[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve VisualVM\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**VisualVM log**\nPlease attach VisualVM messages.log file to help diagnose your problem.\n\nmessages.log is available via Help | About | Logfile and\nvia VisualVM | About VisualVM | Logfile on macOS\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Desktop (please complete the following information):**\n - OS: [e.g. MacOS]\n - JDK version [JDK 1.8.0_181]\n - Version [e.g. 2.0]\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for VisualVM\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".gitignore",
    "content": "/visualvm/nbproject/private/\n/visualvm/*/nbproject/private/\n/visualvm/libs.profiler/*/nbproject/private/\n/visualvm/launcher/windows-src/nbproject/private/\n/visualvm/*/build/\n/visualvm/*/external/*.jar\n/visualvm/libs.profiler/*/build/\n/plugins/*/build/\n/plugins/*/nbproject/private/\n/plugins/*/external/*.jar\n/plugins/visualvm/\n/plugins/glassfish/amx-api/build/\n/samples/*/build/\n/samples/*/nbproject/private/\n/*/build/\n/*/dist/\n/visualvm/netbeans/\n/visualvm/nbantext.jar\n/l10n/en.nbms/\n/l10n/l10nantext.jar\n/plugins/nbproject/private/\n\n# Ignore Mac DS_Store files\n.DS_Store\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to VisualVM\n\n## Opening issues\n\nPlease let us know your ideas, missing features, or bugs found. Either [file a RFE/bug](https://github.com/oracle/visualvm/issues/new/choose) or [leave us a message](https://visualvm.github.io/feedback.html).\n\nAny information, ideas or suggestions that you provide to us either through a Bug Report or a Feature Request ([https://github.com/oracle/visualvm/issues/new/choose](https://github.com/oracle/visualvm/issues/new/choose)) or using Gitter chat or email shall be considered Feedback. If you think you've found a security\nvulnerability, do not raise a GitHub issue and follow the instructions in our [security policy](./SECURITY.md).\n\n## Contributing code\n\nFor legal reasons, we cannot accept external pull requests. \n\n## Pull request process\n\n**Pull requests are currently not being accepted for the VisualVM project.**\n\n## Code of conduct\n\nOracle and its affiliates have a perpetual, royalty-free, non-exclusive, irrevocable license to use, reproduce, distribute or otherwise commercialize any Feedback that you voluntarily provide.  Oracle shall have no obligation to respond to any Feedback or to incorporate your Feedback into the VisualVM software.\n\n[OCA]: https://oca.opensource.oracle.com\n\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "Project VisualVM\n\nThe GNU General Public License (GPL)\n\nVersion 2, June 1991\n\nCopyright (C) 1989, 1991 Free Software Foundation, Inc.\n51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nEveryone is permitted to copy and distribute verbatim copies of this license\ndocument, but changing it is not allowed.\n\nPreamble\n\nThe licenses for most software are designed to take away your freedom to share\nand change it.  By contrast, the GNU General Public License is intended to\nguarantee your freedom to share and change free software--to make sure the\nsoftware is free for all its users.  This General Public License applies to\nmost of the Free Software Foundation's software and to any other program whose\nauthors commit to using it.  (Some other Free Software Foundation software is\ncovered by the GNU Library General Public License instead.) You can apply it to\nyour programs, too.\n\nWhen we speak of free software, we are referring to freedom, not price.  Our\nGeneral Public Licenses are designed to make sure that you have the freedom to\ndistribute copies of free software (and charge for this service if you wish),\nthat you receive source code or can get it if you want it, that you can change\nthe software or use pieces of it in new free programs; and that you know you\ncan do these things.\n\nTo protect your rights, we need to make restrictions that forbid anyone to deny\nyou these rights or to ask you to surrender the rights.  These restrictions\ntranslate to certain responsibilities for you if you distribute copies of the\nsoftware, or if you modify it.\n\nFor example, if you distribute copies of such a program, whether gratis or for\na fee, you must give the recipients all the rights that you have.  You must\nmake sure that they, too, receive or can get the source code.  And you must\nshow them these terms so they know their rights.\n\nWe protect your rights with two steps: (1) copyright the software, and (2)\noffer you this license which gives you legal permission to copy, distribute\nand/or modify the software.\n\nAlso, for each author's protection and ours, we want to make certain that\neveryone understands that there is no warranty for this free software.  If the\nsoftware is modified by someone else and passed on, we want its recipients to\nknow that what they have is not the original, so that any problems introduced\nby others will not reflect on the original authors' reputations.\n\nFinally, any free program is threatened constantly by software patents.  We\nwish to avoid the danger that redistributors of a free program will\nindividually obtain patent licenses, in effect making the program proprietary.\nTo prevent this, we have made it clear that any patent must be licensed for\neveryone's free use or not licensed at all.\n\nThe precise terms and conditions for copying, distribution and modification\nfollow.\n\nTERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n0. This License applies to any program or other work which contains a notice\nplaced by the copyright holder saying it may be distributed under the terms of\nthis General Public License.  The \"Program\", below, refers to any such program\nor work, and a \"work based on the Program\" means either the Program or any\nderivative work under copyright law: that is to say, a work containing the\nProgram or a portion of it, either verbatim or with modifications and/or\ntranslated into another language.  (Hereinafter, translation is included\nwithout limitation in the term \"modification\".) Each licensee is addressed as\n\"you\".\n\nActivities other than copying, distribution and modification are not covered by\nthis License; they are outside its scope.  The act of running the Program is\nnot restricted, and the output from the Program is covered only if its contents\nconstitute a work based on the Program (independent of having been made by\nrunning the Program).  Whether that is true depends on what the Program does.\n\n1. You may copy and distribute verbatim copies of the Program's source code as\nyou receive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice and\ndisclaimer of warranty; keep intact all the notices that refer to this License\nand to the absence of any warranty; and give any other recipients of the\nProgram a copy of this License along with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and you may\nat your option offer warranty protection in exchange for a fee.\n\n2. You may modify your copy or copies of the Program or any portion of it, thus\nforming a work based on the Program, and copy and distribute such modifications\nor work under the terms of Section 1 above, provided that you also meet all of\nthese conditions:\n\n    a) You must cause the modified files to carry prominent notices stating\n    that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in whole or\n    in part contains or is derived from the Program or any part thereof, to be\n    licensed as a whole at no charge to all third parties under the terms of\n    this License.\n\n    c) If the modified program normally reads commands interactively when run,\n    you must cause it, when started running for such interactive use in the\n    most ordinary way, to print or display an announcement including an\n    appropriate copyright notice and a notice that there is no warranty (or\n    else, saying that you provide a warranty) and that users may redistribute\n    the program under these conditions, and telling the user how to view a copy\n    of this License.  (Exception: if the Program itself is interactive but does\n    not normally print such an announcement, your work based on the Program is\n    not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If identifiable\nsections of that work are not derived from the Program, and can be reasonably\nconsidered independent and separate works in themselves, then this License, and\nits terms, do not apply to those sections when you distribute them as separate\nworks.  But when you distribute the same sections as part of a whole which is a\nwork based on the Program, the distribution of the whole must be on the terms\nof this License, whose permissions for other licensees extend to the entire\nwhole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest your\nrights to work written entirely by you; rather, the intent is to exercise the\nright to control the distribution of derivative or collective works based on\nthe Program.\n\nIn addition, mere aggregation of another work not based on the Program with the\nProgram (or with a work based on the Program) on a volume of a storage or\ndistribution medium does not bring the other work under the scope of this\nLicense.\n\n3. You may copy and distribute the Program (or a work based on it, under\nSection 2) in object code or executable form under the terms of Sections 1 and\n2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable source\n    code, which must be distributed under the terms of Sections 1 and 2 above\n    on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three years, to\n    give any third party, for a charge no more than your cost of physically\n    performing source distribution, a complete machine-readable copy of the\n    corresponding source code, to be distributed under the terms of Sections 1\n    and 2 above on a medium customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer to\n    distribute corresponding source code.  (This alternative is allowed only\n    for noncommercial distribution and only if you received the program in\n    object code or executable form with such an offer, in accord with\n    Subsection b above.)\n\nThe source code for a work means the preferred form of the work for making\nmodifications to it.  For an executable work, complete source code means all\nthe source code for all modules it contains, plus any associated interface\ndefinition files, plus the scripts used to control compilation and installation\nof the executable.  However, as a special exception, the source code\ndistributed need not include anything that is normally distributed (in either\nsource or binary form) with the major components (compiler, kernel, and so on)\nof the operating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering access to copy\nfrom a designated place, then offering equivalent access to copy the source\ncode from the same place counts as distribution of the source code, even though\nthird parties are not compelled to copy the source along with the object code.\n\n4. You may not copy, modify, sublicense, or distribute the Program except as\nexpressly provided under this License.  Any attempt otherwise to copy, modify,\nsublicense or distribute the Program is void, and will automatically terminate\nyour rights under this License.  However, parties who have received copies, or\nrights, from you under this License will not have their licenses terminated so\nlong as such parties remain in full compliance.\n\n5. You are not required to accept this License, since you have not signed it.\nHowever, nothing else grants you permission to modify or distribute the Program\nor its derivative works.  These actions are prohibited by law if you do not\naccept this License.  Therefore, by modifying or distributing the Program (or\nany work based on the Program), you indicate your acceptance of this License to\ndo so, and all its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n6. Each time you redistribute the Program (or any work based on the Program),\nthe recipient automatically receives a license from the original licensor to\ncopy, distribute or modify the Program subject to these terms and conditions.\nYou may not impose any further restrictions on the recipients' exercise of the\nrights granted herein.  You are not responsible for enforcing compliance by\nthird parties to this License.\n\n7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues), conditions\nare imposed on you (whether by court order, agreement or otherwise) that\ncontradict the conditions of this License, they do not excuse you from the\nconditions of this License.  If you cannot distribute so as to satisfy\nsimultaneously your obligations under this License and any other pertinent\nobligations, then as a consequence you may not distribute the Program at all.\nFor example, if a patent license would not permit royalty-free redistribution\nof the Program by all those who receive copies directly or indirectly through\nyou, then the only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under any\nparticular circumstance, the balance of the section is intended to apply and\nthe section as a whole is intended to apply in other circumstances.\n\nIt is not the purpose of this section to induce you to infringe any patents or\nother property right claims or to contest validity of any such claims; this\nsection has the sole purpose of protecting the integrity of the free software\ndistribution system, which is implemented by public license practices.  Many\npeople have made generous contributions to the wide range of software\ndistributed through that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing to\ndistribute software through any other system and a licensee cannot impose that\nchoice.\n\nThis section is intended to make thoroughly clear what is believed to be a\nconsequence of the rest of this License.\n\n8. If the distribution and/or use of the Program is restricted in certain\ncountries either by patents or by copyrighted interfaces, the original\ncopyright holder who places the Program under this License may add an explicit\ngeographical distribution limitation excluding those countries, so that\ndistribution is permitted only in or among countries not thus excluded.  In\nsuch case, this License incorporates the limitation as if written in the body\nof this License.\n\n9. The Free Software Foundation may publish revised and/or new versions of the\nGeneral Public License from time to time.  Such new versions will be similar in\nspirit to the present version, but may differ in detail to address new problems\nor concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any later\nversion\", you have the option of following the terms and conditions either of\nthat version or of any later version published by the Free Software Foundation.\nIf the Program does not specify a version number of this License, you may\nchoose any version ever published by the Free Software Foundation.\n\n10. If you wish to incorporate parts of the Program into other free programs\nwhose distribution conditions are different, write to the author to ask for\npermission.  For software which is copyrighted by the Free Software Foundation,\nwrite to the Free Software Foundation; we sometimes make exceptions for this.\nOur decision will be guided by the two goals of preserving the free status of\nall derivatives of our free software and of promoting the sharing and reuse of\nsoftware generally.\n\nNO WARRANTY\n\n11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR\nTHE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE\nSTATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE\nPROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\nFITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND\nPERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE,\nYOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL\nANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE\nPROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR\nINABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA\nBEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\nFAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER\nOR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\nEND OF TERMS AND CONDITIONS\n\nHow to Apply These Terms to Your New Programs\n\nIf you develop a new program, and you want it to be of the greatest possible\nuse to the public, the best way to achieve this is to make it free software\nwhich everyone can redistribute and change under these terms.\n\nTo do so, attach the following notices to the program.  It is safest to attach\nthem to the start of each source file to most effectively convey the exclusion\nof warranty; and each file should have at least the \"copyright\" line and a\npointer to where the full notice is found.\n\n    One line to give the program's name and a brief idea of what it does.\n\n    Copyright (C) <year> <name of author>\n\n    This program is free software; you can redistribute it and/or modify it\n    under the terms of the GNU General Public License as published by the Free\n    Software Foundation; either version 2 of the License, or (at your option)\n    any later version.\n\n    This program is distributed in the hope that it will be useful, but WITHOUT\n    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n    more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc., 51\n    Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this when it\nstarts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author Gnomovision comes\n    with ABSOLUTELY NO WARRANTY; for details type 'show w'.  This is free\n    software, and you are welcome to redistribute it under certain conditions;\n    type 'show c' for details.\n\nThe hypothetical commands 'show w' and 'show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may be\ncalled something other than 'show w' and 'show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.  Here\nis a sample; alter the names:\n\n    Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n    'Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n    signature of Ty Coon, 1 April 1989\n\n    Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Library General Public\nLicense instead of this License.\n\n\n\"CLASSPATH\" EXCEPTION TO THE GPL\n\nCertain source files distributed by Oracle America and/or its affiliates are\nsubject to the following clarification and special exception to the GPL, but\nonly where Oracle has expressly included in the particular source file's header\nthe words \"Oracle designates this particular file as subject to the \"Classpath\"\nexception as provided by Oracle in the LICENSE file that accompanied this code.\"\n\n    Linking this library statically or dynamically with other modules is making\n    a combined work based on this library.  Thus, the terms and conditions of\n    the GNU General Public License cover the whole combination.\n\n    As a special exception, the copyright holders of this library give you\n    permission to link this library with independent modules to produce an\n    executable, regardless of the license terms of these independent modules,\n    and to copy and distribute the resulting executable under terms of your\n    choice, provided that you also meet, for each linked independent module,\n    the terms and conditions of the license of that module.  An independent\n    module is a module which is not derived from or based on this library.  If\n    you modify this library, you may extend this exception to your version of\n    the library, but you are not obligated to do so.  If you do not wish to do\n    so, delete this exception statement from your version.\n"
  },
  {
    "path": "README.md",
    "content": "# VisualVM (master) sources repository\n\nVisualVM is a visual tool integrating commandline JDK tools and lightweight profiling capabilities. See https://visualvm.github.io for details, downloads and documentation.\n\n## Get the tools\n\nUse Apache Ant 1.9.15 or above and Oracle JDK 8 to build VisualVM from this repository.\n\n## Get the sources\n\nFirst download or clone this repository into directory `visualvm`. There are two project suites included:\n  * visualvm (`visualvm/visualvm`) - suite for the core VisualVM tool\n  * plugins (`visualvm/plugins`) - suite for the VisualVM plugins available in Plugins Center\n\n## Configure the dependencies\n\nThen download and extract the [NetBeans Platform 22](https://github.com/oracle/visualvm/releases/download/2.2.1/nb220_platform_20260201.zip) into directory `visualvm/visualvm` (should create `visualvm/visualvm/netbeans`).\n\n## How to build\n\nTo build VisualVM, use `ant build-zip` command in the `visualvm/visualvm` directory. \n\n## How to run\n\nTo run VisualVM, use `ant run` command in the `visualvm/visualvm` directory.\n\n## Build and run plugins\n\nTo build or run the plugins suite, use `ant build` or `ant run` in the `visualvm/plugins` directory. This will automatically build the zip distribution of the core VisualVM tool into `visualvm/visualvm/dist/visualvm.zip` and extract it into the `visualvm/plugins/visualvm` directory. After that the build of the plugins suite continues to build each of the individual plugins. Running the plugins suite means starting VisualVM with all the plugins installed.\n\n## Contributing\n\nWe highly appreciate any feedback! Please let us know your ideas, missing features, or bugs found. Either [file a RFE/bug](https://github.com/oracle/visualvm/issues/new/choose) or [leave us a message](https://visualvm.github.io/feedback.html). For legal reasons, we cannot accept external pull requests. See \n[CONTRIBUTING](./CONTRIBUTING.md)\nfor details.\n\n## Security\n\nPlease consult the [security guide](./SECURITY.md) for our responsible security vulnerability disclosure process\n\n## License\n\nCopyright (c) 2017, 2025 Oracle and/or its affiliates.\nReleased under the GNU General Public License, version 2, with the Classpath Exception.\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Reporting security vulnerabilities\n\nOracle values the independent security research community and believes that\nresponsible disclosure of security vulnerabilities helps us ensure the security\nand privacy of all our users.\n\nPlease do NOT raise a GitHub Issue to report a security vulnerability. If you\nbelieve you have found a security vulnerability, please submit a report to\n[secalert_us@oracle.com][1] preferably with a proof of concept. Please review\nsome additional information on [how to report security vulnerabilities to Oracle][2].\nWe encourage people who contact Oracle Security to use email encryption using\n[our encryption key][3].\n\nWe ask that you do not use other channels or contact the project maintainers\ndirectly.\n\nNon-vulnerability related security issues including ideas for new or improved\nsecurity features are welcome on GitHub Issues.\n\n## Security updates, alerts and bulletins\n\nSecurity updates will be released on a regular cadence. Many of our projects\nwill typically release security fixes in conjunction with the\nOracle Critical Patch Update program. Additional\ninformation, including past advisories, is available on our [security alerts][4]\npage.\n\n## Security-related information\n\nWe will provide security related information such as a threat model, considerations\nfor secure use, or any known security issues in our documentation. Please note\nthat labs and sample code are intended to demonstrate a concept and may not be\nsufficiently hardened for production use.\n\n[1]: mailto:secalert_us@oracle.com\n[2]: https://www.oracle.com/corporate/security-practices/assurance/vulnerability/reporting.html\n[3]: https://www.oracle.com/security-alerts/encryptionkey.html\n[4]: https://www.oracle.com/security-alerts/\n"
  },
  {
    "path": "THIRDPARTYLICENSE",
    "content": "Apache NetBeans License and Third party licenses information\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n******* List of Third Party Components ***********\nApache NetBeans includes a number of components and libraries with separate copyright notices and license terms. Your use of those components are subject to the terms and conditions of the following licenses.\n\nTHIRD-PARTY COMPONENT FILE\t\t\t\tVERSION\tLICENSE\t\nplatform/modules/ext/flatlaf-3.3.jar  \t\t\t3.3\tApache-2.0\nplatform/modules/lib/flatlaf-windows-arm64.dll\t\t3.3\tApache-2.0\nplatform/modules/lib/flatlaf-windows-x86.dll\t\t3.3\tApache-2.0\nplatform/modules/lib/flatlaf-windows-x86_64.dll\t\t3.3\tApache-2.0\nplatform/modules/lib/libflatlaf-linux-x86_64.so\t\t3.3\tApache-2.0\nplatform/modules/lib/libflatlaf-macos-arm64.dylib\t3.3\tApache-2.0\nplatform/modules/lib/libflatlaf-macos-x86_64.dylib\t3.3\tApache-2.0\nplatform/modules/ext/jna-5.14.jar\t\t\t5.14\tApache-2.0\nplatform/modules/ext/jna-platform-5.14.jar\t\t5.14\tApache-2.0\nplatform/core/asm-tree-9.7.jar\t\t\t\t9.7\tBSD-INRIA\nplatform/core/asm-9.7.jar\t\t\t\t9.7\tBSD-INRIA\nplatform/core/asm-commons-9.7.jar\t\t\t9.7\tBSD-INRIA\n*******************************************************************************\nBSD-INRIA\nASM: a very small and fast Java bytecode manipulation framework\n Copyright (c) 2000-2011 INRIA, France Telecom\n All rights reserved. Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions\n are met:\n 1. Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n 2. Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in the\n    documentation and/or other materials provided with the distribution.\n 3. Neither the name of the copyright holders nor the names of its\n    contributors may be used to endorse or promote products derived from\n    this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher/.project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>VisualVM Launcher</name>\n\t<comment></comment>\n\t<projects>\n\t\t<project>org.eclipse.visualvm.launcher.common</project>\n\t\t<project>org.eclipse.visualvm.launcher.java</project>\n\t\t<project>org.eclipse.visualvm.launcher.pde</project>\n\t</projects>\n\t<buildSpec>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.pde.FeatureBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t</buildSpec>\n\t<natures>\n\t\t<nature>org.eclipse.pde.FeatureNature</nature>\n\t</natures>\n</projectDescription>\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher/build.properties",
    "content": "bin.includes = feature.xml\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher/feature.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<feature\n      id=\"VisualVM_Launcher\"\n      label=\"VisualVM Launcher Feature\"\n      version=\"1.1.3\"\n      provider-name=\"Oracle Corporation\">\n\n   <description>\n      VisualVM is a visual tool integrating several commandline JDK\ntools and lightweight profiling capabilities. Designed for both\nproduction and development time use, it further enhances the\ncapability of monitoring and performance analysis for the Java\nSE platform.\nThis launcher makes monitoring your eclipse based applications\nas easy as launching them from the IDE.\n   </description>\n\n   <copyright>\n      Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the &quot;Classpath&quot; exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n   </copyright>\n\n   <license url=\"https://visualvm.github.io/legal/gplv2+ce.html\">\n      GNU General Public License, version 2,\nwith the Classpath Exception\nThe GNU General Public License (GPL)\n\nVersion 2, June 1991\n\nCopyright (C) 1989, 1991 Free Software Foundation, Inc.\n59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\nEveryone is permitted to copy and distribute verbatim copies of this license\ndocument, but changing it is not allowed.\n\nPreamble\n\nThe licenses for most software are designed to take away your freedom to share\nand change it.  By contrast, the GNU General Public License is intended to\nguarantee your freedom to share and change free software--to make sure the\nsoftware is free for all its users.  This General Public License applies to\nmost of the Free Software Foundation&apos;s software and to any other program whose\nauthors commit to using it.  (Some other Free Software Foundation software is\ncovered by the GNU Library General Public License instead.) You can apply it to\nyour programs, too.\n\nWhen we speak of free software, we are referring to freedom, not price.  Our\nGeneral Public Licenses are designed to make sure that you have the freedom to\ndistribute copies of free software (and charge for this service if you wish),\nthat you receive source code or can get it if you want it, that you can change\nthe software or use pieces of it in new free programs; and that you know you\ncan do these things.\n\nTo protect your rights, we need to make restrictions that forbid anyone to deny\nyou these rights or to ask you to surrender the rights.  These restrictions\ntranslate to certain responsibilities for you if you distribute copies of the\nsoftware, or if you modify it.\n\nFor example, if you distribute copies of such a program, whether gratis or for\na fee, you must give the recipients all the rights that you have.  You must\nmake sure that they, too, receive or can get the source code.  And you must\nshow them these terms so they know their rights.\n\nWe protect your rights with two steps: (1) copyright the software, and (2)\noffer you this license which gives you legal permission to copy, distribute\nand/or modify the software.\n\nAlso, for each author&apos;s protection and ours, we want to make certain that\neveryone understands that there is no warranty for this free software.  If the\nsoftware is modified by someone else and passed on, we want its recipients to\nknow that what they have is not the original, so that any problems introduced\nby others will not reflect on the original authors&apos; reputations.\n\nFinally, any free program is threatened constantly by software patents.  We\nwish to avoid the danger that redistributors of a free program will\nindividually obtain patent licenses, in effect making the program proprietary.\nTo prevent this, we have made it clear that any patent must be licensed for\neveryone&apos;s free use or not licensed at all.\n\nThe precise terms and conditions for copying, distribution and modification\nfollow.\n\nTERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n0. This License applies to any program or other work which contains a notice\nplaced by the copyright holder saying it may be distributed under the terms of\nthis General Public License.  The &quot;Program&quot;, below, refers to any such program\nor work, and a &quot;work based on the Program&quot; means either the Program or any\nderivative work under copyright law: that is to say, a work containing the\nProgram or a portion of it, either verbatim or with modifications and/or\ntranslated into another language.  (Hereinafter, translation is included\nwithout limitation in the term &quot;modification&quot;.) Each licensee is addressed as\n&quot;you&quot;.\n\nActivities other than copying, distribution and modification are not covered by\nthis License; they are outside its scope.  The act of running the Program is\nnot restricted, and the output from the Program is covered only if its contents\nconstitute a work based on the Program (independent of having been made by\nrunning the Program).  Whether that is true depends on what the Program does.\n\n1. You may copy and distribute verbatim copies of the Program&apos;s source code as\nyou receive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice and\ndisclaimer of warranty; keep intact all the notices that refer to this License\nand to the absence of any warranty; and give any other recipients of the\nProgram a copy of this License along with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and you may\nat your option offer warranty protection in exchange for a fee.\n\n2. You may modify your copy or copies of the Program or any portion of it, thus\nforming a work based on the Program, and copy and distribute such modifications\nor work under the terms of Section 1 above, provided that you also meet all of\nthese conditions:\n\n    a) You must cause the modified files to carry prominent notices stating\n    that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in whole or\n    in part contains or is derived from the Program or any part thereof, to be\n    licensed as a whole at no charge to all third parties under the terms of\n    this License.\n\n    c) If the modified program normally reads commands interactively when run,\n    you must cause it, when started running for such interactive use in the\n    most ordinary way, to print or display an announcement including an\n    appropriate copyright notice and a notice that there is no warranty (or\n    else, saying that you provide a warranty) and that users may redistribute\n    the program under these conditions, and telling the user how to view a copy\n    of this License.  (Exception: if the Program itself is interactive but does\n    not normally print such an announcement, your work based on the Program is\n    not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If identifiable\nsections of that work are not derived from the Program, and can be reasonably\nconsidered independent and separate works in themselves, then this License, and\nits terms, do not apply to those sections when you distribute them as separate\nworks.  But when you distribute the same sections as part of a whole which is a\nwork based on the Program, the distribution of the whole must be on the terms\nof this License, whose permissions for other licensees extend to the entire\nwhole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest your\nrights to work written entirely by you; rather, the intent is to exercise the\nright to control the distribution of derivative or collective works based on\nthe Program.\n\nIn addition, mere aggregation of another work not based on the Program with the\nProgram (or with a work based on the Program) on a volume of a storage or\ndistribution medium does not bring the other work under the scope of this\nLicense.\n\n3. You may copy and distribute the Program (or a work based on it, under\nSection 2) in object code or executable form under the terms of Sections 1 and\n2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable source\n    code, which must be distributed under the terms of Sections 1 and 2 above\n    on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three years, to\n    give any third party, for a charge no more than your cost of physically\n    performing source distribution, a complete machine-readable copy of the\n    corresponding source code, to be distributed under the terms of Sections 1\n    and 2 above on a medium customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer to\n    distribute corresponding source code.  (This alternative is allowed only\n    for noncommercial distribution and only if you received the program in\n    object code or executable form with such an offer, in accord with\n    Subsection b above.)\n\nThe source code for a work means the preferred form of the work for making\nmodifications to it.  For an executable work, complete source code means all\nthe source code for all modules it contains, plus any associated interface\ndefinition files, plus the scripts used to control compilation and installation\nof the executable.  However, as a special exception, the source code\ndistributed need not include anything that is normally distributed (in either\nsource or binary form) with the major components (compiler, kernel, and so on)\nof the operating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering access to copy\nfrom a designated place, then offering equivalent access to copy the source\ncode from the same place counts as distribution of the source code, even though\nthird parties are not compelled to copy the source along with the object code.\n\n4. You may not copy, modify, sublicense, or distribute the Program except as\nexpressly provided under this License.  Any attempt otherwise to copy, modify,\nsublicense or distribute the Program is void, and will automatically terminate\nyour rights under this License.  However, parties who have received copies, or\nrights, from you under this License will not have their licenses terminated so\nlong as such parties remain in full compliance.\n\n5. You are not required to accept this License, since you have not signed it.\nHowever, nothing else grants you permission to modify or distribute the Program\nor its derivative works.  These actions are prohibited by law if you do not\naccept this License.  Therefore, by modifying or distributing the Program (or\nany work based on the Program), you indicate your acceptance of this License to\ndo so, and all its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n6. Each time you redistribute the Program (or any work based on the Program),\nthe recipient automatically receives a license from the original licensor to\ncopy, distribute or modify the Program subject to these terms and conditions.\nYou may not impose any further restrictions on the recipients&apos; exercise of the\nrights granted herein.  You are not responsible for enforcing compliance by\nthird parties to this License.\n\n7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues), conditions\nare imposed on you (whether by court order, agreement or otherwise) that\ncontradict the conditions of this License, they do not excuse you from the\nconditions of this License.  If you cannot distribute so as to satisfy\nsimultaneously your obligations under this License and any other pertinent\nobligations, then as a consequence you may not distribute the Program at all.\nFor example, if a patent license would not permit royalty-free redistribution\nof the Program by all those who receive copies directly or indirectly through\nyou, then the only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under any\nparticular circumstance, the balance of the section is intended to apply and\nthe section as a whole is intended to apply in other circumstances.\n\nIt is not the purpose of this section to induce you to infringe any patents or\nother property right claims or to contest validity of any such claims; this\nsection has the sole purpose of protecting the integrity of the free software\ndistribution system, which is implemented by public license practices.  Many\npeople have made generous contributions to the wide range of software\ndistributed through that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing to\ndistribute software through any other system and a licensee cannot impose that\nchoice.\n\nThis section is intended to make thoroughly clear what is believed to be a\nconsequence of the rest of this License.\n\n8. If the distribution and/or use of the Program is restricted in certain\ncountries either by patents or by copyrighted interfaces, the original\ncopyright holder who places the Program under this License may add an explicit\ngeographical distribution limitation excluding those countries, so that\ndistribution is permitted only in or among countries not thus excluded.  In\nsuch case, this License incorporates the limitation as if written in the body\nof this License.\n\n9. The Free Software Foundation may publish revised and/or new versions of the\nGeneral Public License from time to time.  Such new versions will be similar in\nspirit to the present version, but may differ in detail to address new problems\nor concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and &quot;any later\nversion&quot;, you have the option of following the terms and conditions either of\nthat version or of any later version published by the Free Software Foundation.\nIf the Program does not specify a version number of this License, you may\nchoose any version ever published by the Free Software Foundation.\n\n10. If you wish to incorporate parts of the Program into other free programs\nwhose distribution conditions are different, write to the author to ask for\npermission.  For software which is copyrighted by the Free Software Foundation,\nwrite to the Free Software Foundation; we sometimes make exceptions for this.\nOur decision will be guided by the two goals of preserving the free status of\nall derivatives of our free software and of promoting the sharing and reuse of\nsoftware generally.\n\nNO WARRANTY\n\n11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR\nTHE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE\nSTATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE\nPROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\nFITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND\nPERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE,\nYOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL\nANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE\nPROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR\nINABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA\nBEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\nFAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER\nOR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\nEND OF TERMS AND CONDITIONS\n\nHow to Apply These Terms to Your New Programs\n\nIf you develop a new program, and you want it to be of the greatest possible\nuse to the public, the best way to achieve this is to make it free software\nwhich everyone can redistribute and change under these terms.\n\nTo do so, attach the following notices to the program.  It is safest to attach\nthem to the start of each source file to most effectively convey the exclusion\nof warranty; and each file should have at least the &quot;copyright&quot; line and a\npointer to where the full notice is found.\n\n    One line to give the program&apos;s name and a brief idea of what it does.\n\n    Copyright (C) &lt;year&gt; &lt;name of author&gt;\n\n    This program is free software; you can redistribute it and/or modify it\n    under the terms of the GNU General Public License as published by the Free\n    Software Foundation; either version 2 of the License, or (at your option)\n    any later version.\n\n    This program is distributed in the hope that it will be useful, but WITHOUT\n    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n    more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc., 59\n    Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this when it\nstarts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author Gnomovision comes\n    with ABSOLUTELY NO WARRANTY; for details type &apos;show w&apos;.  This is free\n    software, and you are welcome to redistribute it under certain conditions;\n    type &apos;show c&apos; for details.\n\nThe hypothetical commands &apos;show w&apos; and &apos;show c&apos; should show the appropriate\nparts of the General Public License.  Of course, the commands you use may be\ncalled something other than &apos;show w&apos; and &apos;show c&apos;; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your school,\nif any, to sign a &quot;copyright disclaimer&quot; for the program, if necessary.  Here\nis a sample; alter the names:\n\n    Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n    &apos;Gnomovision&apos; (which makes passes at compilers) written by James Hacker.\n\n    signature of Ty Coon, 1 April 1989\n\n    Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Library General Public\nLicense instead of this License.\n\n\n&quot;CLASSPATH&quot; EXCEPTION TO THE GPL\n\nCertain source files distributed by Oracle America and/or its affiliates are subject to\nthe following clarification and special exception to the GPL, but only where\nSun has expressly included in the particular source file&apos;s header the words\n&quot;Sun designates this particular file as subject to the &quot;Classpath&quot; exception\nas provided by Sun in the LICENSE file that accompanied this code.&quot;\n\n    Linking this library statically or dynamically with other modules is making\n    a combined work based on this library.  Thus, the terms and conditions of\n    the GNU General Public License cover the whole combination.\n\n    As a special exception, the copyright holders of this library give you\n    permission to link this library with independent modules to produce an\n    executable, regardless of the license terms of these independent modules,\n    and to copy and distribute the resulting executable under terms of your\n    choice, provided that you also meet, for each linked independent module,\n    the terms and conditions of the license of that module.  An independent\n    module is a module which is not derived from or based on this library.  If\n    you modify this library, you may extend this exception to your version of\n    the library, but you are not obligated to do so.  If you do not wish to do\n    so, delete this exception statement from your version.\n   </license>\n\n   <requires>\n      <import plugin=\"org.eclipse.ui\"/>\n      <import plugin=\"org.eclipse.core.runtime\"/>\n      <import plugin=\"com.ibm.icu\"/>\n      <import plugin=\"org.eclipse.debug.core\"/>\n      <import plugin=\"org.eclipse.jdt.launching\"/>\n      <import plugin=\"org.eclipse.visualvm.launcher.common\" version=\"1.1.0\" match=\"greaterOrEqual\"/>\n      <import plugin=\"org.eclipse.pde.ui\"/>\n   </requires>\n\n   <plugin\n         id=\"org.eclipse.visualvm.launcher.common\"\n         download-size=\"0\"\n         install-size=\"0\"\n         version=\"1.1.3\"/>\n\n   <plugin\n         id=\"org.eclipse.visualvm.launcher.java\"\n         download-size=\"0\"\n         install-size=\"0\"\n         version=\"1.1.1\"/>\n\n   <plugin\n         id=\"org.eclipse.visualvm.launcher.pde\"\n         download-size=\"0\"\n         install-size=\"0\"\n         version=\"1.1.1\"/>\n\n</feature>\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/.classpath",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classpath>\n\t<classpathentry kind=\"con\" path=\"org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5\"/>\n\t<classpathentry kind=\"con\" path=\"org.eclipse.pde.core.requiredPlugins\"/>\n\t<classpathentry kind=\"src\" path=\"src\"/>\n\t<classpathentry kind=\"output\" path=\"bin\"/>\n</classpath>\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/.project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>org.eclipse.visualvm.launcher.common</name>\n\t<comment></comment>\n\t<projects>\n\t</projects>\n\t<buildSpec>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.pde.ManifestBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.pde.SchemaBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t</buildSpec>\n\t<natures>\n\t\t<nature>org.eclipse.pde.PluginNature</nature>\n\t\t<nature>org.eclipse.jdt.core.javanature</nature>\n\t</natures>\n</projectDescription>\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/.settings/org.eclipse.jdt.core.prefs",
    "content": "eclipse.preferences.version=1\norg.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\norg.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate\norg.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5\norg.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve\norg.eclipse.jdt.core.compiler.compliance=1.5\norg.eclipse.jdt.core.compiler.debug.lineNumber=generate\norg.eclipse.jdt.core.compiler.debug.localVariable=generate\norg.eclipse.jdt.core.compiler.debug.sourceFile=generate\norg.eclipse.jdt.core.compiler.problem.assertIdentifier=error\norg.eclipse.jdt.core.compiler.problem.enumIdentifier=error\norg.eclipse.jdt.core.compiler.source=1.5\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/META-INF/MANIFEST.MF",
    "content": "Manifest-Version: 1.0\nBundle-ManifestVersion: 2\nBundle-Name: VisualVM Launcher Plug-in\nBundle-SymbolicName: org.eclipse.visualvm.launcher.common;singleton:=true\nBundle-Version: 1.1.3\nBundle-Activator: org.eclipse.visualvm.launcher.Activator\nBundle-Vendor: Oracle Corporation\nRequire-Bundle: org.eclipse.ui,\n org.eclipse.core.runtime\nBundle-RequiredExecutionEnvironment: JavaSE-1.6\nImport-Package: com.ibm.icu.text,\n org.eclipse.debug.core,\n org.eclipse.jdt.launching\nExport-Package: org.eclipse.visualvm.launcher.api;version=\"1.1.0\"\nBundle-ActivationPolicy: lazy\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/build.properties",
    "content": "source.. = src/\noutput.. = bin/\nbin.includes = plugin.xml,\\\n               META-INF/,\\\n               .\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<?eclipse version=\"3.2\"?>\n<plugin>\n   <extension\n         point=\"org.eclipse.ui.preferencePages\">\n      <page\n            category=\"org.eclipse.debug.ui.DebugPreferencePage/org.eclipse.debug.ui.LaunchingPreferencePage\"\n            class=\"org.eclipse.visualvm.launcher.preferences.LocationPreferencePage\"\n            id=\"org.eclipse.visualvm.launch.preferences.LocationPreferencePage\"\n            name=\"VisualVM Configuration\">\n      </page>\n   </extension>\n   <extension\n         point=\"org.eclipse.core.runtime.preferences\">\n      <initializer\n            class=\"org.eclipse.visualvm.launcher.preferences.PreferenceInitializer\">\n      </initializer>\n   </extension>\n\n</plugin>\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/Activator.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.eclipse.visualvm.launcher;\n\nimport org.eclipse.core.runtime.IStatus;\nimport org.eclipse.core.runtime.Status;\nimport org.eclipse.jface.resource.ImageDescriptor;\nimport org.eclipse.ui.plugin.AbstractUIPlugin;\nimport org.osgi.framework.BundleContext;\n\n/**\n * The activator class controls the plug-in life cycle\n */\npublic class Activator extends AbstractUIPlugin {\n\n\t// The plug-in ID\n\tpublic static final String PLUGIN_ID = \"org.eclipse.visualvm.launcher\";\n\n\t// The shared instance\n\tprivate static Activator plugin;\n\t\n\t/**\n\t * The constructor\n\t */\n\tpublic Activator() {\n\t}\n\n\t/*\n\t * (non-Javadoc)\n\t * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)\n\t */\n\tpublic void start(BundleContext context) throws Exception {\n\t\tsuper.start(context);\n\t\tplugin = this;\n\t}\n\n\t/*\n\t * (non-Javadoc)\n\t * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)\n\t */\n\tpublic void stop(BundleContext context) throws Exception {\n\t\tplugin = null;\n\t\tsuper.stop(context);\n\t}\n\n\t/**\n\t * Returns the shared instance\n\t *\n\t * @return the shared instance\n\t */\n\tpublic static Activator getDefault() {\n\t\treturn plugin;\n\t}\n\n\t/**\n\t * Returns an image descriptor for the image file at the given\n\t * plug-in relative path\n\t *\n\t * @param path the path\n\t * @return the image descriptor\n\t */\n\tpublic static ImageDescriptor getImageDescriptor(String path) {\n\t\treturn imageDescriptorFromPlugin(PLUGIN_ID, path);\n\t}\n}\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/api/VisualVMHelper.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.eclipse.visualvm.launcher.api;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.util.StringTokenizer;\n\nimport org.eclipse.core.runtime.IStatus;\nimport org.eclipse.core.runtime.Status;\nimport org.eclipse.jface.dialogs.MessageDialog;\nimport org.eclipse.swt.widgets.Display;\nimport org.eclipse.swt.widgets.Shell;\nimport org.eclipse.visualvm.launcher.Activator;\nimport org.eclipse.visualvm.launcher.preferences.PreferenceConstants;\n\npublic final class VisualVMHelper {\n        private static final String JAVA_VERSION_KEY = \"java version\";\n        private static final String OPENJDK_VERSION_KEY = \"openjdk version\";\n    \n\tprivate static class SpecVersion {\n\t\tint major, minor;\n\t\t\n\t\tpublic SpecVersion(String specString) {\n\t\t\tStringTokenizer st = new StringTokenizer(specString, \".\");\n\t\t\tif (st.hasMoreTokens()) {\n\t\t\t\tmajor = Integer.parseInt(st.nextToken());\n\t\t\t}\n\t\t\tif (st.hasMoreTokens()) {\n\t\t\t\tminor = Integer.parseInt(st.nextToken());\n\t\t\t}\n\t\t}\n\t}\n\t\n\tpublic static long getNextID() {\n\t\treturn System.nanoTime();\n\t}\n\t\n\tpublic static String[] getJvmArgs(long id) {\n\t\treturn new String[]{\"-Dvisualvm.id=\" + id}; \n\t}\n\t\n\tpublic static void openInVisualVM(long id) throws IOException {\n\t\tSpecVersion sv = getJavaVersion();\n\t\tif (sv == null || (sv.major == 1 && sv.minor < 6)) {\n\t\t\tfinal Display d = Display.getDefault();\n\t\t\td.asyncExec(new Runnable() {\n\t\t\t\tpublic void run() {\n\t\t\t\t\tShell s = new Shell(d);\n\t\t\t\t\tMessageDialog.openError(s, \"VisualVM requires JDK1.6+ to run\", \"You are trying to launch VisualVM using an unsupported JDK.\\n\\nUse 'Window\\\\Preferences\\\\Run/Debug\\\\Launching\\\\VisualVM Configuration' to set the VisualVM JDK_HOME.\");\t\t\t\t\t\t\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tRuntime.getRuntime().exec(\n\t\t\tnew String[] { \n\t\t\t\t\tActivator.getDefault().getPreferenceStore().getString(PreferenceConstants.P_PATH),\n\t\t\t\t\t\"--jdkhome\",\n\t\t\t\t\tActivator.getDefault().getPreferenceStore().getString(PreferenceConstants.P_JAVAHOME),\n\t\t\t\t\t\"--openid\",\n\t\t\t\t\tString.valueOf(id) \n\t\t});\n\t}\n\n\tpublic static void logException(Exception ex) {\n\t\tIStatus s = new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getLocalizedMessage(), ex);\n\t\tActivator.getDefault().getLog().log(s);\n\t}\n\t\n\tprivate static SpecVersion getJavaVersion() {\n\t\ttry {\n\t\t\tString javaCmd = Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.P_JAVAHOME) + File.separator + \"bin\" + File.separator + \"java\";\n\t\t\tProcess prc = Runtime.getRuntime().exec(\n\t\t\t\tnew String[] {\n\t\t\t\t\t\tjavaCmd,\n\t\t\t\t\t\t\"-version\"\n\t\t\t\t} \n\t\t\t);\n\t\t\t\n\t\t\tString version = getJavaVersion(prc.getErrorStream());\n\t\t\tif (version == null) {\n\t\t\t\tversion = getJavaVersion(prc.getInputStream());\n\t\t\t}\n\t\t\treturn new SpecVersion(version);\n\t\t} catch (IOException e) {\n\t\t\tlogException(e);\n\t\t}\n\t\treturn null;\n\t}\n\t\n\tprivate static String getJavaVersion(InputStream is) throws IOException {\n\t\tBufferedReader br = new BufferedReader(new InputStreamReader(is));\n\t\ttry {\n\t\t\tString line;\n\t\t\twhile ((line = br.readLine()) != null) {\n\t\t\t\tif (line.startsWith(JAVA_VERSION_KEY) || line.startsWith(OPENJDK_VERSION_KEY)) {\n\t\t\t\t\tint start = line.indexOf(\"\\\"\");\n\t\t\t\t\tint end = line.lastIndexOf(\"\\\"\");\n\t\t\t\t\tif (start > -1 && end > -1) {\n\t\t\t\t\t\treturn line.substring(start + 1, end);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tbr.close();\n\t\t}\n\t\treturn null;\n\t}\n}\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/preferences/LocationPreferencePage.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.eclipse.visualvm.launcher.preferences;\n\nimport java.io.File;\n\nimport org.eclipse.jface.preference.*;\nimport org.eclipse.ui.IWorkbenchPreferencePage;\nimport org.eclipse.ui.IWorkbench;\nimport org.eclipse.visualvm.launcher.Activator;\nimport org.eclipse.visualvm.launcher.resources.PreferencesMessages;\n\n/**\n * This class represents a preference page that\n * is contributed to the Preferences dialog. By \n * subclassing <samp>FieldEditorPreferencePage</samp>, we\n * can use the field support built into JFace that allows\n * us to create a page that is small and knows how to \n * save, restore and apply itself.\n * <p>\n * This page is used to modify preferences only. They\n * are stored in the preference store that belongs to\n * the main plug-in class. That way, preferences can\n * be accessed directly via the preference store.\n */\n\npublic class LocationPreferencePage\n\textends FieldEditorPreferencePage\n\timplements IWorkbenchPreferencePage {\n\n\tpublic LocationPreferencePage() {\n\t\tsuper(GRID);\n\t\tsetPreferenceStore(Activator.getDefault().getPreferenceStore());\n\t\tsetDescription(PreferencesMessages.LocationPreferencePage_0);\n\t}\n\t\n\t/**\n\t * Creates the field editors. Field editors are abstractions of\n\t * the common GUI blocks needed to manipulate various types\n\t * of preferences. Each field editor knows how to save and\n\t * restore itself.\n\t */\n\tpublic void createFieldEditors() {\n\t\tfinal boolean isWindows = System.getProperty(\"os.name\").toUpperCase().contains(\"WIN\"); //$NON-NLS-1$ //$NON-NLS-2$\n\t\tFileFieldEditor ffe = new FileFieldEditor(PreferenceConstants.P_PATH, \n\t\t\t\tPreferencesMessages.LocationPreferencePage_1, getFieldEditorParent()) {\n\t\t\t\t\t@Override\n\t\t\t\t\tprotected void refreshValidState() {\n\t\t\t\t\t\tsuper.refreshValidState();\n\t\t\t\t\t\tif (isValid()) {\n\t\t\t\t\t\t\tboolean validated = isWindows ? getStringValue().endsWith(\"visualvm.exe\") : getStringValue().endsWith(\"visualvm\"); //$NON-NLS-1$ //$NON-NLS-2$\n\t\t\t\t\t\t\tif (!validated) {\n\t\t\t\t\t\t\t\tsetErrorMessage(PreferencesMessages.LocationPreferencePage_6);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetValid(validated);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\n\t\t};\n\t\tffe.setValidateStrategy(FileFieldEditor.VALIDATE_ON_KEY_STROKE);\n\t\taddField(ffe);\n\t\t\n\t\t\n\t\t\n\t\tDirectoryFieldEditor dfe = new DirectoryFieldEditor(PreferenceConstants.P_JAVAHOME, \n\t\t\t\tPreferencesMessages.LocationPreferencePage_2, getFieldEditorParent()) {\n\t\t\t\t\t@Override\n\t\t\t\t\tprotected void refreshValidState() {\n\t\t\t\t\t\tsuper.refreshValidState();\n\t\t\t\t\t\tif (isValid()) {\n\t\t\t\t\t\t\tString javacPath = getStringValue() + File.separator + \"bin\" + File.separator + \n\t\t\t\t\t\t\t  (isWindows ? \"javac.exe\" : \"javac\");\n\t\t\t\t\t\t\tFile javacFile = new File(javacPath);\n\t\t\t\t\t\t\tboolean validated = javacFile.exists() && javacFile.isFile();\n\t\t\t\t\t\t\tif (!validated) {\n\t\t\t\t\t\t\t\tsetErrorMessage(PreferencesMessages.LocationPreferencePage_7);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetValid(validated);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\n\t\t};\n\t\tdfe.setValidateStrategy(FileFieldEditor.VALIDATE_ON_KEY_STROKE);\n\t\taddField(dfe);\n\t}\n\n\t/* (non-Javadoc)\n\t * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)\n\t */\n\tpublic void init(IWorkbench workbench) {\n\t}\n\t\n}"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/preferences/PreferenceConstants.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.eclipse.visualvm.launcher.preferences;\n\n/**\n * Constant definitions for plug-in preferences\n */\npublic class PreferenceConstants {\n\n\tpublic static final String P_PATH = \"pathPreference\";\n\t\n\tpublic static final String P_JAVAHOME = \"javaHome\";\n\n//\tpublic static final String P_BOOLEAN = \"booleanPreference\";\n//\n//\tpublic static final String P_CHOICE = \"choicePreference\";\n//\n//\tpublic static final String P_STRING = \"stringPreference\";\n\t\n}\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/preferences/PreferenceInitializer.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.eclipse.visualvm.launcher.preferences;\n\nimport java.io.File;\n\nimport org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;\nimport org.eclipse.jface.preference.IPreferenceStore;\n\nimport org.eclipse.visualvm.launcher.Activator;\n\n/**\n * Class used to initialize default preference values.\n */\npublic class PreferenceInitializer extends AbstractPreferenceInitializer {\n\n\t/*\n\t * (non-Javadoc)\n\t * \n\t * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()\n\t */\n\tpublic void initializeDefaultPreferences() {\n\t\tIPreferenceStore store = Activator.getDefault().getPreferenceStore();\n\t\tString JAVA_HOME = System.getProperty(\"java.home\");\n\t\tif (JAVA_HOME.endsWith(File.separator + \"jre\")) {\n\t\t\tJAVA_HOME = JAVA_HOME.substring(0, JAVA_HOME.length() - 4);\n\t\t}\n\t\tFile visualvm = new File(JAVA_HOME + File.separator + \"bin\" + File.separator + \"jvisualvm\");\n\t\tif (visualvm.exists()) {\n\t\t\tstore.setDefault(PreferenceConstants.P_PATH, visualvm.getAbsolutePath());\n\t\t} else {\n\t\t\tstore.setDefault(PreferenceConstants.P_PATH, \"\");\n\t\t}\n\t\t\n\t\tstore.setDefault(PreferenceConstants.P_JAVAHOME, JAVA_HOME);\n//\t\tstore.setDefault(PreferenceConstants.P_BOOLEAN, true);\n//\t\tstore.setDefault(PreferenceConstants.P_CHOICE, \"choice2\");\n//\t\tstore.setDefault(PreferenceConstants.P_STRING,\n//\t\t\t\t\"Default value\");\n\t}\n\n}\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/resources/LauncherMessages.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.eclipse.visualvm.launcher.resources;\n\nimport org.eclipse.osgi.util.NLS;\n\npublic class LauncherMessages extends NLS {\n\tprivate static final String BUNDLE_NAME = \"org.eclipse.visualvm.launcher.resources.LauncherMessages\";//$NON-NLS-1$\n\t\n\tpublic static String VisualVMLaunchDelegate_task_1;\n\tpublic static String VisualVMLaunchDelegate_task_2;\n\t\n\tstatic {\n\t\t// load message values from bundle file\n\t\tNLS.initializeMessages(BUNDLE_NAME, LauncherMessages.class);\n\t}\n\t\n}"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/resources/LauncherMessages.properties",
    "content": "# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n \nVisualVMLaunchDelegate_task_1=Verifying launch attributes...\nVisualVMLaunchDelegate_task_2=Creating source locator...\n\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/resources/PreferencesMessages.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.eclipse.visualvm.launcher.resources;\n\nimport org.eclipse.osgi.util.NLS;\n\npublic class PreferencesMessages extends NLS {\n\tprivate static final String BUNDLE_NAME = \"org.eclipse.visualvm.launcher.resources.PreferencesMessages\"; //$NON-NLS-1$\n\tpublic static String LocationPreferencePage_0;\n\tpublic static String LocationPreferencePage_1;\n\tpublic static String LocationPreferencePage_2;\n\tpublic static String LocationPreferencePage_6;\n\tpublic static String LocationPreferencePage_7;\n\tstatic {\n\t\t// initialize resource bundle\n\t\tNLS.initializeMessages(BUNDLE_NAME, PreferencesMessages.class);\n\t}\n\n\tprivate PreferencesMessages() {\n\t}\n}\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.common/src/org/eclipse/visualvm/launcher/resources/PreferencesMessages.properties",
    "content": "# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLocationPreferencePage_0=Please, select the VisualVM installation\nLocationPreferencePage_1=&VisualVM Executable:\nLocationPreferencePage_2=JDK &Home:\nLocationPreferencePage_6=Invalid VisualVM installation location. Make sure the file selected exists and is indeed a VisualVM\nLocationPreferencePage_7=VisualVM requires a full JDK to run\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.java/.classpath",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classpath>\n\t<classpathentry kind=\"con\" path=\"org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5\"/>\n\t<classpathentry kind=\"con\" path=\"org.eclipse.pde.core.requiredPlugins\"/>\n\t<classpathentry kind=\"src\" path=\"src\"/>\n\t<classpathentry kind=\"output\" path=\"bin\"/>\n</classpath>\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.java/.project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>org.eclipse.visualvm.launcher.java</name>\n\t<comment></comment>\n\t<projects>\n\t</projects>\n\t<buildSpec>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.pde.ManifestBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.pde.SchemaBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t</buildSpec>\n\t<natures>\n\t\t<nature>org.eclipse.pde.PluginNature</nature>\n\t\t<nature>org.eclipse.jdt.core.javanature</nature>\n\t</natures>\n</projectDescription>\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.java/.settings/org.eclipse.jdt.core.prefs",
    "content": "#Thu Oct 13 12:08:17 CEST 2011\neclipse.preferences.version=1\norg.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\norg.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5\norg.eclipse.jdt.core.compiler.compliance=1.5\norg.eclipse.jdt.core.compiler.problem.assertIdentifier=error\norg.eclipse.jdt.core.compiler.problem.enumIdentifier=error\norg.eclipse.jdt.core.compiler.source=1.5\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.java/META-INF/MANIFEST.MF",
    "content": "Manifest-Version: 1.0\nBundle-ManifestVersion: 2\nBundle-Name: VisualVM Launcher - Java\nBundle-SymbolicName: org.eclipse.visualvm.launcher.java;singleton:=true\nBundle-Version: 1.1.1\nBundle-Vendor: Oracle Corporation\nBundle-RequiredExecutionEnvironment: JavaSE-1.6\nRequire-Bundle: org.eclipse.debug.core,\n org.eclipse.visualvm.launcher.common;bundle-version=\"1.1.3\"\nImport-Package: org.eclipse.core.runtime,\n org.eclipse.jdt.internal.launching,\n org.eclipse.jdt.junit.launcher,\n org.eclipse.jdt.launching,\n org.eclipse.visualvm.launcher.api;version=\"1.0.0\"\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.java/build.properties",
    "content": "source.. = src/\noutput.. = bin/\nbin.includes = META-INF/,\\\n               .,\\\n               plugin.xml\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.java/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<?eclipse version=\"3.2\"?>\n<plugin>\n   <extension\n         point=\"org.eclipse.debug.core.launchDelegates\">\n      <launchDelegate\n            delegate=\"org.eclipse.visualvm.launcher.java.VisualVMJavaDelegate\"\n            delegateDescription=\"The VisualVM Launcher supports running and debugging local Java applications and initiating their monitoring in VisualVM\"\n            id=\"org.eclipse.visualvm.launch.java\"\n            modes=\"run,debug\"\n            name=\"VisualVM\"\n            sourceLocatorId=\"org.eclipse.visualvm.launch.core.java.sourceLocator\"\n            sourcePathComputerId=\"org.eclipse.visualvm.launch.core.java.sourcePathComputer\"\n            type=\"org.eclipse.jdt.launching.localJavaApplication\">\n      </launchDelegate>\n      <launchDelegate\n            delegate=\"org.eclipse.visualvm.launcher.java.VisualVMAppletDelegate\"\n            delegateDescription=\"The VisualVM Launcher supports running and debugging applets and initiating their monitoring in VisualVM\"\n            id=\"org.eclipse.visualvm.launch.applet\"\n            modes=\"run,debug\"\n            name=\"VisualVM\"\n            sourceLocatorId=\"org.eclipse.visualvm.launch.core.applet.sourceLocator\"\n            sourcePathComputerId=\"org.eclipse.visualvm.launch.core.applet.sourcePathComputer\"\n            type=\"org.eclipse.jdt.launching.javaApplet\">\n      </launchDelegate>\n      <launchDelegate\n            delegate=\"org.eclipse.visualvm.launcher.java.VisualVMJUnitDelegate\"\n            delegateDescription=\"The VisualVM Launcher supports running and debugging JUnit tests and initiating their monitoring in VisualVM\"\n            id=\"org.eclipse.visualvm.launch.junit\"\n            modes=\"run,debug\"\n            name=\"VisualVM\"\n            sourceLocatorId=\"org.eclipse.visualvm.launch.core.junit.sourceLocator\"\n            sourcePathComputerId=\"org.eclipse.visualvm.launch.core.junit.sourcePathComputer\"\n            type=\"org.eclipse.jdt.junit.launchconfig\">\n      </launchDelegate>\n   </extension>\n\n</plugin>\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.java/src/org/eclipse/visualvm/launcher/java/VisualVMAppletDelegate.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.eclipse.visualvm.launcher.java;\n\nimport java.io.IOException;\n\nimport org.eclipse.core.runtime.CoreException;\nimport org.eclipse.core.runtime.IProgressMonitor;\nimport org.eclipse.debug.core.ILaunch;\nimport org.eclipse.debug.core.ILaunchConfiguration;\nimport org.eclipse.jdt.internal.launching.JavaAppletLaunchConfigurationDelegate;\nimport org.eclipse.jdt.launching.IVMRunner;\nimport org.eclipse.visualvm.launcher.api.VisualVMHelper;\n\n@SuppressWarnings(\"restriction\")\npublic class VisualVMAppletDelegate extends JavaAppletLaunchConfigurationDelegate {\n\tvolatile private long usedId = -1;\n\n\t\n\t/* (non-Javadoc)\n\t * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)\n\t */\n\tpublic synchronized void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {\n\t\tusedId = VisualVMHelper.getNextID();\n\t\tsuper.launch(configuration, mode, launch, monitor);\n\t}\n\n\n\t/* (non-Javadoc)\n\t * @see org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate#getVMArguments(org.eclipse.debug.core.ILaunchConfiguration)\n\t */\n\tpublic String getVMArguments(ILaunchConfiguration configuration) throws CoreException {\n\t\tStringBuffer arguments = new StringBuffer(super.getVMArguments(configuration));\n\t\tfor(String arg : VisualVMHelper.getJvmArgs(usedId)) {\n\t\t\targuments.append(\" \").append(arg);\n\t\t}\n\t\treturn arguments.toString();\n\t}\n\n\t@Override\n\tpublic IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode)\n\t\t\tthrows CoreException {\n\t\ttry {\n\t\t\tVisualVMHelper.openInVisualVM(usedId);\n\t\t} catch (IOException e) {\n\t\t\tVisualVMHelper.logException(e);\n\t\t}\n\t\treturn super.getVMRunner(configuration, mode);\n\t}\n\n}\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.java/src/org/eclipse/visualvm/launcher/java/VisualVMJUnitDelegate.java",
    "content": "package org.eclipse.visualvm.launcher.java;\n\nimport java.io.IOException;\n\nimport org.eclipse.core.runtime.CoreException;\nimport org.eclipse.core.runtime.IProgressMonitor;\nimport org.eclipse.debug.core.ILaunch;\nimport org.eclipse.debug.core.ILaunchConfiguration;\nimport org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationDelegate;\nimport org.eclipse.jdt.launching.IVMRunner;\nimport org.eclipse.visualvm.launcher.api.VisualVMHelper;\n\npublic class VisualVMJUnitDelegate extends JUnitLaunchConfigurationDelegate {\n\tvolatile private long usedId = -1;\n\t\n\t@Override\n\tpublic void launch(ILaunchConfiguration configuration, String mode,\n\t\t\tILaunch launch, IProgressMonitor monitor) throws CoreException {\n\t\tusedId = VisualVMHelper.getNextID();\n\t\tsuper.launch(configuration, mode, launch, monitor);\n\t}\n\n\t@Override\n\tpublic String getVMArguments(ILaunchConfiguration configuration)\n\t\t\tthrows CoreException {\n\t\tStringBuilder args = new StringBuilder(super.getVMArguments(configuration));\n\t\tfor(String arg : VisualVMHelper.getJvmArgs(usedId)) {\n\t\t\targs.append(\" \").append(arg);\n\t\t}\n\t\treturn args.toString();\n\t}\n\n\t@Override\n\tpublic IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode)\n\t\t\tthrows CoreException {\n\t\ttry {\n\t\t\tVisualVMHelper.openInVisualVM(usedId);\n\t\t} catch (IOException e) {\n\t\t\tVisualVMHelper.logException(e);\n\t\t}\n\t\treturn super.getVMRunner(configuration, mode);\n\t}\n}\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.java/src/org/eclipse/visualvm/launcher/java/VisualVMJavaDelegate.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.eclipse.visualvm.launcher.java;\n\nimport java.io.IOException;\n\nimport org.eclipse.core.runtime.CoreException;\nimport org.eclipse.core.runtime.IProgressMonitor;\nimport org.eclipse.debug.core.ILaunch;\nimport org.eclipse.debug.core.ILaunchConfiguration;\nimport org.eclipse.jdt.launching.IVMRunner;\nimport org.eclipse.jdt.launching.JavaLaunchDelegate;\nimport org.eclipse.visualvm.launcher.api.VisualVMHelper;\n\npublic class VisualVMJavaDelegate extends JavaLaunchDelegate {\n\tvolatile private long usedId = -1;\n\t\n\t@Override\n\tpublic void launch(ILaunchConfiguration configuration, String mode,\n\t\t\tILaunch launch, IProgressMonitor monitor) throws CoreException {\n\t\tusedId = VisualVMHelper.getNextID();\n\t\tsuper.launch(configuration, mode, launch, monitor);\n\t}\n\n\t@Override\n\tpublic String getVMArguments(ILaunchConfiguration configuration)\n\t\t\tthrows CoreException {\n\t\tStringBuilder args = new StringBuilder(super.getVMArguments(configuration));\n\t\tfor(String arg : VisualVMHelper.getJvmArgs(usedId)) {\n\t\t\targs.append(\" \").append(arg);\n\t\t}\n\t\treturn args.toString();\n\t}\n\n\t@Override\n\tpublic IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode)\n\t\t\tthrows CoreException {\n\t\ttry {\n\t\t\tVisualVMHelper.openInVisualVM(usedId);\n\t\t} catch (IOException e) {\n\t\t\tVisualVMHelper.logException(e);\n\t\t}\n\t\treturn super.getVMRunner(configuration, mode);\n\t}\n\n}\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.pde/.classpath",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classpath>\n\t<classpathentry kind=\"con\" path=\"org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5\"/>\n\t<classpathentry exported=\"true\" kind=\"con\" path=\"org.eclipse.pde.core.requiredPlugins\"/>\n\t<classpathentry kind=\"src\" path=\"src\"/>\n\t<classpathentry kind=\"output\" path=\"bin\"/>\n</classpath>\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.pde/.project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>org.eclipse.visualvm.launcher.pde</name>\n\t<comment></comment>\n\t<projects>\n\t</projects>\n\t<buildSpec>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.pde.ManifestBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.pde.SchemaBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t</buildSpec>\n\t<natures>\n\t\t<nature>org.eclipse.pde.PluginNature</nature>\n\t\t<nature>org.eclipse.jdt.core.javanature</nature>\n\t</natures>\n</projectDescription>\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.pde/.settings/org.eclipse.jdt.core.prefs",
    "content": "eclipse.preferences.version=1\norg.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\norg.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate\norg.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5\norg.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve\norg.eclipse.jdt.core.compiler.compliance=1.5\norg.eclipse.jdt.core.compiler.debug.lineNumber=generate\norg.eclipse.jdt.core.compiler.debug.localVariable=generate\norg.eclipse.jdt.core.compiler.debug.sourceFile=generate\norg.eclipse.jdt.core.compiler.problem.assertIdentifier=error\norg.eclipse.jdt.core.compiler.problem.enumIdentifier=error\norg.eclipse.jdt.core.compiler.source=1.5\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.pde/META-INF/MANIFEST.MF",
    "content": "Manifest-Version: 1.0\nBundle-ManifestVersion: 2\nBundle-Name: VisualVM Launcher - PDE\nBundle-SymbolicName: org.eclipse.visualvm.launcher.pde;singleton:=true\nBundle-Version: 1.1.1\nBundle-Vendor: Oracle Corporation\nBundle-RequiredExecutionEnvironment: JavaSE-1.6\nRequire-Bundle: org.eclipse.visualvm.launcher.common;bundle-version=\"1.1.3\",\n org.eclipse.debug.core\nImport-Package: org.eclipse.core.runtime,\n org.eclipse.jdt.junit.launcher,\n org.eclipse.jdt.launching,\n org.eclipse.pde.launching,\n org.eclipse.pde.ui.launcher,\n org.eclipse.visualvm.launcher.api\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.pde/build.properties",
    "content": "source.. = src/\noutput.. = bin/\nbin.includes = META-INF/,\\\n               .,\\\n               plugin.xml\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.pde/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<?eclipse version=\"3.2\"?>\n<plugin>\n   <extension\n         point=\"org.eclipse.debug.core.launchDelegates\">\n      <launchDelegate\n            delegate=\"org.eclipse.visualvm.launcher.pde.VisualVMPDEDelegate\"\n            delegateDescription=\"The VisualVM Launcher supports running and debugging PDE applications and initiating their monitoring in VisualVM\"\n            id=\"org.eclipse.visualvm.launcher.pde\"\n            modes=\"run,debug\"\n            name=\"VisualVM\"\n            sourceLocatorId=\"org.eclipse.visualvm.launch.core.pde.sourceLocator\"\n            sourcePathComputerId=\"org.eclipse.visualvm.launch.core.pde.sourcePathComputer\"\n            type=\"org.eclipse.pde.ui.RuntimeWorkbench\">\n      </launchDelegate>\n      <launchDelegate\n            delegate=\"org.eclipse.visualvm.launcher.pde.VisualVMJUnitPluginDelegate\"\n            delegateDescription=\"The VisualVM Launcher supports running and debugging JUnit tests and initiating their monitoring in VisualVM\"\n            id=\"org.eclipse.visualvm.launch.junitplugin\"\n            modes=\"run,debug\"\n            name=\"VisualVM\"\n            sourceLocatorId=\"org.eclipse.visualvm.launch.core.junitplugin.sourceLocator\"\n            sourcePathComputerId=\"org.eclipse.visualvm.launch.core.junitplugin.sourcePathComputer\"\n            type=\"org.eclipse.pde.ui.JunitLaunchConfig\">\n      </launchDelegate>\n   </extension>\n\n</plugin>\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.pde/src/org/eclipse/visualvm/launcher/pde/VisualVMJUnitPluginDelegate.java",
    "content": "package org.eclipse.visualvm.launcher.pde;\n\nimport java.io.IOException;\n\nimport org.eclipse.core.runtime.CoreException;\nimport org.eclipse.core.runtime.IProgressMonitor;\nimport org.eclipse.debug.core.ILaunch;\nimport org.eclipse.debug.core.ILaunchConfiguration;\nimport org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationDelegate;\nimport org.eclipse.jdt.launching.IVMRunner;\nimport org.eclipse.visualvm.launcher.api.VisualVMHelper;\n\npublic class VisualVMJUnitPluginDelegate extends JUnitLaunchConfigurationDelegate {\n\tvolatile private long usedId = -1;\n\t\n\t@Override\n\tpublic void launch(ILaunchConfiguration configuration, String mode,\n\t\t\tILaunch launch, IProgressMonitor monitor) throws CoreException {\n\t\tusedId = VisualVMHelper.getNextID();\n\t\tsuper.launch(configuration, mode, launch, monitor);\n\t}\n\n\t@Override\n\tpublic String getVMArguments(ILaunchConfiguration configuration)\n\t\t\tthrows CoreException {\n\t\tStringBuilder args = new StringBuilder(super.getVMArguments(configuration));\n\t\tfor(String arg : VisualVMHelper.getJvmArgs(usedId)) {\n\t\t\targs.append(\" \").append(arg);\n\t\t}\n\t\treturn args.toString();\n\t}\n\n\t@Override\n\tpublic IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode)\n\t\t\tthrows CoreException {\n\t\ttry {\n\t\t\tVisualVMHelper.openInVisualVM(usedId);\n\t\t} catch (IOException e) {\n\t\t\tVisualVMHelper.logException(e);\n\t\t}\n\t\treturn super.getVMRunner(configuration, mode);\n\t}\n}\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.pde/src/org/eclipse/visualvm/launcher/pde/VisualVMPDEDelegate.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.eclipse.visualvm.launcher.pde;\n\nimport java.io.IOException;\n\nimport org.eclipse.core.runtime.CoreException;\nimport org.eclipse.core.runtime.IProgressMonitor;\nimport org.eclipse.debug.core.ILaunch;\nimport org.eclipse.debug.core.ILaunchConfiguration;\nimport org.eclipse.jdt.launching.IVMRunner;\nimport org.eclipse.pde.launching.EclipseApplicationLaunchConfiguration;\nimport org.eclipse.visualvm.launcher.api.VisualVMHelper;\n\npublic class VisualVMPDEDelegate extends EclipseApplicationLaunchConfiguration {\n\tvolatile private long usedId = -1;\n\t\n\t@Override\n\tpublic void launch(ILaunchConfiguration configuration, String mode,\n\t\t\tILaunch launch, IProgressMonitor monitor) throws CoreException {\n\t\tusedId = VisualVMHelper.getNextID();\n\t\tsuper.launch(configuration, mode, launch, monitor);\n\t}\n\n\t@Override\n\tpublic String[] getVMArguments(ILaunchConfiguration configuration)\n\t\t\tthrows CoreException {\n\t\tString[] origArgs = super.getVMArguments(configuration);\n\t\tString[] visualvmArgs = VisualVMHelper.getJvmArgs(usedId);\n\t\tString[] newArgs = new String[origArgs.length + visualvmArgs.length];\n\t\tSystem.arraycopy(origArgs, 0, newArgs, 0, origArgs.length);\n\t\tSystem.arraycopy(visualvmArgs, 0, newArgs, origArgs.length, visualvmArgs.length);\n\t\treturn newArgs;\n\t}\n\n\t@Override\n\tpublic IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode)\n\t\t\tthrows CoreException {\n\t\ttry {\n\t\t\tVisualVMHelper.openInVisualVM(usedId);\n\t\t} catch (IOException e) {\n\t\t\tVisualVMHelper.logException(e);\n\t\t}\n\t\treturn super.getVMRunner(configuration, mode);\n\t}\n\n}\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.update/.project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>VisualVM Launcher Update Site</name>\n\t<comment></comment>\n\t<projects>\n\t</projects>\n\t<buildSpec>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.pde.UpdateSiteBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t</buildSpec>\n\t<natures>\n\t\t<nature>org.eclipse.pde.UpdateSiteNature</nature>\n\t</natures>\n</projectDescription>\n"
  },
  {
    "path": "integrations/eclipse/org.eclipse.visualvm.launcher.update/site.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<site>\n   <feature url=\"features/VisualVM_Launcher_1.1.3.jar\" id=\"VisualVM_Launcher\" version=\"1.1.3\"/>\n</site>\n"
  },
  {
    "path": "integrations/vscode/.eslintrc.js",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n👋 Hi! This file was autogenerated by tslint-to-eslint-config.\nhttps://github.com/typescript-eslint/tslint-to-eslint-config\n\nIt represents the closest reasonable ESLint configuration to this\nproject's original TSLint configuration.\n\nWe recommend eventually switching this configuration to extend from\nthe recommended rulesets in typescript-eslint.\nhttps://github.com/typescript-eslint/tslint-to-eslint-config/blob/master/docs/FAQs.md\n\nHappy linting! 💖\n*/\n\n/* eslint-disable @typescript-eslint/naming-convention */\n\n/**@type {import('eslint').ESLint.ConfigData}*/\nmodule.exports = {\n    \"env\": {\n        \"browser\": true,\n        \"es6\": true,\n        \"node\": true\n    },\n    \"parser\": \"@typescript-eslint/parser\",\n    \"parserOptions\": {\n        \"project\": \"tsconfig.eslint.json\",\n        \"tsconfigRootDir\": __dirname,\n        \"sourceType\": \"module\"\n    },\n    \"plugins\": [\n        \"@typescript-eslint\"\n    ],\n    \"root\": true,\n    \"rules\": {\n        \"@typescript-eslint/member-delimiter-style\": [\n            \"warn\",\n            {\n                \"multiline\": {\n                    \"delimiter\": \"semi\",\n                    \"requireLast\": true\n                },\n                \"singleline\": {\n                    \"delimiter\": \"semi\",\n                    \"requireLast\": false\n                }\n            }\n        ],\n        \"@typescript-eslint/naming-convention\": \"off\",\n        \"@typescript-eslint/no-unused-expressions\": \"warn\",\n        \"@typescript-eslint/semi\": [\n            \"warn\",\n            \"always\"\n        ],\n        \"curly\": \"off\",\n        \"eqeqeq\": [\n            \"warn\",\n            \"always\"\n        ],\n        \"no-redeclare\": \"warn\",\n        \"no-throw-literal\": \"warn\",\n        \"no-unused-expressions\": \"off\",\n        \"semi\": \"off\"\n    }\n};\n"
  },
  {
    "path": "integrations/vscode/.gitignore",
    "content": "dist/\nnode_modules/\nvisualvm-vscode-*.vsix\nLICENSE.txt\n.vscode-test/\noutput\nmochawesome-report\n\n"
  },
  {
    "path": "integrations/vscode/.nvmrc",
    "content": "v14.16.0"
  },
  {
    "path": "integrations/vscode/.vscode/launch.json",
    "content": "// A launch configuration that compiles the extension and then opens it inside a new window\n// Use IntelliSense to learn about possible attributes.\n// Hover to view descriptions of existing attributes.\n// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387\n{\n\t\"version\": \"0.2.0\",\n\t\"configurations\": [\n\t\t{\n\t\t\t\"name\": \"Run Extension\",\n\t\t\t\"type\": \"extensionHost\",\n\t\t\t\"request\": \"launch\",\n\t\t\t\"runtimeExecutable\": \"${execPath}\",\n\t\t\t\"args\": [\n\t\t\t\t\"--extensionDevelopmentPath=${workspaceFolder}\"\n\t\t\t],\n\t\t\t\"outFiles\": [\n\t\t\t\t\"${workspaceFolder}/out/**/*.js\",\n\t\t\t\t\"${workspaceFolder}/dist/**/*.js\"\n\t\t\t],\n\t\t\t\"preLaunchTask\": \"npm: compile\"\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "integrations/vscode/.vscode/settings.json",
    "content": "// Place your settings in this file to overwrite default and user settings.\n{\n    \"files.exclude\": {\n        \"out\": false // set this to true to hide the \"out\" folder with the compiled JS files\n    },\n    \"search.exclude\": {\n        \"out\": true // set this to false to include \"out\" folder in search results\n    },\n    // Turn off tsc task auto detection since we have the necessary tasks as npm scripts\n    \"typescript.tsc.autoDetect\": \"off\"\n}"
  },
  {
    "path": "integrations/vscode/.vscode/tasks.json",
    "content": "// See https://go.microsoft.com/fwlink/?LinkId=733558\n// for the documentation about the tasks.json format\n{\n\t\"version\": \"2.0.0\",\n\t\"tasks\": [\n\t\t{\n\t\t\t\"type\": \"npm\",\n\t\t\t\"script\": \"watch\",\n\t\t\t\"problemMatcher\": \"$tsc-watch\",\n\t\t\t\"isBackground\": true,\n\t\t\t\"presentation\": {\n\t\t\t\t\"reveal\": \"never\"\n\t\t\t},\n\t\t\t\"group\": {\n\t\t\t\t\"kind\": \"build\",\n\t\t\t\t\"isDefault\": true\n\t\t\t}\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "integrations/vscode/.vscodeignore",
    "content": ".vscode/**\nnode_modules/**\nout/**\nsrc/**\n.gitignore\nwebpack.config.js\n**/tsconfig*.json\n**/tslint.json\n**/*.map\n**/*.ts\n"
  },
  {
    "path": "integrations/vscode/CHANGELOG.md",
    "content": "# Change Log\n\n## Version 1.0.1\n* npm vulnerability fixed\n\n## Version 1.0.0\n* First stable release\n* [GH-598](https://github.com/oracle/visualvm/issues/598): (bugfix) VSCode Extension - Source Roots don't work in VSCode extension\n\n## Version 0.2.0\n* [GH-570](https://github.com/oracle/visualvm/issues/570): (enhancement) VSCode Extension - add custom cpu profiler filter\n* [GH-572](https://github.com/oracle/visualvm/issues/572): (bugfix) VSCode Extension - JDK Path with Spaces not working\n* [GH-576](https://github.com/oracle/visualvm/issues/576): (bugfix) VS Code Extension - Usability Issues on macOS\n* [GH-581](https://github.com/oracle/visualvm/issues/581): (bugfix) Conflict between vscode visualvm extension and run test with coverage\n\n## Version 0.1.0\n* Initial release\n"
  },
  {
    "path": "integrations/vscode/README.md",
    "content": "# VisualVM for VS Code\n\nThis extension integrates the [VisualVM](https://visualvm.github.io) monitoring and troubleshooting tool into Visual Studio Code (VS Code).\n\n![VisualVM View](images/visualvm_view.png)\n\n## Features\n* Easy installation of VisualVM.\n* When starting an application from VS Code:\n  - The application process is configured to display its folder name in VisualVM.\n  - The application process PID is detected to invoke VisualVM actions when needed.\n  - When started, the application process can be automatically opened in VisualVM.\n* Shortcuts for VisualVM actions such as Thread dump, Heap dump, Start sampling and Start flight recording are available in a dedicated view within VS Code.\n* The CPU Sampler filter can be automatically configured to include only application classes.\n* Two-way integration: the Go to Source action in VisualVM opens the source code in VS Code.\n\n## Requirements\n\nInstall the following in order to use this extension:\n* VisualVM 2.1+ (we recommend using the latest version of VisualVM; you can [install directly from within VS Code](#configuring-visualvm)).\n* Any JDK 8+ to run VisualVM and detect running processes using `jps`.\n\nEither of these Java language servers must be installed to integrate VisualVM with application startup, to support application class filtering, and to provide the Go to Source feature:\n\n* [Language Server for Java by Apache NetBeans](https://marketplace.visualstudio.com/items?itemName=ASF.apache-netbeans-java)\n* [Extension Pack for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack)\n\nThe extension also tightly integrates with the [Tools for Micronaut® framework](https://marketplace.visualstudio.com/items?itemName=oracle-labs-graalvm.micronaut-tools) to provide the best monitoring and profiling experience. For example:\n* The VisualVM view can be easily displayed in the Micronaut Tools activity.\n* CPU Sampler is configured for the selected Graal Cloud Native (GCN) application subproject.\n* The Go to Source feature is configured for the selected GCN application subproject.\n\n## Quick Start\nFollow these steps to start using VisualVM with VS Code:\n\n1. Install the **VisualVM for VS Code** extension.\n2. Install **Language Server for Java by Apache NetBeans** or **Extension Pack for Java** (or both).\n3. Open your application sources. Make sure it is configured correctly before integrating it with VisualVM.\n4. Click **Download Latest VisualVM** in the VisualVM view and complete the required steps.\n5. Invoke the **Configure** action displayed for the *When started* node in the *VisualVM* view, and select **Open Process**.\n6. Start the application using the **Run Without Debugging** or **Start Debugging** action.\n\nThe application starts and its process is opened in VisualVM and displayed using the name of the source code folder within VS Code.\n\nThe Go to Source action in the VisualVM views, such as the Heap Viewer, CPU or Memory Sampler/Profiler results, opens the associated source code within VS Code.\n\n## Configuring VisualVM\n\nTo download the latest VisualVM release from [https://visualvm.github.io](https://visualvm.github.io), use the **Download Latest VisualVM** action. \nDepending on the host OS, this will either download a ZIP archive or a macOS disk image (.dmg) file. \nThe ZIP archive will be automatically extracted and registered for the extension. \nThe macOS disk image must be installed and registered manually (see the next paragraph).\n\nIf an existing local VisualVM installation is already available on the system, or after manually installing a macOS disk image, use the **Select Local VisualVM Installation** action and point to the VisualVM installation directory. \nThe extension supports **VisualVM 2.1+**, or the corresponding GraalVM component (select the GraalVM installation directory). \nWe recommend using the latest version of VisualVM.\n\nTo manually register an existing local VisualVM installation, or to configure a specific VisualVM installation for the workspace, use the `visualvm.installation.visualvmPath` property to point to the VisualVM installation directory.\n\nCustom VisualVM startup parameters (such as `--userdir`) including VM arguments (such as `-Xmx...`) can be defined using the `visualvm.startup.visualvmParameters` property.\n\nBy default, VisualVM runs using a defined/automatically found local JDK (see the [Configuring a JDK](#configuring-a-jdk) section). \nTo define a custom JDK for running VisualVM, set the `visualvm.startup.useJdkPathForVisualvm` property to `false` and use the `--jdkhome` VisualVM startup parameter.\n\n## Configuring a JDK\n\nThe extension requires a JDK for:\n\n* Running VisualVM (if not disabled, see the [Configuring VisualVM](#configuring-visualvm) section).\n* To detect locally running processes using the `jps` utility, either when starting an application, or for a manual process selection.\n* For configuring the JDK source roots used by the `Go to Source` feature.\n\nThe extension can use any JDK to run the VisualVM tool and detect Java processes. \nHowever, it should match the JDK running a monitored application in order to correctly support Go to Source for the JDK classes. \nThe JDK is located by searching through the following properties in order:\n* Properties: `netbeans.jdkhome`, `java.jdt.ls.java.home`, `java.home`, `graalvm.home`.\n* Environment variables: `JDK_HOME`, `JAVA_HOME`.\n\nTo override the JDK that was selected automatically, or to configure a specific JDK for the workspace, set the `visualvm.java.jdkPath` property to point to a local JDK installation directory (either in the VS Code Settings view, or manually in _settings.json_).\n\n## VisualVM Actions in VS Code\n\n### Start VisualVM\n* *Start VisualVM* (action in the VisualVM view toolbar) starts the VisualVM, or brings its window to the front if it is already running.\n\n### Process Node\n* *Select Process*: Shows a list of all running processes available for monitoring, excluding those already being monitored.\n\n* *Show in VisualVM*: Opens the currently selected process in VisualVM, and preselects the defined view. Use the `visualvm.behavior.preselectProcessView` property to define the view to be preselected (use `Current` for no change).\n\n* *Stop Monitoring*: Clears the currently selected process, but does not stop the process or its monitoring in the VisualVM tool.\n\n### When Started Node\n* *Configure*: Defines the action to be taken when a new application process is started by VS Code. When configured, the process can be automatically opened in VisualVM, and a preconfigured sampling or flight recording session can be started.\n\n  > Note: The *When started* node is only displayed if the automatic application process selection is enabled (`visualvm.integration.automaticallySelectProjectProcess` property is set to `true`), and no process has been selected yet, or it has not been selected manually using the *Select Process* action.\n\n### Thread Dump Node\n* *Take Thread Dump*: Takes a thread dump from a monitored process, and selects its view in VisualVM.\n\n### Heap Dump Node\n* *Take Heap Dump*: Takes a heap dump from a monitored process, and selects its view in VisualVM.\n\n### CPU Sampler Node\n* *Start CPU Sampling*: Starts a new CPU sampling session for a monitored process, and selects its view in VisualVM. The sampling session settings are defined by the *Filter* and *Sampling rate* subnodes.\n\n* *Take Snapshot of Sampler Results*: Takes a snapshot of the collected data, and selects its view in VisualVM.\n\n* *Stop Sampling*: Terminates the current sampling session, and selects its view in VisualVM.\n\n### Memory Sampler Node\n* *Start Memory Sampling*: Starts a new memory sampling session for the monitored process, and selects its view in VisualVM. The sampling session settings are defined by the *Sampling rate* subnode.\n\n* *Take Snapshot of Sampler Results*: Takes a snapshot of the collected data, and selects its view in VisualVM.\n\n* *Stop Sampling*: Terminates the current sampling session, and selects its view in VisualVM.\n\n### JFR Node\n* *Start Flight Recording*: Starts a new flight recording for a monitored process. The flight recorder preset to be used for the recording is defined by the *Settings* subnode.\n\n* *Dump Flight Recording Data*: Dumps the data for the current flight recording, and selects its view in VisualVM.\n\n* *Stop Flight Recording*: Terminates the current flight recording.\n\n## Monitoring Multiple Processes Simultaneously\n\nWhilst monitoring multiple processes concurrently is not a typical scenario, it is supported by the VisualVM for VS Code extension.\n\nTo start monitoring another process using VisualVM, start another application process using the *Run Without Debugging* or *Start Debugging* action, or use the **VisualVM: Select Process** command from the Command Palette.\n\n> Note: The *When started* node is not available for a subsequent monitored process, and its respective *Process* node is removed immediately after monitoring of the process has been stopped.\n\n## Troubleshooting\n\nThe VisualVM for VS Code extension customizes the way VS Code runs an application by adding extra VM arguments to the launch configuration. \nIf the application process fails to start, it may be required to disable these customizations by setting the following properties to `false`:\n\n* `visualvm.integration.automaticallySelectProjectProcess`\n* `visualvm.integration.customizeDisplayNameForProjectProcess`\n\nThe extension also controls the VisualVM startup parameters. \nIf the VisualVM fails to start, disable or tweak the following properties:\n\n* `visualvm.startup.visualvmParameters`\n* `visualvm.startup.useJdkPathForVisualvm`\n* `visualvm.integration.enableGoToSource`\n\nIn case VisualVM fails to open source code using the `Go to Source` action in VS Code, or it opens another VS Code window, configure the following property:\n\n* `visualvm.integration.visualStudioCodeParameters`\n\nFor detailed analysis of any issues encountered when using the extension, see the *VisualVM for VS Code* log in the VS Code *Output* view. \nAdditionally, see the logs of any other extensions involved, or the *Extension Host* log.\n\nFor VisualVM specific troubleshooting, refer to the [VisualVM Troubleshooting Guide](https://visualvm.github.io/troubleshooting.html).\n\n\n## Settings\n\n| Name | Description | Default Value |\n|---|---|---|\n| `visualvm.java.jdkPath` | Path to a local JDK installation directory (leave empty to find automatically) |  |\n| `visualvm.startup.useJdkPathForVisualvm` | Use a defined/automatically found local JDK installation to run VisualVM (not applicable if the selected VisualVM installation is a GraalVM component) | `true` |\n| `visualvm.installation.visualvmPath` | Path to a local VisualVM 2.1+ installation directory (we recommend using the latest version of VisualVM) |  |\n| `visualvm.startup.visualvmParameters` | Optional parameters for starting VisualVM (`--userdir`, `-J-Xmx`, and so on) |  |\n| `visualvm.behavior.visualvmWindowToFront` | Bring a VisualVM window to front when a VisualVM action is invoked from within VS Code | `true` |\n| `visualvm.behavior.preselectProcessView` | Preselected view for a process shown in VisualVM (either the Show in VisualVM action, or the Open Process action when started) | Monitor |\n| `visualvm.integration.automaticallySelectProjectProcess` | Automatically select a started application process for monitoring | `true` |\n| `visualvm.integration.customizeDisplayNameForProjectProcess` | Configure a started application process to display its folder name in VisualVM | `true` |\n| `visualvm.integration.enableGoToSource` | Enable opening source code from VisualVM results in VS Code using the Go to Source action | `true` |\n| `visualvm.integration.visualStudioCodeParameters` | Optional parameters for invoking VS Code launcher to open source code from VisualVM (`--user-data-dir`, `--extensions-dir`, and so on) |  |\n\n## Provide Feedback or Seek Help\n\n* [Request a feature](https://github.com/oracle/visualvm/issues/new?labels=enhancement)\n* [File a bug](https://github.com/oracle/visualvm/issues/new?labels=bug)\n\n## Contributing\n\nWe highly appreciate any feedback! Please let us know your ideas, missing features, or bugs found. Either [file a RFE/bug](https://github.com/oracle/visualvm/issues/new/choose) or [leave us a message](https://visualvm.github.io/feedback.html). For legal reasons, we cannot accept external pull requests. See \n[CONTRIBUTING](https://github.com/oracle/visualvm/blob/master/CONTRIBUTING.md)\nfor details.\n\n## Security\n\nPlease consult the [security guide](https://github.com/oracle/visualvm/blob/master/SECURITY.md) for our responsible security vulnerability disclosure process\n\n## License\n\nCopyright (c) 2017, 2024 Oracle and/or its affiliates.\nReleased under the GNU General Public License, version 2, with the Classpath Exception.\n\n## Release Notes\n\nSee the [CHANGELOG](https://github.com/oracle/visualvm/blob/master/integrations/vscode/CHANGELOG.md)."
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/.gitignore",
    "content": "Thumbs.db\n.DS_Store\n.gradle\nbuild/\ntarget/\nout/\n.micronaut/\n.idea\n*.iml\n*.ipr\n*.iws\n.project\n.settings\n.classpath\n.factorypath\n"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/.mvn/wrapper/maven-wrapper.properties",
    "content": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#   https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\ndistributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip\nwrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar\n"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        https://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       https://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/NOTICE",
    "content": "Copyright (c) 2024, Oracle and/or its affiliates.\n"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/README.md",
    "content": "## Micronaut 4.2.1 Documentation\n\n- [User Guide](https://docs.micronaut.io/4.2.1/guide/)\n- [API Reference](https://docs.micronaut.io/4.2.1/api/)\n- [Configuration Reference](https://docs.micronaut.io/4.2.1/guide/configurationreference.html)\n- [Micronaut Guides](https://guides.micronaut.io/)\n---\n- [Micronaut Maven Plugin documentation](https://micronaut-projects.github.io/micronaut-maven-plugin/latest/)\n## Feature http-client documentation\n\n- [Micronaut HTTP Client documentation](https://docs.micronaut.io/latest/guide/index.html#nettyHttpClient)\n\n\n## Feature maven-enforcer-plugin documentation\n\n- [https://maven.apache.org/enforcer/maven-enforcer-plugin/](https://maven.apache.org/enforcer/maven-enforcer-plugin/)\n\n\n## Feature serialization-jackson documentation\n\n- [Micronaut Serialization Jackson Core documentation](https://micronaut-projects.github.io/micronaut-serialization/latest/guide/)\n\n\n"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/lib/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright 2024 Oracle and/or its affiliates\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    https://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <groupId>com.example</groupId>\n  <artifactId>lib</artifactId>\n  <version>1.0-SNAPSHOT</version>\n  <packaging>jar</packaging>\n\n  <parent>\n    <groupId>com.example</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>1.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <packaging>jar</packaging>\n    <jdk.version>17</jdk.version>\n    <release.version>17</release.version>\n    <micronaut.version>4.2.1-oracle-00001</micronaut.version>\n    <micronaut-maven-plugin.version>4.3.1</micronaut-maven-plugin.version>\n  </properties>\n\n  <repositories>\n    <repository>\n      <id>central</id>\n      <url>https://repo.maven.apache.org/maven2</url>\n    </repository>\n    \n    <repository>\n      <id>gcn</id>\n      <url>https://maven.oracle.com/public</url>\n    </repository>\n  </repositories>\n\n  <dependencyManagement>\n    <dependencies>\n    <dependency>\n      <groupId>cloud.graal.gcn</groupId>\n      <artifactId>gcn-bom</artifactId>\n      <version>4.2.1.3</version>\n      <type>pom</type>\n      <scope>import</scope>\n    </dependency>\n    </dependencies>\n  </dependencyManagement>\n  <dependencies>\n    <dependency>\n      <groupId>io.micronaut</groupId>\n      <artifactId>micronaut-inject</artifactId>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>io.micronaut.validation</groupId>\n      <artifactId>micronaut-validation</artifactId>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>io.micronaut</groupId>\n      <artifactId>micronaut-http-client</artifactId>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>io.micronaut</groupId>\n      <artifactId>micronaut-http-server-netty</artifactId>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>io.micronaut.serde</groupId>\n      <artifactId>micronaut-serde-jackson</artifactId>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>ch.qos.logback</groupId>\n      <artifactId>logback-classic</artifactId>\n      <scope>runtime</scope>\n    </dependency>\n    <dependency>\n      <groupId>io.micronaut.test</groupId>\n      <artifactId>micronaut-test-junit5</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.junit.jupiter</groupId>\n      <artifactId>junit-jupiter-api</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.junit.jupiter</groupId>\n      <artifactId>junit-jupiter-engine</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n  <build>\n\n    <resources>\n      <resource>\n        <directory>${basedir}/src/main/resources</directory>\n      </resource>\n    </resources>\n\n    <plugins>\n      <plugin>\n        <groupId>com.google.cloud.tools</groupId>\n        <artifactId>jib-maven-plugin</artifactId>\n        <configuration>\n          <to>\n            <image>${project.name}</image>\n          </to>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-enforcer-plugin</artifactId>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-compiler-plugin</artifactId>\n        <configuration>\n          <!-- Uncomment to enable incremental compilation -->\n          <!-- <useIncrementalCompilation>false</useIncrementalCompilation> -->\n\n          <annotationProcessorPaths combine.children=\"append\">\n            <path>\n              <groupId>io.micronaut</groupId>\n              <artifactId>micronaut-http-validation</artifactId>\n              <version>${micronaut.core.version}</version>\n            </path>\n            <path>\n              <groupId>io.micronaut.serde</groupId>\n              <artifactId>micronaut-serde-processor</artifactId>\n              <version>${micronaut.serialization.version}</version>\n            </path>\n          </annotationProcessorPaths>\n          <compilerArgs>\n            <arg>-Amicronaut.processing.group=com.example</arg>\n            <arg>-Amicronaut.processing.module=lib</arg>\n          </compilerArgs>\n        </configuration>\n      </plugin>\n    </plugins>\n  </build>\n\n</project>\n"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/lib/src/main/java/com/example/.gitkeep",
    "content": ""
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/lib/src/main/resources/.gitkeep",
    "content": ""
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/micronaut-cli.yml",
    "content": "applicationType: default\ndefaultPackage: com.example\ntestFramework: junit\nsourceLanguage: java\nbuildTool: maven\nfeatures: [app-name, gcn-bom, gcn-license, gcn-oci-cloud-app, graalvm, http-client, java, java-application, junit, logback, maven, maven-enforcer-plugin, micronaut-http-validation, netty-server, properties, readme, serialization-jackson, shade]\n"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/mvnw",
    "content": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#    https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n# ----------------------------------------------------------------------------\n\n# ----------------------------------------------------------------------------\n# Apache Maven Wrapper startup batch script, version 3.1.1\n#\n# Required ENV vars:\n# ------------------\n#   JAVA_HOME - location of a JDK home dir\n#\n# Optional ENV vars\n# -----------------\n#   MAVEN_OPTS - parameters passed to the Java VM when running Maven\n#     e.g. to debug Maven itself, use\n#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n# ----------------------------------------------------------------------------\n\nif [ -z \"$MAVEN_SKIP_RC\" ] ; then\n\n  if [ -f /usr/local/etc/mavenrc ] ; then\n    . /usr/local/etc/mavenrc\n  fi\n\n  if [ -f /etc/mavenrc ] ; then\n    . /etc/mavenrc\n  fi\n\n  if [ -f \"$HOME/.mavenrc\" ] ; then\n    . \"$HOME/.mavenrc\"\n  fi\n\nfi\n\n# OS specific support.  $var _must_ be set to either true or false.\ncygwin=false;\ndarwin=false;\nmingw=false\ncase \"`uname`\" in\n  CYGWIN*) cygwin=true ;;\n  MINGW*) mingw=true;;\n  Darwin*) darwin=true\n    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home\n    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html\n    if [ -z \"$JAVA_HOME\" ]; then\n      if [ -x \"/usr/libexec/java_home\" ]; then\n        JAVA_HOME=\"`/usr/libexec/java_home`\"; export JAVA_HOME\n      else\n        JAVA_HOME=\"/Library/Java/Home\"; export JAVA_HOME\n      fi\n    fi\n    ;;\nesac\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  if [ -r /etc/gentoo-release ] ; then\n    JAVA_HOME=`java-config --jre-home`\n  fi\nfi\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched\nif $cygwin ; then\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=`cygpath --path --unix \"$CLASSPATH\"`\nfi\n\n# For Mingw, ensure paths are in UNIX format before anything is touched\nif $mingw ; then\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=\"`(cd \"$JAVA_HOME\"; pwd)`\"\nfi\n\nif [ -z \"$JAVA_HOME\" ]; then\n  javaExecutable=\"`which javac`\"\n  if [ -n \"$javaExecutable\" ] && ! [ \"`expr \\\"$javaExecutable\\\" : '\\([^ ]*\\)'`\" = \"no\" ]; then\n    # readlink(1) is not available as standard on Solaris 10.\n    readLink=`which readlink`\n    if [ ! `expr \"$readLink\" : '\\([^ ]*\\)'` = \"no\" ]; then\n      if $darwin ; then\n        javaHome=\"`dirname \\\"$javaExecutable\\\"`\"\n        javaExecutable=\"`cd \\\"$javaHome\\\" && pwd -P`/javac\"\n      else\n        javaExecutable=\"`readlink -f \\\"$javaExecutable\\\"`\"\n      fi\n      javaHome=\"`dirname \\\"$javaExecutable\\\"`\"\n      javaHome=`expr \"$javaHome\" : '\\(.*\\)/bin'`\n      JAVA_HOME=\"$javaHome\"\n      export JAVA_HOME\n    fi\n  fi\nfi\n\nif [ -z \"$JAVACMD\" ] ; then\n  if [ -n \"$JAVA_HOME\"  ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n      # IBM's JDK on AIX uses strange locations for the executables\n      JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n      JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n  else\n    JAVACMD=\"`\\\\unset -f command; \\\\command -v java`\"\n  fi\nfi\n\nif [ ! -x \"$JAVACMD\" ] ; then\n  echo \"Error: JAVA_HOME is not defined correctly.\" >&2\n  echo \"  We cannot execute $JAVACMD\" >&2\n  exit 1\nfi\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  echo \"Warning: JAVA_HOME environment variable is not set.\"\nfi\n\n# traverses directory structure from process work directory to filesystem root\n# first directory with .mvn subdirectory is considered project base directory\nfind_maven_basedir() {\n  if [ -z \"$1\" ]\n  then\n    echo \"Path not specified to find_maven_basedir\"\n    return 1\n  fi\n\n  basedir=\"$1\"\n  wdir=\"$1\"\n  while [ \"$wdir\" != '/' ] ; do\n    if [ -d \"$wdir\"/.mvn ] ; then\n      basedir=\"$wdir\"\n      break\n    fi\n    # workaround for JBEAP-8937 (on Solaris 10/Sparc)\n    if [ -d \"${wdir}\" ]; then\n      wdir=`cd \"$wdir/..\"; pwd`\n    fi\n    # end of workaround\n  done\n  printf '%s' \"$(cd \"$basedir\"; pwd)\"\n}\n\n# concatenates all lines of a file\nconcat_lines() {\n  if [ -f \"$1\" ]; then\n    echo \"$(tr -s '\\n' ' ' < \"$1\")\"\n  fi\n}\n\nBASE_DIR=$(find_maven_basedir \"$(dirname \"$0\")\")\nif [ -z \"$BASE_DIR\" ]; then\n  exit 1;\nfi\n\nMAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-\"$BASE_DIR\"}; export MAVEN_PROJECTBASEDIR\nif [ \"$MVNW_VERBOSE\" = true ]; then\n  echo $MAVEN_PROJECTBASEDIR\nfi\n\n##########################################################################################\n# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central\n# This allows using the maven wrapper in projects that prohibit checking in binary data.\n##########################################################################################\nif [ -r \"$BASE_DIR/.mvn/wrapper/maven-wrapper.jar\" ]; then\n    if [ \"$MVNW_VERBOSE\" = true ]; then\n      echo \"Found .mvn/wrapper/maven-wrapper.jar\"\n    fi\nelse\n    if [ \"$MVNW_VERBOSE\" = true ]; then\n      echo \"Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ...\"\n    fi\n    if [ -n \"$MVNW_REPOURL\" ]; then\n      wrapperUrl=\"$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar\"\n    else\n      wrapperUrl=\"https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar\"\n    fi\n    while IFS=\"=\" read key value; do\n      case \"$key\" in (wrapperUrl) wrapperUrl=\"$value\"; break ;;\n      esac\n    done < \"$BASE_DIR/.mvn/wrapper/maven-wrapper.properties\"\n    if [ \"$MVNW_VERBOSE\" = true ]; then\n      echo \"Downloading from: $wrapperUrl\"\n    fi\n    wrapperJarPath=\"$BASE_DIR/.mvn/wrapper/maven-wrapper.jar\"\n    if $cygwin; then\n      wrapperJarPath=`cygpath --path --windows \"$wrapperJarPath\"`\n    fi\n\n    if command -v wget > /dev/null; then\n        QUIET=\"--quiet\"\n        if [ \"$MVNW_VERBOSE\" = true ]; then\n          echo \"Found wget ... using wget\"\n          QUIET=\"\"\n        fi\n        if [ -z \"$MVNW_USERNAME\" ] || [ -z \"$MVNW_PASSWORD\" ]; then\n            wget $QUIET \"$wrapperUrl\" -O \"$wrapperJarPath\"\n        else\n            wget $QUIET --http-user=\"$MVNW_USERNAME\" --http-password=\"$MVNW_PASSWORD\" \"$wrapperUrl\" -O \"$wrapperJarPath\"\n        fi\n        [ $? -eq 0 ] || rm -f \"$wrapperJarPath\"\n    elif command -v curl > /dev/null; then\n        QUIET=\"--silent\"\n        if [ \"$MVNW_VERBOSE\" = true ]; then\n          echo \"Found curl ... using curl\"\n          QUIET=\"\"\n        fi\n        if [ -z \"$MVNW_USERNAME\" ] || [ -z \"$MVNW_PASSWORD\" ]; then\n            curl $QUIET -o \"$wrapperJarPath\" \"$wrapperUrl\" -f -L\n        else\n            curl $QUIET --user \"$MVNW_USERNAME:$MVNW_PASSWORD\" -o \"$wrapperJarPath\" \"$wrapperUrl\" -f -L\n        fi\n        [ $? -eq 0 ] || rm -f \"$wrapperJarPath\"\n    else\n        if [ \"$MVNW_VERBOSE\" = true ]; then\n          echo \"Falling back to using Java to download\"\n        fi\n        javaSource=\"$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java\"\n        javaClass=\"$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class\"\n        # For Cygwin, switch paths to Windows format before running javac\n        if $cygwin; then\n          javaSource=`cygpath --path --windows \"$javaSource\"`\n          javaClass=`cygpath --path --windows \"$javaClass\"`\n        fi\n        if [ -e \"$javaSource\" ]; then\n            if [ ! -e \"$javaClass\" ]; then\n                if [ \"$MVNW_VERBOSE\" = true ]; then\n                  echo \" - Compiling MavenWrapperDownloader.java ...\"\n                fi\n                # Compiling the Java class\n                (\"$JAVA_HOME/bin/javac\" \"$javaSource\")\n            fi\n            if [ -e \"$javaClass\" ]; then\n                # Running the downloader\n                if [ \"$MVNW_VERBOSE\" = true ]; then\n                  echo \" - Running MavenWrapperDownloader.java ...\"\n                fi\n                (\"$JAVA_HOME/bin/java\" -cp .mvn/wrapper MavenWrapperDownloader \"$MAVEN_PROJECTBASEDIR\")\n            fi\n        fi\n    fi\nfi\n##########################################################################################\n# End of extension\n##########################################################################################\n\nMAVEN_OPTS=\"$(concat_lines \"$MAVEN_PROJECTBASEDIR/.mvn/jvm.config\") $MAVEN_OPTS\"\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin; then\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=`cygpath --path --windows \"$JAVA_HOME\"`\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=`cygpath --path --windows \"$CLASSPATH\"`\n  [ -n \"$MAVEN_PROJECTBASEDIR\" ] &&\n    MAVEN_PROJECTBASEDIR=`cygpath --path --windows \"$MAVEN_PROJECTBASEDIR\"`\nfi\n\n# Provide a \"standardized\" way to retrieve the CLI args that will\n# work with both Windows and non-Windows executions.\nMAVEN_CMD_LINE_ARGS=\"$MAVEN_CONFIG $@\"\nexport MAVEN_CMD_LINE_ARGS\n\nWRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\nexec \"$JAVACMD\" \\\n  $MAVEN_OPTS \\\n  $MAVEN_DEBUG_OPTS \\\n  -classpath \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar\" \\\n  \"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}\" \\\n  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG \"$@\"\n"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/mvnw.bat",
    "content": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software Foundation (ASF) under one\n@REM or more contributor license agreements.  See the NOTICE file\n@REM distributed with this work for additional information\n@REM regarding copyright ownership.  The ASF licenses this file\n@REM to you under the Apache License, Version 2.0 (the\n@REM \"License\"); you may not use this file except in compliance\n@REM with the License.  You may obtain a copy of the License at\n@REM\n@REM    https://www.apache.org/licenses/LICENSE-2.0\n@REM\n@REM Unless required by applicable law or agreed to in writing,\n@REM software distributed under the License is distributed on an\n@REM \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n@REM KIND, either express or implied.  See the License for the\n@REM specific language governing permissions and limitations\n@REM under the License.\n@REM ----------------------------------------------------------------------------\n\n@REM ----------------------------------------------------------------------------\n@REM Apache Maven Wrapper startup batch script, version 3.1.1\n@REM\n@REM Required ENV vars:\n@REM JAVA_HOME - location of a JDK home dir\n@REM\n@REM Optional ENV vars\n@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands\n@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending\n@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven\n@REM     e.g. to debug Maven itself, use\n@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n@REM ----------------------------------------------------------------------------\n\n@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'\n@echo off\n@REM set title of command window\ntitle %0\n@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'\n@if \"%MAVEN_BATCH_ECHO%\" == \"on\"  echo %MAVEN_BATCH_ECHO%\n\n@REM set %HOME% to equivalent of $HOME\nif \"%HOME%\" == \"\" (set \"HOME=%HOMEDRIVE%%HOMEPATH%\")\n\n@REM Execute a user defined script before this one\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPre\n@REM check for pre script, once with legacy .bat ending and once with .cmd ending\nif exist \"%USERPROFILE%\\mavenrc_pre.bat\" call \"%USERPROFILE%\\mavenrc_pre.bat\" %*\nif exist \"%USERPROFILE%\\mavenrc_pre.cmd\" call \"%USERPROFILE%\\mavenrc_pre.cmd\" %*\n:skipRcPre\n\n@setlocal\n\nset ERROR_CODE=0\n\n@REM To isolate internal variables from possible post scripts, we use another setlocal\n@setlocal\n\n@REM ==== START VALIDATION ====\nif not \"%JAVA_HOME%\" == \"\" goto OkJHome\n\necho.\necho Error: JAVA_HOME not found in your environment. >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n:OkJHome\nif exist \"%JAVA_HOME%\\bin\\java.exe\" goto init\n\necho.\necho Error: JAVA_HOME is set to an invalid directory. >&2\necho JAVA_HOME = \"%JAVA_HOME%\" >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n@REM ==== END VALIDATION ====\n\n:init\n\n@REM Find the project base dir, i.e. the directory that contains the folder \".mvn\".\n@REM Fallback to current working directory if not found.\n\nset MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%\nIF NOT \"%MAVEN_PROJECTBASEDIR%\"==\"\" goto endDetectBaseDir\n\nset EXEC_DIR=%CD%\nset WDIR=%EXEC_DIR%\n:findBaseDir\nIF EXIST \"%WDIR%\"\\.mvn goto baseDirFound\ncd ..\nIF \"%WDIR%\"==\"%CD%\" goto baseDirNotFound\nset WDIR=%CD%\ngoto findBaseDir\n\n:baseDirFound\nset MAVEN_PROJECTBASEDIR=%WDIR%\ncd \"%EXEC_DIR%\"\ngoto endDetectBaseDir\n\n:baseDirNotFound\nset MAVEN_PROJECTBASEDIR=%EXEC_DIR%\ncd \"%EXEC_DIR%\"\n\n:endDetectBaseDir\n\nIF NOT EXIST \"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\" goto endReadAdditionalConfig\n\n@setlocal EnableExtensions EnableDelayedExpansion\nfor /F \"usebackq delims=\" %%a in (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a\n@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%\n\n:endReadAdditionalConfig\n\nSET MAVEN_JAVA_EXE=\"%JAVA_HOME%\\bin\\java.exe\"\nset WRAPPER_JAR=\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.jar\"\nset WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\nset WRAPPER_URL=\"https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar\"\n\nFOR /F \"usebackq tokens=1,2 delims==\" %%A IN (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.properties\") DO (\n    IF \"%%A\"==\"wrapperUrl\" SET WRAPPER_URL=%%B\n)\n\n@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central\n@REM This allows using the maven wrapper in projects that prohibit checking in binary data.\nif exist %WRAPPER_JAR% (\n    if \"%MVNW_VERBOSE%\" == \"true\" (\n        echo Found %WRAPPER_JAR%\n    )\n) else (\n    if not \"%MVNW_REPOURL%\" == \"\" (\n        SET WRAPPER_URL=\"%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar\"\n    )\n    if \"%MVNW_VERBOSE%\" == \"true\" (\n        echo Couldn't find %WRAPPER_JAR%, downloading it ...\n        echo Downloading from: %WRAPPER_URL%\n    )\n\n    powershell -Command \"&{\"^\n\t\t\"$webclient = new-object System.Net.WebClient;\"^\n\t\t\"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {\"^\n\t\t\"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');\"^\n\t\t\"}\"^\n\t\t\"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')\"^\n\t\t\"}\"\n    if \"%MVNW_VERBOSE%\" == \"true\" (\n        echo Finished downloading %WRAPPER_JAR%\n    )\n)\n@REM End of extension\n\n@REM Provide a \"standardized\" way to retrieve the CLI args that will\n@REM work with both Windows and non-Windows executions.\nset MAVEN_CMD_LINE_ARGS=%*\n\n%MAVEN_JAVA_EXE% ^\n  %JVM_CONFIG_MAVEN_PROPS% ^\n  %MAVEN_OPTS% ^\n  %MAVEN_DEBUG_OPTS% ^\n  -classpath %WRAPPER_JAR% ^\n  \"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%\" ^\n  %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*\nif ERRORLEVEL 1 goto error\ngoto end\n\n:error\nset ERROR_CODE=1\n\n:end\n@endlocal & set ERROR_CODE=%ERROR_CODE%\n\nif not \"%MAVEN_SKIP_RC%\"==\"\" goto skipRcPost\n@REM check for post script, once with legacy .bat ending and once with .cmd ending\nif exist \"%USERPROFILE%\\mavenrc_post.bat\" call \"%USERPROFILE%\\mavenrc_post.bat\"\nif exist \"%USERPROFILE%\\mavenrc_post.cmd\" call \"%USERPROFILE%\\mavenrc_post.cmd\"\n:skipRcPost\n\n@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'\nif \"%MAVEN_BATCH_PAUSE%\"==\"on\" pause\n\nif \"%MAVEN_TERMINATE_CMD%\"==\"on\" exit %ERROR_CODE%\n\ncmd /C exit /B %ERROR_CODE%\n"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/oci/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright 2024 Oracle and/or its affiliates\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    https://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <groupId>com.example</groupId>\n  <artifactId>oci</artifactId>\n  <version>1.0-SNAPSHOT</version>\n  <packaging>${packaging}</packaging>\n  <name>demo-${artifactId}</name>\n\n  <parent>\n    <groupId>com.example</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>1.0-SNAPSHOT</version>\n  </parent>\n  <properties>\n    <packaging>jar</packaging>\n    <jdk.version>17</jdk.version>\n    <release.version>17</release.version>\n    <micronaut.version>4.2.1-oracle-00001</micronaut.version>\n    <micronaut.native-image.base-image-run>frolvlad/alpine-glibc:alpine-3.16</micronaut.native-image.base-image-run>\n    <micronaut-maven-plugin.version>4.3.1</micronaut-maven-plugin.version>\n    <micronaut.runtime>netty</micronaut.runtime>\n    <exec.mainClass>com.example.Application</exec.mainClass>\n  </properties>\n\n  <repositories>\n    <repository>\n      <id>central</id>\n      <url>https://repo.maven.apache.org/maven2</url>\n    </repository>\n    \n    <repository>\n      <id>gcn</id>\n      <url>https://maven.oracle.com/public</url>\n    </repository>\n  </repositories>\n\n  <dependencyManagement>\n    <dependencies>\n    <dependency>\n      <groupId>cloud.graal.gcn</groupId>\n      <artifactId>gcn-bom</artifactId>\n      <version>4.2.1.3</version>\n      <type>pom</type>\n      <scope>import</scope>\n    </dependency>\n    </dependencies>\n  </dependencyManagement>\n  <dependencies>\n    <dependency>\n      <groupId>com.example</groupId>\n      <artifactId>lib</artifactId>\n      <version>1.0-SNAPSHOT</version>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>io.micronaut</groupId>\n      <artifactId>micronaut-http-client</artifactId>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>io.micronaut</groupId>\n      <artifactId>micronaut-http-server-netty</artifactId>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>io.micronaut.serde</groupId>\n      <artifactId>micronaut-serde-jackson</artifactId>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>ch.qos.logback</groupId>\n      <artifactId>logback-classic</artifactId>\n      <scope>runtime</scope>\n    </dependency>\n    <dependency>\n      <groupId>io.micronaut.test</groupId>\n      <artifactId>micronaut-test-junit5</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.junit.jupiter</groupId>\n      <artifactId>junit-jupiter-api</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.junit.jupiter</groupId>\n      <artifactId>junit-jupiter-engine</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>com.google.cloud.tools</groupId>\n        <artifactId>jib-maven-plugin</artifactId>\n        <configuration>\n          <to>\n            <image>${project.name}</image>\n          </to>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>io.micronaut.maven</groupId>\n        <artifactId>micronaut-maven-plugin</artifactId>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-enforcer-plugin</artifactId>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-compiler-plugin</artifactId>\n        <configuration>\n          <!-- Uncomment to enable incremental compilation -->\n          <!-- <useIncrementalCompilation>false</useIncrementalCompilation> -->\n\n          <annotationProcessorPaths combine.children=\"append\">\n            <path>\n              <groupId>io.micronaut</groupId>\n              <artifactId>micronaut-http-validation</artifactId>\n              <version>${micronaut.core.version}</version>\n            </path>\n            <path>\n              <groupId>io.micronaut.serde</groupId>\n              <artifactId>micronaut-serde-processor</artifactId>\n              <version>${micronaut.serialization.version}</version>\n              <exclusions>\n                <exclusion>\n                  <groupId>io.micronaut</groupId>\n                  <artifactId>micronaut-inject</artifactId>\n                </exclusion>\n              </exclusions>\n            </path>\n          </annotationProcessorPaths>\n          <compilerArgs>\n            <arg>-Amicronaut.processing.group=com.example</arg>\n            <arg>-Amicronaut.processing.module=oci</arg>\n          </compilerArgs>\n        </configuration>\n      </plugin>\n    </plugins>\n  </build>\n\n</project>\n"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/oci/src/main/java/com/example/Application.java",
    "content": "/*\n * Copyright 2024 Oracle and/or its affiliates\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *     https://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example;\n\nimport io.micronaut.core.annotation.NonNull;\nimport io.micronaut.context.ApplicationContextBuilder;\nimport io.micronaut.context.ApplicationContextConfigurer;\nimport io.micronaut.context.annotation.ContextConfigurer;\nimport io.micronaut.runtime.Micronaut;\n\npublic class Application {\n\n    @ContextConfigurer\n    public static class Configurer implements ApplicationContextConfigurer {\n        @Override\n        public void configure(@NonNull ApplicationContextBuilder builder) {\n            builder.defaultEnvironments(\"oraclecloud\");\n        }\n    }\n    public static void main(String[] args) {\n        Micronaut.run(Application.class, args);\n    }\n}"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/oci/src/main/resources/application-oraclecloud.properties",
    "content": "micronaut.application.name=oci\n"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/oci/src/main/resources/bootstrap-oraclecloud.properties",
    "content": ""
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/oci/src/main/resources/logback.xml",
    "content": "<configuration>\n\n    <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        <!-- encoders are assigned the type\n             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->\n        <encoder>\n            <pattern>%cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n</pattern>\n        </encoder>\n    </appender>\n\n    <root level=\"info\">\n        <appender-ref ref=\"STDOUT\" />\n    </root>\n</configuration>\n"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/oci/src/test/java/com/example/OciTest.java",
    "content": "/*\n * Copyright 2024 Oracle and/or its affiliates\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * \n *     https://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.example;\n\nimport io.micronaut.runtime.EmbeddedApplication;\nimport io.micronaut.test.extensions.junit5.annotation.MicronautTest;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport jakarta.inject.Inject;\n\n@MicronautTest\nclass OciTest {\n\n    @Inject\n    EmbeddedApplication<?> application;\n\n    @Test\n    void testItWorks() {\n        Assertions.assertTrue(application.isRunning());\n    }\n\n}\n"
  },
  {
    "path": "integrations/vscode/fixtures/test projects/demo/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright 2024 Oracle and/or its affiliates\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    https://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n-->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.micronaut.platform</groupId>\n        <artifactId>micronaut-parent</artifactId>\n        <version>4.2.1-oracle-00001</version>\n    </parent>\n    <repositories>\n        <repository>\n          <id>central</id>\n          <url>https://repo.maven.apache.org/maven2</url>\n        </repository>\n        <repository>\n          <id>gcn</id>\n          <url>https://maven.oracle.com/public</url>\n        </repository>\n    </repositories>\n    <artifactId>demo-parent</artifactId>\n    <version>1.0-SNAPSHOT</version>\n    <groupId>com.example</groupId>\n    <name>demo</name>\n    <packaging>pom</packaging>\n\n    <modules>\n        <module>lib</module>\n        <module>oci</module>\n    </modules>\n</project>\n"
  },
  {
    "path": "integrations/vscode/package.json",
    "content": "{\n\t\"name\": \"visualvm-vscode\",\n\t\"displayName\": \"VisualVM for VS Code\",\n\t\"description\": \"VisualVM integration for Visual Studio Code\",\n\t\"version\": \"1.0.1-dev\",\n\t\"preview\": false,\n\t\"license\": \"GPLv2+CPE\",\n\t\"publisher\": \"oracle-labs-graalvm\",\n\t\"author\": {\n\t\t\"name\": \"Oracle Labs\"\n\t},\n\t\"icon\": \"images/extension_icon.png\",\n\t\"homepage\": \"https://github.com/oracle/visualvm/blob/master/integrations/vscode/README.md\",\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"https://github.com/oracle/visualvm\"\n\t},\n\t\"bugs\": {\n\t\t\"url\": \"https://github.com/oracle/visualvm/issues\"\n\t},\n\t\"engines\": {\n\t\t\"vscode\": \"^1.76.0\"\n\t},\n\t\"categories\": [\n\t\t\"Programming Languages\",\n\t\t\"Debuggers\",\n\t\t\"Testing\",\n\t\t\"Other\"\n\t],\n\t\"keywords\": [\n\t\t\"visualvm\",\n\t\t\"java\",\n\t\t\"performance\",\n\t\t\"profiling\"\n\t],\n\t\"activationEvents\": [\n\t\t\"*\"\n\t],\n\t\"main\": \"./dist/extension\",\n\t\"contributes\": {\n\t\t\"configuration\": {\n\t\t\t\"type\": \"object\",\n\t\t\t\"title\": \"VisualVM\",\n\t\t\t\"properties\": {\n\t\t\t\t\"visualvm.java.jdkPath\": {\n\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\"default\": \"\",\n\t\t\t\t\t\"description\": \"Path to local JDK installation folder (leave empty to find automatically)\",\n\t\t\t\t\t\"scope\": \"machine-overridable\"\n\t\t\t\t},\n\t\t\t\t\"visualvm.startup.useJdkPathForVisualvm\": {\n\t\t\t\t\t\"type\": \"boolean\",\n\t\t\t\t\t\"default\": true,\n\t\t\t\t\t\"description\": \"Use defined/automatically found local JDK installation to run VisualVM (not applicable for GraalVM component)\",\n\t\t\t\t\t\"scope\": \"machine-overridable\"\n\t\t\t\t},\n\t\t\t\t\"visualvm.installation.visualvmPath\": {\n\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\"default\": \"\",\n\t\t\t\t\t\"description\": \"Path to local VisualVM installation folder\",\n\t\t\t\t\t\"scope\": \"machine-overridable\"\n\t\t\t\t},\n\t\t\t\t\"visualvm.startup.visualvmParameters\": {\n\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\"default\": \"\",\n\t\t\t\t\t\"description\": \"Optional parameters for starting VisualVM (--userdir, -J-Xmx, etc.)\",\n\t\t\t\t\t\"scope\": \"machine-overridable\"\n\t\t\t\t},\n\t\t\t\t\"visualvm.behavior.visualvmWindowToFront\": {\n\t\t\t\t\t\"type\": \"boolean\",\n\t\t\t\t\t\"default\": true,\n\t\t\t\t\t\"description\": \"Bring VisualVM window to front when invoked an action\",\n\t\t\t\t\t\"scope\": \"machine-overridable\"\n\t\t\t\t},\n\t\t\t\t\"visualvm.behavior.preselectProcessView\": {\n\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\"default\": \"Monitor\",\n\t\t\t\t\t\"description\": \"Preselected view for a process shown in VisualVM\",\n\t\t\t\t\t\"enum\": [\n\t\t\t\t\t\t\"Current\",\n\t\t\t\t\t\t\"Overview\",\n\t\t\t\t\t\t\"Monitor\",\n\t\t\t\t\t\t\"Threads\",\n\t\t\t\t\t\t\"Sampler\"\n\t\t\t\t\t],\n\t\t\t\t\t\"scope\": \"machine-overridable\"\n\t\t\t\t},\n\t\t\t\t\"visualvm.integration.automaticallySelectProjectProcess\": {\n\t\t\t\t\t\"type\": \"boolean\",\n\t\t\t\t\t\"default\": true,\n\t\t\t\t\t\"description\": \"Automatically select started project process for monitoring\",\n\t\t\t\t\t\"scope\": \"machine-overridable\"\n\t\t\t\t},\n\t\t\t\t\"visualvm.integration.customizeDisplayNameForProjectProcess\": {\n\t\t\t\t\t\"type\": \"boolean\",\n\t\t\t\t\t\"default\": true,\n\t\t\t\t\t\"description\": \"Configure started project process to display its folder name in VisualVM\",\n\t\t\t\t\t\"scope\": \"machine-overridable\"\n\t\t\t\t},\n\t\t\t\t\"visualvm.integration.enableGoToSource\": {\n\t\t\t\t\t\"type\": \"boolean\",\n\t\t\t\t\t\"default\": true,\n\t\t\t\t\t\"description\": \"Enable Go to Source integration\",\n\t\t\t\t\t\"scope\": \"machine-overridable\"\n\t\t\t\t},\n\t\t\t\t\"visualvm.integration.visualStudioCodeParameters\": {\n\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\"default\": \"\",\n\t\t\t\t\t\"description\": \"Optional parameters for invoking VS Code launcher to open sources (--user-data-dir, --extensions-dir, etc.)\",\n\t\t\t\t\t\"scope\": \"machine-overridable\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"commands\": [\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.downloadVisualVM\",\n\t\t\t\t\"title\": \"Download Latest VisualVM\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.selectInstallation\",\n\t\t\t\t\"title\": \"Select Local VisualVM Installation\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.moveView\",\n\t\t\t\t\"title\": \"Move VisualVM View\",\n\t\t\t\t\"icon\": \"$(pin)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.start\",\n\t\t\t\t\"title\": \"Start VisualVM\",\n\t\t\t\t\"icon\": \"$(run)\",\n\t\t\t\t\"category\": \"VisualVM\",\n\t\t\t\t\"enablement\": \"visualvm.initialized && !visualvm.noInstallation\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.configureSetting\",\n\t\t\t\t\"title\": \"Configure\",\n\t\t\t\t\"icon\": \"$(edit)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.showProcess\",\n\t\t\t\t\"title\": \"Show in VisualVM\",\n\t\t\t\t\"icon\": \"$(eye)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.selectProcessGlobal\",\n\t\t\t\t\"title\": \"Select Process\",\n\t\t\t\t\"icon\": \"$(search)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.selectProcess\",\n\t\t\t\t\"title\": \"Select Process\",\n\t\t\t\t\"icon\": \"$(search)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.clearProcess\",\n\t\t\t\t\"title\": \"Stop Monitoring\",\n\t\t\t\t\"icon\": \"$(close)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.threadDumpTake\",\n\t\t\t\t\"title\": \"Take Thread Dump\",\n\t\t\t\t\"icon\": \"$(record)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.heapDumpTake\",\n\t\t\t\t\"title\": \"Take Heap Dump\",\n\t\t\t\t\"icon\": \"$(record)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.cpuSamplerStart\",\n\t\t\t\t\"title\": \"Start CPU Sampling\",\n\t\t\t\t\"icon\": \"$(play-circle)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.cpuSamplerSnapshot\",\n\t\t\t\t\"title\": \"Take Snapshot of Sampler Results\",\n\t\t\t\t\"icon\": \"$(record)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.cpuSamplerStop\",\n\t\t\t\t\"title\": \"Stop Sampling\",\n\t\t\t\t\"icon\": \"$(stop)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.memorySamplerStart\",\n\t\t\t\t\"title\": \"Start Memory Sampling\",\n\t\t\t\t\"icon\": \"$(play-circle)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.memorySamplerSnapshot\",\n\t\t\t\t\"title\": \"Take Snapshot of Sampler Results\",\n\t\t\t\t\"icon\": \"$(record)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.memorySamplerStop\",\n\t\t\t\t\"title\": \"Stop Sampling\",\n\t\t\t\t\"icon\": \"$(stop)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.jfrStart\",\n\t\t\t\t\"title\": \"Start Flight Recording\",\n\t\t\t\t\"icon\": \"$(play-circle)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.jfrDump\",\n\t\t\t\t\"title\": \"Dump Flight Recording Data\",\n\t\t\t\t\"icon\": \"$(record)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"command\": \"visualvm.jfrStop\",\n\t\t\t\t\"title\": \"Stop Flight Recording\",\n\t\t\t\t\"icon\": \"$(stop)\",\n\t\t\t\t\"category\": \"VisualVM\"\n\t\t\t}\n\t\t],\n\t\t\"viewsContainers\": {\n\t\t\t\"activitybar\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"visualvm\",\n\t\t\t\t\t\"title\": \"VisualVM\",\n\t\t\t\t\t\"icon\": \"resources/visualvm_icon.png\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t\"viewsWelcome\": [\n\t\t\t{\n\t\t\t\t\"view\": \"visualvm-visualvm\",\n\t\t\t\t\"contents\": \"Initializing VisualVM...\",\n\t\t\t\t\"when\": \"!visualvm.initialized\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"view\": \"visualvm-visualvm\",\n\t\t\t\t\"contents\": \"Start by downloading the latest [VisualVM](https://visualvm.github.io), or select an existing local installation.\\n[Download Latest VisualVM](command:visualvm.downloadVisualVM)\\n[Select Local VisualVM Installation](command:visualvm.selectInstallation)\\nTip: You can easily [move this view](command:visualvm.moveView) to a different location.\",\n\t\t\t\t\"when\": \"visualvm.noInstallation\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"view\": \"explorer-visualvm\",\n\t\t\t\t\"contents\": \"Initializing VisualVM...\",\n\t\t\t\t\"when\": \"!visualvm.initialized\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"view\": \"explorer-visualvm\",\n\t\t\t\t\"contents\": \"Start by downloading the latest [VisualVM](https://visualvm.github.io), or select an existing local installation.\\n[Download Latest VisualVM](command:visualvm.downloadVisualVM)\\n[Select Local VisualVM Installation](command:visualvm.selectInstallation)\\nTip: You can easily [move this view](command:visualvm.moveView) to a different location.\",\n\t\t\t\t\"when\": \"visualvm.noInstallation\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"view\": \"debug-visualvm\",\n\t\t\t\t\"contents\": \"Initializing VisualVM...\",\n\t\t\t\t\"when\": \"!visualvm.initialized\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"view\": \"debug-visualvm\",\n\t\t\t\t\"contents\": \"Start by downloading the latest [VisualVM](https://visualvm.github.io), or select an existing local installation.\\n[Download Latest VisualVM](command:visualvm.downloadVisualVM)\\n[Select Local VisualVM Installation](command:visualvm.selectInstallation)\\nTip: You can easily [move this view](command:visualvm.moveView) to a different location.\",\n\t\t\t\t\"when\": \"visualvm.noInstallation\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"view\": \"extension-micronaut-tools-visualvm\",\n\t\t\t\t\"contents\": \"Initializing VisualVM...\",\n\t\t\t\t\"when\": \"!visualvm.initialized\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"view\": \"extension-micronaut-tools-visualvm\",\n\t\t\t\t\"contents\": \"Start by downloading the latest [VisualVM](https://visualvm.github.io), or select an existing local installation.\\n[Download Latest VisualVM](command:visualvm.downloadVisualVM)\\n[Select Local VisualVM Installation](command:visualvm.selectInstallation)\\nTip: You can easily [move this view](command:visualvm.moveView) to a different location.\",\n\t\t\t\t\"when\": \"visualvm.noInstallation\"\n\t\t\t}\n\t\t],\n\t\t\"views\": {\n\t\t\t\"visualvm\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"visualvm-visualvm\",\n\t\t\t\t\t\"name\": \"VisualVM\",\n\t\t\t\t\t\"icon\": \"resources/visualvm_icon.png\",\n\t\t\t\t\t\"when\": \"visualvm.view == visualvm-visualvm\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"explorer\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"explorer-visualvm\",\n\t\t\t\t\t\"name\": \"VisualVM\",\n\t\t\t\t\t\"icon\": \"resources/visualvm_icon.png\",\n\t\t\t\t\t\"when\": \"visualvm.view == explorer-visualvm\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"debug\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"debug-visualvm\",\n\t\t\t\t\t\"name\": \"VisualVM\",\n\t\t\t\t\t\"icon\": \"resources/visualvm_icon.png\",\n\t\t\t\t\t\"when\": \"visualvm.view == debug-visualvm\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t\"menus\": {\n\t\t\t\"commandPalette\": [\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.configureSetting\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.showProcess\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.selectProcess\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.clearProcess\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.threadDumpTake\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.heapDumpTake\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.heapDumpTake\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.cpuSamplerStart\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.cpuSamplerSnapshot\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.cpuSamplerStop\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.memorySamplerStart\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.memorySamplerSnapshot\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.memorySamplerStop\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.jfrStart\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.jfrDump\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.jfrStop\",\n\t\t\t\t\t\"when\": \"false\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"editor/context\": [],\n\t\t\t\"view/title\": [\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.start\",\n\t\t\t\t\t\"group\": \"navigation@1\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && visualvm.initialized && !visualvm.noInstallation\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.moveView\",\n\t\t\t\t\t\"group\": \"navigation@2\",\n\t\t\t\t\t\"when\": \"view in visualvm.views\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"view/item/context\": [\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.configureSetting\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem in visualvm.configurableNodes\",\n\t\t\t\t\t\"group\": \"inline@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.configureSetting\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem in visualvm.configurableNodes\",\n\t\t\t\t\t\"group\": \"context@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.showProcess\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.ProcessNode.hasPid\",\n\t\t\t\t\t\"group\": \"inline@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.showProcess\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.ProcessNode.hasPid\",\n\t\t\t\t\t\"group\": \"context@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.selectProcess\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.ProcessNode.noProcess\",\n\t\t\t\t\t\"group\": \"inline@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.selectProcess\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.ProcessNode.noProcess\",\n\t\t\t\t\t\"group\": \"context@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.clearProcess\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem =~ /visualvm\\\\.ProcessNode\\\\.(hasId|hasPid|terminated)/\",\n\t\t\t\t\t\"group\": \"inline@4\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.clearProcess\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem =~ /visualvm\\\\.ProcessNode\\\\.(hasId|hasPid|terminated)/\",\n\t\t\t\t\t\"group\": \"context@4\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.threadDumpTake\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.ThreadDumpNode.invokable\",\n\t\t\t\t\t\"group\": \"inline@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.threadDumpTake\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.ThreadDumpNode.invokable\",\n\t\t\t\t\t\"group\": \"context@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.heapDumpTake\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.HeapDumpNode.invokable\",\n\t\t\t\t\t\"group\": \"inline@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.heapDumpTake\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.HeapDumpNode.invokable\",\n\t\t\t\t\t\"group\": \"context@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.cpuSamplerStart\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.CpuSamplerNode.invokable\",\n\t\t\t\t\t\"group\": \"inline@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.cpuSamplerStart\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.CpuSamplerNode.invokable\",\n\t\t\t\t\t\"group\": \"context@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.cpuSamplerSnapshot\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.CpuSamplerNode.invokable\",\n\t\t\t\t\t\"group\": \"inline@2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.cpuSamplerSnapshot\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.CpuSamplerNode.invokable\",\n\t\t\t\t\t\"group\": \"context@2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.cpuSamplerStop\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.CpuSamplerNode.invokable\",\n\t\t\t\t\t\"group\": \"inline@3\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.cpuSamplerStop\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.CpuSamplerNode.invokable\",\n\t\t\t\t\t\"group\": \"context@3\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.memorySamplerStart\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.MemorySamplerNode.invokable\",\n\t\t\t\t\t\"group\": \"inline@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.memorySamplerStart\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.MemorySamplerNode.invokable\",\n\t\t\t\t\t\"group\": \"context@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.memorySamplerSnapshot\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.MemorySamplerNode.invokable\",\n\t\t\t\t\t\"group\": \"inline@2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.memorySamplerSnapshot\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.MemorySamplerNode.invokable\",\n\t\t\t\t\t\"group\": \"context@2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.memorySamplerStop\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.MemorySamplerNode.invokable\",\n\t\t\t\t\t\"group\": \"inline@3\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.memorySamplerStop\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.MemorySamplerNode.invokable\",\n\t\t\t\t\t\"group\": \"context@3\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.jfrStart\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.JfrNode.invokable\",\n\t\t\t\t\t\"group\": \"inline@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.jfrStart\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.JfrNode.invokable\",\n\t\t\t\t\t\"group\": \"context@1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.jfrDump\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.JfrNode.invokable\",\n\t\t\t\t\t\"group\": \"inline@2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.jfrDump\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.JfrNode.invokable\",\n\t\t\t\t\t\"group\": \"context@2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.jfrStop\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.JfrNode.invokable\",\n\t\t\t\t\t\"group\": \"inline@3\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"command\": \"visualvm.jfrStop\",\n\t\t\t\t\t\"when\": \"view in visualvm.views && viewItem == visualvm.JfrNode.invokable\",\n\t\t\t\t\t\"group\": \"context@3\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t},\n\t\"vsce\": {\n\t\t\"baseImagesUrl\": \"https://github.com/oracle/visualvm/raw/master/integrations/vscode\"\n\t},\n\t\"config\": {\n\t\t\"winBuildPath\": \".\\\\node_modules\\\\.bin\\\\vsce\",\n\t\t\"unixBuildPath\": \"./node_modules/.bin/vsce\",\n\t\t\"buildCmd\": \"package --allow-star-activation --no-update-package-json\"\n\t},\n\t\"scripts\": {\n\t\t\"vscode:prepublish\": \"copyfiles -f ../../LICENSE.txt . && cross-env NODE_OPTIONS='--max-old-space-size=8192' webpack --mode production\",\n\t\t\"compile\": \"webpack --mode development\",\n\t\t\"info\": \"webpack --display-modules\",\n\t\t\"watch\": \"webpack --mode development --watch\",\n\t\t\"prebuild\": \"npm install\",\n\t\t\"build\": \"cross-os build\",\n\t\t\"lint\": \"eslint src --ext ts\",\n\n\t\t\"pretest\": \"tsc -p ./\",\n\t\t\"watch-tests\": \"tsc -watch -p ./\",\n\t\t\"test\": \"cross-env GLOBAL_AGENT_NO_PROXY=$no_proxy GLOBAL_AGENT_HTTP_PROXY=$http_proxy node ./dist/test/runTest.js\"\n\t},\n\t\"cross-os\": {\n\t\t\"build\": {\n\t\t\t\"linux\": \"$npm_package_config_unixBuildPath $npm_package_config_buildCmd `[ -z ${BUILD_NUMBER} ] && echo \\\"${npm_package_version}\\\" || echo \\\"${npm_package_version}-${BUILD_NUMBER}\\\"`\",\n\t\t\t\"darwin\": \"$npm_package_config_unixBuildPath $npm_package_config_buildCmd `[ -z ${BUILD_NUMBER} ] && echo \\\"${npm_package_version}\\\" || echo \\\"${npm_package_version}-${BUILD_NUMBER}\\\"`\",\n\t\t\t\"win32\": \"%npm_package_config_winBuildPath% %npm_package_config_buildCmd%\"\n\t\t}\n\t},\n\t\"dependencies\": {\n\t\t\"decompress\": \"^4.2.1\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@types/decompress\": \"^4.2.3\",\n\t\t\"@types/glob\": \"^8.0.1\",\n\t\t\"@types/isomorphic-fetch\": \"^0.0.36\",\n\t\t\"@types/node\": \"^14.16.0\",\n\t\t\"@types/mocha\": \"^10.0.6\",\n\t\t\"@types/vscode\": \"^1.76.0\",\n\t\t\"@typescript-eslint/eslint-plugin\": \"^5.54.1\",\n\t\t\"@typescript-eslint/parser\": \"^5.54.1\",\n\t\t\"@vscode/codicons\": \"0.0.20\",\n\t\t\"@vscode/test-electron\": \"^2.2.3\",\n\t\t\"@vscode/vsce\": \"^2.15.0\",\n\t\t\"copyfiles\": \"^2.4.1\",\n\t\t\"cross-env\": \"^7.0.3\",\n\t\t\"cross-os\": \"^1.5.0\",\n\t\t\"encoding\": \"^0.1.13\",\n\t\t\"eslint\": \"^8.35.0\",\n\t\t\"eslint-webpack-plugin\": \"^4.0.0\",\n\t\t\"glob\": \"^8.1.0\",\n\t\t\"global-agent\": \"^3.0.0\",\n\t\t\"mocha\": \"^10.1.0\",\n\t\t\"mochawesome\": \"^7.1.3\",\n\t\t\"node-abort-controller\": \"^3.1.1\",\n\t\t\"ts-loader\": \"^9.4.2\",\n\t\t\"typescript\": \"^4.9.5\",\n\t\t\"webpack\": \"^5.94.0\",\n\t\t\"webpack-cli\": \"^4.10.0\"\n\t}\n}\n"
  },
  {
    "path": "integrations/vscode/src/commands.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nexport const COMMAND_DOWNLOAD_LATEST_VISUALVM = 'visualvm.downloadVisualVM';\nexport const COMMAND_SELECT_INSTALLATION = 'visualvm.selectInstallation';\nexport const COMMAND_SELECT_INSTALLATION_NAME = 'Select Local VisualVM Installation';\nexport const COMMAND_START_VISUALVM = 'visualvm.start';\nexport const COMMAND_MOVE_VIEW = 'visualvm.moveView';\nexport const COMMAND_MOVE_VIEW_NAME = 'Move VisualVM View';\nexport const COMMAND_SELECT_PROCESS_GLOBAL = 'visualvm.selectProcessGlobal';\nexport const COMMAND_SELECT_PROCESS = 'visualvm.selectProcess';\nexport const COMMAND_CLEAR_PROCESS = 'visualvm.clearProcess';\nexport const COMMAND_CONFIGURE_SETTING = 'visualvm.configureSetting';\nexport const COMMAND_OPEN_PROCESS = 'visualvm.showProcess';\nexport const COMMAND_THREADDUMP_TAKE = 'visualvm.threadDumpTake';\nexport const COMMAND_HEAPDUMP_TAKE = 'visualvm.heapDumpTake';\nexport const COMMAND_CPU_SAMPLER_START = 'visualvm.cpuSamplerStart';\nexport const COMMAND_CPU_SAMPLER_SNAPSHOT = 'visualvm.cpuSamplerSnapshot';\nexport const COMMAND_CPU_SAMPLER_STOP = 'visualvm.cpuSamplerStop';\nexport const COMMAND_MEMORY_SAMPLER_START = 'visualvm.memorySamplerStart';\nexport const COMMAND_MEMORY_SAMPLER_SNAPSHOT = 'visualvm.memorySamplerSnapshot';\nexport const COMMAND_MEMORY_SAMPLER_STOP = 'visualvm.memorySamplerStop';\nexport const COMMAND_JFR_START = 'visualvm.jfrStart';\nexport const COMMAND_JFR_DUMP = 'visualvm.jfrDump';\nexport const COMMAND_JFR_STOP = 'visualvm.jfrStop';\n"
  },
  {
    "path": "integrations/vscode/src/download.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as vscode from 'vscode';\nimport * as os from 'os';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as https from 'https';\nimport * as process from 'process';\nimport * as install from './install';\nimport * as commands from './commands';\nimport * as visualvm from './visualvm';\nimport * as logUtils from './logUtils';\n\n\nconst VISUALVM_URL: string = 'https://api.github.com';\nconst VISUALVM_RELEASES_URL: string = VISUALVM_URL + '/repos/oracle/visualvm/releases';\n\nconst EXT_ID = 'oracle-labs-graalvm.visualvm-vscode';\nconst VSCODE_AGENT = `VSCode/${vscode.version}`;\nconst SYSTEM_INFO = `${process.platform} ${process.arch}`;\nconst EXT_AGENT = `${EXT_ID}/${vscode.extensions.getExtension(EXT_ID)?.packageJSON.version}`;\nconst USER_AGENT = `${VSCODE_AGENT} (${SYSTEM_INFO}) ${EXT_AGENT}`;\n\nexport function initialize(context: vscode.ExtensionContext) {\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_DOWNLOAD_LATEST_VISUALVM, () => {\n        downloadLatestVisualVM();\n\t}));\n}\n\nexport async function downloadLatestVisualVM(predefinedPath?: string) {\n    logUtils.logInfo('[download] Requested to download latest VisualVM');\n\n    const folder = predefinedPath ? predefinedPath : await selectFolder();\n\n    if (!folder) {\n        logUtils.logInfo('[download] Destination folder selection canceled');\n        return;\n    }\n    logUtils.logInfo(`[download] Selected destination folder ${folder}`);\n\n    let releaseMetadata: any | undefined = undefined;\n    await vscode.window.withProgress({\n        location: vscode.ProgressLocation.Notification,\n        title: 'Searching for the latest VisualVM...'\n    }, async () => {\n        releaseMetadata = await getReleaseMetadata();\n    });\n    if (!releaseMetadata) {\n        return;\n    }\n\n    const releaseName = releaseMetadata.name;\n    logUtils.logInfo(`[download] Found latest release: ${releaseName}`);\n\n    const releaseAsset = getReleaseAsset(releaseMetadata);\n    if (!releaseAsset) {\n        return;\n    }\n\n    const url = releaseAsset.browser_download_url;\n    if (!url) {\n        logUtils.logError(`[download] Could not find download link for ${releaseName}`);\n        const msg = new vscode.MarkdownString(`Could not find download link. Download VisualVM manually from [${visualvm.VISUALVM_HOMEPAGE}](${visualvm.VISUALVM_HOMEPAGE}), and use the ${commands.COMMAND_SELECT_INSTALLATION_NAME} action to start using it.`);\n        vscode.window.showErrorMessage(msg.value);\n        return;\n    }\n    logUtils.logInfo(`[download] Found download link: ${url}`);\n\n    if (process.platform !== 'darwin') {\n        const parsedName = path.parse(releaseAsset.name);\n        const targetFolder = path.join(folder, parsedName.name);\n        if (fs.existsSync(targetFolder)) { // TODO: should check if directory?\n            logUtils.logWarning(`[download] Found existing directory ${targetFolder} while verifying download of ${releaseName}`);\n            const msg = `${releaseName} seems to be already installed in the selected folder. Download anyway?`;\n            const downloadOption = 'Download';\n            const openOption = 'Open Folder';\n            const cancelOption = 'Cancel';\n            const selected = await vscode.window.showWarningMessage(msg, downloadOption, openOption, cancelOption);\n            if (selected !== downloadOption) {\n                if (selected === openOption) {\n                    vscode.commands.executeCommand('revealFileInOS', vscode.Uri.file(targetFolder));\n                }\n                return;\n            }\n        }\n    }\n\n    const file = uniquePath(folder, releaseAsset.name);\n    logUtils.logInfo(`[download] Downloading ${releaseName} to ${file}`);\n    const result = await download(url, file, releaseName);\n    if (!result) {\n        return;\n    }\n    logUtils.logInfo(`[download] Downloaded ${releaseName} to ${file}`);\n\n    if (process.platform === 'darwin') {\n        await install.installDiskImage(result, releaseName); // TODO: add await\n        return result;\n    } else {\n        const parsedName = path.parse(releaseAsset.name);\n        const targetFolder = uniquePath(folder, parsedName.name);\n        await install.installZipArchive(result, targetFolder, releaseName); // TODO: add await\n        return targetFolder;\n    }\n}\n\nasync function selectFolder(): Promise<string | undefined> {\n    const selectedFolder = await vscode.window.showOpenDialog({\n        title: 'Download VisualVM: Select Folder',\n        canSelectFiles: false,\n        canSelectFolders: true,\n        canSelectMany: false,\n        defaultUri: vscode.Uri.file(os.homedir()),\n        openLabel: process.platform === 'darwin' ? 'Select Target Folder' : 'Select'\n    });\n    return selectedFolder?.length === 1 ? selectedFolder[0].fsPath : undefined;\n}\n\nexport async function getReleaseMetadata(): Promise<any | undefined> {\n    logUtils.logInfo('[download] Searching for latest VisualVM release');\n    const USER_AGENT_OPTIONS: https.RequestOptions = {\n        headers: { 'User-Agent': USER_AGENT } // TODO: add support for 'Accept-Encoding': 'gzip';\n    };\n    try {\n        const rawReleases = await getWithOptions(VISUALVM_RELEASES_URL, USER_AGENT_OPTIONS, /^application\\/json/);\n        if (rawReleases) {\n            const releases = JSON.parse(rawReleases);\n            if (Array.isArray(releases)) {\n                for (const release of releases) { // should be sorted latest first\n                    if (release.draft === false) {\n                        return release;\n                    }\n                }\n            }\n        }\n    } catch (err) {\n        logUtils.logError(`[download] Could not find latest VisualVM release: ${err}`);\n        if ((err as any)?.code === 'ENOTFOUND' || (err as any)?.code === 'ETIMEDOUT') {\n            vscode.window.showErrorMessage('Cannot get data from server. Check your connection and verify proxy settings.');\n        } else {\n            vscode.window.showErrorMessage(`Cannot get data from server: ${(err as any)?.message}`);\n        }\n    }\n    return undefined;\n}\n\nfunction getReleaseAsset(releaseMetadata: any): any | undefined {\n    const releaseName = releaseMetadata.name; // VisualVM 2.1.7\n    if (!releaseName) {\n        logUtils.logError('[download] Could not resolve release name');\n        return undefined;\n    }\n    const releaseVersion = String(releaseName).split(' ').pop(); // 2.1.7\n    if (!releaseVersion) {\n        logUtils.logError(`[download] Could not determine release version from ${releaseName}`);\n        return undefined;\n    }\n    const releaseKey = releaseVersion.replace(/\\./g, ''); // 217\n    const fileName = process.platform === 'darwin' ? `VisualVM_${releaseKey}.dmg` : `visualvm_${releaseKey}.zip`;\n    if (!Array.isArray(releaseMetadata.assets)) {\n        logUtils.logError('[download] Could not recognize release assets structure');\n        return undefined;\n    }\n    for (const asset of releaseMetadata.assets) {\n        if (asset.name === fileName) {\n            logUtils.logInfo(`[download] Found release asset for ${fileName}`);\n            return asset;\n        }\n    }\n    logUtils.logError('[download] Could not find release asset');\n    return undefined;\n}\n\nasync function getWithOptions(url: string, options: https.RequestOptions, contentTypeRegExp: RegExp): Promise<string | undefined> {\n    return new Promise<string | undefined>((resolve, reject) => {\n        https.get(url, options, res => {\n            const { statusCode } = res;\n            const contentType = res.headers['content-type'] || '';\n            let error;\n            if (statusCode !== 200) {\n                error = new Error(`Request Failed.\\nStatus Code: ${statusCode}`);\n            } else if (!contentTypeRegExp.test(contentType)) {\n                error = new Error(`Invalid content-type received ${contentType}`);\n            }\n            if (error) {\n                res.resume();\n                reject(error);\n            } else {\n                let rawData: string = '';\n                res.on('data', chunk => { rawData += chunk; });\n                res.on('end', () => {\n                    resolve(rawData);\n                });\n            }\n        }).on('error', e => {\n            reject(e);\n        }).end();\n    });\n}\n\nasync function download(url: string, file: string, name: string): Promise<string | undefined> {\n    try {\n        return await vscode.window.withProgress<string>({\n            location: vscode.ProgressLocation.Notification,\n            title: `Downloading ${name}...`,\n            cancellable: true\n        }, (progress, token) => {\n            return new Promise<string>((resolve, reject) => {\n                const fileStream: fs.WriteStream = fs.createWriteStream(file);\n                const request = function (url: string) {\n                    https.get(url, res => {\n                        const { statusCode } = res;\n                        if (statusCode === 302) {\n                            if (res.headers.location) {\n                                request(res.headers.location);\n                            }\n                        } else {\n                            let error;\n                            const contentType = res.headers['content-type'] || '';\n                            const length = parseInt(res.headers['content-length'] || '0');\n                            if (statusCode !== 200) {\n                                error = new Error(`Request Failed.\\nStatus Code: ${statusCode}`);\n                            } else if (!/^application\\/(octet-stream|x-gtar|zip)/.test(contentType)) {\n                                error = new Error(`Invalid content-type received ${contentType}`);\n                            }\n                            if (error) {\n                                reject(error);\n                                res.resume();\n                                fileStream.end();\n                            } else {\n                                token.onCancellationRequested(() => {\n                                    reject();\n                                    res.destroy();\n                                    fileStream.end();\n                                    fs.unlinkSync(file);\n                                });\n                                res.pipe(fileStream);\n                                if (length) {\n                                    const percent = length / 100;\n                                    let counter = 0;\n                                    let progressCounter = 0;\n                                    res.on('data', chunk => {\n                                        counter += chunk.length;\n                                        let f = Math.floor(counter / percent);\n                                        if (f > progressCounter) {\n                                            progress.report({ increment: f - progressCounter });\n                                            progressCounter = f;\n                                        }\n                                    });\n                                }\n                                res.on('end', () => {\n                                    resolve(file);\n                                    // file.end(); // NOTE: called by 'res.pipe(file);'\n                                });\n                            }\n                        }\n                    }).on('error', e => {\n                        reject(e);\n                        fileStream.end();\n                    });\n                };\n                request(url);\n            });\n        });\n    } catch (err) {\n        if (err) {\n            logUtils.logError(`[download] Download of ${name} from ${url} to ${file} failed: ${err}`);\n            vscode.window.showErrorMessage(`Error downloading ${name}: ${(err as any)?.message}`);\n        } else {\n            logUtils.logInfo(`[download] Download of ${name} canceled`);\n            // canceled\n        }\n        return undefined;\n    }\n}\n\nfunction uniquePath(folder: string, name: string) {\n    let uniquePath = path.join(folder, name);\n    if (fs.existsSync(uniquePath)) {\n        const parsedName = path.parse(name);\n        const namePart = parsedName.name;\n        const extPart = parsedName.ext;\n        let suffix = 0;\n        do { uniquePath = path.join(folder, `${namePart}_${++suffix}${extPart}`); }\n        while (fs.existsSync(uniquePath));\n    }\n    return uniquePath;\n}\n"
  },
  {
    "path": "integrations/vscode/src/extension.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as vscode from 'vscode';\nimport * as presets from './presets'; // must be imported first\nimport * as view from './view';\nimport * as visualvm from './visualvm';\nimport * as nodes from './nodes';\nimport * as monitoredProcesses from './monitoredProcesses';\nimport * as download from './download';\nimport * as logUtils from './logUtils';\n\n\nexport function activate(context: vscode.ExtensionContext) {\n\tlogUtils.registerExtensionForLogging(context);\n\tlogUtils.logInfo('[extension] Activating extension');\n\t\n\tpresets.initialize(context); // must be initialized first\n\tview.initialize(context);\n\tvisualvm.initialize(context);\n\tnodes.initialize(context);\n\tmonitoredProcesses.initialize(context);\n\tdownload.initialize(context);\n\n\tlogUtils.logInfo('[extension] Extension activated');\n}\n"
  },
  {
    "path": "integrations/vscode/src/install.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as vscode from 'vscode';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as decompress from 'decompress';\nimport * as visualvm from './visualvm';\nimport * as commands from './commands';\nimport * as logUtils from './logUtils';\n\n\nexport async function installZipArchive(zipFile: string, targetDir: string, name: string, deleteZipFile: boolean = true) {\n    logUtils.logInfo(`[install] Installing ${name} zip archive ${zipFile} to ${targetDir}`);\n    try {\n        await vscode.window.withProgress({\n            location: vscode.ProgressLocation.Notification,\n            title: `Extracting ${name}...`\n        }, async () => {\n            try {\n                logUtils.logInfo(`[install] Extracting zip archive ${zipFile} to ${targetDir}`);\n                await decompress(zipFile, targetDir, { strip: 1 });\n            } catch (err) {\n                logUtils.logError(`[install] Failed to extract zip archive ${zipFile} to ${targetDir}: ${err}`);\n                vscode.window.showErrorMessage(`Failed to extract ${name}: ${err}`);\n                throw(err);\n            }\n            // This is to prevent VisualVM startup failure - happens for identical .lastModified timestamps in different installation paths\n            touchFile(path.join(targetDir, 'platform', '.lastModified'));\n            touchFile(path.join(targetDir, 'visualvm', '.lastModified'));\n            if (deleteZipFile) {\n                try {\n                    logUtils.logInfo(`[install] Deleting zip archive ${zipFile}`);\n                    fs.unlinkSync(zipFile);\n                } catch (err) {\n                    logUtils.logWarning(`[install] Failed to delete zip archive ${zipFile}: ${err}`);\n                    const msg = `Failed to delete downloaded ${name} archive ${zipFile}: ${err}`;\n                    const openOption = 'Open File Location';\n                    const selected = await vscode.window.showWarningMessage(msg, openOption);\n                    if (selected === openOption) {\n                        vscode.commands.executeCommand('revealFileInOS', vscode.Uri.file(zipFile));\n                    }\n                    throw(err);\n                }\n            }\n        });\n        await visualvm.select(targetDir);\n    } catch (err) {\n        logUtils.logError(`[install] Failed to install zip archive ${zipFile} to ${targetDir}: ${err}`);\n    }\n}\n\nfunction touchFile(path: string): boolean {\n    const date = new Date();\n    try {\n        logUtils.logInfo(`[install] Resetting times for ${path}`);\n        fs.utimesSync(path, date, date);\n        return true;\n    } catch (err) {\n        logUtils.logWarning(`[install] Failed to reset times for ${path}: ${err}`);\n    }\n    return false;\n}\n\nexport async function installDiskImage(dmgFile: string, name: string, _deleteDmgFile: boolean = true) {\n    logUtils.logInfo(`[install] Request to manually install ${name} disk image ${dmgFile}`);\n    const msg = `${name} disk image has been downloaded to the selected folder. Install it and use the ${commands.COMMAND_SELECT_INSTALLATION_NAME} action to start using it.`;\n    const openOption = 'Open File Location';\n    const selected = await vscode.window.showInformationMessage(msg, openOption);\n    if (selected === openOption) {\n        vscode.commands.executeCommand('revealFileInOS', vscode.Uri.file(dmgFile));\n    }\n}\n"
  },
  {
    "path": "integrations/vscode/src/jdk.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as vscode from 'vscode';\nimport * as os from 'os';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as process from 'process';\nimport * as logUtils from './logUtils';\n\n\n// Paths to JDK used in settings.json\nconst VISUALVM_JDK_PATH_KEY = 'visualvm.java.jdkPath';\nconst NETBEANS_JDK_PATH_KEY = 'netbeans.jdkhome';\nconst JDT_JS_JDK_PATH_KEY = 'java.jdt.ls.java.home';\nconst JDK_JDK_PATH_KEY = 'java.home';\nconst GRAALVM_PATH_KEY = 'graalvm.home';\nconst JDK_KEYS = [ VISUALVM_JDK_PATH_KEY, NETBEANS_JDK_PATH_KEY, JDT_JS_JDK_PATH_KEY, JDK_JDK_PATH_KEY, GRAALVM_PATH_KEY ];\n\n// Paths to JDK used in evironment\nconst JDK_HOME_ENV_VAR = 'JDK_HOME';\nconst JAVA_HOME_ENV_VAR = 'JAVA_HOME';\nconst JDK_ENV_VARS = [ JDK_HOME_ENV_VAR, JAVA_HOME_ENV_VAR ];\n\nexport async function getPath(interactive: boolean = true): Promise<string | undefined> {\n    logUtils.logInfo('[jdk] Getting a JDK');\n\n    const configuration = vscode.workspace.getConfiguration();\n    for (const jdkPathKey of JDK_KEYS) {\n        const jdkPath = configuration.get<string>(jdkPathKey);\n        if (jdkPath) {\n            logUtils.logInfo(`[jdk] Resolved path for setting ${jdkPathKey}: ${jdkPath}`);\n            if (isSupportedJDK(jdkPath)) {\n                logUtils.logInfo(`[jdk] Verified path for setting ${jdkPathKey}: ${jdkPath}`);\n                return jdkPath;\n            }\n        }\n    }\n\n    for (const jdkEnvVar of JDK_ENV_VARS) {\n        const jdkPath = process.env[jdkEnvVar];\n        if (jdkPath) {\n            logUtils.logInfo(`[jdk] Resolved path for environment variable ${jdkEnvVar}: ${jdkPath}`);\n            if (isSupportedJDK(jdkPath)) {\n                logUtils.logInfo(`[jdk] Verified path for environment variable ${jdkEnvVar}: ${jdkPath}`);\n                return jdkPath;\n            }\n        }\n    }\n\n    logUtils.logInfo('[jdk] No supported JDK found');\n\n    if (interactive) {\n        logUtils.logInfo('[jdk] Selecting JDK installation');\n        const jdkPath = await select();\n        if (jdkPath) {\n            logUtils.logInfo(`[jdk] Selected JDK installation: ${jdkPath}`);\n            if (isSupportedJDK(jdkPath)) {\n                logUtils.logInfo(`[jdk] Verified selected JDK installation: ${jdkPath}`);\n                await vscode.workspace.getConfiguration().update(VISUALVM_JDK_PATH_KEY, jdkPath, vscode.ConfigurationTarget.Global);\n                return jdkPath;\n            } else {\n                logUtils.logError(`[jdk] Selected JDK installation is invalid: ${jdkPath}`);\n                vscode.window.showErrorMessage(`Selected JDK installation is invalid: ${jdkPath}`);\n            }\n        } else {\n            logUtils.logInfo('[jdk] JDK installation selection canceled');\n        }\n    }\n\n    return undefined;\n}\n\nasync function select(): Promise<string | undefined> {\n    const selectedJDKUri = await vscode.window.showOpenDialog({\n        title: 'Select Local JDK Installation Folder',\n        canSelectFiles: false,\n        canSelectFolders: true,\n        canSelectMany: false,\n        defaultUri: vscode.Uri.file(os.homedir()),\n        openLabel: process.platform !== 'darwin' ? 'Select JDK Installation' : 'Select'\n    });\n    const jdkPath = selectedJDKUri?.length === 1 ? selectedJDKUri[0].fsPath : undefined;\n    if (jdkPath && process.platform === 'darwin') {\n        const jdkHomePath = path.join(jdkPath, 'Contents', 'Home');\n        if (fs.existsSync(jdkHomePath)) {\n            return jdkHomePath;\n        }\n    }\n    return jdkPath;\n}\n\nexport function isSupportedJDK(jdkPath: string): boolean {\n    return !!getJpsPath(jdkPath);\n}\n\nexport function getJpsPath(jdkPath: string): string | undefined {\n    const jdkJpsPath = path.join(jdkPath, 'bin', process.platform === 'win32' ? 'jps.exe' : 'jps');\n    if (!fs.existsSync(jdkJpsPath)) {\n        logUtils.logWarning(`[jdk] Required jps binary does not exist (JRE only?): ${jdkJpsPath}`);\n        return undefined;\n    }\n    if (!fs.statSync(jdkJpsPath).isFile()) {\n        logUtils.logWarning(`[jdk] Required jps binary is not a file: ${jdkJpsPath}`);\n        return undefined;\n    }\n    return jdkJpsPath;\n}\n\nexport function getPackages(): string {\n    let ret = 'java.**, javax.**, jdk.**';\n    ret += ', org.graalvm.**';\n    ret += ', com.sun.**, sun.**, sunw.**';\n    ret += ', org.omg.CORBA.**, org.omg.CosNaming.**, COM.rsa.**';\n    if (process.platform === 'darwin') {\n        ret += ', apple.laf.**, apple.awt.**, com.apple.**';\n    }\n    return ret;\n}\n\nexport async function getSources(jdkPath: string): Promise<{ path: string; modular: boolean } | undefined> {\n    const modularJdkSrc = path.join(jdkPath, 'lib', 'src.zip');\n    if (fs.existsSync(modularJdkSrc)) {\n        return { path: modularJdkSrc, modular: true };\n    }\n\n    const jdkSrc = path.join(jdkPath, 'src.zip');\n    if (fs.existsSync(jdkSrc)) {\n        return { path: jdkSrc, modular: false };\n    }\n    \n    return undefined;\n}\n"
  },
  {
    "path": "integrations/vscode/src/logUtils.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as vscode from 'vscode';\n\nlet LOG_OUTPUT: vscode.LogOutputChannel;\nexport function registerExtensionForLogging(context: vscode.ExtensionContext) {\n    if (!LOG_OUTPUT) {\n        LOG_OUTPUT = vscode.window.createOutputChannel(context.extension.packageJSON.displayName, { log: true });\n    }\n}\n\nexport function logTrace(record: string) {\n    if (!LOG_OUTPUT) { throw new Error(\"Extension isn't registered for logging.\"); }\n    LOG_OUTPUT.trace(record);\n}\n\nexport function logDebug(record: string) {\n    if (!LOG_OUTPUT) { throw new Error(\"Extension isn't registered for logging.\"); }\n    LOG_OUTPUT.debug(record);\n}\n\nexport function logInfo(record: string) {\n    if (!LOG_OUTPUT) { throw new Error(\"Extension isn't registered for logging.\"); }\n    LOG_OUTPUT.info(record);\n}\n\nexport function logWarning(record: string) {\n    if (!LOG_OUTPUT) { throw new Error(\"Extension isn't registered for logging.\"); }\n    LOG_OUTPUT.warn(record);\n}\n\nexport function logError(record: string) {\n    if (!LOG_OUTPUT) { throw new Error(\"Extension isn't registered for logging.\"); }\n    LOG_OUTPUT.error(record);\n}\n\nexport function logAndThrow(record: string, errFnc?: (err: Error) => Error) {\n    if (!LOG_OUTPUT) { throw new Error(\"Extension isn't registered for logging.\"); }\n    LOG_OUTPUT.error(record);\n    const err = new Error(record);\n    throw errFnc ? errFnc(err) : err;\n}\n"
  },
  {
    "path": "integrations/vscode/src/monitoredProcesses.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as vscode from 'vscode';\nimport * as process from 'process';\nimport * as jdk from './jdk';\nimport * as parameters from './parameters';\nimport * as runningProcesses from './runningProcesses';\nimport * as logUtils from './logUtils';\n\n\nexport const AUTO_SELECT_PROJECT_PROCESS_KEY = 'visualvm.integration.automaticallySelectProjectProcess';\nexport const CUSTOMIZE_PROJECT_PROCESS_DISPLAYNAME_KEY = 'visualvm.integration.customizeDisplayNameForProjectProcess';\n\nexport type OnChanged = (added: MonitoredProcess | undefined, removed: MonitoredProcess | undefined, target: any | undefined) => void;\nexport type OnPidChanged = () => void;\n\nconst ON_CHANGED_LISTENERS: OnChanged[] = [];\nexport function onChanged(listener: OnChanged) {\n    ON_CHANGED_LISTENERS.push(listener);\n}\nfunction notifyChanged(added: MonitoredProcess | undefined, removed: MonitoredProcess | undefined, target?: any) {\n    for (const listener of ON_CHANGED_LISTENERS) {\n        listener(added, removed, target);\n    }\n}\n\nexport function initialize(context: vscode.ExtensionContext) {\n    const configurationProvider = new ConfigurationProvider();\n    context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('java8+', configurationProvider));\n    context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('java+', configurationProvider));\n    context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('java', configurationProvider));\n\n    context.subscriptions.push(vscode.debug.onDidStartDebugSession(session => { debugSessionStarted(session); }));\n    context.subscriptions.push(vscode.debug.onDidTerminateDebugSession(session => { debugSessionTerminated(session); }));\n\n    logUtils.logInfo('[monitoredProcess] Initialized');\n}\n\nconst MONITORED_PROCESSES: MonitoredProcess[] = [];\n\nexport function add(running: runningProcesses.RunningProcess, target?: any): MonitoredProcess | undefined {\n    logUtils.logInfo(`[monitoredProcess] Adding running process ${running.displayName}@${running.pid}`);\n    const monitoredRunning = getPids();\n    if (!monitoredRunning.includes(running.pid)) {\n        const monitoredProcess = new MonitoredProcess(running.pid.toString(), running.displayName, undefined, running.pid);\n        return addMonitored(monitoredProcess, target);\n    } else {\n        logUtils.logWarning(`[monitoredProcess] Process already tracked: ${running.displayName}@${running.pid}`);\n        return undefined;\n    }\n}\n\nfunction addMonitored(monitored: MonitoredProcess, target?: any): MonitoredProcess {\n    logUtils.logInfo(`[monitoredProcess] Started tracking process ${monitored.displayName}@${monitored.id}`);\n    MONITORED_PROCESSES.push(monitored);\n    notifyChanged(monitored, undefined, target);\n    return monitored;\n}\n\nexport function remove(monitored: MonitoredProcess, target?: any): MonitoredProcess | undefined {\n    logUtils.logInfo(`[monitoredProcess] Removing monitored process ${monitored.displayName}@${monitored.id}`);\n    const index = MONITORED_PROCESSES.indexOf(monitored);\n    if (index > -1) {\n        logUtils.logInfo(`[monitoredProcess] Stopped tracking process ${monitored.displayName}@${monitored.id}`);\n        MONITORED_PROCESSES.splice(index, 1);\n        monitored.release();\n        notifyChanged(undefined, monitored, target);\n        return monitored;\n    } else {\n        logUtils.logWarning(`[monitoredProcess] Process not tracked: ${monitored.displayName}@${monitored.id}`);\n        return undefined;\n    }\n}\n\nexport function getPids(): number[] {\n    const pids: number[] = [];\n    for (const process of MONITORED_PROCESSES) {\n        const pid = process.getPid();\n        if (pid !== undefined && pid !== null) {\n            pids.push(pid);\n        }\n    }\n    return pids;\n}\n\nfunction debugSessionStarted(session: vscode.DebugSession) {\n    const vmArgs = session.configuration.vmArgs;\n    if (vmArgs) {\n        for (const monitoredProcess of MONITORED_PROCESSES) {\n            const id = parameters.vmArgId(monitoredProcess.id);\n            if (vmArgs.includes(id)) {\n                logUtils.logInfo(`[monitoredProcess] Session started for process ${monitoredProcess.displayName}@${monitoredProcess.id}`);\n                monitoredProcess.sessionStarted(session);\n                break;\n            }\n        }\n    }\n}\n\nfunction debugSessionTerminated(session: vscode.DebugSession) {\n    for (const monitoredProcess of MONITORED_PROCESSES) {\n        if (monitoredProcess.isSession(session)) {\n            logUtils.logInfo(`[monitoredProcess] Session terminated for process ${monitoredProcess.displayName}@${monitoredProcess.id}`);\n            remove(monitoredProcess);\n            break;\n        }\n    }\n}\n\nexport class MonitoredProcess {\n\n    readonly id: string;\n    readonly displayName: string;\n    readonly workspaceFolder: vscode.WorkspaceFolder | undefined;\n\n    readonly isManuallySelected: boolean;\n\n    private pid: number | undefined | null = undefined;\n    private session: vscode.DebugSession | undefined = undefined;\n\n    constructor(id: string, displayName: string, workspaceFolder?: vscode.WorkspaceFolder, pid?: number) {\n        this.id = id;\n        this.displayName = displayName;\n        this.workspaceFolder = workspaceFolder;\n        this.pid = pid;\n        this.isManuallySelected = pid !== undefined;\n    }\n\n    isSession(session: vscode.DebugSession) {\n        return this.session === session;\n    }\n\n    sessionStarted(session: vscode.DebugSession) {\n        this.session = session;\n        if (this.pid === undefined) {\n            const onFound = (pid: number) => {\n                this.pid = pid;\n                this.notifyPidChanged();\n                logUtils.logInfo(`[monitoredProcess] Found running process ${this.displayName}@${this.id}: pid=${pid}`);\n            };\n            const onTimeout = () => {\n                logUtils.logInfo(`[monitoredProcess] Timed out waiting for process ${this.displayName}@${this.id}`);\n                remove(this);\n            };\n            runningProcesses.searchByParameter(parameters.vmArgId(this.id), onFound, onTimeout);\n        }\n    }\n\n    getPid(interactive: boolean = true): number | undefined | null { // undefined - not discovered yet, null - terminated\n        if (this.pid) {\n            try {\n                process.kill(this.pid, 0);\n            } catch (err) {\n                logUtils.logInfo(`[monitoredProcess] Detected terminated process ${this.displayName}@${this.id}`);\n                this.release();\n                if (interactive) {\n                    vscode.window.showWarningMessage(`Process ${this.displayName} already terminated.`);\n                }\n                // Must be delayed to not break iterating MONITORED_PROCESSES[].getPid() \n                setTimeout(() => { remove(this); }, 0);\n            }\n        }\n        return this.pid;\n    }\n\n    release() {\n        if (this.pid !== null) {\n            logUtils.logInfo(`[monitoredProcess] Releasing process ${this.displayName}@${this.id}`);\n            if (this.pid === undefined) {\n                runningProcesses.stopSearching(parameters.vmArgId(this.id));\n            }\n            this.pid = null;\n            this.notifyPidChanged();\n            this.ON_PID_CHANGED_LISTENERS.length = 0;\n        }\n        this.session = undefined;\n    }\n\n    private ON_PID_CHANGED_LISTENERS: OnPidChanged[] = [];\n    onPidChanged(listener: OnPidChanged) {\n        this.ON_PID_CHANGED_LISTENERS.push(listener);\n    }\n    private notifyPidChanged() {\n        for (const listener of this.ON_PID_CHANGED_LISTENERS) {\n            listener();\n        }\n    }\n\n}\n\nfunction displayName(displayName: string | undefined): string {\n    return displayName = displayName || 'VS Code Project';\n}\n\nclass ConfigurationProvider implements vscode.DebugConfigurationProvider {\n\n    resolveDebugConfiguration/*WithSubstitutedVariables?*/(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken): vscode.ProviderResult<vscode.DebugConfiguration> {\n        logUtils.logInfo(`[monitoredProcess] VS Code starting new process${folder ? ' for folder ' + folder.name : ''}`);\n        return new Promise(async resolve => {\n            const name = displayName(folder?.name);\n            const vmArgs: string[] = [];\n            if (vscode.workspace.getConfiguration().get<boolean>(CUSTOMIZE_PROJECT_PROCESS_DISPLAYNAME_KEY)) {\n                logUtils.logInfo(`[monitoredProcess] Will customize display name: ${name}`);\n                vmArgs.push(parameters.vmArgDisplayName(name));\n            }\n            if (vscode.workspace.getConfiguration().get<boolean>(AUTO_SELECT_PROJECT_PROCESS_KEY)) {\n                const jdkPath = await jdk.getPath(false);\n                const jpsPath = jdkPath ? jdk.getJpsPath(jdkPath) : undefined;\n                if (jpsPath) {\n                    runningProcesses.setJpsPath(jpsPath);\n                    const id = Date.now().toString();\n                    const process = new MonitoredProcess(id, name, folder);\n                    logUtils.logInfo(`[monitoredProcess] Will select the process with id: ${id}`);\n                    addMonitored(process);\n                    vmArgs.push(parameters.vmArgId(id));\n                } else {\n                    logUtils.logWarning('[monitoredProcess] Will not select the process, no JDK/jps found');\n                    const reason = jdkPath ? 'The JDK for VisualVM is not valid.' : 'No JDK for VisualVM found.';\n                    const msg = `${reason} The started process will not be selected automatically. Please select a local JDK installation, and then select the started process manually.`;\n                    const selectOption = 'Select JDK Installation';\n                    vscode.window.showInformationMessage(msg, selectOption).then(selectedOption => {\n                        if (selectedOption === selectOption) {\n                            jdk.getPath();\n                        }\n                    });\n                }\n            }\n            if (vmArgs.length) {\n                if (!config.vmArgs) {\n                    config.vmArgs = vmArgs.join(' ');\n                } else {\n                    if (Array.isArray(config.vmArgs)) {\n                        config.vmArgs.push(...vmArgs);\n                    } else {\n                        config.vmArgs = `${config.vmArgs} ${vmArgs.join(' ')}`;\n                    }\n                }\n                logUtils.logInfo(`[monitoredProcess] Added vmArgs for process startup: ${vmArgs.join(' ')}`);\n            } else {\n                logUtils.logInfo('[monitoredProcess] No vmArgs added for process startup');\n            }\n            resolve(config);\n        });\n\t}\n\n}\n"
  },
  {
    "path": "integrations/vscode/src/nodes.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as vscode from 'vscode';\nimport * as visualvm from './visualvm';\nimport * as commands from './commands';\nimport * as parameters from './parameters';\nimport * as presets from './presets';\nimport * as runningProcesses from './runningProcesses';\nimport * as monitoredProcesses from './monitoredProcesses';\nimport * as logUtils from './logUtils';\n\n\nconst CONFIGURABLE_NODES_KEY = 'visualvm.configurableNodes';\nconst INVOKABLE_NODES_KEY = 'visualvm.invokableNodes';\n\nexport function initialize(context: vscode.ExtensionContext) {\n    const configurableNodes = [\n        WhenStartedNode.CONTEXT_BASE + ConfigurableNode.CONFIGURABLE_SUFFIX,\n        CpuSamplerFilterNode.CONTEXT_BASE + ConfigurableNode.CONFIGURABLE_SUFFIX,\n        CpuSamplerSamplingRateNode.CONTEXT_BASE + ConfigurableNode.CONFIGURABLE_SUFFIX,\n        MemorySamplerSamplingRateNode.CONTEXT_BASE + ConfigurableNode.CONFIGURABLE_SUFFIX,\n        JfrSettingsNode.CONTEXT_BASE + ConfigurableNode.CONFIGURABLE_SUFFIX\n    ];\n    vscode.commands.executeCommand('setContext', CONFIGURABLE_NODES_KEY, configurableNodes);\n\n    const invokableNodes = [\n        ThreadDumpNode.CONTEXT_BASE + InvokableNode.INVOKABLE_SUFFIX,\n        HeapDumpNode.CONTEXT_BASE + InvokableNode.INVOKABLE_SUFFIX,\n        CpuSamplerNode.CONTEXT_BASE + InvokableNode.INVOKABLE_SUFFIX,\n        MemorySamplerNode.CONTEXT_BASE + InvokableNode.INVOKABLE_SUFFIX,\n        JfrNode.CONTEXT_BASE + InvokableNode.INVOKABLE_SUFFIX\n    ];\n    vscode.commands.executeCommand('setContext', INVOKABLE_NODES_KEY, invokableNodes);\n\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_SELECT_PROCESS_GLOBAL, async () => {\n        const current = monitoredProcesses.getPids();\n        const selected = await runningProcesses.select(current);\n        if (selected) {\n            monitoredProcesses.add(selected);\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_SELECT_PROCESS, async (node: ProcessNode) => {\n        const current = monitoredProcesses.getPids();\n        const selected = await runningProcesses.select(current);\n        if (selected) {\n            monitoredProcesses.add(selected, node);\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_CLEAR_PROCESS, (node: ProcessNode) => {\n        const process = node.getProcess();\n        if (process) {\n            monitoredProcesses.remove(process, node);\n        } else {\n            provider().removeProcessContainer(node);\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_CONFIGURE_SETTING, (node: ConfigurableNode) => {\n        node.configure();\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_OPEN_PROCESS, async (node: BaseNode) => {\n        const process = await findProcess(node);\n        const pid = process?.getPid();\n        if (pid) {\n            logUtils.logInfo(`[nodes] Opening process pid ${pid}`);\n            visualvm.show(pid, process?.workspaceFolder);\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_THREADDUMP_TAKE, async (node: BaseNode) => {\n        const process = await findProcess(node);\n        const pid = process?.getPid();\n        if (pid) {\n            logUtils.logInfo(`[nodes] Taking thread dump for pid ${pid}`);\n            const command = parameters.threadDump(pid);\n            visualvm.perform(command, process?.workspaceFolder);\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_HEAPDUMP_TAKE, async (node: BaseNode) => {\n        const process = await findProcess(node);\n        const pid = process?.getPid();\n        if (pid) {\n            logUtils.logInfo(`[nodes] Taking heap dump for pid ${pid}`);\n            const command = parameters.heapDump(pid);\n            visualvm.perform(command, process?.workspaceFolder);\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_CPU_SAMPLER_START, async (node: BaseNode) => {\n        const processNode = findProcessNode(node);\n        if (processNode) {\n            const process = await findProcess(node);\n            const pid = process?.getPid();\n            if (process && pid) {\n                const samplingFilter = processNode.cpuSamplerFilterPresets.getSelectedValue();\n                const samplingRate = processNode.cpuSamplerSamplingRatePresets.getSelectedValue();\n                const workspaceFolder = process.workspaceFolder;\n                logUtils.logInfo(`[nodes] Starting CPU sampling for pid ${pid} with filter ${samplingFilter} and sampling rate ${samplingRate} for folder ${workspaceFolder}`);\n                const commandPromise = parameters.cpuSamplerStart(pid, samplingFilter, samplingRate, workspaceFolder);\n                visualvm.perform(commandPromise, workspaceFolder);\n            }\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_CPU_SAMPLER_SNAPSHOT, async (node: BaseNode) => {\n        const process = await findProcess(node);\n        const pid = process?.getPid();\n        if (pid) {\n            logUtils.logInfo(`[nodes] Taking (CPU) sampling snapshot for pid ${pid}`);\n            const command = parameters.samplerSnapshot(pid);\n            visualvm.perform(command, process?.workspaceFolder);\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_CPU_SAMPLER_STOP, async (node: BaseNode) => {\n        const process = await findProcess(node);\n        const pid = process?.getPid();\n        if (pid) {\n            logUtils.logInfo(`[nodes] Stopping (CPU) sampling for pid ${pid}`);\n            const command = parameters.samplerStop(pid);\n            visualvm.perform(command, process?.workspaceFolder);\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_MEMORY_SAMPLER_START, async (node: BaseNode) => {\n        const processNode = findProcessNode(node);\n        if (processNode) {\n            const process = await findProcess(node);\n            const pid = process?.getPid();\n            if (pid) {\n                const samplingRate = processNode.memorySamplerSamplingRatePresets.getSelectedValue();\n                logUtils.logInfo(`[nodes] Starting memory sampling for pid ${pid} with sampling rate ${samplingRate}`);\n                const command = parameters.memorySamplerStart(pid, samplingRate);\n                visualvm.perform(command, process?.workspaceFolder);\n            }\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_MEMORY_SAMPLER_SNAPSHOT, async (node: BaseNode) => {\n        const process = await findProcess(node);\n        const pid = process?.getPid();\n        if (pid) {\n            logUtils.logInfo(`[nodes] Taking (memory) sampling snapshot for pid ${pid}`);\n            const command = parameters.samplerSnapshot(pid);\n            visualvm.perform(command, process?.workspaceFolder);\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_MEMORY_SAMPLER_STOP, async (node: BaseNode) => {\n        const process = await findProcess(node);\n        const pid = process?.getPid();\n        if (pid) {\n            logUtils.logInfo(`[nodes] Stopping (memory) sampling for pid ${pid}`);\n            const command = parameters.samplerStop(pid);\n            visualvm.perform(command, process?.workspaceFolder);\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_JFR_START, async (node: BaseNode) => {\n        const processNode = findProcessNode(node);\n        if (processNode) {\n            const process = await findProcess(processNode);\n            const pid = process?.getPid();\n            if (process && pid) {\n                const jfrSettings = processNode.jfrSettingsPresets.getSelectedValue();\n                logUtils.logInfo(`[nodes] Starting flight recording for pid ${pid} with settings ${jfrSettings}`);\n                const command = parameters.jfrRecordingStart(pid, process.displayName, jfrSettings);\n                visualvm.perform(command, process.workspaceFolder);\n            }\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_JFR_DUMP, async (node: BaseNode) => {\n        const process = await findProcess(node);\n        const pid = process?.getPid();\n        if (pid) {\n            logUtils.logInfo(`[nodes] Dumping flight recording data for pid ${pid}`);\n            const command = parameters.jfrRecordingDump(pid);\n            visualvm.perform(command, process?.workspaceFolder);\n        }\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_JFR_STOP, async (node: BaseNode) => {\n        const process = await findProcess(node);\n        const pid = process?.getPid();\n        if (pid) {\n            logUtils.logInfo(`[nodes] Stopping flight recording for pid ${pid}`);\n            const command = parameters.jfrRecordingStop(pid);\n            visualvm.perform(command, process?.workspaceFolder);\n        }\n\t}));\n\n    monitoredProcesses.onChanged((added, removed, target) => {\n        provider().processesChanged(added, removed, target);\n    });\n\n    context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(event => {\n        if (event.affectsConfiguration(monitoredProcesses.AUTO_SELECT_PROJECT_PROCESS_KEY)) {\n            const isAutoSelectProcess = vscode.workspace.getConfiguration().get<boolean>(monitoredProcesses.AUTO_SELECT_PROJECT_PROCESS_KEY);\n            logUtils.logInfo(`[nodes] Automatic process selection changed to ${isAutoSelectProcess ? 'enabled' : 'disabled'}`);\n            provider().autoSelectProjectProcessChanged(!!isAutoSelectProcess);\n        }\n    }));\n}\n\nasync function findProcess(node: BaseNode): Promise<monitoredProcesses.MonitoredProcess | undefined> {\n    const processNode = findProcessNode(node);\n    if (processNode) {\n        let process = processNode.getProcess();\n        if (!process) {\n            const current = monitoredProcesses.getPids();\n            const selected = await runningProcesses.select(current);\n            if (selected) {\n                process = monitoredProcesses.add(selected, node);\n            }\n        }\n        return process;\n    }\n    return undefined;\n}\n\nfunction findProcessNode(node: BaseNode): ProcessNode | undefined {\n    while (node.parent !== undefined) {\n        node = node.parent;\n    }\n    return node instanceof ProcessNode ? node as ProcessNode : undefined;\n}\n\ntype TreeChanged = (node?: BaseNode) => void;\n\nclass BaseNode extends vscode.TreeItem {\n\n    parent: BaseNode | undefined;\n    children: BaseNode[] | undefined | null;\n\n    constructor(label: string, description: string | undefined, contextValue: string | undefined, children: BaseNode[] | undefined | null, expanded: boolean | undefined) {\n        super(label);\n        this.description = description;\n        this.contextValue = contextValue;\n        this.setChildren(children);\n        if (!children || expanded === undefined) {\n            this.collapsibleState = vscode.TreeItemCollapsibleState.None;\n        } if (expanded === true) {\n            this.collapsibleState = vscode.TreeItemCollapsibleState.Expanded;\n        } else if (expanded === false) {\n            this.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;\n        }\n    }\n\n    public setChildren(children: BaseNode[] | undefined | null) {\n        if (this.children) {\n            for (const child of this.children) {\n                child.parent = undefined;\n            }\n        }\n        this.children = children;\n        if (this.children) {\n            for (const child of this.children) {\n                child.parent = this;\n            }\n        }\n    }\n\n    public getChildren(): BaseNode[] | undefined {\n        return this.children ? this.children : undefined;\n    }\n\n    public removeFromParent(treeChanged?: TreeChanged): boolean {\n        const parent = this.parent;\n        if (parent) {\n            this.parent = undefined;\n            if (parent.removeChild(this)) {\n                if (treeChanged) {\n                    treeChanged(parent);\n                }\n                return true;\n            }\n        }\n        return false;\n    }\n\n    removeChild(child: BaseNode): boolean {\n        if (this.children) {\n            const idx = this.children.indexOf(child);\n            if (idx >= 0) {\n                this.children.splice(idx, 1);\n                return true;\n            }\n        }\n        return false;\n    }\n\n}\n\nclass ChangeableNode extends BaseNode {\n\n    protected readonly treeChanged: TreeChanged;\n\n    constructor(treeChanged: TreeChanged, label: string, description: string | undefined, contextValue: string | undefined, children: BaseNode[] | undefined | null, expanded: boolean | undefined) {\n        super(label, description, contextValue, children, expanded);\n        this.treeChanged = treeChanged;\n    }\n\n}\n\nabstract class ConfigurableNode extends ChangeableNode {\n\n    static readonly CONFIGURABLE_SUFFIX = '.configurable';\n    static readonly NOT_CONFIGURABLE_SUFFIX = 'notConfigurable';\n\n    private readonly contextBase: string;\n\n    private readonly presets: presets.Presets;\n\n    constructor(presets: presets.Presets, treeChanged: TreeChanged, label: string, description: string | undefined, contextBase: string, children: BaseNode[] | undefined | null, expanded: boolean | undefined) {\n        super(treeChanged, label, description, `${contextBase}${ConfigurableNode.CONFIGURABLE_SUFFIX}`, children, expanded);\n        this.contextBase = contextBase;\n        this.presets = presets;\n        this.presets.onChanged(() => { this.updateFromPresets(); this.treeChanged(this); });\n        this.updateFromPresets();\n    }\n\n    setConfigurable(configurable: boolean) {\n        // Only called from ProcessNode, tree will be refreshed from there\n        this.contextValue = `${this.contextBase}${configurable ? ConfigurableNode.CONFIGURABLE_SUFFIX : ConfigurableNode.NOT_CONFIGURABLE_SUFFIX}`;\n    }\n\n    configure(actionName?: string) {\n        actionName = actionName || `Configure ${this.presets.name}`;\n        this.presets.select(actionName);\n    }\n\n    protected getPresetValue(): string {\n        return this.presets.getSelectedValue();\n    }\n\n    private updateFromPresets() {\n        this.description = this.presets.getSelectedString();\n    }\n\n}\n\nabstract class InvokableNode extends BaseNode {\n\n    static readonly INVOKABLE_SUFFIX = '.invokable';\n    static readonly NOT_INVOKABLE_SUFFIX = '.notInvokable';\n\n    private readonly contextBase: string;\n\n    constructor(label: string, description: string | undefined, contextBase: string, children: BaseNode[] | undefined | null, expanded: boolean | undefined) {\n        super(label, description, `${contextBase}${InvokableNode.INVOKABLE_SUFFIX}`, children, expanded);\n        this.contextBase = contextBase;\n    }\n\n    setInvokable(invokable: boolean) {\n        // Only called from ProcessNode, tree will be refreshed from there\n        this.contextValue = `${this.contextBase}${invokable ? InvokableNode.INVOKABLE_SUFFIX : InvokableNode.NOT_INVOKABLE_SUFFIX}`;\n    }\n\n}\n\nclass WhenStartedNode extends ConfigurableNode {\n\n    static readonly CONTEXT_BASE = 'visualvm.WhenStartedNode';\n\n    constructor(presets: presets.Presets, treeChanged: TreeChanged) {\n        super(presets, treeChanged, 'When started:', undefined, WhenStartedNode.CONTEXT_BASE, undefined, undefined);\n        this.tooltip = 'Action when a project process is started';\n    }\n\n}\n\nclass ThreadDumpNode extends InvokableNode {\n\n    static readonly CONTEXT_BASE = 'visualvm.ThreadDumpNode';\n\n    constructor() {\n        super('Thread dump', undefined, ThreadDumpNode.CONTEXT_BASE, undefined, undefined);\n        this.tooltip = 'Take a thread dump and open it in VisualVM';\n    }\n\n}\n\nclass HeapDumpNode extends InvokableNode {\n\n    static readonly CONTEXT_BASE = 'visualvm.HeapDumpNode';\n\n    constructor() {\n        super('Heap dump', undefined, HeapDumpNode.CONTEXT_BASE, undefined, undefined);\n        this.tooltip = 'Take a heap dump and open it in VisualVM';\n    }\n\n}\n\nclass CpuSamplerNode extends InvokableNode {\n\n    static readonly CONTEXT_BASE = 'visualvm.CpuSamplerNode';\n\n    constructor(presets: presets.Presets[], treeChanged: TreeChanged) {\n        super('CPU sampler', undefined, CpuSamplerNode.CONTEXT_BASE, [ ...CpuSamplerNode.createNodes(presets, treeChanged) ], false);\n        this.tooltip = 'Control a CPU sampling session in VisualVM';\n    }\n\n    private static createNodes(presets: presets.Presets[], treeChanged: TreeChanged): BaseNode[] {\n        const nodes: BaseNode[] = [];\n        nodes.push(new CpuSamplerFilterNode(presets[0], treeChanged));\n        nodes.push(new CpuSamplerSamplingRateNode(presets[1], treeChanged));\n        return nodes;\n    }\n\n}\n\nclass CpuSamplerFilterNode extends ConfigurableNode {\n\n    static readonly CONTEXT_BASE = 'visualvm.CpuSamplerFilterNode';\n\n    constructor(presets: presets.Presets, treeChanged: TreeChanged) {\n        super(presets, treeChanged, 'Filter:', undefined, CpuSamplerFilterNode.CONTEXT_BASE, undefined, undefined);\n        this.tooltip = 'CPU sampling filter';\n    }\n\n}\n\nclass CpuSamplerSamplingRateNode extends ConfigurableNode {\n\n    static readonly CONTEXT_BASE = 'visualvm.CpuSamplerSamplingRateNode';\n\n    constructor(presets: presets.Presets, treeChanged: TreeChanged) {\n        super(presets, treeChanged, 'Sampling rate:', undefined, CpuSamplerSamplingRateNode.CONTEXT_BASE, undefined, undefined);\n        this.tooltip = 'CPU sampling rate';\n    }\n\n}\n\nclass MemorySamplerNode extends InvokableNode {\n\n    static readonly CONTEXT_BASE = 'visualvm.MemorySamplerNode';\n\n    constructor(presets: presets.Presets, treeChanged: TreeChanged) {\n        super('Memory sampler', undefined, MemorySamplerNode.CONTEXT_BASE, [ ...MemorySamplerNode.createNodes(presets, treeChanged) ], false);\n        this.tooltip = 'Control a memory sampling session in VisualVM';\n    }\n\n    private static createNodes(presets: presets.Presets, treeChanged: TreeChanged): BaseNode[] {\n        const nodes: BaseNode[] = [];\n        nodes.push(new MemorySamplerSamplingRateNode(presets, treeChanged));\n        return nodes;\n    }\n\n}\n\nclass MemorySamplerSamplingRateNode extends ConfigurableNode {\n\n    static readonly CONTEXT_BASE = 'visualvm.MemorySamplerSamplingRateNode';\n\n    constructor(presets: presets.Presets, treeChanged: TreeChanged) {\n        super(presets, treeChanged, 'Sampling rate:', undefined, MemorySamplerSamplingRateNode.CONTEXT_BASE, undefined, undefined);\n        this.tooltip = 'Memory sampling rate';\n    }\n\n}\n\nclass JfrNode extends InvokableNode {\n\n    static readonly CONTEXT_BASE = 'visualvm.JfrNode';\n\n    constructor(presets: presets.Presets, treeChanged: TreeChanged) {\n        super('JFR', undefined, JfrNode.CONTEXT_BASE, [ ...JfrNode.createNodes(presets, treeChanged) ], false);\n        this.tooltip = 'Control a flight recording session in VisualVM';\n    }\n\n    private static createNodes(presets: presets.Presets, treeChanged: TreeChanged): BaseNode[] {\n        const nodes: BaseNode[] = [];\n        nodes.push(new JfrSettingsNode(presets, treeChanged));\n        return nodes;\n    }\n\n}\n\nclass JfrSettingsNode extends ConfigurableNode {\n\n    static readonly CONTEXT_BASE = 'visualvm.JfrSettingsNode';\n\n    constructor(presets: presets.Presets, treeChanged: TreeChanged) {\n        super(presets, treeChanged, 'Settings:', undefined, JfrSettingsNode.CONTEXT_BASE, undefined, undefined);\n        this.tooltip = 'Flight recorder settings';\n    }\n\n}\n\nclass ProcessNode extends ChangeableNode {\n\n    private static CONTEXT_BASE = 'visualvm.ProcessNode';\n    private static CONTEXT_NO_PROCESS = `${this.CONTEXT_BASE}.noProcess`;\n    private static CONTEXT_HAS_ID = `${this.CONTEXT_BASE}.hasId`;\n    private static CONTEXT_HAS_PID = `${this.CONTEXT_BASE}.hasPid`;\n    // private static CONTEXT_TERMINATED = `${this.CONTEXT_BASE}.terminated`;\n\n    readonly isMaster: boolean;\n    private isAutoSelectProcess: boolean;\n\n    readonly whenStartedPresets: presets.Presets;\n    readonly cpuSamplerFilterPresets: presets.Presets;\n    readonly cpuSamplerSamplingRatePresets: presets.Presets;\n    readonly memorySamplerSamplingRatePresets: presets.Presets;\n    readonly jfrSettingsPresets: presets.Presets;\n\n    private process: monitoredProcesses.MonitoredProcess | undefined;\n\n    // process: undefined -> isMaster, null -> isMaster && persistentPresets\n    constructor(treeChanged: TreeChanged, process?: monitoredProcesses.MonitoredProcess | undefined | null, isAutoSelectProcess?: boolean) {\n        super(treeChanged, 'Process:', undefined, ProcessNode.CONTEXT_NO_PROCESS, [], !process);\n        this.tooltip = 'Java process monitored by VisualVM';\n        this.isMaster = !process;\n        this.isAutoSelectProcess = !!isAutoSelectProcess;\n        \n        const persistentPresets = process === null;\n        this.whenStartedPresets = persistentPresets ? presets.WhenStartedPresets.PERSISTENT : new presets.WhenStartedPresets();\n        this.cpuSamplerFilterPresets = persistentPresets ? presets.CpuSamplerFilterPresets.PERSISTENT : new presets.CpuSamplerFilterPresets();\n        this.cpuSamplerSamplingRatePresets = persistentPresets ? presets.CpuSamplerSamplingRatePresets.PERSISTENT : new presets.CpuSamplerSamplingRatePresets();\n        this.memorySamplerSamplingRatePresets = persistentPresets ? presets.MemorySamplerSamplingRatePresets.PERSISTENT : new presets.MemorySamplerSamplingRatePresets();\n        this.jfrSettingsPresets = persistentPresets ? presets.JfrSettingsPresets.PERSISTENT : new presets.JfrSettingsPresets();\n\n        const nodes: BaseNode[] = [];\n        nodes.push(new ThreadDumpNode());\n        nodes.push(new HeapDumpNode());\n        nodes.push(new CpuSamplerNode([ this.cpuSamplerFilterPresets, this.cpuSamplerSamplingRatePresets ], treeChanged));\n        nodes.push(new MemorySamplerNode(this.memorySamplerSamplingRatePresets, treeChanged));\n        nodes.push(new JfrNode(this.jfrSettingsPresets, treeChanged));\n        this.setChildren(nodes);\n        \n        this.setProcess(process ? process : undefined);\n    }\n\n    getProcess(): monitoredProcesses.MonitoredProcess | undefined {\n        return this.process;\n    }\n\n    setProcess(process: monitoredProcesses.MonitoredProcess | undefined) {\n        this.process = process;\n        this.process?.onPidChanged(() => { this.updateProcess(); });\n        this.updateProcess(true);\n        this.updateWhenStartedAvailable();\n    }\n\n    autoSelectProcessChanged(isAutoSelectProcess: boolean) {\n        this.isAutoSelectProcess = isAutoSelectProcess;\n        if (!this.process) {\n            this.description = this.descriptionHint();\n            this.treeChanged(this);\n        }\n        this.updateWhenStartedAvailable();\n    }\n\n    private updateWhenStartedAvailable(): boolean {\n        if (this.isMaster) {\n            const hasWhenStartedNode = !!this.whenStartedNode();\n            const hasSupportedProcess = this.process === undefined || !this.process.isManuallySelected;\n            if (this.isAutoSelectProcess && hasSupportedProcess) {\n                if (!hasWhenStartedNode) {\n                    const whenStartedNode = new WhenStartedNode(this.whenStartedPresets, this.treeChanged);\n                    whenStartedNode.parent = this;\n                    this.children?.unshift(whenStartedNode);\n                    this.treeChanged(this);\n                    return true;\n                }\n            } else {\n                if (hasWhenStartedNode) {\n                    this.children?.splice(0, 1);\n                    this.treeChanged(this);\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    private updateProcess(initialUpdate: boolean = false) {\n        if (this.process) {\n            const name = this.process.displayName;\n            const pid = this.process.getPid();\n            if (pid === null) {\n                // Do not update & refresh, will be reset/removed immediately after\n                return;\n                // this.description = `${name} (terminated)`;\n                // this.contextValue = ProcessNode.CONTEXT_TERMINATED;\n            } else if (pid === undefined) {\n                this.description = `${name} (pid pending...)`;\n                this.contextValue = ProcessNode.CONTEXT_HAS_ID;\n                this.updateInvokables(false);\n            } else {\n                this.description = `${name} (pid ${pid})`;\n                this.contextValue = ProcessNode.CONTEXT_HAS_PID;\n                if (!initialUpdate) {\n                    setTimeout(() => { this.handleWhenStarted(); }, 0);\n                }\n                this.updateInvokables(true);\n            }\n            this.whenStartedNode()?.setConfigurable(false);\n        } else {\n            this.description = this.descriptionHint();\n            this.contextValue = ProcessNode.CONTEXT_NO_PROCESS;\n            this.whenStartedNode()?.setConfigurable(true);\n            this.updateInvokables(true);\n        }\n        this.treeChanged(this);\n    }\n\n    private descriptionHint(): string {\n        return this.isAutoSelectProcess ? 'start new or select running...' : 'select running...';\n    }\n\n    private whenStartedNode(): WhenStartedNode | undefined {\n        return this.children?.[0] instanceof WhenStartedNode ? (this.children[0] as WhenStartedNode) : undefined;\n    }\n\n    private handleWhenStarted() {\n        const whenStartedNode = this.whenStartedNode();\n        if (whenStartedNode) { // When started is supported\n            const command = this.whenStartedPresets.getSelectedValue();\n            if (command) { // When started is set up to perform an action\n                vscode.commands.executeCommand(command, whenStartedNode);\n            }\n        }\n    }\n\n    private updateInvokables(invokable: boolean) {\n        if (this.children) {\n            for (const child of this.children) {\n                if (child instanceof InvokableNode) {\n                    (child as InvokableNode).setInvokable(invokable);\n                }\n            }\n        }\n    }\n\n}\n\nclass Provider implements vscode.TreeDataProvider<vscode.TreeItem> {\n\n\tprivate _onDidChangeTreeData: vscode.EventEmitter<vscode.TreeItem | undefined | null> = new vscode.EventEmitter<vscode.TreeItem | undefined | null>();\n\treadonly onDidChangeTreeData: vscode.Event<vscode.TreeItem | undefined | null> = this._onDidChangeTreeData.event;\n\n    private readonly treeChanged: TreeChanged = (node?: BaseNode) => {\n        if (this.visible) {\n            if (node) {\n                const processNode = findProcessNode(node);\n                if (!processNode || !this.roots.includes(processNode)) {\n                    // node already removed from tree\n                    return;\n                }\n            }\n            this.refresh(node);\n        }\n    };\n    private readonly roots: ProcessNode[] = [ new ProcessNode(this.treeChanged, null, vscode.workspace.getConfiguration().get<boolean>(monitoredProcesses.AUTO_SELECT_PROJECT_PROCESS_KEY)) ];\n\n    private visible: boolean = false;\n\n    processesChanged(added: monitoredProcesses.MonitoredProcess | undefined, removed: monitoredProcesses.MonitoredProcess | undefined, target: any | undefined) {\n        if (removed) {\n            for (let index = 0; index < this.roots.length; index++) {\n                const root = this.roots[index];\n                if (root.getProcess() === removed) {\n                    if (root.isMaster) {\n                        root.setProcess(undefined);\n                        this.refresh(root);\n                    } else {\n                        this.roots.splice(index, 1);\n                        this.refresh();\n                    }\n                    break;\n                }\n            }\n        } else if (added) {\n            const targetNode = target instanceof ProcessNode ? target as ProcessNode : undefined;\n            let processRoot: ProcessNode | undefined = targetNode;\n            if (!processRoot) {\n                for (const root of this.roots) {\n                    if (root.getProcess() === undefined) {\n                        processRoot = root;\n                        break;\n                    }\n                }\n            }\n            if (processRoot) {\n                processRoot.setProcess(added);\n                this.refresh(processRoot);\n            } else {\n                processRoot = new ProcessNode(this.treeChanged, added);\n                this.roots.push(processRoot);\n                this.refresh();\n            }\n        }\n    }\n\n    autoSelectProjectProcessChanged(isAutoSelectProcess: boolean) {\n        for (const root of this.roots) {\n            if (root.isMaster) {\n                root.autoSelectProcessChanged(isAutoSelectProcess);\n            }\n        }\n    }\n\n    removeProcessContainer(root: ProcessNode) {\n        const index = this.roots.indexOf(root);\n        if (index > -1) {\n            this.roots.splice(index, 1);\n            this.refresh();\n        }\n    }\n\n    refresh(element?: vscode.TreeItem) {\n        this._onDidChangeTreeData.fire(element);\n\t}\n\n\tgetTreeItem(element: vscode.TreeItem): vscode.TreeItem {\n        return element;\n\t}\n\n\tgetChildren(element?: vscode.TreeItem): vscode.TreeItem[] {\n        if (!this.visible) {\n            return [];\n        } else if (!element) {\n            return this.roots;\n        } else {\n            return (element as BaseNode).getChildren() || [];\n        }\n\t}\n\n    getParent?(element: vscode.TreeItem): vscode.TreeItem | undefined {\n        return (element as BaseNode).parent;\n    }\n\n    setVisible(visible: boolean) {\n        if (this.visible !== visible) {\n            this.visible = visible;\n            this.refresh();\n        }\n    }\n}\n\nlet PROVIDER: Provider | undefined;\nexport function provider(): Provider {\n    PROVIDER = PROVIDER || new Provider();\n    return PROVIDER;\n}\n"
  },
  {
    "path": "integrations/vscode/src/parameters.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as vscode from 'vscode';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport * as jdk from './jdk';\nimport * as projectUtils from './projectUtils';\nimport * as vscodeUtils from './vscodeUtils';\n// import * as logUtils from './logUtils';\n\n\nexport const CPU_SAMPLER_FILTER_INCLUSIVE = 'include-classes';\nexport const CPU_SAMPLER_FILTER_EXCLUSIVE = 'exclude-classes';\n\nconst ENABLE_GO_TO_SOURCE_KEY = 'visualvm.integration.enableGoToSource';\nconst VSCODE_PARAMETERS_KEY = 'visualvm.integration.visualStudioCodeParameters';\n\nconst USE_JDK_PATH_FOR_STARTUP_KEY = 'visualvm.startup.useJdkPathForVisualvm';\nconst STARTUP_PARAMETERS_KEY = 'visualvm.startup.visualvmParameters';\nconst WINDOW_TO_FRONT_KEY = 'visualvm.behavior.visualvmWindowToFront';\nconst PRESELECT_VIEW_KEY = 'visualvm.behavior.preselectProcessView';\n\nexport function executable(executable: string): string {\n    return executable.includes(' ') ? `\"${executable}\"` : executable;\n}\n\nexport function perfMaxStringConstLength(): string {\n    return '-J-XX:PerfMaxStringConstLength=10240';\n}\n\nexport async function jdkHome(predefinedJdk?: string): Promise<string | undefined> {\n    if (vscode.workspace.getConfiguration().get<boolean>(USE_JDK_PATH_FOR_STARTUP_KEY)) {\n        const jdkPath = predefinedJdk || await jdk.getPath();\n        if (!jdkPath) {\n            throw new Error();\n        }\n        return `--jdkhome \"${jdkPath}\"`;\n    }\n    return undefined;\n}\n\nexport function windowToFront(): string {\n    return '--window-to-front';\n}\n\nexport function windowToFrontConditional(): string | undefined {\n    if (vscode.workspace.getConfiguration().get<boolean>(WINDOW_TO_FRONT_KEY)) {\n        return windowToFront();\n    }\n    return undefined;\n}\n\nexport function userDefinedParameters(): string | undefined {\n    return vscode.workspace.getConfiguration().get<string>(STARTUP_PARAMETERS_KEY);\n}\n\nexport async function goToSource(folder?: vscode.WorkspaceFolder): Promise<string | undefined> {\n    const parameters: string[] = [];\n    if (vscode.workspace.getConfiguration().get<boolean>(ENABLE_GO_TO_SOURCE_KEY)) {\n        const vsCodeLauncher = vscodeUtils.findLauncher();\n        const vsCodeLauncherParameters = vscode.workspace.getConfiguration().get<string>(VSCODE_PARAMETERS_KEY, '');\n        const vsCodeLauncherCommand = vsCodeLauncher ? `${vsCodeLauncher}${vsCodeLauncherParameters ? ' ' + vsCodeLauncherParameters : ''}` : '';\n        const sourceViewer = vsCodeLauncher ? `${encode(vsCodeLauncherCommand)} -g {file}:{line}:{column}` : '';\n\n        const sourceRootsArr: string[] = [];\n        const workspaceSourceRoots = await getWorkspaceSourceRoots(folder);\n        if (workspaceSourceRoots) {\n            sourceRootsArr.push(...workspaceSourceRoots);\n        }\n        const jdkSourceRoots = await getJdkSourceRoots();\n        if (jdkSourceRoots) {\n            sourceRootsArr.push(jdkSourceRoots);\n        }\n        const sourceRoots = sourceRootsArr.length ? sourceRootsArr.join(path.delimiter) : '';\n\n        if (sourceViewer.length + sourceRoots.length < 200) {\n            parameters.push(`--source-viewer=\"${sourceViewer}\"`);\n            parameters.push(`--source-roots=\"${sourceRoots}\"`);\n        } else {\n            const file = await writeProperties('visualvm-source-config', `source-viewer=${sourceViewer}`, `source-roots=${sourceRoots}`);\n            if (file) {\n                parameters.push(`--source-config=\"${encode(file)}\"`);\n            }\n        }\n    } else {\n        // Make sure to reset the previously forced settings\n        parameters.push('--source-viewer=\"\"');\n        parameters.push('--source-roots=\"\"');\n    }\n    return parameters.length ? parameters.join(' ') : undefined;\n}\n\nexport async function getWorkspaceSourceRoots(folder?: vscode.WorkspaceFolder): Promise<string[] | undefined> {\n    const sourceRoots = await projectUtils.getSourceRoots(folder);\n    if (sourceRoots) {\n        for (let index = 0; index < sourceRoots.length; index++) {\n            sourceRoots[index] = encode(sourceRoots[index]);\n        }\n    }\n    return sourceRoots;\n}\n\nexport async function getJdkSourceRoots(): Promise<string | undefined> {\n    const jdkPath = await jdk.getPath();\n    if (jdkPath) {\n        const jdkSources = await jdk.getSources(jdkPath);\n        if (jdkSources) {\n            const jdkSourcesPath = fs.realpathSync(jdkSources.path); // JDK sources may be a symbolic link on linux\n            return `${encode(jdkSourcesPath)}${jdkSources.modular ? '[subpaths=*modules*]' : ''}`;\n        }\n    }\n    return undefined;\n}\n\nexport function openPid(pid: number): string {\n    const view = vscode.workspace.getConfiguration().get<string>(PRESELECT_VIEW_KEY);\n    function viewIndex(view: string | undefined): number {\n        switch (view) {\n            case 'Overview': return 1;\n            case 'Monitor': return 2;\n            case 'Threads': return 3;\n            case 'Sampler': return 4;\n            default: return 0;\n        }\n    }\n    const index = viewIndex(view);\n    const param = index ? `${pid}@${index}` : `${pid}`;\n    return `--openpid ${param}`;\n}\n\nexport function threadDump(pid: number): string {\n    return `--threaddump ${pid.toString()}`;\n}\n\nexport function heapDump(pid: number): string {\n    return `--heapdump ${pid.toString()}`;\n}\n\nexport async function cpuSamplerStart(pid: number, samplingFilter?: string, samplingRate?: number | string, workspaceFolder?: vscode.WorkspaceFolder): Promise<string | undefined> {\n    const samplingFilterP = await resolveSamplingFilter(samplingFilter, workspaceFolder);\n    if (samplingFilterP !== undefined) {\n        if (typeof samplingRate !== 'string') {\n            samplingRate = Number(samplingRate || 100).toString();\n        }\n        const parameters: string[] = [];\n        parameters.push(`--start-cpu-sampler ${pid}`);\n        const samplingRateP = `sampling-rate=${samplingRate}`;\n        if (samplingFilterP.length + samplingRateP.length < 200) {\n            parameters.push('@');\n            parameters.push(samplingFilterP);\n            parameters.push(',');\n            parameters.push(samplingRateP);\n        } else {\n            const file = await writeProperties('visualvm-sampler-config', samplingFilterP, samplingRateP);\n            if (file) {\n                parameters.push(`@settings-file=\"${encode(file)}\"`);\n            }\n        }\n        return parameters.join('');\n    } else {\n        return undefined;\n    }\n}\n\nexport async function resolveSamplingFilter(samplingFilter?: string, workspaceFolder?: vscode.WorkspaceFolder): Promise<string | undefined> {\n    switch (samplingFilter) {\n        case CPU_SAMPLER_FILTER_EXCLUSIVE: // exclude JDK classes\n            const jdkPackages = jdk.getPackages();\n            return `${CPU_SAMPLER_FILTER_EXCLUSIVE}=${encode(jdkPackages)}`;\n        case CPU_SAMPLER_FILTER_INCLUSIVE: // include only project classes\n            const projectPackages = await projectUtils.getPackages(workspaceFolder);\n            if (projectPackages?.length) {\n                const packages = projectPackages.join(', ');\n                return `${CPU_SAMPLER_FILTER_INCLUSIVE}=${encode(packages)}`;\n            } else {\n                const reason = projectPackages === undefined ? 'No Java support available to resolve project classes' : 'No project classes found';\n                const msg = `${reason}. Select how to proceed:`;\n                const allOption = 'Include All Classes';\n                const jdkOption = 'Exclude JDK Classes';\n                const cancelOption = 'Cancel CPU Sampler';\n                const selected = await vscode.window.showWarningMessage(msg, allOption, jdkOption, cancelOption);\n                if (selected === allOption) {\n                    return resolveSamplingFilter();\n                } else if (selected === jdkOption) {\n                    return resolveSamplingFilter(CPU_SAMPLER_FILTER_EXCLUSIVE);\n                } else {\n                    return undefined;\n                }\n            }\n        default:\n            if (samplingFilter?.startsWith(CPU_SAMPLER_FILTER_EXCLUSIVE + ':')) { // exclude custom classes\n                const filter = samplingFilter.substring(CPU_SAMPLER_FILTER_EXCLUSIVE.length + 1);\n                return `${CPU_SAMPLER_FILTER_EXCLUSIVE}=${encode(filter)}`;\n            } else { // include custom or all classes\n                const filter = samplingFilter?.startsWith(CPU_SAMPLER_FILTER_INCLUSIVE + ':') ? samplingFilter.substring(CPU_SAMPLER_FILTER_INCLUSIVE.length + 1) : '';\n                return `${CPU_SAMPLER_FILTER_INCLUSIVE}=${encode(filter)}`;\n            }\n    }\n}\n\nexport function memorySamplerStart(pid: number, samplingRate?: number | string): string {\n    if (typeof samplingRate !== 'string') {\n        samplingRate = Number(samplingRate || 1000).toString();\n    }\n    const parameters: string[] = [];\n    parameters.push(`--start-memory-sampler ${pid}`);\n    parameters.push('@');\n    parameters.push(`sampling-rate=${samplingRate}`);\n    return parameters.join('');\n}\n\nexport function samplerSnapshot(pid: number): string {\n    return `--snapshot-sampler ${pid}`;\n}\n\nexport function samplerStop(pid: number): string {\n    return `--stop-sampler ${pid}`;\n}\n\nexport function jfrRecordingStart(pid: number, displayName: string, settingsName?: string): string {\n    const parameters: string[] = [];\n    parameters.push(`--start-jfr ${pid}`);\n    parameters.push('@');\n    parameters.push(`name=${encode(displayName)}`);\n    parameters.push(',');\n    parameters.push(`settings=${settingsName || 'default'}`);\n    return parameters.join('');\n}\n\nexport function jfrRecordingDump(pid: number) {\n    return `--dump-jfr ${pid}`;\n}\n\nexport function jfrRecordingStop(pid: number) {\n    return `--stop-jfr ${pid}`;\n}\n\n\n\nexport function vmArgId(id: string): string {\n    return `-Dvisualvm.id=${id}`;\n}\n\nexport function vmArgDisplayName(displayName: string, includePid: boolean = true): string {\n    displayName = displayName.replace(/\\s/g, '_');\n    return `-Dvisualvm.display.name=${displayName}${includePid ? '%PID' : ''}`;\n}\n\n\nexport function encode(text: string | undefined): string {\n    if (text === undefined) return 'undefined';\n    if (text.length) {\n        text = text.replace(/\\'/g, '%27');\n        text = text.replace(/\\\"/g, '%22');\n        text = text.replace(/\\s/g, '%20');\n        text = text.replace( /,/g, '%2C');\n    }\n    return text;\n}\n\nasync function writeProperties(filename: string, ...records: string[]): Promise<string | undefined> {\n    return new Promise(\n        (resolve) => {\n            const tmp = getTmpDir();\n            if (tmp) {\n                const file = path.join(tmp, filename);\n                const stream = fs.createWriteStream(path.join(tmp, filename), { flags: 'w', encoding: 'utf8' });\n                for (let record of records) {\n                    stream.write(record.replace(/\\\\/g, '\\\\\\\\') + '\\n');\n                }\n                stream.on('finish', () => {\n                    resolve(file);\n                });\n                stream.end();\n            } else {\n                resolve(undefined);\n            }\n        }\n    );\n}\n\nexport function getTmpDir(): string {\n    const tmp = os.tmpdir();\n    const realtmp = fs.realpathSync(tmp);\n    return realtmp;\n}\n"
  },
  {
    "path": "integrations/vscode/src/presets.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as vscode from 'vscode';\nimport * as commands from './commands';\nimport * as parameters from './parameters';\n\n\nexport function initialize(context: vscode.ExtensionContext) {\n    WhenStartedPresets.PERSISTENT.initializePersistent(context);\n    CpuSamplerFilterPresets.PERSISTENT.initializePersistent(context);\n    CpuSamplerSamplingRatePresets.PERSISTENT.initializePersistent(context);\n    MemorySamplerSamplingRatePresets.PERSISTENT.initializePersistent(context);\n    JfrSettingsPresets.PERSISTENT.initializePersistent(context);\n}\n\nexport type OnChanged = () => void;\n\nexport abstract class Presets {\n\n    readonly name: string;\n\n    private readonly presets: string[][];\n    private selectedPreset: number;\n    private readonly selectPrompt: string;\n    private readonly singleRowChoices: boolean;\n\n    private storage: vscode.Memento | undefined;\n    private persistenceKey: string | undefined;\n\n    protected constructor(name: string, presets: string[][], initialPreset: number, selectPrompt: string, singleRowChoices: boolean) {\n        this.name = name;\n        this.presets = presets;\n        this.selectedPreset = initialPreset;\n        this.selectPrompt = selectPrompt;\n        this.singleRowChoices = singleRowChoices;\n    }\n\n    protected doInitializePersistent(storage: vscode.Memento, persistenceKey: string) {\n        this.storage = storage;\n        this.persistenceKey = persistenceKey;\n        const loadedPreset = this.storage.get<number>(persistenceKey, this.selectedPreset);\n        if (loadedPreset !== this.selectedPreset) {\n            this.selectedPreset = loadedPreset;\n            this.notifyChanged();\n        }\n    }\n\n    async select(actionName?: string): Promise<boolean | undefined> {\n        const choices: (vscode.QuickPickItem & { index: number })[] = [];\n        for (let index = 0; index < this.presets.length; index++) {\n            choices.push({\n                label: this.presets[index][0],\n                description: this.singleRowChoices ? this.presets[index][1] : undefined,\n                detail: this.singleRowChoices ? undefined : this.presets[index][1],\n                index: index\n            });\n        }\n        const selected = await vscode.window.showQuickPick(choices, {\n            title: actionName,\n            placeHolder: this.selectPrompt\n        });\n        if (selected) {\n            return this.setSelected(selected.index);\n        } else {\n            return undefined;\n        }\n    }\n\n    getSelectedString(): string {\n        return this.presets[this.selectedPreset][0].toLocaleLowerCase();\n    }\n\n    getSelectedValue(): string {\n        return this.presets[this.selectedPreset][2];\n    }\n\n    protected getSelectedPreset(): number {\n        return this.selectedPreset;\n    }\n\n    protected async setSelected(preset: number, forceSelected: boolean = false): Promise<boolean | undefined> {\n        if (forceSelected || this.selectedPreset !== preset) {\n            this.selectedPreset = preset;\n            await this.savePersistent(this.persistenceKey, this.selectedPreset);\n            this.notifyChanged();\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    protected async savePersistent(key: string | undefined, value: any): Promise<void> {\n        if (this.storage && key) {\n            await this.storage.update(key, value);\n        }\n    }\n\n    private readonly listeners: OnChanged[] = [];\n\n    onChanged(listener: OnChanged) {\n        this.listeners.push(listener);\n    }\n\n    private notifyChanged() {\n        for (const listener of this.listeners) {\n            listener();\n        }\n    }\n\n}\n\nexport class WhenStartedPresets extends Presets {\n\n    private static PERSISTENCE_KEY = 'visualvm.presets.WhenStarted';\n    private static NAME = 'When Started Action';\n    private static SELECT_PROMPT = 'Select what happens when a project process is started';\n    private static PRESETS = [\n        [ 'Do Nothing', 'No action when process is started', '' ],\n        [ 'Open Process', 'Open the process in VisualVM', commands.COMMAND_OPEN_PROCESS ],\n        [ 'Start CPU Sampler', 'Open the process in VisualVM and start CPU sampling using the defined settings', commands.COMMAND_CPU_SAMPLER_START ],\n        [ 'Start Memory Sampler', 'Open the process in VisualVM and start memory sampling using the defined settings', commands.COMMAND_MEMORY_SAMPLER_START ],\n        [ 'Start JFR Recording', 'Open the process in VisualVM and start flight recording using the defined settings', commands.COMMAND_JFR_START ]\n    ];\n    private static INITIAL_PRESET = 0;\n    private static SINGLE_ROW_CHOICES = false;\n\n    static PERSISTENT = new WhenStartedPresets();\n\n    constructor() {\n        super(WhenStartedPresets.NAME, WhenStartedPresets.PRESETS, WhenStartedPresets.INITIAL_PRESET, WhenStartedPresets.SELECT_PROMPT, WhenStartedPresets.SINGLE_ROW_CHOICES);\n    }\n\n    initializePersistent(context: vscode.ExtensionContext) {\n        this.doInitializePersistent(context.workspaceState, WhenStartedPresets.PERSISTENCE_KEY);\n    }\n\n    getSelectedString(): string {\n        return super.getSelectedString().replace(/ cpu /g, ' CPU ').replace(/ memory /g, ' Memory ').replace(/ jfr /g, ' JFR ');\n    }\n\n}\n\nexport class CpuSamplerFilterPresets extends Presets {\n    \n    private static PERSISTENCE_KEY = 'visualvm.presets.CpuSamplerFilter';\n    private static PERSISTENCE_KEY_CPU_SAMPLER_FILTER_CUSTOM_INCLUSIVE = 'visualvm.presets.CpuSamplerFilterCustomInclusive';\n    private static PERSISTENCE_KEY_CPU_SAMPLER_FILTER_CUSTOM_EXCLUSIVE = 'visualvm.presets.CpuSamplerFilterCustomExclusive';\n    private static NAME = 'CPU Sampling Filter';\n    private static SELECT_PROMPT = 'Select CPU sampling filter';\n    private static PRESETS = [\n        [ 'Include All Classes', 'Collects data from all classes', '' ],\n        [ 'Exclude JDK Classes', 'Excludes data from JDK classes (java.*, com.sun.*, org.graalvm.*, etc.)', parameters.CPU_SAMPLER_FILTER_EXCLUSIVE ],\n        [ 'Include Only Project Classes', 'Collects data only from project classes', parameters.CPU_SAMPLER_FILTER_INCLUSIVE ],\n        [ 'Include Only Defined Classes', 'Collects data only from user defined classes', parameters.CPU_SAMPLER_FILTER_INCLUSIVE ],\n        [ 'Exclude Defined Classes', 'Excludes data from user defined classes', parameters.CPU_SAMPLER_FILTER_EXCLUSIVE ]\n    ];\n    private static INITIAL_PRESET = 0;\n    private static SINGLE_ROW_CHOICES = false;\n\n    static PERSISTENT = new CpuSamplerFilterPresets();\n\n    private customInclusiveFilter: string = '*';\n    private customExclusiveFilter: string = '*';\n\n    constructor() {\n        super(CpuSamplerFilterPresets.NAME, CpuSamplerFilterPresets.PRESETS, CpuSamplerFilterPresets.INITIAL_PRESET, CpuSamplerFilterPresets.SELECT_PROMPT, CpuSamplerFilterPresets.SINGLE_ROW_CHOICES);\n    }\n\n    initializePersistent(context: vscode.ExtensionContext) {\n        this.doInitializePersistent(context.workspaceState, CpuSamplerFilterPresets.PERSISTENCE_KEY);\n        this.customInclusiveFilter = context.workspaceState.get(CpuSamplerFilterPresets.PERSISTENCE_KEY_CPU_SAMPLER_FILTER_CUSTOM_INCLUSIVE, '*');\n        this.customExclusiveFilter = context.workspaceState.get(CpuSamplerFilterPresets.PERSISTENCE_KEY_CPU_SAMPLER_FILTER_CUSTOM_EXCLUSIVE, '*');\n    }\n\n    protected async setSelected(preset: number): Promise<boolean | undefined> {\n        if (preset >= 3) {\n            function validateFilter(filter: string): string | undefined {\n                if (!filter.length) {\n                    return 'Filter cannot be empty';\n                }\n                // TODO: validate properly\n                return undefined;\n            }\n            const newValue = await vscode.window.showInputBox({\n                title: CpuSamplerFilterPresets.PRESETS[preset][0],\n                value: preset === 3 ? this.customInclusiveFilter : this.customExclusiveFilter,\n                placeHolder: 'Define CPU sampling filter',\n                prompt: 'Format: org.pkg.**, org.pkg.*, org.pkg.Class',\n                validateInput: filter => validateFilter(filter)\n            });\n            if (newValue) {\n                if (preset === 3) {\n                    this.customInclusiveFilter = newValue.trim();\n                    await this.savePersistent(CpuSamplerFilterPresets.PERSISTENCE_KEY_CPU_SAMPLER_FILTER_CUSTOM_INCLUSIVE, this.customInclusiveFilter);\n                } else if (preset === 4) {\n                    this.customExclusiveFilter = newValue.trim();\n                    await this.savePersistent(CpuSamplerFilterPresets.PERSISTENCE_KEY_CPU_SAMPLER_FILTER_CUSTOM_EXCLUSIVE, this.customExclusiveFilter);\n                }\n                return super.setSelected(preset, true);\n            } else {\n                return undefined;\n            }\n        } else {\n            return super.setSelected(preset);\n        }\n    }\n\n    getSelectedString(): string {\n        switch (this.getSelectedPreset()) {\n            case 3:\n                return `include ${this.customInclusiveFilter}`;\n            case 4:\n                return `exclude ${this.customExclusiveFilter}`;\n            default:\n                return super.getSelectedString().replace(/ jdk /g, ' JDK ');\n        }\n    }\n\n    getSelectedValue(): string {\n        switch (this.getSelectedPreset()) {\n            case 3:\n                return `${parameters.CPU_SAMPLER_FILTER_INCLUSIVE}:${this.customInclusiveFilter}`;\n            case 4:\n                return `${parameters.CPU_SAMPLER_FILTER_EXCLUSIVE}:${this.customExclusiveFilter}`;\n            default:\n                return super.getSelectedValue();\n        }\n    }\n\n}\n\nexport class CpuSamplerSamplingRatePresets extends Presets {\n    \n    private static PERSISTENCE_KEY = 'visualvm.presets.CpuSamplerSamplingRate';\n    private static NAME = 'CPU Sampling Rate';\n    private static SELECT_PROMPT = 'Select CPU sampling rate';\n    private static SAMPLING_RATES = [ 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000];\n    private static PRESETS: string[][] = [];\n    static {\n        for (const samplingRate of this.SAMPLING_RATES) {\n            this.PRESETS.push([ Number(samplingRate).toLocaleString(), 'ms', Number(samplingRate).toString() ]);\n        }\n    }\n    private static INITIAL_PRESET = 2;\n    private static SINGLE_ROW_CHOICES = true;\n\n    static PERSISTENT = new CpuSamplerSamplingRatePresets();\n\n    constructor() {\n        super(CpuSamplerSamplingRatePresets.NAME, CpuSamplerSamplingRatePresets.PRESETS, CpuSamplerSamplingRatePresets.INITIAL_PRESET, CpuSamplerSamplingRatePresets.SELECT_PROMPT, CpuSamplerSamplingRatePresets.SINGLE_ROW_CHOICES);\n    }\n\n    initializePersistent(context: vscode.ExtensionContext) {\n        this.doInitializePersistent(context.workspaceState, CpuSamplerSamplingRatePresets.PERSISTENCE_KEY);\n    }\n\n    getSelectedString(): string {\n        return `${super.getSelectedString()} ms`;\n    }\n\n}\n\nexport class MemorySamplerSamplingRatePresets extends Presets {\n    \n    private static PERSISTENCE_KEY = 'visualvm.presets.MemorySamplerSamplingRate';\n    private static NAME = 'Memory Sampling Rate';\n    private static SELECT_PROMPT = 'Select memory sampling rate';\n    private static SAMPLING_RATES = [ 100, 200, 500, 1000, 2000, 5000, 10000];\n    private static PRESETS: string[][] = [];\n    static {\n        for (const samplingRate of this.SAMPLING_RATES) {\n            this.PRESETS.push([ Number(samplingRate).toLocaleString(), 'ms', Number(samplingRate).toString() ]);\n        }\n    }\n    private static INITIAL_PRESET = 3;\n    private static SINGLE_ROW_CHOICES = true;\n\n    static PERSISTENT = new MemorySamplerSamplingRatePresets();\n\n    constructor() {\n        super(MemorySamplerSamplingRatePresets.NAME, MemorySamplerSamplingRatePresets.PRESETS, MemorySamplerSamplingRatePresets.INITIAL_PRESET, MemorySamplerSamplingRatePresets.SELECT_PROMPT, MemorySamplerSamplingRatePresets.SINGLE_ROW_CHOICES);\n    }\n\n    initializePersistent(context: vscode.ExtensionContext) {\n        this.doInitializePersistent(context.workspaceState, MemorySamplerSamplingRatePresets.PERSISTENCE_KEY);\n    }\n\n    getSelectedString(): string {\n        return `${super.getSelectedString()} ms`;\n    }\n\n}\n\nexport class JfrSettingsPresets extends Presets {\n    \n    private static PERSISTENCE_KEY = 'visualvm.presets.JfrSettings';\n    private static NAME = 'Flight Recording Settings';\n    private static SELECT_PROMPT = 'Select JFR settings';\n    private static PRESETS = [\n        [ 'Default', 'Collects a predefined set of information with low overhead', 'default' ],\n        [ 'Profile', 'Provides more data than the Default setting, but with more overhead and impact on performance', 'profile' ]\n    ];\n    private static INITIAL_PRESET = 0;\n    private static SINGLE_ROW_CHOICES = false;\n\n    static PERSISTENT = new JfrSettingsPresets();\n\n    constructor() {\n        super(JfrSettingsPresets.NAME, JfrSettingsPresets.PRESETS, JfrSettingsPresets.INITIAL_PRESET, JfrSettingsPresets.SELECT_PROMPT, JfrSettingsPresets.SINGLE_ROW_CHOICES);\n    }\n\n    initializePersistent(context: vscode.ExtensionContext) {\n        this.doInitializePersistent(context.workspaceState, JfrSettingsPresets.PERSISTENCE_KEY);\n    }\n\n}\n"
  },
  {
    "path": "integrations/vscode/src/projectUtils.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as vscode from 'vscode';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as logUtils from './logUtils';\n\n\nconst NBLS_GET_SOURCE_ROOTS_COMMAND = 'nbls.java.get.project.source.roots';\nconst NBLS_GET_PACKAGES_COMMAND = 'nbls.java.get.project.packages';\nconst NBLS_PROJECT_INFO_COMMAND = 'nbls.project.info';\n\nconst JDT_EXTENSION_ID = 'redhat.java';\nconst JDT_SETTINGS_SOURCE_PATHS = 'org.eclipse.jdt.ls.core.sourcePaths';\nconst JDT_GET_PACKAGE_DATA = 'java.getPackageData';\nconst JDT_EXECUTE_WORKSPACE_COMMAND = 'java.execute.workspaceCommand';\n\nconst MICRONAUT_TOOLS_SELECTED_SUBPROJECT_COMMAND = 'extension.micronaut-tools.navigation.getSelectedSubproject';\n\nexport async function getSourceRoots(workspaceFolder?: vscode.WorkspaceFolder): Promise<string[] | undefined>  {\n    logUtils.logInfo(`[projectUtils] Computing source roots${workspaceFolder ? ' for folder ' + workspaceFolder.uri.fsPath : ''}...`);\n    if (!vscode.workspace.workspaceFolders?.length) { // No folder opened\n        logUtils.logInfo('[projectUtils] No folder opened');\n        return [];\n    }\n\n    const workspaceFolders = [];\n    for (const folder of vscode.workspace.workspaceFolders) {\n        if (folder === workspaceFolder) {\n            workspaceFolders.unshift(folder); // monitored folder should be first so its sources take precendece\n        } else {\n            workspaceFolders.push(folder);\n        }\n    }\n\n    const commands = await vscode.commands.getCommands();\n    const hasNblsProjectSourceRootsCommand = commands.includes(NBLS_GET_SOURCE_ROOTS_COMMAND);\n    const jdtApi = vscode.extensions.getExtension(JDT_EXTENSION_ID)?.exports;\n    if (!hasNblsProjectSourceRootsCommand && !jdtApi?.getProjectSettings) {\n        logUtils.logWarning('[projectUtils] No Java support to compute source roots');\n        // TODO: wait for NBLS/JDT if installed\n        return undefined; // No Java support available\n    }\n\n    const hasNblsProjectInfoCommand = commands.includes(NBLS_PROJECT_INFO_COMMAND);\n    const hasMicronautToolsSubprojectCommand = commands.includes(MICRONAUT_TOOLS_SELECTED_SUBPROJECT_COMMAND);\n\n    const sourceRoots: string[] = [];\n    const getUriSourceRoots = hasNblsProjectSourceRootsCommand ? getUriSourceRootsNbls : getUriSourceRootsJdt;\n    logUtils.logInfo(`[projectUtils] Using ${hasNblsProjectSourceRootsCommand ? 'NBLS' : 'JDT'} to compute source roots`);\n    for (const folder of workspaceFolders) {\n        const unrecognizedProjectFolders: vscode.Uri[] = [];\n        try {\n            const foundSourceRoots = await getUriSourceRoots(sourceRoots, folder, folder.uri.toString(), hasNblsProjectInfoCommand, hasMicronautToolsSubprojectCommand, jdtApi);\n            if (!foundSourceRoots && (!hasNblsProjectSourceRootsCommand || !isSupportedProjectUri(folder.uri))) { // Workaround to allow deep search when using JDT, fixes GDK & JDT without Micronaut Tools\n                unrecognizedProjectFolders.push(folder.uri);\n            }\n        } catch (err) {\n            logUtils.logError(`[projectUtils] Error computing source roots: ${err}`);\n        }\n\n        // Try to find a nested supported project folder\n        while (unrecognizedProjectFolders.length) {\n            const unrecognizedProjectFolder = unrecognizedProjectFolders.shift();\n            if (unrecognizedProjectFolder) {\n                const subfolders = fs.readdirSync(unrecognizedProjectFolder.fsPath);\n                for (const subfolder of subfolders) {\n                    const subfolderUri = vscode.Uri.joinPath(unrecognizedProjectFolder, subfolder);\n                    if (fs.lstatSync(subfolderUri.fsPath)?.isDirectory()) {\n                        const foundSourceRoots = await getUriSourceRoots(sourceRoots, folder, subfolderUri.toString(), hasNblsProjectInfoCommand, hasMicronautToolsSubprojectCommand, jdtApi);\n                        if (!foundSourceRoots && (!hasNblsProjectSourceRootsCommand || !isSupportedProjectUri(subfolderUri))) { // Workaround to allow deep search when using JDT, fixes GDK & JDT without Micronaut Tools\n                            unrecognizedProjectFolders.push(subfolderUri);\n                        }\n                    }\n                }\n            }\n        }\n    }\n    logUtils.logInfo(`[projectUtils] Found ${sourceRoots.length} source root(s)`);\n    return sourceRoots;\n}\n\nasync function getUriSourceRootsNbls(sourceRoots: string[], folder: vscode.WorkspaceFolder, uri: string, hasNblsProjectInfoCommand: boolean, hasMicronautToolsSubprojectCommand: boolean): Promise<boolean> {\n    let foundSourceRoots = false;\n    const uriSourceRoots: string[] | undefined = await vscode.commands.executeCommand(NBLS_GET_SOURCE_ROOTS_COMMAND, uri);\n    if (uriSourceRoots) {\n        if (uriSourceRoots.length) { // found project source roots\n            foundSourceRoots = true;\n            for (const uriSourceRoot of uriSourceRoots) {\n                const sourceRoot = vscode.Uri.parse(uriSourceRoot).fsPath;\n                if (!sourceRoots.includes(sourceRoot)) {\n                    sourceRoots.push(sourceRoot);\n                }\n            }\n        } else { // no project source roots found, may be a modular (GCN) project\n            let selectedSubproject: string | undefined = undefined;\n            if (hasMicronautToolsSubprojectCommand) { // modules selected in Micronaut Tools should be first so their sources take precendece\n                const subprojectUri = await vscode.commands.executeCommand(MICRONAUT_TOOLS_SELECTED_SUBPROJECT_COMMAND, folder);\n                if (subprojectUri instanceof vscode.Uri) { // folder tracked by Micronaut Tools and module selected\n                    selectedSubproject = subprojectUri.fsPath;\n                }\n            }\n            if (hasNblsProjectInfoCommand) {\n                const infos: any[] = await vscode.commands.executeCommand(NBLS_PROJECT_INFO_COMMAND, uri, { projectStructure: true });\n                if (infos?.length && infos[0]) { // multimodule - most likely GCN\n                    const subprojects = [];\n                    for (const subproject of infos[0].subprojects) {\n                        if (vscode.Uri.parse(subproject).fsPath === selectedSubproject) { // add source roots for module selected in Micronaut Tools first\n                            subprojects.unshift(subproject);\n                        } else {\n                            subprojects.push(subproject);\n                        }\n                    }\n                    for (const subproject of subprojects) {\n                        foundSourceRoots = await getUriSourceRootsNbls(sourceRoots, folder, subproject, false, false) || foundSourceRoots; // false prevents deep search (OK for GCN, may need to be enabled for other projects)\n                    }\n                }\n            }\n        }\n    }\n    return foundSourceRoots;\n}\n\n// TODO: add support for modules/subprojects (for example GDK project and Micronaut Tools ext. not installed)\n// NOTE: modules/subprojects are defined by the Micronaut Tools ext., which has NBLS as a required dependency -> getUriSourceRootsNbls will be executed instead of getUriSourceRootsJdt\nasync function getUriSourceRootsJdt(sourceRoots: string[], _folder: vscode.WorkspaceFolder, uri: string, _hasNblsProjectInfoCommand: boolean, _hasMicronautToolsSubprojectCommand: boolean, api: any): Promise<boolean> {\n    let foundSourceRoots = false;\n    try {\n        const settings = await api.getProjectSettings(uri, [ JDT_SETTINGS_SOURCE_PATHS ]);\n        if (settings) {\n            const uriSourceRoots = settings[JDT_SETTINGS_SOURCE_PATHS];\n            if (uriSourceRoots?.length) {\n                foundSourceRoots = true;\n                for (const uriSourceRoot of uriSourceRoots) {\n                    if (!sourceRoots.includes(uriSourceRoot)) {\n                        sourceRoots.push(uriSourceRoot);\n                    }\n                }\n            }\n        }\n        return foundSourceRoots;\n    } catch (err) {\n        // Error: Given URI does not belong to any Java project.\n        return false;\n    }\n}\n\nexport async function getPackages(workspaceFolder?: vscode.WorkspaceFolder): Promise<string[] | undefined> {\n    logUtils.logInfo(`[projectUtils] Computing packages${workspaceFolder ? ' for folder ' + workspaceFolder.uri.fsPath : ''}...`);\n    const workspaceFolders = workspaceFolder ? [ workspaceFolder ] : vscode.workspace.workspaceFolders;\n    if (!workspaceFolders?.length) { // No folder opened\n        logUtils.logInfo('[projectUtils] No folder opened');\n        return [];\n    }\n    \n    const commands = await vscode.commands.getCommands();\n    const hasNblsProjectPackagesCommand = commands.includes(NBLS_GET_PACKAGES_COMMAND);\n    const hasJdtWorkspaceCommand = commands.includes(JDT_EXECUTE_WORKSPACE_COMMAND);\n    if (!hasNblsProjectPackagesCommand && !hasJdtWorkspaceCommand) {\n        logUtils.logWarning('[projectUtils] No Java support to compute packages');\n        // TODO: wait for NBLS/JDT if installed\n        return undefined; // No Java support available\n    }\n    \n    const hasNblsProjectInfoCommand = commands.includes(NBLS_PROJECT_INFO_COMMAND);\n    const hasMicronautToolsSubprojectCommand = commands.includes(MICRONAUT_TOOLS_SELECTED_SUBPROJECT_COMMAND);\n\n    const packages: string[] = [];\n    const getUriPackages = hasNblsProjectPackagesCommand ? getUriPackagesNbls : getUriPackagesJdt;\n    logUtils.logInfo(`[projectUtils] Using ${hasNblsProjectPackagesCommand ? 'NBLS' : 'JDT'} to compute packages`);\n    for (const folder of workspaceFolders) {\n        const unrecognizedProjectFolders: vscode.Uri[] = [];\n        try {\n            const foundPackages = await getUriPackages(packages, folder, folder.uri.toString(), hasNblsProjectInfoCommand, hasMicronautToolsSubprojectCommand);\n            if (!foundPackages && (!hasNblsProjectPackagesCommand || !isSupportedProjectUri(folder.uri))) { // Workaround to allow deep search when using JDT, fixes GDK & JDT without Micronaut Tools\n                unrecognizedProjectFolders.push(folder.uri);\n            }\n        } catch (err) {\n            logUtils.logError(`[projectUtils] Error computing packages: ${err}`);\n        }\n\n        // Try to find a nested supported project folder\n        while (unrecognizedProjectFolders.length) {\n            const unrecognizedProjectFolder = unrecognizedProjectFolders.shift();\n            if (unrecognizedProjectFolder) {\n                const subfolders = fs.readdirSync(unrecognizedProjectFolder.fsPath);\n                for (const subfolder of subfolders) {\n                    const subfolderUri = vscode.Uri.joinPath(unrecognizedProjectFolder, subfolder);\n                    if (fs.lstatSync(subfolderUri.fsPath)?.isDirectory()) {\n                        const foundPackages = await getUriPackages(packages, folder, subfolderUri.toString(), hasNblsProjectInfoCommand, hasMicronautToolsSubprojectCommand);\n                        if (!foundPackages && (!hasNblsProjectPackagesCommand || !isSupportedProjectUri(subfolderUri))) { // Workaround to allow deep search when using JDT, fixes GDK & JDT without Micronaut Tools\n                            unrecognizedProjectFolders.push(subfolderUri);\n                        }\n                    }\n                }\n            }\n        }\n    }\n    logUtils.logInfo(`[projectUtils] Found ${packages.length} package(s)`);\n    return packages;\n}\n\nasync function getUriPackagesNbls(packages: string[], folder: vscode.WorkspaceFolder, uri: string, hasNblsProjectInfoCommand: boolean, hasMicronautToolsSubprojectCommand: boolean): Promise<boolean> {\n    let foundPackages = false;\n    const uriPackages: string[] | undefined = await vscode.commands.executeCommand(NBLS_GET_PACKAGES_COMMAND, uri, true);\n    if (uriPackages) {\n        if (uriPackages.length) { // found project packages\n            foundPackages = true;\n            for (const uriPackage of uriPackages) {\n                const wildcardPackage = uriPackage + '.*';\n                if (!packages.includes(wildcardPackage)) {\n                    packages.push(wildcardPackage);\n                }\n            }\n        } else { // no project packages found, may be a modular (GCN) project\n            if (hasMicronautToolsSubprojectCommand) { // include only packages of the module selected in Micronaut Tools\n                const subprojectUri = await vscode.commands.executeCommand(MICRONAUT_TOOLS_SELECTED_SUBPROJECT_COMMAND, folder);\n                if (subprojectUri instanceof vscode.Uri) { // folder tracked by Micronaut Tools and module selected \n                    return await getUriPackagesNbls(packages, folder, subprojectUri.toString(), false, false); // false prevents deep search (OK for GCN, may need to be enabled for other projects)\n                    // TODO: include dependency subprojects (oci -> lib)?\n                }\n            }\n            if (hasNblsProjectInfoCommand) { // include packages from all found modules\n                const infos: any[] = await vscode.commands.executeCommand(NBLS_PROJECT_INFO_COMMAND, uri, { projectStructure: true });\n                if (infos?.length && infos[0]) {\n                    for (const subproject of infos[0].subprojects) { // multimodule - most likely GCN\n                        foundPackages = await getUriPackagesNbls(packages, folder, subproject, false, false) || foundPackages; // false prevents deep search (OK for GCN, may need to be enabled for other projects)\n                    }\n                }\n            }\n        }\n    }\n    return foundPackages;\n}\n\n// TODO: add support for modules/subprojects (for example GDK project and Micronaut Tools ext. not installed)\n// NOTE: modules/subprojects are defined by the Micronaut Tools ext., which has NBLS as a required dependency -> getUriPackagesNbls will be executed instead of getUriPackagesJdt\nasync function getUriPackagesJdt(packages: string[], _folder: vscode.WorkspaceFolder, uri: string): Promise<boolean> {\n    let foundPackages = false;\n    try {\n        const projectEntries = await getPackageDataJdt({ kind: 2, projectUri: uri });\n        for (const projectEntry of projectEntries) {\n            if (projectEntry.entryKind === 1) { // source root\n                const packageRoots = await getPackageDataJdt({ kind: 3, projectUri: uri, rootPath: projectEntry.path, isHierarchicalView: false });\n                for (const packageRoot of packageRoots) {\n                    if (packageRoot.kind === 4) { // package root\n                        foundPackages = true;\n                        const wildcardPackage = packageRoot.name + '.*';\n                        if (!packages.includes(wildcardPackage)) {\n                            packages.push(wildcardPackage);\n                        }\n                    }\n                }\n            }\n        }\n        return foundPackages;\n    } catch (err) {\n        // Error: Did not find container for URI  <uri>\n        return false;\n    }\n}\n\nasync function getPackageDataJdt(params: { [key: string]: any }): Promise<any[]> {\n    return await vscode.commands.executeCommand(JDT_EXECUTE_WORKSPACE_COMMAND, JDT_GET_PACKAGE_DATA, params) || [];\n}\n\n// Currently supports recognizing Maven Java project root (pom.xml) and Gradle Java project root (settings.gradle or build.gradle)\n// Ideally a NBLS / JDT API should be used to identify a project folder supported by the particular LS\nfunction isSupportedProjectUri(uri: vscode.Uri): boolean {\n    const mavenPomFile = path.join(uri.fsPath, 'pom.xml');\n    if (fs.existsSync(mavenPomFile) && fs.lstatSync(mavenPomFile)?.isFile()) {\n        return true;\n    }\n    const gradleSettingsFile = path.join(uri.fsPath, 'settings.gradle');\n    if (fs.existsSync(gradleSettingsFile) && fs.lstatSync(gradleSettingsFile)?.isFile()) {\n        return true;\n    }\n    const gradleBuildFile = path.join(uri.fsPath, 'build.gradle');\n    if (fs.existsSync(gradleBuildFile) && fs.lstatSync(gradleBuildFile)?.isFile()) {\n        return true;\n    }\n    return false;\n}\n"
  },
  {
    "path": "integrations/vscode/src/runningProcesses.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as vscode from 'vscode';\nimport * as cp from 'child_process';\nimport * as jdk from './jdk';\nimport * as parameters from './parameters';\n// import * as logUtils from './logUtils';\n\n\nexport type RunningProcess = {\n    readonly pid: number;\n    readonly displayName: string;\n};\n\nexport async function select(ignore?: number[]): Promise<RunningProcess | undefined> {\n    const jdkPath = await jdk.getPath();\n    if (!jdkPath) {\n        return undefined;\n    }\n    const jpsPath = jdk.getJpsPath(jdkPath);\n    if (!jpsPath) {\n        return undefined;\n    }\n    try {\n        const processes: Promise<QuickPickProcess[]> = new Promise(async (resolve) => {\n            const parts1 = await getUsingJps(jpsPath, '-v');\n            const parts2 = await getUsingJps(jpsPath, '-lm');\n            const processes: QuickPickProcess[] = [];\n            parts1.forEach(p1 => {\n                const p2 = parts2.find(p2 => p2.pid === p1.pid);\n                if (p2 && !ignore?.includes(p2.pid) && !p2.displayName.includes('--branding visualvm')) { // TODO: filter out jps process\n                    processes.push(new QuickPickProcess(p1.pid, p1.displayName, p2.displayName));\n                }\n            });\n            resolve(processes);\n        });\n        const selected = await vscode.window.showQuickPick(processes, {\n             title: 'Select Running Java Process',\n             placeHolder: 'Select the process to be monitored by VisualVM'\n        });\n        if (selected) {\n            return { pid: selected.pid, displayName: selected.label };\n        } else {\n            return undefined;\n        }\n    } catch (err) {\n        vscode.window.showErrorMessage(`Failed to read running Java processes: ${err}`);\n        return undefined;\n    }\n}\n\nclass QuickPickProcess implements vscode.QuickPickItem{\n\n    label: string;\n    description: string;\n    detail?: string;\n\n    constructor(public readonly pid: number, info1: string, info2: string) {\n        this.label = '';\n        const infos1 = info1.split(' ');\n        const vmArgDisplayName = parameters.vmArgDisplayName('', false);\n        for (const info of infos1) {\n            if (info.startsWith(vmArgDisplayName)) {\n                this.label = info.substring(vmArgDisplayName.length).replace(/\\%PID/g, '').replace(/\\%pid/g, '');\n                break;\n            }\n        }\n        this.label = this.label || infos1[0] || 'Java Process';\n        this.description = `(pid ${pid})`;\n        this.detail = this.normalize(info2 || info1 || 'no details available', 1000); // VS Code fails to display long string in tooltip\n    }\n\n    private normalize(string: string, limit: number): string {\n        string = string.trim();\n        const length = string.length;\n        return length <= limit ? string : string.substring(0, limit);\n    }\n\n}\n\nexport async function getUsingJps(jpsPath: string, command: string = '-v'): Promise<RunningProcess[]> {\n    return new Promise<RunningProcess[]>((resolve, reject) => {\n        const cmd = `\"${jpsPath}\" ${command}`;\n        cp.exec(cmd, async (error: any, stdout: string) => {\n            if (error) {\n                reject(error);\n            }\n            const lines = stdout.split('\\n');\n            const parts: RunningProcess[] = [];\n            lines.forEach(line => {\n                const index = line.trim().indexOf(' ');\n                if (index >= 0) {\n                    parts.push({ pid: Number.parseInt(line.slice(0, index)), displayName: line.slice(index + 1, line.length).trim() });\n                } else {\n                    parts.push({ pid: Number.parseInt(line), displayName: '' });\n                }\n            });\n            resolve(parts);\n        });\n    });\n}\n\nconst SEARCH_PROCESSES_TIMEOUT = 120;   // [s] Time to search for a process before triggering onTimeout()\nconst SEARCH_PROCESSES_INTERVAL = 1000; // [ms] Interval between calling the jps command\nconst SEARCHED_PROCESSES: SearchedProcess[] = [];\n\nlet SEARCH_PROCESSES_JPS_PATH: string | undefined;\n\ntype SearchedProcess = {\n    searchParameter: string;\n    onFound: (pid: number) => void;\n    onTimeout: () => void;\n    timeoutTime: number; // timestamp after which onTimeout() will be triggered\n};\n\nexport function setJpsPath(jpsPath: string) {\n    SEARCH_PROCESSES_JPS_PATH = jpsPath;\n}\n\nexport async function searchByParameter(searchParameter: string, onFound: (pid: number) => void, onTimeout: () => void, searchTimeout: number = SEARCH_PROCESSES_TIMEOUT * 1000) {\n    SEARCHED_PROCESSES.push({\n        searchParameter: searchParameter,\n        onFound: onFound,\n        onTimeout: onTimeout,\n        timeoutTime: Date.now() + searchTimeout\n    });\n    \n    if (SEARCHED_PROCESSES.length === 1) {\n        searchProcesses();\n    }\n}\n\nexport function stopSearching(searchParameter: string) {\n    for (let index = 0; index < SEARCHED_PROCESSES.length; index++) {\n        if (SEARCHED_PROCESSES[index].searchParameter === searchParameter) {\n            SEARCHED_PROCESSES.splice(index, 1);\n            break;\n        }\n    }\n}\n\nfunction searchProcesses() {\n    const now = Date.now();\n    for (let index = SEARCHED_PROCESSES.length - 1; index >= 0; index--) {\n        const process = SEARCHED_PROCESSES[index];\n        if (process.timeoutTime <= now) {\n            setTimeout(() => { process.onTimeout(); }, 0);\n            SEARCHED_PROCESSES.splice(index, 1);\n        }\n    }\n    if (SEARCHED_PROCESSES.length) {\n        if (SEARCH_PROCESSES_JPS_PATH) {\n            getUsingJps(SEARCH_PROCESSES_JPS_PATH).then(results => {\n                if (results.length) {\n                    for (let index = SEARCHED_PROCESSES.length - 1; index >= 0; index--) {\n                        const process = SEARCHED_PROCESSES[index];\n                        for (const result of results) {\n                            if (result.displayName.includes(process.searchParameter)) {\n                                setTimeout(() => { process.onFound(result.pid); }, 0);\n                                SEARCHED_PROCESSES.splice(index, 1);\n                                break;\n                            }\n                        }\n                    }\n                }\n                if (SEARCHED_PROCESSES.length) {\n                    setTimeout(() => { searchProcesses(); }, SEARCH_PROCESSES_INTERVAL);\n                }\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "integrations/vscode/src/test/README.md",
    "content": "# Proxy setup\n\nIn case of network behind the proxy, the following variables must be set:\n\n- `http_proxy` - URL to proxy, incl. protocol and port, e.g. http://acme.com:80\n- `no_proxy`   - URL patterns that must not use proxy. In particular, corporate/internal NPM module repositories must be enumerated in no_proxy env var.\n\nInternally (in package.json), the globalAgent/bootstrap is used with `GLOBAL_AGENT_{HTTP,NO}_PROXY`\nset to the appropriate env variable. The environment variables `http_proxy` and `no_proxy` are read by npm package manager. \n\n\n# Prepare for testing\n\nEnsure that all necessary npm modules are installed. Run\n- `npm install`\nto update the local node_modules module cache, if any changes were pulled for `package.json`.\n\nYou need to compile the VisualVM extension itself, and the test code before launching the tests.\n- `npm run compile`\n- `npm run pretest`\n\n\n# Run the tests from the CLI\n\nTests can be executed by `npm run test`. The test bootstrap will download a separate installation of vscode into `.vscode-test` directory and then duplicated into `output/a vscode-test` to test the space in path of vscode installation. The testing environment will use a **separate** extensions dir (`.vscode-test/extensions`) and user dir (`.vscode-test/user-data`). The tested vscode installation is completely separated from the development one."
  },
  {
    "path": "integrations/vscode/src/test/runTest.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport { downloadAndUnzipVSCode,\n    runTests \n} from '@vscode/test-electron';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n\n\n\nasync function main() {\ntry {\n    // The folder containing the Extension Manifest package.json\n    // Passed to `--extensionDevelopmentPath`\n    const extensionDevelopmentPath = path.resolve(__dirname, '../../');\n\n    // The path to the extension test runner script\n    // Passed to --extensionTestsPath\n    const extensionTestsPath = path.resolve(__dirname, './suite/index');\n\n    // The path to the test project \n    const testWorkspace = path.resolve(__dirname, '../../fixtures/test projects/demo');\n\n    // Manually download latest stable VS Code release for testing.\n    const vscodeExecutablePath = await downloadAndUnzipVSCode('1.89.0'); \n\n    const outputFolder = path.resolve(__dirname, '../../output');\n\n    if (!fs.existsSync(outputFolder)) {   \n        fs.mkdirSync(outputFolder);\n    }\n\n    const noSpacePath = path.resolve(__dirname, '../../.vscode-test');\n    const spacePath = path.resolve(__dirname, '../../output/a vscode-test');\n    const splitPath = vscodeExecutablePath.split('\\\\');\n    const exeFile = splitPath.pop();\n    const vscodeFolder = splitPath.pop();\n\n    let newVscodeExecutablePath: string = vscodeExecutablePath;\n    if (vscodeFolder && exeFile) {\n        newVscodeExecutablePath = path.join(spacePath, vscodeFolder, exeFile);\n    }\n    \n    if (!fs.existsSync(spacePath)) {\n        duplicate(noSpacePath, spacePath);\n    }\n\n    await runTests({\n        vscodeExecutablePath: newVscodeExecutablePath,\n        extensionDevelopmentPath, \n        extensionTestsPath,\n        launchArgs: [testWorkspace]\n    });\n\n} catch (err) {\n    console.error(err);\n    console.error('Failed to run tests');\n    process.exit(1);\n}\n}\n\nmain();\n\nfunction duplicate(sourceFolder: string, targetFolder: string) {\n\nif (!fs.existsSync(targetFolder)) {\n    fs.mkdirSync(targetFolder);\n}\n\nconst content = fs.readdirSync(sourceFolder);\n\ncontent.forEach((element) => {\n    const sourcePath = path.join(sourceFolder, element);\n    const targetPath = path.join(targetFolder, element);\n\n    if (fs.lstatSync(sourcePath).isDirectory()) {\n        duplicate(sourcePath, targetPath);\n    } else {\n        fs.copyFileSync(sourcePath, targetPath);\n    }\n});\n}"
  },
  {
    "path": "integrations/vscode/src/test/suite/download.test.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport { downloadLatestVisualVM, getReleaseMetadata } from '../../download';\nimport * as assert  from 'assert';\nimport * as vscode from 'vscode';\nimport { clean } from './utils';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n\n\n\nsuite('Download Tests', async function () {\n    let returnPath: string|undefined;\n    test('Download Success (Home Path)', async function() {\n        this.timeout(300000); // Time needed to download VisualVM\n        \n        // Creating the mocking Path\n        const outputPath = path.resolve(__dirname, '../../../output');\n        const superFolder : string = vscode.Uri.file(outputPath).fsPath;\n\n        // Before download check\n        const releaseMetadata = await getReleaseMetadata();\n        assert(releaseMetadata, 'No release meta data found.');\n        \n        // Download in the mocking Path \n        returnPath = await downloadLatestVisualVM(superFolder);\n        assert(returnPath, 'The downloadLatestVisualVM() function does not return any Path.'); \n\n        // Get The operating system\n        const opsys = process.platform;\n        \n        // Asserts\n        if (opsys !== 'darwin'){\n            \n            // Check if the VisualVM executable exists\n            assert.strictEqual(fs.existsSync(path.join(returnPath, 'bin', 'visualvm.exe')), true, 'Executable file does not exist.');\n            // Check if the VisualVM startup jar file exists\n            assert.strictEqual(fs.existsSync(path.join(returnPath, 'visualvm', 'core', 'org-graalvm-visualvm-modules-startup.jar')), true, 'Startup jar file does not exist.');\n            // Check if the VisualVM Go to source jar file exists\n            assert.strictEqual(fs.existsSync(path.join(returnPath, 'visualvm', 'modules', 'org-graalvm-visualvm-gotosource.jar')), true, 'Go to source jar file does not exist.');\n            // Check if the installation path set to workspace configuration\n            assert.strictEqual(returnPath, vscode.workspace.getConfiguration().get<string>('visualvm.installation.visualvmPath'), 'The installation path has not been configured in the workspace settings.');\n\n        } else{\n\n            // Check if installation file exists\n            assert.strictEqual(fs.existsSync(returnPath), true, 'VisualVM dmg file does not exist after download.');\n\n        }\n\n        // Clean the test installation\n        await clean(returnPath);\n    });\n\n    // this.afterAll(async () => {\n    //     assert(returnPath);\n\n    // });\n\n});\n\n\n\n\n"
  },
  {
    "path": "integrations/vscode/src/test/suite/extension.test.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as assert from 'assert';\nimport * as vscode from 'vscode';\n\n\nsuite('Extension Test Suite', () => {\n\n    test('Extension loaded', async () => {\n\n        // Get the extension using vscode API and ID  \n        let extension = vscode.extensions.getExtension('oracle-labs-graalvm.visualvm-vscode');\n        assert(extension, 'No VisualVM extension found!');\n\n        // Waiting for activating the extension\n        await extension.activate();\n\n    });\n\n    test('VisualVM commands loaded', async () => {\n\n        // Load all vscode commands\n        let commands = await vscode.commands.getCommands(true);\n\n        // Check for VisualVM commands\n        let containsVisualVMCommands = false;\n        for (const command of commands){\n                if (command.indexOf('visualvm.') === 0)\n                    containsVisualVMCommands = true;\n        }\n        assert(containsVisualVMCommands, 'No VisualVM command has been loaded');\n\n    });\n\n});"
  },
  {
    "path": "integrations/vscode/src/test/suite/index.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as path from 'path';\nimport * as glob from 'glob';\nimport * as Mocha from 'mocha';\n\nexport function run(): Promise<void> {\n\t// Create the mocha test\n\tconst mocha = new Mocha({\n\t\tui: 'tdd',\n\t\tcolor: true,\n\t\treporter: 'mochawesome'\n\t});\n\n\tconst testsRoot = path.resolve(__dirname, '..');\n\t\n\tconst globPattern = process.env['TEST_GLOB_PATTER'] ? process.env['TEST_GLOB_PATTER'] : '**/*.test.js';\n\tconsole.log(globPattern);\n\treturn new Promise((c, e) => {\n\t\tglob(globPattern, { cwd: testsRoot }, (err, files) => {\n\t\t\tif (err) {\n\t\t\t\treturn e(err);\n\t\t\t}\n\n\t\t\t// Add files to the test suite\n\t\t\tfiles.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));\n\n\t\t\ttry {\n\t\t\t\t// Run the mocha test\n\t\t\t\tmocha.run(failures => {\n\t\t\t\t\tif (failures > 0) {\n\t\t\t\t\t\te(new Error(`${failures} tests failed.`));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tc();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(err);\n\t\t\t\te(err);\n\t\t\t}\n\t\t});\n\t});\n}"
  },
  {
    "path": "integrations/vscode/src/test/suite/utils.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport { downloadLatestVisualVM, getReleaseMetadata } from '../../download';\nimport * as cp from 'child_process';\nimport * as vscode from 'vscode';\nimport * as assert from 'assert';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n\n\nexport async function setupSelectEnvironment() {\n\n    // Before download check\n    const releaseMetadata = await getReleaseMetadata();\n    assert(releaseMetadata, 'No release meta data found.');\n\n    const outputPath = path.resolve(__dirname, '../../../output');\n    const dirPath = path.join(outputPath, 'visualvm-test');\n    const firstSubDirPath = path.join(outputPath, 'visualvm-test', 'version 1');\n    const secondSubDirPath = path.join(outputPath, 'visualvm-test', 'version 2');\n\n    await fs.promises.mkdir(dirPath);\n    await fs.promises.mkdir(firstSubDirPath);\n    await fs.promises.mkdir(secondSubDirPath);\n\n    const firstFinalPath : string = vscode.Uri.file(firstSubDirPath).fsPath;\n    const secondFinalPath : string = vscode.Uri.file(secondSubDirPath).fsPath;\n\n    const firstReturnPath = await downloadLatestVisualVM(firstFinalPath);\n    assert(firstReturnPath, 'VisualVM download failed');\n    const secondReturnPath = await downloadLatestVisualVM(secondFinalPath);\n    assert(secondReturnPath, 'VisualVM download failed');\n\n    const returnPaths = {\n        'dirPath': dirPath,\n        'firstReturnPath' : firstReturnPath,\n        'secondReturnPath' : secondReturnPath\n    };\n\n    return returnPaths;\n}\n\nexport async function clean(yourPath: string) {\n\n    try{\n        await fs.promises.rm(yourPath, { recursive: true });\n    } catch (error) {\n        console.error(`Can't delete directory: ${error}`);\n    }\n\n}\n\nexport async function installExtensions(): Promise<void> {\n    const redhatPath = path.resolve(__dirname, '../../../.vscode-test/extensions/redhat.java*');\n    const nblsPath = path.resolve(__dirname, '../../../.vscode-test/extensions/asf.apache-netbeans-java*');\n\n    const redhat = fs.existsSync(redhatPath);\n    const nbls = fs.existsSync(nblsPath);\n\n    if ( !redhat ) {\n        try {\n                await vscode.commands.executeCommand('workbench.extensions.installExtension', 'redhat.java');\n        } catch (error) {\n            console.error('Can\\'t install Redhat Java extension: ', error);\n        }\n    }\n    if ( !nbls ) {\n        try {\n                await vscode.commands.executeCommand('workbench.extensions.installExtension', 'asf.apache-netbeans-java');\n        } catch (error) {\n            console.error('Can\\'t install Netbeans Language Server extension: ', error);\n        }\n    }\n\n    await waitForExtensionsToFinish();\n\n}\n\nasync function waitForExtensionsToFinish(): Promise<void> {\n    return new Promise<void>((resolve) => {\n\n        const interval = setInterval(() => {\n            const nblsExtension = vscode.extensions.getExtension('asf.apache-netbeans-java');\n            const redhatExtension = vscode.extensions.getExtension('redhat.java');\n\n            if (nblsExtension && redhatExtension) {\n                clearInterval(interval);\n                resolve();\n            }\n        }, 20000);\n    });\n}\n\nexport function duplicate(sourceFolder: string, targetFolder: string) {\n\n    if (!fs.existsSync(targetFolder)) {\n        fs.mkdirSync(targetFolder);\n    }\n\n    const content = fs.readdirSync(sourceFolder);\n\n    content.forEach((element) => {\n        const sourcePath = path.join(sourceFolder, element);\n        const targetPath = path.join(targetFolder, element);\n\n        if (fs.lstatSync(sourcePath).isDirectory()) {\n            duplicate(sourcePath, targetPath);\n        } else {\n            fs.copyFileSync(sourcePath, targetPath);\n        }\n    });\n}\n\n\nexport async function buildJavaProject (pathToProject: string) {\n    // Check maven existence    \n    cp.exec('mvn -v', (error) => {\n        if (error) {\n            console.error(`Check MAVEN installation :: Error checking Maven installation: ${error.message}`);\n        }\n    });\n    return new Promise<void> ((resolve, reject) => {\n        cp.exec('mvn clean install', { cwd: pathToProject }, (error) => {\n            if (error) {\n                console.log(`Error executing Maven build: ${error.message}`);\n                reject(error);\n                return;\n            }\n            resolve();\n        });\n    });\n}\n\n"
  },
  {
    "path": "integrations/vscode/src/test/suite/visualvm.test.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport { cpuSamplerStart, encode, getJdkSourceRoots, getTmpDir, getWorkspaceSourceRoots, goToSource, heapDump, jdkHome, jfrRecordingDump, jfrRecordingStart, jfrRecordingStop, memorySamplerStart, openPid, resolveSamplingFilter, samplerSnapshot, samplerStop, threadDump, vmArgDisplayName, vmArgId } from '../../parameters';\nimport { buildJavaProject, clean,duplicate,installExtensions, setupSelectEnvironment } from './utils'; \nimport { getUsingJps } from '../../runningProcesses';\nimport { getPath, getJpsPath } from '../../jdk';\nimport { getSourceRoots } from '../../projectUtils';\nimport { findLauncher } from '../../vscodeUtils';\nimport { invoke, select} from '../../visualvm';\nimport * as cp from 'child_process';\nimport * as assert from 'assert';\nimport * as vscode from 'vscode';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n\n// Get work space folders\nlet wf = vscode.workspace.workspaceFolders;\nsuite('VisualVM Suite Tests', function () {\n\n    // The timeout will propagate to setup dependencies and tests\n    this.timeout(1000000);\n\n    this.beforeAll(async () => {\n        this.timeout(1000000);\n        // Install NBLS & JDT   \n        await installExtensions();\n        // wait for build project\n        const projectPath = path.resolve(__dirname, '../../../fixtures/test projects/demo');\n        await buildJavaProject(projectPath);\n    });\n\n    let downloadPaths: { firstReturnPath: string; dirPath: string; secondReturnPath: string};\n    test('Select new visualvm done', async function () {\n\n        // Setup a test environment    \n        downloadPaths = await setupSelectEnvironment();\n        // Alter the path to which VisualVM is pointing\n        await select(downloadPaths.firstReturnPath);\n\n        // Get from vscode conf. the actual VisualVM path\n        const actualPath = vscode.workspace.getConfiguration().get<string>('visualvm.installation.visualvmPath');\n\n        // Check if the current path matches the expected path\n        assert.strictEqual(actualPath, downloadPaths.firstReturnPath);  \n    });\n\n    let jdk: string | undefined;\n    test('Prerequisites done', async function () {\n\n        // JDK configuration       \n        jdk = await jdkHome();\n        assert(jdk, 'no JDK available');\n\n        // Workspace and java project opened \n        assert(wf, 'workspace not found');\n        assert(wf[0].uri.toString(), 'project not found');\n\n        // Source Roots resolved \n        const sourceRoot = await getSourceRoots(wf[0]);\n        assert(sourceRoot, 'source root not found');\n\n    });\n\n    let testPid: number = 0; // pid of a test Java process\n    let visualvmPid: number = 0; // pid of a VisualVM process\n    test('Manually Selecting Project Process', async function () {\n\n        this.timeout(20000);\n\n        const projectPath = path.resolve(__dirname, '../../../fixtures/test projects/demo');\n\n        // Run Java Project\n        const TEST_JAVA_PROCESS_PARAMETER = '-Dtest.java.process=true';\n        try {\n            const jarFilePath = path.join(projectPath, 'oci/target/oci-1.0-SNAPSHOT.jar');\n            if (fs.existsSync(jarFilePath)) {\n                cp.spawn('java', [TEST_JAVA_PROCESS_PARAMETER, '-jar', 'oci/target/oci-1.0-SNAPSHOT.jar'], { cwd: projectPath });\n            } else {\n                assert(undefined, 'JAR File does not exist ... The build does not done correctly');\n            }\n        } catch (error) {\n            console.error('Error running JAR file:', error);\n        }\n\n        // Wait for the test process to fully start\n        await new Promise(f => setTimeout(f, 1500));\n\n        const jdkPath = await getPath(false);\n        assert(jdkPath, 'no JDK available');\n        const jpsPath = getJpsPath(jdkPath);\n        assert(jpsPath, 'no jps available');\n        const processes = await getUsingJps(jpsPath);\n        assert(processes, 'Can\\'t get running java processes');\n\n        let isProcessExist: boolean = false;\n        for (const process of processes) {\n            if (process.displayName.includes(TEST_JAVA_PROCESS_PARAMETER)) {\n                isProcessExist = true;\n                testPid = process.pid;\n                break;\n            }\n        }\n        assert.strictEqual(isProcessExist, true, 'Java test process not found !');\n    });\n\n    test('CPU Sampler Configuration Correctly Generated', async () => {\n        assert(wf);\n        const projectClasses = await resolveSamplingFilter('include-classes', wf[0]);\n        assert(projectClasses, 'Any project classes resolved');\n        const samplingRateP = `sampling-rate=1000`;\n        const suffix = '--start-cpu-sampler '+testPid+'@';\n\n        const withoutFile = projectClasses+','+samplingRateP;\n        const expectedParameterWithoutFile = suffix+withoutFile;\n\n        const tmp = getTmpDir();\n        assert(tmp, 'Can\\'t get tmp directory');\n        const confFile = path.join(tmp, 'visualvm-sampler-config');\n        assert(confFile);\n        const withFile = `settings-file=\"${confFile}\"`;\n        const expectedParameterWithFile = `${suffix+withFile}`;\n\n        // cases : exclude-classes - include-classes - default\n        const visualvmParameter = await cpuSamplerStart(testPid, 'include-classes', 1000, wf[0]);\n\n        assert(visualvmParameter, 'CPU Sampler can\\'t start');\n\n        if (projectClasses.length + samplingRateP.length > 200) {\n            assert.strictEqual(visualvmParameter, expectedParameterWithFile);\n        } else {\n            assert.strictEqual(visualvmParameter, expectedParameterWithoutFile);\n        }\n    });\n\n    test('Go to Source Configuration Correctly Generated', async () => {\n        assert(wf);\n\n        const jdkSourceRoot = await getJdkSourceRoots();\n        assert(jdkSourceRoot, 'Can\\'t get jdk source roots');\n\n        const workspaceSourceRoots = await getWorkspaceSourceRoots(wf[0]);\n        assert(workspaceSourceRoots, 'Can\\'t get work space source roots');\n        workspaceSourceRoots.push(jdkSourceRoot);\n\n        const launcher = findLauncher();\n        assert(launcher, 'Can\\'t found vs code launcher');\n        const vsCodeLauncherParameters = vscode.workspace.getConfiguration().get<string>('visualvm.integration.visualStudioCodeParameters', '');\n        \n        let firstParamName: string = '';\n        let secondParamName: string = '';\n\n        const params = vsCodeLauncherParameters ? ' ' + vsCodeLauncherParameters : '';\n        const sourceRouts = workspaceSourceRoots.join(path.delimiter);\n        const notFinalSourceViewer = `=${encode(`${launcher}${params}`)} -g {file}:{line}:{column}`;\n        const notFinalSourceRoots = `=${sourceRouts}`;\n\n        let expectedParameters: string = '';\n        let finalSourceRoots: string = '';\n        let finalSourceViewer: string = '';\n\n        // invoke go to source\n        const parameters = await goToSource(wf[0]);\n        assert(parameters);\n\n        if (notFinalSourceViewer.length + notFinalSourceRoots.length > 201) {\n            firstParamName = 'source-viewer';\n            secondParamName = 'source-roots';\n            finalSourceRoots = secondParamName+notFinalSourceRoots.replace(/\\\\/g, '\\\\\\\\') + '\\n';\n            finalSourceViewer = firstParamName+notFinalSourceViewer.replace(/\\\\/g, '\\\\\\\\') + '\\n';\n            expectedParameters = finalSourceViewer+finalSourceRoots;\n\n            const tmp = getTmpDir();\n            assert(tmp, 'Can\\'t get tmp directory');\n            const confFile = path.join(tmp, 'visualvm-source-config');\n            assert(confFile);\n            const expectedReturn = `--source-config=\"${encode(confFile)}\"`;\n            assert.strictEqual(expectedReturn, parameters);\n            \n            let contentOfFile = fs.readFileSync(confFile, 'utf8');\n            assert.strictEqual(expectedParameters, contentOfFile, 'parameters not set correctly');\n        } else {\n            firstParamName = '--source-viewer';\n            secondParamName = '--source-roots';\n            expectedParameters = `${firstParamName}${notFinalSourceViewer} ${secondParamName}${notFinalSourceRoots}`;\n\n            assert(expectedParameters ,parameters);\n        }\n    });\n\n    test('Test open process', () => {\n        const parameter = openPid(testPid);\n        assert.strictEqual(parameter, `--openpid ${testPid.toString()}@2`, 'Test open process failed');\n    });\n\n    test('Test thread Dump', () => {\n        const parameter = threadDump(testPid);\n        assert.strictEqual(parameter, `--threaddump ${testPid.toString()}`, 'Test thread Dump failed');\n    });\n\n    test('Test heap Dump', () => {\n        const parameter = heapDump(testPid);\n        assert.strictEqual(parameter, `--heapdump ${testPid.toString()}`, 'Test heap Dump failed');\n    });\n\n    test('Test memory Sampler Start', () => {\n        const parameter = memorySamplerStart(testPid, 2000);\n        assert.strictEqual(parameter, `--start-memory-sampler ${testPid}@sampling-rate=2000`, 'Test memory Sampler Start failed');\n    });\n\n    test('Test sampler Snapshot', () => {\n        const parameter = samplerSnapshot(testPid);\n        assert.strictEqual(parameter, `--snapshot-sampler ${testPid.toString()}`, 'Test sampler Snapshot failed');\n    });\n\n    test('Test sampler Stop', () => {\n        const parameter = samplerStop(testPid);\n        assert.strictEqual(parameter, `--stop-sampler ${testPid.toString()}`, 'Test sampler Stop failed');\n    });\n\n    test('Test jfr Recording Start', () => {\n        const parameter = jfrRecordingStart(testPid, 'my jfr', 'profile1');\n        assert.strictEqual(parameter, `--start-jfr ${testPid.toString()}@name=my%20jfr,settings=profile1`, 'Test jfr Recording Start failed');\n    });\n\n    test('Test jfr Recording Dump', () => {\n        const parameter = jfrRecordingDump(testPid);\n        assert.strictEqual(parameter, `--dump-jfr ${testPid.toString()}`, 'Test jfr Recording Dump failed');\n    });\n\n    test('Test jfr Recording Stop', () => {\n        const parameter = jfrRecordingStop(testPid);\n        assert.strictEqual(parameter, `--stop-jfr ${testPid.toString()}`, 'Test jfr Recording Stop failed');\n    });\n\n    test('Test vmArg Id', () => {\n        const parameter = vmArgId('Java_ID');\n        assert.strictEqual(parameter, `-Dvisualvm.id=Java_ID`, 'Test vmArg Id failed');\n    });\n\n    test('Test vmArg Display Name', () => {\n        const parameter = vmArgDisplayName('Java Process');\n        assert.strictEqual(parameter, `-Dvisualvm.display.name=Java_Process%PID`, 'Test vmArg Display Name failed');\n    });\n\n    test('Space in Home JDK path Then invoke', async () => {\n\n        let homeJdkPath = process.env['JAVA_HOME'];\n        if (!homeJdkPath) {\n            homeJdkPath = process.env['JDK_HOME'];\n        }\n        assert(homeJdkPath, 'JDK Home not Configured in your machine');\n        const spaceMockPath = path.resolve(__dirname, '../../../output/space JDK');\n\n        if (!fs.existsSync(spaceMockPath)) {\n            duplicate(homeJdkPath, spaceMockPath);\n        }\n\n        const spacePath =  await jdkHome(spaceMockPath);\n        assert.strictEqual(spacePath, `--jdkhome \"${spaceMockPath}\"`);\n\n\n        assert(wf);\n        \n        const TEST_VISUALVM_PROCESS_PARAMETER = '-Dvisualvm.test.process=true';\n        const isShow = await invoke(`-J${TEST_VISUALVM_PROCESS_PARAMETER}`, wf[0], spaceMockPath);\n        if (isShow) {\n            await new Promise(f => setTimeout(f, 3000));\n\n            const jdkPath = await getPath(false);\n            assert(jdkPath, 'no JDK available');\n            const jpsPath = getJpsPath(jdkPath);\n            assert(jpsPath, 'no jps available');\n            const processes = await getUsingJps(jpsPath);\n            assert(processes, 'Can\\'t get running java processes');\n\n            for (const process of processes) {\n                if (process.displayName.includes(TEST_VISUALVM_PROCESS_PARAMETER)) {\n                    visualvmPid = process.pid;\n                    break;\n                }\n            }\n        }\n\n        assert.strictEqual(isShow && !!visualvmPid, true, 'VisualVM can\\'t started');\n    });\n\n\n    this.afterAll(async () => {\n        this.timeout(15000);\n        if (testPid) {\n            try {\n                process.kill(testPid);\n            } catch (err) {\n                console.log(`Failed to kill test process PID=${testPid}: ${err}`)\n            }\n        }\n        if (visualvmPid) {\n            try {\n                process.kill(visualvmPid);\n            } catch (err) {\n                console.log(`Failed to kill visualvm process PID=${visualvmPid}: ${err}`)\n            }\n        }\n        // Wait for a while to have all resources released before the final cleanup\n        await new Promise(f => setTimeout(f, 3000));\n        // Clean the test installations\n        await clean(downloadPaths.dirPath);\n    });\n});\n"
  },
  {
    "path": "integrations/vscode/src/view.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as vscode from 'vscode';\nimport * as nodes from './nodes';\nimport * as commands from './commands';\nimport * as logUtils from './logUtils';\n\n\n// Predefined views\nconst VISUALVM_VIEW_ID = 'visualvm-visualvm';\nconst EXPLORER_TOOLS_VIEW_ID = 'explorer-visualvm';\nconst DEBUG_TOOLS_VIEW_ID = 'debug-visualvm';\nconst PREDEFINED_VIEW_IDS = [ VISUALVM_VIEW_ID, EXPLORER_TOOLS_VIEW_ID, DEBUG_TOOLS_VIEW_ID ];\n\n// Supported external views\nconst MICRONAUT_TOOLS_VIEW: ExternalView = {\n    extension_id: 'oracle-labs-graalvm.micronaut-tools',\n    container_id: 'extension-micronaut-tools',\n    view_id     : 'extension-micronaut-tools-visualvm'\n};\n// const SPRING_BOOT_DASHBOARD_VIEW: ExternalView = {\n//     extension_id: 'vscjava.vscode-spring-boot-dashboard',\n//     container_id: 'spring',\n//     view_id     : 'spring-visualvm'\n// };\nconst EXTERNAL_VIEWS = [ MICRONAUT_TOOLS_VIEW ];\nconst EXTERNAL_VIEW_IDS = EXTERNAL_VIEWS.map(view => view.view_id);\n\n// All views\nconst ALL_VIEW_IDS = [ ...PREDEFINED_VIEW_IDS, ...EXTERNAL_VIEW_IDS ];\n\ntype ExternalView = {\n    extension_id: string;\n    container_id: string;\n    view_id     : string;\n};\n\nconst VIEW_KEY = 'visualvm.view';\nlet currentViewId: string | undefined;\n\nconst ALL_VIEWS_KEY = 'visualvm.views';\n\nconst CREATED_VIEWS: any = {};\n\nlet persistentStorage: vscode.Memento | undefined;\n\nexport function initialize(context: vscode.ExtensionContext) {\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_MOVE_VIEW, (viewId?: string) => {\n        // NOTE: if called without the viewId parameter, the last selected node is passed as a parameter\n        move(typeof viewId === 'string' ? viewId : undefined);\n\t}));\n\n    let viewId: string | undefined;\n\n    // For now the view is always persisted in the global storage\n    // In future we may decide to optionally store it per workspace\n    const workspaceViewId = context.workspaceState.get<string>(VIEW_KEY);\n    if (workspaceViewId) {\n        persistentStorage = context.workspaceState;\n        if (PREDEFINED_VIEW_IDS.includes(workspaceViewId)) {\n            viewId = workspaceViewId;\n            logUtils.logInfo(`[view] Restoring predefined view saved for workspace: ${workspaceViewId}`);\n        } else if (EXTERNAL_VIEW_IDS.includes(workspaceViewId)) {\n            if (externalViewAvailable(workspaceViewId)) {\n                viewId = workspaceViewId;\n                logUtils.logInfo(`[view] Restoring external view saved for workspace: ${workspaceViewId}`);\n            } else {\n                logUtils.logWarning(`[view] External view saved for workspace cannot be restored: ${workspaceViewId}`);\n            }\n        } else {\n            logUtils.logWarning(`[view] Unknown view saved for workspace cannot be restored: ${workspaceViewId}`);\n        }\n    } else {\n        logUtils.logInfo('[view] No view saved for workspace');\n    }\n\n    if (!viewId) {\n        const globalViewId = context.globalState.get<string>(VIEW_KEY);\n        if (globalViewId) {\n            if (PREDEFINED_VIEW_IDS.includes(globalViewId)) {\n                viewId = globalViewId;\n                logUtils.logInfo(`[view] Restoring predefined view saved globally: ${globalViewId}`);\n            } else if (EXTERNAL_VIEW_IDS.includes(globalViewId)) {\n                if (externalViewAvailable(globalViewId)) {\n                    viewId = globalViewId;\n                    logUtils.logInfo(`[view] Restoring external view saved globally: ${globalViewId}`);\n                } else {\n                    logUtils.logWarning(`[view] External view saved globally cannot be restored: ${globalViewId}`);\n                }\n            } else {\n                logUtils.logWarning(`[view] Unknown view saved globally cannot be restored: ${globalViewId}`);\n            }\n        } else {\n            logUtils.logInfo('[view] No view saved globally');\n        }\n    }\n\n    if (!viewId) {\n        viewId = VISUALVM_VIEW_ID;\n        logUtils.logInfo(`[view] Fallback to default view: ${viewId}`);\n    }\n\n    // For now the view is always persisted in the global storage\n    // In future we may decide to optionally store it per workspace\n    if (!persistentStorage) {\n        persistentStorage = context.globalState;\n    }\n\n    switchView(viewId);\n\n    vscode.commands.executeCommand('setContext', ALL_VIEWS_KEY, ALL_VIEW_IDS);\n}\n\nexport async function move(viewId?: string): Promise<boolean | undefined> {\n    if (!viewId) {\n        logUtils.logInfo('[view] Selecting view container');\n        viewId = await selectViewContainer(commands.COMMAND_MOVE_VIEW_NAME);\n        if (!viewId) {\n            logUtils.logInfo('[view] View container selection canceled');\n            return undefined;\n        }\n    } else {\n        logUtils.logInfo(`[view] Requested to move view: ${viewId}`);\n        if (EXTERNAL_VIEW_IDS.includes(viewId)) {\n            if (!externalViewAvailable(viewId)) {\n                logUtils.logWarning(`[view] External view not available: ${viewId}`);\n                return false;\n            }\n        } else if (!PREDEFINED_VIEW_IDS.includes(viewId)) {\n            logUtils.logWarning(`[view] Unknown view: ${viewId}`);\n            return false;\n        }\n    }\n\n    if (persistentStorage) {\n        persistentStorage.update(VIEW_KEY, viewId);\n    }\n\n    switchView(viewId);\n\n    // Make sure the selected view appears in the expected location\n    await vscode.commands.executeCommand(viewId + '.resetViewLocation');\n\n    // Focus the selected view to make sure it's visible\n    await vscode.commands.executeCommand(viewId + '.focus');\n\n    return true;\n}\n\nexport function hideNodes() {\n    nodes.provider().setVisible(false);\n}\n\nexport function showNodes() {\n    nodes.provider().setVisible(true);\n}\n\nexport function getViewId(): string {\n    return currentViewId || VISUALVM_VIEW_ID;\n}\n\nasync function selectViewContainer(actionName?: string): Promise<string | undefined> {\n    const items: (vscode.QuickPickItem & { viewId: string }) [] = [];\n\n    items.push({ label: 'VisualVM', description: currentViewId === VISUALVM_VIEW_ID ? '(current)' : undefined, viewId: VISUALVM_VIEW_ID });\n    items.push({ label: 'Explorer', description: currentViewId === EXPLORER_TOOLS_VIEW_ID ? '(current)' : undefined, viewId: EXPLORER_TOOLS_VIEW_ID });\n    items.push({ label: 'Run and Debug', description: currentViewId === DEBUG_TOOLS_VIEW_ID ? '(current)' : undefined, viewId: DEBUG_TOOLS_VIEW_ID });\n    \n    if (externalViewAvailable(MICRONAUT_TOOLS_VIEW)) {\n        items.push({ label: 'Micronaut Tools', description: currentViewId === MICRONAUT_TOOLS_VIEW.view_id ? '(current)' : undefined, viewId: MICRONAUT_TOOLS_VIEW.view_id });\n    }\n    \n    return vscode.window.showQuickPick(items, { title: actionName || 'Select VisualVM View Container', placeHolder: 'Choose the VisualVM view location:' }).then(selected => selected?.viewId);\n}\n\nfunction externalViewAvailable(view: string | ExternalView): boolean {\n    let externalView = typeof view === 'string' ? findExternalView(view) : view;\n    if (!externalView) {\n        logUtils.logWarning(`[view] Unknown external view: ${view}`);\n        return false;\n    }\n    const extension = vscode.extensions.getExtension(externalView.extension_id);\n    if (extension) {\n        const extensionViews = extension.packageJSON?.contributes?.views?.[externalView.container_id];\n        if (Array.isArray(extensionViews)) {\n            for (const extensionView of extensionViews) {\n                if (extensionView.id === externalView.view_id) {\n                    if (extensionView.name !== 'VisualVM') {\n                        logUtils.logWarning(`[view] Extension providing external view defines unsupported view name: ${extensionView.name}`);\n                        return false;\n                    }\n                    if (extensionView.when !== `${VIEW_KEY} == ${externalView.view_id}` &&\n                        extensionView.when !== `${VIEW_KEY} === ${externalView.view_id}`) {\n                        logUtils.logWarning(`[view] Extension providing external view defines unsupported view activation: ${extensionView.when}`);\n                        return false;\n                    }\n                    return true;\n                }\n            }\n        }\n        logUtils.logWarning(`[view] Extension providing external view doesn't define VisualVM view in: ${externalView.container_id}`);\n    } else {\n        logUtils.logWarning(`[view] Extension providing external view not available: ${externalView.extension_id}`);\n    }\n    return false;\n}\n\nfunction findExternalView(viewId: string): ExternalView | undefined {\n    for (const externalView of EXTERNAL_VIEWS) {\n        if (externalView.view_id === viewId) {\n            return externalView;\n        }\n    }\n    return undefined;\n}\n\nfunction switchView(viewId: string) {\n    if (!CREATED_VIEWS[viewId]) {\n        CREATED_VIEWS[viewId] = vscode.window.createTreeView(viewId, { treeDataProvider: nodes.provider() });\n        logUtils.logInfo(`[view] Created view ${viewId}`);\n    }\n    currentViewId = viewId;\n    vscode.commands.executeCommand('setContext', VIEW_KEY, viewId);\n    logUtils.logInfo(`[view] View switched to ${viewId}`);\n}\n"
  },
  {
    "path": "integrations/vscode/src/visualvm.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as vscode from 'vscode';\nimport * as os from 'os';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as process from 'process';\nimport * as cp from 'child_process';\nimport * as view from './view';\nimport * as parameters from './parameters';\nimport * as commands from './commands';\nimport * as logUtils from './logUtils';\n\n\nexport const VISUALVM_HOMEPAGE = 'https://visualvm.github.io';\n\nconst INITIALIZED_KEY = 'visualvm.initialized';\nconst NO_INSTALLATION_KEY = 'visualvm.noInstallation';\n\nconst INSTALLATION_PATH_KEY = 'visualvm.installation.visualvmPath';\n\ntype VisualVMInstallation = {\n    executable: string;\n    isGraalVM: boolean;\n    // 1: VisualVM 2.1+\n    featureSet: number;\n};\n\nlet interactiveChange: boolean = false;\n\nexport async function initialize(context: vscode.ExtensionContext) {\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_SELECT_INSTALLATION, () => {\n        select();\n\t}));\n    context.subscriptions.push(vscode.commands.registerCommand(commands.COMMAND_START_VISUALVM, () => {\n        show();\n\t}));\n    resolve();\n    context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(event => {\n        if (event.affectsConfiguration(INSTALLATION_PATH_KEY)) {\n            logUtils.logInfo('[visualvm] Installation path changed');\n            const interactive = interactiveChange;\n            interactiveChange = false;\n            resolve(interactive);\n        }\n    }));\n}\n\nexport async function select(visualVMPath?: string) {\n    const savedVisualVMPath = vscode.workspace.getConfiguration().get<string>(INSTALLATION_PATH_KEY);\n    const savedVisualVMUri = savedVisualVMPath ? vscode.Uri.file(savedVisualVMPath) : undefined;\n    if (!visualVMPath) {\n        logUtils.logInfo('[visualvm] Selecting VisualVM installation');\n        const macOS = process.platform === 'darwin';\n        const selectedVisualVMUri = await vscode.window.showOpenDialog({\n            title: `${commands.COMMAND_SELECT_INSTALLATION_NAME} Folder`,\n            canSelectFiles: macOS ? true : false,\n            canSelectFolders: macOS ? false : true,\n            canSelectMany: false,\n            defaultUri: macOS ? vscode.Uri.file('/Applications') : savedVisualVMUri || vscode.Uri.file(os.homedir()),\n            openLabel: process.platform === 'darwin' ? 'Select VisualVM Installation' : 'Select'\n        });\n        if (selectedVisualVMUri?.length === 1) {\n            visualVMPath = selectedVisualVMUri[0].fsPath;\n        } else {\n            logUtils.logInfo('[visualvm] VisualVM installation selection canceled');\n        }\n    }\n    if (visualVMPath) {\n        const selectedVisualVMPath = visualVMPath;\n        if (selectedVisualVMPath !== savedVisualVMPath) {\n            logUtils.logInfo('[visualvm] Selected new VisualVM installation, saving installation path');\n            interactiveChange = true;\n            await vscode.workspace.getConfiguration().update(INSTALLATION_PATH_KEY, selectedVisualVMPath, vscode.ConfigurationTarget.Global);\n        } else {\n            // Has to be handled separately, wouldn't trigger any notification from settings.json\n            logUtils.logInfo('[visualvm] Selected current VisualVM installation, re-resolving');\n            resolve(true);\n        }\n    }\n}\n\nexport async function get(interactive: boolean = false): Promise<VisualVMInstallation | undefined> {\n    const savedVisualVMPath = vscode.workspace.getConfiguration().get<string>(INSTALLATION_PATH_KEY);\n    if (savedVisualVMPath) {\n        logUtils.logInfo(`[visualvm] Found defined installation path: ${savedVisualVMPath}`);\n        return forPath(savedVisualVMPath, interactive);\n    } else {\n        logUtils.logInfo('[visualvm] No installation path defined');\n        return undefined;\n    }\n}\n\nasync function resolve(interactive: boolean = false) {\n    logUtils.logInfo('[visualvm] Searching for VisualVM installation');\n    await vscode.commands.executeCommand('setContext', NO_INSTALLATION_KEY, false);\n    await vscode.commands.executeCommand('setContext', INITIALIZED_KEY, false);\n    view.hideNodes();\n    let installation = undefined;\n    try {\n        installation = await get(interactive);\n    } finally {\n        await vscode.commands.executeCommand('setContext', INITIALIZED_KEY, true);\n        await vscode.commands.executeCommand('setContext', NO_INSTALLATION_KEY, !installation);\n        if (installation) {\n            view.showNodes();\n        }\n    }\n}\n\nasync function forPath(visualVMPath: string, interactive: boolean = false): Promise<VisualVMInstallation | undefined> {\n    if (!fs.existsSync(visualVMPath)) {\n        logUtils.logError(`[visualvm] Installation path does not exist: ${visualVMPath}`);\n        if (interactive) {\n            vscode.window.showErrorMessage(`VisualVM installation path does not exist: ${visualVMPath}`);\n        }\n        return undefined;\n    }\n    if (!fs.statSync(visualVMPath).isDirectory()) {\n        logUtils.logError(`[visualvm] Installation path is not a directory: ${visualVMPath}`);\n        if (interactive) {\n            vscode.window.showErrorMessage(`VisualVM installation path is not a directory: ${visualVMPath}`);\n        }\n        return undefined;\n    }\n\n    let isGraalVM: boolean = false;\n    let isMacOsApp: boolean = false;\n\n    const gvisualVMExecutable = path.join(visualVMPath, 'bin', process.platform === 'win32' ? 'visualvm.exe' : 'visualvm'); // GitHub VisualVM\n    const mvisualVMExecutable = process.platform === 'darwin' && visualVMPath.endsWith('.app') ? path.join(visualVMPath, 'Contents', 'MacOS', 'visualvm') : undefined; // VisualVM.app on macOS\n    const jvisualVMExecutable = path.join(visualVMPath, 'bin', process.platform === 'win32' ? 'jvisualvm.exe' : 'jvisualvm'); // GraalVM VisualVM\n    if (!fs.existsSync(gvisualVMExecutable)) {\n        if (!mvisualVMExecutable || !fs.existsSync(mvisualVMExecutable)) {\n            if (!fs.existsSync(jvisualVMExecutable)) {\n                logUtils.logError(`[visualvm] Installation executable does not exist: ${gvisualVMExecutable}`);\n                if (interactive) {\n                    vscode.window.showErrorMessage(`VisualVM executable does not exist: ${gvisualVMExecutable}`);\n                }\n                return undefined;\n            } else {\n                logUtils.logInfo(`[visualvm] VisualVM executable found in GraalVM installation: ${mvisualVMExecutable}`);\n                isGraalVM = true;\n            }\n        } else {\n            logUtils.logInfo(`[visualvm] VisualVM executable found in MacOS application: ${mvisualVMExecutable}`);\n            isMacOsApp = true;\n        }\n    } else {\n        logUtils.logInfo(`[visualvm] VisualVM executable found in standard installation: ${gvisualVMExecutable}`);\n    }\n    const visualVMExecutable = isGraalVM ? jvisualVMExecutable : (isMacOsApp ? mvisualVMExecutable as string : gvisualVMExecutable);\n    if (!fs.statSync(visualVMExecutable).isFile()) {\n        logUtils.logError(`[visualvm] Installation executable is not a file: ${visualVMExecutable}`);\n        if (interactive) {\n            vscode.window.showErrorMessage(`Invalid VisualVM executable: ${visualVMExecutable}`);\n        }\n        return undefined;\n    }\n    logUtils.logInfo(`[visualvm] Found valid executable: ${visualVMExecutable}`);\n\n    const visualVMGoToSourceJarPath = [];\n    if (isGraalVM) visualVMGoToSourceJarPath.push(...[ 'lib', 'visualvm' ]);\n    else if (isMacOsApp) visualVMGoToSourceJarPath.push(...[ 'Contents', 'Resources', 'visualvm' ]);\n    visualVMGoToSourceJarPath.push(...[ 'visualvm', 'modules', 'org-graalvm-visualvm-gotosource.jar' ]);\n    const visualVMGoToSourceJar = path.join(visualVMPath, ...visualVMGoToSourceJarPath);\n    if (!fs.existsSync(visualVMGoToSourceJar)) {\n        logUtils.logError(`[visualvm] Installation org-graalvm-visualvm-gotosource.jar does not exist: ${visualVMGoToSourceJar}`);\n        if (interactive) {\n            vscode.window.showErrorMessage(`Unsupported VisualVM version found in ${visualVMPath}. Please install the latest VisualVM from [${VISUALVM_HOMEPAGE}](${VISUALVM_HOMEPAGE}).`);\n        }\n        return undefined;\n    }\n    if (!fs.statSync(visualVMGoToSourceJar).isFile()) {\n        logUtils.logError(`[visualvm] Installation org-graalvm-visualvm-gotosource.jar is not a file: ${visualVMGoToSourceJar}`);\n        if (interactive) {\n            vscode.window.showErrorMessage(`The selected VisualVM installation is broken: ${visualVMPath}`);\n        }\n        return undefined;\n    }\n    logUtils.logInfo(`[visualvm] Found valid org-graalvm-visualvm-gotosource.jar: ${visualVMGoToSourceJar}`);\n    \n    return { executable: visualVMExecutable, isGraalVM: isGraalVM, featureSet: 1 };\n}\n\nexport async function show(pid?: number, folder?: vscode.WorkspaceFolder): Promise<boolean> {\n    return vscode.window.withProgress({\n            location: { viewId: view.getViewId() }\n        },\n        async () => {\n            let params = parameters.windowToFront();\n            if (pid !== undefined) {\n                params += ` ${parameters.openPid(pid)}`;\n            }\n            return invoke(params, folder);\n        }\n    );\n}\n\nexport async function perform(params: string | Promise<string | undefined>, folder?: vscode.WorkspaceFolder): Promise<boolean> {\n    return vscode.window.withProgress({\n            location: { viewId: view.getViewId() }\n        },\n        async () => {\n            // Resolve provided params promise\n            if (typeof params !== 'string') {\n                logUtils.logInfo('[visualvm] Resolving provided parameters...');\n                const resolvedParams = await Promise.resolve(params);\n                if (resolvedParams === undefined) {\n                    logUtils.logInfo('[visualvm] Canceled starting VisualVM');\n                    return false;\n                } else {\n                    params = resolvedParams;\n                }\n            }\n\n            const windowToFront = parameters.windowToFrontConditional();\n            if (windowToFront) {\n                params += ` ${windowToFront}`;\n            }\n            return invoke(params, folder);\n        }\n    );\n}\n\nexport async function invoke(params?: string, folder?: vscode.WorkspaceFolder, predefinedJDK?: string): Promise<boolean> {\n    logUtils.logInfo('[visualvm] Starting VisualVM');\n    \n    const installation = await get();\n    if (!installation) {\n        resolve(true);\n        return false;\n    }\n\n    const command: string[] = [];\n\n    // VisualVM executable -----\n    command.push(parameters.executable(installation.executable));\n\n    // Required parameters -----\n    // Increase commandline length for jvmstat\n    command.push(parameters.perfMaxStringConstLength());\n\n    // Configurable pararameters\n    // --jdkhome\n    if (!installation.isGraalVM) {\n        try {\n            const jdkHome = await parameters.jdkHome(predefinedJDK);\n            if (jdkHome) {\n                command.push(jdkHome);\n            }\n        } catch (err) {\n            logUtils.logError('[visualvm] Cannot start with --jdkhome, no JDK available');\n            return false;\n        }\n    }\n\n    // User-defined parameters\n    const userParams = parameters.userDefinedParameters();\n    if (userParams) {\n        command.push(userParams);\n    }\n\n    // Go to Source integration\n    const goToSource = await parameters.goToSource(folder);\n    if (goToSource) {\n        command.push(goToSource);\n    }\n\n    // Provided parameters -----\n    if (params) {\n        command.push(params);\n    }\n    \n    const commandString = command.join(' ');\n    logUtils.logInfo(`[visualvm] Command: ${commandString}`);\n    cp.exec(commandString);\n\n    return true;\n}\n"
  },
  {
    "path": "integrations/vscode/src/vscodeUtils.ts",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as process from 'process';\n\n\nexport function findLauncher(): string | undefined {\n    const execPath = process.execPath;\n    let launcherPath: string | undefined = undefined;\n\n    if (process.platform === 'darwin') {\n        const CONTENTS_HANDLE = '/Contents';\n        const idx = execPath.indexOf(`${CONTENTS_HANDLE}/Frameworks/`);\n        if (idx > -1) {\n            launcherPath = `${execPath.substring(0, idx + CONTENTS_HANDLE.length)}/Resources/app/bin/code`;\n        }\n    } else {\n        const execDir = path.resolve(execPath, '..');\n        launcherPath = path.join(execDir, 'bin', 'code');\n        if (process.platform === 'win32') {\n            launcherPath = `${launcherPath}.cmd`;\n        }\n    }\n\n    if (launcherPath && fs.existsSync(launcherPath)) {\n        if (launcherPath.indexOf(' ') > -1) {\n            launcherPath = `\"${launcherPath}\"`;\n        }\n        return launcherPath;\n    }\n\n    return undefined;\n}\n"
  },
  {
    "path": "integrations/vscode/tsconfig.eslint.json",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n{\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\n      \".eslintrc.js\",\n      \"**/*.ts\",\n      \"webpack.config.js\"\n    ]\n  }"
  },
  {
    "path": "integrations/vscode/tsconfig.json",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n{\n\t\"compilerOptions\": {\n\t\t\"allowJs\": true,\n\t\t\"module\": \"commonjs\",\n\t\t\"target\": \"es6\",\n\t\t\"outDir\": \"dist\",\n\t\t\"lib\": [\n\t\t\t\"es6\", \"DOM\"\n\t\t],\n\t\t\"sourceMap\": true,\n\t\t\"rootDir\": \"src\",\n\t\t/* Strict Type-Checking Option */\n\t\t\"strict\": true,   /* enable all strict type-checking options */\n\t\t/* Additional Checks */\n\t\t\"noUnusedLocals\": true, /* Report errors on unused locals. */\n\t\t\"noImplicitReturns\": true, /* Report error when not all code paths in function return a value. */\n\t\t\"noFallthroughCasesInSwitch\": true, /* Report errors for fallthrough cases in switch statement. */\n\t\t\"noUnusedParameters\": true,  /* Report errors on unused parameters. */\n\t\t\"baseUrl\": \".\",\n\t\t\"paths\": {\n\t\t  \"vscode\": [\n\t\t\t\"node_modules/@types/vscode\"\n\t\t  ]\n\t\t}\n\t},\n\t\"include\": [\n\t\t\"src/**/*\"\n\t],\n\t\"exclude\": [\n\t\t\"node_modules\",\n\t\t\".vscode-test\"\n\t]\n}\n"
  },
  {
    "path": "integrations/vscode/webpack.config.js",
    "content": "/*\n * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n//@ts-check\n/* eslint-disable @typescript-eslint/naming-convention */\n\n'use strict';\n\nconst path = require('path');\nconst webpack = require('webpack');\nconst ESLintPlugin = require('eslint-webpack-plugin');\n\n/**@type {import('webpack').Configuration}*/\nconst config = {\n    target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/\n\n    entry: {\n        extension: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/\n    },\n    output: { // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/\n        path: path.resolve(__dirname, 'dist'),\n        filename: '[name].js',\n        libraryTarget: \"commonjs2\",\n        devtoolModuleFilenameTemplate: \"../[resource-path]\",\n    },\n    devtool: 'source-map',\n    externals: {\n        vscode: \"commonjs2 vscode\", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/\n    },\n    resolve: { // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader\n        extensions: ['.ts', '.js', '.json'],\n        modules: ['node_modules'],\n        mainFields: ['main', 'module'],\n        byDependency: {\n            'node-fetch': {\n                mainFields: ['main', 'module']\n            },\n            'isomorphic-fetch': {\n                mainFields: ['main', 'module']\n            }\n        }\n    },\n    module: {\n        rules: [{\n            test: /\\.ts$/,\n            exclude: /node_modules/,\n            include: path.resolve(__dirname, 'src'),\n            use: [{\n                loader: 'ts-loader'\n            }]\n        }]\n    },\n    plugins: [\n        new ESLintPlugin({extensions: ['ts']})\n    ]\n};\nconst devConf = {\n    target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/\n\n    entry: {\n        extension: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/\n    },\n    output: { // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/\n        path: path.resolve(__dirname, 'dist'),\n        filename: '[name].js',\n        libraryTarget: \"commonjs2\",\n        devtoolModuleFilenameTemplate: \"../[resource-path]\",\n    },\n    devtool: 'source-map',\n    externals: {\n        vscode: \"commonjs2 vscode\", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/\n    },\n    resolve: { // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader\n        extensions: ['.ts', '.js', '.json'],\n        modules: ['node_modules'],\n        mainFields: ['main', 'module'],\n        byDependency: {\n            'node-fetch': {\n                mainFields: ['main', 'module']\n            },\n            'isomorphic-fetch': {\n                mainFields: ['main', 'module']\n            }\n        },\n        symlinks: false,\n        cacheWithContext: false,\n    },\n    module: {\n        rules: [{\n            test: /\\.ts$/,\n            exclude: /node_modules/,\n            include: path.resolve(__dirname, 'src'),\n            use: [{\n                loader: 'ts-loader',\n                options: {\n                    transpileOnly: true, // https://github.com/TypeStrong/ts-loader#faster-builds\n                }\n            }]\n        }]\n    },\n    optimization: {\n        minimize: false\n    },\n    plugins: [\n        new webpack.AutomaticPrefetchPlugin()\n    ],\n    cache: {\n        type: 'filesystem',\n        buildDependencies: {\n            // This makes all dependencies of this file - build dependencies\n            config: [__filename],\n            // By default webpack and loaders are build dependencies\n        },\n    },\n};\n// https://webpack.js.org/configuration/mode/#mode-none\nmodule.exports = (env, argv) => {\n    if (argv.mode === 'development') {\n        return devConf;\n    }\n\n    if (argv.mode === 'production') {\n        return config;\n    }\n    return config;\n};\n"
  },
  {
    "path": "plugins/btrace/PROJECT_MOVED.txt",
    "content": "https://btrace.dev.java.net/source/browse/btrace/extra/visualvm-plugin-suite/\n"
  },
  {
    "path": "plugins/buffermonitor/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.buffermonitor\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.buffermonitor.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/buffermonitor/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.buffermonitor/2\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/buffermonitor/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/buffermonitor/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "plugins/buffermonitor/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.buffermonitor-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/buffermonitor/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=81664b27\nbuild.xml.script.CRC32=dcc223e1\nbuild.xml.stylesheet.CRC32=05353c81\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=7dd7675e\nnbproject/build-impl.xml.script.CRC32=d3d069fa\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "plugins/buffermonitor/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\njavac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Tomas Hurka, Jiri Sedlacek\ncp.extra=${tools.jar}\nmodule.javadoc.packages=org.graalvm.visualvm.modules.buffermonitor.*\n"
  },
  {
    "path": "plugins/buffermonitor/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.buffermonitor</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.charts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/buffermonitor/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/buffermonitor/src/org/graalvm/visualvm/modules/buffermonitor/BufferMonitorView.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.buffermonitor;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.charts.ChartFactory;\nimport org.graalvm.visualvm.charts.SimpleXYChartDescriptor;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport java.awt.BorderLayout;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.logging.Logger;\nimport javax.management.Attribute;\nimport javax.management.MBeanServerConnection;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\nimport javax.swing.Timer;\nimport javax.swing.ImageIcon;\nimport javax.swing.JPanel;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n * @author Tomas Hurka\n */\nclass BufferMonitorView extends DataSourceView implements DataRemovedListener<Application> {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/modules/buffermonitor/resources/monitor.png\"; // NOI18N\n    private static final Logger LOGGER = Logger.getLogger(BufferMonitorView.class.getName());\n    \n    private Timer timer;\n    private Application application;\n    private boolean refreshRunning;\n    \n    public BufferMonitorView(Application application) {\n        super(application, NbBundle.getMessage(BufferMonitorView.class, \"Buffer_Pools\"), new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 60, false); // NOI18N\n        this.application = application;\n    }\n    \n    @Override\n    protected void removed() {\n        timer.stop();\n    }\n    \n    protected DataViewComponent createComponent() {\n        DataViewComponent dvc = new DataViewComponent(\n                new MasterViewSupport(application).getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(false));\n        JmxModel jmx = JmxModelFactory.getJmxModelFor(application);\n        String title = NbBundle.getMessage(BufferMonitorView.class, \"LBL_DIRECT\");  // NOI18N\n        final BufferMonitorViewSupport directBufferViewSupport = new BufferMonitorViewSupport(jmx, title, BufferMonitorViewProvider.DIRECT_BUFFER_NAME);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(title, true), DataViewComponent.TOP_LEFT); \n        dvc.addDetailsView(directBufferViewSupport.getDetailsView(), DataViewComponent.TOP_LEFT);\n        \n        title = NbBundle.getMessage(BufferMonitorView.class, \"LBL_MAPPED\"); // NOI18N\n        final BufferMonitorViewSupport mappedBufferViewSupport = new BufferMonitorViewSupport(jmx, title, BufferMonitorViewProvider.MAPPED_BUFFER_NAME);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(title, true), DataViewComponent.TOP_RIGHT); \n        dvc.addDetailsView(mappedBufferViewSupport.getDetailsView(), DataViewComponent.TOP_RIGHT);\n        \n        timer = new Timer(GlobalPreferences.sharedInstance().getMonitoredDataPoll() * 1000, new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                if (refreshRunning) {\n                    return;\n                }\n                refreshRunning = true;\n                RequestProcessor.getDefault().post(new Runnable() {\n                    public void run() {\n                        try {\n                            if (application.getState() == Application.STATE_AVAILABLE) {\n                                final long time = System.currentTimeMillis();\n                                directBufferViewSupport.refresh(time);\n                                mappedBufferViewSupport.refresh(time);\n                            }\n                        } catch (Exception ex) {\n                            LOGGER.throwing(BufferMonitorView.class.getName(), \"refresh\", ex); // NOI18N\n                        } finally {\n                            refreshRunning = false;\n                        }\n                    }\n                });\n\n            }\n        });\n        timer.setInitialDelay(800);\n        timer.start();\n        getDataSource().notifyWhenRemoved(this);\n        \n        return dvc;\n    }\n    \n    public void dataRemoved(Application app) {\n        timer.stop();\n    }\n    \n    private static class MasterViewSupport extends JPanel  {\n        \n        public MasterViewSupport(Application app) {\n            initComponents(app);\n        }\n        \n        \n        public DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(BufferMonitorView.class, \"Buffer_Pools\"), null, this);   // NOI18N\n        }\n        \n        \n        private void initComponents(Application app) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n        }\n        \n        String getGeneralInfo(Application app) {\n            return \"\";\n        }\n        \n    }\n    private static class BufferMonitorViewSupport extends JPanel  {\n        \n        private static final String MEMORY_USED = NbBundle.getMessage(BufferMonitorView.class, \"LBL_Memory_Used\"); // NOI18N\n        private static final String TOTAL_CAPACITY = NbBundle.getMessage(BufferMonitorView.class, \"LBL_Total_Capacity\"); // NOI18N\n        private static final String COUNT = NbBundle.getMessage(BufferMonitorView.class, \"LBL_Count\"); // NOI18N\n        private SimpleXYChartSupport chartSupport;\n        private final String TITLE;\n        private ObjectName bufferObjectName;\n        private final MBeanServerConnection conn;\n        private final String[] attributes = {\"Count\",\"MemoryUsed\",\"TotalCapacity\"}; // NOI18N\n        \n        public BufferMonitorViewSupport(JmxModel jmx, String title, String bufferName) {\n            GlobalPreferences preferences = GlobalPreferences.sharedInstance();\n            int chartCache = preferences.getMonitoredDataCache() * 60 /\n                         preferences.getMonitoredDataPoll();\n            conn = jmx.getMBeanServerConnection();\n            try {\n                bufferObjectName = new ObjectName(bufferName);\n            } catch (MalformedObjectNameException ex) {\n                ex.printStackTrace();\n            }\n            TITLE = title;\n            initModels(chartCache);\n            initComponents();\n        }\n        \n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(TITLE, null, 10, this, null);\n        }\n        \n        public void refresh(long time) {\n            long count = 0;\n            long memoryUsed = 0;\n            long totalCapacity = 0;\n            List attrs;\n            \n            try {\n                attrs = conn.getAttributes(bufferObjectName, attributes);\n            } catch (Exception ex) {\n                ex.printStackTrace();\n                return;\n            }\n            Iterator attrIt = attrs.iterator();\n            \n            while(attrIt.hasNext()) {\n                Attribute attrib = (Attribute) attrIt.next();\n                String name = attrib.getName();\n                if (attributes[0].equals(name)) {\n                    count = ((Long)attrib.getValue()).longValue();\n                } else if (attributes[1].equals(name)) {\n                    memoryUsed = ((Long)attrib.getValue()).longValue();\n                } else if (attributes[2].equals(name)) {\n                    totalCapacity = ((Long)attrib.getValue()).longValue();\n               }\n            }\n            chartSupport.addValues(time, new long[] { memoryUsed, totalCapacity });\n            chartSupport.updateDetails(new String[] { chartSupport.formatBytes(memoryUsed),\n                                                      chartSupport.formatBytes(totalCapacity),\n                                                      chartSupport.formatDecimal(count)});\n        }\n        \n        private void initModels(int chartCache) {\n            SimpleXYChartDescriptor chartDescriptor =\n                    SimpleXYChartDescriptor.bytes(10 * 1024 * 1024, false, chartCache);\n\n            chartDescriptor.addLineFillItems(MEMORY_USED, TOTAL_CAPACITY);\n            chartDescriptor.setDetailsItems(new String[] { MEMORY_USED, TOTAL_CAPACITY, COUNT });\n\n            chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n        }\n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            add(chartSupport.getChart(), BorderLayout.CENTER);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "plugins/buffermonitor/src/org/graalvm/visualvm/modules/buffermonitor/BufferMonitorViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.buffermonitor;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport java.io.IOException;\nimport javax.management.MBeanServerConnection;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class BufferMonitorViewProvider extends DataSourceViewProvider<Application> {\n\n    static final String DIRECT_BUFFER_NAME = \"java.nio:type=BufferPool,name=direct\";\n    static final String MAPPED_BUFFER_NAME = \"java.nio:type=BufferPool,name=mapped\";\n    \n    protected boolean supportsViewFor(Application application) {\n        JmxModel jmx = JmxModelFactory.getJmxModelFor(application);\n        if (jmx != null && jmx.getConnectionState() == JmxModel.ConnectionState.CONNECTED) {\n            MBeanServerConnection connection = jmx.getMBeanServerConnection();\n            try {\n                if (connection.isRegistered(new ObjectName(DIRECT_BUFFER_NAME))) {\n                    return true;\n                }\n            } catch (MalformedObjectNameException ex) {\n                ex.printStackTrace();\n            } catch (IOException ex) {\n                ex.printStackTrace();\n            }\n        }\n        return false;\n    }\n\n    protected DataSourceView createView(Application application) {\n        return new BufferMonitorView(application);\n    }\n\n    public void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(this, Application.class);\n    }\n}\n"
  },
  {
    "path": "plugins/buffermonitor/src/org/graalvm/visualvm/modules/buffermonitor/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Tools\nOpenIDE-Module-Long-Description=\\\n    A plugin to monitor usage of direct buffers created by <CODE>ByteBuffer.allocateDirect</CODE> and mapped buffers created by <CODE>FileChannel.map</CODE>. \\\n    Note that the buffers monitoring requires the monitored application to run JDK 7 starting from Build 36.\nOpenIDE-Module-Name=VisualVM-BufferMonitor\nOpenIDE-Module-Short-Description=VisualVM Buffer Pools Monitor\n\nBuffer_Pools=Buffer Pools\nLBL_DIRECT=Direct\nLBL_MAPPED=Mapped\nLBL_Memory_Used=Memory Used\nLBL_Total_Capacity=Total Capacity\nLBL_Count=Count\n"
  },
  {
    "path": "plugins/buffermonitor/src/org/graalvm/visualvm/modules/buffermonitor/Installer.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.buffermonitor;\n\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle.\n */\npublic class Installer extends ModuleInstall {\n    @Override\n    public void restored() {\n      new BufferMonitorViewProvider().initialize();\n    }\n}\n"
  },
  {
    "path": "plugins/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"plugins\" basedir=\".\">\n    <description>Builds the module suite plugins.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n\n    <target name=\"-pre-build\">\n        <subant antfile=\"build.xml\" buildpath=\"../visualvm\" target=\"create-platform\" inheritrefs=\"false\" inheritall=\"false\"/>\n    </target>\n    <target name=\"build\" depends=\"-pre-build,suite.build\"/>\n\n    <!-- build source zips for selected modules - useful for populating maven repository only-->\n    <target name=\"build-source-zips\" depends=\"-init\" description=\"Builds source zips for maven repository inclusion.\">\n        <property name=\"netbeans.zipped.sources.dir\" location=\"${suite.build.dir}/source-zips\" />\n\n        <subant target=\"sources-zip\" failonerror=\"true\" inheritall=\"true\">\n            <buildpath path=\"${modules.sorted}\"/>\n        </subant>\n    </target>\n\n    <!-- build javadoc zips for selected modules - useful for populating maven repository only-->\n    <target name=\"build-javadoc-zips\" depends=\"-init\" description=\"Builds javadoc zips for maven repository inclusion.\">\n        <property name=\"netbeans.javadoc.dir\" location=\"${suite.build.dir}/javadoc\" />\n\n        <subant target=\"javadoc-zip\" failonerror=\"true\" inheritall=\"true\">\n            <buildpath path=\"${modules.sorted}\"/>\n        </subant>\n    </target>\n\n</project>\n"
  },
  {
    "path": "plugins/consumerentrypoints/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.netbeans.modules.consumerentrypoints\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.netbeans.modules.consumerentrypoints.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/consumerentrypoints/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: true\nOpenIDE-Module: org.netbeans.modules.consumerentrypoints\nOpenIDE-Module-Localizing-Bundle: org/netbeans/modules/consumerentrypoints/resources/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.0\nOpenIDE-Module-Layer: org/netbeans/modules/consumerentrypoints/resources/layer.xml\n"
  },
  {
    "path": "plugins/consumerentrypoints/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.netbeans.modules.consumerentrypoints-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/consumerentrypoints/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=8d071d57\nbuild.xml.script.CRC32=8d2ba218\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=8d071d57\nnbproject/build-impl.xml.script.CRC32=20b8525a\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "plugins/consumerentrypoints/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\nnbm.module.author=Jirka Rechtacek\n"
  },
  {
    "path": "plugins/consumerentrypoints/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.netbeans.modules.consumerentrypoints</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.consumervisualvm</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/consumerentrypoints/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/consumerentrypoints/src/org/netbeans/modules/consumerentrypoints/resources/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=Consumer VisualVM\n\nOpenIDE-Module-Short-Description=Entry Points to Consumer Visual VM API\norg-netbeans-modules-consumerentrypoints-GlassFishApplicationTypeAction=Enable GlassFish Plugin\n"
  },
  {
    "path": "plugins/consumerentrypoints/src/org/netbeans/modules/consumerentrypoints/resources/glassfish.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    <folder name=\"VisualVM\">\n        <folder name=\"ExplorerPopupSelection\">\n            <file name=\"org-netbeans-modules-consumerentrypoints-GlassFishApplicationTypeAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.netbeans.modules.consumervisualvm.api.ApplicationTypeAction.newAction\"/>\n                <attr name=\"mainClassName\" stringvalue=\"com.sun.enterprise.server.PELaunch\"/>\n                <attr name=\"pluginCodeName\" stringvalue=\"net.java.visualvm.modules.glassfish\"/>\n                <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.netbeans.modules.consumerentrypoints.resources.Bundle\"/>\n                <attr name=\"ActionName\" stringvalue=\"org-netbeans-modules-consumerentrypoints-GlassFishApplicationTypeAction\" />\n                <attr name=\"position\" intvalue=\"2303\"/>\n            </file>\n        </folder>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "plugins/consumerentrypoints/src/org/netbeans/modules/consumerentrypoints/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    <folder name=\"ConsumerVisualVM\">\n        <file name=\"glassfish.instance\">\n            <attr name=\"instanceCreate\" methodvalue=\"org.netbeans.modules.consumervisualvm.api.PluginInfo.create\"/>\n            <attr name=\"codeName\" stringvalue=\"net.java.visualvm.modules.glassfish\"/>\n            <attr name=\"delegateLayer\" urlvalue=\"nbresloc:/org/netbeans/modules/consumerentrypoints/resources/glassfish.xml\"/>\n        </file>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "plugins/consumervisualvm/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.netbeans.modules.consumervisualvm\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.netbeans.modules.consumervisualvm.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/consumervisualvm/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nOpenIDE-Module: org.netbeans.modules.consumervisualvm\nOpenIDE-Module-Localizing-Bundle: org/netbeans/modules/consumervisualvm/resources/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.0\n\n"
  },
  {
    "path": "plugins/consumervisualvm/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.netbeans.modules.consumervisualvm-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/consumervisualvm/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=5e183de4\nbuild.xml.script.CRC32=96930916\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=5e183de4\nnbproject/build-impl.xml.script.CRC32=eddd2eb4\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "plugins/consumervisualvm/nbproject/project.properties",
    "content": "is.autoload=true\njavac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\nnbm.module.author=Jirka Rechtacek\n"
  },
  {
    "path": "plugins/consumervisualvm/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.netbeans.modules.consumervisualvm</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.10.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.autoupdate.services</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.11.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.netbeans.modules.consumervisualvm.api</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/consumervisualvm/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/consumervisualvm/src/META-INF/services/org.openide.filesystems.FileSystem",
    "content": "org.netbeans.modules.consumervisualvm.DecoratedFileSystem\n"
  },
  {
    "path": "plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/DecoratedFileSystem.java",
    "content": "/*\n * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.netbeans.modules.consumervisualvm;\n\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.netbeans.modules.consumervisualvm.PluginInfoAccessor.Internal;\nimport org.netbeans.modules.consumervisualvm.api.PluginInfo;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileSystem;\nimport org.openide.filesystems.MultiFileSystem;\nimport org.openide.filesystems.XMLFileSystem;\nimport org.openide.util.Lookup;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.lookup.Lookups;\n\n/**\n *\n * @author Jirka Rechtacek\n */\npublic class DecoratedFileSystem extends MultiFileSystem implements Runnable {\n\n    final static Logger LOG = Logger.getLogger (DecoratedFileSystem.class.getPackage ().toString ());\n    private static RequestProcessor RP = new RequestProcessor (\"ConsumerVisualVM\"); // NOI18N\n\n    private static Lookup consumerVisualVM;\n\n    public DecoratedFileSystem () {\n        RP.post (this, 2000);\n    //SwingUtilities.invokeLater (this);\n    }\n\n    public void run () {\n        Lookup l = consumerVisualVM ();\n        try {\n            Class.forName (\"org.netbeans.modules.consumervisualvm.api.PluginInfo\");\n        } catch (ClassNotFoundException ex) {\n            // XXX: why ClassNotFoundException sometime?\n            LOG.log (Level.FINE, ex.getLocalizedMessage (), ex);\n            return;\n        }\n        Lookup.Result<PluginInfo> result = l.lookupResult (PluginInfo.class);\n\n        List<XMLFileSystem> delegate = new ArrayList<XMLFileSystem> ();\n        for (PluginInfo pi : result.allInstances ()) {\n            Internal internal = PluginInfoAccessor.DEFAULT.getInternal (pi);\n            if (! internal.isEnabled ()) {\n                delegate.add (internal.getXMLFileSystem ());\n            }\n        }\n        setDelegates (delegate.toArray (new FileSystem[0]));\n    }\n\n    public static DecoratedFileSystem getInstance () {\n        return Lookup.getDefault ().lookup (DecoratedFileSystem.class);\n    }\n\n    public void refresh () {\n        RP.post (this).waitFinished ();\n    }\n\n    public URL getParentFileSystem (FileObject template) {\n        Lookup.Result<PluginInfo> result = consumerVisualVM ().lookupResult (PluginInfo.class);\n\n        String path = template.getPath ();\n        for (PluginInfo pi : result.allInstances ()) {\n            Internal internal = PluginInfoAccessor.DEFAULT.getInternal (pi);\n            XMLFileSystem fs = internal.getXMLFileSystem ();\n            if (fs.findResource (path) != null) {\n                return fs.getXmlUrl ();\n            }\n        }\n        return null;\n    }\n\n    public String getPluginCodeName (FileObject template) {\n        Lookup.Result<PluginInfo> result = consumerVisualVM ().lookupResult (PluginInfo.class);\n\n        String path = template.getPath ();\n        for (PluginInfo pi : result.allInstances ()) {\n            Internal internal = PluginInfoAccessor.DEFAULT.getInternal (pi);\n            XMLFileSystem fs = internal.getXMLFileSystem ();\n            if (fs.findResource (path) != null) {\n                return PluginInfoAccessor.DEFAULT.getCodeName (pi);\n            }\n        }\n        return null;\n    }\n\n    private static synchronized Lookup consumerVisualVM () {\n        if (consumerVisualVM != null) {\n            return consumerVisualVM;\n        }\n        return consumerVisualVM = Lookups.forPath (\"ConsumerVisualVM\"); // NOI18N\n\n    }\n}\n"
  },
  {
    "path": "plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/PluginInfoAccessor.java",
    "content": "/*\n * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.netbeans.modules.consumervisualvm;\n\nimport java.beans.PropertyVetoException;\nimport java.io.IOException;\nimport java.net.URL;\nimport java.util.logging.Level;\nimport org.netbeans.modules.consumervisualvm.api.PluginInfo;\nimport org.openide.filesystems.XMLFileSystem;\nimport org.openide.modules.ModuleInfo;\nimport org.openide.util.Exceptions;\nimport org.openide.util.Lookup;\n\n/** Accessor for non-public methods of FeatureInfo\n *\n * @author Jaroslav Tulach <jtulach@netbeans.org>\n */\npublic abstract class PluginInfoAccessor {\n\n    public static PluginInfoAccessor DEFAULT;\n\n    protected PluginInfoAccessor () {\n        assert DEFAULT == null;\n        DEFAULT = this;\n    }\n\n    public abstract String getCodeName (PluginInfo info);\n\n    public abstract URL getPluginLayer (PluginInfo info);\n\n    public abstract Internal getInternal (PluginInfo info);\n\n    /** Instance associated with each FeatureInfo, which can hold the\n     * internal data needed for it\n     */\n    public static final class Internal {\n\n        private final PluginInfo info;\n        private XMLFileSystem fs;\n\n        public Internal (PluginInfo info) {\n            this.info = info;\n        }\n\n        synchronized XMLFileSystem getXMLFileSystem () {\n            if (fs == null) {\n                URL url = DEFAULT.getPluginLayer (info);\n                fs = new XMLFileSystem ();\n                if (url != null) {\n                    try {\n                        fs.setXmlUrl (url);\n                    } catch (IOException ex) {\n                        DecoratedFileSystem.LOG.log (Level.SEVERE, \"Cannot parse: \" + url, ex);\n                        Exceptions.printStackTrace (ex);\n                    } catch (PropertyVetoException ex) {\n                        DecoratedFileSystem.LOG.log (Level.SEVERE, \"Cannot parse: \" + url, ex);\n                        Exceptions.printStackTrace (ex);\n                    }\n                }\n            }\n            return fs;\n\n        }\n\n        boolean isEnabled () {\n            String cnb = DEFAULT.getCodeName (info);\n            for (ModuleInfo mi : Lookup.getDefault ().lookupAll (ModuleInfo.class)) {\n                if (cnb.equals (mi.getCodeNameBase ())) {\n                    return mi.isEnabled ();\n                }\n            }\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/api/ApplicationTypeAction.java",
    "content": "/*\n * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.netbeans.modules.consumervisualvm.api;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.ui.actions.MultiDataSourceAction;\nimport java.awt.event.ActionEvent;\nimport java.util.Collection;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport org.netbeans.api.autoupdate.UpdateElement;\nimport org.netbeans.modules.consumervisualvm.DecoratedFileSystem;\nimport org.netbeans.modules.consumervisualvm.engine.FindComponentModules;\nimport org.netbeans.modules.consumervisualvm.engine.ModulesActivator;\nimport org.netbeans.modules.consumervisualvm.engine.ModulesInstaller;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jirka Rechtacek\n */\npublic class ApplicationTypeAction extends MultiDataSourceAction<Application> {\n    public static final String MAIN_CLASS_NAME = \"mainClassName\";\n    public static final String PLUGIN_CODE_NAME = \"pluginCodeName\";\n    public static final String ACTION_NAME = \"ActionName\";\n    public static final String LOCALIZING_BUNDLE = \"SystemFileSystem.localizingBundle\";\n\n    private String mainClassName;\n    private String pluginCodeName;\n    private String displayName;\n\n    public static synchronized ApplicationTypeAction newAction (FileObject fo) {\n        return new ApplicationTypeAction (fo);\n    }\n\n    private ApplicationTypeAction (FileObject fo) {\n        super (Application.class);\n        mainClassName = (String) fo.getAttribute (MAIN_CLASS_NAME);\n        pluginCodeName = (String) fo.getAttribute (PLUGIN_CODE_NAME);\n        String bundle = (String) fo.getAttribute (LOCALIZING_BUNDLE);\n        ResourceBundle b = NbBundle.getBundle (bundle);\n        displayName = b.getString ((String) fo.getAttribute (ACTION_NAME));\n        putValue(NAME, displayName);\n    }\n\n    protected void actionPerformed (Set arg0, ActionEvent arg1) {\n        RequestProcessor.getDefault ().post (new Runnable () {\n            public void run () {\n                FindComponentModules findModules = new FindComponentModules (pluginCodeName);\n                findModules.createFindingTask ().waitFinished ();\n                Collection<UpdateElement> toInstall = findModules.getModulesForInstall ();\n                Collection<UpdateElement> toEnable = findModules.getModulesForEnable ();\n                if (toInstall != null && ! toInstall.isEmpty ()) {\n                    ModulesInstaller installer = new ModulesInstaller (toInstall);\n                    installer.getInstallTask ().waitFinished ();\n                    DecoratedFileSystem.getInstance ().refresh ();\n                } else if (toEnable != null && ! toEnable.isEmpty ()) {\n                    ModulesActivator enabler = new ModulesActivator (toEnable);\n                    enabler.getEnableTask ().waitFinished ();\n                    DecoratedFileSystem.getInstance ().refresh ();\n                } else {\n                    DialogDisplayer.getDefault ().notifyLater (new NotifyDescriptor.Message (\n                            NbBundle.getMessage (ApplicationTypeAction.class, \"ApplicationTypeAction_ProblemDescription\",\n                            findModules.getProblemDescription ())));\n                }\n            }\n        }); \n    }\n    \n    protected boolean isEnabled (Set<Application> sources) {\n        if (sources == null || sources.isEmpty ()) {\n            return false;\n        }\n        for (Application app : sources) {\n            Jvm jvm = JvmFactory.getJVMFor (app);\n            if (mainClassName.equals (jvm.getMainClass ())) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/api/Bundle.properties",
    "content": "# Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nApplicationTypeAction_ProblemDescription={0} Check your Update Centers in Tools|Plugins and try it later.\n"
  },
  {
    "path": "plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/api/PluginInfo.java",
    "content": "/*\n * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.netbeans.modules.consumervisualvm.api;\n\nimport java.net.URL;\nimport org.netbeans.modules.consumervisualvm.PluginInfoAccessor;\nimport org.netbeans.modules.consumervisualvm.PluginInfoAccessor.Internal;\nimport org.openide.filesystems.FileObject;\n\n/**\n *\n * @author Jaroslav Tulach <jtulach@netbeans.org>\n */\npublic final class PluginInfo {\n\n    private final String codeName;\n    private final URL pluginLayer;\n    private Internal internal = new Internal (this);\n\n    private PluginInfo (String codeName, URL pluginLayer) {\n        this.codeName = codeName;\n        this.pluginLayer = pluginLayer;\n    }\n\n    private static PluginInfo create (String codeName, URL pluginLayer) {\n        return new PluginInfo (codeName, pluginLayer);\n    }\n\n    static PluginInfo create (FileObject fo) {\n        Object cnb = fo.getAttribute (\"codeName\"); // NOI18N\n        Object layer = fo.getAttribute (\"delegateLayer\"); // NOI18N\n\n        return create ((String) cnb, (URL) layer);\n    }\n\n\n    static {\n        PluginInfoAccessor.DEFAULT = new PluginInfoAccessor () {\n\n            @Override\n            public String getCodeName (PluginInfo info) {\n                return info.codeName;\n            }\n\n            @Override\n            public URL getPluginLayer (PluginInfo info) {\n                return info.pluginLayer;\n            }\n\n            @Override\n            public Internal getInternal (PluginInfo info) {\n                return info.internal;\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/engine/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nInstallerMissingModules_Download=Downloading {0}\nModulesActivator_Enable=Activating {0}\nInstallerMissingModules_Verify=Verifing...\nInstallerMissingModules_Install=Installing...\nInstallerMissingModules_TryAgainButton=&Try Again\nInstallerMissingModules_ErrorPanel_Title=Error\nInstallerMissingModules_ErrorPanel=Installation cannot be completed due to {0} \\n {1}\nInstallerMissingModules_NeedsRestart=Restart IDE to complete instaling asked plugins.\nFindComponentModules_Problem_PluginNotFound=The plugin {0} is not avialable in this moment.\nFindComponentModules_Problem_DependingPluginNotFound=The plugin {0} cannot satisfy all its dependencies {1}. Maybe some required plugins are not avialable in this moment.\n"
  },
  {
    "path": "plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/engine/FindComponentModules.java",
    "content": "/*\n * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.netbeans.modules.consumervisualvm.engine;\n\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.Set;\nimport java.util.StringTokenizer;\nimport java.util.prefs.Preferences;\nimport javax.swing.SwingUtilities;\nimport org.netbeans.api.autoupdate.InstallSupport;\nimport org.netbeans.api.autoupdate.OperationContainer;\nimport org.netbeans.api.autoupdate.OperationSupport;\nimport org.netbeans.api.autoupdate.UpdateElement;\nimport org.netbeans.api.autoupdate.UpdateManager;\nimport org.netbeans.api.autoupdate.UpdateUnit;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jirka Rechtacek\n */\npublic final class FindComponentModules {\n    private Collection<String> codeNames;\n    private String problemDescription;\n\n    public FindComponentModules (String... components) {\n        if (components == null) {\n            codeNames = Collections.emptySet ();\n        } else {\n            codeNames = Arrays.asList (components);\n        }\n    }\n\n    public final String DO_CHECK = \"do-check\";\n\n    private final String ENABLE_LATER = \"enable-later\";\n    private Collection<UpdateElement> forInstall = null;\n    private Collection<UpdateElement> forEnable = null;\n    private RequestProcessor.Task componentModulesFindingTask = null;\n    private RequestProcessor.Task enableLaterTask = null;\n\n    public RequestProcessor.Task getFindingTask () {\n        return componentModulesFindingTask;\n    }\n\n    public RequestProcessor.Task createFindingTask () {\n        assert componentModulesFindingTask == null || componentModulesFindingTask.isFinished () : \"The Finding Task cannot be started nor scheduled.\";\n        componentModulesFindingTask = RequestProcessor.getDefault ().create (doFind);\n        return componentModulesFindingTask;\n    }\n\n    public Collection<UpdateElement> getModulesForInstall () {\n        assert forInstall != null : \"candidates cannot be null if getModulesForInstall() is called.\";\n        return forInstall;\n    }\n    \n    public String getProblemDescription () {\n        return problemDescription;\n    }\n    \n    public void clearModulesForInstall () {\n        forInstall = null;\n        componentModulesFindingTask = null;\n        enableLaterTask = null;\n    }\n    \n    public void writeEnableLater (Collection<UpdateElement> modules) {\n        Preferences pref = FindComponentModules.getPreferences ();\n        if (modules == null) {\n            pref.remove (ENABLE_LATER);\n            return ;\n        }\n        String value = \"\";\n        for (UpdateElement m : modules) {\n            value += value.length () == 0 ? m.getCodeName () : \", \" + m.getCodeName (); // NOI18N\n        }\n        if (value.trim ().length () == 0) {\n            pref.remove (ENABLE_LATER);\n        } else {\n            pref.put (ENABLE_LATER, value);\n        }\n    }\n\n    public Collection<UpdateElement> getModulesForEnable () {\n        assert forEnable != null : \"candidates cannot be null if getModulesForInstall() is called.\";\n        return forEnable;\n    }\n    \n    private Collection<UpdateElement> readEnableLater () {\n        Set<UpdateElement> res = new HashSet<UpdateElement> ();\n        Preferences pref = FindComponentModules.getPreferences ();\n        String value = pref.get (ENABLE_LATER, null);\n        if (value != null && value.trim ().length () > 0) {\n            Enumeration en = new StringTokenizer (value, \",\"); // NOI18N\n            while (en.hasMoreElements ()) {\n                String codeName = ((String) en.nextElement ()).trim ();\n                UpdateElement el = findUpdateElement (codeName, true);\n                if (el != null) {\n                    res.add (el);\n                }\n            }\n        }\n        return res;\n    }\n    \n    public static Collection<UpdateElement> getVisibleUpdateElements (Collection<UpdateElement> elems) {\n        Collection<UpdateElement> res = new HashSet<UpdateElement> ();\n        for (UpdateElement el : new LinkedList<UpdateElement> (elems)) {\n            if (UpdateManager.TYPE.KIT_MODULE.equals (el.getUpdateUnit ().getType ())) {\n                res.add (el);\n            }\n        }\n        return res;\n    }\n\n    public static Preferences getPreferences () {\n        return NbPreferences.forModule (FindComponentModules.class);\n    }\n\n    private Runnable doFind = new Runnable () {\n        public void run() {\n            if (SwingUtilities.isEventDispatchThread ()) {\n                RequestProcessor.getDefault ().post (doFind);\n                return ;\n            }\n            findComponentModules ();\n        }\n    };\n\n    private void findComponentModules () {\n        Collection<UpdateUnit> units = UpdateManager.getDefault ().getUpdateUnits (UpdateManager.TYPE.MODULE);\n        problemDescription = null;\n        \n        // install missing modules\n        Collection<UpdateElement> elementsForInstall = getMissingModules (units);\n        forInstall = getAllForInstall (elementsForInstall);\n        \n        // install disabled modules\n        Collection<UpdateElement> elementsForEnable = getDisabledModules (units);\n        forEnable = getAllForEnable (elementsForEnable);\n        \n        if (problemDescription == null && elementsForInstall.isEmpty () && elementsForEnable.isEmpty ()) {\n            problemDescription = NbBundle.getMessage (FindComponentModules.class, \"FindComponentModules_Problem_PluginNotFound\", codeNames);\n        }\n    }\n    \n    private Collection<UpdateElement> getMissingModules (Collection<UpdateUnit> allUnits) {\n        Set<UpdateElement> res = new HashSet<UpdateElement> ();\n        for (UpdateUnit unit : allUnits) {\n            if (unit.getInstalled () == null && codeNames.contains(unit.getCodeName ())) {\n                res.add (unit.getAvailableUpdates ().get (0));\n            }\n        }\n        return res;\n    }\n    \n    private Collection<UpdateElement> getAllForInstall (Collection<UpdateElement> elements) {\n        Collection<UpdateElement> all = new HashSet<UpdateElement> ();\n        for (UpdateElement el : elements) {\n            OperationContainer<InstallSupport> ocForInstall = OperationContainer.createForInstall ();\n            if (ocForInstall.canBeAdded (el.getUpdateUnit (), el)) {\n                OperationContainer.OperationInfo<InstallSupport> info = ocForInstall.add (el);\n                if (info == null) {\n                    continue;\n                }\n                Set<UpdateElement> reqs = info.getRequiredElements ();\n                ocForInstall.add (reqs);\n                Set<String> breaks = info.getBrokenDependencies ();\n                if (breaks.isEmpty ()) {\n                    all.add (el);\n                    all.addAll (reqs);\n                } else {\n                    problemDescription = NbBundle.getMessage (FindComponentModules.class,\n                            \"FindComponentModules_Problem_DependingPluginNotFound\",\n                            codeNames,\n                            breaks);\n                }\n            }\n        }\n        return all;\n    }\n    \n    private Collection<UpdateElement> getDisabledModules (Collection<UpdateUnit> allUnits) {\n        Set<UpdateElement> res = new HashSet<UpdateElement> ();\n        for (UpdateUnit unit : allUnits) {\n            if (unit.getInstalled () != null && codeNames.contains(unit.getCodeName ())) {\n                if (! unit.getInstalled ().isEnabled ()) {\n                    res.add (unit.getInstalled ());\n                }\n            }\n        }\n        return res;\n    }\n    \n    private Collection<UpdateElement> getAllForEnable (Collection<UpdateElement> elements) {\n        Collection<UpdateElement> all = new HashSet<UpdateElement> ();\n        for (UpdateElement el : elements) {\n            OperationContainer<OperationSupport> ocForEnable = OperationContainer.createForEnable ();\n            if (ocForEnable.canBeAdded (el.getUpdateUnit (), el)) {\n                OperationContainer.OperationInfo<OperationSupport> info = ocForEnable.add (el);\n                if (info == null) {\n                    continue;\n                }\n                Set<UpdateElement> reqs = info.getRequiredElements ();\n                ocForEnable.add (reqs);\n                Set<String> breaks = info.getBrokenDependencies ();\n                if (breaks.isEmpty ()) {\n                    all.add (el);\n                    all.addAll (reqs);\n                } else {\n                    problemDescription = NbBundle.getMessage (FindComponentModules.class,\n                            \"FindComponentModules_Problem_DependingPluginNotFound\",\n                            codeNames,\n                            breaks);\n                }\n            }\n        }\n        return all;\n    }\n    \n    private static UpdateElement findUpdateElement (String codeName, boolean isInstalled) {\n        UpdateElement res = null;\n        for (UpdateUnit u : UpdateManager.getDefault ().getUpdateUnits (UpdateManager.TYPE.MODULE)) {\n            if (codeName.equals (u.getCodeName ())) {\n                if (isInstalled && u.getInstalled () != null) {\n                    res = u.getInstalled ();\n                } else if (! isInstalled && ! u.getAvailableUpdates ().isEmpty ()) {\n                    res = u.getAvailableUpdates ().get (0);\n                }\n                break;\n            }\n        }\n        return res;\n    }\n}\n"
  },
  {
    "path": "plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/engine/FlashingIcon.java",
    "content": "/*\n * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.netbeans.modules.consumervisualvm.engine;\n\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.Point;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JToolTip;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.RequestProcessor.Task;\n\n// Copied from org.netbeans.core.FlashingIcon\n/**\n *\n * A flashing icon to provide visual feedback for the user when something\n * not very important happens in the system.\n * The icon is flashed for a few seconds and then remains visible for a while longer.\n *\n * @author saubrecht\n */\nabstract class FlashingIcon extends JComponent implements MouseListener {\n\n    protected int STOP_FLASHING_DELAY = 10 * 1000;\n    protected int DISAPPEAR_DELAY_MILLIS = STOP_FLASHING_DELAY + 50 * 1000;\n    protected int FLASHING_FREQUENCY = 500;\n\n    private Icon icon;\n\n    private boolean keepRunning = false;\n    private boolean isIconVisible = false;\n    private boolean keepFlashing = true;\n    private long startTime = 0;\n    private Task timerTask;\n\n    /**\n     * Creates a new instance of FlashingIcon\n     *\n     * @param icon The icon that will be flashing (blinking)\n     */\n    protected FlashingIcon( Icon icon ) {\n        this.icon = icon;\n        Dimension d = new Dimension( icon.getIconWidth(), icon.getIconHeight() );\n        setMinimumSize( d );\n        setMaximumSize( d );\n        setPreferredSize( d );\n        setVisible (false);\n\n        addMouseListener( this );\n    }\n\n    /**\n     * Start flashing of the icon. If the icon is already flashing, the timer\n     * is reset.\n     * If the icon is visible but not flashing, it starts flashing again\n     * and the disappear timer is reset.\n     */\n    public void startFlashing() {\n        synchronized( this ) {\n            startTime = System.currentTimeMillis();\n            isIconVisible = !isIconVisible;\n            keepRunning = true;\n            keepFlashing = true;\n            if( null == timerTask ) {\n                timerTask = RequestProcessor.getDefault ().post (new Timer ());\n            } else {\n                timerTask.run ();\n            }\n            this.setVisible (true);\n        }\n        repaint();\n    }\n    \n    /**\n     * Stop the flashing and hide the icon.\n     */\n    public void disappear() {\n        synchronized( this ) {\n            keepRunning = false;\n            isIconVisible = false;\n            keepFlashing = false;\n            if( null != timerTask )\n                timerTask.cancel();\n            timerTask = null;\n            setToolTipText( null );\n            this.setVisible (false);\n        }\n        repaint();\n    }\n    \n    /**\n     * Stop flashing of the icon. The icon remains visible and active (listens \n     * for mouse clicks and displays tooltip) until the disappear timer expires.\n     */\n    public void stopFlashing() {\n        synchronized( this ) {\n            if( keepRunning && !isIconVisible ) {\n                isIconVisible = true;\n                repaint();\n            }\n        }\n        keepFlashing = false;\n    }\n    \n    /**\n     * Switch the current image and repaint\n     */\n    protected void flashIcon() {\n        isIconVisible = !isIconVisible;\n        \n        repaint();\n    }\n\n    @Override\n    public void paint(java.awt.Graphics g) {\n        if( isIconVisible ) {\n            icon.paintIcon( this, g, 0, 0 );\n        }\n    }\n\n    public void mouseReleased(MouseEvent e) {}\n\n    public void mousePressed(MouseEvent e) {\n        stopFlashing();\n    }\n\n    public void mouseExited(MouseEvent e) {\n        stopFlashing();\n    }\n\n    public void mouseEntered(MouseEvent e) {\n        stopFlashing();\n    }\n\n    public void mouseClicked(MouseEvent e) {\n        if( isIconVisible ) {\n            //disappear();\n            onMouseClick();\n        }\n    }\n    \n    /**\n     * Invoked when the user clicks the icon.\n     */\n    protected abstract void onMouseClick();\n\n    /**\n     * Invoked when the disappear timer expired.\n     */\n    protected abstract void timeout();\n\n    @Override\n    public Cursor getCursor() {\n\n        if( isIconVisible ) {\n            return Cursor.getPredefinedCursor( Cursor.HAND_CURSOR );\n        }\n        return Cursor.getDefaultCursor();\n    }\n\n    @Override\n    public Point getToolTipLocation( MouseEvent event ) {\n\n        JToolTip tip = createToolTip();\n        tip.setTipText( getToolTipText() );\n        Dimension d = tip.getPreferredSize();\n        \n        \n        Point retValue = new Point( getWidth()-d.width, -d.height );\n        return retValue;\n    }\n    \n    private class Timer implements Runnable {\n        public void run() {\n            synchronized( FlashingIcon.this ) {\n                long currentTime = System.currentTimeMillis();\n                if( keepFlashing ) {\n                    if( currentTime - startTime < STOP_FLASHING_DELAY ) {\n                        flashIcon();\n                    } else {\n                        stopFlashing();\n                        if (DISAPPEAR_DELAY_MILLIS == -1) {\n                            timerTask = null;\n                        }\n                    }\n                }\n                if( DISAPPEAR_DELAY_MILLIS > 0 && currentTime - startTime >= DISAPPEAR_DELAY_MILLIS ) {\n                    disappear();\n                    timeout();\n                } else {\n                    if( null != timerTask )\n                        timerTask.schedule( FLASHING_FREQUENCY );\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/engine/ModulesActivator.java",
    "content": "/*\n * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.netbeans.modules.consumervisualvm.engine;\n\nimport java.util.Collection;\nimport java.util.LinkedList;\nimport javax.swing.SwingUtilities;\nimport org.netbeans.api.autoupdate.OperationContainer;\nimport org.netbeans.api.autoupdate.OperationException;\nimport org.netbeans.api.autoupdate.OperationSupport;\nimport org.netbeans.api.autoupdate.UpdateElement;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.netbeans.api.progress.ProgressHandleFactory;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jirka Rechtacek\n */\npublic class ModulesActivator {\n\n    private Collection<UpdateElement> modules4enable;\n    private RequestProcessor.Task enableTask = null;\n    private OperationContainer<OperationSupport> enableContainer;\n\n    public ModulesActivator (Collection<UpdateElement> modules) {\n        if (modules == null || modules.isEmpty ()) {\n            throw new IllegalArgumentException (\"Cannot construct ModulesActivator with null or empty Collection \" + modules);\n        }\n        modules4enable = modules;\n    }\n\n    public RequestProcessor.Task getEnableTask () {\n        if (enableTask == null) {\n            enableTask = createEnableTask ();\n        }\n        return enableTask;\n    }\n\n    private RequestProcessor.Task createEnableTask () {\n        assert enableTask == null || enableTask.isFinished () : \"The Enable Task cannot be started nor scheduled.\";\n        enableTask = RequestProcessor.getDefault ().create (doEnable);\n        return enableTask;\n    }\n\n    private Runnable doEnable = new Runnable () {\n        public void run() {\n            enableModules ();\n        }\n\n    };\n\n    private void enableModules () {\n        try {\n            doEnableModules ();\n        } catch (Exception x) {\n            Exceptions.printStackTrace (x);\n        }\n    }\n\n    private void doEnableModules () throws OperationException {\n        assert ! SwingUtilities.isEventDispatchThread () : \"Cannot be called in EQ.\";\n        enableContainer = null;\n        for (UpdateElement module : modules4enable) {\n            if (enableContainer == null) {\n                enableContainer = OperationContainer.createForEnable ();\n            }\n            if (enableContainer.canBeAdded (module.getUpdateUnit (), module)) {\n                enableContainer.add (module);\n            }\n        }\n        if (enableContainer.listAll ().isEmpty ()) {\n            return ;\n        }\n        assert enableContainer.listInvalid ().isEmpty () :\n            \"No invalid Update Elements \" + enableContainer.listInvalid ();\n        if (! enableContainer.listInvalid ().isEmpty ()) {\n            throw new IllegalArgumentException (\"Some are invalid for enable: \" + enableContainer.listInvalid ());\n        }\n        OperationSupport enableSupport = enableContainer.getSupport ();\n        ProgressHandle enableHandle = ProgressHandleFactory.createHandle (\n                getBundle (\"ModulesActivator_Enable\",\n                presentUpdateElements (FindComponentModules.getVisibleUpdateElements (modules4enable))));\n        enableSupport.doOperation (enableHandle);\n    }\n    \n    public static String presentUpdateElements (Collection<UpdateElement> elems) {\n        String res = \"\";\n        for (UpdateElement el : new LinkedList<UpdateElement> (elems)) {\n            res += res.length () == 0 ? el.getDisplayName () : \", \" + el.getDisplayName (); // NOI18N\n        }\n        return res;\n    }\n\n    private static String getBundle (String key, Object... params) {\n        return NbBundle.getMessage (ModulesActivator.class, key, params);\n    }\n    \n}\n"
  },
  {
    "path": "plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/engine/ModulesInstaller.java",
    "content": "/*\n * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.netbeans.modules.consumervisualvm.engine;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.Collection;\nimport java.util.LinkedList;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JTextArea;\nimport javax.swing.SwingUtilities;\nimport org.netbeans.api.autoupdate.InstallSupport;\nimport org.netbeans.api.autoupdate.InstallSupport.Installer;\nimport org.netbeans.api.autoupdate.InstallSupport.Validator;\nimport org.netbeans.api.autoupdate.OperationContainer;\nimport org.netbeans.api.autoupdate.OperationException;\nimport org.netbeans.api.autoupdate.OperationSupport.Restarter;\nimport org.netbeans.api.autoupdate.UpdateElement;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.netbeans.api.progress.ProgressHandleFactory;\nimport org.netbeans.modules.consumervisualvm.engine.RestartNotifier.RestartIcon;\nimport org.openide.DialogDisplayer;\nimport org.openide.LifecycleManager;\nimport org.openide.NotifyDescriptor;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jirka Rechtacek\n */\npublic class ModulesInstaller {\n\n    private Collection<UpdateElement> modules4install;\n    private RequestProcessor.Task installTask = null;\n    private OperationContainer<InstallSupport> installContainer;\n\n    public ModulesInstaller (Collection<UpdateElement> modules) {\n        if (modules == null || modules.isEmpty ()) {\n            throw new IllegalArgumentException (\"Cannot construct InstallerMissingModules with null or empty Collection \" + modules);\n        }\n        modules4install = modules;\n    }\n\n    public RequestProcessor.Task getInstallTask () {\n        if (installTask == null) {\n            installTask = createInstallTask ();\n        }\n        return installTask;\n    }\n\n    private RequestProcessor.Task createInstallTask () {\n        assert installTask == null || installTask.isFinished () : \"The Install Task cannot be started nor scheduled.\";\n        installTask = RequestProcessor.getDefault ().create (doInstall);\n        return installTask;\n    }\n    \n    private Runnable doInstall = new Runnable () {\n        public void run() {\n            installMissingModules ();\n        }\n\n    };\n    \n    private void installMissingModules () {\n        try {\n            doInstallMissingModules ();\n        } catch (Exception x) {\n            JButton tryAgain = new JButton ();\n            tryAgain.addActionListener(new ActionListener () {\n                public void actionPerformed (ActionEvent e) {\n                    if (installContainer != null) {\n                        try {\n                            installContainer.getSupport ().doCancel ();\n                        } catch (Exception ex) {\n                            Logger.getLogger (ModulesInstaller.class.getName ()).\n                                    log (Level.INFO, ex.getLocalizedMessage (), ex);\n                        }\n                    }\n                    RequestProcessor.Task task = getInstallTask ();\n                    if (task != null) {\n                        task.schedule (10);\n                    }\n                }\n            });\n            tryAgain.setEnabled (getInstallTask () != null);\n            Mnemonics.setLocalizedText (tryAgain, getBundle (\"InstallerMissingModules_TryAgainButton\"));\n            NotifyDescriptor nd = new NotifyDescriptor (\n                    getErrorNotifyPanel (x),\n                    getBundle (\"InstallerMissingModules_ErrorPanel_Title\"),\n                    NotifyDescriptor.DEFAULT_OPTION,\n                    NotifyDescriptor.ERROR_MESSAGE,\n                    new Object [] { tryAgain, NotifyDescriptor.OK_OPTION },\n                    NotifyDescriptor.OK_OPTION\n                    );\n            DialogDisplayer.getDefault ().notifyLater (nd);\n        }\n    }\n    \n    private JComponent getErrorNotifyPanel (Exception x) {\n        JTextArea area = new JTextArea ();\n        area.setWrapStyleWord (true);\n        area.setLineWrap (true);\n        area.setEditable (false);\n        area.setRows (15);\n        area.setColumns (40);\n        area.setOpaque (false);\n        area.setText (getBundle (\"InstallerMissingModules_ErrorPanel\", x.getLocalizedMessage (), x));\n        return area;\n    }\n\n    private void doInstallMissingModules () throws OperationException {\n        assert ! SwingUtilities.isEventDispatchThread () : \"Cannot be called in EQ.\";\n        installContainer = null;\n        for (UpdateElement module : modules4install) {\n            if (installContainer == null) {\n                boolean isNewOne = module.getUpdateUnit ().getInstalled () == null;\n                if (isNewOne) {\n                    installContainer = OperationContainer.createForInstall ();\n                } else {\n                    installContainer = OperationContainer.createForUpdate ();\n                }\n            }\n            if (installContainer.canBeAdded (module.getUpdateUnit (), module)) {\n                installContainer.add (module);\n            }\n        }\n        if (installContainer.listAll ().isEmpty ()) {\n            return ;\n        }\n        assert installContainer.listInvalid ().isEmpty () :\n            \"No invalid Update Elements \" + installContainer.listInvalid ();\n        if (! installContainer.listInvalid ().isEmpty ()) {\n            throw new IllegalArgumentException (\"Some are invalid for install: \" + installContainer.listInvalid ());\n        }\n        InstallSupport installSupport = installContainer.getSupport ();\n        ProgressHandle downloadHandle = ProgressHandleFactory.createHandle (\n                getBundle (\"InstallerMissingModules_Download\",\n                presentUpdateElements (FindComponentModules.getVisibleUpdateElements (modules4install))));\n        Validator v = installSupport.doDownload (downloadHandle, false);\n        ProgressHandle verifyHandle = ProgressHandleFactory.createHandle (\n                getBundle (\"InstallerMissingModules_Verify\"));\n        Installer i = installSupport.doValidate (v, verifyHandle);\n        ProgressHandle installHandle = ProgressHandleFactory.createHandle (\n                getBundle (\"InstallerMissingModules_Install\"));\n        Restarter r = installSupport.doInstall (i, installHandle);\n        if (r != null) {\n            installSupport.doRestartLater (r);\n            // XXX FindBrokenModules.writeEnableLater (modules4repair);\n            RestartIcon restartIcon = RestartNotifier.getFlasher (new Runnable () {\n               public void run () {\n                    LifecycleManager.getDefault ().exit ();\n                }\n            });\n            assert restartIcon != null : \"Restart Icon cannot be null.\";\n            restartIcon.setToolTipText (getBundle (\"InstallerMissingModules_NeedsRestart\"));\n            restartIcon.startFlashing ();\n        } else {\n            continueCreating ();\n        }\n        /// XXX FindBrokenModules.clearModulesForRepair ();\n    }\n    \n    public static String presentUpdateElements (Collection<UpdateElement> elems) {\n        String res = \"\";\n        for (UpdateElement el : new LinkedList<UpdateElement> (elems)) {\n            res += res.length () == 0 ? el.getDisplayName () : \", \" + el.getDisplayName (); // NOI18N\n        }\n        return res;\n    }\n\n    private static void continueCreating () {\n        assert ! SwingUtilities.isEventDispatchThread () : \"Cannot be called in EQ.\";\n    }\n    \n    private static String getBundle (String key, Object... params) {\n        return NbBundle.getMessage (ModulesInstaller.class, key, params);\n    }\n    \n}\n"
  },
  {
    "path": "plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/engine/RestartNotifier.java",
    "content": "/*\n * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.netbeans.modules.consumervisualvm.engine;\n\nimport java.awt.Component;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.openide.awt.StatusLineElementProvider;\nimport org.openide.util.Utilities;\n\n/**\n *\n * @author  Jiri Rechtacek\n */\npublic final class RestartNotifier implements StatusLineElementProvider {\n\n    public Component getStatusLineElement () {\n        return getUpdatesVisualizer ();\n    }\n\n    private static RestartIcon flasher = null;\n\n    private static Runnable onMouseClick = null;\n\n    /**\n     * Return an icon that is flashing when a new internal exception occurs.\n     * Clicking the icon opens the regular exception dialog box. The icon\n     * disappears (is hidden) after a short period of time and the exception\n     * list is cleared.\n     *\n     * @return A flashing icon component or null if console logging is switched on.\n     */\n    private static Component getUpdatesVisualizer () {\n        if (null == flasher) {\n            ImageIcon img1 = new ImageIcon (Utilities.loadImage (\"org/netbeans/modules/autoupdate/featureondemand/resources/restart.png\", false)); // NOI18N\n            assert img1 != null : \"Icon cannot be null.\";\n            flasher = new RestartIcon (img1);\n        }\n        return flasher;\n    }\n\n    public static RestartIcon getFlasher (Runnable whatRunOnMouseClick) {\n        onMouseClick = whatRunOnMouseClick;\n        return flasher;\n    }\n\n    public static class RestartIcon extends FlashingIcon {\n        public RestartIcon (Icon img1) {\n            super (img1);\n            DISAPPEAR_DELAY_MILLIS = -1;\n            // don't flashing by http://ui.netbeans.org/docs/ui/AutoUpdate/AutoUpdate.html\n            STOP_FLASHING_DELAY = 0;\n        }\n\n        /**\n         * User clicked the flashing icon, display the exception window.\n         */\n        protected void onMouseClick () {\n            if (onMouseClick != null) {\n                onMouseClick.run ();\n            }\n        }\n\n        /**\n         * The flashing icon disappeared (timed-out), clear the current\n         * exception list.\n         */\n        protected void timeout () {}\n    }\n    \n}\n"
  },
  {
    "path": "plugins/consumervisualvm/src/org/netbeans/modules/consumervisualvm/resources/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=Consumer VisualVM API\nOpenIDE-Module-Short-Description=Consumer Visual VM API\n"
  },
  {
    "path": "plugins/extapptypes/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.customtype\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.customtype.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/extapptypes/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.customtype\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/customtype/Installer.class\nOpenIDE-Module-Layer: org/graalvm/visualvm/modules/customtype/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/customtype/Bundle.properties\nOpenIDE-Module-Provides: org.graalvm.visualvm.modules.customtype\nOpenIDE-Module-Specification-Version: 1.0\n\n"
  },
  {
    "path": "plugins/extapptypes/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.customtype-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/extapptypes/nbproject/project.properties",
    "content": "is.autoload=true\njavac.source=1.6\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "plugins/extapptypes/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.customtype</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.api.caching</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>0.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.2</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.options.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/extapptypes/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/ApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.customtype;\n\nimport org.graalvm.visualvm.modules.customtype.icons.IconCache;\nimport org.graalvm.visualvm.modules.customtype.icons.ImageUtils;\nimport java.awt.Image;\nimport java.awt.image.BufferedImage;\nimport java.io.IOException;\nimport java.net.URL;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.imageio.ImageIO;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ApplicationType extends org.graalvm.visualvm.application.type.ApplicationType {\n    public static final String PROPERTY_INFO_URL = \"info_url\"; // NOI18N\n    public static final String PROPERTY_MAIN_CLASS = \"main-class\"; // NOI18N\n\n    private String defName;\n    private String mainClass;\n    private String name;\n    private String version;\n    private String description;\n    private URL iconUrl;\n    private URL infoUrl;\n\n    private BufferedImage icon;\n    private static BufferedImage DEFAULT_ICON;\n\n    static {\n        try {\n            DEFAULT_ICON = ImageIO.read(new URL(\"nbres:/org/graalvm/visualvm/application/resources/application.png\")); // NOI18N\n        } catch (Exception e) {\n            Logger.getLogger(ApplicationType.class.getName()).log(Level.SEVERE, \"Can not initialize default icon\", e);\n            DEFAULT_ICON = null;\n            throw new RuntimeException(e);\n            // something is seriously broken - can't continue -> shut the whole application down\n        }\n    }\n\n    ApplicationType(String mainClass, String name, String version, String description, URL iconUrl, URL infoUrl) {\n        this.mainClass = mainClass;\n        this.name = name;\n        this.version = version;\n        this.description = description;\n        this.iconUrl = iconUrl;\n        this.infoUrl = infoUrl;\n    }\n\n    void loadIcon() {\n        if (iconUrl == null) {\n            setIcon(DEFAULT_ICON);\n        } else {\n            try {\n                setIcon(ImageUtils.resizeImage(ImageIO.read(iconUrl), 16, 16));\n                return;\n            } catch (IOException e) {}\n        }\n\n        if (iconUrl == null && infoUrl != null) {\n            RequestProcessor.getDefault().post(new Runnable() {\n\n                @Override\n                public void run() {\n                    BufferedImage img = IconCache.getDefault().retrieveObject(infoUrl);\n                    if (img != null) {\n                        setIcon(img);\n                    }\n                }\n            });\n        }\n    }\n\n    @Override\n    public String getDescription() {\n        return description;\n    }\n\n    public void setDescription(String description) {\n        String oldDescription = this.description;\n        this.description = description;\n        firePropertyChange(PROPERTY_DESCRIPTION, oldDescription, description);\n    }\n\n    public URL getIconURL() {\n        return iconUrl;\n    }\n\n    public void setIconURL(URL iconUrl) {\n        this.iconUrl = iconUrl;\n        loadIcon();\n    }\n\n    public URL getInfoURL() {\n        return infoUrl;\n    }\n\n    public void setInfoUrl(URL infoUrl) {\n        URL oldUrl = this.infoUrl;\n        this.infoUrl = infoUrl;\n        firePropertyChange(PROPERTY_INFO_URL, oldUrl, infoUrl);\n        loadIcon();\n    }\n\n    public String getMainClass() {\n        return mainClass;\n    }\n\n    public void setMainClass(String mainClass) {\n        String oldClass = this.mainClass;\n        this.mainClass = mainClass;\n        firePropertyChange(PROPERTY_MAIN_CLASS, oldClass, mainClass);\n    }\n\n    @Override\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        String oldName = this.name;\n        this.name = name;\n        firePropertyChange(PROPERTY_NAME, oldName, name);\n    }\n\n    @Override\n    public String getVersion() {\n        return version;\n    }\n\n    public void setVersion(String version) {\n        String oldVersion = this.version;\n        this.version = version;\n        firePropertyChange(PROPERTY_VERSION, oldVersion, version);\n    }\n\n    @Override\n    public Image getIcon() {\n        if (icon == null) {\n            return DEFAULT_ICON;\n        }\n\n        return ImageUtils.resizeImage(icon, 16, 16);\n    }\n\n    private void setIcon(BufferedImage icon) {\n        BufferedImage oldIcon = this.icon;\n        this.icon = icon != null ? icon : DEFAULT_ICON;\n        firePropertyChange(PROPERTY_ICON, oldIcon, icon);\n    }\n\n    String getDefName() {\n        return defName;\n    }\n\n    void setDefName(String defName) {\n        this.defName = defName;\n    }\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/ApplicationTypeFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.customtype;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ApplicationTypeFactory extends org.graalvm.visualvm.application.type.MainClassApplicationTypeFactory {\n    final private Map<String, ApplicationType> typeMap = new HashMap<String, ApplicationType>();\n\n    final private static class Singleton {\n        final private static ApplicationTypeFactory INSTANCE = new ApplicationTypeFactory();\n    }\n\n    final public static ApplicationTypeFactory getDefault() {\n        return Singleton.INSTANCE;\n    }\n\n    private ApplicationTypeManager manager;\n\n    private ApplicationTypeFactory() {\n        manager = ApplicationTypeManager.getDefault();\n    }\n\n    final public static void initialize() {\n        org.graalvm.visualvm.application.type.ApplicationTypeFactory.getDefault().registerProvider(getDefault());\n    }\n    \n    final public static void shutdown() {\n        org.graalvm.visualvm.application.type.ApplicationTypeFactory.getDefault().unregisterProvider(getDefault());\n    }\n\n    @Override\n    public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) {\n        synchronized(typeMap) {\n            ApplicationType type = typeMap.get(mainClass);\n            if (type == null) {\n                type = findType(mainClass);\n                if (type != null) {\n                    typeMap.put(mainClass, type);\n                }\n            }\n            return type;\n        }\n    }\n\n    private ApplicationType findType(String mainClass) {\n        ApplicationType type = manager.findType(mainClass);\n\n        if (type != null) {\n            type.loadIcon();\n            synchronized(typeMap) {\n                typeMap.put(mainClass, type);\n            }\n        }\n\n        return type;\n    }\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/ApplicationTypeManager.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.modules.customtype;\n\n\nimport org.graalvm.visualvm.api.caching.Cache;\nimport org.graalvm.visualvm.api.caching.CacheFactory;\nimport org.graalvm.visualvm.api.caching.Entry;\nimport org.graalvm.visualvm.api.caching.EntryFactory;\nimport org.graalvm.visualvm.modules.customtype.icons.ImageUtils;\nimport java.awt.image.BufferedImage;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Enumeration;\nimport java.util.HashSet;\nimport java.util.Random;\nimport java.util.Set;\nimport javax.imageio.ImageIO;\nimport org.openide.filesystems.FileLock;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileSystem.AtomicAction;\nimport org.openide.filesystems.Repository;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ApplicationTypeManager {\n\n    final private Random random = new Random(System.currentTimeMillis());\n    final private FileObject defRepository;\n    final private EntryFactory<String, ApplicationType> appTypeResolver = new EntryFactory<String, ApplicationType>() {\n\n        @Override\n        public Entry<ApplicationType> createEntry(String key) {\n            Enumeration<? extends FileObject> defs = defRepository.getFolders(false);\n            while (defs.hasMoreElements()) {\n                FileObject def = defs.nextElement();\n                if (def.getExt().equals(\"def\")) { // NOI18N\n                    String defMainClass = (String) def.getAttribute(\"mainClass\"); // NOI18N\n                    if (defMainClass != null && defMainClass.equals(key)) {\n                        String name = (String) def.getAttribute(\"displayName\"); // NOI18N\n                        String description = (String) def.getAttribute(\"description\"); // NOI18N\n                        description = description.replaceAll(\"\\\\s\\\\s+\", \" \");\n                        String iconPath = (String) def.getAttribute(\"icon\"); // NOI18N\n                        String urlPath = (String) def.getAttribute(\"url\"); // NOI18N\n\n                        URL infoUrl = null;\n                        URL iconUrl = null;\n                        try {\n                            if (urlPath != null) {\n                                infoUrl = new URL(urlPath);\n                            }\n                            if (iconPath != null) {\n                                iconUrl = new URL(iconPath);\n                            }\n                        } catch (MalformedURLException e) {\n                            e.printStackTrace();\n                        }\n                        ApplicationType at = new ApplicationType(key, name, \"\", description, iconUrl, infoUrl);\n                        at.setDefName(def.getNameExt());\n                        return new Entry<ApplicationType>(at);\n                    }\n                }\n            }\n            return null;\n        }\n    };\n    final private Cache<String, ApplicationType> appTypeCache = CacheFactory.getInstance().softMapCache(appTypeResolver);\n\n    final private static class Singleton {\n\n        final private static ApplicationTypeManager INSTANCE = new ApplicationTypeManager();\n    }\n\n    final public static ApplicationTypeManager getDefault() {\n        return Singleton.INSTANCE;\n    }\n\n    private ApplicationTypeManager() {\n        defRepository = Repository.getDefault().getDefaultFileSystem().findResource(\"VisualVM/ApplicationTypes\"); // NOI18N\n    }\n\n    public ApplicationType newType(String mainClass) {\n        return new ApplicationType(mainClass, null, null, null, null, null);\n    }\n\n    public ApplicationType findType(String mainClass) {\n        return appTypeCache.retrieveObject(mainClass);\n    }\n\n    public boolean removeType(ApplicationType type) {\n        FileObject def = defRepository.getFileObject(type.getDefName());\n        if (def != null) {\n            try {\n                def.delete();\n                appTypeCache.invalidateObject(type.getMainClass());\n                return true;\n            } catch (IOException e) {\n            }\n        }\n        return false;\n    }\n\n    public Set<ApplicationType> listTypes() {\n        Set<ApplicationType> types = new HashSet<ApplicationType>();\n        Collection<String> mainClasses = new ArrayList<String>();\n\n        Enumeration<? extends FileObject> defs = defRepository.getFolders(false);\n        while (defs.hasMoreElements()) {\n            FileObject def = defs.nextElement();\n            if (def.getExt().equals(\"def\")) { // NOI18N\n                String mainClass = (String) def.getAttribute(\"mainClass\"); // NOI18N\n                mainClasses.add(mainClass);\n            }\n        }\n        for(String mainClass : mainClasses) {\n            ApplicationType cachedType = appTypeCache.retrieveObject(mainClass);\n            if (cachedType != null) {\n                types.add(cachedType);\n            }\n        }\n        return types;\n    }\n\n    public void storeType(final ApplicationType type) throws IOException {\n        Repository.getDefault().getDefaultFileSystem().runAtomicAction(new AtomicAction() {\n\n            @Override\n            public void run() throws IOException {\n                String defName = type.getDefName();\n                if (defName == null) {\n                    do {\n                        defName = calculateDefName(type);\n                    } while (defRepository.getFileObject(defName) != null);\n                    type.setDefName(defName);\n                }\n\n                FileObject defFolder = defRepository.getFileObject(defName);\n                if (defFolder == null) {\n                    defFolder = defRepository.createFolder(defName);\n                }\n                defFolder.setAttribute(\"displayName\", type.getName());\n                defFolder.setAttribute(\"mainClass\", type.getMainClass());\n                if (type.getInfoURL() != null) {\n                    defFolder.setAttribute(\"url\", type.getInfoURL().toString());\n                } else {\n                    defFolder.setAttribute(\"url\", null);\n                }\n                if (type.getIconURL() != null) {\n                    FileObject iconFile = defFolder.getFileObject(\"icon.png\");\n                    if (iconFile == null) {\n                        iconFile = defFolder.createData(\"icon.png\");\n                    }\n                    BufferedImage bIcon = ImageIO.read(type.getIconURL());\n\n                    FileLock lock = iconFile.lock();\n                    OutputStream os = iconFile.getOutputStream(lock);\n                    try {\n                        ImageIO.write(ImageUtils.resizeImage(bIcon, 16, 16), \"png\", os);\n                        defFolder.setAttribute(\"icon\", iconFile.getURL().toString());\n                        iconFile = null;\n                    } finally {\n                        os.close();\n                        lock.releaseLock();\n                    }\n                } else {\n                    defFolder.setAttribute(\"icon\", null);\n                }\n            }\n        });\n    }\n\n    private String calculateDefName(ApplicationType type) {\n        String rndString = String.valueOf(random.nextInt());\n        return type.getMainClass().replace('.', '_') + \"#\" + rndString + \".def\";\n    }\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Long-Description=\\\n    A declarative approach to defining application types. \\n\\n\\\n    Based on the application main class it is possible to define its display name, display name, description and URL containing more information. \\\n    The plugin will also try to grab a favicon from the supplied URL to use the most up-to-date application icon.\nOpenIDE-Module-Name=Custom Application Type\nOpenIDE-Module-Short-Description=Allows easy, configuration based, creation of application type\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.modules.customtype;\n\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\npublic class Installer extends ModuleInstall {\n\n    @Override\n    public void restored() {\n        ApplicationTypeFactory.initialize();\n    }\n\n    @Override\n    public void uninstalled() {\n        ApplicationTypeFactory.shutdown();\n    }\n\n\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/actions/EditApplicationTypeAction.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.customtype.actions;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.modules.customtype.ApplicationType;\nimport org.graalvm.visualvm.modules.customtype.ApplicationTypeManager;\nimport org.graalvm.visualvm.modules.customtype.ui.ApplicationTypeForm;\nimport org.graalvm.visualvm.core.ui.actions.DataSourceAction;\nimport java.awt.Dialog;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.IOException;\nimport java.util.Set;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class EditApplicationTypeAction extends DataSourceAction<Application> {\n    private Application selectedApp = null;\n\n    final private static class Singleton {\n\n        final private static EditApplicationTypeAction INSTANCE = new EditApplicationTypeAction();\n    }\n\n    final public static EditApplicationTypeAction getDefault() {\n        return Singleton.INSTANCE;\n    }\n\n    private EditApplicationTypeAction() {\n        super(Application.class);\n        putValue(NAME, \"Edit Application Type...\");\n    }\n\n    @Override\n    protected void updateState(Set<Application> selectedApps) {\n        if (selectedApps.size() == 1) {\n            selectedApp = selectedApps.iterator().next();\n            org.graalvm.visualvm.application.type.ApplicationType at = ApplicationTypeFactory.getApplicationTypeFor(selectedApp);\n            if (at instanceof ApplicationType) {\n                if (!JvmFactory.getJVMFor(selectedApp).getMainClass().isEmpty()) {\n                    setEnabled(true);\n                    return;\n                }\n            }\n            selectedApp = null;\n            setEnabled(false);\n        } else {\n            selectedApp = null;\n            setEnabled(false);\n        }\n    }\n\n    @Override\n    public void actionPerformed(ActionEvent e) {\n        final ApplicationType at = (ApplicationType)ApplicationTypeFactory.getApplicationTypeFor(selectedApp);\n        final ApplicationTypeForm form = new ApplicationTypeForm(at);\n\n        final DialogDescriptor[] dd = new DialogDescriptor[1];\n\n        dd[0] = new DialogDescriptor(form, \"Application Type Details\", true, new Object[]{form.getValidationSupport().getOkButton(), DialogDescriptor.CANCEL_OPTION}, form.getValidationSupport().getOkButton(), DialogDescriptor.DEFAULT_ALIGN, null, new ActionListener() {\n\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                if (e.getSource() == form.getValidationSupport().getOkButton() && form.storeData()) {\n                    dd[0].setClosingOptions(new Object[] {form.getValidationSupport().getOkButton()});\n                }\n            }\n        });\n\n        dd[0].setClosingOptions(new Object[] {DialogDescriptor.CANCEL_OPTION});\n\n        Dialog dlg = DialogDisplayer.getDefault().createDialog(dd[0]);\n        dlg.setVisible(true);\n        if (dd[0].getValue() == form.getValidationSupport().getOkButton()) {\n            try {\n                ApplicationTypeManager.getDefault().storeType(at);\n            } catch (IOException ex) {\n                ex.printStackTrace();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/actions/NewApplicationTypeAction.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.customtype.actions;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.application.type.DefaultApplicationType;\nimport org.graalvm.visualvm.modules.customtype.ApplicationTypeManager;\nimport org.graalvm.visualvm.modules.customtype.ui.ApplicationTypeForm;\nimport org.graalvm.visualvm.core.ui.actions.DataSourceAction;\nimport org.graalvm.visualvm.modules.customtype.ApplicationType;\nimport java.awt.Dialog;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.IOException;\nimport java.util.Set;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class NewApplicationTypeAction extends DataSourceAction<Application> {\n    private Application selectedApp = null;\n\n    final private static class Singleton {\n\n        final private static NewApplicationTypeAction INSTANCE = new NewApplicationTypeAction();\n    }\n\n    final public static NewApplicationTypeAction getDefault() {\n        return Singleton.INSTANCE;\n    }\n\n    private NewApplicationTypeAction() {\n        super(Application.class);\n        putValue(NAME, \"Create New Application Type...\");\n    }\n\n    @Override\n    protected void updateState(Set<Application> selectedApps) {\n        if (selectedApps.size() == 1) {\n            selectedApp = selectedApps.iterator().next();\n            org.graalvm.visualvm.application.type.ApplicationType at = ApplicationTypeFactory.getApplicationTypeFor(selectedApp);\n            if (at instanceof DefaultApplicationType) {\n                if (!JvmFactory.getJVMFor(selectedApp).getMainClass().isEmpty()) {\n                    setEnabled(true);\n                    return;\n                }\n            }\n            selectedApp = null;\n            setEnabled(false);\n        } else {\n            selectedApp = null;\n            setEnabled(false);\n        }\n    }\n\n    @Override\n    public void actionPerformed(ActionEvent e) {\n        Jvm jvm = JvmFactory.getJVMFor(selectedApp);\n        if (jvm != null) {\n            ApplicationType eat = ApplicationTypeManager.getDefault().newType(jvm.getMainClass());\n            final ApplicationTypeForm form = new ApplicationTypeForm(eat);\n\n            final DialogDescriptor[] dd = new DialogDescriptor[1];\n\n            dd[0] = new DialogDescriptor(form, \"New Application Type Details\",  true, new Object[]{form.getValidationSupport().getOkButton(), DialogDescriptor.CANCEL_OPTION}, form.getValidationSupport().getOkButton(), DialogDescriptor.DEFAULT_ALIGN, null, new ActionListener() {\n\n                @Override\n                public void actionPerformed(ActionEvent e) {\n                    if (e.getSource().equals(form.getValidationSupport().getOkButton()) && form.storeData()) {\n                        dd[0].setClosingOptions(new Object[] {form.getValidationSupport().getOkButton()});\n                    }\n                }\n            });\n\n            dd[0].setClosingOptions(new Object[] {DialogDescriptor.CANCEL_OPTION});\n\n            Dialog dlg = DialogDisplayer.getDefault().createDialog(dd[0]);\n            dlg.setVisible(true);\n            if (dd[0].getValue() == form.getValidationSupport().getOkButton()) {\n                try {\n                    ApplicationTypeManager.getDefault().storeType(eat);\n                } catch (IOException ex) {\n                    ex.printStackTrace();\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/actions/ValidationSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.customtype.actions;\n\nimport javax.swing.JButton;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\nabstract public class ValidationSupport {\n    final private JButton OK_BUTTON = new JButton(\"OK\");\n\n    public ValidationSupport() {\n    }\n\n    final public JButton getOkButton() {\n        return OK_BUTTON;\n    }\n\n    final public void updateValidity() {\n        OK_BUTTON.setEnabled(isValid());\n    }\n\n    abstract public boolean isValid();\n\n    final public static ValidationSupport DEFAULT = new ValidationSupport() {\n\n        @Override\n        public boolean isValid() {\n            return true;\n        }\n    };\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/icons/FileImagePersistor.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.modules.customtype.icons;\n\nimport org.graalvm.visualvm.api.caching.Entry;\nimport org.graalvm.visualvm.api.caching.Persistor;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport java.awt.image.BufferedImage;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.URL;\nimport javax.imageio.ImageIO;\nimport org.openide.filesystems.FileLock;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class FileImagePersistor implements Persistor<URL, BufferedImage> {\n    final private static String APPTYPE_ICON_CACHE = \"apptype-icon-cache\"; // NOI18N\n    final private FileObject storage;\n\n    public FileImagePersistor() throws InstantiationException {\n        try {\n            FileObject globalStorage = FileUtil.toFileObject(Storage.getPersistentStorageDirectory());\n            FileObject aStorage = globalStorage.getFileObject(APPTYPE_ICON_CACHE);\n\n            if (aStorage == null) {\n                storage = globalStorage.createFolder(APPTYPE_ICON_CACHE);\n            } else {\n                storage = aStorage;\n            }\n        } catch (IOException ex) {\n            throw new InstantiationException(ex.getLocalizedMessage());\n        }\n    }\n\n    @Override\n    public Entry<BufferedImage> retrieve(URL key) {\n        InputStream is = null;\n        try {\n            FileObject imageFile = storage.getFileObject(entryFileName(key));\n            if (imageFile != null) {\n                is = imageFile.getInputStream();\n                return new Entry<BufferedImage>(ImageIO.read(is), imageFile.lastModified().getTime());\n            } else {\n                return null;\n            }\n        } catch (IOException ex) {\n            ex.printStackTrace();\n            return null;\n        } finally {\n            if (is != null) {\n                try {\n                    is.close();\n                } catch (Exception e){}\n            }\n        }\n    }\n\n    @Override\n    public void store(URL key, Entry<BufferedImage> value) {\n        if (value.getContent() == null) return;\n        FileLock outputLock = null;\n        try {\n            String fileName = entryFileName(key);\n            FileObject imageFile = storage.getFileObject(fileName);\n            if (imageFile == null) {\n                imageFile = storage.createData(fileName);\n            }\n            if (imageFile != null) {\n                outputLock = imageFile.lock();\n                ImageIO.write(value.getContent(), \"png\", imageFile.getOutputStream(outputLock));\n            }\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        } finally {\n            if (outputLock != null) {\n                outputLock.releaseLock();\n            }\n        }\n    }\n\n    private static String entryFileName(URL url) {\n        return url.toString().replace(':', '#').replace('/', '_');\n    }\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/icons/IconCache.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.customtype.icons;\n\nimport org.graalvm.visualvm.api.caching.Cache;\nimport org.graalvm.visualvm.api.caching.CacheFactory;\nimport org.graalvm.visualvm.api.caching.Entry;\nimport org.graalvm.visualvm.api.caching.EntryFactory;\nimport org.graalvm.visualvm.api.caching.Persistor;\nimport java.awt.image.BufferedImage;\nimport java.net.URL;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class IconCache extends Cache<URL, BufferedImage> {\n    final private IconResolver resolver = new IconResolver();\n    final private Cache<URL, BufferedImage> delegate;\n\n    final private static class Singleton {\n\n        final private static IconCache INSTANCE = new IconCache();\n    }\n\n    final public static IconCache getDefault() {\n        return Singleton.INSTANCE;\n    }\n\n    private IconCache() {\n        Persistor<URL, BufferedImage> persistor;\n        try {\n            persistor = new FileImagePersistor();\n            \n        } catch (InstantiationException e) {\n            persistor = Persistor.DEFAULT;\n        }\n        delegate = CacheFactory.getInstance().softMapCache(new EntryFactory<URL, BufferedImage>() {\n            @Override\n            public Entry<BufferedImage> createEntry(URL key) {\n                BufferedImage img = resolver.resolveIcon(key);\n                if (img != null) {\n                    img = ImageUtils.resizeImage(img, 16, 16);\n                }\n                return new Entry<BufferedImage>(resolver.resolveIcon(key));\n            }\n        }, persistor);\n\n    }\n\n    @Override\n    public long getTTL() {\n        return delegate.getTTL();\n    }\n\n    @Override\n    public BufferedImage invalidateObject(URL key) {\n        return delegate.invalidateObject(key);\n    }\n\n    @Override\n    public BufferedImage retrieveObject(URL key) {\n        return delegate.retrieveObject(key);\n    }\n\n    @Override\n    public void setTTL(long ttl) {\n        delegate.setTTL(ttl);\n    }\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/icons/IconResolver.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.modules.customtype.icons;\n\nimport java.awt.image.BufferedImage;\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.net.URL;\nimport java.util.logging.Logger;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport javax.imageio.ImageIO;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\nclass IconResolver {\n\n    final private static Pattern favicoLinkPattern = Pattern.compile(\"\\\\<link(.+?)/?\\\\>\", Pattern.MULTILINE | Pattern.DOTALL);\n    final private static Pattern favicoHrefPattern = Pattern.compile(\"href=[\\\\\\\"'](.+?)[\\\\\\\"']\", Pattern.MULTILINE | Pattern.DOTALL);\n    final private static String[] extensions = new String[]{\"png\", \"gif\", \"jpg\", \"jpeg\"};\n\n    BufferedImage resolveIcon(URL url) {\n        BufferedImage resolvedImage = null;\n\n        for (String extension : extensions) {\n            String favIcon = \"favicon.\" + extension;\n            try {\n                URL favicoUrl = new URL(url.toString() + \"/\" + favIcon);\n                resolvedImage = ImageIO.read(favicoUrl);\n                if (resolvedImage != null && resolvedImage.getWidth() > -1) {\n                    break;\n                }\n            } catch (IOException ex) {\n                // ignore\n                }\n        }\n\n        if (resolvedImage == null) {\n            resolvedImage = resolveFromLink(url);\n        }\n\n        return resolvedImage != null ? (resolvedImage.getWidth() > -1 ? resolvedImage : null) : null;\n    }\n\n    private synchronized BufferedImage resolveFromLink(URL url) {\n        try {\n            String index = readIndex(url.openStream());\n            Matcher linkMatcher = favicoLinkPattern.matcher(index);\n            String favicoPath = null;\n            while (linkMatcher.find()) {\n                String content = linkMatcher.group(1);\n                if (content.contains(\"shortcut\") || content.contains(\"icon\")) {\n                    Matcher hrefMatcher = favicoHrefPattern.matcher(content);\n                    if (hrefMatcher.find()) {\n                        favicoPath = hrefMatcher.group(1);\n                        if (isSupported(favicoPath)) {\n                            break;\n                        } else {\n                            favicoPath = null;\n                        }\n                    }\n                }\n            }\n            if (favicoPath != null) {\n                URL favicoUrl = null;\n                if (favicoPath.startsWith(\"/\")) { // absolute path\n                    favicoUrl = new URL(url.getProtocol(), url.getHost(), favicoPath);\n                } else {\n                    favicoUrl = new URL(url.getProtocol(), url.getHost(), url.getFile() + \"/\" + favicoPath);\n                }\n                Logger.getLogger(IconResolver.class.getName()).fine(\"Resolving image: \" + favicoUrl.toString());\n\n                return ImageIO.read(favicoUrl);\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        return null;\n    }\n\n    private String readIndex(InputStream is) throws IOException {\n        BufferedReader br = new BufferedReader(new InputStreamReader(is));\n        StringBuilder sb = new StringBuilder();\n        String line = null;\n        try {\n            do {\n                line = br.readLine();\n                if (line != null) {\n                    sb.append(line).append('\\n');\n                }\n            } while (line != null);\n        } finally {\n            try {\n                is.close();\n            } catch (IOException e) {\n            }\n        }\n        return sb.toString();\n    }\n\n    private boolean isSupported(String imagePath) {\n        int jsIndex = imagePath.indexOf(\";\");\n        if (jsIndex > -1) {\n            imagePath = imagePath.substring(0, jsIndex);\n        }\n        for (String ext : extensions) {\n            if (imagePath.endsWith(ext)) {\n                return true;\n            }\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/icons/ImageUtils.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.customtype.icons;\n\nimport java.awt.AlphaComposite;\nimport java.awt.Graphics2D;\nimport java.awt.GraphicsConfiguration;\nimport java.awt.geom.AffineTransform;\nimport java.awt.image.BufferedImage;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ImageUtils {\n    final public static BufferedImage resizeImage(BufferedImage img, int width, int height) {\n        Graphics2D gin = img.createGraphics();\n        GraphicsConfiguration gc = gin.getDeviceConfiguration();\n        gin.dispose();\n\n        BufferedImage dst = gc.createCompatibleImage(width, height, BufferedImage.BITMASK);\n        Graphics2D gr = dst.createGraphics();\n        gr.setComposite(AlphaComposite.Src);\n\n        AffineTransform at = AffineTransform.getScaleInstance((double)width/img.getWidth(), (double)height/img.getHeight());\n        gr.drawRenderedImage(img,at);\n        return dst;\n    }\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    <folder name=\"VisualVM\">\n         <folder name=\"ExplorerPopupSelection\">\n            <file name=\"org-graalvm-visualvm-modules-customtype-actions-NewApplicationTypeAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.modules.customtype.actions.NewApplicationTypeAction.getDefault\"/>\n                <attr name=\"position\" intvalue=\"3000\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-modules-customtype-actions-EditApplicationTypeAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.modules.customtype.actions.EditApplicationTypeAction.getDefault\"/>\n                <attr name=\"position\" intvalue=\"3100\"/>\n            </file>\n        </folder>\n        <folder name=\"ApplicationTypes\">\n            <!--\n                Here come the registration of the custom application types\n                They must be of the following form\n\n                <folder name=\"Application.def\"> // *.def subfolders are treated as apptype definitions\n                    <attr name=\"displayName\" stringvalue=\"<Custom Application Name>\"/>\n                    <attr name=\"icon\" stringvalue=\"<URL to Icon; can use special NB protocols like nbres:/ or nbfs:/ >\"/>\n                    <attr name=\"mainClass\" stringvalue=\"<main class identifier>\"/>\n                    <attr name=\"url\" stringvalue=\"URL for more information\"/>\n                    <attr name=\"description\" stringvalue=\"description\"/>\n                </folder>\n            -->\n        </folder>\n    </folder>\n    <folder name=\"OptionsDialog\">\n        <file name=\"org-graalvm-visualvm-modules-customtype-options-ApplicationTypeOptionsCategory.instance\">\n            <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.modules.customtype.options.ApplicationTypeOptionsCategory.instance\"/>\n            <attr name=\"position\" intvalue=\"5000\"/>\n        </file>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/options/ApplicationTypeOptionsCategory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.customtype.options;\n\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.netbeans.spi.options.OptionsCategory;\nimport org.netbeans.spi.options.OptionsPanelController;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ApplicationTypeOptionsCategory extends OptionsCategory {\n    final public static ApplicationTypeOptionsCategory instance() {\n        return new ApplicationTypeOptionsCategory();\n    }\n    @Override\n    public OptionsPanelController create() {\n        return new ApplicationTypesOptionsPanelController();\n    }\n\n    @Override\n    public String getCategoryName() {\n        return \"Application Types\";\n    }\n\n    @Override\n    public String getTitle() {\n        return \"VisualVM\";\n    }\n\n    @Override\n    public Icon getIcon() {\n        return new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/modules/customtype/resources/type_options.png\"));\n    }\n\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/options/ApplicationTypeOptionsPanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.6\" maxVersion=\"1.7\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <NonVisualComponents>\n    <Container class=\"javax.swing.JPopupMenu\" name=\"tablePopupMenu\">\n\n      <Layout class=\"org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout\">\n        <Property name=\"useNullLayout\" type=\"boolean\" value=\"true\"/>\n      </Layout>\n      <SubComponents>\n        <MenuItem class=\"javax.swing.JMenuItem\" name=\"menuNew\">\n          <Properties>\n            <Property name=\"accelerator\" type=\"javax.swing.KeyStroke\" editor=\"org.netbeans.modules.form.editors.KeyStrokeEditor\">\n              <KeyStroke key=\"Ctrl+INSERT\"/>\n            </Property>\n            <Property name=\"mnemonic\" type=\"int\" value=\"67\"/>\n            <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n              <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/options/Bundle.properties\" key=\"ApplicationTypeOptionsPanel.menuNew.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n            </Property>\n          </Properties>\n          <Events>\n            <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"menuNewActionPerformed\"/>\n          </Events>\n        </MenuItem>\n        <MenuItem class=\"javax.swing.JMenuItem\" name=\"menuEdit\">\n          <Properties>\n            <Property name=\"accelerator\" type=\"javax.swing.KeyStroke\" editor=\"org.netbeans.modules.form.editors.KeyStrokeEditor\">\n              <KeyStroke key=\"Ctrl+ENTER\"/>\n            </Property>\n            <Property name=\"mnemonic\" type=\"int\" value=\"69\"/>\n            <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n              <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/options/Bundle.properties\" key=\"ApplicationTypeOptionsPanel.menuEdit.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n            </Property>\n            <Property name=\"enabled\" type=\"boolean\" value=\"false\"/>\n          </Properties>\n          <Events>\n            <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"editApplicationType\"/>\n          </Events>\n        </MenuItem>\n        <Component class=\"javax.swing.JSeparator\" name=\"jSeparator1\">\n        </Component>\n        <MenuItem class=\"javax.swing.JMenuItem\" name=\"menuDelete\">\n          <Properties>\n            <Property name=\"accelerator\" type=\"javax.swing.KeyStroke\" editor=\"org.netbeans.modules.form.editors.KeyStrokeEditor\">\n              <KeyStroke key=\"DELETE\"/>\n            </Property>\n            <Property name=\"mnemonic\" type=\"int\" value=\"68\"/>\n            <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n              <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/options/Bundle.properties\" key=\"ApplicationTypeOptionsPanel.menuDelete.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n            </Property>\n            <Property name=\"enabled\" type=\"boolean\" value=\"false\"/>\n          </Properties>\n          <Events>\n            <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"deleteApptype\"/>\n          </Events>\n        </MenuItem>\n      </SubComponents>\n    </Container>\n  </NonVisualComponents>\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"jScrollPane1\" alignment=\"0\" pref=\"382\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"jLabel1\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jLabel1\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jScrollPane1\" pref=\"275\" max=\"32767\" attributes=\"0\"/>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"jLabel1\">\n      <Properties>\n        <Property name=\"font\" type=\"java.awt.Font\" editor=\"org.netbeans.beaninfo.editors.FontEditor\">\n          <Font name=\"DejaVu Sans\" size=\"13\" style=\"1\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/options/Bundle.properties\" key=\"ApplicationTypeOptionsPanel.jLabel1.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Container class=\"javax.swing.JScrollPane\" name=\"jScrollPane1\">\n      <AuxValues>\n        <AuxValue name=\"autoScrollPane\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n\n      <Layout class=\"org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout\"/>\n      <SubComponents>\n        <Component class=\"javax.swing.JTable\" name=\"appTypeTable\">\n          <Properties>\n            <Property name=\"autoCreateRowSorter\" type=\"boolean\" value=\"true\"/>\n            <Property name=\"model\" type=\"javax.swing.table.TableModel\" editor=\"org.netbeans.modules.form.RADConnectionPropertyEditor\">\n              <Connection code=\"tableModel\" type=\"code\"/>\n            </Property>\n            <Property name=\"columnModel\" type=\"javax.swing.table.TableColumnModel\" editor=\"org.netbeans.modules.form.editors2.TableColumnModelEditor\">\n              <TableColumnModel selectionModel=\"3\">\n                <Column maxWidth=\"-1\" minWidth=\"-1\" prefWidth=\"-1\" resizable=\"true\">\n                  <Title editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n                    <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/options/Bundle.properties\" key=\"ApplicationTypeOptionsPanel.appTypeTable.columnModel.title0\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n                  </Title>\n                  <Editor/>\n                  <Renderer/>\n                </Column>\n                <Column maxWidth=\"-1\" minWidth=\"-1\" prefWidth=\"-1\" resizable=\"true\">\n                  <Title editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n                    <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/options/Bundle.properties\" key=\"ApplicationTypeOptionsPanel.appTypeTable.columnModel.title1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n                  </Title>\n                  <Editor/>\n                  <Renderer/>\n                </Column>\n              </TableColumnModel>\n            </Property>\n            <Property name=\"componentPopupMenu\" type=\"javax.swing.JPopupMenu\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n              <ComponentRef name=\"tablePopupMenu\"/>\n            </Property>\n            <Property name=\"opaque\" type=\"boolean\" value=\"false\"/>\n            <Property name=\"selectionModel\" type=\"javax.swing.ListSelectionModel\" editor=\"org.netbeans.modules.form.editors2.JTableSelectionModelEditor\">\n              <JTableSelectionModel selectionMode=\"2\"/>\n            </Property>\n            <Property name=\"tableHeader\" type=\"javax.swing.table.JTableHeader\" editor=\"org.netbeans.modules.form.editors2.JTableHeaderEditor\">\n              <TableHeader reorderingAllowed=\"true\" resizingAllowed=\"true\"/>\n            </Property>\n          </Properties>\n        </Component>\n      </SubComponents>\n    </Container>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/options/ApplicationTypeOptionsPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * ApplicationTypeOptionsPanel.java\n *\n * Created on Nov 3, 2008, 1:33:55 PM\n */\npackage org.graalvm.visualvm.modules.customtype.options;\n\nimport org.graalvm.visualvm.modules.customtype.ApplicationType;\nimport org.graalvm.visualvm.modules.customtype.ApplicationTypeManager;\nimport org.graalvm.visualvm.modules.customtype.ui.ApplicationTypeForm;\nimport java.awt.Dialog;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.AbstractTableModel;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ApplicationTypeOptionsPanel extends javax.swing.JPanel {\n\n    private static class AppTypeTableMode extends AbstractTableModel {\n\n        final private List<ApplicationType> types = new ArrayList<ApplicationType>();\n\n        @Override\n        public int getColumnCount() {\n            return 2;\n        }\n\n        @Override\n        public int getRowCount() {\n            synchronized (types) {\n                return types.size();\n            }\n        }\n\n        @Override\n        public Object getValueAt(int rowIndex, int columnIndex) {\n            synchronized (types) {\n                switch (columnIndex) {\n                    case 0: {\n                        return types.get(rowIndex).getName();\n                    }\n                    case 1: {\n                        return true;\n                    }\n                    default: {\n                        return null;\n                    }\n                }\n            }\n        }\n\n        ApplicationType getTypeAt(int selectedIndex) {\n            synchronized (types) {\n                return types.get(selectedIndex);\n            }\n        }\n\n        void update() {\n            synchronized (types) {\n                types.clear();\n                types.addAll(ApplicationTypeManager.getDefault().listTypes());\n                fireTableDataChanged();\n            }\n        }\n    }\n    final private AppTypeTableMode tableModel = new AppTypeTableMode();\n\n    /** Creates new form ApplicationTypeOptionsPanel */\n    public ApplicationTypeOptionsPanel() {\n        initComponents();\n        appTypeTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n\n            @Override\n            public void valueChanged(ListSelectionEvent e) {\n                if (!e.getValueIsAdjusting()) {\n                    menuEdit.setEnabled(appTypeTable.getSelectedRowCount() == 1);\n                    menuDelete.setEnabled(appTypeTable.getSelectedRowCount() > 0);\n                }\n            }\n        });\n    }\n\n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    @SuppressWarnings(\"unchecked\")\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        tablePopupMenu = new javax.swing.JPopupMenu();\n        menuNew = new javax.swing.JMenuItem();\n        menuEdit = new javax.swing.JMenuItem();\n        jSeparator1 = new javax.swing.JSeparator();\n        menuDelete = new javax.swing.JMenuItem();\n        jLabel1 = new javax.swing.JLabel();\n        jScrollPane1 = new javax.swing.JScrollPane();\n        appTypeTable = new javax.swing.JTable();\n\n        menuNew.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_INSERT, java.awt.event.InputEvent.CTRL_MASK));\n        menuNew.setMnemonic('C');\n        menuNew.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeOptionsPanel.class, \"ApplicationTypeOptionsPanel.menuNew.text\")); // NOI18N\n        menuNew.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                menuNewActionPerformed(evt);\n            }\n        });\n        tablePopupMenu.add(menuNew);\n\n        menuEdit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ENTER, java.awt.event.InputEvent.CTRL_MASK));\n        menuEdit.setMnemonic('E');\n        menuEdit.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeOptionsPanel.class, \"ApplicationTypeOptionsPanel.menuEdit.text\")); // NOI18N\n        menuEdit.setEnabled(false);\n        menuEdit.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                editApplicationType(evt);\n            }\n        });\n        tablePopupMenu.add(menuEdit);\n        tablePopupMenu.add(jSeparator1);\n\n        menuDelete.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DELETE, 0));\n        menuDelete.setMnemonic('D');\n        menuDelete.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeOptionsPanel.class, \"ApplicationTypeOptionsPanel.menuDelete.text\")); // NOI18N\n        menuDelete.setEnabled(false);\n        menuDelete.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                deleteApptype(evt);\n            }\n        });\n        tablePopupMenu.add(menuDelete);\n\n        jLabel1.setFont(new java.awt.Font(\"DejaVu Sans\", 1, 13));\n        jLabel1.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeOptionsPanel.class, \"ApplicationTypeOptionsPanel.jLabel1.text\")); // NOI18N\n\n        appTypeTable.setAutoCreateRowSorter(true);\n        appTypeTable.setModel(tableModel);\n        appTypeTable.setComponentPopupMenu(tablePopupMenu);\n        appTypeTable.setOpaque(false);\n        appTypeTable.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);\n        jScrollPane1.setViewportView(appTypeTable);\n        appTypeTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);\n        appTypeTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(ApplicationTypeOptionsPanel.class, \"ApplicationTypeOptionsPanel.appTypeTable.columnModel.title0\")); // NOI18N\n        appTypeTable.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(ApplicationTypeOptionsPanel.class, \"ApplicationTypeOptionsPanel.appTypeTable.columnModel.title1\")); // NOI18N\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)\n                    .addComponent(jLabel1))\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addComponent(jLabel1)\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 275, Short.MAX_VALUE)\n                .addContainerGap())\n        );\n    }// </editor-fold>//GEN-END:initComponents\n\n    private void editApplicationType(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editApplicationType\n        final ApplicationType at = tableModel.getTypeAt(appTypeTable.getSelectedRow());\n        final ApplicationTypeForm form = new ApplicationTypeForm(at);\n\n        final DialogDescriptor[] dd = new DialogDescriptor[1];\n\n        dd[0] = new DialogDescriptor(form, \"Application Type Details\", true, new Object[]{form.getValidationSupport().getOkButton(), DialogDescriptor.CANCEL_OPTION}, form.getValidationSupport().getOkButton(), DialogDescriptor.DEFAULT_ALIGN, null, new ActionListener() {\n\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                if (e.getSource() == form.getValidationSupport().getOkButton() && form.storeData()) {\n                    dd[0].setClosingOptions(new Object[]{form.getValidationSupport().getOkButton()});\n                }\n            }\n        });\n\n        dd[0].setClosingOptions(new Object[]{DialogDescriptor.CANCEL_OPTION});\n\n        Dialog dlg = DialogDisplayer.getDefault().createDialog(dd[0]);\n        dlg.setVisible(true);\n        if (dd[0].getValue() == form.getValidationSupport().getOkButton()) {\n            try {\n                ApplicationTypeManager.getDefault().storeType(at);\n            } catch (IOException ex) {\n                ex.printStackTrace();\n            }\n        }\n    }//GEN-LAST:event_editApplicationType\n\n    private void menuNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuNewActionPerformed\n        ApplicationType eat = ApplicationTypeManager.getDefault().newType(\"\");\n        final ApplicationTypeForm form = new ApplicationTypeForm(eat);\n\n        final DialogDescriptor[] dd = new DialogDescriptor[1];\n\n        dd[0] = new DialogDescriptor(form, \"New Application Type Details\", true, new Object[]{form.getValidationSupport().getOkButton(), DialogDescriptor.CANCEL_OPTION}, form.getValidationSupport().getOkButton(), DialogDescriptor.DEFAULT_ALIGN, null, new ActionListener() {\n\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                if (e.getSource().equals(form.getValidationSupport().getOkButton()) && form.storeData()) {\n                    dd[0].setClosingOptions(new Object[]{form.getValidationSupport().getOkButton()});\n                }\n            }\n        });\n\n        dd[0].setClosingOptions(new Object[]{DialogDescriptor.CANCEL_OPTION});\n\n        Dialog dlg = DialogDisplayer.getDefault().createDialog(dd[0]);\n        dlg.setVisible(true);\n        if (dd[0].getValue() == form.getValidationSupport().getOkButton()) {\n            try {\n                ApplicationTypeManager.getDefault().storeType(eat);\n            } catch (IOException ex) {\n                ex.printStackTrace();\n            }\n        }\n        tableModel.update();\n    }//GEN-LAST:event_menuNewActionPerformed\n\n    private void deleteApptype(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteApptype\n        final ApplicationType at = tableModel.getTypeAt(appTypeTable.getSelectedRow());\n        ApplicationTypeManager.getDefault().removeType(at);\n        tableModel.update();\n    }//GEN-LAST:event_deleteApptype\n\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JTable appTypeTable;\n    private javax.swing.JLabel jLabel1;\n    private javax.swing.JScrollPane jScrollPane1;\n    private javax.swing.JSeparator jSeparator1;\n    private javax.swing.JMenuItem menuDelete;\n    private javax.swing.JMenuItem menuEdit;\n    private javax.swing.JMenuItem menuNew;\n    private javax.swing.JPopupMenu tablePopupMenu;\n    // End of variables declaration//GEN-END:variables\n\n    void load() {\n        tableModel.update();\n    }\n\n    void store() {\n        System.err.println(\"Store\");\n    }\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/options/ApplicationTypesOptionsPanelController.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.customtype.options;\n\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport javax.swing.JComponent;\nimport org.netbeans.spi.options.OptionsPanelController;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ApplicationTypesOptionsPanelController extends OptionsPanelController{\n    volatile private ApplicationTypeOptionsPanel panel;\n    final private PropertyChangeSupport pcs = new PropertyChangeSupport(this);\n    \n    @Override\n    public void addPropertyChangeListener(PropertyChangeListener listener) {\n        pcs.addPropertyChangeListener(listener);\n    }\n\n    @Override\n    public void applyChanges() {\n        getPanel().store();\n    }\n\n    @Override\n    public void cancel() {\n        // no-op\n    }\n\n    @Override\n    public JComponent getComponent(Lookup arg0) {\n        return getPanel();\n    }\n\n    @Override\n    public HelpCtx getHelpCtx() {\n        return null;\n    }\n\n    @Override\n    public boolean isChanged() {\n        return true;\n    }\n\n    @Override\n    public boolean isValid() {\n        return true;\n    }\n\n    @Override\n    public void removePropertyChangeListener(PropertyChangeListener listener) {\n        pcs.removePropertyChangeListener(listener);\n    }\n\n    @Override\n    public void update() {\n        getPanel().load();\n    }\n\n    synchronized private ApplicationTypeOptionsPanel getPanel() {\n        if (panel == null) {\n            panel = new ApplicationTypeOptionsPanel();\n        }\n        return panel;\n    }\n\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/options/Bundle.properties",
    "content": "# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n *\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n *\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\nApplicationTypeOptionsPanel.jLabel1.text=Application Types\nApplicationTypeOptionsPanel.jTable1.columnModel.title3=Title 4\nApplicationTypeOptionsPanel.jTable1.columnModel.title2=Title 3\nApplicationTypeOptionsPanel.appTypeTable.columnModel.title1=Active\nApplicationTypeOptionsPanel.appTypeTable.columnModel.title0=Application Type\nApplicationTypeOptionsPanel.menuNew.text=Create...\nApplicationTypeOptionsPanel.menuEdit.text=Edit...\nApplicationTypeOptionsPanel.menuDelete.text=Delete\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/ui/ApplicationTypeForm.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.5\" maxVersion=\"1.7\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <NonVisualComponents>\n    <Container class=\"javax.swing.JPopupMenu\" name=\"iconMenu\">\n\n      <Layout class=\"org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout\">\n        <Property name=\"useNullLayout\" type=\"boolean\" value=\"true\"/>\n      </Layout>\n      <SubComponents>\n        <MenuItem class=\"javax.swing.JMenuItem\" name=\"resetIcon\">\n          <Properties>\n            <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n              <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/ui/Bundle.properties\" key=\"ApplicationTypeForm.resetIcon.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n            </Property>\n          </Properties>\n          <Events>\n            <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"resetIconActionPerformed\"/>\n          </Events>\n        </MenuItem>\n      </SubComponents>\n    </Container>\n  </NonVisualComponents>\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"1\" attributes=\"0\">\n                  <Component id=\"jScrollPane2\" alignment=\"0\" pref=\"463\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"mainClassLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n                      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                          <Component id=\"urlLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"descriptionLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"nameLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      </Group>\n                      <EmptySpace min=\"-2\" pref=\"8\" max=\"-2\" attributes=\"0\"/>\n                      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                          <Component id=\"jScrollPane1\" pref=\"379\" max=\"32767\" attributes=\"0\"/>\n                          <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n                              <Component id=\"appTypeName\" pref=\"297\" max=\"32767\" attributes=\"0\"/>\n                              <EmptySpace max=\"-2\" attributes=\"0\"/>\n                              <Component id=\"jLabel4\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                              <EmptySpace max=\"-2\" attributes=\"0\"/>\n                              <Component id=\"appTypeIcon\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          </Group>\n                          <Component id=\"appTypeUrl\" pref=\"379\" max=\"32767\" attributes=\"0\"/>\n                          <Component id=\"appTypeMainClass\" alignment=\"0\" pref=\"379\" max=\"32767\" attributes=\"0\"/>\n                      </Group>\n                  </Group>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"1\" attributes=\"0\">\n                  <Group type=\"102\" attributes=\"0\">\n                      <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                          <Component id=\"nameLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"appTypeName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"jLabel4\" alignment=\"3\" max=\"32767\" attributes=\"1\"/>\n                      </Group>\n                      <EmptySpace min=\"-2\" pref=\"6\" max=\"-2\" attributes=\"0\"/>\n                  </Group>\n                  <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n                      <Component id=\"appTypeIcon\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                  </Group>\n              </Group>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"mainClassLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"appTypeMainClass\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"urlLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"appTypeUrl\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace type=\"separate\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"descriptionLabel\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"jScrollPane1\" min=\"-2\" pref=\"99\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jScrollPane2\" min=\"-2\" pref=\"67\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"nameLabel\">\n      <Properties>\n        <Property name=\"displayedMnemonic\" type=\"int\" value=\"78\"/>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"appTypeName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/ui/Bundle.properties\" key=\"ApplicationTypeForm.nameLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"mainClassLabel\">\n      <Properties>\n        <Property name=\"displayedMnemonic\" type=\"int\" value=\"67\"/>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"appTypeMainClass\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/ui/Bundle.properties\" key=\"ApplicationTypeForm.mainClassLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"urlLabel\">\n      <Properties>\n        <Property name=\"displayedMnemonic\" type=\"int\" value=\"85\"/>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"appTypeUrl\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/ui/Bundle.properties\" key=\"ApplicationTypeForm.urlLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"jLabel4\">\n      <Properties>\n        <Property name=\"displayedMnemonic\" type=\"int\" value=\"73\"/>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"appTypeIcon\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/ui/Bundle.properties\" key=\"ApplicationTypeForm.jLabel4.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"appTypeName\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/ui/Bundle.properties\" key=\"ApplicationTypeForm.appTypeName.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n        <Property name=\"focusCycleRoot\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"nextFocusableComponent\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"appTypeIcon\"/>\n        </Property>\n      </Properties>\n      <Events>\n        <EventHandler event=\"focusGained\" listener=\"java.awt.event.FocusListener\" parameters=\"java.awt.event.FocusEvent\" handler=\"appTypeNameFocusGained\"/>\n        <EventHandler event=\"focusLost\" listener=\"java.awt.event.FocusListener\" parameters=\"java.awt.event.FocusEvent\" handler=\"appTypeNameFocusLost\"/>\n        <EventHandler event=\"keyTyped\" listener=\"java.awt.event.KeyListener\" parameters=\"java.awt.event.KeyEvent\" handler=\"appTypeNameKeyTyped\"/>\n      </Events>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"appTypeMainClass\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/ui/Bundle.properties\" key=\"ApplicationTypeForm.appTypeMainClass.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n        <Property name=\"nextFocusableComponent\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"appTypeUrl\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"appTypeUrl\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/ui/Bundle.properties\" key=\"ApplicationTypeForm.appTypeUrl.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n        <Property name=\"nextFocusableComponent\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"appTypeDescription\"/>\n        </Property>\n      </Properties>\n      <Events>\n        <EventHandler event=\"focusGained\" listener=\"java.awt.event.FocusListener\" parameters=\"java.awt.event.FocusEvent\" handler=\"appTypeUrlFocusGained\"/>\n        <EventHandler event=\"focusLost\" listener=\"java.awt.event.FocusListener\" parameters=\"java.awt.event.FocusEvent\" handler=\"appTypeUrlFocusLost\"/>\n      </Events>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"descriptionLabel\">\n      <Properties>\n        <Property name=\"displayedMnemonic\" type=\"int\" value=\"68\"/>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"appTypeDescription\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/ui/Bundle.properties\" key=\"ApplicationTypeForm.descriptionLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Container class=\"javax.swing.JScrollPane\" name=\"jScrollPane1\">\n      <AuxValues>\n        <AuxValue name=\"autoScrollPane\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n\n      <Layout class=\"org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout\"/>\n      <SubComponents>\n        <Component class=\"javax.swing.JTextArea\" name=\"appTypeDescription\">\n          <Properties>\n            <Property name=\"columns\" type=\"int\" value=\"20\"/>\n            <Property name=\"lineWrap\" type=\"boolean\" value=\"true\"/>\n            <Property name=\"rows\" type=\"int\" value=\"5\"/>\n            <Property name=\"tabSize\" type=\"int\" value=\"4\"/>\n            <Property name=\"wrapStyleWord\" type=\"boolean\" value=\"true\"/>\n            <Property name=\"nextFocusableComponent\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n              <ComponentRef name=\"appTypeName\"/>\n            </Property>\n          </Properties>\n          <Events>\n            <EventHandler event=\"focusGained\" listener=\"java.awt.event.FocusListener\" parameters=\"java.awt.event.FocusEvent\" handler=\"appTypeDescriptionFocusGained\"/>\n            <EventHandler event=\"focusLost\" listener=\"java.awt.event.FocusListener\" parameters=\"java.awt.event.FocusEvent\" handler=\"appTypeDescriptionFocusLost\"/>\n          </Events>\n        </Component>\n      </SubComponents>\n    </Container>\n    <Container class=\"javax.swing.JScrollPane\" name=\"jScrollPane2\">\n      <Properties>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"org.netbeans.modules.form.compat2.border.EmptyBorderInfo\">\n            <EmptyBorder/>\n          </Border>\n        </Property>\n        <Property name=\"viewportBorder\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"org.netbeans.modules.form.compat2.border.EmptyBorderInfo\">\n            <EmptyBorder/>\n          </Border>\n        </Property>\n        <Property name=\"opaque\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"autoScrollPane\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n\n      <Layout class=\"org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout\"/>\n      <SubComponents>\n        <Component class=\"javax.swing.JTextPane\" name=\"jTextPane1\">\n          <Properties>\n            <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n              <Border info=\"org.netbeans.modules.form.compat2.border.EmptyBorderInfo\">\n                <EmptyBorder/>\n              </Border>\n            </Property>\n            <Property name=\"contentType\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n              <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/ui/Bundle.properties\" key=\"ApplicationTypeForm.jTextPane1.contentType\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n            </Property>\n            <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n            <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n              <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/ui/Bundle.properties\" key=\"ApplicationTypeForm.jTextPane1.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n            </Property>\n          </Properties>\n        </Component>\n      </SubComponents>\n    </Container>\n    <Component class=\"javax.swing.JButton\" name=\"appTypeIcon\">\n      <Properties>\n        <Property name=\"icon\" type=\"javax.swing.Icon\" editor=\"org.netbeans.modules.form.editors2.IconEditor\">\n          <Image iconType=\"3\" name=\"/org/graalvm/visualvm/modules/customtype/ui/application.png\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/modules/customtype/ui/Bundle.properties\" key=\"ApplicationTypeForm.appTypeIcon.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n        <Property name=\"componentPopupMenu\" type=\"javax.swing.JPopupMenu\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"iconMenu\"/>\n        </Property>\n        <Property name=\"hideActionText\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"nextFocusableComponent\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"appTypeMainClass\"/>\n        </Property>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"appTypeIconActionPerformed\"/>\n      </Events>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/ui/ApplicationTypeForm.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * NewApplicationTypeForm.java\n *\n * Created on Oct 22, 2008, 2:40:07 PM\n */\npackage org.graalvm.visualvm.modules.customtype.ui;\n\nimport org.graalvm.visualvm.modules.customtype.ApplicationType;\nimport org.graalvm.visualvm.modules.customtype.actions.ValidationSupport;\nimport org.graalvm.visualvm.modules.customtype.icons.ImageUtils;\nimport java.awt.Color;\nimport java.awt.image.BufferedImage;\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport javax.imageio.ImageIO;\nimport javax.swing.ImageIcon;\nimport javax.swing.JFileChooser;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.filechooser.FileFilter;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ApplicationTypeForm extends javax.swing.JPanel {\n\n    final private static String defaultName = \"<\" + \"New Application Type\" + \">\";\n    final private static String defaultDescription = \"<\" + \"Put description here\" + \">\";\n    final private static ImageIcon DEFAULT_ICON = new javax.swing.ImageIcon(ApplicationTypeForm.class.getResource(\"/org/graalvm/visualvm/modules/customtype/ui/application.png\")); // NOI18N\n    private ApplicationType applicationType;\n    private File iconFile = null;\n    private boolean iconFileReset = false;\n    private ValidationSupport validationSupport = new ValidationSupport() {\n\n        @Override\n        public boolean isValid() {\n            return !appTypeName.getText().isEmpty();\n        }\n    };\n\n    /** Creates new form NewApplicationTypeForm */\n    public ApplicationTypeForm(ApplicationType appType) {\n        initComponents();\n        applicationType = appType;\n        appTypeName.getDocument().addDocumentListener(new DocumentListener() {\n\n            @Override\n            public void insertUpdate(DocumentEvent e) {\n                validationSupport.updateValidity();\n            }\n\n            @Override\n            public void removeUpdate(DocumentEvent e) {\n                validationSupport.updateValidity();\n            }\n\n            @Override\n            public void changedUpdate(DocumentEvent e) {\n                validationSupport.updateValidity();\n            }\n        });\n        loadData();\n    }\n\n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    @SuppressWarnings(\"unchecked\")\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        iconMenu = new javax.swing.JPopupMenu();\n        resetIcon = new javax.swing.JMenuItem();\n        nameLabel = new javax.swing.JLabel();\n        mainClassLabel = new javax.swing.JLabel();\n        urlLabel = new javax.swing.JLabel();\n        jLabel4 = new javax.swing.JLabel();\n        appTypeName = new javax.swing.JTextField();\n        appTypeMainClass = new javax.swing.JTextField();\n        appTypeUrl = new javax.swing.JTextField();\n        descriptionLabel = new javax.swing.JLabel();\n        jScrollPane1 = new javax.swing.JScrollPane();\n        appTypeDescription = new javax.swing.JTextArea();\n        jScrollPane2 = new javax.swing.JScrollPane();\n        jTextPane1 = new javax.swing.JTextPane();\n        appTypeIcon = new javax.swing.JButton();\n\n        resetIcon.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, \"ApplicationTypeForm.resetIcon.text\")); // NOI18N\n        resetIcon.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                resetIconActionPerformed(evt);\n            }\n        });\n        iconMenu.add(resetIcon);\n\n        nameLabel.setDisplayedMnemonic('N');\n        nameLabel.setLabelFor(appTypeName);\n        nameLabel.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, \"ApplicationTypeForm.nameLabel.text\")); // NOI18N\n\n        mainClassLabel.setDisplayedMnemonic('C');\n        mainClassLabel.setLabelFor(appTypeMainClass);\n        mainClassLabel.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, \"ApplicationTypeForm.mainClassLabel.text\")); // NOI18N\n\n        urlLabel.setDisplayedMnemonic('U');\n        urlLabel.setLabelFor(appTypeUrl);\n        urlLabel.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, \"ApplicationTypeForm.urlLabel.text\")); // NOI18N\n\n        jLabel4.setDisplayedMnemonic('I');\n        jLabel4.setLabelFor(appTypeIcon);\n        jLabel4.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, \"ApplicationTypeForm.jLabel4.text\")); // NOI18N\n\n        appTypeName.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, \"ApplicationTypeForm.appTypeName.text\")); // NOI18N\n        appTypeName.setFocusCycleRoot(true);\n        appTypeName.setNextFocusableComponent(appTypeIcon);\n        appTypeName.addFocusListener(new java.awt.event.FocusAdapter() {\n            public void focusGained(java.awt.event.FocusEvent evt) {\n                appTypeNameFocusGained(evt);\n            }\n            public void focusLost(java.awt.event.FocusEvent evt) {\n                appTypeNameFocusLost(evt);\n            }\n        });\n        appTypeName.addKeyListener(new java.awt.event.KeyAdapter() {\n            public void keyTyped(java.awt.event.KeyEvent evt) {\n                appTypeNameKeyTyped(evt);\n            }\n        });\n\n        appTypeMainClass.setEditable(false);\n        appTypeMainClass.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, \"ApplicationTypeForm.appTypeMainClass.text\")); // NOI18N\n        appTypeMainClass.setNextFocusableComponent(appTypeUrl);\n\n        appTypeUrl.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, \"ApplicationTypeForm.appTypeUrl.text\")); // NOI18N\n        appTypeUrl.setNextFocusableComponent(appTypeDescription);\n        appTypeUrl.addFocusListener(new java.awt.event.FocusAdapter() {\n            public void focusGained(java.awt.event.FocusEvent evt) {\n                appTypeUrlFocusGained(evt);\n            }\n            public void focusLost(java.awt.event.FocusEvent evt) {\n                appTypeUrlFocusLost(evt);\n            }\n        });\n\n        descriptionLabel.setDisplayedMnemonic('D');\n        descriptionLabel.setLabelFor(appTypeDescription);\n        descriptionLabel.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, \"ApplicationTypeForm.descriptionLabel.text\")); // NOI18N\n\n        appTypeDescription.setColumns(20);\n        appTypeDescription.setLineWrap(true);\n        appTypeDescription.setRows(5);\n        appTypeDescription.setTabSize(4);\n        appTypeDescription.setWrapStyleWord(true);\n        appTypeDescription.setNextFocusableComponent(appTypeName);\n        appTypeDescription.addFocusListener(new java.awt.event.FocusAdapter() {\n            public void focusGained(java.awt.event.FocusEvent evt) {\n                appTypeDescriptionFocusGained(evt);\n            }\n            public void focusLost(java.awt.event.FocusEvent evt) {\n                appTypeDescriptionFocusLost(evt);\n            }\n        });\n        jScrollPane1.setViewportView(appTypeDescription);\n\n        jScrollPane2.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));\n        jScrollPane2.setViewportBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));\n        jScrollPane2.setOpaque(false);\n\n        jTextPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));\n        jTextPane1.setContentType(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, \"ApplicationTypeForm.jTextPane1.contentType\")); // NOI18N\n        jTextPane1.setEditable(false);\n        jTextPane1.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, \"ApplicationTypeForm.jTextPane1.text\")); // NOI18N\n        jScrollPane2.setViewportView(jTextPane1);\n\n        appTypeIcon.setIcon(new javax.swing.ImageIcon(getClass().getResource(\"/org/graalvm/visualvm/modules/customtype/ui/application.png\"))); // NOI18N\n        appTypeIcon.setText(org.openide.util.NbBundle.getMessage(ApplicationTypeForm.class, \"ApplicationTypeForm.appTypeIcon.text\")); // NOI18N\n        appTypeIcon.setComponentPopupMenu(iconMenu);\n        appTypeIcon.setHideActionText(true);\n        appTypeIcon.setNextFocusableComponent(appTypeMainClass);\n        appTypeIcon.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                appTypeIconActionPerformed(evt);\n            }\n        });\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)\n                    .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 463, Short.MAX_VALUE)\n                    .addComponent(mainClassLabel, javax.swing.GroupLayout.Alignment.LEADING)\n                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()\n                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                            .addComponent(urlLabel)\n                            .addComponent(descriptionLabel)\n                            .addComponent(nameLabel))\n                        .addGap(8, 8, 8)\n                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 379, Short.MAX_VALUE)\n                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()\n                                .addComponent(appTypeName, javax.swing.GroupLayout.DEFAULT_SIZE, 297, Short.MAX_VALUE)\n                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                                .addComponent(jLabel4)\n                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                                .addComponent(appTypeIcon))\n                            .addComponent(appTypeUrl, javax.swing.GroupLayout.DEFAULT_SIZE, 379, Short.MAX_VALUE)\n                            .addComponent(appTypeMainClass, javax.swing.GroupLayout.DEFAULT_SIZE, 379, Short.MAX_VALUE))))\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)\n                    .addGroup(layout.createSequentialGroup()\n                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                            .addComponent(nameLabel)\n                            .addComponent(appTypeName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)\n                            .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))\n                        .addGap(6, 6, 6))\n                    .addGroup(layout.createSequentialGroup()\n                        .addComponent(appTypeIcon)\n                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(mainClassLabel)\n                    .addComponent(appTypeMainClass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(urlLabel)\n                    .addComponent(appTypeUrl, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addGap(18, 18, 18)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(descriptionLabel)\n                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 99, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE)\n                .addContainerGap())\n        );\n    }// </editor-fold>//GEN-END:initComponents\n\n    private void appTypeNameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_appTypeNameFocusGained\n        appTypeName.setSelectionStart(0);\n        appTypeName.setSelectionEnd(appTypeName.getText().length());\n    }//GEN-LAST:event_appTypeNameFocusGained\n\n    private void appTypeNameFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_appTypeNameFocusLost\n        appTypeName.setSelectionEnd(0);\n    }//GEN-LAST:event_appTypeNameFocusLost\n\n    private void appTypeDescriptionFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_appTypeDescriptionFocusGained\n        appTypeDescription.setSelectionStart(0);\n        appTypeDescription.setSelectionEnd(appTypeDescription.getText().length());\n    }//GEN-LAST:event_appTypeDescriptionFocusGained\n\n    private void appTypeDescriptionFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_appTypeDescriptionFocusLost\n        appTypeDescription.setSelectionEnd(0);\n    }//GEN-LAST:event_appTypeDescriptionFocusLost\n\n    private void appTypeUrlFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_appTypeUrlFocusGained\n        appTypeUrl.setSelectionStart(0);\n        appTypeUrl.setSelectionEnd(appTypeUrl.getText().length());\n    }//GEN-LAST:event_appTypeUrlFocusGained\n\n    private void appTypeUrlFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_appTypeUrlFocusLost\n        appTypeUrl.setSelectionEnd(0);\n    }//GEN-LAST:event_appTypeUrlFocusLost\n\n    private void appTypeNameKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_appTypeNameKeyTyped\n        validationSupport.updateValidity();\n    }//GEN-LAST:event_appTypeNameKeyTyped\n\n    private void appTypeIconActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_appTypeIconActionPerformed\n        JFileChooser jfc = new JFileChooser();\n        jfc.setFileFilter(new FileFilter() {\n\n            @Override\n            public boolean accept(File f) {\n                return (f.isDirectory() || f.getName().endsWith(\"png\") || f.getName().endsWith(\"jpg\") || f.getName().endsWith(\"jpeg\") || f.getName().endsWith(\"gif\"));\n            }\n\n            @Override\n            public String getDescription() {\n                return \"Icon files\";\n            }\n        });\n        if (jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {\n            iconFile = jfc.getSelectedFile();\n            try {\n                BufferedImage img = ImageIO.read(iconFile);\n                appTypeIcon.setIcon(new ImageIcon(ImageUtils.resizeImage(img, 16, 16)));\n                iconFileReset = false;\n            } catch (IOException iOException) {\n            }\n        }\n}//GEN-LAST:event_appTypeIconActionPerformed\n\n    private void resetIconActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetIconActionPerformed\n        iconFile = null;\n        appTypeIcon.setIcon(DEFAULT_ICON);\n        iconFileReset = true;\n    }//GEN-LAST:event_resetIconActionPerformed\n\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JTextArea appTypeDescription;\n    private javax.swing.JButton appTypeIcon;\n    private javax.swing.JTextField appTypeMainClass;\n    private javax.swing.JTextField appTypeName;\n    private javax.swing.JTextField appTypeUrl;\n    private javax.swing.JLabel descriptionLabel;\n    private javax.swing.JPopupMenu iconMenu;\n    private javax.swing.JLabel jLabel4;\n    private javax.swing.JScrollPane jScrollPane1;\n    private javax.swing.JScrollPane jScrollPane2;\n    private javax.swing.JTextPane jTextPane1;\n    private javax.swing.JLabel mainClassLabel;\n    private javax.swing.JLabel nameLabel;\n    private javax.swing.JMenuItem resetIcon;\n    private javax.swing.JLabel urlLabel;\n    // End of variables declaration//GEN-END:variables\n\n    private void loadData() {\n        iconFileReset = false;\n        appTypeName.setText(applicationType.getName() == null || applicationType.getName().isEmpty() ? defaultName : applicationType.getName());\n        appTypeMainClass.setText(applicationType.getMainClass());\n        appTypeUrl.setText(applicationType.getInfoURL() != null ? applicationType.getInfoURL().toString() : \"\");\n        appTypeDescription.setText((applicationType.getDescription() != null && !applicationType.getDescription().isEmpty()) ? applicationType.getDescription() : defaultDescription);\n        if (applicationType.getIconURL() != null) {\n            BufferedImage iconImage = null;\n            try {\n                iconImage = ImageIO.read(applicationType.getIconURL());\n            } catch (IOException e) {\n            }\n            if (iconImage != null) {\n                iconImage = ImageUtils.resizeImage(iconImage, 16, 16);\n            }\n            appTypeIcon.setIcon(new ImageIcon(iconImage));\n        } else {\n            appTypeIcon.setIcon(DEFAULT_ICON);\n        }\n        appTypeMainClass.setEditable(appTypeMainClass.getText().isEmpty());\n    }\n\n    public boolean storeData() {\n        boolean result = true;\n        if (appTypeName.getText().isEmpty() || appTypeName.getText().equals(defaultName)) {\n            nameLabel.setForeground(Color.RED);\n            result = false;\n        } else {\n            nameLabel.setForeground(Color.BLACK);\n        }\n        URL infoUrl = null;\n        if (!appTypeUrl.getText().isEmpty()) {\n            try {\n                infoUrl = new URL(appTypeUrl.getText());\n                urlLabel.setForeground(Color.BLACK);\n            } catch (MalformedURLException e) {\n                urlLabel.setForeground(Color.RED);\n                result = false;\n            }\n        } else {\n            urlLabel.setForeground(Color.BLACK);\n        }\n\n        if (result) {\n            applicationType.setName(appTypeName.getText());\n            applicationType.setMainClass(appTypeMainClass.getText());\n            applicationType.setDescription(appTypeDescription.getText().equals(defaultDescription) ? \"\" : appTypeDescription.getText());\n            if (iconFileReset) {\n                applicationType.setIconURL(null);\n            } else if (iconFile != null) {\n                try {\n                    applicationType.setIconURL(iconFile.toURI().toURL());\n                } catch (IOException e) {\n                }\n            }\n            applicationType.setInfoUrl(infoUrl);\n        }\n        return result;\n    }\n\n    public ValidationSupport getValidationSupport() {\n        return validationSupport;\n    }\n}\n"
  },
  {
    "path": "plugins/extapptypes/src/org/graalvm/visualvm/modules/customtype/ui/Bundle.properties",
    "content": "# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n *\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n *\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\nApplicationTypeForm.descriptionLabel.text=Description:\nApplicationTypeForm.appTypeUrl.text=\nApplicationTypeForm.appTypeMainClass.text=\nApplicationTypeForm.appTypeName.text=\nApplicationTypeForm.jLabel4.text=Icon:\nApplicationTypeForm.nameLabel.text=Name:\nApplicationTypeForm.mainClassLabel.text=Main Class:\nApplicationTypeForm.urlLabel.text=Info URL:\nApplicationTypeForm.jTextPane1.contentType=text/html\nApplicationTypeForm.jTextPane1.text=<html>\\n  <span style=\"color: red\">\\n   Note: All the changes will be visible only after you have restarted VisualVM or the monitored application\\n  </span>\\n</html>\\n\nApplicationTypeForm.appTypeIcon.text=\nApplicationTypeForm.resetIcon.text=Reset Icon\n"
  },
  {
    "path": "plugins/extapptypes.lib/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.customtype.lib\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.customtype.lib.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/extapptypes.lib/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.customtype.lib\nOpenIDE-Module-Layer: org/graalvm/visualvm/modules/customtype/lib/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/customtype/lib/Bundle.properties\nOpenIDE-Module-Requires: org.graalvm.visualvm.modules.customtype\nOpenIDE-Module-Specification-Version: 1.0\n\n"
  },
  {
    "path": "plugins/extapptypes.lib/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.customtype.lib-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/extapptypes.lib/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "plugins/extapptypes.lib/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.customtype.lib</code-name-base>\n            <suite-component/>\n            <module-dependencies/>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/extapptypes.lib/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/extapptypes.lib/src/org/graalvm/visualvm/modules/customtype/lib/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Long-Description=\\\n    This is a growing collection of application types for the most popular Java applicaitons.\\n\\n\\\n    It contains application types for applications such as jEdit, PMD, FindBugs, aTunes etc.\nOpenIDE-Module-Name=Custom Application Types - Collection\nOpenIDE-Module-Short-Description=Application types for widely used Java applications\n"
  },
  {
    "path": "plugins/extapptypes.lib/src/org/graalvm/visualvm/modules/customtype/lib/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    <folder name=\"VisualVM\">\n        <folder name=\"ApplicationTypes\">\n            <folder name=\"Vuze.def\">\n                <attr name=\"mainClass\" stringvalue=\"org.gudy.azureus2.ui.swt.Main\"/>\n                <attr name=\"displayName\" stringvalue=\"Vuze (formerly Azureus)\" />\n                <attr name=\"url\" stringvalue=\"http://azureus.sourceforge.net\"/>\n                <attr name=\"description\" stringvalue=\"Vuze is the easiest way to find, download, and play high-quality and HD videos.\n                                                      All-in-one bittorrent client.\"/>\n            </folder>\n            <folder name=\"blueMarine.def\">\n                <attr name=\"mainClass\" stringvalue=\"it.tidalwave.netbeans.boot.Main\"/>\n                <attr name=\"displayName\" stringvalue=\"blueMarine\"/>\n                <attr name=\"url\" stringvalue=\"http://bluemarine.tidalwave.it\"/>\n                <attr name=\"description\" stringvalue=\"An open source application for the digital photo workflow,\n                                                      the blueMarine project will provide you an all-in-one tool for managing your photos,\n                                                      from the shoot up to the archiving and beyond.\n                                                      blueMarine is an expandable, open platform and includes specific support for different\n                                                      photographers communities, as well as the latest technologies.\"/>\n            </folder>\n            <folder name=\"jEdit.def\">\n                <attr name=\"mainClass\" stringvalue=\"org.gjt.sp.jedit.jEdit\"/>\n                <attr name=\"displayName\" stringvalue=\"jEdit\"/>\n                <attr name=\"url\" stringvalue=\"http://www.jedit.org\"/>\n                <attr name=\"description\" stringvalue=\"A cross platform programmer's text editor written in Java that is customizable with plugins.\"/>\n            </folder>\n            <folder name=\"pmdDesigner.def\">\n                <attr name=\"mainClass\" stringvalue=\"net.sourceforge.pmd.util.designer.Designer\"/>\n                <attr name=\"displayName\" stringvalue=\"PMD Designer\"/>\n                <attr name=\"description\" stringvalue=\"Scans source code and looks for potential problems possible bugs, unused and suboptimal code,\n                                                      over-complicated expressions and duplicate code.\"/>\n                <attr name=\"url\" stringvalue=\"http://pmd.sourceforge.net\"/>\n            </folder>\n            <folder name=\"pmdAnalyser.def\">\n                <attr name=\"mainClass\" stringvalue=\"net.sourceforge.pmd.PMD\"/>\n                <attr name=\"displayName\" stringvalue=\"PMD Analyser\"/>\n                <attr name=\"description\" stringvalue=\"Scans source code and looks for potential problems possible bugs, unused and suboptimal code,\n                                                      over-complicated expressions and duplicate code.\"/>\n                <attr name=\"url\" stringvalue=\"http://pmd.sourceforge.net\"/>\n            </folder>\n            <folder name=\"findbugs.def\">\n                <attr name=\"mainClass\" stringvalue=\"edu.umd.cs.findbugs.LaunchAppropriateUI\"/>\n                <attr name=\"displayName\" stringvalue=\"FindBugs\"/>\n                <attr name=\"description\" stringvalue=\"FindBugs uses static analysis to inspect Java bytecode for occurrences of bug patterns\"/>\n                <attr name=\"url\" stringvalue=\"http://findbugs.sourceforge.net\"/>\n            </folder>\n            <folder name=\"ganttProject.def\">\n                <attr name=\"mainClass\" stringvalue=\"org.bardsoftware.eclipsito.Boot\"/>\n                <attr name=\"displayName\" stringvalue=\"GanttProject\"/>\n                <attr name=\"description\" stringvalue=\"GanttProject is a project scheduling application written in Java and featuring gantt chart,\n                                                      resource management, calendaring, import/export (MS Project, HTML, PDF, spreadsheets).\"/>\n                <attr name=\"url\" stringvalue=\"http://ganttproject.biz\"/>\n            </folder>\n            <folder name=\"sweetHome3d.def\">\n                <attr name=\"mainClass\" stringvalue=\"com.eteks.sweethome3d.SweetHome3D\"/>\n                <attr name=\"displayName\" stringvalue=\"SweetHome 3D\"/>\n                <attr name=\"url\" stringvalue=\"http://www.sweethome3d.eu\"/>\n                <attr name=\"description\" stringvalue=\"Sweet Home 3D is an interior design Java application for quickly choosing and placing\n                                                      furniture on a house 2D plan drawn by the end-user, with a final 3D preview.\"/>\n            </folder>\n            <folder name=\"aTunes.def\">\n                <attr name=\"mainClass\" stringvalue=\"net.sourceforge.atunes.Main\"/>\n                <attr name=\"displayName\" stringvalue=\"aTunes\"/>\n                <attr name=\"url\" stringvalue=\"http://www.atunes.org\"/>\n                <attr name=\"description\" stringvalue=\"aTunes is a powerful, full-featured, cross-platform player and manager,\n                                                      with audio cd rip frontend. Currently supported formats are mp3, ogg, wav,\n                                                      wma, flac, mp4, ape, mpc, mac, radio streaming and podcasts.\"/>\n            </folder>\n            <folder name=\"squirrelSql.def\">\n                <attr name=\"mainClass\" stringvalue=\"net.sourceforge.squirrel_sql.client.Main\"/>\n                <attr name=\"displayName\" stringvalue=\"SquirrelSQL\"/>\n                <attr name=\"description\" stringvalue=\"SQuirreL SQL Client is a graphical SQL client written in Java that will\n                                                      allow you to view the structure of a JDBC compliant database, browse the\n                                                      data in tables, issue SQL commands etc.\"/>\n                <attr name=\"url\" stringvalue=\"http://www.squirrelsql.org\"/>\n            </folder>\n            <folder name=\"hsql-server.def\">\n                <attr name=\"mainClass\" stringvalue=\"org.hsqldb.Server\"/>\n                <attr name=\"displayName\" stringvalue=\"HSQLDB Server\"/>\n                <attr name=\"description\" stringvalue=\"HSQLDB is a relational database engine written in Java, with a JDBC driver,\n                                                      supporting a large subset of ANSI-92 SQL. A small, fast engine with both in memory and disk\n                                                      based tables. This product is the continuation of HypersonicSQL.\"/>\n                <attr name=\"url\" stringvalue=\"http://hsqldb.org\"/>\n            </folder>\n            <folder name=\"hsql-manager.def\">\n                <attr name=\"mainClass\" stringvalue=\"org.hsqldb.util.DatabaseManager\"/>\n                <attr name=\"displayName\" stringvalue=\"HSQLDB Manager\"/>\n                <attr name=\"description\" stringvalue=\"HSQLDB is a relational database engine written in Java, with a JDBC driver,\n                                                      supporting a large subset of ANSI-92 SQL. A small, fast engine with both in memory and disk\n                                                      based tables. This product is the continuation of HypersonicSQL.\"/>\n                <attr name=\"url\" stringvalue=\"http://hsqldb.org\"/>\n            </folder>\n            <folder name=\"hsql-web.def\">\n                <attr name=\"mainClass\" stringvalue=\"org.hsqldb.WebServer\"/>\n                <attr name=\"displayName\" stringvalue=\"HSQLDB WebServer\"/>\n                <attr name=\"description\" stringvalue=\"HSQLDB is a relational database engine written in Java, with a JDBC driver,\n                                                      supporting a large subset of ANSI-92 SQL. A small, fast engine with both in memory and disk\n                                                      based tables. This product is the continuation of HypersonicSQL.\"/>\n                <attr name=\"url\" stringvalue=\"http://hsqldb.org\"/>\n            </folder>\n            <folder name=\"artofillusion.def\">\n                <attr name=\"mainClass\" stringvalue=\"artofillusion.ArtOfIllusion\"/>\n                <attr name=\"displayName\" stringvalue=\"ArtOfIllusion 3D\"/>\n                <attr name=\"url\" stringvalue=\"http://www.artofillusion.org\"/>\n                <attr name=\"description\" stringvalue=\"Art of Illusion is a full featured 3D modelling, rendering, and animation studio.\n                                                      It is written entirely in Java, and can run on almost any operating system.\"/>\n            </folder>\n            <folder name=\"tuxguitar.def\">\n                <attr name=\"mainClass\" stringvalue=\"org.herac.tuxguitar.gui.TGMain\"/>\n                <attr name=\"displayName\" stringvalue=\"TuxGuitar\"/>\n                <attr name=\"description\" stringvalue=\"TuxGuitar is a multitrack guitar tablature editor and player written in Java-SWT.\n                                                      It can open GuitarPro, PowerTab and TablEdit files.\"/>\n                <attr name=\"url\" stringvalue=\"http://www.tuxguitar.com.ar\"/>\n            </folder>\n            <folder name=\"jython.def\">\n                <attr name=\"mainClass\" stringvalue=\"org.python.util.jython\"/>\n                <attr name=\"displayName\" stringvalue=\"Jython\"/>\n                <attr name=\"description\" stringvalue=\"Jython is a Java implementation of the Python language. It allows users to compile\n                                                      Python source code to Java byte codes, and run the resulting bytecodes on any\n                                                      Java Virtual Machine. It is the successor to JPython.\"/>\n                <attr name=\"url\" stringvalue=\"http://www.jython.org\"/>\n            </folder>\n            \n        </folder>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "plugins/extensions/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.extensions\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.extensions.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/extensions/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.extensions/2\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/extensions/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/extensions/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "plugins/extensions/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.extensions-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/extensions/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=81664b27\nbuild.xml.script.CRC32=dcc223e1\nbuild.xml.stylesheet.CRC32=05353c81\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=7dd7675e\nnbproject/build-impl.xml.script.CRC32=d3d069fa\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "plugins/extensions/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\njavac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Luis-Miguel Alventosa, Tomas Hurka\ncp.extra=${tools.jar}\nmodule.javadoc.packages=org.graalvm.visualvm.modules.extensions.*\n"
  },
  {
    "path": "plugins/extensions/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.extensions</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/extensions/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/extensions/src/org/graalvm/visualvm/modules/extensions/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Platform\nOpenIDE-Module-Long-Description=\\\n    The intent of this module is to add support for additional functionality (such as new JDKs, JVMs, HotSpot versions, ...) not supported by the VisualVM core modules at the time this VisualVM was released.\nOpenIDE-Module-Name=VisualVM-Extensions\nOpenIDE-Module-Short-Description=Extends VisualVM core functionality.\n\n"
  },
  {
    "path": "plugins/extensions/src/org/graalvm/visualvm/modules/extensions/DiabloJvmJvmstatModelProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.extensions;\n\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\n\n/**\n * Detects Diablo JVM 1.5 (FreeBSD)\n * Note that Diablo JVM 1.6 is detected by default VisualVM implemntation\n * \n * @author Tomas Hurka\n */\npublic class DiabloJvmJvmstatModelProvider extends AbstractModelProvider<JvmJvmstatModel, Application> {\n    \n    public JvmJvmstatModel createModelFor(Application app) {\n        JvmstatModel jvmstat = JvmstatModelFactory.getJvmstatFor(app);\n        if (jvmstat != null) {\n            String vmVersion = jvmstat.findByName(\"java.property.java.vm.version\"); // NOI18N\n\n            if (vmVersion != null) {\n                if (vmVersion.startsWith(\"diablo-1.5.\")) {  // NOI18N // Diablo VM\n                    return new ExtendedJvmJvmstatModel(app, jvmstat);\n                }\n            }\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "plugins/extensions/src/org/graalvm/visualvm/modules/extensions/ExtendedJvmJvmstatModel.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.extensions;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.MonitoredValue;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ExtendedJvmJvmstatModel extends JvmJvmstatModel {\n    private static final String PERM_GEN_PREFIX = \"sun.gc.generation.2.\";   // NOI18N\n\n    ExtendedJvmJvmstatModel(Application app,JvmstatModel stat) {\n        super(app,stat);\n        initMonitoredValues();\n    }\n\n    private void initMonitoredValues() {\n      loadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.loadedClasses\");   // NOI18N\n      sharedLoadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.sharedLoadedClasses\");   // NOI18N\n      sharedUnloadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.sharedUnloadedClasses\");   // NOI18N\n      unloadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.unloadedClasses\");   // NOI18N\n      threadsDaemon = jvmstat.findMonitoredValueByName(\"java.threads.daemon\");  // NOI18N\n      threadsLive = jvmstat.findMonitoredValueByName(\"java.threads.live\");  // NOI18N\n      threadsLivePeak = jvmstat.findMonitoredValueByName(\"java.threads.livePeak\");  // NOI18N\n      threadsStarted = jvmstat.findMonitoredValueByName(\"java.threads.started\");    // NOI18N\n      applicationTime = jvmstat.findMonitoredValueByName(\"sun.rt.applicationTime\"); // NOI18N\n      upTime = jvmstat.findMonitoredValueByName(\"sun.os.hrt.ticks\");    // NOI18N\n      MonitoredValue osFrequencyMon = jvmstat.findMonitoredValueByName(\"sun.os.hrt.frequency\"); // NOI18N\n      osFrequency = getLongValue(osFrequencyMon);\n      genCapacity = jvmstat.findMonitoredValueByPattern(\"sun.gc.generation.[0-9]+.capacity\");   // NOI18N\n      genUsed = jvmstat.findMonitoredValueByPattern(\"sun.gc.generation.[0-9]+.space.[0-9]+.used\");  // NOI18N\n      genMaxCapacity=getGenerationSum(jvmstat.findMonitoredValueByPattern(\"sun.gc.generation.[0-9]+.maxCapacity\")); // NOI18N\n    }\n\n    protected String getPermGenPrefix() {\n        return PERM_GEN_PREFIX;\n    }\n    \n}\n"
  },
  {
    "path": "plugins/extensions/src/org/graalvm/visualvm/modules/extensions/Installer.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.extensions;\n\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory;\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle.\n */\npublic class Installer extends ModuleInstall {\n    @Override\n    public void restored() {\n        JvmJvmstatModelFactory factory = JvmJvmstatModelFactory.getDefault();\n        \n        factory.registerProvider(new SapJvmJvmstatModelProvider());\n        factory.registerProvider(new DiabloJvmJvmstatModelProvider());\n    }\n}\n"
  },
  {
    "path": "plugins/extensions/src/org/graalvm/visualvm/modules/extensions/SapJvmJvmstatModelProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.extensions;\n\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\n\n/**\n * Detects SAP JVM\n * @author Tomas Hurka\n */\npublic class SapJvmJvmstatModelProvider extends AbstractModelProvider<JvmJvmstatModel, Application> {\n    \n    public JvmJvmstatModel createModelFor(Application app) {\n        JvmstatModel jvmstat = JvmstatModelFactory.getJvmstatFor(app);\n        if (jvmstat != null) {\n            String vmName = jvmstat.findByName(\"java.property.java.vm.name\");   // NOI18N\n            \n            if (vmName != null && vmName.startsWith(\"SAP Java \")) {  // NOI18N\n                String vmVersion = jvmstat.findByName(\"java.property.java.vm.version\"); // NOI18N\n                \n                if (vmVersion != null) {\n                    if (vmVersion.startsWith(\"5.1\")) {  // NOI18N // SAP VM\n                        return new ExtendedJvmJvmstatModel(app, jvmstat);\n                    }\n                }\n            }\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "plugins/glassfish/amx-api/DUAL_LICENSE.txt",
    "content": "LICENSE #1: \n\nThe GNU General Public License (GPL) Version 2, June 1991 \n\nCopyright (C) 1989, 1991 Free Software Foundation, Inc.\n\n59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\nEveryone is permitted to copy and distribute verbatim copies\nof this license document, but changing it is not allowed.\n\nPreamble\n\nThe licenses for most software are designed to take away\nyour freedom to share and change it. By contrast, the GNU\nGeneral Public License is intended to guarantee your freedom\nto share and change free software--to make sure the software\nis free for all its users. This General Public License\napplies to most of the Free Software Foundation's software\nand to any other program whose authors commit to using it.\n(Some other Free Software Foundation software is covered by\nthe GNU Library General Public License instead.) You can\napply it to your programs, too. When we speak of free\nsoftware, we are referring to freedom, not price. Our\nGeneral Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and\ncharge for this service if you wish), that you receive\nsource code or can get it if you want it, that you can\nchange the software or use pieces of it in new free\nprograms; and that you know you can do these things. To\nprotect your rights, we need to make restrictions that\nforbid anyone to deny you these rights or to ask you to\nsurrender the rights. These restrictions translate to\ncertain responsibilities for you if you distribute copies of\nthe software, or if you modify it.\n\nFor example, if you distribute copies of such a program,\nwhether gratis or for a fee, you must give the recipients\nall the rights that you have. You must make sure that they,\ntoo, receive or can get the source code. And you must show\nthem these terms so they know their rights.\n\nWe protect your rights with two steps: (1) copyright the\nsoftware, and (2) offer you this license which gives you\nlegal permission to copy, distribute and/or modify the\nsoftware.\n\nAlso, for each author's protection and ours, we want to make\ncertain that everyone understands that there is no warranty\nfor this free software. If the software is modified by\nsomeone else and passed on, we want its recipients to know\nthat what they have is not the original, so that any\nproblems introduced by others will not reflect on the\noriginal authors' reputations.\n\nFinally, any free program is threatened constantly by\nsoftware patents. We wish to avoid the danger that\nredistributors of a free program will individually obtain\npatent licenses, in effect making the program proprietary.\nTo prevent this, we have made it clear that any patent must\nbe licensed for everyone's free use or not licensed at all.\n\nThe precise terms and conditions for copying, distribution\nand modification follow.\n\nTERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND\nMODIFICATION\n\n0. This License applies to any program or other work which\ncontains a notice placed by the copyright holder saying it\nmay be distributed under the terms of this General Public\nLicense. The \"Program\", below, refers to any such program or\nwork, and a \"work based on the Program\" means either the\nProgram or any derivative work under copyright law: that is\nto say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into\nanother language. (Hereinafter, translation is included\nwithout limitation in the term \"modification\".) Each\nlicensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification\nare not covered by this License; they are outside its scope.\nThe act of running the Program is not restricted, and the\noutput from the Program is covered only if its contents\nconstitute a work based on the Program (independent of\nhaving been made by running the Program). Whether that is\ntrue depends on what the Program does.\n\n1. You may copy and distribute verbatim copies of the\nProgram's source code as you receive it, in any medium,\nprovided that you conspicuously and appropriately publish on\neach copy an appropriate copyright notice and disclaimer of\nwarranty; keep intact all the notices that refer to this\nLicense and to the absence of any warranty; and give any\nother recipients of the Program a copy of this License along\nwith the Program.\n\nYou may charge a fee for the physical act of transferring a\ncopy, and you may at your option offer warranty protection\nin exchange for a fee.\n\n2. You may modify your copy or copies of the Program or any\nportion of it, thus forming a work based on the Program, and\ncopy and distribute such modifications or work under the\nterms of Section 1 above, provided that you also meet all of\nthese conditions:\n\na) You must cause the modified files to carry prominent\nnotices stating that you changed the files and the date of\nany change.\n\nb) You must cause any work that you distribute or publish,\nthat in whole or in part contains or is derived from the\nProgram or any part thereof, to be licensed as a whole at no\ncharge to all third parties under the terms of this License.\n\nc) If the modified program normally reads commands\ninteractively when run, you must cause it, when started\nrunning for such interactive use in the most ordinary way,\nto print or display an announcement including an appropriate\ncopyright notice and a notice that there is no warranty (or\nelse, saying that you provide a warranty) and that users may\nredistribute the program under these conditions, and telling\nthe user how to view a copy of this License. (Exception: if\nthe Program itself is interactive but does not normally\nprint such an announcement, your work based on the Program\nis not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole. If\nidentifiable sections of that work are not derived from the\nProgram, and can be reasonably considered independent and\nseparate works in themselves, then this License, and its\nterms, do not apply to those sections when you distribute\nthem as separate works. But when you distribute the same\nsections as part of a whole which is a work based on the\nProgram, the distribution of the whole must be on the terms\nof this License, whose permissions for other licensees\nextend to the entire whole, and thus to each and every part\nregardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights\nor contest your rights to work written entirely by you;\nrather, the intent is to exercise the right to control the\ndistribution of derivative or collective works based on the\nProgram. In addition, mere aggregation of another work not\nbased on the Program with the Program (or with a work based\non the Program) on a volume of a storage or distribution\nmedium does not bring the other work under the scope of this\nLicense.\n\n3. You may copy and distribute the Program (or a work based\non it, under Section 2) in object code or executable form\nunder the terms of Sections 1 and 2 above provided that you\nalso do one of the following:\n\na) Accompany it with the complete corresponding\nmachine-readable source code, which must be distributed\nunder the terms of Sections 1 and 2 above on a medium\ncustomarily used for software interchange; or,\n\nb) Accompany it with a written offer, valid for at least\nthree years, to give any third party, for a charge no more\nthan your cost of physically performing source distribution,\na complete machine-readable copy of the corresponding source\ncode, to be distributed under the terms of Sections 1 and 2\nabove on a medium customarily used for software interchange;\nor,\n\nc) Accompany it with the information you received as to the\noffer to distribute corresponding source code. (This\nalternative is allowed only for noncommercial distribution\nand only if you received the program in object code or\nexecutable form with such an offer, in accord with\nSubsection b above.)\n\nThe source code for a work means the preferred form of the\nwork for making modifications to it. For an executable work,\ncomplete source code means all the source code for all\nmodules it contains, plus any associated interface\ndefinition files, plus the scripts used to control\ncompilation and installation of the executable. However, as\na special exception, the source code distributed need not\ninclude anything that is normally distributed (in either\nsource or binary form) with the major components (compiler,\nkernel, and so on) of the operating system on which the\nexecutable runs, unless that component itself accompanies\nthe executable. If distribution of executable or object code\nis made by offering access to copy from a designated place,\nthen offering equivalent access to copy the source code from\nthe same place counts as distribution of the source code,\neven though third parties are not compelled to copy the\nsource along with the object code.\n\n4. You may not copy, modify, sublicense, or distribute the\nProgram except as expressly provided under this License. Any\nattempt otherwise to copy, modify, sublicense or distribute\nthe Program is void, and will automatically terminate your\nrights under this License. However, parties who have\nreceived copies, or rights, from you under this License will\nnot have their licenses terminated so long as such parties\nremain in full compliance.\n\n5. You are not required to accept this License, since you\nhave not signed it. However, nothing else grants you\npermission to modify or distribute the Program or its\nderivative works. These actions are prohibited by law if you\ndo not accept this License. Therefore, by modifying or\ndistributing the Program (or any work based on the Program),\nyou indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or\nmodifying the Program or works based on it.\n\n6. Each time you redistribute the Program (or any work based\non the Program), the recipient automatically receives a\nlicense from the original licensor to copy, distribute or\nmodify the Program subject to these terms and conditions.\nYou may not impose any further restrictions on the\nrecipients' exercise of the rights granted herein. You are\nnot responsible for enforcing compliance by third parties to\nthis License.\n\n7. If, as a consequence of a court judgment or allegation of\npatent infringement or for any other reason (not limited to\npatent issues), conditions are imposed on you (whether by\ncourt order, agreement or otherwise) that contradict the\nconditions of this License, they do not excuse you from the\nconditions of this License. If you cannot distribute so as\nto satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a\nconsequence you may not distribute the Program at all. For\nexample, if a patent license would not permit royalty-free\nredistribution of the Program by all those who receive\ncopies directly or indirectly through you, then the only way\nyou could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or\nunenforceable under any particular circumstance, the balance\nof the section is intended to apply and the section as a\nwhole is intended to apply in other circumstances. It is not\nthe purpose of this section to induce you to infringe any\npatents or other property right claims or to contest\nvalidity of any such claims; this section has the sole\npurpose of protecting the integrity of the free software\ndistribution system, which is implemented by public license\npractices. Many people have made generous contributions to\nthe wide range of software distributed through that system\nin reliance on consistent application of that system; it is\nup to the author/donor to decide if he or she is willing to\ndistribute software through any other system and a licensee\ncannot impose that choice.\n\nThis section is intended to make thoroughly clear what is\nbelieved to be a consequence of the rest of this License.\n\n8. If the distribution and/or use of the Program is\nrestricted in certain countries either by patents or by\ncopyrighted interfaces, the original copyright holder who\nplaces the Program under this License may add an explicit\ngeographical distribution limitation excluding those\ncountries, so that distribution is permitted only in or\namong countries not thus excluded. In such case, this\nLicense incorporates the limitation as if written in the\nbody of this License.\n\n9. The Free Software Foundation may publish revised and/or\nnew versions of the General Public License from time to\ntime. Such new versions will be similar in spirit to the\npresent version, but may differ in detail to address new\nproblems or concerns.\n\nEach version is given a distinguishing version number. If\nthe Program specifies a version number of this License which\napplies to it and \"any later version\", you have the option\nof following the terms and conditions either of that version\nor of any later version published by the Free Software\nFoundation. If the Program does not specify a version number\nof this License, you may choose any version ever published\nby the Free Software Foundation.\n\n10. If you wish to incorporate parts of the Program into\nother free programs whose distribution conditions are\ndifferent, write to the author to ask for permission. For\nsoftware which is copyrighted by the Free Software\nFoundation, write to the Free Software Foundation; we\nsometimes make exceptions for this. Our decision will be\nguided by the two goals of preserving the free status of all\nderivatives of our free software and of promoting the\nsharing and reuse of software generally.\n\nNO WARRANTY\n\n11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS\nNO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE\nCOPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM\n\"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR\nIMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE\nOF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE\nDEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED\nTO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY\nWHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED\nABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,\nSPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF\nTHE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT\nLIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR\nLOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE\nPROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH\nHOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\nEND OF TERMS AND CONDITIONS\n\nHow to Apply These Terms to Your New Programs\n\nIf you develop a new program, and you want it to be of the\ngreatest possible use to the public, the best way to achieve\nthis is to make it free software which everyone can\nredistribute and change under these terms.\n\nTo do so, attach the following notices to the program. It is\nsafest to attach them to the start of each source file to\nmost effectively convey the exclusion of warranty; and each\nfile should have at least the \"copyright\" line and a pointer\nto where the full notice is found.\n\nOne line to give the program's name and a brief idea of what\nit does.\n\nCopyright (C) <year> <name of author>\nThis program is free software; you can redistribute it\nand/or modify it under the terms of the GNU General Public\nLicense as published by the Free Software Foundation; either\nversion 2 of the License, or (at your option) any later\nversion. This program is distributed in the hope that it\nwill be useful, but WITHOUT ANY WARRANTY; without even the\nimplied warranty of MERCHANTABILITY or FITNESS FOR A\nPARTICULAR PURPOSE. See the GNU General Public License for\nmore details. You should have received a copy of the GNU\nGeneral Public License along with this program; if not,\nwrite to the Free Software Foundation, Inc., 59 Temple\nPlace, Suite 330, Boston, MA 02111-1307 USA\n\nAlso add information on how to contact you by electronic and\npaper mail. If the program is interactive, make it output a\nshort notice like this when it starts in an interactive\nmode:\n\nGnomovision version 69, Copyright (C) year name of author\nGnomovision comes with ABSOLUTELY NO WARRANTY; for details\ntype `show w'. This is free software, and you are welcome to\nredistribute it under certain conditions; type `show c' for\ndetails. The hypothetical commands `show w' and `show c'\nshould show the appropriate parts of the General Public\nLicense. Of course, the commands you use may be called\nsomething other than `show w' and `show c'; they could even\nbe mouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a\nprogrammer) or your school, if any, to sign a \"copyright\ndisclaimer\" for the program, if necessary. Here is a sample;\nalter the names:\n\nYoyodyne, Inc., hereby disclaims all copyright interest in\nthe program `Gnomovision' (which makes passes at compilers)\nwritten by James Hacker.\n\nsignature of Ty Coon, 1 April 1989\nTy Coon, President of Vice\nThis General Public License does not permit incorporating\nyour program into proprietary programs. If your program is a\nsubroutine library, you may consider it more useful to\npermit linking proprietary applications with the library. If\nthis is what you want to do, use the GNU Library General\nPublic License instead of this License.\n\n\"CLASSPATH\" EXCEPTION TO THE GPL VERSION 2\n\nCertain source files distributed by Sun Microsystems, Inc. \nare subject to  the following clarification and special\nexception to the GPL Version 2, but only where Sun has\nexpressly included in the particular source file's header\nthe words  \"Sun designates this particular file as subject\nto the \"Classpath\" exception as provided by Sun in the\nLicense file that accompanied this code.\" \n\n   Linking this library statically or dynamically with other\nmodules is making a combined work based on this library. \nThus, the terms and conditions of the GNU General Public\nLicense Version 2 cover the whole combination. \n\n  As a special exception, the copyright holders of this\nlibrary give you  permission to link this library with\nindependent modules to produce an  executable, regardless of\nthe license terms of these independent modules,  and to copy\nand distribute the resulting executable under terms of your \nchoice, provided that you also meet, for each linked\nindependent module,  the terms and conditions of the license\nof that module.  An independent  module is a module which is\nnot derived from or based on this library.  If  you modify\nthis library, you may extend this exception to your version\nof  the library, but you are not obligated to do so.  If you\ndo not wish to do so, delete this exception statement from\nyour version.\n\n***********************************************************\n\nLICENSE #2: \n\nCOMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version\n1.0\n\n1. Definitions.\n1.1. \"Contributor\" means each individual or entity that\ncreates or contributes to the creation of Modifications.\n\n1.2. \"Contributor Version\" means the combination of the\nOriginal Software, prior Modifications used by a\nContributor (if any), and the Modifications made by that\nparticular Contributor.\n\n1.3. \"Covered Software\" means (a) the Original Software, or\n(b) Modifications, or (c) the combination of files\ncontaining Original Software with files containing\nModifications, in each case including portions thereof.\n\n1.4. \"Executable\" means the Covered Software in any form\nother than Source Code. \n\n1.5. \"Initial Developer\" means the individual or entity\nthat first makes Original Software available under this\nLicense. \n\n1.6. \"Larger Work\" means a work which combines Covered\nSoftware or portions thereof with code not governed by the\nterms of this License.\n\n1.7. \"License\" means this document.\n\n1.8. \"Licensable\" means having the right to grant, to the\nmaximum extent possible, whether at the time of the initial\ngrant or subsequently acquired, any and all of the rights\nconveyed herein.\n\n1.9. \"Modifications\" means the Source Code and Executable\nform of any of the following:\n \nA. Any file that results from an addition to,\ndeletion from or modification of the contents of a\nfile containing Original Software or previous\nModifications; \n\nB. Any new file that contains any part of the\nOriginal Software or previous Modification; or \n\nC. Any new file that is contributed or otherwise made\navailable under the terms of this License.\n\n1.10. \"Original Software\" means the Source Code and\nExecutable form of computer software code that is\noriginally released under this License. \n\n1.11. \"Patent Claims\" means any patent claim(s), now owned\nor hereafter acquired, including without limitation,\nmethod, process, and apparatus claims, in any patent\nLicensable by grantor. \n\n1.12. \"Source Code\" means (a) the common form of computer\nsoftware code in which modifications are made and (b)\nassociated documentation included in or with such code.\n\n1.13. \"You\" (or \"Your\") means an individual or a legal\nentity exercising rights under, and complying with all of\nthe terms of, this License. For legal entities, \"You\"\nincludes any entity which controls, is controlled by, or is\nunder common control with You. For purposes of this\ndefinition, \"control\" means (a) the power, direct or\nindirect, to cause the direction or management of such\nentity, whether by contract or otherwise, or (b) ownership\nof more than fifty percent (50%) of the outstanding shares\nor beneficial ownership of such entity.\n\n2. License Grants. \n\n2.1. The Initial Developer Grant.\nConditioned upon Your compliance with Section 3.1 below and\nsubject to third party intellectual property claims, the\nInitial Developer hereby grants You a world-wide,\nroyalty-free, non-exclusive license: \n\n(a) under intellectual property rights (other than\npatent or trademark) Licensable by Initial Developer,\nto use, reproduce, modify, display, perform,\nsublicense and distribute the Original Software (or\nportions thereof), with or without Modifications,\nand/or as part of a Larger Work; and \n\n(b) under Patent Claims infringed by the making,\nusing or selling of Original Software, to make, have\nmade, use, practice, sell, and offer for sale, and/or\notherwise dispose of the Original Software (or\nportions thereof). \n\n(c) The licenses granted in Sections 2.1(a) and (b)\nare effective on the date Initial Developer first\ndistributes or otherwise makes the Original Software\navailable to a third party under the terms of this\nLicense. \n\n(d) Notwithstanding Section 2.1(b) above, no patent\nlicense is granted: (1) for code that You delete from\nthe Original Software, or (2) for infringements\ncaused by: (i) the modification of the Original\nSoftware, or (ii) the combination of the Original\nSoftware with other software or devices. \n\n2.2. Contributor Grant.\nConditioned upon Your compliance with Section 3.1 below and\nsubject to third party intellectual property claims, each\nContributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\n(a) under intellectual property rights (other than\npatent or trademark) Licensable by Contributor to\nuse, reproduce, modify, display, perform, sublicense\nand distribute the Modifications created by such\nContributor (or portions thereof), either on an\nunmodified basis, with other Modifications, as\nCovered Software and/or as part of a Larger Work; and\n\n(b) under Patent Claims infringed by the making,\nusing, or selling of Modifications made by that\nContributor either alone and/or in combination with\nits Contributor Version (or portions of such\ncombination), to make, use, sell, offer for sale,\nhave made, and/or otherwise dispose of: (1)\nModifications made by that Contributor (or portions\nthereof); and (2) the combination of Modifications\nmade by that Contributor with its Contributor Version\n(or portions of such combination). \n\n(c) The licenses granted in Sections 2.2(a) and\n2.2(b) are effective on the date Contributor first\ndistributes or otherwise makes the Modifications\navailable to a third party. \n\n(d) Notwithstanding Section 2.2(b) above, no patent\nlicense is granted: (1) for any code that Contributor\nhas deleted from the Contributor Version; (2) for\ninfringements caused by: (i) third party\nmodifications of Contributor Version, or (ii) the\ncombination of Modifications made by that Contributor\nwith other software (except as part of the\nContributor Version) or other devices; or (3) under\nPatent Claims infringed by Covered Software in the\nabsence of Modifications made by that Contributor. \n\n3. Distribution Obligations.\n\n3.1. Availability of Source Code.\nAny Covered Software that You distribute or otherwise make\navailable in Executable form must also be made available in\nSource Code form and that Source Code form must be\ndistributed only under the terms of this License. You must\ninclude a copy of this License with every copy of the Source\nCode form of the Covered Software You distribute or\notherwise make available. You must inform recipients of any\nsuch Covered Software in Executable form as to how they can\nobtain such Covered Software in Source Code form in a\nreasonable manner on or through a medium customarily used\nfor software exchange.\n\n3.2. Modifications.\nThe Modifications that You create or to which You\ncontribute are governed by the terms of this License. You\nrepresent that You believe Your Modifications are Your\noriginal creation(s) and/or You have sufficient rights to\ngrant the rights conveyed by this License.\n\n3.3. Required Notices.\nYou must include a notice in each of Your Modifications\nthat identifies You as the Contributor of the Modification.\nYou may not remove or alter any copyright, patent or\ntrademark notices contained within the Covered Software, or\nany notices of licensing or any descriptive text giving\nattribution to any Contributor or the Initial Developer.\n\n3.4. Application of Additional Terms.\nYou may not offer or impose any terms on any Covered\nSoftware in Source Code form that alters or restricts the\napplicable version of this License or the recipients'\nrights hereunder. You may choose to offer, and to charge a\nfee for, warranty, support, indemnity or liability\nobligations to one or more recipients of Covered Software.\nHowever, you may do so only on Your own behalf, and not on\nbehalf of the Initial Developer or any Contributor. You\nmust make it absolutely clear that any such warranty,\nsupport, indemnity or liability obligation is offered by\nYou alone, and You hereby agree to indemnify the Initial\nDeveloper and every Contributor for any liability incurred\nby the Initial Developer or such Contributor as a result of\nwarranty, support, indemnity or liability terms You offer.\n\n3.5. Distribution of Executable Versions.\nYou may distribute the Executable form of the Covered\nSoftware under the terms of this License or under the terms\nof a license of Your choice, which may contain terms\ndifferent from this License, provided that You are in\ncompliance with the terms of this License and that the\nlicense for the Executable form does not attempt to limit\nor alter the recipient's rights in the Source Code form\nfrom the rights set forth in this License. If You\ndistribute the Covered Software in Executable form under a\ndifferent license, You must make it absolutely clear that\nany terms which differ from this License are offered by You\nalone, not by the Initial Developer or Contributor. You\nhereby agree to indemnify the Initial Developer and every\nContributor for any liability incurred by the Initial\nDeveloper or such Contributor as a result of any such terms\nYou offer.\n\n3.6. Larger Works.\nYou may create a Larger Work by combining Covered Software\nwith other code not governed by the terms of this License\nand distribute the Larger Work as a single product. In such\na case, You must make sure the requirements of this License\nare fulfilled for the Covered Software. \n\n4. Versions of the License. \n\n4.1. New Versions.\nSun Microsystems, Inc. is the initial license steward and\nmay publish revised and/or new versions of this License\nfrom time to time. Each version will be given a\ndistinguishing version number. Except as provided in\nSection 4.3, no one other than the license steward has the\nright to modify this License. \n\n4.2. Effect of New Versions.\nYou may always continue to use, distribute or otherwise\nmake the Covered Software available under the terms of the\nversion of the License under which You originally received\nthe Covered Software. If the Initial Developer includes a\nnotice in the Original Software prohibiting it from being\ndistributed or otherwise made available under any\nsubsequent version of the License, You must distribute and\nmake the Covered Software available under the terms of the\nversion of the License under which You originally received\nthe Covered Software. Otherwise, You may also choose to\nuse, distribute or otherwise make the Covered Software\navailable under the terms of any subsequent version of the\nLicense published by the license steward. \n\n4.3. Modified Versions.\nWhen You are an Initial Developer and You want to create a\nnew license for Your Original Software, You may create and\nuse a modified version of this License if You: (a) rename\nthe license and remove any references to the name of the\nlicense steward (except to note that the license differs\nfrom this License); and (b) otherwise make it clear that\nthe license contains terms which differ from this License.\n\n5. DISCLAIMER OF WARRANTY.\n\nCOVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN \"AS\nIS\" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR\nIMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE\nCOVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A\nPARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO\nTHE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH\nYOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY\nRESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER\nCONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING,\nREPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY\nCONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY\nCOVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS\nDISCLAIMER. \n\n6. TERMINATION. \n\n6.1. This License and the rights granted hereunder will\nterminate automatically if You fail to comply with terms\nherein and fail to cure such breach within 30 days of\nbecoming aware of the breach. Provisions which, by their\nnature, must remain in effect beyond the termination of\nthis License shall survive.\n\n6.2. If You assert a patent infringement claim (excluding\ndeclaratory judgment actions) against Initial Developer or\na Contributor (the Initial Developer or Contributor against\nwhom You assert such claim is referred to as \"Participant\")\nalleging that the Participant Software (meaning the\nContributor Version where the Participant is a Contributor\nor the Original Software where the Participant is the\nInitial Developer) directly or indirectly infringes any\npatent, then any and all rights granted directly or\nindirectly to You by such Participant, the Initial\nDeveloper (if the Initial Developer is not the Participant)\nand all Contributors under Sections 2.1 and/or 2.2 of this\nLicense shall, upon 60 days notice from Participant\nterminate prospectively and automatically at the expiration\nof such 60 day notice period, unless if within such 60 day\nperiod You withdraw Your claim with respect to the\nParticipant Software against such Participant either\nunilaterally or pursuant to a written agreement with\nParticipant.\n\n6.3. In the event of termination under Sections 6.1 or 6.2\nabove, all end user licenses that have been validly granted\nby You or any distributor hereunder prior to termination\n(excluding licenses granted to You by any distributor)\nshall survive termination.\n\n7. LIMITATION OF LIABILITY.\n\nUNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER\nTORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL\nYOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY\nDISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF\nSUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT,\nSPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY\nCHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST\nPROFITS, LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE\nOR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR\nLOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE\nPOSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY\nSHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY\nRESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT\nAPPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS\nDO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR\nCONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY\nNOT APPLY TO YOU.\n\n8. U.S. GOVERNMENT END USERS.\n\nThe Covered Software is a \"commercial item,\" as that term is\ndefined in 48 C.F.R. 2.101 (Oct. 1995), consisting of\n\"commercial computer software\" (as that term is defined at\n48 C.F.R. ¤ 252.227-7014(a)(1)) and \"commercial computer\nsoftware documentation\" as such terms are used in 48 C.F.R.\n12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48\nC.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S.\nGovernment End Users acquire Covered Software with only\nthose rights set forth herein. This U.S. Government Rights\nclause is in lieu of, and supersedes, any other FAR, DFAR,\nor other clause or provision that addresses Government\nrights in computer software under this License.\n\n9. MISCELLANEOUS.\n\nThis License represents the complete agreement concerning\nsubject matter hereof. If any provision of this License is\nheld to be unenforceable, such provision shall be reformed\nonly to the extent necessary to make it enforceable. This\nLicense shall be governed by the law of the jurisdiction\nspecified in a notice contained within the Original Software\n(except to the extent applicable law, if any, provides\notherwise), excluding such jurisdiction's conflict-of-law\nprovisions. Any litigation relating to this License shall be\nsubject to the jurisdiction of the courts located in the\njurisdiction and venue specified in a notice contained\nwithin the Original Software, with the losing party\nresponsible for costs, including, without limitation, court\ncosts and reasonable attorneys' fees and expenses. The\napplication of the United Nations Convention on Contracts\nfor the International Sale of Goods is expressly excluded.\nAny law or regulation which provides that the language of a\ncontract shall be construed against the drafter shall not\napply to this License. You agree that You alone are\nresponsible for compliance with the United States export\nadministration regulations (and the export control laws and\nregulation of any other countries) when You use, distribute\nor otherwise make available any Covered Software.\n\n10. RESPONSIBILITY FOR CLAIMS.\n\nAs between Initial Developer and the Contributors, each\nparty is responsible for claims and damages arising,\ndirectly or indirectly, out of its utilization of rights\nunder this License and You agree to work with Initial\nDeveloper and Contributors to distribute such responsibility\non an equitable basis. Nothing herein is intended or shall\nbe deemed to constitute any admission of liability.\n\n***********************************************************\n\n"
  },
  {
    "path": "plugins/glassfish/amx-api/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"com.sun.appserv.management\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project com.sun.appserv.management.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/glassfish/amx-api/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: com.sun.appserv.management\nOpenIDE-Module-Localizing-Bundle: com/sun/appserv/management/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.0\n\n"
  },
  {
    "path": "plugins/glassfish/amx-api/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"com.sun.appserv.management-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/glassfish/amx-api/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=f1bd27f3\nbuild.xml.script.CRC32=2e75ad6e\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=f1bd27f3\nnbproject/build-impl.xml.script.CRC32=bbfe7d07\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "plugins/glassfish/amx-api/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nis.autoload=true\nlicense.file=${basedir}/DUAL_LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n"
  },
  {
    "path": "plugins/glassfish/amx-api/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>com.sun.appserv.management</code-name-base>\n            <suite-component/>\n            <module-dependencies/>\n            <public-packages>\n                <package>com.sun.appserv.management</package>\n                <package>com.sun.appserv.management.base</package>\n                <package>com.sun.appserv.management.client</package>\n                <package>com.sun.appserv.management.client.handler</package>\n                <package>com.sun.appserv.management.client.prefs</package>\n                <package>com.sun.appserv.management.config</package>\n                <package>com.sun.appserv.management.deploy</package>\n                <package>com.sun.appserv.management.ext.lb</package>\n                <package>com.sun.appserv.management.ext.logging</package>\n                <package>com.sun.appserv.management.ext.update</package>\n                <package>com.sun.appserv.management.ext.wsmgmt</package>\n                <package>com.sun.appserv.management.helper</package>\n                <package>com.sun.appserv.management.j2ee</package>\n                <package>com.sun.appserv.management.j2ee.statistics</package>\n                <package>com.sun.appserv.management.monitor</package>\n                <package>com.sun.appserv.management.monitor.statistics</package>\n                <package>com.sun.appserv.management.util.j2ee</package>\n                <package>com.sun.appserv.management.util.j2ee.stringifier</package>\n                <package>com.sun.appserv.management.util.jmx</package>\n                <package>com.sun.appserv.management.util.jmx.stringifier</package>\n                <package>com.sun.appserv.management.util.misc</package>\n                <package>com.sun.appserv.management.util.stringifier</package>\n                <package>com.sun.enterprise.management.deploy</package>\n                <package>javax.activation</package>\n                <package>javax.annotation</package>\n                <package>javax.annotation.security</package>\n                <package>javax.ejb</package>\n                <package>javax.ejb.spi</package>\n                <package>javax.el</package>\n                <package>javax.enterprise.deploy.model</package>\n                <package>javax.enterprise.deploy.model.exceptions</package>\n                <package>javax.enterprise.deploy.shared</package>\n                <package>javax.enterprise.deploy.shared.factories</package>\n                <package>javax.enterprise.deploy.spi</package>\n                <package>javax.enterprise.deploy.spi.exceptions</package>\n                <package>javax.enterprise.deploy.spi.factories</package>\n                <package>javax.enterprise.deploy.spi.status</package>\n                <package>javax.faces</package>\n                <package>javax.faces.application</package>\n                <package>javax.faces.component</package>\n                <package>javax.faces.component.html</package>\n                <package>javax.faces.context</package>\n                <package>javax.faces.convert</package>\n                <package>javax.faces.el</package>\n                <package>javax.faces.event</package>\n                <package>javax.faces.lifecycle</package>\n                <package>javax.faces.model</package>\n                <package>javax.faces.render</package>\n                <package>javax.faces.validator</package>\n                <package>javax.faces.webapp</package>\n                <package>javax.interceptor</package>\n                <package>javax.jms</package>\n                <package>javax.jws</package>\n                <package>javax.jws.soap</package>\n                <package>javax.mail</package>\n                <package>javax.mail.event</package>\n                <package>javax.mail.internet</package>\n                <package>javax.mail.search</package>\n                <package>javax.mail.util</package>\n                <package>javax.management.j2ee</package>\n                <package>javax.management.j2ee.statistics</package>\n                <package>javax.persistence</package>\n                <package>javax.persistence.spi</package>\n                <package>javax.resource</package>\n                <package>javax.resource.cci</package>\n                <package>javax.resource.spi</package>\n                <package>javax.resource.spi.endpoint</package>\n                <package>javax.resource.spi.security</package>\n                <package>javax.resource.spi.work</package>\n                <package>javax.security.jacc</package>\n                <package>javax.servlet</package>\n                <package>javax.servlet.http</package>\n                <package>javax.servlet.jsp</package>\n                <package>javax.servlet.jsp.el</package>\n                <package>javax.servlet.jsp.jstl.core</package>\n                <package>javax.servlet.jsp.jstl.fmt</package>\n                <package>javax.servlet.jsp.jstl.sql</package>\n                <package>javax.servlet.jsp.jstl.tlv</package>\n                <package>javax.servlet.jsp.tagext</package>\n                <package>javax.transaction</package>\n                <package>javax.transaction.xa</package>\n                <package>javax.xml.bind</package>\n                <package>javax.xml.bind.annotation</package>\n                <package>javax.xml.bind.annotation.adapters</package>\n                <package>javax.xml.bind.attachment</package>\n                <package>javax.xml.bind.helpers</package>\n                <package>javax.xml.bind.util</package>\n                <package>javax.xml.registry</package>\n                <package>javax.xml.registry.infomodel</package>\n                <package>javax.xml.registry.samples</package>\n                <package>javax.xml.rpc</package>\n                <package>javax.xml.rpc.encoding</package>\n                <package>javax.xml.rpc.handler</package>\n                <package>javax.xml.rpc.handler.soap</package>\n                <package>javax.xml.rpc.holders</package>\n                <package>javax.xml.rpc.server</package>\n                <package>javax.xml.rpc.soap</package>\n                <package>javax.xml.soap</package>\n                <package>javax.xml.stream</package>\n                <package>javax.xml.stream.events</package>\n                <package>javax.xml.stream.util</package>\n                <package>javax.xml.ws</package>\n                <package>javax.xml.ws.handler</package>\n                <package>javax.xml.ws.handler.soap</package>\n                <package>javax.xml.ws.http</package>\n                <package>javax.xml.ws.soap</package>\n                <package>javax.xml.ws.spi</package>\n                <package>javax.xml.ws.wsaddressing</package>\n            </public-packages>\n            <class-path-extension>\n                <runtime-relative-path>ext/amxapi.jar</runtime-relative-path>\n                <binary-origin>release/modules/ext/amxapi.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/javaee.jar</runtime-relative-path>\n                <binary-origin>release/modules/ext/javaee.jar</binary-origin>\n            </class-path-extension>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/glassfish/amx-api/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/../..\n"
  },
  {
    "path": "plugins/glassfish/amx-api/src/com/sun/appserv/management/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Libraries\nOpenIDE-Module-Long-Description=\\\n    GlassFish AMX API Library Wrapper\nOpenIDE-Module-Name=GlassFish AMX API\nOpenIDE-Module-Short-Description=GlassFish AMX API Library Wrapper\n"
  },
  {
    "path": "plugins/glassfish/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"net.java.visualvm.modules.glassfish\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project net.java.visualvm.modules.glassfish.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/glassfish/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: net.java.visualvm.modules.glassfish\nOpenIDE-Module-Install: net/java/visualvm/modules/glassfish/Installer.class\nOpenIDE-Module-Localizing-Bundle: net/java/visualvm/modules/glassfish/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.5\n\n"
  },
  {
    "path": "plugins/glassfish/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"net.java.visualvm.modules.glassfish-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/glassfish/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=a5d05ec0\nbuild.xml.script.CRC32=42d55a6f\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=a5d05ec0\nnbproject/build-impl.xml.script.CRC32=3a954cd9\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "plugins/glassfish/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\njavac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\ncp.extra=${tools.jar}\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jaroslav Bachorik\nproject.license=GPLv2CPE\n"
  },
  {
    "path": "plugins/glassfish/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>net.java.visualvm.modules.glassfish</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>com.sun.appserv.management</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application.views</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.charts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/glassfish/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Application Servers\nOpenIDE-Module-Long-Description=\\\n    A sample plugin giving an overview of advanced monitoring capabilities of VisualVM. \\n\\\n    Enhances monitoring of GlassFish application server by adding specialized overview, new tab for monitoring HTTP Service and the ability to visually select and monitor any of the deployed web applications\nOpenIDE-Module-Name=VisualVM-Glassfish\nOpenIDE-Module-Short-Description=Enhaned monitoring of GlassFish application server\n\nManagementTabContent.jLabel1.text=jLabel1\nManagementTabContent.jLabel2.text=jLabel2\nManagementTabContent.jLabel3.text=jLabel3\nManagementTabContent.jLabel4.text=jLabel4\n\nDESCR_GlassFish=GlassFish instance (domain: {0}). GlassFish is an open source application server for the Java EE platform.\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/GlassFishApplicationType.java",
    "content": "/*\n/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage net.java.visualvm.modules.glassfish;\n\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.openide.util.ImageUtilities;\nimport java.awt.Image;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic abstract class GlassFishApplicationType extends ApplicationType {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected final String appPID;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public GlassFishApplicationType(int pid) {\n        appPID = String.valueOf(pid);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    public Image getIcon() {\n        return ImageUtilities.loadImage(\"net/java/visualvm/modules/glassfish/resources/GlassFish.png\", true);\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/GlassFishApplicationTypeFactory.java",
    "content": "/*\n/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n\npackage net.java.visualvm.modules.glassfish;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.application.type.MainClassApplicationTypeFactory;\n\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishApplicationTypeFactory extends MainClassApplicationTypeFactory {\n    private final static GlassFishApplicationTypeFactory INSTANCE = new GlassFishApplicationTypeFactory();\n    \n    private GlassFishApplicationTypeFactory() {}\n    \n    public static void initialize() {\n        ApplicationTypeFactory.getDefault().registerProvider(INSTANCE);\n    }\n    \n    public static void shutdown() {\n        ApplicationTypeFactory.getDefault().unregisterProvider(INSTANCE);\n    }\n\n    @Override\n    public ApplicationType createModelFor(Application app) {\n        Jvm jvm = JvmFactory.getJVMFor(app);\n        if (!jvm.isBasicInfoSupported()) return null;\n        if (jvm.getMainClass() != null) return super.createModelFor(app);\n        if (jvm.isGetSystemPropertiesSupported() && !jvm.getJvmArgs().contains(\"felix.fileinstall.dir\")) {\n            if (jvm.getSystemProperties().get(\"com.sun.aas.instanceName\") != null) {\n                return new GlassFishInstanceType(app, jvm);\n            }\n        }\n        return null;\n    }\n    \n    @Override\n    public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) {\n        if (!jvm.getJvmArgs().contains(\"felix.fileinstall.dir\")) {\n            if (\"com.sun.enterprise.server.PELaunch\".equals(mainClass)) {\n                return new GlassFishInstanceType(app, jvm);\n            } else if (\"com.sun.enterprise.ee.nodeagent.NodeAgentMain\".equals(mainClass)) {\n                return new GlassFishNodeType(jvm, app.getPid());\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/GlassFishInstanceType.java",
    "content": "/*\n/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage net.java.visualvm.modules.glassfish;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport java.awt.Image;\nimport java.text.MessageFormat;\nimport java.util.Properties;\nimport java.util.logging.Logger;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishInstanceType extends GlassFishApplicationType {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n    private final static Logger LOGGER = Logger.getLogger(GlassFishInstanceType.class.getName());\n    \n    private final String description = NbBundle.getMessage(GlassFishInstanceType.class, \"DESCR_GlassFish\"); // NOI18N\n    private String domainName = \"UNKNOWN\";\n    private final String typeName = \"GlassFish/SJSAS\";\n    private Jvm gfJvm;\n    \n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public GlassFishInstanceType(Application app, Jvm jvm) {\n        super(app.getPid());\n        init(app, jvm);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    public String getDescription() {\n        return MessageFormat.format(description, domainName);\n    }\n\n    @Override\n    public Image getIcon() {\n        Image icon = super.getIcon();\n\n        return ImageUtilities.mergeImages(icon,\n                                     ImageUtilities.loadImage(\"net/java/visualvm/modules/glassfish/resources/instance_badge.png\", true),\n                                     8, 8);\n    }\n\n    @Override\n    public String getName() {\n        return typeName;\n    }\n\n    @Override\n    public String getVersion() {\n        return \"0\";\n    }\n\n    private void init(Application app, Jvm jvm) {\n        try {\n            if (jvm.isGetSystemPropertiesSupported()) {\n                Properties props = jvm.getSystemProperties();\n                if (props != null) {\n                    domainName = props.getProperty(\"com.sun.aas.domainName\", domainName);\n                }\n            }\n        } catch (Exception ex) {\n            LOGGER.throwing(GlassFishInstanceType.class.getName(), \"init\", ex);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/GlassFishNodeType.java",
    "content": "/*\n/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage net.java.visualvm.modules.glassfish;\n\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.openide.util.ImageUtilities;\nimport java.awt.Image;\nimport java.text.MessageFormat;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishNodeType extends GlassFishApplicationType {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final String description = \"(agent = {0})\";\n    private final String typeName = \"GlassFish/SJSAS Node (pid {0})\";\n    private String nodeName = \"UNKNOWN\";\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public GlassFishNodeType(Jvm jvm, int pid) {\n        super(pid);\n        init(jvm);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    public String getDescription() {\n        return MessageFormat.format(description, nodeName);\n    }\n\n    @Override\n    public Image getIcon() {\n        Image icon = super.getIcon();\n\n        return ImageUtilities.mergeImages(icon,\n                                     ImageUtilities.loadImage(\"net/java/visualvm/modules/glassfish/resources/node_badge.png\", true), 8, 8);\n    }\n\n    @Override\n    public String getName() {\n        return MessageFormat.format(typeName, appPID);\n    }\n\n    @Override\n    public String getVersion() {\n        return \"0\";\n    }\n\n    private void init(Jvm jvm) {\n        Pattern pattern = Pattern.compile(\"-Dcom\\\\.sun\\\\.aas\\\\.instanceName=(.*?)\\\\s\");\n        Matcher mtchr = pattern.matcher(jvm.getJvmArgs());\n\n        if (mtchr.find()) {\n            nodeName = mtchr.group(1);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/GlassFishOverviewPlugin.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage net.java.visualvm.modules.glassfish;\n\nimport com.sun.appserv.management.DomainRoot;\nimport com.sun.appserv.management.config.ConfigConfig;\nimport com.sun.appserv.management.config.HTTPListenerConfig;\nimport com.sun.appserv.management.config.HTTPServiceConfig;\nimport com.sun.appserv.management.config.IIOPListenerConfig;\nimport com.sun.appserv.management.config.IIOPServiceConfig;\nimport com.sun.appserv.management.config.ModuleMonitoringLevelsConfig;\nimport com.sun.appserv.management.config.SystemPropertiesAccess;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent.DetailsView;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport javax.swing.event.HyperlinkEvent;\nimport net.java.visualvm.modules.glassfish.jmx.AMXUtil;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.Map;\nimport java.util.StringTokenizer;\nimport javax.swing.BorderFactory;\nimport javax.swing.SwingWorker;\nimport javax.swing.event.HyperlinkListener;\nimport net.java.visualvm.modules.glassfish.jmx.JMXUtil;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishOverviewPlugin extends DataSourceViewPlugin {\n    private JmxModel model = null;\n    \n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n    private static class GlassfishOverviewPanel extends HTMLTextArea {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n        private DomainRoot domainRoot;\n        private String serverName,  configName;\n        private JmxModel jmxModel;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n        public GlassfishOverviewPanel(DomainRoot root, JmxModel jmx) {\n            domainRoot = root;\n            jmxModel = jmx;\n            assert domainRoot != null && jmxModel != null;\n            serverName = JMXUtil.getServerName(jmx);\n            configName = JMXUtil.getServerConfig(jmx);\n            assert serverName != null && configName != null;\n            initComponents();\n        }\n\n        private void initComponents() {\n            setOpaque(true);\n            setBorder(BorderFactory.createEmptyBorder());\n            addHyperlinkListener(new HyperlinkListener() {\n                public void hyperlinkUpdate(HyperlinkEvent e) {\n                    if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {\n                        StringTokenizer st = new StringTokenizer(e.getDescription(), \"#\");\n                        String service = st.nextToken();\n                        String level = st.nextToken();\n                        setMonitoringLevel(AMXUtil.getMonitoringConfig(jmxModel), service, cycleLevel(level));\n                        setText(buildInfo());                        \n                    }\n                }\n            });\n\n           new  SwingWorker<Void, Void>() {\n                private String areaText = null;\n                @Override\n                protected Void doInBackground() throws Exception {\n                    areaText = buildInfo();\n                    return null;\n                }\n\n                @Override\n                protected void done() {\n                    if (areaText != null) setText(areaText);\n                \n                }\n            }.execute();\n        }\n\n        private Collection<String> getHTTPPorts(HTTPServiceConfig config) {\n            Map<String, HTTPListenerConfig> listeners = config.getHTTPListenerConfigMap();\n            Collection<String> ports = new ArrayList<String>();\n\n            for (String key : listeners.keySet()) {\n                String port = listeners.get(key).getPort();\n\n                if (port.startsWith(\"$\")) {\n                    port = resolveToken((port.substring(2, port.length() - 1)));\n                }\n\n                ports.add(port);\n            }\n            return ports;\n        }\n\n        private Collection<String> getIIOPPorts(IIOPServiceConfig config) {\n            //iiop ports\n            Map<String, IIOPListenerConfig> iiopListeners = config.getIIOPListenerConfigMap();\n            Collection<String> iports = new ArrayList<String>();\n            for (String key : iiopListeners.keySet()) {\n                String iport = iiopListeners.get(key).getPort();\n                if (iport.startsWith(\"$\")) {\n                    iport = resolveToken((iport.substring(2, iport.length() - 1)));\n                }\n                iports.add(iport);\n            }\n            return iports;\n        }\n\n        private String getDomain() {\n            String domain;\n            domain = JMXUtil.getServerDomain(jmxModel);\n            return domain != null ? domain : \"<UNRESOLVED\";\n        }\n\n        private String buildInfo() {\n            ConfigConfig cc = domainRoot.getDomainConfig().getConfigConfigMap().get(JMXUtil.getServerConfig(jmxModel));\n\n            StringBuilder sb = new StringBuilder();\n            sb.append(\"<h2>General information</h2>\");\n            sb.append(\"<b>Server Name: </b>\").append(serverName).append(\"<br>\");\n            sb.append(\"<b>Domain: </b>\").append(getDomain()).append(\"<br>\");\n            sb.append(\"<b>Config Dir: </b>\").append(JMXUtil.getServerConfigDir(jmxModel)).append(\"<br>\");\n            sb.append(\"<br>\");\n            sb.append(\"<b>HTTP Port(s): </b>\");\n\n            Collection<String> hports = getHTTPPorts(cc.getHTTPServiceConfig());\n            for (Iterator<String> iter = hports.iterator(); iter.hasNext();) {\n                sb.append(iter.next());\n                if (iter.hasNext()) {\n                    sb.append(\",\");\n                }\n            }\n            sb.append(\"<br>\");\n\n            sb.append(\"<b>IIOP Port(s): </b> \");\n\n            Collection<String> iports = getIIOPPorts(cc.getIIOPServiceConfig());\n            for (Iterator<String> iter = iports.iterator(); iter.hasNext();) {\n                sb.append(iter.next());\n                if (iter.hasNext()) {\n                    sb.append(\",\");\n                }\n            }\n            sb.append(\"<br><br>\");\n\n            String version = domainRoot.getJ2EEDomain().getJ2EEServerMap().get(serverName).getserverVersion();\n            sb.append(\"<b>Installed Version: </b>\").append(version).append(\"<br><br>\");\n            ModuleMonitoringLevelsConfig monitoringConfig = AMXUtil.getMonitoringConfig(jmxModel);\n            if (monitoringConfig != null) {\n                sb.append(\"<hr>\");\n                sb.append(\"<h2>Monitoring Configuration</h2>\");\n                sb.append(\"<table>\");\n                for(Map.Entry<String, String> entry : monitoringConfig.getAllLevels().entrySet()) {\n                    String color;\n                    if (entry.getValue().toUpperCase().equals(\"OFF\")) {\n                        color = \"red\";\n                    } else if (entry.getValue().toUpperCase().equals(\"LOW\")) {\n                        color = \"yellow\";\n                    } else {\n                        color = \"green\";\n                    }\n                    sb.append(\"<tr>\");\n                    sb.append(\"<td>\").append(entry.getKey()).append(\"</td>\");\n                    sb.append(\"<td style=\\\"color: \").append(color).append(\"\\\">\");\n                    sb.append(\"<a href=\\\"\").append(entry.getKey()).append(\"#\").append(entry.getValue()).append(\"\\\" alt=\\\"Click to cycle\\\">\");\n                    sb.append(entry.getValue()).append(\"</a></td>\");\n                    sb.append(\"</tr>\");\n                }\n                sb.append(\"</table>\");\n            }\n            return sb.toString();\n        }\n\n        private String resolveToken(String pn) {\n            //For EE, the instance will have its own override System Properties value instead of using the one from config.\n            if (AMXUtil.isEE(domainRoot)) {\n                SystemPropertiesAccess sprops = domainRoot.getDomainConfig().getStandaloneServerConfigMap().get(serverName);\n\n                if (sprops == null) {\n                    sprops = domainRoot.getDomainConfig().getClusteredServerConfigMap().get(serverName);\n                }\n\n                if (sprops != null) {\n                    if (sprops.existsSystemProperty(pn)) {\n                        return sprops.getSystemPropertyValue(pn);\n                    }\n                }\n            }\n\n            ConfigConfig config = domainRoot.getDomainConfig().getConfigConfigMap().get(configName);\n\n            return config.getSystemPropertyValue(pn);\n        }\n        \n        private static String cycleLevel(String level) {\n            if (level.toUpperCase().equals(\"OFF\")) {\n                return \"LOW\";\n            } else if (level.toUpperCase().equals(\"LOW\")) {\n                return \"HIGH\";\n            } else {\n                return \"OFF\";\n            }\n        }\n        \n        private static void setMonitoringLevel(ModuleMonitoringLevelsConfig config, String service, String level) {\n            if (service.toUpperCase().equals(\"HTTPSERVICE\")) {\n                config.setHTTPService(level);\n            } else if (service.toUpperCase().equals(\"CONNECTORSERVICE\")) {\n                config.setConnectorService(level);\n            } else if (service.toUpperCase().equals(\"JDBCCONNECTIONPOOL\")) {\n                config.setJDBCConnectionPool(level);\n            } else if (service.toUpperCase().equals(\"THREADPOOL\")) {\n                config.setThreadPool(level);\n            } else if (service.toUpperCase().equals(\"ORB\")) {\n                config.setORB(level);\n            } else if (service.toUpperCase().equals(\"CONNECTORCONNECTIONPOOL\")) {\n                config.setConnectorConnectionPool(level);\n            } else if (service.toUpperCase().equals(\"JVM\")) {\n                config.setJVM(level);\n            } else if (service.toUpperCase().equals(\"TRANSACTIONSERVICE\")) {\n                config.setTransactionService(level);\n            } else if (service.toUpperCase().equals(\"WEBCONTAINER\")) {\n                config.setWebContainer(level);\n            } else if (service.toUpperCase().equals(\"JMSSERVICE\")) {\n                config.setJMSService(level);\n            } else if (service.toUpperCase().equals(\"EJBCONTAINER\")) {\n                config.setEJBContainer(level);\n            }\n        }\n    }\n\n    @Override\n    public DetailsView createView(int position) {\n        if (model == null) return null;\n        if (position == DataViewComponent.TOP_RIGHT) {\n            DomainRoot root = AMXUtil.getDomainRoot(model);\n            if (root != null) {\n                return new DataViewComponent.DetailsView(\"Application Server\", null, 0,\n                        new ScrollableContainer(new GlassfishOverviewPanel(root, model)), null);\n            }\n        }\n        return null;\n    }\n\n    public GlassFishOverviewPlugin(Application app) {\n        super(app);\n        model = JmxModelFactory.getJmxModelFor(app);\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/GlassFishOverviewPluginProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage net.java.visualvm.modules.glassfish;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.application.views.ApplicationViewsSupport;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider;\n\n/**\n * Provides a basic overview of a GlassFish application server\n * configuration and capabilities\n * @author Jaroslav Bachorik\n */\npublic class GlassFishOverviewPluginProvider extends DataSourceViewPluginProvider<Application> {\n    private final static class InstanceProvider {\n        public static final GlassFishOverviewPluginProvider INSTANCE = new GlassFishOverviewPluginProvider();\n    }\n    \n    @Override\n    protected DataSourceViewPlugin createPlugin(Application app) {\n        return new GlassFishOverviewPlugin(app);\n    }\n\n    @Override\n    protected boolean supportsPluginFor(Application app) {\n        return (ApplicationTypeFactory.getApplicationTypeFor(app) instanceof GlassFishApplicationType);\n    }\n\n    public static void initialize() {\n        ApplicationViewsSupport.sharedInstance().getOverviewView().\n                registerPluginProvider(InstanceProvider.INSTANCE);\n    }\n    \n    public static void shutdown() {\n        ApplicationViewsSupport.sharedInstance().getOverviewView().\n                unregisterPluginProvider(InstanceProvider.INSTANCE);\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage net.java.visualvm.modules.glassfish;\n\nimport net.java.visualvm.modules.glassfish.datasource.GlassFishApplicationProvider;\nimport net.java.visualvm.modules.glassfish.dataview.GlassFishApplicationViewProvider;\nimport net.java.visualvm.modules.glassfish.datasource.GlassFishModelProvider;\nimport net.java.visualvm.modules.glassfish.datasource.GlassFishDataSourceDescriptorProvider;\nimport net.java.visualvm.modules.glassfish.datasource.GlassFishServletProvider;\nimport net.java.visualvm.modules.glassfish.dataview.GlassFishServletViewProvider;\nimport net.java.visualvm.modules.glassfish.dataview.GlassFishWebModuleViewProvider;\nimport net.java.visualvm.modules.glassfish.jmx.GFJmxModelFactory;\nimport org.openide.modules.ModuleInstall;\n\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\npublic class Installer extends ModuleInstall {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private GlassFishApplicationTypeFactory factory;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    public void restored() {\n        GlassFishApplicationTypeFactory.initialize();        \n        GlassFishApplicationViewProvider.initialize();\n        GlassFishModelProvider.initialize();\n        GlassFishServletProvider.initialize();\n        GlassFishWebModuleViewProvider.initialize();\n        GlassFishServletViewProvider.initialize();\n        GlassFishOverviewPluginProvider.initialize();\n        GlassFishDataSourceDescriptorProvider.initialize();\n        GlassFishApplicationProvider.initialize();\n    }\n\n    @Override\n    public void uninstalled() {\n        GlassFishApplicationTypeFactory.shutdown();   \n        GlassFishApplicationViewProvider.shutdown();\n        GlassFishModelProvider.shutdown();\n        GlassFishServletProvider.shutdown();\n        GlassFishWebModuleViewProvider.shutdown();\n        GlassFishServletViewProvider.shutdown();\n        GlassFishOverviewPluginProvider.shutdown();\n        GlassFishDataSourceDescriptorProvider.shutdown();\n        GlassFishApplicationProvider.shutdown();\n        super.uninstalled();\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishApplication.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage net.java.visualvm.modules.glassfish.datasource;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic abstract class GlassFishApplication extends GlassFishDataSource {    \n    private GlassFishModel glassFishRoot;\n    private String name;\n    private String objectName;\n    \n    public GlassFishApplication(String name, String objName, GlassFishModel gfRoot) {\n        super();\n        this.name = name;\n        this.glassFishRoot = gfRoot;\n        this.objectName = objName;\n    }\n\n    public GlassFishModel getGlassFishRoot() {\n        return glassFishRoot;\n    }\n\n    public String getName() {\n        return name;\n    }\n    \n    public String getObjectName() {\n        return objectName;\n    }\n    \n    abstract public void generateContents();\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj == null) {\n            return false;\n        }\n        if (getClass() != obj.getClass()) {\n            return false;\n        }\n        final GlassFishApplication other = (GlassFishApplication) obj;\n        if (this.glassFishRoot != other.glassFishRoot && (this.glassFishRoot == null || !this.glassFishRoot.equals(other.glassFishRoot))) {\n            return false;\n        }\n        if (this.objectName != other.objectName && (this.objectName == null || !this.objectName.equals(other.objectName))) {\n            return false;\n        }\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int hash = 5;\n        hash = 11 * hash + (this.glassFishRoot != null ? this.glassFishRoot.hashCode() : 0);\n        hash = 11 * hash + (this.objectName != null ? this.objectName.hashCode() : 0);\n        return hash;\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishApplicationProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage net.java.visualvm.modules.glassfish.datasource;\n\nimport com.sun.appserv.management.DomainRoot;\nimport com.sun.appserv.management.config.WebModuleConfig;\nimport com.sun.appserv.management.j2ee.J2EETypes;\nimport com.sun.appserv.management.monitor.ServerRootMonitor;\nimport com.sun.appserv.management.monitor.WebModuleVirtualServerMonitor;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.explorer.ExplorerExpansionListener;\nimport org.graalvm.visualvm.core.explorer.ExplorerSupport;\nimport org.graalvm.visualvm.core.scheduler.Quantum;\nimport org.graalvm.visualvm.core.scheduler.ScheduledTask;\nimport org.graalvm.visualvm.core.scheduler.Scheduler;\nimport org.graalvm.visualvm.core.scheduler.SchedulerTask;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport java.io.IOException;\nimport java.lang.reflect.UndeclaredThrowableException;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport net.java.visualvm.modules.glassfish.jmx.AMXUtil;\nimport net.java.visualvm.modules.glassfish.jmx.JMXUtil;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishApplicationProvider implements DataChangeListener<GlassFishModel>, DataRemovedListener<GlassFishModel>, ExplorerExpansionListener {\n\n    private static final GlassFishApplicationProvider INSTANCE = new GlassFishApplicationProvider();\n    private final Map<GlassFishModel, ScheduledTask> taskMap = new HashMap<GlassFishModel, ScheduledTask>();\n\n    private static class LazyLoadingSource extends GlassFishDataSource {\n        private String message;\n        private GlassFishModel parent;\n        public LazyLoadingSource(String message, GlassFishModel parent) {\n            this.message = message;\n            this.parent = parent;\n        }\n        \n        @Override\n        public DataSourceDescriptor getDescriptor() {\n            return new DataSourceDescriptor(this) {\n\n                @Override\n                public int getAutoExpansionPolicy() {\n                    return EXPAND_NEVER;\n                }\n\n                @Override\n                public String getName() {\n                    return message;\n                }\n            };\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj == null) {\n                return false;\n            }\n            if (getClass() != obj.getClass()) {\n                return false;\n            }\n            final LazyLoadingSource other = (LazyLoadingSource) obj;\n            if (this.message != other.message && (this.message == null || !this.message.equals(other.message))) {\n                return false;\n            }\n            if (this.parent != other.parent && (this.parent == null || !this.parent.equals(other.parent))) {\n                return false;\n            }\n            return true;\n        }\n\n        @Override\n        public int hashCode() {\n            int hash = 7;\n            hash = 19 * hash + (this.message != null ? this.message.hashCode() : 0);\n            hash = 19 * hash + (this.parent != null ? this.parent.hashCode() : 0);\n            return hash;\n        }\n    }\n\n    private class DiscoveryTask implements SchedulerTask {\n\n        final private AtomicBoolean isProcessing = new AtomicBoolean(false);\n        final private AtomicBoolean beenNotified = new AtomicBoolean(false);\n        \n        private GlassFishModel model;\n\n        public DiscoveryTask(GlassFishModel model) {\n            this.model = model;\n        }\n\n        public void onSchedule(long timeStamp) {\n            if (!isProcessing.compareAndSet(false, true)) {\n                return;\n            }\n            try {\n                JmxModel jmx = JmxModelFactory.getJmxModelFor(model.getApplication());\n                if ((jmx == null || jmx.getConnectionState() == JmxModel.ConnectionState.DISCONNECTED)){\n                    if (beenNotified.compareAndSet(false, true)) {\n                        NotifyDescriptor nd = new NotifyDescriptor.Message(\"Cannot establish JMX connection\", NotifyDescriptor.ERROR_MESSAGE);\n                        DialogDisplayer.getDefault().notifyLater(nd);\n                        model.setVisible(false);\n                    }\n                    return;\n                }\n                if (jmx.getConnectionState() != JmxModel.ConnectionState.CONNECTED) {\n                    model.setVisible(true);\n                    return;\n                }\n                \n                DomainRoot dr = AMXUtil.getDomainRoot(jmx);\n                if (dr == null || !dr.getAMXReady()) {\n                    return;\n                }\n\n                String serverName = JMXUtil.getServerName(jmx);\n                if (serverName == null) {\n                    return;\n                }\n\n                ServerRootMonitor srm = dr.getMonitoringRoot().getServerRootMonitorMap().get(serverName);\n\n                Map<String, WebModuleConfig> map = dr.getDomainConfig().getWebModuleConfigMap();\n                Map<String, String> contextRootMap = new HashMap<String, String>();\n\n                for (Map.Entry<String, WebModuleConfig> cfgEntry : map.entrySet()) {\n                    String contextRoot = cfgEntry.getValue().getContextRoot();\n                    if (!contextRoot.startsWith(\"/\")) {\n                        contextRoot = \"/\" + contextRoot;\n                    }\n                    contextRootMap.put(contextRoot, cfgEntry.getKey());\n                }\n                Set<GlassFishApplication> currentApps = new HashSet<GlassFishApplication>();\n                for (Map.Entry<String, WebModuleVirtualServerMonitor> virtMonitorEntry : srm.getWebModuleVirtualServerMonitorMap().entrySet()) {\n                    String objectName = JMXUtil.getObjectName(J2EETypes.WEB_MODULE, virtMonitorEntry.getKey(), jmx);\n                    String moduleName = JMXUtil.getWebModuleName(objectName, jmx, contextRootMap);\n                    String appName = JMXUtil.getJ2EEAppName(objectName);\n\n                    if (moduleName == null || moduleName.length() == 0) {\n                        continue;\n                    }\n                    GlassFishWebModule webModule = new GlassFishWebModule(appName != null ? (moduleName + \" (in \" + appName + \")\") : moduleName, objectName, virtMonitorEntry.getValue(), model);\n\n                    currentApps.add(webModule);\n                }\n\n                Set<GlassFishDataSource> toRemoveApps = new HashSet<GlassFishDataSource>(model.getRepository().getDataSources(GlassFishDataSource.class));\n                Set<GlassFishDataSource> toAdd = new HashSet<GlassFishDataSource>(currentApps);\n                toRemoveApps.removeAll(currentApps);\n                toAdd.removeAll(model.getRepository().getDataSources());\n\n                Set<LazyLoadingSource> lazy = model.getRepository().getDataSources(LazyLoadingSource.class);\n                Set<GlassFishDataSource> toRemove = new HashSet<GlassFishDataSource>(toRemoveApps);\n                toRemove.addAll(lazy);\n\n                if (currentApps.size() == 0) {\n                    LazyLoadingSource unavailable = new LazyLoadingSource(\"Unavailable\", model);\n                    toAdd.add(unavailable);\n                    toRemove.remove(unavailable);\n                }\n                toAdd.removeAll(lazy);\n\n                if (toAdd.size() > 0 || toRemove.size() > 0) {\n                    model.getRepository().addDataSources(toAdd);\n                    model.getRepository().removeDataSources(toRemove);\n//                    model.getRepository().updateDataSources(toAdd, toRemove);\n                }\n            } catch (UndeclaredThrowableException e) {\n                // this is caused by disappearing of the underlying JMX connection\n                // just ignore it\n            } finally {\n                isProcessing.set(false);\n            }\n        }\n    }\n\n    public void dataChanged(DataChangeEvent<GlassFishModel> event) {\n        if (event.getAdded().isEmpty() && event.getRemoved().isEmpty()) {\n            addModels(event.getCurrent());\n        } else {\n            addModels(event.getAdded());\n            removeModels(event.getRemoved());\n        }\n    }\n\n    private void addModels(Set<GlassFishModel> models) {\n        for (GlassFishModel model : models) {\n            GlassFishDataSource lazyDS = new LazyLoadingSource(\"Please wait\", model);\n            model.getRepository().addDataSource(lazyDS);\n            ScheduledTask task = Scheduler.sharedInstance().schedule(new DiscoveryTask(model), Quantum.SUSPENDED);\n            taskMap.put(model, task);\n        }\n    }\n\n    private void removeModels(Set<GlassFishModel> models) {\n        for (GlassFishModel model : models) {\n            // removing the reference to the ScheduledTask practically unschedules the task\n            Scheduler.sharedInstance().unschedule(taskMap.remove(model));\n            \n            Set<GlassFishApplication> roots = model.getRepository().getDataSources(GlassFishApplication.class);\n            model.getRepository().removeDataSources(roots);\n        }\n    }\n\n    public void dataRemoved(GlassFishModel model) {\n        // removing the reference to the ScheduledTask practically unschedules the task\n        Scheduler.sharedInstance().unschedule(taskMap.remove(model));\n        \n        Set<GlassFishApplication> roots = model.getRepository().getDataSources(GlassFishApplication.class);\n        model.getRepository().removeDataSources(roots);\n    }\n\n    public static void initialize() {\n        DataSourceRepository.sharedInstance().addDataChangeListener(INSTANCE, GlassFishModel.class);\n        ExplorerSupport.sharedInstance().addExpansionListener(INSTANCE);\n    }\n\n    public static void shutdown() {\n        DataSourceRepository.sharedInstance().removeDataChangeListener(INSTANCE);\n        ExplorerSupport.sharedInstance().removeExpansionListener(INSTANCE);\n    }\n\n    public void dataSourceCollapsed(DataSource source) {\n        // do nothing\n    }\n\n    public void dataSourceExpanded(DataSource source) {\n        if (source instanceof GlassFishModel) {\n            if (taskMap.containsKey(source)) {\n                taskMap.get(source).setInterval(Quantum.seconds(3));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishDataSource.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage net.java.visualvm.modules.glassfish.datasource;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic abstract class GlassFishDataSource extends DataSource {\n    public GlassFishDataSource() {\n        this(null);\n    }\n    \n    public GlassFishDataSource(DataSource master) {\n        super(master);\n    }\n   \n    abstract public DataSourceDescriptor getDescriptor();\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishDataSourceDescriptorProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage net.java.visualvm.modules.glassfish.datasource;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishDataSourceDescriptorProvider extends AbstractModelProvider<DataSourceDescriptor, DataSource> {\n    final private static GlassFishDataSourceDescriptorProvider INSTANCE = new GlassFishDataSourceDescriptorProvider();\n    \n    private GlassFishDataSourceDescriptorProvider() {}\n    \n    @Override\n    public DataSourceDescriptor createModelFor(DataSource glassFishDS) {\n        if (glassFishDS instanceof GlassFishDataSource) {\n            return ((GlassFishDataSource)glassFishDS).getDescriptor();\n        }\n        return null;\n    }\n    \n    public static void initialize() {\n        DataSourceDescriptorFactory.getDefault().registerProvider(INSTANCE);\n    }\n\n    public static void shutdown() {\n        DataSourceDescriptorFactory.getDefault().unregisterProvider(INSTANCE);\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishModel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage net.java.visualvm.modules.glassfish.datasource;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport java.awt.Image;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishModel extends GlassFishDataSource {\n\n    private Application application;\n    private final DataSourceDescriptor descriptor = new DataSourceDescriptor(this) {\n\n        @Override\n        public Image getIcon() {\n            return null;\n        }\n\n        @Override\n        public String getName() {\n            return \"Model\";\n        }\n\n        @Override\n        public String getDescription() {\n            return \"GlassFish/SJSAS Logical Model\";\n        }\n\n        @Override\n        public int getAutoExpansionPolicy() {\n            return EXPAND_NEVER;\n        }\n    };\n\n    public GlassFishModel(Application app) {\n        super();\n        application = app;\n    }\n\n    public Application getApplication() {\n        return application;\n    }\n\n    @Override\n    public DataSourceDescriptor getDescriptor() {\n        return descriptor;\n    }\n}\n\n//            GlassFishWebModule module = new GlassFishWebModule(appName != null ? (moduleName + \" (in \" + appName + \")\") : moduleName, objectName, virtMonitorEntry.getValue(), root);\n//            registerDataSource(module);\n//            root.getRepository().addDataSource(module);\n\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishModelProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage net.java.visualvm.modules.glassfish.datasource;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport java.util.Set;\nimport net.java.visualvm.modules.glassfish.GlassFishApplicationType;\nimport org.openide.util.RequestProcessor;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishModelProvider implements DataChangeListener<Application>, DataRemovedListener<Application> {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n    private static final GlassFishModelProvider INSTANCE = new GlassFishModelProvider();\n    private final DataRemovedListener<Application> removalListener = new DataRemovedListener<Application>() {\n        public void dataRemoved(Application app) {\n            processFinishedApplication(app);\n        }\n    };\n    \n    private GlassFishModelProvider() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    public void dataChanged(DataChangeEvent<Application> event) {\n        if (event.getAdded().isEmpty() && event.getRemoved().isEmpty()) {\n            // Initial event to deliver DataSources already created by the provider before registering to it as a listener\n            // NOTE: already existing hosts are treated as new for this provider\n            Set<Application> newApplications = event.getCurrent();\n\n            for (Application app : newApplications) {\n                processNewApplication(app);\n            }\n        } else {\n            // Real delta event\n            Set<Application> newApplications = event.getAdded();\n\n            for (Application app : newApplications) {\n                processNewApplication(app);\n            }\n        }\n    }\n\n    public static void initialize() {\n        DataSourceRepository.sharedInstance().addDataChangeListener(INSTANCE, Application.class);\n    }\n\n    public static void shutdown() {\n        DataSourceRepository.sharedInstance().removeDataChangeListener(INSTANCE);\n    }\n    \n    public void dataRemoved(Application application) {\n        processFinishedApplication(application);\n    }\n\n    private void processFinishedApplication(Application app) {\n        // TODO: remove listener!!!\n        Set<GlassFishModel> roots = app.getRepository().getDataSources(GlassFishModel.class);\n        app.getRepository().removeDataSources(roots);\n    }\n\n    private void processNewApplication(final Application app) {\n        if (ApplicationTypeFactory.getApplicationTypeFor(app) instanceof GlassFishApplicationType) {\n            RequestProcessor.getDefault().post(new Runnable() {\n                public void run() {\n                    GlassFishModel gfm = new GlassFishModel(app);\n                    app.getRepository().addDataSource(gfm);\n                    app.notifyWhenRemoved(removalListener);\n                }\n            }, 1500);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishServlet.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage net.java.visualvm.modules.glassfish.datasource;\n\nimport com.sun.appserv.management.monitor.ServletMonitor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport java.awt.Image;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishServlet extends GlassFishDataSource {\n    private static final Image NODE_ICON = ImageUtilities.loadImage(\"net/java/visualvm/modules/glassfish/resources/servlet_icon.png\",\n                                                                   true);\n    private ServletMonitor monitor;\n    private String name;\n    \n    private final DataSourceDescriptor descriptor = new DataSourceDescriptor(this) {\n\n        @Override\n        public Image getIcon() {\n            return NODE_ICON;\n        }\n\n        @Override\n        public String getName() {\n            return name;\n        }\n\n        @Override\n        public String getDescription() {\n            return null;\n        }\n\n//        @Override\n//        public int getAutoExpansionPolicy() {\n//            return DataSourceDescriptor.EXPAND_NEVER;\n//        }\n        \n    };\n    \n    public GlassFishServlet(String name, GlassFishWebModule master, ServletMonitor monitor) {\n        super(master);\n        this.monitor = monitor;\n        this.name = name;\n    }\n\n    public ServletMonitor getMonitor() {\n        return monitor;\n    }\n\n    @Override\n    public DataSourceDescriptor getDescriptor() {\n        return descriptor;\n    }\n\n    public String getName() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishServletProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage net.java.visualvm.modules.glassfish.datasource;\n\nimport com.sun.appserv.management.monitor.ServletMonitor;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport java.util.Map;\nimport java.util.Set;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishServletProvider implements DataChangeListener<GlassFishWebModule>, DataRemovedListener<GlassFishWebModule> {\n    private final static GlassFishServletProvider INSTANCE = new GlassFishServletProvider();\n    \n    private GlassFishServletProvider() {}\n    \n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void dataChanged(DataChangeEvent<GlassFishWebModule> event) {\n        if (event.getAdded().isEmpty() && event.getRemoved().isEmpty()) {\n            // Initial event to deliver DataSources already created by the provider before registering to it as a listener\n            // NOTE: already existing hosts are treated as new for this provider\n            Set<GlassFishWebModule> newModules = event.getCurrent();\n\n            for (GlassFishWebModule module : newModules) {\n                processNewWebModule(module);\n            }\n        } else {\n            // Real delta event\n            Set<GlassFishWebModule> newModules = event.getAdded();\n\n            for (GlassFishWebModule module : newModules) {\n                processNewWebModule(module);\n            }\n        }\n    }\n\n    public static void initialize() {\n        DataSourceRepository.sharedInstance().addDataChangeListener(INSTANCE, GlassFishWebModule.class);\n    }\n    \n    public static void shutdown() {\n        DataSourceRepository.sharedInstance().removeDataChangeListener(INSTANCE);\n    }\n    \n    public void dataRemoved(GlassFishWebModule module) {\n        processFinishedModule(module);\n    }\n\n    private void processFinishedModule(GlassFishWebModule module) {\n        // TODO: remove listener!!!\n        Set<GlassFishServlet> monitoredServlets = module.getRepository().getDataSources(GlassFishServlet.class);\n        module.getRepository().removeDataSources(monitoredServlets);\n    }\n\n    private void processNewWebModule(final GlassFishWebModule module) {\n        for (Map.Entry<String, ServletMonitor> monitorEntry : module.getMonitor().getServletMonitorMap().entrySet()) {\n            GlassFishServlet servlet = new GlassFishServlet(monitorEntry.getKey(), module, monitorEntry.getValue());\n            module.getRepository().addDataSource(servlet);\n        }\n\n        module.notifyWhenRemoved(this);\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/datasource/GlassFishWebModule.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage net.java.visualvm.modules.glassfish.datasource;\n\nimport com.sun.appserv.management.monitor.ServletMonitor;\nimport com.sun.appserv.management.monitor.WebModuleVirtualServerMonitor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport java.awt.Image;\nimport java.util.Map;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishWebModule extends GlassFishApplication {\n    private static final Image NODE_ICON = ImageUtilities.loadImage(\"net/java/visualvm/modules/glassfish/resources/application.png\",\n                                                                   true);\n    private WebModuleVirtualServerMonitor monitor;\n    \n    private final DataSourceDescriptor descriptor = new DataSourceDescriptor(this) {\n\n        @Override\n        public Image getIcon() {\n            return NODE_ICON;\n        }\n\n        @Override\n        public String getName() {\n            return GlassFishWebModule.this.getName();\n        }\n\n        @Override\n        public String getDescription() {\n            return null;\n        }\n\n        @Override\n        public int getAutoExpansionPolicy() {\n            return DataSourceDescriptor.EXPAND_NEVER;\n        }\n    };\n    \n    public GlassFishWebModule(String name, String objName, WebModuleVirtualServerMonitor monitor, GlassFishModel gfRoot) {\n        super(name, objName, gfRoot);\n        this.monitor = monitor;\n        \n    }\n\n    public WebModuleVirtualServerMonitor getMonitor() {\n        return monitor;\n    }\n\n    @Override\n    public void generateContents() {\n        for(Map.Entry<String, ServletMonitor> monitorEntry : monitor.getServletMonitorMap().entrySet()) {\n            GlassFishServlet servlet = new GlassFishServlet(monitorEntry.getKey(), this, monitorEntry.getValue());\n            getOwner().getRepository().addDataSource(servlet);\n        }\n    }\n\n    @Override\n    public DataSourceDescriptor getDescriptor() {\n        return descriptor;\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/AbstractStatsTableModel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage net.java.visualvm.modules.glassfish.dataview;\n\nimport com.sun.appserv.management.monitor.MonitoringStats;\nimport org.graalvm.visualvm.core.scheduler.Quantum;\nimport org.graalvm.visualvm.core.scheduler.ScheduledTask;\nimport org.graalvm.visualvm.core.scheduler.Scheduler;\nimport org.graalvm.visualvm.core.scheduler.SchedulerTask;\nimport java.lang.reflect.UndeclaredThrowableException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.j2ee.statistics.CountStatistic;\nimport javax.management.j2ee.statistics.Statistic;\nimport javax.management.j2ee.statistics.Stats;\nimport javax.management.j2ee.statistics.TimeStatistic;\nimport javax.swing.table.AbstractTableModel;\nimport net.java.visualvm.modules.glassfish.util.Touple;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic abstract class AbstractStatsTableModel<PM, M extends MonitoringStats, S extends Stats> extends AbstractTableModel {\n\n    final protected PM monitor;\n    private ScheduledTask refresh;\n    private final AtomicBoolean columnsInitialized = new AtomicBoolean(false);\n    private final List<Touple<String, S>> statsList = new ArrayList<Touple<String, S>>();\n    private String[] columnNames;\n\n    public AbstractStatsTableModel(PM aMonitor, Quantum refreshInterval) {\n        super();\n        monitor = aMonitor;\n        refresh = Scheduler.sharedInstance().schedule(new SchedulerTask() {\n\n            public void onSchedule(long timeStamp) {\n                try {\n                synchronized (statsList) {\n                    statsList.clear();\n                    for (Map.Entry<String, M> monitor : getMonitorMap().entrySet()) {\n                        setColumnModel(monitor.getValue());\n                        S stats = getStats(monitor.getValue());\n                        if (!isDisplayable(stats)) {\n                            continue;\n                        }\n                        statsList.add(new Touple(monitor.getKey(), stats));\n                    }\n                    fireTableDataChanged();\n                }\n                } catch (Exception e) {\n                    if (!(e instanceof UndeclaredThrowableException)) {\n                        Logger.getLogger(AbstractStatsTableModel.class.getName()).log(Level.INFO,\"onSchedule\",e);\n                    } else {\n                        Scheduler.sharedInstance().unschedule(refresh);\n                        refresh = null;\n                    }\n                }\n            }\n        }, refreshInterval, true);\n    }\n\n    abstract protected Map<String, M> getMonitorMap();\n    abstract protected S getStats(M monitor);\n    abstract protected boolean isDisplayable(S stats);\n    \n    private void setColumnModel(M monitor) {\n        if (columnsInitialized.compareAndSet(false, true)) {\n            columnNames = monitor.getStatisticNames();\n        }\n    }\n\n    public int getColumnCount() {\n        if (columnsInitialized.get()) {\n            return columnNames.length;\n        } else {\n            return 0;\n        }\n    }\n\n    public int getRowCount() {\n        synchronized (statsList) {\n            return statsList.size();\n        }\n    }\n\n    public Object getValueAt(int rowIndex, int columnIndex) {\n        Touple<String, S> entry;\n        synchronized (statsList) {\n            entry = statsList.get(rowIndex);\n        }\n        switch (columnIndex) {\n            case 0:\n                {\n                    return entry.getX();\n                }\n            default:\n                {\n                    String name = columnNames[columnIndex - 1];\n                    Statistic stat = entry.getY().getStatistic(name);\n                    if (stat instanceof CountStatistic) {\n                        return ((CountStatistic) stat).getCount();\n                    } else if (stat instanceof TimeStatistic) {\n                        TimeStatistic ts = (TimeStatistic) stat;\n                        return ts.getCount() != 0 ? (double) ts.getTotalTime() / (double) ts.getCount() : 0.0;\n                    }\n                    return stat;\n                }\n        }\n    }\n\n    @Override\n    public String getColumnName(int column) {\n        if (columnsInitialized.get()) {\n            switch (column) {\n                case 0:\n                    {\n                        return \"Name\";\n                    }\n                default:\n                    {\n                        return columnNames[column - 1];\n                    }\n            }\n        } else {\n            return super.getColumnName(column);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/Bundle.properties",
    "content": "\nWebModuleViewPanel.jPanel1.border.title=Sessions\nWebModuleViewPanel.labelCurrent.text=Active Current\nWebModuleViewPanel.labelMax.text=Active Max\nWebModuleViewPanel.labelPassivated.text=Passivated\nWebModuleViewPanel.labelCreated.text=Created\nWebModuleViewPanel.labelExpired.text=Expired\nWebModuleViewPanel.labelRejected.text=Rejected\nWebModuleViewPanel.valueCurrent.text=0\nWebModuleViewPanel.valueMax.text=0\nWebModuleViewPanel.valuePassivated.text=0\nWebModuleViewPanel.valueCreated.text=0\nWebModuleViewPanel.valueExpired.text=0\nWebModuleViewPanel.valueRejected.text=0\nWebModuleViewPanel.jPanel4.border.title=JSPs\nWebModuleViewPanel.labelJspCount.text=Count\nWebModuleViewPanel.labelJspErrors.text=Errors\nWebModuleViewPanel.valueJspCount.text=0\nWebModuleViewPanel.valueJspErrors.text=0\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/GlassFishApplicationViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage net.java.visualvm.modules.glassfish.dataview;\n\nimport com.sun.appserv.management.DomainRoot;\nimport com.sun.appserv.management.config.ModuleMonitoringLevelValues;\nimport com.sun.appserv.management.config.ModuleMonitoringLevelsConfig;\nimport com.sun.appserv.management.monitor.HTTPServiceMonitor;\nimport com.sun.appserv.management.monitor.ServerRootMonitor;\nimport com.sun.appserv.management.monitor.TransactionServiceMonitor;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport net.java.visualvm.modules.glassfish.GlassFishApplicationType;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.logging.Logger;\nimport net.java.visualvm.modules.glassfish.jmx.AMXUtil;\nimport net.java.visualvm.modules.glassfish.jmx.JMXUtil;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishApplicationViewProvider extends DataSourceViewProvider<Application> {\n\n    private final static GlassFishApplicationViewProvider INSTANCE = new GlassFishApplicationViewProvider();\n    private final static Logger LOGGER = Logger.getLogger(GlassFishApplicationViewProvider.class.getName());\n    private final Map<Application, HTTPServiceView> httpServiceViewMap = new HashMap<Application, HTTPServiceView>();\n    private final Map<Application, TransactionServiceView> transServiceViewMap = new HashMap<Application, TransactionServiceView>();\n\n    private GlassFishApplicationViewProvider() {\n    }\n\n    @Override\n    protected DataSourceView createView(Application app) {\n        final JmxModel model = JmxModelFactory.getJmxModelFor(app);\n        if (model == null) {\n            return null;\n        }\n\n        DomainRoot dr = AMXUtil.getDomainRoot(model);\n        if (dr == null) {\n            return null;\n        }\n\n        final Map<String, ServerRootMonitor> serverMonitors = dr.getMonitoringRoot().getServerRootMonitorMap();\n        final String serverName = JMXUtil.getServerName(model);\n\n        if (serverMonitors.get(serverName) == null) {\n            return null;\n        }\n\n        HTTPServiceMonitor httpMonitor = serverMonitors.get(serverName).getHTTPServiceMonitor();\n        ModuleMonitoringLevelsConfig monitorConfig = AMXUtil.getMonitoringConfig(model);\n        if (!monitorConfig.getHTTPService().equals(ModuleMonitoringLevelValues.OFF)) {\n            if (httpMonitor != null) {\n                return getHTTPServiceView(app, httpMonitor);\n            }\n        }\n        return null;\n    }\n\n    @Override\n    protected boolean supportsViewFor(Application app) {\n        if (!(ApplicationTypeFactory.getApplicationTypeFor(app) instanceof GlassFishApplicationType)) return false;\n        \n        final JmxModel model = JmxModelFactory.getJmxModelFor(app);\n        if (model == null) {\n            return false;\n        }\n\n        DomainRoot dr = AMXUtil.getDomainRoot(model);\n        if (dr == null) {\n            return false;\n        }\n\n        final Map<String, ServerRootMonitor> serverMonitors = dr.getMonitoringRoot().getServerRootMonitorMap();\n        final String serverName = JMXUtil.getServerName(model);\n\n        if (serverMonitors.get(serverName) == null) {\n            return false;\n        }\n\n        HTTPServiceMonitor httpMonitor = serverMonitors.get(serverName).getHTTPServiceMonitor();\n        ModuleMonitoringLevelsConfig monitorConfig = AMXUtil.getMonitoringConfig(model);\n        if (!monitorConfig.getHTTPService().equals(ModuleMonitoringLevelValues.OFF)) {\n            return httpMonitor != null;\n        }\n        return false;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n//    @Override\n//    public Set<? extends DataSourceView> getViews(final Application application) {\n//        ApplicationType at = ApplicationTypeFactory.getApplicationTypeFor(application);\n//        if (!(at instanceof GlassFishApplicationType)) {\n//            return Collections.EMPTY_SET;\n//        }\n//\n//        final JmxModel model = JmxModelFactory.getJmxModelFor(application);\n//        if (model == null) {\n//            return Collections.EMPTY_SET;\n//        }\n//\n//        DomainRoot dr = AMXUtil.getDomainRoot(model);\n//        if (dr == null) {\n//            return Collections.EMPTY_SET;\n//        }\n//\n//        try {\n//            final Map<String, ServerRootMonitor> serverMonitors = dr.getMonitoringRoot().getServerRootMonitorMap();\n//            final String serverName = JMXUtil.getServerName(model);\n//\n//            if (serverMonitors.get(serverName) == null) {\n//                return Collections.EMPTY_SET;\n//            }\n//\n//            return new HashSet<DataSourceView>() {\n//\n//                {\n//                    ModuleMonitoringLevelsConfig monitorConfig = AMXUtil.getMonitoringConfig(model);\n//                    if (!monitorConfig.getHTTPService().equals(ModuleMonitoringLevelValues.OFF)) {\n//                        HTTPServiceMonitor httpMonitor = serverMonitors.get(serverName).getHTTPServiceMonitor();\n//                        if (httpMonitor != null) {\n//                            add(getHTTPServiceView(application, httpMonitor));\n//                        }\n//                    }\n//                    if (!monitorConfig.getHTTPService().equals(ModuleMonitoringLevelValues.OFF)) {\n//                        TransactionServiceMonitor transMonitor = serverMonitors.get(serverName).getTransactionServiceMonitor();\n//                        if (transMonitor != null) {\n//                            add(getTransactionServiceView(application, transMonitor));\n//                        }\n//                    }\n//                }\n//            };\n//        } catch (Exception e) {\n//            LOGGER.throwing(GlassFishApplicationViewProvider.class.getName(), \"getViews\", e);\n//        }\n//\n//        return Collections.EMPTY_SET;\n//    }\n\n    private HTTPServiceView getHTTPServiceView(Application app, HTTPServiceMonitor monitor) {\n        synchronized (httpServiceViewMap) {\n            if (httpServiceViewMap.containsKey(app)) {\n                return httpServiceViewMap.get(app);\n            } else {\n                HTTPServiceView view = new HTTPServiceView(app, monitor);\n                httpServiceViewMap.put(app, view);\n                return view;\n            }\n        }\n    }\n\n    private TransactionServiceView getTransactionServiceView(Application app, TransactionServiceMonitor monitor) {\n        synchronized (transServiceViewMap) {\n            if (transServiceViewMap.containsKey(app)) {\n                return transServiceViewMap.get(app);\n            } else {\n                TransactionServiceView view = new TransactionServiceView(app, monitor);\n                transServiceViewMap.put(app, view);\n                return view;\n            }\n        }\n    }\n\n    public static void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(INSTANCE, Application.class);\n    }\n\n    public static void shutdown() {\n        DataSourceViewsManager.sharedInstance().removeViewProvider(INSTANCE);\n        INSTANCE.httpServiceViewMap.clear();\n        INSTANCE.transServiceViewMap.clear();\n    }\n\n    public boolean supportsViewsFor(Application dataSource) {\n        return (ApplicationTypeFactory.getApplicationTypeFor(dataSource) instanceof GlassFishApplicationType);\n    }\n\n    public void saveViews(Application app, Snapshot snapshot) {\n        // TODO implement later\n    }\n\n    public boolean supportsSaveViewsFor(Application app) {\n        return false;\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/GlassFishServletViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage net.java.visualvm.modules.glassfish.dataview;\n\nimport com.sun.appserv.management.monitor.ServletMonitor;\nimport com.sun.appserv.management.monitor.statistics.AltServletStats;\nimport org.graalvm.visualvm.charts.ChartFactory;\nimport org.graalvm.visualvm.charts.SimpleXYChartDescriptor;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport org.graalvm.visualvm.core.scheduler.Quantum;\nimport org.graalvm.visualvm.core.scheduler.ScheduledTask;\nimport org.graalvm.visualvm.core.scheduler.Scheduler;\nimport org.graalvm.visualvm.core.scheduler.SchedulerTask;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport java.lang.reflect.UndeclaredThrowableException;\nimport net.java.visualvm.modules.glassfish.datasource.GlassFishServlet;\nimport org.openide.util.ImageUtilities;\nimport java.awt.BorderLayout;\nimport java.awt.Image;\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.swing.JPanel;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishServletViewProvider extends DataSourceViewProvider<GlassFishServlet> {\n    private final static GlassFishServletViewProvider INSTANCE = new GlassFishServletViewProvider();\n    private final Map<GlassFishServlet, GlassfishServletView> viewMap = new  HashMap<GlassFishServlet, GlassFishServletViewProvider.GlassfishServletView>();\n    \n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private static class GlassfishServletView extends DataSourceView {\n        //~ Static fields/initializers -------------------------------------------------------------------------------------------\n\n        private static final Image NODE_ICON = ImageUtilities.loadImage(\"net/java/visualvm/modules/glassfish/resources/servlet_icon.png\",\n                                                                   true);\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private SimpleXYChartSupport reqsChart;\n        private SimpleXYChartSupport timesChart;\n        private DataViewComponent dvc;\n        private GlassFishServlet servlet;\n\n        private ScheduledTask refreshTask;\n        \n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public GlassfishServletView(GlassFishServlet servlet) {\n            super(servlet, servlet.getName(), NODE_ICON, 0, true);\n\n            this.servlet = servlet;\n\n            HTMLTextArea generalDataArea = new HTMLTextArea();\n\n            JPanel chartTimesPanel = new JPanel(new BorderLayout());\n            chartTimesPanel.setOpaque(false);\n            SimpleXYChartDescriptor desc = SimpleXYChartDescriptor.decimal(10, false, 500);\n            desc.addLineItems(\"Average Time\",\"Maximum Time\");\n            timesChart = ChartFactory.createSimpleXYChart(desc);\n\n            chartTimesPanel.add(timesChart.getChart(), BorderLayout.CENTER);\n\n            JPanel chartReqsPanel = new JPanel(new BorderLayout());\n            chartReqsPanel.setOpaque(false);\n            desc = SimpleXYChartDescriptor.decimal(10, false, 500);\n            desc.addLineItems(\"Request Count\",\"Error Count\");\n            reqsChart = ChartFactory.createSimpleXYChart(desc);\n            chartReqsPanel.add(reqsChart.getChart(), BorderLayout.CENTER);\n\n            DataViewComponent.MasterView masterView = new DataViewComponent.MasterView(\"Overview\", null, generalDataArea);\n            DataViewComponent.MasterViewConfiguration masterConfiguration = new DataViewComponent.MasterViewConfiguration(false);\n            dvc = new DataViewComponent(masterView, masterConfiguration);\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Time Profile\", true),\n                                     DataViewComponent.TOP_LEFT);\n            dvc.addDetailsView(new DataViewComponent.DetailsView(\"Time Profile\", null, 10, chartTimesPanel, null),\n                               DataViewComponent.TOP_LEFT);\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Requests\", true),\n                                     DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(new DataViewComponent.DetailsView(\"Requests\", null, 10, chartReqsPanel, null),\n                               DataViewComponent.BOTTOM_LEFT);\n\n            refreshTask = Scheduler.sharedInstance().schedule(new SchedulerTask() {\n\n                public void onSchedule(long timeStamp) {\n                    try {\n                    refreshData(timeStamp);\n                    } catch (Exception e) {\n                        if (!(e instanceof UndeclaredThrowableException)) {\n                        System.out.println(\"Error: \"+e.getMessage());\n                        e.printStackTrace();\n                        } else {\n                        Scheduler.sharedInstance().unschedule(refreshTask);\n                        refreshTask = null;\n                        }\n                    }\n                }\n            }, Quantum.seconds(3));\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n        @Override\n        public DataViewComponent createComponent() {\n            return dvc;\n        }\n\n        private void refreshData(long sampleTime) {\n            ServletMonitor monitor = servlet.getMonitor();\n            AltServletStats stats = monitor.getAltServletStats();\n            timesChart.addValues(sampleTime,\n                                     new long[] {\n                                         Math.round((double) stats.getProcessingTime().getCount() / (double) stats.getRequestCount()\n                                                                                                                  .getCount()),\n                                         stats.getMaxTime().getCount()\n                                     });\n            reqsChart.addValues(sampleTime,\n                                    new long[] { stats.getRequestCount().getCount(), stats.getErrorCount().getCount() });\n        }\n    }\n\n    private GlassFishServletViewProvider() {}\n\n    @Override\n    protected DataSourceView createView(GlassFishServlet servlet) {\n        return new GlassfishServletView(servlet);\n    }\n\n    @Override\n    protected boolean supportsViewFor(GlassFishServlet servlet) {\n        return true;\n    }\n    \n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(INSTANCE, GlassFishServlet.class);\n    }\n    \n    public static void shutdown() {\n        DataSourceViewsManager.sharedInstance().removeViewProvider(INSTANCE);\n        INSTANCE.viewMap.clear();\n    }\n\n    public boolean supportsViewsFor(GlassFishServlet dataSource) {\n        return true;\n    }\n    \n    public void saveViews(GlassFishServlet servlet, Snapshot snapshot) {\n        // TODO implement later\n    }\n\n    public boolean supportsSaveViewsFor(GlassFishServlet servlet) {\n        return false;\n    }\n    \n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/GlassFishWebModuleViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage net.java.visualvm.modules.glassfish.dataview;\n\nimport java.io.IOException;\nimport java.lang.reflect.UndeclaredThrowableException;\nimport java.util.logging.Level;\nimport javax.management.AttributeNotFoundException;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.MBeanException;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ReflectionException;\nimport net.java.visualvm.modules.glassfish.ui.StatsTable;\nimport com.sun.appserv.management.monitor.WebModuleVirtualServerMonitor;\nimport com.sun.appserv.management.monitor.statistics.WebModuleVirtualServerStats;\nimport org.graalvm.visualvm.charts.ChartFactory;\nimport org.graalvm.visualvm.charts.SimpleXYChartDescriptor;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.scheduler.Quantum;\nimport org.graalvm.visualvm.core.scheduler.ScheduledTask;\nimport org.graalvm.visualvm.core.scheduler.Scheduler;\nimport org.graalvm.visualvm.core.scheduler.SchedulerTask;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.uisupport.HTMLLabel;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport net.java.visualvm.modules.glassfish.datasource.GlassFishWebModule;\n\nimport org.openide.util.ImageUtilities;\nimport java.awt.BorderLayout;\nimport java.awt.Image;\nimport java.net.URL;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.logging.Logger;\nimport javax.management.MBeanServerConnection;\nimport javax.management.ObjectName;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.RowSorter;\nimport javax.swing.table.TableModel;\nimport javax.swing.table.TableRowSorter;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GlassFishWebModuleViewProvider extends DataSourceViewProvider<GlassFishWebModule> {\n    private final static GlassFishWebModuleViewProvider INSTANCE = new GlassFishWebModuleViewProvider();\n    private final static Logger LOGGER = Logger.getLogger(GlassFishWebModuleViewProvider.class.getName());\n    \n    private final Map<GlassFishWebModule, GlassfishWebModuleView> viewMap = new  HashMap<GlassFishWebModule, GlassFishWebModuleViewProvider.GlassfishWebModuleView>();\n    \n    private static class GlassfishWebModuleView extends DataSourceView {\n        //~ Static fields/initializers -------------------------------------------------------------------------------------------\n\n        private static final Image NODE_ICON = ImageUtilities.loadImage(\"net/java/visualvm/modules/glassfish/resources/application.png\",\n                                                                   true);\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private SimpleXYChartSupport activeSessionsChart;\n        private SimpleXYChartSupport jspChart;\n        private SimpleXYChartSupport totalSessionsChart;\n        private DataViewComponent dvc;\n        private TableModel servletsModel;\n        private TableModel wsModel;\n        private GlassFishWebModule module;\n        private ScheduledTask refreshTask;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public GlassfishWebModuleView(GlassFishWebModule webModule) {\n            super(webModule, \"Overview\", NODE_ICON, 0, true);\n\n            module = webModule;\n            JPanel masterPanel = new JPanel(new BorderLayout());\n            masterPanel.setOpaque(false);\n            \n            HTMLTextArea generalDataArea = new HTMLTextArea();\n            generalDataArea.setText(buildInfo());\n            generalDataArea.setBorder(BorderFactory.createEmptyBorder());\n//            generalDataArea.setOpaque(false);\n            \n            JScrollPane generalDataScroll = new JScrollPane(generalDataArea);\n            generalDataScroll.setViewportBorder(BorderFactory.createEmptyBorder());\n            generalDataScroll.setBorder(BorderFactory.createEmptyBorder());\n            generalDataScroll.setOpaque(false);\n            \n            HTMLLabel appLink = new HTMLLabel(\"<html><body><h2>Application hosted by <a href=\\\"#\\\">\" + DataSourceDescriptorFactory.getDescriptor(module.getGlassFishRoot().getApplication()).getName()+ \"</a></h2></body></html>\") {\n                protected void showURL(URL url) {\n                    DataSourceWindowManager.sharedInstance().openDataSource(module.getGlassFishRoot().getApplication());\n                }\n            };\n            masterPanel.add(generalDataScroll, BorderLayout.CENTER);\n            masterPanel.add(appLink, BorderLayout.NORTH);\n\n            SimpleXYChartDescriptor desc = SimpleXYChartDescriptor.decimal(10, false, 500);\n            desc.addLineItems(\"Current\",\"Maximum\");\n\n            activeSessionsChart = ChartFactory.createSimpleXYChart(desc);\n\n            desc = SimpleXYChartDescriptor.decimal(10, true, 500);\n            desc.addLineItems(\"Created\",\"Expired\",\"Rejected\");\n            totalSessionsChart = ChartFactory.createSimpleXYChart(desc);\n\n            desc = SimpleXYChartDescriptor.decimal(10, false, 500);\n            desc.addLineItems(\"Count\",\"Reloads\",\"Errors\");\n            jspChart = ChartFactory.createSimpleXYChart(desc);\n\n            JPanel servletsPanel = new JPanel(new BorderLayout());\n            servletsPanel.setOpaque(false);\n            servletsModel = new ServletTableModel(webModule.getMonitor(), Quantum.seconds(5));\n\n            RowSorter<TableModel> servletsRowSorter = new TableRowSorter<TableModel>(servletsModel);\n\n            StatsTable servletsTable = new StatsTable(servletsModel);\n            servletsTable.setRowSorter(servletsRowSorter);\n\n            JScrollPane servletsScroller = new JScrollPane(servletsTable);\n            servletsScroller.getViewport().setBackground(generalDataArea.getBackground());\n            servletsPanel.add(servletsScroller, BorderLayout.CENTER);\n\n            JPanel wsPanel = new JPanel(new BorderLayout());\n            wsPanel.setOpaque(false);\n            wsModel = new WSTableModel(webModule.getMonitor(), Quantum.seconds(5));\n\n            RowSorter<TableModel> wsRowSorter = new TableRowSorter<TableModel>(wsModel);\n\n            StatsTable wsTable = new StatsTable(wsModel);\n            wsTable.setRowSorter(wsRowSorter);\n\n            JScrollPane wsScroller = new JScrollPane(wsTable);\n            wsScroller.getViewport().setBackground(generalDataArea.getBackground());\n            wsPanel.add(wsScroller, BorderLayout.CENTER);\n\n            DataViewComponent.MasterView masterView = new DataViewComponent.MasterView(\"Overview\", null, masterPanel);\n            DataViewComponent.MasterViewConfiguration masterConfiguration = new DataViewComponent.MasterViewConfiguration(false);\n            dvc = new DataViewComponent(masterView, masterConfiguration);\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Sessions\", true), DataViewComponent.TOP_LEFT);\n            dvc.addDetailsView(new DataViewComponent.DetailsView(\"Sessions Active\", null, 10, activeSessionsChart.getChart(), null),\n                               DataViewComponent.TOP_LEFT);\n            dvc.addDetailsView(new DataViewComponent.DetailsView(\"Sessions Total\", null, 20, totalSessionsChart.getChart(), null),\n                               DataViewComponent.TOP_LEFT);\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"JSPs\", true), DataViewComponent.TOP_RIGHT);\n            dvc.addDetailsView(new DataViewComponent.DetailsView(\"JSPs\", null, 10, jspChart.getChart(), null), DataViewComponent.TOP_RIGHT);\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Runtime\", true),\n                                     DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(new DataViewComponent.DetailsView(\"Servlets\", null, 10, servletsPanel, null),\n                               DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(new DataViewComponent.DetailsView(\"WebServices\", null, 20, wsPanel, null),\n                               DataViewComponent.BOTTOM_LEFT);\n            \n            refreshTask = Scheduler.sharedInstance().schedule(new SchedulerTask() {\n                public void onSchedule(long timeStamp) {\n                    try {\n                        refreshData(timeStamp);\n                    } catch (Exception e) {\n                        if (!(e instanceof UndeclaredThrowableException)) {\n                            Logger.getLogger(GlassFishWebModuleViewProvider.class.getName()).log(Level.INFO,\"onSchedule\",e);\n                        } else {\n                            Scheduler.sharedInstance().unschedule(refreshTask);\n                            refreshTask = null;\n                        }\n                    }\n                }\n            }, Quantum.seconds(5));\n        }\n\n        @Override\n        protected DataViewComponent createComponent() {\n            return dvc;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        private String buildInfo() {\n                JmxModel jmx = JmxModelFactory.getJmxModelFor(module.getGlassFishRoot().getApplication());\n                StringBuilder sb = new StringBuilder();\n            try {\n                ObjectName objName = new ObjectName(module.getObjectName());\n                MBeanServerConnection connection = jmx.getMBeanServerConnection();\n                sb.append(\"<br/>\");\n                sb.append(\"<b>Context: </b>\").append(connection.getAttribute(objName, \"path\")).append(\"<br/>\");\n                sb.append(\"<b>Document Base: </b>\").append(connection.getAttribute(objName, \"docBase\")).append(\"<br/>\");\n                sb.append(\"<b>Working Dir: </b>\").append(connection.getAttribute(objName, \"workDir\")).append(\"<br/>\");\n                sb.append(\"<br/>\");\n                boolean cacheAllowed = (Boolean)connection.getAttribute(objName, \"cachingAllowed\");\n                sb.append(\"<b>Caching: </b>\").append(cacheAllowed ? \"Allowed\" : \"Disallowed\").append(\"<br/>\");\n                sb.append(\"<br/>\");\n            } catch (MBeanException ex) {\n                LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), \"buildInfo\", ex);\n            } catch (AttributeNotFoundException ex) {\n                LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), \"buildInfo\", ex);\n            } catch (InstanceNotFoundException ex) {\n                LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), \"buildInfo\", ex);\n            } catch (ReflectionException ex) {\n                LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), \"buildInfo\", ex);\n            } catch (IOException ex) {\n                LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), \"buildInfo\", ex);\n            } catch (MalformedObjectNameException ex) {\n                LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), \"buildInfo\", ex);\n            } catch (NullPointerException ex) {\n                LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), \"buildInfo\", ex);\n            }\n            return sb.toString();\n        }\n        \n        private void refreshData(long sampleTime) {\n            WebModuleVirtualServerMonitor monitor = module.getMonitor();\n            WebModuleVirtualServerStats stats = monitor.getWebModuleVirtualServerStats();\n            activeSessionsChart.addValues(sampleTime,\n                                              new long[] {\n                                                  stats.getActiveSessionsCurrent().getCount(),\n                                                  stats.getActiveSessionsHigh().getCount()\n                                              });\n            totalSessionsChart.addValues(sampleTime,\n                                             new long[] {\n                                                 stats.getSessionsTotal().getCount(), stats.getExpiredSessionsTotal().getCount(),\n                                                 stats.getRejectedSessionsTotal().getCount()\n                                             });\n            jspChart.addValues(sampleTime,\n                                   new long[] {\n                                       stats.getJSPCount().getCount(), stats.getJSPReloadCount().getCount(),\n                                       stats.getJSPErrorCount().getCount()\n                                   });\n\n        }\n    }\n\n    private GlassFishWebModuleViewProvider() {}\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    public static void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(INSTANCE, GlassFishWebModule.class);\n    }\n    \n    public static void shutdown() {\n        DataSourceViewsManager.sharedInstance().removeViewProvider(INSTANCE);\n        INSTANCE.viewMap.clear();\n    }\n\n    @Override\n    protected DataSourceView createView(GlassFishWebModule webModule) {\n        return new GlassfishWebModuleView(webModule);\n    }\n\n    @Override\n    protected boolean supportsViewFor(GlassFishWebModule webModule) {\n        return true;\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/HTTPServiceView.java",
    "content": "package net.java.visualvm.modules.glassfish.dataview;\n\nimport com.sun.appserv.management.monitor.ConnectionQueueMonitor;\nimport com.sun.appserv.management.monitor.FileCacheMonitor;\nimport com.sun.appserv.management.monitor.HTTPServiceMonitor;\nimport com.sun.appserv.management.monitor.KeepAliveMonitor;\nimport com.sun.appserv.management.monitor.statistics.KeepAliveStats;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.charts.ChartFactory;\nimport org.graalvm.visualvm.charts.SimpleXYChartDescriptor;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport org.graalvm.visualvm.core.scheduler.Quantum;\nimport org.graalvm.visualvm.core.scheduler.ScheduledTask;\nimport org.graalvm.visualvm.core.scheduler.Scheduler;\nimport org.graalvm.visualvm.core.scheduler.SchedulerTask;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport java.lang.reflect.UndeclaredThrowableException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport org.openide.util.ImageUtilities;\n\nclass HTTPServiceView extends DataSourceView {\n\n    private static final String ICON_PATH = \"net/java/visualvm/modules/glassfish/resources/logviewer_icon.png\";\n    private static final Logger LOGGER = Logger.getLogger(HTTPServiceView.class.getName());\n    private DataViewComponent dvc;\n    private HTTPServiceMonitor monitor;\n    private ScheduledTask queueRefreshTask;\n    private ScheduledTask cacheRefreshTask;\n    private ScheduledTask kaRefreshTask;\n\n    public HTTPServiceView(Application app, HTTPServiceMonitor monitor) {\n        super(app, \"HTTP Service\", new ImageIcon(ImageUtilities.loadImage(ICON_PATH, true)).getImage(), POSITION_AT_THE_END, false);\n        this.monitor = monitor;\n        initComponents();\n    }\n\n    @Override\n    public DataViewComponent createComponent() {\n        return dvc;\n    }\n\n    private SimpleXYChartSupport connectionQueueChart;\n\n    private void configureConnectionQueueVisualizer() {\n        final ConnectionQueueMonitor cqm = monitor.getConnectionQueueMonitor();\n        SimpleXYChartDescriptor desc = SimpleXYChartDescriptor.decimal(10, true, 500);\n        desc.addLineItems(\"1min\",\"5min\",\"15min\");\n        connectionQueueChart = ChartFactory.createSimpleXYChart(desc);\n\n//        ConnectionQueuePanel cqp = new ConnectionQueuePanel();\n//        final ConnectionQueuePanel.Model model = new ConnectionQueuePanel.Model() {\n//\n//            ConnectionQueueMonitor queueMonitor = null;\n//            {\n//                if (monitor != null) {\n//                    queueMonitor = monitor.getConnectionQueueMonitor();\n//                }\n//            }\n//\n//            @Override\n//            public RangedLong getUtilization() {\n//                if (queueMonitor == null) {\n//                    return RangedLong.ZERO;\n//                }\n//                ConnectionQueueStats stats = queueMonitor.getConnectionQueueStats();\n//                long max = stats.getMaxQueued().getCount();\n//                long current = stats.getCountQueued().getCount();\n//                return new RangedLong(0L, max, current);\n//            }\n//\n//            @Override\n//            public int getRefusalRate() {\n//                if (queueMonitor == null) {\n//                    return 0;\n//                }\n//                ConnectionQueueStats stats = queueMonitor.getConnectionQueueStats();\n//\n//                if (stats.getCountTotalQueued().getCount() == 0) {\n//                    return 0;\n//                }\n//\n//                return Math.round(((float) stats.getCountOverflows().getCount() / (float) stats.getCountTotalConnections().getCount()) * 100.0F);\n//            }\n//\n//            @Override\n//            public long getAverage1min() {\n//                if (queueMonitor == null) {\n//                    return 0L;\n//                }\n//                ConnectionQueueStats stats = queueMonitor.getConnectionQueueStats();\n//\n//                return stats.getCountQueued1MinuteAverage().getCount();\n//            }\n//\n//            @Override\n//            public long getAverage5min() {\n//                if (queueMonitor == null) {\n//                    return 0L;\n//                }\n//                ConnectionQueueStats stats = queueMonitor.getConnectionQueueStats();\n//\n//                return stats.getCountQueued5MinuteAverage().getCount();\n//            }\n//\n//            @Override\n//            public long getAverage15min() {\n//                if (queueMonitor == null) {\n//                    return 0L;\n//                }\n//                ConnectionQueueStats stats = queueMonitor.getConnectionQueueStats();\n//\n//                return stats.getCountQueued15MinuteAverage().getCount();\n//            }\n//        };\n\n//        cqp.setModel(model);\n        queueRefreshTask = Scheduler.sharedInstance().schedule(new SchedulerTask() {\n\n            @Override\n            public void onSchedule(long timeStamp) {\n                try {\n                    connectionQueueChart.addValues(timeStamp,\n                            new long[] {cqm.getConnectionQueueStats().getCountQueued1MinuteAverage().getCount(),\n                                        cqm.getConnectionQueueStats().getCountQueued5MinuteAverage().getCount(),\n                                        cqm.getConnectionQueueStats().getCountQueued15MinuteAverage().getCount()});\n                } catch (Exception e) {\n                    if (!(e instanceof UndeclaredThrowableException)) {\n                        LOGGER.log(Level.INFO,\"onSchedule\",e);\n                    } else {\n                        Scheduler.sharedInstance().unschedule(queueRefreshTask);\n                        queueRefreshTask = null;\n                    }\n                }\n            }\n        }, Quantum.seconds(1));\n\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Connection Queue\", true), DataViewComponent.TOP_LEFT);\n        dvc.addDetailsView(new DataViewComponent.DetailsView(\"Connection Queue\", null, 10, connectionQueueChart.getChart(), null), DataViewComponent.TOP_LEFT);\n    }\n\n    private SimpleXYChartSupport fileCacheChart;\n\n    private void configureFileCacheVisualizer() {\n        SimpleXYChartDescriptor desc = SimpleXYChartDescriptor.decimal(10, false, 500);\n        desc.addLineFillItems(\"Min\");\n        desc.addLineItems(\"Max\",\"Current\");\n        fileCacheChart = ChartFactory.createSimpleXYChart(desc);\n\n        final FileCacheMonitor fcm = monitor.getFileCacheMonitor();\n\n//        FileCachePanel fcp = new FileCachePanel();\n//        final FileCachePanel.Model model = new FileCachePanel.Model() {\n//\n//            FileCacheMonitor cacheMonitor = null;\n//            {\n//                if (monitor != null) {\n//                    cacheMonitor = monitor.getFileCacheMonitor();\n//                }\n//            }\n//\n//            @Override\n//            public RangedLong getUtilizationHeap() {\n//                if (cacheMonitor == null) {\n//                    return RangedLong.ZERO;\n//                }\n//                FileCacheStats stats = cacheMonitor.getFileCacheStats();\n//                return new RangedLong(0L, stats.getMaxHeapCacheSize().getCount(), stats.getSizeHeapCache().getCount());\n//            }\n//\n//            @Override\n//            public RangedLong getUtilizationAll() {\n//                if (cacheMonitor == null) {\n//                    return RangedLong.ZERO;\n//                }\n//                FileCacheStats stats = cacheMonitor.getFileCacheStats();\n//                return new RangedLong(0L, stats.getMaxEntries().getCount(), stats.getMaxEntries().getCount());\n//            }\n//\n//            @Override\n//            public RangedLong getUtilizationOpen() {\n//                if (cacheMonitor == null) {\n//                    return RangedLong.ZERO;\n//                }\n//                FileCacheStats stats = cacheMonitor.getFileCacheStats();\n//                return new RangedLong(0L, stats.getMaxOpenEntries().getCount(), stats.getCountOpenEntries().getCount());\n//            }\n//\n//            @Override\n//            public RangedLong getHitRatio() {\n//                if (cacheMonitor == null) {\n//                    return RangedLong.ZERO;\n//                }\n//                FileCacheStats stats = cacheMonitor.getFileCacheStats();\n//\n//                long hits = stats.getCountContentHits().getCount();\n//                long misses = stats.getCountContentMisses().getCount();\n//                return new RangedLong(0L, hits + misses, misses);\n//            }\n//        };\n//\n//        fcp.setModel(model);\n        final long[] minmax = new long[]{Long.MAX_VALUE, 0L};\n\n        cacheRefreshTask = Scheduler.sharedInstance().schedule(new SchedulerTask() {\n\n            @Override\n            public void onSchedule(long timeStamp) {\n                try {\n                    long hits = fcm.getFileCacheStats().getCountContentHits().getCount();\n                    long misses = fcm.getFileCacheStats().getCountContentMisses().getCount();\n                    long percent = (hits + misses > 0) ? (hits * 100) / (hits + misses) : 0L;\n                    if (percent > minmax[1]) {\n                        minmax[1] = percent;\n                    }\n                    if (percent < minmax[0]) {\n                        minmax[0] = percent;\n                    }\n                    fileCacheChart.addValues(timeStamp, new long[] {\n                        minmax[0], minmax[1], percent\n                    });\n                } catch (Exception e) {\n                    if (!(e instanceof UndeclaredThrowableException)) {\n                        LOGGER.log(Level.INFO,\"onSchedule\",e);\n                    } else {\n                        Scheduler.sharedInstance().unschedule(cacheRefreshTask);\n                        cacheRefreshTask = null;\n                    }\n                }\n            }\n        }, Quantum.seconds(1));\n\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"File Cache\", true), DataViewComponent.BOTTOM_LEFT);\n        dvc.addDetailsView(new DataViewComponent.DetailsView(\"File Cache Hits\", null, 10, fileCacheChart.getChart(), null), DataViewComponent.BOTTOM_LEFT);\n    }\n\n    private void configureHttpServiceVisualizer() {\n        configureConnectionQueueVisualizer();\n        configureFileCacheVisualizer();\n        configureKeepAliveVisualizer();\n    }\n\n    private SimpleXYChartSupport keepAliveChart;\n\n    private void configureKeepAliveVisualizer() {\n        final KeepAliveMonitor kaMonitor = monitor.getKeepAliveMonitor();\n        SimpleXYChartDescriptor desc = SimpleXYChartDescriptor.decimal(10, false, 500);\n        desc.addLineItems(\"Refused\",\"Flushed\",\"Timed Out\");\n        keepAliveChart = ChartFactory.createSimpleXYChart(desc);\n\n        kaRefreshTask = Scheduler.sharedInstance().schedule(new SchedulerTask() {\n\n            @Override\n            public void onSchedule(long timeStamp) {\n                try {\n                    KeepAliveStats stats = kaMonitor.getKeepAliveStats();\n                    keepAliveChart.addValues(timeStamp, \n                            new long[] {stats.getCountRefusals().getCount(), stats.getCountFlushes().getCount(), stats.getCountTimeouts().getCount()});\n                } catch (Exception e) {\n                    if (!(e instanceof UndeclaredThrowableException)) {\n                        LOGGER.log(Level.INFO,\"onSchedule\",e);\n                    } else {\n                        Scheduler.sharedInstance().unschedule(kaRefreshTask);\n                        kaRefreshTask = null;\n                    }\n                }\n            }\n        }, Quantum.seconds(1));\n\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Keep Alive\", true), DataViewComponent.BOTTOM_RIGHT);\n        dvc.addDetailsView(new DataViewComponent.DetailsView(\"Keep Alive\", null, 10, keepAliveChart.getChart(), null), DataViewComponent.BOTTOM_RIGHT);\n    }\n\n    private void initComponents() {\n        HTMLTextArea generalDataArea = new HTMLTextArea();\n        generalDataArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n        //            DisplayArea monitoringDisplayArea = new DisplayArea();\n        //            monitoringDisplayArea.setClosable(true);\n        DataViewComponent.MasterView monitoringMasterView = new DataViewComponent.MasterView(\"\", null, generalDataArea);\n        DataViewComponent.MasterViewConfiguration monitoringMasterConfiguration = new DataViewComponent.MasterViewConfiguration(false);\n        dvc = new DataViewComponent(monitoringMasterView, monitoringMasterConfiguration);\n        configureHttpServiceVisualizer();\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/ServletTableModel.java",
    "content": "package net.java.visualvm.modules.glassfish.dataview;\n\nimport com.sun.appserv.management.monitor.ServletMonitor;\nimport com.sun.appserv.management.monitor.WebModuleVirtualServerMonitor;\nimport com.sun.appserv.management.monitor.statistics.AltServletStats;\nimport org.graalvm.visualvm.core.scheduler.Quantum;\nimport java.util.Map;\n\nclass ServletTableModel extends AbstractStatsTableModel<WebModuleVirtualServerMonitor, ServletMonitor, AltServletStats> {\n    public ServletTableModel(WebModuleVirtualServerMonitor aMonitor, Quantum refreshInterval) {\n        super(aMonitor, refreshInterval);\n    }\n    \n    @Override\n    protected Map<String, ServletMonitor> getMonitorMap() {\n        return monitor.getServletMonitorMap();\n    }\n\n    @Override\n    protected AltServletStats getStats(ServletMonitor monitor) {\n        return monitor.getAltServletStats();\n    }\n\n    @Override\n    protected boolean isDisplayable(AltServletStats stats) {\n        return true;\n//        return stats.getRequestCount().getCount() > 0;\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/TransactionServiceView.java",
    "content": "package net.java.visualvm.modules.glassfish.dataview;\n\nimport com.sun.appserv.management.monitor.TransactionServiceMonitor;\nimport com.sun.appserv.management.monitor.statistics.TransactionServiceStats;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.charts.ChartFactory;\nimport org.graalvm.visualvm.charts.SimpleXYChartDescriptor;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport org.graalvm.visualvm.core.scheduler.Quantum;\nimport org.graalvm.visualvm.core.scheduler.ScheduledTask;\nimport org.graalvm.visualvm.core.scheduler.Scheduler;\nimport org.graalvm.visualvm.core.scheduler.SchedulerTask;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport java.lang.reflect.UndeclaredThrowableException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport org.openide.util.ImageUtilities;\n\nclass TransactionServiceView extends DataSourceView {\n\n    private static final String ICON_PATH = \"net/java/visualvm/modules/glassfish/resources/logviewer_icon.png\";\n    private DataViewComponent dvc;\n    private TransactionServiceMonitor monitor;\n    private ScheduledTask transRefreshTask;\n\n    public TransactionServiceView(Application app, TransactionServiceMonitor monitor) {\n        super(app, \"Transaction Service\", new ImageIcon(ImageUtilities.loadImage(ICON_PATH, true)).getImage(), POSITION_AT_THE_END, false);\n        this.monitor = monitor;\n\n        initComponents();\n    }\n\n    @Override\n    public DataViewComponent createComponent() {\n        return dvc;\n    }\n\n    private SimpleXYChartSupport transactionalServiceChart;\n\n    private void configureTransactionalServiceVisualizer() {\n        SimpleXYChartDescriptor desc = SimpleXYChartDescriptor.decimal(10, false, 500);\n        desc.addFillItems(\"Count\",\"Maximum Time\");\n        transactionalServiceChart = ChartFactory.createSimpleXYChart(desc);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Transactional Service\", false), DataViewComponent.BOTTOM_RIGHT);\n\n        final TransactionServiceStats tss = monitor.getTransactionServiceStats();\n\n        transRefreshTask = Scheduler.sharedInstance().schedule(new SchedulerTask() {\n\n            @Override\n            public void onSchedule(long timeStamp) {\n                try {\n                    transactionalServiceChart.addValues(timeStamp,\n                            new long[]{tss.getActiveCount().getCount()});\n                } catch (Exception e) {\n                    if (!(e instanceof UndeclaredThrowableException)) {\n                        Logger.getLogger(TransactionServiceView.class.getName()).log(Level.INFO,\"onSchedule\",e);\n                    } else {\n                        Scheduler.sharedInstance().unschedule(transRefreshTask);\n                        transRefreshTask = null;\n                    }\n                }\n            }\n        }, Quantum.seconds(1));\n        dvc.addDetailsView(new DataViewComponent.DetailsView(\"Transactional Service\", null, 10, transactionalServiceChart.getChart(), null), DataViewComponent.BOTTOM_RIGHT);\n    }\n\n    private void initComponents() {\n        HTMLTextArea generalDataArea = new HTMLTextArea();\n        generalDataArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n        DataViewComponent.MasterView monitoringMasterView = new DataViewComponent.MasterView(\"\", null, generalDataArea);\n        DataViewComponent.MasterViewConfiguration monitoringMasterConfiguration = new DataViewComponent.MasterViewConfiguration(true);\n        dvc = new DataViewComponent(monitoringMasterView, monitoringMasterConfiguration);\n        configureTransactionalServiceVisualizer();\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/dataview/WSTableModel.java",
    "content": "package net.java.visualvm.modules.glassfish.dataview;\n\nimport com.sun.appserv.management.monitor.WebModuleVirtualServerMonitor;\nimport com.sun.appserv.management.monitor.WebServiceEndpointMonitor;\nimport com.sun.appserv.management.monitor.statistics.WebServiceEndpointAggregateStats;\nimport org.graalvm.visualvm.core.scheduler.Quantum;\nimport java.util.Map;\n\nclass WSTableModel extends AbstractStatsTableModel<WebModuleVirtualServerMonitor, WebServiceEndpointMonitor, WebServiceEndpointAggregateStats> {\n    public WSTableModel(WebModuleVirtualServerMonitor aMonitor, Quantum refreshInterval) {\n        super(aMonitor, refreshInterval);\n    }\n    \n    @Override\n    protected Map<String, WebServiceEndpointMonitor> getMonitorMap() {\n        return monitor.getWebServiceEndpointMonitorMap();\n    }\n\n    @Override\n    protected WebServiceEndpointAggregateStats getStats(WebServiceEndpointMonitor monitor) {\n        return monitor.getWebServiceEndpointAggregateStats();\n    }\n\n    @Override\n    protected boolean isDisplayable(WebServiceEndpointAggregateStats stats) {\n        return true;\n//        return stats.getTotalFaults().getCount() + stats.getTotalNumSuccess().getCount() > 0;\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/jmx/AMXUtil.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage net.java.visualvm.modules.glassfish.jmx;\n\nimport com.sun.appserv.management.DomainRoot;\nimport com.sun.appserv.management.base.SystemInfo;\nimport com.sun.appserv.management.client.ProxyFactory;\nimport com.sun.appserv.management.config.ConfigConfig;\nimport com.sun.appserv.management.config.ModuleMonitoringLevelsConfig;\nimport com.sun.appserv.management.monitor.MonitoringRoot;\nimport com.sun.appserv.management.util.jmx.MBeanServerConnectionConnectionSource;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport java.lang.ref.WeakReference;\nimport java.util.Map;\nimport java.util.WeakHashMap;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.MBeanServerConnection;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class AMXUtil {\n    private static final Logger LOGGER = Logger.getLogger(AMXUtil.class.getName());\n    \n    private static final Map<MBeanServerConnection, WeakReference<ProxyFactory>> proxyMap = new WeakHashMap<MBeanServerConnection, WeakReference<ProxyFactory>>();\n    \n    public static MonitoringRoot getMonitoringRoot(MBeanServerConnection connection) throws Exception {\n        DomainRoot dr = getDomainRoot(connection);\n        if (dr == null) return null;\n        return dr.getMonitoringRoot();\n    }\n\n    public static DomainRoot getDomainRoot(JmxModel model) {\n        try {\n            return getDomainRoot(model.getMBeanServerConnection());\n        } catch (Exception e) {\n            return null;\n        }\n    }\n    \n    public static DomainRoot getDomainRoot(MBeanServerConnection connection) throws Exception {\n        try {\n            DomainRoot domainRoot = getAMXProxyFactory(connection).getDomainRoot();\n            domainRoot.waitAMXReady();\n            return domainRoot;\n        } catch (Exception e) {\n            LOGGER.log(Level.FINER, \"\", e);\n            return null;\n        }\n    }\n    \n    public static ModuleMonitoringLevelsConfig getMonitoringConfig(JmxModel jmxModel) {\n        ConfigConfig cc = getDomainRoot(jmxModel).getDomainConfig().getConfigConfigMap().get(JMXUtil.getServerConfig(jmxModel));\n        return cc.getMonitoringServiceConfig().getModuleMonitoringLevelsConfig();\n    }\n    \n    public static ProxyFactory getAMXProxyFactory(MBeanServerConnection connection) throws Exception {\n        WeakReference<ProxyFactory> pfref = proxyMap.get(connection);\n        ProxyFactory pf = null;\n        if (pfref != null && pfref.get() != null && pfref.get().getDomainRoot() != null) {\n            pf = pfref.get();\n            try {\n                pf.getDomainRoot().getAMXReady();\n                return pf;\n            } catch (Exception e) {}\n        }\n        pf = ProxyFactory.getInstance(new MBeanServerConnectionConnectionSource(connection), false);\n        proxyMap.put(connection, new WeakReference<ProxyFactory>(pf));\n        return pf;\n    }\n       \n    public static boolean isEE(DomainRoot dr) {\n        SystemInfo systemInfo = dr.getSystemInfo();\n        return systemInfo.supportsFeature(SystemInfo.CLUSTERS_FEATURE);\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/jmx/Bundle.properties",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\nJMXDetailsPanel.jLabel1.text=User Name:\nJMXDetailsPanel.jLabel2.text=Password:\nJMXDetailsPanel.jLabel3.text=MBean Server Port:\nJMXDetailsPanel.jTextField1.text=jTextField1\nJMXDetailsPanel.jTextField2.text=jTextField2\nJMXDetailsPanel.jLabel1.text_1=User Name:\nJMXDetailsPanel.jLabel2.text_1=Password:\nJMXDetailsPanel.jLabel3.text_1=MBean Server Port:\nJMXDetailsPanel.userName.text_1=admin\nJMXDetailsPanel.password.text=adminadmin\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/jmx/GFJmxModelFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage net.java.visualvm.modules.glassfish.jmx;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.model.ModelFactory;\nimport org.graalvm.visualvm.core.model.ModelProvider;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.io.File;\nimport java.net.MalformedURLException;\nimport javax.management.remote.JMXServiceURL;\nimport net.java.visualvm.modules.glassfish.GlassFishApplicationType;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GFJmxModelFactory extends ModelFactory<JmxModel, Application> implements ModelProvider<JmxModel, Application>{\n    private static final String STORAGE_DIRNAME = \"jmxapplicationsGF\"; // copy from JmxApplicationsSupport ....\n    private static final String PROPERTY_USERNAME = \"prop_username\"; // copy from JmxApplicationsSupport ....\n    private static final String PROPERTY_PASSWORD = \"prop_password\"; // copy from JmxApplicationsSupport ....\n    \n    private static final Storage STORAGE = new Storage(new File(Storage.getPersistentStorageDirectoryString() + File.separator + STORAGE_DIRNAME));\n\n    private final static GFJmxModelFactory INSTANCE = new GFJmxModelFactory();\n    \n    private DialogDescriptor credentialsDD = null;\n    private JMXDetailsPanel credentialsPanel = null;\n    \n    public JmxModel createModelFor(Application app) {\n        // Local applications will use the default JmxModelFactory\n        if (app.isLocalApplication()) {\n            return null;\n        }\n        // Non-GlassFish remote applications will use the default JmxModelFactory too\n        ApplicationType at = ApplicationTypeFactory.getApplicationTypeFor(app);\n        if (!(at instanceof GlassFishApplicationType)) {\n            return null;\n        }\n        String userName = STORAGE.getCustomProperty(PROPERTY_USERNAME);\n        String password = STORAGE.getCustomProperty(PROPERTY_PASSWORD);\n        int serverPort = 8686;\n        getCredentialsPanel().setPassword(password);\n        getCredentialsPanel().setUserName(userName);\n        if (DialogDisplayer.getDefault().notify(getDialogDescriptor()) == DialogDescriptor.OK_OPTION) {\n            STORAGE.setCustomProperty(PROPERTY_USERNAME, getCredentialsPanel().getUserName());\n            STORAGE.setCustomProperty(PROPERTY_PASSWORD, getCredentialsPanel().getPassword());\n            serverPort = getCredentialsPanel().getServerPort();\n        } else {\n            // Revert to default JmxModelFactory on Cancel button\n            return null;\n        }\n        JMXServiceURL serverURL;\n        try {\n            serverURL = new JMXServiceURL(\"service:jmx:rmi:///jndi/rmi://\" +\n                    app.getHost().getHostName() + \":\" + serverPort + \"/jmxrmi\");\n        } catch (MalformedURLException e) {\n            return null;\n        }\n        return null;\n//        return new JmxModel(new JmxApplication(app.getHost(), serverURL, STORAGE));\n    }\n\n    @Override\n    public int priority() {\n        return 10;\n    }\n    \n    public static void initialize() {\n        JmxModelFactory.getDefault().registerProvider(INSTANCE);\n    }\n\n    public static void shutdown() {\n        JmxModelFactory.getDefault().unregisterProvider(INSTANCE);\n    }\n    \n    private synchronized  DialogDescriptor getDialogDescriptor() {\n        if (credentialsDD == null) {\n            credentialsDD = new DialogDescriptor(getCredentialsPanel(), \"JMX Credentials\", true, DialogDescriptor.OK_CANCEL_OPTION, DialogDescriptor.CANCEL_OPTION, null);\n        }\n        return credentialsDD;\n    }\n    private synchronized JMXDetailsPanel getCredentialsPanel() {\n        if (credentialsPanel == null) {\n            credentialsPanel = new JMXDetailsPanel();\n            credentialsPanel.addPropertyChangeListener(JMXDetailsPanel.VALIDITY_PROPERTY, new PropertyChangeListener() {\n                public void propertyChange(PropertyChangeEvent evt) {\n                    getDialogDescriptor().setValid(getCredentialsPanel().hasValidCredentials());\n                }\n            });\n        }\n        return credentialsPanel;\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/jmx/JMXDetailsPanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.5\" maxVersion=\"1.6\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"jSeparator1\" alignment=\"0\" pref=\"253\" max=\"32767\" attributes=\"0\"/>\n                  <Group type=\"102\" attributes=\"0\">\n                      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                          <Component id=\"jLabel1\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"jLabel2\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      </Group>\n                      <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                          <Component id=\"password\" pref=\"164\" max=\"32767\" attributes=\"2\"/>\n                          <Component id=\"userName\" alignment=\"0\" pref=\"164\" max=\"32767\" attributes=\"2\"/>\n                      </Group>\n                  </Group>\n                  <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n                      <Component id=\"jLabel3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                      <Component id=\"serverPort\" pref=\"117\" max=\"32767\" attributes=\"0\"/>\n                  </Group>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"jLabel1\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"userName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"jLabel2\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"password\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"16\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jSeparator1\" min=\"-2\" pref=\"10\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"jLabel3\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"serverPort\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"32767\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"jLabel1\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"userName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"net/java/visualvm/modules/glassfish/jmx/Bundle.properties\" key=\"JMXDetailsPanel.jLabel1.text_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"userName\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"net/java/visualvm/modules/glassfish/jmx/Bundle.properties\" key=\"JMXDetailsPanel.userName.text_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"jLabel2\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"password\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"net/java/visualvm/modules/glassfish/jmx/Bundle.properties\" key=\"JMXDetailsPanel.jLabel2.text_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JPasswordField\" name=\"password\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"net/java/visualvm/modules/glassfish/jmx/Bundle.properties\" key=\"JMXDetailsPanel.password.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"jLabel3\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"net/java/visualvm/modules/glassfish/jmx/Bundle.properties\" key=\"JMXDetailsPanel.jLabel3.text_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JSpinner\" name=\"serverPort\">\n      <Properties>\n        <Property name=\"model\" type=\"javax.swing.SpinnerModel\" editor=\"org.netbeans.modules.form.editors2.SpinnerModelEditor\">\n          <SpinnerModel initial=\"8686\" maximum=\"65535\" minimum=\"1024\" numberType=\"java.lang.Integer\" stepSize=\"1\" type=\"number\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JSeparator\" name=\"jSeparator1\">\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/jmx/JMXDetailsPanel.java",
    "content": "/*\n * JMXDetailsPanel.java\n *\n * Created on March 14, 2008, 9:17 AM\n */\n\npackage net.java.visualvm.modules.glassfish.jmx;\n\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.Document;\n\n/**\n *\n * @author  Jaroslav Bachorik\n */\npublic class JMXDetailsPanel extends javax.swing.JPanel {    \n    public static final String VALIDITY_PROPERTY = JMXDetailsPanel.class.getName() + \"#isValid\";\n    \n    private boolean portValid = true;\n    private boolean usernameValid = false;\n    private boolean passwordValid = false;\n    \n    /** Creates new form JMXDetailsPanel */\n    public JMXDetailsPanel() {\n        initComponents();\n        postInit();\n    }\n\n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    @SuppressWarnings(\"unchecked\")\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        jLabel1 = new javax.swing.JLabel();\n        userName = new javax.swing.JTextField();\n        jLabel2 = new javax.swing.JLabel();\n        password = new javax.swing.JPasswordField();\n        jLabel3 = new javax.swing.JLabel();\n        serverPort = new javax.swing.JSpinner();\n        jSeparator1 = new javax.swing.JSeparator();\n\n        jLabel1.setLabelFor(userName);\n        jLabel1.setText(org.openide.util.NbBundle.getMessage(JMXDetailsPanel.class, \"JMXDetailsPanel.jLabel1.text_1\")); // NOI18N\n\n        userName.setText(org.openide.util.NbBundle.getMessage(JMXDetailsPanel.class, \"JMXDetailsPanel.userName.text_1\")); // NOI18N\n\n        jLabel2.setLabelFor(password);\n        jLabel2.setText(org.openide.util.NbBundle.getMessage(JMXDetailsPanel.class, \"JMXDetailsPanel.jLabel2.text_1\")); // NOI18N\n\n        password.setText(org.openide.util.NbBundle.getMessage(JMXDetailsPanel.class, \"JMXDetailsPanel.password.text\")); // NOI18N\n\n        jLabel3.setText(org.openide.util.NbBundle.getMessage(JMXDetailsPanel.class, \"JMXDetailsPanel.jLabel3.text_1\")); // NOI18N\n\n        serverPort.setModel(new javax.swing.SpinnerNumberModel(8686, 1024, 65535, 1));\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 253, Short.MAX_VALUE)\n                    .addGroup(layout.createSequentialGroup()\n                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                            .addComponent(jLabel1)\n                            .addComponent(jLabel2))\n                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                            .addComponent(password, javax.swing.GroupLayout.DEFAULT_SIZE, 164, Short.MAX_VALUE)\n                            .addComponent(userName, javax.swing.GroupLayout.DEFAULT_SIZE, 164, Short.MAX_VALUE)))\n                    .addGroup(layout.createSequentialGroup()\n                        .addComponent(jLabel3)\n                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                        .addComponent(serverPort, javax.swing.GroupLayout.DEFAULT_SIZE, 117, Short.MAX_VALUE)))\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(jLabel1)\n                    .addComponent(userName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(jLabel2)\n                    .addComponent(password, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addGap(16, 16, 16)\n                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(jLabel3)\n                    .addComponent(serverPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))\n        );\n    }// </editor-fold>//GEN-END:initComponents\n\n\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JLabel jLabel1;\n    private javax.swing.JLabel jLabel2;\n    private javax.swing.JLabel jLabel3;\n    private javax.swing.JSeparator jSeparator1;\n    private javax.swing.JPasswordField password;\n    private javax.swing.JSpinner serverPort;\n    private javax.swing.JTextField userName;\n    // End of variables declaration//GEN-END:variables\n\n    private void postInit() {\n        serverPort.getModel().addChangeListener(new ChangeListener() {\n\n            public void stateChanged(ChangeEvent e) {\n                if (serverPort.getModel().getValue() != null && serverPort.getModel().getValue().toString().length() > 0) {\n                    portValid = true;\n                } else {\n                    portValid = false;\n                }\n                firePropertyChange(VALIDITY_PROPERTY, null, null);\n            }\n        });\n        userName.getDocument().addDocumentListener(new DocumentListener() {\n\n            public void insertUpdate(DocumentEvent e) {\n                checkValidity(e.getDocument());\n            }\n\n            public void removeUpdate(DocumentEvent e) {\n                checkValidity(e.getDocument());\n            }\n\n            public void changedUpdate(DocumentEvent e) {\n                checkValidity(e.getDocument());\n            }\n            \n            private void checkValidity(Document document) {\n                if (document.getLength() > 0) {\n                    usernameValid = true;\n                } else {\n                    usernameValid = false;\n                }\n                firePropertyChange(VALIDITY_PROPERTY, null, null);\n            }\n        });\n        password.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) {\n                checkValidity(e.getDocument());\n            }\n\n            public void removeUpdate(DocumentEvent e) {\n                checkValidity(e.getDocument());\n            }\n\n            public void changedUpdate(DocumentEvent e) {\n                checkValidity(e.getDocument());\n            }\n            \n            private void checkValidity(Document document) {\n                if (document.getLength() > 0) {\n                    passwordValid = true;\n                } else {\n                    passwordValid = false;\n                }\n                firePropertyChange(VALIDITY_PROPERTY, null, null);\n            }\n        });\n    }\n    \n    public int getServerPort() {\n        return (Integer)serverPort.getModel().getValue();\n    }\n\n    public void setServerPort(int value) {\n        this.serverPort.getModel().setValue(value);\n    }\n\n    public String getUserName() {\n        return userName.getText();\n    }\n    \n    public void setUserName(String value) {\n        userName.setText(value);\n    }\n    \n    public String getPassword() {\n        return new String(password.getPassword());\n    }\n    \n    public void setPassword(String value) {\n        password.setText(value);\n    }\n    \n    public boolean hasValidCredentials() {\n        return portValid && usernameValid && passwordValid;\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/jmx/JMXUtil.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage net.java.visualvm.modules.glassfish.jmx;\n\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport java.io.IOException;\nimport java.util.Map;\nimport java.util.logging.Logger;\nimport javax.management.AttributeNotFoundException;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.MBeanException;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\nimport javax.management.ReflectionException;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class JMXUtil {\n    private static final Logger LOGGER = Logger.getLogger(JMXUtil.class.getName());\n    \n    public static final String getServerName(JmxModel jmx) {\n        try {\n            Object serverNameObj = jmx.getMBeanServerConnection().getAttribute(new ObjectName(\"com.sun.appserv:j2eeType=J2EEServer,name=server,category=runtime\"), \"J2EEServer\");\n            return serverNameObj != null ? serverNameObj.toString() : null;\n        } catch (MalformedObjectNameException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerName\", ex);\n        } catch (NullPointerException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerName\", ex);\n        } catch (MBeanException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerName\", ex);\n        } catch (AttributeNotFoundException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerName\", ex);\n        } catch (InstanceNotFoundException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerName\", ex);\n        } catch (ReflectionException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerName\", ex);\n        } catch (IOException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerName\", ex);\n        }\n        return null;\n    }\n    \n    public static final String getServerConfig(JmxModel jmx) {\n        try {\n            Object serverConfObj = jmx.getMBeanServerConnection().getAttribute(new ObjectName(\"com.sun.appserv:j2eeType=J2EEServer,name=server,category=runtime\"), \"config-ref\");\n            return serverConfObj != null ? serverConfObj.toString() : null;\n        } catch (MalformedObjectNameException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerConfig\", ex);\n        } catch (NullPointerException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerConfig\", ex);\n        } catch (MBeanException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerConfig\", ex);\n        } catch (AttributeNotFoundException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerConfig\", ex);\n        } catch (InstanceNotFoundException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerConfig\", ex);\n        } catch (ReflectionException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerConfig\", ex);\n        } catch (IOException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerConfig\", ex);\n        }\n        return null;\n    }\n    \n    public static final String getServerConfigDir(JmxModel jmx) {\n        try {\n            Object serverConfDirObj = jmx.getMBeanServerConnection().invoke(new ObjectName(\"com.sun.appserv:type=domain,category=config\"), \"getConfigDir\", null, null);\n            return serverConfDirObj != null ? serverConfDirObj.toString() : null;\n        } catch (MalformedObjectNameException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerConfigDir\", ex);\n        } catch (NullPointerException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerConfigDir\", ex);\n        } catch (MBeanException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerConfigDir\", ex);\n        } catch (InstanceNotFoundException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerConfigDir\", ex);\n        } catch (ReflectionException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerConfigDir\", ex);\n        } catch (IOException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerConfigDir\", ex);\n        }\n        return null;\n    }\n    \n    public static final String getServerDomain(JmxModel jmx) {\n        try {\n            Object serverDomainObj = jmx.getMBeanServerConnection().invoke(new ObjectName(\"com.sun.appserv:type=domain,category=config\"), \"getName\", null, null);\n            return serverDomainObj != null ? serverDomainObj.toString() : null;\n        } catch (MalformedObjectNameException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerDomain\", ex);\n        } catch (NullPointerException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerDomain\", ex);\n        } catch (MBeanException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerDomain\", ex);\n        } catch (InstanceNotFoundException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerDomain\", ex);\n        } catch (ReflectionException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerDomain\", ex);\n        } catch (IOException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getServerDomain\", ex);\n        }\n        return null;\n    }\n    \n    public static final String getObjectName(String type, String moduleUniqueName, JmxModel jmx) {\n        try {\n            for(String deplObjName : getDeployedObjects(jmx)) {\n                if (deplObjName.startsWith(\"com.sun.appserv:j2eeType=\" + type + \",name=\" + moduleUniqueName)) {\n                    return deplObjName;\n                }\n            }\n        } catch (NullPointerException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getObjectName\", ex);\n        }\n        return moduleUniqueName;\n    }\n    \n    public static final String getJ2EEAppName(String objectName) {\n        int startIndex = objectName.indexOf(\",J2EEApplication=\");\n        int stopIndex = -1;\n        if (startIndex > -1) {\n            stopIndex = objectName.indexOf(\",\", startIndex + 1);\n        }\n        if (startIndex > -1 && stopIndex > -1 && stopIndex > startIndex) {\n            String appName = objectName.substring(startIndex + 17, stopIndex - 1);\n            if (appName == null || appName.startsWith(\"nul\")) return null;\n            return new String(appName);\n        } else {\n            return null;\n        }\n    }\n    \n    public static final String getWebModuleName(String objectName, JmxModel jmx) {\n        try {\n            return (String) jmx.getMBeanServerConnection().getAttribute(new ObjectName(objectName), \"name\");\n        } catch (MBeanException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        } catch (AttributeNotFoundException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        } catch (InstanceNotFoundException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        } catch (ReflectionException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        } catch (IOException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        } catch (MalformedObjectNameException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        } catch (NullPointerException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        }\n        return null;\n    }\n    \n    public static final String getWebModuleName(String objectName, JmxModel jmx, Map<String, String> context2name) {\n        try {\n            String ctxMapping = (String) jmx.getMBeanServerConnection().getAttribute(new ObjectName(objectName), \"name\");\n            if (!ctxMapping.startsWith(\"/\")) ctxMapping = \"/\" + ctxMapping;\n            return context2name.get(ctxMapping);\n        } catch (MBeanException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        } catch (AttributeNotFoundException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        } catch (InstanceNotFoundException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        } catch (ReflectionException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        } catch (IOException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        } catch (MalformedObjectNameException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        } catch (NullPointerException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getWebModuleName\", ex);\n        }\n        return null;\n    }\n    \n    public static final String[] getDeployedObjects(JmxModel jmx) {\n        try {\n            ObjectName on = new ObjectName(\"com.sun.appserv:j2eeType=J2EEServer,name=server,category=runtime\");\n            return (String[]) jmx.getMBeanServerConnection().getAttribute(on, \"deployedObjects\");\n        } catch (MBeanException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getDeployedObjects\", ex);\n        } catch (AttributeNotFoundException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getDeployedObjects\", ex);\n        } catch (InstanceNotFoundException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getDeployedObjects\", ex);\n        } catch (ReflectionException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getDeployedObjects\", ex);\n        } catch (IOException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getDeployedObjects\", ex);\n        } catch (MalformedObjectNameException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getDeployedObjects\", ex);\n        } catch (NullPointerException ex) {\n            LOGGER.throwing(JMXUtil.class.getName(), \"getDeployedObjects\", ex);\n        }\n        return new String[0];\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/ui/Bundle.properties",
    "content": "Tester.jToggleButton1.text=M\nConnectionQueuePanel.labelUtilization.text=Connections:\nConnectionQueuePanel.lableRefusalRate.text=Refusal Rate [%]:\nHttpListenerPanel.labelThreads.text=Threads:\nHttpListenerPanel.labelListeners.text=Listener:\nFileCachePanel.labelHitRatio.text=Hit Ratio:\nKeepAlivePanel.labelUtilization.text=Utilization:\nTransactionsPanel.labelCommits.text=Commits [%]:\nTransactionsPanel.labelRollbacks.text=Rollbacks [%]:\nFileCachePanel.jLabel1.text=Cache Utilization [%]\nConnectionQueuePanel.jLabel1.text=Averages\nKeepAlivePanel.jLabel1.text=Finished Connections\nTransactionsPanel.jLabel1.text=Active Transactions\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/ui/GenericModel.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage net.java.visualvm.modules.glassfish.ui;\n\nimport java.util.Observable;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class GenericModel extends Observable {\n    private long lastTimeStamp;\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class RangedLong {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        public final long max;\n        public final long min;\n        public final long val;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public RangedLong(long min, long max, long val) {\n            this.min = min;\n            this.max = max;\n            this.val = val;\n        }\n        \n        public static final RangedLong ZERO = new RangedLong(0, 0, 0);\n    }\n    \n    public long getLastTimeStamp() {\n        return lastTimeStamp;\n    }\n\n    public void refresh(long timeStamp) {\n        lastTimeStamp = timeStamp;\n        setChanged();\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/ui/StatsTable.java",
    "content": "package net.java.visualvm.modules.glassfish.ui;\n\nimport java.util.Vector;\nimport javax.swing.JTable;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.event.TableModelEvent;\nimport javax.swing.table.TableColumnModel;\nimport javax.swing.table.TableModel;\n\npublic class StatsTable extends JTable {\n\n    private String selectedRowRef = null;\n    {\n        getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n    }\n\n    public StatsTable(Object[][] rowData, Object[] columnNames) {\n        super(rowData, columnNames);\n    }\n\n    public StatsTable(Vector rowData, Vector columnNames) {\n        super(rowData, columnNames);\n    }\n\n    public StatsTable(int numRows, int numColumns) {\n        super(numRows, numColumns);\n    }\n\n    public StatsTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) {\n        super(dm, cm, sm);\n    }\n\n    public StatsTable(TableModel dm, TableColumnModel cm) {\n        super(dm, cm);\n    }\n\n    public StatsTable(TableModel dm) {\n        super(dm);\n    }\n\n    public StatsTable() {\n        super();\n    }\n\n    @Override\n    public void tableChanged(TableModelEvent e) {\n        selectedRowRef = getSelectedRowID();\n        super.tableChanged(e);\n        setSelectedRowByID(selectedRowRef);\n    }\n\n    private String getSelectedRowID() {\n        int rc = getRowCount();\n        int sr = getSelectedRow();\n        if (getRowCount() == 0 || getSelectedRow() <= 0) {\n            return null;\n        }\n\n        return getValueAt(getSelectedRow(), 0).toString();\n    }\n\n    private void setSelectedRowByID(String id) {\n        if (id == null) {\n            return;\n        }\n        for (int i = 0; i < getRowCount(); i++) {\n            if (getValueAt(i, 0).equals(id)) {\n                setRowSelectionInterval(i, i);\n                return;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/ui/Tachometer.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n\npackage net.java.visualvm.modules.glassfish.ui;\n\nimport java.awt.AWTException;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.ImageCapabilities;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport java.awt.RenderingHints;\nimport java.awt.Shape;\nimport java.awt.font.GlyphVector;\nimport java.awt.font.TextLayout;\nimport java.awt.geom.AffineTransform;\nimport java.awt.image.VolatileImage;\nimport javax.swing.JComponent;\nimport javax.swing.border.Border;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class Tachometer extends JComponent {\n    private int val = 0;\n    private int max = 100;\n    private int min = 0;\n    \n    private final static Dimension MINIMUM_SIZE = new Dimension(80, 80);\n    private final static double MAX_ANGLE = 270d;\n    \n    @Override\n    public void paint(Graphics g) {\n        try {\n            Border border = getBorder();\n            Insets insets = new Insets(0, 0, 0, 0);\n            if (border != null) {\n                insets = border.getBorderInsets(this);\n            }\n            \n            int diameter = Math.min(getBounds().width - (insets.left + insets.right), getBounds().height - (insets.top + insets.bottom)) - 4;\n            VolatileImage img = createVolatileImage(getBounds().width - (insets.left + insets.right), getBounds().height - (insets.top + insets.bottom), new ImageCapabilities(true));\n            Graphics2D gr = img.createGraphics();\n\n            gr.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\n            gr.drawOval(insets.left, insets.top, diameter, diameter);\n            TextLayout textTl = new TextLayout(\"fERRARI\", getFont(), gr.getFontRenderContext());\n            AffineTransform at = new AffineTransform();\n            at.translate(0, (float)getBounds().getHeight() - (insets.top + insets.bottom) - (float)textTl.getBounds().getHeight());\n            at.scale(2d, 2d);\n//            at.shear(1.3d, 0.8d);\n            Shape textShape  = textTl.getOutline(at);\n            gr.fill(textShape);\n//            GlyphVector gv = getFont().createGlyphVector(gr.getFontRenderContext(), \"fERRARI\");\n//            Rectangle bounds = gv.getPixelBounds(gr.getFontRenderContext(), 0, 0);\n//            double scale = (double)(getBounds().width - (insets.left + insets.right)) / (double)bounds.width;\n//            for(int i=0;i<gv.getNumGlyphs();i++) {\n//                gv.setGlyphTransform(i, AffineTransform.getScaleInstance(scale, 1d));\n//                gv.\n//            }\n//            gr.drawGlyphVector(gv, insets.left + 2, getBounds().height - (insets.top + insets.bottom) - 2 - bounds.height);\n            int lineLenght = diameter / 2 - 10;\n            gr.drawLine(diameter / 2, diameter / 2, diameter / 2 - getXOnArc(lineLenght, getAngle()), diameter / 2 - getYOnArc(lineLenght, getAngle()));\n            gr.dispose();\n            \n            g.drawImage(img, insets.left, insets.top, this);\n            if (border != null) {\n                border.paintBorder(this, g, 0, 0, getBounds().width, getBounds().height);\n            }\n        } catch (AWTException e) {}\n    }\n\n    @Override\n    public Dimension getMinimumSize() {\n        return MINIMUM_SIZE;\n    }\n\n    @Override\n    public Dimension getPreferredSize() {\n        return MINIMUM_SIZE;\n    }\n    \n    public void setMinValue(int minValue) {\n        min = minValue;\n        repaint();\n    }\n    \n    public void setMaxValue(int maxValue) {\n        max = maxValue;\n        repaint();\n    }\n    \n    public void setValue(int value) {\n        val = value;\n        repaint();\n    }\n    \n    private static int getYOnArc(int diameter, int angle) {\n        return (int)(Math.sin(getRadians(angle)) * (double)diameter);\n    }\n    \n    private static int getXOnArc(int diameter, int angle) {\n        return (int)(Math.cos(getRadians(angle)) * (double)diameter);\n    }\n    \n    private static double getRadians(int angle) {\n        return 0.0175d * angle - Math.PI / 4;\n    }\n    \n    private int getAngle() {\n        double ratio = (double)val / (double)(max - min);\n        int angle = (int)(ratio * MAX_ANGLE);\n        return angle;\n    }\n}\n"
  },
  {
    "path": "plugins/glassfish/src/net/java/visualvm/modules/glassfish/util/Touple.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage net.java.visualvm.modules.glassfish.util;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class Touple<X, Y> {\n    final private X x;\n    final private Y y;\n    \n    public Touple(X aX, Y aY) {\n        x = aX;\n        y = aY;\n    }\n    \n    public X getX() {\n        return x;\n    }\n    \n    public Y getY() {\n        return y;\n    }\n}\n"
  },
  {
    "path": "plugins/graaljs/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.graaljs\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.graaljs.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n    <target name=\"download-all-extbins\" unless=\"ext.binaries.downloaded\" depends=\"init\">\n      <echo>Downloading external binaries (external/ directory)...</echo>\n      <property name=\"binaries.cache\" location=\"${user.home}/.hgexternalcache\"/>\n      <property name=\"binaries.server\" value=\"https://netbeans.osuosl.org/binaries/\"/>\n      <downloadbinaries cache=\"${binaries.cache}\" server=\"${binaries.server}\" >\n          <manifest dir=\".\">\n              <include name=\"external/binaries-list\"/>\n          </manifest>\n      </downloadbinaries>\n      <property name=\"ext.binaries.downloaded\" value=\"true\"/>\n    </target>\n\n    <target name=\"-pre-compile\" depends=\"download-all-extbins\">      \n    </target>\n\n    <target name=\"-pre-release\" depends=\"compile\">\n        <taskdef name=\"releasefilescopy\" classname=\"org.netbeans.nbbuild.extlibs.ReleaseFilesCopy\" classpath=\"${harness.dir}/tasks.jar\"/>\n        <releasefilescopy cluster=\"${cluster}\"/>\n    </target>\n\n    <target name=\"-release.files\" depends=\"projectized-common.-release.files\">\n        <taskdef name=\"releasefilesextra\" classname=\"org.netbeans.nbbuild.extlibs.ReleaseFilesExtra\" classpath=\"${harness.dir}/tasks.jar\"/>\n        <releasefilesextra property=\"release.files.extra\"/>\n    </target>\n\n    <target name=\"-pre-nbm\" depends=\"compile\">\n      <property name=\"license.file.override\" location=\"${build.dir}/license\"/>\n      <property name=\"extra.license.files\" value=\"\"/>\n      <taskdef name=\"releasefileslicense\" classname=\"org.netbeans.nbbuild.extlibs.ReleaseFilesLicense\" classpath=\"${harness.dir}/tasks.jar\"/>\n      <releasefileslicense license=\"${license.file.override}\" standardlicense=\"${license.file}\" extralicensefiles=\"${extra.license.files}\"/>\n    </target>\n</project>\n"
  },
  {
    "path": "plugins/graaljs/external/asm-util-9.2-license.txt",
    "content": "https://gitlab.ow2.org/asm/asm/blob/master/LICENSE.txt\n\nASM: a very small and fast Java bytecode manipulation framework\n Copyright (c) 2000-2011 INRIA, France Telecom\n All rights reserved.\n\n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions\n are met:\n 1. Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n 2. Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in the\n    documentation and/or other materials provided with the distribution.\n 3. Neither the name of the copyright holders nor the names of its\n    contributors may be used to endorse or promote products derived from\n    this software without specific prior written permission.\n\n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "plugins/graaljs/external/binaries-list",
    "content": "6267785D7EA4BCC1A0D3F40DE7D05B77A6C2BEEC org.graalvm.js:js-scriptengine:22.3.0\n42A5D241E5B92589DBF1CBB5DD3EAE0360707C8F org.graalvm.js:js:22.3.0\n3D88E01158436B353C4B54A396D209F9E2791CEF org.graalvm.regex:regex:22.3.0\n2E02DD479A207794D1A5A14B5A83D5556880C876 org.graalvm.truffle:truffle-api:22.3.0\n83179E3310A2ECE87266923FEDE5EF7355C68C9A org.graalvm.sdk:graal-sdk:22.3.0\n9E7D3304C23F9BA5CB71915F7CCE23231A57A445 com.ibm.icu:icu4j:71.1\nFBC178FC5BA3DAB50FD7E8A5317B8B647C8E8946 org.ow2.asm:asm-util:9.2\n"
  },
  {
    "path": "plugins/graaljs/external/icu4j-71.1-license.txt",
    "content": "UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE\n\nSee Terms of Use <https://www.unicode.org/copyright.html>\nfor definitions of Unicode Inc.s Data Files and Software.\n\nNOTICE TO USER: Carefully read the following legal agreement.\nBY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S\nDATA FILES (\"DATA FILES\"), AND/OR SOFTWARE (\"SOFTWARE\"),\nYOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE\nTERMS AND CONDITIONS OF THIS AGREEMENT.\nIF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE\nTHE DATA FILES OR SOFTWARE.\n\nCOPYRIGHT AND PERMISSION NOTICE\n\nCopyright  1991-2022 Unicode, Inc. All rights reserved.\nDistributed under the Terms of Use in https://www.unicode.org/copyright.html.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Unicode data files and any associated documentation\n(the \"Data Files\") or Unicode software and any associated documentation\n(the \"Software\") to deal in the Data Files or Software\nwithout restriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, and/or sell copies of\nthe Data Files or Software, and to permit persons to whom the Data Files\nor Software are furnished to do so, provided that either\n(a) this copyright and permission notice appear with all copies\nof the Data Files or Software, or\n(b) this copyright and permission notice appear in associated\nDocumentation.\n\nTHE DATA FILES AND SOFTWARE ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF\nANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\nWARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT OF THIRD PARTY RIGHTS.\nIN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS\nNOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL\nDAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,\nDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\nTORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THE DATA FILES OR SOFTWARE.\n\nExcept as contained in this notice, the name of a copyright holder\nshall not be used in advertising or otherwise to promote the sale,\nuse or other dealings in these Data Files or Software without prior\nwritten authorization of the copyright holder.\n\n----------------------------------------------------------------------\n\nThird-Party Software Licenses\n\nThis section contains third-party software notices and/or additional\nterms for licensed third-party software components included within ICU\nlibraries.\n\n----------------------------------------------------------------------\n\nICU License - ICU 1.8.1 to ICU 57.1\n\nCOPYRIGHT AND PERMISSION NOTICE\n\nCopyright (c) 1995-2016 International Business Machines Corporation and others\nAll rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, and/or sell copies of the Software, and to permit persons\nto whom the Software is furnished to do so, provided that the above\ncopyright notice(s) and this permission notice appear in all copies of\nthe Software and that both the above copyright notice(s) and this\npermission notice appear in supporting documentation.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR\nHOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY\nSPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER\nRESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF\nCONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN\nCONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\nExcept as contained in this notice, the name of a copyright holder\nshall not be used in advertising or otherwise to promote the sale, use\nor other dealings in this Software without prior written authorization\nof the copyright holder.\n\nAll trademarks and registered trademarks mentioned herein are the\nproperty of their respective owners.\n\n----------------------------------------------------------------------\n\nChinese/Japanese Word Break Dictionary Data (cjdict.txt)\n\n #     The Google Chrome software developed by Google is licensed under\n # the BSD license. Other software included in this distribution is\n # provided under other licenses, as set forth below.\n #\n #  The BSD License\n #  http://opensource.org/licenses/bsd-license.php\n #  Copyright (C) 2006-2008, Google Inc.\n #\n #  All rights reserved.\n #\n #  Redistribution and use in source and binary forms, with or without\n # modification, are permitted provided that the following conditions are met:\n #\n #  Redistributions of source code must retain the above copyright notice,\n # this list of conditions and the following disclaimer.\n #  Redistributions in binary form must reproduce the above\n # copyright notice, this list of conditions and the following\n # disclaimer in the documentation and/or other materials provided with\n # the distribution.\n #  Neither the name of  Google Inc. nor the names of its\n # contributors may be used to endorse or promote products derived from\n # this software without specific prior written permission.\n #\n #\n #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n # CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n #\n #\n #  The word list in cjdict.txt are generated by combining three word lists\n # listed below with further processing for compound word breaking. The\n # frequency is generated with an iterative training against Google web\n # corpora.\n #\n #  * Libtabe (Chinese)\n #    - https://sourceforge.net/project/?group_id=1519\n #    - Its license terms and conditions are shown below.\n #\n #  * IPADIC (Japanese)\n #    - http://chasen.aist-nara.ac.jp/chasen/distribution.html\n #    - Its license terms and conditions are shown below.\n #\n #  ---------COPYING.libtabe ---- BEGIN--------------------\n #\n #  /*\n #   * Copyright (c) 1999 TaBE Project.\n #   * Copyright (c) 1999 Pai-Hsiang Hsiao.\n #   * All rights reserved.\n #   *\n #   * Redistribution and use in source and binary forms, with or without\n #   * modification, are permitted provided that the following conditions\n #   * are met:\n #   *\n #   * . Redistributions of source code must retain the above copyright\n #   *   notice, this list of conditions and the following disclaimer.\n #   * . Redistributions in binary form must reproduce the above copyright\n #   *   notice, this list of conditions and the following disclaimer in\n #   *   the documentation and/or other materials provided with the\n #   *   distribution.\n #   * . Neither the name of the TaBE Project nor the names of its\n #   *   contributors may be used to endorse or promote products derived\n #   *   from this software without specific prior written permission.\n #   *\n #   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n #   * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n #   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n #   * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n #   * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n #   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n #   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n #   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n #   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n #   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n #   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n #   * OF THE POSSIBILITY OF SUCH DAMAGE.\n #   */\n #\n #  /*\n #   * Copyright (c) 1999 Computer Systems and Communication Lab,\n #   *                    Institute of Information Science, Academia\n #       *                    Sinica. All rights reserved.\n #   *\n #   * Redistribution and use in source and binary forms, with or without\n #   * modification, are permitted provided that the following conditions\n #   * are met:\n #   *\n #   * . Redistributions of source code must retain the above copyright\n #   *   notice, this list of conditions and the following disclaimer.\n #   * . Redistributions in binary form must reproduce the above copyright\n #   *   notice, this list of conditions and the following disclaimer in\n #   *   the documentation and/or other materials provided with the\n #   *   distribution.\n #   * . Neither the name of the Computer Systems and Communication Lab\n #   *   nor the names of its contributors may be used to endorse or\n #   *   promote products derived from this software without specific\n #   *   prior written permission.\n #   *\n #   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n #   * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n #   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n #   * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n #   * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n #   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n #   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n #   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n #   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n #   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n #   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n #   * OF THE POSSIBILITY OF SUCH DAMAGE.\n #   */\n #\n #  Copyright 1996 Chih-Hao Tsai @ Beckman Institute,\n #      University of Illinois\n #  c-tsai4@uiuc.edu  http://casper.beckman.uiuc.edu/~c-tsai4\n #\n #  ---------------COPYING.libtabe-----END--------------------------------\n #\n #\n #  ---------------COPYING.ipadic-----BEGIN-------------------------------\n #\n #  Copyright 2000, 2001, 2002, 2003 Nara Institute of Science\n #  and Technology.  All Rights Reserved.\n #\n #  Use, reproduction, and distribution of this software is permitted.\n #  Any copy of this software, whether in its original form or modified,\n #  must include both the above copyright notice and the following\n #  paragraphs.\n #\n #  Nara Institute of Science and Technology (NAIST),\n #  the copyright holders, disclaims all warranties with regard to this\n #  software, including all implied warranties of merchantability and\n #  fitness, in no event shall NAIST be liable for\n #  any special, indirect or consequential damages or any damages\n #  whatsoever resulting from loss of use, data or profits, whether in an\n #  action of contract, negligence or other tortuous action, arising out\n #  of or in connection with the use or performance of this software.\n #\n #  A large portion of the dictionary entries\n #  originate from ICOT Free Software.  The following conditions for ICOT\n #  Free Software applies to the current dictionary as well.\n #\n #  Each User may also freely distribute the Program, whether in its\n #  original form or modified, to any third party or parties, PROVIDED\n #  that the provisions of Section 3 (\"NO WARRANTY\") will ALWAYS appear\n #  on, or be attached to, the Program, which is distributed substantially\n #  in the same form as set out herein and that such intended\n #  distribution, if actually made, will neither violate or otherwise\n #  contravene any of the laws and regulations of the countries having\n #  jurisdiction over the User or the intended distribution itself.\n #\n #  NO WARRANTY\n #\n #  The program was produced on an experimental basis in the course of the\n #  research and development conducted during the project and is provided\n #  to users as so produced on an experimental basis.  Accordingly, the\n #  program is provided without any warranty whatsoever, whether express,\n #  implied, statutory or otherwise.  The term \"warranty\" used herein\n #  includes, but is not limited to, any warranty of the quality,\n #  performance, merchantability and fitness for a particular purpose of\n #  the program and the nonexistence of any infringement or violation of\n #  any right of any third party.\n #\n #  Each user of the program will agree and understand, and be deemed to\n #  have agreed and understood, that there is no warranty whatsoever for\n #  the program and, accordingly, the entire risk arising from or\n #  otherwise connected with the program is assumed by the user.\n #\n #  Therefore, neither ICOT, the copyright holder, or any other\n #  organization that participated in or was otherwise related to the\n #  development of the program and their respective officials, directors,\n #  officers and other employees shall be held liable for any and all\n #  damages, including, without limitation, general, special, incidental\n #  and consequential damages, arising out of or otherwise in connection\n #  with the use or inability to use the program or any product, material\n #  or result produced or otherwise obtained by using the program,\n #  regardless of whether they have been advised of, or otherwise had\n #  knowledge of, the possibility of such damages at any time during the\n #  project or thereafter.  Each user will be deemed to have agreed to the\n #  foregoing by his or her commencement of use of the program.  The term\n #  \"use\" as used herein includes, but is not limited to, the use,\n #  modification, copying and distribution of the program and the\n #  production of secondary products from the program.\n #\n #  In the case where the program, whether in its original form or\n #  modified, was distributed or delivered to or received by a user from\n #  any person, organization or entity other than ICOT, unless it makes or\n #  grants independently of ICOT any specific warranty to the user in\n #  writing, such person, organization or entity, will also be exempted\n #  from and not be held liable to the user for any such damages as noted\n #  above as far as the program is concerned.\n #\n #  ---------------COPYING.ipadic-----END----------------------------------\n\n----------------------------------------------------------------------\n\nLao Word Break Dictionary Data (laodict.txt)\n\n # Copyright (C) 2016 and later: Unicode, Inc. and others.\n # License & terms of use: http://www.unicode.org/copyright.html\n # Copyright (c) 2015 International Business Machines Corporation\n # and others. All Rights Reserved.\n #\n # Project: https://github.com/rober42539/lao-dictionary\n # Dictionary: https://github.com/rober42539/lao-dictionary/laodict.txt\n # License: https://github.com/rober42539/lao-dictionary/LICENSE.txt\n #          (copied below)\n #\n #\tThis file is derived from the above dictionary version of Nov 22, 2020\n #  ----------------------------------------------------------------------\n #  Copyright (C) 2013 Brian Eugene Wilson, Robert Martin Campbell.\n #  All rights reserved.\n #\n #  Redistribution and use in source and binary forms, with or without\n #  modification, are permitted provided that the following conditions are met:\n #\n #  Redistributions of source code must retain the above copyright notice, this\n #  list of conditions and the following disclaimer. Redistributions in binary\n #  form must reproduce the above copyright notice, this list of conditions and\n #  the following disclaimer in the documentation and/or other materials\n #  provided with the distribution.\n #\n # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n # \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n # OF THE POSSIBILITY OF SUCH DAMAGE.\n #  --------------------------------------------------------------------------\n\n----------------------------------------------------------------------\n\nBurmese Word Break Dictionary Data (burmesedict.txt)\n\n #  Copyright (c) 2014 International Business Machines Corporation\n #  and others. All Rights Reserved.\n #\n #  This list is part of a project hosted at:\n #    github.com/kanyawtech/myanmar-karen-word-lists\n #\n #  --------------------------------------------------------------------------\n #  Copyright (c) 2013, LeRoy Benjamin Sharon\n #  All rights reserved.\n #\n #  Redistribution and use in source and binary forms, with or without\n #  modification, are permitted provided that the following conditions\n #  are met: Redistributions of source code must retain the above\n #  copyright notice, this list of conditions and the following\n #  disclaimer.  Redistributions in binary form must reproduce the\n #  above copyright notice, this list of conditions and the following\n #  disclaimer in the documentation and/or other materials provided\n #  with the distribution.\n #\n #    Neither the name Myanmar Karen Word Lists, nor the names of its\n #    contributors may be used to endorse or promote products derived\n #    from this software without specific prior written permission.\n #\n #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n #  CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n #  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n #  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n #  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS\n #  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n #  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n #  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n #  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\n #  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\n #  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n #  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n #  SUCH DAMAGE.\n #  --------------------------------------------------------------------------\n\n----------------------------------------------------------------------\n\nTime Zone Database\n\n  ICU uses the public domain data and code derived from Time Zone\nDatabase for its time zone support. The ownership of the TZ database\nis explained in BCP 175: Procedure for Maintaining the Time Zone\nDatabase section 7.\n\n # 7.  Database Ownership\n #\n #    The TZ database itself is not an IETF Contribution or an IETF\n #    document.  Rather it is a pre-existing and regularly updated work\n #    that is in the public domain, and is intended to remain in the\n #    public domain.  Therefore, BCPs 78 [RFC5378] and 79 [RFC3979] do\n #    not apply to the TZ Database or contributions that individuals make\n #    to it.  Should any claims be made and substantiated against the TZ\n #    Database, the organization that is providing the IANA\n #    Considerations defined in this RFC, under the memorandum of\n #    understanding with the IETF, currently ICANN, may act in accordance\n #    with all competent court orders.  No ownership claims will be made\n #    by ICANN or the IETF Trust on the database or the code.  Any person\n #    making a contribution to the database or code waives all rights to\n #    future claims in that contribution or in the TZ Database.\n\n----------------------------------------------------------------------\n\nGoogle double-conversion\n\nCopyright 2006-2011, the V8 project authors. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above\n      copyright notice, this list of conditions and the following\n      disclaimer in the documentation and/or other materials provided\n      with the distribution.\n    * Neither the name of Google Inc. nor the names of its\n      contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n----------------------------------------------------------------------\n\nFile: aclocal.m4 (only for ICU4C)\nSection: pkg.m4 - Macros to locate and utilise pkg-config.\n\n\nCopyright  2004 Scott James Remnant <scott@netsplit.com>.\nCopyright  2012-2015 Dan Nicholson <dbn.lists@gmail.com>\n\nThis program is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 2 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful, but\nWITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\nGeneral Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program; if not, write to the Free Software\nFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n02111-1307, USA.\n\nAs a special exception to the GNU General Public License, if you\ndistribute this file as part of a program that contains a\nconfiguration script generated by Autoconf, you may include it under\nthe same distribution terms that you use for the rest of that\nprogram.\n\n\n(The condition for the exception is fulfilled because\nICU4C includes a configuration script generated by Autoconf,\nnamely the `configure` script.)\n\n----------------------------------------------------------------------\n\nFile: config.guess (only for ICU4C)\n\n\nThis file is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful, but\nWITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\nGeneral Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program; if not, see <https://www.gnu.org/licenses/>.\n\nAs a special exception to the GNU General Public License, if you\ndistribute this file as part of a program that contains a\nconfiguration script generated by Autoconf, you may include it under\nthe same distribution terms that you use for the rest of that\nprogram.  This Exception is an additional permission under section 7\nof the GNU General Public License, version 3 (\"GPLv3\").\n\n\n(The condition for the exception is fulfilled because\nICU4C includes a configuration script generated by Autoconf,\nnamely the `configure` script.)\n\n----------------------------------------------------------------------\n\nFile: install-sh (only for ICU4C)\n\n\nCopyright 1991 by the Massachusetts Institute of Technology\n\nPermission to use, copy, modify, distribute, and sell this software and its\ndocumentation for any purpose is hereby granted without fee, provided that\nthe above copyright notice appear in all copies and that both that\ncopyright notice and this permission notice appear in supporting\ndocumentation, and that the name of M.I.T. not be used in advertising or\npublicity pertaining to distribution of the software without specific,\nwritten prior permission.  M.I.T. makes no representations about the\nsuitability of this software for any purpose.  It is provided \"as is\"\nwithout express or implied warranty."
  },
  {
    "path": "plugins/graaljs/external/js-22.3.0-license.txt",
    "content": "Name: GraalJS\nDescription: A high performance implementation of the JavaScript programming language. Built on the GraalVM by Oracle Labs.\nLicense: UPL\nOrigin: https://github.com/oracle/graal\nVersion: 22.3.0\nFiles: js-22.3.0.jar, js-scriptengine-22.3.0.jar, regex-22.3.0.jar, truffle-api-22.3.0.jar, graal-sdk-22.3.0.jar,\n\nCopyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n\nThe Universal Permissive License (UPL), Version 1.0\n\nSubject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this software, associated documentation and/or data (collectively the \"Software\"), free of charge and under any and all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or (ii) the Larger Works (as defined below), to deal in both\n\n(a) the Software, and\n\n(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software each a \"Larger Work\" to which the Software is contributed by such licensors),\n\nwithout restriction, including without limitation the rights to copy, create derivative works of, display, perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms.\n\nThis license is subject to the following condition:\n\nThe above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n"
  },
  {
    "path": "plugins/graaljs/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: true\nOpenIDE-Module-Java-Dependencies: Java > 15\nOpenIDE-Module: org.graalvm.visualvm.modules.graaljs\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/graaljs/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.3\n\n"
  },
  {
    "path": "plugins/graaljs/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.graaljs-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/graaljs/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=520d0fe2\nbuild.xml.script.CRC32=f245468f\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=78de761a\nnbproject/build-impl.xml.script.CRC32=e26352d3\nnbproject/build-impl.xml.stylesheet.CRC32=68e521fc@2.73\n"
  },
  {
    "path": "plugins/graaljs/nbproject/project.properties",
    "content": "file.reference.js-scriptengine-22.3.0.jar=external/js-scriptengine-22.3.0.jar\nfile.reference.js-22.3.0.jar=external/js-22.3.0.jar\nfile.reference.regex-22.3.0.jar=external/regex-22.3.0.jar\nfile.reference.truffle-api-22.3.0.jar=external/truffle-api-22.3.0.jar\nfile.reference.graal-sdk-22.3.0.jar=external/graal-sdk-22.3.0.jar\nfile.reference.icu4j-71.1.jar=external/icu4j-71.1.jar\nfile.reference.asm-util-9.2.jar=external/asm-util-9.2.jar\nis.eager=true\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Tomas Hurka\nnbm.needs.restart=true\nrelease.external/js-scriptengine-22.3.0.jar=modules/ext/js-scriptengine-22.3.0.jar\nrelease.external/js-22.3.0.jar=modules/ext/js-22.3.0.jar\nrelease.external/regex-22.3.0.jar=modules/ext/regex-22.3.0.jar\nrelease.external/truffle-api-22.3.0.jar=modules/ext/truffle-api-22.3.0.jar\nrelease.external/graal-sdk-22.3.0.jar=modules/ext/graal-sdk-22.3.0.jar\nrelease.external/icu4j-71.1.jar=modules/ext/icu4j-71.1.jar\nrelease.external/asm-util-9.2.jar=modules/ext/asm-util-9.2.jar\n\njavac.source=1.8\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "plugins/graaljs/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.graaljs</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.netbeans.libs.asm</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>5.10</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n            <class-path-extension>\n                <runtime-relative-path>ext/js-scriptengine-22.3.0.jar</runtime-relative-path>\n                <binary-origin>external/js-scriptengine-22.3.0.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/js-22.3.0.jar</runtime-relative-path>\n                <binary-origin>external/js-22.3.0.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/regex-22.3.0.jar</runtime-relative-path>\n                <binary-origin>external/regex-22.3.0.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/truffle-api-22.3.0.jar</runtime-relative-path>\n                <binary-origin>external/truffle-api-22.3.0.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/graal-sdk-22.3.0.jar</runtime-relative-path>\n                <binary-origin>external/graal-sdk-22.3.0.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/icu4j-71.1.jar</runtime-relative-path>\n                <binary-origin>external/icu4j-71.1.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/asm-util-9.2.jar</runtime-relative-path>\n                <binary-origin>external/asm-util-9.2.jar</binary-origin>\n            </class-path-extension>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/graaljs/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/graaljs/src/org/graalvm/visualvm/modules/graaljs/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Libraries\nOpenIDE-Module-Long-Description=\\\n    A high performance implementation of the JavaScript programming language. \\\n    Built on the GraalVM by Oracle Labs.\nOpenIDE-Module-Name=GraalJS\nOpenIDE-Module-Short-Description=GraalVM implementation of JavaScript\n"
  },
  {
    "path": "plugins/jconsole/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.jconsole\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.jconsole.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/jconsole/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.jconsole/2\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/jconsole/Install.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/jconsole/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "plugins/jconsole/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.jconsole-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/jconsole/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=51f7c3b0\nbuild.xml.script.CRC32=b5cff0b2\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=51f7c3b0\nnbproject/build-impl.xml.script.CRC32=604888e2\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "plugins/jconsole/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\njavac.source=1.5\ncp.extra=${tools.jar}:${nbjdk.home}/lib/jconsole.jar\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Luis-Miguel Alventosa\nmodule.javadoc.packages=org.graalvm.visualvm.modules.jconsole.*\n"
  },
  {
    "path": "plugins/jconsole/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.jconsole</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.options.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.11.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.18.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/jconsole/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/jconsole/src/com/sun/tools/jconsole/JConsoleContext.java",
    "content": "/*\n * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage com.sun.tools.jconsole;\n\nimport javax.management.MBeanServerConnection;\nimport java.beans.PropertyChangeListener;\nimport javax.swing.event.SwingPropertyChangeSupport;\n\n/**\n * {@code JConsoleContext} represents a JConsole connection to a target\n * application.\n * <p>\n * {@code JConsoleContext} notifies any {@code PropertyChangeListeners}\n * about the {@linkplain #CONNECTION_STATE_PROPERTY <i>ConnectionState</i>}\n * property change to {@link ConnectionState#CONNECTED CONNECTED} and\n * {@link ConnectionState#DISCONNECTED DISCONNECTED}.\n * The {@code JConsoleContext} instance will be the source for\n * any generated events.\n * <p>\n *\n * @since 1.6\n */\npublic interface JConsoleContext {\n    /**\n     * The {@link ConnectionState ConnectionState} bound property name.\n     */\n    public static String CONNECTION_STATE_PROPERTY = \"connectionState\"; // NOI18N\n\n    /**\n     * Values for the {@linkplain #CONNECTION_STATE_PROPERTY\n     * <i>ConnectionState</i>} bound property.\n     */\n    public enum ConnectionState {\n        /**\n         * The connection has been successfully established.\n         */\n        CONNECTED,\n        /**\n         * No connection present.\n         */\n        DISCONNECTED,\n        /**\n         * The connection is being attempted.\n         */\n        CONNECTING\n    }\n\n    /**\n     * Returns the {@link MBeanServerConnection MBeanServerConnection} for the\n     * connection to an application.  The returned\n     * {@code MBeanServerConnection} object becomes invalid when\n     * the connection state is changed to the\n     * {@link ConnectionState#DISCONNECTED DISCONNECTED} state.\n     *\n     * @return the {@code MBeanServerConnection} for the\n     * connection to an application.\n     */\n    public MBeanServerConnection getMBeanServerConnection();\n\n    /**\n     * Returns the current connection state.\n     * @return the current connection state.\n     */\n    public ConnectionState getConnectionState();\n\n    /**\n     * Add a {@link java.beans.PropertyChangeListener PropertyChangeListener}\n     * to the listener list.\n     * The listener is registered for all properties.\n     * The same listener object may be added more than once, and will be called\n     * as many times as it is added.\n     * If {@code listener} is {@code null}, no exception is thrown and\n     * no action is taken.\n     *\n     * @param listener  The {@code PropertyChangeListener} to be added\n     */\n    public void addPropertyChangeListener(PropertyChangeListener listener);\n\n    /**\n     * Removes a {@link java.beans.PropertyChangeListener PropertyChangeListener}\n     * from the listener list. This\n     * removes a {@code PropertyChangeListener} that was registered for all\n     * properties. If {@code listener} was added more than once to the same\n     * event source, it will be notified one less time after being removed. If\n     * {@code listener} is {@code null}, or was never added, no exception is\n     * thrown and no action is taken.\n     *\n     * @param listener the {@code PropertyChangeListener} to be removed\n     */\n    public void removePropertyChangeListener(PropertyChangeListener listener);\n}\n"
  },
  {
    "path": "plugins/jconsole/src/com/sun/tools/jconsole/JConsolePlugin.java",
    "content": "/*\n * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage com.sun.tools.jconsole;\n\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.JPanel;\nimport javax.swing.SwingWorker;\n\n/**\n * A JConsole plugin class.  JConsole uses the\n * <a href=\"{@docRoot}/../../../../api/java/util/ServiceLoader.html\">\n * service provider</a> mechanism to search the JConsole plugins.\n * Users can provide their JConsole plugins in a jar file\n * containing a file named\n *\n * <blockquote><pre>\n * META-INF/services/com.sun.tools.jconsole.JConsolePlugin</pre></blockquote>\n *\n * <p> This file contains one line for each plugin, for example,\n *\n * <blockquote><pre>\n * com.sun.example.JTop</pre></blockquote>\n * <p> which is the fully qualified class name of the class implementing\n * {@code JConsolePlugin}.\n *\n * <p> To load the JConsole plugins in JConsole, run:\n *\n * <blockquote><pre>\n * jconsole -pluginpath &lt;plugin-path&gt; </pre></blockquote>\n *\n * <p> where <tt>&lt;plugin-path&gt;</tt> specifies the paths of JConsole\n * plugins to look up which can be a directory or a jar file. Multiple\n * paths are separated by the path separator character of the platform.\n *\n * <p> When a new JConsole window is created for a connection,\n * an instance of each {@code JConsolePlugin} will be created.\n * The {@code JConsoleContext} object is not available at its\n * construction time.\n * JConsole will set the {@link JConsoleContext} object for\n * a plugin after the plugin object is created.  It will then\n * call its {@link #getTabs getTabs} method and add the returned\n * tabs to the JConsole window.\n *\n * @see <a href=\"{@docRoot}/../../../../api/java/util/ServiceLoader.html\">\n * java.util.ServiceLoader</a>\n *\n * @since 1.6\n */\npublic abstract class JConsolePlugin {\n    private volatile JConsoleContext context = null;\n    private List<PropertyChangeListener> listeners = null;\n\n    /**\n     * Constructor.\n     */\n    protected JConsolePlugin() {\n    }\n\n    /**\n     * Sets the {@link JConsoleContext JConsoleContext} object representing\n     * the connection to an application.  This method will be called\n     * only once after the plugin is created and before the {@link #getTabs}\n     * is called. The given {@code context} can be in any\n     * {@link JConsoleContext#getConnectionState connection state} when\n     * this method is called.\n     *\n     * @param context a {@code JConsoleContext} object\n     */\n    public final synchronized void setContext(JConsoleContext context) {\n        this.context = context;\n        if (listeners != null) {\n            for (PropertyChangeListener l : listeners) {\n                context.addPropertyChangeListener(l);\n            }\n            // throw away the listener list\n            listeners = null;\n        }\n    }\n\n    /**\n     * Returns the {@link JConsoleContext JConsoleContext} object representing\n     * the connection to an application.  This method may return <tt>null</tt>\n     * if it is called before the {@link #setContext context} is initialized.\n     *\n     * @return the {@link JConsoleContext JConsoleContext} object representing\n     *         the connection to an application.\n     */\n    public final JConsoleContext getContext() {\n        return context;\n    }\n\n    /**\n     * Returns the tabs to be added in JConsole window.\n     * <p>\n     * The returned map contains one entry for each tab\n     * to be added in the tabbed pane in a JConsole window with\n     * the tab name as the key\n     * and the {@link JPanel} object as the value.\n     * This method returns an empty map if no tab is added by this plugin.\n     * This method will be called from the <i>Event Dispatch Thread</i>\n     * once at the new connection time.\n     *\n     * @return a map of a tab name and a {@link JPanel} object\n     *         representing the tabs to be added in the JConsole window;\n     *         or an empty map.\n     */\n    public abstract java.util.Map<String, JPanel> getTabs();\n\n    /**\n     * Returns a {@link SwingWorker} to perform\n     * the GUI update for this plugin at the same interval\n     * as JConsole updates the GUI.\n     * <p>\n     * JConsole schedules the GUI update at an interval specified\n     * for a connection.  This method will be called at every\n     * update to obtain a {@code SwingWorker} for each plugin.\n     * <p>\n     * JConsole will invoke the {@link SwingWorker#execute execute()}\n     * method to schedule the returned {@code SwingWorker} for execution\n     * if:\n     * <ul>\n     *   <li> the <tt>SwingWorker</tt> object has not been executed\n     *        (i.e. the {@link SwingWorker#getState} method\n     *        returns {@link javax.swing.SwingWorker.StateValue#PENDING PENDING}\n     *        state); and</li>\n     *   <li> the <tt>SwingWorker</tt> object returned in the previous\n     *        update has completed the task if it was not <tt>null</tt>\n     *        (i.e. the {@link SwingWorker#isDone SwingWorker.isDone} method\n     *        returns <tt>true</tt>).</li>\n     * </ul>\n     * <br>\n     * Otherwise, <tt>SwingWorker</tt> object will not be scheduled to work.\n     *\n     * <p>\n     * A plugin can schedule its own GUI update and this method\n     * will return <tt>null</tt>.\n     *\n     * @return a <tt>SwingWorker</tt> to perform the GUI update; or\n     *         <tt>null</tt>.\n     */\n    public abstract SwingWorker<?,?> newSwingWorker();\n\n    /**\n     * Dispose this plugin. This method is called by JConsole to inform\n     * that this plugin will be discarded and that it should free\n     * any resources that it has allocated.\n     * The {@link #getContext JConsoleContext} can be in any\n     * {@link JConsoleContext#getConnectionState connection state} when\n     * this method is called.\n     */\n    public void dispose() {\n        // Default nop implementation\n    }\n\n    /**\n     * Adds a {@link PropertyChangeListener PropertyChangeListener}\n     * to the {@link #getContext JConsoleContext} object for this plugin.\n     * This method is a convenient method for this plugin to register\n     * a listener when the {@code JConsoleContext} object may or\n     * may not be available.\n     *\n     * <p>For example, a plugin constructor can\n     * call this method to register a listener to listen to the\n     * {@link JConsoleContext.ConnectionState connectionState}\n     * property changes and the listener will be added to the\n     * {@link JConsoleContext#addPropertyChangeListener JConsoleContext}\n     * object when it is available.\n     *\n     * @param listener  The {@code PropertyChangeListener} to be added\n     *\n     * @throws NullPointerException if {@code listener} is {@code null}.\n     */\n    public final void addContextPropertyChangeListener(PropertyChangeListener listener) {\n        if (listener == null) {\n            throw new NullPointerException(\"listener is null\"); // NOI18N\n        }\n\n        if (context == null) {\n            // defer registration of the listener until setContext() is called\n            synchronized (this) {\n                // check again if context is not set\n                if (context == null) {\n                    // maintain a listener list to be added later\n                    if (listeners == null) {\n                        listeners = new ArrayList<PropertyChangeListener>();\n                    }\n                    listeners.add(listener);\n                    return;\n                }\n            }\n        }\n        context.addPropertyChangeListener(listener);\n    }\n\n    /**\n     * Removes a {@link PropertyChangeListener PropertyChangeListener}\n     * from the listener list of the {@link #getContext JConsoleContext}\n     * object for this plugin.\n     * If {@code listener} was never added, no exception is\n     * thrown and no action is taken.\n     *\n     * @param listener the {@code PropertyChangeListener} to be removed\n     *\n     * @throws NullPointerException if {@code listener} is {@code null}.\n     */\n    public final void removeContextPropertyChangeListener(PropertyChangeListener listener) {\n        if (listener == null) {\n            throw new NullPointerException(\"listener is null\"); // NOI18N\n        }\n\n        if (context == null) {\n            // defer registration of the listener until setContext() is called\n            synchronized (this) {\n                // check again if context is not set\n                if (context == null) {\n                    if (listeners != null) {\n                        listeners.remove(listener);\n                    }\n                    return;\n                }\n            }\n        }\n        context.removePropertyChangeListener(listener);\n    }\n}\n"
  },
  {
    "path": "plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Tools\nOpenIDE-Module-Long-Description=\\\n    A plugin to enable using custom JConsole plugins in VisualVM. Use \"Tools | Options | JConsole Plugins\" to manage the JConsole plugins.\nOpenIDE-Module-Name=VisualVM-JConsole\nOpenIDE-Module-Short-Description=JConsole Plugins Container\n\nJMX_Not_Available=Data not available because JMX connection to the JMX agent could not be established.\nNoPluginInstalled=No JConsole plugin installed.\nInstallPluginHint=To install a JConsole plugin, click the Configure Plugins button and provide full path to the plugin file/directory.\nConfigurePlugins=Configure Plugins\nJConsole_Plugins=JConsole Plugins\n"
  },
  {
    "path": "plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/Install.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jconsole;\n\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n *\n * @author Luis-Miguel Alventosa\n */\npublic class Install extends ModuleInstall {\n    @Override\n    public void restored() {\n        JConsoleViewsSupport.sharedInstance();\n    }\n}\n"
  },
  {
    "path": "plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/JConsolePluginWrapper.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jconsole;\n\nimport com.sun.tools.jconsole.JConsoleContext;\nimport static com.sun.tools.jconsole.JConsoleContext.*;\nimport com.sun.tools.jconsole.JConsoleContext.ConnectionState;\nimport com.sun.tools.jconsole.JConsolePlugin;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.modules.jconsole.options.JConsoleSettings;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport java.awt.BorderLayout;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.ServiceConfigurationError;\nimport java.util.ServiceLoader;\nimport java.util.Set;\nimport java.util.logging.Logger;\nimport javax.management.MBeanServerConnection;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTabbedPane;\nimport javax.swing.JTextArea;\nimport javax.swing.SwingWorker;\nimport javax.swing.Timer;\nimport javax.swing.event.SwingPropertyChangeSupport;\nimport org.netbeans.api.options.OptionsDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\nclass JConsolePluginWrapper {\n\n    private static final Logger LOGGER = Logger.getLogger(JConsolePluginWrapper.class.getName());\n    private ServiceLoader<JConsolePlugin> pluginService;\n    private JComponent jconsoleView;\n    private VMPanel vmPanel;\n\n    JConsolePluginWrapper(Application application) {\n        JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);\n        if (jmxModel == null || jmxModel.getConnectionState() != JmxModel.ConnectionState.CONNECTED) {\n            JTextArea textArea = new JTextArea();\n            textArea.setBorder(BorderFactory.createEmptyBorder(25, 9, 9, 9));\n            textArea.setEditable(false);\n            textArea.setLineWrap(true);\n            textArea.setWrapStyleWord(true);\n            textArea.setText(NbBundle.getMessage(JConsolePluginWrapper.class, \"JMX_Not_Available\")); // NOI18N\n            jconsoleView = textArea;\n        } else {\n            boolean availablePlugins = getPlugins().iterator().hasNext();\n            if (availablePlugins) {\n                vmPanel = new VMPanel(application, this, new ProxyClient(jmxModel));\n                vmPanel.connect();\n                JPanel panel = new JPanel(new BorderLayout());\n                panel.setOpaque(false);\n                panel.add(new JLabel(\" \"), BorderLayout.NORTH); // NOI18N\n                panel.add(vmPanel, BorderLayout.CENTER);\n                jconsoleView = panel;\n            } else {\n                GridBagConstraints c;\n\n                JPanel hintPanel = new JPanel(new GridBagLayout());\n                hintPanel.setOpaque(false);\n                hintPanel.setBorder(BorderFactory.createEmptyBorder(25, 9, 9, 9));\n\n                JLabel hintLabel = new JLabel(NbBundle.getMessage(\n                        JConsolePluginWrapper.class, \"NoPluginInstalled\")); // NOI18N\n                hintLabel.setFont(hintLabel.getFont().deriveFont(Font.BOLD));\n                c = new GridBagConstraints();\n                c.gridy = 0;\n                c.anchor = GridBagConstraints.WEST;\n                c.fill = GridBagConstraints.NONE;\n                c.insets = new Insets(0, 0, 0, 0);\n                hintPanel.add(hintLabel, c);\n\n                JTextArea hintArea = new JTextArea();\n                hintArea.setEnabled(false);\n                hintArea.setEditable(false);\n                hintArea.setLineWrap(true);\n                hintArea.setWrapStyleWord(true);\n                hintArea.setDisabledTextColor(hintArea.getForeground());\n                hintArea.setOpaque(false);\n                hintArea.setText(NbBundle.getMessage(\n                        JConsolePluginWrapper.class, \"InstallPluginHint\")); // NOI18N\n                c = new GridBagConstraints();\n                c.gridy = 1;\n                c.weightx = 1;\n                c.anchor = GridBagConstraints.WEST;\n                c.fill = GridBagConstraints.HORIZONTAL;\n                c.insets = new Insets(5, 0, 0, 0);\n                hintPanel.add(hintArea, c);\n\n                JButton optionsButton = new JButton() {\n                    protected void fireActionPerformed(ActionEvent event) {\n                        OptionsDisplayer.getDefault().open(\"JConsoleOptions\"); // NOI18N\n                    }\n                };\n                Mnemonics.setLocalizedText(optionsButton, NbBundle.getMessage(\n                        JConsolePluginWrapper.class, \"ConfigurePlugins\")); // NOI18N\n                c = new GridBagConstraints();\n                c.gridy = 2;\n                c.anchor = GridBagConstraints.EAST;\n                c.fill = GridBagConstraints.NONE;\n                c.insets = new Insets(10, 0, 0, 0);\n                hintPanel.add(optionsButton, c);\n\n                c = new GridBagConstraints();\n                c.gridy = 3;\n                c.weighty = 1;\n                c.anchor = GridBagConstraints.NORTHWEST;\n                c.fill = GridBagConstraints.BOTH;\n                c.gridwidth = GridBagConstraints.REMAINDER;\n                hintPanel.add(Spacer.create(), c);\n\n                jconsoleView = hintPanel;\n            }\n        }\n    }\n\n    JComponent getView() {\n        return jconsoleView;\n    }\n    void releasePlugins() {\n        if (vmPanel != null) {\n            vmPanel.disconnect();\n        }\n    }\n\n    // Return a list of newly instantiated JConsolePlugin objects\n    synchronized List<JConsolePlugin> getPlugins() {\n        if (pluginService == null) {\n            String pluginPath = JConsoleSettings.getDefault().getPluginsPath();\n            // First time loading and initializing the plugins\n            initPluginService(pluginPath == null ? \"\" : pluginPath); // NOI18N\n        } else {\n            // Reload the plugin so that new instances will be created\n            pluginService.reload();\n        }\n        List<JConsolePlugin> plugins = new ArrayList<JConsolePlugin>();\n        for (JConsolePlugin p : pluginService) {\n            plugins.add(p);\n        }\n        return plugins;\n    }\n\n    private void initPluginService(String pluginPath) {\n        if (pluginPath.length() > 0) {\n            try {\n                ClassLoader pluginCL = new URLClassLoader(\n                        pathToURLs(pluginPath),\n                        JConsolePluginWrapper.class.getClassLoader());\n                ServiceLoader<JConsolePlugin> plugins =\n                        ServiceLoader.load(JConsolePlugin.class, pluginCL);\n                // Validate all plugins\n                for (JConsolePlugin p : plugins) {\n                    LOGGER.finer(\"JConsole plugin \" + p.getClass().getName() + \" loaded.\"); // NOI18N\n                }\n                pluginService = plugins;\n            } catch (ServiceConfigurationError e) {\n                // Error occurs during initialization of plugin\n                LOGGER.warning(\"Fail to load JConsole plugin: \" + e.getMessage()); // NOI18N\n                LOGGER.throwing(JConsolePluginWrapper.class.getName(), \"initPluginService\", e); // NOI18N\n            } catch (MalformedURLException e) {\n                LOGGER.warning(\"Invalid JConsole plugin path: \" + e.getMessage()); // NOI18N\n                LOGGER.throwing(JConsolePluginWrapper.class.getName(), \"initPluginService\", e); // NOI18N\n            }\n        }\n        if (pluginService == null) {\n            initEmptyPlugin();\n        }\n    }\n\n    private void initEmptyPlugin() {\n        ClassLoader pluginCL = new URLClassLoader(new URL[0], JConsolePluginWrapper.class.getClassLoader());\n        pluginService = ServiceLoader.load(JConsolePlugin.class, pluginCL);\n    }\n\n    /**\n     * Utility method for converting a search path string to an array\n     * of directory and JAR file URLs.\n     *\n     * @param path the search path string\n     * @return the resulting array of directory and JAR file URLs\n     */\n    private static URL[] pathToURLs(String path) throws MalformedURLException {\n        String[] names = path.split(File.pathSeparator);\n        URL[] urls = new URL[names.length + 1];\n        urls[0] = JConsolePluginWrapper.class.getProtectionDomain().getCodeSource().getLocation();\n        int count = 1;\n        for (String f : names) {\n            URL url = fileToURL(new File(f));\n            urls[count++] = url;\n        }\n        return urls;\n    }\n\n    /**\n     * Returns the directory or JAR file URL corresponding to the specified\n     * local file name.\n     *\n     * @param file the File object\n     * @return the resulting directory or JAR file URL, or null if unknown\n     */\n    private static URL fileToURL(File file) throws MalformedURLException {\n        String name;\n        try {\n            name = file.getCanonicalPath();\n        } catch (IOException e) {\n            name = file.getAbsolutePath();\n        }\n        name = name.replace(File.separatorChar, '/');\n        if (!name.startsWith(\"/\")) { // NOI18N\n            name = \"/\" + name; // NOI18N\n        }\n        // If the file does not exist, then assume that it's a directory\n        if (!file.isFile()) {\n            name = name + \"/\"; // NOI18N\n        }\n        return new URL(\"file\", \"\", name); // NOI18N\n    }\n\n    class ProxyClient implements JConsoleContext, PropertyChangeListener {\n\n        private ConnectionState connectionState = ConnectionState.DISCONNECTED;\n\n        // The SwingPropertyChangeSupport will fire events on the EDT\n        private SwingPropertyChangeSupport propertyChangeSupport =\n                new SwingPropertyChangeSupport(this, true);\n        private volatile boolean isDead = true;\n        private JmxModel jmxModel = null;\n        private MBeanServerConnection server = null;\n\n        ProxyClient(JmxModel jmxModel) {\n            this.jmxModel = jmxModel;\n        }\n\n        private void setConnectionState(ConnectionState state) {\n            ConnectionState oldState = this.connectionState;\n            this.connectionState = state;\n            propertyChangeSupport.firePropertyChange(CONNECTION_STATE_PROPERTY,\n                    oldState, state);\n        }\n\n        public ConnectionState getConnectionState() {\n            return this.connectionState;\n        }\n\n        void connect() {\n            setConnectionState(ConnectionState.CONNECTING);\n            try {\n                tryConnect();\n                setConnectionState(ConnectionState.CONNECTED);\n            } catch (Exception e) {\n                e.printStackTrace();\n                setConnectionState(ConnectionState.DISCONNECTED);\n            }\n        }\n\n        private void tryConnect() throws IOException {\n            jmxModel.addPropertyChangeListener(this);\n            this.server = jmxModel.getMBeanServerConnection();\n            this.isDead = false;\n        }\n\n        public MBeanServerConnection getMBeanServerConnection() {\n            return server;\n        }\n\n        synchronized void disconnect() {\n            jmxModel.removePropertyChangeListener(this);\n            // Set connection state to DISCONNECTED\n            if (!isDead) {\n                isDead = true;\n                setConnectionState(ConnectionState.DISCONNECTED);\n            }\n        }\n\n        boolean isDead() {\n            return isDead;\n        }\n\n        boolean isConnected() {\n            return !isDead();\n        }\n\n        public void addPropertyChangeListener(PropertyChangeListener listener) {\n            propertyChangeSupport.addPropertyChangeListener(listener);\n        }\n\n        public void removePropertyChangeListener(PropertyChangeListener listener) {\n            propertyChangeSupport.removePropertyChangeListener(listener);\n        }\n\n        public void propertyChange(PropertyChangeEvent evt) {\n            String prop = evt.getPropertyName();\n            if (CONNECTION_STATE_PROPERTY.equals(prop)) {\n                org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState newState = (org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState) evt.getNewValue();\n                setConnectionState(ConnectionState.valueOf(newState.name()));\n            }\n        }\n    }\n\n    class VMPanel extends JTabbedPane implements PropertyChangeListener {\n\n        private Application application;\n        private ProxyClient proxyClient;\n        private Timer timer;\n        private int updateInterval = JConsoleSettings.getDefault().getPolling() * 1000;\n        private boolean wasConnected = false;\n\n        // Each VMPanel has its own instance of the JConsolePlugin.\n        // A map of JConsolePlugin to the previous SwingWorker.\n        private Map<JConsolePlugin, SwingWorker<?, ?>> plugins = null;\n        private boolean pluginTabsAdded = false;\n\n        VMPanel(Application application, JConsolePluginWrapper wrapper, ProxyClient proxyClient) {\n            this.application = application;\n            this.proxyClient = proxyClient;\n            plugins = new LinkedHashMap<JConsolePlugin, SwingWorker<?, ?>>();\n            for (JConsolePlugin p : wrapper.getPlugins()) {\n                p.setContext(proxyClient);\n                plugins.put(p, null);\n            }\n            // Start listening to connection state events\n            //\n            proxyClient.addPropertyChangeListener(this);\n        }\n\n        boolean isConnected() {\n            return proxyClient.isConnected();\n        }\n\n        // Call on EDT\n        void connect() {\n            if (isConnected()) {\n                // Create plugin tabs if not done\n                createPluginTabs();\n                // Start/Restart update timer on connect/reconnect\n                startUpdateTimer();\n            } else {\n                proxyClient.connect();\n            }\n        }\n\n        // Call on EDT\n        void disconnect() {\n            // Disconnect\n            proxyClient.disconnect();\n            // Dispose JConsole plugins\n            disposePlugins(plugins.keySet());\n            // Cancel pending update tasks\n            //\n            if (timer != null) {\n                timer.stop();\n            }\n            // Stop listening to connection state events\n            //\n            proxyClient.removePropertyChangeListener(this);\n        }\n\n        // Called on EDT\n        public void propertyChange(PropertyChangeEvent ev) {\n            String prop = ev.getPropertyName();\n            if (CONNECTION_STATE_PROPERTY.equals(prop)) {\n                ConnectionState newState = (ConnectionState) ev.getNewValue();\n                switch (newState) {\n                    case CONNECTED:\n                        // Create tabs if not done\n                        createPluginTabs();\n                        repaint();\n                        // Start/Restart update timer on connect/reconnect\n                        startUpdateTimer();\n                        break;\n                    case DISCONNECTED:\n                        disconnect();\n                        break;\n                }\n            }\n        }\n\n        private void startUpdateTimer() {\n            if (timer != null) {\n                timer.stop();\n            }\n            timer = new Timer(updateInterval, new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    RequestProcessor.getDefault().post(new Runnable() {\n                        public void run() {\n                            update();\n                        }\n                    });\n                }\n            });\n            timer.setCoalesce(true);\n            timer.setInitialDelay(0);\n            timer.start();\n        }\n\n        // Note: This method is called on a TimerTask thread. Any GUI manipulation\n        // must be performed with invokeLater() or invokeAndWait().\n        private Object lockObject = new Object();\n\n        private void update() {\n            synchronized (lockObject) {\n                if (!isConnected()) {\n                    if (wasConnected) {\n                        disconnect();\n                    }\n                    wasConnected = false;\n                    return;\n                } else {\n                    wasConnected = true;\n                }\n                // Plugin GUI update\n                for (JConsolePlugin p : plugins.keySet()) {\n                    SwingWorker<?, ?> sw = p.newSwingWorker();\n                    SwingWorker<?, ?> prevSW = plugins.get(p);\n                    // Schedule SwingWorker to run only if the previous\n                    // SwingWorker has finished its task and it hasn't started.\n                    if (prevSW == null || prevSW.isDone()) {\n                        if (sw == null || sw.getState() == SwingWorker.StateValue.PENDING) {\n                            plugins.put(p, sw);\n                            if (sw != null) {\n                                RequestProcessor.getDefault().post(sw);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        private void createPluginTabs() {\n            // Add plugin tabs if not done\n            if (!pluginTabsAdded) {\n                Set<JConsolePlugin> failedPlugins = new HashSet<JConsolePlugin>();\n                for (JConsolePlugin p : plugins.keySet()) {\n                    try {\n                        Map<String, JPanel> tabs = p.getTabs();\n                        for (Map.Entry<String, JPanel> e : tabs.entrySet()) {\n                            addTab(e.getKey(), e.getValue());\n                        }\n                    } catch (Throwable t) {\n                        // Error occurs during plugin tab creation.\n                        failedPlugins.add(p);\n                        LOGGER.warning(\"JConsole plugin \" + p.getClass().getName() + \" removed: Failed to create JConsole plugin tabs.\"); // NOI18N\n                        LOGGER.throwing(VMPanel.class.getName(), \"createPluginTabs\", t); // NOI18N\n                    }\n                }\n                // Remove plugins that failed to return the plugin tabs\n                for (JConsolePlugin p : failedPlugins) {\n                    plugins.remove(p);\n                }\n                disposePlugins(failedPlugins);\n                pluginTabsAdded = true;\n            }\n        }\n\n        private void disposePlugins(Set<JConsolePlugin> pluginSet) {\n            for (JConsolePlugin p : pluginSet) {\n                try {\n                    p.dispose();\n                } catch (Throwable t) {\n                    // Best effort, ignore if plugin fails to cleanup itself.\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/JConsoleView.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jconsole;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport javax.swing.ImageIcon;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * @author Leif Samuelsson\n * @author Luis-Miguel Alventosa\n */\nclass JConsoleView extends DataSourceView {\n\n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/modules/jconsole/ui/resources/jconsole.png\"; // NOI18N\n    \n    private Application application;\n    private JConsolePluginWrapper wrapper;\n\n    public JConsoleView(Application application) {\n        super(application, NbBundle.getMessage(JConsoleView.class, \"JConsole_Plugins\"), new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 60, false); // NOI18N\n        this.application = application;\n    }\n\n    @Override\n    protected void removed() {\n        wrapper.releasePlugins();\n    }\n\n    protected DataViewComponent createComponent() {\n        wrapper = new JConsolePluginWrapper(application);\n        return new DataViewComponent(\n                new DataViewComponent.MasterView(NbBundle.getMessage(JConsoleView.class, \"JConsole_Plugins\"), null, wrapper.getView()), //NOI18N\n                new DataViewComponent.MasterViewConfiguration(true));\n    }\n}\n"
  },
  {
    "path": "plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/JConsoleViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jconsole;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Luis-Miguel Alventosa\n */\npublic class JConsoleViewProvider extends DataSourceViewProvider<Application> {\n\n    protected boolean supportsViewFor(Application application) {\n        return true;\n    }\n\n    protected DataSourceView createView(Application application) {\n        return new JConsoleView(application);\n    }\n\n    public void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(this, Application.class);\n    }\n}\n"
  },
  {
    "path": "plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/JConsoleViewsSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jconsole;\n\n/**\n *\n * @author Luis-Miguel Alventosa\n */\npublic final class JConsoleViewsSupport {\n\n    private static JConsoleViewsSupport sharedInstance;\n\n    public static synchronized JConsoleViewsSupport sharedInstance() {\n        if (sharedInstance == null) {\n            sharedInstance = new JConsoleViewsSupport();\n        }\n        return sharedInstance;\n    }\n\n    private JConsoleViewsSupport() {\n        new JConsoleViewProvider().initialize();\n    }\n}\n"
  },
  {
    "path": "plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/options/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOptionsCategory_Name_JConsole=JConsole Plugins\n\nCAP_PluginsContainer=JConsole Plugins Container\nLAB_PollingPeriod=&Polling period\\:\nLAB_PollingUnits=sec.\nLAB_PluginsPath=P&lugins path\\:\nBTN_Add=&Add JAR/Folder\nBTN_Remove=&Remove\nBTN_MoveUp=Move &Up\nBTN_MoveDown=Move &Down\nFIL_PluginFileFilterDescr=JConsole plugin (*.jar or directory)\nMSG_ReopenTab=The application needs to be (re)opened for the changes to take effect.\n"
  },
  {
    "path": "plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/options/JConsoleCustomizer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jconsole.options;\n\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.io.File;\nimport javax.swing.JButton;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.filechooser.FileFilter;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JSpinner;\nimport javax.swing.SpinnerNumberModel;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.ListDataEvent;\nimport javax.swing.event.ListDataListener;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JConsoleCustomizer extends JPanel {\n\n    private boolean initialized;\n    private PathController pluginsController;\n    private JFileChooser pluginsChooser;\n    private JConsoleOptionsPanelController controler;\n\n    \n    JConsoleCustomizer(JConsoleOptionsPanelController contr) {\n        this.controler = contr;\n        initComponents();\n\n        pluginsChooser = new JFileChooser();\n        pluginsChooser.setMultiSelectionEnabled(true);\n        pluginsChooser.setFileFilter(new CustomizerFileFilter());\n        pluginsChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);\n\n        ListDataListener listListener = new ListDataListener() {\n            public void intervalAdded(ListDataEvent arg0) {}\n            public void intervalRemoved(ListDataEvent arg0) {}\n            public void contentsChanged(ListDataEvent arg0) { changed(); }\n        };\n        pluginsController = new PathController(jList1, pathLabel, jButtonAddJar,\n                                               pluginsChooser, jButtonRemove,\n                                               jButtonMoveUp, jButtonMoveDown,\n                                               listListener);\n\n        pluginsController.setVisible(true);\n\n    }\n\n    synchronized void changed() {\n        controler.changed();\n    }\n\n    synchronized void load() {\n        String plugins = JConsoleSettings.getDefault().getPluginsPath();\n        Integer polling = JConsoleSettings.getDefault().getPolling();\n        pluginsController.updateModel(plugins);\n        pollingPeriodSpinner.setValue(polling);\n        initialized = true;\n    }\n\n    synchronized void store() {\n        if (!initialized) {\n            return;\n        }\n        JConsoleSettings.getDefault().setPluginsPath(pluginsController.toString());\n        JConsoleSettings.getDefault().setPolling((Integer)pollingPeriodSpinner.getValue());\n    }\n\n    void cancel() {\n\n    }\n\n    boolean valid() {\n        return true;\n    }\n\n\n    private void initComponents() {\n        GridBagConstraints c;\n\n        setLayout(new GridBagLayout());\n\n        SectionSeparator pollingSection = UISupport.createSectionSeparator(NbBundle.getMessage(\n                                   JConsoleCustomizer.class, \"CAP_PluginsContainer\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 0;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 5, 0);\n        add(pollingSection, c);\n\n        JLabel pollingPeriodLabel = new JLabel();\n        Mnemonics.setLocalizedText(pollingPeriodLabel, NbBundle.getMessage(\n                                   JConsoleCustomizer.class, \"LAB_PollingPeriod\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 0);\n        add(pollingPeriodLabel, c);\n\n        pollingPeriodSpinner = new JSpinner();\n        pollingPeriodLabel.setLabelFor(pollingPeriodSpinner);\n        pollingPeriodSpinner.setModel(new SpinnerNumberModel(4, 1, 99999, 1));\n        pollingPeriodSpinner.addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) { changed(); }\n\n        });\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 10, 3, 4);\n        add(pollingPeriodSpinner, c);\n\n        JLabel pollingUnitsLabel = new JLabel();\n        Mnemonics.setLocalizedText(pollingUnitsLabel, NbBundle.getMessage(\n                                   JConsoleCustomizer.class, \"LAB_PollingUnits\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 3, 0);\n        add(pollingUnitsLabel, c);\n\n        pathLabel = new JLabel();\n        Mnemonics.setLocalizedText(pathLabel, NbBundle.getMessage(\n                                   JConsoleCustomizer.class, \"LAB_PluginsPath\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 2;\n        c.anchor = GridBagConstraints.WEST;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.insets = new Insets(8, 15, 3, 0);\n        add(pathLabel, c);\n\n        jList1 = new JList();\n        pathLabel.setLabelFor(jList1);\n        JScrollPane listScroll = new JScrollPane(jList1) {\n            public Dimension getPreferredSize() {\n                return new Dimension(super.getPreferredSize().width, 1);\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 3;\n        c.gridwidth = 3;\n        c.gridheight = 4;\n        c.weightx = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(0, 15, 3, 5);\n        add(listScroll, c);\n\n        jButtonAddJar = new JButton();\n        Mnemonics.setLocalizedText(jButtonAddJar, NbBundle.getMessage(\n                                   JConsoleCustomizer.class, \"BTN_Add\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 4;\n        c.gridy = 3;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 5, 3, 0);\n        add(jButtonAddJar, c);\n\n        jButtonRemove = new JButton();\n        Mnemonics.setLocalizedText(jButtonRemove, NbBundle.getMessage(\n                                   JConsoleCustomizer.class, \"BTN_Remove\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 4;\n        c.gridy = 4;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(jButtonRemove, c);\n\n        jButtonMoveUp = new JButton();\n        Mnemonics.setLocalizedText(jButtonMoveUp, NbBundle.getMessage(\n                                   JConsoleCustomizer.class, \"BTN_MoveUp\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 4;\n        c.gridy = 5;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(jButtonMoveUp, c);\n\n        jButtonMoveDown = new JButton();\n        Mnemonics.setLocalizedText(jButtonMoveDown, NbBundle.getMessage(\n                                   JConsoleCustomizer.class, \"BTN_MoveDown\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 4;\n        c.gridy = 6;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(jButtonMoveDown, c);\n\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 7;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        add(Spacer.create(), c);\n\n        // hintLabel\n        JLabel hintLabel = new JLabel();\n        Mnemonics.setLocalizedText(hintLabel, NbBundle.getMessage(\n                JConsoleCustomizer.class, \"MSG_ReopenTab\")); // NOI18N\n        hintLabel.setIcon(ImageUtilities.loadImageIcon(\n                \"org/graalvm/visualvm/modules/jconsole/ui/resources/infoIcon.png\", false)); // NOI18N)\n        hintLabel.setIconTextGap(10);\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 8;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 0, 0);\n        add(hintLabel, c);\n    }\n\n\n    private JButton jButtonAddJar;\n    private JButton jButtonMoveDown;\n    private JButton jButtonMoveUp;\n    private JButton jButtonRemove;\n    private JList jList1;\n    private JLabel pathLabel;\n    private JSpinner pollingPeriodSpinner;\n\n\n    private static class CustomizerFileFilter extends FileFilter {\n\n        public boolean accept(File f) {\n            if (f != null) {\n                if (f.isDirectory()) return true;\n                return f.isFile() && f.getName().toLowerCase().endsWith(\".jar\"); // NOI18N\n            }\n            return false;\n        }\n\n        public String getDescription() {\n            return NbBundle.getMessage(JConsoleCustomizer.class,\n                                       \"FIL_PluginFileFilterDescr\"); // NOI18N\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/options/JConsoleOptionsPanelController.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jconsole.options;\n\nimport org.graalvm.visualvm.core.options.UISupport;\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport javax.swing.JComponent;\nimport org.netbeans.spi.options.OptionsPanelController;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\n\n/**\n * @author Tomas Hurka\n */\n@OptionsPanelController.TopLevelRegistration(\n        id = \"JConsoleOptions\",\n        categoryName = \"#OptionsCategory_Name_JConsole\",\n        iconBase = \"org/graalvm/visualvm/modules/jconsole/ui/resources/jconsole32.png\",\n        position = 6000\n)\npublic final class JConsoleOptionsPanelController extends OptionsPanelController {\n\n    private JConsoleCustomizer panel;\n    private JComponent component;\n    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);\n    private boolean changed;\n\n    public void update() {\n        getPanel().load();\n        changed = false;\n    }\n\n    public void applyChanges() {\n        getPanel().store();\n        changed = false;\n    }\n\n    public void cancel() {\n        // need not do anything special, if no changes have been persisted yet\n    }\n\n    public boolean isValid() {\n        return getPanel().valid();\n    }\n\n    public boolean isChanged() {\n        return changed;\n    }\n\n    public HelpCtx getHelpCtx() {\n        return null; // new HelpCtx(\"...ID\") if you have a help set\n    }\n\n    public JComponent getComponent(Lookup masterLookup) {\n        return getComponent();\n    }\n\n    public void addPropertyChangeListener(PropertyChangeListener l) {\n        pcs.addPropertyChangeListener(l);\n    }\n\n    public void removePropertyChangeListener(PropertyChangeListener l) {\n        pcs.removePropertyChangeListener(l);\n    }\n\n    private JConsoleCustomizer getPanel() {\n        if (panel == null) {\n            panel = new JConsoleCustomizer(this);\n        }\n        return panel;\n    }\n\n    private JComponent getComponent() {\n        if (component == null) {\n            component = UISupport.createScrollableContainer(getPanel());\n        }\n        return component;\n    }\n\n    void changed() {\n        if (!changed) {\n            changed = true;\n            pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);\n        }\n        pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);\n    }\n}\n"
  },
  {
    "path": "plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/options/JConsoleSettings.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jconsole.options;\n\nimport java.util.prefs.Preferences;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.openide.util.NbPreferences;\n\npublic class JConsoleSettings implements ChangeListener {\n\n    private static final String PROP_POLLING = \"POLLING\"; // NOI18N\n    private static final String PROP_PLUGINSPATH = \"PLUGINS\"; // NOI18N\n    private Preferences pref;\n    private static JConsoleSettings INSTANCE;\n\n    JConsoleSettings() {\n        pref = NbPreferences.forModule(JConsoleSettings.class);\n    }\n\n    public static synchronized JConsoleSettings getDefault() {\n        if (INSTANCE == null) {\n            INSTANCE = new JConsoleSettings();\n        }\n        return INSTANCE;\n    }\n\n    public void stateChanged(ChangeEvent e) {\n    }\n\n    public String getPluginsPath() {\n        return pref.get(PROP_PLUGINSPATH, null);\n    }\n\n    public void setPluginsPath(String value) {\n        pref.put(PROP_PLUGINSPATH, value);\n    }\n\n    public Integer getPolling() {\n        return pref.getInt(PROP_POLLING, 4);\n    }\n\n    public void setPolling(Integer polling) {\n        pref.putInt(PROP_POLLING, polling);\n    }\n}\n"
  },
  {
    "path": "plugins/jconsole/src/org/graalvm/visualvm/modules/jconsole/options/PathController.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jconsole.options;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.File;\nimport java.util.Enumeration;\nimport java.util.StringTokenizer;\nimport javax.swing.DefaultListModel;\nimport javax.swing.JButton;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.ListModel;\nimport javax.swing.event.ListDataEvent;\nimport javax.swing.event.ListDataListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jean-Francois Denise\n */\npublic class PathController implements ActionListener, ListSelectionListener, ListDataListener {\n\n    private JList l;\n    private JButton add;\n    private JButton remove;\n    private JButton up;\n    private JButton down;\n    private JFileChooser chooser;\n    private DefaultListModel model;\n    private JLabel label;\n    private ListDataListener lstnr;\n\n    public PathController(JList l, JLabel label, JButton add, JFileChooser chooser, JButton remove, JButton up, JButton down, ListDataListener lstnr) {\n        this(l, label, createModel(\"\"), add, chooser, remove, up, down, lstnr); // NOI18N\n    }\n\n    public PathController(JList l, JLabel label, String items, JButton add, JFileChooser chooser, JButton remove, JButton up, JButton down, ListDataListener lstnr) {\n        this(l, label, createModel(items), add, chooser, remove, up, down, lstnr);\n    }\n\n    /** Creates a new instance of PathController */\n    public PathController(JList l, JLabel label, DefaultListModel model, JButton add, JFileChooser chooser, JButton remove, JButton up, JButton down, ListDataListener lstnr) {\n        this.l = l;\n        this.label = label;\n        this.model = model;\n        this.add = add;\n        this.remove = remove;\n        this.up = up;\n        this.down = down;\n        this.chooser = chooser;\n\n        this.lstnr = lstnr;\n\n        l.setModel(model);\n        if (model != null) {\n            model.addListDataListener(this);\n        }\n        add.setActionCommand(\"add\");// NOI18N\n        remove.setActionCommand(\"remove\");// NOI18N\n        up.setActionCommand(\"up\");// NOI18N\n        down.setActionCommand(\"down\");// NOI18N\n        add.addActionListener(this);\n        remove.addActionListener(this);\n        up.addActionListener(this);\n        down.addActionListener(this);\n        l.addListSelectionListener(this);\n\n        remove.setEnabled(false);\n        up.setEnabled(false);\n        down.setEnabled(false);\n    }\n\n    public void setEnabled(boolean b) {\n        l.setEnabled(b);\n        label.setEnabled(b);\n        add.setEnabled(b);\n        remove.setEnabled(remove.isEnabled() && b);\n        up.setEnabled(up.isEnabled() && b);\n        down.setEnabled(down.isEnabled() && b);\n    }\n\n    public void setVisible(boolean b) {\n        l.setVisible(b);\n        label.setVisible(b);\n        add.setVisible(b);\n        remove.setVisible(b);\n        up.setVisible(b);\n        down.setVisible(b);\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        if (e.getActionCommand().equals(\"add\")) {// NOI18N\n            int returnVal = chooser.showOpenDialog(WindowManager.getDefault().getMainWindow());\n            if (returnVal == JFileChooser.APPROVE_OPTION) {\n                File[] selection = chooser.getSelectedFiles();\n                int size = selection.length;\n                int end = l.getModel().getSize();\n                for (int i = 0; i < size; i++) {\n                    String path = selection[i].getAbsolutePath();\n                    if (!model.contains(path)) {\n                        model.add(end + i, path);\n                    }\n                }\n            }\n            return;\n        }\n        if (e.getActionCommand().equals(\"remove\")) {// NOI18N\n            Object[] values = l.getSelectedValues();\n\n            for (int i = 0; i < values.length; i++) {\n                model.removeElement(values[i]);\n            }\n            if (model.getSize() == 0) {\n                up.setEnabled(false);\n                down.setEnabled(false);\n                remove.setEnabled(false);\n            }\n            l.setSelectedIndex(0);\n        }\n\n        if (e.getActionCommand().equals(\"up\")) {// NOI18N\n            int selectedI = l.getSelectedIndex();\n            Object selected = l.getSelectedValue();\n            int newIndex = selectedI - 1;\n            Object previous = model.getElementAt(newIndex);\n            model.setElementAt(selected, newIndex);\n            model.setElementAt(previous, selectedI);\n            l.setSelectedIndex(newIndex);\n            return;\n        }\n\n        if (e.getActionCommand().equals(\"down\")) {// NOI18N\n            int selectedI = l.getSelectedIndex();\n            Object selected = l.getSelectedValue();\n            int newIndex = selectedI + 1;\n            Object next = model.getElementAt(newIndex);\n            model.setElementAt(selected, newIndex);\n            model.setElementAt(next, selectedI);\n            l.setSelectedIndex(newIndex);\n            return;\n        }\n    }\n\n    // return the list of selected items\n    @Override\n    public String toString() {\n        Enumeration pluginsPath = model.elements();\n        StringBuffer buffer = new StringBuffer();\n        while (pluginsPath.hasMoreElements()) {\n            Object path = pluginsPath.nextElement();\n            buffer.append(path.toString());\n            if (pluginsPath.hasMoreElements()) {\n                buffer.append(File.pathSeparator);\n            }\n        }\n        return buffer.toString();\n    }\n\n    public synchronized void updateModel(String items) {\n        if (items == null) {\n            return;\n        }\n        ListModel m = l.getModel();\n        if (m != null) {\n            m.removeListDataListener(this);\n        }\n\n        model = createModel(items);\n        model.addListDataListener(this);\n        l.setModel(model);\n    }\n\n    public static DefaultListModel createModel(String items) {\n        StringTokenizer tk = new StringTokenizer(items, File.pathSeparator);\n        DefaultListModel model = new DefaultListModel();\n        while (tk.hasMoreTokens()) {\n            String path = tk.nextToken();\n            model.addElement(path);\n        }\n        return model;\n    }\n\n    public void valueChanged(ListSelectionEvent e) {\n        int[] indices = l.getSelectedIndices();\n        if (indices.length != 1) {\n            up.setEnabled(false);\n            down.setEnabled(false);\n            return;\n        }\n        int single = l.getSelectedIndex();\n        up.setEnabled(true);\n        down.setEnabled(true);\n\n        if (model.getSize() > 0) {\n            remove.setEnabled(true);\n        }\n\n        if (single == 0) {\n            up.setEnabled(false);\n            if (model.getSize() == 1) {\n                down.setEnabled(false);\n            }\n        }\n\n        if (single == model.getSize() - 1) {\n            down.setEnabled(false);\n        }\n    }\n\n    public void intervalAdded(ListDataEvent arg0) {\n        if (lstnr == null) {\n            return;\n        }\n        lstnr.intervalAdded(arg0);\n    }\n\n    public void intervalRemoved(ListDataEvent arg0) {\n        if (lstnr == null) {\n            return;\n        }\n        lstnr.intervalRemoved(arg0);\n    }\n\n    public void contentsChanged(ListDataEvent arg0) {\n        if (lstnr == null) {\n            return;\n        }\n        lstnr.contentsChanged(arg0);\n    }\n}\n"
  },
  {
    "path": "plugins/jfr.streaming/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.jfr.streaming\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.jfr.streaming.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/jfr.streaming/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: true\nOpenIDE-Module: org.graalvm.visualvm.jfr.streaming\nOpenIDE-Module-Install: org/graalvm/visualvm/jfr/streaming/Installer.class\nOpenIDE-Module-Java-Dependencies: Java > 17\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/jfr/streaming/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.7\n"
  },
  {
    "path": "plugins/jfr.streaming/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.jfr.streaming-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/jfr.streaming/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=1ba7908e\nbuild.xml.script.CRC32=c2718227\nbuild.xml.stylesheet.CRC32=15ca8a54@2.75.1\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=1ba7908e\nnbproject/build-impl.xml.script.CRC32=dc0dd611\nnbproject/build-impl.xml.stylesheet.CRC32=1016842c@2.75.1\n"
  },
  {
    "path": "plugins/jfr.streaming/nbproject/project.properties",
    "content": "is.eager=true\njavac.compilerargs=-Xlint -Xlint:-serial\njavac.source=17\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Tomas Hurka\nnbm.needs.restart=true\n"
  },
  {
    "path": "plugins/jfr.streaming/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.jfr.streaming</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application.views</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.charts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host.views</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.10</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.60</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.19</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.46</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.20</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/jfr.streaming/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/Bundle.properties",
    "content": "#\n# Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Tools\nOpenIDE-Module-Long-Description=\\\n    Support for the JFR Streaming bundled with JDK 17 and newer (requires running VisualVM on JDK 17+)\nOpenIDE-Module-Name=VisualVM-JFR Streaming\nOpenIDE-Module-Short-Description=Support for the JFR streaming for JDK 17 and newer\n"
  },
  {
    "path": "plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/Installer.java",
    "content": "/*\n * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.streaming;\n\nimport org.graalvm.visualvm.jfr.streaming.network.NetworkViewPluginProvider;\nimport org.openide.modules.ModuleInstall;\n\npublic class Installer extends ModuleInstall {\n\n    @Override\n    public void restored() {\n        NetworkViewPluginProvider.initialize();\n    }\n\n}\n"
  },
  {
    "path": "plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/JFRStream.java",
    "content": "/*\n * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.streaming;\n\nimport java.io.IOException;\nimport java.time.Duration;\nimport java.util.function.Consumer;\nimport jdk.jfr.EventSettings;\nimport jdk.jfr.Period;\nimport jdk.jfr.StackTrace;\nimport jdk.jfr.Threshold;\nimport jdk.jfr.consumer.RecordedEvent;\nimport jdk.management.jfr.RemoteRecordingStream;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class JFRStream {\n\n    private final RemoteRecordingStream rs;\n\n    public static JFRStream getFor(Application app) throws IOException {\n        Jvm jvm = JvmFactory.getJVMFor(app);\n        String ver = jvm.getJavaVersion();\n        if (isJavaVersion(ver, \"17\") || isJavaVersion(ver, \"18\") \n         || isJavaVersion(ver, \"19\") || isJavaVersion(ver, \"20\")\n         || isJavaVersion(ver, \"21\") || isJavaVersion(ver, \"22\")\n         || isJavaVersion(ver, \"23\") || isJavaVersion(ver, \"24\")\n         || isJavaVersion(ver, \"25\")) {\n            JmxModel jmxModel = JmxModelFactory.getJmxModelFor(app);\n            if (jmxModel != null && jmxModel.getConnectionState() == JmxModel.ConnectionState.CONNECTED) {\n                return new JFRStream(jmxModel);\n            }\n        }\n        return null;\n    }\n\n    private JFRStream(JmxModel jmx) throws IOException {\n        rs = new RemoteRecordingStream(jmx.getMBeanServerConnection());\n    }\n\n    public void close() {\n        rs.close();\n    }\n\n    public JFREventSettings enable(String eventName) {\n        EventSettings s = rs.enable(eventName);\n        return new JFREventSettings(eventName, s);\n    }\n\n    public void onEvent(String eventName, Consumer<RecordedEvent> action) {\n        rs.onEvent(eventName, action);\n    }\n\n    public void onFlush(Runnable action) {\n        rs.onFlush(action);\n    }\n\n    public void startAsync() {\n        rs.startAsync();\n    }\n\n    public class JFREventSettings {\n\n        private final String eventName;\n        private final EventSettings delegate;\n\n        private JFREventSettings(String eventName, EventSettings s) {\n            this.eventName = eventName;\n            delegate = s;\n        }\n\n        public JFREventSettings withStackTrace() {\n            return with(StackTrace.NAME, \"true\");\n        }\n\n        public JFREventSettings withoutStackTrace() {\n            return with(StackTrace.NAME, \"false\");\n        }\n\n        public JFREventSettings withoutThreshold() {\n            return withThreshold(null);\n        }\n\n        public JFREventSettings withPeriod(Duration duration) {\n            return with(Period.NAME, getString(duration));\n        }\n\n        public JFREventSettings withThreshold(Duration duration) {\n            return with(Threshold.NAME, getString(duration));\n        }\n\n        public JFREventSettings with(String name, String value) {\n            delegate.with(eventName + \"#\" + name, value);\n            return this;\n        }\n\n        private static String getString(Duration duration) {\n            if (duration == null) {\n                return \"0 s\";\n            }\n            return duration.toNanos() + \" ns\";\n        }\n    }\n\n    private static final boolean isJavaVersion(String javaVersionProperty, String releaseVersion) {\n        if (javaVersionProperty.equals(releaseVersion)) {\n            return true;\n        }\n        if (javaVersionProperty.equals(releaseVersion + \"-ea\")) {\n            return true;\n        }\n        if (javaVersionProperty.equals(releaseVersion + \"-internal\")) {\n            return true;\n        }\n        if (javaVersionProperty.startsWith(releaseVersion + \".\")) {\n            return true;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/network/Bundle.properties",
    "content": "#\n# Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n# HTML-formatted: <unknown> (&lt; and &gt; must remain!)\nLBL_Unknown=&lt;unknown&gt;\n\n\nLBL_Network=Network\n\nLBL_Heap=Heap\n\nLBL_Format_Kibps={0} Kibit/s\n\nLBL_Read_rate=Read rate\n\nLBL_Write_rate=Write rate\n\nLBL_Read_rate_leg=Read rate\n\nLBL_Write_rate_leg=Write rate"
  },
  {
    "path": "plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/network/NetworkModel.java",
    "content": "/*\n * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.streaming.network;\n\nimport java.time.Duration;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport jdk.jfr.consumer.RecordedEvent;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.jfr.streaming.JFRStream;\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class NetworkModel {\n\n    private static final String JFR_NETWORK_UTILIZATION = \"jdk.NetworkUtilization\"; // NOI18N\n\n    private boolean initialized;\n    private Host source;\n    private JFRStream jfr;\n    private boolean live;\n\n    private final List<ChangeListener> listeners;\n    private int chartCache = -1;\n    private long timestamp = -1;\n    private long readRate = -1;\n    private long writeRate = -1;\n\n    static NetworkModel create(Host host, JFRStream rs) {\n        return new NetworkModel(host, rs);\n    }\n\n    DataSource getSource() {\n        return source;\n    }\n\n    boolean isLive() {\n        return live;\n    }\n\n    long getTimestamp() {\n        return timestamp;\n    }\n\n    int getChartCache() {\n        return chartCache;\n    }\n\n    long getReadRate() {\n        return readRate;\n    }\n\n    long getWriteRate() {\n        return writeRate;\n    }\n\n    synchronized void initialize() {\n        if (initialized) {\n            return;\n        }\n        initialized = true;\n        initialize(source);\n    }\n\n    synchronized void cleanup() {\n        listeners.clear();\n        if (!initialized) {\n            return;\n        }\n        jfr.close();\n        jfr = null;\n    }\n\n    void addChangeListener(ChangeListener listener) {\n        if (live) {\n            listeners.add(listener);\n        }\n    }\n\n    void removeChangeListener(ChangeListener listener) {\n        if (live) {\n            listeners.remove(listener);\n        }\n    }\n\n    private void initialize(Host host) {\n        GlobalPreferences preferences = GlobalPreferences.sharedInstance();\n        final int monitoredDataPoll = preferences.getMonitoredDataPoll();\n        chartCache = 60 * preferences.getMonitoredDataCache() / monitoredDataPoll;\n\n        jfr.enable(JFR_NETWORK_UTILIZATION).withPeriod(Duration.ofSeconds(monitoredDataPoll));\n        jfr.onEvent(JFR_NETWORK_UTILIZATION, this::networkEvent);\n        jfr.onFlush(this::jfrFlush);\n        jfr.startAsync();\n    }\n\n    private void jfrFlush() {\n        SwingUtilities.invokeLater(() -> {\n            fireChange();\n            timestamp = -1;\n        });\n    }\n\n    private void networkEvent(final RecordedEvent ev) {\n        final Long[] values = getData(ev);\n\n        if (values != null) {\n            SwingUtilities.invokeLater(() -> {\n                long time = ev.getStartTime().toEpochMilli();\n                if (time == timestamp) {\n                    readRate += values[0];\n                    writeRate += values[1];\n                } else {\n                    fireChange();\n                    readRate = values[0];\n                    writeRate = values[1];\n                    timestamp = time;\n                }\n            });\n        }\n    }\n\n    private Long[] getData(RecordedEvent ev) {\n        if (live) {\n            String iface = ev.getString(\"networkInterface\");        // NOI18N\n            long rRate = ev.getLong(\"readRate\");        // NOI18N\n            long wRate = ev.getLong(\"writeRate\");       // NOI18N\n            return new Long[]{rRate, wRate};\n        }\n        return null;\n    }\n\n    private void fireChange() {\n        if (timestamp == -1) return;\n        final List<ChangeListener> list = new ArrayList<>();\n        synchronized (listeners) {\n            list.addAll(listeners);\n        }\n        for (ChangeListener l : list) {\n            l.stateChanged(new ChangeEvent(this));\n        }\n    }\n\n    private NetworkModel() {\n        initialized = false;\n        listeners = Collections.synchronizedList(new ArrayList<>());\n    }\n\n    private NetworkModel(Host src, JFRStream rs) {\n        this();\n        source = src;\n        jfr = rs;\n        live = true;\n    }\n}\n"
  },
  {
    "path": "plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/network/NetworkViewComponent.java",
    "content": "/*\n * Copyright (c) 2022, 2022 Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.streaming.network;\n\nimport java.awt.BorderLayout;\nimport java.text.MessageFormat;\nimport javax.swing.JPanel;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.charts.ChartFactory;\nimport org.graalvm.visualvm.charts.SimpleXYChartDescriptor;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.NotSupportedDisplayer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass NetworkViewComponent extends JPanel {\n\n    private static final String UNKNOWN = NbBundle.getMessage(NetworkViewComponent.class, \"LBL_Unknown\"); // NOI18N\n\n    private boolean liveModel;\n    private boolean networkMonitoringSupported;\n    private String panelName;\n\n    private SimpleXYChartSupport chartSupport;\n\n    NetworkViewComponent(NetworkModel model) {\n        initModels(model);\n        initComponents();\n    }\n\n    DataViewComponent.DetailsView getDetailsView() {\n        return new DataViewComponent.DetailsView(panelName, null, 10, this, null);\n    }\n\n    private void refresh(NetworkModel model) {\n        if (networkMonitoringSupported) {\n            long readRate = model.getReadRate();\n            long writeRate = model.getWriteRate();\n\n            if (liveModel) {\n                chartSupport.addValues(model.getTimestamp(), new long[]{readRate, writeRate});\n            }\n            chartSupport.updateDetails(new String[]{formatKpbs(readRate / 1024),\n                formatKpbs(writeRate / 1024)});\n        }\n    }\n\n    private String formatKpbs(long value) {\n        String bytesFormat = NbBundle.getMessage(NetworkViewComponent.class,\n                \"LBL_Format_Kibps\"); // NOI18N\n        return MessageFormat.format(bytesFormat, new Object[]{chartSupport.formatDecimal(value)});\n\n    }\n\n    private void initModels(final NetworkModel model) {\n        liveModel = model.isLive();\n        networkMonitoringSupported = true;\n        panelName = NbBundle.getMessage(NetworkViewComponent.class, \"LBL_Network\"); // NOI18N\n\n        if (networkMonitoringSupported) {\n            String READ_RATE = NbBundle.getMessage(NetworkViewComponent.class, \"LBL_Read_rate\"); // NOI18N\n            String READ_RATE_LEG = NbBundle.getMessage(NetworkViewComponent.class, \"LBL_Read_rate_leg\"); // NOI18N\n            String WRITE_RATE = NbBundle.getMessage(NetworkViewComponent.class, \"LBL_Write_rate\"); // NOI18N\n            String WRITE_RATE_LEG = NbBundle.getMessage(NetworkViewComponent.class, \"LBL_Write_rate_leg\"); // NOI18N\n            SimpleXYChartDescriptor chartDescriptor\n                    = SimpleXYChartDescriptor.bitsPerSec(10 * 1024 * 1024, false, model.getChartCache());\n\n            chartDescriptor.addLineItems(READ_RATE_LEG, WRITE_RATE_LEG);\n            chartDescriptor.setDetailsItems(new String[]{READ_RATE, WRITE_RATE});\n\n            chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n            chartSupport.setZoomingEnabled(!liveModel);\n\n            model.addChangeListener(new ChangeListener() {\n                public void stateChanged(ChangeEvent e) {\n                    refresh(model);\n                }\n            });\n        }\n    }\n\n    private void initComponents() {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n\n        if (networkMonitoringSupported) {\n            add(chartSupport.getChart(), BorderLayout.CENTER);\n            chartSupport.updateDetails(new String[]{UNKNOWN, UNKNOWN, UNKNOWN});\n        } else {\n            add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM),\n                    BorderLayout.CENTER);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/network/NetworkViewPlugin.java",
    "content": "/*\n * Copyright (c) 2022, 2022 Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.streaming.network;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class NetworkViewPlugin extends DataSourceViewPlugin {\n\n    private final NetworkModel model;\n    private NetworkViewComponent view;\n\n    @Override\n    public DataViewComponent.DetailsView createView(int location) {\n        switch (location) {\n            case DataViewComponent.TOP_LEFT:\n                view = new NetworkViewComponent(model);\n                return view.getDetailsView();\n            default:\n                return null;\n        }\n    }\n\n    @Override\n    protected void willBeAdded() {\n        model.initialize();\n    }\n\n    @Override\n    protected void removed() {\n        model.cleanup();\n    }\n\n    NetworkModel getModel() {\n        return model;\n    }\n\n    NetworkViewPlugin(DataSource dataSource, NetworkModel model) {\n        super(dataSource);\n        this.model = model;\n    }\n}\n"
  },
  {
    "path": "plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/network/NetworkViewPluginProvider.java",
    "content": "/*\n * Copyright (c) 2022, 2022 Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.streaming.network;\n\nimport java.io.IOException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.host.views.HostViewsSupport;\nimport org.graalvm.visualvm.jfr.streaming.JFRStream;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class NetworkViewPluginProvider extends DataSourceViewPluginProvider<Host> {\n\n    private static final Logger LOGGER = Logger.getLogger(NetworkViewPluginProvider.class.getName());\n    private JFRStream rs;\n\n    @Override\n    protected DataSourceViewPlugin createPlugin(Host host) {\n        return new NetworkViewPlugin(host, NetworkModel.create(host, rs));\n    }\n\n    @Override\n    protected boolean supportsPluginFor(Host t) {\n        if (Host.LOCALHOST.equals(t)) {\n            try {\n                rs = JFRStream.getFor(Application.CURRENT_APPLICATION);\n            } catch (IOException ex) {\n                LOGGER.log(Level.WARNING, \"supportsPluginFor\", ex);\n            }\n            return rs != null;\n        }\n        return false;\n    }\n\n    private NetworkViewPluginProvider() {\n    }\n\n    public static void initialize() {\n        HostViewsSupport.sharedInstance().getOverviewView().\n                registerPluginProvider(new NetworkViewPluginProvider());\n    }\n}\n"
  },
  {
    "path": "plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/threads/JFRThreadDataProvider.java",
    "content": "/*\n * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.streaming.threads;\n\nimport java.lang.management.ThreadInfo;\nimport java.lang.management.ThreadMXBean;\nimport java.time.Instant;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.function.Consumer;\nimport jdk.jfr.consumer.RecordedEvent;\nimport jdk.jfr.consumer.RecordedThread;\nimport org.graalvm.visualvm.application.views.ApplicationThreadsResponseProvider;\nimport org.graalvm.visualvm.jfr.streaming.JFRStream;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.MonitoredNumbersResponse;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class JFRThreadDataProvider implements ApplicationThreadsResponseProvider.ThreadMonitoredDataResponseProvider {\n\n    private final JFRStream recordingStream;\n    private final ThreadMXBean threadMXBean;\n    private final List<JFREvent> events;\n    private final List<JFRThread> newThreads;\n    private final Set<Long> threadIdSet;\n\n    JFRThreadDataProvider(JFRStream rs, ThreadMXBean tb) {\n        recordingStream = rs;\n        threadMXBean = tb;\n        events = new ArrayList<>();\n        threadIdSet = new HashSet<>();\n        newThreads = new ArrayList<>();\n    }\n\n    @Override\n    public MonitoredNumbersResponse createThreadMonitoredDataResponse() {\n        JFRNumbersResponse rp = new JFRNumbersResponse();\n\n        if (threadIdSet.isEmpty()) {\n            threadIdSet.addAll(fillInThreadData(rp));\n            return rp;\n        }\n        synchronized (newThreads) {\n            int[] newThreadsId = new int[newThreads.size()];\n            String[] newThreadsNames = new String[newThreads.size()];\n            String[] newThreadsClasses = new String[newThreads.size()];\n            int ntc = 0;\n            for (JFRThread t : newThreads) {\n                if (threadIdSet.add(t.threadId)) {\n                    newThreadsId[ntc] = (int) t.threadId;\n                    newThreadsNames[ntc] = t.name;\n                    newThreadsClasses[ntc] = \"\";\n                    ntc++;\n                }\n            }\n            if (ntc > 0) {\n                rp.setDataOnNewThreads(ntc, newThreadsId, newThreadsNames, newThreadsClasses);\n            }\n            newThreads.clear();\n        }\n        synchronized (events) {\n            byte[] explicitStates = new byte[events.size()];\n            int[] explicitThreads = new int[events.size()];\n            long[] explicitTimeStamps = new long[events.size()];\n            int ePos = 0;\n            for (int i = 0; i < events.size(); i++) {\n                JFREvent te = events.get(i);\n                if (te.status == CommonConstants.THREAD_STATUS_ZOMBIE) {\n                    if (!threadIdSet.remove(te.threadId)) {\n                        //unknown thread\n                        continue;\n                    }\n                }\n                explicitStates[ePos] = te.status;\n                explicitThreads[ePos] = (int) te.threadId;\n                explicitTimeStamps[ePos] = te.timeStamp;\n                ePos++;\n            }\n            events.clear();\n            if (ePos < explicitStates.length) {\n                byte[] msgExplicitStates = new byte[ePos];\n                System.arraycopy(explicitStates, 0, msgExplicitStates, 0, ePos);\n                int[] msgExplicitThreads = new int[ePos];\n                System.arraycopy(explicitThreads, 0, msgExplicitThreads, 0, ePos);\n                long[] msgExplicitTimeStamps = new long[ePos];\n                System.arraycopy(explicitTimeStamps, 0, msgExplicitTimeStamps, 0, ePos);\n                rp.setExplicitDataOnThreads(msgExplicitThreads, msgExplicitStates, msgExplicitTimeStamps);\n            } else {\n                rp.setExplicitDataOnThreads(explicitThreads, explicitStates, explicitTimeStamps);\n            }\n        }\n        return rp;\n    }\n\n    Consumer<RecordedEvent> threadStart() {\n        return (RecordedEvent e) -> {\n            RecordedThread t = e.getThread();\n            addThreadStart(e.getStartTime(), t.getJavaThreadId(), t.getJavaName());\n        };\n    }\n\n    Consumer<RecordedEvent> threadEnd() {\n        return (RecordedEvent e) -> {\n            addThreadEnd(e.getThread().getJavaThreadId(), e.getStartTime());\n        };\n    }\n\n    Consumer<RecordedEvent> javaMonitorWait() {\n        return (RecordedEvent e) -> {\n            addWaitEvent(CommonConstants.THREAD_STATUS_WAIT, e);\n        };\n    }\n\n    Consumer<RecordedEvent> javaMonitorEnter() {\n        return (RecordedEvent e) -> {\n            addWaitEvent(CommonConstants.THREAD_STATUS_MONITOR, e);\n        };\n    }\n\n    Consumer<RecordedEvent> threadPark() {\n        return (RecordedEvent e) -> {\n            addWaitEvent(CommonConstants.THREAD_STATUS_PARK, e);\n        };\n    }\n\n    Consumer<RecordedEvent> threadSleep() {\n        return (RecordedEvent e) -> {\n            addWaitEvent(CommonConstants.THREAD_STATUS_SLEEPING, e);\n        };\n    }\n\n    public void cleanup() {\n        recordingStream.close();\n    }\n\n    private void addThreadEnd(long id, Instant startTime) {\n        addEvent(id, CommonConstants.THREAD_STATUS_ZOMBIE, startTime.toEpochMilli());\n    }\n\n    private void addThreadStart(Instant startTime, long javaThreadId, String javaName) {\n        synchronized (newThreads) {\n            newThreads.add(new JFRThread(javaThreadId, javaName));\n        }\n    }\n\n    private void addWaitEvent(byte status, RecordedEvent e) {\n        addWaitEvent(status, e.getThread().getJavaThreadId(), e.getStartTime(), e.getEndTime());\n    }\n\n    private void addWaitEvent(byte status, long threadId, Instant startTime, Instant endTime) {\n        addEvent(threadId, status, startTime.toEpochMilli());\n        addEvent(threadId, CommonConstants.THREAD_STATUS_RUNNING, endTime.toEpochMilli());\n    }\n\n    private void addEvent(long threadId, byte status, long toEpochMilli) {\n        synchronized (events) {\n            events.add(new JFREvent(threadId, status, toEpochMilli));\n        }\n    }\n\n    private Set<Long> fillInThreadData(JFRNumbersResponse rp) {\n        long[] currentThreadIds = threadMXBean.getAllThreadIds();\n        ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(currentThreadIds, 1);\n        Set<Long> currentIdSet = new HashSet<>(currentThreadIds.length * 4 / 3);\n        long timeStamps[] = {System.currentTimeMillis()};\n        int maxThreads = currentThreadIds.length;\n        int tids[] = new int[maxThreads];\n        byte states[] = new byte[maxThreads];\n\n        int nNewThreads = 0;\n        int newThreadsId[] = new int[currentThreadIds.length];\n        String[] newThreadsNames = new String[currentThreadIds.length];\n        String[] newThreadsClasses = new String[currentThreadIds.length];\n\n        for (int i = 0; i < currentThreadIds.length; i++) {\n            ThreadInfo tinfo = threadInfos[i];\n            long threadId = currentThreadIds[i];\n\n            if (tinfo == null) {\n                continue;\n            }\n            currentIdSet.add(threadId);\n\n            newThreadsId[nNewThreads] = (int) threadId;\n            newThreadsNames[nNewThreads] = tinfo.getThreadName();\n            newThreadsClasses[nNewThreads] = \"\";\n\n            tids[nNewThreads] = (int) threadId;\n            states[nNewThreads] = getState(tinfo);\n            nNewThreads++;\n        }\n        rp.setDataOnNewThreads(nNewThreads, newThreadsId, newThreadsNames, newThreadsClasses);\n        rp.setDataOnThreads(nNewThreads, timeStamps.length, tids, timeStamps, states);\n        return currentIdSet;\n    }\n\n    byte getState(ThreadInfo threadInfo) {\n        Thread.State state = threadInfo.getThreadState();\n        switch (state) {\n            case BLOCKED:\n                return CommonConstants.THREAD_STATUS_MONITOR;\n            case RUNNABLE:\n                return CommonConstants.THREAD_STATUS_RUNNING;\n            case TIMED_WAITING:\n            case WAITING:\n                StackTraceElement[] stack = threadInfo.getStackTrace();\n                if (stack.length > 0) {\n                    StackTraceElement el = stack[0];\n                    if (isSleeping(el)) {\n                        return CommonConstants.THREAD_STATUS_SLEEPING;\n                    }\n                    if (isParked(el)) {\n                        return CommonConstants.THREAD_STATUS_PARK;\n                    }\n                }\n                return CommonConstants.THREAD_STATUS_WAIT;\n            case TERMINATED:\n            case NEW:\n                return CommonConstants.THREAD_STATUS_ZOMBIE;\n        }\n        return CommonConstants.THREAD_STATUS_UNKNOWN;\n    }\n\n    boolean isSleeping(StackTraceElement element) {\n        return Thread.class.getName().equals(element.getClassName())\n                && \"sleep\".equals(element.getMethodName());    // NOI18N\n    }\n\n    boolean isParked(StackTraceElement element) {\n        String className = element.getClassName();\n\n        if (\"jdk.internal.misc.Unsafe\".equals(className) || \"sun.misc.Unsafe\".equals(className)) {  // NOI18N\n            return \"park\".equals(element.getMethodName());      // NOI18N\n        }\n        return false;\n    }\n\n    private class JFREvent {\n\n        private long threadId;\n        private byte status;\n        private long timeStamp;\n\n        private JFREvent(long id, byte st, long time) {\n            threadId = id;\n            status = st;\n            timeStamp = time;\n        }\n    }\n\n    private class JFRThread {\n\n        private long threadId;\n        private String name;\n\n        private JFRThread(long id, String n) {\n            threadId = id;\n            name = n;\n        }\n    }\n\n    class JFRNumbersResponse extends MonitoredNumbersResponse {\n\n        private static final long[] dummyLong = new long[0];\n\n        JFRNumbersResponse() {\n            super(dummyLong, CommonConstants.SERVER_RUNNING, CommonConstants.SERVER_PROGRESS_INDETERMINATE);\n            setGCstartFinishData(dummyLong, dummyLong);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/jfr.streaming/src/org/graalvm/visualvm/jfr/streaming/threads/ThreadMonitoringProvider.java",
    "content": "/*\n * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.streaming.threads;\n\nimport java.io.IOException;\nimport java.lang.management.ThreadMXBean;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.views.ApplicationThreadsResponseProvider;\nimport org.graalvm.visualvm.jfr.streaming.JFRStream;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service = ApplicationThreadsResponseProvider.class)\npublic class ThreadMonitoringProvider implements ApplicationThreadsResponseProvider {\n\n    private static final String JFR_THREAD_SLEEP = \"jdk.ThreadSleep\";\n    private static final String JFR_THREAD_PARK = \"jdk.ThreadPark\";\n    private static final String JFR_JAVA_MONITOR_ENTER = \"jdk.JavaMonitorEnter\";\n    private static final String JFR_JAVA_MONITOR_WAIT = \"jdk.JavaMonitorWait\";\n    private static final String JFR_THREAD_END = \"jdk.ThreadEnd\";\n    private static final String JFR_THREAD_START = \"jdk.ThreadStart\";\n\n    @Override\n    public ThreadMonitoredDataResponseProvider getMonitoredDataResponseProvider(Application app, ThreadMXBean threadMXBean) {\n        try {\n            JFRStream rs = JFRStream.getFor(app);\n            if (rs != null) {\n                JFRThreadDataProvider rp = new JFRThreadDataProvider(rs, threadMXBean);\n                rs.enable(JFR_THREAD_START);\n                rs.enable(JFR_THREAD_END);\n                rs.enable(JFR_JAVA_MONITOR_WAIT).withoutStackTrace();\n                rs.enable(JFR_JAVA_MONITOR_ENTER).withoutStackTrace();\n                rs.enable(JFR_THREAD_PARK).withoutStackTrace();\n                rs.enable(JFR_THREAD_SLEEP).withoutStackTrace();\n                rs.onEvent(JFR_THREAD_START, rp.threadStart());\n                rs.onEvent(JFR_THREAD_END, rp.threadEnd());\n                rs.onEvent(JFR_JAVA_MONITOR_WAIT, rp.javaMonitorWait());\n                rs.onEvent(JFR_JAVA_MONITOR_ENTER, rp.javaMonitorEnter());\n                rs.onEvent(JFR_THREAD_PARK, rp.threadPark());\n                rs.onEvent(JFR_THREAD_SLEEP, rp.threadSleep());\n                rs.startAsync();\n                return rp;\n            }\n        } catch (IOException ex) {\n            Logger.getLogger(ThreadMonitoringProvider.class.getName()).log(Level.INFO, null, ex);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "plugins/jolokia/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.jolokia\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.jolokia.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n    <target name=\"download-all-extbins\" unless=\"ext.binaries.downloaded\" depends=\"init\">\n      <echo>Downloading external binaries (external/ directory)...</echo>\n      <property name=\"binaries.cache\" location=\"${user.home}/.hgexternalcache\"/>\n      <property name=\"binaries.server\" value=\"https://netbeans.osuosl.org/binaries/\"/>\n      <downloadbinaries cache=\"${binaries.cache}\" server=\"${binaries.server}\" >\n          <manifest dir=\".\">\n              <include name=\"external/binaries-list\"/>\n          </manifest>\n      </downloadbinaries>\n      <property name=\"ext.binaries.downloaded\" value=\"true\"/>\n    </target>\n\n    <target name=\"-pre-compile\" depends=\"download-all-extbins\">      \n    </target>\n\n    <target name=\"-pre-release\" depends=\"compile\">\n        <taskdef name=\"releasefilescopy\" classname=\"org.netbeans.nbbuild.extlibs.ReleaseFilesCopy\" classpath=\"${harness.dir}/tasks.jar\"/>\n        <releasefilescopy cluster=\"${cluster}\"/>\n    </target>\n\n    <target name=\"-release.files\" depends=\"projectized-common.-release.files\">\n        <taskdef name=\"releasefilesextra\" classname=\"org.netbeans.nbbuild.extlibs.ReleaseFilesExtra\" classpath=\"${harness.dir}/tasks.jar\"/>\n        <releasefilesextra property=\"release.files.extra\"/>\n    </target>\n\n    <target name=\"-pre-nbm\" depends=\"compile\">\n      <property name=\"license.file.override\" location=\"${build.dir}/license\"/>\n      <property name=\"extra.license.files\" value=\"\"/>\n      <taskdef name=\"releasefileslicense\" classname=\"org.netbeans.nbbuild.extlibs.ReleaseFilesLicense\" classpath=\"${harness.dir}/tasks.jar\"/>\n      <releasefileslicense license=\"${license.file.override}\" standardlicense=\"${license.file}\" extralicensefiles=\"${extra.license.files}\"/>\n    </target>\n</project>\n"
  },
  {
    "path": "plugins/jolokia/external/binaries-list",
    "content": "A8F24794CF3ABCBB54A2173EA11A45C80544EC75 org.jolokia:jolokia-client-jmx-adapter:2.2.2\n27A76E0BDDEB96DDD14BE07189B3BF3BD0E2764F org.jolokia:jolokia-client-java:2.2.2\n86CC1DAFC21A7214EEC1A3BB6910C865C378EC0A org.jolokia:jolokia-json:2.2.2\n1BC42013E50B0065503821FD1FAD3D9B5C6FB9EB org.jolokia:jolokia-server-core:2.2.2\n28D7DB48D69AAC91CD55CB914371044AC5A83910 org.jolokia:jolokia-service-serializer:2.2.2\n1194890E6F56EC29177673F2F12D0B8E627DEC98 org.apache.httpcomponents:httpclient:4.5.14\n51CF043C87253C9F58B539C9F7E44C8894223850 org.apache.httpcomponents:httpcore:4.4.16\nB9FC14968D63A8B8A8A2C1885FE3E90564239708 commons-logging:commons-logging:1.3.4\n973638B7149D333563584137EBF13A691BB60579 commons-codec:commons-codec:1.17.1\n6C525AFAE116416E5EA3D02FAA70BBA833CF7178 org.jolokia:jolokia-client-kubernetes:2.2.2\n2AA2FC58356CDCEA1C9C23B0F4A58EAF147B973C io.fabric8:kubernetes-client:6.13.4\n5BCBB03DEB72DC59AE8F504207CB85B212B6E3F8 io.fabric8:kubernetes-client-api:6.13.4\n9BB4038F7206BEAC6243FC603D7D8913F47064CE io.fabric8:kubernetes-model-core:6.13.4\n7926CDB2A27C4517F67A57E84B0FDC52321BB881 io.fabric8:kubernetes-model-common:6.13.4\nCA25C2F0E58571D4ED3F44B85EAEEFC006F39BC9 io.fabric8:kubernetes-model-gatewayapi:6.13.4\n06D5724E29416153D3AA4F5EFA2DFBDB308C9416 io.fabric8:kubernetes-model-resource:6.13.4\nBC68CC9AD92E3E6B48ACF518885B07AA94B5ADCF io.fabric8:kubernetes-model-rbac:6.13.4\n81526FAD72FF4E9B633AD9763021E4180EEC7BD5 io.fabric8:kubernetes-model-admissionregistration:6.13.4\nB8535726E5DE504086E7DAC2C775C24A1CD1A272 io.fabric8:kubernetes-model-apps:6.13.4\n14672963E19477F584FB632A2DAF4CBB676AEDE4 io.fabric8:kubernetes-model-autoscaling:6.13.4\nB7A04C7B3E5594B74877CF659C9F271197674833 io.fabric8:kubernetes-model-apiextensions:6.13.4\n7EB4C0785834E1C9DB194C9DAFAB9AE1187FBAA0 io.fabric8:kubernetes-model-batch:6.13.4\n30109AEE3D13E6D633ED974F3CD83761166394BE io.fabric8:kubernetes-model-certificates:6.13.4\nB17C645531BF9F6BFE02E68982BC0E0D62DF15EB io.fabric8:kubernetes-model-coordination:6.13.4\n2718498178FC1D79FF1E7169985CF3D2149AED6E io.fabric8:kubernetes-model-discovery:6.13.4\nD716A15F8A23982FA72EA99A0017E16A3799BA67 io.fabric8:kubernetes-model-events:6.13.4\n14359CF0EEACC9E63274C9D84C679A5923E5D60E io.fabric8:kubernetes-model-extensions:6.13.4\n8D0CF291DDBA20C710F934544920830054617333 io.fabric8:kubernetes-model-flowcontrol:6.13.4\nE9FCBE07E8E44CCD6A3B8A12B052DBF5979A7C9D io.fabric8:kubernetes-model-networking:6.13.4\nD33C2F2C919194171E266D97F790B5CC5347E032 io.fabric8:kubernetes-model-metrics:6.13.4\n9A73E7F0AEEF1BB6E1271092C53D4E0DB92E11BE io.fabric8:kubernetes-model-policy:6.13.4\n0F9AA492F4CD8CB243126E2CD13F84C0FD8EF477 io.fabric8:kubernetes-model-scheduling:6.13.4\n75D3331FBF04D9491649B6606C7997476BA83DFC io.fabric8:kubernetes-model-storageclass:6.13.4\nA4FAD808C14CF3BB6B22B5C9BB3359CA9F0A140F io.fabric8:kubernetes-model-node:6.13.4\n80229737F704B121A318BBA5D5DEACBCF395BC77 org.slf4j:slf4j-api:2.0.13\n5213E62E87E62AC009D80AEB64C8240075BF078A org.snakeyaml:snakeyaml-engine:2.7\nB4C7B8A9EA3F398116A75C146B982B22AFEBC4EE com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.17.1\n3AF797A25458550A16BF89ACC8E4AB2B7F2BFCE0 org.yaml:snakeyaml:2.2\n0969B0C3CB8C75D759E9A6C585C44C9B9F3A4F75 com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.1\nD3EBF0F291297649B4C8DC3ECC81D2EDDEDC100D io.fabric8:zjsonpatch:0.3.0\n508DDD4587B39BF484C0AA71EADC8C6517397720 io.fabric8:kubernetes-httpclient-okhttp:6.13.4\nD3E1CE1D2B3119ADF270B2D00D947BEB03FE3321 com.squareup.okhttp3:okhttp:3.12.12\nBC28B5A964C8F5721EB58EE3F3C47A9BCBF4F4D8 com.squareup.okio:okio:1.15.0\nD952189F6ABB148FF72AAB246AA8C28CF99B469F com.squareup.okhttp3:logging-interceptor:3.12.12\n985D77751EBC7FCE5DB115A986BC9AA82F973F4A com.fasterxml.jackson.core:jackson-annotations:2.18.2\nFB64CCAC5C27DCA8819418EB4E443A9F496D9EE7 com.fasterxml.jackson.core:jackson-core:2.18.2\nDEEF8697B92141FB6CAF7AA86966CFF4EEC9B04F com.fasterxml.jackson.core:jackson-databind:2.18.2\n\n"
  },
  {
    "path": "plugins/jolokia/external/commons-codec-1.17.1-license.txt",
    "content": "Name: Apache Commons Codec\nDescription: General encoding/decoding algorithms (for example phonetic, base64, URL).\nOrigin: https://commons.apache.org/proper/commons-codec/\nVersion: 1.17.1\nLicense: Apache-2.0\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "plugins/jolokia/external/commons-logging-1.3.4-license.txt",
    "content": "Name: Apache Jakarta Commons Logging\nOrigin: Apache Software Foundation\nVersion: 1.3.4\nLicense: Apache-2.0\nDescription: Logging component\nURL: https://commons.apache.org/proper/commons-logging/\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "plugins/jolokia/external/httpclient-4.5.14-license.txt",
    "content": "Name: Apache Commons HttpClient\nOrigin: Apache Software Foundation\nVersion: 4.5.14 \nLicense: Apache-2.0\nDescription: HTTP client\nOrigin: http://hc.apache.org/\nFiles: httpclient-4.5.14.jar, httpcore-4.4.16.jar\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "plugins/jolokia/external/jackson-2.18.2-license.txt",
    "content": "Name: Jackson\nDescription: Jackson is a high-performance JSON processor for Java.\nLicense: Apache-2.0\nOrigin: https://github.com/FasterXML/jackson\nVersion: 2.18.2\nFiles: jackson-annotations-2.18.2.jar, jackson-core-2.18.2.jar, jackson-databind-2.18.2.jar, jackson-dataformat-yaml-2.17.1.jar, jackson-datatype-jsr310-2.17.1.jar\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "plugins/jolokia/external/jolokia-client-kubernetes-2.2.2-license.txt",
    "content": "Name: Jolokia\nDescription: Jolokia is remote JMX with JSON over HTTP.\nLicense: Apache-2.0\nOrigin: https://jolokia.org\nVersion: 2.2.2\nFiles: jolokia-client-java-2.2.2.jar, jolokia-client-jmx-adapter-2.2.2.jar, jolokia-client-kubernetes-2.2.2.jar, jolokia-json-2.2.2.jar, jolokia-server-core-2.2.2.jar, jolokia-service-serializer-2.2.2.jar\n\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "plugins/jolokia/external/kubernetes-client-6.13.4-license.txt",
    "content": "Name: Kubernetes Client\nDescription: Java client for Kubernetes and OpenShift.\nLicense: Apache-2.0\nOrigin: https://github.com/fabric8io/kubernetes-client/\nVersion: 6.13.4\nFiles: kubernetes-client-6.13.4.jar, kubernetes-client-api-6.13.4.jar, kubernetes-httpclient-okhttp-6.13.4.jar, kubernetes-model-admissionregistration-6.13.4.jar, kubernetes-model-apiextensions-6.13.4.jar, kubernetes-model-apps-6.13.4.jar, kubernetes-model-autoscaling-6.13.4.jar, kubernetes-model-batch-6.13.4.jar, kubernetes-model-certificates-6.13.4.jar, kubernetes-model-common-6.13.4.jar, kubernetes-model-coordination-6.13.4.jar, kubernetes-model-core-6.13.4.jar, kubernetes-model-discovery-6.13.4.jar, kubernetes-model-events-6.13.4.jar, kubernetes-model-extensions-6.13.4.jar, kubernetes-model-flowcontrol-6.13.4.jar, kubernetes-model-gatewayapi-6.13.4.jar, kubernetes-model-metrics-6.13.4.jar, kubernetes-model-networking-6.13.4.jar, kubernetes-model-node-6.13.4.jar, kubernetes-model-policy-6.13.4.jar, kubernetes-model-rbac-6.13.4.jar, kubernetes-model-resource-6.13.4.jar, kubernetes-model-scheduling-6.13.4.jar, kubernetes-model-storageclass-6.13.4.jar, zjsonpatch-0.3.0.jar\n\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "plugins/jolokia/external/okhttp-3.12.12-license.txt",
    "content": "Name: OkHttp\nDescription: An HTTP+HTTP/2 client for Android and Java applications.\nLicense: Apache-2.0\nOrigin: https://github.com/square/okhttp/\nVersion: 3.12.12\nFiles: logging-interceptor-3.12.12.jar, okhttp-3.12.12.jar, okio-1.15.0.jar\n\n\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "plugins/jolokia/external/slf4j-api-2.0.13-license.txt",
    "content": "Name: SLF4J\nVersion: 2.0.13\nLicense: MIT-slf4j-22\nOrigin: https://www.slf4j.org/\nDescription: Simple Logging Facade for Java (SLF4J).\n\nCopyright (c) 2004-2024 QOS.ch Sarl (Switzerland)\nAll rights reserved.\n\nPermission is hereby granted, free  of charge, to any person obtaining\na  copy  of this  software  and  associated  documentation files  (the\n\"Software\"), to  deal in  the Software without  restriction, including\nwithout limitation  the rights to  use, copy, modify,  merge, publish,\ndistribute,  sublicense, and/or sell  copies of  the Software,  and to\npermit persons to whom the Software  is furnished to do so, subject to\nthe following conditions:\n\nThe  above  copyright  notice  and  this permission  notice  shall  be\nincluded in all copies or substantial portions of the Software.\n\nTHE  SOFTWARE IS  PROVIDED  \"AS  IS\", WITHOUT  WARRANTY  OF ANY  KIND,\nEXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF\nMERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "plugins/jolokia/external/snakeyaml-2.2-license.txt",
    "content": "Name: snakeyaml\nDescription: YAML 1.2 parser, reader, writer library\nOrigin: GitHub\nVersion: 2.2\nLicense: Apache-2.0\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "plugins/jolokia/external/snakeyaml-engine-2.7-license.txt",
    "content": "Name: snakeyaml-engine\nDescription: YAML 1.2 parser, reader, writer library\nOrigin: GitHub\nVersion: 2.7\nLicense: Apache-2.0\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "plugins/jolokia/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: true\nOpenIDE-Module-Java-Dependencies: Java > 11\nOpenIDE-Module: org.graalvm.visualvm.modules.jolokia\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/jolokia/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.2.2\n\n"
  },
  {
    "path": "plugins/jolokia/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.jolokia-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/jolokia/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=520d0fe2\nbuild.xml.script.CRC32=f245468f\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=78de761a\nnbproject/build-impl.xml.script.CRC32=e26352d3\nnbproject/build-impl.xml.stylesheet.CRC32=68e521fc@2.73\n"
  },
  {
    "path": "plugins/jolokia/nbproject/project.properties",
    "content": "file.reference.jolokia-client-jmx-adapter-2.2.2.jar=external/jolokia-client-jmx-adapter-2.2.2.jar\nfile.reference.jolokia-client-java-2.2.2.jar=external/jjolokia-client-java-2.2.2.jar\nfile.reference.jolokia-json-2.2.2.jar=external/jolokia-json-2.2.2.jar\nfile.reference.jolokia-server-core-2.2.2.jar=external/jolokia-server-core-2.2.2.jar\nfile.reference.jolokia-service-serializer-2.2.2.jar=external/jolokia-service-serializer-2.2.2.jar\nfile.reference.httpclient-4.5.14.jar=external/httpclient-4.5.14.jar\nfile.reference.httpcore-4.4.16.jar=external/httpcore-4.4.16.jar\nfile.reference.commons-logging-1.3.4.jar=external/commons-logging-1.3.4.jar\nfile.reference.commons-codec-1.17.1.jar=external/commons-codec-1.17.1.jar\nfile.reference.jolokia-client-kubernetes-2.2.2.jar=external/jolokia-client-kubernetes-2.2.2.jar\nfile.reference.kubernetes-client-6.13.4.jar=external/kubernetes-client-6.13.4.jar\nfile.reference.kubernetes-client-api-6.13.4.jar=external/kubernetes-client-api-6.13.4.jar\nfile.reference.kubernetes-model-core-6.13.4.jar=external/kubernetes-model-core-6.13.4.jar\nfile.reference.kubernetes-model-common-6.13.4.jar=external/kubernetes-model-common-6.13.4.jar\nfile.reference.kubernetes-model-gatewayapi-6.13.4.jar=external/kubernetes-model-gatewayapi-6.13.4.jar\nfile.reference.kubernetes-model-resource-6.13.4.jar=external/kubernetes-model-resource-6.13.4.jar\nfile.reference.kubernetes-model-rbac-6.13.4.jar=external/kubernetes-model-rbac-6.13.4.jar\nfile.reference.kubernetes-model-admissionregistration-6.13.4.jar=external/kubernetes-model-admissionregistration-6.13.4.jar\nfile.reference.kubernetes-model-apps-6.13.4.jar=external/kubernetes-model-apps-6.13.4.jar\nfile.reference.kubernetes-model-autoscaling-6.13.4.jar=external/kubernetes-model-autoscaling-6.13.4.jar\nfile.reference.kubernetes-model-apiextensions-6.13.4.jar=external/kubernetes-model-apiextensions-6.13.4.jar\nfile.reference.kubernetes-model-batch-6.13.4.jar=external/kubernetes-model-batch-6.13.4.jar\nfile.reference.kubernetes-model-certificates-6.13.4.jar=external/kubernetes-model-certificates-6.13.4.jar\nfile.reference.kubernetes-model-coordination-6.13.4.jar=external/kubernetes-model-coordination-6.13.4.jar\nfile.reference.kubernetes-model-discovery-6.13.4.jar=external/kubernetes-model-discovery-6.13.4.jar\nfile.reference.kubernetes-model-events-6.13.4.jar=external/kubernetes-model-events-6.13.4.jar\nfile.reference.kubernetes-model-extensions-6.13.4.jar=external/kubernetes-model-extensions-6.13.4.jar\nfile.reference.kubernetes-model-flowcontrol-6.13.4.jar=external/kubernetes-model-flowcontrol-6.13.4.jar\nfile.reference.kubernetes-model-networking-6.13.4.jar=external/kubernetes-model-networking-6.13.4.jar\nfile.reference.kubernetes-model-metrics-6.13.4.jar=external/kubernetes-model-metrics-6.13.4.jar\nfile.reference.kubernetes-model-policy-6.13.4.jar=external/kubernetes-model-policy-6.13.4.jar\nfile.reference.kubernetes-model-scheduling-6.13.4.jar=external/kubernetes-model-scheduling-6.13.4.jar\nfile.reference.kubernetes-model-storageclass-6.13.4.jar=external/kubernetes-model-storageclass-6.13.4.jar\nfile.reference.kubernetes-model-node-6.13.4.jar=external/kubernetes-model-node-6.13.4.jar\nfile.reference.slf4j-api-2.0.13.jar=external/slf4j-api-2.0.13.jar\nfile.reference.snakeyaml-engine-2.7.jar=external/snakeyaml-engine-2.7.jar\nfile.reference.jackson-dataformat-yaml-2.17.1.jar=external/jackson-dataformat-yaml-2.17.1.jar\nfile.reference.snakeyaml-2.2.jar=external/snakeyaml-2.2.jar\nfile.reference.jackson-datatype-jsr310-2.17.1.jar=external/jackson-datatype-jsr310-2.17.1.jar\nfile.reference.zjsonpatch-0.3.0.jar=external/zjsonpatch-0.3.0.jar\nfile.reference.kubernetes-httpclient-okhttp-6.13.4.jar=external/kubernetes-httpclient-okhttp-6.13.4.jar\nfile.reference.okhttp-3.12.12.jar=external/okhttp-3.12.12.jar\nfile.reference.okio-1.15.0.jar=external/okio-1.15.0.jar\nfile.reference.logging-interceptor-3.12.12.jar=external/logging-interceptor-3.12.12.jar\nfile.reference.jackson-annotations-2.18.2.jar=external/jackson-annotations-2.18.2.jar\nfile.reference.jackson-core-2.18.2.jar=external/jackson-core-2.18.2.jar\nfile.reference.jackson-databind-2.18.2.jar=external/jackson-databind-2.18.2.jar\nis.eager=true\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Tomas Hurka\nnbm.needs.restart=true\nrelease.external/jolokia-client-jmx-adapter-2.2.2.jar=modules/ext/jolokia-client-jmx-adapter-2.2.2.jar\nrelease.external/jolokia-client-java-2.2.2.jar=modules/ext/jolokia-client-java-2.2.2.jar\nrelease.external/jolokia-json-2.2.2.jar=modules/ext/jolokia-json-2.2.2.jar\nrelease.external/jolokia-server-core-2.2.2.jar=modules/ext/jolokia-server-core-2.2.2.jar\nrelease.external/jolokia-service-serializer-2.2.2.jar=modules/ext/jolokia-service-serializer-2.2.2.jar\nrelease.external/httpclient-4.5.14.jar=modules/ext/httpclient-4.5.14.jar\nrelease.external/httpcore-4.4.16.jar=modules/ext/httpcore-4.4.16.jar\nrelease.external/commons-logging-1.3.4.jar=modules/ext/commons-logging-1.3.4.jar\nrelease.external/commons-codec-1.17.1.jar=modules/ext/commons-codec-1.17.1.jar\nrelease.external/jolokia-client-kubernetes-2.2.2.jar=modules/ext/jolokia-client-kubernetes-2.2.2.jar\nrelease.external/kubernetes-client-6.13.4.jar=modules/ext/kubernetes-client-6.13.4.jar\nrelease.external/kubernetes-client-api-6.13.4.jar=modules/ext/kubernetes-client-api-6.13.4.jar\nrelease.external/kubernetes-model-core-6.13.4.jar=modules/ext/kubernetes-model-core-6.13.4.jar\nrelease.external/kubernetes-model-common-6.13.4.jar=modules/ext/kubernetes-model-common-6.13.4.jar\nrelease.external/kubernetes-model-gatewayapi-6.13.4.jar=modules/ext/kubernetes-model-gatewayapi-6.13.4.jar\nrelease.external/kubernetes-model-resource-6.13.4.jar=modules/ext/kubernetes-model-resource-6.13.4.jar\nrelease.external/kubernetes-model-rbac-6.13.4.jar=modules/ext/kubernetes-model-rbac-6.13.4.jar\nrelease.external/kubernetes-model-admissionregistration-6.13.4.jar=modules/ext/kubernetes-model-admissionregistration-6.13.4.jar\nrelease.external/kubernetes-model-apps-6.13.4.jar=modules/ext/kubernetes-model-apps-6.13.4.jar\nrelease.external/kubernetes-model-autoscaling-6.13.4.jar=modules/ext/kubernetes-model-autoscaling-6.13.4.jar\nrelease.external/kubernetes-model-apiextensions-6.13.4.jar=modules/ext/kubernetes-model-apiextensions-6.13.4.jar\nrelease.external/kubernetes-model-batch-6.13.4.jar=modules/ext/kubernetes-model-batch-6.13.4.jar\nrelease.external/kubernetes-model-certificates-6.13.4.jar=modules/ext/kubernetes-model-certificates-6.13.4.jar\nrelease.external/kubernetes-model-coordination-6.13.4.jar=modules/ext/kubernetes-model-coordination-6.13.4.jar\nrelease.external/kubernetes-model-discovery-6.13.4.jar=modules/ext/kubernetes-model-discovery-6.13.4.jar\nrelease.external/kubernetes-model-events-6.13.4.jar=modules/ext/kubernetes-model-events-6.13.4.jar\nrelease.external/kubernetes-model-extensions-6.13.4.jar=modules/ext/kubernetes-model-extensions-6.13.4.jar\nrelease.external/kubernetes-model-flowcontrol-6.13.4.jar=modules/ext/kubernetes-model-flowcontrol-6.13.4.jar\nrelease.external/kubernetes-model-networking-6.13.4.jar=modules/ext/kubernetes-model-networking-6.13.4.jar\nrelease.external/kubernetes-model-metrics-6.13.4.jar=modules/ext/kubernetes-model-metrics-6.13.4.jar\nrelease.external/kubernetes-model-policy-6.13.4.jar=modules/ext/kubernetes-model-policy-6.13.4.jar\nrelease.external/kubernetes-model-scheduling-6.13.4.jar=modules/ext/kubernetes-model-scheduling-6.13.4.jar\nrelease.external/kubernetes-model-storageclass-6.13.4.jar=modules/ext/kubernetes-model-storageclass-6.13.4.jar\nrelease.external/kubernetes-model-node-6.13.4.jar=modules/ext/kubernetes-model-node-6.13.4.jar\nrelease.external/slf4j-api-2.0.13.jar=modules/ext/slf4j-api-2.0.13.jar\nrelease.external/snakeyaml-engine-2.7.jar=modules/ext/snakeyaml-engine-2.7.jar\nrelease.external/jackson-dataformat-yaml-2.17.1.jar=modules/ext/jackson-dataformat-yaml-2.17.1.jar\nrelease.external/snakeyaml-2.2.jar=modules/ext/snakeyaml-2.2.jar\nrelease.external/jackson-datatype-jsr310-2.17.1.jar=modules/ext/jackson-datatype-jsr310-2.17.1.jar\nrelease.external/zjsonpatch-0.3.0.jar=modules/ext/zjsonpatch-0.3.0.jar\nrelease.external/kubernetes-httpclient-okhttp-6.13.4.jar=modules/ext/kubernetes-httpclient-okhttp-6.13.4.jar\nrelease.external/okhttp-3.12.12.jar=modules/ext/okhttp-3.12.12.jar\nrelease.external/okio-1.15.0.jar=modules/ext/okio-1.15.0.jar\nrelease.external/logging-interceptor-3.12.12.jar=modules/ext/logging-interceptor-3.12.12.jar\nrelease.external/jackson-annotations-2.18.2.jar=modules/ext/jackson-annotations-2.18.2.jar\nrelease.external/jackson-core-2.18.2.jar=modules/ext/jackson-core-2.18.2.jar\nrelease.external/jackson-databind-2.18.2.jar=modules/ext/jackson-databind-2.18.2.jar\n\njavac.source=1.8\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "plugins/jolokia/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.jolokia</code-name-base>\n            <suite-component/>\n            <module-dependencies/>\n            <public-packages/>\n            <class-path-extension>\n                <runtime-relative-path>ext/jolokia-client-jmx-adapter-2.2.2.jar</runtime-relative-path>\n                <binary-origin>external/jolokia-client-jmx-adapter-2.2.2.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/jolokia-client-java-2.2.2.jar</runtime-relative-path>\n                <binary-origin>external/jolokia-client-java-2.2.2.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/jolokia-json-2.2.2.jar</runtime-relative-path>\n                <binary-origin>external/jolokia-json-2.2.2.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/jolokia-server-core-2.2.2.jar</runtime-relative-path>\n                <binary-origin>external/jolokia-server-core-2.2.2.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/jolokia-service-serializer-2.2.2.jar</runtime-relative-path>\n                <binary-origin>external/jolokia-service-serializer-2.2.2.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/httpclient-4.5.14.jar</runtime-relative-path>\n                <binary-origin>external/httpclient-4.5.14.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/httpcore-4.4.16.jar</runtime-relative-path>\n                <binary-origin>external/httpcore-4.4.16.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/commons-logging-1.3.4.jar</runtime-relative-path>\n                <binary-origin>external/commons-logging-1.3.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/commons-codec-1.17.1.jar</runtime-relative-path>\n                <binary-origin>external/commons-codec-1.17.1.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/jolokia-client-kubernetes-2.2.2.jar</runtime-relative-path>\n                <binary-origin>external/jolokia-client-kubernetes-2.2.2.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-client-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-client-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-client-api-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-client-api-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-core-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-core-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-common-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-common-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-gatewayapi-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-gatewayapi-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-resource-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-resource-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-rbac-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-rbac-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-admissionregistration-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-admissionregistration-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-apps-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-apps-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-autoscaling-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-autoscaling-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-apiextensions-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-apiextensions-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-batch-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-batch-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-certificates-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-certificates-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-coordination-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-coordination-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-discovery-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-discovery-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-events-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-events-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-extensions-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-extensions-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-flowcontrol-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-flowcontrol-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-networking-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-networking-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-metrics-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-metrics-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-policy-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-policy-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-scheduling-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-scheduling-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-storageclass-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-storageclass-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-model-node-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-model-node-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/slf4j-api-2.0.13.jar</runtime-relative-path>\n                <binary-origin>external/slf4j-api-2.0.13.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/snakeyaml-engine-2.7.jar</runtime-relative-path>\n                <binary-origin>external/snakeyaml-engine-2.7.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/jackson-dataformat-yaml-2.17.1.jar</runtime-relative-path>\n                <binary-origin>external/jackson-dataformat-yaml-2.17.1.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/snakeyaml-2.2.jar</runtime-relative-path>\n                <binary-origin>external/snakeyaml-2.2.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/jackson-datatype-jsr310-2.17.1.jar</runtime-relative-path>\n                <binary-origin>external/jackson-datatype-jsr310-2.17.1.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/zjsonpatch-0.3.0.jar</runtime-relative-path>\n                <binary-origin>external/zjsonpatch-0.3.0.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/kubernetes-httpclient-okhttp-6.13.4.jar</runtime-relative-path>\n                <binary-origin>external/kubernetes-httpclient-okhttp-6.13.4.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/okhttp-3.12.12.jar</runtime-relative-path>\n                <binary-origin>external/okhttp-3.12.12.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/okio-1.15.0.jar</runtime-relative-path>\n                <binary-origin>external/okio-1.15.0.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/logging-interceptor-3.12.12.jar</runtime-relative-path>\n                <binary-origin>external/logging-interceptor-3.12.12.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/jackson-annotations-2.18.2.jar</runtime-relative-path>\n                <binary-origin>external/jackson-annotations-2.18.2.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/jackson-core-2.18.2.jar</runtime-relative-path>\n                <binary-origin>external/jackson-core-2.18.2.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/jackson-databind-2.18.2.jar</runtime-relative-path>\n                <binary-origin>external/jackson-databind-2.18.2.jar</binary-origin>\n            </class-path-extension>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/jolokia/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/jolokia/src/org/graalvm/visualvm/modules/jolokia/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Libraries\nOpenIDE-Module-Long-Description=\\\n       Jolokia is a JMX-HTTP bridge giving an alternative to JSR-160 connectors. \\\n       It is an agent based approach with support for many platforms. In addition \\\n       to basic JMX operations it enhances JMX remoting with unique features like \\\n       bulk requests and fine grained security policies.\nOpenIDE-Module-Name=Jolokia\nOpenIDE-Module-Short-Description=Jolokia is remote JMX with JSON over HTTP\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"jsyntaxpane.lib\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project jsyntaxpane.lib.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/APACHE-LICENSE-2.0.txt",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/CHANGELOG.txt",
    "content": "Version 0.9.4 - IntelliSense additions\r\n    * Adding IntelliSense to Java with simple List of selectable keywords\r\n    * Added Toggle Comment Actions using Control SLASH\r\n    * Fixed Issue 47.\r\n    * Added Clojure, Scala, DOS Batch and 'nix bash support\r\nVersion 0.9.3 - Start of scripts for the document:\r\n    * Added new methods getLine() to SyntaxDocument\r\n    * SyntaxDocument getIndexOf methods deprecated, use getMatchers instead\r\n    * Added Line Numbering to Java\r\n    * Added CaretMonitor Class\r\n    * Merged Find And Replace dialogs into one.\r\n    * Created SyntaxComponent interface and have all UI components implement\r\n      that interface.  DefaultSyntaxKit will use config.properties class to\r\n      dynamically install these components.\r\n    * Added Right Margin option and Single Color Selection Options\r\n    * Added Python, C and C++ Support\r\n    * Added Ruby Syntax Support\r\n    * Fixed Issue 37 (NPE for LineNumbersRuler)\r\n    * Fixed Issue 39 (Highlighting Tokens overrides selection highlights)\r\n    * Fixed some JavaDoc comments.\r\n    * Fixed Line Numbers being displayed for the height of the editor and now\r\n      just for the actual available lines.\r\n    * Fixed Margin typo in all project. Issue 43\r\n    * Changing Actions to be more configurable:\r\n      * SyntaxActions renamed to ActionUtils\r\n      * Removed all inner classes from SyntaxActions\r\n      * Will create new SyntaxAction interface that will allow dynamic addition\r\n        actions (in the addKeyActions of DefaultSyntaxKit\r\n    * Added Text AA property to SyntaxView\r\nVersion 0.9.2:\r\n    * Fixing Java Indentation and Un-Indentattion Actions\r\n    * Added and used (in the Tester) clearUndoes on the SyntaxDocument\r\n    * Added Basic JFlex Syntax\r\n    * Added getContentTypes to DefaultSyntaxKit to get all registered\r\n      ContentTypes.  This is now also used in the SyntaxTester instead of\r\n      hardcoding the types.\r\n    * Cleanup and optimization of Lexers by removing duplicate Java Code\r\n      (replaced with Regex OR)\r\n    * Removed calls to deprecated calls in SyntaxView\r\n    * Modified the SyntaxDOcument to override the fireXXX methods and parse\r\n      the document at that time instead of overriding the inserUpdate method.\r\n      This fixes issue 24.\r\n    * Added Groovy GString expression highlights\r\n    * Removed getLanguages method from Lexer interface and implementations.\r\n    * Added WARNING and ERROR TokenTypes and added their default styles.\r\n    * Moved Keymaps and install methods to SyntaxKits instead of the Lexers\r\n    * Removed deprecated methods from SyntaxActions class\r\n    * Split SyntaxActions into new package and moved inner classes to the new\r\n      package\r\n    * Added Token HighLighter to Java\r\n    * Added Pairs Highlighter to Java\r\n    * Token class made immutable (all final fields)\r\n    * Added Find and Replace Dialogs and Action to Java (mapped to C-F and\r\n      C-H )\r\n    * Added pair matching to XML tags\r\n    * Added CDATA matching and pair highlights for XML\r\n    * Added Comment Pair Highlighting in XML\r\n    * Fixed highlighting with selections so the selection always appears\r\n    * Merged Find and Replace Dialogs into one\r\n    * Fixed issue 33 (undable to add new line after final closing brace for\r\n      Java)\r\n    * Added Groovy Multi-Line strings and fixed Comments as Regex issue.\r\n    * Fixes to empty find text field causing NPE\r\nVersion 0.9.1\r\n    * Fixed empty strings in XML syntax  Issue 29\r\n    * Fixed TAL lexer using incorrect package name\r\nVersion 0.9.0\r\n    * Initial version after major overhaul"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/nbactions.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<actions>\n        <action>\n            <actionName>run</actionName>\n            <packagings>\n                <packaging>jar</packaging>\n            </packagings>\n            <goals>\n                <goal>process-classes</goal>\n                <goal>org.codehaus.mojo:exec-maven-plugin:1.1:exec</goal>\n            </goals>\n            <properties>\n                <exec.args>-classpath %classpath jsyntaxpane.SyntaxTester</exec.args>\n                <exec.executable>java</exec.executable>\n            </properties>\n        </action>\n        <action>\n            <actionName>debug</actionName>\n            <packagings>\n                <packaging>jar</packaging>\n            </packagings>\n            <goals>\n                <goal>process-classes</goal>\n                <goal>org.codehaus.mojo:exec-maven-plugin:1.1:exec</goal>\n            </goals>\n            <properties>\n                <exec.args>-Xdebug -Djava.compiler=none -Xnoagent -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath jsyntaxpane.SyntaxTester</exec.args>\n                <jpda.listen>true</jpda.listen>\n                <exec.executable>java</exec.executable>\n            </properties>\n        </action>\n        <action>\n            <actionName>build</actionName>\n            <packagings>\n                <packaging>*</packaging>\n            </packagings>\n            <goals>\n                <goal>install</goal>\n            </goals>\n            <properties>\n                <maven.test.skip>true</maven.test.skip>\n            </properties>\n        </action>\n    </actions>\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <groupId>jsyntaxpane</groupId>\n  <artifactId>jsyntaxpane</artifactId>\n  <packaging>jar</packaging>\n  <version>0.9.4.1-visualvm</version>\n  <name>jsyntaxpane</name>\n  <description>A very simple to use and extend JEditorKit that supports few languages. The main goal is to make it easy to have nice looking Java Swing Editors with support for Syntax Highlighting.</description>\n  <url>http://jsyntaxpane.googlecode.com/</url>\n\n  <licenses>\n    <license>\n      <name>The Apache Software License, Version 2.0</name>\n      <url>http://www.apache.org/licenses/LICENSE-2.0</url>\n      <distribution>repo</distribution>\n    </license>\n  </licenses>\n\n  <scm>\n    <url>http://jsyntaxpane.googlecode.com/svn/</url>\n  </scm>\n\n  <pluginRepositories>\n    <pluginRepository>\n      <id>jflex</id>\n      <name>JFlex repository</name>\n      <url>https://jflex.sourceforge.net/repo/</url>\n    </pluginRepository>\n  </pluginRepositories>\n  \n  <build>\n    <plugins>\n      <plugin>\n        <artifactId>maven-compiler-plugin</artifactId>\n        <version>RELEASE</version>\n        <configuration>\n          <source>1.5</source>\n          <target>1.5</target>\n          <debug>false</debug>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-jar-plugin</artifactId>\n        <configuration>\n          <archive>\n            <manifest>\n              <mainClass>jsyntaxpane.SyntaxTester</mainClass>\n              <packageName>jsyntaxpane</packageName>\n              <addClasspath>true</addClasspath>\n              <classpathPrefix />\n            </manifest>\n            <manifestEntries>\n              <mode>development</mode>\n              <url>${pom.url}</url>\n            </manifestEntries>\n          </archive>\n        </configuration>\n      </plugin>\n\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-jar-plugin</artifactId>\n        <configuration>\n          <outputDirectory>../../release/modules/ext</outputDirectory>\n          <archive>\n            <manifest>\n              <mainClass>jsyntaxpane.SyntaxTester</mainClass>\n              <packageName>jsyntaxpane</packageName>\n              <addClasspath>true</addClasspath>\n              <classpathPrefix />\n            </manifest>\n            <manifestEntries>\n              <mode>development</mode>\n              <url>${pom.url}</url>\n            </manifestEntries>\n          </archive>\n        </configuration>\n      </plugin>\n\n      <plugin>\n        <groupId>de.jflex.maven.plugin</groupId>\n        <artifactId>maven-jflex-plugin</artifactId>\n        <!--version>0.2</version-->\n        <executions>\n          <execution>\n            <goals>\n              <goal>generate</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n    </plugins>\n  </build>\n\n</project>\n\n\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/CompoundUndoManager.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\n\npackage jsyntaxpane;\n\nimport javax.swing.undo.CannotRedoException;\nimport javax.swing.undo.CannotUndoException;\nimport javax.swing.undo.CompoundEdit;\nimport javax.swing.undo.UndoManager;\nimport javax.swing.undo.UndoableEdit;\n\n/**\n * A simple UndoManager that groups the Edits in each 0.5 second.  If the time \n * difference between the current undo and the last one is less than 0.5 secs,\n * then the two edits are compound.\n * @author Ayman Al-Sairafi\n */\npublic class CompoundUndoManager extends UndoManager {\n    \n    /**\n     * Delay between consequtive edits in ms where edits are added together.\n     * If the delay is greater than this, then separate undo operations are \n     * done, otherwise they are combined.\n     */\n    public static final int IDLE_DELAY_MS = 500;\n\n    long startMillis = 0;\n    CompoundEdit comp = null;\n\n    public CompoundUndoManager() {\n    }\n\n    @Override\n    public synchronized boolean addEdit(UndoableEdit anEdit) {\n        long now = System.currentTimeMillis();\n        if (comp == null) {\n            comp = new CompoundEdit();\n        }\n        comp.addEdit(anEdit);\n        if (now - startMillis > IDLE_DELAY_MS) {\n            comp.end();\n            super.addEdit(comp);\n            comp = null;\n        }\n        startMillis = now;\n        return true;\n    }\n\n    @Override\n    public synchronized boolean canRedo() {\n        commitCompound();\n        return super.canRedo();\n    }\n\n    @Override\n    public synchronized boolean canUndo() {\n        commitCompound();\n        return super.canUndo();\n    }\n\n    @Override\n    public synchronized void discardAllEdits() {\n        comp = null;\n        super.discardAllEdits();\n    }\n\n    @Override\n    public synchronized void redo() throws CannotRedoException {\n        commitCompound();\n        super.redo();\n    }\n\n    @Override\n    public synchronized void undo() throws CannotUndoException {\n        commitCompound();\n        super.undo();\n    }\n\n    private void commitCompound() {\n        if (comp != null) {\n            comp.end();\n            super.addEdit(comp);\n            comp = null;\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/DefaultLexer.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane;\n\n/**\n * This is a default, and abstract implemenatation of a Lexer with\n * some utility methods that Lexers can implement.\n *\n * @author Ayman Al-Sairafi\n */\npublic abstract class DefaultLexer implements Lexer {\n    \n    protected int tokenStart;\n    protected int tokenLength;\n\n    /**\n     * Helper method to create and return a new Token from of TokenType\n     * @param type\n     * @param tStart\n     * @param tLength\n     * @param newStart\n     * @param newLength\n     * @return\n     */\n    protected Token token(TokenType type, int tStart, int tLength,\n            int newStart, int newLength) {\n        tokenStart = newStart;\n        tokenLength = newLength;\n        return new Token(type, tStart, tLength);\n    }\n\n    /**\n     * Return the current matched token as a string.  This is <b>expensive</b>\n     * as it creates a new String object for the token.  Use with care.\n     *\n     * @return\n     */\n    protected CharSequence getTokenSrring() {\n        return yytext();\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/DefaultSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane;\n\nimport java.awt.Color;\nimport java.util.logging.Level;\nimport java.awt.Font;\nimport java.awt.GraphicsEnvironment;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.Set;\nimport java.util.logging.Logger;\nimport java.util.regex.Pattern;\nimport javax.swing.JEditorPane;\nimport javax.swing.KeyStroke;\nimport javax.swing.text.DefaultEditorKit;\nimport javax.swing.text.Document;\nimport javax.swing.text.Element;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.Keymap;\nimport javax.swing.text.TextAction;\nimport javax.swing.text.View;\nimport javax.swing.text.ViewFactory;\nimport jsyntaxpane.actions.SyntaxAction;\nimport jsyntaxpane.components.SyntaxComponent;\nimport jsyntaxpane.util.Configuration;\nimport jsyntaxpane.util.JarServiceProvider;\n\n/**\n * The DefaultSyntaxKit is the main entry to SyntaxPane.  To use the package, just \n * set the EditorKit of the EditorPane to a new instance of this class.\n * \n * You need to pass a proper lexer to the class.\n * \n * @author ayman\n */\npublic class DefaultSyntaxKit extends DefaultEditorKit implements ViewFactory {\n\n    public static Font DEFAULT_FONT;\n    private static Set<String> CONTENTS = new HashSet<String>();\n    private static boolean initialized = false;\n    private Lexer lexer;\n    private static final Logger LOG = Logger.getLogger(DefaultSyntaxKit.class.getName());\n    public static final Pattern COMMA_REGEX = Pattern.compile(\"\\\\w+,\\\\w+\");\n    private List<SyntaxComponent> editorComponents = new ArrayList<SyntaxComponent>();\n    private Map<String, SyntaxAction> editorActions = new HashMap<String, SyntaxAction>();\n    /**\n     * Main Configuration of JSyntaxPane\n     */\n    private static Configuration CONFIG;\n\n\n    static {\n        initKit();\n    }\n\n    /**\n     * Create a new Kit for the given language \n     * @param lexer \n     */\n    public DefaultSyntaxKit(Lexer lexer) {\n        super();\n        this.lexer = lexer;\n    }\n\n    @Override\n    public ViewFactory getViewFactory() {\n        return this;\n    }\n\n    @Override\n    public View create(Element element) {\n        return new SyntaxView(element, CONFIG, this.getClass().getSimpleName());\n    }\n\n    /**\n     * Install the View on the given EditorPane.  This is called by Swing and\n     * can be used to do anything you need on the JEditorPane control.  Here\n     * I set some default Actions.\n     * \n     * @param editorPane\n     */\n    @Override\n    public void install(JEditorPane editorPane) {\n        super.install(editorPane);\n        editorPane.setFont(DEFAULT_FONT);\n        Keymap km_parent = JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP);\n        Keymap km_new = JTextComponent.addKeymap(null, km_parent);\n        String kitName = this.getClass().getSimpleName();\n        Color caretColor = CONFIG.getPrefixColor(kitName, \"CaretColor\", Color.BLACK);\n        editorPane.setCaretColor(caretColor);\n        addSyntaxActions(km_new, \"\"); // shared actions\n        addSyntaxActions(km_new, kitName);\n        editorPane.setKeymap(km_new);\n        // install the components to the editor:\n        String[] components = CONFIG.getPrefixPropertyList(kitName, \"Components\");\n        for (String c : components) {\n            try {\n                @SuppressWarnings(\"unchecked\")\n                Class<SyntaxComponent> compClass = (Class<SyntaxComponent>) Class.forName(c);\n                SyntaxComponent comp = compClass.newInstance();\n                comp.config(CONFIG, kitName);\n                comp.install(editorPane);\n                editorComponents.add(comp);\n            } catch (InstantiationException ex) {\n                LOG.log(Level.SEVERE, null, ex);\n            } catch (IllegalAccessException ex) {\n                LOG.log(Level.SEVERE, null, ex);\n            } catch (ClassNotFoundException ex) {\n                LOG.log(Level.SEVERE, null, ex);\n            }\n        }\n    }\n\n    @Override\n    public void deinstall(JEditorPane editorPane) {\n        for (SyntaxComponent c : editorComponents) {\n            c.deinstall(editorPane);\n        }\n        editorComponents.clear();\n    }\n\n    /**\n     * Add keyboard actions to this control using the Configuration we have\n     * @param map\n     * @param prefix \n     */\n    public void addSyntaxActions(Keymap map, String prefix) {\n        // look at all keys that either start with prefix.Action, or\n        // that start with Action.\n\n        Pattern splitter = CONFIG.getValueSeparator(prefix);\n        Configuration actionsConf = CONFIG.subConfig(prefix, \"Action.\");\n\n        for (String actionName : actionsConf.stringPropertyNames()) {\n            String[] values = splitter.split(\n                    actionsConf.getProperty(actionName));\n            String actionClass = values[0];\n            SyntaxAction action = editorActions.get(actionClass);\n            if (action == null) {\n                action = createAction(actionClass);\n                action.config(CONFIG, prefix, actionName);\n            }\n            String keyStrokeString = values[1];\n            KeyStroke ks = KeyStroke.getKeyStroke(keyStrokeString);\n            // KeyEvent.VK_QUOTEDBL\n            if (ks == null) {\n                throw new IllegalArgumentException(\"Invalid KeyStroke: \" +\n                        keyStrokeString);\n            }\n            TextAction ta = action.getAction(actionName);\n            if(ta == null) {\n                throw new IllegalArgumentException(\"Invalid ActionName: \" +\n                        actionName);\n            }\n            map.addActionForKeyStroke(ks, ta);\n        }\n    }\n\n    private SyntaxAction createAction(String actionClassName) {\n        SyntaxAction action = null;\n        try {\n            Class clazz = JarServiceProvider.loadClass(actionClassName);\n            action = (SyntaxAction) clazz.newInstance();\n            editorActions.put(actionClassName, action);\n        } catch (InstantiationException ex) {\n            throw new IllegalArgumentException(\"Cannot create action class: \" +\n                    actionClassName, ex);\n        } catch (IllegalAccessException ex) {\n            throw new IllegalArgumentException(\"Cannot create action class: \" +\n                    actionClassName, ex);\n        } catch (ClassNotFoundException ex) {\n            throw new IllegalArgumentException(\"Cannot create action class: \" +\n                    actionClassName, ex);\n        } catch (ClassCastException ex) {\n            throw new IllegalArgumentException(\"Cannot create action class: \" +\n                    actionClassName, ex);\n        }\n        return action;\n    }\n\n    /**\n     * This is called by Swing to create a Document for the JEditorPane document\n     * This may be called before you actually get a reference to the control.\n     * We use it here to create a proper lexer and pass it to the \n     * SyntaxDcument we return.\n     * @return\n     */\n    @Override\n    public Document createDefaultDocument() {\n        return new SyntaxDocument(lexer);\n    }\n\n    /**\n     * This is called to initialize the list of <code>Lexer</code>s we have.\n     * You can call  this at initialization, or it will be called when needed.\n     * The method will also add the appropriate EditorKit classes to the\n     * corresponding ContentType of the JEditorPane.  After this is called,\n     * you can simply call the editor.setCOntentType(\"text/java\") on the \n     * control and you will be done.\n     */\n    public static void initKit() {\n        // attempt to find a suitable default font\n        CONFIG = new Configuration(JarServiceProvider.readProperties(\"jsyntaxpane.config\"));\n\n        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();\n        String[] fonts = ge.getAvailableFontFamilyNames();\n        Arrays.sort(fonts);\n        if (Arrays.binarySearch(fonts, \"Courier new\") >= 0) {\n            DEFAULT_FONT = new Font(\"Courier New\", Font.PLAIN, 12);\n        } else if (Arrays.binarySearch(fonts, \"Courier\") >= 0) {\n            DEFAULT_FONT = new Font(\"Courier\", Font.PLAIN, 12);\n        } else if (Arrays.binarySearch(fonts, \"Monospaced\") >= 0) {\n            DEFAULT_FONT = new Font(\"Monospaced\", Font.PLAIN, 13);\n        }\n\n        // read the Default Kits and their associated types\n        Properties kitsForTypes = JarServiceProvider.readProperties(\"jsyntaxpane.kitsfortypes\");\n        for (String type : kitsForTypes.stringPropertyNames()) {\n            String classname = kitsForTypes.getProperty(type);\n            registerContentType(type, classname);\n        }\n\n        initialized = true;\n    }\n\n    /**\n     * Register the given content type to use the given class name as its kit\n     * When this is called, an entry is added into the private HashMap of the\n     * registered editors kits.  This is needed so that the SyntaxPane library\n     * has it's own registration of all the EditorKits\n     * @param type\n     * @param classname\n     */\n    public static void registerContentType(String type, String classname) {\n        JEditorPane.registerEditorKitForContentType(type, classname);\n        CONTENTS.add(type);\n    }\n\n    /**\n     * Return all the content types supported by this library.  This will be the\n     * content types in the file WEB-INF/services/resources/jsyntaxpane.kitsfortypes\n     * @return sorted array of all registered content types\n     */\n    public static String[] getContentTypes() {\n        String[] types = CONTENTS.toArray(new String[0]);\n        Arrays.sort(types);\n        return types;\n    }\n\n    /**\n     * returns the current config\n     * @return\n     */\n    public static Configuration getConfig() {\n        if (!initialized) {\n            initKit();\n        }\n        return CONFIG;\n    }\n\n    /**\n     * Merges the given properties with the defaults, which are read from the\n     * Jar file\n     * @param config\n     */\n    public static void setConfig(Properties config) {\n        DefaultSyntaxKit.CONFIG.putAll(config);\n    }\n\n    /**\n     * Sets the given property to the given value.  If the kit is not\n     * initialized,  then calls initKit\n     * @param key\n     * @param value\n     */\n    public static void setProperty(String key, String value) {\n        if (!initialized) {\n            initKit();\n        }\n        CONFIG.put(key, value);\n    }\n\n    /**\n     * Return the property with the given key.  If the kit is not\n     * initialized,  then calls initKit\n     * Be careful when changing property as the default property may be used \n     * @param key\n     * @return value for given key\n     */\n    public static String getProperty(String key) {\n        if (!initialized) {\n            initKit();\n        }\n        return CONFIG.getProperty(key);\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/Lexer.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane;\n\nimport java.io.Reader;\n\n/**\n * Lexers must implement these methods.  These are used in the Tokenizer \n * \n * A Lexer should be tied to one document.\n * \n * @author Ayman Al-Sairafi\n */\npublic interface Lexer {\n\n    /**\n     * This will be called to reset the the lexer, generally whenever a\n     * document is changed\n     * @param reader\n     */\n    public void yyreset(Reader reader);\n\n    /**\n     * This is called to return the next Token from the Input Reader\n     * @return next token, or null if no more tokens.\n     * @throws java.io.IOException\n     */\n    public Token yylex() throws java.io.IOException;\n\n    /**\n     * Returns the character at position <tt>pos</tt> from the\n     * matched text.\n     *\n     * It is equivalent to yytext().charAt(pos), but faster\n     *\n     * @param pos the position of the character to fetch.\n     *            A value from 0 to yylength()-1.\n     *\n     * @return the character at position pos\n     */\n    public char yycharat(int pos);\n\n    /**\n     * Returns the length of the matched text region.\n     */\n    public int yylength();\n\n    /**\n     * Returns the text matched by the current regular expression.\n     */\n    public String yytext();\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxDocument.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane;\n\nimport java.io.CharArrayReader;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.ListIterator;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.UndoableEditEvent;\nimport javax.swing.event.UndoableEditListener;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.Element;\nimport javax.swing.text.PlainDocument;\nimport javax.swing.text.Segment;\nimport javax.swing.undo.UndoManager;\n\n/**\n * A document that supports being highlighted.  The document maintains an\n * internal List of all the Tokens.  The Tokens are updated using\n * a Lexer, passed to it during construction.\n * \n * @author Ayman Al-Sairafi\n */\npublic class SyntaxDocument extends PlainDocument {\n\n    Lexer lexer;\n    List<Token> tokens;\n    UndoManager undo = new CompoundUndoManager();\n\n    public SyntaxDocument(Lexer lexer) {\n        super();\n        putProperty(PlainDocument.tabSizeAttribute, 4);\n        this.lexer = lexer;\n        // Listen for undo and redo events\n        addUndoableEditListener(new UndoableEditListener() {\n\n            @Override\n            public void undoableEditHappened(UndoableEditEvent evt) {\n                if (evt.getEdit().isSignificant()) {\n                    undo.addEdit(evt.getEdit());\n                }\n            }\n        });\n    }\n\n    /**\n     * Parse the entire document and return list of tokens that do not already\n     * exist in the tokens list.  There may be overlaps, and replacements, \n     * which we will cleanup later.\n     * @return list of tokens that do not exist in the tokens field \n     */\n    private void parse() {\n        // if we have no lexer, then we must have no tokens...\n        if (lexer == null) {\n            tokens = null;\n            return;\n        }\n        List<Token> toks = new ArrayList<Token>(getLength() / 10);\n        long ts = System.nanoTime();\n        int len = getLength();\n        try {\n            Segment seg = new Segment();\n            getText(0, getLength(), seg);\n            CharArrayReader reader = new CharArrayReader(seg.array, seg.offset, seg.count);\n            lexer.yyreset(reader);\n            Token token;\n            while ((token = lexer.yylex()) != null) {\n                toks.add(token);\n            }\n        } catch (BadLocationException ex) {\n            log.log(Level.SEVERE, null, ex);\n        } catch (IOException ex) {\n            // This will not be thrown from the Lexer\n            log.log(Level.SEVERE, null, ex);\n        } finally {\n            if (log.isLoggable(Level.FINEST)) {\n                log.finest(String.format(\"Parsed %d in %d ms, giving %d tokens\\n\",\n                        len, (System.nanoTime() - ts) / 1000000, toks.size()));\n            }\n            tokens = toks;\n        }\n    }\n\n    @Override\n    protected void fireChangedUpdate(DocumentEvent e) {\n        parse();\n        super.fireChangedUpdate(e);\n    }\n\n    @Override\n    protected void fireInsertUpdate(DocumentEvent e) {\n        parse();\n        super.fireInsertUpdate(e);\n    }\n\n    @Override\n    protected void fireRemoveUpdate(DocumentEvent e) {\n        parse();\n        super.fireRemoveUpdate(e);\n    }\n\n    @Override\n    protected void fireUndoableEditUpdate(UndoableEditEvent e) {\n        parse();\n        super.fireUndoableEditUpdate(e);\n    }\n\n    /**\n     * Replace the token with the replacement string\n     * @param token\n     * @param replacement\n     */\n    public void replaceToken(Token token, String replacement) {\n        try {\n            replace(token.start, token.length, replacement, null);\n        } catch (BadLocationException ex) {\n            log.log(Level.WARNING, \"unable to replace token: \" + token, ex);\n        }\n    }\n\n    /**\n     * This class is used to iterate over tokens between two positions\n     * \n     */\n    class TokenIterator implements ListIterator<Token> {\n\n        int start;\n        int end;\n        int ndx = 0;\n\n        @SuppressWarnings(\"unchecked\")\n        private TokenIterator(int start, int end) {\n            this.start = start;\n            this.end = end;\n            if (tokens != null && !tokens.isEmpty()) {\n                Token token = new Token(TokenType.COMMENT, start, end - start);\n                ndx = Collections.binarySearch((List) tokens, token);\n                // we will probably not find the exact token...\n                if (ndx < 0) {\n                    // so, start from one before the token where we should be...\n                    // -1 to get the location, and another -1 to go back..\n                    ndx = (-ndx - 1 - 1 < 0) ? 0 : (-ndx - 1 - 1);\n                    Token t = tokens.get(ndx);\n                    // if the prev token does not overlap, then advance one\n                    if (t.end() <= start) {\n                        ndx++;\n                    }\n\n                }\n            }\n        }\n\n        @Override\n        public boolean hasNext() {\n            if (tokens == null) {\n                return false;\n            }\n            if (ndx >= tokens.size()) {\n                return false;\n            }\n            Token t = tokens.get(ndx);\n            if (t.start >= end) {\n                return false;\n            }\n            return true;\n        }\n\n        @Override\n        public Token next() {\n            return tokens.get(ndx++);\n        }\n\n        @Override\n        public void remove() {\n            throw new UnsupportedOperationException();\n        }\n\n        public boolean hasPrevious() {\n            if (tokens == null) {\n                return false;\n            }\n            if (ndx <= 0) {\n                return false;\n            }\n            Token t = tokens.get(ndx);\n            if (t.end() <= start) {\n                return false;\n            }\n            return true;\n        }\n\n        @Override\n        public Token previous() {\n            return tokens.get(ndx--);\n        }\n\n        @Override\n        public int nextIndex() {\n            return ndx + 1;\n        }\n\n        @Override\n        public int previousIndex() {\n            return ndx - 1;\n        }\n\n        @Override\n        public void set(Token e) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public void add(Token e) {\n            throw new UnsupportedOperationException();\n        }\n    }\n\n    /**\n     * Return an iterator of tokens between p0 and p1.\n     * @param start start position for getting tokens\n     * @param end position for last token\n     * @return Iterator for tokens that overal with range from start to end\n     */\n    public Iterator<Token> getTokens(int start, int end) {\n        return new TokenIterator(start, end);\n    }\n\n    /**\n     * Find the token at a given position.  May return null if no token is\n     * found (whitespace skipped) or if the position is out of range:\n     * @param pos\n     * @return\n     */\n    public Token getTokenAt(int pos) {\n        if (tokens == null || tokens.isEmpty() || pos > getLength()) {\n            return null;\n        }\n        Token tok = null;\n        Token tKey = new Token(TokenType.DEFAULT, pos, 1);\n        @SuppressWarnings(\"unchecked\")\n        int ndx = Collections.binarySearch((List) tokens, tKey);\n        if (ndx < 0) {\n            // so, start from one before the token where we should be...\n            // -1 to get the location, and another -1 to go back..\n            ndx = (-ndx - 1 - 1 < 0) ? 0 : (-ndx - 1 - 1);\n            Token t = tokens.get(ndx);\n            if ((t.start <= pos) && (pos <= t.end())) {\n                tok = t;\n            }\n        } else {\n            tok = tokens.get(ndx);\n        }\n        return tok;\n    }\n\n    /**\n     * This is used to return the other part of a paired token in the document.\n     * A paired part has token.pairValue <> 0, and the paired token will\n     * have the negative of t.pairValue.\n     * This method properly handles nestings of same pairValues, but overlaps\n     * are not checked.\n     * if The document does not contain a paired\n     * @param t\n     * @return the other pair's token, or null if nothing is found.\n     */\n    public Token getPairFor(Token t) {\n        if (t == null || t.pairValue == 0) {\n            return null;\n        }\n        Token p = null;\n        int ndx = tokens.indexOf(t);\n        // w will be similar to a stack. The openners weght is added to it\n        // and the closers are subtracted from it (closers are already negative)\n        int w = t.pairValue;\n        int direction = (t.pairValue > 0) ? 1 : -1;\n        boolean done = false;\n        int v = Math.abs(t.pairValue);\n        while (!done) {\n            ndx += direction;\n            if (ndx < 0 || ndx >= tokens.size()) {\n                break;\n            }\n            Token current = tokens.get(ndx);\n            if (Math.abs(current.pairValue) == v) {\n                w += current.pairValue;\n                if (w == 0) {\n                    p = current;\n                    done = true;\n                }\n            }\n        }\n\n        return p;\n    }\n\n    /**\n     * Perform an undo action, if possible\n     */\n    public void doUndo() {\n        if (undo.canUndo()) {\n            undo.undo();\n            parse();\n        }\n    }\n\n    /**\n     * Perform a redo action, if possible.\n     */\n    public void doRedo() {\n        if (undo.canRedo()) {\n            undo.redo();\n            parse();\n        }\n    }\n\n    /**\n     * Find the location of the given String in the document.  returns -1\n     * if the search string is not found starting at position <code>start</code>\n     * @param search The String to search for\n     * @param start The beginning index of search\n     * @return\n     * @deprecated use {@link getMatcher} instead\n     */\n    @Deprecated\n    public int getIndexOf(String search, int start) {\n        int flag = Pattern.LITERAL;\n        Pattern pattern = Pattern.compile(search, flag);\n        return getIndexOf(pattern, start);\n    }\n\n    /**\n     * Find the next position that matches <code>pattern</code> in the document.\n     * returns -1 if the pattern is not found.\n     * @param pattern the regex pattern to find\n     * @param start The beginning index of search\n     * @return\n     * @deprecated use {@link getMatcher} instead\n     */\n    @Deprecated\n    public int getIndexOf(Pattern pattern, int start) {\n        int ndx = -1;\n        if (pattern == null || getLength() == 0) {\n            return -1;\n        }\n        try {\n            Segment segment = new Segment();\n            getText(start, getLength() - start, segment);\n            Matcher m = pattern.matcher(segment);\n            if (m.find()) {\n                // remember that the index is relative to the document, so\n                // always add the start position to it\n                ndx = m.start() + start;\n            }\n        } catch (BadLocationException ex) {\n            log.log(Level.SEVERE, null, ex);\n        }\n        return ndx;\n    }\n\n    /**\n     * Return a matcher that matches the given pattern on the entire document\n     * @param pattern\n     * @return matcher object\n     */\n    public Matcher getMatcher(Pattern pattern) {\n        return getMatcher(pattern, 0, getLength());\n    }\n\n    /**\n     * Return a matcher that matches the given pattern in the part of the\n     * document starting at offset start.  Note that the matcher will have\n     * offset starting from <code>start</code>\n     *\n     * @param pattern\n     * @param start\n     * @return matcher that <b>MUST</b> be offset by start to get the proper\n     * location within the document\n     */\n    public Matcher getMatcher(Pattern pattern, int start) {\n        return getMatcher(pattern, start, getLength() - start);\n    }\n\n    /**\n     * Return a matcher that matches the given pattern in the part of the\n     * document starting at offset start and ending at start + length.\n     * Note that the matcher will have\n     * offset starting from <code>start</code>\n     *\n     * @param pattern\n     * @param start\n     * @param length\n     * @return matcher that <b>MUST</b> be offset by start to get the proper\n     * location within the document\n     */\n    public Matcher getMatcher(Pattern pattern, int start, int length) {\n        Matcher matcher = null;\n        if (getLength() == 0) {\n            return null;\n        }\n        try {\n            Segment seg = new Segment();\n            getText(start, length, seg);\n            matcher = pattern.matcher(seg);\n        } catch (BadLocationException ex) {\n            log.log(Level.SEVERE, \"Requested offset: \" + ex.offsetRequested(), ex);\n        }\n        return matcher;\n    }\n\n    /**\n     * This will discard all undoable edits\n     */\n    public void clearUndos() {\n        undo.discardAllEdits();\n    }\n\n    /**\n     * Gets the line at given position.  The line returned will NOT include\n     * the line terminator '\\n'\n     * @param pos Position (usually from text.getCaretPosition()\n     * @return the STring of text at given position\n     * @throws BadLocationException\n     */\n    public String getLineAt(int pos) throws BadLocationException {\n        Element e = getParagraphElement(pos);\n        Segment seg = new Segment();\n        getText(e.getStartOffset(), e.getEndOffset() - e.getStartOffset(), seg);\n        char last = seg.last();\n        if (last == '\\n' || last == '\\r') {\n            return seg.subSequence(0, seg.length() - 1).toString();\n        }\n        return seg.toString();\n    }\n\n    /**\n     * Deletes the line at given position\n     * @param pos\n     * @throws javax.swing.text.BadLocationException\n     */\n    public void removeLineAt(int pos)\n            throws BadLocationException {\n        Element e = getParagraphElement(pos);\n        remove(e.getStartOffset(), getElementLength(e));\n    }\n\n    /**\n     * Replace the line at given position with the given string, which can span\n     * multiple lines\n     * @param pos\n     * @param newLines\n     * @throws javax.swing.text.BadLocationException\n     */\n    public void replaceLineAt(int pos, String newLines)\n            throws BadLocationException {\n        Element e = getParagraphElement(pos);\n        replace(e.getStartOffset(), getElementLength(e), newLines, null);\n    }\n\n    /**\n     * Helper method to get the length of an element and avoid getting\n     * a too long element at the end of the document\n     * @param e\n     * @return\n     */\n    private int getElementLength(Element e) {\n        int end = e.getEndOffset();\n        if (end >= (getLength() - 1)) {\n            end--;\n        }\n        return end - e.getStartOffset();\n    }\n\n    /**\n     * Gets the text without the comments. For example for the string\n     * <code>{ // it's a comment</code> this method will return \"{ \".\n     * @param aStart start of the text.\n     * @param anEnd end of the text.\n     * @return String for the line without comments (if exists).\n     */\n    public synchronized String getUncommentedText(int aStart, int anEnd) {\n        readLock();\n        StringBuilder result = new StringBuilder();\n        Iterator<Token> iter = getTokens(aStart, anEnd);\n        while (iter.hasNext()) {\n            Token t = iter.next();\n            if (TokenType.COMMENT != t.type && TokenType.COMMENT2 != t.type) {\n                result.append(t.getText(this));\n            }\n        }\n        readUnlock();\n        return result.toString();\n    }\n\n    /**\n     * Returns the starting position of the line at pos\n     * @param pos\n     * @return starting position of the line\n     */\n    public int getLineStartOffset(int pos) {\n        return getParagraphElement(pos).getStartOffset();\n    }\n\n    /**\n     * Returns the end position of the line at pos.\n     * Does a bounds check to ensure the returned value does not exceed\n     * document length\n     * @param pos\n     * @return\n     */\n    public int getLineEndOffset(int pos) {\n        int end = 0;\n        end = getParagraphElement(pos).getEndOffset();\n        if (end >= getLength()) {\n            end = getLength();\n        }\n        return end;\n    }\n\n    /**\n     * Return the number of lines in this document\n     * @return\n     */\n    public int getLineCount() {\n        Element e = getDefaultRootElement();\n        int cnt = e.getElementCount();\n        return cnt;\n    }\n\n    /**\n     * Return the line number at given position.  The line numbers are zero based\n     * @param pos\n     * @return\n     */\n    public int getLineNumberAt(int pos) {\n        int lineNr = getDefaultRootElement().getElementIndex(pos);\n        return lineNr;\n    }\n\n    @Override\n    public String toString() {\n        return \"SyntaxDocument(\" + lexer + \", \" + ((tokens == null) ? 0 : tokens.size()) + \" tokens)@\" +\n                hashCode();\n    }\n\n// our logger instance...\n    private static final Logger log = Logger.getLogger(SyntaxDocument.class.getName());\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxStyle.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane;\n\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.awt.FontMetrics;\nimport java.awt.Graphics;\nimport javax.swing.text.Segment;\nimport javax.swing.text.TabExpander;\nimport javax.swing.text.Utilities;\n\npublic final class SyntaxStyle {\n\n    private Color color;\n    private int fontStyle;\n\n    public SyntaxStyle() {\n        super();\n    }\n\n    public SyntaxStyle(Color color, boolean bold, boolean italic) {\n        super();\n        this.color = color;\n        setBold(bold);\n        setItalic(italic);\n    }\n\n    public SyntaxStyle(Color color, int fontStyle) {\n        super();\n        this.color = color;\n        this.fontStyle = fontStyle;\n    }\n\n    SyntaxStyle(String str) {\n        String[] parts = str.split(\"\\\\s*,\\\\s*\");\n        if (parts.length != 2) {\n            throw new IllegalArgumentException(\"style not correct format: \" + str);\n        }\n        this.color = new Color(Integer.decode(parts[0]));\n        this.fontStyle = Integer.decode(parts[1]);\n    }\n\n    public boolean isBold() {\n        return (fontStyle & Font.BOLD) != 0;\n    }\n\n    public void setBold(Boolean bold) {\n        if (bold) {\n            fontStyle |= Font.BOLD;\n        } else {\n            int mask = -1 ^ Font.BOLD;\n            fontStyle = (fontStyle & (mask));\n        }\n    }\n\n    public String getColorString() {\n        return String.format(\"0x%06x\", color.getRGB() & 0x00ffffff);\n    }\n\n    public void setColorString(String color) {\n        this.color = Color.decode(color);\n    }\n\n    public Boolean isItalic() {\n        return (fontStyle & Font.ITALIC) != 0;\n    }\n\n    public void setItalic(Boolean italic) {\n        if (italic) {\n            fontStyle |= Font.ITALIC;\n        } else {\n            fontStyle = (fontStyle & (-1 ^ Font.ITALIC));\n        }\n    }\n\n    public int getFontStyle() {\n        return fontStyle;\n    }\n\n    public Color getColor() {\n        return color;\n    }\n\n    /**\n     * Draw text.  This can directly call the Utilities.drawTabbedText.\n     * Sub-classes can override this method to provide any other decorations.\n     * @param  segment - the source of the text\n     * @param  x - the X origin >= 0\n     * @param  y - the Y origin >= 0\n     * @param  graphics - the graphics context\n     * @param e - how to expand the tabs. If this value is null, tabs will be \n     * expanded as a space character.\n     * @param startOffset - starting offset of the text in the document >= 0 \n     * @return\n     */\n    public int drawText(Segment segment, int x, int y,\n            Graphics graphics, TabExpander e, int startOffset) {\n        graphics.setFont(graphics.getFont().deriveFont(getFontStyle()));\n        FontMetrics fontMetrics = graphics.getFontMetrics();\n        int a = fontMetrics.getAscent();\n        int h = a + fontMetrics.getDescent();\n        int w = Utilities.getTabbedTextWidth(segment, fontMetrics, 0, e, startOffset);\n        int rX = x - 1;\n        int rY = y - a;\n        int rW = w + 2;\n        int rH = h;\n        if ((getFontStyle() & 0x10) != 0) {\n            graphics.setColor(Color.decode(\"#EEEEEE\"));\n            graphics.fillRect(rX, rY, rW, rH);\n        }\n        graphics.setColor(getColor());\n        x = Utilities.drawTabbedText(segment, x, y, graphics, e, startOffset);\n        if ((getFontStyle() & 0x8) != 0) {\n            graphics.setColor(Color.RED);\n            graphics.drawRect(rX, rY, rW, rH);\n        }\n        return x;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxStyles.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane;\n\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.logging.Logger;\nimport javax.swing.text.Segment;\nimport javax.swing.text.TabExpander;\nimport jsyntaxpane.util.JarServiceProvider;\n\n/**\n * The STyles to use for each TokenType.  The defaults are created here, and\n * then the resource META-INF/services/syntaxstyles.properties is read and\n * merged.  You can also pass a properties instance and merge your prefered\n * styles into the default styles\n * \n * @author Ayman\n */\npublic class SyntaxStyles {\n\n    /**\n     * You can call the mergeStyles method with a Properties file to customize\n     * the existing styles.  Any existing styles will be overwritten by the\n     * styles you provide.\n     * @param styles\n     */\n    public void mergeStyles(Properties styles) {\n        for (String token : styles.stringPropertyNames()) {\n            String stv = styles.getProperty(token);\n            try {\n                TokenType tt = TokenType.valueOf(token);\n                SyntaxStyle tokenStyle = new SyntaxStyle(stv);\n                put(tt, tokenStyle);\n            } catch (IllegalArgumentException ex) {\n                LOG.warning(\"illegal token type or style for: \" + token);\n            }\n        }\n    }\n    Map<TokenType, SyntaxStyle> styles;\n    private static SyntaxStyles instance = createInstance();\n    private static final Logger LOG = Logger.getLogger(SyntaxStyles.class.getName());\n    \n    private static SyntaxStyle DEFAULT_STYLE = new SyntaxStyle(Color.BLACK, Font.PLAIN);\n\n    private SyntaxStyles() {\n    }\n\n    /**\n     * Create default styles\n     * @return\n     */\n    private static SyntaxStyles createInstance() {\n        SyntaxStyles syntaxstyles = new SyntaxStyles();\n        Properties styles = JarServiceProvider.readProperties(SyntaxStyles.class);\n        syntaxstyles.mergeStyles(styles);\n        return syntaxstyles;\n    }\n\n    public static SyntaxStyles getInstance() {\n        return instance;\n    }\n\n    public void put(TokenType type, SyntaxStyle style) {\n        if (styles == null) {\n            styles = new HashMap<TokenType, SyntaxStyle>();\n        }\n        styles.put(type, style);\n    }\n\n    /**\n     * Set the graphics font and others to the style for the given token\n     * @param g\n     * @param type\n     * @deprecated \n     */\n    @Deprecated\n    public void setGraphicsStyle(Graphics g, TokenType type) {\n        Font c = g.getFont();\n        SyntaxStyle ss = styles.get(type);\n        if (ss != null) {\n            g.setFont(g.getFont().deriveFont(ss.getFontStyle()));\n            g.setColor(ss.getColor());\n        } else {\n            g.setFont(g.getFont().deriveFont(Font.PLAIN));\n            g.setColor(Color.BLACK);\n        }\n    }\n\n    /**\n     * Return the style for the given TokenType\n     * @param type\n     * @return\n     */\n    public SyntaxStyle getStyle(TokenType type) {\n        if (styles.containsKey(type)) {\n            return styles.get(type);\n        } else {\n            return DEFAULT_STYLE;\n        }\n    }\n\n    /**\n     * Draw the given Token.  This will simply find the proper SyntaxStyle for\n     * the TokenType and then asks the proper Style to draw the text of the\n     * Token.\n     * @param segment\n     * @param x\n     * @param y\n     * @param graphics\n     * @param e\n     * @param token\n     * @return\n     */\n    public int drawText(Segment segment, int x, int y,\n            Graphics graphics, TabExpander e, Token token) {\n        SyntaxStyle s = getStyle(token.type);\n        return s.drawText(segment, x, y, graphics, e, token.start);\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxTester.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.5\" maxVersion=\"1.6\" type=\"org.netbeans.modules.form.forminfo.JFrameFormInfo\">\n  <Properties>\n    <Property name=\"defaultCloseOperation\" type=\"int\" value=\"3\"/>\n    <Property name=\"title\" type=\"java.lang.String\" value=\"JSyntaxPane Tester\"/>\n  </Properties>\n  <SyntheticProperties>\n    <SyntheticProperty name=\"formSizePolicy\" type=\"int\" value=\"1\"/>\n  </SyntheticProperties>\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"1\" attributes=\"0\">\n                  <Component id=\"lblToken\" alignment=\"0\" pref=\"612\" max=\"32767\" attributes=\"0\"/>\n                  <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n                      <Component id=\"jCmbLangs\" pref=\"231\" max=\"32767\" attributes=\"0\"/>\n                      <EmptySpace min=\"-2\" pref=\"262\" max=\"-2\" attributes=\"0\"/>\n                      <Component id=\"lblCaretPos\" min=\"-2\" pref=\"119\" max=\"-2\" attributes=\"0\"/>\n                  </Group>\n                  <Component id=\"jScrollPane1\" alignment=\"0\" pref=\"612\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jScrollPane1\" pref=\"395\" max=\"32767\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" pref=\"2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"lblToken\" min=\"-2\" pref=\"19\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace type=\"unrelated\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"jCmbLangs\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblCaretPos\" alignment=\"3\" pref=\"23\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"lblCaretPos\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" value=\"Caret Position\"/>\n      </Properties>\n    </Component>\n    <Container class=\"javax.swing.JScrollPane\" name=\"jScrollPane1\">\n      <AuxValues>\n        <AuxValue name=\"autoScrollPane\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n\n      <Layout class=\"org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout\"/>\n      <SubComponents>\n        <Component class=\"javax.swing.JEditorPane\" name=\"jEdtTest\">\n          <Properties>\n            <Property name=\"contentType\" type=\"java.lang.String\" value=\"\"/>\n            <Property name=\"font\" type=\"java.awt.Font\" editor=\"org.netbeans.beaninfo.editors.FontEditor\">\n              <Font name=\"Monospaced\" size=\"13\" style=\"0\"/>\n            </Property>\n          </Properties>\n          <Events>\n            <EventHandler event=\"caretUpdate\" listener=\"javax.swing.event.CaretListener\" parameters=\"javax.swing.event.CaretEvent\" handler=\"jEdtTestCaretUpdate\"/>\n          </Events>\n        </Component>\n      </SubComponents>\n    </Container>\n    <Component class=\"javax.swing.JLabel\" name=\"lblToken\">\n      <Properties>\n        <Property name=\"font\" type=\"java.awt.Font\" editor=\"org.netbeans.beaninfo.editors.FontEditor\">\n          <Font name=\"Courier New\" size=\"12\" style=\"0\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" value=\"Token under cursor\"/>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JComboBox\" name=\"jCmbLangs\">\n      <Properties>\n        <Property name=\"maximumRowCount\" type=\"int\" value=\"20\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"0\"/>\n        </Property>\n        <Property name=\"focusable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n      <Events>\n        <EventHandler event=\"itemStateChanged\" listener=\"java.awt.event.ItemListener\" parameters=\"java.awt.event.ItemEvent\" handler=\"jCmbLangsItemStateChanged\"/>\n      </Events>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxTester.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane;\n\nimport java.awt.event.ItemEvent;\nimport java.awt.Rectangle;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.text.BadLocationException;\nimport jsyntaxpane.actions.CaretMonitor;\n\npublic class SyntaxTester extends javax.swing.JFrame {\n\n    /** Creates new form Tester */\n    public SyntaxTester() {\n        DefaultSyntaxKit.initKit();\n        initComponents();\n        jCmbLangs.setModel(new DefaultComboBoxModel(DefaultSyntaxKit.getContentTypes()));\n        // jEdtTest.setContentType(jCmbLangs.getItemAt(0).toString());\n        jCmbLangs.setSelectedItem(\"text/java\");\n        new CaretMonitor(jEdtTest, lblCaretPos);\n    }\n\n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        lblCaretPos = new javax.swing.JLabel();\n        jScrollPane1 = new javax.swing.JScrollPane();\n        jEdtTest = new javax.swing.JEditorPane();\n        lblToken = new javax.swing.JLabel();\n        jCmbLangs = new javax.swing.JComboBox();\n\n        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);\n        setTitle(\"JSyntaxPane Tester\");\n\n        lblCaretPos.setText(\"Caret Position\");\n\n        jEdtTest.setContentType(\"\");\n        jEdtTest.setFont(new java.awt.Font(\"Monospaced\", 0, 13));\n        jEdtTest.addCaretListener(new javax.swing.event.CaretListener() {\n            public void caretUpdate(javax.swing.event.CaretEvent evt) {\n                jEdtTestCaretUpdate(evt);\n            }\n        });\n        jScrollPane1.setViewportView(jEdtTest);\n\n        lblToken.setFont(new java.awt.Font(\"Courier New\", 0, 12));\n        lblToken.setText(\"Token under cursor\");\n\n        jCmbLangs.setMaximumRowCount(20);\n        jCmbLangs.setFocusable(false);\n        jCmbLangs.addItemListener(new java.awt.event.ItemListener() {\n            public void itemStateChanged(java.awt.event.ItemEvent evt) {\n                jCmbLangsItemStateChanged(evt);\n            }\n        });\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());\n        getContentPane().setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)\n                    .addComponent(lblToken, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 612, Short.MAX_VALUE)\n                    .addGroup(layout.createSequentialGroup()\n                        .addComponent(jCmbLangs, 0, 231, Short.MAX_VALUE)\n                        .addGap(262, 262, 262)\n                        .addComponent(lblCaretPos, javax.swing.GroupLayout.PREFERRED_SIZE, 119, javax.swing.GroupLayout.PREFERRED_SIZE))\n                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 612, Short.MAX_VALUE))\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()\n                .addContainerGap()\n                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 395, Short.MAX_VALUE)\n                .addGap(2, 2, 2)\n                .addComponent(lblToken, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(jCmbLangs, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)\n                    .addComponent(lblCaretPos, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE))\n                .addContainerGap())\n        );\n\n        pack();\n    }// </editor-fold>//GEN-END:initComponents\n\nprivate void jEdtTestCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_jEdtTestCaretUpdate\n    if (jEdtTest.getDocument() instanceof SyntaxDocument) {\n        SyntaxDocument sDoc = (SyntaxDocument) jEdtTest.getDocument();\n        Token t = sDoc.getTokenAt(evt.getDot());\n        if (t != null) {\n            try {\n                String tData = sDoc.getText(t.start, Math.min(t.length, 40));\n                if (t.length > 40) {\n                    tData += \"...\";\n                }\n                lblToken.setText(t.toString() + \": \" + tData);\n            } catch (BadLocationException ex) {\n                // should not happen.. and if it does, just ignore it\n                System.err.println(ex);\n                ex.printStackTrace();\n            }\n        }\n    }\n\n}//GEN-LAST:event_jEdtTestCaretUpdate\n\nprivate void jCmbLangsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jCmbLangsItemStateChanged\n    if (evt.getStateChange() == ItemEvent.SELECTED) {\n        String lang = jCmbLangs.getSelectedItem().toString();\n\n        // save the state of the current JEditorPane, as it's Document is about\n        // to be replaced.\n        String t = jEdtTest.getText();\n        int caretPosition = jEdtTest.getCaretPosition();\n        Rectangle visibleRectangle = jEdtTest.getVisibleRect();\n\n        // install a new DefaultSyntaxKit on the JEditorPane for the requested language.\n        jEdtTest.setContentType(lang);\n\n        // restore the state of the JEditorPane - note that installing a new\n        // EditorKit causes the Document to be recreated.\n        SyntaxDocument sDoc = (SyntaxDocument) jEdtTest.getDocument();\n        jEdtTest.setText(t);\n        sDoc.clearUndos();\n        jEdtTest.setCaretPosition(caretPosition);\n        jEdtTest.scrollRectToVisible(visibleRectangle);\n    }\n}//GEN-LAST:event_jCmbLangsItemStateChanged\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String args[]) {\n        java.awt.EventQueue.invokeLater(new Runnable() {\n\n            @Override\n            public void run() {\n                new SyntaxTester().setVisible(true);\n            }\n        });\n    }\n\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JComboBox jCmbLangs;\n    private javax.swing.JEditorPane jEdtTest;\n    private javax.swing.JScrollPane jScrollPane1;\n    private javax.swing.JLabel lblCaretPos;\n    private javax.swing.JLabel lblToken;\n    // End of variables declaration//GEN-END:variables\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxView.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane;\n\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.RenderingHints;\nimport java.awt.Shape;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.Element;\nimport javax.swing.text.PlainView;\nimport javax.swing.text.Segment;\nimport javax.swing.text.ViewFactory;\nimport jsyntaxpane.util.Configuration;\n\npublic class SyntaxView extends PlainView {\n\n    public static final String PROPERTY_RIGHT_MARGIN_COLOR = \"RightMarginColor\";\n    public static final String PROPERTY_RIGHT_MARGIN_COLUMN = \"RightMarginColumn\";\n    public static final String PROPERTY_SINGLE_COLOR_SELECT = \"SingleColorSelect\";\n    public static final String PROPERTY_TEXTAA = \"TextAA\";\n    \n    private static final Logger log = Logger.getLogger(SyntaxView.class.getName());\n    private SyntaxStyle DEFAULT_STYLE = SyntaxStyles.getInstance().getStyle(TokenType.DEFAULT);\n    private final boolean singleColorSelect;\n    private final int rightMarginColumn;\n    private final Color rightMarginColor;\n    private final Object textAAHint;\n\n    /**\n     * Construct a new view using the given configuration and prefix given\n     * \n     * @param element\n     * @param config\n     * @param prefix\n     */\n    public SyntaxView(Element element, Configuration config, String prefix) {\n        super(element);\n        singleColorSelect = config.getPrefixBoolean(prefix, PROPERTY_SINGLE_COLOR_SELECT, false);\n        rightMarginColor = new Color(config.getPrefixInteger(prefix, PROPERTY_RIGHT_MARGIN_COLOR,\n                0xFF7777));\n        rightMarginColumn = config.getPrefixInteger(prefix, PROPERTY_RIGHT_MARGIN_COLUMN,\n                0);\n        String textaa = config.getPrefixProperty(prefix, PROPERTY_TEXTAA,\n                \"DEFAULT\");\n        textAAHint = TEXT_AA_HINT_NAMES.get(textaa);\n    }\n\n    @Override\n    protected int drawUnselectedText(Graphics graphics, int x, int y, int p0,\n            int p1) {\n        Graphics2D graphics2D = (Graphics2D) graphics;\n        graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,\n                textAAHint);\n        Font saveFont = graphics.getFont();\n        Color saveColor = graphics.getColor();\n        SyntaxDocument doc = (SyntaxDocument) getDocument();\n        Segment segment = getLineBuffer();\n        // Draw the right margin first, if needed.  This way the text overalys\n        // the margin\n        if (rightMarginColumn > 0) {\n            int m_x = rightMarginColumn * graphics.getFontMetrics().charWidth('m');\n            int h = graphics.getFontMetrics().getHeight();\n            graphics.setColor(rightMarginColor);\n            graphics.drawLine(m_x, y, m_x, y - h);\n        }\n        try {\n            // Colour the parts\n            Iterator<Token> i = doc.getTokens(p0, p1);\n            int start = p0;\n            while (i.hasNext()) {\n                Token t = i.next();\n                // if there is a gap between the next token start and where we\n                // should be starting (spaces not returned in tokens), then draw\n                // it in the default type\n                if (start < t.start) {\n                    doc.getText(start, t.start - start, segment);\n                    x = DEFAULT_STYLE.drawText(segment, x, y, graphics, this, start);\n                }\n                // t and s are the actual start and length of what we should\n                // put on the screen.  assume these are the whole token....\n                int l = t.length;\n                int s = t.start;\n                // ... unless the token starts before p0:\n                if (s < p0) {\n                    // token is before what is requested. adgust the length and s\n                    l -= (p0 - s);\n                    s = p0;\n                }\n                // if token end (s + l is still the token end pos) is greater \n                // than p1, then just put up to p1\n                if (s + l > p1) {\n                    l = p1 - s;\n                }\n                doc.getText(s, l, segment);\n                x = SyntaxStyles.getInstance().drawText(segment, x, y, graphics, this, t);\n                start = t.end();\n            }\n            // now for any remaining text not tokenized:\n            if (start < p1) {\n                doc.getText(start, p1 - start, segment);\n                x = DEFAULT_STYLE.drawText(segment, x, y, graphics, this, start);\n            }\n        } catch (BadLocationException ex) {\n            System.err.println(\"Requested: \" + ex.offsetRequested());\n            log.log(Level.SEVERE, null, ex);\n        } finally {\n            graphics.setFont(saveFont);\n            graphics.setColor(saveColor);\n        }\n        return x;\n    }\n\n    @Override\n    protected int drawSelectedText(Graphics graphics, int x, int y, int p0, int p1)\n            throws BadLocationException {\n        if (singleColorSelect) {\n            if (rightMarginColumn > 0) {\n                int m_x = rightMarginColumn * graphics.getFontMetrics().charWidth('m');\n                int h = graphics.getFontMetrics().getHeight();\n                graphics.setColor(rightMarginColor);\n                graphics.drawLine(m_x, y, m_x, y - h);\n            }\n            return super.drawUnselectedText(graphics, x, y, p0, p1);\n        } else {\n            return drawUnselectedText(graphics, x, y, p0, p1);\n        }\n    }\n\n    @Override\n    protected void updateDamage(javax.swing.event.DocumentEvent changes,\n            Shape a,\n            ViewFactory f) {\n        super.updateDamage(changes, a, f);\n        java.awt.Component host = getContainer();\n        host.repaint();\n    }\n\n    /**\n     * The values for the string key for Text Anti-Aliasing\n     */\n    private static Map<String, Object> TEXT_AA_HINT_NAMES =\n            new HashMap<String, Object>();\n\n    static {\n        TEXT_AA_HINT_NAMES.put(\"DEFAULT\", RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);\n        TEXT_AA_HINT_NAMES.put(\"GASP\", RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);\n        TEXT_AA_HINT_NAMES.put(\"HBGR\", RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR);\n        TEXT_AA_HINT_NAMES.put(\"HRGB\", RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);\n        TEXT_AA_HINT_NAMES.put(\"VBGR\", RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR);\n        TEXT_AA_HINT_NAMES.put(\"VRGB\", RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR);\n        TEXT_AA_HINT_NAMES.put(\"OFF\", RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);\n        TEXT_AA_HINT_NAMES.put(\"ON\", RenderingHints.VALUE_TEXT_ANTIALIAS_ON);\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/Token.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane;\n\nimport java.io.Serializable;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.Document;\n\npublic class Token implements Serializable, Comparable {\n\n    public final TokenType type;\n    public final int start;\n    public final int length;\n    /**\n     * the pair value to use if this token is one of a pair:\n     * This is how it is used:\n     * The openning part will have a positive number X\n     * The closing part will have a negative number X\n     * X should be unique for a pair:\n     *   e.g. for [ pairValue = +1\n     *        for ] pairValue = -1\n     */\n    public final byte pairValue;\n\n    /**\n     * Constructs a new token\n     * @param type\n     * @param start\n     * @param length\n     */\n    public Token(TokenType type, int start, int length) {\n        this.type = type;\n        this.start = start;\n        this.length = length;\n        this.pairValue = 0;\n    }\n\n    /**\n     * Construct a new part of pair token\n     * @param type\n     * @param start\n     * @param length\n     * @param pairValue\n     */\n    public Token(TokenType type, int start, int length, byte pairValue) {\n        this.type = type;\n        this.start = start;\n        this.length = length;\n        this.pairValue = pairValue;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj instanceof Object) {\n            Token token = (Token) obj;\n            return ((this.start == token.start) &&\n                    (this.length == token.length) &&\n                    (this.type.equals(token.type)));\n        } else {\n            return false;\n        }\n    }\n\n    @Override\n    public int hashCode() {\n        return start;\n    }\n\n    @Override\n    public String toString() {\n        return String.format(\"%s (%d, %d) (%d)\", type, start, length, pairValue);\n    }\n\n    @Override\n    public int compareTo(Object o) {\n        Token t = (Token) o;\n        if (this.start !=  t.start) {\n            return (this.start - t.start);\n        } else if(this.length != t.length) {\n            return (this.length - t.length);\n        } else {\n            return this.type.compareTo(t.type);\n        }\n    }\n\n    /**\n     * return the end position of the token.\n     * @return start + length\n     */\n    public int end() {\n        return start + length;\n    }\n    \n    /**\n     * Get the text of the token from this document\n     * @param doc\n     * @return\n     */\n    public String getText(Document doc) {\n        String text = null;\n        try {\n            text = doc.getText(start, length);\n        } catch (BadLocationException ex) {\n            Logger.getLogger(Token.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        return text;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/TokenType.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane;\n\n/**\n * These are the various token types supported by JSyntaxPane.\n * \n * @author ayman\n */\npublic enum TokenType {\n\n    OPERATOR,   // Language operators\n    KEYWORD,    // language reserved keywords\n    KEYWORD2,   // Other language reserved keywords, like C #defines\n    IDENTIFIER, // identifiers, variable names, class names\n    NUMBER,     // numbers in various formats\n    STRING,     // String\n    STRING2,    // For highlighting meta chars within a String\n    COMMENT,    // comments\n    COMMENT2,   // special stuff within comments\n    REGEX,      // regular expressions\n    REGEX2,     // special chars within regular expressions\n    TYPE,       // Types, usually not keywords, but supported by the language\n    TYPE2,      // Types from standard libraries\n    TYPE3,      // Types for users\n    DEFAULT,    // any other text\n    WARNING,    // Text that should be highlighted as a warning\n    ERROR       // Text that signals an error \n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ActionUtils.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.actions;\n\nimport java.awt.Component;\nimport java.awt.Frame;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.Window;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.JComboBox;\nimport javax.swing.MutableComboBoxModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.Document;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.PlainDocument;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.Token;\n\n/**\n * Various utility methods to work on JEditorPane and its SyntaxDocument\n * for use by Actions\n *\n * @author Ayman Al-Sairafi\n */\npublic class ActionUtils {\n\n    /**\n     * Perform Smart Indentation:  pos must be on a line: this method will\n     * use the previous lines indentation (number of spaces before any non-space\n     * character or end of line) and return that as the prefix\n     * @param line the line of text\n     * @return\n     */\n    public static String getIndent(String line) {\n        if (line == null || line.length() == 0) {\n            return \"\";\n        }\n        int i = 0;\n        while (i < line.length() && line.charAt(i) == ' ') {\n            i++;\n        }\n        return line.substring(0, i);\n    }\n\n    /**\n     * Return the lines that span the selection (split as an array of Strings)\n     * if there is no selection then current line is returned.\n     * \n     * Note that the strings returned will not contain the terminating line feeds\n     * \n     * The text component will then have the full lines set as selection\n     * @param target\n     * @return String[] of lines spanning selection / or Dot\n     */\n    public static String[] getSelectedLines(JTextComponent target) {\n        String[] lines = null;\n        try {\n            PlainDocument pDoc = (PlainDocument) target.getDocument();\n            int start = pDoc.getParagraphElement(target.getSelectionStart()).getStartOffset();\n            int end;\n            if (target.getSelectionStart() == target.getSelectionEnd()) {\n                end = pDoc.getParagraphElement(target.getSelectionEnd()).getEndOffset();\n            } else {\n                // if more than one line is selected, we need to subtract one from the end\n                // so that we do not select the line with the caret and no selection in it\n                end = pDoc.getParagraphElement(target.getSelectionEnd() - 1).getEndOffset();\n            }\n            target.select(start, end);\n            lines = pDoc.getText(start, end - start).split(\"\\n\");\n            target.select(start, end);\n        } catch (BadLocationException ex) {\n            Logger.getLogger(ActionUtils.class.getName()).log(Level.SEVERE, null, ex);\n            lines = EMPTY_STRING_ARRAY;\n        }\n        return lines;\n    }\n\n    /**\n     * Return the line of text at the TextComponent's current position\n     * @param target\n     * @return\n     */\n    public static String getLine(JTextComponent target) {\n        return getLineAt(target, target.getCaretPosition());\n    }\n\n    /**\n     * Return the line of text at the given position.  The returned value may\n     * be null.  It will not contain the trailing new-line character.\n     * @param target the text component\n     * @param pos char position\n     * @return\n     */\n    public static String getLineAt(JTextComponent target, int pos) {\n        String line = null;\n        Document doc = target.getDocument();\n        if (doc instanceof PlainDocument) {\n            PlainDocument pDoc = (PlainDocument) doc;\n            int start = pDoc.getParagraphElement(pos).getStartOffset();\n            int end = pDoc.getParagraphElement(pos).getEndOffset();\n            try {\n                line = doc.getText(start, end - start);\n                if (line != null && line.endsWith(\"\\n\")) {\n                    line = line.substring(0, line.length() - 1);\n                }\n            } catch (BadLocationException ex) {\n                Logger.getLogger(ActionUtils.class.getName()).log(Level.SEVERE, null, ex);\n            }\n        }\n        return line;\n    }\n\n    /**\n     * Returns the Frame that contains this component or null if the component\n     * is not within a Window or the containing window is not a frame\n     * @param comp\n     * @return\n     */\n    public static Frame getFrameFor(Component comp) {\n        Window w = SwingUtilities.getWindowAncestor(comp);\n        if (w != null && w instanceof Frame) {\n            Frame frame = (Frame) w;\n            return frame;\n        }\n        return null;\n    }\n\n    /**\n     * Returns the the Token at pos as a String\n     * @param doc\n     * @param pos\n     * @return\n     */\n    public static String getTokenStringAt(\n            SyntaxDocument doc, int pos) {\n        String word = \"\";\n        Token t = doc.getTokenAt(pos);\n        if (t != null) {\n            try {\n                word = doc.getText(t.start, t.length);\n            } catch (BadLocationException ex) {\n                Logger.getLogger(ActionUtils.class.getName()).log(Level.SEVERE, null, ex);\n            }\n        }\n        return word;\n    }\n\n    /**\n     * A helper function that will return the SyntaxDocument attached to the\n     * given text component.  Return null if the document is not a \n     * SyntaxDocument, or if the text component is null\n     * @param component\n     * @return\n     */\n    public static SyntaxDocument getSyntaxDocument(JTextComponent component) {\n        if (component == null) {\n            return null;\n        }\n        Document doc = component.getDocument();\n        if (doc instanceof SyntaxDocument) {\n            return (SyntaxDocument) doc;\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * Gets the Line Number at the give position of the editor component.\n     * The first line number is ZERO\n     * @param editor\n     * @param pos\n     * @return line number\n     * @throws javax.swing.text.BadLocationException\n     */\n    public static int getLineNumber(JTextComponent editor, int pos)\n            throws BadLocationException {\n        if (getSyntaxDocument(editor) != null) {\n            SyntaxDocument sdoc = getSyntaxDocument(editor);\n            return sdoc.getLineNumberAt(pos);\n        } else {\n            Document doc = editor.getDocument();\n            return doc.getDefaultRootElement().getElementIndex(pos);\n        }\n    }\n\n    /**\n     * Gets the column number at given position of editor.  The first column is\n     * ZERO\n     * @param editor\n     * @param pos\n     * @return the 0 based column number\n     * @throws javax.swing.text.BadLocationException\n     */\n    public static int getColumnNumber(JTextComponent editor, int pos)\n            throws BadLocationException {\n        Rectangle r = editor.modelToView(pos);\n        int start = editor.viewToModel(new Point(0, r.y));\n        int column = pos - start;\n        return column;\n    }\n\n    /**\n     * Get the closest position within the document of the component that\n     * has given line and column.  \n     * @param editor\n     * @param line\n     * @param column\n     * @return the closest positon for the text component at given line and\n     * column\n     */\n    public static int getDocumentPosition(JTextComponent editor, int line,\n            int column) {\n        int lineHeight = editor.getFontMetrics(editor.getFont()).getHeight();\n        int charWidth = editor.getFontMetrics(editor.getFont()).charWidth('m');\n        int y = line * lineHeight;\n        int x = column * charWidth;\n        Point pt = new Point(x, y);\n        int pos = editor.viewToModel(pt);\n        return pos;\n    }\n\n    public static int getLineCount(JTextComponent pane) {\n        SyntaxDocument sdoc = getSyntaxDocument(pane);\n        if (sdoc != null) {\n            return sdoc.getLineCount();\n        }\n        int count = 0;\n        try {\n            int p = pane.getDocument().getLength() - 1;\n            if (p > 0) {\n                count = getLineNumber(pane, p);\n            }\n        } catch (BadLocationException ex) {\n            Logger.getLogger(ActionUtils.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        return count;\n    }\n\n    /**\n     * Insert the given item into the combo box, and set it as first selected\n     * item.  If the item already exists, it is removed, so there are no\n     * duplicates.\n     * @param combo\n     * @param item\n     */\n    public static void insertIntoCombo(JComboBox combo, Object item) {\n        MutableComboBoxModel model = (MutableComboBoxModel) combo.getModel();\n        if (model.getSize() == 0) {\n            model.insertElementAt(item, 0);\n            return;\n        }\n\n        Object o = model.getElementAt(0);\n        if (o.equals(item)) {\n            return;\n        }\n        model.removeElement(item);\n        model.insertElementAt(item, 0);\n        combo.setSelectedIndex(0);\n    }\n\n    /**\n     * Repeat the string source repeat times.\n     * If repeats == 0 then empty String is returned\n     * if source is null, then empty string is returned\n     * @param source\n     * @param repeat\n     * @return source String repeated repeat times.\n     */\n    public static String repeatString(String source, int repeat) {\n        if (repeat < 0) {\n            throw new IllegalArgumentException(\"Cannot repeat \" + repeat + \" times.\");\n        }\n        if (repeat == 0 || source == null || source.length() == 0) {\n            return \"\";\n        }\n        StringBuffer buffer = new StringBuffer();\n        for (int i = 0; i < repeat; i++) {\n            buffer.append(source);\n        }\n        return buffer.toString();\n    }\n\n    /**\n     * Checks if the given string is null, empty or contains whitespace only\n     * @param string\n     * @return true if string is null, empty or contains whitespace only, false\n     * otherwise.\n     */\n    public static boolean isEmptyOrBlanks(String string) {\n        if (string == null || string.length() == 0) {\n            return true;\n        }\n        for (int i = 0; i < string.length(); i++) {\n            char c = string.charAt(i);\n            if (!Character.isWhitespace(c)) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * Return the TabStop property for the given text component, or 0 if not\n     * used\n     * @param text\n     * @return\n     */\n    public static int getTabSize(JTextComponent text) {\n        Integer tabs = (Integer) text.getDocument().getProperty(PlainDocument.tabSizeAttribute);\n        return (null == tabs) ? 0 : tabs.intValue();\n    }\n\n    /**\n     * Insert the given String into the textcomponent.  If the string contains\n     * the | vertical BAr char, then it will not be inserted, and the cursor will\n     * be set to its location.\n     * If there are TWO vertical bars, then the text between them will be selected\n     * <b>FIXME: add following feature\n     * If the String is multi-line, then it will be indented with the same\n     * indentattion as the line with pos.</b>\n     * @param target\n     * @param dot\n     * @param toInsert\n     * @throws javax.swing.text.BadLocationException\n     */\n    public static void insertMagicString(JTextComponent target, int dot, String toInsert)\n            throws BadLocationException {\n        Document doc = target.getDocument();\n        if (toInsert.indexOf('|') >= 0) {\n            int ofst = toInsert.indexOf('|');\n            int ofst2 = toInsert.indexOf('|', ofst + 1);\n            toInsert = toInsert.replace(\"|\", \"\");\n            doc.insertString(dot, toInsert, null);\n            dot = target.getCaretPosition();\n            final int strLength = toInsert.length();\n            if (ofst2 > 0) {\n                // note that we already removed the first |, so end offset is now\n                // one less than what it was.\n                target.select(dot + ofst - strLength, dot + ofst2 - strLength - 1);\n            } else {\n                target.setCaretPosition(dot + ofst -strLength);\n            }\n        } else {\n            doc.insertString(dot, toInsert, null);\n        }\n    }\n    // This is used internally to avoid NPE if we have no Strings\n    static String[] EMPTY_STRING_ARRAY = new String[0];\n    // This is used to quickly create Strings of at most 16 spaces (using substring)\n    static String SPACES = \"                \";\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/CaretMonitor.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.actions;\n\nimport javax.swing.JLabel;\nimport javax.swing.event.CaretEvent;\nimport javax.swing.event.CaretListener;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.JTextComponent;\nimport jsyntaxpane.SyntaxDocument;\n\n/**\n * This class can be used to display the caret location in friendly manner for\n * an EditorPane.\n *\n * FIXME: Add configurable position text using String.format and arrays of locations\n *\n * @author Ayman Al-Sairafi\n */\npublic class CaretMonitor implements CaretListener {\n\n    private JLabel label;\n    private JTextComponent text;\n\n    public CaretMonitor(JTextComponent text, JLabel label) {\n        this.label = label;\n        this.text = text;\n        text.addCaretListener(this);\n    }\n\n    public void caretUpdate(CaretEvent evt) {\n        if (text.getDocument() instanceof SyntaxDocument) {\n            try {\n                if (text.getSelectionStart() == text.getSelectionEnd()) {\n                    int pos = evt.getDot();\n                    String loc = String.format(\"%d:%d (%d)\",\n                            ActionUtils.getLineNumber(text, pos) + 1,\n                            ActionUtils.getColumnNumber(text, pos) + 1,\n                            pos);\n                    label.setText(loc);\n                } else {\n                    int start = text.getSelectionStart();\n                    int end = text.getSelectionEnd();\n                    String loc = String.format(\"%d:%d - %d:%d (%d)\",\n                            ActionUtils.getLineNumber(text, start) + 1,\n                            ActionUtils.getColumnNumber(text, start) + 1,\n                            ActionUtils.getLineNumber(text, end) + 1,\n                            ActionUtils.getColumnNumber(text, end) + 1,\n                            (end - start));\n                    label.setText(loc);\n                }\n            } catch (BadLocationException ex) {\n                label.setText(\"Ex: \" + ex.getMessage());\n            }\n        } else {\n            label.setText(\"Position\");\n        }\n    }\n\n    @Override\n    protected void finalize() throws Throwable {\n        text.removeCaretListener(this);\n        super.finalize();\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ComboCompletionAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.actions;\n\nimport java.awt.Frame;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.SwingUtilities;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.Token;\nimport jsyntaxpane.util.Configuration;\nimport jsyntaxpane.util.JarServiceProvider;\n\n/**\n * ComboBox like Completion Action:\n * This will display a list of items to choose from, its can be used similar to\n * IntelliSense\n *\n * @author Ayman Al-Sairafi\n */\npublic class ComboCompletionAction extends TextAction implements SyntaxAction {\n    final private static Set<String> CLOSING = new HashSet<String>() {\n        {\n            add(\")\");\n            add(\"}\");\n            add(\"[\");\n        }\n    };\n    final private static String MEMBER_SEPARATOR = \".\";\n\n    Map<String, String> completions;\n    ComboCompletionDialog dlg;\n    private String[] items;\n\n    public ComboCompletionAction() {\n        super(\"COMBO_COMPLETION\");\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        if (target != null && target.getDocument() instanceof SyntaxDocument) {\n            SyntaxDocument sDoc = (SyntaxDocument) target.getDocument();\n            int dot = target.getCaretPosition();\n            Token token = sDoc.getTokenAt(dot);\n            String abbrev = \"\";\n            try {\n                if (token != null) {\n                    abbrev = token.getText(sDoc);\n                    while (CLOSING.contains(abbrev)) {\n                        token = sDoc.getTokenAt(token.start - 1);\n                        abbrev = token.getText(sDoc);\n                    }\n                    if (MEMBER_SEPARATOR.equals(abbrev)) {\n                        abbrev = \"[\" + ActionUtils.getTokenStringAt(sDoc, token.start - 1) + \"]\" + abbrev;\n                    } else {\n                        Token prev = sDoc.getTokenAt(token.start - 1);\n                        if (prev != null && MEMBER_SEPARATOR.equals(prev.getText(sDoc))) {\n                            abbrev = \"[\" + ActionUtils.getTokenStringAt(sDoc, prev.start - 1) + \"]\" + MEMBER_SEPARATOR + abbrev;\n                        }\n                    }\n                    sDoc.remove(token.start, token.length);\n                    dot = token.start;\n                }\n\n                Frame frame = ActionUtils.getFrameFor(target);\n                if (dlg == null) {\n                    dlg = new ComboCompletionDialog(frame, true, items);\n                }\n                dlg.setLocationRelativeTo(frame);\n                Point p = frame.getLocation();\n                // Get location of Dot in rt\n                Rectangle rt = target.modelToView(dot);\n                Point loc = new Point(rt.x, rt.y);\n                // convert the location from Text Componet coordinates to\n                // Frame coordinates...\n                loc = SwingUtilities.convertPoint(target, loc, frame);\n                // and then to Screen coordinates\n                SwingUtilities.convertPointToScreen(loc, frame);\n                dlg.setLocation(loc);\n                dlg.setFonts(target.getFont());\n                dlg.setText(abbrev);\n                dlg.setVisible(true);\n                String res = dlg.getResult();\n                ActionUtils.insertMagicString(target, dot, res);\n            } catch (BadLocationException ex) {\n                Logger.getLogger(ComboCompletionAction.class.getName()).log(Level.SEVERE, null, ex);\n            }\n        }\n    }\n\n    /**\n     * The completions will for now reside on another properties style file\n     * referenced by prefix.Completions.File\n     *\n     * @param config\n     * @param prefix\n     * @param name\n     */\n    public void config(Configuration config, String prefix, String name) {\n        // for now we will use just one list for anything.  This can be modified\n        // by having a map from TokenType to String[] or something....\n        items = config.getPrefixPropertyList(prefix, name + \".Items\");\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ComboCompletionDialog.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.3\" maxVersion=\"1.7\" type=\"org.netbeans.modules.form.forminfo.JDialogFormInfo\">\n  <Properties>\n    <Property name=\"defaultCloseOperation\" type=\"int\" value=\"2\"/>\n    <Property name=\"resizable\" type=\"boolean\" value=\"false\"/>\n    <Property name=\"undecorated\" type=\"boolean\" value=\"true\"/>\n  </Properties>\n  <SyntheticProperties>\n    <SyntheticProperty name=\"formSizePolicy\" type=\"int\" value=\"1\"/>\n  </SyntheticProperties>\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Component id=\"jTxtItem\" alignment=\"0\" pref=\"270\" max=\"32767\" attributes=\"0\"/>\n          <Component id=\"jScrollPane1\" alignment=\"0\" pref=\"270\" max=\"32767\" attributes=\"0\"/>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n              <Component id=\"jTxtItem\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" pref=\"0\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jScrollPane1\" pref=\"111\" max=\"32767\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JTextField\" name=\"jTxtItem\">\n      <Properties>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"null\"/>\n        </Property>\n      </Properties>\n      <Events>\n        <EventHandler event=\"keyPressed\" listener=\"java.awt.event.KeyListener\" parameters=\"java.awt.event.KeyEvent\" handler=\"jTxtItemKeyPressed\"/>\n      </Events>\n    </Component>\n    <Container class=\"javax.swing.JScrollPane\" name=\"jScrollPane1\">\n      <AuxValues>\n        <AuxValue name=\"autoScrollPane\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n\n      <Layout class=\"org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout\"/>\n      <SubComponents>\n        <Component class=\"javax.swing.JList\" name=\"jLstItems\">\n          <Properties>\n            <Property name=\"selectionMode\" type=\"int\" value=\"0\"/>\n            <Property name=\"focusable\" type=\"boolean\" value=\"false\"/>\n          </Properties>\n        </Component>\n      </SubComponents>\n    </Container>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ComboCompletionDialog.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.actions;\n\nimport java.awt.Font;\nimport java.awt.event.KeyEvent;\nimport java.util.Vector;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class ComboCompletionDialog extends javax.swing.JDialog {\n\n    /**\n     * The result returned to the caller\n     */\n    private String result = null;\n    /**\n     * The current filter, to avoid refiltering the items\n     */\n    public String escapeChars = \";(= \\t\\n\";\n    public String[] items;\n\n    /** Creates new form ComboCompletionDialog\n     * @param parent\n     * @param modal\n     * @param items\n     */\n    public ComboCompletionDialog(java.awt.Frame parent, boolean modal,\n            String[] items) {\n        super(parent, modal);\n        initComponents();\n        this.items = items;\n        jLstItems.setListData(items);\n        jTxtItem.getDocument().addDocumentListener(new DocumentListener() {\n\n            public void insertUpdate(DocumentEvent e) {\n                refilterList();\n            }\n\n            public void removeUpdate(DocumentEvent e) {\n                refilterList();\n            }\n\n            public void changedUpdate(DocumentEvent e) {\n                refilterList();\n            }\n        });\n        // This will allow the textfield to receive TAB keys\n        jTxtItem.setFocusTraversalKeysEnabled(false);\n    }\n\n    public void setFonts(Font font) {\n        jTxtItem.setFont(font);\n        jLstItems.setFont(font);\n        doLayout();\n    }\n\n    public void setText(String abbrev) {\n        jTxtItem.setText(abbrev);\n    }\n\n    private void refilterList() {\n        String prefix = jTxtItem.getText();\n        Vector<String> filtered = new Vector<String>();\n        Object selected = jLstItems.getSelectedValue();\n        for (String s : items) {\n            if (s.startsWith(prefix)) {\n                filtered.add(trimPrefix(s));\n            }\n        }\n        jLstItems.setListData(filtered);\n        if (selected != null) {\n            jLstItems.setSelectedValue(selected, true);\n        } else {\n            jLstItems.setSelectedIndex(0);\n        }\n    }\n\n    private String trimPrefix(String item) {\n        int idx1 = item.indexOf(\"[\");\n        int idx2 = item.indexOf(\"]\");\n        if (idx1 > -1 && idx2 > -1) {\n            return (idx1 > 0 ? item.substring(0, idx1 - 1) : \"\") + (idx2 < item.length() - 1 ? item.substring(idx2 + 1) : \"\");\n        }\n        return item;\n    }\n\n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    @SuppressWarnings(\"unchecked\")\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        jTxtItem = new javax.swing.JTextField();\n        jScrollPane1 = new javax.swing.JScrollPane();\n        jLstItems = new javax.swing.JList();\n\n        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);\n        setResizable(false);\n        setUndecorated(true);\n\n        jTxtItem.setBorder(null);\n        jTxtItem.addKeyListener(new java.awt.event.KeyAdapter() {\n            public void keyPressed(java.awt.event.KeyEvent evt) {\n                jTxtItemKeyPressed(evt);\n            }\n        });\n\n        jLstItems.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);\n        jLstItems.setFocusable(false);\n        jScrollPane1.setViewportView(jLstItems);\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());\n        getContentPane().setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addComponent(jTxtItem, javax.swing.GroupLayout.DEFAULT_SIZE, 270, Short.MAX_VALUE)\n            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 270, Short.MAX_VALUE)\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addComponent(jTxtItem, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)\n                .addGap(0, 0, 0)\n                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 111, Short.MAX_VALUE))\n        );\n\n        pack();\n    }// </editor-fold>//GEN-END:initComponents\n\n    private void jTxtItemKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTxtItemKeyPressed\n\n        int i = jLstItems.getSelectedIndex();\n        switch (evt.getKeyCode()) {\n            case KeyEvent.VK_ESCAPE:\n                result = jTxtItem.getText();\n                setVisible(false);\n                return;\n            case KeyEvent.VK_DOWN:\n                if (i < jLstItems.getModel().getSize() - 1) {\n                    i++;\n                }\n                jLstItems.setSelectedIndex(i);\n                jLstItems.ensureIndexIsVisible(i);\n                break;\n            case KeyEvent.VK_UP:\n                if (i > 0) {\n                    i--;\n                }\n                jLstItems.setSelectedIndex(i);\n                jLstItems.ensureIndexIsVisible(i);\n                break;\n        }\n\n        if (escapeChars.indexOf(evt.getKeyChar()) >= 0) {\n            if (jLstItems.getSelectedIndex() >= 0) {\n                result = jLstItems.getSelectedValue().toString();\n            } else {\n                result = jTxtItem.getText();\n            }\n            char pressed = evt.getKeyChar();\n            // we need to just accept ENTER, and replace the tab with a single\n            // space\n            if (pressed != '\\n') {\n                result += (pressed == '\\t') ? ' ' : pressed;\n            }\n            setVisible(false);\n        }\n    }//GEN-LAST:event_jTxtItemKeyPressed\n\n    /**\n     * Gets the selected text shown on the dialog.\n     * @return the selected text, or empty string if nothing is selected\n     */\n    public String getResult() {\n        return result == null ? \"\" : trimPrefix(result);\n    }\n\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JList jLstItems;\n    private javax.swing.JScrollPane jScrollPane1;\n    private javax.swing.JTextField jTxtItem;\n    // End of variables declaration//GEN-END:variables\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/DeleteLinesAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * This Action deletes the current line, or all the highlighted lines.\n * @author Ayman Al-Sairafi\n */\npublic class DeleteLinesAction extends TextAction implements SyntaxAction {\n\n    public DeleteLinesAction() {\n        super(\"DELETE_LINES\");\n    }\n\n\n\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        if (target != null) {\n            try {\n                SyntaxDocument sDoc = (SyntaxDocument) target.getDocument();\n                int st = sDoc.getLineStartOffset(target.getSelectionStart());\n                int en = sDoc.getLineEndOffset(target.getSelectionEnd());\n                sDoc.remove(st, en - st);\n            } catch (BadLocationException ex) {\n                Logger.getLogger(DeleteLinesAction.class.getName()).log(Level.SEVERE, null, ex);\n            }\n        }\n    }\n\n    public void config(Configuration config, String prefix, String name) {\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/DuplicateLinesAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.KeyEvent;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * This Action duplicates the current line, or all the highlighted lines.\n * @author Ayman Al-Sairafi\n */\npublic class DuplicateLinesAction extends TextAction implements SyntaxAction {\n\n    public DuplicateLinesAction() {\n        super(\"DUPLICATE_LINES\");\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        if (target != null) {\n            try {\n                SyntaxDocument sDoc = (SyntaxDocument) target.getDocument();\n                int st = sDoc.getLineStartOffset(target.getSelectionStart());\n                int en = sDoc.getLineEndOffset(target.getSelectionEnd());\n                String dupLines = sDoc.getText(st, en-st);\n                sDoc.insertString(st, dupLines, null);\n            } catch (BadLocationException ex) {\n                Logger.getLogger(DuplicateLinesAction.class.getName()).log(Level.SEVERE, null, ex);\n            }\n        }\n    }\n\n    public void config(Configuration config, String prefix, String name) {\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/FindReplaceActions.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport javax.swing.JOptionPane;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * Finder class.  This class contains the general Find, Find Next,\n * Find Previous, and the Find Marker Actions.\n * \n * Note that all Actions are subclasses of this class because all actions\n * require the find text to be shared among them.  This is the best approach\n * to have all Action classes share this same data.\n *\n * @author Ayman Al-Sairafi\n */\npublic class FindReplaceActions implements SyntaxAction {\n\n    private Pattern pattern = null;\n    private boolean wrap = true;\n    private final FindDialogAction findDialogAction = new FindDialogAction();\n    private final FindNextAction findNextAction = new FindNextAction();\n    private ReplaceDialog dlg;\n\n    public FindReplaceActions() {\n    }\n\n    public TextAction getFindDialogAction() {\n        return findDialogAction;\n    }\n\n    public TextAction getFindNextAction() {\n        return findNextAction;\n    }\n\n    public void config(Configuration config, String prefix, String name) {\n    }\n\n    public TextAction getAction(String key) {\n        if(key.equals(\"FIND\") ) {\n        return findDialogAction;\n        } else if(key.equals(\"REPLACE\")) {\n            return findDialogAction;\n        } else if(key.equals(\"FIND_NEXT\")) {\n            return findNextAction;\n        } else {\n            throw new IllegalArgumentException(\"Bad Action: \" + key);\n        }\n    }\n\n    /**\n     * This class displays the Find Dialog.  The dialog will use the pattern\n     * and will update it once it is closed.\n     */\n    class FindDialogAction extends TextAction {\n\n        public FindDialogAction() {\n            super(\"FIND_ACTION\");\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            JTextComponent target = getTextComponent(e);\n            if (target != null) {\n                showDialog(target);\n            }\n        }\n    }\n\n    /**\n     * This class performs a Find Next operation by using the current pattern\n     */\n    class FindNextAction extends TextAction {\n\n        public FindNextAction() {\n            super(\"FIND_NEXT\");\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            // if we did not start searching, return now\n            if (pattern == null) {\n                return;\n            }\n            JTextComponent target = getTextComponent(e);\n            doFindNext(target);\n        }\n    }\n\n    /**\n     * Display an OptionPane dialog that the search string is not found\n     */\n    public void msgNotFound() {\n        JOptionPane.showMessageDialog(null,\n                \"Search String \" + pattern + \" not found\",\n                \"Find\", JOptionPane.INFORMATION_MESSAGE);\n    }\n\n    /**\n     * Show the dialog\n     * @param targetFrame\n     * @param sDoc\n     * @param target\n     */\n    private void showDialog(JTextComponent target) {\n        if (dlg == null) {\n            dlg = new ReplaceDialog(target, FindReplaceActions.this);\n        }\n        dlg.setVisible(true);\n    }\n\n    /**\n     * Perform a FindNext operation on the given text component.  Position\n     * the caret at the start of the next found pattern\n     * @param target\n     */\n    public void doFindNext(JTextComponent target) {\n        if (target == null || pattern == null) {\n            return;\n        }\n        SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(target);\n        if (sDoc == null) {\n            return;\n        }\n        int start = target.getCaretPosition() + 1;\n        // we must advance the position by one, otherwise we will find\n        // the same text again\n        if (start >= sDoc.getLength()) {\n            start = 0;\n        }\n        Matcher matcher = sDoc.getMatcher(pattern, start);\n        if (matcher != null && matcher.find()) {\n            // since we used an offset in the matcher, the matcher location\n            // MUST be offset by that location\n            target.select(matcher.start() + start, matcher.end() + start);\n        } else {\n            if (isWrap()) {\n                matcher = sDoc.getMatcher(pattern);\n                if (matcher != null && matcher.find()) {\n                    target.select(matcher.start(), matcher.end());\n                } else {\n                    msgNotFound();\n                }\n            } else {\n                msgNotFound();\n            }\n        }\n    }\n\n    /**\n     * Perform a replace all operation on the given component.\n     * Note that this create a new duplicate String big as the entire\n     * document and then assign it to the target text component\n     * @param target\n     * @param replacement\n     */\n    public void replaceAll(JTextComponent target, String replacement) {\n        SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(target);\n        if (pattern == null || sDoc == null) {\n            return;\n        }\n        Matcher matcher = sDoc.getMatcher(pattern);\n        String newText = matcher.replaceAll(replacement);\n        target.setText(newText);\n    }\n\n    // - Getters and setters -------------------------------------------------\n    public Pattern getPattern() {\n        return pattern;\n    }\n\n    public void setPattern(Pattern pattern) {\n        this.pattern = pattern;\n    }\n\n    public boolean isWrap() {\n        return wrap;\n    }\n\n    public void setWrap(boolean wrap) {\n        this.wrap = wrap;\n    }\n}"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/GotoLineAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport java.util.WeakHashMap;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * This actions displays the GotoLine dialog\n */\npublic class GotoLineAction extends TextAction implements SyntaxAction {\n\n    private static WeakHashMap<JTextComponent, GotoLineDialog> DIALOGS =\n            new WeakHashMap<JTextComponent, GotoLineDialog>();\n\n    public GotoLineAction() {\n        super(\"GOTO_LINE\");\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        GotoLineDialog dlg = DIALOGS.get(target);\n        if(dlg == null) {\n            dlg = new GotoLineDialog(target);\n            DIALOGS.put(target, dlg);\n        }\n        dlg.setVisible(true);\n    }\n\n    public void config(Configuration config, String prefix, String name) {\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/GotoLineDialog.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.3\" maxVersion=\"1.7\" type=\"org.netbeans.modules.form.forminfo.JDialogFormInfo\">\n  <Properties>\n    <Property name=\"title\" type=\"java.lang.String\" value=\"Goto Line\"/>\n    <Property name=\"modal\" type=\"boolean\" value=\"true\"/>\n    <Property name=\"name\" type=\"java.lang.String\" value=\"\" noResource=\"true\"/>\n    <Property name=\"resizable\" type=\"boolean\" value=\"false\"/>\n  </Properties>\n  <SyntheticProperties>\n    <SyntheticProperty name=\"formSizePolicy\" type=\"int\" value=\"1\"/>\n  </SyntheticProperties>\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jCmbLineNumbers\" min=\"-2\" pref=\"104\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jBtnOk\" pref=\"47\" max=\"32767\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"jCmbLineNumbers\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"jBtnOk\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"32767\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JComboBox\" name=\"jCmbLineNumbers\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"0\"/>\n        </Property>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"jCmbLineNumbersActionPerformed\"/>\n      </Events>\n    </Component>\n    <Component class=\"javax.swing.JButton\" name=\"jBtnOk\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" value=\"Go\"/>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"jBtnOkActionPerformed\"/>\n      </Events>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/GotoLineDialog.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.actions;\n\nimport javax.swing.JOptionPane;\nimport javax.swing.text.JTextComponent;\n\n/**\n * A simple dialog to prompt for a line number and go to it\n * @author Ayman Al-Sairafi\n */\npublic class GotoLineDialog extends javax.swing.JDialog {\n\n    private JTextComponent text;\n\n    /** \n     * Creates new form GotoLineDialog\n     * @param text\n     */\n    public GotoLineDialog(JTextComponent text) {\n        super(ActionUtils.getFrameFor(text), false);\n        initComponents();\n        this.text = text;\n        setLocationRelativeTo(text.getRootPane());\n    }\n\n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    @SuppressWarnings(\"unchecked\")\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        jCmbLineNumbers = new javax.swing.JComboBox();\n        jBtnOk = new javax.swing.JButton();\n\n        setTitle(\"Goto Line\");\n        setModal(true);\n        setName(\"\"); // NOI18N\n        setResizable(false);\n\n        jCmbLineNumbers.setEditable(true);\n        jCmbLineNumbers.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                jCmbLineNumbersActionPerformed(evt);\n            }\n        });\n\n        jBtnOk.setText(\"Go\");\n        jBtnOk.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                jBtnOkActionPerformed(evt);\n            }\n        });\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());\n        getContentPane().setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addComponent(jCmbLineNumbers, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE)\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(jBtnOk, javax.swing.GroupLayout.DEFAULT_SIZE, 47, Short.MAX_VALUE)\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(jCmbLineNumbers, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)\n                    .addComponent(jBtnOk))\n                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))\n        );\n\n        pack();\n    }// </editor-fold>//GEN-END:initComponents\n\n    private void jBtnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnOkActionPerformed\n        setTextPos();\n    }//GEN-LAST:event_jBtnOkActionPerformed\n\n    private void setTextPos() {\n        Object line = jCmbLineNumbers.getSelectedItem();\n        if (line != null) {\n            try {\n                int lineNr = Integer.parseInt(line.toString());\n                int pos = ActionUtils.getDocumentPosition(text, lineNr, 0);\n                ActionUtils.insertIntoCombo(jCmbLineNumbers, line);\n                text.setCaretPosition(pos);\n                setVisible(false);\n            } catch (NumberFormatException ex) {\n                JOptionPane.showMessageDialog(this, \"Invalid Number: \" + line,\n                        \"Number Error\", JOptionPane.ERROR_MESSAGE);\n            }\n        }\n    }\n\n    private void jCmbLineNumbersActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCmbLineNumbersActionPerformed\n        // FIXME: this is called twice by the action, skip it\n        setTextPos();\n        // FIXME: Add ESC key listener to hide the dialog\n    }//GEN-LAST:event_jCmbLineNumbersActionPerformed\n\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JButton jBtnOk;\n    private javax.swing.JComboBox jCmbLineNumbers;\n    // End of variables declaration//GEN-END:variables\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/IndentAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.text.DefaultEditorKit;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.PlainDocument;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * IndentAction is used to replace Tabs with spaces.  If there is selected\n * text, then the lines spanning the selection will be shifted\n * right by one tab-width space  character\n */\npublic class IndentAction extends DefaultEditorKit.InsertTabAction \n        implements SyntaxAction {\n\n    public IndentAction() {\n        super();\n    }\n\n    @Override\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        if (target != null) {\n            String selected = target.getSelectedText();\n            if (selected == null) {\n                PlainDocument pDoc = (PlainDocument) target.getDocument();\n                Integer tabStop = (Integer) pDoc.getProperty(PlainDocument.tabSizeAttribute);\n                int lineStart = pDoc.getParagraphElement(target.getCaretPosition()).getStartOffset();\n                int column = target.getCaretPosition() - lineStart;\n                int needed = tabStop - (column % tabStop);\n                target.replaceSelection(ActionUtils.SPACES.substring(0, needed));\n            } else {\n                String[] lines = ActionUtils.getSelectedLines(target);\n                int start = target.getSelectionStart();\n                StringBuilder sb = new StringBuilder();\n                for (String line : lines) {\n                    sb.append('\\t');\n                    sb.append(line);\n                    sb.append('\\n');\n                }\n                target.replaceSelection(sb.toString());\n                target.select(start, start + sb.length());\n            }\n        }\n    }\n\n    public void config(Configuration config, String prefix, String name) {\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/JIndentAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.util.Configuration;\n\npublic class JIndentAction extends TextAction implements SyntaxAction {\n\n    /**\n     * creates new JIndentAction.\n     * Initial Code contributed by ser... AT mail.ru\n     */\n    public JIndentAction() {\n        super(\"JINDENT\");\n    }\n\n    /**\n     * {@inheritDoc}\n     * @param e \n     */\n    @Override\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        if (target != null) {\n            SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(target);\n            int pos = target.getCaretPosition();\n            int start = sDoc.getParagraphElement(pos).getStartOffset();\n            String line = ActionUtils.getLine(target);\n            String lineToPos = line.substring(0, pos - start);\n            String prefix = ActionUtils.getIndent(line);\n            int tabSize = ActionUtils.getTabSize(target);\n            if (lineToPos.trim().endsWith(\"{\")) {\n                prefix += ActionUtils.SPACES.substring(0, tabSize);\n            } else {\n                String noComment = sDoc.getUncommentedText(start, pos); // skip EOL comments\n\n                if (noComment.trim().endsWith(\"{\")) {\n                    prefix += ActionUtils.SPACES.substring(0, tabSize);\n                }\n            }\n            target.replaceSelection(\"\\n\" + prefix);\n        }\n    }\n\n\n    public void config(Configuration config, String prefix, String name) {\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/JUnindentAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.Token;\nimport jsyntaxpane.util.Configuration;\n\npublic class JUnindentAction extends TextAction implements SyntaxAction {\n\n    /**\n     * creates new JUnindentAction.\n     * Initial Code contributed by ser... AT mail.ru\n     */\n    public JUnindentAction() {\n        super(\"JUNINDENT\");\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        if (target != null) {\n            SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(target);\n            int pos = target.getCaretPosition();\n            int start = sDoc.getParagraphElement(pos).getStartOffset();\n            String line = ActionUtils.getLine(target);\n            if (ActionUtils.isEmptyOrBlanks(line)) {\n                try {\n                    sDoc.insertString(pos, \"}\", null);\n                    Token t = sDoc.getPairFor(sDoc.getTokenAt(pos));\n                    if (null != t) {\n                        String pairLine = ActionUtils.getLineAt(target, t.start);\n                        String indent = ActionUtils.getIndent(pairLine);\n                        sDoc.replace(start, line.length() + 1, indent + \"}\", null);\n                    }\n                } catch (BadLocationException ble) {\n                    target.replaceSelection(\"}\");\n                }\n            } else {\n                target.replaceSelection(\"}\");\n            }\n        }\n    }\n\n    public void config(Configuration config, String prefix, String name) {\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/JavaIndentAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.PlainDocument;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * This action performs Java Indentation each time VK_ENTER is pressed\n * Java Indentation is inserting the same amount of spaces as\n * the line above.\n * If the current line ends with a '{' character, then an additional virtual\n * tab is inserted.\n * If the trimmed current line ends with '}', then the line is unindented\n */\npublic class JavaIndentAction extends TextAction implements SyntaxAction {\n\n    public JavaIndentAction() {\n        super(\"JAVA_INDENT\");\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        if (target != null) {\n            String line = ActionUtils.getLine(target);\n            String prefix = ActionUtils.getIndent(line);\n            Integer tabSize = (Integer) target.getDocument().getProperty(PlainDocument.tabSizeAttribute);\n            if (line.trim().endsWith(\"{\")) {\n                prefix += ActionUtils.SPACES.substring(0, tabSize);\n            }\n            SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(target);\n            if (sDoc != null && line.trim().equals(\"}\")) {\n                int pos = target.getCaretPosition();\n                int start = sDoc.getParagraphElement(pos).getStartOffset();\n                int end = sDoc.getParagraphElement(pos).getEndOffset();\n                if (end >= sDoc.getLength()) {\n                    end--;\n                }\n                if (line.startsWith(ActionUtils.SPACES.substring(0, tabSize))) {\n                    try {\n                        sDoc.replace(start, end - start, line.substring(tabSize) + \"\\n\", null);\n                    } catch (BadLocationException ex) {\n                        Logger.getLogger(ActionUtils.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);\n                    }\n                } else {\n                    target.replaceSelection(\"\\n\" + prefix);\n                }\n            } else {\n                target.replaceSelection(\"\\n\" + prefix);\n            }\n        }\n    }\n\n    public void config(Configuration config, String prefix, String name) {\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/MapCompletionAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport java.util.Map;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.Token;\nimport jsyntaxpane.util.Configuration;\nimport jsyntaxpane.util.JarServiceProvider;\n\n/**\n * Completion Actions:\n * All completions are based on a simple String to String Map.\n */\npublic class MapCompletionAction extends TextAction implements SyntaxAction {\n\n    Map<String, String> completions;\n\n    public MapCompletionAction() {\n        super(\"MAP_COMPLETION\");\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        if (target != null && target.getDocument() instanceof SyntaxDocument) {\n            SyntaxDocument sDoc = (SyntaxDocument) target.getDocument();\n            int dot = target.getCaretPosition();\n            Token token = sDoc.getTokenAt(dot);\n            if (token != null) {\n                String abbriv = ActionUtils.getTokenStringAt(sDoc, dot);\n                if (completions.containsKey(abbriv)) {\n                    String completed = completions.get(abbriv);\n                    if (completed.indexOf('|') >= 0) {\n                        int ofst = completed.length() - completed.indexOf('|') - 1;\n                        sDoc.replaceToken(token, completed.replace(\"|\", \"\"));\n                        target.setCaretPosition(target.getCaretPosition() - ofst);\n                    } else {\n                        sDoc.replaceToken(token, completed);\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * The completions will for now reside on another properties style file\n     * referenced by prefix.Completions.File\n     * \n     * @param config\n     * @param prefix\n     * @param name \n     */\n    public void config(Configuration config, String prefix, String name) {\n        String completionsFile = config.getPrefixProperty(prefix, \"Completions.File\", \"NONE\");\n        if(completionsFile != null) {\n            completions = JarServiceProvider.readStringsMap(completionsFile);\n        }\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/PairAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * A Pair action inserts a pair of characters (left and right) around the\n * current selection, and then places the caret between them\n *\n * The pairs are hard-coded here.\n */\npublic class PairAction extends TextAction implements SyntaxAction {\n\n    public PairAction() {\n        super(\"PAIR_ACTION\");\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        if (target != null) {\n            String left = e.getActionCommand();\n            String right = PAIRS.get(left);\n            String selected = target.getSelectedText();\n            if (selected != null) {\n                target.replaceSelection(left + selected + right);\n            } else {\n                target.replaceSelection(left + right);\n            }\n            target.setCaretPosition(target.getCaretPosition() - 1);\n        }\n    }\n\n    public void config(Configuration config, String prefix, String name) {\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n\n    private static Map<String, String> PAIRS = new HashMap<String, String>(4);\n\n    static {\n        PAIRS.put(\"(\", \")\");\n        PAIRS.put(\"[\", \"]\");\n        PAIRS.put(\"\\\"\", \"\\\"\");\n        PAIRS.put(\"'\", \"'\");\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/RedoAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * Redo action\n */\npublic class RedoAction extends TextAction implements SyntaxAction {\n\n    public RedoAction() {\n        super(\"REDO\");\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        if (target != null) {\n            if (target.getDocument() instanceof SyntaxDocument) {\n                SyntaxDocument sDoc = (SyntaxDocument) target.getDocument();\n                sDoc.doRedo();\n            }\n        }\n    }\n\n    public void config(Configuration config, String prefix, String name) {\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ReplaceDialog.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.3\" maxVersion=\"1.7\" type=\"org.netbeans.modules.form.forminfo.JDialogFormInfo\">\n  <Properties>\n    <Property name=\"title\" type=\"java.lang.String\" value=\"Find and Replace\"/>\n    <Property name=\"name\" type=\"java.lang.String\" value=\"\" noResource=\"true\"/>\n    <Property name=\"resizable\" type=\"boolean\" value=\"false\"/>\n  </Properties>\n  <SyntheticProperties>\n    <SyntheticProperty name=\"formSizePolicy\" type=\"int\" value=\"1\"/>\n  </SyntheticProperties>\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"1\" attributes=\"0\">\n                  <Component id=\"jLabel2\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"jLabel1\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n                      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                          <Component id=\"jChkRegex\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"jChkIgnoreCase\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      </Group>\n                      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                          <Group type=\"102\" attributes=\"0\">\n                              <EmptySpace min=\"-2\" pref=\"178\" max=\"-2\" attributes=\"0\"/>\n                              <Component id=\"jLblStatus\" pref=\"39\" max=\"32767\" attributes=\"0\"/>\n                              <EmptySpace min=\"-2\" pref=\"3\" max=\"-2\" attributes=\"0\"/>\n                          </Group>\n                          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n                              <EmptySpace max=\"-2\" attributes=\"0\"/>\n                              <Component id=\"jChkWrap\" min=\"-2\" pref=\"105\" max=\"-2\" attributes=\"0\"/>\n                          </Group>\n                      </Group>\n                  </Group>\n                  <Component id=\"jCmbFind\" alignment=\"0\" pref=\"337\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"jCmbReplace\" alignment=\"0\" pref=\"337\" max=\"32767\" attributes=\"1\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"1\" attributes=\"0\">\n                  <Component id=\"jBtnReplaceAll\" alignment=\"0\" pref=\"102\" max=\"32767\" attributes=\"1\"/>\n                  <Component id=\"jBtnNext\" alignment=\"0\" pref=\"102\" max=\"32767\" attributes=\"1\"/>\n                  <Component id=\"jTglHighlight\" alignment=\"1\" pref=\"102\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Group type=\"102\" attributes=\"0\">\n                      <EmptySpace min=\"-2\" pref=\"29\" max=\"-2\" attributes=\"0\"/>\n                      <Component id=\"jLblStatus\" min=\"-2\" max=\"-2\" attributes=\"1\"/>\n                  </Group>\n                  <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                          <Group type=\"103\" alignment=\"0\" groupAlignment=\"3\" attributes=\"0\">\n                              <Component id=\"jLabel1\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                              <Component id=\"jCmbFind\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          </Group>\n                          <Component id=\"jBtnNext\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      </Group>\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                      <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                          <Component id=\"jLabel2\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"jBtnReplaceAll\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"1\"/>\n                          <Component id=\"jCmbReplace\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      </Group>\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                      <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                          <Component id=\"jChkRegex\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"jChkWrap\" alignment=\"3\" min=\"-2\" pref=\"23\" max=\"-2\" attributes=\"0\"/>\n                          <Component id=\"jTglHighlight\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      </Group>\n                  </Group>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jChkIgnoreCase\" min=\"-2\" max=\"-2\" attributes=\"1\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"jLabel1\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" value=\"Find\"/>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JButton\" name=\"jBtnNext\">\n      <Properties>\n        <Property name=\"mnemonic\" type=\"int\" value=\"78\"/>\n        <Property name=\"text\" type=\"java.lang.String\" value=\"Next\"/>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"jBtnNextActionPerformed\"/>\n      </Events>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"jLblStatus\">\n    </Component>\n    <Component class=\"javax.swing.JButton\" name=\"jBtnReplaceAll\">\n      <Properties>\n        <Property name=\"mnemonic\" type=\"int\" value=\"72\"/>\n        <Property name=\"text\" type=\"java.lang.String\" value=\"Replace All\"/>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"jBtnReplaceAllActionPerformed\"/>\n      </Events>\n    </Component>\n    <Component class=\"javax.swing.JCheckBox\" name=\"jChkWrap\">\n      <Properties>\n        <Property name=\"mnemonic\" type=\"int\" value=\"87\"/>\n        <Property name=\"text\" type=\"java.lang.String\" value=\"Wrap around\"/>\n        <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"Wrap to beginning when end is reached\"/>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JCheckBox\" name=\"jChkRegex\">\n      <Properties>\n        <Property name=\"mnemonic\" type=\"int\" value=\"82\"/>\n        <Property name=\"text\" type=\"java.lang.String\" value=\"Regular Expression\"/>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JCheckBox\" name=\"jChkIgnoreCase\">\n      <Properties>\n        <Property name=\"mnemonic\" type=\"int\" value=\"73\"/>\n        <Property name=\"text\" type=\"java.lang.String\" value=\"Ignore Case\"/>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"jLabel2\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" value=\"Replace\"/>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JToggleButton\" name=\"jTglHighlight\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" value=\"Highlight\"/>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"jTglHighlightActionPerformed\"/>\n      </Events>\n    </Component>\n    <Component class=\"javax.swing.JComboBox\" name=\"jCmbReplace\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"0\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JComboBox\" name=\"jCmbFind\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"0\"/>\n        </Property>\n      </Properties>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ReplaceDialog.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ContainerEvent;\nimport java.awt.event.KeyEvent;\nimport jsyntaxpane.components.Markers;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.HeadlessException;\nimport java.awt.event.ContainerListener;\nimport java.awt.event.KeyListener;\nimport java.util.regex.Pattern;\nimport java.util.regex.PatternSyntaxException;\nimport javax.swing.JOptionPane;\nimport javax.swing.event.CaretEvent;\nimport javax.swing.event.CaretListener;\nimport javax.swing.text.JTextComponent;\n\n/**\n * A Find and Replace Dialog.  The dialog will also act as a listener to\n * Document changes so that all highlights are updated if the document is\n * changed.\n * \n * @author Ayman Al-Sairafi\n */\npublic class ReplaceDialog extends javax.swing.JDialog implements CaretListener, KeyListener, ContainerListener {\n\n    private JTextComponent textComponent;\n    private FindReplaceActions finder;\n    private static Markers.SimpleMarker SEARCH_MARKER = new Markers.SimpleMarker(Color.YELLOW);\n\n    /** Creates new form FindDialog */\n    public ReplaceDialog(JTextComponent text,\n            FindReplaceActions finderActions) {\n        super(ActionUtils.getFrameFor(text), false);\n        initComponents();\n        registerKeyAction(this);\n        textComponent = text;\n        finder = finderActions;\n        textComponent.addCaretListener(this);\n        setLocationRelativeTo(text.getRootPane());\n    }\n\n    /**\n     * updates the highlights in the document when it is updated.\n     * This is called by the DocumentListener methods\n     */\n    public void updateHighlights() {\n        Markers.removeMarkers(textComponent, SEARCH_MARKER);\n        if (jTglHighlight.isSelected()) {\n            Markers.markAll(textComponent, finder.getPattern(), SEARCH_MARKER);\n        }\n    }\n\n    private void showRegexpError(PatternSyntaxException ex) throws HeadlessException {\n        JOptionPane.showMessageDialog(this, \"Regexp error: \" + ex.getMessage(),\n                \"Regular Expression Error\", JOptionPane.ERROR_MESSAGE);\n        jCmbFind.requestFocus();\n    }\n\n    /**\n     * update the finder object with data from our UI\n     */\n    private void updateFinder() {\n        int flag = 0;\n        if (!jChkRegex.isSelected()) {\n            flag |= Pattern.LITERAL;\n        }\n        flag |= (jChkIgnoreCase.isSelected()) ? Pattern.CASE_INSENSITIVE : 0;\n        if (jChkIgnoreCase.isSelected()) {\n            flag |= Pattern.CASE_INSENSITIVE;\n        }\n        String regex = (String) jCmbFind.getSelectedItem();\n        if (regex != null && regex.length() > 0) {\n            Pattern pattern = Pattern.compile(regex, flag);\n            finder.setWrap(jChkWrap.isSelected());\n            finder.setPattern(pattern);\n            ActionUtils.insertIntoCombo(jCmbFind, regex);\n        } else {\n            finder.setPattern(null);\n        }\n    }\n\n    /** \n     * This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    @SuppressWarnings(\"unchecked\")\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        jLabel1 = new javax.swing.JLabel();\n        jBtnNext = new javax.swing.JButton();\n        jLblStatus = new javax.swing.JLabel();\n        jBtnReplaceAll = new javax.swing.JButton();\n        jChkWrap = new javax.swing.JCheckBox();\n        jChkRegex = new javax.swing.JCheckBox();\n        jChkIgnoreCase = new javax.swing.JCheckBox();\n        jLabel2 = new javax.swing.JLabel();\n        jTglHighlight = new javax.swing.JToggleButton();\n        jCmbReplace = new javax.swing.JComboBox();\n        jCmbFind = new javax.swing.JComboBox();\n\n        setTitle(\"Find and Replace\");\n        setName(\"\"); // NOI18N\n        setResizable(false);\n\n        jLabel1.setText(\"Find\");\n\n        jBtnNext.setMnemonic('N');\n        jBtnNext.setText(\"Next\");\n        jBtnNext.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                jBtnNextActionPerformed(evt);\n            }\n        });\n\n        jBtnReplaceAll.setMnemonic('H');\n        jBtnReplaceAll.setText(\"Replace All\");\n        jBtnReplaceAll.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                jBtnReplaceAllActionPerformed(evt);\n            }\n        });\n\n        jChkWrap.setMnemonic('W');\n        jChkWrap.setText(\"Wrap around\");\n        jChkWrap.setToolTipText(\"Wrap to beginning when end is reached\");\n\n        jChkRegex.setMnemonic('R');\n        jChkRegex.setText(\"Regular Expression\");\n\n        jChkIgnoreCase.setMnemonic('I');\n        jChkIgnoreCase.setText(\"Ignore Case\");\n\n        jLabel2.setText(\"Replace\");\n\n        jTglHighlight.setText(\"Highlight\");\n        jTglHighlight.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                jTglHighlightActionPerformed(evt);\n            }\n        });\n\n        jCmbReplace.setEditable(true);\n\n        jCmbFind.setEditable(true);\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());\n        getContentPane().setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)\n                    .addComponent(jLabel2)\n                    .addComponent(jLabel1))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addGroup(layout.createSequentialGroup()\n                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                            .addComponent(jChkRegex)\n                            .addComponent(jChkIgnoreCase))\n                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                            .addGroup(layout.createSequentialGroup()\n                                .addGap(178, 178, 178)\n                                .addComponent(jLblStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 39, Short.MAX_VALUE)\n                                .addGap(3, 3, 3))\n                            .addGroup(layout.createSequentialGroup()\n                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                                .addComponent(jChkWrap, javax.swing.GroupLayout.PREFERRED_SIZE, 105, javax.swing.GroupLayout.PREFERRED_SIZE))))\n                    .addComponent(jCmbFind, 0, 337, Short.MAX_VALUE)\n                    .addComponent(jCmbReplace, 0, 337, Short.MAX_VALUE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)\n                    .addComponent(jBtnReplaceAll, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 102, Short.MAX_VALUE)\n                    .addComponent(jBtnNext, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 102, Short.MAX_VALUE)\n                    .addComponent(jTglHighlight, javax.swing.GroupLayout.DEFAULT_SIZE, 102, Short.MAX_VALUE))\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addGroup(layout.createSequentialGroup()\n                        .addGap(29, 29, 29)\n                        .addComponent(jLblStatus))\n                    .addGroup(layout.createSequentialGroup()\n                        .addContainerGap()\n                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                                .addComponent(jLabel1)\n                                .addComponent(jCmbFind, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                            .addComponent(jBtnNext))\n                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                            .addComponent(jLabel2)\n                            .addComponent(jBtnReplaceAll)\n                            .addComponent(jCmbReplace, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                            .addComponent(jChkRegex)\n                            .addComponent(jChkWrap, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)\n                            .addComponent(jTglHighlight))))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(jChkIgnoreCase)\n                .addContainerGap())\n        );\n\n        pack();\n    }// </editor-fold>//GEN-END:initComponents\n\n    private void jBtnNextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnNextActionPerformed\n        try {\n            updateFinder();\n            finder.doFindNext(textComponent);\n            textComponent.requestFocusInWindow();\n        } catch (PatternSyntaxException ex) {\n            showRegexpError(ex);\n        }\n    }//GEN-LAST:event_jBtnNextActionPerformed\n\n    private void jBtnReplaceAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jBtnReplaceAllActionPerformed\n        try {\n            updateFinder();\n            String replacement = (String) jCmbReplace.getSelectedItem();\n            ActionUtils.insertIntoCombo(jCmbFind, replacement);\n            finder.replaceAll(textComponent, replacement);\n            textComponent.requestFocusInWindow();\n        } catch (PatternSyntaxException ex) {\n            showRegexpError(ex);\n        }\n}//GEN-LAST:event_jBtnReplaceAllActionPerformed\n\n    private void jTglHighlightActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTglHighlightActionPerformed\n        updateFinder();\n        updateHighlights();\n    }//GEN-LAST:event_jTglHighlightActionPerformed\n\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JButton jBtnNext;\n    private javax.swing.JButton jBtnReplaceAll;\n    private javax.swing.JCheckBox jChkIgnoreCase;\n    private javax.swing.JCheckBox jChkRegex;\n    private javax.swing.JCheckBox jChkWrap;\n    private javax.swing.JComboBox jCmbFind;\n    private javax.swing.JComboBox jCmbReplace;\n    private javax.swing.JLabel jLabel1;\n    private javax.swing.JLabel jLabel2;\n    private javax.swing.JLabel jLblStatus;\n    private javax.swing.JToggleButton jTglHighlight;\n    // End of variables declaration//GEN-END:variables\n\n    public void caretUpdate(CaretEvent e) {\n        updateHighlights();\n    }\n\n    public void keyTyped(KeyEvent arg0) {\n        \n    }\n\n    public void keyPressed(KeyEvent e) {\n        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {\n            this.setVisible(false);\n        }\n    }\n\n    public void keyReleased(KeyEvent arg0) {\n        \n    }\n\n    public void componentAdded(ContainerEvent e) {\n        registerKeyAction(e.getChild());\n    }\n\n    public void componentRemoved(ContainerEvent e) {\n        registerKeyAction(e.getChild());\n    }\n\n    private void registerKeyAction(Component c) {\n        if (c instanceof ReplaceDialog == false) {\n            c.removeKeyListener(this);\n            c.addKeyListener(this);\n        }\n\n        if (c instanceof Container) {\n            Container cnt = (Container) c;\n            cnt.removeContainerListener(this);\n            cnt.addContainerListener(this);\n            Component[] ch = cnt.getComponents();\n            for (int i = 0; i < ch.length; i++) {\n                registerKeyAction(ch[i]);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/SmartIndent.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.TextAction;\n\n/**\n * This action performs SmartIndentation each time VK_ENTER is pressed\n * SmartIndentation is inserting the same amount of spaces as\n * the line above.  May not be too smart, but good enough.\n */\npublic class SmartIndent extends TextAction {\n\n    public SmartIndent() {\n        super(\"SMART_INDENT\");\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        if (target != null) {\n            String line = ActionUtils.getLine(target);\n            target.replaceSelection(\"\\n\" + ActionUtils.getIndent(line));\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/SyntaxAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.actions;\n\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * All JSyntaxPane Keyboard related actions implement this class.  These\n * classes are created dynamically, and then registered to the SyntaxKit.\n *\n * A class may have multiple TextActions that may be related.  Each EditorKit\n * that is installed will have only one instance of each class, even if more\n * than one action is specified.\n *\n * The key value pairs in the COnfiguration are of the form:\n *\n * [EditorKit.]Action.NAME = class, keyboard key\n *\n * @author Ayman Al-Sairafi\n */\npublic interface SyntaxAction {\n\n    /**\n     * Configure the actions in this class\n     * @param config\n     * @param prefix\n     * @param name: name of the action, will be obtained from the property Key\n     * as the text following the Action.\n     */\n    public void config(Configuration config, String prefix, String name);\n\n    /**\n     * A class may contain several related actions, this will return the action\n     * with given name.\n     * @param name\n     * @return\n     */\n    public TextAction getAction(String name);\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/ToggleCommentsAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.KeyEvent;\nimport java.security.KeyStore;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * This action will toggle comments on or off on selected whole lines.\n * \n * @author Ayman Al-Sairafi\n */\npublic class ToggleCommentsAction extends TextAction implements SyntaxAction {\n\n    protected String lineCommentStart = \"// \";\n    protected Pattern lineCommentPattern = null;\n\n    /**\n     * creates new JIndentAction.\n     * Initial Code contributed by ser... AT mail.ru\n     */\n    public ToggleCommentsAction() {\n        super(\"TOGGLE\");\n    }\n\n    /**\n     * {@inheritDoc}\n     * @param e \n     */\n    @Override\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        if (target != null && target.getDocument() instanceof SyntaxDocument) {\n            String[] lines = ActionUtils.getSelectedLines(target);\n            StringBuffer toggled = new StringBuffer();\n            for (int i = 0; i < lines.length; i++) {\n                Matcher m = lineCommentPattern.matcher(lines[i]);\n                if (m.find()) {\n                    toggled.append(m.replaceFirst(\"$2\"));\n                } else {\n                    toggled.append(lineCommentStart);\n                    toggled.append(lines[i]);\n                }\n                toggled.append('\\n');\n            }\n            target.replaceSelection(toggled.toString());\n        }\n    }\n\n    public void config(Configuration config, String prefix, String name) {\n        // we need to escape the chars\n        lineCommentStart = config.getPrefixProperty(prefix,\n                name + \".LineComments\", \"// \").replace(\"\\\"\", \"\");\n        lineCommentPattern = Pattern.compile(\"(^\" + lineCommentStart + \")(.*)\");\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/UndoAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * Undo action\n */\npublic class UndoAction extends TextAction implements SyntaxAction {\n\n    public UndoAction() {\n        super(\"UNDO\");\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        if (target != null) {\n            if (target.getDocument() instanceof SyntaxDocument) {\n                SyntaxDocument sDoc = (SyntaxDocument) target.getDocument();\n                sDoc.doUndo();\n            }\n        }\n    }\n\n    public void config(Configuration config, String prefix, String name) {\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/actions/UnindentAction.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.actions;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.PlainDocument;\nimport javax.swing.text.TextAction;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * This is usually mapped to Shift-TAB to unindent the selection.  The\n * current line, or the selected lines are un-indented by the tabstop of the\n * document.\n */\npublic class UnindentAction extends TextAction implements SyntaxAction {\n\n    public UnindentAction() {\n        super(\"UNINDENT\");\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        JTextComponent target = getTextComponent(e);\n        Integer tabStop = (Integer) target.getDocument().getProperty(PlainDocument.tabSizeAttribute);\n        String indent = ActionUtils.SPACES.substring(0, tabStop);\n        if (target != null) {\n            String[] lines = ActionUtils.getSelectedLines(target);\n            int start = target.getSelectionStart();\n            StringBuilder sb = new StringBuilder();\n            for (String line : lines) {\n                if (line.startsWith(indent)) {\n                    sb.append(line.substring(indent.length()));\n                } else if (line.startsWith(\"\\t\")) {\n                    sb.append(line.substring(1));\n                } else {\n                    sb.append(line);\n                }\n                sb.append('\\n');\n            }\n            target.replaceSelection(sb.toString());\n            target.select(start, start + sb.length());\n        }\n    }\n\n    public void config(Configuration config, String prefix, String name) {\n    }\n\n    public TextAction getAction(String key) {\n        return this;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/components/LineNumbersRuler.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.components;\n\nimport java.awt.*;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.logging.Logger;\nimport javax.swing.*;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.JTextComponent;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.actions.GotoLineDialog;\nimport jsyntaxpane.actions.ActionUtils;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * LineRuleis used to number the lines in the EdiorPane\n * @author Ayman Al-Sairafi\n */\npublic class LineNumbersRuler extends JComponent\n        implements SyntaxComponent, PropertyChangeListener, DocumentListener {\n\n    public static final String PROPERTY_BACKGROUND = \"LineNumbers.Background\";\n    public static final String PROPERTY_FOREGROUND = \"LineNumbers.Foreground\";\n    public static final String PROPERTY_LEFT_MARGIN = \"LineNumbers.LeftMargin\";\n    public static final String PROPERTY_RIGHT_MARGIN = \"LineNumbers.RightMargin\";\n    public static final int DEFAULT_R_MARGIN = 5;\n    public static final int DEFAULT_L_MARGIN = 5;\n    private JEditorPane pane;\n    private String format;\n    private int lineCount = -1;\n    private int r_margin;\n    private int l_margin;\n    private int charHeight;\n    private int charWidth;\n    private GotoLineDialog gotoLineDialog = null;\n    private MouseListener mouseListener = null;\n\n    /**\n     * The status is used to have proper propertyCHange support.  We need to know if we are INSTALLING\n     * the component or DE-INSTALLING it\n     */\n    static enum Status {\n        INSTALLING,\n        DEINSTALLING\n    }\n    private Status status;\n\n    public LineNumbersRuler() {\n        super();\n    }\n\n    @Override\n    protected void paintComponent(Graphics g) {\n        g.setFont(pane.getFont());\n        Rectangle clip = g.getClipBounds();\n        g.setColor(getBackground());\n        g.fillRect(clip.x, clip.y, clip.width, clip.height);\n        g.setColor(getForeground());\n        int lh = charHeight;\n        int end = clip.y + clip.height + lh;\n        int lineNum = clip.y / lh + 1;\n        // round the start to a multiple of lh, and shift by 2 pixels to align\n        // properly to the text.\n        for (int y = (clip.y / lh) * lh + lh - 2; y <= end; y += lh) {\n            String text = String.format(format, lineNum);\n            g.drawString(text, l_margin, y);\n            lineNum++;\n            if (lineNum > lineCount) {\n                break;\n            }\n        }\n    }\n\n    /**\n     * Update the size of the line numbers based on the length of the document\n     */\n    private void updateSize() {\n        int newLineCount = ActionUtils.getLineCount(pane);\n        if (newLineCount == lineCount) {\n            return;\n        }\n        lineCount = newLineCount;\n        int h = lineCount * charHeight + pane.getHeight();\n        int d = (int) Math.log10(lineCount) + 1;\n        if (d < 1) {\n            d = 1;\n        }\n        int w = d * charWidth + r_margin + l_margin;\n        format = \"%\" + d + \"d\";\n        setPreferredSize(new Dimension(w, h));\n        if(getParent() != null){\n            getParent().doLayout();\n        }\n    }\n\n    /**\n     * Get the JscrollPane that contains this EditorPane, or null if no\n     * JScrollPane is the parent of this editor\n     * @param editorPane\n     * @return\n     */\n    public JScrollPane getScrollPane(JTextComponent editorPane) {\n        Container p = editorPane.getParent();\n        while (p != null) {\n            if (p instanceof JScrollPane) {\n                return (JScrollPane) p;\n            }\n            p = p.getParent();\n        }\n        return null;\n    }\n\n    public void config(Configuration config, String prefix) {\n        r_margin = config.getPrefixInteger(prefix,\n                PROPERTY_RIGHT_MARGIN, DEFAULT_R_MARGIN);\n        l_margin = config.getPrefixInteger(prefix,\n                PROPERTY_LEFT_MARGIN, DEFAULT_L_MARGIN);\n        Color foreground = config.getPrefixColor(prefix,\n                PROPERTY_FOREGROUND,\n                Color.BLACK);\n        setForeground(foreground);\n        Color back = config.getPrefixColor(prefix,\n                PROPERTY_BACKGROUND,\n                Color.WHITE);\n        setBackground(back);\n    }\n\n    public void install(JEditorPane editor) {\n        this.pane = editor;\n        charHeight = pane.getFontMetrics(pane.getFont()).getHeight();\n        charWidth = pane.getFontMetrics(pane.getFont()).charWidth('0');\n        editor.addPropertyChangeListener(this);\n        JScrollPane sp = getScrollPane(pane);\n        if (sp == null) {\n            Logger.getLogger(this.getClass().getName()).warning(\n                    \"JEditorPane is not enclosed in JScrollPane, \" +\n                    \"no LineNumbers will be displayed\");\n        } else {\n            sp.setRowHeaderView(this);\n            this.pane.getDocument().addDocumentListener(this);\n            updateSize();\n            gotoLineDialog = new GotoLineDialog(pane);\n            mouseListener = new MouseAdapter() {\n\n                @Override\n                public void mouseClicked(MouseEvent e) {\n                    gotoLineDialog.setVisible(true);\n                }\n            };\n            addMouseListener(mouseListener);\n        }\n        status = Status.INSTALLING;\n    }\n\n    public void deinstall(JEditorPane editor) {\n        removeMouseListener(mouseListener);\n        status = Status.DEINSTALLING;\n        JScrollPane sp = getScrollPane(editor);\n        if (sp != null) {\n            editor.getDocument().removeDocumentListener(this);\n            sp.setRowHeaderView(null);\n        }\n    }\n\n    public void propertyChange(PropertyChangeEvent evt) {\n        if (evt.getPropertyName().equals(\"document\")) {\n            if (evt.getOldValue() instanceof SyntaxDocument) {\n                SyntaxDocument syntaxDocument = (SyntaxDocument) evt.getOldValue();\n                syntaxDocument.removeDocumentListener(this);\n            }\n            if (evt.getNewValue() instanceof SyntaxDocument && status.equals(Status.INSTALLING)) {\n                SyntaxDocument syntaxDocument = (SyntaxDocument) evt.getNewValue();\n                syntaxDocument.addDocumentListener(this);\n            }\n        } else if (evt.getPropertyName().equals(\"font\")) {\n            charHeight = pane.getFontMetrics(pane.getFont()).getHeight();\n            charWidth = pane.getFontMetrics(pane.getFont()).charWidth('0');\n        }\n    }\n\n    public void insertUpdate(DocumentEvent e) {\n        updateSize();\n    }\n\n    public void removeUpdate(DocumentEvent e) {\n        updateSize();\n    }\n\n    public void changedUpdate(DocumentEvent e) {\n        updateSize();\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/components/Markers.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.components;\n\nimport jsyntaxpane.actions.*;\nimport java.awt.Color;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.DefaultHighlighter;\nimport javax.swing.text.Highlighter;\nimport javax.swing.text.JTextComponent;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.Token;\n\n/**\n * This class contains static utility methods to make highliting in text \n * components easier.\n * \n * @author Ayman Al-Sairafi\n */\npublic class Markers {\n\n    // This subclass is used in our highlighting code\n    public static class SimpleMarker extends DefaultHighlighter.DefaultHighlightPainter {\n\n        public SimpleMarker(Color color) {\n            super(color);\n        }\n    }\n\n    /**\n     * Removes only our private highlights\n     * This is public so that we can remove the highlights when the editorKit\n     * is unregistered.  SimpleMarker can be null, in which case all instances of\n     * our Markers are removed.\n     * @param component the text component whose markers are to be removed\n     * @param marker the SimpleMarker to remove\n     */\n    public static void removeMarkers(JTextComponent component, SimpleMarker marker) {\n        Highlighter hilite = component.getHighlighter();\n        Highlighter.Highlight[] hilites = hilite.getHighlights();\n\n        for (int i = 0; i < hilites.length; i++) {\n            if (hilites[i].getPainter() instanceof SimpleMarker) {\n                SimpleMarker hMarker = (SimpleMarker) hilites[i].getPainter();\n                if (marker == null || hMarker.equals(marker)) {\n                    hilite.removeHighlight(hilites[i]);\n                }\n            }\n        }\n    }\n\n    /**\n     * Remove all the markers from an JEditorPane\n     * @param editorPane\n     */\n    public static void removeMarkers(JTextComponent editorPane) {\n        removeMarkers(editorPane, null);\n    }\n\n    /**\n     * add highlights for the given Token on the given pane\n     * @param pane\n     * @param token\n     * @param marker\n     */\n    public static void markToken(JTextComponent pane, Token token, SimpleMarker marker) {\n        markText(pane, token.start, token.end(), marker);\n    }\n\n    /**\n     * add highlights for the given region on the given pane\n     * @param pane\n     * @param start\n     * @param end\n     * @param marker\n     */\n    public static void markText(JTextComponent pane, int start, int end, SimpleMarker marker) {\n        try {\n            Highlighter hiliter = pane.getHighlighter();\n            int selStart = pane.getSelectionStart();\n            int selEnd = pane.getSelectionEnd();\n            // if there is no selection or selection does not overlap\n            if(selStart == selEnd || end < selStart || start > selStart) {\n                hiliter.addHighlight(start, end, marker);\n                return;\n            }\n            // selection starts within the highlight, highlight before slection\n            if(selStart > start && selStart < end ) {\n                hiliter.addHighlight(start, selStart, marker);\n            }\n            // selection ends within the highlight, highlight remaining\n            if(selEnd > start && selEnd < end ) {\n                hiliter.addHighlight(selEnd, end, marker);\n            }\n\n        } catch (BadLocationException ex) {\n            // nothing we can do if the request is out of bound\n            LOG.log(Level.SEVERE, null, ex);\n        }\n    }\n\n    /**\n     * Mark all text in the document that matches the given pattern\n     * @param pane control to use\n     * @param pattern pattern to match\n     * @param marker marker to use for highlighting\n     */\n    public static void markAll(JTextComponent pane, Pattern pattern, SimpleMarker marker) {\n        SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(pane);\n        if(sDoc  == null || pattern == null) {\n            return;\n        }\n        Matcher matcher = sDoc.getMatcher(pattern);\n        while(matcher.find()) {\n            markText(pane, matcher.start(), matcher.end(), marker);\n        }\n    }\n    \n    private static final Logger LOG = Logger.getLogger(Markers.class.getName());\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/components/PairsMarker.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.components;\n\nimport java.awt.Color;\nimport jsyntaxpane.actions.*;\nimport javax.swing.JEditorPane;\nimport javax.swing.event.CaretEvent;\nimport javax.swing.event.CaretListener;\nimport javax.swing.text.JTextComponent;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.Token;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * This class highlights any pairs of the given language.  Pairs are defined\n * with the Token.pairValue.\n *\n * @author Ayman Al-Sairafi\n */\npublic class PairsMarker implements CaretListener, SyntaxComponent {\n    public static final String PROPERTY_COLOR = \"PairMarker.Color\";\n\n    private JTextComponent pane;\n    private Markers.SimpleMarker marker;\n\n    public PairsMarker() {\n    }\n\n    @Override\n    public void caretUpdate(CaretEvent e) {\n        removeMarkers();\n        int pos = e.getDot();\n        SyntaxDocument doc = ActionUtils.getSyntaxDocument(pane);\n        Token token = doc.getTokenAt(pos);\n        if (token != null && token.pairValue != 0) {\n            Markers.markToken(pane, token, marker);\n            Token other = doc.getPairFor(token);\n            if (other != null) {\n                Markers.markToken(pane, other, marker);\n            }\n        }\n    }\n\n    /**\n     * Remove all the highlights from the editor pane.  This should be called\n     * when the editorkit is removed.\n     */\n    public void removeMarkers() {\n        Markers.removeMarkers(pane, marker);\n    }\n\n    public void config(Configuration config, String prefix) {\n        Color markerColor = new Color(config.getPrefixInteger(prefix,\n                PROPERTY_COLOR,\n                0xeeee33));\n        this.marker = new Markers.SimpleMarker(markerColor);\n    }\n\n    public void install(JEditorPane editor) {\n        pane = editor;\n        pane.addCaretListener(this);\n    }\n\n    public void deinstall(JEditorPane editor) {\n        pane.removeCaretListener(this);\n        removeMarkers();\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/components/SyntaxComponent.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.components;\n\nimport javax.swing.JEditorPane;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * A Component that is installed to the EditorKit to perform GUI operations\n * on the Editor.\n *\n * @author Ayman Al-Sairafi\n */\npublic interface SyntaxComponent {\n\n    /**\n     * Configure the component using the given properties.  The keys\n     * needed for configuration will be prefixed by the given prefix\n     * @param config configuration data\n     * @param prefix prefix for keys\n     */\n    public void config(Configuration config, String prefix);\n\n    /**\n     * Called to install the component on an editor\n     * @param editor\n     */\n    public void install(JEditorPane editor);\n\n    /**\n     * Called when the component is to be removed from the editor\n     * @param editor\n     */\n    public void deinstall(JEditorPane editor);\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/components/TokenMarker.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.components;\n\nimport jsyntaxpane.actions.*;\nimport java.awt.Color;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Set;\nimport java.util.logging.Logger;\nimport javax.swing.JEditorPane;\nimport javax.swing.event.CaretEvent;\nimport javax.swing.event.CaretListener;\nimport jsyntaxpane.SyntaxDocument;\nimport jsyntaxpane.Token;\nimport jsyntaxpane.TokenType;\nimport jsyntaxpane.util.Configuration;\n\n/**\n * This class highlights Tokens within a document whenever the caret is moved\n * to a TokenType provided in the config file.\n * \n * @author Ayman Al-Sairafi\n */\npublic class TokenMarker implements SyntaxComponent, CaretListener {\n\n    public static final String DEFAULT_TOKENTYPES = \"IDENTIFIER, TYPE, TYPE2, TYPE3\";\n    public static final String PROPERTY_COLOR = \"TokenMarker.Color\";\n    public static final String PROPERTY_TOKENTYPES = \"TokenMarker.TokenTypes\";\n    private static final int DEFAULT_COLOR = 16772710;\n    private JEditorPane pane;\n    private Set<TokenType> tokenTypes = new HashSet<TokenType>();\n    private Markers.SimpleMarker marker;\n\n    /**\n     * Constructs a new Token highlighter\n     */\n    public TokenMarker() {\n    }\n\n    @Override\n    public void caretUpdate(CaretEvent e) {\n        int pos = e.getDot();\n        SyntaxDocument doc = ActionUtils.getSyntaxDocument(pane);\n        Token token = doc.getTokenAt(pos);\n        removeMarkers();\n        if (token != null && tokenTypes.contains(token.type)) {\n            addMarkers(token);\n        }\n    }\n\n    /**\n     * removes all markers from the pane.\n     */\n    public void removeMarkers() {\n        Markers.removeMarkers(pane, marker);\n    }\n\n    /**\n     * add highlights for the given pattern\n     * @param pattern\n     */\n    void addMarkers(Token tok) {\n        SyntaxDocument sDoc = (SyntaxDocument) pane.getDocument();\n        sDoc.readLock();\n        String text = tok.getText(sDoc);\n        Iterator<Token> it = sDoc.getTokens(0, sDoc.getLength());\n        while (it.hasNext()) {\n            Token nextToken = it.next();\n            if (nextToken.length == tok.length && text.equals(nextToken.getText(sDoc))) {\n                Markers.markToken(pane, nextToken, marker);\n            }\n        }\n        sDoc.readUnlock();\n    }\n\n    @Override\n    public void config(Configuration config, String prefix) {\n        Color markerColor = new Color(config.getPrefixInteger(prefix, \n                PROPERTY_COLOR, DEFAULT_COLOR));\n        this.marker = new Markers.SimpleMarker(markerColor);\n        String types = config.getPrefixProperty(prefix,\n                PROPERTY_TOKENTYPES, DEFAULT_TOKENTYPES);\n\n        for (String type : types.split(\"\\\\s*,\\\\s*\")) {\n            try {\n                TokenType tt = TokenType.valueOf(type);\n                tokenTypes.add(tt);\n            } catch (IllegalArgumentException e) {\n                LOG.warning(\"Error in setting up TokenMarker for \" + prefix +\n                        \" - Invalid TokenType: \" + type);\n            }\n        }\n    }\n\n    @Override\n    public void install(JEditorPane editor) {\n        this.pane = editor;\n        pane.addCaretListener(this);\n    }\n\n    @Override\n    public void deinstall(JEditorPane editor) {\n        removeMarkers();\n        pane.removeCaretListener(this);\n    }\n    private static final Logger LOG = Logger.getLogger(TokenMarker.class.getName());\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/BashSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.lexers.BashLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class BashSyntaxKit extends DefaultSyntaxKit {\n\n    public BashSyntaxKit() {\n        super(new BashLexer());\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/CSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.Lexer;\nimport jsyntaxpane.lexers.CLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class CSyntaxKit extends DefaultSyntaxKit {\n\n    public CSyntaxKit() {\n        super(new CLexer());\n    }\n\n    /**\n     * Construct a JavaSyntaxKit user the supplied lexer.  This is protected so\n     * only subclasses may extend this with a new lexer.\n     * @param lexer\n     */\n    CSyntaxKit(Lexer lexer) {\n        super(lexer);\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/ClojureSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.Lexer;\nimport jsyntaxpane.lexers.ClojureLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class ClojureSyntaxKit extends DefaultSyntaxKit {\n\n    public ClojureSyntaxKit() {\n        super(new ClojureLexer());\n    }\n\n    public ClojureSyntaxKit(Lexer lexer) {\n        super(lexer);\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/CppSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.lexers.CppLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class CppSyntaxKit extends CSyntaxKit {\n\n    public CppSyntaxKit() {\n        super(new CppLexer());\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/DOSBatchSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.lexers.DOSBatchLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class DOSBatchSyntaxKit extends DefaultSyntaxKit {\n\n    public DOSBatchSyntaxKit() {\n        super(new DOSBatchLexer());\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/GroovySyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.lexers.GroovyLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class GroovySyntaxKit extends JavaSyntaxKit {\n\n    public GroovySyntaxKit() {\n        super(new GroovyLexer());\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/JFlexSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.lexers.JFlexLexer;\n\n/**\n * JFlex lexer \n * @author Ayman Al-Sairafi\n */\npublic class JFlexSyntaxKit extends JavaSyntaxKit {\n\n    public JFlexSyntaxKit() {\n        super(new JFlexLexer());\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/JavaScriptSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.lexers.JavaScriptLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class JavaScriptSyntaxKit extends DefaultSyntaxKit {\n\n    public JavaScriptSyntaxKit() {\n        super(new JavaScriptLexer());\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/JavaSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.Lexer;\nimport jsyntaxpane.lexers.JavaLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class JavaSyntaxKit extends DefaultSyntaxKit {\n\n    public JavaSyntaxKit() {\n        super(new JavaLexer());\n    }\n\n    JavaSyntaxKit(Lexer lexer) {\n        super(lexer);\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/PropertiesSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.lexers.PropertiesLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class PropertiesSyntaxKit extends DefaultSyntaxKit {\n\n    public PropertiesSyntaxKit() {\n        super(new PropertiesLexer());\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/PythonSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.lexers.PythonLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class PythonSyntaxKit extends DefaultSyntaxKit {\n\n    public PythonSyntaxKit() {\n        super(new PythonLexer());\n    }\n\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/RubySyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.lexers.RubyLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class RubySyntaxKit extends DefaultSyntaxKit {\n\n    public RubySyntaxKit() {\n        super(new RubyLexer());\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/ScalaSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.Lexer;\nimport jsyntaxpane.lexers.ScalaLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class ScalaSyntaxKit extends DefaultSyntaxKit {\n\n    public ScalaSyntaxKit() {\n        super(new ScalaLexer());\n    }\n\n    public ScalaSyntaxKit(Lexer lexer) {\n        super(lexer);\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/SqlSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.lexers.SqlLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class SqlSyntaxKit extends DefaultSyntaxKit {\n\n    public SqlSyntaxKit() {\n        super(new SqlLexer());\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/TALSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.lexers.TALLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class TALSyntaxKit extends DefaultSyntaxKit {\n\n    public TALSyntaxKit() {\n        super(new TALLexer());\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/syntaxkits/XmlSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.syntaxkits;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.lexers.XmlLexer;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class XmlSyntaxKit extends DefaultSyntaxKit {\n\n    public XmlSyntaxKit() {\n        super(new XmlLexer());\n    }\n\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/util/Configuration.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage jsyntaxpane.util;\n\nimport java.awt.Color;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.regex.Pattern;\n\n/**\n * Wrapper around the Properties class with more functionality\n * This is mainly needed to provide easier support for getting values by an\n * optional prefix.\n * \n * @author Ayman Al-Sairafi\n */\npublic class Configuration extends Properties {\n    final private Map<String, Pattern> valueSeparatorMap = new HashMap<String, Pattern>();\n\n    public Configuration(Properties defaults) {\n        super(defaults);\n    }\n\n    private Configuration() {\n        super();\n    }\n\n    /**\n     * Gets the String value for the key prefix.key, or key, or default\n     * @param prefix\n     * @param key\n     * @param Default\n     * @return\n     */\n    public String getPrefixProperty(String prefix, String key, String Default) {\n        String v = super.getProperty(prefix + \".\" + key);\n        if (v != null) {\n            return v;\n        }\n        return super.getProperty(key, Default);\n    }\n\n    /**\n     * Gets a prefixed integer from the properties.  If number cannot be found\n     * or if it cannot be decoded, the default is returned\n     * The integer is decoded using {@link Integer.decode(String)}\n     * @param prefix\n     * @param key\n     * @param Default\n     * @return\n     */\n    public int getPrefixInteger(String prefix, String key, int Default) {\n        String v = getPrefixProperty(prefix, key, null);\n        if (v == null) {\n            return Default;\n        }\n        try {\n            int i = Integer.decode(v);\n            return i;\n        } catch (NumberFormatException e) {\n            LOG.log(Level.WARNING, null, e);\n            return Default;\n        }\n    }\n\n    /**\n     * Returns a String[] of the comma separated items in the value for\n     * prefix.key or key\n     * Does NOT return null.  If the prefix.key or key value is not found,\n     * then an empty string array is returned.  So the return of this method\n     * can be used directly in a foreach loop\n     * @param prefix\n     * @param key\n     * @return non-null String[] \n     */\n    public String[] getPrefixPropertyList(String prefix, String key) {\n        String v = getProperty(prefix + \".\" + key);\n        if (v == null) {\n            v = getProperty(key);\n        }\n        if (v == null) {\n            return EMPTY_LIST;\n        }\n        return getValueSeparator(prefix).split(v);\n    }\n\n    /**\n     * Returns a boolean from the configuration\n     * @param prefix\n     * @param key\n     * @param Default\n     * @return\n     */\n    public boolean getPrefixBoolean(String prefix, String key, boolean Default) {\n        String b = getPrefixProperty(prefix, key, null);\n        if (b == null) {\n            return Default;\n        }\n        return Boolean.parseBoolean(b.trim());\n    }\n\n    /**\n     * return the COlor that has the given key = prefix.key or key = key or\n     * default, in that order\n     * @param prefix\n     * @param key\n     * @param Default\n     * @return\n     */\n    public Color getPrefixColor(String prefix, String key, Color Default) {\n        String c = getPrefixProperty(prefix, key, null);\n        if (c == null) {\n            return Default;\n        }\n        try {\n            return Color.decode(c);\n        } catch (NumberFormatException e) {\n            return Default;\n        }\n    }\n\n    /**\n     * Return a sub configuration from this instance that has the keys equal to\n     * either prefix.keyPrefix or keyPrefix.  The entries of keyPrefix are\n     * added first, so they are the defaults if prefix is not found.\n     * \n     * @param prefix\n     * @param keyPrefix\n     * @return\n     */\n    public Configuration subConfig(String prefix, String keyPrefix) {\n        Configuration sub = new Configuration();\n        addToSubConf(sub, prefix.length() > 0 ? prefix + \".\" + keyPrefix : keyPrefix);\n        return sub;\n    }\n\n    private void addToSubConf(Configuration subConf, String prefix) {\n        int prefixLen = prefix.length();\n        for (String k : stringPropertyNames()) {\n            if (k.startsWith(prefix)) {\n                subConf.put(k.substring(prefixLen), getProperty(k));\n            }\n        }\n    }\n\n    public Pattern getValueSeparator(String prefix) {\n        synchronized(valueSeparatorMap) {\n            Pattern val = valueSeparatorMap.get(prefix);\n            if (val == null) {\n                val = Pattern.compile(\"\\\\s*\" + getPrefixProperty(prefix, \"ValueSeparator\", COMMA_SEPARATOR) + \"\\\\s*\");\n                valueSeparatorMap.put(prefix, val);\n            }\n            return val;\n        }\n    }\n\n    public static final String[] EMPTY_LIST = new String[0];\n    public static final String COMMA_SEPARATOR = \",\";\n    private static final Logger LOG = Logger.getLogger(Configuration.class.getName());\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/java/jsyntaxpane/util/JarServiceProvider.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage jsyntaxpane.util;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.net.URL;\nimport java.nio.charset.Charset;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n/**\n *\n * @author subwiz\n */\npublic class JarServiceProvider {\n\n    private static final Logger LOG = Logger.getLogger(JarServiceProvider.class.getName());\n\n    private static ClassLoader globalLoader = ClassLoader.getSystemClassLoader();\n    /**\n     * Prevent anyone from instantiating this class.  \n     * Just use the static method\n     */\n    private JarServiceProvider() {\n    }\n\n    public static Class loadClass(String className) throws ClassNotFoundException {\n        return globalLoader.loadClass(className);\n    }\n\n    /**\n     * Return an Object array from the file in META-INF/resources/{classname}\n     * @param cls\n     * @return\n     * @throws java.io.IOException\n     */\n    public static List<Object> getServiceProviders(Class cls) throws IOException {\n        ArrayList<Object> l = new ArrayList<Object>();\n        if (globalLoader != null) {\n            String serviceFile = \"META-INF/services/\" + cls.getName();\n            Enumeration<URL> e = globalLoader.getResources(serviceFile);\n            while (e.hasMoreElements()) {\n                URL u = e.nextElement();\n                InputStream is = u.openStream();\n                BufferedReader br = null;\n                try {\n                    br = new BufferedReader(\n                            new InputStreamReader(is, Charset.forName(\"UTF-8\")));\n                    String str = null;\n                    while ((str = br.readLine()) != null) {\n                        int commentStartIdx = str.indexOf(\"#\");\n                        if (commentStartIdx != -1) {\n                            str = str.substring(0, commentStartIdx);\n                        }\n                        str = str.trim();\n                        if (str.length() == 0) {\n                            continue;\n                        }\n                        try {\n                            Object obj = globalLoader.loadClass(str).newInstance();\n                            l.add(obj);\n                        } catch (Exception ex) {\n                            LOG.warning(\"Could not load: \" + str);\n                            LOG.warning(ex.getMessage());\n                        }\n                    }\n                } finally {\n                    if (br != null) {\n                        br.close();\n                    }\n                }\n            }\n        }\n        return l;\n    }\n\n    /**\n     * Read a file in the META-INF/services location.  File name will be\n     * fully qualified classname, in all lower-case, appended with \".properties\"\n     * If no file is found, then a an empty Property instance will be returned\n     * @param clazz\n     * @return Property file read.\n     */\n    public static Properties readProperties(Class clazz) {\n        return readProperties(clazz.getName());\n    }\n\n    /**\n     * Read a file in the META-INF/services named name appended with \n     * \".properties\"\n     * If no file is found, then a an empty Property instance will be returned\n     * @param name name of file (use dots to separate subfolders).\n     * @return Property file read.\n     */\n    public static Properties readProperties(String name) {\n        Properties props = new Properties();\n        if (globalLoader != null) {\n            InputStream is = null;\n            try {\n                String serviceFile = \"META-INF/services/\" +\n                        name.toLowerCase() + \".properties\";\n                Enumeration<URL> locs = globalLoader.getResources(serviceFile);\n                while(locs.hasMoreElements()) {\n                    URL loc = locs.nextElement();\n                    if (loc != null) {\n                        try {\n                            is = loc.openStream();\n                            Properties p = new Properties();\n                            p.load(is);\n                            props.putAll(p);\n                        } finally {\n                            if (is != null) {\n                                is.close();\n                            }\n                        }\n\n                    }\n                }\n            } catch (IOException ex) {\n                LOG.log(Level.SEVERE, null, ex);\n            } finally {\n                try {\n                    // maybe the is was not open coz we did not find the file\n                    if (is != null) {\n                        is.close();\n                    }\n                } catch (IOException ex) {\n                    LOG.log(Level.SEVERE, null, ex);\n                }\n            }\n        }\n        return props;\n    }\n\n    /**\n     * Read a file in the META-INF/services named name appended with \n     * \".properties\", and returns it as a <code>Map<String, String></code>\n     * If no file is found, then a an empty Property instance will be returned\n     * @param name name of file (use dots to separate subfolders).\n     * @return Map of keys and values\n     */\n    public static Map<String, String> readStringsMap(String name) {\n        Properties props = readProperties(name);\n        HashMap<String, String> map = new HashMap<String, String>();\n        if (props != null) {\n            for (Map.Entry e : props.entrySet()) {\n                map.put(e.getKey().toString(), e.getValue().toString());\n            }\n        }\n        return map;\n    }\n\n    public static void setGlobalLoader(ClassLoader loader) {\n        globalLoader = loader;\n    }\n}\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/bash.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n\r\n%%\r\n\r\n%public\r\n%class BashLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n\r\n%{\r\n    /**\r\n     * Create an empty lexer, yyrset will be called later to reset and assign\r\n     * the reader\r\n     */\r\n    public BashLexer() {\r\n        super();\r\n    }\r\n\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n\r\n    private Token token(TokenType type, int pairValue) {\r\n        return new Token(type, yychar, yylength(), (byte)pairValue);\r\n    }\r\n\r\n    private static final byte PARAN     = 1;\r\n    private static final byte BRACKET   = 2;\r\n    private static final byte CURLY     = 3;\r\n    private static final byte DO        = 4;\r\n    private static final byte CASE      = 5;\r\n    private static final byte IF        = 5;\r\n    private static final byte INT_EXPR  = 6;\r\n\r\n%}\r\n\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\n\r\nIdentifier = [a-zA-Z][a-zA-Z0-9_]*\r\n\r\nComment = \"#\"  {InputCharacter}* {LineTerminator}?\r\nShebang = \"#!\" {InputCharacter}* {LineTerminator}?\r\n\r\nStringCharacter = [^\\r\\n\\\"\\\\]\r\nSingleCharacter = [^\\r\\n\\'\\\\]\r\nBackQuoteChars  = [^\\r\\n\\`\\\\]\r\n\r\n\r\n%%\r\n\r\n<YYINITIAL> \r\n{\r\n  /* Bash keywords */\r\n  \"if\"                          { return token(TokenType.KEYWORD,  IF); }\r\n  \"fi\"                          { return token(TokenType.KEYWORD, -IF); }\r\n  \"do\"                          { return token(TokenType.KEYWORD,  DO); }\r\n  \"done\"                        { return token(TokenType.KEYWORD, -DO); }\r\n  \"case\"                        { return token(TokenType.KEYWORD,  CASE); }\r\n  \"esac\"                        { return token(TokenType.KEYWORD, -CASE); }\r\n  \"$((\"                         { return token(TokenType.KEYWORD,  INT_EXPR); }\r\n  \"))\"                          { return token(TokenType.KEYWORD, -INT_EXPR); }\r\n\r\n  \"(\"                           { return token(TokenType.OPERATOR,  PARAN); }\r\n  \")\"                           { return token(TokenType.OPERATOR, -PARAN); }\r\n  \"{\"                           { return token(TokenType.OPERATOR,  CURLY); }\r\n  \"}\"                           { return token(TokenType.OPERATOR, -CURLY); }\r\n  \"[\"                           { return token(TokenType.OPERATOR,  BRACKET); }\r\n  \"]\"                           { return token(TokenType.OPERATOR, -BRACKET); }\r\n\r\n  \"-eq\"                         |\r\n  \"-ne\"                         |\r\n  \"-lt\"                         |\r\n  \"-gt\"                         |\r\n  \"-ge\"                         |\r\n  \"-le\"                         |\r\n  \">=\"                          |\r\n  \"<=\"                          |\r\n  \"==\"                          |\r\n  \"!=\"                          |\r\n  \"-z\"                          |\r\n  \"-n\"                          |\r\n  \"=~\"                          |\r\n\r\n  \"$\"                           |\r\n  \"#\"                           |\r\n  \"&\"                           |\r\n  \".\"                           |\r\n  \";\"                           |\r\n  \"+\"                           |\r\n  \"-\"                           |\r\n  \"=\"                           |\r\n  \"/\"                           |\r\n  \"++\"                          |\r\n  \"@\"                           { return token(TokenType.OPERATOR); }\r\n\r\n  \"then\"                        |\r\n  \"else\"                        |\r\n  \"elif\"                        |\r\n  \"for\"                         |\r\n  \"in\"                          |\r\n  \"until\"                       |\r\n  \"while\"                       |\r\n  \"break\"                       |\r\n  \"local\"                       |\r\n  \"continue\"                    { return token(TokenType.KEYWORD); }\r\n\r\n  /* string literal */\r\n  \\\"{StringCharacter}+\\\"        |\r\n\r\n  \\'{SingleCharacter}+\\         { return token(TokenType.STRING); }\r\n\r\n  \\`{BackQuoteChars}+\\`         { return token(TokenType.STRING2); }\r\n\r\n\r\n  /* Other commands */\r\n  \"alias\"                    |\r\n  \"apropos\"                  |\r\n  \"apt\"                      |\r\n  \"aspell\"                   |\r\n  \"awk\"                      |\r\n  \"bash\"                     |\r\n  \"basename\"                 |\r\n  \"bc\"                       |\r\n  \"bg\"                       |\r\n  \"builtin\"                  |\r\n  \"bzip2\"                    |\r\n  \"cal\"                      |\r\n  \"cat\"                      |\r\n  \"cd\"                       |\r\n  \"cfdisk\"                   |\r\n  \"chgrp\"                    |\r\n  \"chmod\"                    |\r\n  \"chown\"                    |\r\n  \"chroot\"                   |\r\n  \"chkconfig\"                |\r\n  \"cksum\"                    |\r\n  \"clear\"                    |\r\n  \"cmp\"                      |\r\n  \"comm\"                     |\r\n  \"command\"                  |\r\n  \"continue\"                 |\r\n  \"cp\"                       |\r\n  \"cron\"                     |\r\n  \"crontab\"                  |\r\n  \"csplit\"                   |\r\n  \"cut\"                      |\r\n  \"date\"                     |\r\n  \"dc\"                       |\r\n  \"dd\"                       |\r\n  \"ddrescue\"                 |\r\n  \"declare\"                  |\r\n  \"df\"                       |\r\n  \"diff\"                     |\r\n  \"diff3\"                    |\r\n  \"dig\"                      |\r\n  \"dir\"                      |\r\n  \"dircolors\"                |\r\n  \"dirname\"                  |\r\n  \"dirs\"                     |\r\n  \"dmesg\"                    |\r\n  \"du\"                       |\r\n  \"echo\"                     |\r\n  \"egrep\"                    |\r\n  \"eject\"                    |\r\n  \"enable\"                   |\r\n  \"env\"                      |\r\n  \"ethtool\"                  |\r\n  \"eval\"                     |\r\n  \"exec\"                     |\r\n  \"exit\"                     |\r\n  \"expect\"                   |\r\n  \"expand\"                   |\r\n  \"export\"                   |\r\n  \"expr\"                     |\r\n  \"false\"                    |\r\n  \"fdformat\"                 |\r\n  \"fdisk\"                    |\r\n  \"fg\"                       |\r\n  \"fgrep\"                    |\r\n  \"file\"                     |\r\n  \"find\"                     |\r\n  \"fmt\"                      |\r\n  \"fold\"                     |\r\n  \"format\"                   |\r\n  \"free\"                     |\r\n  \"fsck\"                     |\r\n  \"ftp\"                      |\r\n  \"function\"                 |\r\n  \"gawk\"                     |\r\n  \"getopts\"                  |\r\n  \"grep\"                     |\r\n  \"groups\"                   |\r\n  \"gzip\"                     |\r\n  \"hash\"                     |\r\n  \"head\"                     |\r\n  \"history\"                  |\r\n  \"hostname\"                 |\r\n  \"id\"                       |\r\n  \"ifconfig\"                 |\r\n  \"ifdown\"                   |\r\n  \"ifup\"                     |\r\n  \"import\"                   |\r\n  \"install\"                  |\r\n  \"join\"                     |\r\n  \"kill\"                     |\r\n  \"killall\"                  |\r\n  \"less\"                     |\r\n  \"let\"                      |\r\n  \"ln\"                       |\r\n  \"locate\"                   |\r\n  \"logname\"                  |\r\n  \"logout\"                   |\r\n  \"look\"                     |\r\n  \"lpc\"                      |\r\n  \"lpr\"                      |\r\n  \"lprint\"                   |\r\n  \"lprintd\"                  |\r\n  \"lprintq\"                  |\r\n  \"lprm\"                     |\r\n  \"ls\"                       |\r\n  \"lsof\"                     |\r\n  \"man\"                      |\r\n  \"mkdir\"                    |\r\n  \"mkfifo\"                   |\r\n  \"mkisofs\"                  |\r\n  \"mknod\"                    |\r\n  \"more\"                     |\r\n  \"mount\"                    |\r\n  \"mtools\"                   |\r\n  \"mv\"                       |\r\n  \"mmv\"                      |\r\n  \"netstat\"                  |\r\n  \"nice\"                     |\r\n  \"nl\"                       |\r\n  \"nohup\"                    |\r\n  \"nslookup\"                 |\r\n  \"open\"                     |\r\n  \"op\"                       |\r\n  \"passwd\"                   |\r\n  \"paste\"                    |\r\n  \"pathchk\"                  |\r\n  \"ping\"                     |\r\n  \"popd\"                     |\r\n  \"pr\"                       |\r\n  \"printcap\"                 |\r\n  \"printenv\"                 |\r\n  \"printf\"                   |\r\n  \"ps\"                       |\r\n  \"pushd\"                    |\r\n  \"pwd\"                      |\r\n  \"quota\"                    |\r\n  \"quotacheck\"               |\r\n  \"quotactl\"                 |\r\n  \"ram\"                      |\r\n  \"rcp\"                      |\r\n  \"read\"                     |\r\n  \"readonly\"                 |\r\n  \"reboot\"                   |\r\n  \"renice\"                   |\r\n  \"remsync\"                  |\r\n  \"return\"                   |\r\n  \"rev\"                      |\r\n  \"rm\"                       |\r\n  \"rmdir\"                    |\r\n  \"rsync\"                    |\r\n  \"screen\"                   |\r\n  \"scp\"                      |\r\n  \"sdiff\"                    |\r\n  \"sed\"                      |\r\n  \"select\"                   |\r\n  \"seq\"                      |\r\n  \"set\"                      |\r\n  \"sftp\"                     |\r\n  \"shift\"                    |\r\n  \"shopt\"                    |\r\n  \"shutdown\"                 |\r\n  \"sleep\"                    |\r\n  \"slocate\"                  |\r\n  \"sort\"                     |\r\n  \"source\"                   |\r\n  \"split\"                    |\r\n  \"ssh\"                      |\r\n  \"strace\"                   |\r\n  \"su\"                       |\r\n  \"sudo\"                     |\r\n  \"sum\"                      |\r\n  \"symlink\"                  |\r\n  \"sync\"                     |\r\n  \"tail\"                     |\r\n  \"tar\"                      |\r\n  \"tee\"                      |\r\n  \"test\"                     |\r\n  \"time\"                     |\r\n  \"times\"                    |\r\n  \"touch\"                    |\r\n  \"top\"                      |\r\n  \"traceroute\"               |\r\n  \"trap\"                     |\r\n  \"tr\"                       |\r\n  \"true\"                     |\r\n  \"tsort\"                    |\r\n  \"tty\"                      |\r\n  \"type\"                     |\r\n  \"ulimit\"                   |\r\n  \"umask\"                    |\r\n  \"umount\"                   |\r\n  \"unalias\"                  |\r\n  \"uname\"                    |\r\n  \"unexpand\"                 |\r\n  \"uniq\"                     |\r\n  \"units\"                    |\r\n  \"unset\"                    |\r\n  \"unshar\"                   |\r\n  \"useradd\"                  |\r\n  \"usermod\"                  |\r\n  \"users\"                    |\r\n  \"uuencode\"                 |\r\n  \"uudecode\"                 |\r\n  \"v\"                        |\r\n  \"vdir\"                     |\r\n  \"vi\"                       |\r\n  \"vmstat\"                   |\r\n  \"watch\"                    |\r\n  \"wc\"                       |\r\n  \"whereis\"                  |\r\n  \"which\"                    |\r\n  \"who\"                      |\r\n  \"whoami\"                   |\r\n  \"Wget\"                     |\r\n  \"write\"                    |\r\n  \"xargs\"                    |\r\n  \"yes\"                      { return token(TokenType.KEYWORD); }\r\n\r\n  {Identifier}               { return token(TokenType.IDENTIFIER); }\r\n\r\n  /* labels */\r\n  \":\" [a-zA-Z][a-zA-Z0-9_]*  { return token(TokenType.TYPE); }\r\n\r\n  /* comments */\r\n  {Shebang}                   { return token(TokenType.COMMENT2); }\r\n  {Comment}                   { return token(TokenType.COMMENT); }\r\n  . | {LineTerminator}        { /* skip */ }\r\n\r\n}\r\n\r\n<<EOF>>                          { return null; }"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/c.flex",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/*\n * Copyright 2006 Arnout Engelen <arnouten[remove] at bzzt dot net>.\n * Copyright 2000-2006 Omnicore Software, Hans Kratz & Dennis Strein GbR,\n *                     Geert Bevin <gbevin[remove] at uwyn dot com>.\n * Distributed under the terms of either:\n * - the common development and distribution license (CDDL), v1.0; or\n * - the GNU Lesser General Public License, v2.1 or later\n */\npackage jsyntaxpane.lexers;\n\nimport jsyntaxpane.DefaultLexer;\nimport jsyntaxpane.Token;\nimport jsyntaxpane.TokenType;\n\n%%\n\n%public\n%class CLexer\n%extends DefaultLexer\n%final\n%unicode\n%char\n%type Token\n\n\n%{\n\n    public CLexer() {\n        super();\n    }\n\n\tprivate Token token(TokenType type) {\n        return new Token(type, yychar, yylength());\n    }\n    \n    private Token token(TokenType type, int pairValue) {\n        return new Token(type, yychar, yylength(), (byte)pairValue);\n    }\n\n    private static final byte PARAN     = 1;\n    private static final byte BRACKET   = 2;\n    private static final byte CURLY     = 3;\n\n    // These will be used to store Token Start positions and length for Complex \n    // Tokens that need deifferent Lexer States, like STRING\n    int tokenStart;\n    int tokenLength;\n\n%}\n\n/* main character classes */\nLineTerminator = \\r|\\n|\\r\\n\nInputCharacter = [^\\r\\n]\n\nWhiteSpace = {LineTerminator} | [ \\t\\f]+\n\n/* comments */\nComment = {TraditionalComment} | {EndOfLineComment} \n\nTraditionalComment = \"/*\" [^*] ~\"*/\" | \"/*\" \"*\"+ \"/\"\nEndOfLineComment = \"//\" {InputCharacter}* {LineTerminator}?\n\n/* identifiers */\n\nConstantIdentifier = {SimpleConstantIdentifier}\nSimpleConstantIdentifier = [#A-Z0-9_]+\n\nIdentifier = [:jletter:][:jletterdigit:]*\n\nTypeIdentifier = {SimpleTypeIdentifier}\nSimpleTypeIdentifier = [A-Z][:jletterdigit:]*\n\n/* int literals */\n\nDecLiteral = 0 | [1-9][0-9]* {IntegerSuffix}\n\nHexLiteral    = 0 [xX] 0* {HexDigit}* {IntegerSuffix}\nHexDigit      = [0-9a-fA-F]\n\nOctLiteral    = 0+ {OctDigit}* {IntegerSuffix}\nOctDigit          = [0-7]\n\nIntegerSuffix = [uU]? [lL]? [uU]?\n\t\n/* float literals */\n\nFloatLiteral  = ({FLit1}|{FLit2}|{FLit3}|{FLit4}) ([fF]|[dD])?\n\nFLit1 = [0-9]+ \\. [0-9]* {Exponent}?\nFLit2 = \\. [0-9]+ {Exponent}?\nFLit3 = [0-9]+ {Exponent}\nFLit4 = [0-9]+ {Exponent}?\n\nExponent = [eE] [+\\-]? [0-9]+\n\n%%\n\n<YYINITIAL> {\n\n  /* keywords */\n  \"break\" |\n  \"case\" |\n  \"catch\" |\n  \"continue\" |\n  \"default\" |\n  \"do\" |\n  \"else\" |\n  \"for\" |\n  \"goto\" |\n  \"enum\" |\n  \"if\" |\n  \"inline\" |\n  \"mutable\" |\n  \"noinline\" |\n  \"return\" |\n  \"safecast\" |\n  \"sealed\" |\n  \"selectany\" |\n  \"sizeof\" |\n  \"static_cast\" |\n  \"switch\" |\n  \"template\" |\n  \"this\" |\n  \"thread\" |\n  \"throw\" |\n  \"try\" |\n  \"typedef\" |\n  \"typeid\" |\n  \"typename\" |\n  \"using\" |\n  \"uuid\" |\n  \"value\" |\n  \"virtual\" |\n  \"while\"\n     { return token(TokenType.KEYWORD); }\n     \n  \"static\" |\n  \"struct\" |\n  \"union\" |\n  \"volatile\" |\n  \"register\" |\n  \"extern\" |\n  \"const\" |\n  \"signed\" |\n  \"unsigned\" |\n  \"bool\" |\n  \"char\" |\n  \"double\" |\n  \"int\" |\n  \"long\" |\n  \"float\" |\n  \"short\" |\n  \"void\" { return token(TokenType.TYPE); }\n\n  /* literals */\n  \n\n  (\\\" ( [^\\\"\\n\\\\] | \\\\[^\\n] )* (\\n | \\\\\\n | \\\")) |\n  (\\' ( [^\\'\\n\\\\] | \\\\[^\\n] )* (\\n | \\\\\\n | \\')) \n \t{ return token(TokenType.STRING); }\n \t\n  \"true\" |\n  \"false\" |\n  {DecLiteral} |\n  {OctLiteral} |\n  {HexLiteral} |\n\n  {FloatLiteral}\n\t { return token(TokenType.NUMBER); }\n\n  /* preprocessor symbols */\n  \"#define\" |\n  \"#elif\" |\n  \"#else\" |\n  \"#endif\" |\n  \"#error\" |\n  \"#ifdef\" |\n  \"#ifndef\" |\n  \"#if\" |\n  \"#import\" |\n  \"#include\" |\n  \"#line\" |\n  \"#pragma\" |\n  \"#undef\" |\n  \"#using\"\n  \t{ return token(TokenType.KEYWORD2); }\n\n  \n  /* separators */\n  \"(\"                            { return token(TokenType.OPERATOR,  PARAN); }\n  \")\"                            { return token(TokenType.OPERATOR, -PARAN); }\n  \"{\"                            { return token(TokenType.OPERATOR,  CURLY); }\n  \"}\"                            { return token(TokenType.OPERATOR, -CURLY); }\n  \"[\"                            { return token(TokenType.OPERATOR,  BRACKET); }\n  \"]\"                            { return token(TokenType.OPERATOR, -BRACKET); }\n\n  /* operators */\n  \"=\" |\n  \";\" |\n  \",\" |\n  \".\" |\n  \">\" |\n  \"<\" |\n  \"!\" |\n  \"~\" |\n  \"?\" |\n  \":\" |\n  \"+\" |\n  \"-\" |\n  \"*\" |\n  \"/\" |\n  \"&\" |\n  \"|\" |\n  \"^\" |\n  \">>\"       |\n  \"<<\"       |\n  \"%\"                      { return token(TokenType.OPERATOR); }\n\n  {ConstantIdentifier}                    { return token(TokenType.IDENTIFIER); }\n\n  {TypeIdentifier}  { return token(TokenType.IDENTIFIER); }\n\n  \\n |\n  {Identifier} |\n  {WhiteSpace}                   { return token(TokenType.IDENTIFIER); }\n\n\n\n  {Comment}   \t{ return token(TokenType.COMMENT); }\n\n}\n\n\n\n/* error fallback */\n.|\\n                             {  }\n<<EOF>>                          { return null; }\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/clojure.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n \r\n%% \r\n\r\n%public\r\n%class ClojureLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n\r\n\r\n%{\r\n    /**\r\n     * Create an empty lexer, yyrset will be called later to reset and assign\r\n     * the reader\r\n     */\r\n    public ClojureLexer() {\r\n        super();\r\n    }\r\n\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n\r\n    private Token token(TokenType type, int pairValue) {\r\n        return new Token(type, yychar, yylength(), (byte)pairValue);\r\n    }\r\n\r\n    private static final byte PARAN     = 1;\r\n    private static final byte BRACKET   = 2;\r\n    private static final byte CURLY     = 3;\r\n\r\n%}\r\n\r\n/* main character classes */\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\n\r\nWhiteSpace = {LineTerminator} | [ \\t\\f]+\r\n\r\n/* comments */\r\nComment = {EndOfLineComment} \r\n\r\nEndOfLineComment = \";\" {InputCharacter}* {LineTerminator}?\r\n\r\n/* identifiers */\r\nIdentifier = [:jletter:][:jletterdigit:]*\r\n\r\n/* integer literals */\r\nDecIntegerLiteral = 0 | [1-9][0-9]*\r\nDecLongLiteral    = {DecIntegerLiteral} [lL]\r\n\r\nHexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8}\r\nHexLongLiteral    = 0 [xX] 0* {HexDigit} {1,16} [lL]\r\nHexDigit          = [0-9a-fA-F]\r\n\r\nOctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15}\r\nOctLongLiteral    = 0+ 1? {OctDigit} {1,21} [lL]\r\nOctDigit          = [0-7]\r\n    \r\n/* floating point literals */        \r\nFloatLiteral  = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF]\r\nDoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}?\r\n\r\nFLit1    = [0-9]+ \\. [0-9]* \r\nFLit2    = \\. [0-9]+ \r\nFLit3    = [0-9]+ \r\nExponent = [eE] [+-]? [0-9]+\r\n\r\n/* string and character literals */\r\nStringCharacter = [^\\r\\n\\\"\\\\]\r\nSingleCharacter = [^\\r\\n\\'\\\\]\r\n\r\n%state STRING, CHARLITERAL\r\n\r\n%%\r\n\r\n<YYINITIAL> {\r\n\r\n  /* keywords */\r\n  \"fn\"             |\r\n  \"fn*\"            |\r\n  \"if\"             |\r\n  \"def\"            |\r\n  \"let\"            |\r\n  \"let*\"           |\r\n  \"loop*\"          |\r\n  \"new\"            |\r\n  \"nil\"            |\r\n  \"recur\"          |\r\n  \"loop\"           |\r\n  \"do\"             |\r\n  \"quote\"          |\r\n  \"the-var\"        |\r\n  \"identical?\"     |\r\n  \"throw\"          |\r\n  \"set!\"           |\r\n  \"monitor-enter\"  |\r\n  \"monitor-exit\"   |\r\n  \"try\"            |\r\n  \"catch\"          |\r\n  \"finally\"        |\r\n  \"in-ns\"          { return token(TokenType.KEYWORD); }\r\n\r\n  /* Built-ins */\r\n  \"*agent*\"                   |\r\n  \"*command-line-args*\"       |\r\n  \"*in*\"                      |\r\n  \"*macro-meta*\"              |\r\n  \"*ns*\"                      |\r\n  \"*out*\"                     |\r\n  \"*print-meta*\"              |\r\n  \"*print-readably*\"          |\r\n  \"*proxy-classes*\"           |\r\n  \"*warn-on-reflection*\"      |\r\n  \"+\"                         |\r\n  \"-\"                         |\r\n  \"->\"                        |\r\n  \"..\"                        |\r\n  \"/\"                         |\r\n  \"<\"                         |\r\n  \"<=\"                        |\r\n  \"=\"                         |\r\n  \"==\"                        |\r\n  \">\"                         |\r\n  \">=\"                        |\r\n  \"accessor\"                  |\r\n  \"agent\"                     |\r\n  \"agent-errors\"              |\r\n  \"aget\"                      |\r\n  \"alength\"                   |\r\n  \"all-ns\"                    |\r\n  \"alter\"                     |\r\n  \"and\"                       |\r\n  \"apply\"                     |\r\n  \"array-map\"                 |\r\n  \"aset\"                      |\r\n  \"aset-boolean\"              |\r\n  \"aset-byte\"                 |\r\n  \"aset-char\"                 |\r\n  \"aset-double\"               |\r\n  \"aset-float\"                |\r\n  \"aset-int\"                  |\r\n  \"aset-long\"                 |\r\n  \"aset-short\"                |\r\n  \"assert\"                    |\r\n  \"assoc\"                     |\r\n  \"await\"                     |\r\n  \"await-for\"                 |\r\n  \"bean\"                      |\r\n  \"binding\"                   |\r\n  \"bit-and\"                   |\r\n  \"bit-not\"                   |\r\n  \"bit-or\"                    |\r\n  \"bit-shift-left\"            |\r\n  \"bit-shift-right\"           |\r\n  \"bit-xor\"                   |\r\n  \"boolean\"                   |\r\n  \"butlast\"                   |\r\n  \"byte\"                      |\r\n  \"cast\"                      |\r\n  \"char\"                      |\r\n  \"class\"                     |\r\n  \"clear-agent-errors\"        |\r\n  \"comment\"                   |\r\n  \"commute\"                   |\r\n  \"comp\"                      |\r\n  \"comparator\"                |\r\n  \"complement\"                |\r\n  \"concat\"                    |\r\n  \"cond\"                      |\r\n  \"conj\"                      |\r\n  \"cons\"                      |\r\n  \"constantly\"                |\r\n  \"construct-proxy\"           |\r\n  \"contains?\"                 |\r\n  \"count\"                     |\r\n  \"create-ns\"                 |\r\n  \"create-struct\"             |\r\n  \"cycle\"                     |\r\n  \"dec\"                       |\r\n  \"defmacro\"                  |\r\n  \"defmethod\"                 |\r\n  \"defmulti\"                  |\r\n  \"defn\"                      |\r\n  \"defn-\"                     |\r\n  \"defstruct\"                 |\r\n  \"deref\"                     |\r\n  \"destructure\"               |\r\n  \"disj\"                      |\r\n  \"dissoc\"                    |\r\n  \"distinct\"                  |\r\n  \"doall\"                     |\r\n  \"doc\"                       |\r\n  \"dorun\"                     |\r\n  \"doseq\"                     |\r\n  \"dosync\"                    |\r\n  \"dotimes\"                   |\r\n  \"doto\"                      |\r\n  \"double\"                    |\r\n  \"drop\"                      |\r\n  \"drop-while\"                |\r\n  \"ensure\"                    |\r\n  \"eval\"                      |\r\n  \"every?\"                    |\r\n  \"false?\"                    |\r\n  \"ffirst\"                    |\r\n  \"file-seq\"                  |\r\n  \"filter\"                    |\r\n  \"find\"                      |\r\n  \"find-doc\"                  |\r\n  \"find-ns\"                   |\r\n  \"find-var\"                  |\r\n  \"first\"                     |\r\n  \"float\"                     |\r\n  \"flush\"                     |\r\n  \"fnseq\"                     |\r\n  \"for\"                       |\r\n  \"frest\"                     |\r\n  \"gensym\"                    |\r\n  \"gen-class\"                 |\r\n  \"gen-interface\"             |\r\n  \"get\"                       |\r\n  \"get-proxy-class\"           |\r\n  \"hash-map\"                  |\r\n  \"hash-set\"                  |\r\n  \"identity\"                  |\r\n  \"if-let\"                    |\r\n  \"import\"                    |\r\n  \"inc\"                       |\r\n  \"instance?\"                 |\r\n  \"int\"                       |\r\n  \"interleave\"                |\r\n  \"into\"                      |\r\n  \"into-array\"                |\r\n  \"iterate\"                   |\r\n  \"key\"                       |\r\n  \"keys\"                      |\r\n  \"keyword\"                   |\r\n  \"keyword?\"                  |\r\n  \"last\"                      |\r\n  \"lazy-cat\"                  |\r\n  \"lazy-cons\"                 |\r\n  \"line-seq\"                  |\r\n  \"list\"                      |\r\n  \"list*\"                     |\r\n  \"load\"                      |\r\n  \"load-file\"                 |\r\n  \"locking\"                   |\r\n  \"long\"                      |\r\n  \"macroexpand\"               |\r\n  \"macroexpand-1\"             |\r\n  \"make-array\"                |\r\n  \"map\"                       |\r\n  \"map?\"                      |\r\n  \"mapcat\"                    |\r\n  \"max\"                       |\r\n  \"max-key\"                   |\r\n  \"memfn\"                     |\r\n  \"merge\"                     |\r\n  \"merge-with\"                |\r\n  \"meta\"                      |\r\n  \"min\"                       |\r\n  \"min-key\"                   |\r\n  \"name\"                      |\r\n  \"namespace\"                 |\r\n  \"neg?\"                      |\r\n  \"newline\"                   |\r\n  \"nil?\"                      |\r\n  \"not\"                       |\r\n  \"not-any?\"                  |\r\n  \"not-every?\"                |\r\n  \"not=\"                      |\r\n  \"ns-imports\"                |\r\n  \"ns-interns\"                |\r\n  \"ns-map\"                    |\r\n  \"ns-name\"                   |\r\n  \"ns-publics\"                |\r\n  \"ns-refers\"                 |\r\n  \"ns-resolve\"                |\r\n  \"ns-unmap\"                  |\r\n  \"nth\"                       |\r\n  \"nthrest\"                   |\r\n  \"or\"                        |\r\n  \"partial\"                   |\r\n  \"peek\"                      |\r\n  \"pmap\"                      |\r\n  \"pop\"                       |\r\n  \"pos?\"                      |\r\n  \"pr\"                        |\r\n  \"pr-str\"                    |\r\n  \"print\"                     |\r\n  \"print-doc\"                 |\r\n  \"print-str\"                 |\r\n  \"println\"                   |\r\n  \"println-str\"               |\r\n  \"prn\"                       |\r\n  \"prn-str\"                   |\r\n  \"proxy\"                     |\r\n  \"proxy-mappings\"            |\r\n  \"quot\"                      |\r\n  \"rand\"                      |\r\n  \"rand-int\"                  |\r\n  \"range\"                     |\r\n  \"re-find\"                   |\r\n  \"re-groups\"                 |\r\n  \"re-matcher\"                |\r\n  \"re-matches\"                |\r\n  \"re-pattern\"                |\r\n  \"re-seq\"                    |\r\n  \"read\"                      |\r\n  \"read-line\"                 |\r\n  \"reduce\"                    |\r\n  \"ref\"                       |\r\n  \"ref-set\"                   |\r\n  \"refer\"                     |\r\n  \"rem\"                       |\r\n  \"remove-method\"             |\r\n  \"remove-ns\"                 |\r\n  \"repeat\"                    |\r\n  \"replace\"                   |\r\n  \"replicate\"                 |\r\n  \"require\"                   |\r\n  \"resolve\"                   |\r\n  \"rest\"                      |\r\n  \"resultset-seq\"             |\r\n  \"reverse\"                   |\r\n  \"rfirst\"                    |\r\n  \"rrest\"                     |\r\n  \"rseq\"                      |\r\n  \"scan\"                      |\r\n  \"second\"                    |\r\n  \"select-keys\"               |\r\n  \"send\"                      |\r\n  \"send-off\"                  |\r\n  \"seq\"                       |\r\n  \"seq?\"                      |\r\n  \"set\"                       |\r\n  \"short\"                     |\r\n  \"slurp\"                     |\r\n  \"some\"                      |\r\n  \"sort\"                      |\r\n  \"sort-by\"                   |\r\n  \"sorted-map\"                |\r\n  \"sorted-map-by\"             |\r\n  \"sorted-set\"                |\r\n  \"special-symbol?\"           |\r\n  \"split-at\"                  |\r\n  \"split-with\"                |\r\n  \"str\"                       |\r\n  \"string?\"                   |\r\n  \"struct\"                    |\r\n  \"struct-map\"                |\r\n  \"subs\"                      |\r\n  \"subvec\"                    |\r\n  \"symbol\"                    |\r\n  \"symbol?\"                   |\r\n  \"sync\"                      |\r\n  \"take\"                      |\r\n  \"take-nth\"                  |\r\n  \"take-while\"                |\r\n  \"test\"                      |\r\n  \"time\"                      |\r\n  \"to-array\"                  |\r\n  \"to-array-2d\"               |\r\n  \"touch\"                     |\r\n  \"tree-seq\"                  |\r\n  \"true?\"                     |\r\n  \"update-proxy\"              |\r\n  \"val\"                       |\r\n  \"vals\"                      |\r\n  \"var-get\"                   |\r\n  \"var-set\"                   |\r\n  \"var?\"                      |\r\n  \"vector\"                    |\r\n  \"vector?\"                   |\r\n  \"when\"                      |\r\n  \"when-first\"                |\r\n  \"when-let\"                  |\r\n  \"when-not\"                  |\r\n  \"while\"                     |\r\n  \"with-local-vars\"           |\r\n  \"with-meta\"                 |\r\n  \"with-open\"                 |\r\n  \"with-out-str\"              |\r\n  \"xml-seq\"                   |\r\n  \"zero?\"                     |\r\n  \"zipmap\"                    |\r\n  \"repeatedly\"                |\r\n  \"add-classpath\"             |\r\n  \"vec\"                       |\r\n  \"hash\"                      { return token(TokenType.KEYWORD2); }\r\n\r\n\r\n  /* operators */\r\n\r\n  \"(\"                            { return token(TokenType.OPERATOR,  PARAN); }\r\n  \")\"                            { return token(TokenType.OPERATOR, -PARAN); }\r\n  \"{\"                            { return token(TokenType.OPERATOR,  CURLY); }\r\n  \"}\"                            { return token(TokenType.OPERATOR, -CURLY); }\r\n  \"[\"                            { return token(TokenType.OPERATOR,  BRACKET); }\r\n  \"]\"                            { return token(TokenType.OPERATOR, -BRACKET); }\r\n  \r\n  /* string literal */\r\n  \\\"                             {  \r\n                                    yybegin(STRING); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 1; \r\n                                 }\r\n\r\n  /* character literal */\r\n  \\'                             {  \r\n                                    yybegin(CHARLITERAL); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 1; \r\n                                 }\r\n\r\n  /* numeric literals */\r\n\r\n  {DecIntegerLiteral}            |\r\n  {DecLongLiteral}               |\r\n  \r\n  {HexIntegerLiteral}            |\r\n  {HexLongLiteral}               |\r\n \r\n  {OctIntegerLiteral}            |\r\n  {OctLongLiteral}               |\r\n  \r\n  {FloatLiteral}                 |\r\n  {DoubleLiteral}                |\r\n  {DoubleLiteral}[dD]            { return token(TokenType.NUMBER); }\r\n  \r\n  /* comments */\r\n  {Comment}                      { return token(TokenType.COMMENT); }\r\n\r\n  /* whitespace */\r\n  {WhiteSpace}                   { }\r\n\r\n  /* identifiers */ \r\n  {Identifier}                   { return token(TokenType.IDENTIFIER); }\r\n}\r\n\r\n\r\n<STRING> {\r\n  \\\"                             { \r\n                                     yybegin(YYINITIAL); \r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 1);\r\n                                 }\r\n  \r\n  {StringCharacter}+             { tokenLength += yylength(); }\r\n\r\n  \\\\[0-3]?{OctDigit}?{OctDigit}  { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n}\r\n\r\n<CHARLITERAL> {\r\n  \\'                             { \r\n                                     yybegin(YYINITIAL); \r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 1);\r\n                                 }\r\n  \r\n  {SingleCharacter}+             { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n}\r\n\r\n/* error fallback */\r\n.|\\n                             {  }\r\n<<EOF>>                          { return null; }\r\n\r\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/cpp.flex",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/*\n * Copyright 2006 Arnout Engelen <arnouten[remove] at bzzt dot net>.\n * Copyright 2000-2006 Omnicore Software, Hans Kratz & Dennis Strein GbR,\n *                     Geert Bevin <gbevin[remove] at uwyn dot com>.\n * Distributed under the terms of either:\n * - the common development and distribution license (CDDL), v1.0; or\n * - the GNU Lesser General Public License, v2.1 or later\n */\npackage jsyntaxpane.lexers;\n\nimport jsyntaxpane.DefaultLexer;\nimport jsyntaxpane.Token;\nimport jsyntaxpane.TokenType;\n\n%%\n\n%public\n%class CppLexer\n%extends DefaultLexer\n%final\n%unicode\n%char\n%type Token\n\n\n%{\n\n    public CppLexer() {\n        super();\n    }\n\n\tprivate Token token(TokenType type) {\n        return new Token(type, yychar, yylength());\n    }\n    \n    private Token token(TokenType type, int pairValue) {\n        return new Token(type, yychar, yylength(), (byte)pairValue);\n    }\n\n    private static final byte PARAN     = 1;\n    private static final byte BRACKET   = 2;\n    private static final byte CURLY     = 3;\n\n    // These will be used to store Token Start positions and length for Complex \n    // Tokens that need deifferent Lexer States, like STRING\n    int tokenStart;\n    int tokenLength;\n\n%}\n\n/* main character classes */\nLineTerminator = \\r|\\n|\\r\\n\nInputCharacter = [^\\r\\n]\n\n/* comments */\nComment = {TraditionalComment} | {EndOfLineComment} \n\nTraditionalComment = \"/*\" [^*] ~\"*/\" | \"/*\" \"*\"+ \"/\"\nEndOfLineComment = \"//\" {InputCharacter}* {LineTerminator}?\n\n/* identifiers */\n\nConstantIdentifier = {SimpleConstantIdentifier}\nSimpleConstantIdentifier = [#A-Z0-9_]+\n\nIdentifier = [:jletter:][:jletterdigit:]*\n\n/* int literals */\n\nDecLiteral = 0 | [1-9][0-9]* {IntegerSuffix}\n\nHexLiteral    = 0 [xX] 0* {HexDigit}* {IntegerSuffix}\nHexDigit      = [0-9a-fA-F]\n\nOctLiteral    = 0+ {OctDigit}* {IntegerSuffix}\nOctDigit          = [0-7]\n\nIntegerSuffix = [uU]? [lL]? [uU]?\n\t\n/* float literals */\n\nFloatLiteral  = ({FLit1}|{FLit2}|{FLit3}|{FLit4}) ([fF]|[dD])?\n\nFLit1 = [0-9]+ \\. [0-9]* {Exponent}?\nFLit2 = \\. [0-9]+ {Exponent}?\nFLit3 = [0-9]+ {Exponent}\nFLit4 = [0-9]+ {Exponent}?\n\nExponent = [eE] [+\\-]? [0-9]+\n\n%%\n\n<YYINITIAL> {\n\n  /* keywords */\n  \"break\" |\n  \"case\" |\n  \"catch\" |\n  \"continue\" |\n  \"default\" |\n  \"do\" |\n  \"else\" |\n  \"for\" |\n  \"goto\" |\n  \"enum\" |\n  \"if\" |\n  \"inline\" |\n  \"mutable\" |\n  \"noinline\" |\n  \"return\" |\n  \"safecast\" |\n  \"sealed\" |\n  \"selectany\" |\n  \"sizeof\" |\n  \"static_cast\" |\n  \"switch\" |\n  \"template\" |\n  \"this\" |\n  \"thread\" |\n  \"throw\" |\n  \"try\" |\n  \"typedef\" |\n  \"typeid\" |\n  \"typename\" |\n  \"using\" |\n  \"uuid\" |\n  \"value\" |\n  \"virtual\" |\n  \"while\" |\n  /* C++ Keywords */\n  \"new\"       |\n  \"delete\"    |\n  \"this\"      |\n  \"friend\"    |\n  \"using\"     |\n  \"throw\"     |\n  \"try\"       |\n  \"catch\"     |\n  \"class\"     |\n  \"typename\"  |\n  \"template\"  |\n  \"namespace\" \n     { return token(TokenType.KEYWORD); }\n     \n  \"static\" |\n  \"struct\" |\n  \"union\" |\n  \"volatile\" |\n  \"register\" |\n  \"extern\" |\n  \"const\" |\n  \"signed\" |\n  \"unsigned\" |\n  \"bool\" |\n  \"char\" |\n  \"double\" |\n  \"int\" |\n  \"long\" |\n  \"float\" |\n  \"short\" |\n  \"void\" |\n\n  \"public\"     |\n  \"protected\"  |\n  \"private\"    |\n  \"virtual\"    |\n  \"inline\"     |\n  \"virtual\"    |\n  \"explicit\"   |\n  \"export\"     |\n  \"bool\"       |\n  \"wchar_t\"\n  { return token(TokenType.TYPE); }\n\n  /* literals */\n  \n\n  (\\\" ( [^\\\"\\n\\\\] | \\\\[^\\n] )* (\\n | \\\\\\n | \\\")) |\n  (\\' ( [^\\'\\n\\\\] | \\\\[^\\n] )* (\\n | \\\\\\n | \\')) \n \t{ return token(TokenType.STRING); }\n \t\n  \"true\" |\n  \"false\" |\n  {DecLiteral} |\n  {OctLiteral} |\n  {HexLiteral} |\n\n  {FloatLiteral}\n\t { return token(TokenType.NUMBER); }\n\n  /* preprocessor symbols */\n  \"#define\" |\n  \"#elif\" |\n  \"#else\" |\n  \"#endif\" |\n  \"#error\" |\n  \"#ifdef\" |\n  \"#ifndef\" |\n  \"#if\" |\n  \"#import\" |\n  \"#include\" |\n  \"#line\" |\n  \"#pragma\" |\n  \"#undef\" |\n  \"#using\"\n  \t{ return token(TokenType.KEYWORD2); }\n\n  \n  /* separators */\n  \"(\"                            { return token(TokenType.OPERATOR,  PARAN); }\n  \")\"                            { return token(TokenType.OPERATOR, -PARAN); }\n  \"{\"                            { return token(TokenType.OPERATOR,  CURLY); }\n  \"}\"                            { return token(TokenType.OPERATOR, -CURLY); }\n  \"[\"                            { return token(TokenType.OPERATOR,  BRACKET); }\n  \"]\"                            { return token(TokenType.OPERATOR, -BRACKET); }\n\n  /* operators */\n  \"=\" |\n  \";\" |\n  \",\" |\n  \".\" |\n  \">\" |\n  \"<\" |\n  \"!\" |\n  \"~\" |\n  \"?\" |\n  \":\" |\n  \"+\" |\n  \"-\" |\n  \"*\" |\n  \"/\" |\n  \"&\" |\n  \"|\" |\n  \"^\" |\n  \"%\" |\n  \">>\"       |\n  \"<<\"       |\n  \"operator\" |\n  \"typeid\"   |\n  \"and\"      |\n  \"bitor\"    |\n  \"or\"       |\n  \"xor\"      |\n  \"compl\"    |\n  \"bitand\"   |\n  \"and_eq\"   |\n  \"or_eq\"    |\n  \"xor_eq\"   |\n  \"not\"      |\n  \"not_eq\"\n                     { return token(TokenType.OPERATOR); }\n\n  /** C++ standard and built-in objects */\n  \"cin\"  |\n  \"cout\"\n  { return token(TokenType.TYPE2); }\n\n  {ConstantIdentifier}     { return token(TokenType.TYPE); }\n\n  {Identifier}             { return token(TokenType.IDENTIFIER); }\n\n  {Comment}   \t           { return token(TokenType.COMMENT); }\n}\n\n\n\n/* error fallback */\n.|\\n                             {  }\n<<EOF>>                          { return null; }\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/dosbatch.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n\r\n%%\r\n\r\n%public\r\n%class DOSBatchLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n%ignorecase\r\n\r\n\r\n%{\r\n    /**\r\n     * Create an empty lexer, yyrset will be called later to reset and assign\r\n     * the reader\r\n     */\r\n    public DOSBatchLexer() {\r\n        super();\r\n    }\r\n\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n%}\r\n\r\nStartComment = rem\r\nWhiteSpace = [ \\t]\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\nKeyCharacter = [a-zA-Z0-9._ ]\r\n\r\nComment = \"rem\" {InputCharacter}* {LineTerminator}?\r\n\r\n%%\r\n\r\n<YYINITIAL> \r\n{\r\n  /* DOS keywords */\r\n  \"@\"                           |\r\n  \"echo\"                        |\r\n  \"goto\"                        |\r\n  \"call\"                        |\r\n  \"exit\"                        |\r\n  \"if\"                          |\r\n  \"else\"                        |\r\n  \"for\"                         |\r\n  \"copy\"                        |\r\n  \"set\"                         |\r\n  \"dir\"                         |\r\n  \"cd\"                          |\r\n  \"set\"                         |\r\n  \"errorlevel\"                  { return token(TokenType.KEYWORD); }\r\n\r\n  /* DOS commands */\r\n  \"append\"     |\r\n  \"assoc\"      |\r\n  \"at\"         |\r\n  \"attrib\"     |\r\n  \"break\"      |\r\n  \"cacls\"      |\r\n  \"cd\"         |\r\n  \"chcp\"       |\r\n  \"chdir\"      |\r\n  \"chkdsk\"     |\r\n  \"chkntfs\"    |\r\n  \"cls\"        |\r\n  \"cmd\"        |\r\n  \"color\"      |\r\n  \"comp\"       |\r\n  \"compact\"    |\r\n  \"convert\"    |\r\n  \"copy\"       |\r\n  \"date\"       |\r\n  \"del\"        |\r\n  \"dir\"        |\r\n  \"diskcomp\"   |\r\n  \"diskcopy\"   |\r\n  \"doskey\"     |\r\n  \"echo\"       |\r\n  \"endlocal\"   |\r\n  \"erase\"      |\r\n  \"fc\"         |\r\n  \"find\"       |\r\n  \"findstr\"    |\r\n  \"format\"     |\r\n  \"ftype\"      |\r\n  \"graftabl\"   |\r\n  \"help\"       |\r\n  \"keyb\"       |\r\n  \"label\"      |\r\n  \"md\"         |\r\n  \"mkdir\"      |\r\n  \"mode\"       |\r\n  \"more\"       |\r\n  \"move\"       |\r\n  \"path\"       |\r\n  \"pause\"      |\r\n  \"popd\"       |\r\n  \"print\"      |\r\n  \"prompt\"     |\r\n  \"pushd\"      |\r\n  \"rd\"         |\r\n  \"recover\"    |\r\n  \"rem\"        |\r\n  \"ren\"        |\r\n  \"rename\"     |\r\n  \"replace\"    |\r\n  \"restore\"    |\r\n  \"rmdir\"      |\r\n  \"set\"        |\r\n  \"setlocal\"   |\r\n  \"shift\"      |\r\n  \"sort\"       |\r\n  \"start\"      |\r\n  \"subst\"      |\r\n  \"time\"       |\r\n  \"title\"      |\r\n  \"tree\"       |\r\n  \"type\"       |\r\n  \"ver\"        |\r\n  \"verify\"     |\r\n  \"vol\"        |\r\n  \"xcopy\"      { return token(TokenType.KEYWORD); }\r\n\r\n\r\n  /* labels */\r\n  \":\" [a-zA-Z][a-zA-Z0-9_]*     { return token(TokenType.TYPE); }\r\n\r\n  /* comments */\r\n  {Comment}                      { return token(TokenType.COMMENT); }\r\n  . | {LineTerminator}           { /* skip */ }\r\n}\r\n\r\n<<EOF>>                          { return null; }"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/groovy.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n\r\n%%\r\n\r\n%public\r\n%class GroovyLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n\r\n\r\n%{\r\n    /**\r\n     * Default constructor is needed as we will always call the yyreset\r\n     */\r\n    public GroovyLexer() {\r\n        super();\r\n    }\r\n\r\n    /**\r\n     * Helper method to create and return a new Token of TokenType\r\n     */\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n\r\n    private Token token(TokenType type, int pairValue) {\r\n        return new Token(type, yychar, yylength(), (byte)pairValue);\r\n    }\r\n\r\n    private static final byte PARAN     = 1;\r\n    private static final byte BRACKET   = 2;\r\n    private static final byte CURLY     = 3;\r\n%}\r\n\r\n/* main character classes */\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\n\r\nWhiteSpace = {LineTerminator} | [ \\t\\f]\r\n\r\n/* comments */\r\nComment = {TraditionalComment} | {EndOfLineComment} \r\n\r\nTraditionalComment = \"/*\" [^*] ~\"*/\" | \"/*\" \"*\"+ \"/\"\r\nEndOfLineComment = \"//\" {InputCharacter}* {LineTerminator}?\r\n\r\n/* identifiers */\r\nIdentifier = [:jletter:][:jletterdigit:]*\r\n\r\n/* Groovy and generally Java types have first UpperCase Letter */\r\n// Type = [:uppercase:][:jletterdigit:]*\r\n\r\n/* integer literals */\r\nDecIntegerLiteral = 0 | [1-9][0-9]*\r\nDecLongLiteral    = {DecIntegerLiteral} [lL]\r\n\r\nHexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8}\r\nHexLongLiteral    = 0 [xX] 0* {HexDigit} {1,16} [lL]\r\nHexDigit          = [0-9a-fA-F]\r\n\r\nOctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15}\r\nOctLongLiteral    = 0+ 1? {OctDigit} {1,21} [lL]\r\nOctDigit          = [0-7]\r\n    \r\n/* floating point literals */        \r\nFloatLiteral  = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF]\r\nDoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}?\r\n\r\nFLit1    = [0-9]+ \\. [0-9]* \r\nFLit2    = \\. [0-9]+ \r\nFLit3    = [0-9]+ \r\nExponent = [eE] [+-]? [0-9]+\r\n\r\n/* string and character literals */\r\nStringCharacter = [^\\r\\n\\\"\\\\\\$]\r\nSingleCharacter = [^\\r\\n\\'\\\\]\r\nRegexCharacter  = [^\\r\\n\\/]\r\n\r\n%state STRING, CHARLITERAL, REGEX, GSTRING_EXPR, CHARLITERAL, JDOC, JDOC_TAG\r\n%state ML_STRING, ML_STRING_EXPR\r\n\r\n%%\r\n\r\n<YYINITIAL> {\r\n\r\n  /* keywords */\r\n  \"abstract\"                     |\r\n  \"boolean\"                      |\r\n  \"break\"                        |\r\n  \"byte\"                         |\r\n  \"case\"                         |\r\n  \"catch\"                        |\r\n  \"char\"                         |\r\n  \"class\"                        |\r\n  \"const\"                        |\r\n  \"continue\"                     |\r\n  \"do\"                           |\r\n  \"double\"                       |\r\n  \"enum\"                         |\r\n  \"else\"                         |\r\n  \"extends\"                      |\r\n  \"final\"                        |\r\n  \"finally\"                      |\r\n  \"float\"                        |\r\n  \"for\"                          |\r\n  \"default\"                      |\r\n  \"implements\"                   |\r\n  \"import\"                       |\r\n  \"instanceof\"                   |\r\n  \"int\"                          |\r\n  \"interface\"                    |\r\n  \"long\"                         |\r\n  \"native\"                       |\r\n  \"new\"                          |\r\n  \"goto\"                         |\r\n  \"if\"                           |\r\n  \"public\"                       |\r\n  \"short\"                        |\r\n  \"super\"                        |\r\n  \"switch\"                       |\r\n  \"synchronized\"                 |\r\n  \"package\"                      |\r\n  \"private\"                      |\r\n  \"protected\"                    |\r\n  \"transient\"                    |\r\n  \"return\"                       |\r\n  \"void\"                         |\r\n  \"static\"                       |\r\n  \"while\"                        |\r\n  \"this\"                         |\r\n  \"throw\"                        |\r\n  \"throws\"                       |\r\n  \"try\"                          |\r\n  \"volatile\"                     |\r\n  \"strictfp\"                     |\r\n\r\n  /* Groovy reserved words not in Java */\r\n  \"as\"                           |\r\n  \"asssert\"                      | \r\n  \"def\"                          |\r\n  \"in\"                           |\r\n  \"threadsafe\"                   |\r\n\r\n  /* Booleans and null */\r\n  \"true\"                         |\r\n  \"false\"                        |\r\n  \"null\"                         { return token(TokenType.KEYWORD); }\r\n\r\n\r\n  /* Builtin Types and Object Wrappers */\r\n  \"Boolean\"                      |\r\n  \"Byte\"                         |\r\n  \"Character\"                    |\r\n  \"Double\"                       |\r\n  \"Float\"                        |\r\n  \"Integer\"                      |\r\n  \"Object\"                       |\r\n  \"Short\"                        |\r\n  \"String\"                       |\r\n  \"Void\"                         |\r\n  \"Class\"                        |\r\n  \"Number\"                       |\r\n  \"Package\"                      |\r\n  \"StringBuffer\"                 |\r\n  \"StringBuilder\"                |\r\n  \"CharSequence\"                 |\r\n  \"Thread\"                       |\r\n  \"Regex\"                        { return token(TokenType.TYPE); }\r\n  \r\n  /* Some Java standard Library Types */\r\n  \"Throwable\"                    |\r\n  \"Cloneable\"                    |\r\n  \"Comparable\"                   |\r\n  \"Serializable\"                 |\r\n  \"Runnable\"                     { return token(TokenType.TYPE); }\r\n\r\n  /* Groovy commonly used methods */\r\n  \"print\"                        |\r\n  \"println\"                      { return token(TokenType.KEYWORD); }\r\n\r\n  /* Frequently used Standard Exceptions */\r\n  \"ArithmeticException\"              |\r\n  \"ArrayIndexOutOfBoundsException\"   |\r\n  \"ClassCastException\"               |\r\n  \"ClassNotFoundException\"           |\r\n  \"CloneNotSupportedException\"       |\r\n  \"Exception\"                        |\r\n  \"IllegalAccessException\"           |\r\n  \"IllegalArgumentException\"         |\r\n  \"IllegalStateException\"            |\r\n  \"IllegalThreadStateException\"      |\r\n  \"IndexOutOfBoundsException\"        |\r\n  \"InstantiationException\"           |\r\n  \"InterruptedException\"             |\r\n  \"NegativeArraySizeException\"       |\r\n  \"NoSuchFieldException\"             |\r\n  \"NoSuchMethodException\"            |\r\n  \"NullPointerException\"             |\r\n  \"NumberFormatException\"            |\r\n  \"RuntimeException\"                 |\r\n  \"SecurityException\"                |\r\n  \"StringIndexOutOfBoundsException\"  |\r\n  \"UnsupportedOperationException\"    { return token(TokenType.TYPE2); }\r\n\r\n  /* operators */\r\n  \"(\"                            { return token(TokenType.OPERATOR,  PARAN); }\r\n  \")\"                            { return token(TokenType.OPERATOR, -PARAN); }\r\n  \"{\"                            { return token(TokenType.OPERATOR,  CURLY); }\r\n  \"}\"                            { return token(TokenType.OPERATOR, -CURLY); }\r\n  \"[\"                            { return token(TokenType.OPERATOR,  BRACKET); }\r\n  \"]\"                            { return token(TokenType.OPERATOR, -BRACKET); }\r\n\r\n  \";\"                            | \r\n  \",\"                            | \r\n  \".\"                            | \r\n  \"@\"                            | \r\n  \"=\"                            | \r\n  \">\"                            | \r\n  \"<\"                            |\r\n  \"!\"                            | \r\n  \"~\"                            | \r\n  \"?\"                            | \r\n  \":\"                            | \r\n  \"==\"                           | \r\n  \"<=\"                           | \r\n  \">=\"                           | \r\n  \"!=\"                           | \r\n  \"&&\"                           | \r\n  \"||\"                           | \r\n  \"++\"                           | \r\n  \"--\"                           | \r\n  \"+\"                            | \r\n  \"-\"                            | \r\n  \"*\"                            | \r\n  \"/\"                            | \r\n  \"&\"                            | \r\n  \"|\"                            | \r\n  \"^\"                            | \r\n  \"%\"                            | \r\n  \"<<\"                           | \r\n  \">>\"                           | \r\n  \">>>\"                          | \r\n  \"+=\"                           | \r\n  \"-=\"                           | \r\n  \"*=\"                           | \r\n  \"/=\"                           | \r\n  \"&=\"                           | \r\n  \"|=\"                           | \r\n  \"^=\"                           | \r\n  \"%=\"                           | \r\n  \"<<=\"                          | \r\n  \">>=\"                          | \r\n  \">>>=\"                         { return token(TokenType.OPERATOR); }\r\n\r\n  \"~=\"                           | \r\n  \"?.\"                           { return token(TokenType.OPERATOR); } \r\n\r\n  /* string literal */\r\n  \\\"{3}                          {\r\n                                    yybegin(ML_STRING);\r\n                                    tokenStart = yychar;\r\n                                    tokenLength = 3;\r\n                                 }\r\n\r\n  /* string literal */\r\n  \\\"                             {  \r\n                                    yybegin(STRING); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 1; \r\n                                 }\r\n\r\n  /* character literal */\r\n  \\'                             {  \r\n                                    yybegin(CHARLITERAL); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 1; \r\n                                 }\r\n\r\n  /* numeric literals */\r\n\r\n  {DecIntegerLiteral}            |\r\n  {DecLongLiteral}               |\r\n  \r\n  {HexIntegerLiteral}            |\r\n  {HexLongLiteral}               |\r\n \r\n  {OctIntegerLiteral}            |\r\n  {OctLongLiteral}               |\r\n  \r\n  {FloatLiteral}                 |\r\n  {DoubleLiteral}                |\r\n  {DoubleLiteral}[dD]            { return token(TokenType.NUMBER); }\r\n  \r\n  // JavaDoc comments need a state so that we can highlight the @ controls\r\n  \"/**\"                          {\r\n                                    yybegin(JDOC);\r\n                                    tokenStart = yychar;\r\n                                    tokenLength = 3;\r\n                                 }\r\n\r\n  /* comments */\r\n  {Comment}                      { return token(TokenType.COMMENT); }\r\n\r\n  /* whitespace */\r\n  {WhiteSpace}+                  { /* skip */ }\r\n\r\n  /* identifiers */ \r\n  {Identifier}                   { return token(TokenType.IDENTIFIER); }\r\n\r\n  /*\r\n     Groovy Regex -- state cannot be easily used here due to / by itself being\r\n     a valid operator.  So if we flip into the REGEX state, we cannot distinguish\r\n     a regular /\r\n  */\r\n  \"/\" [^*] {RegexCharacter}+ \"/\"  { return token(TokenType.REGEX); }\r\n\r\n}\r\n\r\n\r\n<STRING> {\r\n\r\n  \\\"                             { \r\n                                    yybegin(YYINITIAL); \r\n                                    // length also includes the trailing quote\r\n                                    return new Token(TokenType.STRING, tokenStart, tokenLength + 1);\r\n                                 }\r\n\r\n  \"${\"                           { \r\n                                    yybegin(GSTRING_EXPR); \r\n                                    // length also includes the trailing quote\r\n                                    int s = tokenStart;\r\n                                    int l = tokenLength;\r\n                                    tokenStart = yychar;\r\n                                    tokenLength = 2;\r\n                                    return new Token(TokenType.STRING, s, l);\r\n                                 }\r\n  \r\n  {StringCharacter}+             { tokenLength += yylength(); }\r\n\r\n  \\\\[0-3]?{OctDigit}?{OctDigit}  { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n\r\n}\r\n\r\n<GSTRING_EXPR> {\r\n    \"}\"                          { \r\n                                    yybegin(STRING); \r\n                                    // length also includes the trailing quote\r\n                                    int s = tokenStart;\r\n                                    int l = tokenLength + 1;\r\n                                    tokenStart = yychar + 1;\r\n                                    tokenLength = 0;\r\n                                    return new Token(TokenType.STRING2, s, l);\r\n                                 }\r\n\r\n  {StringCharacter}              { tokenLength ++; }\r\n}\r\n\r\n<ML_STRING> {\r\n\r\n  \\\"{3}                          {\r\n                                    yybegin(YYINITIAL);\r\n                                    // length also includes the trailing quote\r\n                                    return new Token(TokenType.STRING, tokenStart, tokenLength + 3);\r\n                                 }\r\n\r\n  \"${\"                           {\r\n                                    yybegin(ML_STRING_EXPR);\r\n                                    // length also includes the trailing quote\r\n                                    int s = tokenStart;\r\n                                    int l = tokenLength;\r\n                                    tokenStart = yychar;\r\n                                    tokenLength = 2;\r\n                                    return new Token(TokenType.STRING, s, l);\r\n                                 }\r\n\r\n  \\\\[0-3]?{OctDigit}?{OctDigit}  { tokenLength += yylength(); }\r\n\r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  .|{LineTerminator}             { tokenLength += yylength(); }\r\n\r\n}\r\n\r\n<ML_STRING_EXPR> {\r\n    \"}\"                          {\r\n                                    yybegin(ML_STRING);\r\n                                    // length also includes the trailing quote\r\n                                    int s = tokenStart;\r\n                                    int l = tokenLength + 1;\r\n                                    tokenStart = yychar + 1;\r\n                                    tokenLength = 0;\r\n                                    return new Token(TokenType.STRING2, s, l);\r\n                                 }\r\n\r\n  .|\\n|\\r                        { tokenLength ++; }\r\n}\r\n\r\n<CHARLITERAL> {\r\n  \\'                             { \r\n                                     yybegin(YYINITIAL); \r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 1);\r\n                                 }\r\n  \r\n  {SingleCharacter}+             { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n}\r\n\r\n<JDOC> {\r\n  \"*/\"                           {\r\n                                     yybegin(YYINITIAL);\r\n                                     return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2);\r\n                                 }\r\n\r\n  \"@\"                            {\r\n                                     yybegin(JDOC_TAG);\r\n                                     int start = tokenStart;\r\n                                     tokenStart = yychar;\r\n                                     int len = tokenLength;\r\n                                     tokenLength = 1;\r\n                                     return new Token(TokenType.COMMENT, start, len);\r\n                                 }\r\n\r\n  .|\\n                           { tokenLength ++; }\r\n\r\n}\r\n\r\n<JDOC_TAG> {\r\n  ([:letter:])+ \":\"?             { tokenLength += yylength(); }\r\n\r\n  \"*/\"                           {\r\n                                     yybegin(YYINITIAL);\r\n                                     return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2);\r\n                                 }\r\n\r\n  .|\\n                           {\r\n                                     yybegin(JDOC);\r\n                                     // length also includes the trailing quote\r\n                                     int start = tokenStart;\r\n                                     tokenStart = yychar;\r\n                                     int len = tokenLength;\r\n                                     tokenLength = 1;\r\n                                     return new Token(TokenType.COMMENT2, start, len);\r\n                                 }\r\n}\r\n\r\n<REGEX> {\r\n  \"/\"                            { \r\n                                     yybegin(YYINITIAL); \r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.REGEX, tokenStart, tokenLength + 1);\r\n                                 }\r\n  \r\n  {RegexCharacter}+             { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n}\r\n\r\n/* error fallback */\r\n.|\\n                             {  }\r\n<<EOF>>                          { return null; }\r\n\r\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/java.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n \r\n%% \r\n\r\n%public\r\n%class JavaLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n\r\n\r\n%{\r\n    /**\r\n     * Create an empty lexer, yyrset will be called later to reset and assign\r\n     * the reader\r\n     */\r\n    public JavaLexer() {\r\n        super();\r\n    }\r\n\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n\r\n    private Token token(TokenType type, int pairValue) {\r\n        return new Token(type, yychar, yylength(), (byte)pairValue);\r\n    }\r\n\r\n    private static final byte PARAN     = 1;\r\n    private static final byte BRACKET   = 2;\r\n    private static final byte CURLY     = 3;\r\n\r\n%}\r\n\r\n/* main character classes */\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\n\r\nWhiteSpace = {LineTerminator} | [ \\t\\f]+\r\n\r\n/* comments */\r\nComment = {TraditionalComment} | {EndOfLineComment} \r\n\r\nTraditionalComment = \"/*\" [^*] ~\"*/\" | \"/*\" \"*\"+ \"/\"\r\nEndOfLineComment = \"//\" {InputCharacter}* {LineTerminator}?\r\n\r\n/* identifiers */\r\nIdentifier = [:jletter:][:jletterdigit:]*\r\n\r\n/* integer literals */\r\nDecIntegerLiteral = 0 | [1-9][0-9]*\r\nDecLongLiteral    = {DecIntegerLiteral} [lL]\r\n\r\nHexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8}\r\nHexLongLiteral    = 0 [xX] 0* {HexDigit} {1,16} [lL]\r\nHexDigit          = [0-9a-fA-F]\r\n\r\nOctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15}\r\nOctLongLiteral    = 0+ 1? {OctDigit} {1,21} [lL]\r\nOctDigit          = [0-7]\r\n    \r\n/* floating point literals */        \r\nFloatLiteral  = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF]\r\nDoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}?\r\n\r\nFLit1    = [0-9]+ \\. [0-9]* \r\nFLit2    = \\. [0-9]+ \r\nFLit3    = [0-9]+ \r\nExponent = [eE] [+-]? [0-9]+\r\n\r\n/* string and character literals */\r\nStringCharacter = [^\\r\\n\\\"\\\\]\r\nSingleCharacter = [^\\r\\n\\'\\\\]\r\n\r\n%state STRING, CHARLITERAL, JDOC, JDOC_TAG\r\n\r\n%%\r\n\r\n<YYINITIAL> {\r\n\r\n  /* keywords */\r\n  \"abstract\"                     |\r\n  \"boolean\"                      |\r\n  \"break\"                        |\r\n  \"byte\"                         |\r\n  \"case\"                         |\r\n  \"catch\"                        |\r\n  \"char\"                         |\r\n  \"class\"                        |\r\n  \"const\"                        |\r\n  \"continue\"                     |\r\n  \"do\"                           |\r\n  \"double\"                       |\r\n  \"enum\"                         |\r\n  \"else\"                         |\r\n  \"extends\"                      |\r\n  \"final\"                        |\r\n  \"finally\"                      |\r\n  \"float\"                        |\r\n  \"for\"                          |\r\n  \"default\"                      |\r\n  \"implements\"                   |\r\n  \"import\"                       |\r\n  \"instanceof\"                   |\r\n  \"int\"                          |\r\n  \"interface\"                    |\r\n  \"long\"                         |\r\n  \"native\"                       |\r\n  \"new\"                          |\r\n  \"goto\"                         |\r\n  \"if\"                           |\r\n  \"public\"                       |\r\n  \"short\"                        |\r\n  \"super\"                        |\r\n  \"switch\"                       |\r\n  \"synchronized\"                 |\r\n  \"package\"                      |\r\n  \"private\"                      |\r\n  \"protected\"                    |\r\n  \"transient\"                    |\r\n  \"return\"                       |\r\n  \"void\"                         |\r\n  \"static\"                       |\r\n  \"while\"                        |\r\n  \"this\"                         |\r\n  \"throw\"                        |\r\n  \"throws\"                       |\r\n  \"try\"                          |\r\n  \"volatile\"                     |\r\n  \"strictfp\"                     |\r\n  \r\n  \"true\"                         |\r\n  \"false\"                        |\r\n  \"null\"                         { return token(TokenType.KEYWORD); }\r\n\r\n  /* Java Built in types and wrappers */\r\n  \"Boolean\"                      |\r\n  \"Byte\"                         |\r\n  \"Character\"                    |\r\n  \"Double\"                       |\r\n  \"Float\"                        |\r\n  \"Integer\"                      |\r\n  \"Object\"                       |\r\n  \"Short\"                        |\r\n  \"Void\"                         |\r\n  \"Class\"                        |\r\n  \"Number\"                       |\r\n  \"Package\"                      |\r\n  \"StringBuffer\"                 |\r\n  \"StringBuilder\"                |\r\n  \"CharSequence\"                 |\r\n  \"Thread\"                       |\r\n  \"String\"                       { return token(TokenType.TYPE); }\r\n\r\n  /* Some Java standard Library Types */\r\n  \"Throwable\"                    |\r\n  \"Cloneable\"                    |\r\n  \"Comparable\"                   |\r\n  \"Serializable\"                 |\r\n  \"Runnable\"                     { return token(TokenType.TYPE); }\r\n\r\n  \"WARNING\"                      { return token(TokenType.WARNING); }\r\n  \"ERROR\"                        { return token(TokenType.ERROR); }\r\n\r\n  /* Frequently used Standard Exceptions */\r\n  \"ArithmeticException\"              |\r\n  \"ArrayIndexOutOfBoundsException\"   |\r\n  \"ClassCastException\"               |\r\n  \"ClassNotFoundException\"           |\r\n  \"CloneNotSupportedException\"       |\r\n  \"Exception\"                        |\r\n  \"IllegalAccessException\"           |\r\n  \"IllegalArgumentException\"         |\r\n  \"IllegalStateException\"            |\r\n  \"IllegalThreadStateException\"      |\r\n  \"IndexOutOfBoundsException\"        |\r\n  \"InstantiationException\"           |\r\n  \"InterruptedException\"             |\r\n  \"NegativeArraySizeException\"       |\r\n  \"NoSuchFieldException\"             |\r\n  \"NoSuchMethodException\"            |\r\n  \"NullPointerException\"             |\r\n  \"NumberFormatException\"            |\r\n  \"RuntimeException\"                 |\r\n  \"SecurityException\"                |\r\n  \"StringIndexOutOfBoundsException\"  |\r\n  \"UnsupportedOperationException\"    { return token(TokenType.TYPE2); }\r\n\r\n  /* operators */\r\n\r\n  \"(\"                            { return token(TokenType.OPERATOR,  PARAN); }\r\n  \")\"                            { return token(TokenType.OPERATOR, -PARAN); }\r\n  \"{\"                            { return token(TokenType.OPERATOR,  CURLY); }\r\n  \"}\"                            { return token(TokenType.OPERATOR, -CURLY); }\r\n  \"[\"                            { return token(TokenType.OPERATOR,  BRACKET); }\r\n  \"]\"                            { return token(TokenType.OPERATOR, -BRACKET); }\r\n  \";\"                            | \r\n  \",\"                            | \r\n  \".\"                            | \r\n  \"=\"                            | \r\n  \">\"                            | \r\n  \"<\"                            |\r\n  \"!\"                            | \r\n  \"~\"                            | \r\n  \"?\"                            | \r\n  \":\"                            | \r\n  \"==\"                           | \r\n  \"<=\"                           | \r\n  \">=\"                           | \r\n  \"!=\"                           | \r\n  \"&&\"                           | \r\n  \"||\"                           | \r\n  \"++\"                           | \r\n  \"--\"                           | \r\n  \"+\"                            | \r\n  \"-\"                            | \r\n  \"*\"                            | \r\n  \"/\"                            | \r\n  \"&\"                            | \r\n  \"|\"                            | \r\n  \"^\"                            | \r\n  \"%\"                            | \r\n  \"<<\"                           | \r\n  \">>\"                           | \r\n  \">>>\"                          | \r\n  \"+=\"                           | \r\n  \"-=\"                           | \r\n  \"*=\"                           | \r\n  \"/=\"                           | \r\n  \"&=\"                           | \r\n  \"|=\"                           | \r\n  \"^=\"                           | \r\n  \"%=\"                           | \r\n  \"<<=\"                          | \r\n  \">>=\"                          | \r\n  \">>>=\"                         { return token(TokenType.OPERATOR); } \r\n  \r\n  /* string literal */\r\n  \\\"                             {  \r\n                                    yybegin(STRING); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 1; \r\n                                 }\r\n\r\n  /* character literal */\r\n  \\'                             {  \r\n                                    yybegin(CHARLITERAL); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 1; \r\n                                 }\r\n\r\n  /* numeric literals */\r\n\r\n  {DecIntegerLiteral}            |\r\n  {DecLongLiteral}               |\r\n  \r\n  {HexIntegerLiteral}            |\r\n  {HexLongLiteral}               |\r\n \r\n  {OctIntegerLiteral}            |\r\n  {OctLongLiteral}               |\r\n  \r\n  {FloatLiteral}                 |\r\n  {DoubleLiteral}                |\r\n  {DoubleLiteral}[dD]            { return token(TokenType.NUMBER); }\r\n  \r\n  // JavaDoc comments need a state so that we can highlight the @ controls\r\n  \"/**\"                          {  \r\n                                    yybegin(JDOC); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 3; \r\n                                 }\r\n\r\n  /* comments */\r\n  {Comment}                      { return token(TokenType.COMMENT); }\r\n\r\n  /* whitespace */\r\n  {WhiteSpace}                   { }\r\n\r\n  /* identifiers */ \r\n  {Identifier}                   { return token(TokenType.IDENTIFIER); }\r\n}\r\n\r\n\r\n<STRING> {\r\n  \\\"                             { \r\n                                     yybegin(YYINITIAL); \r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 1);\r\n                                 }\r\n  \r\n  {StringCharacter}+             { tokenLength += yylength(); }\r\n\r\n  \\\\[0-3]?{OctDigit}?{OctDigit}  { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n}\r\n\r\n<CHARLITERAL> {\r\n  \\'                             { \r\n                                     yybegin(YYINITIAL); \r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 1);\r\n                                 }\r\n  \r\n  {SingleCharacter}+             { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n}\r\n\r\n<JDOC> {\r\n  \"*/\"                           { \r\n                                     yybegin(YYINITIAL); \r\n                                     return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2);\r\n                                 }\r\n\r\n  \"@\"                            {   \r\n                                     yybegin(JDOC_TAG); \r\n                                     int start = tokenStart;\r\n                                     tokenStart = yychar;\r\n                                     int len = tokenLength;\r\n                                     tokenLength = 1;\r\n                                     return new Token(TokenType.COMMENT, start, len);\r\n                                 }\r\n\r\n  .|\\n                           { tokenLength ++; }\r\n\r\n}\r\n\r\n<JDOC_TAG> {\r\n  ([:letter:])+ \":\"?             { tokenLength += yylength(); }\r\n\r\n  \"*/\"                           { \r\n                                     yybegin(YYINITIAL); \r\n                                     return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2);\r\n                                 }\r\n\r\n  .|\\n                           {   \r\n                                     yybegin(JDOC); \r\n                                     // length also includes the trailing quote\r\n                                     int start = tokenStart;\r\n                                     tokenStart = yychar;\r\n                                     int len = tokenLength;\r\n                                     tokenLength = 1;\r\n                                     return new Token(TokenType.COMMENT2, start, len);\r\n                                 }\r\n}\r\n\r\n\r\n/* error fallback */\r\n.|\\n                             {  }\r\n<<EOF>>                          { return null; }\r\n\r\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/javascript.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n\r\n%%\r\n\r\n%public\r\n%class JavaScriptLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n\r\n\r\n%{\r\n    /**\r\n     * Create an empty lexer, yyrset will be called later to reset and assign\r\n     * the reader\r\n     */\r\n    public JavaScriptLexer() {\r\n        super();\r\n    }\r\n\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n\r\n%}\r\n\r\n/* main character classes */\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\n\r\nWhiteSpace = {LineTerminator} | [ \\t\\f]+\r\n\r\n/* comments */\r\nComment = {TraditionalComment} | {EndOfLineComment} \r\n\r\nTraditionalComment = \"/*\" [^*] ~\"*/\" | \"/*\" \"*\"+ \"/\"\r\nEndOfLineComment = \"//\" {InputCharacter}* {LineTerminator}?\r\n\r\n/* identifiers */\r\nIdentifier = [:jletter:][:jletterdigit:]*\r\n\r\n/* integer literals */\r\nDecIntegerLiteral = 0 | [1-9][0-9]*\r\nDecLongLiteral    = {DecIntegerLiteral} [lL]\r\n\r\nHexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8}\r\nHexLongLiteral    = 0 [xX] 0* {HexDigit} {1,16} [lL]\r\nHexDigit          = [0-9a-fA-F]\r\n\r\nOctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15}\r\nOctLongLiteral    = 0+ 1? {OctDigit} {1,21} [lL]\r\nOctDigit          = [0-7]\r\n    \r\n/* floating point literals */        \r\nFloatLiteral  = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF]\r\nDoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}?\r\n\r\nFLit1    = [0-9]+ \\. [0-9]* \r\nFLit2    = \\. [0-9]+ \r\nFLit3    = [0-9]+ \r\nExponent = [eE] [+-]? [0-9]+\r\n\r\n/* string and character literals */\r\nStringCharacter = [^\\r\\n\\\"\\\\]\r\n\r\n%state STRING\r\n\r\n%%\r\n\r\n<YYINITIAL> {\r\n\r\n  /* keywords */\r\n  \"break\"                        |\r\n  \"case\"                         |\r\n  \"catch\"                        |\r\n  \"continue\"                     |\r\n  \"do\"                           |\r\n  \"else\"                         |\r\n  \"finally\"                      |\r\n  \"for\"                          |\r\n  \"default\"                      |\r\n  \"delete\"                       |\r\n  \"new\"                          |\r\n  \"goto\"                         |\r\n  \"if\"                           |\r\n  \"switch\"                       |\r\n  \"return\"                       |\r\n  \"while\"                        |\r\n  \"this\"                         |\r\n  \"try\"                          |\r\n  \"var\"                          |\r\n  \"function\"                     |\r\n  \"with\"                         |\r\n  \"in\"                           |\r\n  \r\n  /* boolean literals */\r\n  \"true\"                         |\r\n  \"false\"                        |\r\n  \r\n  /* null literal */\r\n  \"null\"                         { return token(TokenType.KEYWORD); }\r\n\r\n  /* Built-in Types*/\r\n  \"Array\"                        |\r\n  \"Boolean\"                      |\r\n  \"RegExp\"                       |\r\n  \"String\"                       |\r\n  {Identifier} \":\"               { return token(TokenType.TYPE); }\r\n\r\n  \r\n  /* operators */\r\n\r\n  \"(\"                            |\r\n  \")\"                            |\r\n  \"{\"                            | \r\n  \"}\"                            | \r\n  \"[\"                            | \r\n  \"]\"                            | \r\n  \";\"                            | \r\n  \",\"                            | \r\n  \".\"                            | \r\n  \"=\"                            | \r\n  \">\"                            | \r\n  \"<\"                            |\r\n  \"!\"                            | \r\n  \"~\"                            | \r\n  \"?\"                            | \r\n  \":\"                            | \r\n  \"==\"                           | \r\n  \"<=\"                           | \r\n  \">=\"                           | \r\n  \"!=\"                           | \r\n  \"&&\"                           | \r\n  \"||\"                           | \r\n  \"++\"                           | \r\n  \"--\"                           | \r\n  \"+\"                            | \r\n  \"-\"                            | \r\n  \"*\"                            | \r\n  \"/\"                            | \r\n  \"&\"                            | \r\n  \"|\"                            | \r\n  \"^\"                            | \r\n  \"%\"                            | \r\n  \"<<\"                           | \r\n  \">>\"                           | \r\n  \">>>\"                          | \r\n  \"+=\"                           | \r\n  \"-=\"                           | \r\n  \"*=\"                           | \r\n  \"/=\"                           | \r\n  \"&=\"                           | \r\n  \"|=\"                           | \r\n  \"^=\"                           | \r\n  \"%=\"                           | \r\n  \"<<=\"                          | \r\n  \">>=\"                          | \r\n  \">>>=\"                         { return token(TokenType.OPERATOR); } \r\n  \r\n  /* string literal */\r\n  \\\"                             {  \r\n                                    yybegin(STRING); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 1; \r\n                                 }\r\n\r\n  /* numeric literals */\r\n\r\n  {DecIntegerLiteral}            |\r\n  {DecLongLiteral}               |\r\n  \r\n  {HexIntegerLiteral}            |\r\n  {HexLongLiteral}               |\r\n \r\n  {OctIntegerLiteral}            |\r\n  {OctLongLiteral}               |\r\n  \r\n  {FloatLiteral}                 |\r\n  {DoubleLiteral}                |\r\n  {DoubleLiteral}[dD]            { return token(TokenType.NUMBER); }\r\n  \r\n  /* comments */\r\n  {Comment}                      { return token(TokenType.COMMENT); }\r\n\r\n  /* whitespace */\r\n  {WhiteSpace}                   { }\r\n\r\n  /* identifiers */ \r\n  {Identifier}                   { return token(TokenType.IDENTIFIER); }\r\n}\r\n\r\n<STRING> {\r\n  \\\"                             { \r\n                                     yybegin(YYINITIAL); \r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 1);\r\n                                 }\r\n  \r\n  {StringCharacter}+             { tokenLength += yylength(); }\r\n\r\n  \\\\[0-3]?{OctDigit}?{OctDigit}  { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n}\r\n\r\n/* error fallback */\r\n.|\\n                             {  }\r\n<<EOF>>                          { return null; }\r\n\r\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/jflex.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n \r\n%% \r\n\r\n%public\r\n%class JFlexLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n\r\n\r\n%{\r\n    /**\r\n     * Create an empty lexer, yyrset will be called later to reset and assign\r\n     * the reader\r\n     */\r\n    public JFlexLexer() {\r\n        super();\r\n    }\r\n\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n\r\n%}\r\n\r\n/* main character classes */\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\n\r\nWhiteSpace = {LineTerminator} | [ \\t\\f]+\r\n\r\n/* comments */\r\nComment = {TraditionalComment} | {EndOfLineComment} \r\n\r\nTraditionalComment = \"/*\" [^*] ~\"*/\" | \"/*\" \"*\"+ \"/\"\r\nEndOfLineComment = \"//\" {InputCharacter}* {LineTerminator}?\r\n\r\n/* identifiers */\r\nIdentifier = [:jletter:][:jletterdigit:]*\r\n\r\n/* integer literals */\r\nDecIntegerLiteral = 0 | [1-9][0-9]*\r\nDecLongLiteral    = {DecIntegerLiteral} [lL]\r\n\r\nHexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8}\r\nHexLongLiteral    = 0 [xX] 0* {HexDigit} {1,16} [lL]\r\nHexDigit          = [0-9a-fA-F]\r\n\r\nOctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15}\r\nOctLongLiteral    = 0+ 1? {OctDigit} {1,21} [lL]\r\nOctDigit          = [0-7]\r\n    \r\n/* floating point literals */        \r\nFloatLiteral  = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF]\r\nDoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}?\r\n\r\nFLit1    = [0-9]+ \\. [0-9]* \r\nFLit2    = \\. [0-9]+ \r\nFLit3    = [0-9]+ \r\nExponent = [eE] [+-]? [0-9]+\r\n\r\n/* string and character literals */\r\nStringCharacter = [^\\r\\n\\\"\\\\]\r\nSingleCharacter = [^\\r\\n\\'\\\\]\r\n\r\n%state STRING, CHARLITERAL, JDOC, JDOC_TAG\r\n\r\n%%\r\n\r\n<YYINITIAL> {\r\n\r\n  /* keywords */\r\n  \"abstract\"                     |\r\n  \"boolean\"                      |\r\n  \"break\"                        |\r\n  \"byte\"                         |\r\n  \"case\"                         |\r\n  \"catch\"                        |\r\n  \"char\"                         |\r\n  \"class\"                        |\r\n  \"const\"                        |\r\n  \"continue\"                     |\r\n  \"do\"                           |\r\n  \"double\"                       |\r\n  \"enum\"                         |\r\n  \"else\"                         |\r\n  \"extends\"                      |\r\n  \"final\"                        |\r\n  \"finally\"                      |\r\n  \"float\"                        |\r\n  \"for\"                          |\r\n  \"default\"                      |\r\n  \"implements\"                   |\r\n  \"import\"                       |\r\n  \"instanceof\"                   |\r\n  \"int\"                          |\r\n  \"interface\"                    |\r\n  \"long\"                         |\r\n  \"native\"                       |\r\n  \"new\"                          |\r\n  \"goto\"                         |\r\n  \"if\"                           |\r\n  \"public\"                       |\r\n  \"short\"                        |\r\n  \"super\"                        |\r\n  \"switch\"                       |\r\n  \"synchronized\"                 |\r\n  \"package\"                      |\r\n  \"private\"                      |\r\n  \"protected\"                    |\r\n  \"transient\"                    |\r\n  \"return\"                       |\r\n  \"void\"                         |\r\n  \"static\"                       |\r\n  \"while\"                        |\r\n  \"this\"                         |\r\n  \"throw\"                        |\r\n  \"throws\"                       |\r\n  \"try\"                          |\r\n  \"volatile\"                     |\r\n  \"strictfp\"                     |\r\n  \"true\"                         |\r\n  \"false\"                        |\r\n  \"null\"                         { return token(TokenType.KEYWORD); }\r\n\r\n  /* JFlex special types */\r\n  \"<<EOF>>\"                      |\r\n  \"[:jletter:]\"                  |\r\n  \"[:jletterdigit:]\"             |\r\n  \"[:letter:]\"                   |\r\n  \"[:digit:]\"                    |\r\n  \"[:uppercase:]\"                |\r\n  \"[:lowercase:]\"                |\r\n  \"<\" [a-zA-Z][a-zA-Z0-9_]* \">\"  { return token(TokenType.TYPE2); }\r\n\r\n  /* JFlex Specials */\r\n  \"%%\"                           |\r\n  \"%{\"                           |\r\n  \"%}\"                           |\r\n  \"%class\"                       |\r\n  \"%implements\"                  |\r\n  \"%extends\"                     |\r\n  \"%public\"                      |\r\n  \"%final\"                       |\r\n  \"%abstract\"                    |\r\n  \"%apiprivate\"                  |\r\n  \"%init{\"                       |\r\n  \"%init}\"                       |\r\n  \"%initthrow{\"                  |\r\n  \"%initthrow}\"                  |\r\n  \"%initthrow\"                   |\r\n  \"%ctorarg\"                     |\r\n  \"%scanerror\"                   |\r\n  \"%buffer\"                      |\r\n  \"%include\"                     |\r\n  \"%function\"                    |\r\n  \"%integer\"                     |\r\n  \"%int\"                         |\r\n  \"%intwrap\"                     |\r\n  \"%yylexthrow{\"                 |\r\n  \"%yylexthrow}\"                 |\r\n  \"%yylexthrow\"                  |\r\n  \"%eofval{\"                     |\r\n  \"%eofval}\"                     |\r\n  \"%eof{\"                        |\r\n  \"%eof}\"                        |\r\n  \"%eofthrow{\"                   |\r\n  \"%eofthrow}\"                   |\r\n  \"%eofthrow\"                    |\r\n  \"%eofclose\"                    |\r\n  \"%debug\"                       |\r\n  \"%standalone\"                  |\r\n  \"%cup\"                         |\r\n  \"%cupsym\"                      |\r\n  \"%cupdebug\"                    |\r\n  \"%byacc\"                       |\r\n  \"%switch\"                      |\r\n  \"%table\"                       |\r\n  \"%pack\"                        |\r\n  \"%7bit\"                        |\r\n  \"%8bit\"                        |\r\n  \"%full\"                        |\r\n  \"%unicode\"                     |\r\n  \"%16bit\"                       |\r\n  \"%caseless\"                    |\r\n  \"%ignorecase\"                  |\r\n  \"%char\"                        |\r\n  \"%line\"                        |\r\n  \"%column\"                      |\r\n  \"%notunix\"                     |\r\n  \"%yyeof\"                       |\r\n  \"%s\"                           |\r\n  \"%state\"                       |\r\n  \"%x\"                           |\r\n  \"%xstate\"                      |\r\n  \"%type\"                        { return token(TokenType.KEYWORD2); }\r\n\r\n\r\n  /* Java Built in types and wrappers */\r\n  \"Boolean\"                      |\r\n  \"Byte\"                         |\r\n  \"Double\"                       |\r\n  \"Float\"                        |\r\n  \"Integer\"                      |\r\n  \"Object\"                       |\r\n  \"Short\"                        |\r\n  \"String\"                       { return token(TokenType.TYPE); }\r\n  \r\n  /* operators */\r\n\r\n  \"(\"                            |\r\n  \")\"                            |\r\n  \"{\"                            | \r\n  \"}\"                            | \r\n  \"[\"                            | \r\n  \"]\"                            | \r\n  \";\"                            | \r\n  \",\"                            | \r\n  \".\"                            | \r\n  \"=\"                            | \r\n  \">\"                            | \r\n  \"<\"                            |\r\n  \"!\"                            | \r\n  \"~\"                            | \r\n  \"?\"                            | \r\n  \":\"                            | \r\n  \"==\"                           | \r\n  \"<=\"                           | \r\n  \">=\"                           | \r\n  \"!=\"                           | \r\n  \"&&\"                           | \r\n  \"||\"                           | \r\n  \"++\"                           | \r\n  \"--\"                           | \r\n  \"+\"                            | \r\n  \"-\"                            | \r\n  \"*\"                            | \r\n  \"/\"                            | \r\n  \"&\"                            | \r\n  \"|\"                            | \r\n  \"^\"                            | \r\n  \"%\"                            | \r\n  \"<<\"                           | \r\n  \">>\"                           | \r\n  \">>>\"                          | \r\n  \"+=\"                           | \r\n  \"-=\"                           | \r\n  \"*=\"                           | \r\n  \"/=\"                           | \r\n  \"&=\"                           | \r\n  \"|=\"                           | \r\n  \"^=\"                           | \r\n  \"%=\"                           | \r\n  \"<<=\"                          | \r\n  \">>=\"                          | \r\n  \">>>=\"                         { return token(TokenType.OPERATOR); } \r\n  \r\n  /* string literal */\r\n  \\\"                             {  \r\n                                    yybegin(STRING); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 1; \r\n                                 }\r\n\r\n  /* character literal */\r\n  \\'                             {  \r\n                                    yybegin(CHARLITERAL); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 1; \r\n                                 }\r\n\r\n  /* numeric literals */\r\n\r\n  {DecIntegerLiteral}            |\r\n  {DecLongLiteral}               |\r\n  \r\n  {HexIntegerLiteral}            |\r\n  {HexLongLiteral}               |\r\n \r\n  {OctIntegerLiteral}            |\r\n  {OctLongLiteral}               |\r\n  \r\n  {FloatLiteral}                 |\r\n  {DoubleLiteral}                |\r\n  {DoubleLiteral}[dD]            { return token(TokenType.NUMBER); }\r\n  \r\n  // JavaDoc comments need a state so that we can highlight the @ controls\r\n  \"/**\"                          {  \r\n                                    yybegin(JDOC); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 3; \r\n                                 }\r\n\r\n  /* comments */\r\n  {Comment}                      { return token(TokenType.COMMENT); }\r\n\r\n  /* whitespace */\r\n  {WhiteSpace}                   { }\r\n\r\n  /* identifiers */ \r\n  {Identifier}                   { return token(TokenType.IDENTIFIER); }\r\n}\r\n\r\n\r\n<STRING> {\r\n  \\\"                             { \r\n                                     yybegin(YYINITIAL); \r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 1);\r\n                                 }\r\n  \r\n  {StringCharacter}+             { tokenLength += yylength(); }\r\n\r\n  \\\\[0-3]?{OctDigit}?{OctDigit}  { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n}\r\n\r\n<CHARLITERAL> {\r\n  \\'                             { \r\n                                     yybegin(YYINITIAL); \r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 1);\r\n                                 }\r\n  \r\n  {SingleCharacter}+             { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n}\r\n\r\n<JDOC> {\r\n  \"*/\"                           { \r\n                                     yybegin(YYINITIAL); \r\n                                     return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2);\r\n                                 }\r\n\r\n  \"@\"                            {   \r\n                                     yybegin(JDOC_TAG); \r\n                                     int start = tokenStart;\r\n                                     tokenStart = yychar;\r\n                                     int len = tokenLength;\r\n                                     tokenLength = 1;\r\n                                     return new Token(TokenType.COMMENT, start, len);\r\n                                 }\r\n\r\n  .|\\n                           { tokenLength ++; }\r\n\r\n}\r\n\r\n<JDOC_TAG> {\r\n  ([:letter:])+ \":\"?             { tokenLength += yylength(); }\r\n\r\n  \"*/\"                           { \r\n                                     yybegin(YYINITIAL); \r\n                                     return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2);\r\n                                 }\r\n\r\n  .|\\n                           {   \r\n                                     yybegin(JDOC); \r\n                                     // length also includes the trailing quote\r\n                                     int start = tokenStart;\r\n                                     tokenStart = yychar;\r\n                                     int len = tokenLength;\r\n                                     tokenLength = 1;\r\n                                     return new Token(TokenType.COMMENT2, start, len);\r\n                                 }\r\n}\r\n\r\n\r\n/* error fallback */\r\n.|\\n                             {  }\r\n<<EOF>>                          { return null; }\r\n\r\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/properties.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n\r\n%%\r\n\r\n%public\r\n%class PropertiesLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n\r\n\r\n%{\r\n    /**\r\n     * Create an empty lexer, yyrset will be called later to reset and assign\r\n     * the reader\r\n     */\r\n    public PropertiesLexer() {\r\n        super();\r\n    }\r\n\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n%}\r\n\r\nStartComment = #\r\nWhiteSpace = [ \\t]\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\nKeyCharacter = [a-zA-Z0-9._ ]\r\n\r\n%%\r\n\r\n<YYINITIAL> \r\n{\r\n\t{KeyCharacter}+{WhiteSpace}*=    { return token(TokenType.KEYWORD); }\r\n        {StartComment} {InputCharacter}* {LineTerminator}?         \r\n                                         { return token(TokenType.COMMENT); }\r\n        . | {LineTerminator}             { /* skip */ }\r\n}\r\n\r\n<<EOF>>                   { return null; }"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/python.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n\r\n%%\r\n\r\n%public\r\n%class PythonLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n\r\n\r\n%{\r\n    /**\r\n     * Create an empty lexer, yyrset will be called later to reset and assign\r\n     * the reader\r\n     */\r\n    public PythonLexer() {\r\n        super();\r\n    }\r\n\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n\r\n    private Token token(TokenType type, int pairValue) {\r\n        return new Token(type, yychar, yylength(), (byte)pairValue);\r\n    }\r\n\r\n    private static final byte PARAN     = 1;\r\n    private static final byte BRACKET   = 2;\r\n    private static final byte CURLY     = 3;\r\n\r\n%}\r\n\r\n/* main character classes */\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\n\r\nWhiteSpace = {LineTerminator} | [ \\t\\f]+\r\n\r\n/* comments */\r\nComment = \"#\" {InputCharacter}* {LineTerminator}?\r\n\r\n/* identifiers */\r\nIdentifier = [a-zA-Z][a-zA-Z0-9_]*\r\n\r\n/* integer literals */\r\nDecIntegerLiteral = 0 | [1-9][0-9]*\r\nDecLongLiteral    = {DecIntegerLiteral} [lL]\r\n\r\nHexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8}\r\nHexLongLiteral    = 0 [xX] 0* {HexDigit} {1,16} [lL]\r\nHexDigit          = [0-9a-fA-F]\r\n\r\nOctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15}\r\nOctLongLiteral    = 0+ 1? {OctDigit} {1,21} [lL]\r\nOctDigit          = [0-7]\r\n    \r\n/* floating point literals */        \r\nFloatLiteral  = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF]\r\nDoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}?\r\n\r\nFLit1    = [0-9]+ \\. [0-9]* \r\nFLit2    = \\. [0-9]+ \r\nFLit3    = [0-9]+ \r\nExponent = [eE] [+-]? [0-9]+\r\n\r\n/* string and character literals */\r\nStringCharacter = [^\\r\\n\\\"\\\\]\r\n\r\n%state STRING, ML_STRING\r\n\r\n%%\r\n\r\n<YYINITIAL> {\r\n\r\n  /* keywords */\r\n  \"and\"                          |\r\n  \"as\"                           |\r\n  \"assert\"                       |\r\n  \"break\"                        |\r\n  \"class\"                        |\r\n  \"continue\"                     |\r\n  \"def\"                          |\r\n  \"del\"                          |\r\n  \"elif\"                         |\r\n  \"else\"                         |\r\n  \"except\"                       |\r\n  \"exec\"                         |\r\n  \"finally\"                      |\r\n  \"for\"                          |\r\n  \"from\"                         |\r\n  \"global\"                       |\r\n  \"if\"                           |\r\n  \"import\"                       |\r\n  \"in\"                           |\r\n  \"is\"                           |\r\n  \"lambda\"                       |\r\n  \"not\"                          |\r\n  \"or\"                           |\r\n  \"pass\"                         |\r\n  \"print\"                        |\r\n  \"self\"                         | /* not exactly keyword, but almost */\r\n  \"raise\"                        |\r\n  \"return\"                       |\r\n  \"try\"                          |\r\n  \"while\"                        |\r\n  \"with\"                         |\r\n  \"yield\"                        { return token(TokenType.KEYWORD); }\r\n\r\n  /* Built-in Types*/\r\n  \"yield\"                        |\r\n  \"Ellipsis\"                     |\r\n  \"False\"                        |\r\n  \"None\"                         |\r\n  \"NotImplemented\"               |\r\n  \"True\"                         |\r\n  \"__import__\"                   |\r\n  \"__name__\"                     |\r\n  \"abs\"                          |\r\n  \"apply\"                        |\r\n  \"bool\"                         |\r\n  \"buffer\"                       |\r\n  \"callable\"                     |\r\n  \"chr\"                          |\r\n  \"classmethod\"                  |\r\n  \"cmp\"                          |\r\n  \"coerce\"                       |\r\n  \"compile\"                      |\r\n  \"complex\"                      |\r\n  \"delattr\"                      |\r\n  \"dict\"                         |\r\n  \"dir\"                          |\r\n  \"divmod\"                       |\r\n  \"enumerate\"                    |\r\n  \"eval\"                         |\r\n  \"execfile\"                     |\r\n  \"file\"                         |\r\n  \"filter\"                       |\r\n  \"float\"                        |\r\n  \"frozenset\"                    |\r\n  \"getattr\"                      |\r\n  \"globals\"                      |\r\n  \"hasattr\"                      |\r\n  \"hash\"                         |\r\n  \"help\"                         |\r\n  \"hex\"                          |\r\n  \"id\"                           |\r\n  \"input\"                        |\r\n  \"int\"                          |\r\n  \"intern\"                       |\r\n  \"isinstance\"                   |\r\n  \"issubclass\"                   |\r\n  \"iter\"                         |\r\n  \"len\"                          |\r\n  \"list\"                         |\r\n  \"locals\"                       |\r\n  \"long\"                         |\r\n  \"map\"                          |\r\n  \"max\"                          |\r\n  \"min\"                          |\r\n  \"object\"                       |\r\n  \"oct\"                          |\r\n  \"open\"                         |\r\n  \"ord\"                          |\r\n  \"pow\"                          |\r\n  \"property\"                     |\r\n  \"range\"                        |\r\n  \"raw_input\"                    |\r\n  \"reduce\"                       |\r\n  \"reload\"                       |\r\n  \"repr\"                         |\r\n  \"reversed\"                     |\r\n  \"round\"                        |\r\n  \"set\"                          |\r\n  \"setattr\"                      |\r\n  \"slice\"                        |\r\n  \"sorted\"                       |\r\n  \"staticmethod\"                 |\r\n  \"str\"                          |\r\n  \"sum\"                          |\r\n  \"super\"                        |\r\n  \"tuple\"                        |\r\n  \"type\"                         |\r\n  \"unichr\"                       |\r\n  \"unicode\"                      |\r\n  \"vars\"                         |\r\n  \"xrange\"                       |\r\n  \"zip\"                          {  return token(TokenType.TYPE);  }\r\n\r\n\r\n  \r\n  /* operators */\r\n\r\n  \"(\"                            { return token(TokenType.OPERATOR,  PARAN); }\r\n  \")\"                            { return token(TokenType.OPERATOR, -PARAN); }\r\n  \"{\"                            { return token(TokenType.OPERATOR,  CURLY); }\r\n  \"}\"                            { return token(TokenType.OPERATOR, -CURLY); }\r\n  \"[\"                            { return token(TokenType.OPERATOR,  BRACKET); }\r\n  \"]\"                            { return token(TokenType.OPERATOR, -BRACKET); }\r\n  \"+\"                            |\r\n  \"-\"                            |\r\n  \"*\"                            |\r\n  \"**\"                           |\r\n  \"/\"                            |\r\n  \"//\"                           |\r\n  \"%\"                            |\r\n  \"<<\"                           |\r\n  \">>\"                           |\r\n  \"&\"                            |\r\n  \"|\"                            |\r\n  \"^\"                            |\r\n  \"~\"                            |\r\n  \"<\"                            |\r\n  \">\"                            |\r\n  \"<=\"                           |\r\n  \">=\"                           |\r\n  \"==\"                           |\r\n  \"!=\"                           |\r\n  \"<>\"                           |\r\n  \"@\"                            |\r\n  \",\"                            |\r\n  \":\"                            |\r\n  \".\"                            |\r\n  \"`\"                            |\r\n  \"=\"                            |\r\n  \";\"                            |\r\n  \"+=\"                           |\r\n  \"-=\"                           |\r\n  \"*=\"                           |\r\n  \"/=\"                           |\r\n  \"//=\"                          |\r\n  \"%=\"                           |\r\n  \"&=\"                           |\r\n  \"|=\"                           |\r\n  \"^=\"                           |\r\n  \">>=\"                          |\r\n  \"<<=\"                          |\r\n  \"**=\"                          { return token(TokenType.OPERATOR); }\r\n  \r\n  /* string literal */\r\n  \\\"{3}                          {\r\n                                    yybegin(ML_STRING);\r\n                                    tokenStart = yychar;\r\n                                    tokenLength = 3;\r\n                                 }\r\n\r\n  \\\"                             {\r\n                                    yybegin(STRING);\r\n                                    tokenStart = yychar;\r\n                                    tokenLength = 1;\r\n                                 }\r\n\r\n\r\n  /* numeric literals */\r\n\r\n  {DecIntegerLiteral}            |\r\n  {DecLongLiteral}               |\r\n  \r\n  {HexIntegerLiteral}            |\r\n  {HexLongLiteral}               |\r\n \r\n  {OctIntegerLiteral}            |\r\n  {OctLongLiteral}               |\r\n\r\n  {FloatLiteral}                 |\r\n  {DoubleLiteral}                |\r\n  {FloatLiteral}[jJ]             { return token(TokenType.NUMBER); }\r\n  \r\n  /* comments */\r\n  {Comment}                      { return token(TokenType.COMMENT); }\r\n\r\n  /* whitespace */\r\n  {WhiteSpace}                   { }\r\n\r\n  /* identifiers */ \r\n  {Identifier}                   { return token(TokenType.IDENTIFIER); }\r\n\r\n  \"$\" | \"?\"                      { return token(TokenType.ERROR); }\r\n}\r\n\r\n<STRING> {\r\n  \\\"                             { \r\n                                     yybegin(YYINITIAL); \r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 1);\r\n                                 }\r\n  \r\n  {StringCharacter}+             { tokenLength += yylength(); }\r\n\r\n  \\\\[0-3]?{OctDigit}?{OctDigit}  { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n}\r\n\r\n<ML_STRING> {\r\n  \\\"{3}                          {\r\n                                     yybegin(YYINITIAL);\r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 3);\r\n                                 }\r\n\r\n  {StringCharacter}+             { tokenLength += yylength(); }\r\n\r\n  \\\\[0-3]?{OctDigit}?{OctDigit}  { tokenLength += yylength(); }\r\n\r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { tokenLength ++;  }\r\n}\r\n\r\n\r\n/* error fallback */\r\n.|\\n                             {  }\r\n<<EOF>>                          { return null; }\r\n\r\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/ruby.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n\r\n%%\r\n\r\n%public\r\n%class RubyLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n\r\n\r\n%{\r\n    /**\r\n     * Create an empty lexer, yyrset will be called later to reset and assign\r\n     * the reader\r\n     */\r\n    public RubyLexer() {\r\n        super();\r\n    }\r\n\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n\r\n    private Token token(TokenType type, int pairValue) {\r\n        return new Token(type, yychar, yylength(), (byte)pairValue);\r\n    }\r\n\r\n    private static final byte PARAN     = 1;\r\n    private static final byte BRACKET   = 2;\r\n    private static final byte CURLY     = 3;\r\n    private static final byte WORD      = 4;\r\n\r\n%}\r\n\r\n/* main character classes */\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\n\r\nWhiteSpace = {LineTerminator} | [ \\t\\f]+\r\n\r\n/* comments */\r\nComment = \"#\" {InputCharacter}* {LineTerminator}?\r\n\r\n/* identifiers */\r\nIdentifier = [a-zA-Z][a-zA-Z0-9_]*\r\n\r\n/* integer literals */\r\nDecIntegerLiteral = 0 | [1-9][0-9]*\r\nDecLongLiteral    = {DecIntegerLiteral} [lL]\r\n\r\nHexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8}\r\nHexLongLiteral    = 0 [xX] 0* {HexDigit} {1,16} [lL]\r\nHexDigit          = [0-9a-fA-F]\r\n\r\nOctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15}\r\nOctLongLiteral    = 0+ 1? {OctDigit} {1,21} [lL]\r\nOctDigit          = [0-7]\r\n    \r\n/* floating point literals */        \r\nFloatLiteral  = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF]\r\nDoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}?\r\n\r\nFLit1    = [0-9]+ \\. [0-9]* \r\nFLit2    = \\. [0-9]+ \r\nFLit3    = [0-9]+ \r\nExponent = [eE] [+-]? [0-9]+\r\n\r\n/* string and character literals */\r\nStringCharacter = [^\\r\\n\\\"\\\\]\r\n\r\n%state STRING, ML_STRING\r\n\r\n%%\r\n\r\n<YYINITIAL> {\r\n\r\n  /* keywords */\r\n  \"BEGIN\"                        |\r\n  \"ensure\"                       |\r\n  \"assert\"                       |\r\n  \"nil\"                          |\r\n  \"self\"                         |\r\n  \"when\"                         |\r\n  \"END\"                          |\r\n  \"false\"                        |\r\n  \"not\"                          |\r\n  \"super\"                        |\r\n  \"alias\"                        |\r\n  \"defined\"                      |\r\n  \"or\"                           |\r\n  \"then\"                         |\r\n  \"yield\"                        |\r\n  \"and\"                          |\r\n  \"redo\"                         |\r\n  \"true\"                         |\r\n  \"else\"                         |\r\n  \"in\"                           |\r\n  \"rescue\"                       |\r\n  \"undef\"                        |\r\n  \"break\"                        |\r\n  \"elsif\"                        |\r\n  \"module\"                       |\r\n  \"retry\"                        |\r\n  \"unless\"                       |\r\n  \"next\"                         |\r\n  \"return\"                       { return token(TokenType.KEYWORD); }\r\n\r\n  \"begin\"                        |\r\n  \"case\"                         |\r\n  \"class\"                        |\r\n  \"def\"                          |\r\n  \"for\"                          |\r\n  \"while\"                        |\r\n  \"until\"                        |\r\n  \"do\"                           |\r\n  \"if\"                           { return token(TokenType.KEYWORD,  WORD); }\r\n\r\n  \"end\"                          { return token(TokenType.KEYWORD, -WORD); }\r\n\r\n\r\n  /* Built-in Types*/\r\n  \"self\"                         |\r\n  \"nil\"                          |\r\n  \"true\"                         |\r\n  \"false\"                        |\r\n  \"__FILE__\"                     |\r\n  \"__LINE__\"                     {  return token(TokenType.TYPE);  }\r\n\r\n\r\n  \r\n  /* operators */\r\n\r\n  \"(\"                            { return token(TokenType.OPERATOR,  PARAN); }\r\n  \")\"                            { return token(TokenType.OPERATOR, -PARAN); }\r\n  \"{\"                            { return token(TokenType.OPERATOR,  CURLY); }\r\n  \"}\"                            { return token(TokenType.OPERATOR, -CURLY); }\r\n  \"[\"                            { return token(TokenType.OPERATOR,  BRACKET); }\r\n  \"]\"                            { return token(TokenType.OPERATOR, -BRACKET); }\r\n  \"+\"                            |\r\n  \"-\"                            |\r\n  \"*\"                            |\r\n  \"**\"                           |\r\n  \"/\"                            |\r\n  \"//\"                           |\r\n  \"%\"                            |\r\n  \"<<\"                           |\r\n  \">>\"                           |\r\n  \"&\"                            |\r\n  \"|\"                            |\r\n  \"^\"                            |\r\n  \"~\"                            |\r\n  \"<\"                            |\r\n  \">\"                            |\r\n  \"<=\"                           |\r\n  \">=\"                           |\r\n  \"==\"                           |\r\n  \"!=\"                           |\r\n  \"<>\"                           |\r\n  \"@\"                            |\r\n  \",\"                            |\r\n  \":\"                            |\r\n  \".\"                            |\r\n  \"..\"                           |\r\n  \"`\"                            |\r\n  \"=\"                            |\r\n  \";\"                            |\r\n  \"+=\"                           |\r\n  \"-=\"                           |\r\n  \"*=\"                           |\r\n  \"/=\"                           |\r\n  \"//=\"                          |\r\n  \"%=\"                           |\r\n  \"&=\"                           |\r\n  \"|=\"                           |\r\n  \"^=\"                           |\r\n  \">>=\"                          |\r\n  \"<<=\"                          |\r\n  \"**=\"                          { return token(TokenType.OPERATOR); }\r\n  \r\n  /* string literal */\r\n  \\\"{3}                          {\r\n                                    yybegin(ML_STRING);\r\n                                    tokenStart = yychar;\r\n                                    tokenLength = 3;\r\n                                 }\r\n\r\n  \\\"                             {\r\n                                    yybegin(STRING);\r\n                                    tokenStart = yychar;\r\n                                    tokenLength = 1;\r\n                                 }\r\n\r\n\r\n  /* numeric literals */\r\n\r\n  {DecIntegerLiteral}            |\r\n  {DecLongLiteral}               |\r\n  \r\n  {HexIntegerLiteral}            |\r\n  {HexLongLiteral}               |\r\n \r\n  {OctIntegerLiteral}            |\r\n  {OctLongLiteral}               |\r\n\r\n  {FloatLiteral}                 |\r\n  {DoubleLiteral}                |\r\n  {FloatLiteral}[jJ]             { return token(TokenType.NUMBER); }\r\n  \r\n  /* comments */\r\n  {Comment}                      { return token(TokenType.COMMENT); }\r\n\r\n  /* whitespace */\r\n  {WhiteSpace}                   { }\r\n\r\n  /* identifiers */ \r\n  {Identifier}\"?\"                { return token(TokenType.TYPE2); }\r\n  {Identifier}                   { return token(TokenType.IDENTIFIER); }\r\n}\r\n\r\n<STRING> {\r\n  \\\"                             { \r\n                                     yybegin(YYINITIAL); \r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 1);\r\n                                 }\r\n  \r\n  {StringCharacter}+             { tokenLength += yylength(); }\r\n\r\n  \\\\[0-3]?{OctDigit}?{OctDigit}  { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n}\r\n\r\n<ML_STRING> {\r\n  \\\"{3}                          {\r\n                                     yybegin(YYINITIAL);\r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 3);\r\n                                 }\r\n\r\n  {StringCharacter}+             { tokenLength += yylength(); }\r\n\r\n  \\\\[0-3]?{OctDigit}?{OctDigit}  { tokenLength += yylength(); }\r\n\r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { tokenLength ++;  }\r\n}\r\n\r\n\r\n/* error fallback */\r\n.|\\n                             {  }\r\n<<EOF>>                          { return null; }\r\n\r\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/scala.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n \r\n%% \r\n\r\n%public\r\n%class ScalaLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n\r\n\r\n%{\r\n    /**\r\n     * Create an empty lexer, yyrset will be called later to reset and assign\r\n     * the reader\r\n     */\r\n    public ScalaLexer() {\r\n        super();\r\n    }\r\n\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n\r\n    private Token token(TokenType type, int pairValue) {\r\n        return new Token(type, yychar, yylength(), (byte)pairValue);\r\n    }\r\n\r\n    private static final byte PARAN     = 1;\r\n    private static final byte BRACKET   = 2;\r\n    private static final byte CURLY     = 3;\r\n\r\n%}\r\n\r\n/* main character classes */\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\n\r\nWhiteSpace = {LineTerminator} | [ \\t\\f]+\r\n\r\n/* comments */\r\nComment = {TraditionalComment} | {EndOfLineComment} \r\n\r\nTraditionalComment = \"/*\" [^*] ~\"*/\" | \"/*\" \"*\"+ \"/\"\r\nEndOfLineComment = \"//\" {InputCharacter}* {LineTerminator}?\r\n\r\n/* identifiers */\r\nIdentifier = [:jletter:][:jletterdigit:]*\r\n\r\n/* integer literals */\r\nDecIntegerLiteral = 0 | [1-9][0-9]*\r\nDecLongLiteral    = {DecIntegerLiteral} [lL]\r\n\r\nHexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8}\r\nHexLongLiteral    = 0 [xX] 0* {HexDigit} {1,16} [lL]\r\nHexDigit          = [0-9a-fA-F]\r\n\r\nOctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15}\r\nOctLongLiteral    = 0+ 1? {OctDigit} {1,21} [lL]\r\nOctDigit          = [0-7]\r\n    \r\n/* floating point literals */        \r\nFloatLiteral  = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF]\r\nDoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}?\r\n\r\nFLit1    = [0-9]+ \\. [0-9]* \r\nFLit2    = \\. [0-9]+ \r\nFLit3    = [0-9]+ \r\nExponent = [eE] [+-]? [0-9]+\r\n\r\n/* string and character literals */\r\nStringCharacter = [^\\r\\n\\\"\\\\]\r\nSingleCharacter = [^\\r\\n\\'\\\\]\r\n\r\n%state STRING, CHARLITERAL, JDOC, JDOC_TAG\r\n\r\n%%\r\n\r\n<YYINITIAL> {\r\n\r\n  /* keywords */\r\n  \"def\"            |\r\n  \"import\"         |\r\n  \"package\"        |\r\n  \"if\"             |\r\n  \"then\"           |\r\n  \"else\"           |\r\n  \"while\"          |\r\n  \"for\"            |\r\n  \"do\"             |\r\n  \"boolean\"        |\r\n  \"int\"            |\r\n  \"double\"         |\r\n  \"byte\"           |\r\n  \"short\"          |\r\n  \"char\"           |\r\n  \"long\"           |\r\n  \"float\"          |\r\n  \"unit\"           |\r\n  \"val\"            |\r\n  \"with\"           |\r\n  \"type\"           |\r\n  \"var\"            |\r\n  \"yield\"          |\r\n  \"return\"         |\r\n  \"true\"           |\r\n  \"false\"          |\r\n  \"null\"           |\r\n  \"this\"           |\r\n  \"super\"          |\r\n  \"String\"         |\r\n  \"Array\"          |\r\n  \"private\"        |\r\n  \"protected\"      |\r\n  \"override\"       |\r\n  \"abstract\"       |\r\n  \"final\"          |\r\n  \"sealed\"         |\r\n  \"throw\"          |\r\n  \"try\"            |\r\n  \"catch\"          |\r\n  \"finally\"        |\r\n  \"extends\"        { return token(TokenType.KEYWORD); }\r\n\r\n  /* Java Built in types and wrappers */\r\n  \"object\"                       |\r\n  \"Boolean\"                      |\r\n  \"Byte\"                         |\r\n  \"Character\"                    |\r\n  \"Double\"                       |\r\n  \"Float\"                        |\r\n  \"Integer\"                      |\r\n  \"Object\"                       |\r\n  \"Short\"                        |\r\n  \"Void\"                         |\r\n  \"Class\"                        |\r\n  \"Number\"                       |\r\n  \"Package\"                      |\r\n  \"StringBuffer\"                 |\r\n  \"StringBuilder\"                |\r\n  \"CharSequence\"                 |\r\n  \"Thread\"                       |\r\n  \"String\"                       { return token(TokenType.TYPE); }\r\n\r\n  /* Some Scala predefines */\r\n  \"println\"                      { return token(TokenType.KEYWORD2); }\r\n\r\n  /* Some Java standard Library Types */\r\n  \"Throwable\"                    |\r\n  \"Cloneable\"                    |\r\n  \"Comparable\"                   |\r\n  \"Serializable\"                 |\r\n  \"Runnable\"                     { return token(TokenType.TYPE); }\r\n\r\n  \"WARNING\"                      { return token(TokenType.WARNING); }\r\n  \"ERROR\"                        { return token(TokenType.ERROR); }\r\n\r\n  /* operators */\r\n\r\n  \"(\"                            { return token(TokenType.OPERATOR,  PARAN); }\r\n  \")\"                            { return token(TokenType.OPERATOR, -PARAN); }\r\n  \"{\"                            { return token(TokenType.OPERATOR,  CURLY); }\r\n  \"}\"                            { return token(TokenType.OPERATOR, -CURLY); }\r\n  \"[\"                            { return token(TokenType.OPERATOR,  BRACKET); }\r\n  \"]\"                            { return token(TokenType.OPERATOR, -BRACKET); }\r\n  \";\"                            | \r\n  \",\"                            | \r\n  \".\"                            | \r\n  \"=\"                            | \r\n  \">\"                            | \r\n  \"<\"                            |\r\n  \"!\"                            | \r\n  \"~\"                            | \r\n  \"?\"                            | \r\n  \":\"                            | \r\n  \"==\"                           | \r\n  \"<=\"                           | \r\n  \">=\"                           | \r\n  \"!=\"                           | \r\n  \"&&\"                           | \r\n  \"||\"                           | \r\n  \"++\"                           | \r\n  \"--\"                           | \r\n  \"+\"                            | \r\n  \"-\"                            | \r\n  \"*\"                            | \r\n  \"/\"                            | \r\n  \"&\"                            | \r\n  \"|\"                            | \r\n  \"^\"                            | \r\n  \"%\"                            | \r\n  \"<<\"                           | \r\n  \">>\"                           | \r\n  \">>>\"                          | \r\n  \"+=\"                           | \r\n  \"-=\"                           | \r\n  \"*=\"                           | \r\n  \"/=\"                           | \r\n  \"&=\"                           | \r\n  \"|=\"                           | \r\n  \"^=\"                           | \r\n  \"%=\"                           | \r\n  \"<<=\"                          | \r\n  \">>=\"                          | \r\n  \">>>=\"                         { return token(TokenType.OPERATOR); } \r\n  \r\n  /* string literal */\r\n  \\\"                             {  \r\n                                    yybegin(STRING); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 1; \r\n                                 }\r\n\r\n  /* character literal */\r\n  \\'                             {  \r\n                                    yybegin(CHARLITERAL); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 1; \r\n                                 }\r\n\r\n  /* numeric literals */\r\n\r\n  {DecIntegerLiteral}            |\r\n  {DecLongLiteral}               |\r\n  \r\n  {HexIntegerLiteral}            |\r\n  {HexLongLiteral}               |\r\n \r\n  {OctIntegerLiteral}            |\r\n  {OctLongLiteral}               |\r\n  \r\n  {FloatLiteral}                 |\r\n  {DoubleLiteral}                |\r\n  {DoubleLiteral}[dD]            { return token(TokenType.NUMBER); }\r\n  \r\n  // JavaDoc comments need a state so that we can highlight the @ controls\r\n  \"/**\"                          {  \r\n                                    yybegin(JDOC); \r\n                                    tokenStart = yychar; \r\n                                    tokenLength = 3; \r\n                                 }\r\n\r\n  /* comments */\r\n  {Comment}                      { return token(TokenType.COMMENT); }\r\n\r\n  /* whitespace */\r\n  {WhiteSpace}                   { }\r\n\r\n  /* identifiers */ \r\n  {Identifier}                   { return token(TokenType.IDENTIFIER); }\r\n}\r\n\r\n\r\n<STRING> {\r\n  \\\"                             { \r\n                                     yybegin(YYINITIAL); \r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 1);\r\n                                 }\r\n  \r\n  {StringCharacter}+             { tokenLength += yylength(); }\r\n\r\n  \\\\[0-3]?{OctDigit}?{OctDigit}  { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n}\r\n\r\n<CHARLITERAL> {\r\n  \\'                             { \r\n                                     yybegin(YYINITIAL); \r\n                                     // length also includes the trailing quote\r\n                                     return new Token(TokenType.STRING, tokenStart, tokenLength + 1);\r\n                                 }\r\n  \r\n  {SingleCharacter}+             { tokenLength += yylength(); }\r\n  \r\n  /* escape sequences */\r\n\r\n  \\\\.                            { tokenLength += 2; }\r\n  {LineTerminator}               { yybegin(YYINITIAL);  }\r\n}\r\n\r\n<JDOC> {\r\n  \"*/\"                           { \r\n                                     yybegin(YYINITIAL); \r\n                                     return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2);\r\n                                 }\r\n\r\n  \"@\"                            {   \r\n                                     yybegin(JDOC_TAG); \r\n                                     int start = tokenStart;\r\n                                     tokenStart = yychar;\r\n                                     int len = tokenLength;\r\n                                     tokenLength = 1;\r\n                                     return new Token(TokenType.COMMENT, start, len);\r\n                                 }\r\n\r\n  .|\\n                           { tokenLength ++; }\r\n\r\n}\r\n\r\n<JDOC_TAG> {\r\n  ([:letter:])+ \":\"?             { tokenLength += yylength(); }\r\n\r\n  \"*/\"                           { \r\n                                     yybegin(YYINITIAL); \r\n                                     return new Token(TokenType.COMMENT, tokenStart, tokenLength + 2);\r\n                                 }\r\n\r\n  .|\\n                           {   \r\n                                     yybegin(JDOC); \r\n                                     // length also includes the trailing quote\r\n                                     int start = tokenStart;\r\n                                     tokenStart = yychar;\r\n                                     int len = tokenLength;\r\n                                     tokenLength = 1;\r\n                                     return new Token(TokenType.COMMENT2, start, len);\r\n                                 }\r\n}\r\n\r\n\r\n/* error fallback */\r\n.|\\n                             {  }\r\n<<EOF>>                          { return null; }\r\n\r\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/sql.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n\r\n%%\r\n\r\n%public\r\n%class SqlLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n%caseless\r\n\r\n\r\n%{\r\n    /**\r\n     * Default constructor is needed as we will always call the yyreset\r\n     */\r\n    public SqlLexer() {\r\n        super();\r\n    }\r\n\r\n    /**\r\n     * Helper method to create and return a new Token from of TokenType\r\n     */\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n\r\n%}\r\n\r\n/* main character classes */\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\n\r\nWhiteSpace = {LineTerminator} | [ \\t\\f]\r\n\r\n/* comments */\r\nComment = {EndOfLineComment}\r\n\r\nEndOfLineComment = \"--\" {InputCharacter}* {LineTerminator}?\r\n\r\n/* identifiers */\r\nIdentifier = [:jletter:][:jletterdigit:]*\r\n\r\n/* integer literals */\r\nDecIntegerLiteral = 0 | [1-9][0-9]*\r\n    \r\n/* floating point literals */        \r\nFloatLiteral  = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF]\r\n\r\nFLit1    = [0-9]+ \\. [0-9]* \r\nFLit2    = \\. [0-9]+ \r\nFLit3    = [0-9]+ \r\nExponent = [eE] [+-]? [0-9]+\r\n\r\n/* string and character literals */\r\nStringCharacter = [^\\r\\n\\\"\\\\]\r\nSingleCharacter = [^\\r\\n\\'\\\\]\r\n\r\nReserved = \r\n   \"ADD\"                 |\r\n   \"ALL\"                 |\r\n   \"ALTER\"               |\r\n   \"ANALYZE\"             |\r\n   \"AND\"                 |\r\n   \"AS\"                  |\r\n   \"ASC\"                 |\r\n   \"BEFORE\"              |\r\n   \"BETWEEN\"             |\r\n   \"BIGINT\"              |\r\n   \"BINARY\"              |\r\n   \"BLOB\"                |\r\n   \"BOTH\"                |\r\n   \"BY\"                  |\r\n   \"CALL\"                |\r\n   \"CASCADE\"             |\r\n   \"CASE\"                |\r\n   \"CHANGE\"              |\r\n   \"CHAR\"                |\r\n   \"CHARACTER\"           |\r\n   \"CHECK\"               |\r\n   \"COLLATE\"             |\r\n   \"COLUMN\"              |\r\n   \"CONDITION\"           |\r\n   \"CONSTRAINT\"          |\r\n   \"CONTINUE\"            |\r\n   \"CONVERT\"             |\r\n   \"CREATE\"              |\r\n   \"CROSS\"               |\r\n   \"CURSOR\"              |\r\n   \"DATABASE\"            |\r\n   \"DATABASES\"           |\r\n   \"DEC\"                 |\r\n   \"DECIMAL\"             |\r\n   \"DECLARE\"             |\r\n   \"DEFAULT\"             |\r\n   \"DELAYED\"             |\r\n   \"DELETE\"              |\r\n   \"DESC\"                |\r\n   \"DESCRIBE\"            |\r\n   \"DETERMINISTIC\"       |\r\n   \"DISTINCT\"            |\r\n   \"DISTINCTROW\"         |\r\n   \"DIV\"                 |\r\n   \"DOUBLE\"              |\r\n   \"DROP\"                |\r\n   \"DUAL\"                |\r\n   \"EACH\"                |\r\n   \"ELSE\"                |\r\n   \"ELSEIF\"              |\r\n   \"ENCLOSED\"            |\r\n   \"ESCAPED\"             |\r\n   \"EXISTS\"              |\r\n   \"EXIT\"                |\r\n   \"EXPLAIN\"             |\r\n   \"FALSE\"               |\r\n   \"FETCH\"               |\r\n   \"FLOAT\"               |\r\n   \"FLOAT4\"              |\r\n   \"FLOAT8\"              |\r\n   \"FOR\"                 |\r\n   \"FORCE\"               |\r\n   \"FOREIGN\"             |\r\n   \"FROM\"                |\r\n   \"FULLTEXT\"            |\r\n   \"GRANT\"               |\r\n   \"GROUP\"               |\r\n   \"HAVING\"              |\r\n   \"IF\"                  |\r\n   \"IGNORE\"              |\r\n   \"IN\"                  |\r\n   \"INDEX\"               |\r\n   \"INFILE\"              |\r\n   \"INNER\"               |\r\n   \"INOUT\"               |\r\n   \"INSENSITIVE\"         |\r\n   \"INSERT\"              |\r\n   \"INT\"                 |\r\n   \"INTEGER\"             |\r\n   \"INTERVAL\"            |\r\n   \"INTO\"                |\r\n   \"IS\"                  |\r\n   \"ITERATE\"             |\r\n   \"JOIN\"                |\r\n   \"KEY\"                 |\r\n   \"KEYS\"                |\r\n   \"KILL\"                |\r\n   \"LEADING\"             |\r\n   \"LEAVE\"               |\r\n   \"LEFT\"                |\r\n   \"LIKE\"                |\r\n   \"LIMIT\"               |\r\n   \"LINES\"               |\r\n   \"LOAD\"                |\r\n   \"LOCK\"                |\r\n   \"LONG\"                |\r\n   \"LOOP\"                |\r\n   \"MATCH\"               |\r\n   \"MERGE\"               |\r\n   \"MOD\"                 |\r\n   \"MODIFIES\"            |\r\n   \"NATURAL\"             |\r\n   \"NOT\"                 |\r\n   \"NULL\"                |\r\n   \"NUMERIC\"             |\r\n   \"ON\"                  |\r\n   \"OPTIMIZE\"            |\r\n   \"OPTION\"              |\r\n   \"OPTIONALLY\"          |\r\n   \"OR\"                  |\r\n   \"ORDER\"               |\r\n   \"OUT\"                 |\r\n   \"OUTER\"               |\r\n   \"OUTFILE\"             |\r\n   \"PRECISION\"           |\r\n   \"PRIMARY\"             |\r\n   \"PROCEDURE\"           |\r\n   \"PURGE\"               |\r\n   \"READ\"                |\r\n   \"READS\"               |\r\n   \"REAL\"                |\r\n   \"REFERENCES\"          |\r\n   \"REGEXP\"              |\r\n   \"RELEASE\"             |\r\n   \"RENAME\"              |\r\n   \"REPEAT\"              |\r\n   \"REPLACE\"             |\r\n   \"REQUIRE\"             |\r\n   \"RESTRICT\"            |\r\n   \"RETURN\"              |\r\n   \"REVOKE\"              |\r\n   \"RIGHT\"               |\r\n   \"RLIKE\"               |\r\n   \"SCHEMA\"              |\r\n   \"SCHEMAS\"             |\r\n   \"SELECT\"              |\r\n   \"SENSITIVE\"           |\r\n   \"SEPARATOR\"           |\r\n   \"SET\"                 |\r\n   \"SHOW\"                |\r\n   \"SMALLINT\"            |\r\n   \"SONAME\"              |\r\n   \"SPATIAL\"             |\r\n   \"SPECIFIC\"            |\r\n   \"SQL\"                 |\r\n   \"SQLEXCEPTION\"        |\r\n   \"SQLSTATE\"            |\r\n   \"SQLWARNING\"          |\r\n   \"STARTING\"            |\r\n   \"TABLE\"               |\r\n   \"TERMINATED\"          |\r\n   \"THEN\"                |\r\n   \"TO\"                  |\r\n   \"TRAILING\"            |\r\n   \"TRIGGER\"             |\r\n   \"TRUE\"                |\r\n   \"TRUNCATE\"            |\r\n   \"UNDO\"                |\r\n   \"UNION\"               |\r\n   \"UNIQUE\"              |\r\n   \"UNLOCK\"              |\r\n   \"UNSIGNED\"            |\r\n   \"UPDATE\"              |\r\n   \"USAGE\"               |\r\n   \"USE\"                 |\r\n   \"USING\"               |\r\n   \"VALUES\"              |\r\n   \"VARBINARY\"           |\r\n   \"VARCHAR\"             |\r\n   \"VARCHARACTER\"        |\r\n   \"VARYING\"             |\r\n   \"WHEN\"                |\r\n   \"WHERE\"               |\r\n   \"WHILE\"               |\r\n   \"WITH\"                |\r\n   \"WRITE\"               |\r\n   \"XOR\"                 |\r\n   \"ZEROFILL\"\r\n%%\r\n\r\n<YYINITIAL> {\r\n\r\n  /* keywords */\r\n  {Reserved}                     { return token(TokenType.KEYWORD); }\r\n  \r\n  /* operators */\r\n\r\n  \"(\"                            |\r\n  \")\"                            |\r\n  \"{\"                            | \r\n  \"}\"                            | \r\n  \"[\"                            | \r\n  \"]\"                            | \r\n  \";\"                            | \r\n  \",\"                            | \r\n  \".\"                            | \r\n  \"@\"                            | \r\n  \"=\"                            | \r\n  \">\"                            | \r\n  \"<\"                            |\r\n  \"!\"                            | \r\n  \"~\"                            | \r\n  \"?\"                            | \r\n  \":\"                            { return token(TokenType.OPERATOR); } \r\n\r\n  /* string literal */\r\n  \\\"{StringCharacter}+\\\"         | \r\n\r\n  \\'{SingleCharacter}+\\          { return token(TokenType.STRING); } \r\n\r\n  /* numeric literals */\r\n\r\n  {DecIntegerLiteral}            |\r\n \r\n  {FloatLiteral}                 { return token(TokenType.NUMBER); }\r\n  \r\n  /* comments */\r\n  {Comment}                      { return token(TokenType.COMMENT); }\r\n\r\n  /* whitespace */\r\n  {WhiteSpace}+                  { /* skip */ }\r\n\r\n  /* identifiers */ \r\n  {Identifier}                   { return token(TokenType.IDENTIFIER); }\r\n\r\n}\r\n\r\n/* error fallback */\r\n.|\\n                             {  }\r\n<<EOF>>                          { return null; }\r\n\r\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/tal.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n\r\n%%\r\n\r\n%public\r\n%class TALLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n%caseless\r\n\r\n\r\n%{\r\n    /**\r\n     * Create an empty lexer, yyrset will be called later to reset and assign\r\n     * the reader\r\n     */\r\n    public TALLexer() {\r\n        super();\r\n    }\r\n\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n%}\r\n\r\n/* main character classes */\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\n\r\nWhiteSpace = {LineTerminator} | [ \\t\\f]+\r\n\r\n/* comments */\r\nComment = {TraditionalComment} | {EndOfLineComment}\r\n\r\nTraditionalComment = \"!\" [^\\r\\n!]* ( \"!\" | {LineTerminator} )\r\nEndOfLineComment = \"--\" {InputCharacter}* {LineTerminator}?\r\n\r\n/* identifiers */\r\nIdentifier = [A-Za-z_][A-Za-z0-9\\^_]*\r\n\r\n/* integer literals */\r\nDecIntegerLiteral = 0 | [1-9][0-9]*\r\n\r\nHexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8}\r\nHexLongLiteral    = 0 [xX] 0* {HexDigit} {1,16} [lL]\r\nHexDigit          = [0-9a-fA-F]\r\n\r\nOctIntegerLiteral = \"%\" [1-3]? {OctDigit} {1,15}\r\nOctLongLiteral    = 0+ 1? {OctDigit} {1,21} [lL]\r\nOctDigit          = [0-7]\r\n    \r\nFixedLiteral  = DecIntegerLiteral [fF]\r\nDoubleLiteral = DecIntegerLiteral [dD]\r\n\r\n/* string and character literals */\r\nStringCharacter = [^\\r\\n\\\"\\\\]\r\nSingleCharacter = [^\\r\\n\\'\\\\]\r\n\r\n%%\r\n\r\n<YYINITIAL> {\r\n\r\n  /* keywords */\r\n  \"begin\"                        |\r\n  \"end\"                          |\r\n  \"struct\"                       |\r\n  \"fieldalign\"                   |\r\n  \"shared\"                       |\r\n  \"shared2\"                      |\r\n  \"literal\"                      |\r\n  \"for\"                          |\r\n  \"do\"                           |\r\n  \"while\"                        |\r\n  \"?page\"                        |\r\n  \"?section\"                     { return token(TokenType.KEYWORD); }\r\n\r\n  \"int\"                          |\r\n  \"string\"                       |\r\n  \"int(32)\"                      |\r\n  \"fixed\"                        |\r\n  \"byte\"                         |\r\n  \"float\"                        |\r\n  \"filler\"                       { return token(TokenType.TYPE); }\r\n\r\n\r\n  \"(\"                            |\r\n  \")\"                            |\r\n  \"{\"                            | \r\n  \"}\"                            | \r\n  \"[\"                            | \r\n  \"]\"                            | \r\n  \";\"                            | \r\n  \",\"                            | \r\n  \".\"                            | \r\n  \"=\"                            | \r\n  \">\"                            | \r\n  \"<\"                            |\r\n  \"!\"                            | \r\n  \"?\"                            | \r\n  \":\"                            | \r\n  \":=\"                           | \r\n  \"':='\"                         | \r\n  \"'=:'\"                         | \r\n  \"<>\"                           | \r\n  \"+\"                            | \r\n  \"-\"                            | \r\n  \"*\"                            | \r\n  \"/\"                            | \r\n  \"<<\"                           | \r\n  \">>\"                           { return token(TokenType.OPERATOR); } \r\n  \r\n  /* string literal */\r\n  \\\"{StringCharacter}+\\\"         { return token(TokenType.STRING); }\r\n\r\n  /* character literal */\r\n  \\'{SingleCharacter}\\'          { return token(TokenType.STRING); }\r\n\r\n  /* numeric literals */\r\n\r\n  {DecIntegerLiteral}            |\r\n  \r\n  {HexIntegerLiteral}            |\r\n  {HexLongLiteral}               |\r\n \r\n  {OctIntegerLiteral}            |\r\n  {OctLongLiteral}               |\r\n  \r\n  {FixedLiteral}                 |\r\n  {DoubleLiteral}                { return token(TokenType.NUMBER); }\r\n  \r\n  /* comments */\r\n  {Comment}                      { return token(TokenType.COMMENT); }\r\n\r\n  /* whitespace */\r\n  {WhiteSpace}                   { }\r\n\r\n  /* identifiers */ \r\n  {Identifier}                   { return token(TokenType.IDENTIFIER); }\r\n}\r\n\r\n\r\n/* error fallback */\r\n.|\\n                             {  }\r\n<<EOF>>                          { return null; }\r\n\r\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/xml.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage jsyntaxpane.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n\r\n%%\r\n\r\n%public\r\n%class XmlLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n\r\n%{\r\n    /**\r\n     * Create an empty lexer, yyrset will be called later to reset and assign\r\n     * the reader\r\n     */\r\n    public XmlLexer() {\r\n        super();\r\n    }\r\n\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n\r\n    private Token token(TokenType type, int pairValue) {\r\n        return new Token(type, yychar, yylength(), (byte)pairValue);\r\n    }\r\n\r\n    private static final byte TAG_OPEN      =  1;\r\n    private static final byte TAG_CLOSE     = -1;\r\n\r\n    private static final byte INSTR_OPEN    =  2;\r\n    private static final byte INSTR_CLOSE   = -2;\r\n\r\n    private static final byte CDATA_OPEN    =  3;\r\n    private static final byte CDATA_CLOSE   = -3;\r\n\r\n    private static final byte COMMENT_OPEN  =  4;\r\n    private static final byte COMMENT_CLOSE = -4;\r\n%}\r\n\r\n%xstate COMMENT, CDATA, TAG, INSTR\r\n\r\n/* main character classes */\r\n\r\n/* white space */\r\nS = (\\u0020 | \\u0009 | \\u000D | \\u000A)+\r\n\r\n/* characters */\r\n\r\nChar = \\u0009 | \\u000A | \\u000D | [\\u0020-\\uD7FF] | [\\uE000-\\uFFFD] | [\\u10000-\\u10FFFF]\r\n\r\n/* comments */\r\nCommentStart = \"<!--\"\r\nCommentEnd = \"-->\"\r\n\r\nNameStartChar = \":\" | [A-Z] | \"_\" | [a-z]\r\nNameStartCharUnicode = [\\u00C0-\\u00D6]   |\r\n        [\\u00D8-\\u00F6] |\r\n        [\\u00F8-\\u02FF] |\r\n        [\\u0370-\\u037D] |\r\n        [\\u037F-\\u1FFF] |\r\n        [\\u200C-\\u200D] |\r\n        [\\u2070-\\u218F] |\r\n        [\\u2C00-\\u2FEF] |\r\n        [\\u3001-\\uD7FF] |\r\n        [\\uF900-\\uFDCF] |\r\n        [\\uFDF0-\\uFFFD] |\r\n        [\\u10000-\\uEFFFF]\r\n\r\nNameChar = {NameStartChar} | \"-\" | \".\" | [0-9] | \\u00B7\r\nNameCharUnicode = [\\u0300-\\u036F] | [\\u0203F-\\u2040]\r\nName = {NameStartChar} {NameChar}*\r\nNameUnicode = ({NameStartChar}|{NameStartCharUnicode}) ({NameChar}|{NameCharUnicode})*\r\n\r\n/* XML Processing Instructions */\r\nInstrStart = \"<?\" {Name}\r\nInstrEnd   = \"?>\"\r\n\r\n/* CDATA  */\r\nCDataStart = \"<![CDATA[\"\r\nCDataEnd   = \"]]>\"\r\n\r\n/* Tags */\r\nOpenTagStart = \"<\" {Name}\r\nOpenTagClose = \"/>\"\r\nOpenTagEnd = \">\"\r\n\r\nCloseTag = \"</\" {Name} {S}* \">\"\r\n\r\n/* attribute */\r\nAttribute = {Name} \"=\"\r\n\r\n/* string and character literals */\r\nDQuoteStringChar = [^\\r\\n\\\"]\r\nSQuoteStringChar = [^\\r\\n\\']\r\n\r\n%%\r\n\r\n<YYINITIAL> {\r\n  \r\n  \"&\"  [a-z]+ \";\"                |\r\n  \"&#\" [:digit:]+ \";\"            { return token(TokenType.KEYWORD2); }\r\n\r\n  {InstrStart}                   {\r\n                                     yybegin(INSTR);\r\n                                     return token(TokenType.TYPE2, INSTR_OPEN);\r\n                                 }\r\n  {OpenTagStart}                 {\r\n                                     yybegin(TAG);\r\n                                     return token(TokenType.TYPE, TAG_OPEN);\r\n                                 }\r\n  {CloseTag}                       {   return token(TokenType.TYPE, TAG_CLOSE); }\r\n  {CommentStart}                 {\r\n                                     yybegin(COMMENT);\r\n                                     return token(TokenType.COMMENT2, COMMENT_OPEN);\r\n                                 }\r\n  {CDataStart}                   {\r\n                                     yybegin(CDATA);\r\n                                     return token(TokenType.COMMENT2, CDATA_OPEN);\r\n                                 }\r\n}\r\n\r\n<INSTR> {\r\n  {Attribute}                    { return token(TokenType.IDENTIFIER); }\r\n\r\n  \\\"{DQuoteStringChar}*\\\"        |\r\n  \\'{SQuoteStringChar}*\\'        { return token(TokenType.STRING); }\r\n\r\n  {InstrEnd}                     {\r\n                                     yybegin(YYINITIAL);\r\n                                     return token(TokenType.TYPE2, INSTR_CLOSE);\r\n                                 }\r\n                                 }\r\n\r\n<TAG> {\r\n  {Attribute}                    { return token(TokenType.IDENTIFIER); }\r\n\r\n  \\\"{DQuoteStringChar}*\\\"        |\r\n  \\'{SQuoteStringChar}*\\'        { return token(TokenType.STRING); }\r\n\r\n\r\n  {OpenTagClose}                 {\r\n                                     yybegin(YYINITIAL);\r\n                                     return token(TokenType.TYPE, TAG_CLOSE);\r\n}\r\n\r\n  {OpenTagEnd}                   {\r\n                                     yybegin(YYINITIAL);\r\n                                     return token(TokenType.TYPE);\r\n                                 }\r\n}\r\n\r\n<COMMENT> {\r\n  {CommentEnd}                   {\r\n                                     yybegin(YYINITIAL);\r\n                                     return token(TokenType.COMMENT2, COMMENT_CLOSE);\r\n                                 }\r\n   ~{CommentEnd}                 {\r\n                                     yypushback(3);\r\n                                     return token(TokenType.COMMENT);\r\n                                 }\r\n}\r\n\r\n<CDATA> {\r\n  {CDataEnd}                     {\r\n                                     yybegin(YYINITIAL);\r\n                                     return token(TokenType.COMMENT2, CDATA_CLOSE);\r\n                                 }\r\n  ~{CDataEnd}                    {\r\n                                     yypushback(3);\r\n                                     return token(TokenType.COMMENT);\r\n                                 }\r\n}\r\n\r\n<YYINITIAL,TAG,INSTR,CDATA,COMMENT> {\r\n/* error fallback */\r\n   .|\\n                          {  }\r\n   <<EOF>>                       { return null; }\r\n}\r\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/resources/META-INF/services/jsyntaxpane.config.properties",
    "content": "#\n# Main Configuration of JSyntaxPane\n#\n# -----------------------------------------------------------------------------\n#\n# These will be used by all kits, unless the same key is used for a specific\n# kit, in which case the specific will be used:\n#\n# These are the componets that will be installed be default for any kit, unless\n# specified otherwise\nComponents = jsyntaxpane.components.PairsMarker, \\\n    jsyntaxpane.components.LineNumbersRuler\n# This is the color to highlight tokens whenever the cursor is on them\nTokenMarker.Color = 0xffeeaa\n# Colors for PairMarkers\nPairMarker.Color = 0xffbb77\n#\n# Right Margin for LineNumbers border in pixels, Default = 5\nLineNumbers.RightMargin = 10\n# Foreground for line numbers, Default = Black\nLineNumbers.Foreground = 0x333300\n# Background for line numbers, Default = White\nLineNumbers.Background = 0xeeeeff\n# Default color for the Caret, Black\nCaretColor = 0x000000\n#\n# Actions:\n# The key is of the format:\n# Actions.NAME = class, key\n# where NAME is the name of the action as defined by class.getAction(NAME)\n# class is the fully qualified class name of the SyntaxAction class.  Only\n# one object of that class will be created for all the actions it provides\n# and key is the keyboard key to map it to as specified by\n# KeyStroke.getKeyStroge(String key)\n#\nAction.FIND = jsyntaxpane.actions.FindReplaceActions, control F\nAction.REPLACE = jsyntaxpane.actions.FindReplaceActions, control H\nAction.FIND_NEXT = jsyntaxpane.actions.FindReplaceActions, F3\nAction.GOTO_LINE = jsyntaxpane.actions.GotoLineAction, control G\nAction.INDENT = jsyntaxpane.actions.IndentAction, TAB\nAction.UNINDENT = jsyntaxpane.actions.UnindentAction, shift TAB\n# Action.JAVA_INDENT = jsyntaxpane.actions.JavaIndentAction, ENTER\nAction.JINDENT = jsyntaxpane.actions.JIndentAction, ENTER\nAction.UNDO = jsyntaxpane.actions.UndoAction, control Z\nAction.REDO = jsyntaxpane.actions.RedoAction, control Y\nAction.DELETE_LINES = jsyntaxpane.actions.DeleteLinesAction, control E\nAction.DUPLICATE_LINES_UP = jsyntaxpane.actions.DuplicateLinesAction, shift control UP\nAction.DUPLICATE_LINES_DOWN = jsyntaxpane.actions.DuplicateLinesAction, shift control DOWN\n#\n# View configuration:\n# This controls how text is anti-aliased on the editor control:\n# see the RenderingHints.VALUE_TEXT_ANTIALIAS.... for details\n# DEFAULT: use the JRE default (default value)\n# ON: set to on, let the JRE determine best method for the display\n# OFF: no AA\n# GASP: used on GTK\n# HBGR:\n# HRGB:\n# VBGR:\n# VRGM\nTextAA = ON\n\n#\n# JavaSyntaxKit\n#\nJavaSyntaxKit.Components = jsyntaxpane.components.PairsMarker, \\\n    jsyntaxpane.components.LineNumbersRuler, \\\n    jsyntaxpane.components.TokenMarker\nJavaSyntaxKit.TokenMarker.TokenTypes = IDENTIFIER, TYPE, TYPE2, TYPE3\n#\n# Performs single color selection (Default = false)\n#\nJavaSyntaxKit.SingleColorSelect = true\n#\n# DIsplaying of a right margin line.  If RightMarginColumn is 0, then no margin\n# will be displayed\nJavaSyntaxKit.RightMarginColumn = 80\nJavaSyntaxKit.RightMarginColor = 0xdddddd\nJavaSyntaxKit.Action.PARENTHISIS = jsyntaxpane.actions.PairAction, typed (\nJavaSyntaxKit.Action.BRACKETS = jsyntaxpane.actions.PairAction, typed [\nJavaSyntaxKit.Action.QUOTE = jsyntaxpane.actions.PairAction, typed '\nJavaSyntaxKit.Action.DBL_QUOTE = jsyntaxpane.actions.PairAction, typed \"\nJavaSyntaxKit.Action.CLOSE_CURLY = jsyntaxpane.actions.JUnindentAction, typed }\nJavaSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH\n# For completions, you have to define the Action (key to trigger completions):\n# JavaSyntaxKit.Action.COMPELTION = jsyntaxpane.actions.MapCompletionAction, control SPACE\nJavaSyntaxKit.Action.COMBO_COMPELTION = jsyntaxpane.actions.ComboCompletionAction, control SPACE\n# and then the specified completions map in the below file\nJavaSyntaxKit.Completions.File = jsyntaxpane.javasyntaxkit.completions\n#\n# These are the completions to be in the IntelliSense completion dialog\n# comma separated values.\n# Vertical bars: if there is one, it will position the cursor.  If there are\n# two, they will be start and end of selection\nJavaSyntaxKit.COMBO_COMPELTION.Items = public, protected, private, class, static, \\\n  .toString(), .equals(|), .hashCode(), \\\n  JTextField, JEditorPane, JTextPane, JComboBox, JList, JTree, \\\n  jsyntaxpane, .setContentType(\"text/|lang|\"), .setProperty(\"|key|\")\n#\n# Other Java type actions for other languages:\n#\nJavaScriptSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH\nGroovySyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH\nCSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH\nCppSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH\n# The LineComments Characters can be enclosed in double quotes if spaces are present\n# in them\nGroovySyntaxKit.TOGGLE_COMMENTS.LineComments = \"// \"\n#\n# Other Languages\nRubySyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control NUMBER_SIGN\nRubySyntaxKit.TOGGLE_COMMENTS.LineComments = \"# \"\nPythonSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control NUMBER_SIGN\nPythonSyntaxKit.TOGGLE_COMMENTS.LineComments = \"# \"\n# -----------------------------------------------------------------------------\n#\n# These are the componets that will be installed for XML\n#\nXmlSyntaxKit.Components = jsyntaxpane.components.PairsMarker, \\\n    jsyntaxpane.components.LineNumbersRuler\nXmlSyntaxKit.PairMarker.Color = 0xffeeaa\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/resources/META-INF/services/jsyntaxpane.groovysyntaxkit.completions.properties",
    "content": "# This file contains the completions that will be used by the Java Syntax\n# editor kit.\n# The keys are the completion strings, and the values are the full expansion\n# of the text.  The | character will set the cursor to that location in\n# completion string\npu=public |\npr=private |\nst=static |\ncl=class |\nSt=String |\nfri=for(int i=0; i<10; i++) {\\n|\nsout=System.out.println(|)\nserr=System.err.println(|)\npsvm=public static void main(String[] args) {\\n|\n\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/resources/META-INF/services/jsyntaxpane.javasyntaxkit.completions.properties",
    "content": "# This file contains the completions that will be used by the Java Syntax\n# editor kit.\n# The keys are the completion strings, and the values are the full expansion\n# of the text.  The | character will set the cursor to that location in\n# completion string\npu=public |\npr=private |\nst=static |\ncl=class |\nSt=String |\nfri=for(int i=0; i<10; i++) {\\n|\nsout=System.out.println(|)\nserr=System.err.println(|)\npsvm=public static void main(String[] args) {\\n|\n\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/resources/META-INF/services/jsyntaxpane.kitsfortypes.properties",
    "content": "# This file contains the default content types and the SyntaxKit class names\n# that will be used for them.\n# The keys are content types, and the values are the fully qualified class \n# names\ntext/c=jsyntaxpane.syntaxkits.CSyntaxKit\ntext/cpp=jsyntaxpane.syntaxkits.CppSyntaxKit\ntext/java=jsyntaxpane.syntaxkits.JavaSyntaxKit\ntext/groovy=jsyntaxpane.syntaxkits.GroovySyntaxKit\ntext/javascript=jsyntaxpane.syntaxkits.JavaScriptSyntaxKit\ntext/xml=jsyntaxpane.syntaxkits.XmlSyntaxKit\ntext/sql=jsyntaxpane.syntaxkits.SqlSyntaxKit\ntext/properties=jsyntaxpane.syntaxkits.PropertiesSyntaxKit\ntext/python=jsyntaxpane.syntaxkits.PythonSyntaxKit\ntext/tal=jsyntaxpane.syntaxkits.TALSyntaxKit\ntext/jflex=jsyntaxpane.syntaxkits.JFlexSyntaxKit\ntext/ruby=jsyntaxpane.syntaxkits.RubySyntaxKit\ntext/scala=jsyntaxpane.syntaxkits.ScalaSyntaxKit\ntext/clojure=jsyntaxpane.syntaxkits.ClojureSyntaxKit\ntext/dosbatch=jsyntaxpane.syntaxkits.DOSBatchSyntaxKit\ntext/bash=jsyntaxpane.syntaxkits.BashSyntaxKit\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/resources/META-INF/services/jsyntaxpane.syntaxstyles.properties",
    "content": "# These are the various Attributes for each TokenType.\n# The keys of this map are the TokenType Strings, and the values are:\n# color (hex, or integer), Font.Style attribute\n# Style is one of: 0 = plain, 1=bold, 2=italic, 3=bold/italic\nOPERATOR = 0x000000, 0\nKEYWORD = 0x3333ee, 0\nKEYWORD2 = 0x3333ee, 3\nTYPE = 0x000000, 1\nTYPE2 = 0x000000, 3\nSTRING = 0xcc6600, 0\nSTRING2 = 0xcc6600, 1\nNUMBER = 0x999933, 1\nREGEX = 0xcc6600, 0\nIDENTIFIER = 0x000000, 0\nCOMMENT = 0x339933, 2\nCOMMENT2 = 0x339933, 3\nDEFAULT = 0x000000, 0\nWARNING = 0xCC0000, 0\nERROR = 0xCC0000, 3\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nOpenIDE-Module: jsyntaxpane.lib/1\nOpenIDE-Module-Install: jsyntaxpane/lib/Installer.class\nOpenIDE-Module-Localizing-Bundle: jsyntaxpane/lib/Bundle.properties\nOpenIDE-Module-Provides: org.graalvm.visualvm.editor.SyntaxSupport\nOpenIDE-Module-Specification-Version: 0.9.4.3\n\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"jsyntaxpane.lib-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=6b4ac280\nbuild.xml.script.CRC32=3633b2fc\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=6b4ac280\nnbproject/build-impl.xml.script.CRC32=f19940e9\nnbproject/build-impl.xml.stylesheet.CRC32=68e521fc@2.73\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/nbproject/project.properties",
    "content": "is.autoload=true\njavac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.6\nlicense.file=external/jsyntaxpane/APACHE-LICENSE-2.0.txt\nnbm.homepage=http://code.google.com/p/jsyntaxpane/\nnbm.module.author=Ayman Al-Sairafi\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>jsyntaxpane.lib</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.7.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>jsyntaxpane</package>\n                <package>jsyntaxpane.actions</package>\n                <package>jsyntaxpane.components</package>\n                <package>jsyntaxpane.lexers</package>\n                <package>jsyntaxpane.syntaxkits</package>\n                <package>jsyntaxpane.util</package>\n            </public-packages>\n            <class-path-extension>\n                <runtime-relative-path>ext/jsyntaxpane-0.9.4-visualvm.jar</runtime-relative-path>\n                <binary-origin>release/modules/ext/jsyntaxpane-0.9.4-visualvm.jar</binary-origin>\n            </class-path-extension>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/src/jsyntaxpane/lib/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Libraries\nOpenIDE-Module-Long-Description=\\\n    <p>\\nA very simple to use and extend JEditorKit that supports few grammars. \\\n    The main goal is to make it easy to have nice looking Java Swing Editors with support for Syntax Highlighting. \\n\\\n    </P>\\n<p>\\n<h4>\\nCurrently supported grammars: </h4>\\nC, C++, Java, Groovy, JavaScript, XML, SQL, OQL, Properties, Python, Tal, JFlex, Ruby, Scala, Clojure, Dos BAT, Bash\\n</p>\nOpenIDE-Module-Name=jSyntaxPane-lib\nOpenIDE-Module-Short-Description=A light-weight syntax highlighting support for swing\n"
  },
  {
    "path": "plugins/jsyntaxpane-lib/src/jsyntaxpane/lib/Installer.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage jsyntaxpane.lib;\n\nimport jsyntaxpane.DefaultSyntaxKit;\nimport jsyntaxpane.util.JarServiceProvider;\nimport org.openide.modules.ModuleInstall;\nimport org.openide.util.Lookup;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\npublic class Installer extends ModuleInstall {\n\n    @Override\n    public void restored() {\n        JarServiceProvider.setGlobalLoader(Lookup.getDefault().lookup(ClassLoader.class));\n        DefaultSyntaxKit.initKit();\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.mbeans\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.mbeans.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/mbeans/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.mbeans/2\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/mbeans/Install.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/mbeans/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "plugins/mbeans/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.mbeans-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/mbeans/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=88cd756f\nbuild.xml.script.CRC32=c5b2575a\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=88cd756f\nnbproject/build-impl.xml.script.CRC32=69fdc836\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "plugins/mbeans/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\njavac.source=1.5\ncp.extra=${tools.jar}\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Luis-Miguel Alventosa\nmodule.javadoc.packages=org.graalvm.visualvm.modules.mbeans.*\n"
  },
  {
    "path": "plugins/mbeans/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.mbeans</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.options.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.11.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.18.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/mbeans/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/BorderedComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\nimport javax.swing.*;\nimport javax.swing.border.*;\nimport javax.swing.plaf.*;\nimport javax.swing.plaf.basic.BasicGraphicsUtils;\n\nimport static javax.swing.SwingConstants.*;\n\nimport static org.graalvm.visualvm.modules.mbeans.Resources.*;\nimport static org.graalvm.visualvm.modules.mbeans.Utilities.*;\n\n@SuppressWarnings(\"serial\")\nclass BorderedComponent extends JPanel implements ActionListener {\n    JButton moreOrLessButton;\n    String valueLabelStr;\n    JLabel label;\n    JComponent comp;\n    boolean collapsed = false;\n\n    private JPopupMenu popupMenu;\n\n    private Icon collapseIcon;\n    private Icon expandIcon;\n\n    private static Image getImage(String name) {\n        Toolkit tk = Toolkit.getDefaultToolkit();\n        name = \"resources/\" + name + \".png\"; // NOI18N\n        return tk.getImage(BorderedComponent.class.getResource(name));\n    }\n\n    public BorderedComponent(String text) {\n        this(text, null, false);\n    }\n\n    public BorderedComponent(String text, JComponent comp) {\n        this(text, comp, false);\n    }\n\n    public BorderedComponent(String text, JComponent comp, boolean collapsible) {\n        super(null);\n\n        this.comp = comp;\n\n        // Only add border if text is not null\n        if (text != null) {\n            TitledBorder border;\n            if (collapsible) {\n                final JLabel textLabel = new JLabel(text);\n                JPanel borderLabel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 0)) {\n                    public int getBaseline(int w, int h) {\n                        Dimension dim = textLabel.getPreferredSize();\n                        return textLabel.getBaseline(dim.width, dim.height) + textLabel.getY();\n                    }\n                };\n                borderLabel.add(textLabel);\n                border = new LabeledBorder(borderLabel);\n                textLabel.setForeground(border.getTitleColor());\n\n                collapseIcon = new ArrowIcon(SOUTH, textLabel);\n                expandIcon = new ArrowIcon(EAST, textLabel);\n\n                moreOrLessButton = new JButton(collapseIcon);\n                moreOrLessButton.setContentAreaFilled(false);\n                moreOrLessButton.setBorderPainted(false);\n                moreOrLessButton.setMargin(new Insets(0, 0, 0, 0));\n                moreOrLessButton.addActionListener(this);\n                String toolTip =\n                    getText(\"LBL_BorderedComponent.moreOrLessButton.toolTip\"); // NOI18N\n                moreOrLessButton.setToolTipText(toolTip);\n                borderLabel.add(moreOrLessButton);\n                borderLabel.setSize(borderLabel.getPreferredSize());\n                add(borderLabel);\n            } else {\n                border = new TitledBorder(text);\n            }\n            setBorder(new CompoundBorder(new FocusBorder(this), border));\n        } else {\n            setBorder(new FocusBorder(this));\n        }\n        if (comp != null) {\n            add(comp);\n        }\n    }\n\n    public void setComponent(JComponent comp) {\n        if (this.comp != null) {\n            remove(this.comp);\n        }\n        this.comp = comp;\n        if (!collapsed) {\n            LayoutManager lm = getLayout();\n            if (lm instanceof BorderLayout) {\n                add(comp, BorderLayout.CENTER);\n            } else {\n                add(comp);\n            }\n        }\n        revalidate();\n    }\n\n    public void setValueLabel(String str) {\n        this.valueLabelStr = str;\n        if (label != null) {\n            label.setText(Resources.getText(\"LBL_CurrentValue\",valueLabelStr)); // NOI18N\n        }\n    }\n\n    public void actionPerformed(ActionEvent ev) {\n        if (collapsed) {\n            if (label != null) {\n                remove(label);\n            }\n            add(comp);\n            moreOrLessButton.setIcon(collapseIcon);\n        } else {\n            remove(comp);\n            if (valueLabelStr != null) {\n                if (label == null) {\n                    label = new JLabel(Resources.getText(\"LBL_CurrentValue\", // NOI18N\n                                                         valueLabelStr));\n                }\n                add(label);\n            }\n            moreOrLessButton.setIcon(expandIcon);\n        }\n        collapsed = !collapsed;\n\n        JComponent container = (JComponent)getParent();\n        if (container != null &&\n            container.getLayout() instanceof VariableGridLayout) {\n\n            ((VariableGridLayout)container.getLayout()).setFillRow(this, !collapsed);\n            container.revalidate();\n        }\n    }\n\n    public Dimension getMinimumSize() {\n        if (getLayout() != null) {\n            // A layout manager has been set, so delegate to it\n            return super.getMinimumSize();\n        }\n\n        if (moreOrLessButton != null) {\n            Dimension d = moreOrLessButton.getMinimumSize();\n            Insets i = getInsets();\n            d.width  += i.left + i.right;\n            d.height += i.top + i.bottom;\n            return d;\n        } else {\n            return super.getMinimumSize();\n        }\n    }\n\n    public void doLayout() {\n        if (getLayout() != null) {\n            // A layout manager has been set, so delegate to it\n            super.doLayout();\n            return;\n        }\n\n        Dimension d = getSize();\n        Insets i = getInsets();\n\n        if (collapsed) {\n            if (label != null) {\n                Dimension p = label.getPreferredSize();\n                label.setBounds(i.left,\n                                i.top + (d.height - i.top - i.bottom - p.height) / 2,\n                                p.width,\n                                p.height);\n            }\n        } else {\n            if (comp != null) {\n                comp.setBounds(i.left,\n                               i.top,\n                               d.width - i.left - i.right,\n                               d.height - i.top - i.bottom);\n            }\n        }\n    }\n\n    private static class ArrowIcon implements Icon {\n        private int direction;\n        private JLabel textLabel;\n\n        public ArrowIcon(int direction, JLabel textLabel) {\n            this.direction = direction;\n            this.textLabel = textLabel;\n        }\n\n        public void paintIcon(Component c, Graphics g, int x, int y) {\n            int w = getIconWidth();\n            int h = w;\n            Polygon p = new Polygon();\n            switch (direction) {\n              case EAST:\n                p.addPoint(x + 2,     y);\n                p.addPoint(x + w - 2, y + h / 2);\n                p.addPoint(x + 2,     y + h - 1);\n                break;\n\n              case SOUTH:\n                p.addPoint(x,         y + 2);\n                p.addPoint(x + w / 2, y + h - 2);\n                p.addPoint(x + w - 1, y + 2);\n                break;\n            }\n            g.fillPolygon(p);\n        }\n\n        public int getIconWidth() {\n            return getIconHeight();\n        }\n\n        public int getIconHeight() {\n            Graphics g = textLabel.getGraphics();\n            if (g != null) {\n                int h = g.getFontMetrics(textLabel.getFont()).getAscent() * 6/10;\n                if (h % 2 == 0) {\n                    h += 1;     // Make it odd\n                }\n                return h;\n            } else {\n                return 7;\n            }\n        }\n    }\n\n\n    /**\n     * A subclass of <code>TitledBorder</code> which implements an arbitrary border\n     * with the addition of a JComponent (JLabel, JPanel, etc) in the\n     * default position.\n     * <p>\n     * If the border property value is not\n     * specified in the constuctor or by invoking the appropriate\n     * set method, the property value will be defined by the current\n     * look and feel, using the following property name in the\n     * Defaults Table:\n     * <ul>\n     * <li>&quot;TitledBorder.border&quot;\n     * </ul>\n     */\n    protected static class LabeledBorder extends TitledBorder {\n        protected JComponent label;\n\n        private Point compLoc = new Point();\n\n        /**\n         * Creates a LabeledBorder instance.\n         *\n         * @param label  the label the border should display\n         */\n        public LabeledBorder(JComponent label)     {\n            this(null, label);\n        }\n\n        /**\n         * Creates a LabeledBorder instance with the specified border\n         * and an empty label.\n         *\n         * @param border  the border\n         */\n        public LabeledBorder(Border border)       {\n            this(border, null);\n        }\n\n        /**\n         * Creates a LabeledBorder instance with the specified border and\n         * label.\n         *\n         * @param border  the border\n         * @param label  the label the border should display\n         */\n        public LabeledBorder(Border border, JComponent label) {\n            super(border);\n\n            this.label = label;\n\n            if (label instanceof JLabel &&\n                label.getForeground() instanceof ColorUIResource) {\n\n                label.setForeground(getTitleColor());\n            }\n\n        }\n\n        /**\n         * Paints the border for the specified component with the\n         * specified position and size.\n         * @param c the component for which this border is being painted\n         * @param g the paint graphics\n         * @param x the x position of the painted border\n         * @param y the y position of the painted border\n         * @param width the width of the painted border\n         * @param height the height of the painted border\n         */\n        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {\n\n            Border border = getBorder();\n\n            if (label == null) {\n                if (border != null) {\n                    border.paintBorder(c, g, x, y, width, height);\n                }\n                return;\n            }\n\n            Rectangle grooveRect = new Rectangle(x + EDGE_SPACING, y + EDGE_SPACING,\n                                                 width - (EDGE_SPACING * 2),\n                                                 height - (EDGE_SPACING * 2));\n\n            Dimension   labelDim = label.getPreferredSize();\n            int baseline = label.getBaseline(labelDim.width, labelDim.height);\n            int         ascent = Math.max(0, baseline);\n            int         descent = labelDim.height - ascent;\n            int         diff;\n            Insets      insets;\n\n            if (border != null) {\n                insets = border.getBorderInsets(c);\n            } else {\n                insets = new Insets(0, 0, 0, 0);\n            }\n\n            diff = Math.max(0, ascent/2 + TEXT_SPACING - EDGE_SPACING);\n            grooveRect.y += diff;\n            grooveRect.height -= diff;\n            compLoc.y = grooveRect.y + insets.top/2 - (ascent + descent) / 2 - 1;\n\n            int justification;\n            if (c.getComponentOrientation().isLeftToRight()) {\n                justification = LEFT;\n            } else {\n                justification = RIGHT;\n            }\n\n            switch (justification) {\n                case LEFT:\n                    compLoc.x = grooveRect.x + TEXT_INSET_H + insets.left;\n                    break;\n                case RIGHT:\n                    compLoc.x = (grooveRect.x + grooveRect.width\n                                 - (labelDim.width + TEXT_INSET_H + insets.right));\n                    break;\n            }\n\n            // If title is positioned in middle of border AND its fontsize\n            // is greater than the border's thickness, we'll need to paint\n            // the border in sections to leave space for the component's background\n            // to show through the title.\n            //\n            if (border != null) {\n                if (grooveRect.y > compLoc.y - ascent) {\n                    Rectangle clipRect = new Rectangle();\n\n                    // save original clip\n                    Rectangle saveClip = g.getClipBounds();\n\n                    // paint strip left of text\n                    clipRect.setBounds(saveClip);\n                    if (computeIntersection(clipRect, x, y, compLoc.x-1-x, height)) {\n                        g.setClip(clipRect);\n                        border.paintBorder(c, g, grooveRect.x, grooveRect.y,\n                                      grooveRect.width, grooveRect.height);\n                    }\n\n                    // paint strip right of text\n                    clipRect.setBounds(saveClip);\n                    if (computeIntersection(clipRect, compLoc.x+ labelDim.width +1, y,\n                                   x+width-(compLoc.x+ labelDim.width +1), height)) {\n                        g.setClip(clipRect);\n                        border.paintBorder(c, g, grooveRect.x, grooveRect.y,\n                                      grooveRect.width, grooveRect.height);\n                    }\n\n                    // paint strip below text\n                    clipRect.setBounds(saveClip);\n                    if (computeIntersection(clipRect,\n                                            compLoc.x - 1, compLoc.y + ascent + descent,\n                                            labelDim.width + 2,\n                                            y + height - compLoc.y - ascent - descent)) {\n                        g.setClip(clipRect);\n                        border.paintBorder(c, g, grooveRect.x, grooveRect.y,\n                                  grooveRect.width, grooveRect.height);\n                    }\n\n                    // restore clip\n                    g.setClip(saveClip);\n\n                } else {\n                    border.paintBorder(c, g, grooveRect.x, grooveRect.y,\n                                      grooveRect.width, grooveRect.height);\n                }\n\n                label.setLocation(compLoc);\n                label.setSize(labelDim);\n            }\n        }\n\n        /**\n         * Reinitialize the insets parameter with this Border's current Insets.\n         * @param c the component for which this border insets value applies\n         * @param insets the object to be reinitialized\n         */\n        public Insets getBorderInsets(Component c, Insets insets) {\n            int height = 16;\n\n            Border border = getBorder();\n            if (border != null) {\n                if (border instanceof AbstractBorder) {\n                    ((AbstractBorder)border).getBorderInsets(c, insets);\n                } else {\n                    // Can't reuse border insets because the Border interface\n                    // can't be enhanced.\n                    Insets i = border.getBorderInsets(c);\n                    insets.top = i.top;\n                    insets.right = i.right;\n                    insets.bottom = i.bottom;\n                    insets.left = i.left;\n                }\n            } else {\n                insets.left = insets.top = insets.right = insets.bottom = 0;\n            }\n\n            insets.left += EDGE_SPACING + TEXT_SPACING;\n            insets.right += EDGE_SPACING + TEXT_SPACING;\n            insets.top += EDGE_SPACING + TEXT_SPACING;\n            insets.bottom += EDGE_SPACING + TEXT_SPACING;\n\n            if (c == null || label == null) {\n                return insets;\n            }\n\n            insets.top += label.getHeight();\n\n            return insets;\n        }\n\n        /**\n         * Returns the label of the labeled border.\n         */\n        public JComponent getLabel() {\n            return label;\n        }\n\n\n        /**\n         * Sets the title of the titled border.\n         * param title the title for the border\n         */\n        public void setLabel(JComponent label) {\n            this.label = label;\n        }\n\n\n\n        /**\n         * Returns the minimum dimensions this border requires\n         * in order to fully display the border and title.\n         * @param c the component where this border will be drawn\n         */\n        public Dimension getMinimumSize(Component c) {\n            Insets insets = getBorderInsets(c);\n            Dimension minSize = new Dimension(insets.right + insets.left,\n                                              insets.top + insets.bottom);\n            minSize.width += label.getWidth();\n\n            return minSize;\n        }\n\n\n        private static boolean computeIntersection(Rectangle dest,\n                                                   int rx, int ry, int rw, int rh) {\n            int x1 = Math.max(rx, dest.x);\n            int x2 = Math.min(rx + rw, dest.x + dest.width);\n            int y1 = Math.max(ry, dest.y);\n            int y2 = Math.min(ry + rh, dest.y + dest.height);\n            dest.x = x1;\n            dest.y = y1;\n            dest.width = x2 - x1;\n            dest.height = y2 - y1;\n\n            if (dest.width <= 0 || dest.height <= 0) {\n                return false;\n            }\n            return true;\n        }\n    }\n\n\n    protected static class FocusBorder extends AbstractBorder implements FocusListener {\n        private Component comp;\n        private Color focusColor;\n        private boolean focusLostTemporarily = false;\n\n        public FocusBorder(Component comp) {\n            this.comp = comp;\n\n            comp.addFocusListener(this);\n\n            // This is the best guess for a L&F specific color\n            focusColor = UIManager.getColor(\"TabbedPane.focus\"); // NOI18N\n        }\n\n        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {\n            if (comp.hasFocus() || focusLostTemporarily) {\n                Color color = g.getColor();\n                g.setColor(focusColor);\n                BasicGraphicsUtils.drawDashedRect(g, x, y, width, height);\n                g.setColor(color);\n            }\n        }\n\n        public Insets getBorderInsets(Component c, Insets insets) {\n            insets.set(2, 2, 2, 2);\n            return insets;\n        }\n\n\n        public void focusGained(FocusEvent e) {\n            comp.repaint();\n        }\n\n        public void focusLost(FocusEvent e) {\n            // We will still paint focus even if lost temporarily\n            focusLostTemporarily = e.isTemporary();\n            if (!focusLostTemporarily) {\n                comp.repaint();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Tools\nOpenIDE-Module-Long-Description=\\\n    The MBeans plugin integrates JConsole's MBeans tab functionality into VisualVM.\nOpenIDE-Module-Name=VisualVM-MBeans\nOpenIDE-Module-Short-Description=MBeans\n\nLBL_1_day=\\ 1 day\nLBL_1_hour=\\ 1 hour\nLBL_1_min=\\ 1 min\nLBL_1_month=\\ 1 month\nLBL_1_year=\\ 1 year\nLBL_2_hours=\\ 2 hours\nLBL_3_hours=\\ 3 hours\nLBL_3_months=\\ 3 months\nLBL_5_min=\\ 5 min\nLBL_6_hours=\\ 6 hours\nLBL_6_months=\\ 6 months\nLBL_7_days=\\ 7 days\nLBL_10_min=10 min\nLBL_12_hours=12 hours\nLBL_30_min=30 min\nLBL_<=<\nLBL_<<=<<\nLBL_>=>\nLBL_ACTION=ACTION\nLBL_ACTION_INFO=ACTION_INFO\nLBL_All=All\nLBL_Attribute=Attribute\nLBL_AttributeValue=Attribute value\nLBL_AttributeValues=Attribute values\nLBL_Attributes=Attributes\nLBL_BorderedComponent.moreOrLessButton.toolTip=Toggle to show more or less information\nLBL_Chart=Chart\nLBL_Chart.mnemonic='C'\nLBL_ClassName=ClassName\nLBL_ConnectionNotEstablished=Data not available because JMX connection to the JMX agent could not be established.\nLBL_Constructor=Constructor\nLBL_CurrentValue=Current value: {0}\nLBL_DoubleClickToExpandCollapse=Double click to expand/collapse\nLBL_DoubleClickToVisualize=Double click to visualize\nLBL_Description=Description\nLBL_Descriptor=Descriptor\nLBL_Details=Details\nLBL_DimensionIsNotSupported=Dimension is not supported\nLBL_DiscardChart=Discard chart\nLBL_DurationDaysHoursMinutes={0,choice,1#{0,number,integer} day |1.0<{0,number,integer} days }{1,choice,0<{1,number,integer} hours |1#{1,number,integer} hour |1<{1,number,integer} hours }{2,choice,0<{2,number,integer} minutes|1#{2,number,integer} minute|1.0<{2,number,integer} minutes}\nLBL_DurationHoursMinutes={0,choice,1#{0,number,integer} hour |1<{0,number,integer} hours }{1,choice,0<{1,number,integer} minutes|1#{1,number,integer} minute|1.0<{1,number,integer} minutes}\nLBL_DurationMinutes={0,choice,1#{0,number,integer} minute|1.0<{0,number,integer} minutes}\nLBL_DurationSeconds={0} seconds\nLBL_EmptyArray=Empty array\nLBL_Error=Error\nLBL_Event=Event\nLBL_FileChooser.fileExists.cancelOption=Cancel\nLBL_FileChooser.fileExists.message=<html><center>File already exists:<br>{0}<br>Do you want to replace it?\nLBL_FileChooser.fileExists.okOption=Replace\nLBL_FileChooser.fileExists.title=File Exists\nLBL_FileChooser.savedFile=<html>Saved to file:<br>{0}<br>({1} bytes)\nLBL_FileChooser.saveFailed.message=<html><center>Save to file failed:<br>{0}<br>{1}\nLBL_FileChooser.saveFailed.title=Save Failed\nLBL_Impact=Impact\nLBL_Info=Info\nLBL_INFO=INFO\nLBL_Is=Is\nLBL_MBeanAttributeInfo=MBeanAttributeInfo\nLBL_MBeanInfo=MBeanInfo\nLBL_MBeanNotificationInfo=MBeanNotificationInfo\nLBL_MBeanOperationInfo=MBeanOperationInfo\nLBL_MBeans=MBeans\nLBL_MBeansBrowser=MBeans Browser\nLBL_MBeansTab.clearNotificationsButton=Clear\nLBL_MBeansTab.clearNotificationsButton.mnemonic='C'\nLBL_MBeansTab.clearNotificationsButton.toolTip=Clear notifications\nLBL_MBeansTab.compositeNavigationMultiple=Composite Navigation {0}/{1}\nLBL_MBeansTab.compositeNavigationSingle=Composite Navigation\nLBL_MBeansTab.refreshAttributesButton=Refresh\nLBL_MBeansTab.refreshAttributesButton.mnemonic='R'\nLBL_MBeansTab.refreshAttributesButton.toolTip=Refresh attributes\nLBL_MBeansTab.subscribeNotificationsButton=Subscribe\nLBL_MBeansTab.subscribeNotificationsButton.mnemonic='S'\nLBL_MBeansTab.subscribeNotificationsButton.toolTip=Start listening for notifications\nLBL_MBeansTab.tabularNavigationMultiple=Tabular Navigation {0}/{1}\nLBL_MBeansTab.tabularNavigationSingle=Tabular Navigation\nLBL_MBeansTab.unsubscribeNotificationsButton=Unsubscribe\nLBL_MBeansTab.unsubscribeNotificationsButton.mnemonic='U'\nLBL_MBeansTab.unsubscribeNotificationsButton.toolTip=Stop listening for notifications\nLBL_Message=Message\nLBL_Metadata=Metadata\nLBL_MethodSuccessfullyInvoked=Method successfully invoked\nLBL_Name=Name\nLBL_Notification=Notification\nLBL_NotificationBuffer=Notification buffer\nLBL_Notifications=Notifications\nLBL_NotifTypes=NotifTypes\nLBL_ObjectName=ObjectName\nLBL_Operation=Operation\nLBL_OperationInvocation=Operation invocation\nLBL_OperationReturnValue=Operation return value\nLBL_Operations=Operations\nLBL_Parameter=Parameter\nLBL_Plotter.accessibleName=Chart\nLBL_Plotter.accessibleName.keyAndValue={0}={1}\\n\nLBL_Plotter.accessibleName.noData=No data plotted.\nLBL_Plotter.saveAsMenuItem=Save data as...\nLBL_Plotter.saveAsMenuItem.mnemonic='a'\nLBL_Plotter.timeRangeMenu=Time Range\nLBL_Plotter.timeRangeMenu.mnemonic='T'\nLBL_ProblemAddingListener=Problem adding listener\nLBL_ProblemDisplayingMBean=Problem displaying MBean\nLBL_ProblemInvoking=Problem invoking\nLBL_ProblemRemovingListener=Problem removing listener\nLBL_ProblemSettingAttribute=Problem setting attribute\nLBL_Readable=Readable\nLBL_ReturnType=ReturnType\nLBL_SeqNum=SeqNum\nLBL_SizeBytes={0,number,integer} bytes\nLBL_SizeGb={0} Gb\nLBL_SizeKb={0} Kb\nLBL_SizeMb={0} Mb\nLBL_Source=Source\nLBL_TimeStamp=TimeStamp\nLBL_Type=Type\nLBL_Unavailable=Unavailable\nLBL_UNKNOWN=UNKNOWN\nLBL_UserData=UserData\nLBL_Value=Value\nLBL_Writable=Writable\nLBL_expand=expand\nLBL_kbytes={0} kbytes\nLBL_plot=plot\nLBL_visualize=visualize\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Formatter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.text.*;\nimport java.util.*;\n\nimport static org.graalvm.visualvm.modules.mbeans.Resources.*;\n\nclass Formatter {\n    final static long SECOND = 1000;\n    final static long MINUTE = 60 * SECOND;\n    final static long HOUR   = 60 * MINUTE;\n    final static long DAY    = 24 * HOUR;\n\n    final static String cr = System.getProperty(\"line.separator\"); // NOI18N\n\n    final static DateFormat timeDF            = new SimpleDateFormat(\"HH:mm\"); // NOI18N\n    private final static DateFormat timeWithSecondsDF = new SimpleDateFormat(\"HH:mm:ss\"); // NOI18N\n    private final static DateFormat dateDF            = new SimpleDateFormat(\"yyyy-MM-dd\"); // NOI18N\n    private final static String decimalZero =\n                                new DecimalFormatSymbols().getDecimalSeparator() + \"0\"; // NOI18N\n\n    static String formatTime(long t) {\n        String str;\n        if (t < 1 * MINUTE) {\n            String seconds = String.format(\"%.3f\", t / (double)SECOND); // NOI18N\n            str = Resources.getText(\"LBL_DurationSeconds\", seconds); // NOI18N\n        } else {\n            long remaining = t;\n            long days = remaining / DAY;\n            remaining %= 1 * DAY;\n            long hours = remaining / HOUR;\n            remaining %= 1 * HOUR;\n            long minutes = remaining / MINUTE;\n\n            if (t >= 1 * DAY) {\n                str = Resources.getText(\"LBL_DurationDaysHoursMinutes\", // NOI18N\n                                        days, hours, minutes);\n            } else if (t >= 1 * HOUR) {\n                str = Resources.getText(\"LBL_DurationHoursMinutes\", // NOI18N\n                                        hours, minutes);\n            } else {\n                str = Resources.getText(\"LBL_DurationMinutes\", minutes); // NOI18N\n            }\n        }\n        return str;\n    }\n\n    static String formatNanoTime(long t) {\n        long ms = t / 1000000;\n        return formatTime(ms);\n    }\n\n\n    static String formatClockTime(long time) {\n        return timeDF.format(time);\n    }\n\n    static String formatDate(long time) {\n        return dateDF.format(time);\n    }\n\n    static String formatDateTime(long time) {\n        return dateDF.format(time) + \" \" + timeWithSecondsDF.format(time); // NOI18N\n    }\n\n    static DateFormat getDateTimeFormat(String key) {\n        String dtfStr = getText(key);\n        int dateStyle = -1;\n        int timeStyle = -1;\n\n        if (dtfStr.startsWith(\"SHORT\")) { // NOI18N\n            dateStyle = DateFormat.SHORT;\n        } else if (dtfStr.startsWith(\"MEDIUM\")) { // NOI18N\n            dateStyle = DateFormat.MEDIUM;\n        } else if (dtfStr.startsWith(\"LONG\")) { // NOI18N\n            dateStyle = DateFormat.LONG;\n        } else if (dtfStr.startsWith(\"FULL\")) { // NOI18N\n            dateStyle = DateFormat.FULL;\n        }\n\n        if (dtfStr.endsWith(\"SHORT\")) { // NOI18N\n            timeStyle = DateFormat.SHORT;\n        } else if (dtfStr.endsWith(\"MEDIUM\")) { // NOI18N\n            timeStyle = DateFormat.MEDIUM;\n        } else if (dtfStr.endsWith(\"LONG\")) { // NOI18N\n            timeStyle = DateFormat.LONG;\n        } else if (dtfStr.endsWith(\"FULL\")) { // NOI18N\n            timeStyle = DateFormat.FULL;\n        }\n\n        if (dateStyle != -1 && timeStyle != -1) {\n            return DateFormat.getDateTimeInstance(dateStyle, timeStyle);\n        } else if (dtfStr.length() > 0) {\n            return new SimpleDateFormat(dtfStr);\n        } else {\n            return DateFormat.getDateTimeInstance();\n        }\n    }\n\n    static double toExcelTime(long time) {\n        // Excel is bug compatible with Lotus 1-2-3 and pretends\n        // that 1900 was a leap year, so count from 1899-12-30.\n        // Note that the month index is zero-based in Calendar.\n        Calendar cal = new GregorianCalendar(1899, 11, 30);\n\n        // Adjust for the fact that now may be DST but then wasn't\n        Calendar tmpCal = new GregorianCalendar();\n        tmpCal.setTimeInMillis(time);\n        int dst = tmpCal.get(Calendar.DST_OFFSET);\n        if (dst > 0) {\n            cal.set(Calendar.DST_OFFSET, dst);\n        }\n\n        long millisSince1900 = time - cal.getTimeInMillis();\n        double value = (double)millisSince1900 / (24 * 60 * 60 * 1000);\n\n        return value;\n    }\n\n\n\n    static String[] formatKByteStrings(long... bytes) {\n        int n = bytes.length;\n        for (int i = 0; i < n; i++) {\n            if (bytes[i] > 0) {\n                bytes[i] /= 1024;\n            }\n        }\n        String[] strings = formatLongs(bytes);\n        for (int i = 0; i < n; i++) {\n            strings[i] = getText(\"LBL_kbytes\", strings[i]); // NOI18N\n        }\n        return strings;\n    }\n\n    static String formatKBytes(long bytes) {\n        if (bytes == -1) {\n            return getText(\"LBL_kbytes\", \"-1\"); // NOI18N\n        }\n\n        long kb = bytes / 1024;\n        return getText(\"LBL_kbytes\", justify(kb, 10)); // NOI18N\n    }\n\n\n    static String formatBytes(long v, boolean html) {\n        return formatBytes(v, v, html);\n    }\n\n    static String formatBytes(long v, long vMax) {\n        return formatBytes(v, vMax, false);\n    }\n\n    static String formatBytes(long v, long vMax, boolean html) {\n        String s;\n\n        int exp = (int)Math.log10((double)vMax);\n\n        if (exp < 3) {\n            s = Resources.getText(\"LBL_SizeBytes\", v); // NOI18N\n        } else if (exp < 6) {\n            s = Resources.getText(\"LBL_SizeKb\", trimDouble(v / Math.pow(10.0, 3))); // NOI18N\n        } else if (exp < 9) {\n            s = Resources.getText(\"LBL_SizeMb\", trimDouble(v / Math.pow(10.0, 6))); // NOI18N\n        } else {\n            s = Resources.getText(\"LBL_SizeGb\", trimDouble(v / Math.pow(10.0, 9))); // NOI18N\n        }\n        if (html) {\n            s = s.replace(\" \", \"&nbsp;\"); // NOI18N\n        }\n        return s;\n    }\n\n    /*\n     * Return the input value rounded to one decimal place.  If after\n     * rounding the string ends in the (locale-specific) decimal point\n     * followed by a zero then trim that off as well.\n     */\n    private static String trimDouble(double d) {\n        String s = String.format(\"%.1f\", d); // NOI18N\n        if (s.length() > 3 && s.endsWith(decimalZero)) {\n            s = s.substring(0, s.length()-2);\n        }\n        return s;\n    }\n\n    static String formatLong(long value) {\n        return String.format(\"%,d\", value); // NOI18N\n    }\n\n    static String[] formatLongs(long... longs) {\n        int n = longs.length;\n        int size = 0;\n        String[] strings = new String[n];\n        for (int i = 0; i < n; i++) {\n            strings[i] = formatLong(longs[i]);\n            size = Math.max(size, strings[i].length());\n        }\n        for (int i = 0; i < n; i++) {\n            strings[i] = justify(strings[i], size);\n        }\n        return strings;\n    }\n\n\n    // A poor attempt at right-justifying for numerical data\n    static String justify(long value, int size) {\n        return justify(formatLong(value), size);\n    }\n\n    static String justify(String str, int size) {\n        StringBuffer buf = new StringBuffer();\n        buf.append(\"<TT>\"); // NOI18N\n        int n = size - str.length();\n        for (int i = 0; i < n; i++) {\n            buf.append(\"&nbsp;\"); // NOI18N\n        }\n        buf.append(str);\n        buf.append(\"</TT>\"); // NOI18N\n        return buf.toString();\n    }\n\n    static String newRow(String label, String value) {\n        return newRow(label, value, 2);\n    }\n\n    static String newRow(String label, String value, int columnPerRow) {\n        if (label == null) {\n            label = \"\"; // NOI18N\n        } else {\n            label += \":&nbsp;\"; // NOI18N\n        }\n        label = \"<th nowrap align=right valign=top>\" + label; // NOI18N\n        value = \"<td colspan=\" + (columnPerRow-1) + \"> <font size =-1>\" + value; // NOI18N\n\n        return \"<tr>\" + label + value + \"</tr>\"; // NOI18N\n    }\n\n    static String newRow(String label1, String value1,\n                         String label2, String value2) {\n        label1 = \"<th nowrap align=right valign=top>\" + label1 + \":&nbsp;\"; // NOI18N\n        value1 = \"<td><font size =-1>\" + value1; // NOI18N\n        label2 = \"<th nowrap align=right valign=top>\" + label2 + \":&nbsp;\"; // NOI18N\n        value2 = \"<td><font size =-1>\" + value2; // NOI18N\n\n        return \"<tr>\" + label1 + value1 + label2 + value2 + \"</tr>\"; // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/IconManager.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.Image;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.openide.util.ImageUtilities;\n\nclass IconManager {\n\n    public static Icon MBEAN =\n            getSmallIcon(getImage(\"mbean.gif\")); // NOI18N\n    public static Icon MBEANSERVERDELEGATE =\n            getSmallIcon(getImage(\"mbeanserverdelegate.gif\")); // NOI18N\n    public static Icon DEFAULT_XOBJECT =\n            getSmallIcon(getImage(\"xobject.gif\")); // NOI18N\n\n    private static ImageIcon getImage(String img) {\n        return new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/modules/mbeans/ui/resources/\" + img, true)); // NOI18N\n    }\n\n    private static ImageIcon getSmallIcon(ImageIcon icon) {\n        return new ImageIcon(\n                icon.getImage().getScaledInstance(16, 16, Image.SCALE_SMOOTH));\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Install.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n * \n * \n * @author Tomas Hurka\n */\npublic class Install extends ModuleInstall {\n    @Override\n    public void restored() {\n        MBeansViewsSupport.sharedInstance();\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansAttributesView.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.BorderLayout;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass MBeansAttributesView extends JPanel {\n\n    private MBeansTab mbeansTab;\n\n    public MBeansAttributesView(MBeansTab mbeansTab) {\n        this.mbeansTab = mbeansTab;\n        initComponents();\n    }\n\n    private void initComponents() {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n\n        JPanel attributes = mbeansTab.getAttributesPanel();\n\n        JScrollPane attributesScrollPane = new JScrollPane(attributes, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n        attributesScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());\n\n        add(attributesScrollPane, BorderLayout.CENTER);\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansMetadataView.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.BorderLayout;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass MBeansMetadataView extends JPanel {\n\n    private MBeansTab mbeansTab;\n\n    public MBeansMetadataView(MBeansTab mbeansTab) {\n        this.mbeansTab = mbeansTab;\n        initComponents();\n    }\n\n    private void initComponents() {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n\n        JPanel metadata = mbeansTab.getMetadataPanel();\n\n        JScrollPane metadataScrollPane = new JScrollPane(metadata, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n        metadataScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());\n\n        add(metadataScrollPane, BorderLayout.CENTER);\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansNotificationsView.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.BorderLayout;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass MBeansNotificationsView extends JPanel {\n\n    private MBeansTab mbeansTab;\n\n    public MBeansNotificationsView(MBeansTab mbeansTab) {\n        this.mbeansTab = mbeansTab;\n        initComponents();\n    }\n\n    private void initComponents() {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n\n        JPanel notifications = mbeansTab.getNotificationsPanel();\n\n        JScrollPane notificationsScrollPane = new JScrollPane(notifications, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n        notificationsScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());\n\n        add(notificationsScrollPane, BorderLayout.CENTER);\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansOperationsView.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.BorderLayout;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass MBeansOperationsView extends JPanel {\n\n    private MBeansTab mbeansTab;\n\n    public MBeansOperationsView(MBeansTab mbeansTab) {\n        this.mbeansTab = mbeansTab;\n        initComponents();\n    }\n\n    private void initComponents() {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n\n        JPanel operations = mbeansTab.getOperationsPanel();\n\n        JScrollPane operationsScrollPane = new JScrollPane(operations, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n        operationsScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());\n\n        add(operationsScrollPane, BorderLayout.CENTER);\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansTab.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.tools.jmx.CachedMBeanServerConnection;\nimport org.graalvm.visualvm.tools.jmx.CachedMBeanServerConnectionFactory;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.modules.mbeans.options.GlobalPreferences;\nimport java.awt.BorderLayout;\nimport java.awt.EventQueue;\nimport java.beans.*;\nimport java.io.*;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.*;\nimport javax.swing.*;\nimport javax.swing.event.*;\nimport javax.swing.tree.*;\nimport org.openide.util.RequestProcessor;\n\nclass MBeansTab extends JPanel implements\n        NotificationListener, PropertyChangeListener,\n        TreeSelectionListener, TreeWillExpandListener {\n    private static final Logger LOGGER = Logger.getLogger(MBeansTab.class.getName());\n    private static final RequestProcessor worker = new RequestProcessor(\"MBeansTab Processor\"); // NOI18N\n\n    private Application application;\n    private DataViewComponent view;\n    private XTree tree;\n    private XSheet sheet;\n    private XDataViewer viewer;\n    private CachedMBeanServerConnection cachedMBSC;\n    \n    public static String getTabName() {\n        return Resources.getText(\"LBL_MBeans\"); // NOI18N\n    }\n    \n    public MBeansTab(Application application) {\n        this.application = application;\n        addPropertyChangeListener(this);\n        setupTab();\n    }\n    \n    public RequestProcessor getRequestProcessor() {\n        return worker;\n    }\n    \n    public XDataViewer getDataViewer() {\n        return viewer;\n    }\n    \n    public XTree getTree() {\n        return tree;\n    }\n    \n    public XSheet getSheet() {\n        return sheet;\n    }\n    \n    public JPanel getAttributesPanel() {\n        return sheet.getAttributes();\n    }\n    \n    public JPanel getOperationsPanel() {\n        return sheet.getOperations();\n    }\n    \n    public JPanel getNotificationsPanel() {\n        return sheet.getNotifications();\n    }\n    \n    public JPanel getMetadataPanel() {\n        return sheet.getMetadata();\n    }\n\n    public DataViewComponent getView() {\n        return view;\n    }\n\n    public void setView(DataViewComponent view) {\n        this.view = view;\n    }\n\n    public JButton getButtonAt(int position) {\n        JComponent containerPanel = (JComponent) view.getComponent(0);\n        JComponent detailsPanel = (JComponent) containerPanel.getComponent(1);\n        JSplitPane detailsVerticalSplitter = (JSplitPane) detailsPanel.getComponent(0);\n        JComponent detailsTopPanel = (JComponent) detailsVerticalSplitter.getLeftComponent();\n        JSplitPane detailsTopHorizontalSplitter = (JSplitPane) detailsTopPanel.getComponent(0);\n        JComponent detailsTopRightArea = (JComponent) detailsTopHorizontalSplitter.getRightComponent();\n        JComponent captionArea = (JComponent) detailsTopRightArea.getComponent(0);\n        JComponent tabsContainer = (JComponent) captionArea.getComponent(0);\n        JComponent tabButtonContainer = (JComponent) tabsContainer.getComponent(position);\n        return (JButton) tabButtonContainer.getComponent(0);\n    }\n    \n    public void dispose() {\n        removePropertyChangeListener(this);\n        tree.removeTreeSelectionListener(this);\n        tree.removeTreeWillExpandListener(this);\n        sheet.dispose();\n    }\n    \n    public int getUpdateInterval() {\n        return GlobalPreferences.sharedInstance().getPlottersPoll() * 1000;\n    }\n    \n    public void buildMBeanServerView() {\n        SwingWorker<Set<ObjectName>, Void> sw = new SwingWorker<Set<ObjectName>, Void>() {\n            @Override\n            public Set<ObjectName> doInBackground() {\n                // Register listener for MBean registration/unregistration\n                //\n                try {\n                    getMBeanServerConnection().addNotificationListener(\n                            MBeanServerDelegate.DELEGATE_NAME,\n                            MBeansTab.this,\n                            null,\n                            null);\n                } catch (InstanceNotFoundException e) {\n                    // Should never happen because the MBeanServerDelegate\n                    // is always present in any standard MBeanServer\n                    //\n                    LOGGER.throwing(MBeansTab.class.getName(), \"buildMBeanServerView\", e); // NOI18N\n                } catch (IOException e) {\n                    LOGGER.throwing(MBeansTab.class.getName(), \"buildMBeanServerView\", e); // NOI18N\n                    return null;\n                }\n                // Retrieve MBeans from MBeanServer\n                //\n                Set<ObjectName> mbeans = null;\n                try {\n                    mbeans = getMBeanServerConnection().queryNames(null,null);\n                } catch (IOException e) {\n                    LOGGER.throwing(MBeansTab.class.getName(), \"buildMBeanServerView\", e); // NOI18N\n                    return null;\n                }\n                return mbeans;\n            }\n            @Override\n            protected void done() {\n                try {\n                    // Wait for mbsc.queryNames() result\n                    Set<ObjectName> mbeans = get();\n                    // Do not display anything until the new tree has been built\n                    //\n                    tree.setVisible(false);\n                    // Cleanup current tree\n                    //\n                    tree.removeAll();\n                    // Add MBeans to tree\n                    //\n                    tree.addMBeansToView(mbeans);\n                    // Display the new tree\n                    //\n                    tree.setVisible(true);\n                } catch (Exception e) {\n                    Throwable t = Utils.getActualException(e);\n                    LOGGER.log(Level.SEVERE, \"Problem at MBean tree construction\", t); // NOI18N\n                }\n            }\n        };\n        worker.post(sw);\n    }\n    \n    public MBeanServerConnection getMBeanServerConnection() {\n        JmxModel jmx = JmxModelFactory.getJmxModelFor(application);\n        return jmx == null ? null : jmx.getMBeanServerConnection();\n    }\n    \n    public CachedMBeanServerConnection getCachedMBeanServerConnection() {\n        if (cachedMBSC == null) {\n            cachedMBSC =\n                CachedMBeanServerConnectionFactory.getCachedMBeanServerConnection(\n                    getMBeanServerConnection(), getUpdateInterval());\n        }\n        return cachedMBSC;\n    }\n    \n    private void setupTab() {\n        // set up the split pane with the MBean tree and MBean sheet panels\n        setLayout(new BorderLayout());\n        JSplitPane mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);\n        mainSplit.setDividerLocation(160);\n        mainSplit.setBorder(BorderFactory.createEmptyBorder());\n        \n        // set up the MBean tree panel (left pane)\n        tree = new XTree(this);\n        tree.setCellRenderer(new XTreeRenderer());\n        tree.getSelectionModel().setSelectionMode(\n                TreeSelectionModel.SINGLE_TREE_SELECTION);\n        tree.addTreeSelectionListener(this);\n        tree.addTreeWillExpandListener(this);\n        JScrollPane theScrollPane = new JScrollPane(\n                tree,\n                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n        JPanel treePanel = new JPanel(new BorderLayout());\n        treePanel.add(theScrollPane, BorderLayout.CENTER);\n        mainSplit.add(treePanel, JSplitPane.LEFT, 0);\n        \n        // set up the MBean sheet panel (right pane)\n        viewer = new XDataViewer(this);\n        sheet = new XSheet(this);\n        mainSplit.add(sheet, JSplitPane.RIGHT, 0);\n        \n        add(mainSplit);\n    }\n    \n    /* notification listener:  handleNotification */\n    public void handleNotification(\n            final Notification notification, Object handback) {\n        EventQueue.invokeLater(new Runnable() {\n            public void run() {\n                if (notification instanceof MBeanServerNotification) {\n                    ObjectName mbean =\n                            ((MBeanServerNotification) notification).getMBeanName();\n                    if (notification.getType().equals(\n                            MBeanServerNotification.REGISTRATION_NOTIFICATION)) {\n                        tree.addMBeanToView(mbean);\n                    } else if (notification.getType().equals(\n                            MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {\n                        tree.removeMBeanFromView(mbean);\n                    }\n                }\n            }\n        });\n    }\n    \n    /* property change listener:  propertyChange */\n    public void propertyChange(PropertyChangeEvent evt) {\n        if (JmxModel.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) {\n            ConnectionState newState = (ConnectionState) evt.getNewValue();\n            switch (newState) {\n                case CONNECTED:\n                    buildMBeanServerView();\n                    break;\n                case DISCONNECTED:\n                    dispose();\n                    break;\n            }\n        }\n    }\n    \n    /* tree selection listener: valueChanged */\n    public void valueChanged(TreeSelectionEvent e) {\n        DefaultMutableTreeNode node =\n                (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();\n        sheet.displayNode(node);\n    }\n    \n    /* tree will expand listener: treeWillExpand */\n    public void treeWillExpand(TreeExpansionEvent e)\n    throws ExpandVetoException {\n//        TreePath path = e.getPath();\n//        // if first path component has already been expanded do nothing\n//        // else build the tree branch for the given domain\n//        if (!tree.hasBeenExpanded(path)) {\n//            DefaultMutableTreeNode node =\n//                    (DefaultMutableTreeNode) path.getLastPathComponent();\n//            // TODO: build branch for given domain - queryNames(\"d:*\", null);\n//            // - if not already expanded, create from scracth\n//            // - if already expanded, update\n//        }\n    }\n    \n    /* tree will expand listener: treeWillCollapse */\n    public void treeWillCollapse(TreeExpansionEvent e)\n    throws ExpandVetoException {\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansTreeView.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState;\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTree;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass MBeansTreeView extends JPanel implements PropertyChangeListener {\n\n    private MBeansTab mbeansTab;\n\n    public MBeansTreeView(MBeansTab mbeansTab) {\n        this.mbeansTab = mbeansTab;\n        initComponents();\n    }\n\n    public void dispose() {\n        removePropertyChangeListener(this);\n        mbeansTab.getTree().clearSelection();\n        mbeansTab.getTree().setEnabled(false);\n    }\n\n    /* property change listener:  propertyChange */\n    public void propertyChange(PropertyChangeEvent evt) {\n        if (JmxModel.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) {\n            ConnectionState newState = (ConnectionState) evt.getNewValue();\n            switch (newState) {\n                case DISCONNECTED:\n                    dispose();\n                    break;\n            }\n        }\n    }\n\n\n    private void initComponents() {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n        setPreferredSize(new Dimension(220, 1));\n\n        JTree mbeansTree = mbeansTab.getTree();\n        mbeansTab.buildMBeanServerView();\n\n        JScrollPane mbeansTreeScrollPane = new JScrollPane(mbeansTree, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n        mbeansTreeScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());\n\n        add(mbeansTreeScrollPane, BorderLayout.CENTER);\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansView.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport javax.swing.JLabel;\nimport javax.swing.JTextArea;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.WeakListeners;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Luis-Miguel Alventosa\n */\nclass MBeansView extends DataSourceView {\n\n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/modules/mbeans/ui/resources/mbeans.png\"; // NOI18N\n    private Application application;\n    private MBeansTab mbeansTab;\n    private MBeansTreeView mbeansTreeView;\n    \n    public MBeansView(Application application) {\n        super(application, Resources.getText(\"LBL_MBeans\"), new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 50, false); // NOI18N\n        this.application = application;\n    }\n\n    @Override\n    protected void removed() {\n        if (mbeansTreeView != null) {\n            mbeansTreeView.dispose();\n        }\n        if (mbeansTab != null) {\n            mbeansTab.dispose();\n        }\n    }\n\n    protected DataViewComponent createComponent() {\n        DataViewComponent dvc = null;\n        JmxModel jmx = JmxModelFactory.getJmxModelFor(application);\n        if (jmx == null || jmx.getConnectionState() != JmxModel.ConnectionState.CONNECTED) {\n            JTextArea textArea = new JTextArea();\n            textArea.setBorder(BorderFactory.createEmptyBorder(25, 9, 9, 9));\n            textArea.setEditable(false);\n            textArea.setLineWrap(true);\n            textArea.setWrapStyleWord(true);\n            textArea.setText(Resources.getText(\"LBL_ConnectionNotEstablished\")); // NOI18N\n            dvc = new DataViewComponent(\n                new DataViewComponent.MasterView(Resources.getText(\"LBL_MBeansBrowser\"), null, textArea), // NOI18N\n                new DataViewComponent.MasterViewConfiguration(true));\n        } else {           \n            // MBeansTab\n            mbeansTab = new MBeansTab(application);\n            jmx.addPropertyChangeListener(WeakListeners.propertyChange(mbeansTab, jmx));\n\n            // MBeansTreeView\n            mbeansTreeView = new MBeansTreeView(mbeansTab);\n            jmx.addPropertyChangeListener(WeakListeners.propertyChange(mbeansTreeView, jmx));\n\n            // MBeansAttributesView\n            MBeansAttributesView mbeansAttributesView = new MBeansAttributesView(mbeansTab);\n\n            // MBeansOperationsView\n            MBeansOperationsView mbeansOperationsView = new MBeansOperationsView(mbeansTab);\n\n            // MBeansNotificationsView\n            MBeansNotificationsView mbeansNotificationsView = new MBeansNotificationsView(mbeansTab);\n\n            // MBeansMetadataView\n            MBeansMetadataView mbeansMetadataView = new MBeansMetadataView(mbeansTab);\n\n            DataViewComponent.MasterView monitoringMasterView = new DataViewComponent.MasterView(Resources.getText(\"LBL_MBeansBrowser\"), null, new JLabel(\" \")); // NOI18N\n            DataViewComponent.MasterViewConfiguration monitoringMasterConfiguration = new DataViewComponent.MasterViewConfiguration(false);\n            dvc = new DataViewComponent(monitoringMasterView, monitoringMasterConfiguration);\n        \n            dvc.configureDetailsView(new DataViewComponent.DetailsViewConfiguration(0.33, 0, -1, -1, -1, -1));\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(Resources.getText(\"LBL_MBeans\"), false), DataViewComponent.TOP_LEFT); // NOI18N\n            dvc.addDetailsView(new DataViewComponent.DetailsView(Resources.getText(\"LBL_MBeans\"), null, 10, mbeansTreeView, null), DataViewComponent.TOP_LEFT); // NOI18N\n            \n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(Resources.getText(\"LBL_Details\"), false), DataViewComponent.TOP_RIGHT); // NOI18N\n            dvc.addDetailsView(new DataViewComponent.DetailsView(Resources.getText(\"LBL_Attributes\"), null, 10, mbeansAttributesView, null), DataViewComponent.TOP_RIGHT); // NOI18N\n            dvc.addDetailsView(new DataViewComponent.DetailsView(Resources.getText(\"LBL_Operations\"), null, 20, mbeansOperationsView, null), DataViewComponent.TOP_RIGHT); // NOI18N\n            dvc.addDetailsView(new DataViewComponent.DetailsView(Resources.getText(\"LBL_Notifications\"), null, 30, mbeansNotificationsView, null), DataViewComponent.TOP_RIGHT); // NOI18N\n            dvc.addDetailsView(new DataViewComponent.DetailsView(Resources.getText(\"LBL_Metadata\"), null, 40, mbeansMetadataView, null), DataViewComponent.TOP_RIGHT); // NOI18N\n\n            mbeansTab.setView(dvc);\n            mbeansTab.getButtonAt(0).setEnabled(false); // Disable \"Attributes\"\n            mbeansTab.getButtonAt(1).setEnabled(false); // Disable \"Operations\"\n            mbeansTab.getButtonAt(2).setEnabled(false); // Disable \"Notifications\"\n            mbeansTab.getButtonAt(3).setEnabled(false); // Disable \"Metadata\"\n        }\n        return dvc;\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Luis-Miguel Alventosa\n */\npublic class MBeansViewProvider extends DataSourceViewProvider<Application> {\n\n    protected boolean supportsViewFor(Application application) {\n        return true;\n    }\n\n    protected DataSourceView createView(Application application) {\n        return new MBeansView(application);\n    }\n\n    public void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(this, Application.class);\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/MBeansViewsSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\n/**\n *\n * @author Luis-Miguel Alventosa\n */\npublic final class MBeansViewsSupport {\n\n    private static MBeansViewsSupport sharedInstance;\n\n    public static synchronized MBeansViewsSupport sharedInstance() {\n        if (sharedInstance == null) {\n            sharedInstance = new MBeansViewsSupport();\n        }\n        return sharedInstance;\n    }\n\n    private MBeansViewsSupport() {\n        new MBeansViewProvider().initialize();\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/OperationEntry.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.*;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.*;\nimport javax.swing.*;\n\n@SuppressWarnings(\"serial\")\nclass OperationEntry extends JPanel {\n    private final static Logger LOGGER = Logger.getLogger(OperationEntry.class.getName());\n    \n    private MBeanOperationInfo operation;\n    private JComboBox sigs;\n    private Dimension preferredSize;\n    private XTextField inputs[];\n\n    public OperationEntry (MBeanOperationInfo operation,\n                           boolean isCallable,\n                           JButton button,\n                           XMBeanOperations xoperations) {\n        super(new BorderLayout());\n        this.operation = operation;\n        setLayout(new FlowLayout(FlowLayout.LEFT));\n        setPanel(isCallable, button, xoperations);\n    }\n\n    /**\n     * This method chops off the throws exceptions, removes \"java.lang\".\n     */\n    private String preProcessSignature(String signature) {\n        int index;\n        if ((index=signature.indexOf(\" throws\"))>0) { // NOI18N\n            signature = signature.substring(0,index);\n        }\n        while ((index = signature.indexOf(\"java.lang.\"))>0) { // NOI18N\n            signature = signature.substring(0,index)+\n                signature.substring(index+10,signature.length());\n        }\n        return signature;\n    }\n\n    private void setPanel(boolean isCallable,\n                          JButton button,\n                          XMBeanOperations xoperations) {\n        try {\n            MBeanParameterInfo params[] = operation.getSignature();\n            add(new JLabel(\"(\",JLabel.CENTER)); // NOI18N\n            inputs = new XTextField[params.length];\n            for (int i = 0; i < params.length; i++) {\n                if(params[i].getName() != null) {\n                    JLabel name =\n                        new JLabel(params[i].getName(), JLabel.CENTER);\n                    name.setToolTipText(params[i].getDescription());\n                    add(name);\n                }\n\n                String defaultTextValue =\n                    Utils.getDefaultValue(params[i].getType());\n                int fieldWidth = defaultTextValue.length();\n                if (fieldWidth > 15) fieldWidth = 15;\n                else\n                    if (fieldWidth < 10) fieldWidth = 10;\n\n                Class<?> clazz;\n                try {\n                    clazz = Utils.getClass(params[i].getType());\n                } catch (ClassNotFoundException e) {\n                    clazz = null;\n                }\n\n                add(inputs[i] =\n                        new XTextField(Utils.getReadableClassName(defaultTextValue),\n                        clazz,\n                        fieldWidth,\n                        isCallable,\n                        button,\n                        xoperations));\n                inputs[i].setHorizontalAlignment(SwingConstants.CENTER);\n\n                if (i < params.length-1)\n                    add(new JLabel(\",\",JLabel.CENTER)); // NOI18N\n            }\n            add(new JLabel(\")\",JLabel.CENTER)); // NOI18N\n            validate();\n            doLayout();\n        } catch (Exception e) {\n            LOGGER.log(Level.SEVERE, \"Error setting Operation panel: \", e); // NOI18N\n        }\n    }\n\n    public String[] getSignature() {\n        MBeanParameterInfo params[] = operation.getSignature();\n        String result[] = new String[params.length];\n        for (int i = 0; i < params.length; i++) {\n            result[i] = params[i].getType();\n        }\n        return result;\n    }\n\n    public Object[] getParameters() throws Exception {\n        MBeanParameterInfo params[] = operation.getSignature();\n        String signature[] = new String[params.length];\n        for (int i = 0; i < params.length; i++)\n        signature[i] = params[i].getType();\n        return Utils.getParameters(inputs,signature);\n    }\n\n    public String getReturnType() {\n        return operation.getReturnType();\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Plotter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.beans.*;\nimport java.io.*;\nimport java.lang.reflect.Array;\nimport java.util.*;\n\nimport javax.accessibility.*;\nimport javax.swing.*;\nimport javax.swing.border.*;\nimport javax.swing.filechooser.*;\nimport javax.swing.filechooser.FileFilter;\n\nimport org.openide.windows.WindowManager;\nimport static org.graalvm.visualvm.modules.mbeans.Formatter.*;\nimport static org.graalvm.visualvm.modules.mbeans.Resources.*;\nimport static org.graalvm.visualvm.modules.mbeans.Utilities.*;\n\nclass Plotter extends JComponent\n                     implements Accessible, ActionListener, PropertyChangeListener {\n\n    public static enum Unit {\n        NONE, BYTES, PERCENT\n    }\n\n    static final String[] rangeNames = {\n        Resources.getText(\"LBL_1_min\"), // NOI18N\n        Resources.getText(\"LBL_5_min\"), // NOI18N\n        Resources.getText(\"LBL_10_min\"), // NOI18N\n        Resources.getText(\"LBL_30_min\"), // NOI18N\n        Resources.getText(\"LBL_1_hour\"), // NOI18N\n        Resources.getText(\"LBL_2_hours\"), // NOI18N\n        Resources.getText(\"LBL_3_hours\"), // NOI18N\n        Resources.getText(\"LBL_6_hours\"), // NOI18N\n        Resources.getText(\"LBL_12_hours\"), // NOI18N\n        Resources.getText(\"LBL_1_day\"), // NOI18N\n        Resources.getText(\"LBL_7_days\"), // NOI18N\n        Resources.getText(\"LBL_1_month\"), // NOI18N\n        Resources.getText(\"LBL_3_months\"), // NOI18N\n        Resources.getText(\"LBL_6_months\"), // NOI18N\n        Resources.getText(\"LBL_1_year\"), // NOI18N\n        Resources.getText(\"LBL_All\") // NOI18N\n    };\n\n    static final int[] rangeValues = {\n        1,\n        5,\n        10,\n        30,\n        1 * 60,\n        2 * 60,\n        3 * 60,\n        6 * 60,\n        12 * 60,\n        1 * 24 * 60,\n        7 * 24 * 60,\n        1 * 31 * 24 * 60,\n        3 * 31 * 24 * 60,\n        6 * 31 * 24 * 60,\n        366 * 24 * 60,\n        -1\n    };\n\n\n    final static long SECOND = 1000;\n    final static long MINUTE = 60 * SECOND;\n    final static long HOUR   = 60 * MINUTE;\n    final static long DAY    = 24 * HOUR;\n\n    final static Color bgColor = new Color(250, 250, 250);\n    final static Color defaultColor = Color.blue.darker();\n\n    final static int ARRAY_SIZE_INCREMENT = 4000;\n\n    private static Stroke dashedStroke;\n\n    private TimeStamps times = new TimeStamps();\n    private ArrayList<Sequence> seqs = new ArrayList<Sequence>();\n    private JPopupMenu popupMenu;\n    private JMenu timeRangeMenu;\n    private JRadioButtonMenuItem[] menuRBs;\n    private JMenuItem saveAsMI;\n    private JFileChooser saveFC;\n\n    private int viewRange = -1; // Minutes (value <= 0 means full range)\n    private Unit unit;\n    private int decimals;\n    private double decimalsMultiplier;\n    private Border border = null;\n    private Rectangle r = new Rectangle(1, 1, 1, 1);\n    private Font smallFont = null;\n\n    // Initial margins, may be recalculated as needed\n    private int topMargin = 10;\n    private int bottomMargin = 45;\n    private int leftMargin = 65;\n    private int rightMargin = 70;\n    // if display legend is true, the name of the attribute is displayed\n    // next to the attribute value on the right of the plotter...\n    private final boolean displayLegend;\n\n    public Plotter() {\n        this(Unit.NONE, 0, true);\n    }\n\n    public Plotter(Unit unit) {\n        this(unit, 0, true);\n    }\n\n    public Plotter(Unit unit, int decimals) {\n        this(unit, decimals, true);\n    }\n\n    // Note: If decimals > 0 then values must be decimally shifted left\n    // that many places, i.e. multiplied by Math.pow(10.0, decimals).\n    public Plotter(Unit unit, int decimals, boolean displayLegend) {\n        this.displayLegend = displayLegend;\n        setUnit(unit);\n        setDecimals(decimals);\n\n        enableEvents(AWTEvent.MOUSE_EVENT_MASK);\n\n        addMouseListener(new MouseAdapter() {\n            @Override\n            public void mousePressed(MouseEvent e) {\n                if (getParent() instanceof PlotterPanel) {\n                    getParent().requestFocusInWindow();\n                }\n            }\n        });\n\n    }\n\n    public void setUnit(Unit unit) {\n        this.unit = unit;\n    }\n\n    public void setDecimals(int decimals) {\n        this.decimals = decimals;\n        this.decimalsMultiplier = Math.pow(10.0, decimals);\n    }\n\n    public void createSequence(String key, String name, Color color, boolean isPlotted) {\n        Sequence seq = getSequence(key);\n        if (seq == null) {\n            seq = new Sequence(key);\n        }\n        seq.name = name;\n        seq.color = (color != null) ? color : defaultColor;\n        seq.isPlotted = isPlotted;\n\n        seqs.add(seq);\n    }\n\n    public void setUseDashedTransitions(String key, boolean b) {\n        Sequence seq = getSequence(key);\n        if (seq != null) {\n            seq.transitionStroke = b ? getDashedStroke() : null;\n        }\n    }\n\n    public void setIsPlotted(String key, boolean isPlotted) {\n        Sequence seq = getSequence(key);\n        if (seq != null) {\n            seq.isPlotted = isPlotted;\n        }\n    }\n\n    // Note: If decimals > 0 then values must be decimally shifted left\n    // that many places, i.e. multiplied by Math.pow(10.0, decimals).\n    public synchronized void addValues(long time, long... values) {\n        assert (values.length == seqs.size());\n        times.add(time);\n        for (int i = 0; i < values.length; i++) {\n            seqs.get(i).add(values[i]);\n        }\n        repaint();\n    }\n\n    private Sequence getSequence(String key) {\n        for (Sequence seq : seqs) {\n            if (seq.key.equals(key)) {\n                return seq;\n            }\n        }\n        return null;\n    }\n\n    /**\n     * @return the displayed time range in minutes, or -1 for all data\n     */\n    public int getViewRange() {\n        return viewRange;\n    }\n\n    /**\n     * @param minutes the displayed time range in minutes, or -1 to diaplay all data\n     */\n    public void setViewRange(int minutes) {\n        if (minutes != viewRange) {\n            int oldValue = viewRange;\n            viewRange = minutes;\n            /* Do not i18n this string */\n            firePropertyChange(\"viewRange\", oldValue, viewRange); // NOI18N\n            if (popupMenu != null) {\n                for (int i = 0; i < menuRBs.length; i++) {\n                    if (rangeValues[i] == viewRange) {\n                        menuRBs[i].setSelected(true);\n                        break;\n                    }\n                }\n            }\n            repaint();\n        }\n    }\n\n    @Override\n    public JPopupMenu getComponentPopupMenu() {\n        if (popupMenu == null) {\n            popupMenu = new JPopupMenu(Resources.getText(\"LBL_Chart\") + \":\"); // NOI18N\n            timeRangeMenu = new JMenu(Resources.getText(\"LBL_Plotter.timeRangeMenu\")); // NOI18N\n            timeRangeMenu.setMnemonic(getMnemonicInt(\"LBL_Plotter.timeRangeMenu\")); // NOI18N\n            popupMenu.add(timeRangeMenu);\n            menuRBs = new JRadioButtonMenuItem[rangeNames.length];\n            ButtonGroup rbGroup = new ButtonGroup();\n            for (int i = 0; i < rangeNames.length; i++) {\n                menuRBs[i] = new JRadioButtonMenuItem(rangeNames[i]);\n                rbGroup.add(menuRBs[i]);\n                menuRBs[i].addActionListener(this);\n                if (viewRange == rangeValues[i]) {\n                    menuRBs[i].setSelected(true);\n                }\n                timeRangeMenu.add(menuRBs[i]);\n            }\n\n            popupMenu.addSeparator();\n\n            saveAsMI = new JMenuItem(getText(\"LBL_Plotter.saveAsMenuItem\")); // NOI18N\n            saveAsMI.setMnemonic(getMnemonicInt(\"LBL_Plotter.saveAsMenuItem\")); // NOI18N\n            saveAsMI.addActionListener(this);\n            popupMenu.add(saveAsMI);\n        }\n        return popupMenu;\n    }\n\n    public void actionPerformed(ActionEvent ev) {\n        JComponent src = (JComponent)ev.getSource();\n        if (src == saveAsMI) {\n            saveAs();\n        } else {\n            int index = timeRangeMenu.getPopupMenu().getComponentIndex(src);\n            setViewRange(rangeValues[index]);\n        }\n    }\n\n    private void saveAs() {\n        if (saveFC == null) {\n            saveFC = new SaveDataFileChooser();\n        }\n        int ret = saveFC.showSaveDialog(WindowManager.getDefault().getMainWindow());\n        if (ret == JFileChooser.APPROVE_OPTION) {\n            saveDataToFile(saveFC.getSelectedFile());\n        }\n    }\n\n    private void saveDataToFile(File file) {\n        try {\n            PrintStream out = new PrintStream(new FileOutputStream(file));\n\n            // Print header line\n            out.print(\"Time\"); // NOI18N\n            for (Sequence seq : seqs) {\n                out.print(\",\"+seq.name); // NOI18N\n            }\n            out.println();\n\n            // Print data lines\n            if (seqs.size() > 0 && seqs.get(0).size > 0) {\n                for (int i = 0; i < seqs.get(0).size; i++) {\n                    double excelTime = toExcelTime(times.time(i));\n                    out.print(String.format(Locale.ENGLISH, \"%.6f\", excelTime)); // NOI18N\n                    for (Sequence seq : seqs) {\n                        out.print(\",\" + getFormattedValue(seq.value(i), false)); // NOI18N\n                    }\n                    out.println();\n                }\n            }\n\n            out.close();\n            JOptionPane.showMessageDialog(this,\n                                          getText(\"LBL_FileChooser.savedFile\", // NOI18N\n                                                  file.getAbsolutePath(),\n                                                  file.length()));\n        } catch (IOException ex) {\n            String msg = ex.getLocalizedMessage();\n            String path = file.getAbsolutePath();\n            if (msg.startsWith(path)) {\n                msg = msg.substring(path.length()).trim();\n            }\n            JOptionPane.showMessageDialog(this,\n                                          getText(\"LBL_FileChooser.saveFailed.message\", // NOI18N\n                                                  path, msg),\n                                          getText(\"LBL_FileChooser.saveFailed.title\"), // NOI18N\n                                          JOptionPane.ERROR_MESSAGE);\n        }\n    }\n\n    @Override\n    public void paintComponent(Graphics g) {\n        super.paintComponent(g);\n\n        Color oldColor = g.getColor();\n        Font  oldFont  = g.getFont();\n        Color fg = getForeground();\n        Color bg = getBackground();\n        boolean bgIsLight = (bg.getRed() > 200 &&\n                             bg.getGreen() > 200 &&\n                             bg.getBlue() > 200);\n\n\n        ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,\n                                         RenderingHints.VALUE_ANTIALIAS_ON);\n\n        if (smallFont == null) {\n            smallFont = oldFont.deriveFont(9.0F);\n        }\n\n        r.x = leftMargin - 5;\n        r.y = topMargin  - 8;\n        r.width  = getWidth()-leftMargin-rightMargin;\n        r.height = getHeight()-topMargin-bottomMargin+16;\n\n        if (border == null) {\n            // By setting colors here, we avoid recalculating them\n            // over and over.\n            border = new BevelBorder(BevelBorder.LOWERED,\n                                     getBackground().brighter().brighter(),\n                                     getBackground().brighter(),\n                                     getBackground().darker().darker(),\n                                     getBackground().darker());\n        }\n\n        border.paintBorder(this, g, r.x, r.y, r.width, r.height);\n\n        // Fill background color\n        g.setColor(bgColor);\n        g.fillRect(r.x+2, r.y+2, r.width-4, r.height-4);\n        g.setColor(oldColor);\n\n        long tMin = Long.MAX_VALUE;\n        long tMax = Long.MIN_VALUE;\n        long vMin = Long.MAX_VALUE;\n        long vMax = 1;\n\n        int w = getWidth()-rightMargin-leftMargin-10;\n        int h = getHeight()-topMargin-bottomMargin;\n\n        if (times.size > 1) {\n            tMin = Math.min(tMin, times.time(0));\n            tMax = Math.max(tMax, times.time(times.size-1));\n        }\n        long viewRangeMS;\n        if (viewRange > 0) {\n            viewRangeMS = viewRange * MINUTE;\n        } else {\n            // Display full time range, but no less than a minute\n            viewRangeMS = Math.max(tMax - tMin, 1 * MINUTE);\n        }\n\n        // Calculate min/max values\n        for (Sequence seq : seqs) {\n            if (seq.size > 0) {\n                for (int i = 0; i < seq.size; i++) {\n                    if (seq.size == 1 || times.time(i) >= tMax - viewRangeMS) {\n                        long val = seq.value(i);\n                        if (val > Long.MIN_VALUE) {\n                            vMax = Math.max(vMax, val);\n                            vMin = Math.min(vMin, val);\n                        }\n                    }\n                }\n            } else {\n                vMin = 0L;\n            }\n            if (unit == Unit.BYTES || !seq.isPlotted) {\n                // We'll scale only to the first (main) value set.\n                // TODO: Use a separate property for this.\n                break;\n            }\n        }\n\n        // Normalize scale\n        vMax = normalizeMax(vMax);\n        if (vMin > 0) {\n            if (vMax / vMin > 4) {\n                vMin = 0;\n            } else {\n                vMin = normalizeMin(vMin);\n            }\n        }\n\n\n        g.setColor(fg);\n\n        // Axes\n        // Draw vertical axis\n        int x = leftMargin - 18;\n        int y = topMargin;\n        FontMetrics fm = g.getFontMetrics();\n\n        g.drawLine(x,   y,   x,   y+h);\n\n        int n = 5;\n        if ((\"\"+vMax).startsWith(\"2\")) { // NOI18N\n            n = 4;\n        } else if ((\"\"+vMax).startsWith(\"3\")) { // NOI18N\n            n = 6;\n        } else if ((\"\"+vMax).startsWith(\"4\")) { // NOI18N\n            n = 4;\n        } else if ((\"\"+vMax).startsWith(\"6\")) { // NOI18N\n            n = 6;\n        } else if ((\"\"+vMax).startsWith(\"7\")) { // NOI18N\n            n = 7;\n        } else if ((\"\"+vMax).startsWith(\"8\")) { // NOI18N\n            n = 8;\n        } else if ((\"\"+vMax).startsWith(\"9\")) { // NOI18N\n            n = 3;\n        }\n\n        // Ticks\n        ArrayList<Long> tickValues = new ArrayList<Long>();\n        tickValues.add(vMin);\n        for (int i = 0; i < n; i++) {\n            long v = i * vMax / n;\n            if (v > vMin) {\n                tickValues.add(v);\n            }\n        }\n        tickValues.add(vMax);\n        n = tickValues.size();\n\n        String[] tickStrings = new String[n];\n        for (int i = 0; i < n; i++) {\n            long v = tickValues.get(i);\n            tickStrings[i] = getSizeString(v, vMax);\n        }\n\n        // Trim trailing decimal zeroes.\n        if (decimals > 0) {\n            boolean trimLast = true;\n            boolean removedDecimalPoint = false;\n            do {\n                for (String str : tickStrings) {\n                    if (!(str.endsWith(\"0\") || str.endsWith(\".\"))) { // NOI18N\n                        trimLast = false;\n                        break;\n                    }\n                }\n                if (trimLast) {\n                    if (tickStrings[0].endsWith(\".\")) { // NOI18N\n                        removedDecimalPoint = true;\n                    }\n                    for (int i = 0; i < n; i++) {\n                        String str = tickStrings[i];\n                        tickStrings[i] = str.substring(0, str.length()-1);\n                    }\n                }\n            } while (trimLast && !removedDecimalPoint);\n        }\n\n        // Draw ticks\n        int lastY = Integer.MAX_VALUE;\n        for (int i = 0; i < n; i++) {\n            long v = tickValues.get(i);\n            y = topMargin+h-(int)(h * (v-vMin) / (vMax-vMin));\n            g.drawLine(x-2, y, x+2, y);\n            String s = tickStrings[i];\n            if (unit == Unit.PERCENT) {\n                s += \"%\"; // NOI18N\n            }\n            int sx = x-6-fm.stringWidth(s);\n            if (y < lastY-13) {\n                if (checkLeftMargin(sx)) {\n                    // Wait for next repaint\n                    return;\n                }\n                g.drawString(s, sx, y+4);\n            }\n            // Draw horizontal grid line\n            g.setColor(Color.lightGray);\n            g.drawLine(r.x + 4, y, r.x + r.width - 4, y);\n            g.setColor(fg);\n            lastY = y;\n        }\n\n        // Draw horizontal axis\n        x = leftMargin;\n        y = topMargin + h + 15;\n        g.drawLine(x,   y,   x+w, y);\n\n        long t1 = tMax;\n        if (t1 <= 0L) {\n            // No data yet, so draw current time\n            t1 = System.currentTimeMillis();\n        }\n        long tz = timeDF.getTimeZone().getOffset(t1);\n        long tickInterval = calculateTickInterval(w, 40, viewRangeMS);\n        if (tickInterval > 3 * HOUR) {\n            tickInterval = calculateTickInterval(w, 80, viewRangeMS);\n        }\n        long t0 = tickInterval - (t1 - viewRangeMS + tz) % tickInterval;\n        while (t0 < viewRangeMS) {\n            x = leftMargin + (int)(w * t0 / viewRangeMS);\n            g.drawLine(x, y-2, x, y+2);\n\n            long t = t1 - viewRangeMS + t0;\n            String str = formatClockTime(t);\n            g.drawString(str, x, y+16);\n            //if (tickInterval > (1 * HOUR) && t % (1 * DAY) == 0) {\n            if ((t + tz) % (1 * DAY) == 0) {\n                str = formatDate(t);\n                g.drawString(str, x, y+27);\n            }\n            // Draw vertical grid line\n            g.setColor(Color.lightGray);\n            g.drawLine(x, topMargin, x, topMargin + h);\n            g.setColor(fg);\n            t0 += tickInterval;\n        }\n\n        // Plot values\n        int start = 0;\n        int nValues = 0;\n        int nLists = seqs.size();\n        if (nLists > 0) {\n            nValues = seqs.get(0).size;\n        }\n        if (nValues == 0) {\n            g.setColor(oldColor);\n            return;\n        } else {\n            Sequence seq = seqs.get(0);\n            // Find starting point\n            for (int p = 0; p < seq.size; p++) {\n                if (times.time(p) >= tMax - viewRangeMS) {\n                    start = p;\n                    break;\n                }\n            }\n        }\n\n        //Optimization: collapse plot of more than four values per pixel\n        int pointsPerPixel = (nValues - start) / w;\n        if (pointsPerPixel < 4) {\n            pointsPerPixel = 1;\n        }\n\n        // Draw graphs\n        // Loop backwards over sequences because the first needs to be painted on top\n        for (int i = nLists-1; i >= 0; i--) {\n            int x0 = leftMargin;\n            int y0 = topMargin + h + 1;\n\n            Sequence seq = seqs.get(i);\n            if (seq.isPlotted && seq.size > 0) {\n                // Paint twice, with white and with color\n                for (int pass = 0; pass < 2; pass++) {\n                    g.setColor((pass == 0) ? Color.white : seq.color);\n                    int x1 = -1;\n                    long v1 = -1;\n                    for (int p = start; p < nValues; p += pointsPerPixel) {\n                        // Make sure we get the last value\n                        if (pointsPerPixel > 1 && p >= nValues - pointsPerPixel) {\n                            p = nValues - 1;\n                        }\n                        int x2 = (int)(w * (times.time(p)-(t1-viewRangeMS)) / viewRangeMS);\n                        long v2 = seq.value(p);\n                        if (v2 >= vMin && v2 <= vMax) {\n                            int y2  = (int)(h * (v2 -vMin) / (vMax-vMin));\n                            if (x1 >= 0 && v1 >= vMin && v1 <= vMax) {\n                                int y1 = (int)(h * (v1-vMin) / (vMax-vMin));\n\n                                if (y1 == y2) {\n                                    // fillrect is much faster\n                                    g.fillRect(x0+x1, y0-y1-pass, x2-x1, 1);\n                                } else {\n                                    Graphics2D g2d = (Graphics2D)g;\n                                    Stroke oldStroke = null;\n                                    if (seq.transitionStroke != null) {\n                                        oldStroke = g2d.getStroke();\n                                        g2d.setStroke(seq.transitionStroke);\n                                    }\n                                    g.drawLine(x0+x1, y0-y1-pass, x0+x2, y0-y2-pass);\n                                    if (oldStroke != null) {\n                                        g2d.setStroke(oldStroke);\n                                    }\n                                }\n                            }\n                        }\n                        x1 = x2;\n                        v1 = v2;\n                    }\n                }\n\n                // Current value\n                long v = seq.value(seq.size - 1);\n                if (v >= vMin && v <= vMax) {\n                    if (bgIsLight) {\n                        g.setColor(seq.color);\n                    } else {\n                        g.setColor(fg);\n                    }\n                    x = r.x + r.width + 2;\n                    y = topMargin+h-(int)(h * (v-vMin) / (vMax-vMin));\n                    // a small triangle/arrow\n                    g.fillPolygon(new int[] { x+2, x+6, x+6 },\n                                  new int[] { y,   y+3, y-3 },\n                                  3);\n                }\n                g.setColor(fg);\n            }\n        }\n\n        int[] valueStringSlots = new int[nLists];\n        for (int i = 0; i < nLists; i++) valueStringSlots[i] = -1;\n        for (int i = 0; i < nLists; i++) {\n            Sequence seq = seqs.get(i);\n            if (seq.isPlotted && seq.size > 0) {\n                // Draw current value\n\n                // TODO: collapse values if pointsPerPixel >= 4\n\n                long v = seq.value(seq.size - 1);\n                if (v >= vMin && v <= vMax) {\n                    x = r.x + r.width + 2;\n                    y = topMargin+h-(int)(h * (v-vMin) / (vMax-vMin));\n                    int y2 = getValueStringSlot(valueStringSlots, y, 2*10, i);\n                    g.setFont(smallFont);\n                    if (bgIsLight) {\n                        g.setColor(seq.color);\n                    } else {\n                        g.setColor(fg);\n                    }\n                    String curValue = getFormattedValue(v, true);\n                    if (unit == Unit.PERCENT) {\n                        curValue += \"%\"; // NOI18N\n                    }\n                    int valWidth = fm.stringWidth(curValue);\n                    String legend = displayLegend?seq.name:\"\";\n                    int legendWidth = fm.stringWidth(legend);\n                    if (checkRightMargin(valWidth) || checkRightMargin(legendWidth)) {\n                        // Wait for next repaint\n                        return;\n                    }\n                    g.drawString(legend  , x + 17, Math.min(topMargin+h,      y2 + 3 - 10));\n                    g.drawString(curValue, x + 17, Math.min(topMargin+h + 10, y2 + 3));\n\n                    // Maybe draw a short line to value\n                    if (y2 > y + 3) {\n                        g.drawLine(x + 9, y + 2, x + 14, y2);\n                    } else if (y2 < y - 3) {\n                        g.drawLine(x + 9, y - 2, x + 14, y2);\n                    }\n                }\n                g.setFont(oldFont);\n                g.setColor(fg);\n\n            }\n        }\n        g.setColor(oldColor);\n    }\n\n    private boolean checkLeftMargin(int x) {\n        // Make sure leftMargin has at least 2 pixels over\n        if (x < 2) {\n            leftMargin += (2 - x);\n            // Repaint from top (above any cell renderers)\n            SwingUtilities.getWindowAncestor(this).repaint();\n            return true;\n        }\n        return false;\n    }\n\n    private boolean checkRightMargin(int w) {\n        // Make sure rightMargin has at least 2 pixels over\n        if (w + 2 > rightMargin) {\n            rightMargin = (w + 2);\n            // Repaint from top (above any cell renderers)\n            SwingUtilities.getWindowAncestor(this).repaint();\n            return true;\n        }\n        return false;\n    }\n\n    private int getValueStringSlot(int[] slots, int y, int h, int i) {\n        for (int s = 0; s < slots.length; s++) {\n            if (slots[s] >= y && slots[s] < y + h) {\n                // collide below us\n                if (slots[s] > h) {\n                    return getValueStringSlot(slots, slots[s]-h, h, i);\n                } else {\n                    return getValueStringSlot(slots, slots[s]+h, h, i);\n                }\n            } else if (y >= h && slots[s] > y - h && slots[s] < y) {\n                // collide above us\n                return getValueStringSlot(slots, slots[s]+h, h, i);\n            }\n        }\n        slots[i] = y;\n        return y;\n    }\n\n    private long calculateTickInterval(int w, int hGap, long viewRangeMS) {\n        long tickInterval = viewRangeMS * hGap / w;\n        if (tickInterval < 1 * MINUTE) {\n            tickInterval = 1 * MINUTE;\n        } else if (tickInterval < 5 * MINUTE) {\n            tickInterval = 5 * MINUTE;\n        } else if (tickInterval < 10 * MINUTE) {\n            tickInterval = 10 * MINUTE;\n        } else if (tickInterval < 30 * MINUTE) {\n            tickInterval = 30 * MINUTE;\n        } else if (tickInterval < 1 * HOUR) {\n            tickInterval = 1 * HOUR;\n        } else if (tickInterval < 3 * HOUR) {\n            tickInterval = 3 * HOUR;\n        } else if (tickInterval < 6 * HOUR) {\n            tickInterval = 6 * HOUR;\n        } else if (tickInterval < 12 * HOUR) {\n            tickInterval = 12 * HOUR;\n        } else if (tickInterval < 1 * DAY) {\n            tickInterval = 1 * DAY;\n        } else {\n            tickInterval = normalizeMax(tickInterval / DAY) * DAY;\n        }\n        return tickInterval;\n    }\n\n    private long normalizeMin(long l) {\n        int exp = (int)Math.log10((double)l);\n        long multiple = (long)Math.pow(10.0, exp);\n        int i = (int)(l / multiple);\n        return i * multiple;\n    }\n\n    private long normalizeMax(long l) {\n        int exp = (int)Math.log10((double)l);\n        long multiple = (long)Math.pow(10.0, exp);\n        int i = (int)(l / multiple);\n        l = (i+1)*multiple;\n        return l;\n    }\n\n    private String getFormattedValue(long v, boolean groupDigits) {\n        String str;\n        String fmt = \"%\"; // NOI18N\n        if (groupDigits) {\n            fmt += \",\"; // NOI18N\n        }\n        if (decimals > 0) {\n            fmt += \".\" + decimals + \"f\"; // NOI18N\n            str = String.format(fmt, v / decimalsMultiplier);\n        } else {\n            fmt += \"d\"; // NOI18N\n            str = String.format(fmt, v);\n        }\n        return str;\n    }\n\n    private String getSizeString(long v, long vMax) {\n        String s;\n\n        if (unit == Unit.BYTES && decimals == 0) {\n            s = formatBytes(v, vMax);\n        } else {\n            s = getFormattedValue(v, true);\n        }\n        return s;\n    }\n\n    private static synchronized Stroke getDashedStroke() {\n        if (dashedStroke == null) {\n            dashedStroke = new BasicStroke(1.0f,\n                                           BasicStroke.CAP_BUTT,\n                                           BasicStroke.JOIN_MITER,\n                                           10.0f,\n                                           new float[] { 2.0f, 3.0f },\n                                           0.0f);\n        }\n        return dashedStroke;\n    }\n\n    private static Object extendArray(Object a1) {\n        int n = Array.getLength(a1);\n        Object a2 =\n            Array.newInstance(a1.getClass().getComponentType(),\n                              n + ARRAY_SIZE_INCREMENT);\n        System.arraycopy(a1, 0, a2, 0, n);\n        return a2;\n    }\n\n\n    private static class TimeStamps {\n        // Time stamps (long) are split into offsets (long) and a\n        // series of times from the offsets (int). A new offset is\n        // stored when the the time value doesn't fit in an int\n        // (approx every 24 days).  An array of indices is used to\n        // define the starting point for each offset in the times\n        // array.\n        long[] offsets = new long[0];\n        int[] indices = new int[0];\n        int[] rtimes = new int[ARRAY_SIZE_INCREMENT];\n\n        // Number of stored timestamps\n        int size = 0;\n\n        /**\n         * Returns the time stamp for index i\n         */\n        public long time(int i) {\n            long offset = 0;\n            for (int j = indices.length - 1; j >= 0; j--) {\n                if (i >= indices[j]) {\n                    offset = offsets[j];\n                    break;\n                }\n            }\n            return offset + rtimes[i];\n        }\n\n        public void add(long time) {\n            // May need to store a new time offset\n            int n = offsets.length;\n            if (n == 0 || time - offsets[n - 1] > Integer.MAX_VALUE) {\n                // Grow offset and indices arrays and store new offset\n                offsets = Arrays.copyOf(offsets, n + 1);\n                offsets[n] = time;\n                indices = Arrays.copyOf(indices, n + 1);\n                indices[n] = size;\n            }\n\n            // May need to extend the array size\n            if (rtimes.length == size) {\n                rtimes = (int[])extendArray(rtimes);\n            }\n\n            // Store the time\n            rtimes[size]  = (int)(time - offsets[offsets.length - 1]);\n            size++;\n        }\n    }\n\n    private static class Sequence {\n        String key;\n        String name;\n        Color color;\n        boolean isPlotted;\n        Stroke transitionStroke = null;\n\n        // Values are stored in an int[] if all values will fit,\n        // otherwise in a long[]. An int can represent up to 2 GB.\n        // Use a random start size, so all arrays won't need to\n        // be grown during the same update interval\n        Object values =\n            new byte[ARRAY_SIZE_INCREMENT + (int)(Math.random() * 100)];\n\n        // Number of stored values\n        int size = 0;\n\n        public Sequence(String key) {\n            this.key = key;\n        }\n\n        /**\n         * Returns the value at index i\n         */\n        public long value(int i) {\n            return Array.getLong(values, i);\n        }\n\n        public void add(long value) {\n            // May need to switch to a larger array type\n            if ((values instanceof byte[] ||\n                 values instanceof short[] ||\n                 values instanceof int[]) &&\n                       value > Integer.MAX_VALUE) {\n                long[] la = new long[Array.getLength(values)];\n                for (int i = 0; i < size; i++) {\n                    la[i] = Array.getLong(values, i);\n                }\n                values = la;\n            } else if ((values instanceof byte[] ||\n                        values instanceof short[]) &&\n                       value > Short.MAX_VALUE) {\n                int[] ia = new int[Array.getLength(values)];\n                for (int i = 0; i < size; i++) {\n                    ia[i] = Array.getInt(values, i);\n                }\n                values = ia;\n            } else if (values instanceof byte[] &&\n                       value > Byte.MAX_VALUE) {\n                short[] sa = new short[Array.getLength(values)];\n                for (int i = 0; i < size; i++) {\n                    sa[i] = Array.getShort(values, i);\n                }\n                values = sa;\n            }\n\n            // May need to extend the array size\n            if (Array.getLength(values) == size) {\n                values = extendArray(values);\n            }\n\n            // Store the value\n            if (values instanceof long[]) {\n                ((long[])values)[size] = value;\n            } else if (values instanceof int[]) {\n                ((int[])values)[size] = (int)value;\n            } else if (values instanceof short[]) {\n                ((short[])values)[size] = (short)value;\n            } else {\n                ((byte[])values)[size] = (byte)value;\n            }\n            size++;\n        }\n    }\n\n    // Can be overridden by subclasses\n    long getValue() {\n        return 0;\n    }\n\n    long getLastTimeStamp() {\n        return times.time(times.size - 1);\n    }\n\n    long getLastValue(String key) {\n        Sequence seq = getSequence(key);\n        return (seq != null && seq.size > 0) ? seq.value(seq.size - 1) : 0L;\n    }\n\n\n    // Called on EDT\n    public void propertyChange(PropertyChangeEvent ev) {\n        if (JmxModel.CONNECTION_STATE_PROPERTY.equals(ev.getPropertyName())) {\n            ConnectionState newState = (ConnectionState) ev.getNewValue();\n            switch (newState) {\n              case DISCONNECTED:\n                synchronized (this) {\n                    long time = System.currentTimeMillis();\n                    times.add(time);\n                    for (Sequence seq : seqs) {\n                        seq.add(Long.MIN_VALUE);\n                    }\n                }\n                break;\n            }\n        }\n    }\n\n    private static class SaveDataFileChooser extends JFileChooser {\n        SaveDataFileChooser() {\n            setFileFilter(new FileNameExtensionFilter(\"CSV file\", \"csv\")); // NOI18N\n        }\n\n        @Override\n        public void approveSelection() {\n            File file = getSelectedFile();\n            if (file != null) {\n                FileFilter filter = getFileFilter();\n                if (filter != null && filter instanceof FileNameExtensionFilter) {\n                    String[] extensions =\n                        ((FileNameExtensionFilter)filter).getExtensions();\n\n                    boolean goodExt = false;\n                    for (String ext : extensions) {\n                        if (file.getName().toLowerCase().endsWith(\".\" + ext.toLowerCase())) { // NOI18N\n                            goodExt = true;\n                            break;\n                        }\n                    }\n                    if (!goodExt) {\n                        file = new File(file.getParent(),\n                                        file.getName() + \".\" + extensions[0]); // NOI18N\n                    }\n                }\n\n                if (file.exists()) {\n                    String okStr = getText(\"LBL_FileChooser.fileExists.okOption\"); // NOI18N\n                    String cancelStr = getText(\"LBL_FileChooser.fileExists.cancelOption\"); // NOI18N\n                    int ret =\n                        JOptionPane.showOptionDialog(this,\n                                                     getText(\"LBL_FileChooser.fileExists.message\", // NOI18N\n                                                             file.getName()),\n                                                     getText(\"LBL_FileChooser.fileExists.title\"), // NOI18N\n                                                     JOptionPane.OK_CANCEL_OPTION,\n                                                     JOptionPane.WARNING_MESSAGE,\n                                                     null,\n                                                     new Object[] { okStr, cancelStr },\n                                                     okStr);\n                    if (ret != JOptionPane.OK_OPTION) {\n                        return;\n                    }\n                }\n                setSelectedFile(file);\n            }\n            super.approveSelection();\n        }\n    }\n\n    @Override\n    public AccessibleContext getAccessibleContext() {\n        if (accessibleContext == null) {\n            accessibleContext = new AccessiblePlotter();\n        }\n        return accessibleContext;\n    }\n\n    protected class AccessiblePlotter extends AccessibleJComponent {\n        protected AccessiblePlotter() {\n            setAccessibleName(getText(\"LBL_Plotter.accessibleName\")); // NOI18N\n        }\n\n        @Override\n        public String getAccessibleName() {\n            String name = super.getAccessibleName();\n\n            if (seqs.size() > 0 && seqs.get(0).size > 0) {\n                String keyValueList = \"\"; // NOI18N\n                for (Sequence seq : seqs) {\n                    if (seq.isPlotted) {\n                        String value = \"null\"; // NOI18N\n                        if (seq.size > 0) {\n                            if (unit == Unit.BYTES) {\n                                value = getText(\"LBL_SizeBytes\", seq.value(seq.size - 1)); // NOI18N\n                            } else {\n                                value =\n                                    getFormattedValue(seq.value(seq.size - 1), false) +\n                                    ((unit == Unit.PERCENT) ? \"%\" : \"\"); // NOI18N\n                            }\n                        }\n                        // Assume format string ends with newline\n                        keyValueList +=\n                            getText(\"LBL_Plotter.accessibleName.keyAndValue\", // NOI18N\n                                    seq.key, value);\n                    }\n                }\n                name += \"\\n\" + keyValueList + \".\"; // NOI18N\n            } else {\n                name += \"\\n\" + getText(\"LBL_Plotter.accessibleName.noData\"); // NOI18N\n            }\n            return name;\n        }\n\n        @Override\n        public AccessibleRole getAccessibleRole() {\n            return AccessibleRole.CANVAS;\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/PlotterPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\nimport javax.accessibility.*;\nimport javax.swing.*;\n\n@SuppressWarnings(\"serial\")\nclass PlotterPanel extends BorderedComponent {\n    private Plotter plotter;\n\n    public PlotterPanel(String labelStr, Plotter.Unit unit, boolean collapsible) {\n        super(labelStr, new Plotter(unit), collapsible);\n\n        this.plotter = (Plotter)comp;\n\n        init();\n    }\n\n    public PlotterPanel(String labelStr) {\n        super(labelStr, null);\n\n        init();\n    }\n\n    public Plotter getPlotter() {\n        return this.plotter;\n    }\n\n    public void setPlotter(Plotter plotter) {\n        this.plotter = plotter;\n        setComponent(plotter);\n    }\n\n    private void init() {\n        setFocusable(true);\n\n        addMouseListener(new MouseAdapter() {\n            public void mousePressed(MouseEvent e) {\n                requestFocusInWindow();\n            }\n        });\n    }\n\n    public JPopupMenu getComponentPopupMenu() {\n        return (getPlotter() != null)? getPlotter().getComponentPopupMenu() : null;\n    }\n\n    public AccessibleContext getAccessibleContext() {\n        if (accessibleContext == null) {\n            accessibleContext = new AccessiblePlotterPanel();\n        }\n        return accessibleContext;\n    }\n\n    protected class AccessiblePlotterPanel extends AccessibleJComponent {\n        public String getAccessibleName() {\n            String name = null;\n            if (getPlotter() != null) {\n                name = getPlotter().getAccessibleContext().getAccessibleName();\n            }\n            if (name == null) {\n                name = super.getAccessibleName();\n            }\n            return name;\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Resources.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport org.openide.util.NbBundle;\n\n/**\n * Provides resource support for the containing java package.\n */\nfinal class Resources {\n\n    private Resources() {\n        throw new AssertionError();\n    }\n\n    /**\n     * Returns the text of the resource for the specified\n     * key formatted with the specified arguments.\n     */\n    public static String getText(String key, Object... args) {\n        return NbBundle.getMessage(Resources.class, key, args);\n    }\n\n    /**\n     * Returns the mnemonic keycode int of the resource for\n     * the specified key.\n     */\n    public static int getMnemonicInt(String key) {\n        String m = getText(key + \".mnemonic\"); // NOI18N\n        int mnemonic = m.charAt(0);\n        if (mnemonic >= 'a' && mnemonic <= 'z') {\n            mnemonic -= ('a' - 'A');\n        }\n        return mnemonic;\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/TableSorter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.util.*;\nimport java.awt.event.*;\nimport javax.swing.table.*;\nimport javax.swing.event.*;\n\n// Imports for picking up mouse events from the JTable.\n\nimport java.awt.event.MouseEvent;\nimport javax.swing.JTable;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.table.TableColumnModel;\n\n@SuppressWarnings(\"serial\")\nclass TableSorter extends DefaultTableModel implements MouseListener {\n    private boolean ascending = true;\n    private TableColumnModel columnModel;\n    private JTable tableView;\n    private Vector<TableModelListener> evtListenerList;\n    private int sortColumn = 0;\n\n    private int[] invertedIndex;\n\n    public TableSorter() {\n        super();\n        evtListenerList = new Vector<TableModelListener>();\n    }\n\n    public TableSorter(Object[] columnNames, int numRows) {\n        super(columnNames,numRows);\n        evtListenerList = new Vector<TableModelListener>();\n    }\n\n    @Override\n    public void newDataAvailable(TableModelEvent e) {\n        super.newDataAvailable(e);\n        invertedIndex = new int[getRowCount()];\n        for (int i = 0; i < invertedIndex.length; i++) {\n            invertedIndex[i] = i;\n        }\n        sort(this.sortColumn, this.ascending);\n    }\n\n    @Override\n    public void addTableModelListener(TableModelListener l) {\n        evtListenerList.add(l);\n        super.addTableModelListener(l);\n    }\n\n    @Override\n    public void removeTableModelListener(TableModelListener l) {\n        evtListenerList.remove(l);\n        super.removeTableModelListener(l);\n    }\n\n    private void removeListeners() {\n        for(TableModelListener tnl : evtListenerList)\n            super.removeTableModelListener(tnl);\n    }\n\n    private void restoreListeners() {\n        for(TableModelListener tnl : evtListenerList)\n            super.addTableModelListener(tnl);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private int compare(Object o1, Object o2) {\n        // take care of the case where both o1 & o2 are null. Needed to keep\n        // the method symetric. Without this quickSort gives surprising results.\n        if (o1 == o2)\n            return 0;\n        if (o1==null)\n            return 1;\n        if (o2==null)\n            return -1;\n        //two object of the same class and that are comparable\n        else if ((o1.getClass().equals(o2.getClass())) &&\n                 (o1 instanceof Comparable)) {\n            return (((Comparable) o1).compareTo(o2));\n        }\n        else {\n            return o1.toString().compareTo(o2.toString());\n        }\n    }\n\n    private void sort(int column, boolean isAscending) {\n        final XMBeanAttributes attrs =\n                (tableView instanceof XMBeanAttributes)\n                ?(XMBeanAttributes) tableView\n                :null;\n\n        // We cannot sort rows when a cell is being\n        // edited - so we're going to cancel cell editing here if needed.\n        // This might happen when the user is editing a row, and clicks on\n        // another row without validating. In that case there are two events\n        // that compete: one is the validation of the value that was previously\n        // edited, the other is the mouse click that opens the new editor.\n        //\n        // When we reach here the previous value is already validated, and the\n        // old editor is closed, but the new editor might have opened.\n        // It's this new editor that wil be cancelled here, if needed.\n        //\n        if (attrs != null && attrs.isEditing())\n            attrs.cancelCellEditing();\n\n        // remove registered listeners\n        removeListeners();\n        // do the sort\n        quickSort(0,getRowCount()-1,column,isAscending);\n        // restore registered listeners\n        restoreListeners();\n\n        // update row heights in XMBeanAttributes (required by expandable cells)\n        if (attrs != null) {\n            for (int i = 0; i < getRowCount(); i++) {\n                Vector data = (Vector) dataVector.elementAt(i);\n                attrs.updateRowHeight(data.elementAt(1), i);\n            }\n        }\n    }\n\n    private boolean compareS(Object s1, Object s2, boolean isAscending) {\n        if (isAscending)\n            return (compare(s1,s2) > 0);\n        else\n            return (compare(s1,s2) < 0);\n    }\n\n    private boolean compareG(Object s1, Object s2, boolean isAscending) {\n        if (isAscending)\n            return (compare(s1,s2) < 0);\n        else\n            return (compare(s1,s2) > 0);\n    }\n\n    private void quickSort(int lo0,int hi0, int key, boolean isAscending) {\n        int lo = lo0;\n        int hi = hi0;\n        Object mid;\n\n        if ( hi0 > lo0)\n            {\n                mid = getValueAt( ( lo0 + hi0 ) / 2 , key);\n\n                while( lo <= hi )\n                    {\n                        /* find the first element that is greater than\n                         * or equal to the partition element starting\n                         * from the left Index.\n                         */\n                        while( ( lo < hi0 ) &&\n                               ( compareS(mid,getValueAt(lo,key), isAscending) ))\n                            ++lo;\n\n                        /* find an element that is smaller than or equal to\n                         * the partition element starting from the right Index.\n                         */\n                        while( ( hi > lo0 ) &&\n                               ( compareG(mid,getValueAt(hi,key), isAscending) ))\n                            --hi;\n\n                        // if the indexes have not crossed, swap\n                        if( lo <= hi )\n                            {\n                                swap(lo, hi, key);\n                                ++lo;\n                                --hi;\n                            }\n                    }\n\n                                /* If the right index has not reached the\n                                 * left side of array\n                                 * must now sort the left partition.\n                                 */\n                if( lo0 < hi )\n                    quickSort(lo0, hi , key, isAscending);\n\n                                /* If the left index has not reached the right\n                                 * side of array\n                                 * must now sort the right partition.\n                                 */\n                if( lo <= hi0 )\n                    quickSort(lo, hi0 , key, isAscending);\n            }\n    }\n\n    private Vector getRow(int row) {\n        return (Vector) dataVector.elementAt(row);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private void setRow(Vector data, int row) {\n        dataVector.setElementAt(data,row);\n    }\n\n    private void swap(int i, int j, int column) {\n        Vector data = getRow(i);\n        setRow(getRow(j),i);\n        setRow(data,j);\n\n        int a = invertedIndex[i];\n        invertedIndex[i] = invertedIndex[j];\n        invertedIndex[j] = a;\n    }\n\n    public void sortByColumn(int column) {\n        sortByColumn(column, !ascending);\n    }\n\n    public void sortByColumn(int column, boolean ascending) {\n        this.ascending = ascending;\n        this.sortColumn = column;\n        sort(column,ascending);\n    }\n\n    public int getIndexOfRow(int row) {\n        return invertedIndex[row];\n    }\n\n    // Add a mouse listener to the Table to trigger a table sort\n    // when a column heading is clicked in the JTable.\n    public void addMouseListenerToHeaderInTable(JTable table) {\n        tableView = table;\n        columnModel = tableView.getColumnModel();\n        JTableHeader th = tableView.getTableHeader();\n        th.addMouseListener(this);\n    }\n\n    public void mouseClicked(MouseEvent e) {\n        int viewColumn = columnModel.getColumnIndexAtX(e.getX());\n        int column = tableView.convertColumnIndexToModel(viewColumn);\n        if (e.getClickCount() == 1 && column != -1) {\n            if (tableView instanceof XTable) {\n                XTable attrs = (XTable) tableView;\n                // inform the table view that the rows are going to be sorted\n                // against the values in a given column. This gives the\n                // chance to the table view to close its editor - if needed.\n                //\n                attrs.sortRequested(column);\n            }\n            tableView.invalidate();\n            sortByColumn(column);\n            tableView.validate();\n            tableView.repaint();\n        }\n    }\n\n    public void mousePressed(MouseEvent e) {\n    }\n\n    public void mouseEntered(MouseEvent e) {\n    }\n\n    public void mouseExited(MouseEvent e) {\n    }\n\n    public void mouseReleased(MouseEvent e) {\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/ThreadDialog.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.*;\nimport javax.swing.*;\nimport java.io.*;\n\nclass ThreadDialog implements Runnable {\n\n    Component parentComponent;\n    Object message;\n    String title;\n    int messageType;\n\n    public ThreadDialog(Component parentComponent,\n                        Object message,\n                        String title,\n                        int messageType) {\n        this.parentComponent = parentComponent;\n        this.message = message;\n        this.title = title;\n        this.messageType = messageType;\n    }\n\n    public void run() {\n        JOptionPane pane = new JOptionPane(message, messageType);\n        JDialog dialog = pane.createDialog(parentComponent, title);\n        dialog.setResizable(true);\n        dialog.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Utilities.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.*;\n\nimport javax.accessibility.*;\nimport javax.swing.*;\nimport javax.swing.border.*;\nimport javax.swing.tree.*;\n\nimport static java.lang.Math.*;\n\n/**\n * Miscellaneous utility methods for JConsole\n */\nclass Utilities {\n    private static final String windowsLaF =\n        \"com.sun.java.swing.plaf.windows.WindowsLookAndFeel\"; // NOI18N\n\n    public static void updateTransparency(JComponent comp) {\n        LookAndFeel laf = UIManager.getLookAndFeel();\n        boolean transparent = laf.getClass().getName().equals(windowsLaF);\n        setTabbedPaneTransparency(comp, transparent);\n    }\n\n    private static void setTabbedPaneTransparency(JComponent comp, boolean transparent) {\n        for (Component child : comp.getComponents()) {\n            if (comp instanceof JTabbedPane) {\n                setTransparency((JComponent)child, transparent);\n            } else if (child instanceof JComponent) {\n                setTabbedPaneTransparency((JComponent)child, transparent);\n            }\n        }\n    }\n\n    private static void setTransparency(JComponent comp, boolean transparent) {\n        comp.setOpaque(!transparent);\n        for (Component child : comp.getComponents()) {\n            if (child instanceof JPanel ||\n                child instanceof JSplitPane ||\n                child instanceof JScrollPane ||\n                child instanceof JViewport ||\n                child instanceof JCheckBox) {\n\n                setTransparency((JComponent)child, transparent);\n            }\n            if (child instanceof XTree) {\n                XTree t = (XTree)child;\n                DefaultTreeCellRenderer cr = (DefaultTreeCellRenderer)t.getCellRenderer();\n\n                cr.setBackground(null);\n                cr.setBackgroundNonSelectionColor(new Color(0, 0, 0, 1));\n                t.setCellRenderer(cr);\n                setTransparency((JComponent)child, transparent);\n            }\n        }\n    }\n\n\n    /**\n     * A slightly modified border for JScrollPane to be used with a JTable inside\n     * a JTabbedPane. It has only top part and the rest is clipped to make the\n     * overall border less thick.\n     * The top border helps differentiating the containing table from its container.\n     */\n    public static JScrollPane newTableScrollPane(JComponent comp) {\n        return new TableScrollPane(comp);\n    }\n\n    @SuppressWarnings(\"serial\")\n    private static class TableScrollPane extends JScrollPane {\n        public TableScrollPane(JComponent comp) {\n            super(comp);\n        }\n\n        @Override\n        protected void paintBorder(Graphics g) {\n            Border border = getBorder();\n            if (border != null) {\n                Insets insets = border.getBorderInsets(this);\n                if (insets != null) {\n                    Shape oldClip = g.getClip();\n                    g.clipRect(0, 0, getWidth(), insets.top);\n                    super.paintBorder(g);\n                    g.setClip(oldClip);\n                }\n            }\n        }\n    }\n\n    public static void setAccessibleName(Accessible comp, String name) {\n        comp.getAccessibleContext().setAccessibleName(name);\n    }\n\n    public static void setAccessibleDescription(Accessible comp, String description) {\n        comp.getAccessibleContext().setAccessibleDescription(description);\n    }\n\n\n    /**\n     * Modifies color c1 to ensure it has acceptable contrast\n     * relative to color c2.\n     *\n     * http://www.w3.org/TR/AERT#color-contrast\n     * http://www.cs.rit.edu/~ncs/color/t_convert.html#RGB%20to%20YIQ%20&%20YIQ%20to%20RGB\n     */\n    public static Color ensureContrast(Color c1, Color c2) {\n        double y1 = getColorBrightness(c1);\n        double y2 = getColorBrightness(c2);\n\n        if (abs(y1 - y2) < 125.0) {\n            if (y2 < 128.0) {\n                c1 = setColorBrightness(c1, y2 + 125.0);\n            } else {\n                c1 = setColorBrightness(c1, y2 - 125.0);\n            }\n        }\n\n        return c1;\n    }\n\n    public static double getColorBrightness(Color c) {\n        // Convert RGB -> YIQ and return the Y value\n        return (c.getRed() * 0.299 + c.getGreen() * 0.587 + c.getBlue() * 0.114);\n    }\n\n    private static Color setColorBrightness(Color c, double y) {\n        // Convert YIQ -> RGB\n        double i = (c.getRed() * 0.596 - c.getGreen() * 0.275 - c.getBlue() * 0.321);\n        double q = (c.getRed() * 0.212 - c.getGreen() * 0.523 + c.getBlue() * 0.311);\n\n        // Keep values in legal range. This may reduce the\n        // achieved contrast somewhat.\n        int r = max(0, min(255, (int)round(y + i * 0.956 + q * 0.621)));\n        int g = max(0, min(255, (int)round(y - i * 0.272 - q * 0.647)));\n        int b = max(0, min(255, (int)round(y - i * 1.105 + q * 1.702)));\n\n        return new Color(r, g, b);\n    }\n\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/Utils.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.event.*;\nimport java.lang.reflect.*;\nimport java.math.BigDecimal;\nimport java.math.BigInteger;\nimport java.util.*;\nimport java.util.concurrent.ExecutionException;\nimport javax.management.*;\nimport javax.management.openmbean.*;\nimport javax.swing.*;\nimport javax.swing.text.*;\n\nclass Utils {\n    \n    private Utils() {\n    }\n    \n    private static Set<Integer> tableNavigationKeys =\n            new HashSet<Integer>(Arrays.asList(new Integer[] {\n        KeyEvent.VK_TAB, KeyEvent.VK_ENTER,\n        KeyEvent.VK_HOME, KeyEvent.VK_END,\n        KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT,\n        KeyEvent.VK_UP, KeyEvent.VK_DOWN,\n        KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN}));\n    \n    private static final Set<Class<?>> primitiveWrappers =\n            new HashSet<Class<?>>(Arrays.asList(new Class<?>[] {\n        Byte.class, Short.class, Integer.class, Long.class,\n        Float.class, Double.class, Character.class, Boolean.class}));\n    \n    private static final Set<Class<?>> primitives = new HashSet<Class<?>>();\n    \n    private static final Map<String, Class<?>> primitiveMap =\n            new HashMap<String, Class<?>>();\n    \n    private static final Map<String, Class<?>> primitiveToWrapper =\n            new HashMap<String, Class<?>>();\n    \n    private static final Set<String> editableTypes = new HashSet<String>();\n    \n    private static final Set<Class<?>> extraEditableClasses =\n            new HashSet<Class<?>>(Arrays.asList(new Class<?>[] {\n        BigDecimal.class, BigInteger.class, Number.class,\n        String.class, String[].class, ObjectName.class}));\n    \n    private static final Set<String> numericalTypes = new HashSet<String>();\n    \n    private static final Set<String> extraNumericalTypes =\n            new HashSet<String>(Arrays.asList(new String[] {\n        BigDecimal.class.getName(), BigInteger.class.getName(),\n        Number.class.getName()}));\n    \n    private static final Set<String> booleanTypes =\n            new HashSet<String>(Arrays.asList(new String[] {\n        Boolean.TYPE.getName(), Boolean.class.getName()}));\n    \n    static {\n        // compute primitives/primitiveMap/primitiveToWrapper\n        for (Class<?> c : primitiveWrappers) {\n            try {\n                Field f = c.getField(\"TYPE\"); // NOI18N\n                Class<?> p = (Class<?>) f.get(null);\n                primitives.add(p);\n                primitiveMap.put(p.getName(), p);\n                primitiveToWrapper.put(p.getName(), c);\n            } catch (Exception e) {\n                throw new AssertionError(e);\n            }\n        }\n        // compute editableTypes\n        for (Class<?> c : primitives) {\n            editableTypes.add(c.getName());\n        }\n        for (Class<?> c : primitiveWrappers) {\n            editableTypes.add(c.getName());\n        }\n        for (Class<?> c : extraEditableClasses) {\n            editableTypes.add(c.getName());\n        }\n        // compute numericalTypes\n        for (Class<?> c : primitives) {\n            String name = c.getName();\n            if (!name.equals(Boolean.TYPE.getName())) {\n                numericalTypes.add(name);\n            }\n        }\n        for (Class<?> c : primitiveWrappers) {\n            String name = c.getName();\n            if (!name.equals(Boolean.class.getName())) {\n                numericalTypes.add(name);\n            }\n        }\n    }\n    \n    /**\n     * This method returns the class matching the name className.\n     * It's used to cater for the primitive types.\n     */\n    public static Class<?> getClass(String className)\n    throws ClassNotFoundException {\n        Class<?> c;\n        if ((c = primitiveMap.get(className)) != null)\n            return c;\n        return Class.forName(className);\n    }\n    \n    /**\n     * Check if the given collection is a uniform collection of the given type.\n     */\n    public static boolean isUniformCollection(Collection<?> c, Class<?> e) {\n        if (e == null) {\n            throw new IllegalArgumentException(\"Null reference type\"); // NOI18N\n        }\n        if (c == null) {\n            throw new IllegalArgumentException(\"Null collection\"); // NOI18N\n        }\n        if (c.isEmpty()) {\n            return false;\n        }\n        for (Object o : c) {\n            if (o == null || !e.isAssignableFrom(o.getClass())) {\n                return false;\n            }\n        }\n        return true;\n    }\n    \n    /**\n     * Check if the given element denotes a supported array-friendly data\n     * structure, i.e. a data structure jconsole can render as an array.\n     */\n    public static boolean canBeRenderedAsArray(Object elem) {\n        if (isSupportedArray(elem)) return true;\n        if (elem instanceof Collection) {\n            Collection<?> c = (Collection<?>) elem;\n            if (c.isEmpty()) {\n                // Empty collections of any Java type are not handled as arrays\n                //\n                return false;\n            } else {\n                // - Collections of CompositeData/TabularData are not handled\n                //   as arrays\n                // - Collections of other Java types are handled as arrays\n                //\n                return !isUniformCollection(c, CompositeData.class) &&\n                       !isUniformCollection(c, TabularData.class);\n            }\n        }\n        if (elem instanceof Map) {\n            return !(elem instanceof TabularData);\n        }\n        return false;\n    }\n    \n    /**\n     * Check if the given element is an array.\n     *\n     * Multidimensional arrays are not supported.\n     *\n     * Non-empty 1-dimensional arrays of CompositeData\n     * and TabularData are not handled as arrays but as\n     * tabular data.\n     */\n    public static boolean isSupportedArray(Object elem) {\n        if (elem == null || !elem.getClass().isArray()) {\n            return false;\n        }\n        Class<?> ct = elem.getClass().getComponentType();\n        if (ct.isArray()) {\n            return false;\n        }\n        if (Array.getLength(elem) > 0 &&\n                (CompositeData.class.isAssignableFrom(ct) ||\n                TabularData.class.isAssignableFrom(ct))) {\n            return false;\n        }\n        return true;\n    }\n    \n    /**\n     * This method provides a readable classname if it's an array,\n     * i.e. either the classname of the component type for arrays\n     * of java reference types or the name of the primitive type\n     * for arrays of java primitive types. Otherwise, it returns null.\n     */\n    public static String getArrayClassName(String name) {\n        String className = null;\n        if (name.startsWith(\"[\")) { // NOI18N\n            int index = name.lastIndexOf(\"[\"); // NOI18N\n            className = name.substring(index, name.length());\n            if (className.startsWith(\"[L\")) { // NOI18N\n                className = className.substring(2, className.length() - 1);\n            } else {\n                try {\n                    Class<?> c = Class.forName(className);\n                    className = c.getComponentType().getName();\n                } catch (ClassNotFoundException e) {\n                    // Should not happen\n                    throw new IllegalArgumentException(\n                            \"Bad class name \" + name, e); // NOI18N\n                }\n            }\n        }\n        return className;\n    }\n    \n    /**\n     * This methods provides a readable classname. If the supplied name\n     * parameter denotes an array this method returns either the classname\n     * of the component type for arrays of java reference types or the name\n     * of the primitive type for arrays of java primitive types followed by\n     * n-times \"[]\" where 'n' denotes the arity of the array. Otherwise, if\n     * the supplied name doesn't denote an array it returns the same classname.\n     */\n    public static String getReadableClassName(String name) {\n        String className = getArrayClassName(name);\n        if (className == null) return name;\n        int index = name.lastIndexOf(\"[\"); // NOI18N\n        StringBuilder brackets = new StringBuilder(className);\n        for (int i = 0; i <= index; i++) {\n            brackets.append(\"[]\"); // NOI18N\n        }\n        return brackets.toString();\n    }\n    \n    /**\n     * This method tells whether the type is editable\n     * (means can be created with a String or not)\n     */\n    public static boolean isEditableType(String type) {\n        return editableTypes.contains(type);\n    }\n    \n    /**\n     * This method inserts a default value for the standard java types,\n     * else it inserts the text name of the expected class type.\n     * It acts to give a clue as to the input type.\n     */\n    public static String getDefaultValue(String type) {\n        if (numericalTypes.contains(type) ||\n                extraNumericalTypes.contains(type)) {\n            return \"0\"; // NOI18N\n        }\n        if (booleanTypes.contains(type)) {\n            return \"true\"; // NOI18N\n        }\n        type = getReadableClassName(type);\n        int i = type.lastIndexOf('.');\n        if (i > 0) {\n            return type.substring(i + 1, type.length());\n        } else {\n            return type;\n        }\n    }\n    \n    /**\n     * Try to create a Java object using a one-string-param constructor.\n     */\n    public static Object newStringConstructor(String type, String param)\n    throws Exception {\n        Constructor c = Utils.getClass(type).getConstructor(String.class);\n        try {\n            return c.newInstance(param);\n        } catch (InvocationTargetException e) {\n            Throwable t = e.getTargetException();\n            if (t instanceof Exception) {\n                throw (Exception) t;\n            } else {\n                throw e;\n            }\n        }\n    }\n    \n    /**\n     * Try to convert a string value into a numerical value.\n     */\n    private static Number createNumberFromStringValue(String type, String value)\n    throws NumberFormatException {\n        final String suffix = value.substring(value.length() - 1);\n        if (\"L\".equalsIgnoreCase(suffix)) { // NOI18N\n            return Long.valueOf(value.substring(0, value.length() - 1));\n        }\n        if (\"F\".equalsIgnoreCase(suffix)) { // NOI18N\n            return Float.valueOf(value.substring(0, value.length() - 1));\n        }\n        if (\"D\".equalsIgnoreCase(suffix)) { // NOI18N\n            return Double.valueOf(value.substring(0, value.length() - 1));\n        }\n        try {\n            return (Number) newStringConstructor(type, value);\n        } catch (Exception ex) {\n            // OK: Ignore exception...\n        }\n        try {\n            return Integer.valueOf(value);\n        } catch (NumberFormatException e) {\n            // OK: Ignore exception...\n        }\n        try {\n            return Long.valueOf(value);\n        } catch (NumberFormatException e1) {\n            // OK: Ignore exception...\n        }\n        try {\n            return Double.valueOf(value);\n        } catch (NumberFormatException e2) {\n            // OK: Ignore exception...\n        }\n        throw new NumberFormatException(\"Cannot convert string value '\" + // NOI18N\n                value + \"' into a numerical value\"); // NOI18N\n    }\n    \n    /**\n     * This method attempts to create an object of the given \"type\"\n     * using the \"value\" parameter.\n     * e.g. calling createObjectFromString(\"java.lang.Integer\", \"10\")\n     * will return an Integer object initialized to 10.\n     */\n    public static Object createObjectFromString(String type, String value)\n    throws Exception {\n        Object result;\n        if (primitiveToWrapper.containsKey(type)) {\n            if (type.equals(Character.TYPE.getName())) {\n                result = new Character(value.charAt(0));\n            } else {\n                result = newStringConstructor(\n                        ((Class<?>) primitiveToWrapper.get(type)).getName(),\n                        value);\n            }\n        } else if (type.equals(Character.class.getName())) {\n            result = new Character(value.charAt(0));\n        } else if (Number.class.isAssignableFrom(Utils.getClass(type))) {\n            result = createNumberFromStringValue(type, value);\n        } else if (String[].class.isAssignableFrom(Utils.getClass(type))) {\n            String[] args = value.split(\",\");       // NOI18N\n            for (int i = 0; i < args.length; i++) {\n                args[i] = args[i].trim();\n            }\n            result = args;\n        } else if (value == null || value.toString().equals(\"null\")) { // NOI18N\n            // hack for null value\n            result = null;\n        } else {\n            // try to create a Java object using\n            // the one-string-param constructor\n            result = newStringConstructor(type, value);\n        }\n        return result;\n    }\n    \n    /**\n     * This method is responsible for converting the inputs given by the user\n     * into a useful object array for passing into a parameter array.\n     */\n    public static Object[] getParameters(XTextField[] inputs, String[] params)\n    throws Exception {\n        Object result[] = new Object[inputs.length];\n        Object userInput;\n        for (int i = 0; i < inputs.length; i++) {\n            userInput = inputs[i].getValue();\n            // if it's already a complex object, use the value\n            // else try to instantiate with string constructor\n            if (userInput instanceof XObject) {\n                result[i] = ((XObject) userInput).getObject();\n            } else {\n                result[i] = createObjectFromString(params[i].toString(),\n                        (String) userInput);\n            }\n        }\n        return result;\n    }\n    \n    /**\n     * If the exception is wrapped, unwrap it.\n     */\n    public static Throwable getActualException(Throwable e) {\n        if (e instanceof ExecutionException)\n            e = e.getCause();\n        if (e instanceof MBeanException ||\n                e instanceof RuntimeMBeanException ||\n                e instanceof RuntimeOperationsException ||\n                e instanceof ReflectionException) {\n            Throwable t = e.getCause();\n            if (t != null) return t;\n        }\n        return e;\n    }\n    \n    @SuppressWarnings(\"serial\")\n    public static class ReadOnlyTableCellEditor\n            extends DefaultCellEditor {\n        public ReadOnlyTableCellEditor(JTextField tf) {\n            super(tf);\n            tf.addFocusListener(new Utils.EditFocusAdapter(this));\n            tf.addKeyListener(new Utils.CopyKeyAdapter());\n        }\n    }\n    \n    public static class EditFocusAdapter extends FocusAdapter {\n        private CellEditor editor;\n        public EditFocusAdapter(CellEditor editor) {\n            this.editor = editor;\n        }\n        @Override\n        public void focusLost(FocusEvent e) {\n            editor.stopCellEditing();\n        }\n    };\n    \n    public static class CopyKeyAdapter extends KeyAdapter {\n        private static final String defaultEditorKitCopyActionName =\n                DefaultEditorKit.copyAction;\n        private static final String transferHandlerCopyActionName =\n                (String) TransferHandler.getCopyAction().getValue(Action.NAME);\n        @Override\n        public void keyPressed(KeyEvent e) {\n            // Accept \"copy\" key strokes\n            KeyStroke ks = KeyStroke.getKeyStroke(\n                    e.getKeyCode(), e.getModifiers());\n            JComponent comp = (JComponent) e.getSource();\n            for (int i = 0; i < 3; i++) {\n                InputMap im = comp.getInputMap(i);\n                Object key = im.get(ks);\n                if (defaultEditorKitCopyActionName.equals(key) ||\n                        transferHandlerCopyActionName.equals(key)) {\n                    return;\n                }\n            }\n            // Accept JTable navigation key strokes\n            if (!tableNavigationKeys.contains(e.getKeyCode())) {\n                e.consume();\n            }\n        }\n        @Override\n        public void keyTyped(KeyEvent e) {\n            e.consume();\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/VariableGridLayout.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.*;\nimport java.util.*;\nimport javax.swing.*;\n\n@SuppressWarnings(\"serial\")\nclass VariableGridLayout extends GridLayout {\n\n    private boolean fillRows, fillColumns;\n\n    public VariableGridLayout(int rows, int cols,\n                              int hgap, int vgap,\n                              boolean fillRows, boolean fillColumns) {\n        super(rows, cols, hgap, vgap);\n\n        this.fillRows    = fillRows;\n        this.fillColumns = fillColumns;\n    }\n\n    public void setFillRow(JComponent c, boolean b) {\n        c.putClientProperty(\"VariableGridLayout.fillRow\", b); // NOI18N\n    }\n\n    public void setFillColumn(JComponent c, boolean b) {\n        c.putClientProperty(\"VariableGridLayout.fillColumn\", b); // NOI18N\n    }\n\n    public boolean getFillRow(JComponent c) {\n        Boolean b = (Boolean)c.getClientProperty(\"VariableGridLayout.fillRow\"); // NOI18N\n        return (b != null) ? b : fillRows;\n    }\n\n    public boolean getFillColumn(JComponent c) {\n        Boolean b = (Boolean)c.getClientProperty(\"VariableGridLayout.fillColumn\"); // NOI18N\n        return (b != null) ? b : fillColumns;\n    }\n\n    @Override\n    public void layoutContainer(Container parent) {\n        Insets insets = parent.getInsets();\n        int ncomponents = parent.getComponentCount();\n        int nrows = getRows();\n        int ncols = getColumns();\n        int hgap =  getHgap();\n        int vgap =  getVgap();\n\n        if (nrows > 0) {\n            ncols = (ncomponents + nrows - 1) / nrows;\n        } else {\n            nrows = (ncomponents + ncols - 1) / ncols;\n        }\n\n        // Set heights\n        int x;\n        int y;\n        int nFills = 0;\n        boolean[] fills = new boolean[nrows];\n        int lastFillRow = -1;\n        int nComps = parent.getComponentCount();\n\n        y = insets.top;\n        for (int row = 0; row < nrows; row++) {\n            // Find largest minimum height for this row\n            int h = 0;\n            for (int col = 0; col < ncols; col++) {\n                if (row * ncols + col < nComps) {\n                    Component c = parent.getComponent(row * ncols + col);\n                    h = Math.max(h, c.getMinimumSize().height);\n                }\n            }\n            // Set heights for this row\n            x = insets.left;\n            for (int col = 0; col < ncols; col++) {\n                if (row * ncols + col < nComps) {\n                    JComponent c = (JComponent)parent.getComponent(row * ncols + col);\n                    int w = c.getWidth();\n                    c.setBounds(x, y, w, h);\n                    x += w + hgap;\n                    if (col == 0 && getFillRow(c)) {\n                        fills[row] = true;\n                    }\n                }\n            }\n            y += h + vgap;\n            if (fills[row]) {\n                nFills++;\n                lastFillRow = row;\n            }\n        }\n\n        // Fill heights\n        if (nFills > 0 && y < parent.getHeight()) {\n            // How much height to add\n            int hAdd = (parent.getHeight() - y) / nFills;\n            int hAdded = 0;\n            for (int row = 0; row < nrows; row++) {\n                if (fills[row]) {\n                    if (row == lastFillRow) {\n                        // Compensate for rounding error\n                        hAdd = parent.getHeight() - (y+hAdded);\n                    }\n                    for (int col = 0; col < ncols; col++) {\n                        if (row * ncols + col < nComps) {\n                            Component c = parent.getComponent(row * ncols + col);\n                            Rectangle b = c.getBounds();\n                            c.setBounds(b.x, b.y + hAdded, b.width, b.height + hAdd);\n                        }\n                    }\n                    hAdded += hAdd;\n                }\n            }\n        }\n\n        // Set widths\n        nFills = 0;\n        fills = new boolean[ncols];\n        int lastFillCol = -1;\n\n        x = insets.left;\n        for (int col = 0; col < ncols; col++) {\n            // Find largest minimum width for this column\n            int w = 0;\n            for (int row = 0; row < nrows; row++) {\n                if (row * ncols + col < nComps) {\n                    Component c = parent.getComponent(row * ncols + col);\n                    w = Math.max(w, c.getMinimumSize().width);\n                }\n            }\n            // Set widths for this column\n            y = insets.top;\n            for (int row = 0; row < nrows; row++) {\n                if (row * ncols + col < nComps) {\n                    JComponent c = (JComponent)parent.getComponent(row * ncols + col);\n                    int h = c.getHeight();\n                    c.setBounds(x, y, w, h);\n                    y += h + vgap;\n                    if (row == 0 && getFillColumn(c)) {\n                        fills[col] = true;\n                    }\n                }\n            }\n            x += w + hgap;\n            if (fills[col]) {\n                nFills++;\n                lastFillCol = col;\n            }\n        }\n\n        // Fill widths\n        if (nFills > 0 && x < parent.getWidth()) {\n            // How much width to add\n            int wAdd = (parent.getWidth() - x) / nFills;\n            int wAdded = 0;\n            for (int col = 0; col < ncols; col++) {\n                if (fills[col]) {\n                    if (col == lastFillCol) {\n                        wAdd = parent.getWidth() - (x+wAdded);\n                    }\n                    for (int row = 0; row < nrows; row++) {\n                        if (row * ncols + col < nComps) {\n                            Component c = parent.getComponent(row * ncols + col);\n                            Rectangle b = c.getBounds();\n                            c.setBounds(b.x + wAdded, b.y, b.width + wAdd, b.height);\n                        }\n                    }\n                    wAdded += wAdd;\n                }\n            }\n        }\n    }\n\n    @Override\n    public Dimension preferredLayoutSize(Container parent) {\n        Insets insets = parent.getInsets();\n        int ncomponents = parent.getComponentCount();\n        int nrows = getRows();\n        int ncols = getColumns();\n        int hgap =  getHgap();\n        int vgap =  getVgap();\n\n        if (nrows > 0) {\n            ncols = (ncomponents + nrows - 1) / nrows;\n        } else {\n            nrows = (ncomponents + ncols - 1) / ncols;\n        }\n\n        int nComps = parent.getComponentCount();\n\n        int y = insets.top;\n        for (int row = 0; row < nrows; row++) {\n            int h = 0;\n            for (int col = 0; col < ncols; col++) {\n                if (row * ncols + col < nComps) {\n                    Component c = parent.getComponent(row * ncols + col);\n                    h = Math.max(h, c.getMinimumSize().height);\n                }\n            }\n            y += h + vgap;\n        }\n\n        int x = insets.left;\n        for (int col = 0; col < ncols; col++) {\n            int w = 0;\n            for (int row = 0; row < nrows; row++) {\n                if (row * ncols + col < nComps) {\n                    Component c = parent.getComponent(row * ncols + col);\n                    w = Math.max(w, c.getMinimumSize().width);\n                }\n            }\n            x += w + hgap;\n        }\n        return new Dimension(x, y);\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XArrayDataViewer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.lang.reflect.Array;\nimport java.util.Collection;\nimport java.util.Map;\nimport javax.swing.JEditorPane;\nimport javax.swing.JScrollPane;\n\nclass XArrayDataViewer {\n\n    private XArrayDataViewer() {}\n\n    public static boolean isViewableValue(Object value) {\n        return Utils.canBeRenderedAsArray(value);\n    }\n\n    public static Component loadArray(Object value) {\n        Component comp = null;\n        if (isViewableValue(value)) {\n            Object[] arr;\n            if (value instanceof Collection) {\n                arr = ((Collection) value).toArray();\n            } else if (value instanceof Map) {\n                arr = ((Map) value).entrySet().toArray();\n            } else if (value instanceof Object[]) {\n                arr = (Object[]) value;\n            } else {\n                int length = Array.getLength(value);\n                arr = new Object[length];\n                for (int i = 0; i < length; i++) {\n                    arr[i] = Array.get(value, i);\n                }\n            }\n            JEditorPane arrayEditor = new JEditorPane();\n            arrayEditor.setContentType(\"text/html\"); // NOI18N\n            arrayEditor.setEditable(false);\n            Color evenRowColor = arrayEditor.getBackground();\n            int red = evenRowColor.getRed();\n            int green = evenRowColor.getGreen();\n            int blue = evenRowColor.getBlue();\n            String evenRowColorStr =\n                    \"rgb(\" + red + \",\" + green + \",\" + blue + \")\"; // NOI18N\n            Color oddRowColor = new Color(\n                    red < 20 ? red + 20 : red - 20,\n                    green < 20 ? green + 20 : green - 20,\n                    blue < 20 ? blue + 20 : blue - 20);\n            String oddRowColorStr =\n                    \"rgb(\" + oddRowColor.getRed() + \",\" + // NOI18N\n                    oddRowColor.getGreen() + \",\" + // NOI18N\n                    oddRowColor.getBlue() + \")\"; // NOI18N\n            Color foreground = arrayEditor.getForeground();\n            String textColor = String.format(\"%06x\", // NOI18N\n                                             foreground.getRGB() & 0xFFFFFF);\n            StringBuilder sb = new StringBuilder();\n            sb.append(\"<html><body text=#\"+textColor+\"><table width=\\\"100%\\\">\"); // NOI18N\n            for (int i = 0; i < arr.length; i++) {\n                if (i % 2 == 0) {\n                    sb.append(\"<tr style=\\\"background-color: \" + // NOI18N\n                            evenRowColorStr + \"\\\"><td><pre>\" + // NOI18N\n                            (arr[i] == null ?\n                                arr[i] : htmlize(arr[i].toString())) +\n                            \"</pre></td></tr>\"); // NOI18N\n                } else {\n                    sb.append(\"<tr style=\\\"background-color: \" + // NOI18N\n                            oddRowColorStr + \"\\\"><td><pre>\" + // NOI18N\n                            (arr[i] == null ?\n                                arr[i] : htmlize(arr[i].toString())) +\n                            \"</pre></td></tr>\"); // NOI18N\n                }\n            }\n            if (arr.length == 0) {\n                sb.append(\"<tr style=\\\"background-color: \" + // NOI18N\n                        evenRowColorStr + \"\\\"><td></td></tr>\"); // NOI18N\n            }\n            sb.append(\"</table></body></html>\"); // NOI18N\n            arrayEditor.setText(sb.toString());\n            JScrollPane scrollp = new JScrollPane(arrayEditor);\n            comp = scrollp;\n        }\n        return comp;\n    }\n\n    private static String htmlize(String value) {\n        return value.replace(\"&\", \"&amp;\").replace(\"<\", \"&lt;\"); // NOI18N\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XDataViewer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport javax.swing.JTable;\nimport javax.swing.JScrollPane;\nimport javax.swing.JButton;\n\nimport java.awt.event.MouseListener;\nimport java.awt.Component;\nimport java.awt.Container;\n\nclass XDataViewer {\n\n    public static final int OPEN = 1;\n    public static final int ARRAY = 2;\n    public static final int NUMERIC = 3;\n    public static final int NOT_SUPPORTED = 4;\n\n    private MBeansTab tab;\n    public XDataViewer(MBeansTab tab) {\n        this.tab = tab;\n    }\n\n    public static void registerForMouseEvent(Component comp,\n                                             MouseListener mouseListener) {\n        if(comp instanceof JScrollPane) {\n            JScrollPane pane = (JScrollPane) comp;\n            comp = pane.getViewport().getView();\n        }\n        if(comp instanceof Container) {\n            Container container = (Container) comp;\n            Component[] components = container.getComponents();\n            for(int i = 0; i < components.length; i++) {\n                registerForMouseEvent(components[i], mouseListener);\n            }\n        }\n\n        //No registration for XOpenTypedata that are themselves clickable.\n        //No registration for JButton that are themselves clickable.\n        if(comp != null &&\n           (!(comp instanceof XOpenTypeViewer.XOpenTypeData) &&\n            !(comp instanceof JButton)) )\n            comp.addMouseListener(mouseListener);\n    }\n\n    public static void dispose(MBeansTab tab) {\n        XPlottingViewer.dispose(tab);\n    }\n\n    public static boolean isViewableValue(Object value) {\n        boolean ret = false;\n        if((ret = XArrayDataViewer.isViewableValue(value)))\n            return ret;\n        if((ret = XOpenTypeViewer.isViewableValue(value)))\n            return ret;\n        if((ret = XPlottingViewer.isViewableValue(value)))\n            return ret;\n\n        return ret;\n    }\n\n    public static int getViewerType(Object data) {\n        if(XArrayDataViewer.isViewableValue(data))\n            return ARRAY;\n        if(XOpenTypeViewer.isViewableValue(data))\n            return OPEN;\n        if(XPlottingViewer.isViewableValue(data))\n            return NUMERIC;\n\n        return NOT_SUPPORTED;\n    }\n\n    public static String getActionLabel(int type) {\n        if(type == ARRAY ||\n           type == OPEN)\n            return Resources.getText(\"LBL_visualize\"); // NOI18N\n        if(type == NUMERIC)\n            return Resources.getText(\"LBL_plot\"); // NOI18N\n        return Resources.getText(\"LBL_expand\"); // NOI18N\n    }\n\n    public Component createOperationViewer(Object value,\n                                           XMBean mbean) {\n        if (value instanceof Number) return null;\n        if (value instanceof Component) return (Component) value;\n        return createAttributeViewer(value, mbean, null, null);\n    }\n\n    public static Component createNotificationViewer(Object value) {\n        Component comp = null;\n\n        if(value instanceof Number) return null;\n\n        if((comp = XArrayDataViewer.loadArray(value)) != null)\n            return comp;\n\n        if((comp = XOpenTypeViewer.loadOpenType(value)) != null)\n            return comp;\n\n        return comp;\n    }\n\n    public Component createAttributeViewer(Object value,\n                                           XMBean mbean,\n                                           String attributeName,\n                                           JTable table) {\n        Component comp = null;\n        if((comp = XArrayDataViewer.loadArray(value)) != null)\n            return comp;\n        if((comp = XOpenTypeViewer.loadOpenType(value)) != null)\n            return comp;\n        if((comp = XPlottingViewer.loadPlotting(mbean,\n                                                attributeName,\n                                                value,\n                                                table,\n                                                tab)) != null)\n            return comp;\n\n        return comp;\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XMBean.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport org.graalvm.visualvm.tools.jmx.CachedMBeanServerConnection;\nimport java.io.IOException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.*;\nimport javax.swing.Icon;\n\nclass XMBean {\n    private final MBeansTab mbeansTab;\n    private final ObjectName objectName;\n    private Icon icon;\n    private String text;\n    private Boolean broadcaster;\n    private final Object broadcasterLock = new Object();\n    private MBeanInfo mbeanInfo;\n    private final Object mbeanInfoLock = new Object();\n    private final static Logger LOGGER = Logger.getLogger(XMBean.class.getName());\n    \n    public XMBean(ObjectName objectName, MBeansTab mbeansTab) {\n        this.mbeansTab = mbeansTab;\n        this.objectName = objectName;\n        text = objectName.getKeyProperty(\"name\"); // NOI18N\n        if (text == null)\n            text = objectName.getDomain();\n        if (MBeanServerDelegate.DELEGATE_NAME.equals(objectName)) {\n            icon = IconManager.MBEANSERVERDELEGATE;\n        } else {\n            icon = IconManager.MBEAN;\n        }\n    }\n    \n    MBeanServerConnection getMBeanServerConnection() {\n        return mbeansTab.getMBeanServerConnection();\n    }\n    \n    CachedMBeanServerConnection getCachedMBeanServerConnection() {\n        return mbeansTab.getCachedMBeanServerConnection();\n    }\n    \n    public Boolean isBroadcaster() {\n        synchronized (broadcasterLock) {\n            if (broadcaster == null) {\n                try {\n                    broadcaster = getMBeanServerConnection().isInstanceOf(\n                            getObjectName(),\n                            \"javax.management.NotificationBroadcaster\"); // NOI18N\n                } catch (Exception e) {\n                    LOGGER.log(Level.SEVERE, \"Couldn't check if MBean [\" + // NOI18N\n                            objectName + \"] is a notification broadcaster\", e); // NOI18N\n                    return false;\n                }\n            }\n            return broadcaster;\n        }\n    }\n    \n    public Object invoke(String operationName) throws Exception {\n        Object result = getMBeanServerConnection().invoke(\n                getObjectName(), operationName, new Object[0], new String[0]);\n        return result;\n    }\n    \n    public Object invoke(String operationName, Object params[], String sig[])\n    throws Exception {\n        Object result = getMBeanServerConnection().invoke(\n                getObjectName(), operationName, params, sig);\n        return result;\n    }\n    \n    public void setAttribute(Attribute attribute)\n    throws AttributeNotFoundException, InstanceNotFoundException,\n            InvalidAttributeValueException, MBeanException,\n            ReflectionException, IOException {\n        getMBeanServerConnection().setAttribute(getObjectName(), attribute);\n    }\n    \n    public Object getAttribute(String attributeName)\n    throws AttributeNotFoundException, InstanceNotFoundException,\n            MBeanException, ReflectionException, IOException {\n        return getCachedMBeanServerConnection().getAttribute(\n                getObjectName(), attributeName);\n    }\n    \n    public AttributeList getAttributes(String attributeNames[])\n    throws AttributeNotFoundException, InstanceNotFoundException,\n            MBeanException, ReflectionException, IOException {\n        return getCachedMBeanServerConnection().getAttributes(\n                getObjectName(), attributeNames);\n    }\n    \n    public AttributeList getAttributes(MBeanAttributeInfo attributeNames[])\n    throws AttributeNotFoundException, InstanceNotFoundException,\n            MBeanException, ReflectionException, IOException {\n        String attributeString[] = new String[attributeNames.length];\n        for (int i = 0; i < attributeNames.length; i++) {\n            attributeString[i] = attributeNames[i].getName();\n        }\n        return getAttributes(attributeString);\n    }\n    \n    public ObjectName getObjectName() {\n        return objectName;\n    }\n    \n    public MBeanInfo getMBeanInfo() throws InstanceNotFoundException,\n            IntrospectionException, ReflectionException, IOException {\n        synchronized (mbeanInfoLock) {\n            if (mbeanInfo == null) {\n                mbeanInfo = getMBeanServerConnection().getMBeanInfo(objectName);\n            }\n            return mbeanInfo;\n        }\n    }\n    \n    @Override\n    public boolean equals(Object obj) {\n        if (obj == null) return false;\n        if (obj == this) return true;\n        if (!(obj instanceof XMBean)) return false;\n        XMBean that = (XMBean) obj;\n        return getObjectName().equals(that.getObjectName());\n    }\n\n    @Override\n    public int hashCode() {\n        return (objectName == null ? 0 : objectName.hashCode());\n    }\n    \n    public String getText() {\n        return text;\n    }\n    \n    public void setText(String text) {\n        this.text = text;\n    }\n    \n    public Icon getIcon() {\n        return icon;\n    }\n    \n    public void setIcon(Icon icon) {\n        this.icon = icon;\n    }\n    \n    @Override\n    public String toString() {\n        return getText();\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XMBeanAttributes.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport org.graalvm.visualvm.tools.jmx.CachedMBeanServerConnection;\n\nimport javax.swing.*;\nimport javax.swing.event.*;\nimport javax.swing.table.*;\nimport java.awt.Component;\nimport java.awt.EventQueue;\nimport java.awt.event.*;\nimport java.awt.Dimension;\nimport java.io.IOException;\nimport java.util.*;\n\nimport java.lang.reflect.Array;\n\nimport java.util.concurrent.ExecutionException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.*;\nimport javax.management.openmbean.CompositeData;\nimport javax.management.openmbean.TabularData;\n\n/*IMPORTANT :\n  There is a deadlock issue there if we don't synchronize well loadAttributes,\n  refresh attributes and empty table methods since a UI thread can call\n  loadAttributes and at the same time a JMX notification can raise an\n  emptyTable. Since there are synchronization in the JMX world it's\n  COMPULSORY to not call the JMX world in synchronized blocks */\nclass XMBeanAttributes extends XTable {\n    private static final Logger LOGGER = Logger.getLogger(XMBeanAttributes.class.getName());\n\n    private final static String[] columnNames =\n    {Resources.getText(\"LBL_Name\"), // NOI18N\n     Resources.getText(\"LBL_Value\")}; // NOI18N\n\n    private XMBean mbean;\n    private MBeanInfo mbeanInfo;\n    private MBeanAttributeInfo[] attributesInfo;\n    private HashMap<String, Object> attributes;\n    private HashMap<String, Object> unavailableAttributes;\n    private HashMap<String, Object> viewableAttributes;\n    private WeakHashMap<XMBean, HashMap<String, ZoomedCell>> viewersCache =\n            new WeakHashMap<XMBean, HashMap<String, ZoomedCell>>();\n    private final TableModelListener attributesListener;\n    private MBeansTab mbeansTab;\n    private TableCellEditor valueCellEditor = new ValueCellEditor();\n    private int rowMinHeight = -1;\n    private AttributesMouseListener mouseListener = new AttributesMouseListener();\n\n    private static TableCellEditor editor =\n            new Utils.ReadOnlyTableCellEditor(new JTextField());\n\n    public XMBeanAttributes(MBeansTab mbeansTab) {\n        super();\n        this.mbeansTab = mbeansTab;\n        ((DefaultTableModel)getModel()).setColumnIdentifiers(columnNames);\n        attributesListener = new AttributesListener(this);\n        getModel().addTableModelListener(attributesListener);\n        getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(40);\n\n        addMouseListener(mouseListener);\n        getTableHeader().setReorderingAllowed(false);\n        setColumnEditors();\n        addKeyListener(new Utils.CopyKeyAdapter());\n    }\n\n    @Override\n    public synchronized Component prepareRenderer(TableCellRenderer renderer,\n                                                  int row, int column) {\n        //In case we have a repaint thread that is in the process of\n        //repainting an obsolete table, just ignore the call.\n        //It can happen when MBean selection is switched at a very quick rate\n        if(row >= getRowCount())\n            return null;\n        else\n            return super.prepareRenderer(renderer, row, column);\n    }\n\n    void updateRowHeight(Object obj, int row) {\n        ZoomedCell cell = null;\n        if(obj instanceof ZoomedCell) {\n            cell = (ZoomedCell) obj;\n            if(cell.isInited())\n                setRowHeight(row, cell.getHeight());\n            else\n                if(rowMinHeight != - 1)\n                    setRowHeight(row, rowMinHeight);\n        } else\n            if(rowMinHeight != - 1)\n                setRowHeight(row, rowMinHeight);\n    }\n\n    @Override\n    public synchronized TableCellRenderer getCellRenderer(int row,\n            int column) {\n        //In case we have a repaint thread that is in the process of\n        //repainting an obsolete table, just ignore the call.\n        //It can happen when MBean selection is switched at a very quick rate\n        if (row >= getRowCount()) {\n            return null;\n        } else {\n            if (column == VALUE_COLUMN) {\n                Object obj = getModel().getValueAt(row, column);\n                if (obj instanceof ZoomedCell) {\n                    ZoomedCell cell = (ZoomedCell) obj;\n                    if (cell.isInited()) {\n                        DefaultTableCellRenderer renderer =\n                                (DefaultTableCellRenderer) cell.getRenderer();\n                        renderer.setToolTipText(getToolTip(row,column));\n                        return renderer;\n                    }\n                }\n            }\n            DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)\n                super.getCellRenderer(row, column);\n            if (!isCellError(row, column)) {\n                if (!(isColumnEditable(column) && isWritable(row) &&\n                      Utils.isEditableType(getClassName(row)))) {\n                    renderer.setForeground(getDefaultColor());\n                }\n            }\n            return renderer;\n        }\n    }\n\n    private void setColumnEditors() {\n        TableColumnModel tcm = getColumnModel();\n        for (int i = 0; i < columnNames.length; i++) {\n            TableColumn tc = tcm.getColumn(i);\n            if (isColumnEditable(i)) {\n                tc.setCellEditor(valueCellEditor);\n            } else {\n                tc.setCellEditor(editor);\n            }\n        }\n    }\n\n    public void cancelCellEditing() {\n        if (LOGGER.isLoggable(Level.FINER)) {\n            LOGGER.finer(\"Cancel Editing Row: \"+getEditingRow());\n        }\n        final TableCellEditor tableCellEditor = getCellEditor();\n        if (tableCellEditor != null) {\n            tableCellEditor.cancelCellEditing();\n        }\n    }\n\n    public void stopCellEditing() {\n        if (LOGGER.isLoggable(Level.FINER)) {\n            LOGGER.finer(\"Stop Editing Row: \"+getEditingRow());\n        }\n        final TableCellEditor tableCellEditor = getCellEditor();\n        if (tableCellEditor != null) {\n            tableCellEditor.stopCellEditing();\n        }\n    }\n\n    @Override\n    public final boolean editCellAt(final int row, final int column, EventObject e) {\n        if (LOGGER.isLoggable(Level.FINER)) {\n            LOGGER.finer(\"editCellAt(row=\"+row+\", col=\"+column+\n                    \", e=\"+e+\")\");\n        }\n        boolean retVal = super.editCellAt(row, column, e);\n        if (retVal) {\n            final TableCellEditor tableCellEditor =\n                    getColumnModel().getColumn(column).getCellEditor();\n            if (tableCellEditor == valueCellEditor) {\n                ((JComponent) tableCellEditor).requestFocus();\n            }\n        }\n        return retVal;\n    }\n\n    @Override\n    public boolean isCellEditable(int row, int col) {\n        // All the cells in non-editable columns are editable\n        if (!isColumnEditable(col)) {\n            return true;\n        }\n        // Maximized zoomed cells are editable\n        Object obj = getModel().getValueAt(row, col);\n        if (obj instanceof ZoomedCell) {\n            ZoomedCell cell = (ZoomedCell) obj;\n            return cell.isMaximized();\n        }\n        return true;\n    }\n\n    @Override\n    public void setValueAt(Object value, int row, int column) {\n        if (!isCellError(row, column) && isColumnEditable(column) &&\n            isWritable(row) && Utils.isEditableType(getClassName(row))) {\n            if (LOGGER.isLoggable(Level.FINER)) {\n                LOGGER.finer(\"setValueAt(row=\"+row+\", column=\"+column+\n                        \"): \"+getValueName(row)+\"=\"+value);\n            }\n            super.setValueAt(value, row, column);\n        }\n    }\n\n    //Table methods\n\n    public boolean isTableEditable() {\n        return true;\n    }\n\n    public void setTableValue(Object value, int row) {\n    }\n\n    public boolean isColumnEditable(int column) {\n        if (column < getColumnCount()) {\n            return getColumnName(column).equals(Resources.getText(\"LBL_Value\")); // NOI18N\n        }\n        else {\n            return false;\n        }\n    }\n\n    public String getClassName(int row) {\n        int index = convertRowToIndex(row);\n        if (index != -1) {\n            return attributesInfo[index].getType();\n        }\n        else {\n            return null;\n        }\n    }\n\n\n    public String getValueName(int row) {\n        int index = convertRowToIndex(row);\n        if (index != -1) {\n            return attributesInfo[index].getName();\n        }\n        else {\n            return null;\n        }\n    }\n\n    public Object getValue(int row) {\n        final Object val = ((DefaultTableModel) getModel())\n                .getValueAt(row, VALUE_COLUMN);\n        return val;\n    }\n\n    //tool tip only for editable column\n    @Override\n    public String getToolTip(int row, int column) {\n        if (isCellError(row, column)) {\n            return (String) unavailableAttributes.get(getValueName(row));\n        }\n        if (isColumnEditable(column)) {\n            Object value = getValue(row);\n            String tip = null;\n            if (value != null) {\n                tip = value.toString();\n                if(isAttributeViewable(row, VALUE_COLUMN))\n                    tip = Resources.getText(\"LBL_DoubleClickToExpandCollapse\")+ // NOI18N\n                        \". \" + tip; // NOI18N\n            }\n\n            return tip;\n        }\n\n        if(column == NAME_COLUMN) {\n            int index = convertRowToIndex(row);\n            if (index != -1) {\n                return attributesInfo[index].getDescription();\n            }\n        }\n        return null;\n    }\n\n    public synchronized boolean isWritable(int row) {\n        int index = convertRowToIndex(row);\n        if (index != -1) {\n            return (attributesInfo[index].isWritable());\n        }\n        else {\n            return false;\n        }\n    }\n\n    /**\n     * Override JTable method in order to make any call to this method\n     * atomic with TableModel elements.\n     */\n    @Override\n    public synchronized int getRowCount() {\n        return super.getRowCount();\n    }\n\n    public synchronized boolean isReadable(int row) {\n        int index = convertRowToIndex(row);\n        if (index != -1) {\n            return (attributesInfo[index].isReadable());\n        }\n        else {\n            return false;\n        }\n    }\n\n    public synchronized boolean isCellError(int row, int col) {\n        return (isColumnEditable(col) &&\n                (unavailableAttributes.containsKey(getValueName(row))));\n    }\n\n    public synchronized boolean isAttributeViewable(int row, int col) {\n        boolean isViewable = false;\n        if(col == VALUE_COLUMN) {\n            Object obj = getModel().getValueAt(row, col);\n            if(obj instanceof ZoomedCell)\n                isViewable = true;\n        }\n\n        return isViewable;\n    }\n\n    // Call this in EDT\n    public void loadAttributes(final XMBean mbean, final MBeanInfo mbeanInfo) {\n\n        final SwingWorker<Runnable,Void> load =\n                new SwingWorker<Runnable,Void>() {\n            @Override\n            protected Runnable doInBackground() throws Exception {\n                return doLoadAttributes(mbean,mbeanInfo);\n            }\n\n            @Override\n            protected void done() {\n                try {\n                    final Runnable updateUI = get();\n                    if (updateUI != null) updateUI.run();\n                } catch (RuntimeException x) {\n                    throw x;\n                } catch (ExecutionException x) {\n                    LOGGER.log(Level.FINE,\n                            \"Exception raised while loading attributes\",\n                            x.getCause());\n                } catch (InterruptedException x) {\n                    LOGGER.log(Level.FINE,\n                            \"Interrupted while loading attributes\",x);\n                }\n            }\n\n        };\n        mbeansTab.getRequestProcessor().post(load);\n    }\n\n    // Don't call this in EDT, but execute returned Runnable inside\n    // EDT - typically in the done() method of a SwingWorker\n    // This method can return null.\n    private Runnable doLoadAttributes(final XMBean mbean, MBeanInfo infoOrNull)\n        throws JMException, IOException {\n        // To avoid deadlock with events coming from the JMX side,\n        // we retrieve all JMX stuff in a non synchronized block.\n\n        if(mbean == null) return null;\n        final MBeanInfo curMBeanInfo =\n                (infoOrNull==null)?mbean.getMBeanInfo():infoOrNull;\n\n        final MBeanAttributeInfo[] attrsInfo = curMBeanInfo.getAttributes();\n        final HashMap<String, Object> attrs =\n            new HashMap<String, Object>(attrsInfo.length);\n        final HashMap<String, Object> unavailableAttrs =\n            new HashMap<String, Object>(attrsInfo.length);\n        final HashMap<String, Object> viewableAttrs =\n            new HashMap<String, Object>(attrsInfo.length);\n        AttributeList list = null;\n\n        try {\n            list = mbean.getAttributes(attrsInfo);\n        }catch(Exception e) {\n            list = new AttributeList();\n            //Can't load all attributes, do it one after each other.\n            for(int i = 0; i < attrsInfo.length; i++) {\n                String name = null;\n                try {\n                    name = attrsInfo[i].getName();\n                    Object value =\n                        mbean.getMBeanServerConnection().\n                        getAttribute(mbean.getObjectName(), name);\n                    list.add(new Attribute(name, value));\n                }catch(Exception ex) {\n                    if(attrsInfo[i].isReadable()) {\n                        unavailableAttrs.put(name,\n                                Utils.getActualException(ex).toString());\n                    }\n                }\n            }\n        }\n        try {\n            int att_length = list.size();\n            for (int i=0;i<att_length;i++) {\n                Attribute attribute = (Attribute) list.get(i);\n                if(isViewable(attribute)) {\n                    viewableAttrs.put(attribute.getName(),\n                                           attribute.getValue());\n                }\n                else\n                    attrs.put(attribute.getName(),attribute.getValue());\n\n            }\n            // if not all attributes are accessible,\n            // check them one after the other.\n            if (att_length < attrsInfo.length) {\n                for (int i=0;i<attrsInfo.length;i++) {\n                    MBeanAttributeInfo attributeInfo = attrsInfo[i];\n                    if (!attrs.containsKey(attributeInfo.getName()) &&\n                        !viewableAttrs.containsKey(attributeInfo.\n                                                        getName()) &&\n                        !unavailableAttrs.containsKey(attributeInfo.\n                                                           getName())) {\n                        if (attributeInfo.isReadable()) {\n                            // getAttributes didn't help resolving the\n                            // exception.\n                            // We must call it again to understand what\n                            // went wrong.\n                            try {\n                                Object v =\n                                    mbean.getMBeanServerConnection().getAttribute(\n                                    mbean.getObjectName(), attributeInfo.getName());\n                                //What happens if now it is ok?\n                                // Be pragmatic, add it to readable...\n                                attrs.put(attributeInfo.getName(),\n                                               v);\n                            }catch(Exception e) {\n                                //Put the exception that will be displayed\n                                // in tooltip\n                                unavailableAttrs.put(attributeInfo.getName(),\n                                        Utils.getActualException(e).toString());\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        catch(Exception e) {\n            //sets all attributes unavailable except the writable ones\n            for (int i=0;i<attrsInfo.length;i++) {\n                MBeanAttributeInfo attributeInfo = attrsInfo[i];\n                if (attributeInfo.isReadable()) {\n                    unavailableAttrs.put(attributeInfo.getName(),\n                                              Utils.getActualException(e).\n                                              toString());\n                }\n            }\n        }\n        //end of retrieval\n\n        //one update at a time\n        return new Runnable() {\n            public void run() {\n                synchronized (XMBeanAttributes.this) {\n                    XMBeanAttributes.this.mbean = mbean;\n                    XMBeanAttributes.this.mbeanInfo = curMBeanInfo;\n                    XMBeanAttributes.this.attributesInfo = attrsInfo;\n                    XMBeanAttributes.this.attributes = attrs;\n                    XMBeanAttributes.this.unavailableAttributes = unavailableAttrs;\n                    XMBeanAttributes.this.viewableAttributes = viewableAttrs;\n\n                    DefaultTableModel tableModel =\n                            (DefaultTableModel) getModel();\n\n                    // add attribute information\n                    emptyTable(tableModel);\n\n                    addTableData(tableModel,\n                            mbean,\n                            attrsInfo,\n                            attrs,\n                            unavailableAttrs,\n                            viewableAttrs);\n\n                    // update the model with the new data\n                    tableModel.newDataAvailable(new TableModelEvent(tableModel));\n                    // re-register for change events\n                    tableModel.addTableModelListener(attributesListener);\n                }\n            }\n        };\n    }\n\n    void collapse(String attributeName, final Component c) {\n        final int row = getSelectedRow();\n        Object obj = getModel().getValueAt(row, VALUE_COLUMN);\n        if(obj instanceof ZoomedCell) {\n            cancelCellEditing();\n            ZoomedCell cell = (ZoomedCell) obj;\n            cell.reset();\n            setRowHeight(row,\n                         cell.getHeight());\n            editCellAt(row,\n                       VALUE_COLUMN);\n            invalidate();\n            repaint();\n        }\n    }\n\n    ZoomedCell updateZoomedCell(int row,\n                                int col) {\n        Object obj = getModel().getValueAt(row, VALUE_COLUMN);\n        ZoomedCell cell = null;\n        if(obj instanceof ZoomedCell) {\n            cell = (ZoomedCell) obj;\n            if(!cell.isInited()) {\n                Object elem = cell.getValue();\n                String attributeName =\n                    (String) getModel().getValueAt(row,\n                                                   NAME_COLUMN);\n                Component comp = mbeansTab.getDataViewer().\n                        createAttributeViewer(elem, mbean, attributeName, this);\n                if(comp != null){\n                    if(rowMinHeight == -1)\n                        rowMinHeight = getRowHeight(row);\n\n                    cell.init(super.getCellRenderer(row, col),\n                              comp,\n                              rowMinHeight);\n\n                    mbeansTab.getDataViewer().registerForMouseEvent(\n                            comp, mouseListener);\n                } else\n                    return cell;\n            }\n\n            cell.switchState();\n            setRowHeight(row,\n                         cell.getHeight());\n\n            if(!cell.isMaximized()) {\n                cancelCellEditing();\n                //Back to simple editor.\n                editCellAt(row,\n                           VALUE_COLUMN);\n            }\n\n            invalidate();\n            repaint();\n        }\n        return cell;\n    }\n\n    // This is called by XSheet when the \"refresh\" button is pressed.\n    // In this case we will commit any pending attribute values by\n    // calling 'stopCellEditing'.\n    //\n    public void refreshAttributes() {\n         refreshAttributes(true);\n    }\n\n    // refreshAttributes(false) is called by tableChanged().\n    // in this case we must not call stopCellEditing, because it's already\n    // been called - e.g.\n    // lostFocus/mousePressed -> stopCellEditing -> setValueAt -> tableChanged\n    //                        -> refreshAttributes(false)\n    //\n    // Can be called in EDT - as long as the implementation of\n    // mbeansTab.getCachedMBeanServerConnection() and mbsc.flush() doesn't\n    // change\n    //\n    private void refreshAttributes(final boolean stopCellEditing) {\n         SwingWorker<Void,Void> sw = new SwingWorker<Void,Void>() {\n\n            @Override\n            protected Void doInBackground() throws Exception {\n                CachedMBeanServerConnection mbsc =\n                        mbeansTab.getCachedMBeanServerConnection();\n                mbsc.flush();\n                return null;\n            }\n\n            @Override\n            protected void done() {\n                try {\n                    get();\n                    if (stopCellEditing) stopCellEditing();\n                    loadAttributes(mbean, mbeanInfo);\n                } catch (Exception x) {\n                    if (LOGGER.isLoggable(Level.FINER)) {\n                        LOGGER.log(Level.FINER,\n                        \"Unexpected exception while loading attributes\",// No I18N\n                                x);\n                    }\n                }\n            }\n         };\n         mbeansTab.getRequestProcessor().post(sw);\n     }\n\n    // We need to call stop editing here - otherwise edits are lost\n    // when resizing the table.\n    //\n    @Override\n    public void columnMarginChanged(ChangeEvent e) {\n        if (isEditing()) stopCellEditing();\n        super.columnMarginChanged(e);\n    }\n\n    // We need to call stop editing here - otherwise the edited value\n    // is transferred to the wrong row...\n    //\n    @Override\n    void sortRequested(int column) {\n        if (isEditing()) stopCellEditing();\n        super.sortRequested(column);\n    }\n\n\n    @Override\n    public synchronized void emptyTable() {\n         emptyTable((DefaultTableModel)getModel());\n     }\n\n    // Call this in synchronized block.\n    private void emptyTable(DefaultTableModel model) {\n         model.removeTableModelListener(attributesListener);\n         super.emptyTable();\n    }\n\n    private boolean isViewable(Attribute attribute) {\n        Object data = attribute.getValue();\n        return XDataViewer.isViewableValue(data);\n\n    }\n\n    synchronized void removeAttributes() {\n        if (attributes != null) {\n            attributes.clear();\n        }\n        if (unavailableAttributes != null) {\n            unavailableAttributes.clear();\n        }\n        if (viewableAttributes != null) {\n            viewableAttributes.clear();\n        }\n        mbean = null;\n    }\n\n    private ZoomedCell getZoomedCell(XMBean mbean, String attribute, Object value) {\n        synchronized (viewersCache) {\n            HashMap<String, ZoomedCell> viewers;\n            if (viewersCache.containsKey(mbean)) {\n                viewers = viewersCache.get(mbean);\n            } else {\n                viewers = new HashMap<String, ZoomedCell>();\n            }\n            ZoomedCell cell;\n            if (viewers.containsKey(attribute)) {\n                cell = viewers.get(attribute);\n                cell.setValue(value);\n                if (cell.isMaximized() && cell.getType() != XDataViewer.NUMERIC) {\n                    // Plotters are the only viewers with auto update capabilities.\n                    // Other viewers need to be updated manually.\n                    Component comp =\n                        mbeansTab.getDataViewer().createAttributeViewer(\n                            value, mbean, attribute, XMBeanAttributes.this);\n                    cell.init(cell.getMinRenderer(), comp, cell.getMinHeight());\n                    mbeansTab.getDataViewer().registerForMouseEvent(comp, mouseListener);\n                }\n            } else {\n                cell = new ZoomedCell(value);\n                viewers.put(attribute, cell);\n            }\n            viewersCache.put(mbean, viewers);\n            return cell;\n        }\n    }\n\n    //will be called in a synchronzed block\n    protected void addTableData(DefaultTableModel tableModel,\n                                XMBean mbean,\n                                MBeanAttributeInfo[] attributesInfo,\n                                HashMap<String, Object> attributes,\n                                HashMap<String, Object> unavailableAttributes,\n                                HashMap<String, Object> viewableAttributes) {\n\n        Object rowData[] = new Object[2];\n        int col1Width = 0;\n        int col2Width = 0;\n        for (int i = 0; i < attributesInfo.length; i++) {\n            rowData[0] = (attributesInfo[i].getName());\n            if (unavailableAttributes.containsKey(rowData[0])) {\n                rowData[1] = Resources.getText(\"LBL_Unavailable\"); // NOI18N\n            } else if (viewableAttributes.containsKey(rowData[0])) {\n                rowData[1] = viewableAttributes.get(rowData[0]);\n                if (!attributesInfo[i].isWritable() ||\n                    !Utils.isEditableType(attributesInfo[i].getType())) {\n                    rowData[1] = getZoomedCell(mbean, (String) rowData[0], rowData[1]);\n                }\n            } else {\n                rowData[1] = attributes.get(rowData[0]);\n            }\n\n            tableModel.addRow(rowData);\n\n            //Update column width\n            //\n            String str = null;\n            if(rowData[0] != null) {\n                str = rowData[0].toString();\n                if(str.length() > col1Width)\n                    col1Width = str.length();\n            }\n            if(rowData[1] != null) {\n                str = rowData[1].toString();\n                if(str.length() > col2Width)\n                    col2Width = str.length();\n            }\n        }\n        updateColumnWidth(col1Width, col2Width);\n    }\n\n    private void updateColumnWidth(int col1Width, int col2Width) {\n        TableColumnModel colModel = getColumnModel();\n\n        //Get the column at index pColumn, and set its preferred width.\n        col1Width = col1Width * 7;\n        col2Width = col2Width * 7;\n        if(col1Width + col2Width <\n           (int) getPreferredScrollableViewportSize().getWidth())\n            col2Width = (int) getPreferredScrollableViewportSize().getWidth()\n                - col1Width;\n\n        colModel.getColumn(NAME_COLUMN).setPreferredWidth(50);\n    }\n\n    class AttributesMouseListener extends MouseAdapter {\n\n        @Override\n        public void mousePressed(MouseEvent e) {\n            if(e.getButton() == MouseEvent.BUTTON1) {\n                if(e.getClickCount() >= 2) {\n\n                    int row = XMBeanAttributes.this.getSelectedRow();\n                    int col = XMBeanAttributes.this.getSelectedColumn();\n                    if(col != VALUE_COLUMN) return;\n                    if(col == -1 || row == -1) return;\n\n                    XMBeanAttributes.this.updateZoomedCell(row, col);\n                }\n            }\n        }\n    }\n\n    @SuppressWarnings(\"serial\")\n    class ValueCellEditor extends XTextFieldEditor {\n        // implements javax.swing.table.TableCellEditor\n        @Override\n        public Component getTableCellEditorComponent(JTable table,\n                                                     Object value,\n                                                     boolean isSelected,\n                                                     int row,\n                                                     int column) {\n            Object val = value;\n            if(column == VALUE_COLUMN) {\n                Object obj = getModel().getValueAt(row,\n                                                   column);\n                if(obj instanceof ZoomedCell) {\n                    ZoomedCell cell = (ZoomedCell) obj;\n                    if(cell.getRenderer() instanceof MaximizedCellRenderer) {\n                        MaximizedCellRenderer zr =\n                            (MaximizedCellRenderer) cell.getRenderer();\n                        return zr.getComponent();\n                    }\n                } else {\n                    Component comp = super.getTableCellEditorComponent(\n                            table, val, isSelected, row, column);\n                    if (isCellError(row, column) ||\n                        !isWritable(row) ||\n                        !Utils.isEditableType(getClassName(row))) {\n                        textField.setEditable(false);\n                    }\n                    return comp;\n                }\n            }\n            return super.getTableCellEditorComponent(table,\n                                                     val,\n                                                     isSelected,\n                                                     row,\n                                                     column);\n        }\n        @Override\n        public boolean stopCellEditing() {\n            int editingRow = getEditingRow();\n            int editingColumn = getEditingColumn();\n            if (editingColumn == VALUE_COLUMN) {\n                Object obj = getModel().getValueAt(editingRow, editingColumn);\n                if (obj instanceof ZoomedCell) {\n                    ZoomedCell cell = (ZoomedCell) obj;\n                    if (cell.isMaximized()) {\n                        this.cancelCellEditing();\n                        return true;\n                    }\n                }\n            }\n            return super.stopCellEditing();\n        }\n    }\n\n    @SuppressWarnings(\"serial\")\n    class MaximizedCellRenderer extends  DefaultTableCellRenderer {\n        Component comp;\n        MaximizedCellRenderer(Component comp) {\n            this.comp = comp;\n            Dimension d = comp.getPreferredSize();\n            if (d.getHeight() > 220) {\n                comp.setPreferredSize(new Dimension((int) d.getWidth(), 220));\n            }\n        }\n        @Override\n        public Component getTableCellRendererComponent(JTable table,\n                                                       Object value,\n                                                       boolean isSelected,\n                                                       boolean hasFocus,\n                                                       int row,\n                                                       int column) {\n            return comp;\n        }\n        public Component getComponent() {\n            return comp;\n        }\n    }\n\n    class ZoomedCell {\n        TableCellRenderer minRenderer;\n        MaximizedCellRenderer maxRenderer;\n        int minHeight;\n        boolean minimized = true;\n        boolean init = false;\n        int type;\n        Object value;\n        ZoomedCell(Object value) {\n            type = XDataViewer.getViewerType(value);\n            this.value = value;\n        }\n\n        boolean isInited() {\n            return init;\n        }\n\n        Object getValue() {\n            return value;\n        }\n\n        void setValue(Object value) {\n            this.value = value;\n        }\n\n        void init(TableCellRenderer minRenderer,\n                  Component maxComponent,\n                  int minHeight) {\n            this.minRenderer = minRenderer;\n            this.maxRenderer = new MaximizedCellRenderer(maxComponent);\n\n            this.minHeight = minHeight;\n            init = true;\n        }\n\n        int getType() {\n            return type;\n        }\n\n        void reset() {\n            init = false;\n            minimized = true;\n        }\n\n        void switchState() {\n            minimized = !minimized;\n        }\n        boolean isMaximized() {\n            return !minimized;\n        }\n        void minimize() {\n            minimized = true;\n        }\n\n        void maximize() {\n            minimized = false;\n        }\n\n        int getHeight() {\n            if(minimized) return minHeight;\n            else\n                return (int) maxRenderer.getComponent().\n                    getPreferredSize().getHeight() ;\n        }\n\n        int getMinHeight() {\n            return minHeight;\n        }\n\n        @Override\n        public String toString() {\n\n            if(value == null) return null;\n\n            if(value.getClass().isArray()) {\n                String name =\n                    Utils.getArrayClassName(value.getClass().getName());\n                int length = Array.getLength(value);\n                return name + \"[\" + length +\"]\"; // NOI18N\n            }\n\n            if(value instanceof CompositeData ||\n               value instanceof TabularData)\n                return value.getClass().getName();\n\n            return value.toString();\n        }\n\n        TableCellRenderer getRenderer() {\n            if(minimized) return minRenderer;\n            else return maxRenderer;\n        }\n\n        TableCellRenderer getMinRenderer() {\n            return minRenderer;\n        }\n    }\n\n    class AttributesListener implements  TableModelListener {\n\n        private Component component;\n\n        public AttributesListener(Component component) {\n            this.component = component;\n        }\n\n        // Call this in EDT\n        public void tableChanged(final TableModelEvent e) {\n            // only post changes to the draggable column\n            if (isColumnEditable(e.getColumn())) {\n                final TableModel model = (TableModel)e.getSource();\n                Object tableValue = model.getValueAt(e.getFirstRow(),\n                                                 e.getColumn());\n\n                if (LOGGER.isLoggable(Level.FINER)) {\n                    LOGGER.finer(\"tableChanged: firstRow=\"+e.getFirstRow()+\n                        \", lastRow=\"+e.getLastRow()+\", column=\"+e.getColumn()+\n                        \", value=\"+tableValue);\n                }\n                // if it's a String, try construct new value\n                // using the defined type.\n                if (tableValue instanceof String) {\n                    try {\n                        tableValue =\n                            Utils.createObjectFromString(getClassName(e.getFirstRow()), // type\n                            (String)tableValue);// value\n                    } catch (Throwable ex) {\n                        popupAndLog(ex,\"tableChanged\",\n                                \"LBL_ProblemSettingAttribute\");\n                    }\n                }\n                final String attributeName = getValueName(e.getFirstRow());\n                final Attribute attribute =\n                      new Attribute(attributeName,tableValue);\n                setAttribute(attribute, \"tableChanged\");\n            }\n        }\n\n        // Call this in EDT\n        private void setAttribute(final Attribute attribute, final String method) {\n            final SwingWorker<Void,Void> setAttribute =\n                    new SwingWorker<Void,Void>() {\n                @Override\n                protected Void doInBackground() throws Exception {\n                    try {\n                        mbean.setAttribute(attribute);\n                    } catch (Throwable ex) {\n                        popupAndLog(ex,method,\"LBL_ProblemSettingAttribute\");\n                    }\n                    return null;\n                }\n                @Override\n                protected void done() {\n                    try {\n                        get();\n                    } catch (Exception x) {\n                        // XX should not happen\n                        // XXX log this\n                    }\n                    refreshAttributes(false);\n                }\n\n            };\n            mbeansTab.getRequestProcessor().post(setAttribute);\n        }\n\n        // Call this outside EDT\n        private void popupAndLog(Throwable ex, String method, String key) {\n            ex = Utils.getActualException(ex);\n            LOGGER.throwing(XMBeanAttributes.class.getName(), method, ex); // NOI18N\n\n            String message = (ex.getMessage() != null) ? ex.getMessage()\n                    : ex.toString();\n            EventQueue.invokeLater(\n                    new ThreadDialog(component,\n                                     message+\"\\n\", // NOI18N\n                                     Resources.getText(key), // NOI18N\n                                     JOptionPane.ERROR_MESSAGE));\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XMBeanInfo.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.util.*;\nimport javax.management.*;\nimport javax.swing.*;\nimport javax.swing.event.*;\nimport javax.swing.table.*;\n\nimport static org.graalvm.visualvm.modules.mbeans.Utilities.*;\n\n@SuppressWarnings(\"serial\")\nclass XMBeanInfo extends JPanel {\n    \n    private static final Color lightSalmon = new Color(255, 160, 122);\n    private static final Color lightYellow = new Color(255, 255, 128);\n    \n    private final int NAME_COLUMN = 0;\n    private final int VALUE_COLUMN = 1;\n    \n    private final String[] columnNames = {\n        Resources.getText(\"LBL_Name\"), // NOI18N\n        Resources.getText(\"LBL_Value\") // NOI18N\n    };\n    \n    private JTable infoTable = new JTable();\n    \n    private static class ReadOnlyDefaultTableModel extends DefaultTableModel {\n        @Override\n        public void setValueAt(Object value, int row, int col) {\n        }\n    }\n    \n    private static class TableRowDivider {\n        \n        public String tableRowDividerText;\n        public Color tableRowDividerColor;\n        \n        public TableRowDivider(\n                String tableRowDividerText, Color tableRowDividerColor) {\n            this.tableRowDividerText = tableRowDividerText;\n            this.tableRowDividerColor = tableRowDividerColor;\n        }\n        \n        @Override\n        public String toString() {\n            return tableRowDividerText;\n        }\n    }\n    \n    private static MBeanInfoTableCellRenderer renderer =\n            new MBeanInfoTableCellRenderer();\n    \n    private static class MBeanInfoTableCellRenderer\n            extends DefaultTableCellRenderer {\n        @Override\n        public Component getTableCellRendererComponent(\n                JTable table, Object value, boolean isSelected,\n                boolean hasFocus, int row, int column) {\n            Component comp = super.getTableCellRendererComponent(\n                    table, value, isSelected, hasFocus, row, column);\n            if (value instanceof TableRowDivider) {\n                JLabel label = new JLabel(\n                        \"<html><b>\" + value.toString() + \"</b></html>\"); // NOI18N\n                label.setBackground(ensureContrast(\n                        ((TableRowDivider) value).tableRowDividerColor,\n                        label.getForeground()));\n                label.setOpaque(true);\n                return label;\n            }\n            return comp;\n        }\n    }\n    \n    private static TableCellEditor editor =\n            new MBeanInfoTableCellEditor(new JTextField());\n    \n    private static class MBeanInfoTableCellEditor\n            extends Utils.ReadOnlyTableCellEditor {\n        public MBeanInfoTableCellEditor(JTextField tf) {\n            super(tf);\n        }\n        @Override\n        public Component getTableCellEditorComponent(\n                JTable table, Object value, boolean isSelected,\n                int row, int column) {\n            Component comp = super.getTableCellEditorComponent(\n                    table, value, isSelected, row, column);\n            if (value instanceof TableRowDivider) {\n                JLabel label = new JLabel(\n                        \"<html><b>\" + value.toString() + \"</b></html>\"); // NOI18N\n                label.setBackground(ensureContrast(\n                        ((TableRowDivider) value).tableRowDividerColor,\n                        label.getForeground()));\n                label.setOpaque(true);\n                return label;\n            }\n            return comp;\n        }\n    }\n    \n    public XMBeanInfo() {\n        super(new BorderLayout());\n        setBorder(BorderFactory.createTitledBorder(Resources.getText(\"LBL_MBeanInfo\"))); // NOI18N\n        infoTable.setModel(new ReadOnlyDefaultTableModel());\n        infoTable.setRowSelectionAllowed(false);\n        infoTable.setColumnSelectionAllowed(false);\n        infoTable.getTableHeader().setReorderingAllowed(false);\n        ((DefaultTableModel) infoTable.getModel()).setColumnIdentifiers(columnNames);\n        infoTable.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(140);\n        infoTable.getColumnModel().getColumn(NAME_COLUMN).setMaxWidth(140);\n        infoTable.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(renderer);\n        infoTable.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(renderer);\n        infoTable.getColumnModel().getColumn(NAME_COLUMN).setCellEditor(editor);\n        infoTable.getColumnModel().getColumn(VALUE_COLUMN).setCellEditor(editor);\n        infoTable.addKeyListener(new Utils.CopyKeyAdapter());\n        infoTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);\n        JScrollPane infoTableScrollPane = new JScrollPane(infoTable);\n        add(infoTableScrollPane);\n    }\n    \n    // Call on EDT\n    public void emptyInfoTable() {\n        DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();\n        while (tableModel.getRowCount() > 0) {\n            tableModel.removeRow(0);\n        }\n    }\n    \n    // Call on EDT\n    private void addDescriptor(Descriptor desc, String text) {\n        if (desc != null && desc.getFieldNames().length > 0) {\n            DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();\n            Object rowData[] = new Object[2];\n            rowData[0] = new TableRowDivider(\n                    text + \" \" + Resources.getText(\"LBL_Descriptor\") + \":\", lightYellow); // NOI18N\n            rowData[1] = new TableRowDivider(\"\", lightYellow); // NOI18N\n            tableModel.addRow(rowData);\n            for (String fieldName : desc.getFieldNames()) {\n                rowData[0] = fieldName;\n                Object fieldValue = desc.getFieldValue(fieldName);\n                if (fieldValue instanceof boolean[]) {\n                    rowData[1] = Arrays.toString((boolean[]) fieldValue);\n                } else if (fieldValue instanceof byte[]) {\n                    rowData[1] = Arrays.toString((byte[]) fieldValue);\n                } else if (fieldValue instanceof char[]) {\n                    rowData[1] = Arrays.toString((char[]) fieldValue);\n                } else if (fieldValue instanceof double[]) {\n                    rowData[1] = Arrays.toString((double[]) fieldValue);\n                } else if (fieldValue instanceof float[]) {\n                    rowData[1] = Arrays.toString((float[]) fieldValue);\n                } else if (fieldValue instanceof int[]) {\n                    rowData[1] = Arrays.toString((int[]) fieldValue);\n                } else if (fieldValue instanceof long[]) {\n                    rowData[1] = Arrays.toString((long[]) fieldValue);\n                } else if (fieldValue instanceof short[]) {\n                    rowData[1] = Arrays.toString((short[]) fieldValue);\n                } else if (fieldValue instanceof Object[]) {\n                    rowData[1] = Arrays.toString((Object[]) fieldValue);\n                } else {\n                    rowData[1] = fieldValue;\n                }\n                tableModel.addRow(rowData);\n            }\n            tableModel.newDataAvailable(new TableModelEvent(tableModel));\n        }\n    }\n    \n    // Call on EDT\n    private void addMBeanInfo(XMBean mbean, MBeanInfo mbeanInfo) {\n        String border = Resources.getText(\"LBL_MBeanInfo\"); // NOI18N\n        String text = Resources.getText(\"LBL_Info\"); // NOI18N\n        DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();\n        Object rowData[] = new Object[2];\n        rowData[0] = new TableRowDivider(border, lightSalmon);\n        rowData[1] = new TableRowDivider(\"\", lightSalmon); // NOI18N\n        tableModel.addRow(rowData);\n        rowData[0] = new TableRowDivider(text + \":\", lightYellow); // NOI18N\n        rowData[1] = new TableRowDivider(\"\", lightYellow); // NOI18N\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_ObjectName\"); // NOI18N\n        rowData[1] = mbean.getObjectName();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_ClassName\"); // NOI18N\n        rowData[1] = mbeanInfo.getClassName();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Description\"); // NOI18N\n        rowData[1] = mbeanInfo.getDescription();\n        tableModel.addRow(rowData);\n        addDescriptor(mbeanInfo.getDescriptor(), text);\n        // MBeanConstructorInfo\n        //\n        int i = 0;\n        for (MBeanConstructorInfo mbci : mbeanInfo.getConstructors()) {\n            addMBeanConstructorInfo(mbci,\n                    Resources.getText(\"LBL_Constructor\") + \"-\" + i); // NOI18N\n            // MBeanParameterInfo\n            //\n            int j = 0;\n            for (MBeanParameterInfo mbpi : mbci.getSignature()) {\n                addMBeanParameterInfo(mbpi,\n                        Resources.getText(\"LBL_Parameter\") + \"-\" + i + \"-\" + j); // NOI18N\n                j++;\n            }\n            i++;\n        }\n        tableModel.newDataAvailable(new TableModelEvent(tableModel));\n    }\n    \n    // Call on EDT\n    private void addMBeanAttributeInfo(MBeanAttributeInfo mbai) {\n        String border = Resources.getText(\"LBL_MBeanAttributeInfo\"); // NOI18N\n        String text = Resources.getText(\"LBL_Attribute\"); // NOI18N\n        DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();\n        Object rowData[] = new Object[2];\n        rowData[0] = new TableRowDivider(border, lightSalmon);\n        rowData[1] = new TableRowDivider(\"\", lightSalmon); // NOI18N\n        tableModel.addRow(rowData);\n        rowData[0] = new TableRowDivider(text + \":\", lightYellow); // NOI18N\n        rowData[1] = new TableRowDivider(\"\", lightYellow); // NOI18N\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Name\"); // NOI18N\n        rowData[1] = mbai.getName();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Description\"); // NOI18N\n        rowData[1] = mbai.getDescription();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Readable\"); // NOI18N\n        rowData[1] = mbai.isReadable();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Writable\"); // NOI18N\n        rowData[1] = mbai.isWritable();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Is\"); // NOI18N\n        rowData[1] = mbai.isIs();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Type\"); // NOI18N\n        rowData[1] = mbai.getType();\n        tableModel.addRow(rowData);\n        addDescriptor(mbai.getDescriptor(), text);\n        tableModel.newDataAvailable(new TableModelEvent(tableModel));\n    }\n    \n    // Call on EDT\n    private void addMBeanOperationInfo(MBeanOperationInfo mboi) {\n        String border = Resources.getText(\"LBL_MBeanOperationInfo\"); // NOI18N\n        String text = Resources.getText(\"LBL_Operation\"); // NOI18N\n        DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();\n        Object rowData[] = new Object[2];\n        rowData[0] = new TableRowDivider(border, lightSalmon);\n        rowData[1] = new TableRowDivider(\"\", lightSalmon); // NOI18N\n        tableModel.addRow(rowData);\n        rowData[0] = new TableRowDivider(text + \":\", lightYellow); // NOI18N\n        rowData[1] = new TableRowDivider(\"\", lightYellow); // NOI18N\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Name\"); // NOI18N\n        rowData[1] = mboi.getName();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Description\"); // NOI18N\n        rowData[1] = mboi.getDescription();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Impact\"); // NOI18N\n        switch (mboi.getImpact()) {\n            case MBeanOperationInfo.INFO:\n                rowData[1] = Resources.getText(\"LBL_INFO\"); // NOI18N\n                break;\n            case MBeanOperationInfo.ACTION:\n                rowData[1] = Resources.getText(\"LBL_ACTION\"); // NOI18N\n                break;\n            case MBeanOperationInfo.ACTION_INFO:\n                rowData[1] = Resources.getText(\"LBL_ACTION_INFO\"); // NOI18N\n                break;\n            case MBeanOperationInfo.UNKNOWN:\n                rowData[1] = Resources.getText(\"LBL_UNKNOWN\"); // NOI18N\n                break;\n        }\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_ReturnType\"); // NOI18N\n        rowData[1] = mboi.getReturnType();\n        tableModel.addRow(rowData);\n        addDescriptor(mboi.getDescriptor(), text);\n        // MBeanParameterInfo\n        //\n        int i = 0;\n        for (MBeanParameterInfo mbpi : mboi.getSignature()) {\n            addMBeanParameterInfo(mbpi,\n                    Resources.getText(\"LBL_Parameter\") + \"-\" + i++); // NOI18N\n        }\n        tableModel.newDataAvailable(new TableModelEvent(tableModel));\n    }\n    \n    // Call on EDT\n    private void addMBeanNotificationInfo(MBeanNotificationInfo mbni) {\n        String border = Resources.getText(\"LBL_MBeanNotificationInfo\") + \":\"; // NOI18N\n        String text = Resources.getText(\"LBL_Notification\"); // NOI18N\n        DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();\n        Object rowData[] = new Object[2];\n        rowData[0] = new TableRowDivider(border, lightSalmon);\n        rowData[1] = new TableRowDivider(\"\", lightSalmon); // NOI18N\n        tableModel.addRow(rowData);\n        rowData[0] = new TableRowDivider(text + \":\", lightYellow); // NOI18N\n        rowData[1] = new TableRowDivider(\"\", lightYellow); // NOI18N\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Name\"); // NOI18N\n        rowData[1] = mbni.getName();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Description\"); // NOI18N\n        rowData[1] = mbni.getDescription();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_NotifTypes\"); // NOI18N\n        rowData[1] = Arrays.toString(mbni.getNotifTypes());\n        tableModel.addRow(rowData);\n        addDescriptor(mbni.getDescriptor(), text);\n        tableModel.newDataAvailable(new TableModelEvent(tableModel));\n    }\n    \n    // Call on EDT\n    private void addMBeanConstructorInfo(MBeanConstructorInfo mbci, String text) {\n        DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();\n        Object rowData[] = new Object[2];\n        rowData[0] = new TableRowDivider(text + \":\", lightYellow); // NOI18N\n        rowData[1] = new TableRowDivider(\"\", lightYellow); // NOI18N\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Name\"); // NOI18N\n        rowData[1] = mbci.getName();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Description\"); // NOI18N\n        rowData[1] = mbci.getDescription();\n        tableModel.addRow(rowData);\n        addDescriptor(mbci.getDescriptor(), text);\n        tableModel.newDataAvailable(new TableModelEvent(tableModel));\n    }\n    \n    // Call on EDT\n    private void addMBeanParameterInfo(MBeanParameterInfo mbpi, String text) {\n        DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();\n        Object rowData[] = new Object[2];\n        rowData[0] = new TableRowDivider(text + \":\", lightYellow); // NOI18N\n        rowData[1] = new TableRowDivider(\"\", lightYellow); // NOI18N\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Name\"); // NOI18N\n        rowData[1] = mbpi.getName();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Description\"); // NOI18N\n        rowData[1] = mbpi.getDescription();\n        tableModel.addRow(rowData);\n        rowData[0] = Resources.getText(\"LBL_Type\"); // NOI18N\n        rowData[1] = mbpi.getType();\n        tableModel.addRow(rowData);\n        addDescriptor(mbpi.getDescriptor(), text);\n        tableModel.newDataAvailable(new TableModelEvent(tableModel));\n    }\n\n    // Call on EDT\n    public void loadMBeanInfo(XMBean mbean, MBeanInfo mbeanInfo) {\n        // MBeanInfo\n        //\n        addMBeanInfo(mbean, mbeanInfo);\n        // MBeanAttributeInfo\n        //\n        MBeanAttributeInfo[] ai = mbeanInfo.getAttributes();\n        if (ai != null && ai.length > 0) {\n            for (MBeanAttributeInfo mbai : ai) {\n                addMBeanAttributeInfo(mbai);\n            }\n        }\n        // MBeanOperationInfo\n        //\n        MBeanOperationInfo[] oi = mbeanInfo.getOperations();\n        if (oi != null && oi.length > 0) {\n            for (MBeanOperationInfo mboi : oi) {\n                addMBeanOperationInfo(mboi);\n            }\n        }\n        // MBeanNotificationInfo\n        //\n        MBeanNotificationInfo[] ni = mbeanInfo.getNotifications();\n        if (ni != null && ni.length > 0) {\n            for (MBeanNotificationInfo mbni : ni) {\n                addMBeanNotificationInfo(mbni);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XMBeanNotifications.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport javax.swing.*;\nimport javax.swing.event.*;\nimport javax.swing.table.*;\nimport javax.swing.tree.*;\nimport java.awt.Font;\n\nimport java.text.SimpleDateFormat;\n\nimport java.awt.Component;\nimport java.awt.EventQueue;\nimport java.awt.event.*;\nimport java.awt.Dimension;\nimport java.util.*;\nimport java.io.*;\nimport java.lang.reflect.Array;\n\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.*;\nimport javax.management.openmbean.CompositeData;\nimport javax.management.openmbean.TabularData;\n\nclass XMBeanNotifications extends JTable implements NotificationListener {\n    \n    private final static String[] columnNames =  {\n        Resources.getText(\"LBL_TimeStamp\"), // NOI18N\n        Resources.getText(\"LBL_Type\"), // NOI18N\n        Resources.getText(\"LBL_UserData\"), // NOI18N\n        Resources.getText(\"LBL_SeqNum\"), // NOI18N\n        Resources.getText(\"LBL_Message\"), // NOI18N\n        Resources.getText(\"LBL_Event\"), // NOI18N\n        Resources.getText(\"LBL_Source\")}; // NOI18N\n    \n    private final static Logger LOGGER = Logger.getLogger(XMBeanNotifications.class.getName());\n    \n    private HashMap<ObjectName, XMBeanNotificationsListener> listeners =\n            new HashMap<ObjectName, XMBeanNotificationsListener>();\n    private volatile boolean subscribed;\n    private XMBeanNotificationsListener currentListener;\n    public final static String NOTIFICATION_RECEIVED_EVENT =\n            \"jconsole.xnotification.received\"; // NOI18N\n    private List<NotificationListener> notificationListenersList;\n    private volatile boolean enabled;\n    private Font normalFont, boldFont;\n    private int rowMinHeight = -1;\n    private TableCellEditor userDataEditor = new UserDataCellEditor();\n    private NotifMouseListener mouseListener = new NotifMouseListener();\n    private SimpleDateFormat timeFormater = new SimpleDateFormat(\"HH:mm:ss:SSS\"); // NOI18N\n    private static TableCellEditor editor =\n            new Utils.ReadOnlyTableCellEditor(new JTextField());\n    \n    public XMBeanNotifications() {\n        super(new TableSorter(columnNames,0));\n        setColumnSelectionAllowed(false);\n        setRowSelectionAllowed(false);\n        getTableHeader().setReorderingAllowed(false);\n        ArrayList<NotificationListener> l =\n                new ArrayList<NotificationListener>(1);\n        notificationListenersList = Collections.synchronizedList(l);\n        \n        addMouseListener(mouseListener);\n        \n        TableColumnModel colModel = getColumnModel();\n        colModel.getColumn(0).setPreferredWidth(45);\n        colModel.getColumn(1).setPreferredWidth(50);\n        colModel.getColumn(2).setPreferredWidth(50);\n        colModel.getColumn(3).setPreferredWidth(40);\n        colModel.getColumn(4).setPreferredWidth(50);\n        colModel.getColumn(5).setPreferredWidth(50);\n        setColumnEditors();\n        addKeyListener(new Utils.CopyKeyAdapter());\n    }\n    \n    // Call on EDT\n    public void cancelCellEditing() {\n        TableCellEditor tce = getCellEditor();\n        if (tce != null) {\n            tce.cancelCellEditing();\n        }\n    }\n    \n    // Call on EDT\n    public void stopCellEditing() {\n        TableCellEditor tce = getCellEditor();\n        if (tce != null) {\n            tce.stopCellEditing();\n        }\n    }\n    \n    // Call on EDT\n    @Override\n    public boolean isCellEditable(int row, int col) {\n        UserDataCell cell = getUserDataCell(row, col);\n        if (cell != null) {\n            return cell.isMaximized();\n        }\n        return true;\n    }\n    \n    // Call on EDT\n    @Override\n    public void setValueAt(Object value, int row, int column) {\n    }\n    \n    // Call on EDT\n    @Override\n    public synchronized Component prepareRenderer(\n            TableCellRenderer renderer, int row, int column) {\n        //In case we have a repaint thread that is in the process of\n        //repainting an obsolete table, just ignore the call.\n        //It can happen when MBean selection is switched at a very quick rate\n        if (row >= getRowCount())\n            return null;\n        \n        Component comp = super.prepareRenderer(renderer, row, column);\n        \n        if (normalFont == null) {\n            normalFont = comp.getFont();\n            boldFont = normalFont.deriveFont(Font.BOLD);\n        }\n        UserDataCell cell = getUserDataCell(row, 2);\n        if (column == 2 && cell != null) {\n            comp.setFont(boldFont);\n            int size = cell.getHeight();\n            if (size > 0) {\n                if(getRowHeight(row) != size)\n                    setRowHeight(row, size);\n            }\n        } else {\n            comp.setFont(normalFont);\n        }\n        \n        return comp;\n    }\n    \n    // Call on EDT\n    @Override\n    public synchronized TableCellRenderer getCellRenderer(int row, int column) {\n        //In case we have a repaint thread that is in the process of\n        //repainting an obsolete table, just ignore the call.\n        //It can happen when MBean selection is switched at a very quick rate\n        if (row >= getRowCount())\n            return null;\n        \n        DefaultTableCellRenderer renderer;\n        String toolTip = null;\n        UserDataCell cell = getUserDataCell(row, column);\n        if (cell != null && cell.isInited()) {\n            renderer = (DefaultTableCellRenderer) cell.getRenderer();\n        } else {\n            renderer =\n                    (DefaultTableCellRenderer) super.getCellRenderer(row, column);\n        }\n        \n        if (cell != null)\n            toolTip = Resources.getText(\"LBL_DoubleClickToExpandCollapse\") + // NOI18N\n                    \". \" + cell.toString(); // NOI18N\n        else {\n            Object val =\n                    ((DefaultTableModel) getModel()).getValueAt(row, column);\n            if (val != null)\n                toolTip = val.toString();\n        }\n        \n        renderer.setToolTipText(toolTip);\n        \n        return renderer;\n    }\n    \n    // Call on EDT\n    private UserDataCell getUserDataCell(int row, int column) {\n        Object obj = ((DefaultTableModel) getModel()).getValueAt(row,column);\n        if (obj instanceof UserDataCell) return (UserDataCell) obj;\n        return null;\n    }\n    \n    synchronized void dispose() {\n        listeners.clear();\n    }\n    \n    public long getReceivedNotifications(XMBean mbean) {\n        XMBeanNotificationsListener listener =\n                listeners.get(mbean.getObjectName());\n        if (listener == null)\n            return 0;\n        else\n            return listener.getReceivedNotifications();\n    }\n    \n    public synchronized boolean clearCurrentNotifications() {\n        emptyTable();\n        if (currentListener != null) {\n            currentListener.clear();\n            return true;\n        } else\n            return false;\n    }\n    \n    public synchronized boolean unregisterListener(DefaultMutableTreeNode node) {\n        XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData();\n        return unregister(mbean.getObjectName());\n    }\n    \n    public synchronized void registerListener(DefaultMutableTreeNode node)\n    throws InstanceNotFoundException, IOException {\n        XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData();\n        if (!subscribed) {\n            try {\n                mbean.getMBeanServerConnection().addNotificationListener(\n                        MBeanServerDelegate.DELEGATE_NAME, this, null, null);\n                subscribed = true;\n            } catch (Exception e) {\n                LOGGER.log(Level.SEVERE, \"Error adding listener for delegate\", e); // NOI18N\n            }\n        }\n        XMBeanNotificationsListener listener =\n                listeners.get(mbean.getObjectName());\n        if (listener == null) {\n            listener = new XMBeanNotificationsListener(\n                    this, mbean, node, columnNames);\n            listeners.put(mbean.getObjectName(), listener);\n        } else {\n            if (!listener.isRegistered()) {\n                emptyTable();\n                listener.register(node);\n            }\n        }\n        enabled = true;\n        currentListener = listener;\n    }\n    \n    public synchronized void handleNotification(\n            Notification notif, Object handback) {\n        try {\n            if (notif instanceof MBeanServerNotification) {\n                ObjectName mbean =\n                        ((MBeanServerNotification) notif).getMBeanName();\n                if (notif.getType().indexOf(\"JMX.mbean.unregistered\") >= 0) { // NOI18N\n                    unregister(mbean);\n                }\n            }\n        } catch(Exception e) {\n            LOGGER.log(Level.SEVERE, \"Error unregistering notification\", e); // NOI18N\n        }\n    }\n    \n    public synchronized void disableNotifications() {\n        emptyTable();\n        currentListener = null;\n        enabled = false;\n    }\n    \n    private synchronized boolean unregister(ObjectName mbean) {\n        XMBeanNotificationsListener listener = listeners.get(mbean);\n        if (listener != null && listener.isRegistered()) {\n            listener.unregister();\n            return true;\n        } else\n            return false;\n    }\n    \n    public void addNotificationsListener(NotificationListener nl) {\n        notificationListenersList.add(nl);\n    }\n    \n    public void removeNotificationsListener(NotificationListener nl) {\n        notificationListenersList.remove(nl);\n    }\n    \n    // Call on EDT\n    void fireNotificationReceived(\n            XMBeanNotificationsListener listener, XMBean mbean,\n            DefaultMutableTreeNode node, Object[] rowData, long received) {\n        if (enabled) {\n            DefaultTableModel tableModel = (DefaultTableModel) getModel();\n            if (listener == currentListener) {\n                tableModel.insertRow(0, rowData);\n                repaint();\n            }\n        }\n        Notification notif =\n                new Notification(NOTIFICATION_RECEIVED_EVENT, this, 0);\n        notif.setUserData(received);\n        for (NotificationListener nl : notificationListenersList)\n            nl.handleNotification(notif, node);\n    }\n    \n    // Call on EDT\n    private void updateModel(List<Object[]> data) {\n        emptyTable();\n        DefaultTableModel tableModel = (DefaultTableModel) getModel();\n        for (Object[] rowData : data)\n            tableModel.addRow(rowData);\n    }\n    \n    public synchronized boolean isListenerRegistered(XMBean mbean) {\n        XMBeanNotificationsListener listener =\n                listeners.get(mbean.getObjectName());\n        if (listener == null) return false;\n        return listener.isRegistered();\n    }\n    \n    // Call on EDT\n    public synchronized void loadNotifications(XMBean mbean) {\n        XMBeanNotificationsListener listener =\n                listeners.get(mbean.getObjectName());\n        emptyTable();\n        if (listener != null) {\n            enabled = true;\n            List<Object[]> data = listener.getData();\n            updateModel(data);\n            currentListener = listener;\n            validate();\n            repaint();\n        } else\n            enabled = false;\n    }\n    \n    // Call on EDT\n    private void setColumnEditors() {\n        TableColumnModel tcm = getColumnModel();\n        for (int i = 0; i < columnNames.length; i++) {\n            TableColumn tc = tcm.getColumn(i);\n            if (i == 2) {\n                tc.setCellEditor(userDataEditor);\n            } else {\n                tc.setCellEditor(editor);\n            }\n        }\n    }\n    \n    // Call on EDT\n    public boolean isTableEditable() {\n        return true;\n    }\n    \n    // Call on EDT\n    public synchronized void emptyTable() {\n        DefaultTableModel model = (DefaultTableModel) getModel();\n        //invalidate();\n        while (model.getRowCount() > 0)\n            model.removeRow(0);\n        validate();\n    }\n    \n    // Call on EDT\n    synchronized void updateUserDataCell(int row, int col) {\n        Object obj = getModel().getValueAt(row, 2);\n        if (obj instanceof UserDataCell) {\n            UserDataCell cell = (UserDataCell) obj;\n            if (!cell.isInited()) {\n                if (rowMinHeight == -1)\n                    rowMinHeight = getRowHeight(row);\n                cell.init(super.getCellRenderer(row, col), rowMinHeight);\n            }\n            \n            cell.switchState();\n            setRowHeight(row, cell.getHeight());\n            \n            if(!cell.isMaximized()) {\n                cancelCellEditing();\n                //Back to simple editor.\n                editCellAt(row, 2);\n            }\n            \n            invalidate();\n            repaint();\n        }\n    }\n    \n    class UserDataCellRenderer extends DefaultTableCellRenderer {\n        Component comp;\n        UserDataCellRenderer(Component comp) {\n            this.comp = comp;\n            Dimension d = comp.getPreferredSize();\n            if (d.getHeight() > 200) {\n                comp.setPreferredSize(new Dimension((int) d.getWidth(), 200));\n            }\n        }\n        \n        @Override\n        public Component getTableCellRendererComponent(\n                JTable table,\n                Object value,\n                boolean isSelected,\n                boolean hasFocus,\n                int row,\n                int column) {\n            return comp;\n        }\n        \n        public Component getComponent() {\n            return comp;\n        }\n        \n    }\n    \n    class UserDataCell {\n        TableCellRenderer minRenderer;\n        UserDataCellRenderer maxRenderer;\n        int minHeight;\n        boolean minimized = true;\n        boolean init = false;\n        Object userData;\n        UserDataCell(Object userData, Component max) {\n            this.userData = userData;\n            this.maxRenderer = new UserDataCellRenderer(max);\n            \n        }\n        \n        @Override\n        public String toString() {\n            if (userData == null) return null;\n            if (userData.getClass().isArray()) {\n                String name =\n                        Utils.getArrayClassName(userData.getClass().getName());\n                int length = Array.getLength(userData);\n                return name + \"[\" + length +\"]\"; // NOI18N\n            }\n            \n            if (userData instanceof CompositeData ||\n                    userData instanceof TabularData)\n                return userData.getClass().getName();\n            \n            return userData.toString();\n        }\n        \n        boolean isInited() {\n            return init;\n        }\n        \n        void init(TableCellRenderer minRenderer, int minHeight) {\n            this.minRenderer = minRenderer;\n            this.minHeight = minHeight;\n            init = true;\n        }\n        \n        void switchState() {\n            minimized = !minimized;\n        }\n        boolean isMaximized() {\n            return !minimized;\n        }\n        void minimize() {\n            minimized = true;\n        }\n        \n        void maximize() {\n            minimized = false;\n        }\n        \n        int getHeight() {\n            if (minimized) return minHeight;\n            else\n                return (int) maxRenderer.getComponent().\n                        getPreferredSize().getHeight();\n        }\n        \n        TableCellRenderer getRenderer() {\n            if (minimized) return minRenderer;\n            else return maxRenderer;\n        }\n    }\n    \n    class NotifMouseListener extends MouseAdapter {\n        \n        @Override\n        public void mousePressed(MouseEvent e) {\n            if (e.getButton() == MouseEvent.BUTTON1) {\n                if (e.getClickCount() >= 2) {\n                    int row = XMBeanNotifications.this.getSelectedRow();\n                    int col = XMBeanNotifications.this.getSelectedColumn();\n                    if (col != 2) return;\n                    if (col == -1 || row == -1) return;\n                    \n                    XMBeanNotifications.this.updateUserDataCell(row, col);\n                }\n            }\n        }\n    }\n    \n    class UserDataCellEditor extends XTextFieldEditor {\n        // implements javax.swing.table.TableCellEditor\n        @Override\n        public Component getTableCellEditorComponent(\n                JTable table,\n                Object value,\n                boolean isSelected,\n                int row,\n                int column) {\n            Object val = value;\n            if (column == 2) {\n                Object obj = getModel().getValueAt(row, column);\n                if (obj instanceof UserDataCell) {\n                    UserDataCell cell = (UserDataCell) obj;\n                    if (cell.getRenderer() instanceof UserDataCellRenderer) {\n                        UserDataCellRenderer zr =\n                                (UserDataCellRenderer) cell.getRenderer();\n                        return zr.getComponent();\n                    }\n                } else {\n                    Component comp = super.getTableCellEditorComponent(\n                            table, val, isSelected, row, column);\n                    textField.setEditable(false);\n                    return comp;\n                }\n            }\n            return super.getTableCellEditorComponent(\n                    table,\n                    val,\n                    isSelected,\n                    row,\n                    column);\n        }\n        @Override\n        public boolean stopCellEditing() {\n            int editingRow = getEditingRow();\n            int editingColumn = getEditingColumn();\n            if (editingColumn == 2) {\n                Object obj = getModel().getValueAt(editingRow, editingColumn);\n                if (obj instanceof UserDataCell) {\n                    UserDataCell cell = (UserDataCell) obj;\n                    if (cell.isMaximized()) {\n                        cancelCellEditing();\n                        return true;\n                    }\n                }\n            }\n            return super.stopCellEditing();\n        }\n    }\n    \n    class XMBeanNotificationsListener implements NotificationListener {\n        \n        private String[] columnNames;\n        private XMBean mbean;\n        private DefaultMutableTreeNode node;\n        private volatile long received;\n        private XMBeanNotifications notifications;\n        private volatile boolean unregistered;\n        private ArrayList<Object[]> data = new ArrayList<Object[]>();\n        \n        public XMBeanNotificationsListener(\n                XMBeanNotifications notifications,\n                XMBean mbean,\n                DefaultMutableTreeNode node,\n                String[] columnNames) {\n            this.notifications = notifications;\n            this.mbean = mbean;\n            this.node = node;\n            this.columnNames = columnNames;\n            register(node);\n        }\n        \n        public synchronized List<Object[]> getData() {\n            return data;\n        }\n        \n        public synchronized void clear() {\n            data.clear();\n            received = 0;\n        }\n        \n        public synchronized boolean isRegistered() {\n            return !unregistered;\n        }\n        \n        public synchronized void unregister() {\n            try {\n                mbean.getMBeanServerConnection().removeNotificationListener(\n                        mbean.getObjectName(), this, null, null);\n            } catch (Exception e) {\n                LOGGER.log(Level.SEVERE, \"Error removing listener\", e); // NOI18N\n            }\n            unregistered = true;\n        }\n        \n        public synchronized long getReceivedNotifications() {\n            return received;\n        }\n        \n        public synchronized void register(DefaultMutableTreeNode node) {\n            clear();\n            this.node = node;\n            try {\n                mbean.getMBeanServerConnection().addNotificationListener(\n                        mbean.getObjectName(), this, null, null);\n                unregistered = false;\n            } catch (Exception e) {\n                LOGGER.log(Level.SEVERE, \"Error adding listener\", e); // NOI18N\n            }\n        }\n        \n        public synchronized void handleNotification(\n                final Notification n, Object hb) {\n            EventQueue.invokeLater(new Runnable() {\n                public void run() {\n                    synchronized (XMBeanNotificationsListener.this) {\n                        try {\n                            if (unregistered) return;\n                            Date receivedDate = new Date(n.getTimeStamp());\n                            String time = timeFormater.format(receivedDate);\n                            \n                            Object userData = n.getUserData();\n                            Component comp = null;\n                            UserDataCell cell = null;\n                            if ((comp = XDataViewer.createNotificationViewer(userData)) != null) {\n                                XDataViewer.registerForMouseEvent(comp, mouseListener);\n                                cell = new UserDataCell(userData, comp);\n                            }\n                            \n                            Object[] rowData = {\n                                time,\n                                n.getType(),\n                                (cell == null ? userData : cell),\n                                n.getSequenceNumber(),\n                                n.getMessage(),\n                                n,\n                                n.getSource()\n                            };\n                            received++;\n                            data.add(0, rowData);\n                            \n                            notifications.fireNotificationReceived(\n                                    XMBeanNotificationsListener.this,\n                                    mbean, node, rowData, received);\n                        } catch (Exception e) {\n                            LOGGER.log(Level.SEVERE, \"Error handling notification\", e); // NOI18N\n                        }\n                    }\n                }\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XMBeanOperations.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport javax.swing.*;\nimport java.awt.BorderLayout;\nimport java.awt.GridLayout;\nimport java.awt.FlowLayout;\nimport java.awt.Component;\nimport java.awt.event.*;\nimport java.rmi.UnmarshalException;\nimport java.util.*;\n\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.*;\n\nclass XMBeanOperations extends JPanel implements ActionListener {\n    private final static Logger LOGGER = Logger.getLogger(XMBeanOperations.class.getName());\n    \n    public final static String OPERATION_INVOCATION_EVENT =\n            \"jam.xoperations.invoke.result\"; // NOI18N\n    private java.util.List<NotificationListener> notificationListenersList;\n    \n    private Hashtable<JButton, OperationEntry> operationEntryTable;\n    \n    private XMBean mbean;\n    private MBeanInfo mbeanInfo;\n    private MBeansTab mbeansTab;\n    \n    public XMBeanOperations(MBeansTab mbeansTab) {\n        super(new GridLayout(1,1));\n        this.mbeansTab = mbeansTab;\n        operationEntryTable = new Hashtable<JButton, OperationEntry>();\n        ArrayList<NotificationListener> l =\n                new ArrayList<NotificationListener>(1);\n        notificationListenersList =\n                Collections.synchronizedList(l);\n    }\n    \n    // Call on EDT\n    public void removeOperations() {\n        removeAll();\n    }\n    \n    // Call on EDT\n    public void loadOperations(XMBean mbean,MBeanInfo mbeanInfo) {\n        this.mbean = mbean;\n        this.mbeanInfo = mbeanInfo;\n        // add operations information\n        MBeanOperationInfo operations[] = mbeanInfo.getOperations();\n        invalidate();\n        \n        // remove listeners, if any\n        Component listeners[] = getComponents();\n        for (int i = 0; i < listeners.length; i++)\n            if (listeners[i] instanceof JButton)\n                ((JButton)listeners[i]).removeActionListener(this);\n        \n        removeAll();\n        setLayout(new BorderLayout());\n        \n        JButton methodButton;\n        JLabel methodLabel;\n        JPanel innerPanelLeft,innerPanelRight;\n        JPanel outerPanelLeft,outerPanelRight;\n        outerPanelLeft  = new JPanel(new GridLayout(operations.length,1));\n        outerPanelRight = new JPanel(new GridLayout(operations.length,1));\n        \n        for (int i=0;i<operations.length;i++) {\n            innerPanelLeft  = new JPanel(new FlowLayout(FlowLayout.RIGHT));\n            innerPanelRight = new JPanel(new FlowLayout(FlowLayout.LEFT));\n            String returnType = operations[i].getReturnType();\n            if (returnType == null) {\n                methodLabel = new JLabel(\"null\", JLabel.RIGHT); // NOI18N\n                if (LOGGER.isLoggable(Level.WARNING)) {\n                    LOGGER.warning(\n                            \"The operation's return type \" + // NOI18N\n                            \"shouldn't be \\\"null\\\". Check how the \" + // NOI18N\n                            \"MBeanOperationInfo for the \\\"\" + // NOI18N\n                            operations[i].getName() + \"\\\" operation has \" + // NOI18N\n                            \"been defined in the MBean's implementation code.\"); // NOI18N\n                }\n            } else {\n                methodLabel = new JLabel(\n                        Utils.getReadableClassName(returnType), JLabel.RIGHT);\n            }\n            innerPanelLeft.add(methodLabel);\n            if (methodLabel.getText().length()>20) {\n                methodLabel.setText(methodLabel.getText().\n                        substring(methodLabel.getText().\n                        lastIndexOf(\".\")+1, // NOI18N\n                        methodLabel.getText().length()));\n            }\n            \n            methodButton = new JButton(operations[i].getName());\n            methodButton.setToolTipText(operations[i].getDescription());\n            boolean callable = isCallable(operations[i].getSignature());\n            if(callable)\n                methodButton.addActionListener(this);\n            else\n                methodButton.setEnabled(false);\n            \n            MBeanParameterInfo[] signature = operations[i].getSignature();\n            OperationEntry paramEntry = new OperationEntry(operations[i],\n                    callable,\n                    methodButton,\n                    this);\n            operationEntryTable.put(methodButton, paramEntry);\n            innerPanelRight.add(methodButton);\n            if(signature.length==0)\n                innerPanelRight.add(new JLabel(\"( )\",JLabel.CENTER)); // NOI18N\n            else\n                innerPanelRight.add(paramEntry);\n            \n            outerPanelLeft.add(innerPanelLeft,BorderLayout.WEST);\n            outerPanelRight.add(innerPanelRight,BorderLayout.CENTER);\n        }\n        add(outerPanelLeft,BorderLayout.WEST);\n        add(outerPanelRight,BorderLayout.CENTER);\n        validate();\n    }\n    \n    private boolean isCallable(MBeanParameterInfo[] signature) {\n        for(int i = 0; i < signature.length; i++) {\n            if(!Utils.isEditableType(signature[i].getType()))\n                return false;\n        }\n        return true;\n    }\n    \n    // Call on EDT\n    public void actionPerformed(final ActionEvent e) {\n        performInvokeRequest((JButton)e.getSource());\n    }\n    \n    void performInvokeRequest(final JButton button) {\n        final OperationEntry entryIf = operationEntryTable.get(button);\n        SwingWorker<Object, Void> sw = new SwingWorker<Object, Void>() {\n            @Override\n            public Object doInBackground() throws Exception {\n                return mbean.invoke(button.getText(),\n                        entryIf.getParameters(), entryIf.getSignature());\n            }\n            @Override\n            protected void done() {\n                try {\n                    Object result = get();\n                    // sends result notification to upper level if\n                    // there is a return value\n                    if (entryIf.getReturnType() != null &&\n                            !entryIf.getReturnType().equals(Void.TYPE.getName()) &&\n                            !entryIf.getReturnType().equals(Void.class.getName()))\n                        fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result);\n                    else\n                        new ThreadDialog(\n                                button,\n                                Resources.getText(\"LBL_MethodSuccessfullyInvoked\"), // NOI18N\n                                Resources.getText(\"LBL_Info\"), // NOI18N\n                                JOptionPane.INFORMATION_MESSAGE).run();\n                } catch (Throwable t) {\n                    t = Utils.getActualException(t);\n                    LOGGER.throwing(XMBeanOperations.class.getName(), \"performInvokeRequest\", t); // NOI18N\n                    t = checkCNFE(t);\n                    \n                    new ThreadDialog(\n                            button,\n                            Resources.getText(\"LBL_ProblemInvoking\") + \" \" + // NOI18N\n                            button.getText() + \" : \" + t.toString(), // NOI18N\n                            Resources.getText(\"LBL_Error\"), // NOI18N\n                            JOptionPane.ERROR_MESSAGE).run();\n                }\n            }\n\n            private Throwable checkCNFE(Throwable t) {\n                if (t instanceof UnmarshalException) {\n                    Throwable nt = t.getCause();\n                    if (nt instanceof ClassNotFoundException) {\n                        return new RuntimeException(\"Cannot instantiate remote class \"+nt.getMessage());  // NOI18N\n                    }\n                }\n                return t;\n            }\n        };\n        mbeansTab.getRequestProcessor().post(sw);\n    }\n    \n    public void addOperationsListener(NotificationListener nl) {\n        notificationListenersList.add(nl);\n    }\n    \n    public void removeOperationsListener(NotificationListener nl) {\n        notificationListenersList.remove(nl);\n    }\n    \n    // Call on EDT\n    private void fireChangedNotification(\n            String type, Object source, Object handback) {\n        Notification n = new Notification(type, source, 0);\n        for(NotificationListener nl : notificationListenersList)\n            nl.handleNotification(n, handback);\n    }\n    \n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XNodeInfo.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\n/**\n * <p>This class represents the user object of the nodes in the MBean tree.</p>\n *\n * <p>It encapsulates the node's info, i.e. the type of the node, the label to\n * be used when displaying the node in the MBean tree, the node's tool tip text\n * and arbitrary data which varies depending on the type of the node: an XMBean\n * reference for MBEAN, ATTRIBUTES, OPERATIONS and NOTIFICATIONS nodes; the\n * corresponding MBeanInfo for ATTRIBUTE, OPERATION and NOTIFICATION nodes;\n * it is not used for NONMBEAN nodes.</p>\n */\nclass XNodeInfo {\n\n    public static enum Type {\n        MBEAN, NONMBEAN,\n        ATTRIBUTES, OPERATIONS, NOTIFICATIONS,\n        ATTRIBUTE, OPERATION, NOTIFICATION\n    };\n\n    public XNodeInfo(Type type, Object data, String label, String tooltip) {\n        this.type = type;\n        this.data = data;\n        this.label = label;\n        this.tooltip = tooltip;\n    }\n\n    public Type getType() {\n        return type;\n    }\n\n    public Object getData() {\n        return data;\n    }\n\n    public String getLabel() {\n        return label;\n    }\n\n    public String getToolTipText() {\n        return tooltip;\n    }\n\n    @Override\n    public String toString() {\n        return label;\n    }\n\n    private Type type;\n    private Object data;\n    private String label;\n    private String tooltip;\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XObject.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\n// java import\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.*;\n\n//\n\n// java import\n\n\n/**\n * This provides a wrapper to the Object class to allow it to be\n displayed/manipulated as a GUI object.\n*/\n@SuppressWarnings(\"serial\")\nclass XObject extends JLabel {\n    private Object object;\n    private static boolean useHashCodeRepresentation = true;\n    private final static Logger LOGGER = Logger.getLogger(XObject.class.getName());\n    \n    public final static XObject NULL_OBJECT = new XObject(\"null\"); // NOI18N\n    \n    public XObject (Object object, Icon icon) {\n        this(object);\n        setIcon(icon);\n    }\n\n    public XObject (Object object) {\n        setObject(object);\n        setHorizontalAlignment(SwingConstants.LEFT);\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        try {\n            if (o instanceof XObject) {\n                return object.equals(((XObject)o).getObject());\n            }\n        }\n        catch (Throwable t) {\n            LOGGER.log(Level.SEVERE, \"Error comparing XObjects\", t); // NOI18N\n        }\n        return false;\n    }\n\n\n    public Object getObject() {\n        return object;\n    }\n\n    //if true the the object.hashcode is added to the label\n    public static void\n        useHashCodeRepresentation(boolean useHashCodeRepresentation) {\n        XObject.useHashCodeRepresentation = useHashCodeRepresentation;\n    }\n\n    public static boolean hashCodeRepresentation() {\n        return useHashCodeRepresentation;\n    }\n\n    public void setObject(Object object) {\n        this.object = object;\n        // if the object is not  a swing component,\n        // use default icon\n        try {\n            String text = null;\n            if (object instanceof JLabel) {\n                setIcon(((JLabel)object).getIcon());\n                if (getText() != null) {\n                    text = ((JLabel)object).getText();\n\n                }\n            }\n            else if (object instanceof JButton) {\n                setIcon(((JButton)object).getIcon());\n                if (getText() != null) {\n                    text = ((JButton)object).getText();\n                }\n            }\n            else if (getText() != null) {\n                text = object.toString();\n                setIcon(IconManager.DEFAULT_XOBJECT);\n            }\n            if (text != null) {\n                if (useHashCodeRepresentation && (this != NULL_OBJECT)) {\n                    text = text + \"     (\"+object.hashCode()+\")\"; // NOI18N\n                }\n                setText(text);\n            }\n        }\n        catch (Exception e) {\n            LOGGER.log(Level.SEVERE, \"Error setting XObject object\", e); // NOI18N\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XOpenTypeViewer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport javax.swing.*;\nimport javax.swing.event.*;\nimport javax.swing.table.*;\nimport java.awt.BorderLayout;\nimport java.awt.FlowLayout;\nimport java.awt.Component;\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.awt.event.*;\nimport java.awt.Dimension;\nimport java.util.*;\nimport java.lang.reflect.Array;\n\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.openmbean.*;\n\nclass XOpenTypeViewer extends JPanel implements ActionListener {\n    private final static Logger LOGGER = Logger.getLogger(XOpenTypeViewer.class.getName());\n    \n    JButton prev, incr, decr, tabularPrev, tabularNext;\n    JLabel compositeLabel, tabularLabel;\n    JScrollPane container;\n    XOpenTypeData current;\n    XOpenTypeDataListener listener = new XOpenTypeDataListener();\n\n    private static final String compositeNavigationSingle =\n            Resources.getText(\"LBL_MBeansTab.compositeNavigationSingle\"); // NOI18N\n    private static final String tabularNavigationSingle =\n            Resources.getText(\"LBL_MBeansTab.tabularNavigationSingle\"); // NOI18N\n\n    private static TableCellEditor editor =\n            new Utils.ReadOnlyTableCellEditor(new JTextField());\n\n    class XOpenTypeDataListener extends MouseAdapter {\n        XOpenTypeDataListener() {\n        }\n\n        @Override\n        public void mousePressed(MouseEvent e) {\n            if(e.getButton() == MouseEvent.BUTTON1) {\n                if(e.getClickCount() >= 2) {\n                    XOpenTypeData elem = getSelectedViewedOpenType();\n                    if(elem != null) {\n                        try {\n                            elem.viewed(XOpenTypeViewer.this);\n                        }catch(Exception ex) {\n                            //Nothing to change, the element\n                            //can't be displayed\n                        }\n                    }\n                }\n            }\n        }\n\n        private XOpenTypeData getSelectedViewedOpenType() {\n            int row = XOpenTypeViewer.this.current.getSelectedRow();\n            int col = XOpenTypeViewer.this.current.getSelectedColumn();\n            Object elem =\n                    XOpenTypeViewer.this.current.getModel().getValueAt(row, col);\n            if(elem instanceof XOpenTypeData)\n                return (XOpenTypeData) elem;\n            else\n                return null;\n        }\n    }\n\n    static interface Navigatable {\n        public void incrElement();\n        public void decrElement();\n        public boolean canDecrement();\n        public boolean canIncrement();\n        public int getElementCount();\n        public int getSelectedElementIndex();\n    }\n\n    static interface XViewedTabularData extends Navigatable {\n    }\n\n    static interface XViewedArrayData extends Navigatable {\n    }\n\n    static abstract class XOpenTypeData extends JTable {\n        XOpenTypeData parent;\n        private Color defaultColor;\n        protected int col1Width = -1;\n        protected int col2Width = -1;\n        private boolean init;\n        private Font normalFont, boldFont;\n        protected XOpenTypeData(XOpenTypeData parent) {\n            this.parent = parent;\n        }\n\n        public XOpenTypeData getViewedParent() {\n            return parent;\n        }\n\n        public String getToolTip(int row, int col) {\n            if(col == XTable.VALUE_COLUMN) {\n                Object value = getModel().getValueAt(row, col);\n                if (value != null) {\n                    if(isClickableElement(value))\n                        return Resources.getText(\"LBL_DoubleClickToVisualize\") // NOI18N\n                        + \". \" + value.toString(); // NOI18N\n                    else\n                        return value.toString();\n                }\n            }\n            return null;\n        }\n\n        @Override\n        public TableCellRenderer getCellRenderer(int row, int column) {\n            DefaultTableCellRenderer tcr =\n                    (DefaultTableCellRenderer)super.getCellRenderer(row,column);\n            tcr.setToolTipText(getToolTip(row,column));\n            return tcr;\n        }\n\n        public void renderKey(String key,  Component comp) {\n            comp.setFont(normalFont);\n        }\n\n        @Override\n        public Component prepareRenderer(TableCellRenderer renderer,\n                int row, int column) {\n            Component comp = super.prepareRenderer(renderer, row, column);\n\n            if (normalFont == null) {\n                normalFont = comp.getFont();\n                boldFont = normalFont.deriveFont(Font.BOLD);\n            }\n\n            Object o = ((DefaultTableModel) getModel()).getValueAt(row, column);\n            if (column == 0) {\n                String key = o.toString();\n                renderKey(key, comp);\n            } else {\n                if (isClickableElement(o)) {\n                    comp.setFont(boldFont);\n                } else {\n                    comp.setFont(normalFont);\n                }\n            }\n\n            return comp;\n        }\n\n        protected boolean isClickableElement(Object obj) {\n            if (obj instanceof XOpenTypeData) {\n                if (obj instanceof Navigatable) {\n                    return (((Navigatable) obj).getElementCount() != 0);\n                } else {\n                    return (obj instanceof XCompositeData);\n                }\n            }\n            return false;\n        }\n\n        protected void updateColumnWidth() {\n            if (!init) {\n                TableColumnModel colModel = getColumnModel();\n                if (col2Width == -1) {\n                    col1Width = col1Width * 7;\n                    if (col1Width <\n                            getPreferredScrollableViewportSize().getWidth()) {\n                        col1Width = (int)\n                        getPreferredScrollableViewportSize().getWidth();\n                    }\n                    colModel.getColumn(0).setPreferredWidth(col1Width);\n                    init = true;\n                    return;\n                }\n                col1Width = (col1Width * 7) + 7;\n                col1Width = Math.max(col1Width, 70);\n                col2Width = (col2Width * 7) + 7;\n                if (col1Width + col2Width <\n                        getPreferredScrollableViewportSize().getWidth()) {\n                    col2Width = (int)\n                    getPreferredScrollableViewportSize().getWidth() -\n                            col1Width;\n                }\n                colModel.getColumn(0).setPreferredWidth(col1Width);\n                colModel.getColumn(1).setPreferredWidth(col2Width);\n                init = true;\n            }\n        }\n\n        public abstract void viewed(XOpenTypeViewer viewer) throws Exception;\n\n        protected void initTable(String[] columnNames) {\n            setRowSelectionAllowed(false);\n            setColumnSelectionAllowed(false);\n            getTableHeader().setReorderingAllowed(false);\n            ((DefaultTableModel) getModel()).setColumnIdentifiers(columnNames);\n            for (Enumeration<TableColumn> e = getColumnModel().getColumns();\n            e.hasMoreElements();) {\n                TableColumn tc = e.nextElement();\n                tc.setCellEditor(editor);\n            }\n            addKeyListener(new Utils.CopyKeyAdapter());\n            setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);\n            setPreferredScrollableViewportSize(new Dimension(350, 200));\n        }\n\n        protected void emptyTable() {\n            invalidate();\n            while (getModel().getRowCount()>0)\n                ((DefaultTableModel) getModel()).removeRow(0);\n            validate();\n        }\n\n        @Override\n        public void setValueAt(Object value, int row, int col) {\n        }\n    }\n\n    static class TabularDataComparator implements Comparator<CompositeData> {\n\n        private final List<String> indexNames;\n\n        public TabularDataComparator(TabularType type) {\n            indexNames = type.getIndexNames();\n        }\n\n        @SuppressWarnings(\"unchecked\")\n        public int compare(CompositeData o1, CompositeData o2) {\n            for (String key : indexNames) {\n                Object c1 = o1.get(key);\n                Object c2 = o2.get(key);\n                if (c1 instanceof Comparable && c2 instanceof Comparable) {\n                    int result = ((Comparable) c1).compareTo(c2);\n                    if (result != 0)\n                        return result;\n                }\n            }\n            return 0;\n        }\n    }\n\n    static class XTabularData extends XCompositeData\n            implements XViewedTabularData {\n\n        final TabularData tabular;\n        final TabularType type;\n        int currentIndex = 0;\n        final Object[] elements;\n        final int size;\n        private Font normalFont, italicFont;\n\n        @SuppressWarnings(\"unchecked\")\n        public XTabularData(XOpenTypeData parent, TabularData tabular) {\n            super(parent, accessFirstElement(tabular));\n            this.tabular = tabular;\n            type = tabular.getTabularType();\n            size = tabular.values().size();\n            if (size > 0) {\n                // Order tabular data elements using index names\n                List<CompositeData> data = new ArrayList<CompositeData>(\n                        (Collection<CompositeData>) tabular.values());\n                Collections.sort(data, new TabularDataComparator(type));\n                elements = data.toArray();\n                loadCompositeData((CompositeData) elements[0]);\n            } else {\n                elements = new Object[0];\n            }\n        }\n\n        private static CompositeData accessFirstElement(TabularData tabular) {\n            if(tabular.values().size() == 0) return null;\n            return (CompositeData) tabular.values().toArray()[0];\n        }\n\n        @Override\n        public void renderKey(String key,  Component comp) {\n            if (normalFont == null) {\n                normalFont = comp.getFont();\n                italicFont = normalFont.deriveFont(Font.ITALIC);\n            }\n            for(Object k : type.getIndexNames()) {\n                if(key.equals(k))\n                    comp.setFont(italicFont);\n            }\n        }\n\n        public int getElementCount() {\n            return size;\n        }\n\n        public int getSelectedElementIndex() {\n            return currentIndex;\n        }\n\n        public void incrElement() {\n            currentIndex++;\n            loadCompositeData((CompositeData)elements[currentIndex]);\n        }\n\n        public void decrElement() {\n            currentIndex--;\n            loadCompositeData((CompositeData)elements[currentIndex]);\n        }\n\n        public boolean canDecrement() {\n            if(currentIndex == 0)\n                return false;\n            else\n                return true;\n        }\n\n        public boolean canIncrement(){\n            if(size == 0 ||\n                    currentIndex == size -1)\n                return false;\n            else\n                return true;\n        }\n\n        @Override\n        public String toString() {\n            return type == null ? \"\" : type.getDescription(); // NOI18N\n        }\n    }\n\n    static class XCompositeData extends XOpenTypeData {\n        protected final String[] columnNames = {\n            Resources.getText(\"LBL_Name\"), Resources.getText(\"LBL_Value\") // NOI18N\n        };\n        CompositeData composite;\n\n        public XCompositeData() {\n            super(null);\n            initTable(columnNames);\n        }\n\n        //In sync with array, no init table.\n        public XCompositeData(XOpenTypeData parent) {\n            super(parent);\n        }\n\n        public XCompositeData(XOpenTypeData parent,\n                CompositeData composite) {\n            super(parent);\n            initTable(columnNames);\n            if(composite != null) {\n                this.composite = composite;\n                loadCompositeData(composite);\n            }\n        }\n\n        public void viewed(XOpenTypeViewer viewer) throws Exception {\n            viewer.setOpenType(this);\n            updateColumnWidth();\n        }\n\n        @Override\n        public String toString() {\n            return composite == null ? \"\" : // NOI18N\n                composite.getCompositeType().getTypeName();\n        }\n\n        protected Object formatKey(String key) {\n            return key;\n        }\n\n        public String getToolTip(int row, int col) {\n            if (col == XTable.NAME_COLUMN && composite != null) {\n                String val = getModel().getValueAt(row,col).toString();\n                \n                return composite.getCompositeType().getDescription(val);\n            }\n            return super.getToolTip(row, col);\n        }\n\n        private void load(CompositeData data) {\n            CompositeType type = data.getCompositeType();\n            Set keys = type.keySet();\n            Iterator it = keys.iterator();\n            Object[] rowData = new Object[2];\n            while (it.hasNext()) {\n                String key = (String) it.next();\n                Object val = data.get(key);\n                rowData[0] = formatKey(key);\n                if (val == null) {\n                    rowData[1] = \"\"; // NOI18N\n                } else {\n                    OpenType openType = type.getType(key);\n                    if (openType instanceof CompositeType) {\n                        rowData[1] =\n                                new XCompositeData(this, (CompositeData) val);\n                    } else if (openType instanceof ArrayType) {\n                        rowData[1] =\n                                new XArrayData(this, (ArrayType) openType, val);\n                    } else if (openType instanceof SimpleType) {\n                        rowData[1] = val;\n                    } else if (openType instanceof TabularType) {\n                        rowData[1] = new XTabularData(this, (TabularData) val);\n                    }\n                }\n                // Update column width\n                String str = null;\n                if (rowData[0] != null) {\n                    str = rowData[0].toString();\n                    if (str.length() > col1Width) {\n                        col1Width = str.length();\n                    }\n                }\n                if (rowData[1] != null) {\n                    str = rowData[1].toString();\n                    if (str.length() > col2Width) {\n                        col2Width = str.length();\n                    }\n                }\n                ((DefaultTableModel) getModel()).addRow(rowData);\n            }\n        }\n\n        protected void loadCompositeData(CompositeData data) {\n            composite = data;\n            emptyTable();\n            load(data);\n            DefaultTableModel tableModel = (DefaultTableModel) getModel();\n            tableModel.newDataAvailable(new TableModelEvent(tableModel));\n        }\n    }\n\n    static class XArrayData extends XCompositeData\n            implements XViewedArrayData {\n\n        private int dimension;\n        private int size;\n        private OpenType elemType;\n        private Object val;\n        private boolean isCompositeType;\n        private boolean isTabularType;\n        private int currentIndex;\n        private CompositeData[] elements;\n        private final String[] arrayColumns = {Resources.getText(\"LBL_Value\")}; // NOI18N\n        private Font normalFont, boldFont;\n\n        XArrayData(XOpenTypeData parent, ArrayType type, Object val) {\n            this(parent, type.getDimension(), type.getElementOpenType(), val);\n        }\n\n        XArrayData(XOpenTypeData parent, int dimension,\n                OpenType elemType, Object val) {\n            super(parent);\n            this.dimension = dimension;\n            this.elemType = elemType;\n            this.val = val;\n            String[] columns = null;\n\n            if (dimension > 1) return;\n\n            isCompositeType = (elemType instanceof CompositeType);\n            isTabularType = (elemType instanceof TabularType);\n            columns = isCompositeType ? columnNames : arrayColumns;\n\n            initTable(columns);\n            loadArray();\n        }\n\n        @Override\n        public void viewed(XOpenTypeViewer viewer) throws Exception {\n            if (size == 0)\n                throw new Exception(Resources.getText(\"LBL_EmptyArray\")); // NOI18N\n            if (dimension > 1)\n                throw new Exception(Resources.getText(\"LBL_DimensionIsNotSupported\") // NOI18N\n                        + \": \" + dimension); // NOI18N\n            super.viewed(viewer);\n        }\n\n        public int getElementCount() {\n            return size;\n        }\n\n        public int getSelectedElementIndex() {\n            return currentIndex;\n        }\n\n        @Override\n        public void renderKey(String key,  Component comp) {\n            if (normalFont == null) {\n                normalFont = comp.getFont();\n                boldFont = normalFont.deriveFont(Font.BOLD);\n            }\n            if (isTabularType) {\n                comp.setFont(boldFont);\n            }\n        }\n\n        public void incrElement() {\n            currentIndex++;\n            loadCompositeData(elements[currentIndex]);\n        }\n\n        public void decrElement() {\n            currentIndex--;\n            loadCompositeData(elements[currentIndex]);\n        }\n\n        public boolean canDecrement() {\n            if (isCompositeType && currentIndex > 0) {\n                return true;\n            }\n            return false;\n        }\n\n        public boolean canIncrement() {\n            if (isCompositeType && currentIndex < size - 1) {\n                return true;\n            }\n            return false;\n        }\n\n        private void loadArray() {\n            if (isCompositeType) {\n                elements = (CompositeData[]) val;\n                size = elements.length;\n                if (size != 0) {\n                    loadCompositeData(elements[0]);\n                }\n            } else {\n                load();\n            }\n        }\n\n        private void load() {\n            Object[] rowData = new Object[1];\n            size = Array.getLength(val);\n            for (int i = 0; i < size; i++) {\n                rowData[0] = isTabularType ?\n                    new XTabularData(this, (TabularData) Array.get(val, i)) :\n                    Array.get(val, i);\n                String str = rowData[0].toString();\n                if (str.length() > col1Width) {\n                    col1Width = str.length();\n                }\n                ((DefaultTableModel) getModel()).addRow(rowData);\n            }\n        }\n\n        @Override\n        public String toString() {\n            if (dimension > 1) {\n                return Resources.getText(\"LBL_DimensionIsNotSupported\") + // NOI18N\n                        \": \" + dimension; // NOI18N\n            } else {\n                return elemType.getTypeName() + \"[\" + size + \"]\"; // NOI18N\n            }\n        }\n    }\n\n    /**\n     * The supplied value is viewable iff:\n     * - it's a CompositeData/TabularData, or\n     * - it's a non-empty array of CompositeData/TabularData, or\n     * - it's a non-empty Collection of CompositeData/TabularData.\n     */\n    public static boolean isViewableValue(Object value) {\n        // Check for CompositeData/TabularData\n        //\n        if (value instanceof CompositeData || value instanceof TabularData) {\n            return true;\n        }\n        // Check for non-empty array of CompositeData/TabularData\n        //\n        if (value instanceof CompositeData[] || value instanceof TabularData[]) {\n            return Array.getLength(value) > 0;\n        }\n        // Check for non-empty Collection of CompositeData/TabularData\n        //\n        if (value instanceof Collection) {\n            Collection<?> c = (Collection<?>) value;\n            if (c.isEmpty()) {\n                // Empty Collections are not viewable\n                //\n                return false;\n            } else {\n                // Only Collections of CompositeData/TabularData are viewable\n                //\n                return Utils.isUniformCollection(c, CompositeData.class) ||\n                        Utils.isUniformCollection(c, TabularData.class);\n            }\n        }\n        return false;\n    }\n\n    public static Component loadOpenType(Object value) {\n        Component comp = null;\n        if(isViewableValue(value)) {\n            XOpenTypeViewer open =\n                    new XOpenTypeViewer(value);\n            comp = open;\n        }\n        return comp;\n    }\n\n    private XOpenTypeViewer(Object value) {\n        XOpenTypeData comp = null;\n        if (value instanceof CompositeData) {\n            comp = new XCompositeData(null, (CompositeData) value);\n        } else if (value instanceof TabularData) {\n            comp = new XTabularData(null, (TabularData) value);\n        } else if (value instanceof CompositeData[]) {\n            CompositeData cda[] = (CompositeData[]) value;\n            CompositeType ct = cda[0].getCompositeType();\n            comp = new XArrayData(null, 1, ct, cda);\n        } else if (value instanceof TabularData[]) {\n            TabularData tda[] = (TabularData[]) value;\n            TabularType tt = tda[0].getTabularType();\n            comp = new XArrayData(null, 1, tt, tda);\n        } else if (value instanceof Collection) {\n            // At this point we know 'value' is a uniform collection, either\n            // Collection<CompositeData> or Collection<TabularData>, because\n            // isViewableValue() has been called before calling the private\n            // XOpenTypeViewer() constructor.\n            //\n            Object e = ((Collection<?>) value).iterator().next();\n            if (e instanceof CompositeData) {\n                Collection<?> cdc = (Collection<?>) value;\n                CompositeData cda[] = cdc.toArray(new CompositeData[0]);\n                CompositeType ct = cda[0].getCompositeType();\n                comp = new XArrayData(null, 1, ct, cda);\n            } else if (e instanceof TabularData) {\n                Collection<?> tdc = (Collection<?>) value;\n                TabularData tda[] = tdc.toArray(new TabularData[0]);\n                TabularType tt = tda[0].getTabularType();\n                comp = new XArrayData(null, 1, tt, tda);\n            }\n        }\n        setupDisplay(comp);\n        try {\n            comp.viewed(this);\n        } catch (Exception e) {\n            // Nothing to change, the element can't be displayed\n            LOGGER.log(Level.SEVERE, \"Exception viewing openType\", e); // NOI18N\n        }\n    }\n\n    void setOpenType(XOpenTypeData data) {\n        if (current != null) {\n            current.removeMouseListener(listener);\n        }\n\n        current = data;\n\n        // Enable/Disable the previous (<<) button\n        if (current.getViewedParent() == null) {\n            prev.setEnabled(false);\n        } else {\n            prev.setEnabled(true);\n        }\n\n        // Set the listener to handle double-click mouse events\n        current.addMouseListener(listener);\n\n        // Enable/Disable the tabular buttons\n        if (!(data instanceof XViewedTabularData)) {\n            tabularPrev.setEnabled(false);\n            tabularNext.setEnabled(false);\n            tabularLabel.setText(tabularNavigationSingle);\n            tabularLabel.setEnabled(false);\n        } else {\n            XViewedTabularData tabular = (XViewedTabularData) data;\n            tabularNext.setEnabled(tabular.canIncrement());\n            tabularPrev.setEnabled(tabular.canDecrement());\n            boolean hasMoreThanOneElement =\n                    tabular.canIncrement() || tabular.canDecrement();\n            if (hasMoreThanOneElement) {\n                tabularLabel.setText(\n                        Resources.getText(\"LBL_MBeansTab.tabularNavigationMultiple\", // NOI18N\n                        String.format(\"%d\", tabular.getSelectedElementIndex() + 1), // NOI18N\n                        String.format(\"%d\", tabular.getElementCount()))); // NOI18N\n            } else {\n                tabularLabel.setText(tabularNavigationSingle);\n            }\n            tabularLabel.setEnabled(hasMoreThanOneElement);\n        }\n\n        // Enable/Disable the composite buttons\n        if (!(data instanceof XViewedArrayData)) {\n            incr.setEnabled(false);\n            decr.setEnabled(false);\n            compositeLabel.setText(compositeNavigationSingle);\n            compositeLabel.setEnabled(false);\n        } else {\n            XViewedArrayData array = (XViewedArrayData) data;\n            incr.setEnabled(array.canIncrement());\n            decr.setEnabled(array.canDecrement());\n            boolean hasMoreThanOneElement =\n                    array.canIncrement() || array.canDecrement();\n            if (hasMoreThanOneElement) {\n                compositeLabel.setText(\n                        Resources.getText(\"LBL_MBeansTab.compositeNavigationMultiple\", // NOI18N\n                        String.format(\"%d\", array.getSelectedElementIndex() + 1), // NOI18N\n                        String.format(\"%d\", array.getElementCount()))); // NOI18N\n            } else {\n                compositeLabel.setText(compositeNavigationSingle);\n            }\n            compositeLabel.setEnabled(hasMoreThanOneElement);\n        }\n\n        container.invalidate();\n        container.setViewportView(current);\n        container.validate();\n    }\n\n    public void actionPerformed(ActionEvent event) {\n        if (event.getSource() instanceof JButton) {\n            JButton b = (JButton) event.getSource();\n            if (b == prev) {\n                XOpenTypeData parent = current.getViewedParent();\n                try {\n                    parent.viewed(this);\n                } catch (Exception e) {\n                    //Nothing to change, the element can't be displayed\n                }\n            } else if (b == incr) {\n                ((XViewedArrayData) current).incrElement();\n                try {\n                    current.viewed(this);\n                } catch (Exception e) {\n                    //Nothing to change, the element can't be displayed\n                }\n            } else if (b == decr) {\n                ((XViewedArrayData) current).decrElement();\n                try {\n                    current.viewed(this);\n                } catch (Exception e) {\n                    //Nothing to change, the element can't be displayed\n                }\n            } else if (b == tabularNext) {\n                ((XViewedTabularData) current).incrElement();\n                try {\n                    current.viewed(this);\n                } catch (Exception e) {\n                    //Nothing to change, the element can't be displayed\n                }\n            } else if (b == tabularPrev) {\n                ((XViewedTabularData) current).decrElement();\n                try {\n                    current.viewed(this);\n                } catch (Exception e) {\n                    //Nothing to change, the element can't be displayed\n                }\n            }\n        }\n    }\n\n    private void setupDisplay(XOpenTypeData data) {\n        setBackground(Color.white);\n        container =\n                new JScrollPane(data,\n                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n\n        JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEFT));\n        tabularPrev = new JButton(Resources.getText(\"LBL_<\")); // NOI18N\n        tabularNext = new JButton(Resources.getText(\"LBL_>\")); // NOI18N\n        JPanel tabularButtons = new JPanel(new FlowLayout(FlowLayout.LEFT));\n        tabularButtons.add(tabularPrev);\n        tabularPrev.addActionListener(this);\n        tabularLabel = new JLabel(tabularNavigationSingle);\n        tabularLabel.setEnabled(false);\n        tabularButtons.add(tabularLabel);\n        tabularButtons.add(tabularNext);\n        tabularNext.addActionListener(this);\n        tabularButtons.setBackground(Color.white);\n\n        prev = new JButton(Resources.getText(\"LBL_<<\")); // NOI18N\n        prev.addActionListener(this);\n        buttons.add(prev);\n\n        incr = new JButton(Resources.getText(\"LBL_>\")); // NOI18N\n        incr.addActionListener(this);\n        decr = new JButton(Resources.getText(\"LBL_<\")); // NOI18N\n        decr.addActionListener(this);\n\n        JPanel array = new JPanel();\n        array.setBackground(Color.white);\n        array.add(decr);\n        compositeLabel = new JLabel(compositeNavigationSingle);\n        compositeLabel.setEnabled(false);\n        array.add(compositeLabel);\n        array.add(incr);\n\n        buttons.add(array);\n        setLayout(new BorderLayout());\n        buttons.setBackground(Color.white);\n\n        JPanel navigationPanel = new JPanel(new BorderLayout());\n        navigationPanel.setBackground(Color.white);\n        navigationPanel.add(tabularButtons, BorderLayout.NORTH);\n        navigationPanel.add(buttons, BorderLayout.WEST);\n        add(navigationPanel, BorderLayout.NORTH);\n\n        add(container, BorderLayout.CENTER);\n        Dimension d = new Dimension((int)container.getPreferredSize().\n                getWidth() + 20,\n                (int)container.getPreferredSize().\n                getHeight() + 20);\n        setPreferredSize(d);\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XPlotter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport javax.swing.JTable;\n\n@SuppressWarnings(\"serial\")\nclass XPlotter extends Plotter {\n    JTable table;\n    public XPlotter(JTable table,\n                    Plotter.Unit unit) {\n        super(unit,0,false);\n        this.table = table;\n    }\n    @Override\n    public void addValues(long time, long... values) {\n        super.addValues(time, values);\n        table.repaint();\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XPlottingViewer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.logging.Logger;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTable;\nimport javax.swing.Timer;\n\n@SuppressWarnings(\"serial\")\nclass XPlottingViewer extends PlotterPanel implements ActionListener {\n\n    private final static Logger LOGGER =\n            Logger.getLogger(XPlottingViewer.class.getName());\n\n    // TODO: Make number of decimal places customizable\n    private static final int PLOTTER_DECIMALS = 4;\n\n    private JButton plotButton;\n    // The plotter cache holds Plotter instances for the various attributes\n    private static HashMap<String, XPlottingViewer> plotterCache =\n            new HashMap<String, XPlottingViewer>();\n    private static HashMap<String, Timer> timerCache =\n            new HashMap<String, Timer>();\n    private MBeansTab tab;\n    private XMBean mbean;\n    private String attributeName;\n    private String key;\n    private JTable table;\n\n    private XPlottingViewer(String key,\n                            XMBean mbean,\n                            String attributeName,\n                            Object value,\n                            JTable table,\n                            MBeansTab tab) {\n        super(null);\n        this.tab = tab;\n        this.key = key;\n        this.mbean = mbean;\n        this.table = table;\n        this.attributeName = attributeName;\n        setupDisplay(createPlotter(mbean, attributeName, key, table));\n    }\n\n    static void dispose(MBeansTab tab) {\n        Iterator it = plotterCache.keySet().iterator();\n        while(it.hasNext()) {\n            String key = (String) it.next();\n            if(key.startsWith(String.valueOf(tab.hashCode()))) {\n                it.remove();\n            }\n        }\n        //plotterCache.clear();\n        it = timerCache.keySet().iterator();\n        while(it.hasNext()) {\n            String key = (String) it.next();\n            if(key.startsWith(String.valueOf(tab.hashCode()))) {\n                Timer t = timerCache.get(key);\n                t.stop();\n                it.remove();\n            }\n        }\n    }\n\n    public static boolean isViewableValue(Object value) {\n        return (value instanceof Number);\n    }\n\n    // Fired by dbl click\n    public static Component loadPlotting(\n            XMBean mbean, String attributeName, Object value, JTable table,\n            MBeansTab tab) {\n        Component comp = null;\n        if (isViewableValue(value)) {\n            String key = String.valueOf(tab.hashCode()) + \" \" + // NOI18N\n                    String.valueOf(mbean.hashCode()) + \" \" + // NOI18N\n                    mbean.getObjectName().getCanonicalName() + attributeName;\n            XPlottingViewer p = plotterCache.get(key);\n            if (p == null) {\n                p = new XPlottingViewer(key, mbean, attributeName, value,\n                        table, tab);\n                plotterCache.put(key, p);\n            }\n            comp = p;\n        }\n        return comp;\n    }\n\n    @Override\n    public void actionPerformed(ActionEvent evt) {\n        plotterCache.remove(key);\n        Timer t = timerCache.remove(key);\n        t.stop();\n        ((XMBeanAttributes) table).collapse(attributeName, this);\n    }\n\n    // Create plotter instance\n    public Plotter createPlotter(final XMBean xmbean,\n                                 final String attributeName,\n                                 String key,\n                                 JTable table) {\n        final Plotter p = new XPlotter(table, Plotter.Unit.NONE) {\n            Dimension prefSize = new Dimension(400, 170);\n            @Override\n            public Dimension getPreferredSize() {\n                return prefSize;\n            }\n            @Override\n            public Dimension getMinimumSize() {\n                return prefSize;\n            }\n        };\n\n        p.createSequence(attributeName, attributeName, null, true);\n\n        Timer timer = new Timer(tab.getUpdateInterval(), new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                intervalElapsed(p);\n            }\n        });\n        timer.setCoalesce(true);\n        timer.setInitialDelay(0);\n        timer.start();\n        timerCache.put(key, timer);\n        return p;\n    }\n\n    void intervalElapsed(final Plotter p) {\n        tab.getRequestProcessor().post(new Runnable() {\n            public void run() {\n                try {\n                    Number n = (Number) mbean.getCachedMBeanServerConnection().\n                            getAttribute(\n                            mbean.getObjectName(), attributeName);\n                    long v;\n                    if (n instanceof Float || n instanceof Double) {\n                        p.setDecimals(PLOTTER_DECIMALS);\n                        double d = (n instanceof Float) ? (Float) n : (Double) n;\n                        v = Math.round(d * Math.pow(10.0, PLOTTER_DECIMALS));\n                    } else {\n                        v = n.longValue();\n                    }\n                    p.addValues(System.currentTimeMillis(), v);\n                } catch (Exception e) {\n                    LOGGER.throwing(XPlottingViewer.class.getName(),\n                            \"intervalElapsed\", e); // NOI18N\n                }\n            }\n        });\n    }\n\n    // Create Plotter display\n    private void setupDisplay(Plotter p) {\n        final JPanel buttonPanel = new JPanel();\n        final GridBagLayout gbl = new GridBagLayout();\n        buttonPanel.setLayout(gbl);\n        setLayout(new BorderLayout());\n        plotButton = new JButton(Resources.getText(\"LBL_DiscardChart\")); // NOI18N\n        plotButton.addActionListener(this);\n        plotButton.setEnabled(true);\n\n        GridBagConstraints buttonConstraints = new GridBagConstraints();\n        buttonConstraints.gridx = 0;\n        buttonConstraints.gridy = 0;\n        buttonConstraints.fill = GridBagConstraints.VERTICAL;\n        buttonConstraints.anchor = GridBagConstraints.CENTER;\n        gbl.setConstraints(plotButton, buttonConstraints);\n        buttonPanel.add(plotButton);\n\n        if (attributeName != null && attributeName.length()!=0) {\n            final JPanel plotterLabelPanel = new JPanel();\n            final JLabel atlabel = new JLabel(attributeName);\n            final GridBagLayout gbl2 = new GridBagLayout();\n            plotterLabelPanel.setLayout(gbl2);\n            final GridBagConstraints labelConstraints = new GridBagConstraints();\n            labelConstraints.gridx = 0;\n            labelConstraints.gridy = 0;\n            labelConstraints.fill = GridBagConstraints.VERTICAL;\n            labelConstraints.anchor = GridBagConstraints.CENTER;\n            labelConstraints.ipady = 10;\n            gbl2.setConstraints(atlabel, labelConstraints);\n            plotterLabelPanel.add(atlabel);\n            add(plotterLabelPanel, BorderLayout.NORTH);\n        }\n\n        setPlotter(p);\n        add(buttonPanel, BorderLayout.SOUTH);\n        repaint();\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XSheet.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.io.*;\nimport javax.management.*;\nimport javax.swing.*;\nimport javax.swing.tree.*;\nimport org.graalvm.visualvm.modules.mbeans.XNodeInfo.Type;\n\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport static org.graalvm.visualvm.modules.mbeans.Resources.*;\n\n@SuppressWarnings(\"serial\")\nclass XSheet extends JPanel\n        implements ActionListener, NotificationListener {\n    private final static Logger LOGGER = Logger.getLogger(XSheet.class.getName());\n\n    private JPanel topPanelAttributes;\n    private JPanel topPanelOperations;\n    private JPanel topPanelNotifications;\n    private JPanel topPanelMetadata;\n\n    // Node being currently displayed\n    private volatile DefaultMutableTreeNode currentNode;\n\n    // MBean being currently displayed\n    private volatile XMBean mbean;\n\n    // XMBeanAttributes container\n    private XMBeanAttributes mbeanAttributes;\n\n    // XMBeanOperations container\n    private XMBeanOperations mbeanOperations;\n\n    // XMBeanNotifications container\n    private XMBeanNotifications mbeanNotifications;\n\n    // XMBeanInfo container\n    private XMBeanInfo mbeanInfo;\n\n    // Refresh JButton (mbean attributes case)\n    private JButton refreshButton;\n\n    // Subscribe/Unsubscribe/Clear JButton (mbean notifications case)\n    private JButton clearButton, subscribeButton, unsubscribeButton;\n\n    // Reference to MBeans tab\n    private MBeansTab mbeansTab;\n\n    public XSheet(MBeansTab mbeansTab) {\n        this.mbeansTab = mbeansTab;\n        setupScreen();\n    }\n\n    public JPanel getAttributes() {\n        return topPanelAttributes;\n    }\n\n    public JPanel getOperations() {\n        return topPanelOperations;\n    }\n\n    public JPanel getNotifications() {\n        return topPanelNotifications;\n    }\n\n    public JPanel getMetadata() {\n        return topPanelMetadata;\n    }\n\n    public void dispose() {\n        clearNotifications();\n        clear();\n        XDataViewer.dispose(mbeansTab);\n        mbeanNotifications.dispose();\n        displayEmptyNode();\n    }\n\n    private void setupScreen() {\n        setLayout(new BorderLayout());\n        setBorder(BorderFactory.createLineBorder(Color.GRAY));\n        // create attributes panel\n        topPanelAttributes = new JPanel();\n        topPanelAttributes.setLayout(new BorderLayout());\n        // create operations panel\n        topPanelOperations = new JPanel();\n        topPanelOperations.setLayout(new BorderLayout());\n        // create notifications panel\n        topPanelNotifications = new JPanel();\n        topPanelNotifications.setLayout(new BorderLayout());\n        // create metadata panel\n        topPanelMetadata = new JPanel();\n        topPanelMetadata.setLayout(new BorderLayout());\n        // create the refresh button\n        String refreshButtonKey = \"LBL_MBeansTab.refreshAttributesButton\"; // NOI18N\n        refreshButton = new JButton(getText(refreshButtonKey));\n        refreshButton.setMnemonic(getMnemonicInt(refreshButtonKey));\n        refreshButton.setToolTipText(getText(refreshButtonKey + \".toolTip\")); // NOI18N\n        refreshButton.addActionListener(this);\n        // create the clear button\n        String clearButtonKey = \"LBL_MBeansTab.clearNotificationsButton\"; // NOI18N\n        clearButton = new JButton(getText(clearButtonKey));\n        clearButton.setMnemonic(getMnemonicInt(clearButtonKey));\n        clearButton.setToolTipText(getText(clearButtonKey + \".toolTip\")); // NOI18N\n        clearButton.addActionListener(this);\n        // create the subscribe button\n        String subscribeButtonKey = \"LBL_MBeansTab.subscribeNotificationsButton\"; // NOI18N\n        subscribeButton = new JButton(getText(subscribeButtonKey));\n        subscribeButton.setMnemonic(getMnemonicInt(subscribeButtonKey));\n        subscribeButton.setToolTipText(getText(subscribeButtonKey + \".toolTip\")); // NOI18N\n        subscribeButton.addActionListener(this);\n        // create the unsubscribe button\n        String unsubscribeButtonKey = \"LBL_MBeansTab.unsubscribeNotificationsButton\"; // NOI18N\n        unsubscribeButton = new JButton(getText(unsubscribeButtonKey));\n        unsubscribeButton.setMnemonic(getMnemonicInt(unsubscribeButtonKey));\n        unsubscribeButton.setToolTipText(getText(unsubscribeButtonKey + \".toolTip\")); // NOI18N\n        unsubscribeButton.addActionListener(this);\n        // create XMBeanAttributes container\n        mbeanAttributes = new XMBeanAttributes(mbeansTab);\n        // create XMBeanOperations container\n        mbeanOperations = new XMBeanOperations(mbeansTab);\n        mbeanOperations.addOperationsListener(this);\n        // create XMBeanNotifications container\n        mbeanNotifications = new XMBeanNotifications();\n        mbeanNotifications.addNotificationsListener(this);\n        // create XMBeanInfo container\n        mbeanInfo = new XMBeanInfo();\n    }\n\n    private boolean isSelectedNode(DefaultMutableTreeNode n, DefaultMutableTreeNode cn) {\n        return (cn == n);\n    }\n\n    // Call on EDT\n    private void showErrorDialog(Object message, String title) {\n        new ThreadDialog(this, message, title, JOptionPane.ERROR_MESSAGE).run();\n    }\n\n    public boolean isMBeanNode(DefaultMutableTreeNode node) {\n        Object userObject = node.getUserObject();\n        if (userObject instanceof XNodeInfo) {\n            XNodeInfo uo = (XNodeInfo) userObject;\n            return uo.getType().equals(Type.MBEAN);\n        }\n        return false;\n    }\n\n    // Call on EDT\n    public synchronized void displayNode(DefaultMutableTreeNode node) {\n        clear();\n        displayEmptyNode();\n        if (node == null) {\n            return;\n        }\n        currentNode = node;\n        clearNotifications();\n        Object userObject = node.getUserObject();\n        if (userObject instanceof XNodeInfo) {\n            XNodeInfo uo = (XNodeInfo) userObject;\n            switch (uo.getType()) {\n                case MBEAN:\n                    displayMBeanAttributesNode(node);\n                    displayMBeanOperationsNode(node);\n                    displayMBeanNotificationsNode(node);\n                    displayMBeanMetadataNode(node);\n                    break;\n                case NONMBEAN:\n                    displayEmptyNode();\n                    break;\n                default:\n                    displayEmptyNode();\n                    break;\n            }\n        } else {\n            displayEmptyNode();\n        }\n    }\n\n    // Call on EDT\n    private void displayMBeanMetadataNode(final DefaultMutableTreeNode node) {\n        final XNodeInfo uo = (XNodeInfo) node.getUserObject();\n        if (!uo.getType().equals(Type.MBEAN)) {\n            return;\n        }\n        mbean = (XMBean) uo.getData();\n        final XMBean xmb = mbean; \n        SwingWorker<MBeanInfo,Void> sw = new SwingWorker<MBeanInfo,Void>() {\n            @Override\n            public MBeanInfo doInBackground() throws InstanceNotFoundException,\n                    IntrospectionException, ReflectionException, IOException {\n                return xmb.getMBeanInfo();\n            }\n            @Override\n            protected void done() {\n                try {\n                    MBeanInfo mbi = get();\n                    if (xmb == mbean && mbi != null) {\n                        if (!isSelectedNode(node, currentNode)) return;\n                        mbeanInfo.loadMBeanInfo(xmb, mbi);\n                        topPanelMetadata.invalidate();\n                        topPanelMetadata.removeAll();\n                        mbeansTab.getButtonAt(3).setEnabled(true);\n                        JPanel mainPanelMetadata = new JPanel();\n                        mainPanelMetadata.setLayout(new BorderLayout());\n                        mainPanelMetadata.add(mbeanInfo, BorderLayout.CENTER);\n                        topPanelMetadata.add(mainPanelMetadata, BorderLayout.CENTER);\n                        JPanel southPanelMetadata = new JPanel();\n                        topPanelMetadata.add(southPanelMetadata, BorderLayout.SOUTH);\n                        topPanelMetadata.validate();\n                        repaint();\n                    }\n                } catch (Exception e) {\n                    Throwable t = Utils.getActualException(e);\n                    LOGGER.log(Level.SEVERE, \"Couldn't get MBeanInfo for MBean [\" + // NOI18N\n                            xmb.getObjectName() + \"]\", t); // NOI18N\n\n                    showErrorDialog(t.toString(),\n                            Resources.getText(\"LBL_ProblemDisplayingMBean\")); // NOI18N\n                }\n            }\n        };\n        mbeansTab.getRequestProcessor().post(sw);\n    }\n\n    // Call on EDT\n    private void displayMBeanAttributesNode(final DefaultMutableTreeNode node) {\n        final XNodeInfo uo = (XNodeInfo) node.getUserObject();\n        if (!uo.getType().equals(Type.MBEAN)) {\n            return;\n        }\n        mbean = (XMBean) uo.getData();\n        final XMBean xmb = mbean;\n        SwingWorker<MBeanInfo,Void> sw = new SwingWorker<MBeanInfo,Void>() {\n            @Override\n            public MBeanInfo doInBackground() throws InstanceNotFoundException,\n                    IntrospectionException, ReflectionException, IOException {\n                MBeanInfo mbi = xmb.getMBeanInfo();\n                return mbi;\n            }\n            @Override\n            protected void done() {\n                try {\n                    MBeanInfo mbi = get();\n                    mbeanAttributes.loadAttributes(xmb, mbi);\n                    if (xmb == mbean && mbi != null && mbi.getAttributes() != null && mbi.getAttributes().length > 0) {\n                        if (!isSelectedNode(node, currentNode)) return;\n                        topPanelAttributes.invalidate();\n                        topPanelAttributes.removeAll();\n                        mbeansTab.getButtonAt(0).setEnabled(true);\n                        JPanel borderPanel = new JPanel(new BorderLayout());\n                        borderPanel.setBorder(BorderFactory.createTitledBorder(\n                                Resources.getText(\"LBL_AttributeValues\"))); // NOI18N\n                        borderPanel.add(new JScrollPane(mbeanAttributes));\n                        JPanel mainPanelAttributes = new JPanel();\n                        mainPanelAttributes.setLayout(new BorderLayout());\n                        mainPanelAttributes.add(borderPanel, BorderLayout.CENTER);\n                        topPanelAttributes.add(mainPanelAttributes, BorderLayout.CENTER);\n                        // add the refresh button to the south panel\n                        JPanel southPanelAttributes = new JPanel();\n                        southPanelAttributes.add(refreshButton, BorderLayout.SOUTH);\n                        southPanelAttributes.setVisible(true);\n                        refreshButton.setEnabled(true);\n                        topPanelAttributes.add(southPanelAttributes, BorderLayout.SOUTH);\n                        topPanelAttributes.validate();\n                        repaint();\n                            }\n                } catch (Exception e) {\n                    Throwable t = Utils.getActualException(e);\n                    LOGGER.log(Level.SEVERE, \"Problem displaying MBean \" + // NOI18N\n                            \"attributes for MBean [\" + // NOI18N\n                            xmb.getObjectName() + \"]\", t); // NOI18N\n\n                    showErrorDialog(t.toString(),\n                            Resources.getText(\"LBL_ProblemDisplayingMBean\")); // NOI18N\n                }\n            }\n        };\n        mbeansTab.getRequestProcessor().post(sw);\n    }\n\n    // Call on EDT\n    private void displayMBeanOperationsNode(final DefaultMutableTreeNode node) {\n        final XNodeInfo uo = (XNodeInfo) node.getUserObject();\n        if (!uo.getType().equals(Type.MBEAN)) {\n            return;\n        }\n        mbean = (XMBean) uo.getData();\n        final XMBean xmb = mbean; \n        SwingWorker<MBeanInfo,Void> sw = new SwingWorker<MBeanInfo,Void>() {\n            @Override\n            public MBeanInfo doInBackground() throws InstanceNotFoundException,\n                    IntrospectionException, ReflectionException, IOException {\n                return xmb.getMBeanInfo();\n            }\n            @Override\n            protected void done() {\n                try {\n                    MBeanInfo mbi = get();\n                    if (xmb == mbean && mbi != null && mbi.getOperations() != null && mbi.getOperations().length > 0) {\n                        if (!isSelectedNode(node, currentNode)) return;\n                        mbeanOperations.loadOperations(xmb, mbi);\n                        topPanelOperations.invalidate();\n                        topPanelOperations.removeAll();\n                        mbeansTab.getButtonAt(1).setEnabled(true);\n                        JPanel borderPanel = new JPanel(new BorderLayout());\n                        borderPanel.setBorder(BorderFactory.createTitledBorder(\n                                Resources.getText(\"LBL_OperationInvocation\"))); // NOI18N\n                        borderPanel.add(new JScrollPane(mbeanOperations));\n                        JPanel mainPanelOperations = new JPanel();\n                        mainPanelOperations.setLayout(new BorderLayout());\n                        mainPanelOperations.add(borderPanel, BorderLayout.CENTER);\n                        topPanelOperations.add(mainPanelOperations, BorderLayout.CENTER);\n                        JPanel southPanelOperations = new JPanel();\n                        topPanelOperations.add(southPanelOperations, BorderLayout.SOUTH);\n                        topPanelOperations.validate();\n                        repaint();\n                    }\n                } catch (Exception e) {\n                    Throwable t = Utils.getActualException(e);\n                    LOGGER.log(Level.SEVERE, \"Problem displaying MBean \" + // NOI18N\n                            \"operations for MBean [\" + // NOI18N\n                            xmb.getObjectName() + \"]\", t); // NOI18N\n                    showErrorDialog(t.toString(),\n                            Resources.getText(\"LBL_ProblemDisplayingMBean\")); // NOI18N\n                }\n            }\n        };\n        mbeansTab.getRequestProcessor().post(sw);\n    }\n\n    // Call on EDT\n    private void displayMBeanNotificationsNode(final DefaultMutableTreeNode node) {\n        final XNodeInfo uo = (XNodeInfo) node.getUserObject();\n        if (!uo.getType().equals(Type.MBEAN)) {\n            return;\n        }\n        mbean = (XMBean) uo.getData();\n        final XMBean xmb = mbean; \n        SwingWorker<Boolean,Void> sw = new SwingWorker<Boolean,Void>() {\n            @Override\n            public Boolean doInBackground() {\n                return xmb.isBroadcaster();\n            }\n            @Override\n            protected void done() {\n                try {\n                    Boolean isBroadcaster = get();\n                    if (xmb == mbean && isBroadcaster != null && isBroadcaster.booleanValue()) {\n                        if (!isSelectedNode(node, currentNode)) return;\n                        mbeanNotifications.loadNotifications(xmb);\n                        updateNotifications();\n                        topPanelNotifications.invalidate();\n                        topPanelNotifications.removeAll();\n                        mbeansTab.getButtonAt(2).setEnabled(true);\n                        JPanel borderPanel = new JPanel(new BorderLayout());\n                        borderPanel.setBorder(BorderFactory.createTitledBorder(\n                                Resources.getText(\"LBL_NotificationBuffer\"))); // NOI18N\n                        borderPanel.add(new JScrollPane(mbeanNotifications));\n                        JPanel mainPanelNotifications = new JPanel();\n                        mainPanelNotifications.setLayout(new BorderLayout());\n                        mainPanelNotifications.add(borderPanel, BorderLayout.CENTER);\n                        topPanelNotifications.add(mainPanelNotifications, BorderLayout.CENTER);\n                        // add the subscribe/unsubscribe/clear buttons to the south panel\n                        JPanel southPanelNotifications = new JPanel();\n                        southPanelNotifications.add(subscribeButton, BorderLayout.WEST);\n                        southPanelNotifications.add(unsubscribeButton, BorderLayout.CENTER);\n                        southPanelNotifications.add(clearButton, BorderLayout.EAST);\n                        southPanelNotifications.setVisible(true);\n                        subscribeButton.setEnabled(true);\n                        unsubscribeButton.setEnabled(true);\n                        clearButton.setEnabled(true);\n                        topPanelNotifications.add(southPanelNotifications, BorderLayout.SOUTH);\n                        topPanelNotifications.validate();\n                        repaint();\n                    }\n                } catch (Exception e) {\n                    Throwable t = Utils.getActualException(e);\n                    LOGGER.log(Level.SEVERE, \"Problem displaying MBean \" + // NOI18N\n                            \"notifications for MBean [\" + // NOI18N\n                            xmb.getObjectName() + \"]\", t); // NOI18N\n                    showErrorDialog(t.toString(),\n                            Resources.getText(\"LBL_ProblemDisplayingMBean\")); // NOI18N\n                }\n            }\n        };\n        mbeansTab.getRequestProcessor().post(sw);\n    }\n\n    // Call on EDT\n    private void displayEmptyNode() {\n        invalidate();\n        topPanelAttributes.invalidate();\n        topPanelAttributes.removeAll();\n        topPanelAttributes.validate();\n        topPanelAttributes.repaint();\n        topPanelOperations.invalidate();\n        topPanelOperations.removeAll();\n        topPanelOperations.validate();\n        topPanelOperations.repaint();\n        topPanelNotifications.invalidate();\n        topPanelNotifications.removeAll();\n        topPanelNotifications.validate();\n        topPanelNotifications.repaint();\n        topPanelMetadata.invalidate();\n        topPanelMetadata.removeAll();\n        topPanelMetadata.validate();\n        topPanelMetadata.repaint();\n        mbeansTab.getButtonAt(0).setEnabled(false);\n        mbeansTab.getButtonAt(1).setEnabled(false);\n        mbeansTab.getButtonAt(2).setEnabled(false);\n        mbeansTab.getButtonAt(3).setEnabled(false);\n        validate();\n        repaint();\n    }\n\n    /**\n     * Subscribe button action.\n     */\n    private void registerListener() {\n        SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>() {\n            @Override\n            public Void doInBackground()\n            throws InstanceNotFoundException, IOException {\n                mbeanNotifications.registerListener(currentNode);\n                return null;\n            }\n            @Override\n            protected void done() {\n                try {\n                    get();\n                    updateNotifications();\n                    validate();\n                } catch (Exception e) {\n                    Throwable t = Utils.getActualException(e);\n                    LOGGER.log(Level.SEVERE, \"Problem adding listener\", t); // NOI18N\n\n                    showErrorDialog(t.getMessage(),\n                            Resources.getText(\"LBL_ProblemAddingListener\")); // NOI18N\n                }\n            }\n        };\n        mbeansTab.getRequestProcessor().post(sw);\n    }\n\n    /**\n     * Unsubscribe button action.\n     */\n    private void unregisterListener() {\n        SwingWorker<Boolean, Void> sw = new SwingWorker<Boolean, Void>() {\n            @Override\n            public Boolean doInBackground() {\n                return mbeanNotifications.unregisterListener(currentNode);\n            }\n            @Override\n            protected void done() {\n                try {\n                    if (get()) {\n                        updateNotifications();\n                        validate();\n                    }\n                } catch (Exception e) {\n                    Throwable t = Utils.getActualException(e);\n                    LOGGER.log(Level.SEVERE, \"Problem removing listener\", t); // NOI18N\n                    showErrorDialog(t.getMessage(),\n                            Resources.getText(\"LBL_ProblemRemovingListener\")); // NOI18N\n                }\n            }\n        };\n        mbeansTab.getRequestProcessor().post(sw);\n    }\n\n    /**\n     * Refresh button action.\n     */\n    private void refreshAttributes() {\n        mbeanAttributes.refreshAttributes();\n    }\n\n    // Call on EDT\n    private void updateNotifications() {\n        if (mbeanNotifications.isListenerRegistered(mbean)) {\n            long received = mbeanNotifications.getReceivedNotifications(mbean);\n            updateReceivedNotifications(currentNode, received);\n        } else {\n            clearNotifications();\n        }\n    }\n\n    /**\n     * Update notification node label in MBean tree: \"Notifications[received]\".\n     */\n    // Call on EDT\n    private void updateReceivedNotifications(\n            DefaultMutableTreeNode emitter, long received) {\n        String text = Resources.getText(\"LBL_Notifications\") + \"[\" + received + \"]\"; // NOI18N\n        updateNotificationsNodeLabel(emitter, text);\n    }\n\n    /**\n     * Update notification node label in MBean tree: \"Notifications\".\n     */\n    // Call on EDT\n    private void clearNotifications() {\n        updateNotificationsNodeLabel(currentNode,\n                Resources.getText(\"LBL_Notifications\")); // NOI18N\n    }\n\n    /**\n     * Update notification node label in MBean tree: \"Notifications[0]\".\n     */\n    // Call on EDT\n    private void clearNotifications0() {\n        updateNotificationsNodeLabel(currentNode,\n                Resources.getText(\"LBL_Notifications\") + \"[0]\"); // NOI18N\n    }\n\n    /**\n     * Update the label of the supplied MBean tree node.\n     */\n    // Call on EDT\n    private void updateNotificationsNodeLabel(\n            DefaultMutableTreeNode node, String label) {\n        // Find Notifications TabButton and update text\n        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)\n                mbeansTab.getTree().getLastSelectedPathComponent();\n        if (node != selectedNode) {\n            return;\n        }\n        invalidate();\n        mbeansTab.getButtonAt(2).setText(label);\n        validate();\n        repaint();\n    }\n\n    /**\n     * Clear button action.\n     */\n    // Call on EDT\n    private void clearCurrentNotifications() {\n        mbeanNotifications.clearCurrentNotifications();\n        if (mbeanNotifications.isListenerRegistered(mbean)) {\n            // Update notifs in MBean tree \"Notifications[0]\".\n            //\n            // Notification buffer has been cleared with a listener been\n            // registered so add \"[0]\" at the end of the node label.\n            //\n            clearNotifications0();\n        } else {\n            // Update notifs in MBean tree \"Notifications\".\n            //\n            // Notification buffer has been cleared without a listener been\n            // registered so don't add \"[0]\" at the end of the node label.\n            //\n            clearNotifications();\n        }\n    }\n\n    // Call on EDT\n    private void clear() {\n        mbeanAttributes.stopCellEditing();\n        mbeanAttributes.emptyTable();\n        mbeanAttributes.removeAttributes();\n        mbeanOperations.removeOperations();\n        mbeanNotifications.stopCellEditing();\n        mbeanNotifications.emptyTable();\n        mbeanNotifications.disableNotifications();\n        mbeanInfo.emptyInfoTable();\n        mbean = null;\n        currentNode = null;\n    }\n\n    /**\n     * Notification listener: handles asynchronous reception\n     * of MBean operation results and MBean notifications.\n     */\n    // Call on EDT\n    public void handleNotification(Notification e, Object handback) {\n        // Operation result\n        if (e.getType().equals(XMBeanOperations.OPERATION_INVOCATION_EVENT)) {\n            final Object message;\n            if (handback == null) {\n                JTextArea textArea = new JTextArea(\"null\"); // NOI18N\n                textArea.setEditable(false);\n                textArea.setEnabled(true);\n                textArea.setRows(textArea.getLineCount());\n                message = textArea;\n            } else {\n                Component comp = mbeansTab.getDataViewer().\n                        createOperationViewer(handback, mbean);\n                if (comp == null) {\n                    JTextArea textArea = new JTextArea(handback.toString());\n                    textArea.setEditable(false);\n                    textArea.setEnabled(true);\n                    textArea.setRows(textArea.getLineCount());\n                    JScrollPane scrollPane = new JScrollPane(textArea);\n                    Dimension d = scrollPane.getPreferredSize();\n                    if (d.getWidth() > 400 || d.getHeight() > 250) {\n                        scrollPane.setPreferredSize(new Dimension(400, 250));\n                    }\n                    message = scrollPane;\n                } else {\n                    if (!(comp instanceof JScrollPane)) {\n                        comp = new JScrollPane(comp);\n                    }\n                    Dimension d = comp.getPreferredSize();\n                    if (d.getWidth() > 400 || d.getHeight() > 250) {\n                        comp.setPreferredSize(new Dimension(400, 250));\n                    }\n                    message = comp;\n                }\n            }\n            new ThreadDialog(\n                    (Component) e.getSource(),\n                    message,\n                    Resources.getText(\"LBL_OperationReturnValue\"), // NOI18N\n                    JOptionPane.INFORMATION_MESSAGE).run();\n        }\n        // Got notification\n        else if (e.getType().equals(\n                XMBeanNotifications.NOTIFICATION_RECEIVED_EVENT)) {\n            DefaultMutableTreeNode emitter = (DefaultMutableTreeNode) handback;\n            Long received = (Long) e.getUserData();\n            updateReceivedNotifications(emitter, received.longValue());\n        }\n    }\n\n    /**\n     * Action listener: handles actions in panel buttons\n     */\n    // Call on EDT\n    public void actionPerformed(ActionEvent e) {\n        if (e.getSource() instanceof JButton) {\n            JButton button = (JButton) e.getSource();\n            // Refresh button\n            if (button == refreshButton) {\n                refreshAttributes();\n                return;\n            }\n            // Clear button\n            if (button == clearButton) {\n                clearCurrentNotifications();\n                return;\n            }\n            // Subscribe button\n            if (button == subscribeButton) {\n                registerListener();\n                return;\n            }\n            // Unsubscribe button\n            if (button == unsubscribeButton) {\n                unregisterListener();\n                return;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XTable.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport javax.swing.*;\nimport javax.swing.table.*;\nimport java.awt.*;\nimport java.io.*;\n\nabstract class XTable extends JTable {\n    static final int NAME_COLUMN = 0;\n    static final int VALUE_COLUMN = 1;\n    private Color defaultColor, editableColor, errorColor;\n    private Font normalFont, boldFont;\n\n    public XTable () {\n        super();\n        @SuppressWarnings(\"serial\")\n        final TableSorter sorter = new TableSorter();\n        setModel(sorter);\n        sorter.addMouseListenerToHeaderInTable(this);\n        setRowSelectionAllowed(false);\n        setColumnSelectionAllowed(false);\n        setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);\n    }\n\n    Color getDefaultColor() {\n        return defaultColor;\n    }\n\n    Color getEditableColor() {\n        return editableColor;\n    }\n\n    /**\n     * Called by TableSorter if a mouse event requests to sort the rows.\n     * @param column the column against which the rows are sorted\n     */\n    void sortRequested(int column) {\n        // This is a hook for subclasses\n    }\n\n    /**\n     * This returns the select index as the table was at initialization\n     */\n    public int getSelectedIndex() {\n        return convertRowToIndex(getSelectedRow());\n    }\n\n    /*\n     * Converts the row into index (before sorting)\n     */\n    public int convertRowToIndex(int row) {\n        if (row == -1) return row;\n        if (getModel() instanceof TableSorter) {\n            return ((TableSorter) getModel()).getIndexOfRow(row);\n        } else {\n            return row;\n        }\n    }\n\n    public void emptyTable() {\n        DefaultTableModel model = (DefaultTableModel)getModel();\n        while (model.getRowCount()>0)\n            model.removeRow(0);\n    }\n\n    public abstract boolean isTableEditable();\n    public abstract boolean isColumnEditable(int column);\n    public abstract boolean isReadable(int row);\n    public abstract boolean isWritable(int row);\n    public abstract boolean isCellError(int row, int col);\n    public abstract boolean isAttributeViewable(int row, int col);\n    public abstract void setTableValue(Object value,int row);\n    public abstract Object getValue(int row);\n    public abstract String getClassName(int row);\n    public abstract String getValueName(int row);\n\n    public boolean isReadWrite(int row) {\n        return (isReadable(row) && isWritable(row));\n    }\n\n    //JTable re-implementation\n\n    //attribute can be editable even if unavailable\n    @Override\n    public boolean isCellEditable(int row, int col) {\n        return ((isTableEditable() && isColumnEditable(col)\n                 &&  isWritable(row)\n                 && Utils.isEditableType(getClassName(row))));\n    }\n\n    //attribute can be droppable even if unavailable\n    public boolean isCellDroppable(int row, int col) {\n        return (isTableEditable() && isColumnEditable(col)\n                && isWritable(row));\n    }\n\n    //returns null, means no tool tip\n    public String getToolTip(int row, int column) {\n        return null;\n    }\n\n    /**\n     * This method sets read write rows to be blue, and other rows to be their\n     * default rendered colour.\n     */\n    @Override\n    public TableCellRenderer getCellRenderer(int row, int column) {\n        DefaultTableCellRenderer tcr =\n            (DefaultTableCellRenderer) super.getCellRenderer(row,column);\n        tcr.setToolTipText(getToolTip(row,column));\n        if (defaultColor == null) {\n            defaultColor = tcr.getForeground();\n            editableColor = Color.blue;\n            errorColor = Color.red;\n            // this sometimes happens for some reason\n            if (defaultColor == null) {\n                return tcr;\n            }\n        }\n        if (column != VALUE_COLUMN) {\n            tcr.setForeground(defaultColor);\n            return tcr;\n        }\n        if (isCellError(row,column)) {\n            tcr.setForeground(errorColor);\n        } else if (isCellEditable(row, column)) {\n            tcr.setForeground(editableColor);\n        } else {\n            tcr.setForeground(defaultColor);\n        }\n        return tcr;\n    }\n\n    @Override\n    public Component prepareRenderer(TableCellRenderer renderer,\n                                     int row, int column) {\n        Component comp = super.prepareRenderer(renderer, row, column);\n\n        if (normalFont == null) {\n            normalFont = comp.getFont();\n            boldFont = normalFont.deriveFont(Font.BOLD);\n        }\n\n        if (column == VALUE_COLUMN && isAttributeViewable(row, VALUE_COLUMN)) {\n            comp.setFont(boldFont);\n        } else {\n            comp.setFont(normalFont);\n        }\n\n        return comp;\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XTextField.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.*;\nimport java.awt.dnd.*;\nimport java.awt.event.*;\nimport java.awt.datatransfer.*;\nimport java.io.*;\nimport java.util.*;\nimport javax.swing.plaf.*;\nimport javax.swing.event.*;\nimport javax.swing.*;\n\n\n/**\n * This list implements the drag and drop functionality.\n */\n@SuppressWarnings(\"serial\")\nclass XTextField extends JPanel\n    implements DocumentListener,\n               ActionListener {\n\n    private XObject selectedObject;\n    private Class expectedClass;\n    private Object value;\n    protected JTextField textField;\n\n    private static boolean allowNullSelection = false;\n\n    protected final static int COMPATIBLE_VALUE = 1;\n    protected final static int CURRENT_VALUE = 2;\n    protected final static int NULL_VALUE = 3;\n\n    private JButton button;\n    private XMBeanOperations operation;\n\n    //used in XTestFieldEditor\n    public XTextField() {\n        super(new BorderLayout());\n        add(textField = new JTextField(),BorderLayout.CENTER);\n        textField.addActionListener(this);\n        //\n    }\n\n    public XTextField(Object value) {\n        this(value,value.toString().length());\n    }\n\n    public XTextField(Object value, int colWidth) {\n        this(value,value.getClass(),colWidth, true, null, null);\n    }\n\n    public XTextField(Object value,\n                      Class expectedClass,\n                      int colWidth,\n                      boolean isCallable,\n                      JButton button,\n                      XMBeanOperations operation) {\n        super(new BorderLayout());\n        this.expectedClass = expectedClass;\n        this.button = button;\n        this.operation = operation;\n        add(textField = new JTextField(value.toString(),colWidth),\n            BorderLayout.CENTER);\n        if(isCallable)\n            textField.addActionListener(this);\n\n        boolean fieldEditable = expectedClass == null ? false :\n            Utils.isEditableType(expectedClass.getName());\n        if (fieldEditable && isCallable) {\n            textField.setEditable(true);\n        }\n        else {\n            textField.setEditable(false);\n        }\n    }\n\n    public static void setNullSelectionAllowed(boolean allowNullSelection) {\n        XTextField.allowNullSelection = allowNullSelection;\n    }\n\n    public static boolean getNullSelectionAllowed() {\n        return allowNullSelection;\n    }\n\n    protected void init(Object value, Class expectedClass) {\n        this.expectedClass = expectedClass;\n        this.value = value;\n        boolean fieldEditable = expectedClass == null ? false :\n            Utils.isEditableType(expectedClass.getName());\n        clearObject();\n        if (value != null) {\n            textField.setText(value.toString());\n        }\n        else {\n            //null String value for the moment\n            textField.setText(\"\"); // NOI18N\n        }\n        textField.setToolTipText(null);\n        if (fieldEditable) {\n            if (!textField.isEditable()) {\n                textField.setEditable(true);\n            }\n\n        }\n        else {\n            if (textField.isEditable()) {\n                textField.setEditable(false);\n            }\n        }\n    }\n\n\n\n\n\n    private synchronized void setObject(XObject object) {\n        clearObject();\n        selectedObject = object;\n        setSelectedColors();\n        textField.setText(object.getText());\n        textField.getDocument().addDocumentListener(this);\n        paintImmediately(getVisibleRect());\n    }\n\n    private synchronized void clearObject() {\n        textField.getDocument().removeDocumentListener(this);\n        selectedObject = null;\n        setDefaultColors();\n    }\n\n    private synchronized void setSelectedColors() {\n        // fore = textField.getForeground();\n        // back = textField.getBackground();\n\n        //textField.setForeground(Color.red);\n        // textField.setBackground(Color.yellow);\n    }\n\n    private synchronized void setDefaultColors() {\n        //  if (fore != null) textField.setForeground(fore);\n        // if (back != null)  textField.setBackground(back);\n    }\n\n    public void setHorizontalAlignment(int h) {\n        textField.setHorizontalAlignment(h);\n    }\n\n    //can be overwritten\n    protected JMenuItem buildJMenuItem(XObject xobject, int valueType) {\n        if (valueType == COMPATIBLE_VALUE) {\n            return new JMenuItem(xobject.getText());\n        }\n        else if (valueType == CURRENT_VALUE) {\n            return new JMenuItem(\"> \"+xobject.getText()); // NOI18N\n        }\n        else if (valueType == NULL_VALUE) {\n            return new JMenuItem(\"null\"); // NOI18N\n        }\n        else {\n            return null;\n        }\n    }\n\n    private JPopupMenu buildEditPopupMenu() {\n        JPopupMenu menu = new JPopupMenu();\n        return menu;\n    }\n\n\n    // ACTIONLISTENER IMPLEMENTATION\n    public void actionPerformed(ActionEvent e) {\n        if (e.getSource() instanceof JTextField) {\n            if(operation != null)\n                operation.performInvokeRequest(button);\n        }\n    }\n\n    /**\n     * This method returns either the user inputted String, or an XObject\n     * if one was dropped on the input field.\n     */\n    public Object getValue() {\n        if (selectedObject!=null) {\n            if (selectedObject == XObject.NULL_OBJECT) {\n                //null case\n                return null;\n            }\n            else {\n                return selectedObject;\n            }\n        }\n        else {\n            return  textField.getText();\n        }\n    }\n\n    public void changedUpdate(DocumentEvent e) {\n        // the user typed something, so remove references\n        // to the obejct that was dropped.\n        clearObject();\n    }\n\n    public void removeUpdate(DocumentEvent e) {\n        // the user typed something, so remove references\n        // to the obejct that was dropped.\n        clearObject();\n    }\n\n    public void insertUpdate(DocumentEvent e) {\n        // the user typed something, so remove references\n        // to the obejct that was dropped.\n        clearObject();\n    }\n\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XTextFieldEditor.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.Component;\nimport java.util.EventObject;\nimport java.awt.event.*;\nimport javax.swing.*;\nimport javax.swing.event.*;\nimport javax.swing.table.*;\n\n@SuppressWarnings(\"serial\")\nclass XTextFieldEditor extends XTextField implements TableCellEditor {\n\n    protected EventListenerList evtListenerList = new EventListenerList();\n    protected ChangeEvent changeEvent = new ChangeEvent(this);\n\n    private FocusListener editorFocusListener = new FocusAdapter() {\n        @Override\n        public void focusLost(FocusEvent e) {\n            // https://java.net/jira/browse/VISUALVM-167\n            // must not call fireEditingStopped() here!\n        }\n    };\n\n    public XTextFieldEditor() {\n        super();\n        textField.addFocusListener(editorFocusListener);\n    }\n\n    //edition stopped ou JMenuItem selection & JTextField selection\n    @Override\n    public void  actionPerformed(ActionEvent e) {\n        super.actionPerformed(e);\n        if ((e.getSource() instanceof JMenuItem) ||\n            (e.getSource() instanceof JTextField)) {\n            fireEditingStopped();\n        }\n    }\n\n    //edition stopped on drag & drop success\n    protected void dropSuccess() {\n        fireEditingStopped();\n    }\n\n    //TableCellEditor implementation\n\n    public void addCellEditorListener(CellEditorListener listener) {\n        evtListenerList.add(CellEditorListener.class,listener);\n    }\n\n    public void removeCellEditorListener(CellEditorListener listener) {\n        evtListenerList.remove(CellEditorListener.class, listener);\n    }\n\n    protected void fireEditingStopped() {\n        CellEditorListener listener;\n        Object[] listeners = evtListenerList.getListenerList();\n        for (int i=0;i< listeners.length;i++) {\n            if (listeners[i] == CellEditorListener.class) {\n                listener = (CellEditorListener) listeners[i+1];\n                listener.editingStopped(changeEvent);\n            }\n        }\n    }\n\n    protected void fireEditingCanceled() {\n        CellEditorListener listener;\n        Object[] listeners = evtListenerList.getListenerList();\n        for (int i=0;i< listeners.length;i++) {\n            if (listeners[i] == CellEditorListener.class) {\n                listener = (CellEditorListener) listeners[i+1];\n                listener.editingCanceled(changeEvent);\n            }\n        }\n    }\n\n    public void cancelCellEditing() {\n        fireEditingCanceled();\n    }\n\n    public boolean stopCellEditing() {\n        fireEditingStopped();\n        return true;\n    }\n\n    public boolean isCellEditable(EventObject event) {\n        return true;\n    }\n\n    public boolean shouldSelectCell(EventObject event) {\n        return true;\n    }\n\n    public Object getCellEditorValue() {\n        Object object = getValue();\n\n        if (object instanceof XObject) {\n            return ((XObject) object).getObject();\n        }\n        else {\n            return object;\n        }\n    }\n\n    public Component getTableCellEditorComponent(JTable table,\n                                                 Object value,\n                                                 boolean isSelected,\n                                                 int row,\n                                                 int column) {\n        String className;\n        if (table instanceof XTable) {\n            XTable mytable = (XTable) table;\n            className = mytable.getClassName(row);\n        } else {\n            className = String.class.getName();\n        }\n        Class<?> clazz;\n        try {\n            clazz = Utils.getClass(className);\n        } catch (ClassNotFoundException e) {\n            clazz = null;\n        }\n        init(value, clazz);\n\n        return this;\n    }\n\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XTree.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.util.*;\nimport javax.management.*;\nimport javax.swing.*;\nimport javax.swing.tree.*;\nimport org.graalvm.visualvm.modules.mbeans.options.GlobalPreferences;\nimport static org.graalvm.visualvm.modules.mbeans.XNodeInfo.Type;\n\n@SuppressWarnings(\"serial\")\nclass XTree extends JTree {\n\n    private List<String> orderedKeyPropertyList;\n    private MBeansTab mbeansTab;\n    private Map<String, DefaultMutableTreeNode> nodes =\n            new HashMap<String, DefaultMutableTreeNode>();\n\n    public XTree(MBeansTab mbeansTab) {\n        super(new DefaultMutableTreeNode(\"MBeanTreeRootNode\")); // NOI18N\n        this.mbeansTab = mbeansTab;\n        setRootVisible(false);\n        setShowsRootHandles(true);\n        ToolTipManager.sharedInstance().registerComponent(this);\n        orderedKeyPropertyList = getOrderedKeyPropertyList();\n    }\n\n    /**\n     * This method removes the node from its parent\n     */\n    // Call on EDT\n    private synchronized void removeChildNode(DefaultMutableTreeNode child) {\n        DefaultTreeModel model = (DefaultTreeModel) getModel();\n        model.removeNodeFromParent(child);\n    }\n\n    /**\n     * This method adds the child to the specified parent node\n     * at specific index.\n     */\n    // Call on EDT\n    private synchronized void addChildNode(\n            DefaultMutableTreeNode parent,\n            DefaultMutableTreeNode child,\n            int index) {\n        DefaultTreeModel model = (DefaultTreeModel) getModel();\n        boolean isRootLeaf = (parent == model.getRoot()) && parent.isLeaf();\n        model.insertNodeInto(child, parent, index);\n        // Make the root node's children visible if the\n        // parent node is the root node and is a leaf\n        if (isRootLeaf) {\n            model.nodeStructureChanged(parent);\n        }\n    }\n\n    /**\n     * This method adds the child to the specified parent node.\n     * The index where the child is to be added depends on the\n     * child node being Comparable or not. If the child node is\n     * not Comparable then it is added at the end, i.e. right\n     * after the current parent's children.\n     */\n    // Call on EDT\n    private synchronized void addChildNode(\n            DefaultMutableTreeNode parent, DefaultMutableTreeNode child) {\n        int childCount = parent.getChildCount();\n        if (childCount == 0) {\n            addChildNode(parent, child, 0);\n            return;\n        }\n        if (child instanceof ComparableDefaultMutableTreeNode) {\n            ComparableDefaultMutableTreeNode comparableChild =\n                    (ComparableDefaultMutableTreeNode) child;\n            for (int i = childCount - 1; i >= 0; i--) {\n                DefaultMutableTreeNode brother =\n                        (DefaultMutableTreeNode) parent.getChildAt(i);\n                // \"child >= brother\", add child after brother\n                if (comparableChild.compareTo(brother) >= 0) {\n                    addChildNode(parent, child, i + 1);\n                    return;\n                }\n            }\n            // \"child < all brothers\", add at the beginning\n            addChildNode(parent, child, 0);\n            return;\n        }\n        // \"child not comparable\", add at the end\n        addChildNode(parent, child, childCount);\n    }\n\n    /**\n     * This method removes all the displayed nodes from the tree,\n     * but does not affect actual MBeanServer contents.\n     */\n    // Call on EDT\n    @Override\n    public synchronized void removeAll() {\n        DefaultTreeModel model = (DefaultTreeModel) getModel();\n        DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();\n        root.removeAllChildren();\n        model.nodeStructureChanged(root);\n        nodes.clear();\n    }\n\n    // Call on EDT\n    public synchronized void removeMBeanFromView(ObjectName mbean) {\n        // We assume here that MBeans are removed one by one (on MBean\n        // unregistered notification). Deletes the tree node associated\n        // with the given MBean and recursively all the node parents\n        // which are leaves and non XMBean.\n        //\n        DefaultMutableTreeNode node = null;\n        Dn dn = new Dn(mbean, orderedKeyPropertyList);\n        if (dn.getTokenCount() > 0) {\n            DefaultTreeModel model = (DefaultTreeModel) getModel();\n            Token token = dn.getToken(0);\n            String hashKey = dn.getHashKey(token);\n            node = nodes.get(hashKey);\n            if ((node != null) && (!node.isRoot())) {\n                if (node.getChildCount() > 0) {\n                    String label = token.getValue();\n                    XNodeInfo userObject = new XNodeInfo(\n                            Type.NONMBEAN, label,\n                            label, token.getTokenValue());\n                    changeNodeValue(node, userObject);\n                } else {\n                    DefaultMutableTreeNode parent =\n                            (DefaultMutableTreeNode) node.getParent();\n                    model.removeNodeFromParent(node);\n                    nodes.remove(hashKey);\n                    removeParentFromView(dn, 1, parent);\n                }\n            }\n        }\n    }\n\n    /**\n     * Removes only the parent nodes which are non MBean and leaf.\n     * This method assumes the child nodes have been removed before.\n     */\n    // Call on EDT\n    private DefaultMutableTreeNode removeParentFromView(\n            Dn dn, int index, DefaultMutableTreeNode node) {\n        if ((!node.isRoot()) && node.isLeaf() &&\n                (!(((XNodeInfo) node.getUserObject()).getType().equals(Type.MBEAN)))) {\n            DefaultMutableTreeNode parent =\n                    (DefaultMutableTreeNode) node.getParent();\n            removeChildNode(node);\n            String hashKey = dn.getHashKey(dn.getToken(index));\n            nodes.remove(hashKey);\n            removeParentFromView(dn, index + 1, parent);\n        }\n        return node;\n    }\n\n    // Call on EDT\n    public synchronized void addMBeansToView(Set<ObjectName> mbeans) {\n        Set<Dn> dns = new TreeSet<Dn>();\n        for (ObjectName mbean : mbeans) {\n            Dn dn = new Dn(mbean, orderedKeyPropertyList);\n            dns.add(dn);\n        }\n        for (Dn dn : dns) {\n            ObjectName mbean = dn.getObjectName();\n            XMBean xmbean = new XMBean(mbean, mbeansTab);\n            addMBeanToView(mbean, xmbean, dn);\n        }\n    }\n\n    // Call on EDT\n    public synchronized void addMBeanToView(ObjectName mbean) {\n        // Build XMBean for the given MBean\n        //\n        XMBean xmbean = new XMBean(mbean, mbeansTab);\n        // Build Dn for the given MBean\n        //\n        Dn dn = new Dn(mbean, orderedKeyPropertyList);\n        // Add the new nodes to the MBean tree from leaf to root\n        //\n        addMBeanToView(mbean, xmbean, dn);\n    }\n\n    // Call on EDT\n    private synchronized void addMBeanToView(\n            ObjectName mbean, XMBean xmbean, Dn dn) {\n\n        DefaultMutableTreeNode childNode = null;\n        DefaultMutableTreeNode parentNode = null;\n\n        // Add the node or replace its user object if already added\n        //\n        Token token = dn.getToken(0);\n        String hashKey = dn.getHashKey(token);\n        if (nodes.containsKey(hashKey)) {\n            // Found existing node previously created when adding another node\n            //\n            childNode = nodes.get(hashKey);\n            // Replace user object to reflect that this node is an MBean\n            //\n            Object data = createNodeValue(xmbean, token);\n            String label = data.toString();\n            XNodeInfo userObject =\n                    new XNodeInfo(Type.MBEAN, data, label, mbean.toString());\n            changeNodeValue(childNode, userObject);\n            return;\n        }\n\n        // Create new leaf node\n        //\n        childNode = createDnNode(dn, token, xmbean);\n        nodes.put(hashKey, childNode);\n\n        // Add intermediate non MBean nodes\n        //\n        for (int i = 1; i < dn.getTokenCount(); i++) {\n            token = dn.getToken(i);\n            hashKey = dn.getHashKey(token);\n            if (nodes.containsKey(hashKey)) {\n                // Intermediate node already present, add new node as child\n                //\n                parentNode = nodes.get(hashKey);\n                addChildNode(parentNode, childNode);\n                return;\n            } else {\n                // Create new intermediate node\n                //\n                if (\"domain\".equals(token.getTokenType())) { // NOI18N\n                    parentNode = createDomainNode(dn, token);\n                    DefaultMutableTreeNode root =\n                            (DefaultMutableTreeNode) getModel().getRoot();\n                    addChildNode(root, parentNode);\n                } else {\n                    parentNode = createSubDnNode(dn, token);\n                }\n                nodes.put(hashKey, parentNode);\n                addChildNode(parentNode, childNode);\n            }\n            childNode = parentNode;\n        }\n    }\n\n    // Call on EDT\n    private synchronized void changeNodeValue(\n            DefaultMutableTreeNode node, XNodeInfo nodeValue) {\n        if (node instanceof ComparableDefaultMutableTreeNode) {\n            // should it stay at the same place?\n            DefaultMutableTreeNode clone =\n                    (DefaultMutableTreeNode) node.clone();\n            clone.setUserObject(nodeValue);\n            if (((ComparableDefaultMutableTreeNode) node).compareTo(clone) == 0) {\n                // the order in the tree didn't change\n                node.setUserObject(nodeValue);\n                DefaultTreeModel model = (DefaultTreeModel) getModel();\n                model.nodeChanged(node);\n            } else {\n                // delete the node and re-order it in case the\n                // node value modifies the order in the tree\n                DefaultMutableTreeNode parent =\n                        (DefaultMutableTreeNode) node.getParent();\n                removeChildNode(node);\n                node.setUserObject(nodeValue);\n                addChildNode(parent, node);\n            }\n        } else {\n            // not comparable stays at the same place\n            node.setUserObject(nodeValue);\n            DefaultTreeModel model = (DefaultTreeModel) getModel();\n            model.nodeChanged(node);\n        }\n        // Clear the current selection and set it\n        // again so valueChanged() gets called\n        if (node == getLastSelectedPathComponent()) {\n            TreePath selectionPath = getSelectionPath();\n            clearSelection();\n            setSelectionPath(selectionPath);\n        }\n    }\n\n    /**\n     * Creates the domain node.\n     */\n    private DefaultMutableTreeNode createDomainNode(Dn dn, Token token) {\n        DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();\n        String label = dn.getDomain();\n        XNodeInfo userObject =\n                new XNodeInfo(Type.NONMBEAN, label, label, label);\n        node.setUserObject(userObject);\n        return node;\n    }\n\n    /**\n     * Creates the node corresponding to the whole Dn, i.e. an MBean.\n     */\n    private DefaultMutableTreeNode createDnNode(\n            Dn dn, Token token, XMBean xmbean) {\n        DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();\n        Object data = createNodeValue(xmbean, token);\n        String label = data.toString();\n        XNodeInfo userObject = new XNodeInfo(Type.MBEAN, data, label,\n                xmbean.getObjectName().toString());\n        node.setUserObject(userObject);\n        return node;\n    }\n\n    /**\n     * Creates the node corresponding to a subDn, i.e. a non-MBean\n     * intermediate node.\n     */\n    private DefaultMutableTreeNode createSubDnNode(Dn dn, Token token) {\n        DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();\n        String label = isKeyValueView() ? token.getTokenValue() : token.getValue();\n        XNodeInfo userObject =\n                new XNodeInfo(Type.NONMBEAN, label, label, token.getTokenValue());\n        node.setUserObject(userObject);\n        return node;\n    }\n\n    private Object createNodeValue(XMBean xmbean, Token token) {\n        String label = isKeyValueView() ? token.getTokenValue() : token.getValue();\n        xmbean.setText(label);\n        return xmbean;\n    }\n\n    private List<String> getOrderedKeyPropertyList() {\n        if (orderedKeyPropertyList == null) {\n            orderedKeyPropertyList = new ArrayList<String>();\n            String keyPropertyList = GlobalPreferences.sharedInstance().getOrderedKeyPropertyList();\n            if (keyPropertyList.isEmpty()) {\n                orderedKeyPropertyList.add(\"type\"); // NOI18N\n                orderedKeyPropertyList.add(\"j2eeType\"); // NOI18N\n            } else {\n                String[] tokens = keyPropertyList.split(\",\"); // NOI18N\n                for (String token : tokens) {\n                    orderedKeyPropertyList.add(token);\n                }\n            }\n        }\n        return orderedKeyPropertyList;\n    }\n\n    /**\n     * Parses the MBean ObjectName comma-separated properties string and puts\n     * the individual key/value pairs into the map. Key order in the properties\n     * string is preserved by the map.\n     */\n    private static Map<String, String> extractKeyValuePairs(\n            String props, ObjectName mbean) {\n        Map<String, String> map = new LinkedHashMap<String, String>();\n        int eq = props.indexOf(\"=\"); // NOI18N\n        while (eq != -1) {\n            String key = props.substring(0, eq);\n            String value = mbean.getKeyProperty(key);\n            map.put(key, value);\n            props = props.substring(key.length() + 1 + value.length());\n            if (props.startsWith(\",\")) { // NOI18N\n                props = props.substring(1);\n            }\n            eq = props.indexOf(\"=\"); // NOI18N\n        }\n        return map;\n    }\n\n    /**\n     * Returns the ordered key property list that will be used to build the\n     * MBean tree. If the \"com.sun.tools.jconsole.mbeans.keyPropertyList\" system\n     * property is not specified, then the ordered key property list used\n     * to build the MBean tree will be the one returned by the method\n     * ObjectName.getKeyPropertyListString() with \"type\" as first key,\n     * and \"j2eeType\" as second key, if present. If any of the keys specified\n     * in the comma-separated key property list does not apply to the given\n     * MBean then it will be discarded.\n     */\n    private static String getKeyPropertyListString(\n            ObjectName mbean, List<String> orderedKeyPropertyList) {\n        String props = mbean.getKeyPropertyListString();\n        Map<String, String> map = extractKeyValuePairs(props, mbean);\n        StringBuilder sb = new StringBuilder();\n        // Add the key/value pairs to the buffer following the\n        // key order defined by the \"orderedKeyPropertyList\"\n        for (String key : orderedKeyPropertyList) {\n            if (map.containsKey(key)) {\n                sb.append(key + \"=\" + map.get(key) + \",\"); // NOI18N\n                map.remove(key);\n            }\n        }\n        // Add the remaining key/value pairs to the buffer\n        for (Map.Entry<String, String> entry : map.entrySet()) {\n            sb.append(entry.getKey() + \"=\" + entry.getValue() + \",\"); // NOI18N\n        }\n        String orderedKeyPropertyListString = sb.toString();\n        orderedKeyPropertyListString = orderedKeyPropertyListString.substring(\n                0, orderedKeyPropertyListString.length() - 1);\n        return orderedKeyPropertyListString;\n    }\n\n    //\n    // Tree preferences\n    //\n    private static boolean treeView;\n    private static boolean treeViewInit = false;\n\n    private static boolean isTreeView() {\n        if (!treeViewInit) {\n            treeView = getTreeViewValue();\n            treeViewInit = true;\n        }\n        return treeView;\n    }\n\n    private static boolean getTreeViewValue() {\n        String tv = System.getProperty(\"treeView\"); // NOI18N\n        return ((tv == null) ? true : !(tv.equals(\"false\"))); // NOI18N\n    }\n\n    //\n    // MBean key-value preferences\n    //\n    private boolean keyValueView = Boolean.getBoolean(\"keyValueView\"); // NOI18N\n\n    private boolean isKeyValueView() {\n        return keyValueView;\n    }\n\n    //\n    // Utility classes\n    //\n    private static class ComparableDefaultMutableTreeNode\n            extends DefaultMutableTreeNode\n            implements Comparable<DefaultMutableTreeNode> {\n\n        public int compareTo(DefaultMutableTreeNode node) {\n            return (this.toString().compareTo(node.toString()));\n        }\n    }\n\n    private static class Dn implements Comparable<Dn> {\n\n        private ObjectName mbean;\n        private String domain;\n        private String keyPropertyList;\n        private String hashDn;\n        private List<Token> tokens = new ArrayList<Token>();\n\n        public Dn(ObjectName mbean, List<String> orderedKeyPropertyList) {\n            this.mbean = mbean;\n            this.domain = mbean.getDomain();\n            this.keyPropertyList = getKeyPropertyListString(mbean, orderedKeyPropertyList);\n\n            if (isTreeView()) {\n                // Tree view\n                Map<String, String> map =\n                        extractKeyValuePairs(keyPropertyList, mbean);\n                for (Map.Entry<String, String> entry : map.entrySet()) {\n                    tokens.add(new Token(\"key\", entry.getKey() + \"=\" + entry.getValue())); // NOI18N\n                }\n            } else {\n                // Flat view\n                tokens.add(new Token(\"key\", \"properties=\" + keyPropertyList)); // NOI18N\n            }\n\n            // Add the domain as the first token in the Dn\n            tokens.add(0, new Token(\"domain\", \"domain=\" + domain)); // NOI18N\n\n            // Reverse the Dn (from leaf to root)\n            Collections.reverse(tokens);\n\n            // Compute hash for Dn\n            computeHashDn();\n        }\n\n        public ObjectName getObjectName() {\n            return mbean;\n        }\n\n        public String getDomain() {\n            return domain;\n        }\n\n        public String getKeyPropertyList() {\n            return keyPropertyList;\n        }\n\n        public Token getToken(int index) {\n            return tokens.get(index);\n        }\n\n        public int getTokenCount() {\n            return tokens.size();\n        }\n\n        public String getHashDn() {\n            return hashDn;\n        }\n\n        public String getHashKey(Token token) {\n            final int begin = hashDn.indexOf(token.getTokenValue());\n            return hashDn.substring(begin, hashDn.length());\n        }\n\n        private void computeHashDn() {\n            if (tokens.isEmpty()) {\n                return;\n            }\n            final StringBuilder hdn = new StringBuilder();\n            for (int i = 0; i < tokens.size(); i++) {\n                hdn.append(tokens.get(i).getTokenValue());\n                hdn.append(\",\"); // NOI18N\n            }\n            hashDn = hdn.substring(0, hdn.length() - 1);\n        }\n\n        @Override\n        public String toString() {\n            return domain + \":\" + keyPropertyList; // NOI18N\n        }\n\n        public int compareTo(Dn dn) {\n            return this.toString().compareTo(dn.toString());\n        }\n    }\n\n    private static class Token {\n\n        private String tokenType;\n        private String tokenValue;\n        private String key;\n        private String value;\n\n        public Token(String tokenType, String tokenValue) {\n            this.tokenType = tokenType;\n            this.tokenValue = tokenValue;\n            buildKeyValue();\n        }\n\n        public String getTokenType() {\n            return tokenType;\n        }\n\n        public String getTokenValue() {\n            return tokenValue;\n        }\n\n        public String getKey() {\n            return key;\n        }\n\n        public String getValue() {\n            return value;\n        }\n\n        private void buildKeyValue() {\n            int index = tokenValue.indexOf(\"=\"); // NOI18N\n            if (index < 0) {\n                key = tokenValue;\n                value = tokenValue;\n            } else {\n                key = tokenValue.substring(0, index);\n                value = tokenValue.substring(index + 1, tokenValue.length());\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/XTreeRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans;\n\nimport java.awt.Component;\nimport javax.swing.ImageIcon;\nimport javax.swing.JTree;\nimport javax.swing.tree.DefaultMutableTreeNode;\nimport javax.swing.tree.DefaultTreeCellRenderer;\n\nclass XTreeRenderer extends DefaultTreeCellRenderer {\n    @Override\n    public Component getTreeCellRendererComponent(\n            JTree tree, Object value, boolean selected, boolean expanded,\n            boolean leaf, int row, boolean hasFocus) {\n        super.getTreeCellRendererComponent(\n                tree, value, selected, expanded, leaf, row, hasFocus);\n        Object userObject = ((DefaultMutableTreeNode) value).getUserObject();\n        if (userObject instanceof XNodeInfo) {\n            XNodeInfo node = (XNodeInfo) userObject;\n            setToolTipText(node.getToolTipText());\n            switch (node.getType()) {\n                case MBEAN:\n                    XMBean xmbean = (XMBean) node.getData();\n                    setIcon((ImageIcon) xmbean.getIcon());\n                    break;\n                case NONMBEAN:\n                    break;\n                case ATTRIBUTES:\n                case OPERATIONS:\n                case NOTIFICATIONS:\n                    setIcon(null);\n                    break;\n                case ATTRIBUTE:\n                case OPERATION:\n                case NOTIFICATION:\n                    setIcon(null);\n                    break;\n            }\n        } else {\n            setToolTipText(null);\n        }\n        return this;\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/options/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOptionsCategory_Name_MBeans=MBeans\nLBL_MBeansBrowser=MBeans Browser\nLBL_Plotters=&Plotters polling period\\:\nLBL_Sec=sec.\nLBL_Ordered_Key_Property_List=&Ordered key property list\\:\nMSG_CommaSeparatedListOfKeys=Comma-separated list of keys\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/options/GlobalPreferences.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans.options;\n\nimport org.graalvm.visualvm.core.datasupport.ComparableWeakReference;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.prefs.BackingStoreException;\nimport java.util.prefs.PreferenceChangeEvent;\nimport java.util.prefs.PreferenceChangeListener;\nimport java.util.prefs.Preferences;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Luis-Miguel Alventosa\n */\npublic class GlobalPreferences implements PreferenceChangeListener {\n    private final static Logger LOGGER = Logger.getLogger(\"org.graalvm.visualvm.modules.mbeans.options\"); // NOI18N\n\n    private static final String INT_KEY_PLOTTERS_POLL = \"PlottersPoll\"; // NOI18N\n    private static final int PLOTTERS_POLL_DEFAULT = 4;\n\n    private static final String STRING_KEY_ORDERED_KEY_PROPERTY_LIST = \"OrderedKeyPropertyList\"; // NOI18N\n    private static final String ORDERED_KEY_PROPERTY_LIST_DEFAULT = \"\"; // NOI18N\n\n    private final static GlobalPreferences INSTANCE = new GlobalPreferences();\n    private final Preferences prefs;\n    private final Map<String, Set<ComparableWeakReference<PreferenceChangeListener>>> listenerMap = new HashMap<String, Set<ComparableWeakReference<PreferenceChangeListener>>>();\n\n    private final ExecutorService dispatcher = Executors.newCachedThreadPool();\n    \n    private GlobalPreferences() {\n        prefs =  NbPreferences.forModule(GlobalPreferences.class);\n        prefs.addPreferenceChangeListener(this);\n    }\n    \n    public static GlobalPreferences sharedInstance() {\n        return INSTANCE;\n    }\n\n    public void preferenceChange(final PreferenceChangeEvent evt) {\n        synchronized(listenerMap) {\n            Set<ComparableWeakReference<PreferenceChangeListener>> set = listenerMap.get(evt.getKey());\n            if (set != null) {\n                final Set<PreferenceChangeListener> tmpListeners = new HashSet<PreferenceChangeListener>();\n                Collection<ComparableWeakReference<PreferenceChangeListener>> deadRefs = new ArrayList<ComparableWeakReference<PreferenceChangeListener>>();\n                for(ComparableWeakReference<PreferenceChangeListener> pclRef : set) {\n                    if (pclRef.get() != null) {\n                        tmpListeners.add(pclRef.get());\n                    } else {\n                        deadRefs.add(pclRef);\n                    }\n                }\n                set.removeAll(deadRefs);\n                dispatcher.submit(new Runnable() {\n                    public void run() {\n                        for(PreferenceChangeListener pcl : tmpListeners) {\n                            pcl.preferenceChange(evt);\n                        }\n                    }\n                });\n            }\n        }\n    }\n\n    public int getPlottersPoll() {\n        return getPollingInterval(INT_KEY_PLOTTERS_POLL, PLOTTERS_POLL_DEFAULT);\n    }\n    \n    public void setPlottersPoll(int value) {\n        setPollingInterval(INT_KEY_PLOTTERS_POLL, value);\n    }\n    \n    public void watchPlottersPoll(PreferenceChangeListener pcl) {\n        addListener(INT_KEY_PLOTTERS_POLL, pcl);\n    }\n    \n    public String getOrderedKeyPropertyList() {\n        synchronized(prefs) {\n            return prefs.get(STRING_KEY_ORDERED_KEY_PROPERTY_LIST, ORDERED_KEY_PROPERTY_LIST_DEFAULT);\n        }\n    }\n    \n    public void setOrderedKeyPropertyList(String value) {\n        synchronized(prefs) {\n            prefs.put(STRING_KEY_ORDERED_KEY_PROPERTY_LIST, value);\n        }\n    }\n    \n    public void watchOrderedKeyPropertyList(PreferenceChangeListener pcl) {\n        addListener(STRING_KEY_ORDERED_KEY_PROPERTY_LIST, pcl);\n    }\n\n    public boolean store() {\n        try {\n            prefs.sync();\n            return true;\n        } catch (BackingStoreException ex) {\n            LOGGER.log(Level.SEVERE, \"Error saving preferences\", ex); // NOI18N\n        }\n        return false;\n    }\n    \n    private void addListener(String property, PreferenceChangeListener pcl) {\n        synchronized(listenerMap) {\n            if (listenerMap.containsKey(property)) {\n                Set<ComparableWeakReference<PreferenceChangeListener>> set = listenerMap.get(property);\n                set.add(new ComparableWeakReference<PreferenceChangeListener>(pcl));\n            } else {\n                Set<ComparableWeakReference<PreferenceChangeListener>> set = new HashSet<ComparableWeakReference<PreferenceChangeListener>>();\n                set.add(new ComparableWeakReference<PreferenceChangeListener>(pcl));\n                listenerMap.put(property, set);\n            }\n        }\n    }\n    \n    private int getPollingInterval(String property, int deflt) {\n        int value = -1;\n        synchronized (prefs) {\n            value = prefs.getInt(property, -1);\n            if (value == -1) {\n                value = deflt;\n                prefs.putInt(property, value);\n            }\n        }\n        return value;\n    }\n    \n    private void setPollingInterval(String property, int value) {\n        synchronized(prefs) {\n            prefs.putInt(property, value);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/options/MBeansOptionsPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans.options;\n\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JSpinner;\nimport javax.swing.JTextField;\nimport javax.swing.SpinnerNumberModel;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class MBeansOptionsPanel extends JPanel {\n\n    private final MBeansOptionsPanelController controller;\n\n    private final ChangeListener changeListener = new ChangeListener() {\n        public void stateChanged(ChangeEvent e) {\n            controller.changed();\n        }\n    };\n\n\n    MBeansOptionsPanel(MBeansOptionsPanelController controller) {\n        this.controller = controller;\n        initComponents();\n        startTrackingChanges();\n    }\n\n    void load() {\n        // TODO read settings and initialize GUI\n        // Example:\n        // someCheckBox.setSelected(Preferences.userNodeForPackage(CorePanel.class).getBoolean(\"someFlag\", false));\n        // or for org.openide.util with API spec. version >= 7.4:\n        // someCheckBox.setSelected(NbPreferences.forModule(CorePanel.class).getBoolean(\"someFlag\", false));\n        // or:\n        // someTextField.setText(SomeSystemOption.getDefault().getSomeStringProperty());\n        plottersSpinner.setValue(GlobalPreferences.sharedInstance().getPlottersPoll());\n        propertyListField.setText(GlobalPreferences.sharedInstance().getOrderedKeyPropertyList());\n    }\n\n    void store() {\n        GlobalPreferences.sharedInstance().setPlottersPoll((Integer) plottersSpinner.getValue());\n        GlobalPreferences.sharedInstance().setOrderedKeyPropertyList(propertyListField.getText());\n        // TODO store modified settings\n        // Example:\n        // Preferences.userNodeForPackage(CorePanel.class).putBoolean(\"someFlag\", someCheckBox.isSelected());\n        // or for org.openide.util with API spec. version >= 7.4:\n        // NbPreferences.forModule(CorePanel.class).putBoolean(\"someFlag\", someCheckBox.isSelected());\n        // or:\n        // SomeSystemOption.getDefault().setSomeStringProperty(someTextField.getText());\n        GlobalPreferences.sharedInstance().store();\n    }\n\n    boolean valid() {\n        try {\n            return (Integer)plottersSpinner.getValue() > 0;\n        } catch (Exception e) {}\n        return false;\n    }\n\n\n    private void initComponents() {\n        GridBagConstraints c;\n\n        setLayout(new GridBagLayout());\n\n        // pollingSeparator\n        SectionSeparator pollingSeparator = UISupport.createSectionSeparator(\n                NbBundle.getMessage(MBeansOptionsPanel.class, \"LBL_MBeansBrowser\"));  // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 0;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 5, 0);\n        add(pollingSeparator, c);\n\n        // plottersLabel\n        JLabel plottersLabel = new JLabel();\n        Mnemonics.setLocalizedText(plottersLabel, NbBundle.getMessage(\n                                   MBeansOptionsPanel.class, \"LBL_Plotters\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 0);\n        add(plottersLabel, c);\n\n        // plottersSpinner\n        plottersSpinner = new JSpinner();\n        plottersLabel.setLabelFor(plottersSpinner);\n        plottersSpinner.setModel(new SpinnerNumberModel(3, 1, 99999, 1));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 4);\n        add(plottersSpinner, c);\n\n        // plottersUnits\n        JLabel plottersUnits = new JLabel();\n        Mnemonics.setLocalizedText(plottersUnits, NbBundle.getMessage(\n                MBeansOptionsPanel.class, \"LBL_Sec\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 3, 0);\n        add(plottersUnits, c);\n\n        // propertyListLabel\n        JLabel propertyListLabel = new JLabel();\n        Mnemonics.setLocalizedText(propertyListLabel, NbBundle.getMessage(\n                MBeansOptionsPanel.class, \"LBL_Ordered_Key_Property_List\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 2;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 0);\n        add(propertyListLabel, c);\n\n        // propertyListField\n        propertyListField = new JTextField();\n        propertyListLabel.setLabelFor(propertyListField);\n        propertyListField.setToolTipText(NbBundle.getMessage(\n                MBeansOptionsPanel.class, \"MSG_CommaSeparatedListOfKeys\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 2;\n        c.anchor = GridBagConstraints.WEST;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(propertyListField, c);\n\n        // filler\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 3;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        add(Spacer.create(), c);\n    }\n\n    private void startTrackingChanges() {\n        plottersSpinner.getModel().addChangeListener(changeListener);\n    }\n\n    \n    private JSpinner plottersSpinner;\n    private JTextField propertyListField;\n\n}\n"
  },
  {
    "path": "plugins/mbeans/src/org/graalvm/visualvm/modules/mbeans/options/MBeansOptionsPanelController.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.mbeans.options;\n\nimport org.graalvm.visualvm.core.options.UISupport;\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport javax.swing.JComponent;\nimport org.netbeans.spi.options.OptionsPanelController;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Luis-Miguel Alventosa\n */\n@OptionsPanelController.TopLevelRegistration(\n        id = \"MBeansOptions\",\n        categoryName = \"#OptionsCategory_Name_MBeans\",\n        iconBase = \"org/graalvm/visualvm/modules/mbeans/ui/resources/mbeans32.png\",\n        position = 4000\n)\npublic final class MBeansOptionsPanelController extends OptionsPanelController {\n\n    private MBeansOptionsPanel panel;\n    private JComponent component;\n    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);\n    private boolean changed;\n\n    public void update() {\n        getPanel().load();\n        changed = false;\n    }\n\n    public void applyChanges() {\n        getPanel().store();\n        changed = false;\n    }\n\n    public void cancel() {\n    // need not do anything special, if no changes have been persisted yet\n    }\n\n    public boolean isValid() {\n        return getPanel().valid();\n    }\n\n    public boolean isChanged() {\n        return changed;\n    }\n\n    public HelpCtx getHelpCtx() {\n        return null; // new HelpCtx(\"...ID\") if you have a help set\n    }\n\n    public JComponent getComponent(Lookup masterLookup) {\n        return getComponent();\n    }\n\n    public void addPropertyChangeListener(PropertyChangeListener l) {\n        pcs.addPropertyChangeListener(l);\n    }\n\n    public void removePropertyChangeListener(PropertyChangeListener l) {\n        pcs.removePropertyChangeListener(l);\n    }\n\n    private MBeansOptionsPanel getPanel() {\n        if (panel == null) {\n            panel = new MBeansOptionsPanel(this);\n        }\n        return panel;\n    }\n\n    private JComponent getComponent() {\n        if (component == null) {\n            component = UISupport.createScrollableContainer(getPanel());\n        }\n        return component;\n    }\n\n    void changed() {\n        if (!changed) {\n            changed = true;\n            pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);\n        }\n        pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);\n    }\n}\n"
  },
  {
    "path": "plugins/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"plugins-impl\" basedir=\"..\" xmlns:sproject=\"http://www.netbeans.org/ns/nb-module-suite-project/1\">\n    <property file=\"nbproject/private/platform-private.properties\"/>\n    <property file=\"nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-suite-project/1\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <sproject:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\"/>\n    <sproject:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/suite.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=b0c79715\nbuild.xml.script.CRC32=1bdb7168\nbuild.xml.stylesheet.CRC32=531c622b\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=b0c79715\nnbproject/build-impl.xml.script.CRC32=01096de6\nnbproject/build-impl.xml.stylesheet.CRC32=0f381476@2.73\nnbproject/platform.xml.data.CRC32=b0c79715\nnbproject/platform.xml.script.CRC32=6dcbd131\nnbproject/platform.xml.stylesheet.CRC32=45ddf0e0@2.73\n"
  },
  {
    "path": "plugins/nbproject/platform.properties",
    "content": "# Deprecated since 5.0u1; for compatibility with 5.0:\ndisabled.clusters=\nenabled.clusters=\\\n    platform,\\\n    profiler,\\\n    visualvm\nnbjdk.active=default\nnbplatform.active=VisualVM_100609-dd12ae64a19c\nsuite.dir=${basedir}\nnetbeans.dest.dir=${suite.dir}/visualvm\nharness.dir=${suite.dir}/../visualvm/netbeans/harness\n\n"
  },
  {
    "path": "plugins/nbproject/platform.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project name=\"platform\" default=\"download\" basedir=\"..\">\n    <condition property=\"download.required\">\n        <and>\n            <not>\n                <available file=\"${harness.dir}/suite.xml\"/>\n            </not>\n            <isset property=\"bootstrap.url\"/>\n            <isset property=\"autoupdate.catalog.url\"/>\n        </and>\n    </condition>\n    <target name=\"download\" if=\"download.required\">\n        <mkdir dir=\"${harness.dir}\"/>\n        <pathconvert pathsep=\"|\" property=\"download.clusters\">\n            <mapper type=\"flatten\"/>\n            <path path=\"${cluster.path}\"/>\n        </pathconvert>\n        <property name=\"disabled.modules\" value=\"\"/>\n        <pathconvert property=\"module.includes\" pathsep=\"\">\n            <mapper type=\"glob\" from=\"${basedir}${file.separator}*\" to=\"(?!^\\Q*\\E$)\"/>\n            <path>\n                <filelist files=\"${disabled.modules}\" dir=\".\"/>\n            </path>\n        </pathconvert>\n        <echo message=\"Downloading clusters ${download.clusters}\"/>\n        <property name=\"tasks.jar\" location=\"${java.io.tmpdir}/tasks.jar\"/>\n        <get src=\"${bootstrap.url}\" dest=\"${tasks.jar}\" usetimestamp=\"true\" verbose=\"true\"/>\n        <taskdef name=\"autoupdate\" classname=\"org.netbeans.nbbuild.AutoUpdate\" classpath=\"${tasks.jar}\"/>\n        <autoupdate installdir=\"${nbplatform.active.dir}\" updatecenter=\"${autoupdate.catalog.url}\">\n            <modules includes=\"${module.includes}.*\" clusters=\"${download.clusters}\"/>\n            <modules includes=\"org[.]netbeans[.]modules[.]apisupport[.]harness\" clusters=\"harness\"/>\n        </autoupdate>\n    </target>\n</project>\n"
  },
  {
    "path": "plugins/nbproject/project.properties",
    "content": "modules=\\\n    ${project.net.java.visualvm.modules.glassfish}:\\\n    ${project.org.graalvm.visualvm.modules.jconsole}:\\\n    ${project.org.graalvm.visualvm.modules.mbeans}:\\\n    ${project.com.sun.appserv.management}:\\\n    ${project.org.graalvm.visualvm.modules.extensions}:\\\n    ${project.org.graalvm.visualvm.modules.buffermonitor}:\\\n    ${project.org.graalvm.visualvm.modules.systray}:\\\n    ${project.jsyntaxpane.lib}:\\\n    ${project.org.graalvm.visualvm.modules.oqlsyntax}:\\\n    ${project.org.graalvm.visualvm.modules.tracer}:\\\n    ${project.org.graalvm.visualvm.modules.tracer.monitor}:\\\n    ${project.org.graalvm.visualvm.modules.saplugin}:\\\n    ${project.org.graalvm.visualvm.modules.security}:\\\n    ${project.org.graalvm.visualvm.modules.tracer.io}:\\\n    ${project.org.graalvm.visualvm.modules.tracer.jvmstat}:\\\n    ${project.org.graalvm.visualvm.modules.tracer.dynamic}:\\\n    ${project.org.graalvm.visualvm.modules.tracer.jvm}:\\\n    ${project.org.graalvm.visualvm.modules.threadinspect}:\\\n    ${project.org.graalvm.visualvm.modules.tracer.dtrace}:\\\n    ${project.org.graalvm.visualvm.modules.tracer.javafx}:\\\n    ${project.org.graalvm.visualvm.modules.tracer.swing}:\\\n    ${project.org.graalvm.visualvm.modules.tracer.collections}:\\\n    ${project.org.graalvm.visualvm.profiler.startup}:\\\n    ${project.org.graalvm.visualvm.modules.jolokia}:\\\n    ${project.org.graalvm.visualvm.modules.graaljs}\n#    ${project.org.graalvm.visualvm.jfr.streaming}:\\\nproject.com.sun.appserv.management=glassfish/amx-api\nproject.org.graalvm.visualvm.application.type.custom=extapptypes\nproject.org.graalvm.visualvm.modules.customtype.lib=extapptypes.lib\nproject.org.graalvm.visualvm.modules.graaljs=graaljs\nproject.org.graalvm.visualvm.modules.jolokia=jolokia\nproject.org.graalvm.visualvm.modules.jconsole=jconsole\nproject.org.graalvm.visualvm.modules.mbeans=mbeans\nproject.org.graalvm.visualvm.modules.oqlsyntax=oqlsyntax\nproject.org.graalvm.visualvm.modules.security=security\nproject.org.graalvm.visualvm.modules.systray=systray\nproject.org.graalvm.visualvm.modules.threadinspect=threadinspect\nproject.org.graalvm.visualvm.modules.tracer.collections=tracercollect\nproject.org.graalvm.visualvm.modules.tracer.dtrace=tracerdtrace\nproject.org.graalvm.visualvm.modules.tracer.dynamic=tracerdynamic\nproject.org.graalvm.visualvm.modules.tracer.jvm=tracerjvm\nproject.org.graalvm.visualvm.modules.tracer.swing=tracerswing\nproject.org.graalvm.visualvm.modules.tracer.javafx=tracerjavafx\nproject.net.java.visualvm.modules.glassfish=glassfish\nproject.jsyntaxpane.lib=jsyntaxpane-lib\nproject.org.graalvm.visualvm.modules.extensions=extensions\nproject.org.graalvm.visualvm.modules.saplugin=saplugin\nproject.org.graalvm.visualvm.modules.buffermonitor=buffermonitor\nproject.org.graalvm.visualvm.modules.tracer=tracer\nproject.org.graalvm.visualvm.modules.tracer.io=tracerio\nproject.org.graalvm.visualvm.modules.tracer.jvmstat=tracerjvmstat\nproject.org.graalvm.visualvm.modules.tracer.monitor=tracermonitor\nproject.org.graalvm.visualvm.profiler.startup=startupprofiler\nproject.org.graalvm.visualvm.jfr.streaming=jfr.streaming\n\nbranding.token=visualvm\nbranding.dir=none\n\nrun.args.extra=-J-Dsun.java2d.noddraw=true -J-Dsun.java2d.d3d=false\n"
  },
  {
    "path": "plugins/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project.suite</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-suite-project/1\">\n            <name>plugins</name>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/oqlsyntax/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.oqlsyntax\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.oqlsyntax.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/oqlsyntax/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.oqlsyntax/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/oqlsyntax/Bundle.properties\nOpenIDE-Module-Requires: org.graalvm.visualvm.editor.SyntaxSupport\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "plugins/oqlsyntax/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.oqlsyntax-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/oqlsyntax/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=ee04bb9c\nbuild.xml.script.CRC32=6838e77a\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=ee04bb9c\nnbproject/build-impl.xml.script.CRC32=da8406b8\nnbproject/build-impl.xml.stylesheet.CRC32=68e521fc@2.73\n"
  },
  {
    "path": "plugins/oqlsyntax/nbproject/project.properties",
    "content": "javac.source=1.6\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jaroslav Bachorik\n"
  },
  {
    "path": "plugins/oqlsyntax/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.oqlsyntax</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>jsyntaxpane.lib</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>0.9.4.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.oql</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/oqlsyntax/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/oqlsyntax/resources/README.txt",
    "content": "1. Get http://jflex.de/jflex-1.4.3.zip\n2. Generate the OqlLexer.java and place it to src/org/graalvm/visualvm/modules/oqlsyntax"
  },
  {
    "path": "plugins/oqlsyntax/resources/oql.flex",
    "content": "/*\r\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License\r\n *       at http://www.apache.org/licenses/LICENSE-2.0\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\npackage org.graalvm.visualvm.modules.oqlsyntax.lexers;\r\n\r\nimport jsyntaxpane.DefaultLexer;\r\nimport jsyntaxpane.Token;\r\nimport jsyntaxpane.TokenType;\r\n\r\n%%\r\n\r\n%public\r\n%class OqlLexer\r\n%extends DefaultLexer\r\n%final\r\n%unicode\r\n%char\r\n%type Token\r\n%caseless\r\n\r\n\r\n%{\r\n    /**\r\n     * Default constructor is needed as we will always call the yyreset\r\n     */\r\n    public OqlLexer() {\r\n        super();\r\n    }\r\n\r\n    /**\r\n     * Helper method to create and return a new Token from of TokenType\r\n     */\r\n    private Token token(TokenType type) {\r\n        return new Token(type, yychar, yylength());\r\n    }\r\n\r\n%}\r\n\r\n/* main character classes */\r\nLineTerminator = \\r|\\n|\\r\\n\r\nInputCharacter = [^\\r\\n]\r\n\r\nWhiteSpace = {LineTerminator} | [ \\t\\f]\r\n\r\n/* comments */\r\nComment = {EndOfLineComment}\r\n\r\nEndOfLineComment = \"--\" {InputCharacter}* {LineTerminator}?\r\n\r\n/* identifiers */\r\nIdentifier = [:jletter:][:jletterdigit:]*\r\n\r\n/* integer literals */\r\nDecIntegerLiteral = 0 | [1-9][0-9]*\r\n    \r\n/* floating point literals */        \r\nFloatLiteral  = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF]\r\n\r\nFLit1    = [0-9]+ \\. [0-9]* \r\nFLit2    = \\. [0-9]+ \r\nFLit3    = [0-9]+ \r\nExponent = [eE] [+-]? [0-9]+\r\n\r\n/* string and character literals */\r\nStringCharacter = [^\\r\\n\\\"\\\\]\r\nSingleCharacter = [^\\r\\n\\'\\\\]\r\n\r\nReserved = \r\n   \"SELECT\"              |\r\n   \"FROM\"                |\r\n   \"INSTANCEOF\"          |\r\n   \"WHERE\"\r\n%%\r\n\r\n<YYINITIAL> {\r\n\r\n  /* keywords */\r\n  {Reserved}                     { return token(TokenType.KEYWORD); }\r\n  \r\n  /* operators */\r\n\r\n  \"(\"                            |\r\n  \")\"                            |\r\n  \"{\"                            | \r\n  \"}\"                            | \r\n  \"[\"                            | \r\n  \"]\"                            | \r\n  \";\"                            | \r\n  \",\"                            | \r\n  \".\"                            | \r\n  \"@\"                            | \r\n  \"=\"                            | \r\n  \">\"                            | \r\n  \"<\"                            |\r\n  \"!\"                            | \r\n  \"~\"                            | \r\n  \"?\"                            | \r\n  \":\"                            { return token(TokenType.OPERATOR); } \r\n\r\n  /* string literal */\r\n  \\\"{StringCharacter}+\\\"         | \r\n\r\n  \\'{SingleCharacter}+\\          { return token(TokenType.STRING); } \r\n\r\n  /* numeric literals */\r\n\r\n  {DecIntegerLiteral}            |\r\n \r\n  {FloatLiteral}                 { return token(TokenType.NUMBER); }\r\n  \r\n  /* comments */\r\n  {Comment}                      { return token(TokenType.COMMENT); }\r\n\r\n  /* whitespace */\r\n  {WhiteSpace}+                  { /* skip */ }\r\n\r\n  /* identifiers */ \r\n  {Identifier}                   { return token(TokenType.IDENTIFIER); }\r\n\r\n}\r\n\r\n/* error fallback */\r\n.|\\n                             {  }\r\n<<EOF>>                          { return null; }\r\n\r\n"
  },
  {
    "path": "plugins/oqlsyntax/src/META-INF/services/jsyntaxpane.config.properties",
    "content": "#\n# OqlSyntaxKit specific jSyntaxPane settings\n#\nOqlSyntaxKit.Components = jsyntaxpane.components.PairsMarker, \\\n    jsyntaxpane.components.TokenMarker\n\nOqlSyntaxKit.TokenMarker.TokenTypes = IDENTIFIER, TYPE, TYPE2, TYPE3\n#\n# Performs single color selection (Default = false)\n#\nOqlSyntaxKit.SingleColorSelect = true\n#\n# DIsplaying of a right margin line.  If RightMarginColumn is 0, then no margin\n# will be displayed\nOqlSyntaxKit.RightMarginColumn = 80\nOqlSyntaxKit.RightMarginColor = 0xdddddd\nOqlSyntaxKit.Action.PARENTHISIS = jsyntaxpane.actions.PairAction, typed (\nOqlSyntaxKit.Action.BRACKETS = jsyntaxpane.actions.PairAction, typed [\nOqlSyntaxKit.Action.QUOTE = jsyntaxpane.actions.PairAction, typed '\nOqlSyntaxKit.Action.DBL_QUOTE = jsyntaxpane.actions.PairAction, typed \"\nOqlSyntaxKit.Action.CLOSE_CURLY = jsyntaxpane.actions.JUnindentAction, typed }\nOqlSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH\n# For completions, you have to define the Action (key to trigger completions):\n# JavaSyntaxKit.Action.COMPELTION = jsyntaxpane.actions.MapCompletionAction, control SPACE\nOqlSyntaxKit.Action.COMBO_COMPELTION = jsyntaxpane.actions.ComboCompletionAction, control SPACE\n# and then the specified completions map in the below file\nOqlSyntaxKit.Completions.File = jsyntaxpane.oqlsyntaxkit.completions\n#\n# These are the completions to be in the IntelliSense completion dialog\n# comma separated values.\n# Vertical bars: if there is one, it will position the cursor.  If there are\n# two, they will be start and end of selection\nOqlSyntaxKit.COMBO_COMPELTION.Items = select, from, instanceof, where, \\\n  heap., objectid(|), unique(\"|key|\"), \\\n  .forEachObject(|), .forEachClass(\"|callback|\"), .findClass(\"|className|\"), \\\n  .findObject(\"|objectid|\"), .classes(), .objects(\"|className|\"), \\\n  .isSubclassOf(\"|className|\"), .isSuperClassOf(\"|className|\"), .subclasses(), \\\n  .superclasses(), .finalizables(), .livepaths(), .roots, \\\n  classof(|object|), forEachReferrer(|), identical(|), \\\n  objectid(|object|), reachables(|), referrers(|object|), \\\n  referees(|object|), refers(|), sizeof(|), \\\n  toHtml(|), contains(|), count(|), \\\n  filter(|), length(|a|), map(|), max(|), \\\n  min(|), sort(|), top(|), \\\n  sum(|), toArray(|a|), unique(|), \\\n  .it, .index, .array, .result\n\n\n#\n# Other Java type actions for other languages:\n#\nOqlScriptSyntaxKit.Action.TOGGLE_COMMENTS = jsyntaxpane.actions.ToggleCommentsAction, control SLASH\n"
  },
  {
    "path": "plugins/oqlsyntax/src/META-INF/services/jsyntaxpane.kitsfortypes.properties",
    "content": "# This file contains the default content types and the SyntaxKit class names\n# that will be used for them.\n# The keys are content types, and the values are the fully qualified class \n# names\ntext/x-oql=org.graalvm.visualvm.modules.oqlsyntax.OqlSyntaxKit"
  },
  {
    "path": "plugins/oqlsyntax/src/META-INF/services/jsyntaxpane.oqlsyntaxkit.completions.properties",
    "content": "# This file contains the completions that will be used by the Java Syntax\n# editor kit.\n# The keys are the completion strings, and the values are the full expansion\n# of the text.  The | character will set the cursor to that location in\n# completion string\nse=select |\nfr=from |\nins=instanceof |\nwh=where |\n"
  },
  {
    "path": "plugins/oqlsyntax/src/org/graalvm/visualvm/modules/oqlsyntax/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=UI\nOpenIDE-Module-Long-Description=\\\n    Provides syntax highlighting, brace matching, intendation and simple code completion\nOpenIDE-Module-Name=OQL Syntax Support\nOpenIDE-Module-Short-Description=Enhanced UI for OQL query editor\n"
  },
  {
    "path": "plugins/oqlsyntax/src/org/graalvm/visualvm/modules/oqlsyntax/OQLSyntaxEditor.java",
    "content": "/*\n *  Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.oqlsyntax;\n\nimport javax.swing.JEditorPane;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.lib.profiler.oql.spi.*;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jaroslav Bachorik <jaroslav.bachorik@sun.com>\n */\n@ServiceProvider(service=OQLEditorImpl.class)\npublic class OQLSyntaxEditor extends OQLEditorImpl {\n\n    private class DocumentListenerEx implements DocumentListener {\n        @Override\n        public void insertUpdate(DocumentEvent e) {\n            if (e.getDocument().getLength() > 0) {\n                getValidationCallback(e.getDocument()).callback(true);\n            } else {\n                getValidationCallback(e.getDocument()).callback(false);\n            }\n        }\n\n        @Override\n        public void removeUpdate(DocumentEvent e) {\n            if (e.getDocument().getLength() > 0) {\n                getValidationCallback(e.getDocument()).callback(true);\n            } else {\n                getValidationCallback(e.getDocument()).callback(false);\n            }\n        }\n\n        @Override\n        public void changedUpdate(DocumentEvent e) {\n            if (e.getDocument().getLength() > 0) {\n                getValidationCallback(e.getDocument()).callback(true);\n            } else {\n                getValidationCallback(e.getDocument()).callback(false);\n            }\n        }\n    };\n\n    @Override\n    public JEditorPane getEditorPane() {\n        JEditorPane pane = new JEditorPane();\n        pane.setContentType(\"text/x-oql\");\n        pane.getDocument().addDocumentListener(new DocumentListenerEx());\n        return pane;\n    }\n}\n"
  },
  {
    "path": "plugins/oqlsyntax/src/org/graalvm/visualvm/modules/oqlsyntax/OqlLexer.java",
    "content": "/* The following code was generated by JFlex 1.4.1 on 10/12/09 8:42 PM */\n\n/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License\n *       at http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.graalvm.visualvm.modules.oqlsyntax;\n\nimport jsyntaxpane.DefaultLexer;\nimport jsyntaxpane.Token;\nimport jsyntaxpane.TokenType;\n\n\n/**\n * This class is a scanner generated by \n * <a href=\"http://www.jflex.de/\">JFlex</a> 1.4.1\n * on 10/12/09 8:42 PM from the specification file\n * <tt>/home/jb198685/projects/visualvm/plugins/jsyntaxpane-lib/external/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/oql.flex</tt>\n */\npublic final class OqlLexer extends DefaultLexer {\n\n  /** This character denotes the end of file */\n  public static final int YYEOF = -1;\n\n  /** initial size of the lookahead buffer */\n  private static final int ZZ_BUFFERSIZE = 16384;\n\n  /** lexical states */\n  public static final int YYINITIAL = 0;\n\n  /** \n   * Translates characters to character classes\n   */\n  private static final String ZZ_CMAP_PACKED = \n    \"\\11\\6\\1\\3\\1\\2\\1\\0\\1\\3\\1\\1\\16\\6\\4\\0\\1\\35\\1\\34\"+\n    \"\\1\\15\\1\\0\\1\\5\\2\\0\\1\\16\\1\\34\\1\\34\\1\\0\\1\\14\\1\\34\"+\n    \"\\1\\4\\1\\12\\1\\0\\1\\7\\11\\10\\1\\34\\1\\34\\1\\34\\1\\34\\1\\34\"+\n    \"\\1\\34\\1\\34\\1\\31\\1\\5\\1\\22\\1\\5\\1\\13\\1\\11\\1\\5\\1\\33\"+\n    \"\\1\\27\\2\\5\\1\\21\\1\\26\\1\\30\\1\\25\\2\\5\\1\\24\\1\\20\\1\\23\"+\n    \"\\2\\5\\1\\32\\3\\5\\1\\34\\1\\17\\1\\34\\1\\0\\1\\5\\1\\0\\1\\31\"+\n    \"\\1\\5\\1\\22\\1\\5\\1\\13\\1\\11\\1\\5\\1\\33\\1\\27\\2\\5\\1\\21\"+\n    \"\\1\\26\\1\\30\\1\\25\\2\\5\\1\\24\\1\\20\\1\\23\\2\\5\\1\\32\\3\\5\"+\n    \"\\1\\34\\1\\0\\1\\34\\1\\34\\41\\6\\2\\0\\4\\5\\4\\0\\1\\5\\2\\0\"+\n    \"\\1\\6\\7\\0\\1\\5\\4\\0\\1\\5\\5\\0\\27\\5\\1\\0\\37\\5\\1\\0\"+\n    \"\\u013f\\5\\31\\0\\162\\5\\4\\0\\14\\5\\16\\0\\5\\5\\11\\0\\1\\5\\21\\0\"+\n    \"\\130\\6\\5\\0\\23\\6\\12\\0\\1\\5\\13\\0\\1\\5\\1\\0\\3\\5\\1\\0\"+\n    \"\\1\\5\\1\\0\\24\\5\\1\\0\\54\\5\\1\\0\\46\\5\\1\\0\\5\\5\\4\\0\"+\n    \"\\202\\5\\1\\0\\4\\6\\3\\0\\105\\5\\1\\0\\46\\5\\2\\0\\2\\5\\6\\0\"+\n    \"\\20\\5\\41\\0\\46\\5\\2\\0\\1\\5\\7\\0\\47\\5\\11\\0\\21\\6\\1\\0\"+\n    \"\\27\\6\\1\\0\\3\\6\\1\\0\\1\\6\\1\\0\\2\\6\\1\\0\\1\\6\\13\\0\"+\n    \"\\33\\5\\5\\0\\3\\5\\15\\0\\4\\6\\14\\0\\6\\6\\13\\0\\32\\5\\5\\0\"+\n    \"\\13\\5\\16\\6\\7\\0\\12\\6\\4\\0\\2\\5\\1\\6\\143\\5\\1\\0\\1\\5\"+\n    \"\\10\\6\\1\\0\\6\\6\\2\\5\\2\\6\\1\\0\\4\\6\\2\\5\\12\\6\\3\\5\"+\n    \"\\2\\0\\1\\5\\17\\0\\1\\6\\1\\5\\1\\6\\36\\5\\33\\6\\2\\0\\3\\5\"+\n    \"\\60\\0\\46\\5\\13\\6\\1\\5\\u014f\\0\\3\\6\\66\\5\\2\\0\\1\\6\\1\\5\"+\n    \"\\20\\6\\2\\0\\1\\5\\4\\6\\3\\0\\12\\5\\2\\6\\2\\0\\12\\6\\21\\0\"+\n    \"\\3\\6\\1\\0\\10\\5\\2\\0\\2\\5\\2\\0\\26\\5\\1\\0\\7\\5\\1\\0\"+\n    \"\\1\\5\\3\\0\\4\\5\\2\\0\\1\\6\\1\\5\\7\\6\\2\\0\\2\\6\\2\\0\"+\n    \"\\3\\6\\11\\0\\1\\6\\4\\0\\2\\5\\1\\0\\3\\5\\2\\6\\2\\0\\12\\6\"+\n    \"\\4\\5\\15\\0\\3\\6\\1\\0\\6\\5\\4\\0\\2\\5\\2\\0\\26\\5\\1\\0\"+\n    \"\\7\\5\\1\\0\\2\\5\\1\\0\\2\\5\\1\\0\\2\\5\\2\\0\\1\\6\\1\\0\"+\n    \"\\5\\6\\4\\0\\2\\6\\2\\0\\3\\6\\13\\0\\4\\5\\1\\0\\1\\5\\7\\0\"+\n    \"\\14\\6\\3\\5\\14\\0\\3\\6\\1\\0\\11\\5\\1\\0\\3\\5\\1\\0\\26\\5\"+\n    \"\\1\\0\\7\\5\\1\\0\\2\\5\\1\\0\\5\\5\\2\\0\\1\\6\\1\\5\\10\\6\"+\n    \"\\1\\0\\3\\6\\1\\0\\3\\6\\2\\0\\1\\5\\17\\0\\2\\5\\2\\6\\2\\0\"+\n    \"\\12\\6\\1\\0\\1\\5\\17\\0\\3\\6\\1\\0\\10\\5\\2\\0\\2\\5\\2\\0\"+\n    \"\\26\\5\\1\\0\\7\\5\\1\\0\\2\\5\\1\\0\\5\\5\\2\\0\\1\\6\\1\\5\"+\n    \"\\6\\6\\3\\0\\2\\6\\2\\0\\3\\6\\10\\0\\2\\6\\4\\0\\2\\5\\1\\0\"+\n    \"\\3\\5\\4\\0\\12\\6\\1\\0\\1\\5\\20\\0\\1\\6\\1\\5\\1\\0\\6\\5\"+\n    \"\\3\\0\\3\\5\\1\\0\\4\\5\\3\\0\\2\\5\\1\\0\\1\\5\\1\\0\\2\\5\"+\n    \"\\3\\0\\2\\5\\3\\0\\3\\5\\3\\0\\10\\5\\1\\0\\3\\5\\4\\0\\5\\6\"+\n    \"\\3\\0\\3\\6\\1\\0\\4\\6\\11\\0\\1\\6\\17\\0\\11\\6\\11\\0\\1\\5\"+\n    \"\\7\\0\\3\\6\\1\\0\\10\\5\\1\\0\\3\\5\\1\\0\\27\\5\\1\\0\\12\\5\"+\n    \"\\1\\0\\5\\5\\4\\0\\7\\6\\1\\0\\3\\6\\1\\0\\4\\6\\7\\0\\2\\6\"+\n    \"\\11\\0\\2\\5\\4\\0\\12\\6\\22\\0\\2\\6\\1\\0\\10\\5\\1\\0\\3\\5\"+\n    \"\\1\\0\\27\\5\\1\\0\\12\\5\\1\\0\\5\\5\\2\\0\\1\\6\\1\\5\\7\\6\"+\n    \"\\1\\0\\3\\6\\1\\0\\4\\6\\7\\0\\2\\6\\7\\0\\1\\5\\1\\0\\2\\5\"+\n    \"\\4\\0\\12\\6\\22\\0\\2\\6\\1\\0\\10\\5\\1\\0\\3\\5\\1\\0\\27\\5\"+\n    \"\\1\\0\\20\\5\\4\\0\\6\\6\\2\\0\\3\\6\\1\\0\\4\\6\\11\\0\\1\\6\"+\n    \"\\10\\0\\2\\5\\4\\0\\12\\6\\22\\0\\2\\6\\1\\0\\22\\5\\3\\0\\30\\5\"+\n    \"\\1\\0\\11\\5\\1\\0\\1\\5\\2\\0\\7\\5\\3\\0\\1\\6\\4\\0\\6\\6\"+\n    \"\\1\\0\\1\\6\\1\\0\\10\\6\\22\\0\\2\\6\\15\\0\\60\\5\\1\\6\\2\\5\"+\n    \"\\7\\6\\4\\0\\10\\5\\10\\6\\1\\0\\12\\6\\47\\0\\2\\5\\1\\0\\1\\5\"+\n    \"\\2\\0\\2\\5\\1\\0\\1\\5\\2\\0\\1\\5\\6\\0\\4\\5\\1\\0\\7\\5\"+\n    \"\\1\\0\\3\\5\\1\\0\\1\\5\\1\\0\\1\\5\\2\\0\\2\\5\\1\\0\\4\\5\"+\n    \"\\1\\6\\2\\5\\6\\6\\1\\0\\2\\6\\1\\5\\2\\0\\5\\5\\1\\0\\1\\5\"+\n    \"\\1\\0\\6\\6\\2\\0\\12\\6\\2\\0\\2\\5\\42\\0\\1\\5\\27\\0\\2\\6\"+\n    \"\\6\\0\\12\\6\\13\\0\\1\\6\\1\\0\\1\\6\\1\\0\\1\\6\\4\\0\\2\\6\"+\n    \"\\10\\5\\1\\0\\42\\5\\6\\0\\24\\6\\1\\0\\2\\6\\4\\5\\4\\0\\10\\6\"+\n    \"\\1\\0\\44\\6\\11\\0\\1\\6\\71\\0\\42\\5\\1\\0\\5\\5\\1\\0\\2\\5\"+\n    \"\\1\\0\\7\\6\\3\\0\\4\\6\\6\\0\\12\\6\\6\\0\\6\\5\\4\\6\\106\\0\"+\n    \"\\46\\5\\12\\0\\51\\5\\7\\0\\132\\5\\5\\0\\104\\5\\5\\0\\122\\5\\6\\0\"+\n    \"\\7\\5\\1\\0\\77\\5\\1\\0\\1\\5\\1\\0\\4\\5\\2\\0\\7\\5\\1\\0\"+\n    \"\\1\\5\\1\\0\\4\\5\\2\\0\\47\\5\\1\\0\\1\\5\\1\\0\\4\\5\\2\\0\"+\n    \"\\37\\5\\1\\0\\1\\5\\1\\0\\4\\5\\2\\0\\7\\5\\1\\0\\1\\5\\1\\0\"+\n    \"\\4\\5\\2\\0\\7\\5\\1\\0\\7\\5\\1\\0\\27\\5\\1\\0\\37\\5\\1\\0\"+\n    \"\\1\\5\\1\\0\\4\\5\\2\\0\\7\\5\\1\\0\\47\\5\\1\\0\\23\\5\\16\\0\"+\n    \"\\11\\6\\56\\0\\125\\5\\14\\0\\u026c\\5\\2\\0\\10\\5\\12\\0\\32\\5\\5\\0\"+\n    \"\\113\\5\\3\\0\\3\\5\\17\\0\\15\\5\\1\\0\\4\\5\\3\\6\\13\\0\\22\\5\"+\n    \"\\3\\6\\13\\0\\22\\5\\2\\6\\14\\0\\15\\5\\1\\0\\3\\5\\1\\0\\2\\6\"+\n    \"\\14\\0\\64\\5\\40\\6\\3\\0\\1\\5\\3\\0\\2\\5\\1\\6\\2\\0\\12\\6\"+\n    \"\\41\\0\\3\\6\\2\\0\\12\\6\\6\\0\\130\\5\\10\\0\\51\\5\\1\\6\\126\\0\"+\n    \"\\35\\5\\3\\0\\14\\6\\4\\0\\14\\6\\12\\0\\12\\6\\36\\5\\2\\0\\5\\5\"+\n    \"\\u038b\\0\\154\\5\\224\\0\\234\\5\\4\\0\\132\\5\\6\\0\\26\\5\\2\\0\\6\\5\"+\n    \"\\2\\0\\46\\5\\2\\0\\6\\5\\2\\0\\10\\5\\1\\0\\1\\5\\1\\0\\1\\5\"+\n    \"\\1\\0\\1\\5\\1\\0\\37\\5\\2\\0\\65\\5\\1\\0\\7\\5\\1\\0\\1\\5\"+\n    \"\\3\\0\\3\\5\\1\\0\\7\\5\\3\\0\\4\\5\\2\\0\\6\\5\\4\\0\\15\\5\"+\n    \"\\5\\0\\3\\5\\1\\0\\7\\5\\17\\0\\4\\6\\32\\0\\5\\6\\20\\0\\2\\5\"+\n    \"\\23\\0\\1\\5\\13\\0\\4\\6\\6\\0\\6\\6\\1\\0\\1\\5\\15\\0\\1\\5\"+\n    \"\\40\\0\\22\\5\\36\\0\\15\\6\\4\\0\\1\\6\\3\\0\\6\\6\\27\\0\\1\\5\"+\n    \"\\4\\0\\1\\5\\2\\0\\12\\5\\1\\0\\1\\5\\3\\0\\5\\5\\6\\0\\1\\5\"+\n    \"\\1\\0\\1\\5\\1\\0\\1\\5\\1\\0\\4\\5\\1\\0\\3\\5\\1\\0\\7\\5\"+\n    \"\\3\\0\\3\\5\\5\\0\\5\\5\\26\\0\\44\\5\\u0e81\\0\\3\\5\\31\\0\\11\\5\"+\n    \"\\6\\6\\1\\0\\5\\5\\2\\0\\5\\5\\4\\0\\126\\5\\2\\0\\2\\6\\2\\0\"+\n    \"\\3\\5\\1\\0\\137\\5\\5\\0\\50\\5\\4\\0\\136\\5\\21\\0\\30\\5\\70\\0\"+\n    \"\\20\\5\\u0200\\0\\u19b6\\5\\112\\0\\u51a6\\5\\132\\0\\u048d\\5\\u0773\\0\\u2ba4\\5\\u215c\\0\"+\n    \"\\u012e\\5\\2\\0\\73\\5\\225\\0\\7\\5\\14\\0\\5\\5\\5\\0\\1\\5\\1\\6\"+\n    \"\\12\\5\\1\\0\\15\\5\\1\\0\\5\\5\\1\\0\\1\\5\\1\\0\\2\\5\\1\\0\"+\n    \"\\2\\5\\1\\0\\154\\5\\41\\0\\u016b\\5\\22\\0\\100\\5\\2\\0\\66\\5\\50\\0\"+\n    \"\\15\\5\\3\\0\\20\\6\\20\\0\\4\\6\\17\\0\\2\\5\\30\\0\\3\\5\\31\\0\"+\n    \"\\1\\5\\6\\0\\5\\5\\1\\0\\207\\5\\2\\0\\1\\6\\4\\0\\1\\5\\13\\0\"+\n    \"\\12\\6\\7\\0\\32\\5\\4\\0\\1\\5\\1\\0\\32\\5\\12\\0\\132\\5\\3\\0\"+\n    \"\\6\\5\\2\\0\\6\\5\\2\\0\\6\\5\\2\\0\\3\\5\\3\\0\\2\\5\\3\\0\"+\n    \"\\2\\5\\22\\0\\3\\6\\4\\0\";\n\n  /** \n   * Translates characters to character classes\n   */\n  private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);\n\n  /** \n   * Translates DFA states to action switch labels.\n   */\n  private static final int [] ZZ_ACTION = zzUnpackAction();\n\n  private static final String ZZ_ACTION_PACKED_0 =\n    \"\\1\\0\\1\\1\\1\\2\\1\\1\\1\\3\\2\\4\\1\\3\\1\\5\"+\n    \"\\2\\1\\3\\3\\1\\5\\1\\6\\1\\0\\1\\4\\2\\0\\1\\3\"+\n    \"\\2\\0\\3\\3\\2\\6\\2\\0\\1\\3\\2\\7\\3\\3\\1\\10\"+\n    \"\\11\\3\";\n\n  private static int [] zzUnpackAction() {\n    int [] result = new int[46];\n    int offset = 0;\n    offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);\n    return result;\n  }\n\n  private static int zzUnpackAction(String packed, int offset, int [] result) {\n    int i = 0;       /* index in packed string  */\n    int j = offset;  /* index in unpacked array */\n    int l = packed.length();\n    while (i < l) {\n      int count = packed.charAt(i++);\n      int value = packed.charAt(i++);\n      do result[j++] = value; while (--count > 0);\n    }\n    return j;\n  }\n\n\n  /** \n   * Translates a state to a row index in the transition table\n   */\n  private static final int [] ZZ_ROWMAP = zzUnpackRowMap();\n\n  private static final String ZZ_ROWMAP_PACKED_0 =\n    \"\\0\\0\\0\\36\\0\\74\\0\\132\\0\\170\\0\\226\\0\\264\\0\\322\"+\n    \"\\0\\360\\0\\u010e\\0\\u012c\\0\\u014a\\0\\u0168\\0\\u0186\\0\\36\\0\\u01a4\"+\n    \"\\0\\226\\0\\36\\0\\u01c2\\0\\u01e0\\0\\u01fe\\0\\u021c\\0\\u023a\\0\\u0258\"+\n    \"\\0\\u0276\\0\\u0294\\0\\u02b2\\0\\36\\0\\u02d0\\0\\u02ee\\0\\u030c\\0\\36\"+\n    \"\\0\\u023a\\0\\u032a\\0\\u0348\\0\\u0366\\0\\170\\0\\u0384\\0\\u03a2\\0\\u03c0\"+\n    \"\\0\\u03de\\0\\u03fc\\0\\u041a\\0\\u0438\\0\\u0456\\0\\u0474\";\n\n  private static int [] zzUnpackRowMap() {\n    int [] result = new int[46];\n    int offset = 0;\n    offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);\n    return result;\n  }\n\n  private static int zzUnpackRowMap(String packed, int offset, int [] result) {\n    int i = 0;  /* index in packed string  */\n    int j = offset;  /* index in unpacked array */\n    int l = packed.length();\n    while (i < l) {\n      int high = packed.charAt(i++) << 16;\n      result[j++] = high | packed.charAt(i++);\n    }\n    return j;\n  }\n\n  /** \n   * The transition table of the DFA\n   */\n  private static final int [] ZZ_TRANS = zzUnpackTrans();\n\n  private static final String ZZ_TRANS_PACKED_0 =\n    \"\\1\\2\\3\\3\\1\\4\\1\\5\\1\\2\\1\\6\\1\\7\\1\\10\"+\n    \"\\1\\11\\1\\5\\1\\2\\1\\12\\1\\13\\1\\2\\1\\14\\6\\5\"+\n    \"\\1\\15\\2\\5\\1\\16\\1\\5\\1\\17\\1\\3\\37\\0\\3\\3\"+\n    \"\\31\\0\\1\\3\\4\\0\\1\\20\\36\\0\\5\\5\\1\\0\\1\\5\"+\n    \"\\4\\0\\14\\5\\11\\0\\2\\21\\1\\22\\1\\23\\1\\24\\31\\0\"+\n    \"\\2\\7\\1\\22\\1\\23\\1\\24\\27\\0\\5\\5\\1\\0\\1\\5\"+\n    \"\\4\\0\\4\\5\\1\\25\\7\\5\\11\\0\\2\\23\\25\\0\\1\\26\"+\n    \"\\2\\0\\12\\26\\1\\0\\1\\26\\1\\0\\16\\26\\1\\27\\2\\0\"+\n    \"\\13\\27\\2\\0\\16\\27\\5\\0\\5\\5\\1\\0\\1\\30\\4\\0\"+\n    \"\\14\\5\\7\\0\\5\\5\\1\\0\\1\\5\\4\\0\\10\\5\\1\\31\"+\n    \"\\3\\5\\7\\0\\5\\5\\1\\0\\1\\5\\4\\0\\13\\5\\1\\32\"+\n    \"\\2\\0\\1\\20\\1\\33\\1\\34\\33\\20\\7\\0\\2\\23\\1\\22\"+\n    \"\\1\\0\\1\\24\\26\\0\\1\\35\\2\\0\\2\\36\\3\\0\\1\\35\"+\n    \"\\26\\0\\5\\5\\1\\0\\1\\5\\4\\0\\5\\5\\1\\37\\6\\5\"+\n    \"\\2\\0\\1\\26\\2\\0\\12\\26\\1\\40\\1\\26\\1\\0\\16\\26\"+\n    \"\\1\\27\\2\\0\\13\\27\\2\\0\\15\\27\\1\\41\\5\\0\\5\\5\"+\n    \"\\1\\0\\1\\5\\4\\0\\1\\5\\1\\42\\12\\5\\7\\0\\5\\5\"+\n    \"\\1\\0\\1\\5\\4\\0\\1\\43\\13\\5\\7\\0\\5\\5\\1\\0\"+\n    \"\\1\\44\\4\\0\\14\\5\\4\\0\\1\\34\\42\\0\\2\\36\\34\\0\"+\n    \"\\2\\36\\1\\22\\31\\0\\5\\5\\1\\0\\1\\5\\4\\0\\6\\5\"+\n    \"\\1\\45\\5\\5\\7\\0\\5\\5\\1\\0\\1\\46\\4\\0\\14\\5\"+\n    \"\\7\\0\\5\\5\\1\\0\\1\\5\\4\\0\\3\\5\\1\\47\\10\\5\"+\n    \"\\7\\0\\5\\5\\1\\0\\1\\5\\4\\0\\4\\5\\1\\50\\7\\5\"+\n    \"\\7\\0\\5\\5\\1\\0\\1\\5\\4\\0\\2\\5\\1\\51\\11\\5\"+\n    \"\\7\\0\\5\\5\\1\\0\\1\\5\\4\\0\\11\\5\\1\\52\\2\\5\"+\n    \"\\7\\0\\5\\5\\1\\0\\1\\45\\4\\0\\14\\5\\7\\0\\5\\5\"+\n    \"\\1\\0\\1\\5\\4\\0\\3\\5\\1\\45\\10\\5\\7\\0\\5\\5\"+\n    \"\\1\\0\\1\\5\\4\\0\\10\\5\\1\\53\\3\\5\\7\\0\\5\\5\"+\n    \"\\1\\0\\1\\5\\4\\0\\2\\5\\1\\54\\11\\5\\7\\0\\5\\5\"+\n    \"\\1\\0\\1\\55\\4\\0\\14\\5\\7\\0\\5\\5\\1\\0\\1\\5\"+\n    \"\\4\\0\\5\\5\\1\\56\\6\\5\\7\\0\\4\\5\\1\\45\\1\\0\"+\n    \"\\1\\5\\4\\0\\14\\5\\2\\0\";\n\n  private static int [] zzUnpackTrans() {\n    int [] result = new int[1170];\n    int offset = 0;\n    offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);\n    return result;\n  }\n\n  private static int zzUnpackTrans(String packed, int offset, int [] result) {\n    int i = 0;       /* index in packed string  */\n    int j = offset;  /* index in unpacked array */\n    int l = packed.length();\n    while (i < l) {\n      int count = packed.charAt(i++);\n      int value = packed.charAt(i++);\n      value--;\n      do result[j++] = value; while (--count > 0);\n    }\n    return j;\n  }\n\n\n  /* error codes */\n  private static final int ZZ_UNKNOWN_ERROR = 0;\n  private static final int ZZ_NO_MATCH = 1;\n  private static final int ZZ_PUSHBACK_2BIG = 2;\n\n  /* error messages for the codes above */\n  private static final String ZZ_ERROR_MSG[] = {\n    \"Unkown internal scanner error\",\n    \"Error: could not match input\",\n    \"Error: pushback value was too large\"\n  };\n\n  /**\n   * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>\n   */\n  private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();\n\n  private static final String ZZ_ATTRIBUTE_PACKED_0 =\n    \"\\1\\0\\1\\11\\14\\1\\1\\11\\1\\1\\1\\0\\1\\11\\2\\0\"+\n    \"\\1\\1\\2\\0\\4\\1\\1\\11\\2\\0\\1\\1\\1\\11\\16\\1\";\n\n  private static int [] zzUnpackAttribute() {\n    int [] result = new int[46];\n    int offset = 0;\n    offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);\n    return result;\n  }\n\n  private static int zzUnpackAttribute(String packed, int offset, int [] result) {\n    int i = 0;       /* index in packed string  */\n    int j = offset;  /* index in unpacked array */\n    int l = packed.length();\n    while (i < l) {\n      int count = packed.charAt(i++);\n      int value = packed.charAt(i++);\n      do result[j++] = value; while (--count > 0);\n    }\n    return j;\n  }\n\n  /** the input device */\n  private java.io.Reader zzReader;\n\n  /** the current state of the DFA */\n  private int zzState;\n\n  /** the current lexical state */\n  private int zzLexicalState = YYINITIAL;\n\n  /** this buffer contains the current text to be matched and is\n      the source of the yytext() string */\n  private char zzBuffer[] = new char[ZZ_BUFFERSIZE];\n\n  /** the textposition at the last accepting state */\n  private int zzMarkedPos;\n\n  /** the textposition at the last state to be included in yytext */\n  private int zzPushbackPos;\n\n  /** the current text position in the buffer */\n  private int zzCurrentPos;\n\n  /** startRead marks the beginning of the yytext() string in the buffer */\n  private int zzStartRead;\n\n  /** endRead marks the last character in the buffer, that has been read\n      from input */\n  private int zzEndRead;\n\n  /** number of newlines encountered up to the start of the matched text */\n  private int yyline;\n\n  /** the number of characters up to the start of the matched text */\n  private int yychar;\n\n  /**\n   * the number of characters from the last newline up to the start of the \n   * matched text\n   */\n  private int yycolumn;\n\n  /** \n   * zzAtBOL == true <=> the scanner is currently at the beginning of a line\n   */\n  private boolean zzAtBOL = true;\n\n  /** zzAtEOF == true <=> the scanner is at the EOF */\n  private boolean zzAtEOF;\n\n  /* user code: */\n    /**\n     * Default constructor is needed as we will always call the yyreset\n     */\n    public OqlLexer() {\n        super();\n    }\n\n    /**\n     * Helper method to create and return a new Token from of TokenType\n     */\n    private Token token(TokenType type) {\n        return new Token(type, yychar, yylength());\n    }\n\n\n\n  /**\n   * Creates a new scanner\n   * There is also a java.io.InputStream version of this constructor.\n   *\n   * @param   in  the java.io.Reader to read input from.\n   */\n  public OqlLexer(java.io.Reader in) {\n    this.zzReader = in;\n  }\n\n  /**\n   * Creates a new scanner.\n   * There is also java.io.Reader version of this constructor.\n   *\n   * @param   in  the java.io.Inputstream to read input from.\n   */\n  public OqlLexer(java.io.InputStream in) {\n    this(new java.io.InputStreamReader(in));\n  }\n\n  /** \n   * Unpacks the compressed character translation table.\n   *\n   * @param packed   the packed character translation table\n   * @return         the unpacked character translation table\n   */\n  private static char [] zzUnpackCMap(String packed) {\n    char [] map = new char[0x10000];\n    int i = 0;  /* index in packed string  */\n    int j = 0;  /* index in unpacked array */\n    while (i < 1788) {\n      int  count = packed.charAt(i++);\n      char value = packed.charAt(i++);\n      do map[j++] = value; while (--count > 0);\n    }\n    return map;\n  }\n\n\n  /**\n   * Refills the input buffer.\n   *\n   * @return      <code>false</code>, iff there was new input.\n   * \n   * @exception   java.io.IOException  if any I/O-Error occurs\n   */\n  private boolean zzRefill() throws java.io.IOException {\n\n    /* first: make room (if you can) */\n    if (zzStartRead > 0) {\n      System.arraycopy(zzBuffer, zzStartRead,\n                       zzBuffer, 0,\n                       zzEndRead-zzStartRead);\n\n      /* translate stored positions */\n      zzEndRead-= zzStartRead;\n      zzCurrentPos-= zzStartRead;\n      zzMarkedPos-= zzStartRead;\n      zzPushbackPos-= zzStartRead;\n      zzStartRead = 0;\n    }\n\n    /* is the buffer big enough? */\n    if (zzCurrentPos >= zzBuffer.length) {\n      /* if not: blow it up */\n      char newBuffer[] = new char[zzCurrentPos*2];\n      System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length);\n      zzBuffer = newBuffer;\n    }\n\n    /* finally: fill the buffer with new input */\n    int numRead = zzReader.read(zzBuffer, zzEndRead,\n                                            zzBuffer.length-zzEndRead);\n\n    if (numRead < 0) {\n      return true;\n    }\n    else {\n      zzEndRead+= numRead;\n      return false;\n    }\n  }\n\n    \n  /**\n   * Closes the input stream.\n   */\n  public final void yyclose() throws java.io.IOException {\n    zzAtEOF = true;            /* indicate end of file */\n    zzEndRead = zzStartRead;  /* invalidate buffer    */\n\n    if (zzReader != null)\n      zzReader.close();\n  }\n\n\n  /**\n   * Resets the scanner to read from a new input stream.\n   * Does not close the old reader.\n   *\n   * All internal variables are reset, the old input stream \n   * <b>cannot</b> be reused (internal buffer is discarded and lost).\n   * Lexical state is set to <tt>ZZ_INITIAL</tt>.\n   *\n   * @param reader   the new input stream \n   */\n  public final void yyreset(java.io.Reader reader) {\n    zzReader = reader;\n    zzAtBOL  = true;\n    zzAtEOF  = false;\n    zzEndRead = zzStartRead = 0;\n    zzCurrentPos = zzMarkedPos = zzPushbackPos = 0;\n    yyline = yychar = yycolumn = 0;\n    zzLexicalState = YYINITIAL;\n  }\n\n\n  /**\n   * Returns the current lexical state.\n   */\n  public final int yystate() {\n    return zzLexicalState;\n  }\n\n\n  /**\n   * Enters a new lexical state\n   *\n   * @param newState the new lexical state\n   */\n  public final void yybegin(int newState) {\n    zzLexicalState = newState;\n  }\n\n\n  /**\n   * Returns the text matched by the current regular expression.\n   */\n  public final String yytext() {\n    return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead );\n  }\n\n\n  /**\n   * Returns the character at position <tt>pos</tt> from the \n   * matched text. \n   * \n   * It is equivalent to yytext().charAt(pos), but faster\n   *\n   * @param pos the position of the character to fetch. \n   *            A value from 0 to yylength()-1.\n   *\n   * @return the character at position pos\n   */\n  public final char yycharat(int pos) {\n    return zzBuffer[zzStartRead+pos];\n  }\n\n\n  /**\n   * Returns the length of the matched text region.\n   */\n  public final int yylength() {\n    return zzMarkedPos-zzStartRead;\n  }\n\n\n  /**\n   * Reports an error that occured while scanning.\n   *\n   * In a wellformed scanner (no or only correct usage of \n   * yypushback(int) and a match-all fallback rule) this method \n   * will only be called with things that \"Can't Possibly Happen\".\n   * If this method is called, something is seriously wrong\n   * (e.g. a JFlex bug producing a faulty scanner etc.).\n   *\n   * Usual syntax/scanner level error handling should be done\n   * in error fallback rules.\n   *\n   * @param   errorCode  the code of the errormessage to display\n   */\n  private void zzScanError(int errorCode) {\n    String message;\n    try {\n      message = ZZ_ERROR_MSG[errorCode];\n    }\n    catch (ArrayIndexOutOfBoundsException e) {\n      message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR];\n    }\n\n    throw new Error(message);\n  } \n\n\n  /**\n   * Pushes the specified amount of characters back into the input stream.\n   *\n   * They will be read again by then next call of the scanning method\n   *\n   * @param number  the number of characters to be read again.\n   *                This number must not be greater than yylength()!\n   */\n  public void yypushback(int number)  {\n    if ( number > yylength() )\n      zzScanError(ZZ_PUSHBACK_2BIG);\n\n    zzMarkedPos -= number;\n  }\n\n\n  /**\n   * Resumes scanning until the next regular expression is matched,\n   * the end of input is encountered or an I/O-Error occurs.\n   *\n   * @return      the next token\n   * @exception   java.io.IOException  if any I/O-Error occurs\n   */\n  public Token yylex() throws java.io.IOException {\n    int zzInput;\n    int zzAction;\n\n    // cached fields:\n    int zzCurrentPosL;\n    int zzMarkedPosL;\n    int zzEndReadL = zzEndRead;\n    char [] zzBufferL = zzBuffer;\n    char [] zzCMapL = ZZ_CMAP;\n\n    int [] zzTransL = ZZ_TRANS;\n    int [] zzRowMapL = ZZ_ROWMAP;\n    int [] zzAttrL = ZZ_ATTRIBUTE;\n\n    while (true) {\n      zzMarkedPosL = zzMarkedPos;\n\n      yychar+= zzMarkedPosL-zzStartRead;\n\n      zzAction = -1;\n\n      zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;\n  \n      zzState = zzLexicalState;\n\n\n      zzForAction: {\n        while (true) {\n    \n          if (zzCurrentPosL < zzEndReadL)\n            zzInput = zzBufferL[zzCurrentPosL++];\n          else if (zzAtEOF) {\n            zzInput = YYEOF;\n            break zzForAction;\n          }\n          else {\n            // store back cached positions\n            zzCurrentPos  = zzCurrentPosL;\n            zzMarkedPos   = zzMarkedPosL;\n            boolean eof = zzRefill();\n            // get translated positions and possibly new buffer\n            zzCurrentPosL  = zzCurrentPos;\n            zzMarkedPosL   = zzMarkedPos;\n            zzBufferL      = zzBuffer;\n            zzEndReadL     = zzEndRead;\n            if (eof) {\n              zzInput = YYEOF;\n              break zzForAction;\n            }\n            else {\n              zzInput = zzBufferL[zzCurrentPosL++];\n            }\n          }\n          int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];\n          if (zzNext == -1) break zzForAction;\n          zzState = zzNext;\n\n          int zzAttributes = zzAttrL[zzState];\n          if ( (zzAttributes & 1) == 1 ) {\n            zzAction = zzState;\n            zzMarkedPosL = zzCurrentPosL;\n            if ( (zzAttributes & 8) == 8 ) break zzForAction;\n          }\n\n        }\n      }\n\n      // store back cached position\n      zzMarkedPos = zzMarkedPosL;\n\n      switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {\n        case 7: \n          { return token(TokenType.STRING);\n          }\n        case 9: break;\n        case 8: \n          { return token(TokenType.KEYWORD);\n          }\n        case 10: break;\n        case 5: \n          { return token(TokenType.OPERATOR);\n          }\n        case 11: break;\n        case 2: \n          { /* skip */\n          }\n        case 12: break;\n        case 4: \n          { return token(TokenType.NUMBER);\n          }\n        case 13: break;\n        case 3: \n          { return token(TokenType.IDENTIFIER);\n          }\n        case 14: break;\n        case 6: \n          { return token(TokenType.COMMENT);\n          }\n        case 15: break;\n        case 1: \n          { \n          }\n        case 16: break;\n        default: \n          if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {\n            zzAtEOF = true;\n              {\n                return null;\n              }\n          } \n          else {\n            zzScanError(ZZ_NO_MATCH);\n          }\n      }\n    }\n  }\n\n\n}\n"
  },
  {
    "path": "plugins/oqlsyntax/src/org/graalvm/visualvm/modules/oqlsyntax/OqlSyntaxKit.java",
    "content": "/*\n * Copyright 2008 Ayman Al-Sairafi ayman.alsairafi@gmail.com\n * \n * Licensed under the Apache License, Version 2.0 (the \"License\"); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License \n *       at http://www.apache.org/licenses/LICENSE-2.0 \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an \"AS IS\" BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License.  \n */\npackage org.graalvm.visualvm.modules.oqlsyntax;\n\nimport jsyntaxpane.DefaultSyntaxKit;\n\n/**\n *\n * @author Ayman Al-Sairafi\n */\npublic class OqlSyntaxKit extends DefaultSyntaxKit {\n\n    public OqlSyntaxKit() {\n        super(new OqlLexer());\n    }\n}\n"
  },
  {
    "path": "plugins/saplugin/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.saplugin\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project SAPlugin.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/saplugin/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: true\nOpenIDE-Module: org.graalvm.visualvm.modules.saplugin/2\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/saplugin/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/saplugin/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "plugins/saplugin/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.saplugin-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/saplugin/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=3999dcf2\nbuild.xml.script.CRC32=14b0729f\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=3999dcf2\nnbproject/build-impl.xml.script.CRC32=e8e935b2\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "plugins/saplugin/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nauxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=8\nauxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=80\nauxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=default\njavac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Poonam Bajaj\nnbm.needs.restart=true\nmodule.javadoc.packages=org.graalvm.visualvm.modules.saplugin.*\n"
  },
  {
    "path": "plugins/saplugin/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.saplugin</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.coredump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.8.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/saplugin/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/Agent.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport java.io.File;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Proxy;\nimport java.net.MalformedURLException;\nimport java.util.Map;\nimport java.util.HashMap;\nimport org.openide.util.Exceptions;\n\nclass Agent {\n\n    private static Map<DataSource,Agent> agentMap = new HashMap();\n    private static Map<File,SAWrapper> classloaderMap = new HashMap();\n    \n    \n    static Agent createAgent(File jdkHome,File saJarFile) throws ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException  {\n       /*synchronized (agentMap) {\n            Agent agent = agentMap.get(saJarFile);\n            if (agent == null) {\n                agent = new Agent(jdkHome,saJarFile);\n                agentMap.put(saJarFile,agent);\n            }\n            return agent;\n        }\n      */\n        Agent agent = new Agent(jdkHome,saJarFile);\n        return agent;\n    }\n    \n    private SAWrapper saClassLoader = null;\n    //private final SAObject bugspotAgent;\n    private final SAObject hotspotAgent;\n    private VM vm;\n    private Arguments args;\n    private Object saListener = null;\n\n    private Agent(File jdkHome,File saJarFile) throws ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException {\n     //   saClassLoader = classloaderMap.get(jdkHome);\n     //   if (saClassLoader == null) {\n            saClassLoader = new SAWrapper(jdkHome,saJarFile);\n      //      classloaderMap.put(jdkHome, saClassLoader);\n      //  }\n        hotspotAgent = new SAObject(saClassLoader.HotspotAgent().newInstance());\n    }\n\n    boolean attach(int pid) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {\n        hotspotAgent.invoke(\"attach\",pid);  // NOI18N\n        return true; //isJavaMode();\n    }\n\n    boolean attach(String executable,String coredump) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {\n        hotspotAgent.invoke(\"attach\",executable,coredump);  // NOI18N\n        return true;\n    }\n    \n    boolean attach(String remoteServer) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {\n        hotspotAgent.invoke(\"attach\",remoteServer); // NOI18N\n        return true;\n    }\n    \n    void detach() throws IllegalAccessException, InvocationTargetException {\n        hotspotAgent.invoke(\"detach\");  // NOI18N\n    }\n\n    VM getVM() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {\n        if (vm == null) {\n            Class vmClass = saClassLoader.VM();\n            Object saVM = vmClass.getMethod(\"getVM\").invoke(null);  // NOI18N\n            vm = new VM(saVM);\n        }\n        return vm;\n    }\n    \n    Arguments getArguments() throws ClassNotFoundException {\n        if (args == null) {\n            args = new Arguments(saClassLoader.Arguments());\n        }\n        return args;\n    }\n    \n    SAObject getHeapHprofBinWriter() throws ClassNotFoundException, InstantiationException, IllegalAccessException {\n        return new SAObject(saClassLoader.HeapHprofBinWriter().newInstance());\n    }\n       \n    \n/*    private boolean isJavaMode() throws IllegalAccessException, InvocationTargetException {\n        Boolean b = (Boolean) hotspotAgent.invoke(\"isJavaMode\");    // NOI18N\n        return b.booleanValue();\n    }  \n    */\n/////////////////////////////////////////////////\n    \n    \n    JavaStackTracePanel createJavaStackTracePanel() throws ClassNotFoundException, InstantiationException, IllegalAccessException {\n        return new JavaStackTracePanel(saClassLoader.JavaStackTracePanel().newInstance());\n    }\n    JavaThreadsPanel createJavaThreadsPanel() throws ClassNotFoundException, InstantiationException, IllegalAccessException {\n        return new JavaThreadsPanel(saClassLoader.JavaThreadsPanel().newInstance());\n    }\n    CodeViewerPanel createCodeViewerPanel() throws ClassNotFoundException, InstantiationException, IllegalAccessException {\n        return new CodeViewerPanel(saClassLoader.CodeViewerPanel().newInstance());\n    }\n    FindPointerPanel createFindPointerPanel() throws ClassNotFoundException, InstantiationException, IllegalAccessException {\n        return new FindPointerPanel(saClassLoader.FindPanel().newInstance());\n    }\n    FindInHeapPanel createFindInHeapPanel() throws ClassNotFoundException, InstantiationException, IllegalAccessException {\n        return new FindInHeapPanel(saClassLoader.FindInHeapPanel().newInstance());\n    }\n    FindInCodeCachePanel createFindInCodeCachePanel() throws ClassNotFoundException, InstantiationException, IllegalAccessException {\n        return new FindInCodeCachePanel(saClassLoader.FindInCodeCachePanel().newInstance());\n    }\n    \n    \n    Inspector createOopInspector() throws ClassNotFoundException, InstantiationException, IllegalAccessException {\n        return new Inspector(saClassLoader.OopInspector().newInstance());\n    }\n    Inspector createOopInspector(Object root) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException {\n        Constructor con = saClassLoader.OopInspector().getDeclaredConstructor(new Class[] { saClassLoader.SimpleTreeNode()});\n        Object instance = null;\n        try {\n            instance = con.newInstance(root);\n        } catch (IllegalArgumentException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (InvocationTargetException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n        \n        return new Inspector(instance);\n    }\n    OopTreeNodeAdapter createOopTreeNodeAdapter(Object oopObject, Object fieldID) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException {\n        //return new OopTreeNodeAdapter(saClassLoader.OopTreeNodeAdapter().newInstance());\n        Constructor con = saClassLoader.OopTreeNodeAdapter().getDeclaredConstructor(new Class[] { saClassLoader.Oop(), saClassLoader.FieldIdentifier() });\n        Object instance = null;\n        try {\n            instance = con.newInstance(new Object[]{oopObject, fieldID});\n        } catch (IllegalArgumentException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (InvocationTargetException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n        return new OopTreeNodeAdapter(instance);\n    }\n    \n    Object SAListener(SAModelImpl model) throws ClassNotFoundException, InstantiationException, IllegalAccessException {\n      if (saListener == null) {\n            saListener =  Proxy.newProxyInstance(saClassLoader.loader, new Class[] {saClassLoader.SAListener()}, new ProxyListener(model));\n      }\n        return saListener;\n    }\n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/Arguments.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.lang.reflect.InvocationTargetException;\n\n\nclass Arguments {\n\n    private final Class arguments;\n\n    Arguments(Class args) {\n        arguments = args;\n    }\n\n    String getJVMFlags() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {\n        return (String) arguments.getMethod(\"getJVMFlags\").invoke(null);    // NOI18N\n    }\n\n    String getJVMArgs()  throws NoSuchMethodException, IllegalAccessException, InvocationTargetException{\n        return (String) arguments.getMethod(\"getJVMArgs\").invoke(null); // NOI18N\n    }\n\n    String getJavaCommand()  throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {\n        return (String) arguments.getMethod(\"getJavaCommand\").invoke(null); // NOI18N\n    }\n\n\n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Tools\nOpenIDE-Module-Long-Description=\\\n    SAPlugin makes key features of Serviceability Agent (SA) available in VisualVM. \\\n    Serviceability Agent is a snapshot debugger for Hotspot VM. \\\n    It can be used to explore Java Objects present in Java Heap, and Hotspot Data Structures, both in live processes as well as in core files.\nOpenIDE-Module-Name=SAPlugin\nOpenIDE-Module-Short-Description=Serviceability Agent Plugin\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/CodeViewerPanel.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.lang.reflect.InvocationTargetException;\nimport javax.swing.JPanel;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author poonam\n */\npublic class CodeViewerPanel {\n    public final SAObject codeViewer;\n\n    public CodeViewerPanel(Object panel) {\n        this.codeViewer = new SAObject(panel);\n               \n    }\n    public JPanel getPanel() {\n        return (JPanel)codeViewer.instance;\n    }\n    public void setListener(Object o) {\n        try {\n            codeViewer.invoke(\"addPanelListener\", o);\n        } catch (IllegalAccessException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (InvocationTargetException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/FindInCodeCachePanel.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.lang.reflect.InvocationTargetException;\nimport javax.swing.JPanel;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author poonam\n */\npublic class FindInCodeCachePanel {\n    public final SAObject findInCodeCache;\n\n    public FindInCodeCachePanel(Object panel) {\n        this.findInCodeCache = new SAObject(panel);\n        \n    }\n    public JPanel getPanel() {\n        return (JPanel)findInCodeCache.instance;\n    }\n    public void setListener(Object o) {\n        try {\n            findInCodeCache.invoke(\"addPanelListener\", o);\n        } catch (IllegalAccessException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (InvocationTargetException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/FindInHeapPanel.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.lang.reflect.InvocationTargetException;\nimport javax.swing.JPanel;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author poonam\n */\npublic class FindInHeapPanel {\n    public final SAObject findInHeapPanel;\n\n    public FindInHeapPanel(Object panel) {\n        this.findInHeapPanel = new SAObject(panel);\n        \n    }\n    public JPanel getPanel() {\n        return (JPanel)findInHeapPanel.instance;\n    }\n    public void setListener(Object o) {\n        try {\n            findInHeapPanel.invoke(\"addPanelListener\", o);\n        } catch (IllegalAccessException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (InvocationTargetException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/FindPointerPanel.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.lang.reflect.InvocationTargetException;\nimport javax.swing.JPanel;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author poonam\n */\npublic class FindPointerPanel {\n    public final SAObject findPanel;\n\n    public FindPointerPanel(Object panel) {\n        this.findPanel = new SAObject(panel);\n        \n    }\n    public JPanel getPanel() {\n        return (JPanel)findPanel.instance;\n    }\n    public void setListener(Object o) {\n        try {\n            findPanel.invoke(\"addPanelListener\", o);\n        } catch (IllegalAccessException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (InvocationTargetException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/Inspector.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.lang.reflect.InvocationTargetException;\nimport javax.swing.JPanel;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author poonam\n */\npublic class Inspector {\n    public final SAObject inspector;\n\n    public Inspector(Object panel) {\n        this.inspector = new SAObject(panel);              \n    }\n    public JPanel getPanel() {\n        return (JPanel)inspector.instance;\n    }\n    public void setListener(Object o) {\n        try {\n            inspector.invoke(\"addPanelListener\", o);\n        } catch (IllegalAccessException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (InvocationTargetException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/Installer.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport org.graalvm.visualvm.tools.sa.SaModelFactory;\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\npublic class Installer extends ModuleInstall {\n\n    @Override\n    public void restored() {\n        SaModelFactory.getDefault().registerProvider(new SAModelProvider());\n        new SAViewProvider().initialize();\n    }\n\n    @Override\n    public void uninstalled() {\n        SAViewProvider.unregister();        \n    }\n\n    @Override\n    public boolean closing() {\n        SAView.isClosing = true;\n        return super.closing();\n    }\n\n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/JavaStackTracePanel.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.lang.reflect.InvocationTargetException;\nimport javax.swing.JPanel;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author poonam\n */\npublic class JavaStackTracePanel {\n    private SAObject stackTracePanel;\n\n    public JavaStackTracePanel(Object panel) {\n        this.stackTracePanel = new SAObject(panel);\n        \n    }\n    public JPanel getPanel() {\n        return (JPanel)stackTracePanel.instance;\n    }\n    public void setJavaThread(Object thread) {\n        try {\n            stackTracePanel.invoke(\"setJavaThread\", thread);\n        } catch (IllegalAccessException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (InvocationTargetException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/JavaThreadsPanel.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.lang.reflect.InvocationTargetException;\nimport javax.swing.JPanel;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author poonam\n */\npublic class JavaThreadsPanel {\n    private SAObject threadsPanel;\n\n    public JavaThreadsPanel(Object panel) {\n        this.threadsPanel = new SAObject(panel);\n       // threadsPanel.invoke(\"addListener\", )\n        \n    }\n    public JPanel getPanel() {\n        return (JPanel)threadsPanel.instance;\n    }\n    public void setListener(Object o) {\n        try {\n            threadsPanel.invoke(\"addPanelListener\", o);\n        } catch (IllegalAccessException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (InvocationTargetException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n    }\n    public void removeListener(Object o) {\n        try {\n            threadsPanel.invoke(\"removePanelListener\", o);\n        } catch (IllegalAccessException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (InvocationTargetException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/OopInspectorView.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport java.awt.BorderLayout;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\n\n/**\n *\n * @author poonam\n */\npublic class OopInspectorView extends JComponent {\n\n        private JPanel inspectorPanel;\n        private String caption;\n        private int position;\n        private SAModelImpl model;\n        private DataViewComponent.DetailsView detailView;\n        \n        public OopInspectorView(SAModelImpl model, String caption, int position) {\n            this.model = model;\n            this.caption = caption;\n            this.position = position;\n            detailView = null;\n            initComponents();\n        }\n        public DataViewComponent.DetailsView getDetailsView() {\n            if (detailView == null) {\n                detailView = new DataViewComponent.DetailsView(caption, null, position, this, null);\n            }\n            return detailView;\n        }\n        public void refresh(Object oop) {\n            this.removeAll();\n            Inspector inspector = null;\n            if (oop != null)\n                inspector = model.createOopInspector(model.createOopTreeNodeAdapter(oop, null).treeNode.instance);\n            else\n                inspector = model.createOopInspector();\n\n            inspector.setListener(model.getSAListener());\n            inspectorPanel = inspector.getPanel();\n            add(inspectorPanel, BorderLayout.CENTER);\n            \n        }\n        private void initComponents() {\n            setLayout(new BorderLayout());\n        }\n        public void remove() {\n            this.removeAll();\n        }\n        \n    }\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/OopTreeNodeAdapter.java",
    "content": "/*\n * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.lang.reflect.InvocationTargetException;\nimport javax.swing.JPanel;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author poonam\n */\npublic class OopTreeNodeAdapter {\n    public final SAObject treeNode;\n\n    public OopTreeNodeAdapter(Object node) {\n        this.treeNode = new SAObject(node);\n               \n    }\n    public JPanel getPanel() {\n        return (JPanel)treeNode.instance;\n    }\n    public void setListener(Object o) {\n        try {\n            treeNode.invoke(\"addPanelListener\", o);\n        } catch (IllegalAccessException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (InvocationTargetException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/ProxyListener.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.lang.reflect.*;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author poonam\n */\npublic class ProxyListener implements java.lang.reflect.InvocationHandler {    \n    SAModelImpl model = null;\n  \n    public ProxyListener(SAModelImpl model) {\n          this.model = model;\n    }\n    \n    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {\n        Object result = null;\n        try {\n            System.out.print(\"begin method \"\n             + m.getName() + \"(\");\n            for(int i=0; i<args.length; i++) {\n                if(i>0) System.out.print(\",\");\n                    System.out.print(\" \" +\n                    args[i].toString());\n         }\n         System.out.println(\" )\");\n         if (m.getName().equals(\"showThreadOopInspector\")) {\n             showThreadOopInspector(args[0]);\n         } else if (m.getName().equals(\"showInspector\")) {\n            showInspector(args[0]);\n         } else if (m.getName().equals(\"showThreadStackMemory\")) {\n             showStackMemoryPanel(args[0]);\n\n         } else if (m.getName().equals(\"showThreadInfo\")) {\n\n         } else if (m.getName().equals(\"showJavaStackTrace\")) {\n            showJavaStackTrace(args[0]);\n\n         } else if (m.getName().equals(\"showCodeViewer\")) {\n\n         } else if (m.getName().equals(\"showLiveness\")) {\n            showLivenessPanel(args[0]);\n         }         \n         \n         } catch (Exception e) {\n           throw new RuntimeException\n           (\"unexpected invocation exception: \" +\n                                  e.getMessage());\n         } finally {\n             System.out.println(\n             \"end method \" + m.getName());\n         }\n         return result;\n     }\n    void showJavaStackTrace(Object thread) {\n\n        SAView view = model.getView();\n        view.updateStackTraceView(thread);\n    }\n    void showLivenessPanel(Object o) {\n        NotifyDescriptor nd = new NotifyDescriptor.Message(\"Not yet implemented\", NotifyDescriptor.INFORMATION_MESSAGE) ;\n        DialogDisplayer.getDefault().notify(nd);\n    }\n\n    void showStackMemoryPanel(Object thread) {\n        NotifyDescriptor nd = new NotifyDescriptor.Message(\"Not yet implemented\", NotifyDescriptor.INFORMATION_MESSAGE) ;\n        DialogDisplayer.getDefault().notify(nd);\n    }\n\n    void showThreadOopInspector(Object o) {       \n        SAObject thread = new SAObject(o);     \n        SAObject threadObj = null;\n        try {\n            threadObj = thread.invokeSA(\"getThreadObj\");\n        } catch (IllegalAccessException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (InvocationTargetException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n  \n        showInspector(threadObj.instance);\n    }\n    public void showInspector(Object oopObject) {        \n        SAView view = model.getView();\n        view.updateOopInspectorView(oopObject);\n    }\n  }\n\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAModelImpl.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport org.graalvm.visualvm.tools.sa.SaModel;\nimport java.io.File;\nimport java.lang.reflect.InvocationTargetException;\nimport java.net.MalformedURLException;\nimport java.util.Properties;\nimport org.openide.ErrorManager;\nimport org.openide.util.Exceptions;\n\n\npublic class SAModelImpl extends SaModel {\n    private Agent agent;\n    private int pid;\n    String executable;\n    String core;\n    private Properties sysProp;\n    private String jvmFlags;\n    private String jvmArgs;\n    private String commandLine;\n    private SAView view;\n    \n    \n    SAModelImpl(File jdkHome,File sajar,int id) throws ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException, InvocationTargetException, NoSuchMethodException {\n        agent = Agent.createAgent(jdkHome,sajar);\n        pid = id;\n        //readData();\n    }\n    \n    SAModelImpl(File jdkHome,File sajar,File execFile,File coreFile) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, MalformedURLException, NoSuchMethodException {\n        agent = Agent.createAgent(jdkHome,sajar);\n        executable = execFile.getAbsolutePath();\n        core = coreFile.getAbsolutePath();\n        //readData();\n    }\n    \n    public Properties getSystemProperties() {\n        return sysProp;\n    }\n    \n    public boolean takeHeapDump(String file){\n        try {\n            synchronized (agent) {\n                try {\n                    if (attach()) {\n                        SAObject hprofWrite = agent.getHeapHprofBinWriter();\n                        hprofWrite.invoke(\"write\",file);    // NOI18N\n                        return true;\n                    }\n                    } finally {\n                        agent.detach();\n                    }\n            }\n        } catch (Exception ex) {\n            Throwable e = ex.getCause();\n            ErrorManager.getDefault().notify(e == null ? ex : e);\n        }\n        return false;\n    }\n    \n    public String takeThreadDump(){\n        try {\n            synchronized (agent) {\n                try {\n                    if (attach()) {\n                        return new StackTrace(agent.getVM()).getStackTrace();\n                    }\n                } finally {\n                    agent.detach();\n                }\n            }\n        } catch (Exception ex) {\n            Throwable e = ex.getCause();\n            ErrorManager.getDefault().notify(e == null ? ex : e);\n        }\n        return null;\n    }\n    \n    public String getJvmFlags() {\n        return jvmFlags;\n    }\n    \n    public String getJvmArgs() {\n        return jvmArgs;\n    }\n    \n    public String getJavaCommand() {\n        return commandLine;\n    }    \n  \n    public boolean attach() throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {\n        if (core == null) {\n            return agent.attach(pid);\n        }\n        return agent.attach(executable,core);\n    }\n    public void detach() throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {\n        agent.detach();\n    }\n\n    public Agent getAgent() {\n        return agent;\n    }\n    public void readData() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {\n        synchronized (agent) {\n            //try {\n            //    if (attach()) {\n                    Arguments args = agent.getArguments();\n                    jvmFlags = args.getJVMFlags();\n                    jvmArgs = args.getJVMArgs();\n                    commandLine = args.getJavaCommand();\n                    sysProp = (Properties)agent.getVM().getSystemProperties().clone();\n             //   }\n          //  } finally {\n          //      agent.detach();\n          //  }\n        }\n    }\n    \n//------------------------------------------------------------//\n    \n    public Inspector createOopInspector() {\n        Inspector obj = null;\n        try {\n        obj = agent.createOopInspector();\n        } catch (Exception e) {\n        }\n        return obj;\n    }\n    public Inspector createOopInspector(Object o) {\n        Inspector obj = null;\n        try {\n        obj = agent.createOopInspector(o);\n        } catch (Exception e) {\n        }\n        return obj;\n    }\n    \n    public JavaStackTracePanel createJavaStackTracePanel() {\n        JavaStackTracePanel obj = null;\n        try {\n        obj = agent.createJavaStackTracePanel();\n        } catch (Exception e) {\n        }\n        return obj;\n    }\n    public JavaThreadsPanel createJavaThreadsPanel() {\n        JavaThreadsPanel obj = null;\n        try {\n        obj = agent.createJavaThreadsPanel();\n        } catch (Exception e) {\n        }\n        return obj;\n    }\n    public CodeViewerPanel createCodeViewerPanel() {\n        CodeViewerPanel obj = null;\n        try {\n        obj = agent.createCodeViewerPanel();\n        } catch (Exception e) {\n        }\n        return obj;\n    }\n    public FindPointerPanel createFindPointerPanel() {\n        FindPointerPanel obj = null;\n        try {\n        obj = agent.createFindPointerPanel();\n        } catch (Exception e) {\n        }\n        return obj;\n    }\n    public FindInHeapPanel createFindInHeapPanel() {\n        FindInHeapPanel obj = null;\n        try {\n            obj = agent.createFindInHeapPanel();\n        } catch (Exception e) {\n        }\n        return obj;\n    }\n\n    public FindInCodeCachePanel createFindInCodeCachePanel() {\n        FindInCodeCachePanel obj = null;\n        try {\n            obj = agent.createFindInCodeCachePanel();\n        } catch (Exception e) {\n        }\n        return obj;\n    }\n            \n    public OopTreeNodeAdapter createOopTreeNodeAdapter(Object oopObject, Object fieldID) {\n        OopTreeNodeAdapter obj = null;\n        try {\n        obj = agent.createOopTreeNodeAdapter(oopObject, fieldID);\n        } catch (Exception e) {\n        }\n        return obj;\n    }\n    public Object getSAListener() {\n        Object obj = null;\n        try {\n            obj = agent.SAListener(this);\n        } catch (ClassNotFoundException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (InstantiationException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (IllegalAccessException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n        return obj;\n    }\n\n    public SAView getView() {\n        return view;\n    }\n\n    public void setView(SAView view) {\n        this.view = view;\n    }\n    \n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAModelProvider.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory;\nimport org.graalvm.visualvm.tools.sa.SaModel;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n\npublic class SAModelProvider extends AbstractModelProvider<SaModel, DataSource>  {\n    private static final Logger LOGGER = Logger.getLogger(SAModelProvider.class.getName());\n    \n    private static final String SA_JAR = \"lib/sa-jdi.jar\";  // NOI18N\n    \n    \n    SAModelProvider() {\n        \n    }\n    \n    public SaModel createModelFor(DataSource ds) {\n        if (ds instanceof Application) {\n            Application app = (Application) ds;\n            if (Host.LOCALHOST.equals(app.getHost())) {\n                JvmJvmstatModel jvmstat = JvmJvmstatModelFactory.getJvmstatModelFor(app);\n                File jdkHome = new File(jvmstat.getJavaHome());\n                if (\"jre\".equals(jdkHome.getName())) {\n                    jdkHome = jdkHome.getParentFile();\n                }\n                File saJar = getSaJar(jdkHome);\n\n                if (saJar == null) {\n                    return null;\n                }\n                try {\n                    return new SAModelImpl(jdkHome,saJar,app.getPid());\n                } catch (Exception ex) {\n                    LOGGER.log(Level.INFO, \"Error getting SA agent\", ex);   // NOI18N\n                }                \n            }\n        } else if (ds instanceof CoreDump) {\n            CoreDump coredump = (CoreDump) ds;\n            File executable = new File(coredump.getExecutable());\n            File coreFile = coredump.getFile();\n            if (executable.exists() && coreFile.exists()) {\n                File jdkHome = executable.getParentFile().getParentFile();\n                File saJar = getSaJar(jdkHome);\n                \n                if (saJar == null) {\n                    return null;\n                }\n                try {\n                    return new SAModelImpl(jdkHome,saJar,executable,coreFile);\n                } catch (Exception ex) {\n                    LOGGER.log(Level.INFO, \"Unable to retrieve SA agent\", ex);  // NOI18N\n                }\n               \n            }\n        }\n        return null;\n    }\n    \n    static File getSaJar(File jdkHome) {\n        File saJar = new File(jdkHome,SA_JAR);\n        try {\n            if (saJar.exists()) {\n                return saJar.getCanonicalFile();\n            }\n            saJar = new File( SA_JAR);  //Changed this\n            if (saJar.exists()) {\n                return saJar.getCanonicalFile();\n            }\n        } catch (IOException ex) {\n            LOGGER.log(Level.INFO, saJar.getPath(), ex);            \n        }\n        return null;\n    }\n    \n      \n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAObject.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n\n\nclass SAObject {\n    final Object instance;\n    Map<String,List<Method>> methodCache;\n    private static Map<Class,Class> primitiveTypes;\n\n    static {\n        primitiveTypes = new HashMap();\n        primitiveTypes.put(Integer.class,Integer.TYPE);\n    }\n\n    SAObject(Object i) {\n        instance = i;\n        if (i != null) {\n            methodCache = new HashMap();\n            Method[] methods = i.getClass().getMethods();\n            for (int j = 0; j < methods.length; j++) {\n                Method method = methods[j];\n                String name = method.getName();\n                int pars = method.getParameterTypes().length;\n                String id = methodId(name,pars);\n                List<Method> mlist = Collections.singletonList(method);\n                List<Method> oldlist = methodCache.put(id,mlist);\n                if (oldlist != null) {\n                    List<Method> unitedList = new ArrayList(mlist);\n                    unitedList.addAll(oldlist);\n                    methodCache.put(id,unitedList);\n                }\n            }\n        }\n    }\n    \n    boolean isNull() {\n        return instance == null;\n    }\n    \n    Object invoke(String methodName,Object... parameters) throws IllegalAccessException, InvocationTargetException {\n        String mid = methodId(methodName,parameters.length);\n        List<Method> methods = methodCache.get(mid);\n        Method method = null;\n        \n        if (methods == null) {\n            throw new IllegalAccessException(\"No method \"+mid); // NOI18N\n        }\n        if (methods.size()==1) {\n            method = methods.get(0);\n        } else {\n            Class[] parClasses = new Class[parameters.length];\n            \n            for (int i = 0; i < parameters.length; i++) {\n                Class cl = parameters[i].getClass();\n                if (primitiveTypes.containsKey(cl)) {\n                    cl = primitiveTypes.get(cl);\n                }\n                parClasses[i] = cl;\n            }\n            for (Method m : methods) {\n                if (Arrays.deepEquals(m.getParameterTypes(),parClasses)) {\n                    method = m;\n                    break;\n                }\n            }\n        }\n        if (method == null) {\n            throw new IllegalArgumentException(instance+\" \"+methodName+\" \"+Arrays.toString(parameters));\n        }\n        return method.invoke(instance,parameters);\n    }\n    \n    SAObject invokeSA(String methodName,Object... parameters) throws IllegalAccessException, InvocationTargetException {\n        return new SAObject(invoke(methodName,parameters));\n    }\n    \n    private static String methodId(String name,int pars) {\n        return name.concat(\"#\").concat(Integer.toString(pars)); // NOI18N\n    }\n    \n    public String toString() {\n        if (instance != null) {\n            return instance.toString();\n        }\n        return \"<null>\";    // NOI18N\n    }\n\n    public int hashCode() {\n        if (instance == null)\n            return 0;\n        return instance.hashCode();\n    }\n\n    public boolean equals(Object obj) {\n        if (obj instanceof SAObject) {\n            SAObject saobj = (SAObject) obj;\n            if (instance == null) {\n                return saobj.instance == null;\n            }\n            return instance.equals(saobj.instance);\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAPluginClassLoader.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.io.File;\nimport java.io.InputStream;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.net.URLClassLoader;\n\n/**\n *\n * @author poonam\n */\nclass SAPluginClassLoader extends URLClassLoader {\n\n    private static ClassLoader parent;\n    private boolean classPathSet;\n    private File libraryPath;\n\n    SAPluginClassLoader(ClassLoader parent) {\n        super(new URL[0], parent);\n        this.parent = parent;\n    }\n\n    SAPluginClassLoader(ClassLoader parent, File jdkHome, File saJarFile) {\n        this(parent);\n        this.classPathSet = true;\n        try {\n            addURL(saJarFile.toURI().toURL());\n        } catch(MalformedURLException mue) {\n            throw new RuntimeException(mue);\n        }\n        libraryPath = new File(jdkHome, \"jre/bin/\");\n\n    }\n\n    public synchronized Class loadClass(String name)\n        throws ClassNotFoundException {\n        // First, check if the class has already been loaded\n        Class c = findLoadedClass(name);\n        if (c == null) {\n            /* If we are loading any class in 'sun.jvm.hotspot.'  or any of the\n             * sub-packages (except for 'debugger' sub-pkg. please refer below),\n             * we load it by 'this' loader. Or else, we forward the request to\n             * 'parent' loader, system loader etc. (rest of the code follows\n             * the patten in java.lang.ClassLoader.loadClass).\n             *\n             * 'sun.jvm.hotspot.debugger.' and sub-package classes are\n             * also loaded by parent loader. This is done for two reasons:\n             *\n             * 1. to avoid code bloat by too many classes.\n             * 2. to avoid loading same native library multiple times\n             *    from multiple class loaders (which results in getting a\n             *    UnsatisifiedLinkageError from System.loadLibrary).\n             */\n\n            if ( ( name.startsWith(\"sun.jvm.hotspot.\") ||\n                    name.startsWith(\"com.sun.java.swing.\") ) &&\n                    !name.startsWith(\"sun.jvm.hotspot.debugger.\")) {\n                return findClass(name);\n            }\n            if (parent != null) {\n                c = parent.loadClass(name);\n            } else {\n                c = findSystemClass(name);\n            }\n        }\n        return c;\n    }\n\n    protected Class findClass(String name) throws ClassNotFoundException {\n        if (classPathSet) {\n            return super.findClass(name);\n        } else {\n            byte[] b = null;\n            try {\n                InputStream in = getResourceAsStream(name.replace('.', '/') + \".class\");\n                // Read until end of stream is reached\n                b = new byte[1024];\n                int total = 0;\n                int len = 0;\n                while ((len = in.read(b, total, b.length - total)) != -1) {\n                    total += len;\n                    if (total >= b.length) {\n                        byte[] tmp = new byte[total * 2];\n                        System.arraycopy(b, 0, tmp, 0, total);\n                        b = tmp;\n                    }\n                }\n                // Trim array to correct size, if necessary\n                if (total != b.length) {\n                    byte[] tmp = new byte[total];\n                    System.arraycopy(b, 0, tmp, 0, total);\n                    b = tmp;\n                }\n            } catch (Exception exp) {\n                throw (ClassNotFoundException) new ClassNotFoundException().initCause(exp);\n            }\n            return defineClass(name, b, 0, b.length);\n        }\n    }\n    protected String findLibrary(String libname) {\n        String name = System.mapLibraryName(libname);\n        File library = new File(libraryPath, name);\n        //   LOGGER.fine(\"Library \" + library.getAbsolutePath());\n        String f = library.getAbsolutePath();// NOI18N\n\n        if (library.exists() && library.canRead()) {            \n            return library.getAbsolutePath();\n        }\n        return super.findLibrary(libname);\n    }\n}\n\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAView.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport java.beans.PropertyChangeEvent;\nimport javax.swing.ImageIcon;\nimport javax.swing.JPanel;\nimport org.openide.util.Utilities;\nimport org.graalvm.visualvm.tools.sa.SaModelFactory;\nimport java.awt.BorderLayout;\nimport java.awt.Cursor;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.ItemListener;\nimport java.beans.PropertyChangeListener;\nimport javax.swing.AbstractAction;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.WeakListeners;\n\n/**\n *\n * @author poonam\n */\npublic class SAView extends DataSourceView implements PropertyChangeListener, DataRemovedListener<DataSource>, ActionListener {\n\n    private DataViewComponent dvc;\n    DataSource dataSource;\n    SAModelImpl saModel = null;\n    private boolean isAttached = false;\n    MasterViewSupport master;\n    ThreadsView threadsView;\n    OopInspectorView oopInspector;\n    StackTraceViewer stackTraceViewer;\n    CodeViewer codeviewer;\n    FindPanel findPointer;\n    FindPanel findInHeap;\n    FindPanel findInCode;\n    //Reusing an image from the sources:\n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/modules/saplugin/resources/SA.png\"; // NOI18N\n    private String dsString = \"Process\";\n    private boolean doNotShowMessage = false;\n    public static boolean isClosing = false;\n\n\n    public SAView(DataSource ds) {\n        super(ds, \"SA Plugin\", new ImageIcon(Utilities.loadImage(IMAGE_PATH, true)).getImage(), 60, false);\n        dataSource = ds;\n        isAttached = false;\n\n        ds.notifyWhenRemoved(this);\n        ds.addPropertyChangeListener(Stateful.PROPERTY_STATE, WeakListeners.propertyChange(this, ds));\n\n        if (ds instanceof Application) {\n            dsString = \"Process\";\n        } else if (ds instanceof CoreDump){\n            dsString = \"CoreDump\";\n        }\n    }\n\n    public DataViewComponent getDataViewComponent() {\n        return dvc;\n    }\n\n    @Override\n    protected void removed() {\n        detachFromProcess(dataSource);\n        dataSource = null;\n    }\n    public void propertyChange(PropertyChangeEvent evt) {\n        dataRemoved(dataSource);\n    }\n\n    public void dataRemoved(DataSource ds) {        \n        this.dataSource = null;\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        throw new UnsupportedOperationException(\"Not supported yet.\");\n    }\n    \n    @Override\n    protected DataViewComponent createComponent() {\n        // attachToProcess(dataSource);\n        master = new MasterViewSupport(dataSource);\n        //Master view:\n        DataViewComponent.MasterView masterView = new DataViewComponent.MasterView(\"SA Plugin\", null, master);\n        DataViewComponent.MasterViewConfiguration masterConfiguration =\n                new DataViewComponent.MasterViewConfiguration(false);\n        dvc = new DataViewComponent(masterView, masterConfiguration);\n        //addDetailsViews();\n        if (saModel != null)\n            saModel.setView(this);\n        \n        return dvc;\n    }\n\n    private void addDetailsViews() {\n        Cursor cur = dvc.getCursor();\n        dvc.setCursor(new Cursor(Cursor.WAIT_CURSOR));\n\n        //Add detail views to the component:\n        threadsView = new ThreadsView(\"Java Threads\", 10);\n        stackTraceViewer = new StackTraceViewer(\"Java Stack Trace\", 20);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\n                \"Java Threads / Java Stack Trace\", true), DataViewComponent.TOP_LEFT);\n        dvc.addDetailsView(threadsView.getDetailsView(), DataViewComponent.TOP_LEFT);\n        dvc.addDetailsView(stackTraceViewer.getDetailsView(), DataViewComponent.TOP_LEFT);\n\n        oopInspector = new OopInspectorView(saModel, \"Oop Inspector\", 10);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\n                \"Oop Inspector\", true), DataViewComponent.TOP_RIGHT);\n        dvc.addDetailsView(oopInspector.getDetailsView(), DataViewComponent.TOP_RIGHT);\n\n        codeviewer = new CodeViewer(\"Code Viewer\", 10);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\n                \"Code Viewer\", true), DataViewComponent.BOTTOM_LEFT);\n        dvc.addDetailsView(codeviewer.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n\n        findPointer = new FindPanel(\"Find Pointer\", 10, 1);\n        findInHeap = new FindPanel(\"Find Value in Heap\", 20, 2);\n        findInCode = new FindPanel(\"Find Value in CodeCache\", 30, 3);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\n                \"Find Panel\", true), DataViewComponent.BOTTOM_RIGHT);\n        dvc.addDetailsView(findPointer.getDetailsView(), DataViewComponent.BOTTOM_RIGHT);\n        dvc.addDetailsView(findInHeap.getDetailsView(), DataViewComponent.BOTTOM_RIGHT);\n        dvc.addDetailsView(findInCode.getDetailsView(), DataViewComponent.BOTTOM_RIGHT);\n\n        dvc.hideDetailsArea(DataViewComponent.BOTTOM_LEFT);\n        dvc.hideDetailsArea(DataViewComponent.BOTTOM_RIGHT);\n\n        dvc.setCursor(cur);\n\n    }\n\n\n    public OopInspectorView getOopInspectorView() {\n        return oopInspector;\n    }\n\n    public void updateOopInspectorView(Object oop) {\n        Cursor cur = dvc.getCursor();\n        dvc.setCursor(new Cursor(Cursor.WAIT_CURSOR));\n\n        oopInspector.refresh(oop);\n        dvc.showDetailsArea(DataViewComponent.TOP_RIGHT);\n        dvc.selectDetailsView(oopInspector.getDetailsView());\n\n        dvc.setCursor(cur);\n    }\n\n    public void updateStackTraceView(Object thread) {\n        Cursor cur = dvc.getCursor();\n        dvc.setCursor(new Cursor(Cursor.WAIT_CURSOR));\n\n        stackTraceViewer.refresh(thread);\n        dvc.selectDetailsView(stackTraceViewer.getDetailsView());\n        dvc.showDetailsArea(DataViewComponent.TOP_LEFT);\n\n        dvc.setCursor(cur);\n    }\n\n    public boolean attachToProcess(DataSource ds) {\n        if (isAttached) {\n            return true;\n        }\n        Cursor cur = dvc.getCursor();\n        dvc.setCursor(new Cursor(Cursor.WAIT_CURSOR));\n\n        try {\n            saModel = (SAModelImpl) SaModelFactory.getSAAgentFor(ds);\n            isAttached = saModel.attach();\n\n            dvc.setCursor(cur);\n            return isAttached;\n\n        } catch (Exception e) {\n            e.printStackTrace();\n            NotifyDescriptor nd = new NotifyDescriptor.Message(e.getCause().toString(), NotifyDescriptor.INFORMATION_MESSAGE);\n            DialogDisplayer.getDefault().notify(nd);\n\n//            System.out.println(e.getCause().toString());\n//            if (e.getCause().toString().contains(\"Windbg Error: AttachProcess failed!\")) {\n            detachFromProcess(ds);\n//            }            \n        }\n        dvc.setCursor(cur);\n        return false;\n    }\n\n    public void detachFromProcess(DataSource ds) {\n\n        try {\n            saModel = (SAModelImpl) SaModelFactory.getSAAgentFor(ds);            \n            saModel.detach();\n            isAttached = false;\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    public void refreshView(DataSource ds) {\n        Cursor cur = dvc.getCursor();\n        dvc.setCursor(new Cursor(Cursor.WAIT_CURSOR));\n\n        threadsView.refresh();\n        oopInspector.refresh(null);\n        stackTraceViewer.refresh(null);\n        codeviewer.refresh();\n        findPointer.refresh();\n        findInHeap.refresh();\n        findInCode.refresh();\n\n        dvc.showDetailsArea(DataViewComponent.TOP_LEFT);\n        dvc.selectDetailsView(threadsView.getDetailsView());\n        dvc.hideDetailsArea(DataViewComponent.BOTTOM_LEFT);\n        dvc.hideDetailsArea(DataViewComponent.BOTTOM_RIGHT);\n        dvc.hideDetailsArea(DataViewComponent.TOP_RIGHT);\n        dvc.showDetailsArea(DataViewComponent.TOP_LEFT);\n        dvc.setCursor(cur);\n\n    }\n\n    public void removeDetailsViews(DataSource ds) {\n        threadsView.remove();\n        oopInspector.remove();\n        stackTraceViewer.remove();\n        codeviewer.remove();\n        findPointer.remove();\n        findInHeap.remove();\n        findInCode.remove();\n\n        dvc.hideDetailsArea(DataViewComponent.TOP_LEFT);\n        dvc.hideDetailsArea(DataViewComponent.TOP_RIGHT);\n        dvc.hideDetailsArea(DataViewComponent.BOTTOM_LEFT);\n        dvc.hideDetailsArea(DataViewComponent.BOTTOM_RIGHT);\n    }\n\n    // ----------Master View----------------------------\n    private class MasterViewSupport extends JPanel {\n\n        private JButton attachButton;\n        JLabel vmInformation;\n        DataSource dataSource;\n        boolean firstTimeShow = true;\n\n        public MasterViewSupport(DataSource ds) {\n            this.dataSource = ds;\n            saModel = (SAModelImpl) SaModelFactory.getSAAgentFor(dataSource);\n            initComponents(dataSource);\n\n            if (dataSource instanceof Application) {\n                addHierarchyListener(new HierarchyListener() {\n\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                            if (isShowing()) {\n                                /*                                if (!isAttached && (dataSource != null)) {\n                                if (attachToProcess(dataSource)) {\n                                if (firstTimeShow) {\n                                try {\n                                saModel.readData();\n                                } catch (Exception ex) {\n                                ex.printStackTrace();\n                                }\n                                addVMInfo(dataSource);\n                                addDetailsViews();\n                                firstTimeShow = false;\n                                }\n                                }\n                                setAttachButtonText(\"Detach from process\");\n                                refreshView(dataSource);\n                                }   */\n                            } else {/*\n                                if (!dvc.isVisible())\n                                    return;\n                                \n                                Component parent = dvc.getParent();\n                                Component top = null;\n                                while (parent != null) {\n                                    top = parent;\n                                    parent = top.getParent();\n                                }\n                                if (!top.isShowing())\n                                    return;\n\n                                if (!top.isVisible())\n                                    return;\n                                \n                               if (isAttached && (dataSource != null) && (doNotShowMessage == false) ) {\n                                   if (isClosing == false) {\n                                    MessagePanel messagePanel = new MessagePanel();\n                                    DialogDescriptor dd = new DialogDescriptor(messagePanel, \"Warning!\");\n                                    Object result = DialogDisplayer.getDefault().notify(dd);\n                                    if (result == NotifyDescriptor.OK_OPTION) {\n                                        detachFromProcess(dataSource);\n                                        removeDetailsViews(dataSource);\n                                        setAttachButtonText(\"Attach to \" + dsString);\n                                    }\n                                   }\n                                }*/\n                            }\n                        }\n                    }\n                });\n            }\n        }\n\n        public DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(\"SAPlugin\", null, this);  // NOI18N\n        }\n\n\n        private void addVMInfo(final DataSource ds) {\n            JLabel label = new JLabel();\n            String vminfo = null;\n            vminfo = saModel.getVmVersion() + \" \" + saModel.getVmName() + \" \" + saModel.getVmInfo();\n            label.setText(vminfo);\n            add(label);\n        }\n\n        private void initComponents(final DataSource ds) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            String buttonLabel = null;\n\n            if (isAttached) {\n                buttonLabel = \"Detach from \" + dsString;\n            } else {\n                buttonLabel = \"Attach to \" + dsString;\n            }\n\n\n            attachButton = new JButton(new AbstractAction(buttonLabel) {\n\n                public void actionPerformed(ActionEvent e) {\n                    if (ds == null) {\n                        return;\n                    }\n                    Cursor cur = dvc.getCursor();\n                    dvc.setCursor(new Cursor(Cursor.WAIT_CURSOR));\n\n                    if (isAttached) {\n                        detachFromProcess(ds);\n                    //    removeWarning();\n                        removeDetailsViews(ds);                        \n                        setAttachButtonText(\"Attach to \" + dsString);\n                    } else {\n                        if (attachToProcess(ds)) {\n                            if (firstTimeShow) {\n                                try {\n                                    saModel.readData();\n                                } catch (Exception ex) {\n                                    ex.printStackTrace();\n                                }\n                                addVMInfo(dataSource);\n                                addDetailsViews();\n                                firstTimeShow = false;\n                            }\n                            refreshView(ds);\n\n                            if (isAttached && (ds instanceof Application) && (doNotShowMessage == false)) {\n                                if (isClosing == false) {\n                                    MessagePanel messagePanel = new MessagePanel();\n                                    //DialogDescriptor dd = new DialogDescriptor(messagePanel, \"SAPlugin Warning !\");\n                                    NotifyDescriptor nd = new NotifyDescriptor.Message((Object) messagePanel, NotifyDescriptor.INFORMATION_MESSAGE) ;\n\n                                    Object result = DialogDisplayer.getDefault().notify(nd);\n                                    /*if (result == NotifyDescriptor.OK_OPTION) {\n                                        detachFromProcess(dataSource);\n                                        removeDetailsViews(dataSource);\n                                        setAttachButtonText(\"Attach to \" + dsString);\n                                    }\n                                     * */\n                                }\n                            }\n                            \n                            setAttachButtonText(\"Detach from \" + dsString);\n                        }\n                    }\n\n                    dvc.setCursor(cur);\n                }\n            });\n            attachButton.setEnabled(true);\n\n            JPanel buttonsArea = new JPanel(new BorderLayout());\n            buttonsArea.setOpaque(false);\n            JPanel buttonsContainer = new JPanel(new BorderLayout(3, 0));\n            buttonsContainer.setOpaque(false);\n            buttonsContainer.setBorder(BorderFactory.createEmptyBorder(9, 5, 20, 10));\n            buttonsContainer.add(attachButton, BorderLayout.WEST);\n            buttonsArea.add(buttonsContainer, BorderLayout.NORTH);\n            add(buttonsArea, BorderLayout.EAST);\n\n        }\n\n        void setAttachButtonText(String s) {\n            if (attachButton != null) {\n                attachButton.setText(s);\n            }\n        }\n    }\n\n    //Details views\n    private class ThreadsView extends JComponent {\n\n        private JPanel threads;\n        private String caption;\n        private int position;\n        private DataViewComponent.DetailsView detailsView;\n        private Object saListener = null;\n        private JavaThreadsPanel threadsPanel = null;\n\n        public ThreadsView(String caption, int position) {\n            this.caption = caption;\n            this.position = position;\n            detailsView = null;\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            if (detailsView == null) {\n                detailsView = new DataViewComponent.DetailsView(caption, null, position, this, null);\n            }\n            return detailsView;\n        }\n\n        public void refresh() {\n            this.removeAll();\n            threadsPanel = saModel.createJavaThreadsPanel();\n            if (threadsPanel != null) {\n                saListener = saModel.getSAListener();\n                threadsPanel.setListener(saListener);\n                threads = threadsPanel.getPanel();\n                add(threads, BorderLayout.CENTER);\n            }\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n        }\n\n        public void remove() {\n           // threadsPanel.removeListener(saListener);\n            this.removeAll();\n        }\n    }\n\n    private class CodeViewer extends JComponent {\n\n        private JPanel codeviewer;\n        private String caption;\n        private int position;\n        private DataViewComponent.DetailsView detailsView;\n\n        public CodeViewer(String caption, int position) {\n            this.caption = caption;\n            this.position = position;\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            if (detailsView == null) {\n              detailsView = new DataViewComponent.DetailsView(caption, null, position, this, null);\n            }\n            return detailsView;\n        }\n\n        public void refresh() {\n            this.removeAll();\n            try {\n                codeviewer = saModel.createCodeViewerPanel().getPanel();\n            } catch (Throwable t) {\n                NotifyDescriptor nd = new NotifyDescriptor.Message(\"Code Viewer is not yet implemented for this platform\", NotifyDescriptor.INFORMATION_MESSAGE);\n                DialogDisplayer.getDefault().notify(nd);\n                dvc.removeDetailsView(detailsView);\n                return;\n            }\n            add(codeviewer, BorderLayout.CENTER);\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n        }\n\n        public void remove() {\n            this.removeAll();\n        }\n    }\n\n    private class FindPanel extends JComponent {\n\n        private JPanel findPanel;\n        private String caption;\n        private int position;\n        private int mode;\n\n        public FindPanel(String caption, int position, int mode) {\n            this.caption = caption;\n            this.position = position;\n            this.mode = mode;\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(caption, null, position, this, null);\n        }\n\n        public void refresh() {\n            this.removeAll();\n            switch (mode) {\n                case 1:\n                    findPanel = saModel.createFindPointerPanel().getPanel();\n                    break;\n                case 2:\n                    findPanel = saModel.createFindInHeapPanel().getPanel();\n                    break;\n                case 3:\n                    findPanel = saModel.createFindInCodeCachePanel().getPanel();\n                    break;\n            }\n            add(findPanel, BorderLayout.CENTER);\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n        }\n\n        public void remove() {\n            this.removeAll();            \n        }\n    }\n\n    private class StackTraceViewer extends JComponent {\n\n        private JPanel traceViewer;\n        private String caption;\n        private int position;\n        private DataViewComponent.DetailsView detailsView;\n\n        public StackTraceViewer(String caption, int position) {\n            this.caption = caption;\n            this.position = position;\n            detailsView = null;\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            if (detailsView == null) {\n                detailsView = new DataViewComponent.DetailsView(caption, null, position, this, null);\n            }\n            return detailsView;\n        }\n\n        public void refresh(Object thread) {\n            this.removeAll();\n            try {\n                JavaStackTracePanel tracePanel = saModel.createJavaStackTracePanel();\n\n                if (thread != null) {\n                    tracePanel.setJavaThread(thread);\n                }\n                traceViewer = tracePanel.getPanel();\n            } catch (Throwable t) {\n                NotifyDescriptor nd = new NotifyDescriptor.Message(\"Java Stack Trace Viewer is not yet implemented for this platform\", NotifyDescriptor.INFORMATION_MESSAGE);\n                DialogDisplayer.getDefault().notify(nd);\n                dvc.removeDetailsView(detailsView);\n                return;\n            }\n            add(traceViewer, BorderLayout.CENTER);\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n        }\n\n        public void remove() {\n            this.removeAll();\n        }\n    }\n\n    public class MessagePanel extends JPanel implements ItemListener {\n\n        private String warning = new String(\"\" +\n                \"<html><br>&nbsp Other tabs for this process will not be usable as long as<br>\" +\n                \"&nbsp SAPlugin is attached to it. Please detach SAPlugin from<br>\" +\n                \"&nbsp the process before using other tabs.<br><br></html>\");\n        \n        public MessagePanel() {\n         initComponents();\n        }\n\n        void initComponents() {\n            setLayout(new BorderLayout());\n            //setSize(150,100);\n\n            JLabel msg = new JLabel(warning);\n            this.add(msg,BorderLayout.NORTH);\n\n            JCheckBox check = new JCheckBox(\"Do not show this message again\");\n            add(check, BorderLayout.SOUTH);\n            check.addItemListener(this);\n        }\n\n        public void itemStateChanged(ItemEvent e) {\n            if (e.getStateChange() == ItemEvent.SELECTED) {\n                doNotShowMessage = true;\n            }\n        }\n    }\n}\n\n    \n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAViewProvider.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory;\nimport java.io.File;\n\n/**\n *\n * @author poonam\n */\nclass SAViewProvider extends DataSourceViewProvider<DataSource> {\n\n    private static DataSourceViewProvider<DataSource> instance =  new SAViewProvider();\n\n    private SAView saview = null;\n    \n    @Override\n    public boolean supportsViewFor(DataSource ds) {\n        if (ds == Application.CURRENT_APPLICATION)\n            return false;\n        \n        if (ds instanceof Application) {\n            if (Host.LOCALHOST.equals(((Application) ds).getHost())) {\n                JvmJvmstatModel jvmstat = JvmJvmstatModelFactory.getJvmstatModelFor((Application) ds);\n                if (jvmstat == null) {\n                    return false;\n                }\n                File jdkHome = new File(jvmstat.getJavaHome());\n                if (\"jre\".equals(jdkHome.getName())) {\n                    jdkHome = jdkHome.getParentFile();\n                }\n                File saJar = SAModelProvider.getSaJar(jdkHome);\n                if (saJar == null) {\n                    return false;\n                } else {\n                    return true;\n                }\n            }\n        } else if (ds instanceof CoreDump) {\n            CoreDump coredump = (CoreDump) ds;\n            File executable = new File(coredump.getExecutable());\n            File coreFile = coredump.getFile();\n            if (executable.exists() && coreFile.exists()) {\n                File jdkHome = executable.getParentFile().getParentFile();\n                File saJar = SAModelProvider.getSaJar(jdkHome);\n\n                if (saJar == null) {\n                    return false;\n                } else {\n                    return true;\n                }\n            }\n        }\n\n        return false;\n    }\n\n    @Override\n    public synchronized DataSourceView createView(final DataSource ds) {\n        saview = new SAView(ds);\n        return saview;\n\n    }\n     \n    //@Override\n    public boolean supportsSaveViewsFor(DataSource arg0) {\n        return false;\n    }    \n\n  //  @Override\n    public void saveViews(DataSource arg0, Snapshot arg1) {\n    }\n    \n    void initialize() {        \n        DataSourceViewsManager.sharedInstance().addViewProvider(instance, DataSource.class);\n    }\n    \n    static void unregister() {\n        DataSourceViewsManager.sharedInstance().removeViewProvider(instance);\n    }\n\n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/SAWrapper.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.io.File;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.util.logging.Logger;\n\n\nclass SAWrapper {\n    private static final Logger LOGGER = Logger.getLogger(SAWrapper.class.getName());\n    \n    URLClassLoader loader;\n    private static ClassLoader parent;\n    File libraryPath;\n    \n    SAWrapper(File jdkHome, File saJarFile) throws MalformedURLException {\n        // By default SA agent classes prefer dbx debugger to proc debugger\n        // and Windows process debugger to windbg debugger. SA expects\n        // special properties to be set to choose other debuggers.\n        // We will set those here before attaching to SA agent.\n        System.setProperty(\"sun.jvm.hotspot.debugger.useProcDebugger\", \"true\"); // NOI18N\n        System.setProperty(\"sun.jvm.hotspot.debugger.useWindbgDebugger\", \"true\");   // NOI18N\n        //File maf = new File(jdkHome, \"lib/maf-1_0.jar\");\n        URL[] saJarUrls = new URL[]{saJarFile.toURI().toURL()/*, maf.toURI().toURL()*/};\n        \n//        String osArch = System.getProperty(\"os.arch\");  // NOI18N\n//        if (\"x86\".equals(osArch)) {\n//            osArch = \"i386\";\n//        }\n        //libraryPath = new File(\"lib/\" + osArch);   // NOI18N   /// Changed this\n        libraryPath = new File(jdkHome, \"jre/bin/\");\n        LOGGER.fine(\"Path \" + libraryPath.getAbsolutePath());   // NOI18N\n        \n        //We want only one parent for all the SAPluginClassLoader instances.\n        if (parent == null)\n            parent = new URLClassLoader(new URL[]{saJarFile.toURI().toURL()});\n        loader = new SAPluginClassLoader(parent, jdkHome, saJarFile);\n        \n/*        loader = new URLClassLoader(saJarUrls, parent) {\n            @Override\n            protected String findLibrary(String libname) {\n                String name = System.mapLibraryName(libname);\n                File library = new File(libraryPath, name);\n                LOGGER.fine(\"Library \" + library.getAbsolutePath());\n                String f = library.getAbsolutePath();// NOI18N\n                \n                if (library.exists() && library.canRead()) {\n                    //return \"D:/Java/jdk1.6.0_03/jre/lib/i386/sawindbg.dll\";\n                    return library.getAbsolutePath();\n                }\n                return super.findLibrary(libname);\n            }\n\n            @Override\n            public synchronized Class loadClass(String name)\n                    throws ClassNotFoundException {\n                // First, check if the class has already been loaded\n                Class c = findLoadedClass(name);\n                if (c == null) {\n                    /* If we are loading any class in 'sun.jvm.hotspot.'  or any of the\n                     * sub-packages (except for 'debugger' sub-pkg. please refer below),\n                     * we load it by 'this' loader. Or else, we forward the request to\n                     * 'parent' loader, system loader etc. (rest of the code follows\n                     * the patten in java.lang.ClassLoader.loadClass).\n                     *\n                     * 'sun.jvm.hotspot.debugger.' and sub-package classes are\n                     * also loaded by parent loader. This is done for two reasons:\n                     *\n                     * 1. to avoid code bloat by too many classes.\n                     * 2. to avoid loading same native library multiple times\n                     *    from multiple class loaders (which results in getting a\n                     *    UnsatisifiedLinkageError from System.loadLibrary).\n                     *\n\n                    if (name.startsWith(\"sun.jvm.hotspot.\") &&\n                            !name.startsWith(\"sun.jvm.hotspot.debugger.\")) {\n                        return findClass(name);\n                    }\n                    if (name.startsWith(\"sun.jvm.hotspot.debugger.\")) {\n                        c = parent.loadClass(name);\n                    } else  if (parent != null) {\n                        c = parent.loadClass(name);\n                    } else {\n                        c = findSystemClass(name);\n                    }\n                }\n                return c;\n            }\n        };\n    }\n*/\n    }\n    Class classForName(String name) throws ClassNotFoundException {\n       return Class.forName(name, true, loader);\n    }\n\n    Class Tool() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.tools.Tool\");  // NOI18N\n    }\n\n    Class VM() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.runtime.VM\");  // NOI18N\n    }\n\n    Class BugspotAgent() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.bugspot.BugSpotAgent\");    // NOI18N\n    }\n\n    Class HotspotAgent() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.HotSpotAgent\");    // NOI18N\n    }\n\n    Class HeapHprofBinWriter() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.utilities.HeapHprofBinWriter\");    // NOI18N\n    }\n\n    Class Arguments() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.runtime.Arguments\");   // NOI18N\n    }\n\n    ///////////////////////////////////\n    Class OopInspector() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.ui.Inspector\");    // NOI18N\n    }\n\n    Class JavaStackTracePanel() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.ui.JavaStackTracePanel\");    // NOI18N\n    }\n\n    Class JavaThreadsPanel() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.ui.JavaThreadsPanel\");    // NOI18N\n    }\n\n    Class SAListener() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.ui.SAListener\");    // NOI18N\n    }\n\n    Class OopTreeNodeAdapter() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.ui.tree.OopTreeNodeAdapter\");    // NOI18N\n    }\n\n    Class SimpleTreeNode() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.ui.tree.SimpleTreeNode\");    // NOI18N\n    }\n\n    Class CodeViewerPanel() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.ui.classbrowser.CodeViewerPanel\");    // NOI18N\n    }\n    Class FindPanel() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.ui.FindPanel\");    // NOI18N\n    }\n    Class FindInHeapPanel() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.ui.FindInHeapPanel\");    // NOI18N\n    }\n    Class FindInCodeCachePanel() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.ui.FindInCodeCachePanel\");    // NOI18N\n    }\n        \n    \n    //Non-ui\n    Class Oop() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.oops.Oop\");    // NOI18N\n    }\n    Class JavaThread() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.runtime.JavaThread\");    // NOI18N\n    }\n    Class FieldIdentifier() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.oops.FieldIdentifier\");    // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/StackTrace.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.PrintStream;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass StackTrace {\n\n    private VM vm;\n    private SAObject heap;\n    private SAObject objectClass;\n\n    StackTrace(VM v) throws IllegalAccessException, InvocationTargetException {\n        vm = v;\n        heap = vm.getObjectHeap();\n        objectClass = vm.getSystemDictionary().invokeSA(\"getObjectKlass\");  // NOI18N\n    }\n\n    public String getStackTrace() throws IllegalAccessException, InvocationTargetException {\n        ByteArrayOutputStream data = new ByteArrayOutputStream(4096);\n        PrintStream out = new PrintStream(data);\n        SAObject threads = vm.getThreads();\n        SAObject curThread = threads.invokeSA(\"first\"); // NOI18N\n\n        for (;!curThread.isNull();curThread=curThread.invokeSA(\"next\")) {   // NOI18N\n            try {\n                Boolean isJavaThread = (Boolean) curThread.invoke(\"isJavaThread\");  // NOI18N\n                if (!isJavaThread.booleanValue()) {\n                    out.print(\"VM \");   // NOI18N\n                }\n                out.print(\"Thread \");   // NOI18N\n                curThread.invoke(\"printThreadIDOn\",out);    // NOI18N\n                out.print(\" \\\"\"+curThread.invoke(\"getThreadName\")+\"\\\"\");    // NOI18N\n                out.print(\": (state = \");   // NOI18N\n                out.print(curThread.invoke(\"getThreadState\"));  // NOI18N\n                out.println(\")\");\n                if (isJavaThread.booleanValue()) { // Java thread\n                    SAObject javaFrame = curThread.invokeSA(\"getLastJavaVFrameDbg\");    // NOI18N\n                    Object waitingToLockMonitor = curThread.invoke(\"getCurrentPendingMonitor\"); // NOI18N\n                    boolean objectWaitFrame = isJavaLangObjectWaitFrame(javaFrame);\n                    for (;!javaFrame.isNull();javaFrame=javaFrame.invokeSA(\"javaSender\")) { // NOI18N\n                        printJavaFrame(out, javaFrame);\n                        printMonitors(out, javaFrame, waitingToLockMonitor, objectWaitFrame);\n                        waitingToLockMonitor = null;\n                        objectWaitFrame = false;\n                    }\n                }\n            } catch (Exception ex) {\n                out.println(\"\\t-- Error occurred during stack walking\");\n                Logger.getLogger(StackTrace.class.getName()).log(Level.INFO,\"getStackTrace\",ex);\n            }\n            out.println();\n        }\n        return data.toString();\n    }\n    \n    private boolean isJavaLangObjectWaitFrame(SAObject javaFrame) throws IllegalAccessException, InvocationTargetException {\n        if (!javaFrame.isNull()) {\n            SAObject method = javaFrame.invokeSA(\"getMethod\");  // NOI18N\n            SAObject klass = method.invokeSA(\"getMethodHolder\");    // NOI18N\n            Boolean isNative = (Boolean) method.invoke(\"isNative\"); // NOI18N\n            if (objectClass.equals(klass) && isNative.booleanValue()) {\n                if (\"wait\".equals(method.invokeSA(\"getName\").invoke(\"asString\"))) { // NOI18N\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n    \n    private void printMonitors(\n            final PrintStream out, final SAObject javaFrame,\n            Object waitingToLockMonitor, boolean objectWaitFrame)\n            throws IllegalAccessException, InvocationTargetException {\n        if (objectWaitFrame) {\n            SAObject stackValueCollection = javaFrame.invokeSA(\"getLocals\");    // NOI18N\n            Boolean isEmpty = (Boolean) stackValueCollection.invoke(\"isEmpty\"); // NOI18N\n            if (!isEmpty.booleanValue()) {\n                Object oopHandle = stackValueCollection.invoke(\"oopHandleAt\", 0);   // NOI18N\n                printMonitor(out, oopHandle, \"waiting on\"); // NOI18N\n            }\n        }\n        try {\n            List mList = (List) javaFrame.invoke(\"getMonitors\");    // NOI18N\n            Object[] monitors = mList.toArray();\n            for (int i = monitors.length - 1; i >= 0; i--) {\n                SAObject monitorInfo = new SAObject(monitors[i]);\n                Object ownerHandle = monitorInfo.invoke(\"owner\");   // NOI18N\n                if (ownerHandle != null) {\n                    String state = \"locked\";    // NOI18N\n                    if (waitingToLockMonitor != null) {\n                        Object objectHandle = new SAObject(waitingToLockMonitor).invoke(\"object\");  // NOI18N\n                        if (objectHandle.equals(ownerHandle)) {\n                            state = \"waiting to lock\";  // NOI18N\n                        }\n                    }\n                    printMonitor(out, ownerHandle, state);\n                }\n            }\n        } catch (Exception e) {\n            // Ignore...\n        }\n    }\n\n    private void printMonitor(\n            final PrintStream out,\n            final Object ownerHandle,\n            final String state) {\n        try {\n            StringBuilder sb = new StringBuilder();\n            sb.append(\"\\t- \" + state + \" <\" + ownerHandle + \"> \");  // NOI18N\n            printOop(sb, ownerHandle);\n            out.println(sb.toString());\n        } catch (Exception e) {\n            // Ignore...\n        }\n    }\n\n    private void printOop(StringBuilder sb, Object oopHandle)\n            throws IllegalAccessException, InvocationTargetException {\n        SAObject oop = heap.invokeSA(\"newOop\", oopHandle);  // NOI18N\n        if (!oop.isNull()) {\n            sb.append(\"(a \");   // NOI18N\n            String monitorClassName = (String) oop.invokeSA(\"getKlass\").invokeSA(\"getName\").invoke(\"asString\"); // NOI18N\n            sb.append(monitorClassName.replace('/', '.'));\n            sb.append(\")\");\n        } else {\n            sb.append(\"(Raw Monitor)\"); // NOI18N\n        }\n    }\n    \n    private void printJavaFrame(final PrintStream out, final SAObject javaFrame) throws IllegalAccessException, InvocationTargetException {\n        SAObject method = javaFrame.invokeSA(\"getMethod\");  // NOI18N\n        \n        out.print(\"\\tat \"); // NOI18N\n        SAObject klass = method.invokeSA(\"getMethodHolder\");    // NOI18N\n        String className = (String) klass.invokeSA(\"getName\").invoke(\"asString\");   // NOI18N\n        out.print(className.replace('/','.'));\n        out.print(\".\");\n        out.print(method.invokeSA(\"getName\").invoke(\"asString\"));   // NOI18N\n        Integer bci = (Integer) javaFrame.invoke(\"getBCI\"); // NOI18N\n        out.print(\"(\");\n        if (((Boolean)method.invoke(\"isNative\")).booleanValue()) {  // NOI18N\n            out.print(\"Native Method\"); // NOI18N\n        } else {\n            Integer lineNumber = (Integer) method.invoke(\"getLineNumberFromBCI\",bci);   // NOI18N\n            SAObject sourceName = klass.invokeSA(\"getSourceFileName\");  // NOI18N\n            \n            if (lineNumber.intValue()!=-1  && !sourceName.isNull()) {\n                out.print(sourceName.invoke(\"asString\"));   // NOI18N\n                out.print(\":\");\n                out.print(lineNumber);\n            } else {\n                out.print(\"bci=\");  // NOI18N\n                out.print(bci);\n            }\n        }\n        out.println(\")\");\n    }\n}\n"
  },
  {
    "path": "plugins/saplugin/src/org/graalvm/visualvm/modules/saplugin/VM.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.saplugin;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.Properties;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass VM {\n\n    private final SAObject vm;\n\n    VM(Object saVM) {\n        vm = new SAObject(saVM);\n    }\n\n    Properties getSystemProperties() throws IllegalAccessException, InvocationTargetException {\n        return (Properties) vm.invoke(\"getSystemProperties\");   // NOI18N\n    }\n\n    SAObject getThreads() throws IllegalAccessException, InvocationTargetException {\n        return vm.invokeSA(\"getThreads\");   // NOI18N\n    }\n\n    SAObject getObjectHeap() throws IllegalAccessException, InvocationTargetException {\n        return vm.invokeSA(\"getObjectHeap\");    // NOI18N\n    }\n\n    SAObject getSystemDictionary() throws IllegalAccessException, InvocationTargetException {\n        return vm.invokeSA(\"getSystemDictionary\");  // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "plugins/security/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.security\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.security.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/security/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.security/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/security/Bundle.properties\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/security/Installer.class\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "plugins/security/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.security-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/security/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=00c4bee7\nbuild.xml.script.CRC32=c28e99b3\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=00c4bee7\nnbproject/build-impl.xml.script.CRC32=1b990c4b\nnbproject/build-impl.xml.stylesheet.CRC32=68e521fc@2.73\n"
  },
  {
    "path": "plugins/security/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jiri Sedlacek\nmodule.javadoc.packages=org.graalvm.visualvm.modules.security.*\n"
  },
  {
    "path": "plugins/security/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.security</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.options.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.11.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.18.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/security/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/security/src/org/graalvm/visualvm/modules/security/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Security\nOpenIDE-Module-Long-Description=\\\n    This plugin provides a GUI for setting the standard system properties controlling SSL/TLS connections in VisualVM. \\\n    Setting the properties using the plugin is equivalent to providing the properties on the command line. \\\n    However, the properties provided on the command line take precedence and if set the GUI editing is disabled.\\n\\\n    <BR>\\n<BR>\\nCurrently the plugin supports editing these system properties:\\n<BR>\\n<UL>\\n<LI><CODE>javax.net.ssl.keyStore</CODE></LI>\\n<LI><CODE>javax.net.ssl.keyStoreType</CODE></LI>\\n<LI><CODE>javax.net.ssl.keyStorePassword</CODE></LI>\\n<LI><CODE>javax.net.ssl.trustStore</CODE></LI>\\n<LI><CODE>javax.net.ssl.trustStoreType</CODE></LI>\\n<LI><CODE>javax.net.ssl.trustStorePassword</CODE></LI>\\n<LI><CODE>javax.rmi.ssl.client.enabledCipherSuites</CODE></LI>\\n<LI><CODE>javax.rmi.ssl.client.enabledProtocols</CODE></LI>\\n</UL>\nOpenIDE-Module-Name=VisualVM-Security\nOpenIDE-Module-Short-Description=Options category for customizing SSL certificates, protocols and cipher suites\n\nOptionsCategory_Name_Security=Security\n\nMSG_SaveToFile=Save Security Settings To File\nMSG_FailedSaveToFile=Failed to save security settings\nMSG_LoadFromFile=Load Security Settings From File\nMSG_FailedLoadFromFile=Failed to load security settings\n\nCAP_SelectProtocols=Select Protocols To Enable\nHINT_SelectProtocols=Select the &protocols to enable\\:\nCOL_Protocols=Protocols\nCAP_SelectCipherSuites=Select Cipher Suites To Enable\nHINT_SelectCipherSuites=Select the &cipher suites to enable\\:\nCOL_CipherSuites=Cipher Suites\nCOL_Enabled=Enabled\nACT_SelectAll=&Select All\nACT_DeselectAll=&Deselect All\n\nMSG_AlreadyDefined=Properties already defined using the command line options on VisualVM startup. Remove the command line options to enable the GUI settings.\nSEP_Certificates=Certificates\nCHK_KeyStore=&Key store\\:\nMSG_ValueOf=Value of {0}\nBTN_Browse1=&Browse...\nCAP_SelectKeyStore=Select Key Store File\nLBL_Password1=P&assword\\:\nLBL_Type1=T&ype\\:\nOPT_Default=Default\nCHK_TrustStore=&Trust store\\:\nBTN_Browse2=B&rowse...\nCAP_SelectTrustStore=Select Trust Store File\nLBL_Password2=Pass&word\\:\nLBL_Type2=Typ&e\\:\nSEP_Protocols=Protocols\nCHK_Protocols=&Protocols\\:\nBTN_Customize1=C&ustomize...\nCHK_CipherSuites=&Cipher suites\\:\nBTN_Customize2=Cust&omize...\nSEP_ExportImport=Export / Import\nBTN_LoadFromFile=&Load From File...\nBTN_SaveToFile=&Save To File...\nMSG_RestartVisualVM=VisualVM needs to be restarted for the changes to take effect.\nCHK_RestartVisualVM=Restart &VisualVM after clicking the OK button\n"
  },
  {
    "path": "plugins/security/src/org/graalvm/visualvm/modules/security/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.security;\n\n\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.openide.modules.ModuleInstall;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class Installer extends ModuleInstall {\n\n    private static final Logger LOGGER = Logger.getLogger(Installer.class.getName());\n\n    public void restored() {\n        SecurityModel model = SecurityModel.getInstance();\n        if (!model.environmentCustomized()) {\n            if (model.customizeEnvironment())\n                LOGGER.log(Level.INFO, \"VisualVM-Security customized security environment\"); // NOI18N\n        } else {\n            LOGGER.log(Level.INFO, \"VisualVM-Security detected customized security environment\"); // NOI18N\n        }\n    }\n    \n}\n"
  },
  {
    "path": "plugins/security/src/org/graalvm/visualvm/modules/security/PersistenceSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.security;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.Properties;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.JFileChooser;\nimport javax.swing.SwingUtilities;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass PersistenceSupport {\n\n    private static final String SNAPSHOT_VERSION = \"snapshot_version\";  // NOI18N\n    private static final String SNAPSHOT_VERSION_DIVIDER = \".\";\n    private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = \"1\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MINOR = \"0\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION =\n                                                CURRENT_SNAPSHOT_VERSION_MAJOR +\n                                                SNAPSHOT_VERSION_DIVIDER +\n                                                CURRENT_SNAPSHOT_VERSION_MINOR;\n\n\n    private static final Logger LOGGER =\n            Logger.getLogger(PersistenceSupport.class.getName());\n\n\n    static File chooseLoadFile(String title, File startFile) {\n        JFileChooser chooser = new JFileChooser();\n        chooser.setDialogTitle(title);\n        chooser.setSelectedFile(startFile);\n        if (chooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) ==\n                                   JFileChooser.APPROVE_OPTION)\n            return chooser.getSelectedFile();\n        return null;\n    }\n\n    static File chooseSaveFile(String title) {\n        JFileChooser chooser = new JFileChooser();\n        chooser.setDialogTitle(title);\n        if (chooser.showSaveDialog(WindowManager.getDefault().getMainWindow()) ==\n                                   JFileChooser.APPROVE_OPTION)\n            return chooser.getSelectedFile();\n        return null;\n    }\n\n\n    static void saveToFile(SecurityOptionsPanel panel) {\n        final File file = chooseSaveFile(NbBundle.getMessage(\n                          PersistenceSupport.class, \"MSG_SaveToFile\")); // NOI18N\n        if (file == null) return;\n\n        final Properties props = new Properties();\n\n        props.put(SNAPSHOT_VERSION, CURRENT_SNAPSHOT_VERSION);\n\n        String keyStore = panel.getKeyStore();\n        if (keyStore != null) {\n            props.put(SecurityModel.KEYSTORE_LOCATION, keyStore);\n\n            char[] keyStorePassword = panel.getKeyStorePassword();\n            if (keyStorePassword != null)\n                props.put(SecurityModel.KEYSTORE_PASSWORD, new String(keyStorePassword));\n\n            String keyStoreType = panel.getKeyStoreType();\n            if (keyStoreType != null)\n                props.put(SecurityModel.KEYSTORE_TYPE, keyStoreType);\n        }\n\n        String trustStore = panel.getTrustStore();\n        if (trustStore != null) {\n            props.put(SecurityModel.TRUSTSTORE_LOCATION, trustStore);\n\n            char[] trustStorePassword = panel.getTrustStorePassword();\n            if (trustStorePassword != null)\n                props.put(SecurityModel.TRUSTSTORE_PASSWORD, new String(trustStorePassword));\n\n            String trustStoreType = panel.getTrustStoreType();\n            if (trustStoreType != null)\n                props.put(SecurityModel.TRUSTSTORE_TYPE, trustStoreType);\n        }\n\n        String enabledProtocols = panel.getEnabledProtocols();\n        if (enabledProtocols != null)\n            props.put(SecurityModel.ENABLED_PROTOCOLS, enabledProtocols);\n\n        String enabledCipherSuites = panel.getEnabledCipherSuites();\n        if (enabledCipherSuites != null)\n            props.put(SecurityModel.ENABLED_CIPHER_SUITES, enabledCipherSuites);\n\n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() {\n                boolean saved = saveProperties(props, file);\n                if (!saved) {\n                    NotifyDescriptor nd = new NotifyDescriptor.Message(\n                            NbBundle.getMessage(PersistenceSupport.class,\n                            \"MSG_FailedSaveToFile\"), NotifyDescriptor.ERROR_MESSAGE); // NOI18N\n                    DialogDisplayer.getDefault().notifyLater(nd);\n                    return;\n                }\n            }\n        });\n    }\n\n    static void loadFromFile(final SecurityOptionsPanel panel) {\n        final File file = chooseLoadFile(NbBundle.getMessage(PersistenceSupport.class,\n                                         \"MSG_LoadFromFile\"), null); // NOI18N\n        if (file == null) return;\n\n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() {\n                final Properties props = loadProperties(file);\n                if (props == null) {\n                    NotifyDescriptor nd = new NotifyDescriptor.Message(\n                            NbBundle.getMessage(PersistenceSupport.class,\n                            \"MSG_FailedLoadFromFile\"), NotifyDescriptor.ERROR_MESSAGE);\n                    DialogDisplayer.getDefault().notifyLater(nd);\n                    return;\n                }\n\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        panel.setKeyStore(props.getProperty(SecurityModel.KEYSTORE_LOCATION));\n                        String keyStorePassword = props.getProperty(SecurityModel.KEYSTORE_PASSWORD);\n                        panel.setKeyStorePassword(keyStorePassword == null ? null : keyStorePassword.toCharArray());\n                        panel.setKeyStoreType(props.getProperty(SecurityModel.KEYSTORE_TYPE));\n                        panel.setTrustStore(props.getProperty(SecurityModel.TRUSTSTORE_LOCATION));\n                        String trustStorePassword = props.getProperty(SecurityModel.TRUSTSTORE_PASSWORD);\n                        panel.setTrustStorePassword(trustStorePassword == null ? null : trustStorePassword.toCharArray());\n                        panel.setTrustStoreType(props.getProperty(SecurityModel.TRUSTSTORE_TYPE));\n                        panel.setEnabledProtocols(props.getProperty(SecurityModel.ENABLED_PROTOCOLS));\n                        panel.setEnabledCipherSuites(props.getProperty(SecurityModel.ENABLED_CIPHER_SUITES));\n                    }\n                });\n            }\n        });\n    }\n\n\n    private static boolean saveProperties(Properties properties, File file) {\n        OutputStream os = null;\n        BufferedOutputStream bos = null;\n        try {\n            os = new FileOutputStream(file);\n            bos = new BufferedOutputStream(os);\n            properties.storeToXML(os, null);\n            return true;\n        } catch (Exception e) {\n            LOGGER.log(Level.INFO, \"Error storing properties to \" + file, e);    // NOI18N\n            return false;\n        } finally {\n            try {\n                if (bos != null) bos.close();\n                if (os != null) os.close();\n            } catch (Exception e) {\n                LOGGER.log(Level.INFO, \"Problem closing output stream\", e);   // NOI18N\n            }\n        }\n    }\n\n    private static Properties loadProperties(File file) {\n        InputStream is = null;\n        BufferedInputStream bis = null;\n        try {\n            is = new FileInputStream(file);\n            bis = new BufferedInputStream(is);\n            Properties properties = new Properties();\n            properties.loadFromXML(bis);\n            return properties;\n        } catch (Exception e) {\n            LOGGER.log(Level.INFO, \"Error loading properties from \" + file, e);    // NOI18N\n            return null;\n        } finally {\n            try {\n                if (bis != null) bis.close();\n                if (is != null) is.close();\n            } catch (Exception e) {\n                LOGGER.log(Level.INFO, \"Problem closing input stream\", e);    // NOI18N\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/security/src/org/graalvm/visualvm/modules/security/SecurityModel.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.security;\n\nimport java.util.prefs.Preferences;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass SecurityModel {\n\n    static final String KEYSTORE_LOCATION     = \"javax.net.ssl.keyStore\"; // NOI18N\n    static final String KEYSTORE_TYPE         = \"javax.net.ssl.keyStoreType\"; // NOI18N\n    static final String KEYSTORE_PASSWORD     = \"javax.net.ssl.keyStorePassword\"; // NOI18N\n\n    static final String TRUSTSTORE_LOCATION   = \"javax.net.ssl.trustStore\"; // NOI18N\n    static final String TRUSTSTORE_TYPE       = \"javax.net.ssl.trustStoreType\"; // NOI18N\n    static final String TRUSTSTORE_PASSWORD   = \"javax.net.ssl.trustStorePassword\"; // NOI18N\n\n    static final String ENABLED_CIPHER_SUITES = \"javax.rmi.ssl.client.enabledCipherSuites\"; // NOI18N\n    static final String ENABLED_PROTOCOLS     = \"javax.rmi.ssl.client.enabledProtocols\"; // NOI18N\n\n    private static final String CUSTOMIZED_MSG = \"Environment already customized by command line\"; // NOI18N\n\n    private static SecurityModel INSTANCE;\n\n    private final boolean environmentCustomized;\n\n    private final Preferences prefs;\n\n\n    static synchronized SecurityModel getInstance() {\n        if (INSTANCE == null) INSTANCE = new SecurityModel();\n        return INSTANCE;\n    }\n\n\n    boolean environmentCustomized() {\n        return environmentCustomized;\n    }\n\n    boolean customizeEnvironment() {\n        if (environmentCustomized)\n            throw new UnsupportedOperationException(CUSTOMIZED_MSG);\n\n        boolean customized = false;\n\n        String keyStore = getKeyStore();\n        if (keyStore != null) {\n            customized = true;\n\n            System.setProperty(KEYSTORE_LOCATION, keyStore);\n\n            char[] keyStorePassword = getKeyStorePassword();\n            if (keyStorePassword != null)\n                System.setProperty(KEYSTORE_PASSWORD, new String(keyStorePassword));\n\n            String keyStoreType = getKeyStoreType();\n            if (keyStoreType != null)\n                System.setProperty(KEYSTORE_TYPE, keyStoreType);\n        }\n\n        String trustStore = getTrustStore();\n        if (trustStore != null) {\n            customized = true;\n\n            System.setProperty(TRUSTSTORE_LOCATION, trustStore);\n\n            char[] trustStorePassword = getTrustStorePassword();\n            if (trustStorePassword != null)\n                System.setProperty(TRUSTSTORE_PASSWORD, new String(trustStorePassword));\n\n            String trustStoreType = getTrustStoreType();\n            if (trustStoreType != null)\n                System.setProperty(TRUSTSTORE_TYPE, trustStoreType);\n        }\n\n        String enabledProtocols = getEnabledProtocols();\n        if (enabledProtocols != null) {\n            customized = true;\n            System.setProperty(ENABLED_PROTOCOLS, enabledProtocols);\n        }\n\n        String enabledCipherSuites = getEnabledCipherSuites();\n        if (enabledCipherSuites != null) {\n            customized = true;\n            System.setProperty(ENABLED_CIPHER_SUITES, enabledCipherSuites);\n        }\n\n        return customized;\n    }\n\n\n    String getKeyStore() {\n        if (environmentCustomized) return getKeyStoreEnv();\n        else return prefs.get(KEYSTORE_LOCATION, null);\n    }\n\n    static String getKeyStoreEnv() {\n        return System.getProperty(KEYSTORE_LOCATION);\n    }\n\n    void setKeyStore(String keyStore) {\n        if (environmentCustomized)\n            throw new UnsupportedOperationException(CUSTOMIZED_MSG);\n\n        if (keyStore == null) prefs.remove(KEYSTORE_LOCATION);\n        else prefs.put(KEYSTORE_LOCATION, keyStore);\n    }\n\n    char[] getKeyStorePassword() {\n        if (environmentCustomized) return getKeyStorePasswordEnv();\n        String password = prefs.get(KEYSTORE_PASSWORD, null);\n        return password == null ? null : Utils.decodePassword(password).toCharArray();\n    }\n\n    static char[] getKeyStorePasswordEnv() {\n        String password = System.getProperty(KEYSTORE_PASSWORD);\n        return password == null ? null : password.toCharArray();\n    }\n\n    void setKeyStorePassword(char[] keyStorePassword) {\n        if (environmentCustomized)\n            throw new UnsupportedOperationException(CUSTOMIZED_MSG);\n\n        if (keyStorePassword == null) prefs.remove(KEYSTORE_PASSWORD);\n        else prefs.put(KEYSTORE_PASSWORD, Utils.encodePassword(\n                       new String(keyStorePassword)));\n    }\n\n    String getKeyStoreType() {\n        if (environmentCustomized) return getKeyStoreTypeEnv();\n        else return prefs.get(KEYSTORE_TYPE, null);\n    }\n\n    static String getKeyStoreTypeEnv() {\n        return System.getProperty(KEYSTORE_TYPE);\n    }\n\n    void setKeyStoreType(String keyStoreType) {\n        if (environmentCustomized)\n            throw new UnsupportedOperationException(CUSTOMIZED_MSG);\n\n        if (keyStoreType == null) prefs.remove(KEYSTORE_TYPE);\n        else prefs.put(KEYSTORE_TYPE, keyStoreType);\n    }\n\n    String getTrustStore() {\n        if (environmentCustomized) return getTrustStoreEnv();\n        else return prefs.get(TRUSTSTORE_LOCATION, null);\n    }\n\n    static String getTrustStoreEnv() {\n        return System.getProperty(TRUSTSTORE_LOCATION);\n    }\n\n    void setTrustStore(String trustStore) {\n        if (environmentCustomized)\n            throw new UnsupportedOperationException(CUSTOMIZED_MSG);\n\n        if (trustStore == null) prefs.remove(TRUSTSTORE_LOCATION);\n        else prefs.put(TRUSTSTORE_LOCATION, trustStore);\n    }\n\n    char[] getTrustStorePassword() {\n        if (environmentCustomized) return getTrustStorePasswordEnv();\n        String password = prefs.get(TRUSTSTORE_PASSWORD, null);\n        return password == null ? null : Utils.decodePassword(password).toCharArray();\n    }\n\n    static char[] getTrustStorePasswordEnv() {\n        String password = System.getProperty(TRUSTSTORE_PASSWORD);\n        return password == null ? null : password.toCharArray();\n    }\n\n    void setTrustStorePassword(char[] trustStorePassword) {\n        if (environmentCustomized)\n            throw new UnsupportedOperationException(CUSTOMIZED_MSG);\n\n        if (trustStorePassword == null) prefs.remove(TRUSTSTORE_PASSWORD);\n        else prefs.put(TRUSTSTORE_PASSWORD, Utils.encodePassword(\n                       new String(trustStorePassword)));\n    }\n\n    String getTrustStoreType() {\n        if (environmentCustomized) return getTrustStoreTypeEnv();\n        else return prefs.get(TRUSTSTORE_TYPE, null);\n    }\n\n    static String getTrustStoreTypeEnv() {\n        return System.getProperty(TRUSTSTORE_TYPE);\n    }\n\n    void setTrustStoreType(String trustStoreType) {\n        if (environmentCustomized)\n            throw new UnsupportedOperationException(CUSTOMIZED_MSG);\n\n        if (trustStoreType == null) prefs.remove(TRUSTSTORE_TYPE);\n        else prefs.put(TRUSTSTORE_TYPE, trustStoreType);\n    }\n\n    String getEnabledProtocols() {\n        if (environmentCustomized) return getEnabledProtocolsEnv();\n        else return prefs.get(ENABLED_PROTOCOLS, null);\n    }\n\n    static String getEnabledProtocolsEnv() {\n        return System.getProperty(ENABLED_PROTOCOLS);\n    }\n\n    void setEnabledProtocols(String enabledProtocols) {\n        if (environmentCustomized)\n            throw new UnsupportedOperationException(CUSTOMIZED_MSG);\n\n        if (enabledProtocols == null) prefs.remove(ENABLED_PROTOCOLS); // NOI18N\n        else prefs.put(ENABLED_PROTOCOLS, enabledProtocols);\n    }\n\n    String getEnabledCipherSuites() {\n        if (environmentCustomized) return getEnabledCipherSuitesEnv();\n        else return prefs.get(ENABLED_CIPHER_SUITES, null);\n    }\n\n    static String getEnabledCipherSuitesEnv() {\n        return System.getProperty(ENABLED_CIPHER_SUITES);\n    }\n\n    void setEnabledCipherSuites(String enabledCipherSuites) {\n        if (environmentCustomized)\n            throw new UnsupportedOperationException(CUSTOMIZED_MSG);\n        \n        if (enabledCipherSuites == null) prefs.remove(ENABLED_CIPHER_SUITES); // NOI18N\n        else prefs.put(ENABLED_CIPHER_SUITES, enabledCipherSuites);\n    }\n\n\n    private static boolean environmentCustomizedImpl() {\n        if (getKeyStoreEnv() != null) return true;\n        else if (getKeyStorePasswordEnv() != null) return true;\n        else if (getKeyStoreTypeEnv() != null) return true;\n        else if (getTrustStoreEnv() != null) return true;\n        else if (getTrustStorePasswordEnv() != null) return true;\n        else if (getTrustStoreTypeEnv() != null) return true;\n        else if (getEnabledProtocolsEnv() != null) return true;\n        else if (getEnabledCipherSuitesEnv() != null) return true;\n        return false;\n    }\n\n\n    private SecurityModel() {\n        environmentCustomized = environmentCustomizedImpl();\n        prefs = NbPreferences.forModule(SecurityModel.class);\n    }\n\n}\n"
  },
  {
    "path": "plugins/security/src/org/graalvm/visualvm/modules/security/SecurityOptionsPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.security;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.ItemListener;\nimport java.io.File;\nimport java.util.Arrays;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPasswordField;\nimport javax.swing.JTextArea;\nimport javax.swing.JTextField;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass SecurityOptionsPanel extends JPanel {\n\n    private static final String PASSWORD_NOT_CHANGED = \"----------\"; // NOI18N\n\n    private final SecurityOptionsPanelController controller;\n    private boolean dataValid;\n\n    private char[] keyStorePassword;\n    private char[] trustStorePassword;\n    \n\n    SecurityOptionsPanel(SecurityOptionsPanelController controller) {\n        this.controller = controller;\n        initComponents();\n        update();\n    }\n\n\n    void cleanup() {\n        setKeyStorePassword(PASSWORD_NOT_CHANGED.toCharArray());\n        setTrustStorePassword(PASSWORD_NOT_CHANGED.toCharArray());\n    }\n\n    boolean dataValid() {\n        return dataValid;\n    }\n\n    boolean shouldRestart() {\n        return restartCheckBox.isSelected();\n    }\n\n    void resetRestart() {\n        restartCheckBox.setSelected(false);\n    }\n\n\n    String getKeyStore() {\n        if (!keyStoreLocCheckBox.isSelected()) return null;\n        return keyStoreLocField.getText().trim();\n    }\n\n    void setKeyStore(String keyStore) {\n        keyStoreLocCheckBox.setSelected(keyStore != null);\n        if (keyStore != null) keyStoreLocField.setText(keyStore);\n        else keyStoreLocField.setText(\"\"); // NOI18N\n    }\n\n    char[] getKeyStorePassword() {\n        if (!keyStoreLocCheckBox.isSelected()) return null;\n        char[] password = keyStorePassField.getPassword();\n        if (Arrays.equals(password, PASSWORD_NOT_CHANGED.toCharArray()))\n            return keyStorePassword;\n        else\n            return password;\n    }\n\n    void setKeyStorePassword(char[] keyStorePassword) {\n        this.keyStorePassword = keyStorePassword;\n        keyStorePassField.setText(PASSWORD_NOT_CHANGED);\n    }\n\n    String getKeyStoreType() {\n        if (!keyStoreLocCheckBox.isSelected()) return null;\n        if (keyStoreTypeCombo.getSelectedIndex() == 0) return null;\n        return keyStoreTypeCombo.getSelectedItem().toString().trim();\n    }\n\n    void setKeyStoreType(String keyStoreType) {\n        if (keyStoreType == null) keyStoreTypeCombo.setSelectedIndex(0);\n        else keyStoreTypeCombo.setSelectedItem(keyStoreType);\n    }\n\n    String getTrustStore() {\n        if (!trustStoreLocCheckBox.isSelected()) return null;\n        return trustStoreLocField.getText().trim();\n    }\n\n    void setTrustStore(String trustStore) {\n        trustStoreLocCheckBox.setSelected(trustStore != null);\n        if (trustStore != null) trustStoreLocField.setText(trustStore);\n        else trustStoreLocField.setText(\"\"); // NOI18N\n    }\n\n    char[] getTrustStorePassword() {\n        if (!trustStoreLocCheckBox.isSelected()) return null;\n        char[] password = trustStorePassField.getPassword();\n        if (Arrays.equals(password, PASSWORD_NOT_CHANGED.toCharArray()))\n            return trustStorePassword;\n        else\n            return password;\n    }\n\n    void setTrustStorePassword(char[] trustStorePassword) {\n        this.trustStorePassword = trustStorePassword;\n        trustStorePassField.setText(PASSWORD_NOT_CHANGED);\n    }\n\n    String getTrustStoreType() {\n        if (!trustStoreLocCheckBox.isSelected()) return null;\n        if (trustStoreTypeCombo.getSelectedIndex() == 0) return null;\n        return trustStoreTypeCombo.getSelectedItem().toString().trim();\n    }\n\n    void setTrustStoreType(String trustStoreType) {\n        if (trustStoreType == null) trustStoreTypeCombo.setSelectedIndex(0);\n        else trustStoreTypeCombo.setSelectedItem(trustStoreType);\n    }\n\n    String getEnabledProtocols() {\n        if (!protocolsCheckBox.isSelected()) return null;\n        return protocolsField.getText().trim();\n    }\n\n    void setEnabledProtocols(String enabledProtocols) {\n        protocolsCheckBox.setSelected(enabledProtocols != null);\n        if (enabledProtocols != null) protocolsField.setText(enabledProtocols);\n        else protocolsField.setText(\"\"); // NOI18N\n    }\n\n    String getEnabledCipherSuites() {\n        if (!cipherSuitesCheckBox.isSelected()) return null;\n        return cipherSuitesField.getText().trim();\n    }\n\n    void setEnabledCipherSuites(String enabledCipherSuites) {\n        cipherSuitesCheckBox.setSelected(enabledCipherSuites != null);\n        if (enabledCipherSuites != null) cipherSuitesField.setText(enabledCipherSuites);\n        else cipherSuitesField.setText(\"\"); // NOI18N\n    }\n\n\n    private void update() {\n        SecurityModel model = controller.getModel();\n        boolean externallyCustomized = model.environmentCustomized();\n\n        boolean keyStoreCustomized = keyStoreLocCheckBox.isSelected();\n        keyStoreLocCheckBox.setEnabled(!externallyCustomized);\n        keyStoreLocField.setEnabled(!externallyCustomized && keyStoreCustomized);\n        keyStoreLocButton.setEnabled(!externallyCustomized && keyStoreCustomized);\n        keyStorePassLabel.setEnabled(!externallyCustomized && keyStoreCustomized);\n        keyStorePassField.setEnabled(!externallyCustomized && keyStoreCustomized);\n        keyStoreTypeLabel.setEnabled(!externallyCustomized && keyStoreCustomized);\n        keyStoreTypeCombo.setEnabled(!externallyCustomized && keyStoreCustomized);\n        boolean keyStoreValid = !keyStoreCustomized ||\n                                new File(keyStoreLocField.getText().trim()).isFile();\n\n        boolean trustStoreCustomized = trustStoreLocCheckBox.isSelected();\n        trustStoreLocCheckBox.setEnabled(!externallyCustomized);\n        trustStoreLocField.setEnabled(!externallyCustomized && trustStoreCustomized);\n        trustStoreLocButton.setEnabled(!externallyCustomized && trustStoreCustomized);\n        trustStorePassLabel.setEnabled(!externallyCustomized && trustStoreCustomized);\n        trustStorePassField.setEnabled(!externallyCustomized && trustStoreCustomized);\n        trustStoreTypeLabel.setEnabled(!externallyCustomized && trustStoreCustomized);\n        trustStoreTypeCombo.setEnabled(!externallyCustomized && trustStoreCustomized);\n        boolean trustStoreValid = !trustStoreCustomized ||\n                                new File(trustStoreLocField.getText().trim()).isFile();\n\n        boolean protocolsCustomized = protocolsCheckBox.isSelected();\n        protocolsCheckBox.setEnabled(!externallyCustomized);\n        protocolsField.setEnabled(!externallyCustomized && protocolsCustomized);\n        protocolsButton.setEnabled(!externallyCustomized && protocolsCustomized);\n\n        boolean cipherSuitesCustomized = cipherSuitesCheckBox.isSelected();\n        cipherSuitesCheckBox.setEnabled(!externallyCustomized);\n        cipherSuitesField.setEnabled(!externallyCustomized && cipherSuitesCustomized);\n        cipherSuitesButton.setEnabled(!externallyCustomized && cipherSuitesCustomized);\n\n        loadFromFileButton.setEnabled(!externallyCustomized);\n        saveToFileButton.setEnabled(keyStoreCustomized || trustStoreCustomized ||\n                                    protocolsCustomized || cipherSuitesCustomized);\n\n        dataValid = keyStoreValid && trustStoreValid;\n        controller.changed();\n\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                hintPanel.setVisible(controller.differsFromEnv());\n            }\n        });\n    }\n\n\n    private void initComponents() {\n        setLayout(new GridBagLayout());\n\n        GridBagConstraints c;\n\n        // --- Notification header ---------------------------------------------\n\n        // notificationLabel\n        notificationArea = new JTextArea(NbBundle.getMessage(SecurityOptionsPanel.class,\n                                         \"MSG_AlreadyDefined\")); // NOI18N\n        notificationArea.setEditable(false);\n        notificationArea.setEnabled(false);\n        notificationArea.setLineWrap(true);\n        notificationArea.setWrapStyleWord(true);\n        notificationArea.setOpaque(false);\n        notificationArea.setDisabledTextColor(notificationArea.getForeground());\n        notificationArea.setBorder(BorderFactory.createCompoundBorder(\n                BorderFactory.createLineBorder(Color.RED), BorderFactory.createEmptyBorder(5, 5, 5, 5)));\n        notificationArea.setVisible(controller.getModel().environmentCustomized());\n        c = new GridBagConstraints();\n        c.gridy = 0;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 15, 0);\n        add(notificationArea, c);\n\n        // --- KeyStore --------------------------------------------------------\n\n        // keyStoreSeparator\n        SectionSeparator keyStoreSeparator = UISupport.createSectionSeparator(\n                NbBundle.getMessage(SecurityOptionsPanel.class, \"SEP_Certificates\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 0, 0);\n        add(keyStoreSeparator, c);\n\n        // keyStoreLocCheckBox\n        keyStoreLocCheckBox = new JCheckBox();\n        Mnemonics.setLocalizedText(keyStoreLocCheckBox, NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"CHK_KeyStore\")); // NOI18N\n        keyStoreLocCheckBox.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.KEYSTORE_LOCATION)); // NOI18N\n        keyStoreLocCheckBox.addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                update();\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 2;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(7, 10, 0, 0);\n        add(keyStoreLocCheckBox, c);\n\n        // keyStoreField\n        keyStoreLocField = new JTextField();\n        keyStoreLocField.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.KEYSTORE_LOCATION)); // NOI18N\n        keyStoreLocField.setPreferredSize(\n                new Dimension(250, keyStoreLocField.getPreferredSize().height));\n        keyStoreLocField.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) {\n                update();\n            }\n            public void removeUpdate(DocumentEvent e) {\n                update();\n            }\n            public void changedUpdate(DocumentEvent e) {\n                update();\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 2;\n        c.gridwidth = 1;\n        c.weightx = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(7, 5, 0, 0);\n        add(keyStoreLocField, c);\n\n        // keyStoreLocButton\n        keyStoreLocButton = new JButton();\n        Mnemonics.setLocalizedText(keyStoreLocButton,\n                NbBundle.getMessage(SecurityOptionsPanel.class, \"BTN_Browse1\")); // NOI18N\n        keyStoreLocButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                File currentFile = new File(keyStoreLocField.getText().trim());\n                File file = PersistenceSupport.chooseLoadFile(\n                        NbBundle.getMessage(SecurityOptionsPanel.class,\n                        \"CAP_SelectKeyStore\"), currentFile); // NOI18N\n                if (file != null) keyStoreLocField.setText(file.toString());\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 2;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(7, 5, 0, 0);\n        add(keyStoreLocButton, c);\n\n        // keyStoreSettingsPanel\n        JPanel keyStoreSettingsPanel = new JPanel(new GridBagLayout());\n\n        // keyStorePassLabel\n        keyStorePassLabel = new JLabel();\n        Mnemonics.setLocalizedText(keyStorePassLabel, NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"LBL_Password1\")); // NOI18N\n        keyStorePassLabel.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.KEYSTORE_PASSWORD)); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(0, 5, 0, 0);\n        keyStoreSettingsPanel.add(keyStorePassLabel, c);\n\n        // keyStorePassField\n        keyStorePassField = new JPasswordField();\n        keyStorePassLabel.setLabelFor(keyStorePassField);\n        keyStorePassField.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) {\n                update();\n            }\n            public void removeUpdate(DocumentEvent e) {\n                update();\n            }\n            public void changedUpdate(DocumentEvent e) {\n                update();\n            }\n        });\n        keyStorePassField.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.KEYSTORE_PASSWORD)); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.weightx = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(0, 5, 0, 0);\n        keyStoreSettingsPanel.add(keyStorePassField, c);\n\n        // keyStoreTypeLabel\n        keyStoreTypeLabel = new JLabel();\n        Mnemonics.setLocalizedText(keyStoreTypeLabel, NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"LBL_Type1\")); // NOI18N\n        keyStoreTypeLabel.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.KEYSTORE_TYPE)); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.EAST;\n        c.insets = new Insets(0, 25, 0, 0);\n        keyStoreSettingsPanel.add(keyStoreTypeLabel, c);\n\n        // keyStoreTypeCombo\n        keyStoreTypeCombo = new JComboBox(new String[] { NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"OPT_Default\"), \"jks\", \"pkcs12\", \"jceks\" }) { // NOI18N\n            public Dimension getMinimumSize() { return getPreferredSize(); }\n        };\n        keyStoreTypeLabel.setLabelFor(keyStoreTypeCombo);\n        keyStoreTypeCombo.addItemListener(new ItemListener() {\n            public void itemStateChanged(ItemEvent e) {\n                update();\n            }\n        });\n        keyStoreTypeCombo.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.KEYSTORE_TYPE)); // NOI18N\n        keyStoreTypeCombo.setEditable(true);\n        c = new GridBagConstraints();\n        c.gridx = 3;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.EAST;\n        c.insets = new Insets(0, 5, 0, 0);\n        keyStoreSettingsPanel.add(keyStoreTypeCombo, c);\n\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 3;\n        c.weightx = 1;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(5, 0, 0, 0);\n        add(keyStoreSettingsPanel, c);\n\n\n        // --- TrustStore ------------------------------------------------------\n\n        // trustStoreLocLabel\n        trustStoreLocCheckBox = new JCheckBox();\n        Mnemonics.setLocalizedText(trustStoreLocCheckBox, NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"CHK_TrustStore\")); // NOI18N\n        trustStoreLocCheckBox.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.TRUSTSTORE_LOCATION)); // NOI18N\n        trustStoreLocCheckBox.addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                update();\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 5;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(20, 10, 0, 0);\n        add(trustStoreLocCheckBox, c);\n\n        // trustStoreField\n        trustStoreLocField = new JTextField();\n        trustStoreLocField.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.TRUSTSTORE_LOCATION)); // NOI18N\n        trustStoreLocField.setPreferredSize(\n                new Dimension(250, trustStoreLocField.getPreferredSize().height));\n        trustStoreLocField.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) {\n                update();\n            }\n            public void removeUpdate(DocumentEvent e) {\n                update();\n            }\n            public void changedUpdate(DocumentEvent e) {\n                update();\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 5;\n        c.gridwidth = 1;\n        c.weightx = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(20, 5, 0, 0);\n        add(trustStoreLocField, c);\n\n        // trustStoreLocButton\n        trustStoreLocButton = new JButton();\n        Mnemonics.setLocalizedText(trustStoreLocButton,\n                NbBundle.getMessage(SecurityOptionsPanel.class, \"BTN_Browse2\")); // NOI18N\n        trustStoreLocButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                File currentFile = new File(trustStoreLocField.getText().trim());\n                File file = PersistenceSupport.chooseLoadFile(\n                        NbBundle.getMessage(SecurityOptionsPanel.class,\n                        \"CAP_SelectTrustStore\"), currentFile); // NOI18N\n                if (file != null) trustStoreLocField.setText(file.toString());\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 5;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(20, 5, 0, 0);\n        add(trustStoreLocButton, c);\n\n        // trustStoreSettingsPanel\n        JPanel trustStoreSettingsPanel = new JPanel(new GridBagLayout());\n\n        // trustStorePassLabel\n        trustStorePassLabel = new JLabel();\n        Mnemonics.setLocalizedText(trustStorePassLabel, NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"LBL_Password2\")); // NOI18N\n        trustStorePassLabel.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.TRUSTSTORE_PASSWORD)); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(0, 5, 0, 0);\n        trustStoreSettingsPanel.add(trustStorePassLabel, c);\n\n        // trustStorePassField\n        trustStorePassField = new JPasswordField();\n        trustStorePassLabel.setLabelFor(trustStorePassField);\n        trustStorePassField.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) {\n                update();\n            }\n            public void removeUpdate(DocumentEvent e) {\n                update();\n            }\n            public void changedUpdate(DocumentEvent e) {\n                update();\n            }\n        });\n        trustStorePassField.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.TRUSTSTORE_PASSWORD)); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.weightx = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(0, 5, 0, 0);\n        trustStoreSettingsPanel.add(trustStorePassField, c);\n\n        // trustStoreTypeLabel\n        trustStoreTypeLabel = new JLabel();\n        Mnemonics.setLocalizedText(trustStoreTypeLabel, NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"LBL_Type2\")); // NOI18N\n        trustStoreTypeLabel.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.TRUSTSTORE_TYPE)); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.EAST;\n        c.insets = new Insets(0, 25, 0, 0);\n        trustStoreSettingsPanel.add(trustStoreTypeLabel, c);\n\n        // trustStoreTypeCombo\n        trustStoreTypeCombo = new JComboBox(new String[] { NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"OPT_Default\"), \"jks\", \"pkcs12\", \"jceks\" }) { // NOI18N\n            public Dimension getMinimumSize() { return getPreferredSize(); }\n        };\n        trustStoreTypeLabel.setLabelFor(trustStoreTypeCombo);\n        trustStoreTypeCombo.addItemListener(new ItemListener() {\n            public void itemStateChanged(ItemEvent e) {\n                update();\n            }\n        });\n        trustStoreTypeCombo.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.TRUSTSTORE_TYPE)); // NOI18N\n        trustStoreTypeCombo.setEditable(true);\n        c = new GridBagConstraints();\n        c.gridx = 3;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.EAST;\n        c.insets = new Insets(0, 5, 0, 0);\n        trustStoreSettingsPanel.add(trustStoreTypeCombo, c);\n\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 6;\n        c.weightx = 1;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(5, 0, 0, 0);\n        add(trustStoreSettingsPanel, c);\n\n\n        // --- Protocols -------------------------------------------------------\n\n        // protocolsSeparator\n        SectionSeparator protocolsSeparator = UISupport.createSectionSeparator(\n                NbBundle.getMessage(SecurityOptionsPanel.class, \"SEP_Protocols\")); // NOI18N\n        c = new GridBagConstraints();\n        c = new GridBagConstraints();\n        c.gridy = 7;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(18, 0, 0, 0);\n        add(protocolsSeparator, c);\n\n        // protocolsCheckBox\n        protocolsCheckBox = new JCheckBox();\n        Mnemonics.setLocalizedText(protocolsCheckBox, NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"CHK_Protocols\")); // NOI18N\n        protocolsCheckBox.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.ENABLED_PROTOCOLS)); // NOI18N\n        protocolsCheckBox.addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                update();\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 8;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(7, 15, 0, 0);\n        add(protocolsCheckBox, c);\n\n        // protocolsField\n        protocolsField = new JTextField();\n        protocolsField.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.ENABLED_PROTOCOLS)); // NOI18N\n        protocolsField.setPreferredSize(\n                new Dimension(250, protocolsField.getPreferredSize().height));\n        protocolsField.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) {\n                update();\n            }\n            public void removeUpdate(DocumentEvent e) {\n                update();\n            }\n            public void changedUpdate(DocumentEvent e) {\n                update();\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 8;\n        c.gridwidth = 1;\n        c.weightx = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(7, 5, 0, 0);\n        add(protocolsField, c);\n\n        // protocolsButton\n        protocolsButton = new JButton();\n        Mnemonics.setLocalizedText(protocolsButton, NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"BTN_Customize1\")); // NOI18N\n        protocolsButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                String protocols = ValuesCustomizer.customize(\n                                   ValuesCustomizer.PROTOCOLS,\n                                   protocolsField.getText().trim());\n                if (protocols != null) protocolsField.setText(protocols);\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 8;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(7, 5, 0, 0);\n        add(protocolsButton, c);\n\n        // cipherSuitesCheckBox\n        cipherSuitesCheckBox = new JCheckBox();\n        Mnemonics.setLocalizedText(cipherSuitesCheckBox, NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"CHK_CipherSuites\")); // NOI18N\n        cipherSuitesCheckBox.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.ENABLED_CIPHER_SUITES)); // NOI18N\n        cipherSuitesCheckBox.addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                update();\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 9;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(5, 15, 0, 0);\n        add(cipherSuitesCheckBox, c);\n\n        // cipherSuitesField\n        cipherSuitesField = new JTextField();\n        cipherSuitesField.setToolTipText(NbBundle.getMessage(SecurityOptionsPanel.class,\n                \"MSG_ValueOf\", SecurityModel.ENABLED_CIPHER_SUITES)); // NOI18N\n        cipherSuitesField.setPreferredSize(\n                new Dimension(250, cipherSuitesField.getPreferredSize().height));\n        cipherSuitesField.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) {\n                update();\n            }\n            public void removeUpdate(DocumentEvent e) {\n                update();\n            }\n            public void changedUpdate(DocumentEvent e) {\n                update();\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 9;\n        c.gridwidth = 1;\n        c.weightx = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(5, 5, 0, 0);\n        add(cipherSuitesField, c);\n\n        // cipherSuitesButton\n        cipherSuitesButton = new JButton();\n        Mnemonics.setLocalizedText(cipherSuitesButton, NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"BTN_Customize2\")); // NOI18N\n        cipherSuitesButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                String cipherSuites = ValuesCustomizer.customize(\n                                      ValuesCustomizer.CIPHER_SUITES,\n                                      cipherSuitesField.getText().trim());\n                if (cipherSuites != null) cipherSuitesField.setText(cipherSuites);\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 9;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(5, 5, 0, 0);\n        add(cipherSuitesButton, c);\n\n\n        // --- Export / Import -----------------------------------------------------\n\n        // exportImportSeparator\n        SectionSeparator exportImportSeparator = UISupport.createSectionSeparator(\n                NbBundle.getMessage(SecurityOptionsPanel.class, \"SEP_ExportImport\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 10;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(18, 0, 0, 0);\n        add(exportImportSeparator, c);\n\n        // exportImportPanel\n        JPanel exportImportPanel = new JPanel(new GridBagLayout());\n\n        // loadFromFileButton\n        loadFromFileButton = new JButton();\n        Mnemonics.setLocalizedText(loadFromFileButton, NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"BTN_LoadFromFile\")); // NOI18N\n        loadFromFileButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                PersistenceSupport.loadFromFile(SecurityOptionsPanel.this);\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.EAST;\n        c.insets = new Insets(0, 5, 0, 0);\n        exportImportPanel.add(loadFromFileButton, c);\n\n        // saveToFileButton\n        saveToFileButton = new JButton();\n        Mnemonics.setLocalizedText(saveToFileButton, NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"BTN_SaveToFile\")); // NOI18N\n        saveToFileButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                PersistenceSupport.saveToFile(SecurityOptionsPanel.this);\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.EAST;\n        c.insets = new Insets(0, 5, 0, 0);\n        exportImportPanel.add(saveToFileButton, c);\n\n        c = new GridBagConstraints();\n        c.gridy = 11;\n        c.weightx = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.EAST;\n        c.insets = new Insets(7, 0, 0, 0);\n        add(exportImportPanel, c);\n\n        // hintPanel\n        hintPanel = new JPanel(new GridBagLayout());\n        hintPanel.setVisible(false);\n\n        // hintLabel\n        JLabel hintLabel = new JLabel();\n        Mnemonics.setLocalizedText(hintLabel, NbBundle.getMessage(\n                SecurityOptionsPanel.class, \"MSG_RestartVisualVM\")); // NOI18N\n        hintLabel.setIcon(ImageUtilities.loadImageIcon(\n                \"org/graalvm/visualvm/modules/security/resources/infoIcon.png\", false)); // NOI18N)\n        hintLabel.setIconTextGap(10);\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.weightx = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(0, 0, 0, 0);\n        hintPanel.add(hintLabel, c);\n\n        // restartCheckBox\n        restartCheckBox = new JCheckBox();\n        Mnemonics.setLocalizedText(restartCheckBox, NbBundle.getMessage(\n                            SecurityOptionsPanel.class, \"CHK_RestartVisualVM\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(0, 20, 0, 0);\n        hintPanel.add(restartCheckBox, c);\n\n        // --- Filler ---\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 12;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        add(Spacer.create(), c);\n\n        c = new GridBagConstraints();\n        c.gridy = 13;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(30, 0, 0, 0);\n        add(hintPanel, c);\n\n    }\n    \n\n    private JTextArea notificationArea;\n    private JCheckBox keyStoreLocCheckBox;\n    private JTextField keyStoreLocField;\n    private JButton keyStoreLocButton;\n    private JLabel keyStorePassLabel;\n    private JPasswordField keyStorePassField;\n    private JLabel keyStoreTypeLabel;\n    private JComboBox keyStoreTypeCombo;\n    private JCheckBox trustStoreLocCheckBox;\n    private JTextField trustStoreLocField;\n    private JButton trustStoreLocButton;\n    private JLabel trustStorePassLabel;\n    private JPasswordField trustStorePassField;\n    private JLabel trustStoreTypeLabel;\n    private JComboBox trustStoreTypeCombo;\n    private JCheckBox protocolsCheckBox;\n    private JTextField protocolsField;\n    private JButton protocolsButton;\n    private JCheckBox cipherSuitesCheckBox;\n    private JTextField cipherSuitesField;\n    private JButton cipherSuitesButton;\n    private JButton loadFromFileButton;\n    private JButton saveToFileButton;\n    private JPanel hintPanel;\n    private JCheckBox restartCheckBox;\n\n}\n"
  },
  {
    "path": "plugins/security/src/org/graalvm/visualvm/modules/security/SecurityOptionsPanelController.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.security;\n\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport java.util.Arrays;\nimport javax.swing.JComponent;\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.netbeans.spi.options.OptionsPanelController;\nimport org.openide.LifecycleManager;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\n\n@OptionsPanelController.TopLevelRegistration(\n        id = \"SecurityOptions\",\n        categoryName = \"#OptionsCategory_Name_Security\",\n        iconBase = \"org/graalvm/visualvm/modules/security/resources/security.png\",\n        position = 3000\n)\npublic class SecurityOptionsPanelController extends OptionsPanelController {\n    private SecurityModel model = SecurityModel.getInstance();\n    private SecurityOptionsPanel panel;\n    private JComponent component;\n    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);\n    private boolean changed;\n\n\n    public void update() {\n        SecurityOptionsPanel p = getPanel();\n        p.setKeyStore(model.getKeyStore());\n        p.setKeyStorePassword(model.getKeyStorePassword());\n        p.setKeyStoreType(model.getKeyStoreType());\n        p.setTrustStore(model.getTrustStore());\n        p.setTrustStorePassword(model.getTrustStorePassword());\n        p.setTrustStoreType(model.getTrustStoreType());\n        p.setEnabledProtocols(model.getEnabledProtocols());\n        p.setEnabledCipherSuites(model.getEnabledCipherSuites());\n        p.resetRestart();\n    }\n\n    public void applyChanges() {\n        SecurityOptionsPanel p = getPanel();\n        model.setKeyStore(p.getKeyStore());\n        model.setKeyStorePassword(p.getKeyStorePassword());\n        model.setKeyStoreType(p.getKeyStoreType());\n        model.setTrustStore(p.getTrustStore());\n        model.setTrustStorePassword(p.getTrustStorePassword());\n        model.setTrustStoreType(p.getTrustStoreType());\n        model.setEnabledProtocols(p.getEnabledProtocols());\n        model.setEnabledCipherSuites(p.getEnabledCipherSuites());\n\n        if (p.shouldRestart() && differsFromEnv()) {\n            LifecycleManager lcm = LifecycleManager.getDefault();\n            lcm.markForRestart();\n            lcm.exit();\n        }\n    }\n\n    public void cancel() {\n        getPanel().cleanup();\n    }\n\n    public boolean isValid() {\n        return getPanel().dataValid();\n    }\n\n    public boolean isChanged() {\n        SecurityOptionsPanel p = getPanel();\n        if (!equals(p.getKeyStore(), model.getKeyStore())) return true;\n        if (!equals(p.getKeyStorePassword(), model.getKeyStorePassword())) return true;\n        if (!equals(p.getKeyStoreType(), model.getKeyStoreType())) return true;\n        if (!equals(p.getTrustStore(), model.getTrustStore())) return true;\n        if (!equals(p.getTrustStorePassword(), model.getTrustStorePassword())) return true;\n        if (!equals(p.getTrustStoreType(), model.getTrustStoreType())) return true;\n        if (!equals(p.getEnabledProtocols(), model.getEnabledProtocols())) return true;\n        if (!equals(p.getEnabledCipherSuites(), model.getEnabledCipherSuites())) return true;\n        return false;\n    }\n\n    public boolean differsFromEnv() {\n        SecurityOptionsPanel p = getPanel();\n        if (!equals(p.getKeyStore(), SecurityModel.getKeyStoreEnv())) return true;\n        if (!equals(p.getKeyStorePassword(), SecurityModel.getKeyStorePasswordEnv())) return true;\n        if (!equals(p.getKeyStoreType(), SecurityModel.getKeyStoreTypeEnv())) return true;\n        if (!equals(p.getTrustStore(), SecurityModel.getTrustStoreEnv())) return true;\n        if (!equals(p.getTrustStorePassword(), SecurityModel.getTrustStorePasswordEnv())) return true;\n        if (!equals(p.getTrustStoreType(), SecurityModel.getTrustStoreTypeEnv())) return true;\n        if (!equals(p.getEnabledProtocols(), SecurityModel.getEnabledProtocolsEnv())) return true;\n        if (!equals(p.getEnabledCipherSuites(), SecurityModel.getEnabledCipherSuitesEnv())) return true;\n        return false;\n    }\n\n\n    public HelpCtx getHelpCtx() {\n        return null;\n\n    }\n\n\n    public JComponent getComponent(Lookup masterLookup) {\n        return getComponent();\n    }\n\n    public void addPropertyChangeListener(PropertyChangeListener l) {\n        pcs.addPropertyChangeListener(l);\n    }\n\n    public void removePropertyChangeListener(PropertyChangeListener l) {\n        pcs.removePropertyChangeListener(l);\n    }\n\n\n    SecurityModel getModel() {\n        return SecurityModel.getInstance();\n    }\n\n\n    private SecurityOptionsPanel getPanel() {\n        if (panel == null) panel = new SecurityOptionsPanel(this);\n        return panel;\n    }\n\n    private JComponent getComponent() {\n        if (component == null) {\n            component = UISupport.createScrollableContainer(getPanel());\n        }\n        return component;\n    }\n\n    void changed() {\n        if (!changed) {\n            changed = true;\n            pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);\n        }\n        pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);\n    }\n\n    private boolean equals(String o1, String o2) {\n        if (o1 == null && o2 == null) return true;\n        if (o1 != null && o1.equals(o2)) return true;\n        return false;\n    }\n\n    private boolean equals(char[] ch1, char[] ch2) {\n        if (ch1 == null && ch2 == null) return true;\n        return Arrays.equals(ch1, ch2);\n    }\n\n}\n"
  },
  {
    "path": "plugins/security/src/org/graalvm/visualvm/modules/security/ValuesCustomizer.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.security;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseEvent;\nimport java.net.Socket;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.StringTokenizer;\nimport javax.net.SocketFactory;\nimport javax.net.ssl.SSLSocket;\nimport javax.net.ssl.SSLSocketFactory;\nimport javax.swing.AbstractAction;\nimport javax.swing.BorderFactory;\nimport javax.swing.BoundedRangeModel;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JScrollBar;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTable;\nimport javax.swing.JViewport;\nimport javax.swing.KeyStroke;\nimport javax.swing.ScrollPaneConstants;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.TableColumnModelEvent;\nimport javax.swing.event.TableColumnModelListener;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumn;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class ValuesCustomizer extends JPanel {\n\n    // --- Private UI constants ------------------------------------------------\n\n    private static final Color DEFAULT_GRID_COLOR = new Color(240, 240, 240);\n\n    // --- Public customizer types ---------------------------------------------\n    \n    static final ValuesCustomizer PROTOCOLS = new Protocols();\n    static final ValuesCustomizer CIPHER_SUITES = new CipherSuites();\n\n\n    // --- Public entrypoint ---------------------------------------------------\n\n    static String customize(final ValuesCustomizer customizer, String selectedValues) {\n        customizer.init(selectedValues);\n\n        final DialogDescriptor dd = new DialogDescriptor(customizer,\n                                    customizer.dialogTitle(), true, null);\n        final Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n        d.pack();\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { customizer.onShown(); }\n        });\n        d.setVisible(true);\n\n        String result = dd.getValue() != DialogDescriptor.OK_OPTION ? null :\n                                         customizer.getSelectedCipherSuites();\n        customizer.cleanup();\n        return result;\n    }\n\n\n    // --- Predefined customizers ----------------------------------------------\n\n    private static class Protocols extends ValuesCustomizer {\n\n        private String[] allValues;\n\n        String dialogTitle() {\n            return NbBundle.getMessage(ValuesCustomizer.class, \"CAP_SelectProtocols\"); // NOI18N\n        }\n\n        String hintText() {\n            return NbBundle.getMessage(ValuesCustomizer.class, \"HINT_SelectProtocols\"); // NOI18N\n        }\n\n        String valueName() {\n            return NbBundle.getMessage(ValuesCustomizer.class, \"COL_Protocols\"); // NOI18N\n        }\n\n        synchronized String[] allValues() {\n            if (allValues == null) {\n                SocketFactory f = SSLSocketFactory.getDefault();\n                if (!(f instanceof SSLSocketFactory)) allValues = new String[0];\n                try {\n                    Socket s = ((SSLSocketFactory)f).createSocket();\n                    if (!(s instanceof SSLSocket)) allValues = new String[0];\n                    allValues = ((SSLSocket)s).getSupportedProtocols();\n                } catch (Exception e) {\n                    allValues = new String[0];\n                }\n            }\n            return allValues;\n        }\n\n    }\n\n\n    private static class CipherSuites extends ValuesCustomizer {\n\n        private String[] allValues;\n\n        String dialogTitle() {\n            return NbBundle.getMessage(ValuesCustomizer.class, \"CAP_SelectCipherSuites\"); // NOI18N\n        }\n\n        String hintText() {\n            return NbBundle.getMessage(ValuesCustomizer.class, \"HINT_SelectCipherSuites\"); // NOI18N\n        }\n\n        String valueName() {\n            return NbBundle.getMessage(ValuesCustomizer.class, \"COL_CipherSuites\"); // NOI18N\n        }\n\n        synchronized String[] allValues() {\n            if (allValues == null) {\n            SocketFactory f = SSLSocketFactory.getDefault();\n                if (!(f instanceof SSLSocketFactory)) allValues = new String[0];\n                allValues = ((SSLSocketFactory)f).getSupportedCipherSuites();\n            }\n            return allValues;\n        }\n\n    }\n\n\n    // --- Abstract interface --------------------------------------------------\n\n    abstract String dialogTitle();\n\n    abstract String hintText();\n\n    abstract String valueName();\n\n    abstract String[] allValues();\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void init(String selectedValues) {\n        initModels(selectedValues);\n        initComponents();\n    }\n\n    private void onShown() {\n        table.requestFocusInWindow();\n    }\n\n    private String getSelectedCipherSuites() {\n        StringBuilder b = new StringBuilder();\n\n        for (int i = 0; i < model.getRowCount(); i++)\n            if (Boolean.TRUE.equals(model.getValueAt(i, 1)))\n                b.append(model.getValueAt(i, 0).toString() + \",\"); // NOI18N\n\n        int length = b.length();\n        if (length > 0) b.deleteCharAt(length - 1);\n        return b.toString();\n    }\n\n    private void cleanup() {\n        removeAll();\n        table = null;\n        model = null;\n    }\n\n\n    private void initModels(String selectedValues) {\n        String[] allValuesArr = allValues();\n        String[] selectedValuesArr = selectedValues(selectedValues);\n\n        final String[] cipherSuites =\n                mergedValues(allValuesArr, selectedValuesArr);\n        final boolean[] selectedMask =\n                selectedValuesMask(cipherSuites, selectedValuesArr);\n        final int rowsCount = cipherSuites.length;\n\n        model = new DefaultTableModel() {\n            public int getRowCount() { return rowsCount; }\n\n            public int getColumnCount() { return 2; }\n\n            public String getColumnName(int columnIndex) {\n                if (columnIndex == 0) return valueName();\n                else return NbBundle.getMessage(ValuesCustomizer.class, \"COL_Enabled\"); // NOI18N\n            }\n\n            public Class<?> getColumnClass(int columnIndex) {\n                if (columnIndex == 0) return String.class;\n                else return Boolean.class;\n            }\n\n            public boolean isCellEditable(int rowIndex, int columnIndex) {\n                if (columnIndex == 0) return false;\n                else return true;\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                if (columnIndex == 0) return cipherSuites[rowIndex];\n                else return selectedMask[rowIndex];\n            }\n\n            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {\n                if (columnIndex == 1) selectedMask[rowIndex] = (Boolean)aValue;\n            }\n        };\n    }\n\n\n    private static String[] selectedValues(String selectedValues) {\n        StringTokenizer st = new StringTokenizer(selectedValues, \",\"); // NOI18N\n        String[] cipherSuites = new String[st.countTokens()];\n        for (int i = 0; i < cipherSuites.length; i++)\n            cipherSuites[i] = st.nextToken();\n        return cipherSuites;\n    }\n\n    private static String[] mergedValues(String[] supported, String[] selected) {\n        List<String> supportedList = Arrays.asList(supported);\n        List<String> selectedList = Arrays.asList(selected);\n        Set<String> mergedSet = new HashSet(supportedList);\n        mergedSet.addAll(selectedList);\n        List<String> merged = new ArrayList(mergedSet);\n        Collections.sort(merged);\n        return merged.toArray(new String[merged.size()]);\n    }\n\n    private static boolean[] selectedValuesMask(String[] allValues,\n                                                String[] selectedValues) {\n        boolean[] mask = new boolean[allValues.length];\n        List<String> selectedValuesList = Arrays.asList(selectedValues);\n        for (int i = 0; i < mask.length; i++)\n            if (selectedValuesList.contains(allValues[i]))\n                mask[i] = true;\n        return mask;\n    }\n\n\n    private void setAllSelected(boolean selected) {\n        for (int i = 0; i < model.getRowCount(); i++)\n            model.setValueAt(selected, i, 1);\n        model.fireTableDataChanged();\n    }\n\n\n    private void initComponents() {\n        // hintLabel\n        JLabel hintLabel = new JLabel();\n        Mnemonics.setLocalizedText(hintLabel, hintText());\n\n        // table\n        table = new JTable(model) {\n            protected void processMouseEvent(MouseEvent e) {\n                MouseEvent eventToDispatch = e;\n                Point p = e.getPoint();\n                int column = columnAtPoint(p);\n                if (column != 1) {\n                    int row = rowAtPoint(p);\n                    Rectangle cellRect = getCellRect(row, 1, false);\n                    p.x = cellRect.x + 1;\n                    eventToDispatch = new MouseEvent((Component)e.getSource(),\n                            e.getID(), e.getWhen(), e.getModifiers(), p.x, p.y,\n                            e.getClickCount(), e.isPopupTrigger(), e.getButton());\n                }\n                super.processMouseEvent(eventToDispatch);\n            }\n            protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,\n\t\t\t\t\tint condition, boolean pressed) {\n                getColumnModel().getSelectionModel().setSelectionInterval(1, 1);\n                return super.processKeyBinding(ks, e, condition, pressed);\n            }\n            protected void initializeLocalVars() {\n                super.initializeLocalVars();\n                setPreferredScrollableViewportSize(new Dimension(450, 300));\n            }\n        };\n        hintLabel.setLabelFor(table);\n        table.setOpaque(true);\n        table.setBackground(UISupport.getDefaultBackground());\n        table.setRowHeight(defaultRowHeight() + 4);\n        table.setRowMargin(0);\n        table.setAutoCreateRowSorter(true);\n        table.setShowHorizontalLines(false);\n        table.setShowVerticalLines(true);\n        table.setGridColor(DEFAULT_GRID_COLOR);\n        table.setDefaultRenderer(String.class, new Renderer(\n                                 table.getDefaultRenderer(String.class)));\n        table.setDefaultRenderer(Boolean.class, new BooleanRenderer(\n                                 table.getDefaultRenderer(Boolean.class)));\n        table.getColumnModel().setColumnMargin(1);\n        TableColumn c = table.getColumnModel().getColumn(1);\n        c.setMaxWidth(c.getPreferredWidth());\n        c.setResizable(false);\n\n        // viewport\n        JViewport viewport = new Viewport(table);\n\n        // tableScroll\n        JScrollPane tableScroll = new JScrollPane(\n                                      JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,\n                                      JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n        tableScroll.setViewport(viewport);\n        final JScrollBar vScrollBar = tableScroll.getVerticalScrollBar();\n        final BoundedRangeModel vScrollBarModel = vScrollBar.getModel();\n        vScrollBarModel.addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                vScrollBar.setEnabled(vScrollBarModel.getExtent() !=\n                                      vScrollBarModel.getMaximum());\n            }\n        });\n\n        // cornerButton\n        final JButton cornerButton = new JButton();\n        cornerButton.setDefaultCapable(false);\n        cornerButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                JMenuItem selectAll = new JMenuItem (new AbstractAction() {\n                    public void actionPerformed(ActionEvent e) {\n                        setAllSelected(true);\n                    }\n                });\n                Mnemonics.setLocalizedText(selectAll, NbBundle.getMessage(\n                        ValuesCustomizer.class, \"ACT_SelectAll\")); // NOI18N\n                JMenuItem deselectAll = new JMenuItem(new AbstractAction() {\n                    public void actionPerformed(ActionEvent e) {\n                        setAllSelected(false);\n                    }\n                });\n                Mnemonics.setLocalizedText(deselectAll, NbBundle.getMessage(\n                        ValuesCustomizer.class, \"ACT_DeselectAll\")); // NOI18N\n                JPopupMenu popup = new JPopupMenu();\n                popup.add(selectAll);\n                popup.add(deselectAll);\n                Dimension s = popup.getPreferredSize();\n                popup.show(cornerButton, cornerButton.getWidth() / 2 - s.width,\n                                         cornerButton.getHeight() / 2);\n            }\n        });\n        tableScroll.setCorner(ScrollPaneConstants.UPPER_RIGHT_CORNER, cornerButton);\n\n        // this\n        setOpaque(false);\n        setBorder(BorderFactory.createEmptyBorder(15, 10, 5, 10));\n        setLayout(new BorderLayout(5, 5));\n        add(hintLabel, BorderLayout.NORTH);\n        add(tableScroll, BorderLayout.CENTER);\n    }\n\n    private static int defaultRowHeight() {\n        return new JLabel(\"X\").getPreferredSize().height + 4; // NOI18N\n    }\n\n\n    private ValuesCustomizer() {}\n\n\n    private DefaultTableModel model;\n    private JTable table;\n\n\n    private static class Renderer implements TableCellRenderer {\n\n        private static final Color BACKGROUND;\n        private static final Color DARKER_BACKGROUND;\n\n        static {\n            BACKGROUND = UISupport.getDefaultBackground();\n\n            int darkerR = BACKGROUND.getRed() - 11;\n            if (darkerR < 0) darkerR += 26;\n            int darkerG = BACKGROUND.getGreen() - 11;\n            if (darkerG < 0) darkerG += 26;\n            int darkerB = BACKGROUND.getBlue() - 11;\n            if (darkerB < 0) darkerB += 26;\n            DARKER_BACKGROUND = new Color(darkerR, darkerG, darkerB);\n        }\n\n        private TableCellRenderer impl;\n\n\n        Renderer(TableCellRenderer impl) {\n            this.impl = impl;\n        }\n\n\n        protected Object formatValue(JTable table, Object value, boolean isSelected,\n                                     boolean hasFocus, int row, int column) {\n            return value;\n        }\n\n        protected void updateRenderer(Component c, JTable table, Object value,\n                                      boolean isSelected, boolean hasFocus, int row,\n                                      int column) {\n            if (!isSelected) {\n                c.setBackground(row % 2 == 0 ? DARKER_BACKGROUND : BACKGROUND);\n                // Make sure the renderer paints its background (Nimbus)\n                if (c instanceof JComponent) ((JComponent)c).setOpaque(true);\n            }\n        }\n\n        public Component getTableCellRendererComponent(JTable table, Object value,\n                                                       boolean isSelected, boolean hasFocus,\n                                                       int row, int column) {\n\n            if (impl == null) impl = table.getDefaultRenderer(table.getColumnClass(column));\n\n            value = formatValue(table, value, isSelected, false, row, column);\n            Component c = impl.getTableCellRendererComponent(table, value, isSelected,\n                                                             false, row, column);\n            updateRenderer(c, table, value, isSelected, false, row, column);\n\n            return c;\n        }\n\n    }\n\n    private static class BooleanRenderer extends Renderer {\n\n        BooleanRenderer(TableCellRenderer renderer) {\n            super(renderer);\n        }\n\n        public Component getTableCellRendererComponent(JTable table, Object value,\n                                                       boolean isSelected, boolean hasFocus,\n                                                       int row, int column) {\n\n            // Workaround strange selection behavior for newly selected checkbox\n            isSelected = isSelected || hasFocus;\n\n            return super.getTableCellRendererComponent(table, value, isSelected,\n                                                       hasFocus, row, column);\n        }\n\n    }\n\n    private static class Viewport extends JViewport {\n\n        private final JTable view;\n        private final Color background;\n\n        Viewport(JTable view) {\n            super();\n\n            setView(view);\n            this.view = view;\n\n            setOpaque(true);\n            background = view.getBackground();\n            setBackground(background);\n\n            view.getColumnModel().addColumnModelListener(new TableColumnModelListener() {\n                public void columnAdded(TableColumnModelEvent e) { repaint(); }\n                public void columnMoved(TableColumnModelEvent e) { repaint(); }\n                public void columnRemoved(TableColumnModelEvent e) { repaint(); }\n                public void columnMarginChanged(ChangeEvent e) { repaint(); }\n                public void columnSelectionChanged(ListSelectionEvent e) {}\n            });\n        }\n\n        protected void paintComponent(Graphics g) {\n            super.paintComponent(g);\n            paintVerticalLines(g);\n        }\n\n        private void paintVerticalLines(Graphics g) {\n            int height = getHeight();\n            int viewHeight = view.getHeight();\n            if (viewHeight >= height) return;\n\n            g.setColor(background);\n            g.fillRect(0, viewHeight, getWidth(), getHeight() - viewHeight);\n\n            int cellX = 0;\n            int cellWidth;\n            TableColumnModel model = view.getColumnModel();\n            int columnCount = model.getColumnCount();\n\n            g.setColor(DEFAULT_GRID_COLOR);\n            for (int i = 0; i < columnCount; i++) {\n                cellWidth = model.getColumn(i).getWidth();\n                cellX += cellWidth;\n                g.drawLine(cellX - 1, viewHeight, cellX - 1, height);\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/startupprofiler/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.profiler.startup\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.profiler.startup.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/startupprofiler/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.profiler.startup/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/profiler/startup/Bundle.properties\nOpenIDE-Module-Layer: org/graalvm/visualvm/profiler/startup/resources/layer.xml\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "plugins/startupprofiler/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.profiler.startup-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/startupprofiler/nbproject/project.properties",
    "content": "javac.source=1.6\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jiri Sedlacek\n"
  },
  {
    "path": "plugins/startupprofiler/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.profiler.startup</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.profiler</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.profiling</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.28.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.35.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/startupprofiler/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/startupprofiler/src/org/graalvm/visualvm/profiler/startup/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Long-Description=\\\n    Startup Profiler plugin enables instrumented profiling of local applications from their startup. \\\n    Java 5+ applications started by the user running VisualVM are supported. \\\n    See the <a href=\"https://visualvm.github.io/startupprofiler.html\">online documentation</a> for more.\nOpenIDE-Module-Name=Startup Profiler\nOpenIDE-Module-Short-Description=Startup Profiler\nToolbars/StartupProfiler=S&tartup Profiler\n"
  },
  {
    "path": "plugins/startupprofiler/src/org/graalvm/visualvm/profiler/startup/Dialogs.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiler.startup;\n\nimport java.awt.Dialog;\nimport java.awt.Image;\nimport java.awt.Window;\nimport java.lang.ref.WeakReference;\nimport java.util.List;\nimport javax.swing.SwingUtilities;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class Dialogs {\n    \n    private static WeakReference<List<Image>> icons;\n    \n    \n    static Dialog dialog(String caption, Object message) {\n        return dialogImpl(caption, message, DialogDescriptor.PLAIN_MESSAGE);\n    }\n    \n    static Dialog info(String caption, String message) {\n        return dialogImpl(caption, message, DialogDescriptor.INFORMATION_MESSAGE, DialogDescriptor.OK_OPTION);\n    }\n    \n    static Dialog warning(String caption, String message) {\n        return dialogImpl(caption, message, DialogDescriptor.WARNING_MESSAGE, DialogDescriptor.OK_OPTION);\n    }\n    \n    static Dialog error(String caption, String message) {\n        return dialogImpl(caption, message, DialogDescriptor.ERROR_MESSAGE, DialogDescriptor.OK_OPTION);\n    }\n    \n    private static Dialog dialogImpl(String caption, Object message, int type, Object... options) {\n        DialogDescriptor dd = new DialogDescriptor(message, caption);\n        dd.setMessageType(type);\n        \n        dd.setOptions(options);\n        \n        Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n        \n        d.setIconImages(getIcons());\n        d.setResizable(false);\n        \n        return d;\n    }\n    \n    private static List<Image> getIcons() {\n        List<Image> i = icons == null ? null : icons.get();\n        \n        if (i == null)\n            for (Window w : Dialog.getWindows()) {\n                List<Image> images = w.getIconImages();\n                if (images != null && !images.isEmpty()) {\n                    i = images;\n                    icons = new WeakReference(images);\n                    break;\n                }\n            }\n        \n        return i;\n    }\n    \n    static void show(final Dialog d) {\n        Runnable r = new Runnable() {\n            public void run() { d.setVisible(true); }\n        };\n        if (SwingUtilities.isEventDispatchThread()) r.run();\n        else SwingUtilities.invokeLater(r);\n    }\n    \n}\n"
  },
  {
    "path": "plugins/startupprofiler/src/org/graalvm/visualvm/profiler/startup/StartupConfigurator.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiler.startup;\n\nimport org.graalvm.visualvm.core.ui.DesktopUtils;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.profiler.CPUSettingsSupport;\nimport org.graalvm.visualvm.profiler.JDBCSettingsSupport;\nimport org.graalvm.visualvm.profiler.MemorySettingsSupport;\nimport org.graalvm.visualvm.profiler.ProfilerSettingsSupport;\nimport org.graalvm.visualvm.profiler.ProfilerSupport;\nimport org.graalvm.visualvm.profiling.presets.PresetSelector;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPreset;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPresets;\nimport org.graalvm.visualvm.uisupport.HorizontalLayout;\nimport org.graalvm.visualvm.uisupport.SeparatorLine;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport org.graalvm.visualvm.uisupport.VerticalLayout;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.Toolkit;\nimport java.awt.Window;\nimport java.awt.datatransfer.StringSelection;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport java.net.URI;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.ButtonGroup;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JComboBox;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JRadioButton;\nimport javax.swing.JScrollPane;\nimport javax.swing.JSpinner;\nimport javax.swing.JTextArea;\nimport javax.swing.SpinnerNumberModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.text.Caret;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"HINT_ProfileStartup=Profile manually started local application from its startup. Follow these steps to start the profiling session.\",\n    \"STEP_1=1. Specify application configuration:\",\n    \"STEP_2=2. Define profiler settings:\",\n    \"STEP_3=3. Setup profiled application:\",\n    \"CAP_InvalidSettings=Invalid Profiler Settings\",\n    \"MSG_InvalidCPUSettings=Provided CPU settings are invalid.\",\n    \"MSG_InvalidMemorySettings=Provided memory settings are invalid.\",\n    \"LBL_Continue=Continue >>>\",\n    \"LBL_Platform=Platform:\",\n    \"LBL_Architecture=Architecture:\",\n    \"LBL_Port=Port:\",\n    \"BTN_Profile=Profile\",\n    \"LBL_Profile=Profile:\",\n    \"LBL_CPU=CPU\",\n    \"LBL_Memory=Memory\",\n    \"LBL_JDBC=JDBC\",\n    \"BTN_Clipboard=Copy to clipboard\",\n    \"CAP_Clipboard=Copy to Clipboard\",\n    \"MSG_Clipboard=Profiler parameter copied to clipboard\",\n    \"HINT_ConfigureApp=Configure the application to run using {0} {1} and add the following parameter to its JVM arguments:\",\n    \"STR_User=user {0}\",\n    \"STR_CurrentUser=the current user\",\n    \"HINT_StartApp=Click the Profile button to submit this dialog and then start the application as {0}.\",\n    \"CAP_OnlineHelp=Online Help\",\n    \"LBL_OnlineHelp=Online help\",\n    \"MSG_OnlineHelp=Please open the following address in your browser:\"\n})\nfinal class StartupConfigurator {\n    \n    private static final String HELP = \"https://visualvm.github.io/startupprofiler.html\"; // NOI18N\n    \n    private static final String CPU_ICON_PATH = \"org/graalvm/visualvm/profiler/startup/resources/cpu.png\";  // NOI18N\n    private static final String MEM_ICON_PATH = \"org/graalvm/visualvm/profiler/startup/resources/memory.png\";  // NOI18N\n    private static final String JDBC_ICON_PATH = \"org/graalvm/visualvm/profiler/startup/resources/jdbc.png\";  // NOI18N\n    private static final String HELP_ICON_PATH = \"org/graalvm/visualvm/profiler/startup/resources/help.png\";  // NOI18N\n    private static final Icon CPU_ICON = ImageUtilities.loadImageIcon(CPU_ICON_PATH, false);\n    private static final Icon MEM_ICON = ImageUtilities.loadImageIcon(MEM_ICON_PATH, false);\n    private static final Icon JDBC_ICON = ImageUtilities.loadImageIcon(JDBC_ICON_PATH, false);\n    private static final Icon HELP_ICON = ImageUtilities.loadImageIcon(HELP_ICON_PATH, false);\n    \n    private CPUSettingsSupport cpuSettings;\n    private MemorySettingsSupport memorySettings;\n    private JDBCSettingsSupport jdbcSettings;\n    \n    private DefaultComboBoxModel selectorModel;\n    private List<PresetSelector> allSelectors;\n    \n    private JComponent ui;\n    private boolean accepted;\n    \n    private JButton submit;\n    private JTextArea start1;\n    private JTextArea start2;\n    private JTextArea param;\n    \n    private JPanel panel;\n    private Dimension cpuSize;\n    private Dimension memorySize;\n    private Dimension jdbcSize;\n    \n    private JRadioButton cpuSelector;\n    private JRadioButton memorySelector;\n    private JRadioButton jdbcSelector;\n    private JComboBox java;\n    private JComboBox arch;\n    private JSpinner port;\n    \n    private String[] javaPlatforms;\n    private String[] architectures;\n\n    \n    StartupConfigurator() {\n        cpuSettings = new CPUSettingsSupport() {\n            public boolean presetValid() {\n                return cpuSettings.settingsValid() &&\n                       memorySettings.settingsValid() &&\n                       jdbcSettings.settingsValid();\n            }\n            public PresetSelector createSelector(Runnable presetSynchronizer) {\n                return StartupConfigurator.this.createSelector(presetSynchronizer);\n            }\n        };\n        memorySettings = new MemorySettingsSupport() {\n            public boolean presetValid() {\n                return cpuSettings.settingsValid() &&\n                       memorySettings.settingsValid() &&\n                       jdbcSettings.settingsValid();\n            }\n            public PresetSelector createSelector(Runnable presetSynchronizer) {\n                return StartupConfigurator.this.createSelector(presetSynchronizer);\n            }\n        };\n        jdbcSettings = new JDBCSettingsSupport() {\n            public boolean presetValid() {\n                return cpuSettings.settingsValid() &&\n                       memorySettings.settingsValid() &&\n                       jdbcSettings.settingsValid();\n            }\n            public PresetSelector createSelector(Runnable presetSynchronizer) {\n                return StartupConfigurator.this.createSelector(presetSynchronizer);\n            }\n        };\n        \n        // Warmup, the implementation expects both panels to be created\n        cpuSettings.getComponent();\n        memorySettings.getComponent();\n        jdbcSettings.getComponent();\n    }\n    \n    private PresetSelector createSelector(Runnable presetSynchronizer) {\n        if (selectorModel == null) selectorModel = new DefaultComboBoxModel();\n        if (allSelectors == null) allSelectors = new ArrayList();\n        PresetSelector selector = ProfilerPresets.getInstance().createSelector(\n                                  selectorModel, allSelectors, presetSynchronizer);\n        allSelectors.add(selector);\n        return selector;\n    }\n    \n    JComponent getUI() {\n        accepted = false;\n        if (ui == null) ui = createUI();\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { if (submit.isShowing()) submit.requestFocusInWindow(); }\n        });\n        return ui;\n    }\n    \n    boolean accepted() {\n        return accepted;\n    }\n    \n    ProfilerSettingsSupport getSettings() {\n        if (cpuSelector.isSelected()) return cpuSettings;\n        else if (memorySelector.isSelected()) return memorySettings;\n        else if (jdbcSelector.isSelected()) return jdbcSettings;\n        return null;\n    }\n    \n    ProfilerPreset getPreset() {\n        return (ProfilerPreset)selectorModel.getSelectedItem();\n    }\n    \n    String getJavaPlatform() {\n        return javaPlatforms[java.getSelectedIndex()];\n    }\n    \n    int getArchitecture() {\n        return Integer.parseInt(architectures[arch.getSelectedIndex()]);\n    }\n    \n    int getPort() {\n        return (Integer)port.getValue();\n    }\n    \n            \n    private JComponent createUI() {\n        JPanel header = new JPanel(new VerticalLayout(false));\n        header.setOpaque(true);\n        JTextArea hint = new JTextArea(Bundle.HINT_ProfileStartup());\n        hint.setLineWrap(true);\n        hint.setWrapStyleWord(true);\n        hint.setEditable(false);\n        hint.setFocusable(false);\n        hint.setOpaque(false);\n        if (UISupport.isNimbusLookAndFeel()) hint.setBackground(new Color(0, 0, 0, 0));\n        hint.setCaret(new NullCaret());\n        hint.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n        header.add(hint);\n        header.add(new SeparatorLine());\n        \n        JPanel content = new JPanel(new VerticalLayout(false));\n        content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n        content.setOpaque(false);\n        \n        content.add(new SectionSeparator(Bundle.STEP_1()));\n        content.add(createAttachPanel());\n        \n        final JPanel show2 = new JPanel(new BorderLayout());\n        show2.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 3));\n        show2.setOpaque(false);\n        show2.setVisible(false);\n        content.add(show2);\n        \n        final JComponent separator2 = new SectionSeparator(Bundle.STEP_2());\n        final JComponent profilerP = createProfilePanel();\n        content.add(separator2);\n        content.add(profilerP);\n        \n        final JPanel show3 = new JPanel(new BorderLayout());\n        show3.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 3));\n        show3.setOpaque(false);\n        show3.setVisible(false);\n        content.add(show3);\n        \n        final JComponent separator3 = new SectionSeparator(Bundle.STEP_3());\n        final JComponent stepsP = createStepsPanel();\n        content.add(separator3);\n        content.add(stepsP);\n        \n        final JPanel footer = new JPanel(new VerticalLayout(false));\n        footer.setOpaque(true);\n        footer.add(new SeparatorLine(), BorderLayout.NORTH);\n        footer.add(createVerticalSpace(10));\n        JPanel buttons = new JPanel(new BorderLayout(0, 0));\n        JPanel buttonsL = new JPanel(new HorizontalLayout(false));\n        JButton help = new JButton(HELP_ICON) {\n            protected void fireActionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { showHelp(null); } // NOI18N\n                });\n            }\n            public Dimension getPreferredSize() {\n                Dimension d = submit.getPreferredSize();\n                d.width = d.height;\n                return d;\n            }\n        };\n        help.setToolTipText(Bundle.LBL_OnlineHelp());\n        buttonsL.add(createHorizontalSpace(10));\n        buttonsL.add(help);\n        JPanel buttonsR = new JPanel(new HorizontalLayout(false));\n        submit = new JButton(Bundle.BTN_Profile(), new ImageIcon(StartupProfilerAction.ICON)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                String err = null;\n                if (cpuSelector.isSelected()) {\n                    if (!cpuSettings.settingsValid())\n                        err = Bundle.MSG_InvalidCPUSettings();\n                } else if (memorySelector.isSelected()) {\n                    if (!memorySettings.settingsValid())\n                        err = Bundle.MSG_InvalidMemorySettings();\n                }\n                \n                if (err != null) {\n                    Dialogs.show(Dialogs.error(Bundle.CAP_InvalidSettings(), err));\n                } else {\n                    accepted = true;\n                    Window w = SwingUtilities.getWindowAncestor(this);\n                    if (w != null) w.setVisible(false);\n                }\n            }\n        };\n        buttonsR.add(submit);\n//        buttonsC.add(createHorizontalSpace(5));\n//        buttonsC.add(new JButton(\"Cancel\") {\n//            protected void fireActionPerformed(ActionEvent e) {\n//                Window w = SwingUtilities.getWindowAncestor(this);\n//                if (w != null) w.setVisible(false);\n//            }\n//        });\n        buttonsR.add(createHorizontalSpace(10));\n        buttons.add(buttonsL, BorderLayout.WEST);\n        buttons.add(buttonsR, BorderLayout.EAST);\n        footer.add(buttons);\n        footer.add(createVerticalSpace(10));\n        \n        // ---\n        panel = new JPanel(new VerticalLayout(false));\n        panel.setBackground(UISupport.getDefaultBackground());\n        panel.setOpaque(true);\n        panel.add(header);\n        panel.add(content);\n        panel.add(footer);\n        // ---\n        \n        // Read the preferred dialog width to initialize textareas\n        int width = panel.getPreferredSize().width;\n        // Correctly layout multiline textareas\n        hint.setSize(width - widthInsetsInContainer(hint, panel), Integer.MAX_VALUE);\n        start1.setSize(width - widthInsetsInContainer(start1, panel), Integer.MAX_VALUE);\n        start2.setSize(width - widthInsetsInContainer(start2, panel), Integer.MAX_VALUE);\n        // Setup dialog size\n        cpuSize = panel.getPreferredSize();\n        memorySize = new Dimension(cpuSize);\n        memorySize.height -= cpuSettings.getComponent().getPreferredSize().height - memorySettings.getComponent().getPreferredSize().height;\n        jdbcSize = new Dimension(cpuSize);\n        jdbcSize.height -= cpuSettings.getComponent().getPreferredSize().height - jdbcSettings.getComponent().getPreferredSize().height;\n        panel.setPreferredSize(cpuSize);\n        \n        separator2.setVisible(false);\n        profilerP.setVisible(false);\n        separator3.setVisible(false);\n        stepsP.setVisible(false);\n        footer.setVisible(false);\n        \n        show2.setVisible(true);\n        \n        JButton show2A = new JButton(HELP_ICON) {\n            protected void fireActionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { showHelp(\"appconfig\"); } // NOI18N\n                });\n            }\n        };\n        show2A.setToolTipText(Bundle.LBL_OnlineHelp());\n        show2A.setContentAreaFilled(false);\n        show2A.setOpaque(false);\n        show2A.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n        show2A.setBorder(BorderFactory.createEmptyBorder(2, 3, 1, 3));\n        \n        JButton show2B = new JButton(\"<html><a href='#'>\" + Bundle.LBL_Continue() + \"</a></html>\") { // NOI18N\n            protected void fireActionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        separator2.setVisible(true);\n                        profilerP.setVisible(true);\n                        show3.setVisible(true);\n                        show2.setVisible(false);\n                    }\n                });\n            }\n        };\n        show2B.setContentAreaFilled(false);\n        show2B.setOpaque(false);\n        show2B.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n        show2B.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));\n        \n        JPanel show2P = new JPanel(new HorizontalLayout(false));\n        show2P.setOpaque(false);\n        show2P.add(show2A);\n        show2P.add(createHorizontalSpace(1));\n        show2P.add(show2B);\n        \n        show2.add(show2P, BorderLayout.EAST);\n        \n        JButton show3A = new JButton(HELP_ICON) {\n            protected void fireActionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { showHelp(\"profsettings\"); } // NOI18N\n                });\n            }\n        };\n        show3A.setToolTipText(Bundle.LBL_OnlineHelp());\n        show3A.setContentAreaFilled(false);\n        show3A.setOpaque(false);\n        show3A.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n        show3A.setBorder(BorderFactory.createEmptyBorder(2, 3, 1, 3));\n        \n        JButton show3B = new JButton(\"<html><a href='#'>\" + Bundle.LBL_Continue() + \"</a></html>\") { // NOI18N\n            protected void fireActionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        separator3.setVisible(true);\n                        stepsP.setVisible(true);\n                        footer.setVisible(true);\n                        show3.setVisible(false);\n                    }\n                });\n            }\n        };\n        show3B.setContentAreaFilled(false);\n        show3B.setOpaque(false);\n        show3B.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n        show3B.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));\n        \n        JPanel show3P = new JPanel(new HorizontalLayout(false));\n        show3P.setOpaque(false);\n        show3P.add(show3A);\n        show3P.add(createHorizontalSpace(1));\n        show3P.add(show3B);\n        \n        show3.add(show3P, BorderLayout.EAST);\n        \n        return panel;\n    }\n    \n    private JPanel createAttachPanel() {\n        JPanel attach = new JPanel(new HorizontalLayout(false, 5));\n        attach.setBorder(BorderFactory.createEmptyBorder(5, 13, 15, 5));\n        attach.setOpaque(false);\n        \n        attach.add(new JLabel(Bundle.LBL_Platform()));\n        String[][] platforms = ProfilerSupport.getInstance().getSupportedJavaPlatforms();\n        javaPlatforms = platforms[1];\n        java = new JComboBox(platforms[0]) {\n            public Dimension getPreferredSize() { // Workaround for Nimbus LaF\n                Dimension d = super.getPreferredSize();\n                if (UISupport.isNimbusLookAndFeel()) d.width += 5;\n                return d;\n            }\n            protected void selectedItemChanged() {\n                super.selectedItemChanged();\n                if (arch != null) {\n                    String[][] archs = ProfilerSupport.getInstance().getSupportedArchitectures(getJavaPlatform());\n                    architectures = archs[1];\n                    Object sel = arch.getSelectedItem();\n                    arch.setModel(new DefaultComboBoxModel(archs[0]));\n                    if (sel == null) sel = archs[2][0];\n                    if (sel != null) arch.setSelectedItem(sel);\n                    arch.setEnabled(arch.getItemCount() > 1);\n                }\n                \n                updateParam();\n            }\n        };\n        java.setEnabled(java.getItemCount() > 1);\n        attach.add(java);\n        attach.add(createHorizontalSpace(2));\n        attach.add(new JLabel(Bundle.LBL_Architecture()));\n        arch = new JComboBox() {\n            public Dimension getPreferredSize() { // Workaround for Nimbus LaF\n                Dimension d = super.getPreferredSize();\n                if (UISupport.isNimbusLookAndFeel()) d.width += 5;\n                return d;\n            }\n            protected void selectedItemChanged() {\n                super.selectedItemChanged();\n                updateParam();\n            }\n        };\n        java.setSelectedItem(platforms[2][0]);\n        attach.add(arch);\n        attach.add(createHorizontalSpace(2));\n        attach.add(new JLabel(Bundle.LBL_Port()));\n        int portv = ProfilerSupport.getInstance().getDefaultPort();\n        port = new JSpinner(new SpinnerNumberModel(portv, 1, 65535, 1));\n        port.getModel().addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) { updateParam(); }\n        });\n        attach.add(port);\n        \n        return attach;\n    }\n    \n    private JPanel createProfilePanel() {\n        final JComponent cpu = cpuSettings.getComponent();\n        ((JComponent)cpu.getComponent(0)).setBorder(BorderFactory.createEmptyBorder(-3, -10, 0, -10));\n        ((JComponent)cpu.getComponent(1)).setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));\n        \n        final JComponent memory = memorySettings.getComponent();\n        ((JComponent)memory.getComponent(0)).setBorder(BorderFactory.createEmptyBorder(-3, -10, 0, -10));\n        ((JComponent)memory.getComponent(1)).setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));\n        memory.setVisible(false);\n        \n        final JComponent jdbc = jdbcSettings.getComponent();\n        ((JComponent)jdbc.getComponent(0)).setBorder(BorderFactory.createEmptyBorder(-3, -10, 0, -10));\n        ((JComponent)jdbc.getComponent(1)).setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));\n        jdbc.setVisible(false);\n        \n        final JPanel profile = new JPanel(new VerticalLayout(false)); \n        profile.setBorder(BorderFactory.createEmptyBorder(5, 13, 15, 5));\n        profile.setOpaque(false);\n        \n        JPanel mode = new JPanel(new HorizontalLayout(false, 5));\n        mode.setOpaque(false);\n        mode.add(new JLabel(Bundle.LBL_Profile()));\n        final ButtonGroup bg = new ButtonGroup();\n        cpuSelector = new IconRadioButton(Bundle.LBL_CPU(), CPU_ICON, true) {\n            boolean firstEvent = true;\n            { bg.add(this); }\n            protected void fireItemStateChanged(ItemEvent e) {\n                super.fireItemStateChanged(e);\n                if (e.getStateChange() == ItemEvent.SELECTED) {\n                    cpu.setVisible(true);\n                    memory.setVisible(false);\n                    jdbc.setVisible(false);\n                    if (panel != null) {\n                        panel.setPreferredSize(cpuSize);\n                        SwingUtilities.getWindowAncestor(profile).pack();\n                    }\n                }\n            }\n        };\n        mode.add(cpuSelector);\n        memorySelector = new IconRadioButton(Bundle.LBL_Memory(), MEM_ICON, false) {\n            { bg.add(this); }\n            protected void fireItemStateChanged(ItemEvent e) {\n                super.fireItemStateChanged(e);\n                if (e.getStateChange() == ItemEvent.SELECTED) {\n                    cpu.setVisible(false);\n                    memory.setVisible(true);\n                    jdbc.setVisible(false);\n                    if (panel != null) {\n                        panel.setPreferredSize(memorySize);\n                        SwingUtilities.getWindowAncestor(profile).pack();\n                    }\n                }\n            }\n        };\n        mode.add(memorySelector);\n        jdbcSelector = new IconRadioButton(Bundle.LBL_JDBC(), JDBC_ICON, false) {\n            { bg.add(this); }\n            protected void fireItemStateChanged(ItemEvent e) {\n                super.fireItemStateChanged(e);\n                if (e.getStateChange() == ItemEvent.SELECTED) {\n                    cpu.setVisible(false);\n                    memory.setVisible(false);\n                    jdbc.setVisible(true);\n                    if (panel != null) {\n                        panel.setPreferredSize(jdbcSize);\n                        SwingUtilities.getWindowAncestor(profile).pack();\n                    }\n                }\n            }\n        };\n        mode.add(jdbcSelector);\n        profile.add(mode);\n        \n        profile.add(cpu);\n        profile.add(memory);\n        profile.add(jdbc);\n        \n        return profile;\n    }\n    \n    private JPanel createStepsPanel() {\n        JPanel steps = new JPanel(new VerticalLayout(false)); \n        steps.setBorder(BorderFactory.createEmptyBorder(5, 13, 15, 5));\n        steps.setOpaque(false);\n        \n        start1 = new JTextArea();\n        start1.setLineWrap(true);\n        start1.setWrapStyleWord(true);\n        start1.setEditable(false);\n        start1.setFocusable(false);\n        start1.setOpaque(false);\n        if (UISupport.isNimbusLookAndFeel()) start1.setBackground(new Color(0, 0, 0, 0));\n        start1.setCaret(new NullCaret());\n        start1.setBorder(BorderFactory.createEmptyBorder());\n        steps.add(start1);\n        \n        final JPanel arg = new JPanel(new BorderLayout(5, 0));\n        arg.setOpaque(false);\n        TextAreaComponent paramA = createTextArea(1);\n        param = paramA.getTextArea();\n        updateParam();\n        arg.add(paramA, BorderLayout.CENTER);\n        JButton link = new JButton(Bundle.BTN_Clipboard()) {\n            protected void fireActionPerformed(ActionEvent e) {\n                RequestProcessor.getDefault().post(new Runnable() {\n                    public void run() {\n                        StringSelection s = new StringSelection(param.getText());\n                        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s, s);\n                        Dialogs.show(Dialogs.info(Bundle.CAP_Clipboard(), Bundle.MSG_Clipboard()));\n                    }\n                });\n            }\n        };\n        arg.add(link, BorderLayout.EAST);\n        \n        steps.add(createVerticalSpace(8));\n        steps.add(arg);\n        steps.add(createVerticalSpace(8));\n        \n        String user = System.getProperty(\"user.name\"); // NOI18N\n        if (user != null) user = Bundle.STR_User(user);\n        else user = Bundle.STR_CurrentUser();\n        start2 = new JTextArea(Bundle.HINT_StartApp(user));\n        start2.setLineWrap(true);\n        start2.setWrapStyleWord(true);\n        start2.setEditable(false);\n        start2.setFocusable(false);\n        start2.setOpaque(false);\n        if (UISupport.isNimbusLookAndFeel()) start2.setBackground(new Color(0, 0, 0, 0));\n        start2.setCaret(new NullCaret());\n        start2.setBorder(BorderFactory.createEmptyBorder());\n        steps.add(start2);\n        \n        return steps;\n    }\n    \n    private void updateParam() {\n        if (param == null) return;\n        \n        start1.setText(Bundle.HINT_ConfigureApp(java.getSelectedItem().toString(),\n                                                arch.getSelectedItem().toString()));\n        \n        int caret = param.getCaretPosition();\n        param.setText(ProfilerSupport.getInstance().getStartupParameter(\n                      getJavaPlatform(), getArchitecture(), getPort()));\n        try {\n            param.setCaretPosition(caret);\n        } catch (IllegalArgumentException e) {\n            param.setCaretPosition(0);\n        }\n        \n        if (param.isShowing()) {\n            final JComponent c = (JComponent)param.getParent().getParent();\n            c.setBorder(BorderFactory.createLineBorder(Color.RED));\n\n            RequestProcessor.getDefault().post(new Runnable() {\n                public void run() {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            JComponent c = (JComponent)param.getParent().getParent();\n                            c.setBorder(BorderFactory.createLineBorder(Color.GRAY));\n                        }\n                    });\n                }\n            }, 180);\n        }\n    }\n    \n    \n    private static void showHelp(String section) {\n        final String addr = (section == null) ? HELP : HELP + \"#\" + section; // NOI18N\n        if (DesktopUtils.isBrowseAvailable()) {\n            RequestProcessor.getDefault().post(new Runnable() {\n                public void run() {\n                    try {\n                        URI uri = new URI(addr);\n                        DesktopUtils.browse(uri);\n                    } catch (Exception e) { showHelpDialog(addr); }\n                }\n            });\n        } else {\n            showHelpDialog(addr);\n        }\n    }\n    \n    private static void showHelpDialog(final String addr) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                Dialogs.show(Dialogs.info(Bundle.CAP_OnlineHelp(),\n                             Bundle.MSG_OnlineHelp() + \"\\n\" + addr)); // NOI18N\n            }\n        });\n    }\n    \n    private static int widthInsetsInContainer(Container c, Container p) {\n        int w = 0;\n        \n        while (c != null && p != null && c != p) {\n            c = c.getParent();\n            Insets i = c.getInsets();\n            w += i.left + i.right;\n        }\n        \n        return w;\n    }\n    \n    private static JComponent createHorizontalSpace(final int width) {\n        JPanel space = new JPanel(null) {\n            public Dimension getPreferredSize() { return new Dimension(width, 0); }\n            public Dimension getMinimumSize() { return getPreferredSize(); }\n            public Dimension getMaximumSize() { return getPreferredSize(); }\n        };\n        space.setOpaque(false);\n        return space;\n    }\n    \n    private static JComponent createVerticalSpace(final int height) {\n        JPanel space = new JPanel(null) {\n            public Dimension getPreferredSize() { return new Dimension(0, height); }\n            public Dimension getMinimumSize() { return getPreferredSize(); }\n            public Dimension getMaximumSize() { return getPreferredSize(); }\n        };\n        space.setOpaque(false);\n        return space;\n    }\n    \n    private static TextAreaComponent createTextArea(int rows) {\n        final JTextArea rootsArea = new JTextArea();\n        rootsArea.setEditable(false);\n        rootsArea.setFont(new Font(\"Monospaced\", Font.PLAIN, UIManager.getFont(\"Label.font\").getSize())); // NOI18N\n        TextAreaComponent rootsAreaScrollPane = new TextAreaComponent(rootsArea,\n                JScrollPane.VERTICAL_SCROLLBAR_NEVER,\n                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                rootsArea.setEnabled(enabled);\n            }\n        };\n        rootsAreaScrollPane.setBorder(BorderFactory.createLineBorder(Color.GRAY));\n        JTextArea referenceArea = new JTextArea(\"X\"); // NOI18N\n        referenceArea.setFont(rootsArea.getFont());\n        referenceArea.setRows(rows);\n        Insets insets = rootsAreaScrollPane.getInsets();\n        rootsAreaScrollPane.setPreferredSize(new Dimension(1, referenceArea.getPreferredSize().height + \n                (insets != null ? insets.top + insets.bottom : 0)));\n        return rootsAreaScrollPane;\n    }\n    \n    private static class TextAreaComponent extends JScrollPane {\n        public TextAreaComponent(JTextArea textArea, int vPolicy, int hPolicy) { super(textArea, vPolicy, hPolicy); }\n        public JTextArea getTextArea() { return (JTextArea)getViewport().getView(); }\n    }\n    \n    private static class IconRadioButton extends JRadioButton {\n\n        private static final int CHECKBOX_OFFSET = getCheckBoxOffset();\n\n        private final JRadioButton renderer;\n\n        public IconRadioButton(String text, Icon icon, boolean selected) {\n            renderer = new JRadioButton(text, icon) {\n                public boolean hasFocus() {\n                    return IconRadioButton.this.hasFocus();\n                }\n            };\n            renderer.setOpaque(false);\n            renderer.setBorderPainted(false);\n            setSelected(selected);\n            setBorderPainted(false);\n            setOpaque(false);\n        }\n\n        protected void paintComponent(Graphics g) {\n            super.paintComponent(g);\n            g.translate(renderer.getX(), renderer.getY());\n            renderer.paint(g);\n            g.translate(-renderer.getX(), -renderer.getY());\n        }\n\n\n        public void setBounds(int x, int y, int width, int height) {\n            Dimension d = super.getPreferredSize();\n            renderer.setBounds(d.width - CHECKBOX_OFFSET, 0,\n                               width - d.width + CHECKBOX_OFFSET, height);\n            super.setBounds(x, y, width, height);\n        }\n\n        public Dimension getPreferredSize() {\n            Dimension d = super.getPreferredSize();\n            d.width += renderer.getPreferredSize().width - CHECKBOX_OFFSET;\n            return d;\n        }\n\n\n        private static int getCheckBoxOffset() {\n            if (UISupport.isWindowsLookAndFeel()) return 3;\n            else if (UISupport.isNimbusLookAndFeel()) return -3;\n            else if (UISupport.isMetalLookAndFeel()) return 3;\n            else if (UISupport.isAquaLookAndFeel()) return 6;\n            else return 0;\n        }\n\n    }\n    \n    private static final class NullCaret implements Caret {\n        public void install(javax.swing.text.JTextComponent c) {}\n        public void deinstall(javax.swing.text.JTextComponent c) {}\n        public void paint(Graphics g) {}\n        public void addChangeListener(ChangeListener l) {}\n        public void removeChangeListener(ChangeListener l) {}\n        public boolean isVisible() { return false; }\n        public void setVisible(boolean v) {}\n        public boolean isSelectionVisible() { return false; }\n        public void setSelectionVisible(boolean v) {}\n        public void setMagicCaretPosition(Point p) {}\n        public Point getMagicCaretPosition() { return new Point(0, 0); }\n        public void setBlinkRate(int rate) {}\n        public int getBlinkRate() { return 0; }\n        public int getDot() { return 0; }\n        public int getMark() { return 0; }\n        public void setDot(int dot) {}\n        public void moveDot(int dot) {}\n    }\n    \n}\n"
  },
  {
    "path": "plugins/startupprofiler/src/org/graalvm/visualvm/profiler/startup/StartupProfiler.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.profiler.startup;\n\nimport org.graalvm.visualvm.profiler.ProfilerSettingsSupport;\nimport org.graalvm.visualvm.profiler.ProfilerSupport;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPreset;\nimport java.awt.Dialog;\nimport javax.swing.SwingUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"CAP_ProfileStartup=Profile Startup\",\n    \"MSG_AnotherSessionRunning=<html><b>Another profiling session in progress.</b><br><br>Please finish profiling of {0}<br>before starting a new profiling session.</html>\"\n})\nfinal class StartupProfiler {\n    \n    private static StartupProfiler sharedInstance;\n    \n    private StartupConfigurator configurator;\n\n    static synchronized StartupProfiler sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new StartupProfiler();\n        return sharedInstance;\n    }\n    \n    \n    void profileStartup() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                String profiledApp = ProfilerSupport.getInstance().getProfiledApplicationName();\n                if (profiledApp != null) {\n                    Dialogs.show(Dialogs.warning(Bundle.CAP_ProfileStartup(),\n                            Bundle.MSG_AnotherSessionRunning(profiledApp)));\n                    return;\n                }\n\n                if (configurator == null) configurator = new StartupConfigurator();\n\n                Dialog d = Dialogs.dialog(Bundle.CAP_ProfileStartup(), configurator.getUI());\n                d.pack();\n                Dialogs.show(d);\n\n                if (configurator.accepted()) attachToProcess();\n            }\n        });\n    }\n    \n    \n    private void attachToProcess() {\n        final int port = configurator.getPort();\n        final String java = configurator.getJavaPlatform();\n        final int architecture = configurator.getArchitecture();\n        \n        final ProfilerSettingsSupport settings = configurator.getSettings();\n        final ProfilerPreset preset = configurator.getPreset();\n        \n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() {\n                ProfilerSupport.getInstance().profileProcessStartup(java, architecture, port,\n                                                                    settings, preset);\n            }\n        });\n    }\n\n}\n"
  },
  {
    "path": "plugins/startupprofiler/src/org/graalvm/visualvm/profiler/startup/StartupProfilerAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiler.startup;\n\nimport org.graalvm.visualvm.profiler.ProfilerSupport;\nimport java.awt.Image;\nimport java.awt.event.ActionEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ImageIcon;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"NAME_ProfileStartup=Prof&ile Startup\",\n    \"DESC_ProfileStartup=Start new process and profile its startup\"\n})\nfinal class StartupProfilerAction extends AbstractAction {\n    \n    private static final String ICON_PATH = \"org/graalvm/visualvm/profiler/startup/resources/profiler.png\";  // NOI18N\n    static final Image ICON = ImageUtilities.loadImage(ICON_PATH);\n    \n    private static StartupProfilerAction menuInstance;\n    private static StartupProfilerAction toolbarAction;\n    \n    \n    static synchronized StartupProfilerAction toolbarInstance() {\n        if (menuInstance == null) {\n            menuInstance = new StartupProfilerAction();\n            menuInstance.putValue(SMALL_ICON, new ImageIcon(ICON));\n            menuInstance.putValue(\"iconBase\", ICON_PATH);  // NOI18N\n        }\n        return menuInstance;\n    }\n    \n    static synchronized StartupProfilerAction menuInstance() {\n        if (toolbarAction == null) {\n            toolbarAction = new StartupProfilerAction();\n        }\n        return toolbarAction;\n    }\n    \n    \n    public void actionPerformed(ActionEvent actionEvent) {\n        StartupProfiler.sharedInstance().profileStartup();\n    }\n    \n    public boolean isEnabled() {\n        return ProfilerSupport.getInstance().hasSupportedJavaPlatforms();\n    }\n    \n    \n    private StartupProfilerAction() {\n        putValue(Action.NAME, Bundle.NAME_ProfileStartup());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.DESC_ProfileStartup());\n    }\n}\n"
  },
  {
    "path": "plugins/startupprofiler/src/org/graalvm/visualvm/profiler/startup/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    \n    <folder name=\"Actions\">\n        <folder name=\"Other\">\n            <file name=\"org-graalvm-visualvm-profiler-startup-StartupProfilerAction-toolbarInstance.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.profiler.startup.StartupProfilerAction.toolbarInstance\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"Menu\">\n        <folder name=\"Applications\">\n            <file name=\"org-graalvm-visualvm-profiler-startup-StartupProfilerAction-menuInstance.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.profiler.startup.StartupProfilerAction.menuInstance\"/>\n                <attr name=\"position\" intvalue=\"1530\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"Toolbars\">\n        <folder name=\"StartupProfiler\">\n            <attr name=\"position\" intvalue=\"300\"/>\n            <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.graalvm.visualvm.profiler.startup.Bundle\"/>\n            <file name=\"org-graalvm-visualvm-profiler-startup-StartupProfilerAction-toolbarInstance.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-profiler-startup-StartupProfilerAction-toolbarInstance.instance\"/>\n                <attr name=\"position\" intvalue=\"500\"/>\n            </file>\n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "plugins/systray/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.systray\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.systray.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/systray/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.systray/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/systray/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/systray/Install.class\n"
  },
  {
    "path": "plugins/systray/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.systray-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/systray/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=2f82a819\nbuild.xml.script.CRC32=a7b0ec32\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=2f82a819\nnbproject/build-impl.xml.script.CRC32=01ff4d5c\nnbproject/build-impl.xml.stylesheet.CRC32=68e521fc@2.73\n"
  },
  {
    "path": "plugins/systray/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jiri Sedlacek\nmodule.javadoc.packages=org.graalvm.visualvm.modules.systray.*\n"
  },
  {
    "path": "plugins/systray/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.systray</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.18.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/systray/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/systray/src/org/graalvm/visualvm/modules/systray/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Tools\nOpenIDE-Module-Long-Description=\\\n    Allows to minimize/restore running VisualVM instance into/from system tray. \\\n    Not supported on macOS (does nothing).\nOpenIDE-Module-Name=SysTray\nOpenIDE-Module-Short-Description=Allows to minimize running VisualVM instance into system tray.\n"
  },
  {
    "path": "plugins/systray/src/org/graalvm/visualvm/modules/systray/Install.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.systray;\n\nimport org.openide.modules.ModuleInstall;\nimport org.openide.util.Utilities;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n\npublic class Install extends ModuleInstall {\n\n    public void restored() {\n        // SysTray isn't supported for Mac\n        if (Utilities.isMac()) return;\n        \n        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n            public void run() {\n                SysTray.getInstance().initialize();\n            }\n        });\n    }\n    \n    public void uninstalled() {\n        // SysTray isn't supported for Mac\n        if (Utilities.isMac()) return;\n        \n        SysTray.getInstance().uninitialize();\n    }\n    \n}\n"
  },
  {
    "path": "plugins/systray/src/org/graalvm/visualvm/modules/systray/SysTray.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.systray;\n\nimport java.awt.AWTException;\nimport java.awt.CheckboxMenuItem;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Frame;\nimport java.awt.Image;\nimport java.awt.MenuItem;\nimport java.awt.PopupMenu;\nimport java.awt.SystemTray;\nimport java.awt.Toolkit;\nimport java.awt.TrayIcon;\nimport java.awt.Window;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.ItemListener;\nimport java.awt.event.WindowEvent;\nimport java.awt.event.WindowStateListener;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport org.openide.DialogDisplayer;\nimport org.openide.LifecycleManager;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.Exceptions;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.Utilities;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"SysTray_NotSupportedUninstall=<html><b>VisualVM tray icon not supported.</b><br><br>Your system can't display VisualVM tray icon.<br>Please uninstall the plugin.</html>\",\n    \"SysTray_Show=Show\",\n    \"SysTray_Hide=Hide\",\n    \"SysTray_AlwaysOnTop=Always on top\",\n    \"SysTray_HideWhenMinimized=Hide when minimized\",\n    \"SysTray_NoTrayicon=No trayicon when showing\",\n    \"SysTray_Exit=Exit\",\n    \"SysTray_Settings=Settings\",\n    \"SysTray_ModalDialog=<html><b>Modal dialog in the way.</b><br><br>Please close all modal dialogs before hiding VisualVM.</html>\"\n})\nclass SysTray {\n\n    private static SysTray INSTANCE;\n\n    private TrayIcon trayIcon;\n    private Frame mainWindow;\n    private WindowStateListener mainWindowListener;\n\n    private PopupMenu trayPopup;\n    private MenuItem showHideItem;\n    private MenuItem exitItem;\n    private CheckboxMenuItem onTopItem;\n    private CheckboxMenuItem hideMinimizedItem;\n    private CheckboxMenuItem hideTrayIconItem;\n\n    private int lastWindowState;\n    private boolean hideWhenMinimized;\n    private boolean hideTrayIcon;\n\n    private boolean workaround;\n\n\n    static synchronized SysTray getInstance() {\n        if (INSTANCE == null) INSTANCE = new SysTray();\n        return INSTANCE;\n    }\n\n\n    synchronized void initialize() {\n        if (SystemTray.isSupported()) {\n            mainWindow = WindowManager.getDefault().getMainWindow();\n            mainWindowListener = new MainWindowListener();\n\n            lastWindowState = mainWindow.getExtendedState();\n\n            loadSettings();\n\n            if (!hideTrayIcon) showTrayIcon();\n            mainWindow.addWindowStateListener(mainWindowListener);\n        }\n    }\n\n    synchronized void uninitialize() {\n        if (trayIcon != null) hideTrayIcon();\n        if (mainWindow != null && mainWindowListener != null) {\n            mainWindow.removeWindowStateListener(mainWindowListener);\n            mainWindow = null;\n        }\n    }\n\n\n    private void loadSettings() {\n        SysTrayPreferences preferences = SysTrayPreferences.getInstance();\n        hideWhenMinimized = preferences.getHideWhenMinimized();\n        hideTrayIcon = preferences.getHideTrayIcon();\n    }\n\n\n    private void showTrayIcon() {\n        try {\n            SystemTray tray = SystemTray.getSystemTray();\n            if (tray != null) {\n                trayIcon = createTrayIcon();\n                if (trayIcon != null) {\n                    try {\n                        tray.add(trayIcon);\n                    } catch (AWTException e) {\n                        trayIcon = null;\n                        DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(\n                            Bundle.SysTray_NotSupportedUninstall(), NotifyDescriptor.ERROR_MESSAGE));\n                        System.err.println(\"Exception showing tray icon: \" + e); // NOI18N\n                    } catch (Exception e) {\n                        trayIcon = null;\n                        Exceptions.printStackTrace(e);\n                    }\n                }\n            }\n        } catch (Exception e) {\n            Exceptions.printStackTrace(e);\n        }\n    }\n\n    private void hideTrayIcon() {\n        SystemTray tray = SystemTray.getSystemTray();\n        if (tray != null) {\n            try {\n                tray.remove(trayIcon);\n            } catch (Exception e) {\n                Exceptions.printStackTrace(e);\n            }\n        }\n        trayIcon = null;\n    }\n\n\n    private TrayIcon createTrayIcon() {\n        Image image = createTrayImage();\n        String tooltip = createTrayTooltip();\n        trayPopup = createTrayPopup();\n        TrayIcon icon = new TrayIcon(image, tooltip, trayPopup);\n        icon.setImageAutoSize(true);\n\n        icon.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        if (trayPopup.isEnabled()) toggleWindowVisibility();\n                    }\n                });\n            }\n        });\n\n        return icon;\n    }\n\n    private String createTrayTooltip() {\n        return mainWindow.getTitle();\n    }\n\n    private Image createTrayImage() {\n        Dimension iconDimension = SystemTray.getSystemTray().getTrayIconSize();\n        int iconWidth = iconDimension.width;\n        int iconHeight = iconDimension.height;\n\n        if (iconWidth <= 16 && iconHeight <= 16)\n            return ImageUtilities.loadImage(\"org/graalvm/visualvm/modules/systray/resources/icon16.png\"); // NOI18N\n\n        if (iconWidth <= 32 && iconHeight <= 32)\n            return ImageUtilities.loadImage(\"org/graalvm/visualvm/modules/systray/resources/icon32.png\"); // NOI18N\n\n        return ImageUtilities.loadImage(\"org/graalvm/visualvm/modules/systray/resources/icon48.png\"); // NOI18N\n    }\n\n    private PopupMenu createTrayPopup() {\n\n        // \"Show / Hide\" menu item\n        showHideItem = new MenuItem(mainWindow.isVisible() ? Bundle.SysTray_Hide() : Bundle.SysTray_Show());\n        showHideItem.setFont(UIManager.getFont(\"MenuItem.font\").deriveFont(Font.BOLD)); // NOI18N\n        showHideItem.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        toggleWindowVisibility();\n                    }\n                });\n            }\n        });\n\n        // \"Always on top\" menu item\n        if (Toolkit.getDefaultToolkit().isAlwaysOnTopSupported() && mainWindow.isAlwaysOnTopSupported()) {\n            onTopItem = new CheckboxMenuItem(Bundle.SysTray_AlwaysOnTop(), SysTrayPreferences.getInstance().getAlwaysOnTop());\n            onTopItem.setFont(UIManager.getFont(\"MenuItem.font\")); // NOI18N\n            onTopItem.addItemListener(new ItemListener() {\n                public void itemStateChanged(ItemEvent e) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            toggleAlwaysOnTop();\n                        }\n                    });\n                }\n            });\n            toggleAlwaysOnTop(); // Sets initial state\n        }\n\n        // \"Hide when minimized\" menu item\n        hideMinimizedItem = new CheckboxMenuItem(Bundle.SysTray_HideWhenMinimized(), hideWhenMinimized);\n        hideMinimizedItem.setFont(UIManager.getFont(\"MenuItem.font\")); // NOI18N\n        hideMinimizedItem.addItemListener(new ItemListener() {\n            public void itemStateChanged(ItemEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        toggleHideWhenMinimized();\n                    }\n                });\n            }\n        });\n\n        // \"No trayicon when showing\" menu item\n        hideTrayIconItem = new CheckboxMenuItem(Bundle.SysTray_NoTrayicon(), hideTrayIcon);\n        hideTrayIconItem.setFont(UIManager.getFont(\"MenuItem.font\")); // NOI18N\n        hideTrayIconItem.addItemListener(new ItemListener() {\n            public void itemStateChanged(ItemEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        toggleNoShowingIcon();\n                    }\n                });\n            }\n        });\n\n        // \"Exit\" menu item\n        exitItem = new MenuItem(Bundle.SysTray_Exit());\n        exitItem.setFont(UIManager.getFont(\"MenuItem.font\")); // NOI18N\n        exitItem.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        LifecycleManager.getDefault().exit();\n                    }\n                });\n            }\n        });\n\n        // \"Settings\" submenu\n        PopupMenu settingsItem = new PopupMenu(Bundle.SysTray_Settings());\n        settingsItem.setFont(UIManager.getFont(\"MenuItem.font\")); // NOI18N\n        if (onTopItem != null) settingsItem.add(onTopItem);\n        settingsItem.add(hideMinimizedItem);\n        settingsItem.add(hideTrayIconItem);\n\n\n        PopupMenu popupMenu = new PopupMenu();\n        popupMenu.add(showHideItem);\n        popupMenu.add(settingsItem);\n        popupMenu.addSeparator();\n        popupMenu.add(exitItem);\n        return popupMenu;\n    }\n\n    private void toggleWindowVisibility() {\n        if (mainWindow.isVisible()) hideWindow(); // May not hide window when modal dialog(s) in the way\n        else showWindow();\n    }\n\n    private void hideWindow() {\n        Window[] windows = mainWindow.getOwnedWindows();\n        for (Window window : windows) {\n            if (window.isVisible() && window instanceof Dialog)\n                if (((Dialog)window).isModal()) {\n                    trayPopup.setEnabled(false);\n                    DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(\n                            Bundle.SysTray_ModalDialog(), NotifyDescriptor.WARNING_MESSAGE));\n                    trayPopup.setEnabled(true);\n                    return;\n                }\n        }\n\n        mainWindow.setVisible(false);\n        if (!Utilities.isWindows() && (mainWindow.getExtendedState() & Frame.ICONIFIED) != 0) {\n            workaround = true;\n        }\n        if (showHideItem != null) showHideItem.setLabel(Bundle.SysTray_Show());\n    }\n\n    private void showWindow() {\n        mainWindow.setVisible(true);\n        mainWindow.setExtendedState(lastWindowState);\n        showHideItem.setLabel(Bundle.SysTray_Hide());\n        mainWindow.toFront();\n    }\n\n    private void toggleAlwaysOnTop() {\n        mainWindow.setAlwaysOnTop(onTopItem.getState());\n        SysTrayPreferences.getInstance().setAlwaysOnTop(onTopItem.getState());\n    }\n\n    private void toggleHideWhenMinimized() {\n        hideWhenMinimized = hideMinimizedItem.getState();\n        if (hideWhenMinimized && (mainWindow.getExtendedState() & Frame.ICONIFIED) != 0)\n            hideWindow(); // May not hide window when modal dialog(s) in the way\n        SysTrayPreferences.getInstance().setHideWhenMinimized(hideWhenMinimized);\n    }\n\n    private void toggleNoShowingIcon() {\n        hideTrayIcon = hideTrayIconItem.getState();\n        int windowState = mainWindow.getExtendedState();\n        if ((windowState & Frame.ICONIFIED) != 0) {\n            if (hideTrayIcon && trayIcon == null) showTrayIcon();\n        } else {\n            if (hideTrayIcon && trayIcon != null) hideTrayIcon();\n        }\n        SysTrayPreferences.getInstance().setHideTrayIcon(hideTrayIcon);\n    }\n\n\n    private SysTray() {}\n\n\n    private class MainWindowListener implements WindowStateListener {\n\n        public void windowStateChanged(WindowEvent e) {\n            int windowState = e.getNewState();\n            if ((windowState & Frame.ICONIFIED) != 0) {\n                if (workaround) {\n                    workaround = false;\n                    mainWindow.setExtendedState(lastWindowState);\n                } else {\n                    workaround = false;\n                    if (hideWhenMinimized || hideTrayIcon) hideWindow(); // May not hide window when modal dialog(s) in the way\n                    if (!mainWindow.isVisible() && hideTrayIcon && trayIcon == null) showTrayIcon();\n                }\n            } else {\n                lastWindowState = windowState;\n                if (hideTrayIcon && trayIcon != null) hideTrayIcon();\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/systray/src/org/graalvm/visualvm/modules/systray/SysTrayPreferences.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.systray;\n\nimport java.util.prefs.Preferences;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class SysTrayPreferences {\n    \n    private static SysTrayPreferences INSTANCE = new SysTrayPreferences();\n\n    private static final String KEY_ALWAYS_ON_TOP = \"AlwaysOnTop\"; // NOI18N\n    private static final String KEY_HIDE_WHEN_MINIMIZED = \"HideWhenMinimized\";   // NOI18N\n    private static final String KEY_HIDE_TRAY_ICON = \"HideTrayIcon\"; // NOI18N\n    \n    private final static boolean ALWAYS_ON_TOP_DEFAULT = false;\n    private final static boolean HIDE_WHEN_MINIMIZED_DEFAULT = true;\n    private final static boolean HIDE_TRAY_ICON_DEFAULT = false;\n    private final Preferences prefs;\n    \n    \n    static synchronized SysTrayPreferences getInstance() {\n        if (INSTANCE == null) INSTANCE = new SysTrayPreferences();\n        return INSTANCE;\n    }\n    \n    \n    void setAlwaysOnTop(boolean alwaysOnTop) {\n        synchronized(prefs) {\n            prefs.putBoolean(KEY_ALWAYS_ON_TOP, alwaysOnTop);\n        }\n    }\n    \n    boolean getAlwaysOnTop() {\n        synchronized(prefs) {\n            return prefs.getBoolean(KEY_ALWAYS_ON_TOP, ALWAYS_ON_TOP_DEFAULT);\n        }\n    }\n    \n    void setHideWhenMinimized(boolean hideWhenMinimized) {\n        synchronized(prefs) {\n            prefs.putBoolean(KEY_HIDE_WHEN_MINIMIZED, hideWhenMinimized);\n        }\n    }\n    \n    boolean getHideWhenMinimized() {\n        synchronized(prefs) {\n            return prefs.getBoolean(KEY_HIDE_WHEN_MINIMIZED, HIDE_WHEN_MINIMIZED_DEFAULT);\n        }\n    }\n    \n    void setHideTrayIcon(boolean hideTrayIcon) {\n        synchronized(prefs) {\n            prefs.putBoolean(KEY_HIDE_TRAY_ICON, hideTrayIcon);\n        }\n    }\n    \n    boolean getHideTrayIcon() {\n        synchronized(prefs) {\n            return prefs.getBoolean(KEY_HIDE_TRAY_ICON, HIDE_TRAY_ICON_DEFAULT);\n        }\n    }\n    \n    \n    private SysTrayPreferences() {\n        prefs = NbPreferences.forModule(SysTrayPreferences.class);\n    }\n}\n"
  },
  {
    "path": "plugins/threadinspect/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.threadinspect\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.threadinspect.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/threadinspect/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.threadinspect/2\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/threadinspect/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/threadinspect/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "plugins/threadinspect/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.threadinspect-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/threadinspect/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jiri Sedlacek\nnbm.needs.restart=true\nmodule.javadoc.packages=org.graalvm.visualvm.modules.threadinspect.*\n"
  },
  {
    "path": "plugins/threadinspect/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.threadinspect</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application.views</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.13.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/threadinspect/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/threadinspect/src/org/graalvm/visualvm/modules/threadinspect/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Tools\nOpenIDE-Module-Long-Description=\\\n    Threads Inspector adds a new section to the Threads tab showing stack traces for the selected live threads.\nOpenIDE-Module-Name=Threads Inspector\nOpenIDE-Module-Short-Description=Threads Inspector plugin for VisualVM\n"
  },
  {
    "path": "plugins/threadinspect/src/org/graalvm/visualvm/modules/threadinspect/Engine.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.threadinspect;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeansFactory;\nimport java.lang.management.ThreadInfo;\nimport java.lang.management.ThreadMXBean;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class Engine {\n\n    private static final Logger LOGGER = Logger.getLogger(Engine.class.getName());\n\n    private JmxModel jmxModel;\n    private ThreadMXBean threadBean;\n    \n    static Engine getEngine(Application application) {\n         try {\n            JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);\n            if (jmxModel != null && jmxModel.getConnectionState() == ConnectionState.CONNECTED) {\n                JvmMXBeans mxbeans = JvmMXBeansFactory.getJvmMXBeans(jmxModel,\n                        GlobalPreferences.sharedInstance().getThreadsPoll() * 1000);\n                if (jmxModel != null) {\n                    ThreadMXBean tbean = mxbeans.getThreadMXBean();\n                    \n                    if (tbean != null) {\n                        return new Engine(jmxModel,tbean);\n                    }\n                }\n            }\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Problem resolving ThreadMXBean\", t); // NOI18N\n        }\n        return null;       \n    }\n    \n    Engine(JmxModel model, ThreadMXBean tbean) {\n        jmxModel = model;\n        threadBean = tbean;\n    }\n    \n    List<ThreadInfo> getThreadInfos() {\n        List<ThreadInfo> tinfosList = null;\n\n        try {\n            long[] threadIds = threadBean.getAllThreadIds();\n            ThreadInfo[] threadInfos = threadBean.getThreadInfo(threadIds);\n\n            tinfosList = new ArrayList(threadInfos.length);\n            for (ThreadInfo tinfo : threadInfos)\n                if (tinfo != null && tinfo.getThreadName() != null)\n                    tinfosList.add(tinfo);\n            Collections.sort(tinfosList, new Comparator<ThreadInfo>() {\n                public int compare(ThreadInfo ti1, ThreadInfo ti2) {\n                    return ti1.getThreadName().compareTo(ti2.getThreadName());\n                }\n            });\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Problem resolving ThreadInfos\", t); // NOI18N\n        }\n        return tinfosList;\n    }\n\n    String getStackTraces(List<Long> threadIdsL) {\n        long[] threadIds = new long[threadIdsL.size()];\n        for (int i = 0; i < threadIds.length; i++) threadIds[i] = threadIdsL.get(i);\n        String stackTraces = jmxModel.takeThreadDump(threadIds);\n\n        return \"<pre>\" + transform(htmlize(stackTraces)) + \"</pre>\"; // NOI18N\n    }\n    \n    private static String htmlize(String value) {\n        return value.replace(\"&\", \"&amp;\").replace(\"<\", \"&lt;\");     // NOI18N\n    }\n\n    private static String transform(String value) {\n        StringBuilder sb = new StringBuilder();\n        String[] result = value.split(\"\\\\n\"); // NOI18N\n        for (int i = 0; i < result.length; i++) {\n            String line = result[i];\n            if (!line.isEmpty() && !Character.isWhitespace(line.charAt(0))) {\n                sb.append(\"<span style=\\\"color: #0033CC\\\">\"); // NOI18N\n                sb.append(line);\n                sb.append(\"</span><br>\"); // NOI18N\n            } else {\n                sb.append(line);\n                sb.append(\"<br>\"); // NOI18N\n            }\n        }\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "plugins/threadinspect/src/org/graalvm/visualvm/modules/threadinspect/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.threadinspect;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.views.ApplicationViewsSupport;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent.DetailsView;\nimport org.openide.modules.ModuleInstall;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class Installer extends ModuleInstall {\n\n    public void restored() {\n        ApplicationViewsSupport.sharedInstance().getThreadsView().\n                registerPluginProvider(new ThreadsViewPluginProvider());\n    }\n\n\n    private static class ThreadsViewPluginProvider extends DataSourceViewPluginProvider<Application> {\n\n        protected boolean supportsPluginFor(Application application) {\n            return true;\n        }\n\n        protected DataSourceViewPlugin createPlugin(Application application) {\n            return new ThreadInspectorViewPlugin(application);\n        }\n\n    }\n\n    private static class ThreadInspectorViewPlugin extends DataSourceViewPlugin {\n\n        public DetailsView createView(int location) {\n            switch (location) {\n                case DataViewComponent.BOTTOM_LEFT:\n                    return new DataViewComponent.DetailsView(\"Threads inspector\", null,\n                                                 10, new ThreadsInspector((Application)\n                                                 getDataSource()), null);\n                default: return null;\n            }\n        }\n\n\n        ThreadInspectorViewPlugin(Application application) {\n            super(application);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/threadinspect/src/org/graalvm/visualvm/modules/threadinspect/JExtendedSplitPane.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.threadinspect;\n\nimport java.awt.Component;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport javax.swing.JSplitPane;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\n\n\n/**\n * Copy of org.graalvm.visualvm.core.ui.components.JExtendedSplitPane.\n *\n * @author Jiri Sedlacek\n */\nclass JExtendedSplitPane extends JSplitPane {\n\n    private HierarchyListener leftComponentListener;\n    private HierarchyListener rightComponentListener;\n    \n    private double dividerLocation;\n    private int customDividerSize;\n    private double requestedDividerLocation = -1;\n\n    \n    public JExtendedSplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent) {\n        this(newOrientation, false, newLeftComponent, newRightComponent);\n    }\n\n    public JExtendedSplitPane(int newOrientation, boolean newContinuousLayout, Component newLeftComponent,\n                              Component newRightComponent) {\n        super(newOrientation, newContinuousLayout, newLeftComponent, newRightComponent);\n\n        updateVisibility();\n\n        if (!newLeftComponent.isVisible())\n            computeDividerLocationWhenInitiallyHidden(newLeftComponent);\n\n        if (!newRightComponent.isVisible())\n            computeDividerLocationWhenInitiallyHidden(newRightComponent);\n    }\n\n\n    public void setDividerSize(int newSize) {\n        super.setDividerSize(newSize);\n        customDividerSize = newSize;\n    }\n\n    public void setDividerLocation(double requestedDividerLocation) {\n        Component divider = getDivider();\n        if (isVisible() && divider.isVisible()) { // SplitPane fully visible\n            super.setDividerLocation(requestedDividerLocation);\n            dividerLocation = requestedDividerLocation;\n        } else if (isVisible()) { // Divider not visible, will be updated in updateVisibility()\n            dividerLocation = requestedDividerLocation;\n        } else if (!isVisible()) { // SplitPane not visible, dividerLocation will be set on first reasonable getSize()\n            this.requestedDividerLocation = requestedDividerLocation;\n        }\n    }\n\n\n    public void setLeftComponent(Component newLeftComponent) {\n        if (leftComponent != null) {\n            leftComponent.removeHierarchyListener(leftComponentListener);\n            leftComponentListener = null;\n        }\n\n        super.setLeftComponent(newLeftComponent);\n\n        if (getLeftComponent() != null) {\n            leftComponentListener = new VisibilityListener(newLeftComponent);\n            newLeftComponent.addHierarchyListener(leftComponentListener);\n        }\n\n        updateVisibility();\n    }\n\n    public void setRightComponent(Component newRightComponent) {\n        if (rightComponent != null) {\n            rightComponent.removeHierarchyListener(rightComponentListener);\n            rightComponentListener = null;\n        }\n\n        super.setRightComponent(newRightComponent);\n\n        if (getRightComponent() != null) {\n            rightComponentListener = new VisibilityListener(newRightComponent);\n            newRightComponent.addHierarchyListener(rightComponentListener);\n        }\n\n        updateVisibility();\n    }\n    \n\n    public void reshape(int x, int y, int width, int height) {\n        super.reshape(x, y, width, height);\n        if (width > 0 && height > 0 && requestedDividerLocation != -1) {\n            super.setDividerLocation(requestedDividerLocation);\n            dividerLocation = requestedDividerLocation;\n            // SplitPaneUI.paint() needs to be invoked here to set the\n            // BasicSplitPaneUI.painted flag to enable resizing the divider\n            // even if the component hasn't been shown yet.\n            ((BasicSplitPaneUI)getUI()).paint(getGraphics(), this);\n            requestedDividerLocation = -1;\n        }\n    }\n\n    \n    private Component getDivider() {\n        if (ui == null) return null;\n        return ((BasicSplitPaneUI)ui).getDivider();\n    }\n\n    private void computeDividerLocationWhenHidden(Component hiddenComponent) {\n        if (leftComponent.isVisible() || rightComponent.isVisible()) {\n            boolean horiz = getOrientation() == JSplitPane.HORIZONTAL_SPLIT;\n            double size  = horiz ? getSize().getWidth() :\n                                   getSize().getHeight();\n            double csize = horiz ? hiddenComponent.getSize().getWidth() :\n                                   hiddenComponent.getSize().getHeight();\n            computeDividerLocation(hiddenComponent, size, csize);\n        }\n    }\n\n    private void computeDividerLocationWhenInitiallyHidden(Component hiddenComponent) {\n        if (leftComponent.isVisible() || rightComponent.isVisible()) {\n            boolean horiz = getOrientation() == JSplitPane.HORIZONTAL_SPLIT;\n            double size  = horiz ? getPreferredSize().getWidth() :\n                                   getPreferredSize().getHeight();\n            double csize = horiz ? hiddenComponent.getPreferredSize().getWidth() :\n                                   hiddenComponent.getPreferredSize().getHeight();\n            computeDividerLocation(hiddenComponent, size, csize);\n        }\n    }\n\n    private void computeDividerLocation(Component hiddenComponent, double size, double csize) {\n        if (hiddenComponent == leftComponent) {\n            dividerLocation = csize / (size - customDividerSize);\n        } else {\n            dividerLocation = (size - customDividerSize - csize) / (size - customDividerSize);\n        }\n    }\n\n    private void updateVisibility() {\n        Component divider = getDivider(); // null UI, not yet set\n        if (divider == null) return;\n\n        if (leftComponent == null || rightComponent == null) return;\n\n        boolean leftVisible = leftComponent.isVisible();\n        boolean rightVisible = rightComponent.isVisible();\n\n        if (leftVisible && rightVisible) {\n            if (!divider.isVisible()) {\n                JExtendedSplitPane.super.setDividerSize(customDividerSize);\n                divider.setVisible(true);\n                setDividerLocation(dividerLocation);\n            }\n            if (!isVisible()) setVisible(true);\n        } else if (!leftVisible && !rightVisible) {\n            if (isVisible()) setVisible(false);\n        } else {\n            if (divider.isVisible()) {\n                JExtendedSplitPane.super.setDividerSize(0);\n                divider.setVisible(false);\n                setDividerLocation(0);\n            }\n            if (!isVisible()) setVisible(true);\n        }\n\n        if (getParent() != null) getParent().doLayout();\n    }\n\n\n    private class VisibilityListener implements HierarchyListener {\n\n        private boolean wasVisible;\n        private final Component c;\n\n        VisibilityListener(Component c) {\n            this.c = c;\n            wasVisible = c.isVisible();\n        }\n\n        public void hierarchyChanged(HierarchyEvent e) {\n            if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                boolean visible = c.isVisible();\n                if (wasVisible == visible) return;\n\n                wasVisible = visible;\n\n                if (visible) componentShown();\n                else componentHidden(c);\n            }\n        }\n\n        private void componentHidden(Component c) {\n            computeDividerLocationWhenHidden(c);\n\n            // Make sure the component is visible when shown\n            if ((dividerLocation <= 0) || (dividerLocation >= 1))\n                dividerLocation = 0.5;\n\n            updateVisibility();\n        }\n\n        private void componentShown() {\n            updateVisibility();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/threadinspect/src/org/graalvm/visualvm/modules/threadinspect/ThreadsInspector.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.threadinspect;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport org.graalvm.visualvm.uisupport.VerticalLayout;\nimport java.awt.BorderLayout;\nimport java.awt.CardLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.lang.management.ThreadInfo;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport javax.swing.plaf.basic.BasicSplitPaneDivider;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.WeakListeners;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ThreadsInspector extends JPanel implements DataRemovedListener<Application>,\n                                                       PropertyChangeListener {\n\n    private static final Color BACKGROUND;\n    private static final Color ITEM_HIGHLIGHT;\n    private static final Color SPLITTER_HIGHLIGHT;\n\n    private static final int SPACING = getPresenterSpacing();\n\n    private static final String EMPTY = \"E\"; // NOI18N\n    private static final String DATA  = \"D\"; // NOI18N\n\n    static {\n        BACKGROUND = UISupport.getDefaultBackground();\n\n        int darkerR = BACKGROUND.getRed() - 11;\n        if (darkerR < 0) darkerR += 26;\n        int darkerG = BACKGROUND.getGreen() - 11;\n        if (darkerG < 0) darkerG += 26;\n        int darkerB = BACKGROUND.getBlue() - 11;\n        if (darkerB < 0) darkerB += 26;\n        ITEM_HIGHLIGHT = new Color(darkerR, darkerG, darkerB);\n\n        darkerR = BACKGROUND.getRed() - 20;\n        if (darkerR < 0) darkerR += 40;\n        darkerG = BACKGROUND.getGreen() - 20;\n        if (darkerG < 0) darkerG += 40;\n        darkerB = BACKGROUND.getBlue() - 20;\n        if (darkerB < 0) darkerB += 40;\n        SPLITTER_HIGHLIGHT = new Color(darkerR, darkerG, darkerB);\n    }\n\n\n    private final Application application;\n\n    private Engine threadEngine;\n    private Set<Long> selectedThreads;\n\n    private JButton refreshButton;\n    private JPanel threadsContainer;\n    private JPanel threadsContainerContainer;\n    private CardLayout detailsLayout;\n    private JPanel detailsContainer;\n    private HTMLTextArea threadsDetails;\n\n    private Long focusedThreadId = Long.MIN_VALUE;\n\n    private boolean internalDetailsChange;\n\n\n    public ThreadsInspector(Application application) {\n        this.application = application;\n\n        initUI();\n        showProgress();\n        initThreads();\n    }\n\n\n    public void dataRemoved(Application application) {\n        disableUI();\n    }\n\n    public void propertyChange(PropertyChangeEvent evt) {\n        disableUI();\n    }\n\n    \n    private void initUI() {\n        setOpaque(false);\n        setLayout(new BorderLayout(0, 0));\n    }\n\n    private void initThreads() {\n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() {\n                if (application.getState() != Stateful.STATE_AVAILABLE) {\n                    showError(\"Application finished\");\n                } else {\n                    threadEngine = Engine.getEngine(application);\n                    if (threadEngine == null) {\n                        showError(\"Cannot access threads using JMX.\");\n                    } else {\n                        application.notifyWhenRemoved(ThreadsInspector.this);\n                        application.addPropertyChangeListener(Stateful.PROPERTY_STATE,\n                                    WeakListeners.propertyChange(ThreadsInspector.this,\n                                    application));\n\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                createUI();\n                                refreshData();\n                            }\n                        });\n                    }\n                }\n            }\n        });\n    }\n\n    private void refreshData() {\n        if (!refreshButton.isEnabled()) return;\n        \n        if (application.getState() != Stateful.STATE_AVAILABLE) {\n            disableUI();\n            return;\n        }\n\n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() {\n                final List<ThreadInfo> tinfs = threadEngine.getThreadInfos();\n                if (tinfs == null) {\n                    disableUI();\n                    return;\n                }\n\n                if (selectedThreads == null) selectedThreads = new HashSet();\n\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        threadsContainer.removeAll();\n                        List<Long> toDisplay = new ArrayList();\n                        Set<Long> selectedZombies = new HashSet(selectedThreads);\n\n                        for (ThreadInfo tinfo : tinfs) {\n                            String name = tinfo.getThreadName();\n                            final long id = tinfo.getThreadId();\n                            selectedZombies.remove(id);\n                            final JCheckBox cb = new JCheckBox(name, selectedThreads.\n                                                         contains(id)) {\n                                protected void fireActionPerformed(ActionEvent e) {\n                                    focusedThreadId = id;\n                                    if (!selectedThreads.remove(id))\n                                        selectedThreads.add(id);\n                                    refreshData();\n                                }\n                                public Dimension getPreferredSize() {\n                                    Dimension size = super.getPreferredSize();\n                                    size.height += SPACING;\n                                    return size;\n                                }\n                            };\n                            cb.setOpaque(false);\n\n                            JPanel cbp = new JPanel(null) {\n                                public Dimension getPreferredSize() {\n                                    Dimension size = cb.getPreferredSize();\n                                    size.width += 8;\n                                    return size;\n                                }\n                                public void doLayout() {\n                                    cb.setBounds(4, 0, getWidth() - 8, getHeight());\n                                }\n                                public void setEnabled(boolean enabled) {\n                                    super.setEnabled(enabled);\n                                    for (Component c : getComponents())\n                                        c.setEnabled(enabled);\n                                }\n                            };\n                            cbp.setOpaque(true);\n                            cbp.setBackground(threadsContainer.getComponentCount() %\n                                              2 == 0 ? BACKGROUND : ITEM_HIGHLIGHT);\n                            cbp.add(cb, BorderLayout.CENTER);\n                            threadsContainer.add(cbp);\n                            \n                            if (focusedThreadId == id) {\n                                cb.requestFocusInWindow();\n                                focusedThreadId = Long.MIN_VALUE;\n                            }\n\n                            if (cb.isSelected()) toDisplay.add(id);\n                        }\n\n                        selectedThreads.removeAll(selectedZombies);\n\n                        // Workaround for JDK7 bug, JScrollPane doesn't layout\n                        // correctly when in a not-selected JTabPane and updated\n                        // lazily. Overriding isValidateRoot() on JScrollPane\n                        // to return false also works around this problem.\n                        threadsContainerContainer.invalidate();\n                        threadsContainerContainer.validate();\n\n                        if (!toDisplay.isEmpty()) displayStackTraces(toDisplay);\n                        else showDetails(\"\"); // NOI18N\n                    }\n                });\n            }\n        });\n    }\n\n    private void displayStackTraces(final List<Long> toDisplay) {\n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() {\n                final String text = threadEngine.getStackTraces(toDisplay);\n                if (text != null) SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { showDetails(text); }\n                });\n            }\n        });\n    }\n\n    private void disableUI() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                refreshButton.setEnabled(false);\n                threadsContainer.setEnabled(false);\n                \n                Component focused = KeyboardFocusManager.\n                        getCurrentKeyboardFocusManager().getFocusOwner();\n                if (focused != null && focused.getParent() == threadsContainer)\n                        threadsDetails.requestFocusInWindow();\n            }\n        });\n    }\n\n    private void showProgress() {\n        JLabel waitLabel = new JLabel(\"Resolving threads...\", SwingConstants.CENTER);\n        waitLabel.setEnabled(false);\n        add(waitLabel, BorderLayout.CENTER);\n    }\n\n    private void showError(final String error) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                removeAll();\n                add(new HTMLTextArea(\"<b>Unable to inspect threads.</b><br>\" +\n                    error), BorderLayout.CENTER);\n                revalidate();\n                repaint();\n            }\n        });\n    }\n\n    private void showDetails(String text) {\n        internalDetailsChange = true;\n        threadsDetails.setText(text);\n        \n        if (text.isEmpty()) detailsLayout.show(detailsContainer, EMPTY);\n        else detailsLayout.show(detailsContainer, DATA);\n    }\n\n    private void createUI() {\n        JLabel hintLabel = new JLabel(\"<Select thread(s) to display stack traces>\");\n        hintLabel.setHorizontalAlignment(JLabel.CENTER);\n        hintLabel.setOpaque(false);\n        hintLabel.setEnabled(false);\n\n        detailsLayout = new CardLayout();\n        detailsContainer = new JPanel(detailsLayout);\n        detailsContainer.setOpaque(false);\n        detailsContainer.add(hintLabel, EMPTY);\n\n        refreshButton = new JButton(\"Refresh\") {\n            protected void fireActionPerformed(ActionEvent e) { refreshData(); }\n        };\n\n        threadsContainer = new JPanel(new VerticalLayout(false)) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents()) c.setEnabled(enabled);\n            }\n        };\n        threadsContainer.setOpaque(false);\n        \n        threadsDetails = new HTMLTextArea() {\n            private Rectangle lastR;\n            public void scrollRectToVisible(Rectangle r) {\n                if (internalDetailsChange) internalDetailsChange = false;\n                else if (!r.equals(lastR)) super.scrollRectToVisible(r);\n                lastR = r;\n            }\n        };\n        threadsDetails.setForeground(new Color(0xcc, 0x33, 0));\n        detailsContainer.add(threadsDetails, DATA);\n        showDetails(\"\"); // NOI18N\n\n        threadsContainerContainer = new JPanel(new BorderLayout(0, 5));\n        threadsContainerContainer.setOpaque(false);\n        threadsContainerContainer.add(new ScrollableContainer(threadsContainer), BorderLayout.CENTER);\n        threadsContainerContainer.add(refreshButton, BorderLayout.SOUTH);\n\n        final CustomizedSplitPaneUI detailsVerticalSplitterUI = new CustomizedSplitPaneUI();\n        JExtendedSplitPane splitPane = new JExtendedSplitPane(JExtendedSplitPane.\n                HORIZONTAL_SPLIT, threadsContainerContainer, new ScrollableContainer(detailsContainer)) {\n            public void updateUI() {\n                if (getUI() != detailsVerticalSplitterUI)\n                    setUI(detailsVerticalSplitterUI);\n\n                setBorder(null);\n                setOpaque(false);\n                setDividerSize(6);\n                setContinuousLayout(true);\n\n                final BasicSplitPaneDivider divider = ((BasicSplitPaneUI)getUI()).\n                                                       getDivider();\n                divider.setBackground(BACKGROUND);\n                divider.setBorder(null);\n\n                divider.addMouseListener(new MouseAdapter() {\n                    public void mouseEntered(MouseEvent e) {\n                        divider.setBackground(SPLITTER_HIGHLIGHT);\n                        divider.repaint();\n                    }\n                    public void mouseExited(MouseEvent e) {\n                        divider.setBackground(BACKGROUND);\n                        divider.repaint();\n                    }\n                });\n            }\n        };\n        splitPane.setDividerLocation(250);\n\n        removeAll();\n        add(splitPane, BorderLayout.CENTER);\n        revalidate();\n        repaint();\n    }\n\n\n    private static int getPresenterSpacing() {\n        if (UISupport.isNimbusLookAndFeel()) return 6;\n        else if (UISupport.isGTKLookAndFeel()) return 4;\n        else return 2;\n    }\n    \n    private static class CustomizedSplitPaneUI extends BasicSplitPaneUI {\n        public BasicSplitPaneDivider createDefaultDivider() {\n            return new BasicSplitPaneDivider(this) {\n                public void paint(Graphics g) {\n                    Dimension size = getSize();\n                    g.setColor(getBackground());\n                    g.fillRect(0, 0, size.width, size.height);\n                }\n            };\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.tracer\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.tracer.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracer/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nOpenIDE-Module: org.graalvm.visualvm.modules.tracer/2\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/tracer/impl/TracerViewProvider.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/tracer/impl/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.1\n"
  },
  {
    "path": "plugins/tracer/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.tracer-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracer/nbproject/project.properties",
    "content": "is.autoload=true\njavac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jiri Sedlacek\nnbm.needs.restart=true\n"
  },
  {
    "path": "plugins/tracer/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.tracer</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.charts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.options.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.16.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.13.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.10.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.30.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.modules.tracer</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/tracer/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/ItemValueFormatter.java",
    "content": "/*\n *  Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer;\n\nimport java.text.NumberFormat;\n\n/**\n * This class is responsible for formatting item values in the UI. In the current\n * version it formats values for chart tooltips, chart units (min/max values) and\n * details table.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ItemValueFormatter {\n\n    /**\n     * Code for tooltip formatting.\n     */\n    public static final int FORMAT_TOOLTIP = 0;\n    /**\n     * Code for units (min/max values) formatting.\n     */\n    public static final int FORMAT_UNITS = 1;\n    /**\n     * Code for details table formatting.\n     */\n    public static final int FORMAT_DETAILS = 2;\n    /**\n     * Code for exported data formatting.\n     */\n    public static final int FORMAT_EXPORT = 3;\n\n    /**\n     * Predefined formatter providing simple numeric values.\n     * Uses Number.getInstance().toString().\n     */\n    public static final ItemValueFormatter SIMPLE = new ItemValueFormatter() {\n        public String formatValue(long value, int format) {\n            return Long.toString(value);\n        }\n        public String getUnits(int format) {\n            return null;\n        }\n    };\n\n    /**\n     * Predefined formatter for decimal values with custom units.\n     * Uses Number.getInstance().toString().\n     */\n    public static final ItemValueFormatter DEFAULT_DECIMAL = new Decimal();\n    /**\n     * Predefined formatter for memory values. Uses B (Bytes) for tooltip,\n     * details table and export, uses MB for units (min/max values).\n     * Uses Number.getInstance().toString().\n     */\n    public static final ItemValueFormatter DEFAULT_BYTES = new Bytes();\n    /**\n     * Predefined formatter for percent values with custom factor.\n     * Uses Number.getPercentInstance().toString().\n     */\n    public static final ItemValueFormatter DEFAULT_PERCENT = new Percent();\n    /**\n     * Predefined formatter for bytes/sec values. Uses B/s (Bytes/sec) for tooltip,\n     * details table and export, uses kB/s for units (min/max values).\n     * Uses Number.getInstance().toString().\n     */\n    public static final ItemValueFormatter DEFAULT_BYTES_PER_SEC = new BytesSec();\n\n\n    /**\n     * Returns value formatted in the requested format.\n     *\n     * @param value value to be formatted\n     * @param format format to be used\n     * @return value formatted in the requested format\n     */\n    public abstract String formatValue(long value, int format);\n\n    /**\n     * Returns value units for the requested format.\n     *\n     * @param format format to be used\n     * @return value units for the requested format or null for no units\n     */\n    public abstract String getUnits(int format);\n\n\n    /**\n     * Predefined formatter for decimal values with custom factor and units.\n     * Uses Number.getInstance().toString().\n     */\n    public static final class Decimal extends ItemValueFormatter {\n        \n        private static final NumberFormat FORMAT = NumberFormat.getInstance();\n\n        private final int factor;\n        private final String units;\n\n\n        Decimal() {\n            this(1, null);\n        }\n\n        /**\n         * Creates new instance of Decimal formatter with the defined units.\n         * The values are computed as value / factor.\n         *\n         * @param factor factor for computing values\n         * @param units units\n         */\n        public Decimal(int factor, String units) {\n            this.factor = factor;\n            this.units = units;\n        }\n\n\n        public String formatValue(long value, int format) {\n            return FORMAT.format(value / factor);\n        }\n        \n        public String getUnits(int format) {\n            return units;\n        }\n        \n    }\n\n\n    /**\n     * Predefined formatter for memory values. Uses B (Bytes) for tooltip,\n     * details table and export, uses MB for units (min/max values).\n     * Uses Number.getInstance().toString().\n     */\n    private static final class Bytes extends ItemValueFormatter {\n\n        private static final NumberFormat FORMAT = NumberFormat.getInstance();\n\n\n        Bytes() {}\n\n\n        public String formatValue(long value, int format) {\n            switch (format) {\n                case FORMAT_TOOLTIP:\n                case FORMAT_DETAILS:\n                case FORMAT_EXPORT:\n                    return FORMAT.format(value);\n                case FORMAT_UNITS:\n                    String est = value == 0 ? \"\" : \"~\";\n                    return est + FORMAT.format(Math.round(value / 1024.0 / 1024.0));\n                default:\n                    return null;\n            }\n        }\n        \n        public String getUnits(int format) {\n            switch (format) {\n                case FORMAT_TOOLTIP:\n                case FORMAT_DETAILS:\n                case FORMAT_EXPORT:\n                    return \"B\";\n                case FORMAT_UNITS:\n                    return \"MB\";\n                default:\n                    return null;\n            }\n        }\n        \n    }\n\n    /**\n     * Predefined formatter for bytes/sec values. Uses B/s (Bytes/sec) for tooltip,\n     * details table and export, uses kB/s for units (min/max values).\n     * Uses Number.getInstance().toString().\n     */\n    private static final class BytesSec extends ItemValueFormatter {\n\n        private static final NumberFormat FORMAT = NumberFormat.getInstance();\n\n\n        public String formatValue(long value, int format) {\n            switch (format) {\n                case FORMAT_TOOLTIP:\n                case FORMAT_DETAILS:\n                case FORMAT_EXPORT:\n                    return FORMAT.format(value);\n                case FORMAT_UNITS:\n                    String est = value == 0 ? \"\" : \"~\";\n                    return est + FORMAT.format(Math.round(value / 1024.0));\n                default:\n                    return null;\n            }\n        }\n\n        public String getUnits(int format) {\n            switch (format) {\n                case FORMAT_TOOLTIP:\n                case FORMAT_DETAILS:\n                case FORMAT_EXPORT:\n                    return \"B/s\";\n                case FORMAT_UNITS:\n                    return \"kB/s\";\n                default:\n                    return null;\n            }\n        }\n    }\n\n    /**\n     * Predefined formatter for percent values with custom factor.\n     * Uses Number.getPercentInstance().toString().\n     */\n    public static final class Percent extends ItemValueFormatter {\n\n        private static final NumberFormat PERCENT_FORMAT;\n        private static final NumberFormat NUMBER_FORMAT;\n\n        static {\n            PERCENT_FORMAT = NumberFormat.getPercentInstance();\n            PERCENT_FORMAT.setMinimumFractionDigits(1);\n            PERCENT_FORMAT.setMaximumIntegerDigits(3);\n            NUMBER_FORMAT = NumberFormat.getInstance();\n            NUMBER_FORMAT.setMinimumFractionDigits(1);\n            NUMBER_FORMAT.setMaximumIntegerDigits(3);\n        }\n        \n        private double factor;\n\n\n        Percent() {\n            this(3);\n        }\n\n        /**\n         * Creates new instance of Percent formatter with the defined decimal\n         * exponent. The values are computed as value / Math.pow(10, decexp).\n         *\n         * @param decexp decimal exponent for computing values\n         */\n        public Percent(int decexp) {\n            factor = Math.pow(10, decexp);\n        }\n\n\n        public String formatValue(long value, int format) {\n            switch (format) {\n                case FORMAT_TOOLTIP:\n                case FORMAT_UNITS:\n                    return PERCENT_FORMAT.format(value / factor);\n                case FORMAT_DETAILS:\n                case FORMAT_EXPORT:\n                    return NUMBER_FORMAT.format(value * 100 / factor);\n                default:\n                    return null;\n            }\n        }\n        \n        public String getUnits(int format) {\n            switch (format) {\n                case FORMAT_TOOLTIP:\n                case FORMAT_UNITS:\n                    return null; // '%' provided by NumberFormat.getPercentInstance()\n                case FORMAT_DETAILS:\n                case FORMAT_EXPORT:\n                    return \"%\"; // '%' is part of column header\n                default:\n                    return null;\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/PackageStateHandler.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\n\n/**\n * PackageStateHandler interface allows an implementing TracerPackage to be\n * notified about Tracer session state. See TracerPackage.getStateHandler().\n *\n * @author Jiri Sedlacek\n * @param <X> any DataSource type\n */\npublic interface PackageStateHandler<X extends DataSource> {\n\n    /**\n     * Invoked when a probe is added into the Timeline view.\n     * \n     * @param probe added probe\n     * @param dataSource monitored DataSource\n     */\n    public void probeAdded(TracerProbe<X> probe, X dataSource);\n\n    /**\n     * Invoked when a probe is removed from the Timeline view.\n     *\n     * @param probe removed probe\n     * @param dataSource monitored DataSource\n     */\n    public void probeRemoved(TracerProbe<X> probe, X dataSource);\n\n\n    /**\n     * Invoked when setting up a new Tracer session. This method allows a\n     * Package to notify the user about initialization progress. The actual\n     * initialization (and updating the TracerProgressObject) should be\n     * performed in the sessionStarting() method. Useful for example for\n     * messaging a delay during instrumention of classes in target application.\n     *\n     * @param probes probes defined for the Tracer session\n     * @param dataSource monitored DataSource\n     * @param refresh session refresh rate in miliseconds\n     * @return TracerProgressObject to track initialization progress\n     */\n    public TracerProgressObject sessionInitializing(TracerProbe<X>[] probes,\n            X dataSource, int refresh);\n\n    /**\n     * Invoked when starting a new Tracer session. Any package/probes\n     * initialization should be performed in this method. If provided by the\n     * sessionInitializing method, a TracerProgressObject should be updated to\n     * reflect the initialization progress. This method may throw a\n     * SessionInitializationException in case of initialization failure. Any\n     * packages/probes initialized so far will be correctly finished, however the\n     * package throwing the SessionInitializationException is responsible for\n     * cleaning up any used resources and restoring its state without any\n     * following events.\n     *\n     * @param probes probes defined for the Tracer session\n     * @param dataSource monitored DataSource\n     * @throws SessionInitializationException in case of initialization failure\n     */\n    public void sessionStarting(TracerProbe<X>[] probes, X dataSource)\n            throws SessionInitializationException;\n\n    /**\n     * Invoked when all packages/probes have been started and the Tracer session\n     * is running and collecting data.\n     *\n     * @param probes probes defined for the Tracer session\n     * @param dataSource monitored DataSource\n     */\n    public void sessionRunning(TracerProbe<X>[] probes, X dataSource);\n\n    /**\n     * Invoked when stopping the Tracer session. Any package/probes cleanup\n     * should be performed in this method. Any long-running cleanup code should\n     * preferably be invoked in a separate worker thread to allow the Tracer\n     * session to finish as fast as possible. Be sure to check/wait for the\n     * cleanup thread when starting a new Tracer session in sessionStarting().\n     * \n     * @param probes probes defined for the Tracer session\n     * @param dataSource monitored DataSource\n     */\n    public void sessionStopping(TracerProbe<X>[] probes, X dataSource);\n\n    /**\n     * Invoked when the Tracer session has finished.\n     *\n     * @param probes probes defined for the Tracer session\n     * @param dataSource monitored DataSource\n     */\n    public void sessionFinished(TracerProbe<X>[] probes, X dataSource);\n\n    /**\n     * Invoked when refresh rate of the Tracer session has been changed.\n     *\n     * @param probes probes defined for the Tracer session\n     * @param dataSource monitored DataSource\n     * @param refresh session refresh rate in miliseconds\n     */\n    public void refreshRateChanged(TracerProbe<X>[] probes, X dataSource, int refresh);\n\n\n    /**\n     * An abstract adapter class for receiving Tracer session state notifications.\n     *\n     * @param <X> any DataSource type\n     */\n    public abstract class Adapter<X extends DataSource> implements PackageStateHandler<X> {\n\n        public void probeAdded(TracerProbe<X> probe, X dataSource) {}\n\n        public void probeRemoved(TracerProbe<X> probe, X dataSource) {}\n\n        /**\n         * Invoked when setting up a new Tracer session. This method allows a\n         * Package to notify the user about initialization progress. The actual\n         * initialization (and updating the TracerProgressObject) should be\n         * performed in the sessionStarting() method. Useful for example for\n         * messaging a delay during instrumention of classes in target application.\n         *\n         * @param probes probes defined for the Tracer session\n         * @param dataSource monitored DataSource\n         * @param refresh session refresh rate in miliseconds\n         * @return TracerProgressObject null in default implementation\n         */\n        public TracerProgressObject sessionInitializing(TracerProbe<X>[] probes,\n                X dataSource, int refresh) { return null; }\n\n        public void sessionStarting(TracerProbe<X>[] probes, X dataSource)\n                throws SessionInitializationException {}\n\n        public void sessionRunning(TracerProbe<X>[] probes, X dataSource) {}\n\n        public void sessionStopping(TracerProbe<X>[] probes, X dataSource) {}\n\n        public void sessionFinished(TracerProbe<X>[] probes, X dataSource) {}\n\n        public void refreshRateChanged(TracerProbe<X>[] probes, X dataSource,\n                int refresh) {}\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/ProbeItemDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer;\n\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.items.ContinuousXYItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.items.DiscreteXYItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.items.ValueItemDescriptor;\nimport java.awt.Color;\n\n/**\n * ProbeItemDescriptor describes a TracerProbe item appearance in the UI.\n * <p>\n *\n * Current version supports two general types of items: continuous and discrete.\n * Continuous items consist of non-rectangular polyline or polygon segments\n * connecting the values. The values define vertices of the segments.\n * <p>\n *\n * Discrete items consist of rectangular segments either connected together or\n * divided into bar segments. The values are located in the middle of the segments.\n * <p>\n *\n * Each descriptor requires a common set of mandatory options:\n * <ul>\n * <li><code>name</code>: item name</li>\n * <li><code>description</code>: item description, may be <code>null</code></li>\n * <li><code>formatter</code>: ItemValueFormatter instance which defines how the item values are presented in UI</li>\n * </ul>\n * <p>\n *\n * The other options which may be set are:\n * <ul>\n * <li><code>dataFactor</code>: a multiplication factor for item values, useful when displaying multiple items in one graph</li>\n * <li><code>minValue</code>: minimum (initial) item value, typically set for zero-based metrics (heap size)</li>\n * <li><code>maxValue</code>: maximum (initial) item value, may be used for the initial graph scale</li>\n * </ul>\n * <p>\n *\n * There's no need to define line width and/or line/fill colors, the framework\n * guarantees that each item in a graph will be displayed by a different color.\n * If needed, line width and/or line/fill colors may be customized by setting\n * these options:\n * <ul>\n * <li><code>lineWidth</code>: width of the line, default is <code>2f</code></li>\n * <li><code>lineColor</code>: color of the line, may be <code>null</code></li>\n * <li><code>fillColor</code>: color of the filled area, may be <code>null</code></li>\n * </ul>\n * <p>\n *\n * <b>Note:</b> Use the predefined static methods to create instances of ProbeItemDescriptor.\n * Custom instances of ProbeItemDescriptor are not supported and will cause a\n * <code>RuntimeException</code>.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProbeItemDescriptor {\n\n    // --- Public predefined constants -----------------------------------------\n\n    /**\n     * Minimum item value is undefined.\n     */\n    public static final long MIN_VALUE_UNDEFINED = Long.MAX_VALUE;\n    /**\n     * Maximum item value is undefined.\n     */\n    public static final long MAX_VALUE_UNDEFINED = Long.MIN_VALUE;\n    /**\n     * Value is undefined. For minimum/maximum value use MIN_VALUE_UNDEFINED or\n     * MAX_VALUE_UNDEFINED.\n     */\n    public static final long VALUE_UNDEFINED = Long.MIN_VALUE - 1;\n\n    /**\n     * Default color.\n     */\n    public static final Color DEFAULT_COLOR = new Color(0, 0, 0); // use == to identify this instance!\n\n    /**\n     * Default line width.\n     */\n    public static final float DEFAULT_LINE_WIDTH = -1.0F;\n\n\n    // --- Private instance variables ------------------------------------------\n\n    private final String name;\n    private final String description;\n\n\n    // --- Protected constructor -----------------------------------------------\n\n    protected ProbeItemDescriptor(String name, String description) {\n        if (name == null)\n            throw new IllegalArgumentException(\"name cannot be null\"); // NOI18N\n\n        // Custom ProbeItemDescriptor subclasses are currently not supported.\n        // May be supported in future versions together with custom Painters.\n        if (!(this instanceof ValueItemDescriptor))\n            throw new UnsupportedOperationException(\"Custom descriptor not supported. Use the predefined descriptors.\"); // NOI18N\n\n        this.name = name;\n        this.description = description;\n    }\n\n\n    // --- Common implementation -----------------------------------------------\n\n    /**\n     * Returns name of the item.\n     * @return name of the item\n     */\n    public final String getName() { return name; }\n\n    /**\n     * Returns description of the item.\n     * @return description of the item\n     */\n    public final String getDescription() { return description; }\n\n\n    // === Public factory methods ==============================================\n\n    // --- Continuous items ----------------------------------------------------\n\n    /**\n     * Creates descriptor for a continuous item created by line segments.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @return descriptor for a continuous item created by line segments\n     */\n    public static ProbeItemDescriptor continuousLineItem(String name, String description,\n                                                         ItemValueFormatter formatter) {\n\n        return continuousItem(name, description, formatter, 1d, 0, MAX_VALUE_UNDEFINED,\n                              DEFAULT_LINE_WIDTH, DEFAULT_COLOR, null);\n    }\n\n    /**\n     * Creates descriptor for a continuous item created by line segments with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @return descriptor for a continuous item created by line segments\n     */\n    public static ProbeItemDescriptor continuousLineItem(String name, String description,\n                                                         ItemValueFormatter formatter,\n                                                         double dataFactor,\n                                                         long minValue, long maxValue) {\n\n        return continuousItem(name, description, formatter, dataFactor, minValue,\n                              maxValue, DEFAULT_LINE_WIDTH, DEFAULT_COLOR, null);\n    }\n\n    /**\n     * Creates descriptor for a continuous item created by filled segments.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @return descriptor for a continuous item created by filled segments\n     */\n    public static ProbeItemDescriptor continuousFillItem(String name, String description,\n                                                         ItemValueFormatter formatter) {\n\n        return continuousItem(name, description, formatter, 1d, 0, MAX_VALUE_UNDEFINED,\n                              DEFAULT_LINE_WIDTH, null, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a continuous item created by filled segments with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @return descriptor for a continuous item created by filled segments\n     */\n    public static ProbeItemDescriptor continuousFillItem(String name, String description,\n                                                         ItemValueFormatter formatter,\n                                                         double dataFactor,\n                                                         long minValue, long maxValue) {\n\n        return continuousItem(name, description, formatter, dataFactor, minValue,\n                              maxValue, DEFAULT_LINE_WIDTH, null, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a continuous item created by line and filled segments.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @return descriptor for a continuous item created by line and filled segments\n     */\n    public static ProbeItemDescriptor continuousLineFillItem(String name, String description,\n                                                             ItemValueFormatter formatter) {\n\n        return continuousItem(name, description, formatter, 1d, 0, MAX_VALUE_UNDEFINED,\n                              DEFAULT_LINE_WIDTH, DEFAULT_COLOR, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a continuous item created by line and filled segments with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @return descriptor for a continuous item created by line and filled segments\n     */\n    public static ProbeItemDescriptor continuousLineFillItem(String name, String description,\n                                                             ItemValueFormatter formatter,\n                                                             double dataFactor,\n                                                             long minValue, long maxValue) {\n\n        return continuousItem(name, description, formatter, dataFactor, minValue,\n                              maxValue, DEFAULT_LINE_WIDTH, DEFAULT_COLOR, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a general continuous item with custom dataFactor ad min/max values, and custom line width and line/fill colors.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @param lineWidth line width\n     * @param lineColor line color or null\n     * @param fillColor fill color or null\n     * @return descriptor for a general continuous item\n     */\n    public static ProbeItemDescriptor continuousItem(String name, String description,\n                                                     ItemValueFormatter formatter,\n                                                     double dataFactor, long minValue,\n                                                     long maxValue, float lineWidth,\n                                                     Color lineColor, Color fillColor) {\n        \n        if (lineColor == null && fillColor == null)\n            throw new IllegalArgumentException(\"Either lineColor or fillColor must be defined\"); // NOI18N\n\n        return new ContinuousXYItemDescriptor(name, description, formatter, dataFactor,\n                                              minValue, maxValue, lineWidth, lineColor,\n                                              fillColor);\n    }\n\n\n    // --- Discrete items ------------------------------------------------------\n\n    /**\n     * Creates descriptor for a discrete item created by line segments representing the outline.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @return descriptor for a discrete item created by line segments representing the outline\n     */\n    public static ProbeItemDescriptor discreteLineItem(String name, String description,\n                                                       ItemValueFormatter formatter) {\n\n        return discreteOutlineItem(name, description, formatter, 1d, 0, MAX_VALUE_UNDEFINED,\n                                   DEFAULT_LINE_WIDTH, DEFAULT_COLOR, null);\n    }\n\n    /**\n     * Creates descriptor for a discrete item created by line segments representing the outline with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @return descriptor for a discrete item created by line segments representing the outline\n     */\n    public static ProbeItemDescriptor discreteLineItem(String name, String description,\n                                                       ItemValueFormatter formatter,\n                                                       double dataFactor,\n                                                       long minValue, long maxValue) {\n\n        return discreteOutlineItem(name, description, formatter, dataFactor, minValue,\n                                   maxValue, DEFAULT_LINE_WIDTH, DEFAULT_COLOR, null);\n    }\n\n    /**\n     * Creates descriptor of a discrete item created by filled segments.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @return descriptor of a discrete item created by filled segments\n     */\n    public static ProbeItemDescriptor discreteFillItem(String name, String description,\n                                                       ItemValueFormatter formatter) {\n\n        return discreteOutlineItem(name, description, formatter, 1d, 0, MAX_VALUE_UNDEFINED,\n                                   DEFAULT_LINE_WIDTH, null, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor of a discrete item created by filled segments with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @return descriptor of a discrete item created by filled segments\n     */\n    public static ProbeItemDescriptor discreteFillItem(String name, String description,\n                                                       ItemValueFormatter formatter,\n                                                       double dataFactor,\n                                                       long minValue, long maxValue) {\n\n        return discreteOutlineItem(name, description, formatter, dataFactor, minValue,\n                                   maxValue, DEFAULT_LINE_WIDTH, null, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a discrete item created by line segments representing the outline and filled segments.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @return descriptor for a discrete item created by line segments representing the outline and filled segments\n     */\n    public static ProbeItemDescriptor discreteLineFillItem(String name, String description,\n                                                           ItemValueFormatter formatter) {\n\n        return discreteOutlineItem(name, description, formatter, 1d, 0, MAX_VALUE_UNDEFINED,\n                                  DEFAULT_LINE_WIDTH, DEFAULT_COLOR, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a discrete item created by line segments representing the outline and filled segments with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @return descriptor for a discrete item created by line segments representing the outline and filled segments\n     */\n    public static ProbeItemDescriptor discreteLineFillItem(String name, String description,\n                                                           ItemValueFormatter formatter,\n                                                           double dataFactor,\n                                                           long minValue, long maxValue) {\n        \n        return discreteOutlineItem(name, description, formatter, dataFactor, minValue,\n                                   maxValue, DEFAULT_LINE_WIDTH, DEFAULT_COLOR, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a general discrete outlined item with custom dataFactor ad min/max values, and custom line width and line/fill colors.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @param lineWidth line width\n     * @param lineColor line color or null\n     * @param fillColor fill color or null\n     * @return descriptor for a general discrete outlined item\n     */\n    public static ProbeItemDescriptor discreteOutlineItem(String name, String description,\n                                                          ItemValueFormatter formatter,\n                                                          double dataFactor, long minValue,\n                                                          long maxValue, float lineWidth,\n                                                          Color lineColor, Color fillColor) {\n        \n        if (lineColor == null && fillColor == null)\n            throw new IllegalArgumentException(\"Either lineColor or fillColor must be defined\"); // NOI18N\n\n        return discreteItem(name, description, formatter, dataFactor, minValue, maxValue,\n                            lineWidth, lineColor, fillColor, 0, false, false, true);\n    }\n\n    /**\n     * Creates descriptor for a discrete item represented by a horizontal line segment, optionally filled, with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @param filled true if the segments are filled\n     * @param width width of/between the segments\n     * @param fixedWidth true if width defines segment width, false if width defines segments spacing\n     * @return descriptor for a discrete item represented by a horizontal line segment, optionally filled\n     */\n    public static ProbeItemDescriptor discreteToplineItem(String name, String description,\n                                                          ItemValueFormatter formatter,\n                                                          double dataFactor, long minValue,\n                                                          long maxValue, boolean filled,\n                                                          int width, boolean fixedWidth) {\n\n        return discreteItem(name, description, formatter, dataFactor, minValue, maxValue,\n                            DEFAULT_LINE_WIDTH, DEFAULT_COLOR, filled ? DEFAULT_COLOR : null,\n                            width, fixedWidth, true, false);\n    }\n\n    /**\n     * Creates descriptor for a discrete item represented by a horizontal line segment, optionally filled, with custom dataFactor ad min/max values, and custom line width and line/fill colors.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @param lineWidth line width\n     * @param lineColor line color or null\n     * @param fillColor fill color or null\n     * @param width width width of/between the segments\n     * @param fixedWidth fixedWidth true if width defines segment width, false if width defines segments spacing\n     * @return descriptor for a discrete item represented by a horizontal line segment, optionally filled\n     */\n    public static ProbeItemDescriptor discreteToplineItem(String name, String description,\n                                                          ItemValueFormatter formatter,\n                                                          double dataFactor, long minValue,\n                                                          long maxValue, float lineWidth,\n                                                          Color lineColor, Color fillColor,\n                                                          int width, boolean fixedWidth) {\n        \n        if (lineColor == null && fillColor == null)\n            throw new IllegalArgumentException(\"Either lineColor or fillColor must be defined\"); // NOI18N\n\n        return discreteItem(name, description, formatter, dataFactor, minValue, maxValue,\n                            lineWidth, lineColor, fillColor, width, fixedWidth, true, false);\n    }\n\n    /**\n     * Creates descriptor for a discrete item represented by vertical bars, with custom dataFactor ad min/max values\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @param outlined true if the bars are outlined\n     * @param filled true if the bars are filled\n     * @param width width width of/between the bars\n     * @param fixedWidth fixedWidth true if width defines bar width, false if width defines bars spacing\n     * @return descriptor for a discrete item represented by vertical bars\n     */\n    public static ProbeItemDescriptor discreteBarItem(String name, String description,\n                                                      ItemValueFormatter formatter,\n                                                      double dataFactor, long minValue,\n                                                      long maxValue, boolean outlined,\n                                                      boolean filled, int width,\n                                                      boolean fixedWidth) {\n\n        if (!outlined && !filled)\n            throw new IllegalArgumentException(\"Either outlined or filled must be set\"); // NOI18N\n\n        return discreteItem(name, description, formatter, dataFactor, minValue, maxValue,\n                            DEFAULT_LINE_WIDTH, outlined ? DEFAULT_COLOR : null,\n                            filled ? DEFAULT_COLOR : null, width, fixedWidth, false, !filled);\n    }\n\n    /**\n     * Creates descriptor for a discrete item represented by vertical bars, with custom dataFactor ad min/max values, and custom line width and line/fill colors.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @param lineWidth line width\n     * @param lineColor line color or null\n     * @param fillColor fill color or null\n     * @param width width width of/between the bars\n     * @param fixedWidth fixedWidth true if width defines bar width, false if width defines bars spacing\n     * @return descriptor for a discrete item represented by vertical bars\n     */\n    public static ProbeItemDescriptor discreteBarItem(String name, String description,\n                                                      ItemValueFormatter formatter,\n                                                      double dataFactor, long minValue,\n                                                      long maxValue, float lineWidth,\n                                                      Color lineColor, Color fillColor,\n                                                      int width, boolean fixedWidth) {\n        \n        if (lineColor == null && fillColor == null)\n            throw new IllegalArgumentException(\"Either lineColor or fillColor must be defined\"); // NOI18N\n\n        return discreteItem(name, description, formatter, dataFactor, minValue, maxValue,\n                            lineWidth, lineColor, fillColor, width, fixedWidth, false, fillColor == null);\n    }\n\n    private static ProbeItemDescriptor discreteItem(String name, String description,\n                                                    ItemValueFormatter formatter,\n                                                    double dataFactor, long minValue,\n                                                    long maxValue, float lineWidth,\n                                                    Color lineColor, Color fillColor,\n                                                    int width, boolean fixedWidth,\n                                                    boolean topLineOnly,\n                                                    boolean outlineOnly) {\n\n        return new DiscreteXYItemDescriptor(name, description, formatter, dataFactor,\n                                            minValue, maxValue, lineWidth, lineColor,\n                                            fillColor, width, fixedWidth, topLineOnly,\n                                            outlineOnly);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/ProbeStateHandler.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\n\n/**\n * ProbeStateHandler interface allows an implementing TracerProbe to be\n * notified about Tracer session state. See TracerProbe.getStateHandler().\n *\n * @author Jiri Sedlacek\n * @param <X> any DataSource type\n */\npublic interface ProbeStateHandler<X extends DataSource> {\n\n    /**\n     * Invoked when the is added into the Timeline view.\n     *\n     * @param dataSource monitored DataSource\n     */\n    public void probeAdded(X dataSource);\n\n    /**\n     * Invoked when the probe is removed from the Timeline view.\n     *\n     * @param dataSource monitored DataSource\n     */\n    public void probeRemoved(X dataSource);\n\n\n    /**\n     * Invoked when setting up a new Tracer session. This method allows a\n     * Probe to notify the user about initialization progress. The actual\n     * initialization (and updating the TracerProgressObject) should be\n     * performed in the sessionStarting() method. Useful for example for\n     * messaging a delay during instrumention of classes in target application.\n     *\n     * @param dataSource monitored DataSource\n     * @param refresh session refresh rate in miliseconds\n     * @return TracerProgressObject to track initialization progress\n     */\n    public TracerProgressObject sessionInitializing(X dataSource, int refresh);\n\n    /**\n     * Invoked when starting a new Tracer session. Any probe initialization\n     * should be performed in this method. If provided by the\n     * sessionInitializing method, a TracerProgressObject should be updated to\n     * reflect the initialization progress. This method may throw a\n     * SessionInitializationException in case of initialization failure. Any\n     * packages/probes initialized so far will be correctly finished, however the\n     * probe throwing the SessionInitializationException is responsible for\n     * cleaning up any used resources and restoring its state without any\n     * following events.\n     *\n     * @param dataSource monitored DataSource\n     * @throws SessionInitializationException in case of initialization failure\n     */\n    public void sessionStarting(X dataSource)\n            throws SessionInitializationException;\n\n    /**\n     * Invoked when all packages/probes have been started and the Tracer session\n     * is running and collecting data.\n     *\n     * @param dataSource monitored DataSource\n     */\n    public void sessionRunning(X dataSource);\n\n    /**\n     * Invoked when stopping the Tracer session. Any probe cleanup should be\n     * performed in this method. Any long-running cleanup code should preferably\n     * be invoked in a separate worker thread to allow the Tracer session to\n     * finish as fast as possible. Be sure to check/wait for the cleanup thread\n     * when starting a new Tracer session in sessionStarting().\n     *\n     * @param dataSource monitored DataSource\n     */\n    public void sessionStopping(X dataSource);\n\n    /**\n     * Invoked when the Tracer session has finished.\n     *\n     * @param dataSource monitored DataSource\n     */\n    public void sessionFinished(X dataSource);\n\n    /**\n     * Invoked when refresh rate of the Tracer session has been changed.\n     *\n     * @param dataSource monitored DataSource\n     * @param refresh session refresh rate in miliseconds\n     */\n    public void refreshRateChanged(X dataSource, int refresh);\n\n\n    /**\n     * An abstract adapter class for receiving Tracer session state notifications.\n     *\n     * @param <X> any DataSource type\n     */\n    public abstract class Adapter<X extends DataSource> implements ProbeStateHandler<X> {\n\n        public void probeAdded(X dataSource) {}\n\n        public void probeRemoved(X dataSource) {}\n\n        /**\n         * Invoked when setting up a new Tracer session. This method allows a\n         * Probe to notify the user about initialization progress. The actual\n         * initialization (and updating the TracerProgressObject) should be\n         * performed in the sessionStarting() method. Useful for example for\n         * messaging a delay during instrumention of classes in target application.\n         *\n         * @param dataSource monitored DataSource\n         * @param refresh session refresh rate in miliseconds\n         * @return TracerProgressObject null in default implementation\n         */\n        public TracerProgressObject sessionInitializing(X dataSource, int refresh) {\n            return null;\n        }\n\n        public void sessionStarting(X dataSource)\n                throws SessionInitializationException {}\n\n        public void sessionRunning(X dataSource) {}\n\n        public void sessionStopping(X dataSource) {}\n\n        public void sessionFinished(X dataSource) {}\n\n        public void refreshRateChanged(X dataSource, int refresh) {}\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/SessionInitializationException.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer;\n\n/**\n * Signals that a TracerPackage/TracerProbe failed to initialize for a new\n * Tracer session. Preferably provides a message to notify the user about\n * the failure.\n *\n * @author Jiri Sedlacek\n */\npublic final class SessionInitializationException extends Exception {\n\n    private final String userMessage;\n\n\n    /**\n     * Creates a new instance of SessionInitializationException with defined\n     * log message and default user message.\n     *\n     * @param logMessage log message\n     */\n    public SessionInitializationException(String logMessage) {\n        this(null, logMessage);\n    }\n\n    /**\n     * Creates a new instance of SessionInitializationException with defined\n     * log message and cause and default user message.\n     *\n     * @param logMessage log message\n     * @param cause exception cause\n     */\n    public SessionInitializationException(String logMessage,\n                                          Throwable cause) {\n        this(null, logMessage, cause);\n    }\n\n    /**\n     * Creates a new instance of SessionInitializationException with defined\n     * user message and log message.\n     *\n     * @param userMessage user message\n     * @param logMessage log message\n     */\n    public SessionInitializationException(String userMessage,\n                                          String logMessage) {\n        super(logMessage);\n        this.userMessage = userMessage;\n    }\n\n    /**\n     * Creates a new instance of SessionInitializationException with defined\n     * user message, log message and cause.\n     *\n     * @param userMessage user message\n     * @param logMessage log message\n     * @param cause exception cause\n     */\n    public SessionInitializationException(String userMessage,\n                                          String logMessage,\n                                          Throwable cause) {\n        super(logMessage, cause);\n        this.userMessage = userMessage;\n    }\n\n\n    /**\n     * Returns an user message to be displayed in Tracer UI. The message should\n     * be short, for example \"Probe XYZ failed to initialize\" or \"Probe XYZ\n     * failed to connect to target application.\"\n     *\n     * @return user message to be displayed in Tracer UI\n     */\n    public String getUserMessage() {\n        return userMessage;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/TracerPackage.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport javax.swing.Icon;\n\n/**\n * TracerPackage is a container for a set of TracerProbes distributed as a single\n * package (plugin). The probes in a package are typically designed to monitor\n * the same functional unit on the target - for example disk I/O, network I/O,\n * memory subsystem etc.\n *\n * @author Jiri Sedlacek\n * @param <X> any DataSource type\n */\npublic abstract class TracerPackage<X extends DataSource> implements Positionable {\n\n    private final String name;\n    private final String description;\n    private final Icon icon;\n    private final int preferredPosition;\n\n\n    /**\n     * Creates new instance of TracerPackage.\n     *\n     * @param name name of the package\n     * @param description description of the package\n     * @param icon icon of the package\n     * @param preferredPosition preferred position of the package in UI\n     */\n    public TracerPackage(String name, String description, Icon icon,\n                         int preferredPosition) {\n        this.name = name;\n        this.description = description;\n        this.icon = icon;\n        this.preferredPosition = preferredPosition;\n    }\n\n\n    /**\n     * Returns name of the package.\n     *\n     * @return name of the package\n     */\n    public final String getName() { return name; }\n\n    /**\n     * Returns description of the package.\n     *\n     * @return description of the package\n     */\n    public final String getDescription() { return description; }\n\n    /**\n     * Returns icon of the package.\n     *\n     * @return icon of the package\n     */\n    public final Icon getIcon() { return icon; }\n\n    /**\n     * Returns preferred position of the package in UI.\n     *\n     * @return preferred position of the package in UI\n     */\n    public final int getPreferredPosition() { return preferredPosition; }\n\n\n    /**\n     * Returns array of TracerProbeDescriptors to present the package probes in UI.\n     * Should always return descriptors for all probes provided by the provider\n     * for each DataSource. If a probe is not available for the DataSource its\n     * descriptor should be disabled - TracerProbeDescriptor.isProbeAvailable()\n     * returns false.\n     *\n     * @return array of TracerProbeDescriptors to present the package probes in UI\n     */\n    public abstract TracerProbeDescriptor[] getProbeDescriptors();\n\n    /**\n     * Returns the probe to be used in Tracer session. The probe to return\n     * is defined by its TracerProbeDescriptor created by getProbeDescriptors()\n     * method and selected by the user.\n     *\n     * @param descriptor TracerProbeDescriptor selecting the probe\n     * @return the probe to be used in Tracer session\n     */\n    public abstract TracerProbe<X> getProbe(TracerProbeDescriptor descriptor);\n\n    \n    /**\n     * Optionally returns PackageStateHandler instance which obtains notifications\n     * about the Tracer session status in context of TracerProbes provided by this\n     * TracerPackage. Default implementation returns null. You may use StateAware\n     * subclass instead of implementing this method to obtain the notifications.\n     *\n     * @return PackageStateHandler instance which obtains status notifications,\n     * default implementation returns null\n     */\n    public PackageStateHandler<X> getStateHandler() { return null; }\n\n\n    /**\n     * An abstract adapter class for receiving Tracer session state notifications.\n     * See PackageStateHandler for details.\n     *\n     * @param <X> any DataSource type\n     */\n    public static abstract class SessionAware<X extends DataSource> extends TracerPackage<X> {\n\n        private PackageStateHandler<X> stateHandler;\n\n\n        /**\n         * Creates new instance of TracerPackage.SessionAware.\n         *\n         * @param name name of the package\n         * @param description description of the package\n         * @param icon icon of the package\n         * @param preferredPosition preferred position of the package in UI\n         */\n        public SessionAware(String name, String description,\n                          Icon icon, int preferredPosition) {\n            super(name, description, icon, preferredPosition);\n        }\n\n\n        /**\n         * Returns a predefined PackageStateHandler which obtains notifications\n         * about the Tracer session state in context of TracerProbes provided by this\n         * TracerPackage.\n         *\n         * @return predefined PackageStateHandler which obtains status notifications\n         */\n        public synchronized final PackageStateHandler<X> getStateHandler() {\n            if (stateHandler == null) stateHandler = new PackageStateHandler<X>() {\n                public void probeAdded(TracerProbe<X> probe, X dataSource) {\n                    SessionAware.this.probeAdded(probe, dataSource);\n                }\n                public void probeRemoved(TracerProbe<X> probe, X dataSource) {\n                    SessionAware.this.probeRemoved(probe, dataSource);\n                }\n                public TracerProgressObject sessionInitializing(TracerProbe<X>[] probes,\n                    X dataSource, int refresh) {\n                    return SessionAware.this.sessionInitializing(probes, dataSource, refresh);\n                }\n                public void sessionStarting(TracerProbe<X>[] probes, X dataSource)\n                        throws SessionInitializationException {\n                    SessionAware.this.sessionStarting(probes, dataSource);\n                }\n                public void sessionRunning(TracerProbe<X>[] probes, X dataSource) {\n                    SessionAware.this.sessionRunning(probes, dataSource);\n                }\n                public void sessionStopping(TracerProbe<X>[] probes, X dataSource) {\n                    SessionAware.this.sessionStopping(probes, dataSource);\n                }\n                public void sessionFinished(TracerProbe<X>[] probes, X dataSource) {\n                    SessionAware.this.sessionFinished(probes, dataSource);\n                }\n                public void refreshRateChanged(TracerProbe<X>[] probes, X dataSource,\n                        int refresh) {\n                    SessionAware.this.refreshRateChanged(probes, dataSource, refresh);\n                }\n            };\n            return stateHandler;\n        }\n\n\n        /**\n         * Invoked when a probe is added into the Timeline view.\n         *\n         * @param probe added probe\n         * @param dataSource monitored DataSource\n         */\n        protected void probeAdded(TracerProbe<X> probe, X dataSource) {}\n\n        /**\n         * Invoked when a probe is removed from the Timeline view.\n         *\n         * @param probe removed probe\n         * @param dataSource monitored DataSource\n         */\n        protected void probeRemoved(TracerProbe<X> probe, X dataSource) {}\n\n\n        /**\n         * Invoked when setting up a new Tracer session. This method allows a\n         * Package to notify the user about initialization progress. The actual\n         * initialization (and updating the TracerProgressObject) should be\n         * performed in the sessionStarting() method. Useful for example for\n         * messaging a delay during instrumention of classes in target application.\n         *\n         * @param probes probes defined for the Tracer session\n         * @param dataSource monitored DataSource\n         * @param refresh session refresh rate in miliseconds\n         * @return TracerProgressObject to track initialization progress\n         */\n        protected TracerProgressObject sessionInitializing(TracerProbe<X>[] probes,\n                X dataSource, int refresh) { return null; }\n\n        /**\n         * Invoked when starting a new Tracer session. Any package/probes\n         * initialization should be performed in this method. If provided by the\n         * sessionInitializing method, a TracerProgressObject should be updated to\n         * reflect the initialization progress. This method may throw a\n         * SessionInitializationException in case of initialization failure. Any\n         * packages/probes initialized so far will be correctly finished, however the\n         * package throwing the SessionInitializationException is responsible for\n         * cleaning up any used resources and restoring its state without any\n         * following events.\n         *\n         * @param probes probes defined for the Tracer session\n         * @param dataSource monitored DataSource\n         * @throws SessionInitializationException in case of initialization failure\n         */\n        protected void sessionStarting(TracerProbe<X>[] probes, X dataSource)\n                throws SessionInitializationException {}\n\n        /**\n         * Invoked when all packages/probes have been started and the Tracer session\n         * is running and collecting data.\n         *\n         * @param probes probes defined for the Tracer session\n         * @param dataSource monitored DataSource\n         */\n        protected void sessionRunning(TracerProbe<X>[] probes, X dataSource) {}\n\n        /**\n         * Invoked when stopping the Tracer session. Any package/probes cleanup\n         * should be performed in this method. Any long-running cleanup code should\n         * preferably be invoked in a separate worker thread to allow the Tracer\n         * session to finish as fast as possible. Be sure to check/wait for the\n         * cleanup thread when starting a new Tracer session in sessionStarting().\n         *\n         * @param probes probes defined for the Tracer session\n         * @param dataSource monitored DataSource\n         */\n        protected void sessionStopping(TracerProbe<X>[] probes, X dataSource) {}\n\n        /**\n         * Invoked when the Tracer session has finished.\n         *\n         * @param probes probes defined for the Tracer session\n         * @param dataSource monitored DataSource\n         */\n        protected void sessionFinished(TracerProbe<X>[] probes, X dataSource) {}\n\n        /**\n         * Invoked when refresh rate of the Tracer session has been changed.\n         *\n         * @param probes probes defined for the Tracer session\n         * @param dataSource monitored DataSource\n         * @param refresh session refresh rate in miliseconds\n         */\n        protected void refreshRateChanged(TracerProbe<X>[] probes, X dataSource,\n                int refresh) {}\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/TracerPackageProvider.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\n\n/**\n * Provider of TracerPackage(s) for a DataSource type.\n *\n * @param <X> any DataSource type\n * @author Jiri Sedlacek\n */\npublic abstract class TracerPackageProvider<X extends DataSource> {\n\n    private final Class<X> scope;\n\n\n    /**\n     * Creates new instance of TracerPackageProvider with defined scope.\n     *\n     * @param scope scope of the provider\n     */\n    public TracerPackageProvider(Class<X> scope) { this.scope = scope; }\n\n\n    /**\n     * Returns scope of the provider.\n     *\n     * @return scope of the provider\n     */\n    public final Class<X> getScope() { return scope; }\n    \n\n    /**\n     * Returns TracerPackages for the provided DataSource.\n     *\n     * @return TracerPackages for the provided DataSource\n     */\n    public abstract TracerPackage<X>[] getPackages(X dataSource);\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/TracerProbe.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\n\n/**\n * Tracer probe represents one monitored unit in the Timeline chart. The probe\n * may provide one or several values displayed in the chart, for example several\n * numeric values of an MBean.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class TracerProbe<X extends DataSource> {\n\n    private final ProbeItemDescriptor[] itemDescriptors;\n\n\n    /**\n     * Creates new instance of TracerProbe.\n     *\n     * @param itemDescriptors descriptors of UI appearance of items provided by the probe\n     */\n    public TracerProbe(ProbeItemDescriptor[] itemDescriptors) {\n        if (itemDescriptors == null || itemDescriptors.length == 0)\n            throw new IllegalArgumentException(\"Invalid ProbeItemDescriptors\"); // NOI18N\n        this.itemDescriptors = itemDescriptors;\n    }\n\n\n    /**\n     * Returns descriptors of UI appearance of items provided by the probe.\n     *\n     * @return descriptors of UI appearance of items provided by the probe\n     */\n    public final ProbeItemDescriptor[] getItemDescriptors() { return itemDescriptors; };\n\n\n    /**\n     * Returns number of items provided by the probe.\n     *\n     * @return number of items provided by the probe\n     */\n    public int getItemsCount() { return itemDescriptors.length; }\n\n    /**\n     * Returns values of items provided by the probe at the defined time. It's up\n     * to the probe implementation whether the values will be read in this method\n     * or retrieved from a private data model prefetching the values asynchronously.\n     * The timestamp is the same for a single data-read event for all selected\n     * probes of the actual Tracer session.\n     * <br><br>\n     * <b>Note: current Tracer version doesn't support negative values. Negative\n     * values returned by the probes will be treated as '0' and the user will be\n     * notified by a warning dialog.</b>\n     *\n     * @param timestamp timestamp of the data-read event\n     * @return values of items provided by the probe\n     */\n    public abstract long[] getItemValues(long timestamp);\n\n\n    /**\n     * Optionally returns ProbeStateHandler instance which obtains notifications\n     * about the Tracer session status. Default implementation returns null.\n     * You may use StateAware subclass instead of implementing this method to\n     * obtain the notifications.\n     *\n     * @return ProbeStateHandler instance which obtains status notifications,\n     * default implementation returns null\n     */\n    public ProbeStateHandler<X> getStateHandler() { return null; }\n\n\n    /**\n     * An abstract adapter class for receiving Tracer session state notifications.\n     * See ProbeStateHandler for details.\n     *\n     * @param <X> any DataSource type\n     */\n    public static abstract class SessionAware<X extends DataSource> extends TracerProbe<X> {\n\n        private ProbeStateHandler<X> stateHandler;\n\n        /**\n         * Creates new instance of TracerProbe.SessionAware.\n         *\n         * @param itemDescriptors descriptors of UI appearance of items provided by the probe\n         */\n        public SessionAware(ProbeItemDescriptor[] itemDescriptors) {\n            super(itemDescriptors);\n        }\n\n\n        /**\n         * Returns a predefined ProbeStateHandler which obtains notifications\n         * about the Tracer session state.\n         *\n         * @return predefined ProbeStateHandler which obtains status notifications\n         */\n        public synchronized final ProbeStateHandler<X> getStateHandler() {\n            if (stateHandler == null) stateHandler = new ProbeStateHandler<X>() {\n                public void probeAdded(X dataSource) {\n                    SessionAware.this.probeAdded(dataSource);\n                }\n                public void probeRemoved(X dataSource) {\n                    SessionAware.this.probeRemoved(dataSource);\n                }\n                public TracerProgressObject sessionInitializing(X dataSource, int refresh) {\n                    return SessionAware.this.sessionInitializing(dataSource, refresh);\n                }\n                public void sessionStarting(X dataSource)\n                        throws SessionInitializationException {\n                    SessionAware.this.sessionStarting(dataSource);\n                }\n                public void sessionRunning(X dataSource) {\n                    SessionAware.this.sessionRunning(dataSource);\n                }\n                public void sessionStopping(X dataSource) {\n                    SessionAware.this.sessionStopping(dataSource);\n                }\n                public void sessionFinished(X dataSource) {\n                    SessionAware.this.sessionFinished(dataSource);\n                }\n                public void refreshRateChanged(X dataSource, int refresh) {\n                    SessionAware.this.refreshRateChanged(dataSource, refresh);\n                }\n            };\n            return stateHandler;\n        }\n\n\n        /**\n         * Invoked when the is added into the Timeline view.\n         *\n         * @param dataSource monitored DataSource\n         */\n        protected void probeAdded(X dataSource) {}\n\n        /**\n         * Invoked when the probe is removed from the Timeline view.\n         *\n         * @param dataSource monitored DataSource\n         */\n        protected void probeRemoved(X dataSource) {}\n\n\n        /**\n         * Invoked when setting up a new Tracer session. This method allows a\n         * Probe to notify the user about initialization progress. The actual\n         * initialization (and updating the TracerProgressObject) should be\n         * performed in the sessionStarting() method. Useful for example for\n         * messaging a delay during instrumention of classes in target application.\n         *\n         * @param dataSource monitored DataSource\n         * @param refresh session refresh rate in miliseconds\n         * @return TracerProgressObject to track initialization progress\n         */\n        protected TracerProgressObject sessionInitializing(X dataSource, int refresh) {\n            return null;\n        }\n\n        /**\n         * Invoked when starting a new Tracer session. Any probe initialization\n         * should be performed in this method. If provided by the\n         * sessionInitializing method, a TracerProgressObject should be updated to\n         * reflect the initialization progress. This method may throw a\n         * SessionInitializationException in case of initialization failure. Any\n         * packages/probes initialized so far will be correctly finished, however the\n         * probe throwing the SessionInitializationException is responsible for\n         * cleaning up any used resources and restoring its state without any\n         * following events.\n         *\n         * @param dataSource monitored DataSource\n         * @throws SessionInitializationException in case of initialization failure\n         */\n        protected void sessionStarting(X dataSource)\n                throws SessionInitializationException {}\n\n        /**\n         * Invoked when all packages/probes have been started and the Tracer session\n         * is running and collecting data.\n         *\n         * @param dataSource monitored DataSource\n         */\n        protected void sessionRunning(X dataSource) {}\n\n        /**\n         * Invoked when stopping the Tracer session. Any probe cleanup should be\n         * performed in this method. Any long-running cleanup code should preferably\n         * be invoked in a separate worker thread to allow the Tracer session to\n         * finish as fast as possible. Be sure to check/wait for the cleanup thread\n         * when starting a new Tracer session in sessionStarting().\n         *\n         * @param dataSource monitored DataSource\n         */\n        protected void sessionStopping(X dataSource) {}\n\n        /**\n         * Invoked when the Tracer session has finished.\n         *\n         * @param dataSource monitored DataSource\n         */\n        protected void sessionFinished(X dataSource) {}\n\n        /**\n         * Invoked when refresh rate of the Tracer session has been changed.\n         *\n         * @param dataSource monitored DataSource\n         * @param refresh session refresh rate in miliseconds\n         */\n        protected void refreshRateChanged(X dataSource, int refresh) {}\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/TracerProbeDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer;\n\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.openide.util.ImageUtilities;\n\n/**\n * TracerProbeDescriptor defines how a TracerProbe appears in the Tracer UI.\n *\n * @author Jiri Sedlacek\n */\npublic final class TracerProbeDescriptor implements Positionable {\n\n    private static final String IMAGE_PATH =\n        \"org/graalvm/visualvm/modules/tracer/impl/resources/probe.png\"; // NOI18N\n\n    private final String name;\n    private final String description;\n    private final Icon icon;\n    private final int preferredPosition;\n    private final boolean available;\n\n\n    /**\n     * Creates new instance of TracerProbeDescriptor.\n     *\n     * @param name probe name\n     * @param description probe description\n     * @param icon probe icon\n     * @param preferredPosition preferred position of the probe in UI\n     * @param available availability of the probe in actual context\n     */\n    public TracerProbeDescriptor(String name, String description, Icon icon,\n                                 int preferredPosition, boolean available) {\n        this.name = name;\n        this.description = description;\n        this.icon = icon != null ? icon : new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH));\n        this.preferredPosition = preferredPosition;\n        this.available = available;\n    }\n\n\n    /**\n     * Returns probe name.\n     *\n     * @return probe name\n     */\n    public String getProbeName() { return name; }\n\n    /**\n     * Returns probe description.\n     *\n     * @return probe description\n     */\n    public String getProbeDescription() { return description; }\n\n    /**\n     * Returns probe icon.\n     *\n     * @return probe icon\n     */\n    public Icon getProbeIcon() { return icon; }\n\n    /**\n     * Returns preferred position of the probe in UI.\n     *\n     * @return preferred position of the probe in UI\n     */\n    public int getPreferredPosition() { return preferredPosition; }\n\n    /**\n     * Returns true if the probe is available in current context, false otherwise.\n     *\n     * @return true if the probe is available in current context, false otherwise\n     */\n    public boolean isProbeAvailable() { return available; }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/TracerProgressObject.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.SwingUtilities;\n\n/**\n * TracerProgressObject describes progress of the TracerPackage/TracerProbe\n * initialization when starting a Tracer session.\n *\n * @author Jiri Sedlacek\n */\npublic final class TracerProgressObject {\n\n    private final int steps;\n    private String text;\n    private int currentStep;\n    private int lastStep;\n\n    private final Set<Listener> listeners;\n\n\n    /**\n     * Creates new instance of TracerProgressObject with a defined number of\n     * steps.\n     *\n     * @param steps number of steps to finish the initialization\n     */\n    public TracerProgressObject(int steps) {\n        this(steps, null);\n    }\n\n    /**\n     * Creates new instance of TracerProgressObject with a defined number of\n     * steps and text describing the initial state.\n     *\n     * @param steps number of steps to finish the initialization\n     * @param text text describing the initial state\n     */\n    public TracerProgressObject(int steps, String text) {\n        if (steps < 1)\n            throw new IllegalArgumentException(\"steps value must be >= 1: \" + steps); // NOI18N\n\n        this.steps = steps;\n        this.text = text;\n        currentStep = 0;\n        lastStep = 0;\n        listeners = new HashSet();\n    }\n\n\n    /**\n     * Returns number of steps to finish the initialization.\n     *\n     * @return number of steps to finish the initialization\n     */\n    public synchronized int getSteps() { return steps; }\n\n    /**\n     * Returns current step of the initialization progress.\n     *\n     * @return current step of the initialization progress\n     */\n    public synchronized int getCurrentStep() { return currentStep; }\n\n    /**\n     * Returns text describing the current state or null.\n     *\n     * @return text describing the current state or null\n     */\n    public synchronized String getText() { return text; }\n\n\n    /**\n     * Adds a single step to the current initialization progress.\n     */\n    public void addStep() { addSteps(1); }\n\n    /**\n     * Adds a single step to the current initialization progress and changes\n     * the text describing the current state.\n     *\n     * @param text text describing the current state\n     */\n    public void addStep(String text)  { addSteps(1, text); }\n\n    /**\n     * Adds a number of steps to the current initialization progress.\n     *\n     * @param steps number of steps to be addded to the current initialization progress\n     */\n    public void addSteps(int steps) { addSteps(steps, text); }\n\n    /**\n     * Adds a number of steps to the current initialization progress and changes\n     * the text describing the current state.\n     *\n     * @param steps number of steps to be addded to the current initialization progress\n     * @param text text describing the current state\n     */\n    public synchronized void addSteps(int steps, String text) {\n        if (steps < 0)\n            throw new IllegalArgumentException(\"steps value must be >= 0: \" + steps); // NOI18N\n        if (currentStep + steps > this.steps)\n            throw new IllegalArgumentException(\"Total steps exceeded: \" + // NOI18N\n                                               (currentStep + steps) + \">\" + this.steps); // NOI18N\n\n        currentStep += steps;\n        this.text = text;\n        fireChange();\n    }\n\n    /**\n     * Updates text describing the current state without adding any steps to the\n     * current initialization progress.\n     *\n     * @param text text describing the current state\n     */\n    public synchronized void setText(String text) {\n        this.text = text;\n        fireChange();\n    }\n\n    /**\n     * Adds all remaining steps to finish the initialization progress.\n     */\n    public synchronized void finish() {\n        if (isFinished()) return;\n        currentStep = steps;\n        fireChange();\n    }\n\n    /**\n     * Returns true for a finished TracerProgressObject, false otherwise.\n     *\n     * @return true for a finished TracerProgressObject, false otherwise.\n     */\n    public synchronized boolean isFinished() {\n        return currentStep == steps;\n    }\n\n\n    /**\n     * Adds a listener to receive progress notifications.\n     *\n     * @param l listener to be added\n     */\n    public synchronized void addListener(Listener l) { listeners.add(l); }\n\n    /**\n     * Removes a listener receiving progress notifications.\n     *\n     * @param l listener to be removed.\n     */\n    public synchronized void removeListener(Listener l) { listeners.remove(l); }\n\n    private void fireChange() {\n        final int currentStepF = currentStep;\n        final int addedStepsF = currentStep - lastStep;\n        final String textF = text;\n        final Set<Listener> toNotify = new HashSet(listeners);\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                for (Listener listener : toNotify)\n                    listener.progressChanged(addedStepsF, currentStepF, textF);\n            }\n        });\n        lastStep = currentStep;\n    }\n\n\n    /**\n     * Listener to receive notifications about the initialization progress.\n     */\n    public static interface Listener {\n\n        /**\n         * Invoked when the progress and/or text describing the current state\n         * changes.\n         *\n         * @param addedSteps new steps added by the change\n         * @param currentStep current step of the initialization progress\n         * @param text text describing the current state\n         */\n        public void progressChanged(int addedSteps, int currentStep, String text);\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/TracerSupport.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer;\n\nimport org.graalvm.visualvm.modules.tracer.impl.TracerSupportImpl;\n\n/**\n * Entrypoint to the Tracer. Use this class to register and unregister\n * TracerPackageProvider implementations.\n *\n * @author Jiri Sedlacek\n */\npublic final class TracerSupport {\n\n    private static TracerSupport INSTANCE;\n\n\n    /**\n     * Returns singleton instance of TracerSupport.\n     *\n     * @return singleton instance of TracerSupport\n     */\n    public static synchronized TracerSupport getInstance() {\n        if (INSTANCE == null) INSTANCE = new TracerSupport();\n        return INSTANCE;\n    }\n\n\n    /**\n     * Registers TracerPackageProvider.\n     *\n     * @param provider TracerPackageProvider\n     */\n    public void registerPackageProvider(TracerPackageProvider provider) {\n        TracerSupportImpl.getInstance().registerPackageProvider(provider);\n    }\n\n    /**\n     * Unregisters TracerPackageProvider.\n     *\n     * @param povider TracerPackageProvider\n     */\n    public void unregisterPackageProvider(TracerPackageProvider povider) {\n        TracerSupportImpl.getInstance().unregisterPackageProvider(povider);\n    }\n\n\n    private TracerSupport() {}\n    \n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Tracer\nOpenIDE-Module-Long-Description=\\\n    Tracer-Framework module is a framework and graphical user interface for visual tracing of applications or other data sources using Tracer probes.\\n\\\n    <BR>\\n<BR>\\nNote: the public API of this module is not stable, incompatible changes may happen at any time!\nOpenIDE-Module-Name=Tracer-Framework\nOpenIDE-Module-Short-Description=Tracer framework and GUI\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/DetailsView.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl;\n\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.modules.tracer.impl.details.DetailsPanel;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.VisibilityHandler;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.TimelineSupport;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class DetailsView {\n\n    private final TimelineSupport timelineSupport;\n    private DetailsPanel panel;\n\n    private boolean hasData;\n\n    private VisibilityHandler viewHandler;\n\n    // --- Constructor ---------------------------------------------------------\n\n    DetailsView(TracerModel model) {\n        timelineSupport = model.getTimelineSupport();\n    }\n\n\n    // --- Internal interface --------------------------------------------------\n\n    void registerViewListener(VisibilityHandler viewHandler) {\n        if (panel != null) {\n            viewHandler.handle(panel);\n        } else {\n            this.viewHandler = viewHandler;\n        }\n\n    }\n\n    boolean isShowing() {\n        return panel != null && panel.isShowing();\n    }\n\n    boolean hasData() {\n        return hasData;\n    }\n\n\n    // --- UI implementation ---------------------------------------------------\n\n    DataViewComponent.DetailsView getView() {\n        panel = new DetailsPanel(timelineSupport);\n\n        timelineSupport.addSelectionListener(new TimelineSupport.SelectionListener() {\n            public void rowSelectionChanged(boolean rowsSelected) {\n                panel.setTableModel(timelineSupport.getDetailsModel());\n                hasData = rowsSelected;\n            }\n            public void timeSelectionChanged(boolean timestampsSelected, boolean justHovering) {}\n        });\n        if (viewHandler != null) {\n            viewHandler.handle(panel);\n            viewHandler = null;\n        }\n\n        return new DataViewComponent.DetailsView(\"Details\", null, 10, panel, null);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/PackagesView.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n\npackage org.graalvm.visualvm.modules.tracer.impl;\n\nimport org.graalvm.visualvm.modules.tracer.impl.probes.ProbeDescriptorComponent;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.modules.tracer.impl.options.TracerOptions;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.CategoryList;\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class PackagesView {\n\n    private final TracerModel model;\n    private final TracerController controller;\n\n\n    PackagesView(TracerModel model, TracerController controller) {\n        this.model = model;\n        this.controller = controller;\n    }\n\n\n    // --- Implementation ------------------------------------------------------\n\n    private void loadPackages(final JComponent view) {\n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() {\n                final List<TracerPackage> packages = model.getPackages();\n                if (packages != null) {\n                    final List<List<TracerProbeDescriptor>> descriptors = new ArrayList();\n                    for (TracerPackage p : packages) {\n                        TracerProbeDescriptor[] da = p.getProbeDescriptors();\n                        Arrays.sort(da, Positionable.COMPARATOR);\n                        List<TracerProbeDescriptor> dl = Arrays.asList(da);\n                        descriptors.add(dl);\n                    }\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { displayPackages(packages, descriptors, view); }\n                    });\n                } else {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { displayError(view); }\n                    });\n                }\n            }\n        });\n    }\n\n\n    // --- UI implementation ---------------------------------------------------\n\n    DataViewComponent.DetailsView getView() {\n        JComponent view = createComponents();\n        initListeners(view);\n        refreshState(view);\n        return new DataViewComponent.DetailsView(\"Probes\", null, 10, new ScrollableContainer(view), null);\n    }\n\n    private void refreshState(JComponent view) {\n        switch (controller.getState()) {\n            case TracerController.STATE_SESSION_INACTIVE:\n                view.setEnabled(true);\n                break;\n            case TracerController.STATE_SESSION_RUNNING:\n            case TracerController.STATE_SESSION_IMPOSSIBLE:\n            case TracerController.STATE_SESSION_STARTING:\n            case TracerController.STATE_SESSION_STOPPING:\n                view.setEnabled(false);\n                break;\n        }\n    }\n\n    private void initListeners(final JComponent view) {\n        view.addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (view.isShowing()) {\n                        view.removeHierarchyListener(this);\n                        loadPackages(view);\n                    }\n                }\n            }\n        });\n        controller.addListener(new PropertyChangeListener() {\n            public void propertyChange(PropertyChangeEvent evt) {\n                refreshState(view);\n            }\n        });\n    }\n\n    private void displayPackages(List<TracerPackage> packages,\n                                 List<List<TracerProbeDescriptor>> descriptors,\n                                 JComponent view) {\n\n        int packagesCount = descriptors.size();\n\n        String[] categories = new String[packagesCount];\n        String[] tooltips = new String[packagesCount];\n        boolean[] initialStates = new boolean[packagesCount];\n        Component[][] items = new Component[packagesCount][];\n\n        ProbeDescriptorComponent.SelectionHandler selectionHandler = new\n                ProbeDescriptorComponent.SelectionHandler() {\n            public void descriptorSelected(TracerPackage<DataSource> p, TracerProbeDescriptor d) {\n                model.addDescriptor(p, d);\n            }\n            public void descriptorUnselected(TracerPackage<DataSource> p, TracerProbeDescriptor d) {\n                model.removeDescriptor(p, d);\n            }\n        };\n\n        int probesApp = TracerOptions.getInstance().getProbesApp();\n        Boolean expanded = null;\n        if (probesApp == TracerOptions.KEY_PROBES_ALLEXP) expanded = true;\n        else if (probesApp == TracerOptions.KEY_PROBES_ALLCOLL) expanded = false;\n\n        for (int i = 0; i < packagesCount; i++) {\n            TracerPackage p = packages.get(i);\n            categories[i] = new String(p.getName());\n            tooltips[i] = new String(p.getDescription());\n            initialStates[i] = expanded == null || expanded;\n            if (expanded == null) expanded = false;\n\n            List<TracerProbeDescriptor> d = descriptors.get(i);\n            int descriptorsCount = d.size();\n\n            items[i] = new Component[descriptorsCount];\n            for (int j = 0; j < descriptorsCount; j++)\n                items[i][j] = new ProbeDescriptorComponent(d.get(j), p,\n                                                           selectionHandler);\n        }\n\n        view.removeAll();\n        view.add(new CategoryList(categories, tooltips, initialStates, items));\n        \n        view.revalidate();\n        view.repaint();\n    }\n    \n    private void displayError(JComponent view) {\n        view.removeAll();\n        view.add(new JLabel(\"Failed to load probes, check the logfile\",\n                 SwingConstants.CENTER), BorderLayout.CENTER);\n        \n        view.revalidate();\n        view.repaint();\n    }\n\n    private JComponent createComponents() {\n        JPanel panel = new JPanel(new BorderLayout()) {\n            public void setEnabled(boolean enabled) {\n                Component[] components = getComponents();\n                for (Component c : components) c.setEnabled(enabled);\n            }\n        };\n        panel.setOpaque(false);\n\n        JLabel waitLabel = new JLabel(\"Loading probes...\", SwingConstants.CENTER);\n        waitLabel.setEnabled(false);\n        panel.add(waitLabel, BorderLayout.CENTER);\n        \n        return panel;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/TimelineView.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl;\n\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.VisibilityHandler;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.TimelinePanel;\nimport javax.swing.AbstractButton;\nimport javax.swing.Action;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineView {\n\n    private final TracerModel model;\n    private TimelinePanel panel;\n\n    private VisibilityHandler viewHandler;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    TimelineView(TracerModel model) {\n        this.model = model;\n    }\n\n\n    // --- Internal interface --------------------------------------------------\n\n    void reset() {\n        if (panel != null) panel.reset();\n    }\n\n    void resetSelection() {\n        if (panel != null) panel.resetSelection();\n    }\n\n    Action zoomInAction() {\n        if (panel != null) return panel.zoomInAction();\n        return null;\n    }\n\n    Action zoomOutAction() {\n        if (panel != null) return panel.zoomOutAction();\n        return null;\n    }\n\n    Action toggleViewAction() {\n        if (panel != null) return panel.toggleViewAction();\n        return null;\n    }\n\n    AbstractButton mouseZoom() {\n        if (panel != null) return panel.mouseZoom();\n        return null;\n    }\n\n    AbstractButton mouseHScroll() {\n        if (panel != null) return panel.mouseHScroll();\n        return null;\n    }\n\n    AbstractButton mouseVScroll() {\n        if (panel != null) return panel.mouseVScroll();\n        return null;\n    }\n\n\n    void registerViewListener(VisibilityHandler viewHandler) {\n        if (panel != null) {\n            viewHandler.handle(panel);\n        } else {\n            this.viewHandler = viewHandler;\n        }\n\n    }\n\n    boolean isShowing() {\n        return panel != null && panel.isShowing();\n    }\n\n    // --- UI implementation ---------------------------------------------------\n\n    DataViewComponent.DetailsView getView() {\n        panel = new TimelinePanel(model.getTimelineSupport());\n\n        if (viewHandler != null) {\n            viewHandler.handle(panel);\n            viewHandler = null;\n        }\n\n        return new DataViewComponent.DetailsView(\"Timeline\", null, 10, panel, null);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/TracerController.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.modules.tracer.PackageStateHandler;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.ProbeStateHandler;\nimport org.graalvm.visualvm.modules.tracer.SessionInitializationException;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport org.graalvm.visualvm.modules.tracer.impl.options.TracerOptions;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.WeakListeners;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TracerController implements DataRemovedListener<DataSource>,\n                                        PropertyChangeListener {\n\n    private static final Logger LOGGER = Logger.getLogger(TracerController.class.getName());\n\n    private static final String PROPERTY_STATE = \"state\"; // NOI18N\n    static final int STATE_SESSION_INACTIVE = 0;\n    static final int STATE_SESSION_RUNNING = 1;\n    static final int STATE_SESSION_IMPOSSIBLE = -1;\n    static final int STATE_SESSION_STARTING = Integer.MAX_VALUE;\n    static final int STATE_SESSION_STOPPING = Integer.MIN_VALUE;\n\n    private final DataSource dataSource;\n    private final TracerModel model;\n\n    private final PropertyChangeSupport changeSupport;\n    private int state;\n\n    private TracerProgressObject progress;\n    private String error;\n    private boolean wasNegativeValue;\n\n    private boolean running;\n    private final Timer timer;\n    private RequestProcessor processor;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    TracerController(TracerModel model) {\n        this.model = model;\n        dataSource = model.getDataSource();\n\n        Stateful stateful = dataSource instanceof Stateful ?\n                            (Stateful) dataSource : null;\n\n        if (stateful == null || stateful.getState() == Stateful.STATE_AVAILABLE) {\n            dataSource.notifyWhenRemoved(this);\n            dataSource.addPropertyChangeListener(Stateful.PROPERTY_STATE,\n                    WeakListeners.propertyChange(this, dataSource));\n            changeSupport = new PropertyChangeSupport(this);\n            state = STATE_SESSION_INACTIVE;\n            timer = createTimer();\n        } else {\n            changeSupport = null;\n            state = STATE_SESSION_IMPOSSIBLE;\n            timer = null;\n        }\n    }\n\n\n    // --- Session & probes state ----------------------------------------------\n\n    private void setState(final int state) {\n        Runnable stateSetter = new Runnable() {\n            public void run() {\n                if (TracerController.this.state == STATE_SESSION_IMPOSSIBLE) return;\n                int oldState = TracerController.this.state;\n                TracerController.this.state = state;\n                changeSupport.firePropertyChange(PROPERTY_STATE, oldState, state);\n                if (state == STATE_SESSION_RUNNING) startTimer();\n            }\n        };\n        if (SwingUtilities.isEventDispatchThread()) stateSetter.run();\n        else SwingUtilities.invokeLater(stateSetter);\n    }\n\n    int getState() {\n        return state;\n    }\n\n    TracerProgressObject getProgress() {\n        return progress;\n    }\n\n    String getErrorMessage() {\n        return error;\n    }\n\n    void addListener(PropertyChangeListener listener) {\n        if (changeSupport != null && state != STATE_SESSION_IMPOSSIBLE)\n            changeSupport.addPropertyChangeListener(PROPERTY_STATE, listener);\n    }\n\n    void removeListener(PropertyChangeListener listener) {\n        if (changeSupport != null)\n            changeSupport.removePropertyChangeListener(PROPERTY_STATE, listener);\n    }\n\n\n    // --- Session control -----------------------------------------------------\n\n    void setRefreshRate(int refreshRate) {\n        if (timer != null && getRefreshRate() != refreshRate) {\n            Set<Map.Entry<TracerPackage, List<TracerProbe>>> toNotify =\n                model.getDefinedProbeSets();\n            notifyRefreshRateChanged(toNotify);\n            timer.setDelay(refreshRate);\n        }\n    }\n\n    int getRefreshRate() {\n        return timer != null ? timer.getDelay() : -1;\n    }\n\n    void startSession() {\n        if (!model.areProbesDefined()) return;\n        if (doStartSession()) setState(STATE_SESSION_RUNNING);\n        else setState(STATE_SESSION_INACTIVE);\n    }\n\n    void stopSession() {\n        stopTimer();\n        if (state == STATE_SESSION_RUNNING) setState(STATE_SESSION_STOPPING);\n        doStopSession();\n        setState(STATE_SESSION_INACTIVE);\n    }\n\n    private boolean doStartSession() {\n        wasNegativeValue = false;\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { model.getTimelineSupport().resetValues(); }\n        });\n        Set<Map.Entry<TracerPackage, List<TracerProbe>>> toNotify =\n                model.getDefinedProbeSets();\n        notifySessionInitializing(toNotify);\n        setState(STATE_SESSION_STARTING);\n        if (!notifySessionStarting(toNotify)) return false;\n        notifySessionRunning(toNotify);\n        return true;\n    }\n\n    private void doStopSession() {\n        Set<Map.Entry<TracerPackage, List<TracerProbe>>> toNotify =\n                model.getDefinedProbeSets();\n        notifySessionStopping(toNotify);\n        notifySessionFinished(toNotify);\n    }\n\n    private void notifySessionInitializing(Set<Map.Entry<TracerPackage, List<TracerProbe>>> items) {\n        List<TracerProgressObject> progresses = new ArrayList();\n        int steps = 0;\n        Iterator<Map.Entry<TracerPackage, List<TracerProbe>>> itemsI = items.iterator();\n        while (itemsI.hasNext()) {\n            Map.Entry<TracerPackage, List<TracerProbe>> item = itemsI.next();\n            List<TracerProbe> probes = item.getValue();\n            TracerProbe[] probesArr = probes.toArray(new TracerProbe[probes.size()]);\n\n            int refresh = getRefreshRate();\n\n            PackageStateHandler ph = item.getKey().getStateHandler();\n            if (ph != null) try {\n                TracerProgressObject c = ph.sessionInitializing(probesArr, dataSource, refresh);\n                if (c != null) {\n                    steps += c.getSteps();\n                    progresses.add(c);\n                }\n            } catch (Throwable t) {\n                LOGGER.log(Level.INFO, \"Package exception in sessionInitializing\", t); // NOI18N\n            }\n\n            Iterator<TracerProbe> probesI = probes.iterator();\n            while (probesI.hasNext()) {\n                TracerProbe probe = probesI.next();\n                ProbeStateHandler rh = probe.getStateHandler();\n                if (rh != null) try {\n                    TracerProgressObject c = rh.sessionInitializing(dataSource, refresh);\n                    if (c != null)  {\n                        steps += c.getSteps();\n                        progresses.add(c);\n                    }\n                } catch (Throwable t) {\n                    LOGGER.log(Level.INFO, \"Probe exception in sessionInitializing\", t); // NOI18N\n                }\n            }\n        }\n        if (steps == 0) {\n            progress = null;\n        } else {\n            progress = new TracerProgressObject(steps, \"Starting session...\");\n            TracerProgressObject.Listener l = new TracerProgressObject.Listener() {\n                public void progressChanged(int addedSteps, int currentStep, String text) {\n                    progress.addSteps(addedSteps, text);\n                }\n            };\n            for (TracerProgressObject o : progresses) o.addListener(l);\n        }\n        error = null;\n    }\n\n    private boolean notifySessionStarting(Set<Map.Entry<TracerPackage, List<TracerProbe>>> items) {\n        Iterator<Map.Entry<TracerPackage, List<TracerProbe>>> itemsI = items.iterator();\n        Map<TracerPackage, List<TracerProbe>> notifiedItems = new HashMap();\n        String notifiedName = null;\n        try {\n            while (itemsI.hasNext()) {\n                Map.Entry<TracerPackage, List<TracerProbe>> item = itemsI.next();\n                TracerPackage pkg = item.getKey();\n                notifiedName = pkg.getName();\n                List<TracerProbe> probes = item.getValue();\n                TracerProbe[] probesArr = probes.toArray(new TracerProbe[probes.size()]);\n\n                PackageStateHandler ph = pkg.getStateHandler();\n                if (ph != null) ph.sessionStarting(probesArr, dataSource);\n                List<TracerProbe> notifiedList = new ArrayList();\n                notifiedItems.put(pkg, notifiedList);\n\n                Iterator<TracerProbe> probesI = probes.iterator();\n                while (probesI.hasNext()) {\n                    TracerProbe probe = probesI.next();\n                    notifiedName = model.getDescriptor(probe).getProbeName();\n                    ProbeStateHandler rh = probe.getStateHandler();\n                    if (rh != null) rh.sessionStarting(dataSource);\n                    notifiedList.add(probe);\n                }\n            }\n            return true;\n        } catch (SessionInitializationException sie) {\n            // TODO: update UI\n            LOGGER.log(Level.INFO, \"Package or probe failed to start Tracer session\", sie); // NOI18N\n            error = sie.getUserMessage();\n            if (error == null) error = notifiedName + \" failed to start\";\n\n            Set<Map.Entry<TracerPackage, List<TracerProbe>>> notifiedItemsE =\n                    notifiedItems.entrySet();\n            notifySessionStopping(notifiedItemsE);\n            setState(STATE_SESSION_STOPPING);\n            notifySessionFinished(notifiedItemsE);\n\n            return false;\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Package or probe exception in sessionStarting\", t); // NOI18N\n            return true;\n            // TODO: ignore or terminate the session as for the SessionInitializationException?\n        }\n    }\n\n    private void notifySessionRunning(Set<Map.Entry<TracerPackage, List<TracerProbe>>> items) {\n        Iterator<Map.Entry<TracerPackage, List<TracerProbe>>> itemsI = items.iterator();\n        while (itemsI.hasNext()) {\n            Map.Entry<TracerPackage, List<TracerProbe>> item = itemsI.next();\n            List<TracerProbe> probes = item.getValue();\n            TracerProbe[] probesArr = probes.toArray(new TracerProbe[probes.size()]);\n\n            PackageStateHandler ph = item.getKey().getStateHandler();\n            if (ph != null) try {\n                ph.sessionRunning(probesArr, dataSource);\n            } catch (Throwable t) {\n                LOGGER.log(Level.INFO, \"Package exception in sessionRunning\", t); // NOI18N\n            }\n\n            Iterator<TracerProbe> probesI = probes.iterator();\n            while (probesI.hasNext()) {\n                TracerProbe probe = probesI.next();\n                ProbeStateHandler rh = probe.getStateHandler();\n                if (rh != null) try {\n                    rh.sessionRunning(dataSource);\n                } catch (Throwable t) {\n                    LOGGER.log(Level.INFO, \"Probe exception in sessionRunning\", t); // NOI18N\n                }\n            }\n        }\n    }\n\n    private void notifySessionStopping(Set<Map.Entry<TracerPackage, List<TracerProbe>>> items) {\n        Iterator<Map.Entry<TracerPackage, List<TracerProbe>>> itemsI = items.iterator();\n        while (itemsI.hasNext()) {\n            Map.Entry<TracerPackage, List<TracerProbe>> item = itemsI.next();\n            List<TracerProbe> probes = item.getValue();\n            TracerProbe[] probesArr = probes.toArray(new TracerProbe[probes.size()]);\n\n            PackageStateHandler ph = item.getKey().getStateHandler();\n            if (ph != null) try {\n                ph.sessionStopping(probesArr, dataSource);\n            } catch (Throwable t) {\n                LOGGER.log(Level.INFO, \"Package exception in sessionStopping\", t); // NOI18N\n            }\n\n            Iterator<TracerProbe> probesI = probes.iterator();\n            while (probesI.hasNext()) {\n                TracerProbe probe = probesI.next();\n                ProbeStateHandler rh = probe.getStateHandler();\n                if (rh != null) try {\n                    rh.sessionStopping(dataSource);\n                } catch (Throwable t) {\n                    LOGGER.log(Level.INFO, \"Probe exception in sessionStopping\", t); // NOI18N\n                }\n            }\n        }\n    }\n\n    private void notifySessionFinished(Set<Map.Entry<TracerPackage, List<TracerProbe>>> items) {\n        Iterator <Map.Entry<TracerPackage, List<TracerProbe>>> itemsI = items.iterator();\n        while (itemsI.hasNext()) {\n            Map.Entry<TracerPackage, List<TracerProbe>> item = itemsI.next();\n            List<TracerProbe> probes = item.getValue();\n            TracerProbe[] probesArr = probes.toArray(new TracerProbe[probes.size()]);\n\n            PackageStateHandler ph = item.getKey().getStateHandler();\n            if (ph != null) try {\n                ph.sessionFinished(probesArr, dataSource);\n            } catch (Throwable t) {\n                LOGGER.log(Level.INFO, \"Package exception in sessionFinished\", t); // NOI18N\n            }\n\n            Iterator<TracerProbe> probesI = probes.iterator();\n            while (probesI.hasNext()) {\n                TracerProbe probe = probesI.next();\n                ProbeStateHandler rh = probe.getStateHandler();\n                if (rh != null) try {\n                    rh.sessionFinished(dataSource);\n                } catch (Throwable t) {\n                    LOGGER.log(Level.INFO, \"Probe exception in sessionFinished\", t); // NOI18N\n                }\n            }\n        }\n    }\n\n    private void notifyRefreshRateChanged(Set<Map.Entry<TracerPackage, List<TracerProbe>>> items) {\n        Iterator<Map.Entry<TracerPackage, List<TracerProbe>>> itemsI = items.iterator();\n        while (itemsI.hasNext()) {\n            Map.Entry<TracerPackage, List<TracerProbe>> item = itemsI.next();\n            List<TracerProbe> probes = item.getValue();\n            TracerProbe[] probesArr = probes.toArray(new TracerProbe[probes.size()]);\n\n            int refresh = getRefreshRate();\n\n            PackageStateHandler ph = item.getKey().getStateHandler();\n            if (ph != null) try {\n                ph.refreshRateChanged(probesArr, dataSource, refresh);\n            } catch (Throwable t) {\n                LOGGER.log(Level.INFO, \"Package exception in refreshRateChanged\", t); // NOI18N\n            }\n\n            Iterator<TracerProbe> probesI = probes.iterator();\n            while (probesI.hasNext()) {\n                TracerProbe probe = probesI.next();\n                ProbeStateHandler rh = probe.getStateHandler();\n                if (rh != null) try {\n                    rh.refreshRateChanged(dataSource, refresh);\n                } catch (Throwable t) {\n                    LOGGER.log(Level.INFO, \"Probe exception in refreshRateChanged\", t); // NOI18N\n                }\n            }\n        }\n    }\n\n\n    // --- Session runtime -----------------------------------------------------\n\n    private Timer createTimer() {\n        int rate = TracerOptions.getInstance().getRefreshRate();\n        Timer t = new Timer(rate, new ActionListener() {\n            public void actionPerformed(ActionEvent e) { fetchData(); }\n        });\n        t.setInitialDelay(0);\n        return t;\n    }\n    \n    private void startTimer() {\n        if (timer != null) {\n            running = true;\n            timer.start();\n        }\n    }\n\n    private void stopTimer() {\n        if (timer != null) {\n            running = false;\n            timer.stop();\n        }\n    }\n\n    private void fetchData() {\n        if (!running) return;\n\n        if (processor == null)\n            processor = new RequestProcessor(\"Tracer Processor for \" + dataSource); // NOI18N\n\n        final List<TracerProbe> probes = model.getDefinedProbes();\n        final int itemsCount = model.getTimelineSupport().getItemsCount();\n        processor.post(new Runnable() {\n            public void run() { fetchDataImpl(probes, itemsCount); }\n        });\n    }\n\n    private void fetchDataImpl(List<TracerProbe> probes, int itemsCount) {\n        if (!running) return;\n\n        final long[] values = new long[itemsCount];\n        int currentIndex = 0;\n\n        final long timestamp = System.currentTimeMillis();\n\n        for (TracerProbe probe : probes) {\n            long[] itemValues;\n            try {\n                itemValues = probe.getItemValues(timestamp);\n            } catch (Throwable t) {\n                itemValues = new long[probe.getItemsCount()];\n                Arrays.fill(itemValues, ProbeItemDescriptor.VALUE_UNDEFINED);\n                LOGGER.log(Level.INFO, \"Probe exception in getItemValues\", t); // NOI18N\n            }\n            for (int i = 0; i < itemValues.length; i++) {\n                long value = itemValues[i];\n                if (value < 0) {\n                    if (!wasNegativeValue) {\n                        DialogDisplayer.getDefault().notifyLater(\n                        new NotifyDescriptor.Message(\"<html><b>One or more probes \"\n                        + \"returned negative value.</b><br><br>Currently this is \"\n                        + \"not supported in Tracer,<br>all negative values will be\"\n                        + \" displayed as 0.</html>\", NotifyDescriptor.WARNING_MESSAGE));\n                        LOGGER.info(\"Probe \" + model.getDescriptor(probe).getProbeName() + // NOI18N\n                                    \" returned negative value: \" + value); // NOI18N\n                        wasNegativeValue = true;\n                    }\n                    value = 0;\n                }\n                values[currentIndex++] = value;\n            }\n        }\n\n        if (!running) return;\n\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (!running) return;\n                model.getTimelineSupport().addValues(timestamp, values);\n            }\n        });\n\n    }\n\n\n    // --- DataSource & DataSourceView lifecycle -------------------------------\n\n    void viewRemoved() {\n        stopSession();\n        setState(STATE_SESSION_IMPOSSIBLE);\n    }\n\n    public void dataRemoved(DataSource dataSource) {\n        stopTimer();\n        setState(STATE_SESSION_IMPOSSIBLE);\n    }\n\n    public void propertyChange(PropertyChangeEvent evt) {\n        stopTimer();\n        setState(STATE_SESSION_IMPOSSIBLE);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/TracerModel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.modules.tracer.PackageStateHandler;\nimport org.graalvm.visualvm.modules.tracer.ProbeStateHandler;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.TimelineSupport;\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.Set;\nimport java.util.TreeSet;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.SwingUtilities;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TracerModel {\n\n    private static final Logger LOGGER = Logger.getLogger(TracerController.class.getName());\n\n    private final DataSource dataSource;\n\n    private final Map<TracerPackage, List<TracerProbe>> probesCache = new HashMap();\n    private final Map<TracerProbe, TracerProbeDescriptor> descriptorsCache = new HashMap();\n\n    private final Set<Listener> listeners = new HashSet();\n\n    private final TimelineSupport timelineSupport;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    TracerModel(DataSource dataSource) {\n        this.dataSource = dataSource;\n        final TimelineSupport[] timelineSupportArr = new TimelineSupport[1];\n        try {\n            SwingUtilities.invokeAndWait(new Runnable() {\n                public void run() {\n                    timelineSupportArr[0] = new TimelineSupport(new TimelineSupport.DescriptorResolver() {\n                    public TracerProbeDescriptor getDescriptor(TracerProbe p) {\n                        return TracerModel.this.getDescriptor(p);\n                    }\n                });\n                }\n            });\n        } catch (Exception e) {\n            LOGGER.severe(\"Failed to create TimelineSupport for \" + dataSource); // NOI18N\n        }\n        timelineSupport = timelineSupportArr[0];\n    }\n\n\n    // --- DataSource ----------------------------------------------------------\n\n    DataSource getDataSource() {\n        return dataSource;\n    }\n\n\n    // --- Packages ------------------------------------------------------------\n\n    List<TracerPackage> getPackages() {\n        try {\n            return TracerSupportImpl.getInstance().getPackages(dataSource);\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Package exception in getPackages\", t); // NOI18N\n            return null;\n        }\n    }\n\n\n    // --- Probes --------------------------------------------------------------\n\n    void addDescriptor(final TracerPackage<DataSource> p,\n                       final TracerProbeDescriptor d) {\n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() { addProbe(p, d); }\n        });\n    }\n\n    void removeDescriptor(final TracerPackage<DataSource> p,\n                          final TracerProbeDescriptor d) {\n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() { removeProbe(p, d); }\n        });\n    }\n\n    TracerProbeDescriptor getDescriptor(TracerProbe p) {\n        synchronized(descriptorsCache) {\n            return descriptorsCache.get(p);\n        }\n    }\n\n    // Must be called in EDT\n    List<TracerProbe> getDefinedProbes() {\n        List<TracerProbe> probes = new ArrayList();\n        probes.addAll(timelineSupport.getProbes());\n        return probes;\n    }\n\n    Set<Map.Entry<TracerPackage, List<TracerProbe>>> getDefinedProbeSets() {\n        Comparator<Map.Entry<TracerPackage, List<TracerProbe>>> comp =\n                new Comparator<Map.Entry<TracerPackage, List<TracerProbe>>>() {\n            public int compare(Entry<TracerPackage, List<TracerProbe>> o1,\n                               Entry<TracerPackage, List<TracerProbe>> o2) {\n                return Positionable.STRONG_COMPARATOR.compare(o1.getKey(), o2.getKey());\n            }\n        };\n        Set<Map.Entry<TracerPackage, List<TracerProbe>>> probes = new TreeSet(comp);\n        synchronized(probesCache) { probes.addAll(probesCache.entrySet()); }\n        return probes;\n    }\n\n    boolean areProbesDefined() {\n        synchronized(probesCache) { return !probesCache.isEmpty(); }\n    }\n\n\n    private void addProbe(TracerPackage<DataSource> p, TracerProbeDescriptor d) {\n        TracerProbe<DataSource> r = p.getProbe(d);\n        synchronized(descriptorsCache) {\n            descriptorsCache.put(r, d);\n        }\n        synchronized(probesCache) {\n            List<TracerProbe> probes = probesCache.get(p);\n            if (probes == null) {\n                probes = new ArrayList();\n                probesCache.put(p, probes);\n            }\n            probes.add(r);\n        }\n\n        timelineSupport.addProbe(r);\n\n        notifyProbeAdded(p, r);\n        fireProbeAdded(r);\n    }\n\n    private void removeProbe(TracerPackage<DataSource> p, TracerProbeDescriptor d) {\n        TracerProbe probe = null;\n        boolean probesDefined = true;\n\n        synchronized(descriptorsCache) {\n            Iterator<Map.Entry<TracerProbe, TracerProbeDescriptor>> iter =\n                    descriptorsCache.entrySet().iterator();\n            while (iter.hasNext()) {\n                Map.Entry<TracerProbe, TracerProbeDescriptor> entry = iter.next();\n                if (entry.getValue() == d) {\n                    probe = entry.getKey();\n                    break;\n                }\n            }\n            descriptorsCache.remove(probe);\n        }\n        synchronized(probesCache) {\n            List<TracerProbe> probes = probesCache.get(p);\n            probes.remove(probe);\n            if (probes.isEmpty()) {\n                probesCache.remove(p);\n                probesDefined = !probesCache.isEmpty();\n            }\n        }\n\n        timelineSupport.removeProbe(probe);\n\n        notifyProbeRemoved(p, probe);\n        fireProbeRemoved(probe, probesDefined);\n    }\n\n    private void notifyProbeAdded(TracerPackage p, TracerProbe<DataSource> r) {\n        PackageStateHandler ph = p.getStateHandler();\n        if (ph != null) try {\n            ph.probeAdded(r, dataSource);\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Package exception in probeAdded\", t); // NOI18N\n        }\n\n        ProbeStateHandler rh = r.getStateHandler();\n        if (rh != null) try {\n            rh.probeAdded(dataSource);\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Probe exception in probeAdded\", t); // NOI18N\n        }\n    }\n\n    private void notifyProbeRemoved(TracerPackage p, TracerProbe<DataSource> r) {\n        PackageStateHandler ph = p.getStateHandler();\n        if (ph != null) try {\n            ph.probeRemoved(r, dataSource);\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Package exception in probeRemoved\", t); // NOI18N\n        }\n\n        ProbeStateHandler rh = r.getStateHandler();\n        if (rh != null) try {\n            rh.probeRemoved(dataSource);\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Probe exception in probeRemoved\", t); // NOI18N\n        }\n    }\n\n\n    // --- Events support ------------------------------------------------------\n\n    void addListener(Listener listener) {\n        synchronized(listeners) { listeners.add(listener); }\n    }\n\n    void removeListener(Listener listener) {\n        synchronized(listeners) { listeners.remove(listener); }\n    }\n\n    private void fireProbeAdded(final TracerProbe probe) {\n        final Set<Listener> toNotify = new HashSet();\n        synchronized(listeners) { toNotify.addAll(listeners); }\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                for (Listener listener : toNotify)\n                    listener.probeAdded(probe);\n            }\n        });\n        \n    }\n\n    private void fireProbeRemoved(final TracerProbe probe, final boolean probesDefined) {\n        final Set<Listener> toNotify = new HashSet();\n        synchronized(listeners) { toNotify.addAll(listeners); }\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                for (Listener listener : toNotify)\n                    listener.probeRemoved(probe, probesDefined);\n            }\n        });\n    }\n\n    static interface Listener {\n\n        public void probeAdded(TracerProbe probe);\n\n        public void probeRemoved(TracerProbe probe, boolean probesDefined);\n\n    }\n\n\n    // --- Timeline ------------------------------------------------------------\n\n    TimelineSupport getTimelineSupport() {\n        return timelineSupport;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/TracerSupportImpl.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport org.graalvm.visualvm.modules.tracer.TracerPackageProvider;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class TracerSupportImpl {\n\n    private static TracerSupportImpl INSTANCE;\n\n    private final Set<TracerPackageProvider> providers;\n\n\n    public static synchronized TracerSupportImpl getInstance() {\n        if (INSTANCE == null) INSTANCE = new TracerSupportImpl();\n        return INSTANCE;\n    }\n\n\n    public synchronized void registerPackageProvider(TracerPackageProvider provider) {\n        providers.add(provider);\n    }\n\n    public synchronized void unregisterPackageProvider(TracerPackageProvider provider) {\n        providers.remove(provider);\n    }\n\n\n    public synchronized boolean hasPackages(DataSource dataSource) {\n        for (TracerPackageProvider provider : providers)\n            if (provider.getScope().isInstance(dataSource))\n                return true;\n        return false;\n    }\n\n    public synchronized List<TracerPackage> getPackages(DataSource dataSource) {\n        List<TracerPackage> packages = new ArrayList();\n        for (TracerPackageProvider provider : providers)\n            if (provider.getScope().isInstance(dataSource))\n                packages.addAll(Arrays.asList(provider.getPackages(dataSource)));\n        Collections.sort(packages, Positionable.COMPARATOR);\n        return packages;\n    }\n\n\n    private TracerSupportImpl() {\n        providers = new HashSet();\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/TracerView.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl;\n\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.CustomComboRenderer;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport org.graalvm.visualvm.modules.tracer.impl.options.TracerOptions;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.DropdownButton;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.SimpleSeparator;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.VisibilityHandler;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.TimelineSupport;\nimport org.graalvm.visualvm.uisupport.HorizontalLayout;\nimport org.graalvm.visualvm.uisupport.TransparentToolBar;\nimport java.awt.CardLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Insets;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.Date;\nimport javax.swing.AbstractAction;\nimport javax.swing.AbstractButton;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.ButtonGroup;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JComboBox;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JProgressBar;\nimport javax.swing.JToggleButton;\nimport javax.swing.JToolBar;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TracerView extends DataSourceView {\n\n    private static final int INDETERMINATE_PROGRESS_THRESHOLD =\n                Integer.getInteger(\"visualvm.tracer.indeterminateProgressThreshold\", 2500); // NOI18N\n\n    private static final String IMAGE_PATH =\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/tracer.png\"; // NOI18N\n\n    private final TracerModel model;\n    private final TracerController controller;\n\n    private DataViewComponent dvc;\n    private TimelineView timelineView;\n    private DetailsView detailsView;\n\n    \n    TracerView(TracerModel model, TracerController controller) {\n        super(model.getDataSource(), \"Tracer\", new ImageIcon(\n              ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 100, false);\n        this.model = model;\n        this.controller = controller;\n    }\n\n\n    // --- DataSourceView implementation ---------------------------------------\n\n    protected DataViewComponent createComponent() {\n        PackagesView packagesView = new PackagesView(model, controller);\n        timelineView = new TimelineView(model);\n        detailsView = new DetailsView(model);\n        MasterViewSupport masterView = new MasterViewSupport();\n        \n        dvc = new DataViewComponent(masterView.getView(),\n                new DataViewComponent.MasterViewConfiguration(false));\n\n        dvc.configureDetailsView(new DataViewComponent.DetailsViewConfiguration(0.33, 0, 0.33, 0, 0.5, 0.5));\n\n        String initiallyOpened = TracerOptions.getInstance().getInitiallyOpened();\n\n        \n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Probes\", true), DataViewComponent.TOP_LEFT);\n        dvc.addDetailsView(packagesView.getView(), DataViewComponent.TOP_LEFT);\n        if (!initiallyOpened.contains(TracerOptions.VIEW_PROBES))\n            dvc.hideDetailsArea(DataViewComponent.TOP_LEFT);\n\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Timeline\", true), DataViewComponent.TOP_RIGHT);\n        dvc.addDetailsView(timelineView.getView(), DataViewComponent.TOP_RIGHT);\n        if (!initiallyOpened.contains(TracerOptions.VIEW_TIMELINE))\n            dvc.hideDetailsArea(DataViewComponent.TOP_RIGHT);\n\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Details\", true), DataViewComponent.BOTTOM_RIGHT);\n        dvc.addDetailsView(detailsView.getView(), DataViewComponent.BOTTOM_RIGHT);\n        if (!initiallyOpened.contains(TracerOptions.VIEW_DETAILS))\n            dvc.hideDetailsArea(DataViewComponent.BOTTOM_RIGHT);\n\n        return dvc;\n    }\n\n\n    // --- Master view implementation ------------------------------------------\n\n    private class MasterViewSupport {\n\n        private static final String START_IMAGE_PATH =\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/start.png\"; // NOI18N\n        private static final String STOP_IMAGE_PATH =\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/stop.png\"; // NOI18N\n        private static final String ERROR_IMAGE_PATH =\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/error.png\"; // NOI18N\n        private static final String SETTINGS_IMAGE_PATH =\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/settings.png\"; // NOI18N\n        private static final String CLPROBE_IMAGE_PATH =\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/probeClear.png\"; // NOI18N\n        private static final String CLMARK_IMAGE_PATH =\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/markClear.png\"; // NOI18N\n        private static final String EXPORT_IMAGE_PATH =\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/export.png\"; // NOI18N\n\n        private static final String SYSTEM_TOOLBAR = \"systemToolbar\"; // NOI18N\n        private static final String CLIENT_TOOLBAR = \"clientToolbar\"; // NOI18N\n\n        private int commonControlHeight;\n\n        private AbstractButton startButton;\n        private AbstractButton stopButton;\n\n        private CardLayout toolbarLayout;\n        private JPanel toolbar;\n        private JPanel systemToolbar;\n        private JPanel clientToolbar;\n\n        private TransparentToolBar timelineToolbar;\n        private TransparentToolBar selectionToolbar;\n        private TransparentToolBar extraToolbar;\n\n        private JButton clearRowSelectionButton;\n        private JButton clearTimestampSelectionButton;\n\n        private Action exportAllAction;\n        private Action exportDetailsAction;\n\n\n        DataViewComponent.MasterView getView() {\n            JComponent view = createComponents();\n            initListeners();\n            refreshState(model.areProbesDefined());\n\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    Dimension size = new Dimension(commonControlHeight, commonControlHeight);\n                    createTimelineToolbar(size);\n                    createSelectionToolbar(size);\n                    createExtraToolbar(size);\n                }\n            });\n\n            return new DataViewComponent.MasterView(\"Tracer\", null, view);\n        }\n\n\n        private void refreshState(boolean probesDefined) {\n            switch (controller.getState()) {\n                case TracerController.STATE_SESSION_RUNNING:\n                    startButton.setEnabled(false);\n                    startButton.setSelected(false);\n                    stopButton.setEnabled(true);\n                    stopButton.requestFocusInWindow();\n                    resetSystemToolbar();\n                    updateViewsOnSessionStart();\n                    break;\n                case TracerController.STATE_SESSION_INACTIVE:\n                    startButton.setEnabled(probesDefined);\n                    startButton.setSelected(false);\n                    stopButton.setEnabled(false);\n                    if (startButton.isEnabled() && KeyboardFocusManager.\n                        getCurrentKeyboardFocusManager().getFocusOwner() == null)\n                        startButton.requestFocusInWindow();\n                    break;\n                case TracerController.STATE_SESSION_IMPOSSIBLE:\n                    startButton.setEnabled(false);\n                    stopButton.setEnabled(false);\n                    break;\n                case TracerController.STATE_SESSION_STARTING:\n                    startButton.setEnabled(false);\n                    stopButton.setEnabled(false);\n                    startButton.setFocusable(false);\n                    startButton.setFocusable(true);\n                    showProgress();\n                    timelineView.reset();\n                    break;\n                case TracerController.STATE_SESSION_STOPPING:\n                    startButton.setEnabled(false);\n                    startButton.setSelected(false);\n                    stopButton.setEnabled(false);\n                    stopButton.setFocusable(false);\n                    stopButton.setFocusable(true);\n                    String error = controller.getErrorMessage();\n                    if (error != null) showMessage(error);\n                    break;\n            }\n        }\n\n        private void initListeners() {\n            controller.addListener(new PropertyChangeListener() {\n                public void propertyChange(PropertyChangeEvent evt) {\n                    refreshState(model.areProbesDefined());\n                }\n            });\n\n            model.addListener(new TracerModel.Listener() {\n                public void probeAdded(TracerProbe probe) {\n                    refreshState(true);\n                    updateViewsOnProbesChange(true);\n                }\n                public void probeRemoved(TracerProbe probe, boolean probesDefined) {\n                    refreshState(probesDefined);\n                    updateViewsOnProbesChange(probesDefined);\n                }\n            });\n\n            final boolean dynamicSelection = TracerOptions.getInstance().getSelectionToolbar() == TracerOptions.SHOW_AS_NEEDED;\n            model.getTimelineSupport().addSelectionListener(\n                    new TimelineSupport.SelectionListener() {\n                public void rowSelectionChanged(boolean rowsSelected) {\n                    updateViewsOnSelectionChange(rowsSelected);\n                    updateSelectionToolbar(dynamicSelection);\n                }\n                public void timeSelectionChanged(boolean timestampsSelected, boolean justHovering) {\n                    updateSelectionToolbar(dynamicSelection);\n                }\n            });\n\n            if (TracerOptions.getInstance().getTimelineToolbar() == TracerOptions.SHOW_AS_NEEDED)\n                timelineView.registerViewListener(new VisibilityHandler() {\n                    public void shown()  { showTimelineToolbar(); }\n                    public void hidden() { hideTimelineToolbar(); }\n                });\n            \n            detailsView.registerViewListener(new VisibilityHandler() {\n                public void shown()  {}\n                public void hidden() {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            // Doesn't clear the selection when switching tabs and\n                            // manipulating topcomponents\n                            if (!detailsView.isShowing() && timelineView.isShowing())\n                                clearSelections();\n                        }\n                    });\n                }\n            });\n\n            if (TracerOptions.getInstance().getExtraToolbar() == TracerOptions.SHOW_AS_NEEDED)\n                model.getTimelineSupport().addValuesListener(new TimelineSupport.ValuesListener() {\n                    public void valuesAdded() { showExtraToolbar(); }\n                    public void valuesReset() { hideExtraToolbar(); }\n                });\n        }\n\n        private void clearSelections() {\n            if (TracerOptions.getInstance().isClearSelection()) {\n                timelineView.resetSelection();\n//                model.getTimelineSupport().resetSelectedTimestamps();\n            }\n        }\n\n        private void updateViewsOnSessionStart() {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    String views = TracerOptions.getInstance().getOnSessionStart();\n                    updateViews(views);\n                }\n            });\n        }\n\n        private void updateViewsOnProbesChange(boolean probesDefined) {\n            String views = probesDefined ?\n                TracerOptions.getInstance().getOnProbeAdded() :\n                TracerOptions.getInstance().getOnProbeAdded2();\n            updateViews(views);\n        }\n\n        private void updateViewsOnSelectionChange(boolean rowsSelected) {\n            String views = rowsSelected ?\n                TracerOptions.getInstance().getOnRowSelected() :\n                TracerOptions.getInstance().getOnRowSelected2();\n            updateViews(views);\n        }\n\n        private void updateViews(String views) {\n            if (!views.equals(TracerOptions.VIEWS_UNCHANGED)) {\n                // Probes\n                setProbesVisible(views.contains(TracerOptions.VIEW_PROBES));\n                // Timeline\n                setTimelineVisible(views.contains(TracerOptions.VIEW_TIMELINE));\n                // Details\n                setDetailsVisible(views.contains(TracerOptions.VIEW_DETAILS));\n            }\n        }\n\n        private void setProbesVisible(boolean visible) {\n            if (visible) dvc.showDetailsArea(DataViewComponent.TOP_LEFT);\n            else dvc.hideDetailsArea(DataViewComponent.TOP_LEFT);\n        }\n\n        private void setTimelineVisible(boolean visible) {\n            if (visible) dvc.showDetailsArea(DataViewComponent.TOP_RIGHT);\n            else dvc.hideDetailsArea(DataViewComponent.TOP_RIGHT);\n        }\n\n        private void setDetailsVisible(boolean visible) {\n            if (visible) dvc.showDetailsArea(DataViewComponent.BOTTOM_RIGHT);\n            else dvc.hideDetailsArea(DataViewComponent.BOTTOM_RIGHT);\n        }\n\n        private void showMessage(String text) {\n            setSystemToolbarItem(new JLabel(text, new ImageIcon(ImageUtilities.\n                                 loadImage(ERROR_IMAGE_PATH)), JLabel.CENTER));\n        }\n\n        private void showProgress() {\n            final TracerProgressObject progress = controller.getProgress();\n            if (progress != null) {\n                final JProgressBar p = new JProgressBar(0, progress.getSteps());\n                p.setPreferredSize(new Dimension(120, p.getPreferredSize().height + 2));\n                p.setBorder(BorderFactory.createEmptyBorder());\n                String text = progress.getText();\n                final JLabel l = new JLabel(text == null ? \"\" : text); // NOI18N\n                l.setBorder(BorderFactory.createEmptyBorder(0, 7, 0, 0));\n                p.setValue(progress.getCurrentStep());\n                final Timer t = new Timer(INDETERMINATE_PROGRESS_THRESHOLD, null);\n                t.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        p.setIndeterminate(true);\n                        t.stop();\n                    }\n                });\n                progress.addListener(new TracerProgressObject.Listener() {\n                    public void progressChanged(int addedSteps, int currentStep, String text) {\n                        t.stop();\n                        p.setIndeterminate(false);\n                        p.setValue(currentStep);\n                        l.setText(text == null ? \"\" : text); // NOI18N\n                        if (!progress.isFinished()) t.start();\n                    }\n                });\n                JLabel s = new JLabel(\"Starting:\");\n                s.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 4));\n                JPanel container = new JPanel(new HorizontalLayout(true));\n                container.setOpaque(false);\n                container.add(s);\n                container.add(p);\n                container.add(l);\n                setSystemToolbarItem(container);\n            }\n        }\n\n        private void setSystemToolbarItem(Component c) {\n            clearSystemToolbar();\n            systemToolbar.add(c);\n            systemToolbar.revalidate();\n            systemToolbar.repaint();\n            toolbarLayout.show(toolbar, SYSTEM_TOOLBAR);\n        }\n\n        private void resetSystemToolbar() {\n            toolbarLayout.show(toolbar, CLIENT_TOOLBAR);\n            clearSystemToolbar();\n        }\n\n        private void clearSystemToolbar() {\n            while (systemToolbar.getComponentCount() > 1)\n                systemToolbar.remove(systemToolbar.getComponentCount() - 1);\n            systemToolbar.revalidate();\n            systemToolbar.repaint();\n        }\n\n\n        private void createTimelineToolbar(Dimension size) {\n            timelineToolbar = new TransparentToolBar();\n\n            JButton c1 = new JButton(timelineView.zoomInAction());\n            c1.setMinimumSize(size);\n            c1.setPreferredSize(size);\n            c1.setMaximumSize(size);\n            timelineToolbar.addItem(c1);\n\n            JButton c2 = new JButton(timelineView.zoomOutAction());\n            c2.setMinimumSize(size);\n            c2.setPreferredSize(size);\n            c2.setMaximumSize(size);\n            timelineToolbar.addItem(c2);\n\n            JButton c3 = new JButton(timelineView.toggleViewAction());\n            c3.setMinimumSize(size);\n            c3.setPreferredSize(size);\n            c3.setMaximumSize(size);\n            timelineToolbar.addItem(c3);\n\n            JPanel sp1 = new JPanel(null) {\n                public Dimension getPreferredSize() {\n                    Dimension d = super.getPreferredSize();\n                    d.width = 14;\n                    return d;\n                }\n            };\n            timelineToolbar.addItem(sp1);\n\n            ButtonGroup bg = new ButtonGroup();\n\n            AbstractButton b1 = timelineView.mouseZoom();\n            bg.add(b1);\n            b1.setMinimumSize(size);\n            b1.setPreferredSize(size);\n            b1.setMaximumSize(size);\n            timelineToolbar.addItem(b1);\n\n            AbstractButton b2 = timelineView.mouseHScroll();\n            bg.add(b2);\n            b2.setMinimumSize(size);\n            b2.setPreferredSize(size);\n            b2.setMaximumSize(size);\n            timelineToolbar.addItem(b2);\n\n            AbstractButton b3 = timelineView.mouseVScroll();\n            bg.add(b3);\n            b3.setMinimumSize(size);\n            b3.setPreferredSize(size);\n            b3.setMaximumSize(size);\n            timelineToolbar.addItem(b3);\n\n            JPanel sp2 = new JPanel(null) {\n                public Dimension getPreferredSize() {\n                    Dimension d = super.getPreferredSize();\n                    d.width = 14;\n                    return d;\n                }\n            };\n            timelineToolbar.addItem(sp2);\n\n            DropdownButton d = new DropdownButton(new ImageIcon(\n                    ImageUtilities.loadImage(SETTINGS_IMAGE_PATH)));\n            d.setToolTipText(\"Settings\");\n            Action action21 = new AbstractAction(\"Show min/max values\") {\n                public Object getValue(String key) {\n                    if (DropdownButton.KEY_BOOLVALUE.equals(key)) {\n                        putValue(DropdownButton.KEY_BOOLVALUE, model.\n                                 getTimelineSupport().isShowValuesEnabled());\n                    }\n                    return super.getValue(key);\n                }\n                public void actionPerformed(ActionEvent e) {\n                    model.getTimelineSupport().setShowValuesEnabled(!model.\n                            getTimelineSupport().isShowValuesEnabled());\n                }\n            };\n            action21.putValue(DropdownButton.KEY_CLASS, Boolean.class);\n            d.addAction(action21);\n\n            Action action22 = new AbstractAction(\"Show row legend\") {\n                public Object getValue(String key) {\n                    if (DropdownButton.KEY_BOOLVALUE.equals(key)) {\n                        putValue(DropdownButton.KEY_BOOLVALUE, model.\n                                 getTimelineSupport().isShowLegendEnabled());\n                    }\n                    return super.getValue(key);\n                }\n                public void actionPerformed(ActionEvent e) {\n                    model.getTimelineSupport().setShowLegendEnabled(!model.\n                            getTimelineSupport().isShowLegendEnabled());\n                }\n            };\n            action22.putValue(DropdownButton.KEY_CLASS, Boolean.class);\n            d.addAction(action22);\n\n            d.setMinimumSize(size);\n            d.setPreferredSize(size);\n            d.setMaximumSize(size);\n            timelineToolbar.addItem(d);\n\n            TracerOptions options = TracerOptions.getInstance();\n            int tbVis = options.getTimelineToolbar();\n            if (tbVis == TracerOptions.SHOW_NEVER)\n                timelineToolbar.setVisible(false);\n            else if (tbVis == TracerOptions.SHOW_AS_NEEDED)\n                timelineToolbar.setVisible(timelineView.isShowing());\n            \n            addClientToobarItem(timelineToolbar);\n        }\n\n        private void hideTimelineToolbar() {\n            if (timelineToolbar != null) timelineToolbar.setVisible(false);\n        }\n\n        private void showTimelineToolbar() {\n            if (timelineToolbar != null) timelineToolbar.setVisible(true);\n        }\n\n\n        private void createSelectionToolbar(Dimension size) {\n            selectionToolbar = new TransparentToolBar();\n            final TimelineSupport support = model.getTimelineSupport();\n\n            clearRowSelectionButton = new JButton(new ImageIcon(\n                    ImageUtilities.loadImage(CLPROBE_IMAGE_PATH))) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            timelineView.resetSelection();\n                        }\n                    });\n                }\n            };\n            clearRowSelectionButton.setToolTipText(\"Clear selected probes\");\n            clearRowSelectionButton.setMinimumSize(size);\n            clearRowSelectionButton.setPreferredSize(size);\n            clearRowSelectionButton.setMaximumSize(size);\n            selectionToolbar.addItem(clearRowSelectionButton);\n\n            clearTimestampSelectionButton = new JButton(new ImageIcon(\n                    ImageUtilities.loadImage(CLMARK_IMAGE_PATH))) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            support.resetSelectedTimestamps();\n                        }\n                    });\n                }\n            };\n            clearTimestampSelectionButton.setToolTipText(\"Clear marks\");\n            clearTimestampSelectionButton.setMinimumSize(size);\n            clearTimestampSelectionButton.setPreferredSize(size);\n            clearTimestampSelectionButton.setMaximumSize(size);\n            selectionToolbar.addItem(clearTimestampSelectionButton);\n\n            TracerOptions options = TracerOptions.getInstance();\n            int tbVis = options.getSelectionToolbar();\n            if (tbVis == TracerOptions.SHOW_AS_NEEDED) {\n                updateSelectionToolbar(true);\n            } else {\n                if (tbVis == TracerOptions.SHOW_NEVER)\n                    selectionToolbar.setVisible(false);\n                updateSelectionToolbar(false);\n            }\n\n            addClientToobarItem(selectionToolbar);\n        }\n\n        private void updateSelectionToolbar(boolean dynamicSelection) {\n            TimelineSupport support = model.getTimelineSupport();\n            boolean rowSelection = support.isRowSelection();\n            boolean timestampSelection = support.isTimestampSelection(false);\n            clearRowSelectionButton.setEnabled(rowSelection);\n            clearTimestampSelectionButton.setEnabled(timestampSelection);\n            if (dynamicSelection)\n                selectionToolbar.setVisible(rowSelection || timestampSelection);\n        }\n\n\n        private void createExtraToolbar(Dimension size) {\n            extraToolbar = new TransparentToolBar();\n\n            DropdownButton d = new DropdownButton(new ImageIcon(\n                    ImageUtilities.loadImage(EXPORT_IMAGE_PATH)));\n            d.setToolTipText(\"Export data\");\n            exportAllAction = new AbstractAction(\"Export all data\") {\n                public void actionPerformed(ActionEvent e) {\n                    String title = DataSourceDescriptorFactory.\n                                   getDescriptor(model.getDataSource()).getName();\n                    title = \"Exported Tracer Data for \" + title + \" at \" +\n                            new Date(System.currentTimeMillis()).toString();\n                    model.getTimelineSupport().exportAllValues(title);\n                }\n                public boolean isEnabled() {\n                    return model.getTimelineSupport().hasData();\n                }\n            };\n            d.addAction(exportAllAction);\n\n            exportDetailsAction = new AbstractAction(\"Export Details table\") {\n                public void actionPerformed(ActionEvent e) {\n                    String title = DataSourceDescriptorFactory.\n                                   getDescriptor(model.getDataSource()).getName();\n                    title = \"Exported Tracer Details for \" + title + \" at \" +\n                            new Date(System.currentTimeMillis()).toString();\n                    model.getTimelineSupport().exportDetailsValues(title);\n                }\n                public boolean isEnabled() {\n                    return detailsView.hasData();\n                }\n            };\n            d.addAction(exportDetailsAction);\n\n            d.setMinimumSize(size);\n            d.setPreferredSize(size);\n            d.setMaximumSize(size);\n            extraToolbar.addItem(d);\n\n            TracerOptions options = TracerOptions.getInstance();\n            int tbVis = options.getExtraToolbar();\n            if (tbVis == TracerOptions.SHOW_NEVER)\n                extraToolbar.setVisible(false);\n            else if (tbVis == TracerOptions.SHOW_AS_NEEDED)\n                extraToolbar.setVisible(exportAllAction.isEnabled());\n\n            addClientToobarItem(extraToolbar);\n        }\n\n        private void hideExtraToolbar() {\n            if (extraToolbar != null) extraToolbar.setVisible(false);\n        }\n\n        private void showExtraToolbar() {\n            if (extraToolbar != null) extraToolbar.setVisible(true);\n        }\n\n        private void addClientToobarItem(Component c) {\n            final SimpleSeparator s = createToolbarSeparator();\n            new VisibilityHandler() {\n                public void shown() { s.setVisible(true); }\n                public void hidden() { s.setVisible(false); }\n            }.handle(c);\n            s.setVisible(c.isShowing());\n            clientToolbar.add(s);\n            clientToolbar.add(c);\n            clientToolbar.revalidate();\n            clientToolbar.repaint();\n        }\n\n        private void removeClientToolbarItem(Component c) {\n            int index = -1;\n            for (int i = 0; i < clientToolbar.getComponentCount(); i++)\n                if (clientToolbar.getComponent(i) == c) {\n                    index = i;\n                    break;\n                }\n            if (index != -1) {\n                clientToolbar.remove(index);\n                clientToolbar.remove(index - 1); // separator\n                clientToolbar.revalidate();\n                clientToolbar.repaint();\n            }\n        }\n\n        private SimpleSeparator createToolbarSeparator() {\n            SimpleSeparator separator = new SimpleSeparator(SwingConstants.VERTICAL);\n            separator.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));\n            Dimension dim = separator.getPreferredSize();\n            dim.height = commonControlHeight;\n            separator.setPreferredSize(dim);\n            return separator;\n        }\n\n        private JComponent createComponents() {\n            final int refHeight = new TransparentToolBar().getPreferredSize().height;\n            JPanel view = new JPanel(new HorizontalLayout(true)) {\n                public Dimension getPreferredSize() {\n                    Dimension dim = super.getPreferredSize();\n                    Insets i = getInsets();\n                    dim.height = Math.max(dim.height, refHeight + i.top + i.bottom + 4);\n                    return dim;\n                }\n            };\n            view.setBorder(BorderFactory.createEmptyBorder(10, 8, 10, 8));\n            view.setOpaque(false);\n\n            startButton = new JToggleButton(\"Start\", new ImageIcon(ImageUtilities.\n                                                     loadImage(START_IMAGE_PATH))) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    RequestProcessor.getDefault().post(new Runnable() {\n                        public void run() { controller.startSession(); }\n                    });\n                }\n            };\n            startButton.setToolTipText(\"Starts new Tracer session\");\n            Insets i = startButton.getMargin();\n            i.left = Math.min(i.left, 10);\n            i.right = i.left;\n            startButton.setMargin(i);\n            view.add(startButton);\n\n            JPanel buttonGap = new JPanel(null);\n            buttonGap.setOpaque(false);\n            buttonGap.setPreferredSize(new Dimension(6, 1));\n            view.add(buttonGap);\n\n            stopButton = new JButton(\"Stop\", new ImageIcon(ImageUtilities.\n                                             loadImage(STOP_IMAGE_PATH))) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    startButton.requestFocusInWindow();\n                    RequestProcessor.getDefault().post(new Runnable() {\n                        public void run() { controller.stopSession(); }\n                    });\n                }\n            };\n            stopButton.setToolTipText(\"Stops current Tracer session\");\n            ((JButton)stopButton).setDefaultCapable(false);\n            stopButton.setMargin(i);\n            view.add(stopButton);\n\n            Dimension size1 = startButton.getPreferredSize();\n            commonControlHeight = size1.height;\n\n            Dimension size2 = stopButton.getPreferredSize();\n            commonControlHeight = Math.max(commonControlHeight, size2.height);\n\n            Action tmpAction = new AbstractAction(null, startButton.getIcon()) {\n                public void actionPerformed(ActionEvent e) {}\n            };\n            commonControlHeight = Math.max(commonControlHeight, new JToolBar().\n                                           add(tmpAction).getPreferredSize().height);\n\n            size1.height = commonControlHeight;\n            startButton.setMinimumSize(size1);\n            startButton.setPreferredSize(size1);\n            startButton.setMaximumSize(size1);\n\n            size2.height = commonControlHeight;\n            stopButton.setMinimumSize(size2);\n            stopButton.setPreferredSize(size2);\n            stopButton.setMaximumSize(size2);\n\n            toolbarLayout = new CardLayout(0, 0);\n            toolbar = new JPanel(toolbarLayout);\n            toolbar.setOpaque(false);\n\n            systemToolbar = new JPanel(new HorizontalLayout(false));\n            systemToolbar.setOpaque(false);\n            systemToolbar.add(createToolbarSeparator());\n            toolbar.add(systemToolbar, SYSTEM_TOOLBAR);\n\n            clientToolbar = new JPanel(new HorizontalLayout(false));\n            clientToolbar.setOpaque(false);\n            toolbar.add(clientToolbar, CLIENT_TOOLBAR);\n\n            toolbarLayout.show(toolbar, CLIENT_TOOLBAR);\n            view.add(toolbar);\n\n            if (TracerOptions.getInstance().isRefreshCustomizable()) {\n                JPanel refreshRateContainer = new JPanel(new HorizontalLayout(true, 4));\n                refreshRateContainer.setOpaque(false);\n\n                JLabel refreshRateLabel = new JLabel(\"Sample:\");\n                refreshRateLabel.setToolTipText(\"Tracer sampling frequency\");\n                refreshRateContainer.add(refreshRateLabel);\n\n                Integer[] refreshRates = new Integer[] { 100, 200, 500, 1000, 2000, 5000, 10000 };\n                final JComboBox refreshCombo = new JComboBox(refreshRates) {\n                    public Dimension getMinimumSize() { return getPreferredSize(); }\n                    public Dimension getMaximumSize() { return getPreferredSize(); }\n                };\n                refreshCombo.setToolTipText(\"Tracer sampling frequency\");\n                refreshCombo.setEditable(false);\n                refreshCombo.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                controller.setRefreshRate(\n                                        (Integer)refreshCombo.getSelectedItem());\n                            }\n                        });\n                    }\n                });\n                refreshCombo.setSelectedItem(Integer.valueOf(controller.getRefreshRate()));\n                refreshCombo.setRenderer(new CustomComboRenderer.Number(refreshCombo, null, false));\n                refreshRateContainer.add(refreshCombo);\n\n                JLabel refreshUnitsLabel = new JLabel(\"ms\");\n                refreshUnitsLabel.setToolTipText(\"Tracer sampling frequency\");\n                refreshRateContainer.add(refreshUnitsLabel);\n\n                addClientToobarItem(refreshRateContainer);\n            }\n\n            return view;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/TracerViewProvider.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.openide.modules.ModuleInstall;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TracerViewProvider extends ModuleInstall {\n\n    private Impl provider;\n\n\n    public synchronized void restored() {\n        if (provider == null) provider = new Impl();\n        DataSourceViewsManager.sharedInstance().addViewProvider(\n                provider, DataSource.class);\n    }\n\n    public synchronized void uninstalled() {\n        if (provider == null) return;\n        DataSourceViewsManager.sharedInstance().removeViewProvider(provider);\n        provider = null;\n    }\n\n\n    private static final class Impl extends DataSourceViewProvider<DataSource> {\n\n        protected boolean supportsViewFor(DataSource dataSource) {\n            return TracerSupportImpl.getInstance().hasPackages(dataSource);\n        }\n\n        protected DataSourceView createView(DataSource dataSource) {\n            TracerModel model = new TracerModel(dataSource);\n            TracerController controller = new TracerController(model);\n            return new TracerView(model, controller);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/details/DetailsPanel.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.details;\n\nimport org.graalvm.visualvm.modules.tracer.impl.swing.HeaderPanel;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.ScrollBar;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.TimelineSupport;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Rectangle;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.KeyListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.JScrollPane;\nimport javax.swing.JViewport;\nimport javax.swing.KeyStroke;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.Scrollable;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.event.TableColumnModelEvent;\nimport javax.swing.event.TableColumnModelListener;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.TableColumnModel;\nimport javax.swing.table.TableModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class DetailsPanel extends JPanel {\n\n    private JPanel noDataContainer;\n    private JComponent dataContainer;\n\n    private JScrollBar scrollBar;\n\n    private DetailsTable table;\n    private final TimelineSupport support;\n\n    private boolean selectionAdjusting;\n    private KeyStroke tableKeyStroke;\n\n\n    public DetailsPanel(TimelineSupport support) {\n        this.support = support;\n        initComponents();\n        initListeners();\n    }\n\n\n    public void setTableModel(TableModel model) {\n        if (model == null) {\n            table.clearSelection();\n            table.setModel(new DefaultTableModel());\n            removeAll();\n            add(noDataContainer, BorderLayout.CENTER);\n        } else {\n            int selectedRow = getSelectedRow();\n            table.setModel(model);\n            if (selectedRow != -1)\n                table.getSelectionModel().setSelectionInterval(selectedRow,\n                                                               selectedRow);\n            removeAll();\n            add(dataContainer, BorderLayout.CENTER);\n        }\n        \n        validate();\n        repaint();\n    }\n\n\n    private void initListeners() {\n        TableListener tableListener = new TableListener();\n        table.getSelectionModel().addListSelectionListener(tableListener);\n        table.addKeyListener(tableListener);\n        table.addMouseListener(tableListener);\n    }\n\n    private int getSelectedRow() {\n        int selectedRow = table.getSelectedRow();\n        return selectedRow == -1 ? -1 : table.convertRowIndexToModel(selectedRow);\n    }\n\n    private boolean isTrackingEnd() {\n        if (scrollBar == null) return false;\n        return scrollBar.getValue() + scrollBar.getVisibleAmount() >= scrollBar.getMaximum();\n    }\n\n    private boolean isSelectionChanging() {\n        if (selectionAdjusting) return true;\n        if (tableKeyStroke == null) return false;\n        return table.getActionForKeyStroke(tableKeyStroke) != null;\n    }\n\n    private void initComponents() {        \n        table = new DetailsTable();\n        table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n\n        JViewport viewport = new Viewport(table);\n\n        final JScrollPane tableScroll = new JScrollPane(\n                                            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,\n                                            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n        tableScroll.setViewport(viewport);\n        tableScroll.setBorder(BorderFactory.createEmptyBorder());\n        tableScroll.setViewportBorder(BorderFactory.createEmptyBorder());\n        tableScroll.setCorner(JScrollPane.UPPER_RIGHT_CORNER, new HeaderPanel());\n        \n        scrollBar = new ScrollBar(JScrollBar.VERTICAL) {\n            public int getUnitIncrement(int direction) {\n                JViewport vp = tableScroll.getViewport();\n                Scrollable view = (Scrollable)(vp.getView());\n                Rectangle vr = vp.getViewRect();\n                return view.getScrollableUnitIncrement(vr, getOrientation(), direction);\n            }\n            public int getBlockIncrement(int direction) {\n                JViewport vp = tableScroll.getViewport();\n                Scrollable view = (Scrollable)(vp.getView());\n                Rectangle vr = vp.getViewRect();\n                return view.getScrollableBlockIncrement(vr, getOrientation(), direction);\n            }\n            public void setValues(int newValue, int newExtent, int newMin, int newMax) {\n                setEnabled(newExtent < newMax);\n                if (isEnabled() && !isSelectionChanging() && isTrackingEnd())\n                    newValue = newMax - newExtent;\n                super.setValues(newValue, newExtent, newMin, newMax);\n            }\n        };\n        tableScroll.setVerticalScrollBar(scrollBar);\n        dataContainer = tableScroll;\n\n        JLabel noDataLabel = new JLabel(\"<No probe selected>\", JLabel.CENTER);\n        noDataLabel.setEnabled(false);\n        noDataContainer = new JPanel(new BorderLayout());\n        noDataContainer.setOpaque(false);\n        noDataContainer.add(noDataLabel, BorderLayout.CENTER);\n\n        setOpaque(false);\n        setLayout(new BorderLayout());\n        add(noDataContainer, BorderLayout.CENTER);\n    }\n\n\n    private class TableListener extends MouseAdapter implements\n                                ListSelectionListener, KeyListener {\n        public void valueChanged(ListSelectionEvent e) {\n            selectionAdjusting = e.getValueIsAdjusting();\n        }\n        public void keyPressed(KeyEvent e) {\n            tableKeyStroke = KeyStroke.getKeyStrokeForEvent(e);\n        }\n        public void keyReleased(KeyEvent e) {\n            tableKeyStroke = null;\n            if (e.getKeyCode() == KeyEvent.VK_SPACE)\n                support.scrollChartToIndex(getSelectedRow());\n        }\n        public void keyTyped(KeyEvent e) {}\n        public void mouseClicked(MouseEvent e) {\n            if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2)\n                support.scrollChartToIndex(getSelectedRow());\n        }\n    }\n\n\n    private static class Viewport extends JViewport {\n        \n        private final DetailsTable view;\n        private final Color background;\n\n        Viewport(DetailsTable view) {\n            super();\n\n            setView(view);\n            this.view = view;\n            \n            setOpaque(true);\n            background = view.getBackground();\n            setBackground(background);\n\n            view.getColumnModel().addColumnModelListener(new TableColumnModelListener() {\n                public void columnAdded(TableColumnModelEvent e) { repaint(); }\n                public void columnMoved(TableColumnModelEvent e) { repaint(); }\n                public void columnRemoved(TableColumnModelEvent e) { repaint(); }\n                public void columnMarginChanged(ChangeEvent e) { repaint(); }\n                public void columnSelectionChanged(ListSelectionEvent e) {}\n            });\n        }\n\n        protected void paintComponent(Graphics g) {\n            super.paintComponent(g);\n            paintVerticalLines(g);\n        }\n\n        private void paintVerticalLines(Graphics g) {\n            int height = getHeight();\n            int viewHeight = view.getHeight();\n            if (viewHeight >= height) return;\n\n            g.setColor(background);\n            g.fillRect(0, viewHeight, getWidth(), getHeight() - viewHeight);\n\n            int cellX = 0;\n            int cellWidth;\n            TableColumnModel model = view.getColumnModel();\n            int columnCount = model.getColumnCount();\n            \n            g.setColor(DetailsTable.DEFAULT_GRID_COLOR);\n            for (int i = 0; i < columnCount; i++) {\n                cellWidth = model.getColumn(i).getWidth();\n                cellX += cellWidth;\n                g.drawLine(cellX - 1, viewHeight, cellX - 1, height);\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/details/DetailsTable.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.details;\n\nimport org.graalvm.visualvm.modules.tracer.impl.swing.HeaderLabel;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.event.MouseEvent;\nimport javax.swing.JLabel;\nimport javax.swing.JTable;\nimport javax.swing.event.TableModelEvent;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumn;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class DetailsTable extends JTable {\n\n    private static final int DEFAULT_ROW_HEIGHT = defaultRowHeight();\n    static final Color DEFAULT_GRID_COLOR = new Color(240, 240, 240);\n\n    private TableCellRenderer markRenderer;\n    private TimestampRenderer timestampRenderer;\n\n\n    DetailsTable() {\n        setOpaque(true);\n        setBackground(UISupport.getDefaultBackground());\n        setRowHeight(DEFAULT_ROW_HEIGHT);\n        setRowMargin(0);\n        setAutoCreateRowSorter(true);\n        setShowHorizontalLines(false);\n        setShowVerticalLines(true);\n        setGridColor(DEFAULT_GRID_COLOR);\n        getTableHeader().setPreferredSize(new Dimension(1, HeaderLabel.DEFAULT_HEIGHT));\n        getColumnModel().setColumnMargin(1);\n        initRenderers();\n    }\n    \n\n    public void addColumn(TableColumn aColumn) {\n        super.addColumn(aColumn);\n        if (aColumn.getModelIndex() == 0 || aColumn.getModelIndex() == 1)\n            updateColumns(true);\n    }\n\n    public void tableChanged(TableModelEvent e) {\n        super.tableChanged(e);\n        if (e.getType() == TableModelEvent.INSERT) updateColumns(false);\n    }\n\n    protected JTableHeader createDefaultTableHeader() {\n        return new JTableHeader(columnModel) {\n            public String getToolTipText(MouseEvent e) {\n                int index = columnModel.getColumnIndexAtX(e.getPoint().x);\n                int realIndex = columnModel.getColumn(index).getModelIndex();\n                return ((DetailsTableModel)dataModel).getColumnTooltip(realIndex);\n            }\n        };\n    }\n\n\n    private void initRenderers() {\n        markRenderer = getDefaultRenderer(Boolean.class);\n        TableCellRenderer dateRenderer = getDefaultRenderer(String.class);\n        timestampRenderer = new TimestampRenderer(dateRenderer);\n        TableCellRenderer numberRenderer = getDefaultRenderer(Long.class);\n        setDefaultRenderer(Boolean.class, new MarkRenderer(markRenderer));\n        setDefaultRenderer(DetailsPanel.class, timestampRenderer);\n        setDefaultRenderer(Long.class, new ItemValueRenderer(numberRenderer));\n    }\n\n    private void updateColumns(boolean initialUpdate) {\n        if (timestampRenderer == null) return;\n\n        if (initialUpdate) {\n            Component boolRenderer = markRenderer.getTableCellRendererComponent(\n                                     DetailsTable.this, Boolean.FALSE, false,\n                                     false, 0, 0);\n            int width = boolRenderer.getPreferredSize().width;\n            TableColumn column = columnModel.getColumn(0);\n            TableCellRenderer headerRenderer = getTableHeader().getDefaultRenderer();\n            Component renderer = headerRenderer.getTableCellRendererComponent(\n                                 DetailsTable.this, column.getHeaderValue(), false,\n                                 false, 0, 0);\n            width = Math.max(width, renderer.getPreferredSize().width);\n            width += 16;\n            column.setPreferredWidth(width);\n            column.setMaxWidth(width);\n        }\n\n        if (columnModel.getColumnCount() > 1) {\n            if (!timestampRenderer.updateFormat(dataModel) && !initialUpdate) return;\n            Component renderer = timestampRenderer.getTableCellRendererComponent(\n                                 DetailsTable.this, TimestampRenderer.\n                                 REFERENCE_TIMESTAMP, false, false, 0, 1);\n            TableColumn column = columnModel.getColumn(1);\n            int width = renderer.getPreferredSize().width + 5;\n            if (initialUpdate || column.getMaxWidth() < width) {\n                column.setPreferredWidth(width);\n                column.setMaxWidth(width);\n                if (!initialUpdate) repaint();\n            }\n        }\n    }\n\n    private static int defaultRowHeight() {\n        return new JLabel(\"X\").getPreferredSize().height + 4; // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/details/DetailsTableCellRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.details;\n\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport java.awt.Color;\nimport java.awt.Component;\nimport javax.swing.JComponent;\nimport javax.swing.JTable;\nimport javax.swing.table.TableCellRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass DetailsTableCellRenderer implements TableCellRenderer {\n\n    private static final Color BACKGROUND;\n    private static final Color DARKER_BACKGROUND;\n\n    static {\n        BACKGROUND = UISupport.getDefaultBackground();\n\n        int darkerR = BACKGROUND.getRed() - 11;\n        if (darkerR < 0) darkerR += 26;\n        int darkerG = BACKGROUND.getGreen() - 11;\n        if (darkerG < 0) darkerG += 26;\n        int darkerB = BACKGROUND.getBlue() - 11;\n        if (darkerB < 0) darkerB += 26;\n        DARKER_BACKGROUND = new Color(darkerR, darkerG, darkerB);\n    }\n\n    private TableCellRenderer impl;\n\n\n    DetailsTableCellRenderer(TableCellRenderer impl) {\n        this.impl = impl;\n    }\n\n\n    protected Object formatValue(JTable table, Object value, boolean isSelected,\n                                 boolean hasFocus, int row, int column) {\n        return value;\n    }\n\n    protected void updateRenderer(Component c, JTable table, Object value,\n                                  boolean isSelected, boolean hasFocus, int row,\n                                  int column) {\n        if (!isSelected) {\n            c.setBackground(row % 2 == 0 ? DARKER_BACKGROUND : BACKGROUND);\n            // Make sure the renderer paints its background (Nimbus)\n            if (c instanceof JComponent) ((JComponent)c).setOpaque(true);\n        }\n    }\n\n    public Component getTableCellRendererComponent(JTable table, Object value,\n                                                   boolean isSelected, boolean hasFocus,\n                                                   int row, int column) {\n\n        if (impl == null) impl = table.getDefaultRenderer(table.getColumnClass(column));\n        \n        value = formatValue(table, value, isSelected, hasFocus, row, column);\n        Component c = impl.getTableCellRendererComponent(table, value, isSelected,\n                                                         hasFocus, row, column);\n        updateRenderer(c, table, value, isSelected, hasFocus, row, column);\n\n        return c;\n    }\n    \n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/details/DetailsTableModel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.details;\n\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.items.ValueItemDescriptor;\nimport javax.swing.table.AbstractTableModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class DetailsTableModel extends AbstractTableModel {\n\n    public abstract String getColumnTooltip(int columnIndex);\n\n    public abstract ValueItemDescriptor getDescriptor(int columnIndex);\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/details/ItemValueRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.details;\n\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.items.ValueItemDescriptor;\nimport javax.swing.JTable;\nimport javax.swing.table.TableCellRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ItemValueRenderer extends DetailsTableCellRenderer {\n\n    ItemValueRenderer(TableCellRenderer renderer) {\n        super(renderer);\n    }\n\n    protected Object formatValue(JTable table, Object value, boolean isSelected,\n                                 boolean hasFocus, int row, int column) {\n\n        DetailsTableModel model = (DetailsTableModel)table.getModel();\n        int columnIndex = table.convertColumnIndexToModel(column);\n        ValueItemDescriptor descriptor = model.getDescriptor(columnIndex);\n\n        String valueString = descriptor.getValueString((Long)value,\n                             ItemValueFormatter.FORMAT_DETAILS);\n        // Improve spacing of the text\n        return \" \" + valueString + \" \"; // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/details/MarkRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.details;\n\nimport java.awt.Component;\nimport javax.swing.JTable;\nimport javax.swing.table.TableCellRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class MarkRenderer extends DetailsTableCellRenderer {\n\n    MarkRenderer(TableCellRenderer renderer) {\n        super(renderer);\n    }\n\n    public Component getTableCellRendererComponent(JTable table, Object value,\n                                                   boolean isSelected, boolean hasFocus,\n                                                   int row, int column) {\n\n        // Workaround strange selection behavior for newly selected checkbox\n        isSelected = isSelected || hasFocus;\n\n        return super.getTableCellRendererComponent(table, value, isSelected,\n                                                   hasFocus, row, column);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/details/TimestampRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.details;\n\nimport java.awt.Component;\nimport java.text.Format;\nimport java.text.SimpleDateFormat;\nimport javax.swing.JLabel;\nimport javax.swing.JTable;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.lib.charts.axis.TimeAxisUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimestampRenderer extends DetailsTableCellRenderer {\n\n    // Fri Mar 19 11:59:59.999 AM 2010\n    static final long REFERENCE_TIMESTAMP = 1268996399999l;\n\n    private String formatString;\n    private Format format;\n\n    TimestampRenderer(TableCellRenderer renderer) {\n        super(renderer);\n    }\n\n    protected Object formatValue(JTable table, Object value, boolean isSelected,\n                                 boolean hasFocus, int row, int column) {\n        String valueString = format.format(value);\n        // Improve spacing of the text\n        return \" \" + valueString + \" \"; // NOI18N\n    }\n\n    protected void updateRenderer(Component c, JTable table, Object value,\n                                  boolean isSelected, boolean hasFocus, int row,\n                                  int column) {\n        super.updateRenderer(c, table, value, isSelected, hasFocus, row, column);\n        if (c instanceof JLabel) ((JLabel)c).setHorizontalAlignment(JLabel.TRAILING);\n    }\n\n    boolean updateFormat(TableModel model) {\n        int rowCount = model.getRowCount();\n\n        long first = rowCount > 0 ? (Long)model.getValueAt(0, 1) : REFERENCE_TIMESTAMP;\n        long last  = rowCount > 0 ? (Long)model.getValueAt(rowCount - 1, 1) :\n                                    REFERENCE_TIMESTAMP + 1;\n        \n        String newFormatString = TimeAxisUtils.getFormatString(1, first, last);\n        if (!newFormatString.equals(formatString)) {\n            formatString = newFormatString;\n            format = new SimpleDateFormat(formatString);\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/export/CSVExporter.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n\npackage org.graalvm.visualvm.modules.tracer.impl.export;\n\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport java.io.IOException;\nimport java.io.Writer;\nimport javax.swing.table.TableModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class CSVExporter extends Exporter {\n\n    private static final String DELIMITER = \",\"; // NOI18N\n\n    private float step = 1;\n    private int lastStep = 0;\n    \n\n    protected int getSteps(TableModel model) {\n        int steps = model.getRowCount();\n        if (steps > MAX_STEPS) {\n            step = MAX_STEPS / (float)steps;\n            steps = MAX_STEPS;\n        }\n        return steps;\n    }\n\n    protected void writeData(TableModel model, String title, Writer writer,\n                             TracerProgressObject progress) throws IOException {\n        int columnsCount = model.getColumnCount();\n        int rowsCount = model.getRowCount();\n\n        for (int c = 0; c < columnsCount; c++) {\n            write(writer, \"\\\"\" + model.getColumnName(c) + \"\\\"\"); // NOI18N\n            if (c < columnsCount - 1) write(writer, DELIMITER);\n        }\n        writeLine(writer);\n\n        for (int r = 0; r < rowsCount; r++) {\n            for (int c = 0; c < columnsCount; c++) {\n                write(writer, \"\\\"\" + model.getValueAt(r, c) + \"\\\"\"); // NOI18N\n                if (c < columnsCount - 1) write(writer, DELIMITER);\n            }\n            writeLine(writer);\n            \n            if (progress.isFinished()) break;\n            \n            if (step == 1) {\n                progress.addStep();\n            } else {\n                int currentStep = (int)(r * step);\n                if (currentStep > lastStep) {\n                    progress.addStep();\n                    lastStep = currentStep;\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/export/DataExport.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.export;\n\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport org.graalvm.visualvm.uisupport.VerticalLayout;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.OutputStreamWriter;\nimport java.io.Writer;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JDialog;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JProgressBar;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport javax.swing.filechooser.FileFilter;\nimport javax.swing.table.TableModel;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.RequestProcessor;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class DataExport {\n\n    private static final Logger LOGGER = Logger.getLogger(DataExport.class.getName());\n\n    private static final int INDETERMINATE_PROGRESS_THRESHOLD =\n                Integer.getInteger(\"visualvm.tracer.indeterminateProgressThreshold\", 2500); // NOI18N\n\n    private static final Filter CSV_FILTER  = Filter.create(\"CSV Files\", \".csv\");\n    private static final Filter HTML_FILTER = Filter.create(\"HTML Files\", \".html\");\n    private static final Filter XML_FILTER  = Filter.create(\"XML Files\", \".xml\");\n\n    private static JFileChooser fileChooser;\n    private static File lastDirectory;\n    private static Filter lastFilter = CSV_FILTER;\n\n\n    public static void exportData(final TableModel model, final String title) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                JFileChooser chooser = getFileChooser();\n                if (chooser.showSaveDialog(WindowManager.getDefault().getRegistry().\n                        getActivated()) == JFileChooser.APPROVE_OPTION) {\n                    File file = chooser.getSelectedFile();\n                    Filter filter = (Filter)chooser.getFileFilter();\n                    doExportData(model, title, file, filter);\n                }\n                lastDirectory = chooser.getCurrentDirectory();\n                lastFilter = (Filter)chooser.getFileFilter();\n            }\n        });\n    }\n\n\n    private static void doExportData(final TableModel model, final String title,\n                                     final File file, final Filter filter) {\n        \n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() {\n                Writer writer = null;\n                TracerProgressObject progress = null;\n                try {\n                    writer = new OutputStreamWriter(new FileOutputStream(file), \"UTF-8\"); // NOI18N\n                    ExportBatch batch = null;\n\n                    if (filter == XML_FILTER)\n                        batch = new XMLExporter().createBatch(model, title, writer);\n                    else if (filter == HTML_FILTER)\n                        batch = new HTMLExporter().createBatch(model, title, writer);\n                    else if (filter == CSV_FILTER)\n                        batch = new CSVExporter().createBatch(model, title, writer);\n\n                    if (batch != null) {\n                        progress = batch.getProgress();\n                        final TracerProgressObject progressF = progress;\n                        SwingUtilities.invokeAndWait(new Runnable() {\n                            public void run() { showProgressDialog(progressF); }\n                        });\n                        batch.getWorker().run();\n                    }\n                } catch (Throwable t) {\n                    if (progress != null) {\n                        progress.setText(\"Exporting data failed\");\n                        progress.finish();\n                    }\n                    LOGGER.log(Level.INFO, \"Exporting data failed\", t); // NOI18N\n                } finally {\n                    if (writer != null) try { writer.close(); } catch (Exception e) {}\n                }\n            }\n        });\n    }\n\n    private static void showProgressDialog(final TracerProgressObject progress) {\n        final JLabel l = new JLabel();\n        l.setBorder(BorderFactory.createEmptyBorder(0, 0, 7, 0));\n\n        final JProgressBar p = new JProgressBar(0, progress.getSteps()) {\n            public Dimension getPreferredSize() {\n                Dimension d = super.getPreferredSize();\n                d.width = Exporter.MAX_STEPS;\n                d.height += 2;\n                return d;\n            }\n        };\n        p.setBorder(BorderFactory.createEmptyBorder());\n        final Timer t = new Timer(INDETERMINATE_PROGRESS_THRESHOLD, null);\n        t.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                p.setIndeterminate(true);\n                t.stop();\n            }\n        });\n\n        final JButton b = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                SwingUtilities.getWindowAncestor(this).setVisible(false);\n            }\n        };\n\n        progress.addListener(new TracerProgressObject.Listener() {\n            public void progressChanged(int addedSteps, int currentStep, String text) {\n                t.stop();\n                p.setIndeterminate(false);\n                p.setValue(currentStep);\n                l.setText(text == null ? \"\" : text); // NOI18N\n                if (!progress.isFinished()) t.start();\n                else b.setText(\"Close\");\n            }\n        });\n        l.setText(progress.getText());\n        p.setValue(progress.getCurrentStep());\n        b.setText(progress.isFinished() ? \"Close\" : \"Cancel\");\n\n        JPanel c = new JPanel(new VerticalLayout(false));\n        c.setBorder(BorderFactory.createEmptyBorder(20, 10, 15, 10));\n        c.add(l);\n        c.add(p);\n\n        final DialogDescriptor dd = new DialogDescriptor(c, \"Export Tracer Data\",\n                                                        true, new Object[] { b },\n                                                        b, DialogDescriptor.BOTTOM_ALIGN,\n                                                        null, null);\n\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n                openDialog(d);\n                progress.finish();\n            }\n        });\n    }\n    \n\n    private static JFileChooser getFileChooser() {\n        if (fileChooser == null)   fileChooser = createFileChooser();\n        if (lastDirectory != null) fileChooser.setCurrentDirectory(lastDirectory);\n        if (lastFilter != null)    fileChooser.setFileFilter(lastFilter);\n        return fileChooser;\n    }\n\n    private static JFileChooser createFileChooser() {\n        JFileChooser chooser = new JFileChooser() {\n            public void approveSelection() {\n                File file = getSelectedFile();\n                Filter filter = (Filter)getFileFilter();\n\n                if (!file.getName().endsWith(filter.getExt())) {\n                    file = new File(file.getPath() + filter.getExt());\n                    setSelectedFile(file);\n                }\n\n                if (!file.isFile()) {\n                    super.approveSelection();\n                    return;\n                }\n                \n                final boolean[] ret = new boolean[1];\n                JButton yesB = new JButton(\"Yes\") {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        ret[0] = true;\n                        super.fireActionPerformed(e);\n                    }\n                };\n                DialogDescriptor desc = new DialogDescriptor(\n                    \"File \\\"\" + file.getName() + \"\\\" already exists.\\n\" +\n                    \"Do you want to replace it?\", \"Replace Existing File\",\n                    true, new Object[] { yesB, new JButton(\"No\") }, yesB,\n                    DialogDescriptor.BOTTOM_ALIGN, null, null);\n                desc.setMessageType(NotifyDescriptor.QUESTION_MESSAGE);\n                Dialog d = DialogDisplayer.getDefault().createDialog(desc);\n                openDialog(d);\n                if (ret[0] == true) super.approveSelection();\n            }\n        };\n\n        chooser.setDialogTitle(\"Export Tracer Data\");\n        chooser.setDialogType(JFileChooser.SAVE_DIALOG);\n        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);\n\n        chooser.setAcceptAllFileFilterUsed(false);\n\n        chooser.addChoosableFileFilter(CSV_FILTER);\n        chooser.addChoosableFileFilter(HTML_FILTER);\n        chooser.addChoosableFileFilter(XML_FILTER);\n\n        return chooser;\n    }\n\n    private static void openDialog(Dialog d) {\n        if (d instanceof JDialog) ((JDialog)d).setLocationRelativeTo(\n                WindowManager.getDefault().getRegistry().getActivated());\n        d.setVisible(true);\n    }\n\n    \n    private static abstract class Filter extends FileFilter {\n\n        abstract String getExt();\n\n        static Filter create(final String descr, final String ext) {\n            return new Filter() {\n                public boolean accept(File f) {\n                    return f.isDirectory() ||\n                           Utils.getFileExt(f.getName()).equals(ext);\n                }\n                public String getExt() {\n                    return ext;\n                }\n                public String getDescription() {\n                    return descr + \" (*\" + ext + \")\";\n                }\n            };\n        }\n\n        private Filter() {}\n\n    }\n\n\n    private DataExport() {}\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/export/ExportBatch.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.export;\n\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport java.io.IOException;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ExportBatch {\n    \n    private final TracerProgressObject progress;\n    private final BatchRunnable worker;\n\n    protected ExportBatch(TracerProgressObject progress, BatchRunnable worker) {\n        this.progress = progress;\n        this.worker = worker;\n    }\n\n    TracerProgressObject getProgress() { return progress; }\n    BatchRunnable getWorker() { return worker; }\n\n    static interface BatchRunnable {\n        public void run() throws IOException;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/export/Exporter.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.export;\n\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport java.io.IOException;\nimport java.io.Writer;\nimport javax.swing.table.TableModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class Exporter {\n\n    protected static final int MAX_STEPS = 300; // Defines also JProgressBar width\n\n    \n    protected abstract int getSteps(TableModel model);\n    \n    protected void writeHeader(TableModel model, String title, Writer writer,\n                               TracerProgressObject progress) throws IOException {}\n\n    protected void writeData(TableModel model, String title, Writer writer,\n                             TracerProgressObject progress) throws IOException {}\n\n    protected void writeFooter(TableModel model, String title, Writer writer,\n                               TracerProgressObject progress) throws IOException {}\n\n\n    protected static void writeLine(Writer writer) throws IOException {\n        writer.write(\"\\n\"); // NOI18N\n    }\n\n    protected static void writeLine(Writer writer, String line) throws IOException {\n        writer.write(line + \"\\n\"); // NOI18N\n    }\n\n    protected static void write(Writer writer, String text) throws IOException {\n        writer.write(text);\n    }\n\n\n    final ExportBatch createBatch(final TableModel model, final String title,\n                                  final Writer writer) {\n        \n        final TracerProgressObject progress = new TracerProgressObject(getSteps(model) + 2);\n\n        ExportBatch.BatchRunnable worker = new ExportBatch.BatchRunnable() {\n            public void run() throws IOException {\n                doExport(model, title, writer, progress);\n            }\n        };\n\n        return new ExportBatch(progress, worker);\n    }\n\n    private void doExport(TableModel model, String title, Writer writer,\n                          TracerProgressObject progress) throws IOException {\n        progress.setText(\"Initializing export...\");\n        writeHeader(model, title, writer, progress);\n\n        if (progress.isFinished()) return;\n\n        progress.addStep(\"Exporting data...\");\n        writeData(model, title, writer, progress);\n\n        if (progress.isFinished()) return;\n\n        progress.setText(\"Finishing export...\");\n        writeFooter(model, title, writer, progress);\n\n        if (progress.isFinished()) return;\n\n        progress.setText(\"Data exported\");\n        progress.finish();\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/export/HTMLExporter.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n\npackage org.graalvm.visualvm.modules.tracer.impl.export;\n\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport java.io.IOException;\nimport java.io.Writer;\nimport javax.swing.table.TableModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class HTMLExporter extends Exporter {\n\n    private float step = 1;\n    private int lastStep = 0;\n\n\n    protected int getSteps(TableModel model) {\n        int steps = model.getRowCount();\n        if (steps > MAX_STEPS) {\n            step = MAX_STEPS / (float)steps;\n            steps = MAX_STEPS;\n        }\n        return steps;\n    }\n\n    protected void writeHeader(TableModel model, String title, Writer writer,\n                               TracerProgressObject progress) throws IOException {\n        writeLine(writer, \"<!DOCTYPE HTML PUBLIC \\\"-//W3C//DTD HTML 4.01 Transitional//EN\\\" \\\"http://www.w3.org/TR/html4/loose.dtd\\\">\"); // NOI18N\n        writeLine(writer);\n\n        writeLine(writer, \"<html>\"); // NOI18N\n        writeLine(writer, \"<head>\"); // NOI18N\n        writeLine(writer, \"  <title>\"); // NOI18N\n        writeLine(writer, \"    \" + title); // NOI18N\n        writeLine(writer, \"  </title>\"); // NOI18N\n        writeLine(writer, \"</head>\"); // NOI18N\n        writeLine(writer);\n        \n        writeLine(writer, \"<body>\"); // NOI18N\n    }\n\n    protected void writeData(TableModel model, String title, Writer writer,\n                             TracerProgressObject progress) throws IOException {\n        int columnsCount = model.getColumnCount();\n        int rowsCount = model.getRowCount();\n\n        writeLine(writer, \"  <table border=\\\"1\\\" summary=\\\"\" + title + \"\\\">\"); // NOI18N\n\n        writeLine(writer, \"    <thead>\"); // NOI18N\n        writeLine(writer, \"      <tr>\"); // NOI18N\n        for (int c = 0; c < columnsCount; c++)\n            writeLine(writer, \"        <td>\" + model.getColumnName(c) + \"</td>\"); // NOI18N\n        writeLine(writer, \"      </tr>\"); // NOI18N\n        writeLine(writer, \"    </thead>\"); // NOI18N\n\n        writeLine(writer, \"    <tbody>\"); // NOI18N\n        for (int r = 0; r < rowsCount; r++) {\n            writeLine(writer, \"      <tr>\"); // NOI18N\n            for (int c = 0; c < columnsCount; c++)\n                writeLine(writer, \"        <td>\" + model.getValueAt(r, c) + \"</td>\"); // NOI18N\n            writeLine(writer, \"      </tr>\"); // NOI18N\n            \n            if (progress.isFinished()) break;\n\n            if (step == 1) {\n                progress.addStep();\n            } else {\n                int currentStep = (int)(r * step);\n                if (currentStep > lastStep) {\n                    progress.addStep();\n                    lastStep = currentStep;\n                }\n            }\n        }\n        writeLine(writer, \"    </tbody>\"); // NOI18N\n\n        writeLine(writer, \"  </table>\"); // NOI18N\n    }\n\n    protected void writeFooter(TableModel model, String title, Writer writer,\n                               TracerProgressObject progress) throws IOException {\n        writeLine(writer, \"</body>\"); // NOI18N\n        writeLine(writer, \"</html>\"); // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/export/XMLExporter.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n\npackage org.graalvm.visualvm.modules.tracer.impl.export;\n\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport java.io.IOException;\nimport java.io.Writer;\nimport javax.swing.table.TableModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class XMLExporter extends Exporter {\n\n    private float step = 1;\n    private int lastStep = 0;\n\n\n    protected int getSteps(TableModel model) {\n        int steps = model.getRowCount();\n        if (steps > MAX_STEPS) {\n            step = MAX_STEPS / (float)steps;\n            steps = MAX_STEPS;\n        }\n        return steps;\n    }\n\n    protected void writeHeader(TableModel model, String title, Writer writer,\n                               TracerProgressObject progress) throws IOException {\n        writeLine(writer, \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"); // NOI18N\n        writeLine(writer, \"<ExportedView Name=\\\"\" + title + \"\\\">\"); // NOI18N\n    }\n\n    protected void writeData(TableModel model, String title, Writer writer,\n                             TracerProgressObject progress) throws IOException {\n        int columnsCount = model.getColumnCount();\n        int rowsCount = model.getRowCount();\n\n        writeLine(writer, \"  <TableData NumRows=\\\"\" + rowsCount + // NOI18N\n                             \"\\\" NumColumns=\\\"\" + columnsCount + \"\\\">\"); // NOI18N\n\n        writeLine(writer, \"    <TableHeader>\"); // NOI18N\n        for (int c = 0; c < columnsCount; c++)\n            writeLine(writer, \"      <TableColumn>\" + model.getColumnName(c) + \"</TableColumn>\"); // NOI18N\n        writeLine(writer, \"    </TableHeader>\"); // NOI18N\n\n        writeLine(writer, \"    <TableBody>\"); // NOI18N\n        for (int r = 0; r < rowsCount; r++) {\n            writeLine(writer, \"      <TableRow>\"); // NOI18N\n            for (int c = 0; c < columnsCount; c++)\n                writeLine(writer, \"        <TableColumn>\" + model.getValueAt(r, c) + \"</TableColumn>\"); // NOI18N\n            writeLine(writer, \"      </TableRow>\"); // NOI18N\n            \n            if (progress.isFinished()) break;\n\n            if (step == 1) {\n                progress.addStep();\n            } else {\n                int currentStep = (int)(r * step);\n                if (currentStep > lastStep) {\n                    progress.addStep();\n                    lastStep = currentStep;\n                }\n            }\n        }\n        writeLine(writer, \"    </TableBody>\"); // NOI18N\n\n        writeLine(writer, \"  </TableData>\"); // NOI18N\n    }\n\n    protected void writeFooter(TableModel model, String title, Writer writer,\n                               TracerProgressObject progress) throws IOException {\n        writeLine(writer, \"</ExportedView>\"); // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/options/TracerOptions.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.options;\n\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport java.util.prefs.Preferences;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class TracerOptions {\n\n    private static final String PROP_PROBES_APP = \"TracerOptions.probesApp\"; // NOI18N\n    public static final int KEY_PROBES_FIRSTEXP = 0;\n    public static final int KEY_PROBES_ALLEXP = 1;\n    public static final int KEY_PROBES_ALLCOLL = 2;\n    private static final int PROBES_APP_DEFAULT = KEY_PROBES_FIRSTEXP;\n\n    private static final String PROP_REFRESH_RATE = \"TracerOptions.refreshRate\"; // NOI18N\n    private static final String PROP_REFRESH_CUSTOMIZABLE = \"TracerOptions.refreshCustomizable\"; // NOI18N\n\n    private static final String PROP_SHOW_VALUES = \"TracerOptions.showValues\"; // NOI18N\n    private static final String PROP_SHOW_LEGEND = \"TracerOptions.showLegend\"; // NOI18N\n    private static final String PROP_ROWS_DECORATION = \"TracerOptions.rowsDecoration\"; // NOI18N\n    private static final String PROP_ROWS_SELECTION = \"TracerOptions.rowsSelection\"; // NOI18N\n\n    private static final String PROP_INITIALLY_OPEN = \"TracerOptions.initiallyOpen\"; // NOI18N\n    private static final String PROP_PROBE_ADDED = \"TracerOptions.probeAdded\"; // NOI18N\n    private static final String PROP_PROBE_ADDED2 = \"TracerOptions.probeAdded2\"; // NOI18N\n    private static final String PROP_SESSION_STARTED = \"TracerOptions.sessionStarted\"; // NOI18N\n    private static final String PROP_ROW_SELECTED = \"TracerOptions.rowSelected\"; // NOI18N\n    private static final String PROP_ROW_SELECTED2 = \"TracerOptions.rowSelected2\"; // NOI18N\n    public static final String VIEWS_UNCHANGED = \"\"; // NOI18N\n    public static final String VIEW_PROBES = \"KEY_probes\"; // NOI18N\n    public static final String VIEW_TIMELINE = \"KEY_timeline\"; // NOI18N\n    public static final String VIEW_SETTINGS = \"KEY_settings\"; // NOI18N\n    public static final String VIEW_DETAILS = \"KEY_details\"; // NOI18N\n    static final String INITIALLY_OPEN_DEFAULT = VIEW_PROBES;\n    static final String PROBE_ADDED_DEFAULT = INITIALLY_OPEN_DEFAULT + \",\" + VIEW_TIMELINE; // NOI18N\n    static final String PROBE_ADDED_DEFAULT2 = INITIALLY_OPEN_DEFAULT;\n    static final String SESSION_STARTED_DEFAULT = VIEW_TIMELINE;\n    static final String ROW_SELECTED_DEFAULT = SESSION_STARTED_DEFAULT + \",\" + VIEW_DETAILS; // NOI18N\n    static final String ROW_SELECTED_DEFAULT2 = SESSION_STARTED_DEFAULT;\n\n    private static final String PROP_CLEAR_SELECTION = \"TracerOptions.clearSelection\"; // NOI18N\n\n    private static final String PROP_ZOOM_MODE = \"TracerOptions.zoomMode\"; // NOI18N\n    private static final String KEY_FIXED_SCALE = \"KEY_fixedScale\"; // NOI18N\n    private static final String KEY_SCALE_TO_FIT = \"KEY_scaleToFit\"; // NOI18N\n    public static final String FIXED_SCALE = \"fixed scale\";\n    public static final String SCALE_TO_FIT = \"scale to fit\";\n\n    private static final String PROP_MOUSE_WHEEL_ACTION = \"TracerOptions.mouseWheelAction\"; // NOI18N\n    private static final String KEY_MOUSE_WHEEL_ZOOMS = \"KEY_mouseWheelZooms\"; // NOI18N\n    private static final String KEY_MOUSE_WHEEL_HSCROLLS = \"KEY_mouseWheelHScrolls\"; // NOI18N\n    private static final String KEY_MOUSE_WHEEL_VSCROLLS = \"KEY_mouseWheelVScrolls\"; // NOI18N\n    public static final String MOUSE_WHEEL_ZOOMS = \"zoom\";\n    public static final String MOUSE_WHEEL_HSCROLLS = \"horizontal scroll\";\n    public static final String MOUSE_WHEEL_VSCROLLS = \"vertical scroll\";\n\n    private static final String PROP_TIMELINE_TOOLBAR = \"TracerOptions.timelineToolbar\"; // NOI18N\n    private static final String PROP_SELECTION_TOOLBAR = \"TracerOptions.selectionToolbar\"; // NOI18N\n    private static final String PROP_EXTRA_TOOLBAR = \"TracerOptions.extraToolbar\"; // NOI18N\n    public static final int SHOW_ALWAYS = 0;\n    public static final int SHOW_AS_NEEDED = 1;\n    public static final int SHOW_NEVER = 2;\n    private static final int TIMELINE_TOOLBAR_DEFAULT = SHOW_AS_NEEDED;\n    private static final int SELECTION_TOOLBAR_DEFAULT = SHOW_AS_NEEDED;\n    private static final int EXTRA_TOOLBAR_DEFAULT = SHOW_AS_NEEDED;\n\n\n\n    private static TracerOptions INSTANCE;\n\n    private final Preferences prefs;\n\n\n    public static synchronized TracerOptions getInstance() {\n        if (INSTANCE == null) INSTANCE = new TracerOptions();\n        return INSTANCE;\n    }\n\n\n    void setProbesApp(int probesApp) {\n        prefs.putInt(PROP_PROBES_APP, probesApp);\n    }\n\n    public int getProbesApp() {\n        return prefs.getInt(PROP_PROBES_APP, PROBES_APP_DEFAULT);\n    }\n\n    void setRefresh(int refreshRate) {\n        prefs.putInt(PROP_REFRESH_RATE, refreshRate);\n    }\n\n    int getRefresh() {\n        return prefs.getInt(PROP_REFRESH_RATE, -1);\n    }\n\n    public int getRefreshRate() {\n        int refresh = getRefresh();\n        return refresh != -1 ? refresh :\n               GlobalPreferences.sharedInstance().getMonitoredDataPoll() * 1000;\n    }\n\n    void setRefreshCustomizable(boolean customizable) {\n        prefs.putBoolean(PROP_REFRESH_CUSTOMIZABLE, customizable);\n    }\n\n    public boolean isRefreshCustomizable() {\n        return prefs.getBoolean(PROP_REFRESH_CUSTOMIZABLE, false);\n    }\n\n    void setShowValuesEnabled(boolean showValuesEnabled) {\n        prefs.putBoolean(PROP_SHOW_VALUES, showValuesEnabled);\n    }\n\n    public boolean isShowValuesEnabled() {\n        return prefs.getBoolean(PROP_SHOW_VALUES, true);\n    }\n\n    void setShowLegendEnabled(boolean showLegendEnabled) {\n        prefs.putBoolean(PROP_SHOW_LEGEND, showLegendEnabled);\n    }\n\n    public boolean isShowLegendEnabled() {\n        return prefs.getBoolean(PROP_SHOW_LEGEND, true); // Default 'false' might be better\n    }\n\n    void setRowsDecorationEnabled(boolean rowsDecorationEnabled) {\n        if (Utils.forceSpeed()) return;\n        prefs.putBoolean(PROP_ROWS_DECORATION, rowsDecorationEnabled);\n    }\n\n    public boolean isRowsDecorationEnabled() {\n        if (Utils.forceSpeed()) return false;\n        return prefs.getBoolean(PROP_ROWS_DECORATION, !Utils.forceSpeed());\n    }\n\n    void setRowsSelectionEnabled(boolean rowsSelectionEnabled) {\n        prefs.putBoolean(PROP_ROWS_SELECTION, rowsSelectionEnabled);\n    }\n\n    public boolean isRowsSelectionEnabled() {\n        return prefs.getBoolean(PROP_ROWS_SELECTION, !Utils.forceSpeed());\n    }\n\n    void setInitiallyOpened(String opened) {\n        prefs.put(PROP_INITIALLY_OPEN, opened);\n    }\n\n    public String getInitiallyOpened() {\n        return prefs.get(PROP_INITIALLY_OPEN, INITIALLY_OPEN_DEFAULT);\n    }\n\n    void setOnProbeAdded(String opened) {\n        prefs.put(PROP_PROBE_ADDED, opened);\n    }\n\n    public String getOnProbeAdded() {\n        return prefs.get(PROP_PROBE_ADDED, PROBE_ADDED_DEFAULT);\n    }\n\n    void setOnProbeAdded2(String opened) {\n        prefs.put(PROP_PROBE_ADDED2, opened);\n    }\n\n    public String getOnProbeAdded2() {\n        return prefs.get(PROP_PROBE_ADDED2, PROBE_ADDED_DEFAULT2);\n    }\n\n    void setOnSessionStart(String opened) {\n        prefs.put(PROP_SESSION_STARTED, opened);\n    }\n\n    public String getOnSessionStart() {\n        return prefs.get(PROP_SESSION_STARTED, SESSION_STARTED_DEFAULT);\n    }\n\n     void setOnRowSelected(String opened) {\n        prefs.put(PROP_ROW_SELECTED, opened);\n    }\n\n    public String getOnRowSelected() {\n        return prefs.get(PROP_ROW_SELECTED, ROW_SELECTED_DEFAULT);\n    }\n\n    void setOnRowSelected2(String opened) {\n        prefs.put(PROP_ROW_SELECTED2, opened);\n    }\n\n    public String getOnRowSelected2() {\n        return prefs.get(PROP_ROW_SELECTED2, ROW_SELECTED_DEFAULT2);\n    }\n\n    void setZoomMode(String zoomMode) {\n        if (SCALE_TO_FIT.equals(zoomMode))\n            prefs.put(PROP_ZOOM_MODE, KEY_SCALE_TO_FIT);\n        else\n            prefs.put(PROP_ZOOM_MODE, KEY_FIXED_SCALE);\n    }\n\n    public String getZoomMode() {\n        String zoomMode = prefs.get(PROP_ZOOM_MODE, KEY_FIXED_SCALE);\n        if (KEY_SCALE_TO_FIT.equals(zoomMode)) return SCALE_TO_FIT;\n        return FIXED_SCALE;\n    }\n\n    void setMouseWheelAction(String mouseWheelAction) {\n        if (MOUSE_WHEEL_HSCROLLS.equals(mouseWheelAction))\n            prefs.put(PROP_MOUSE_WHEEL_ACTION, KEY_MOUSE_WHEEL_HSCROLLS);\n        else if (MOUSE_WHEEL_VSCROLLS.equals(mouseWheelAction))\n            prefs.put(PROP_MOUSE_WHEEL_ACTION, KEY_MOUSE_WHEEL_VSCROLLS);\n        else\n            prefs.put(PROP_MOUSE_WHEEL_ACTION, KEY_MOUSE_WHEEL_ZOOMS);\n    }\n\n    public String getMouseWheelAction() {\n        String mouseWheelAction = prefs.get(PROP_MOUSE_WHEEL_ACTION, KEY_MOUSE_WHEEL_ZOOMS);\n        if (KEY_MOUSE_WHEEL_HSCROLLS.equals(mouseWheelAction)) return MOUSE_WHEEL_HSCROLLS;\n        else if (KEY_MOUSE_WHEEL_VSCROLLS.equals(mouseWheelAction)) return MOUSE_WHEEL_VSCROLLS;\n        return MOUSE_WHEEL_ZOOMS;\n    }\n\n    void setTimelineToolbar(int visible) {\n        prefs.putInt(PROP_TIMELINE_TOOLBAR, visible);\n    }\n\n    public int getTimelineToolbar() {\n        return prefs.getInt(PROP_TIMELINE_TOOLBAR, TIMELINE_TOOLBAR_DEFAULT);\n    }\n\n    void setSelectionToolbar(int visible) {\n        prefs.putInt(PROP_SELECTION_TOOLBAR, visible);\n    }\n\n    public int getSelectionToolbar() {\n        return prefs.getInt(PROP_SELECTION_TOOLBAR, SELECTION_TOOLBAR_DEFAULT);\n    }\n\n    void setExtraToolbar(int visible) {\n        prefs.putInt(PROP_EXTRA_TOOLBAR, visible);\n    }\n\n    public int getExtraToolbar() {\n        return prefs.getInt(PROP_EXTRA_TOOLBAR, EXTRA_TOOLBAR_DEFAULT);\n    }\n\n    void setClearSelection(boolean clear) {\n        prefs.putBoolean(PROP_CLEAR_SELECTION, clear);\n    }\n\n    public boolean isClearSelection() {\n        return prefs.getBoolean(PROP_CLEAR_SELECTION, true);\n    }\n\n\n    private TracerOptions() {\n        prefs = NbPreferences.forModule(TracerOptions.class);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/options/TracerOptionsPanel.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.options;\n\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.CustomComboRenderer;\nimport org.graalvm.visualvm.uisupport.VerticalLayout;\nimport java.awt.BorderLayout;\nimport java.awt.CardLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.GridLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.AbstractButton;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultListModel;\nimport javax.swing.DefaultListSelectionModel;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComboBox;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.ListCellRenderer;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.border.Border;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TracerOptionsPanel extends JPanel {\n\n    private final TracerOptionsPanelController controller;\n    private boolean internalChange;\n\n\n    TracerOptionsPanel(TracerOptionsPanelController controller) {\n        this.controller = controller;\n        initComponents();\n    }\n\n\n    boolean dataValid() {\n        return true;\n    }\n\n\n    void setProbesApp(int probesApp) {\n        internalChange = true;\n        probesDefaultsCombo.setSelectedIndex(probesApp);\n        internalChange = false;\n    }\n\n    int getProbesApp() {\n        return probesDefaultsCombo.getSelectedIndex();\n    }\n\n    void setRefresh(int refresh) {\n        internalChange = true;\n        refreshCombo.setSelectedItem(refresh);\n        internalChange = false;\n    }\n\n    int getRefresh() {\n        return (Integer)refreshCombo.getSelectedItem();\n    }\n\n    void setRefreshCustomizable(boolean customizable) {\n        refreshCheckBox.setSelected(customizable);\n    }\n\n    boolean isRefreshCustomizable() {\n        return refreshCheckBox.isSelected();\n    }\n\n    void setShowValuesEnabled(boolean showValuesEnabled) {\n        internalChange = true;\n        minMaxValsCombo.setSelectedItem(showValuesEnabled);\n        internalChange = false;\n    }\n\n    boolean isShowValuesEnabled() {\n        return (Boolean)minMaxValsCombo.getSelectedItem();\n    }\n\n    void setShowLegendEnabled(boolean showLegendEnabled) {\n        internalChange = true;\n        rowLegendCombo.setSelectedItem(showLegendEnabled);\n        internalChange = false;\n    }\n\n    boolean isShowLegendEnabled() {\n        return (Boolean)rowLegendCombo.getSelectedItem();\n    }\n\n    void setRowsDecorationEnabled(boolean rowsDecorationEnabled) {\n        internalChange = true;\n        rowsDecorationCombo.setSelectedItem(rowsDecorationEnabled);\n        internalChange = false;\n    }\n\n    boolean isRowsDecorationEnabled() {\n        return (Boolean)rowsDecorationCombo.getSelectedItem();\n    }\n\n    void setRowsSelectionEnabled(boolean rowsSelectionEnabled) {\n        internalChange = true;\n        rowsSelectionCombo.setSelectedIndex(rowsSelectionEnabled ? 0 : 1);\n        internalChange = false;\n    }\n\n    boolean isRowsSelectionEnabled() {\n        return rowsSelectionCombo.getSelectedIndex() == 0;\n    }\n\n    void setTimelineToolbar(int visible) {\n        internalChange = true;\n        timelineToolbarCombo.setSelectedIndex(visible);\n        internalChange = false;\n    }\n\n    int getTimelineToolbar() {\n        return timelineToolbarCombo.getSelectedIndex();\n    }\n\n    void setSelectionToolbar(int visible) {\n        internalChange = true;\n        selectionToolbarCombo.setSelectedIndex(visible);\n        internalChange = false;\n    }\n\n    int getSelectionToolbar() {\n        return selectionToolbarCombo.getSelectedIndex();\n    }\n\n    void setExtraToolbar(int visible) {\n        internalChange = true;\n        extraToolbarCombo.setSelectedIndex(visible);\n        internalChange = false;\n    }\n\n    int getExtraToolbar() {\n        return extraToolbarCombo.getSelectedIndex();\n    }\n\n    void setInitiallyOpened(String opened) {\n        internalChange = true;\n        initialProbesCheckBox.setSelected(\n                opened.contains(TracerOptions.VIEW_PROBES));\n        initialTimelineCheckBox.setSelected(\n                opened.contains(TracerOptions.VIEW_TIMELINE));\n        initialDetailsCheckBox.setSelected(\n                opened.contains(TracerOptions.VIEW_DETAILS));\n        internalChange = false;\n    }\n\n    String getInitiallyOpened() {\n        String result = TracerOptions.VIEWS_UNCHANGED;\n        result = append(result, TracerOptions.VIEW_PROBES,\n               initialProbesCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_TIMELINE,\n               initialTimelineCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_DETAILS,\n               initialDetailsCheckBox.isSelected());\n        return result;\n    }\n\n    void setOnProbeAdded(String opened) {\n        internalChange = true;\n        if (TracerOptions.VIEWS_UNCHANGED.equals(opened)) {\n            onProbeAddedProbesCheckBox.setSelected(false);\n            onProbeAddedTimelineCheckBox.setSelected(false);\n            onProbeAddedDetailsCheckBox.setSelected(false);\n            onProbeAddedNothingCheckBox.setSelected(true);\n        } else {\n            onProbeAddedProbesCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_PROBES));\n            onProbeAddedTimelineCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_TIMELINE));\n            onProbeAddedDetailsCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_DETAILS));\n            onProbeAddedNothingCheckBox.setSelected(false);\n        }\n        internalChange = false;\n    }\n\n    String getOnProbeAdded() {\n        String result = TracerOptions.VIEWS_UNCHANGED;\n        result = append(result, TracerOptions.VIEW_PROBES,\n               onProbeAddedProbesCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_TIMELINE,\n               onProbeAddedTimelineCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_DETAILS,\n               onProbeAddedDetailsCheckBox.isSelected());\n        return result;\n    }\n\n    void setOnProbeAdded2(String opened) {\n        internalChange = true;\n        if (TracerOptions.VIEWS_UNCHANGED.equals(opened)) {\n            onProbeAddedProbesCheckBox2.setSelected(false);\n            onProbeAddedTimelineCheckBox2.setSelected(false);\n            onProbeAddedDetailsCheckBox2.setSelected(false);\n            onProbeAddedNothingCheckBox2.setSelected(true);\n        } else {\n            onProbeAddedProbesCheckBox2.setSelected(\n                    opened.contains(TracerOptions.VIEW_PROBES));\n            onProbeAddedTimelineCheckBox2.setSelected(\n                    opened.contains(TracerOptions.VIEW_TIMELINE));\n            onProbeAddedDetailsCheckBox2.setSelected(\n                    opened.contains(TracerOptions.VIEW_DETAILS));\n            onProbeAddedNothingCheckBox2.setSelected(false);\n        }\n        internalChange = false;\n    }\n\n    String getOnProbeAdded2() {\n        String result = TracerOptions.VIEWS_UNCHANGED;\n        result = append(result, TracerOptions.VIEW_PROBES,\n               onProbeAddedProbesCheckBox2.isSelected());\n        result = append(result, TracerOptions.VIEW_TIMELINE,\n               onProbeAddedTimelineCheckBox2.isSelected());\n        result = append(result, TracerOptions.VIEW_DETAILS,\n               onProbeAddedDetailsCheckBox2.isSelected());\n        return result;\n    }\n\n    void setOnSessionStart(String opened) {\n        internalChange = true;\n        if (TracerOptions.VIEWS_UNCHANGED.equals(opened)) {\n            onStartProbesCheckBox.setSelected(false);\n            onStartTimelineCheckBox.setSelected(false);\n            onStartDetailsCheckBox.setSelected(false);\n            onStartNothingCheckBox.setSelected(true);\n        } else {\n            onStartProbesCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_PROBES));\n            onStartTimelineCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_TIMELINE));\n            onStartDetailsCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_DETAILS));\n            onStartNothingCheckBox.setSelected(false);\n        }\n        internalChange = false;\n    }\n\n    String getOnSessionStart() {\n        String result = TracerOptions.VIEWS_UNCHANGED;\n        result = append(result, TracerOptions.VIEW_PROBES,\n               onStartProbesCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_TIMELINE,\n               onStartTimelineCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_DETAILS,\n               onStartDetailsCheckBox.isSelected());\n        return result;\n    }\n\n    void setOnRowSelected(String opened) {\n        internalChange = true;\n        if (TracerOptions.VIEWS_UNCHANGED.equals(opened)) {\n            onRowSelectedProbesCheckBox.setSelected(false);\n            onRowSelectedTimelineCheckBox.setSelected(false);\n            onRowSelectedDetailsCheckBox.setSelected(false);\n            onRowSelectedNothingCheckBox.setSelected(true);\n        } else {\n            onRowSelectedProbesCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_PROBES));\n            onRowSelectedTimelineCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_TIMELINE));\n            onRowSelectedDetailsCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_DETAILS));\n            onRowSelectedNothingCheckBox.setSelected(false);\n        }\n        internalChange = false;\n    }\n\n    String getOnRowSelected() {\n        String result = TracerOptions.VIEWS_UNCHANGED;\n        result = append(result, TracerOptions.VIEW_PROBES,\n               onRowSelectedProbesCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_TIMELINE,\n               onRowSelectedTimelineCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_DETAILS,\n               onRowSelectedDetailsCheckBox.isSelected());\n        return result;\n    }\n\n    void setOnRowSelected2(String opened) {\n        internalChange = true;\n        if (TracerOptions.VIEWS_UNCHANGED.equals(opened)) {\n            onRowSelectedProbesCheckBox2.setSelected(false);\n            onRowSelectedTimelineCheckBox2.setSelected(false);\n            onRowSelectedDetailsCheckBox2.setSelected(false);\n            onRowSelectedNothingCheckBox2.setSelected(true);\n        } else {\n            onRowSelectedProbesCheckBox2.setSelected(\n                    opened.contains(TracerOptions.VIEW_PROBES));\n            onRowSelectedTimelineCheckBox2.setSelected(\n                    opened.contains(TracerOptions.VIEW_TIMELINE));\n            onRowSelectedDetailsCheckBox2.setSelected(\n                    opened.contains(TracerOptions.VIEW_DETAILS));\n            onRowSelectedNothingCheckBox2.setSelected(false);\n        }\n        internalChange = false;\n    }\n\n    String getOnRowSelected2() {\n        String result = TracerOptions.VIEWS_UNCHANGED;\n        result = append(result, TracerOptions.VIEW_PROBES,\n               onRowSelectedProbesCheckBox2.isSelected());\n        result = append(result, TracerOptions.VIEW_TIMELINE,\n               onRowSelectedTimelineCheckBox2.isSelected());\n        result = append(result, TracerOptions.VIEW_DETAILS,\n               onRowSelectedDetailsCheckBox2.isSelected());\n        return result;\n    }\n\n    void setZoomMode(String zoomMode) {\n        internalChange = true;\n        zoomModeCombo.setSelectedIndex(0); // fallback for invalid zoomMode\n        zoomModeCombo.setSelectedItem(zoomMode);\n        internalChange = false;\n    }\n\n    String getZoomMode() {\n        return zoomModeCombo.getSelectedItem().toString();\n    }\n\n    void setMouseWheelAction(String action) {\n        internalChange = true;\n        mouseWheelCombo.setSelectedIndex(0); // fallback for invalid action\n        mouseWheelCombo.setSelectedItem(action);\n        internalChange = false;\n    }\n\n    String getMouseWheelAction() {\n        return mouseWheelCombo.getSelectedItem().toString();\n    }\n    \n    void setClearSelection(boolean clear) {\n        clearSelectionsCheckBox.setSelected(clear);\n    }\n\n    boolean isClearSelection() {\n        return clearSelectionsCheckBox.isSelected();\n    }\n\n\n    private String append(String result, String item, boolean append) {\n        if (!append) return result;\n        if (result.length() == 0) return result += item;\n        else return result += \",\" + item; // NOI18N\n    }\n\n    void update() {\n        if (internalChange) return;\n\n        // --- refreshInterval -------------------------------------------------\n        if (refreshCombo.getSelectedIndex() == 0) {\n            refreshCheckBox.setSelected(false);\n            refreshCheckBox.setEnabled(false);\n        } else {\n            refreshCheckBox.setEnabled(true);\n        }\n\n        // --- rowsDecoration --------------------------------------------------\n        if (Utils.forceSpeed()) {\n            rowsDecorationCombo.setSelectedItem(Boolean.FALSE);\n            rowsDecorationCombo.setEnabled(false);\n        }\n\n        // --- initiallyOpened -------------------------------------------------\n        List selected = getSelected(initiallyOpenedPanel);\n\n        if (selected.isEmpty()) {\n            // Fallback to defaults\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    setInitiallyOpened(TracerOptions.INITIALLY_OPEN_DEFAULT);\n                    update();\n                }\n            });\n        } else {\n            initialProbesCheckBox.setEnabled(selected.size() > 1 ||\n                    !selected.contains(initialProbesCheckBox));\n            initialTimelineCheckBox.setEnabled(selected.size() > 1 ||\n                    !selected.contains(initialTimelineCheckBox));\n            initialDetailsCheckBox.setEnabled(selected.size() > 1 ||\n                    !selected.contains(initialDetailsCheckBox));\n        }\n\n        // --- onProbeAdded ----------------------------------------------------\n        if (onProbeAddedNothingCheckBox.isSelected()) {\n            onProbeAddedProbesCheckBox.setSelected(false);\n            onProbeAddedProbesCheckBox.setEnabled(false);\n            onProbeAddedTimelineCheckBox.setSelected(false);\n            onProbeAddedTimelineCheckBox.setEnabled(false);\n            onProbeAddedDetailsCheckBox.setSelected(false);\n            onProbeAddedDetailsCheckBox.setEnabled(false);\n        } else {\n            selected = getSelected(onProbeAddedPanel);\n\n            if (selected.isEmpty()) {\n                // Fallback to defaults\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setOnProbeAdded(TracerOptions.PROBE_ADDED_DEFAULT);\n                        update();\n                    }\n                });\n            } else {\n                onProbeAddedProbesCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onProbeAddedProbesCheckBox));\n                onProbeAddedTimelineCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onProbeAddedTimelineCheckBox));\n                onProbeAddedDetailsCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onProbeAddedDetailsCheckBox));\n            }\n        }\n\n        if (onProbeAddedNothingCheckBox2.isSelected()) {\n            onProbeAddedProbesCheckBox2.setSelected(false);\n            onProbeAddedProbesCheckBox2.setEnabled(false);\n            onProbeAddedTimelineCheckBox2.setSelected(false);\n            onProbeAddedTimelineCheckBox2.setEnabled(false);\n            onProbeAddedDetailsCheckBox2.setSelected(false);\n            onProbeAddedDetailsCheckBox2.setEnabled(false);\n        } else {\n            selected = getSelected(onProbeAddedPanel2);\n\n            if (selected.isEmpty()) {\n                // Fallback to defaults\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setOnProbeAdded2(TracerOptions.PROBE_ADDED_DEFAULT2);\n                        update();\n                    }\n                });\n            } else {\n                onProbeAddedProbesCheckBox2.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onProbeAddedProbesCheckBox2));\n                onProbeAddedTimelineCheckBox2.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onProbeAddedTimelineCheckBox2));\n                onProbeAddedDetailsCheckBox2.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onProbeAddedDetailsCheckBox2));\n            }\n        }\n\n        // --- onStart ---------------------------------------------------------\n        if (onStartNothingCheckBox.isSelected()) {\n            onStartProbesCheckBox.setSelected(false);\n            onStartProbesCheckBox.setEnabled(false);\n            onStartTimelineCheckBox.setSelected(false);\n            onStartTimelineCheckBox.setEnabled(false);\n            onStartDetailsCheckBox.setSelected(false);\n            onStartDetailsCheckBox.setEnabled(false);\n        } else {\n            selected = getSelected(onStartOpenedPanel);\n\n            if (selected.isEmpty()) {\n                // Fallback to defaults\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setOnSessionStart(TracerOptions.SESSION_STARTED_DEFAULT);\n                        update();\n                    }\n                });\n            } else {\n                onStartProbesCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onStartProbesCheckBox));\n                onStartTimelineCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onStartTimelineCheckBox));\n                onStartDetailsCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onStartDetailsCheckBox));\n            }\n        }\n\n        // --- onRowSelected ---------------------------------------------------\n        if (onRowSelectedNothingCheckBox.isSelected()) {\n            onRowSelectedProbesCheckBox.setSelected(false);\n            onRowSelectedProbesCheckBox.setEnabled(false);\n            onRowSelectedTimelineCheckBox.setSelected(false);\n            onRowSelectedTimelineCheckBox.setEnabled(false);\n            onRowSelectedDetailsCheckBox.setSelected(false);\n            onRowSelectedDetailsCheckBox.setEnabled(false);\n        } else {\n            selected = getSelected(onRowSelectedPanel);\n\n            if (selected.isEmpty()) {\n                // Fallback to defaults\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setOnRowSelected(TracerOptions.ROW_SELECTED_DEFAULT);\n                        update();\n                    }\n                });\n            } else {\n                onRowSelectedProbesCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onRowSelectedProbesCheckBox));\n                onRowSelectedTimelineCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onRowSelectedTimelineCheckBox));\n                onRowSelectedDetailsCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onRowSelectedDetailsCheckBox));\n            }\n        }\n\n        if (onRowSelectedNothingCheckBox2.isSelected()) {\n            onRowSelectedProbesCheckBox2.setSelected(false);\n            onRowSelectedProbesCheckBox2.setEnabled(false);\n            onRowSelectedTimelineCheckBox2.setSelected(false);\n            onRowSelectedTimelineCheckBox2.setEnabled(false);\n            onRowSelectedDetailsCheckBox2.setSelected(false);\n            onRowSelectedDetailsCheckBox2.setEnabled(false);\n        } else {\n            selected = getSelected(onRowSelectedPanel2);\n\n            if (selected.isEmpty()) {\n                // Fallback to defaults\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setOnRowSelected2(TracerOptions.ROW_SELECTED_DEFAULT2);\n                        update();\n                    }\n                });\n            } else {\n                onRowSelectedProbesCheckBox2.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onRowSelectedProbesCheckBox2));\n                onRowSelectedTimelineCheckBox2.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onRowSelectedTimelineCheckBox2));\n                onRowSelectedDetailsCheckBox2.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onRowSelectedDetailsCheckBox2));\n            }\n        }\n\n        controller.changed();\n    }\n\n    private List<AbstractButton> getSelected(JPanel container) {\n        List<AbstractButton> selected = new ArrayList();\n        for (Component c : container.getComponents())\n            if (c instanceof AbstractButton && ((AbstractButton)c).isSelected())\n                selected.add((AbstractButton)c);\n        return selected;\n    }\n\n\n    private void initComponents() {\n        setLayout(new GridBagLayout());\n\n        GridBagConstraints c;\n\n        // probesDefaultsSeparator\n        SectionSeparator probesDefaultsSeparator =\n                UISupport.createSectionSeparator(\"Probes Settings\"); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 0;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 5, 0);\n        add(probesDefaultsSeparator, c);\n\n        JLabel probesDefaultsLabel = new JLabel(\"Initial appearance:\");\n        c.gridx = 0;\n        c.gridy = 1;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(probesDefaultsLabel, c);\n\n        // probesDefaultsCombo\n        probesDefaultsCombo = new JComboBox(new String[] { \"first expanded\",\n                                                           \"all expanded\",\n                                                           \"all collapsed\" }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        probesDefaultsLabel.setLabelFor(probesDefaultsCombo);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 1;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(probesDefaultsCombo, c);\n\n        // timelineDefaultsSeparator\n        SectionSeparator timelineDefaultsSeparator =\n                UISupport.createSectionSeparator(\"Timeline Settings\"); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 2;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(15, 0, 5, 0);\n        add(timelineDefaultsSeparator, c);\n\n        JLabel refreshRateLabel = new JLabel(\"Sampling frequency:\");\n        c.gridx = 0;\n        c.gridy = 3;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(refreshRateLabel, c);\n\n        Integer[] refreshRates = new Integer[] { -1, 100, 200, 500, 1000, 2000, 5000, 10000 };\n        refreshCombo = new JComboBox(refreshRates)  {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        refreshRateLabel.setLabelFor(refreshCombo);\n        refreshCombo.setRenderer(new CustomComboRenderer.Number(refreshCombo, \"ms\", true));\n        refreshCombo.setEditable(false);\n        c.gridx = 1;\n        c.gridy = 3;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(refreshCombo, c);\n\n        refreshCheckBox = new JCheckBox(\"Customizable in Tracer tab\") {\n            public Dimension getPreferredSize() {\n                Dimension d = super.getPreferredSize();\n                d.height = Math.min(d.height, refreshCombo.getPreferredSize().height);\n                return d;\n            }\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n        c.gridx = 2;\n        c.gridy = 3;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(refreshCheckBox, c);\n\n        // zoomModeLabel\n        JLabel zoomModeLabel = new JLabel(\"Zoom mode:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 4;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(zoomModeLabel, c);\n\n        // zoomModeCombo\n        zoomModeCombo = new JComboBox(new String[] {\n                                          TracerOptions.FIXED_SCALE,\n                                          TracerOptions.SCALE_TO_FIT }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        zoomModeLabel.setLabelFor(zoomModeCombo);\n        zoomModeCombo.setRenderer(new CustomComboRenderer.String(zoomModeCombo));\n        zoomModeCombo.setEditable(false);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 4;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(zoomModeCombo, c);\n\n        // customizableZoomModeLabel\n        JLabel customizableZoomModeLabel = new JLabel(\"Customizable in Tracer tab\");\n        customizableZoomModeLabel.setEnabled(false);\n        c.gridx = 2;\n        c.gridy = 4;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 9, 3, 0);\n        add(customizableZoomModeLabel, c);\n\n        // mouseWheelLabel\n        JLabel mouseWheelLabel = new JLabel(\"Mouse wheel action:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 5;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(mouseWheelLabel, c);\n\n        // mouseWheelCombo\n        mouseWheelCombo = new JComboBox(new String[] {\n                                          TracerOptions.MOUSE_WHEEL_ZOOMS,\n                                          TracerOptions.MOUSE_WHEEL_HSCROLLS,\n                                          TracerOptions.MOUSE_WHEEL_VSCROLLS }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        mouseWheelLabel.setLabelFor(mouseWheelCombo);\n        mouseWheelCombo.setRenderer(new CustomComboRenderer.String(mouseWheelCombo));\n        mouseWheelCombo.setEditable(false);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 5;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(mouseWheelCombo, c);\n\n        // customizableMouseWheelLabel\n        JLabel customizableMouseWheelLabel = new JLabel(\"Customizable in Tracer tab\");\n        customizableMouseWheelLabel.setEnabled(false);\n        c.gridx = 2;\n        c.gridy = 5;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 9, 3, 0);\n        add(customizableMouseWheelLabel, c);\n\n\n        // timelineAppearanceSeparator\n        SectionSeparator timelineAppearanceSeparator =\n                UISupport.createSectionSeparator(\"Timeline Appearance\"); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 6;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(15, 0, 5, 0);\n        add(timelineAppearanceSeparator, c);\n\n        // minMaxValsLabel\n        JLabel minMaxValsLabel = new JLabel(\"Show min/max values:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 7;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(minMaxValsLabel, c);\n\n        // minMaxValsCombo\n        minMaxValsCombo = new JComboBox(new Boolean[] { Boolean.TRUE,\n                                                        Boolean.FALSE }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n//            protected void selectedItemChanged() {\n//                TracerOptionsPanel.this.update();\n//                super.selectedItemChanged();\n//            }\n        };\n        minMaxValsLabel.setLabelFor(minMaxValsCombo);\n        minMaxValsCombo.setRenderer(new CustomComboRenderer.Boolean(minMaxValsCombo));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 7;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(minMaxValsCombo, c);\n\n        // customizableMinMaxValsLabel\n        JLabel customizableMinMaxValsLabel = new JLabel(\"Customizable in Tracer tab\");\n        customizableMinMaxValsLabel.setEnabled(false);\n        c.gridx = 2;\n        c.gridy = 7;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 9, 3, 0);\n        add(customizableMinMaxValsLabel, c);\n\n        // rowLegendLabel\n        JLabel rowLegendLabel = new JLabel(\"Show row legend:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 8;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(rowLegendLabel, c);\n\n        // rowLegendCombo\n        rowLegendCombo = new JComboBox(new Boolean[] { Boolean.TRUE,\n                                                       Boolean.FALSE }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n//            protected void selectedItemChanged() {\n//                TracerOptionsPanel.this.update();\n//                super.selectedItemChanged();\n//            }\n        };\n        rowLegendLabel.setLabelFor(rowLegendCombo);\n        rowLegendCombo.setRenderer(new CustomComboRenderer.Boolean(rowLegendCombo));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 8;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(rowLegendCombo, c);\n\n        // customizableRowLegendLabel\n        JLabel customizableRowLegendLabel = new JLabel(\"Customizable in Tracer tab\");\n        customizableRowLegendLabel.setEnabled(false);\n        c.gridx = 2;\n        c.gridy = 8;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 9, 3, 0);\n        add(customizableRowLegendLabel, c);\n\n        // rowsDecorationLabel\n        JLabel rowsDecorationLabel = new JLabel(\"Rows decoration:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 9;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(rowsDecorationLabel, c);\n\n        // rowsDecorationCombo\n        rowsDecorationCombo = new JComboBox(new Boolean[] { Boolean.TRUE,\n                                                            Boolean.FALSE }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n//            protected void selectedItemChanged() {\n//                TracerOptionsPanel.this.update();\n//                super.selectedItemChanged();\n//            }\n        };\n        rowsDecorationLabel.setLabelFor(rowsDecorationCombo);\n        rowsDecorationCombo.setRenderer(new CustomComboRenderer.Boolean(rowsDecorationCombo));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 9;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(rowsDecorationCombo, c);\n\n        // rowsSelectionLabel\n        JLabel rowsSelectionLabel = new JLabel(\"Rows selection:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 10;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(rowsSelectionLabel, c);\n\n        // rowsSelectionCombo\n        rowsSelectionCombo = new JComboBox(new String[] { \"panel and chart\",\n                                                          \"panel only\" }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n//            protected void selectedItemChanged() {\n//                TracerOptionsPanel.this.update();\n//                super.selectedItemChanged();\n//            }\n        };\n        rowsSelectionLabel.setLabelFor(rowsSelectionCombo);\n//        rowsSelectionCombo.setRenderer(new CustomComboRenderer.Boolean(rowsSelectionCombo));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 10;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(rowsSelectionCombo, c);\n\n\n        // toolbarsBehaviorSeparator\n        SectionSeparator toolbarsBehaviorSeparator =\n                UISupport.createSectionSeparator(\"Toolbars Behavior\"); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 11;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(15, 0, 5, 0);\n        add(toolbarsBehaviorSeparator, c);\n\n        // minMaxValsLabel\n        JLabel timelineToolbarLabel = new JLabel(\"Timeline toolbar:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 12;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(timelineToolbarLabel, c);\n\n        // timelineToolbarCombo\n        timelineToolbarCombo = new JComboBox(new String[] { \"always visible\",\n                                                            \"show with timeline\" }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        timelineToolbarLabel.setLabelFor(timelineToolbarCombo);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 12;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(timelineToolbarCombo, c);\n\n        // selectionToolbarLabel\n        JLabel selectionToolbarLabel = new JLabel(\"Selection toolbar:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 13;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(selectionToolbarLabel, c);\n\n        // rowLegendCombo\n        selectionToolbarCombo = new JComboBox(new String[] { \"always visible\",\n                                                             \"show on selection\",\n                                                             \"always hidden\"}) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        selectionToolbarLabel.setLabelFor(selectionToolbarCombo);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 13;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(selectionToolbarCombo, c);\n\n        // extraToolbarLabel\n        JLabel extraToolbarLabel = new JLabel(\"Export toolbar:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 14;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(extraToolbarLabel, c);\n\n        // extraToolbarCombo\n        extraToolbarCombo = new JComboBox(new String[] { \"always visible\",\n                                                          \"show on data\",\n                                                          \"always hidden\"}) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        extraToolbarLabel.setLabelFor(extraToolbarCombo);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 14;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(extraToolbarCombo, c);\n\n\n        // viewsBehaviorSeparator\n        SectionSeparator viewsBehaviorSeparator =\n                UISupport.createSectionSeparator(\"Views Behavior\"); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 15;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(15, 0, 5, 0);\n        add(viewsBehaviorSeparator, c);\n\n        // viewsBehaviorPanel\n//        JPanel viewsBehaviorPanel = new JPanel(new GridLayout(1, 3));\n        JPanel viewsBehaviorPanel = new JPanel(new BorderLayout(0, 0));\n        viewsBehaviorPanel.setOpaque(false);\n        c = new GridBagConstraints();\n        c.gridy = 16;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n//        c.insets = new Insets(3, 15, 0, 0);\n        c.insets = new Insets(8, 15, 0, 0);\n        add(viewsBehaviorPanel, c);\n\n        final CardLayout viewsSettingsLayout = new CardLayout();\n        final JPanel viewsSettingsContainer = new JPanel(viewsSettingsLayout);\n        final String INITIALLY_OPEN = \"Initial appearance\";\n        final String OPEN_PROBE_ADDED = \"Probe added or removed\";\n        final String OPEN_SESSION_STARTS = \"Session started\";\n        final String OPEN_ROW_SELECTED = \"Row selected or unselected\";\n\n        final DefaultListModel connectionTypeListModel = new DefaultListModel();\n        connectionTypeListModel.addElement(INITIALLY_OPEN);\n        connectionTypeListModel.addElement(OPEN_PROBE_ADDED);\n        connectionTypeListModel.addElement(OPEN_SESSION_STARTS);\n        connectionTypeListModel.addElement(OPEN_ROW_SELECTED);\n\n        JList connectionTypeList = new JList(connectionTypeListModel);\n        connectionTypeList.setVisibleRowCount(connectionTypeListModel.getSize());\n\n        connectionTypeList.setSelectionModel(new DefaultListSelectionModel() {\n            public void setSelectionInterval(int index0, int index1) {\n                super.setSelectionInterval(index0, index1);\n                viewsSettingsLayout.show(viewsSettingsContainer, connectionTypeListModel.get(getMinSelectionIndex()).toString());\n            }\n            public void removeSelectionInterval(int i1, int i2) {}\n        });\n        connectionTypeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        connectionTypeList.setSelectedIndex(0);\n        final ListCellRenderer defaultRenderer = connectionTypeList.getCellRenderer();\n        Component rc = defaultRenderer.getListCellRendererComponent(connectionTypeList, \"X\", 0, false, false); // NOI18N\n        connectionTypeList.setFixedCellHeight(rc.getPreferredSize().height + 2);\n        connectionTypeList.setCellRenderer(new ListCellRenderer() {\n            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {\n                return defaultRenderer.getListCellRendererComponent(list, \" \" + value + \" \", index, isSelected, cellHasFocus); // NOI18N\n            }\n        });\n        JScrollPane connectionTypeScroll = new JScrollPane(connectionTypeList,\n                                    JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                                    JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) {\n            public Dimension getMinimumSize() { return getPreferredSize(); }\n        };\n        createBorder(connectionTypeScroll, BorderFactory.createEmptyBorder(0, 0, 0, 10));\n        viewsBehaviorPanel.add(connectionTypeScroll, BorderLayout.WEST);\n        viewsBehaviorPanel.add(viewsSettingsContainer, BorderLayout.CENTER);\n\n\n//        // initiallyOpenedPanel\n        initiallyOpenedPanel = new JPanel(new VerticalLayout(false));\n        initiallyOpenedPanel.setBorder(titledBorder(\"Select the views to open:\"));\n        initiallyOpenedPanel.setOpaque(false);\n        // initialProbesCheckBox\n        initialProbesCheckBox = new JCheckBox(\"Probes\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        initiallyOpenedPanel.add(initialProbesCheckBox);\n        // initialTimelineCheckBox\n        initialTimelineCheckBox = new JCheckBox(\"Timeline\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        initiallyOpenedPanel.add(initialTimelineCheckBox);\n//        // initialSettingsCheckBox\n//        JCheckBox initialSettingsCheckBox = new JCheckBox(\"Settings\");\n//        initiallyOpenedPanel.add(initialSettingsCheckBox);\n//        initialSettingsCheckBox.setEnabled(false);\n        // initialDetailsCheckBox\n        initialDetailsCheckBox = new JCheckBox(\"Details\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        initiallyOpenedPanel.add(initialDetailsCheckBox);\n//        viewsBehaviorPanel.add(initiallyOpenedPanel);\n        viewsSettingsContainer.add(initiallyOpenedPanel, INITIALLY_OPEN);\n\n        // onProbeAddedPanel\n        onProbeAddedPanel = new JPanel(new VerticalLayout(false));\n        onProbeAddedPanel.setBorder(titledBorder(\"Open for selected probes:\"));\n        onProbeAddedPanel.setOpaque(false);\n        // initialProbesCheckBox\n        onProbeAddedProbesCheckBox = new JCheckBox(\"Probes\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel.add(onProbeAddedProbesCheckBox);\n        // initialTimelineCheckBox\n        onProbeAddedTimelineCheckBox = new JCheckBox(\"Timeline\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel.add(onProbeAddedTimelineCheckBox);\n//        // initialSettingsCheckBox\n//        JCheckBox onProbeAddedSettingsCheckBox = new JCheckBox(\"Settings\");\n//        onProbeAddedPanel.add(onProbeAddedSettingsCheckBox);\n//        onProbeAddedSettingsCheckBox.setEnabled(false);\n        // initialDetailsCheckBox\n        onProbeAddedDetailsCheckBox = new JCheckBox(\"Details\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel.add(onProbeAddedDetailsCheckBox);\n        // onStartNothingCheckBox\n        onProbeAddedNothingCheckBox = new JCheckBox(\"No change\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel.add(onProbeAddedNothingCheckBox);\n//        viewsBehaviorPanel.add(onProbeAddedPanel);\n\n\n        // onProbeAddedPanel2\n        onProbeAddedPanel2 = new JPanel(new VerticalLayout(false));\n        onProbeAddedPanel2.setBorder(titledBorder(\"Open for no selection:\"));\n        onProbeAddedPanel2.setOpaque(false);\n        // initialProbesCheckBox2\n        onProbeAddedProbesCheckBox2 = new JCheckBox(\"Probes\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel2.add(onProbeAddedProbesCheckBox2);\n        // initialTimelineCheckBox2\n        onProbeAddedTimelineCheckBox2 = new JCheckBox(\"Timeline\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel2.add(onProbeAddedTimelineCheckBox2);\n//        // onProbeAddedSettingsCheckBox2\n//        JCheckBox onProbeAddedSettingsCheckBox2 = new JCheckBox(\"Settings\");\n//        onProbeAddedPanel2.add(onProbeAddedSettingsCheckBox2);\n//        onProbeAddedSettingsCheckBox2.setEnabled(false);\n        // onProbeAddedDetailsCheckBox2\n        onProbeAddedDetailsCheckBox2 = new JCheckBox(\"Details\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel2.add(onProbeAddedDetailsCheckBox2);\n        // onProbeAddedNothingCheckBox2\n        onProbeAddedNothingCheckBox2 = new JCheckBox(\"No change\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel2.add(onProbeAddedNothingCheckBox2);\n//        viewsBehaviorPanel.add(onProbeAddedPanel2);\n\n        JPanel onProbeAddedContainer = new JPanel(new GridLayout(1, 2));\n        onProbeAddedContainer.add(onProbeAddedPanel);\n        onProbeAddedContainer.add(onProbeAddedPanel2);\n        viewsSettingsContainer.add(onProbeAddedContainer, OPEN_PROBE_ADDED);\n\n        // onStartOpenedPanel\n        onStartOpenedPanel = new JPanel(new VerticalLayout(false));\n        onStartOpenedPanel.setBorder(titledBorder(\"Select the views to open:\"));\n        onStartOpenedPanel.setOpaque(false);\n        // initialProbesCheckBox\n        onStartProbesCheckBox = new JCheckBox(\"Probes\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onStartOpenedPanel.add(onStartProbesCheckBox);\n        // initialTimelineCheckBox\n        onStartTimelineCheckBox = new JCheckBox(\"Timeline\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onStartOpenedPanel.add(onStartTimelineCheckBox);\n//        // initialSettingsCheckBox\n//        JCheckBox onStartSettingsCheckBox = new JCheckBox(\"Settings\");\n//        onStartOpenedPanel.add(onStartSettingsCheckBox);\n//        onStartSettingsCheckBox.setEnabled(false);\n        // initialDetailsCheckBox\n        onStartDetailsCheckBox = new JCheckBox(\"Details\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onStartOpenedPanel.add(onStartDetailsCheckBox);\n        // onStartNothingCheckBox\n        onStartNothingCheckBox = new JCheckBox(\"No change\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onStartOpenedPanel.add(onStartNothingCheckBox);\n//        viewsBehaviorPanel.add(onStartOpenedPanel);\n        viewsSettingsContainer.add(onStartOpenedPanel, OPEN_SESSION_STARTS);\n\n        // onRowSelectedPanel\n        onRowSelectedPanel = new JPanel(new VerticalLayout(false));\n        onRowSelectedPanel.setBorder(titledBorder(\"Open for selected rows:\"));\n        onRowSelectedPanel.setOpaque(false);\n        // initialProbesCheckBox\n        onRowSelectedProbesCheckBox = new JCheckBox(\"Probes\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel.add(onRowSelectedProbesCheckBox);\n        // initialTimelineCheckBox\n        onRowSelectedTimelineCheckBox = new JCheckBox(\"Timeline\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel.add(onRowSelectedTimelineCheckBox);\n//        // initialSettingsCheckBox\n//        JCheckBox onProbeAddedSettingsCheckBox = new JCheckBox(\"Settings\");\n//        onProbeAddedPanel.add(onProbeAddedSettingsCheckBox);\n//        onProbeAddedSettingsCheckBox.setEnabled(false);\n        // initialDetailsCheckBox\n        onRowSelectedDetailsCheckBox = new JCheckBox(\"Details\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel.add(onRowSelectedDetailsCheckBox);\n        // onStartNothingCheckBox\n        onRowSelectedNothingCheckBox = new JCheckBox(\"No change\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel.add(onRowSelectedNothingCheckBox);\n//        viewsBehaviorPanel.add(onProbeAddedPanel);\n\n\n        // onRowSelectedPanel2\n        onRowSelectedPanel2 = new JPanel(new VerticalLayout(false));\n        onRowSelectedPanel2.setBorder(titledBorder(\"Open for no selection:\"));\n        onRowSelectedPanel2.setOpaque(false);\n        // initialProbesCheckBox2\n        onRowSelectedProbesCheckBox2 = new JCheckBox(\"Probes\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel2.add(onRowSelectedProbesCheckBox2);\n        // initialTimelineCheckBox2\n        onRowSelectedTimelineCheckBox2 = new JCheckBox(\"Timeline\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel2.add(onRowSelectedTimelineCheckBox2);\n//        // onProbeAddedSettingsCheckBox2\n//        JCheckBox onProbeAddedSettingsCheckBox2 = new JCheckBox(\"Settings\");\n//        onProbeAddedPanel2.add(onProbeAddedSettingsCheckBox2);\n//        onProbeAddedSettingsCheckBox2.setEnabled(false);\n        // onProbeAddedDetailsCheckBox2\n        onRowSelectedDetailsCheckBox2 = new JCheckBox(\"Details\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel2.add(onRowSelectedDetailsCheckBox2);\n        // onProbeAddedNothingCheckBox2\n        onRowSelectedNothingCheckBox2 = new JCheckBox(\"No change\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel2.add(onRowSelectedNothingCheckBox2);\n//        viewsBehaviorPanel.add(onProbeAddedPanel2);\n\n        JPanel onRowSelectedContainer = new JPanel(new GridLayout(1, 2));\n        onRowSelectedContainer.add(onRowSelectedPanel);\n        onRowSelectedContainer.add(onRowSelectedPanel2);\n        viewsSettingsContainer.add(onRowSelectedContainer, OPEN_ROW_SELECTED);\n\n        // clearSelectionsCheckBox\n        clearSelectionsCheckBox = new JCheckBox(\"Clear selected rows when closing Details view\") {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 17;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.insets = new Insets(8, 15, 0, 0);\n        add(clearSelectionsCheckBox, c);\n\n\n        // bottomFiller\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 100;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        add(Spacer.create(), c);\n    }\n\n\n    private JComboBox probesDefaultsCombo;\n    private JComboBox refreshCombo;\n    private JCheckBox refreshCheckBox;\n    private JComboBox minMaxValsCombo;\n    private JComboBox rowLegendCombo;\n    private JComboBox rowsDecorationCombo;\n    private JComboBox rowsSelectionCombo;\n    private JComboBox timelineToolbarCombo;\n    private JComboBox selectionToolbarCombo;\n    private JComboBox extraToolbarCombo;\n    private JPanel initiallyOpenedPanel;\n    private JCheckBox initialProbesCheckBox;\n    private JCheckBox initialTimelineCheckBox;\n    private JCheckBox initialDetailsCheckBox;\n    private JPanel onProbeAddedPanel;\n    private JCheckBox onProbeAddedProbesCheckBox;\n    private JCheckBox onProbeAddedTimelineCheckBox;\n    private JCheckBox onProbeAddedDetailsCheckBox;\n    private JCheckBox onProbeAddedNothingCheckBox;\n    private JPanel onProbeAddedPanel2;\n    private JCheckBox onProbeAddedProbesCheckBox2;\n    private JCheckBox onProbeAddedTimelineCheckBox2;\n    private JCheckBox onProbeAddedDetailsCheckBox2;\n    private JCheckBox onProbeAddedNothingCheckBox2;\n    private JPanel onStartOpenedPanel;\n    private JCheckBox onStartProbesCheckBox;\n    private JCheckBox onStartTimelineCheckBox;\n    private JCheckBox onStartDetailsCheckBox;\n    private JCheckBox onStartNothingCheckBox;\n    private JPanel onRowSelectedPanel;\n    private JCheckBox onRowSelectedProbesCheckBox;\n    private JCheckBox onRowSelectedTimelineCheckBox;\n    private JCheckBox onRowSelectedDetailsCheckBox;\n    private JCheckBox onRowSelectedNothingCheckBox;\n    private JPanel onRowSelectedPanel2;\n    private JCheckBox onRowSelectedProbesCheckBox2;\n    private JCheckBox onRowSelectedTimelineCheckBox2;\n    private JCheckBox onRowSelectedDetailsCheckBox2;\n    private JCheckBox onRowSelectedNothingCheckBox2;\n    private JCheckBox clearSelectionsCheckBox;\n\n    private JComboBox zoomModeCombo;\n    private JComboBox mouseWheelCombo;\n\n\n    private static Border titledBorder(String title) {\n        String titleBorder = org.graalvm.visualvm.uisupport.UISupport.\n                             isWindowsLookAndFeel() ? \" \" : \"\"; //NOI18N\n        Border inner = BorderFactory.createEmptyBorder(0, 12, 3, 3);\n        Border outer = BorderFactory.createTitledBorder(titleBorder + title);\n        return BorderFactory.createCompoundBorder(outer, inner);\n    }\n\n    private static void createBorder(JComponent component, Border border) {\n        Border cBorder = component.getBorder();\n        if (cBorder == null) component.setBorder(border);\n        else component.setBorder(BorderFactory.createCompoundBorder(border, cBorder));\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/options/TracerOptionsPanelController.java",
    "content": "/*\n *  Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.options;\n\nimport org.graalvm.visualvm.core.options.UISupport;\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport javax.swing.JComponent;\nimport org.netbeans.spi.options.OptionsPanelController;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@OptionsPanelController.TopLevelRegistration(\n        id = \"TracerOptions\",\n        categoryName = \"Tracer\",\n        iconBase = \"org/graalvm/visualvm/modules/tracer/impl/resources/tracer24.png\",\n        position = 5500\n)\npublic final class TracerOptionsPanelController extends OptionsPanelController {\n\n    private TracerOptions options = TracerOptions.getInstance();\n    private TracerOptionsPanel panel;\n    private JComponent component;\n    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);\n    private boolean changed;\n\n\n    public void update() {\n        TracerOptionsPanel p = getPanel();\n\n        p.setProbesApp(options.getProbesApp());\n\n        p.setRefresh(options.getRefresh());\n        p.setRefreshCustomizable(options.isRefreshCustomizable());\n\n        p.setShowValuesEnabled(options.isShowValuesEnabled());\n        p.setShowLegendEnabled(options.isShowLegendEnabled());\n        p.setRowsDecorationEnabled(options.isRowsDecorationEnabled());\n        p.setRowsSelectionEnabled(options.isRowsSelectionEnabled());\n\n        p.setInitiallyOpened(options.getInitiallyOpened());\n        p.setOnProbeAdded(options.getOnProbeAdded());\n        p.setOnProbeAdded2(options.getOnProbeAdded2());\n        p.setOnSessionStart(options.getOnSessionStart());\n        p.setOnRowSelected(options.getOnRowSelected());\n        p.setOnRowSelected2(options.getOnRowSelected2());\n\n        p.setZoomMode(options.getZoomMode());\n        p.setMouseWheelAction(options.getMouseWheelAction());\n\n        p.setTimelineToolbar(options.getTimelineToolbar());\n        p.setSelectionToolbar(options.getSelectionToolbar());\n        p.setExtraToolbar(options.getExtraToolbar());\n\n        p.setClearSelection(options.isClearSelection());\n\n        p.update();\n    }\n\n    public void applyChanges() {\n        TracerOptionsPanel p = getPanel();\n\n        options.setProbesApp(p.getProbesApp());\n\n        options.setRefresh(p.getRefresh());\n        options.setRefreshCustomizable(p.isRefreshCustomizable());\n\n        options.setShowValuesEnabled(p.isShowValuesEnabled());\n        options.setShowLegendEnabled(p.isShowLegendEnabled());\n        options.setRowsDecorationEnabled(p.isRowsDecorationEnabled());\n        options.setRowsSelectionEnabled(p.isRowsSelectionEnabled());\n\n        options.setInitiallyOpened(p.getInitiallyOpened());\n        options.setOnProbeAdded(p.getOnProbeAdded());\n        options.setOnProbeAdded2(p.getOnProbeAdded2());\n        options.setOnSessionStart(p.getOnSessionStart());\n        options.setOnRowSelected(p.getOnRowSelected());\n        options.setOnRowSelected2(p.getOnRowSelected2());\n\n        options.setZoomMode(p.getZoomMode());\n        options.setMouseWheelAction(p.getMouseWheelAction());\n\n        options.setTimelineToolbar(p.getTimelineToolbar());\n        options.setSelectionToolbar(p.getSelectionToolbar());\n        options.setExtraToolbar(p.getExtraToolbar());\n\n        options.setClearSelection(p.isClearSelection());\n    }\n\n    public void cancel() {}\n\n    public boolean isValid() {\n        return getPanel().dataValid();\n    }\n\n    public boolean isChanged() {\n        TracerOptionsPanel p = getPanel();\n\n        if (options.getProbesApp() != p.getProbesApp()) return true;\n\n        if (options.getRefresh() != p.getRefresh()) return true;\n        if (options.isRefreshCustomizable() != p.isRefreshCustomizable()) return true;\n\n        if (options.isShowValuesEnabled() != p.isShowValuesEnabled()) return true;\n        if (options.isShowLegendEnabled() != p.isShowLegendEnabled()) return true;\n        if (options.isRowsDecorationEnabled() != p.isRowsDecorationEnabled()) return true;\n        if (options.isRowsSelectionEnabled() != p.isRowsSelectionEnabled()) return true;\n\n        if (!options.getInitiallyOpened().equals(p.getInitiallyOpened())) return true;\n        if (!options.getOnProbeAdded().equals(p.getOnProbeAdded())) return true;\n        if (!options.getOnProbeAdded2().equals(p.getOnProbeAdded2())) return true;\n        if (!options.getOnSessionStart().equals(p.getOnSessionStart())) return true;\n        if (!options.getOnRowSelected().equals(p.getOnRowSelected())) return true;\n        if (!options.getOnRowSelected2().equals(p.getOnRowSelected2())) return true;\n\n        if (!options.getZoomMode().equals(p.getZoomMode())) return true;\n        if (!options.getMouseWheelAction().equals(p.getMouseWheelAction())) return true;\n\n        if (options.getTimelineToolbar() != p.getTimelineToolbar()) return true;\n        if (options.getSelectionToolbar() != p.getSelectionToolbar()) return true;\n        if (options.getExtraToolbar() != p.getExtraToolbar()) return true;\n\n        if (options.isClearSelection() != p.isClearSelection()) return true;\n\n        return false;\n    }\n\n\n    public HelpCtx getHelpCtx() {\n        return null;\n\n    }\n\n\n    public JComponent getComponent(Lookup masterLookup) {\n        return getComponent();\n    }\n\n    public void addPropertyChangeListener(PropertyChangeListener l) {\n        pcs.addPropertyChangeListener(l);\n    }\n\n    public void removePropertyChangeListener(PropertyChangeListener l) {\n        pcs.removePropertyChangeListener(l);\n    }\n\n\n    private TracerOptionsPanel getPanel() {\n        if (panel == null) panel = new TracerOptionsPanel(this);\n        return panel;\n    }\n\n    private JComponent getComponent() {\n        if (component == null) {\n            component = UISupport.createScrollableContainer(getPanel());\n        }\n        return component;\n    }\n\n    void changed() {\n        if (!changed) {\n            changed = true;\n            pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);\n        }\n        pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/probes/ProbeDescriptorComponent.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.probes;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport java.awt.Component;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport javax.swing.Icon;\nimport javax.swing.JCheckBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ProbeDescriptorComponent extends JPanel {\n\n    public ProbeDescriptorComponent(final TracerProbeDescriptor descriptor,\n                                    final TracerPackage p,\n                                    final SelectionHandler handler) {\n        setOpaque(false);\n        setLayout(new GridBagLayout());\n        GridBagConstraints c;\n\n        JCheckBox checkBox = new JCheckBox() {\n            protected void fireActionPerformed(ActionEvent event) {\n                if (isSelected()) handler.descriptorSelected(p, descriptor);\n                else handler.descriptorUnselected(p, descriptor);\n            }\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled && descriptor.isProbeAvailable());\n            }\n        };\n        checkBox.setOpaque(false);\n        checkBox.setEnabled(descriptor.isProbeAvailable());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.gridheight = 2;\n        c.anchor = GridBagConstraints.CENTER;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(checkBox, c);\n\n        JLabel icon = new JLabel() {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled && descriptor.isProbeAvailable());\n            }\n        };\n        Icon ic = descriptor.getProbeIcon();\n        icon.setIcon(ic);\n        icon.setEnabled(descriptor.isProbeAvailable());\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.gridheight = 2;\n        c.anchor = GridBagConstraints.CENTER;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 5, 3, 5);\n        add(icon, c);\n\n        JLabel name = new JLabel(descriptor.getProbeName()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled && descriptor.isProbeAvailable());\n            }\n        };\n        name.setFont(name.getFont().deriveFont(Font.BOLD));\n        name.setEnabled(descriptor.isProbeAvailable());\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.gridheight = 1;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 10, 0, 5);\n        add(name, c);\n\n        JLabel descr = new JLabel(descriptor.getProbeDescription()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled && descriptor.isProbeAvailable());\n            }\n        };\n        descr.setFont(descr.getFont().deriveFont(Font.PLAIN));\n        descr.setEnabled(descriptor.isProbeAvailable());\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 1;\n        c.gridwidth = 1;\n        c.gridheight = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 10, 3, 5);\n        add(descr, c);\n    }\n\n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        Component[] components = getComponents();\n        for (Component c : components) c.setEnabled(enabled);\n    }\n\n\n    public static interface SelectionHandler {\n\n        public void descriptorSelected(TracerPackage<DataSource> p, TracerProbeDescriptor d);\n\n        public void descriptorUnselected(TracerPackage<DataSource> p, TracerProbeDescriptor d);\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/probes/ProbePresenter.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.probes;\n\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.LinearGradientPaint;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ProbePresenter extends JLabel {\n\n    private static final Color SELECTED_FILTER = new Color(0, 0, 200, 40);\n    private static final float[] FRACTIONS = new float[] { 0.0f, 0.49f, 0.51f, 1.0f };\n    private static final Color[] COLORS = new Color[] { new Color(250, 251, 252, 120),\n                                                        new Color(237, 240, 242, 120),\n                                                        new Color(229, 233, 236, 125),\n                                                        new Color(215, 221, 226, 130) };\n    private static final Color BACKGROUND = UIManager.getColor(\"Panel.background\"); // NOI18N\n\n    private LinearGradientPaint gradientPaint;\n\n    private static final boolean GRADIENT = !Utils.forceSpeed();\n    private boolean isSelected = false;\n\n    public ProbePresenter(TracerProbe p, TracerProbeDescriptor d) {\n        super(d.getProbeName(), d.getProbeIcon(), JLabel.LEADING);\n        \n        // --- ToolTips support\n        // Note: cannot use setToolTipText here, breaks mouseListener on parent\n//        setToolTipText(d.getProbeDescription());\n        // Let's store the tooltip in client property and resolve it from parent\n        putClientProperty(\"ToolTipHelper\", d.getProbeDescription()); // NOI18N\n        // ---\n        \n        setIconTextGap(7);\n        setBorder(BorderFactory.createCompoundBorder(\n                    BorderFactory.createMatteBorder(0, 1, 1, 1, Color.LIGHT_GRAY),\n                    BorderFactory.createEmptyBorder(5, 10, 5, 10)\n                ));\n    }\n    \n\n    public void setSelected(boolean selected) {\n        if (isSelected == selected) return;\n        isSelected = selected;\n        repaint();\n    }\n    \n    public boolean isSelected() {\n        return isSelected;\n    }\n\n\n    public void reshape(int x, int y, int w, int h) {\n        if (GRADIENT) gradientPaint = new LinearGradientPaint(0, 0, 0, h - 1,\n                                                              FRACTIONS, COLORS);\n        super.reshape(x, y, w, h);\n    }\n\n\n    protected void paintComponent(Graphics g) {\n        int y = getHeight() - 1;\n\n        ((Graphics2D)g).setPaint(GRADIENT ? gradientPaint : BACKGROUND);\n        g.fillRect(0, 0, getWidth(), y);\n        \n        if (isSelected) {\n            g.setColor(SELECTED_FILTER);\n            g.fillRect(0, 0, getWidth(), y);\n        }\n\n        super.paintComponent(g);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/CategoryList.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport org.graalvm.visualvm.uisupport.VerticalLayout;\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Cursor;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.image.BufferedImage;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuBar;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.UIManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class CategoryList extends JPanel {\n\n    private static final Icon expandedIcon;\n    private static final Icon collapsedIcon;\n\n    static {\n        Icon expanded = UIManager.getIcon(\"Tree.expandedIcon\"); // NOI18N\n        Icon collapsed = UIManager.getIcon(\"Tree.collapsedIcon\"); // NOI18N\n        int width = Math.max(expanded.getIconWidth(), collapsed.getIconWidth());\n        int height = Math.max(expanded.getIconHeight(), collapsed.getIconHeight());\n        expandedIcon = centeredIcon(expanded, width, height);\n        collapsedIcon = centeredIcon(collapsed, width, height);\n    }\n\n\n    public CategoryList(String[] categories, String[] tooltips,\n                    boolean[] initialStates, Component[][] items) {\n\n        setOpaque(false);\n        setLayout(new VerticalLayout(false));\n\n        int captionsCount = categories.length;\n        for (int i = 0; i < captionsCount; i++)\n            add(new Category(categories[i], tooltips[i], initialStates[i],\n                             items[i], i, captionsCount));\n\n    }\n\n\n    public void setEnabled(boolean enabled) {\n        Component[] components = getComponents();\n        for (Component c : components) c.setEnabled(enabled);\n    }\n\n\n    private static class Category extends JPanel {\n\n        private boolean expanded;\n\n        private final JLabel headerLabel;\n        private final JPanel itemsContainer;\n\n\n        public Category(String caption, String tooltip,\n                        boolean initialState, Component[] items,\n                        int index, int categoriesCount) {\n\n            expanded = initialState;\n\n            setOpaque(false);\n            setLayout(new BorderLayout());\n\n            headerLabel = new JLabel(caption);\n            headerLabel.setForeground(new JMenuItem().getForeground());\n            headerLabel.setToolTipText(tooltip);\n            headerLabel.setIconTextGap(5);\n            headerLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n            headerLabel.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));\n            headerLabel.addMouseListener(new MouseAdapter() {\n                public void mouseClicked(MouseEvent e) {\n                    expanded = !expanded;\n                    updateState();\n                }\n            });\n            \n            JMenuBar menuBar = new JMenuBar();\n            menuBar.setBorder(BorderFactory.createEmptyBorder());\n            menuBar.setBorderPainted(false);\n            menuBar.setLayout(new BorderLayout());\n            menuBar.add(headerLabel, BorderLayout.CENTER);\n            \n            itemsContainer = new JPanel() {\n                public void setEnabled(boolean enabled) {\n                    Component[] components = getComponents();\n                    for (Component c : components) c.setEnabled(enabled);\n                }\n            };\n            itemsContainer.setOpaque(false);\n            itemsContainer.setLayout(new VerticalLayout(false));\n\n            for (int i = 0; i < items.length; i++)\n                itemsContainer.add(items[i]);\n\n            add(menuBar, BorderLayout.NORTH);\n            add(itemsContainer, BorderLayout.CENTER);\n\n            updateState();\n\n        }\n\n        public void setEnabled(boolean enabled) {\n            Component[] components = getComponents();\n            for (Component c : components)\n                if (!(c instanceof JMenuBar)) c.setEnabled(enabled);\n        }\n\n        private void updateState() {\n            headerLabel.setIcon(expanded ? expandedIcon : collapsedIcon);\n            itemsContainer.setVisible(expanded);\n        }\n\n    }\n\n\n    private static Icon centeredIcon(final Icon icon, final int width, final int height) {\n        JLabel l = new JLabel(icon);\n        l.setIconTextGap(0);\n        l.setBorder(null);\n        l.setSize(width, height);\n        \n        BufferedImage img = new BufferedImage(l.getWidth(), l.getHeight(), BufferedImage.TYPE_INT_ARGB);\n        l.paint(img.getGraphics());\n        \n        return new ImageIcon(img);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/ColorIcon.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport java.awt.Color;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ColorIcon implements javax.swing.Icon {\n\n    private static int WIDTH = 8;\n    private static int HEIGHT = 8;\n    private static Color BACKGROUND_COLOR = Color.WHITE;\n    private static Color FOREGROUND_COLOR = Color.BLACK;\n\n    public static final ColorIcon BOTTOM_SHADOW = new ColorIcon(null, true);\n\n    private final boolean shadow;\n    private final Color color;\n\n    private static final Map<Color, ColorIcon> icons = new HashMap();\n\n\n    private ColorIcon(Color color) {\n        this(color, false);\n    }\n\n    private ColorIcon(Color color, boolean shadow) {\n        this.color = color;\n        this.shadow = shadow;\n    }\n\n\n    public static void setup(int width, int height, Color foreground, Color background) {\n        WIDTH = width;\n        HEIGHT = height;\n        BACKGROUND_COLOR = background;\n        FOREGROUND_COLOR = foreground;\n        icons.clear();\n    }\n\n    public static ColorIcon fromColor(Color color) {\n        ColorIcon icon = icons.get(color);\n        if (icon == null) {\n            icon = new ColorIcon(color);\n            icons.put(color, icon);\n        }\n        return icon;\n    }\n\n\n    public int getIconWidth() {\n        return WIDTH;\n    }\n\n    public int getIconHeight() {\n        return HEIGHT;\n    }\n\n    public void paintIcon(java.awt.Component c, java.awt.Graphics g, int x, int y) {\n        if (shadow) {\n            g.setColor(BACKGROUND_COLOR);\n            g.drawLine(x, y + HEIGHT + 1, x + WIDTH - 1, y + HEIGHT + 1);\n        } else {\n            g.setColor(color);\n            g.fillRect(x, y, WIDTH, HEIGHT);\n            g.setColor(FOREGROUND_COLOR);\n            g.drawRect(x, y, WIDTH - 1, HEIGHT - 1);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/CustomComboRenderer.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport java.awt.Component;\nimport java.text.NumberFormat;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.ListCellRenderer;\nimport javax.swing.SwingConstants;\nimport javax.swing.event.PopupMenuEvent;\nimport javax.swing.event.PopupMenuListener;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class CustomComboRenderer implements ListCellRenderer {\n\n    private final JComboBox combo;\n    private final ListCellRenderer renderer;\n    private final JLabel rendererL;\n\n\n    private CustomComboRenderer(JComboBox combo) {\n        this.combo = combo;\n        renderer = combo.getRenderer();\n        if (renderer instanceof JLabel) rendererL = (JLabel)renderer;\n        else rendererL = null;\n\n        this.combo.addPopupMenuListener(new PopupMenuListener() {\n            public void popupMenuWillBecomeVisible(PopupMenuEvent e)   { repaint(); }\n            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { repaint(); }\n            public void popupMenuCanceled(PopupMenuEvent e)            { repaint(); }\n            private void repaint() { CustomComboRenderer.this.combo.repaint(); }\n        });\n    }\n\n\n    protected void setupRenderer(ListCellRenderer renderer, boolean popupVisible) {}\n\n    protected void setupRenderer(JLabel renderer, boolean popupVisible) {}\n\n    public abstract java.lang.String value(Object value);\n\n\n    public Component getListCellRendererComponent(JList list, Object value,\n                                                  int index, boolean isSelected,\n                                                  boolean cellHasFocus) {\n\n        if (rendererL != null) setupRenderer(rendererL, combo.isPopupVisible());\n        else setupRenderer(renderer, combo.isPopupVisible());\n        \n        return renderer.getListCellRendererComponent(list, value(value), index,\n                                                     isSelected, cellHasFocus);\n    }\n\n\n    public static final class String extends CustomComboRenderer {\n\n        public String(JComboBox combo) {\n            super(combo);\n        }\n\n        public java.lang.String value(Object value) {\n            return value == null ? \"null\" : value.toString(); // NOI18N\n        }\n\n    }\n\n\n    public static final class Boolean extends CustomComboRenderer {\n\n        public Boolean(JComboBox combo) {\n            super(combo);\n        }\n\n        public java.lang.String value(Object value) {\n            if (java.lang.Boolean.TRUE.equals(value)) return \"enabled\";\n            if (java.lang.Boolean.FALSE.equals(value)) return \"disabled\";\n            return \"default\";\n        }\n\n    }\n\n\n    public static final class Number extends CustomComboRenderer {\n\n        private final java.lang.String units;\n        private final boolean lAlign;\n\n        public Number(JComboBox combo, java.lang.String units, boolean lAlign) {\n            super(combo);\n            this.units = units;\n            this.lAlign = lAlign;\n        }\n\n        protected void setupRenderer(JLabel renderer, boolean popupVisible) {\n            if (popupVisible || !lAlign) renderer.setHorizontalAlignment(SwingConstants.TRAILING);\n            else renderer.setHorizontalAlignment(SwingConstants.LEADING);\n        }\n\n        public java.lang.String value(Object value) {\n            java.lang.String sunits = units == null ? \"\" : \" \" + units;\n            return Integer.valueOf(-1).equals(value) ? \"default\" :\n                   NumberFormat.getInstance().format(value) + sunits;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/DropdownButton.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.Action;\nimport javax.swing.Icon;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.event.PopupMenuEvent;\nimport javax.swing.event.PopupMenuListener;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class DropdownButton extends JToggleButton {\n\n    public static final String KEY_CLASS = \"KEY_CLASS\"; // NOI18N\n    public static final String KEY_BOOLVALUE = \"KEY_BOOLVALUE\"; // NOI18N\n\n    private final List<Action> actions = new ArrayList();\n\n    \n    public DropdownButton(Icon icon) {\n        super(icon);\n    }\n\n\n    public void addAction(Action action) {\n        actions.add(action);\n    }\n\n    public void addSeparator() {\n        actions.add(null);\n    }\n\n\n    protected void fireActionPerformed(ActionEvent event) {\n        JPopupMenu popup = new JPopupMenu();\n        for (Action action : actions) addAction(popup, action);\n        popup.addPopupMenuListener(new PopupMenuListener() {\n            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {\n                setSelected(true);\n            }\n            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {\n                setSelected(false);\n            }\n            public void popupMenuCanceled(PopupMenuEvent e) {}\n        });\n        popup.show(this, getWidth() - popup.getPreferredSize().width, getHeight());\n//        popup.show(this, 0, getHeight());\n    }\n\n    private void addAction(JPopupMenu popup, Action action) {\n        if (action == null) {\n            popup.addSeparator();\n        } else {\n            Class cls = (Class)action.getValue(KEY_CLASS);\n            if (Boolean.class.equals(cls)) {\n                Boolean boolvalue = (Boolean)action.getValue(KEY_BOOLVALUE);\n                JCheckBoxMenuItem item = new JCheckBoxMenuItem(action);\n                item.setSelected(boolvalue);\n                popup.add(item);\n            } else {\n                popup.add(action);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/EnhancedLabelRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport javax.swing.border.Border;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class EnhancedLabelRenderer extends LabelRenderer {\n\n    private static final EnhancedInsets EMPTY_INSETS = new EnhancedInsets();\n\n    private EnhancedInsets marginInsets;\n    private EnhancedInsets borderInsets;\n    private Border border;\n    private Color background;\n\n\n    public void setMargin(Insets marginInsets) {\n        if (marginInsets == null) this.marginInsets = EMPTY_INSETS;\n        else this.marginInsets = new EnhancedInsets(marginInsets);\n    }\n\n    // Overridden for performance reasons.\n    public void setBorder(Border border) {\n        this.border = border;\n        if (border == null) borderInsets = EMPTY_INSETS;\n        else borderInsets = new EnhancedInsets(border.getBorderInsets(this));\n    }\n\n    // Overridden for performance reasons.\n    public Border getBorder() {\n        return border;\n    }\n\n    // Overridden for performance reasons.\n    public void setBackground(Color background) {\n        this.background = background;\n    }\n\n    // Overridden for performance reasons.\n    public Color getBackground() {\n        return background;\n    }\n\n    private EnhancedInsets getMarginInsets() {\n        if (marginInsets == null) marginInsets = EMPTY_INSETS;\n        return marginInsets;\n    }\n\n    private EnhancedInsets getBorderInsets() {\n        if (borderInsets == null) borderInsets = EMPTY_INSETS;\n        return borderInsets;\n    }\n\n\n    protected void prePaint(Graphics g, int x, int y) {\n        if (background != null) {\n            g.setColor(background);\n            EnhancedInsets margin = getMarginInsets();\n            Dimension size = getPreferredSize();\n            g.fillRect(x - margin.left,\n                       y - margin.top,\n                       size.width + margin.width(),\n                       size.height + margin.height());\n        }\n    }\n\n    protected void postPaint(Graphics g, int x, int y) {\n        if (border != null) {\n            EnhancedInsets bi = getBorderInsets();\n            EnhancedInsets margin = getMarginInsets();\n            Dimension size = getPreferredSize();\n            border.paintBorder(this, g,\n                               x - margin.left - bi.left,\n                               y - margin.top - bi.top,\n                               size.width + margin.width() + bi.width(),\n                               size.height + margin.height() + bi.height());\n        }\n    }\n\n\n    private static class EnhancedInsets extends Insets {\n\n        public EnhancedInsets() {\n            this(0, 0, 0, 0);\n        }\n        \n        public EnhancedInsets(Insets insets) {\n            this(insets.top, insets.left, insets.bottom, insets.right);\n        }\n\n        public EnhancedInsets(int top, int left, int bottom, int right) {\n            super(top, left, bottom, right);\n        }\n\n\n        public int width() {\n            return left + right;\n        }\n\n        public int height() {\n            return top + bottom;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/HeaderButton.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport java.awt.BasicStroke;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseEvent;\nimport javax.swing.AbstractButton;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JPanel;\nimport javax.swing.plaf.ButtonUI;\nimport javax.swing.plaf.basic.BasicButtonUI;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class HeaderButton extends HeaderPanel {\n\n    private static final HeaderButtonUI UI = new HeaderButtonUI();\n\n    private final JButton button;\n\n\n    public HeaderButton(String text, Icon icon) {\n        JPanel panel = super.getClientContainer();\n        panel.setLayout(new BorderLayout());\n        button = new JButton(text, icon) {\n            protected void processMouseEvent(MouseEvent e) {\n                super.processMouseEvent(e);\n                if (!isEnabled()) return;\n                HeaderButton.this.processMouseEvent(e);\n            }\n            protected void fireActionPerformed(ActionEvent e) {\n                performAction(e);\n            }\n        };\n        panel.add(button, BorderLayout.CENTER);\n\n        button.setOpaque(false);\n        button.setBorderPainted(false);\n        button.setMargin(new Insets(0, 0, 0, 0));\n        button.setUI(UI);\n    }\n\n    public void setToolTipText(String text) {\n        button.setToolTipText(text);\n    }\n\n    public void setEnabled(boolean enabled) {\n        button.setEnabled(enabled);\n        super.setEnabled(enabled);\n    }\n\n    public void reset() {\n        processMouseEvent(new MouseEvent(this, MouseEvent.MOUSE_EXITED,\n                          System.currentTimeMillis(), 0, -1, -1, 0, false));\n    }\n\n    protected boolean processMouseEvents() { return true; }\n\n    protected void performAction(ActionEvent e) {}\n    \n    public void setUI(ButtonUI ui) { if (ui == UI) super.setUI(ui); }\n\n\n    private static class HeaderButtonUI extends BasicButtonUI {\n\n        private static final Color FOCUS_COLOR = Color.BLACK;\n        private static final Stroke FOCUS_STROKE =\n                new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL,\n                                0, new float[] {0, 2}, 0);\n        private static final Color PRESSED_FOREGROUND =\n                Utils.checkedColor(new Color(100, 100, 100, 70));\n\n        protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect,\n                                  Rectangle textRect, Rectangle iconRect) {\n            Graphics2D g2 = (Graphics2D)g;\n            g2.setStroke(FOCUS_STROKE);\n            g2.setColor(FOCUS_COLOR);\n            g2.drawRect(2, 2, b.getWidth() - 5, b.getHeight() - 5);\n        }\n\n        protected void paintButtonPressed(Graphics g, AbstractButton b) {\n            g.setColor(PRESSED_FOREGROUND);\n            g.fillRect(0, 0, b.getWidth(), b.getHeight());\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/HeaderLabel.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport javax.swing.JLabel;\nimport javax.swing.SwingConstants;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class HeaderLabel extends HeaderPanel {\n\n    public static final int DEFAULT_HEIGHT = computeHeight();\n\n\n    private String text;\n    private int hAlign = SwingConstants.CENTER;\n\n\n    public HeaderLabel() {\n        this(\"\"); // NOI18N\n    }\n\n    public HeaderLabel(String text) {\n        this.text = text;\n    }\n\n\n    public final void setText(String text) {\n        this.text = text;\n        repaint();\n    }\n\n    public final String getText() {\n        return text;\n    }\n\n    public final void setHorizontalAlignment(int align) {\n        hAlign = align;\n        repaint();\n    }\n\n    public final int getHorizontalAlignment() {\n        return hAlign;\n    }\n\n\n    protected Object getRendererValue() {\n        return getText();\n    }\n\n\n    protected void setupRenderer(Component renderer) {\n        if (renderer instanceof JLabel) {\n            JLabel label = (JLabel)renderer;\n            label.setHorizontalAlignment(hAlign);\n        }\n    }\n\n\n    public Dimension getPreferredSize() {\n        return new Dimension(0, DEFAULT_HEIGHT);\n    }\n\n    private Dimension getPreferredSizeSuper() {\n        return super.getPreferredSize();\n    }\n\n\n    private static int computeHeight() {\n        int height = new HeaderLabel(\"X\").getPreferredSizeSuper().height; // NOI18N\n        if (UISupport.isMetalLookAndFeel()) height += 4;\n//        else if (UISupport.isAquaLookAndFeel()) height += 6;\n        return height;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/HeaderPanel.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.event.MouseEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTable;\nimport javax.swing.OverlayLayout;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumn;\nimport javax.swing.table.TableColumnModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class HeaderPanel extends JPanel {\n\n    private JPanel clientContainer;\n    private Header header;\n\n    public HeaderPanel() {\n        initComponents();\n    }\n\n\n    protected Object getRendererValue() { return null; }\n\n    protected void setupRenderer(Component renderer) {}\n\n    protected boolean isSelected() { return false; }\n\n    protected boolean processMouseEvents() { return false; }\n\n\n    public JPanel getClientContainer() {\n        if (clientContainer == null) {\n            clientContainer = Spacer.create();\n            add(clientContainer, 0);\n        }\n        return clientContainer;\n    }\n\n    public boolean isOptimizedDrawingEnabled() {\n        return clientContainer == null;\n    }\n    \n    protected void processMouseEvent(MouseEvent e) {\n        if (processMouseEvents()) header.processMouseEvent(e);\n        if (!e.isConsumed()) super.processMouseEvent(e);\n    }\n\n    private void initComponents() {\n        JTable impl = new JTable(new DefaultTableModel(new Object[] { \"\" }, 0)); // NOI18N\n        TableColumnModel colMod = impl.getColumnModel();\n        final TableColumn col = colMod.getColumn(0);\n        impl.setFocusable(false);\n        header = new Header(colMod);\n        impl.setTableHeader(header);\n        header.setResizingAllowed(false);\n        header.setReorderingAllowed(false);\n\n        final TableCellRenderer renderer = header.getDefaultRenderer();\n        header.setDefaultRenderer(new TableCellRenderer() {\n            public Component getTableCellRendererComponent(\n                    JTable table, Object value, boolean isSelected, boolean hasFocus,\n                    int row, int column) {\n\n                Component component = renderer.getTableCellRendererComponent(\n                        table, getRendererValue(), isSelected(),\n                        isSelected(), row, processMouseEvents() ? 0 : 1);\n\n                setupRenderer(component);\n\n                col.setWidth(header.getWidth());\n                return component;\n            }\n        });\n\n        JScrollPane scroll = new JScrollPane(impl, JScrollPane.VERTICAL_SCROLLBAR_NEVER,\n                                                   JScrollPane.HORIZONTAL_SCROLLBAR_NEVER) {\n            public Dimension getPreferredSize() { return header.getPreferredSize(); }\n            public void reshape(int x, int y, int width, int height) {\n                header.setPreferredSize(new Dimension(width, height));\n                super.reshape(x, y, width, height);\n            }\n        };\n        scroll.setBorder(BorderFactory.createEmptyBorder());\n        scroll.setViewportBorder(BorderFactory.createEmptyBorder());\n\n        setLayout(new OverlayLayout(this));\n        add(scroll);\n    }\n\n    private static class Header extends JTableHeader {\n        Header(TableColumnModel model) { super(model); };\n        public void processMouseEvent(MouseEvent e) { super.processMouseEvent(e); }\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/LabelRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.FontMetrics;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport javax.swing.Icon;\nimport javax.swing.JLabel;\nimport javax.swing.plaf.LabelUI;\nimport javax.swing.plaf.basic.BasicLabelUI;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class LabelRenderer extends JLabel {\n\n    private static final LabelRendererUI UI = new LabelRendererUI();\n    private static final int DIRTY = Integer.MIN_VALUE;\n\n    private int x;\n    private int y;\n    private Insets insets = new Insets(0, 0, 0, 0);\n    private Dimension preferredSize;\n\n    private FontMetrics fontMetrics;\n    private String text;\n    private Icon icon;\n    private Color foreground;\n    private boolean enabled;\n\n    private int iconWidth;\n    private int iconHeight;\n    private int iconTextGap;\n    private int textWidth;\n    private int fontAscent;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    public LabelRenderer() {\n        setHorizontalAlignment(LEFT);\n        setVerticalAlignment(TOP);\n        setSize(Integer.MAX_VALUE, Integer.MAX_VALUE);\n\n        setOpaque(false);\n        setEnabled(true);\n\n        iconTextGap = super.getIconTextGap();\n    }\n\n\n    // --- Implementation ------------------------------------------------------\n\n    public Insets getInsets() {\n        return insets;\n    }\n\n    public Insets getInsets(Insets insets) {\n        return this.insets;\n    }\n\n    public void setLocation(int x, int y) {\n        this.x = x;\n        this.y = y;\n    }\n\n    public Dimension getPreferredSize() {\n        if (preferredSize == null) preferredSize = new Dimension(DIRTY, DIRTY);\n\n        if (preferredSize.width == DIRTY) {\n            textWidth = text == null || text.isEmpty() ? 0 : fontMetrics.stringWidth(text);\n            preferredSize.width = iconWidth + textWidth;\n            if (iconWidth > 0 && textWidth > 0) preferredSize.width += iconTextGap;\n        }\n\n        if (preferredSize.height == DIRTY) {\n            fontAscent = fontMetrics.getAscent();\n            preferredSize.height = fontAscent + fontMetrics.getDescent();\n        }\n\n        return preferredSize;\n    }\n\n    public void setUI(LabelUI ui) {\n        super.setUI(UI);\n    }\n\n    private void resetPreferredSize(boolean width, boolean height) {\n        if (preferredSize == null) return;\n        if (width) preferredSize.width = DIRTY;\n        if (height) preferredSize.height = DIRTY;\n    }\n\n    protected void prePaint(Graphics g, int x, int y) {}\n    protected void postPaint(Graphics g, int x, int y) {}\n\n    public void paint(Graphics g) {\n        Graphics cg = getComponentGraphics(g);\n\n        prePaint(cg, x, y);\n\n        int xx = x;\n        if (iconWidth > 0) {\n            int yy = (preferredSize.height - iconHeight) / 2;\n            icon.paintIcon(this, cg, xx, y + yy);\n            xx += iconWidth + iconTextGap;\n        }\n        if (textWidth > 0)\n            UI.paintEnabledText(this, cg, text, xx, y + fontAscent);\n\n        postPaint(cg, x, y);\n    }\n\n\n    // --- Peformance tweaks ---------------------------------------------------\n\n    // Overridden for performance reasons.\n    public void setText(String text) {\n        this.text = text;\n        resetPreferredSize(true, false);\n    }\n\n    // Overridden for performance reasons.\n    public String getText() {\n        return text;\n    }\n\n    // Overridden for performance reasons.\n    public void setIcon(Icon icon) {\n        int oldIconWidth = iconWidth;\n        iconWidth = icon == null ? 0 : icon.getIconWidth();\n        iconHeight = icon == null ? 0 : icon.getIconHeight();\n        this.icon = icon;\n        if (oldIconWidth != iconWidth) resetPreferredSize(true, false);\n    }\n\n    // Overridden for performance reasons.\n    public Icon getIcon() {\n        return icon;\n    }\n\n    // Overridden for performance reasons.\n    public void setForeground(Color foreground) {\n        this.foreground = foreground;\n    }\n\n    // Overridden for performance reasons.\n    public Color getForeground() {\n        return foreground;\n    }\n\n    // Overridden for performance reasons.\n    public void setEnabled(boolean enabled) {\n        this.enabled = enabled;\n    }\n\n    // Overridden for performance reasons.\n    public boolean isEnabled() {\n        return enabled;\n    }\n\n    // Overridden for performance reasons.\n    public int getDisplayedMnemonicIndex() {\n        return -1;\n    }\n\n    // Overridden for performance reasons.\n    public FontMetrics getFontMetrics(Font font) {\n        return fontMetrics;\n    }\n\n    // Overridden for performance reasons.\n    public void setFont(Font font) {\n        super.setFont(font);\n        fontMetrics = super.getFontMetrics(font);\n        resetPreferredSize(true, true);\n    }\n\n    // Overridden for performance reasons.\n    public int getIconTextGap() {\n        return iconTextGap;\n    }\n\n\n    // Overridden for performance reasons.\n    public void setIconTextGap(int iconTextGap) {\n        this.iconTextGap = iconTextGap;\n        resetPreferredSize(true, false);\n    }\n\n    // Overridden for performance reasons.\n    public void validate() {}\n\n    // Overridden for performance reasons.\n    public void revalidate() {}\n\n    // Overridden for performance reasons.\n    public void repaint(long tm, int x, int y, int width, int height) {}\n\n    // Overridden for performance reasons.\n    public void repaint(Rectangle r) {}\n\n    // Overridden for performance reasons.\n    public void repaint() {}\n\n    // Overridden for performance reasons.\n    public void setDisplayedMnemonic(int key) {}\n\n    // Overridden for performance reasons.\n    public void setDisplayedMnemonic(char aChar) {}\n\n    // Overridden for performance reasons.\n    public void setDisplayedMnemonicIndex(int index) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, char oldValue, char newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, short oldValue, short newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, int oldValue, int newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, long oldValue, long newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, float oldValue, float newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, double oldValue, double newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}\n\n    // Overridden for performance reasons.\n    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}\n\n\n    private static class LabelRendererUI extends BasicLabelUI {\n        protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) {\n            super.paintEnabledText(l, g, s, textX, textY);\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/LegendFont.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport java.awt.Color;\nimport java.awt.Font;\nimport javax.swing.JLabel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class LegendFont extends Font {\n\n    public static final Color FOREGROUND_COLOR = new Color(100, 100, 100);\n    public static final Color BACKGROUND_COLOR = new Color(255, 255, 255);\n\n    private static final Font baseFont = baseFont();\n\n\n    public LegendFont() {\n        super(baseFont);\n    }\n\n\n    private static Font baseFont() {\n        Font font = new JLabel().getFont();\n        return new Font(font.getName(), font.getStyle(), font.getSize() - 2);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/ScrollBar.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport java.awt.Insets;\nimport javax.swing.BorderFactory;\nimport javax.swing.JScrollBar;\n\n/**\n * Use only for creating ScrollBars which mimic insets of JScrollPane's SBs.\n *\n * @author Jiri Sedlacek\n */\npublic class ScrollBar extends JScrollBar {\n\n    public ScrollBar(int orientation) {\n        super(orientation);\n\n        if (UISupport.isGTKLookAndFeel()) {\n            Insets insets = getBorder().getBorderInsets(this);\n            // Typically the insets are 2 for GTK themes except for Nimbus theme\n            // which uses 3 and requires 1 (other themes seem to require 0). Lets\n            // lower the insets to mimic JScrollBars used in JScrollPanes.\n            setBorder(BorderFactory.createEmptyBorder(Math.max(insets.top - 2, 0),\n                                                    Math.max(insets.left - 2, 0),\n                                                    Math.max(insets.bottom - 2, 0),\n                                                    Math.max(insets.right - 2, 0)\n                                                   ));\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/SimpleSeparator.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport javax.swing.JPanel;\nimport javax.swing.SwingConstants;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class SimpleSeparator extends JPanel implements SwingConstants {\n\n    private final int orientation;\n    private final Dimension preferredSize = new Dimension(1, 1);\n\n\n    public SimpleSeparator() {\n        this(HORIZONTAL);\n    }\n\n    public SimpleSeparator(int orientation) {\n        super(null);\n        this.orientation = orientation;\n    }\n\n\n    public void setPreferredSize(Dimension preferredSize) {\n        this.preferredSize.width = preferredSize.width;\n        this.preferredSize.height = preferredSize.height;\n    }\n\n\n    public Dimension getMinimumSize() {\n        Insets insets = getInsets();\n        if (orientation == HORIZONTAL)\n            return new Dimension(insets.left + insets.right,\n                                 insets.top + insets.bottom + 1);\n        else\n            return new Dimension(insets.left + insets.right + 1,\n                                 insets.top + insets.bottom);\n    }\n\n    public Dimension getMaximumSize() {\n        Insets insets = getInsets();\n        if (orientation == HORIZONTAL)\n            return new Dimension(Integer.MAX_VALUE,\n                                 insets.top + insets.bottom + 1);\n        else\n            return new Dimension(insets.left + insets.right + 1,\n                                 Integer.MAX_VALUE);\n    }\n\n    public Dimension getPreferredSize() {\n        Insets insets = getInsets();\n        if (orientation == HORIZONTAL)\n            return new Dimension(Math.max(insets.left + insets.right, preferredSize.width),\n                                 insets.top + insets.bottom + 1);\n        else\n            return new Dimension(insets.left + insets.right + 1,\n                                 Math.max(insets.top + insets.bottom, preferredSize.height));\n    }\n\n\n    public void paint(Graphics g) {\n        g.setColor(new Color(192, 192, 192));\n        Insets insets = getInsets();\n        if (orientation == HORIZONTAL)\n            g.drawLine(insets.left, insets.top, getWidth() - insets.right, insets.top);\n        else\n            g.drawLine(insets.left, insets.top, insets.left, getHeight() - insets.bottom);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/TimelineMarksPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport java.awt.Component;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMark;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimeAxisUtils;\nimport org.graalvm.visualvm.lib.charts.axis.TimeMark;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class TimelineMarksPainter extends LabelRenderer implements AxisMarksPainter {\n\n    public TimelineMarksPainter() {\n        super();\n        setFont(new LegendFont());\n    }\n\n    public Component getPainter(AxisMark mark) {\n        setText(TimeAxisUtils.formatTime((TimeMark)mark));\n        return this;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/swing/VisibilityHandler.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.swing;\n\nimport java.awt.Component;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class VisibilityHandler {\n\n    private Component component;\n    private boolean wasVisible;\n\n    private HierarchyListener listener;\n\n\n    public VisibilityHandler() {}\n\n    public abstract void shown();\n    public abstract void hidden();\n\n\n    public final void handle(Component component) {\n        if (component == null)\n            throw new NullPointerException(\"component cannot be null\"); // NOI18N\n\n        if (listener != null && component != null)\n            component.removeHierarchyListener(listener);\n\n        this.component = component;\n        wasVisible = component.isVisible();\n\n        if (listener == null) listener = createListener();\n        component.addHierarchyListener(listener);\n    }\n\n\n    private HierarchyListener createListener() {\n        return new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    boolean visible = component.isShowing();\n                    if (wasVisible == visible) return;\n\n                    wasVisible = visible;\n\n                    if (visible) shown();\n                    else hidden();\n                }\n            }\n        };\n    }\n\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/ChartPanel.java",
    "content": "/*\n *  Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport org.graalvm.visualvm.modules.tracer.impl.options.TracerOptions;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.ScrollBar;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.AdjustmentEvent;\nimport java.awt.event.AdjustmentListener;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseWheelEvent;\nimport java.awt.event.MouseWheelListener;\nimport javax.swing.AbstractAction;\nimport javax.swing.AbstractButton;\nimport javax.swing.Action;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ChartPanel extends JPanel {\n\n    private static final String ZOOM_IN_STRING = \"Zoom in\"; //\"Zoom In (Mouse Wheel)\";\n    private static final String ZOOM_OUT_STRING = \"Zoom out\"; //\"Zoom Out (Mouse Wheel)\";\n    private static final String FIXED_SCALE_STRING = \"Fixed scale\"; //\"Fixed Scale (Mouse Wheel Click)\";\n    private static final String SCALE_TO_FIT_STRING = \"Scale to fit\"; //\"Scale To Fit (Mouse Wheel Click)\";\n\n    private static final Icon ZOOM_IN_ICON = new ImageIcon(ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/zoomIn.png\")); // NOI18N\n    private static final Icon ZOOM_OUT_ICON = new ImageIcon(ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/zoomOut.png\")); // NOI18N\n    private static final Icon FIXED_SCALE_ICON = new ImageIcon(ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/zoom.png\")); // NOI18N\n    private static final Icon SCALE_TO_FIT_ICON = new ImageIcon(ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/scaleToFit.png\")); // NOI18N\n    private static final Icon ZMWHEEL_ICON = new ImageIcon(ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/zmwheel.png\")); // NOI18N\n    private static final Icon HMWHEEL_ICON = new ImageIcon(ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/hmwheel.png\")); // NOI18N\n    private static final Icon VMWHEEL_ICON = new ImageIcon(ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/vmwheel.png\")); // NOI18N\n\n\n    private final TimelineChart chart;\n\n    private ZoomInAction zoomInAction;\n    private ZoomOutAction zoomOutAction;\n    private ToggleViewAction toggleViewAction;\n\n    private final JScrollBar hScrollBar;\n    private final JScrollBar vScrollBar;\n    private final MouseWheelListener defaultWheelHandler;\n    private AbstractButton mouseZoom;\n    private AbstractButton mouseHScroll;\n    private AbstractButton mouseVScroll;\n\n\n    ChartPanel(TimelineChart chart, TimelineSupport support) {\n        this.chart = chart;\n\n        boolean speed = Utils.forceSpeed();\n\n        chart.setBackground(Color.WHITE);\n        if (speed && TracerOptions.getInstance().isRowsSelectionEnabled())\n            chart.addPreDecorator(new RowBackgroundDecorator(chart));\n        chart.addPreDecorator(new RowBoundsDecorator(chart));\n        chart.addPostDecorator(new RowForegroundDecorator(chart,\n                TracerOptions.getInstance().isRowsDecorationEnabled(),\n                speed ? false : TracerOptions.getInstance().isRowsSelectionEnabled()));\n\n        TimelineSelectionOverlay selectionOverlay = new TimelineSelectionOverlay();\n        chart.addOverlayComponent(selectionOverlay);\n        selectionOverlay.registerChart(support);\n\n        ChartSelectionModel selectionModel = chart.getSelectionModel();\n        if (selectionModel != null) {\n            selectionModel.setHoverMode(ChartSelectionModel.HOVER_EACH_NEAREST);\n            selectionModel.setMoveMode(ChartSelectionModel.SELECTION_LINE_V);\n        }\n        \n        TimelineAxis axis = new TimelineAxis(chart, support);\n        \n        hScrollBar = new ScrollBar(JScrollBar.HORIZONTAL);\n        hScrollBar.addAdjustmentListener(new AdjustmentListener() {\n            public void adjustmentValueChanged(AdjustmentEvent e) {\n                if (hScrollBar.getValueIsAdjusting())\n                    ChartPanel.this.chart.updateSelection(false, hScrollBar);\n                else\n                    ChartPanel.this.chart.updateSelection(true, hScrollBar);\n            }\n        });\n        chart.attachHorizontalScrollBar(hScrollBar);\n\n        vScrollBar = new ScrollBar(JScrollBar.VERTICAL);\n        vScrollBar.addAdjustmentListener(new AdjustmentListener() {\n            public void adjustmentValueChanged(AdjustmentEvent e) {\n                if (vScrollBar.getValueIsAdjusting())\n                    ChartPanel.this.chart.updateSelection(false, vScrollBar);\n                else\n                    ChartPanel.this.chart.updateSelection(true, vScrollBar);\n            }\n        });\n        chart.attachVerticalScrollBar(vScrollBar);\n        \n        defaultWheelHandler = chart.getMouseWheelListeners()[0];\n\n        chart.addConfigurationListener(new VisibleBoundsListener());\n\n        setOpaque(false);\n        setLayout(new BorderLayout());\n        add(axis, BorderLayout.NORTH);\n        add(chart, BorderLayout.CENTER);\n        add(vScrollBar, BorderLayout.EAST);\n        add(hScrollBar, BorderLayout.SOUTH);\n\n        resetChart();\n    }\n\n\n    // --- Internal interface --------------------------------------------------\n\n    void resetChart() {\n        chart.setScale(0.02, 1);\n        chart.setOffset(0, 0);\n    }\n\n    boolean resetSelection() {\n        if (chart.isRowSelection()) {\n            chart.clearRowsSelection();\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n\n    Action zoomInAction() {\n        if (zoomInAction == null) zoomInAction = new ZoomInAction();\n        return zoomInAction;\n    }\n\n    Action zoomOutAction() {\n        if (zoomOutAction == null) zoomOutAction = new ZoomOutAction();\n        return zoomOutAction;\n    }\n\n    Action toggleViewAction() {\n        if (toggleViewAction == null) {\n            toggleViewAction = new ToggleViewAction();\n            if (TracerOptions.getInstance().getZoomMode().equals(TracerOptions.\n                    SCALE_TO_FIT)) toggleViewAction.actionPerformed(null);\n        }\n        return toggleViewAction;\n    }\n\n\n    AbstractButton mouseZoom() {\n        if (mouseZoom == null) {\n            mouseZoom = new OneWayToggleButton(ZMWHEEL_ICON, \"Mouse wheel zooms\") {\n                protected void performAction() { mouseZoomImpl(); }\n            };\n            if (TracerOptions.getInstance().getMouseWheelAction().equals(\n                    TracerOptions.MOUSE_WHEEL_ZOOMS)) {\n                mouseZoom.setSelected(true);\n                mouseZoomImpl();\n            }\n        }\n        return mouseZoom;\n    }\n\n    AbstractButton mouseHScroll() {\n        if (mouseHScroll == null) {\n            mouseHScroll = new OneWayToggleButton(HMWHEEL_ICON, \"Mouse wheel scrolls horizontally\") {\n                protected void performAction() { mouseHScrollImpl(); }\n            };\n            if (TracerOptions.getInstance().getMouseWheelAction().equals(\n                    TracerOptions.MOUSE_WHEEL_HSCROLLS)) {\n                mouseHScroll.setSelected(true);\n                mouseHScrollImpl();\n            }\n        }\n        return mouseHScroll;\n    }\n\n    AbstractButton mouseVScroll() {\n        if (mouseVScroll == null) {\n            mouseVScroll = new OneWayToggleButton(VMWHEEL_ICON, \"Mouse wheel scrolls vertically\") {\n                protected void performAction() { mouseVScrollImpl(); }\n            };\n            if (TracerOptions.getInstance().getMouseWheelAction().equals(\n                    TracerOptions.MOUSE_WHEEL_VSCROLLS)) {\n                mouseVScroll.setSelected(true);\n                mouseVScrollImpl();\n            }\n        }\n        return mouseVScroll;\n    }\n\n\n    // --- Mouse wheel handling ------------------------------------------------\n\n    void vScroll(MouseWheelEvent e) {\n        scroll(vScrollBar, e);\n    }\n\n    private void mouseZoomImpl() {\n        clearWheelHandlers();\n        chart.setMouseZoomingEnabled(true);\n        chart.addMouseWheelListener(defaultWheelHandler);\n    }\n\n    private void mouseHScrollImpl() {\n        chart.setMouseZoomingEnabled(false);\n        clearWheelHandlers();\n        setWheelScrollHandler(hScrollBar);\n    }\n\n    private void mouseVScrollImpl() {\n        chart.setMouseZoomingEnabled(false);\n        clearWheelHandlers();\n        setWheelScrollHandler(vScrollBar);\n    }\n\n    private void clearWheelHandlers() {\n        MouseWheelListener[] handlers = chart.getMouseWheelListeners();\n        for (MouseWheelListener handler : handlers)\n            chart.removeMouseWheelListener(handler);\n    }\n\n    private void setWheelScrollHandler(final JScrollBar scrollBar) {\n        chart.addMouseWheelListener(new MouseWheelListener() {\n            public void mouseWheelMoved(MouseWheelEvent e) {\n                scroll(scrollBar, e);\n            }\n        });\n    }\n\n    private static void scroll(JScrollBar scrollBar, MouseWheelEvent e) {\n        if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {\n            int unitsToScroll = e.getUnitsToScroll();\n            if (unitsToScroll != 0) {\n                int direction = unitsToScroll < 0 ? -1 : 1;\n                int increment = scrollBar.getUnitIncrement(direction);\n                int oldValue = scrollBar.getValue();\n                int newValue = oldValue + increment * unitsToScroll;\n                newValue = Math.max(Math.min(newValue, scrollBar.getMaximum() -\n                        scrollBar.getVisibleAmount()), scrollBar.getMinimum());\n                if (oldValue != newValue) scrollBar.setValue(newValue);\n            }\n        }\n    }\n\n\n    // --- Actions support -----------------------------------------------------\n\n    private class ZoomInAction extends AbstractAction {\n\n        private static final int ONE_SECOND_WIDTH_THRESHOLD = 200;\n\n        public ZoomInAction() {\n            super();\n\n            putValue(SHORT_DESCRIPTION, ZOOM_IN_STRING);\n            putValue(SMALL_ICON, ZOOM_IN_ICON);\n\n            updateAction();\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            boolean followsWidth = chart.currentlyFollowingDataWidth();\n            chart.zoom(getWidth() / 2, getHeight() / 2, 2d);\n            if (followsWidth) chart.setOffset(chart.maxOffsetX(), chart.getOffsetY());\n\n            chart.repaintDirty();\n        }\n\n        private void updateAction() {\n            Timeline timeline = ((SynchronousXYItemsModel)chart.getItemsModel()).getTimeline();\n            setEnabled(timeline.getTimestampsCount() > 1 && !chart.fitsWidth() &&\n                       chart.viewWidth(1000) < ONE_SECOND_WIDTH_THRESHOLD);\n        }\n\n    }\n\n    private class ZoomOutAction extends AbstractAction {\n\n        private static final float USED_CHART_WIDTH_THRESHOLD = 0.33f;\n\n        public ZoomOutAction() {\n            super();\n\n            putValue(SHORT_DESCRIPTION, ZOOM_OUT_STRING);\n            putValue(SMALL_ICON, ZOOM_OUT_ICON);\n\n            updateAction();\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            boolean followsWidth = chart.currentlyFollowingDataWidth();\n            chart.zoom(getWidth() / 2, getHeight() / 2, 0.5d);\n            if (followsWidth) chart.setOffset(chart.maxOffsetX(), chart.getOffsetY());\n\n            chart.repaintDirty();\n        }\n\n        private void updateAction() {\n            Timeline timeline = ((SynchronousXYItemsModel)chart.getItemsModel()).getTimeline();\n            setEnabled(timeline.getTimestampsCount() > 0 && !chart.fitsWidth() &&\n                       chart.getContentsWidth() > getWidth() * USED_CHART_WIDTH_THRESHOLD);\n        }\n\n    }\n\n    private class ToggleViewAction extends AbstractAction {\n\n        private long origOffsetX  = -1;\n        private double origScaleX = -1;\n\n        public ToggleViewAction() {\n            super();\n            updateAction();\n            addMouseListener(new MouseAdapter() {\n                public void mouseClicked(MouseEvent e) {\n                    if (SwingUtilities.isMiddleMouseButton(e))\n                        actionPerformed(null);\n                }\n            });\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            boolean fitsWidth = chart.fitsWidth();\n\n            if (!fitsWidth) {\n                origOffsetX = chart.getOffsetX();\n                if (chart.tracksDataWidth() && origOffsetX == chart.maxOffsetX())\n                    origOffsetX = Long.MAX_VALUE;\n                origScaleX  = chart.getScaleX();\n            }\n\n            chart.setFitsWidth(!fitsWidth);\n\n            if (fitsWidth && origOffsetX != -1 && origScaleX != -1) {\n                chart.setScale(origScaleX, chart.getScaleY());\n                chart.setOffset(origOffsetX, chart.getOffsetY());\n            }\n\n            updateAction();\n            if (zoomInAction != null) zoomInAction.updateAction();\n            if (zoomOutAction != null) zoomOutAction.updateAction();\n\n            chart.repaintDirty();\n\n        }\n\n        private void updateAction() {\n            boolean fitsWidth = chart.fitsWidth();\n            Icon icon = fitsWidth ? FIXED_SCALE_ICON : SCALE_TO_FIT_ICON;\n            String name = fitsWidth ? FIXED_SCALE_STRING : SCALE_TO_FIT_STRING;\n            putValue(SHORT_DESCRIPTION, name);\n            putValue(SMALL_ICON, icon);\n        }\n\n    }\n\n\n    private static abstract class OneWayToggleButton extends JToggleButton {\n\n        private boolean action;\n\n\n        public OneWayToggleButton(Icon icon, String toolTip) {\n            super(icon);\n            setToolTipText(toolTip);\n        }\n\n        protected void processMouseEvent(MouseEvent e) {\n            if (isSelected()) {\n                e.consume();\n                action = false;\n            } else {\n                action = true;\n            }\n            super.processMouseEvent(e);\n        }\n\n        protected void processKeyEvent(KeyEvent e) {\n            if (isSelected()) {\n                e.consume();\n                action = false;\n            } else {\n                action = true;\n            }\n            super.processKeyEvent(e);\n        }\n\n        protected final void fireActionPerformed(ActionEvent e) {\n            if (action) performAction();\n        }\n\n        protected abstract void performAction();\n\n    }\n\n\n    // --- ChartConfigurationListener implementation ---------------------------\n\n    private class VisibleBoundsListener extends ChartConfigurationListener.Adapter {\n\n        public void dataBoundsChanged(long dataOffsetX, long dataOffsetY,\n                                      long dataWidth, long dataHeight,\n                                      long oldDataOffsetX, long oldDataOffsetY,\n                                      long oldDataWidth, long oldDataHeight) {\n\n            if (zoomInAction != null) zoomInAction.updateAction();\n            if (zoomOutAction != null) zoomOutAction.updateAction();\n        }\n\n        public void scaleChanged(double oldScaleX, double oldScaleY,\n                                 double newScaleX, double newScaleY) {\n\n            if (zoomInAction != null) zoomInAction.updateAction();\n            if (zoomOutAction != null) zoomOutAction.updateAction();\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/ContinuousXYPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Polygon;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ContinuousXYPainter extends TimelineXYPainter {\n\n    private static final Polygon POLYGON = new Polygon();\n    \n    protected final int lineWidth;\n    protected final Color lineColor;\n    protected final Color fillColor;\n    protected final Color definingColor;\n\n    protected final Stroke lineStroke;\n\n    private final PointsComputer computer;\n\n\n    ContinuousXYPainter(float lineWidth, Color lineColor, Color fillColor,\n                        double dataFactor, PointsComputer computer) {\n\n        super((int)Math.ceil(lineWidth), fillColor != null, dataFactor);\n\n        if (lineColor == null && fillColor == null)\n            throw new IllegalArgumentException(\"lineColor or fillColor must not be null\"); // NOI18N\n\n        this.lineWidth = (int)Math.ceil(lineWidth);\n        this.lineColor = Utils.checkedColor(lineColor);\n        this.fillColor = Utils.checkedColor(fillColor);\n\n        definingColor = lineColor != null ? lineColor : fillColor;\n\n        this.lineStroke = new BasicStroke(lineWidth, BasicStroke.CAP_ROUND,\n                                          BasicStroke.JOIN_ROUND);\n\n        this.computer = computer;\n    }\n\n\n    protected Color getDefiningColor() {\n        return definingColor;\n    }\n\n    protected void paint(XYItem item, List<ItemSelection> highlighted,\n                         List<ItemSelection> selected, Graphics2D g,\n                         Rectangle dirtyArea, SynchronousXYChartContext context) {\n\n        int valuesCount = item.getValuesCount();\n        int extraTrailing = fillColor != null ? 2 : 0;\n\n        Rectangle dirtyExt = new Rectangle(dirtyArea);\n        dirtyExt.x -= lineWidth;\n        dirtyExt.width += lineWidth * 2;\n\n        int[][] idxs = computer.getVisible(dirtyExt, valuesCount, context, 1,\n                                           extraTrailing);\n        if (idxs == null) return;\n        int[] visibleIndexes = idxs[0];\n        int npoints = idxs[1][0];\n        int[][] points = computer.createPoints(visibleIndexes, npoints, item,\n                                               dataFactor, context);\n        \n        if (fillColor != null) {\n            points[0][npoints - 2] = points[0][npoints - 3];\n            points[1][npoints - 2] = computer.getZeroY(context);\n            points[0][npoints - 1] = points[0][0];\n            points[1][npoints - 1] = points[1][npoints - 2];\n\n            POLYGON.xpoints = points[0];\n            POLYGON.ypoints = points[1];\n            POLYGON.npoints = npoints;\n\n            g.setPaint(fillColor);\n            g.fill(POLYGON);\n        }\n\n        if (lineColor != null) {\n            g.setPaint(lineColor);\n            g.setStroke(lineStroke);\n            g.drawPolyline(points[0], points[1], npoints - extraTrailing);\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/DiscreteXYPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Polygon;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class DiscreteXYPainter extends TimelineXYPainter {\n\n    private static final Polygon POLYGON = new Polygon();\n\n    private static final int[] x3arr = new int[3];\n    private static final int[] y3arr = new int[3];\n    private static final int[] x4arr = new int[4];\n    private static final int[] y4arr = new int[4];\n\n    protected final int lineWidth;\n    protected final Color lineColor;\n    protected final Color fillColor;\n    protected final Color definingColor;\n\n    protected final Stroke lineStroke;\n\n    protected final int width;\n    protected final boolean fixedWidth;\n    protected final boolean topLineOnly;\n    protected final boolean outlineOnly;\n\n    private final PointsComputer computer;\n\n\n    DiscreteXYPainter(float lineWidth, Color lineColor, Color fillColor,\n                      int width, boolean fixedWidth, boolean topLineOnly,\n                      boolean outlineOnly, double dataFactor, PointsComputer computer) {\n\n        super((int)Math.ceil(lineWidth), fillColor != null ||\n              (!topLineOnly && !outlineOnly), dataFactor);\n        \n        if (lineColor == null && fillColor == null)\n            throw new IllegalArgumentException(\"lineColor or fillColor must not be null\"); // NOI18N\n\n        this.lineWidth = (int)Math.ceil(lineWidth);\n        this.lineColor = Utils.checkedColor(lineColor);\n        this.fillColor = Utils.checkedColor(fillColor);\n\n        definingColor = lineColor != null ? lineColor : fillColor;\n\n        this.lineStroke = new BasicStroke(lineWidth, BasicStroke.CAP_ROUND,\n                                          BasicStroke.JOIN_ROUND);\n\n        this.width = width;\n        this.fixedWidth = fixedWidth;\n        this.topLineOnly = topLineOnly;\n        this.outlineOnly = outlineOnly;\n\n        this.computer = computer;\n    }\n\n    \n    protected Color getDefiningColor() {\n        return definingColor;\n    }\n\n    protected void paint(XYItem item, List<ItemSelection> highlighted,\n                         List<ItemSelection> selected, Graphics2D g,\n                         Rectangle dirtyArea, SynchronousXYChartContext context) {\n\n        int zeroY = 0;\n        int zeroYLimit = 0;\n        if (fillColor != null || !topLineOnly) {\n            zeroY = Utils.checkedInt(context.getViewY(context.getDataOffsetY()));\n            zeroY = Math.max(Utils.checkedInt(context.getViewportOffsetY()), zeroY);\n            zeroY = Math.min(Utils.checkedInt(context.getViewportOffsetY() +\n                                              context.getViewportHeight()), zeroY);\n            zeroYLimit = zeroY - lineWidth + 1;\n        }\n\n        int outlineWidth = lineColor == null || topLineOnly || outlineOnly ? 0 :\n                           Math.max(1, (width > 0 ? 2 : 1) * lineWidth - 1);\n        int valuesCount = item.getValuesCount();\n\n        Rectangle dirtyExt = new Rectangle(dirtyArea);\n        dirtyExt.x -= lineWidth;\n        dirtyExt.width += lineWidth * 2;\n\n        if (width > 0 || lineColor == null || topLineOnly) {\n\n            int[][] idxs = computer.getVisible(dirtyExt, valuesCount, context,\n                                               1, 0);\n            if (idxs == null) return;\n            int[] visibleIndexes = idxs[0];\n            int npoints = idxs[1][0];\n            int[][] points = computer.createPoints(visibleIndexes, npoints, item,\n                                                   dataFactor, context);\n            int[] xpoints = points[0];\n            int[] ypoints = points[1];\n            \n\n            int startX = xpoints[0];\n            int stopX;\n            int currentX = startX;\n            int nextX = 0;\n            int itemsOffset = fixedWidth ? 0 : width;\n            \n            for (int i = 0; i < npoints; i++) {\n                int height = zeroY - ypoints[i];\n\n                if (fixedWidth) {\n                    startX = Math.max(startX, currentX - width / 2);\n                    nextX = i == npoints - 1 ? xpoints[i] : xpoints[i + 1];\n                    stopX = currentX + Math.min(width / 2, (nextX - currentX) / 2);\n                } else {\n                    nextX = i == npoints - 1 ? xpoints[i] : xpoints[i + 1];\n                    int diff = nextX - currentX;\n                    itemsOffset = Math.min(diff, width + 1);\n                    stopX = currentX + (diff - itemsOffset) / 2;\n                }\n\n                int segmentWidth = stopX - startX;\n\n                if (fillColor != null && segmentWidth >= outlineWidth) {\n                    g.setColor(fillColor);\n                    g.fillRect(startX, zeroY - height, segmentWidth + 1, height);\n                }\n                if (lineColor != null) {\n                    g.setColor(lineColor);\n                    g.setStroke(lineStroke);\n\n                    if (topLineOnly) {\n                        g.drawLine(startX, zeroY - height, Math.max(startX + 1, stopX), zeroY - height);\n                    } else if (segmentWidth + 1 <= lineWidth) {\n                        g.drawLine(startX, zeroY - height, startX, zeroYLimit);\n                    } else {\n                        int[] xx;\n                        int[] yy;\n\n                        if (i == 0) {\n                            xx = xArr(startX, stopX, stopX);\n                            yy = yArr(zeroY - height, zeroY - height, zeroYLimit);\n                        } else if (i == npoints - 1) {\n                            xx = xArr(startX, startX, stopX);\n                            yy = yArr(zeroYLimit, zeroY - height, zeroY - height);\n                        } else {\n                            xx = xArr(startX, startX, stopX, stopX);\n                            yy = yArr(zeroYLimit, zeroY - height, zeroY - height, zeroYLimit);\n                        }\n\n                        g.drawPolyline(xx, yy, xx.length);\n                    }\n                }\n                \n                currentX = nextX;\n                startX = stopX + itemsOffset;\n            }\n\n        } else {\n\n            int extraPoints = fillColor != null ? 2 : 0;\n            int[][] idxs = computer.getVisible(dirtyExt, valuesCount, context,\n                                               2, extraPoints);\n            if (idxs == null) return;\n            int[] visibleIndexes = idxs[0];\n            int npoints = idxs[1][0];\n            int[][] points = computer.createPoints(visibleIndexes, npoints, item,\n                                                   dataFactor, context);\n            int[] xpoints = points[0];\n            int[] ypoints = points[1];\n            int npointse = npoints;\n            npoints -= extraPoints;\n            \n            int index = 1;\n            int lastX = xpoints[0];\n\n            while (index < npoints - 2) {\n                int currentX = xpoints[index + 1];\n                currentX -= (currentX - lastX) / 2;\n                xpoints[index] = currentX;\n                lastX = xpoints[index + 1];\n                xpoints[index + 1] = currentX;\n                index += 2;\n            }\n\n            if (fillColor != null) {\n                xpoints[npointse - 2] = xpoints[npointse - 3];\n                ypoints[npointse - 2] = zeroY;\n                xpoints[npointse - 1] = xpoints[0];\n                ypoints[npointse - 1] = ypoints[npointse - 2];\n\n                POLYGON.xpoints = xpoints;\n                POLYGON.ypoints = ypoints;\n                POLYGON.npoints = npointse;\n\n                g.setPaint(fillColor);\n                g.fill(POLYGON);\n            }\n\n            g.setColor(lineColor);\n            g.setStroke(lineStroke);\n            g.drawPolyline(xpoints, ypoints, npoints);\n\n            if (!outlineOnly) {\n                g.setColor(lineColor);\n                g.setStroke(lineStroke);\n\n                int i = 1;\n                while (i < npoints - 1) {\n                    int y = ypoints[i] + lineWidth / 2;\n                    if (y < zeroYLimit) g.drawLine(xpoints[i], y, xpoints[i], zeroYLimit);\n                    i += 3;\n                    if (i >= npoints - 1) break;\n                    y = ypoints[i] + lineWidth / 2;\n                    if (y < zeroYLimit) g.drawLine(xpoints[i], y, xpoints[i], zeroYLimit);\n                    i++;\n                }\n            }\n\n        }\n    }\n    \n    private static int[] xArr(int... vals) {\n        if (vals.length == 3) {\n            x3arr[0] = vals[0];\n            x3arr[1] = vals[1];\n            x3arr[2] = vals[2];\n            return x3arr;\n        } else {\n            x4arr[0] = vals[0];\n            x4arr[1] = vals[1];\n            x4arr[2] = vals[2];\n            x4arr[3] = vals[3];\n            return x4arr;\n        }\n    }\n\n    private static int[] yArr(int... vals) {\n        if (vals.length == 3) {\n            y3arr[0] = vals[0];\n            y3arr[1] = vals[1];\n            y3arr[2] = vals[2];\n            return y3arr;\n        } else {\n            y4arr[0] = vals[0];\n            y4arr[1] = vals[1];\n            y4arr[2] = vals[2];\n            y4arr[3] = vals[3];\n            return y4arr;\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/PointsComputer.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport java.awt.Rectangle;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class PointsComputer {\n\n    private static final int INDEXES_STEP = 1000;\n\n    private int[] arr1;\n    private int[] arr2;\n    private final int[] count = new int[1];\n    private final int[][] ret = new int[2][];\n\n\n    PointsComputer() {}\n\n\n    void reset() {\n        arr1 = null;\n        arr2 = null;\n    }\n\n    private int[] arr1(int size) {\n        if (arr1 == null || arr1.length < size)\n            arr1 = newArr(size + INDEXES_STEP, true);\n        return arr1;\n    }\n    \n    private int[] arr2(int size) {\n        if (arr2 == null || arr2.length < size)\n            arr2 = newArr(size + INDEXES_STEP, false);\n        return arr2;\n    }\n\n    private int[] newArr(int size, boolean arr1) {\n        int[] arr = new int[size];\n        if (arr1) ret[0] = arr;\n        return arr;\n    }\n\n\n    int[][] getVisible(Rectangle dirtyArea, int valuesCount,\n                       SynchronousXYChartContext context,\n                       int extraFactor, int extraTrailing) {\n\n        if (context.getViewWidth() == 0) return null;\n        \n        int[][] visibleBounds = context.getVisibleBounds(dirtyArea);\n\n        int firstFirst = visibleBounds[0][0];\n        int firstIndex = firstFirst;\n        if (firstIndex == -1) firstIndex = visibleBounds[0][1];\n        if (firstIndex == -1) return null;\n        // firstIndex - 2: workaround for polyline joins\n        if (firstFirst != -1) firstIndex = Math.max(firstIndex - 2, 0);\n\n        int lastFirst = visibleBounds[1][0];\n        int lastIndex = lastFirst;\n        if (lastIndex == -1) lastIndex = visibleBounds[1][1];\n        if (lastIndex == -1) lastIndex = valuesCount - 1;\n        // lastIndex + 2: workaround for polyline joins\n        if (lastFirst != -1) lastIndex = Math.min(lastIndex + 2, valuesCount - 1);\n\n        int itemsStep = (int)Math.ceil(valuesCount / context.getViewWidth());\n        if (itemsStep == 0) itemsStep = 1;\n\n        int visibleCount = lastIndex - firstIndex + 1;\n\n        if (itemsStep > 1) {\n            int firstMod = firstIndex % itemsStep;\n            firstIndex -= firstMod;\n            int lastMod = lastIndex % itemsStep;\n            lastIndex = lastIndex - lastMod + itemsStep;\n            visibleCount = (lastIndex - firstIndex) / itemsStep + 1;\n            lastIndex = Math.min(lastIndex, valuesCount - 1);\n        }\n\n        int visibleCountEx = extraFactor == 1 ? visibleCount :\n                            (visibleCount - 1) * extraFactor + 2;\n\n        count[0] = visibleCountEx + extraTrailing;\n        int[] visibleIndexes = arr1(count[0]);\n\n        for (int i = 0; i < visibleCountEx; i++) {\n            int index = firstIndex + (i / extraFactor) * itemsStep;\n            if (index > lastIndex) index = lastIndex;\n            visibleIndexes[i] = index;\n        }\n        \n        for (int i = visibleCountEx; i < visibleIndexes.length; i++)\n            visibleIndexes[i] = -1;\n\n        ret[1] = count;\n        return ret;\n    }\n\n    int getZeroY(SynchronousXYChartContext context) {\n        int zeroY = Utils.checkedInt(context.getViewY(context.getDataOffsetY()));\n        zeroY = Math.max(Utils.checkedInt(context.getViewportOffsetY()), zeroY);\n        zeroY = Math.min(Utils.checkedInt(context.getViewportOffsetY() +\n                                          context.getViewportHeight()), zeroY);\n        return zeroY;\n    }\n\n    int[][] createPoints(int[] indexes, int itemsCount, XYItem item,\n                         double dataFactor, SynchronousXYChartContext context) {\n\n        int[] xPoints = indexes;\n        int[] yPoints = arr2(itemsCount);\n\n        for (int i = 0; i < itemsCount; i++) {\n            int dataIndex = xPoints[i];\n            if (dataIndex != -1) {\n                xPoints[i] = Utils.checkedInt(Math.ceil(\n                             context.getViewX(item.getXValue(dataIndex))));\n                yPoints[i] = Utils.checkedInt(Math.ceil(\n                             context.getViewY(item.getYValue(dataIndex) *\n                             dataFactor)));\n            }\n        }\n\n        ret[1] = yPoints;\n        return ret;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/ProbesPanel.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.impl.probes.ProbePresenter;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.HeaderButton;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.HeaderLabel;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.ScrollBar;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.GridLayout;\nimport java.awt.LayoutManager;\nimport java.awt.Point;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseEvent;\nimport java.util.List;\nimport javax.swing.ImageIcon;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.JViewport;\nimport javax.swing.SwingUtilities;\nimport javax.swing.ToolTipManager;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ProbesPanel extends JPanel {\n    \n    private static final String INCREMENT_IMAGE_PATH =\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/increment.png\"; // NOI18N\n    private static final String DECREMENT_IMAGE_PATH =\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/decrement.png\"; // NOI18N\n    private static final String RESET_IMAGE_PATH =\n            \"org/graalvm/visualvm/modules/tracer/impl/resources/reset.png\"; // NOI18N\n\n    private final ListPanel listPanel;\n    private final JViewport viewport;\n    private final HeaderButton increaseB;\n    private final HeaderButton decreaseB;\n    private final HeaderButton resetB;\n\n    ProbesPanel(final TimelineSupport support) {\n        final TimelineChart chart = support.getChart();\n\n        listPanel = new ListPanel(new VerticalTimelineLayout(chart)) {\n            public Dimension getPreferredSize() {\n                Dimension d = super.getPreferredSize();\n                d.height = Utils.checkedInt(chart.getChartContext().getViewHeight());\n                return d;\n            }\n            protected void updateSelection() {\n                int count = getComponentCount();\n                for (int i = 0; i < count; i++)\n                    ((ProbePresenter)getComponent(i)).setSelected(\n                            chart.isRowSelected(chart.getRow(i)));\n            }\n        };\n\n        viewport = new JViewport() {\n            public String getToolTipText(MouseEvent event) {\n                Point p = event.getPoint();\n                p.y += getViewPosition().y;\n                return listPanel.getToolTipText(p);\n            }\n        };\n        ToolTipManager.sharedInstance().registerComponent(viewport);\n        viewport.setOpaque(true);\n        viewport.setBackground(new Color(247, 247, 247));\n        viewport.setView(listPanel);\n        viewport.setViewPosition(new Point(0, 0));\n        final ViewportUpdater updater = new ViewportUpdater(viewport);\n        chart.addConfigurationListener(new ChartConfigurationListener.Adapter() {\n            public void contentsWillBeUpdated(long offsetX, final long offsetY,\n                                              double scaleX, double scaleY,\n                                              long lastOffsetX, final long lastOffsetY,\n                                              double lastScaleX, double lastScaleY) {\n                if (lastOffsetY != offsetY)\n                    SwingUtilities.invokeLater(updater.forPoint(new Point(\n                            0, Utils.checkedInt(offsetY))));\n            }\n        });\n        final JPanel bottomPanel = new JPanel(new GridLayout(1, 3));\n        bottomPanel.setPreferredSize(new Dimension(100, new ScrollBar(JScrollBar.\n                                     HORIZONTAL).getPreferredSize().height));\n        bottomPanel.setOpaque(false);\n\n        increaseB = new HeaderButton(null, new ImageIcon(ImageUtilities.loadImage(\n                                                         INCREMENT_IMAGE_PATH))) {\n            protected void performAction(ActionEvent e) {\n                chart.increaseRowHeights((e.getModifiers() & Toolkit.getDefaultToolkit().\n                                         getMenuShortcutKeyMask()) == 0);\n            }\n        };\n        increaseB.setToolTipText(\"Increase rows height\");\n        bottomPanel.add(increaseB);\n\n        decreaseB = new HeaderButton(null, new ImageIcon(ImageUtilities.loadImage(\n                                                         DECREMENT_IMAGE_PATH))) {\n            protected void performAction(ActionEvent e) {\n                chart.decreaseRowHeights((e.getModifiers() & Toolkit.getDefaultToolkit().\n                                         getMenuShortcutKeyMask()) == 0);\n            }\n        };\n        decreaseB.setToolTipText(\"Decrease rows height\");\n        bottomPanel.add(decreaseB);\n\n        resetB = new HeaderButton(null, new ImageIcon(ImageUtilities.loadImage(\n                                                      RESET_IMAGE_PATH))) {\n            protected void performAction(ActionEvent e) {\n                chart.resetRowHeights();\n            }\n        };\n        resetB.setToolTipText(\"Reset rows height\");\n        bottomPanel.add(resetB);\n        \n        setOpaque(false);\n        setLayout(new BorderLayout());\n        add(new HeaderLabel(\"Probes\"), BorderLayout.NORTH);\n        add(viewport, BorderLayout.CENTER);\n        add(bottomPanel, BorderLayout.SOUTH);\n\n        chart.addRowListener(new TimelineChart.RowListener() {\n            public void rowsAdded(List<TimelineChart.Row> rows) {\n                for (TimelineChart.Row row : rows) {\n                    TracerProbe probe = support.getProbe(row);\n                    listPanel.add(new ProbePresenter(probe, support.\n                                  getDescriptor(probe)), row.getIndex());\n                }\n                listPanel.sync();\n                revalidate();\n                repaint();\n                refreshButtons(true);\n            }\n\n            public void rowsRemoved(List<TimelineChart.Row> rows) {\n                for (TimelineChart.Row row : rows)\n                    listPanel.remove(row.getIndex());\n                listPanel.sync();\n                revalidate();\n                repaint();\n                refreshButtons(chart.hasRows());\n            }\n\n            public void rowsResized(List<TimelineChart.Row> rows) {\n                listPanel.sync();\n                revalidate();\n                repaint();\n            }\n        });\n\n        refreshButtons(chart.hasRows());\n    }\n\n    \n    public void setCursor(Cursor cursor) {\n        viewport.setCursor(cursor);\n    }\n\n    Component getMouseTarget() {\n        return viewport;\n    }\n\n    void updateSelection() {\n        listPanel.updateSelection();\n    }\n\n\n    private void refreshButtons(boolean enabled) {\n        increaseB.setEnabled(enabled);\n        decreaseB.setEnabled(enabled);\n        resetB.setEnabled(enabled);\n    }\n\n\n    private static class ViewportUpdater implements Runnable {\n\n        private final JViewport viewport;\n        private Point point;\n\n        ViewportUpdater(JViewport viewport) { this.viewport = viewport; }\n\n        Runnable forPoint(Point point) { this.point = point; return this; }\n\n        public void run() { viewport.setViewPosition(point); }\n\n    }\n\n\n    private static class ListPanel extends JPanel {\n\n        ListPanel(LayoutManager layout) {\n            super(layout);\n            setOpaque(false);\n        }\n\n        protected void updateSelection() {\n        }\n        \n        String getToolTipText(Point p) {\n            String tooltip = null;\n            Component c = getComponentAt(p);\n            if (c instanceof JComponent)\n                tooltip = (String)((JComponent)c).getClientProperty(\"ToolTipHelper\"); // NOI18N\n            return tooltip;\n        }\n\n        private void sync() {\n            doLayout();\n            repaint();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/RowBackgroundDecorator.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartDecorator;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class RowBackgroundDecorator implements ChartDecorator {\n\n    private static final Color BACKGROUND = new Color(228, 228, 248);\n\n    private final TimelineChart chart;\n\n\n    RowBackgroundDecorator(TimelineChart chart) {\n        this.chart = chart;\n    }\n\n\n    public void paint(Graphics2D g, Rectangle dirtyArea, ChartContext context) {\n        int rowsCount = chart.getRowsCount();\n        for (int i = 0; i < rowsCount; i++) {\n            TimelineChart.Row row = chart.getRow(i);\n            ChartContext rowContext = row.getContext();\n\n            int y = Utils.checkedInt(rowContext.getViewportOffsetY());\n            int h = Utils.checkedInt(rowContext.getViewportHeight() - 1);\n\n            if (chart.isRowSelected(row)) {\n                    g.setColor(BACKGROUND);\n                    g.fillRect(0, y, chart.getWidth(), h);\n                }\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/RowBoundsDecorator.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartDecorator;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class RowBoundsDecorator implements ChartDecorator {\n\n    private static final Color BORDER_COLOR = Color.LIGHT_GRAY;\n\n    private final TimelineChart chart;\n\n\n    RowBoundsDecorator(TimelineChart chart) {\n        this.chart = chart;\n    }\n\n\n    public void paint(Graphics2D g, Rectangle dirtyArea, ChartContext context) {\n        int rowsCount = chart.getRowsCount();\n        for (int i = 0; i < rowsCount; i++) {\n            TimelineChart.Row row = chart.getRow(i);\n            ChartContext rowContext = row.getContext();\n\n            int y = Utils.checkedInt(rowContext.getViewportOffsetY()) +\n                    rowContext.getViewportHeight() - 1;\n            int w = chart.getWidth();\n\n            g.setColor(BORDER_COLOR);\n            g.drawLine(0, y, w, y);\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/RowForegroundDecorator.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.LinearGradientPaint;\nimport java.awt.Rectangle;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartDecorator;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class RowForegroundDecorator implements ChartDecorator {\n\n    private static final Color SELECTED_FILTER = new Color(0, 0, 200, 25);\n    private static final float[] FRACTIONS = new float[] { 0.0f, 0.49f, 0.51f, 1.0f };\n    private static final Color[] COLORS = new Color[] { new Color(250, 251, 252, 120),\n                                                        new Color(237, 240, 242, 120),\n                                                        new Color(229, 233, 236, 125),\n                                                        new Color(215, 221, 226, 130) };\n\n    private final TimelineChart chart;\n    private final boolean gradient;\n    private final boolean selection;\n\n\n    RowForegroundDecorator(TimelineChart chart, boolean gradient, boolean selection) {\n        this.chart = chart;\n        this.gradient = gradient;\n        this.selection = selection;\n    }\n\n\n    public void paint(Graphics2D g, Rectangle dirtyArea, ChartContext context) {\n        if (gradient || selection) {\n            int rowsCount = chart.getRowsCount();\n            for (int i = 0; i < rowsCount; i++) {\n                TimelineChart.Row row = chart.getRow(i);\n                ChartContext rowContext = row.getContext();\n\n                int y = Utils.checkedInt(rowContext.getViewportOffsetY());\n                int h = Utils.checkedInt(rowContext.getViewportHeight() - 1);\n\n                if (gradient) {\n                    g.setPaint(new LinearGradientPaint(0, y, 0, y + h, FRACTIONS, COLORS));\n                    g.fillRect(0, y, chart.getWidth(), h);\n                }\n\n                if (selection && chart.isRowSelected(row)) {\n                    g.setColor(SELECTED_FILTER);\n                    g.fillRect(0, y, chart.getWidth(), h);\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelineAxis.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport org.graalvm.visualvm.modules.tracer.impl.swing.EnhancedLabelRenderer;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.HeaderLabel;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.HeaderPanel;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.LegendFont;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.TimelineMarksPainter;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Image;\nimport java.awt.Insets;\nimport java.awt.Paint;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseMotionListener;\nimport java.awt.event.MouseWheelEvent;\nimport java.awt.event.MouseWheelListener;\nimport java.awt.image.BufferedImage;\nimport java.text.Format;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.axis.AxisComponent;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMark;\nimport org.graalvm.visualvm.lib.charts.axis.TimeAxisUtils;\nimport org.graalvm.visualvm.lib.charts.axis.TimelineMarksComputer;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineAxis extends JPanel {\n\n    private final HeaderRenderer painter;\n    private final AxisComponent axis;\n    private final MarksComponent marks;\n\n    private int preferredHeight;\n    \n    private int pointerX;\n\n\n    TimelineAxis(final TimelineChart chart, TimelineSupport support) {\n\n        super(null);\n\n        painter = new HeaderRenderer();\n        \n        Timeline timeline = ((SynchronousXYItemsModel)chart.getItemsModel()).getTimeline();\n        axis = new Axis(chart, new MarksComputer(timeline, chart.getChartContext()));\n\n        marks = new MarksComponent(support);\n\n        preferredHeight = HeaderLabel.DEFAULT_HEIGHT;\n\n        add(marks);\n        add(axis);\n        add(painter);\n\n        chart.addConfigurationListener(new ChartConfigurationListener.Adapter() {\n\n            private final Runnable updater = new Runnable() {\n                public void run() {\n                    if (!axis.isVisible()) {\n                        marks.setupTicks();\n                        marks.refreshHoverMark(pointerX);\n                        marks.repaint();\n                    }\n                }\n            };\n\n            public void contentsUpdated(long offsetX, long offsetY,\n                                        double scaleX, double scaleY,\n                                        long lastOffsetX, long lastOffsetY,\n                                        double lastScaleX, double lastScaleY,\n                                        int shiftX, int shiftY) {\n                \n                if (lastOffsetX != offsetX || lastScaleX != scaleX)\n                    marks.refreshMarks();\n                SwingUtilities.invokeLater(updater);\n            }\n\n        });\n\n        support.addSelectionListener(new TimelineSupport.SelectionListener() {\n\n            public void rowSelectionChanged(boolean rowsSelected) {}\n\n            public void timeSelectionChanged(boolean timestampsSelected, boolean justHovering) {\n                marks.refreshMarks();\n                marks.repaint();\n            }\n        });\n\n        marks.addMouseListener(new MouseAdapter() {\n            public void mouseEntered(MouseEvent e) {\n                pointerX = e.getX();\n                marks.setupTicks();\n                marks.refreshHoverMark(pointerX);\n                axis.setVisible(false);\n            }\n\n            public void mouseExited(MouseEvent e) {\n                axis.setVisible(true);\n                marks.clearTicks();\n                marks.refreshHoverMark(-10);\n            }\n\n            public void mouseClicked(MouseEvent e) {\n                marks.handleAction();\n                marks.repaint();\n            }\n        });\n\n        marks.addMouseMotionListener(new MouseMotionListener() {\n            public void mouseDragged(MouseEvent e) {\n                pointerX = e.getX();\n            }\n\n            public void mouseMoved(MouseEvent e) {\n                pointerX = e.getX();\n                if (!axis.isVisible()) marks.refreshHoverMark(pointerX);\n            }\n        });\n\n        marks.addMouseWheelListener(new MouseWheelListener() {\n            public void mouseWheelMoved(MouseWheelEvent e) {\n                e.setSource(chart);\n                chart.processMouseWheelEvent(e);\n            }\n        });\n\n    }\n\n\n    public boolean isOptimizedDrawingEnabled() {\n        return false;\n    }\n\n    public Dimension getPreferredSize() {\n        Dimension size = super.getPreferredSize();\n        size.height = preferredHeight;\n        return size;\n    }\n\n\n    public void validate() {}\n    public void doLayout() {}\n\n    public void reshape(int x, int y, int width, int height) {\n        super.reshape(x, y, width, height);\n        painter.reshape(0, 0, width, height);\n        axis.reshape(1, 1, width - 2, height - 2);\n        marks.reshape(0, 0, width, height);\n    }\n\n\n    private static class HeaderRenderer extends HeaderPanel {\n\n        private Image offscreen;\n\n        public void reshape(int x, int y, int width, int height) {\n            if (getWidth() != width || getHeight() != height) offscreen = null;\n            super.reshape(x, y, width, height);\n        }\n\n        long total = 0;\n        int count = 0;\n\n        public void validate() {}\n\n        public void paint(Graphics g) {\n            if (offscreen == null) {\n                offscreen = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);\n                super.paint(offscreen.getGraphics());\n            }\n            g.drawImage(offscreen, 0, 0, null);\n        }\n\n    }\n\n\n    private static class MarksComponent extends JComponent {\n\n        private static final Image MARK = ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/modules/tracer/impl/resources/mark.png\");  // NOI18N\n        private static final Image MARK_HIGHL = ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/modules/tracer/impl/resources/markHighl.png\");  // NOI18N\n        private static final int MARK_EXTENT = MARK.getWidth(null) / 2;\n        private static final int MARK_HEIGHT = MARK.getHeight(null);\n\n        private final TimelineSupport support;\n        private final Timeline timeline;\n        private final SynchronousXYChartContext context;\n\n        private final EnhancedLabelRenderer timeRenderer;\n        private final Format timeFormat;\n\n        private int[] ticks;\n        private int hoverIndex = -1;\n        private int hoverX = -10;\n        private boolean wasSelected;\n        private long hoverTime;\n\n        private final List<Integer> selections = new ArrayList();\n        private final int markExtent = 2;\n\n\n        MarksComponent(TimelineSupport support) {\n            this.support = support;\n\n            TimelineChart chart = support.getChart();\n            SynchronousXYItemsModel model = (SynchronousXYItemsModel)chart.getItemsModel();\n            context = (SynchronousXYChartContext)chart.getChartContext();\n            timeline = model.getTimeline();\n\n            timeRenderer = new EnhancedLabelRenderer();\n            if (UISupport.isAquaLookAndFeel()) {\n                Font f = new LegendFont();\n                timeRenderer.setFont(f.deriveFont(f.getSize2D() - 1));\n                timeRenderer.setMargin(new Insets(0, 2, 0, 2));\n            } else {\n                timeRenderer.setFont(new LegendFont());\n                timeRenderer.setMargin(new Insets(1, 2, 1, 2));\n            }\n            timeRenderer.setBackground(Color.WHITE);\n            timeRenderer.setBorder(BorderFactory.createLineBorder(Color.BLACK));\n            timeFormat = new SimpleDateFormat(TimeAxisUtils.getFormatString(1, 1, 1));\n\n            setToolTipText(\"Click a mark to select or unselect it\");\n\n            setOpaque(false);\n        }\n        \n        public void validate() {}\n        public void doLayout() {}\n\n\n        void refreshMarks() {\n            Set<Integer> selectedIndexes = support.getSelectedTimestamps();\n            if (selectedIndexes.size() == 0 && selections.isEmpty()) return;\n\n            selections.clear();\n\n            for (int selectedIndex : selectedIndexes) {\n                long time = timeline.getTimestamp(selectedIndex);\n                int x = Utils.checkedInt(context.getViewX(time));\n                if (x > -markExtent && x < getWidth() + markExtent)\n                    selections.add(x + 1);\n            }\n        }\n\n        void setupTicks() {\n            int[][] idxs = support.getPointsComputer().getVisible(getBounds(),\n                           timeline.getTimestampsCount(), context, 1, 0);\n            ticks = idxs == null ? null : idxs[0];\n            if (ticks != null) for (int i = 0; i < idxs[1][0]; i++)\n                    ticks[i] = Utils.checkedInt(context.getViewX(timeline.\n                                                getTimestamp(ticks[i]))) + 1;\n        }\n\n        void refreshHoverMark(int pointerX) {\n            int lastHoverIndex = hoverIndex;\n\n            hoverIndex = context.getNearestTimestampIndex(pointerX - 1, 0);\n            hoverX = hoverIndex == -1 ? -10 : Utils.checkedInt(context.getViewX(\n                                        timeline.getTimestamp(hoverIndex))) + 1;\n            if (Math.abs(hoverX - pointerX + 1) > MARK_EXTENT) {\n                hoverIndex = -1;\n                hoverX = -10;\n            }\n\n            if (lastHoverIndex != hoverIndex) {\n                if (!wasSelected) support.unselectTimestamp(lastHoverIndex);\n                wasSelected = hoverIndex != -1 && support.isTimestampSelected(hoverIndex);\n                support.setTimestampHovering(hoverIndex != -1, wasSelected);\n                if (hoverIndex != -1) {\n                    support.selectTimestamp(hoverIndex, false);\n                    hoverTime = timeline.getTimestamp(hoverIndex);\n                    if (wasSelected) repaint();\n                } else {\n                    if (!wasSelected) repaint();\n                }\n                if (hoverIndex == -1) setCursor(Cursor.getDefaultCursor());\n                else setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n            }\n\n        }\n\n        void clearTicks() {\n            ticks = null;\n        }\n\n        void handleAction() {\n            wasSelected = !wasSelected;\n            support.setTimestampHovering(hoverIndex != -1, wasSelected);\n        }\n\n\n        public void paint(Graphics g) {\n            int top = getHeight() / 2 - 1;\n            int bottom = top + 2;\n\n            if (ticks != null)\n                for (int i = 0; i < ticks.length; i++)\n                    g.drawLine(ticks[i], top, ticks[i], bottom);\n\n            if (selections == null || selections.isEmpty()) return;\n\n            int y = getHeight() - 5 - MARK_HEIGHT;\n            for (int x : selections)\n                g.drawImage((x == hoverX && wasSelected) ? MARK_HIGHL :\n                            MARK, x - MARK_EXTENT + 1, y, null);\n\n            if (hoverIndex != -1) {\n                timeRenderer.setText(timeFormat.format(hoverTime));\n                Dimension timeSize = timeRenderer.getPreferredSize();\n                int timeWidth = timeSize.width;\n                int extraWidth = MARK_EXTENT + TimelineTooltipOverlay.TOOLTIP_OFFSET;\n                int timeX = hoverX + extraWidth;\n                if (timeX > getWidth() - timeWidth - TimelineTooltipOverlay.TOOLTIP_MARGIN)\n                    timeX = hoverX - timeWidth - extraWidth;\n                timeRenderer.setLocation(timeX, top - timeSize.height / 2);\n                timeRenderer.paint(g);\n            }\n        }\n\n    }\n\n\n    private static class MarksComputer extends TimelineMarksComputer {\n\n        MarksComputer(Timeline timeline, ChartContext context) {\n            super(timeline, context, SwingConstants.HORIZONTAL);\n        }\n\n        void refresh() {\n            refreshConfiguration();\n        }\n\n    }\n\n\n    private static class Axis extends AxisComponent {\n\n        private static final int LAF_OFFSET = resolveOffset();\n\n        private final Paint meshPaint = Utils.checkedColor(new Color(180, 180, 180, 50));\n        private final Stroke meshStroke = new BasicStroke(1);\n\n        private final TimelineChart chart;\n        private final MarksComputer marksComputer;\n        private final TimelineMarksPainter marksPainter;\n        private boolean hadTicks = false;\n\n        private final Runnable repainter;\n\n\n        Axis(TimelineChart chart, MarksComputer marksComputer) {\n\n            super(chart, marksComputer, null, SwingConstants.NORTH,\n                  AxisComponent.MESH_FOREGROUND);\n\n            this.chart = chart;\n            this.marksComputer = marksComputer;\n            this.marksPainter = new TimelineMarksPainter();\n\n            repainter = new Runnable() {\n                public void run() { Axis.this.chart.invalidateRepaint(); }\n            };\n        }\n\n\n        public void validate() {}\n        public void doLayout() {}\n\n\n        public void paint(Graphics g) {\n            Rectangle clip = g.getClipBounds();\n            if (clip == null) clip = new Rectangle(0, 0, getWidth(), getHeight());\n\n            marksComputer.refresh();\n\n            paintHorizontalAxis(g, clip);\n        }\n\n        protected void paintHorizontalMesh(Graphics2D g, Rectangle clip, Rectangle chartMask) {\n            Iterator<AxisMark> marks =\n                    marksComputer.marksIterator(chartMask.x, chartMask.x + chartMask.width);\n\n            boolean hasTicks = false;\n\n            while (marks.hasNext()) {\n                hasTicks = true;\n\n                AxisMark mark = marks.next();\n                int x = mark.getPosition();\n\n                g.setPaint(meshPaint);\n                g.setStroke(meshStroke);\n                g.drawLine(x, chartMask.y, x, chartMask.y + chartMask.height);\n            }\n\n            if (!hadTicks && hasTicks) SwingUtilities.invokeLater(repainter);\n            hadTicks = hasTicks;\n        }\n\n        protected void paintHorizontalAxis(Graphics g, Rectangle clip) {\n            int viewStart = -1; // -1: extra 1px for axis\n            int viewEnd = viewStart + chart.getWidth() + 2; // +2 extra 1px + 1px for axis\n\n            Iterator<AxisMark> marks = marksComputer.marksIterator(viewStart, viewEnd);\n\n            int lZeroOffset = chart.isRightBased() ? 0 : 1;\n            int rZeroOffset = chart.isRightBased() ? 1 : 0;\n\n            while (marks.hasNext()) {\n                AxisMark mark = marks.next();\n\n                int x = mark.getPosition() - 1;\n\n                if (x < -1 - lZeroOffset ||\n                    x >= -1 + chart.getWidth() + rZeroOffset) continue;\n\n                TimelineMarksPainter painter =\n                        (TimelineMarksPainter)marksPainter.getPainter(mark);\n                Dimension painterSize = painter.getPreferredSize();\n                int markOffsetX = painterSize.width / 2;\n\n                if (x + markOffsetX < clip.x ||\n                    x - markOffsetX >= clip.x + clip.width) continue;\n\n                g.setColor(getForeground());\n                g.drawLine(x, 1, x, 3);\n                \n                int markOffsetY = (getHeight() - painterSize.height) / 2 + LAF_OFFSET;\n                painter.setLocation(x - markOffsetX, markOffsetY);\n                painter.paint(g);\n            }\n        }\n\n        private static int resolveOffset() {\n            if (UISupport.isWindowsLookAndFeel() ||\n                UISupport.isMetalLookAndFeel() ||\n                UISupport.isGTKLookAndFeel()) return 1;\n            return 0;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelineChart.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport java.awt.Rectangle;\nimport java.awt.event.MouseWheelEvent;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.TreeSet;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartItemChange;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemPainter;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChart;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineChart extends SynchronousXYChart {\n\n    static final int MIN_ROW_HEIGHT = 25;\n    static final int MAX_ROW_HEIGHT = 500;\n    static final int DEF_ROW_HEIGHT = 75;\n    static final int ROW_RESIZE_STEP = MIN_ROW_HEIGHT;\n\n    private static final int ROW_MARGIN_TOP = 3;\n    private static final int ROW_MARGIN_BOTTOM = 3;\n\n    private int currentRowHeight = DEF_ROW_HEIGHT;\n\n    private final List<Row> rows;\n    private final Map<ChartItem, Row> itemsToRows;\n\n    private final Set selectedRows = new TreeSet(new RowComparator());\n    private final Set selectionBlockers = new HashSet();\n    private int lastHoverMode;\n    private int lastMoveMode;\n\n    private final Set<RowListener> rowListeners = new HashSet();\n\n\n    // --- Constructors --------------------------------------------------------\n\n    TimelineChart(SynchronousXYItemsModel itemsModel) {\n        super(itemsModel, new PaintersModel.Default());\n\n        rows = new ArrayList();\n        itemsToRows = new HashMap();\n\n        setBottomBased(false);\n\n        setZoomMode(ZOOM_X);\n        setMouseZoomingEnabled(false);\n        setMousePanningEnabled(false);\n\n        setAccelerationPriority(1f);\n    }\n\n\n    // --- Rows management -----------------------------------------------------\n\n    Row addRow() {\n        Row row = new Row();\n        int rowIndex = rows.size();\n        row.setIndex(rowIndex);\n        rows.add(row);\n        row.setHeight(currentRowHeight, true);\n        row.updateOffset();\n//        repaintRows(row.getIndex());\n        updateChart();\n        notifyRowsAdded(Collections.singletonList(row));\n        return row;\n    }\n\n    Row addRow(int rowIndex) {\n        Row row = new Row();\n        row.setIndex(rowIndex);\n        rows.add(rowIndex, row);\n        row.setHeight(currentRowHeight, true);\n        updateRowOffsets(rowIndex);\n        updateRowIndexes(rowIndex + 1);\n//        repaintRows(rowIndex);\n        updateChart();\n        notifyRowsAdded(Collections.singletonList(row));\n        return row;\n    }\n\n    Row removeRow(int rowIndex) {\n        return removeRow(rows.get(rowIndex));\n    }\n\n    Row removeRow(Row row) {\n        row.clearItems();\n        rows.remove(row);\n        int rowIndex = row.getIndex();\n        updateRowIndexes(rowIndex);\n        updateRowOffsets(rowIndex);\n//        repaintRows(row.getIndex());\n        updateChart();\n        notifyRowsRemoved(Collections.singletonList(row));\n        return row;\n    }\n\n\n    // --- Rows access ---------------------------------------------------------\n\n    boolean hasRows() {\n        return !rows.isEmpty();\n    }\n\n    int getRowsCount() {\n        return rows.size();\n    }\n\n    Row getRow(int rowIndex) {\n        return rows.get(rowIndex);\n    }\n\n    Row getRow(ChartItem item) {\n        return itemsToRows.get(item);\n    }\n\n\n    // --- Row appearance ------------------------------------------------------\n\n    void setRowHeight(int rowIndex, int rowHeight) {\n        setRowHeight(rowIndex, rowHeight, true);\n    }\n\n    void setRowHeight(int rowIndex, int rowHeight, boolean checkStep) {\n        Row row = rows.get(rowIndex);\n        boolean changed = row.setHeight(rowHeight, checkStep);\n        updateRowOffsets(rowIndex + 1);\n        if (changed) notifyRowsResized(Collections.singletonList(row));\n        updateChart(); // TODO: update only affected rows!\n    }\n\n    int getRowHeight(int rowIndex) {\n        return rows.get(rowIndex).getHeight();\n    }\n\n    void increaseRowHeights(boolean step) {\n        if (rows.isEmpty()) return;\n        int incr = step ? ROW_RESIZE_STEP : 1;\n        List<Row> resized = new ArrayList(rows.size());\n        for (Row row : rows)\n            if (row.setHeight(row.getHeight() + incr, step))\n                resized.add(row);\n        updateRowOffsets(0);\n        if (!resized.isEmpty()) notifyRowsResized(resized);\n        updateChart(); // TODO: update only affected rows!\n        currentRowHeight += incr;\n    }\n\n    void decreaseRowHeights(boolean step) {\n        if (rows.isEmpty()) return;\n        int decr = step ? ROW_RESIZE_STEP : 1;\n        List<Row> resized = new ArrayList(rows.size());\n        for (Row row : rows)\n            if (row.setHeight(row.getHeight() - decr, step))\n                resized.add(row);\n        updateRowOffsets(0);\n        if (!resized.isEmpty()) notifyRowsResized(resized);\n        updateChart(); // TODO: update only affected rows!\n        currentRowHeight = Math.max(currentRowHeight - decr, MIN_ROW_HEIGHT);\n    }\n\n    void resetRowHeights() {\n        if (rows.isEmpty()) return;\n        List<Row> resized = new ArrayList(rows.size());\n        for (Row row : rows)\n            if (row.setHeight(DEF_ROW_HEIGHT, true))\n                resized.add(row);\n        updateRowOffsets(0);\n        if (!resized.isEmpty()) notifyRowsResized(new ArrayList(rows));\n        updateChart(); // TODO: update only affected rows!\n        currentRowHeight = DEF_ROW_HEIGHT;\n    }\n\n    Row getRowAt(int ypos) {\n        ypos += getOffsetY();\n        for (Row row : rows) {\n            int pos = row.getOffset();\n            if (ypos < pos) return null;\n            pos += row.getHeight();\n            if (ypos <= pos) return row;\n        }\n        return null;\n    }\n\n    Row getNearestRow(int ypos, int range, boolean noFirst) {\n        if (rows.size() == 0) return null;\n        \n        ypos += getOffsetY();\n\n        if (noFirst) {\n            Row row = rows.get(0);\n            int pos = row.getOffset() + row.getHeight();\n            if (ypos < pos - range) return null;\n        }\n\n        for (Row row : rows) {\n            int pos = row.getOffset();\n            if (ypos < pos - range) return null;\n            if (ypos <= pos + range) return row;\n            pos += row.getHeight();\n            if (ypos < pos - range) return null;\n            if (ypos <= pos + range) return row;\n        }\n        return null;\n    }\n\n    private void updateRowOffsets(int rowIndex) {\n        int rowsCount = rows.size();\n        if (rowIndex >= rowsCount) return;\n        for (int i = rowIndex; i < rowsCount; i++)\n            rows.get(i).updateOffset();\n    }\n\n\n    // --- Row events ----------------------------------------------------------\n\n    void addRowListener(RowListener listener) {\n        rowListeners.add(listener);\n    }\n\n    void removeRowListener(RowListener listener) {\n        rowListeners.remove(listener);\n    }\n\n\n    private void notifyRowsAdded(final List<Row> rows) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                for (RowListener listener : rowListeners)\n                    listener.rowsAdded(rows);\n            }\n        });\n    }\n\n    private void notifyRowsRemoved(final List<Row> rows) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                for (RowListener listener : rowListeners)\n                    listener.rowsRemoved(rows);\n            }\n        });\n    }\n\n    private void notifyRowsResized(final List<Row> rows) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                for (RowListener listener : rowListeners)\n                    listener.rowsResized(rows);\n            }\n        });\n    }\n\n\n    // --- Selection support ---------------------------------------------------\n\n    boolean selectRow(Row row) {\n        if (!selectedRows.add(row)) return false;\n        repaintRows();\n        return true;\n    }\n\n    boolean unselectRow(Row row) {\n        if (!selectedRows.remove(row)) return false;\n        repaintRows();\n        return true;\n    }\n\n    boolean setSelectedRow(Row row) {\n        if (row == null) {\n            return clearRowsSelection();\n        } else {\n            if (selectedRows.size() == 1 && selectedRows.contains(row)) return false;\n            selectedRows.clear();\n            selectedRows.add(row);\n            repaintRows();\n            return true;\n        }\n    }\n\n    boolean toggleRowSelection(Row row) {\n        if (selectedRows.contains(row)) return unselectRow(row);\n        else return selectRow(row);\n    }\n\n    boolean clearRowsSelection() {\n        if (selectedRows.isEmpty()) return false;\n        selectedRows.clear();\n        repaintRows();\n        return true;\n    }\n\n    boolean isRowSelected(Row row) {\n        return selectedRows.contains(row);\n    }\n\n    boolean isRowSelection() {\n        return !selectedRows.isEmpty();\n    }\n\n    List<Row> getSelectedRows() {\n        return new ArrayList(selectedRows);\n    }\n    \n\n    void updateSelection(boolean enable, Object source) {\n        int blockersSize = selectionBlockers.size();\n        if (enable) selectionBlockers.remove(source);\n        else selectionBlockers.add(source);\n        if (selectionBlockers.size() == blockersSize) return;\n\n        ChartSelectionModel selectionModel = getSelectionModel();\n        if (selectionModel == null) return;\n\n        if (selectionBlockers.isEmpty()) {\n            selectionModel.setHoverMode(lastHoverMode);\n            selectionModel.setMoveMode(lastMoveMode);\n        } else {\n            lastHoverMode = selectionModel.getHoverMode();\n            lastMoveMode = selectionModel.getMoveMode();\n            selectionModel.setHoverMode(ChartSelectionModel.HOVER_NONE);\n            selectionModel.setMoveMode(ChartSelectionModel.SELECTION_NONE);\n        }\n    }\n\n\n    // --- Internal API to access protected methods ----------------------------\n\n    long maxOffsetX() {\n        return super.getMaxOffsetX();\n    }\n\n    double viewWidth(double d) {\n        return super.getViewWidth(d);\n    }\n\n    protected void processMouseWheelEvent(MouseWheelEvent e) {\n        super.processMouseWheelEvent(e);\n    }\n\n\n    // --- Protected implementation --------------------------------------------\n\n    protected ChartContext getChartContext(ChartItem item) {\n        if (item == null) return super.getChartContext(null);\n        else return itemsToRows.get(item).getContext();\n    }\n\n    protected void computeDataBounds() {\n        LongRect.clear(dataBounds);\n\n        if (rows == null) return;\n\n        for (Row row : rows) {\n            RowContext context = (RowContext)row.getContext();\n            if (LongRect.isClear(dataBounds)) LongRect.set(dataBounds, context.bounds);\n            else LongRect.add(dataBounds, context.bounds);\n        }\n\n        dataBounds.y = 0;\n        Row lastRow = rows.size() > 0 ? rows.get(rows.size() - 1) : null;\n        dataBounds.height = lastRow != null ? lastRow.getOffset() + lastRow.getHeight() : 0;\n    }\n\n    protected void updateChart() {\n        updateRowBounds();\n        super.updateChart();\n    }\n\n\n    protected void itemsAdded(List<ChartItem> addedItems) {\n        updateRowBounds();\n        super.itemsAdded(addedItems);\n    }\n\n    protected void itemsRemoved(List<ChartItem> removedItems) {\n        updateRowBounds();\n        super.itemsRemoved(removedItems);\n    }\n\n    protected void itemsChanged(List<ChartItemChange> itemChanges) {\n        updateRowBounds(); // NOTE: should be computed from itemChanges!!!\n        super.itemsChanged(itemChanges);\n    }\n\n    protected void paintersChanged(List<ItemPainter> changedPainters) {\n        updateRowBounds();\n        super.paintersChanged(changedPainters);\n    }\n\n\n    // --- Internal implementation ---------------------------------------------\n\n    void addItemsImpl(SynchronousXYItem[] addedItems, ItemPainter[] addedPainters, Row row) {\n        for (SynchronousXYItem item : addedItems) itemsToRows.put(item, row);\n        paintersModel().addPainters(addedItems, addedPainters);\n        itemsModel().addItems(addedItems);\n    }\n\n    void removeItemsImpl(SynchronousXYItem[] removedItems) {\n        itemsModel().removeItems(removedItems);\n        paintersModel().removePainters(removedItems);\n        for (SynchronousXYItem item : removedItems) itemsToRows.remove(item);\n    }\n\n\n    void invalidateRepaint() {\n        invalidateImage();\n        repaintDirty();\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private SynchronousXYItemsModel itemsModel() {\n        return (SynchronousXYItemsModel)getItemsModel();\n    }\n\n    private PaintersModel.Default paintersModel() {\n        return (PaintersModel.Default)getPaintersModel();\n    }\n\n    private void updateRowIndexes(int startIndex) {\n        for (int i = startIndex; i < rows.size(); i++)\n            rows.get(i).setIndex(i);\n    }\n\n    private void repaintRows() {\n        invalidateImage();\n        repaintDirty();\n    }\n\n    private void repaintRows(final int startIndex) {\n//        SwingUtilities.invokeLater(new Runnable() {\n//            public void run() {\n                for (int i = startIndex; i < rows.size(); i++) {\n                    ChartContext rowContext = rows.get(i).getContext();\n                    invalidateImage(new Rectangle(0, Utils.checkedInt(rowContext.\n                                   getViewportOffsetY()), getWidth(), rowContext.\n                                   getViewportHeight()));\n                }\n                repaintDirty();\n//            }\n//        });\n    }\n\n    private void updateRowBounds() {\n        if (rows == null) return; // Happens when called from constructor\n        for (Row row : rows) ((RowContext)row.getContext()).updateBounds();\n    }\n\n\n    // --- Row definition ------------------------------------------------------\n\n    class Row {\n\n        private int rowIndex;\n        private int rowOffset;\n        private int rowHeight;\n        private final List<SynchronousXYItem> items;\n        private final RowContext context;\n\n\n        // --- Constructors ----------------------------------------------------\n\n        Row() {\n            items = new ArrayList();\n            context = new RowContext(this);\n        }\n\n\n        // --- Row telemetry ---------------------------------------------------\n\n        int getIndex() {\n            return rowIndex;\n        }\n\n        private void updateOffset() {\n            if (rowIndex != 0) {\n                Row previousRow = rows.get(rowIndex - 1);\n                rowOffset = previousRow.rowOffset + previousRow.rowHeight;\n            } else {\n                rowOffset = 0;\n            }\n        }\n\n        int getOffset() {\n            return rowOffset;\n        }\n\n        private boolean setHeight(int height, boolean checkStep) {\n            height = Math.max(MIN_ROW_HEIGHT, height);\n            height = Math.min(MAX_ROW_HEIGHT, height);\n            if (checkStep) height = height / ROW_RESIZE_STEP * ROW_RESIZE_STEP;\n            boolean changed = rowHeight != height;\n            rowHeight = height;\n            return changed;\n        }\n\n        int getHeight() {\n            return rowHeight;\n        }\n\n\n        // --- Items management ------------------------------------------------\n\n        void addItems(SynchronousXYItemsModel addedItems, PaintersModel addedPainters) {\n            int itemsCount = addedItems.getItemsCount();\n\n            SynchronousXYItem[] addedItemsArr = new SynchronousXYItem[itemsCount];\n            for (int i = 0; i < itemsCount; i++)\n                addedItemsArr[i] = addedItems.getItem(i);\n\n            ItemPainter[] addedPaintersArr = new ItemPainter[itemsCount];\n            for (int i = 0; i < itemsCount; i++)\n                addedPaintersArr[i] = addedPainters.getPainter(addedItemsArr[i]);\n\n            addItems(addedItemsArr, addedPaintersArr);\n        }\n\n        void addItems(SynchronousXYItem[] addedItems, ItemPainter[] addedPainters) {\n            for (SynchronousXYItem item : addedItems) items.add(item);\n            addItemsImpl(addedItems, addedPainters, this);\n        }\n\n        void removeItems(SynchronousXYItemsModel removedItems) {\n            int itemsCount = removedItems.getItemsCount();\n\n            SynchronousXYItem[] removedItemsArr = new SynchronousXYItem[itemsCount];\n            for (int i = 0; i < itemsCount; i++)\n                removedItemsArr[i] = removedItems.getItem(i);\n\n            removeItems(removedItemsArr);\n        }\n\n        void removeItems(SynchronousXYItem[] removedItems) {\n            removeItemsImpl(removedItems);\n            for (SynchronousXYItem item : removedItems) items.remove(item);\n        }\n\n\n        // --- Items access ----------------------------------------------------\n\n        int getItemsCount() {\n            return items.size();\n        }\n\n        ChartItem getItem(int itemIndex) {\n            return items.get(itemIndex);\n        }\n\n        SynchronousXYItem[] getItems() {\n            return items.toArray(new SynchronousXYItem[items.size()]);\n        }\n\n        @SuppressWarnings(\"element-type-mismatch\")\n        boolean containsItem(ChartItem item) {\n            return items.contains(item);\n        }\n\n\n        // --- Row context -----------------------------------------------------\n\n        ChartContext getContext() {\n            return context;\n        }\n\n\n        // --- Internal interface ----------------------------------------------\n\n        private void setIndex(int rowIndex) {\n            this.rowIndex = rowIndex;\n        }\n\n        private void clearItems() {\n            if (items.size() == 0) return;\n            removeItemsImpl(getItems());\n        }\n\n    }\n\n\n    // --- RowContext implementation -------------------------------------------\n\n    private class RowContext extends SynchronousXYChart.Context {\n\n        private final Row row;\n\n        private final LongRect bounds;\n        private double scaleY;\n\n        private int marginTop;\n        private int marginBottom;\n\n\n        RowContext(Row row) {\n            super(TimelineChart.this);\n            this.row = row;\n\n            marginTop = ROW_MARGIN_TOP;\n            marginBottom = ROW_MARGIN_BOTTOM;\n\n            bounds = new LongRect();\n        }\n\n\n        protected void updateBounds() {\n            LongRect.clear(bounds);\n\n            PaintersModel painters = paintersModel();\n            int itemsCount = row.getItemsCount();\n\n            for (int i = 0; i < itemsCount; i++) {\n                ChartItem item = row.getItem(i);\n                ItemPainter painter = painters.getPainter(item);\n                LongRect itemBounds = painter.getItemBounds(item);\n                if (LongRect.isClear(bounds)) {\n                    LongRect.set(bounds, itemBounds);\n                } else if (LongRect.isEmpty(itemBounds)) { // Zero height (constant value)\n                    LongRect.add(bounds, itemBounds.x, itemBounds.height);\n                } else {\n                    LongRect.add(bounds, itemBounds);\n                }\n            }\n\n            double oldScaleY = scaleY;\n            scaleY = (double)(row.getHeight() - marginTop - marginBottom) /\n                     (double)(bounds.height == 0 ? 1 : bounds.height);\n\n            if (scaleY != oldScaleY) invalidateImage(Utils.checkedRectangle(\n                                                     getViewRect(bounds)));\n        }\n\n\n        public boolean isBottomBased() { return true; }\n\n        public boolean fitsHeight() { return true; }\n\n        public long getDataOffsetY() { return bounds.y; }\n\n        public long getDataHeight() { return bounds.height; }\n\n        public long getViewHeight() { return row.getHeight(); }\n\n        public long getViewportOffsetY() { return row.getOffset() - getOffsetY(); }\n\n        public int getViewportHeight() { return row.getHeight(); }\n\n        public double getViewY(double dataY) { return getViewY(dataY, false); }\n\n        public double getReversedViewY(double dataY) { return getViewY(dataY, true); }\n\n        public double getViewHeight(double dataHeight) { return dataHeight * scaleY; }\n\n        public double getDataY(double viewY) { return getDataY(viewY, false); }\n\n        public double getReversedDataY(double viewY) { return getDataY(viewY, true); }\n\n        public double getDataHeight(double viewHeight) { return viewHeight / scaleY; }\n\n\n        private double getViewY(double dataY, boolean reverse) {\n            if (isBottomBased() && !reverse || !isBottomBased() && reverse) {\n                return row.getHeight() - (dataY - bounds.y) * scaleY - getOffsetY() +\n                       getViewInsets().top - marginBottom + row.getOffset();\n            } else {\n                return (dataY - bounds.y) * scaleY - getOffsetY() +\n                       getViewInsets().top + marginTop + row.getOffset();\n            }\n        }\n\n        private double getDataY(double viewY, boolean reverse) {\n            if ((isBottomBased() && !reverse) || (!isBottomBased() && reverse)) {\n                return bounds.y - (viewY + getViewInsets().bottom - marginBottom -\n                       getOffsetY() - getHeight()) / scaleY;\n            } else {\n                return (viewY + getOffsetY() - getViewInsets().top - marginTop) /\n                       scaleY + bounds.y;\n            }\n        }\n\n    }\n\n\n    private static class RowComparator implements Comparator<Row> {\n\n        public int compare(Row r1, Row r2) {\n            int r1i = r1.getIndex();\n            int r2i = r2.getIndex();\n            return (r1i < r2i ? -1 : (r1i == r2i ? 0 : 1));\n        }\n\n    }\n\n\n    public static interface RowListener {\n\n        public void rowsAdded(List<Row> rows);\n\n        public void rowsRemoved(List<Row> rows);\n\n        public void rowsResized(List<Row> rows);\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelineColorFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport java.awt.Color;\n\n/**\n * Utility class to access colors predefined for VisualVM.\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineColorFactory {\n    \n    private static final Color[] PREDEFINED_COLORS = new Color[] {\n                                                new Color(241, 154,  42),\n                                                new Color( 32, 171, 217),\n                                                new Color(144,  97, 207),\n                                                new Color(158, 156,   0)\n    };\n\n    private static final Color[][] PREDEFINED_GRADIENTS = new Color[][] {\n        new Color[] { new Color(245, 204, 152), new Color(255, 243, 226) },\n        new Color[] { new Color(151, 223, 246), new Color(227, 248, 255) },\n        new Color[] { new Color(200, 163, 248), new Color(242, 232, 255) },\n        new Color[] { new Color(212, 211, 131), new Color(244, 243, 217) }\n    };\n    \n\n//    /**\n//     * Returns number of colors predefined for VisualVM charts.\n//     * Always contains at least 4 colors.\n//     *\n//     * @return number of colors predefined for VisualVM charts\n//     */\n//    private static int getPredefinedColorsCount() {\n//        return PREDEFINED_COLORS.length;\n//    }\n\n    /**\n     * Returns a color predefined for VisualVM charts.\n     *\n     * @param index index of the predefined color\n     * @return color predefined for VisualVM charts\n     */\n    private static Color getPredefinedColor(int index) {\n        return PREDEFINED_COLORS[index];\n    }\n\n    static Color getColor(int index) {\n        Color color;\n\n        if (index >= PREDEFINED_COLORS.length) {\n            color = getPredefinedColor(index % PREDEFINED_COLORS.length);\n            int darkerFactor = index / PREDEFINED_COLORS.length;\n            while (darkerFactor-- > 0) color = color.darker();\n        } else {\n            color = getPredefinedColor(index);\n        }\n\n        return color;\n    }\n\n\n//    /**\n//     * Returns number of color pairs predefined for VisualVM charts gradients.\n//     * Always contains at least 4 color pairs.\n//     *\n//     * @return number of color pairs predefined for VisualVM charts gradients\n//     */\n//    private static int getPredefinedGradientsCount() {\n//        return PREDEFINED_GRADIENTS.length;\n//    }\n\n    /**\n     * Returns a color pair predefined for VisualVM charts gradients.\n     *\n     * @param index index of the predefined color pair\n     * @return color pair predefined for VisualVM charts gradients\n     */\n    private static Color[] getPredefinedGradient(int index) {\n        return PREDEFINED_GRADIENTS[index];\n    }\n\n    static Color[] getGradient(int index) {\n        Color[] colors = null;\n\n        if (index >= PREDEFINED_GRADIENTS.length) {\n            colors = getPredefinedGradient(index % PREDEFINED_GRADIENTS.length);\n            int darkerFactor = index / PREDEFINED_GRADIENTS.length;\n            while (darkerFactor-- > 0) {\n                colors[0] = colors[0].darker();\n                colors[1] = colors[1].darker();\n            }\n        } else {\n            colors = getPredefinedGradient(index);\n        }\n\n        return colors;\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelineLegendOverlay.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport org.graalvm.visualvm.modules.tracer.impl.swing.ColorIcon;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.LabelRenderer;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.LegendFont;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartOverlay;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineLegendOverlay extends ChartOverlay {\n\n    private final TimelineChart chart;\n    private final LabelRenderer painter;\n\n\n    TimelineLegendOverlay(TimelineChart chart) {\n        this.chart = chart;\n\n        painter = new LabelRenderer();\n        painter.setFont(new LegendFont());\n\n        int size = painter.getFont().getSize() - 3;\n        ColorIcon.setup(size, size,\n                LegendFont.FOREGROUND_COLOR, LegendFont.BACKGROUND_COLOR);\n    }\n\n\n    private void setupPainter(String text, Color color) {\n        painter.setText(text);\n        painter.setIcon(ColorIcon.fromColor(color));\n    }\n\n\n    public void paint(Graphics g) {\n        int rowsCount = chart.getRowsCount();\n        for (int i = 0; i < rowsCount; i++) {\n            TimelineChart.Row row = chart.getRow(i);\n            ChartContext rowContext = row.getContext();\n            SynchronousXYItem[] rowItems = row.getItems();\n\n            int x = 3;\n            int y = -1;\n\n            for (SynchronousXYItem rowItem : rowItems) {\n                TimelineXYPainter itemPainter =\n                        (TimelineXYPainter)chart.getPaintersModel().getPainter(rowItem);\n                if (itemPainter.isPainting()) {\n                    setupPainter(rowItem.getName(), itemPainter.getDefiningColor());\n                    Dimension pd = painter.getPreferredSize();\n                    if (y == -1)\n                        y = Utils.checkedInt(rowContext.getViewportOffsetY()) +\n                            rowContext.getViewportHeight() - pd.height - 1;\n                    paint(g, x, y);\n                    x += pd.width + 10;\n                }\n            }\n        }\n    }\n\n    private void paint(Graphics g, int x, int y) {\n        painter.setLocation(x, y + 1);\n        painter.setForeground(LegendFont.BACKGROUND_COLOR);\n        painter.paint(g);\n\n        painter.setLocation(x, y);\n        painter.setForeground(LegendFont.FOREGROUND_COLOR);\n        painter.setIcon(ColorIcon.BOTTOM_SHADOW);\n        painter.paint(g);\n    }\n\n    // --- Peformance tweaks ---------------------------------------------------\n\n    public void invalidate() {}\n\n    public void update(Graphics g) {}\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelineModel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.items.ValueItemDescriptor;\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\n\n/**\n * All methods must be invoked from the EDT.\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineModel implements Timeline {\n\n    private static final int STORAGE_BUFFER_STEP = 50;\n\n    private int bufferStep;\n\n    private int valuesCount;\n    private long[] timestamps;\n    private long[][] values;\n\n    private final List<TimelineXYItem> items = new ArrayList();\n\n\n    TimelineModel() {\n        this(STORAGE_BUFFER_STEP);\n    }\n    \n    private TimelineModel(int bufferStep) {\n        this.bufferStep = bufferStep;\n        reset();\n    }\n\n\n    int getItemsCount() {\n        return items.size();\n    }\n\n\n    TimelineXYItem[] createItems(ProbeItemDescriptor[] itemDescriptors) {\n        int itemsCount = values == null ? 0 : values.length;\n        int addedItemsCount = itemDescriptors.length;\n        TimelineXYItem[] itemsArr = new TimelineXYItem[addedItemsCount];\n\n        for (int i = 0; i < addedItemsCount; i++) {\n            if (itemDescriptors[i] instanceof ValueItemDescriptor) {\n                ValueItemDescriptor d = (ValueItemDescriptor)itemDescriptors[i];\n                itemsArr[i] = new TimelineXYItem(d.getName(), d.getMinValue(),\n                                                 d.getMaxValue(), itemsCount + i) {\n                    public long getYValue(int valueIndex) {\n                        return values[getIndex()][valueIndex];\n                    }\n                };\n            } else {\n                // Reserved for non-value items\n            }\n            items.add(itemsArr[i]);\n        }\n\n        addItemsImpl(addedItemsCount);\n\n        return itemsArr;\n    }\n\n    void removeItems(SynchronousXYItem[] removed) {\n        removeItemsImpl(removed.length);\n\n        int firstRemovedIndex = ((TimelineXYItem)removed[0]).getIndex();\n        for (SynchronousXYItem item : removed)\n            items.remove(firstRemovedIndex);\n        for (int i = firstRemovedIndex; i < items.size(); i++)\n            items.get(i).setIndex(i);\n    }\n\n\n    void addValues(long timestamp, long[] newValues) {\n        updateStorage();\n\n        // Check last timestamp whether greater than the new one\n        long lastTimestamp = valuesCount == 0 ? -1 : timestamps[valuesCount - 1];\n        // Silently increase timestamp, JVM was busy - timer out of sync\n        if (lastTimestamp >= timestamp) timestamp = lastTimestamp + 1;\n\n        timestamps[valuesCount] = timestamp;\n        for (int i = 0; i < values.length; i++)\n            values[i][valuesCount] = newValues[i];\n\n        valuesCount++;\n    }\n    \n\n    void reset() {\n        valuesCount = 0;\n\n        timestamps = null;\n        if (values != null) {\n            if (values.length == 0) {\n                values = null;\n            } else {\n                for (int i = 0; i < values.length; i++)\n                    values[i] = new long[0];\n            }\n        }\n    }\n\n\n    private void addItemsImpl(int addedItemsCount) {\n        int newItemsCount = (values == null ? 0 : values.length) + addedItemsCount;\n        values = new long[newItemsCount][];\n        reset();\n    }\n\n    private void removeItemsImpl(int removedItemsCount) {\n        values = new long[values.length - removedItemsCount][];\n        reset();\n    }\n\n\n    public int getTimestampsCount() {\n        return valuesCount;\n    }\n\n    public long getTimestamp(int index) {\n        return timestamps[index];\n    }\n\n\n    private void updateStorage() {\n        if (timestamps == null) {\n            timestamps = new long[bufferStep];\n            for (int i = 0; i < values.length; i++)\n                values[i] = new long[bufferStep];\n        } else if (valuesCount == timestamps.length) {\n            timestamps = extendArray(timestamps, bufferStep);\n            for (int i = 0; i < values.length; i++)\n                values[i] = extendArray(values[i], bufferStep);\n        }\n    }\n\n    private static long[] extendArray(long[] array, int extraLength) {\n        int originalLength = array.length;\n        long[] newArray = new long[originalLength + extraLength];\n        System.arraycopy(array, 0, newArray, 0, originalLength);\n        return newArray;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelinePaintersFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.items.ContinuousXYItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.items.DiscreteXYItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.items.ValueItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.items.XYItemDescriptor;\nimport java.awt.Color;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelinePaintersFactory {\n\n    static TimelineXYPainter createPainter(ProbeItemDescriptor descriptor,\n                                           int itemIndex, PointsComputer c) {\n\n        // --- ValueItem -------------------------------------------------------\n        if (descriptor instanceof ValueItemDescriptor)\n            return createValuePainter((ValueItemDescriptor)descriptor, itemIndex, c);\n\n        return null;\n    }\n\n    private static TimelineXYPainter createValuePainter(\n            ValueItemDescriptor descriptor, int itemIndex, PointsComputer c) {\n\n        // --- XYItem ----------------------------------------------------------\n        if (descriptor instanceof ContinuousXYItemDescriptor)\n            return createContinuousPainter((ContinuousXYItemDescriptor)descriptor, itemIndex, c);\n        \n        // --- BarItem ---------------------------------------------------------\n        if (descriptor instanceof DiscreteXYItemDescriptor)\n            return createDiscretePainter((DiscreteXYItemDescriptor)descriptor, itemIndex, c);\n\n        return null;\n    }\n\n    private static TimelineXYPainter createContinuousPainter(\n            XYItemDescriptor descriptor, int itemIndex, PointsComputer c) {\n\n        double dataFactor = descriptor.getDataFactor();\n\n        float lineWidth = descriptor.getLineWidth();\n        if (lineWidth == ProbeItemDescriptor.DEFAULT_LINE_WIDTH)\n            lineWidth = 2f;\n\n        Color lineColor = descriptor.getLineColor();\n        if (lineColor == ProbeItemDescriptor.DEFAULT_COLOR)\n            lineColor = TimelineColorFactory.getColor(itemIndex);\n\n        Color fillColor = descriptor.getFillColor();\n        if (fillColor == ProbeItemDescriptor.DEFAULT_COLOR) {\n            if (lineColor == null)\n                fillColor = TimelineColorFactory.getColor(itemIndex);\n            else\n                fillColor = TimelineColorFactory.getGradient(itemIndex)[0];\n        }\n\n        return new ContinuousXYPainter(lineWidth, lineColor, fillColor, dataFactor, c);\n    }\n\n    private static DiscreteXYPainter createDiscretePainter(\n            DiscreteXYItemDescriptor descriptor, int itemIndex, PointsComputer c) {\n\n        double dataFactor = descriptor.getDataFactor();\n\n        float lineWidth = descriptor.getLineWidth();\n        if (lineWidth == ProbeItemDescriptor.DEFAULT_LINE_WIDTH)\n            lineWidth = 2f;\n\n        Color lineColor = descriptor.getLineColor();\n        if (lineColor == ProbeItemDescriptor.DEFAULT_COLOR)\n            lineColor = TimelineColorFactory.getColor(itemIndex);\n\n        Color fillColor = descriptor.getFillColor();\n        if (fillColor == ProbeItemDescriptor.DEFAULT_COLOR) {\n            if (lineColor == null)\n                fillColor = TimelineColorFactory.getColor(itemIndex);\n            else\n                fillColor = TimelineColorFactory.getGradient(itemIndex)[0];\n        }\n\n        return new DiscreteXYPainter(lineWidth, lineColor, fillColor, descriptor.getWidth(),\n                                     descriptor.isFixedWidth(), descriptor.isTopLineOnly(),\n                                     descriptor.isOutlineOnly(), dataFactor, c);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelinePanel.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport java.awt.BorderLayout;\nimport java.awt.Cursor;\nimport java.awt.Toolkit;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseWheelEvent;\nimport java.awt.event.MouseWheelListener;\nimport javax.swing.AbstractButton;\nimport javax.swing.Action;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class TimelinePanel extends JPanel {\n\n    private final ChartPanel chartPanel;\n    private final RowMouseHandler mouseHandler;\n\n\n    // --- Constructor ---------------------------------------------------------\n    \n    public TimelinePanel(TimelineSupport support) {\n        super(new BorderLayout());\n        setOpaque(false);\n\n        ProbesPanel probesPanel = new ProbesPanel(support);\n        chartPanel = new ChartPanel(support.getChart(), support);\n\n        add(probesPanel, BorderLayout.WEST);\n        add(chartPanel, BorderLayout.CENTER);\n\n        new ProbesWheelHandler(chartPanel, probesPanel).register();\n        mouseHandler = new RowMouseHandler(support, probesPanel);\n        mouseHandler.register();\n    }\n\n\n    // --- Public interface ----------------------------------------------------\n\n    public void reset() {\n        chartPanel.resetChart();\n        resetSelection();\n    }\n\n    public void resetSelection() {\n        if (chartPanel.resetSelection()) mouseHandler.updateSelection();\n    }\n\n    public Action zoomInAction() {\n        return chartPanel.zoomInAction();\n    }\n\n    public Action zoomOutAction() {\n        return chartPanel.zoomOutAction();\n    }\n\n    public Action toggleViewAction() {\n        return chartPanel.toggleViewAction();\n    }\n\n    public AbstractButton mouseZoom() {\n        return chartPanel.mouseZoom();\n    }\n\n    public AbstractButton mouseHScroll() {\n        return chartPanel.mouseHScroll();\n    }\n\n    public AbstractButton mouseVScroll() {\n        return chartPanel.mouseVScroll();\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private static class ProbesWheelHandler implements MouseWheelListener {\n\n        private final ChartPanel chartPanel;\n        private final ProbesPanel probesPanel;\n\n        ProbesWheelHandler(ChartPanel chartPanel, ProbesPanel probesPanel) {\n            this.chartPanel = chartPanel;\n            this.probesPanel = probesPanel;\n        }\n\n        void register() {\n            probesPanel.addMouseWheelListener(this);\n        }\n\n        public void mouseWheelMoved(MouseWheelEvent e) {\n            chartPanel.vScroll(e);\n        }\n\n    }\n\n    private static class RowMouseHandler extends MouseAdapter {\n\n        private static final int RESIZE_RANGE = 3;\n\n        private final TimelineSupport support;\n        private final TimelineChart chart;\n        private final ProbesPanel probesPanel;\n\n        private int baseY;\n        private int baseHeight;\n        private TimelineChart.Row draggingRow;\n\n\n        RowMouseHandler(TimelineSupport support, ProbesPanel probesPanel) {\n            this.support = support;\n            this.chart = support.getChart();\n            this.probesPanel = probesPanel;\n        }\n\n\n        void register() {\n            chart.addMouseListener(this);\n            chart.addMouseMotionListener(this);\n            probesPanel.getMouseTarget().addMouseListener(this);\n            probesPanel.getMouseTarget().addMouseMotionListener(this);\n        }\n\n\n        public void mousePressed(MouseEvent e) {\n            updateRowState(e, SwingUtilities.isLeftMouseButton(e));\n            if (draggingRow != null) chart.updateSelection(false, this);\n            updateCursor();\n        }\n\n        public void mouseReleased(MouseEvent e) {\n            if (draggingRow != null) chart.updateSelection(true, this);\n            updateRowState(e, false);\n            updateCursor();\n        }\n\n//        public void mouseClicked(MouseEvent e) {\n//            if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2)\n//                if (e.getSource() == chart) ; // TODO: select row in Details\n//        }\n\n        public void mouseMoved(MouseEvent e) {\n            updateRowState(e, false);\n            updateCursor();\n        }\n\n        public void mouseDragged(MouseEvent e){\n            if (draggingRow != null) {\n                boolean checkStep = (e.getModifiers() & Toolkit.getDefaultToolkit().\n                                     getMenuShortcutKeyMask()) == 0;\n                chart.setRowHeight(draggingRow.getIndex(), baseHeight + e.getY() - baseY, checkStep);\n            }\n        }\n\n\n        private void updateRowState(MouseEvent e, boolean updateSelection) {\n            baseY = e.getY();\n            draggingRow = chart.getNearestRow(baseY, RESIZE_RANGE, true);\n            if (draggingRow != null) {\n                baseHeight = draggingRow.getHeight();\n            } else if (updateSelection) {\n                TimelineChart.Row row = chart.getRowAt(baseY);\n                if ((e.getModifiers() & Toolkit.getDefaultToolkit().\n                        getMenuShortcutKeyMask()) == 0) {\n                    if (chart.setSelectedRow(row)) updateSelection();\n                } else {\n                    if (row != null && chart.toggleRowSelection(row)) updateSelection();\n                }\n            }\n        }\n\n        void updateSelection() {\n            probesPanel.updateSelection();\n            support.rowSelectionChanged();\n        }\n\n        private void updateCursor() {\n            if (draggingRow != null) {\n                Cursor resizeCursor = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);\n                chart.setCursor(resizeCursor);\n                probesPanel.setCursor(resizeCursor);\n            } else {\n                Cursor defaultCursor = Cursor.getDefaultCursor();\n                chart.setCursor(defaultCursor);\n                probesPanel.setCursor(defaultCursor);\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelineSelectionOverlay.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport org.graalvm.visualvm.lib.charts.ChartOverlay;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionListener;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Paint;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.SortedSet;\nimport java.util.TreeSet;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineSelectionOverlay extends ChartOverlay {\n\n    private TimelineChart chart;\n    private TimelineSupport support;\n\n    private int selectionExtent;\n\n    private ConfigurationListener configurationListener;\n    private SelectionListener selectionListener;\n    private TimeSelectionListener timeSelectionListener;\n    private final Set<Point> highlightedValues;\n    private final Set<Point> selectedValues;\n\n    private Paint sMarkPaint;\n    private Paint sOddPerfPaint;\n    private Paint sEvenPerfPaint;\n\n    private Paint hMarkPaint;\n    private Paint hOddPerfPaint;\n    private Paint hEvenPerfPaint;\n\n    private Stroke markStroke;\n    private Stroke oddPerfStroke;\n    private Stroke evenPerfStroke;\n\n\n    TimelineSelectionOverlay() {\n        configurationListener = new ConfigurationListener();\n        selectionListener = new SelectionListener();\n        timeSelectionListener = new TimeSelectionListener();\n        highlightedValues = new HashSet();\n        selectedValues = new HashSet();\n        initDefaultValues();\n    }\n    \n\n    // --- Internal API --------------------------------------------------------\n\n    final void registerChart(TimelineSupport support) {\n        unregisterListener();\n        this.support = support;\n        this.chart = support.getChart();\n        registerListener();\n    }\n\n    final void unregisterChart(TimelineSupport support) {\n        unregisterListener();\n        this.support = null;\n        this.chart = null;\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void registerListener() {\n        if (support == null || chart == null) return;\n        chart.addConfigurationListener(configurationListener);\n        chart.addRowListener(configurationListener);\n        chart.getSelectionModel().addSelectionListener(selectionListener);\n        support.addSelectionListener(timeSelectionListener);\n    }\n\n    private void unregisterListener() {\n        if (support == null || chart == null) return;\n        chart.removeConfigurationListener(configurationListener);\n        chart.removeRowListener(configurationListener);\n        chart.getSelectionModel().removeSelectionListener(selectionListener);\n        support.removeSelectionListener(timeSelectionListener);\n    }\n\n    private void initDefaultValues() {\n        sMarkPaint = new Color(120, 120, 120);\n        sOddPerfPaint = new Color(120, 120, 120);\n        sEvenPerfPaint = Color.WHITE;\n\n        hMarkPaint = new Color(80, 80, 80);\n        hOddPerfPaint = Color.BLACK;\n        hEvenPerfPaint = Color.WHITE;\n\n        markStroke = new BasicStroke(2.8f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);\n        oddPerfStroke = new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 0, new float[] { 1.0f, 3.0f }, 0);\n        evenPerfStroke = new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 0, new float[] { 1.0f, 3.0f }, 2);\n\n        selectionExtent = 3;\n    }\n\n    private final Set<Integer> paintedLines = new HashSet();\n\n    public void paint(Graphics g) {\n        if (highlightedValues.isEmpty() && selectedValues.isEmpty()) return;\n\n        Graphics2D g2 = (Graphics2D)g;\n        g2.setRenderingHints(chart.getRenderingHints());\n\n        Iterator<Point> it = selectedValues.iterator();\n        paintedLines.clear();\n        \n        int height = getHeight();\n        int extentP = 1 - selectionExtent;\n        int extentD = selectionExtent * 2 - 1;\n\n        while (it.hasNext()) {\n            Point p = it.next();\n            int x = p.x;\n            int y = p.y;\n\n            if (!paintedLines.contains(x)) {\n                g2.setPaint(sEvenPerfPaint);\n                g2.setStroke(evenPerfStroke);\n                g2.drawLine(x, 0, x, height);\n                g2.setPaint(sOddPerfPaint);\n                g2.setStroke(oddPerfStroke);\n                g2.drawLine(x, 0, x, height);\n\n                g2.setPaint(sMarkPaint);\n                g2.setStroke(markStroke);\n\n                paintedLines.add(x);\n            }\n            \n            if (y - selectionExtent >= 0 && y + selectionExtent <= height)\n                g2.fillOval(x + extentP, y + extentP, extentD, extentD);\n        }\n\n        it = highlightedValues.iterator();\n        paintedLines.clear();\n\n        while (it.hasNext()) {\n            Point p = it.next();\n            int x = p.x;\n            int y = p.y;\n\n            if (!paintedLines.contains(x)) {\n                g2.setPaint(hEvenPerfPaint);\n                g2.setStroke(evenPerfStroke);\n                g2.drawLine(x, 0, x, height);\n                g2.setPaint(hOddPerfPaint);\n                g2.setStroke(oddPerfStroke);\n                g2.drawLine(x, 0, x, height);\n\n                g2.setPaint(hMarkPaint);\n                g2.setStroke(markStroke);\n\n                paintedLines.add(x);\n            }\n            \n            if (y - selectionExtent >= 0 && y + selectionExtent <= height)\n                g2.fillOval(x + extentP, y + extentP, extentD, extentD);\n        }\n\n    }\n\n    private void vLineBoundsChanged(Set<Point> oldSelection, Set<Point> newSelection) {\n        SortedSet<Integer> selectionBounds = new TreeSet();\n        for (Point p : oldSelection) selectionBounds.add(p.x);\n        int selections = selectionBounds.size();\n        if (selections == 1) {\n            repaint(selectionBounds.first() - selectionExtent,\n                    0, selectionExtent * 2, getHeight());\n            selectionBounds.clear();\n        }\n\n        for (Point p : newSelection) selectionBounds.add(p.x);\n        selections = selectionBounds.size();\n        if (selections == 1) {\n            repaint(selectionBounds.first() - selectionExtent,\n                    0, selectionExtent * 2, getHeight());\n        } else if (selections > 1) {\n            int firstX = selectionBounds.first() - selectionExtent;\n            int lastX  = selectionBounds.last() + selectionExtent;\n            repaint(firstX, 0, lastX - firstX, getHeight());\n        }\n    }\n\n    private List<ItemSelection> getSelections() {\n        List<ItemSelection> items = new ArrayList();\n\n        Set<Integer> timestamps = support.getSelectedTimestamps();\n        SynchronousXYItemsModel model = (SynchronousXYItemsModel)chart.getItemsModel();\n        int itemsCount = model.getItemsCount();\n        for (int itemIndex = 0; itemIndex < itemsCount; itemIndex++)\n            for (int timestamp : timestamps)\n                items.add(new XYItemSelection.Default(model.getItem(itemIndex),\n                          timestamp, XYItemSelection.DISTANCE_UNKNOWN));\n\n        return items;\n    }\n\n    private static void updateValues(Set<Point> values,\n                                     List<ItemSelection> selectedItems,\n                                     TimelineChart chart) {\n        values.clear();\n        for (ItemSelection sel : selectedItems) {\n            XYItemSelection xySel = (XYItemSelection)sel;\n            XYItem item = xySel.getItem();\n            TimelineXYPainter painter = (TimelineXYPainter)chart.getPaintersModel().getPainter(item);\n            ChartContext context = chart.getChartContext(item);\n            long xValue = item.getXValue(xySel.getValueIndex());\n            long yValue = item.getYValue(xySel.getValueIndex());\n            int xPos = Utils.checkedInt(Math.ceil(context.getViewX(xValue)));\n            int yPos = Utils.checkedInt(Math.ceil(painter.getItemView(yValue, item, context)));\n            if (xPos >= 0 && xPos <= chart.getWidth()) values.add(new Point(xPos, yPos));\n        }\n    }\n\n\n    private class ConfigurationListener extends ChartConfigurationListener.Adapter\n                                        implements TimelineChart.RowListener {\n        private final Runnable selectionUpdater = new Runnable() {\n            public void run() {\n                Set<Point> oldSelectedValues = new HashSet(selectedValues);\n                updateValues(selectedValues, getSelections(), chart);\n                vLineBoundsChanged(oldSelectedValues, selectedValues);\n                \n                Set<Point> oldValues = new HashSet(highlightedValues);\n                updateValues(highlightedValues, chart.getSelectionModel().\n                             getHighlightedItems(), chart);\n                vLineBoundsChanged(oldValues, highlightedValues);\n            }\n        };\n        public void contentsUpdated(long offsetX, long offsetY,\n                                    double scaleX, double scaleY,\n                                    long lastOffsetX, long lastOffsetY,\n                                    double lastScaleX, double lastScaleY,\n                                    int shiftX, int shiftY) {\n            if (highlightedValues.isEmpty() && !support.isTimestampSelection(true)) return;\n            if (lastOffsetX != offsetX || lastOffsetY != offsetY ||\n                scaleX != lastScaleX || scaleY != lastScaleY)\n                SwingUtilities.invokeLater(selectionUpdater);\n        }\n        public void rowsAdded(List<TimelineChart.Row> rows) { selectionUpdater.run(); };\n\n        public void rowsRemoved(List<TimelineChart.Row> rows) { selectionUpdater.run(); };\n\n        public void rowsResized(List<TimelineChart.Row> rows) { selectionUpdater.run(); };\n    }\n\n    private class SelectionListener implements ChartSelectionListener {\n\n        public void selectionModeChanged(int newMode, int oldMode) {}\n\n        public void selectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds) {}\n\n        public void selectedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n        }\n\n        public void highlightedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n            Set<Point> oldHighlightedValues = new HashSet(highlightedValues);\n            updateValues(highlightedValues, currentItems, chart);\n            vLineBoundsChanged(oldHighlightedValues, highlightedValues);\n        }\n\n    }\n\n    private class TimeSelectionListener implements TimelineSupport.SelectionListener {\n\n        public void rowSelectionChanged(boolean rowsSelected) {}\n\n        public void timeSelectionChanged(boolean timestampsSelected, boolean justHovering) {\n            Set<Point> oldSelectedValues = new HashSet(selectedValues);\n            updateValues(selectedValues, getSelections(), chart);\n            vLineBoundsChanged(oldSelectedValues, selectedValues);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelineSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.modules.tracer.impl.options.TracerOptions;\nimport org.graalvm.visualvm.modules.tracer.impl.details.DetailsPanel;\nimport org.graalvm.visualvm.modules.tracer.impl.details.DetailsTableModel;\nimport org.graalvm.visualvm.modules.tracer.impl.export.DataExport;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.TimelineChart.Row;\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.items.ValueItemDescriptor;\nimport java.awt.Color;\nimport java.text.Format;\nimport java.text.MessageFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.AbstractTableModel;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.axis.TimeAxisUtils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\n\n/**\n * All methods must be invoked from the EDT.\n *\n * @author Jiri Sedlacek\n */\npublic final class TimelineSupport {\n\n    public static final int[] EMPTY_TIMESTAMPS = new int[0];\n\n    private final TimelineChart chart;\n    private final TimelineModel model;\n    private final SynchronousXYItemsModel itemsModel;\n\n    private final PointsComputer pointsComputer;\n\n    private final TimelineTooltipOverlay tooltips;\n    private final TimelineLegendOverlay legend;\n    private final TimelineUnitsOverlay units;\n\n    private final List<TracerProbe> probes = new ArrayList();\n    private final List<TimelineChart.Row> rows = new ArrayList();\n    private final DescriptorResolver descriptorResolver;\n\n    private final Set<ValuesListener> valuesListeners = new HashSet();\n\n    private final Set<Integer> selectedTimestamps = new HashSet();\n    private final Set<SelectionListener> selectionListeners = new HashSet();\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    public TimelineSupport(DescriptorResolver descriptorResolver) {\n        this.descriptorResolver = descriptorResolver;\n        \n        // TODO: must be called in EDT!\n        model = new TimelineModel();\n        itemsModel = new SynchronousXYItemsModel(model);\n        chart = new TimelineChart(itemsModel);\n        tooltips = new TimelineTooltipOverlay(this);\n        chart.addOverlayComponent(tooltips);\n\n        pointsComputer = new PointsComputer();\n\n        legend = new TimelineLegendOverlay(chart);\n        legend.setVisible(TracerOptions.getInstance().isShowLegendEnabled());\n        chart.addOverlayComponent(legend);\n\n        units = new TimelineUnitsOverlay(chart);\n        units.setVisible(TracerOptions.getInstance().isShowValuesEnabled());\n        chart.addOverlayComponent(units);\n    }\n\n\n    // --- Chart access --------------------------------------------------------\n\n    TimelineChart getChart() {\n        return chart;\n    }\n\n    public ChartSelectionModel getChartSelectionModel() {\n        return chart.getSelectionModel();\n    }\n\n\n    // --- Indexes computer access ---------------------------------------------\n\n    PointsComputer getPointsComputer() {\n        return pointsComputer;\n    }\n\n\n    // --- Overlays access -----------------------------------------------------\n\n    public void setShowValuesEnabled(boolean enabled) {\n        units.setVisible(enabled);\n    }\n\n    public boolean isShowValuesEnabled() {\n        return units.isVisible();\n    }\n\n    public void setShowLegendEnabled(boolean enabled) {\n        legend.setVisible(enabled);\n    }\n\n    public boolean isShowLegendEnabled() {\n        return legend.isVisible();\n    }\n\n\n    // --- Probes management ---------------------------------------------------\n\n    public void addProbe(final TracerProbe probe) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                resetValues();\n\n                TimelineChart.Row row = chart.addRow();\n\n                probes.add(probe);\n                rows.add(row);\n\n                ProbeItemDescriptor[] itemDescriptors = probe.getItemDescriptors();\n                TimelineXYItem[] items = model.createItems(itemDescriptors);\n                XYItemPainter[] painters  = new XYItemPainter[items.length];\n                for (int i = 0; i < painters.length; i++)\n                    painters[i] = TimelinePaintersFactory.createPainter(\n                            itemDescriptors[i], i, pointsComputer);\n                \n                row.addItems(items, painters);\n\n                setupOverlays();\n            }\n        });\n    }\n\n    public void removeProbe(final TracerProbe probe) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                resetValues();\n                \n                TimelineChart.Row row = getRow(probe);\n\n                chart.removeRow(row);\n                \n                model.removeItems(row.getItems());\n\n                rows.remove(row);\n                probes.remove(probe);\n\n                setupOverlays();\n            }\n        });\n    }\n\n    public List<TracerProbe> getProbes() {\n        return probes;\n    }\n\n    public int getItemsCount() {\n        return model.getItemsCount();\n    }\n\n    public boolean hasData() {\n        return model.getTimestampsCount() > 0;\n    }\n\n\n    // --- Tooltips support ----------------------------------------------------\n\n    private void setupOverlays() {\n        final int rowsCount = chart.getRowsCount();\n\n        TimelineTooltipPainter.Model[] rowModels = new TimelineTooltipPainter.Model[rowsCount];\n        \n        for (int rowIndex = 0; rowIndex < rowModels.length; rowIndex++) {\n            final TimelineChart.Row row = chart.getRow(rowIndex);\n            final TracerProbe probe = getProbe(row);\n\n            final int itemsCount = row.getItemsCount();\n            final String[] rowNames = new String[itemsCount];\n            final ValueItemDescriptor[] viDescriptors = new ValueItemDescriptor[itemsCount];\n            final String[] unitsStrings = new String[itemsCount];\n            for (int itemIndex = 0; itemIndex < itemsCount; itemIndex++) {\n                rowNames[itemIndex] = ((TimelineXYItem)row.getItem(itemIndex)).getName();\n                viDescriptors[itemIndex] = (ValueItemDescriptor)probe.getItemDescriptors()[itemIndex];\n                unitsStrings[itemIndex] = viDescriptors[itemIndex].getUnitsString(ItemValueFormatter.FORMAT_TOOLTIP);\n            }\n\n            rowModels[rowIndex] = new TimelineTooltipPainter.Model() {\n\n                public int getRowsCount() {\n                    return itemsCount;\n                }\n\n                public String getRowName(int index) {\n                    return rowNames[index];\n                }\n\n                public String getRowValue(int index, long itemValue) {\n                    return viDescriptors[index].getValueString(itemValue,\n                            ItemValueFormatter.FORMAT_TOOLTIP);\n                }\n\n                public String getRowUnits(int index) {\n                    return unitsStrings[index];\n                }\n\n            };\n        }\n        tooltips.setupModel(rowModels);\n\n        units.setupModel(new TimelineUnitsOverlay.Model() {\n\n            private final String LAST_UNITS_STRING = \"lastUnitsString\"; // NOI18N\n\n            private Color[][] rowColors = new Color[rowsCount][];\n            private String[][] rowMinValues = new String[rowsCount][];\n            private String[][] rowMaxValues = new String[rowsCount][];\n\n            private List<Color> visibleRowItemColors;\n            private List<String> visibleRowItemMinValues;\n            private List<String> visibleRowItemMaxValues;\n\n            public void prefetch() {\n                PaintersModel paintersModel = chart.getPaintersModel();\n                for (int rowIndex = 0; rowIndex < rowsCount; rowIndex++) {\n                    \n                    Row row = chart.getRow(rowIndex);\n                    TracerProbe probe = getProbe(row);\n                    int rowItemsCount = row.getItemsCount();\n\n                    ChartContext rowContext = row.getContext();\n                    long commonMinY = rowContext.getDataOffsetY();\n                    long commonMaxY = commonMinY + rowContext.getDataHeight();\n\n                    if (visibleRowItemColors != null) {\n                        visibleRowItemColors.clear();\n                        visibleRowItemMinValues.clear();\n                        visibleRowItemMaxValues.clear();\n                    } else {\n                        visibleRowItemColors = new ArrayList(rowItemsCount);\n                        visibleRowItemMinValues = new ArrayList(rowItemsCount);\n                        visibleRowItemMaxValues = new ArrayList(rowItemsCount);\n                    }\n                    \n                    boolean sameFactorUnits = true;\n                    double lastDataFactor = -1;\n                    String lastUnitsString = LAST_UNITS_STRING;\n\n                    for (int itemIndex = 0; itemIndex < rowItemsCount; itemIndex++) {\n                        TimelineXYItem item = (TimelineXYItem)row.getItem(itemIndex);\n                        TimelineXYPainter painter =\n                                (TimelineXYPainter)paintersModel.getPainter(item);\n\n                        if (painter.isPainting()) {\n                            visibleRowItemColors.add(painter.getDefiningColor());\n\n                            ValueItemDescriptor descriptor = (ValueItemDescriptor)\n                                    probe.getItemDescriptors()[itemIndex];\n\n                            double dataFactor = descriptor.getDataFactor();\n                            String unitsString = descriptor.getUnitsString(\n                                    ItemValueFormatter.FORMAT_UNITS);\n                            \n                            if (sameFactorUnits) {\n                                if (lastDataFactor == -1)\n                                    lastDataFactor = dataFactor;\n                                else if (lastDataFactor != dataFactor)\n                                    sameFactorUnits = false;\n                                lastDataFactor = dataFactor;\n                                \n                                if (lastUnitsString == LAST_UNITS_STRING)\n                                    lastUnitsString = unitsString;\n                                else if (!equals(lastUnitsString, unitsString))\n                                    sameFactorUnits = false;\n                                lastUnitsString = unitsString;\n                            }\n\n                            String minValueString = descriptor.getValueString(\n                                    (long)(commonMinY / painter.dataFactor),\n                                    ItemValueFormatter.FORMAT_UNITS);\n                            visibleRowItemMinValues.add(unitsString == null ?\n                                minValueString : minValueString + \" \" + unitsString);\n                            \n                            String maxValueString = descriptor.getValueString(\n                                    (long)(commonMaxY / painter.dataFactor),\n                                    ItemValueFormatter.FORMAT_UNITS);\n                            visibleRowItemMaxValues.add(unitsString == null ?\n                                maxValueString : maxValueString + \" \" + unitsString);\n                        }\n                    }\n\n                    if (sameFactorUnits) {\n                        rowColors[rowIndex] = new Color[] { null };\n                        rowMinValues[rowIndex] =\n                                new String[] { visibleRowItemMinValues.get(0) };\n                        rowMaxValues[rowIndex] =\n                                new String[] { visibleRowItemMaxValues.get(0) };\n                    } else {\n                        rowColors[rowIndex] = visibleRowItemColors.toArray(\n                                new Color[visibleRowItemColors.size()]);\n                        rowMinValues[rowIndex] = visibleRowItemMinValues.toArray(\n                                new String[visibleRowItemMinValues.size()]);\n                        rowMaxValues[rowIndex] = visibleRowItemMaxValues.toArray(\n                                new String[visibleRowItemMaxValues.size()]);\n                    }\n                }\n            }\n\n            public Color[] getColors(Row row) {\n                return rowColors[row.getIndex()];\n            }\n\n            public String[] getMinUnits(TimelineChart.Row row) {\n                return rowMinValues[row.getIndex()];\n            }\n\n            public String[] getMaxUnits(TimelineChart.Row row) {\n                return rowMaxValues[row.getIndex()];\n            }\n\n            private boolean equals(String s1, String s2) {\n                if (s1 == null) {\n                    if (s2 == null) return true;\n                    else return false;\n                } else {\n                    return s1.equals(s2);\n                }\n            }\n            \n        });\n    }\n\n\n    // --- Rows <-> Probes mapping ---------------------------------------------\n\n    TimelineChart.Row getRow(TracerProbe probe) {\n        return rows.get(probes.indexOf(probe));\n    }\n\n    TracerProbe getProbe(TimelineChart.Row row) {\n        return probes.get(rows.indexOf(row));\n    }\n\n\n    // --- Probe -> Descriptor mapping -----------------------------------------\n\n    TracerProbeDescriptor getDescriptor(TracerProbe p) {\n        return descriptorResolver.getDescriptor(p);\n    }\n\n\n    // --- Values management ---------------------------------------------------\n\n    public void addValues(final long timestamp, final long[] newValues) {\n        int newRow = detailsModel == null ? -1 : detailsModel.getRowCount();\n        model.addValues(timestamp, newValues);\n        itemsModel.valuesAdded();\n        if (newRow != -1) detailsModel.fireTableRowsInserted(newRow, newRow);\n        fireValuesAdded();\n    }\n\n    public void resetValues() {\n        model.reset();\n        itemsModel.valuesReset();\n        resetSelectedTimestamps();\n        pointsComputer.reset();\n        if (detailsModel != null) detailsModel.fireTableStructureChanged();\n        fireValuesReset();\n    }\n\n    public void exportAllValues(String title) {\n        final int rowsCount = model.getTimestampsCount();\n        final int columnsCount = model.getItemsCount();\n        \n        final Format timeFormatter = new SimpleDateFormat(MessageFormat.format(\n                                     TimeAxisUtils.TIME_DATE_FORMAT, new Object[] {\n                                     TimeAxisUtils.TIME_MSEC, TimeAxisUtils.DATE_YEAR}));\n\n        final List<ProbeItemDescriptor> probeDescriptors = new ArrayList(columnsCount);\n        for (TracerProbe probe : probes)\n            probeDescriptors.addAll(Arrays.asList(probe.getItemDescriptors()));\n        final ValueItemDescriptor[] descriptors = new ValueItemDescriptor[columnsCount];\n        for (int i = 0; i < columnsCount; i++)\n            descriptors[i] = (ValueItemDescriptor)probeDescriptors.get(i);\n\n        TableModel exportModel = new AbstractTableModel() {\n            public int getRowCount() {\n                return rowsCount;\n            }\n\n            public int getColumnCount() {\n                return columnsCount + 1;\n            }\n\n            public String getColumnName(int columnIndex) {\n                if (columnIndex == 0) return \"Time [ms]\";\n\n                String unitsString = descriptors[columnIndex - 1].getUnitsString(\n                                     ItemValueFormatter.FORMAT_EXPORT);\n                unitsString = unitsString == null ? \"\" : \" [\" + unitsString + \"]\";\n                return itemsModel.getItem(columnIndex - 1).getName() + unitsString;\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                if (columnIndex == 0) return timeFormatter.format(model.\n                                             getTimestamp(rowIndex));\n\n                long value = itemsModel.getItem(columnIndex - 1).getYValue(rowIndex);\n                return descriptors[columnIndex - 1].getValueString(value,\n                                                    ItemValueFormatter.FORMAT_EXPORT);\n            }\n        };\n        DataExport.exportData(exportModel, title);\n    }\n\n    public void exportDetailsValues(String title) {\n        if (detailsModel == null) return;\n\n        final int rowsCount = detailsModel.getRowCount();\n        final int columnsCount = detailsModel.getColumnCount();\n\n        final Format timeFormatter = new SimpleDateFormat(MessageFormat.format(\n                                     TimeAxisUtils.TIME_DATE_FORMAT, new Object[] {\n                                     TimeAxisUtils.TIME_MSEC, TimeAxisUtils.DATE_YEAR}));\n        \n        TableModel exportModel = new AbstractTableModel() {\n            public int getRowCount() {\n                return rowsCount;\n            }\n\n            public int getColumnCount() {\n                return columnsCount - 1;\n            }\n\n            public String getColumnName(int columnIndex) {\n                return detailsModel.getColumnName(columnIndex + 1);\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                Object value = detailsModel.getValueAt(rowIndex, columnIndex + 1);\n\n                if (columnIndex == 0) return timeFormatter.format(value);\n\n                return detailsModel.getDescriptor(columnIndex + 1).getValueString(\n                                    (Long)value, ItemValueFormatter.FORMAT_EXPORT);\n            }\n        };\n        DataExport.exportData(exportModel, title);\n    }\n\n    public void addValuesListener(ValuesListener listener) {\n        valuesListeners.add(listener);\n    }\n\n    public void removeValuesListener(ValuesListener listener) {\n        valuesListeners.remove(listener);\n    }\n    \n    private void fireValuesAdded() {\n        for (ValuesListener listener : valuesListeners)\n            listener.valuesAdded();\n    }\n    \n    private void fireValuesReset() {\n        for (ValuesListener listener : valuesListeners)\n            listener.valuesReset();\n    }\n\n\n    public static interface ValuesListener {\n\n        public void valuesAdded();\n\n        public void valuesReset();\n\n    }\n\n    // --- Row selection management --------------------------------------------\n\n    private DetailsTableModel detailsModel;\n\n    void rowSelectionChanged() {\n        updateSelectedItems();\n        notifyRowSelectionChanged();\n    }\n\n    public boolean isRowSelection() {\n        return chart.isRowSelection();\n    }\n\n    public TableModel getDetailsModel() {\n        if (!chart.isRowSelection()) detailsModel = null;\n        else detailsModel = createSelectionModel();\n        return detailsModel;\n    }\n\n    private DetailsTableModel createSelectionModel() {\n        final List<SynchronousXYItem> selectedItems = getSelectedItems();\n        final List<ValueItemDescriptor> selectedDescriptors = getSelectedDescriptors();\n        int selectedItemsCount = selectedItems.size();\n        \n        final int columnCount = selectedItemsCount + 2;\n        final SynchronousXYItem[] selectedItemsArr =\n                selectedItems.toArray(new SynchronousXYItem[selectedItemsCount]);\n        final String[] columnNames = new String[columnCount];\n        columnNames[0] = \"Mark\";\n        columnNames[1] = \"Time [ms]\";\n        final String[] columnTooltips = new String[columnCount];\n        columnTooltips[0] = \"Mark a timestamp in Timeline view\";\n        columnTooltips[1] = \"Timestamp of the data\";\n        for (int i = 2; i < columnCount; i++) {\n            String itemName = selectedItemsArr[i - 2].getName();\n            String unitsString = selectedDescriptors.get(i - 2).\n                                 getUnitsString(ItemValueFormatter.FORMAT_DETAILS);\n            unitsString = unitsString == null ? \"\" : \" [\" + unitsString + \"]\";\n            columnNames[i] = itemName + unitsString;\n            columnTooltips[i] = selectedDescriptors.get(i - 2).getDescription();\n        }\n\n        return new DetailsTableModel() {\n\n            public int getRowCount() {\n                return model.getTimestampsCount();\n            }\n\n            public int getColumnCount() {\n                return columnCount;\n            }\n\n            public String getColumnName(int columnIndex) {\n                return columnNames[columnIndex];\n            }\n\n            public String getColumnTooltip(int columnIndex) {\n                return columnTooltips[columnIndex];\n            }\n\n            public Class getColumnClass(int columnIndex) {\n                if (columnIndex == 0) return Boolean.class;\n                if (columnIndex == 1) return DetailsPanel.class;\n                return Long.class;\n            }\n\n            public ValueItemDescriptor getDescriptor(int columnIndex) {\n                if (columnIndex == 0) return null;\n                if (columnIndex == 1) return null;\n                return selectedDescriptors.get(columnIndex - 2);\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                if (columnIndex == 0) return selectedTimestamps.contains(rowIndex);\n                if (columnIndex == 1) return model.getTimestamp(rowIndex);\n                return selectedItemsArr[columnIndex - 2].getYValue(rowIndex);\n            }\n\n            public boolean isCellEditable(int rowIndex, int columnIndex) {\n                return columnIndex == 0;\n            }\n\n            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {\n                if (Boolean.TRUE.equals(aValue)) selectTimestamp(rowIndex, true, false);\n                else unselectTimestamp(rowIndex, false);\n            }\n\n        };\n    }\n\n\n    // --- Time selection management -------------------------------------------\n\n    private static final int SCROLL_MARGIN_LEFT = 10;\n    private static final int SCROLL_MARGIN_RIGHT = 50;\n\n    private boolean hovering;\n    private boolean hoveredSelected;\n\n    \n    void setTimestampHovering(boolean hovering, boolean hoveredSelected) {\n        this.hovering = hovering;\n        this.hoveredSelected = hoveredSelected;\n        notifyTimeSelectionChanged();\n    }\n\n    public void selectTimestamp(int index, boolean scrollToVisible) {\n        selectTimestamp(index, scrollToVisible, true);\n    }\n\n    private void selectTimestamp(int index, boolean scrollToVisible, boolean notifyTable) {\n        boolean change = selectedTimestamps.add(index);\n        if (notifyTable && detailsModel != null)\n            detailsModel.fireTableCellUpdated(index, 0);\n        if (change) {\n            updateSelectedItems();\n            notifyTimeSelectionChanged();\n            if (scrollToVisible) highlightTimestamp(index);\n        }\n    }\n\n    public void unselectTimestamp(int index) {\n        unselectTimestamp(index, true);\n    }\n\n    public void toggleTimestampSelection(int index) {\n        if (!selectedTimestamps.contains(index)) selectTimestamp(index, false);\n        else unselectTimestamp(index);\n    }\n\n    public boolean isTimestampSelected(int index) {\n        return selectedTimestamps.contains(index);\n    }\n\n    public boolean isTimestampSelection(boolean includeHover) {\n        int selectedTimestampsCount = selectedTimestamps.size();\n        if (selectedTimestampsCount == 0) return false;\n        if (selectedTimestampsCount > 1)  return true;\n        return (includeHover || !hovering || hoveredSelected);\n    }\n\n\n    private void unselectTimestamp(int index, boolean notifyTable) {\n        boolean change = selectedTimestamps.remove(index);\n        if (notifyTable && detailsModel != null)\n            detailsModel.fireTableCellUpdated(index, 0);\n        if (change) {\n            updateSelectedItems();\n            notifyTimeSelectionChanged();\n        }\n    }\n\n    public void resetSelectedTimestamps() {\n        if (selectedTimestamps.isEmpty()) return;\n        selectedTimestamps.clear();\n        if (detailsModel != null) detailsModel.fireTableDataChanged();\n        updateSelectedItems();\n        notifyTimeSelectionChanged();\n    }\n\n    private void updateSelectedItems() {\n        List<SynchronousXYItem> selectedItems = getSelectedItems();\n        List<ItemSelection> selections =\n                new ArrayList(selectedItems.size() * selectedTimestamps.size());\n\n        for (int selectedIndex : selectedTimestamps)\n            for (SynchronousXYItem selectedItem : selectedItems)\n                selections.add(new XYItemSelection.Default(selectedItem,\n                               selectedIndex, XYItemSelection.DISTANCE_UNKNOWN));\n\n        chart.getSelectionModel().setSelectedItems(selections);\n    }\n\n    public Set<Integer> getSelectedTimestamps() {\n        return selectedTimestamps;\n    }\n\n    private void highlightTimestamp(int selectedIndex) {\n//        List<SynchronousXYItem> selectedItems = new ArrayList();\n//        if (selectedIndex != -1) {\n//            int rowsCount = chart.getRowsCount();\n//            for (int i = 0; i < rowsCount; i++)\n//                selectedItems.addAll(Arrays.asList(chart.getRow(i).getItems()));\n//        }\n//        List<ItemSelection> selections = new ArrayList(selectedItems.size());\n//        if (selectedIndex != -1) {\n//            for (SynchronousXYItem selectedItem : selectedItems)\n//                selections.add(new XYItemSelection.Default(selectedItem,\n//                               selectedIndex, XYItemSelection.DISTANCE_UNKNOWN));\n//        }\n//\n        ChartSelectionModel selectionModel = chart.getSelectionModel();\n        List<ItemSelection> oldSelection = selectionModel.getHighlightedItems();\n        int oldSelectedIndex = -1;\n        if (!oldSelection.isEmpty()) {\n            XYItemSelection sel = (XYItemSelection)oldSelection.get(0);\n            oldSelectedIndex = sel.getValueIndex();\n        }\n//        selectionModel.setHighlightedItems(selections);\n\n        if (selectedIndex != -1)\n            scrollChartToSelection(oldSelectedIndex, selectedIndex);\n    }\n\n\n    public void scrollChartToIndex(int index) {\n        scrollChartToSelection(-1, index);\n    }\n\n    private void scrollChartToSelection(int oldIndex, int newIndex) {\n        Timeline timeline = itemsModel.getTimeline();\n        ChartContext context = chart.getChartContext();\n        long dataOffsetX = context.getDataOffsetX();\n        long newDataX = timeline.getTimestamp(newIndex);\n        long newOffsetX = (long)context.getViewWidth(newDataX - dataOffsetX);\n\n        long offsetX = chart.getOffsetX();\n        long viewWidth = context.getViewportWidth();\n        if (newOffsetX >= offsetX + SCROLL_MARGIN_LEFT &&\n            newOffsetX <= offsetX + viewWidth - SCROLL_MARGIN_RIGHT) return;\n\n        long oldDataX = oldIndex == -1 ? -1 : timeline.getTimestamp(oldIndex);\n        long oldOffsetX = oldIndex == -1 ? -1 : (long)context.getViewWidth(oldDataX - dataOffsetX);\n\n        if (oldIndex == -1) {\n            chart.setOffset(newOffsetX - context.getViewportWidth() / 2, chart.getOffsetY());\n        } else if (oldOffsetX > newOffsetX) {\n            chart.setOffset(newOffsetX - SCROLL_MARGIN_LEFT, chart.getOffsetY());\n        } else {\n            chart.setOffset(newOffsetX - context.getViewportWidth() + SCROLL_MARGIN_RIGHT, chart.getOffsetY());\n        }\n\n        chart.repaintDirty();\n    }\n\n\n    private List<SynchronousXYItem> getSelectedItems() {\n        List<TimelineChart.Row> selectedRows = chart.getSelectedRows();\n        List<SynchronousXYItem> selectedItems = new ArrayList();\n        for (TimelineChart.Row selectedRow : selectedRows)\n            selectedItems.addAll(Arrays.asList(selectedRow.getItems()));\n        return selectedItems;\n    }\n\n    private List<ValueItemDescriptor> getSelectedDescriptors() {\n        List<TimelineChart.Row> selectedRows = chart.getSelectedRows();\n        List selectedDescriptors = new ArrayList();\n        for (TimelineChart.Row selectedRow : selectedRows)\n            selectedDescriptors.addAll(Arrays.asList(getProbe(selectedRow).getItemDescriptors()));\n        return selectedDescriptors;\n    }\n\n\n    // --- General selection support -------------------------------------------\n\n    public void addSelectionListener(SelectionListener listener) {\n        selectionListeners.add(listener);\n    }\n\n    public void removeSelectionListener(SelectionListener listener) {\n        selectionListeners.remove(listener);\n    }\n\n    private void notifyRowSelectionChanged() {\n        boolean rowsSelected = chart.isRowSelection();\n        for (SelectionListener selectionListener: selectionListeners)\n            selectionListener.rowSelectionChanged(rowsSelected);\n    }\n\n    private void notifyTimeSelectionChanged() {\n        boolean sel = isTimestampSelection(true);\n        boolean hov = sel && !isTimestampSelection(false);\n        for (SelectionListener selectionListener: selectionListeners)\n            selectionListener.timeSelectionChanged(sel, hov);\n    }\n\n\n    public static interface SelectionListener {\n\n        public void rowSelectionChanged(boolean rowsSelected);\n\n        public void timeSelectionChanged(boolean timestampsSelected,\n                                         boolean justHovering);\n\n    }\n\n    public static interface DescriptorResolver {\n\n        public TracerProbeDescriptor getDescriptor(TracerProbe p);\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelineTooltipOverlay.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport org.graalvm.visualvm.modules.tracer.impl.timeline.TimelineChart.Row;\nimport org.graalvm.visualvm.lib.charts.ChartOverlay;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionListener;\nimport org.graalvm.visualvm.lib.charts.ItemPainter;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport java.awt.Graphics;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.TreeSet;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineTooltipOverlay extends ChartOverlay implements ActionListener {\n\n    static final int TOOLTIP_OFFSET = 15;\n    static final int TOOLTIP_MARGIN = 10;\n    private static final int TOOLTIP_RESPONSE = 50;\n    private static final int ANIMATION_STEPS = 5;\n\n    private TimelineTooltipPainter.Model[] rowModels;\n\n    private Set<Integer> selectedTimestamps = Collections.EMPTY_SET;\n\n    private Timer timer;\n    private int currentStep;\n    private Point[] targetPositions;\n\n\n    TimelineTooltipOverlay(final TimelineSupport support) {\n        final TimelineChart chart = support.getChart();\n\n        if (chart.getSelectionModel() == null)\n            throw new NullPointerException(\"No ChartSelectionModel set for \" + chart); // NOI18N\n\n        if (!Utils.forceSpeed()) {\n            timer = new Timer(TOOLTIP_RESPONSE / ANIMATION_STEPS, this);\n            timer.setInitialDelay(0);\n        }\n\n        setLayout(null);\n\n        final Runnable tooltipUpdater = new Runnable() {\n            public void run() { updateTooltip(chart); }\n        };\n\n        chart.getSelectionModel().addSelectionListener(new ChartSelectionListener() {\n\n            public void selectionModeChanged(int newMode, int oldMode) {}\n\n            public void selectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds) {}\n\n            public void highlightedItemsChanged(List<ItemSelection> currentItems,\n                List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n                tooltipUpdater.run();\n            }\n\n            public void selectedItemsChanged(List<ItemSelection> currentItems,\n                List<ItemSelection> addedItems, List<ItemSelection> removedItems) {}\n\n        });\n\n        chart.addConfigurationListener(new ChartConfigurationListener.Adapter() {\n            \n            public void contentsUpdated(long offsetX, long offsetY,\n                                    double scaleX, double scaleY,\n                                    long lastOffsetX, long lastOffsetY,\n                                    double lastScaleX, double lastScaleY,\n                                    int shiftX, int shiftY) {\n                if (lastOffsetX != offsetX || lastOffsetY != offsetY ||\n                    scaleX != lastScaleX || scaleY != lastScaleY)\n                    SwingUtilities.invokeLater(tooltipUpdater);\n            }\n\n        });\n\n        chart.addRowListener(new TimelineChart.RowListener() {\n\n            public void rowsAdded(List<Row> rows) { tooltipUpdater.run(); }\n\n            public void rowsRemoved(List<Row> rows) { tooltipUpdater.run(); }\n\n            public void rowsResized(List<Row> rows) { tooltipUpdater.run(); }\n        });\n\n        support.addSelectionListener(new TimelineSupport.SelectionListener() {\n\n            public void rowSelectionChanged(boolean rowsSelected) {}\n\n            public void timeSelectionChanged(boolean timestampsSelected, boolean justHovering) {\n                selectedTimestamps = new TreeSet(support.getSelectedTimestamps());\n                tooltipUpdater.run();\n            }\n        });\n    }\n\n    void setupModel(TimelineTooltipPainter.Model[] rowModels) {\n        removeAll();\n        \n        this.rowModels = rowModels;\n\n        for (TimelineTooltipPainter.Model rowModel : rowModels) {\n            TimelineTooltipPainter painter = new TimelineTooltipPainter(false);\n            add(painter);\n            painter.setVisible(false);\n        }\n\n        targetPositions = new Point[rowModels.length];\n    }\n\n    private void setPosition(Point p, TimelineTooltipPainter tooltipPainter,\n                             int index, boolean immediate) {\n        if (getComponentCount() > 0) {\n            if (p == null) {\n                if (tooltipPainter.isVisible()) tooltipPainter.setVisible(false);\n                if (timer != null) timer.stop();\n            } else {\n                if (immediate || !tooltipPainter.isVisible() || timer == null) {\n                    tooltipPainter.setVisible(true);\n                    tooltipPainter.setLocation(p);\n                } else {\n                    currentStep = 0;\n                    targetPositions[index] = p;\n                    timer.restart();\n                }\n            }\n        }\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        for (int i = 0; i < rowModels.length; i++) {\n            TimelineTooltipPainter tooltipPainter = (TimelineTooltipPainter)getComponent(i);\n            Point targetPosition = targetPositions[i];\n            Point currentPosition = tooltipPainter.getLocation();\n\n            currentPosition.x += (targetPosition.x - currentPosition.x) /\n                                 (ANIMATION_STEPS - currentStep);\n            currentPosition.y += (targetPosition.y - currentPosition.y) /\n                                 (ANIMATION_STEPS - currentStep);\n            tooltipPainter.setLocation(currentPosition);\n        }\n        if (++currentStep == ANIMATION_STEPS) timer.stop();\n    }\n\n\n    private void checkAllocatedSelectionPainters() {\n        int allocatedPainters = getComponentCount() - rowModels.length;\n        int requiredPainters = rowModels.length * selectedTimestamps.size();\n        if (allocatedPainters == requiredPainters) return;\n\n        int diff = requiredPainters - allocatedPainters;\n        if (diff > 0) {\n            for (int i = 0; i < diff; i++) add(new TimelineTooltipPainter(true));\n        } else {\n            for (int i = 0; i > diff; i--) remove(getComponentCount() - 1);\n            repaint();\n        }\n    }\n\n    @SuppressWarnings(\"element-type-mismatch\")\n    private void updateTooltip(TimelineChart chart) {\n        if (rowModels == null) return;\n\n        ChartSelectionModel selectionModel = chart.getSelectionModel();\n        if (selectionModel == null) return;\n\n        checkAllocatedSelectionPainters();\n        \n        int painterIndex = getComponentCount() - 1;\n        for (int rowIndex = 0; rowIndex < chart.getRowsCount(); rowIndex++) {\n            TimelineChart.Row row = chart.getRow(rowIndex);\n            ChartContext rowContext = row.getContext();\n            int itemsCount = row.getItemsCount();\n            TimelineTooltipPainter.Model model = rowModels[rowIndex];\n            for (int mark : selectedTimestamps) {\n                List<ItemSelection> selections = new ArrayList(itemsCount);\n                for (int itemIndex = 0; itemIndex < itemsCount; itemIndex++) {\n                    SynchronousXYItem item = (SynchronousXYItem)row.getItem(itemIndex);\n                    selections.add(new XYItemSelection.Default(item, mark,\n                                   XYItemSelection.DISTANCE_UNKNOWN));\n                }\n                TimelineTooltipPainter tooltipPainter =\n                        (TimelineTooltipPainter)getComponent(painterIndex--);\n                tooltipPainter.update(model, selections);\n                tooltipPainter.setSize(tooltipPainter.getPreferredSize());\n                setPosition(selections, chart.getPaintersModel(), rowContext,\n                            tooltipPainter, rowIndex, true);\n            }\n        }\n\n        List<ItemSelection> highlightedItems =\n                selectionModel.getHighlightedItems();\n\n        boolean noSelection = highlightedItems.isEmpty();\n        if (!noSelection) {\n            XYItemSelection sel = (XYItemSelection)highlightedItems.get(0);\n            noSelection = sel.getItem().getValuesCount() <= sel.getValueIndex();\n        }\n\n        int rowsCount = chart.getRowsCount();\n        for (int i = 0; i < rowsCount; i++) {\n            TimelineTooltipPainter tooltipPainter =\n                    (TimelineTooltipPainter)getComponent(i);\n            if (noSelection) {\n                setPosition(null, tooltipPainter, i, false);\n            } else {\n                TimelineChart.Row row = chart.getRow(i);\n                List<ItemSelection> selections = new ArrayList(highlightedItems.size());\n\n                for (ItemSelection sel : highlightedItems)\n                    if (row.containsItem(sel.getItem()))\n                        selections.add(sel);\n                \n                tooltipPainter.update(rowModels[i], selections);\n                tooltipPainter.setSize(tooltipPainter.getPreferredSize());\n                setPosition(selections, chart.getPaintersModel(), row.getContext(), tooltipPainter, i, false);\n            }\n        }\n    }\n\n    private void setPosition(List<ItemSelection> selectedItems, PaintersModel paintersModel,\n                             ChartContext chartContext, TimelineTooltipPainter tooltipPainter,\n                             int index, boolean immediate) {\n        LongRect bounds = null;\n\n        for (ItemSelection selection : selectedItems) {\n            ItemPainter painter = paintersModel.getPainter(selection.getItem());\n            LongRect selBounds = painter.getSelectionBounds(selection, chartContext);\n            if (bounds == null) bounds = selBounds; else LongRect.add(bounds, selBounds);\n        }\n\n        setPosition(normalizePosition(Utils.checkedRectangle(bounds), tooltipPainter,\n                    chartContext), tooltipPainter, index, immediate);\n    }\n\n    private Point normalizePosition(Rectangle bounds, TimelineTooltipPainter tooltipPainter, ChartContext chartContext) {\n        Point p = new Point();\n\n        p.x = bounds.x + bounds.width + TOOLTIP_OFFSET;\n        if (p.x > chartContext.getViewportWidth() - tooltipPainter.getWidth() - TOOLTIP_MARGIN)\n            p.x = bounds.x - tooltipPainter.getWidth() - TOOLTIP_OFFSET;\n\n        int rowY = Utils.checkedInt(chartContext.getViewportOffsetY());\n        int rowHeight = chartContext.getViewportHeight();\n        p.y = rowY + (rowHeight - tooltipPainter.getHeight()) / 2;\n\n        return p;\n    }\n\n\n    public void paint(Graphics g) {\n        if (getComponentCount() == 0) return;\n\n        Rectangle bounds = new Rectangle(0, 0, getWidth(), getHeight());\n        Rectangle clip = g.getClipBounds();\n        if (clip == null) g.setClip(bounds);\n        else g.setClip(clip.intersection(bounds));\n\n        super.paint(g);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelineTooltipPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.LegendFont;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineTooltipPainter extends JPanel {\n\n    private static Color SELECTION_FOREGROUND = Color.BLACK;\n    private static Color SELECTION_BACKGROUND = Utils.forceSpeed() ?\n                                            new Color(255, 255, 255) :\n                                            new Color(255, 255, 255, 225);\n    private static Color HOVER_FOREGROUND = Color.WHITE;\n    private static Color HOVER_BACKGROUND = Utils.forceSpeed() ?\n                                            new Color(80, 80, 80) :\n                                            new Color(0, 0, 0, 170);\n\n    private JLabel[] valueNames;\n    private JLabel[] valuePainters;\n    private JLabel[] unitsPainters;\n\n    private final boolean selection;\n    private final Color foreground;\n    private final Color background;\n\n\n    TimelineTooltipPainter(boolean selection) {\n        this.selection = selection;\n\n        foreground = selection ? SELECTION_FOREGROUND : HOVER_FOREGROUND;\n        background = selection ? SELECTION_BACKGROUND : HOVER_BACKGROUND;\n\n        initUI();\n    }\n\n\n    void update(Model rowModel, List<ItemSelection> selectedItems) {\n        int rowsCount = rowModel.getRowsCount();\n        if (valueNames == null || valueNames.length != rowsCount)\n            initComponents(rowsCount);\n        \n        for (int i = 0; i < rowsCount; i++) {\n            XYItemSelection sel = (XYItemSelection)selectedItems.get(i);\n            long itemValue = sel.getItem().getYValue(sel.getValueIndex());\n            valueNames[i].setText(rowModel.getRowName(i));\n            valuePainters[i].setText(rowModel.getRowValue(i, itemValue));\n            unitsPainters[i].setText(rowModel.getRowUnits(i));\n        }\n    }\n\n\n    protected void paintComponent(Graphics g) {\n        g.setColor(background);\n        g.fillRect(0, 0, getWidth(), getHeight());\n        super.paintComponent(g);\n        if (selection) {\n            g.setColor(foreground);\n            g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);\n        }\n    }\n\n\n    private void initUI() {\n        setOpaque(false);\n        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));\n\n        setLayout(new GridBagLayout());\n    }\n\n    private void initComponents(int rowsCount) {\n        removeAll();\n        \n        valueNames = new JLabel[rowsCount];\n        valuePainters = new JLabel[rowsCount];\n        unitsPainters = new JLabel[rowsCount];\n        \n        GridBagConstraints constraints;\n\n        for (int i = 0; i < rowsCount; i++) {\n            JLabel itemLabel = new JLabel();\n            valueNames[i] = itemLabel;\n            itemLabel.setFont(new LegendFont());\n            itemLabel.setForeground(foreground);\n            itemLabel.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = i;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            add(itemLabel, constraints);\n\n            JLabel valueLabel = new JLabel();\n            valuePainters[i] = valueLabel;\n            valueLabel.setFont(new LegendFont());\n            valueLabel.setForeground(foreground);\n            valueLabel.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = i;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.insets = new Insets(0, 8, 0, 0);\n            add(valueLabel, constraints);\n\n            JLabel unitsLabel = new JLabel();\n            unitsPainters[i] = unitsLabel;\n            unitsLabel.setFont(new LegendFont());\n            unitsLabel.setForeground(foreground);\n            unitsLabel.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 2;\n            constraints.gridy = i;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.insets = new Insets(0, 3, 0, 0);\n            add(unitsLabel, constraints);\n\n            constraints = new GridBagConstraints();\n            constraints.gridx = 3;\n            constraints.gridy = i;\n            constraints.weightx = 1;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            add(Spacer.create(), constraints);\n        }\n    }\n\n\n    static interface Model {\n\n        public int    getRowsCount      ();\n        public String getRowName        (int index);\n        public String getRowValue       (int index, long itemValue);\n        public String getRowUnits       (int index);\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelineUnitsOverlay.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport org.graalvm.visualvm.modules.tracer.impl.swing.ColorIcon;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.LabelRenderer;\nimport org.graalvm.visualvm.modules.tracer.impl.swing.LegendFont;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartOverlay;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineUnitsOverlay extends ChartOverlay {\n\n    private final TimelineChart chart;\n    private final LabelRenderer painter;\n\n    private Model model;\n\n\n    TimelineUnitsOverlay(TimelineChart chart) {\n        this.chart = chart;\n\n        painter = new LabelRenderer();\n        painter.setFont(new LegendFont());\n\n        int size = painter.getFont().getSize() - 3;\n        ColorIcon.setup(size, size,\n                LegendFont.FOREGROUND_COLOR, LegendFont.BACKGROUND_COLOR);\n    }\n\n\n    void setupModel(Model model) {\n        this.model = model;\n    }\n\n\n    private boolean hasValues() {\n        return ((SynchronousXYItemsModel)chart.getItemsModel()).getTimeline().\n                getTimestampsCount() > 0;\n    }\n\n    private void setupPainter(String text, Color color) {\n        painter.setText(text);\n        painter.setIcon(color == null ? null : ColorIcon.fromColor(color));\n    }\n\n\n    public void paint(Graphics g) {\n        if (model == null || !hasValues()) return;\n\n        int w = getWidth();\n        model.prefetch();\n        int rowsCount = chart.getRowsCount();\n\n        for (int rowIndex = 0; rowIndex < rowsCount; rowIndex++) {\n            TimelineChart.Row row = chart.getRow(rowIndex);\n            ChartContext rowContext = row.getContext();\n\n            int y = Utils.checkedInt(rowContext.getViewportOffsetY());\n            int h = rowContext.getViewportHeight();\n\n            Color[] colors = model.getColors(row);\n\n            int xx = w - 2;\n            int yy = y;\n            for (int itemIndex = colors.length - 1; itemIndex >= 0; itemIndex--) {\n                setupPainter(model.getMaxUnits(row)[itemIndex], colors[itemIndex]);\n                xx -= painter.getPreferredSize().width;\n                paint(g, xx, yy);\n                xx -= 10;\n            }\n\n            xx = w - 2;\n            yy = -1;\n            for (int itemIndex = colors.length - 1; itemIndex >= 0; itemIndex--) {\n                setupPainter(model.getMinUnits(row)[itemIndex], colors[itemIndex]);\n                Dimension pd = painter.getPreferredSize();\n                xx -= pd.width;\n                if (yy == -1) yy = y + h - pd.height - 1;\n                paint(g, xx, yy);\n                xx -= 10;\n            }\n        }\n    }\n\n    private void paint(Graphics g, int x, int y) {\n        painter.setLocation(x, y + 1);\n        painter.setForeground(LegendFont.BACKGROUND_COLOR);\n        painter.paint(g);\n\n        painter.setLocation(x, y);\n        painter.setForeground(LegendFont.FOREGROUND_COLOR);\n        if (painter.getIcon() != null)\n            painter.setIcon(ColorIcon.BOTTOM_SHADOW);\n        painter.paint(g);\n    }\n\n\n    // --- Peformance tweaks ---------------------------------------------------\n\n    public void invalidate() {}\n\n    public void update(Graphics g) {}\n\n\n    // --- Model definition ----------------------------------------------------\n\n    static interface Model {\n\n        public void prefetch();\n        public Color[]  getColors(TimelineChart.Row row);\n        public String[] getMinUnits(TimelineChart.Row row);\n        public String[] getMaxUnits(TimelineChart.Row row);\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelineXYItem.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemChange;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class TimelineXYItem extends SynchronousXYItem {\n\n    private int lastIndex;\n    private int lastValuesCount;\n    \n    private final LongRect bounds;\n    private long initialMinY;\n    private long initialMaxY;\n\n    private long minY;\n    private long maxY;\n\n    private int itemIndex;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    TimelineXYItem(String name, int itemIndex) {\n        this(name, Long.MAX_VALUE, itemIndex);\n    }\n\n    TimelineXYItem(String name, long initialMinY, int itemIndex) {\n        this(name, initialMinY, Long.MIN_VALUE, itemIndex);\n    }\n\n    TimelineXYItem(String name, long initialMinY, long initialMaxY, int itemIndex) {\n        super(name, initialMinY, initialMaxY);\n        this.initialMinY = initialMinY;\n        this.initialMaxY = initialMaxY;\n        minY = Long.MAX_VALUE;\n        maxY = Long.MIN_VALUE;\n        bounds = new LongRect();\n        lastIndex = -1;\n        setIndex(itemIndex);\n    }\n\n\n    // --- Internal interface --------------------------------------------------\n\n    final void setIndex(int itemIndex) { this.itemIndex = itemIndex; }\n\n    final int getIndex() { return itemIndex; }\n\n\n    // --- Item telemetry ------------------------------------------------------\n\n    public XYItemChange valuesChanged() {\n\n        int valuesCount = getValuesCount();\n        int index = valuesCount - 1;\n        XYItemChange change = null;\n\n        if (index > -1) { // New item(s)\n\n            // Save oldBounds, setup dirtyBounds\n            LongRect oldBounds = new LongRect(bounds);\n            LongRect dirtyBounds = new LongRect();\n\n            boolean initBounds = lastIndex == -1;\n            int dirtyIndex = lastIndex == -1 ? 0 : lastIndex;\n\n            // Process other values\n            for (int i = dirtyIndex; i <= index; i++) {\n\n                long timestamp = getXValue(i);\n                long value = getYValue(i);\n\n                // Update item minY/maxY\n                minY = Math.min(value, minY);\n                maxY = Math.max(value, maxY);\n\n                // Process item bounds\n                if (initBounds) {\n                    // Initialize item bounds\n                    bounds.x = timestamp;\n                    bounds.y = Math.min(value, initialMinY);\n                    bounds.width = 0;\n                    bounds.height = Math.max(value, initialMaxY) - bounds.y;\n                    initBounds = false;\n                } else {\n                    // Update item bounds\n                    LongRect.add(bounds, timestamp, value);\n                    if (valuesCount == lastValuesCount) {\n                        bounds.x = getXValue(0);\n                        bounds.width = getXValue(valuesCount - 1) - bounds.x;\n                    }\n                }\n\n                // Process dirty bounds\n                if (i == dirtyIndex) {\n                    // Setup dirty bounds\n                    dirtyBounds.x = timestamp;\n                    dirtyBounds.y = value;\n                    dirtyBounds.width = getXValue(index) - dirtyBounds.x;\n                } else {\n                    // Update dirty y/height\n                    long dirtyY = dirtyBounds.y;\n                    dirtyBounds.y = Math.min(dirtyY, value);\n                    dirtyBounds.height = Math.max(dirtyY, value) - dirtyBounds.y;\n                }\n\n            }\n\n            // Return ItemChange\n            int indexesCount = index - lastIndex;\n            int[] indexes = new int[indexesCount];\n            for (int i = 0; i < indexesCount; i++) indexes[i] = lastIndex + 1 + i;\n            change = new XYItemChange.Default(this, indexes, oldBounds,\n                                              new LongRect(bounds), dirtyBounds);\n\n        } else { // Reset\n\n            minY = Long.MAX_VALUE;\n            maxY = Long.MIN_VALUE;\n\n            // Save oldBounds\n            LongRect oldBounds = new LongRect(bounds);\n            LongRect.set(bounds, 0, 0, 0, 0);\n\n            // Return ItemChange\n            change = new XYItemChange.Default(this, new int[] { -1 }, oldBounds,\n                                            new LongRect(bounds), oldBounds);\n\n        }\n        \n        lastIndex = index;\n        lastValuesCount = valuesCount;\n        return change;\n        \n    }\n\n    public long getMinYValue() { return minY; }\n\n    public long getMaxYValue() { return maxY; }\n    \n    public LongRect getBounds() {\n        if (getValuesCount() > 0) return bounds;\n        else return getInitialBounds();\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/TimelineXYPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport java.awt.Color;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartItemChange;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemChange;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class TimelineXYPainter extends XYItemPainter.Abstract {\n\n    private final int viewExtent;\n    private final boolean bottomBased;\n\n    private boolean painting;\n\n    protected final double dataFactor;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    TimelineXYPainter(int viewExtent, boolean bottomBased, double dataFactor) {\n        this.viewExtent = viewExtent;\n        this.bottomBased = bottomBased;\n        this.dataFactor = dataFactor;\n        painting = true;\n    }\n\n\n    // --- Abstract interface --------------------------------------------------\n\n    protected abstract void paint(XYItem item, List<ItemSelection> highlighted,\n                                  List<ItemSelection> selected, Graphics2D g,\n                                  Rectangle dirtyArea, SynchronousXYChartContext\n                                  context);\n\n    protected abstract Color getDefiningColor();\n\n\n    // --- Public interface ----------------------------------------------------\n\n    void setPainting(boolean painting) {\n        this.painting = painting;\n    }\n\n    boolean isPainting() {\n        return painting;\n    }\n\n\n    // --- Protected interface -------------------------------------------------\n\n    protected final int getViewExtent() {\n        return viewExtent;\n    }\n    \n\n    // --- ItemPainter implementation ------------------------------------------\n\n    public LongRect getItemBounds(ChartItem item) {\n        XYItem xyItem = (XYItem)item;\n        return getDataBounds(xyItem.getBounds());\n    }\n\n    public LongRect getItemBounds(ChartItem item, ChartContext context) {\n        XYItem xyItem = (XYItem)item;\n        return getViewBounds(xyItem.getBounds(), context);\n    }\n\n\n    public boolean isBoundsChange(ChartItemChange itemChange) {\n        XYItemChange change = (XYItemChange)itemChange;\n        return !LongRect.equals(change.getOldValuesBounds(),\n                                change.getNewValuesBounds());\n    }\n\n    public boolean isAppearanceChange(ChartItemChange itemChange) {\n        XYItemChange change = (XYItemChange)itemChange;\n        LongRect dirtyBounds = change.getDirtyValuesBounds();\n        return dirtyBounds.width != 0 || dirtyBounds.height != 0;\n    }\n\n    public LongRect getDirtyBounds(ChartItemChange itemChange, ChartContext context) {\n        XYItemChange change = (XYItemChange)itemChange;\n        return getViewBounds(change.getDirtyValuesBounds(), context);\n    }\n\n\n    public boolean supportsHovering(ChartItem item) {\n        return true;\n    }\n\n    public boolean supportsSelecting(ChartItem item) {\n        return true;\n    }\n\n    public LongRect getSelectionBounds(ItemSelection selection, ChartContext context) {\n\n        XYItemSelection sel = (XYItemSelection)selection;\n        XYItem item  = sel.getItem();\n        int selectedValueIndex = sel.getValueIndex();\n\n        if (selectedValueIndex == -1 ||\n            selectedValueIndex >= item.getValuesCount())\n            // This happens on reset - bounds of the selection are unknown, let's clear whole area\n            return new LongRect(0, 0, context.getViewportWidth(),\n                                context.getViewportHeight());\n        else\n            return getViewBounds(item, selectedValueIndex, context);\n//            return getViewBounds(item, new int[] { selectedValueIndex }, context);\n    }\n\n    public XYItemSelection getClosestSelection(ChartItem item, int viewX,\n                                               int viewY, ChartContext context) {\n\n        SynchronousXYChartContext contx = (SynchronousXYChartContext)context;\n\n        int nearestTimestampIndex = contx.getNearestTimestampIndex(viewX, viewY);\n        if (nearestTimestampIndex == -1) return null; // item not visible\n\n        SynchronousXYItem xyItem = (SynchronousXYItem)item;\n        return new XYItemSelection.Default(xyItem, nearestTimestampIndex,\n                                           ItemSelection.DISTANCE_UNKNOWN);\n    }\n\n    public final void paintItem(ChartItem item, List<ItemSelection> highlighted,\n                          List<ItemSelection> selected, Graphics2D g,\n                          Rectangle dirtyArea, ChartContext context) {\n\n        if (!painting) return;\n        \n        XYItem it = (XYItem)item;\n        if (it.getValuesCount() < 1) return;\n        if (context.getViewWidth() == 0 || context.getViewHeight() == 0) return;\n\n        SynchronousXYChartContext ctx = (SynchronousXYChartContext)context;\n        paint((XYItem)item, highlighted, selected, g, dirtyArea, ctx);\n    }\n\n\n    // --- XYItemPainter implementation ----------------------------------------\n\n    public double getItemView(double dataY, XYItem item, ChartContext context) {\n        return context.getViewY(dataY * dataFactor);\n    }\n\n    public double getItemValue(double viewY, XYItem item, ChartContext context) {\n        return context.getDataY(viewY / dataFactor);\n    }\n\n    public double getItemValueScale(XYItem item, ChartContext context) {\n        double scale = context.getViewHeight(dataFactor);\n        if (scale <= 0) scale = -1;\n        return scale;\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private LongRect getDataBounds(LongRect itemBounds) {\n        LongRect bounds = new LongRect(itemBounds);\n        bounds.y *= dataFactor;\n        bounds.height *= dataFactor;\n\n        if (bottomBased) {\n            bounds.height += bounds.y;\n            bounds.y = 0;\n        }\n\n        return bounds;\n    }\n\n    private LongRect getViewBounds(LongRect itemBounds, ChartContext context) {\n        LongRect dataBounds = getDataBounds(itemBounds);\n\n        LongRect viewBounds = context.getViewRect(dataBounds);\n        LongRect.addBorder(viewBounds, viewExtent);\n\n        return viewBounds;\n    }\n\n    private LongRect getViewBounds(XYItem item, int valueIndex, ChartContext context) {\n        long xValue = item.getXValue(valueIndex);\n        long yValue = (long)(item.getYValue(valueIndex) * dataFactor);\n        return context.getViewRect(new LongRect(xValue, yValue, 0, 0));\n    }\n\n//    private LongRect getViewBounds(XYItem item, int[] valuesIndexes, ChartContext context) {\n//\n//        LongRect dataBounds = new LongRect();\n//\n//        if (valuesIndexes == null) {\n//            LongRect.set(dataBounds, item.getBounds());\n//            dataBounds.y *= dataFactor;\n//            dataBounds.height *= dataFactor;\n//        } else {\n//            boolean firstPoint = true;\n//            for (int valueIndex : valuesIndexes) {\n//                if (valueIndex == -1) continue;\n//                long xValue = item.getXValue(valueIndex);\n//                long yValue = (long)(item.getYValue(valueIndex) * dataFactor);\n//                if (firstPoint) {\n//                    LongRect.set(dataBounds, xValue, yValue, 0, 0);\n//                    firstPoint = false;\n//                } else {\n//                    LongRect.add(dataBounds, xValue, yValue);\n//                }\n//            }\n//        }\n//\n//        LongRect viewBounds = context.getViewRect(dataBounds);\n//        LongRect.addBorder(viewBounds, viewExtent);\n//        return viewBounds;\n//    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/VerticalTimelineLayout.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline;\n\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.LayoutManager2;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class VerticalTimelineLayout implements LayoutManager2 {\n\n    private final TimelineChart chart;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    VerticalTimelineLayout(TimelineChart chart) {\n        this.chart = chart;\n    }\n\n\n    // --- Public API ----------------------------------------------------------\n\n    public Dimension minimumLayoutSize(Container parent) {\n        return preferredLayoutSize(parent);\n    }\n\n    public Dimension maximumLayoutSize(Container parent) {\n        return preferredLayoutSize(parent);\n    }\n\n    public Dimension preferredLayoutSize(Container parent) {\n//        synchronized (parent.getTreeLock()) {\n            Dimension dim = new Dimension(0, Utils.checkedInt(chart.getChartContext().getViewHeight()));\n\n            for (int i = 0; i < parent.getComponentCount(); i++)\n                dim.width = Math.max(dim.width, parent.getComponent(i).\n                                     getPreferredSize().width);\n\n            return dim;\n//        }\n    }\n\n    public void layoutContainer(Container parent) {\n//        synchronized (parent.getTreeLock()) {\n            int width = parent.getWidth();\n            int rowsCount = Math.min(chart.getRowsCount(), parent.getComponentCount());\n            for (int i = 0; i < rowsCount; i++) {\n                ChartContext context = chart.getRow(i).getContext();\n                parent.getComponent(i).setBounds(0, Utils.checkedInt(context.getViewportOffsetY() + chart.getOffsetY()),\n                                                 width, context.getViewportHeight());\n//            }\n        }\n    }\n\n\n    // --- Implicit implementation ---------------------------------------------\n\n    public void addLayoutComponent(Component comp, Object constraints) {}\n\n    public void addLayoutComponent(String name, Component comp) {}\n\n    public void removeLayoutComponent(Component comp) {}\n\n    public float getLayoutAlignmentX(Container target) { return 0.5f; }\n\n    public float getLayoutAlignmentY(Container target) { return 0.5f; }\n\n    public void invalidateLayout(Container target) {}\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/items/ContinuousXYItemDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline.items;\n\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport java.awt.Color;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ContinuousXYItemDescriptor extends XYItemDescriptor {\n\n    public ContinuousXYItemDescriptor(String name, String description,\n                                      ItemValueFormatter formatter, double dataFactor,\n                                      long minValue, long maxValue, float lineWidth,\n                                      Color lineColor, Color fillColor) {\n\n        super(name, description, formatter, dataFactor, minValue, maxValue,\n              lineWidth, lineColor, fillColor);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/items/DiscreteXYItemDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline.items;\n\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport java.awt.Color;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class DiscreteXYItemDescriptor extends XYItemDescriptor {\n\n    private final int width;\n    private final boolean fixedWidth;\n    private final boolean topLineOnly;\n    private final boolean outlineOnly;\n\n\n    public DiscreteXYItemDescriptor(String name, String description,\n                                    ItemValueFormatter formatter, double dataFactor,\n                                    long minValue, long maxValue, float lineWidth,\n                                    Color lineColor, Color fillColor, int width,\n                                    boolean fixedWidth, boolean topLineOnly,\n                                    boolean outlineOnly) {\n\n        super(name, description, formatter, dataFactor, minValue, maxValue,\n              lineWidth, lineColor, fillColor);\n\n        this.width = width;\n        this.fixedWidth = fixedWidth;\n        this.topLineOnly = topLineOnly;\n        this.outlineOnly = outlineOnly;\n    }\n\n\n    public int getWidth() {\n        return width;\n    }\n\n    public boolean isFixedWidth() {\n        return fixedWidth;\n    }\n\n    public boolean isTopLineOnly() {\n        return topLineOnly;\n    }\n\n    public boolean isOutlineOnly() {\n        return outlineOnly;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/items/ValueItemDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline.items;\n\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\n\n/**\n * \n * @author Jiri Sedlacek\n */\npublic abstract class ValueItemDescriptor extends ProbeItemDescriptor {\n\n    private final ItemValueFormatter formatter;\n    private final double dataFactor;\n    private final long minValue;\n    private final long maxValue;\n\n\n    ValueItemDescriptor(String name, String description,\n                        ItemValueFormatter formatter, double dataFactor,\n                        long minValue, long maxValue) {\n\n        super(name, description);\n        if (formatter == null) {\n            throw new IllegalArgumentException(\"formatter cannot be null\"); // NOI18N\n        }\n        if (dataFactor == 0) {\n            throw new IllegalArgumentException(\"dataFactor cannot be 0\"); // NOI18N\n        }\n        this.formatter = formatter;\n        this.dataFactor = dataFactor;\n        this.minValue = minValue;\n        this.maxValue = maxValue;\n    }\n\n\n    public final String getValueString(long value, int format) {\n        return formatter.formatValue(value, format);\n    }\n\n    public final String getUnitsString(int format) {\n        return formatter.getUnits(format);\n    }\n\n    public final double getDataFactor() {\n        return dataFactor;\n    }\n\n    public final long getMinValue() {\n        return minValue;\n    }\n\n    public final long getMaxValue() {\n        return maxValue;\n    }\n    \n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/impl/timeline/items/XYItemDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.impl.timeline.items;\n\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport java.awt.Color;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class XYItemDescriptor extends ValueItemDescriptor {\n\n    private final float lineWidth;\n    private final Color lineColor;\n    private final Color fillColor;\n\n\n    XYItemDescriptor(String name, String description,\n                     ItemValueFormatter formatter, double dataFactor,\n                     long minValue, long maxValue, float lineWidth,\n                     Color lineColor, Color fillColor) {\n\n        super(name, description, formatter, dataFactor, minValue, maxValue);\n        this.lineWidth = lineWidth;\n        this.lineColor = lineColor;\n        this.fillColor = fillColor;\n    }\n\n    \n    public final float getLineWidth() {\n        return lineWidth;\n    }\n\n    public final Color getLineColor() {\n        return lineColor;\n    }\n\n    public final Color getFillColor() {\n        return fillColor;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracer/src/org/graalvm/visualvm/modules/tracer/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Framework and graphical user interface for visual tracing of applications or\n * other data sources using the Tracer probes.\n * <p>\n * The entrypoint is TracerSupport where custom TracerPackageProviders providing\n * TracerPackages need to be registered. TracerPackages provide TracerProbes\n * representing the monitored targets like JVM metrics or MBean values.\n * <p>\n * <b>Note:</b> the API is not stable yet and may be changed in an incompatible\n * way in the following releases.\n */\npackage org.graalvm.visualvm.modules.tracer;\n"
  },
  {
    "path": "plugins/tracercollect/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.tracer.collections\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.tracer.collections.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracercollect/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: true\nOpenIDE-Module: org.graalvm.visualvm.modules.tracer.collections/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/modules/tracer/collections/resources/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/tracer/collections/Bundle.properties\nOpenIDE-Module-Requires: org.openjdk.btrace.visualvm.tracer.deployer\nOpenIDE-Module-Specification-Version: 2.2\n\n"
  },
  {
    "path": "plugins/tracercollect/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.tracer.collections-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracercollect/nbproject/project.properties",
    "content": "javac.source=1.6\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jiri Sedlacek\nmodule.javadoc.packages=org.graalvm.visualvm.modules.tracer.collections.*\n"
  },
  {
    "path": "plugins/tracercollect/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.tracer.collections</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer.dynamic</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/tracercollect/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/tracercollect/src/org/graalvm/visualvm/modules/tracer/collections/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Tracer\nOpenIDE-Module-Long-Description=\\\n    Tracer probes to monitor the Java Collections framework.\\n\\\n    <BR>\\n<BR>\\n<B>Technologies:</B>\\n<BR>\\nJMX, BTrace\\n<BR>\\n<BR>\\n<B>Requirements:</B>\\n<BR>\\nThis plugin requires the BTrace Deployer plugin to be installed.\nOpenIDE-Module-Name=Tracer-Collections Probes\nOpenIDE-Module-Short-Description=Collections Tracer Probes\n"
  },
  {
    "path": "plugins/tracercollect/src/org/graalvm/visualvm/modules/tracer/collections/resources/CollectionsTracer.btrace",
    "content": "package org.graalvm.visualvm.modules.tracer.collections.resources;\n\nimport org.openjdk.btrace.core.Profiler;\nimport org.openjdk.btrace.core.annotations.*;\nimport static org.openjdk.btrace.core.BTraceUtils.*;\n\n@BTrace(name=\"CollectionsStats\") public class CollectionsTracer {\n    // <fragment name=\"sorting\">\n    @Property(name=\"sortingProfiler\") private static Profiler sortingProfiler = Profiling.newProfiler(2);\n\n    @OnMethod(\n        clazz=\"java.util.Collections\",\n        method=\"sort\"\n    )\n    public static void collectionsSortBefore() {\n        Profiling.recordEntry(sortingProfiler, \"Collections.sort\");\n    }\n\n    @OnMethod(\n        clazz=\"java.util.Collections\",\n        method=\"sort\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void collectionsSortAfter(@Duration long time) {\n        Profiling.recordExit(sortingProfiler, \"Collections.sort\", time);\n    }\n\n    @OnMethod(\n        clazz=\"java.util.Arrays\",\n        method=\"sort\"\n    )\n    public static void arraysSortBefore() {\n        Profiling.recordEntry(sortingProfiler, \"Arrays.sort\");\n    }\n\n    @OnMethod(\n        clazz=\"java.util.Arrays\",\n        method=\"sort\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void arraysSortAfter(@Duration long time) {\n        Profiling.recordExit(sortingProfiler, \"Arrays.sort\", time);\n    }\n    // </fragment>\n\n    // <fragment name=\"conversions\">\n    @Property(name=\"conversionsProfiler\") private static Profiler conversionsProfiler = Profiling.newProfiler(4);\n\n    @OnMethod(\n        clazz=\"+java.util.Set\",\n        method=\"toArray\"\n    )\n    public static void setToArrayBefore() {\n        Profiling.recordEntry(conversionsProfiler, \"Set.toArray\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Set\",\n        method=\"toArray\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void setToArrayAfter(@Duration long time) {\n        Profiling.recordExit(conversionsProfiler, \"Set.toArray\", time);\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.List\",\n        method=\"toArray\"\n    )\n    public static void listToArrayBefore() {\n        Profiling.recordEntry(conversionsProfiler, \"List.toArray\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.List\",\n        method=\"toArray\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void listToArrayAfter(@Duration long time) {\n        Profiling.recordExit(conversionsProfiler, \"List.toArray\", time);\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Queue\",\n        method=\"toArray\"\n    )\n    public static void queueToArrayBefore() {\n        Profiling.recordEntry(conversionsProfiler, \"Queue.toArray\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Queue\",\n        method=\"toArray\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void queueToArrayAfter(@Duration long time) {\n        Profiling.recordExit(conversionsProfiler, \"List.Queue\", time);\n    }\n\n    @OnMethod(\n        clazz=\"java.util.Arrays\",\n        method=\"asList\"\n    )\n    public static void arraysAsListBefore() {\n        Profiling.recordEntry(conversionsProfiler, \"Arrays.asList\");\n    }\n\n    @OnMethod(\n        clazz=\"java.util.Arrays\",\n        method=\"asList\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void arraysAsListAfter(@Duration long time) {\n        Profiling.recordExit(conversionsProfiler, \"Arrays.asList\", time);\n    }\n    // </fragment>\n\n    // <fragment name=\"general_search\">\n    @Property(name=\"generalSearchProfiler\") private static Profiler generalSearchProfiler = Profiling.newProfiler(2);\n\n    @OnMethod(\n        clazz=\"java.util.Collections\",\n        method=\"binarySearch\"\n    )\n    public static void collectionsSearchBefore() {\n        Profiling.recordEntry(generalSearchProfiler, \"Collections.binarySearch\");\n    }\n\n    @OnMethod(\n        clazz=\"java.util.Collections\",\n        method=\"binarySearch\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void collectionsSearchAfter(@Duration long time) {\n        Profiling.recordExit(generalSearchProfiler, \"Collections.binarySearch\", time);\n    }\n\n    @OnMethod(\n        clazz=\"java.util.Arrays\",\n        method=\"binarySearch\"\n    )\n    public static void arraysSearchBefore() {\n        Profiling.recordEntry(generalSearchProfiler, \"Arrays.binarySearch\");\n    }\n\n    @OnMethod(\n        clazz=\"java.util.Arrays\",\n        method=\"binarySearch\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void arraysSearchAfter(@Duration long time) {\n        Profiling.recordExit(generalSearchProfiler, \"Arrays.binarySearch\", time);\n    }\n    // </fragment>\n\n    // <fragment name=\"collections_search\">\n    @Property(name=\"collectionsSearchProfiler\") private static Profiler collectionsSearchProfiler = Profiling.newProfiler(7);\n\n    @OnMethod(\n        clazz=\"+java.util.Set\",\n        method=\"contains\"\n    )\n    public static void setContainsBefore() {\n        Profiling.recordEntry(collectionsSearchProfiler, \"Set.contains\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Set\",\n        method=\"contains\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void setContainsAfter(@Duration long time) {\n        Profiling.recordExit(collectionsSearchProfiler, \"Set.contains\", time);\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Set\",\n        method=\"containsAll\"\n    )\n    public static void setContainsAllBefore() {\n        Profiling.recordEntry(collectionsSearchProfiler, \"Set.containsAll\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Set\",\n        method=\"containsAll\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void setContainsAllAfter(@Duration long time) {\n        Profiling.recordExit(collectionsSearchProfiler, \"Set.containsAll\", time);\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.List\",\n        method=\"contains\"\n    )\n    public static void listContainsBefore() {\n        Profiling.recordEntry(collectionsSearchProfiler, \"List.contains\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.List\",\n        method=\"contains\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void listContainsAfter(@Duration long time) {\n        Profiling.recordExit(collectionsSearchProfiler, \"List.contains\", time);\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.List\",\n        method=\"containsAll\"\n    )\n    public static void listContainsAllBefore() {\n        Profiling.recordEntry(collectionsSearchProfiler, \"List.containsAll\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.List\",\n        method=\"containsAll\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void listContainsAllAfter(@Duration long time) {\n        Profiling.recordExit(collectionsSearchProfiler, \"List.containsAll\", time);\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.List\",\n        method=\"indexOf\"\n    )\n    public static void listIndexOfBefore() {\n        Profiling.recordEntry(collectionsSearchProfiler, \"List.indexOf\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.List\",\n        method=\"indexOf\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void listIndexOfAfter(@Duration long time) {\n        Profiling.recordExit(collectionsSearchProfiler, \"List.indexOf\", time);\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.List\",\n        method=\"lastIndexOf\"\n    )\n    public static void listLastIndexOfBefore() {\n        Profiling.recordEntry(collectionsSearchProfiler, \"List.lastIndexOf\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.List\",\n        method=\"lastIndexOf\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void listLastIndexOfAfter(@Duration long time) {\n        Profiling.recordExit(collectionsSearchProfiler, \"List.lastIndexOf\", time);\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Queue\",\n        method=\"contains\"\n    )\n    public static void queueContainsBefore() {\n        Profiling.recordEntry(collectionsSearchProfiler, \"Queue.contains\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Queue\",\n        method=\"contains\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void queueContainsAfter(@Duration long time) {\n        Profiling.recordExit(collectionsSearchProfiler, \"Queue.contains\", time);\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Queue\",\n        method=\"containsAll\"\n    )\n    public static void queueContainsAllBefore() {\n        Profiling.recordEntry(collectionsSearchProfiler, \"Queue.containsAll\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Queue\",\n        method=\"containsAll\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void queueContainsAllAfter(@Duration long time) {\n        Profiling.recordExit(collectionsSearchProfiler, \"Queue.containsAll\", time);\n    }\n    // </fragment>\n\n    // <fragment name=\"map_search\">\n    @Property(name=\"mapSearchProfiler\") private static Profiler mapSearchProfiler = Profiling.newProfiler(3);\n\n    @OnMethod(\n        clazz=\"+java.util.Map\",\n        method=\"get\"\n    )\n    public static void mapGetBefore() {\n        Profiling.recordEntry(mapSearchProfiler, \"Map.get\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Map\",\n        method=\"get\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void mapGetAfter(@Duration long time) {\n        Profiling.recordExit(mapSearchProfiler, \"Map.get\", time);\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Map\",\n        method=\"containsKey\"\n    )\n    public static void mapContainsKeyBefore() {\n        Profiling.recordEntry(mapSearchProfiler, \"Map.containsKey\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Map\",\n        method=\"containsKey\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void mapContainsKeyAfter(@Duration long time) {\n        Profiling.recordExit(mapSearchProfiler, \"Map.containsKey\", time);\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Map\",\n        method=\"containsValue\"\n    )\n    public static void mapContainsValueBefore() {\n        Profiling.recordEntry(mapSearchProfiler, \"Map.containsValue\");\n    }\n\n    @OnMethod(\n        clazz=\"+java.util.Map\",\n        method=\"containsValue\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void mapContainsValueAfter(@Duration long time) {\n        Profiling.recordExit(mapSearchProfiler, \"Map.containsValue\", time);\n    }\n    // </fragment>\n\n    // <fragment name=\"map_resize\">\n    @Property(name=\"mapResizeProfiler\") private static Profiler mapResizeProfiler = Profiling.newProfiler(3);\n    @OnMethod(\n        clazz=\"+java.util.Map\",\n        method=\"resize\"\n    )\n    public static void mapResizeBefore(@ProbeClassName String pcn, int newSize) {\n        Profiling.recordEntry(mapResizeProfiler, pcn);\n    }\n    @OnMethod(\n        clazz=\"+java.util.Map\",\n        method=\"resize\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void mapResizeBefore(int newSize, @ProbeClassName String pcn, @Duration long time) {\n        Profiling.recordExit(mapResizeProfiler, pcn, time);\n    }\n    // </fragment>\n    \n    @OnTimer(1000)\n    public static void updateMBeans() {\n        // <fragment name=\"sorting\">\n        Profiling.snapshotAndReset(sortingProfiler);\n        // </fragment>\n\n        // <fragment name=\"conversions\">\n        Profiling.snapshotAndReset(conversionsProfiler);\n        // </fragment>\n\n        // <fragment name=\"general_search\">\n        Profiling.snapshotAndReset(generalSearchProfiler);\n        // </fragment>\n\n        // <fragment name=\"map_search\">\n        Profiling.snapshotAndReset(mapSearchProfiler);\n        // </fragment>\n\n        // <fragment name=\"collections_search\">\n        Profiling.snapshotAndReset(collectionsSearchProfiler);\n        // </fragment>\n        \n        // <fragment name=\"map_resize\">\n        Profiling.snapshotAndReset(mapResizeProfiler);\n        // </fragment>\n    }\n}\n"
  },
  {
    "path": "plugins/tracercollect/src/org/graalvm/visualvm/modules/tracer/collections/resources/collections_traces.js",
    "content": "/*\n *  Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\nvar scriptPath = \"nbres:/org/graalvm/visualvm/modules/tracer/collections/resources/CollectionsTracer.btrace\"\nvar btraceDeployerClass;\ntry {\n  btraceDeployerClass = Java.type(\"org.openjdk.btrace.visualvm.tracer.deployer.BTraceDeployer\");\n} catch (e) {\n  btraceDeployerClass = null;\n}\nvar btraceDeployer = btraceDeployerClass ? btraceDeployerClass.instance() : undefined;\n\n\nfunction SelfTimePercentAcc(mbean, blockName) {\n    var valAcc = mbean.get(\"data\").get(blockName).get(\"selfTime.percent\");\n    this.value = function (ts) {\n        var val = valAcc.getValue(ts);\n        return  val * 10;\n    }\n}\n\nfunction selfTimePercent(mbean, blockName) {\n    return new SelfTimePercentAcc(mbean, blockName).value;\n}\n\nfunction invocations(mbean, blockName) {\n    return mbean.get(\"data\").get(blockName).get(\"invocations\");\n}\n\nVisualVM.Tracer.addPackages([{\n        name: \"Java Collections\",\n        desc: \"Java Collections framework statistics\",\n        position: 522,\n        probes: [\n            {\n                name: \"Sorting Count\",\n                desc: \"Invocations count of Collections.sort(), Arrays.sort().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"sorting\"\n                },\n                properties: [\n                    {\n                        name: \"Collections.sort\",\n                        desc: \"Invocations count of Collections.sort().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"sortingProfiler\"), \"Collections.sort\")\n\n                    },\n                    {\n                        name: \"Arrays.sort\",\n                        desc: \"Invocations count of Arrays.sort().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"sortingProfiler\"), \"Arrays.sort\")\n                    }\n                ]\n            },\n            {\n                name: \"Sorting Time\",\n                desc: \"Relative time spent in Collections.sort(), Arrays.sort().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"sorting\"\n                },\n                properties: [\n                    {\n                        name: \"Collections.sort\",\n                        desc: \"Relative time spent in Collections.sort().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"sortingProfiler\"), \"Collections.sort\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"Arrays.sort\",\n                        desc: \"Relative time spent in Arrays.sort().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"sortingProfiler\"), \"Arrays.sort\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    }\n                ]\n            },\n            {\n                name: \"Conversions Count\",\n                desc: \"Invocations count of Set.toArray(), List.toArray(), Queue.toArray(), Arrays.asList().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"conversions\"\n                },\n                properties: [\n                    {\n                        name: \"Set.toArray\",\n                        desc: \"Invocations count of Set.toArray.\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"conversionsProfiler\"), \"Set.toArray\")\n\n                    },\n                    {\n                        name: \"List.toArray\",\n                        desc: \"Invocations count of List.toArray().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"conversionsProfiler\"), \"List.toArray\")\n                    },\n                    {\n                        name: \"Queue.toArray\",\n                        desc: \"Invocations count of Queue.toArray().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"conversionsProfiler\"), \"Queue.toArray\")\n                    },\n                    {\n                        name: \"Arrays.asList\",\n                        desc: \"Invocations count of Arrays.asList().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"conversionsProfiler\"), \"Arrays.asList\")\n                    }\n                ]\n            },\n            {\n                name: \"Conversions Time\",\n                desc: \"Relative time spent in Set.toArray(), List.toArray(), Queue.toArray(), Arrays.asList().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"conversions\"\n                },\n                properties: [\n                    {\n                        name: \"Set.toArray\",\n                        desc: \"Relative time spent in Set.toArray.\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"conversionsProfiler\"), \"Set.toArray\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"List.toArray\",\n                        desc: \"Relative time spent in List.toArray().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"conversionsProfiler\"), \"List.toArray\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"Queue.toArray\",\n                        desc: \"Relative time spent in Queue.toArray().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"conversionsProfiler\"), \"Queue.toArray\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"Arrays.asList\",\n                        desc: \"Relative time spent in Arrays.asList().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"conversionsProfiler\"), \"Arrays.asList\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    }\n                ]\n            },\n            {\n                name: \"General Search Count\",\n                desc: \"Invocations count of Collections.binarySearch(), Arrays.binarySearch().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"general_search\"\n                },\n                properties: [\n                    {\n                        name: \"Collections.binarySearch\",\n                        desc: \"Invocations count of Collections.binarySearch().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"generalSearchProfiler\"), \"Collections.binarySearch\")\n\n                    },\n                    {\n                        name: \"Arrays.binarySearch\",\n                        desc: \"Invocations count of Arrays.binarySearch().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"generalSearchProfiler\"), \"Arrays.binarySearch\")\n                    }\n                ]\n            },\n            {\n                name: \"General Search Time\",\n                desc: \"Relative time spent in Collections.binarySearch(), Arrays.binarySearch().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"general_search\"\n                },\n                properties: [\n                    {\n                        name: \"Collections.binarySearch\",\n                        desc: \"Relative time spent in Collections.binarySearch().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"generalSearchProfiler\"), \"Collections.binarySearch\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"Arrays.binarySearch\",\n                        desc: \"Relative time spent in Arrays.binarySearch().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"generalSearchProfiler\"), \"Arrays.binarySearch\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    }\n                ]\n            },\n            {\n                name: \"Collections Search Count\",\n                desc: \"Invocations count of Set.contains(), Set.containsAll(), List.contains(), List.containsAll(), List.indexOf(), List.lastIndexOf(), Queue.contains(), Queue.containsAll().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"collections_search\"\n                },\n                properties: [\n                    {\n                        name: \"Set.contains\",\n                        desc: \"Invocations count of Set.contains().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"Set.contains\")\n\n                    },\n                    {\n                        name: \"Set.containsAll\",\n                        desc: \"Invocations count of Set.containsAll().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"Set.containsAll\")\n\n                    },\n                    {\n                        name: \"List.contains\",\n                        desc: \"Invocations count of List.contains().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"List.contains\")\n                    },\n                    {\n                        name: \"List.containsAll\",\n                        desc: \"Invocations count of List.containsAll().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"List.containsAll\")\n\n                    },\n                    {\n                        name: \"List.indexOf\",\n                        desc: \"Invocations count of List.indexOf().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"List.indexOf\")\n\n                    },\n                    {\n                        name: \"List.lastIndexOf\",\n                        desc: \"Invocations count of List.lastIndexOf().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"List.lastIndexOf\")\n\n                    },\n                    {\n                        name: \"Queue.contains\",\n                        desc: \"Invocations count of Queue.contains().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"Queue.contains\")\n                    },\n                    {\n                        name: \"Queue.containsAll\",\n                        desc: \"Invocations count of Queue.containsAll().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"Queue.containsAll\")\n                    }\n                ]\n            },\n            {\n                name: \"Collections Search Time\",\n                desc: \"Relative time spent in Set.contains(), Set.containsAll(), List.contains(), List.containsAll(), List.indexOf(), List.lastIndexOf(), Queue.contains(), Queue.containsAll().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"collections_search\"\n                },\n                properties: [\n                    {\n                        name: \"Set.contains\",\n                        desc: \"Relative time spent in Set.contains().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"Set.contains\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"Set.containsAll\",\n                        desc: \"Relative time spent in Set.containsAll().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"Set.containsAll\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"List.contains\",\n                        desc: \"Relative time spent in List.contains().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"List.contains\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"List.containsAll\",\n                        desc: \"Relative time spent in List.containsAll().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"List.containsAll\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"List.indexOf\",\n                        desc: \"Relative time spent in List.indexOf().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"List.indexOf\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"List.lastIndexOf\",\n                        desc: \"Relative time spent in List.lastIndexOf().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"List.lastIndexOf\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"Queue.contains\",\n                        desc: \"Relative time spent in Queue.contains().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"Queue.contains\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"Queue.containsAll\",\n                        desc: \"Relative time spent in Queue.containsAll().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"collectionsSearchProfiler\"), \"Queue.containsAll\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    }\n                ]\n            },\n            {\n                name: \"Map Search Count\",\n                desc: \"Invocations count of Map.get(), Map.containsKey(), Map.containsValue().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"map_search\"\n                },\n                properties: [\n                    {\n                        name: \"Map.get\",\n                        desc: \"Invocations count of Map.get().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"mapSearchProfiler\"), \"Map.get\")\n\n                    },\n                    {\n                        name: \"Map.containsKey\",\n                        desc: \"Invocations count of Map.containsKey().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"mapSearchProfiler\"), \"Map.containsKey\")\n\n                    },\n                    {\n                        name: \"Map.containsValue\",\n                        desc: \"Invocations count of Map.containsValue().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"mapSearchProfiler\"), \"Map.containsValue\")\n                    }\n                ]\n            },\n            {\n                name: \"Map Search Time\",\n                desc: \"Relative time spent in Map.get(), Map.containsKey(), Map.containsValue().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"map_search\"\n                },\n                properties: [\n                    {\n                        name: \"Map.get\",\n                        desc: \"Relative time spent in Map.get().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"mapSearchProfiler\"), \"Map.get\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"Map.containsKey\",\n                        desc: \"Relative time spent in Map.containsKey().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"mapSearchProfiler\"), \"Map.containsKey\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"Map.containsValue\",\n                        desc: \"Relative time spent in Map.containsValue().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"mapSearchProfiler\"), \"Map.containsValue\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    }\n                ]\n            },\n            {\n                name: \"Map Resize Count\",\n                desc: \"Invocations count of resize() method in Map implementations.\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"map_resize\"\n                },\n                properties: [\n                    {\n                        name: \"HashMap\",\n                        desc: \"Invocations count of resize().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"mapResizeProfiler\"), \"java.util.HashMap\")\n\n                    },\n                    {\n                        name: \"WeakHashMap\",\n                        desc: \"Invocations count of resize().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"mapResizeProfiler\"), \"java.util.WeakHashMap\")\n\n                    },\n                    {\n                        name: \"IdentityHashMap\",\n                        desc: \"Invocations count of resize().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=CollectionsStats\", \"mapResizeProfiler\"), \"java.util.IdentityHashMap\")\n\n                    }\n                ]\n            },\n            {\n                name: \"Map Resize Time\",\n                desc: \"Relative time spent in resize() method in Map implementations.\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"map_resize\"\n                },\n                properties: [\n                    {\n                        name: \"HashMap\",\n                        desc: \"Relative time spent in resize().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"mapResizeProfiler\"), \"java.util.HashMap\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"WeakHashMap\",\n                        desc: \"Relative time spent in resize().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"mapResizeProfiler\"), \"java.util.WeakHashMap\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"IdentityHashMap\",\n                        desc: \"Relative time spent in resize().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=CollectionsStats\", \"mapResizeProfiler\"), \"java.util.IdentityHashMap\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    }\n                ]\n            }\n        ]\n    }\n])\n"
  },
  {
    "path": "plugins/tracercollect/src/org/graalvm/visualvm/modules/tracer/collections/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.2//EN\" \"http://www.netbeans.org/dtds/filesystem-1_2.dtd\">\n<filesystem>\n    <folder name=\"VisualVM\">\n        <folder name=\"Tracer\">\n            <folder name=\"packages\">\n                <file name=\"collections_traces.js\" url=\"collections_traces.js\">\n                    <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.modules.tracer.platformjmx.Bundle#VisualVM/Tracer/packages/platform_mx.js\"/>\n                </file>\n            </folder>\n        </folder>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "plugins/tracerdtrace/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.tracer.dtrace\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.tracer.dtrace.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerdtrace/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: true\nOpenIDE-Module: org.graalvm.visualvm.modules.tracer.dtrace/2\nOpenIDE-Module-Requires: org.openide.modules.os.Solaris\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/tracer/dtrace/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/tracer/dtrace/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "plugins/tracerdtrace/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.tracer.jvm-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerdtrace/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=bc3cd978\nbuild.xml.script.CRC32=bc22c6c6\nbuild.xml.stylesheet.CRC32=79c3b980@1.31.1.7\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=bc3cd978\nnbproject/build-impl.xml.script.CRC32=e28ed7e0\nnbproject/build-impl.xml.stylesheet.CRC32=261c4bef@1.31.1.7\n"
  },
  {
    "path": "plugins/tracerdtrace/nbproject/project.properties",
    "content": "is.eager=true\njavac.source=1.6\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Tomas Hurka\nmodule.javadoc.packages=org.graalvm.visualvm.modules.tracer.dtrace.*\n"
  },
  {
    "path": "plugins/tracerdtrace/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.tracer.dtrace</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.13.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.opensolaris.os.dtrace</package>\n            </public-packages>\n            <class-path-extension>\n                <runtime-relative-path>ext/dtrace.jar</runtime-relative-path>\n                <binary-origin>release/modules/ext/dtrace.jar</binary-origin>\n            </class-path-extension>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/tracerdtrace/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/tracerdtrace/src/org/graalvm/visualvm/modules/tracer/dtrace/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Tracer\nOpenIDE-Module-Long-Description=\\\n    A plugin to provide low level system metrics using the DTrace technology.\\n\\\n    <BR>\\n<BR>\\n<B>Technologies:</B>\\n<BR>\\nDTrace\\n<BR>\\n<BR>\\n<B>Requirements:</B>\\n<BR>\\nThis plugin currently supports only the Solaris and OpenSolaris OS.\nOpenIDE-Module-Name=Tracer-DTrace Probes\nOpenIDE-Module-Short-Description=Tracer DTrace Probes\n"
  },
  {
    "path": "plugins/tracerdtrace/src/org/graalvm/visualvm/modules/tracer/dtrace/BytesIOProbe.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dtrace;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport java.util.List;\nimport javax.swing.Icon;\nimport org.openide.util.Exceptions;\nimport org.opensolaris.os.dtrace.Aggregate;\nimport org.opensolaris.os.dtrace.Aggregation;\nimport org.opensolaris.os.dtrace.AggregationRecord;\nimport org.opensolaris.os.dtrace.Consumer;\nimport org.opensolaris.os.dtrace.DTraceException;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass BytesIOProbe extends TracerProbe.SessionAware<Application> {\n\n    private static final String NAME = \"I/O bytes\";\n    private static final String DESCR = \"Monitors I/O bytes per second.\";\n    private static final int POSITION = 20;\n    private static final String AGGREG_VALUE = \"bytes\";\n    private static final int probes = 2;\n    private long lastValues[];\n    private DTracePackage dtrace;\n    private long lastTime;\n\n    BytesIOProbe(DTracePackage dt) {\n        super(createItemDescriptors());\n        dtrace = dt;\n    }\n\n    static final TracerProbeDescriptor createDescriptor(Icon icon, boolean available) {\n        return new TracerProbeDescriptor(NAME, DESCR, icon, POSITION, available);\n    }\n\n    private static final ProbeItemDescriptor[] createItemDescriptors() {\n        ProbeItemDescriptor[] descs = new ProbeItemDescriptor[probes];\n        descs[0] = ProbeItemDescriptor.continuousLineItem(\"I/O reads\",\n                \"Monitors read bytes per second.\",\n                ItemValueFormatter.DEFAULT_BYTES, 1d, 0, 1000);\n        descs[1] = ProbeItemDescriptor.continuousLineItem(\"I/O writes\",\n                \"Monitors written bytes per second.\",\n                ItemValueFormatter.DEFAULT_BYTES, 1d, 0, 1000);\n        return descs;\n    }\n\n    @Override\n    protected TracerProgressObject sessionInitializing(Application dataSource, int refresh) {\n        lastTime = 0;\n        lastValues = null;\n        return super.sessionInitializing(dataSource, refresh);\n    }\n\n    @Override\n    public long[] getItemValues(long timestamp) {\n        long time;\n        long vals[];\n        long diffs[] = new long[probes];\n        try {\n            time = System.currentTimeMillis();\n            vals = getCurrentValues();\n            if (lastValues != null) {\n                long delta = time - lastTime;\n                for (int i = 0; i < vals.length; i++) {\n                    diffs[i] = 1000* (vals[i] - lastValues[i]) / delta;\n                }\n            }\n        } catch (DTraceException ex) {\n            Exceptions.printStackTrace(ex);\n            return diffs;\n        }\n        lastTime = time;\n        lastValues = vals;\n        return diffs;\n    }\n\n    private long[] getCurrentValues() throws DTraceException {\n        long vals[] = new long[probes];\n        Consumer c = dtrace.getConsumer();\n        Aggregate result = c.getAggregate();\n        Aggregation agg = result.getAggregation(AGGREG_VALUE);\n        if (agg != null) {\n            List<AggregationRecord> records = agg.getRecords();\n\n            for (AggregationRecord record : records) {\n                Number index = (Number) record.getTuple().get(0).getValue();\n                Number val = record.getValue().getValue();\n                vals[index.intValue()] = val.longValue();\n            }\n        }\n        return vals;\n    }\n}\n"
  },
  {
    "path": "plugins/tracerdtrace/src/org/graalvm/visualvm/modules/tracer/dtrace/CpusMonitorProbe.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dtrace;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport java.util.List;\nimport javax.swing.Icon;\nimport org.openide.util.Exceptions;\nimport org.opensolaris.os.dtrace.Aggregate;\nimport org.opensolaris.os.dtrace.Aggregation;\nimport org.opensolaris.os.dtrace.AggregationRecord;\nimport org.opensolaris.os.dtrace.Consumer;\nimport org.opensolaris.os.dtrace.DTraceException;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass CpusMonitorProbe extends TracerProbe.SessionAware<Application> {\n\n    private static final String NAME = \"CPUs usage\";\n    private static final String DESCR = \"Monitors CPUs usage.\";\n    private static final int POSITION = 10;\n    private static final String AGGREG_VALUE = \"cpu\";\n    private final int processorsCount;\n    private long lastValues[];\n    private DTracePackage dtrace;\n    private long lastTime;\n\n    CpusMonitorProbe(DTracePackage dt) {\n        super(createItemDescriptors(dt.getProcessors()));\n        processorsCount = getItemsCount();\n        dtrace = dt;\n    }\n\n    static final TracerProbeDescriptor createDescriptor(Icon icon, boolean available) {\n        return new TracerProbeDescriptor(NAME, DESCR, icon, POSITION, available);\n    }\n\n    private static final ProbeItemDescriptor[] createItemDescriptors(int procs) {\n        ProbeItemDescriptor[] descs = new ProbeItemDescriptor[procs];\n\n        for (int i = 0; i < procs; i++) {\n            descs[i] = ProbeItemDescriptor.continuousLineItem(\"CPU\" + i + \" usage\",\n                    \"Monitors relative CPU\" + i + \" usage (%)\",\n                    ItemValueFormatter.DEFAULT_PERCENT, 1d, 0, 1000);\n        }\n        return descs;\n    }\n\n    @Override\n    protected TracerProgressObject sessionInitializing(Application dataSource, int refresh) {\n        lastTime = 0;\n        lastValues = null;\n        return super.sessionInitializing(dataSource, refresh);\n    }\n\n\n    @Override\n    public long[] getItemValues(long timestamp) {\n        long time;\n        long vals[];\n        long diffs[] = new long[processorsCount];\n        try {\n            time = System.currentTimeMillis();\n            vals = getCurrentValues();\n            if (lastValues != null) {\n                long delta = time - lastTime;\n                for (int i = 0; i < vals.length; i++) {\n                    diffs[i] = (vals[i] - lastValues[i]) / (1000 * delta);\n                }\n            }\n        } catch (DTraceException ex) {\n            Exceptions.printStackTrace(ex);\n            return diffs;\n        }\n        lastTime = time;\n        lastValues = vals;\n        return diffs;\n    }\n\n    private long[] getCurrentValues() throws DTraceException {\n        long vals[] = new long[processorsCount];\n        Consumer c = dtrace.getConsumer();\n        Aggregate result = c.getAggregate();\n        Aggregation agg = result.getAggregation(AGGREG_VALUE);\n        if (agg != null) {\n            List<AggregationRecord> records = agg.getRecords();\n\n            for (AggregationRecord record : records) {\n                Number cpu = (Number) record.getTuple().get(0).getValue();\n                Number val = record.getValue().getValue();\n                vals[cpu.intValue()] = val.longValue();\n            }\n        }\n        return vals;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracerdtrace/src/org/graalvm/visualvm/modules/tracer/dtrace/DTracePackage.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dtrace;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.SessionInitializationException;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.lang.management.ManagementFactory;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.openide.util.Exceptions;\nimport org.openide.util.ImageUtilities;\nimport org.opensolaris.os.dtrace.Consumer;\nimport org.opensolaris.os.dtrace.DTraceException;\nimport org.opensolaris.os.dtrace.LocalConsumer;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass DTracePackage extends TracerPackage.SessionAware<Application>{\n\n    static final Icon ICON = new ImageIcon(ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/modules/tracer/dtrace/resources/cpuSmall.png\", true)); // NOI18N\n    private static final String NAME = \"DTrace Probes\";\n    private static final String DESCR = \"Provides low level system metrics using the DTrace technology.\";\n    private static final int POSITION = 120;\n    private static final String DSCRIPT_FILE =\n            \"org/graalvm/visualvm/modules/tracer/dtrace/resources/probes.d\"; // NOI18N\n\n    private Consumer consumer;\n    private Application application;\n    private String probe;\n    private TracerProgressObject progress;\n    private TracerProbeDescriptor cpusDesc;\n    private TracerProbeDescriptor syscallDesc;\n    private TracerProbeDescriptor bytesIODesc;\n    private TracerProbeDescriptor jvmOverhead;\n\n    DTracePackage(Application app) {\n        super(NAME,DESCR,ICON,POSITION);\n        application = app;\n    }\n\n    @Override\n    public TracerProbeDescriptor[] getProbeDescriptors() {\n        cpusDesc = CpusMonitorProbe.createDescriptor(ICON, true);\n        syscallDesc = SyscallsProbe.createDescriptor(ICON, true);\n        bytesIODesc = BytesIOProbe.createDescriptor(ICON, true);\n        jvmOverhead = JVMOverheadProbe.createDescriptor(ICON, true);\n        return new TracerProbeDescriptor[] { cpusDesc, syscallDesc, bytesIODesc, jvmOverhead };\n    }\n\n    @Override\n    public TracerProbe<Application> getProbe(TracerProbeDescriptor descriptor) {\n        if (descriptor == cpusDesc) {\n            return new CpusMonitorProbe(this);\n        }\n        if (descriptor == syscallDesc) {\n            return new SyscallsProbe(this);\n        }\n        if (descriptor == bytesIODesc) {\n            return new BytesIOProbe(this);\n        }\n        if (descriptor == jvmOverhead) {\n            return new JVMOverheadProbe(this);\n        }\n        return null;\n    }\n\n    @Override\n    protected TracerProgressObject sessionInitializing(TracerProbe<Application>[] probes, Application app, int refresh) {\n        return progress = new TracerProgressObject(5);\n    }\n\n\n    @Override\n    protected void sessionStarting(TracerProbe<Application>[] probes, Application app) throws SessionInitializationException {\n        try {\n            consumer = new LocalConsumer();\n//            consumer.addConsumerListener(new ConsumerAdapter() {\n//\n//                @Override\n//                public void dataReceived(DataEvent e) throws ConsumerException {\n//                    System.out.println(e);\n//                }\n//\n//            });\n            progress.addStep(\"Loading script\");\n            probe = readScript(DSCRIPT_FILE);\n            progress.addStep(\"Opening dtrace connection\");\n            consumer.open();\n            progress.addStep(\"Attaching to process\");\n            consumer.grabProcess(app.getPid());\n            progress.addStep(\"Compiling\");\n            consumer.compile(probe, (String[])null);\n            progress.addStep(\"Enabling\");\n            consumer.enable();\n        } catch (IOException ex) {\n            throw new SessionInitializationException(ex.getMessage(), ex);\n        } catch (DTraceException ex) {\n            throw new SessionInitializationException(ex.getMessage(), ex);\n        }\n    }\n\n    @Override\n    protected void sessionRunning(TracerProbe<Application>[] probes, Application app) {\n        try {\n            consumer.go();\n        } catch (DTraceException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n    }\n\n    @Override\n    protected void sessionStopping(TracerProbe<Application>[] probes, Application dataSource) {\n        consumer.stop();\n        consumer.close();\n    }\n\n    int getProcessors() {\n        return ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors();\n    }\n\n    private static String readScript(String scriptFile) throws IOException {\n        BufferedReader br = new BufferedReader(\n                new InputStreamReader(DTracePackage.class.\n                getClassLoader().getResourceAsStream(scriptFile)));\n        String line = null;\n        StringBuilder sb = new StringBuilder();\n        while ((line = br.readLine()) != null)\n            sb.append(line).append(\"\\n\"); // NOI18N\n        return sb.toString();\n    }\n\n    Consumer getConsumer() {\n        return consumer;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracerdtrace/src/org/graalvm/visualvm/modules/tracer/dtrace/DTracePackageProvider.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dtrace;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport org.graalvm.visualvm.modules.tracer.TracerPackageProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass DTracePackageProvider extends TracerPackageProvider<Application>{\n\n    DTracePackageProvider() {\n        super(Application.class);\n    }\n    \n    @Override\n    public TracerPackage<Application>[] getPackages(Application app) {\n        return new TracerPackage[] { new DTracePackage(app) };\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracerdtrace/src/org/graalvm/visualvm/modules/tracer/dtrace/Installer.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dtrace;\n\nimport org.graalvm.visualvm.modules.tracer.TracerSupport;\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n *\n * @author Tomas Hurka\n */\npublic class Installer extends ModuleInstall {\n\n    DTracePackageProvider provider;\n\n    @Override\n    public void restored() {\n        assert provider == null;\n        provider = new DTracePackageProvider();\n        TracerSupport.getInstance().registerPackageProvider(provider);\n    }\n\n    @Override\n    public void uninstalled() {\n        assert provider != null;\n        TracerSupport.getInstance().unregisterPackageProvider(provider);\n        provider = null;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracerdtrace/src/org/graalvm/visualvm/modules/tracer/dtrace/JVMOverheadProbe.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dtrace;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeansFactory;\nimport java.lang.management.ThreadMXBean;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.Icon;\nimport org.openide.util.Exceptions;\nimport org.opensolaris.os.dtrace.Aggregate;\nimport org.opensolaris.os.dtrace.Aggregation;\nimport org.opensolaris.os.dtrace.AggregationRecord;\nimport org.opensolaris.os.dtrace.Consumer;\nimport org.opensolaris.os.dtrace.DTraceException;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JVMOverheadProbe extends TracerProbe.SessionAware<Application> {\n\n    private static final String NAME = \"JVM overhead\";\n    private static final String DESCR = \"Monitors JVM overhead.\";\n    private static final int POSITION = 16;\n    private static final String AGGREG_VALUE = \"threads\";\n    private static final int probes = 1;\n    private final int processorsCount;\n    private long lastValues[];\n    private DTracePackage dtrace;\n    private long lastTime;\n    private ThreadMXBean threads;\n    private Set<Long> threadIds;\n\n    JVMOverheadProbe(DTracePackage dt) {\n        super(createItemDescriptors());\n        processorsCount = getItemsCount();\n        dtrace = dt;\n    }\n\n    static final TracerProbeDescriptor createDescriptor(Icon icon, boolean available) {\n        return new TracerProbeDescriptor(NAME, DESCR, icon, POSITION, available);\n    }\n\n    private static final ProbeItemDescriptor[] createItemDescriptors() {\n        ProbeItemDescriptor[] descs = new ProbeItemDescriptor[probes];\n        descs[0] = ProbeItemDescriptor.continuousLineItem(\"JVM overhead\",\n                \"Monitors relative JVM overhead (%)\",\n                ItemValueFormatter.DEFAULT_PERCENT, 1d, 0, 1000);\n        return descs;\n    }\n\n    @Override\n    protected TracerProgressObject sessionInitializing(Application dataSource, int refresh) {\n        lastTime = 0;\n        lastValues = null;\n        return super.sessionInitializing(dataSource, refresh);\n    }\n\n    @Override\n    protected void sessionRunning(Application dataSource) {\n        JmxModel model = JmxModelFactory.getJmxModelFor(dataSource);\n        JvmMXBeans beans = JvmMXBeansFactory.getJvmMXBeans(model);\n        threads = beans.getThreadMXBean();\n        threadIds = new HashSet();\n        long[] tids = threads.getAllThreadIds();\n        for (long tid : tids) {\n            threadIds.add(Long.valueOf(tid));\n        }\n//        System.out.println(threadIds);\n        super.sessionRunning(dataSource);\n    }\n\n    @Override\n    public long[] getItemValues(long timestamp) {\n        long time;\n        long vals[];\n        long diffs[] = new long[probes];\n        try {\n            time = System.currentTimeMillis();\n            vals = getCurrentValues();\n            if (lastValues != null) {\n                long delta = time - lastTime;\n                for (int i = 0; i < vals.length; i++) {\n                    diffs[i] = (vals[i] - lastValues[i]) / (1000 * delta);\n                }\n            } else {\n                long[] tids = threads.getAllThreadIds();\n                for (long tid : tids) {\n                    threadIds.add(Long.valueOf(tid));\n                }\n//                System.out.println(threadIds);\n            }\n        } catch (DTraceException ex) {\n            Exceptions.printStackTrace(ex);\n            return diffs;\n        }\n        lastTime = time;\n        lastValues = vals;\n        return diffs;\n    }\n\n    private long[] getCurrentValues() throws DTraceException {\n        long vals[] = new long[probes];\n        Consumer c = dtrace.getConsumer();\n        Aggregate result = c.getAggregate();\n        Aggregation agg = result.getAggregation(AGGREG_VALUE);\n        if (agg != null) {\n            List<AggregationRecord> records = agg.getRecords();\n            long time = 0;\n\n            for (AggregationRecord record : records) {\n                Number tid = (Number) record.getTuple().get(0).getValue();\n                Number val = record.getValue().getValue();\n                if (!threadIds.contains(Long.valueOf(tid.longValue()))) {\n                    time += val.longValue();\n//                    System.out.println(\"VM thread id: \" + tid.longValue());\n                }\n            }\n            vals[0] = time / processorsCount;\n        }\n        return vals;\n    }\n}\n"
  },
  {
    "path": "plugins/tracerdtrace/src/org/graalvm/visualvm/modules/tracer/dtrace/SyscallsProbe.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.modules.tracer.dtrace;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport java.util.List;\nimport javax.swing.Icon;\nimport org.openide.util.Exceptions;\nimport org.opensolaris.os.dtrace.Aggregate;\nimport org.opensolaris.os.dtrace.Aggregation;\nimport org.opensolaris.os.dtrace.AggregationRecord;\nimport org.opensolaris.os.dtrace.Consumer;\nimport org.opensolaris.os.dtrace.DTraceException;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass SyscallsProbe extends TracerProbe.SessionAware<Application> {\n\n    private static final String NAME = \"Syscalls\";\n    private static final String DESCR = \"Monitors number of system calls per second.\";\n    private static final int POSITION = 20;\n    private static final String AGGREG_VALUE = \"syscalls\";\n    private static final int probes = 1;\n    private long lastValues[];\n    private DTracePackage dtrace;\n    private long lastTime;\n\n    SyscallsProbe(DTracePackage dt) {\n        super(createItemDescriptors());\n        dtrace = dt;\n    }\n\n    static final TracerProbeDescriptor createDescriptor(Icon icon, boolean available) {\n        return new TracerProbeDescriptor(NAME, DESCR, icon, POSITION, available);\n    }\n\n    private static final ProbeItemDescriptor[] createItemDescriptors() {\n        ProbeItemDescriptor[] descs = new ProbeItemDescriptor[probes];\n        descs[0] = ProbeItemDescriptor.continuousLineItem(\"Syscalls\",\n                \"Monitors number of system calls per second.\",\n                ItemValueFormatter.DEFAULT_DECIMAL, 1d, 0, 1000);\n        return descs;\n    }\n\n    @Override\n    protected TracerProgressObject sessionInitializing(Application dataSource, int refresh) {\n        lastTime = 0;\n        lastValues = null;\n        return super.sessionInitializing(dataSource, refresh);\n    }\n\n    @Override\n    public long[] getItemValues(long timestamp) {\n        long time;\n        long vals[];\n        long diffs[] = new long[probes];\n        try {\n            time = System.currentTimeMillis();\n            vals = getCurrentValues();\n            if (lastValues != null) {\n                long delta = time - lastTime;\n                for (int i = 0; i < vals.length; i++) {\n                    diffs[i] = 1000* (vals[i] - lastValues[i]) / delta;\n                }\n            }\n        } catch (DTraceException ex) {\n            Exceptions.printStackTrace(ex);\n            return diffs;\n        }\n        lastTime = time;\n        lastValues = vals;\n        return diffs;\n    }\n\n    private long[] getCurrentValues() throws DTraceException {\n        long vals[] = new long[probes];\n        Consumer c = dtrace.getConsumer();\n        Aggregate result = c.getAggregate();\n        Aggregation agg = result.getAggregation(AGGREG_VALUE);\n        if (agg != null) {\n            List<AggregationRecord> records = agg.getRecords();\n\n            for (AggregationRecord record : records) {\n                Number index = (Number) record.getTuple().get(0).getValue();\n                Number val = record.getValue().getValue();\n                vals[index.intValue()] = val.longValue();\n            }\n        }\n        return vals;\n    }\n}\n"
  },
  {
    "path": "plugins/tracerdtrace/src/org/graalvm/visualvm/modules/tracer/dtrace/resources/probes.d",
    "content": "/*\n *  Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/*\n * Author Tomas Hurka\n*/\n\n#pragma D option quiet \n\nsched:::on-cpu \n/pid == $target/\n{ \nself->ts = timestamp; \n} \nsched:::off-cpu \n/self->ts/ \n{ \n@cpu[cpu] = sum(timestamp - self->ts); \nself->ts = 0; \n}\n \nsyscall:::entry\n/pid == $target/\n{ @syscalls[0] = count();\n}\n\nsysinfo:::readch,\nsysinfo:::writech\n/pid == $target/\n{ i = probename == \"readch\" ? 0 : 1;\n  @bytes[i] = sum(arg0);\n}\n\nsched:::on-cpu\n/pid == $target/\n{\nself->ts1 = timestamp;\n}\nsched:::off-cpu\n/self->ts1 && !javathread[tid]/\n{\n@threads[tid] = sum(timestamp - self->ts1);\nself->ts1 = 0;\n}\n\nhotspot$target:::thread-start\n{\n javathread[tid] = 1;\n}\n"
  },
  {
    "path": "plugins/tracerdynamic/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.tracer.dynamic\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.tracer.dynamic.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerdynamic/doc/QuickStart.txt",
    "content": "1. Introduction:\n================================================================================\nDynamic tracer modules enables declaratively specify tracer probes, using JSON\nlike syntax. It provides rudimentary support for accessing JMX mbean attributes,\nthus making it really simple to connect a tracer probe mbean backed performance\ndata.\n\n2. Creating new tracer probes:\n================================================================================\nIn order to create a new tracer probe (or, better said, set of probe packages)\none needs to create a new NetBeans module which declares requirement of the\n\"org.graalvm.visualvm.modules.tracer.dynamic\" token and contains the layer\ndefinition (layer.xml).\n\nThe second step is creating a reference to the defining JS file from inside the\nlayer. You need to register the file in folder \"VisualVM/Tracer/packages\".\nAll such registered files will be processed by the dynamic tracer support with\nthe context of VisualVM Tracer.\n\n3. Syntax:\n================================================================================\nThe defining JS file must contain at least one invocation of the\n\"VisualVM.Tracer.addPackages(packages)\" method. The \"packages\" variable passed\nto this method is an array of tracer probe package definitions.\n\n3.1 Probe package definition\n================================================================================\n{\n  name: <package display name>,\n  desc: <package description>,\n  reqs: <string or array of strings which will be appended to the description\n        when the package is disabled (according to validator)>,\n  icon: <icon to be used by the package - either a path or actual instance>,\n  validator: <function() returning true/false indicating package availability>,\n  probes: [<list of probe definitions {3.2} separated by \",\">]\n}\n\n\"desc\", \"icon\" and \"validator\" attributes are optional. \"name\" and \"probes\"\nattributes are mandatory and without them the package will not be processed.\nThe order of attributes is not important.\n\n3.2 Probe definition\n================================================================================\n{\n  name: <probe display name>,\n  desc: <probe description>,\n  reqs: <string or array of strings which will be appended to the description\n        when the probe is disabled (according to validator)>,\n  validator: <function() returning true/false indicating probe availability>,\n  deployment: <deployment definition {3.2.1}>,\n  properties: [list of probe property definitions {3.3} separated by \",\">]\n}\n\n\"desc\", \"validator\" and \"deployment\" attributes are optional. \"name\" and\n\"properties\" attributes are mandatory and without them the probe will not be\nprocessed.\nThe order of attributes is not important.\n\n3.2.1 Deployment definition\n================================================================================\nSometimes it is necessary to deploy a certain technology before being able to\ncollect performance data (eg. BTrace, DTrace etc.). Deployment definition\nconfigures this deployment.\n\n{\n  deployer: <\"org.graalvm.visualvm.modules.tracer.dynamic.spi.DeployerImpl\"\n             implementor>,\n  /*\n  list of the deployer specific attributes which will be converted to name/value\n  map passed to the deployer\n  */\n}\n\n3.3 Probe property definition\n================================================================================\n{\n  name: <property display name>,\n  desc: <property description>,\n  value: <function(timestamp) returning the property value at the timestamp>,\n  presenter: <presenter definition {3.3.1}>\n}\n\n\"desc\" and \"presenter\" attributes are optional. \"presenter\" attribute defaults\nto an auto-colored line graph representation. \"name\" and \"value\" attributes\nare mandatory and the property will not be processed without them.\n\nThe order of attributes is not important.\n\n3.3.1 Property presenter definition\n================================================================================\n{\n  type: <\"discrete\" or \"continuous\">,\n  format: <either an instance of\n           \"org.graalvm.visualvm.modules.tracer.ItemValueFormatter\" or a\n           format definition object {3.3.1.1}>,\n  min: <anticipated property minimum>,\n  max: <anticipated property maximum>,\n  factor: <magnifying factor>,\n  lineColor: <line color, can use \"AUTOCOLOR\" {4.4.2} to indicate autocoloring>,\n  fillColor: <fill color, can use \"AUTOCOLOR\" {4.4.2} to indicate autocoloring>,\n  lineWidth: <line width>,\n  fixedWidth: <true/false; applicable only to \"discrete\" property>,\n  topLine: <true/false; applicable only to \"discrete\" property>,\n  outline: <true/false; applicable only to \"discrete\" property>\n}\n\nAll attributes are optional.\n\n3.3.1.1 Property presenter format definition\n================================================================================\n{\n  formatValue: <function(value, format) - returns a specifically formatted value\n                - the \"format\" parameter can be one of the\n                \"org.graalvm.visualvm.modules.tracer.ItemValueFormatter.FORMAT_*\"\n                constants>,\n  getUnits: <function(format) - returns the units text used for the given format\n             - the \"format\" parameter can be one of the\n             \"org.graalvm.visualvm.modules.tracer.ItemValueFormatter.FORMAT_*\"\n             constants>\n}\n\nAt least one of the attributes must be defined.\n\n4. Helpers\n================================================================================\n4.1 Value retrieving helper functions\n================================================================================\nThese functions can be used to define the \"value\" attribute of a property {3.3}\nThey can both be considered to be a value provider.\n\n4.1.1 mbeanAttribute(objectName, attributeName):\n* retrieves an mbean attribute value if it exists and performs safe conversion\n   to long\n* in order to access nested data structures (composite data, maps, tabular data etc.)\n   one can invoke \"get(key)\" function on the result of invoking \"mbeanAttribute\".\n   The result of this invocation supports \"get(key)\" function, too.\n\n4.1.2 delta(valueProvider)\n* computes the delta between the last two known values provided by the valueProvider\n\n4.2 MBean helper functions\n================================================================================\n4.2.1 VisualVM.MBeans.listMBeanNames(objectNamePattern, queryExp)\n* retrieves an array of object names fitting the \"objectNamePattern\" and \"queryExp\"\n* see \"javax.management.MBeanServerConnection#queryNames\" method for parameter\n  details\n\n4.2.2 VisualVM.MBeans.attribute(objectName, attributeName)\n* the same as \"mbeanAttribute\" {4.1.1}\n\n4.3 L11N and I18N\n================================================================================\n4.3.1 new L11N(bundleBaseName)\n* instantiates a new L11N support from \"bundleBaseName\"/Bundle.properties file\n\n4.3.1 <L11N instance>.message(key)\n* looks up the message by \"key\" in the assigned bundle\n\n4.4 Other helpers\n================================================================================\n4.4.1 Color\n* a shortcut to Packages.java.awt.Color\n\n4.4.2 AUTOCOLOR\n* a particular color value used to indicate request to auto-color a property\n\n4.4.3 NULL_VALUE\n* a value provider always returning 0"
  },
  {
    "path": "plugins/tracerdynamic/doc/Sample.js",
    "content": "/*\n * A sample definition file for dynamic tracer\n */\n\nVisualVM.Tracer.addPackages([\n    {\n        name: \"Package 1\",\n        desc: \"Sample package 1\",\n        icon: \"org/graalvm/visualvm/modules/somemodule/resources/myicon.png\",\n        validator: function() {\n            return true; // always enabled\n        },\n        probes: [\n            {\n                name: \"Probe 1\",\n                desc: \"Sample probe 1\",\n                properties: [\n                    {\n                        name: \"Property 1\",\n                        desc: \"Sample property 1\",\n                        value: mbeanAttribute(\"java.lang:type=Compilation\", \"CompilationTime\"),\n                        presenter: {\n                            type: \"discrete\",\n                            lineColor: AUTOCOLOR,\n                            format: { // custom format\n                                getUnits: function(format) {\n                                    return \"years\";\n                                }\n                            }\n                        }\n                    },\n                    {\n                        name: \"Property 2\",\n                        value: function(timestamp) {\n                            if (this.counter == undefined) {\n                                this.counter = 0;\n                            }\n                            return this.counter++;\n                        }\n                    }\n                ]\n            },\n            {\n                name: \"Probe 2\",\n                validator: function() { // overriding the availability inherited from the package\n                    return false; // never enabled\n                },\n                properties: [\n                    {\n                        name: \"Property 3\",\n                        value: NULL_VALUE, // always return 0\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000 // required by the DEFAULT_PERCENT formatter\n                        }\n                    }\n                ]\n            }\n        ]\n    }\n])\n"
  },
  {
    "path": "plugins/tracerdynamic/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.tracer.dynamic/2\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/tracer/dynamic/impl/DynamicPackageProvider.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/tracer/dynamic/Bundle.properties\nOpenIDE-Module-Provides: org.graalvm.visualvm.modules.tracer.dynamic\nOpenIDE-Module-Specification-Version: 2.1\n\n"
  },
  {
    "path": "plugins/tracerdynamic/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.tracer.dynamic-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerdynamic/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=b39ebfee\nbuild.xml.script.CRC32=3354b38e\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=b39ebfee\nnbproject/build-impl.xml.script.CRC32=4d5dbed9\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "plugins/tracerdynamic/nbproject/project.properties",
    "content": "is.autoload=true\njavac.source=1.6\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jaroslav Bachorik\n"
  },
  {
    "path": "plugins/tracerdynamic/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.tracer.dynamic</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.11</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.13.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.34</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.modules.tracer.dynamic.spi</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/tracerdynamic/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/tracerdynamic/src/org/graalvm/visualvm/modules/tracer/dynamic/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Tracer\nOpenIDE-Module-Name=Tracer-Dynamic\n"
  },
  {
    "path": "plugins/tracerdynamic/src/org/graalvm/visualvm/modules/tracer/dynamic/impl/DynamicPackage.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dynamic.impl;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.modules.tracer.SessionInitializationException;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport org.graalvm.visualvm.modules.tracer.dynamic.spi.DeployerImpl;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.TreeMap;\nimport java.util.logging.Logger;\nimport javax.swing.Icon;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class DynamicPackage extends TracerPackage.SessionAware<Application> {\n\n    private static final Logger LOGGER = Logger.getLogger(DynamicPackage.class.getName());\n\n    private TracerProgressObject progress;\n\n    final private Map<TracerProbeDescriptor, DynamicProbe> probeMap = new TreeMap<TracerProbeDescriptor, DynamicProbe>(Positionable.STRONG_COMPARATOR);\n\n    final private Set<DeployerImpl> deployers = new HashSet<DeployerImpl>();\n\n    public DynamicPackage(String name, String desc, Icon icon, int position) {\n        super(name, desc, icon, position);\n    }\n\n    public void addProbe(DynamicProbe probe) {\n        probeMap.put(probe.getProbeDescriptor(), probe);\n    }\n\n    @Override\n    public TracerProbeDescriptor[] getProbeDescriptors() {\n        return probeMap.keySet().toArray(new TracerProbeDescriptor[probeMap.keySet().size()]);\n    }\n\n    @Override\n    public TracerProbe<Application> getProbe(TracerProbeDescriptor descriptor) {\n        return probeMap.get(descriptor);\n    }\n\n    @Override\n    protected TracerProgressObject sessionInitializing(TracerProbe<Application>[] probes, final Application dataSource, int refresh) {\n        for(TracerProbe probe : probes) {\n            DynamicProbe dp = (DynamicProbe)probe;\n            deployers.addAll(dp.applyDeployerConfigs(dataSource));\n//            DeployerImpl di = dp.getDeployment() != null ? dp.getDeployment().getDeployer() : null;\n//            if (di != null) {\n//                di.applyConfig(dataSource, dp.getDeployment().getConfig());\n//                deployers.add(di);\n//            }\n        }\n\n        progress = new TracerProgressObject(deployers.size() * 50 + probes.length + 5, \"\");\n\n        return progress;\n    }\n\n    @Override\n    protected void sessionStarting(TracerProbe<Application>[] probes, Application application)\n                throws SessionInitializationException {\n        try {\n            for(DeployerImpl di : deployers) {\n                if (!di.deploy(application, progress, 50)) {\n                    throw new SessionInitializationException(\"Error deploying dynamic probe (\" + di.getClass().getName() + \")\"); // NOI18N\n                }\n            }\n        } finally {\n            if (progress != null) progress.finish();\n        }\n    }\n\n    @Override\n    protected void sessionStopping(TracerProbe<Application>[] probes, Application application) {\n        for(DeployerImpl d : deployers) {\n            d.undeploy(application);\n        }\n        deployers.clear();\n    }\n}\n"
  },
  {
    "path": "plugins/tracerdynamic/src/org/graalvm/visualvm/modules/tracer/dynamic/impl/DynamicPackageProvider.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dynamic.impl;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport org.graalvm.visualvm.modules.tracer.TracerPackageProvider;\nimport org.graalvm.visualvm.modules.tracer.TracerSupport;\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.util.Collection;\nimport java.util.Enumeration;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.logging.Logger;\nimport javax.script.Bindings;\nimport javax.script.ScriptEngine;\nimport javax.script.ScriptEngineManager;\nimport javax.script.ScriptException;\nimport javax.swing.ImageIcon;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.modules.ModuleInstall;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\nclass DynamicPackageProvider extends ModuleInstall {\n    final private static Logger LOGGER = Logger.getLogger(DynamicPackageProvider.class.getName());\n\n    final private static ImageIcon defaultIcon = ImageUtilities.loadImageIcon(\"org/graalvm/visualvm/modules/tracer/dynamic/resources/default.png\", true); // NOI18N\n    private Impl provider;\n    private ScriptEngine jsEngine;\n    private boolean enabled = false;\n\n    @Override\n    public synchronized void restored() {\n        if (provider == null) provider = new Impl();\n        TracerSupport.getInstance().registerPackageProvider(provider);\n        jsEngine = new ScriptEngineManager().getEngineByExtension(\"js\");\n        if (jsEngine != null) {\n            enabled = true;\n        }\n    }\n\n    @Override\n    public synchronized void uninstalled() {\n        if (provider == null) return;\n        TracerSupport.getInstance().unregisterPackageProvider(provider);\n        provider = null;\n    }\n\n\n    private class Impl extends TracerPackageProvider<Application> {\n\n        Impl() { super(Application.class); }\n\n        @Override\n        public TracerPackage<Application>[] getPackages(Application application) {\n            if (!enabled) return new TracerPackage[0];\n            Set<TracerPackage<Application>> packages = new HashSet<TracerPackage<Application>>();\n\n            Bindings bindings = jsEngine.createBindings();\n            bindings.put(\"application\", application);\n\n            try {\n                FileObject probesRoot = FileUtil.getConfigFile(\"VisualVM/Tracer/packages\"); // NOI18N\n                if (probesRoot != null) {\n                    jsEngine.eval(readResource(\"org/graalvm/visualvm/modules/tracer/dynamic/resources/configurator.js\").toString(), bindings);\n\n                    Enumeration<? extends FileObject> data = probesRoot.getData(false);\n\n                    while (data.hasMoreElements()) {\n                        FileObject cfg = data.nextElement();\n                        jsEngine.eval(cfg.asText(), bindings);\n                    }\n\n                    packages.addAll((Collection<TracerPackage<Application>>)bindings.get(\"configuredPackages\"));\n                }\n            } catch (IOException e) {\n            } catch (ScriptException e) {\n                e.printStackTrace();\n            }\n            return packages.toArray(new TracerPackage[packages.size()]);\n        }\n\n        private CharSequence readResource(String resName) {\n            StringBuilder sb = new StringBuilder();\n            InputStream is = getClass().getClassLoader().getResourceAsStream(resName);\n            if (is != null) {\n                BufferedReader br = new BufferedReader(new InputStreamReader(is));\n                try {\n                    String line = null;\n                    while ((line = br.readLine()) != null) {\n                        sb.append(line).append('\\n');\n                    }\n                } catch (IOException e) {\n                } finally {\n                    try {\n                        br.close();\n                    } catch (IOException e) {\n                    }\n                }\n            }\n            return sb;\n        }\n//        private static boolean isAvailable(ApplicationValidator validator, Application application) {\n//            if (validator == null) return true;\n//\n//            if (!application.isLocalApplication() ||\n//                 application.getState() != Stateful.STATE_AVAILABLE)\n//            return false;\n//\n//            return validator.isPackageApplicable(application);\n//        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracerdynamic/src/org/graalvm/visualvm/modules/tracer/dynamic/impl/DynamicProbe.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dynamic.impl;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.modules.tracer.dynamic.spi.DeployerImpl;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class DynamicProbe extends TracerProbe<Application>{\n    private TracerProbeDescriptor descriptor;\n    private List<ValueProvider> valueProviders;\n\n    private Map<DeployerImpl, Map<String, Object>>  deployers = new HashMap<DeployerImpl, Map<String, Object>>();\n\n    public DynamicProbe(List<ProbeItemDescriptor> itemDescriptors, List<ValueProvider> valueProviders) {\n        super(itemDescriptors.toArray(new ProbeItemDescriptor[itemDescriptors.size()]));\n        this.valueProviders = valueProviders;\n    }\n\n    public TracerProbeDescriptor getProbeDescriptor() {\n        return descriptor;\n    }\n\n    public void setProbeDescriptor(TracerProbeDescriptor descriptor) {\n        this.descriptor = descriptor;\n    }\n\n    public void addDeployment(DeployerImpl d, Map<String, Object> attribs) {\n        deployers.put(d, attribs);\n    }\n\n    public Set<DeployerImpl> applyDeployerConfigs(Application app) {\n        for(Map.Entry<DeployerImpl, Map<String, Object>> entry : deployers.entrySet()) {\n            entry.getKey().applyConfig(app, entry.getValue());\n        }\n        return deployers.keySet();\n    }\n\n    @Override\n    public long[] getItemValues(long timestamp) {\n        long[] vals = new long[valueProviders.size()];\n        int index = 0;\n        for(ValueProvider vp : valueProviders) {\n            vals[index++] = vp.getValue(timestamp);\n        }\n        return vals;\n    }\n}\n"
  },
  {
    "path": "plugins/tracerdynamic/src/org/graalvm/visualvm/modules/tracer/dynamic/impl/ItemValueFormatterInterface.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dynamic.impl;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface ItemValueFormatterInterface {\n    String formatValue(long value, int format);\n    String getUnits(int format);\n}\n"
  },
  {
    "path": "plugins/tracerdynamic/src/org/graalvm/visualvm/modules/tracer/dynamic/impl/ItemValueFormatterProxy.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dynamic.impl;\n\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ItemValueFormatterProxy extends ItemValueFormatter {\n    private ItemValueFormatterInterface impl;\n\n    public ItemValueFormatterProxy(ItemValueFormatterInterface impl) {\n        this.impl = impl;\n    }\n\n    @Override\n    public String getUnits(int format) {\n        return impl.getUnits(format);\n    }\n\n    @Override\n    public String formatValue(long value, int format) {\n        return impl.formatValue(value, format);\n    }\n}\n"
  },
  {
    "path": "plugins/tracerdynamic/src/org/graalvm/visualvm/modules/tracer/dynamic/impl/ValueProvider.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dynamic.impl;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface ValueProvider {\n    long getValue(long timestamp);\n}\n"
  },
  {
    "path": "plugins/tracerdynamic/src/org/graalvm/visualvm/modules/tracer/dynamic/jmx/JMXValueCache.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dynamic.jmx;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.WeakHashMap;\nimport javax.management.Attribute;\nimport javax.management.AttributeList;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.MBeanAttributeInfo;\nimport javax.management.MBeanInfo;\nimport javax.management.MBeanServerConnection;\nimport javax.management.ObjectName;\nimport javax.management.ReflectionException;\nimport javax.management.RuntimeMBeanException;\n\n/**\n * A per application cached MBean attribute values provider<br/>\n * It uses a timestamp to decide whether fresh values should be retrieved\n * from the server. It also tries to batch the retrieval process to reduce\n * the network utilization overhead.\n *\n * @author Jaroslav Bachorik\n */\nfinal public class JMXValueCache {\n    final private static Map<Application, JMXValueCache> instanceMap = new WeakHashMap<Application, JMXValueCache>();\n    final private Map<ObjectName, Collection<String>> attributeMap = new HashMap<ObjectName, Collection<String>>();\n    final private Map<String, Object> valueMap = new HashMap<String, Object>();\n\n    final private MBeanServerConnection connection;\n    volatile private long lastTimestamp = 0L;\n\n    private JMXValueCache(Application app) {\n        JmxModel model = JmxModelFactory.getJmxModelFor(app);\n        connection = model.getMBeanServerConnection();\n        \n    }\n\n    public static JMXValueCache forApplication(Application app) {\n        synchronized(instanceMap) {\n            JMXValueCache cvp = instanceMap.get(app);\n            if (cvp == null) {\n                cvp = new JMXValueCache(app);\n                instanceMap.put(app, cvp);\n            }\n            return cvp;\n        }\n    }\n\n    public JMXValueCache register(ObjectName name, String attribute) {\n        register(name, Collections.singleton(attribute));\n        return this;\n    }\n\n    public JMXValueCache register(ObjectName name, Collection<String> attributes) {\n        synchronized(attributeMap) {\n            Collection<String> existingAttribs = attributeMap.get(name);\n            if (existingAttribs == null) {\n                existingAttribs = new ArrayList<String>();\n                attributeMap.put(name, existingAttribs);\n            }\n            existingAttribs.addAll(attributes);\n            lastTimestamp = -1; // need to clear the timestamp so the cache is loaded at the next getValue() request\n        }\n        return this;\n    }\n\n    public JMXValueCache unregister(ObjectName name, String attribute) {\n        unregister(name, Collections.singleton(attribute));\n        return this;\n    }\n\n    public JMXValueCache unregister(ObjectName name, Collection<String> attributes) {\n        synchronized(attributeMap) {\n            Collection<String> existingAttribs = attributeMap.get(name);\n            if (existingAttribs != null) {\n                existingAttribs.removeAll(attributes);\n            }\n        }\n        return this;\n    }\n\n    public MBeanAttributeInfo getInfo(ObjectName on, String attribute) {\n        try {\n            MBeanInfo mbeanInfo = connection.getMBeanInfo(on);\n            for (MBeanAttributeInfo mbAttrInfo : mbeanInfo.getAttributes()) {\n                if (mbAttrInfo.getName().equals(attribute)) {\n                    return mbAttrInfo;\n                }\n            }\n        } catch (Exception e) {\n        }\n        return null;\n    }\n\n    public Object getValue(ObjectName name, String attribute, long timestamp) {\n        refreshCache(timestamp);\n        return valueMap.get(getId(name, attribute));\n    }\n    \n    private void refreshCache(long timestamp) {\n        if (lastTimestamp == timestamp) {\n            return;\n        }\n\n        lastTimestamp = timestamp;\n\n        synchronized(attributeMap) {\n            for(Map.Entry<ObjectName, Collection<String>> entry : attributeMap.entrySet()) {\n                try {\n                    AttributeList al = connection.getAttributes(entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]));\n                    for(Attribute a : al.asList()) {\n                        valueMap.put(getId(entry.getKey(), a.getName()), a.getValue());\n                    }\n                    continue;\n                } catch (RuntimeMBeanException ex) {\n                } catch (ReflectionException ex) {\n                } catch (IOException ex) {\n                } catch (InstanceNotFoundException e) {\n                }\n                for(String an : entry.getValue()) {\n                    String id = getId(entry.getKey(), an);\n                    if (!valueMap.containsKey(id)) valueMap.put(id, 0);\n                }\n            }\n        }\n    }\n\n    private String getId(ObjectName on, String attrName) {\n        return on.toString() + \"#\" + attrName;\n    }\n}\n"
  },
  {
    "path": "plugins/tracerdynamic/src/org/graalvm/visualvm/modules/tracer/dynamic/jmx/JMXValueProvider.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dynamic.jmx;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.dynamic.impl.ValueProvider;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.MBeanAttributeInfo;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class JMXValueProvider implements ValueProvider {\n    final private static Logger LOG = Logger.getLogger(JMXValueProvider.class.getName());\n    private ObjectName on;\n    private String attributeName;\n    private JMXValueCache cache;\n\n    public JMXValueProvider(String objectName, String attributeName, Application app) throws MalformedObjectNameException {\n        this.on = ObjectName.getInstance(objectName);\n        this.attributeName = attributeName;\n        cache = JMXValueCache.forApplication(app).register(on, attributeName);\n    }\n\n    @Override\n    public long getValue(long timestamp) {\n        Object val = value(timestamp);\n        if (val instanceof Number) {\n            return ((Number)val).longValue();\n        }\n        return 0L;\n    }\n\n    public Object value(long timestamp) {\n        Object val = cache.getValue(on, attributeName, timestamp);\n        if (val == null) {\n            LOG.log(Level.FINE, \"NULL({0}#{1}) @ {2}\", new Object[]{on, attributeName, timestamp});\n        }\n        return val == null ? 0 : val;\n    }\n\n    public MBeanAttributeInfo getInfo() {\n        return cache.getInfo(on, attributeName);\n    }\n}\n"
  },
  {
    "path": "plugins/tracerdynamic/src/org/graalvm/visualvm/modules/tracer/dynamic/resources/configurator.js",
    "content": "/*\n *  Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\nvar Color = Java.type(\"java.awt.Color\");\nvar ArrayList = Java.type(\"java.util.ArrayList\");\nvar HashMap = Java.type(\"java.util.HashMap\");\nvar Integer = Java.type(\"java.lang.Integer\");\nvar ObjectArray = Java.type('java.lang.Object[]');\nvar ProbeItemDescriptor = Java.type(\"org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor\");\nvar ItemValueFormatter = Java.type(\"org.graalvm.visualvm.modules.tracer.ItemValueFormatter\");\nvar TracerProbeDescriptor = Java.type(\"org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor\");\nvar ValueProvider = Java.type(\"org.graalvm.visualvm.modules.tracer.dynamic.impl.ValueProvider\");\nvar DynamicPackage = Java.type(\"org.graalvm.visualvm.modules.tracer.dynamic.impl.DynamicPackage\");\nvar DynamicProbe = Java.type(\"org.graalvm.visualvm.modules.tracer.dynamic.impl.DynamicProbe\");\nvar ItemValueFormatterInterface = Java.type(\"org.graalvm.visualvm.modules.tracer.dynamic.impl.ItemValueFormatterInterface\");\nvar ItemValueFormatterProxy = Java.type(\"org.graalvm.visualvm.modules.tracer.dynamic.impl.ItemValueFormatterProxy\");\nvar DeployerImpl = Java.type(\"org.graalvm.visualvm.modules.tracer.dynamic.spi.DeployerImpl\");\nvar JMXValueProvider = Java.type(\"org.graalvm.visualvm.modules.tracer.dynamic.jmx.JMXValueProvider\");\nvar JmxModelFactory = Java.type(\"org.graalvm.visualvm.tools.jmx.JmxModelFactory\");\nvar NbBundle = Java.type(\"org.openide.util.NbBundle\");\nvar ImageUtilities = Java.type(\"org.openide.util.ImageUtilities\");\nvar QueryExp = Java.type(\"javax.management.QueryExp\");\nvar ObjectName = Java.type(\"javax.management.ObjectName\");\nvar TabularData = Java.type(\"javax.management.openmbean.TabularData\");\nvar CompositeData = Java.type(\"javax.management.openmbean.CompositeData\");\nvar AUTOCOLOR = ProbeItemDescriptor.DEFAULT_COLOR;\n\nfunction VisualVM(){}\n\nVisualVM.Tracer = {\n    Type: {\n        discrete: \"discrete\",\n        continuous: \"continuous\"\n    },\n    addPackages: function (packages) {\n        if (application != undefined && packages != undefined) {\n            if (packages instanceof Array) {\n                for(var index in packages) {\n                    processPackage(packages[index]);\n                }\n            } else {\n                processPackage(packages);\n            }\n        }\n    }\n}\n\nVisualVM.MBeans = {\n    listMBeanNames: function(objectNamePattern, query) {\n        if (query != undefined && (query instanceof QueryExp)) {\n            return undefined;\n        }\n        objectNamePattern = objectNamePattern == undefined ? \"*\" : objectNamePattern;\n        query = query == undefined ? null : query;\n\n        var jmxModel = JmxModelFactory.getJmxModelFor(application);\n        if (jmxModel != undefined && jmxModel != null) {\n            var connection = jmxModel.getMBeanServerConnection();\n            if (connection != undefined && connection != null) {\n                var names = connection.queryNames(ObjectName.getInstance(objectNamePattern), query);\n                var iter = names.iterator();\n                var nameArr = new Array();\n                while (iter.hasNext()) {\n                    nameArr[nameArr.length] = iter.next().toString();\n                }\n                return nameArr;\n            }\n        }\n        return undefined;\n    },\n    attribute: function (objectName, attrName) {\n        return new MBeanAttribute(objectName, attrName);\n    }\n}\n\nvar NULL_VALUE = new ValueProvider({\n    getValue: function(timestamp) {\n        return 0;\n    }\n})\n\nfunction L11N(baseName) {\n    this.bundle = NbBundle.getBundle(baseName + \".Bundle\");\n\n    this.message = function (key, attrs) {\n        if (this.bundle != undefined) {\n            var msg = this.bundle.getString(key);\n            if (attrs != undefined && msg != undefined && msg != null) {\n                msg = java.text.MessageFormat(msg, attrs);\n            }\n            return msg;\n        }\n        return \"No resource bundle available for \" + baseName;\n    }\n}\n\nfunction getContinousItemDescriptorProvider(formatter) {\n    formatter = formatter || ItemValueFormatter.DECIMAL;\n\n    return function(property) {\n        var factor = property.presenter.factor != undefined ? property.factor : 1;\n        var min = property.presenter.min != undefined ? property.presenter.min : 0;\n        var max = property.presenter.max || ProbeItemDescriptor.MAX_VALUE_UNDEFINED;\n        var lineWidth = property.presenter.lineWidth || ProbeItemDescriptor.DEFAULT_LINE_WIDTH;\n        var lineColor = null;\n        var fillColor = null;\n        if (property.presenter.lineColor == undefined && property.presenter.fillColor == undefined) {\n            lineColor = AUTOCOLOR;\n        } else {\n            if (property.presenter.lineColor != undefined) {\n                lineColor = property.presenter.lineColor;\n            }\n            if (property.presenter.fillColor != undefined) {\n                fillColor = property.presenter.fillColor;\n            }\n        }\n        if (fillColor != undefined && lineColor == undefined) {\n            lineColor = fillColor;\n        }\n\n        return ProbeItemDescriptor.continuousItem(property.name, property.desc || \"\", formatter, factor, min, max, lineWidth, lineColor, fillColor);\n    }\n}\n\nfunction getDiscreteItemDescriptorProvider(formatter) {\n    formatter = formatter || ItemValueFormatter.DECIMAL;\n\n    return function(property) {\n        var factor = property.presenter.factor == undefined ? 1 : property.presenter.factor;\n        var min = property.presenter.min == undefined ? 0 : property.presenter.min;\n        var max = property.presenter.max == undefined ? ProbeItemDescriptor.MAX_VALUE_UNDEFINED : property.presenter.max;\n        var lineWidth = property.presenter.lineWidth == undefined ? ProbeItemDescriptor.DEFAULT_LINE_WIDTH : property.presenter.lineWidth;\n        var lineColor = null;\n        var fillColor = null;\n        if (property.presenter.lineColor == undefined && property.presenter.fillColor == undefined) {\n            lineColor = ProbeItemDescriptor.DEFAULT_COLOR;\n        } else {\n            if (property.presenter.lineColor != undefined) {\n                lineColor = property.presenter.lineColor;\n            }\n            if (property.presenter.fillColor != undefined) {\n                fillColor = property.presenter.fillColor;\n            }\n        }\n\n        if (fillColor != undefined && lineColor == undefined) {\n            lineColor = fillColor;\n        }\n        \n        if (property.presenter.topLine == undefined) {\n            property.presenter.topLine = false;\n        }\n        if (property.presenter.outline == undefined) {\n            property.presenter.outline = false;\n        }\n        if (property.presenter.fixedWidth == undefined) {\n            property.presenter.fixedWidth = false;\n        }\n        \n        if (property.presenter.topLine && !property.presenter.outline) {\n            return ProbeItemDescriptor.discreteToplineItem(property.name, property.desc || \"\",\n                formatter, factor, min, max, lineWidth, lineColor, fillColor,\n                property.presenter.width == undefined ? 0 : property.presenter.width,\n                property.presenter.fixedWidth\n            )\n        } else if (!property.presenter.fixedWidth) {\n            return ProbeItemDescriptor.discreteOutlineItem(property.name, property.desc || \"\",\n                formatter, factor, min, max, lineWidth, lineColor, fillColor)\n        } else {\n            return ProbeItemDescriptor.discreteBarItem(property.name, property.desc || \"\",\n                formatter, factor, min, max, lineWidth, lineColor, fillColor,\n                property.presenter.width == undefined ? 0 : property.presenter.width,\n                property.presenter.fixedWidth\n            )\n        }\n    }\n}\n\nfunction getItemDescriptor(property) {\n    if (property.presenter.type == undefined) {\n        property.presenter.type = VisualVM.Tracer.Type.continuous\n    }\n    if (property.presenter.format == undefined) {\n        property.presenter.format = ItemValueFormatter.DEFAULT_DECIMAL\n    } else if (property.presenter.format instanceof ItemValueFormatterInterface) {\n        property.presenter.format = new ItemValueFormatterProxy(property.presenter.format);\n    } else if (property.presenter != undefined &&\n        property.presenter.format != undefined &&\n        !(property.presenter.format instanceof ItemValueFormatter)) {\n        var presFormat = property.presenter.format;\n        var forward = {\n            formatValue: function(value, format) {\n                if (presFormat.formatValue != undefined) {\n                    return presFormat.formatValue(value, format);\n                }\n                return value;\n            },\n            getUnits: function(format) {\n                if (presFormat.getUnits != undefined) {\n                    return presFormat.getUnits(format);\n                }\n                return \"\";\n            }\n        }\n        property.presenter.format = new ItemValueFormatterProxy(new ItemValueFormatterInterface(forward));\n    }\n\n    if (property.presenter.type == VisualVM.Tracer.Type.continuous) {\n        return getContinousItemDescriptorProvider(property.presenter.format)(property);\n    } else if (property.presenter.type == VisualVM.Tracer.Type.discrete) {\n        return getDiscreteItemDescriptorProvider(property.presenter.format)(property);\n    }\n    return undefined;\n}\n\nvar configuredPackages = new ArrayList();\n\nfunction configure(packages) {\n    if (application != undefined && packages != undefined) {\n        if (packages instanceof Array) {\n            for(var index in packages) {\n                processPackage(packages[index]);\n            }\n        } else {\n            processPackage(packages);\n        }\n    }\n}\n\nfunction processPackage(pkg) {\n    // don't process package definition if it does not contain any probes\n    if (pkg.probes != undefined) {\n        var enabled = pkg.validator == undefined || pkg.validator(application);\n\n        var desc = pkg.desc != undefined ? pkg.desc : \"\";\n        if (!enabled) {\n            desc = desc.concat(getReqDesc(pkg));\n        }\n        var icon = pkg.icon != undefined ? pkg.icon : null;\n        var position = pkg.position != undefined ? pkg.position : Integer.MAX_VALUE;\n\n        if (typeof(icon) == \"string\") {\n            try {\n                icon = ImageUtilities.loadImageIcon(icon, true);\n            } catch (e) {\n                icon = null;\n            }\n        }\n\n        var dPkg = new DynamicPackage(pkg.name, desc, icon, position);\n\n        var probes = typeof(pkg.probes) == \"function\" ? pkg.probes() : pkg.probes;\n        var inferredPosition = 0;\n\n        for(var probeIndex in probes) {\n            var probe = probes[probeIndex];\n\n            // a valid probe must have properties\n            if (probe.properties != undefined) {\n                var itemDescriptors = new ArrayList();\n                var valProviders = new ArrayList();\n                var propArray;\n                if (typeof(probe.properties) == \"function\") {\n                    propArray = probe.properties();\n                } else if (probe.properties instanceof Array) {\n                    propArray = probe.properties;\n                }\n                if (propArray != undefined) {\n                    for(var propIndex in propArray) {\n                        var prop = probe.properties[propIndex];\n                        if (prop.presenter == undefined) {\n                            // setting default\n                            prop.presenter = {\n                                type: \"continuous\",\n                                format: ItemValueFormatter.DEFAULT_DECIMAL\n                            }\n                        }\n                        var itemDescriptor = getItemDescriptor(prop);\n                        \n                        if (itemDescriptor != null && itemDescriptor != undefined) {\n                            itemDescriptors.add(itemDescriptor);\n                        }\n                        if (typeof(prop.value) == \"function\") {\n                            var handler = {\n                                getValue: prop.value\n                            };\n                            valProviders.add(new ValueProvider(handler));\n                        } else if (prop.value.getValue != undefined) {\n                            valProviders.add(new ValueProvider(prop.value));\n                        } else if (prop.value.valueProvider != undefined) {\n                            valProviders.add(prop.value.valueProvider);\n                        }\n                    }\n\n                }\n                if (itemDescriptors.size() > 0) {\n                    var dProbe = new DynamicProbe(itemDescriptors, valProviders);\n                    // deployment is optional\n                    if (probe.deployment != undefined) {\n                        if (probe.deployment instanceof Array) {\n                            for (var deployment in probe.deployment) {\n                                if (deployment.deployer instanceof DeployerImpl) {\n                                    dProbe.addDeployment(deployment.deployer, getDeploymentAttributes(deployment));\n                                }\n                            }\n                        } else if (probe.deployment.deployer != undefined) {\n                            if (probe.deployment.deployer instanceof DeployerImpl) {\n                                dProbe.addDeployment(probe.deployment.deployer, getDeploymentAttributes(probe.deployment));\n                            }\n                        }\n                    }\n                    var pEnabled = enabled;\n                    desc = probe.desc != undefined ? probe.desc : \"\";\n                    if (pEnabled) {\n                        if (probe.validator != undefined) {\n                            pEnabled = probe.validator();\n                        }\n                        if (probe.deployment != undefined && probe.deployment.deployer != undefined) {\n                            pEnabled = probe.deployment.deployer.isApplicable(application);\n                        }\n                    }\n                    if (!pEnabled && enabled) {\n                        desc = desc.concat(getReqDesc(probe));\n                    }\n                    dProbe.setProbeDescriptor(new TracerProbeDescriptor(\n                        probe.name,\n                        desc || \"\", icon,\n                        probe.position != undefined ? probe.position : (inferredPosition += 10),\n                        pEnabled\n                    ));\n                    dPkg.addProbe(dProbe);\n                }\n            }\n        }\n        if (dPkg.getProbeDescriptors().length > 0) { // add only packages with at least one probe\n            configuredPackages.add(dPkg);\n        }\n    }\n}\n\nfunction getDeploymentAttributes(deployment) {\n    var map = new HashMap();\n    for(var attr in deployment) {\n        if (attr != \"deployer\") {\n            map.put(attr, deployment[attr]);\n        }\n    }\n    return map;\n}\n\nfunction mbeanAttribute(objectName, attrName) {\n    return new MBeanAttribute(objectName, attrName);\n}\n\nfunction delta(valProvider) {\n    return new Delta(valProvider);\n}\n\nfunction getKeys(map) {\n    var ret = new Array();\n    if (map == undefined || map == null) return 0;\n    if (map instanceof TabularData) {\n        var iter2 = map.keySet().iterator();\n        while (iter2.hasNext()) {\n            ret[ret.length] = iter2.next().get(0);\n        }        \n    } else if (map.length != undefined && map.length > 0 && map[0].getCompositeType != undefined) {\n        for(var counter=0; counter < map.length; counter++) {\n            ret[ret.length] = map[counter].get(\"key\");\n        }\n    } else if (map instanceof CompositeData) {\n        if (map.getCompositeType != undefined) {\n            var type = map.getCompositeType();\n        \n            var iter1 = type.keySet().iterator();\n            while (iter1.hasNext()) {\n                var val = iter1.next();\n                ret[ret.length] = val.get != undefined ? val.get(0) : val;\n            }\n        } else if (map.getTabularType != undefined) {\n            var iter2 = map.keySet().iterator();\n            while (iter2.hasNext()) {\n                ret[ret.length] = iter2.next().get(0);\n            }\n        }\n    }\n    return ret;\n}\n\nfunction arr(key) {\n    var array = new ObjectArray(1);\n    array[0] = key;\n    return array;\n}\n\nfunction get(map, keys) {\n    var ret;\n    var keyArray = isArray(keys);\n    var key = keyArray ? keys[0] : keys;\n    if (map == undefined || map == null) return 0;\n    if (map instanceof TabularData) {\n        // javax.management.openmbean.TabularDataSupport -> effectively a Map instance\n        if (!keyArray || keys.length == 1) {\n            ret = map.get(arr(key)).get(\"value\");\n            return ret;\n        } else {\n            ret = get(map.get(arr(key)).get(\"value\"), keys.slice(1));\n            return ret;\n        }\n    } else if (map.length != undefined && map.length > 0 && map[0].getCompositeType != undefined) {\n        for(var counter=0; counter < map.length; counter++) {\n            if (map[counter].get(\"key\") == key) {\n                if (!keyArray || keys.length == 1) {\n                    ret = map[counter].get(\"value\");\n                    return ret;\n                } else {\n                    ret = get(map[counter].get(\"value\"), keys.slice(1));\n                    return ret;\n                }\n            }\n        }\n    } else if (map instanceof CompositeData) {\n        if (map.getTabularType != undefined) {\n            // javax.management.openmbean.TabularDataSupport -> effectively a Map instance\n            if (!keyArray || keys.length == 1) {\n                ret = map.get(arr(key)).get(\"value\");\n                return ret;\n            } else {\n                ret = get(map.get(arr(key)).get(\"value\"), keys.slice(1));\n                return ret;\n            }\n        } else if (map.getCompositeType != undefined) {\n            if (!keyArray || keys.length == 1) {\n                ret = map.get(key);\n                return ret;\n            } else {\n                ret = get(map.get(key), keys.slice(1));\n                return ret;\n            }\n        }\n    }\n    return 0;\n}\n\nfunction getReqDesc(reqHolder) {\n    var desc = \"\";\n    if (reqHolder.reqs != undefined) {\n        desc = desc.concat(\" (\");\n        if (reqHolder.reqs.constructor == Array) {\n            for(var pi in reqHolder.reqs) {\n                desc = desc.concat((pi > 0) ? \", \" : \"\", reqHolder.reqs[pi]);\n            }\n        } else {\n            desc = desc.concat(reqHolder.reqs);\n        }\n        desc = desc.concat(\")\");\n    }\n    return desc;\n}\n\nfunction isArray(obj) {\n   return obj != undefined && obj.constructor == Array\n}\n\nfunction printStackTrace(exp) {\n    if (exp == undefined) {\n        try {\n            exp.toString();\n        } catch (e) {\n            exp = e;\n        }\n    }\n    // note that user could have caught some other\n    // \"exception\"- may be even a string or number -\n    // and passed the same as argument. Also, check for\n    // rhinoException property before using it\n    if (exp instanceof Error &&\n        exp.rhinoException != undefined) {\n        exp.rhinoException.printStackTrace();\n    }\n}\n\nfunction isFunction(obj) {\n    return obj != undefined && typeof(obj) == \"function\";\n}\n\n// ======================== Prototypes ===============================\nfunction MBeanAttribute(objectName, attributeName) {\n    var provider;\n\n    MBeanAttribute.prototype.sharedId++;\n\n    this.on = objectName != undefined ? objectName : \"\";\n    this.an = attributeName != undefined ? attributeName : \"\";\n    this.id = MBeanAttribute.prototype.sharedId;\n\n    var mbean = this;\n    this.get = function (key) {\n        return new WrappedValueProvider(this, key);\n    }\n\n    this.keys = function() {\n        return getKeys(mbean.getProvider().value(0));\n    }\n    \n    this.getInfo = function () {\n        return mbean.getProvider().getInfo();\n    }\n\n    this.value = function (timestamp) {\n        return mbean.getProvider().value(timestamp);\n//        return 0;\n    }\n\n    this.getValue =  this.value;\n\n    this.getProvider = function() {\n        if (provider == undefined) {\n            provider = new JMXValueProvider(this.on, this.an, application);\n        }\n        return provider;\n    }\n}\n\nMBeanAttribute.prototype.sharedId = 0;\n\nMBeanAttribute.prototype.clone = function() {\n    return new MBeanAttribute(this.on, this.an);\n}\nMBeanAttribute.prototype.setObjectName = function(objectName) {\n    this.on = objectName;\n}\nMBeanAttribute.prototype.setAttributeName = function(attribName) {\n    this.an = attribName;\n}\n\nfunction WrappedValueProvider(mbeanAttr, keys) {\n    this.attribute = mbeanAttr;\n    this.keys = new Array();\n    if (isArray(keys)) {\n        this.keys = this.keys.concat(keys);\n    } else {\n        this.keys.push(keys);\n    }\n\n    this.getNewKeys = function (key) {\n        var newKeys = new Array();\n        if (isArray(this.keys)) {\n            newKeys = newKeys.concat(this.keys);\n        } else {\n            newKeys.push(this.keys);\n        }\n            \n        newKeys.push(key);\n\n        return newKeys;\n    }\n\n    WrappedValueProvider.prototype.get = function (key) {\n        var myKeys = this.getNewKeys(key);\n        var ret = new WrappedValueProvider(this.attribute, myKeys);\n        return ret;\n    }\n\n    WrappedValueProvider.prototype.getValue = function (timestamp) {\n        var val = this.attribute.value(timestamp);\n        return get(val, this.keys);\n    }\n\n    WrappedValueProvider.prototype.getKeys = function() {\n        return getKeys(this.getValue(0));\n    }\n\n    WrappedValueProvider.prototype.dump = function () {\n        println(this.keys)\n    }\n}\n\n\nfunction Delta(valProvider) {\n    var oldValue;\n    var oldTimeStamp;\n    this.provider = valProvider;\n\n    this.getDelta = function(timeStamp) {\n        if (timeStamp == oldTimeStamp) return 0;\n        \n        var newValue = valProvider.getValue(timeStamp);\n        var delta = oldValue != undefined ? (newValue - oldValue) : 0;\n        oldValue = newValue;\n        return delta;\n    }\n}\n\nDelta.prototype.setObjectName = function(objectName) {\n    if (this.provider.setObjectName != undefined) {\n        this.provider.setObjectName(objectName);\n    }\n}\nDelta.prototype.setAttribute = function(attrName) {\n    if (this.provider.setAttribute != undefined) {\n        this.provider.setAttributeName(attrName);\n    }\n}\nDelta.prototype.getValue = function(timestamp) {\n    return this.getDelta(timestamp);\n}\nDelta.prototype.clone = function() {\n    return new Delta(isFunction(this.provider.clone) ? this.provider.clone() : this.provider);\n}\n"
  },
  {
    "path": "plugins/tracerdynamic/src/org/graalvm/visualvm/modules/tracer/dynamic/spi/DeployerImpl.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.dynamic.spi;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport java.util.Map;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\nabstract public class DeployerImpl {\n    abstract public void applyConfig(Application app, Map<String, Object> config);\n    abstract public boolean isApplicable(Application app);\n    abstract public boolean deploy(Application app, TracerProgressObject progress, int availableSteps);\n    abstract public void undeploy(Application app);\n}\n"
  },
  {
    "path": "plugins/tracerio/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.tracer.io\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.tracer.io.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerio/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: true\nOpenIDE-Module: org.graalvm.visualvm.modules.tracer.io/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/modules/tracer/io/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/tracer/io/Bundle.properties\nOpenIDE-Module-Requires: org.openjdk.btrace.visualvm.tracer.deployer\nOpenIDE-Module-Specification-Version: 2.2\n\n"
  },
  {
    "path": "plugins/tracerio/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.tracer.io-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerio/nbproject/project.properties",
    "content": "javac.source=1.6\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Tomas Hurka\n"
  },
  {
    "path": "plugins/tracerio/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.tracer.io</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer.dynamic</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/tracerio/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/tracerio/src/org/graalvm/visualvm/modules/tracer/io/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Tracer\nOpenIDE-Module-Long-Description=\\\n    Tracer probes to monitor Java I/O calls.\\n\\\n    <BR>\\n<BR>\\n<B>Technologies:</B>\\n<BR>\\nJMX, BTrace\\n<BR>\\n<BR>\\n<B>Requirements:</B>\\n<BR>\\nThis plugin requires the BTrace Deployer plugin to be installed.\nOpenIDE-Module-Name=Tracer-IO Probes\nOpenIDE-Module-Short-Description=Java I/O Tracer Probes\n"
  },
  {
    "path": "plugins/tracerio/src/org/graalvm/visualvm/modules/tracer/io/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.2//EN\" \"http://www.netbeans.org/dtds/filesystem-1_2.dtd\">\n<filesystem>\n    <folder name=\"VisualVM\">\n        <folder name=\"Tracer\">\n            <folder name=\"packages\">\n                <file name=\"io_traces.js\" url=\"resources/io_traces.js\">\n                    <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.modules.tracer.platformjmx.Bundle#VisualVM/Tracer/packages/platform_mx.js\"/>\n                </file>\n            </folder>\n        </folder>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "plugins/tracerio/src/org/graalvm/visualvm/modules/tracer/io/resources/IOTracer.btrace",
    "content": "/*\n *  Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.io.resources;\n\nimport org.openjdk.btrace.core.annotations.*;\nimport java.util.concurrent.atomic.AtomicLong;\nimport static org.openjdk.btrace.core.BTraceUtils.*;\n\n@BTrace(name=\"IOStats\") public class IOTracer {\n    // <fragment name=\"Java_IO\">\n    private static AtomicLong readCount = Atomic.newAtomicLong(0);\n    private static AtomicLong readBytes = Atomic.newAtomicLong(0);\n    private static AtomicLong writeCount = Atomic.newAtomicLong(0);\n    private static AtomicLong writtenBytes = Atomic.newAtomicLong(0);\n    @Property private static long lastReadCount,lastReadBytes,lastWriteCount,lastWrittenBytes;\n\t\n    @OnMethod(\n        clazz=\"/(java.io.FileInputStream)|(java.io.RandomAccessFile)/\",\n        method=\"read\",\n        type=\"int ()\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void onFileReadSingle(@ProbeClassName String pcn, @Self Object fis,@Return int data) {\n        readBytes(pcn, fis, \"single read\", data==-1?-1:1);\n    }\n\n    @OnMethod(\n        clazz=\"/(java.io.FileInputStream)|(java.io.RandomAccessFile)/\",\n        method=\"read\",\n        type=\"int (byte[])\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void onFileReadArray(@ProbeClassName String pcn, @Self Object fis, @Return int length) {\n        readBytes(pcn, fis, \"read byte array\", length);\n    }\n    \n    @OnMethod(\n        clazz=\"/(java.io.FileInputStream)|(java.io.RandomAccessFile)/\",\n        method=\"read\",\n        type=\"int (byte[], int, int)\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void onFileRead(@ProbeClassName String pcn, @Self Object fis, @Return int length) {\n        readBytes(pcn, fis, \"read byte array (start,off)\", length);\n    }\n        \n    @OnMethod(\n        clazz=\"/(java.io.FileOutputStream)|(java.io.RandomAccessFile)/\",\n        method=\"write\",\n        type=\"void (int)\"\n    )\n    public static void onFileWriteSingle(@ProbeClassName String pcn, @Self Object fos) {\n        writeBytes(pcn, fos, \"single write\", 1);\n    }\n\n    @OnMethod(\n        clazz=\"/(java.io.FileOutputStream)|(java.io.RandomAccessFile)/\",\n        method=\"write\",\n        type=\"void (byte[])\"\n    )\n    public static void onFileWriteArray(@ProbeClassName String pcn, @Self Object fos, byte[] data) {\n        writeBytes(pcn, fos, \"write byte array\", data.length);\n    }\n    \n    @OnMethod(\n        clazz=\"/(java.io.FileOutputStream)|(java.io.RandomAccessFile)/\",\n        method=\"write\",\n        type=\"void (byte[], int, int)\"\n    )\n    public static void onFileRead(@ProbeClassName String pcn, @Self Object fos, byte[] data, int offset, int length) {\n        writeBytes(pcn, fos, \"write byte array (start,off)\", length);\n    }\n    \n    @OnMethod(\n              clazz=\"sun.nio.ch.FileChannelImpl\",\n              method=\"read\",\n              type=\"int (java.nio.ByteBuffer)\",\n              location=@Location(Kind.RETURN)\n              )\n    public static void onFileChannelReadArray(@ProbeClassName String pcn, @Self Object fis, @Return int length) {\n        readBytes(pcn, fis, \"FC read byte array\", length);\n    }\n\n    @OnMethod(\n              clazz=\"sun.nio.ch.FileChannelImpl\",\n              method=\"read\",\n              type=\"long (java.nio.ByteBuffer[], int, int)\",\n              location=@Location(Kind.RETURN)\n              )\n    public static void onFileChannelRead(@ProbeClassName String pcn, @Self Object fis, @Return long length) {\n        readBytes(pcn, fis, \"FC read byte array (offset, len)\", length);\n    }\n\n    @OnMethod(\n              clazz=\"sun.nio.ch.FileChannelImpl\",\n              method=\"readInternal\",\n              type=\"int (java.nio.ByteBuffer, long)\",\n              location=@Location(Kind.RETURN)\n              )\n    public static void onFileChannelReadInternal(@ProbeClassName String pcn, @Self Object fis, @Return int length) {\n        readBytes(pcn, fis, \"FC read internal byte array\", length);\n    }\n    \n    @OnMethod(\n              clazz=\"sun.nio.ch.FileChannelImpl\",\n              method=\"write\",\n              type=\"int (java.nio.ByteBuffer)\",\n              location=@Location(Kind.RETURN)\n              )\n    public static void onFileChannelWriteArray(@ProbeClassName String pcn, @Self Object fis, @Return int length) {\n        writeBytes(pcn, fis, \"FC write byte array\", length);\n    }\n    \n    @OnMethod(\n              clazz=\"sun.nio.ch.FileChannelImpl\",\n              method=\"write\",\n              type=\"long (java.nio.ByteBuffer[], int, int)\",\n              location=@Location(Kind.RETURN)\n              )\n    public static void onFileChannelWrite(@ProbeClassName String pcn, @Self Object fis, @Return long length) {\n        writeBytes(pcn, fis, \"FC write byte array (offset, len)\", length);\n    }\n    \n    @OnMethod(\n              clazz=\"sun.nio.ch.FileChannelImpl\",\n              method=\"writeInternal\",\n              type=\"int (java.nio.ByteBuffer, long)\",\n              location=@Location(Kind.RETURN)\n              )\n    public static void onFileChannelWrite(@ProbeClassName String pcn, @Self Object fis, @Return int length) {\n        writeBytes(pcn, fis, \"FC write internal byte array\", length);\n    }\n\n    private static void readBytes(String pcn, Object self, String info, long length) {\n        Atomic.getAndIncrement(readCount);\n        if (length != -1) {\n            Atomic.getAndAdd(readBytes, length);\n        }\n    }\n\n    private static void writeBytes(String pcn, Object self, String info, long length) {\n        Atomic.getAndIncrement(writeCount);\n        Atomic.getAndAdd(writtenBytes, length);\n    }\n    // </fragment>\n    \n    @OnTimer(1000)\n    public static void onTimer() {\n        // <fragment name=\"Java_IO\">\n        lastReadCount = Atomic.getAndSet(readCount,0);\n        lastReadBytes = Atomic.getAndSet(readBytes,0);\n        lastWriteCount = Atomic.getAndSet(writeCount,0);\n        lastWrittenBytes = Atomic.getAndSet(writtenBytes,0);\n        // </fragment>\n    }\n}\n"
  },
  {
    "path": "plugins/tracerio/src/org/graalvm/visualvm/modules/tracer/io/resources/io_traces.js",
    "content": "/*\n *  Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\nvar scriptPath = \"nbres:/org/graalvm/visualvm/modules/tracer/io/resources/IOTracer.btrace\"\nvar btraceDeployerClass;\ntry {\n  btraceDeployerClass = Java.type(\"org.openjdk.btrace.visualvm.tracer.deployer.BTraceDeployer\");\n} catch (e) {\n  btraceDeployerClass = null;\n}\nvar btraceDeployer = btraceDeployerClass ? btraceDeployerClass.instance() : undefined;\n\nfunction DivideBytesAcc(mbeanBytes, mbeanCount) {\n    this.value = function (ts) {\n        var bytes = mbeanBytes.getValue(ts);\n        var count = mbeanCount.getValue(ts);\n        if (count != 0) {\n            return bytes/count;\n        }\n        return  0;\n    }\n}\n\nfunction divideBytes(mbeanBytes, mbeanCount) {\n    return new DivideBytesAcc(mbeanBytes, mbeanCount).value;\n}\n\nVisualVM.Tracer.addPackages([{\n        name: \"Java I/O\",\n        desc: \"Java I/O statistics\",\n        position: 553,\n        probes: [\n            {\n                name: \"File I/O count\",\n                desc: \"Invocations count of file read/write operations.\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"Java_IO\"\n                },\n                properties: [\n                    {\n                        name: \"File Read Count\",\n                        desc: \"Invocations count of file read operations.\",\n                        value: mbeanAttribute(\"btrace:name=IOStats\", \"lastReadCount\")\n\n                    },\n                    {\n                        name: \"File Write Count\",\n                        desc: \"Invocations count of file write operations.\",\n                        value: mbeanAttribute(\"btrace:name=IOStats\", \"lastWriteCount\")\n\n                    }\n                ]\n            },\n            {\n                name: \"File I/O bytes\",\n                desc: \"Number of bytes read or written to files.\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"Java_IO\"\n                },\n                properties: [\n                    {\n                        name: \"File Read Bytes\",\n                        desc: \"Number of bytes read from files.\",\n                        value: mbeanAttribute(\"btrace:name=IOStats\", \"lastReadBytes\")\n                    },\n                    {\n                        name: \"File Write Bytes\",\n                        desc: \"Number of bytes written to files.\",\n                        value: mbeanAttribute(\"btrace:name=IOStats\", \"lastWrittenBytes\")\n                    }\n                ]\n            },\n            {\n                name: \"File I/O size\",\n                desc: \"Average number of bytes per one read/write operation.\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"Java_IO\"\n                },\n                properties: [\n                    {\n                        name: \"File Read Size\",\n                        desc: \"Average number of bytes read per one operation.\",\n                        value: divideBytes(mbeanAttribute(\"btrace:name=IOStats\", \"lastReadBytes\"),mbeanAttribute(\"btrace:name=IOStats\", \"lastReadCount\"))\n                    },\n                    {\n                        name: \"File Write Size\",\n                        desc: \"Average number of bytes written per one operation.\",\n                        value: divideBytes(mbeanAttribute(\"btrace:name=IOStats\", \"lastWrittenBytes\"),mbeanAttribute(\"btrace:name=IOStats\", \"lastWriteCount\"))\n                    }\n                ]\n            }\n        ]\n    }\n]);\n"
  },
  {
    "path": "plugins/tracerjavafx/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.tracer.javafx\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.tracer.javafx.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerjavafx/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.tracer.javafx/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/modules/tracer/javafx/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/tracer/javafx/Bundle.properties\nOpenIDE-Module-Requires: org.openjdk.btrace.visualvm.tracer.deployer\nOpenIDE-Module-Specification-Version: 2.2\n\n"
  },
  {
    "path": "plugins/tracerjavafx/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.tracer.javafx-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerjavafx/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=6b101b50\nbuild.xml.script.CRC32=c320ec58\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=5ed75970\nnbproject/build-impl.xml.script.CRC32=077f8270\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.42.1\n"
  },
  {
    "path": "plugins/tracerjavafx/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Petr Suchomel\n"
  },
  {
    "path": "plugins/tracerjavafx/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.tracer.javafx</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer.dynamic</code-name-base>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/tracerjavafx/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/tracerjavafx/src/org/graalvm/visualvm/modules/tracer/javafx/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Tracer\nOpenIDE-Module-Long-Description=\\\n    VisualVM-Tracer plugin providing various metrics for monitoring runtime behavior of a JavaFX application.\\n\\\n    <BR>\\n<BR>\\n<B>Technologies:</B>\\n<BR>\\nJMX, BTrace\\n<BR>\\n<BR>\\n<B>Requirements:</B>\\n<BR>\\nThis plugin requires the BTrace Deployer plugin to be installed.\nOpenIDE-Module-Name=Tracer-JavaFX Probes\nOpenIDE-Module-Short-Description=JavaFX Metrics for Tracer\nVisualVM/Tracer/packages/jfx=JavaFX Metrics\nVisualVM/Tracer/packages/jfx/probes/fps=Average FPS\nVisualVM/Tracer/packages/jfx/probes/fps/properties/averageFPS=Average FPS\nVisualVM/Tracer/packages/jfx/probes/metrics=FX Metrics\nVisualVM/Tracer/packages/jfx/probes/metrics/properties/invalidationRate=Invalidation Rate\nVisualVM/Tracer/packages/jfx/probes/metrics/properties/replacementRate=Replacement Rate\nVisualVM/Tracer/packages/jfx/probes/objects=FX Objects\nVisualVM/Tracer/packages/jfx/probes/objects/properties/fxObjectCreationRate=Overall rate\nVisualVM/Tracer/packages/jfx/probes/pulseCount=Scenegraph mouse and key statistic\nVisualVM/Tracer/packages/jfx/probes/pulseCount/properties/keyPulses=Key events\nVisualVM/Tracer/packages/jfx/probes/pulseCount/properties/mousePulses=Mouse events\nVisualVM/Tracer/packages/jfx/probes/pulseTiming=Scenegraph mouse and key event timing\nVisualVM/Tracer/packages/jfx/probes/pulseTiming/properties/keyPulsesCumulativeTime=Key events time\nVisualVM/Tracer/packages/jfx/probes/pulseTiming/properties/mousePulsesCumulativeTime=Mouse events time\nVisualVM/Tracer/packages/jfx/probes/sgCss=Scenegraph CSS statistic\nVisualVM/Tracer/packages/jfx/probes/sgCss/properties/getStyleHelperCalls=Style helpers calls\nVisualVM/Tracer/packages/jfx/probes/sgCss/properties/processCssCount=CSS process calls\nVisualVM/Tracer/packages/jfx/probes/sgCss/properties/styleHelperCount=Style helpers count\nVisualVM/Tracer/packages/jfx/probes/sgCss/properties/transitionToStateCalls=Transitions\nVisualVM/Tracer/packages/jfx/probes/sgNode=Scenegraph nodes statistic\nVisualVM/Tracer/packages/jfx/probes/sgNode/properties/needsLayout=Layout required\nVisualVM/Tracer/packages/jfx/probes/sgNode/properties/nodeCount=Node count\nVisualVM/Tracer/packages/jfx/probes/sgTiming=Scenegraph timing monitoring\nVisualVM/Tracer/packages/jfx/probes/sgTiming/properties/dirtyRegionsCumulativeTime=Dirty regions\nVisualVM/Tracer/packages/jfx/probes/sgTiming/properties/paintCumulativeTime=Paint time\nVisualVM/Tracer/packages/jfx/probes/sgTiming/properties/synchronizationTime=Synchronization time\nVisualVM/Tracer/packages/jfx/probes/synCalls=Synchronization calls\nVisualVM/Tracer/packages/jfx/probes/synCalls/properties/synchronizationCalls=Synchronization calls\n"
  },
  {
    "path": "plugins/tracerjavafx/src/org/graalvm/visualvm/modules/tracer/javafx/fx_tracer.js",
    "content": "/*\n *  Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\nvar loc = new L11N(\"org.graalvm.visualvm.modules.tracer.javafx\")\n\nvar scriptPath = \"nbres:/org/graalvm/visualvm/modules/tracer/javafx/resources/JavaFXTracer.probe\"\nvar btraceDeployerClass;\ntry {\n  btraceDeployerClass = Java.type(\"org.openjdk.btrace.visualvm.tracer.deployer.BTraceDeployer\");\n} catch (e) {\n  btraceDeployerClass = null;\n}\nvar btraceDeployer = btraceDeployerClass ? btraceDeployerClass.instance() : undefined;\nvar JvmFactory = Java.type(\"org.graalvm.visualvm.application.jvm.JvmFactory\");\n\nVisualVM.Tracer.addPackages({\n    // JavaFX Metrics package\n    name: loc.message(\"VisualVM/Tracer/packages/jfx\"),\n    desc: \"Monitors runtime behavior of JavaFX applications\",\n    icon: \"org/graalvm/visualvm/modules/tracer/javafx/resources/fx.png\",\n    position: 800,\n    reqs: \"Available only for JavaFX applications\",\n    validator: function() {\n        var jvm = JvmFactory.getJVMFor(application);\n        return jvm != undefined && jvm.getMainClass() == \"com.sun.javafx.runtime.Main\";\n    },\n    probes: [\n        {\n            // FX Metrics\n            name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/metrics\"),\n            desc: \"Monitors Invalidation Rate and Replacement Rate\",\n            reqs: \"Requires BTrace Deployer plugin.\",\n            validator: function() {\n                return btraceDeployer != undefined;\n            },\n            deployment: {\n                deployer: btraceDeployer,\n                fragment: \"metrics\",\n                script: scriptPath\n            },\n            properties: [\n                {\n                    // invalidation rate\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/metrics/properties/invalidationRate\"),\n                    desc: \"Monitors number of invalidations per second\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"invalidationRate\")\n                },\n                {\n                    // replacement rate\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/metrics/properties/replacementRate\"),\n                    desc: \"Monitors number of replacements per second\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"replacementRate\")\n                }\n            ]\n        },\n        {\n            // FX Objects\n            name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/objects\"),\n            desc: \"Monitors Overall Rate and Hot Class Rate\",\n            reqs: \"Requires BTrace Deployer plugin.\",\n            validator: function() {\n                return btraceDeployer != undefined;\n            },\n            deployment: {\n                deployer: btraceDeployer,\n                fragment: \"objects\",\n                script: scriptPath\n            },\n            properties: [\n                {\n                    // Overall Rate\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/objects/properties/fxObjectCreationRate\"),\n                    desc: \"Monitors the number of created objects per second\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"fxObjectCreationRate\")\n                }\n            ]\n        },\n        {\n            // Average FPS\n            name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/fps\"),\n            desc: \"Monitors average frame per second rate\",\n            reqs: \"Requires BTrace Deployer plugin.\",\n            validator: function() {\n                return btraceDeployer != undefined;\n            },\n            deployment: {\n                deployer: btraceDeployer,\n                fragment: \"fps\",\n                script: scriptPath\n            },\n            properties: [\n                {\n                    // Average FPS\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/fps/properties/averageFPS\"),\n                    desc: \"Monitors average frame per second rate\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"averageFPS\")\n                }\n            ]\n        },\n        {\n            // Scenegraph mouse and key statistics\n            name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/pulseCount\"),\n            desc: \"Monitors mouse and keyboard activity\",\n            reqs: \"Requires BTrace Deployer plugin.\",\n            validator: function() {\n                return btraceDeployer != undefined;\n            },\n            deployment: {\n                deployer: btraceDeployer,\n                fragment: \"pulseCount\",\n                script: scriptPath\n            },\n            properties: [\n                {\n                    // Key events\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/pulseCount/properties/keyPulses\"),\n                    desc: \"Monitors keyboard activity\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"keyPulses\")\n                },\n                {\n                    // Mouse events\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/pulseCount/properties/mousePulses\"),\n                    desc: \"Monitors mouse activity\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"mousePulses\")\n                }\n            ]\n        },\n        {\n            // Scenegraph mouse and key event timing\n            name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/pulseTiming\"),\n            desc: \"Monitors mouse and keyboard event timing\",\n            reqs: \"Requires BTrace Deployer plugin.\",\n            validator: function() {\n                return btraceDeployer != undefined;\n            },\n            deployment: {\n                deployer: btraceDeployer,\n                fragment: \"pulseTiming\",\n                script: scriptPath\n            },\n            properties: [\n                {\n                    // Key events time\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/pulseTiming/properties/keyPulsesCumulativeTime\"),\n                    desc: \"Monitors keyboard processing time\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"keyPulsesCumulativeTime\")\n                },\n                {\n                    // Mouse events time\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/pulseTiming/properties/mousePulsesCumulativeTime\"),\n                    desc: \"Monitors mouse processing time\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"mousePulsesCumulativeTime\")\n                }\n            ]\n        },\n        {\n            // Scenegraph timing monitoring\n            name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/sgTiming\"),\n            desc: \"Monitors scenegraph timing\",\n            reqs: \"Requires BTrace Deployer plugin.\",\n            validator: function() {\n                return btraceDeployer != undefined;\n            },\n            deployment: {\n                deployer: btraceDeployer,\n                fragment: \"sgTiming\",\n                script: scriptPath\n            },\n            properties: [\n                {\n                    // Dirty regions\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/sgTiming/properties/dirtyRegionsCumulativeTime\"),\n                    desc: \"Dirty regions processing time\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"dirtyRegionsCumulativeTime\")\n                },\n                {\n                    // Paint time\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/sgTiming/properties/paintCumulativeTime\"),\n                    desc: \"Paint processing time\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"paintCumulativeTime\")\n                },\n                {\n                    // Synchronization time\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/sgTiming/properties/synchronizationTime\"),\n                    desc: \"Synchronization time\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"synchronizationTime\")\n                }\n            ]\n        },\n        {\n            // Scenegraph nodes statistics\n            name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/sgNode\"),\n            desc: \"Scenegraph nodes statistic\",\n            reqs: \"Requires BTrace Deployer plugin.\",\n            validator: function() {\n                return btraceDeployer != undefined;\n            },\n            deployment: {\n                deployer: btraceDeployer,\n                fragment: \"sgNode\",\n                script: scriptPath\n            },\n            properties: [\n                {\n                    // Layout required\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/sgNode/properties/needsLayout\"),\n                    desc: \"How many nodes layout required\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"needsLayout\")\n                },\n                {\n                    // Node count\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/sgNode/properties/nodeCount\"),\n                    desc: \"Amount of nodes in sceengraph\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"nodeCount\")\n                }\n            ]\n        },\n        {\n            // Scenegraph CSS statistics\n            name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/sgCss\"),\n            desc: \"Scenegraph CSS statistic\",\n            reqs: \"Requires BTrace Deployer plugin.\",\n            validator: function() {\n                return btraceDeployer != undefined;\n            },\n            deployment: {\n                deployer: btraceDeployer,\n                fragment: \"sgCss\",\n                script: scriptPath\n            },\n            properties: [\n                {\n                    // Style helpers calls\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/sgCss/properties/getStyleHelperCalls\"),\n                    desc: \"Style helpers calls\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"getStyleHelperCalls\")\n                },\n                {\n                    // Style helpers count\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/sgCss/properties/styleHelperCount\"),\n                    desc: \"Style helpers count\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"styleHelperCount\")\n                },\n                {\n                    // Style helpers count\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/sgCss/properties/transitionToStateCalls\"),\n                    desc: \"Transitions\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"transitionToStateCalls\")\n                },\n                {\n                    // Style helpers count\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/sgCss/properties/processCssCount\"),\n                    desc: \"CSS process calls\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"processCssCount\")\n                }\n            ]\n        },\n        {\n            // Synchronization calls\n            name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/synCalls\"),\n            desc: \"Monitors amount of synchronization calls\",\n            reqs: \"Requires BTrace Deployer plugin.\",\n            validator: function() {\n                return btraceDeployer != undefined;\n            },\n            deployment: {\n                deployer: btraceDeployer,\n                fragment: \"synCalls\",\n                script: scriptPath\n            },\n            properties: [\n                {\n                    // Synchronization calls\n                    name: loc.message(\"VisualVM/Tracer/packages/jfx/probes/synCalls/properties/synchronizationCalls\"),\n                    desc: \"Monitors amount of synchronization calls\",\n                    value: mbeanAttribute(\"btrace:name=FxBtraceTracker\", \"synchronizationCalls\")\n                }\n            ]\n        },\n    ]\n})\n"
  },
  {
    "path": "plugins/tracerjavafx/src/org/graalvm/visualvm/modules/tracer/javafx/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.2//EN\" \"http://www.netbeans.org/dtds/filesystem-1_2.dtd\">\n<filesystem>\n    <folder name=\"VisualVM\">\n        <folder name=\"Tracer\">\n            <folder name=\"packages\">\n                <file name=\"fx_tracer.js\" url=\"fx_tracer.js\"/>\n            </folder>\n        </folder>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "plugins/tracerjavafx/src/org/graalvm/visualvm/modules/tracer/javafx/resources/JavaFXTracer.probe",
    "content": "/*\n * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nimport org.openjdk.btrace.core.annotations.*;\nimport static org.openjdk.btrace.core.BTraceUtils.*;\nimport java.util.Map;\nimport java.lang.ref.*;\nimport java.util.concurrent.atomic.AtomicLong;\nimport java.util.Iterator;\n\n// <fragment name=\"sgNode\">\nimport com.sun.javafx.runtime.sequence.Sequence;\n// </fragment>\n\n/**\n * This BTrace script tries to measure aggregate stat like total\n * FXObject count, total dependent count, total notification count etc.\n * This script measures histogram of FXObjects as well.\n *\n * @author A. Sundararajan\n * @author J. Bachorik\n */\n@BTrace(name=\"FxBtraceTracker\", unsafe=true) public class FxBtraceTracker {\n\n    // @Property exposes this field as MBean attribute\n\n    // <fragment name=\"metrics\">\n    @Property private static long invalidationRate = 0;\n    volatile private static long invalidations = 0;\n\n    @Property private static long replacementRate = 0;\n    volatile private static long replacements = 0;\n    // </fragment>\n\n    // <fragment name=\"objects\">\n    volatile private static long fxObjectCountRunning = 0;\n\n    @Property private static long fxObjectCreationRate = 0;\n    @Property private static long fxObjectDeletionRate = 0;\n    // </fragment>\n\n    // <fragment name=\"fps\">\n    @Property private static int allPulses = 0;\n    volatile private static int pulses = 0;\n    @Property private static double averageFPS = 0.0;\n    // </fragment>\n\n    // <fragment name=\"pulseCount\">\n    @Property private static long mousePulses = 0L;\n    @Property private static long keyPulses = 0L;\n\n    volatile private static int mPulses = 0;\n    volatile private static int kPulses = 0;\n    // </fragment>\n\n    // <fragment name=\"pulseTiming\">\n    @Property private static long mousePulsesCumulativeTime = 0L;\n    @Property private static long keyPulsesCumulativeTime = 0L;\n    volatile private static long mCumulativeTime = 0L;\n    volatile private static long mCurrentTime = 0L;\n    \n    volatile private static long kCumulativeTime = 0L;\n    volatile private static long kCurrentTime = 0L;\n    // </fragment>\n\n    // <fragment name=\"sgCss\">\n    //styles\n    @Property private static long getStyleHelperCalls = 0;\n    @Property private static long styleHelperCount = 0;\n    @Property private static long transitionToStateCalls = 0;\n    @Property private static long processCssCount = 0;\n    @Property private static long processCssOnRootCount = 0;\n\n    volatile private static long getStyleHelperCallsLocal = 0;\n    volatile private static long transitionToStateCallsLocal = 0;\n    volatile private static long processCssCountLocal = 0;\n    volatile private static long processCssOnRootCountLocal = 0;\n    // </fragment>\n\n    // <fragment name=\"sgNode\">\n    //unsafe\n    //\n    @Property private static long nodeCount = 0L;\n    @Property private static long needsLayout = 0L;\n    volatile private static long nodeCountInternal = 0L;\n    volatile private static long needsLayoutInternal = 0L;\n    // </fragment>\n\n    // <fragment name=\"sgTiming\">\n    @Property private static long paintCumulativeTime = 0L;\n    @Property private static long dirtyRegionsCumulativeTime = 0L;\n    //paint\n    volatile private static long pCumulativeTime = 0L;\n    volatile private static long pCurrentTime = 0L;\n    //dirty regions\n    volatile private static long dCumulativeTime = 0L;\n    volatile private static long dCurrentTime = 0L;\n    //synchronization\n    @Property private static long synchronizationTime = 0L;\n    volatile private static long syncCumulativeTime = 0L;\n    volatile private static long syncCurrentTime = 0L;\n    // </fragment>\n\n    // <fragment name=\"synCalls\">\n    @Property private static long synchronizationCalls = 0L;\n    @Property private static String clazzName;\n    volatile private static long syncCalls = 0L;\n    // </fragment>\n\n    volatile private static long startTime = 0;\n\n    //just the debug variables\n    @Property private static long xyz = 0L;\n    volatile private static long _xyz = 0L;\n\n    // <fragment name=\"objects\">\n    @OnMethod(\n\tclazz=\"com.sun.javafx.runtime.FXBase\",\n        method=\"<init>\"\n    )\n    public static void onNewFXObject(@Self Object obj, boolean dummy) {\n        fxObjectCountRunning++;\n    }\n    // </fragment>\n\n    // <fragment name=\"metrics\">\n    @OnMethod(\n        clazz=\"+com.sun.javafx.runtime.FXBase\",\n        method=\"/invalidate\\\\$.+/\"\n    )\n    public static void onInvalidate() {\n        invalidations++;\n    }\n\n    @OnMethod(\n        clazz=\"+com.sun.javafx.runtime.FXBase\",\n        method=\"/onReplace\\\\$.+/\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void onOnReplaceReturn() {\n        replacements++;\n    }\n    // </fragment>\n\n    //here to compute FPS related fields\n    @OnMethod(\n        clazz=\"javafx.scene.Scene$ScenePulseListener\",\n        method=\"pulse\"\n    )\n    public static void onPulse(@Self Object obj){\n        // <fragment name=\"fps\">\n        if (startTime == 0)\n            startTime = timeNanos();\n            pulses++;\n        // </fragment>\n\n        // <fragment name=\"sgNode\">\n        //here the unsafe operations\n//        java.lang.reflect.Field f = field(\"com.sun.stylesheet.StyleManager\", \"$defaultContainer\");\n//        println(f);\n\n        //$javafx$scene$Scene$ScenePulseListener$scene$\n        javafx.scene.Scene scene = (javafx.scene.Scene)get(field(name(classOf(obj)), \"accessOuterField$\"), obj);\n        Sequence seq = scene.get$content();//(Sequence)get(field(name(classOf(scene)), \"$content\"), scene);\n\n        int cnt = 0;\n        int needsLayout = 0;\n        java.util.Deque<java.util.Iterator> queue = newDeque();\n        java.util.Iterator it = seq.iterator();\n        while(it != null && it.hasNext()){\n            Object object = it.next();\n            if (object instanceof javafx.scene.Parent){\n                seq = ((javafx.scene.Parent)object).impl_getChildren();\n                //println(\"It is sequence \" + seq.size());\n                push(queue, it);\n                it = seq.iterator();\n                /* pulse enter point seems to be correct for computing if layouting is needed,\n                   as long as layouting calls are done within this procedure - in this place,\n                   all needsLayout must be set IMO */\n            }\n            if(((javafx.scene.Node)object).get$parent().get$needsLayout()){\n                needsLayoutInternal++;\n            }\n            cnt++;\n\n            if (!it.hasNext()){\n                it = poll(queue);\n            }\n        }\n        nodeCountInternal = cnt;\n        // </fragment>\n    }\n\n    // <fragment name=\"sgTiming\">\n    @OnMethod(\n        clazz=\"com.sun.scenario.scenegraph.JSGPanel\",\n        method=\"paintComponent\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void painComponentExit(@Duration long dur){\n        pCumulativeTime += dur;\n    }\n\n    @OnMethod(\n        clazz=\"com.sun.scenario.scenegraph.JSGPanel\",\n        method=\"accumulateDirtyRegions\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void accumulateDirtyRegionsExit(@Duration long dur){\n        dCumulativeTime += dur;\n    }\n    // </fragment>\n\n    // <fragment name=\"pulseCount\">\n    //mouse\n    @OnMethod(\n        clazz=\"javafx.scene.Scene\",\n        method=\"impl_processMouseEvent\"\n    )\n    public static void onMousePulseEnter(){\n        mPulses++;\n    }\n    //keyboard\n    @OnMethod(\n        clazz=\"javafx.scene.Scene\",\n        method=\"impl_processKeyEvent\"\n    )\n    public static void onKeyPulseEnter(){\n        kPulses++;\n    }\n    // </fragment>\n\n    // <fragment name=\"pulseTiming\">\n    // mouse\n    @OnMethod(\n        clazz=\"javafx.scene.Scene\",\n        method=\"impl_processMouseEvent\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void onMousePulseExit(@Duration long dur){\n        mCumulativeTime += dur;\n    }\n    //keyboard\n    @OnMethod(\n        clazz=\"javafx.scene.Scene\",\n        method=\"impl_processKeyEvent\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void onKeyPulseExit(@Duration long dur){\n        kCumulativeTime += dur;\n    }\n    // </fragment>\n\n    //synchronization\n    // <fragment name=\"synCalls\">\n    @OnMethod(\n        clazz=\"javafx.scene.Node\",\n        method=\"impl_updatePG\"\n//I suspect, we should track the calls on scene, but they do not anything\n//    @OnMethod(\n//        clazz=\"javafx.scene.Scene\",\n//        method=\"synchronizePGScene\"\n    )\n    public static void doSynchronizeStart(@Self Object obj){\n        clazzName = name(classOf(obj));//str(obj);\n        syncCalls++;\n    }\n    // </fragment>\n\n    // <fragment name=\"sgTiming\">\n    @OnMethod(\n        clazz=\"javafx.scene.Node\",\n        method=\"impl_updatePG\",\n//I suspect, we should track the calls on scene, but they do not anything\n//    @OnMethod(\n//        clazz=\"javafx.scene.Scene\",\n//        method=\"synchronizePGScene\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void doSynchronizeEnds(@Duration long dur){\n        syncCumulativeTime += dur;\n    }\n    // </fragment>\n\n    // <fragment name=\"sgCss\">\n    //styles\n    @OnMethod(\n        clazz=\"com.sun.stylesheet.StyleManager\",\n        method=\"getStyleHelper\"\n    )\n    public static void styleHelperRequest(@Self Object obj){\n        getStyleHelperCallsLocal++;\n        println(obj);\n        //# of style helper ==> containerMap + defaultContainer\n        //update amount of StyleHelper here?\n        println(((com.sun.stylesheet.StyleManager)obj).$defaultContainer);\n    }\n\n    @OnMethod(\n        clazz=\"com.sun.stylesheet.StyleHelper\",\n        method=\"transitionToState\"\n    )\n    public static void styleHelperTransition(){\n        transitionToStateCallsLocal++;\n    }\n\n    @OnMethod(\n        clazz=\"javafx.scene.Node\",\n        method=\"impl_processCSS\"\n    )\n    public static void processCss(@Self Object object){\n        //println(name(classOf(object)));\n        processCssCountLocal++;\n        if (compareTo(name(classOf(object)), \"javafx.scene.Scene$Root\") == 0)\n            processCssOnRootCountLocal++;\n    }\n    // </fragment>\n\n    @OnMethod(\n        clazz=\"com.sun.embeddedswing.EmbeddedEventQueue\",\n        method=\"dispatchEvent\"\n    )\n    public static void onDispatchEvent(@Self Object object){\n        printFields(object);\n    }\n\n    @OnTimer(1000)\n    public static void calculatePerSecondRates() {\n        // <fragment name=\"metrics\">\n        invalidationRate = invalidations;\n        replacementRate = replacements;\n        invalidations = 0;\n        replacements = 0;\n        // </fragment>\n        // <fragment name=\"objects\">\n        fxObjectCreationRate = fxObjectCountRunning;\n        fxObjectCountRunning = 0;\n        // </fragment>\n\n        // <fragment name=\"fps\">\n        //here we compute FPS related variables\n        if (pulses > 0){\n            averageFPS  = ((1000000000.0 * pulses) / (timeNanos() - startTime));\n            allPulses = pulses;\n        }\n        pulses = 0;\n        startTime = 0L;\n        // </fragment>\n\n        // <fragment name=\"pulseCount\">\n        //key/mouse events\n        keyPulses = kPulses;\n        kPulses = 0;\n\n        mousePulses = mPulses;\n        mPulses = 0;\n        // </fragment>\n\n        // <fragment name=\"pulseTiming\">\n        //key/mouse events\n        keyPulsesCumulativeTime = kCumulativeTime/1000000; //in miliSec\n        kCumulativeTime = 0L;\n\n        mousePulsesCumulativeTime = mCumulativeTime/1000000; //in miliSec\n        mCumulativeTime = 0L;\n        // </fragment>\n\n        // <fragment name=\"sgTiming\">\n        //paint\n        paintCumulativeTime = pCumulativeTime/1000000; //in miliSec\n        pCumulativeTime = 0L;\n\n        //dirty regions\n        dirtyRegionsCumulativeTime = dCumulativeTime/1000000; //in miliSec\n        dCumulativeTime = 0L;\n        // </fragment>\n\n        //synchronization\n        // <fragment name=\"sgTiming\">\n        synchronizationTime = syncCumulativeTime/1000000;\n        syncCumulativeTime = 0L;\n        // </fragment>\n\n        // <fragment name=\"synCall\">\n        synchronizationCalls = syncCalls;\n        syncCalls = 0L;\n        // </fragment>\n\n        // <fragment name=\"sgNode\">\n        //unsafe\n        needsLayout = needsLayoutInternal;\n        needsLayoutInternal = 0;\n        nodeCount = nodeCountInternal != 0 ? nodeCountInternal : nodeCount; //do not reset to zero\n        nodeCountInternal = 0;\n        // </fragment>\n\n        // <fragment name=\"sgCss\">\n        getStyleHelperCalls = getStyleHelperCallsLocal;\n        getStyleHelperCallsLocal = 0;\n        transitionToStateCalls = transitionToStateCallsLocal;\n        transitionToStateCallsLocal = 0;\n        processCssCount = processCssCountLocal;\n        processCssCountLocal = 0;\n        processCssOnRootCount = processCssOnRootCountLocal;\n        processCssOnRootCountLocal = 0;\n        // </fragment>\n    }\n}\n"
  },
  {
    "path": "plugins/tracerjvm/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.tracer.jvm\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.tracer.jvm.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerjvm/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.tracer.jvm/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/modules/tracer/jvm/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/tracer/jvm/Bundle.properties\nOpenIDE-Module-Requires: org.openjdk.btrace.visualvm.tracer.deployer\nOpenIDE-Module-Specification-Version: 2.2\n\n"
  },
  {
    "path": "plugins/tracerjvm/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.tracer.jvm-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerjvm/nbproject/project.properties",
    "content": "javac.source=1.6\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jaroslav Bachorik\n"
  },
  {
    "path": "plugins/tracerjvm/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.tracer.jvm</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer.dynamic</code-name-base>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/tracerjvm/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/tracerjvm/src/org/graalvm/visualvm/modules/tracer/jvm/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Tracer\nOpenIDE-Module-Long-Description=\\\n    Tracer probes to monitor JVM internals: JIT Compiler, GC, NIO Buffers and Java I/O.\\n\\\n    <BR>\\n<BR>\\n<B>Technologies:</B>\\n<BR>\\nJMX, BTrace (optional, see Requirements)\\n<BR>\\n<BR>\\n<B>Requirements:</B>\\n<BR>\\nJava I/O monitoring requires the BTrace Deployer plugin to be installed.\\n\\\n    <BR>\\nNIO Buffers monitoring requires the monitored application to run on JDK 7.\nOpenIDE-Module-Name=Tracer-JVM Probes\nOpenIDE-Module-Short-Description=JVM Internals Tracer Probes\nVisualVM/Tracer/packages/platform_mx.js=Extra JVM Metrics\nVisualVM/Tracer/packages/platformMX=Extra JVM Metrics\nVisualVM/Tracer/packages/platformMX/probes/hotspot_compiler=HotSpot Compiler\nVisualVM/Tracer/packages/platformMX/probes/hotspot_compiler/properties/CpuUsage=CPU Usage\n"
  },
  {
    "path": "plugins/tracerjvm/src/org/graalvm/visualvm/modules/tracer/jvm/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.2//EN\" \"http://www.netbeans.org/dtds/filesystem-1_2.dtd\">\n<filesystem>\n    <folder name=\"VisualVM\">\n        <folder name=\"Tracer\">\n            <folder name=\"packages\">\n                <file name=\"platform_mx.js\" url=\"resources/platform_mx.js\">\n                    <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.modules.tracer.platformjmx.Bundle#VisualVM/Tracer/packages/platform_mx.js\"/>\n                </file>\n            </folder>\n        </folder>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "plugins/tracerjvm/src/org/graalvm/visualvm/modules/tracer/jvm/resources/JavaIOTracer.btrace",
    "content": "package org.openjdk.btrace.visualvm.tracer.jvm.resources;\n\nimport org.openjdk.btrace.core.annotations.*;\nimport static org.openjdk.btrace.core.BTraceUtils.*;\n\n@BTrace(name=\"JavaIOStats\") public class JavaIOTracer {\n    // <fragment name=\"files\">\n    private static long fileWriteBytes = 0;\n    private static long fileReadBytes = 0;\n    @Property volatile private static long fileWriteRate = 0;\n    @Property volatile private static long fileReadRate = 0;\n\n    @OnMethod(\n        clazz=\"/java.io.(FileInputStream|RandomAccessFile)/\",\n        method=\"read\",\n        type=\"int(byte[])\",\n        location=@Location(value=Kind.RETURN)\n    )\n    public static void onRead(@Return int bytes) {\n        fileReadBytes += bytes > -1 ? bytes : 0;\n    }\n\n    @OnMethod(\n        clazz=\"/java.io.(FileInputStream|RandomAccessFile)/\",\n        method=\"read\",\n        type=\"int(byte[], int, int)\",\n        location=@Location(value=Kind.RETURN)\n    )\n    public static void onRead1(@Return int bytes) {\n        fileReadBytes += bytes > -1 ? bytes : 0;\n    }\n\n    @OnMethod(\n        clazz=\"java.io.RandomAccessFile\",\n        method=\"/read(Boolean|Byte|UnsignedByte)/\"\n    )\n    public static void onReadByte() {\n        fileReadBytes++;\n    }\n\n    @OnMethod(\n        clazz=\"java.io.RandomAccessFile\",\n        method=\"/read(Short|UnsignedShort|Char)/\"\n    )\n    public static void onReadWord() {\n        fileReadBytes += 2;\n    }\n\n    @OnMethod(\n        clazz=\"java.io.RandomAccessFile\",\n        method=\"/read(Int|Float)/\"\n    )\n    public static void onReadDWord() {\n        fileReadBytes += 4;\n    }\n\n    @OnMethod(\n        clazz=\"java.io.RandomAccessFile\",\n        method=\"/read(Long|Double)/\"\n    )\n    public static void onReadQWord() {\n        fileReadBytes += 8;\n    }\n\n    @OnMethod(\n        clazz=\"java.io.RandomAccessFile\",\n        method=\"readLine\",\n        location=@Location(value=Kind.RETURN)\n    )\n    public static void onReadLine(@Return String line) {\n        fileReadBytes += length(line);\n    }\n\n    @OnMethod(\n        clazz=\"java.io.RandomAccessFile\",\n        method=\"readUTF\",\n        location=@Location(value=Kind.RETURN)\n    )\n    public static void onReadUTF(@Return String text) {\n        fileReadBytes += (length(text) * 2);\n    }\n\n    @OnMethod(\n        clazz=\"/java.io.(FileOutputStream|RandomAccessFile)/\",\n        method=\"write\"\n    )\n    public static void onWrite1(byte[] data) {\n        fileWriteBytes += data.length;\n    }\n\n    @OnMethod(\n        clazz=\"/java.io.(FileOutputStream|RandomAccessFile)/\",\n        method=\"write\"\n    )\n    public static void onWrite(byte[] data, int offset, int len) {\n        fileWriteBytes += len;\n    }\n\n    @OnMethod(\n        clazz=\"java.io.RandomAccessFile\",\n        method=\"/write(Boolean|Byte|UnsignedByte)/\"\n    )\n    public static void onWriteByte() {\n        fileWriteBytes++;\n    }\n\n    @OnMethod(\n        clazz=\"java.io.RandomAccessFile\",\n        method=\"/write(Short|UnsignedShort|Char)/\"\n    )\n    public static void onWriteWord() {\n        fileWriteBytes += 2;\n    }\n\n    @OnMethod(\n        clazz=\"java.io.RandomAccessFile\",\n        method=\"/write(Int|Float)/\"\n    )\n    public static void onWriteDWord() {\n        fileWriteBytes += 4;\n    }\n\n    @OnMethod(\n        clazz=\"java.io.RandomAccessFile\",\n        method=\"/write(Long|Double)/\"\n    )\n    public static void onWriteQWord() {\n        fileWriteBytes += 8;\n    }\n\n    @OnMethod(\n        clazz=\"java.io.RandomAccessFile\",\n        method=\"writeChars\"\n    )\n    public static void onWriteChars(String txt) {\n        fileWriteBytes += length(txt);\n    }\n\n    @OnMethod(\n        clazz=\"java.io.RandomAccessFile\",\n        method=\"writeUTF\"\n    )\n    public static void onWriteUTF(String txt) {\n        fileWriteBytes += (length(txt) * 2);\n    }\n    // </fragment>\n\n    // <fragment name=\"nio\">\n    private static long nioReadData = 0;\n    @Property volatile private static long nioReadRate = 0;\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"getChar\"\n    )\n    public static void onGetChar() {\n        nioReadData++;\n    }\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"/get(Long|Double)/\"\n    )\n    public static void onRead8() {\n        nioReadData += 8;\n    }\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"/get(Int|Float)/\"\n    )\n    public static void onRead4() {\n        nioReadData += 4;\n    }\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"getShort\"\n    )\n    public static void onGetShort() {\n        nioReadData += 2;\n    }\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"get\"\n    )\n    public static void onGetByte() {\n        nioReadData++;\n    }\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"get\"\n    )\n    public static void onGetByteArr(byte[] data, int offset, int len) {\n        nioReadData += len;\n    }\n\n    private static long nioWriteData = 0;\n    @Property volatile private static long nioWriteRate = 0;\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"putChar\"\n    )\n    public static void onPutChar() {\n        nioWriteData++;\n    }\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"/put(Long|Double)/\"\n    )\n    public static void onPut8() {\n        nioWriteData += 8;\n    }\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"/put(Int|Float)/\"\n    )\n    public static void onPut4() {\n        nioWriteData += 4;\n    }\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"putShort\"\n    )\n    public static void onPutShort() {\n        nioWriteData += 2;\n    }\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"put\",\n        type=\"java.nio.ByteBuffer(byte)\"\n    )\n    public static void onPutByte() {\n        nioWriteData++;\n    }\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"put\",\n        type=\"java.nio.ByteBuffer(byte[])\"\n    )\n    public static void onPutByteArr(byte[] data) {\n        nioWriteData += data.length;\n    }\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"put\",\n        type=\"java.nio.ByteBuffer(byte[], int, int)\"\n    )\n    public static void onPutByteArrLen(byte[] data, int offset, int len) {\n        nioWriteData += len;\n    }\n\n    @OnMethod(\n        clazz=\"+java.nio.ByteBuffer\",\n        method=\"put\",\n        type=\"java.nio.ByteBuffer(java.nio.ByteBuffer)\"\n    )\n    public static void onPutByte(java.nio.ByteBuffer buffer) {\n        int cap = unbox((Integer)get(field(\"java.nio.Buffer\", \"capacity\"), buffer));\n        nioWriteData += cap;\n    }\n    // </fragment>\n\n    @OnTimer(value=1000)\n    public static void calcRates() {\n        // <fragment name=\"files\">\n        fileReadRate = fileReadBytes;\n        fileWriteRate = fileWriteBytes;\n        fileReadBytes = 0;\n        fileWriteBytes = 0;\n        // </fragment>\n\n       // <fragment name=\"nio\">\n       nioReadRate = nioReadData;\n       nioWriteRate = nioWriteData;\n       nioReadData = 0;\n       nioWriteData = 0;\n       // </fragment>\n    }\n}\n"
  },
  {
    "path": "plugins/tracerjvm/src/org/graalvm/visualvm/modules/tracer/jvm/resources/platform_mx.js",
    "content": "/*\n *  Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/* @author Jaroslav Bachorik\n * @author Tomas Hurka\n */\n\nvar scriptPath = \"nbres:/org/graalvm/visualvm/modules/tracer/jvm/resources/JavaIOTracer.btrace\"\nvar btraceDeployerClass;\ntry {\n  btraceDeployerClass = Java.type(\"org.openjdk.btrace.visualvm.tracer.deployer.BTraceDeployer\");\n} catch (e) {\n  btraceDeployerClass = null;\n}\nvar btraceDeployer = btraceDeployerClass ? btraceDeployerClass.instance() : undefined;\n\n\nfunction getGCRunProvider(on) {\n    return function(timestamp) {\n        if (this.delta == undefined) {\n            this.delta = delta(mbeanAttribute(on, \"CollectionCount\"))\n        }\n        if (this.lastTs == undefined) {\n            this.lastTs = timestamp;\n        }\n        var timeDelta = timestamp - this.lastTs;\n        this.lastTs = timestamp;\n        if (timeDelta > 0) {\n            return (this.delta.getValue(timestamp) * 1000) / timeDelta;\n        }\n        return 0;\n    }\n}\n\nfunction getGCRuns() {\n    var metrics = new Array();\n    var gcMbNames = VisualVM.MBeans.listMBeanNames(\"java.lang:type=GarbageCollector,name=*\");\n    if (gcMbNames != undefined) {\n        for(var i in gcMbNames) {\n            var name = gcMbNames[i];\n            name.match(/name=(.*)/);\n            var dispName = RegExp.$1;\n            metrics[metrics.length] = {\n                name: dispName,\n                desc: \"GC runs of \" + dispName + \" GC\",\n                value: getGCRunProvider(name),\n                presenter: {\n                    type: VisualVM.Tracer.Type.discrete,\n                    format: {\n                        getUnits: function(format) {\n                            return \"runs/s\";\n                        }\n                    }\n                }\n            }\n        }\n    }\n    return metrics;\n}\n\nfunction getReclaimedMemoryProvider(on) {\n    var keys = mbeanAttribute(on, \"LastGcInfo\").get(\"memoryUsageBeforeGc\").getKeys();\n    // externalize the indexed values\n    var before = new Array();\n    var after = new Array();\n    for(var pool in keys) {\n        before[pool] = mbeanAttribute(on, \"LastGcInfo\").get(\"memoryUsageBeforeGc\").get(keys[pool]).get(\"used\");\n        after[pool] = mbeanAttribute(on, \"LastGcInfo\").get(\"memoryUsageAfterGc\").get(keys[pool]).get(\"used\");\n    }\n\n    return function(timestamp) {\n        var delta = 0;\n        for(var pool in keys) {\n            var pre = before[pool].getValue(timestamp);\n            var post = after[pool].getValue(timestamp);\n            delta += (pre - post);\n        }\n        return delta;\n    }\n}\n\nfunction getReclaimedMemory() {\n    var props = new Array();\n    var gcMbNames = VisualVM.MBeans.listMBeanNames(\"java.lang:type=GarbageCollector,name=*\");\n    if (gcMbNames != undefined) {\n        for(var i in gcMbNames) {\n            var mbName = gcMbNames[i];\n            mbName.match(/name=(.*)/);\n            var dispName = RegExp.$1;\n\n            props[props.length] = {\n                name: dispName,\n                desc: \"Memory reclaimed during the last run of \" + dispName + \" GC\",\n                value: getReclaimedMemoryProvider(mbName),\n                presenter: {\n                    format: ItemValueFormatter.DEFAULT_BYTES,\n                    type: VisualVM.Tracer.Type.discrete,\n                    fillColor: AUTOCOLOR\n                }\n            }\n        }\n    }\n    return props;\n}\n\nfunction getNIOBufferProperties(attrName, attrPresenter) {\n    var props = new Array();\n    var bufferNames = VisualVM.MBeans.listMBeanNames(\"java.nio:type=BufferPool,name=*\");\n    if (bufferNames != undefined) {\n        for(var i in bufferNames) {\n            var mbName = bufferNames[i];\n            mbName.match(/name=(.*)/);\n            var dispName = RegExp.$1;\n\n            props[props.length] = {\n                name: dispName,\n                value: mbeanAttribute(mbName, attrName),\n                presenter: attrPresenter\n            }\n        }\n    }\n    return props;\n}\n\nfunction isNIOBuffersSupported() {\n    var list = VisualVM.MBeans.listMBeanNames(\"java.nio:type=BufferPool,name=*\");\n    return list != undefined && list.length > 0;\n}\n\nfunction isFileDescriptorSupported() {\n    return mbeanAttribute(\"java.lang:type=OperatingSystem\", \"OpenFileDescriptorCount\").getInfo() != null;\n}\n\nfunction isBTraceAvailable() {\n    return btraceDeployer != undefined;\n}\n\nVisualVM.Tracer.addPackages([{\n    name: \"JIT Compiler\",\n    desc: \"Displays JIT compiler metrics\",\n    icon: \"org/graalvm/visualvm/modules/tracer/jvm/resources/hotspot.gif\",\n    position: 500,\n    probes: [\n        {\n            name: \"JIT Compiler\",\n            desc: \"Monitors the JIT compiler activity\",\n            properties: [\n                {\n                    name: \"Compiler activity\",\n                    desc: \"Monitors relative JIT compiler activity (%)\",\n                    value: function(timestamp) {\n                        if (this.valDelta == undefined) {\n                            this.valDelta = delta(mbeanAttribute(\"java.lang:type=Compilation\", \"TotalCompilationTime\"));\n                        }\n                        if (this.timeDelta == undefined) {\n                            this.timeDelta = delta(new ValueProvider({\n                                getValue: function(timestamp) {\n                                    return timestamp;\n                                }\n                            }));\n                        }\n\n                        var valDiff = this.valDelta.getValue(timestamp);\n                        var timeDiff = this.timeDelta.getValue(timestamp);\n\n                        return timeDiff > 0 ? (valDiff * 1000 / timeDiff) : 0;\n                    },\n                    presenter: {\n                        format: ItemValueFormatter.DEFAULT_PERCENT,\n                        min: 0,\n                        max: 1000 // 1000 = 100.0%\n                    }\n                }\n            ]\n        },\n    ]\n    },\n    {\n        name: \"Garbage Collectors\",\n        desc: \"GC statistics\",\n        position: 510,\n        probes: [\n            {\n                name: \"GC Runs\",\n                desc: \"Shows the average number of runs per second for a particular GC during the last sample period\",\n                properties: getGCRuns()\n            },\n            {\n                name: \"Reclaimed Memory\",\n                desc: \"The amout of memory reclaimed during the last GC run\",\n                properties: getReclaimedMemory()\n            },\n            {\n                name: \"Pending Finalizers Count\",\n                desc: \"The approximate number of objects for which finalization is pending\",\n                properties: [\n                    {\n                        name: \"Pending Finalizers Count\",\n                        value: mbeanAttribute(\"java.lang:type=Memory\", \"ObjectPendingFinalizationCount\"),\n                        presenter: {\n                            lineColor: Color.RED\n                        }\n                    }\n                ]\n            }\n        ]\n    },\n    {\n        name: \"NIO Buffers\",\n        desc: \"NIO buffers metrics\",\n        reqs: \"Requires the target application to run on JDK 7.\",\n        position: 520,\n        validator: isNIOBuffersSupported,\n        probes: [\n            {\n                name: \"Count\",\n                desc: \"Reports number of NIO buffers.\",\n                properties: getNIOBufferProperties(\"Count\")\n            },\n            {\n                name: \"Memory Used\",\n                desc: \"Reports total physical memory used by the NIO buffers.\",\n                properties: getNIOBufferProperties(\"MemoryUsed\", {\n                    format: ItemValueFormatter.DEFAULT_BYTES\n                })\n            },\n            {\n                name: \"Total Capacity\",\n                desc: \"Reports available capacity of the NIO buffers\",\n                properties: getNIOBufferProperties(\"TotalCapacity\", {\n                    format: ItemValueFormatter.DEFAULT_BYTES\n                })\n            }\n        ]\n\n    },\n    {\n        name: \"Java I/O\",\n        desc: \"IO subsystem statistics\",\n        position: 530,\n        probes: [\n            {\n                name: \"File Descriptors\",\n                reqs: \"Not supported on Windows.\",\n                desc: \"Measures number of available and used file descriptors.\",\n                validator: isFileDescriptorSupported,\n                properties: [\n                    {\n                        name: \"Available\",\n                        value: mbeanAttribute(\"java.lang:type=OperatingSystem\", \"MaxFileDescriptorCount\"),\n                        presenter: {\n                            lineColor: Color.RED\n                        }\n                    },\n                    {\n                        name: \"Used\",\n                        value: mbeanAttribute(\"java.lang:type=OperatingSystem\", \"OpenFileDescriptorCount\"),\n                        presenter: {\n                            fillColor: new Color(((80 & 0xFF) << 16) |\n                                                 ((180 & 0xFF) << 8)  |\n                                                 ((250 & 0xFF) << 0))\n                        }\n                    },\n                ]\n            },\n            {\n                name: \"Java Files Utilization\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                desc: \"Measures read/write rates of Java Files.\",\n                validator: isBTraceAvailable,\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"files\"\n                },\n                properties: [\n                    {\n                        name: \"Reading rate\",\n                        value: mbeanAttribute(\"btrace:name=JavaIOStats\", \"fileReadRate\"),\n                        presenter: {\n                            lineColor: Color.GREEN,\n                            format: ItemValueFormatter.DEFAULT_BYTES_PER_SEC\n                        }\n                    },\n                    {\n                        name: \"Writing rate\",\n                        value: mbeanAttribute(\"btrace:name=JavaIOStats\", \"fileWriteRate\"),\n                        presenter: {\n                            lineColor: Color.RED,\n                            format: ItemValueFormatter.DEFAULT_BYTES_PER_SEC\n                        }\n                    }\n                ]\n            },\n            {\n                name: \"NIO Utilization\",\n                desc: \"Measures read/write rates of NIO.\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: scriptPath,\n                    fragment: \"nio\"\n                },\n                properties: [\n                    {\n                        name: \"Reading rate\",\n                        value: mbeanAttribute(\"btrace:name=JavaIOStats\", \"nioReadRate\"),\n                        presenter: {\n                            lineColor: Color.GREEN,\n                            format: ItemValueFormatter.DEFAULT_BYTES_PER_SEC\n                        }\n                    },\n                    {\n                        name: \"Writing rate\",\n                        value: mbeanAttribute(\"btrace:name=JavaIOStats\", \"nioWriteRate\"),\n                        presenter: {\n                            lineColor: Color.RED,\n                            format: ItemValueFormatter.DEFAULT_BYTES_PER_SEC\n                        }\n                    }\n                ]\n            }\n        ]\n    }\n])\n"
  },
  {
    "path": "plugins/tracerjvmstat/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.tracer.jvmstat\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.tracer.jvmstat.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerjvmstat/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.tracer.jvmstat/2\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/tracer/jvmstat/Install.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/tracer/jvmstat/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "plugins/tracerjvmstat/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.tracer.jvmstat-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerjvmstat/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=51f7c3b0\nbuild.xml.script.CRC32=b5cff0b2\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=51f7c3b0\nnbproject/build-impl.xml.script.CRC32=604888e2\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "plugins/tracerjvmstat/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\njavac.source=1.5\ncp.extra=${tools.jar}\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Tomas Hurka\nmodule.javadoc.packages=org.graalvm.visualvm.modules.tracer.jvmstat.*\n"
  },
  {
    "path": "plugins/tracerjvmstat/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.tracer.jvmstat</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/tracerjvmstat/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/tracerjvmstat/src/org/graalvm/visualvm/modules/tracer/jvmstat/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Tracer\nOpenIDE-Module-Long-Description=\\\n    A plugin to add Jvmstat counters as Tracer probes.\\n\\\n    <BR>\\n<BR>\\n<B>Technologies:</B>\\n<BR>\\nJvmstat\nOpenIDE-Module-Name=Tracer-Jvmstat Probes\nOpenIDE-Module-Short-Description=Tracer Jvmstat probes\n\n"
  },
  {
    "path": "plugins/tracerjvmstat/src/org/graalvm/visualvm/modules/tracer/jvmstat/Install.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.jvmstat;\n\nimport org.graalvm.visualvm.modules.tracer.TracerSupport;\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n *\n * @author Tomas Hurka \n */\npublic class Install extends ModuleInstall {\n    \n    private JvmstatCountersPackageProvider provider;\n\n    public synchronized void restored() {\n        if (provider == null) provider = new JvmstatCountersPackageProvider();\n        TracerSupport.getInstance().registerPackageProvider(provider);\n    }\n\n    public synchronized void uninstalled() {\n        if (provider == null) return;\n        TracerSupport.getInstance().unregisterPackageProvider(provider);\n        provider = null;\n    }\n}\n"
  },
  {
    "path": "plugins/tracerjvmstat/src/org/graalvm/visualvm/modules/tracer/jvmstat/JvmstatCounterFormatter.java",
    "content": "/*\n *  Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.jvmstat;\n\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport sun.jvmstat.monitor.Monitor;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JvmstatCounterFormatter extends ItemValueFormatter {\n    static final String Units_STRING = \"String\";  // NOI18N\n    static final String Units_NONE = \"None\";  // NOI18N\n    static final String Units_INVALID = \"Invalid\";  // NOI18N\n    static final String Units_BYTES = \"Bytes\";  // NOI18N\n    static final String Units_EVENTS = \"Events\";    // NOI18N\n    static final String Units_TICKS = \"Ticks\";  // NOI18N\n    \n    private static final Logger LOGGER = Logger.getLogger(JvmstatCounterFormatter.class.getName());\n    private Monitor counter;\n    private ItemValueFormatter del;\n    private String unitsName;\n\n    JvmstatCounterFormatter(Monitor c) {\n        counter = c;\n        unitsName = Utils.getUnits(counter).toString();\n        if (unitsName.equals(Units_BYTES)) {\n            del = ItemValueFormatter.DEFAULT_BYTES;\n        } else if (unitsName.equals(Units_EVENTS)) {\n            del = ItemValueFormatter.DEFAULT_DECIMAL;\n        } else if (unitsName.equals(Units_TICKS)) {\n            \n        }\n    }\n\n    public String formatValue(long l, int i) {\n        if (del != null) {\n            return del.formatValue(l,i);\n        }\n        return String.valueOf(l);\n    }\n\n    public String getUnits(int i) {\n        if (del != null) {\n            return del.getUnits(i);\n        }\n        return unitsName;\n    }\n    \n}\n"
  },
  {
    "path": "plugins/tracerjvmstat/src/org/graalvm/visualvm/modules/tracer/jvmstat/JvmstatCounterProbe.java",
    "content": "/*\n *  Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.jvmstat;\n\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport static org.graalvm.visualvm.modules.tracer.jvmstat.JvmstatCounterFormatter.*;\nimport sun.jvmstat.monitor.Monitor;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JvmstatCounterProbe extends TracerProbe {\n    private static final Logger LOGGER = Logger.getLogger(JvmstatCounterProbe.class.getName());    \n    private static final String Variability_MONOTONIC = \"Monotonic\";    // NOI18N\n\n    private Monitor counter;\n    private long lastVal;\n    private long lastTime;\n    private boolean ticks;\n    \n    JvmstatCounterProbe(String name, String desc, Monitor c) {\n        super(createItemDescriptors(name, desc, c));\n        counter = c;\n        String u = Utils.getUnits(c).toString();\n  \n        ticks = u.equals(Units_TICKS) || (u.equals(Units_EVENTS) && Utils.getVariability(c).toString().equals(Variability_MONOTONIC));\n    }\n    \n    private static final ProbeItemDescriptor[] createItemDescriptors(String name, String desc, Monitor c) {\n        return new ProbeItemDescriptor[] {\n            ProbeItemDescriptor.continuousLineItem(name, desc,\n                    new JvmstatCounterFormatter(c), 1d, 0, ProbeItemDescriptor.MAX_VALUE_UNDEFINED),\n        };\n    }\n    \n    public long[] getItemValues(long time) {\n        try {\n            Object val = counter.getValue();\n            if (val instanceof Number) {\n                Number num = (Number) val;\n                long value = num.longValue();\n                \n                return new long[] {convert(value)};\n            }\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Failed to read UnixOperatingSystemMXBean attributes\", t); // NOI18N\n        }\n        return new long[1]; // ??? should return null -- or -- catch exception in TracerController.fetchDataImpl() \n    }\n\n    private long convert(long value) {\n        if (ticks) {\n            long now = System.currentTimeMillis();\n            long diff = 0;\n            if (lastTime != 0) {\n                diff = 1000 * (value - lastVal) / (now - lastTime);\n            }\n            lastTime = now;\n            lastVal = value;\n            return diff;\n        }\n        return value;\n    }\n    \n}\n"
  },
  {
    "path": "plugins/tracerjvmstat/src/org/graalvm/visualvm/modules/tracer/jvmstat/JvmstatCountersPackage.java",
    "content": "/*\n *  Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.jvmstat;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProgressObject;\nimport org.openide.util.ImageUtilities;\nimport sun.jvmstat.monitor.Monitor;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JvmstatCountersPackage extends TracerPackage.SessionAware<Application> {\n    \n    private static final Icon ICON = new ImageIcon(ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/modules/tracer/jvmstat/resources/jvmstatProbe.png\", true)); // NOI18N\n    private static final String NAME = \"Jvmstat counters\";\n    private static final String DESCR = \"Provides metrics for jvmstat counters.\";\n    private static final int POSITION = 1000;\n    \n    private Map<TracerProbeDescriptor,TracerProbe<Application>> probes;\n    private JvmstatCountersPackages master;\n    \n    JvmstatCountersPackage(JvmstatCountersPackages m, String name, int pos) {\n        super(NAME + \" '\" + name + \"'\", DESCR, ICON, POSITION + pos);\n        probes = new HashMap();\n        master = m;\n    }\n    \n    public TracerProbeDescriptor[] getProbeDescriptors() {\n        return probes.keySet().toArray(new TracerProbeDescriptor[probes.size()]);\n    }\n    \n    public TracerProbe<Application> getProbe(TracerProbeDescriptor descriptor) {\n        return probes.get(descriptor);\n    }\n\n    void addProbe(Monitor monitor, int pos, String probeName) {\n        String descName = \"Counter: \"+monitor.getName()+\", Units: \"+Utils.getUnits(monitor);\n        TracerProbeDescriptor desc = new TracerProbeDescriptor(probeName,descName,ICON,pos,true);\n        probes.put(desc,new JvmstatCounterProbe(probeName, descName, monitor));\n    }\n\n    protected TracerProgressObject sessionInitializing(TracerProbe<Application>[] probes, Application dataSource, int refresh) {\n        master.setInterval(refresh*1000);\n        return null;\n    }\n\n    protected void refreshRateChanged(TracerProbe<Application>[] probes, Application dataSource, int refresh) {\n        master.setInterval(refresh*1000);\n    }\n\n    protected void sessionStopping(TracerProbe<Application>[] probes, Application dataSource) {\n    }\n\n\n}\n"
  },
  {
    "path": "plugins/tracerjvmstat/src/org/graalvm/visualvm/modules/tracer/jvmstat/JvmstatCountersPackageProvider.java",
    "content": "/*\n *  Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.jvmstat;\n\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport org.graalvm.visualvm.modules.tracer.TracerPackageProvider;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JvmstatCountersPackageProvider extends TracerPackageProvider<Application> {\n    \n    private static final Logger LOGGER = Logger.getLogger(JvmstatCountersPackageProvider.class.getName());\n    \n    JvmstatCountersPackageProvider() { super(Application.class); }\n    \n    public TracerPackage<Application>[] getPackages(Application application) {\n        return new JvmstatCountersPackages(application).getPackages();\n    }\n \n}\n"
  },
  {
    "path": "plugins/tracerjvmstat/src/org/graalvm/visualvm/modules/tracer/jvmstat/JvmstatCountersPackages.java",
    "content": "/*\n *  Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.jvmstat;\n\nimport java.net.URISyntaxException;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport static org.graalvm.visualvm.modules.tracer.jvmstat.JvmstatCounterFormatter.*;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory;\nimport sun.jvmstat.monitor.Monitor;\nimport sun.jvmstat.monitor.MonitorException;\nimport sun.jvmstat.monitor.MonitoredHost;\nimport sun.jvmstat.monitor.MonitoredVm;\nimport sun.jvmstat.monitor.VmIdentifier;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JvmstatCountersPackages  {\n    private static final Logger LOGGER = Logger.getLogger(JvmstatCountersPackage.class.getName());\n    private static final String Variability_INVALID = \"Invalid\";    // NOI18N\n    private static final String Variability_CONSTANT = \"Constant\";  // NOI18N\n\n    private Application application;\n    private MonitoredVm monitoredVm;\n    \n    JvmstatCountersPackages(Application app) {\n        application = app;\n        monitoredVm = getMonitoredHost();\n    }\n\n    TracerPackage<Application>[] getPackages() {\n        if (monitoredVm != null) {\n            return computePackages();\n        }\n        return new TracerPackage[0];        \n    }\n    \n    private MonitoredVm getMonitoredHost() {\n        JvmstatModel jvmstat = JvmstatModelFactory.getJvmstatFor(application);\n        if (jvmstat != null) {\n            String connectionId = jvmstat.getConnectionId();\n            try {\n                VmIdentifier vmId = new VmIdentifier(connectionId);\n                MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);\n                return monitoredHost.getMonitoredVm(vmId);\n            } catch (URISyntaxException ex) {\n                LOGGER.log(Level.WARNING,ex.getLocalizedMessage(),ex);\n            } catch (Exception ex) {\n                // MonitoredHostProvider.getMonitoredVm can throw java.lang.Exception on Windows,\n                // when opening shared memory file (java.lang.Exception: Could not open PerfMemory)\n                LOGGER.log(Level.INFO,\"getMonitoredVm failed\",ex);  // NOI18N\n            }\n        }\n        return null;\n    }\n    \n    private TracerPackage<Application>[] computePackages() {\n        List counters;\n        Iterator it;\n        Map<String,JvmstatCountersPackage> packages = new HashMap();\n        \n        try {\n            counters = monitoredVm.findByPattern(\".*\");\n            Collections.sort(counters,new Comparator<Monitor>() {\n                public int compare(Monitor o1, Monitor o2) {\n                    return o1.getName().compareTo(o2.getName());\n                }\n            });\n            it = counters.iterator();\n            for (int i=0;it.hasNext();i++) {\n                Monitor monitor = (Monitor) it.next();\n                String unitsName = Utils.getUnits(monitor).toString();\n                String var = Utils.getVariability(monitor).toString();\n                String name = monitor.getName();\n                String baseName = monitor.getBaseName();\n                \n                if (unitsName.equals(Units_STRING) || unitsName.equals(Units_INVALID) || unitsName.equals(Units_NONE)) {\n                    continue;\n                }\n                if (var.equals(Variability_INVALID) || var.equals(Variability_CONSTANT)) {\n                    continue;\n                }\n                if (monitor.isVector()) {\n                    continue;\n                }\n                getPackage(packages,monitor,i,name);\n             }\n        } catch (MonitorException ex) {\n            LOGGER.log(Level.INFO,\"findByPattern failed\",ex);  // NOI18N\n        }\n        return packages.values().toArray(new TracerPackage[0]);\n    }\n\n    private void getPackage(Map<String,JvmstatCountersPackage> packages, Monitor monitor, int pos, String name) {\n        String pckName;\n        String probeName;\n        JvmstatCountersPackage pck;\n        int dots = 0;\n        int i;\n        \n        for (i = 0; i< name.length(); i++) {\n            char ch = name.charAt(i);\n            if (ch == '.') {\n                dots++;\n                if (dots == 2) {\n                    break;\n                }\n            }    \n        }\n        if (dots == 2) {\n            pckName = name.substring(0,i);\n            probeName = name.substring(i+1);\n            pck = packages.get(pckName);\n            if (pck == null) {\n                pck = new JvmstatCountersPackage(this,pckName,packages.size());\n                packages.put(pckName,pck);\n            }\n            pck.addProbe(monitor,pos,probeName);\n        }\n    }\n\n    void setInterval(int refresh) {\n        monitoredVm.setInterval(refresh);\n//        System.out.println(\"New refresh \"+refresh);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracerjvmstat/src/org/graalvm/visualvm/modules/tracer/jvmstat/Utils.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.jvmstat;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport sun.jvmstat.monitor.Monitor;\n\n\n/**\n * @author Tomas Hurka\n */\nclass Utils {\n    private static Method getVariabilityMethod = getMonitorMethod(\"getVariability\");\n    private static Method getUnitsMethod = getMonitorMethod(\"getUnits\");\n    \n    static Object getVariability(Monitor monitor) {\n        return invokeGetter(monitor, getVariabilityMethod);\n    }\n    \n    static Object getUnits(Monitor monitor) {\n        return invokeGetter(monitor, getUnitsMethod);\n    }\n    \n    private static Object invokeGetter(Monitor monitor, Method method) {\n        try {\n            return method.invoke(monitor);\n        } catch (IllegalArgumentException ex) {\n            throw new RuntimeException(ex);\n        } catch (InvocationTargetException ex) {\n            throw new RuntimeException(ex);\n        } catch (IllegalAccessException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n    \n    private static Method getMonitorMethod(String methodName) {\n        try {\n            return Monitor.class.getDeclaredMethod(methodName);\n        } catch (SecurityException ex) {\n            throw new RuntimeException(ex);\n        } catch (NoSuchMethodException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/tracermonitor/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.tracer.monitor\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.tracer.monitor.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracermonitor/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.tracer.monitor/2\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/tracer/monitor/MonitorPackageProvider.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/tracer/monitor/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "plugins/tracermonitor/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.tracer.monitor-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracermonitor/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jiri Sedlacek\nmodule.javadoc.packages=org.graalvm.visualvm.modules.tracer.monitor.*\n"
  },
  {
    "path": "plugins/tracermonitor/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.tracer.monitor</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.13.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/tracermonitor/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/tracermonitor/src/org/graalvm/visualvm/modules/tracer/monitor/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Tracer\nOpenIDE-Module-Long-Description=\\\n    Set of Tracer probes providing the same metrics as the Monitor tab.\\n\\\n    <BR>\\n<BR>\\n<B>Technologies:</B>\\n<BR>\\nJMX, Jvmstat\nOpenIDE-Module-Name=Tracer-Monitor Probes\nOpenIDE-Module-Short-Description=Monitor probes for Tracer\n"
  },
  {
    "path": "plugins/tracermonitor/src/org/graalvm/visualvm/modules/tracer/monitor/ClassesMonitorProbe.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.monitor;\n\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport javax.swing.Icon;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ClassesMonitorProbe extends MonitorProbe {\n    \n    private static final String NAME = \"Classes\";\n    private static final String DESCR = \"Monitors number of classes loaded by the JVM.\";\n    private static final int POSITION = 40;\n\n\n    ClassesMonitorProbe(MonitoredDataResolver resolver) {\n        super(2, createItemDescriptors(), resolver);\n    }\n\n\n    long[] getValues(MonitoredData data) {\n        long sharedUnloaded = data.getSharedUnloadedClasses();\n        long totalUnloaded  = data.getUnloadedClasses();\n        long sharedClasses  = data.getSharedLoadedClasses() - sharedUnloaded;\n        long totalClasses   = data.getLoadedClasses() - totalUnloaded + sharedClasses;\n        return new long[] {\n            totalClasses,\n            sharedClasses\n        };\n    }\n\n\n    static final TracerProbeDescriptor createDescriptor(Icon icon, boolean available,\n                                                        Jvm jvm) {\n        return new TracerProbeDescriptor(NAME, DESCR, icon, POSITION, available &&\n                                         jvm.isClassMonitoringSupported());\n    }\n    \n    private static final ProbeItemDescriptor[] createItemDescriptors() {\n        return new ProbeItemDescriptor[] {\n            ProbeItemDescriptor.continuousLineItem(\"Total loaded\",\n                    \"Monitors number of all Classes currently loaded by the JVM\",\n                    ItemValueFormatter.DEFAULT_DECIMAL, 1d, 0, 100),\n            ProbeItemDescriptor.continuousLineItem(\"Shared loaded\",\n                    \"Monitors number of shared Classes currently loaded by the JVM\",\n                    ItemValueFormatter.DEFAULT_DECIMAL, 1d, 0, 100)\n        };\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracermonitor/src/org/graalvm/visualvm/modules/tracer/monitor/CpuMonitorProbe.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.monitor;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeansFactory;\nimport java.lang.management.OperatingSystemMXBean;\nimport javax.swing.Icon;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass CpuMonitorProbe extends MonitorProbe {\n    \n    private static final String NAME = \"Cpu & GC\";\n    private static final String DESCR = \"Monitors CPU usage and GC activity.\";\n    private static final int POSITION = 10;\n\n    private final boolean cpuSupported;\n    private final boolean gcSupported;\n    private final int processorsCount;\n\n    private long prevUpTime = -1;\n    private long prevProcessCpuTime = -1;\n    private long prevProcessGcTime = -1;\n\n\n    CpuMonitorProbe(MonitoredDataResolver resolver, Application application,\n                    Jvm jvm) {\n        super(2, createItemDescriptors(), resolver);\n        cpuSupported = jvm.isCpuMonitoringSupported();\n        gcSupported = jvm.isCollectionTimeSupported();\n        int pCount = 1;\n        JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);\n        if (jmxModel != null && jmxModel.getConnectionState() == ConnectionState.CONNECTED) {\n            JvmMXBeans mxbeans = JvmMXBeansFactory.getJvmMXBeans(jmxModel);\n            if (mxbeans != null) {\n                OperatingSystemMXBean osbean = mxbeans.getOperatingSystemMXBean();\n                if (osbean != null) pCount = osbean.getAvailableProcessors();\n            }\n        }\n        processorsCount = pCount;\n    }\n\n\n    long[] getValues(MonitoredData data) {\n        long cpuUsage = -1;\n        long gcUsage = -1;\n         \n        long upTime = data.getUpTime() * 1000000;\n        \n        long processCpuTime = cpuSupported ?\n            data.getProcessCpuTime() / processorsCount : -1;\n        long processGcTime  = gcSupported ?\n            data.getCollectionTime() * 1000000 / processorsCount : -1;\n\n        if (prevUpTime != -1) {\n            long upTimeDiff = upTime - prevUpTime;\n\n            if (cpuSupported && prevProcessCpuTime != -1) {\n                long processTimeDiff = processCpuTime - prevProcessCpuTime;\n                cpuUsage = upTimeDiff > 0 ? Math.min((long)(1000 * (float)processTimeDiff /\n                                                     (float)upTimeDiff), 1000) : 0;\n            }\n\n            if (gcSupported && prevProcessGcTime != -1) {\n                long processGcTimeDiff = processGcTime - prevProcessGcTime;\n                gcUsage = upTimeDiff > 0 ? Math.min((long)(1000 * (float)processGcTimeDiff /\n                                                    (float)upTimeDiff), 1000) : 0;\n                if (cpuUsage != -1 && cpuUsage < gcUsage) gcUsage = cpuUsage;\n            }\n        }\n\n        prevUpTime = upTime;\n        prevProcessCpuTime = processCpuTime;\n        prevProcessGcTime  = processGcTime;\n\n        return new long[] {\n            Math.max(cpuUsage, 0),\n            Math.max(gcUsage, 0)\n        };\n    }\n\n\n    static final TracerProbeDescriptor createDescriptor(Icon icon, boolean available,\n                                                        Jvm jvm) {\n        return new TracerProbeDescriptor(NAME, DESCR, icon, POSITION, available &&\n                                         jvm.isCpuMonitoringSupported() ||\n                                         jvm.isCollectionTimeSupported());\n    }\n    \n    private static final ProbeItemDescriptor[] createItemDescriptors() {\n        return new ProbeItemDescriptor[] {\n            ProbeItemDescriptor.continuousLineItem(\"CPU usage\",\n                    \"Monitors relative CPU usage (%)\",\n                    ItemValueFormatter.DEFAULT_PERCENT, 1d, 0, 1000),\n            ProbeItemDescriptor.continuousLineItem(\"GC activity\",\n                    \"Monitors relative GC activity (%)\",\n                    ItemValueFormatter.DEFAULT_PERCENT, 1d, 0, 1000)\n        };\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracermonitor/src/org/graalvm/visualvm/modules/tracer/monitor/HeapMonitorProbe.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.monitor;\n\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport javax.swing.Icon;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass HeapMonitorProbe extends MonitorProbe {\n    \n    private static final String NAME = \"Heap\";\n    private static final String DESCR = \"Monitors allocated and used Heap size.\";\n    private static final int POSITION = 20;\n\n\n    HeapMonitorProbe(MonitoredDataResolver resolver) {\n        super(2, createItemDescriptors(), resolver);\n    }\n\n\n    long[] getValues(MonitoredData data) {\n        return new long[] {\n            data.getGenCapacity()[0],\n            data.getGenUsed()[0]\n        };\n    }\n\n\n    static final TracerProbeDescriptor createDescriptor(Icon icon, boolean available,\n                                                        Jvm jvm) {\n        return new TracerProbeDescriptor(NAME, DESCR, icon, POSITION, available &&\n                                         jvm.isMemoryMonitoringSupported());\n    }\n    \n    private static final ProbeItemDescriptor[] createItemDescriptors() {\n        return new ProbeItemDescriptor[] {\n            ProbeItemDescriptor.continuousLineFillItem(\"Size\",\n                    \"Monitors current Heap size\", ItemValueFormatter.DEFAULT_BYTES,\n                    1d, 0, 10 * 1024 * 1024),\n            ProbeItemDescriptor.continuousLineFillItem(\"Used\",\n                    \"Monitors currently used Heap\", ItemValueFormatter.DEFAULT_BYTES,\n                    1d, 0, 10 * 1024 * 1024)\n        };\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracermonitor/src/org/graalvm/visualvm/modules/tracer/monitor/MonitorPackage.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.monitor;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass MonitorPackage extends TracerPackage<Application> implements MonitorProbe.MonitoredDataResolver {\n\n    static final Icon ICON = new ImageIcon(ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/modules/tracer/monitor/resources/monitor.png\", true)); // NOI18N\n    private static final String NAME = \"Basic JVM Metrics\";\n    private static final String DESCR = \"Provides the same basic JVM metrics as the Monitor tab.\";\n    private static final int POSITION = 50;\n\n    private TracerProbeDescriptor cpuProbeDescriptor;\n    private TracerProbeDescriptor heapProbeDescriptor;\n    private TracerProbeDescriptor permgenProbeDescriptor;\n    private TracerProbeDescriptor classesProbeDescriptor;\n    private TracerProbeDescriptor threadsProbeDescriptor;\n    private MonitorProbe cpuProbe;\n    private MonitorProbe heapProbe;\n    private MonitorProbe permgenProbe;\n    private MonitorProbe classesProbe;\n    private MonitorProbe threadsProbe;\n\n    private final Application application;\n    private final Jvm jvm;\n\n    private long lastTimestamp = -1;\n    private MonitoredData lastMonitoredData;\n\n\n    MonitorPackage(Application application) {\n        super(NAME, DESCR, ICON, POSITION);\n        this.application = application;\n        this.jvm = JvmFactory.getJVMFor(application);\n    }\n\n\n    public TracerProbeDescriptor[] getProbeDescriptors() {\n        boolean available = jvm != null && jvm.isMonitoringSupported();\n        cpuProbeDescriptor = CpuMonitorProbe.createDescriptor(ICON, available, jvm);\n        heapProbeDescriptor = HeapMonitorProbe.createDescriptor(ICON, available, jvm);\n        permgenProbeDescriptor = PermgenMonitorProbe.createDescriptor(ICON, available, jvm);\n        classesProbeDescriptor = ClassesMonitorProbe.createDescriptor(ICON, available, jvm);\n        threadsProbeDescriptor = ThreadsMonitorProbe.createDescriptor(ICON, available, jvm);\n        return new TracerProbeDescriptor[] { cpuProbeDescriptor,\n                                             heapProbeDescriptor,\n                                             permgenProbeDescriptor,\n                                             classesProbeDescriptor,\n                                             threadsProbeDescriptor};\n    }\n\n    public TracerProbe<Application> getProbe(TracerProbeDescriptor descriptor) {\n        if (descriptor == cpuProbeDescriptor) {\n            if (cpuProbe == null)\n                cpuProbe = new CpuMonitorProbe(this, application, jvm);\n            return cpuProbe;\n        } else if (descriptor == heapProbeDescriptor) {\n            if (heapProbe == null)\n                heapProbe = new HeapMonitorProbe(this);\n            return heapProbe;\n        } else if (descriptor == permgenProbeDescriptor) {\n            if (permgenProbe == null)\n                permgenProbe = new PermgenMonitorProbe(this);\n            return permgenProbe;\n        } else if (descriptor == classesProbeDescriptor) {\n            if (classesProbe == null)\n                classesProbe = new ClassesMonitorProbe(this);\n            return classesProbe;\n        } else if (descriptor == threadsProbeDescriptor) {\n            if (threadsProbe == null)\n                threadsProbe = new ThreadsMonitorProbe(this);\n            return threadsProbe;\n        } else {\n            return null;\n        }\n    }\n\n    public MonitoredData getMonitoredData(long timestamp) {\n        // TODO: validity may be extended to some timeslot (~100ms)\n        if (lastTimestamp != timestamp) {\n            lastMonitoredData = jvm.getMonitoredData();\n            lastTimestamp = timestamp;\n        }\n        return lastMonitoredData;\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracermonitor/src/org/graalvm/visualvm/modules/tracer/monitor/MonitorPackageProvider.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.monitor;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.modules.tracer.TracerPackage;\nimport org.graalvm.visualvm.modules.tracer.TracerPackageProvider;\nimport org.graalvm.visualvm.modules.tracer.TracerSupport;\nimport org.openide.modules.ModuleInstall;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass MonitorPackageProvider extends ModuleInstall {\n\n    private Impl provider;\n\n\n    public synchronized void restored() {\n        if (provider == null) provider = new Impl();\n        TracerSupport.getInstance().registerPackageProvider(provider);\n    }\n\n    public synchronized void uninstalled() {\n        if (provider == null) return;\n        TracerSupport.getInstance().unregisterPackageProvider(provider);\n        provider = null;\n    }\n\n\n    private static class Impl extends TracerPackageProvider<Application> {\n\n        Impl() { super(Application.class); }\n\n        public TracerPackage<Application>[] getPackages(Application application) {\n            return new MonitorPackage[] { new MonitorPackage(application) };\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracermonitor/src/org/graalvm/visualvm/modules/tracer/monitor/MonitorProbe.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.modules.tracer.monitor;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProbe;\nimport java.util.Arrays;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class MonitorProbe extends TracerProbe<Application> {\n\n    private final MonitoredDataResolver resolver;\n\n    private final int valuesCount;\n\n\n    MonitorProbe(int valuesCount, ProbeItemDescriptor[] itemDescriptors,\n                 MonitoredDataResolver resolver) {\n        super(itemDescriptors);\n        this.valuesCount = valuesCount;\n        this.resolver = resolver;\n    }\n\n\n    public synchronized final long[] getItemValues(long timestamp) {\n        MonitoredData data = resolver.getMonitoredData(timestamp);\n        if (data != null) return getValues(data);\n        \n        long[] noData = new long[valuesCount];\n        Arrays.fill(noData, ProbeItemDescriptor.VALUE_UNDEFINED);\n        return noData;\n    }\n\n    abstract long[] getValues(MonitoredData data);\n\n\n    static interface MonitoredDataResolver {\n        public MonitoredData getMonitoredData(long timestamp);\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracermonitor/src/org/graalvm/visualvm/modules/tracer/monitor/PermgenMonitorProbe.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.monitor;\n\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport javax.swing.Icon;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass PermgenMonitorProbe extends MonitorProbe {\n    \n    private static final String NAME = \"PermGen\";\n    private static final String DESCR = \"Monitors allocated and used PermGen size.\";\n    private static final int POSITION = 30;\n\n\n    PermgenMonitorProbe(MonitoredDataResolver resolver) {\n        super(2, createItemDescriptors(), resolver);\n    }\n\n\n    long[] getValues(MonitoredData data) {\n        return new long[] {\n            data.getGenCapacity()[1],\n            data.getGenUsed()[1]\n        };\n    }\n\n\n    static final TracerProbeDescriptor createDescriptor(Icon icon, boolean available,\n                                                        Jvm jvm) {\n        return new TracerProbeDescriptor(NAME, DESCR, icon, POSITION, available &&\n                                         jvm.isMemoryMonitoringSupported());\n    }\n    \n    private static final ProbeItemDescriptor[] createItemDescriptors() {\n        return new ProbeItemDescriptor[] {\n            ProbeItemDescriptor.continuousLineFillItem(\"Size\",\n                    \"Monitors current PermGen size\", ItemValueFormatter.DEFAULT_BYTES,\n                    1d, 0, 10 * 1024 * 1024),\n            ProbeItemDescriptor.continuousLineFillItem(\"Used\",\n                    \"Monitors currently used PermGen\", ItemValueFormatter.DEFAULT_BYTES,\n                    1d, 0, 10 * 1024 * 1024)\n        };\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracermonitor/src/org/graalvm/visualvm/modules/tracer/monitor/ThreadsMonitorProbe.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.modules.tracer.monitor;\n\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.modules.tracer.ItemValueFormatter;\nimport org.graalvm.visualvm.modules.tracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.modules.tracer.TracerProbeDescriptor;\nimport javax.swing.Icon;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ThreadsMonitorProbe extends MonitorProbe {\n    \n    private static final String NAME = \"Threads\";\n    private static final String DESCR = \"Monitors number of threads running in the JVM.\";\n    private static final int POSITION = 50;\n\n\n    ThreadsMonitorProbe(MonitoredDataResolver resolver) {\n        super(2, createItemDescriptors(), resolver);\n    }\n\n\n    long[] getValues(MonitoredData data) {\n        return new long[] {\n            data.getThreadsLive(),\n            data.getThreadsDaemon()\n        };\n    }\n\n\n    static final TracerProbeDescriptor createDescriptor(Icon icon, boolean available,\n                                                        Jvm jvm) {\n        return new TracerProbeDescriptor(NAME, DESCR, icon, POSITION, available &&\n                                         jvm.isThreadMonitoringSupported());\n    }\n    \n    private static final ProbeItemDescriptor[] createItemDescriptors() {\n        return new ProbeItemDescriptor[] {\n            ProbeItemDescriptor.discreteLineItem(\"Live\",\n                    \"Monitors total number of live Threads in the JVM\",\n                    ItemValueFormatter.DEFAULT_DECIMAL, 1d, 0, 3),\n            ProbeItemDescriptor.discreteLineItem(\"Daemon\",\n                    \"Monitors number of live daemon Threads in the JVM\",\n                    ItemValueFormatter.DEFAULT_DECIMAL, 1d, 0, 3)\n        };\n    }\n\n}\n"
  },
  {
    "path": "plugins/tracerswing/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.tracer.swing\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.tracer.swing.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerswing/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: true\nOpenIDE-Module: org.graalvm.visualvm.modules.tracer.swing/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/modules/tracer/swing/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/tracer/swing/Bundle.properties\nOpenIDE-Module-Requires: org.openjdk.btrace.visualvm.tracer.deployer\nOpenIDE-Module-Specification-Version: 2.2\n\n"
  },
  {
    "path": "plugins/tracerswing/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.tracer.swing-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "plugins/tracerswing/nbproject/project.properties",
    "content": "javac.source=1.6\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jaroslav Bachorik\n"
  },
  {
    "path": "plugins/tracerswing/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.tracer.swing</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.tracer.dynamic</code-name-base>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "plugins/tracerswing/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "plugins/tracerswing/src/org/graalvm/visualvm/modules/tracer/swing/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Tracer\nOpenIDE-Module-Long-Description=\\\n    Tracer probes to monitor the Swing and AWT frameworks.\\n\\\n    <BR>\\n<BR>\\n<B>Technologies:</B>\\n<BR>\\nJMX, BTrace\\n<BR>\\n<BR>\\n<B>Requirements:</B>\\n<BR>\\nThis plugin requires the BTrace Deployer plugin to be installed.\nOpenIDE-Module-Name=Tracer-Swing Probes\nOpenIDE-Module-Short-Description=Swing Tracer Probes\n"
  },
  {
    "path": "plugins/tracerswing/src/org/graalvm/visualvm/modules/tracer/swing/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.2//EN\" \"http://www.netbeans.org/dtds/filesystem-1_2.dtd\">\n<filesystem>\n    <folder name=\"VisualVM\">\n        <folder name=\"Tracer\">\n            <folder name=\"packages\">\n                <file name=\"swing_traces.js\" url=\"resources/swing_traces.js\">\n                    <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.modules.tracer.platformjmx.Bundle#VisualVM/Tracer/packages/platform_mx.js\"/>\n                </file>\n            </folder>\n        </folder>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "plugins/tracerswing/src/org/graalvm/visualvm/modules/tracer/swing/resources/AWTTracer.btrace",
    "content": "package org.openjdk.btrace.visualvm.tracer.swing.resources;\n\nimport org.openjdk.btrace.core.Profiler;\nimport org.openjdk.btrace.core.annotations.*;\nimport static org.openjdk.btrace.core.BTraceUtils.*;\n\n@BTrace(name=\"AWTStats\") public class AWTTracer {\n    private static long lastTimeStamp = -1L;\n    // <fragment name=\"edt_counts\">\n    private static long cntDispatchEvent = 0;\n    private static long cntInvokeWait = 0;\n    private static long cntInvokeLater = 0;\n\n    @Property volatile private static long dispatchEventCount = 0;\n    @Property volatile private static long invokeWaitCount = 0;\n    @Property volatile private static long invokeLaterCount = 0;\n\n    @OnMethod(\n        clazz=\"java.awt.EventQueue\",\n        method=\"/(dispatchEvent|invokeAndWait|invokeLater)/\"\n    )\n    public static void eqCountHandler(@ProbeMethodName String pmn) {\n        if (startsWith(pmn, \"dispatchEvent\")) {\n            cntDispatchEvent++;\n        } else if (startsWith(pmn, \"invokeAndWait\")) {\n            cntInvokeWait++;\n        } else if (startsWith(pmn, \"invokeLater\")) {\n            cntInvokeLater++;\n        }\n    }\n    // </fragment>\n\n    // <fragment name=\"edt_times\">\n    @Property volatile private static int dispatchEventTime = 0;\n    @Property volatile private static int invokeWaitTime = 0;\n\n    private static long tmrDispatchEvent = 0;\n    private static long tmrInvokeWait = 0;\n\n    @OnMethod(\n        clazz=\"java.awt.EventQueue\",\n        method=\"/(dispatchEvent|invokeAndWait)/\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void eqTimerHandler(@Duration long time, @ProbeMethodName String pmn) {\n        if (startsWith(pmn, \"dispatchEvent\")) {\n            tmrDispatchEvent += time;\n        } else if (startsWith(pmn, \"invokeAndWait\")) {\n            tmrInvokeWait += time;\n        }\n    }\n    // </fragment>\n\n    // <fragment name=\"awt_paint\">\n    @Property(name=\"awtPaintProfiler\") private static Profiler awtPaintProfiler = Profiling.newProfiler(3);\n\n    @OnMethod(\n        clazz=\"+java.awt.Component\",\n        method=\"/(paint|update|repaint)/\"\n    )\n    public static void componentPaintBefore(@ProbeMethodName String pmn) {\n        Profiling.recordEntry(awtPaintProfiler, pmn);\n    }\n\n    @OnMethod(\n        clazz=\"+java.awt.Component\",\n        method=\"/(paint|update|repaint)/\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void componentPaintAfter(@Duration long time, @ProbeMethodName String pmn) {\n        Profiling.recordExit(awtPaintProfiler, pmn, time);\n    }\n    // </fragment>\n\n    // <fragment name=\"utilization\">\n    private static long timeInEDT = 0;\n    private static long timeInPaint = 0;\n    private static long timeInLayout = 0;\n\n    @Property volatile private static int dispatch = 0;\n    @Property volatile private static int paint = 0;\n    @Property volatile private static int layout = 0;\n\n    @TLS private static int handlerDepth = 0;\n\n    @OnMethod(\n        clazz=\"java.awt.EventQueue\",\n        method=\"dispatchEvent\"\n    )\n    public static void onDispatchEnter() {\n        handlerDepth++;\n    }\n\n    @OnMethod(\n        clazz=\"java.awt.EventQueue\",\n        method=\"dispatchEvent\",\n        location=@Location(value=Kind.RETURN)\n    )\n    public static void onDispatchExit(@Duration long time) {\n        if (--handlerDepth == 0) {\n            timeInEDT += time;\n        }\n    }\n\n    @OnMethod(\n        clazz=\"javax.swing.RepaintManager\",\n        method=\"paint\",\n        location=@Location(value=Kind.RETURN)\n    )\n    public static void onPaint(@Duration long time) {\n        timeInPaint += time;\n    }\n\n    @OnMethod(\n        clazz=\"+java.awt.LayoutManager\",\n        method=\"layoutContainer\",\n        location=@Location(value=Kind.RETURN)\n    )\n    public static void onLayout(@Duration long time) {\n        timeInLayout += time;\n    }\n    // </fragment>\n\n    @OnTimer(value=1000)\n    public static void calcRates() {\n        // <fragment name=\"utilization\">\n        long inLayout = timeInLayout;\n        long inPaint = timeInPaint;\n        long edt = timeInEDT;\n        timeInLayout = 0;\n        timeInPaint = 0;\n        timeInEDT = 0;\n        // </fragment>\n        // <fragment name=\"edt_times\">\n        long tmpDispatchEvent = tmrDispatchEvent;\n        long tmpInvokeWait = tmrInvokeWait;\n        tmrDispatchEvent = 0;\n        tmrInvokeWait = 0;\n\n        // </fragment>\n        // <fragment name=\"edt_counts\">\n        dispatchEventCount = cntDispatchEvent;\n        invokeWaitCount = cntInvokeWait;\n        invokeLaterCount = cntInvokeLater;\n        cntDispatchEvent = 0;\n        cntInvokeLater = 0;\n        cntInvokeWait = 0;\n        // </fragment>\n        // <fragment name=\"awt_paint\">\n        Profiling.snapshotAndReset(awtPaintProfiler);\n        // </fragment>\n\n        long timeStamp = timeMillis();\n        long span = lastTimeStamp > -1 ? timeStamp - lastTimeStamp : 1000;\n        lastTimeStamp = timeStamp;\n\n        long divider = span * 1000L; // nanoseconds in 1 millisecond * 100 (as %)\n\n        // <fragment name=\"edt_times\">\n        dispatchEventTime = (int)(tmpDispatchEvent / divider);\n        invokeWaitTime = (int)(tmpInvokeWait / divider);\n        // </fragment>\n\n        // <fragment name=\"utilization\">\n        dispatch = (int)(edt / divider);\n        paint = (int)(inPaint / divider);\n        layout = (int)(inLayout / divider);\n        // </fragment>\n    }\n}\n"
  },
  {
    "path": "plugins/tracerswing/src/org/graalvm/visualvm/modules/tracer/swing/resources/SwingTracer.btrace",
    "content": "package org.graalvm.visualvm.modules.tracer.swing.resources;\n\nimport org.openjdk.btrace.core.Profiler;\nimport org.openjdk.btrace.core.annotations.*;\nimport static org.openjdk.btrace.core.BTraceUtils.*;\n\n@BTrace(name=\"SwingStats\") public class SwingTracer {\n    // <fragment name=\"swing_paint\">\n    @Property(name=\"jcPaintProfiler\") private static Profiler jcPaintProfiler = Profiling.newProfiler(3);\n\n    @OnMethod(\n        clazz=\"+javax.swing.JComponent\",\n        method=\"/paint(Component|Border|Children)/\"\n    )\n    public static void componentPaintBefore(@ProbeMethodName String pmn) {\n        Profiling.recordEntry(jcPaintProfiler, pmn);\n    }\n\n    @OnMethod(\n        clazz=\"+javax.swing.JComponent\",\n        method=\"/paint(Component|Border|Children)/\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void componentPaintAfter(@Duration long time, @ProbeMethodName String pmn) {\n        Profiling.recordExit(jcPaintProfiler, pmn, time);\n    }\n    // </fragment>\n\n    // <fragment name=\"componentui\">\n    @Property(name=\"cuiProfiler\") private static Profiler cuiProfiler = Profiling.newProfiler(5);\n    @OnMethod(\n        clazz=\"+javax.swing.plaf.ComponentUI\",\n        method=\"/(paint|update|getPreferredSize|getMinimumSize|getMaximumSize)/\")\n    public static void cuPaintEntry(@ProbeMethodName String pmn) {\n        Profiling.recordEntry(cuiProfiler, pmn);\n    }\n\n    @OnMethod(\n        clazz=\"+javax.swing.plaf.ComponentUI\",\n        method=\"/(paint|update|getPreferredSize|getMinimumSize|getMaximumSize)/\",\n        location=@Location(Kind.RETURN))\n    public static void cuPaintExit(@Duration long time, @ProbeMethodName String pmn) {\n        Profiling.recordExit(cuiProfiler, pmn, time);\n    }\n    // </fragment>\n\n    // <fragment name=\"component_events\">\n    @Property(name=\"jcEventsProfiler\") private static Profiler jcEventsProfiler = Profiling.newProfiler(10);\n\n    @OnMethod(\n        clazz=\"+java.awt.Component\",\n        method=\"/process(Component|Focus|Key|Mouse|MouseMotion|MouseWheel|InputMethod|Hierarchy)Event/\"\n    )\n    public static void componentEventBefore(@ProbeMethodName String pmn) {\n        Profiling.recordEntry(jcEventsProfiler, pmn);\n    }\n\n    @OnMethod(\n        clazz=\"+java.awt.Component\",\n        method=\"/process(Component|Focus|Key|Mouse|MouseMotion|MouseWheel|InputMethod|Hierarchy)Event/\",\n        location=@Location(Kind.RETURN)\n    )\n    public static void componentEventsAfter(@Duration long time, @ProbeMethodName String pmn) {\n        Profiling.recordExit(jcEventsProfiler, pmn, time);\n    }\n    // </fragment>\n\n    // <fragment name=\"basic_events\">\n    @Property(name=\"eventsProfiler\") private static Profiler eventsProfiler = Profiling.newProfiler(3);\n    @OnMethod(\n        clazz=\"+java.awt.event.ActionListener\",\n        method=\"actionPerformed\")\n    public static void apEntry(@ProbeMethodName String pmn) {\n        Profiling.recordEntry(eventsProfiler, pmn);\n    }\n\n    @OnMethod(\n        clazz=\"+java.awt.event.ActionListener\",\n        method=\"actionPerformed\",\n        location=@Location(Kind.RETURN))\n    public static void apExit(@Duration long time, @ProbeMethodName String pmn) {\n        Profiling.recordExit(eventsProfiler, pmn, time);\n    }\n\n    @OnMethod(\n        clazz=\"+javax.swing.event.ChangeListener\",\n        method=\"stateChanged\")\n    public static void scEntry(@ProbeMethodName String pmn) {\n        Profiling.recordEntry(eventsProfiler, pmn);\n    }\n\n    @OnMethod(\n        clazz=\"+javax.swing.event.ChangeListener\",\n        method=\"stateChanged\",\n        location=@Location(Kind.RETURN))\n    public static void scExit(@Duration long time, @ProbeMethodName String pmn) {\n        Profiling.recordExit(eventsProfiler, pmn, time);\n    }\n\n    @OnMethod(\n        clazz=\"+java.beans.PropertyChangeListener\",\n        method=\"propertyChange\")\n    public static void pcEntry(@ProbeMethodName String pmn) {\n        Profiling.recordEntry(eventsProfiler, pmn);\n    }\n\n    @OnMethod(\n        clazz=\"+java.beans.PropertyChangeListener\",\n        method=\"propertyChange\",\n        location=@Location(Kind.RETURN))\n    public static void pcExit(@Duration long time, @ProbeMethodName String pmn) {\n        Profiling.recordExit(eventsProfiler, pmn, time);\n    }\n    // </fragment>\n\n    // <fragment name=\"layout\">\n    @Property(name=\"layoutProfiler\") private static Profiler layoutProfiler = Profiling.newProfiler(3);\n    @OnMethod(\n        clazz=\"+java.awt.LayoutManager\",\n        method=\"/(preferredLayoutSize|minimumLayoutSize|layoutContainer)/\")\n    public static void layoutEntry(@ProbeMethodName String pmn) {\n        Profiling.recordEntry(layoutProfiler, pmn);\n    }\n\n    @OnMethod(\n        clazz=\"+java.awt.LayoutManager\",\n        method=\"/(preferredLayoutSize|minimumLayoutSize|layoutContainer)/\",\n        location=@Location(Kind.RETURN))\n    public static void layoutExit(@Duration long time, @ProbeMethodName String pmn) {\n        Profiling.recordExit(layoutProfiler, pmn, time);\n    }\n    // </fragment>\n\n    @OnTimer(1000)\n    public static void updateMBeans() {\n        // <fragment name=\"swing_paint\">\n        Profiling.snapshotAndReset(jcPaintProfiler);\n        // </fragment>\n\n        // <fragment name=\"componentui\">\n        Profiling.snapshotAndReset(cuiProfiler);\n        // </fragment>\n\n        // <fragment name=\"component_events\">\n        Profiling.snapshotAndReset(jcEventsProfiler);\n        // </fragment>\n\n        // <fragment name=\"basic_events\">\n        Profiling.snapshotAndReset(eventsProfiler);\n        // </fragment>\n\n        // <fragment name=\"layout\">\n        Profiling.snapshotAndReset(layoutProfiler);\n        // </fragment>\n    }\n}\n"
  },
  {
    "path": "plugins/tracerswing/src/org/graalvm/visualvm/modules/tracer/swing/resources/swing_traces.js",
    "content": "/*\n *  Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\nvar awtScriptPath = \"nbres:/org/graalvm/visualvm/modules/tracer/swing/resources/AWTTracer.btrace\"\nvar swingScriptPath = \"nbres:/org/graalvm/visualvm/modules/tracer/swing/resources/SwingTracer.btrace\"\nvar btraceDeployerClass;\ntry {\n  btraceDeployerClass = Java.type(\"org.openjdk.btrace.visualvm.tracer.deployer.BTraceDeployer\");\n} catch (e) {\n  btraceDeployerClass = null;\n}\nvar btraceDeployer = btraceDeployerClass ? btraceDeployerClass.instance() : undefined;\n\nfunction SelfTimePercentAcc(mbean, blockName) {\n    var valAcc = mbean.get(\"data\").get(blockName).get(\"selfTime.percent\");\n    this.value = function (ts) {\n        var val = valAcc.getValue(ts);\n        return  val * 10;\n    }\n}\n\nfunction selfTimePercent(mbean, blockName) {\n    return new SelfTimePercentAcc(mbean, blockName).value;\n}\n\nfunction invocations(mbean, blockName) {\n    return mbean.get(\"data\").get(blockName).get(\"invocations\");\n}\n\nVisualVM.Tracer.addPackages([{\n        name: \"Swing & AWT\",\n        desc: \"Swing & AWT subsystem statistics\",\n        icon: \"org/graalvm/visualvm/modules/tracer/swing/resources/icon.png\",\n        position: 540,\n        probes: [\n            {\n                name: \"EventQueue Calls Count\",\n                desc: \"Invocations count of EventQueue.dispatchEvent(), EventQueue.invokeAndWait(), EventQueue.invokeLater().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: awtScriptPath,\n                    fragment: \"edt_counts\"\n                },\n                properties: [\n                    {\n                        name: \"dispatchEvent\",\n                        desc: \"Invocations count of EventQueue.dispatchEvent().\",\n                        value: mbeanAttribute(\"btrace:name=AWTStats\", \"dispatchEventCount\")\n                    },\n                    {\n                        name: \"invokeAndWait\",\n                        desc: \"Invocations count EventQueue.invokeAndWait().\",\n                        value: mbeanAttribute(\"btrace:name=AWTStats\", \"invokeWaitCount\")\n                    },\n                    {\n                        name: \"invokeLater\",\n                        desc: \"Invocations count of EventQueue.invokeLater().\",\n                        value: mbeanAttribute(\"btrace:name=AWTStats\", \"invokeLaterCount\")\n                    }\n                ]\n            },\n            {\n                name: \"EventQueue Calls Time\",\n                desc: \"Relative time spent in EventQueue.dispatchEvent(), EventQueue.invokeAndWait().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: awtScriptPath,\n                    fragment: \"edt_times\"\n                },\n                properties: [\n                    {\n                        name: \"dispatchEvent\",\n                        desc: \"Relative time spent in EventQueue.dispatchEvent().\",\n                        value: mbeanAttribute(\"btrace:name=AWTStats\", \"dispatchEventTime\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"invokeAndWait\",\n                        desc: \"Relative time spent in EventQueue.invokeAndWait().\",\n                        value: mbeanAttribute(\"btrace:name=AWTStats\", \"invokeWaitTime\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    }\n                ]\n            },\n            awt_paints_count = {\n                name: \"Component Paints Count\",\n                desc: \"Invocations count of Component.paint(), Component.update(), Component.repaint().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: awtScriptPath,\n                    fragment: \"awt_paint\"\n                },\n                properties: [\n                    {\n                        name: \"paint\",\n                        desc: \"Invocations count of Component.paint().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=AWTStats\", \"awtPaintProfiler\"), \"paint\")\n\n                    },\n                    {\n                        name: \"update\",\n                        desc: \"Invocations count of Component.update().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=AWTStats\", \"awtPaintProfiler\"), \"update\")\n                    },\n                    {\n                        name: \"repaint\",\n                        desc: \"Invocations count of Component.repaint().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=AWTStats\", \"awtPaintProfiler\"), \"repaint\")\n                    }\n                ]\n            },\n            awt_paints_time = {\n                name: \"Component Paints Time\",\n                desc: \"Relative time spent in Component.paint(), Component.update().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: awtScriptPath,\n                    fragment: \"awt_paint\"\n                },\n                properties: [\n                    {\n                        name: \"paint\",\n                        desc: \"Relative time spent in Component.paint().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=AWTStats\", \"awtPaintProfiler\"), \"paint\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"update\",\n                        desc: \"Relative time spent in Component.update().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=AWTStats\", \"awtPaintProfiler\"), \"update\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    }\n                ]\n            },\n            jc_paints_count = {\n                name: \"JComponent Paints Count\",\n                desc: \"Invocations count of JComponent.paintComponent(), JComponent.paintBorder(), JComponent.paintChildren().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: swingScriptPath,\n                    fragment: \"swing_paint\"\n                },\n                properties: [\n                    {\n                        name: \"paintComponent\",\n                        desc: \"Invocations count of JComponent.paintComponent().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"jcPaintProfiler\"), \"paintComponent\")\n                    },\n                    {\n                        name: \"paintBorder\",\n                        desc: \"Invocations count of JComponent.paintBorder().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"jcPaintProfiler\"), \"paintBorder\")\n                    },\n                    {\n                        name: \"paintChildren\",\n                        desc: \"Invocations count of JComponent.paintChildren().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"jcPaintProfiler\"), \"paintChildren\")\n                    }\n                ]\n            },\n            jc_paints_time = {\n                name: \"JComponent Paints Time\",\n                desc: \"Relative time spent in JComponent.paintComponent(), JComponent.paintBorder(), JComponent.paintChildren().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: swingScriptPath,\n                    fragment: \"swing_paint\"\n                },\n                properties: [\n                    {\n                        name: \"paintComponent\",\n                        desc: \"Relative time spent in JComponent.paintComponent().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"jcPaintProfiler\"), \"paintComponent\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"paintBorder\",\n                        desc: \"Relative time spent in JComponent.paintBorder().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"jcPaintProfiler\"), \"paintBorder\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"paintChildren\",\n                        desc: \"Relative time spent in JComponent.paintChildren().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"jcPaintProfiler\"), \"paintChildren\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    }\n                ]\n            },\n            cu_paints_time = {\n                name: \"ComponentUI Paints Time\",\n                desc: \"Relative time spent in ComponentUI.paint(), ComponentUI.update().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: swingScriptPath,\n                    fragment: \"componentui\"\n                },\n                properties: [\n                    {\n                        name: \"paint\",\n                        desc: \"Relative time spent in ComponentUI.paint().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"cuiProfiler\"), \"paint\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"update\",\n                        desc: \"Relative time spent in ComponentUI.update().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"cuiProfiler\"), \"update\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    }\n                ]\n            },\n            cu_layouts_time = {\n                name: \"ComponentUI Layouts Time\",\n                desc: \"Relative time spent in ComponentUI.getPreferredSize(), ComponentUI.getMinimumSize(), ComponentUI.getMaximumSize().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: swingScriptPath,\n                    fragment: \"componentui\"\n                },\n                properties: [\n                    {\n                        name: \"getPreferredSize\",\n                        desc: \"Relative time spent in ComponentUI.getPreferredSize().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"cuiProfiler\"), \"getPreferredSize\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"getMinimumSize\",\n                        desc: \"Relative time spent in ComponentUI.getMinimumSize().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"cuiProfiler\"), \"getMaximumSize\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    },\n                    {\n                        name: \"getMaximumSize\",\n                        desc: \"Relative time spent in ComponentUI.getMaximumSize().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"cuiProfiler\"), \"getMinimumSize\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT,\n                            max: 1000\n                        }\n                    }\n                ]\n            },\n            layout_counts = {\n                name: \"Layouts Count\",\n                desc: \"Invocations count of LayoutManager.preferredLayoutSize(), LayoutManager.minimumLayoutSize(), LayoutManager.layoutContainer().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: swingScriptPath,\n                    fragment: \"layout\"\n                },\n                properties: [\n                    {\n                        name: \"preferredLayoutSize\",\n                        desc: \"Invocations count of LayoutManager.preferredLayoutSize().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"layoutProfiler\"), \"preferredLayoutSize\")\n                    },\n                    {\n                        name: \"minimumLayoutSize\",\n                        desc: \"Invocations count of LayoutManager.minimumLayoutSize().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"layoutProfiler\"), \"minimumLayoutSize\")\n                    },\n                    {\n                        name: \"layoutContainer\",\n                        desc: \"Invocations count of LayoutManager.layoutContainer().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"layoutProfiler\"), \"layoutContainer\")\n                    }\n                ]\n            },\n            layout_time = {\n                name: \"Layouts Time\",\n                desc: \"Relative time spent in LayoutManager.preferredLayoutSize(), LayoutManager.minimumLayoutSize(), LayoutManager.layoutContainer().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: swingScriptPath,\n                    fragment: \"layout\"\n                },\n                properties: [\n                    {\n                        name: \"preferredLayoutSize\",\n                        desc: \"Relative time spent in LayoutManager.preferredLayoutSize().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"layoutProfiler\"), \"preferredLayoutSize\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    },\n                    {\n                        name: \"minimumLayoutSize\",\n                        desc: \"Relative time spent in LayoutManager.minimumLayoutSize().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"layoutProfiler\"), \"minimumLayoutSize\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    },\n                    {\n                        name: \"layoutContainer\",\n                        desc: \"Relative time spent in LayoutManager.layoutContainer().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"layoutProfiler\"), \"layoutContainer\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    }\n                ]\n            },\n            events_counts = {\n                name: \"Common Events Count\",\n                desc: \"Invocations count of ActionListener.actionPerformed(), ChangeListener.stateChanged(), PropertyChangeListener.propertyChange().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: swingScriptPath,\n                    fragment: \"basic_events\"\n                },\n                properties: [\n                    {\n                        name: \"actionPerformed\",\n                        desc: \"Invocations count of ActionListener.actionPerformed().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"eventsProfiler\"), \"actionPerformed\")\n                    },\n                    {\n                        name: \"stateChanged\",\n                        desc: \"Invocations count of ChangeListener.stateChanged().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"eventsProfiler\"), \"stateChanged\")\n                    },\n                    {\n                        name: \"propertyChange\",\n                        desc: \"Invocations count of PropertyChangeListener.propertyChange().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"eventsProfiler\"), \"propertyChange\")\n                    }\n                ]\n            },\n            events_time = {\n                name: \"Common Events Time\",\n                desc: \"Relative time spent in ActionListener.actionPerformed(), ChangeListener.stateChanged(), PropertyChangeListener.propertyChange().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: swingScriptPath,\n                    fragment: \"basic_events\"\n                },\n                properties: [\n                    {\n                        name: \"actionPerformed\",\n                        desc: \"Relative time spent in ActionListener.actionPerformed().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"eventsProfiler\"), \"actionPerformed\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    },\n                    {\n                        name: \"stateChanged\",\n                        desc: \"Relative time spent in ChangeListener.stateChanged().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"eventsProfiler\"), \"stateChanged\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    },\n                    {\n                        name: \"propertyChange\",\n                        desc: \"Relative time spent in PropertyChangeListener.propertyChange().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"eventsProfiler\"), \"propertyChange\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    }\n                ]\n            },\n            jc_events_count = {\n                name: \"Component Events Count\",\n                desc: \"Invocations count of Component.processComponentEvent(), Component.processFocusEvent(), Component.processKeyEvent(), Component.processMouseEvent(), Component.processMouseMotionEvent(), Component.processMouseWheelEvent(), Component.processInputMethodEvent(), Component.processHierarchyEvent().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: swingScriptPath,\n                    fragment: \"component_events\"\n                },\n                properties: [\n                    {\n                        name: \"processComponentEvent\",\n                        desc: \"Invocations count of Component.processComponentEvent().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processComponentEvent\")\n                    },\n                    {\n                        name: \"processFocusEvent\",\n                        desc: \"Invocations count of Component.processFocusEvent().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processFocusEvent\")\n                    },\n                    {\n                        name: \"processKeyEvent\",\n                        desc: \"Invocations count of Component.processKeyEvent().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processKeyEvent\")\n                    },\n                    {\n                        name: \"processMouseEvent\",\n                        desc: \"Invocations count of Component.processMouseEvent().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processMouseEvent\")\n                    },\n                    {\n                        name: \"processMouseMotionEvent\",\n                        desc: \"Invocations count of Component.processMouseMotionEvent().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"),\"processMouseMotionEvent\")\n                    },\n                    {\n                        name: \"processMouseWheelEvent\",\n                        desc: \"Invocations count of Component.processMouseWheelEvent().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processMouseWheelEvent\")\n                    },\n                    {\n                        name: \"processInputMethodEvent\",\n                        desc: \"Invocations count of Component.processInputMethodEvent().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processInputMethodEvent\")\n                    },\n                    {\n                        name: \"processHierarchyEvent\",\n                        desc: \"Invocations count of Component.processHierarchyEvent().\",\n                        value: invocations(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processHierarchyEvent\")\n                    }\n                ]\n            },\n            jc_events_time = {\n                name: \"Component Events Time\",\n                desc: \"Relative time spent in Component.processComponentEvent(), Component.processFocusEvent(), Component.processKeyEvent(), Component.processMouseEvent(), Component.processMouseMotionEvent(), Component.processMouseWheelEvent(), Component.processInputMethodEvent(), Component.processHierarchyEvent().\",\n                reqs: \"Requires BTrace Deployer plugin.\",\n                validator: function() {\n                    return btraceDeployer != undefined;\n                },\n                deployment: {\n                    deployer: btraceDeployer,\n                    script: swingScriptPath,\n                    fragment: \"component_events\"\n                },\n                properties: [\n                    {\n                        name: \"processComponentEvent\",\n                        desc: \"Relative time spent in Component.processComponentEvent().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processComponentEvent\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    },\n                    {\n                        name: \"processFocusEvent\",\n                        desc: \"Relative time spent in Component.processFocusEvent().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processFocusEvent\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    },\n                    {\n                        name: \"processKeyEvent\",\n                        desc: \"Relative time spent in Component.processKeyEvent().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processKeyEvent\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    },\n                    {\n                        name: \"processMouseEvent\",\n                        desc: \"Relative time spent in Component.processMouseEvent().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processMouseEvent\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    },\n                    {\n                        name: \"processMouseMotionEvent\",\n                        desc: \"Relative time spent in Component.processMouseMotionEvent().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processMouseMotionEvent\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    },\n                    {\n                        name: \"processMouseWheelEvent\",\n                        desc: \"Relative time spent in Component.processMouseWheelEvent().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processMouseWheelEvent\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    },\n                    {\n                        name: \"processInputMethodEvent\",\n                        desc: \"Relative time spent in Component.processInputMethodEvent().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processInputMethodEvent\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    },\n                    {\n                        name: \"processHierarchyEvent\",\n                        desc: \"Relative time spent in Component.processHierarchyEvent().\",\n                        value: selfTimePercent(mbeanAttribute(\"btrace:name=SwingStats\", \"jcEventsProfiler\"), \"processHierarchyEvent\"),\n                        presenter: {\n                            format: ItemValueFormatter.DEFAULT_PERCENT\n                        }\n                    }\n                ]\n            }\n        ]\n    }\n])\n"
  },
  {
    "path": "samples/apptype/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.visualvm.demoapplicationtype\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.visualvm.demoapplicationtype.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/apptype/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.visualvm.demoapplicationtype\nOpenIDE-Module-Install: org/visualvm/demoapplicationtype/Installer.class\nOpenIDE-Module-Layer: org/visualvm/demoapplicationtype/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/visualvm/demoapplicationtype/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.0\n\n"
  },
  {
    "path": "samples/apptype/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.visualvm.demoapplicationtype-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/platform-private.properties\"/>\n    <property file=\"nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/apptype/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=b952152d\nbuild.xml.script.CRC32=bb14dfaa\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=b952152d\nnbproject/build-impl.xml.script.CRC32=0c1d0bde\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "samples/apptype/nbproject/platform.properties",
    "content": "nbplatform.active=VisualVM_1.0_RC_\n"
  },
  {
    "path": "samples/apptype/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "samples/apptype/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.visualvm.demoapplicationtype</code-name-base>\n            <standalone/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application.views</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "samples/apptype/src/org/visualvm/demoapplicationtype/AnagramAction.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.visualvm.demoapplicationtype;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport java.awt.event.ActionEvent;\nimport javax.swing.Action;\nimport javax.swing.JOptionPane;\n\npublic class AnagramAction extends SingleDataSourceAction<Application> {\n\n    public AnagramAction() {\n        super(Application.class);\n        putValue(Action.NAME, \"Show Anagram PID\");\n        putValue(Action.SHORT_DESCRIPTION, \"Demoes a menu item\");\n    }\n\n    @Override\n    protected void actionPerformed(Application application, ActionEvent arg1) {\n        JOptionPane.showMessageDialog(null, application.getPid());\n    }\n\n    //Here you can determine whether the menu item is enabled,\n    //depending on the data source type that is selected. In this\n    //example, the menu item is enabled for all types within\n    //the current data source:\n    @Override\n    protected boolean isEnabled(Application application) {\n        if (ApplicationTypeFactory.getApplicationTypeFor(application) instanceof AnagramApplicationType) {\n            return true;\n        }\n        return false;\n    }\n}\n\n"
  },
  {
    "path": "samples/apptype/src/org/visualvm/demoapplicationtype/AnagramApplicationType.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.visualvm.demoapplicationtype;\n\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport java.awt.Image;\nimport org.openide.util.Utilities;\n\npublic class AnagramApplicationType extends ApplicationType {\n\n    protected final int appPID;\n\n    public AnagramApplicationType(int pid) {\n        appPID = pid;\n    }\n\n    @Override\n    public String getName() {\n        return \"Anagram\";\n    }\n\n    @Override\n    public String getVersion() {\n        return \"1.0\";\n    }\n\n    @Override\n    public String getDescription() {\n        return \"Application type for Anagram\";\n    }\n\n    @Override\n    public Image getIcon() {\n        return Utilities.loadImage(\"org/graalvm/visualvm/core/ui/resources/snapshot.png\", true);\n    }\n}\n"
  },
  {
    "path": "samples/apptype/src/org/visualvm/demoapplicationtype/AnagramApplicationTypeFactory.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.visualvm.demoapplicationtype;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.graalvm.visualvm.application.type.MainClassApplicationTypeFactory;\n\npublic class AnagramApplicationTypeFactory extends MainClassApplicationTypeFactory {\n\n    @Override\n    public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) {\n\n        //TODO: Specify the name of the application's main class here:\n        if (\"com.toy.anagrams.ui.Anagrams\".equals(mainClass)) {\n            return new AnagramApplicationType(app.getPid());\n        }\n        return null;\n\n    }\n}\n"
  },
  {
    "path": "samples/apptype/src/org/visualvm/demoapplicationtype/AnagramOverview.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.visualvm.demoapplicationtype;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport javax.swing.JPanel;\n\n/**\n *\n * @author geertjan\n */\npublic class AnagramOverview extends DataSourceViewPlugin {\n\n    AnagramOverview(Application application) {\n        super(application);\n    }\n\n    public DataViewComponent.DetailsView createView(int location) {\n        switch (location) {\n            case DataViewComponent.TOP_RIGHT:\n                JPanel panel = new JPanel();\n                return new DataViewComponent.DetailsView(\"User Interface\", null, 30,\n                        new ScrollableContainer(panel), null);\n            default:\n                return null;\n        }\n    }\n}"
  },
  {
    "path": "samples/apptype/src/org/visualvm/demoapplicationtype/AnagramViewPluginProvider.java",
    "content": "package org.visualvm.demoapplicationtype;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.application.views.ApplicationViewsSupport;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass AnagramViewPluginProvider extends DataSourceViewPluginProvider<Application> {\n\n    protected DataSourceViewPlugin createPlugin(Application application) {\n        return new AnagramOverview(application);\n    }\n\n    protected boolean supportsPluginFor(Application application) {\n        if (ApplicationTypeFactory.getApplicationTypeFor(application) instanceof AnagramApplicationType) {\n            return true;\n        }\n        return false;\n    }\n\n    static void initialize() {\n        ApplicationViewsSupport.sharedInstance().getOverviewView().\n                registerPluginProvider(new AnagramViewPluginProvider());\n    }\n\n    static void uninitialize() {\n        ApplicationViewsSupport.sharedInstance().getMonitorView().unregisterPluginProvider(new AnagramViewPluginProvider());\n    }\n}\n"
  },
  {
    "path": "samples/apptype/src/org/visualvm/demoapplicationtype/Bundle.properties",
    "content": "OpenIDE-Module-Name=VisualVM-DemoApplicationType\nVisualVM/ExplorerPopupSelection/org-visualvm-demoapplicationtype-AnagramAction.instance=\n"
  },
  {
    "path": "samples/apptype/src/org/visualvm/demoapplicationtype/Installer.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.visualvm.demoapplicationtype;\n\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.openide.modules.ModuleInstall;\n\npublic class Installer extends ModuleInstall {\n\n    private static AnagramApplicationTypeFactory INSTANCE = new AnagramApplicationTypeFactory();\n\n    @Override\n    public void restored() {\n        ApplicationTypeFactory.getDefault().registerProvider(INSTANCE);\n        AnagramViewPluginProvider.initialize();\n    }\n\n    @Override\n    public void uninstalled() {\n        ApplicationTypeFactory.getDefault().unregisterProvider(INSTANCE);\n        AnagramViewPluginProvider.uninitialize();\n    }\n}\n\n"
  },
  {
    "path": "samples/apptype/src/org/visualvm/demoapplicationtype/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    <folder name=\"VisualVM\">\n        <folder name=\"ExplorerPopupSelection\">\n            <file name=\"org-visualvm-demoapplicationtype-AnagramAction.instance\">\n                <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.visualvm.demoapplicationtype.Bundle\"/>\n                <attr name=\"position\" intvalue=\"3000\"/>\n            </file>\n        </folder>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "samples/datasource/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.visualvm.demodescriptorprovider\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.visualvm.demodescriptorprovider.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/datasource/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.visualvm.demodescriptorprovider\nOpenIDE-Module-Install: org/visualvm/demodescriptorprovider/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/visualvm/demodescriptorprovider/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.0\n\n"
  },
  {
    "path": "samples/datasource/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.visualvm.demodescriptorprovider-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/platform-private.properties\"/>\n    <property file=\"nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/datasource/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=a6909753\nbuild.xml.script.CRC32=d6e7eed3\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=a6909753\nnbproject/build-impl.xml.script.CRC32=f166a412\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "samples/datasource/nbproject/platform.properties",
    "content": "nbplatform.active=VisualVM_1.0_RC_\n"
  },
  {
    "path": "samples/datasource/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "samples/datasource/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.visualvm.demodescriptorprovider</code-name-base>\n            <standalone/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <implementation-version/>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                </module-dependencies>\n            <public-packages>\n                <package>org.visualvm.demodescriptorprovider</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "samples/datasource/src/org/visualvm/demodescriptorprovider/Bundle.properties",
    "content": "OpenIDE-Module-Name=VisualVM-DataSource\n"
  },
  {
    "path": "samples/datasource/src/org/visualvm/demodescriptorprovider/DemoDataSource.java",
    "content": "package org.visualvm.demodescriptorprovider;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\n\npublic class DemoDataSource extends DataSource {\n\n    private static DemoDataSource sharedInstance;\n\n    public static synchronized DemoDataSource sharedInstance() {\n        if (sharedInstance == null) {\n            sharedInstance = new DemoDataSource();\n        }\n        return sharedInstance;\n    }\n    \n}\n"
  },
  {
    "path": "samples/datasource/src/org/visualvm/demodescriptorprovider/DemoDataSourceDescriptor.java",
    "content": "package org.visualvm.demodescriptorprovider;\n\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport java.awt.Image;\nimport org.openide.util.Utilities;\n\npublic class DemoDataSourceDescriptor extends DataSourceDescriptor<DemoDataSource> {\n\n    private static final Image NODE_ICON =\n            Utilities.loadImage(\n            \"org/visualvm/demodescriptorprovider/icon.png\",\n            true);\n\n   \n    public DemoDataSourceDescriptor(DemoDataSource application) {\n        super(application,\n                \"System Monitors\",\n                \"Descriptor for System Monitors container\",\n                NODE_ICON,\n                POSITION_AT_THE_END,\n                EXPAND_NEVER);\n    }\n\n}\n"
  },
  {
    "path": "samples/datasource/src/org/visualvm/demodescriptorprovider/DemoDataSourceDescriptorProvider.java",
    "content": "package org.visualvm.demodescriptorprovider;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\npublic class DemoDataSourceDescriptorProvider extends AbstractModelProvider<DataSourceDescriptor, DataSource> {\n\n    DemoDataSourceDescriptorProvider() {\n    }\n\n    public DataSourceDescriptor createModelFor(DataSource ds) {\n        if (ds instanceof DemoDataSource) {\n            return new DemoDataSourceDescriptor((DemoDataSource) ds);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "samples/datasource/src/org/visualvm/demodescriptorprovider/DemoDataSourceView.java",
    "content": "package org.visualvm.demodescriptorprovider;\n\nimport org.visualvm.demodescriptorprovider.panels.MemoryMonitor5;\nimport org.visualvm.demodescriptorprovider.panels.MemoryMonitor2;\nimport org.visualvm.demodescriptorprovider.panels.MemoryMonitor1;\nimport org.visualvm.demodescriptorprovider.panels.MemoryMonitor4;\nimport org.visualvm.demodescriptorprovider.panels.MemoryMonitor3;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport org.openide.util.Utilities;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\n\nclass DemoDataSourceView extends DataSourceView {\n\n    private DataViewComponent dvc;\n    private static final String IMAGE_PATH = \"\" +\n            \"org/visualvm/demodescriptorprovider/icon.png\"; // NOI18N\n\n    public DemoDataSourceView(DemoDataSource ds) {\n        super(ds, \"Memory Monitor\", new ImageIcon(\n                Utilities.loadImage(IMAGE_PATH, true)).getImage(), 60, true);\n    }\n\n    @Override\n    protected DataViewComponent createComponent() {\n\n        //Data area for master view:\n        MemoryMonitor1 panel1 = new MemoryMonitor1();\n        MemoryMonitor2 panel2 = new MemoryMonitor2();\n        MemoryMonitor3 panel3 = new MemoryMonitor3();\n        MemoryMonitor4 panel4 = new MemoryMonitor4();\n        MemoryMonitor5 panel5 = new MemoryMonitor5();\n\n        panel1.setPreferredSize(new Dimension(650, 200));\n        panel2.setPreferredSize(new Dimension(650, 200));\n        panel3.setPreferredSize(new Dimension(650, 200));\n        panel4.setPreferredSize(new Dimension(650, 200));\n        panel5.setPreferredSize(new Dimension(650, 200));\n\n        ScrollableContainer container1 = new ScrollableContainer(panel1);\n\n        JScrollPane jScrollPane1 = new JScrollPane(panel1);\n        JScrollPane jScrollPane2 = new JScrollPane(panel2);\n        JScrollPane jScrollPane3 = new JScrollPane(panel3);\n        JScrollPane jScrollPane4 = new JScrollPane(panel4);\n        JScrollPane jScrollPane5 = new JScrollPane(panel5);\n\n        JPanel panel = new JPanel();\n        final HTMLTextArea area = new HTMLTextArea();\n        area.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n        panel.setBackground(area.getBackground());\n        area.setText(\"<a href=\\\"\" + \"hello\" + \"\\\">www.hello.org</a>\");\n        panel.add(new ScrollableContainer(area), BorderLayout.CENTER);\n\n        //Master view:\n        DataViewComponent.MasterView masterView = new DataViewComponent.MasterView(\"\", null, null);\n\n        //Configuration of master view:\n        DataViewComponent.MasterViewConfiguration masterConfiguration =\n                new DataViewComponent.MasterViewConfiguration(false);\n\n        //Add the master view and configuration view to the component:\n        dvc = new DataViewComponent(masterView, masterConfiguration);\n\n        //Add configuration details to the component, which are the show/hide checkboxes at the top:\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\n                \"Show Code Cache\", true), DataViewComponent.TOP_LEFT);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\n                \"Show Eden Space\", true), DataViewComponent.TOP_RIGHT);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\n                \"Show Survivor Space\", true), DataViewComponent.BOTTOM_LEFT);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\n                \"Show Gen\", true), DataViewComponent.BOTTOM_RIGHT);\n\n        //Add detail views to the component:\n        dvc.addDetailsView(new DataViewComponent.DetailsView(\n                \"Code Cache\", null, 30, jScrollPane1, null), DataViewComponent.TOP_LEFT);\n        dvc.addDetailsView(new DataViewComponent.DetailsView(\n                \"Eden Space\", null, 30, jScrollPane2, null), DataViewComponent.TOP_RIGHT);\n        dvc.addDetailsView(new DataViewComponent.DetailsView(\n                \"Survivor Space\", null, 30, jScrollPane3, null), DataViewComponent.BOTTOM_LEFT);\n        dvc.addDetailsView(new DataViewComponent.DetailsView(\n                \"Old Gen\", null, 30, jScrollPane4, null), DataViewComponent.BOTTOM_RIGHT);\n        dvc.addDetailsView(new DataViewComponent.DetailsView(\n                \"Perm Gen\", null, 30, jScrollPane5, null), DataViewComponent.BOTTOM_RIGHT);\n\n        return dvc;\n\n    }\n}\n\n"
  },
  {
    "path": "samples/datasource/src/org/visualvm/demodescriptorprovider/DemoDataSourceViewProvider.java",
    "content": "package org.visualvm.demodescriptorprovider;\n\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\n\npublic class DemoDataSourceViewProvider extends DataSourceViewProvider<DemoDataSource> {\n\n    @Override\n    protected boolean supportsViewFor(DemoDataSource ds) {\n        if (DemoDataSource.sharedInstance().equals(ds)) {\n            return true;\n        }\n        return false;\n    }\n\n    @Override\n    protected DataSourceView createView(DemoDataSource ds) {\n        return new DemoDataSourceView(ds);\n    }\n\n}\n"
  },
  {
    "path": "samples/datasource/src/org/visualvm/demodescriptorprovider/Installer.java",
    "content": "package org.visualvm.demodescriptorprovider;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.openide.modules.ModuleInstall;\n\npublic class Installer extends ModuleInstall {\n\n    DemoDataSource ds = DemoDataSource.sharedInstance();\n    private static DemoDataSourceViewProvider INSTANCE = new DemoDataSourceViewProvider();\n\n    @Override\n    public void restored() {\n        DataSource.ROOT.getRepository().addDataSource(ds);\n        DataSourceViewsManager.sharedInstance().addViewProvider(INSTANCE, DemoDataSource.class);\n        DataSourceDescriptorFactory.getDefault().registerProvider(new DemoDataSourceDescriptorProvider());\n    }\n\n    @Override\n    public void uninstalled() {\n        DataSource.ROOT.getRepository().removeDataSource(ds);\n        DataSourceViewsManager.sharedInstance().removeViewProvider(INSTANCE);\n        DataSourceDescriptorFactory.getDefault().unregisterProvider(new DemoDataSourceDescriptorProvider());\n    }\n    \n}\n"
  },
  {
    "path": "samples/datasource/src/org/visualvm/demodescriptorprovider/panels/MemoryMonitor1.java",
    "content": "package org.visualvm.demodescriptorprovider.panels;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.awt.image.BufferedImage;\nimport java.awt.geom.Line2D;\nimport java.awt.geom.Rectangle2D;\nimport java.util.Date;\nimport javax.swing.*;\nimport javax.swing.border.EtchedBorder;\nimport javax.swing.border.TitledBorder;\nimport java.lang.management.*;\nimport java.util.*;\n\npublic class MemoryMonitor1 extends JPanel {\n\n    static JCheckBox dateStampCB = new JCheckBox(\"Output Date Stamp\");\n    public Surface surf;\n    JPanel controls;\n    boolean doControls;\n    JTextField tf;\n    // Get memory pools.\n    static java.util.List<MemoryPoolMXBean> mpools = \n        ManagementFactory.getMemoryPoolMXBeans();\n    // Total number of memory pools.\n    static int numPools = 1;\n\n    public MemoryMonitor1() {\n        setLayout(new BorderLayout());\n        add(surf = new Surface());\n        controls = new JPanel();\n        controls.setPreferredSize(new Dimension(135,80));\n        Font font = new Font(\"serif\", Font.PLAIN, 10);\n        JLabel label = new JLabel(\"Sample Rate\");\n        label.setFont(font);\n        label.setForeground(Color.red);\n        controls.add(label);\n        tf = new JTextField(\"1000\");\n        tf.setPreferredSize(new Dimension(45,20));\n        controls.add(tf);\n        controls.add(label = new JLabel(\"ms\"));\n        label.setFont(font);\n        label.setForeground(Color.red);\n        controls.add(dateStampCB);\n        dateStampCB.setFont(font);\n        addMouseListener(new MouseAdapter() {\n            public void mouseClicked(MouseEvent e) {\n               removeAll();\n               if ((doControls = !doControls)) {\n                   surf.stop();\n                   add(controls);\n               } else {\n                   try { \n                       surf.sleepAmount = Long.parseLong(tf.getText().trim());\n                   } catch (Exception ex) {}\n                   surf.start();\n                   add(surf);\n               }\n               validate();\n               repaint();\n            }\n        });\n    }\n\n\n    public class Surface extends JPanel implements Runnable {\n\n        public Thread thread;\n        public long sleepAmount = 1000;\n\tpublic int  usageHistCount = 20000;\n        private int w, h;\n        private BufferedImage bimg;\n        private Graphics2D big;\n        private Font font = new Font(\"Times New Roman\", Font.PLAIN, 11);\n        private int columnInc;\n        private float usedMem[][];\n        private int ptNum[];\n        private int ascent, descent;\n        private Rectangle graphOutlineRect = new Rectangle();\n        private Rectangle2D mfRect = new Rectangle2D.Float();\n        private Rectangle2D muRect = new Rectangle2D.Float();\n        private Line2D graphLine = new Line2D.Float();\n        private Color graphColor = new Color(46, 139, 87);\n        private Color mfColor = new Color(0, 100, 0);\n        private String usedStr;\n      \n\n        public Surface() {\n            setBackground(Color.black);\n            addMouseListener(new MouseAdapter() {\n                public void mouseClicked(MouseEvent e) {\n                    if (thread == null) start(); else stop();\n                }\n            });\n\t    int i = 0;\n\t    usedMem = new float[numPools][];\n\t    ptNum = new int[numPools];\n        }\n\n        public Dimension getMinimumSize() {\n            return getPreferredSize();\n        }\n\n        public Dimension getMaximumSize() {\n            return getPreferredSize();\n        }\n\n        public Dimension getPreferredSize() {\n            return new Dimension(135,80);\n        }\n\n            \n        public void paint(Graphics g) {\n\n            if (big == null) {\n                return;\n            }\n\n            big.setBackground(getBackground());\n            big.clearRect(0,0,w,h);\n\n\n\t    h = h / ((numPools + numPools%2) / 2); \n\t    w = h *3;\n\n\t    int k=0; // index of memory pool.\n\t    for (int i=0; i < 2;i++) {\n\t       for (int j=0; j < (numPools + numPools%2)/ 2; j++) {\n\t         plotMemoryUsage(w*i,h*j,w,h,k);\n\t\t if (++k >= numPools) {\n\t\t    i = 3;\n\t\t    j = (numPools + numPools%2)/ 2;\n\t\t    break;\n\t\t }\n\t       }\n\t    }\n            g.drawImage(bimg, 0, 0, this);\n        }\n\n\tpublic void plotMemoryUsage(int x1, int y1, int x2, int y2, int npool) {\n\n\t    MemoryPoolMXBean mp = mpools.get(0); \n\t    float usedMemory =  mp.getUsage().getUsed();\n            float totalMemory =  mp.getUsage().getMax();\n\n            // .. Draw allocated and used strings ..\n            big.setColor(Color.green);\n\n\t    // Print Max memory allocated for this memory pool.\n            big.drawString(String.valueOf((int)totalMemory/1024) + \"K Max \", x1+4.0f, (float) y1 + ascent+0.5f);\n            big.setColor(Color.yellow);\n\n\t    // Print the memory pool name.\n            //big.drawString(mp.getName(),  x1+x2/2, (float) y1 + ascent+0.5f);\n\n\t    // Print the memory used by this memory pool.\n            usedStr = String.valueOf((int)usedMemory/1024) \n                + \"K used\";\n            big.setColor(Color.green);\n            big.drawString(usedStr, x1+4, y1+y2-descent);\n\n            // Calculate remaining size\n            float ssH = ascent + descent;\n            float remainingHeight = (float) (y2 - (ssH*2) - 0.5f);\n            float blockHeight = remainingHeight/10;\n            float blockWidth = 20.0f;\n            float remainingWidth = (float) (x2 - blockWidth - 10);\n\n            // .. Memory Free ..\n            big.setColor(mfColor);\n            int MemUsage = (int) (((totalMemory - usedMemory) / totalMemory) * 10);\n            int i = 0;\n            for ( ; i < MemUsage ; i++) { \n                mfRect.setRect(x1+5,(float) y1+ssH+i*blockHeight,\n                                blockWidth,(float) blockHeight-1);\n                big.fill(mfRect);\n            }\n\n            // .. Memory Used ..\n            big.setColor(Color.green);\n            for ( ; i < 10; i++)  {\n                muRect.setRect(x1+5,(float) y1 + ssH+i*blockHeight,\n                                blockWidth,(float) blockHeight-1);\n                big.fill(muRect);\n            }\n\n            // .. Draw History Graph ..\n\t    if (remainingWidth <= 30) remainingWidth = (float)30;\n\t    if (remainingHeight <= ssH) remainingHeight = (float)ssH;\n            big.setColor(graphColor);\n            int graphX = x1+30;\n            int graphY = y1 + (int) ssH;\n            int graphW = (int) remainingWidth;\n            int graphH = (int) remainingHeight;\n\n            graphOutlineRect.setRect(graphX, graphY, graphW, graphH);\n            big.draw(graphOutlineRect);\n\n            int graphRow = graphH/10;\n\n            // .. Draw row ..\n            for (int j = graphY; j <= graphH+graphY; j += graphRow) {\n                graphLine.setLine(graphX,j,graphX+graphW,j);\n                big.draw(graphLine);\n            }\n        \n            // .. Draw animated column movement ..\n            int graphColumn = graphW/15;\n\n            if (columnInc == 0) {\n                columnInc = graphColumn;\n            }\n\n            for (int j = graphX+columnInc; j < graphW+graphX; j+=graphColumn) {\n                graphLine.setLine(j,graphY,j,graphY+graphH);\n                big.draw(graphLine);\n            }\n\n            --columnInc;\n\n            // Plot memory usage by this memory pool.\t\n            if (usedMem[npool] == null) {\n\t\tusedMem[npool] = new float[usageHistCount];\n                ptNum[npool] = 0;\n            } \n\n\t    // save memory usage history.\n\t    usedMem[npool][ptNum[npool]] = usedMemory;\n\n            big.setColor(Color.yellow);\n\n\t    int w1; // width of memory usage history.\n\t    if (ptNum[npool] > graphW) {\n\t        w1 = graphW;\n\t    } else {\n\t\tw1 = ptNum[npool]; \n            }\n\n\n            for (int j=graphX+graphW-w1, k=ptNum[npool]-w1; k < ptNum[npool]; \n\t\t\t\t\t\t\t\tk++, j++) {\n                 if (k != 0) {\n                     if (usedMem[npool][k] != usedMem[npool][k-1]) {\n\t\t         int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k-1])/totalMemory));\n\t\t         int h2 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory));\n                         big.drawLine(j-1, h1, j, h2);\n                     } else {\n\t\t         int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory));\n                         big.fillRect(j, h1, 1, 1);\n                     }\n                 }\n            }\n            if (ptNum[npool]+2 == usedMem[npool].length) {\n                // throw out oldest point\n                for (int j = 1;j < ptNum[npool]; j++) {\n                     usedMem[npool][j-1] = usedMem[npool][j];\n                }\n                --ptNum[npool];\n            } else {\n                ptNum[npool]++;\n            }\n        }\n\n\n        public void start() {\n            thread = new Thread(this);\n            thread.setPriority(Thread.MIN_PRIORITY);\n            thread.setName(\"MemoryMonitor\");\n            thread.start();\n        }\n\n\n        public synchronized void stop() {\n            thread = null;\n            notify();\n        }\n\n        public void run() {\n\n            Thread me = Thread.currentThread();\n\n            while (thread == me && !isShowing() || getSize().width == 0) {\n                try {\n                    thread.sleep(500);\n                } catch (InterruptedException e) { return; }\n            }\n\t\n            while (thread == me && isShowing()) {\n                Dimension d = getSize();\n                if (d.width != w || d.height != h) {\n                    w = d.width;\n                    h = d.height;\n                    bimg = (BufferedImage) createImage(w, h);\n                    big = bimg.createGraphics();\n                    big.setFont(font);\n                    FontMetrics fm = big.getFontMetrics(font);\n                    ascent = (int) fm.getAscent();\n                    descent = (int) fm.getDescent();\n                }\n                repaint();\n                try {\n                    thread.sleep(sleepAmount);\n                } catch (InterruptedException e) { break; }\n                if (MemoryMonitor1.dateStampCB.isSelected()) {\n                     System.out.println(new Date().toString() + \" \" + usedStr);\n                }\n            }\n            thread = null;\n        }\n    }\n\n\n    // Test thread to consume memory\n    static class Memeater extends ClassLoader implements Runnable {\n\tObject y[];\n\tpublic Memeater() {}\n\tpublic void run() {\n\t    y = new Object[10000000];\n\t    int k =0;\n\t    while(true) {\n\t         if (k == 5000000) k=0;\n\t         y[k++] = new Object();\n\t         try {\n\t\t     Thread.sleep(20);\n\t         } catch (Exception x){}\n\n\t\t // to consume perm gen storage\n\t         try {\n                     // the classes are small so we load 10 at a time\n                     for (int i=0; i<10; i++) {\n                        loadNext();\n                     }\n                 } catch (ClassNotFoundException x) {\n\t\t   // ignore exception\n                 }\n\n\t   }\n\n\t}\n\n\tClass loadNext() throws ClassNotFoundException {\n\n            // public class TestNNNNNN extends java.lang.Object{\n            // public TestNNNNNN();\n            //   Code:\n            //    0:    aload_0\n            //    1:    invokespecial   #1; //Method java/lang/Object.\"<init>\":()V\n            //    4:    return\n            // }\n\n            int begin[] = {\n                0xca, 0xfe, 0xba, 0xbe, 0x00, 0x00, 0x00, 0x30,\n                0x00, 0x0a, 0x0a, 0x00, 0x03, 0x00, 0x07, 0x07,\n                0x00, 0x08, 0x07, 0x00, 0x09, 0x01, 0x00, 0x06,\n                0x3c, 0x69, 0x6e, 0x69, 0x74, 0x3e, 0x01, 0x00,\n                0x03, 0x28, 0x29, 0x56, 0x01, 0x00, 0x04, 0x43,\n                0x6f, 0x64, 0x65, 0x0c, 0x00, 0x04, 0x00, 0x05,\n                0x01, 0x00, 0x0a, 0x54, 0x65, 0x73, 0x74 };\n\n            int end [] = {\n                0x01, 0x00, 0x10,\n                0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e,\n                0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,\n                0x00, 0x21, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00,\n                0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04,\n                0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00,\n                0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,\n                0x00, 0x05, 0x2a, 0xb7, 0x00, 0x01, 0xb1, 0x00,\n                0x00, 0x00, 0x00, 0x00, 0x00 };\n\n\n            // TestNNNNNN\n\n            String name = \"Test\" + Integer.toString(count++);\n\n            byte value[];\n            try {\n                value = name.substring(4).getBytes(\"UTF-8\");\n            } catch (java.io.UnsupportedEncodingException x) {\n                throw new Error();\n            }\n\n            // construct class file\n\n            int len = begin.length + value.length + end.length;\n            byte b[] = new byte[len];\n            int i, pos=0;\n            for (i=0; i<begin.length; i++) {\n                b[pos++] = (byte)begin[i];\n            }\n            for (i=0; i<value.length; i++) {\n                b[pos++] = value[i];\n            }\n            for (i=0; i<end.length; i++) {\n                b[pos++] = (byte)end[i];\n            }\n\n            return defineClass(name, b, 0, b.length);\n\n\t}\n\tstatic int count = 100000;\n\t\n    }\n\t\n    public static void main(String s[]) {\n        final MemoryMonitor1 demo = new MemoryMonitor1();\n        WindowListener l = new WindowAdapter() {\n            public void windowClosing(WindowEvent e) {System.exit(0);}\n            public void windowDeiconified(WindowEvent e) { demo.surf.start(); }\n            public void windowIconified(WindowEvent e) { demo.surf.stop(); }\n        };\n        JFrame f = new JFrame(\"MemoryMonitor\");\n        f.addWindowListener(l);\n        f.getContentPane().add(\"Center\", demo);\n        f.pack();\n        f.setSize(new Dimension(400,500));\n        f.setVisible(true);\n        demo.surf.start();\n\tThread thr = new Thread(new Memeater());\n\tthr.start();\n    }\n\n}\n\n"
  },
  {
    "path": "samples/datasource/src/org/visualvm/demodescriptorprovider/panels/MemoryMonitor2.java",
    "content": "package org.visualvm.demodescriptorprovider.panels;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.awt.image.BufferedImage;\nimport java.awt.geom.Line2D;\nimport java.awt.geom.Rectangle2D;\nimport java.util.Date;\nimport javax.swing.*;\nimport javax.swing.border.EtchedBorder;\nimport javax.swing.border.TitledBorder;\nimport java.lang.management.*;\nimport java.util.*;\n\npublic class MemoryMonitor2 extends JPanel {\n\n    static JCheckBox dateStampCB = new JCheckBox(\"Output Date Stamp\");\n    public Surface surf;\n    JPanel controls;\n    boolean doControls;\n    JTextField tf;\n    // Get memory pools.\n    static java.util.List<MemoryPoolMXBean> mpools = \n        ManagementFactory.getMemoryPoolMXBeans();\n    // Total number of memory pools.\n    static int numPools = 1;\n\n    public MemoryMonitor2() {\n        setLayout(new BorderLayout());\n        add(surf = new Surface());\n        controls = new JPanel();\n        controls.setPreferredSize(new Dimension(135,80));\n        Font font = new Font(\"serif\", Font.PLAIN, 10);\n        JLabel label = new JLabel(\"Sample Rate\");\n        label.setFont(font);\n        label.setForeground(Color.red);\n        controls.add(label);\n        tf = new JTextField(\"1000\");\n        tf.setPreferredSize(new Dimension(45,20));\n        controls.add(tf);\n        controls.add(label = new JLabel(\"ms\"));\n        label.setFont(font);\n        label.setForeground(Color.red);\n        controls.add(dateStampCB);\n        dateStampCB.setFont(font);\n        addMouseListener(new MouseAdapter() {\n            public void mouseClicked(MouseEvent e) {\n               removeAll();\n               if ((doControls = !doControls)) {\n                   surf.stop();\n                   add(controls);\n               } else {\n                   try { \n                       surf.sleepAmount = Long.parseLong(tf.getText().trim());\n                   } catch (Exception ex) {}\n                   surf.start();\n                   add(surf);\n               }\n               validate();\n               repaint();\n            }\n        });\n    }\n\n\n    public class Surface extends JPanel implements Runnable {\n\n        public Thread thread;\n        public long sleepAmount = 1000;\n\tpublic int  usageHistCount = 20000;\n        private int w, h;\n        private BufferedImage bimg;\n        private Graphics2D big;\n        private Font font = new Font(\"Times New Roman\", Font.PLAIN, 11);\n        private int columnInc;\n        private float usedMem[][];\n        private int ptNum[];\n        private int ascent, descent;\n        private Rectangle graphOutlineRect = new Rectangle();\n        private Rectangle2D mfRect = new Rectangle2D.Float();\n        private Rectangle2D muRect = new Rectangle2D.Float();\n        private Line2D graphLine = new Line2D.Float();\n        private Color graphColor = new Color(46, 139, 87);\n        private Color mfColor = new Color(0, 100, 0);\n        private String usedStr;\n      \n\n        public Surface() {\n            setBackground(Color.black);\n            addMouseListener(new MouseAdapter() {\n                public void mouseClicked(MouseEvent e) {\n                    if (thread == null) start(); else stop();\n                }\n            });\n\t    int i = 0;\n\t    usedMem = new float[numPools][];\n\t    ptNum = new int[numPools];\n        }\n\n        public Dimension getMinimumSize() {\n            return getPreferredSize();\n        }\n\n        public Dimension getMaximumSize() {\n            return getPreferredSize();\n        }\n\n        public Dimension getPreferredSize() {\n            return new Dimension(135,80);\n        }\n\n            \n        public void paint(Graphics g) {\n\n            if (big == null) {\n                return;\n            }\n\n            big.setBackground(getBackground());\n            big.clearRect(0,0,w,h);\n\n\n\t    h = h / ((numPools + numPools%2) / 2); \n\t    w = h *3;\n\n\t    int k=0; // index of memory pool.\n\t    for (int i=0; i < 2;i++) {\n\t       for (int j=0; j < (numPools + numPools%2)/ 2; j++) {\n\t         plotMemoryUsage(w*i,h*j,w,h,k);\n\t\t if (++k >= numPools) {\n\t\t    i = 3;\n\t\t    j = (numPools + numPools%2)/ 2;\n\t\t    break;\n\t\t }\n\t       }\n\t    }\n            g.drawImage(bimg, 0, 0, this);\n        }\n\n\tpublic void plotMemoryUsage(int x1, int y1, int x2, int y2, int npool) {\n\n\t    MemoryPoolMXBean mp = mpools.get(1); \n\t    float usedMemory =  mp.getUsage().getUsed();\n            float totalMemory =  mp.getUsage().getMax();\n\n            // .. Draw allocated and used strings ..\n            big.setColor(Color.green);\n\n\t    // Print Max memory allocated for this memory pool.\n            big.drawString(String.valueOf((int)totalMemory/1024) + \"K Max \", x1+4.0f, (float) y1 + ascent+0.5f);\n            big.setColor(Color.yellow);\n\n\t    // Print the memory pool name.\n            //big.drawString(mp.getName(),  x1+x2/2, (float) y1 + ascent+0.5f);\n\n\t    // Print the memory used by this memory pool.\n            usedStr = String.valueOf((int)usedMemory/1024) \n                + \"K used\";\n            big.setColor(Color.green);\n            big.drawString(usedStr, x1+4, y1+y2-descent);\n\n            // Calculate remaining size\n            float ssH = ascent + descent;\n            float remainingHeight = (float) (y2 - (ssH*2) - 0.5f);\n            float blockHeight = remainingHeight/10;\n            float blockWidth = 20.0f;\n            float remainingWidth = (float) (x2 - blockWidth - 10);\n\n            // .. Memory Free ..\n            big.setColor(mfColor);\n            int MemUsage = (int) (((totalMemory - usedMemory) / totalMemory) * 10);\n            int i = 0;\n            for ( ; i < MemUsage ; i++) { \n                mfRect.setRect(x1+5,(float) y1+ssH+i*blockHeight,\n                                blockWidth,(float) blockHeight-1);\n                big.fill(mfRect);\n            }\n\n            // .. Memory Used ..\n            big.setColor(Color.green);\n            for ( ; i < 10; i++)  {\n                muRect.setRect(x1+5,(float) y1 + ssH+i*blockHeight,\n                                blockWidth,(float) blockHeight-1);\n                big.fill(muRect);\n            }\n\n            // .. Draw History Graph ..\n\t    if (remainingWidth <= 30) remainingWidth = (float)30;\n\t    if (remainingHeight <= ssH) remainingHeight = (float)ssH;\n            big.setColor(graphColor);\n            int graphX = x1+30;\n            int graphY = y1 + (int) ssH;\n            int graphW = (int) remainingWidth;\n            int graphH = (int) remainingHeight;\n\n            graphOutlineRect.setRect(graphX, graphY, graphW, graphH);\n            big.draw(graphOutlineRect);\n\n            int graphRow = graphH/10;\n\n            // .. Draw row ..\n            for (int j = graphY; j <= graphH+graphY; j += graphRow) {\n                graphLine.setLine(graphX,j,graphX+graphW,j);\n                big.draw(graphLine);\n            }\n        \n            // .. Draw animated column movement ..\n            int graphColumn = graphW/15;\n\n            if (columnInc == 0) {\n                columnInc = graphColumn;\n            }\n\n            for (int j = graphX+columnInc; j < graphW+graphX; j+=graphColumn) {\n                graphLine.setLine(j,graphY,j,graphY+graphH);\n                big.draw(graphLine);\n            }\n\n            --columnInc;\n\n            // Plot memory usage by this memory pool.\t\n            if (usedMem[npool] == null) {\n\t\tusedMem[npool] = new float[usageHistCount];\n                ptNum[npool] = 0;\n            } \n\n\t    // save memory usage history.\n\t    usedMem[npool][ptNum[npool]] = usedMemory;\n\n            big.setColor(Color.yellow);\n\n\t    int w1; // width of memory usage history.\n\t    if (ptNum[npool] > graphW) {\n\t        w1 = graphW;\n\t    } else {\n\t\tw1 = ptNum[npool]; \n            }\n\n\n            for (int j=graphX+graphW-w1, k=ptNum[npool]-w1; k < ptNum[npool]; \n\t\t\t\t\t\t\t\tk++, j++) {\n                 if (k != 0) {\n                     if (usedMem[npool][k] != usedMem[npool][k-1]) {\n\t\t         int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k-1])/totalMemory));\n\t\t         int h2 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory));\n                         big.drawLine(j-1, h1, j, h2);\n                     } else {\n\t\t         int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory));\n                         big.fillRect(j, h1, 1, 1);\n                     }\n                 }\n            }\n            if (ptNum[npool]+2 == usedMem[npool].length) {\n                // throw out oldest point\n                for (int j = 1;j < ptNum[npool]; j++) {\n                     usedMem[npool][j-1] = usedMem[npool][j];\n                }\n                --ptNum[npool];\n            } else {\n                ptNum[npool]++;\n            }\n        }\n\n\n        public void start() {\n            thread = new Thread(this);\n            thread.setPriority(Thread.MIN_PRIORITY);\n            thread.setName(\"MemoryMonitor\");\n            thread.start();\n        }\n\n\n        public synchronized void stop() {\n            thread = null;\n            notify();\n        }\n\n        public void run() {\n\n            Thread me = Thread.currentThread();\n\n            while (thread == me && !isShowing() || getSize().width == 0) {\n                try {\n                    thread.sleep(500);\n                } catch (InterruptedException e) { return; }\n            }\n\t\n            while (thread == me && isShowing()) {\n                Dimension d = getSize();\n                if (d.width != w || d.height != h) {\n                    w = d.width;\n                    h = d.height;\n                    bimg = (BufferedImage) createImage(w, h);\n                    big = bimg.createGraphics();\n                    big.setFont(font);\n                    FontMetrics fm = big.getFontMetrics(font);\n                    ascent = (int) fm.getAscent();\n                    descent = (int) fm.getDescent();\n                }\n                repaint();\n                try {\n                    thread.sleep(sleepAmount);\n                } catch (InterruptedException e) { break; }\n                if (MemoryMonitor2.dateStampCB.isSelected()) {\n                     System.out.println(new Date().toString() + \" \" + usedStr);\n                }\n            }\n            thread = null;\n        }\n    }\n\n\n    // Test thread to consume memory\n    static class Memeater extends ClassLoader implements Runnable {\n\tObject y[];\n\tpublic Memeater() {}\n\tpublic void run() {\n\t    y = new Object[10000000];\n\t    int k =0;\n\t    while(true) {\n\t         if (k == 5000000) k=0;\n\t         y[k++] = new Object();\n\t         try {\n\t\t     Thread.sleep(20);\n\t         } catch (Exception x){}\n\n\t\t // to consume perm gen storage\n\t         try {\n                     // the classes are small so we load 10 at a time\n                     for (int i=0; i<10; i++) {\n                        loadNext();\n                     }\n                 } catch (ClassNotFoundException x) {\n\t\t   // ignore exception\n                 }\n\n\t   }\n\n\t}\n\n\tClass loadNext() throws ClassNotFoundException {\n\n            // public class TestNNNNNN extends java.lang.Object{\n            // public TestNNNNNN();\n            //   Code:\n            //    0:    aload_0\n            //    1:    invokespecial   #1; //Method java/lang/Object.\"<init>\":()V\n            //    4:    return\n            // }\n\n            int begin[] = {\n                0xca, 0xfe, 0xba, 0xbe, 0x00, 0x00, 0x00, 0x30,\n                0x00, 0x0a, 0x0a, 0x00, 0x03, 0x00, 0x07, 0x07,\n                0x00, 0x08, 0x07, 0x00, 0x09, 0x01, 0x00, 0x06,\n                0x3c, 0x69, 0x6e, 0x69, 0x74, 0x3e, 0x01, 0x00,\n                0x03, 0x28, 0x29, 0x56, 0x01, 0x00, 0x04, 0x43,\n                0x6f, 0x64, 0x65, 0x0c, 0x00, 0x04, 0x00, 0x05,\n                0x01, 0x00, 0x0a, 0x54, 0x65, 0x73, 0x74 };\n\n            int end [] = {\n                0x01, 0x00, 0x10,\n                0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e,\n                0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,\n                0x00, 0x21, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00,\n                0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04,\n                0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00,\n                0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,\n                0x00, 0x05, 0x2a, 0xb7, 0x00, 0x01, 0xb1, 0x00,\n                0x00, 0x00, 0x00, 0x00, 0x00 };\n\n\n            // TestNNNNNN\n\n            String name = \"Test\" + Integer.toString(count++);\n\n            byte value[];\n            try {\n                value = name.substring(4).getBytes(\"UTF-8\");\n            } catch (java.io.UnsupportedEncodingException x) {\n                throw new Error();\n            }\n\n            // construct class file\n\n            int len = begin.length + value.length + end.length;\n            byte b[] = new byte[len];\n            int i, pos=0;\n            for (i=0; i<begin.length; i++) {\n                b[pos++] = (byte)begin[i];\n            }\n            for (i=0; i<value.length; i++) {\n                b[pos++] = value[i];\n            }\n            for (i=0; i<end.length; i++) {\n                b[pos++] = (byte)end[i];\n            }\n\n            return defineClass(name, b, 0, b.length);\n\n\t}\n\tstatic int count = 100000;\n\t\n    }\n\t\n    public static void main(String s[]) {\n        final MemoryMonitor2 demo = new MemoryMonitor2();\n        WindowListener l = new WindowAdapter() {\n            public void windowClosing(WindowEvent e) {System.exit(0);}\n            public void windowDeiconified(WindowEvent e) { demo.surf.start(); }\n            public void windowIconified(WindowEvent e) { demo.surf.stop(); }\n        };\n        JFrame f = new JFrame(\"MemoryMonitor\");\n        f.addWindowListener(l);\n        f.getContentPane().add(\"Center\", demo);\n        f.pack();\n        f.setSize(new Dimension(400,500));\n        f.setVisible(true);\n        demo.surf.start();\n\tThread thr = new Thread(new Memeater());\n\tthr.start();\n    }\n\n}\n\n"
  },
  {
    "path": "samples/datasource/src/org/visualvm/demodescriptorprovider/panels/MemoryMonitor3.java",
    "content": "package org.visualvm.demodescriptorprovider.panels;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.awt.image.BufferedImage;\nimport java.awt.geom.Line2D;\nimport java.awt.geom.Rectangle2D;\nimport java.util.Date;\nimport javax.swing.*;\nimport java.lang.management.*;\nimport java.util.*;\n\npublic class MemoryMonitor3 extends JPanel {\n\n    static JCheckBox dateStampCB = new JCheckBox(\"Output Date Stamp\");\n    public Surface surf;\n    JPanel controls;\n    boolean doControls;\n    JTextField tf;\n    // Get memory pools.\n    static java.util.List<MemoryPoolMXBean> mpools = \n        ManagementFactory.getMemoryPoolMXBeans();\n    // Total number of memory pools.\n    static int numPools = 1;\n\n    public MemoryMonitor3() {\n        setLayout(new BorderLayout());\n        add(surf = new Surface());\n        controls = new JPanel();\n        controls.setPreferredSize(new Dimension(135,80));\n        Font font = new Font(\"serif\", Font.PLAIN, 10);\n        JLabel label = new JLabel(\"Sample Rate\");\n        label.setFont(font);\n        label.setForeground(Color.red);\n        controls.add(label);\n        tf = new JTextField(\"1000\");\n        tf.setPreferredSize(new Dimension(45,20));\n        controls.add(tf);\n        controls.add(label = new JLabel(\"ms\"));\n        label.setFont(font);\n        label.setForeground(Color.red);\n        controls.add(dateStampCB);\n        dateStampCB.setFont(font);\n        addMouseListener(new MouseAdapter() {\n            public void mouseClicked(MouseEvent e) {\n               removeAll();\n               if ((doControls = !doControls)) {\n                   surf.stop();\n                   add(controls);\n               } else {\n                   try { \n                       surf.sleepAmount = Long.parseLong(tf.getText().trim());\n                   } catch (Exception ex) {}\n                   surf.start();\n                   add(surf);\n               }\n               validate();\n               repaint();\n            }\n        });\n    }\n\n\n    public class Surface extends JPanel implements Runnable {\n\n        public Thread thread;\n        public long sleepAmount = 1000;\n\tpublic int  usageHistCount = 20000;\n        private int w, h;\n        private BufferedImage bimg;\n        private Graphics2D big;\n        private Font font = new Font(\"Times New Roman\", Font.PLAIN, 11);\n        private int columnInc;\n        private float usedMem[][];\n        private int ptNum[];\n        private int ascent, descent;\n        private Rectangle graphOutlineRect = new Rectangle();\n        private Rectangle2D mfRect = new Rectangle2D.Float();\n        private Rectangle2D muRect = new Rectangle2D.Float();\n        private Line2D graphLine = new Line2D.Float();\n        private Color graphColor = new Color(46, 139, 87);\n        private Color mfColor = new Color(0, 100, 0);\n        private String usedStr;\n      \n\n        public Surface() {\n            setBackground(Color.black);\n            addMouseListener(new MouseAdapter() {\n                public void mouseClicked(MouseEvent e) {\n                    if (thread == null) start(); else stop();\n                }\n            });\n\t    int i = 0;\n\t    usedMem = new float[numPools][];\n\t    ptNum = new int[numPools];\n        }\n\n        public Dimension getMinimumSize() {\n            return getPreferredSize();\n        }\n\n        public Dimension getMaximumSize() {\n            return getPreferredSize();\n        }\n\n        public Dimension getPreferredSize() {\n            return new Dimension(135,80);\n        }\n\n            \n        public void paint(Graphics g) {\n\n            if (big == null) {\n                return;\n            }\n\n            big.setBackground(getBackground());\n            big.clearRect(0,0,w,h);\n\n\n\t    h = h / ((numPools + numPools%2) / 2); \n\t    w = h *3;\n\n\t    int k=0; // index of memory pool.\n\t    for (int i=0; i < 2;i++) {\n\t       for (int j=0; j < (numPools + numPools%2)/ 2; j++) {\n\t         plotMemoryUsage(w*i,h*j,w,h,k);\n\t\t if (++k >= numPools) {\n\t\t    i = 3;\n\t\t    j = (numPools + numPools%2)/ 2;\n\t\t    break;\n\t\t }\n\t       }\n\t    }\n            g.drawImage(bimg, 0, 0, this);\n        }\n\n\tpublic void plotMemoryUsage(int x1, int y1, int x2, int y2, int npool) {\n\n\t    MemoryPoolMXBean mp = mpools.get(2); \n\t    float usedMemory =  mp.getUsage().getUsed();\n            float totalMemory =  mp.getUsage().getMax();\n\n            // .. Draw allocated and used strings ..\n            big.setColor(Color.green);\n\n\t    // Print Max memory allocated for this memory pool.\n            big.drawString(String.valueOf((int)totalMemory/1024) + \"K Max \", x1+4.0f, (float) y1 + ascent+0.5f);\n            big.setColor(Color.yellow);\n\n\t    // Print the memory pool name.\n            //big.drawString(mp.getName(),  x1+x2/2, (float) y1 + ascent+0.5f);\n\n\t    // Print the memory used by this memory pool.\n            usedStr = String.valueOf((int)usedMemory/1024) \n                + \"K used\";\n            big.setColor(Color.green);\n            big.drawString(usedStr, x1+4, y1+y2-descent);\n\n            // Calculate remaining size\n            float ssH = ascent + descent;\n            float remainingHeight = (float) (y2 - (ssH*2) - 0.5f);\n            float blockHeight = remainingHeight/10;\n            float blockWidth = 20.0f;\n            float remainingWidth = (float) (x2 - blockWidth - 10);\n\n            // .. Memory Free ..\n            big.setColor(mfColor);\n            int MemUsage = (int) (((totalMemory - usedMemory) / totalMemory) * 10);\n            int i = 0;\n            for ( ; i < MemUsage ; i++) { \n                mfRect.setRect(x1+5,(float) y1+ssH+i*blockHeight,\n                                blockWidth,(float) blockHeight-1);\n                big.fill(mfRect);\n            }\n\n            // .. Memory Used ..\n            big.setColor(Color.green);\n            for ( ; i < 10; i++)  {\n                muRect.setRect(x1+5,(float) y1 + ssH+i*blockHeight,\n                                blockWidth,(float) blockHeight-1);\n                big.fill(muRect);\n            }\n\n            // .. Draw History Graph ..\n\t    if (remainingWidth <= 30) remainingWidth = (float)30;\n\t    if (remainingHeight <= ssH) remainingHeight = (float)ssH;\n            big.setColor(graphColor);\n            int graphX = x1+30;\n            int graphY = y1 + (int) ssH;\n            int graphW = (int) remainingWidth;\n            int graphH = (int) remainingHeight;\n\n            graphOutlineRect.setRect(graphX, graphY, graphW, graphH);\n            big.draw(graphOutlineRect);\n\n            int graphRow = graphH/10;\n\n            // .. Draw row ..\n            for (int j = graphY; j <= graphH+graphY; j += graphRow) {\n                graphLine.setLine(graphX,j,graphX+graphW,j);\n                big.draw(graphLine);\n            }\n        \n            // .. Draw animated column movement ..\n            int graphColumn = graphW/15;\n\n            if (columnInc == 0) {\n                columnInc = graphColumn;\n            }\n\n            for (int j = graphX+columnInc; j < graphW+graphX; j+=graphColumn) {\n                graphLine.setLine(j,graphY,j,graphY+graphH);\n                big.draw(graphLine);\n            }\n\n            --columnInc;\n\n            // Plot memory usage by this memory pool.\t\n            if (usedMem[npool] == null) {\n\t\tusedMem[npool] = new float[usageHistCount];\n                ptNum[npool] = 0;\n            } \n\n\t    // save memory usage history.\n\t    usedMem[npool][ptNum[npool]] = usedMemory;\n\n            big.setColor(Color.yellow);\n\n\t    int w1; // width of memory usage history.\n\t    if (ptNum[npool] > graphW) {\n\t        w1 = graphW;\n\t    } else {\n\t\tw1 = ptNum[npool]; \n            }\n\n\n            for (int j=graphX+graphW-w1, k=ptNum[npool]-w1; k < ptNum[npool]; \n\t\t\t\t\t\t\t\tk++, j++) {\n                 if (k != 0) {\n                     if (usedMem[npool][k] != usedMem[npool][k-1]) {\n\t\t         int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k-1])/totalMemory));\n\t\t         int h2 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory));\n                         big.drawLine(j-1, h1, j, h2);\n                     } else {\n\t\t         int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory));\n                         big.fillRect(j, h1, 1, 1);\n                     }\n                 }\n            }\n            if (ptNum[npool]+2 == usedMem[npool].length) {\n                // throw out oldest point\n                for (int j = 1;j < ptNum[npool]; j++) {\n                     usedMem[npool][j-1] = usedMem[npool][j];\n                }\n                --ptNum[npool];\n            } else {\n                ptNum[npool]++;\n            }\n        }\n\n\n        public void start() {\n            thread = new Thread(this);\n            thread.setPriority(Thread.MIN_PRIORITY);\n            thread.setName(\"MemoryMonitor\");\n            thread.start();\n        }\n\n\n        public synchronized void stop() {\n            thread = null;\n            notify();\n        }\n\n        public void run() {\n\n            Thread me = Thread.currentThread();\n\n            while (thread == me && !isShowing() || getSize().width == 0) {\n                try {\n                    thread.sleep(500);\n                } catch (InterruptedException e) { return; }\n            }\n\t\n            while (thread == me && isShowing()) {\n                Dimension d = getSize();\n                if (d.width != w || d.height != h) {\n                    w = d.width;\n                    h = d.height;\n                    bimg = (BufferedImage) createImage(w, h);\n                    big = bimg.createGraphics();\n                    big.setFont(font);\n                    FontMetrics fm = big.getFontMetrics(font);\n                    ascent = (int) fm.getAscent();\n                    descent = (int) fm.getDescent();\n                }\n                repaint();\n                try {\n                    thread.sleep(sleepAmount);\n                } catch (InterruptedException e) { break; }\n                if (MemoryMonitor3.dateStampCB.isSelected()) {\n                     System.out.println(new Date().toString() + \" \" + usedStr);\n                }\n            }\n            thread = null;\n        }\n    }\n\n\n    // Test thread to consume memory\n    static class Memeater extends ClassLoader implements Runnable {\n\tObject y[];\n\tpublic Memeater() {}\n\tpublic void run() {\n\t    y = new Object[10000000];\n\t    int k =0;\n\t    while(true) {\n\t         if (k == 5000000) k=0;\n\t         y[k++] = new Object();\n\t         try {\n\t\t     Thread.sleep(20);\n\t         } catch (Exception x){}\n\n\t\t // to consume perm gen storage\n\t         try {\n                     // the classes are small so we load 10 at a time\n                     for (int i=0; i<10; i++) {\n                        loadNext();\n                     }\n                 } catch (ClassNotFoundException x) {\n\t\t   // ignore exception\n                 }\n\n\t   }\n\n\t}\n\n\tClass loadNext() throws ClassNotFoundException {\n\n            // public class TestNNNNNN extends java.lang.Object{\n            // public TestNNNNNN();\n            //   Code:\n            //    0:    aload_0\n            //    1:    invokespecial   #1; //Method java/lang/Object.\"<init>\":()V\n            //    4:    return\n            // }\n\n            int begin[] = {\n                0xca, 0xfe, 0xba, 0xbe, 0x00, 0x00, 0x00, 0x30,\n                0x00, 0x0a, 0x0a, 0x00, 0x03, 0x00, 0x07, 0x07,\n                0x00, 0x08, 0x07, 0x00, 0x09, 0x01, 0x00, 0x06,\n                0x3c, 0x69, 0x6e, 0x69, 0x74, 0x3e, 0x01, 0x00,\n                0x03, 0x28, 0x29, 0x56, 0x01, 0x00, 0x04, 0x43,\n                0x6f, 0x64, 0x65, 0x0c, 0x00, 0x04, 0x00, 0x05,\n                0x01, 0x00, 0x0a, 0x54, 0x65, 0x73, 0x74 };\n\n            int end [] = {\n                0x01, 0x00, 0x10,\n                0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e,\n                0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,\n                0x00, 0x21, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00,\n                0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04,\n                0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00,\n                0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,\n                0x00, 0x05, 0x2a, 0xb7, 0x00, 0x01, 0xb1, 0x00,\n                0x00, 0x00, 0x00, 0x00, 0x00 };\n\n\n            // TestNNNNNN\n\n            String name = \"Test\" + Integer.toString(count++);\n\n            byte value[];\n            try {\n                value = name.substring(4).getBytes(\"UTF-8\");\n            } catch (java.io.UnsupportedEncodingException x) {\n                throw new Error();\n            }\n\n            // construct class file\n\n            int len = begin.length + value.length + end.length;\n            byte b[] = new byte[len];\n            int i, pos=0;\n            for (i=0; i<begin.length; i++) {\n                b[pos++] = (byte)begin[i];\n            }\n            for (i=0; i<value.length; i++) {\n                b[pos++] = value[i];\n            }\n            for (i=0; i<end.length; i++) {\n                b[pos++] = (byte)end[i];\n            }\n\n            return defineClass(name, b, 0, b.length);\n\n\t}\n\tstatic int count = 100000;\n\t\n    }\n\t\n    public static void main(String s[]) {\n        final MemoryMonitor3 demo = new MemoryMonitor3();\n        WindowListener l = new WindowAdapter() {\n            public void windowClosing(WindowEvent e) {System.exit(0);}\n            public void windowDeiconified(WindowEvent e) { demo.surf.start(); }\n            public void windowIconified(WindowEvent e) { demo.surf.stop(); }\n        };\n        JFrame f = new JFrame(\"MemoryMonitor\");\n        f.addWindowListener(l);\n        f.getContentPane().add(\"Center\", demo);\n        f.pack();\n        f.setSize(new Dimension(400,500));\n        f.setVisible(true);\n        demo.surf.start();\n\tThread thr = new Thread(new Memeater());\n\tthr.start();\n    }\n\n}\n\n"
  },
  {
    "path": "samples/datasource/src/org/visualvm/demodescriptorprovider/panels/MemoryMonitor4.java",
    "content": "package org.visualvm.demodescriptorprovider.panels;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.awt.image.BufferedImage;\nimport java.awt.geom.Line2D;\nimport java.awt.geom.Rectangle2D;\nimport java.util.Date;\nimport javax.swing.*;\nimport java.lang.management.*;\nimport java.util.*;\n\npublic class MemoryMonitor4 extends JPanel {\n\n    static JCheckBox dateStampCB = new JCheckBox(\"Output Date Stamp\");\n    public Surface surf;\n    JPanel controls;\n    boolean doControls;\n    JTextField tf;\n    // Get memory pools.\n    static java.util.List<MemoryPoolMXBean> mpools = \n        ManagementFactory.getMemoryPoolMXBeans();\n    // Total number of memory pools.\n    static int numPools = 1;\n\n    public MemoryMonitor4() {\n        setLayout(new BorderLayout());\n        add(surf = new Surface());\n        controls = new JPanel();\n        controls.setPreferredSize(new Dimension(135,80));\n        Font font = new Font(\"serif\", Font.PLAIN, 10);\n        JLabel label = new JLabel(\"Sample Rate\");\n        label.setFont(font);\n        label.setForeground(Color.red);\n        controls.add(label);\n        tf = new JTextField(\"1000\");\n        tf.setPreferredSize(new Dimension(45,20));\n        controls.add(tf);\n        controls.add(label = new JLabel(\"ms\"));\n        label.setFont(font);\n        label.setForeground(Color.red);\n        controls.add(dateStampCB);\n        dateStampCB.setFont(font);\n        addMouseListener(new MouseAdapter() {\n            public void mouseClicked(MouseEvent e) {\n               removeAll();\n               if ((doControls = !doControls)) {\n                   surf.stop();\n                   add(controls);\n               } else {\n                   try { \n                       surf.sleepAmount = Long.parseLong(tf.getText().trim());\n                   } catch (Exception ex) {}\n                   surf.start();\n                   add(surf);\n               }\n               validate();\n               repaint();\n            }\n        });\n    }\n\n\n    public class Surface extends JPanel implements Runnable {\n\n        public Thread thread;\n        public long sleepAmount = 1000;\n\tpublic int  usageHistCount = 20000;\n        private int w, h;\n        private BufferedImage bimg;\n        private Graphics2D big;\n        private Font font = new Font(\"Times New Roman\", Font.PLAIN, 11);\n        private int columnInc;\n        private float usedMem[][];\n        private int ptNum[];\n        private int ascent, descent;\n        private Rectangle graphOutlineRect = new Rectangle();\n        private Rectangle2D mfRect = new Rectangle2D.Float();\n        private Rectangle2D muRect = new Rectangle2D.Float();\n        private Line2D graphLine = new Line2D.Float();\n        private Color graphColor = new Color(46, 139, 87);\n        private Color mfColor = new Color(0, 100, 0);\n        private String usedStr;\n      \n\n        public Surface() {\n            setBackground(Color.black);\n            addMouseListener(new MouseAdapter() {\n                public void mouseClicked(MouseEvent e) {\n                    if (thread == null) start(); else stop();\n                }\n            });\n\t    int i = 0;\n\t    usedMem = new float[numPools][];\n\t    ptNum = new int[numPools];\n        }\n\n        public Dimension getMinimumSize() {\n            return getPreferredSize();\n        }\n\n        public Dimension getMaximumSize() {\n            return getPreferredSize();\n        }\n\n        public Dimension getPreferredSize() {\n            return new Dimension(135,80);\n        }\n\n            \n        public void paint(Graphics g) {\n\n            if (big == null) {\n                return;\n            }\n\n            big.setBackground(getBackground());\n            big.clearRect(0,0,w,h);\n\n\n\t    h = h / ((numPools + numPools%2) / 2); \n\t    w = h *3;\n\n\t    int k=0; // index of memory pool.\n\t    for (int i=0; i < 2;i++) {\n\t       for (int j=0; j < (numPools + numPools%2)/ 2; j++) {\n\t         plotMemoryUsage(w*i,h*j,w,h,k);\n\t\t if (++k >= numPools) {\n\t\t    i = 3;\n\t\t    j = (numPools + numPools%2)/ 2;\n\t\t    break;\n\t\t }\n\t       }\n\t    }\n            g.drawImage(bimg, 0, 0, this);\n        }\n\n\tpublic void plotMemoryUsage(int x1, int y1, int x2, int y2, int npool) {\n\n\t    MemoryPoolMXBean mp = mpools.get(3); \n\t    float usedMemory =  mp.getUsage().getUsed();\n            float totalMemory =  mp.getUsage().getMax();\n\n            // .. Draw allocated and used strings ..\n            big.setColor(Color.green);\n\n\t    // Print Max memory allocated for this memory pool.\n            big.drawString(String.valueOf((int)totalMemory/1024) + \"K Max \", x1+4.0f, (float) y1 + ascent+0.5f);\n            big.setColor(Color.yellow);\n\n\t    // Print the memory pool name.\n            //big.drawString(mp.getName(),  x1+x2/2, (float) y1 + ascent+0.5f);\n\n\t    // Print the memory used by this memory pool.\n            usedStr = String.valueOf((int)usedMemory/1024) \n                + \"K used\";\n            big.setColor(Color.green);\n            big.drawString(usedStr, x1+4, y1+y2-descent);\n\n            // Calculate remaining size\n            float ssH = ascent + descent;\n            float remainingHeight = (float) (y2 - (ssH*2) - 0.5f);\n            float blockHeight = remainingHeight/10;\n            float blockWidth = 20.0f;\n            float remainingWidth = (float) (x2 - blockWidth - 10);\n\n            // .. Memory Free ..\n            big.setColor(mfColor);\n            int MemUsage = (int) (((totalMemory - usedMemory) / totalMemory) * 10);\n            int i = 0;\n            for ( ; i < MemUsage ; i++) { \n                mfRect.setRect(x1+5,(float) y1+ssH+i*blockHeight,\n                                blockWidth,(float) blockHeight-1);\n                big.fill(mfRect);\n            }\n\n            // .. Memory Used ..\n            big.setColor(Color.green);\n            for ( ; i < 10; i++)  {\n                muRect.setRect(x1+5,(float) y1 + ssH+i*blockHeight,\n                                blockWidth,(float) blockHeight-1);\n                big.fill(muRect);\n            }\n\n            // .. Draw History Graph ..\n\t    if (remainingWidth <= 30) remainingWidth = (float)30;\n\t    if (remainingHeight <= ssH) remainingHeight = (float)ssH;\n            big.setColor(graphColor);\n            int graphX = x1+30;\n            int graphY = y1 + (int) ssH;\n            int graphW = (int) remainingWidth;\n            int graphH = (int) remainingHeight;\n\n            graphOutlineRect.setRect(graphX, graphY, graphW, graphH);\n            big.draw(graphOutlineRect);\n\n            int graphRow = graphH/10;\n\n            // .. Draw row ..\n            for (int j = graphY; j <= graphH+graphY; j += graphRow) {\n                graphLine.setLine(graphX,j,graphX+graphW,j);\n                big.draw(graphLine);\n            }\n        \n            // .. Draw animated column movement ..\n            int graphColumn = graphW/15;\n\n            if (columnInc == 0) {\n                columnInc = graphColumn;\n            }\n\n            for (int j = graphX+columnInc; j < graphW+graphX; j+=graphColumn) {\n                graphLine.setLine(j,graphY,j,graphY+graphH);\n                big.draw(graphLine);\n            }\n\n            --columnInc;\n\n            // Plot memory usage by this memory pool.\t\n            if (usedMem[npool] == null) {\n\t\tusedMem[npool] = new float[usageHistCount];\n                ptNum[npool] = 0;\n            } \n\n\t    // save memory usage history.\n\t    usedMem[npool][ptNum[npool]] = usedMemory;\n\n            big.setColor(Color.yellow);\n\n\t    int w1; // width of memory usage history.\n\t    if (ptNum[npool] > graphW) {\n\t        w1 = graphW;\n\t    } else {\n\t\tw1 = ptNum[npool]; \n            }\n\n\n            for (int j=graphX+graphW-w1, k=ptNum[npool]-w1; k < ptNum[npool]; \n\t\t\t\t\t\t\t\tk++, j++) {\n                 if (k != 0) {\n                     if (usedMem[npool][k] != usedMem[npool][k-1]) {\n\t\t         int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k-1])/totalMemory));\n\t\t         int h2 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory));\n                         big.drawLine(j-1, h1, j, h2);\n                     } else {\n\t\t         int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory));\n                         big.fillRect(j, h1, 1, 1);\n                     }\n                 }\n            }\n            if (ptNum[npool]+2 == usedMem[npool].length) {\n                // throw out oldest point\n                for (int j = 1;j < ptNum[npool]; j++) {\n                     usedMem[npool][j-1] = usedMem[npool][j];\n                }\n                --ptNum[npool];\n            } else {\n                ptNum[npool]++;\n            }\n        }\n\n\n        public void start() {\n            thread = new Thread(this);\n            thread.setPriority(Thread.MIN_PRIORITY);\n            thread.setName(\"MemoryMonitor\");\n            thread.start();\n        }\n\n\n        public synchronized void stop() {\n            thread = null;\n            notify();\n        }\n\n        public void run() {\n\n            Thread me = Thread.currentThread();\n\n            while (thread == me && !isShowing() || getSize().width == 0) {\n                try {\n                    thread.sleep(500);\n                } catch (InterruptedException e) { return; }\n            }\n\t\n            while (thread == me && isShowing()) {\n                Dimension d = getSize();\n                if (d.width != w || d.height != h) {\n                    w = d.width;\n                    h = d.height;\n                    bimg = (BufferedImage) createImage(w, h);\n                    big = bimg.createGraphics();\n                    big.setFont(font);\n                    FontMetrics fm = big.getFontMetrics(font);\n                    ascent = (int) fm.getAscent();\n                    descent = (int) fm.getDescent();\n                }\n                repaint();\n                try {\n                    thread.sleep(sleepAmount);\n                } catch (InterruptedException e) { break; }\n                if (MemoryMonitor4.dateStampCB.isSelected()) {\n                     System.out.println(new Date().toString() + \" \" + usedStr);\n                }\n            }\n            thread = null;\n        }\n    }\n\n\n    // Test thread to consume memory\n    static class Memeater extends ClassLoader implements Runnable {\n\tObject y[];\n\tpublic Memeater() {}\n\tpublic void run() {\n\t    y = new Object[10000000];\n\t    int k =0;\n\t    while(true) {\n\t         if (k == 5000000) k=0;\n\t         y[k++] = new Object();\n\t         try {\n\t\t     Thread.sleep(20);\n\t         } catch (Exception x){}\n\n\t\t // to consume perm gen storage\n\t         try {\n                     // the classes are small so we load 10 at a time\n                     for (int i=0; i<10; i++) {\n                        loadNext();\n                     }\n                 } catch (ClassNotFoundException x) {\n\t\t   // ignore exception\n                 }\n\n\t   }\n\n\t}\n\n\tClass loadNext() throws ClassNotFoundException {\n\n            // public class TestNNNNNN extends java.lang.Object{\n            // public TestNNNNNN();\n            //   Code:\n            //    0:    aload_0\n            //    1:    invokespecial   #1; //Method java/lang/Object.\"<init>\":()V\n            //    4:    return\n            // }\n\n            int begin[] = {\n                0xca, 0xfe, 0xba, 0xbe, 0x00, 0x00, 0x00, 0x30,\n                0x00, 0x0a, 0x0a, 0x00, 0x03, 0x00, 0x07, 0x07,\n                0x00, 0x08, 0x07, 0x00, 0x09, 0x01, 0x00, 0x06,\n                0x3c, 0x69, 0x6e, 0x69, 0x74, 0x3e, 0x01, 0x00,\n                0x03, 0x28, 0x29, 0x56, 0x01, 0x00, 0x04, 0x43,\n                0x6f, 0x64, 0x65, 0x0c, 0x00, 0x04, 0x00, 0x05,\n                0x01, 0x00, 0x0a, 0x54, 0x65, 0x73, 0x74 };\n\n            int end [] = {\n                0x01, 0x00, 0x10,\n                0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e,\n                0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,\n                0x00, 0x21, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00,\n                0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04,\n                0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00,\n                0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,\n                0x00, 0x05, 0x2a, 0xb7, 0x00, 0x01, 0xb1, 0x00,\n                0x00, 0x00, 0x00, 0x00, 0x00 };\n\n\n            // TestNNNNNN\n\n            String name = \"Test\" + Integer.toString(count++);\n\n            byte value[];\n            try {\n                value = name.substring(4).getBytes(\"UTF-8\");\n            } catch (java.io.UnsupportedEncodingException x) {\n                throw new Error();\n            }\n\n            // construct class file\n\n            int len = begin.length + value.length + end.length;\n            byte b[] = new byte[len];\n            int i, pos=0;\n            for (i=0; i<begin.length; i++) {\n                b[pos++] = (byte)begin[i];\n            }\n            for (i=0; i<value.length; i++) {\n                b[pos++] = value[i];\n            }\n            for (i=0; i<end.length; i++) {\n                b[pos++] = (byte)end[i];\n            }\n\n            return defineClass(name, b, 0, b.length);\n\n\t}\n\tstatic int count = 100000;\n\t\n    }\n\t\n    public static void main(String s[]) {\n        final MemoryMonitor4 demo = new MemoryMonitor4();\n        WindowListener l = new WindowAdapter() {\n            public void windowClosing(WindowEvent e) {System.exit(0);}\n            public void windowDeiconified(WindowEvent e) { demo.surf.start(); }\n            public void windowIconified(WindowEvent e) { demo.surf.stop(); }\n        };\n        JFrame f = new JFrame(\"MemoryMonitor\");\n        f.addWindowListener(l);\n        f.getContentPane().add(\"Center\", demo);\n        f.pack();\n        f.setSize(new Dimension(400,500));\n        f.setVisible(true);\n        demo.surf.start();\n\tThread thr = new Thread(new Memeater());\n\tthr.start();\n    }\n\n}\n\n"
  },
  {
    "path": "samples/datasource/src/org/visualvm/demodescriptorprovider/panels/MemoryMonitor5.java",
    "content": "package org.visualvm.demodescriptorprovider.panels;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.awt.image.BufferedImage;\nimport java.awt.geom.Line2D;\nimport java.awt.geom.Rectangle2D;\nimport java.util.Date;\nimport javax.swing.*;\nimport java.lang.management.*;\nimport java.util.*;\n\npublic class MemoryMonitor5 extends JPanel {\n\n    static JCheckBox dateStampCB = new JCheckBox(\"Output Date Stamp\");\n    public Surface surf;\n    JPanel controls;\n    boolean doControls;\n    JTextField tf;\n    // Get memory pools.\n    static java.util.List<MemoryPoolMXBean> mpools = \n        ManagementFactory.getMemoryPoolMXBeans();\n    // Total number of memory pools.\n    static int numPools = 1;\n\n    public MemoryMonitor5() {\n        setLayout(new BorderLayout());\n        add(surf = new Surface());\n        controls = new JPanel();\n        controls.setPreferredSize(new Dimension(135,80));\n        Font font = new Font(\"serif\", Font.PLAIN, 10);\n        JLabel label = new JLabel(\"Sample Rate\");\n        label.setFont(font);\n        label.setForeground(Color.red);\n        controls.add(label);\n        tf = new JTextField(\"1000\");\n        tf.setPreferredSize(new Dimension(45,20));\n        controls.add(tf);\n        controls.add(label = new JLabel(\"ms\"));\n        label.setFont(font);\n        label.setForeground(Color.red);\n        controls.add(dateStampCB);\n        dateStampCB.setFont(font);\n        addMouseListener(new MouseAdapter() {\n            public void mouseClicked(MouseEvent e) {\n               removeAll();\n               if ((doControls = !doControls)) {\n                   surf.stop();\n                   add(controls);\n               } else {\n                   try { \n                       surf.sleepAmount = Long.parseLong(tf.getText().trim());\n                   } catch (Exception ex) {}\n                   surf.start();\n                   add(surf);\n               }\n               validate();\n               repaint();\n            }\n        });\n    }\n\n\n    public class Surface extends JPanel implements Runnable {\n\n        public Thread thread;\n        public long sleepAmount = 1000;\n\tpublic int  usageHistCount = 20000;\n        private int w, h;\n        private BufferedImage bimg;\n        private Graphics2D big;\n        private Font font = new Font(\"Times New Roman\", Font.PLAIN, 11);\n        private int columnInc;\n        private float usedMem[][];\n        private int ptNum[];\n        private int ascent, descent;\n        private Rectangle graphOutlineRect = new Rectangle();\n        private Rectangle2D mfRect = new Rectangle2D.Float();\n        private Rectangle2D muRect = new Rectangle2D.Float();\n        private Line2D graphLine = new Line2D.Float();\n        private Color graphColor = new Color(46, 139, 87);\n        private Color mfColor = new Color(0, 100, 0);\n        private String usedStr;\n      \n\n        public Surface() {\n            setBackground(Color.black);\n            addMouseListener(new MouseAdapter() {\n                public void mouseClicked(MouseEvent e) {\n                    if (thread == null) start(); else stop();\n                }\n            });\n\t    int i = 0;\n\t    usedMem = new float[numPools][];\n\t    ptNum = new int[numPools];\n        }\n\n        public Dimension getMinimumSize() {\n            return getPreferredSize();\n        }\n\n        public Dimension getMaximumSize() {\n            return getPreferredSize();\n        }\n\n        public Dimension getPreferredSize() {\n            return new Dimension(135,80);\n        }\n\n            \n        public void paint(Graphics g) {\n\n            if (big == null) {\n                return;\n            }\n\n            big.setBackground(getBackground());\n            big.clearRect(0,0,w,h);\n\n\n\t    h = h / ((numPools + numPools%2) / 2); \n\t    w = h *3;\n\n\t    int k=0; // index of memory pool.\n\t    for (int i=0; i < 2;i++) {\n\t       for (int j=0; j < (numPools + numPools%2)/ 2; j++) {\n\t         plotMemoryUsage(w*i,h*j,w,h,k);\n\t\t if (++k >= numPools) {\n\t\t    i = 3;\n\t\t    j = (numPools + numPools%2)/ 2;\n\t\t    break;\n\t\t }\n\t       }\n\t    }\n            g.drawImage(bimg, 0, 0, this);\n        }\n\n\tpublic void plotMemoryUsage(int x1, int y1, int x2, int y2, int npool) {\n\n\t    MemoryPoolMXBean mp = mpools.get(4); \n\t    float usedMemory =  mp.getUsage().getUsed();\n            float totalMemory =  mp.getUsage().getMax();\n\n            // .. Draw allocated and used strings ..\n            big.setColor(Color.green);\n\n\t    // Print Max memory allocated for this memory pool.\n            big.drawString(String.valueOf((int)totalMemory/1024) + \"K Max \", x1+4.0f, (float) y1 + ascent+0.5f);\n            big.setColor(Color.yellow);\n\n\t    // Print the memory pool name.\n            //big.drawString(mp.getName(),  x1+x2/2, (float) y1 + ascent+0.5f);\n\n\t    // Print the memory used by this memory pool.\n            usedStr = String.valueOf((int)usedMemory/1024) \n                + \"K used\";\n            big.setColor(Color.green);\n            big.drawString(usedStr, x1+4, y1+y2-descent);\n\n            // Calculate remaining size\n            float ssH = ascent + descent;\n            float remainingHeight = (float) (y2 - (ssH*2) - 0.5f);\n            float blockHeight = remainingHeight/10;\n            float blockWidth = 20.0f;\n            float remainingWidth = (float) (x2 - blockWidth - 10);\n\n            // .. Memory Free ..\n            big.setColor(mfColor);\n            int MemUsage = (int) (((totalMemory - usedMemory) / totalMemory) * 10);\n            int i = 0;\n            for ( ; i < MemUsage ; i++) { \n                mfRect.setRect(x1+5,(float) y1+ssH+i*blockHeight,\n                                blockWidth,(float) blockHeight-1);\n                big.fill(mfRect);\n            }\n\n            // .. Memory Used ..\n            big.setColor(Color.green);\n            for ( ; i < 10; i++)  {\n                muRect.setRect(x1+5,(float) y1 + ssH+i*blockHeight,\n                                blockWidth,(float) blockHeight-1);\n                big.fill(muRect);\n            }\n\n            // .. Draw History Graph ..\n\t    if (remainingWidth <= 30) remainingWidth = (float)30;\n\t    if (remainingHeight <= ssH) remainingHeight = (float)ssH;\n            big.setColor(graphColor);\n            int graphX = x1+30;\n            int graphY = y1 + (int) ssH;\n            int graphW = (int) remainingWidth;\n            int graphH = (int) remainingHeight;\n\n            graphOutlineRect.setRect(graphX, graphY, graphW, graphH);\n            big.draw(graphOutlineRect);\n\n            int graphRow = graphH/10;\n\n            // .. Draw row ..\n            for (int j = graphY; j <= graphH+graphY; j += graphRow) {\n                graphLine.setLine(graphX,j,graphX+graphW,j);\n                big.draw(graphLine);\n            }\n        \n            // .. Draw animated column movement ..\n            int graphColumn = graphW/15;\n\n            if (columnInc == 0) {\n                columnInc = graphColumn;\n            }\n\n            for (int j = graphX+columnInc; j < graphW+graphX; j+=graphColumn) {\n                graphLine.setLine(j,graphY,j,graphY+graphH);\n                big.draw(graphLine);\n            }\n\n            --columnInc;\n\n            // Plot memory usage by this memory pool.\t\n            if (usedMem[npool] == null) {\n\t\tusedMem[npool] = new float[usageHistCount];\n                ptNum[npool] = 0;\n            } \n\n\t    // save memory usage history.\n\t    usedMem[npool][ptNum[npool]] = usedMemory;\n\n            big.setColor(Color.yellow);\n\n\t    int w1; // width of memory usage history.\n\t    if (ptNum[npool] > graphW) {\n\t        w1 = graphW;\n\t    } else {\n\t\tw1 = ptNum[npool]; \n            }\n\n\n            for (int j=graphX+graphW-w1, k=ptNum[npool]-w1; k < ptNum[npool]; \n\t\t\t\t\t\t\t\tk++, j++) {\n                 if (k != 0) {\n                     if (usedMem[npool][k] != usedMem[npool][k-1]) {\n\t\t         int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k-1])/totalMemory));\n\t\t         int h2 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory));\n                         big.drawLine(j-1, h1, j, h2);\n                     } else {\n\t\t         int h1 = (int)(graphY + graphH * ((totalMemory -usedMem[npool][k])/totalMemory));\n                         big.fillRect(j, h1, 1, 1);\n                     }\n                 }\n            }\n            if (ptNum[npool]+2 == usedMem[npool].length) {\n                // throw out oldest point\n                for (int j = 1;j < ptNum[npool]; j++) {\n                     usedMem[npool][j-1] = usedMem[npool][j];\n                }\n                --ptNum[npool];\n            } else {\n                ptNum[npool]++;\n            }\n        }\n\n\n        public void start() {\n            thread = new Thread(this);\n            thread.setPriority(Thread.MIN_PRIORITY);\n            thread.setName(\"MemoryMonitor\");\n            thread.start();\n        }\n\n\n        public synchronized void stop() {\n            thread = null;\n            notify();\n        }\n\n        public void run() {\n\n            Thread me = Thread.currentThread();\n\n            while (thread == me && !isShowing() || getSize().width == 0) {\n                try {\n                    thread.sleep(500);\n                } catch (InterruptedException e) { return; }\n            }\n\t\n            while (thread == me && isShowing()) {\n                Dimension d = getSize();\n                if (d.width != w || d.height != h) {\n                    w = d.width;\n                    h = d.height;\n                    bimg = (BufferedImage) createImage(w, h);\n                    big = bimg.createGraphics();\n                    big.setFont(font);\n                    FontMetrics fm = big.getFontMetrics(font);\n                    ascent = (int) fm.getAscent();\n                    descent = (int) fm.getDescent();\n                }\n                repaint();\n                try {\n                    thread.sleep(sleepAmount);\n                } catch (InterruptedException e) { break; }\n                if (MemoryMonitor5.dateStampCB.isSelected()) {\n                     System.out.println(new Date().toString() + \" \" + usedStr);\n                }\n            }\n            thread = null;\n        }\n    }\n\n\n    // Test thread to consume memory\n    static class Memeater extends ClassLoader implements Runnable {\n\tObject y[];\n\tpublic Memeater() {}\n\tpublic void run() {\n\t    y = new Object[10000000];\n\t    int k =0;\n\t    while(true) {\n\t         if (k == 5000000) k=0;\n\t         y[k++] = new Object();\n\t         try {\n\t\t     Thread.sleep(20);\n\t         } catch (Exception x){}\n\n\t\t // to consume perm gen storage\n\t         try {\n                     // the classes are small so we load 10 at a time\n                     for (int i=0; i<10; i++) {\n                        loadNext();\n                     }\n                 } catch (ClassNotFoundException x) {\n\t\t   // ignore exception\n                 }\n\n\t   }\n\n\t}\n\n\tClass loadNext() throws ClassNotFoundException {\n\n            // public class TestNNNNNN extends java.lang.Object{\n            // public TestNNNNNN();\n            //   Code:\n            //    0:    aload_0\n            //    1:    invokespecial   #1; //Method java/lang/Object.\"<init>\":()V\n            //    4:    return\n            // }\n\n            int begin[] = {\n                0xca, 0xfe, 0xba, 0xbe, 0x00, 0x00, 0x00, 0x30,\n                0x00, 0x0a, 0x0a, 0x00, 0x03, 0x00, 0x07, 0x07,\n                0x00, 0x08, 0x07, 0x00, 0x09, 0x01, 0x00, 0x06,\n                0x3c, 0x69, 0x6e, 0x69, 0x74, 0x3e, 0x01, 0x00,\n                0x03, 0x28, 0x29, 0x56, 0x01, 0x00, 0x04, 0x43,\n                0x6f, 0x64, 0x65, 0x0c, 0x00, 0x04, 0x00, 0x05,\n                0x01, 0x00, 0x0a, 0x54, 0x65, 0x73, 0x74 };\n\n            int end [] = {\n                0x01, 0x00, 0x10,\n                0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e,\n                0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,\n                0x00, 0x21, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00,\n                0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04,\n                0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00,\n                0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,\n                0x00, 0x05, 0x2a, 0xb7, 0x00, 0x01, 0xb1, 0x00,\n                0x00, 0x00, 0x00, 0x00, 0x00 };\n\n\n            // TestNNNNNN\n\n            String name = \"Test\" + Integer.toString(count++);\n\n            byte value[];\n            try {\n                value = name.substring(4).getBytes(\"UTF-8\");\n            } catch (java.io.UnsupportedEncodingException x) {\n                throw new Error();\n            }\n\n            // construct class file\n\n            int len = begin.length + value.length + end.length;\n            byte b[] = new byte[len];\n            int i, pos=0;\n            for (i=0; i<begin.length; i++) {\n                b[pos++] = (byte)begin[i];\n            }\n            for (i=0; i<value.length; i++) {\n                b[pos++] = value[i];\n            }\n            for (i=0; i<end.length; i++) {\n                b[pos++] = (byte)end[i];\n            }\n\n            return defineClass(name, b, 0, b.length);\n\n\t}\n\tstatic int count = 100000;\n\t\n    }\n\t\n    public static void main(String s[]) {\n        final MemoryMonitor5 demo = new MemoryMonitor5();\n        WindowListener l = new WindowAdapter() {\n            public void windowClosing(WindowEvent e) {System.exit(0);}\n            public void windowDeiconified(WindowEvent e) { demo.surf.start(); }\n            public void windowIconified(WindowEvent e) { demo.surf.stop(); }\n        };\n        JFrame f = new JFrame(\"MemoryMonitor\");\n        f.addWindowListener(l);\n        f.getContentPane().add(\"Center\", demo);\n        f.pack();\n        f.setSize(new Dimension(400,500));\n        f.setVisible(true);\n        demo.surf.start();\n\tThread thr = new Thread(new Memeater());\n\tthr.start();\n    }\n\n}\n\n"
  },
  {
    "path": "samples/filtersortsample/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.visualvm.samples.filtersortsample\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.visualvm.samples.filtersortsample.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/filtersortsample/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.visualvm.samples.filtersortsample\nOpenIDE-Module-Layer: org/visualvm/samples/filtersortsample/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/visualvm/samples/filtersortsample/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.0\nOpenIDE-Module-Install: org/visualvm/samples/filtersortsample/Install.class\n\n"
  },
  {
    "path": "samples/filtersortsample/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.visualvm.samples.filtersortsample-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/platform-private.properties\"/>\n    <property file=\"nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/filtersortsample/nbproject/platform.properties",
    "content": "nbplatform.active=VisualVM_Trunk_Build\n"
  },
  {
    "path": "samples/filtersortsample/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "samples/filtersortsample/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.visualvm.samples.filtersortsample</code-name-base>\n            <standalone/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.2</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.7.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "samples/filtersortsample/src/org/visualvm/samples/filtersortsample/Bundle.properties",
    "content": "OpenIDE-Module-Name=FilterSortSample\nOpenIDE-Module-Short-Description=Demo of filtering and sorting nodes in Applications tree\n"
  },
  {
    "path": "samples/filtersortsample/src/org/visualvm/samples/filtersortsample/Controller.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.visualvm.samples.filtersortsample;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.ui.actions.DataSourceAction;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class Controller {\n    \n    private static Controller instance;\n    \n    private ShowHideDSAction showHideDSAction;\n    private boolean dataSourcesHidden;\n    \n    private SortDSAction sortDSAction;\n    private boolean currentSortOrder;\n    \n    \n    public static synchronized Controller instance() {\n        if (instance == null) instance = new Controller();\n        return instance;\n    }\n    \n    public static DataSourceAction showHideDSAction() { return instance().showHideAction(); }\n    \n    public static DataSourceAction sortDSAction() { return instance().sortAction(); }\n\n    \n    private synchronized DataSourceAction showHideAction() {\n        if (showHideDSAction == null) showHideDSAction = new ShowHideDSAction();\n        return showHideDSAction;\n    }\n    \n    private synchronized DataSourceAction sortAction() {\n        if (sortDSAction == null) sortDSAction = new SortDSAction();\n        return sortDSAction;\n    }\n    \n    \n    private static void filterDataSources(boolean visible) {\n        Set<DataSource> dataSources = DataSource.ROOT.getRepository().getDataSources();\n        for (DataSource dataSource : dataSources)\n            if (!(dataSource instanceof FilterSortRootNode))\n                dataSource.setVisible(visible);\n    }\n    \n    private static void sortDataSources(final boolean sortOrder) {\n        Set<DataSource> dataSources = FilterSortRootNode.sharedInstance().getRepository().getDataSources();\n        List<FilterSortNode.FilterSortDescriptorProvider.FilterSortDescriptor> descriptors = new ArrayList(dataSources.size());\n        for (DataSource dataSource : dataSources)\n            descriptors.add((FilterSortNode.FilterSortDescriptorProvider.FilterSortDescriptor)DataSourceDescriptorFactory.getDescriptor(dataSource));\n        Collections.sort(descriptors, new Comparator<DataSourceDescriptor>() {\n            public int compare(DataSourceDescriptor dsd1, DataSourceDescriptor dsd2) {\n                String name1 = dsd1.getName();\n                Integer int1 = Integer.decode(name1.substring(name1.lastIndexOf(\"@\") + 1));\n                String name2 = dsd2.getName();\n                Integer int2 = Integer.decode(name2.substring(name1.lastIndexOf(\"@\") + 1));\n                return sortOrder ? int2.compareTo(int1) : int1.compareTo(int2);\n            }\n        });\n        for (int i = 0; i < descriptors.size(); i++) descriptors.get(i).changePreferredPosition(i);\n    }\n    \n    \n    \n    private class ShowHideDSAction extends SingleDataSourceAction<FilterSortRootNode> {\n\n        protected void actionPerformed(FilterSortRootNode arg0, ActionEvent arg1) {\n            filterDataSources(dataSourcesHidden);\n            dataSourcesHidden = !dataSourcesHidden;\n            updateName();\n        }\n\n        protected boolean isEnabled(FilterSortRootNode arg0) { return true; }\n        \n        \n        private void updateName() {\n            putValue(NAME, dataSourcesHidden ? \"Reset Filter\" : \"Filter Out DataSources\");\n        }\n\n\n        ShowHideDSAction() {\n            super(FilterSortRootNode.class);\n            updateName();\n        }\n\n    }\n    \n    private class SortDSAction extends SingleDataSourceAction<FilterSortRootNode> {\n\n        protected void actionPerformed(FilterSortRootNode arg0, ActionEvent arg1) {\n            sortDataSources(currentSortOrder);\n            currentSortOrder = !currentSortOrder;\n            updateName();\n        }\n\n        protected boolean isEnabled(FilterSortRootNode arg0) { return true; }\n        \n        \n        private void updateName() {\n            putValue(NAME, currentSortOrder ? \"Sort Descending\" : \"Sort Ascending\");\n        }\n\n\n        SortDSAction() {\n            super(FilterSortRootNode.class);\n            updateName();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "samples/filtersortsample/src/org/visualvm/samples/filtersortsample/FilterSortNode.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.visualvm.samples.filtersortsample;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport java.awt.Image;\nimport org.openide.util.Utilities;\n\n/**\n * \n * @author Jiri Sedlacek\n */\npublic class FilterSortNode extends DataSource {\n    \n    private static FilterSortDescriptorProvider descriptorProvider;\n    \n    \n    private FilterSortNode() {}\n    \n    \n    static synchronized void initialize() {\n        if (descriptorProvider != null) return;\n        descriptorProvider = new FilterSortDescriptorProvider();\n        DataSourceDescriptorFactory.getDefault().registerProvider(descriptorProvider);\n        for (int i = 0; i < 10; i++)\n            FilterSortRootNode.sharedInstance().getRepository().addDataSource(new FilterSortNode());\n    }\n    \n    static synchronized void uninitialize() {\n        if (descriptorProvider == null) return;\n        FilterSortRootNode.sharedInstance().getRepository().removeDataSources(\n                FilterSortRootNode.sharedInstance().getRepository().getDataSources());\n        DataSourceDescriptorFactory.getDefault().unregisterProvider(descriptorProvider);\n        descriptorProvider = null;\n    }\n    \n    \n    static class FilterSortDescriptorProvider extends AbstractModelProvider<DataSourceDescriptor, DataSource> {\n    \n        public DataSourceDescriptor createModelFor(DataSource ds) {\n            if (ds instanceof FilterSortNode) return new FilterSortDescriptor((FilterSortNode)ds);\n            else return null;\n        }\n\n        static class FilterSortDescriptor extends DataSourceDescriptor {\n            private static final Image NODE_ICON =\n                    Utilities.loadImage(\"org/graalvm/visualvm/core/ui/resources/busy-icon5.png\", true);  // NOI18N\n\n            FilterSortDescriptor(FilterSortNode node) {\n                super(node, \"FilterSortDemo @\" + node.hashCode(), null, NODE_ICON,\n                        Positionable.POSITION_LAST, EXPAND_ON_EACH_NEW_CHILD); // NOI18N\n            }\n            \n            void changePreferredPosition(int position) {\n                setPreferredPosition(position);\n            }\n\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "samples/filtersortsample/src/org/visualvm/samples/filtersortsample/FilterSortRootNode.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.visualvm.samples.filtersortsample;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport java.awt.Image;\nimport org.openide.util.Utilities;\n\n/**\n * \n * @author Jiri Sedlacek\n */\npublic class FilterSortRootNode extends DataSource {\n    \n    private static FilterSortRootNode sharedInstance;\n    private static FilterSortRootDescriptorProvider descriptorProvider;\n    \n    \n    public static synchronized FilterSortRootNode sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new FilterSortRootNode();\n        return sharedInstance;\n    }\n    \n    \n    private FilterSortRootNode() {}\n    \n    \n    static synchronized void initialize() {\n        if (descriptorProvider != null) return;\n        descriptorProvider = new FilterSortRootDescriptorProvider();\n        DataSourceDescriptorFactory.getDefault().registerProvider(descriptorProvider);\n    }\n    \n    static synchronized void uninitialize() {\n        if (descriptorProvider == null) return;\n        DataSourceDescriptorFactory.getDefault().unregisterProvider(descriptorProvider);\n        descriptorProvider = null;\n    }\n    \n    \n    private static class FilterSortRootDescriptorProvider extends AbstractModelProvider<DataSourceDescriptor, DataSource> {\n    \n        public DataSourceDescriptor createModelFor(DataSource ds) {\n            if (FilterSortRootNode.sharedInstance().equals(ds)) return new FilterSortRootDescriptor();\n            else return null;\n        }\n\n        private static class FilterSortRootDescriptor extends DataSourceDescriptor {\n            private static final Image NODE_ICON = Utilities.loadImage(\"org/graalvm/visualvm/core/ui/resources/idle-icon.png\", true);  // NOI18N\n\n            FilterSortRootDescriptor() {\n                super(FilterSortRootNode.sharedInstance(), \"FilterSortDemo\", null, NODE_ICON, Positionable.POSITION_LAST, EXPAND_ON_EACH_NEW_CHILD); // NOI18N\n            }\n\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "samples/filtersortsample/src/org/visualvm/samples/filtersortsample/Install.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.visualvm.samples.filtersortsample;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.openide.modules.ModuleInstall;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class Install extends ModuleInstall {\n\n    public void restored() {\n        FilterSortRootNode.initialize();\n        DataSource.ROOT.getRepository().addDataSource(FilterSortRootNode.sharedInstance());\n        FilterSortNode.initialize();\n    }\n    \n    public void uninstalled() {\n        FilterSortNode.uninitialize();\n        DataSource.ROOT.getRepository().removeDataSource(FilterSortRootNode.sharedInstance());\n        FilterSortRootNode.uninitialize();\n    }\n    \n}\n"
  },
  {
    "path": "samples/filtersortsample/src/org/visualvm/samples/filtersortsample/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    \n    <folder name=\"VisualVM\">\n        <folder name=\"ExplorerPopupSelection\">\n            \n            <file name=\"org-visualvm-samples-filtersortsample-showHideDSAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.visualvm.samples.filtersortsample.Controller.showHideDSAction\"/>\n                <attr name=\"position\" intvalue=\"10\"/>\n            </file>\n            \n            <file name=\"org-visualvm-samples-filtersortsample-sortDSAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.visualvm.samples.filtersortsample.Controller.sortDSAction\"/>\n                <attr name=\"position\" intvalue=\"20\"/>\n            </file>\n            \n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "samples/hellovvm/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.hellovisualvm\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.hellovisualvm.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/hellovvm/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.hellovisualvm\nOpenIDE-Module-Install: org/hellovisualvm/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/hellovisualvm/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.0\n\n"
  },
  {
    "path": "samples/hellovvm/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.hellovisualvm-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/platform-private.properties\"/>\n    <property file=\"nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/hellovvm/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=39de642e\nbuild.xml.script.CRC32=6d5d9819\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=39de642e\nnbproject/build-impl.xml.script.CRC32=7d66f016\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "samples/hellovvm/nbproject/platform.properties",
    "content": "nbplatform.active=VisualVM_1.0_RC_\n"
  },
  {
    "path": "samples/hellovvm/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "samples/hellovvm/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.hellovisualvm</code-name-base>\n            <standalone/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "samples/hellovvm/src/org/hellovisualvm/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=VisualVM\nOpenIDE-Module-Long-Description=\\\n    Sample plugin displaying \"Hello World\" scenario: a new tab for all applications.\nOpenIDE-Module-Name=VisualVM-HelloWorld\nOpenIDE-Module-Short-Description=Plugin displaying \"Hello World\" tab.\n"
  },
  {
    "path": "samples/hellovvm/src/org/hellovisualvm/HelloWorldView.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.hellovisualvm;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport javax.swing.JEditorPane;\nimport javax.swing.JPanel;\nimport org.openide.util.Utilities;\n\npublic class HelloWorldView extends DataSourceView {\n\n    private DataViewComponent dvc;\n    //Make sure there is an image at this location in your project:\n    private static final String IMAGE_PATH = \"org/hellovisualvm/coredump.png\"; // NOI18N\n\n    public HelloWorldView(Application Application) {\n        //closeable/not = last boolean (closebale views for thread/heap/Application\n        super(Application,\"Hello World\", new ImageIcon(Utilities.loadImage(IMAGE_PATH, true)).getImage(), 60, false);\n    }\n\n    protected DataViewComponent createComponent() {\n\n        //Data area for master view:\n        JEditorPane generalDataArea = new JEditorPane();\n        generalDataArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n        //Panel, which we'll reuse in all four of our detail views for this sample:\n        JPanel panel = new JPanel();\n\n        //Master view:\n        DataViewComponent.MasterView masterView = new DataViewComponent.MasterView(\"Hello World Overview\", null, generalDataArea);\n\n        //Configuration of master view:\n        DataViewComponent.MasterViewConfiguration masterConfiguration =\n                new DataViewComponent.MasterViewConfiguration(false);\n\n        //Add the master view and configuration view to the component:\n        dvc = new DataViewComponent(masterView, masterConfiguration);\n\n        //Add detail views to the component:\n        dvc.addDetailsView(new DataViewComponent.DetailsView(\n                \"Hello World Details 1\", null, 10, panel, null), DataViewComponent.TOP_LEFT);\n\n        return dvc;\n\n    }\n}\n"
  },
  {
    "path": "samples/hellovvm/src/org/hellovisualvm/HelloWorldViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.hellovisualvm;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\n\npublic class HelloWorldViewProvider extends DataSourceViewProvider<Application> {\n\n    private static DataSourceViewProvider<Application> instance = new HelloWorldViewProvider();\n\n    @Override\n    public boolean supportsViewFor(Application application) {\n        //Always shown:\n        return true;\n    }\n\n    @Override\n    protected DataSourceView createView(Application application) {\n        return new HelloWorldView(application);\n    }\n\n    static void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(instance, Application.class);\n    }\n\n    static void unregister() {\n        DataSourceViewsManager.sharedInstance().removeViewProvider(instance);\n    }\n}\n"
  },
  {
    "path": "samples/hellovvm/src/org/hellovisualvm/Installer.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.hellovisualvm;\n\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\npublic class Installer extends ModuleInstall {\n\n    @Override\n    public void restored() {\n        HelloWorldViewProvider.initialize();\n    }\n\n    @Override\n    public void uninstalled() {\n        HelloWorldViewProvider.unregister();\n    }\n}\n"
  },
  {
    "path": "samples/hostcompare/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.nb.hostcompare\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.nb.hostcompare.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/hostcompare/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.nb.hostcompare\nOpenIDE-Module-Install: org/nb/hostcompare/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/nb/hostcompare/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.0\n\n"
  },
  {
    "path": "samples/hostcompare/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.nb.hostcompare-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/platform-private.properties\"/>\n    <property file=\"nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/hostcompare/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=f099da30\nbuild.xml.script.CRC32=1582346c\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=f099da30\nnbproject/build-impl.xml.script.CRC32=0e633cc7\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "samples/hostcompare/nbproject/platform.properties",
    "content": "nbplatform.active=VisualVM_1.0_RC_\n"
  },
  {
    "path": "samples/hostcompare/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "samples/hostcompare/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.nb.hostcompare</code-name-base>\n            <standalone/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <implementation-version/>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "samples/hostcompare/src/org/nb/hostcompare/Bundle.properties",
    "content": "OpenIDE-Module-Name=VisualVM-HostViewSysProps\n"
  },
  {
    "path": "samples/hostcompare/src/org/nb/hostcompare/HostView.java",
    "content": "\npackage org.nb.hostcompare;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.host.Host;\nimport java.util.Iterator;\nimport java.util.Properties;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport javax.swing.JEditorPane;\nimport org.openide.util.Utilities;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\n\npublic class HostView extends DataSourceView {\n\n    private DataViewComponent dvc;\n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/coredump/resources/coredump.png\"; // NOI18N\n\n    private Host host;\n    private Jvm jvm;\n\n    public HostView(Host host) {\n        super(host, \"Host\", new ImageIcon(Utilities.loadImage(IMAGE_PATH, true)).getImage(), 60, false);\n        this.host = host;\n    }\n\n    @Override\n    protected DataViewComponent createComponent() {\n\n        //Data area for master view:\n        JEditorPane generalDataArea = new JEditorPane();\n        generalDataArea.setText(\"Below you see the system properties of\" +\n                \" all running apps!\");\n        generalDataArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n        //Master view:\n        DataViewComponent.MasterView masterView =\n                new DataViewComponent.MasterView(\"All System Properties\",\n                null, generalDataArea);\n\n        //Configuration of master view:\n        DataViewComponent.MasterViewConfiguration masterConfiguration =\n                new DataViewComponent.MasterViewConfiguration(false);\n\n        //Add the master view and configuration view to the component:\n        dvc = new DataViewComponent(masterView, masterConfiguration);\n\n        //Get all the applications deployed to the host:\n        Set apps = host.getRepository().getDataSources(Application.class);\n\n        //Get the iterator:\n        Iterator it = apps.iterator();\n\n        //Set count to zero:\n        int count = 0;\n\n        //Iterate through our applications:\n        while (it.hasNext()) {\n\n            //Increase the count:\n            count = count + 1;\n\n            //Now we have our application:\n            Application app = (Application) it.next();\n\n            //Get the process id:\n            String pid = count + \": \" + (String.valueOf(app.getPid()));\n\n            //Get the system properties:\n            Properties jvmProperties = null;\n            jvm = JvmFactory.getJVMFor(app);\n            if (jvm.isGetSystemPropertiesSupported()) {\n                jvmProperties = jvm.getSystemProperties();\n            }\n\n            //Extrapolate the name from the type:\n            ApplicationType appType = ApplicationTypeFactory.getApplicationTypeFor(app);\n            String appName = appType.getName();\n\n            //Put the first application top left:\n            if (count == 1) {\n\n                dvc.addDetailsView(new SystemPropertiesViewSupport(jvmProperties).getDetailsView(app, appName), DataViewComponent.TOP_LEFT);\n\n//            //Put the second application top right:\n            } else if (count == 2) {\n                dvc.addDetailsView(new SystemPropertiesViewSupport(jvmProperties).getDetailsView(app, appName), DataViewComponent.TOP_RIGHT);\n\n//\n//            //Put the third application bottom left:    \n            } else if (count == 3) {\n                dvc.addDetailsView(new SystemPropertiesViewSupport(jvmProperties).getDetailsView(app, appName), DataViewComponent.BOTTOM_LEFT);\n\n            //Put the fourth application bottom right:        \n            } else if (count == 4) {\n                dvc.addDetailsView(new SystemPropertiesViewSupport(jvmProperties).getDetailsView(app, appName), DataViewComponent.BOTTOM_RIGHT);\n\n            //Put all other applications bottom right, \n            //which creates tabs within the bottom right tab    \n            } else {\n                dvc.addDetailsView(new SystemPropertiesViewSupport(jvmProperties).getDetailsView(app, appName), DataViewComponent.BOTTOM_RIGHT);\n            }\n\n        }\n\n        return dvc;\n\n    }\n}\n"
  },
  {
    "path": "samples/hostcompare/src/org/nb/hostcompare/HostViewProvider.java",
    "content": "\npackage org.nb.hostcompare;\n\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\nimport org.graalvm.visualvm.host.Host;\nimport java.util.Set;\n\npublic class HostViewProvider extends PluggableDataSourceViewProvider<Host> {\n\n    private static DataSourceViewProvider<Host> instance = new HostViewProvider();\n\n    @Override\n    public boolean supportsViewFor(Host MyHost) {\n        //Always shown:\n        return true;\n    }\n\n    @Override\n    public synchronized DataSourceView createView(final Host MyHost) {\n        return new HostView(MyHost);\n    }\n\n    static void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(instance, Host.class);\n    }\n\n    static void unregister() {\n        DataSourceViewsManager.sharedInstance().removeViewProvider(instance);\n    }\n\n    @Override\n    public Set<Integer> getPluggableLocations(DataSourceView arg0) {\n        return ALL_LOCATIONS;\n    }\n}\n\n"
  },
  {
    "path": "samples/hostcompare/src/org/nb/hostcompare/HostViewSupport.java",
    "content": "\npackage org.nb.hostcompare;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\n\npublic class HostViewSupport {\n\n    private static HostViewSupport instance;\n    private HostViewProvider HostPluggableView = new HostViewProvider();\n\n    public static synchronized HostViewSupport getInstance() {\n        if (instance == null) {\n            instance = new HostViewSupport();\n        }\n        return instance;\n    }\n\n    public PluggableDataSourceViewProvider getApplicationPluggableView() {\n        return HostPluggableView;\n    }\n\n    public HostViewSupport() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(HostPluggableView, Application.class);\n    }\n}\n\n"
  },
  {
    "path": "samples/hostcompare/src/org/nb/hostcompare/Installer.java",
    "content": "\npackage org.nb.hostcompare;\n\nimport org.openide.modules.ModuleInstall;\n\npublic class Installer extends ModuleInstall {\n\n    @Override\n    public void restored() {\n        HostViewProvider.initialize();\n    }\n\n    @Override\n    public void uninstalled() {\n        HostViewProvider.unregister();\n    }\n}\n"
  },
  {
    "path": "samples/hostcompare/src/org/nb/hostcompare/SystemPropertiesViewSupport.java",
    "content": "package org.nb.hostcompare;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.NotSupportedDisplayer;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport java.awt.BorderLayout;\nimport java.awt.Image;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Properties;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\n\npublic class SystemPropertiesViewSupport extends JPanel {\n\n    public SystemPropertiesViewSupport(Properties properties) {\n        initComponents(properties);\n    }\n\n    public DataViewComponent.DetailsView getDetailsView(Application app, String appName) {\n        Image icon = DataSourceDescriptorFactory.getDescriptor(app).getIcon();\n        JLabel label = wrap(icon);\n        JComponent[] options = {label};\n        String text = app.getPid() + \": \" + appName;\n        return new DataViewComponent.DetailsView(text, null, 20, this, options);    // NOI18N\n\n    }\n\n    private JLabel wrap(Image image) {\n        ImageIcon icon = new ImageIcon(image);\n        JLabel label = new JLabel(icon, JLabel.CENTER);\n        return label;\n    }\n\n    private void initComponents(Properties properties) {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n\n        JComponent contents;\n\n        if (properties != null) {\n            HTMLTextArea area = new HTMLTextArea(\"<nobr>\" + formatSystemProperties(properties) + \"</nobr>\");    // NOI18N\n\n            area.setCaretPosition(0);\n            area.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n            contents = area;\n        } else {\n            contents = new NotSupportedDisplayer(NotSupportedDisplayer.JVM);\n        }\n\n        add(new ScrollableContainer(contents), BorderLayout.CENTER);\n    }\n\n    private String formatSystemProperties(Properties properties) {\n        StringBuffer text = new StringBuffer(200);\n        List keys = new ArrayList(properties.keySet());\n        Iterator keyIt;\n\n        Collections.sort(keys);\n        keyIt = keys.iterator();\n        while (keyIt.hasNext()) {\n            String key = (String) keyIt.next();\n            String val = properties.getProperty(key);\n\n            text.append(\"<b>\"); // NOI18N\n\n            text.append(key);\n            text.append(\"</b>=\");   // NOI18N\n\n            text.append(val);\n            text.append(\"<br>\");    // NOI18N\n\n        }\n        return text.toString();\n    }\n}\n"
  },
  {
    "path": "samples/jvmcap/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.jvmcap\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.jvmcap.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/jvmcap/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.modules.jvmcap\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/jvmcap/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/jvmcap/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.1\n\n"
  },
  {
    "path": "samples/jvmcap/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.jvmcap-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/platform-private.properties\"/>\n    <property file=\"nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/jvmcap/nbproject/platform.properties",
    "content": "nbjdk.active=default\nnbplatform.active=VisualVM_2.0\n"
  },
  {
    "path": "samples/jvmcap/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jiri Sedlacek\n"
  },
  {
    "path": "samples/jvmcap/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.jvmcap</code-name-base>\n            <standalone/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application.views</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.53</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.13</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "samples/jvmcap/src/org/graalvm/visualvm/modules/jvmcap/ApplicationSnapshotViewPluginProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jvmcap;\n\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.application.views.ApplicationViewsSupport;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ApplicationSnapshotViewPluginProvider extends DataSourceViewPluginProvider<ApplicationSnapshot> {\n\n    protected DataSourceViewPlugin createPlugin(ApplicationSnapshot snapshot) {\n        return new JvmCapabilitiesViewPlugin(snapshot, JvmCapabilitiesModel.create(snapshot));\n    }\n    \n    protected boolean supportsPluginFor(ApplicationSnapshot snapshot) {\n        return true;\n    }\n    \n    \n    private ApplicationSnapshotViewPluginProvider() {\n    }\n    \n    \n    static void initialize() {\n        ApplicationViewsSupport.sharedInstance().getSnapshotOverviewView().\n                registerPluginProvider(new ApplicationSnapshotViewPluginProvider());\n    }\n    \n}\n"
  },
  {
    "path": "samples/jvmcap/src/org/graalvm/visualvm/modules/jvmcap/ApplicationViewPluginProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jvmcap;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.application.views.ApplicationViewsSupport;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ApplicationViewPluginProvider extends DataSourceViewPluginProvider<Application> {\n\n    protected DataSourceViewPlugin createPlugin(Application application) {\n        return new JvmCapabilitiesViewPlugin(application, JvmCapabilitiesModel.create(application));\n    }\n    \n    protected boolean supportsPluginFor(Application t) {\n        return true;\n    }\n    \n    protected boolean supportsSavePluginFor(Application application, Class<? extends Snapshot> snapshotClass) {\n        return ApplicationSnapshot.class.isAssignableFrom(snapshotClass);\n    }\n    \n    protected void savePlugin(Application application, Snapshot snapshot) {\n        JvmCapabilitiesViewPlugin view = (JvmCapabilitiesViewPlugin)getCachedPlugin(application);\n        if (view != null) view.getModel().save(snapshot);\n        else JvmCapabilitiesModel.create(application).save(snapshot);\n    }\n    \n    \n    private ApplicationViewPluginProvider() {\n    }\n    \n    \n    static void initialize() {\n        ApplicationViewsSupport.sharedInstance().getOverviewView().\n                registerPluginProvider(new ApplicationViewPluginProvider());\n    }\n\n}\n"
  },
  {
    "path": "samples/jvmcap/src/org/graalvm/visualvm/modules/jvmcap/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Tools\nOpenIDE-Module-Long-Description=\\\n    Sample plugin displaying JVM capabilities in Overview tab. \\\n    It shows how default tabs can be extended by plugins. \\\n    Plugin view can be saved into Application Snapshot and later restored.\nOpenIDE-Module-Name=VisualVM-JvmCapabilities\nOpenIDE-Module-Short-Description=Plugin displaying JVM capabilities in Overview tab\n"
  },
  {
    "path": "samples/jvmcap/src/org/graalvm/visualvm/modules/jvmcap/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jvmcap;\n\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\nfinal class Installer extends ModuleInstall {\n    public void restored() {\n        ApplicationViewPluginProvider.initialize();\n        ApplicationSnapshotViewPluginProvider.initialize();\n    }\n}\n"
  },
  {
    "path": "samples/jvmcap/src/org/graalvm/visualvm/modules/jvmcap/JvmCapabilitiesModel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jvmcap;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JvmCapabilitiesModel {\n    \n    private static final String PROP_PREFIX = \"JvmCapabilitiesModel_\";\n    \n    static final String SNAPSHOT_VERSION = PROP_PREFIX + \"version\";\n    private static final String SNAPSHOT_VERSION_DIVIDER = \".\";\n    private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = \"1\";\n    private static final String CURRENT_SNAPSHOT_VERSION_MINOR = \"0\";\n    private static final String CURRENT_SNAPSHOT_VERSION = CURRENT_SNAPSHOT_VERSION_MAJOR + SNAPSHOT_VERSION_DIVIDER + CURRENT_SNAPSHOT_VERSION_MINOR;\n    \n    public static final String PROP_IS_ATTACHABLE = PROP_PREFIX + \"is_attachable\";\n    public static final String PROP_BASIC_INFO_SUPPORTED = PROP_PREFIX + \"basic_info_supported\";\n    public static final String PROP_MONITORING_SUPPORTED = PROP_PREFIX + \"monitoring_supported\";\n    public static final String PROP_CLASS_MONITORING_SUPPORTED = PROP_PREFIX + \"class_monitoring_supported\";\n    public static final String PROP_THREAD_MONITORING_SUPPORTED = PROP_PREFIX + \"thread_monitoring_supported\";\n    public static final String PROP_MEMORY_MONITORING_SUPPORTED = PROP_PREFIX + \"memory_monitoring_supported\";\n    public static final String PROP_CPU_MONITORING_SUPPORTED = PROP_PREFIX + \"cpu_monitoring_supported\";\n    public static final String PROP_COLLECTIONTIME_MONITORING_SUPPORTED = PROP_PREFIX + \"collection_monitoring_supported\";\n    public static final String PROP_GET_SYSTEM_PROPERTIES_SUPPORTED = PROP_PREFIX + \"get_system_properties_supported\";\n    public static final String PROP_DUMP_ON_OOM_SUPPORTED = PROP_PREFIX + \"dump_on_oom_supported\";\n    public static final String PROP_TAKE_HEAP_DUMP_SUPPORTED = PROP_PREFIX + \"take_heap_dump_supported\";\n    public static final String PROP_TAKE_THREAD_DUMP_SUPPORTED = PROP_PREFIX + \"take_thread_dump_supported\";\n    \n    private static final String VAL_TRUE = \"yes\";\n    private static final String VAL_FALSE = \"no\";\n    private static final String VAL_UNKNOWN = \"&lt;unknown&gt;\";\n    \n    private boolean initialized;\n    private DataSource source;\n    \n    private String isAttachable;\n    private String isBasicInfoSupported;\n    private String isMonitoringSupported;\n    private String isClassMonitoringSupported;\n    private String isThreadMonitoringSupported;\n    private String isMemoryMonitoringSupported;\n    private String isCpuMonitoringSupported;\n    private String isCollectionTimeMonitoringSupported;\n    private String isGetSystemPropertiesSupported;\n    private String isDumpOnOOMSupported;\n    private String isTakeHeapDumpSupported;\n    private String isTakeThreadDumpSupported;    \n    \n    static JvmCapabilitiesModel create(Application application) {\n        JvmCapabilitiesModel model = new JvmCapabilitiesModel();\n        model.initialized = false;\n        model.source = application;\n        return model;\n    }\n    \n    static JvmCapabilitiesModel create(Snapshot snapshot) {\n        JvmCapabilitiesModel model = new JvmCapabilitiesModel();\n        model.initialized = false;\n        model.source = snapshot;\n        return model;\n    }\n    \n    \n    synchronized void initialize() {\n        if (initialized) return;\n        initialized = true;\n        if (source instanceof Application) initialize((Application)source);\n        else if (source instanceof ApplicationSnapshot) initialize((Snapshot)source);\n        else throw new IllegalStateException(\"Cannot initialize model for \" + source);\n    }\n    \n    void save(Snapshot snapshot) {\n        initialize();\n        Storage storage = snapshot.getStorage();\n        \n        storage.setCustomProperty(SNAPSHOT_VERSION, CURRENT_SNAPSHOT_VERSION);\n        storage.setCustomProperty(PROP_IS_ATTACHABLE, isAttachable);\n        storage.setCustomProperty(PROP_BASIC_INFO_SUPPORTED, isBasicInfoSupported);\n        storage.setCustomProperty(PROP_MONITORING_SUPPORTED, isMonitoringSupported);\n        storage.setCustomProperty(PROP_CLASS_MONITORING_SUPPORTED, isClassMonitoringSupported);\n        storage.setCustomProperty(PROP_THREAD_MONITORING_SUPPORTED, isThreadMonitoringSupported);\n        storage.setCustomProperty(PROP_MEMORY_MONITORING_SUPPORTED, isMemoryMonitoringSupported);\n        storage.setCustomProperty(PROP_CPU_MONITORING_SUPPORTED, isCpuMonitoringSupported);\n        storage.setCustomProperty(PROP_COLLECTIONTIME_MONITORING_SUPPORTED, isCollectionTimeMonitoringSupported);\n        storage.setCustomProperty(PROP_GET_SYSTEM_PROPERTIES_SUPPORTED, isGetSystemPropertiesSupported);\n        storage.setCustomProperty(PROP_DUMP_ON_OOM_SUPPORTED, isDumpOnOOMSupported);\n        storage.setCustomProperty(PROP_TAKE_HEAP_DUMP_SUPPORTED, isTakeHeapDumpSupported);\n        storage.setCustomProperty(PROP_TAKE_THREAD_DUMP_SUPPORTED, isTakeThreadDumpSupported);\n    }\n    \n    \n    String isAttachable() { return isAttachable; }\n    String isBasicInfoSupported() { return isBasicInfoSupported; }\n    String isMonitoringSupported() { return isMonitoringSupported; }\n    String isClassMonitoringSupported() { return isClassMonitoringSupported; }\n    String isThreadMonitoringSupported() { return isThreadMonitoringSupported; }\n    String isMemoryMonitoringSupported() { return isMemoryMonitoringSupported; }\n    String isCpuMonitoringSupported() { return isCpuMonitoringSupported; }\n    String isCollectionTimeMonitoringSupported() { return isCollectionTimeMonitoringSupported; }\n    String isGetSystemPropertiesSupported() { return isGetSystemPropertiesSupported; }\n    String isDumpOnOOMSupported() { return isDumpOnOOMSupported; }\n    String isTakeHeapDumpSupported() { return isTakeHeapDumpSupported; }\n    String isTakeThreadDumpSupported() { return isTakeThreadDumpSupported; }\n    \n    \n    private void initialize(Application application) {\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        \n        isAttachable = getValue(jvm.isAttachable());\n        isBasicInfoSupported = getValue(jvm.isBasicInfoSupported());\n        isMonitoringSupported = getValue(jvm.isMonitoringSupported());\n        isClassMonitoringSupported = getValue(jvm.isClassMonitoringSupported());\n        isThreadMonitoringSupported = getValue(jvm.isThreadMonitoringSupported());\n        isMemoryMonitoringSupported = getValue(jvm.isMemoryMonitoringSupported());\n        isCpuMonitoringSupported = getValue(jvm.isCpuMonitoringSupported());\n        isCollectionTimeMonitoringSupported = getValue(jvm.isCollectionTimeSupported());\n        isGetSystemPropertiesSupported = getValue(jvm.isGetSystemPropertiesSupported());\n        isDumpOnOOMSupported = getValue(jvm.isDumpOnOOMEnabledSupported());\n        isTakeHeapDumpSupported = getValue(jvm.isTakeHeapDumpSupported());\n        isTakeThreadDumpSupported = getValue(jvm.isTakeThreadDumpSupported());\n    }\n    \n    private void initialize(Snapshot snapshot) {\n        Storage storage = snapshot.getStorage();\n        \n        isAttachable = getValue(storage, PROP_IS_ATTACHABLE);\n        isBasicInfoSupported = getValue(storage, PROP_BASIC_INFO_SUPPORTED);\n        isMonitoringSupported = getValue(storage, PROP_MONITORING_SUPPORTED);\n        isClassMonitoringSupported = getValue(storage, PROP_CLASS_MONITORING_SUPPORTED);\n        isThreadMonitoringSupported = getValue(storage, PROP_THREAD_MONITORING_SUPPORTED);\n        isMemoryMonitoringSupported = getValue(storage, PROP_MEMORY_MONITORING_SUPPORTED);\n        isCpuMonitoringSupported = getValue(storage, PROP_CPU_MONITORING_SUPPORTED);\n        isCollectionTimeMonitoringSupported = getValue(storage, PROP_COLLECTIONTIME_MONITORING_SUPPORTED);\n        isGetSystemPropertiesSupported = getValue(storage, PROP_GET_SYSTEM_PROPERTIES_SUPPORTED);\n        isDumpOnOOMSupported = getValue(storage, PROP_DUMP_ON_OOM_SUPPORTED);\n        isTakeHeapDumpSupported = getValue(storage, PROP_TAKE_HEAP_DUMP_SUPPORTED);\n        isTakeThreadDumpSupported = getValue(storage, PROP_TAKE_THREAD_DUMP_SUPPORTED);\n    }\n    \n    private static String getValue(boolean boolValue) {\n        return boolValue ? VAL_TRUE : VAL_FALSE;\n    }\n    \n    private static String getValue(Storage storage, String property) {\n        String val = storage.getCustomProperty(property);\n        return val != null ? val : VAL_UNKNOWN;\n    }\n    \n    \n    private JvmCapabilitiesModel() {\n    }\n\n}\n"
  },
  {
    "path": "samples/jvmcap/src/org/graalvm/visualvm/modules/jvmcap/JvmCapabilitiesViewComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jvmcap;\n\nimport java.awt.BorderLayout;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JvmCapabilitiesViewComponent extends JPanel {\n\n    public JvmCapabilitiesViewComponent(JvmCapabilitiesModel model) {\n        initComponents(model);\n    }\n    \n    \n    private void initComponents(JvmCapabilitiesModel model) {\n        HTMLTextArea dataArea = new HTMLTextArea(\"<nobr>\" + content(model) + \"</nobr>\");\n        \n        setLayout(new BorderLayout());\n        dataArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n        setBackground(dataArea.getBackground());\n        add(dataArea, BorderLayout.CENTER);\n    }\n    \n    \n    private static String content(JvmCapabilitiesModel model) {\n        StringBuilder builder = new StringBuilder();\n        \n        builder.append(\"<b>Attachable:</b> \" + model.isAttachable() + \"<br>\");\n        builder.append(\"<b>Basic info supported:</b> \" + model.isBasicInfoSupported() + \"<br>\");\n        builder.append(\"<b>System properties supported:</b> \" + model.isGetSystemPropertiesSupported() + \"<br>\");\n        builder.append(\"<b>Monitoring supported:</b> \" + model.isMonitoringSupported() + \"<br>\");\n        builder.append(\"<b>CPU monitoring supported:</b> \" + model.isCpuMonitoringSupported() + \"<br>\");\n        builder.append(\"<b>Memory monitoring supported:</b> \" + model.isMemoryMonitoringSupported() + \"<br>\");\n        builder.append(\"<b>GC activity monitoring supported:</b> \" + model.isCollectionTimeMonitoringSupported() + \"<br>\");\n        builder.append(\"<b>Class monitoring supported:</b> \" + model.isClassMonitoringSupported() + \"<br>\");\n        builder.append(\"<b>Thread monitoring supported:</b> \" + model.isThreadMonitoringSupported() + \"<br>\");\n        builder.append(\"<b>Thread dump supported:</b> \" + model.isTakeThreadDumpSupported() + \"<br>\");\n        builder.append(\"<b>Heap dump supported:</b> \" + model.isTakeHeapDumpSupported() + \"<br>\");\n        builder.append(\"<b>Heap dump on OOME supported:</b> \" + model.isDumpOnOOMSupported() + \"<br>\");\n        \n        return builder.toString();\n    }\n\n}\n"
  },
  {
    "path": "samples/jvmcap/src/org/graalvm/visualvm/modules/jvmcap/JvmCapabilitiesViewPlugin.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.jvmcap;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JvmCapabilitiesViewPlugin extends DataSourceViewPlugin {\n    \n    private JvmCapabilitiesModel model;\n    \n\n    public DataViewComponent.DetailsView createView(int location) {\n        switch (location) {\n            case DataViewComponent.TOP_RIGHT:\n                return new DataViewComponent.DetailsView(\"JVM capabilities\", null, 30,\n                        new ScrollableContainer(new JvmCapabilitiesViewComponent(model)), null);\n            default: return null;\n        }\n    }\n    \n    \n    protected void willBeAdded() {\n        model.initialize();\n    }\n    \n    \n    JvmCapabilitiesModel getModel() {\n        return model;\n    }\n    \n    \n    JvmCapabilitiesViewPlugin(DataSource dataSource, JvmCapabilitiesModel model) {\n        super(dataSource);\n        this.model = model;\n    }\n\n}\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"pluggableViewDemoSuite\" basedir=\".\">\n    <description>Builds the module suite pluggableViewDemoSuite.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldPluggableView/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.hellovisualvm\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.hellovisualvm.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldPluggableView/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.hellovisualvm\nOpenIDE-Module-Localizing-Bundle: org/hellovisualvm/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.0\n\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldPluggableView/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.hellovisualvm-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldPluggableView/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=279792e6\nbuild.xml.script.CRC32=6d5d9819\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=279792e6\nnbproject/build-impl.xml.script.CRC32=e7ddc77a\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldPluggableView/nbproject/platform.properties",
    "content": "nbplatform.active=VisualVM_1.0_RC_\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldPluggableView/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldPluggableView/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.hellovisualvm</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application.views</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.10.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.hellovisualvm</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldPluggableView/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldPluggableView/src/org/hellovisualvm/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=VisualVM\nOpenIDE-Module-Long-Description=\\\n    Sample plugin displaying \"Hello World\" scenario: a new tab for all applications.\nOpenIDE-Module-Name=VisualVM-HelloWorld\nOpenIDE-Module-Short-Description=Plugin displaying \"Hello World\" tab.\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldPluggableView/src/org/hellovisualvm/HelloWorldView.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.hellovisualvm;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport javax.swing.JEditorPane;\nimport javax.swing.JPanel;\nimport org.openide.util.Utilities;\n\npublic class HelloWorldView extends DataSourceView {\n\n    private DataViewComponent dvc;\n    //Make sure there is an image at this location in your project:\n    private static final String IMAGE_PATH = \"org/hellovisualvm/coredump.png\"; // NOI18N\n\n    public HelloWorldView(Application Application) {\n        //closeable/not = last boolean (closebale views for thread/heap/Application\n        super(Application,\"Hello World\", new ImageIcon(Utilities.loadImage(IMAGE_PATH, true)).getImage(), 60, false);\n    }\n\n    protected DataViewComponent createComponent() {\n\n        //Data area for master view:\n        JEditorPane generalDataArea = new JEditorPane();\n        generalDataArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n        //Panel, which we'll reuse in all four of our detail views for this sample:\n        JPanel panel = new JPanel();\n\n        //Master view:\n        DataViewComponent.MasterView masterView = new DataViewComponent.MasterView(\"Hello World Overview\", null, generalDataArea);\n\n        //Configuration of master view:\n        DataViewComponent.MasterViewConfiguration masterConfiguration =\n                new DataViewComponent.MasterViewConfiguration(false);\n\n        //Add the master view and configuration view to the component:\n        dvc = new DataViewComponent(masterView, masterConfiguration);\n\n        //Add detail views to the component:\n        dvc.addDetailsView(new DataViewComponent.DetailsView(\n                \"Hello World Details 1\", null, 10, panel, null), DataViewComponent.TOP_LEFT);\n\n        return dvc;\n\n    }\n}\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldPluggableView/src/org/hellovisualvm/HelloWorldViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.hellovisualvm;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\nimport java.util.Set;\n\npublic class HelloWorldViewProvider extends PluggableDataSourceViewProvider<Application> {\n\n    private static DataSourceViewProvider<Application> instance = new HelloWorldViewProvider();\n\n    @Override\n    public boolean supportsViewFor(Application application) {\n        //Always shown:\n        return true;\n    }\n\n    @Override\n    protected DataSourceView createView(Application application) {\n        return new HelloWorldView(application);\n    }\n\n    static void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(instance, Application.class);\n    }\n\n    static void unregister() {\n        DataSourceViewsManager.sharedInstance().removeViewProvider(instance);\n    }\n\n    @Override\n    public Set<Integer> getPluggableLocations(DataSourceView arg0) {\n        return ALL_LOCATIONS;\n    }\n}\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldPluggableView/src/org/hellovisualvm/HelloWorldViewSupport.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.hellovisualvm;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\n\n/**\n *\n * @author geertjan\n */\npublic class HelloWorldViewSupport {\n\n    private static HelloWorldViewSupport instance;\n\n    private HelloWorldViewProvider helloWorldPluggableView = new HelloWorldViewProvider();\n\n\n    public static synchronized HelloWorldViewSupport getInstance() {\n        if (instance == null) {\n            instance = new HelloWorldViewSupport();\n        }\n        return instance;\n    }\n\n    public PluggableDataSourceViewProvider getApplicationPluggableView() {\n        return helloWorldPluggableView;\n    }\n\n    public HelloWorldViewSupport() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(helloWorldPluggableView, Application.class);\n    }\n\n}\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldViewPlugin/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.netbeans.helloworldplugin\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.netbeans.helloworldplugin.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldViewPlugin/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.netbeans.helloworldplugin\nOpenIDE-Module-Install: org/netbeans/helloworldplugin/Installer.class\nOpenIDE-Module-Layer: org/netbeans/helloworldplugin/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/netbeans/helloworldplugin/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.0\n\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldViewPlugin/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.netbeans.helloworldplugin-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldViewPlugin/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=8c83fe47\nbuild.xml.script.CRC32=ffcee3ea\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=8c83fe47\nnbproject/build-impl.xml.script.CRC32=bee5e9c4\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldViewPlugin/nbproject/platform.properties",
    "content": "# Deprecated since 5.0u1; for compatibility with 5.0:\ndisabled.clusters=\nenabled.clusters=\\\n    platform9,\\\n    profiler3,\\\n    visualvm\nnbplatform.active=VisualVM_1.1\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldViewPlugin/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldViewPlugin/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.netbeans.helloworldplugin</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application.views</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0-1</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.coredump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.heapdump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.threaddump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.hellovisualvm</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.10.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldViewPlugin/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldViewPlugin/src/org/netbeans/helloworldplugin/Bundle.properties",
    "content": "OpenIDE-Module-Name=helloWorldPlugin\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldViewPlugin/src/org/netbeans/helloworldplugin/HelloWorldViewPlugin.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.netbeans.helloworldplugin;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport javax.swing.JPanel;\n\n/**\n *\n * @author geertjan\n */\npublic class HelloWorldViewPlugin extends DataSourceViewPlugin {\n\n    HelloWorldViewPlugin(Application application) {\n        super(application);\n    }\n\n    public DataViewComponent.DetailsView createView(int location) {\n        switch (location) {\n            case DataViewComponent.TOP_RIGHT:\n                JPanel panel = new JPanel();\n                return new DataViewComponent.DetailsView(\"I'm plugged in from outside!\", null, 30,\n                        new ScrollableContainer(panel), null);\n            default:\n                return null;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldViewPlugin/src/org/netbeans/helloworldplugin/HelloWorldViewPluginProvider.java",
    "content": "package org.netbeans.helloworldplugin;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider;\nimport org.hellovisualvm.HelloWorldViewSupport;\n\nclass HelloWorldViewPluginProvider extends DataSourceViewPluginProvider<Application> {\n\n    protected DataSourceViewPlugin createPlugin(Application application) {\n        return new HelloWorldViewPlugin(application);\n    }\n\n    protected boolean supportsPluginFor(Application application) {\n        return true;\n    }\n\n    static void initialize() {\n      HelloWorldViewSupport.getInstance().getApplicationPluggableView().registerPluginProvider(new HelloWorldViewPluginProvider());\n    }\n\n    static void uninitialize() {\n        HelloWorldViewSupport.getInstance().getApplicationPluggableView().unregisterPluginProvider(new HelloWorldViewPluginProvider());\n    }\n}\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldViewPlugin/src/org/netbeans/helloworldplugin/Installer.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.netbeans.helloworldplugin;\n\nimport org.openide.modules.ModuleInstall;\n\npublic class Installer extends ModuleInstall {\n\n    @Override\n    public void restored() {\n       HelloWorldViewPluginProvider.initialize();\n    }\n\n    @Override\n    public void uninstalled() {\n        HelloWorldViewPluginProvider.uninitialize();\n    }\n}\n\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/helloWorldViewPlugin/src/org/netbeans/helloworldplugin/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n</filesystem>\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"pluggableViewDemoSuite-impl\" basedir=\"..\" xmlns:sproject=\"http://www.netbeans.org/ns/nb-module-suite-project/1\">\n    <property file=\"nbproject/private/platform-private.properties\"/>\n    <property file=\"nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-suite-project/1\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <sproject:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\"/>\n    <sproject:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/suite.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=fda63b4c\nbuild.xml.script.CRC32=136cd841\nbuild.xml.stylesheet.CRC32=531c622b\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=fda63b4c\nnbproject/build-impl.xml.script.CRC32=ce2d7732\nnbproject/build-impl.xml.stylesheet.CRC32=196c7090\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/nbproject/platform.properties",
    "content": "# Deprecated since 5.0u1; for compatibility with 5.0:\ndisabled.clusters=\nenabled.clusters=\\\n    platform9,\\\n    profiler3,\\\n    visualvm\nnbplatform.active=VisualVM_1.1\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/nbproject/project.properties",
    "content": "modules=\\\n    ${project.org.hellovisualvm}:\\\n    ${project.org.netbeans.helloworldplugin}\nproject.org.hellovisualvm=helloWorldPluggableView\nproject.org.netbeans.helloworldplugin=helloWorldViewPlugin\n"
  },
  {
    "path": "samples/pluggableViewDemoSuite/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project.suite</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-suite-project/1\">\n            <name>pluggableViewDemoSuite</name>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "samples/sampleBundle/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.nb.samplebundle\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.nb.samplebundle.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/sampleBundle/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.nb.samplebundle\nOpenIDE-Module-Layer: org/nb/samplebundle/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/nb/samplebundle/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.0\n\n"
  },
  {
    "path": "samples/sampleBundle/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.nb.samplebundle-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/platform-private.properties\"/>\n    <property file=\"nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/sampleBundle/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=0a5b831b\nbuild.xml.script.CRC32=47053a63\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=0a5b831b\nnbproject/build-impl.xml.script.CRC32=bc4fe686\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "samples/sampleBundle/nbproject/platform.properties",
    "content": "nbplatform.active=default\n"
  },
  {
    "path": "samples/sampleBundle/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "samples/sampleBundle/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.nb.samplebundle</code-name-base>\n            <standalone/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.14</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.projectuiapi</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.29.0.6</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.1.0.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.6</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/Bundle.properties",
    "content": "OpenIDE-Module-Name=sampleBundle\nTemplates/Project/Samples/VisualVM/hellovvmProject.zip=Hello World\nTemplates/Project/Samples/VisualVM/pluggableViewDemoSuiteProject.zip=Pluggable View\nTemplates/Project/Samples/VisualVM/apptypeProject.zip=Application Type\nTemplates/Project/Samples/VisualVM/datasourceProject.zip=Data Source\nTemplates/Project/Samples/VisualVM/hostviewProject.zip=JVM Comparison\nTemplates/Project/Samples/VisualVM/jvmcapsProject.zip=JVM Capabilities\nTemplates/Project/Samples/VisualVM/subnodesProject.zip=Explorer Subnodes\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/apptype/Bundle.properties",
    "content": "LBL_CreateProjectStep=Name and Location\napptypePanelVisual.browseButton.text=Br&owse...\napptypePanelVisual.projectLocationLabel.text=Project &Location:\napptypePanelVisual.projectNameLabel.text=Project &Name:\napptypePanelVisual.createdFolderLabel.text=Project &Folder:\napptypePanelVisual.browseButton.actionCommand=BROWSE\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/apptype/apptypeDescription.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n        Gives you a sample application type\n        for VisualVM, for the\n        NetBeans sample Anagram Game.\n    </body>\n</html>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/apptype/apptypePanelVisual.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.5\" maxVersion=\"1.6\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"browseButton\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectNameTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectLocationLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"browseButton\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"createdFolderLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace pref=\"213\" max=\"32767\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"projectNameLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectNameTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/apptype/Bundle.properties\" key=\"apptypePanelVisual.projectNameLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectNameTextField\">\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"projectLocationLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectLocationTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/apptype/Bundle.properties\" key=\"apptypePanelVisual.projectLocationLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectLocationTextField\">\n    </Component>\n    <Component class=\"javax.swing.JButton\" name=\"browseButton\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/apptype/Bundle.properties\" key=\"apptypePanelVisual.browseButton.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n        <Property name=\"actionCommand\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/apptype/Bundle.properties\" key=\"apptypePanelVisual.browseButton.actionCommand\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"browseButtonActionPerformed\"/>\n      </Events>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"createdFolderLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"createdFolderTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/apptype/Bundle.properties\" key=\"apptypePanelVisual.createdFolderLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"createdFolderTextField\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/apptype/apptypePanelVisual.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.nb.samplebundle.apptype;\n\nimport java.io.File;\nimport javax.swing.JFileChooser;\nimport javax.swing.JPanel;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.Document;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.filesystems.FileUtil;\n\npublic class apptypePanelVisual extends JPanel implements DocumentListener {\n\n    public static final String PROP_PROJECT_NAME = \"projectName\";\n\n    private apptypeWizardPanel panel;\n\n    public apptypePanelVisual(apptypeWizardPanel panel) {\n        initComponents();\n        this.panel = panel;\n        // Register listener on the textFields to make the automatic updates\n        projectNameTextField.getDocument().addDocumentListener(this);\n        projectLocationTextField.getDocument().addDocumentListener(this);\n    }\n\n    public String getProjectName() {\n        return this.projectNameTextField.getText();\n    }\n\n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        projectNameLabel = new javax.swing.JLabel();\n        projectNameTextField = new javax.swing.JTextField();\n        projectLocationLabel = new javax.swing.JLabel();\n        projectLocationTextField = new javax.swing.JTextField();\n        browseButton = new javax.swing.JButton();\n        createdFolderLabel = new javax.swing.JLabel();\n        createdFolderTextField = new javax.swing.JTextField();\n\n        projectNameLabel.setLabelFor(projectNameTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectNameLabel, org.openide.util.NbBundle.getMessage(apptypePanelVisual.class, \"apptypePanelVisual.projectNameLabel.text\")); // NOI18N\n\n        projectLocationLabel.setLabelFor(projectLocationTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectLocationLabel, org.openide.util.NbBundle.getMessage(apptypePanelVisual.class, \"apptypePanelVisual.projectLocationLabel.text\")); // NOI18N\n\n        org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(apptypePanelVisual.class, \"apptypePanelVisual.browseButton.text\")); // NOI18N\n        browseButton.setActionCommand(org.openide.util.NbBundle.getMessage(apptypePanelVisual.class, \"apptypePanelVisual.browseButton.actionCommand\")); // NOI18N\n        browseButton.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                browseButtonActionPerformed(evt);\n            }\n        });\n\n        createdFolderLabel.setLabelFor(createdFolderTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(createdFolderLabel, org.openide.util.NbBundle.getMessage(apptypePanelVisual.class, \"apptypePanelVisual.createdFolderLabel.text\")); // NOI18N\n\n        createdFolderTextField.setEditable(false);\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(createdFolderLabel))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(browseButton)\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)\n                    .addComponent(browseButton))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(createdFolderLabel)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addContainerGap(213, Short.MAX_VALUE))\n        );\n    }// </editor-fold>//GEN-END:initComponents\n\n    private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed\n        String command = evt.getActionCommand();\n        if (\"BROWSE\".equals(command)) {\n            JFileChooser chooser = new JFileChooser();\n            FileUtil.preventFileChooserSymlinkTraversal(chooser, null);\n            chooser.setDialogTitle(\"Select Project Location\");\n            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\n            String path = this.projectLocationTextField.getText();\n            if (path.length() > 0) {\n                File f = new File(path);\n                if (f.exists()) {\n                    chooser.setSelectedFile(f);\n                }\n            }\n            if (JFileChooser.APPROVE_OPTION == chooser.showOpenDialog(this)) {\n                File projectDir = chooser.getSelectedFile();\n                projectLocationTextField.setText(FileUtil.normalizeFile(projectDir).getAbsolutePath());\n            }\n            panel.fireChangeEvent();\n        }\n\n    }//GEN-LAST:event_browseButtonActionPerformed\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JButton browseButton;\n    private javax.swing.JLabel createdFolderLabel;\n    private javax.swing.JTextField createdFolderTextField;\n    private javax.swing.JLabel projectLocationLabel;\n    private javax.swing.JTextField projectLocationTextField;\n    private javax.swing.JLabel projectNameLabel;\n    private javax.swing.JTextField projectNameTextField;\n    // End of variables declaration//GEN-END:variables\n\n    @Override\n    public void addNotify() {\n        super.addNotify();\n        //same problem as in 31086, initial focus on Cancel button\n        projectNameTextField.requestFocus();\n    }\n\n    boolean valid(WizardDescriptor wizardDescriptor) {\n\n        if (projectNameTextField.getText().length() == 0) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Name is not a valid folder name.\");\n            return false; // Display name not specified\n\n        }\n        File f = FileUtil.normalizeFile(new File(projectLocationTextField.getText()).getAbsoluteFile());\n        if (!f.isDirectory()) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n        final File destFolder = FileUtil.normalizeFile(new File(createdFolderTextField.getText()).getAbsoluteFile());\n\n        File projLoc = destFolder;\n        while (projLoc != null && !projLoc.exists()) {\n            projLoc = projLoc.getParentFile();\n        }\n        if (projLoc == null || !projLoc.canWrite()) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder cannot be created.\");\n            return false;\n        }\n\n        if (FileUtil.toFileObject(projLoc) == null) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n\n        File[] kids = destFolder.listFiles();\n        if (destFolder.exists() && kids != null && kids.length > 0) {\n            // Folder exists and is not empty\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder already exists and is not empty.\");\n            return false;\n        }\n        wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", \"\");\n        return true;\n    }\n\n    void store(WizardDescriptor d) {\n        String name = projectNameTextField.getText().trim();\n        String folder = createdFolderTextField.getText().trim();\n\n        d.putProperty(\"projdir\", new File(folder));\n        d.putProperty(\"name\", name);\n    }\n\n    void read(WizardDescriptor settings) {\n        File projectLocation = (File) settings.getProperty(\"projdir\");\n        if (projectLocation == null || projectLocation.getParentFile() == null || !projectLocation.getParentFile().isDirectory()) {\n            projectLocation = ProjectChooser.getProjectsFolder();\n        } else {\n            projectLocation = projectLocation.getParentFile();\n        }\n        this.projectLocationTextField.setText(projectLocation.getAbsolutePath());\n\n        String projectName = (String) settings.getProperty(\"name\");\n        if (projectName == null) {\n            projectName = \"apptype\";\n        }\n        this.projectNameTextField.setText(projectName);\n        this.projectNameTextField.selectAll();\n    }\n\n    void validate(WizardDescriptor d) throws WizardValidationException {\n        // nothing to validate\n    }\n\n    // Implementation of DocumentListener --------------------------------------\n    public void changedUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void insertUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void removeUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    /** Handles changes in the Project name and project directory, */\n    private void updateTexts(DocumentEvent e) {\n\n        Document doc = e.getDocument();\n\n        if (doc == projectNameTextField.getDocument() || doc == projectLocationTextField.getDocument()) {\n            // Change in the project name\n\n            String projectName = projectNameTextField.getText();\n            String projectFolder = projectLocationTextField.getText();\n\n            //if (projectFolder.trim().length() == 0 || projectFolder.equals(oldName)) {\n            createdFolderTextField.setText(projectFolder + File.separatorChar + projectName);\n        //}\n\n        }\n        panel.fireChangeEvent(); // Notify that the panel changed\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/apptype/apptypeWizardIterator.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.apptype;\n\nimport java.awt.Component;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.text.MessageFormat;\nimport java.util.Enumeration;\nimport java.util.LinkedHashSet;\nimport java.util.NoSuchElementException;\nimport java.util.Set;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\nimport javax.swing.JComponent;\nimport javax.swing.event.ChangeListener;\nimport org.netbeans.api.project.ProjectManager;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.netbeans.spi.project.ui.templates.support.Templates;\nimport org.openide.WizardDescriptor;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.xml.XMLUtil;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.NodeList;\nimport org.xml.sax.InputSource;\n\npublic class apptypeWizardIterator implements WizardDescriptor./*Progress*/InstantiatingIterator {\n\n    private int index;\n    private WizardDescriptor.Panel[] panels;\n    private WizardDescriptor wiz;\n\n    public apptypeWizardIterator() {\n    }\n\n    public static apptypeWizardIterator createIterator() {\n        return new apptypeWizardIterator();\n    }\n\n    private WizardDescriptor.Panel[] createPanels() {\n        return new WizardDescriptor.Panel[]{\n                    new apptypeWizardPanel(),\n                };\n    }\n\n    private String[] createSteps() {\n        return new String[]{\n                    NbBundle.getMessage(apptypeWizardIterator.class, \"LBL_CreateProjectStep\")\n                };\n    }\n\n    public Set/*<FileObject>*/ instantiate(/*ProgressHandle handle*/) throws IOException {\n        Set<FileObject> resultSet = new LinkedHashSet<FileObject>();\n        File dirF = FileUtil.normalizeFile((File) wiz.getProperty(\"projdir\"));\n        dirF.mkdirs();\n\n        FileObject template = Templates.getTemplate(wiz);\n        FileObject dir = FileUtil.toFileObject(dirF);\n        unZipFile(template.getInputStream(), dir);\n\n        // Always open top dir as a project:\n        resultSet.add(dir);\n        // Look for nested projects to open as well:\n        Enumeration<? extends FileObject> e = dir.getFolders(true);\n        while (e.hasMoreElements()) {\n            FileObject subfolder = e.nextElement();\n            if (ProjectManager.getDefault().isProject(subfolder)) {\n                resultSet.add(subfolder);\n            }\n        }\n\n        File parent = dirF.getParentFile();\n        if (parent != null && parent.exists()) {\n            ProjectChooser.setProjectsFolder(parent);\n        }\n\n        return resultSet;\n    }\n\n    public void initialize(WizardDescriptor wiz) {\n        this.wiz = wiz;\n        index = 0;\n        panels = createPanels();\n        // Make sure list of steps is accurate.\n        String[] steps = createSteps();\n        for (int i = 0; i < panels.length; i++) {\n            Component c = panels[i].getComponent();\n            if (steps[i] == null) {\n                // Default step name to component name of panel.\n                // Mainly useful for getting the name of the target\n                // chooser to appear in the list of steps.\n                steps[i] = c.getName();\n            }\n            if (c instanceof JComponent) { // assume Swing components\n\n                JComponent jc = (JComponent) c;\n                // Step #.\n                jc.putClientProperty(\"WizardPanel_contentSelectedIndex\", new Integer(i));\n                // Step name (actually the whole list for reference).\n                jc.putClientProperty(\"WizardPanel_contentData\", steps);\n            }\n        }\n    }\n\n    public void uninitialize(WizardDescriptor wiz) {\n        this.wiz.putProperty(\"projdir\", null);\n        this.wiz.putProperty(\"name\", null);\n        this.wiz = null;\n        panels = null;\n    }\n\n    public String name() {\n        return MessageFormat.format(\"{0} of {1}\",\n                new Object[]{new Integer(index + 1), new Integer(panels.length)});\n    }\n\n    public boolean hasNext() {\n        return index < panels.length - 1;\n    }\n\n    public boolean hasPrevious() {\n        return index > 0;\n    }\n\n    public void nextPanel() {\n        if (!hasNext()) {\n            throw new NoSuchElementException();\n        }\n        index++;\n    }\n\n    public void previousPanel() {\n        if (!hasPrevious()) {\n            throw new NoSuchElementException();\n        }\n        index--;\n    }\n\n    public WizardDescriptor.Panel current() {\n        return panels[index];\n    }\n\n    // If nothing unusual changes in the middle of the wizard, simply:\n    public final void addChangeListener(ChangeListener l) {\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n    }\n\n    private static void unZipFile(InputStream source, FileObject projectRoot) throws IOException {\n        try {\n            ZipInputStream str = new ZipInputStream(source);\n            ZipEntry entry;\n            while ((entry = str.getNextEntry()) != null) {\n                if (entry.isDirectory()) {\n                    FileUtil.createFolder(projectRoot, entry.getName());\n                } else {\n                    FileObject fo = FileUtil.createData(projectRoot, entry.getName());\n                    if (\"nbproject/project.xml\".equals(entry.getName())) {\n                        // Special handling for setting name of Ant-based projects; customize as needed:\n                        filterProjectXML(fo, str, projectRoot.getName());\n                    } else {\n                        writeFile(str, fo);\n                    }\n                }\n            }\n        } finally {\n            source.close();\n        }\n    }\n\n    private static void writeFile(ZipInputStream str, FileObject fo) throws IOException {\n        OutputStream out = fo.getOutputStream();\n        try {\n            FileUtil.copy(str, out);\n        } finally {\n            out.close();\n        }\n    }\n\n    private static void filterProjectXML(FileObject fo, ZipInputStream str, String name) throws IOException {\n        try {\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            FileUtil.copy(str, baos);\n            Document doc = XMLUtil.parse(new InputSource(new ByteArrayInputStream(baos.toByteArray())), false, false, null, null);\n            NodeList nl = doc.getDocumentElement().getElementsByTagName(\"name\");\n            if (nl != null) {\n                for (int i = 0; i < nl.getLength(); i++) {\n                    Element el = (Element) nl.item(i);\n                    if (el.getParentNode() != null && \"data\".equals(el.getParentNode().getNodeName())) {\n                        NodeList nl2 = el.getChildNodes();\n                        if (nl2.getLength() > 0) {\n                            nl2.item(0).setNodeValue(name);\n                        }\n                        break;\n                    }\n                }\n            }\n            OutputStream out = fo.getOutputStream();\n            try {\n                XMLUtil.write(doc, out, \"UTF-8\");\n            } finally {\n                out.close();\n            }\n        } catch (Exception ex) {\n            Exceptions.printStackTrace(ex);\n            writeFile(str, fo);\n        }\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/apptype/apptypeWizardPanel.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.apptype;\n\nimport java.awt.Component;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\n\n/**\n * Panel just asking for basic info.\n */\npublic class apptypeWizardPanel implements WizardDescriptor.Panel,\n        WizardDescriptor.ValidatingPanel, WizardDescriptor.FinishablePanel {\n\n    private WizardDescriptor wizardDescriptor;\n    private apptypePanelVisual component;\n\n    public apptypeWizardPanel() {\n    }\n\n    public Component getComponent() {\n        if (component == null) {\n            component = new apptypePanelVisual(this);\n            component.setName(NbBundle.getMessage(apptypeWizardPanel.class, \"LBL_CreateProjectStep\"));\n        }\n        return component;\n    }\n\n    public HelpCtx getHelp() {\n        return new HelpCtx(apptypeWizardPanel.class);\n    }\n\n    public boolean isValid() {\n        getComponent();\n        return component.valid(wizardDescriptor);\n    }\n    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0\n\n\n    public final void addChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.add(l);\n        }\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.remove(l);\n        }\n    }\n\n    protected final void fireChangeEvent() {\n        Set<ChangeListener> ls;\n        synchronized (listeners) {\n            ls = new HashSet<ChangeListener>(listeners);\n        }\n        ChangeEvent ev = new ChangeEvent(this);\n        for (ChangeListener l : ls) {\n            l.stateChanged(ev);\n        }\n    }\n\n    public void readSettings(Object settings) {\n        wizardDescriptor = (WizardDescriptor) settings;\n        component.read(wizardDescriptor);\n    }\n\n    public void storeSettings(Object settings) {\n        WizardDescriptor d = (WizardDescriptor) settings;\n        component.store(d);\n    }\n\n    public boolean isFinishPanel() {\n        return true;\n    }\n\n    public void validate() throws WizardValidationException {\n        getComponent();\n        component.validate(wizardDescriptor);\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/datasource/Bundle.properties",
    "content": "LBL_CreateProjectStep=Name and Location\ndatasourcePanelVisual.projectLocationLabel.text=Project &Location:\ndatasourcePanelVisual.projectNameLabel.text=Project &Name:\ndatasourcePanelVisual.createdFolderLabel.text=Project &Folder:\ndatasourcePanelVisual.browseButton.actionCommand=BROWSE\ndatasourcePanelVisual.browseButton.text=Br&owse...\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/datasource/datasourceDescription.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n        Gives you a sample data source\n        for the System Monitor application,\n        taken from the JDK's sources.\n    </body>\n</html>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/datasource/datasourcePanelVisual.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.5\" maxVersion=\"1.6\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"browseButton\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectNameTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectLocationLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"browseButton\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"createdFolderLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace pref=\"213\" max=\"32767\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"projectNameLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectNameTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/datasource/Bundle.properties\" key=\"datasourcePanelVisual.projectNameLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectNameTextField\">\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"projectLocationLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectLocationTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/datasource/Bundle.properties\" key=\"datasourcePanelVisual.projectLocationLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectLocationTextField\">\n    </Component>\n    <Component class=\"javax.swing.JButton\" name=\"browseButton\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/datasource/Bundle.properties\" key=\"datasourcePanelVisual.browseButton.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n        <Property name=\"actionCommand\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/datasource/Bundle.properties\" key=\"datasourcePanelVisual.browseButton.actionCommand\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"browseButtonActionPerformed\"/>\n      </Events>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"createdFolderLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"createdFolderTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/datasource/Bundle.properties\" key=\"datasourcePanelVisual.createdFolderLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"createdFolderTextField\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/datasource/datasourcePanelVisual.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.nb.samplebundle.datasource;\n\nimport java.io.File;\nimport javax.swing.JFileChooser;\nimport javax.swing.JPanel;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.Document;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.filesystems.FileUtil;\n\npublic class datasourcePanelVisual extends JPanel implements DocumentListener {\n\n    public static final String PROP_PROJECT_NAME = \"projectName\";\n\n    private datasourceWizardPanel panel;\n\n    public datasourcePanelVisual(datasourceWizardPanel panel) {\n        initComponents();\n        this.panel = panel;\n        // Register listener on the textFields to make the automatic updates\n        projectNameTextField.getDocument().addDocumentListener(this);\n        projectLocationTextField.getDocument().addDocumentListener(this);\n    }\n\n    public String getProjectName() {\n        return this.projectNameTextField.getText();\n    }\n\n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        projectNameLabel = new javax.swing.JLabel();\n        projectNameTextField = new javax.swing.JTextField();\n        projectLocationLabel = new javax.swing.JLabel();\n        projectLocationTextField = new javax.swing.JTextField();\n        browseButton = new javax.swing.JButton();\n        createdFolderLabel = new javax.swing.JLabel();\n        createdFolderTextField = new javax.swing.JTextField();\n\n        projectNameLabel.setLabelFor(projectNameTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectNameLabel, org.openide.util.NbBundle.getMessage(datasourcePanelVisual.class, \"datasourcePanelVisual.projectNameLabel.text\")); // NOI18N\n\n        projectLocationLabel.setLabelFor(projectLocationTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectLocationLabel, org.openide.util.NbBundle.getMessage(datasourcePanelVisual.class, \"datasourcePanelVisual.projectLocationLabel.text\")); // NOI18N\n\n        org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(datasourcePanelVisual.class, \"datasourcePanelVisual.browseButton.text\")); // NOI18N\n        browseButton.setActionCommand(org.openide.util.NbBundle.getMessage(datasourcePanelVisual.class, \"datasourcePanelVisual.browseButton.actionCommand\")); // NOI18N\n        browseButton.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                browseButtonActionPerformed(evt);\n            }\n        });\n\n        createdFolderLabel.setLabelFor(createdFolderTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(createdFolderLabel, org.openide.util.NbBundle.getMessage(datasourcePanelVisual.class, \"datasourcePanelVisual.createdFolderLabel.text\")); // NOI18N\n\n        createdFolderTextField.setEditable(false);\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(createdFolderLabel))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(browseButton)\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)\n                    .addComponent(browseButton))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(createdFolderLabel)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addContainerGap(213, Short.MAX_VALUE))\n        );\n    }// </editor-fold>//GEN-END:initComponents\n\n    private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed\n        String command = evt.getActionCommand();\n        if (\"BROWSE\".equals(command)) {\n            JFileChooser chooser = new JFileChooser();\n            FileUtil.preventFileChooserSymlinkTraversal(chooser, null);\n            chooser.setDialogTitle(\"Select Project Location\");\n            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\n            String path = this.projectLocationTextField.getText();\n            if (path.length() > 0) {\n                File f = new File(path);\n                if (f.exists()) {\n                    chooser.setSelectedFile(f);\n                }\n            }\n            if (JFileChooser.APPROVE_OPTION == chooser.showOpenDialog(this)) {\n                File projectDir = chooser.getSelectedFile();\n                projectLocationTextField.setText(FileUtil.normalizeFile(projectDir).getAbsolutePath());\n            }\n            panel.fireChangeEvent();\n        }\n\n    }//GEN-LAST:event_browseButtonActionPerformed\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JButton browseButton;\n    private javax.swing.JLabel createdFolderLabel;\n    private javax.swing.JTextField createdFolderTextField;\n    private javax.swing.JLabel projectLocationLabel;\n    private javax.swing.JTextField projectLocationTextField;\n    private javax.swing.JLabel projectNameLabel;\n    private javax.swing.JTextField projectNameTextField;\n    // End of variables declaration//GEN-END:variables\n\n    @Override\n    public void addNotify() {\n        super.addNotify();\n        //same problem as in 31086, initial focus on Cancel button\n        projectNameTextField.requestFocus();\n    }\n\n    boolean valid(WizardDescriptor wizardDescriptor) {\n\n        if (projectNameTextField.getText().length() == 0) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Name is not a valid folder name.\");\n            return false; // Display name not specified\n\n        }\n        File f = FileUtil.normalizeFile(new File(projectLocationTextField.getText()).getAbsoluteFile());\n        if (!f.isDirectory()) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n        final File destFolder = FileUtil.normalizeFile(new File(createdFolderTextField.getText()).getAbsoluteFile());\n\n        File projLoc = destFolder;\n        while (projLoc != null && !projLoc.exists()) {\n            projLoc = projLoc.getParentFile();\n        }\n        if (projLoc == null || !projLoc.canWrite()) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder cannot be created.\");\n            return false;\n        }\n\n        if (FileUtil.toFileObject(projLoc) == null) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n\n        File[] kids = destFolder.listFiles();\n        if (destFolder.exists() && kids != null && kids.length > 0) {\n            // Folder exists and is not empty\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder already exists and is not empty.\");\n            return false;\n        }\n        wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", \"\");\n        return true;\n    }\n\n    void store(WizardDescriptor d) {\n        String name = projectNameTextField.getText().trim();\n        String folder = createdFolderTextField.getText().trim();\n\n        d.putProperty(\"projdir\", new File(folder));\n        d.putProperty(\"name\", name);\n    }\n\n    void read(WizardDescriptor settings) {\n        File projectLocation = (File) settings.getProperty(\"projdir\");\n        if (projectLocation == null || projectLocation.getParentFile() == null || !projectLocation.getParentFile().isDirectory()) {\n            projectLocation = ProjectChooser.getProjectsFolder();\n        } else {\n            projectLocation = projectLocation.getParentFile();\n        }\n        this.projectLocationTextField.setText(projectLocation.getAbsolutePath());\n\n        String projectName = (String) settings.getProperty(\"name\");\n        if (projectName == null) {\n            projectName = \"datasource\";\n        }\n        this.projectNameTextField.setText(projectName);\n        this.projectNameTextField.selectAll();\n    }\n\n    void validate(WizardDescriptor d) throws WizardValidationException {\n        // nothing to validate\n    }\n\n    // Implementation of DocumentListener --------------------------------------\n    public void changedUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void insertUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void removeUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    /** Handles changes in the Project name and project directory, */\n    private void updateTexts(DocumentEvent e) {\n\n        Document doc = e.getDocument();\n\n        if (doc == projectNameTextField.getDocument() || doc == projectLocationTextField.getDocument()) {\n            // Change in the project name\n\n            String projectName = projectNameTextField.getText();\n            String projectFolder = projectLocationTextField.getText();\n\n            //if (projectFolder.trim().length() == 0 || projectFolder.equals(oldName)) {\n            createdFolderTextField.setText(projectFolder + File.separatorChar + projectName);\n        //}\n\n        }\n        panel.fireChangeEvent(); // Notify that the panel changed\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/datasource/datasourceWizardIterator.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.datasource;\n\nimport java.awt.Component;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.text.MessageFormat;\nimport java.util.Enumeration;\nimport java.util.LinkedHashSet;\nimport java.util.NoSuchElementException;\nimport java.util.Set;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\nimport javax.swing.JComponent;\nimport javax.swing.event.ChangeListener;\nimport org.netbeans.api.project.ProjectManager;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.netbeans.spi.project.ui.templates.support.Templates;\nimport org.openide.WizardDescriptor;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.xml.XMLUtil;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.NodeList;\nimport org.xml.sax.InputSource;\n\npublic class datasourceWizardIterator implements WizardDescriptor./*Progress*/InstantiatingIterator {\n\n    private int index;\n    private WizardDescriptor.Panel[] panels;\n    private WizardDescriptor wiz;\n\n    public datasourceWizardIterator() {\n    }\n\n    public static datasourceWizardIterator createIterator() {\n        return new datasourceWizardIterator();\n    }\n\n    private WizardDescriptor.Panel[] createPanels() {\n        return new WizardDescriptor.Panel[]{\n                    new datasourceWizardPanel(),\n                };\n    }\n\n    private String[] createSteps() {\n        return new String[]{\n                    NbBundle.getMessage(datasourceWizardIterator.class, \"LBL_CreateProjectStep\")\n                };\n    }\n\n    public Set/*<FileObject>*/ instantiate(/*ProgressHandle handle*/) throws IOException {\n        Set<FileObject> resultSet = new LinkedHashSet<FileObject>();\n        File dirF = FileUtil.normalizeFile((File) wiz.getProperty(\"projdir\"));\n        dirF.mkdirs();\n\n        FileObject template = Templates.getTemplate(wiz);\n        FileObject dir = FileUtil.toFileObject(dirF);\n        unZipFile(template.getInputStream(), dir);\n\n        // Always open top dir as a project:\n        resultSet.add(dir);\n        // Look for nested projects to open as well:\n        Enumeration<? extends FileObject> e = dir.getFolders(true);\n        while (e.hasMoreElements()) {\n            FileObject subfolder = e.nextElement();\n            if (ProjectManager.getDefault().isProject(subfolder)) {\n                resultSet.add(subfolder);\n            }\n        }\n\n        File parent = dirF.getParentFile();\n        if (parent != null && parent.exists()) {\n            ProjectChooser.setProjectsFolder(parent);\n        }\n\n        return resultSet;\n    }\n\n    public void initialize(WizardDescriptor wiz) {\n        this.wiz = wiz;\n        index = 0;\n        panels = createPanels();\n        // Make sure list of steps is accurate.\n        String[] steps = createSteps();\n        for (int i = 0; i < panels.length; i++) {\n            Component c = panels[i].getComponent();\n            if (steps[i] == null) {\n                // Default step name to component name of panel.\n                // Mainly useful for getting the name of the target\n                // chooser to appear in the list of steps.\n                steps[i] = c.getName();\n            }\n            if (c instanceof JComponent) { // assume Swing components\n\n                JComponent jc = (JComponent) c;\n                // Step #.\n                jc.putClientProperty(\"WizardPanel_contentSelectedIndex\", new Integer(i));\n                // Step name (actually the whole list for reference).\n                jc.putClientProperty(\"WizardPanel_contentData\", steps);\n            }\n        }\n    }\n\n    public void uninitialize(WizardDescriptor wiz) {\n        this.wiz.putProperty(\"projdir\", null);\n        this.wiz.putProperty(\"name\", null);\n        this.wiz = null;\n        panels = null;\n    }\n\n    public String name() {\n        return MessageFormat.format(\"{0} of {1}\",\n                new Object[]{new Integer(index + 1), new Integer(panels.length)});\n    }\n\n    public boolean hasNext() {\n        return index < panels.length - 1;\n    }\n\n    public boolean hasPrevious() {\n        return index > 0;\n    }\n\n    public void nextPanel() {\n        if (!hasNext()) {\n            throw new NoSuchElementException();\n        }\n        index++;\n    }\n\n    public void previousPanel() {\n        if (!hasPrevious()) {\n            throw new NoSuchElementException();\n        }\n        index--;\n    }\n\n    public WizardDescriptor.Panel current() {\n        return panels[index];\n    }\n\n    // If nothing unusual changes in the middle of the wizard, simply:\n    public final void addChangeListener(ChangeListener l) {\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n    }\n\n    private static void unZipFile(InputStream source, FileObject projectRoot) throws IOException {\n        try {\n            ZipInputStream str = new ZipInputStream(source);\n            ZipEntry entry;\n            while ((entry = str.getNextEntry()) != null) {\n                if (entry.isDirectory()) {\n                    FileUtil.createFolder(projectRoot, entry.getName());\n                } else {\n                    FileObject fo = FileUtil.createData(projectRoot, entry.getName());\n                    if (\"nbproject/project.xml\".equals(entry.getName())) {\n                        // Special handling for setting name of Ant-based projects; customize as needed:\n                        filterProjectXML(fo, str, projectRoot.getName());\n                    } else {\n                        writeFile(str, fo);\n                    }\n                }\n            }\n        } finally {\n            source.close();\n        }\n    }\n\n    private static void writeFile(ZipInputStream str, FileObject fo) throws IOException {\n        OutputStream out = fo.getOutputStream();\n        try {\n            FileUtil.copy(str, out);\n        } finally {\n            out.close();\n        }\n    }\n\n    private static void filterProjectXML(FileObject fo, ZipInputStream str, String name) throws IOException {\n        try {\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            FileUtil.copy(str, baos);\n            Document doc = XMLUtil.parse(new InputSource(new ByteArrayInputStream(baos.toByteArray())), false, false, null, null);\n            NodeList nl = doc.getDocumentElement().getElementsByTagName(\"name\");\n            if (nl != null) {\n                for (int i = 0; i < nl.getLength(); i++) {\n                    Element el = (Element) nl.item(i);\n                    if (el.getParentNode() != null && \"data\".equals(el.getParentNode().getNodeName())) {\n                        NodeList nl2 = el.getChildNodes();\n                        if (nl2.getLength() > 0) {\n                            nl2.item(0).setNodeValue(name);\n                        }\n                        break;\n                    }\n                }\n            }\n            OutputStream out = fo.getOutputStream();\n            try {\n                XMLUtil.write(doc, out, \"UTF-8\");\n            } finally {\n                out.close();\n            }\n        } catch (Exception ex) {\n            Exceptions.printStackTrace(ex);\n            writeFile(str, fo);\n        }\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/datasource/datasourceWizardPanel.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.datasource;\n\nimport java.awt.Component;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\n\n/**\n * Panel just asking for basic info.\n */\npublic class datasourceWizardPanel implements WizardDescriptor.Panel,\n        WizardDescriptor.ValidatingPanel, WizardDescriptor.FinishablePanel {\n\n    private WizardDescriptor wizardDescriptor;\n    private datasourcePanelVisual component;\n\n    public datasourceWizardPanel() {\n    }\n\n    public Component getComponent() {\n        if (component == null) {\n            component = new datasourcePanelVisual(this);\n            component.setName(NbBundle.getMessage(datasourceWizardPanel.class, \"LBL_CreateProjectStep\"));\n        }\n        return component;\n    }\n\n    public HelpCtx getHelp() {\n        return new HelpCtx(datasourceWizardPanel.class);\n    }\n\n    public boolean isValid() {\n        getComponent();\n        return component.valid(wizardDescriptor);\n    }\n    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0\n\n\n    public final void addChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.add(l);\n        }\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.remove(l);\n        }\n    }\n\n    protected final void fireChangeEvent() {\n        Set<ChangeListener> ls;\n        synchronized (listeners) {\n            ls = new HashSet<ChangeListener>(listeners);\n        }\n        ChangeEvent ev = new ChangeEvent(this);\n        for (ChangeListener l : ls) {\n            l.stateChanged(ev);\n        }\n    }\n\n    public void readSettings(Object settings) {\n        wizardDescriptor = (WizardDescriptor) settings;\n        component.read(wizardDescriptor);\n    }\n\n    public void storeSettings(Object settings) {\n        WizardDescriptor d = (WizardDescriptor) settings;\n        component.store(d);\n    }\n\n    public boolean isFinishPanel() {\n        return true;\n    }\n\n    public void validate() throws WizardValidationException {\n        getComponent();\n        component.validate(wizardDescriptor);\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/hellovvm/Bundle.properties",
    "content": "LBL_CreateProjectStep=Name and Location\nhellovvmPanelVisual.projectLocationLabel.text=Project &Location:\nhellovvmPanelVisual.browseButton.actionCommand=BROWSE\nhellovvmPanelVisual.browseButton.text=Br&owse...\nhellovvmPanelVisual.createdFolderLabel.text=Project &Folder:\nhellovvmPanelVisual.projectNameLabel.text=Project &Name:\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/hellovvm/hellovvmDescription.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n        Gives you a new tab for all\n        application types, with some\n        placeholders for content.\n    </body>\n</html>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/hellovvm/hellovvmPanelVisual.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.5\" maxVersion=\"1.6\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"browseButton\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectNameTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectLocationLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"browseButton\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"createdFolderLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace pref=\"213\" max=\"32767\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"projectNameLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectNameTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/hellovvm/Bundle.properties\" key=\"hellovvmPanelVisual.projectNameLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectNameTextField\">\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"projectLocationLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectLocationTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/hellovvm/Bundle.properties\" key=\"hellovvmPanelVisual.projectLocationLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectLocationTextField\">\n    </Component>\n    <Component class=\"javax.swing.JButton\" name=\"browseButton\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/hellovvm/Bundle.properties\" key=\"hellovvmPanelVisual.browseButton.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n        <Property name=\"actionCommand\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/hellovvm/Bundle.properties\" key=\"hellovvmPanelVisual.browseButton.actionCommand\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"browseButtonActionPerformed\"/>\n      </Events>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"createdFolderLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"createdFolderTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/hellovvm/Bundle.properties\" key=\"hellovvmPanelVisual.createdFolderLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"createdFolderTextField\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/hellovvm/hellovvmPanelVisual.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.nb.samplebundle.hellovvm;\n\nimport java.io.File;\nimport javax.swing.JFileChooser;\nimport javax.swing.JPanel;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.Document;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.filesystems.FileUtil;\n\npublic class hellovvmPanelVisual extends JPanel implements DocumentListener {\n\n    public static final String PROP_PROJECT_NAME = \"projectName\";\n\n    private hellovvmWizardPanel panel;\n\n    public hellovvmPanelVisual(hellovvmWizardPanel panel) {\n        initComponents();\n        this.panel = panel;\n        // Register listener on the textFields to make the automatic updates\n        projectNameTextField.getDocument().addDocumentListener(this);\n        projectLocationTextField.getDocument().addDocumentListener(this);\n    }\n\n    public String getProjectName() {\n        return this.projectNameTextField.getText();\n    }\n\n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        projectNameLabel = new javax.swing.JLabel();\n        projectNameTextField = new javax.swing.JTextField();\n        projectLocationLabel = new javax.swing.JLabel();\n        projectLocationTextField = new javax.swing.JTextField();\n        browseButton = new javax.swing.JButton();\n        createdFolderLabel = new javax.swing.JLabel();\n        createdFolderTextField = new javax.swing.JTextField();\n\n        projectNameLabel.setLabelFor(projectNameTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectNameLabel, org.openide.util.NbBundle.getMessage(hellovvmPanelVisual.class, \"hellovvmPanelVisual.projectNameLabel.text\")); // NOI18N\n\n        projectLocationLabel.setLabelFor(projectLocationTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectLocationLabel, org.openide.util.NbBundle.getMessage(hellovvmPanelVisual.class, \"hellovvmPanelVisual.projectLocationLabel.text\")); // NOI18N\n\n        org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(hellovvmPanelVisual.class, \"hellovvmPanelVisual.browseButton.text\")); // NOI18N\n        browseButton.setActionCommand(org.openide.util.NbBundle.getMessage(hellovvmPanelVisual.class, \"hellovvmPanelVisual.browseButton.actionCommand\")); // NOI18N\n        browseButton.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                browseButtonActionPerformed(evt);\n            }\n        });\n\n        createdFolderLabel.setLabelFor(createdFolderTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(createdFolderLabel, org.openide.util.NbBundle.getMessage(hellovvmPanelVisual.class, \"hellovvmPanelVisual.createdFolderLabel.text\")); // NOI18N\n\n        createdFolderTextField.setEditable(false);\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(createdFolderLabel))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(browseButton)\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)\n                    .addComponent(browseButton))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(createdFolderLabel)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addContainerGap(213, Short.MAX_VALUE))\n        );\n    }// </editor-fold>//GEN-END:initComponents\n\n    private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed\n        String command = evt.getActionCommand();\n        if (\"BROWSE\".equals(command)) {\n            JFileChooser chooser = new JFileChooser();\n            FileUtil.preventFileChooserSymlinkTraversal(chooser, null);\n            chooser.setDialogTitle(\"Select Project Location\");\n            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\n            String path = this.projectLocationTextField.getText();\n            if (path.length() > 0) {\n                File f = new File(path);\n                if (f.exists()) {\n                    chooser.setSelectedFile(f);\n                }\n            }\n            if (JFileChooser.APPROVE_OPTION == chooser.showOpenDialog(this)) {\n                File projectDir = chooser.getSelectedFile();\n                projectLocationTextField.setText(FileUtil.normalizeFile(projectDir).getAbsolutePath());\n            }\n            panel.fireChangeEvent();\n        }\n\n    }//GEN-LAST:event_browseButtonActionPerformed\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JButton browseButton;\n    private javax.swing.JLabel createdFolderLabel;\n    private javax.swing.JTextField createdFolderTextField;\n    private javax.swing.JLabel projectLocationLabel;\n    private javax.swing.JTextField projectLocationTextField;\n    private javax.swing.JLabel projectNameLabel;\n    private javax.swing.JTextField projectNameTextField;\n    // End of variables declaration//GEN-END:variables\n\n    @Override\n    public void addNotify() {\n        super.addNotify();\n        //same problem as in 31086, initial focus on Cancel button\n        projectNameTextField.requestFocus();\n    }\n\n    boolean valid(WizardDescriptor wizardDescriptor) {\n\n        if (projectNameTextField.getText().length() == 0) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Name is not a valid folder name.\");\n            return false; // Display name not specified\n\n        }\n        File f = FileUtil.normalizeFile(new File(projectLocationTextField.getText()).getAbsoluteFile());\n        if (!f.isDirectory()) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n        final File destFolder = FileUtil.normalizeFile(new File(createdFolderTextField.getText()).getAbsoluteFile());\n\n        File projLoc = destFolder;\n        while (projLoc != null && !projLoc.exists()) {\n            projLoc = projLoc.getParentFile();\n        }\n        if (projLoc == null || !projLoc.canWrite()) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder cannot be created.\");\n            return false;\n        }\n\n        if (FileUtil.toFileObject(projLoc) == null) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n\n        File[] kids = destFolder.listFiles();\n        if (destFolder.exists() && kids != null && kids.length > 0) {\n            // Folder exists and is not empty\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder already exists and is not empty.\");\n            return false;\n        }\n        wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", \"\");\n        return true;\n    }\n\n    void store(WizardDescriptor d) {\n        String name = projectNameTextField.getText().trim();\n        String folder = createdFolderTextField.getText().trim();\n\n        d.putProperty(\"projdir\", new File(folder));\n        d.putProperty(\"name\", name);\n    }\n\n    void read(WizardDescriptor settings) {\n        File projectLocation = (File) settings.getProperty(\"projdir\");\n        if (projectLocation == null || projectLocation.getParentFile() == null || !projectLocation.getParentFile().isDirectory()) {\n            projectLocation = ProjectChooser.getProjectsFolder();\n        } else {\n            projectLocation = projectLocation.getParentFile();\n        }\n        this.projectLocationTextField.setText(projectLocation.getAbsolutePath());\n\n        String projectName = (String) settings.getProperty(\"name\");\n        if (projectName == null) {\n            projectName = \"hellovvm\";\n        }\n        this.projectNameTextField.setText(projectName);\n        this.projectNameTextField.selectAll();\n    }\n\n    void validate(WizardDescriptor d) throws WizardValidationException {\n        // nothing to validate\n    }\n\n    // Implementation of DocumentListener --------------------------------------\n    public void changedUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void insertUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void removeUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    /** Handles changes in the Project name and project directory, */\n    private void updateTexts(DocumentEvent e) {\n\n        Document doc = e.getDocument();\n\n        if (doc == projectNameTextField.getDocument() || doc == projectLocationTextField.getDocument()) {\n            // Change in the project name\n\n            String projectName = projectNameTextField.getText();\n            String projectFolder = projectLocationTextField.getText();\n\n            //if (projectFolder.trim().length() == 0 || projectFolder.equals(oldName)) {\n            createdFolderTextField.setText(projectFolder + File.separatorChar + projectName);\n        //}\n\n        }\n        panel.fireChangeEvent(); // Notify that the panel changed\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/hellovvm/hellovvmWizardIterator.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.hellovvm;\n\nimport java.awt.Component;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.text.MessageFormat;\nimport java.util.Enumeration;\nimport java.util.LinkedHashSet;\nimport java.util.NoSuchElementException;\nimport java.util.Set;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\nimport javax.swing.JComponent;\nimport javax.swing.event.ChangeListener;\nimport org.netbeans.api.project.ProjectManager;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.netbeans.spi.project.ui.templates.support.Templates;\nimport org.openide.WizardDescriptor;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.xml.XMLUtil;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.NodeList;\nimport org.xml.sax.InputSource;\n\npublic class hellovvmWizardIterator implements WizardDescriptor./*Progress*/InstantiatingIterator {\n\n    private int index;\n    private WizardDescriptor.Panel[] panels;\n    private WizardDescriptor wiz;\n\n    public hellovvmWizardIterator() {\n    }\n\n    public static hellovvmWizardIterator createIterator() {\n        return new hellovvmWizardIterator();\n    }\n\n    private WizardDescriptor.Panel[] createPanels() {\n        return new WizardDescriptor.Panel[]{\n                    new hellovvmWizardPanel(),\n                };\n    }\n\n    private String[] createSteps() {\n        return new String[]{\n                    NbBundle.getMessage(hellovvmWizardIterator.class, \"LBL_CreateProjectStep\")\n                };\n    }\n\n    public Set/*<FileObject>*/ instantiate(/*ProgressHandle handle*/) throws IOException {\n        Set<FileObject> resultSet = new LinkedHashSet<FileObject>();\n        File dirF = FileUtil.normalizeFile((File) wiz.getProperty(\"projdir\"));\n        dirF.mkdirs();\n\n        FileObject template = Templates.getTemplate(wiz);\n        FileObject dir = FileUtil.toFileObject(dirF);\n        unZipFile(template.getInputStream(), dir);\n\n        // Always open top dir as a project:\n        resultSet.add(dir);\n        // Look for nested projects to open as well:\n        Enumeration<? extends FileObject> e = dir.getFolders(true);\n        while (e.hasMoreElements()) {\n            FileObject subfolder = e.nextElement();\n            if (ProjectManager.getDefault().isProject(subfolder)) {\n                resultSet.add(subfolder);\n            }\n        }\n\n        File parent = dirF.getParentFile();\n        if (parent != null && parent.exists()) {\n            ProjectChooser.setProjectsFolder(parent);\n        }\n\n        return resultSet;\n    }\n\n    public void initialize(WizardDescriptor wiz) {\n        this.wiz = wiz;\n        index = 0;\n        panels = createPanels();\n        // Make sure list of steps is accurate.\n        String[] steps = createSteps();\n        for (int i = 0; i < panels.length; i++) {\n            Component c = panels[i].getComponent();\n            if (steps[i] == null) {\n                // Default step name to component name of panel.\n                // Mainly useful for getting the name of the target\n                // chooser to appear in the list of steps.\n                steps[i] = c.getName();\n            }\n            if (c instanceof JComponent) { // assume Swing components\n\n                JComponent jc = (JComponent) c;\n                // Step #.\n                jc.putClientProperty(\"WizardPanel_contentSelectedIndex\", new Integer(i));\n                // Step name (actually the whole list for reference).\n                jc.putClientProperty(\"WizardPanel_contentData\", steps);\n            }\n        }\n    }\n\n    public void uninitialize(WizardDescriptor wiz) {\n        this.wiz.putProperty(\"projdir\", null);\n        this.wiz.putProperty(\"name\", null);\n        this.wiz = null;\n        panels = null;\n    }\n\n    public String name() {\n        return MessageFormat.format(\"{0} of {1}\",\n                new Object[]{new Integer(index + 1), new Integer(panels.length)});\n    }\n\n    public boolean hasNext() {\n        return index < panels.length - 1;\n    }\n\n    public boolean hasPrevious() {\n        return index > 0;\n    }\n\n    public void nextPanel() {\n        if (!hasNext()) {\n            throw new NoSuchElementException();\n        }\n        index++;\n    }\n\n    public void previousPanel() {\n        if (!hasPrevious()) {\n            throw new NoSuchElementException();\n        }\n        index--;\n    }\n\n    public WizardDescriptor.Panel current() {\n        return panels[index];\n    }\n\n    // If nothing unusual changes in the middle of the wizard, simply:\n    public final void addChangeListener(ChangeListener l) {\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n    }\n\n    private static void unZipFile(InputStream source, FileObject projectRoot) throws IOException {\n        try {\n            ZipInputStream str = new ZipInputStream(source);\n            ZipEntry entry;\n            while ((entry = str.getNextEntry()) != null) {\n                if (entry.isDirectory()) {\n                    FileUtil.createFolder(projectRoot, entry.getName());\n                } else {\n                    FileObject fo = FileUtil.createData(projectRoot, entry.getName());\n                    if (\"nbproject/project.xml\".equals(entry.getName())) {\n                        // Special handling for setting name of Ant-based projects; customize as needed:\n                        filterProjectXML(fo, str, projectRoot.getName());\n                    } else {\n                        writeFile(str, fo);\n                    }\n                }\n            }\n        } finally {\n            source.close();\n        }\n    }\n\n    private static void writeFile(ZipInputStream str, FileObject fo) throws IOException {\n        OutputStream out = fo.getOutputStream();\n        try {\n            FileUtil.copy(str, out);\n        } finally {\n            out.close();\n        }\n    }\n\n    private static void filterProjectXML(FileObject fo, ZipInputStream str, String name) throws IOException {\n        try {\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            FileUtil.copy(str, baos);\n            Document doc = XMLUtil.parse(new InputSource(new ByteArrayInputStream(baos.toByteArray())), false, false, null, null);\n            NodeList nl = doc.getDocumentElement().getElementsByTagName(\"name\");\n            if (nl != null) {\n                for (int i = 0; i < nl.getLength(); i++) {\n                    Element el = (Element) nl.item(i);\n                    if (el.getParentNode() != null && \"data\".equals(el.getParentNode().getNodeName())) {\n                        NodeList nl2 = el.getChildNodes();\n                        if (nl2.getLength() > 0) {\n                            nl2.item(0).setNodeValue(name);\n                        }\n                        break;\n                    }\n                }\n            }\n            OutputStream out = fo.getOutputStream();\n            try {\n                XMLUtil.write(doc, out, \"UTF-8\");\n            } finally {\n                out.close();\n            }\n        } catch (Exception ex) {\n            Exceptions.printStackTrace(ex);\n            writeFile(str, fo);\n        }\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/hellovvm/hellovvmWizardPanel.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.hellovvm;\n\nimport java.awt.Component;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\n\n/**\n * Panel just asking for basic info.\n */\npublic class hellovvmWizardPanel implements WizardDescriptor.Panel,\n        WizardDescriptor.ValidatingPanel, WizardDescriptor.FinishablePanel {\n\n    private WizardDescriptor wizardDescriptor;\n    private hellovvmPanelVisual component;\n\n    public hellovvmWizardPanel() {\n    }\n\n    public Component getComponent() {\n        if (component == null) {\n            component = new hellovvmPanelVisual(this);\n            component.setName(NbBundle.getMessage(hellovvmWizardPanel.class, \"LBL_CreateProjectStep\"));\n        }\n        return component;\n    }\n\n    public HelpCtx getHelp() {\n        return new HelpCtx(hellovvmWizardPanel.class);\n    }\n\n    public boolean isValid() {\n        getComponent();\n        return component.valid(wizardDescriptor);\n    }\n    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0\n\n\n    public final void addChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.add(l);\n        }\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.remove(l);\n        }\n    }\n\n    protected final void fireChangeEvent() {\n        Set<ChangeListener> ls;\n        synchronized (listeners) {\n            ls = new HashSet<ChangeListener>(listeners);\n        }\n        ChangeEvent ev = new ChangeEvent(this);\n        for (ChangeListener l : ls) {\n            l.stateChanged(ev);\n        }\n    }\n\n    public void readSettings(Object settings) {\n        wizardDescriptor = (WizardDescriptor) settings;\n        component.read(wizardDescriptor);\n    }\n\n    public void storeSettings(Object settings) {\n        WizardDescriptor d = (WizardDescriptor) settings;\n        component.store(d);\n    }\n\n    public boolean isFinishPanel() {\n        return true;\n    }\n\n    public void validate() throws WizardValidationException {\n        getComponent();\n        component.validate(wizardDescriptor);\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/hostview/Bundle.properties",
    "content": "LBL_CreateProjectStep=Name and Location\nhostviewPanelVisual.projectLocationLabel.text=Project &Location:\nhostviewPanelVisual.browseButton.actionCommand=BROWSE\nhostviewPanelVisual.browseButton.text=Br&owse...\nhostviewPanelVisual.createdFolderLabel.text=Project &Folder:\nhostviewPanelVisual.projectNameLabel.text=Project &Name:\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/hostview/hostviewDescription.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n        Gives you a new tab for the Host\n        data source, displaying a subtab\n        for each running application.\n    </body>\n</html>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/hostview/hostviewPanelVisual.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.5\" maxVersion=\"1.6\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"browseButton\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectNameTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectLocationLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"browseButton\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"createdFolderLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace pref=\"213\" max=\"32767\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"projectNameLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectNameTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/hostview/Bundle.properties\" key=\"hostviewPanelVisual.projectNameLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectNameTextField\">\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"projectLocationLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectLocationTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/hostview/Bundle.properties\" key=\"hostviewPanelVisual.projectLocationLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectLocationTextField\">\n    </Component>\n    <Component class=\"javax.swing.JButton\" name=\"browseButton\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/hostview/Bundle.properties\" key=\"hostviewPanelVisual.browseButton.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n        <Property name=\"actionCommand\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/hostview/Bundle.properties\" key=\"hostviewPanelVisual.browseButton.actionCommand\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"browseButtonActionPerformed\"/>\n      </Events>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"createdFolderLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"createdFolderTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/hostview/Bundle.properties\" key=\"hostviewPanelVisual.createdFolderLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"createdFolderTextField\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/hostview/hostviewPanelVisual.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.nb.samplebundle.hostview;\n\nimport java.io.File;\nimport javax.swing.JFileChooser;\nimport javax.swing.JPanel;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.Document;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.filesystems.FileUtil;\n\npublic class hostviewPanelVisual extends JPanel implements DocumentListener {\n\n    public static final String PROP_PROJECT_NAME = \"projectName\";\n\n    private hostviewWizardPanel panel;\n\n    public hostviewPanelVisual(hostviewWizardPanel panel) {\n        initComponents();\n        this.panel = panel;\n        // Register listener on the textFields to make the automatic updates\n        projectNameTextField.getDocument().addDocumentListener(this);\n        projectLocationTextField.getDocument().addDocumentListener(this);\n    }\n\n    public String getProjectName() {\n        return this.projectNameTextField.getText();\n    }\n\n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        projectNameLabel = new javax.swing.JLabel();\n        projectNameTextField = new javax.swing.JTextField();\n        projectLocationLabel = new javax.swing.JLabel();\n        projectLocationTextField = new javax.swing.JTextField();\n        browseButton = new javax.swing.JButton();\n        createdFolderLabel = new javax.swing.JLabel();\n        createdFolderTextField = new javax.swing.JTextField();\n\n        projectNameLabel.setLabelFor(projectNameTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectNameLabel, org.openide.util.NbBundle.getMessage(hostviewPanelVisual.class, \"hostviewPanelVisual.projectNameLabel.text\")); // NOI18N\n\n        projectLocationLabel.setLabelFor(projectLocationTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectLocationLabel, org.openide.util.NbBundle.getMessage(hostviewPanelVisual.class, \"hostviewPanelVisual.projectLocationLabel.text\")); // NOI18N\n\n        org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(hostviewPanelVisual.class, \"hostviewPanelVisual.browseButton.text\")); // NOI18N\n        browseButton.setActionCommand(org.openide.util.NbBundle.getMessage(hostviewPanelVisual.class, \"hostviewPanelVisual.browseButton.actionCommand\")); // NOI18N\n        browseButton.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                browseButtonActionPerformed(evt);\n            }\n        });\n\n        createdFolderLabel.setLabelFor(createdFolderTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(createdFolderLabel, org.openide.util.NbBundle.getMessage(hostviewPanelVisual.class, \"hostviewPanelVisual.createdFolderLabel.text\")); // NOI18N\n\n        createdFolderTextField.setEditable(false);\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(createdFolderLabel))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(browseButton)\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)\n                    .addComponent(browseButton))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(createdFolderLabel)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addContainerGap(213, Short.MAX_VALUE))\n        );\n    }// </editor-fold>//GEN-END:initComponents\n\n    private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed\n        String command = evt.getActionCommand();\n        if (\"BROWSE\".equals(command)) {\n            JFileChooser chooser = new JFileChooser();\n            FileUtil.preventFileChooserSymlinkTraversal(chooser, null);\n            chooser.setDialogTitle(\"Select Project Location\");\n            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\n            String path = this.projectLocationTextField.getText();\n            if (path.length() > 0) {\n                File f = new File(path);\n                if (f.exists()) {\n                    chooser.setSelectedFile(f);\n                }\n            }\n            if (JFileChooser.APPROVE_OPTION == chooser.showOpenDialog(this)) {\n                File projectDir = chooser.getSelectedFile();\n                projectLocationTextField.setText(FileUtil.normalizeFile(projectDir).getAbsolutePath());\n            }\n            panel.fireChangeEvent();\n        }\n\n    }//GEN-LAST:event_browseButtonActionPerformed\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JButton browseButton;\n    private javax.swing.JLabel createdFolderLabel;\n    private javax.swing.JTextField createdFolderTextField;\n    private javax.swing.JLabel projectLocationLabel;\n    private javax.swing.JTextField projectLocationTextField;\n    private javax.swing.JLabel projectNameLabel;\n    private javax.swing.JTextField projectNameTextField;\n    // End of variables declaration//GEN-END:variables\n\n    @Override\n    public void addNotify() {\n        super.addNotify();\n        //same problem as in 31086, initial focus on Cancel button\n        projectNameTextField.requestFocus();\n    }\n\n    boolean valid(WizardDescriptor wizardDescriptor) {\n\n        if (projectNameTextField.getText().length() == 0) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Name is not a valid folder name.\");\n            return false; // Display name not specified\n\n        }\n        File f = FileUtil.normalizeFile(new File(projectLocationTextField.getText()).getAbsoluteFile());\n        if (!f.isDirectory()) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n        final File destFolder = FileUtil.normalizeFile(new File(createdFolderTextField.getText()).getAbsoluteFile());\n\n        File projLoc = destFolder;\n        while (projLoc != null && !projLoc.exists()) {\n            projLoc = projLoc.getParentFile();\n        }\n        if (projLoc == null || !projLoc.canWrite()) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder cannot be created.\");\n            return false;\n        }\n\n        if (FileUtil.toFileObject(projLoc) == null) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n\n        File[] kids = destFolder.listFiles();\n        if (destFolder.exists() && kids != null && kids.length > 0) {\n            // Folder exists and is not empty\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder already exists and is not empty.\");\n            return false;\n        }\n        wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", \"\");\n        return true;\n    }\n\n    void store(WizardDescriptor d) {\n        String name = projectNameTextField.getText().trim();\n        String folder = createdFolderTextField.getText().trim();\n\n        d.putProperty(\"projdir\", new File(folder));\n        d.putProperty(\"name\", name);\n    }\n\n    void read(WizardDescriptor settings) {\n        File projectLocation = (File) settings.getProperty(\"projdir\");\n        if (projectLocation == null || projectLocation.getParentFile() == null || !projectLocation.getParentFile().isDirectory()) {\n            projectLocation = ProjectChooser.getProjectsFolder();\n        } else {\n            projectLocation = projectLocation.getParentFile();\n        }\n        this.projectLocationTextField.setText(projectLocation.getAbsolutePath());\n\n        String projectName = (String) settings.getProperty(\"name\");\n        if (projectName == null) {\n            projectName = \"hostview\";\n        }\n        this.projectNameTextField.setText(projectName);\n        this.projectNameTextField.selectAll();\n    }\n\n    void validate(WizardDescriptor d) throws WizardValidationException {\n        // nothing to validate\n    }\n\n    // Implementation of DocumentListener --------------------------------------\n    public void changedUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void insertUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void removeUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    /** Handles changes in the Project name and project directory, */\n    private void updateTexts(DocumentEvent e) {\n\n        Document doc = e.getDocument();\n\n        if (doc == projectNameTextField.getDocument() || doc == projectLocationTextField.getDocument()) {\n            // Change in the project name\n\n            String projectName = projectNameTextField.getText();\n            String projectFolder = projectLocationTextField.getText();\n\n            //if (projectFolder.trim().length() == 0 || projectFolder.equals(oldName)) {\n            createdFolderTextField.setText(projectFolder + File.separatorChar + projectName);\n        //}\n\n        }\n        panel.fireChangeEvent(); // Notify that the panel changed\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/hostview/hostviewWizardIterator.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.hostview;\n\nimport java.awt.Component;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.text.MessageFormat;\nimport java.util.Enumeration;\nimport java.util.LinkedHashSet;\nimport java.util.NoSuchElementException;\nimport java.util.Set;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\nimport javax.swing.JComponent;\nimport javax.swing.event.ChangeListener;\nimport org.netbeans.api.project.ProjectManager;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.netbeans.spi.project.ui.templates.support.Templates;\nimport org.openide.WizardDescriptor;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.xml.XMLUtil;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.NodeList;\nimport org.xml.sax.InputSource;\n\npublic class hostviewWizardIterator implements WizardDescriptor./*Progress*/InstantiatingIterator {\n\n    private int index;\n    private WizardDescriptor.Panel[] panels;\n    private WizardDescriptor wiz;\n\n    public hostviewWizardIterator() {\n    }\n\n    public static hostviewWizardIterator createIterator() {\n        return new hostviewWizardIterator();\n    }\n\n    private WizardDescriptor.Panel[] createPanels() {\n        return new WizardDescriptor.Panel[]{\n                    new hostviewWizardPanel(),\n                };\n    }\n\n    private String[] createSteps() {\n        return new String[]{\n                    NbBundle.getMessage(hostviewWizardIterator.class, \"LBL_CreateProjectStep\")\n                };\n    }\n\n    public Set/*<FileObject>*/ instantiate(/*ProgressHandle handle*/) throws IOException {\n        Set<FileObject> resultSet = new LinkedHashSet<FileObject>();\n        File dirF = FileUtil.normalizeFile((File) wiz.getProperty(\"projdir\"));\n        dirF.mkdirs();\n\n        FileObject template = Templates.getTemplate(wiz);\n        FileObject dir = FileUtil.toFileObject(dirF);\n        unZipFile(template.getInputStream(), dir);\n\n        // Always open top dir as a project:\n        resultSet.add(dir);\n        // Look for nested projects to open as well:\n        Enumeration<? extends FileObject> e = dir.getFolders(true);\n        while (e.hasMoreElements()) {\n            FileObject subfolder = e.nextElement();\n            if (ProjectManager.getDefault().isProject(subfolder)) {\n                resultSet.add(subfolder);\n            }\n        }\n\n        File parent = dirF.getParentFile();\n        if (parent != null && parent.exists()) {\n            ProjectChooser.setProjectsFolder(parent);\n        }\n\n        return resultSet;\n    }\n\n    public void initialize(WizardDescriptor wiz) {\n        this.wiz = wiz;\n        index = 0;\n        panels = createPanels();\n        // Make sure list of steps is accurate.\n        String[] steps = createSteps();\n        for (int i = 0; i < panels.length; i++) {\n            Component c = panels[i].getComponent();\n            if (steps[i] == null) {\n                // Default step name to component name of panel.\n                // Mainly useful for getting the name of the target\n                // chooser to appear in the list of steps.\n                steps[i] = c.getName();\n            }\n            if (c instanceof JComponent) { // assume Swing components\n\n                JComponent jc = (JComponent) c;\n                // Step #.\n                jc.putClientProperty(\"WizardPanel_contentSelectedIndex\", new Integer(i));\n                // Step name (actually the whole list for reference).\n                jc.putClientProperty(\"WizardPanel_contentData\", steps);\n            }\n        }\n    }\n\n    public void uninitialize(WizardDescriptor wiz) {\n        this.wiz.putProperty(\"projdir\", null);\n        this.wiz.putProperty(\"name\", null);\n        this.wiz = null;\n        panels = null;\n    }\n\n    public String name() {\n        return MessageFormat.format(\"{0} of {1}\",\n                new Object[]{new Integer(index + 1), new Integer(panels.length)});\n    }\n\n    public boolean hasNext() {\n        return index < panels.length - 1;\n    }\n\n    public boolean hasPrevious() {\n        return index > 0;\n    }\n\n    public void nextPanel() {\n        if (!hasNext()) {\n            throw new NoSuchElementException();\n        }\n        index++;\n    }\n\n    public void previousPanel() {\n        if (!hasPrevious()) {\n            throw new NoSuchElementException();\n        }\n        index--;\n    }\n\n    public WizardDescriptor.Panel current() {\n        return panels[index];\n    }\n\n    // If nothing unusual changes in the middle of the wizard, simply:\n    public final void addChangeListener(ChangeListener l) {\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n    }\n\n    private static void unZipFile(InputStream source, FileObject projectRoot) throws IOException {\n        try {\n            ZipInputStream str = new ZipInputStream(source);\n            ZipEntry entry;\n            while ((entry = str.getNextEntry()) != null) {\n                if (entry.isDirectory()) {\n                    FileUtil.createFolder(projectRoot, entry.getName());\n                } else {\n                    FileObject fo = FileUtil.createData(projectRoot, entry.getName());\n                    if (\"nbproject/project.xml\".equals(entry.getName())) {\n                        // Special handling for setting name of Ant-based projects; customize as needed:\n                        filterProjectXML(fo, str, projectRoot.getName());\n                    } else {\n                        writeFile(str, fo);\n                    }\n                }\n            }\n        } finally {\n            source.close();\n        }\n    }\n\n    private static void writeFile(ZipInputStream str, FileObject fo) throws IOException {\n        OutputStream out = fo.getOutputStream();\n        try {\n            FileUtil.copy(str, out);\n        } finally {\n            out.close();\n        }\n    }\n\n    private static void filterProjectXML(FileObject fo, ZipInputStream str, String name) throws IOException {\n        try {\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            FileUtil.copy(str, baos);\n            Document doc = XMLUtil.parse(new InputSource(new ByteArrayInputStream(baos.toByteArray())), false, false, null, null);\n            NodeList nl = doc.getDocumentElement().getElementsByTagName(\"name\");\n            if (nl != null) {\n                for (int i = 0; i < nl.getLength(); i++) {\n                    Element el = (Element) nl.item(i);\n                    if (el.getParentNode() != null && \"data\".equals(el.getParentNode().getNodeName())) {\n                        NodeList nl2 = el.getChildNodes();\n                        if (nl2.getLength() > 0) {\n                            nl2.item(0).setNodeValue(name);\n                        }\n                        break;\n                    }\n                }\n            }\n            OutputStream out = fo.getOutputStream();\n            try {\n                XMLUtil.write(doc, out, \"UTF-8\");\n            } finally {\n                out.close();\n            }\n        } catch (Exception ex) {\n            Exceptions.printStackTrace(ex);\n            writeFile(str, fo);\n        }\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/hostview/hostviewWizardPanel.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.hostview;\n\nimport java.awt.Component;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\n\n/**\n * Panel just asking for basic info.\n */\npublic class hostviewWizardPanel implements WizardDescriptor.Panel,\n        WizardDescriptor.ValidatingPanel, WizardDescriptor.FinishablePanel {\n\n    private WizardDescriptor wizardDescriptor;\n    private hostviewPanelVisual component;\n\n    public hostviewWizardPanel() {\n    }\n\n    public Component getComponent() {\n        if (component == null) {\n            component = new hostviewPanelVisual(this);\n            component.setName(NbBundle.getMessage(hostviewWizardPanel.class, \"LBL_CreateProjectStep\"));\n        }\n        return component;\n    }\n\n    public HelpCtx getHelp() {\n        return new HelpCtx(hostviewWizardPanel.class);\n    }\n\n    public boolean isValid() {\n        getComponent();\n        return component.valid(wizardDescriptor);\n    }\n    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0\n\n\n    public final void addChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.add(l);\n        }\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.remove(l);\n        }\n    }\n\n    protected final void fireChangeEvent() {\n        Set<ChangeListener> ls;\n        synchronized (listeners) {\n            ls = new HashSet<ChangeListener>(listeners);\n        }\n        ChangeEvent ev = new ChangeEvent(this);\n        for (ChangeListener l : ls) {\n            l.stateChanged(ev);\n        }\n    }\n\n    public void readSettings(Object settings) {\n        wizardDescriptor = (WizardDescriptor) settings;\n        component.read(wizardDescriptor);\n    }\n\n    public void storeSettings(Object settings) {\n        WizardDescriptor d = (WizardDescriptor) settings;\n        component.store(d);\n    }\n\n    public boolean isFinishPanel() {\n        return true;\n    }\n\n    public void validate() throws WizardValidationException {\n        getComponent();\n        component.validate(wizardDescriptor);\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/jvmcaps/Bundle.properties",
    "content": "LBL_CreateProjectStep=Name and Location\njvmcapsPanelVisual.createdFolderLabel.text=Project &Folder:\njvmcapsPanelVisual.projectNameLabel.text=Project &Name:\njvmcapsPanelVisual.browseButton.actionCommand=BROWSE\njvmcapsPanelVisual.browseButton.text=Br&owse...\njvmcapsPanelVisual.projectLocationLabel.text=Project &Location:\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/jvmcaps/jvmcapsDescription.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n        Gives you a new subtab in the\n        Overview tab and in the Snapshot\n        tab.\n    </body>\n</html>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/jvmcaps/jvmcapsPanelVisual.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.5\" maxVersion=\"1.6\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"browseButton\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectNameTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectLocationLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"browseButton\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"createdFolderLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace pref=\"213\" max=\"32767\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"projectNameLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectNameTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/jvmcaps/Bundle.properties\" key=\"jvmcapsPanelVisual.projectNameLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectNameTextField\">\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"projectLocationLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectLocationTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/jvmcaps/Bundle.properties\" key=\"jvmcapsPanelVisual.projectLocationLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectLocationTextField\">\n    </Component>\n    <Component class=\"javax.swing.JButton\" name=\"browseButton\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/jvmcaps/Bundle.properties\" key=\"jvmcapsPanelVisual.browseButton.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n        <Property name=\"actionCommand\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/jvmcaps/Bundle.properties\" key=\"jvmcapsPanelVisual.browseButton.actionCommand\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"browseButtonActionPerformed\"/>\n      </Events>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"createdFolderLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"createdFolderTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/jvmcaps/Bundle.properties\" key=\"jvmcapsPanelVisual.createdFolderLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"createdFolderTextField\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/jvmcaps/jvmcapsPanelVisual.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.nb.samplebundle.jvmcaps;\n\nimport java.io.File;\nimport javax.swing.JFileChooser;\nimport javax.swing.JPanel;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.Document;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.filesystems.FileUtil;\n\npublic class jvmcapsPanelVisual extends JPanel implements DocumentListener {\n\n    public static final String PROP_PROJECT_NAME = \"projectName\";\n\n    private jvmcapsWizardPanel panel;\n\n    public jvmcapsPanelVisual(jvmcapsWizardPanel panel) {\n        initComponents();\n        this.panel = panel;\n        // Register listener on the textFields to make the automatic updates\n        projectNameTextField.getDocument().addDocumentListener(this);\n        projectLocationTextField.getDocument().addDocumentListener(this);\n    }\n\n    public String getProjectName() {\n        return this.projectNameTextField.getText();\n    }\n\n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        projectNameLabel = new javax.swing.JLabel();\n        projectNameTextField = new javax.swing.JTextField();\n        projectLocationLabel = new javax.swing.JLabel();\n        projectLocationTextField = new javax.swing.JTextField();\n        browseButton = new javax.swing.JButton();\n        createdFolderLabel = new javax.swing.JLabel();\n        createdFolderTextField = new javax.swing.JTextField();\n\n        projectNameLabel.setLabelFor(projectNameTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectNameLabel, org.openide.util.NbBundle.getMessage(jvmcapsPanelVisual.class, \"jvmcapsPanelVisual.projectNameLabel.text\")); // NOI18N\n\n        projectLocationLabel.setLabelFor(projectLocationTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectLocationLabel, org.openide.util.NbBundle.getMessage(jvmcapsPanelVisual.class, \"jvmcapsPanelVisual.projectLocationLabel.text\")); // NOI18N\n\n        org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(jvmcapsPanelVisual.class, \"jvmcapsPanelVisual.browseButton.text\")); // NOI18N\n        browseButton.setActionCommand(org.openide.util.NbBundle.getMessage(jvmcapsPanelVisual.class, \"jvmcapsPanelVisual.browseButton.actionCommand\")); // NOI18N\n        browseButton.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                browseButtonActionPerformed(evt);\n            }\n        });\n\n        createdFolderLabel.setLabelFor(createdFolderTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(createdFolderLabel, org.openide.util.NbBundle.getMessage(jvmcapsPanelVisual.class, \"jvmcapsPanelVisual.createdFolderLabel.text\")); // NOI18N\n\n        createdFolderTextField.setEditable(false);\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(createdFolderLabel))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(browseButton)\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)\n                    .addComponent(browseButton))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(createdFolderLabel)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addContainerGap(213, Short.MAX_VALUE))\n        );\n    }// </editor-fold>//GEN-END:initComponents\n\n    private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed\n        String command = evt.getActionCommand();\n        if (\"BROWSE\".equals(command)) {\n            JFileChooser chooser = new JFileChooser();\n            FileUtil.preventFileChooserSymlinkTraversal(chooser, null);\n            chooser.setDialogTitle(\"Select Project Location\");\n            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\n            String path = this.projectLocationTextField.getText();\n            if (path.length() > 0) {\n                File f = new File(path);\n                if (f.exists()) {\n                    chooser.setSelectedFile(f);\n                }\n            }\n            if (JFileChooser.APPROVE_OPTION == chooser.showOpenDialog(this)) {\n                File projectDir = chooser.getSelectedFile();\n                projectLocationTextField.setText(FileUtil.normalizeFile(projectDir).getAbsolutePath());\n            }\n            panel.fireChangeEvent();\n        }\n\n    }//GEN-LAST:event_browseButtonActionPerformed\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JButton browseButton;\n    private javax.swing.JLabel createdFolderLabel;\n    private javax.swing.JTextField createdFolderTextField;\n    private javax.swing.JLabel projectLocationLabel;\n    private javax.swing.JTextField projectLocationTextField;\n    private javax.swing.JLabel projectNameLabel;\n    private javax.swing.JTextField projectNameTextField;\n    // End of variables declaration//GEN-END:variables\n\n    @Override\n    public void addNotify() {\n        super.addNotify();\n        //same problem as in 31086, initial focus on Cancel button\n        projectNameTextField.requestFocus();\n    }\n\n    boolean valid(WizardDescriptor wizardDescriptor) {\n\n        if (projectNameTextField.getText().length() == 0) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Name is not a valid folder name.\");\n            return false; // Display name not specified\n\n        }\n        File f = FileUtil.normalizeFile(new File(projectLocationTextField.getText()).getAbsoluteFile());\n        if (!f.isDirectory()) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n        final File destFolder = FileUtil.normalizeFile(new File(createdFolderTextField.getText()).getAbsoluteFile());\n\n        File projLoc = destFolder;\n        while (projLoc != null && !projLoc.exists()) {\n            projLoc = projLoc.getParentFile();\n        }\n        if (projLoc == null || !projLoc.canWrite()) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder cannot be created.\");\n            return false;\n        }\n\n        if (FileUtil.toFileObject(projLoc) == null) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n\n        File[] kids = destFolder.listFiles();\n        if (destFolder.exists() && kids != null && kids.length > 0) {\n            // Folder exists and is not empty\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder already exists and is not empty.\");\n            return false;\n        }\n        wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", \"\");\n        return true;\n    }\n\n    void store(WizardDescriptor d) {\n        String name = projectNameTextField.getText().trim();\n        String folder = createdFolderTextField.getText().trim();\n\n        d.putProperty(\"projdir\", new File(folder));\n        d.putProperty(\"name\", name);\n    }\n\n    void read(WizardDescriptor settings) {\n        File projectLocation = (File) settings.getProperty(\"projdir\");\n        if (projectLocation == null || projectLocation.getParentFile() == null || !projectLocation.getParentFile().isDirectory()) {\n            projectLocation = ProjectChooser.getProjectsFolder();\n        } else {\n            projectLocation = projectLocation.getParentFile();\n        }\n        this.projectLocationTextField.setText(projectLocation.getAbsolutePath());\n\n        String projectName = (String) settings.getProperty(\"name\");\n        if (projectName == null) {\n            projectName = \"jvmcaps\";\n        }\n        this.projectNameTextField.setText(projectName);\n        this.projectNameTextField.selectAll();\n    }\n\n    void validate(WizardDescriptor d) throws WizardValidationException {\n        // nothing to validate\n    }\n\n    // Implementation of DocumentListener --------------------------------------\n    public void changedUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void insertUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void removeUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    /** Handles changes in the Project name and project directory, */\n    private void updateTexts(DocumentEvent e) {\n\n        Document doc = e.getDocument();\n\n        if (doc == projectNameTextField.getDocument() || doc == projectLocationTextField.getDocument()) {\n            // Change in the project name\n\n            String projectName = projectNameTextField.getText();\n            String projectFolder = projectLocationTextField.getText();\n\n            //if (projectFolder.trim().length() == 0 || projectFolder.equals(oldName)) {\n            createdFolderTextField.setText(projectFolder + File.separatorChar + projectName);\n        //}\n\n        }\n        panel.fireChangeEvent(); // Notify that the panel changed\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/jvmcaps/jvmcapsWizardIterator.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.jvmcaps;\n\nimport java.awt.Component;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.text.MessageFormat;\nimport java.util.Enumeration;\nimport java.util.LinkedHashSet;\nimport java.util.NoSuchElementException;\nimport java.util.Set;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\nimport javax.swing.JComponent;\nimport javax.swing.event.ChangeListener;\nimport org.netbeans.api.project.ProjectManager;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.netbeans.spi.project.ui.templates.support.Templates;\nimport org.openide.WizardDescriptor;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.xml.XMLUtil;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.NodeList;\nimport org.xml.sax.InputSource;\n\npublic class jvmcapsWizardIterator implements WizardDescriptor./*Progress*/InstantiatingIterator {\n\n    private int index;\n    private WizardDescriptor.Panel[] panels;\n    private WizardDescriptor wiz;\n\n    public jvmcapsWizardIterator() {\n    }\n\n    public static jvmcapsWizardIterator createIterator() {\n        return new jvmcapsWizardIterator();\n    }\n\n    private WizardDescriptor.Panel[] createPanels() {\n        return new WizardDescriptor.Panel[]{\n                    new jvmcapsWizardPanel(),\n                };\n    }\n\n    private String[] createSteps() {\n        return new String[]{\n                    NbBundle.getMessage(jvmcapsWizardIterator.class, \"LBL_CreateProjectStep\")\n                };\n    }\n\n    public Set/*<FileObject>*/ instantiate(/*ProgressHandle handle*/) throws IOException {\n        Set<FileObject> resultSet = new LinkedHashSet<FileObject>();\n        File dirF = FileUtil.normalizeFile((File) wiz.getProperty(\"projdir\"));\n        dirF.mkdirs();\n\n        FileObject template = Templates.getTemplate(wiz);\n        FileObject dir = FileUtil.toFileObject(dirF);\n        unZipFile(template.getInputStream(), dir);\n\n        // Always open top dir as a project:\n        resultSet.add(dir);\n        // Look for nested projects to open as well:\n        Enumeration<? extends FileObject> e = dir.getFolders(true);\n        while (e.hasMoreElements()) {\n            FileObject subfolder = e.nextElement();\n            if (ProjectManager.getDefault().isProject(subfolder)) {\n                resultSet.add(subfolder);\n            }\n        }\n\n        File parent = dirF.getParentFile();\n        if (parent != null && parent.exists()) {\n            ProjectChooser.setProjectsFolder(parent);\n        }\n\n        return resultSet;\n    }\n\n    public void initialize(WizardDescriptor wiz) {\n        this.wiz = wiz;\n        index = 0;\n        panels = createPanels();\n        // Make sure list of steps is accurate.\n        String[] steps = createSteps();\n        for (int i = 0; i < panels.length; i++) {\n            Component c = panels[i].getComponent();\n            if (steps[i] == null) {\n                // Default step name to component name of panel.\n                // Mainly useful for getting the name of the target\n                // chooser to appear in the list of steps.\n                steps[i] = c.getName();\n            }\n            if (c instanceof JComponent) { // assume Swing components\n\n                JComponent jc = (JComponent) c;\n                // Step #.\n                jc.putClientProperty(\"WizardPanel_contentSelectedIndex\", new Integer(i));\n                // Step name (actually the whole list for reference).\n                jc.putClientProperty(\"WizardPanel_contentData\", steps);\n            }\n        }\n    }\n\n    public void uninitialize(WizardDescriptor wiz) {\n        this.wiz.putProperty(\"projdir\", null);\n        this.wiz.putProperty(\"name\", null);\n        this.wiz = null;\n        panels = null;\n    }\n\n    public String name() {\n        return MessageFormat.format(\"{0} of {1}\",\n                new Object[]{new Integer(index + 1), new Integer(panels.length)});\n    }\n\n    public boolean hasNext() {\n        return index < panels.length - 1;\n    }\n\n    public boolean hasPrevious() {\n        return index > 0;\n    }\n\n    public void nextPanel() {\n        if (!hasNext()) {\n            throw new NoSuchElementException();\n        }\n        index++;\n    }\n\n    public void previousPanel() {\n        if (!hasPrevious()) {\n            throw new NoSuchElementException();\n        }\n        index--;\n    }\n\n    public WizardDescriptor.Panel current() {\n        return panels[index];\n    }\n\n    // If nothing unusual changes in the middle of the wizard, simply:\n    public final void addChangeListener(ChangeListener l) {\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n    }\n\n    private static void unZipFile(InputStream source, FileObject projectRoot) throws IOException {\n        try {\n            ZipInputStream str = new ZipInputStream(source);\n            ZipEntry entry;\n            while ((entry = str.getNextEntry()) != null) {\n                if (entry.isDirectory()) {\n                    FileUtil.createFolder(projectRoot, entry.getName());\n                } else {\n                    FileObject fo = FileUtil.createData(projectRoot, entry.getName());\n                    if (\"nbproject/project.xml\".equals(entry.getName())) {\n                        // Special handling for setting name of Ant-based projects; customize as needed:\n                        filterProjectXML(fo, str, projectRoot.getName());\n                    } else {\n                        writeFile(str, fo);\n                    }\n                }\n            }\n        } finally {\n            source.close();\n        }\n    }\n\n    private static void writeFile(ZipInputStream str, FileObject fo) throws IOException {\n        OutputStream out = fo.getOutputStream();\n        try {\n            FileUtil.copy(str, out);\n        } finally {\n            out.close();\n        }\n    }\n\n    private static void filterProjectXML(FileObject fo, ZipInputStream str, String name) throws IOException {\n        try {\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            FileUtil.copy(str, baos);\n            Document doc = XMLUtil.parse(new InputSource(new ByteArrayInputStream(baos.toByteArray())), false, false, null, null);\n            NodeList nl = doc.getDocumentElement().getElementsByTagName(\"name\");\n            if (nl != null) {\n                for (int i = 0; i < nl.getLength(); i++) {\n                    Element el = (Element) nl.item(i);\n                    if (el.getParentNode() != null && \"data\".equals(el.getParentNode().getNodeName())) {\n                        NodeList nl2 = el.getChildNodes();\n                        if (nl2.getLength() > 0) {\n                            nl2.item(0).setNodeValue(name);\n                        }\n                        break;\n                    }\n                }\n            }\n            OutputStream out = fo.getOutputStream();\n            try {\n                XMLUtil.write(doc, out, \"UTF-8\");\n            } finally {\n                out.close();\n            }\n        } catch (Exception ex) {\n            Exceptions.printStackTrace(ex);\n            writeFile(str, fo);\n        }\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/jvmcaps/jvmcapsWizardPanel.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.jvmcaps;\n\nimport java.awt.Component;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\n\n/**\n * Panel just asking for basic info.\n */\npublic class jvmcapsWizardPanel implements WizardDescriptor.Panel,\n        WizardDescriptor.ValidatingPanel, WizardDescriptor.FinishablePanel {\n\n    private WizardDescriptor wizardDescriptor;\n    private jvmcapsPanelVisual component;\n\n    public jvmcapsWizardPanel() {\n    }\n\n    public Component getComponent() {\n        if (component == null) {\n            component = new jvmcapsPanelVisual(this);\n            component.setName(NbBundle.getMessage(jvmcapsWizardPanel.class, \"LBL_CreateProjectStep\"));\n        }\n        return component;\n    }\n\n    public HelpCtx getHelp() {\n        return new HelpCtx(jvmcapsWizardPanel.class);\n    }\n\n    public boolean isValid() {\n        getComponent();\n        return component.valid(wizardDescriptor);\n    }\n    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0\n\n\n    public final void addChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.add(l);\n        }\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.remove(l);\n        }\n    }\n\n    protected final void fireChangeEvent() {\n        Set<ChangeListener> ls;\n        synchronized (listeners) {\n            ls = new HashSet<ChangeListener>(listeners);\n        }\n        ChangeEvent ev = new ChangeEvent(this);\n        for (ChangeListener l : ls) {\n            l.stateChanged(ev);\n        }\n    }\n\n    public void readSettings(Object settings) {\n        wizardDescriptor = (WizardDescriptor) settings;\n        component.read(wizardDescriptor);\n    }\n\n    public void storeSettings(Object settings) {\n        WizardDescriptor d = (WizardDescriptor) settings;\n        component.store(d);\n    }\n\n    public boolean isFinishPanel() {\n        return true;\n    }\n\n    public void validate() throws WizardValidationException {\n        getComponent();\n        component.validate(wizardDescriptor);\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    \n    <folder name=\"Templates\">\n        <folder name=\"Project\">\n            <folder name=\"Samples\">\n                <folder name=\"VisualVM\">\n                    <file name=\"hellovvmProject.zip\" url=\"hellovvmProject.zip\">\n                        <attr name=\"SystemFileSystem.icon\" urlvalue=\"nbresloc:/org/nb/samplebundle/vvm.png\"/>\n                        <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.nb.samplebundle.Bundle\"/>\n                        <attr name=\"instantiatingIterator\" methodvalue=\"org.nb.samplebundle.hellovvm.hellovvmWizardIterator.createIterator\"/>\n                        <attr name=\"instantiatingWizardURL\" urlvalue=\"nbresloc:/org/nb/samplebundle/hellovvm/hellovvmDescription.html\"/>\n                        <attr name=\"position\" intvalue=\"100\"/>\n                        <attr name=\"template\" boolvalue=\"true\"/>\n                    </file>\n                    <file name=\"pluggableViewDemoSuiteProject.zip\" url=\"pluggableViewDemoSuiteProject.zip\">\n                        <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.nb.samplebundle.Bundle\"/>\n                        <attr name=\"SystemFileSystem.icon\" urlvalue=\"nbresloc:/org/nb/samplebundle/vvm.png\"/>\n                        <attr name=\"instantiatingIterator\" methodvalue=\"org.nb.samplebundle.pluggableViewDemoSuite.pluggableViewDemoSuiteWizardIterator.createIterator\"/>\n                        <attr name=\"instantiatingWizardURL\" urlvalue=\"nbresloc:/org/nb/samplebundle/pluggableViewDemoSuite/pluggableViewDemoSuiteDescription.html\"/>\n                        <attr name=\"position\" intvalue=\"200\"/>\n                        <attr name=\"template\" boolvalue=\"true\"/>\n                    </file>\n                    <file name=\"apptypeProject.zip\" url=\"apptypeProject.zip\">\n                        <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.nb.samplebundle.Bundle\"/>\n                        <attr name=\"SystemFileSystem.icon\" urlvalue=\"nbresloc:/org/nb/samplebundle/vvm.png\"/>\n                        <attr name=\"instantiatingIterator\" methodvalue=\"org.nb.samplebundle.apptype.apptypeWizardIterator.createIterator\"/>\n                        <attr name=\"instantiatingWizardURL\" urlvalue=\"nbresloc:/org/nb/samplebundle/apptype/apptypeDescription.html\"/>\n                        <attr name=\"position\" intvalue=\"300\"/>\n                        <attr name=\"template\" boolvalue=\"true\"/>\n                    </file>\n                    <file name=\"datasourceProject.zip\" url=\"datasourceProject.zip\">\n                        <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.nb.samplebundle.Bundle\"/>\n                        <attr name=\"SystemFileSystem.icon\" urlvalue=\"nbresloc:/org/nb/samplebundle/vvm.png\"/>\n                        <attr name=\"instantiatingIterator\" methodvalue=\"org.nb.samplebundle.datasource.datasourceWizardIterator.createIterator\"/>\n                        <attr name=\"instantiatingWizardURL\" urlvalue=\"nbresloc:/org/nb/samplebundle/datasource/datasourceDescription.html\"/>\n                        <attr name=\"position\" intvalue=\"400\"/>\n                        <attr name=\"template\" boolvalue=\"true\"/>\n                    </file>\n                    <file name=\"hostviewProject.zip\" url=\"hostviewProject.zip\">\n                        <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.nb.samplebundle.Bundle\"/>\n                        <attr name=\"SystemFileSystem.icon\" urlvalue=\"nbresloc:/org/nb/samplebundle/vvm.png\"/>\n                        <attr name=\"instantiatingIterator\" methodvalue=\"org.nb.samplebundle.hostview.hostviewWizardIterator.createIterator\"/>\n                        <attr name=\"instantiatingWizardURL\" urlvalue=\"nbresloc:/org/nb/samplebundle/hostview/hostviewDescription.html\"/>\n                        <attr name=\"position\" intvalue=\"500\"/>\n                        <attr name=\"template\" boolvalue=\"true\"/>\n                    </file>\n                    <file name=\"jvmcapsProject.zip\" url=\"jvmcapsProject.zip\">\n                        <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.nb.samplebundle.Bundle\"/>\n                        <attr name=\"SystemFileSystem.icon\" urlvalue=\"nbresloc:/org/nb/samplebundle/vvm.png\"/>\n                        <attr name=\"instantiatingIterator\" methodvalue=\"org.nb.samplebundle.jvmcaps.jvmcapsWizardIterator.createIterator\"/>\n                        <attr name=\"instantiatingWizardURL\" urlvalue=\"nbresloc:/org/nb/samplebundle/jvmcaps/jvmcapsDescription.html\"/>\n                        <attr name=\"position\" intvalue=\"600\"/>\n                        <attr name=\"template\" boolvalue=\"true\"/>\n                    </file>\n                    <file name=\"subnodesProject.zip\" url=\"subnodesProject.zip\">\n                        <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.nb.samplebundle.Bundle\"/>\n                        <attr name=\"SystemFileSystem.icon\" urlvalue=\"nbresloc:/org/nb/samplebundle/vvm.png\"/>\n                        <attr name=\"instantiatingIterator\" methodvalue=\"org.nb.samplebundle.subnodes.subnodesWizardIterator.createIterator\"/>\n                        <attr name=\"instantiatingWizardURL\" urlvalue=\"nbresloc:/org/nb/samplebundle/subnodes/subnodesDescription.html\"/>\n                        <attr name=\"position\" intvalue=\"700\"/>\n                        <attr name=\"template\" boolvalue=\"true\"/>\n                    </file>\n                </folder>\n            </folder>\n        </folder>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/pluggableViewDemoSuite/Bundle.properties",
    "content": "LBL_CreateProjectStep=Name and Location\npluggableViewDemoSuitePanelVisual.projectNameLabel.text=Project &Name:\npluggableViewDemoSuitePanelVisual.projectLocationLabel.text=Project &Location:\npluggableViewDemoSuitePanelVisual.browseButton.actionCommand=BROWSE\npluggableViewDemoSuitePanelVisual.browseButton.text=Br&owse...\npluggableViewDemoSuitePanelVisual.createdFolderLabel.text=Project &Folder:\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/pluggableViewDemoSuite/pluggableViewDemoSuiteDescription.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n        Gives you a module suite with\n        two modules, one providing a\n        pluggable view and the other\n        plugging a subtab into it.\n    </body>\n</html>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/pluggableViewDemoSuite/pluggableViewDemoSuitePanelVisual.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.5\" maxVersion=\"1.6\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"browseButton\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectNameTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectLocationLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"browseButton\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"createdFolderLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace pref=\"213\" max=\"32767\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"projectNameLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectNameTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/pluggableViewDemoSuite/Bundle.properties\" key=\"pluggableViewDemoSuitePanelVisual.projectNameLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectNameTextField\">\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"projectLocationLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectLocationTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/pluggableViewDemoSuite/Bundle.properties\" key=\"pluggableViewDemoSuitePanelVisual.projectLocationLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectLocationTextField\">\n    </Component>\n    <Component class=\"javax.swing.JButton\" name=\"browseButton\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/pluggableViewDemoSuite/Bundle.properties\" key=\"pluggableViewDemoSuitePanelVisual.browseButton.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n        <Property name=\"actionCommand\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/pluggableViewDemoSuite/Bundle.properties\" key=\"pluggableViewDemoSuitePanelVisual.browseButton.actionCommand\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"browseButtonActionPerformed\"/>\n      </Events>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"createdFolderLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"createdFolderTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/pluggableViewDemoSuite/Bundle.properties\" key=\"pluggableViewDemoSuitePanelVisual.createdFolderLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"createdFolderTextField\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/pluggableViewDemoSuite/pluggableViewDemoSuitePanelVisual.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.nb.samplebundle.pluggableViewDemoSuite;\n\nimport java.io.File;\nimport javax.swing.JFileChooser;\nimport javax.swing.JPanel;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.Document;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.filesystems.FileUtil;\n\npublic class pluggableViewDemoSuitePanelVisual extends JPanel implements DocumentListener {\n\n    public static final String PROP_PROJECT_NAME = \"projectName\";\n\n    private pluggableViewDemoSuiteWizardPanel panel;\n\n    public pluggableViewDemoSuitePanelVisual(pluggableViewDemoSuiteWizardPanel panel) {\n        initComponents();\n        this.panel = panel;\n        // Register listener on the textFields to make the automatic updates\n        projectNameTextField.getDocument().addDocumentListener(this);\n        projectLocationTextField.getDocument().addDocumentListener(this);\n    }\n\n    public String getProjectName() {\n        return this.projectNameTextField.getText();\n    }\n\n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        projectNameLabel = new javax.swing.JLabel();\n        projectNameTextField = new javax.swing.JTextField();\n        projectLocationLabel = new javax.swing.JLabel();\n        projectLocationTextField = new javax.swing.JTextField();\n        browseButton = new javax.swing.JButton();\n        createdFolderLabel = new javax.swing.JLabel();\n        createdFolderTextField = new javax.swing.JTextField();\n\n        projectNameLabel.setLabelFor(projectNameTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectNameLabel, org.openide.util.NbBundle.getMessage(pluggableViewDemoSuitePanelVisual.class, \"pluggableViewDemoSuitePanelVisual.projectNameLabel.text\")); // NOI18N\n\n        projectLocationLabel.setLabelFor(projectLocationTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectLocationLabel, org.openide.util.NbBundle.getMessage(pluggableViewDemoSuitePanelVisual.class, \"pluggableViewDemoSuitePanelVisual.projectLocationLabel.text\")); // NOI18N\n\n        org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(pluggableViewDemoSuitePanelVisual.class, \"pluggableViewDemoSuitePanelVisual.browseButton.text\")); // NOI18N\n        browseButton.setActionCommand(org.openide.util.NbBundle.getMessage(pluggableViewDemoSuitePanelVisual.class, \"pluggableViewDemoSuitePanelVisual.browseButton.actionCommand\")); // NOI18N\n        browseButton.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                browseButtonActionPerformed(evt);\n            }\n        });\n\n        createdFolderLabel.setLabelFor(createdFolderTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(createdFolderLabel, org.openide.util.NbBundle.getMessage(pluggableViewDemoSuitePanelVisual.class, \"pluggableViewDemoSuitePanelVisual.createdFolderLabel.text\")); // NOI18N\n\n        createdFolderTextField.setEditable(false);\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(createdFolderLabel))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(browseButton)\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)\n                    .addComponent(browseButton))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(createdFolderLabel)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addContainerGap(213, Short.MAX_VALUE))\n        );\n    }// </editor-fold>//GEN-END:initComponents\n\n    private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed\n        String command = evt.getActionCommand();\n        if (\"BROWSE\".equals(command)) {\n            JFileChooser chooser = new JFileChooser();\n            FileUtil.preventFileChooserSymlinkTraversal(chooser, null);\n            chooser.setDialogTitle(\"Select Project Location\");\n            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\n            String path = this.projectLocationTextField.getText();\n            if (path.length() > 0) {\n                File f = new File(path);\n                if (f.exists()) {\n                    chooser.setSelectedFile(f);\n                }\n            }\n            if (JFileChooser.APPROVE_OPTION == chooser.showOpenDialog(this)) {\n                File projectDir = chooser.getSelectedFile();\n                projectLocationTextField.setText(FileUtil.normalizeFile(projectDir).getAbsolutePath());\n            }\n            panel.fireChangeEvent();\n        }\n\n    }//GEN-LAST:event_browseButtonActionPerformed\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JButton browseButton;\n    private javax.swing.JLabel createdFolderLabel;\n    private javax.swing.JTextField createdFolderTextField;\n    private javax.swing.JLabel projectLocationLabel;\n    private javax.swing.JTextField projectLocationTextField;\n    private javax.swing.JLabel projectNameLabel;\n    private javax.swing.JTextField projectNameTextField;\n    // End of variables declaration//GEN-END:variables\n\n    @Override\n    public void addNotify() {\n        super.addNotify();\n        //same problem as in 31086, initial focus on Cancel button\n        projectNameTextField.requestFocus();\n    }\n\n    boolean valid(WizardDescriptor wizardDescriptor) {\n\n        if (projectNameTextField.getText().length() == 0) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Name is not a valid folder name.\");\n            return false; // Display name not specified\n\n        }\n        File f = FileUtil.normalizeFile(new File(projectLocationTextField.getText()).getAbsoluteFile());\n        if (!f.isDirectory()) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n        final File destFolder = FileUtil.normalizeFile(new File(createdFolderTextField.getText()).getAbsoluteFile());\n\n        File projLoc = destFolder;\n        while (projLoc != null && !projLoc.exists()) {\n            projLoc = projLoc.getParentFile();\n        }\n        if (projLoc == null || !projLoc.canWrite()) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder cannot be created.\");\n            return false;\n        }\n\n        if (FileUtil.toFileObject(projLoc) == null) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n\n        File[] kids = destFolder.listFiles();\n        if (destFolder.exists() && kids != null && kids.length > 0) {\n            // Folder exists and is not empty\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder already exists and is not empty.\");\n            return false;\n        }\n        wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", \"\");\n        return true;\n    }\n\n    void store(WizardDescriptor d) {\n        String name = projectNameTextField.getText().trim();\n        String folder = createdFolderTextField.getText().trim();\n\n        d.putProperty(\"projdir\", new File(folder));\n        d.putProperty(\"name\", name);\n    }\n\n    void read(WizardDescriptor settings) {\n        File projectLocation = (File) settings.getProperty(\"projdir\");\n        if (projectLocation == null || projectLocation.getParentFile() == null || !projectLocation.getParentFile().isDirectory()) {\n            projectLocation = ProjectChooser.getProjectsFolder();\n        } else {\n            projectLocation = projectLocation.getParentFile();\n        }\n        this.projectLocationTextField.setText(projectLocation.getAbsolutePath());\n\n        String projectName = (String) settings.getProperty(\"name\");\n        if (projectName == null) {\n            projectName = \"pluggableViewDemoSuite\";\n        }\n        this.projectNameTextField.setText(projectName);\n        this.projectNameTextField.selectAll();\n    }\n\n    void validate(WizardDescriptor d) throws WizardValidationException {\n        // nothing to validate\n    }\n\n    // Implementation of DocumentListener --------------------------------------\n    public void changedUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void insertUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void removeUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    /** Handles changes in the Project name and project directory, */\n    private void updateTexts(DocumentEvent e) {\n\n        Document doc = e.getDocument();\n\n        if (doc == projectNameTextField.getDocument() || doc == projectLocationTextField.getDocument()) {\n            // Change in the project name\n\n            String projectName = projectNameTextField.getText();\n            String projectFolder = projectLocationTextField.getText();\n\n            //if (projectFolder.trim().length() == 0 || projectFolder.equals(oldName)) {\n            createdFolderTextField.setText(projectFolder + File.separatorChar + projectName);\n        //}\n\n        }\n        panel.fireChangeEvent(); // Notify that the panel changed\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/pluggableViewDemoSuite/pluggableViewDemoSuiteWizardIterator.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.pluggableViewDemoSuite;\n\nimport java.awt.Component;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.text.MessageFormat;\nimport java.util.Enumeration;\nimport java.util.LinkedHashSet;\nimport java.util.NoSuchElementException;\nimport java.util.Set;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\nimport javax.swing.JComponent;\nimport javax.swing.event.ChangeListener;\nimport org.netbeans.api.project.ProjectManager;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.netbeans.spi.project.ui.templates.support.Templates;\nimport org.openide.WizardDescriptor;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.xml.XMLUtil;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.NodeList;\nimport org.xml.sax.InputSource;\n\npublic class pluggableViewDemoSuiteWizardIterator implements WizardDescriptor./*Progress*/InstantiatingIterator {\n\n    private int index;\n    private WizardDescriptor.Panel[] panels;\n    private WizardDescriptor wiz;\n\n    public pluggableViewDemoSuiteWizardIterator() {\n    }\n\n    public static pluggableViewDemoSuiteWizardIterator createIterator() {\n        return new pluggableViewDemoSuiteWizardIterator();\n    }\n\n    private WizardDescriptor.Panel[] createPanels() {\n        return new WizardDescriptor.Panel[]{\n                    new pluggableViewDemoSuiteWizardPanel(),\n                };\n    }\n\n    private String[] createSteps() {\n        return new String[]{\n                    NbBundle.getMessage(pluggableViewDemoSuiteWizardIterator.class, \"LBL_CreateProjectStep\")\n                };\n    }\n\n    public Set/*<FileObject>*/ instantiate(/*ProgressHandle handle*/) throws IOException {\n        Set<FileObject> resultSet = new LinkedHashSet<FileObject>();\n        File dirF = FileUtil.normalizeFile((File) wiz.getProperty(\"projdir\"));\n        dirF.mkdirs();\n\n        FileObject template = Templates.getTemplate(wiz);\n        FileObject dir = FileUtil.toFileObject(dirF);\n        unZipFile(template.getInputStream(), dir);\n\n        // Always open top dir as a project:\n        resultSet.add(dir);\n        // Look for nested projects to open as well:\n        Enumeration<? extends FileObject> e = dir.getFolders(true);\n        while (e.hasMoreElements()) {\n            FileObject subfolder = e.nextElement();\n            if (ProjectManager.getDefault().isProject(subfolder)) {\n                resultSet.add(subfolder);\n            }\n        }\n\n        File parent = dirF.getParentFile();\n        if (parent != null && parent.exists()) {\n            ProjectChooser.setProjectsFolder(parent);\n        }\n\n        return resultSet;\n    }\n\n    public void initialize(WizardDescriptor wiz) {\n        this.wiz = wiz;\n        index = 0;\n        panels = createPanels();\n        // Make sure list of steps is accurate.\n        String[] steps = createSteps();\n        for (int i = 0; i < panels.length; i++) {\n            Component c = panels[i].getComponent();\n            if (steps[i] == null) {\n                // Default step name to component name of panel.\n                // Mainly useful for getting the name of the target\n                // chooser to appear in the list of steps.\n                steps[i] = c.getName();\n            }\n            if (c instanceof JComponent) { // assume Swing components\n\n                JComponent jc = (JComponent) c;\n                // Step #.\n                jc.putClientProperty(\"WizardPanel_contentSelectedIndex\", new Integer(i));\n                // Step name (actually the whole list for reference).\n                jc.putClientProperty(\"WizardPanel_contentData\", steps);\n            }\n        }\n    }\n\n    public void uninitialize(WizardDescriptor wiz) {\n        this.wiz.putProperty(\"projdir\", null);\n        this.wiz.putProperty(\"name\", null);\n        this.wiz = null;\n        panels = null;\n    }\n\n    public String name() {\n        return MessageFormat.format(\"{0} of {1}\",\n                new Object[]{new Integer(index + 1), new Integer(panels.length)});\n    }\n\n    public boolean hasNext() {\n        return index < panels.length - 1;\n    }\n\n    public boolean hasPrevious() {\n        return index > 0;\n    }\n\n    public void nextPanel() {\n        if (!hasNext()) {\n            throw new NoSuchElementException();\n        }\n        index++;\n    }\n\n    public void previousPanel() {\n        if (!hasPrevious()) {\n            throw new NoSuchElementException();\n        }\n        index--;\n    }\n\n    public WizardDescriptor.Panel current() {\n        return panels[index];\n    }\n\n    // If nothing unusual changes in the middle of the wizard, simply:\n    public final void addChangeListener(ChangeListener l) {\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n    }\n\n    private static void unZipFile(InputStream source, FileObject projectRoot) throws IOException {\n        try {\n            ZipInputStream str = new ZipInputStream(source);\n            ZipEntry entry;\n            while ((entry = str.getNextEntry()) != null) {\n                if (entry.isDirectory()) {\n                    FileUtil.createFolder(projectRoot, entry.getName());\n                } else {\n                    FileObject fo = FileUtil.createData(projectRoot, entry.getName());\n                    if (\"nbproject/project.xml\".equals(entry.getName())) {\n                        // Special handling for setting name of Ant-based projects; customize as needed:\n                        filterProjectXML(fo, str, projectRoot.getName());\n                    } else {\n                        writeFile(str, fo);\n                    }\n                }\n            }\n        } finally {\n            source.close();\n        }\n    }\n\n    private static void writeFile(ZipInputStream str, FileObject fo) throws IOException {\n        OutputStream out = fo.getOutputStream();\n        try {\n            FileUtil.copy(str, out);\n        } finally {\n            out.close();\n        }\n    }\n\n    private static void filterProjectXML(FileObject fo, ZipInputStream str, String name) throws IOException {\n        try {\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            FileUtil.copy(str, baos);\n            Document doc = XMLUtil.parse(new InputSource(new ByteArrayInputStream(baos.toByteArray())), false, false, null, null);\n            NodeList nl = doc.getDocumentElement().getElementsByTagName(\"name\");\n            if (nl != null) {\n                for (int i = 0; i < nl.getLength(); i++) {\n                    Element el = (Element) nl.item(i);\n                    if (el.getParentNode() != null && \"data\".equals(el.getParentNode().getNodeName())) {\n                        NodeList nl2 = el.getChildNodes();\n                        if (nl2.getLength() > 0) {\n                            nl2.item(0).setNodeValue(name);\n                        }\n                        break;\n                    }\n                }\n            }\n            OutputStream out = fo.getOutputStream();\n            try {\n                XMLUtil.write(doc, out, \"UTF-8\");\n            } finally {\n                out.close();\n            }\n        } catch (Exception ex) {\n            Exceptions.printStackTrace(ex);\n            writeFile(str, fo);\n        }\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/pluggableViewDemoSuite/pluggableViewDemoSuiteWizardPanel.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.pluggableViewDemoSuite;\n\nimport java.awt.Component;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\n\n/**\n * Panel just asking for basic info.\n */\npublic class pluggableViewDemoSuiteWizardPanel implements WizardDescriptor.Panel,\n        WizardDescriptor.ValidatingPanel, WizardDescriptor.FinishablePanel {\n\n    private WizardDescriptor wizardDescriptor;\n    private pluggableViewDemoSuitePanelVisual component;\n\n    public pluggableViewDemoSuiteWizardPanel() {\n    }\n\n    public Component getComponent() {\n        if (component == null) {\n            component = new pluggableViewDemoSuitePanelVisual(this);\n            component.setName(NbBundle.getMessage(pluggableViewDemoSuiteWizardPanel.class, \"LBL_CreateProjectStep\"));\n        }\n        return component;\n    }\n\n    public HelpCtx getHelp() {\n        return new HelpCtx(pluggableViewDemoSuiteWizardPanel.class);\n    }\n\n    public boolean isValid() {\n        getComponent();\n        return component.valid(wizardDescriptor);\n    }\n    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0\n\n\n    public final void addChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.add(l);\n        }\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.remove(l);\n        }\n    }\n\n    protected final void fireChangeEvent() {\n        Set<ChangeListener> ls;\n        synchronized (listeners) {\n            ls = new HashSet<ChangeListener>(listeners);\n        }\n        ChangeEvent ev = new ChangeEvent(this);\n        for (ChangeListener l : ls) {\n            l.stateChanged(ev);\n        }\n    }\n\n    public void readSettings(Object settings) {\n        wizardDescriptor = (WizardDescriptor) settings;\n        component.read(wizardDescriptor);\n    }\n\n    public void storeSettings(Object settings) {\n        WizardDescriptor d = (WizardDescriptor) settings;\n        component.store(d);\n    }\n\n    public boolean isFinishPanel() {\n        return true;\n    }\n\n    public void validate() throws WizardValidationException {\n        getComponent();\n        component.validate(wizardDescriptor);\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/subnodes/Bundle.properties",
    "content": "LBL_CreateProjectStep=Name and Location\nsubnodesPanelVisual.projectNameLabel.text=Project &Name:\nsubnodesPanelVisual.projectLocationLabel.text=Project &Location:\nsubnodesPanelVisual.createdFolderLabel.text=Project &Folder:\nsubnodesPanelVisual.browseButton.actionCommand=BROWSE\nsubnodesPanelVisual.browseButton.text=Br&owse...\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/subnodes/subnodesDescription.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n        Gives you an application type\n        for the Anagram Game, with\n        subnodes for attributes obtained\n        from a JMX bean defined for the game.\n    </body>\n</html>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/subnodes/subnodesPanelVisual.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.5\" maxVersion=\"1.6\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderLabel\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"projectNameTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"1\" pref=\"191\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"browseButton\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectNameLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectNameTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"projectLocationLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"projectLocationTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"browseButton\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"createdFolderLabel\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFolderTextField\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace pref=\"213\" max=\"32767\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"projectNameLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectNameTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/subnodes/Bundle.properties\" key=\"subnodesPanelVisual.projectNameLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectNameTextField\">\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"projectLocationLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"projectLocationTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/subnodes/Bundle.properties\" key=\"subnodesPanelVisual.projectLocationLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"projectLocationTextField\">\n    </Component>\n    <Component class=\"javax.swing.JButton\" name=\"browseButton\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/subnodes/Bundle.properties\" key=\"subnodesPanelVisual.browseButton.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n        <Property name=\"actionCommand\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/subnodes/Bundle.properties\" key=\"subnodesPanelVisual.browseButton.actionCommand\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"browseButtonActionPerformed\"/>\n      </Events>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"createdFolderLabel\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"createdFolderTextField\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/nb/samplebundle/subnodes/Bundle.properties\" key=\"subnodesPanelVisual.createdFolderLabel.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"createdFolderTextField\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/subnodes/subnodesPanelVisual.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.nb.samplebundle.subnodes;\n\nimport java.io.File;\nimport javax.swing.JFileChooser;\nimport javax.swing.JPanel;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.Document;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.filesystems.FileUtil;\n\npublic class subnodesPanelVisual extends JPanel implements DocumentListener {\n\n    public static final String PROP_PROJECT_NAME = \"projectName\";\n\n    private subnodesWizardPanel panel;\n\n    public subnodesPanelVisual(subnodesWizardPanel panel) {\n        initComponents();\n        this.panel = panel;\n        // Register listener on the textFields to make the automatic updates\n        projectNameTextField.getDocument().addDocumentListener(this);\n        projectLocationTextField.getDocument().addDocumentListener(this);\n    }\n\n    public String getProjectName() {\n        return this.projectNameTextField.getText();\n    }\n\n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        projectNameLabel = new javax.swing.JLabel();\n        projectNameTextField = new javax.swing.JTextField();\n        projectLocationLabel = new javax.swing.JLabel();\n        projectLocationTextField = new javax.swing.JTextField();\n        browseButton = new javax.swing.JButton();\n        createdFolderLabel = new javax.swing.JLabel();\n        createdFolderTextField = new javax.swing.JTextField();\n\n        projectNameLabel.setLabelFor(projectNameTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectNameLabel, org.openide.util.NbBundle.getMessage(subnodesPanelVisual.class, \"subnodesPanelVisual.projectNameLabel.text\")); // NOI18N\n\n        projectLocationLabel.setLabelFor(projectLocationTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(projectLocationLabel, org.openide.util.NbBundle.getMessage(subnodesPanelVisual.class, \"subnodesPanelVisual.projectLocationLabel.text\")); // NOI18N\n\n        org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(subnodesPanelVisual.class, \"subnodesPanelVisual.browseButton.text\")); // NOI18N\n        browseButton.setActionCommand(org.openide.util.NbBundle.getMessage(subnodesPanelVisual.class, \"subnodesPanelVisual.browseButton.actionCommand\")); // NOI18N\n        browseButton.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                browseButtonActionPerformed(evt);\n            }\n        });\n\n        createdFolderLabel.setLabelFor(createdFolderTextField);\n        org.openide.awt.Mnemonics.setLocalizedText(createdFolderLabel, org.openide.util.NbBundle.getMessage(subnodesPanelVisual.class, \"subnodesPanelVisual.createdFolderLabel.text\")); // NOI18N\n\n        createdFolderTextField.setEditable(false);\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(createdFolderLabel))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(browseButton)\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectNameLabel)\n                    .addComponent(projectNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(projectLocationLabel)\n                    .addComponent(projectLocationTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)\n                    .addComponent(browseButton))\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)\n                    .addComponent(createdFolderLabel)\n                    .addComponent(createdFolderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))\n                .addContainerGap(213, Short.MAX_VALUE))\n        );\n    }// </editor-fold>//GEN-END:initComponents\n\n    private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed\n        String command = evt.getActionCommand();\n        if (\"BROWSE\".equals(command)) {\n            JFileChooser chooser = new JFileChooser();\n            FileUtil.preventFileChooserSymlinkTraversal(chooser, null);\n            chooser.setDialogTitle(\"Select Project Location\");\n            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\n            String path = this.projectLocationTextField.getText();\n            if (path.length() > 0) {\n                File f = new File(path);\n                if (f.exists()) {\n                    chooser.setSelectedFile(f);\n                }\n            }\n            if (JFileChooser.APPROVE_OPTION == chooser.showOpenDialog(this)) {\n                File projectDir = chooser.getSelectedFile();\n                projectLocationTextField.setText(FileUtil.normalizeFile(projectDir).getAbsolutePath());\n            }\n            panel.fireChangeEvent();\n        }\n\n    }//GEN-LAST:event_browseButtonActionPerformed\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JButton browseButton;\n    private javax.swing.JLabel createdFolderLabel;\n    private javax.swing.JTextField createdFolderTextField;\n    private javax.swing.JLabel projectLocationLabel;\n    private javax.swing.JTextField projectLocationTextField;\n    private javax.swing.JLabel projectNameLabel;\n    private javax.swing.JTextField projectNameTextField;\n    // End of variables declaration//GEN-END:variables\n\n    @Override\n    public void addNotify() {\n        super.addNotify();\n        //same problem as in 31086, initial focus on Cancel button\n        projectNameTextField.requestFocus();\n    }\n\n    boolean valid(WizardDescriptor wizardDescriptor) {\n\n        if (projectNameTextField.getText().length() == 0) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Name is not a valid folder name.\");\n            return false; // Display name not specified\n\n        }\n        File f = FileUtil.normalizeFile(new File(projectLocationTextField.getText()).getAbsoluteFile());\n        if (!f.isDirectory()) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n        final File destFolder = FileUtil.normalizeFile(new File(createdFolderTextField.getText()).getAbsoluteFile());\n\n        File projLoc = destFolder;\n        while (projLoc != null && !projLoc.exists()) {\n            projLoc = projLoc.getParentFile();\n        }\n        if (projLoc == null || !projLoc.canWrite()) {\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder cannot be created.\");\n            return false;\n        }\n\n        if (FileUtil.toFileObject(projLoc) == null) {\n            String message = \"Project Folder is not a valid path.\";\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", message);\n            return false;\n        }\n\n        File[] kids = destFolder.listFiles();\n        if (destFolder.exists() && kids != null && kids.length > 0) {\n            // Folder exists and is not empty\n            wizardDescriptor.putProperty(\"WizardPanel_errorMessage\",\n                    \"Project Folder already exists and is not empty.\");\n            return false;\n        }\n        wizardDescriptor.putProperty(\"WizardPanel_errorMessage\", \"\");\n        return true;\n    }\n\n    void store(WizardDescriptor d) {\n        String name = projectNameTextField.getText().trim();\n        String folder = createdFolderTextField.getText().trim();\n\n        d.putProperty(\"projdir\", new File(folder));\n        d.putProperty(\"name\", name);\n    }\n\n    void read(WizardDescriptor settings) {\n        File projectLocation = (File) settings.getProperty(\"projdir\");\n        if (projectLocation == null || projectLocation.getParentFile() == null || !projectLocation.getParentFile().isDirectory()) {\n            projectLocation = ProjectChooser.getProjectsFolder();\n        } else {\n            projectLocation = projectLocation.getParentFile();\n        }\n        this.projectLocationTextField.setText(projectLocation.getAbsolutePath());\n\n        String projectName = (String) settings.getProperty(\"name\");\n        if (projectName == null) {\n            projectName = \"subnodes\";\n        }\n        this.projectNameTextField.setText(projectName);\n        this.projectNameTextField.selectAll();\n    }\n\n    void validate(WizardDescriptor d) throws WizardValidationException {\n        // nothing to validate\n    }\n\n    // Implementation of DocumentListener --------------------------------------\n    public void changedUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void insertUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    public void removeUpdate(DocumentEvent e) {\n        updateTexts(e);\n        if (this.projectNameTextField.getDocument() == e.getDocument()) {\n            firePropertyChange(PROP_PROJECT_NAME, null, this.projectNameTextField.getText());\n        }\n    }\n\n    /** Handles changes in the Project name and project directory, */\n    private void updateTexts(DocumentEvent e) {\n\n        Document doc = e.getDocument();\n\n        if (doc == projectNameTextField.getDocument() || doc == projectLocationTextField.getDocument()) {\n            // Change in the project name\n\n            String projectName = projectNameTextField.getText();\n            String projectFolder = projectLocationTextField.getText();\n\n            //if (projectFolder.trim().length() == 0 || projectFolder.equals(oldName)) {\n            createdFolderTextField.setText(projectFolder + File.separatorChar + projectName);\n        //}\n\n        }\n        panel.fireChangeEvent(); // Notify that the panel changed\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/subnodes/subnodesWizardIterator.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.subnodes;\n\nimport java.awt.Component;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.text.MessageFormat;\nimport java.util.Enumeration;\nimport java.util.LinkedHashSet;\nimport java.util.NoSuchElementException;\nimport java.util.Set;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\nimport javax.swing.JComponent;\nimport javax.swing.event.ChangeListener;\nimport org.netbeans.api.project.ProjectManager;\nimport org.netbeans.spi.project.ui.support.ProjectChooser;\nimport org.netbeans.spi.project.ui.templates.support.Templates;\nimport org.openide.WizardDescriptor;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.xml.XMLUtil;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.NodeList;\nimport org.xml.sax.InputSource;\n\npublic class subnodesWizardIterator implements WizardDescriptor./*Progress*/InstantiatingIterator {\n\n    private int index;\n    private WizardDescriptor.Panel[] panels;\n    private WizardDescriptor wiz;\n\n    public subnodesWizardIterator() {\n    }\n\n    public static subnodesWizardIterator createIterator() {\n        return new subnodesWizardIterator();\n    }\n\n    private WizardDescriptor.Panel[] createPanels() {\n        return new WizardDescriptor.Panel[]{\n                    new subnodesWizardPanel(),\n                };\n    }\n\n    private String[] createSteps() {\n        return new String[]{\n                    NbBundle.getMessage(subnodesWizardIterator.class, \"LBL_CreateProjectStep\")\n                };\n    }\n\n    public Set/*<FileObject>*/ instantiate(/*ProgressHandle handle*/) throws IOException {\n        Set<FileObject> resultSet = new LinkedHashSet<FileObject>();\n        File dirF = FileUtil.normalizeFile((File) wiz.getProperty(\"projdir\"));\n        dirF.mkdirs();\n\n        FileObject template = Templates.getTemplate(wiz);\n        FileObject dir = FileUtil.toFileObject(dirF);\n        unZipFile(template.getInputStream(), dir);\n\n        // Always open top dir as a project:\n        resultSet.add(dir);\n        // Look for nested projects to open as well:\n        Enumeration<? extends FileObject> e = dir.getFolders(true);\n        while (e.hasMoreElements()) {\n            FileObject subfolder = e.nextElement();\n            if (ProjectManager.getDefault().isProject(subfolder)) {\n                resultSet.add(subfolder);\n            }\n        }\n\n        File parent = dirF.getParentFile();\n        if (parent != null && parent.exists()) {\n            ProjectChooser.setProjectsFolder(parent);\n        }\n\n        return resultSet;\n    }\n\n    public void initialize(WizardDescriptor wiz) {\n        this.wiz = wiz;\n        index = 0;\n        panels = createPanels();\n        // Make sure list of steps is accurate.\n        String[] steps = createSteps();\n        for (int i = 0; i < panels.length; i++) {\n            Component c = panels[i].getComponent();\n            if (steps[i] == null) {\n                // Default step name to component name of panel.\n                // Mainly useful for getting the name of the target\n                // chooser to appear in the list of steps.\n                steps[i] = c.getName();\n            }\n            if (c instanceof JComponent) { // assume Swing components\n\n                JComponent jc = (JComponent) c;\n                // Step #.\n                jc.putClientProperty(\"WizardPanel_contentSelectedIndex\", new Integer(i));\n                // Step name (actually the whole list for reference).\n                jc.putClientProperty(\"WizardPanel_contentData\", steps);\n            }\n        }\n    }\n\n    public void uninitialize(WizardDescriptor wiz) {\n        this.wiz.putProperty(\"projdir\", null);\n        this.wiz.putProperty(\"name\", null);\n        this.wiz = null;\n        panels = null;\n    }\n\n    public String name() {\n        return MessageFormat.format(\"{0} of {1}\",\n                new Object[]{new Integer(index + 1), new Integer(panels.length)});\n    }\n\n    public boolean hasNext() {\n        return index < panels.length - 1;\n    }\n\n    public boolean hasPrevious() {\n        return index > 0;\n    }\n\n    public void nextPanel() {\n        if (!hasNext()) {\n            throw new NoSuchElementException();\n        }\n        index++;\n    }\n\n    public void previousPanel() {\n        if (!hasPrevious()) {\n            throw new NoSuchElementException();\n        }\n        index--;\n    }\n\n    public WizardDescriptor.Panel current() {\n        return panels[index];\n    }\n\n    // If nothing unusual changes in the middle of the wizard, simply:\n    public final void addChangeListener(ChangeListener l) {\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n    }\n\n    private static void unZipFile(InputStream source, FileObject projectRoot) throws IOException {\n        try {\n            ZipInputStream str = new ZipInputStream(source);\n            ZipEntry entry;\n            while ((entry = str.getNextEntry()) != null) {\n                if (entry.isDirectory()) {\n                    FileUtil.createFolder(projectRoot, entry.getName());\n                } else {\n                    FileObject fo = FileUtil.createData(projectRoot, entry.getName());\n                    if (\"nbproject/project.xml\".equals(entry.getName())) {\n                        // Special handling for setting name of Ant-based projects; customize as needed:\n                        filterProjectXML(fo, str, projectRoot.getName());\n                    } else {\n                        writeFile(str, fo);\n                    }\n                }\n            }\n        } finally {\n            source.close();\n        }\n    }\n\n    private static void writeFile(ZipInputStream str, FileObject fo) throws IOException {\n        OutputStream out = fo.getOutputStream();\n        try {\n            FileUtil.copy(str, out);\n        } finally {\n            out.close();\n        }\n    }\n\n    private static void filterProjectXML(FileObject fo, ZipInputStream str, String name) throws IOException {\n        try {\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            FileUtil.copy(str, baos);\n            Document doc = XMLUtil.parse(new InputSource(new ByteArrayInputStream(baos.toByteArray())), false, false, null, null);\n            NodeList nl = doc.getDocumentElement().getElementsByTagName(\"name\");\n            if (nl != null) {\n                for (int i = 0; i < nl.getLength(); i++) {\n                    Element el = (Element) nl.item(i);\n                    if (el.getParentNode() != null && \"data\".equals(el.getParentNode().getNodeName())) {\n                        NodeList nl2 = el.getChildNodes();\n                        if (nl2.getLength() > 0) {\n                            nl2.item(0).setNodeValue(name);\n                        }\n                        break;\n                    }\n                }\n            }\n            OutputStream out = fo.getOutputStream();\n            try {\n                XMLUtil.write(doc, out, \"UTF-8\");\n            } finally {\n                out.close();\n            }\n        } catch (Exception ex) {\n            Exceptions.printStackTrace(ex);\n            writeFile(str, fo);\n        }\n\n    }\n}\n"
  },
  {
    "path": "samples/sampleBundle/src/org/nb/samplebundle/subnodes/subnodesWizardPanel.java",
    "content": "/*\n * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.nb.samplebundle.subnodes;\n\nimport java.awt.Component;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.openide.WizardDescriptor;\nimport org.openide.WizardValidationException;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\n\n/**\n * Panel just asking for basic info.\n */\npublic class subnodesWizardPanel implements WizardDescriptor.Panel,\n        WizardDescriptor.ValidatingPanel, WizardDescriptor.FinishablePanel {\n\n    private WizardDescriptor wizardDescriptor;\n    private subnodesPanelVisual component;\n\n    public subnodesWizardPanel() {\n    }\n\n    public Component getComponent() {\n        if (component == null) {\n            component = new subnodesPanelVisual(this);\n            component.setName(NbBundle.getMessage(subnodesWizardPanel.class, \"LBL_CreateProjectStep\"));\n        }\n        return component;\n    }\n\n    public HelpCtx getHelp() {\n        return new HelpCtx(subnodesWizardPanel.class);\n    }\n\n    public boolean isValid() {\n        getComponent();\n        return component.valid(wizardDescriptor);\n    }\n    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0\n\n\n    public final void addChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.add(l);\n        }\n    }\n\n    public final void removeChangeListener(ChangeListener l) {\n        synchronized (listeners) {\n            listeners.remove(l);\n        }\n    }\n\n    protected final void fireChangeEvent() {\n        Set<ChangeListener> ls;\n        synchronized (listeners) {\n            ls = new HashSet<ChangeListener>(listeners);\n        }\n        ChangeEvent ev = new ChangeEvent(this);\n        for (ChangeListener l : ls) {\n            l.stateChanged(ev);\n        }\n    }\n\n    public void readSettings(Object settings) {\n        wizardDescriptor = (WizardDescriptor) settings;\n        component.read(wizardDescriptor);\n    }\n\n    public void storeSettings(Object settings) {\n        WizardDescriptor d = (WizardDescriptor) settings;\n        component.store(d);\n    }\n\n    public boolean isFinishPanel() {\n        return true;\n    }\n\n    public void validate() throws WizardValidationException {\n        getComponent();\n        component.validate(wizardDescriptor);\n    }\n}\n"
  },
  {
    "path": "samples/subnodes/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.visualvm.demoapplicationtype\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.visualvm.demoapplicationtype.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/subnodes/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.visualvm.demoapplicationtype\nOpenIDE-Module-Install: org/visualvm/demoapplicationtype/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/visualvm/demoapplicationtype/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.0\n\n"
  },
  {
    "path": "samples/subnodes/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.visualvm.demoapplicationtype-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/platform-private.properties\"/>\n    <property file=\"nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "samples/subnodes/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=af2ea54f\nbuild.xml.script.CRC32=bb14dfaa\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=af2ea54f\nnbproject/build-impl.xml.script.CRC32=0c1d0bde\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "samples/subnodes/nbproject/platform.properties",
    "content": "nbplatform.active=VisualVM_1.0_RC_\n"
  },
  {
    "path": "samples/subnodes/nbproject/project.properties",
    "content": "javac.source=1.5\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "samples/subnodes/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.visualvm.demoapplicationtype</code-name-base>\n            <standalone/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>0</release-version>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "samples/subnodes/src/org/visualvm/demoapplicationtype/Bundle.properties",
    "content": "OpenIDE-Module-Name=VisualVM-SubNodes\nNewJPanel.jLabel1.text=jLabel1\n"
  },
  {
    "path": "samples/subnodes/src/org/visualvm/demoapplicationtype/Installer.java",
    "content": "package org.visualvm.demoapplicationtype;\n\nimport org.visualvm.demoapplicationtype.applicationtype.AnagramApplicationTypeFactory;\nimport org.visualvm.demoapplicationtype.application.AnagramApplicationProvider;\nimport org.openide.modules.ModuleInstall;\nimport org.visualvm.demoapplicationtype.datasource.AnagramDataSourceDescriptorProvider;\nimport org.visualvm.demoapplicationtype.model.AnagramModelProvider;\n\npublic class Installer extends ModuleInstall {\n\n    @Override\n    public void restored() {\n        AnagramApplicationTypeFactory.initialize();\n        AnagramDataSourceDescriptorProvider.initialize();\n        AnagramModelProvider.initialize();\n        AnagramApplicationProvider.initialize();\n    }\n    \n    @Override\n    public void uninstalled() {\n        AnagramApplicationTypeFactory.shutdown();\n        AnagramDataSourceDescriptorProvider.shutdown();\n        AnagramModelProvider.shutdown();\n        AnagramApplicationProvider.shutdown();\n    }\n}\n"
  },
  {
    "path": "samples/subnodes/src/org/visualvm/demoapplicationtype/application/AnagramApplication.java",
    "content": "package org.visualvm.demoapplicationtype.application;\n\nimport org.visualvm.demoapplicationtype.datasource.AnagramDataSource;\nimport org.visualvm.demoapplicationtype.model.AnagramModel;\n\npublic abstract class AnagramApplication extends AnagramDataSource {    \n    private AnagramModel AnagramRoot;\n    private String name;\n    private String objectName;\n    \n    public AnagramApplication(String name, String objName, AnagramModel gfRoot) {\n        super();\n        this.name = name;\n        this.AnagramRoot = gfRoot;\n        this.objectName = objName;\n    }\n\n    public AnagramModel getAnagramRoot() {\n        return AnagramRoot;\n    }\n\n    public String getName() {\n        return name;\n    }\n    \n    public String getObjectName() {\n        return objectName;\n    }\n    \n    abstract public void generateContents();\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj == null) {\n            return false;\n        }\n        if (getClass() != obj.getClass()) {\n            return false;\n        }\n        final AnagramApplication other = (AnagramApplication) obj;\n        if (this.AnagramRoot != other.AnagramRoot && (this.AnagramRoot == null || !this.AnagramRoot.equals(other.AnagramRoot))) {\n            return false;\n        }\n        if (!this.objectName.equals(other.objectName) && (this.objectName == null || !this.objectName.equals(other.objectName))) {\n            return false;\n        }\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int hash = 5;\n        hash = 11 * hash + (this.AnagramRoot != null ? this.AnagramRoot.hashCode() : 0);\n        hash = 11 * hash + (this.objectName != null ? this.objectName.hashCode() : 0);\n        return hash;\n    }\n}\n"
  },
  {
    "path": "samples/subnodes/src/org/visualvm/demoapplicationtype/application/AnagramApplicationProvider.java",
    "content": "package org.visualvm.demoapplicationtype.application;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.explorer.ExplorerExpansionListener;\nimport org.graalvm.visualvm.core.explorer.ExplorerSupport;\nimport org.graalvm.visualvm.core.scheduler.Quantum;\nimport org.graalvm.visualvm.core.scheduler.ScheduledTask;\nimport org.graalvm.visualvm.core.scheduler.Scheduler;\nimport org.graalvm.visualvm.core.scheduler.SchedulerTask;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.IntrospectionException;\nimport javax.management.MBeanAttributeInfo;\nimport javax.management.MBeanInfo;\nimport javax.management.MBeanServerConnection;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\nimport javax.management.ReflectionException;\nimport org.openide.util.Exceptions;\nimport org.visualvm.demoapplicationtype.datasource.AnagramDataSource;\nimport org.visualvm.demoapplicationtype.model.AnagramModel;\n\npublic class AnagramApplicationProvider implements DataChangeListener<AnagramModel>, DataRemovedListener<AnagramModel>, ExplorerExpansionListener {\n    \n    private static final AnagramApplicationProvider INSTANCE = new AnagramApplicationProvider();\n    private final Map<AnagramModel, ScheduledTask> taskMap = new HashMap<AnagramModel, ScheduledTask>();\n    \n    private static class LazyLoadingSource extends AnagramDataSource {\n        private String message;\n        private AnagramModel parent;\n        \n        public LazyLoadingSource(String message, AnagramModel parent) {\n            this.message = message;\n            this.parent = parent;\n        }\n        \n        @Override\n        public DataSourceDescriptor getDescriptor() {\n            return new DataSourceDescriptor(this) {\n                \n                @Override\n                public int getAutoExpansionPolicy() {\n                    return EXPAND_NEVER;\n                }\n                \n                @Override\n                public String getName() {\n                    return message;\n                }\n            };\n        }\n    }\n    \n    private class DiscoveryTask implements SchedulerTask {\n        \n        private AnagramModel model;\n        private volatile boolean running;\n        \n        public DiscoveryTask(AnagramModel model) {\n            this.model = model;\n        }\n        \n        public void onSchedule(long timeStamp) {\n            if (running) return;\n            running = true;\n            try {\n                \n                JmxModel jmx = JmxModelFactory.getJmxModelFor(model.getApplication());\n                if (jmx == null || jmx.getConnectionState() != JmxModel.ConnectionState.CONNECTED) {\n                    return;\n                }\n                MBeanServerConnection conn = jmx.getMBeanServerConnection();\n                ObjectName obj = new ObjectName(\"com.toy.anagrams.mbeans:type=AnagramsStats\");               \n                MBeanInfo infos = conn.getMBeanInfo(obj);\n                MBeanAttributeInfo[] attrs = infos.getAttributes();             \n                Set<AnagramApplication> currentApps = new HashSet<AnagramApplication>();\n                \n                for (int i = 0; i < attrs.length; i++) {                  \n                    MBeanAttributeInfo attr = attrs[i];               \n                    AnagramMbeansModule attrModule = new AnagramMbeansModule(attr != null ? (attr.getName() + \" (\" + attr.getType() + \")\") : attr.getName(), attr.getName(), model);\n        \n                    currentApps.add(attrModule);\n                }\n                Set<AnagramDataSource> toRemoveApps = new HashSet<AnagramDataSource>(model.getRepository().getDataSources(AnagramDataSource.class));\n                Set<AnagramDataSource> toAdd = new HashSet<AnagramDataSource>(currentApps);\n                toRemoveApps.removeAll(currentApps);\n                toAdd.removeAll(model.getRepository().getDataSources());\n                \n                Set<LazyLoadingSource> lazy = model.getRepository().getDataSources(LazyLoadingSource.class);\n                Set<AnagramDataSource> toRemove = new HashSet<AnagramDataSource>(toRemoveApps);\n                toRemove.addAll(lazy);\n                if (currentApps.size() == 0) {\n                    LazyLoadingSource unavailable = new LazyLoadingSource(\"Unavailable\", model);\n                    toAdd.add(unavailable);\n                    toRemove.remove(unavailable);\n                }\n                toAdd.removeAll(lazy);\n\n                if (toAdd.size() > 0 || toRemove.size() > 0) {\n                    model.getRepository().addDataSources(toAdd);\n                    model.getRepository().removeDataSources(toRemove);\n                }\n                \n            } catch (MalformedObjectNameException ex) {\n                Exceptions.printStackTrace(ex);\n            } catch (NullPointerException ex) {\n                Exceptions.printStackTrace(ex);\n            } catch (InstanceNotFoundException ex) {\n                Exceptions.printStackTrace(ex);\n            } catch (IntrospectionException ex) {\n                Exceptions.printStackTrace(ex);\n            } catch (ReflectionException ex) {\n                Exceptions.printStackTrace(ex);\n            } catch (IOException ex) {\n                Exceptions.printStackTrace(ex);\n            } finally {\n                running = false;\n            }\n        }\n    }\n    \n    public void dataChanged(DataChangeEvent<AnagramModel> event) {\n        if (event.getAdded().isEmpty() && event.getRemoved().isEmpty()) {\n            addModels(event.getCurrent());\n        } else {\n            addModels(event.getAdded());\n            removeModels(event.getRemoved());\n        }\n    }\n    \n    private void addModels(Set<AnagramModel> models) {\n        for (AnagramModel model : models) {\n            AnagramDataSource lazyDS = new LazyLoadingSource(\"Please Wait ...\",model);\n            model.getRepository().addDataSource(lazyDS);\n            ScheduledTask task = Scheduler.sharedInstance().schedule(new DiscoveryTask(model), Quantum.SUSPENDED);\n            taskMap.put(model, task);\n        }\n    }\n    \n    private void removeModels(Set<AnagramModel> models) {\n        for (AnagramModel model : models) {\n            // removing the reference to the ScheduledTask practically unschedules the task\n            Scheduler.sharedInstance().unschedule(taskMap.remove(model));\n        }\n    }\n    \n    public void dataRemoved(AnagramModel model) {\n        // removing the reference to the ScheduledTask practically unschedules the task\n        Scheduler.sharedInstance().unschedule(taskMap.remove(model));\n        Set<AnagramApplication> roots = model.getRepository().getDataSources(AnagramApplication.class);\n        model.getRepository().removeDataSources(roots);\n    }\n    \n    public static void initialize() {\n        DataSourceRepository.sharedInstance().addDataChangeListener(INSTANCE, AnagramModel.class);\n        ExplorerSupport.sharedInstance().addExpansionListener(INSTANCE);\n    }\n    \n    public static void shutdown() {\n        DataSourceRepository.sharedInstance().removeDataChangeListener(INSTANCE);\n        ExplorerSupport.sharedInstance().removeExpansionListener(INSTANCE);\n    }\n    \n    public void dataSourceCollapsed(DataSource source) {\n        // do nothing\n    }\n    \n    public void dataSourceExpanded(DataSource source) {\n        if (source instanceof AnagramModel) {\n            if (taskMap.containsKey(source)) {\n                taskMap.get(source).setInterval(Quantum.seconds(3));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/subnodes/src/org/visualvm/demoapplicationtype/application/AnagramMbeansModule.java",
    "content": "package org.visualvm.demoapplicationtype.application;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport java.awt.Image;\nimport org.openide.util.Utilities;\nimport org.visualvm.demoapplicationtype.model.AnagramModel;\n\npublic class AnagramMbeansModule extends AnagramApplication {\n\n    private static final Image NODE_ICON = Utilities.loadImage(\"org/visualvm/demoapplicationtype/resources/application.png\",\n            true);\n    private final Descriptor descriptor;\n\n    public AnagramMbeansModule(String name, String objName, AnagramModel gfRoot) {\n        super(name, objName, gfRoot);\n        descriptor = new Descriptor();\n    }\n\n    @Override\n    public void generateContents() {\n    }\n\n    @Override\n    public DataSourceDescriptor getDescriptor() {\n        return descriptor;\n    }\n    \n    private class Descriptor extends DataSourceDescriptor<DataSource> {\n        public Descriptor() {\n            super(AnagramMbeansModule.this);\n        }\n        \n        @Override\n        public Image getIcon() {\n            return NODE_ICON;\n        }\n\n        @Override\n        public String getName() {\n            return AnagramMbeansModule.this.getName();\n        }\n\n        @Override\n        public String getDescription() {\n            return null;\n        }\n\n        @Override\n        public int getAutoExpansionPolicy() {\n            return DataSourceDescriptor.EXPAND_NEVER;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/subnodes/src/org/visualvm/demoapplicationtype/applicationtype/AnagramApplicationType.java",
    "content": "package org.visualvm.demoapplicationtype.applicationtype;\n\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport java.awt.Image;\nimport org.openide.util.Utilities;\n\npublic class AnagramApplicationType extends ApplicationType {\n\n    protected final int appPID;\n\n    public AnagramApplicationType(int pid) {\n        appPID = pid;\n    }\n\n    @Override\n    public String getName() {\n        return \"Anagram Game\";\n    }\n\n    @Override\n    public String getVersion() {\n        return \"1.0\";\n    }\n\n    @Override\n    public String getDescription() {\n        return \"Application type for Anagram Game\";\n    }\n\n    @Override\n    public Image getIcon() {\n        return Utilities.loadImage(\"org/visualvm/demoapplicationtype/resources/AnagramGame.png\", true);\n    }\n}\n"
  },
  {
    "path": "samples/subnodes/src/org/visualvm/demoapplicationtype/applicationtype/AnagramApplicationTypeFactory.java",
    "content": "package org.visualvm.demoapplicationtype.applicationtype;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.application.type.MainClassApplicationTypeFactory;\n\n\npublic class AnagramApplicationTypeFactory extends MainClassApplicationTypeFactory {\n\n    private final static AnagramApplicationTypeFactory INSTANCE = new AnagramApplicationTypeFactory();\n\n    @Override\n    public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) {\n        if (\"com.toy.anagrams.ui.Anagrams\".equals(mainClass)) {\n            return new AnagramApplicationType(app.getPid());\n            \n        }\n        return null;\n    }\n\n    public static void initialize() {\n        ApplicationTypeFactory.getDefault().registerProvider(INSTANCE);\n    }\n\n    public static void shutdown() {\n        ApplicationTypeFactory.getDefault().unregisterProvider(INSTANCE);\n    }\n}\n"
  },
  {
    "path": "samples/subnodes/src/org/visualvm/demoapplicationtype/datasource/AnagramDataSource.java",
    "content": "package org.visualvm.demoapplicationtype.datasource;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\n\n\npublic abstract class AnagramDataSource extends DataSource {\n\n    public AnagramDataSource() {\n        this(null);\n    }\n\n    public AnagramDataSource(DataSource master) {\n        super(master);\n    }\n\n    abstract public DataSourceDescriptor getDescriptor();\n}\n"
  },
  {
    "path": "samples/subnodes/src/org/visualvm/demoapplicationtype/datasource/AnagramDataSourceDescriptorProvider.java",
    "content": "package org.visualvm.demoapplicationtype.datasource;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\n\npublic class AnagramDataSourceDescriptorProvider extends AbstractModelProvider<DataSourceDescriptor, DataSource> {\n\n    final private static AnagramDataSourceDescriptorProvider INSTANCE = new AnagramDataSourceDescriptorProvider();\n\n    private AnagramDataSourceDescriptorProvider() {\n    }\n\n    @Override\n    public DataSourceDescriptor createModelFor(DataSource anagramDS) {\n        if (anagramDS instanceof AnagramDataSource) {\n            return ((AnagramDataSource) anagramDS).getDescriptor();\n        }\n        return null;\n    }\n\n    public static void initialize() {\n        DataSourceDescriptorFactory.getDefault().registerProvider(INSTANCE);\n    }\n\n    public static void shutdown() {\n        DataSourceDescriptorFactory.getDefault().unregisterProvider(INSTANCE);\n    }\n}\n"
  },
  {
    "path": "samples/subnodes/src/org/visualvm/demoapplicationtype/model/AnagramModel.java",
    "content": "package org.visualvm.demoapplicationtype.model;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport java.awt.Image;\nimport org.visualvm.demoapplicationtype.datasource.AnagramDataSource;\n\npublic class AnagramModel extends AnagramDataSource {\n\n    private Application application;\n    private final Descriptor descriptor;\n\n    public AnagramModel(Application app) {\n        super();\n        application = app;\n        descriptor = new Descriptor(application);\n    }\n\n    public Application getApplication() {\n        return application;\n    }\n\n    @Override\n    public DataSourceDescriptor getDescriptor() {\n        return descriptor;\n    }\n    \n    private static class Descriptor extends DataSourceDescriptor<Application> {\n        public Descriptor(Application application) {\n            super(application);\n        }\n        \n        @Override\n        public Image getIcon() {\n            return null;\n        }\n\n        @Override\n        public String getName() {\n            return \"Attributes\";\n        }\n\n        @Override\n        public String getDescription() {\n            return \"Anagram Model\";\n        }\n\n        @Override\n        public int getAutoExpansionPolicy() {\n            return EXPAND_NEVER;\n        }\n    }\n}\n\n//            AnagramWebModule module = new AnagramWebModule(appName != null ? (moduleName + \" (in \" + appName + \")\") : moduleName, objectName, virtMonitorEntry.getValue(), root);\n//            registerDataSource(module);\n//            root.getRepository().addDataSource(module);\n\n"
  },
  {
    "path": "samples/subnodes/src/org/visualvm/demoapplicationtype/model/AnagramModelProvider.java",
    "content": "package org.visualvm.demoapplicationtype.model;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.core.datasource.DataSourceProvider;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.visualvm.demoapplicationtype.applicationtype.AnagramApplicationType;\nimport java.util.Set;\n\npublic class AnagramModelProvider implements DataChangeListener<Application>, DataRemovedListener<Application> {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n    private static final AnagramModelProvider INSTANCE = new AnagramModelProvider();\n    \n    private final DataRemovedListener<Application> removelListener = new DataRemovedListener<Application>() {\n\n                public void dataRemoved(Application app) {\n                    processFinishedApplication(app);\n                }\n            };\n            \n    public AnagramModelProvider() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    public void dataChanged(DataChangeEvent<Application> event) {\n        if (event.getAdded().isEmpty() && event.getRemoved().isEmpty()) {\n            // Initial event to deliver DataSources already created by the provider before registering to it as a listener\n            // NOTE: already existing hosts are treated as new for this provider\n            Set<Application> newApplications = event.getCurrent();\n\n            for (Application app : newApplications) {\n                processNewApplication(app);\n            }\n        } else {\n            // Real delta event\n            Set<Application> newApplications = event.getAdded();\n\n            for (Application app : newApplications) {\n                processNewApplication(app);\n            }\n        }\n    }\n\n    public static void initialize() {\n        DataSourceRepository.sharedInstance().addDataChangeListener(INSTANCE, Application.class);\n    }\n\n    public static void shutdown() {\n        DataSourceRepository.sharedInstance().removeDataChangeListener(INSTANCE);\n    }\n    \n    public void dataRemoved(Application application) {\n        processFinishedApplication(application);\n    }\n\n    private void processFinishedApplication(Application app) {\n        // TODO: remove listener!!!\n        Set<AnagramModel> roots = app.getRepository().getDataSources(AnagramModel.class);\n        app.getRepository().removeDataSources(roots);\n    }\n\n    private void processNewApplication(final Application app) {\n        if (ApplicationTypeFactory.getApplicationTypeFor(app) instanceof AnagramApplicationType) {\n            AnagramModel am = new AnagramModel(app);\n            app.getRepository().addDataSource(am);\n            app.notifyWhenRemoved(removelListener);\n        }\n    }\n\n}\n"
  },
  {
    "path": "templates/apisupport/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.apisupport\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.apisupport.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "templates/apisupport/javahelp/org/graalvm/visualvm/apisupport/docs/visualvmview-about.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <title>VisualVM View Wizard: Name and Location</title>\n        <link rel=\"stylesheet\" href=\"nbdocs:/org/netbeans/modules/usersguide/ide.css\" type=\"text/css\">\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n        <h2>VisualVM View Wizard: Name and Location</h2>\n        <p>\n            The VisualVM View wizard creates a new VisualVM View\n            for a selected VisualVM data source.\n            You open the New VisualVM View wizard by right-clicking a\n            module project, choosing New > Other and selecting VisualVM View\n            from the Module Development category.\n        </p>\n        <p>In the Name and Location page, you have to set the following:\n            <ul>\n                <li><b>Prefix.</b> Specifies the prefix for the new\n                VisualVM classes that will be generated by the wizard. This\n                value also sets the text in the view's tab.\n                <li><b>Data Source.</b> Specifies the data source for which\n                you are creating the view:\n                <ul>\n                    <li>Application\n                    <li>CoreDump\n                    <li>DataSource\n                    <li>HeapDump\n                    <li>Host\n                    <li>SnapShot\n                    <li>ThreadDump\n                </ul>\n                <p><b>Note:</b> If you select \"DataSource\", you will create a new\n                view that will be shown for <i>all</i> data sources. Selecting any\n                of the others will create a new view only for the specific data source\n                that you selected.\n                <li><b>Package Name.</b> Specifies the name of the package where the\n                generated classes will be created.\n            </ul>\n            <hr>\n        </p>\n    </body>\n</html>\n<!--\nTip: to create a link which will open in an external web browser, try:\n<object classid=\"java:org.netbeans.modules.javahelp.BrowserDisplayer\">\n<param name=\"content\" value=\"https://www.netbeans.org/\">\n<param name=\"text\" value=\"<html><u>https://www.netbeans.org/</u></html>\">\n<param name=\"textFontSize\" value=\"medium\">\n<param name=\"textColor\" value=\"blue\">\n</object>\nTo create a link to a help set from another module, you need to know the code name base and path, e.g.:\n<a href=\"nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html\">Using the Options Window</a>\n(This link will behave sanely if that module is disabled or missing.)\n-->\n"
  },
  {
    "path": "templates/apisupport/javahelp/org/graalvm/visualvm/apisupport/docs/visualvmview-hs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<!DOCTYPE helpset PUBLIC \"-//Sun Microsystems Inc.//DTD JavaHelp HelpSet Version 2.0//EN\" \"http://java.sun.com/products/javahelp/helpset_2_0.dtd\">\n<helpset version=\"2.0\">\n    <title>VisualVM View Help</title>\n    <maps>\n        <homeID>org.visualvm.visualvmview.about</homeID>\n        <mapref location=\"visualvmview-map.xml\"/>\n    </maps>\n    <view mergetype=\"javax.help.AppendMerge\">\n        <name>TOC</name>\n        <label>Table of Contents</label>\n        <type>javax.help.TOCView</type>\n        <data>visualvmview-toc.xml</data>\n    </view>\n    <view mergetype=\"javax.help.AppendMerge\">\n        <name>Index</name>\n        <label>Index</label>\n        <type>javax.help.IndexView</type>\n        <data>visualvmview-idx.xml</data>\n    </view>\n    <view>\n        <name>Search</name>\n        <label>Search</label>\n        <type>javax.help.SearchView</type>\n        <data engine=\"com.sun.java.help.search.DefaultSearchEngine\">JavaHelpSearch\n        </data>\n    </view>\n</helpset>\n"
  },
  {
    "path": "templates/apisupport/javahelp/org/graalvm/visualvm/apisupport/docs/visualvmview-idx.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<!DOCTYPE index PUBLIC \"-//Sun Microsystems Inc.//DTD JavaHelp Index Version 2.0//EN\" \"http://java.sun.com/products/javahelp/index_2_0.dtd\">\n<index version=\"2.0\">\n    <indexitem text=\"About VisualVM View\" target=\"org.visualvm.visualvmview.about\"/>\n</index>\n"
  },
  {
    "path": "templates/apisupport/javahelp/org/graalvm/visualvm/apisupport/docs/visualvmview-map.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<!DOCTYPE map PUBLIC \"-//Sun Microsystems Inc.//DTD JavaHelp Map Version 2.0//EN\" \"http://java.sun.com/products/javahelp/map_2_0.dtd\">\n<map version=\"2.0\">\n    <mapID target=\"org.graalvm.visualvm.apisupport.tabs.NameAndLocationPanel\" url=\"visualvmview-about.html\"/>\n</map>\n"
  },
  {
    "path": "templates/apisupport/javahelp/org/graalvm/visualvm/apisupport/docs/visualvmview-toc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<!DOCTYPE toc PUBLIC \"-//Sun Microsystems Inc.//DTD JavaHelp TOC Version 2.0//EN\" \"http://java.sun.com/products/javahelp/toc_2_0.dtd\">\n<toc version=\"2.0\">\n\n</toc>\n"
  },
  {
    "path": "templates/apisupport/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.apisupport\nOpenIDE-Module-Layer: org/graalvm/visualvm/apisupport/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/apisupport/Bundle.properties\n\n"
  },
  {
    "path": "templates/apisupport/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.apisupport-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/platform-private.properties\"/>\n    <property file=\"nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "templates/apisupport/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=40e350c9\nbuild.xml.script.CRC32=7e378f36\nbuild.xml.stylesheet.CRC32=a56c6a5b@1.44\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=40e350c9\nnbproject/build-impl.xml.script.CRC32=1fb79f12\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.44\n"
  },
  {
    "path": "templates/apisupport/nbproject/platform.properties",
    "content": "cluster.path=\\\n    ${nbplatform.active.dir}/groovy:\\\n    ${nbplatform.active.dir}/nb:\\\n    ${nbplatform.active.dir}/cnd:\\\n    ${nbplatform.active.dir}/enterprise:\\\n    ${nbplatform.active.dir}/apisupport:\\\n    ${nbplatform.active.dir}/harness:\\\n    ${nbplatform.active.dir}/profiler:\\\n    ${nbplatform.active.dir}/javacard:\\\n    ${nbplatform.active.dir}/dlight:\\\n    ${nbplatform.active.dir}/ergonomics:\\\n    ${nbplatform.active.dir}/php:\\\n    ${nbplatform.active.dir}/identity:\\\n    ${nbplatform.active.dir}/ide:\\\n    ${nbplatform.active.dir}/ruby:\\\n    ${nbplatform.active.dir}/mobility:\\\n    ${nbplatform.active.dir}/java:\\\n    ${nbplatform.active.dir}/platform:\\\n    ${nbplatform.active.dir}/websvccommon\nnbplatform.active=NetBeans_IDE_7.0_Beta_(Build_201011152355)\n"
  },
  {
    "path": "templates/apisupport/nbproject/project.properties",
    "content": "javac.source=1.6\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../../visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=http://visualvm.dev.java.net\nnbm.module.author=Geertjan Wielenga, Jaroslav Bachorik\nspec.version.base=1.1\n"
  },
  {
    "path": "templates/apisupport/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.apisupport</code-name-base>\n            <standalone/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.jdesktop.beansbinding</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.9.0.121</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.jdesktop.layout</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.15</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.apisupport.project</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <implementation-version/>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.34</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.29</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.17</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.42</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.9</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Developing VisualVM\nOpenIDE-Module-Long-Description=\\\n    This module adds wizards for the extension points most frequently used while developing VisualVM plugins.\nOpenIDE-Module-Name=VisualVM API Support\n\nOpenIDE-Module-Short-Description=Support for developing VisualVM plugins\nTemplates/VisualVMPluginDevelopment=VisualVM Plugins\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/actions/Bundle.properties",
    "content": "# Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nTemplates/VisualVMPluginDevelopment/action=Action\n\nLBL_ProjectWizardTitle=VisualVM Action\nLBL_ProjectSelection_Title=Select Project\n\nLBL_NameLocation_Title=Name and Location\nLBL_ProjectName=&Project\\:\nLBL_PackageName=Pac&kage\\:\nLBL_CreatedFiles=&Created Files\\:\nLBL_ModifiedFiles=&Modified Files\\:\n\nACS_SelectProjectPanel=Select Project panel\nACS_CTL_btnProject=Browse Project button\nACS_CTL_comProject=Select from opened projects combobox\n\nLBL_Name=&Template Name \\:\nLBL_DisplayName=D&isplay Name \\:\nLBL_Category=C&ategory\nLBL_Project_Label=&Project \\:\nLBL_Browse=Bro&wse...\nACS_NameAndLocationPanel=Name and Location Panel\nACS_CTL_PackageName=Package Name\nACS_CTL_Category=Category\nACS_CTL_DisplayName=Display Name\nACS_CTL_Name=Template Name\nACS_CTL_ProjectName=Project Name\nACS_CTL_CreatedFilesValue=Created Files\nACS_CTL_ModifiedFilesValue=Modified Files\n\nMSG_No_Projects=No Projects opened\nMSG_NoExternalRoots=Projects with external roots are not supported.\nMSG_NoProjectSelected=A project needs to be selected.\n\nERR_Category_Invalid=Category is malformed.\nERR_Name_Prefix_Empty=Template Name is empty.\nERR_Name_Prefix_Invalid=Template Name is invalid, not a Java identifier.\nERR_Package_Invalid=Package is blank or malformed.\nERR_ToBeCreateFileExists=The file {0} already exists.\nERR_Missing_Modules=The NetBeans platform is missing required modules.\nERR_No_Platform=No NetBeans Platform defined.\nLBL_Name_1=Action Name:\nLBL_DisplayName_1=Data Source:\nLBL_ProjectName_1=Project Name:\nLBL_PackageName_1=Package Name:\nLBL_CreatedFiles_1=Created Files:\nLBL_ModifiedFiles_1=Modified Files:"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/actions/NameAndLocationPanel.form",
    "content": "<?xml version=\"1.1\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.2\" maxVersion=\"1.2\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"2\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Component id=\"filler\" min=\"-2\" pref=\"400\" max=\"-2\" attributes=\"0\"/>\n          <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n              <Group type=\"103\" groupAlignment=\"1\" attributes=\"0\">\n                  <Component id=\"lblProjectName\" alignment=\"0\" pref=\"192\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"lblPackageName\" alignment=\"0\" pref=\"192\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFiles\" alignment=\"0\" pref=\"192\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"modifiedFiles\" alignment=\"0\" pref=\"192\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"lblName\" alignment=\"0\" pref=\"192\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"lblDisplayName\" alignment=\"1\" pref=\"192\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"12\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"txtName\" alignment=\"0\" pref=\"300\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"comCategory\" alignment=\"0\" pref=\"300\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"txtProjectName\" alignment=\"0\" pref=\"300\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"comPackageName\" alignment=\"0\" pref=\"300\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFilesValue\" alignment=\"0\" pref=\"300\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"modifiedFilesValue\" alignment=\"0\" pref=\"300\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"txtName\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Group type=\"102\" attributes=\"0\">\n                      <EmptySpace min=\"2\" pref=\"2\" max=\"2\" attributes=\"0\"/>\n                      <Component id=\"lblName\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  </Group>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"6\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"2\" attributes=\"0\">\n                  <Component id=\"lblDisplayName\" alignment=\"2\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"comCategory\" alignment=\"2\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"18\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"lblProjectName\" min=\"-2\" pref=\"19\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"txtProjectName\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"6\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"lblPackageName\" min=\"-2\" pref=\"24\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"comPackageName\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"36\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"createdFiles\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFilesValue\" pref=\"20\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"6\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"modifiedFiles\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"modifiedFilesValue\" pref=\"20\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <Component id=\"filler\" min=\"-2\" pref=\"92\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" pref=\"20\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"lblName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"txtName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/actions/Bundle.properties\" key=\"LBL_Name_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"txtName\">\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblDisplayName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"comCategory\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/actions/Bundle.properties\" key=\"LBL_DisplayName_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblProjectName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"txtProjectName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/actions/Bundle.properties\" key=\"LBL_ProjectName_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"txtProjectName\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"JavaCodeGenerator_CreateCodeCustom\" type=\"java.lang.String\" value=\"new JTextField(ProjectUtils.getInformation(this.data.getProject()).getDisplayName());\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblPackageName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"comPackageName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/actions/Bundle.properties\" key=\"LBL_PackageName_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JComboBox\" name=\"comPackageName\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"0\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"JavaCodeGenerator_CreateCodeCustom\" type=\"java.lang.String\" value=\"UIUtil.createPackageComboBox(this.data.getSourceRootGroup());\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"createdFiles\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"createdFilesValue\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/actions/Bundle.properties\" key=\"LBL_CreatedFiles_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"modifiedFiles\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"modifiedFilesValue\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/actions/Bundle.properties\" key=\"LBL_ModifiedFiles_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"filler\">\n    </Component>\n    <Component class=\"javax.swing.JTextArea\" name=\"createdFilesValue\">\n      <Properties>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"rows\" type=\"int\" value=\"5\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"null\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextArea\" name=\"modifiedFilesValue\">\n      <Properties>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"rows\" type=\"int\" value=\"5\"/>\n        <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"modifiedFilesValue\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"null\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JComboBox\" name=\"comCategory\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"7\">\n            <StringItem index=\"0\" value=\"Application\"/>\n            <StringItem index=\"1\" value=\"CoreDump\"/>\n            <StringItem index=\"2\" value=\"DataSource\"/>\n            <StringItem index=\"3\" value=\"HeapDump\"/>\n            <StringItem index=\"4\" value=\"Host\"/>\n            <StringItem index=\"5\" value=\"Snapshot\"/>\n            <StringItem index=\"6\" value=\"ThreadDump\"/>\n          </StringArray>\n        </Property>\n      </Properties>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/actions/NameAndLocationPanel.java",
    "content": "\npackage org.graalvm.visualvm.apisupport.actions;\n\nimport java.awt.Color;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport javax.swing.JTextField;\nimport javax.swing.UIManager;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.netbeans.api.project.ProjectUtils;\nimport org.netbeans.modules.apisupport.project.CreatedModifiedFiles;\nimport org.netbeans.modules.apisupport.project.NbModuleProject;\nimport org.netbeans.modules.apisupport.project.ui.UIUtil;\nimport org.netbeans.modules.apisupport.project.ui.wizard.BasicWizardIterator;\nimport org.netbeans.modules.apisupport.project.universe.ModuleEntry;\nimport org.netbeans.modules.apisupport.project.universe.NbPlatform;\nimport org.openide.WizardDescriptor;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\nimport org.openide.util.Utilities;\n\n/**\n * The second panel in project template wizard.\n *\n * @author Milos Kleint\n */\nfinal class NameAndLocationPanel extends BasicWizardIterator.Panel {\n    \n    private static final String PROJECT_TEMPLATES_DIR = \"Templates/Project\"; // NOI18N\n    private static final String DEFAULT_CATEGORY_PATH = PROJECT_TEMPLATES_DIR + \"/Other\"; // NOI18N\n    \n    private NewActionIterator.DataModel data;\n    \n    /** Creates new NameAndLocationPanel */\n    NameAndLocationPanel(WizardDescriptor setting, NewActionIterator.DataModel data) {\n        super(setting);\n        this.data = data;\n        initComponents();\n        initAccessibility();\n        Color lblBgr = UIManager.getColor(\"Label.background\"); // NOI18N\n        putClientProperty(\"NewFileWizard_Title\", getMessage(\"LBL_ProjectWizardTitle\"));\n        modifiedFilesValue.setBackground(lblBgr);\n        createdFilesValue.setBackground(lblBgr);\n        modifiedFilesValue.setEditable(false);\n        createdFilesValue.setEditable(false);\n        \n        DocumentListener dListener = new UIUtil.DocumentAdapter() {\n            public void insertUpdate(DocumentEvent e) {\n                if (checkValidity()) {\n                    updateData();\n                }\n            }\n        };\n        txtName.getDocument().addDocumentListener(dListener);\n         if (comCategory.getEditor().getEditorComponent() instanceof JTextField) {\n            JTextField txt = (JTextField) comCategory.getEditor().getEditorComponent();\n            txt.getDocument().addDocumentListener(dListener);\n        }\n        if (comPackageName.getEditor().getEditorComponent() instanceof JTextField) {\n            JTextField txt = (JTextField)comPackageName.getEditor().getEditorComponent();\n            txt.getDocument().addDocumentListener(dListener);\n        }\n    }\n    \n    protected void storeToDataModel() {\n        updateData();\n    }\n    \n   \n    \n    private void updateData() {\n        data.setPackageName(comPackageName.getEditor().getItem().toString());\n        data.setName(txtName.getText().trim());\n        data.setCategory(comCategory.getEditor().getItem().toString());\n        NewActionIterator.generateFileChanges(data);\n        CreatedModifiedFiles fls = data.getCreatedModifiedFiles();\n        createdFilesValue.setText(generateText(fls.getCreatedPaths()));\n        modifiedFilesValue.setText(generateText(fls.getModifiedPaths()));\n        //#68294 check if the paths for newly created files are valid or not..\n        String[] invalid  = data.getCreatedModifiedFiles().getInvalidPaths();\n        if (invalid.length > 0) {\n            setError(NbBundle.getMessage(NameAndLocationPanel.class, \"ERR_ToBeCreateFileExists\", invalid[0]));\n        }\n        \n    }\n    \n    protected void readFromDataModel() {\n        \n        checkValidity();\n    }\n    \n    protected String getPanelName() {\n        return getMessage(\"LBL_NameLocation_Title\");\n    }\n    \n    private boolean checkValidity() {\n//        if (!checkPlatformValidity()) {\n//            return false;\n//        }\n        if (txtName.getText().trim().length() == 0) {\n            setError(getMessage(\"ERR_Name_Prefix_Empty\"));\n            return false;\n        }\n        if (!Utilities.isJavaIdentifier(txtName.getText().trim())) {\n            setError(getMessage(\"ERR_Name_Prefix_Invalid\"));\n            return false;\n        }\n        String packageName = comPackageName.getEditor().getItem().toString().trim();\n        if (packageName.length() == 0 || !UIUtil.isValidPackageName(packageName)) {\n            setError(getMessage(\"ERR_Package_Invalid\"));\n            return false;\n        }\n\n        markValid();\n        return true;\n    }\n    \n//    private boolean checkPlatformValidity() {\n//        NbModuleProject nbprj = data.getProject().getLookup().lookup(NbModuleProject.class);\n//        if (nbprj == null) {\n//            //ignore this check for non default netbeans projects.\n//            return true;\n//        }\n//        NbPlatform platform = nbprj.getPlatform(false);\n//        if (platform == null) {\n//            setError(getMessage(\"ERR_No_Platform\"));\n//            return false;\n//        }\n//        ModuleEntry[] entries = platform.getModules();\n//        Collection<String> modules = new HashSet<String>(Arrays.asList(NewActionIterator.MODULES));\n//\n//        for (int i = 0; i < entries.length; i++) {\n//            modules.remove(entries[i].getCodeNameBase());\n//        }\n//        if (modules.size() > 0) {\n//            setError(getMessage(\"ERR_Missing_Modules\"));\n//            return false;\n//        }\n//        return true;\n//    }\n    \n  \n    \n    protected HelpCtx getHelp() {\n        return new HelpCtx(NameAndLocationPanel.class);\n    }\n    \n    private static String getMessage(String key) {\n        return NbBundle.getMessage(NameAndLocationPanel.class, key);\n    }\n    \n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        lblName = new javax.swing.JLabel();\n        txtName = new javax.swing.JTextField();\n        lblDisplayName = new javax.swing.JLabel();\n        lblProjectName = new javax.swing.JLabel();\n        txtProjectName = new JTextField(ProjectUtils.getInformation(this.data.getProject()).getDisplayName());\n        lblPackageName = new javax.swing.JLabel();\n        comPackageName = UIUtil.createPackageComboBox(this.data.getSourceRootGroup());\n        createdFiles = new javax.swing.JLabel();\n        modifiedFiles = new javax.swing.JLabel();\n        filler = new javax.swing.JLabel();\n        createdFilesValue = new javax.swing.JTextArea();\n        modifiedFilesValue = new javax.swing.JTextArea();\n        comCategory = new javax.swing.JComboBox();\n\n        lblName.setLabelFor(txtName);\n        org.openide.awt.Mnemonics.setLocalizedText(lblName, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, \"LBL_Name_1\")); // NOI18N\n\n        lblDisplayName.setLabelFor(comCategory);\n        org.openide.awt.Mnemonics.setLocalizedText(lblDisplayName, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, \"LBL_DisplayName_1\")); // NOI18N\n\n        lblProjectName.setLabelFor(txtProjectName);\n        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle(\"org/graalvm/visualvm/apisupport/actions/Bundle\"); // NOI18N\n        org.openide.awt.Mnemonics.setLocalizedText(lblProjectName, bundle.getString(\"LBL_ProjectName_1\")); // NOI18N\n\n        txtProjectName.setEditable(false);\n\n        lblPackageName.setLabelFor(comPackageName);\n        org.openide.awt.Mnemonics.setLocalizedText(lblPackageName, bundle.getString(\"LBL_PackageName_1\")); // NOI18N\n\n        comPackageName.setEditable(true);\n\n        createdFiles.setLabelFor(createdFilesValue);\n        org.openide.awt.Mnemonics.setLocalizedText(createdFiles, bundle.getString(\"LBL_CreatedFiles_1\")); // NOI18N\n\n        modifiedFiles.setLabelFor(modifiedFilesValue);\n        org.openide.awt.Mnemonics.setLocalizedText(modifiedFiles, bundle.getString(\"LBL_ModifiedFiles_1\")); // NOI18N\n\n        createdFilesValue.setColumns(20);\n        createdFilesValue.setRows(5);\n        createdFilesValue.setBorder(null);\n\n        modifiedFilesValue.setColumns(20);\n        modifiedFilesValue.setRows(5);\n        modifiedFilesValue.setToolTipText(\"modifiedFilesValue\");\n        modifiedFilesValue.setBorder(null);\n\n        comCategory.setEditable(true);\n        comCategory.setModel(new javax.swing.DefaultComboBoxModel(new String[] { \"Application\", \"CoreDump\", \"DataSource\", \"HeapDump\", \"Host\", \"Snapshot\", \"ThreadDump\" }));\n\n        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n            .add(filler, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 400, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)\n                    .add(org.jdesktop.layout.GroupLayout.LEADING, lblProjectName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE)\n                    .add(org.jdesktop.layout.GroupLayout.LEADING, lblPackageName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE)\n                    .add(org.jdesktop.layout.GroupLayout.LEADING, createdFiles, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE)\n                    .add(org.jdesktop.layout.GroupLayout.LEADING, modifiedFiles, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE)\n                    .add(org.jdesktop.layout.GroupLayout.LEADING, lblName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE)\n                    .add(lblDisplayName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE))\n                .add(12, 12, 12)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(txtName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)\n                    .add(comCategory, 0, 300, Short.MAX_VALUE)\n                    .add(txtProjectName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)\n                    .add(comPackageName, 0, 300, Short.MAX_VALUE)\n                    .add(createdFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)\n                    .add(modifiedFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)))\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n            .add(layout.createSequentialGroup()\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(txtName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(layout.createSequentialGroup()\n                        .add(2, 2, 2)\n                        .add(lblName)))\n                .add(6, 6, 6)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.CENTER)\n                    .add(lblDisplayName)\n                    .add(comCategory, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(18, 18, 18)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(lblProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 19, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(txtProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(6, 6, 6)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(lblPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 24, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(comPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(36, 36, 36)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(createdFiles)\n                    .add(createdFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 20, Short.MAX_VALUE))\n                .add(6, 6, 6)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(modifiedFiles)\n                    .add(modifiedFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 20, Short.MAX_VALUE))\n                .add(filler, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 92, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                .add(20, 20, 20))\n        );\n    }// </editor-fold>//GEN-END:initComponents\n    \n    private void initAccessibility() {\n        this.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_NameAndLocationPanel\"));\n        comPackageName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_PackageName\"));\n        comCategory.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_DisplayName\"));\n        txtName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_Name\"));\n        txtProjectName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_ProjectName\"));\n        createdFilesValue.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_CreatedFilesValue\"));\n        modifiedFilesValue.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_ModifiedFilesValue\"));\n    }\n    \n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JComboBox comCategory;\n    private javax.swing.JComboBox comPackageName;\n    private javax.swing.JLabel createdFiles;\n    private javax.swing.JTextArea createdFilesValue;\n    private javax.swing.JLabel filler;\n    private javax.swing.JLabel lblDisplayName;\n    private javax.swing.JLabel lblName;\n    private javax.swing.JLabel lblPackageName;\n    private javax.swing.JLabel lblProjectName;\n    private javax.swing.JLabel modifiedFiles;\n    private javax.swing.JTextArea modifiedFilesValue;\n    private javax.swing.JTextField txtName;\n    private javax.swing.JTextField txtProjectName;\n    // End of variables declaration//GEN-END:variables\n    \n    private static String generateText(String[] relPaths) {\n        StringBuffer sb = new StringBuffer();\n        if (relPaths.length > 0) {\n            for (int i = 0; i < relPaths.length; i++) {\n                if (i > 0) {\n                    sb.append('\\n');\n                }\n                sb.append(relPaths[i]);\n            }\n        }\n        return sb.toString();\n    }\n    \n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/actions/NewActionIterator.java",
    "content": "package org.graalvm.visualvm.apisupport.actions;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Set;\nimport org.netbeans.api.project.Project;\nimport org.netbeans.modules.apisupport.project.CreatedModifiedFiles;\nimport org.netbeans.modules.apisupport.project.spi.NbModuleProvider;\nimport org.netbeans.modules.apisupport.project.ui.wizard.BasicWizardIterator;\nimport org.openide.WizardDescriptor;\nimport org.openide.filesystems.FileObject;\n\nfinal class NewActionIterator extends BasicWizardIterator {\n\n    static final String OPENIDE_MODULE_INSTALL = \"OpenIDE-Module-Install\"; // NOI18N\n\n    private NewActionIterator.DataModel data;\n    public static final String[] MODULES = {\n        \"org.openide.util\", // NOI18N\n        \"org.openide.modules\", // NOI18N\n        \"org.graalvm.visualvm.core\", // NOI18N\n        \"org.graalvm.visualvm.application\", // NOI18N\n        \"org.graalvm.visualvm.coredump\", // NOI18N\n        \"org.graalvm.visualvm.heapdump\", // NOI18N\n        \"org.graalvm.visualvm.threaddump\", // NOI18N\n        \"org.graalvm.visualvm.host\" // NOI18N\n\n    };\n\n    public static NewActionIterator createIterator() {\n        return new NewActionIterator();\n    }\n\n    public Set instantiate() throws IOException {\n        CreatedModifiedFiles cmf = data.getCreatedModifiedFiles();\n        cmf.run();\n        return getCreatedFiles(cmf, data.getProject());\n    }\n\n    protected BasicWizardIterator.Panel[] createPanels(WizardDescriptor wiz) {\n        data = new NewActionIterator.DataModel(wiz);\n        return new BasicWizardIterator.Panel[]{\n                    new NameAndLocationPanel(wiz, data)\n                };\n    }\n\n    public \n    @Override\n    void uninitialize( WizardDescriptor wiz) {\n        super.uninitialize(wiz);\n        data = null;\n    }\n\n    static final class DataModel extends BasicWizardIterator.BasicDataModel {\n\n        private Project template;\n        private String name;\n        private String displayName;\n        private String category;\n        private CreatedModifiedFiles files;\n\n        DataModel(WizardDescriptor wiz) {\n            super(wiz);\n        }\n\n        public CreatedModifiedFiles getCreatedModifiedFiles() {\n            return getFiles();\n        }\n\n        public void setCreatedModifiedFiles(CreatedModifiedFiles files) {\n            this.setFiles(files);\n        }\n\n        public Project getTemplate() {\n            return template;\n        }\n\n        public void setTemplate(Project template) {\n            this.template = template;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public String getDisplayName() {\n            return displayName;\n        }\n\n        public void setDisplayName(String displayName) {\n            this.displayName = displayName;\n        }\n\n        public String getCategory() {\n            return category;\n        }\n\n        public void setCategory(String category) {\n            this.category = category;\n        }\n\n        public CreatedModifiedFiles getFiles() {\n            return files;\n        }\n\n        public void setFiles(CreatedModifiedFiles files) {\n            this.files = files;\n        }\n    }\n\n    public static void generateFileChanges(DataModel model) {\n        CreatedModifiedFiles fileChanges = new CreatedModifiedFiles(model.getProject());\n        NbModuleProvider moduleInfo = model.getModuleInfo();\n        final String category = model.getCategory();\n        final String name = model.getName();\n        final String packageName = model.getPackageName();\n\n        HashMap<String, String> replaceTokens = new HashMap<String, String>();\n        replaceTokens.put(\"DISPLAYNAME\", category);//NOI18N\n\n        replaceTokens.put(\"TEMPLATENAME\", name);//NOI18N\n\n        replaceTokens.put(\"PACKAGENAME\", packageName);//NOI18N\n\n        // Update project dependencies\n        for (int i = 0; i < MODULES.length; i++) {\n            fileChanges.add(fileChanges.addModuleDependency(MODULES[i]));\n        }\n\n        // Generate action class:\n        String iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n                name, \"Action.java\"); //NOI18N\n\n        FileObject template = CreatedModifiedFiles.getTemplate(\"templateAction.java\");//NOI18N\n\n        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n\n        //Layer entry:\n        fileChanges.add(fileChanges.createLayerEntry(\"VisualVM/\" + \"ExplorerPopupSelection/\" + packageName.replace(\".\", \"-\") + \"-\" + name + \"Action.instance\", //NOI18N\n                    null,\n                    null,\n                    \"\",\n                    null));\n        \n        //Layer attr:\n        fileChanges.add(fileChanges.createLayerAttribute(\n                \"VisualVM/\" + \"ExplorerPopupSelection/\" + packageName.replace(\".\", \"-\") + \"-\" + name + \"Action.instance\",\n                \"position\", 3000));\n\n\n        model.setCreatedModifiedFiles(fileChanges);\n\n    }\n\n    private static String getRelativePath(String rootPath, String fullyQualifiedPackageName,\n            String prefix, String postfix) {\n        StringBuffer sb = new StringBuffer();\n        sb.append(rootPath).append('/').\n                append(fullyQualifiedPackageName.replace('.', '/')).\n                append('/').append(prefix).append(postfix);\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/actions/templateAction.javx",
    "content": "<#assign licenseFirst = \"/*\">\n<#assign licensePrefix = \" * \">\n<#assign licenseLast = \" */\">\n<#include \"../Licenses/license-${project.license}.txt\">\n\npackage ${PACKAGENAME};\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.heapdump.HeapDump;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.threaddump.ThreadDump;\nimport java.awt.event.ActionEvent;\nimport javax.swing.Action;\nimport javax.swing.JOptionPane;\n\npublic class ${TEMPLATENAME}Action extends SingleDataSourceAction<${DISPLAYNAME}> {\n\n    public ${TEMPLATENAME}Action() {\n        super(${DISPLAYNAME}.class);\n        putValue(Action.NAME, \"${TEMPLATENAME}\");\n        putValue(Action.SHORT_DESCRIPTION, \"Demoes a menu item\");\n    }\n\n    @Override\n    protected void actionPerformed(${DISPLAYNAME} arg0, ActionEvent arg1) {\n        JOptionPane.showMessageDialog(null, \"hello\");\n    }\n\n    //Here you can determine whether the menu item is enabled,\n    //depending on the data source type that is selected. In this\n    //example, the menu item is enabled for all types within\n    //the current data source:\n    @Override\n    protected boolean isEnabled(${DISPLAYNAME} arg0) {\n        return true;\n    }\n\n}\n\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/actions/visualVMAction.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n        Creates a skeleton VisualVM shared action.\n    </body>\n</html>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/apptypes/Bundle.properties",
    "content": "# Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nTemplates/VisualVMPluginDevelopment/apptype=Application Type\n\nLBL_ProjectWizardTitle=VisualVM Application Type\n\nLBL_ProjectSelection_Title=Select Project\n\nLBL_NameLocation_Title=Name and Location\nLBL_ProjectName=&Project\\:\nLBL_PackageName=Pac&kage\\:\nLBL_CreatedFiles=&Created Files\\:\nLBL_ModifiedFiles=&Modified Files\\:\n\nACS_SelectProjectPanel=Select Project panel\nACS_CTL_btnProject=Browse Project button\nACS_CTL_comProject=Select from opened projects combobox\n\nLBL_Name=&Template Name \\:\nLBL_DisplayName=D&isplay Name \\:\nLBL_Category=C&ategory\nLBL_Project_Label=&Project \\:\nLBL_Browse=Bro&wse...\nACS_NameAndLocationPanel=Name and Location Panel\nACS_CTL_PackageName=Package Name\nACS_CTL_Category=Category\nACS_CTL_DisplayName=Display Name\nACS_CTL_Name=Template Name\nACS_CTL_ProjectName=Project Name\nACS_CTL_CreatedFilesValue=Created Files\nACS_CTL_ModifiedFilesValue=Modified Files\n\nMSG_No_Projects=No Projects opened\nMSG_NoExternalRoots=Projects with external roots are not supported.\nMSG_NoProjectSelected=A project needs to be selected.\n\nERR_Category_Invalid=Category is malformed.\nERR_Name_Prefix_Empty=Template Name is empty.\nERR_Name_Prefix_Invalid=Template Name is invalid, not a Java identifier.\nERR_Package_Invalid=Package is blank or malformed.\nERR_ToBeCreateFileExists=The file {0} already exists.\nERR_Missing_Modules=The NetBeans platform is missing required modules.\nERR_No_Platform=No NetBeans Platform defined.\nLBL_Name_1=Prefix:\nLBL_DisplayName_1=Data Source:\nLBL_ProjectName_1=Project Name:\nLBL_PackageName_1=Package Name:\nLBL_CreatedFiles_1=Created Files:\nLBL_ModifiedFiles_1=Modified Files:\nLBL_Name_1_1=Type Name:\nLBL_DisplayName_1_1=Main Class:\nLBL_ProjectName_1_1=Project Name:\nLBL_PackageName_1_1=Package Name:\nLBL_CreatedFiles_1_1=Created Files:\nLBL_ModifiedFiles_1_1=Modified Files:\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/apptypes/NameAndLocationPanel.form",
    "content": "<?xml version=\"1.1\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.5\" maxVersion=\"1.7\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"2\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Component id=\"filler\" alignment=\"0\" pref=\"488\" max=\"32767\" attributes=\"0\"/>\n          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n              <Group type=\"103\" groupAlignment=\"0\" max=\"-2\" attributes=\"0\">\n                  <Component id=\"modifiedFiles\" max=\"32767\" attributes=\"1\"/>\n                  <Component id=\"createdFiles\" alignment=\"0\" max=\"32767\" attributes=\"1\"/>\n                  <Component id=\"lblPackageName\" alignment=\"0\" max=\"32767\" attributes=\"1\"/>\n                  <Component id=\"lblName\" alignment=\"0\" max=\"32767\" attributes=\"1\"/>\n                  <Component id=\"lblProjectName\" alignment=\"0\" max=\"32767\" attributes=\"1\"/>\n                  <Component id=\"lblDisplayName\" alignment=\"0\" pref=\"106\" max=\"32767\" attributes=\"1\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"modifiedFilesValue\" pref=\"358\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFilesValue\" pref=\"358\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"comPackageName\" pref=\"358\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"txtProjectName\" pref=\"358\" max=\"32767\" attributes=\"0\"/>\n                  <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n                      <Component id=\"comCategory\" pref=\"332\" max=\"32767\" attributes=\"2\"/>\n                      <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                      <Component id=\"useMainClass\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  </Group>\n                  <Component id=\"txtName\" alignment=\"0\" pref=\"358\" max=\"32767\" attributes=\"2\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <EmptySpace min=\"2\" pref=\"2\" max=\"2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"lblName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"txtName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"14\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"2\" attributes=\"0\">\n                  <Component id=\"lblDisplayName\" alignment=\"2\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"comCategory\" alignment=\"2\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"useMainClass\" alignment=\"2\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"18\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"lblProjectName\" alignment=\"3\" min=\"-2\" pref=\"19\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"txtProjectName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"14\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"lblPackageName\" alignment=\"3\" min=\"-2\" pref=\"24\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"comPackageName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"39\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"createdFiles\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFilesValue\" alignment=\"3\" pref=\"17\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"modifiedFiles\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"modifiedFilesValue\" alignment=\"3\" pref=\"17\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Component id=\"filler\" min=\"-2\" pref=\"92\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" pref=\"20\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"lblName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"txtName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/apptypes/Bundle.properties\" key=\"LBL_Name_1_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"txtName\">\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblDisplayName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"comCategory\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/apptypes/Bundle.properties\" key=\"LBL_DisplayName_1_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblProjectName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"txtProjectName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/apptypes/Bundle.properties\" key=\"LBL_ProjectName_1_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"txtProjectName\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"JavaCodeGenerator_CreateCodeCustom\" type=\"java.lang.String\" value=\"new JTextField(ProjectUtils.getInformation(this.data.getProject()).getDisplayName());\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblPackageName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"comPackageName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/apptypes/Bundle.properties\" key=\"LBL_PackageName_1_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JComboBox\" name=\"comPackageName\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"0\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"JavaCodeGenerator_CreateCodeCustom\" type=\"java.lang.String\" value=\"UIUtil.createPackageComboBox(this.data.getSourceRootGroup());\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"createdFiles\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"createdFilesValue\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/apptypes/Bundle.properties\" key=\"LBL_CreatedFiles_1_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"modifiedFiles\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"modifiedFilesValue\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/apptypes/Bundle.properties\" key=\"LBL_ModifiedFiles_1_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"filler\">\n    </Component>\n    <Component class=\"javax.swing.JTextArea\" name=\"createdFilesValue\">\n      <Properties>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"rows\" type=\"int\" value=\"5\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"null\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextArea\" name=\"modifiedFilesValue\">\n      <Properties>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"rows\" type=\"int\" value=\"5\"/>\n        <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"modifiedFilesValue\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"null\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JComboBox\" name=\"comCategory\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"1\">\n            <StringItem index=\"0\" value=\"com.toy.anagrams.ui.Anagrams\"/>\n          </StringArray>\n        </Property>\n        <Property name=\"nextFocusableComponent\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"useMainClass\"/>\n        </Property>\n      </Properties>\n      <BindingProperties>\n        <BindingProperty name=\"enabled\" source=\"useMainClass\" sourcePath=\"${selected}\" target=\"comCategory\" targetPath=\"enabled\" updateStrategy=\"0\" immediately=\"false\"/>\n      </BindingProperties>\n    </Component>\n    <Component class=\"javax.swing.JCheckBox\" name=\"useMainClass\">\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/apptypes/NameAndLocationPanel.java",
    "content": "\npackage org.graalvm.visualvm.apisupport.apptypes;\n\nimport java.awt.Color;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport javax.swing.JTextField;\nimport javax.swing.UIManager;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.netbeans.api.project.ProjectUtils;\nimport org.netbeans.modules.apisupport.project.CreatedModifiedFiles;\nimport org.netbeans.modules.apisupport.project.NbModuleProject;\nimport org.netbeans.modules.apisupport.project.ui.UIUtil;\nimport org.netbeans.modules.apisupport.project.ui.wizard.BasicWizardIterator;\nimport org.netbeans.modules.apisupport.project.universe.ModuleEntry;\nimport org.netbeans.modules.apisupport.project.universe.NbPlatform;\nimport org.openide.WizardDescriptor;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\nimport org.openide.util.Utilities;\n\n/**\n * The second panel in project template wizard.\n *\n * @author Milos Kleint\n */\nfinal class NameAndLocationPanel extends BasicWizardIterator.Panel {\n    \n    private static final String PROJECT_TEMPLATES_DIR = \"Templates/Project\"; // NOI18N\n    private static final String DEFAULT_CATEGORY_PATH = PROJECT_TEMPLATES_DIR + \"/Other\"; // NOI18N\n    \n    private NewProjectIterator.DataModel data;\n    \n    /** Creates new NameAndLocationPanel */\n    NameAndLocationPanel(WizardDescriptor setting, NewProjectIterator.DataModel data) {\n        super(setting);\n        this.data = data;\n        initComponents();\n        initAccessibility();\n        Color lblBgr = UIManager.getColor(\"Label.background\"); // NOI18N\n        putClientProperty(\"NewFileWizard_Title\", getMessage(\"LBL_ProjectWizardTitle\"));\n        modifiedFilesValue.setBackground(lblBgr);\n        createdFilesValue.setBackground(lblBgr);\n        modifiedFilesValue.setEditable(false);\n        createdFilesValue.setEditable(false);\n        \n        DocumentListener dListener = new UIUtil.DocumentAdapter() {\n            public void insertUpdate(DocumentEvent e) {\n                if (checkValidity()) {\n                    updateData();\n                }\n            }\n        };\n        txtName.getDocument().addDocumentListener(dListener);\n         if (comCategory.getEditor().getEditorComponent() instanceof JTextField) {\n            JTextField txt = (JTextField) comCategory.getEditor().getEditorComponent();\n            txt.getDocument().addDocumentListener(dListener);\n        }\n        if (comPackageName.getEditor().getEditorComponent() instanceof JTextField) {\n            JTextField txt = (JTextField)comPackageName.getEditor().getEditorComponent();\n            txt.getDocument().addDocumentListener(dListener);\n        }\n    }\n    \n    protected void storeToDataModel() {\n        updateData();\n    }\n    \n   \n    \n    private void updateData() {\n        data.setPackageName(comPackageName.getEditor().getItem().toString());\n        data.setName(txtName.getText().trim());\n        data.setCategory(useMainClass.isSelected() ? comCategory.getEditor().getItem().toString() : null);\n        NewProjectIterator.generateFileChanges(data);\n        CreatedModifiedFiles fls = data.getCreatedModifiedFiles();\n        createdFilesValue.setText(generateText(fls.getCreatedPaths()));\n        modifiedFilesValue.setText(generateText(fls.getModifiedPaths()));\n        //#68294 check if the paths for newly created files are valid or not..\n        String[] invalid  = data.getCreatedModifiedFiles().getInvalidPaths();\n        if (invalid.length > 0) {\n            setError(NbBundle.getMessage(NameAndLocationPanel.class, \"ERR_ToBeCreateFileExists\", invalid[0]));\n        }\n        \n    }\n    \n    protected void readFromDataModel() {\n        \n        checkValidity();\n    }\n    \n    protected String getPanelName() {\n        return getMessage(\"LBL_NameLocation_Title\");\n    }\n    \n    private boolean checkValidity() {\n//        if (!checkPlatformValidity()) {\n//            return false;\n//        }\n        if (txtName.getText().trim().length() == 0) {\n            setError(getMessage(\"ERR_Name_Prefix_Empty\"));\n            return false;\n        }\n        if (!Utilities.isJavaIdentifier(txtName.getText().trim())) {\n            setError(getMessage(\"ERR_Name_Prefix_Invalid\"));\n            return false;\n        }\n        String packageName = comPackageName.getEditor().getItem().toString().trim();\n        if (packageName.length() == 0 || !UIUtil.isValidPackageName(packageName)) {\n            setError(getMessage(\"ERR_Package_Invalid\"));\n            return false;\n        }\n\n        markValid();\n        return true;\n    }\n    \n//    private boolean checkPlatformValidity() {\n//        NbModuleProject nbprj = data.getProject().getLookup().lookup(NbModuleProject.class);\n//        if (nbprj == null) {\n//            //ignore this check for non default netbeans projects.\n//            return true;\n//        }\n//        NbPlatform platform = nbprj.getPlatform(false);\n//        if (platform == null) {\n//            setError(getMessage(\"ERR_No_Platform\"));\n//            return false;\n//        }\n//        ModuleEntry[] entries = platform.getModules();\n//        Collection<String> modules = new HashSet<String>(Arrays.asList(NewProjectIterator.MODULES));\n//\n//        for (int i = 0; i < entries.length; i++) {\n//            modules.remove(entries[i].getCodeNameBase());\n//        }\n//        if (modules.size() > 0) {\n//            setError(getMessage(\"ERR_Missing_Modules\"));\n//            return false;\n//        }\n//        return true;\n//    }\n//\n  \n    \n    protected HelpCtx getHelp() {\n        return new HelpCtx(NameAndLocationPanel.class);\n    }\n    \n    private static String getMessage(String key) {\n        return NbBundle.getMessage(NameAndLocationPanel.class, key);\n    }\n    \n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();\n\n        lblName = new javax.swing.JLabel();\n        txtName = new javax.swing.JTextField();\n        lblDisplayName = new javax.swing.JLabel();\n        lblProjectName = new javax.swing.JLabel();\n        txtProjectName = new JTextField(ProjectUtils.getInformation(this.data.getProject()).getDisplayName());\n        lblPackageName = new javax.swing.JLabel();\n        comPackageName = UIUtil.createPackageComboBox(this.data.getSourceRootGroup());\n        createdFiles = new javax.swing.JLabel();\n        modifiedFiles = new javax.swing.JLabel();\n        filler = new javax.swing.JLabel();\n        createdFilesValue = new javax.swing.JTextArea();\n        modifiedFilesValue = new javax.swing.JTextArea();\n        comCategory = new javax.swing.JComboBox();\n        useMainClass = new javax.swing.JCheckBox();\n\n        lblName.setLabelFor(txtName);\n        org.openide.awt.Mnemonics.setLocalizedText(lblName, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, \"LBL_Name_1_1\")); // NOI18N\n\n        lblDisplayName.setLabelFor(comCategory);\n        org.openide.awt.Mnemonics.setLocalizedText(lblDisplayName, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, \"LBL_DisplayName_1_1\")); // NOI18N\n\n        lblProjectName.setLabelFor(txtProjectName);\n        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle(\"org/graalvm/visualvm/apisupport/apptypes/Bundle\"); // NOI18N\n        org.openide.awt.Mnemonics.setLocalizedText(lblProjectName, bundle.getString(\"LBL_ProjectName_1_1\")); // NOI18N\n\n        txtProjectName.setEditable(false);\n\n        lblPackageName.setLabelFor(comPackageName);\n        org.openide.awt.Mnemonics.setLocalizedText(lblPackageName, bundle.getString(\"LBL_PackageName_1_1\")); // NOI18N\n\n        comPackageName.setEditable(true);\n\n        createdFiles.setLabelFor(createdFilesValue);\n        org.openide.awt.Mnemonics.setLocalizedText(createdFiles, bundle.getString(\"LBL_CreatedFiles_1_1\")); // NOI18N\n\n        modifiedFiles.setLabelFor(modifiedFilesValue);\n        org.openide.awt.Mnemonics.setLocalizedText(modifiedFiles, bundle.getString(\"LBL_ModifiedFiles_1_1\")); // NOI18N\n\n        createdFilesValue.setColumns(20);\n        createdFilesValue.setRows(5);\n        createdFilesValue.setBorder(null);\n\n        modifiedFilesValue.setColumns(20);\n        modifiedFilesValue.setRows(5);\n        modifiedFilesValue.setToolTipText(\"modifiedFilesValue\");\n        modifiedFilesValue.setBorder(null);\n\n        comCategory.setEditable(true);\n        comCategory.setModel(new javax.swing.DefaultComboBoxModel(new String[] { \"com.toy.anagrams.ui.Anagrams\" }));\n        comCategory.setNextFocusableComponent(useMainClass);\n\n        org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, useMainClass, org.jdesktop.beansbinding.ELProperty.create(\"${selected}\"), comCategory, org.jdesktop.beansbinding.BeanProperty.create(\"enabled\"));\n        bindingGroup.addBinding(binding);\n\n        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n            .add(filler, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 488, Short.MAX_VALUE)\n            .add(layout.createSequentialGroup()\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)\n                    .add(modifiedFiles, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)\n                    .add(createdFiles, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)\n                    .add(lblPackageName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)\n                    .add(lblName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)\n                    .add(lblProjectName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)\n                    .add(lblDisplayName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 106, Short.MAX_VALUE))\n                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(modifiedFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 358, Short.MAX_VALUE)\n                    .add(createdFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 358, Short.MAX_VALUE)\n                    .add(comPackageName, 0, 358, Short.MAX_VALUE)\n                    .add(txtProjectName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 358, Short.MAX_VALUE)\n                    .add(layout.createSequentialGroup()\n                        .add(comCategory, 0, 332, Short.MAX_VALUE)\n                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)\n                        .add(useMainClass))\n                    .add(txtName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 358, Short.MAX_VALUE))\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n            .add(layout.createSequentialGroup()\n                .add(2, 2, 2)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(lblName)\n                    .add(txtName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(14, 14, 14)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.CENTER)\n                    .add(lblDisplayName)\n                    .add(comCategory, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(useMainClass))\n                .add(18, 18, 18)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(lblProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 19, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(txtProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(14, 14, 14)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(lblPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 24, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(comPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(39, 39, 39)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(createdFiles)\n                    .add(createdFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 17, Short.MAX_VALUE))\n                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(modifiedFiles)\n                    .add(modifiedFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 17, Short.MAX_VALUE))\n                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)\n                .add(filler, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 92, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                .add(20, 20, 20))\n        );\n\n        bindingGroup.bind();\n    }// </editor-fold>//GEN-END:initComponents\n    \n    private void initAccessibility() {\n        this.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_NameAndLocationPanel\"));\n        comPackageName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_PackageName\"));\n        comCategory.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_DisplayName\"));\n        txtName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_Name\"));\n        txtProjectName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_ProjectName\"));\n        createdFilesValue.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_CreatedFilesValue\"));\n        modifiedFilesValue.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_ModifiedFilesValue\"));\n    }\n    \n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JComboBox comCategory;\n    private javax.swing.JComboBox comPackageName;\n    private javax.swing.JLabel createdFiles;\n    private javax.swing.JTextArea createdFilesValue;\n    private javax.swing.JLabel filler;\n    private javax.swing.JLabel lblDisplayName;\n    private javax.swing.JLabel lblName;\n    private javax.swing.JLabel lblPackageName;\n    private javax.swing.JLabel lblProjectName;\n    private javax.swing.JLabel modifiedFiles;\n    private javax.swing.JTextArea modifiedFilesValue;\n    private javax.swing.JTextField txtName;\n    private javax.swing.JTextField txtProjectName;\n    private javax.swing.JCheckBox useMainClass;\n    private org.jdesktop.beansbinding.BindingGroup bindingGroup;\n    // End of variables declaration//GEN-END:variables\n    \n    private static String generateText(String[] relPaths) {\n        StringBuffer sb = new StringBuffer();\n        if (relPaths.length > 0) {\n            for (int i = 0; i < relPaths.length; i++) {\n                if (i > 0) {\n                    sb.append('\\n');\n                }\n                sb.append(relPaths[i]);\n            }\n        }\n        return sb.toString();\n    }\n    \n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/apptypes/NewProjectIterator.java",
    "content": "package org.graalvm.visualvm.apisupport.apptypes;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Set;\nimport org.netbeans.api.project.Project;\nimport org.netbeans.modules.apisupport.project.CreatedModifiedFiles;\nimport org.netbeans.modules.apisupport.project.spi.NbModuleProvider;\nimport org.netbeans.modules.apisupport.project.ui.wizard.BasicWizardIterator;\nimport org.openide.WizardDescriptor;\nimport org.openide.filesystems.FileObject;\n\nfinal class NewProjectIterator extends BasicWizardIterator {\n\n    private NewProjectIterator.DataModel data;\n    \n    public static final String[] MODULES = {\n        \"org.openide.util\", // NOI18N\n        \"org.graalvm.visualvm.application\", // NOI18N\n        \"org.graalvm.visualvm.core\" // NOI18N\n    };\n\n    private NewProjectIterator() { /* Use factory method. */ }\n    ;\n\n    public static NewProjectIterator createIterator() {\n        return new NewProjectIterator();\n    }\n\n    public Set instantiate() throws IOException {\n        CreatedModifiedFiles cmf = data.getCreatedModifiedFiles();\n        cmf.run();\n        return getCreatedFiles(cmf, data.getProject());\n    }\n\n    protected BasicWizardIterator.Panel[] createPanels(WizardDescriptor wiz) {\n        data = new NewProjectIterator.DataModel(wiz);\n        return new BasicWizardIterator.Panel[]{\n                    new NameAndLocationPanel(wiz, data)\n                };\n    }\n\n    public \n    @Override\n    void uninitialize( WizardDescriptor wiz) {\n        super.uninitialize(wiz);\n        data = null;\n    }\n\n    static final class DataModel extends BasicWizardIterator.BasicDataModel {\n\n        private Project template;\n        private String name;\n        private String displayName;\n        private String category;\n        private CreatedModifiedFiles files;\n\n        DataModel(WizardDescriptor wiz) {\n            super(wiz);\n        }\n\n        public CreatedModifiedFiles getCreatedModifiedFiles() {\n            return getFiles();\n        }\n\n        public void setCreatedModifiedFiles(CreatedModifiedFiles files) {\n            this.setFiles(files);\n        }\n\n        public Project getTemplate() {\n            return template;\n        }\n\n        public void setTemplate(Project template) {\n            this.template = template;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public String getDisplayName() {\n            return displayName;\n        }\n\n        public void setDisplayName(String displayName) {\n            this.displayName = displayName;\n        }\n\n        public String getCategory() {\n            return category;\n        }\n\n        public void setCategory(String category) {\n            this.category = category;\n        }\n\n        public CreatedModifiedFiles getFiles() {\n            return files;\n        }\n\n        public void setFiles(CreatedModifiedFiles files) {\n            this.files = files;\n        }\n    }\n\n    public static void generateFileChanges(DataModel model) {\n        CreatedModifiedFiles fileChanges = new CreatedModifiedFiles(model.getProject());\n        NbModuleProvider moduleInfo = model.getModuleInfo();\n        final String category = model.getCategory();\n        final String name = model.getName();\n        final String packageName = model.getPackageName();\n\n        HashMap<String, String> replaceTokens = new HashMap<String, String>();\n        replaceTokens.put(\"DISPLAYNAME\", category);//NOI18N\n\n        replaceTokens.put(\"TEMPLATENAME\", name);//NOI18N\n\n        replaceTokens.put(\"PACKAGENAME\", packageName);//NOI18N\n\n        // Update project dependencies\n        for (int i = 0; i < MODULES.length; i++) {\n            fileChanges.add(fileChanges.addModuleDependency(MODULES[i]));\n        }\n        \n        // Generate view provider class:\n        String iteratorName  = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n                name, \"ApplicationTypeProvider.java\"); //NOI18N\n\n        FileObject template = CreatedModifiedFiles.getTemplate(category != null ? \"templateMainClassApplicationTypeProvider.java\" : \"templateApplicationTypeProvider.java\");//NOI18N\n\n        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n\n        // Generate view class:\n        iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n                name, \"ApplicationType.java\"); //NOI18N\n\n        template = CreatedModifiedFiles.getTemplate(\"templateApplicationType.java\");//NOI18N\n\n        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n        \n        model.setCreatedModifiedFiles(fileChanges);\n    }\n\n    private static String getRelativePath(String rootPath, String fullyQualifiedPackageName,\n            String prefix, String postfix) {\n        StringBuilder sb = new StringBuilder();\n        sb.append(rootPath).append('/').\n                append(fullyQualifiedPackageName.replace('.', '/')).\n                append('/').append(prefix).append(postfix);\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/apptypes/templateApplicationType.javx",
    "content": "<#assign licenseFirst = \"/*\">\n<#assign licensePrefix = \" * \">\n<#assign licenseLast = \" */\">\n<#include \"../Licenses/license-${project.license}.txt\">\n\npackage ${PACKAGENAME};\n\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport java.awt.Image;\nimport org.openide.util.Utilities;\n\npublic class ${TEMPLATENAME}ApplicationType extends ApplicationType {\n\n    protected final int appPID;\n\n    public ${TEMPLATENAME}ApplicationType(int pid) {\n        appPID = pid;\n    }\n\n    @Override\n    public String getName() {\n        return \"${TEMPLATENAME}\";\n    }\n\n    @Override\n    public String getVersion() {\n        return \"1.0\";\n    }\n\n    @Override\n    public String getDescription() {\n        return \"Application type for ${TEMPLATENAME}\";\n    }\n\n    @Override\n    public Image getIcon() {\n        return Utilities.loadImage(\"org/graalvm/visualvm/core/ui/resources/snapshot.png\", true);\n    }\n\n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/apptypes/templateApplicationTypeProvider.javx",
    "content": "<#assign licenseFirst = \"/*\">\n<#assign licensePrefix = \" * \">\n<#assign licenseLast = \" */\">\n<#include \"../Licenses/license-${project.license}.txt\">\n\npackage ${PACKAGENAME};\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\n\npublic class ${TEMPLATENAME}ApplicationTypeProvider extends AbstractModelProvider<ApplicationType,Application> {\n    private static class Singleton {\n        final private static ${TEMPLATENAME}ApplicationTypeProvider INSTANCE = new ${TEMPLATENAME}ApplicationTypeProvider();\n    }\n\n    private ${TEMPLATENAME}ApplicationTypeProvider() {}\n\n    /**\n     * TODO Call this method from the module Installer#restored()\n     **/\n    static public void install() {\n        ApplicationTypeFactory.getDefault().registerProvider(Singleton.INSTANCE);\n    }\n    \n    /**\n     * TODO Call this method from the module Installer#uninstalled()\n     **/\n    static public void uninstall() {\n        ApplicationTypeFactory.getDefault().unregisterProvider(Singleton.INSTANCE);\n    }\n\n    @Override\n    public ApplicationType createModelFor(Application appl) {\n        /* put your logic here */\n        return null;\n    }    \n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/apptypes/templateMainClassApplicationTypeProvider.javx",
    "content": "<#assign licenseFirst = \"/*\">\n<#assign licensePrefix = \" * \">\n<#assign licenseLast = \" */\">\n<#include \"../Licenses/license-${project.license}.txt\">\n\npackage ${PACKAGENAME};\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.application.type.MainClassApplicationTypeFactory;\n\npublic class ${TEMPLATENAME}ApplicationTypeProvider extends MainClassApplicationTypeFactory {\n    private static class Singleton {\n        final private static ${TEMPLATENAME}ApplicationTypeProvider INSTANCE = new ${TEMPLATENAME}ApplicationTypeProvider();\n    }\n\n    private ${TEMPLATENAME}ApplicationTypeProvider() {}\n\n    /**\n     * Call this method from the module Installer#restored()\n     **/\n    static public void install() {\n        ApplicationTypeFactory.getDefault().registerProvider(Singleton.INSTANCE);\n    }\n    \n    /**\n     * Call this method from the module Installer#uninstalled()\n     **/\n    static public void uninstall() {\n        ApplicationTypeFactory.getDefault().unregisterProvider(Singleton.INSTANCE);\n    }\n\n    @Override\n    public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) {\n\n        //TODO: Specify the name of the application's main class here:\n        if (\"${DISPLAYNAME}\".equals(mainClass)) {\n            return new ${TEMPLATENAME}ApplicationType(app.getPid());\n        }\n        return null;\n\n    }\n    \n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/apptypes/visualVMAppType.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n        Creates a skeleton VisualVM application type.\n    </body>\n</html>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/datasources/Bundle.properties",
    "content": "# Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nTemplates/VisualVMPluginDevelopment/datasource=DataSource\n\nLBL_ProjectWizardTitle=VisualVM DataSource\n\nLBL_ProjectSelection_Title=Select Project\n\nLBL_NameLocation_Title=Name and Location\nLBL_ProjectName=&Project\\:\nLBL_PackageName=Pac&kage\\:\nLBL_CreatedFiles=&Created Files\\:\nLBL_ModifiedFiles=&Modified Files\\:\n\nACS_SelectProjectPanel=Select Project panel\nACS_CTL_btnProject=Browse Project button\nACS_CTL_comProject=Select from opened projects combobox\n\nLBL_Name=&Template Name \\:\nLBL_DisplayName=D&isplay Name \\:\nLBL_Category=C&ategory\nLBL_Project_Label=&Project \\:\nLBL_Browse=Bro&wse...\nACS_NameAndLocationPanel=Name and Location Panel\nACS_CTL_PackageName=Package Name\nACS_CTL_Category=Category\nACS_CTL_DisplayName=Display Name\nACS_CTL_Name=Template Name\nACS_CTL_ProjectName=Project Name\nACS_CTL_CreatedFilesValue=Created Files\nACS_CTL_ModifiedFilesValue=Modified Files\n\nMSG_No_Projects=No Projects opened\nMSG_NoExternalRoots=Projects with external roots are not supported.\nMSG_NoProjectSelected=A project needs to be selected.\n\nERR_Category_Invalid=Category is malformed.\nERR_Name_Prefix_Empty=Template Name is empty.\nERR_Name_Prefix_Invalid=Template Name is invalid, not a Java identifier.\nERR_Package_Invalid=Package is blank or malformed.\nERR_ToBeCreateFileExists=The file {0} already exists.\nERR_Missing_Modules=The NetBeans platform is missing required modules.\nERR_No_Platform=No NetBeans Platform defined.\nLBL_Name_1=Prefix:\nLBL_DisplayName_1=Data Source:\nLBL_ProjectName_1=Project Name:\nLBL_PackageName_1=Package Name:\nLBL_CreatedFiles_1=Created Files:\nLBL_ModifiedFiles_1=Modified Files:\nLBL_Name_1_1=Type Name:\nLBL_DisplayName_1_1=Main Class:\nLBL_ProjectName_1_1=Project Name:\nLBL_PackageName_1_1=Package Name:\nLBL_CreatedFiles_1_1=Created Files:\nLBL_ModifiedFiles_1_1=Modified Files:\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/datasources/NameAndLocationPanel.form",
    "content": "<?xml version=\"1.1\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.2\" maxVersion=\"1.2\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"2\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n              <Group type=\"103\" groupAlignment=\"0\" max=\"-2\" attributes=\"0\">\n                  <Component id=\"lblProjectName\" min=\"-2\" pref=\"121\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblPackageName\" min=\"-2\" pref=\"121\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFiles\" min=\"-2\" pref=\"121\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"modifiedFiles\" min=\"-2\" pref=\"121\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblName\" min=\"-2\" pref=\"121\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"comPackageName\" alignment=\"0\" pref=\"293\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFilesValue\" alignment=\"0\" pref=\"293\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"modifiedFilesValue\" alignment=\"0\" pref=\"293\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"txtProjectName\" alignment=\"1\" pref=\"293\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"txtName\" alignment=\"1\" pref=\"293\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n          </Group>\n          <Component id=\"filler\" alignment=\"0\" pref=\"426\" max=\"32767\" attributes=\"0\"/>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"txtName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"txtProjectName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblProjectName\" alignment=\"3\" min=\"-2\" pref=\"19\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"6\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"comPackageName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblPackageName\" alignment=\"3\" min=\"-2\" pref=\"24\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"36\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"createdFilesValue\" alignment=\"3\" pref=\"20\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFiles\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"6\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"modifiedFilesValue\" alignment=\"3\" pref=\"20\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"modifiedFiles\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"filler\" pref=\"131\" max=\"32767\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" pref=\"20\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"lblName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"txtName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_Name_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"txtName\">\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblProjectName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"txtProjectName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_ProjectName_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"txtProjectName\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"JavaCodeGenerator_CreateCodeCustom\" type=\"java.lang.String\" value=\"new JTextField(ProjectUtils.getInformation(this.data.getProject()).getDisplayName());\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblPackageName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"comPackageName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_PackageName_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JComboBox\" name=\"comPackageName\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"0\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"JavaCodeGenerator_CreateCodeCustom\" type=\"java.lang.String\" value=\"UIUtil.createPackageComboBox(this.data.getSourceRootGroup());\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"createdFiles\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"createdFilesValue\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_CreatedFiles_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"modifiedFiles\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"modifiedFilesValue\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_ModifiedFiles_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"filler\">\n    </Component>\n    <Component class=\"javax.swing.JTextArea\" name=\"createdFilesValue\">\n      <Properties>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"rows\" type=\"int\" value=\"5\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"null\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextArea\" name=\"modifiedFilesValue\">\n      <Properties>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"rows\" type=\"int\" value=\"5\"/>\n        <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"modifiedFilesValue\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"null\"/>\n        </Property>\n      </Properties>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/datasources/NameAndLocationPanel.java",
    "content": "\npackage org.graalvm.visualvm.apisupport.datasources;\n\nimport java.awt.Color;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport javax.swing.JTextField;\nimport javax.swing.UIManager;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.netbeans.api.project.ProjectUtils;\nimport org.netbeans.modules.apisupport.project.CreatedModifiedFiles;\nimport org.netbeans.modules.apisupport.project.NbModuleProject;\nimport org.netbeans.modules.apisupport.project.ui.UIUtil;\nimport org.netbeans.modules.apisupport.project.ui.wizard.BasicWizardIterator;\nimport org.netbeans.modules.apisupport.project.universe.ModuleEntry;\nimport org.netbeans.modules.apisupport.project.universe.NbPlatform;\nimport org.openide.WizardDescriptor;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\nimport org.openide.util.Utilities;\n\n/**\n * The second panel in project template wizard.\n *\n * @author Milos Kleint\n */\nfinal class NameAndLocationPanel extends BasicWizardIterator.Panel {\n    \n    private static final String PROJECT_TEMPLATES_DIR = \"Templates/Project\"; // NOI18N\n    private static final String DEFAULT_CATEGORY_PATH = PROJECT_TEMPLATES_DIR + \"/Other\"; // NOI18N\n    \n    private NewProjectIterator.DataModel data;\n    \n    /** Creates new NameAndLocationPanel */\n    NameAndLocationPanel(WizardDescriptor setting, NewProjectIterator.DataModel data) {\n        super(setting);\n        this.data = data;\n        initComponents();\n        initAccessibility();\n        Color lblBgr = UIManager.getColor(\"Label.background\"); // NOI18N\n        putClientProperty(\"NewFileWizard_Title\", getMessage(\"LBL_ProjectWizardTitle\"));\n        modifiedFilesValue.setBackground(lblBgr);\n        createdFilesValue.setBackground(lblBgr);\n        modifiedFilesValue.setEditable(false);\n        createdFilesValue.setEditable(false);\n        \n        DocumentListener dListener = new UIUtil.DocumentAdapter() {\n            public void insertUpdate(DocumentEvent e) {\n                if (checkValidity()) {\n                    updateData();\n                }\n            }\n        };\n        txtName.getDocument().addDocumentListener(dListener);\n        if (comPackageName.getEditor().getEditorComponent() instanceof JTextField) {\n            JTextField txt = (JTextField)comPackageName.getEditor().getEditorComponent();\n            txt.getDocument().addDocumentListener(dListener);\n        }\n    }\n    \n    protected void storeToDataModel() {\n        updateData();\n    }\n    \n   \n    \n    private void updateData() {\n        data.setPackageName(comPackageName.getEditor().getItem().toString());\n        data.setName(txtName.getText().trim());\n        NewProjectIterator.generateFileChanges(data);\n        CreatedModifiedFiles fls = data.getCreatedModifiedFiles();\n        createdFilesValue.setText(generateText(fls.getCreatedPaths()));\n        modifiedFilesValue.setText(generateText(fls.getModifiedPaths()));\n        //#68294 check if the paths for newly created files are valid or not..\n        String[] invalid  = data.getCreatedModifiedFiles().getInvalidPaths();\n        if (invalid.length > 0) {\n            setError(NbBundle.getMessage(NameAndLocationPanel.class, \"ERR_ToBeCreateFileExists\", invalid[0]));\n        }\n        \n    }\n    \n    protected void readFromDataModel() {\n        \n        checkValidity();\n    }\n    \n    protected String getPanelName() {\n        return getMessage(\"LBL_NameLocation_Title\");\n    }\n    \n    private boolean checkValidity() {\n//        if (!checkPlatformValidity()) {\n//            return false;\n//        }\n        if (txtName.getText().trim().length() == 0) {\n            setError(getMessage(\"ERR_Name_Prefix_Empty\"));\n            return false;\n        }\n        if (!Utilities.isJavaIdentifier(txtName.getText().trim())) {\n            setError(getMessage(\"ERR_Name_Prefix_Invalid\"));\n            return false;\n        }\n        String packageName = comPackageName.getEditor().getItem().toString().trim();\n        if (packageName.length() == 0 || !UIUtil.isValidPackageName(packageName)) {\n            setError(getMessage(\"ERR_Package_Invalid\"));\n            return false;\n        }\n\n        markValid();\n        return true;\n    }\n    \n//    private boolean checkPlatformValidity() {\n//        NbModuleProject nbprj = data.getProject().getLookup().lookup(NbModuleProject.class);\n//        if (nbprj == null) {\n//            //ignore this check for non default netbeans projects.\n//            return true;\n//        }\n//        NbPlatform platform = nbprj.getPlatform(false);\n//        if (platform == null) {\n//            setError(getMessage(\"ERR_No_Platform\"));\n//            return false;\n//        }\n//        ModuleEntry[] entries = platform.getModules();\n//        Collection<String> modules = new HashSet<String>(Arrays.asList(NewProjectIterator.MODULES));\n//\n//        for (int i = 0; i < entries.length; i++) {\n//            modules.remove(entries[i].getCodeNameBase());\n//        }\n//        if (modules.size() > 0) {\n//            setError(getMessage(\"ERR_Missing_Modules\"));\n//            return false;\n//        }\n//        return true;\n//    }\n    \n  \n    \n    protected HelpCtx getHelp() {\n        return new HelpCtx(NameAndLocationPanel.class);\n    }\n    \n    private static String getMessage(String key) {\n        return NbBundle.getMessage(NameAndLocationPanel.class, key);\n    }\n    \n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        lblName = new javax.swing.JLabel();\n        txtName = new javax.swing.JTextField();\n        lblProjectName = new javax.swing.JLabel();\n        txtProjectName = new JTextField(ProjectUtils.getInformation(this.data.getProject()).getDisplayName());\n        lblPackageName = new javax.swing.JLabel();\n        comPackageName = UIUtil.createPackageComboBox(this.data.getSourceRootGroup());\n        createdFiles = new javax.swing.JLabel();\n        modifiedFiles = new javax.swing.JLabel();\n        filler = new javax.swing.JLabel();\n        createdFilesValue = new javax.swing.JTextArea();\n        modifiedFilesValue = new javax.swing.JTextArea();\n\n        lblName.setLabelFor(txtName);\n        org.openide.awt.Mnemonics.setLocalizedText(lblName, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, \"LBL_Name_1\")); // NOI18N\n\n        lblProjectName.setLabelFor(txtProjectName);\n        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle(\"org/graalvm/visualvm/apisupport/tabs/Bundle\"); // NOI18N\n        org.openide.awt.Mnemonics.setLocalizedText(lblProjectName, bundle.getString(\"LBL_ProjectName_1\")); // NOI18N\n\n        txtProjectName.setEditable(false);\n\n        lblPackageName.setLabelFor(comPackageName);\n        org.openide.awt.Mnemonics.setLocalizedText(lblPackageName, bundle.getString(\"LBL_PackageName_1\")); // NOI18N\n\n        comPackageName.setEditable(true);\n\n        createdFiles.setLabelFor(createdFilesValue);\n        org.openide.awt.Mnemonics.setLocalizedText(createdFiles, bundle.getString(\"LBL_CreatedFiles_1\")); // NOI18N\n\n        modifiedFiles.setLabelFor(modifiedFilesValue);\n        org.openide.awt.Mnemonics.setLocalizedText(modifiedFiles, bundle.getString(\"LBL_ModifiedFiles_1\")); // NOI18N\n\n        createdFilesValue.setColumns(20);\n        createdFilesValue.setRows(5);\n        createdFilesValue.setBorder(null);\n\n        modifiedFilesValue.setColumns(20);\n        modifiedFilesValue.setRows(5);\n        modifiedFilesValue.setToolTipText(\"modifiedFilesValue\");\n        modifiedFilesValue.setBorder(null);\n\n        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)\n                    .add(lblProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 121, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(lblPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 121, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(createdFiles, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 121, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(modifiedFiles, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 121, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(lblName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 121, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(comPackageName, 0, 293, Short.MAX_VALUE)\n                    .add(createdFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 293, Short.MAX_VALUE)\n                    .add(modifiedFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 293, Short.MAX_VALUE)\n                    .add(org.jdesktop.layout.GroupLayout.TRAILING, txtProjectName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 293, Short.MAX_VALUE)\n                    .add(org.jdesktop.layout.GroupLayout.TRAILING, txtName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 293, Short.MAX_VALUE)))\n            .add(filler, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 426, Short.MAX_VALUE)\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n            .add(layout.createSequentialGroup()\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(txtName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(lblName))\n                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(txtProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(lblProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 19, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(6, 6, 6)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(comPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(lblPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 24, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(36, 36, 36)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(createdFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 20, Short.MAX_VALUE)\n                    .add(createdFiles))\n                .add(6, 6, 6)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(modifiedFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 20, Short.MAX_VALUE)\n                    .add(modifiedFiles))\n                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)\n                .add(filler, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 131, Short.MAX_VALUE)\n                .add(20, 20, 20))\n        );\n    }// </editor-fold>//GEN-END:initComponents\n    \n    private void initAccessibility() {\n        this.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_NameAndLocationPanel\"));\n        comPackageName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_PackageName\"));\n        txtName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_Name\"));\n        txtProjectName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_ProjectName\"));\n        createdFilesValue.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_CreatedFilesValue\"));\n        modifiedFilesValue.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_ModifiedFilesValue\"));\n    }\n    \n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JComboBox comPackageName;\n    private javax.swing.JLabel createdFiles;\n    private javax.swing.JTextArea createdFilesValue;\n    private javax.swing.JLabel filler;\n    private javax.swing.JLabel lblName;\n    private javax.swing.JLabel lblPackageName;\n    private javax.swing.JLabel lblProjectName;\n    private javax.swing.JLabel modifiedFiles;\n    private javax.swing.JTextArea modifiedFilesValue;\n    private javax.swing.JTextField txtName;\n    private javax.swing.JTextField txtProjectName;\n    // End of variables declaration//GEN-END:variables\n    \n    private static String generateText(String[] relPaths) {\n        StringBuffer sb = new StringBuffer();\n        if (relPaths.length > 0) {\n            for (int i = 0; i < relPaths.length; i++) {\n                if (i > 0) {\n                    sb.append('\\n');\n                }\n                sb.append(relPaths[i]);\n            }\n        }\n        return sb.toString();\n    }\n    \n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/datasources/NewProjectIterator.java",
    "content": "package org.graalvm.visualvm.apisupport.datasources;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Set;\nimport org.netbeans.api.project.Project;\nimport org.netbeans.modules.apisupport.project.CreatedModifiedFiles;\nimport org.netbeans.modules.apisupport.project.spi.NbModuleProvider;\nimport org.netbeans.modules.apisupport.project.ui.wizard.BasicWizardIterator;\nimport org.openide.WizardDescriptor;\nimport org.openide.filesystems.FileObject;\n\nfinal class NewProjectIterator extends BasicWizardIterator {\n\n    private NewProjectIterator.DataModel data;\n    public static final String[] MODULES = {\n        \"org.openide.util\", // NOI18N\n        \"org.graalvm.visualvm.core\" // NOI18N\n    };\n\n    private NewProjectIterator() { /* Use factory method. */ }\n    ;\n\n    public static NewProjectIterator createIterator() {\n        return new NewProjectIterator();\n    }\n\n    public Set instantiate() throws IOException {\n        CreatedModifiedFiles cmf = data.getCreatedModifiedFiles();\n        cmf.run();\n        return getCreatedFiles(cmf, data.getProject());\n    }\n\n    protected BasicWizardIterator.Panel[] createPanels(WizardDescriptor wiz) {\n        data = new NewProjectIterator.DataModel(wiz);\n        return new BasicWizardIterator.Panel[]{\n                    new NameAndLocationPanel(wiz, data)\n                };\n    }\n\n    public \n    @Override\n    void uninitialize( WizardDescriptor wiz) {\n        super.uninitialize(wiz);\n        data = null;\n    }\n\n    static final class DataModel extends BasicWizardIterator.BasicDataModel {\n\n        private Project template;\n        private String name;\n        private String displayName;\n        private String category;\n        private CreatedModifiedFiles files;\n\n        DataModel(WizardDescriptor wiz) {\n            super(wiz);\n        }\n\n        public CreatedModifiedFiles getCreatedModifiedFiles() {\n            return getFiles();\n        }\n\n        public void setCreatedModifiedFiles(CreatedModifiedFiles files) {\n            this.setFiles(files);\n        }\n\n        public Project getTemplate() {\n            return template;\n        }\n\n        public void setTemplate(Project template) {\n            this.template = template;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public String getDisplayName() {\n            return displayName;\n        }\n\n        public void setDisplayName(String displayName) {\n            this.displayName = displayName;\n        }\n\n        public String getCategory() {\n            return category;\n        }\n\n        public void setCategory(String category) {\n            this.category = category;\n        }\n\n        public CreatedModifiedFiles getFiles() {\n            return files;\n        }\n\n        public void setFiles(CreatedModifiedFiles files) {\n            this.files = files;\n        }\n    }\n\n    public static void generateFileChanges(DataModel model) {\n        CreatedModifiedFiles fileChanges = new CreatedModifiedFiles(model.getProject());\n        NbModuleProvider moduleInfo = model.getModuleInfo();\n        final String name = model.getName();\n        final String packageName = model.getPackageName();\n\n        HashMap<String, String> replaceTokens = new HashMap<String, String>();\n\n        replaceTokens.put(\"TEMPLATENAME\", name);//NOI18N\n\n        replaceTokens.put(\"PACKAGENAME\", packageName);//NOI18N\n\n        // Update project dependencies\n        for (int i = 0; i < MODULES.length; i++) {\n            fileChanges.add(fileChanges.addModuleDependency(MODULES[i]));\n        }\n\n//        // Generate Support class:\n//        String iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n//                name, \"ViewSupport.java\"); //NOI18N\n//\n//        FileObject template = CreatedModifiedFiles.getTemplate(\"templateViewSupport.java\");//NOI18N\n//\n//        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n//\n        // Generate view provider class:\n        String iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n                name, \"Provider.java\"); //NOI18N\n\n        FileObject template = CreatedModifiedFiles.getTemplate(\"templateDataSourceProvider.java\");//NOI18N\n\n        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n\n        // Generate view class:\n        iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n                name, \".java\"); //NOI18N\n\n        template = CreatedModifiedFiles.getTemplate(\"templateDataSource.java\");//NOI18N\n\n        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n\n        model.setCreatedModifiedFiles(fileChanges);\n    }\n\n    private static String getRelativePath(String rootPath, String fullyQualifiedPackageName,\n            String prefix, String postfix) {\n        StringBuilder sb = new StringBuilder();\n        sb.append(rootPath).append('/').\n                append(fullyQualifiedPackageName.replace('.', '/')).\n                append('/').append(prefix).append(postfix);\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/datasources/templateVisualVMDataSource.javx",
    "content": "<#assign licenseFirst = \"/*\">\n<#assign licensePrefix = \" * \">\n<#assign licenseLast = \" */\">\n<#include \"../Licenses/license-${project.license}.txt\">\n\npackage ${PACKAGENAME};\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\n\nimport java.awt.Image;\n\npublic class ${TEMPLATENAME} extends DataSource {\n    public static class Descriptor extends DataSourceDescriptor<${TEMPLATENAME}> {\n        // TODO adjust the constructors as needed\n        public Descriptor(Bimbo ds, String n, String desc, Image ic, int pos, int aep) {\n            super(ds, n, desc, ic, pos, aep);\n        }\n\n        public Descriptor(Bimbo dataSource) {\n            super(dataSource);\n        }\n    }\n\n    public ${TEMPLATENAME}(DataSource parent) {\n        super(parent);\n        // uncomment to make the datasource invisible\n        // setVisible(false);\n    }\n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/datasources/templateVisualVMDataSourceProvider.javx",
    "content": "<#assign licenseFirst = \"/*\">\n<#assign licensePrefix = \" * \">\n<#assign licenseLast = \" */\">\n<#include \"../Licenses/license-${project.license}.txt\">\n\npackage ${PACKAGENAME};\n\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.TimeUnit;\nimport org.graalvm.visualvm.core.datasource.DataSource;\n\n\n\npublic class ${TEMPLATENAME}Provider {\n    private static class Singleton {\n        final private static ${TEMPLATENAME}Provider INSTANCE = new ${TEMPLATENAME}Provider();\n    }\n\n    final private ScheduledExecutorService discoveryProcess = Executors.newSingleThreadScheduledExecutor();\n\n    private ${TEMPLATENAME}Provider() {}\n\n    private void startup() {\n        // TODO adjust the refresh interval\n        discoveryProcess.schedule(new Runnable() {\n\n            @Override\n            public void run() {\n                discoverDataSources();\n            }\n        }, 5, TimeUnit.SECONDS);\n    }\n    \n    private void shutdown() {\n        discoveryProcess.shutdown();\n    }\n\n    private void discoverDataSources() {\n        // TODO handle the datasource discovery\n        // call <parent datasource>.getRepository().addDataSource()/ addDataSources() to add discovered datasources\n        // call <parent datasource>.getRepository().removeDataSource()/removeDataSources() to remove discovered datasources\n    }\n    \n    public static ${TEMPLATENAME}Provider getInstance() {\n        return Singleton.INSTANCE;\n    }\n\n    /**\n     * TODO Call this method from the module Installer#restored()\n     **/\n    public static void install() {\n        Singleton.INSTANCE.startup();\n    }\n    \n    /**\n     * TODO Call this method from the module Installer#uninstalled()\n     **/\n    public static void uninstall() {\n        Singleton.INSTANCE.shutdown();\n    }\n}\n\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/datasources/visualVMDatasource.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n\n        Creates a skeleton for a new VisualVM datasource support.\n    </body>\n</html>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.2//EN\" \"http://www.netbeans.org/dtds/filesystem-1_2.dtd\">\n<filesystem>\n    <!-- tabs -->\n    <folder name=\"Services\">\n        <folder name=\"JavaHelp\">\n            <file name=\"visualvmview-helpset.xml\" url=\"tabs/visualvmview-helpset.xml\">\n                <attr name=\"position\" stringvalue=\"3665\"/>\n            </file>\n        </folder>\n    </folder>\n    <!-- #tabs -->\n    <folder name=\"Templates\">\n        <folder name=\"VisualVMPluginDevelopment\">\n            <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.apisupport.Bundle#Templates/VisualVMPluginDevelopment\"/>\n            <attr name=\"position\" intvalue=\"225\"/>\n            <file name=\"action\">\n                <attr name=\"SystemFileSystem.icon\" urlvalue=\"nbresloc:/org/graalvm/visualvm/apisupport/resources/vvm.png\"/>\n                <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.graalvm.visualvm.apisupport.actions.Bundle\"/>\n                <attr name=\"instantiatingIterator\" methodvalue=\"org.graalvm.visualvm.apisupport.actions.NewActionIterator.createIterator\"/>\n                <attr name=\"position\" intvalue=\"200\"/>\n                <attr name=\"template\" boolvalue=\"true\"/>\n                <attr name=\"templateWizardURL\" urlvalue=\"nbresloc:/org/graalvm/visualvm/apisupport/actions/visualVMAction.html\"/>\n            </file>\n            <file name=\"apptype\">\n                <attr name=\"position\" intvalue=\"100\"/>\n                <attr name=\"template\" boolvalue=\"true\"/>\n                <attr name=\"SystemFileSystem.icon\" urlvalue=\"nbresloc:/org/graalvm/visualvm/apisupport/resources/vvm.png\"/>\n                <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.graalvm.visualvm.apisupport.apptypes.Bundle\"/>\n                <attr name=\"instantiatingIterator\" methodvalue=\"org.graalvm.visualvm.apisupport.apptypes.NewProjectIterator.createIterator\"/>\n                <attr name=\"templateWizardURL\" urlvalue=\"nbresloc:/org/graalvm/visualvm/apisupport/apptypes/visualVMAppType.html\"/>\n            </file>\n            <file name=\"tab\">\n                <attr name=\"SystemFileSystem.icon\" urlvalue=\"nbresloc:/org/graalvm/visualvm/apisupport/resources/vvm.png\"/>\n                <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.graalvm.visualvm.apisupport.tabs.Bundle\"/>\n                <attr name=\"instantiatingIterator\" methodvalue=\"org.graalvm.visualvm.apisupport.tabs.NewProjectIterator.createIterator\"/>\n                <attr name=\"position\" intvalue=\"150\"/>\n                <attr name=\"template\" boolvalue=\"true\"/>\n                <attr name=\"templateWizardURL\" urlvalue=\"nbresloc:/org/graalvm/visualvm/apisupport/tabs/visualVMView.html\"/>\n            </file>\n            <file name=\"subtab\">\n                <attr name=\"SystemFileSystem.icon\" urlvalue=\"nbresloc:/org/graalvm/visualvm/apisupport/resources/vvm.png\"/>\n                <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.graalvm.visualvm.apisupport.subtabs.Bundle\"/>\n                <attr name=\"instantiatingIterator\" methodvalue=\"org.graalvm.visualvm.apisupport.subtabs.NewProjectIterator.createIterator\"/>\n                <attr name=\"position\" intvalue=\"175\"/>\n                <attr name=\"template\" boolvalue=\"true\"/>\n                <attr name=\"templateWizardURL\" urlvalue=\"nbresloc:/org/graalvm/visualvm/apisupport/subtabs/visualVMSubTab.html\"/>\n            </file>\n            <file name=\"datasource\">\n                <attr name=\"SystemFileSystem.icon\" urlvalue=\"nbresloc:/org/graalvm/visualvm/apisupport/resources/vvm.png\"/>\n                <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.graalvm.visualvm.apisupport.datasources.Bundle\"/>\n                <attr name=\"instantiatingIterator\" methodvalue=\"org.graalvm.visualvm.apisupport.datasources.NewProjectIterator.createIterator\"/>\n                <attr name=\"position\" intvalue=\"500\"/>\n                <attr name=\"template\" boolvalue=\"true\"/>\n                <attr name=\"templateWizardURL\" urlvalue=\"nbresloc:/org/graalvm/visualvm/apisupport/datasources/visualVMDatasource.html\"/>\n            </file>\n            <file name=\"model\">\n                <attr name=\"SystemFileSystem.icon\" urlvalue=\"nbresloc:/org/graalvm/visualvm/apisupport/resources/vvm.png\"/>\n                <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.graalvm.visualvm.apisupport.models.Bundle\"/>\n                <attr name=\"instantiatingIterator\" methodvalue=\"org.graalvm.visualvm.apisupport.models.NewProjectIterator.createIterator\"/>\n                <attr name=\"position\" intvalue=\"400\"/>\n                <attr name=\"template\" boolvalue=\"true\"/>\n                <attr name=\"templateWizardURL\" urlvalue=\"nbresloc:/org/graalvm/visualvm/apisupport/models/visualVMModel.html\"/>\n            </file>\n        </folder>\n        <folder name=\"NetBeansModuleDevelopment-files\">\n            <attr name=\"position\" intvalue=\"0\"/>\n            <attr name=\"simple\" boolvalue=\"false\"/>\n            <!-- actions-->\n            <file name=\"templateAction.java\" url=\"actions/templateAction.javx\"/>\n            <!-- #actions -->\n            <!-- apptypes -->\n            <file name=\"templateApplicationTypeProvider.java\" url=\"apptypes/templateApplicationTypeProvider.javx\"/>\n            <file name=\"templateMainClassApplicationTypeProvider.java\" url=\"apptypes/templateMainClassApplicationTypeProvider.javx\"/>\n            <file name=\"templateApplicationType.java\" url=\"apptypes/templateApplicationType.javx\"/>\n            <!-- #apptypes -->\n            <!-- tabs -->\n            <file name=\"templateViewProvider.java\" url=\"tabs/templateVisualVMViewProvider.javx\"/>\n            <file name=\"templateView.java\" url=\"tabs/templateVisualVMView.javx\"/>\n            <!-- #tabs -->\n            <!-- subtabs -->\n            <file name=\"templateViewPluginProvider.java\" url=\"subtabs/templateVisualVMViewPluginProvider.javx\"/>\n            <file name=\"templateViewPlugin.java\" url=\"subtabs/templateVisualVMViewPlugin.javx\"/>\n            <!-- #subtabs -->\n            <!-- datasources -->\n            <file name=\"templateDataSourceProvider.java\" url=\"datasources/templateVisualVMDataSourceProvider.javx\"/>\n            <file name=\"templateDataSource.java\" url=\"datasources/templateVisualVMDataSource.javx\"/>\n            <!-- #datasources -->\n            <!-- models -->\n            <file name=\"templateModelProvider.java\" url=\"models/templateVisualVMModelProvider.javx\"/>\n            <file name=\"templateModel.java\" url=\"models/templateVisualVMModel.javx\"/>\n            <file name=\"templateModelFactory.java\" url=\"models/templateVisualVMModelFactory.javx\"/>\n            <!-- #models -->\n        </folder>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/models/Bundle.properties",
    "content": "# Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nTemplates/VisualVMPluginDevelopment/model=Model\n\nLBL_ProjectWizardTitle=VisualVM Model\n\nLBL_ProjectSelection_Title=Select Project\n\nLBL_NameLocation_Title=Name and Location\nLBL_ProjectName=&Project\\:\nLBL_PackageName=Pac&kage\\:\nLBL_CreatedFiles=&Created Files\\:\nLBL_ModifiedFiles=&Modified Files\\:\n\nACS_SelectProjectPanel=Select Project panel\nACS_CTL_btnProject=Browse Project button\nACS_CTL_comProject=Select from opened projects combobox\n\nLBL_Name=&Template Name \\:\nLBL_DisplayName=D&isplay Name \\:\nLBL_Category=C&ategory\nLBL_Project_Label=&Project \\:\nLBL_Browse=Bro&wse...\nACS_NameAndLocationPanel=Name and Location Panel\nACS_CTL_PackageName=Package Name\nACS_CTL_Category=Category\nACS_CTL_DisplayName=Display Name\nACS_CTL_Name=Template Name\nACS_CTL_ProjectName=Project Name\nACS_CTL_CreatedFilesValue=Created Files\nACS_CTL_ModifiedFilesValue=Modified Files\nACS_CTL_GenerateModelFactory=Generate Model Factory\n\nMSG_No_Projects=No Projects opened\nMSG_NoExternalRoots=Projects with external roots are not supported.\nMSG_NoProjectSelected=A project needs to be selected.\n\nERR_Category_Invalid=Category is malformed.\nERR_Name_Prefix_Empty=Template Name is empty.\nERR_Name_Prefix_Invalid=Template Name is invalid, not a Java identifier.\nERR_Package_Invalid=Package is blank or malformed.\nERR_ToBeCreateFileExists=The file {0} already exists.\nERR_Missing_Modules=The NetBeans platform is missing required modules.\nERR_No_Platform=No NetBeans Platform defined.\nLBL_Name_1=Name:\nLBL_DisplayName_1=Data Source:\nLBL_ProjectName_1=Project Name:\nLBL_PackageName_1=Package Name:\nLBL_CreatedFiles_1=Created Files:\nLBL_ModifiedFiles_1=Modified Files:\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/models/NameAndLocationPanel.form",
    "content": "<?xml version=\"1.1\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.2\" maxVersion=\"1.2\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"2\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Component id=\"filler\" alignment=\"0\" pref=\"426\" max=\"32767\" attributes=\"0\"/>\n          <Component id=\"generateFactory\" alignment=\"1\" pref=\"426\" max=\"32767\" attributes=\"0\"/>\n          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n              <Group type=\"103\" groupAlignment=\"0\" max=\"-2\" attributes=\"0\">\n                  <Component id=\"modifiedFiles\" alignment=\"0\" min=\"-2\" pref=\"104\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblProjectName\" min=\"-2\" pref=\"104\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblPackageName\" min=\"-2\" pref=\"104\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblName\" min=\"-2\" pref=\"104\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFiles\" min=\"-2\" pref=\"104\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n                      <Group type=\"103\" groupAlignment=\"1\" attributes=\"0\">\n                          <Component id=\"createdFilesValue\" alignment=\"0\" pref=\"298\" max=\"32767\" attributes=\"0\"/>\n                          <Component id=\"modifiedFilesValue\" alignment=\"1\" pref=\"298\" max=\"32767\" attributes=\"0\"/>\n                      </Group>\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                  </Group>\n                  <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n                      <Group type=\"103\" groupAlignment=\"1\" attributes=\"0\">\n                          <Component id=\"txtName\" alignment=\"0\" pref=\"298\" max=\"32767\" attributes=\"2\"/>\n                          <Component id=\"txtProjectName\" alignment=\"0\" pref=\"298\" max=\"32767\" attributes=\"0\"/>\n                          <Component id=\"comPackageName\" alignment=\"1\" pref=\"298\" max=\"32767\" attributes=\"0\"/>\n                      </Group>\n                      <EmptySpace max=\"-2\" attributes=\"0\"/>\n                  </Group>\n              </Group>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"txtName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"txtProjectName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblProjectName\" alignment=\"3\" min=\"-2\" pref=\"19\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"6\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"comPackageName\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblPackageName\" alignment=\"3\" min=\"-2\" pref=\"24\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace type=\"separate\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"generateFactory\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace type=\"separate\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"createdFiles\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFilesValue\" alignment=\"3\" pref=\"18\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"3\" attributes=\"0\">\n                  <Component id=\"modifiedFiles\" alignment=\"3\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"modifiedFilesValue\" alignment=\"3\" pref=\"18\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"43\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"filler\" min=\"-2\" pref=\"76\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" pref=\"20\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"lblName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"txtName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_Name_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"txtName\">\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblProjectName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"txtProjectName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_ProjectName_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"txtProjectName\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"JavaCodeGenerator_CreateCodeCustom\" type=\"java.lang.String\" value=\"new JTextField(ProjectUtils.getInformation(this.data.getProject()).getDisplayName());\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblPackageName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"comPackageName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_PackageName_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JComboBox\" name=\"comPackageName\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"0\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"JavaCodeGenerator_CreateCodeCustom\" type=\"java.lang.String\" value=\"UIUtil.createPackageComboBox(this.data.getSourceRootGroup());\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"createdFiles\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"createdFilesValue\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_CreatedFiles_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"modifiedFiles\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"modifiedFilesValue\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_ModifiedFiles_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"filler\">\n    </Component>\n    <Component class=\"javax.swing.JTextArea\" name=\"createdFilesValue\">\n      <Properties>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"rows\" type=\"int\" value=\"5\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"null\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextArea\" name=\"modifiedFilesValue\">\n      <Properties>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"rows\" type=\"int\" value=\"5\"/>\n        <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"modifiedFilesValue\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"null\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JCheckBox\" name=\"generateFactory\">\n      <Properties>\n        <Property name=\"text\" type=\"java.lang.String\" value=\"Generate Model Factory\"/>\n        <Property name=\"horizontalTextPosition\" type=\"int\" value=\"10\"/>\n      </Properties>\n      <Events>\n        <EventHandler event=\"actionPerformed\" listener=\"java.awt.event.ActionListener\" parameters=\"java.awt.event.ActionEvent\" handler=\"generateFactoryActionPerformed\"/>\n      </Events>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/models/NameAndLocationPanel.java",
    "content": "\npackage org.graalvm.visualvm.apisupport.models;\n\nimport org.graalvm.visualvm.apisupport.datasources.*;\nimport java.awt.Color;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport javax.swing.JTextField;\nimport javax.swing.UIManager;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.netbeans.api.project.ProjectUtils;\nimport org.netbeans.modules.apisupport.project.CreatedModifiedFiles;\nimport org.netbeans.modules.apisupport.project.NbModuleProject;\nimport org.netbeans.modules.apisupport.project.ui.UIUtil;\nimport org.netbeans.modules.apisupport.project.ui.wizard.BasicWizardIterator;\nimport org.netbeans.modules.apisupport.project.universe.ModuleEntry;\nimport org.netbeans.modules.apisupport.project.universe.NbPlatform;\nimport org.openide.WizardDescriptor;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\nimport org.openide.util.Utilities;\n\n/**\n * The second panel in project template wizard.\n *\n * @author Milos Kleint\n */\nfinal class NameAndLocationPanel extends BasicWizardIterator.Panel {\n    \n    private static final String PROJECT_TEMPLATES_DIR = \"Templates/Project\"; // NOI18N\n    private static final String DEFAULT_CATEGORY_PATH = PROJECT_TEMPLATES_DIR + \"/Other\"; // NOI18N\n    \n    private NewProjectIterator.DataModel data;\n    \n    /** Creates new NameAndLocationPanel */\n    NameAndLocationPanel(WizardDescriptor setting, NewProjectIterator.DataModel data) {\n        super(setting);\n        this.data = data;\n        initComponents();\n        initAccessibility();\n        Color lblBgr = UIManager.getColor(\"Label.background\"); // NOI18N\n        putClientProperty(\"NewFileWizard_Title\", getMessage(\"LBL_ProjectWizardTitle\"));\n        modifiedFilesValue.setBackground(lblBgr);\n        createdFilesValue.setBackground(lblBgr);\n        modifiedFilesValue.setEditable(false);\n        createdFilesValue.setEditable(false);\n        \n        DocumentListener dListener = new UIUtil.DocumentAdapter() {\n            public void insertUpdate(DocumentEvent e) {\n                if (checkValidity()) {\n                    updateData();\n                }\n            }\n        };\n        txtName.getDocument().addDocumentListener(dListener);\n        if (comPackageName.getEditor().getEditorComponent() instanceof JTextField) {\n            JTextField txt = (JTextField)comPackageName.getEditor().getEditorComponent();\n            txt.getDocument().addDocumentListener(dListener);\n        }\n    }\n    \n    protected void storeToDataModel() {\n        updateData();\n    }\n    \n   \n    \n    private void updateData() {\n        data.setPackageName(comPackageName.getEditor().getItem().toString());\n        data.setName(txtName.getText().trim());\n        data.setGenerateFactory(generateFactory.isSelected());\n        \n        NewProjectIterator.generateFileChanges(data);\n        CreatedModifiedFiles fls = data.getCreatedModifiedFiles();\n        createdFilesValue.setText(generateText(fls.getCreatedPaths()));\n        modifiedFilesValue.setText(generateText(fls.getModifiedPaths()));\n        //#68294 check if the paths for newly created files are valid or not..\n        String[] invalid  = data.getCreatedModifiedFiles().getInvalidPaths();\n        if (invalid.length > 0) {\n            setError(NbBundle.getMessage(NameAndLocationPanel.class, \"ERR_ToBeCreateFileExists\", invalid[0]));\n        }\n        \n    }\n    \n    protected void readFromDataModel() {\n        \n        checkValidity();\n    }\n    \n    protected String getPanelName() {\n        return getMessage(\"LBL_NameLocation_Title\");\n    }\n    \n    private boolean checkValidity() {\n//        if (!checkPlatformValidity()) {\n//            return false;\n//        }\n        if (txtName.getText().trim().length() == 0) {\n            setError(getMessage(\"ERR_Name_Prefix_Empty\"));\n            return false;\n        }\n        if (!Utilities.isJavaIdentifier(txtName.getText().trim())) {\n            setError(getMessage(\"ERR_Name_Prefix_Invalid\"));\n            return false;\n        }\n        String packageName = comPackageName.getEditor().getItem().toString().trim();\n        if (packageName.length() == 0 || !UIUtil.isValidPackageName(packageName)) {\n            setError(getMessage(\"ERR_Package_Invalid\"));\n            return false;\n        }\n\n        markValid();\n        return true;\n    }\n    \n//    private boolean checkPlatformValidity() {\n//        NbModuleProject nbprj = data.getProject().getLookup().lookup(NbModuleProject.class);\n//        if (nbprj == null) {\n//            //ignore this check for non default netbeans projects.\n//            return true;\n//        }\n//        NbPlatform platform = nbprj.getPlatform(false);\n//        if (platform == null) {\n//            setError(getMessage(\"ERR_No_Platform\"));\n//            return false;\n//        }\n//        ModuleEntry[] entries = platform.getModules();\n//        Collection<String> modules = new HashSet<String>(Arrays.asList(NewProjectIterator.MODULES));\n//\n//        for (int i = 0; i < entries.length; i++) {\n//            modules.remove(entries[i].getCodeNameBase());\n//        }\n//        if (modules.size() > 0) {\n//            setError(getMessage(\"ERR_Missing_Modules\"));\n//            return false;\n//        }\n//        return true;\n//    }\n    \n  \n    \n    protected HelpCtx getHelp() {\n        return new HelpCtx(NameAndLocationPanel.class);\n    }\n    \n    private static String getMessage(String key) {\n        return NbBundle.getMessage(NameAndLocationPanel.class, key);\n    }\n    \n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        lblName = new javax.swing.JLabel();\n        txtName = new javax.swing.JTextField();\n        lblProjectName = new javax.swing.JLabel();\n        txtProjectName = new JTextField(ProjectUtils.getInformation(this.data.getProject()).getDisplayName());\n        lblPackageName = new javax.swing.JLabel();\n        comPackageName = UIUtil.createPackageComboBox(this.data.getSourceRootGroup());\n        createdFiles = new javax.swing.JLabel();\n        modifiedFiles = new javax.swing.JLabel();\n        filler = new javax.swing.JLabel();\n        createdFilesValue = new javax.swing.JTextArea();\n        modifiedFilesValue = new javax.swing.JTextArea();\n        generateFactory = new javax.swing.JCheckBox();\n\n        lblName.setLabelFor(txtName);\n        org.openide.awt.Mnemonics.setLocalizedText(lblName, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, \"LBL_Name_1\")); // NOI18N\n\n        lblProjectName.setLabelFor(txtProjectName);\n        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle(\"org/graalvm/visualvm/apisupport/tabs/Bundle\"); // NOI18N\n        org.openide.awt.Mnemonics.setLocalizedText(lblProjectName, bundle.getString(\"LBL_ProjectName_1\")); // NOI18N\n\n        txtProjectName.setEditable(false);\n\n        lblPackageName.setLabelFor(comPackageName);\n        org.openide.awt.Mnemonics.setLocalizedText(lblPackageName, bundle.getString(\"LBL_PackageName_1\")); // NOI18N\n\n        comPackageName.setEditable(true);\n\n        createdFiles.setLabelFor(createdFilesValue);\n        org.openide.awt.Mnemonics.setLocalizedText(createdFiles, bundle.getString(\"LBL_CreatedFiles_1\")); // NOI18N\n\n        modifiedFiles.setLabelFor(modifiedFilesValue);\n        org.openide.awt.Mnemonics.setLocalizedText(modifiedFiles, bundle.getString(\"LBL_ModifiedFiles_1\")); // NOI18N\n\n        createdFilesValue.setColumns(20);\n        createdFilesValue.setRows(5);\n        createdFilesValue.setBorder(null);\n\n        modifiedFilesValue.setColumns(20);\n        modifiedFilesValue.setRows(5);\n        modifiedFilesValue.setToolTipText(\"modifiedFilesValue\");\n        modifiedFilesValue.setBorder(null);\n\n        org.openide.awt.Mnemonics.setLocalizedText(generateFactory, \"Generate Model Factory\");\n        generateFactory.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);\n        generateFactory.addActionListener(new java.awt.event.ActionListener() {\n            public void actionPerformed(java.awt.event.ActionEvent evt) {\n                generateFactoryActionPerformed(evt);\n            }\n        });\n\n        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n            .add(filler, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 426, Short.MAX_VALUE)\n            .add(org.jdesktop.layout.GroupLayout.TRAILING, generateFactory, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 426, Short.MAX_VALUE)\n            .add(layout.createSequentialGroup()\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)\n                    .add(modifiedFiles, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 104, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(lblProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 104, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(lblPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 104, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(lblName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 104, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(createdFiles, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 104, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()\n                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)\n                            .add(org.jdesktop.layout.GroupLayout.LEADING, createdFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 298, Short.MAX_VALUE)\n                            .add(modifiedFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 298, Short.MAX_VALUE))\n                        .addContainerGap())\n                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()\n                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)\n                            .add(org.jdesktop.layout.GroupLayout.LEADING, txtName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 298, Short.MAX_VALUE)\n                            .add(org.jdesktop.layout.GroupLayout.LEADING, txtProjectName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 298, Short.MAX_VALUE)\n                            .add(comPackageName, 0, 298, Short.MAX_VALUE))\n                        .addContainerGap())))\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n            .add(layout.createSequentialGroup()\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(txtName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(lblName))\n                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(txtProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(lblProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 19, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(6, 6, 6)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(comPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(lblPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 24, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(18, 18, 18)\n                .add(generateFactory)\n                .add(18, 18, 18)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(createdFiles)\n                    .add(createdFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 18, Short.MAX_VALUE))\n                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)\n                    .add(modifiedFiles)\n                    .add(modifiedFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 18, Short.MAX_VALUE))\n                .add(43, 43, 43)\n                .add(filler, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 76, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                .add(20, 20, 20))\n        );\n    }// </editor-fold>//GEN-END:initComponents\n\n    private void generateFactoryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_generateFactoryActionPerformed\n        if (checkValidity()) {\n            updateData();\n        }\n    }//GEN-LAST:event_generateFactoryActionPerformed\n    \n    private void initAccessibility() {\n        this.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_NameAndLocationPanel\"));\n        comPackageName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_PackageName\"));\n        txtName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_Name\"));\n        txtProjectName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_ProjectName\"));\n        createdFilesValue.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_CreatedFilesValue\"));\n        modifiedFilesValue.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_ModifiedFilesValue\"));\n        generateFactory.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_GenerateModelFactory\"));\n    }\n    \n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JComboBox comPackageName;\n    private javax.swing.JLabel createdFiles;\n    private javax.swing.JTextArea createdFilesValue;\n    private javax.swing.JLabel filler;\n    private javax.swing.JCheckBox generateFactory;\n    private javax.swing.JLabel lblName;\n    private javax.swing.JLabel lblPackageName;\n    private javax.swing.JLabel lblProjectName;\n    private javax.swing.JLabel modifiedFiles;\n    private javax.swing.JTextArea modifiedFilesValue;\n    private javax.swing.JTextField txtName;\n    private javax.swing.JTextField txtProjectName;\n    // End of variables declaration//GEN-END:variables\n    \n    private static String generateText(String[] relPaths) {\n        StringBuilder sb = new StringBuilder();\n        if (relPaths.length > 0) {\n            for (int i = 0; i < relPaths.length; i++) {\n                if (i > 0) {\n                    sb.append('\\n');\n                }\n                sb.append(relPaths[i]);\n            }\n        }\n        return sb.toString();\n    }\n    \n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/models/NewProjectIterator.java",
    "content": "package org.graalvm.visualvm.apisupport.models;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Set;\nimport org.netbeans.api.project.Project;\nimport org.netbeans.modules.apisupport.project.CreatedModifiedFiles;\nimport org.netbeans.modules.apisupport.project.spi.NbModuleProvider;\nimport org.netbeans.modules.apisupport.project.ui.wizard.BasicWizardIterator;\nimport org.openide.WizardDescriptor;\nimport org.openide.filesystems.FileObject;\n\nfinal class NewProjectIterator extends BasicWizardIterator {\n\n    private NewProjectIterator.DataModel data;\n    public static final String[] MODULES = {\n        \"org.openide.util\", // NOI18N\n        \"org.graalvm.visualvm.core\" // NOI18N\n    };\n\n    private NewProjectIterator() { /* Use factory method. */ }\n    ;\n\n    public static NewProjectIterator createIterator() {\n        return new NewProjectIterator();\n    }\n\n    public Set instantiate() throws IOException {\n        CreatedModifiedFiles cmf = data.getCreatedModifiedFiles();\n        cmf.run();\n        return getCreatedFiles(cmf, data.getProject());\n    }\n\n    protected BasicWizardIterator.Panel[] createPanels(WizardDescriptor wiz) {\n        data = new NewProjectIterator.DataModel(wiz);\n        return new BasicWizardIterator.Panel[]{\n                    new NameAndLocationPanel(wiz, data)\n                };\n    }\n\n    public \n    @Override\n    void uninitialize( WizardDescriptor wiz) {\n        super.uninitialize(wiz);\n        data = null;\n    }\n\n    static final class DataModel extends BasicWizardIterator.BasicDataModel {\n\n        private Project template;\n        private String name;\n        private String displayName;\n        private String category;\n        private CreatedModifiedFiles files;\n        private boolean generateFactory;\n\n        DataModel(WizardDescriptor wiz) {\n            super(wiz);\n        }\n\n        public CreatedModifiedFiles getCreatedModifiedFiles() {\n            return getFiles();\n        }\n\n        public void setCreatedModifiedFiles(CreatedModifiedFiles files) {\n            this.setFiles(files);\n        }\n\n        public Project getTemplate() {\n            return template;\n        }\n\n        public void setTemplate(Project template) {\n            this.template = template;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public String getDisplayName() {\n            return displayName;\n        }\n\n        public void setDisplayName(String displayName) {\n            this.displayName = displayName;\n        }\n\n        public String getCategory() {\n            return category;\n        }\n\n        public void setCategory(String category) {\n            this.category = category;\n        }\n\n        public CreatedModifiedFiles getFiles() {\n            return files;\n        }\n\n        public void setFiles(CreatedModifiedFiles files) {\n            this.files = files;\n        }\n\n        public boolean isGenerateFactory() {\n            return generateFactory;\n        }\n\n        public void setGenerateFactory(boolean generateFactory) {\n            this.generateFactory = generateFactory;\n        }\n    }\n\n    public static void generateFileChanges(DataModel model) {\n        CreatedModifiedFiles fileChanges = new CreatedModifiedFiles(model.getProject());\n        NbModuleProvider moduleInfo = model.getModuleInfo();\n        final String category = model.getCategory();\n        final String name = model.getName();\n        final String packageName = model.getPackageName();\n\n        HashMap<String, String> replaceTokens = new HashMap<String, String>();\n\n        replaceTokens.put(\"TEMPLATENAME\", name);//NOI18N\n\n        replaceTokens.put(\"PACKAGENAME\", packageName);//NOI18N\n\n        // Update project dependencies\n        for (int i = 0; i < MODULES.length; i++) {\n            fileChanges.add(fileChanges.addModuleDependency(MODULES[i]));\n        }\n\n//        // Generate Support class:\n//        String iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n//                name, \"ViewSupport.java\"); //NOI18N\n//\n//        FileObject template = CreatedModifiedFiles.getTemplate(\"templateViewSupport.java\");//NOI18N\n//\n//        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n//\n        // Generate view provider class:\n        String iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n                name, \"ModelProvider.java\"); //NOI18N\n\n        FileObject template = CreatedModifiedFiles.getTemplate(\"templateModelProvider.java\");//NOI18N\n\n        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n\n        // Generate view class:\n        iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n                name, \"Model.java\"); //NOI18N\n\n        template = CreatedModifiedFiles.getTemplate(\"templateModel.java\");//NOI18N\n\n        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n        \n        if (model.isGenerateFactory()) {\n            iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n                name, \"ModelFactory.java\"); //NOI18N\n\n            template = CreatedModifiedFiles.getTemplate(\"templateModelFactory.java\");//NOI18N\n\n            fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n        }\n\n        model.setCreatedModifiedFiles(fileChanges);\n    }\n\n    private static String getRelativePath(String rootPath, String fullyQualifiedPackageName,\n            String prefix, String postfix) {\n        StringBuilder sb = new StringBuilder();\n        sb.append(rootPath).append('/').\n                append(fullyQualifiedPackageName.replace('.', '/')).\n                append('/').append(prefix).append(postfix);\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/models/templateVisualVMModel.javx",
    "content": "<#assign licenseFirst = \"/*\">\n<#assign licensePrefix = \" * \">\n<#assign licenseLast = \" */\">\n<#include \"../Licenses/license-${project.license}.txt\">\n\npackage ${PACKAGENAME};\n\nimport org.graalvm.visualvm.core.model.Model;\n\npublic class ${TEMPLATENAME}Model extends Model {\n    // TODO add model specific properties\n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/models/templateVisualVMModelFactory.javx",
    "content": "<#assign licenseFirst = \"/*\">\n<#assign licensePrefix = \" * \">\n<#assign licenseLast = \" */\">\n<#include \"../Licenses/license-${project.license}.txt\">\n\npackage ${PACKAGENAME};\n\nimport org.graalvm.visualvm.core.model.ModelFactory;\nimport org.graalvm.visualvm.core.datasource.DataSource;\n\npublic class ${TEMPLATENAME}ModelFactory extends ModelFactory<${TEMPLATENAME}Model, DataSource> {\n    private static class Singleton {\n        final private static ${TEMPLATENAME}ModelFactory INSTANCE = new ${TEMPLATENAME}ModelFactory();\n    }\n\n    private ${TEMPLATENAME}ModelFactory() {\n        \n    }\n    \n    public static ${TEMPLATENAME}ModelFactory getInstance() {\n        return Singleton.INSTANCE;\n    }\n\n    /**\n     * Factory method for obtaining the {@link ${TEMPLATENAME}Model} for the given\n     * {@link DataSource}. Note that there is only one instance of\n     * {@link ${TEMPLATENAME}Model} for application instance. This {@link ${TEMPLATENAME}Model}\n     * instance is cached.\n     * \n     * @param ds datasource.\n     * \n     * @return a {@link ${TEMPLATENAME}Model} instance which encapsulates the\n     * application's ${TEMPLATENAME} model.\n     */\n    public static ${TEMPLATENAME}Model get${TEMPLATENAME}ModelFor(DataSource ds) {\n        return getInstance().getModel(ds);\n    }\n}"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/models/templateVisualVMModelProvider.javx",
    "content": "<#assign licenseFirst = \"/*\">\n<#assign licensePrefix = \" * \">\n<#assign licenseLast = \" */\">\n<#include \"../Licenses/license-${project.license}.txt\">\n\npackage ${PACKAGENAME};\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\npublic class ${TEMPLATENAME}ModelProvider extends AbstractModelProvider<${TEMPLATENAME}Model, DataSource> {\n    private static class Singleton {\n        final private static ${TEMPLATENAME}ModelProvider INSTANCE = new ${TEMPLATENAME}ModelProvider();\n    }\n\n    private ${TEMPLATENAME}ModelProvider() {}\n\n    @Override\n    public ${TEMPLATENAME}Model createModelFor(DataSource datasource) {\n        // TODO check the datasource and create an appropriate model, eventually\n        return null;\n    }\n    \n    public static ${TEMPLATENAME}ModelProvider getInstance() {\n        return Singleton.INSTANCE;\n    }\n\n    /**\n     * TODO Call this method from the module Installer#restored()\n     **/\n    public static void install() {\n        // TODO register with the appropriate model factory\n    }\n\n    /**\n     * TODO Call this method from the module Installer#uninstalled()\n     **/\n    public static void uninstall() {\n        // TODO unregister from the appropriate model factory\n    }\n}\n\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/models/visualVMModel.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n\n        Creates a skeleton for a new VisualVM model support.\n    </body>\n</html>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/subtabs/Bundle.properties",
    "content": "# Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nTemplates/VisualVMPluginDevelopment/subtab=View Plugin (Subtab)\n\nLBL_ProjectWizardTitle=VisualVM View Plugin (Subtab)\n\nLBL_ProjectSelection_Title=Select Project\n\nLBL_NameLocation_Title=Name and Location\nLBL_ProjectName=&Project\\:\nLBL_PackageName=Pac&kage\\:\nLBL_CreatedFiles=&Created Files\\:\nLBL_ModifiedFiles=&Modified Files\\:\n\nACS_SelectProjectPanel=Select Project panel\nACS_CTL_btnProject=Browse Project button\nACS_CTL_comProject=Select from opened projects combobox\n\nLBL_Name=&Template Name \\:\nLBL_DisplayName=D&isplay Name \\:\nLBL_Category=C&ategory\nLBL_Project_Label=&Project \\:\nLBL_Browse=Bro&wse...\nACS_NameAndLocationPanel=Name and Location Panel\nACS_CTL_PackageName=Package Name\nACS_CTL_Category=Category\nACS_CTL_DisplayName=Display Name\nACS_CTL_Name=Template Name\nACS_CTL_ProjectName=Project Name\nACS_CTL_CreatedFilesValue=Created Files\nACS_CTL_ModifiedFilesValue=Modified Files\n\nMSG_No_Projects=No Projects opened\nMSG_NoExternalRoots=Projects with external roots are not supported.\nMSG_NoProjectSelected=A project needs to be selected.\n\nERR_Category_Invalid=Category is malformed.\nERR_Name_Prefix_Empty=Template Name is empty.\nERR_Name_Prefix_Invalid=Template Name is invalid, not a Java identifier.\nERR_Package_Invalid=Package is blank or malformed.\nERR_ToBeCreateFileExists=The file {0} already exists.\nERR_Missing_Modules=The NetBeans platform is missing required modules.\nERR_No_Platform=No NetBeans Platform defined.\nLBL_Name_1=Prefix:\nLBL_DisplayName_1=Data Source:\nLBL_ProjectName_1=Project Name:\nLBL_PackageName_1=Package Name:\nLBL_CreatedFiles_1=Created Files:\nLBL_ModifiedFiles_1=Modified Files:\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/subtabs/NameAndLocationPanel.form",
    "content": "<?xml version=\"1.1\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.2\" maxVersion=\"1.2\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"2\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <Group type=\"103\" groupAlignment=\"0\" max=\"-2\" attributes=\"0\">\n                  <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n                      <Component id=\"lblName\" min=\"-2\" pref=\"64\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace pref=\"54\" max=\"32767\" attributes=\"3\"/>\n                  </Group>\n                  <Component id=\"lblProjectName\" min=\"-2\" pref=\"118\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblPackageName\" min=\"-2\" pref=\"118\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFiles\" min=\"-2\" pref=\"118\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"modifiedFiles\" min=\"-2\" pref=\"118\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"12\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"txtName\" alignment=\"0\" pref=\"296\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"comCategory\" alignment=\"0\" pref=\"296\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"txtProjectName\" alignment=\"0\" pref=\"296\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"comPackageName\" alignment=\"0\" pref=\"296\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFilesValue\" alignment=\"0\" pref=\"296\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"modifiedFilesValue\" alignment=\"0\" pref=\"296\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n          </Group>\n          <Component id=\"filler\" min=\"-2\" pref=\"400\" max=\"-2\" attributes=\"0\"/>\n          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n              <Component id=\"lblDisplayName\" min=\"-2\" pref=\"103\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace pref=\"323\" max=\"32767\" attributes=\"3\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Group type=\"102\" attributes=\"0\">\n                      <EmptySpace min=\"2\" pref=\"2\" max=\"2\" attributes=\"0\"/>\n                      <Component id=\"lblName\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  </Group>\n                  <Component id=\"txtName\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"6\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"2\" attributes=\"0\">\n                  <Component id=\"lblDisplayName\" alignment=\"2\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"comCategory\" alignment=\"2\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"18\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"lblProjectName\" min=\"-2\" pref=\"19\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"txtProjectName\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"6\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"lblPackageName\" min=\"-2\" pref=\"24\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"comPackageName\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"36\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"createdFiles\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFilesValue\" pref=\"20\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"6\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"modifiedFiles\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"modifiedFilesValue\" pref=\"20\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <Component id=\"filler\" min=\"-2\" pref=\"92\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" pref=\"20\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"lblName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"txtName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_Name_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"txtName\">\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblDisplayName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"comCategory\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_DisplayName_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblProjectName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"txtProjectName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_ProjectName_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"txtProjectName\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"JavaCodeGenerator_CreateCodeCustom\" type=\"java.lang.String\" value=\"new JTextField(ProjectUtils.getInformation(this.data.getProject()).getDisplayName());\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblPackageName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"comPackageName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_PackageName_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JComboBox\" name=\"comPackageName\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"0\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"JavaCodeGenerator_CreateCodeCustom\" type=\"java.lang.String\" value=\"UIUtil.createPackageComboBox(this.data.getSourceRootGroup());\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"createdFiles\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"createdFilesValue\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_CreatedFiles_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"modifiedFiles\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"modifiedFilesValue\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_ModifiedFiles_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"filler\">\n    </Component>\n    <Component class=\"javax.swing.JTextArea\" name=\"createdFilesValue\">\n      <Properties>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"rows\" type=\"int\" value=\"5\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"null\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextArea\" name=\"modifiedFilesValue\">\n      <Properties>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"rows\" type=\"int\" value=\"5\"/>\n        <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"modifiedFilesValue\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"null\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JComboBox\" name=\"comCategory\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"7\">\n            <StringItem index=\"0\" value=\"Application\"/>\n            <StringItem index=\"1\" value=\"CoreDump\"/>\n            <StringItem index=\"2\" value=\"DataSource\"/>\n            <StringItem index=\"3\" value=\"HeapDump\"/>\n            <StringItem index=\"4\" value=\"Host\"/>\n            <StringItem index=\"5\" value=\"Snapshot\"/>\n            <StringItem index=\"6\" value=\"ThreadDump\"/>\n          </StringArray>\n        </Property>\n      </Properties>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/subtabs/NameAndLocationPanel.java",
    "content": "\npackage org.graalvm.visualvm.apisupport.subtabs;\n\nimport java.awt.Color;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport javax.swing.JTextField;\nimport javax.swing.UIManager;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.netbeans.api.project.ProjectUtils;\nimport org.netbeans.modules.apisupport.project.CreatedModifiedFiles;\nimport org.netbeans.modules.apisupport.project.NbModuleProject;\nimport org.netbeans.modules.apisupport.project.ui.UIUtil;\nimport org.netbeans.modules.apisupport.project.ui.wizard.BasicWizardIterator;\nimport org.netbeans.modules.apisupport.project.universe.ModuleEntry;\nimport org.netbeans.modules.apisupport.project.universe.NbPlatform;\nimport org.openide.WizardDescriptor;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\nimport org.openide.util.Utilities;\n\n/**\n * The second panel in project template wizard.\n *\n * @author Milos Kleint\n */\nfinal class NameAndLocationPanel extends BasicWizardIterator.Panel {\n    \n    private static final String PROJECT_TEMPLATES_DIR = \"Templates/Project\"; // NOI18N\n    private static final String DEFAULT_CATEGORY_PATH = PROJECT_TEMPLATES_DIR + \"/Other\"; // NOI18N\n    \n    private NewProjectIterator.DataModel data;\n    \n    /** Creates new NameAndLocationPanel */\n    NameAndLocationPanel(WizardDescriptor setting, NewProjectIterator.DataModel data) {\n        super(setting);\n        this.data = data;\n        initComponents();\n        initAccessibility();\n        Color lblBgr = UIManager.getColor(\"Label.background\"); // NOI18N\n        putClientProperty(\"NewFileWizard_Title\", getMessage(\"LBL_ProjectWizardTitle\"));\n        modifiedFilesValue.setBackground(lblBgr);\n        createdFilesValue.setBackground(lblBgr);\n        modifiedFilesValue.setEditable(false);\n        createdFilesValue.setEditable(false);\n        \n        DocumentListener dListener = new UIUtil.DocumentAdapter() {\n            public void insertUpdate(DocumentEvent e) {\n                if (checkValidity()) {\n                    updateData();\n                }\n            }\n        };\n        txtName.getDocument().addDocumentListener(dListener);\n         if (comCategory.getEditor().getEditorComponent() instanceof JTextField) {\n            JTextField txt = (JTextField) comCategory.getEditor().getEditorComponent();\n            txt.getDocument().addDocumentListener(dListener);\n        }\n        if (comPackageName.getEditor().getEditorComponent() instanceof JTextField) {\n            JTextField txt = (JTextField)comPackageName.getEditor().getEditorComponent();\n            txt.getDocument().addDocumentListener(dListener);\n        }\n    }\n    \n    protected void storeToDataModel() {\n        updateData();\n    }\n    \n   \n    \n    private void updateData() {\n        data.setPackageName(comPackageName.getEditor().getItem().toString());\n        data.setName(txtName.getText().trim());\n        data.setCategory(comCategory.getEditor().getItem().toString());\n        NewProjectIterator.generateFileChanges(data);\n        CreatedModifiedFiles fls = data.getCreatedModifiedFiles();\n        createdFilesValue.setText(generateText(fls.getCreatedPaths()));\n        modifiedFilesValue.setText(generateText(fls.getModifiedPaths()));\n        //#68294 check if the paths for newly created files are valid or not..\n        String[] invalid  = data.getCreatedModifiedFiles().getInvalidPaths();\n        if (invalid.length > 0) {\n            setError(NbBundle.getMessage(NameAndLocationPanel.class, \"ERR_ToBeCreateFileExists\", invalid[0]));\n        }\n        \n    }\n    \n    protected void readFromDataModel() {\n        \n        checkValidity();\n    }\n    \n    protected String getPanelName() {\n        return getMessage(\"LBL_NameLocation_Title\");\n    }\n    \n    private boolean checkValidity() {\n//        if (!checkPlatformValidity()) {\n//            return false;\n//        }\n        if (txtName.getText().trim().length() == 0) {\n            setError(getMessage(\"ERR_Name_Prefix_Empty\"));\n            return false;\n        }\n        if (!Utilities.isJavaIdentifier(txtName.getText().trim())) {\n            setError(getMessage(\"ERR_Name_Prefix_Invalid\"));\n            return false;\n        }\n        String packageName = comPackageName.getEditor().getItem().toString().trim();\n        if (packageName.length() == 0 || !UIUtil.isValidPackageName(packageName)) {\n            setError(getMessage(\"ERR_Package_Invalid\"));\n            return false;\n        }\n\n        markValid();\n        return true;\n    }\n    \n//    private boolean checkPlatformValidity() {\n//        NbModuleProject nbprj = data.getProject().getLookup().lookup(NbModuleProject.class);\n//        if (nbprj == null) {\n//            //ignore this check for non default netbeans projects.\n//            return true;\n//        }\n//        NbPlatform platform = nbprj.getPlatform(false);\n//        if (platform == null) {\n//            setError(getMessage(\"ERR_No_Platform\"));\n//            return false;\n//        }\n//        ModuleEntry[] entries = platform.getModules();\n//        Collection<String> modules = new HashSet<String>(Arrays.asList(NewProjectIterator.MODULES));\n//\n//        for (int i = 0; i < entries.length; i++) {\n//            modules.remove(entries[i].getCodeNameBase());\n//        }\n//        if (modules.size() > 0) {\n//            setError(getMessage(\"ERR_Missing_Modules\"));\n//            return false;\n//        }\n//        return true;\n//    }\n    \n  \n    \n    protected HelpCtx getHelp() {\n        return new HelpCtx(NameAndLocationPanel.class);\n    }\n    \n    private static String getMessage(String key) {\n        return NbBundle.getMessage(NameAndLocationPanel.class, key);\n    }\n    \n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        lblName = new javax.swing.JLabel();\n        txtName = new javax.swing.JTextField();\n        lblDisplayName = new javax.swing.JLabel();\n        lblProjectName = new javax.swing.JLabel();\n        txtProjectName = new JTextField(ProjectUtils.getInformation(this.data.getProject()).getDisplayName());\n        lblPackageName = new javax.swing.JLabel();\n        comPackageName = UIUtil.createPackageComboBox(this.data.getSourceRootGroup());\n        createdFiles = new javax.swing.JLabel();\n        modifiedFiles = new javax.swing.JLabel();\n        filler = new javax.swing.JLabel();\n        createdFilesValue = new javax.swing.JTextArea();\n        modifiedFilesValue = new javax.swing.JTextArea();\n        comCategory = new javax.swing.JComboBox();\n\n        lblName.setLabelFor(txtName);\n        org.openide.awt.Mnemonics.setLocalizedText(lblName, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, \"LBL_Name_1\")); // NOI18N\n\n        lblDisplayName.setLabelFor(comCategory);\n        org.openide.awt.Mnemonics.setLocalizedText(lblDisplayName, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, \"LBL_DisplayName_1\")); // NOI18N\n\n        lblProjectName.setLabelFor(txtProjectName);\n        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle(\"org/graalvm/visualvm/apisupport/tabs/Bundle\"); // NOI18N\n        org.openide.awt.Mnemonics.setLocalizedText(lblProjectName, bundle.getString(\"LBL_ProjectName_1\")); // NOI18N\n\n        txtProjectName.setEditable(false);\n\n        lblPackageName.setLabelFor(comPackageName);\n        org.openide.awt.Mnemonics.setLocalizedText(lblPackageName, bundle.getString(\"LBL_PackageName_1\")); // NOI18N\n\n        comPackageName.setEditable(true);\n\n        createdFiles.setLabelFor(createdFilesValue);\n        org.openide.awt.Mnemonics.setLocalizedText(createdFiles, bundle.getString(\"LBL_CreatedFiles_1\")); // NOI18N\n\n        modifiedFiles.setLabelFor(modifiedFilesValue);\n        org.openide.awt.Mnemonics.setLocalizedText(modifiedFiles, bundle.getString(\"LBL_ModifiedFiles_1\")); // NOI18N\n\n        createdFilesValue.setColumns(20);\n        createdFilesValue.setRows(5);\n        createdFilesValue.setBorder(null);\n\n        modifiedFilesValue.setColumns(20);\n        modifiedFilesValue.setRows(5);\n        modifiedFilesValue.setToolTipText(\"modifiedFilesValue\");\n        modifiedFilesValue.setBorder(null);\n\n        comCategory.setEditable(true);\n        comCategory.setModel(new javax.swing.DefaultComboBoxModel(new String[] { \"Application\", \"CoreDump\", \"DataSource\", \"HeapDump\", \"Host\", \"Snapshot\", \"ThreadDump\" }));\n\n        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n            .add(layout.createSequentialGroup()\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)\n                    .add(layout.createSequentialGroup()\n                        .add(lblName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 64, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 54, Short.MAX_VALUE))\n                    .add(lblProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 118, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(lblPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 118, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(createdFiles, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 118, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(modifiedFiles, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 118, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(12, 12, 12)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(txtName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)\n                    .add(comCategory, 0, 296, Short.MAX_VALUE)\n                    .add(txtProjectName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)\n                    .add(comPackageName, 0, 296, Short.MAX_VALUE)\n                    .add(createdFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)\n                    .add(modifiedFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)))\n            .add(filler, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 400, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n            .add(layout.createSequentialGroup()\n                .add(lblDisplayName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 103, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                .addContainerGap(323, Short.MAX_VALUE))\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n            .add(layout.createSequentialGroup()\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(layout.createSequentialGroup()\n                        .add(2, 2, 2)\n                        .add(lblName))\n                    .add(txtName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(6, 6, 6)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.CENTER)\n                    .add(lblDisplayName)\n                    .add(comCategory, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(18, 18, 18)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(lblProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 19, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(txtProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(6, 6, 6)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(lblPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 24, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(comPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(36, 36, 36)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(createdFiles)\n                    .add(createdFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 20, Short.MAX_VALUE))\n                .add(6, 6, 6)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(modifiedFiles)\n                    .add(modifiedFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 20, Short.MAX_VALUE))\n                .add(filler, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 92, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                .add(20, 20, 20))\n        );\n    }// </editor-fold>//GEN-END:initComponents\n    \n    private void initAccessibility() {\n        this.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_NameAndLocationPanel\"));\n        comPackageName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_PackageName\"));\n        comCategory.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_DisplayName\"));\n        txtName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_Name\"));\n        txtProjectName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_ProjectName\"));\n        createdFilesValue.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_CreatedFilesValue\"));\n        modifiedFilesValue.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_ModifiedFilesValue\"));\n    }\n    \n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JComboBox comCategory;\n    private javax.swing.JComboBox comPackageName;\n    private javax.swing.JLabel createdFiles;\n    private javax.swing.JTextArea createdFilesValue;\n    private javax.swing.JLabel filler;\n    private javax.swing.JLabel lblDisplayName;\n    private javax.swing.JLabel lblName;\n    private javax.swing.JLabel lblPackageName;\n    private javax.swing.JLabel lblProjectName;\n    private javax.swing.JLabel modifiedFiles;\n    private javax.swing.JTextArea modifiedFilesValue;\n    private javax.swing.JTextField txtName;\n    private javax.swing.JTextField txtProjectName;\n    // End of variables declaration//GEN-END:variables\n    \n    private static String generateText(String[] relPaths) {\n        StringBuffer sb = new StringBuffer();\n        if (relPaths.length > 0) {\n            for (int i = 0; i < relPaths.length; i++) {\n                if (i > 0) {\n                    sb.append('\\n');\n                }\n                sb.append(relPaths[i]);\n            }\n        }\n        return sb.toString();\n    }\n    \n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/subtabs/NewProjectIterator.java",
    "content": "package org.graalvm.visualvm.apisupport.subtabs;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Set;\nimport org.netbeans.api.project.Project;\nimport org.netbeans.modules.apisupport.project.CreatedModifiedFiles;\nimport org.netbeans.modules.apisupport.project.spi.NbModuleProvider;\nimport org.netbeans.modules.apisupport.project.ui.wizard.BasicWizardIterator;\nimport org.openide.WizardDescriptor;\nimport org.openide.filesystems.FileObject;\n\nfinal class NewProjectIterator extends BasicWizardIterator {\n\n    private NewProjectIterator.DataModel data;\n    public static final String[] MODULES = {\n        \"org.openide.util\", // NOI18N\n        \"org.graalvm.visualvm.core\", // NOI18N\n        \"org.graalvm.visualvm.application\", // NOI18N\n        \"org.graalvm.visualvm.coredump\", // NOI18N\n        \"org.graalvm.visualvm.heapdump\", // NOI18N\n        \"org.graalvm.visualvm.threaddump\", // NOI18N\n        \"org.graalvm.visualvm.host\" // NOI18N\n    };\n\n    private NewProjectIterator() { /* Use factory method. */ }\n    ;\n\n    public static NewProjectIterator createIterator() {\n        return new NewProjectIterator();\n    }\n\n    public Set instantiate() throws IOException {\n        CreatedModifiedFiles cmf = data.getCreatedModifiedFiles();\n        cmf.run();\n        return getCreatedFiles(cmf, data.getProject());\n    }\n\n    protected BasicWizardIterator.Panel[] createPanels(WizardDescriptor wiz) {\n        data = new NewProjectIterator.DataModel(wiz);\n        return new BasicWizardIterator.Panel[]{\n                    new NameAndLocationPanel(wiz, data)\n                };\n    }\n\n    public \n    @Override\n    void uninitialize( WizardDescriptor wiz) {\n        super.uninitialize(wiz);\n        data = null;\n    }\n\n    static final class DataModel extends BasicWizardIterator.BasicDataModel {\n\n        private Project template;\n        private String name;\n        private String displayName;\n        private String category;\n        private CreatedModifiedFiles files;\n\n        DataModel(WizardDescriptor wiz) {\n            super(wiz);\n        }\n\n        public CreatedModifiedFiles getCreatedModifiedFiles() {\n            return getFiles();\n        }\n\n        public void setCreatedModifiedFiles(CreatedModifiedFiles files) {\n            this.setFiles(files);\n        }\n\n        public Project getTemplate() {\n            return template;\n        }\n\n        public void setTemplate(Project template) {\n            this.template = template;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public String getDisplayName() {\n            return displayName;\n        }\n\n        public void setDisplayName(String displayName) {\n            this.displayName = displayName;\n        }\n\n        public String getCategory() {\n            return category;\n        }\n\n        public void setCategory(String category) {\n            this.category = category;\n        }\n\n        public CreatedModifiedFiles getFiles() {\n            return files;\n        }\n\n        public void setFiles(CreatedModifiedFiles files) {\n            this.files = files;\n        }\n    }\n\n    public static void generateFileChanges(DataModel model) {\n        CreatedModifiedFiles fileChanges = new CreatedModifiedFiles(model.getProject());\n        NbModuleProvider moduleInfo = model.getModuleInfo();\n        final String category = model.getCategory();\n        final String name = model.getName();\n        final String packageName = model.getPackageName();\n\n        HashMap<String, String> replaceTokens = new HashMap<String, String>();\n        replaceTokens.put(\"DISPLAYNAME\", category);//NOI18N\n\n        replaceTokens.put(\"TEMPLATENAME\", name);//NOI18N\n\n        replaceTokens.put(\"PACKAGENAME\", packageName);//NOI18N\n\n        // Update project dependencies\n        for (int i = 0; i < MODULES.length; i++) {\n            fileChanges.add(fileChanges.addModuleDependency(MODULES[i]));\n        }\n\n//        // Generate Support class:\n//        String iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n//                name, \"ViewSupport.java\"); //NOI18N\n//\n//        FileObject template = CreatedModifiedFiles.getTemplate(\"templateViewSupport.java\");//NOI18N\n//\n//        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n//\n        // Generate view provider class:\n        String iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n                name, \"ViewPluginProvider.java\"); //NOI18N\n\n        FileObject template = CreatedModifiedFiles.getTemplate(\"templateViewPluginProvider.java\");//NOI18N\n\n        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n\n        // Generate view class:\n        iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n                name, \"ViewPlugin.java\"); //NOI18N\n\n        template = CreatedModifiedFiles.getTemplate(\"templateViewPlugin.java\");//NOI18N\n\n        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n\n        model.setCreatedModifiedFiles(fileChanges);\n    }\n\n    private static String getRelativePath(String rootPath, String fullyQualifiedPackageName,\n            String prefix, String postfix) {\n        StringBuffer sb = new StringBuffer();\n        sb.append(rootPath).append('/').\n                append(fullyQualifiedPackageName.replace('.', '/')).\n                append('/').append(prefix).append(postfix);\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/subtabs/templateVisualVMViewPlugin.javx",
    "content": "<#assign licenseFirst = \"/*\">\n<#assign licensePrefix = \" * \">\n<#assign licenseLast = \" */\">\n<#include \"../Licenses/license-${project.license}.txt\">\n\npackage ${PACKAGENAME};\n\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent.DetailsView;\nimport javax.swing.JLabel;\n\npublic class ${TEMPLATENAME}ViewPlugin extends DataSourceViewPlugin {\n    public ${TEMPLATENAME}ViewPlugin(${DISPLAYNAME} My${DISPLAYNAME}) {\n        super(My${DISPLAYNAME});\n    }\n\n    @Override\n    public DetailsView createView(int position) {\n        /* TODO Check the position (DataViewComponent.TOP_LEFT, DataViewComponent.TOP_RIGHT, DataViewComponent.BOTTOM_LEFT, DataViewComponent.BOTTOM_RIGHT)\n           before creating a new view. If the position is not applicable, return null\n        */\n        return new DetailsView(\"${TEMPLATENAME}\", \"${TEMPLATENAME} desc\", DataSourceView.POSITION_AT_THE_END, new JLabel(\"${TEMPLATENAME}\"), null);\n    }    \n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/subtabs/templateVisualVMViewPluginProvider.javx",
    "content": "<#assign licenseFirst = \"/*\">\n<#assign licensePrefix = \" * \">\n<#assign licenseLast = \" */\">\n<#include \"../Licenses/license-${project.license}.txt\">\n\npackage ${PACKAGENAME};\n\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider;\n\npublic class ${TEMPLATENAME}ViewPluginProvider extends DataSourceViewPluginProvider<${DISPLAYNAME}> {\n    private static class Singleton {\n        final private static ${TEMPLATENAME}ViewPluginProvider INSTANCE = new ${TEMPLATENAME}ViewPluginProvider();\n    }\n\n    private ${TEMPLATENAME}ViewPluginProvider() {}\n\n    // TODO adjust the view visibility\n    @Override\n    protected boolean supportsPluginFor(${DISPLAYNAME} my${DISPLAYNAME}) {\n        // Always shown\n        return true;\n    }\n\n    @Override\n    protected DataSourceViewPlugin createPlugin(${DISPLAYNAME} my${DISPLAYNAME}) {\n        return new ${TEMPLATENAME}ViewPlugin(my${DISPLAYNAME});\n    }\n    \n    public static ${TEMPLATENAME}ViewPluginProvider getInstance() {\n        return Singleton.INSTANCE;\n    }\n\n    /**\n     * TODO Call this method from the module Installer#restored()\n     **/\n    public static void install() {\n        // TODO register with the appropriate org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider\n    }\n    \n    /**\n     * TODO Call this method from the module Installer#uninstalled()\n     **/\n    public static void uninstall() {\n        // TODO unregister from the appropriate org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider\n    }\n}\n\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/subtabs/visualVMSubTab.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n        Creates a skeleton VisualVM datasource subtab.\n    </body>\n</html>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/tabs/Bundle.properties",
    "content": "# Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nTemplates/VisualVMPluginDevelopment/tab=View (Tab)\n\nLBL_ProjectWizardTitle=VisualVM View (Tab)\n\nLBL_ProjectSelection_Title=Select Project\n\nLBL_NameLocation_Title=Name and Location\nLBL_ProjectName=&Project\\:\nLBL_PackageName=Pac&kage\\:\nLBL_CreatedFiles=&Created Files\\:\nLBL_ModifiedFiles=&Modified Files\\:\n\nACS_SelectProjectPanel=Select Project panel\nACS_CTL_btnProject=Browse Project button\nACS_CTL_comProject=Select from opened projects combobox\n\nLBL_Name=&Template Name \\:\nLBL_DisplayName=D&isplay Name \\:\nLBL_Category=C&ategory\nLBL_Project_Label=&Project \\:\nLBL_Browse=Bro&wse...\nACS_NameAndLocationPanel=Name and Location Panel\nACS_CTL_PackageName=Package Name\nACS_CTL_Category=Category\nACS_CTL_DisplayName=Display Name\nACS_CTL_Name=Template Name\nACS_CTL_ProjectName=Project Name\nACS_CTL_CreatedFilesValue=Created Files\nACS_CTL_ModifiedFilesValue=Modified Files\n\nMSG_No_Projects=No Projects opened\nMSG_NoExternalRoots=Projects with external roots are not supported.\nMSG_NoProjectSelected=A project needs to be selected.\n\nERR_Category_Invalid=Category is malformed.\nERR_Name_Prefix_Empty=Template Name is empty.\nERR_Name_Prefix_Invalid=Template Name is invalid, not a Java identifier.\nERR_Package_Invalid=Package is blank or malformed.\nERR_ToBeCreateFileExists=The file {0} already exists.\nERR_Missing_Modules=The NetBeans platform is missing required modules.\nERR_No_Platform=No NetBeans Platform defined.\nLBL_Name_1=Name:\nLBL_DisplayName_1=Data Source:\nLBL_ProjectName_1=Project Name:\nLBL_PackageName_1=Package Name:\nLBL_CreatedFiles_1=Created Files:\nLBL_ModifiedFiles_1=Modified Files:\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/tabs/NameAndLocationPanel.form",
    "content": "<?xml version=\"1.1\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.2\" maxVersion=\"1.2\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"2\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <Group type=\"103\" groupAlignment=\"0\" max=\"-2\" attributes=\"0\">\n                  <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n                      <Component id=\"lblName\" min=\"-2\" pref=\"64\" max=\"-2\" attributes=\"0\"/>\n                      <EmptySpace pref=\"54\" max=\"32767\" attributes=\"3\"/>\n                  </Group>\n                  <Component id=\"lblProjectName\" min=\"-2\" pref=\"118\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lblPackageName\" min=\"-2\" pref=\"118\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFiles\" min=\"-2\" pref=\"118\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"modifiedFiles\" min=\"-2\" pref=\"118\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"12\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"txtName\" alignment=\"0\" pref=\"296\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"comCategory\" alignment=\"0\" pref=\"296\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"txtProjectName\" alignment=\"0\" pref=\"296\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"comPackageName\" alignment=\"0\" pref=\"296\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"createdFilesValue\" alignment=\"0\" pref=\"296\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"modifiedFilesValue\" alignment=\"0\" pref=\"296\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n          </Group>\n          <Component id=\"filler\" min=\"-2\" pref=\"400\" max=\"-2\" attributes=\"0\"/>\n          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n              <Component id=\"lblDisplayName\" min=\"-2\" pref=\"103\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace pref=\"323\" max=\"32767\" attributes=\"3\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" attributes=\"0\">\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Group type=\"102\" attributes=\"0\">\n                      <EmptySpace min=\"2\" pref=\"2\" max=\"2\" attributes=\"0\"/>\n                      <Component id=\"lblName\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  </Group>\n                  <Component id=\"txtName\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"6\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"2\" attributes=\"0\">\n                  <Component id=\"lblDisplayName\" alignment=\"2\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"comCategory\" alignment=\"2\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"18\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"lblProjectName\" min=\"-2\" pref=\"19\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"txtProjectName\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"6\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"lblPackageName\" min=\"-2\" pref=\"24\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"comPackageName\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"36\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"createdFiles\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"createdFilesValue\" pref=\"20\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <EmptySpace min=\"-2\" pref=\"6\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n                  <Component id=\"modifiedFiles\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"modifiedFilesValue\" pref=\"20\" max=\"32767\" attributes=\"0\"/>\n              </Group>\n              <Component id=\"filler\" min=\"-2\" pref=\"92\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" pref=\"20\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"lblName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"txtName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_Name_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"txtName\">\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblDisplayName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"comCategory\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_DisplayName_1\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblProjectName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"txtProjectName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_ProjectName_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextField\" name=\"txtProjectName\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"JavaCodeGenerator_CreateCodeCustom\" type=\"java.lang.String\" value=\"new JTextField(ProjectUtils.getInformation(this.data.getProject()).getDisplayName());\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"lblPackageName\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"comPackageName\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_PackageName_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JComboBox\" name=\"comPackageName\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"0\"/>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"JavaCodeGenerator_CreateCodeCustom\" type=\"java.lang.String\" value=\"UIUtil.createPackageComboBox(this.data.getSourceRootGroup());\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"createdFiles\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"createdFilesValue\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_CreatedFiles_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"modifiedFiles\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"modifiedFilesValue\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/apisupport/tabs/Bundle.properties\" key=\"LBL_ModifiedFiles_1\" replaceFormat=\"java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JLabel\" name=\"filler\">\n    </Component>\n    <Component class=\"javax.swing.JTextArea\" name=\"createdFilesValue\">\n      <Properties>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"rows\" type=\"int\" value=\"5\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"null\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JTextArea\" name=\"modifiedFilesValue\">\n      <Properties>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"rows\" type=\"int\" value=\"5\"/>\n        <Property name=\"toolTipText\" type=\"java.lang.String\" value=\"modifiedFilesValue\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"null\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Component class=\"javax.swing.JComboBox\" name=\"comCategory\">\n      <Properties>\n        <Property name=\"editable\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"model\" type=\"javax.swing.ComboBoxModel\" editor=\"org.netbeans.modules.form.editors2.ComboBoxModelEditor\">\n          <StringArray count=\"7\">\n            <StringItem index=\"0\" value=\"Application\"/>\n            <StringItem index=\"1\" value=\"CoreDump\"/>\n            <StringItem index=\"2\" value=\"DataSource\"/>\n            <StringItem index=\"3\" value=\"HeapDump\"/>\n            <StringItem index=\"4\" value=\"Host\"/>\n            <StringItem index=\"5\" value=\"Snapshot\"/>\n            <StringItem index=\"6\" value=\"ThreadDump\"/>\n          </StringArray>\n        </Property>\n      </Properties>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/tabs/NameAndLocationPanel.java",
    "content": "\npackage org.graalvm.visualvm.apisupport.tabs;\n\nimport java.awt.Color;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport javax.swing.JTextField;\nimport javax.swing.UIManager;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.netbeans.api.project.ProjectUtils;\nimport org.netbeans.modules.apisupport.project.CreatedModifiedFiles;\nimport org.netbeans.modules.apisupport.project.NbModuleProject;\nimport org.netbeans.modules.apisupport.project.ui.UIUtil;\nimport org.netbeans.modules.apisupport.project.ui.wizard.BasicWizardIterator;\nimport org.netbeans.modules.apisupport.project.universe.ModuleEntry;\nimport org.netbeans.modules.apisupport.project.universe.NbPlatform;\nimport org.openide.WizardDescriptor;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\nimport org.openide.util.Utilities;\n\n/**\n * The second panel in project template wizard.\n *\n * @author Milos Kleint\n */\nfinal class NameAndLocationPanel extends BasicWizardIterator.Panel {\n    \n    private static final String PROJECT_TEMPLATES_DIR = \"Templates/Project\"; // NOI18N\n    private static final String DEFAULT_CATEGORY_PATH = PROJECT_TEMPLATES_DIR + \"/Other\"; // NOI18N\n    \n    private NewProjectIterator.DataModel data;\n    \n    /** Creates new NameAndLocationPanel */\n    NameAndLocationPanel(WizardDescriptor setting, NewProjectIterator.DataModel data) {\n        super(setting);\n        this.data = data;\n        initComponents();\n        initAccessibility();\n        Color lblBgr = UIManager.getColor(\"Label.background\"); // NOI18N\n        putClientProperty(\"NewFileWizard_Title\", getMessage(\"LBL_ProjectWizardTitle\"));\n        modifiedFilesValue.setBackground(lblBgr);\n        createdFilesValue.setBackground(lblBgr);\n        modifiedFilesValue.setEditable(false);\n        createdFilesValue.setEditable(false);\n        \n        DocumentListener dListener = new UIUtil.DocumentAdapter() {\n            public void insertUpdate(DocumentEvent e) {\n                if (checkValidity()) {\n                    updateData();\n                }\n            }\n        };\n        txtName.getDocument().addDocumentListener(dListener);\n         if (comCategory.getEditor().getEditorComponent() instanceof JTextField) {\n            JTextField txt = (JTextField) comCategory.getEditor().getEditorComponent();\n            txt.getDocument().addDocumentListener(dListener);\n        }\n        if (comPackageName.getEditor().getEditorComponent() instanceof JTextField) {\n            JTextField txt = (JTextField)comPackageName.getEditor().getEditorComponent();\n            txt.getDocument().addDocumentListener(dListener);\n        }\n    }\n    \n    protected void storeToDataModel() {\n        updateData();\n    }\n    \n   \n    \n    private void updateData() {\n        data.setPackageName(comPackageName.getEditor().getItem().toString());\n        data.setName(txtName.getText().trim());\n        data.setCategory(comCategory.getEditor().getItem().toString());\n        NewProjectIterator.generateFileChanges(data);\n        CreatedModifiedFiles fls = data.getCreatedModifiedFiles();\n        createdFilesValue.setText(generateText(fls.getCreatedPaths()));\n        modifiedFilesValue.setText(generateText(fls.getModifiedPaths()));\n        //#68294 check if the paths for newly created files are valid or not..\n        String[] invalid  = data.getCreatedModifiedFiles().getInvalidPaths();\n        if (invalid.length > 0) {\n            setError(NbBundle.getMessage(NameAndLocationPanel.class, \"ERR_ToBeCreateFileExists\", invalid[0]));\n        }\n        \n    }\n    \n    protected void readFromDataModel() {\n        \n        checkValidity();\n    }\n    \n    protected String getPanelName() {\n        return getMessage(\"LBL_NameLocation_Title\");\n    }\n    \n    private boolean checkValidity() {\n//        if (!checkPlatformValidity()) {\n//            return false;\n//        }\n        if (txtName.getText().trim().length() == 0) {\n            setError(getMessage(\"ERR_Name_Prefix_Empty\"));\n            return false;\n        }\n        if (!Utilities.isJavaIdentifier(txtName.getText().trim())) {\n            setError(getMessage(\"ERR_Name_Prefix_Invalid\"));\n            return false;\n        }\n        String packageName = comPackageName.getEditor().getItem().toString().trim();\n        if (packageName.length() == 0 || !UIUtil.isValidPackageName(packageName)) {\n            setError(getMessage(\"ERR_Package_Invalid\"));\n            return false;\n        }\n\n        markValid();\n        return true;\n    }\n    \n//    private boolean checkPlatformValidity() {\n//        NbModuleProject nbprj = data.getProject().getLookup().lookup(NbModuleProject.class);\n//        if (nbprj == null) {\n//            //ignore this check for non default netbeans projects.\n//            return true;\n//        }\n//        NbPlatform platform = nbprj.getPlatform(false);\n//        if (platform == null) {\n//            setError(getMessage(\"ERR_No_Platform\"));\n//            return false;\n//        }\n//        ModuleEntry[] entries = platform.getModules();\n//        Collection<String> modules = new HashSet<String>(Arrays.asList(NewProjectIterator.MODULES));\n//\n//        for (int i = 0; i < entries.length; i++) {\n//            modules.remove(entries[i].getCodeNameBase());\n//        }\n//        if (modules.size() > 0) {\n//            setError(getMessage(\"ERR_Missing_Modules\"));\n//            return false;\n//        }\n//        return true;\n//    }\n    \n  \n    \n    protected HelpCtx getHelp() {\n        return new HelpCtx(NameAndLocationPanel.class);\n    }\n    \n    private static String getMessage(String key) {\n        return NbBundle.getMessage(NameAndLocationPanel.class, key);\n    }\n    \n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        lblName = new javax.swing.JLabel();\n        txtName = new javax.swing.JTextField();\n        lblDisplayName = new javax.swing.JLabel();\n        lblProjectName = new javax.swing.JLabel();\n        txtProjectName = new JTextField(ProjectUtils.getInformation(this.data.getProject()).getDisplayName());\n        lblPackageName = new javax.swing.JLabel();\n        comPackageName = UIUtil.createPackageComboBox(this.data.getSourceRootGroup());\n        createdFiles = new javax.swing.JLabel();\n        modifiedFiles = new javax.swing.JLabel();\n        filler = new javax.swing.JLabel();\n        createdFilesValue = new javax.swing.JTextArea();\n        modifiedFilesValue = new javax.swing.JTextArea();\n        comCategory = new javax.swing.JComboBox();\n\n        lblName.setLabelFor(txtName);\n        org.openide.awt.Mnemonics.setLocalizedText(lblName, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, \"LBL_Name_1\")); // NOI18N\n\n        lblDisplayName.setLabelFor(comCategory);\n        org.openide.awt.Mnemonics.setLocalizedText(lblDisplayName, org.openide.util.NbBundle.getMessage(NameAndLocationPanel.class, \"LBL_DisplayName_1\")); // NOI18N\n\n        lblProjectName.setLabelFor(txtProjectName);\n        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle(\"org/graalvm/visualvm/apisupport/tabs/Bundle\"); // NOI18N\n        org.openide.awt.Mnemonics.setLocalizedText(lblProjectName, bundle.getString(\"LBL_ProjectName_1\")); // NOI18N\n\n        txtProjectName.setEditable(false);\n\n        lblPackageName.setLabelFor(comPackageName);\n        org.openide.awt.Mnemonics.setLocalizedText(lblPackageName, bundle.getString(\"LBL_PackageName_1\")); // NOI18N\n\n        comPackageName.setEditable(true);\n\n        createdFiles.setLabelFor(createdFilesValue);\n        org.openide.awt.Mnemonics.setLocalizedText(createdFiles, bundle.getString(\"LBL_CreatedFiles_1\")); // NOI18N\n\n        modifiedFiles.setLabelFor(modifiedFilesValue);\n        org.openide.awt.Mnemonics.setLocalizedText(modifiedFiles, bundle.getString(\"LBL_ModifiedFiles_1\")); // NOI18N\n\n        createdFilesValue.setColumns(20);\n        createdFilesValue.setRows(5);\n        createdFilesValue.setBorder(null);\n\n        modifiedFilesValue.setColumns(20);\n        modifiedFilesValue.setRows(5);\n        modifiedFilesValue.setToolTipText(\"modifiedFilesValue\");\n        modifiedFilesValue.setBorder(null);\n\n        comCategory.setEditable(true);\n        comCategory.setModel(new javax.swing.DefaultComboBoxModel(new String[] { \"Application\", \"CoreDump\", \"DataSource\", \"HeapDump\", \"Host\", \"Snapshot\", \"ThreadDump\" }));\n\n        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n            .add(layout.createSequentialGroup()\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)\n                    .add(layout.createSequentialGroup()\n                        .add(lblName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 64, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 54, Short.MAX_VALUE))\n                    .add(lblProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 118, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(lblPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 118, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(createdFiles, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 118, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(modifiedFiles, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 118, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(12, 12, 12)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(txtName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)\n                    .add(comCategory, 0, 296, Short.MAX_VALUE)\n                    .add(txtProjectName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)\n                    .add(comPackageName, 0, 296, Short.MAX_VALUE)\n                    .add(createdFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)\n                    .add(modifiedFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)))\n            .add(filler, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 400, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n            .add(layout.createSequentialGroup()\n                .add(lblDisplayName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 103, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                .addContainerGap(323, Short.MAX_VALUE))\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n            .add(layout.createSequentialGroup()\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(layout.createSequentialGroup()\n                        .add(2, 2, 2)\n                        .add(lblName))\n                    .add(txtName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(6, 6, 6)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.CENTER)\n                    .add(lblDisplayName)\n                    .add(comCategory, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(18, 18, 18)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(lblProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 19, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(txtProjectName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(6, 6, 6)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(lblPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 24, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                    .add(comPackageName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))\n                .add(36, 36, 36)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(createdFiles)\n                    .add(createdFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 20, Short.MAX_VALUE))\n                .add(6, 6, 6)\n                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)\n                    .add(modifiedFiles)\n                    .add(modifiedFilesValue, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 20, Short.MAX_VALUE))\n                .add(filler, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 92, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)\n                .add(20, 20, 20))\n        );\n    }// </editor-fold>//GEN-END:initComponents\n    \n    private void initAccessibility() {\n        this.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_NameAndLocationPanel\"));\n        comPackageName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_PackageName\"));\n        comCategory.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_DisplayName\"));\n        txtName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_Name\"));\n        txtProjectName.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_ProjectName\"));\n        createdFilesValue.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_CreatedFilesValue\"));\n        modifiedFilesValue.getAccessibleContext().setAccessibleDescription(getMessage(\"ACS_CTL_ModifiedFilesValue\"));\n    }\n    \n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JComboBox comCategory;\n    private javax.swing.JComboBox comPackageName;\n    private javax.swing.JLabel createdFiles;\n    private javax.swing.JTextArea createdFilesValue;\n    private javax.swing.JLabel filler;\n    private javax.swing.JLabel lblDisplayName;\n    private javax.swing.JLabel lblName;\n    private javax.swing.JLabel lblPackageName;\n    private javax.swing.JLabel lblProjectName;\n    private javax.swing.JLabel modifiedFiles;\n    private javax.swing.JTextArea modifiedFilesValue;\n    private javax.swing.JTextField txtName;\n    private javax.swing.JTextField txtProjectName;\n    // End of variables declaration//GEN-END:variables\n    \n    private static String generateText(String[] relPaths) {\n        StringBuffer sb = new StringBuffer();\n        if (relPaths.length > 0) {\n            for (int i = 0; i < relPaths.length; i++) {\n                if (i > 0) {\n                    sb.append('\\n');\n                }\n                sb.append(relPaths[i]);\n            }\n        }\n        return sb.toString();\n    }\n    \n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/tabs/NewProjectIterator.java",
    "content": "package org.graalvm.visualvm.apisupport.tabs;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Set;\nimport org.netbeans.api.project.Project;\nimport org.netbeans.modules.apisupport.project.CreatedModifiedFiles;\nimport org.netbeans.modules.apisupport.project.spi.NbModuleProvider;\nimport org.netbeans.modules.apisupport.project.ui.wizard.BasicWizardIterator;\nimport org.openide.WizardDescriptor;\nimport org.openide.filesystems.FileObject;\n\nfinal class NewProjectIterator extends BasicWizardIterator {\n\n    private NewProjectIterator.DataModel data;\n    public static final String[] MODULES = {\n        \"org.openide.util\", // NOI18N\n        \"org.graalvm.visualvm.core\", // NOI18N\n        \"org.graalvm.visualvm.application\", // NOI18N\n        \"org.graalvm.visualvm.coredump\", // NOI18N\n        \"org.graalvm.visualvm.heapdump\", // NOI18N\n        \"org.graalvm.visualvm.threaddump\", // NOI18N\n        \"org.graalvm.visualvm.host\" // NOI18N\n    };\n\n    private NewProjectIterator() { /* Use factory method. */ }\n    ;\n\n    public static NewProjectIterator createIterator() {\n        return new NewProjectIterator();\n    }\n\n    public Set instantiate() throws IOException {\n        CreatedModifiedFiles cmf = data.getCreatedModifiedFiles();\n        cmf.run();\n        return getCreatedFiles(cmf, data.getProject());\n    }\n\n    protected BasicWizardIterator.Panel[] createPanels(WizardDescriptor wiz) {\n        data = new NewProjectIterator.DataModel(wiz);\n        return new BasicWizardIterator.Panel[]{\n                    new NameAndLocationPanel(wiz, data)\n                };\n    }\n\n    public \n    @Override\n    void uninitialize( WizardDescriptor wiz) {\n        super.uninitialize(wiz);\n        data = null;\n    }\n\n    static final class DataModel extends BasicWizardIterator.BasicDataModel {\n\n        private Project template;\n        private String name;\n        private String displayName;\n        private String category;\n        private CreatedModifiedFiles files;\n\n        DataModel(WizardDescriptor wiz) {\n            super(wiz);\n        }\n\n        public CreatedModifiedFiles getCreatedModifiedFiles() {\n            return getFiles();\n        }\n\n        public void setCreatedModifiedFiles(CreatedModifiedFiles files) {\n            this.setFiles(files);\n        }\n\n        public Project getTemplate() {\n            return template;\n        }\n\n        public void setTemplate(Project template) {\n            this.template = template;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public String getDisplayName() {\n            return displayName;\n        }\n\n        public void setDisplayName(String displayName) {\n            this.displayName = displayName;\n        }\n\n        public String getCategory() {\n            return category;\n        }\n\n        public void setCategory(String category) {\n            this.category = category;\n        }\n\n        public CreatedModifiedFiles getFiles() {\n            return files;\n        }\n\n        public void setFiles(CreatedModifiedFiles files) {\n            this.files = files;\n        }\n    }\n\n    public static void generateFileChanges(DataModel model) {\n        CreatedModifiedFiles fileChanges = new CreatedModifiedFiles(model.getProject());\n        NbModuleProvider moduleInfo = model.getModuleInfo();\n        final String category = model.getCategory();\n        final String name = model.getName();\n        final String packageName = model.getPackageName();\n\n        HashMap<String, String> replaceTokens = new HashMap<String, String>();\n        replaceTokens.put(\"DISPLAYNAME\", category);//NOI18N\n\n        replaceTokens.put(\"TEMPLATENAME\", name);//NOI18N\n\n        replaceTokens.put(\"PACKAGENAME\", packageName);//NOI18N\n\n        // Update project dependencies\n        for (int i = 0; i < MODULES.length; i++) {\n            fileChanges.add(fileChanges.addModuleDependency(MODULES[i]));\n        }\n\n//        // Generate Support class:\n//        String iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n//                name, \"ViewSupport.java\"); //NOI18N\n//\n//        FileObject template = CreatedModifiedFiles.getTemplate(\"templateViewSupport.java\");//NOI18N\n//\n//        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n//\n        // Generate view provider class:\n        String iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n                name, \"ViewProvider.java\"); //NOI18N\n\n        FileObject template = CreatedModifiedFiles.getTemplate(\"templateViewProvider.java\");//NOI18N\n\n        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n\n        // Generate view class:\n        iteratorName = getRelativePath(moduleInfo.getSourceDirectoryPath(), packageName,\n                name, \"View.java\"); //NOI18N\n\n        template = CreatedModifiedFiles.getTemplate(\"templateView.java\");//NOI18N\n\n        fileChanges.add(fileChanges.createFileWithSubstitutions(iteratorName, template, replaceTokens));\n\n        model.setCreatedModifiedFiles(fileChanges);\n    }\n\n    private static String getRelativePath(String rootPath, String fullyQualifiedPackageName,\n            String prefix, String postfix) {\n        StringBuffer sb = new StringBuffer();\n        sb.append(rootPath).append('/').\n                append(fullyQualifiedPackageName.replace('.', '/')).\n                append('/').append(prefix).append(postfix);\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/tabs/templateVisualVMView.javx",
    "content": "<#assign licenseFirst = \"/*\">\n<#assign licensePrefix = \" * \">\n<#assign licenseLast = \" */\">\n<#include \"../Licenses/license-${project.license}.txt\">\n\npackage ${PACKAGENAME};\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.heapdump.HeapDump;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.threaddump.ThreadDump;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport javax.swing.JEditorPane;\nimport javax.swing.JPanel;\nimport org.openide.util.ImageUtilities;\n\npublic class ${TEMPLATENAME}View extends DataSourceView {\n\n    private DataViewComponent dvc;\n    // TODO update the icon path\n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/coredump/resources/coredump.png\"; // NOI18N\n\n    public ${TEMPLATENAME}View(${DISPLAYNAME} My${DISPLAYNAME}) {\n        super(My${DISPLAYNAME}, \"${TEMPLATENAME}\", new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 60, false);\n    }\n\n    @Override\n    protected DataViewComponent createComponent() {\n\n        //Data area for master view:\n        JEditorPane generalDataArea = new JEditorPane();\n        generalDataArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n        //Panel, which we'll reuse in all four of our detail views for this sample:\n        JPanel panel = new JPanel();\n\n        //Master view:\n        DataViewComponent.MasterView masterView = new DataViewComponent.MasterView\n                (\"${TEMPLATENAME} Overview\", null, generalDataArea);\n\n        //Configuration of master view:\n        DataViewComponent.MasterViewConfiguration masterConfiguration = \n                new DataViewComponent.MasterViewConfiguration(false);\n\n        //Add the master view and configuration view to the component:\n        dvc = new DataViewComponent(masterView, masterConfiguration);\n\n        // TODO adjust the details view properties\n        //Add detail views to the component:\n        dvc.addDetailsView(new DataViewComponent.DetailsView(\n                \"${TEMPLATENAME} Details\", null, 10, panel, null), DataViewComponent.TOP_LEFT);\n\n        return dvc;\n\n    }\n    \n}\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/tabs/templateVisualVMViewProvider.javx",
    "content": "<#assign licenseFirst = \"/*\">\n<#assign licensePrefix = \" * \">\n<#assign licenseLast = \" */\">\n<#include \"../Licenses/license-${project.license}.txt\">\n\npackage ${PACKAGENAME};\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.heapdump.HeapDump;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.threaddump.ThreadDump;\nimport java.util.Set;\n\npublic class ${TEMPLATENAME}ViewProvider extends PluggableDataSourceViewProvider<${DISPLAYNAME}> {\n    private static class Singleton {\n        final private static ${TEMPLATENAME}ViewProvider INSTANCE = new ${TEMPLATENAME}ViewProvider();\n    }\n\n    private ${TEMPLATENAME}ViewProvider() {}\n\n    // TODO adjust the view visibility\n    @Override\n    public boolean supportsViewFor(${DISPLAYNAME} my${DISPLAYNAME}) {\n        //Always shown:\n        return true;\n    }\n\n    @Override\n    public synchronized DataSourceView createView(final ${DISPLAYNAME} my${DISPLAYNAME}) {\n        return new ${TEMPLATENAME}View(my${DISPLAYNAME}) ;\n    }\n    \n    public static ${TEMPLATENAME}ViewProvider getInstance() {\n        return Singleton.INSTANCE;\n    }\n\n    /**\n     * TODO Call this method from the module Installer#restored()\n     **/\n    public static void install() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(Singleton.INSTANCE, ${DISPLAYNAME}.class);\n    }\n    \n    /**\n     * TODO Call this method from the module Installer#uninstalled()\n     **/\n    public static void uninstall() {\n        DataSourceViewsManager.sharedInstance().removeViewProvider(Singleton.INSTANCE);\n    }\n\n    @Override\n    public Set<Integer> getPluggableLocations(DataSourceView arg0) {\n        // TODO update the view supported locations (DataViewComponent.TOP_LEFT, DataViewComponent.TOP_RIGHT, DataViewComponent.BOTTOM_LEFT, DataViewComponent.BOTTOM_RIGHT)\n        return ALL_LOCATIONS;\n    }\n\n}\n\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/tabs/visualVMView.html",
    "content": "<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    </head>\n    <body>\n\n        Creates a skeleton VisualVM tab.\n    </body>\n</html>\n"
  },
  {
    "path": "templates/apisupport/src/org/graalvm/visualvm/apisupport/tabs/visualvmview-helpset.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<!DOCTYPE helpsetref PUBLIC \"-//NetBeans//DTD JavaHelp Help Set Reference 1.0//EN\" \"http://www.netbeans.org/dtds/helpsetref-1_0.dtd\">\n<helpsetref url=\"nbdocs:/org/graalvm/visualvm/apisupport/docs/visualvmview-hs.xml\"/>\n"
  },
  {
    "path": "visualvm/antsrc/org/netbeans/nbbuild/AutoUpdate.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.netbeans.nbbuild;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.net.URISyntaxException;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.regex.Pattern;\nimport java.util.zip.CRC32;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\nimport javax.xml.parsers.SAXParser;\nimport javax.xml.parsers.SAXParserFactory;\nimport org.apache.tools.ant.BuildException;\nimport org.apache.tools.ant.DirectoryScanner;\nimport org.apache.tools.ant.Project;\nimport org.apache.tools.ant.Task;\nimport org.apache.tools.ant.taskdefs.Get;\nimport org.apache.tools.ant.types.FileSet;\nimport org.netbeans.nbbuild.AutoUpdateCatalogParser.ModuleItem;\nimport org.xml.sax.Attributes;\nimport org.xml.sax.InputSource;\nimport org.xml.sax.SAXException;\nimport org.xml.sax.helpers.DefaultHandler;\n\n/**\n *\n * @author Jaroslav Tulach <jtulach@netbeans.org>\n */\npublic class AutoUpdate extends Task {\n    private List<Modules> modules = new ArrayList<Modules>();\n    private FileSet nbmSet;\n    private File dir;\n    private File cluster;\n    private URL catalog;\n    private boolean force;\n\n    public void setUpdateCenter(URL u) {\n        catalog = u;\n    }\n\n    public FileSet createNbms() {\n        if (nbmSet != null) {\n            throw new BuildException(\"Just one nbms set allowed\");\n        }\n        nbmSet = new FileSet();\n        return nbmSet;\n    }\n\n    public void setInstallDir(File dir) {\n        this.dir = dir;\n    }\n\n    public void setToDir(File dir) {\n        this.cluster = dir;\n    }\n\n    /** Forces rewrite even the version of a module is not newer */\n    public void setForce(boolean force) {\n        this.force = force;\n    }\n\n    public Modules createModules() {\n        final Modules m = new Modules();\n        modules.add(m);\n        return m;\n    }\n\n    @Override\n    public void execute() throws BuildException {\n        if ((dir != null) == (cluster != null)) {\n            throw new BuildException(\"Specify either todir or installdir\");\n        }\n        Map<String, ModuleItem> units;\n        if (catalog != null) {\n            try {\n                units = AutoUpdateCatalogParser.getUpdateItems(catalog, catalog, this);\n            } catch (IOException ex) {\n                throw new BuildException(ex.getMessage(), ex);\n            }\n        } else {\n            if (nbmSet == null) {\n                throw new BuildException(\"Specify updatecenter or list of NBMs\");\n            }\n            DirectoryScanner s = nbmSet.getDirectoryScanner(getProject());\n            File basedir = s.getBasedir();\n            units = new HashMap<String, ModuleItem>();\n            for (String incl : s.getIncludedFiles()) {\n                File nbm = new File(basedir, incl);\n                try {\n                    URL u = new URL(\"jar:\" + nbm.toURI() + \"!/Info/info.xml\");\n                    Map<String, ModuleItem> map;\n                    final URL url = nbm.toURI().toURL();\n                    map = AutoUpdateCatalogParser.getUpdateItems(u, url, this);\n                    assert map.size() == 1;\n                    Map.Entry<String,ModuleItem> entry = map.entrySet().iterator().next();\n                    units.put(entry.getKey(), entry.getValue().changeDistribution(url));\n                } catch (IOException ex) {\n                    throw new BuildException(ex);\n                }\n            }\n        }\n\n        Map<String,List<String>> installed;\n        if (dir != null) {\n            File[] arr = dir.listFiles();\n            if (arr == null) {\n                throw new BuildException(\"installdir must be existing directory: \" + dir);\n            }\n            installed = findExistingModules(arr);\n        } else {\n            installed = findExistingModules(cluster);\n        }\n\n\n        for (ModuleItem uu : units.values()) {\n            if (!matches(uu.getCodeName(), uu.targetcluster)) {\n                continue;\n            }\n            log(\"found module: \" + uu, Project.MSG_VERBOSE);\n            List<String> info = installed.get(uu.getCodeName());\n            if (info != null && !uu.isNewerThan(info.get(0))) {\n                log(\"Version \" + info.get(0) + \" of \" + uu.getCodeName() + \" is up to date\", Project.MSG_VERBOSE);\n                if (!force) {\n                    continue;\n                }\n            }\n            if (info == null) {\n                log(uu.getCodeName() + \" is not present, downloading version \" + uu.getSpecVersion(), Project.MSG_INFO);\n            } else {\n                log(\"Version \" + info.get(0) + \" of \" + uu.getCodeName() + \" needs update to \" + uu.getSpecVersion(), Project.MSG_INFO);\n            }\n\n            byte[] bytes = new byte[4096];\n            File tmp = null;\n            boolean delete = false;\n            File lastM = null;\n            try {\n                if (uu.getURL().getProtocol().equals(\"file\")) {\n                    try {\n                        tmp = new File(uu.getURL().toURI());\n                    } catch (URISyntaxException ex) {\n                        tmp = null;\n                    }\n                    if (!tmp.exists()) {\n                        tmp = null;\n                    }\n                }\n                final String dash = uu.getCodeName().replace('.', '-');\n                if (tmp == null) {\n                    tmp = File.createTempFile(dash, \".nbm\");\n                    tmp.deleteOnExit();\n                    delete = true;\n                    Get get = new Get();\n                    get.setProject(getProject());\n                    get.setTaskName(\"get:\" + uu.getCodeName());\n                    get.setSrc(uu.getURL());\n                    get.setDest(tmp);\n                    get.setVerbose(true);\n                    get.execute();\n                }\n\n                File whereTo = dir != null ? new File(dir, uu.targetcluster) : cluster;\n                whereTo.mkdirs();\n                lastM = new File(whereTo, \".lastModified\");\n                lastM.createNewFile();\n\n                if (info != null) {\n                    for (int i = 1; i < info.size(); i++) {\n                        File oldFile = new File(whereTo, info.get(i).replace('/', File.separatorChar));\n                        oldFile.delete();\n                    }\n                }\n\n                File tracking = new File(new File(whereTo, \"update_tracking\"), dash + \".xml\");\n                log(\"Writing tracking file \" + tracking, Project.MSG_VERBOSE);\n                tracking.getParentFile().mkdirs();\n                OutputStream config = new BufferedOutputStream(new FileOutputStream(tracking));\n                config.write((\"<?xml version='1.0' encoding='UTF-8'?>\\n\" +\n                    \"<module codename='\" + uu.getCodeName() + \"'>\\n\").getBytes(\"UTF-8\"));\n                config.write((\"  <module_version install_time='\" + System.currentTimeMillis() + \"' last='true' origin='Ant'\" +\n                        \" specification_version='\" + uu.getSpecVersion() + \"'>\\n\").getBytes(\"UTF-8\"));\n\n                ZipFile  zf = new ZipFile(tmp);\n                Enumeration<? extends ZipEntry> en = zf.entries();\n                while (en.hasMoreElements()) {\n                    ZipEntry zipEntry = en.nextElement();\n                    if (!zipEntry.getName().startsWith(\"netbeans/\")) {\n                        continue;\n                    }\n                    if (zipEntry.getName().endsWith(\"/\")) {\n                        continue;\n                    }\n                    String relName = zipEntry.getName().substring(9);\n                    File trgt = new File(whereTo, relName.replace('/', File.separatorChar));\n                    trgt.getParentFile().mkdirs();\n                    log(\"Writing \" + trgt, Project.MSG_VERBOSE);\n\n                    InputStream is = zf.getInputStream(zipEntry);\n                    OutputStream os = new FileOutputStream(trgt);\n                    boolean doUnpack200 = false;\n                    if(relName.endsWith(\".jar.pack.gz\") && zf.getEntry(zipEntry.getName().substring(0, zipEntry.getName().length() - 8))==null) {\n                        doUnpack200 = true;\n                    }\n                    CRC32 crc = new CRC32();\n                    for (;;) {\n                        int len = is.read(bytes);\n                        if (len == -1) {\n                            break;\n                        }\n                        if(!doUnpack200) {\n                            crc.update(bytes, 0, len);\n                        }\n                        os.write(bytes, 0, len);\n                    }\n                    is.close();\n                    os.close();\n                    long crcValue = crc.getValue();\n                    if(doUnpack200) {\n                        File dest = new File(trgt.getParentFile(), trgt.getName().substring(0, trgt.getName().length() - 8));\n                        log(\"Unpacking \" + trgt + \" to \" + dest, Project.MSG_VERBOSE);\n                        unpack200(trgt, dest);\n                        trgt.delete();\n                        crcValue = getFileCRC(dest);\n                        relName = relName.substring(0, relName.length() - 8);\n                    }\n                    config.write((\"    <file crc='\" + crcValue + \"' name='\" + relName + \"'/>\\n\").getBytes(\"UTF-8\"));\n                }\n                config.write(\"  </module_version>\\n</module>\\n\".getBytes(\"UTF-8\"));\n                config.close();\n            } catch (IOException ex) {\n                throw new BuildException(ex);\n            } finally {\n                if (delete && tmp != null) {\n                    tmp.delete();\n                }\n                if (lastM != null) {\n                    lastM.setLastModified(System.currentTimeMillis());\n                }\n            }\n        }\n    }\n\n    \n    public static boolean unpack200(File src, File dest) {\n        // Copy of ModuleUpdater.unpack200        \n        String unpack200Executable = new File(System.getProperty(\"java.home\"),\n                \"bin/unpack200\" + (isWindows() ? \".exe\" : \"\")).getAbsolutePath();\n        ProcessBuilder pb = new ProcessBuilder(unpack200Executable, src.getAbsolutePath(), dest.getAbsolutePath());\n        pb.directory(src.getParentFile());\n        int result = 1;\n        try {\n            //maybe reuse start() method here?\n            Process process = pb.start();\n            //TODO: Need to think of unpack200/lvprcsrv.exe issues\n            //https://netbeans.org/bugzilla/show_bug.cgi?id=117334\n            //https://netbeans.org/bugzilla/show_bug.cgi?id=119861\n            result = process.waitFor();\n            process.destroy();\n        } catch (IOException e) {\n            e.printStackTrace();\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n        return result == 0;\n    }\n    private static boolean isWindows() {\n        String os = System.getProperty(\"os.name\"); // NOI18N\n        return (os != null && os.toLowerCase().startsWith(\"windows\"));//NOI18N\n    }\n\n    private static long getFileCRC(File file) throws IOException {\n        BufferedInputStream bsrc = null;\n        CRC32 crc = new CRC32();\n        try {\n            bsrc = new BufferedInputStream( new FileInputStream( file ) );\n            byte[] bytes = new byte[1024];\n            int i;\n            while( (i = bsrc.read(bytes)) != -1 ) {\n                crc.update(bytes, 0, i );\n            }\n        }\n        finally {\n            if ( bsrc != null )\n                bsrc.close();\n        }\n        return crc.getValue();\n    }\n\n    private boolean matches(String cnb, String targetCluster) {\n        for (Modules ps : modules) {\n            if (ps.clusters != null) {\n                if (targetCluster == null) {\n                    continue;\n                }\n                if (!ps.clusters.matcher(targetCluster).matches()) {\n                    continue;\n                }\n            }\n\n            if (ps.pattern.matcher(cnb).matches()) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private Map<String,List<String>> findExistingModules(File... clusters) {\n        Map<String,List<String>> all = new HashMap<String, List<String>>();\n        for (File c : clusters) {\n            File mc = new File(c, \"update_tracking\");\n            final File[] arr = mc.listFiles();\n            if (arr == null) {\n                continue;\n            }\n            for (File m : arr) {\n                try {\n                    parseVersion(m, all);\n                } catch (Exception ex) {\n                    log(\"Cannot parse \" + m, ex, Project.MSG_WARN);\n                }\n            }\n        }\n        return all;\n    }\n\n    private void parseVersion(final File config, final Map<String,List<String>> toAdd) throws Exception {\n        class P extends DefaultHandler {\n            String name;\n            List<String> arr;\n\n            @Override\n            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {\n                if (\"module\".equals(qName)) {\n                    name = attributes.getValue(\"codename\");\n                    int slash = name.indexOf('/');\n                    if (slash > 0) {\n                        name = name.substring(0, slash);\n                    }\n                    return;\n                }\n                if (\"module_version\".equals(qName)) {\n                    String version = attributes.getValue(\"specification_version\");\n                    if (name == null || version == null) {\n                        throw new BuildException(\"Cannot find version in \" + config);\n                    }\n                    arr = new ArrayList<String>();\n                    arr.add(version);\n                    toAdd.put(name, arr);\n                    return;\n                }\n                if (\"file\".equals(qName)) {\n                    arr.add(attributes.getValue(\"name\"));\n                }\n            }\n\n            @Override\n            public InputSource resolveEntity(String string, String string1) throws IOException, SAXException {\n                return new InputSource(new ByteArrayInputStream(new byte[0]));\n            }\n        }\n        P p = new P();\n        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();\n        parser.parse(config, p);\n    }\n\n    public static final class Modules {\n        Pattern pattern;\n        Pattern clusters;\n\n        public void setIncludes(String regExp) {\n            pattern = Pattern.compile(regExp);\n        }\n\n        public void setClusters(String regExp) {\n            clusters = Pattern.compile(regExp);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/antsrc/org/netbeans/nbbuild/AutoUpdateCatalogParser.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.netbeans.nbbuild;\n\nimport java.io.BufferedInputStream;\nimport java.io.ByteArrayInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.MalformedURLException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.net.URL;\nimport java.text.DateFormat;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Stack;\nimport java.util.jar.Manifest;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.zip.GZIPInputStream;\nimport javax.xml.parsers.SAXParser;\nimport javax.xml.parsers.SAXParserFactory;\nimport org.apache.tools.ant.Project;\nimport org.apache.tools.ant.Task;\nimport org.xml.sax.Attributes;\nimport org.xml.sax.EntityResolver;\nimport org.xml.sax.InputSource;\nimport org.xml.sax.SAXException;\nimport org.xml.sax.SAXParseException;\nimport org.xml.sax.helpers.DefaultHandler;\n\n/**\n *\n * @author Jiri Rechtacek\n */\nclass AutoUpdateCatalogParser extends DefaultHandler {\n    private final Map<String, ModuleItem> items;\n    private final URL provider;\n    private final EntityResolver entityResolver;\n    private final URI baseUri;\n    \n    private AutoUpdateCatalogParser (Map<String, ModuleItem> items, URL provider, URI base) {\n        this.items = items;\n        this.provider = provider;\n        this.entityResolver = newEntityResolver();\n        this.baseUri = base;\n    }\n\n    private EntityResolver newEntityResolver () {\n        return new EntityResolver() {\n            public InputSource resolveEntity(String string, String string1) throws SAXException, IOException {\n                return new InputSource(new ByteArrayInputStream(new byte[0]));\n            }\n        };\n    }\n\n    \n    private static final Logger ERR = Logger.getLogger (AutoUpdateCatalogParser.class.getName ());\n    \n    private static enum ELEMENTS {\n        module_updates, module_group, notification, module, description,\n        module_notification, external_package, manifest, l10n, license\n    }\n    \n    private static final String MODULE_UPDATES_ATTR_TIMESTAMP = \"timestamp\"; // NOI18N\n    \n    private static final String MODULE_GROUP_ATTR_NAME = \"name\"; // NOI18N\n    \n    private static final String NOTIFICATION_ATTR_URL = \"url\"; // NOI18N\n    \n    private static final String LICENSE_ATTR_NAME = \"name\"; // NOI18N\n    \n    private static final String MODULE_ATTR_CODE_NAME_BASE = \"codenamebase\"; // NOI18N\n    private static final String MODULE_ATTR_HOMEPAGE = \"homepage\"; // NOI18N\n    private static final String MODULE_ATTR_DISTRIBUTION = \"distribution\"; // NOI18N\n    private static final String MODULE_ATTR_DOWNLOAD_SIZE = \"downloadsize\"; // NOI18N\n    private static final String MODULE_ATTR_NEEDS_RESTART = \"needsrestart\"; // NOI18N\n    private static final String MODULE_ATTR_MODULE_AUTHOR = \"moduleauthor\"; // NOI18N\n    private static final String MODULE_ATTR_RELEASE_DATE = \"releasedate\"; // NOI18N\n    private static final String MODULE_ATTR_IS_GLOBAL = \"global\"; // NOI18N\n    private static final String MODULE_ATTR_TARGET_CLUSTER = \"targetcluster\"; // NOI18N\n    private static final String MODULE_ATTR_EAGER = \"eager\"; // NOI18N\n    private static final String MODULE_ATTR_AUTOLOAD = \"autoload\"; // NOI18N\n    private static final String MODULE_ATTR_LICENSE = \"license\"; // NOI18N\n    private static final String LICENSE_ATTR_URL = \"url\"; // NOI18N\n    \n    private static final String MANIFEST_ATTR_SPECIFICATION_VERSION = \"OpenIDE-Module-Specification-Version\"; // NOI18N\n    \n    private static final String TIME_STAMP_FORMAT = \"ss/mm/hh/dd/MM/yyyy\"; // NOI18N\n    \n    private static final String L10N_ATTR_LOCALE = \"langcode\"; // NOI18N\n    private static final String L10N_ATTR_BRANDING = \"brandingcode\"; // NOI18N\n    private static final String L10N_ATTR_MODULE_SPECIFICATION = \"module_spec_version\"; // NOI18N\n    private static final String L10N_ATTR_MODULE_MAJOR_VERSION = \"module_major_version\"; // NOI18N\n    private static final String L10N_ATTR_LOCALIZED_MODULE_NAME = \"OpenIDE-Module-Name\"; // NOI18N\n    private static final String L10N_ATTR_LOCALIZED_MODULE_DESCRIPTION = \"OpenIDE-Module-Long-Description\"; // NOI18N\n    \n    private static String GZIP_EXTENSION = \".gz\"; // NOI18N\n\n    private static Map<String, ModuleItem> cache;\n    private static URI cacheURI;\n    synchronized static Map<String, ModuleItem> getUpdateItems (URL url, URL provider, Task task) throws IOException {\n\n        Map<String, ModuleItem> items = new HashMap<String, ModuleItem> ();\n        URI base;\n        try {\n            if (provider != null) {\n                base = provider.toURI();\n            } else {\n                base = url.toURI();\n            }\n            if (cache != null && cacheURI.equals(base)) {\n                task.log(\"Using existing module item cache \" + base, Project.MSG_INFO);\n                return cache;\n            }\n            task.log(\"Downloading \" + base, Project.MSG_INFO);\n            InputSource is = null;\n            try {\n                SAXParserFactory factory = SAXParserFactory.newInstance();\n                factory.setValidating(false);\n                SAXParser saxParser = factory.newSAXParser();\n                is = getInputSource(url, provider, base);\n                saxParser.parse(is, new AutoUpdateCatalogParser(items, provider, base));\n                cacheURI = base;\n                cache = items;\n            } catch (IOException ex) {\n                throw ex;\n            } catch (Exception ex) {\n                throw (IOException)new IOException(ex.getMessage()).initCause(ex);\n            } finally {\n                if (is != null && is.getByteStream() != null) {\n                    try {\n                        is.getByteStream().close();\n                    } catch (IOException e) {\n                    }\n                }\n            }\n        } catch (URISyntaxException ex) {\n            ERR.log(Level.INFO, null, ex);\n        }\n        return items;\n    }\n    \n    private static boolean isGzip (URL url) {\n        boolean res = false;\n        if (url != null) {\n            res = url.getPath ().toLowerCase ().endsWith (GZIP_EXTENSION);\n            ERR.log (Level.FINER, \"Is GZIP \" + url + \" ? \" + res);\n        } else {\n            ERR.log (Level.WARNING, \"AutoupdateCatalogProvider has not URL.\");\n        }\n        return res;\n    }\n    \n    private static InputSource getInputSource(URL toParse, URL p, URI base) throws IOException {\n        InputStream is = toParse.openStream ();\n        if (isGzip (p)) {\n            try {\n                is = new GZIPInputStream(is);\n            } catch (IOException e) {\n                ERR.log (Level.INFO,\n                        \"The file at \" + toParse +\n                        \", corresponding to the catalog at \" + p +\n                        \", does not look like the gzip file, trying to parse it as the pure xml\" , e);\n                //#150034\n                // Sometimes the .xml.gz file is downloaded as the pure .xml file due to the strange content-encoding processing\n                is.close();\n                is = null;\n                is = toParse.openStream();\n            }\n        }\n        InputSource src = new InputSource(new BufferedInputStream (is));\n        src.setSystemId(base.toString());\n        return src;\n    }\n    \n    private Stack<String> currentGroup = new Stack<String> ();\n    private String catalogDate;\n    private Stack<ModuleDescriptor> currentModule = new Stack<ModuleDescriptor> ();\n    private Stack<Map <String,String>> currentLicense = new Stack<Map <String,String>> ();\n    private Stack<String> currentNotificationUrl = new Stack<String> ();\n    private List<String> lines = new ArrayList<String> ();\n    private int bufferInitSize = 0;\n\n    @Override\n    public void characters (char[] ch, int start, int length) throws SAXException {\n        lines.add (new String(ch, start, length));\n        bufferInitSize += length;\n    }\n\n    @Override\n    public void endElement (String uri, String localName, String qName) throws SAXException {\n        switch (ELEMENTS.valueOf (qName)) {\n            case module_updates :\n                break;\n            case module_group :\n                assert ! currentGroup.empty () : \"Premature end of module_group \" + qName;\n                currentGroup.pop ();\n                break;\n            case module :\n                assert ! currentModule.empty () : \"Premature end of module \" + qName;\n                currentModule.pop ();\n                break;\n            case l10n :\n                break;\n            case manifest :\n                break;\n            case description :\n                ERR.info (\"Not supported yet.\");\n                break;\n            case notification :\n                // write catalog notification\n                if (this.provider != null && ! lines.isEmpty ()) {\n                    StringBuffer sb = new StringBuffer (bufferInitSize);\n                    for (String line : lines) {\n                        sb.append (line);\n                    }\n                    String notification = sb.toString ();\n                    String notificationUrl = currentNotificationUrl.peek ();\n                    if (notificationUrl != null && notificationUrl.length () > 0) {\n                        notification += (notification.length () > 0 ? \"<br>\" : \"\") + // NOI18N\n                                \"<a name=\\\"autoupdate_catalog_parser\\\" href=\\\"\" + notificationUrl + \"\\\">\" + notificationUrl + \"</a>\"; // NOI18N\n                    } else {\n                        notification += (notification.length () > 0 ? \"<br>\" : \"\") +\n                                \"<a name=\\\"autoupdate_catalog_parser\\\"/>\"; // NOI18N\n                    }\n                }\n                currentNotificationUrl.pop ();\n                break;\n            case module_notification :\n                // write module notification\n                if (! lines.isEmpty ()) {\n                    ModuleDescriptor md = currentModule.peek ();\n                    assert md != null : \"ModuleDescriptor found for \" + provider;\n                    StringBuffer buf = new StringBuffer (bufferInitSize);\n                    for (String line : lines) {\n                        buf.append (line);\n                    }\n                    md.appendNotification (buf.toString ());\n                }\n                break;\n            case external_package :\n                ERR.info (\"Not supported yet.\");\n                break;\n            case license :\n                assert ! currentLicense.empty () : \"Premature end of license \" + qName;\n                Map <String, String> curLic = currentLicense.peek ();\n                String licenseName = curLic.keySet().iterator().next();\n                Collection<String> values = curLic.values();\n                String licenseUrl = (values.size() > 0) ? values.iterator().next() : null;\n                \n                currentLicense.pop ();\n                break;\n            default:\n                ERR.warning (\"Unknown element \" + qName);\n        }\n    }\n\n    @Override\n    public void endDocument () throws SAXException {\n        ERR.fine (\"End parsing \" + (provider == null ? \"\" : provider) + \" at \" + System.currentTimeMillis ());\n    }\n\n    @Override\n    public void startDocument () throws SAXException {\n        ERR.fine (\"Start parsing \" + (provider == null ? \"\" : provider) + \" at \" + System.currentTimeMillis ());\n    }\n\n    @Override\n    public void startElement (String uri, String localName, String qName, Attributes attributes) throws SAXException {\n        lines.clear();\n        bufferInitSize = 0;\n        switch (ELEMENTS.valueOf (qName)) {\n            case module_updates :\n                try {\n                    catalogDate = \"\";\n                    DateFormat format = new SimpleDateFormat (TIME_STAMP_FORMAT);\n                    String timeStamp = attributes.getValue (MODULE_UPDATES_ATTR_TIMESTAMP);\n                    if (timeStamp == null) {\n                        ERR.info (\"No timestamp is presented in \" + (this.provider == null ? \"\" : this.provider));\n                    } else {\n                        //catalogDate = Utilities.formatDate (format.parse (timeStamp));\n                        catalogDate = format.parse (timeStamp).toString();\n                        ERR.finer (\"Successfully read time \" + timeStamp); // NOI18N\n                    }\n                } catch (ParseException pe) {\n                    ERR.log (Level.INFO, null, pe);\n                }\n                break;\n            case module_group :\n                currentGroup.push (attributes.getValue (MODULE_GROUP_ATTR_NAME));\n                break;\n            case module :\n                ModuleDescriptor md = ModuleDescriptor.getModuleDescriptor (\n                        currentGroup.size () > 0 ? currentGroup.peek () : null, /* group */\n                        baseUri, /* base URI */\n                        this.catalogDate); /* catalog date */\n                md.appendModuleAttributes (attributes);\n                currentModule.push (md);\n                break;\n            case l10n :\n                // construct l10n\n                // XXX\n                break;\n            case manifest :\n                \n                // construct module\n                ModuleDescriptor desc = currentModule.peek ();\n                desc.appendManifest (attributes);\n                ModuleItem m = desc.createUpdateItem ();\n                \n                // put module into UpdateItems\n                items.put (desc.getId (), m);\n                \n                break;\n            case description :\n                ERR.info (\"Not supported yet.\");\n                break;\n            case module_notification :\n                break;\n            case notification :\n                currentNotificationUrl.push (attributes.getValue (NOTIFICATION_ATTR_URL));\n                break;\n            case external_package :\n                ERR.info (\"Not supported yet.\");\n                break;\n            case license :\n                Map <String, String> map = new HashMap<String,String> ();\n                map.put(attributes.getValue (LICENSE_ATTR_NAME), attributes.getValue (LICENSE_ATTR_URL));\n                currentLicense.push (map);\n                break;\n            default:\n                ERR.warning (\"Unknown element \" + qName);\n        }\n    }\n\n    @Override\n    public void warning(SAXParseException e) throws SAXException {\n        parseError(e);\n    }\n\n    @Override\n    public void error(SAXParseException e) throws SAXException {\n        parseError(e);\n    }\n\n    @Override\n    public void fatalError(SAXParseException e) throws SAXException {\n        parseError(e);\n    }\n\n    private void parseError(SAXParseException e) {\n        ERR.warning(e.getSystemId() + \":\" + e.getLineNumber() + \":\" + e.getColumnNumber() + \": \" + e.getLocalizedMessage());\n    }\n\n    @Override\n    public InputSource resolveEntity (String publicId, String systemId) throws IOException, SAXException {\n        return entityResolver.resolveEntity (publicId, systemId);\n    }\n    \n    private static class ModuleDescriptor {\n        private String moduleCodeName;\n        private URL distributionURL;\n        private String targetcluster;\n        private String homepage;\n        private String downloadSize;\n        private String author;\n        private String publishDate;\n        private String notification;\n\n        private Boolean needsRestart;\n        private Boolean isGlobal;\n        private Boolean isEager;\n        private Boolean isAutoload;\n\n        private String specVersion;\n        private Manifest mf;\n        \n        private String id;\n\n        private String group;\n        private URI base;\n        private String catalogDate;\n        \n        private static ModuleDescriptor md = null;\n        \n        private ModuleDescriptor () {}\n        \n        public static ModuleDescriptor getModuleDescriptor (String group, URI base, String catalogDate) {\n            if (md == null) {\n                md = new ModuleDescriptor ();\n            }\n            \n            md.group = group;\n            md.base = base;\n            md.catalogDate = catalogDate;\n            \n            return md;\n        }\n        \n        public void appendModuleAttributes (Attributes module) {\n            moduleCodeName = module.getValue (MODULE_ATTR_CODE_NAME_BASE);\n            distributionURL = getDistribution (module.getValue (MODULE_ATTR_DISTRIBUTION), base);\n            targetcluster = module.getValue (MODULE_ATTR_TARGET_CLUSTER);\n            homepage = module.getValue (MODULE_ATTR_HOMEPAGE);\n            downloadSize = module.getValue (MODULE_ATTR_DOWNLOAD_SIZE);\n            author = module.getValue (MODULE_ATTR_MODULE_AUTHOR);\n            publishDate = module.getValue (MODULE_ATTR_RELEASE_DATE);\n            if (publishDate == null || publishDate.length () == 0) {\n                publishDate = catalogDate;\n            }\n            String needsrestart = module.getValue (MODULE_ATTR_NEEDS_RESTART);\n            String global = module.getValue (MODULE_ATTR_IS_GLOBAL);\n            String eager = module.getValue (MODULE_ATTR_EAGER);\n            String autoload = module.getValue (MODULE_ATTR_AUTOLOAD);\n                        \n            needsRestart = needsrestart == null || needsrestart.trim ().length () == 0 ? null : Boolean.valueOf (needsrestart);\n            isGlobal = global == null || global.trim ().length () == 0 ? null : Boolean.valueOf (global);\n            isEager = Boolean.parseBoolean (eager);\n            isAutoload = Boolean.parseBoolean (autoload);\n                        \n            String licName = module.getValue (MODULE_ATTR_LICENSE);\n        }\n        \n        public void appendManifest (Attributes manifest) {\n            specVersion = manifest.getValue (MANIFEST_ATTR_SPECIFICATION_VERSION);\n            mf = getManifest (manifest);\n            id = moduleCodeName + '_' + specVersion; // NOI18N\n        }\n        \n        public void appendNotification (String notification) {\n            this.notification = notification;\n        }\n        \n        public String getId () {\n            return id;\n        }\n        \n        public ModuleItem createUpdateItem () {\n            ModuleItem res = ModuleItem.createModule (\n                    moduleCodeName,\n                    specVersion,\n                    distributionURL,\n                    author,\n                    downloadSize,\n                    homepage,\n                    publishDate,\n                    group,\n                    mf,\n                    isEager,\n                    isAutoload,\n                    needsRestart,\n                    isGlobal,\n                    targetcluster,\n                    null);\n            \n            // clean-up ModuleDescriptor\n            cleanUp ();\n            \n            return res;\n        }\n        \n        private void cleanUp (){\n            this.specVersion = null;\n            this.mf = null;\n            this.notification = null;\n        }\n    }\n    \n    private static URL getDistribution (String distribution, URI base) {\n        URL retval = null;\n        if (distribution != null && distribution.length () > 0) {\n            try {\n                URI distributionURI = new URI (distribution);\n                if (! distributionURI.isAbsolute ()) {\n                    if (base != null) {\n                        distributionURI = base.resolve (distributionURI);\n                    }\n                }\n                retval = distributionURI.toURL ();\n            } catch (MalformedURLException ex) {\n                ERR.log (Level.INFO, null, ex);\n            } catch (URISyntaxException ex) {\n                ERR.log (Level.INFO, null, ex);\n            }\n        }\n        return retval;\n    }\n\n    private static Manifest getManifest (Attributes attrList) {\n        Manifest mf = new Manifest ();\n        java.util.jar.Attributes mfAttrs = mf.getMainAttributes ();\n\n        for (int i = 0; i < attrList.getLength (); i++) {\n            mfAttrs.put (new java.util.jar.Attributes.Name (attrList.getQName (i)), attrList.getValue (i));\n        }\n        return mf;\n    }\n\n    public static final class ModuleItem {\n        private final String moduleCodeName;\n        private final String specVersion;\n        private final URL distributionURL;\n        public final String targetcluster;\n\n        private ModuleItem(String moduleCodeName, String specVersion, URL distributionURL, String targetcluster) {\n            this.moduleCodeName = moduleCodeName;\n            this.specVersion = specVersion;\n            this.distributionURL = distributionURL;\n            this.targetcluster = targetcluster;\n        }\n\n        ModuleItem changeDistribution(URL u) {\n            return new ModuleItem(moduleCodeName, specVersion, u, targetcluster);\n        }\n\n\n        static ModuleItem createModule(\n            String moduleCodeName,\n            String specVersion,\n            URL distributionURL,\n            String author,\n            String downloadSize,\n            String homepage,\n            String publishDate,\n            String group,\n            Manifest mf,\n            Boolean eager,\n            Boolean autoload,\n            Boolean needsRestart,\n            Boolean global,\n            String targetcluster,\n            Object object\n        ) {\n            return new ModuleItem(moduleCodeName, specVersion, distributionURL, targetcluster);\n        }\n\n        public String getCodeName() {\n            return moduleCodeName;\n        }\n\n        String getSpecVersion() {\n            return specVersion;\n        }\n\n        URL getURL() {\n            return distributionURL;\n        }\n\n        @Override\n        public String toString() {\n            return \"[\" + moduleCodeName + \"@\" + specVersion + \"(\" + targetcluster + \") <- \" + distributionURL + \"]\";\n        }\n\n        boolean isNewerThan(String version) {\n            String[] mine = specVersion.split(\"\\\\.\");\n            String[] its = version.split(\"\\\\.\");\n\n            int min = Math.min(mine.length, its.length);\n            for (int i = 0; i < min; i++) {\n                int m = Integer.parseInt(mine[i]);\n                int it = Integer.parseInt(its[i]);\n\n                if (m > it) {\n                    return true;\n                }\n                if (m < it) {\n                    return false;\n                }\n            }\n            return mine.length > its.length;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/application/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.application\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.application.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/application/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.application/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/application/resources/layer.xml\nOpenIDE-Module-Install: org/graalvm/visualvm/application/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/application/resources/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.4\n\n"
  },
  {
    "path": "visualvm/application/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.application-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/application/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=3a862d27\nbuild.xml.script.CRC32=be44af4b\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=3a862d27\nnbproject/build-impl.xml.script.CRC32=9f1a32ca\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/application/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/application/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.application</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.sendopts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.11.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.50</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.18.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.application</package>\n                <package>org.graalvm.visualvm.application.jvm</package>\n                <package>org.graalvm.visualvm.application.snapshot</package>\n                <package>org.graalvm.visualvm.application.type</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/application/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/Application.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application;\n\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.io.File;\nimport java.util.Objects;\nimport org.graalvm.visualvm.core.datasource.StatefulDataSource;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowListener;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.host.Host;\n\n/**\n * Abstract implementation of Application.\n * Each application is defined by a Host on which it's running and a unique identificator.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class Application extends StatefulDataSource {\n    \n    /**\n     * Instance representing actually running VisualVM application.\n     */\n    public static final Application CURRENT_APPLICATION = ApplicationSupport.getInstance().createCurrentApplication();\n    \n    /**\n     * Process ID of the application is unknown.\n     */\n    public static final int UNKNOWN_PID = -1;\n\n    private String id;\n    private Host host;\n    \n\n    /**\n     * Creates new instance of Application defined by a Host and unique identificator.\n     * \n     * @param host Host on which the application is running.\n     * @param id unique identificator of the application.\n     */\n    public Application(Host host, String id) {\n        this(host, id, STATE_AVAILABLE);\n    }\n    \n    /**\n     * Creates new instance of Application defined by a Host and unique identificator.\n     * \n     * @param host Host on which the application is running.\n     * @param id unique identificator of the application.\n     * @param state initial state of the application.\n     */\n    protected Application(Host host, String id, int state) {\n        super(state);\n        if (host == null) throw new IllegalArgumentException(\"Host cannot be null\");    // NOI18N\n        if (id == null) throw new IllegalArgumentException(\"Application id cannot be null\");  // NOI18N\n        this.host = host;\n        this.id = id;\n    }\n\n\n    /**\n     * Returns unique identificator of the application.\n     * \n     * @return unique identificator of the application.\n     */\n    public final String getId() {\n        return id;\n    }\n\n    /**\n     * Returns process id of the application or Application.UNKNOWN_PID.\n     * \n     * @return process id of the application or Application.UNKNOWN_PID.\n     */\n    public int getPid() {\n        return UNKNOWN_PID;\n    }\n\n    /**\n     * Returns Host on which the application is running.\n     * \n     * @return Host on which the application is running.\n     */\n    public final Host getHost() {\n        return host;\n    }\n\n    /**\n     * Returns true if the application is running on {@code Host.LOCALHOST}, false otherwise.\n     * \n     * @return true if the application is running on {@code Host.LOCALHOST}, false otherwise.\n     */\n    public boolean isLocalApplication() {\n        return Host.LOCALHOST.equals(getHost());\n    }\n    \n    protected boolean supportsFinishedRemove() {\n        return true;\n    }\n    \n    protected boolean handleControlledRemove() {\n        if (!canRemoveFinished_Opened()) {\n            class ApplicationListener implements DataSourceWindowListener<Application>, DataRemovedListener<Application>, PropertyChangeListener {\n                private boolean done;\n                \n                public void windowClosed(Application application) {\n                    synchronized (ApplicationListener.this) {\n                        if (!done) {\n                            unregister();\n                            if (canRemoveFinished_Snapshots())\n                                application.getHost().getRepository().removeDataSource(application);\n                        }\n                    }\n                }\n                \n                public void dataRemoved(Application application) {\n                    synchronized (ApplicationListener.this) {\n                        if (!done) unregister();\n                    }\n                }\n                \n                public void propertyChange(PropertyChangeEvent evt) {\n                    if (PROPERTY_STATE.equals(evt.getPropertyName()) &&\n                        !Objects.equals(evt.getNewValue(), STATE_UNAVAILABLE))\n                            synchronized (ApplicationListener.this) {\n                                if (!done) unregister();\n                            }\n                }\n                \n                void register() {\n                    Application.this.notifyWhenRemoved(this);\n                    Application.this.addPropertyChangeListener(PROPERTY_STATE, this);\n                    DataSourceWindowManager.sharedInstance().addWindowListener(Application.this, this);\n                }\n                \n                void unregister() {\n                    done = true;\n                    DataSourceWindowManager.sharedInstance().removeWindowListener(Application.this, this);\n                    Application.this.removePropertyChangeListener(this);\n                }\n            }\n            \n            new ApplicationListener().register();\n            \n            return true;\n        }\n        \n        if (!canRemoveFinished_Snapshots()) {\n            return true;\n        }\n        \n        return false;\n    }\n    \n    private boolean canRemoveFinished_Opened() {\n        return GlobalPreferences.sharedInstance().autoRemoveOpenedFinishedApps() ||\n               !DataSourceWindowManager.sharedInstance().isDataSourceOpened(this);\n    }\n    \n    private boolean canRemoveFinished_Snapshots() {\n        return GlobalPreferences.sharedInstance().autoRemoveFinishedAppsWithSnapshots() ||\n               getRepository().getDataSources().isEmpty();\n    }\n    \n    @Override\n    public final int hashCode() {\n        return getId().hashCode();\n    }\n\n    @Override\n    public final boolean equals(Object obj) {\n        if (!(obj instanceof Application)) return false;\n        Application app = (Application) obj;\n        return getId().equals(app.getId());\n    }\n    \n    @Override\n    public String toString() {\n        return \"Application [id: \" + getId() + \", pid: \" + getPid() + \", host: \" + getHost().getHostName() + \"]\";   // NOI18N\n    }\n    \n    \n    // <system_temp>/visualvm_<username>.dat/<application_id>\n    @Override\n    protected Storage createStorage() {\n        File directory = new File(Storage.getTemporaryStorageDirectoryString() +\n                                  File.separator + validFileName(getId()));\n        return new Storage(directory);\n    }\n\n    private static String validFileName(String fileName) {\n        char[] fileNameCh = fileName.toCharArray();\n        StringBuilder validFileName = new StringBuilder();\n        for (char ch : fileNameCh)\n            if (Character.isLetterOrDigit(ch)) validFileName.append(ch);\n            else validFileName.append('_'); // NOI18N\n        return validFileName.toString();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/ApplicationDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application;\n\nimport java.awt.Image;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.openide.util.WeakListeners;\n\n/**\n * DataSourceDescriptor for Application.\n *\n * @author Jiri Sedlacek\n */\npublic class ApplicationDescriptor extends DataSourceDescriptor<Application> implements PropertyChangeListener {\n    \n    private static final String DISPLAY_NAME_PROPERTY = \"-Dvisualvm.display.name=\"; // NOI18N\n    \n    private static final String pid_PARAM = \"%pid\"; // NOI18N\n    private static final String PID_PARAM = \"%PID\"; // NOI18N\n    \n    \n    private String name;\n    \n    private ApplicationType type;\n    \n\n    /**\n     * Creates new instance of Application Descriptor.\n     *\n     * @param application Application described by the descriptor\n     */\n    protected ApplicationDescriptor(Application application) {\n        this(application, ApplicationTypeFactory.getApplicationTypeFor(\n             application), POSITION_AT_THE_END);\n    }\n\n    /**\n     * Creates new instance of Application Descriptor.\n     *\n     * @param application Application described by the descriptor\n     * @param preferredPosition preferred position of the Application\n     */\n    protected ApplicationDescriptor(Application application, int preferredPosition) {\n        this(application, ApplicationTypeFactory.getApplicationTypeFor(application),\n             preferredPosition);\n    }\n\n    protected ApplicationDescriptor(final Application application, final ApplicationType type, int preferredPosition) {\n        super(application, resolveApplicationName(application, type), resolveApplicationDescription(application, type),\n              resolveApplicationIcon(application, type), preferredPosition, EXPAND_ON_EACH_FIRST_CHILD);\n        \n        name = super.getName();\n        \n        setApplicationType(type);\n    }\n    \n    public String getName() {\n        if (supportsRename()) return super.getName();\n        else return name;\n    }\n\n    public boolean providesProperties() {\n        return true;\n    }\n    \n    \n    protected void setApplicationType(ApplicationType type) {\n//        if (this.type != null) this.type.removePropertyChangeListener(this);\n        \n        this.type = type;\n        \n        this.type.addPropertyChangeListener(WeakListeners.propertyChange(this, this.type));\n//        this.type.addPropertyChangeListener(this);\n    }\n    \n    protected ApplicationType getApplicationType() {\n        return type;\n    }\n    \n    \n    @Override\n    public void propertyChange(PropertyChangeEvent evt) {\n        String propertyName = evt.getPropertyName();\n        if (ApplicationType.PROPERTY_NAME.equals(propertyName)) {\n            Application application = getDataSource();\n            \n            // Name already customized by the user, do not change it\n            if (resolveName(application, null) != null) return;\n\n            if (supportsRename()) {\n                // Descriptor supports renaming, use setName(), sync name\n                setName((String)evt.getNewValue());\n                name = ApplicationDescriptor.super.getName();\n            } else {\n                // Descriptor doesn't support renaming, set name for overriden getName()\n                String oldName = name;\n                name = formatName(createGenericName(application, type.getName()));\n                PropertyChangeSupport pcs = ApplicationDescriptor.this.getChangeSupport();\n                pcs.firePropertyChange(PROPERTY_NAME, oldName, name);\n            }\n        } else if (ApplicationType.PROPERTY_ICON.equals(propertyName)) {\n            setIcon((Image)evt.getNewValue());\n        } else if (ApplicationType.PROPERTY_DESCRIPTION.equals(propertyName)) {\n            setDescription((String)evt.getNewValue());\n        } else if (ApplicationType.PROPERTY_VERSION.equals(propertyName)) {\n            // Not supported by ApplicationDescriptor\n        }\n    }\n    \n\n    /**\n     * Returns Application name if available in Snapshot Storage as PROPERTY_NAME\n     * or user-provided display name defined by JVM argument <code>-Dvisualvm.display.name</code>\n     * (since VisualVM 1.3.4) or generates new name using the provided ApplicationType.\n     *\n     * @param application Application for which to resolve the name\n     * @param type ApplicationType to be used for generating Application name\n     * @return persisted Application name if available or new generated name\n     */\n    protected static String resolveApplicationName(Application application, ApplicationType type) {\n        // Check for persisted displayname (currently only for JmxApplications)\n        String persistedName = resolveName(application, null);\n        if (persistedName != null) return persistedName;\n        \n        // Check for custom name defined by -Dvisualvm.display.name\n        String customName = resolveCustomName(application);\n        if (customName != null) return customName;\n\n        // Provide generic displayname\n        return createGenericName(application, type.getName());\n    }\n    \n    protected static String resolveCustomName(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return null;\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        if (jvm.isBasicInfoSupported()) {\n            String args = jvm.getJvmArgs();\n            int propIndex = args != null ? args.indexOf(DISPLAY_NAME_PROPERTY) : -1;\n\n            if (propIndex != -1) {  // display name propery detected on commandline\n                propIndex += DISPLAY_NAME_PROPERTY.length();\n                int endIndex = args.indexOf(' ', propIndex); // NOI18N\n                if (endIndex == -1) return args.substring(propIndex);\n                else return args.substring(propIndex, endIndex);\n            }\n        }\n        return null;\n    }\n    \n    protected String formatName(String namePattern) {\n        if (namePattern == null) return null;\n        \n        String formatted = namePattern;\n        \n        Integer pid = namePattern.contains(pid_PARAM) || namePattern.contains(PID_PARAM) ? getDataSource().getPid() : null;\n        if (pid != null) {\n            boolean unknownPid = Application.UNKNOWN_PID == pid;\n            formatted = formatted.replace(pid_PARAM, unknownPid ? \"unknown\" : pid.toString()); // NOI18N\n            formatted = formatted.replace(PID_PARAM, unknownPid ? \" (unknown pid) \" : \" (pid \" + pid.toString() + \") \").trim(); // NOI18N\n        }\n        \n        return formatted;\n    }\n    \n    protected static String createGenericName(Application application, String nameBase) {\n        if (nameBase.contains(PID_PARAM) || nameBase.contains(pid_PARAM)) return nameBase;\n        \n        int pid = application.getPid();\n        String id = Application.CURRENT_APPLICATION.getPid() == pid ||\n                    pid == Application.UNKNOWN_PID ? \"\" : PID_PARAM; // NOI18N\n        \n        return nameBase + id;\n    }\n    \n    \n    protected static String resolveApplicationDescription(Application application, ApplicationType type) {\n        String persistedDescription = application.getStorage().getCustomProperty(PROPERTY_DESCRIPTION);\n        if (persistedDescription != null) return persistedDescription;\n        \n        return type.getDescription();\n    }\n    \n    protected static Image resolveApplicationIcon(Application application, ApplicationType type) {\n        String persistedIconString = application.getStorage().getCustomProperty(PROPERTY_ICON);\n        if (persistedIconString != null) {\n            Image persistedIcon = Utils.stringToImage(persistedIconString);\n            if (persistedIcon != null) return persistedIcon;\n        }\n        \n        return type.getIcon();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/ApplicationDescriptorProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\n/**\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n * @author Luis-Miguel Alventosa\n */\nclass ApplicationDescriptorProvider extends\n        AbstractModelProvider<DataSourceDescriptor, DataSource> {\n\n    public DataSourceDescriptor createModelFor(DataSource ds) {\n        if (ds instanceof Application) {\n            return new ApplicationDescriptor((Application) ds);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/ApplicationFinder.java",
    "content": "/*\n * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.application;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.Set;\nimport javax.swing.Timer;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.host.Host;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ApplicationFinder {\n    \n    private static final int DEFAULT_TIMEOUT = Integer.getInteger(\"visualvm.search.process.timeout\", 5000); // NOI18N\n    \n    \n    private final int pid;\n    private final String id;\n    private final Host host;\n    private final int timeout;\n    \n    \n    public ApplicationFinder(int pid) {\n        this(pid, null);\n    }\n    \n    public ApplicationFinder(String id) {\n        this(Application.UNKNOWN_PID, id);\n    }\n    \n    public ApplicationFinder(int pid, String id) {\n        this(pid, id, Host.LOCALHOST, DEFAULT_TIMEOUT);\n    }\n    \n    public ApplicationFinder(int pid, String id, Host host, int timeout) {\n        this.pid = pid;\n        this.id = id;\n        this.host = host;\n        this.timeout = timeout;\n    }\n    \n    \n    public abstract void found(Application application);\n    \n    public void notFound(int pid, String id) {}\n    \n    \n    public final void find() {\n        if (timeout <= 0) findImmediately();\n        else new FindLater().find();\n    }\n    \n    \n    private void findImmediately() {\n        Application application = findInSet(pid, id, host.getRepository().getDataSources(Application.class));\n        if (application != null) found(application);\n        else notFound(pid, id);\n    }\n    \n    \n    private static Application findInSet(int pid, String id, Set<Application> applications) {\n        for (Application application : applications) {\n            if (pid != Application.UNKNOWN_PID) {\n                if (application.getPid() == pid) {\n                    return application;\n                }\n            }\n            if (id != null) {\n                Jvm jvm = JvmFactory.getJVMFor(application);\n                if (jvm.isBasicInfoSupported()) {\n                    String args = jvm.getJvmArgs();\n                    if (args != null && args.contains(id)) {\n                        return application;\n                    }\n                }\n            }\n        }\n        return null;\n    }\n    \n    \n    private class FindLater implements DataChangeListener<Application>, ActionListener {\n        \n        private volatile boolean removed;\n        private final Timer timer;\n\n        \n        FindLater() {\n            timer = new Timer(timeout, this);\n        }\n        \n        \n        synchronized void find() {\n            removed = false;\n            timer.start();\n            host.getRepository().addDataChangeListener(this, Application.class);\n        }\n\n        \n        public synchronized void dataChanged(DataChangeEvent<Application> event) {\n            Set<Application> applications = event.getAdded();\n            if (applications.isEmpty()) applications = event.getCurrent();\n            Application application = findInSet(pid, id, applications);\n            if (application != null) {\n                if (!removed) {\n                    cleanup();\n                    timer.stop();\n                }\n                found(application);\n            }\n        }\n\n        public synchronized void actionPerformed(ActionEvent e) {\n            if (!removed) {\n                cleanup();\n                notFound(pid, id);\n            }\n        }\n        \n        \n        private void cleanup() {\n            host.getRepository().removeDataChangeListener(this);\n            removed = true;\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/ApplicationSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application;\n\nimport java.lang.management.ManagementFactory;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.properties.PropertiesSupport;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.host.LocalHostDescriptor;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ApplicationSupport {\n\n    private static ApplicationSupport instance;\n\n    public static synchronized ApplicationSupport getInstance() {\n        if (instance == null) instance = new ApplicationSupport();\n        return instance;\n    }\n    \n    Application createCurrentApplication() {\n        String selfName = ManagementFactory.getRuntimeMXBean().getName();\n        final Integer selfPid = Integer.valueOf(selfName.substring(0, selfName.indexOf('@')));\n        return new CurrentApplication(selfPid, Host.LOCALHOST, Host.LOCALHOST.getHostName() + \"-\" + selfPid);\n    }\n    \n    private void initCurrentApplication() {\n        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n            public void run() {\n                VisualVM.getInstance().runTask(new Runnable() {\n                    public void run() {\n                        // Initialize sorting\n                        DataSourceDescriptor localHostDescriptor =\n                                DataSourceDescriptorFactory.getDescriptor(Host.LOCALHOST);\n                        if (localHostDescriptor instanceof LocalHostDescriptor) {\n                            ((LocalHostDescriptor)localHostDescriptor).setChildrenComparator(\n                                    ApplicationsSorting.instance().getInitialSorting());\n                        }\n                        \n                        Host.LOCALHOST.getRepository().addDataSource(Application.CURRENT_APPLICATION);\n                    }\n                });\n            }\n        });\n    }\n\n    private ApplicationSupport() {\n        DataSourceDescriptorFactory descriptorFactory = DataSourceDescriptorFactory.getDefault();\n        descriptorFactory.registerProvider(new ApplicationDescriptorProvider());\n        PropertiesSupport.sharedInstance().registerPropertiesProvider(\n                new GeneralPropertiesProvider(), CurrentApplication.class);\n        initCurrentApplication();\n    }\n\n    class CurrentApplication extends Application {\n\n        private int selfPid;\n        \n        private CurrentApplication(int selfPid, Host host, String id) {\n            super(host, id);\n            this.selfPid = selfPid;\n        }\n\n        public int getPid() {\n            return selfPid;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/ApplicationsSorting.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application;\n\nimport java.awt.Component;\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.prefs.Preferences;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JRadioButtonMenuItem;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.host.LocalHostDescriptor;\nimport org.graalvm.visualvm.host.RemoteHostDescriptor;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.actions.Presenter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ApplicationsSorting implements Presenter.Menu {\n\n    private static final String PROP_APPS_SORTING = \"Applications.sorting\"; // NOI18N\n    private static final String PROP_APPS_FINISHED = \"Applications.finishedLast\"; // NOI18N\n\n    private static ApplicationsSorting instance;\n    \n    private final Comparator<DataSource> BY_TIME_COMPARATOR = byTimeComparator();\n    private final Comparator<DataSource> BY_NAME_COMPARATOR = byNameComparator();\n    private final Comparator<DataSource> BY_PID_COMPARATOR = byPidComparator();\n    private final List<Comparator<DataSource>> COMPARATORS = new ArrayList<>();\n    { COMPARATORS.add(BY_TIME_COMPARATOR); COMPARATORS.add(BY_NAME_COMPARATOR); COMPARATORS.add(BY_PID_COMPARATOR); }\n\n    private final Preferences prefs;\n\n    private JMenuItem presenter;\n    private final Sorter sorter;\n\n\n    public static synchronized ApplicationsSorting instance() {\n        if (instance == null) instance = new ApplicationsSorting();\n        return instance;\n    }\n\n    public JMenuItem getMenuPresenter() {\n        if (presenter == null) presenter = createPresenter();\n        return presenter;\n    }\n\n\n    Comparator<DataSource> getInitialSorting() {\n        return COMPARATORS.get(prefs.getInt(PROP_APPS_SORTING, COMPARATORS.\n                                            indexOf(BY_TIME_COMPARATOR)));\n    }\n\n\n    private JMenuItem createPresenter() {\n        final JMenu menu = new JMenu() {\n            protected void fireMenuSelected() {\n                Component[] items = getMenuComponents();\n                for (Component item : items)\n                    if (item instanceof SortAction)\n                        ((SortAction)item).updateAction();\n            }\n        };\n        Mnemonics.setLocalizedText(menu, NbBundle.getMessage(ApplicationsSorting.class,\n                                   \"ACT_SortApps\")); // NOI18N\n\n        menu.add(new SortAction(NbBundle.getMessage(ApplicationsSorting.class,\n                                \"ACT_TimeAdded\"), BY_TIME_COMPARATOR, sorter)); // NOI18N\n        menu.add(new SortAction(NbBundle.getMessage(ApplicationsSorting.class,\n                                \"ACT_DisplayName\"), BY_NAME_COMPARATOR, sorter)); // NOI18N\n        menu.add(new SortAction(NbBundle.getMessage(ApplicationsSorting.class,\n                                \"ACT_Pid\"), BY_PID_COMPARATOR, sorter)); // NOI18N\n        \n        menu.addSeparator();\n        \n        menu.add(new SortSwitch());\n\n        return menu;\n    }\n    \n    private Comparator<DataSource> byTimeComparator() {\n        return new Comparator<DataSource>() {\n            public int compare(DataSource d1, DataSource d2) {\n                return isFinishedAtBottom() ? checkUnavailable(d1, d2) : 0;\n            }\n        };\n    }\n\n    private Comparator<DataSource> byNameComparator() {\n        return new Comparator<DataSource>() {\n            public int compare(DataSource d1, DataSource d2) {\n                if (isFinishedAtBottom()) {\n                    int ret = checkUnavailable(d1, d2);\n                    if (ret != 0) return ret;\n                }\n                \n                DataSourceDescriptor dd1 = DataSourceDescriptorFactory.getDescriptor(d1);\n                DataSourceDescriptor dd2 = DataSourceDescriptorFactory.getDescriptor(d2);\n\n                return dd1.getName().compareTo(dd2.getName());\n            }\n        };\n    }\n\n    private Comparator<DataSource> byPidComparator() {\n        return new Comparator<DataSource>() {\n            public int compare(DataSource d1, DataSource d2) {\n                if (isFinishedAtBottom()) {\n                    int ret = checkUnavailable(d1, d2);\n                    if (ret != 0) return ret;\n                }\n                \n                boolean d1app = d1 instanceof Application;\n                boolean d2app = d2 instanceof Application;\n\n                if (!d1app && !d2app) return BY_NAME_COMPARATOR.compare(d1, d2);\n                else if (!d1app) return 1;\n                else if (!d2app) return -1;\n\n                int d1pid = ((Application)d1).getPid();\n                if (d1pid == Application.UNKNOWN_PID) d1pid = Integer.MAX_VALUE;\n                int d2pid = ((Application)d2).getPid();\n                if (d2pid == Application.UNKNOWN_PID) d2pid = Integer.MAX_VALUE;\n\n                if (d1pid == d2pid) return BY_NAME_COMPARATOR.compare(d1, d2);\n                else if (d1pid > d2pid) return 1;\n                else return -1;\n            }\n        };\n    }\n    \n    private static int checkUnavailable(DataSource d1, DataSource d2) {\n        Stateful s1 = d1 instanceof Stateful ? (Stateful)d1 : null;\n        Stateful s2 = d2 instanceof Stateful ? (Stateful)d2 : null;\n        \n        if (s1 == null || s2 == null || s1.getState() == s2.getState()) return 0;\n        \n        return s1.getState() == Stateful.STATE_UNAVAILABLE ? 1 : -1;\n    }\n    \n    private boolean isFinishedAtBottom() {\n        return prefs.getBoolean(PROP_APPS_FINISHED, false);\n    }\n\n    private ApplicationsSorting() {\n        prefs = NbPreferences.forModule(ApplicationsSorting.class);\n\n        sorter = new Sorter() {\n            public void sort(Comparator<DataSource> comparator) {\n                // Sort localhost\n                DataSourceDescriptor ld = DataSourceDescriptorFactory.getDescriptor(\n                                         Host.LOCALHOST);\n                if (ld instanceof LocalHostDescriptor) {\n                    ((LocalHostDescriptor)ld).setChildrenComparator(comparator);\n                    prefs.putInt(PROP_APPS_SORTING, COMPARATORS.indexOf(comparator));\n                }\n\n                // Sort remote hosts\n                Set<Host> remoteHosts = DataSourceRepository.sharedInstance().\n                                        getDataSources(Host.class);\n                for (Host host : remoteHosts) {\n                    if (host == Host.LOCALHOST) continue;\n                    DataSourceDescriptor rd = DataSourceDescriptorFactory.\n                                              getDescriptor(host);\n                    if (rd instanceof RemoteHostDescriptor)\n                        ((RemoteHostDescriptor)rd).setChildrenComparator(comparator);\n                }\n            }\n        };\n    }\n\n\n    private static class SortAction extends JRadioButtonMenuItem {\n\n        private final Sorter sorter;\n        private final Comparator<DataSource> comparator;\n        private boolean currentlySelected;\n\n        SortAction(String name, Comparator<DataSource> comparator, Sorter sorter) {\n            Mnemonics.setLocalizedText(this, name);\n            this.comparator = comparator;\n            this.sorter = sorter;\n        }\n\n        void updateAction() {\n            DataSourceDescriptor d = DataSourceDescriptorFactory.getDescriptor(\n                                     Host.LOCALHOST);\n            setEnabled(d instanceof LocalHostDescriptor);\n            currentlySelected = d.getChildrenComparator() == comparator;\n            setSelected(currentlySelected);\n        }\n\n        protected void fireActionPerformed(ActionEvent e) {\n            if (!currentlySelected) sorter.sort(comparator);\n        }\n\n    }\n    \n    private class SortSwitch extends JCheckBoxMenuItem {\n        \n        SortSwitch() {\n            Mnemonics.setLocalizedText(this, NbBundle.getMessage(ApplicationsSorting.class, \"ACT_Finished\")); // NOI18N\n            setSelected(isFinishedAtBottom());\n        }\n\n        protected void fireActionPerformed(ActionEvent e) {\n            prefs.putBoolean(PROP_APPS_FINISHED, isSelected());\n            \n            // Sort localhost\n            DataSourceDescriptor ld = DataSourceDescriptorFactory.getDescriptor(\n                                     Host.LOCALHOST);\n            if (ld instanceof LocalHostDescriptor) {\n                Comparator<DataSource> comparator = ld.getChildrenComparator();\n                ((LocalHostDescriptor)ld).setChildrenComparator(null);\n                ((LocalHostDescriptor)ld).setChildrenComparator(comparator);\n            }\n            \n            // Sort remote hosts\n            Set<Host> remoteHosts = DataSourceRepository.sharedInstance().\n                                    getDataSources(Host.class);\n            for (Host host : remoteHosts) {\n                if (host == Host.LOCALHOST) continue;\n                DataSourceDescriptor rd = DataSourceDescriptorFactory.\n                                          getDescriptor(host);\n                if (rd instanceof RemoteHostDescriptor) {\n                    Comparator<DataSource> comparator = rd.getChildrenComparator();\n                    ((RemoteHostDescriptor)rd).setChildrenComparator(null);\n                    ((RemoteHostDescriptor)rd).setChildrenComparator(comparator);\n                }\n            }\n        }\n\n    }\n\n    private static interface Sorter {\n\n        void sort(Comparator<DataSource> comparator);\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nLBL_ConnectionProperties=Connection\nDESCR_ConnectionProperties=Connection used to discover and manage the application\nMSG_ConnectionProperties=Host VisualVM instance is managed by direct VM connection.\n\nACT_SortApps=Sort &Applications By\nACT_TimeAdded=&Time Added\nACT_DisplayName=&Display Name\nACT_Pid=&Process ID\nACT_Finished=&Finished Applications at the Bottom\nACT_RemoveFinishedName=Remove &Finished Applications\nACT_RemoveFinishedDescr=Remove finished applications from the Applications view.\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/GeneralPropertiesProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport javax.swing.BorderFactory;\nimport javax.swing.JTextArea;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.core.properties.PropertiesPanel;\nimport org.graalvm.visualvm.core.properties.PropertiesProvider;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass GeneralPropertiesProvider extends PropertiesProvider<ApplicationSupport.CurrentApplication> {\n\n    GeneralPropertiesProvider() {\n        super(NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_ConnectionProperties\"), // NOI18N\n              NbBundle.getMessage(GeneralPropertiesProvider.class, \"DESCR_ConnectionProperties\"), // NOI18N\n              CATEGORY_GENERAL, 50);\n    }\n\n\n    public PropertiesPanel createPanel(ApplicationSupport.CurrentApplication dataSource) {\n        PropertiesPanel panel = new PropertiesPanel();\n        panel.setLayout(new BorderLayout());\n        JTextArea textArea = new JTextArea(NbBundle.getMessage(\n                GeneralPropertiesProvider.class, \"MSG_ConnectionProperties\")) { // NOI18N\n            public Dimension getMinimumSize() {\n                Dimension prefSize = getPreferredSize();\n                Dimension minSize = super.getMinimumSize();\n                prefSize.width = 0;\n                if (minSize.height < prefSize.height) return prefSize;\n                else return minSize;\n            }\n        };\n        textArea.setBorder(BorderFactory.createEmptyBorder());\n        textArea.setOpaque(false);\n        // Nimbus LaF doesn't respect setOpaque(false), this is a workaround.\n        // May cause delays for remote X sessions due to color transparency.\n        if (UIManager.getLookAndFeel().getID().equals(\"Nimbus\")) // NOI18N\n            textArea.setBackground(new Color(0, 0, 0, 0));\n        textArea.setEditable(false);\n        textArea.setLineWrap(true);\n        textArea.setWrapStyleWord(true);\n        textArea.setCaretPosition(0);\n        textArea.setMinimumSize(new Dimension(1, 1));\n        panel.add(textArea, BorderLayout.CENTER);\n\n        return panel;\n    }\n\n\n    public boolean supportsDataSource(ApplicationSupport.CurrentApplication dataSource) {\n        return true;\n    }\n\n    public void propertiesDefined(PropertiesPanel panel, ApplicationSupport.CurrentApplication dataSource) {}\n\n    public void propertiesChanged(PropertiesPanel panel, ApplicationSupport.CurrentApplication dataSource) {}\n\n    public void propertiesCancelled(PropertiesPanel panel, ApplicationSupport.CurrentApplication dataSource) {}\n\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.application;\n\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshotsSupport;\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n * \n * @author Jiri Sedlacek\n */\nfinal class Installer extends ModuleInstall {\n\n    public void restored() {\n        ApplicationSupport.getInstance();\n        ApplicationSnapshotsSupport.getInstance();\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/RemoveFinishedApplicationsAction.java",
    "content": "/*\n *  Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.application;\n\nimport java.awt.event.ActionEvent;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.core.ui.actions.MultiDataSourceAction;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.host.RemoteHostsContainer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class RemoveFinishedApplicationsAction extends MultiDataSourceAction<Host> {\n    \n    private static RemoveFinishedApplicationsAction alwaysEnabled;\n    private static RemoveFinishedApplicationsAction selectionAware;\n    \n    \n    private final boolean tracksSelection;\n    \n    \n    static synchronized RemoveFinishedApplicationsAction alwaysEnabled() {\n        if (alwaysEnabled == null) alwaysEnabled = new RemoveFinishedApplicationsAction(false);\n        return alwaysEnabled;\n    }\n    \n    static synchronized RemoveFinishedApplicationsAction selectionAware() {\n        if (selectionAware == null) selectionAware = new RemoveFinishedApplicationsAction(true);\n        return selectionAware;\n    }\n    \n\n    @Override\n    protected void actionPerformed(final Set<Host> hosts, ActionEvent actionEvent) {\n        DataSource.EVENT_QUEUE.post(new Runnable() {\n            public void run() {\n                if (tracksSelection) {\n                    removeApplications(hosts);\n                } else {\n                    Set<Host> _hosts = new HashSet<>();\n                    _hosts.add(Host.LOCALHOST);\n                    _hosts.addAll(RemoteHostsContainer.sharedInstance().getRepository().getDataSources(Host.class));\n                    removeApplications(_hosts);\n                }\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        updateState(ActionUtils.getSelectedDataSources(getScope()));\n                    }\n                });\n            }\n        });\n    }\n\n    @Override\n    protected boolean isEnabled(Set<Host> hosts) {\n        for (Host host : hosts) {\n            Set<Application> applications = host.getRepository().getDataSources(Application.class);\n            for (Application application : applications)\n                if (isRemovable(application)) return true;\n        }\n        \n        return false;\n    }\n    \n    \n    protected void updateState(Set<Host> hosts) {\n        if (tracksSelection) super.updateState(hosts);\n    }\n    \n    \n    private void removeApplications(Set<Host> hosts) {\n        for (Host host : hosts) {\n            Set<Application> applications = host.getRepository().getDataSources(Application.class);\n            for (Application application : applications) {\n                if (isRemovable(application)) host.getRepository().removeDataSource(application);\n            }\n        }\n    }\n    \n    \n    private static boolean isRemovable(Application application) {\n        return application.getState() == Stateful.STATE_UNAVAILABLE && application.supportsFinishedRemove();\n    }\n    \n    \n    private RemoveFinishedApplicationsAction(boolean tracksSelection) {\n        super(Host.class);\n        \n        this.tracksSelection = tracksSelection;\n        \n        putValue(NAME, NbBundle.getMessage(RemoveFinishedApplicationsAction.class, \"ACT_RemoveFinishedName\"));  // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(RemoveFinishedApplicationsAction.class, \"ACT_RemoveFinishedDescr\")); // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/jvm/DefaultJvm.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.jvm;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Properties;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass DefaultJvm extends Jvm {\n    \n    \n    DefaultJvm() {\n        \n    }\n    \n    public boolean is14() {\n        return false;\n    }\n    \n    public boolean is15() {\n        return false;\n    }\n    \n    public boolean is16() {\n        return false;\n    }\n    \n    public boolean is17() {\n        return false;\n    }\n        \n    public boolean is18() {\n        return false;\n    }\n    \n    public boolean is19() {\n        return false;\n    }\n    \n    public boolean is100() {\n        return false;\n    }\n\n    public boolean is110() {\n        return false;\n    }\n\n    public boolean isAttachable() {\n        return false;\n    }\n    \n    public String getCommandLine() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public String getJvmArgs() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public String getJvmFlags() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public String getMainArgs() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public String getMainClass() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public String getVmVersion() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public String getJavaVersion() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public String getJavaHome() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public String getVmInfo() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public String getVmName() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public String getVmVendor() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public Properties getSystemProperties() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public synchronized void addMonitoredDataListener(MonitoredDataListener l) {\n        throw new UnsupportedOperationException();\n    }\n    \n    public synchronized void removeMonitoredDataListener(MonitoredDataListener l) {\n        throw new UnsupportedOperationException();\n    }\n    \n    public String[] getGenName() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public boolean isDumpOnOOMEnabled() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public void setDumpOnOOMEnabled(boolean enabled) {\n        throw new UnsupportedOperationException();\n    }\n    \n    public boolean takeHeapDump(File outoutFile) throws IOException {\n        throw new UnsupportedOperationException();\n    }\n    \n    public String takeThreadDump() {\n        throw new UnsupportedOperationException();\n    }\n    \n    public HeapHistogram takeHeapHistogram() {\n        return null;\n    }\n    \n    public boolean isBasicInfoSupported() {\n        return false;\n    }\n    \n    public boolean isMonitoringSupported() {\n        return isClassMonitoringSupported() || isThreadMonitoringSupported() || isMemoryMonitoringSupported();\n    }\n    \n    public boolean isClassMonitoringSupported() {\n        return false;\n    }\n    \n    public boolean isThreadMonitoringSupported() {\n        return false;\n    }\n    \n    public boolean isMemoryMonitoringSupported() {\n        return false;\n    }\n    \n    public boolean isGetSystemPropertiesSupported() {\n        return false;\n    }\n    \n    public boolean isDumpOnOOMEnabledSupported() {\n        return false;\n    }\n    \n    public boolean isTakeHeapDumpSupported() {\n        return false;\n    }\n    \n    public boolean isTakeThreadDumpSupported() {\n        return false;\n    }\n    \n    public boolean isCpuMonitoringSupported() {\n        return false;\n    }\n    \n    public boolean isCollectionTimeSupported() {\n        return false;\n    }\n    \n    public MonitoredData getMonitoredData() {\n        return null;\n    }\n\n    public boolean isJfrAvailable() {\n        return false;\n    }\n\n    public List<Long> jfrCheck() {\n        return Collections.emptyList();\n    }\n\n    public String takeJfrDump(long recording, String fileName) {\n        throw new UnsupportedOperationException();\n    }\n\n    public boolean startJfrRecording(String name, String[] settings, String delay,\n            String duration, Boolean disk, String path, String maxAge, String maxSize,\n            Boolean dumpOnExit) {\n        throw new UnsupportedOperationException();\n    }\n\n    public boolean stopJfrRecording() {\n        throw new UnsupportedOperationException();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/jvm/HeapHistogram.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.jvm;\n\nimport java.util.Date;\nimport java.util.Set;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic abstract class HeapHistogram {\n    \n    public abstract Date getTime();\n    public abstract long getTotalInstances();\n    public abstract long getTotalBytes();\n    public abstract Set<ClassInfo> getHeapHistogram();\n    public abstract long getTotalHeapInstances();\n    public abstract long getTotalHeapBytes();\n    public abstract Set<ClassInfo> getPermGenHistogram();\n    public abstract long getTotalPerGenInstances();\n    public abstract long getTotalPermGenHeapBytes();\n    \n    public static abstract class ClassInfo {\n        \n        public abstract String getName();\n        public abstract long getInstancesCount();\n        public abstract long getBytes();\n        \n        public int hashCode() {\n            return getName().hashCode();\n        }\n        \n        public boolean equals(Object obj) {\n            if (obj instanceof ClassInfo) {\n                return getName().equals(((ClassInfo)obj).getName());\n            }\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/jvm/Jvm.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.jvm;\n\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.List;\nimport java.util.Properties;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.Model;\n\n/**\n * This class encapsulates functionality of the target Java application. Use\n * {@link JvmFactory#getJVMFor(Application )} to get instance of Jvm class.\n * @author Tomas Hurka\n */\npublic abstract class Jvm extends Model {\n    protected static final Logger LOGGER = Logger.getLogger(Jvm.class.getName());\n    \n    /**\n     * Property name for {@link #isDumpOnOOMEnabled()}. \n     * If property dumpOnOOMEnabled changes its state, property change is fired\n     * with this property name.\n     */\n    public static final String PROPERTY_DUMP_OOME_ENABLED = \"prop_oome\";    // NOI18N\n    \n    private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);\n    \n    /**\n     * Tests if target JVM is JRE 1.4.\n     * @return <CODE>true</CODE> if JVM is JRE 1.4, <CODE>false</CODE> otherwise\n     */\n    public abstract boolean is14();\n\n    /**\n     * Tests if target JVM is JRE 1.5.\n     * @return <CODE>true</CODE> if JVM is JRE 1.5, <CODE>false</CODE> otherwise\n     */\n    public abstract boolean is15();\n\n    /**\n     * Tests if target JVM is JRE 1.6.\n     * @return <CODE>true</CODE> if JVM is JRE 1.6, <CODE>false</CODE> otherwise\n     */\n    public abstract boolean is16();\n\n    /**\n     * Tests if target JVM is JRE 1.7.\n     * @return <CODE>true</CODE> if JVM is JRE 1.7, <CODE>false</CODE> otherwise\n     */\n    public abstract boolean is17();\n\n    /**\n     * Tests if target JVM is JRE 1.8.\n     * @return <CODE>true</CODE> if JVM is JRE 1.8, <CODE>false</CODE> otherwise\n     */\n    public boolean is18() {\n        // default implementation for backward compatibility\n        return false;\n    }\n\n    /**\n     * Tests if target JVM is JRE 1.9.\n     * @return <CODE>true</CODE> if JVM is JRE 1.9, <CODE>false</CODE> otherwise\n     */\n    public boolean is19() {\n        // default implementation for backward compatibility\n        return false;\n    }\n\n    /**\n     * Tests if target JVM is JRE 10.\n     * @return <CODE>true</CODE> if JVM is JRE 10, <CODE>false</CODE> otherwise\n     */\n    public boolean is100() {\n        // default implementation for backward compatibility\n        return false;\n    }\n\n    /**\n     * Tests if target JVM is JRE 11.\n     * @return <CODE>true</CODE> if JVM is JRE 11, <CODE>false</CODE> otherwise\n     */\n    public boolean is110() {\n        // default implementation for backward compatibility\n        return false;\n    }\n\n    /**\n     * Tests if VisualVM can attach to target JVM via\n     * <a href=http://download.oracle.com/javase/6/docs/technotes/guides/attach/index.html>Attach API</a>.\n     * @return <CODE>true</CODE> if VisualVM can attach to target JVMvia Attach API, <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isAttachable();\n\n    /**\n     * Tests if target JVM supports getting basic JVM information. This includes\n     * getCommandLine(), getJvmArgs(), getJvmFlags(), getMainClass(),\n     * getVmVersion(), getJavaHome(), getVMInfo(), getVMName() methods.\n     * @return <CODE>true</CODE> if target JVM supports basic JVM information,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isBasicInfoSupported();\n\n    /**\n     * Return the command line for the target Java application.\n     * @return Returns the command line of the target Java application.\n     */\n    public abstract String getCommandLine();\n\n    /**\n     * Return the JVM arguments for the target Java application.\n     * @return Returns the arguments passed to the JVM for the target Java application\n     */\n    public abstract String getJvmArgs();\n\n    /**\n     * Return the JVM flags for the target Java application.\n     * @return Returns the flags passed to the JVM for the target Java application\n     */\n    public abstract String getJvmFlags();\n\n    /**\n     * Return the arguments to the main class for the target Java application.\n     * @return Returns the arguments to the main class.\n     */\n    public abstract String getMainArgs();\n\n    /**\n     * Return the main class for the target Java application or the name of the jar file if the application\n     * was started with the <code>-jar</code> option.\n     * @return Returns the main class of the target Java application\n     * or the name of the jar file.\n     */\n    public abstract String getMainClass();\n\n    /**\n     * Returns the VM version for the target Java application.\n     * @return Returns the version of the target Java application\n     */\n    public abstract String getVmVersion();\n\n    /**\n     * Returns the Java version for the target Java application.\n     * @return Returns the Java version of the target Java application\n     */\n    public abstract String getJavaVersion();\n    \n    /**\n     * Returns the {@code java.home} property for the target Java application.\n     * \"java.home\" property specify the directory\n     * into which the JRE was installed.\n     * @return Returns {@code java.home} property.\n     */\n    public abstract String getJavaHome();\n\n    /**\n     * Returns the java.vm.info property for the target Java application.\n     * the java.vm.info property (which is reflected in the text displayed by \"java -version\")\n     * @return Returns java.vm.info property.\n     */\n    public abstract String getVmInfo();\n\n    /**\n     * Returns the java.vm.name property for the target Java application.\n     * java.vm.name property is Java Virtual Machine implementation name.\n     * @return Returns java.vm.name property.\n     */\n    public abstract String getVmName();\n    \n    /**\n     * Returns the java.vm.vendor property for the target Java application.\n     * java.vm.vendor property is Java Virtual Machine vendor name.\n     * @return Returns java.vm.vendor property.\n     */\n    public abstract String getVmVendor();\n\n    /**\n     * Tests if target JVM monitoring is supported. If true, JVM fires\n     * {@link MonitoredDataListener#monitoredDataEvent(MonitoredData )}\n     * @return <CODE>true</CODE> if JVM is supports monitoring,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isMonitoringSupported();\n\n    /**\n     * Tests if target JVM supports class monitoring. If true,\n     * methods getLoadedClasses(), getSharedLoadedClasses(),\n     * getSharedUnloadedClasses(), getUnloadedClasses()\n     * from {@link MonitoredData} returns meaningful data.\n     * @return <CODE>true</CODE> if JVM supports class monitoring,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isClassMonitoringSupported();\n\n    /**\n     * Tests if target JVM supports thread monitoring. If true,\n     * methods getThreadsDaemon(), getThreadsLive(),\n     * getThreadsLivePeak(), getThreadsStarted()\n     * from {@link MonitoredData} returns meaningful data.\n     * @return <CODE>true</CODE> if JVM supports thread monitoring,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isThreadMonitoringSupported();\n\n    /**\n     * Tests if target JVM supports thread monitoring. If true,\n     * methods getGenCapacity(), getGenUsed(), getGenMaxCapacity()\n     * from {@link MonitoredData} returns meaningful data.\n     * @return <CODE>true</CODE> if JVM supports memory monitoring,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isMemoryMonitoringSupported();\n\n    /**\n     * Tests if target JVM supports process CPU time monitoring. If true,\n     * methods getProcessCpuTime()\n     * from {@link MonitoredData} returns meaningful data.\n     * @return <CODE>true</CODE> if JVM supports process CPU time monitoring,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isCpuMonitoringSupported();\n    \n    /**\n     * Tests if target JVM supports Garbage collection time monitoring. If true,\n     * methods getCollectionTime()\n     * from {@link MonitoredData} returns meaningful data.\n     * @return <CODE>true</CODE> if JVM supports Garbage collection time monitoring,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isCollectionTimeSupported();\n\n    /**\n     * Adds a {@link MonitoredDataListener} to the listener list.\n     * @param l the MonitoredDataListener to be added\n     */\n    public abstract void addMonitoredDataListener(MonitoredDataListener l);\n\n    /**\n     * Removes a {@link MonitoredDataListener} to the listener list.\n     * @param l the MonitoredDataListener to be removed\n     */\n    public abstract void removeMonitoredDataListener(MonitoredDataListener l);\n\n    /**\n     * Returns the names of Java virtual machine spaces.\n     *\n     * @return Index 0 is the display name for heap,\n     * index 1 is display name for Permanent Generation (PermGen)\n     */\n    public abstract String[] getGenName();\n\n    /**\n     * Tests if it is possible to obtain system properties from target JVM.\n     * @return <CODE>true</CODE> if JVM supports system properties,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isGetSystemPropertiesSupported();\n\n    /**\n     * Returns a map of names and values of all system properties of target JVM.\n     * @return a map of names and values of all system properties.\n     */\n    public abstract Properties getSystemProperties();\n\n    /**\n     * Tests if it is possible to set HeapDumpOnOutOfMemoryError flag in target JVM.\n     * @return <CODE>true</CODE> if JVM supports setting of HeapDumpOnOutOfMemoryError flag,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isDumpOnOOMEnabledSupported();\n\n    /**\n     * Gets value of HeapDumpOnOutOfMemoryError flag from target JVM.\n     * @return returns value of HeapDumpOnOutOfMemoryError flag.\n     */\n    public abstract boolean isDumpOnOOMEnabled();\n\n    /**\n     * sets HeapDumpOnOutOfMemoryError flag on target JVM.\n     * @param enabled new value of HeapDumpOnOutOfMemoryError flag\n     */\n    public abstract void setDumpOnOOMEnabled(boolean enabled);\n\n    /**\n     * Tests if it is possible to obtain heap dump from target JVM.\n     * @return <CODE>true</CODE> if JVM supports heap dump,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isTakeHeapDumpSupported();\n\n    /**\n     * Dumps the heap to the <tt>outputFile</tt> file in the same\n     * format as the hprof heap dump.\n     * @param outputFile {@link File} where heap dump will be stored\n     * @return <CODE>true</CODE> if heap dump was created,\n     * <CODE>false</CODE> otherwise\n     * @throws java.io.IOException I/O error\n     */\n    public abstract boolean takeHeapDump(File outputFile) throws IOException;\n\n    /**\n     * Tests if it is possible to obtain thread dump from target JVM.\n     * @return <CODE>true</CODE> if JVM supports thread dump,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isTakeThreadDumpSupported();\n\n    /**\n     * Takes thread dump of target JVM.\n     * @return Returns {@link String} of the thread dump from target JVM.\n     */\n    public abstract String takeThreadDump();\n    \n    /**\n     * Takes heap histogram of target Application.\n     * @return Returns {@link HeapHistogram} of the heap from target Application.\n     */\n    public HeapHistogram takeHeapHistogram() {\n        // default implementation for backward compatibility\n        return null;        \n    }\n     \n    /**\n     * Returns the number of processors available to the Java virtual machine.\n     *\n     * <p> This value may change during a particular invocation of the virtual\n     * machine.  Applications that are sensitive to the number of available\n     * processors should therefore occasionally poll this property and adjust\n     * their resource usage appropriately. </p>\n     *\n     * @return  the maximum number of processors available to the virtual\n     *          machine; never smaller than one\n     */\n    public int getAvailableProcessors() {\n        // default implementation\n        return 1;\n    }\n\n    /**\n     * Tests if it is possible to use JFR in target JVM.\n     *\n     * @return <CODE>true</CODE> if JVM supports JFR,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isJfrAvailable();\n\n    /**\n     * Checks running JFR recording(s) of target Application.\n     *\n     * @return returns List of recording id-s. If no recordings are in progress,\n     * empty List is returned.\n     */\n    public abstract List<Long> jfrCheck();\n\n    /**\n     * Takes JFR dump of target Application.\n     * The JFR snapshot is written to the <tt>fileName</tt> file.\n     *\n     * @param recording id of recording obtained using {@link #jfrCheck()}\n     * @param fileName path to file, where JFR snapshot will be written\n     * @return returns <CODE>null</CODE> if operation was successful.\n     */\n    public abstract String takeJfrDump(long recording, String fileName);\n\n    /**\n     * Starts a new JFR recording.\n     *\n     * @param name optional name that can be used to identify recording.\n     * @param settings names of settings files to use, i.e. \"default\" or\n     *        \"default.jfc\".\n     * @param delay optional delay recording start with (s)econds, (m)inutes,\n     *        (h)ours, or (d)ays, e.g. 5h.\n     * @param duration optional duration of recording in (s)econds, (m)inutes,\n     *        (h)ours, or (d)ays, e.g. 300s.\n     * @param disk if recording should be persisted to disk\n     * @param path file path where recording data should be written\n     * @param maxAge optional maximum time to keep recorded data (on disk) in \n     *        (s)econds, (m)inutes, (h)ours, or (d)ays, e.g. 60m, \n     *        or <code>0</code> if no limit should be set.\n     * @param maxSize optional maximum amount of bytes to keep (on disk) in \n     *        (k)B, (M)B or (G)B, e.g. 500M, or <code>0</code> if no \n     *        limit should be set.\n     * @param dumpOnExit if recording should dump on exit\n     *\n     * @return true if recording was successfully started.\n     */\n    public abstract boolean startJfrRecording(String name, String[] settings, \n            String delay, String duration, Boolean disk, String path, \n            String maxAge, String maxSize, Boolean dumpOnExit);\n\n    /**\n     * Stops JFR recording.\n     * @return true if recording was successfully stopped.\n     */\n    public abstract boolean stopJfrRecording();\n\n    /**\n     * Provides access to current values of monitored data in instance of {@link MonitoredData}. \n     * The methods may return <CODE>null</CODE> if the {@link MonitoredData} are not available\n     * or are not supported by particular {@link Jvm} instance.\n     * @return instance of {@link MonitoredData} with current values of monitored data or\n     * <CODE>null</CODE> if the monitored data cannot be retrieved.\n     */\n    public abstract MonitoredData getMonitoredData();\n    \n    /**\n     * Add a PropertyChangeListener to the listener list.\n     * The listener is registered for all properties.\n     * The same listener object may be added more than once, and will be called\n     * as many times as it is added.\n     * If <code>listener</code> is null, no exception is thrown and no action\n     * is taken.\n     *\n     * @param listener  The PropertyChangeListener to be added\n     */\n    public final void addPropertyChangeListener(PropertyChangeListener listener) {\n        changeSupport.addPropertyChangeListener(listener);\n    }\n\n    /**\n     * Remove a PropertyChangeListener from the listener list.\n     * This removes a PropertyChangeListener that was registered\n     * for all properties.\n     * If <code>listener</code> was added more than once to the same event\n     * source, it will be notified one less time after being removed.\n     * If <code>listener</code> is null, or was never added, no exception is\n     * thrown and no action is taken.\n     *\n     * @param listener  The PropertyChangeListener to be removed\n     */\n    public final void removePropertyChangeListener(PropertyChangeListener listener) {\n        changeSupport.removePropertyChangeListener(listener);\n    }\n    \n    /**\n     * Report a bound property update to any registered listeners.\n     * No event is fired if old and new are equal and non-null.\n     *\n     * @param propertyName  The programmatic name of the property\n     *\t\tthat was changed.\n     * @param oldValue  The old value of the property.\n     * @param newValue  The new value of the property.\n     */\n    protected final void firePropertyChange(String propertyName, Object oldValue, Object newValue) {\n        changeSupport.firePropertyChange(propertyName, oldValue, newValue);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/jvm/JvmFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.jvm;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.ModelFactory;\nimport org.graalvm.visualvm.core.model.ModelProvider;\n\n/**\n * The JVMFactory class is a factory class for getting the\n * {@link Jvm} representation  for the {@link Application}.\n * \n * @author Tomas Hurka\n */\npublic final class JvmFactory extends ModelFactory<Jvm,Application> implements ModelProvider<Jvm,Application> {\n\n    private static JvmFactory jvmFactory;\n\n    private JvmFactory() {\n    }\n    \n    /**\n     * Getter for the default version of the JvmFactory.\n     * @return instance of {@link JvmFactory}.\n     */\n    public static synchronized JvmFactory getDefault() {\n        if (jvmFactory == null) {\n            jvmFactory = new JvmFactory();\n            jvmFactory.registerProvider(jvmFactory);\n        }\n        return jvmFactory;\n    }\n    \n    /**\n     * Factory method for obtaining {@link Jvm} for {@link Application}. Note that there\n     * is only one instance of {@link Jvm} for a concrete application. This {@link Jvm}\n     * instance is cached.\n     * @param app application \n     * @return {@link Jvm} instance which encapsulates application's JVM.\n     */\n    public static Jvm getJVMFor(Application app) {\n        return getDefault().getModel(app);\n    }\n    \n    /**\n     * Default {@link ModelProvider} implementation, which creates \n     * dummy {@link Jvm} instances. If you want to extend JvmFactory use \n     * {@link JvmFactory#registerProvider(ModelProvider )} to register the new instances\n     * of {@link ModelProvider} for the different types of {@link Application}.\n     * @param app application\n     * @return dummy instance of {@link Jvm}\n     */\n    public Jvm createModelFor(Application app) {\n        return new DefaultJvm();\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/jvm/MonitoredData.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.jvm;\n\n/**\n * This class encapsulates non-static information from JVM. Instances of MonitoredData\n * is periodically fired by {@link Jvm} via {@link MonitoredDataListener}\n * @author Tomas Hurka\n */\npublic abstract class MonitoredData {\n    \n    protected long loadedClasses;\n    protected long sharedLoadedClasses;\n    protected long sharedUnloadedClasses;\n    protected long unloadedClasses;\n    protected long threadsDaemon;\n    protected long threadsLive;\n    protected long threadsLivePeak;\n    protected long threadsStarted;\n    protected long applicationTime;\n    protected long upTime;\n    protected long[] genCapacity;\n    protected long[] genUsed;\n    protected long[] genMaxCapacity;\n    protected long processCpuTime;\n    protected long collectionTime;\n    protected Jvm monitoredVm;\n    \n    \n    /**\n     * Returns the total number of classes that have been loaded since\n     * the Java virtual machine has started execution.\n     *\n     * @return the total number of classes loaded.\n     *\n     */\n    public long getLoadedClasses() {\n        return loadedClasses;\n    }\n    \n    /**\n     * Returns the total number of shared classes that have been loaded since\n     * the Java virtual machine has started execution.\n     *\n     * @return the total number of shared classes loaded.\n     *\n     */\n    public long getSharedLoadedClasses() {\n        return sharedLoadedClasses;\n    }\n    \n    /**\n     * Returns the total number of shared classes unloaded since the Java virtual machine\n     * has started execution.\n     *\n     * @return the total number of unloaded shared classes.\n     */\n    public long getSharedUnloadedClasses() {\n        return sharedUnloadedClasses;\n    }\n    \n    /**\n     * Returns the total number of classes unloaded since the Java virtual machine\n     * has started execution.\n     *\n     * @return the total number of unloaded classes.\n     */\n    public long getUnloadedClasses() {\n        return unloadedClasses;\n    }\n    \n    /**\n     * Returns the current number of live daemon threads.\n     *\n     * @return the current number of live daemon threads.\n     */\n    public long getThreadsDaemon() {\n        return threadsDaemon;\n    }\n    \n    /**\n     * Returns the current number of live threads including both\n     * daemon and non-daemon threads.\n     *\n     * @return the current number of live threads.\n     */\n    public long getThreadsLive() {\n        return threadsLive;\n    }\n    \n    /**\n     * Returns the peak live thread count since the Java virtual machine\n     * started\n     *\n     * @return the peak live thread count.\n     */\n    public long getThreadsLivePeak() {\n        return threadsLivePeak;\n    }\n    \n    /**\n     * Returns the total number of threads created and also started\n     * since the Java virtual machine started.\n     *\n     * @return the total number of threads started.\n     */\n    public long getThreadsStarted() {\n        return threadsStarted;\n    }\n    \n    /**\n     * Returns the time spent in application code (excluding time in safe points)\n     * since the Java virtual machine start.\n     *\n     * @return the application time in milliseconds. Returns 0 if unsupported.\n     */\n    public long getApplicationTime() {\n        return applicationTime;\n    }\n    \n    /**\n     * Returns {@link Jvm} for which this information is valid.\n     *\n     * @return instance of {@link Jvm}\n     */\n    public Jvm getMonitoredVm() {\n        return monitoredVm;\n    }\n    \n    /**\n     * Returns the uptime of the Java virtual machine in milliseconds.\n     *\n     * @return uptime of the Java virtual machine in milliseconds.\n     */\n    public long getUpTime() {\n        return upTime;\n    }\n    \n    /**\n     * Returns the amount of memory in bytes that is available for\n     * the Java virtual machine to use.\n     *\n     * @return the amount of memory in bytes. Index 0 is for heap,\n     * index 1 is for Permanent Generation (PermGen)\n     *\n     */\n    public long[] getGenCapacity() {\n        return genCapacity.clone();\n    }\n    \n    /**\n     * Returns the currently used amount of memory in bytes.\n     *\n     * @return the amount of currently used memory in bytes. Index 0 is for heap,\n     * index 1 is for Permanent Generation (PermGen)\n     *\n     */\n    public long[] getGenUsed() {\n        return genUsed.clone();\n    }\n    \n    /**\n     * Returns the maximum amount of memory in bytes that is available for\n     * the Java virtual machine to use.\n     *\n     * @return the maximum amount of memory in bytes. Index 0 is for heap,\n     * index 1 is for Permanent Generation (PermGen)\n     *\n     */\n    public long[] getGenMaxCapacity() {\n        return genMaxCapacity.clone();\n    }\n    \n    /**\n     * Returns the approximate accumulated process CPU elapsed time\n     * in nanoseconds.  This method returns <tt>-1</tt> if the collection\n     * elapsed time is undefined for this collector.\n     *\n     * @return the approximate accumulated process CPU elapsed time\n     * in nanoseconds.\n     */\n    public long getProcessCpuTime() {\n        return processCpuTime;\n    }\n    \n    /**\n     * Returns the approximate accumulated (for all collectors) collection elapsed time\n     * in milliseconds.  This method returns <tt>-1</tt> if the collection\n     * elapsed time is undefined for this collector.\n     * <p>\n     * The Java virtual machine implementation may use a high resolution\n     * timer to measure the elapsed time.  This method may return the\n     * same value even if the collection count has been incremented\n     * if the collection elapsed time is very short.\n     *\n     * @return the approximate accumulated collection elapsed time\n     * in milliseconds.\n     */\n    public long getCollectionTime() {\n        return collectionTime;\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/jvm/MonitoredDataListener.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.jvm;\n\n/**\n * \"monitoredDataEvent\" event is periodically fired by {@link Jvm}.\n * \n * @author Tomas Hurka\n */\npublic interface MonitoredDataListener {\n\n  /**\n   * This method is periodically called by JVM.\n   * @param data {@link MonitoredData} object describing the monitored data. \n   */   \n  void monitoredDataEvent(MonitoredData data);\n\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/jvm/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * This package uses Jvmstat, JMX, SA and Attach API to present unifiled view for JVM.\n * The implemnetation uses the fastest method to get the requested infomation or operation.\n */\npackage org.graalvm.visualvm.application.jvm;\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/options/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\nMSG_NO_APP_PID=Cannot open application with pid {0}.\nMSG_NO_APP_ID=Cannot open requested application.\nMSG_OPENPID=open application with process id <arg>\nMSG_OPENID=open application with id <arg>\nMSG_PID_FAILED=Incorrect pid defined ({0})\nMSG_VIEWIDX_FAILED=Incorrect view index defined ({0})\n\n\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/options/Open.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.application.options;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.swing.Timer;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasource.DataSourceContainer;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.host.Host;\nimport org.netbeans.api.sendopts.CommandException;\nimport org.netbeans.spi.sendopts.Env;\nimport org.netbeans.spi.sendopts.Option;\nimport org.netbeans.spi.sendopts.OptionProcessor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n * Handling of --openpid and --openid commandline option\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=OptionProcessor.class)\npublic final class Open extends OptionProcessor { // TODO: rewrite to use org.graalvm.visualvm.application.ApplicationFinder\n    private Option openpid = Option.requiredArgument(Option.NO_SHORT_NAME,\"openpid\");    // NOI18N\n    private Option openid = Option.requiredArgument(Option.NO_SHORT_NAME,\"openid\");    // NOI18N\n    private static final int TIMEOUT = Integer.getInteger(\"visualvm.search.process.timeout\", 5000); // NOI18N\n    private static final String ID = \"visualvm.id\"; // NOI18N\n\n    public Open() {\n        openpid = Option.shortDescription(openpid,\"org.graalvm.visualvm.application.options.Bundle\",\"MSG_OPENPID\"); // NOI18N\n        openid = Option.shortDescription(openid,\"org.graalvm.visualvm.application.options.Bundle\",\"MSG_OPENID\"); // NOI18N\n    }\n\n    protected Set<Option> getOptions() {\n        Set<Option> options = new HashSet<>();\n        options.add(openpid);\n        options.add(openid);\n        return options;\n    }\n\n    protected void process(Env env, Map<Option, String[]> optionValues) throws CommandException {\n        Integer pid = null;\n        String id = null;\n        String[] pids = optionValues.get(openpid);\n        String[] ids = optionValues.get(openid);\n        \n        Integer viewIndex = null;\n        \n        if (pids != null && pids.length>0) {\n            String pidStr = pids[0];\n            int idx = pidStr.indexOf('@'); // NOI18N\n            if (idx > -1) {\n                try {\n                    viewIndex = Integer.valueOf(pidStr.substring(idx + 1));\n                } catch (NumberFormatException e) {\n                    throw new CommandException(0, NbBundle.getMessage(Open.class,\"MSG_VIEWIDX_FAILED\",new Object[] {e.toString()})); // NOI18N\n                }\n                pidStr = pidStr.substring(0, idx);\n            }\n            try {\n                pid = Integer.valueOf(pidStr);\n            } catch (NumberFormatException e) {\n                throw new CommandException(0, NbBundle.getMessage(Open.class,\"MSG_PID_FAILED\",new Object[] {e.toString()})); // NOI18N\n            }\n        }\n        if (ids != null && ids.length>0) {\n            String idStr = ids[0];\n            int idx = idStr.indexOf('@'); // NOI18N\n            if (idx > -1) {\n                try {\n                    viewIndex = Integer.valueOf(idStr.substring(idx + 1));\n                } catch (NumberFormatException e) {\n                    throw new CommandException(0, NbBundle.getMessage(Open.class,\"MSG_VIEWIDX_FAILED\",new Object[] {e.toString()})); // NOI18N\n                }\n                idStr = idStr.substring(0, idx);\n            }\n            id = \"-D\"+ID+\"=\"+idStr; // NOI18N\n        }\n        \n        DataSourceContainer container = Host.LOCALHOST.getRepository();\n        Set<Application> apps = container.getDataSources(Application.class);\n        if (openApplication(id, pid, viewIndex, apps)) {\n            return;\n        }\n        Listener l = new Listener(id, pid, viewIndex, container);\n        container.addDataChangeListener(l,Application.class);\n    }\n\n    private boolean openApplication(final String id, final Integer pid, final Integer viewIndex, final Set<Application> apps) {\n        for (Application app : apps) {\n            if (pid != null && app.getPid() == pid.intValue()) {\n                int index = viewIndex != null ? viewIndex.intValue() - 1 : 0;\n                DataSourceWindowManager.sharedInstance().openDataSource(app, true, index);\n                return true;\n            }\n            if (id != null) {\n                Jvm jvm = JvmFactory.getJVMFor(app);\n                if (jvm.isBasicInfoSupported()) {\n                    String args = jvm.getJvmArgs();\n                    if (args != null && args.contains(id)) {\n                        int index = viewIndex != null ? viewIndex.intValue() - 1 : 0;\n                        DataSourceWindowManager.sharedInstance().openDataSource(app, true, index);\n                        return true;                        \n                    }\n                }\n            }\n        }\n        return false;\n    }\n\n    private class Listener implements DataChangeListener<Application>, ActionListener {\n        private final Integer pid;\n        private final String id;\n        private final Integer viewIndex;\n        private final DataSourceContainer container;\n        private volatile boolean removed;\n        private final Timer timer;\n\n        private Listener(String i,Integer p,Integer x,DataSourceContainer c) {\n            id = i;\n            pid = p;\n            viewIndex = x;\n            container = c;\n            timer = new Timer(TIMEOUT,this);\n            timer.start();\n        }\n\n        public synchronized void dataChanged(DataChangeEvent<Application> event) {\n            Set<Application> added = event.getAdded();\n            if (openApplication(id,pid,viewIndex,added)) {\n                if (!removed) {\n                    container.removeDataChangeListener(this);\n                    removed = true;\n                    timer.stop();\n                }\n            }\n        }\n\n        public synchronized void actionPerformed(ActionEvent e) {\n            if (!removed) {\n                container.removeDataChangeListener(this);\n                removed = true;\n                String msg = \"\"; // NOI18N\n                if (pid != null) {\n                    msg = NbBundle.getMessage(Open.class,\"MSG_NO_APP_PID\",new Object[] {Integer.toString(pid)});    // NOI18N\n                }\n                if (id != null) {\n                    msg = NbBundle.getMessage(Open.class,\"MSG_NO_APP_ID\");    // NOI18N\n                }\n                \n                NotifyDescriptor desc = new NotifyDescriptor.Message(msg,NotifyDescriptor.WARNING_MESSAGE);\n                DialogDisplayer.getDefault().notifyLater(desc);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Support for applications in VisualVM.\n */\npackage org.graalvm.visualvm.application;\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/resources/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Application\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    \n    <folder name=\"Actions\">\n        <folder name=\"Other\">\n            <file name=\"org-graalvm-visualvm-application-snapshot-AddApplicationSnapshotAction-alwaysEnabled.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.application.snapshot.AddApplicationSnapshotAction.alwaysEnabled\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-application-RemoveFinishedApplicationsAction-alwaysEnabled.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.application.RemoveFinishedApplicationsAction.alwaysEnabled\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"Menu\">\n        <folder name=\"File\">\n            <file name=\"org-graalvm-visualvm-application-snapshot-AddApplicationSnapshotAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-application-snapshot-AddApplicationSnapshotAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"800\"/>\n            </file>\n        </folder>        \n        \n        <folder name=\"Applications\">\n            <file name=\"org-graalvm-visualvm-application-snapshot-ApplicationSnapshotAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-application-snapshot-ApplicationSnapshotAction.instance\"/>\n                <attr name=\"position\" intvalue=\"2500\"/>\n            </file>\n        </folder>\n\n        <folder name=\"View\">\n            <file name=\"org-graalvm-visualvm-application-ApplicationsSorting.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.application.ApplicationsSorting.instance\"/>\n                <attr name=\"position\" intvalue=\"850\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"Toolbars\">\n        <folder name=\"DataSource\">\n            <file name=\"org-graalvm-visualvm-application-snapshot-AddApplicationSnapshotAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-application-snapshot-AddApplicationSnapshotAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"400\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"VisualVM\">\n        <folder name=\"Actions\">\n            <file name=\"org-graalvm-visualvm-application-snapshot-ApplicationSnapshotAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.application.snapshot.ApplicationSnapshotAction.instance\"/>\n            </file>\n        </folder>\n\n        <folder name=\"ExplorerPopupSelection\">\n            \n            <file name=\"org-graalvm-visualvm-application-snapshot-AddApplicationSnapshotAction-selectionAware.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.application.snapshot.AddApplicationSnapshotAction.selectionAware\"/>\n                <attr name=\"position\" intvalue=\"0\"/>\n                <attr name=\"default\" boolvalue=\"true\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-application-snapshot-ApplicationSnapshotAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-application-snapshot-ApplicationSnapshotAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1500\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-application-RemoveFinishedApplicationsAction-selectionAware.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.application.RemoveFinishedApplicationsAction.selectionAware\"/>\n                <attr name=\"position\" intvalue=\"1600\"/>\n            </file>\n            \n        </folder>\n        \n        <folder name=\"ExplorerPopupNoSelection\">\n            \n            <file name=\"org-graalvm-visualvm-application-snapshot-AddApplicationSnapshotAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-application-snapshot-AddApplicationSnapshotAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"400\"/>\n            </file>\n            \n            <file name=\"ExplorerPopupNoSelection-Separator-1000.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"1000\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-application-RemoveFinishedApplicationsAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-application-RemoveFinishedApplicationsAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"1100\"/>\n            </file>\n            \n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/snapshot/AddApplicationSnapshotAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.application.snapshot;\n\nimport java.awt.Image;\nimport java.awt.event.ActionEvent;\nimport java.util.Set;\nimport javax.swing.Action;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsContainer;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n    \n/**\n *\n * @author Jiri Sedlacek\n */\nclass AddApplicationSnapshotAction extends SingleDataSourceAction<SnapshotsContainer> {\n    \n    private static final String ICON_PATH = \"org/graalvm/visualvm/application/resources/addApplicationSnapshot.png\";  // NOI18N\n    private static final Image ICON =  ImageUtilities.loadImage(ICON_PATH);\n    \n    private boolean tracksSelection = false;\n    \n    \n    private static AddApplicationSnapshotAction alwaysEnabled;\n    private static AddApplicationSnapshotAction selectionAware;\n    \n    \n    static synchronized AddApplicationSnapshotAction alwaysEnabled() {\n        if (alwaysEnabled == null) {\n            alwaysEnabled = new AddApplicationSnapshotAction();\n            alwaysEnabled.putValue(SMALL_ICON, new ImageIcon(ICON));\n            alwaysEnabled.putValue(\"iconBase\", ICON_PATH);  // NOI18N\n        }\n        return alwaysEnabled;\n    }\n    \n    static synchronized AddApplicationSnapshotAction selectionAware() {\n        if (selectionAware == null) {\n            selectionAware = new AddApplicationSnapshotAction();\n            selectionAware.tracksSelection = true;\n        }\n        return selectionAware;\n    }\n    \n    \n    protected void actionPerformed(SnapshotsContainer snapshotsContainer, ActionEvent actionEvent) {\n        ApplicationSnapshotConfigurator newSnapshotConfiguration = ApplicationSnapshotConfigurator.defineSnapshot();\n        if (newSnapshotConfiguration != null) {\n            ApplicationSnapshotProvider provider = ApplicationSnapshotsSupport.getInstance().getSnapshotProvider();\n            provider.addSnapshotArchive(newSnapshotConfiguration.getSnapshotFile(), newSnapshotConfiguration.deleteSourceFile());\n        }\n    }\n    \n    protected boolean isEnabled(SnapshotsContainer snapshotsContainer) {\n        return true;\n    }\n    \n    protected void updateState(Set<SnapshotsContainer> snapshotsContainerSet) {\n        if (tracksSelection) super.updateState(snapshotsContainerSet);\n    }\n    \n    \n    private AddApplicationSnapshotAction() {\n        super(SnapshotsContainer.class);\n        putValue(Action.NAME, NbBundle.getMessage(AddApplicationSnapshotAction.class, \"LBL_Add_Application_Snapshot\")); // NOI18N\n        putValue(Action.SHORT_DESCRIPTION, NbBundle.getMessage(AddApplicationSnapshotAction.class, \"ToolTip_Add_Application_Snapshot\"));    // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/snapshot/ApplicationSnapshot.java",
    "content": "/*\n *  Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.application.snapshot;\n\nimport java.io.File;\nimport javax.swing.JFileChooser;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n * Snapshot of an Application.\n *\n * @author Jiri Sedlacek\n */\npublic final class ApplicationSnapshot extends Snapshot {\n    \n    private Storage storage;\n    \n    \n    /**\n     * Creates new instance of an application snapshot.\n     * \n     * @param directory directory for snapshot data\n     * @param storage Storage object for the snapshot.\n     */\n    public ApplicationSnapshot(File directory, Storage storage) {\n        super(directory, ApplicationSnapshotsSupport.getInstance().getCategory());\n        this.storage = storage;\n    }\n    \n    \n    // Save to a file within given directory\n    public void save(File directory) {\n        saveArchive(new File(directory, getFile().getName()));\n    }\n    \n    public boolean supportsSaveAs() {\n        return getFile() != null;\n    }\n\n    public void saveAs() {\n        JFileChooser chooser = new JFileChooser();\n        chooser.setDialogTitle(NbBundle.getMessage(ApplicationSnapshot.class, \"LBL_Save_Application_Snapshot_As\")); // NOI18N\n        chooser.setSelectedFile(new File(getFile().getName()));\n        chooser.setAcceptAllFileFilterUsed(false);\n        chooser.setFileFilter(getCategory().getFileFilter());\n        if (chooser.showSaveDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) {\n            String categorySuffix = ApplicationSnapshotCategory.SUFFIX;\n            String filePath = chooser.getSelectedFile().getAbsolutePath();\n            if (!filePath.endsWith(categorySuffix)) filePath += categorySuffix;\n            final File file = new File(filePath);\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    ProgressHandle pHandle = null;\n                    try {\n                        pHandle = ProgressHandle.createHandle(NbBundle.getMessage(ApplicationSnapshot.class, \"MSG_Saving\", DataSourceDescriptorFactory.getDescriptor(ApplicationSnapshot.this).getName()));  // NOI18N\n                        pHandle.setInitialDelay(0);\n                        pHandle.start();\n                        saveArchive(file);\n                    } finally {\n                        final ProgressHandle pHandleF = pHandle;\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() { if (pHandleF != null) pHandleF.finish(); }\n                        });\n                    }\n                }\n            });\n        }\n    }\n    \n    \n    protected Storage createStorage() {\n        return storage;\n    }\n    \n    \n    private void saveArchive(File archive) {\n        Utils.createArchive(getFile(), archive);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/snapshot/ApplicationSnapshotAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.application.snapshot;\n\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.core.ui.actions.MultiDataSourceAction;\nimport org.openide.util.NbBundle;\n\n    \n/**\n *\n * @author Jiri Sedlacek\n */\nclass ApplicationSnapshotAction extends MultiDataSourceAction<Application> {\n    \n    private Set<Application> lastSelectedApplications = new HashSet<>();\n    \n    private static ApplicationSnapshotAction instance;\n    \n    public static synchronized ApplicationSnapshotAction instance() {\n        if (instance == null) \n            instance = new ApplicationSnapshotAction();\n        return instance;\n    }\n    \n    \n    private final DataChangeListener<Snapshot> changeListener = new DataChangeListener<Snapshot>() {\n        public void dataChanged(DataChangeEvent<Snapshot> event) {\n            ApplicationSnapshotAction.super.updateState(ActionUtils.getSelectedDataSources(Application.class));\n        }\n    };\n    \n        \n    protected void actionPerformed(Set<Application> applications, ActionEvent actionEvent) {\n        for (Application application : applications)\n            ApplicationSnapshotsSupport.getInstance().getSnapshotProvider().createSnapshot(application,\n            (actionEvent.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n    }\n    \n    protected boolean isEnabled(Set<Application> applications) {\n        for (Application application : applications) {\n            if (DataSourceViewsManager.sharedInstance().canSaveViewsFor(application, ApplicationSnapshot.class))\n                return true;\n            if (application.getRepository().getDataSources(Snapshot.class).isEmpty())\n                return false;\n        }\n        return true;\n    }\n    \n    protected void updateState(Set<Application> selectedApplications) {\n        super.updateState(selectedApplications);\n    \n        if (!lastSelectedApplications.isEmpty())\n            for (Application application : lastSelectedApplications)\n                application.getRepository().removeDataChangeListener(changeListener);\n        lastSelectedApplications.clear();\n        \n        if (!selectedApplications.isEmpty()) {\n            lastSelectedApplications.addAll(selectedApplications);\n            for (Application application : lastSelectedApplications)\n                application.getRepository().addDataChangeListener(changeListener, Snapshot.class);\n        }\n    }\n\n    \n    private ApplicationSnapshotAction() {\n        super(Application.class);\n        putValue(NAME, NbBundle.getMessage(ApplicationSnapshotAction.class, \"LBL_Application_Snapshot\"));   // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(ApplicationSnapshotAction.class, \"DESCR_Application_Snapshot\"));  // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/snapshot/ApplicationSnapshotCategory.java",
    "content": "/*\n *  Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.application.snapshot;\n\nimport java.io.File;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ApplicationSnapshotCategory extends SnapshotCategory<ApplicationSnapshot> {\n    \n    private static final String NAME = NbBundle.getMessage(ApplicationSnapshotCategory.class, \"LBL_Application_Snapshots\"); // NOI18N\n    private static final String PREFIX = \"application\"; // NOI18N\n    static final String SUFFIX = \".apps\";   // NOI18N\n    \n    ApplicationSnapshotCategory() {\n        super(NAME, ApplicationSnapshot.class, PREFIX, SUFFIX, POSITION_NONE);\n    }\n\n    public boolean supportsOpenSnapshot() {\n        return true;\n    }\n\n    public void openSnapshot(File file) {\n        ApplicationSnapshotProvider.sharedInstance().loadSnapshotArchive(file);\n    }\n    \n    boolean isSnapshotArchive(File file) {\n        return file.exists() && file.isFile() && isSnapshot(file);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/snapshot/ApplicationSnapshotConfigurator.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.snapshot;\n\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.File;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTextField;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n * \n */\nclass ApplicationSnapshotConfigurator extends JPanel {\n\n  static ApplicationSnapshotConfigurator defineSnapshot() {\n    ApplicationSnapshotConfigurator hc = getDefault();\n    hc.setupDefineCoreDump();\n    \n    final DialogDescriptor dd = new DialogDescriptor(hc, NbBundle.getMessage(ApplicationSnapshotConfigurator.class, \"Title_Add_Application_Snapshot\"), true, new Object[] {   // NOI18N\n      hc.okButton, DialogDescriptor.CANCEL_OPTION }, hc.okButton, 0, null, null);\n    final Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n    d.pack();\n    d.setVisible(true);\n    \n    if (dd.getValue() == hc.okButton) return hc;\n    else return null;\n  }\n  \n  File getSnapshotFile() {\n    return new File(snapshotFileField.getText().trim());\n  }\n  \n  boolean deleteSourceFile() {\n      return deleteSourceCheckbox.isSelected();\n  }\n  \n  private static ApplicationSnapshotConfigurator defaultInstance;\n  \n  private ApplicationSnapshotConfigurator() {\n    initComponents();\n    update();\n  }\n  \n  private static ApplicationSnapshotConfigurator getDefault() {\n    if (defaultInstance == null) defaultInstance = new ApplicationSnapshotConfigurator();\n    return defaultInstance;\n  }\n  \n  private void setupDefineCoreDump() {\n    snapshotFileField.setText(\"\");\n    deleteSourceCheckbox.setSelected(false);\n  }\n  \n  private void update() {\n    SwingUtilities.invokeLater(new Runnable() {\n      public void run() {\n        File snapshotFile = getSnapshotFile();\n        okButton.setEnabled(ApplicationSnapshotsSupport.getInstance().getApplicationSnapshotCategory().isSnapshotArchive(snapshotFile));\n      }\n    });\n  }\n\n  private void chooseSnapshot() {\n      JFileChooser chooser = new JFileChooser();\n      chooser.setDialogTitle(NbBundle.getMessage(ApplicationSnapshotConfigurator.class, \"LBL_Select_Application_Snapshot\"));     // NOI18N\n      chooser.setSelectedFile(getSnapshotFile());\n      chooser.setAcceptAllFileFilterUsed(false);\n      chooser.setFileFilter(ApplicationSnapshotsSupport.getInstance().getCategory().getFileFilter());\n      if (chooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) snapshotFileField.setText(chooser.getSelectedFile().getAbsolutePath());\n  }\n  \n  private void initComponents() {\n    setLayout(new GridBagLayout());\n    GridBagConstraints constraints;\n    \n    // snapshotFileLabel\n    snapshotFileLabel = new JLabel();\n    Mnemonics.setLocalizedText(snapshotFileLabel, NbBundle.getMessage(ApplicationSnapshotConfigurator.class, \"LBL_Snapshot_file\")); // NOI18N\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 0;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.EAST;\n    constraints.insets = new Insets(15, 10, 0, 0);\n    add(snapshotFileLabel, constraints);\n    \n    // snapshotFileField\n    snapshotFileField = new JTextField();\n    snapshotFileLabel.setLabelFor(snapshotFileField);\n    snapshotFileField.setPreferredSize(new Dimension(220, snapshotFileField.getPreferredSize().height));\n    snapshotFileField.getDocument().addDocumentListener(new DocumentListener() {\n      public void insertUpdate(DocumentEvent e)  { update(); }\n      public void removeUpdate(DocumentEvent e)  { update(); }\n      public void changedUpdate(DocumentEvent e) { update(); }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 1;\n    constraints.gridy = 0;\n    constraints.weightx = 1;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.HORIZONTAL;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(15, 5, 0, 0);\n    add(snapshotFileField, constraints);\n    \n    // snapshotFileButton\n    snapshotFileButton = new JButton();\n    Mnemonics.setLocalizedText(snapshotFileButton, NbBundle.getMessage(ApplicationSnapshotConfigurator.class, \"LBL_Browse\")); // NOI18N\n    snapshotFileButton.addActionListener(new ActionListener() {\n        public void actionPerformed(ActionEvent e) {\n            chooseSnapshot();\n        }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 2;\n    constraints.gridy = 0;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(15, 5, 0, 10);\n    add(snapshotFileButton, constraints);         \n    \n    // deleteSourceCheckbox\n    deleteSourceCheckbox = new JCheckBox();\n    Mnemonics.setLocalizedText(deleteSourceCheckbox, NbBundle.getMessage(ApplicationSnapshotConfigurator.class, \"LBL_Delete_source_file\")); // NOI18N\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 1;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(18, 10, 0, 0);\n    add(deleteSourceCheckbox, constraints);\n    \n    // spacer\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 2;\n    constraints.weighty = 1;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.BOTH;\n    constraints.anchor = GridBagConstraints.NORTHWEST;\n    constraints.insets = new Insets(0, 0, 15, 0);\n    add(Spacer.create(), constraints);\n    \n    // okButton\n    okButton = new JButton(NbBundle.getMessage(ApplicationSnapshotConfigurator.class, \"LBL_OK\"));    // NOI18N\n    \n    // UI tweaks\n    deleteSourceCheckbox.setBorder(snapshotFileLabel.getBorder());\n  }\n  \n  private JLabel snapshotFileLabel;\n  private JTextField snapshotFileField;\n  private JButton snapshotFileButton;\n  private JCheckBox deleteSourceCheckbox;\n  \n  private JButton okButton;\n  \n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/snapshot/ApplicationSnapshotDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.application.snapshot;\n\nimport java.awt.Image;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.snapshot.SnapshotDescriptor;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsSupport;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * DataSourceDescriptor for ApplicationSnapshot.\n *\n * @author Jiri Sedlacek\n */\npublic class ApplicationSnapshotDescriptor extends SnapshotDescriptor<ApplicationSnapshot> {\n\n    private static final Image NODE_ICON = ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/core/ui/resources/application.png\", true);    // NOI18N\n\n    \n    /**\n     * Creates new instance of ApplicationSnapshotDescriptor.\n     * \n     * @param snapshot ApplicationSnapshot for the descriptor.\n     */\n    public ApplicationSnapshotDescriptor(ApplicationSnapshot snapshot) {\n        super(snapshot, resolveSnapshotName(snapshot), NbBundle.getMessage(\n              ApplicationSnapshotDescriptor.class, \"DESCR_ApplicationSnapshot\"), // NOI18N\n              resolveIcon(snapshot), resolvePosition(snapshot, POSITION_AT_THE_END,\n              true), EXPAND_NEVER);\n    }\n\n    private static Image resolveIcon(ApplicationSnapshot snapshot) {\n        Image icon = NODE_ICON;\n        String persistedIconString = snapshot.getStorage().getCustomProperty(PROPERTY_ICON);\n        if (persistedIconString != null) {\n            Image persistedIcon = Utils.stringToImage(persistedIconString);\n            if (persistedIcon != null) {\n                icon = persistedIcon;\n            }\n        }\n\n        return icon != null ? SnapshotsSupport.getInstance().createSnapshotIcon(icon) : null;\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/snapshot/ApplicationSnapshotDescriptorProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.snapshot;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ApplicationSnapshotDescriptorProvider extends AbstractModelProvider<DataSourceDescriptor, DataSource> {\n    \n    ApplicationSnapshotDescriptorProvider() {\n    }\n    \n    public DataSourceDescriptor createModelFor(DataSource ds) {\n        if (ds instanceof ApplicationSnapshot) {\n            return new ApplicationSnapshotDescriptor((ApplicationSnapshot)ds);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/snapshot/ApplicationSnapshotProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.snapshot;\n\nimport java.io.File;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.explorer.ExplorerSupport;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsContainer;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsSupport;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ApplicationSnapshotProvider {\n    \n    private static final String SNAPSHOT_VERSION = \"snapshot_version\";   // NOI18N\n    private static final String SNAPSHOT_VERSION_DIVIDER = \".\";  // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = \"1\";    // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MINOR = \"0\";    // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION = CURRENT_SNAPSHOT_VERSION_MAJOR + SNAPSHOT_VERSION_DIVIDER + CURRENT_SNAPSHOT_VERSION_MINOR;\n    \n    private static final String PROPERTIES_FILENAME = \"application_snapshot\" + Storage.DEFAULT_PROPERTIES_EXT;   // NOI18N\n    \n    private static final Logger LOGGER = Logger.getLogger(ApplicationSnapshotProvider.class.getName());\n    \n    private static ApplicationSnapshotProvider sharedInstance;\n    \n    synchronized static ApplicationSnapshotProvider sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new ApplicationSnapshotProvider();\n        return sharedInstance;\n    }\n    \n    \n    private ApplicationSnapshotProvider() {\n    }\n    \n    void createSnapshot(final Application application, final boolean openSnapshot) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                ProgressHandle pHandle = null;\n                try {\n                    pHandle = ProgressHandle.createHandle(NbBundle.getMessage(ApplicationSnapshotProvider.class, \"MSG_Saving_snapshot\", DataSourceDescriptorFactory.getDescriptor(application).getName()));  // NOI18N\n                    pHandle.setInitialDelay(0);\n                    pHandle.start();\n                    createSnapshotImpl(application, openSnapshot);\n                } finally {\n                    final ProgressHandle pHandleF = pHandle;\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { if (pHandleF != null) pHandleF.finish(); }\n                    });\n                }\n            }\n        });\n    }\n    \n    private void createSnapshotImpl(final Application application, final boolean openSnapshot) {\n        Set<Snapshot> snapshots = application.getRepository().getDataSources(Snapshot.class);\n        if (snapshots.isEmpty() && !DataSourceViewsManager.sharedInstance().canSaveViewsFor(application, ApplicationSnapshot.class)) return;\n        \n        File snapshotDirectory = null;\n        synchronized (ApplicationSnapshotProvider.this) {\n            snapshotDirectory = Utils.getUniqueFile(ApplicationSnapshotsSupport.getStorageDirectory(),\n                                                    ApplicationSnapshotsSupport.getInstance().\n                                                    getCategory().createFileName());\n            if (!Utils.prepareDirectory(snapshotDirectory))\n                throw new IllegalStateException(\"Cannot save datasource snapshot \" + snapshotDirectory);    // NOI18N\n        }\n        \n        for (Snapshot snapshot : snapshots) {\n            try {\n                Storage storage = snapshot.getStorage();\n                String prop = DataSourceDescriptor.PROPERTY_PREFERRED_POSITION;\n                boolean customPos = storage.getCustomProperty(prop) != null;\n                if (!customPos) {\n                    int pos = ExplorerSupport.sharedInstance().getDataSourcePosition(snapshot);\n                    storage.setCustomProperty(prop, Integer.toString(pos));\n                }\n                snapshot.save(snapshotDirectory);\n                if (!customPos) {\n                    storage.clearCustomProperty(prop);\n                    if (!storage.hasCustomProperties()) storage.deleteCustomPropertiesStorage();\n                }\n            } catch (Exception e) {\n                LOGGER.log(Level.SEVERE, \"Error saving snapshot to application snapshot\", e);   // NOI18N\n            }\n        }\n\n        // See #299\n//        ApplicationType applicationType = ApplicationTypeFactory.getApplicationTypeFor(application);\n        DataSourceDescriptor descriptor = DataSourceDescriptorFactory.getDescriptor(application);\n        String[] propNames = new String[] {\n            SNAPSHOT_VERSION,\n            DataSourceDescriptor.PROPERTY_NAME,\n            DataSourceDescriptor.PROPERTY_ICON\n        };\n        String[] propValues = new String[] {\n            CURRENT_SNAPSHOT_VERSION,\n            descriptor.getName() + getDisplayNameSuffix(application),\n            Utils.imageToString(descriptor.getIcon(), \"png\")   // NOI18N\n        };\n        \n        Storage storage = new Storage(snapshotDirectory, PROPERTIES_FILENAME);\n        storage.setCustomProperties(propNames, propValues);\n        \n        ApplicationSnapshot snapshot = new ApplicationSnapshot(snapshotDirectory, storage);\n        DataSourceViewsManager.sharedInstance().saveViewsFor(application, snapshot);\n        SnapshotsContainer.sharedInstance().getRepository().addDataSource(snapshot);\n        \n        if (openSnapshot && DataSourceWindowManager.sharedInstance().canOpenDataSource(snapshot))\n            DataSourceWindowManager.sharedInstance().openDataSource(snapshot); // TODO: check #VISUALVM-636\n    }\n    \n    private static String getDisplayNameSuffix(Application application) {\n        return \", \" + SnapshotsSupport.getInstance().getTimeStamp(System.currentTimeMillis()); // NOI18N\n        // See #299\n//        StringBuilder builder = new StringBuilder(\" (\");    // NOI18N\n//        int pid = application.getPid();\n//        if (pid != Application.UNKNOWN_PID) builder.append(\"pid \" + pid + \", \");\n//        builder.append(SnapshotsSupport.getInstance().getTimeStamp(System.currentTimeMillis()));\n//        builder.append(\")\");    // NOI18N\n//        return builder.toString();\n    }\n    \n    void addSnapshotArchive(File archive, boolean deleteArchive) {\n        processApplicationSnapshotImpl(archive, deleteArchive, true, NbBundle.\n                getMessage(ApplicationSnapshotProvider.class, \"MSG_Adding\", // NOI18N\n                archive.getName()), false);\n    }\n\n    void loadSnapshotArchive(File archive) {\n        processApplicationSnapshotImpl(archive, false, false, NbBundle.\n                getMessage(ApplicationSnapshotProvider.class, \"MSG_Loading\", // NOI18N\n                archive.getName()), true);\n    }\n\n\n    private void processApplicationSnapshotImpl(final File archive, final boolean deleteArchive,\n                                                final boolean persistent, final String progressMsg,\n                                                final boolean openSnapshot) {\n        // TODO: check if the same snapshot isn't already imported\n\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                ProgressHandle pHandle = null;\n                try {\n                    pHandle = ProgressHandle.createHandle(progressMsg);\n                    pHandle.setInitialDelay(0);\n                    pHandle.start();\n\n                    File storageDirectory = persistent ? ApplicationSnapshotsSupport.getStorageDirectory() :\n                                                         Storage.getTemporaryStorageDirectory();\n                    \n                    File snapshotDirectory = new File(storageDirectory, archive.getName());\n                    \n                    // Only extract the archive if not already extracted (subsequent opening of the same snapshot)\n                    if (!snapshotDirectory.isDirectory() || !snapshotDirectory.canRead())\n                        snapshotDirectory = Utils.extractArchive(archive, storageDirectory);\n                    \n                    if (snapshotDirectory != null) {\n                        Storage storage = new Storage(snapshotDirectory, PROPERTIES_FILENAME);\n                        ApplicationSnapshot snapshot = new ApplicationSnapshot(snapshotDirectory, storage);\n                        if (persistent) SnapshotsContainer.sharedInstance().getRepository().addDataSource(snapshot);\n                        if (openSnapshot) {\n                            if (DataSourceWindowManager.sharedInstance().canOpenDataSource(snapshot)) {\n                                DataSourceWindowManager.sharedInstance().openDataSource(snapshot); // TODO: check #VISUALVM-636\n                            } else {\n                                DialogDisplayer.getDefault().notifyLater(\n                                        new NotifyDescriptor.Message(NbBundle.\n                                        getMessage(ApplicationSnapshotProvider.class,\n                                        \"MSG_Opening_snapshot_failed\", archive. // NOI18N\n                                        getName()), NotifyDescriptor.ERROR_MESSAGE));\n                            }\n                        }\n                        if (deleteArchive) if (!archive.delete()) archive.deleteOnExit();\n                    } else {\n                        DialogDisplayer.getDefault().notifyLater(\n                                    new NotifyDescriptor.Message(NbBundle.\n                                    getMessage(ApplicationSnapshotProvider.class,\n                                    \"MSG_Adding_snapshot_failed\", archive. // NOI18N\n                                    getName()), NotifyDescriptor.ERROR_MESSAGE));\n                    }\n                } finally {\n                    final ProgressHandle pHandleF = pHandle;\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { if (pHandleF != null) pHandleF.finish(); }\n                    });\n                }\n            }\n        });\n    }\n    \n        \n    private void loadSnapshots() {\n        if (!ApplicationSnapshotsSupport.storageDirectoryExists()) return;\n        \n        File[] files = ApplicationSnapshotsSupport.getStorageDirectory().listFiles(\n                ApplicationSnapshotsSupport.getInstance().getCategory().getFilenameFilter());\n        \n        Set<ApplicationSnapshot> snapshots = new HashSet<>();\n        for (File file : files) {\n            if (file.isDirectory()) { // NOTE: once archived snapshots are implemented, this is not necessary\n                Storage storage = new Storage(file, PROPERTIES_FILENAME);\n                snapshots.add(new ApplicationSnapshot(file, storage));\n            }\n        }\n        \n        if (!snapshots.isEmpty()) \n            SnapshotsContainer.sharedInstance().getRepository().addDataSources(snapshots);\n    }\n    \n    \n    void initialize() {\n        VisualVM.getInstance().runTask(this::loadSnapshots);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/snapshot/ApplicationSnapshotsSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.snapshot;\n\nimport java.io.File;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.snapshot.RegisteredSnapshotCategories;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsContainer;\n\n/**\n * Support for application snapshots in VisualVM.\n *\n * @author Jiri Sedlacek\n */\npublic final class ApplicationSnapshotsSupport {\n    \n    private static ApplicationSnapshotsSupport instance;\n    \n    private static final String SNAPSHOTS_STORAGE_DIRNAME = \"snapshots\";    // NOI18N\n    \n    private static File snapshotsStorageDirectory;\n    private static String snapshotsStorageDirectoryString;\n\n    private ApplicationSnapshotProvider snapshotProvider;\n    private ApplicationSnapshotCategory snapshotCategory = new ApplicationSnapshotCategory();\n\n\n    /**\n     * Returns singleton instance of ApplicationSnapshotsSupport.\n     * \n     * @return singleton instance of ApplicationSnapshotsSupport.\n     */\n    public static synchronized ApplicationSnapshotsSupport getInstance() {\n        if (instance == null) instance = new ApplicationSnapshotsSupport();\n        return instance;\n    }\n    \n    \n    /**\n     * Returns SnapshotCategory instance for application snapshots.\n     * \n     * @return SnapshotCategory instance for application snapshots.\n     */\n    public SnapshotCategory<ApplicationSnapshot> getCategory() {\n        return snapshotCategory;\n    }\n    \n    ApplicationSnapshotCategory getApplicationSnapshotCategory() {\n        return snapshotCategory;\n    } \n    \n    \n    ApplicationSnapshotProvider getSnapshotProvider() {\n        return snapshotProvider;\n    }\n    \n    static synchronized String getStorageDirectoryString() {\n        if (snapshotsStorageDirectoryString == null)\n            snapshotsStorageDirectoryString = Storage.getPersistentStorageDirectoryString() + File.separator + SNAPSHOTS_STORAGE_DIRNAME;\n        return snapshotsStorageDirectoryString;\n    }\n    \n    static synchronized File getStorageDirectory() {\n        if (snapshotsStorageDirectory == null) {\n            String snapshotsStorageString = getStorageDirectoryString();\n            snapshotsStorageDirectory = new File(snapshotsStorageString);\n            if (snapshotsStorageDirectory.exists() && snapshotsStorageDirectory.isFile())\n                throw new IllegalStateException(\"Cannot create snapshots storage directory \" + snapshotsStorageString + \", file in the way\");   // NOI18N\n            if (snapshotsStorageDirectory.exists() && (!snapshotsStorageDirectory.canRead() || !snapshotsStorageDirectory.canWrite()))\n                throw new IllegalStateException(\"Cannot access snapshots storage directory \" + snapshotsStorageString + \", read&write permission required\");    // NOI18N\n            if (!Utils.prepareDirectory(snapshotsStorageDirectory))\n                throw new IllegalStateException(\"Cannot create snapshots storage directory \" + snapshotsStorageString); // NOI18N\n        }\n        return snapshotsStorageDirectory;\n    }\n    \n    static boolean storageDirectoryExists() {\n        return new File(getStorageDirectoryString()).isDirectory();\n    }\n    \n    \n    private ApplicationSnapshotsSupport() {\n        DataSourceDescriptorFactory.getDefault().registerProvider(new ApplicationSnapshotDescriptorProvider());\n        snapshotProvider = ApplicationSnapshotProvider.sharedInstance();\n        \n        RegisteredSnapshotCategories.sharedInstance().registerCategory(snapshotCategory);\n        SnapshotsContainer.sharedInstance(); // Notify SnapshotsContainer\n        snapshotProvider.initialize();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/snapshot/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nLBL_Add_Application_Snapshot=Add &Application Snapshot...\n\nToolTip_Add_Application_Snapshot=Add Application Snapshot\n\nTitle_Add_Application_Snapshot=Add Application Snapshot\n\nLBL_Save_Application_Snapshot_As=Save Application Snapshot As\n\nMSG_Saving=Saving {0}...\n\nLBL_Application_Snapshot=&Application Snapshot\n\nDESCR_Application_Snapshot=Application Snapshot\n\nLBL_Application_Snapshots=Application Snapshots\n\nLBL_Select_Application_Snapshot=Select Application Snapshot\n\nLBL_Snapshot_file=&Snapshot file\\:\n\nLBL_Browse=&Browse...\n\nLBL_Delete_source_file=&Delete source file\n\nLBL_OK=OK\n\nMSG_Saving_snapshot=Saving snapshot of {0}...\n\nMSG_Adding=Adding {0}...\n\nMSG_Adding_snapshot_failed=<html><b>Adding snapshot {0} failed.</b><br><br>Make sure the file is not broken.</html>\n\nMSG_Loading=Loading {0}..\n\nMSG_Opening_snapshot_failed=<html><b>Opening snapshot {0} failed.</b><br><br>No known displayable data found in the snapshot.</html>.\n\nDESCR_ApplicationSnapshot=Application snapshot.\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/snapshot/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Support for application snapshots in VisualVM.\n */\npackage org.graalvm.visualvm.application.snapshot;\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/ApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.application.type;\n\nimport java.awt.Image;\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.Model;\n\n/**\n * This class is used to identify different type of Java\n * applications. Using this class you can obtain \n * application's name and icon. VisualVM plugins can\n * use instances of this class to identify particular\n * application type (like GlassFish) and provide\n * additional information for that application type.\n * To get instance of ApplicationType for {@link Application}\n * use the following factory method <code>\n * ApplicationTypeFactory.getApplicationTypeFor(Application app)\n * </code>\n * @author Tomas Hurka\n */\npublic abstract class ApplicationType extends Model {\n    public static final String PROPERTY_NAME = \"name\"; // NOI18N\n    /**\n     * Named property for suggested name of the application type. This name will\n     * eventually be used instead of \"Local Application\" or \"Remote Application\"\n     * in case the application type is not recognized.\n     */\n    public static final String PROPERTY_SUGGESTED_NAME = \"prop_suggested_name\"; // NOI18N\n    public static final String PROPERTY_DESCRIPTION = \"description\"; // NOI18N\n    public static final String PROPERTY_VERSION = \"version\"; // NOI18N\n    public static final String PROPERTY_ICON = \"icon\"; // NOI18N\n\n    private PropertyChangeSupport pcs = new PropertyChangeSupport(this);\n\n    /**\n     * Gets the name of the application.\n     * @return this application's name\n     */\n    public abstract String getName();\n\n    /**\n     * Gets the version of the application.\n     * @return this application's version\n     */    \n    public abstract String getVersion();\n\n    /**\n     * Gets the description of the application.\n     * @return this application's description\n     */    \n    public abstract String getDescription();\n\n    /**\n     * Gets the icon of the application.\n     * @return this application's icon\n     */    \n    public abstract Image getIcon();\n\n    /**\n     * Add a PropertyChangeListener to the listener list.\n     * The listener is registered for all properties.\n     * The same listener object may be added more than once, and will be called\n     * as many times as it is added.\n     * If <code>listener</code> is null, no exception is thrown and no action\n     * is taken.\n     *\n     * @param listener  The PropertyChangeListener to be added\n     */\n    public void addPropertyChangeListener(PropertyChangeListener listener) {\n        pcs.addPropertyChangeListener(listener);\n    }\n\n    /**\n     * Remove a PropertyChangeListener from the listener list.\n     * This removes a PropertyChangeListener that was registered\n     * for all properties.\n     * If <code>listener</code> was added more than once to the same event\n     * source, it will be notified one less time after being removed.\n     * If <code>listener</code> is null, or was never added, no exception is\n     * thrown and no action is taken.\n     *\n     * @param listener  The PropertyChangeListener to be removed\n     */\n    public void removePropertyChangeListener(PropertyChangeListener listener) {\n        pcs.removePropertyChangeListener(listener);\n    }\n\n    /**\n     * Report a bound property update to any registered listeners.\n     * No event is fired if old and new are equal and non-null.\n     *\n     * @param propertyName  The programmatic name of the property\n     *\t\tthat was changed.\n     * @param oldValue  The old value of the property.\n     * @param newValue  The new value of the property.\n     */\n    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {\n        pcs.firePropertyChange(propertyName, oldValue, newValue);\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/ApplicationTypeFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.ModelFactory;\nimport org.graalvm.visualvm.core.model.ModelProvider;\n\n/**\n * The ApplicationTypeFactory class is a factory class for getting the\n * {@link ApplicationType} representation for the {@link Application}.\n *\n * @author Tomas Hurka\n * @author Luis-Miguel Alventosa\n */\npublic final class ApplicationTypeFactory extends ModelFactory<ApplicationType,Application> implements ModelProvider<ApplicationType,Application> {\n    \n    private static ApplicationTypeFactory appTypeFactory;\n    \n    private ApplicationTypeFactory() {\n    }\n    \n    /**\n     * Getter for the default version of the ApplicationTypeFactory.\n     * @return instance of {@link ApplicationTypeFactory}.\n     */\n    public static synchronized ApplicationTypeFactory getDefault() {\n        if (appTypeFactory == null) {\n            appTypeFactory = new ApplicationTypeFactory();\n            appTypeFactory.registerProvider(appTypeFactory);\n            appTypeFactory.registerProvider(new MainClassApplicationTypeFactory());\n            appTypeFactory.registerProvider(new NetBeansApplicationTypeFactory());\n            appTypeFactory.registerProvider(new JavaPluginApplicationTypeFactory());\n            appTypeFactory.registerProvider(new JavaWebStartApplicationTypeFactory());\n            appTypeFactory.registerProvider(new JDeveloperApplicationTypeFactory());\n            appTypeFactory.registerProvider(new MavenApplicationTypeFactory());\n            appTypeFactory.registerProvider(new IntellijApplicationTypeFactory());\n            appTypeFactory.registerProvider(new EclipseApplicationTypeFactory());\n        }\n        return appTypeFactory;\n    }\n    \n    /**\n     * Factory method for obtaining {@link ApplicationType} for {@link Application}. Note that there\n     * is only one instance of {@link ApplicationType} for a concrete application. This {@link ApplicationType}\n     * instance is cached.\n     * @param app application \n     * @return {@link ApplicationType} instance which describes application type.\n     */\n    public static ApplicationType getApplicationTypeFor(Application app) {\n        return getDefault().getModel(app);\n    }\n    \n    /**\n     * Default {@link ApplicationType} implementation, which creates \n     * generic {@link ApplicationType} instances. If you want to extend ApplicationTypeFactory use \n     * {@link ApplicationTypeFactory#registerProvider(ModelProvider )} to register the new instances\n     * of {@link ModelProvider} for the different types of {@link Application}.\n     * @param app application\n     * @return generic instance of {@link ApplicationType}\n     */\n    public ApplicationType createModelFor(Application app) {\n        return new DefaultApplicationType(app);\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Name=VisualVM-ApplicationType\n\nLBL_NbPlatformApplication=NetBeans Platform application\n\nLBL_Local_Application=Local Application\nLBL_Remote_Application=Remote Application\n\nLBL_Unknown_Version=<Unknown Version>\n\nLBL_Java_Plug-in_ver=Java Plug-in {0}\n\nLBL_Java_Plug-in=Java Plug-in\n\nLBL_Java_Web_Start=Java Web Start\n\nLBL_Unknown=<Unknown>\n\nDESCR_VisualVMApplicationType=VisualVM is a visual tool integrating several commandline JDK tools and lightweight profiling capabilities.\nDESCR_NetBeansBasedApplicationType=Java application built on top of the NetBeans Platform.\nDESCR_NetBeansApplicationType=NetBeans IDE: The only IDE you need! Runs on Windows, Linux, macOS and Solaris. NetBeans IDE is open-source and free.\nDESCR_JDeveloperApplicationType=Oracle JDeveloper is a free integrated development environment that simplifies the development of Java-based SOA applications and user interfaces with support for the full development life cycle.\nDESCR_IntelliJPlatformApplicationType=The IntelliJ Platform is a platform for building smart, language-aware IDEs with a comprehensive set of components.\nDESCR_EclipseApplicationType=Eclipse is an open-source community that develops open platforms and products.\nDESCR_MavenApplicationType=Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.\nDESCR_MavenWrapperApplicationType=The Maven Wrapper is an easy way to ensure a user of Maven build has everything necessary to run Maven build.\nDESCR_Ant=Apache Ant is a Java-based build tool. In theory, it is kind of like Make, but without Make's wrinkles.\nDESCR_GlassFish=GlassFish is an open source application server for the Java EE platform.\nDESCR_Tomcat=Apache Tomcat is an open source software implementation of the Java Servlet and JavaServer Pages technologies.\nDESCR_JBoss=JBoss Application Server is an open source, standards-compliant, J2EE based application server implemented in 100% Pure Java.\nDESCR_JConsole=jconsole: JMX-compliant graphical tool for monitoring a Java virtual machine.\nDESCR_Jps=jps: Java virtual machine process status tool. Lists the instrumented HotSpot Java Virtual Machines (JVMs) on the target system.\nDESCR_Jcmd=jcmd: utility used to send diagnostic command requests to the JVM, where these requests are useful for controlling Java Flight Recordings, troubleshoot, and diagnose JVM and Java Applications.\nDESCR_Jstat=jstat: Java virtual machine statistics monitoring tool. Displays performance statistics for an instrumented HotSpot Java virtual machine (JVM).\nDESCR_Jstatd=jstatd: virtual machine jstat daemon. RMI server application that monitors for the creation and termination of instrumented HotSpot Java virtual machines (JVMs) and provides a interface to allow remote monitoring tools to attach to JVMs running on the local host.\nDESCR_Jstack=jstack: prints Java stack traces of Java threads for a given Java process or core file or a remote debug server.\nDESCR_Jmap=jmap: prints shared object memory maps or heap memory details of a given process or core file or a remote debug server.\nDESCR_Jhat=jhat: Java heap analysis tool. Parses a Java heap dump file and launches a webserver to enable browsing heap dumps using a webbrowser.\nDESCR_Jinfo=jinfo: prints Java configuration information for a given Java process or core file or a remote debug server.\nDESCR_Jsadebugd=jsadebugd: serviceability agent debug daemon. Attaches to a Java process or core file and acts as a debug server.\nDESCR_JShell=jshell: an interactive tool for learning the Java programming language and prototyping Java code.\nDESCR_Jdeprscan=jdeprscan: a static analysis tool that scans a jar file (or some other aggregation of class files) for uses of deprecated API elements.\nDESCR_Jdeps=jdeps: Java class dependency analyzer.\nDESCR_Jfr=jfr: a tool for interacting with flight recorder files (.jfr). \nDESCR_Jimage=jimage: list, extract, verify, or get information about the JIMAGE entries.\nDESCR_Jlink=jlink: tool to assemble and optimize a set of modules and their dependencies into a custom runtime image.\nDESCR_Jmod=jmod: tool to create JMOD files and list the content of existing JMOD files.\nDESCR_Jpackage=jpackage: generates installable packages for modular and non-modular Java applications. Platform-specific packages for Linux, macOS and Windows provide your users with a familiar way to install and launch your applications.\nDESCR_Jrunscript=jrunscript: a command-line script shell that supports interactive and batch modes.\nDESCR_Jwebserver=jwebserver: tool provides a minimal HTTP server, designed to be used for prototyping, testing, and debugging.\nDESCR_Jdb=jdb: The Java Debugger (JDB) is a simple command-line debugger for Java classes.\nDESCR_Jhsdb=jhsdb: attach to a Java process or launch a postmortem debugger to analyze the content of a core dump from a crashed Java Virtual Machine (JVM).\nDESCR_Jar=jar: Java archive tool. Combines multiple files into a single JAR archive file.\nDESCR_Pack200=pack200: JAR packing tool. Java application that transforms a JAR file into a compressed pack200 file using the Java gzip compressor.\nDESCR_JavaDoc=javadoc: Java API documentation generator. Generates HTML pages of API documentation from Java source files.\nDESCR_Javac=javac: Java programming language compiler. Reads class and interface definitions, written in the Java programming language, and compiles them into bytecode class files.\nDESCR_Javah=javah: C header and stub file generator. Generates C header and source files that are needed to implement native methods.\nDESCR_Javap=javap: Java class file disassembler. Disassembles a class file.\nDESCR_JarSigner=jarsigner: JAR signing and verification tool. Used for signing Java ARchive (JAR) files and verifying the signatures and integrity of signed JAR files.\nDESCR_Apt=apt: annotation processing tool. Finds and executes annotation processors based on the annotations present in the set of specified source files being examined.\nDESCR_AppletViewer=appletviewer: Java applet viewer. Allows to run applets outside of the context of a World-Wide Web browser.\nDESCR_JavaDb=Java DB is Sun's supported distribution of the Apache Derby open-source database. Java DB is 100 percent Java technology and easy to use.\nDESCR_JdkDemoApp=JFC demo application.\nDESCR_JRMC=Oracle JRockit Mission Control is a set of powerful tools running on the Oracle JRockit JVM. These tools deliver advanced, unobtrusive JVM monitoring and management, suitable for use both in development and production environments.\nDESCR_WLS=Oracle WebLogic Server. Application server for building and deploying enterprise Java EE applications.\nLBL_Jruby=JRuby application\nDESCR_Jruby=JRuby application.\nLBL_Scala=Scala application\nDESCR_Scala=Scala application.\nLBL_Clojure=Clojure application\nDESCR_Clojure=Clojure application.\nLBL_Groovy=Groovy application\nDESCR_Groovy=Groovy application.\nLBL_Jython=Jython application\nDESCR_Jython=Jython application.\nLBL_Gradle=Gradle Daemon\nDESCR_Gradle=Gradle Daemon: a long-lived background process that executes your builds much more quickly than would otherwise be the case.\nLBL_GradleLauncher=Gradle Launcher\nDESCR_GradleLauncher=Gradle Launcher.\nLBL_GradleWrapper=Gradle Wrapper\nDESCR_GradleWrapper=Gradle Wrapper is a script that invokes a declared version of Gradle, downloading it beforehand if necessary.\nLBL_GradleWorker=Gradle Worker\nDESCR_GradleWorker=Gradle Worker is long-lived worker daemon process that can be reused for future work items.\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/DefaultApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport java.awt.Image;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n\n/**\n * Default application type, which returns main class name as \n * application name and uses generic Java icon as application\n * icon. It is used when application is not recognized\n * by any of more specific ApplicationTypes.\n * \n * @author Tomas Hurka\n * @author Luis-Miguel Alventosa\n * @author Jiri Sedlacek\n */\npublic class DefaultApplicationType extends ApplicationType {\n    String name;\n    Application application;\n    \n    protected DefaultApplicationType(Application app) {\n        application = app;\n    }\n    \n    /**\n     * Gets the name of the application.\n     * Application's main class is used as the name\n     * of the application.\n     * @return this application's name\n     */\n    public String getName() {\n        if (name == null) {\n            String mainClassName = null;\n            if (Stateful.STATE_AVAILABLE == application.getState()) {\n                Jvm jvm = JvmFactory.getJVMFor(application);\n                if (jvm.isBasicInfoSupported()) {\n                    mainClassName = jvm.getMainClass();\n                }\n            }\n            \n            if (mainClassName != null && !mainClassName.isEmpty()) {\n                name = mainClassName;\n            } else {\n                name = application.getStorage().getCustomProperty(PROPERTY_SUGGESTED_NAME);\n            }\n            if (name == null) {\n                name = application.isLocalApplication() ?\n                        NbBundle.getMessage(DefaultApplicationType.class, \"LBL_Local_Application\") : // NOI18N\n                        NbBundle.getMessage(DefaultApplicationType.class, \"LBL_Remote_Application\"); // NOI18N\n            }\n        }\n        return name;\n    }\n    \n    /**\n     * {@inheritDoc}\n     */ \n    public String getVersion() {\n        return NbBundle.getMessage(DefaultApplicationType.class, \"LBL_Unknown_Version\");    // NOI18N\n    }\n    \n    /**\n     * {@inheritDoc}\n     */ \n    public String getDescription() {\n        return \"\";\n    }\n\n    /**\n     * {@inheritDoc}\n     */     \n    public Image getIcon() {\n        String iconPath = \"org/graalvm/visualvm/application/resources/application.png\";   // NOI18N\n        return ImageUtilities.loadImage(iconPath, true);\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/EclipseApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.openide.util.NbBundle;\n\n/**\n * This {@link ApplicationType} represents Eclipse application.\n * @author Tomas Hurka\n */\npublic class EclipseApplicationType extends MainClassApplicationType {\n    \n    EclipseApplicationType(Application app, String name) {\n        super(app, name, NbBundle.getMessage(\n                MainClassApplicationType.class, \"DESCR_EclipseApplicationType\"), // NOI18N\n                \"org/graalvm/visualvm/application/type/resources/Eclipse.png\"); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/EclipseApplicationTypeFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport java.util.Properties;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\n\n/**\n * Factory which recognizes Eclipse application.\n * @author Tomas Hurka\n */\npublic class EclipseApplicationTypeFactory extends MainClassApplicationTypeFactory {\n    \n    private static final String MAIN_CLASS = \"org.eclipse.equinox.launcher.Main\"; // NOI18N\n    private static final String ECLIPSE_ID = \"-Dosgi.requiredJavaVersion=\"; // NOI18N\n    private static final String ECLIPSE_ID2 = \"-XstartOnFirstThread\"; // NOI18N\n    private static final String ECLIPSE_SYSPROP_ID = \"eclipse.buildId\"; // NOI18N\n    private static final String ECLIPSE_NAME = \"Eclipse\"; // NOI18N\n    \n    /**\n     * Detects Eclipse application. It returns\n     * {@link EclipseApplicationType} for Eclipse application.\n     *\n     * @return {@link ApplicationType} subclass or <code>null</code> if\n     * this application is not Eclipse application\n     */\n    public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) {\n        if (MAIN_CLASS.equals(mainClass)) {\n            String name = getName(jvm);\n            if (name == null) {\n                name = ECLIPSE_NAME;\n            }\n            return new EclipseApplicationType(app, name);\n        }\n        if (mainClass == null || mainClass.isEmpty()) {    // there is no main class - detect native Windows launcher\n            String args = jvm.getJvmArgs();\n            if (args != null && (args.contains(ECLIPSE_ID) || args.contains(ECLIPSE_ID2))) {\n                String name = getName(jvm);\n                if (name != null) {\n                    return new EclipseApplicationType(app, name);\n                }\n            }\n        }\n        return null;\n    }\n    \n    private String getName(Jvm jvm) {\n        if (jvm.isGetSystemPropertiesSupported()) {\n            Properties p = jvm.getSystemProperties();\n            if (p != null && p.containsKey(ECLIPSE_SYSPROP_ID)) {\n                return ECLIPSE_NAME;\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/IntellijApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.openide.util.NbBundle;\n\n/**\n * This {@link ApplicationType} represents IntelliJ Platform application.\n * @author Tomas Hurka\n */\npublic class IntellijApplicationType extends MainClassApplicationType {\n    \n    IntellijApplicationType(Application app, String name) {\n        super(app, name, NbBundle.getMessage(\n                MainClassApplicationType.class, \"DESCR_IntelliJPlatformApplicationType\"), // NOI18N\n                \"org/graalvm/visualvm/application/type/resources/JB.png\"); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/IntellijApplicationTypeFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport java.util.Scanner;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\n\n/**\n * Factory which recognizes application based IntelliJ Platform.\n * @author Tomas Hurka\n */\npublic class IntellijApplicationTypeFactory extends MainClassApplicationTypeFactory {\n    \n    private static final String MAIN_CLASS = \"com.intellij.idea.Main\"; // NOI18N\n    private static final String PLATFORM_ID = \"-Didea.paths.selector=\"; // NOI18N\n    private static final String PLATFORM_PREFIX = \"-Didea.platform.prefix=\"; // NOI18N\n    private static final String IDEA_ID = \"Idea\";  // NOI18N\n    private static final String IDEA_CE = \"IdeaIC\"; // NOI18N\n    private static final String IDEA_ENT = \"IntelliJIdea\"; // NOI18N\n    private static final String PYCHARM_CE = \"PyCharmCE\"; // NOI18N\n    private static final String IDEA_NAME = \"IntelliJ IDEA\"; // NOI18N\n    private static final String IDEA_CE_NAME = \"IntelliJ IDEA CE\"; // NOI18N\n    private static final String IDEA_ENT_NAME = \"IntelliJ IDEA\"; // NOI18N\n    private static final String PYCHARM_CE_NAME = \"PyCharm CE\"; // NOI18N\n    private static final String PLATFORM_NAME = \"IntelliJ Platform\"; // NOI18N\n    \n    /**\n     * Detects IntelliJ Platform application. It returns\n     * {@link IntellijApplicationType} for IntelliJ Platform application.\n     *\n     * @return {@link ApplicationType} subclass or <code>null</code> if\n     * this application is not IntelliJ Platform application\n     */\n    public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) {\n        if (MAIN_CLASS.equals(mainClass)) {\n            return new IntellijApplicationType(app, getName(jvm));\n        }\n        if (mainClass == null || mainClass.isEmpty()) {    // there is no main class - detect native Windows launcher\n            String args = jvm.getJvmArgs();\n            if (args != null && args.contains(PLATFORM_ID)) {\n                return new IntellijApplicationType(app, getName(jvm));\n            }\n        }\n        return null;\n    }\n    \n    private String getName(Jvm jvm) {\n        String jvmArgs = jvm.getJvmArgs();\n        String name = getValue(jvmArgs, PLATFORM_PREFIX);\n        String selector = getValue(jvmArgs, PLATFORM_ID);\n\n        if (selector != null) {\n            if (selector.startsWith(IDEA_CE)) {\n                return IDEA_CE_NAME;\n            }\n            if (selector.startsWith(IDEA_ENT)) {\n                return IDEA_ENT_NAME;\n            }\n            if (selector.startsWith(PYCHARM_CE)) {\n                return PYCHARM_CE_NAME;\n            }\n        }\n        if (name != null) {\n            return name;\n        }\n        selector = getValue(jvmArgs, PLATFORM_ID);\n        if (selector != null && selector.startsWith(IDEA_ID)) {\n            return IDEA_NAME;\n        }\n        return PLATFORM_NAME;\n    }\n    \n    private String getValue(String args, String key) {\n        if (args == null) return null;\n        int index = args.indexOf(key);\n        \n        if (index >= 0) {\n            Scanner sc = new Scanner(args.substring(index+key.length()));\n            if (sc.hasNext()) {\n                return sc.next();\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/JDeveloperApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.openide.util.NbBundle;\n\n/**\n * This {@link ApplicationType} represents JDeveloper IDE application.\n * @author Tomas Hurka\n */\npublic class JDeveloperApplicationType extends MainClassApplicationType {\n    private String version;\n    \n    JDeveloperApplicationType(Application app,String ver) {\n        super(app,\"JDeveloper \" + ver, NbBundle.getMessage( // NOI18N\n                MainClassApplicationType.class, \"DESCR_JDeveloperApplicationType\"), // NOI18N\n                \"org/graalvm/visualvm/application/type/resources/JDeveloper.png\"); // NOI18N\n        version = ver;\n    }\n    \n    public String getVersion() {\n        return version;\n    }\n    \n    \n    \n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/JDeveloperApplicationTypeFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport java.util.regex.Pattern;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\n\n/**\n * Factory which recognizes JDeveloper 11g and 10g.\n * @author Tomas Hurka\n */\npublic class JDeveloperApplicationTypeFactory extends MainClassApplicationTypeFactory {\n    \n    private static final String MAIN_CLASS_12 = \"oracle.ide.osgi.boot.JDeveloper\"; // NOI18N\n    private static final String MAIN_CLASS_11 = \"oracle.ide.boot.Launcher\"; // NOI18N\n    private static final String MAIN_CLASS_10 = \"oracle.ideimpl.Main\"; // NOI18N\n    private static final String IDE_CONF_12 = \"\\\\-Dide.conf=\\\\S+jdev.conf\"; // NOI18N\n    private static final String IDE_CONF_11 = \"-Dide.config_pathname=\"; // NOI18N\n    private static final String IDE_PRODUCT_10 = \"-Dide.product=oracle.jdeveloper\"; // NOI18N\n\n    private static final Pattern IDE_CONF_12_PATTERN = Pattern.compile(IDE_CONF_12);\n    \n    private String getJDeveloperVersion(Jvm jvm, String mainClass) {\n        if (MAIN_CLASS_12.equals(mainClass)) {\n            return \"12c\";  // NOI18N\n        }\n        if (MAIN_CLASS_11.equals(mainClass)) {\n            return \"11g\";  // NOI18N\n        }\n        if (MAIN_CLASS_10.equals(mainClass)) {\n            return \"10g\";  // NOI18N\n        }\n        if (mainClass == null || mainClass.isEmpty()) {    // there is no main class - detect native Windows launcher\n            String args = jvm.getJvmArgs();\n            if (args != null) {\n                if (args.contains(IDE_CONF_11)) {\n                    return \"11g\";  // NOI18N\n                }\n                if (args.contains(IDE_PRODUCT_10)) {\n                    return \"10g\";  // NOI18N\n                }\n                if (IDE_CONF_12_PATTERN.matcher(args).find()) {\n                    return \"12c\";  // NOI18N\n                }\n            }\n        }\n        return null;\n    }\n    \n    \n    /**\n     * Detects JDeveloper IDE. It returns\n     * {@link JDeveloperApplicationType} for JDeveloper 12c, 11g and 10g.\n     *\n     * @return {@link ApplicationType} subclass or <code>null</code> if\n     * this application is not JDeveloper IDE\n     */\n    public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) {\n        String version = getJDeveloperVersion(jvm,mainClass);\n        \n        if (version != null) {\n            return new JDeveloperApplicationType(app,version);\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/JavaPluginApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport java.awt.Image;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * This ApplicationType represent Java-Plugin.\n * \n * @author Luis-Miguel Alventosa\n */\npublic class JavaPluginApplicationType extends ApplicationType {\n\n    private String version;\n\n    public JavaPluginApplicationType(String version) {\n        this.version = version;\n    }\n\n    /**\n     * Gets the name of the Java plugin.\n     * @return this application's name\n     */\n    public String getName() {\n        return NbBundle.getMessage(JavaPluginApplicationType.class, \"LBL_Java_Plug-in_ver\", version);   // NOI18N\n    }\n\n    /**\n     * Gets the version of the Java-Plugin.\n     * The version is the same as {@code java.version} of the JVM\n     * @return this Java-Plugin's version\n     */\n    public String getVersion() {\n        return version;\n    }\n\n    /**\n     * Gets the description of the application.\n     * @return this application's description\n     */\n    public String getDescription() {\n        return NbBundle.getMessage(JavaPluginApplicationType.class, \"LBL_Java_Plug-in\");    // NOI18N\n    }\n\n    /**\n     * Gets the icon of the application.\n     * @return this application's icon\n     */\n    public Image getIcon() {\n        String iconPath = \"org/graalvm/visualvm/application/resources/application.png\";   // NOI18N\n        return ImageUtilities.loadImage(iconPath, true);\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/JavaPluginApplicationTypeFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\n/**\n * Factory which recognizes Java-Plugin application \n * @author Luis-Miguel Alventosa\n */\npublic class JavaPluginApplicationTypeFactory\n        extends AbstractModelProvider<ApplicationType, Application> {\n\n    private static final String JAVA_PLUGIN = \"-Djavaplugin.version=\";  // NOI18N\n    private static final String JAVA_PLUGIN2_MAIN = \"sun.plugin2.main.client.PluginMain\"; // NOI18N\n\n    /**\n     * Detects Java-Plugin application.\n     * @return {@link JavaPluginApplicationType} instance or <code>null</code>\n     * if application is not Java-Plugin application\n     * @param application Application\n     */\n    @Override\n    public ApplicationType createModelFor(Application application) {\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        if (jvm.isBasicInfoSupported()) {\n            String args = jvm.getJvmArgs();\n            int plugin_index = args != null ? args.indexOf(JAVA_PLUGIN) : -1;\n            if (plugin_index != -1) {\n                String version;\n                int version_index = plugin_index + JAVA_PLUGIN.length();\n                int space_index = args.indexOf(' ', version_index);\n                if (space_index != -1) {\n                    version = args.substring(version_index, space_index);\n                } else {\n                    version = args.substring(version_index);\n                }\n                return new JavaPluginApplicationType(version);\n            }\n            if (JAVA_PLUGIN2_MAIN.equals(jvm.getMainClass())) { // detect Java Plugin2\n                return new JavaPluginApplicationType(\"2\");  // NOI18N              \n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/JavaWebStartApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport java.awt.Image;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * This ApplicationType represent Java Web Start application.\n * @author Luis-Miguel Alventosa\n */\npublic class JavaWebStartApplicationType extends ApplicationType {\n\n    private String version;\n\n    public JavaWebStartApplicationType(String version) {\n        this.version = version;\n    }\n\n    /**\n     * Gets the name of the Java Web Start.\n     * @return this application's name\n     */\n    public String getName() {\n        return NbBundle.getMessage(JavaWebStartApplicationType.class, \"LBL_Java_Web_Start\");    // NOI18N\n    }\n\n    /**\n     * Gets the version of the Java Web Start.\n     * The version is the same as {@code java.version} of the JVM\n     * @return this Java Web Start's version\n     */\n    public String getVersion() {\n        return version;\n    }\n\n    /**\n     * Gets the description of the application.\n     * @return this application's description\n     */\n    public String getDescription() {\n        return NbBundle.getMessage(JavaWebStartApplicationType.class, \"LBL_Java_Web_Start\");    // NOI18N\n    }\n\n    /**\n     * Gets the icon of the application.\n     * @return this application's icon\n     */\n    public Image getIcon() {\n        String iconPath = \"org/graalvm/visualvm/application/resources/application.png\";   // NOI18N\n        return ImageUtilities.loadImage(iconPath, true);\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/JavaWebStartApplicationTypeFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\n/**\n * Factory which recognizes Java Web Start Application\n * @author Luis-Miguel Alventosa\n */\npublic class JavaWebStartApplicationTypeFactory\n        extends AbstractModelProvider<ApplicationType, Application> {\n\n    private static final String JWS = \"-Djnlpx.home=\";  // NOI18N\n\n    /**\n     * Detects Java Web Start application.\n     * @return {@link JavaWebStartApplicationType} instance or <code>null</code>\n     * if application is not Java Web Start application\n     * @param application Application\n     */\n    @Override\n    public ApplicationType createModelFor(Application application) {\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        if (jvm.isBasicInfoSupported()) {\n            String args = jvm.getJvmArgs();\n            if (args != null && args.contains(JWS)) {\n                return new JavaWebStartApplicationType(\"\");\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/MainClassApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport java.awt.Image;\nimport org.graalvm.visualvm.application.Application;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n\n/**\n * ApplicationType which has custom name and icon.\n * Instance of this class is constructed by {@link MainClassApplicationTypeFactory}\n * @author Tomas Hurka\n */\npublic class MainClassApplicationType extends ApplicationType  {\n  String name;\n  String description;\n  String iconPath;\n\n  MainClassApplicationType(Application app, String n, String d, String path) {\n    name = n;\n    description = d;\n    iconPath = path;\n  }\n\n  /**\n   * {@inheritDoc}\n   */ \n  public String getName() {\n    return name;\n  }\n\n  /**\n   * {@inheritDoc}\n   */\n  public String getVersion() {\n    return NbBundle.getMessage(MainClassApplicationType.class, \"LBL_Unknown\");  // NOI18N\n  }\n\n  /**\n   * {@inheritDoc}\n   */\n  public String getDescription() {\n    return description != null ? description : \"\"; // NOI18N\n  }\n\n  /**\n   * {@inheritDoc}\n   */\n  public Image getIcon() {\n    return ImageUtilities.loadImage(iconPath, true);\n  }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/MainClassApplicationTypeFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.openide.util.NbBundle;\n\n/**\n * This application type factory recognizes some well-known Java application\n * based on their main class name.\n * \n * @author Tomas Hurka\n */\npublic class MainClassApplicationTypeFactory extends AbstractModelProvider<ApplicationType,Application> {\n    private static final int CLASS_NAME = 0;\n    private static final int NAME = 1;\n    private static final int DESCRIPTION = 2;\n    private static final int ICON_PATH = 3;\n\n    private String[][] appmatrix = {\n        // build tools\n        {\"org.apache.tools.ant.launch.Launcher\",\"Ant\",descr(\"DESCR_Ant\"),\"org/graalvm/visualvm/application/resources/application.png\"},  // NOI18N\n\n        // Application servers\n        {\"com.sun.enterprise.server.PELaunch\",\"GlassFish\",descr(\"DESCR_GlassFish\"),\"org/graalvm/visualvm/application/type/resources/GlassFish.png\"},   // NOI18N\n        {\"com.sun.enterprise.glassfish.bootstrap.ASMain\",\"GlassFish\",descr(\"DESCR_GlassFish\"),\"org/graalvm/visualvm/application/type/resources/GlassFish.png\"},   // NOI18N\n        {\"com.sun.enterprise.ee.nodeagent.NodeAgentMain\", \"GlassFish Node\", \"GlassFish Node\", \"org/graalvm/visualvm/application/type/resources/GlassFish.png\"}, // NOI18N\n        {\"org.apache.catalina.startup.Bootstrap\",\"Tomcat\",descr(\"DESCR_Tomcat\"),\"org/graalvm/visualvm/application/type/resources/Tomcat.png\"},  // NOI18N\n        {\"org.jboss.Main\",\"JBoss\",descr(\"DESCR_JBoss\"),\"org/graalvm/visualvm/application/resources/application.png\"},  // NOI18N\n        \n        // JDK tools\n        {\"com.sun.tools.example.debug.tty.TTY\",\"Jdb\",descr(\"DESCR_Jdb\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"com.sun.tools.hat.Main\",\"JHat\",descr(\"DESCR_Jhat\"),\"org/graalvm/visualvm/application/resources/application.png\"},   // NOI18N\n        {\"com.sun.tools.jdeprscan.Main\",\"Jdeprscan\",descr(\"DESCR_Jdeprscan\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"com.sun.tools.jdeps.Main\",\"Jdeps\",descr(\"DESCR_Jdeps\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"com.sun.tools.script.shell.Main\",\"Jrunscript\",descr(\"DESCR_Jrunscript\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"jdk.incubator.jpackage.main.Main\",\"Jpackage\",descr(\"DESCR_Jpackage\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"jdk.internal.jshell.tool.JShellToolProvider\",\"JShell\",descr(\"DESCR_JShell\"),\"org/graalvm/visualvm/application/resources/application.png\"},  // NOI18N\n        {\"jdk.jfr.internal.tool.Main\",\"Jfr\",descr(\"DESCR_Jfr\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"jdk.jshell.execution.RemoteExecutionControl\",\"JShell remote agent\",descr(\"DESCR_JShell\"),\"org/graalvm/visualvm/application/resources/application.png\"},  // NOI18N\n        {\"jdk.tools.jimage.Main\",\"Jimage\",descr(\"DESCR_Jimage\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"jdk.tools.jlink.internal.Main\",\"Jlink\",descr(\"DESCR_Jlink\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"jdk.tools.jmod.Main\",\"Jmod\",descr(\"DESCR_Jmod\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"sun.jvm.hotspot.SALauncher\",\"Jhsdb\",descr(\"DESCR_Jhsdb\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"sun.jvm.hotspot.jdi.SADebugServer\",\"jsadebugd\",descr(\"DESCR_Jsadebugd\"),\"org/graalvm/visualvm/application/resources/application.png\"},   // NOI18N\n        {\"sun.jvm.hotspot.tools.JMap\",\"JMap\",descr(\"DESCR_Jmap\"),\"org/graalvm/visualvm/application/resources/application.png\"},   // NOI18N\n        {\"sun.jvm.hotspot.tools.JStack\",\"JStack\",descr(\"DESCR_Jstack\"),\"org/graalvm/visualvm/application/resources/application.png\"},   // NOI18N\n        {\"sun.net.httpserver.simpleserver.JWebServer\",\"Jwebserver\",descr(\"DESCR_Jwebserver\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"sun.tools.jcmd.JCmd\",\"Jcmd\",descr(\"DESCR_Jcmd\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"sun.tools.jconsole.JConsole\",\"JConsole\",descr(\"DESCR_JConsole\"),\"org/graalvm/visualvm/application/resources/application.png\"},  // NOI18N\n        {\"sun.tools.jinfo.JInfo\",\"JInfo\",descr(\"DESCR_Jinfo\"),\"org/graalvm/visualvm/application/resources/application.png\"},   // NOI18N\n        {\"sun.tools.jmap.JMap\",\"JMap\",descr(\"DESCR_Jmap\"),\"org/graalvm/visualvm/application/resources/application.png\"},  // NOI18N\n        {\"sun.tools.jps.Jps\",\"Jps\",descr(\"DESCR_Jps\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"sun.tools.jstack.JStack\",\"JStack\",descr(\"DESCR_Jstack\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"sun.tools.jstat.Jstat\",\"Jstat\",descr(\"DESCR_Jstat\"),\"org/graalvm/visualvm/application/resources/application.png\"},   // NOI18N\n        {\"sun.tools.jstatd.Jstatd\",\"Jstatd\",descr(\"DESCR_Jstatd\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        \n        // JDK utilitites\n        {\"sun.tools.jar.Main\",\"Jar\",descr(\"DESCR_Jar\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"com.sun.java.util.jar.pack.Driver\",\"pack200\",descr(\"DESCR_Pack200\"),\"org/graalvm/visualvm/application/resources/application.png\"}, // NOI18N\n        {\"com.sun.tools.javadoc.Main\",\"JavaDoc\",descr(\"DESCR_JavaDoc\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"com.sun.tools.javac.Main\",\"Javac\",descr(\"DESCR_Javac\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"com.sun.tools.javah.Main\",\"Javah\",descr(\"DESCR_Javah\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"sun.tools.javap.Main\",\"Javap\",descr(\"DESCR_Javap\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"sun.security.tools.JarSigner\",\"JarSigner\",descr(\"DESCR_JarSigner\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"com.sun.tools.apt.Main\",\"APT\",descr(\"DESCR_Apt\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"sun.applet.Main\",\"Applet Viewer\",descr(\"DESCR_AppletViewer\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"sun.applet.AppletViewer\",\"Applet Viewer\",descr(\"DESCR_AppletViewer\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n\n        // Best known JDK demos\n        {\"FileChooserDemo\",\"FileChooserDemo\",descr(\"DESCR_JdkDemoApp\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"Font2DTest\",\"Font2DTest\",descr(\"DESCR_JdkDemoApp\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"java2d.Java2Demo\",\"Java2Demo\",descr(\"DESCR_JdkDemoApp\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"Metalworks\",\"Metalworks\",descr(\"DESCR_JdkDemoApp\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"Notepad\",\"Notepad\",descr(\"DESCR_JdkDemoApp\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"SampleTree\",\"SampleTree\",descr(\"DESCR_JdkDemoApp\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"Stylepad\",\"Stylepad\",descr(\"DESCR_JdkDemoApp\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"SwingSet2\",\"SwingSet2\",descr(\"DESCR_JdkDemoApp\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        {\"TableExample\",\"TableExample\",descr(\"DESCR_JdkDemoApp\"),\"org/graalvm/visualvm/application/resources/application.png\"},    // NOI18N\n        \n        // Java DB\n        {\"org.apache.derby.drda.NetworkServerControl\", \"JavaDB\", descr(\"DESCR_JavaDb\"), \"org/graalvm/visualvm/application/type/resources/JavaDB.png\"},   // NOI18N\n\n        // JRockit Mission Control\n        {\"com.jrockit.mc.rcp.start.MCMain\",\"JRockit Mission Control\",descr(\"DESCR_JRMC\"),\"org/graalvm/visualvm/application/type/resources/JRMC.png\"},  // NOI18N\n\n        // Oracle WebLogic\n        {\"weblogic.Server\",\"WebLogic\",descr(\"DESCR_WLS\"),\"org/graalvm/visualvm/application/type/resources/WLS.png\"},  // NOI18N\n        \n        // JRuby runtime\n        {\"org.jruby.Main\",descr(\"LBL_Jruby\"),descr(\"DESCR_Jruby\"),\"org/graalvm/visualvm/application/type/resources/JRuby.png\"},  // NOI18N\n        \n        // Scala runtime\n        {\"scala.tools.nsc.MainGenericRunner\",descr(\"LBL_Scala\"),descr(\"DESCR_Scala\"),\"org/graalvm/visualvm/application/type/resources/Scala.png\"},  // NOI18N\n        \n        // Clojure runtime\n        {\"clojure.main\",descr(\"LBL_Clojure\"),descr(\"DESCR_Clojure\"),\"org/graalvm/visualvm/application/type/resources/Clojure.png\"},  // NOI18N\n        {\"clojure.jar\",descr(\"LBL_Clojure\"),descr(\"DESCR_Clojure\"),\"org/graalvm/visualvm/application/type/resources/Clojure.png\"},  // NOI18N\n        {\"clojure.lang.Script\",descr(\"LBL_Clojure\"),descr(\"DESCR_Clojure\"),\"org/graalvm/visualvm/application/type/resources/Clojure.png\"},  // NOI18N\n        {\"clojure.lang.Repl\",descr(\"LBL_Clojure\"),descr(\"DESCR_Clojure\"),\"org/graalvm/visualvm/application/type/resources/Clojure.png\"},  // NOI18N\n        \n        // Groovy runtime\n        {\"org.codehaus.groovy.tools.GroovyStarter\",descr(\"LBL_Groovy\"),descr(\"DESCR_Groovy\"),\"org/graalvm/visualvm/application/type/resources/Groovy.png\"},  // NOI18N\n        \n        // Jython runtime\n        {\"org.python.util.jython\",descr(\"LBL_Jython\"),descr(\"DESCR_Jython\"),\"org/graalvm/visualvm/application/type/resources/Jython.png\"},  // NOI18N\n\n        // Gradle runtime\n        {\"org.gradle.launcher.daemon.bootstrap.GradleDaemon\",descr(\"LBL_Gradle\"),descr(\"DESCR_Gradle\"),\"org/graalvm/visualvm/application/type/resources/Gradle.png\"},  // NOI18N\n        {\"org.gradle.launcher.GradleMain\",descr(\"LBL_GradleLauncher\"),descr(\"DESCR_GradleLauncher\"),\"org/graalvm/visualvm/application/type/resources/Gradle.png\"},  // NOI18N\n        {\"org.gradle.wrapper.GradleWrapperMain\",descr(\"LBL_GradleWrapper\"),descr(\"DESCR_GradleWrapper\"),\"org/graalvm/visualvm/application/type/resources/Gradle.png\"},  // NOI18N\n        {\"worker.org.gradle.process.internal.worker.GradleWorkerMain\",descr(\"LBL_GradleWorker\"),descr(\"DESCR_GradleWorker\"),\"org/graalvm/visualvm/application/type/resources/Gradle.png\"},  // NOI18N\n    };\n    \n    Map<String,String[]> map;\n\n    private static String descr(String key) {\n        return NbBundle.getMessage(MainClassApplicationTypeFactory.class, key); // NOI18N\n    }\n    \n    protected MainClassApplicationTypeFactory() {\n        map = new HashMap<>();\n        for (String[] appDesc : appmatrix) {\n            map.put(appDesc[CLASS_NAME],appDesc);\n        }\n    }\n    \n    /**\n     * Detects well-known application.\n     * @param appl Application\n     * @return {@link MainClassApplicationType} instance or <code>null</code>\n     * if application is not well-known application\n     */\n    public ApplicationType createModelFor(Application appl) {\n        Jvm jvm = JvmFactory.getJVMFor(appl);\n            \n        if (jvm.isBasicInfoSupported()) {\n            String mainClass = jvm.getMainClass();\n            if (mainClass != null) {\n                return createApplicationTypeFor(appl,jvm,mainClass);\n            }\n        }\n        return null;\n    }\n    \n    /**\n     * Creates ApplicationType for application, jvm and mainClass. Can be overridden\n     * by subclasses, which relies on mainClass name\n     * @param app Application\n     * @param jvm Applications's jvm\n     * @param mainClass Application's mainClass\n     * @return instance of {@link ApplicationType} or \n     * <CODE>null</CODE> if the app cannot be recognized \n     * by this ApplicationType factory\n     */ \n    public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) {\n        String[] appDesc = map.get(mainClass);\n        if (appDesc != null) {\n            return new MainClassApplicationType(app,appDesc[NAME],appDesc[DESCRIPTION],appDesc[ICON_PATH]);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/MavenApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.openide.util.NbBundle;\n\n/**\n * This {@link ApplicationType} represents Apache Maven application.\n * @author Tomas Hurka\n */\npublic class MavenApplicationType extends MainClassApplicationType {\n    \n    MavenApplicationType(Application app, boolean wrapper) {\n        super(app,\n              wrapper ? \"Apache Maven Wrapper\" : \"Apache Maven\",     // NOI18N\n              NbBundle.getMessage(MavenApplicationType.class, wrapper ? \"DESCR_MavenWrapperApplicationType\" : \"DESCR_MavenApplicationType\"), // NOI18N\n              \"org/graalvm/visualvm/application/type/resources/Maven2Icon.png\"); // NOI18N\n    }    \n    \n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/MavenApplicationTypeFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\n\n/**\n * Factory which recognizes Apache Maven.\n * @author Tomas Hurka\n */\npublic class MavenApplicationTypeFactory extends MainClassApplicationTypeFactory {\n    \n    private static final String MAIN_CLASS = \"org.codehaus.classworlds.Launcher\"; // NOI18N\n    private static final String MAIN_CLASS_1 = \"org.codehaus.plexus.classworlds.launcher.Launcher\"; // NOI18N\n    private static final String PROP_1 = \"-Dclassworlds.conf=\"; // NOI18N\n    private static final String PROP_2 = \"-Dmaven.home=\"; // NOI18N\n    private static final String WRAPPER_MAIN_CLASS = \"org.apache.maven.wrapper.MavenWrapperMain\";   // NOI18N\n    \n    /**\n     * Detects Apache Maven. It returns\n     * {@link MavenApplicationType} for Maven.\n     *\n     * @return {@link ApplicationType} subclass or <code>null</code> if\n     * this application is not Apache Maven\n     */\n    public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) {\n        if (MAIN_CLASS.equals(mainClass) || MAIN_CLASS_1.equals(mainClass)) {\n            String args = jvm.getJvmArgs();\n            if (args != null) {\n                if (args.contains(PROP_1) && args.contains(PROP_2)) {\n                    return new MavenApplicationType(app, false);\n                }\n            }\n        }\n        if (WRAPPER_MAIN_CLASS.equals(mainClass)) {\n            return new MavenApplicationType(app, true);\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/NetBeans3xApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.openide.util.NbBundle;\n\n/**\n * This {@link ApplicationType} represents NetBeans 3.x application\n * @author Tomas Hurka\n */\npublic class NetBeans3xApplicationType extends MainClassApplicationType {\n    \n    \n    NetBeans3xApplicationType(Application app, Jvm jvm) {\n        super(app, \"NetBeans 3.x\", NbBundle.getMessage( // NOI18N\n                MainClassApplicationType.class, \"DESCR_NetBeansApplicationType\"), // NOI18N\n                \"org/graalvm/visualvm/application/resources/application.png\"); // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/NetBeansApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport java.awt.Image;\nimport java.util.Properties;\nimport java.util.Scanner;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport static org.graalvm.visualvm.application.type.NetBeansApplicationTypeFactory.NB_CLUSTER;\nimport static org.graalvm.visualvm.application.type.NetBeansApplicationTypeFactory.PRODUCT_VERSION_PROPERTY;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * This {@link ApplicationType} represents NetBeans application from version 4.0.\n * @author Tomas Hurka\n */\npublic class NetBeansApplicationType extends ApplicationType {\n    private static final String BUILD_NUMBER_PROPERTY=\"netbeans.buildnumber\";\n    private static final String[] BUILD_NUMBERS={\n                                    \"201006101454\",\"6.9\",\n                                    \"201007282301\",\"6.9.1\",\n                                    \"201104080000\",\"7.0\",\n                                    \"201107282000\",\"7.0.1\"\n                                };\n    private static final String VERSION_REG=\"\\\\d{1,2}\\\\.\\\\d{1,2}(\\\\.\\\\d{1,2})?\";\n    Application application;\n    String name;\n    Set<String> clusters;\n    Jvm jvm;\n    \n    NetBeansApplicationType(Application app,Jvm vm,Set<String> cls) {\n        application = app;\n        jvm = vm;\n        clusters = cls;\n    }\n    \n    /**\n     * Returns set of BetBeans' clusters.\n     *\n     */\n    public Set<String> getClusters() {\n        return clusters;\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    public String getName() {\n        return \"NetBeans IDE \" + getVersion();    // NOI18N\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    public String getVersion() {\n        for (String cluster : getClusters()) {\n            if (cluster.startsWith(NB_CLUSTER)) {\n                String ver = cluster.substring(NB_CLUSTER.length());\n                \n                if (!ver.isEmpty() && Character.isDigit(ver.charAt(0))) {\n                    return ver;\n                }\n            }\n            if (cluster.equals(NB_CLUSTER)) {\n                //6.9+ does not have version in nb cluster\n                // try to use system properties\n                if (jvm.isGetSystemPropertiesSupported()) {\n                    String ver = getVersionFromSysProps(jvm.getSystemProperties());\n                    if (ver != null) {\n                        return ver;\n                    }\n                }\n                return \"6.9+\";  // NOI18N\n            }\n        }\n        return NbBundle.getMessage(NetBeansApplicationType.class, \"LBL_Unknown\");   // NOI18N\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    public String getDescription() {\n        if (jvm.isGetSystemPropertiesSupported()) {\n            Properties sysProps = jvm.getSystemProperties();\n            \n            if (sysProps != null) {\n                String versionString = sysProps.getProperty(PRODUCT_VERSION_PROPERTY);\n\n                if (versionString != null) {\n                    return versionString;\n                }\n            }\n        }\n        return NbBundle.getMessage(NetBeansApplicationType.class, \"DESCR_NetBeansApplicationType\");   // NOI18N\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    public Image getIcon() {\n        String iconPath = \"org/graalvm/visualvm/application/type/resources/NetBeans.png\"; // NOI18N\n        return ImageUtilities.loadImage(iconPath, true);\n    }\n\n    private String getVersionFromSysProps(Properties properties) {\n        if (properties == null) return null;\n        String versionString = properties.getProperty(PRODUCT_VERSION_PROPERTY);\n        \n        if (versionString != null) {\n            Scanner s = new Scanner(versionString);\n\n            if (s.hasNext(\"Apache\")) s.next();  // NOI18N\n            if (\"NetBeans\".equals(s.next())) {  // NOI18N\n                if (\"IDE\".equals(s.next())) {   // NOI18N\n                    return s.next();\n                }\n            }\n            String ver = s.findInLine(VERSION_REG);\n            if (ver != null) {\n                return ver;\n            }\n        } else {\n            String buildNumber = properties.getProperty(BUILD_NUMBER_PROPERTY);\n            for (int i=0; i<BUILD_NUMBERS.length; i+=2) {\n                if (BUILD_NUMBERS[i].equals(buildNumber)) {\n                    return BUILD_NUMBERS[i+1];\n                }\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/NetBeansApplicationTypeFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.Scanner;\nimport java.util.Set;\nimport java.util.regex.Pattern;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\n\n/**\n * Factory which recognizes NetBeans IDE, NetBeans Platform based\n * application and VisualVM itself\n * @author Tomas Hurka\n */\npublic class NetBeansApplicationTypeFactory extends MainClassApplicationTypeFactory {\n    \n    private static final String NETBEANS_DIRS = \"-Dnetbeans.dirs=\"; // NOI18N\n    private static final String NB_PLATFORM_HOME = \"-Dnetbeans.home=\"; // NOI18N\n    private static final String BRANDING_ID = \"--branding \"; // NOI18N\n    private static final String VISUALVM_ID = \"visualvm\"; // NOI18N\n    private static final String MAIN_CLASS = \"org.netbeans.Main\"; // NOI18N\n    private static final Pattern NBCLUSTER_PATTERN = Pattern.compile(\"nb[0-9]+\\\\.[0-9]+\");    // NOI18N\n    private static final String BUILD_CLUSTER = \"cluster\"; // NOI18N\n    private static final String VISUALVM_BUILD_WIN_ID = \"\\\\visualvm\\\\build\\\\cluster;\"; // NOI18N\n    static final String NB_CLUSTER = \"nb\";    // NOI18N\n    static final String PRODUCT_VERSION_PROPERTY=\"netbeans.productversion\";  // NOI18N\n    \n    private boolean isNetBeans(Jvm jvm, String mainClass) {\n        if (MAIN_CLASS.equals(mainClass)) {\n            return true;\n        }\n        if (mainClass == null || mainClass.isEmpty()) {    // there is no main class - detect new NB 7.0 windows launcher\n            String args = jvm.getJvmArgs();\n            if (args != null && args.contains(NB_PLATFORM_HOME)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    \n    protected Set<String> computeClusters(Jvm jvm) {\n        String args = jvm.getJvmArgs();\n        int clusterIndex = args != null ? args.indexOf(NETBEANS_DIRS) : -1;\n        String pathSeparator = jvm.getJavaHome().contains(\"\\\\\")?\";\":\":\";    // NOI18N\n        String separator = pathSeparator.equals(\":\")?\"/\":\"\\\\\";      // NOI18N\n        Set<String> clusters = new HashSet<>();\n        \n        if (clusterIndex > -1) {\n            String clustersString=args.substring(clusterIndex);\n            int endIndex = clustersString.indexOf(\" -\");  // NOI18N\n            Scanner clusterScanner;\n            if (endIndex == -1) {\n                endIndex = clustersString.indexOf(\" exit\");  // NOI18N\n            }\n            if (endIndex > -1) {\n                clustersString = clustersString.substring(0,endIndex);\n            }\n            clusterScanner = new Scanner(clustersString).useDelimiter(pathSeparator);\n            while (clusterScanner.hasNext()) {\n                String clusterPath = clusterScanner.next();\n                int pathIndex = clusterPath.lastIndexOf(separator);\n                if (pathIndex > -1) {\n                    clusters.add(clusterPath.substring(pathIndex+1));\n                }\n            }\n        }\n        return Collections.unmodifiableSet(clusters);\n    }\n    \n    protected String getBranding(Jvm jvm) {\n        String args = jvm.getMainArgs();\n        if (args != null) {\n            int brandingOffset = args.indexOf(BRANDING_ID);\n            \n            if (brandingOffset > -1) {\n                Scanner sc = new Scanner(args.substring(brandingOffset));\n                sc.next(); // skip --branding\n                if (sc.hasNext()) {\n                    return sc.next();\n                }\n            }\n        }\n        return null;\n    }\n    \n    /**\n     * Detects NetBeans IDE, NetBeans Platform based\n     * application and VisualVM itself. It returns\n     * {@link VisualVMApplicationType} for VisualVM,\n     * {@link NetBeansApplicationType} for NetBeans 4.0 and newer and\n     * {@link NetBeans3xApplicationType} for NetBeans 3.x\n     *\n     * @return {@link ApplicationType} subclass or <code>null</code> if\n     * this application is not NetBeans\n     */\n    public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) {\n        if (isNetBeans(jvm,mainClass)) {\n            String branding = getBranding(jvm);\n            if (VISUALVM_ID.equals(branding)) {\n                return new VisualVMApplicationType(app);\n            }\n            Set<String> clusters = computeClusters(jvm);\n            \n            for (String cluster : clusters) {\n                if (NBCLUSTER_PATTERN.matcher(cluster).matches()) {\n                    return new NetBeansApplicationType(app,jvm,clusters);\n                }\n                if (NB_CLUSTER.equals(cluster)) {\n                    return new NetBeansApplicationType(app,jvm,clusters);\n                }\n                if (VISUALVM_ID.equals(cluster)) {\n                    return new VisualVMApplicationType(app);\n                }\n                if (BUILD_CLUSTER.equals(cluster)) {\n                    // NetBeans platform application was executed \n                    // directly from IDE or from ant script.\n                    // Check if it is VisualVM on Windows - on other platforms\n                    // VisualVM is recognized via branding\n                    if (jvm.getJvmArgs().contains(VISUALVM_BUILD_WIN_ID)) {\n                        return new VisualVMApplicationType(app);\n                    }\n                }\n            }\n            if (clusters.isEmpty() && branding == null) {\n                return new NetBeans3xApplicationType(app,jvm);\n            }\n            return new NetBeansBasedApplicationType(app,jvm,clusters,branding);\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/NetBeansBasedApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport java.awt.Image;\nimport java.util.Properties;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport static org.graalvm.visualvm.application.type.NetBeansApplicationTypeFactory.PRODUCT_VERSION_PROPERTY;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n * This {@link ApplicationType} represents application based on\n * NetBeans Platform.\n * @author Tomas Hurka\n */\npublic class NetBeansBasedApplicationType extends ApplicationType {\n    private static final Logger LOGGER = Logger.getLogger(NetBeansBasedApplicationType.class.getName());\n    private static final int START_TIME = 5000;\n    private static final int RETRY_TIME = 5000;\n\n    Application application;\n    String branding;\n    Set<String> clusters;\n    String fullVersionString;\n    \n    NetBeansBasedApplicationType(Application app,Jvm jvm,Set<String> cls, String br) {\n        application = app;\n        clusters = cls;\n        branding = br;\n        if (jvm.isGetSystemPropertiesSupported()) {\n            Properties p = jvm.getSystemProperties();\n            if (p != null) {\n                fullVersionString = p.getProperty(PRODUCT_VERSION_PROPERTY);\n                if (fullVersionString == null) {\n                    MonitoredData d = jvm.getMonitoredData();\n                    if (d != null && d.getUpTime() < START_TIME) {\n                        LOGGER.log(Level.INFO, \"{0} full version not initialized\", app.getId());\n                        RequestProcessor.getDefault().post(() -> updateFullVersion(jvm), RETRY_TIME);\n                    }\n                }\n            }\n        }\n    }\n    \n    /**\n     * Returns set of NetBeans' clusters.\n     *\n     */\n    public Set<String> getClusters() {\n        return clusters;\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    public String getName() {\n        if (fullVersionString != null) {\n            int index = fullVersionString.indexOf('('); // NOI18N\n            if (index != -1) {\n                return fullVersionString.substring(0,index).trim();\n            }\n            index = fullVersionString.lastIndexOf(' '); // NOI18N\n            if (index != -1) {\n                String buildNo = fullVersionString.substring(index+1);\n                if (buildNo.length()>19 && buildNo.charAt(8)=='-') { // NOI18N\n                    return fullVersionString.substring(0,index);\n                }\n            }\n            return fullVersionString;\n        }\n        return NbBundle.getMessage(NetBeansBasedApplicationType.class, \"LBL_NbPlatformApplication\"); // NOI18N\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    public String getVersion() {\n        return NbBundle.getMessage(NetBeansBasedApplicationType.class, \"LBL_Unknown\");  // NOI18N\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    public String getDescription() {\n        if (fullVersionString != null) {\n            return fullVersionString;\n        }\n        return NbBundle.getMessage(NetBeansBasedApplicationType.class, \"DESCR_NetBeansBasedApplicationType\"); // NOI18N\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    public Image getIcon() {\n        String iconPath = \"org/graalvm/visualvm/application/type/resources/NetBeansPlatform.png\";   // NOI18N\n        return ImageUtilities.loadImage(iconPath, true);\n    }\n\n    private void updateFullVersion(Jvm jvm) {\n        if (application.getState() != Application.STATE_AVAILABLE) {\n            return;\n        }\n        Properties p = jvm.getSystemProperties();\n        if (p != null) {\n            fullVersionString = p.getProperty(PRODUCT_VERSION_PROPERTY);\n            LOGGER.log(Level.INFO, \"updateFullVersion {0}\", fullVersionString);\n            if (fullVersionString != null) {\n                firePropertyChange(PROPERTY_NAME, null, fullVersionString);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/VisualVMApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.type;\n\nimport java.awt.Image;\nimport org.graalvm.visualvm.application.Application;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n\n/**\n * This {@link ApplicationType} represents VisualVM.\n * @author Tomas Hurka\n */\npublic class VisualVMApplicationType extends ApplicationType {\n    Application application;\n    \n    VisualVMApplicationType(Application app) {\n        application = app;\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    public String getName() {\n        return \"VisualVM\";  // NOI18N\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    public String getVersion() {\n        return NbBundle.getMessage(VisualVMApplicationType.class, \"LBL_Unknown\");   // NOI18N\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    public String getDescription() {\n        return NbBundle.getMessage(VisualVMApplicationType.class, \"DESCR_VisualVMApplicationType\");   // NOI18N\n    }\n    \n    /**\n     * {@inheritDoc}\n     */\n    public Image getIcon() {\n        String iconPath = \"org/graalvm/visualvm/application/resources/visualvm.png\";  // NOI18N\n        return ImageUtilities.loadImage(iconPath, true);\n    }\n}\n"
  },
  {
    "path": "visualvm/application/src/org/graalvm/visualvm/application/type/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Package with basic ApplicationType(s).\n */\npackage org.graalvm.visualvm.application.type;\n"
  },
  {
    "path": "visualvm/applicationviews/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.application.views\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.application.views.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/applicationviews/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.application.views/2\nOpenIDE-Module-Install: org/graalvm/visualvm/application/views/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/application/views/resources/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.1\n\n"
  },
  {
    "path": "visualvm/applicationviews/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.application.views-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/applicationviews/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=fbd63fa3\nbuild.xml.script.CRC32=cfc6f413\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=fbd63fa3\nnbproject/build-impl.xml.script.CRC32=1e1e54da\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/applicationviews/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/applicationviews/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.application.views</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.charts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.coredump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.heapdump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.threaddump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.28.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.46</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.application.views</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/applicationviews/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/ApplicationThreadsResponseProvider.java",
    "content": "/*\n * Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.application.views;\n\nimport java.lang.management.ThreadMXBean;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.MonitoredNumbersResponse;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic interface ApplicationThreadsResponseProvider {\n\n    ThreadMonitoredDataResponseProvider getMonitoredDataResponseProvider(Application app, ThreadMXBean threadMXBean);\n\n    public interface ThreadMonitoredDataResponseProvider {\n\n        MonitoredNumbersResponse createThreadMonitoredDataResponse();\n\n        void cleanup();\n    }\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/ApplicationViewsSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.application.views.monitor.ApplicationMonitorViewProvider;\nimport org.graalvm.visualvm.application.views.monitor.ApplicationSnapshotMonitorViewProvider;\nimport org.graalvm.visualvm.application.views.overview.ApplicationOverviewViewProvider;\nimport org.graalvm.visualvm.application.views.overview.ApplicationSnapshotOverviewViewProvider;\nimport org.graalvm.visualvm.application.views.threads.ApplicationSnapshotThreadsViewProvider;\nimport org.graalvm.visualvm.application.views.threads.ApplicationThreadsViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\n\n/**\n * Support for built-in application views in VisualVM.\n * Currently publishes Overview, Monitor and Threads subtabs for Application and\n * Overview subtab for ApplicationSnapshot.\n *\n * @author Jiri Sedlacek\n */\npublic final class ApplicationViewsSupport {\n    \n    private static ApplicationViewsSupport sharedInstance;\n    \n    private ApplicationSnapshotOverviewViewProvider applicationSnapshotOverviewView = new ApplicationSnapshotOverviewViewProvider();\n    private ApplicationOverviewViewProvider overviewPluggableView = new ApplicationOverviewViewProvider();\n    private ApplicationSnapshotMonitorViewProvider applicationSnapshotMonitorView = new ApplicationSnapshotMonitorViewProvider();\n    private ApplicationMonitorViewProvider monitorPluggableView = new ApplicationMonitorViewProvider();\n    private ApplicationSnapshotThreadsViewProvider applicationSnapshotThreadsView = new ApplicationSnapshotThreadsViewProvider();\n    private ApplicationThreadsViewProvider threadsPluggableView = new ApplicationThreadsViewProvider();\n    \n    \n    /**\n     * Returns singleton instance of ApplicationViewsSupport.\n     * \n     * @return singleton instance of ApplicationViewsSupport.\n     */\n    public static synchronized ApplicationViewsSupport sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new ApplicationViewsSupport();\n        return sharedInstance;\n    }\n    \n    \n    /**\n     * Returns PluggableDataSourceViewProvider for Overview application subtab.\n     * \n     * @return PluggableDataSourceViewProvider for Overview application subtab.\n     */\n    public PluggableDataSourceViewProvider<Application> getOverviewView() {\n        return overviewPluggableView;\n    }\n    \n    /**\n     * Returns PluggableDataSourceViewProvider for Overview application snapshot subtab.\n     * \n     * @return PluggableDataSourceViewProvider for Overview application snapshot subtab.\n     */\n    public PluggableDataSourceViewProvider<ApplicationSnapshot> getSnapshotOverviewView() {\n        return applicationSnapshotOverviewView;\n    }\n    \n    /**\n     * Returns PluggableDataSourceViewProvider for Monitor application subtab.\n     * \n     * @return PluggableDataSourceViewProvider for Monitor application subtab.\n     */\n    public PluggableDataSourceViewProvider<Application> getMonitorView() {\n        return monitorPluggableView;\n    }\n\n    /**\n     * Returns PluggableDataSourceViewProvider for Monitor application snapshot subtab.\n     *\n     * @return PluggableDataSourceViewProvider for Monitor application snapshot subtab.\n     */\n    public PluggableDataSourceViewProvider<ApplicationSnapshot> getSnapshotMonitorView() {\n        return applicationSnapshotMonitorView;\n    }\n    \n    /**\n     * Returns PluggableDataSourceViewProvider for Threads application subtab.\n     * \n     * @return PluggableDataSourceViewProvider for Threads application subtab.\n     */\n    public PluggableDataSourceViewProvider<Application> getThreadsView() {\n        return threadsPluggableView;\n    }\n\n    /**\n     * Returns PluggableDataSourceViewProvider for Threads application snapshot subtab.\n     *\n     * @return PluggableDataSourceViewProvider for Threads application snapshot subtab.\n     */\n    public PluggableDataSourceViewProvider<ApplicationSnapshot> getSnapshotThreadsView() {\n        return applicationSnapshotThreadsView;\n    }\n    \n    \n    private ApplicationViewsSupport() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(overviewPluggableView, Application.class);\n        DataSourceViewsManager.sharedInstance().addViewProvider(applicationSnapshotOverviewView, ApplicationSnapshot.class);\n        DataSourceViewsManager.sharedInstance().addViewProvider(monitorPluggableView, Application.class);\n        DataSourceViewsManager.sharedInstance().addViewProvider(applicationSnapshotMonitorView, ApplicationSnapshot.class);\n        DataSourceViewsManager.sharedInstance().addViewProvider(threadsPluggableView, Application.class);\n        DataSourceViewsManager.sharedInstance().addViewProvider(applicationSnapshotThreadsView, ApplicationSnapshot.class);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views;\n\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\nfinal class Installer extends ModuleInstall {\n    @Override\n    public void restored() {\n        ApplicationViewsSupport.sharedInstance();\n    }\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/monitor/ApplicationMonitorModel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.monitor;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.lang.management.MemoryMXBean;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.Attribute;\nimport javax.management.MBeanServerConnection;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.application.jvm.MonitoredDataListener;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.heapdump.HeapDumpSupport;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.openide.util.NbBundle;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ApplicationMonitorModel {\n    \n    private static final Logger LOGGER = Logger.getLogger(ApplicationMonitorModel.class.getName());\n    private static final String PROP_PREFIX = \"ApplicationMonitorModel_\";  // NOI18N\n    \n    static final String SNAPSHOT_VERSION = PROP_PREFIX + \"version\"; // NOI18N\n    private static final String SNAPSHOT_VERSION_DIVIDER = \".\"; // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = \"1\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MINOR = \"1\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION = CURRENT_SNAPSHOT_VERSION_MAJOR + SNAPSHOT_VERSION_DIVIDER + CURRENT_SNAPSHOT_VERSION_MINOR;\n    \n    private static final String PROP_NOT_DEFINED = \"<not defined>\"; // NOI18N\n\n    public static final String PROP_CHART_CACHE = PROP_PREFIX + \"chart_cache\";    // NOI18N\n    public static final String PROP_UPTIME = PROP_PREFIX + \"uptime\";    // NOI18N\n    public static final String PROP_PREV_UPTIME = PROP_PREFIX + \"prev_uptime\";    // NOI18N\n    public static final String PROP_INVOKE_GC_SUPPORTED = PROP_PREFIX + \"invoke_gc_supported\";    // NOI18N\n    public static final String PROP_HEAP_DUMP_SUPPORTED = PROP_PREFIX + \"heap_dump_supported\";    // NOI18N\n    public static final String PROP_CPU_MONITORING_SUPPORTED = PROP_PREFIX + \"cpu_monitoring_supported\";  // NOI18N\n    public static final String PROP_GC_MONITORING_SUPPORTED = PROP_PREFIX + \"gc_monitoring_supported\";  // NOI18N\n    public static final String PROP_MEMORY_MONITORING_SUPPORTED = PROP_PREFIX + \"memory_monitoring_supported\";  // NOI18N\n    public static final String PROP_CLASS_MONITORING_SUPPORTED = PROP_PREFIX + \"class_monitoring_supported\";    // NOI18N\n    public static final String PROP_THREADS_MONITORING_SUPPORTED = PROP_PREFIX + \"threads_monitoring_supported\";  // NOI18N\n    public static final String PROP_VIRTUAL_THREADS_MONITORING_SUPPORTED = PROP_PREFIX + \"virtual_threads_monitoring_supported\";  // NOI18N\n    public static final String PROP_NUMBER_OF_PROCESSORS = PROP_PREFIX + \"number_of_processors\";  // NOI18N\n\n    public static final String PROP_PROCESS_CPU_TIME = PROP_PREFIX + \"process_cpu_time\"; // NOI18N\n    public static final String PROP_PROCESS_GC_TIME = PROP_PREFIX + \"process_gc_time\"; // NOI18N\n    public static final String PROP_PREV_PROCESS_CPU_TIME = PROP_PREFIX + \"prev_process_cpu_time\"; // NOI18N\n    public static final String PROP_PREV_PROCESS_GC_TIME = PROP_PREFIX + \"prev_process_gc_time\"; // NOI18N\n    public static final String PROP_HEAP_NAME = PROP_PREFIX + \"heap_name\"; // NOI18N\n    public static final String PROP_HEAP_CAPACITY = PROP_PREFIX + \"heap_capacity\"; // NOI18N\n    public static final String PROP_HEAP_USED = PROP_PREFIX + \"heap_used\"; // NOI18N\n    public static final String PROP_MAX_HEAP = PROP_PREFIX + \"max_heap\"; // NOI18N\n    public static final String PROP_PERMGEN_NAME = PROP_PREFIX + \"permgen_name\"; // NOI18N\n    public static final String PROP_PERMGEN_CAPACITY = PROP_PREFIX + \"permgen_capacity\"; // NOI18N\n    public static final String PROP_PERMGEN_USED = PROP_PREFIX + \"permgen_used\"; // NOI18N\n    public static final String PROP_PERMGEN_MAX = PROP_PREFIX + \"permgen_max\"; // NOI18N\n    public static final String PROP_SHARED_UNLOADED = PROP_PREFIX + \"shared_unloaded\"; // NOI18N\n    public static final String PROP_TOTAL_UNLOADED = PROP_PREFIX + \"total_unloaded\"; // NOI18N\n    public static final String PROP_SHARED_LOADED = PROP_PREFIX + \"shared_loaded\"; // NOI18N\n    public static final String PROP_TOTAL_LOADED = PROP_PREFIX + \"total_loaded\"; // NOI18N\n    public static final String PROP_TOTAL_THREADS = PROP_PREFIX + \"total_threads\"; // NOI18N\n    public static final String PROP_DAEMON_THREADS = PROP_PREFIX + \"daemon_threads\"; // NOI18N\n    public static final String PROP_PEAK_THREADS = PROP_PREFIX + \"peak_threads\"; // NOI18N\n    public static final String PROP_STARTED_THREADS = PROP_PREFIX + \"started_threads\"; // NOI18N\n    public static final String PROP_PARALLELISM = PROP_PREFIX + \"parallelism\"; // NOI18N\n    public static final String PROP_POOL_SIZE = PROP_PREFIX + \"pool_size\"; // NOI18N\n    public static final String PROP_MOUNTED_VIRTUAL_THREADS_COUNT = PROP_PREFIX + \"mounted_virtual_thread_count\"; // NOI18N\n    public static final String PROP_QUEUED_VIRTUAL_THREAD_COUNT = PROP_PREFIX + \"queued_virtual_thread_count\"; // NOI18N\n\n    private static final String CPU_CHART_STORAGE = \"monitor_cpu.dat\"; // NOI18N\n    private static final String HEAP_CHART_STORAGE = \"monitor_heap.dat\"; // NOI18N\n    private static final String PERMGEN_CHART_STORAGE = \"monitor_permgen.dat\"; // NOI18N\n    private static final String CLASSES_CHART_STORAGE = \"monitor_classes.dat\"; // NOI18N\n    private static final String THREADS_CHART_STORAGE = \"monitor_threads.dat\"; // NOI18N\n    private static final String VIRTUAL_THREADS_CHART_STORAGE = \"monitor_vthreads.dat\"; // NOI18N\n    \n    private boolean initialized;\n    private final DataSource source;\n    private final boolean live;\n\n    private final List<ChangeListener> listeners;\n\n    private Jvm jvm;\n    private MemoryMXBean memoryMXBean;\n    private MonitoredDataListener monitoredDataListener;\n    private ObjectName virtualThreadsName;\n    private MBeanServerConnection connection;\n\n    private int chartCache = -1;\n\n    private long timestamp = -1;\n\n    private long uptime = -1;\n    private long prevUpTime = -1;\n    private boolean takeHeapDumpSupported = false;\n    private boolean cpuMonitoringSupported = false;\n    private boolean gcMonitoringSupported = false;\n    private boolean memoryMonitoringSupported = false;\n    private boolean classMonitoringSupported = false;\n    private boolean threadsMonitoringSupported = false;\n    private boolean virtualThreadsMonitoringSupported = false;\n    private int processorsCount = -1;\n\n    private long processCpuTime = -1;\n    private long processGcTime = -1;\n    private long prevProcessCpuTime = -1;\n    private long prevProcessGcTime = -1;\n    private String heapName;\n    private long heapCapacity = -1;\n    private long heapUsed = -1;\n    private long maxHeap = -1;\n    private String permgenName;\n    private long permgenCapacity = -1;\n    private long permgenUsed = -1;\n    private long permgenMax = -1;\n    private long sharedUnloaded = -1;\n    private long totalUnloaded = -1;\n    private long sharedLoaded = -1;\n    private long totalLoaded = -1;\n    private long totalThreads = -1;\n    private long daemonThreads = -1;\n    private long peakThreads = -1;\n    private long startedThreads = -1;\n    private int parallelism = -1;\n    private int poolSize = -1;\n    private int mountedVirtualThreadCount = -1;\n    private long queuedVirtualThreadCount = -1;\n\n    private SimpleXYChartSupport cpuChartSupport;\n    private SimpleXYChartSupport heapChartSupport;\n    private SimpleXYChartSupport permGenChartSupport;\n    private SimpleXYChartSupport classesChartSupport;\n    private SimpleXYChartSupport threadsChartSupport;\n    private SimpleXYChartSupport virtualThreadsChartSupport;\n\n    \n    public static ApplicationMonitorModel create(Application application, boolean live) {\n        return new ApplicationMonitorModel(application, live);\n    }\n    \n    public static ApplicationMonitorModel create(Snapshot snapshot) {\n        return new ApplicationMonitorModel(snapshot, false);\n    }\n\n    \n    public DataSource getSource() { return source; }\n    public boolean    isLive() { return live; }\n\n\n    public MemoryMXBean getMemoryMXBean() { return memoryMXBean; }\n\n    public int     getChartCache() { return chartCache; }\n    public boolean isInvokeGCSupported() { return memoryMXBean != null; }\n    public boolean isTakeHeapDumpSupported() { return takeHeapDumpSupported; }\n    public boolean isCpuMonitoringSupported() { return cpuMonitoringSupported; }\n    public boolean isGcMonitoringSupported() { return gcMonitoringSupported; }\n    public boolean isMemoryMonitoringSupported() { return memoryMonitoringSupported; }\n    public boolean isClassMonitoringSupported() { return classMonitoringSupported; }\n    public boolean isThreadsMonitoringSupported() { return threadsMonitoringSupported; }\n    public boolean isVirtualThreadsMonitoringSupported() { return virtualThreadsMonitoringSupported; }\n    public int     getProcessorsCount() { return processorsCount; }\n    \n    public long    getTimestamp() { return timestamp; }\n    public long    getUpTime() { return uptime; }\n    public long    getPrevUpTime() { return prevUpTime; }\n\n    public long getProcessCpuTime() { return processCpuTime; }\n    public long getProcessGcTime() { return processGcTime; }\n    public long getPrevProcessCpuTime() { return prevProcessCpuTime; }\n    public long getPrevProcessGcTime() { return prevProcessGcTime; }\n    public String getHeapName() { return heapName; }\n    public long getHeapCapacity() { return heapCapacity; }\n    public long getHeapUsed() { return heapUsed; }\n    public long getMaxHeap() { return maxHeap; }\n    public String getPermgenName() { return permgenName; }\n    public long getPermgenCapacity() { return permgenCapacity; }\n    public long getPermgenUsed() { return permgenUsed; }\n    public long getPermgenMax() { return permgenMax; }\n    public long getSharedUnloaded() { return sharedUnloaded; }\n    public long getTotalUnloaded() { return totalUnloaded; }\n    public long getSharedLoaded() { return sharedLoaded; }\n    public long getTotalLoaded() { return totalLoaded; }\n    public long getTotalThreads() { return totalThreads; }\n    public long getDeamonThreads() { return daemonThreads; }\n    public long getPeakThreads() { return peakThreads; }\n    public long getStartedThreads() { return startedThreads; }\n    public int getParallelism() { return parallelism; }\n    public int getPoolSize() { return poolSize; }\n    public int getMountedVirtualThreadCount() { return mountedVirtualThreadCount; }\n    public long getQueuedVirtualThreadCount() { return queuedVirtualThreadCount; }\n    \n    \n    public synchronized void initialize() {\n        if (initialized) return;\n        initialized = true;\n        if (source instanceof Application) initialize((Application)source);\n        else initialize((Snapshot)source);\n    }\n\n    public void registerCpuChartSupport(final SimpleXYChartSupport cpuChartSupport) {\n        this.cpuChartSupport = cpuChartSupport;\n        if (cpuChartSupport != null && source instanceof Snapshot)\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    File file = new File(source.getStorage().getDirectory(), CPU_CHART_STORAGE);\n                    if (file.isFile()) loadChartSupport(cpuChartSupport, file);\n                }\n            });\n    }\n\n    public void registerHeapChartSupport(final SimpleXYChartSupport heapChartSupport) {\n        this.heapChartSupport = heapChartSupport;\n        if (heapChartSupport != null && source instanceof Snapshot)\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    File file = new File(source.getStorage().getDirectory(), HEAP_CHART_STORAGE);\n                    if (file.isFile()) loadChartSupport(heapChartSupport, file);\n                }\n            });\n    }\n\n    public void registerPermGenChartSupport(final SimpleXYChartSupport permgenChartSupport) {\n        this.permGenChartSupport = permgenChartSupport;\n        if (permGenChartSupport != null && source instanceof Snapshot)\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    File file = new File(source.getStorage().getDirectory(), PERMGEN_CHART_STORAGE);\n                    if (file.isFile()) loadChartSupport(permGenChartSupport, file);\n                }\n            });\n    }\n\n    public void registerClassesChartSupport(final SimpleXYChartSupport classesChartSupport) {\n        this.classesChartSupport = classesChartSupport;\n        if (classesChartSupport != null && source instanceof Snapshot)\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    File file = new File(source.getStorage().getDirectory(), CLASSES_CHART_STORAGE);\n                    if (file.isFile()) loadChartSupport(classesChartSupport, file);\n                }\n            });\n    }\n\n    public void registerThreadsChartSupport(final SimpleXYChartSupport threadsChartSupport) {\n        this.threadsChartSupport = threadsChartSupport;\n        if (threadsChartSupport != null && source instanceof Snapshot)\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    File file = new File(source.getStorage().getDirectory(), THREADS_CHART_STORAGE);\n                    if (file.isFile()) loadChartSupport(threadsChartSupport, file);\n                }\n            });\n    }\n\n    public void registerVirtualThreadsChartSupport(final SimpleXYChartSupport virtualThreadsChartSupport) {\n        this.virtualThreadsChartSupport = virtualThreadsChartSupport;\n        if (virtualThreadsChartSupport != null && source instanceof Snapshot)\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    File file = new File(source.getStorage().getDirectory(), VIRTUAL_THREADS_CHART_STORAGE);\n                    if (file.isFile()) loadChartSupport(virtualThreadsChartSupport, file);\n                }\n            });\n    }\n\n    public synchronized void cleanup() {\n        listeners.clear();\n        if (!initialized) return;\n        if (jvm != null && monitoredDataListener != null)\n            jvm.removeMonitoredDataListener(monitoredDataListener);\n    }\n\n    public void addChangeListener(ChangeListener listener) {\n        if (live) listeners.add(listener);\n    }\n\n    public void removeChangeListener(ChangeListener listener) {\n        if (live) listeners.remove(listener);\n    }\n\n    \n    public void save(Snapshot snapshot) {\n        \n        initialize();\n        \n        Storage storage = snapshot.getStorage();\n        \n        setProperty(storage, SNAPSHOT_VERSION, CURRENT_SNAPSHOT_VERSION);\n\n        setProperty(storage, PROP_CHART_CACHE, Integer.toString(chartCache));\n        setProperty(storage, PROP_UPTIME, Long.toString(uptime));\n        setProperty(storage, PROP_PREV_UPTIME, Long.toString(prevUpTime));\n        setProperty(storage, PROP_CPU_MONITORING_SUPPORTED, Boolean.toString(cpuMonitoringSupported));\n        setProperty(storage, PROP_GC_MONITORING_SUPPORTED, Boolean.toString(gcMonitoringSupported));\n        setProperty(storage, PROP_MEMORY_MONITORING_SUPPORTED, Boolean.toString(memoryMonitoringSupported));\n        setProperty(storage, PROP_CLASS_MONITORING_SUPPORTED, Boolean.toString(classMonitoringSupported));\n        setProperty(storage, PROP_THREADS_MONITORING_SUPPORTED, Boolean.toString(threadsMonitoringSupported));\n        setProperty(storage, PROP_VIRTUAL_THREADS_MONITORING_SUPPORTED, Boolean.toString(virtualThreadsMonitoringSupported));\n        setProperty(storage, PROP_NUMBER_OF_PROCESSORS, Integer.toString(processorsCount));\n\n        setProperty(storage, PROP_PROCESS_CPU_TIME, Long.toString(processCpuTime));\n        setProperty(storage, PROP_PROCESS_GC_TIME, Long.toString(processGcTime));\n        setProperty(storage, PROP_PREV_PROCESS_CPU_TIME, Long.toString(prevProcessCpuTime));\n        setProperty(storage, PROP_PREV_PROCESS_GC_TIME, Long.toString(prevProcessGcTime));\n        setProperty(storage, PROP_HEAP_NAME, heapName);\n        setProperty(storage, PROP_HEAP_CAPACITY, Long.toString(heapCapacity));\n        setProperty(storage, PROP_HEAP_USED, Long.toString(heapUsed));\n        setProperty(storage, PROP_MAX_HEAP, Long.toString(maxHeap));\n        setProperty(storage, PROP_PERMGEN_NAME, permgenName);\n        setProperty(storage, PROP_PERMGEN_CAPACITY, Long.toString(permgenCapacity));\n        setProperty(storage, PROP_PERMGEN_USED, Long.toString(permgenUsed));\n        setProperty(storage, PROP_PERMGEN_MAX, Long.toString(permgenMax));\n        setProperty(storage, PROP_SHARED_UNLOADED, Long.toString(sharedUnloaded));\n        setProperty(storage, PROP_TOTAL_UNLOADED, Long.toString(totalUnloaded));\n        setProperty(storage, PROP_SHARED_LOADED, Long.toString(sharedLoaded));\n        setProperty(storage, PROP_TOTAL_LOADED, Long.toString(totalLoaded));\n        setProperty(storage, PROP_TOTAL_THREADS, Long.toString(totalThreads));\n        setProperty(storage, PROP_DAEMON_THREADS, Long.toString(daemonThreads));\n        setProperty(storage, PROP_PEAK_THREADS, Long.toString(peakThreads));\n        setProperty(storage, PROP_STARTED_THREADS, Long.toString(startedThreads));\n        setProperty(storage, PROP_PARALLELISM, Integer.toString(parallelism));\n        setProperty(storage, PROP_POOL_SIZE, Integer.toString(poolSize));\n        setProperty(storage, PROP_MOUNTED_VIRTUAL_THREADS_COUNT, Integer.toString(mountedVirtualThreadCount));\n        setProperty(storage, PROP_QUEUED_VIRTUAL_THREAD_COUNT, Long.toString(queuedVirtualThreadCount));\n\n        File dir = storage.getDirectory();\n\n        if (cpuMonitoringSupported || gcMonitoringSupported)\n            saveChartSupport(cpuChartSupport, new File(dir, CPU_CHART_STORAGE));\n        if (memoryMonitoringSupported)\n            saveChartSupport(heapChartSupport, new File(dir, HEAP_CHART_STORAGE));\n        if (memoryMonitoringSupported)\n            saveChartSupport(permGenChartSupport, new File(dir, PERMGEN_CHART_STORAGE));\n        if (classMonitoringSupported)\n            saveChartSupport(classesChartSupport, new File(dir, CLASSES_CHART_STORAGE));\n        if (threadsMonitoringSupported)\n            saveChartSupport(threadsChartSupport, new File(dir, THREADS_CHART_STORAGE));\n        if (virtualThreadsMonitoringSupported)\n            saveChartSupport(virtualThreadsChartSupport, new File(dir, VIRTUAL_THREADS_CHART_STORAGE));\n        \n    }\n\n    private static void saveChartSupport(SimpleXYChartSupport chartSupport, File file) {\n        if (chartSupport == null) return;\n        \n        try (OutputStream os = new FileOutputStream(file)){\n            chartSupport.saveValues(os);\n        } catch (Exception e) {\n            // TODO: log it\n        }\n    }\n\n    private static void loadChartSupport(SimpleXYChartSupport chartSupport, File file) {\n        try (InputStream is = new FileInputStream(file)) {\n            chartSupport.loadValues(is);\n        } catch (Exception e) {\n            // TODO: log it\n        }\n    }\n\n    private void initialize(Snapshot snapshot) {\n        // TODO: if some property cannot be loaded for current snapshot version, FAIL initializing the snapshot!\n        Storage storage = snapshot.getStorage();\n\n        String version = getProperty(storage, SNAPSHOT_VERSION);\n        chartCache = Integer.parseInt(getProperty(storage, PROP_CHART_CACHE));\n        uptime = Long.parseLong(getProperty(storage, PROP_UPTIME));\n        prevUpTime = Long.parseLong(getProperty(storage, PROP_PREV_UPTIME));\n        takeHeapDumpSupported = false;\n        cpuMonitoringSupported = Boolean.parseBoolean(getProperty(storage, PROP_CPU_MONITORING_SUPPORTED));\n        gcMonitoringSupported = Boolean.parseBoolean(getProperty(storage, PROP_GC_MONITORING_SUPPORTED));\n        memoryMonitoringSupported = Boolean.parseBoolean(getProperty(storage, PROP_MEMORY_MONITORING_SUPPORTED));\n        classMonitoringSupported = Boolean.parseBoolean(getProperty(storage, PROP_CLASS_MONITORING_SUPPORTED));\n        threadsMonitoringSupported = Boolean.parseBoolean(getProperty(storage, PROP_THREADS_MONITORING_SUPPORTED));\n        virtualThreadsMonitoringSupported = Boolean.parseBoolean(getProperty(storage, PROP_VIRTUAL_THREADS_MONITORING_SUPPORTED));\n        processorsCount = Integer.parseInt(getProperty(storage, PROP_NUMBER_OF_PROCESSORS));\n\n        processCpuTime = Long.parseLong(getProperty(storage, PROP_PROCESS_CPU_TIME));\n        processGcTime = Long.parseLong(getProperty(storage, PROP_PROCESS_GC_TIME));\n        prevProcessCpuTime = Long.parseLong(getProperty(storage, PROP_PREV_PROCESS_CPU_TIME));\n        prevProcessGcTime = Long.parseLong(getProperty(storage, PROP_PREV_PROCESS_GC_TIME));\n        heapCapacity = Long.parseLong(getProperty(storage, PROP_HEAP_CAPACITY));\n        heapUsed = Long.parseLong(getProperty(storage, PROP_HEAP_USED));\n        maxHeap = Long.parseLong(getProperty(storage, PROP_MAX_HEAP));\n        permgenCapacity = Long.parseLong(getProperty(storage, PROP_PERMGEN_CAPACITY));\n        permgenUsed = Long.parseLong(getProperty(storage, PROP_PERMGEN_USED));\n        permgenMax = Long.parseLong(getProperty(storage, PROP_PERMGEN_MAX));\n        sharedUnloaded = Long.parseLong(getProperty(storage, PROP_SHARED_UNLOADED));\n        totalUnloaded = Long.parseLong(getProperty(storage, PROP_TOTAL_UNLOADED));\n        sharedLoaded = Long.parseLong(getProperty(storage, PROP_SHARED_LOADED));\n        totalLoaded = Long.parseLong(getProperty(storage, PROP_TOTAL_LOADED));\n        totalThreads = Long.parseLong(getProperty(storage, PROP_TOTAL_THREADS));\n        daemonThreads = Long.parseLong(getProperty(storage, PROP_DAEMON_THREADS));\n        peakThreads = Long.parseLong(getProperty(storage, PROP_PEAK_THREADS));\n        startedThreads = Long.parseLong(getProperty(storage, PROP_STARTED_THREADS));\n        parallelism = Integer.parseInt(getProperty(storage, PROP_PARALLELISM));\n        poolSize = Integer.parseInt(getProperty(storage, PROP_POOL_SIZE));\n        mountedVirtualThreadCount = Integer.parseInt(getProperty(storage, PROP_MOUNTED_VIRTUAL_THREADS_COUNT));\n        queuedVirtualThreadCount = Long.parseLong(getProperty(storage, PROP_QUEUED_VIRTUAL_THREAD_COUNT));\n        \n        if (version.compareTo(\"1.1\") >= 0) {                      // NOI18N\n            heapName = getProperty(storage, PROP_HEAP_NAME);\n            permgenName = getProperty(storage, PROP_PERMGEN_NAME);\n        } else {\n            heapName = NbBundle.getMessage(ApplicationMonitorModel.class, \"LBL_Heap\");  // NOI18N\n            permgenName = NbBundle.getMessage(ApplicationMonitorModel.class, \"LBL_PermGen\");    // NOI18N\n        }\n    }\n    \n    private static void setProperty(Storage storage, String property, String value) {\n        storage.setCustomProperty(property, value == null ? PROP_NOT_DEFINED : value);\n    }\n    \n    private static String getProperty(Storage storage, String property) {\n        String value = storage.getCustomProperty(property);\n        return PROP_NOT_DEFINED.equals(value) ? null : value;\n    }\n    \n    private void initialize(Application application) {\n        GlobalPreferences preferences = GlobalPreferences.sharedInstance();\n        chartCache = preferences.getMonitoredDataCache() * 60 /\n                     preferences.getMonitoredDataPoll();\n\n        processorsCount = 1;\n        \n        jvm = JvmFactory.getJVMFor(application);\n        HeapDumpSupport hds = HeapDumpSupport.getInstance();\n        if (application.isLocalApplication()) {\n            takeHeapDumpSupported = hds.supportsHeapDump(application);\n        } else {\n            takeHeapDumpSupported = hds.supportsRemoteHeapDump(application);\n        }\n        cpuMonitoringSupported = jvm.isCpuMonitoringSupported();\n        gcMonitoringSupported = jvm.isCollectionTimeSupported();\n        memoryMonitoringSupported = jvm.isMemoryMonitoringSupported();\n        classMonitoringSupported = jvm.isClassMonitoringSupported();\n        threadsMonitoringSupported = jvm.isThreadMonitoringSupported();\n        if (memoryMonitoringSupported) {\n            String[] names = jvm.getGenName();\n            heapName = names[0];\n            permgenName = names[1];\n        }\n        processorsCount = jvm.getAvailableProcessors();\n\n        memoryMXBean = null;\n        JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);\n        if (jmxModel != null && jmxModel.getConnectionState() == ConnectionState.CONNECTED) {\n            JvmMXBeans mxbeans = jmxModel.getJvmMXBeans();\n            if (mxbeans != null) {\n                memoryMXBean = mxbeans.getMemoryMXBean();\n            }\n            virtualThreadsName = getVirtualThreadsName();\n            try {\n                virtualThreadsMonitoringSupported = jmxModel.getMBeanServerConnection().isRegistered(virtualThreadsName);\n                if (virtualThreadsMonitoringSupported) connection = jmxModel.getMBeanServerConnection();\n            } catch (IOException ex) {\n                \n            }\n        }\n\n        if (jvm != null) {\n            updateValues(System.currentTimeMillis(), jvm.getMonitoredData());\n\n            if (live) {\n                monitoredDataListener = new MonitoredDataListener() {\n                    long lastTimestamp = -1;\n                    public void monitoredDataEvent(final MonitoredData data) {\n                        long timestamp = System.currentTimeMillis();\n                        final long timestampF = lastTimestamp < timestamp ?\n                            lastTimestamp = timestamp : ++lastTimestamp;\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                updateValues(timestampF, data);\n                                fireChange();\n                            }\n                        });\n                    }\n                };\n                jvm.addMonitoredDataListener(monitoredDataListener);\n            }\n        }\n\n    }\n\n    private void updateValues(final long time, final MonitoredData data) {\n        timestamp = time;\n        if (data != null) {\n            prevUpTime = uptime;\n            uptime = data.getUpTime();\n            \n            if (cpuMonitoringSupported) {\n                prevProcessCpuTime = processCpuTime;\n                processCpuTime = data.getProcessCpuTime();\n            }\n\n            if (gcMonitoringSupported) {\n                prevProcessGcTime = processGcTime;\n                processGcTime = data.getCollectionTime();\n            }\n\n            if (memoryMonitoringSupported) {\n                heapCapacity = data.getGenCapacity()[0];\n                heapUsed = data.getGenUsed()[0];\n                maxHeap = data.getGenMaxCapacity()[0];\n                permgenCapacity = data.getGenCapacity()[1];\n                permgenUsed = data.getGenUsed()[1];\n                permgenMax = data.getGenMaxCapacity()[1];\n            }\n\n            if (classMonitoringSupported) {\n                sharedUnloaded = data.getSharedUnloadedClasses();\n                totalUnloaded  = data.getUnloadedClasses();\n                sharedLoaded  = data.getSharedLoadedClasses();\n                totalLoaded   = data.getLoadedClasses();\n            }\n\n            if (threadsMonitoringSupported) {\n                totalThreads   = data.getThreadsLive();\n                daemonThreads  = data.getThreadsDaemon();\n                peakThreads    = data.getThreadsLivePeak();\n                startedThreads = data.getThreadsStarted();\n            }\n            if (virtualThreadsMonitoringSupported) {\n                Object[] attributes = getVirtualThreadAttributes(\"Parallelism\", \"PoolSize\", \"MountedVirtualThreadCount\", \"QueuedVirtualThreadCount\");\n                if (attributes != null) {\n                    parallelism = (Integer)attributes[0];\n                    poolSize = (Integer)attributes[1];\n                    mountedVirtualThreadCount = (Integer)attributes[2];\n                    queuedVirtualThreadCount = (Long)attributes[3];\n                } else {\n                    virtualThreadsMonitoringSupported = false;\n                }\n            }\n        }\n    }\n\n    private void fireChange() {\n        final List<ChangeListener> list = new ArrayList<>();\n        synchronized (listeners) { list.addAll(listeners); }\n        for (ChangeListener l : list) l.stateChanged(new ChangeEvent(this));\n    }\n\n    \n    private ApplicationMonitorModel(DataSource source, boolean live) {\n        initialized = false;\n        \n        this.source = source;\n        this.live = live;\n\n        listeners = Collections.synchronizedList(new ArrayList<>());\n    }\n\n    private Object[] getVirtualThreadAttributes(String... names) {\n        try {\n            List<Attribute> attrs = connection.getAttributes(virtualThreadsName, names).asList();\n            Object[] values = new Object[attrs.size()];\n\n            for (int i = 0; i < values.length; i++) {\n                values[i] = attrs.get(i).getValue();\n            }\n            return values;\n        } catch (Exception ex) {\n            LOGGER.log(Level.INFO, \"getAttributes\", ex);   // NOI18N\n        }\n        return null;\n    }\n\n    private static ObjectName getVirtualThreadsName() {\n        try {\n            return new ObjectName(\"jdk.management:type=VirtualThreadScheduler\");    // NOI18N\n        } catch (MalformedObjectNameException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/monitor/ApplicationMonitorView.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.monitor;\n\nimport java.awt.BorderLayout;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.AbstractAction;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.charts.ChartFactory;\nimport org.graalvm.visualvm.charts.SimpleXYChartDescriptor;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.NotSupportedDisplayer;\nimport org.graalvm.visualvm.heapdump.HeapDumpSupport;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.WeakListeners;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ApplicationMonitorView extends DataSourceView {\n    \n    private static final Logger LOGGER = Logger.getLogger(ApplicationMonitorView.class.getName());\n\n    private static final String UNKNOWN = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Unknown\"); // NOI18N\n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/application/views/resources/monitor.png\";  // NOI18N\n\n    private final ApplicationMonitorModel model;\n    \n\n    ApplicationMonitorView(ApplicationMonitorModel model) {\n        super(model.getSource(), NbBundle.getMessage(ApplicationMonitorView.class,\n                                 \"LBL_Monitor\"), new ImageIcon(ImageUtilities.   // NOI18N\n                                 loadImage(IMAGE_PATH, true)).getImage(), 20, false);\n        this.model = model;\n    }\n    \n    protected void willBeAdded() {\n        model.initialize();\n    }\n    \n    protected void removed() {\n        model.cleanup();\n    }\n\n    ApplicationMonitorModel getModel() {\n        return model;\n    }\n    \n    protected DataViewComponent createComponent() {\n        final MasterViewSupport masterViewSupport = new MasterViewSupport(model);\n        DataViewComponent dvc = new DataViewComponent(\n                masterViewSupport.getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(false));\n        \n        final CpuViewSupport cpuViewSupport = new CpuViewSupport(model);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.\n                getMessage(ApplicationMonitorView.class, \"LBL_Cpu\"), true), DataViewComponent.TOP_LEFT);  // NOI18N\n        dvc.addDetailsView(cpuViewSupport.getDetailsView(), DataViewComponent.TOP_LEFT);\n\n        final HeapViewSupport heapViewSupport = new HeapViewSupport(model);\n        final PermGenViewSupport permGenViewSupport = model.isMemoryMonitoringSupported() ? new PermGenViewSupport(model) : null;\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.\n                getMessage(ApplicationMonitorView.class, \"LBL_Memory\"), true), DataViewComponent.TOP_RIGHT);  // NOI18N\n        dvc.addDetailsView(heapViewSupport.getDetailsView(), DataViewComponent.TOP_RIGHT);\n        if (permGenViewSupport != null) dvc.addDetailsView(permGenViewSupport.getDetailsView(), DataViewComponent.TOP_RIGHT);\n\n        final ClassesViewSupport classesViewSupport = new ClassesViewSupport(model);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.\n                getMessage(ApplicationMonitorView.class, \"LBL_Classes\"), true), DataViewComponent.BOTTOM_LEFT);    // NOI18N\n        dvc.addDetailsView(classesViewSupport.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n\n        final ThreadsViewSupport threadsViewSupport = new ThreadsViewSupport(model);\n        final VirtualThreadsViewSupport vThreadsViewSupport = model.isVirtualThreadsMonitoringSupported() ? new VirtualThreadsViewSupport(model) : null;\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.\n                getMessage(ApplicationMonitorView.class, \"LBL_Threads\"), true), DataViewComponent.BOTTOM_RIGHT);   // NOI18N\n        dvc.addDetailsView(threadsViewSupport.getDetailsView(), DataViewComponent.BOTTOM_RIGHT);\n        if (vThreadsViewSupport != null) dvc.addDetailsView(vThreadsViewSupport.getDetailsView(), DataViewComponent.BOTTOM_RIGHT);\n\n        final Runnable refresher = new Runnable() {\n            public void run() {\n                masterViewSupport.refresh(model);\n                cpuViewSupport.refresh(model);\n                heapViewSupport.refresh(model);\n                if (permGenViewSupport != null) permGenViewSupport.refresh(model);\n                classesViewSupport.refresh(model);\n                threadsViewSupport.refresh(model);\n                if (vThreadsViewSupport != null) vThreadsViewSupport.refresh(model);\n            }\n        };\n\n        refresher.run();\n\n        model.addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                refresher.run();\n            }\n        });\n        \n        return dvc;\n    }\n    \n    \n    // --- General data --------------------------------------------------------\n    \n    private static class MasterViewSupport extends JPanel implements DataRemovedListener<DataSource>, PropertyChangeListener {\n\n        private HTMLTextArea area;\n        private JButton gcButton;\n        private JButton heapDumpButton;\n        \n        MasterViewSupport(ApplicationMonitorModel model) {\n            initComponents(model);\n        }\n        \n        \n        public DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Monitor\"), null, this);  // NOI18N\n        }\n        \n        public void refresh(ApplicationMonitorModel model) {\n            int selStart = area.getSelectionStart();\n            int selEnd   = area.getSelectionEnd();\n            area.setText(getBasicTelemetry(model));\n            area.select(selStart, selEnd);\n        }\n        \n        public void dataRemoved(DataSource dataSource) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    gcButton.setEnabled(false);\n                    heapDumpButton.setEnabled(false);\n                }\n            });\n        }\n\n        public void propertyChange(PropertyChangeEvent evt) {\n            dataRemoved(null);\n        }\n        \n        private void initComponents(final ApplicationMonitorModel model) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea(getBasicTelemetry(model));\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n                        \n            add(area, BorderLayout.CENTER);\n\n            gcButton = new JButton(new AbstractAction(NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Perform_GC\")) {    // NOI18N\n                public void actionPerformed(ActionEvent e) {\n                    new RequestProcessor(\"GC Processor\").post(new Runnable() { // NOI18N\n                        public void run() {\n                            try {\n                                model.getMemoryMXBean().gc(); \n                            } catch (SecurityException ex) {\n                                String err = NbBundle.getMessage(ApplicationMonitorView.class, \"TXT_Perform_GC_failed\", ex.getLocalizedMessage());  // NOI18N\n                                NotifyDescriptor nd = new NotifyDescriptor.Message(err, NotifyDescriptor.INFORMATION_MESSAGE);\n                                DialogDisplayer.getDefault().notify(nd);\n                                gcButton.setEnabled(false);\n                            } catch (Exception e) {\n                                LOGGER.log(Level.WARNING, \"initComponents\", e);   // NOI18N\n                                gcButton.setEnabled(false);\n                            }\n                        }\n                    });\n                }\n            });\n            gcButton.setEnabled(model.getMemoryMXBean() != null);\n            \n            heapDumpButton = new JButton(new AbstractAction(NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Heap_Dump\")) {   // NOI18N\n                public void actionPerformed(ActionEvent e) {\n                    Application application = (Application)model.getSource();\n                    boolean local = application.isLocalApplication();\n                    boolean tagged = (e.getModifiers() & Toolkit.getDefaultToolkit().\n                                      getMenuShortcutKeyMask()) != 0;\n                    HeapDumpSupport hds = HeapDumpSupport.getInstance();\n                    if (local) hds.takeHeapDump(application, !tagged);\n                    else hds.takeRemoteHeapDump(application, null, !tagged);\n                }\n            });\n            heapDumpButton.setEnabled(model.isTakeHeapDumpSupported());\n            \n            JPanel buttonsArea = new JPanel(new BorderLayout());\n            buttonsArea.setOpaque(false);\n            JPanel buttonsContainer = new JPanel(new BorderLayout(3, 0));\n            buttonsContainer.setBackground(area.getBackground());\n            buttonsContainer.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n            buttonsContainer.add(gcButton, BorderLayout.WEST);\n            buttonsContainer.add(heapDumpButton, BorderLayout.EAST);\n            buttonsArea.add(buttonsContainer, BorderLayout.NORTH);\n            \n            add(buttonsArea, BorderLayout.AFTER_LINE_ENDS);\n\n            if (model.getSource() instanceof Application) {\n                Application application = (Application)model.getSource();\n                application.notifyWhenRemoved(this);\n                application.addPropertyChangeListener(Stateful.PROPERTY_STATE, WeakListeners.propertyChange(this,application));\n            }\n        }\n\n        private String getBasicTelemetry(ApplicationMonitorModel model) {\n            String uptime = model.getUpTime() == -1 ? UNKNOWN : getTime(model.getUpTime());\n            return NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Uptime\", uptime); // NOI18N\n        }\n        \n        public static String getTime(long millis) {\n            // Hours\n            long hours = millis / 3600000;\n            String sHours = (hours == 0 ? \"\" : \"\" + hours); // NOI18N\n            millis = millis % 3600000;\n            \n            // Minutes\n            long minutes = millis / 60000;\n            String sMinutes = (((hours > 0) && (minutes < 10)) ? \"0\" + minutes : \"\" + minutes); // NOI18N\n            millis = millis % 60000;\n            \n            // Seconds\n            long seconds = millis / 1000;\n            String sSeconds = ((seconds < 10) ? \"0\" + seconds : \"\" + seconds); // NOI18N\n            \n            if (sHours.isEmpty()) {\n                 return NbBundle.getMessage(ApplicationMonitorView.class, \"FORMAT_ms\", // NOI18N\n                                            new Object[] { sMinutes, sSeconds });\n            } else {\n                return NbBundle.getMessage(ApplicationMonitorView.class, \"FORMAT_hms\", // NOI18N\n                                            new Object[] { sHours, sMinutes, sSeconds });\n            }\n        }\n        \n    }\n\n    \n    // --- CPU -----------------------------------------------------------------\n    \n    private static class CpuViewSupport extends JPanel  {\n\n        private static final String CPU = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Cpu\"); // NOI18N\n        private static final String CPU_USAGE = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Cpu_Usage\"); // NOI18N\n        private static final String GC_USAGE = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Gc_Usage\"); // NOI18N\n\n        private boolean liveModel;\n        private int processorsCount;\n        private boolean cpuMonitoringSupported;\n        private boolean gcMonitoringSupported;\n\n        private SimpleXYChartSupport chartSupport;\n\n\n        CpuViewSupport(ApplicationMonitorModel model) {\n            initModels(model);\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(CPU, null, 10, this, null);\n        }\n\n        public void refresh(ApplicationMonitorModel model) {\n            if (cpuMonitoringSupported || gcMonitoringSupported) {\n\n                long upTime = model.getUpTime() * 1000000;\n                long prevUpTime = model.getPrevUpTime() * 1000000;\n\n                boolean tracksProcessCpuTime = cpuMonitoringSupported &&\n                                               model.getPrevProcessCpuTime() != -1;\n                long processCpuTime = tracksProcessCpuTime ?\n                    model.getProcessCpuTime() / processorsCount : -1;\n                long prevProcessCpuTime = tracksProcessCpuTime ?\n                    model.getPrevProcessCpuTime() / processorsCount : -1;\n\n                boolean tracksProcessGcTime  = gcMonitoringSupported &&\n                                               model.getPrevProcessGcTime() != -1;\n                long processGcTime  = tracksProcessGcTime  ?\n                    model.getProcessGcTime() * 1000000 / processorsCount : -1;\n                long prevProcessGcTime  = tracksProcessGcTime  ?\n                    model.getPrevProcessGcTime() * 1000000 / processorsCount : -1;\n\n                if (prevUpTime != -1 && (tracksProcessCpuTime || tracksProcessGcTime)) {\n\n                    long upTimeDiff = upTime - prevUpTime;\n                    long cpuUsage = -1;\n                    long gcUsage = -1;\n                    String cpuDetail = UNKNOWN;\n                    String gcDetail = UNKNOWN;\n\n                    if (tracksProcessCpuTime) {\n                        long processTimeDiff = processCpuTime - prevProcessCpuTime;\n                        cpuUsage = upTimeDiff > 0 ? Math.min((long)(1000 * (float)processTimeDiff /\n                                                             (float)upTimeDiff), 1000) : 0;\n                        cpuDetail = cpuUsage == -1 ? UNKNOWN : chartSupport.formatPercent(cpuUsage);\n                    }\n\n                    if (tracksProcessGcTime) {\n                        long processGcTimeDiff = processGcTime - prevProcessGcTime;\n                        gcUsage = upTimeDiff > 0 ? Math.min((long)(1000 * (float)processGcTimeDiff /\n                                                            (float)upTimeDiff), 1000) : 0;\n                        if (cpuUsage != -1 && cpuUsage < gcUsage) gcUsage = cpuUsage;\n                        gcDetail = gcUsage == -1 ? UNKNOWN : chartSupport.formatPercent(gcUsage);\n                    }\n                    \n                    if (liveModel)\n                        chartSupport.addValues(model.getTimestamp(), new long[] { Math.max(cpuUsage, 0), Math.max(gcUsage, 0) });\n                    chartSupport.updateDetails(new String[] { cpuDetail, gcDetail });\n\n                }\n            }\n        }\n\n        private void initModels(ApplicationMonitorModel model) {\n            liveModel = model.isLive();\n            processorsCount = model.getProcessorsCount();\n            cpuMonitoringSupported = model.isCpuMonitoringSupported();\n            gcMonitoringSupported = model.isGcMonitoringSupported();\n\n            if (cpuMonitoringSupported || gcMonitoringSupported) {\n                SimpleXYChartDescriptor chartDescriptor =\n                        SimpleXYChartDescriptor.percent(false, 0.1d, model.getChartCache());\n\n                chartDescriptor.addLineItems(CPU_USAGE, GC_USAGE);\n                chartDescriptor.setDetailsItems(new String[] { CPU_USAGE, GC_USAGE });\n\n                chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n                model.registerCpuChartSupport(chartSupport);\n\n                chartSupport.setZoomingEnabled(!liveModel);\n            }\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (cpuMonitoringSupported || gcMonitoringSupported) {\n                add(chartSupport.getChart(), BorderLayout.CENTER);\n                chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN });\n            } else {\n                add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM),\n                    BorderLayout.CENTER);\n            }\n        }\n\n    }\n\n\n    // --- Heap ----------------------------------------------------------------\n\n    private static class HeapViewSupport extends JPanel  {\n        private boolean liveModel;\n        private boolean memoryMonitoringSupported;\n        private String heapName;\n\n        private SimpleXYChartSupport chartSupport;\n\n        HeapViewSupport(ApplicationMonitorModel model) {\n            initModels(model);\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(heapName, null, 10, this, null);\n        }\n\n        public void refresh(ApplicationMonitorModel model) {\n            if (memoryMonitoringSupported) {\n                long heapCapacity = model.getHeapCapacity();\n                long heapUsed = model.getHeapUsed();\n                long maxHeap = model.getMaxHeap();\n\n                if (liveModel)\n                        chartSupport.addValues(model.getTimestamp(), new long[] { heapCapacity, heapUsed });\n                chartSupport.updateDetails(new String[] { chartSupport.formatBytes(heapCapacity),\n                                                          chartSupport.formatBytes(heapUsed),\n                                                          chartSupport.formatBytes(maxHeap) });\n            }\n        }\n\n        private void initModels(ApplicationMonitorModel model) {\n            liveModel = model.isLive();\n            memoryMonitoringSupported = model.isMemoryMonitoringSupported();\n            heapName = memoryMonitoringSupported ? model.getHeapName() : NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Memory\"); // NOI18N\n\n            if (memoryMonitoringSupported) {\n                String HEAP_SIZE = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Heap_size\"); // NOI18N\n                String HEAP_SIZE_LEG = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Heap_size_leg\",heapName); // NOI18N\n                String USED_HEAP = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Used_heap\"); // NOI18N\n                String USED_HEAP_LEG = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Used_heap_leg\",heapName.toLowerCase()); // NOI18N\n                String MAX_HEAP = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Max_Heap\");   // NOI18N\n\n                SimpleXYChartDescriptor chartDescriptor =\n                        SimpleXYChartDescriptor.bytes(10 * 1024 * 1024, false, model.getChartCache());\n\n                chartDescriptor.addLineFillItems(HEAP_SIZE_LEG, USED_HEAP_LEG);\n                chartDescriptor.setDetailsItems(new String[] { HEAP_SIZE, USED_HEAP, MAX_HEAP });\n                chartDescriptor.setLimitYValue(model.getMaxHeap());\n\n                chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n                model.registerHeapChartSupport(chartSupport);\n\n                chartSupport.setZoomingEnabled(!liveModel);\n            }\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (memoryMonitoringSupported) {\n                add(chartSupport.getChart(), BorderLayout.CENTER);\n                chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN, UNKNOWN });\n            } else {\n                add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM),\n                    BorderLayout.CENTER);\n            }\n        }\n\n    }\n\n\n    // --- PermGen -------------------------------------------------------------\n\n    private static class PermGenViewSupport extends JPanel  {\n\n        private boolean liveModel;\n        private boolean memoryMonitoringSupported;\n        private String permgenName;\n\n        private SimpleXYChartSupport chartSupport;\n\n        PermGenViewSupport(ApplicationMonitorModel model) {\n            initModels(model);\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(permgenName, null, 10, this, null);\n        }\n\n        public void refresh(ApplicationMonitorModel model) {\n            if (memoryMonitoringSupported) {\n                long permgenCapacity = model.getPermgenCapacity();\n                long permgenUsed = model.getPermgenUsed();\n                long permgenMax = model.getPermgenMax();\n\n                if (liveModel)\n                        chartSupport.addValues(model.getTimestamp(), new long[] { permgenCapacity, permgenUsed });\n                chartSupport.updateDetails(new String[] { chartSupport.formatBytes(permgenCapacity),\n                                                          chartSupport.formatBytes(permgenUsed),\n                                                          chartSupport.formatBytes(permgenMax) });\n            }\n        }\n\n        private void initModels(ApplicationMonitorModel model) {\n            liveModel = model.isLive();\n            memoryMonitoringSupported = model.isMemoryMonitoringSupported();\n            permgenName = model.getPermgenName();\n\n            if (memoryMonitoringSupported) {\n                String PERM_SIZE = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_PermGen_size\");  // NOI18N\n                String PERM_SIZE_LEG = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_PermGen_size_leg\", permgenName);  // NOI18N\n                String USED_PERM = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Used_PermGen\");  // NOI18N\n                String USED_PERM_LEG = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Used_PermGen_leg\", permgenName);  // NOI18N\n                String MAX_PERM = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Max_PermGen_size\");   // NOI18N\n                long permgenMax = model.getPermgenMax();\n\n                SimpleXYChartDescriptor chartDescriptor =\n                        SimpleXYChartDescriptor.bytes(10 * 1024 * 1024, false, model.getChartCache());\n\n                chartDescriptor.addLineFillItems(PERM_SIZE_LEG, USED_PERM_LEG);\n                chartDescriptor.setDetailsItems(new String[] { PERM_SIZE, USED_PERM, MAX_PERM });\n                if (permgenMax != -1) {\n                    chartDescriptor.setLimitYValue(permgenMax);\n                }\n\n                chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n                model.registerPermGenChartSupport(chartSupport);\n\n                chartSupport.setZoomingEnabled(!liveModel);\n            }\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (memoryMonitoringSupported) {\n                add(chartSupport.getChart(), BorderLayout.CENTER);\n                chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN, UNKNOWN });\n            } else {\n                add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM),\n                    BorderLayout.CENTER);\n            }\n        }\n\n    }\n\n\n    // --- Classes -------------------------------------------------------------\n\n    private static class ClassesViewSupport extends JPanel  {\n\n        private static final String TOTAL_LOADED = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Total_loaded_classes\");   // NOI18N\n        private static final String TOTAL_LOADED_LEG = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Total_loaded_classes_leg\");   // NOI18N\n        private static final String SHARED_LOADED = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Shared_loaded_classes\"); // NOI18N\n        private static final String SHARED_LOADED_LEG = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Shared_loaded_classes_leg\"); // NOI18N\n        private static final String TOTAL_UNLOADED = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Total_unloaded_classes\");   // NOI18N\n        private static final String SHARED_UNLOADED = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Shared_unloaded_classes\"); // NOI18N\n\n        private boolean liveModel;\n        private boolean classMonitoringSupported;\n\n        private SimpleXYChartSupport chartSupport;\n\n        ClassesViewSupport(ApplicationMonitorModel model) {\n            initModels(model);\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Classes\"), null, 10, this, null);   // NOI18N\n        }\n\n        public void refresh(ApplicationMonitorModel model) {\n            if (classMonitoringSupported) {\n                long sharedUnloaded = model.getSharedUnloaded();\n                long totalUnloaded  = model.getTotalUnloaded();\n                long sharedClasses  = model.getSharedLoaded() - sharedUnloaded;\n                long totalClasses   = model.getTotalLoaded() - totalUnloaded + sharedClasses;\n\n                if (liveModel)\n                        chartSupport.addValues(model.getTimestamp(), new long[] { totalClasses, sharedClasses });\n                chartSupport.updateDetails(new String[] { chartSupport.formatDecimal(totalClasses),\n                                                          chartSupport.formatDecimal(sharedClasses),\n                                                          chartSupport.formatDecimal(totalUnloaded),\n                                                          chartSupport.formatDecimal(sharedUnloaded) });\n            }\n        }\n\n        private void initModels(ApplicationMonitorModel model) {\n            liveModel = model.isLive();\n            classMonitoringSupported = model.isClassMonitoringSupported();\n\n            if (classMonitoringSupported) {\n                SimpleXYChartDescriptor chartDescriptor =\n                        SimpleXYChartDescriptor.decimal(100, false, model.getChartCache());\n\n                chartDescriptor.addLineItems(TOTAL_LOADED_LEG, SHARED_LOADED_LEG);\n                chartDescriptor.setDetailsItems(new String[] { TOTAL_LOADED, SHARED_LOADED,\n                                                               TOTAL_UNLOADED, SHARED_UNLOADED });\n\n                chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n                model.registerClassesChartSupport(chartSupport);\n\n                chartSupport.setZoomingEnabled(!liveModel);\n            }\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (classMonitoringSupported) {\n                add(chartSupport.getChart(), BorderLayout.CENTER);\n                chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN });\n            } else {\n                add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM),\n                    BorderLayout.CENTER);\n            }\n        }\n\n    }\n\n\n    // --- Threads -------------------------------------------------------------\n\n    private static class ThreadsViewSupport extends JPanel  {\n\n        private static final String LIVE = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Live_threads\");   // NOI18N\n        private static final String LIVE_LEG = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Live_threads_leg\");   // NOI18N\n        private static final String DAEMON = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Daemon_threads\");// NOI18N\n        private static final String DAEMON_LEG = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Daemon_threads_leg\");// NOI18N\n        private static final String PEAK = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Live_threads_peak\");  // NOI18N\n        private static final String STARTED = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Started_threads_total\");   // NOI18N\n\n        private boolean liveModel;\n        private boolean threadsMonitoringSupported;\n\n        private SimpleXYChartSupport chartSupport;\n\n        ThreadsViewSupport(ApplicationMonitorModel model) {\n            initModels(model);\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Threads\"), null, 10, this, null);   // NOI18N\n        }\n\n        public void refresh(ApplicationMonitorModel model) {\n            if (threadsMonitoringSupported) {\n                long totalThreads   = model.getTotalThreads();\n                long daemonThreads  = model.getDeamonThreads();\n                long peakThreads    = model.getPeakThreads();\n                long startedThreads = model.getStartedThreads();\n\n                if (liveModel)\n                        chartSupport.addValues(model.getTimestamp(), new long[] { totalThreads, daemonThreads });\n                chartSupport.updateDetails(new String[] { chartSupport.formatDecimal(totalThreads),\n                                                          chartSupport.formatDecimal(daemonThreads),\n                                                          chartSupport.formatDecimal(peakThreads),\n                                                          chartSupport.formatDecimal(startedThreads) });\n            }\n        }\n\n        private void initModels(ApplicationMonitorModel model) {\n            liveModel = model.isLive();\n            threadsMonitoringSupported = model.isThreadsMonitoringSupported();\n\n            if (threadsMonitoringSupported) {\n                SimpleXYChartDescriptor chartDescriptor =\n                        SimpleXYChartDescriptor.decimal(3, false, model.getChartCache());\n\n                chartDescriptor.addLineItems(LIVE_LEG, DAEMON_LEG);\n                chartDescriptor.setDetailsItems(new String[] { LIVE, DAEMON,\n                                                               PEAK, STARTED });\n\n                chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n                model.registerThreadsChartSupport(chartSupport);\n\n                chartSupport.setZoomingEnabled(!liveModel);\n            }\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (threadsMonitoringSupported) {\n                add(chartSupport.getChart(), BorderLayout.CENTER);\n                chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN });\n            } else {\n                add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM),\n                    BorderLayout.CENTER);\n            }\n        }\n\n    }\n\n    // --- Virtual Threads -------------------------------------------------------------\n\n    private static class VirtualThreadsViewSupport extends JPanel  {\n\n        private static final String PARALLELISM = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Parallelism\");   // NOI18N\n        private static final String POOL_SIZE = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Pool_size\");  // NOI18N\n        private static final String MOUNTED_VT_COUNT = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Mounted_virtual_thread_count\");   // NOI18N\n        private static final String MOUNTED_VT_COUNT_LEG = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Mounted_virtual_thread_count_leg\");   // NOI18N\n        private static final String QUEUED_VT_COUNT = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Queued_virtual_thread_count\");// NOI18N\n        private static final String QUEUED_VT_COUNT_LEG = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Queued_virtual_thread_count_leg\");// NOI18N\n        private static final String VIRTUAL_THREADS = NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Virtual_Threads\");   // NOI18N\n\n        private boolean liveModel;\n        private boolean virtualThreadsMonitoringSupported;\n\n        private SimpleXYChartSupport chartSupport;\n\n\n        VirtualThreadsViewSupport(ApplicationMonitorModel model) {\n            initModels(model);\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(VIRTUAL_THREADS, null, 10, this, null);\n        }\n\n        public void refresh(ApplicationMonitorModel model) {\n                int parallelism = model.getParallelism();\n                int poolSize = model.getPoolSize();\n                int mountedVirtualThreadCount = model.getMountedVirtualThreadCount();\n                long queuedVirtualThreadCount = model.getQueuedVirtualThreadCount();\n\n                if (liveModel)\n                        chartSupport.addValues(model.getTimestamp(), new long[] { mountedVirtualThreadCount, queuedVirtualThreadCount });\n                chartSupport.updateDetails(new String[] { chartSupport.formatDecimal(parallelism),\n                                                          chartSupport.formatDecimal(poolSize),\n                                                          chartSupport.formatDecimal(mountedVirtualThreadCount),\n                                                          chartSupport.formatDecimal(queuedVirtualThreadCount) });\n        }\n\n        private void initModels(ApplicationMonitorModel model) {\n            liveModel = model.isLive();\n            virtualThreadsMonitoringSupported = model.isVirtualThreadsMonitoringSupported();\n\n            if (virtualThreadsMonitoringSupported) {\n                SimpleXYChartDescriptor chartDescriptor =\n                        SimpleXYChartDescriptor.decimal(3, false, model.getChartCache());\n\n                chartDescriptor.addLineItems(MOUNTED_VT_COUNT_LEG, QUEUED_VT_COUNT_LEG);\n                chartDescriptor.setDetailsItems(new String[] { PARALLELISM, POOL_SIZE,\n                                                               MOUNTED_VT_COUNT, QUEUED_VT_COUNT });\n\n                chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n                model.registerThreadsChartSupport(chartSupport);\n\n                chartSupport.setZoomingEnabled(!liveModel);\n            }\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            add(chartSupport.getChart(), BorderLayout.CENTER);\n            chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN });\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/monitor/ApplicationMonitorViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.monitor;\n\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ApplicationMonitorViewProvider extends PluggableDataSourceViewProvider<Application>{\n    \n    protected boolean supportsViewFor(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE)\n            return getCachedView(application) != null;\n\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        return jvm.isMonitoringSupported();\n    }\n\n    protected DataSourceView createView(Application application) {\n        return new ApplicationMonitorView(ApplicationMonitorModel.create(application, true));\n    }\n    \n    public Set<Integer> getPluggableLocations(DataSourceView view) {\n        return ALL_LOCATIONS;\n    }\n\n    protected boolean supportsSaveViewFor(Application application, Class<? extends Snapshot> snapshotClass) {\n        return ApplicationSnapshot.class.isAssignableFrom(snapshotClass);\n    }\n\n    protected void saveView(Application application, Snapshot snapshot) {\n        ApplicationMonitorView view = (ApplicationMonitorView)getCachedView(application);\n        if (view != null) view.getModel().save(snapshot);\n        else ApplicationMonitorModel.create(application, false).save(snapshot);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/monitor/ApplicationSnapshotMonitorViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.monitor;\n\nimport java.util.Set;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ApplicationSnapshotMonitorViewProvider extends PluggableDataSourceViewProvider<ApplicationSnapshot> {\n    \n    protected boolean supportsViewFor(ApplicationSnapshot snapshot) {\n        return snapshot.getStorage().getCustomProperty(ApplicationMonitorModel.SNAPSHOT_VERSION) != null;\n    }\n\n    protected DataSourceView createView(ApplicationSnapshot snapshot) {\n        return new ApplicationMonitorView(ApplicationMonitorModel.create(snapshot));\n    }\n    \n    public Set<Integer> getPluggableLocations(DataSourceView view) {\n        return ALL_LOCATIONS;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/monitor/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n# HTML-formatted: <unknown> (&lt; and &gt; must remain!)\nLBL_Unknown=&lt;unknown&gt;\n\nLBL_Monitor=Monitor\n\nLBL_Cpu=CPU\n\nLBL_Cpu_Usage=CPU usage\n\nLBL_Gc_Usage=GC activity\n\nLBL_Memory=Memory\n\nLBL_Heap=Heap\n\nLBL_PermGen=PermGen\n\nLBL_Classes=Classes\n\nLBL_Threads=Threads\n\nLBL_Perform_GC=Perform GC\n\nTXT_Perform_GC_failed=Perform GC action failed.\\n{0}\n\nLBL_Heap_Dump=Heap Dump\n\n# HTML-formatted: Uptime: 11:20 AM\nLBL_Uptime=<nobr><b>Uptime:</b> {0}</nobr>\n\nLBL_Heap_size=Size\n\nLBL_Used_heap=Used\n\nLBL_Heap_size_leg={0} size\n\nLBL_Used_heap_leg=Used {0}\n\nLBL_Max_Heap=Max\n\nLBL_PermGen_size=Size\n\nLBL_Used_PermGen=Used\n\nLBL_PermGen_size_leg={0} size\n\nLBL_Used_PermGen_leg=Used {0}\n\nLBL_Max_PermGen_size=Max\n\nLBL_Total_loaded_classes=Total loaded\n\nLBL_Shared_loaded_classes=Shared loaded\n\nLBL_Total_unloaded_classes=Total unloaded\n\nLBL_Shared_unloaded_classes=Shared unloaded\n\nLBL_Total_loaded_classes_leg=Total loaded classes\n\nLBL_Shared_loaded_classes_leg=Shared loaded classes\n\nLBL_Live_threads=Live\n\nLBL_Daemon_threads=Daemon\n\nLBL_Live_threads_peak=Live peak\n\nLBL_Started_threads_total=Total started\n\nLBL_Live_threads_leg=Live threads\n\nLBL_Daemon_threads_leg=Daemon threads\n\nLBL_Virtual_Threads=Virtual Threads\n\nLBL_Parallelism=Parallelism\n\nLBL_Pool_size=Pool size\n\nLBL_Mounted_virtual_thread_count=Mounted VT count\n\nLBL_Mounted_virtual_thread_count_leg=Mounted VT count\n\nLBL_Queued_virtual_thread_count=Queued VT count\n\nLBL_Queued_virtual_thread_count_leg=Queued VT count\n\nFORMAT_hms={0} hrs {1} min {2} sec\nFORMAT_ms={0} min {1} sec\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/overview/ApplicationOverviewModel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.overview;\n\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Properties;\nimport java.util.StringTokenizer;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.openide.util.NbBundle;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ApplicationOverviewModel {\n    \n    private static final String PROP_PREFIX = \"ApplicationOverviewModel_\";  // NOI18N\n    \n    static final String SNAPSHOT_VERSION = PROP_PREFIX + \"version\"; // NOI18N\n    private static final String SNAPSHOT_VERSION_DIVIDER = \".\"; // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = \"1\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MINOR = \"0\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION = CURRENT_SNAPSHOT_VERSION_MAJOR + SNAPSHOT_VERSION_DIVIDER + CURRENT_SNAPSHOT_VERSION_MINOR;\n    \n    private static final String PROP_NOT_DEFINED = \"<not defined>\"; // NOI18N\n    \n    public static final String PROP_BASIC_INFO_SUPPORTED = PROP_PREFIX + \"basic_info_supported\";    // NOI18N\n    public static final String PROP_SYSTEM_PROPERTIES_SUPPORTED = PROP_PREFIX + \"system_properties_supported\";  // NOI18N\n    public static final String PROP_PID = PROP_PREFIX + \"pid\";  // NOI18N\n    public static final String PROP_HOST_NAME = PROP_PREFIX + \"host_name\";  // NOI18N\n    public static final String PROP_MAIN_CLASS = PROP_PREFIX + \"main_class\";    // NOI18N\n    public static final String PROP_MAIN_ARGS = PROP_PREFIX + \"main_args\";  // NOI18N\n    public static final String PROP_VM_ID = PROP_PREFIX + \"vm_id\";  // NOI18N\n    public static final String PROP_JAVA_HOME = PROP_PREFIX + \"java_home\";  // NOI18N\n    public static final String PROP_JAVA_VERSION = PROP_PREFIX + \"java_version\";  // NOI18N\n    public static final String PROP_JAVA_VENDOR = PROP_PREFIX + \"java_vendor\";  // NOI18N\n    public static final String PROP_JVM_FLAGS = PROP_PREFIX + \"jvm_flags\";  // NOI18N\n    public static final String PROP_OOME_ENABLED = PROP_PREFIX + \"oome_enabled\";    // NOI18N\n    public static final String PROP_JVM_ARGS = PROP_PREFIX + \"jvm_args\";    // NOI18N\n    public static final String PROP_SYSTEM_PROPERTIES = PROP_PREFIX + \"system.properties\";  // NOI18N\n    \n    private boolean initialized;\n    private DataSource source;\n\n    private boolean basicInfoSupported;\n    private boolean systemPropertiesSupported;\n    private String pid;\n    private String hostName;\n    private String mainClass;\n    private String mainArgs;\n    private String vmId;\n    private String javaHome;\n    private String javaVersion;\n    private String javaVendor;\n    private String jvmFlags;\n    private String oomeEnabled;\n    private String jvmArgs;\n    private String systemProperties;\n\n    \n    public static ApplicationOverviewModel create(Application application) {\n        ApplicationOverviewModel model = new ApplicationOverviewModel();\n        model.initialized = false;\n        model.source = application;\n        return model;\n    }\n    \n    public static ApplicationOverviewModel create(Snapshot snapshot) {\n        ApplicationOverviewModel model = new ApplicationOverviewModel();\n        model.initialized = false;\n        model.source = snapshot;\n        return model;\n    }\n\n    \n    public DataSource getSource() { return source; }\n    public boolean basicInfoSupported() { return basicInfoSupported; }\n    public boolean systemPropertiesSupported() { return systemPropertiesSupported; }\n    public String getPid() { return pid; }\n    public String getHostName() { return hostName; }\n    public String getMainClass() { return mainClass; }\n    public String getMainArgs() { return mainArgs; }\n    public String getVmId() { return vmId; }\n    public String getJavaHome() { return javaHome; }\n    public String getJavaVersion() { return javaVersion; }\n    public String getJavaVendor() { return javaVendor; }\n    public String getJvmFlags() { return jvmFlags; }\n    public String oomeEnabled() {\n        if (basicInfoSupported() && source instanceof Application) {\n            Jvm jvm = JvmFactory.getJVMFor((Application)source);\n            oomeEnabled = jvm.isDumpOnOOMEnabled() ? NbBundle.getMessage(ApplicationOverviewModel.class, \"LBL_enabled\") : NbBundle.getMessage(ApplicationOverviewModel.class, \"LBL_disabled\");  // NOI18N\n        }\n        return oomeEnabled;\n    }\n    public String getJvmArgs() { return jvmArgs; }\n    public String getSystemProperties() { return systemProperties; }\n    \n    \n    public synchronized void initialize() {\n        if (initialized) return;\n        initialized = true;\n        if (source instanceof Application) initialize((Application)source);\n        else initialize((Snapshot)source);\n    }\n    \n    public void save(Snapshot snapshot) {\n        \n        initialize();\n        \n        Storage storage = snapshot.getStorage();\n        \n        setProperty(storage, SNAPSHOT_VERSION, CURRENT_SNAPSHOT_VERSION);\n        \n        setProperty(storage, PROP_BASIC_INFO_SUPPORTED, Boolean.toString(basicInfoSupported));\n        setProperty(storage, PROP_SYSTEM_PROPERTIES_SUPPORTED, Boolean.toString(systemPropertiesSupported));\n        setProperty(storage, PROP_PID, pid);\n        setProperty(storage, PROP_HOST_NAME, hostName);\n        setProperty(storage, PROP_MAIN_CLASS, mainClass);\n        setProperty(storage, PROP_MAIN_ARGS, mainArgs);\n        setProperty(storage, PROP_VM_ID, vmId);\n        setProperty(storage, PROP_JAVA_HOME, javaHome);\n        setProperty(storage, PROP_JAVA_VERSION, javaVersion);\n        setProperty(storage, PROP_JAVA_VENDOR, javaVendor);\n        setProperty(storage, PROP_JVM_FLAGS, jvmFlags);\n        setProperty(storage, PROP_OOME_ENABLED, oomeEnabled);\n        setProperty(storage, PROP_JVM_ARGS, jvmArgs);\n        setProperty(storage, PROP_SYSTEM_PROPERTIES, systemProperties);\n        \n    }\n\n    private void initialize(Snapshot snapshot) {\n        // TODO: if some property cannot be loaded for current snapshot version, FAIL initializing the snapshot!\n        Storage storage = snapshot.getStorage();\n        \n        basicInfoSupported = Boolean.parseBoolean(getProperty(storage, PROP_BASIC_INFO_SUPPORTED));\n        systemPropertiesSupported = Boolean.parseBoolean(getProperty(storage, PROP_SYSTEM_PROPERTIES_SUPPORTED));\n        pid = getProperty(storage, PROP_PID);\n        hostName = getProperty(storage, PROP_HOST_NAME);\n        mainClass = getProperty(storage, PROP_MAIN_CLASS);\n        mainArgs = getProperty(storage, PROP_MAIN_ARGS);\n        vmId = getProperty(storage, PROP_VM_ID);\n        javaHome = getProperty(storage, PROP_JAVA_HOME);\n        javaVersion = getProperty(storage, PROP_JAVA_VERSION);\n        javaVendor = getProperty(storage, PROP_JAVA_VENDOR);\n        jvmFlags = getProperty(storage, PROP_JVM_FLAGS);\n        oomeEnabled = getProperty(storage, PROP_OOME_ENABLED);\n        jvmArgs = getProperty(storage, PROP_JVM_ARGS);\n        systemProperties = getProperty(storage, PROP_SYSTEM_PROPERTIES);\n        \n    }\n    \n    private static void setProperty(Storage storage, String property, String value) {\n        storage.setCustomProperty(property, value == null ? PROP_NOT_DEFINED : value);\n    }\n    \n    private static String getProperty(Storage storage, String property) {\n        String value = storage.getCustomProperty(property);\n        return PROP_NOT_DEFINED.equals(value) ? null : value;\n    }\n    \n    private void initialize(Application application) {\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        \n        source = application;\n\n        basicInfoSupported = jvm.isBasicInfoSupported();\n        systemPropertiesSupported = jvm.isGetSystemPropertiesSupported();\n\n        int pidInt = application.getPid();\n        pid = pidInt == Application.UNKNOWN_PID ? NbBundle.getMessage(ApplicationOverviewModel.class, \"LBL_unknown\") : \"\" + pidInt; // NOI18N\n        \n        hostName = application.getHost().getHostName();\n        \n        if (basicInfoSupported) {\n            mainClass = jvm.getMainClass();\n            if (mainClass == null || mainClass.isEmpty()) mainClass = NbBundle.getMessage(ApplicationOverviewModel.class, \"LBL_unknown\");  // NOI18N\n\n            mainArgs = jvm.getMainArgs();\n            if (mainArgs == null) mainArgs = NbBundle.getMessage(ApplicationOverviewModel.class, \"LBL_none\");   // NOI18N\n\n            String vmVersion = jvm.getVmVersion();\n            String vmInfo = jvm.getVmInfo();\n            String vmName = jvm.getVmName();\n            \n            String vmDetails = null;\n            if (vmVersion != null && vmInfo != null) vmDetails = vmVersion + \", \" + vmInfo;   // NOI18N\n            else if (vmVersion != null) vmDetails = vmVersion;\n            else if (vmInfo != null) vmDetails = vmInfo;\n            if (vmName == null || vmName.isEmpty()) vmName = NbBundle.getMessage(ApplicationOverviewModel.class, \"LBL_unknown\");  // NOI18N\n            \n            vmId = vmName;\n            if (vmDetails != null) vmId += \" (\" + vmDetails + \")\";  // NOI18N\n\n            javaHome = jvm.getJavaHome();\n            if (javaHome == null || javaHome.isEmpty()) javaHome = NbBundle.getMessage(ApplicationOverviewModel.class, \"LBL_unknown\");  // NOI18N\n            \n            javaVersion = jvm.getJavaVersion();\n            javaVendor = jvm.getVmVendor();\n\n            jvmFlags = jvm.getJvmFlags();\n            if (jvmFlags == null || jvmFlags.isEmpty()) jvmFlags = NbBundle.getMessage(ApplicationOverviewModel.class, \"LBL_none\"); // NOI18N\n\n            oomeEnabled = jvm.isDumpOnOOMEnabled() ? NbBundle.getMessage(ApplicationOverviewModel.class, \"LBL_enabled\") : NbBundle.getMessage(ApplicationOverviewModel.class, \"LBL_disabled\");  // NOI18N\n            String jvmArgs = jvm.getJvmArgs();\n            if (jvmArgs != null) this.jvmArgs = formatJVMArgs(jvmArgs);\n        }\n        \n        if (systemPropertiesSupported) {\n            Properties jvmProperties = jvm.getSystemProperties();\n            if (jvmProperties != null) {\n                systemProperties = formatSystemProperties(jvmProperties);\n                String relDate = jvmProperties.getProperty(\"java.version.date\", \"\");         // NOI18N\n                if (!relDate.isEmpty()) javaVersion += \" \" + relDate;\n                if (jvm.getVmVersion().contains(\"LTS\")) javaVersion += \" LTS\";           // NOI18N\n            }\n        }\n    }\n\n    \n    private static String formatJVMArgs(String jvmargs) {\n        String mangledString = \" \".concat(jvmargs).replace(\" -\", \"\\n\"); // NOI18N\n        StringTokenizer tok = new StringTokenizer(mangledString, \"\\n\"); // NOI18N\n        StringBuilder text = new StringBuilder(100);\n        while (tok.hasMoreTokens()) {\n            String arg = tok.nextToken().replace(\" \", \"&nbsp;\");    // NOI18N\n            int equalsSign = arg.indexOf('=');\n\n            text.append(\"<b>\"); // NOI18N\n            text.append(\"-\");   // NOI18N\n            if (equalsSign != -1) {\n                text.append(arg, 0, equalsSign);\n                text.append(\"</b>\");    // NOI18N\n                text.append(arg.substring(equalsSign));\n            } else {\n                text.append(arg);\n                text.append(\"</b>\");    // NOI18N\n            }\n            text.append(\"<br>\");    // NOI18N\n        }\n        return text.toString();\n    }\n\n    private static String formatSystemProperties(Properties properties) {\n        StringBuilder text = new StringBuilder(200);\n        List<Object> keys = new ArrayList<>();\n        Enumeration<?> en = properties.propertyNames();\n        Iterator<?> keyIt;\n        \n        while (en.hasMoreElements()) {\n            keys.add(en.nextElement());\n        }\n\n        keys.sort(null);\n        keyIt = keys.iterator();\n        while (keyIt.hasNext()) {\n            String key = (String) keyIt.next();\n            String val = properties.getProperty(key);\n            \n            if (\"line.separator\".equals(key) && val != null) {  // NOI18N\n                val = val.replace(\"\\n\", \"\\\\n\"); // NOI18N\n                val = val.replace(\"\\r\", \"\\\\r\"); // NOI18N\n            }\n\n            text.append(\"<b>\"); // NOI18N\n            text.append(key);\n            text.append(\"</b>=\");   // NOI18N\n            text.append(val);\n            text.append(\"<br>\");    // NOI18N\n        }\n        return expandInvalidXMLChars(text);\n    }\n    \n    private static String expandInvalidXMLChars(CharSequence chars) {\n        StringBuilder text = new StringBuilder(chars.length());\n        char ch;\n        \n        for (int i = 0; i < chars.length(); i++) {\n            ch = chars.charAt(i);\n            text.append(isValidXMLChar(ch) ? ch :\n                    \"&lt;0x\" + Integer.toHexString(0x10000 | ch).substring(1).toUpperCase() + \"&gt;\"); // NOI18N\n        }\n        \n        return text.toString();\n    }\n    \n    private static boolean isValidXMLChar(char ch) {\n        return (ch == 0x9 || ch == 0xA || ch == 0xD ||\n              ((ch >= 0x20) && (ch <= 0xD7FF)) ||\n              ((ch >= 0xE000) && (ch <= 0xFFFD)) ||\n              ((ch >= 0x10000) && (ch <= 0x10FFFF)));\n    }\n    \n    private ApplicationOverviewModel() {}\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/overview/ApplicationOverviewView.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.overview;\n\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nclass ApplicationOverviewView extends DataSourceView {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/application/views/resources/overview.png\"; // NOI18N\n\n    private ApplicationOverviewModel model;\n    \n    private OverviewViewSupport.SnapshotsViewSupport snapshotsView;\n    \n\n    ApplicationOverviewView(DataSource dataSource, ApplicationOverviewModel model) {\n        super(dataSource, NbBundle.getMessage(ApplicationOverviewView.class, \"LBL_Overview\"), new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 10, false);  // NOI18N\n        this.model = model;\n    }\n    \n    \n    protected void willBeAdded() {\n        model.initialize();\n    }\n    \n    protected void removed() {\n        snapshotsView.removed();\n    }\n    \n    \n    ApplicationOverviewModel getModel() {\n        return model;\n    }\n    \n    \n    protected DataViewComponent createComponent() {\n        DataViewComponent dvc = new DataViewComponent(\n                new OverviewViewSupport.MasterViewSupport(model).getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(false));\n        \n        dvc.configureDetailsView(new DataViewComponent.DetailsViewConfiguration(0.25, 0, -1, -1, -1, -1));\n        \n        snapshotsView = new OverviewViewSupport.SnapshotsViewSupport(model.getSource());\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(ApplicationOverviewView.class, \"LBL_Saved_data\"), true), DataViewComponent.TOP_LEFT);   // NOI18N\n        dvc.addDetailsView(snapshotsView.getDetailsView(), DataViewComponent.TOP_LEFT);\n        \n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(ApplicationOverviewView.class, \"LBL_Details\"), true), DataViewComponent.TOP_RIGHT); // NOI18N\n        dvc.addDetailsView(new OverviewViewSupport.JVMArgumentsViewSupport(model.getJvmArgs()).getDetailsView(), DataViewComponent.TOP_RIGHT);\n        dvc.addDetailsView(new OverviewViewSupport.SystemPropertiesViewSupport(model.getSystemProperties()).getDetailsView(), DataViewComponent.TOP_RIGHT);\n        \n        return dvc;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/overview/ApplicationOverviewViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.overview;\n\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ApplicationOverviewViewProvider extends PluggableDataSourceViewProvider<Application> {\n    \n    protected boolean supportsViewFor(Application application) {\n        return true;\n    }\n\n    protected DataSourceView createView(Application application) {\n        return new ApplicationOverviewView(application, ApplicationOverviewModel.create(application));\n    }\n    \n    public Set<Integer> getPluggableLocations(DataSourceView view) {\n        return ALL_LOCATIONS;\n    }\n\n    protected boolean supportsSaveViewFor(Application application, Class<? extends Snapshot> snapshotClass) {\n        return ApplicationSnapshot.class.isAssignableFrom(snapshotClass);\n    }\n    \n    protected void saveView(Application application, Snapshot snapshot) {\n        ApplicationOverviewView view = (ApplicationOverviewView)getCachedView(application);\n        if (view != null) view.getModel().save(snapshot);\n        else ApplicationOverviewModel.create(application).save(snapshot);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/overview/ApplicationSnapshotOverviewViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.overview;\n\nimport java.util.Set;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ApplicationSnapshotOverviewViewProvider extends PluggableDataSourceViewProvider<ApplicationSnapshot> {\n    \n    protected boolean supportsViewFor(ApplicationSnapshot snapshot) {\n        return snapshot.getStorage().getCustomProperty(ApplicationOverviewModel.SNAPSHOT_VERSION) != null;\n    }\n\n    protected DataSourceView createView(ApplicationSnapshot snapshot) {\n        return new ApplicationOverviewView(snapshot, ApplicationOverviewModel.create(snapshot));\n    }\n    \n    public Set<Integer> getPluggableLocations(DataSourceView view) {\n        return ALL_LOCATIONS;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/overview/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nLBL_enabled=enabled\n\nLBL_disabled=disabled\n\n# HTML-formatted: <unknown> (&lt; and &gt; must remain!)\nLBL_unknown=&lt;unknown&gt;\n\n# HTML-formatted: <none> (&lt; and &gt; must remain!)\nLBL_none=&lt;none&gt;\n\nLBL_Overview=Overview\n\nLBL_Saved_data=Saved data\n\nLBL_Details=Details\n\nLBL_PID=PID\n\nLBL_Host=Host\n\nLBL_Main_class=Main class\n\nLBL_Arguments=Arguments\n\nLBL_JVM=JVM\n\nLBL_Java_Home=Java Home\n\nLBL_Java=Java\n\nLBL_Java_Version=version\n\nLBL_Java_Vendor=vendor\n\nLBL_JVM_Flags=JVM Flags\n\nLBL_Heap_dump_on_OOME=Heap dump on OOME\n\nLBL_JVM_arguments=JVM arguments\n\nLBL_System_properties=System properties\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/overview/OverviewViewSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.overview;\n\nimport java.awt.BorderLayout;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.core.snapshot.RegisteredSnapshotCategories;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.NotSupportedDisplayer;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextAreaSearchUtils;\nimport org.openide.util.NbBundle;\nimport org.openide.util.WeakListeners;\n\n/**\n * A public entrypoint to the Overview subtab.\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nclass OverviewViewSupport {\n\n    // --- General data --------------------------------------------------------\n    \n    static class MasterViewSupport extends JPanel  {\n        private PropertyChangeListener oomeListener;\n        \n        MasterViewSupport(ApplicationOverviewModel model) {\n            initComponents(model);\n        }\n        \n        \n        public DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(OverviewViewSupport.class, \"LBL_Overview\"), null, this);    // NOI18N\n        }\n        \n        \n        private void initComponents(final ApplicationOverviewModel model) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            final HTMLTextArea area = new HTMLTextArea(\"<nobr>\" + getGeneralProperties(model) + \"</nobr>\"); // NOI18N\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n            \n            DataSource source = model.getSource();\n            if (source instanceof Application) {\n                oomeListener = new PropertyChangeListener() {\n                    public void propertyChange(PropertyChangeEvent evt) {\n                        if (Jvm.PROPERTY_DUMP_OOME_ENABLED.equals(evt.getPropertyName())) {\n                            int selStart = area.getSelectionStart();\n                            int selEnd   = area.getSelectionEnd();\n                            area.setText(\"<nobr>\" + getGeneralProperties(model) + \"</nobr>\");   // NOI18N\n                            area.select(selStart, selEnd);\n                        }\n                    }\n                };\n                Jvm jvm = JvmFactory.getJVMFor((Application)source);\n                jvm.addPropertyChangeListener(WeakListeners.propertyChange(oomeListener,jvm));\n            }\n            add(area, BorderLayout.CENTER);\n        }\n        \n        private String getGeneralProperties(ApplicationOverviewModel model) {\n            StringBuilder data = new StringBuilder();\n            \n            // Application information\n            String PID = NbBundle.getMessage(OverviewViewSupport.class, \"LBL_PID\"); // NOI18N\n            String HOST = NbBundle.getMessage(OverviewViewSupport.class, \"LBL_Host\");   // NOI18N\n            data.append(\"<b>\"+PID+\":</b> \" + model.getPid() + \"<br>\");  // NOI18N\n            data.append(\"<b>\"+HOST+\":</b> \" + model.getHostName() + \"<br>\");    // NOI18N\n            \n            if (model.basicInfoSupported()) {\n                String MAIN_CLASS = NbBundle.getMessage(OverviewViewSupport.class, \"LBL_Main_class\");   // NOI18N\n                String ARGS = NbBundle.getMessage(OverviewViewSupport.class, \"LBL_Arguments\");  // NOI18N\n                String JVM = NbBundle.getMessage(OverviewViewSupport.class, \"LBL_JVM\"); // NOI18N\n                String JAVA_HOME = NbBundle.getMessage(OverviewViewSupport.class, \"LBL_Java_Home\"); // NOI18N\n                String JAVA = NbBundle.getMessage(OverviewViewSupport.class, \"LBL_Java\"); // NOI18N\n                String JAVA_VERSION = NbBundle.getMessage(OverviewViewSupport.class, \"LBL_Java_Version\"); // NOI18N\n                String JAVA_VENDOR = NbBundle.getMessage(OverviewViewSupport.class, \"LBL_Java_Vendor\"); // NOI18N\n                String JVM_FLAGS = NbBundle.getMessage(OverviewViewSupport.class, \"LBL_JVM_Flags\"); // NOI18N\n                String HEAP_DUMP_OOME = NbBundle.getMessage(OverviewViewSupport.class, \"LBL_Heap_dump_on_OOME\");    // NOI18N\n                data.append(\"<b>\"+MAIN_CLASS+\":</b> \" + model.getMainClass() + \"<br>\"); // NOI18N\n                data.append(\"<b>\"+ARGS+\":</b> \" + model.getMainArgs() + \"<br>\");    // NOI18N\n                \n                data.append(\"<br>\");    // NOI18N\n                data.append(\"<b>\"+JVM+\":</b> \" + model.getVmId() + \"<br>\"); // NOI18N\n                String javaVersion = model.getJavaVersion();\n                String javaVendor = model.getJavaVendor();\n                if (javaVersion != null || javaVendor != null) {\n                    data.append(\"<b>\"+JAVA+\":</b>\");\n                    if (javaVersion != null) {\n                        data.append(\" \"+JAVA_VERSION+\" \" + javaVersion);   // NOI18N\n                    }\n                    if (javaVendor != null) {\n                        if (javaVersion != null) data.append(\",\");\n                        data.append(\" \"+JAVA_VENDOR+\" \" + javaVendor);   // NOI18N\n                    }\n                    data.append(\"<br>\");\n                }\n                data.append(\"<b>\"+JAVA_HOME+\":</b> \" + model.getJavaHome() + \"<br>\");   // NOI18N\n                data.append(\"<b>\"+JVM_FLAGS+\":</b> \" + model.getJvmFlags() + \"<br><br>\");   // NOI18N\n                data.append(\"<b>\"+HEAP_DUMP_OOME+\":</b> \" + model.oomeEnabled() + \"<br>\");  // NOI18N\n            }\n            \n            return data.toString();\n            \n        }\n        \n    }\n    \n    // --- Snapshots -----------------------------------------------------------\n    \n    static class SnapshotsViewSupport extends JPanel implements DataChangeListener<Snapshot> {\n        \n        private static final String LINK_TOGGLE_CATEGORY = \"file:/toggle_category\"; // NOI18N\n        private static final String LINK_OPEN_SNAPSHOT = \"file:/open_snapshot\"; // NOI18N\n        \n        private DataSource dataSource;\n        private HTMLTextArea area;\n        \n        private final Map<Integer, Snapshot> snapshotsMap = new HashMap<>();\n        private final Map<String, Boolean> expansionMap = new HashMap<>();\n\n        private boolean standaloneAppSnapshot;\n        \n        \n        SnapshotsViewSupport(DataSource dataSource) {\n            this.dataSource = dataSource;\n            initComponents();\n            dataSource.getRepository().addDataChangeListener(this, Snapshot.class);\n\n            standaloneAppSnapshot = dataSource.getOwner() == null &&\n                                    dataSource instanceof ApplicationSnapshot;\n            if (standaloneAppSnapshot) {\n                dataSource.setVisible(false);\n                DataSource.ROOT.getRepository().addDataSource(dataSource);\n            }\n        }\n        \n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(OverviewViewSupport.class, \"LBL_Saved_data\"), null, 10, this, null);   // NOI18N\n        }\n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea() {\n                protected void showURL(URL url) {\n                    String link = url.toString();\n                    if (link.startsWith(LINK_TOGGLE_CATEGORY)) {\n                        link = link.substring(LINK_TOGGLE_CATEGORY.length());\n                        toggleExpanded(link); \n                        updateSavedData();\n                    } else if (link.startsWith(LINK_OPEN_SNAPSHOT)) {\n                        link = link.substring(LINK_OPEN_SNAPSHOT.length());\n                        Snapshot s = snapshotsMap.get(Integer.parseInt(link));\n                        if (s != null) DataSourceWindowManager.sharedInstance().openDataSource(s);\n                    }\n                }\n            };\n            updateSavedData();\n            area.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n            \n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n        }\n        \n        public void dataChanged(DataChangeEvent<Snapshot> event) {\n            SwingUtilities.invokeLater(this::updateSavedData);\n        }\n            \n        void removed() {\n            dataSource.getRepository().removeDataChangeListener(this);\n            if (standaloneAppSnapshot)\n                DataSource.ROOT.getRepository().removeDataSource(dataSource);\n        }\n        \n        private void updateSavedData() {\n            snapshotsMap.clear();\n            StringBuilder data = new StringBuilder();\n            \n            List<SnapshotCategory<? extends Snapshot>> snapshotCategories = RegisteredSnapshotCategories.sharedInstance().getVisibleCategories();\n            for (SnapshotCategory<? extends Snapshot> category : snapshotCategories) {\n                Set<? extends Snapshot> snapshots = dataSource.getRepository().getDataSources(category.getType());\n                if (snapshots.isEmpty()) {\n                    data.append(\"<b>\" + category.getName() + \":</b> \" + snapshots.size() + \"<br>\"); // NOI18N\n                } else {\n                    String categoryName = category.getName();\n                    data.append(\"<b>\" + categoryName + \":</b> <a href='\" + (LINK_TOGGLE_CATEGORY + categoryName) + \"'>\" + snapshots.size() + \"</a><br>\"); // NOI18N\n                    \n                    if (isExpanded(categoryName)) {\n                        List<DataSourceDescriptor<? extends Snapshot>> descriptors = new ArrayList<>();\n                        Map<DataSourceDescriptor<? extends Snapshot>, Snapshot> dataSources = new HashMap<>();\n\n                        for (Snapshot s : snapshots) {\n                            DataSourceDescriptor<? extends Snapshot> dsd = DataSourceDescriptorFactory.getDescriptor(s);\n                            descriptors.add(dsd);\n                            dataSources.put(dsd, s);\n                        }\n                        descriptors.sort(Positionable.STRONG_COMPARATOR);\n\n                        int size = snapshotsMap.size();\n                        for (int i = 0; i < descriptors.size(); i++) {\n                            DataSourceDescriptor<? extends Snapshot> dsd = descriptors.get(i);\n                            Snapshot s = dataSources.get(dsd);\n                            snapshotsMap.put(i + size, s);\n                            data.append(\"&nbsp;&nbsp;&nbsp;<a href='\" + LINK_OPEN_SNAPSHOT + (i + size) + \"'>\" + dsd.getName() + \"</a><br>\"); // NOI18N\n                        }\n                        data.append(\"<br>\"); // NOI18N\n                    }\n                }\n            }            \n            \n            area.setText(\"<nobr>\" + data.toString() + \"</nobr>\");   // NOI18N\n        }\n        \n        private boolean isExpanded(String categoryName) {\n            Boolean expanded = expansionMap.computeIfAbsent(categoryName, k -> standaloneAppSnapshot);\n            return expanded.booleanValue();\n        }\n        \n        private void toggleExpanded(String categoryName) {\n            expansionMap.put(categoryName, !isExpanded(categoryName));\n        }\n        \n    }\n    \n    \n    // --- JVM arguments -------------------------------------------------------\n    \n    static class JVMArgumentsViewSupport extends JPanel  {\n        \n        JVMArgumentsViewSupport(String jvmargs) {\n            initComponents(jvmargs);\n        }\n        \n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(OverviewViewSupport.class, \"LBL_JVM_arguments\"), null, 10, this, null);    // NOI18N\n        }\n        \n        private void initComponents(String jvmargs) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            JComponent contents;\n            HTMLTextArea area = null;\n            \n            if (jvmargs != null) {\n                area = new HTMLTextArea(\"<nobr>\" + jvmargs + \"</nobr>\");   // NOI18N\n                area.setCaretPosition(0);\n                area.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n                contents = area;\n            } else {\n                contents = new NotSupportedDisplayer(NotSupportedDisplayer.JVM);\n            }\n            \n            add(new ScrollableContainer(contents), BorderLayout.CENTER);\n            if (area != null) add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n    }\n        \n    \n    // --- System properties ---------------------------------------------------\n    \n    static class SystemPropertiesViewSupport extends JPanel  {\n        \n        SystemPropertiesViewSupport(String properties) {\n            initComponents(properties);\n        }\n        \n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(OverviewViewSupport.class, \"LBL_System_properties\"), null, 20, this, null);    // NOI18N\n        }\n        \n        private void initComponents(String properties) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            JComponent contents;\n            HTMLTextArea area = null;\n            \n            if (properties != null) {\n                area = new HTMLTextArea(\"<nobr>\" + properties + \"</nobr>\");    // NOI18N\n                area.setCaretPosition(0);\n                area.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n                contents = area;\n            } else {\n                contents = new NotSupportedDisplayer(NotSupportedDisplayer.JVM);\n            }\n            \n            add(new ScrollableContainer(contents), BorderLayout.CENTER);\n            if (area != null) add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n    }\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Support for views (subtabs) for applications and application snapshots.\n */\npackage org.graalvm.visualvm.application.views;\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/resources/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Application Views\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/threads/ApplicationSnapshotThreadsViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.threads;\n\nimport java.util.Set;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ApplicationSnapshotThreadsViewProvider extends PluggableDataSourceViewProvider<ApplicationSnapshot> {\n    \n    protected boolean supportsViewFor(ApplicationSnapshot snapshot) {\n        return PersistenceSupport.supportsStorage(snapshot.getStorage());\n    }\n\n    protected DataSourceView createView(ApplicationSnapshot snapshot) {\n        return new ApplicationThreadsView(snapshot);\n    }\n    \n    public Set<Integer> getPluggableLocations(DataSourceView view) {\n        return ALL_LOCATIONS;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/threads/ApplicationThreadsView.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.threads;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.ActionPopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.threads.ThreadsPanel;\nimport org.graalvm.visualvm.threaddump.ThreadDumpSupport;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeansFactory;\nimport org.graalvm.visualvm.tools.jmx.MBeanCacheListener;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.WeakListeners;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ApplicationThreadsView extends DataSourceView implements DataRemovedListener<Application> {\n\n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/application/views/resources/threads.png\";  // NOI18N\n    private static final String DEADLOCK_ALERT_TEXT = NbBundle.getMessage(ApplicationThreadsView.class, \"Deadlock_Alert_Text\"); // NOI18N\n    private JvmMXBeans mxbeans;\n    private VisualVMThreadsDataManager threadsManager;\n    private MBeanCacheListener listener;\n    private boolean takeThreadDumpSupported;\n    private MasterViewSupport mvs;\n\n    ApplicationThreadsView(DataSource dataSource) {\n        super(dataSource, NbBundle.getMessage(ApplicationThreadsView.class, \"LBL_Threads\"), new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 30, false);   // NOI18N\n    }\n\n    @Override\n    protected void willBeAdded() {\n        DataSource ds = getDataSource();\n        if (ds instanceof Application) {\n            Application application = (Application)ds;\n            Jvm jvm = JvmFactory.getJVMFor(application);\n            takeThreadDumpSupported = jvm.isTakeThreadDumpSupported();\n            threadsManager = null;\n            JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);\n            if (jmxModel != null && jmxModel.getConnectionState() == ConnectionState.CONNECTED) {\n                mxbeans = JvmMXBeansFactory.getJvmMXBeans(jmxModel, GlobalPreferences.sharedInstance().getThreadsPoll() * 1000);\n                if (mxbeans != null) {\n                    ThreadMXBeanDataManager threadsMXManager = new ThreadMXBeanDataManager(application, mxbeans.getThreadMXBean());\n                    \n                    threadsMXManager.addPropertyChangeListener(this::handleThreadsPropertyChange);\n                    threadsManager = threadsMXManager;\n                }\n            }\n        } else {\n            threadsManager = PersistenceSupport.loadDataManager(ds.getStorage());\n        }\n    }\n\n    @Override\n    protected synchronized void removed() {\n        cleanup();\n    }\n\n    VisualVMThreadsDataManager getDataManager() {\n        return threadsManager;\n    }\n\n    public synchronized void dataRemoved(Application dataSource) {\n        cleanup();\n    }\n    \n    private synchronized void cleanup() {\n        if (mxbeans != null) {\n            mxbeans.removeMBeanCacheListener(listener);\n            mxbeans = null;\n            threadsManager.cleanup();\n        }\n    }\n\n    @Override\n    protected void setAlert(Alert newAlert, String newText) {\n        super.setAlert(newAlert,newText);\n        mvs.setAlertText(newText);\n    }\n\n    protected DataViewComponent createComponent() {\n        DataSource ds = getDataSource();\n        final Application application = ds instanceof Application ?\n            (Application)ds : null;\n        mvs = new MasterViewSupport(ds, takeThreadDumpSupported, threadsManager);\n        if (mxbeans != null) {\n            listener = new MBeanCacheListener() {\n                public void flushed() {\n                    if (application.getState() != Stateful.STATE_AVAILABLE) {\n                        cleanup();\n                    } else {\n                        ((ThreadMXBeanDataManager)threadsManager).refreshThreadsAsync();\n                        mvs.updateThreadsCounts(threadsManager);\n                    }\n                }\n            };\n            mxbeans.addMBeanCacheListener(listener);\n        }\n        if (application != null) application.notifyWhenRemoved(this);\n\n        final DataViewComponent dvc = new DataViewComponent(mvs.getMasterView(), new DataViewComponent.MasterViewConfiguration(false));\n\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(ApplicationThreadsView.class, \"LBL_Threads_visualization\"), true), DataViewComponent.TOP_LEFT); // NOI18N\n        dvc.addDetailsView(new TimelineViewSupport(threadsManager).getDetailsView(), DataViewComponent.TOP_LEFT);\n\n        return dvc;\n    }\n    \n    private void handleThreadsPropertyChange(PropertyChangeEvent evt) {\n        if (ThreadMXBeanDataManager.DEADLOCK_PROP.equals(evt.getPropertyName())) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    setAlert(Alert.ERROR,DEADLOCK_ALERT_TEXT);\n                    \n                }\n            });\n        }\n    }\n\n    // --- General data --------------------------------------------------------\n\n    private static class MasterViewSupport extends JPanel implements DataRemovedListener<Application>, PropertyChangeListener {\n\n        private Application application;\n        private HTMLTextArea area;\n        private HTMLTextArea alertArea;\n        private JButton threadDumpButton;\n        private static final String LIVE_THREADS = NbBundle.getMessage(ApplicationThreadsView.class, \"LBL_Live_threads\");    // NOI18N\n        private static final String DAEMON_THREADS = NbBundle.getMessage(ApplicationThreadsView.class, \"LBL_Daemon_threads\");   // NOI18N\n\n        MasterViewSupport(DataSource dataSource, boolean takeThreadDumpSupported,\n                          VisualVMThreadsDataManager threadsManager) {\n            if (dataSource instanceof Application) application = (Application)dataSource;\n            initComponents(takeThreadDumpSupported);\n            updateThreadsCounts(threadsManager);\n        }\n\n        DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(ApplicationThreadsView.class, \"LBL_Threads\"), null, this);  // NOI18N\n        }\n\n        public void dataRemoved(Application dataSource) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    threadDumpButton.setEnabled(false);\n                }\n            });\n        }\n\n        public void propertyChange(PropertyChangeEvent evt) {\n            dataRemoved(application);\n        }\n\n        private void initComponents(boolean takeThreadDumpSupported) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            area = new HTMLTextArea();\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n            add(area, BorderLayout.WEST);\n\n            alertArea = new HTMLTextArea();\n            alertArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n            alertArea.setForeground(Color.RED);\n\n            add(alertArea, BorderLayout.CENTER);\n\n            threadDumpButton = new JButton(new AbstractAction(NbBundle.getMessage(ApplicationThreadsView.class, \"LBL_Thread_Dump\")) {   // NOI18N\n                public void actionPerformed(ActionEvent e) {\n                    ThreadDumpSupport.getInstance().takeThreadDump(application, (e.getModifiers() &\n                            Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n                }\n            });\n            threadDumpButton.setEnabled(takeThreadDumpSupported);\n\n            JPanel buttonsArea = new JPanel(new BorderLayout());\n            buttonsArea.setOpaque(false);\n            JPanel buttonsContainer = new JPanel(new BorderLayout(3, 0));\n            buttonsContainer.setBackground(area.getBackground());\n            buttonsContainer.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n            buttonsContainer.add(threadDumpButton, BorderLayout.EAST);\n            buttonsArea.add(buttonsContainer, BorderLayout.NORTH);\n\n            add(buttonsArea, BorderLayout.AFTER_LINE_ENDS);\n\n            if (application != null) {\n                application.notifyWhenRemoved(this);\n                application.addPropertyChangeListener(Stateful.PROPERTY_STATE,\n                        WeakListeners.propertyChange(this, application));\n            }\n        }\n\n        private void updateThreadsCounts(final VisualVMThreadsDataManager threadsManager) {\n\n            final int[] threads = new int[2];\n            // TODO: needs a worker thread to read threadCount/daemonThreadCount?\n//            getWorker().post(new Runnable() {\n//                public void run() {\n//                    try {\n                        threads[0] = threadsManager.getThreadCount();\n                        threads[1] = threadsManager.getDaemonThreadCount();\n//                    } catch (Exception ex) {\n//                        threads[0] = 0;\n//                        threads[1] = 0;\n//                    }\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            updateThreadsCounts(threads[0], threads[1]);\n                        }\n                    });\n//                }\n//            });\n        }\n\n        private void setAlertText(String alert) {\n            int selStart = alertArea.getSelectionStart();\n            int selEnd = alertArea.getSelectionEnd();\n            alertArea.setText(\"<center>\"+alert+\"</center>\");   // NOI18N\n            alertArea.select(selStart, selEnd);\n        }\n        \n        private void updateThreadsCounts(int liveThreads, int daemonThreads) {\n            StringBuilder data = new StringBuilder();\n\n            data.append(\"<b>\" + LIVE_THREADS + \":</b> \" + liveThreads + \"<br>\");  // NOI18N\n            data.append(\"<b>\" + DAEMON_THREADS + \":</b> \" + daemonThreads + \"<br>\");   // NOI18N\n\n            int selStart = area.getSelectionStart();\n            int selEnd = area.getSelectionEnd();\n            area.setText(data.toString());\n            area.select(selStart, selEnd);\n        }\n\n    }\n\n    // --- Timeline ------------------------------------------------------------\n\n    @NbBundle.Messages({\n        \"ThreadsFeatureUI_show=Show:\",\n        \"ThreadsFeatureUI_filterAll=All Threads\",\n        \"ThreadsFeatureUI_filterLive=Live Threads\",\n        \"ThreadsFeatureUI_filterFinished=Finished Threads\",\n        \"ThreadsFeatureUI_filterSelected=Selected Threads\",\n        \"ThreadsFeatureUI_timeline=Timeline:\",\n        \"ThreadsFeatureUI_threadsFilter=Threads filter\",\n        \"# HTML formatted:\",\n        \"ThreadsFeatureUI_noThreadsMsg=<html><b>No threads are currently selected.</b><br><br>Use the Selected column or invoke Select thread action to select threads.</html>\"\n    })\n    private static class TimelineViewSupport extends JPanel {\n        private ProfilerToolbar toolbar;\n        private ThreadsPanel threadsPanel;\n        \n        private JLabel shLabel;\n        private ActionPopupButton shFilter;\n\n        private JLabel tlLabel;\n        private JComponent tlZoomInButton;\n        private JComponent tlZoomOutButton;\n        private JComponent tlFitWidthButton;\n        \n\n        TimelineViewSupport(VisualVMThreadsDataManager threadsManager) {\n            initComponents(threadsManager);\n        }\n\n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(ApplicationThreadsView.class, \"LBL_Timeline\"), null, 10, this, null);  // NOI18N\n        }\n\n        private void initComponents(VisualVMThreadsDataManager threadsManager) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            threadsPanel = new ThreadsPanel(threadsManager, null) {\n                protected void filterSelected(ThreadsPanel.Filter filter) {\n                    super.filterSelected(filter);\n                    shFilter.selectAction(filter.ordinal());\n                }\n            };\n            threadsPanel.threadsMonitoringEnabled();\n            \n            InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n            ActionMap actionMap = getActionMap();\n\n            final String filterKey = FilterUtils.FILTER_ACTION_KEY;\n            Action filterAction = new AbstractAction() {\n                public void actionPerformed(ActionEvent e) {\n                    Action action = threadsPanel.getActionMap().get(filterKey);\n                    if (action != null && action.isEnabled()) action.actionPerformed(e);\n                }\n            };\n            ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);\n\n            final String findKey = SearchUtils.FIND_ACTION_KEY;\n            Action findAction = new AbstractAction() {\n                public void actionPerformed(ActionEvent e) {\n                    Action action = threadsPanel.getActionMap().get(findKey);\n                    if (action != null && action.isEnabled()) action.actionPerformed(e);\n                }\n            };\n            ActionsSupport.registerAction(findKey, findAction, actionMap, inputMap);\n            \n            // -----------------------------------------------------------------\n            // --- copy-pasted timeline toolbar from org.graalvm.visualvm.lib.profiler.v2.features.ThreadsFeatureUI\n            \n            shLabel = new GrayLabel(Bundle.ThreadsFeatureUI_show());\n\n            Action aAll = new AbstractAction() {\n                { putValue(NAME, Bundle.ThreadsFeatureUI_filterAll()); }\n                public void actionPerformed(ActionEvent e) { setFilter(ThreadsPanel.Filter.ALL); }\n\n            };\n            Action aLive = new AbstractAction() {\n                { putValue(NAME, Bundle.ThreadsFeatureUI_filterLive()); }\n                public void actionPerformed(ActionEvent e) { setFilter(ThreadsPanel.Filter.LIVE); }\n\n            };\n            Action aFinished = new AbstractAction() {\n                { putValue(NAME, Bundle.ThreadsFeatureUI_filterFinished()); }\n                public void actionPerformed(ActionEvent e) { setFilter(ThreadsPanel.Filter.FINISHED); }\n\n            };\n            Action aSelected = new AbstractAction() {\n                { putValue(NAME, Bundle.ThreadsFeatureUI_filterSelected()); }\n                public void actionPerformed(ActionEvent e) { setSelectedFilter(); }\n\n            };\n            shFilter = new ActionPopupButton(aAll, aLive, aFinished, aSelected);\n            shFilter.setToolTipText(Bundle.ThreadsFeatureUI_threadsFilter());\n\n            tlLabel = new GrayLabel(Bundle.ThreadsFeatureUI_timeline());\n\n\n            tlZoomInButton = (JComponent)threadsPanel.getZoomIn();\n            tlZoomInButton.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            tlZoomInButton.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n            tlZoomOutButton = (JComponent)threadsPanel.getZoomOut();\n            tlZoomOutButton.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            tlZoomOutButton.putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n            tlFitWidthButton = (JComponent)threadsPanel.getFitWidth();\n            tlFitWidthButton.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            tlFitWidthButton.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n\n            toolbar = ProfilerToolbar.create(true);\n\n//            toolbar.addSpace(2);\n//            toolbar.addSeparator();\n            toolbar.addSpace(5);\n\n            toolbar.add(shLabel);\n            toolbar.addSpace(2);\n            toolbar.add(shFilter);\n\n            toolbar.addSpace(2);\n            toolbar.addSeparator();\n            toolbar.addSpace(5);\n\n            toolbar.add(tlLabel);\n            toolbar.addSpace(2);\n            toolbar.add(tlZoomInButton);\n            toolbar.add(tlZoomOutButton);\n            toolbar.add(tlFitWidthButton);\n            \n            add(toolbar.getComponent(), BorderLayout.NORTH);\n\n            setFilter(ThreadsPanel.Filter.LIVE);\n            \n            // -----------------------------------------------------------------\n\n            add(threadsPanel, BorderLayout.CENTER);\n        }\n        \n        private void setSelectedFilter() {\n            if (threadsPanel.hasSelectedThreads()) {\n                setFilter(ThreadsPanel.Filter.SELECTED);\n            } else {\n                threadsPanel.showSelectedColumn();\n                shFilter.selectAction(threadsPanel.getFilter().ordinal());\n                ProfilerDialogs.displayWarning(Bundle.ThreadsFeatureUI_noThreadsMsg());\n            }\n        }\n\n        private void setFilter(ThreadsPanel.Filter filter) {\n            threadsPanel.setFilter(filter);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/threads/ApplicationThreadsViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.threads;\n\nimport java.lang.management.ThreadMXBean;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ApplicationThreadsViewProvider extends PluggableDataSourceViewProvider<Application> {\n\n    protected boolean supportsViewFor(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE)\n            return getCachedView(application) != null;\n        return resolveThreads(application) != null;\n    }\n\n    protected DataSourceView createView(Application application) {\n        return new ApplicationThreadsView(application);\n    }\n    \n    public Set<Integer> getPluggableLocations(DataSourceView view) {\n        return ALL_LOCATIONS;\n    }\n\n    protected boolean supportsSaveViewFor(Application application, Class<? extends Snapshot> snapshotClass) {\n        return ApplicationSnapshot.class.isAssignableFrom(snapshotClass);\n    }\n\n    protected void saveView(Application application, Snapshot snapshot) {\n        VisualVMThreadsDataManager tmanager = null;\n        ApplicationThreadsView view = (ApplicationThreadsView)getCachedView(application);\n        if (view != null) {\n            tmanager = view.getDataManager();\n        } else {\n            ThreadMXBean tbean = resolveThreads(application);\n            if (tbean != null) {\n                tmanager = new ThreadMXBeanDataManager(tbean);\n                ((ThreadMXBeanDataManager)tmanager).refreshThreadsSync();\n//                try { Thread.sleep(50); } catch (Exception e) {} // Collect some data\n//                ((ThreadMXBeanDataManager)tmanager).refreshThreadsSync();\n            }\n        }\n\n        if (tmanager != null) PersistenceSupport.saveDataManager(tmanager, snapshot.getStorage());\n    }\n\n    static ThreadMXBean resolveThreads(Application application) {\n        JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);\n        if (jmxModel != null && jmxModel.getConnectionState() == JmxModel.ConnectionState.CONNECTED) {\n            if (jmxModel.isTakeThreadDumpSupported()) {\n                JvmMXBeans mxbeans = jmxModel.getJvmMXBeans();\n                return mxbeans == null ? null : mxbeans.getThreadMXBean();\n            }\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/threads/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_Threads=Threads\n\nLBL_Threads_visualization=Threads visualization\n\nLBL_Thread_Dump=Thread Dump\n\nLBL_Timeline=Timeline\n\nLBL_Table=Table\n\nLBL_Details=Details\n\nLBL_Live_threads=Live threads\n\nLBL_Daemon_threads=Daemon threads\n\nDeadlock_Alert_Text=<b>Deadlock detected!</b><br>Take a thread dump to get more info.\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/threads/DeadlockDetector.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.threads;\n\nimport java.lang.management.ThreadMXBean;\nimport java.lang.reflect.UndeclaredThrowableException;\nimport java.util.logging.Logger;\nimport javax.management.ReflectionException;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass DeadlockDetector {\n    private static final Logger LOGGER = Logger.getLogger(DeadlockDetector.class.getName());\n    private static int deadlockNumber = 10;\n    private ThreadMXBean threadBean;\n    private boolean deadlockDetectionDisabled;\n    private boolean findDeadlockedThreadsSupported;\n    private int countDown;\n    \n    DeadlockDetector(ThreadMXBean tb) {\n        threadBean = tb;\n        findDeadlockedThreadsSupported = true;\n    }\n    \n    long[] detectDeadlock() {\n        long threadIds[];\n        \n        if (deadlockDetectionDisabled) {\n            return null;\n        }\n        if (countDown++ % deadlockNumber != 0) {\n            return null;\n        }\n        try {\n            if (findDeadlockedThreadsSupported) {\n                threadIds = threadBean.findDeadlockedThreads();\n            } else {\n                threadIds = threadBean.findMonitorDeadlockedThreads();                \n            }\n        } catch (SecurityException ex) {\n            LOGGER.throwing(ThreadMXBeanDataManager.class.getName(), \"detectDeadlock\", ex); // NOI18N\n            deadlockDetectionDisabled = true;\n            return null;\n        } catch (UnsupportedOperationException ex) {\n            tryJdk15(ex);\n            return null;\n        } catch (UndeclaredThrowableException ex) {\n            Throwable t = ex.getUndeclaredThrowable();\n            if (t instanceof ReflectionException) {\n                ReflectionException re = (ReflectionException) t;\n                if (re.getTargetException() instanceof NoSuchMethodException) {\n                    tryJdk15(ex);\n                }\n            }\n            return null;\n        }\n        if (threadIds != null) { // Deadlock\n            assert threadIds.length>0;\n            // LOGGER.info(\"Deadlock \"+Arrays.toString(threadIds));\n        }\n        return threadIds;\n    }\n\n    private void tryJdk15(Exception ex) {\n        if (findDeadlockedThreadsSupported) {\n            findDeadlockedThreadsSupported = false;\n            countDown--;\n            detectDeadlock();\n        } else {\n            LOGGER.throwing(ThreadMXBeanDataManager.class.getName(), \"detectDeadlock\", ex); // NOI18N\n            deadlockDetectionDisabled = true;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/threads/PersistenceSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.threads;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadData;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class PersistenceSupport {\n\n    private static final String THREADS_DATA_FILE = \"threads.dat\"; // NOI18N\n    private static final String THREADS_SNAPSHOT_HEADER = \"ThreadsDataManagerSnapshot\"; // NOI18N\n    private static final int THREADS_SNAPSHOT_VERSION = 1;\n\n    private static final String PROP_PREFIX = \"ApplicationThreadsModel_\";  // NOI18N\n\n    static final String SNAPSHOT_VERSION = PROP_PREFIX + \"version\"; // NOI18N\n    private static final String SNAPSHOT_VERSION_DIVIDER = \".\"; // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = \"1\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MINOR = \"0\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION = CURRENT_SNAPSHOT_VERSION_MAJOR + SNAPSHOT_VERSION_DIVIDER + CURRENT_SNAPSHOT_VERSION_MINOR;\n\n\n    static boolean supportsStorage(Storage storage) {\n        return storage.getCustomProperty(SNAPSHOT_VERSION) != null;\n    }\n\n    static void saveDataManager(VisualVMThreadsDataManager dm, Storage storage) {\n        if (dm == null) return;\n\n        File dir = storage.getDirectory();\n\n        try (OutputStream os = new FileOutputStream(new File(dir, THREADS_DATA_FILE))) {\n            saveDataManager(dm, os);\n            storage.setCustomProperty(SNAPSHOT_VERSION, CURRENT_SNAPSHOT_VERSION);\n        } catch (Exception e) {\n            // TODO: log it\n        }\n    }\n\n    static VisualVMThreadsDataManager loadDataManager(Storage storage) {\n        File dir = storage.getDirectory();\n\n        try (InputStream is = new FileInputStream(new File(dir, THREADS_DATA_FILE))) {\n            return loadDataManager(is);\n        } catch (Exception e) {\n            // TODO: log it\n            return null;\n        }\n    }\n\n\n    private synchronized static void saveDataManager(VisualVMThreadsDataManager dm, OutputStream os) throws IOException {\n        synchronized(dm) {\n            int tcount = dm.getThreadsCount();\n            try (DataOutputStream dos = new DataOutputStream(os)) {\n\n                dos.writeUTF(THREADS_SNAPSHOT_HEADER); // Snapshot format\n                dos.writeInt(THREADS_SNAPSHOT_VERSION); // Snapshot version\n\n                dos.writeLong(dm.getStartTime()); // Start time\n                dos.writeLong(dm.getEndTime()); // End time\n                dos.writeInt(tcount); // Threads count\n                dos.writeInt(dm.getDaemonThreadCount()); // Daemon threads count\n\n                for (int tidx = 0; tidx < tcount; tidx++) {\n                    ThreadData tdata = dm.getThreadData(tidx);\n                    int scount = tdata.size();\n                    dos.writeUTF(tdata.getName()); // Thread name\n                    dos.writeInt(scount); // Number of thread states\n                    for (int sidx = 0; sidx < scount; sidx++) {\n                        dos.writeLong(tdata.getTimeStampAt(sidx)); // State timestamp\n                        dos.writeByte(tdata.getStateAt(sidx)); // Thread state\n                    }\n                }\n            }\n        }\n    }\n\n    private static VisualVMThreadsDataManager loadDataManager(InputStream is) throws IOException {\n        try (DataInputStream dis = new DataInputStream(is)) {\n\n            if (!THREADS_SNAPSHOT_HEADER.equals(dis.readUTF()))\n                throw new IOException(\"Unknown snapshot format\"); // NOI18N\n            if (THREADS_SNAPSHOT_VERSION != dis.readInt())\n                throw new IOException(\"Unsupported snapshot version\"); // NOI18N\n\n            long stime = dis.readLong(); // Start time\n            long etime = dis.readLong(); // End time\n            int tcount = dis.readInt(); // Threads count\n            int dtcount = dis.readInt(); // Daemon threads count\n            ThreadData[] tdata = new ThreadData[tcount];\n\n            for (int tidx = 0; tidx < tcount; tidx++) {\n                ThreadData td = new ThreadData(dis.readUTF(), \"\"); // NOI18N // Thread name\n                int scount = dis.readInt(); // Number of thread states\n                for (int sidx = 0; sidx < scount; sidx++)\n                    td.add(dis.readLong(), dis.readByte()); // State timestamp, thread state\n                tdata[tidx] = td;\n            }\n\n            return new SavedThreadsDataManager(stime, etime, dtcount, tdata);\n        }\n    }\n\n\n    private static class SavedThreadsDataManager extends VisualVMThreadsDataManager {\n\n        private final long startTime;\n        private final long endTime;\n        private final int daemonThreads;\n        private final ThreadData[] threadData;\n\n        SavedThreadsDataManager(long startTime, long endTime,\n                                       int daemonThreads, ThreadData[] threadData) {\n            this.startTime = startTime;\n            this.endTime = endTime;\n            this.daemonThreads = daemonThreads;\n            this.threadData = threadData;\n        }\n\n        public int getThreadCount() { return getThreadsCount(); }\n        public int getDaemonThreadCount() { return daemonThreads; }\n\n        public long getStartTime() { return startTime; }\n        public long getEndTime() { return endTime; }\n\n        public int getThreadsCount() { return threadData.length; }\n        public String getThreadName(int index) { return threadData[index].getName(); }\n        public String getThreadClassName(int index) { return threadData[index].getClassName(); }\n\n        public ThreadData getThreadData(int index) { return threadData[index]; }\n        void cleanup() {}\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/threads/ThreadMXBeanDataManager.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.threads;\n\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport java.lang.management.ThreadInfo;\nimport java.lang.management.ThreadMXBean;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.logging.Logger;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.views.ApplicationThreadsResponseProvider;\nimport org.graalvm.visualvm.application.views.ApplicationThreadsResponseProvider.ThreadMonitoredDataResponseProvider;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.lib.jfluid.client.MonitoredData;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.MonitoredNumbersResponse;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ThreadMXBeanDataManager extends VisualVMThreadsDataManager {\n\n    private static final long[] dummyLong = new long[0];\n    private static final Logger LOGGER = Logger.getLogger(ThreadMXBeanDataManager.class.getName());\n    static final String DEADLOCK_PROP = \"Deadlock\";   // NOI18N\n    private static ApplicationThreadsResponseProvider appRespProvider = Lookup.getDefault().lookup(ApplicationThreadsResponseProvider.class);\n    \n    private ThreadMXBean threadBean;\n    private Set<Long> threadIdSet = new HashSet<>();\n    private boolean refreshRunning;\n    private DeadlockDetector deadlockDetector;\n    private PropertyChangeSupport changeSupport;\n    private long[] deadlockThreadIds;\n    private ThreadMonitoredDataResponseProvider threadMonProvider;\n    private int threadCount, daemonThreadCount;\n    \n            \n    ThreadMXBeanDataManager(Application app, ThreadMXBean tb) {\n        this(tb);\n        if (appRespProvider != null) {\n            threadMonProvider = appRespProvider.getMonitoredDataResponseProvider(app, tb);\n        }\n    }\n\n    ThreadMXBeanDataManager(ThreadMXBean tb) {\n        threadBean = tb;\n        deadlockDetector = new DeadlockDetector(tb);\n        changeSupport = new PropertyChangeSupport(this);\n    }\n\n    // Non-blocking call for general usage\n    void refreshThreadsAsync() {\n        synchronized (this) {\n            if (refreshRunning) return;\n            refreshRunning = true;\n        }\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                long[] oldDeadlockThreadIds = deadlockThreadIds;\n                \n                refreshThreadsSync();\n                deadlockThreadIds = deadlockDetector.detectDeadlock();\n                if (deadlockThreadIds != null && !Arrays.equals(oldDeadlockThreadIds,deadlockThreadIds)) {\n                    changeSupport.firePropertyChange(DEADLOCK_PROP,oldDeadlockThreadIds,deadlockThreadIds);\n                }\n                synchronized (ThreadMXBeanDataManager.this) {\n                   refreshRunning = false; \n                }\n            }\n        });\n    }\n\n    // Blocking call used to save application snapshot for not opened application\n    void refreshThreadsSync() {\n        try {\n            MonitoredNumbersResponse resp = null;\n            if (threadMonProvider != null) {\n                resp = threadMonProvider.createThreadMonitoredDataResponse();\n            }\n            if (resp == null) {\n                ThreadMonitoredDataResponse tresp = new ThreadMonitoredDataResponse();\n                tresp.fillInThreadData();\n                resp = tresp;\n            }\n            threadCount = threadBean.getThreadCount();\n            daemonThreadCount = threadBean.getDaemonThreadCount();\n            final MonitoredData monitoredData = MonitoredData.getMonitoredData(resp);\n            SwingUtilities.invokeLater(new Runnable() {\n\n                public void run() {\n                    // must run in AWT\n                    processData(monitoredData);\n                }\n            });\n        } catch (Exception ex) {\n            LOGGER.throwing(ThreadMXBeanDataManager.class.getName(), \"refreshThreads\", ex); // NOI18N\n        }\n    }\n\n    int getDaemonThreadCount() {\n        return daemonThreadCount;\n    }\n\n    int getThreadCount() {\n        return threadCount;\n    }\n    \n    void addPropertyChangeListener(PropertyChangeListener l) {\n         changeSupport.addPropertyChangeListener(l);\n    }\n    \n    void removePropertyChangeListener(PropertyChangeListener l) {\n        changeSupport.removePropertyChangeListener(l);\n    }\n    \n    void cleanup() {\n        if (threadMonProvider != null) threadMonProvider.cleanup();\n    }\n\n    class ThreadMonitoredDataResponse extends MonitoredNumbersResponse {\n\n        ThreadMonitoredDataResponse() {\n            super(dummyLong, CommonConstants.SERVER_RUNNING, CommonConstants.SERVER_PROGRESS_INDETERMINATE);\n            setGCstartFinishData(dummyLong, dummyLong);\n        }\n\n        private void fillInThreadData() {\n            long[] currentThreadIds = threadBean.getAllThreadIds();\n            ThreadInfo[] threadInfos = threadBean.getThreadInfo(currentThreadIds, 1);\n            Set<Long> currentIdSet = new HashSet<>(currentThreadIds.length * 4 / 3);\n            int nThreads = 0;\n            long timeStamps[] = {System.currentTimeMillis()};\n            int maxThreads = currentThreadIds.length + threadIdSet.size();\n            int tids[] = new int[maxThreads];\n            byte states[] = new byte[maxThreads];\n\n            int nNewThreads = 0;\n            int newThreadsId[] = new int[currentThreadIds.length];\n            String[] newThreadsNames = new String[currentThreadIds.length];\n            String[] newThreadsClasses = new String[currentThreadIds.length];\n\n            for (int i = 0; i < currentThreadIds.length; i++) {\n                ThreadInfo tinfo = threadInfos[i];\n                long threadId = currentThreadIds[i];\n                Long threadIdLong;\n\n                if (tinfo == null) {\n                    continue;\n                }\n                threadIdLong = Long.valueOf(threadId);\n                currentIdSet.add(threadIdLong);\n                tids[nThreads] = (int) threadId;\n                states[nThreads] = getState(tinfo);\n                nThreads++;\n\n                if (!threadIdSet.remove(threadIdLong)) { // New Thread\n                    newThreadsId[nNewThreads] = (int) threadId;\n                    newThreadsNames[nNewThreads] = tinfo.getThreadName();\n                    newThreadsClasses[nNewThreads] = \"\";\n                    nNewThreads++;\n                }\n            }\n            // set remaining threads as terminated\n            for (Long elem : threadIdSet) {\n                tids[nThreads] = elem.intValue();\n                states[nThreads] = CommonConstants.THREAD_STATUS_ZOMBIE;\n                nThreads++;\n            }\n            threadIdSet = currentIdSet;\n            setDataOnNewThreads(nNewThreads, newThreadsId, newThreadsNames, newThreadsClasses);\n            setDataOnThreads(nThreads, timeStamps.length, tids, timeStamps, states);\n        }\n\n        byte getState(ThreadInfo threadInfo) {\n            Thread.State state = threadInfo.getThreadState();\n            switch (state) {\n                case BLOCKED:\n                    return CommonConstants.THREAD_STATUS_MONITOR;\n                case RUNNABLE:\n                    return CommonConstants.THREAD_STATUS_RUNNING;\n                case TIMED_WAITING:\n                case WAITING:\n                    StackTraceElement[] stack = threadInfo.getStackTrace();\n                    if (stack.length>0) {\n                        StackTraceElement el = stack[0];\n                        if (isSleeping(el)) return CommonConstants.THREAD_STATUS_SLEEPING;\n                        if (isParked(el)) return CommonConstants.THREAD_STATUS_PARK;\n                    }\n                    return CommonConstants.THREAD_STATUS_WAIT;\n                case TERMINATED:\n                case NEW:\n                    return CommonConstants.THREAD_STATUS_ZOMBIE;\n            }\n            return CommonConstants.THREAD_STATUS_UNKNOWN;\n        }\n\n        boolean isSleeping(StackTraceElement element) {\n            return Thread.class.getName().equals(element.getClassName()) &&\n                    \"sleep\".equals(element.getMethodName());    // NOI18N\n        }\n\n        boolean isParked(StackTraceElement element) {\n            String className = element.getClassName();\n\n            if (\"jdk.internal.misc.Unsafe\".equals(className) || \"sun.misc.Unsafe\".equals(className)) { // NOI18N\n                return \"park\".equals(element.getMethodName());          // NOI18N\n            }\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/applicationviews/src/org/graalvm/visualvm/application/views/threads/VisualVMThreadsDataManager.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.application.views.threads;\n\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadsDataManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class VisualVMThreadsDataManager extends ThreadsDataManager {\n\n    abstract int getThreadCount();\n    abstract int getDaemonThreadCount();\n    abstract void cleanup();\n\n}\n"
  },
  {
    "path": "visualvm/appui/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.appui\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.appui.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/appui/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.modules.appui/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/modules/appui/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/appui/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.1\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/appui/Install.class\n"
  },
  {
    "path": "visualvm/appui/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.appui-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/appui/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=a80e1525\nbuild.xml.script.CRC32=0fce0d15\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=a80e1525\nnbproject/build-impl.xml.script.CRC32=37f807f0\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "visualvm/appui/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\njavac.source=1.8\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nmodule.javadoc.packages=org.graalvm.visualvm.modules.appui.*\n\n"
  },
  {
    "path": "visualvm/appui/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.appui</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.common</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.core</code-name-base>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>3.11.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.core.ui</code-name-base>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.10</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.core.windows</code-name-base>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.8.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.autoupdate.services</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.autoupdate.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.53</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.keyring</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.options.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.11.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.43</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.swing.laf.flatlaf</code-name-base>\n                    <run-dependency>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.18</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/appui/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/AboutAction.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.modules.appui;\n\nimport java.awt.Image;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.URL;\nimport java.util.Enumeration;\nimport java.util.HashSet;\nimport java.util.Locale;\nimport java.util.Properties;\nimport java.util.Set;\nimport java.util.StringTokenizer;\nimport java.util.logging.Logger;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport org.graalvm.visualvm.modules.appui.about.AboutDialog;\nimport org.openide.modules.Modules;\nimport org.openide.modules.Places;\nimport org.openide.util.Enumerations;\nimport org.openide.util.NbBundle;\nimport org.openide.util.Utilities;\nimport org.openide.windows.WindowManager;\n\n\npublic final class AboutAction extends AbstractAction {\n    private final static Logger LOGGER = Logger.getLogger(AboutAction.class.getName());\n    \n    private String versionString = \"Dev\"; // Use \"Dev\" for development builds   // NOI18N\n\n\n    public AboutAction() {\n        putValue(Action.NAME, NbBundle.getMessage(AboutAction.class, \"CTL_AboutAction\")); // NOI18N\n        putValue(\"noIconInMenu\", Boolean.TRUE); // NOI18N\n    }\n    \n    public void actionPerformed(final ActionEvent e) {\n        AboutDialog ad = getAboutDialog();\n        if (ad != null) ad.show();\n    }\n    \n    static AboutAction getMenuAction() {\n        if (Utilities.isMac()) {\n            return null;\n        }\n        return new AboutAction();\n    }\n    \n    private AboutDialog getAboutDialog() {\n        if (aboutDialog == null) {\n            try {\n                URL imageURL = getClass().getResource(\"/org/graalvm/visualvm/modules/appui/about/image.png\"); // NOI18N\n                Image splashImage = Toolkit.getDefaultToolkit().createImage(imageURL);\n                aboutDialog = AboutDialog.createInstance(WindowManager.getDefault().getMainWindow(), splashImage);\n                aboutDialog.setCaption(NbBundle.getMessage(AboutAction.class, \"LBL_About_VisualVM\"));   // NOI18N\n                aboutDialog.setBuildID(NbBundle.getMessage(AboutAction.class, \"LBL_Version_Build\", new Object[] {versionString,getBuildNumber()}));\n                aboutDialog.setMessage(NbBundle.getMessage(AboutAction.class, \"MSG_License\") + NbBundle.getMessage(AboutAction.class, \"MSG_License1\"));\n                aboutDialog.setHTMLMessage(NbBundle.getMessage(AboutAction.class, \"MSG_Html_License\") + NbBundle.getMessage(AboutAction.class, \"MSG_Html_License1\"));\n                aboutDialog.setDetails(getDetails());\n                aboutDialog.setLogfile(getLogfile());\n            } catch (Exception e) {\n                LOGGER.throwing(AboutAction.class.getName(), \"getAboutDialog\", e);\n            }\n        }\n        \n        return aboutDialog;\n    }\n    \n    private String getBuildNumber() {\n        if (buildNumber == null) {\n            buildNumber = Modules.getDefault().ownerOf(AboutAction.class).getBuildVersion();\n        }\n        \n        return buildNumber;\n    }\n    \n    private String getLogfile() {\n        String logfilePath = \"var/log/messages.log\"; // NOI18N\n        File logfile = new File(Places.getUserDirectory(), logfilePath);\n        if (logfile.exists() && logfile.isFile() && logfile.canRead()) return logfile.getAbsolutePath();\n        else return null;\n    }\n    \n    private String getDetails() {\n        if (details == null) {\n            StringBuilder sb = new StringBuilder();\n            \n            sb.append(\"<table border=\\\"0\\\">\"); // NOI18N\n            \n            sb.append(\"<tr>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + \"<b>Version: </b>\" + \"</td>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + versionString + \" (Build \" + getBuildNumber() + \"); platform \" + System.getProperty(\"netbeans.buildnumber\") + \"</td>\"); // NOI18N\n            sb.append(\"</tr>\"); // NOI18N\n            \n            sb.append(\"<tr>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + \"<b>System: </b>\" + \"</td>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + getOSInfo() + \"</td>\"); // NOI18N\n            sb.append(\"</tr>\"); // NOI18N\n            \n            sb.append(\"<tr>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + \"<b>Java: </b>\" + \"</td>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + getJavaInfo() + \"</td>\"); // NOI18N\n            sb.append(\"</tr>\"); // NOI18N\n\n            sb.append(\"<tr>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + \"<b>Vendor: </b>\" + \"</td>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + getJavaVendor() + \"</td>\"); // NOI18N\n            sb.append(\"</tr>\"); // NOI18N\n            \n            sb.append(\"<tr>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + \"<b>Environment: </b>\" + \"</td>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + getEnvironment() + \"</td>\"); // NOI18N\n            sb.append(\"</tr>\"); // NOI18N\n            \n            sb.append(\"<tr>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + \"<b>User directory: </b>\" + \"</td>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + getUserDir() + \"</td>\"); // NOI18N\n            sb.append(\"</tr>\"); // NOI18N\n            \n            sb.append(\"<tr>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + \"<b>Cache directory: </b>\" + \"</td>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + Places.getCacheDirectory().getAbsolutePath() + \"</td>\"); // NOI18N\n            sb.append(\"</tr>\"); // NOI18N\n            \n            sb.append(\"<tr>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + \"<b>Clusters: </b>\" + \"</td>\"); // NOI18N\n            sb.append(\"<td valign=\\\"top\\\" nowrap>\" + getIDEInstallValue() + \"</td>\"); // NOI18N\n            sb.append(\"</tr>\"); // NOI18N\n            \n            sb.append(\"</table>\"); // NOI18N\n            \n            details = sb.toString();\n        }\n        \n        return details;\n    }\n    \n    private static String getOSInfo() {\n        Properties systemProperties = System.getProperties();\n        String osName = systemProperties.getProperty(\"os.name\", \"&lt;not available&gt;\"); // NOI18N\n        String osVersion = systemProperties.getProperty(\"os.version\", \"\"); // NOI18N\n        String patchLevel = systemProperties.getProperty(\"sun.os.patch.level\", \"\"); // NOI18N\n        String osArch = systemProperties.getProperty(\"os.arch\", \"&lt;not available&gt;\");   // NOI18N\n        String sunArch = systemProperties.getProperty(\"sun.arch.data.model\", \"?\") + \"bit\";  // NOI18N\n        return osName + \" (\" + osVersion + \") \" + (\"unknown\".equals(patchLevel) ? \"\" : patchLevel) + \", \" + osArch + \" \" + sunArch; // NOI18N\n    }\n    \n    private static String getJavaInfo() {\n        Properties systemProperties = System.getProperties();\n        String javaVersion = systemProperties.getProperty(\"java.version\", \"unknown\");   // NOI18N\n        String vmName = systemProperties.getProperty(\"java.vm.name\", \"&lt;not available&gt;\");  // NOI18N\n        String vmVersion = systemProperties.getProperty(\"java.vm.version\", \"\"); // NOI18N\n        String vmInfo = systemProperties.getProperty(\"java.vm.info\", \"\");   // NOI18N\n        return javaVersion + \"; \" + vmName + \" (\" + vmVersion + \", \" + vmInfo + \")\";\n    }\n\n    private static String getJavaVendor() {\n        Properties systemProperties = System.getProperties();\n        String javaVendor = systemProperties.getProperty(\"java.vendor\", \"unknown\");   // NOI18N\n        String javaVendorUrl = systemProperties.getProperty(\"java.vendor.url\", null);  // NOI18N\n        return javaVendor + (javaVendorUrl == null ? \"\" : \", \" + javaVendorUrl); // NOI18N\n    }\n    \n    private static String getEnvironment() {\n        String branding = NbBundle.getBranding();\n        String encoding = System.getProperty(\"file.encoding\", \"unknown\");   // NOI18N\n        String locale = Locale.getDefault().toString() + (branding == null ? \"\" : (\" (\" + branding + \")\")); // NOI18N\n        return encoding + \"; \" + locale;\n    }\n    \n    private static String getUserDir() {\n        File userdirf = Places.getUserDirectory();\n        String userdir = userdirf != null ? userdirf.getAbsolutePath() : null;\n        return userdir != null ? userdir : \"unknown\";   // NOI18N\n    }\n    \n    private static String getIDEInstallValue() {\n        String nbhome = System.getProperties().getProperty(\"netbeans.home\");    // NOI18N\n        String nbdirs = System.getProperty(\"netbeans.dirs\");    // NOI18N\n        \n        Enumeration<Object> more;\n        if (nbdirs != null) {\n            more = new StringTokenizer(nbdirs, File.pathSeparator);\n        } else {\n            more = Enumerations.empty();\n        }\n            \n        Enumeration<Object> all = Enumerations.concat(Enumerations.singleton(nbhome), more);\n        \n        Set<File> files = new HashSet<>();\n        StringBuilder sb = new StringBuilder ();\n        String prefix = \"\";\n        while (all.hasMoreElements ()) {\n            String s = (String)all.nextElement ();\n            if (s == null) {\n                continue;\n            }\n            File f = (new File(s));\n            if (files.add (f)) {\n                // new file\n                sb.append (prefix);\n                try {\n                    sb.append(f.getCanonicalPath());\n                } catch (IOException e) {\n                    sb.append(f.getAbsolutePath());\n                }\n                prefix = \"\\n\";  // NOI18N\n            }\n        }\n        \n        return sb.toString ();\n    }\n    \n    \n    private AboutDialog aboutDialog;\n    private String buildNumber;\n    private String details;\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nCTL_AboutAction=&About\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Long-Description=\\\n    Customizes NetBeans platform/application UI using the layer.xml to show only items applicable for VisualVM.\nOpenIDE-Module-Name=VisualVM-AppUI\nOpenIDE-Module-Short-Description=UI customizations for VisualVM\n\nLBL_About_VisualVM=About VisualVM\n\nLBL_Version_Build=Version: {0} (Build {1})\n\nMSG_License=<b>VisualVM</b> has been licensed under the GNU General Public License (GPL) Version 2 with Classpath Exception. \n\nMSG_License1=Visit <nobr>https://visualvm.github.io</nobr> for more information. Built on <nobr>NetBeans Platform</nobr>.\n\nMSG_Html_License=<b>VisualVM</b> has been licensed under the GNU General Public License (GPL) Version 2 with Classpath Exception. \n\nMSG_Html_License1=Visit <a href=\"https://visualvm.github.io\"><nobr>https://visualvm.github.io</nobr></a> for more information. Built on <nobr>NetBeans Platform</nobr>.\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/Install.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui;\n\nimport org.graalvm.visualvm.modules.appui.proxysettings.ProxySettingsHack;\nimport org.openide.modules.ModuleInstall;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n// Class implementing logic on VisualVM module install\npublic class Install extends ModuleInstall {\n\n    public void restored() {\n        // #582, do not make undocked TopComponents semi-transparent\n        NbPreferences.root().node(\"org/netbeans/core/windows\"). // NOI18N\n                putBoolean(\"transparency.floating\", false); // NOI18N\n        \n        // Initialize opening warning dialog on Proxy Settings\n        ProxySettingsHack.hackProxySettings();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/Standard.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\nCopyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n\n<!DOCTYPE Configuration PUBLIC \"-//NetBeans IDE//DTD toolbar//EN\" \"http://www.netbeans.org/dtds/toolbar.dtd\">\n\n<Configuration>\n  <Row>\n    <Toolbar name=\"File\" />\n    <Toolbar name=\"Clipboard\" visible=\"false\"/>\n    <Toolbar name=\"UndoRedo\" />\n    <Toolbar name=\"Memory\" visible=\"false\"/>\n  </Row>\n\n</Configuration>\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/WindowManager.wswmgr",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!DOCTYPE windowmanager PUBLIC\n          \"-//NetBeans//DTD Window Manager Properties 2.1//EN\"\n          \"http://www.netbeans.org/dtds/windowmanager-properties2_1.dtd\">\n\n<windowmanager version=\"2.1\">\n    <main-window> \n        <joined-properties centered-horizontally=\"true\" centered-vertically=\"true\"\n                           width=\"900\" height=\"590\" />\n        <separated-properties centered-horizontally=\"true\" centered-vertically=\"true\"\n                           width=\"900\" height=\"590\" />\n    </main-window>\n    <editor-area state=\"joined\">\n        <constraints>\n            <path orientation=\"horizontal\" number=\"60\" weight=\"0.7\" />\n            <path orientation=\"vertical\" number=\"40\" weight=\"0.7\" />\n            <path orientation=\"horizontal\" number=\"40\" weight=\"0.7\" />\n        </constraints>\n    </editor-area>\n    <active-mode name=\"explorer\" />\n    <maximized-mode name=\"\" />\n    <toolbar configuration=\"Standard\" preferred-icon-size=\"16\" />\n</windowmanager>\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/about/AboutDialog.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.about;\n\nimport java.awt.BorderLayout;\nimport java.awt.Frame;\nimport java.awt.Image;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.WindowAdapter;\nimport java.awt.event.WindowEvent;\nimport java.awt.image.BufferedImage;\nimport javax.swing.AbstractAction;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JDialog;\nimport javax.swing.KeyStroke;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class AboutDialog {\n\n\n    // --- Public API ----------------------------------------------------------\n\n    public synchronized static AboutDialog createInstance(Frame parentFrame, Image aboutImage) {\n        if (instance != null) instance.close();\n        instance = new AboutDialog(parentFrame, aboutImage);\n        instance.initComponents();\n        return instance;\n    }\n    \n    public synchronized static AboutDialog getInstance() {\n        if (instance == null) {\n            instance = new AboutDialog();\n            instance.initComponents();\n        }\n        return instance;\n    }\n    \n    public void setCaption(String caption) {\n        dialog.setTitle(caption);\n    }\n    \n    public String getCaption() {\n        return dialog.getTitle();\n    }\n    \n    public void setMessage(String message) {\n        this.message = message;\n    }\n    \n    public String getMessage() {\n        return message;\n    }\n    \n    public void setHTMLMessage(String htmlMessage) {\n        this.htmlMessage = htmlMessage;\n    }\n    \n    public String getHTMLMessage() {\n        return htmlMessage;\n    }\n    \n    public void setBuildID(String buildID) {\n        this.buildID = buildID;\n    }\n    \n    public String getBuildID() {\n        return buildID;\n    }\n    \n    public void setDetails(String details) {\n        this.details = details;\n    }\n    \n    public String getDetails() {\n        return details;\n    }\n    \n    public void setLogfile(String logfile) {\n        this.logfile = logfile;\n    }\n    \n    public String getLogfile() {\n        return logfile;\n    }\n    \n    public void show() {\n        aboutDialogPanel.updateAppearance();\n        aboutDialogControls.updateAppearance();\n        dialog.pack();\n        aboutDialogControls.getDefaultButton().requestFocusInWindow();\n        dialog.setLocationRelativeTo(parentFrame);\n        dialog.setVisible(true);\n    }\n    \n    public void close() {\n        dialog.setVisible(false);\n        dialog.dispose();\n    }\n    \n    \n    // --- Internal API --------------------------------------------------------    \n    \n    Image getAboutImage() {\n        return aboutImage;\n    }\n    \n    void setDefaultButton(JButton button) {\n        dialog.getRootPane().setDefaultButton(button);\n    }\n    \n    JDialog getDialog() {\n        return dialog;\n    }\n    \n    \n    // --- Private implementation ----------------------------------------------\n    \n    private AboutDialog() {\n        this(null, new BufferedImage(400, 300, BufferedImage.TYPE_INT_RGB));\n    }\n    \n    private AboutDialog(Frame parentFrame, Image aboutImage) {\n        this.parentFrame = parentFrame;\n        this.aboutImage = aboutImage;\n    }\n    \n    private void initComponents() {\n        dialog = new JDialog(parentFrame, NbBundle.getMessage(AboutDialog.class, \"LBL_About\"), true);   // NOI18N\n        dialog.addWindowListener(new WindowAdapter() {\n            public void windowClosed(WindowEvent e) { cleanup(); }\n        });\n        \n        JComponent contentPane = (JComponent)dialog.getContentPane();\n        contentPane.setLayout(new BorderLayout());\n        contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)\n                 .put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), \"CLOSE_ACTION\"); // NOI18N\n        contentPane.getActionMap().put(\"CLOSE_ACTION\", new AbstractAction() { // NOI18N\n                public void actionPerformed(ActionEvent e) { close(); }});\n        \n        aboutDialogPanel = new AboutDialogPanel();\n        aboutDialogControls = new AboutDialogControls();\n        \n        contentPane.add(aboutDialogPanel, BorderLayout.CENTER);\n        contentPane.add(aboutDialogControls, BorderLayout.SOUTH);\n        \n        dialog.getRootPane().setDefaultButton(aboutDialogControls.getDefaultButton());\n        dialog.setResizable(false);\n        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);\n    }\n    \n    private void cleanup() {\n    }\n    \n    private static AboutDialog instance;\n    \n    private AboutDialogPanel aboutDialogPanel;\n    private AboutDialogControls aboutDialogControls;\n    \n    private JDialog dialog;\n    \n    private String buildID;\n    private String message;\n    private String htmlMessage;\n    private String details;\n    private String logfile;\n    private Frame parentFrame;\n    private Image aboutImage;\n    \n    \n    // --- main method for testing purposes ------------------------------------\n\n//    public static void main(String[] args) {\n//        try {\n//            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());\n//        } catch (Exception e) {}\n//        \n//        AboutDialog aboutDialog = AboutDialog.getInstance();\n//        \n//        aboutDialog.setCaption(\"About VisualVM\");\n//        aboutDialog.setBuildID(\"Version: Dev (Build xxx)\");\n//        aboutDialog.setMessage(\"<b>VisualVM for JDK 6.0</b> has been licensed under the GNU General Public License (GPL) Version 2. It is built on NetBeans Platform. For more information, please visit https://visualvm.github.io.\");\n//        aboutDialog.setHTMLMessage(\"<b>VisualVM for JDK 6.0</b> has been licensed under the GNU General Public License (GPL) Version 2. It is built on NetBeans Platform. For more information, please visit <a href=\\\"https://visualvm.github.io\\\">https://visualvm.github.io</a>.\");\n//        aboutDialog.setDetails(\"<b>Version: </b> Dev\");\n//        aboutDialog.setLogfile(\"E:\\\\Dev\\\\userdirdev\\\\var\\\\log\\\\messages.log\");\n//        \n//        aboutDialog.show();\n//    }\n    \n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/about/AboutDialogControls.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.about;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridLayout;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.File;\nimport java.io.RandomAccessFile;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JOptionPane;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.ui.DesktopUtils;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class AboutDialogControls extends JPanel {\n    private final static Logger LOGGER = Logger.getLogger(AboutDialogControls.class.getName());\n\n    // --- Internal API --------------------------------------------------------\n\n    AboutDialogControls() {\n        initComponents();\n        \n        lastLogfileSave = System.getProperty(\"user.home\"); // NOI18N\n        if (!new File(lastLogfileSave).isDirectory()) {\n            lastLogfileSave = System.getProperty(\"java.io.tmpdir\"); // NOI18N\n            if (!new File(lastLogfileSave).isDirectory()) lastLogfileSave = null;\n        }\n        if (lastLogfileSave != null) lastLogfileSave = lastLogfileSave +\n                                     File.separator + \"logfile.txt\"; // NOI18N\n    }\n\n    JButton getDefaultButton() {\n        return closeButton;\n    }\n\n    void updateAppearance() {\n        int buttonsCount = 1; // Close button always present\n        \n        String buildID = AboutDialog.getInstance().getBuildID();\n        String details = AboutDialog.getInstance().getDetails();\n        String logfile = AboutDialog.getInstance().getLogfile();\n        \n        buildIDLabel.setVisible(buildID != null);\n        if (buildID != null) buildIDLabel.setText(buildID);\n        \n        detailsButton.setVisible(details != null);\n        if (details != null) buttonsCount++;\n        \n        logfileButton.setVisible(logfile != null);\n        if (logfile != null) buttonsCount++;\n        \n        buttonsContainer.removeAll();\n        buttonsContainer.setLayout(new GridLayout(1, buttonsCount, 6, 0));\n        if (details != null) buttonsContainer.add(detailsButton);\n        if (logfile != null) buttonsContainer.add(logfileButton);\n        buttonsContainer.add(closeButton);\n    }\n    \n    \n    // --- Private implementation ----------------------------------------------\n    \n    private void initComponents() {\n        setLayout(new BorderLayout());\n        \n        buildIDLabel = new JLabel();\n        buildIDLabel.setFont(buildIDLabel.getFont().deriveFont(Font.BOLD));\n        buildIDLabel.setEnabled(false);\n        \n        detailsButton = new JButton();\n        Mnemonics.setLocalizedText(detailsButton, NbBundle.getMessage(AboutDialogControls.class, \"LBL_Details\")); // NOI18N\n        detailsButton.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(AboutDialogControls.class, \"DESCR_Details\")); // NOI18N\n        detailsButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                showDetails();\n            }\n        });\n        \n        logfileButton = new JButton();\n        Mnemonics.setLocalizedText(logfileButton, NbBundle.getMessage(AboutDialogControls.class, \"LBL_Logfile\")); // NOI18N\n        logfileButton.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(AboutDialogControls.class, \"DESCR_Logfile\")); // NOI18N\n        logfileButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                showLogfile();\n            }\n        });\n        \n        closeButton = new JButton();\n        Mnemonics.setLocalizedText(closeButton, NbBundle.getMessage(AboutDialogControls.class, \"LBL_Close\")); // NOI18N\n        closeButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        AboutDialog.getInstance().close();\n                    }\n                });\n            }\n        });\n        \n        buttonsContainer = new JPanel(new GridLayout(1, 3, 6, 0));\n        buttonsContainer.add(detailsButton);\n        buttonsContainer.add(logfileButton);\n        buttonsContainer.add(closeButton);\n        \n        setBorder(BorderFactory.createEmptyBorder(10, 10, 7, 10));\n        add(buildIDLabel, BorderLayout.WEST);\n        add(buttonsContainer, BorderLayout.EAST);\n    }\n    \n    private void showDetails() {\n        final TextBrowser tb = TextBrowser.getInstance();\n        JButton helperButton = new JButton() {\n            protected void fireActionPerformed(ActionEvent event) {\n                tb.copyAllHtmlToClipboard();\n                JOptionPane.showMessageDialog(AboutDialog.getInstance().getDialog(),\n                        NbBundle.getMessage(AboutDialogControls.class, \"MSG_Copy_Clipboard\"), // NOI18N\n                        NbBundle.getMessage(AboutDialogControls.class, \"CAPTION_Copy_Clipboard\"), // NOI18N\n                        JOptionPane.INFORMATION_MESSAGE);\n            }\n        };\n        Mnemonics.setLocalizedText(helperButton, NbBundle.getMessage(AboutDialogControls.class, \"BTN_Copy_Clipboard\")); // NOI18N\n        tb.setCaption(NbBundle.getMessage(AboutDialogControls.class, \"TITLE_Details\"));    // NOI18N\n        tb.setPreferredBrowserSize(new Dimension(450, 250));\n        tb.setHelperButton(helperButton);\n        tb.showHTMLText(AboutDialog.getInstance().getDetails());\n    }\n    \n    private void showLogfile() {\n        Runnable logfileDisplayer = new Runnable() {\n            public void run() {\n                logfileButton.setEnabled(false);\n                \n                File logfile = new File(AboutDialog.getInstance().getLogfile());\n        \n                try {\n                    if (!logfile.exists() || !logfile.isFile() || !logfile.canRead()) {\n                        JOptionPane.showMessageDialog(AboutDialog.getInstance().getDialog(), \n                                NbBundle.getMessage(AboutDialogControls.class, \"LBL_Cannot_open_the_logfile\", logfile.getAbsolutePath()),   // NOI18N\n                                NbBundle.getMessage(AboutDialogControls.class, \"LBL_Error\"),    // NOI18N\n                                JOptionPane.ERROR_MESSAGE);\n                        return;\n                    }\n\n                    TextBrowser.getInstance().setCaption(NbBundle.getMessage(AboutDialogControls.class, \"LBL_Logfile_Viewer_\", logfile.getAbsolutePath())); // NOI18N\n                    if (DesktopUtils.isOpenAvailable()) {\n                        try {\n                            DesktopUtils.open(logfile);\n                        } catch (Exception ex) {\n                            showLogfileInBrowser(logfile);\n                            LOGGER.throwing(AboutDialogControls.class.getName(), \"showLogFile\", ex);    // NOI18N\n                        }\n                    } else {\n                        showLogfileInBrowser(logfile);\n                    }\n                } catch (Exception e) {\n                    LOGGER.throwing(AboutDialogControls.class.getName(), \"showLogFile\", e); // NOI18N\n                    JOptionPane.showMessageDialog(AboutDialog.getInstance().getDialog(), \n                            NbBundle.getMessage(AboutDialogControls.class, \"LBL_Cannot_open_the_logfile\", logfile.getAbsolutePath()),   // NOI18N\n                            NbBundle.getMessage(AboutDialogControls.class, \"LBL_Error\"),    // NOI18N\n                            JOptionPane.ERROR_MESSAGE);\n                } finally {\n                    logfileButton.setEnabled(true);\n                }\n            }\n        };\n\n        new Thread(logfileDisplayer).start();\n    }\n    \n    private void showLogfileInBrowser(final File logfile) throws Exception {\n        try (RandomAccessFile raf = new RandomAccessFile(logfile, \"r\")) { // NOI18N\n            byte[] buffer = new byte[(int)raf.length()];\n            raf.readFully(buffer);\n            final String logfileContents = new String(buffer);\n            SwingUtilities.invokeAndWait(new Runnable() {\n               public void run() {\n                   String string = logfileContents;\n                   if (string.isEmpty()) string = NbBundle.getMessage(AboutDialogControls.class, \"MSG_Logfile_notready\"); // NOI18N\n                   final TextBrowser tb = TextBrowser.getInstance();\n                   JButton helperButton = new JButton() {\n                       protected void fireActionPerformed(ActionEvent event) {\n                            saveFileAs(logfile);\n                        }\n                   };\n                   Mnemonics.setLocalizedText(helperButton, NbBundle.getMessage(AboutDialogControls.class, \"BTN_Save_file\")); // NOI18N\n                   helperButton.setEnabled(!logfileContents.isEmpty());\n                   tb.setPreferredBrowserSize(new Dimension(700, 550));\n                   tb.setHelperButton(helperButton);\n                   tb.showCodeText(string);\n               } \n            });\n        }\n    }\n    \n    private void saveFileAs(final File file) {\n        JFileChooser chooser = new JFileChooser();\n        chooser.setDialogTitle(NbBundle.getMessage(AboutDialogControls.class, \"CAPTION_Save_logfile\")); // NOI18N\n        chooser.setSelectedFile(new File(lastLogfileSave));\n        if (chooser.showSaveDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) {\n            final File copy = chooser.getSelectedFile();\n//            if (copy.isFile()) // TODO: show a confirmation dialog for already existing file\n            lastLogfileSave = copy.getAbsolutePath();\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    ProgressHandle pHandle = null;\n                    try {\n                        pHandle = ProgressHandle.createHandle(\n                                NbBundle.getMessage(AboutDialogControls.class,\n                                \"MSG_Saving_logfile\", file.getName()));  // NOI18N\n                        pHandle.setInitialDelay(0);\n                        pHandle.start();\n                        if (!Utils.copyFile(file, copy)) JOptionPane.showMessageDialog(AboutDialog.getInstance().getDialog(), \n                            NbBundle.getMessage(AboutDialogControls.class, \"MSG_Save_logfile_failed\"),   // NOI18N\n                            NbBundle.getMessage(AboutDialogControls.class, \"CAPTION_Save_logfile_failed\"),    // NOI18N\n                            JOptionPane.ERROR_MESSAGE);\n                    } finally {\n                        final ProgressHandle pHandleF = pHandle;\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() { if (pHandleF != null) pHandleF.finish(); }\n                        });\n                    }\n                }\n            });\n        }\n    }\n    \n    \n    private JLabel buildIDLabel;\n    private JButton closeButton;\n    private JButton detailsButton;\n    private JButton logfileButton;\n    private JPanel buttonsContainer;\n    \n    private String lastLogfileSave;\n\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/about/AboutDialogPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.modules.appui.about;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Point;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.net.URL;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.text.Caret;\nimport org.graalvm.visualvm.core.ui.DesktopUtils;\nimport org.graalvm.visualvm.lib.ui.components.ImagePanel;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport org.graalvm.visualvm.uisupport.SeparatorLine;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class AboutDialogPanel extends JPanel {\n    private final static Logger LOGGER = Logger.getLogger(AboutDialogPanel.class.getName());\n\n    // --- Internal API --------------------------------------------------------\n\n    AboutDialogPanel() {\n        initComponents();\n\n        final Runnable repainter = new Runnable() {\n            public void run() { AboutDialogPanel.this.repaint(); }\n        };\n        \n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && isShowing()) {\n                    SwingUtilities.invokeLater(repainter);\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { SwingUtilities.invokeLater(repainter); }\n                    });\n                }\n            }\n        });\n    }\n    \n    void updateAppearance() {\n        String message = AboutDialog.getInstance().getMessage();\n        String htmlMessage = AboutDialog.getInstance().getHTMLMessage();\n                \n        licenseArea.setVisible(message != null);\n        if (message != null) {\n            if (htmlMessage != null && DesktopUtils.isBrowseAvailable()) {\n                licenseArea.setText(htmlMessage);\n            } else {\n                licenseArea.setText(message);\n            }\n        }\n    }\n    \n    \n    // --- Private implementation ----------------------------------------------\n\n    private void initComponents() {\n        JPanel splashImageContainer = new ImagePanel(AboutDialog.getInstance().getAboutImage());\n        \n        SeparatorLine separator = new SeparatorLine();\n\n        licenseArea = new HTMLTextArea() {\n            protected void showURL(URL url) {\n                if (DesktopUtils.isBrowseAvailable()) {\n                    try {\n                        DesktopUtils.browse(url.toURI());\n                    } catch (Exception e) {\n                        LOGGER.throwing(AboutDialogPanel.class.getName(), \"initComponents\", e); // NOI18N\n                    }\n                }\n            }\n        };\n        licenseArea.setOpaque(true);\n        licenseArea.setForeground(Color.BLACK);\n        licenseArea.setBorder(BorderFactory.createEmptyBorder(10, 22, 10, 22));\n        licenseArea.setCaret(new NullCaret());\n        licenseArea.setShowPopup(false);\n        licenseArea.setFocusable(false);\n\n        splashImageContainer.setLayout(new BorderLayout());\n\n        if (UIManager.getLookAndFeel().getID().equals(\"Nimbus\")) { // NOI18N\n            // Nimbus LaF doesn't respect setOpaque(false), this is a workaround.\n            licenseArea.setBackground(new Color(0, 0, 0, 0));\n            JPanel transparentPanel = new JPanel(new BorderLayout()) {\n                public void paint(Graphics g) {\n                    g.setColor(getBackground());\n                    g.fillRect(0, 0, getWidth(), getHeight());\n                    paintChildren(g);\n                }\n            };\n            transparentPanel.setOpaque(true);\n            transparentPanel.setBackground(new Color(255, 255, 255, 100));\n            transparentPanel.add(licenseArea, BorderLayout.CENTER);\n            splashImageContainer.add(transparentPanel, BorderLayout.SOUTH);\n        } else {\n            licenseArea.setBackground(new Color(255, 255, 255, 100));\n            splashImageContainer.add(licenseArea, BorderLayout.SOUTH);\n        }\n\n        setLayout(new BorderLayout());\n        add(splashImageContainer, BorderLayout.CENTER);\n        add(separator, BorderLayout.SOUTH);\n    }\n    \n    private HTMLTextArea licenseArea;\n\n    private static final class NullCaret implements Caret {\n        public void install(javax.swing.text.JTextComponent c) {}\n        public void deinstall(javax.swing.text.JTextComponent c) {}\n        public void paint(Graphics g) {}\n        public void addChangeListener(ChangeListener l) {}\n        public void removeChangeListener(ChangeListener l) {}\n        public boolean isVisible() { return false; }\n        public void setVisible(boolean v) {}\n        public boolean isSelectionVisible() { return false; }\n        public void setSelectionVisible(boolean v) {}\n        public void setMagicCaretPosition(Point p) {}\n        public Point getMagicCaretPosition() { return new Point(0, 0); }\n        public void setBlinkRate(int rate) {}\n        public int getBlinkRate() { return 0; }\n        public int getDot() { return 0; }\n        public int getMark() { return 0; }\n        public void setDot(int dot) {}\n        public void moveDot(int dot) {}\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/about/Bundle.properties",
    "content": "# Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nTextViewerComponent_CutString=Cut\nTextViewerComponent_CopyString=Copy\nTextViewerComponent_PasteString=Paste\nTextViewerComponent_DeleteString=Delete\nTextViewerComponent_SelectAllString=Select All\nLBL_About=About\n\nLBL_Details=&Details\n\nTITLE_Details=Details\n\nDESCR_Details=VisualVM runtime details\n\nLBL_Logfile=&Logfile\n\nDESCR_Logfile=Opens VisualVM logfile viewer\n\nLBL_Close=&Close\n\nLBL_Cannot_open_the_logfile=Cannot open the logfile {0}\n\nLBL_Error=Error\n\nLBL_Logfile_Viewer_=Logfile Viewer ({0})\n\nBTN_Copy_Clipboard=C&opy to Clipboard\n\nCAPTION_Copy_Clipboard=Copy To Clipboard\n\nMSG_Copy_Clipboard=<html>Details copied to the clipboard.</html>\n\nBTN_Save_file=&Save to File\n\nCAPTION_Save_logfile=Save Logfile As\n\nMSG_Saving_logfile=Saving logfile to {0}\n\nCAPTION_Save_logfile_failed=Save Logfile Failed\n\nMSG_Save_logfile_failed=Saving the logfile to the selected destination failed.\n\nMSG_Logfile_notready=Logfile is not ready yet.\\nPlease close the logfile viewer and open it again after a while.\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/about/TextBrowser.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.about;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.WindowAdapter;\nimport java.awt.event.WindowEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JDialog;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.JScrollPane;\nimport javax.swing.KeyStroke;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport org.graalvm.visualvm.uisupport.SeparatorLine;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class TextBrowser {\n\n    private boolean copyingAllHtmlToClipboard = false;\n\n    // --- Internal API --------------------------------------------------------\n\n    synchronized static TextBrowser getInstance() {\n        if (instance == null) {\n            instance = new TextBrowser();\n            instance.initComponents();\n        }\n        return instance;\n    }\n    \n    void setCaption(String caption) {\n        dialog.setTitle(caption);\n    }\n    \n    void setPreferredBrowserSize(Dimension preferredSize) {\n        this.preferredSize = preferredSize;\n    }\n    \n    void showCodeText(String text) {\n        textDisplayer.setText(text);\n        displayerScrollPane.setViewportView(textDisplayer);\n        try { textDisplayer.setCaretPosition(0); } catch (Exception e) {}\n        displayerScrollPane.setPreferredSize(preferredSize);\n        dialog.pack();\n        closeButton.requestFocusInWindow();\n        dialog.setLocationRelativeTo(null);\n        dialog.setResizable(true);\n        dialog.setVisible(true);\n    }\n    \n    void showHTMLText(String text) {\n        htmlTextDisplayer.setText(text);\n        displayerScrollPane.setViewportView(htmlTextDisplayer);\n        try { htmlTextDisplayer.setCaretPosition(0); } catch (Exception e) {}\n        Dimension htmlSize = htmlTextDisplayer.getPreferredSize();\n        htmlSize.width = Math.min(htmlSize.width, 700);\n        htmlSize.height = Math.min(htmlSize.height, 500);\n        displayerScrollPane.setPreferredSize(htmlSize);\n        dialog.pack();\n        closeButton.requestFocusInWindow();\n        dialog.setLocationRelativeTo(null);\n        dialog.setResizable(false);\n        dialog.setVisible(true);\n    }\n    \n    void setHelperButton(JButton helperButton) {\n        if (this.helperButton != null && helperButton == null)\n            buttonsContainer.remove(this.helperButton);\n        else if (this.helperButton == null && helperButton != null)\n            buttonsContainer.add(helperButton, BorderLayout.WEST);\n        this.helperButton = helperButton;\n    }\n    \n    void close() {\n        dialog.setVisible(false);\n        dialog.dispose();\n    }\n    \n    void copyAllHtmlToClipboard() {\n        if (!htmlTextDisplayer.getText().isEmpty()) {\n            copyingAllHtmlToClipboard = true;\n            try { htmlTextDisplayer.copy(); }\n            finally { copyingAllHtmlToClipboard = false; }\n        }\n    }\n    \n    \n    // --- Private implementation ----------------------------------------------\n    \n    private TextBrowser() {}\n    \n    private void initComponents() {\n        dialog = new JDialog(AboutDialog.getInstance().getDialog(), \"\", true); // NOI18N\n        dialog.addWindowListener(new WindowAdapter() {\n            public void windowClosed(WindowEvent e) { cleanup(); }\n        });\n\n        contentPane = (JComponent)dialog.getContentPane();\n        contentPane.setLayout(new BorderLayout());\n        contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)\n                 .put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), \"CLOSE_ACTION\"); // NOI18N\n        contentPane.getActionMap().put(\"CLOSE_ACTION\", new AbstractAction() { // NOI18N\n                public void actionPerformed(ActionEvent e) { close(); }});\n        \n        textDisplayer = new TextViewerComponent();\n        htmlTextDisplayer = new HTMLTextArea() {\n            public int getSelectionStart() {\n                if (copyingAllHtmlToClipboard) return 0;\n                else return super.getSelectionStart();\n            }\n            public int getSelectionEnd() {\n                if (copyingAllHtmlToClipboard) return getText().length();\n                else return super.getSelectionEnd();\n            }\n        };\n        displayerScrollPane = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n        displayerScrollPane.setBorder(BorderFactory.createEmptyBorder());\n        displayerScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());\n        \n        textDisplayer.setForeground(htmlTextDisplayer.getForeground());\n        textDisplayer.setBackground(htmlTextDisplayer.getBackground());\n        textDisplayer.setSelectionColor(htmlTextDisplayer.getSelectionColor());\n        textDisplayer.setSelectedTextColor(htmlTextDisplayer.getSelectedTextColor());\n        \n        closeButton = new JButton(); // NOI18N\n        Mnemonics.setLocalizedText(closeButton, NbBundle.getMessage(AboutDialogControls.class, \"LBL_Close\")); // NOI18N\n        closeButton.setDefaultCapable(true);\n        closeButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(TextBrowser.this::close);\n            }\n        });\n        \n        buttonsContainer = new JPanel(new BorderLayout());\n        buttonsContainer.setBorder(BorderFactory.createEmptyBorder(10, 10, 6, 10));\n        buttonsContainer.add(closeButton, BorderLayout.EAST);\n\n        JPanel bottomPanel = new JPanel(new BorderLayout());\n        final SeparatorLine separator = new SeparatorLine();\n        bottomPanel.add(separator, BorderLayout.NORTH);\n        bottomPanel.add(buttonsContainer, BorderLayout.CENTER);\n\n        final JScrollBar horizontalScroll = displayerScrollPane.getHorizontalScrollBar();\n        if (horizontalScroll != null) horizontalScroll.addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    separator.setVisible(!horizontalScroll.isShowing());\n                }\n            }\n        });\n        \n        contentPane.add(displayerScrollPane, BorderLayout.CENTER);\n        contentPane.add(bottomPanel, BorderLayout.SOUTH);\n        \n        dialog.getRootPane().setDefaultButton(closeButton);\n        dialog.setResizable(true);\n        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);\n    }\n    \n    private void cleanup() {\n        setHelperButton(null);\n        displayerScrollPane.getViewport().removeAll();\n        textDisplayer.setText(\"\"); // NOI18N\n        htmlTextDisplayer.setText(\"\"); // NOI18N\n    }\n    \n    private static TextBrowser instance;\n    \n    private JDialog dialog;\n    private JComponent contentPane;\n    private JPanel buttonsContainer;\n    private JButton closeButton;\n    private JButton helperButton;\n    private TextViewerComponent textDisplayer;\n    private HTMLTextArea htmlTextDisplayer;\n    private JScrollPane displayerScrollPane;\n    private Dimension preferredSize = new Dimension(400, 300);\n\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/about/TextViewerComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.about;\n\nimport java.awt.Font;\nimport java.awt.Toolkit;\nimport java.awt.datatransfer.DataFlavor;\nimport java.awt.datatransfer.Transferable;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport java.util.ResourceBundle;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JTextArea;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.uisupport.UISupport;\n\n\n/**\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic class TextViewerComponent extends JTextArea implements MouseListener {\n\n    /** Private Writer that extracts correctly formatted string from HTMLDocument */\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.modules.appui.about.Bundle\"); // NOI18N\n    private static final String CUT_STRING = messages.getString(\"TextViewerComponent_CutString\"); // NOI18N\n    private static final String COPY_STRING = messages.getString(\"TextViewerComponent_CopyString\"); // NOI18N\n    private static final String PASTE_STRING = messages.getString(\"TextViewerComponent_PasteString\"); // NOI18N\n    private static final String DELETE_STRING = messages.getString(\"TextViewerComponent_DeleteString\"); // NOI18N\n    private static final String SELECT_ALL_STRING = messages.getString(\"TextViewerComponent_SelectAllString\"); // NOI18N\n                                                                                                        // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ActionListener popupListener;\n    private JMenuItem itemCopy;\n    private JMenuItem itemCut;\n    private JMenuItem itemDelete;\n    private JMenuItem itemPaste;\n    private JMenuItem itemSelectAll;\n\n    // --- Popup menu support ----------------------------------------------------\n    private JPopupMenu popupMenu;\n    private boolean showPopup = true;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public TextViewerComponent() {\n        setEditable(false);\n        setOpaque(true);\n        setAutoscrolls(true);\n        setFont(new Font(Font.MONOSPACED, Font.PLAIN, UIManager.getFont(\"Label.font\").getSize())); // NOI18N\n        setBackground(UISupport.getDefaultBackground());\n        addMouseListener(this);\n    }\n\n    public TextViewerComponent(String text) {\n        this();\n        setText(text);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setShowPopup(boolean showPopup) {\n        this.showPopup = showPopup;\n    }\n\n    public boolean getShowPopup() {\n        return showPopup;\n    }\n\n    public void deleteSelection() {\n        try {\n            getDocument().remove(getSelectionStart(), getSelectionEnd() - getSelectionStart());\n        } catch (Exception ex) {\n        }\n    }\n\n    private void showPopupMenu(MouseEvent e) {\n        if (isEnabled() && isFocusable() && showPopup) {\n            JPopupMenu popup = getPopupMenu();\n\n            if (popup != null) {\n                updatePopupMenu();\n\n                if (!hasFocus()) {\n                    requestFocus(); // required for Select All functionality\n                }\n\n                popup.show(this, e.getX(), e.getY());\n            }\n        }\n    }\n\n    public void mouseClicked(MouseEvent e) {\n    }\n\n    public void mouseEntered(MouseEvent e) {\n    }\n\n    public void mouseExited(MouseEvent e) {\n    }\n\n    public void mousePressed(MouseEvent e) {\n        if (e.isPopupTrigger()) showPopupMenu(e);\n    }\n\n    public void mouseReleased(MouseEvent e) {\n        if (e.isPopupTrigger()) showPopupMenu(e);\n    }\n\n    public void paste() {\n        try {\n            replaceSelection(Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this)\n                                    .getTransferData(DataFlavor.stringFlavor).toString());\n        } catch (Exception ex) {\n        }\n    }\n\n    protected JPopupMenu getPopupMenu() {\n        if (popupMenu == null) {\n            popupMenu = createPopupMenu();\n        }\n\n        return popupMenu;\n    }\n\n    protected JPopupMenu createPopupMenu() {\n        JPopupMenu popup = new JPopupMenu();\n\n        popupListener = createPopupListener();\n\n        itemCut = new JMenuItem(CUT_STRING);\n        itemCopy = new JMenuItem(COPY_STRING);\n        itemPaste = new JMenuItem(PASTE_STRING);\n        itemDelete = new JMenuItem(DELETE_STRING);\n        itemSelectAll = new JMenuItem(SELECT_ALL_STRING);\n\n        itemCut.addActionListener(popupListener);\n        itemCopy.addActionListener(popupListener);\n        itemPaste.addActionListener(popupListener);\n        itemDelete.addActionListener(popupListener);\n        itemSelectAll.addActionListener(popupListener);\n\n        popup.add(itemCut);\n        popup.add(itemCopy);\n        popup.add(itemPaste);\n        popup.add(itemDelete);\n        popup.addSeparator();\n        popup.add(itemSelectAll);\n\n        return popup;\n    }\n\n    protected void updatePopupMenu() {\n        // Cut\n        itemCut.setEnabled(isEditable() && (getSelectedText() != null));\n\n        // Copy\n        itemCopy.setEnabled(getSelectedText() != null);\n\n        // Paste\n        try {\n            Transferable clipboardContent = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this);\n            itemPaste.setEnabled(isEditable() && (clipboardContent != null)\n                                 && clipboardContent.isDataFlavorSupported(DataFlavor.stringFlavor));\n        } catch (Exception e) {\n            itemPaste.setEnabled(false);\n        }\n\n        // Delete\n        if (isEditable()) {\n            itemDelete.setVisible(true);\n            itemDelete.setEnabled(getSelectedText() != null);\n        } else {\n            itemDelete.setVisible(false);\n        }\n\n        // Select All\n        // always visible and enabled...\n    }\n\n    private ActionListener createPopupListener() {\n        return new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    if (e.getSource() == itemCut) {\n                        cut();\n                    } else if (e.getSource() == itemCopy) {\n                        copy();\n                    } else if (e.getSource() == itemPaste) {\n                        paste();\n                    } else if (e.getSource() == itemDelete) {\n                        deleteSelection();\n                    } else if (e.getSource() == itemSelectAll) {\n                        selectAll();\n                    }\n                }\n            };\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/actions/VisualVMActionsSupportProvider.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.modules.appui.actions;\n\nimport java.awt.Toolkit;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyEvent;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.InputMap;\nimport javax.swing.KeyStroke;\nimport org.graalvm.visualvm.lib.profiler.spi.ActionsSupportProvider;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n * Definition of VisualVM shortcuts for UI actions.\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=ActionsSupportProvider.class, position=10)\npublic final class VisualVMActionsSupportProvider extends ActionsSupportProvider {\n    \n    public KeyStroke registerAction(String actionKey, Action action, ActionMap actionMap, InputMap inputMap) {\n        KeyStroke ks = null;\n\n        if (FilterUtils.FILTER_ACTION_KEY.equals(actionKey)) {\n            ks = KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());\n        } else if (SearchUtils.FIND_ACTION_KEY.equals(actionKey)) {\n            ks = KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());\n        } else if (SearchUtils.FIND_NEXT_ACTION_KEY.equals(actionKey)) {\n            ks = KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0);\n        } else if (SearchUtils.FIND_PREV_ACTION_KEY.equals(actionKey)) {\n            ks = KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.SHIFT_MASK);\n        } else if (SearchUtils.FIND_SEL_ACTION_KEY.equals(actionKey)) {\n            ks = KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.CTRL_MASK);\n        }\n\n        if (ks != null) {\n            actionMap.put(actionKey, action);\n            inputMap.put(ks, actionKey);\n        }\n\n        return ks;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/keystore/CacertsKeyStoreProvider.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.keystore;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.security.KeyStore;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.netbeans.spi.autoupdate.KeyStoreProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n * The cacerts keystore with the configured CA certificates.\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=KeyStoreProvider.class)\npublic class CacertsKeyStoreProvider implements KeyStoreProvider {\n\n    private static String getCacerts() {\n        String fs = File.separator;\n        // ${java_home}/lib/security/cacerts\n        return System.getProperty(\"java.home\") + fs\n              + \"lib\" + fs + \"security\" + fs + \"cacerts\";\n    }\n\n    /**\n     * Returns the cacerts keystore with the configured CA certificates.\n     */\n    @Override\n    public KeyStore getKeyStore() {\n        KeyStore keyStore = null;\n\n        File file = new File(getCacerts());\n        if (!file.exists()) {\n            return null;\n        }\n\n        try (FileInputStream is = new FileInputStream(file)){\n            keyStore = KeyStore.getInstance(KeyStore.getDefaultType());\n            keyStore.load(is, null);\n        } catch (Exception ex) {\n            Logger.getLogger(\"global\").log(Level.INFO, ex.getMessage(), ex);\n        }\n        return keyStore;\n    }\n\n    @Override\n    public TrustLevel getTrustLevel() {\n        return TrustLevel.TRUST;\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/keystore/VisualVMKeyStoreProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.keystore;\n\nimport java.io.InputStream;\nimport java.security.KeyStore;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.netbeans.spi.autoupdate.KeyStoreProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Rechtacek\n * @author Tomas Hurka\n */\n@ServiceProvider(service=KeyStoreProvider.class)\npublic final class VisualVMKeyStoreProvider implements KeyStoreProvider {\n    \n    public static final String KS_FILE_PATH = \"ide.ks\";\n    private static final String KS_DEFAULT_PASSWORD = \"open4all\";\n    \n    public KeyStore getKeyStore() {\n        KeyStore keyStore = null;\n        \n        try (InputStream is = getClass().getResourceAsStream(KS_FILE_PATH)) {\n            keyStore = KeyStore.getInstance(KeyStore.getDefaultType());\n            keyStore.load (is, KS_DEFAULT_PASSWORD.toCharArray());           \n        } catch (Exception ex) {\n            Logger.getLogger (\"global\").log(Level.INFO, ex.getMessage(), ex);\n        }\n        return keyStore;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    <folder name=\"Actions\">\n        <file name=\"Edit_hidden\"/>\n        <folder name=\"Help\">\n            <file name=\"master-help.xml_hidden\"/>\n            <file name=\"org-netbeans-core-actions-AboutAction.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"org.graalvm.visualvm.modules.appui.AboutAction\"/>\n           </file>\n            <file name=\"org-netbeans-modules-javahelp-HelpAction.instance_hidden\"/>\n            <!--file name=\"Show Welcome.instance\">\n\t        <attr name=\"instanceClass\" stringvalue=\"org.graalvm.visualvm.modules.appui.welcome.ShowWelcomeAction\"/>\n            </file-->\n        </folder>\n        <folder name=\"Profile\">\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-AttachAction.instance_hidden\"/>\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-ControlPanelAction.instance_hidden\"/>\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-GetCmdLineArgumentsAction.instance_hidden\"/>\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-HeapDumpAction.instance_hidden\"/>\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-InternalStatsAction.instance_hidden\"/>\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-LoadSnapshotAction.instance_hidden\"/>\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-ModifyProfilingAction.instance_hidden\"/>\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-RerunAction.instance_hidden\"/>\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-RunCalibrationAction.instance_hidden\"/>\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-ShowLiveResultsWindowAction.instance_hidden\"/>\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-ShowTelemetryViewAction.instance_hidden\"/>\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-ShowThreadsViewAction.instance_hidden\"/>\n        </folder>\n        <file name=\"Profile_hidden\"/>\n        <folder name=\"System\">\n            <file name=\"org-netbeans-core-actions-JumpNextAction.instance_hidden\"/>\n            <file name=\"org-netbeans-core-actions-JumpPrevAction.instance_hidden\"/>\n            <file name=\"org-netbeans-core-windows-model-NewMode.instance_hidden\"/>\n            <file name=\"org-netbeans-modules-masterfs-ui-suspend-PauseAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-EditAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-InstantiateAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-MoveDownAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-MoveUpAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-NewAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-NewTemplateAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-OpenAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-PageSetupAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-PopupAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-PrintAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-PropertiesAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-RenameAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-ReorderAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-SaveAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-SaveAllAction.instance_hidden\"/>\n            <file name=\"org-openide-actions-SaveAsAction.instance_hidden\"/>\n        </folder>\n        <folder name=\"View\">\n            <file name=\"org-netbeans-core-actions-HTMLViewAction.instance_hidden\"/>\n            <file name=\"org-netbeans-core-actions-LogAction.instance_hidden\"/>\n        </folder>\n        <folder name=\"Window\">\n            <file name=\"org-netbeans-core-actions-GlobalPropertiesAction.instance_hidden\"/>\n            <file name=\"org-netbeans-core-io-ui-IOWindowAction.instance_hidden\"/>\n            <file name=\"org-netbeans-core-windows-actions-GlobalPropertiesAction.instance_hidden\"/>\n        </folder>\n    </folder>\n    <folder name=\"Menu\">\n        <file name=\"Edit_hidden\"/>\n        <folder name=\"File\">\n            <file name=\"Separator2.instance_hidden\"/>\n            <file name=\"org-netbeans-modules-print-action-PageSetupAction.shadow_hidden\"/>\n            <file name=\"org-netbeans-modules-print-action-PrintAction.shadow_hidden\"/>\n            <file name=\"org-openide-actions-SaveAction.shadow_hidden\"/>\n            <file name=\"org-openide-actions-SaveAllAction.shadow_hidden\"/>\n            <file name=\"org-openide-actions-SaveAsAction.shadow_hidden\"/>\n        </folder>\n        <file name=\"GoTo_hidden\"/>\n        <folder name=\"Help\">\n            <file name=\"Separator1.instance_hidden\"/>\n            <file name=\"master-help.xml_hidden\"/>\n            <file name=\"org-graalvm-visualvm-modules-appui-welcome-ShowWelcomeAction.instance\">\n                <attr name=\"position\" intvalue=\"1100\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-modules-appui-AboutAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.modules.appui.AboutAction.getMenuAction\"/>\n                <attr name=\"position\" intvalue=\"1200\"/>\n            </file>\n            <file name=\"org-netbeans-core-actions-AboutAction.shadow_hidden\"/>\n            <file name=\"org-netbeans-modules-autoupdate-ui-actions-CheckForUpdatesAction.shadow_hidden\"/>\n        </folder>\n        <file name=\"Profile_hidden\"/>\n        <folder name=\"Tools\">\n            <file name=\"Separator1.instance_hidden\"/>\n            <file name=\"Separator2.instance_hidden\"/>\n            <file name=\"org-netbeans-modules-templates-actions-TemplatesAction.shadow_hidden\"/>\n            <file name=\"org-openide-actions-ToolsAction.shadow_hidden\"/>\n        </folder>\n        <folder name=\"View\">\n            <file name=\"Separator1.instance_hidden\"/>\n            <file name=\"Separator2.instance_hidden\"/>\n            <file name=\"ShowEditorOnlyAction.shadow_hidden\"/>\n            <file name=\"org-netbeans-core-actions-LogAction.shadow_hidden\"/>\n            <file name=\"org-netbeans-core-multiview-SplitAction.instance_hidden\"/>\n        </folder>\n        <folder name=\"Window\">\n            <file name=\"CloseAllButThisAction.shadow_hidden\"/>\n            <file name=\"CloseAllDocumentsAction.shadow_hidden\"/>\n            <folder name=\"ConfigureWindow\">\n                <file name=\"CloneDocumentAction.shadow_hidden\"/>\n                <file name=\"CollapseDocumentTabGroupAction.shadow_hidden\"/>\n                <file name=\"NewDocumentTabGroupAction.shadow_hidden\"/>\n                <file name=\"Separator1.instance_hidden\"/>\n                <file name=\"org-netbeans-core-multiview-SplitAction.instance_hidden\"/>\n                <file name=\"org-netbeans-core-windows-actions-DockModeAction.shadow_hidden\"/>\n                <file name=\"org-netbeans-core-windows-actions-MinimizeModeAction.shadow_hidden\"/>\n                <file name=\"org-netbeans-core-windows-actions-UndockModeAction.shadow_hidden\"/>\n            </folder>\n            <file name=\"DocumentsAction.shadow_hidden\"/>\n            <file name=\"GroupsMenuAction.shadow_hidden\"/>\n            <file name=\"Profile_hidden\"/>\n            <file name=\"Separator4.instance_hidden\"/>\n            <file name=\"SwitchToRecentDocumentAction.shadow_hidden\"/>\n            <file name=\"Tools_hidden\"/>\n            <file name=\"Web_hidden\"/>\n            <file name=\"org-netbeans-core-io-ui-IOWindowAction.shadow_hidden\"/>\n        </folder>\n    </folder>\n    <folder name=\"OptionsDialog\">\n        <folder name=\"Advanced.instance_hidden\"/>\n        <folder name=\"Appearance\">\n            <file name=\"DocumentTabs.instance_hidden\"/>\n        </folder>\n        <file name=\"General.instance_hidden\"/>\n        <file name=\"Keymaps.instance_hidden\"/>\n        <file name=\"Appearance.instance\">\n            <attr intvalue=\"3000\" name=\"position\"/>\n        </file>\n    </folder>\n    <file name=\"OptionsExport_hidden\"/>\n    <folder name=\"Services\">\n        <folder name=\"JavaHelp\">\n            <file name=\"org-graalvm-visualvm-lib-profiler-helpset.xml_hidden\"/>\n        </folder>\n        <folder name=\"NoOps\">\n            <file name=\"NoIndentEngine.instance_hidden\"/>\n        </folder>\n        <file name=\"org-openide-text-PrintSettings.settings_hidden\"/>\n    </folder>\n    <folder name=\"Shortcuts\">\n        <file name=\"S-F9.instance_hidden\"/>\n        <file name=\"AS-F2.instance_hidden\"/>\n        <file name=\"CS-F2.instance_hidden\"/>\n        \n        <file name=\"D-W.shadow\">\n            <attr name=\"originalFile\" stringvalue=\"Actions/Window/org-netbeans-core-windows-actions-CloseWindowAction.instance\"/>\n        </file>\n    </folder>\n    <folder name=\"Toolbars\">\n        <file name=\"File_hidden\"/>\n        <file name=\"Clipboard_hidden\"/>\n        <file name=\"Edit_hidden\"/>\n        <folder name=\"Memory\">\n            <file name=\"org-netbeans-modules-masterfs-ui-suspend-PauseAction.shadow_hidden\"/>\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-SelfSamplerAction.shadow_hidden\"/>\n        </folder>\n        <file name=\"Profile_hidden\"/>\n        <file name=\"Standard.xml\" url=\"Standard.xml\"/>\n        <file name=\"UndoRedo_hidden\"/>\n        <file name=\"QuickSearch_hidden\"/>        \n    </folder>\n    <folder name=\"Windows2\">\n        <file name=\"WindowManager.wswmgr\" url=\"WindowManager.wswmgr\"/>\n        <folder name=\"Modes\">\n            <folder name=\"editor\">\n                <file name=\"VisualVMWelcome.wstcref\" url=\"welcome/resources/VisualVMWelcome.wstcref\"/>\n            </folder>\n        </folder>\n        <folder name=\"Components\">\n            <file name=\"VisualVMWelcome.settings\" url=\"welcome/resources/VisualVMWelcome.settings\"/>\n        </folder>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/options/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOptionsCategory_Name_Network=Network\n\nNetworkOptionsPanel_ProxySettingsCaption=Proxy Settings\nNetworkOptionsPanel_NoProxyRadio=&No proxy\nNetworkOptionsPanel_SystemProxyRadio=&Use system proxy settings\nNetworkOptionsPanel_ManualProxyRadio=&Manual proxy settings\\:\nNetworkOptionsPanel_HttpProxy=&HTTP Proxy\\:\nNetworkOptionsPanel_HttpProxyPort=&Port\\:\nNetworkOptionsPanel_SameSettingsCheckbox=Use the same proxy settings for &all protocols\nNetworkOptionsPanel_HttpsProxy=HTTP&S Proxy\\:\nNetworkOptionsPanel_HttpsProxyPort=P&ort\\:\nNetworkOptionsPanel_SocksProxy=SOC&KS Proxy\\:\nNetworkOptionsPanel_SocksProxyPort=Po&rt\\:\nNetworkOptionsPanel_NoProxyHosts=No Pro&xy hosts\\:\nNetworkOptionsPanel_NoProxyHint=(e.g. localhost, *.java.net, 127.0.0.1)\nNetworkOptionsPanel_AuthCheckbox=Proxy re&quires authentication\\:\nNetworkOptionsPanel_Username=Us&ername\\:\nNetworkOptionsPanel_Password=Pass&word\\:\nNetworkOptionsPanel_Password_Description=Proxy password\nNetworkOptionsPanel_JavaScript_Required_Msg=JavaScript engine may be required\nNetworkOptionsPanel_JavaScript_Required_Tooltip=Download & install JavaScript engine required to resolve the proxy using PAC\nNetworkOptionsPanel_JavaScript_Install_Caption=Download & Install JavaScript Engine\nNetworkOptionsPanel_JavaScript_Install_Msg=JavaScript engine is not available in the host JDK,\\nbut may be required to resolve the proxy server.\\n\\nDo you want to download and install the GraalJS engine?\n\nNetworkOptionsModel_PortError=Port number must be an integer value.\n\n# ProxySettings\nProxySettings.password.description=Proxy password\n#NOI18N\nStaticNonProxyHosts=localhost|127.0.0.1\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/options/FiltersOptionsCategory.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.options;\n\nimport java.beans.PropertyChangeListener;\nimport javax.swing.JComponent;\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.netbeans.spi.options.OptionsPanelController;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@OptionsPanelController.TopLevelRegistration(\n        id = \"FiltersOptions\",\n        categoryName = \"#FiltersOptionsCategory_Name\", \n        iconBase = \"org/graalvm/visualvm/modules/appui/options/filters.png\",\n        position = 1550)\n@NbBundle.Messages({\n        \"FiltersOptionsCategory_Name=Filters\"\n}) \npublic final class FiltersOptionsCategory extends OptionsPanelController {\n    \n    private static final HelpCtx HELP_CTX = null;\n//    private static final HelpCtx HELP_CTX = new HelpCtx(\"HeapViewerOptions.Help\"); // NOI18N\n    \n    public static final String OPTIONS_HANDLE = \"HeapViewerOptions\"; // NOI18N\n    \n    private FiltersOptionsPanel settingsPanel;\n    private JComponent settingsComponent;\n\n    \n    private FiltersOptionsPanel getPanel() {\n        if (settingsPanel == null) settingsPanel = new FiltersOptionsPanel();\n        return settingsPanel;\n    }\n    \n    public JComponent getComponent(Lookup lookup) {\n        if (settingsComponent == null) settingsComponent = UISupport.createScrollableContainer(getPanel());\n        return settingsComponent;\n    }\n\n    public HelpCtx getHelpCtx() {\n        return HELP_CTX;\n    }\n    \n    public boolean isChanged() {\n        if (settingsPanel == null) return false;\n        return !settingsPanel.equalsTo(ProfilerIDESettings.getInstance());\n    }\n\n    public boolean isValid() {\n        return true;\n    }\n\n    public void applyChanges() {\n        if (settingsPanel == null) return;\n        settingsPanel.storeTo(ProfilerIDESettings.getInstance());\n    }\n\n    public void cancel() {\n    }\n\n    public void update() {\n        if (settingsPanel == null) return;\n        settingsPanel.loadFrom(ProfilerIDESettings.getInstance());\n    }\n    \n    public void addPropertyChangeListener(PropertyChangeListener l) {\n    }\n    \n    public void removePropertyChangeListener(PropertyChangeListener l) {\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/options/FiltersOptionsPanel.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.options;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.Window;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ComponentAdapter;\nimport java.awt.event.ComponentEvent;\nimport java.awt.event.MouseEvent;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.AbstractAction;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JColorChooser;\nimport javax.swing.JDialog;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTable;\nimport javax.swing.JTextArea;\nimport javax.swing.JTextField;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.AbstractTableModel;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.results.ColoredFilter;\nimport org.graalvm.visualvm.lib.ui.results.PackageColorer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.SmallButton;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"FiltersOptionsPanel_Name=Filters\",\n    \"FiltersOptionsPanel_ColoringResults=&Use defined filters for coloring results (Sampler, Profiler, Heap Viewer, JFR Viewer, etc.)\",\n    \"FiltersOptionsPanel_DefinedFilters=Defined &Filters:\",\n    \"FiltersOptionsPanel_AddFilter=Add new filter\",\n    \"FiltersOptionsPanel_EditFilter=Edit selected filter\",\n    \"FiltersOptionsPanel_DeleteFilter=Delete selected filter\",\n    \"FiltersOptionsPanel_MoveUp=Move selected filter up\",\n    \"FiltersOptionsPanel_MoveDown=Move selected filter down\",\n    \"FiltersOptionsPanel_ColumnFilter=Filter\",\n    \"FiltersOptionsPanel_ColumnPackages=Packages\",\n    \"FiltersOptionsPanel_ColumnColor=Color\",\n    \"ColorCustomizer_DefaultColor=Default color\",\n    \"# {0} - red\",\n    \"# {1} - green\",\n    \"# {2} - blue\",\n    \"ColorCustomizer_CustomColor=Custom color [{0},{1},{2}]\",\n    \"ColorCustomizer_Name=Name:\",\n    \"ColorCustomizer_Color=Color:\",\n    \"ColorCustomizer_ColorHint=Select to define custom color, unselect to use the default color\",\n    \"ColorCustomizer_Value=Value:\",\n    \"ColorCustomizer_AddCaption=Add Filter\",\n    \"ColorCustomizer_EditCaption=Edit Filter\",\n    \"ColorCustomizer_ColorCaption=Choose Filter Color\"\n})\nfinal class FiltersOptionsPanel extends JPanel {\n    \n    private final List<ColoredFilter> colors = new ArrayList<>();\n    private final ColorsTableModel colorsModel = new ColorsTableModel();\n    \n    private JCheckBox coloringChoice;\n    \n    \n    FiltersOptionsPanel() {\n        initUI();\n    }\n\n    \n    public String getDisplayName() {\n        return Bundle.FiltersOptionsPanel_Name();\n    }\n\n    public void storeTo(ProfilerIDESettings settings) {\n        settings.setSourcesColoringEnabled(coloringChoice.isSelected());\n        PackageColorer.setRegisteredColors(colors);\n        for (Window w : Window.getWindows()) w.repaint();\n    }\n\n    public void loadFrom(ProfilerIDESettings settings) {\n        coloringChoice.setSelected(settings.isSourcesColoringEnabled());\n        colors.clear();\n        colors.addAll(PackageColorer.getRegisteredColors());\n        colorsModel.fireTableDataChanged();\n    }\n\n    public boolean equalsTo(ProfilerIDESettings settings) {\n        if (coloringChoice.isSelected() != settings.isSourcesColoringEnabled()) return false;\n        return Objects.equals(PackageColorer.getRegisteredColors(), colors);\n    }\n    \n    \n    private void initUI() {\n        setLayout(new GridBagLayout());\n        \n        GridBagConstraints c;\n        int y = 0;\n        int htab = 15;\n        int vgap = 5;\n        \n        SectionSeparator filtersSection = UISupport.createSectionSeparator(Bundle.FiltersOptionsPanel_Name());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = y++;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 7, 0);\n        add(filtersSection, c);\n        \n        coloringChoice = new JCheckBox();\n        Mnemonics.setLocalizedText(coloringChoice, Bundle.FiltersOptionsPanel_ColoringResults());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = y++;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(0, htab, vgap * 3, 0);\n        add(coloringChoice, c);\n        \n        JLabel tableCaption = new JLabel();\n        Mnemonics.setLocalizedText(tableCaption, Bundle.FiltersOptionsPanel_DefinedFilters());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = y++;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(0, htab, vgap, 0);\n        add(tableCaption, c);\n        \n        final String colorString = \"ABCabc123\"; // NOI18N\n        final ProfilerTable colorsTable = new ProfilerTable(colorsModel, false, false, null);\n        colorsTable.setMainColumn(1);\n        colorsTable.setFitWidthColumn(1);\n        LabelRenderer stringRenderer = new LabelRenderer();\n        colorsTable.setColumnRenderer(0, stringRenderer);\n        colorsTable.setColumnRenderer(1, stringRenderer);\n        LabelRenderer colorRenderer = new LabelRenderer() {\n            private final Color _fg = new JTable().getForeground();\n            private Color fg;\n            {\n                setText(colorString); // NOI18N\n                setHorizontalAlignment(TRAILING);\n            }\n            public void setValue(Object value, int row) {\n                fg = (Color)value;\n            }\n            public void setForeground(Color color) {\n                if (fg != null && Objects.equals(color, _fg)) super.setForeground(fg);\n                else super.setForeground(color);\n            }\n        };\n        colorsTable.setColumnRenderer(2, colorRenderer);\n        stringRenderer.setValue(\"PLACEHOLDER FILTER NAME\", -1); // NOI18N\n        colorsTable.setDefaultColumnWidth(0, stringRenderer.getPreferredSize().width);\n        stringRenderer.setValue(colorString, -1);\n        colorsTable.setDefaultColumnWidth(2, stringRenderer.getPreferredSize().width + 10);\n        ProfilerTableContainer colorsContainer = new ProfilerTableContainer(colorsTable, true, null);\n        colorsContainer.setPreferredSize(new Dimension(1, 1));\n        tableCaption.setLabelFor(colorsTable);\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = y;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.gridheight = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(0, htab, 0, 0);\n        add(colorsContainer, c);\n        \n        JButton addButton = new SmallButton(Icons.getIcon(GeneralIcons.ADD)) {\n            {\n                setToolTipText(Bundle.FiltersOptionsPanel_AddFilter());\n            }\n            protected void fireActionPerformed(ActionEvent e) {\n                ColoredFilter newColor = ColorCustomizer.customize(new ColoredFilter(\"\", \"\", null), true); // NOI18N\n                if (newColor != null) {\n                    colors.add(newColor);\n                    colorsModel.fireTableDataChanged();\n                }\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = y++;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, htab, 0, 0);\n        add(addButton, c);\n        \n        final Runnable editPerformer = new Runnable() {\n            public void run() {\n                int row = colorsTable.getSelectedRow();\n                if (row == -1) return;\n                ColoredFilter selected = colors.get(row);\n                ColoredFilter edited = ColorCustomizer.customize(selected, false);\n                if (edited != null) {\n                    selected.setName(edited.getName());\n                    selected.setValue(edited.getValue());\n                    selected.setColor(edited.getColor());\n                    colorsModel.fireTableDataChanged();\n                }\n            }\n        };\n        final JButton editButton = new SmallButton(Icons.getIcon(GeneralIcons.EDIT)) {\n            {\n                setToolTipText(Bundle.FiltersOptionsPanel_EditFilter());\n            }\n            protected void fireActionPerformed(ActionEvent e) {\n                editPerformer.run();\n            }\n        };\n        colorsTable.setDefaultAction(new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { editPerformer.run(); }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = y++;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, htab, 0, 0);\n        add(editButton, c);\n        \n        final JButton removeButton = new SmallButton(Icons.getIcon(GeneralIcons.REMOVE)) {\n            {\n                setToolTipText(Bundle.FiltersOptionsPanel_DeleteFilter());\n            }\n            protected void fireActionPerformed(ActionEvent e) {\n                int row = colorsTable.getSelectedRow();\n                if (row == -1) return;\n                colors.remove(row);\n                colorsModel.fireTableDataChanged();\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = y++;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, htab, vgap * 2, 0);\n        add(removeButton, c);\n        \n        final JButton upButton = new SmallButton(Icons.getIcon(GeneralIcons.UP)) {\n            {\n                setToolTipText(Bundle.FiltersOptionsPanel_MoveUp());\n            }\n            protected void fireActionPerformed(ActionEvent e) {\n                int row = colorsTable.getSelectedRow();\n                if (row < 1) return;\n                ColoredFilter color = colors.remove(row);\n                colors.add(row - 1, color);\n                colorsModel.fireTableDataChanged();\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = y++;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, htab, 0, 0);\n        add(upButton, c);\n        \n        final JButton downButton = new SmallButton(Icons.getIcon(GeneralIcons.DOWN)) {\n            {\n                setToolTipText(Bundle.FiltersOptionsPanel_MoveDown());\n            }\n            protected void fireActionPerformed(ActionEvent e) {\n                int row = colorsTable.getSelectedRow();\n                if (row == -1 || row > colorsTable.getRowCount() - 2) return;\n                ColoredFilter color = colors.remove(row);\n                colors.add(row + 1, color);\n                colorsModel.fireTableDataChanged();\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = y++;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, htab, 0, 0);\n        add(downButton, c);\n        \n        ListSelectionListener selection = new ListSelectionListener() {\n            public void valueChanged(ListSelectionEvent e) {\n                int row = colorsTable.getSelectedRow();\n                if (row == -1) {\n                    editButton.setEnabled(false);\n                    removeButton.setEnabled(false);\n                    upButton.setEnabled(false);\n                    downButton.setEnabled(false);\n                } else {\n                    editButton.setEnabled(true);\n                    removeButton.setEnabled(true);\n                    upButton.setEnabled(row > 0);\n                    downButton.setEnabled(row < colorsTable.getRowCount() - 1);\n                }\n            }\n        };\n        colorsTable.getSelectionModel().addListSelectionListener(selection);\n        selection.valueChanged(null);\n    }\n    \n    \n    private class ColorsTableModel extends AbstractTableModel {\n        \n        public String getColumnName(int column) {\n            switch (column) {\n                case 0: return Bundle.FiltersOptionsPanel_ColumnFilter();\n                case 1: return Bundle.FiltersOptionsPanel_ColumnPackages();\n                case 2: return Bundle.FiltersOptionsPanel_ColumnColor();\n                default: return null;\n            }\n        }\n\n        public int getRowCount() {\n            return colors.size();\n        }\n\n        public int getColumnCount() {\n            return 3;\n        }\n\n        public Object getValueAt(int rowIndex, int column) {\n            switch (column) {\n                case 0: return colors.get(rowIndex).getName();\n                case 1: return colors.get(rowIndex).getValue();\n                case 2: return colors.get(rowIndex).getColor();\n                default: return null;\n            }\n        }\n        \n    }\n    \n    \n    private static class ColorCustomizer {\n        \n        static ColoredFilter customize(ColoredFilter color, boolean newFilter) {\n            final ColoredFilter customized = new ColoredFilter(color);\n            JTextField nameF = new JTextField(customized.getName());\n            JTextArea valueA = new JTextArea(customized.getValue());\n            valueA.setRows(8);\n            valueA.setColumns(45);\n            valueA.setLineWrap(true);\n            valueA.setWrapStyleWord(true);\n            final JButton colorB = new JButton() {\n                {\n                    setIcon(customized.getIcon(16, 12));\n                    setToolTipText(\"\"); // NOI18N // register with ToolTipManager\n                }\n                protected void fireActionPerformed(ActionEvent e) {\n                    Color c = selectColor(this, customized.getColor());\n                    if (c != null) {\n                        customized.setColor(c);\n                        repaint();\n                    }\n                }\n                public String getToolTipText(MouseEvent e) {\n                    Color col = customized.getColor();\n                    return col == null ? Bundle.ColorCustomizer_DefaultColor() :\n                           Bundle.ColorCustomizer_CustomColor(col.getRed(), col.getGreen(), col.getBlue());\n                }\n            };\n            \n            JPanel p = new JPanel(new GridBagLayout());\n            GridBagConstraints c;\n            int hgap = 10;\n            int htab = 5;\n            int vgap = 5;\n            int y = 0;\n            \n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y;\n            c.insets = new Insets(vgap * 2, hgap, 0, 0);\n            p.add(new JLabel(Bundle.ColorCustomizer_Name()), c);\n            \n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = y;\n            c.weightx = 1;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(vgap * 2, htab, 0, 0);\n            p.add(nameF, c);\n            \n            JCheckBox colorC = new JCheckBox(Bundle.ColorCustomizer_Color(), customized.getColor() != null) {\n                private Color bkpC;\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    if (isSelected()) {\n                        customized.setColor(bkpC);\n                        colorB.setEnabled(true);\n                    } else {\n                        bkpC = customized.getColor();\n                        customized.setColor(null);\n                        colorB.setEnabled(false);\n                    }\n                }\n            };\n            colorC.setOpaque(false);\n            colorC.setToolTipText(Bundle.ColorCustomizer_ColorHint());\n            colorB.setEnabled(colorC.isSelected());\n            c = new GridBagConstraints();\n            c.gridx = 2;\n            c.gridy = y;\n            c.insets = new Insets(vgap * 2, hgap * 2, 0, 0);\n            p.add(colorC, c);\n            \n            c = new GridBagConstraints();\n            c.gridx = 3;\n            c.gridy = y++;\n            c.insets = new Insets(vgap * 2, 2, 0, hgap);\n            p.add(colorB, c);\n            \n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.insets = new Insets(vgap * 2, hgap, 0, 0);\n            p.add(new JLabel(Bundle.ColorCustomizer_Value()), c);\n            \n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.weightx = 1;\n            c.weighty = 1;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.fill = GridBagConstraints.BOTH;\n            c.insets = new Insets(vgap * 2, htab, vgap, hgap);\n            p.add(new JScrollPane(valueA), c);\n            \n//            HelpCtx helpCtx = new HelpCtx(\"PackageColorCustomizer.HelpCtx\"); // NOI18N\n            String dialogCaption = newFilter ? Bundle.ColorCustomizer_AddCaption() :\n                                               Bundle.ColorCustomizer_EditCaption();\n            DialogDescriptor dd = new DialogDescriptor(p, dialogCaption, true,\n                                  new Object[] { DialogDescriptor.OK_OPTION, DialogDescriptor.CANCEL_OPTION }, \n                                  DialogDescriptor.OK_OPTION, DialogDescriptor.DEFAULT_ALIGN,\n                                  null, null);\n            if (DialogDisplayer.getDefault().notify(dd) != DialogDescriptor.OK_OPTION) return null;\n            \n            customized.setName(nameF.getText().trim());\n            customized.setValue(valueA.getText().trim());\n        \n            return customized;\n        }\n        \n        private static Color selectColor(Component comp, Color color) {\n            JPanel previewPanel = new JPanel(new BorderLayout());\n            previewPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 5));\n            \n            String[][] previewData = new String[][] { { \"org.mypackage\", \"100 ms\" }, // NOI18N\n                                                      { \"org.mypackage.MyClass\", \"10 ms\" }, // NOI18N\n                                                      { \"org.mypackage.MyClass.myMethod(boolean, int, String)\", \"1 ms\" } }; // NOI18N\n            TableModel previewModel = new DefaultTableModel(previewData, new String[] { \"Very long column name\", \"xxx\" }); // NOI18N\n            ProfilerTable previewTable = new ProfilerTable(previewModel, false, false, null);\n            \n            final Color initial = color == null ? previewTable.getForeground() : null;\n            final JColorChooser pane = new JColorChooser(color == null ? initial : color);\n            \n            previewTable.setColumnRenderer(0, new JavaNameRenderer(Icons.getIcon(ProfilerIcons.NODE_LEAF)) {\n                protected void setNormalValue(String value) {\n                    super.setNormalValue(value);\n                    Color color = pane.getColor();\n                    if (initial != color) setCustomForeground(color);\n                }\n            });\n            previewTable.setColumnRenderer(1, new LabelRenderer() { { setHorizontalAlignment(TRAILING); } });\n            previewTable.setTableHeader(null);\n            previewTable.setVisibleRows(3);\n            JScrollPane previewScroll = new JScrollPane(previewTable, JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n            \n            previewPanel.add(previewScroll, BorderLayout.CENTER);\n            pane.setPreviewPanel(previewPanel);\n            \n            class Ret implements ActionListener {\n                private Color clr;\n                public void actionPerformed(ActionEvent e) { clr = pane.getColor(); }\n                Color getColor() { return clr; }\n            }\n            Ret ret = new Ret();\n\n            JDialog dialog = JColorChooser.createDialog(comp, Bundle.ColorCustomizer_ColorCaption(), true, pane, ret, null);\n\n            dialog.addComponentListener(new ComponentAdapter() {\n                public void componentHidden(ComponentEvent e) {\n                    Window w = (Window)e.getComponent();\n                    w.dispose();\n                }\n            });\n\n            dialog.setVisible(true);\n            \n            return ret.getColor();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/options/NetworkOptionsModel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.options;\n\nimport java.io.IOException;\nimport java.net.HttpURLConnection;\nimport java.net.InetSocketAddress;\nimport java.net.MalformedURLException;\nimport java.net.Proxy;\nimport java.net.URL;\nimport java.util.StringTokenizer;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.prefs.Preferences;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nclass NetworkOptionsModel {\n\n    enum TestingStatus {\n\n        OK,\n        FAILED,\n        WAITING,\n        NOT_TESTED\n    }\n\n    private static final Logger LOGGER = Logger.getLogger(NetworkOptionsModel.class.getName());\n\n    private static final String NON_PROXY_HOSTS_DELIMITER = \"|\"; //NOI18N\n\n    private static final RequestProcessor rp = new RequestProcessor(NetworkOptionsModel.class);\n\n    private static Preferences getProxyPreferences() {\n        return ProxySettings.getPreferences();\n    }\n\n    boolean getUsageStatistics() {\n        String key = System.getProperty(\"nb.show.statistics.ui\");   // NOI18N\n        if (key != null) {\n            return getProxyPreferences().getBoolean(key, Boolean.FALSE);\n        } else {\n            return false;\n        }\n    }\n\n    void setUsageStatistics(boolean use) {\n        String key = System.getProperty(\"nb.show.statistics.ui\");   //NOI18N\n        if ((key != null) && (use != getUsageStatistics())) {\n            getProxyPreferences().putBoolean(key, use);\n        }\n    }\n\n    int getProxyType() {\n        return getProxyPreferences().getInt(ProxySettings.PROXY_TYPE, ProxySettings.AUTO_DETECT_PROXY);\n    }\n\n    void setProxyType(int proxyType) {\n        if (proxyType != getProxyType()) {\n            if (ProxySettings.AUTO_DETECT_PROXY == proxyType) {\n                getProxyPreferences().putInt(ProxySettings.PROXY_TYPE, usePAC() ? ProxySettings.AUTO_DETECT_PAC : ProxySettings.AUTO_DETECT_PROXY);\n            } else {\n                getProxyPreferences().putInt(ProxySettings.PROXY_TYPE, proxyType);\n            }\n        }\n    }\n\n    String getHttpProxyHost() {\n        return ProxySettings.getHttpHost();\n    }\n\n    void setHttpProxyHost(String proxyHost) {\n        if (!proxyHost.equals(getHttpProxyHost())) {\n            getProxyPreferences().put(ProxySettings.PROXY_HTTP_HOST, proxyHost);\n        }\n    }\n\n    String getHttpProxyPort() {\n        return ProxySettings.getHttpPort();\n    }\n\n    void setHttpProxyPort(String proxyPort) {\n        if (!proxyPort.equals(getHttpProxyPort())) {\n            getProxyPreferences().put(ProxySettings.PROXY_HTTP_PORT, validatePort(proxyPort) ? proxyPort : \"\");\n        }\n    }\n\n    String getHttpsProxyHost() {\n        return ProxySettings.getHttpsHost();\n    }\n\n    void setHttpsProxyHost(String proxyHost) {\n        if (!proxyHost.equals(getHttpsProxyHost())) {\n            getProxyPreferences().put(ProxySettings.PROXY_HTTPS_HOST, proxyHost);\n        }\n    }\n\n    String getHttpsProxyPort() {\n        return ProxySettings.getHttpsPort();\n    }\n\n    void setHttpsProxyPort(String proxyPort) {\n        if (!proxyPort.equals(getHttpsProxyPort())) {\n            getProxyPreferences().put(ProxySettings.PROXY_HTTPS_PORT, validatePort(proxyPort) ? proxyPort : \"\");\n        }\n    }\n\n    String getSocksHost() {\n        return ProxySettings.getSocksHost();\n    }\n\n    void setSocksHost(String socksHost) {\n        if (!socksHost.equals(getSocksHost())) {\n            getProxyPreferences().put(ProxySettings.PROXY_SOCKS_HOST, socksHost);\n        }\n    }\n\n    String getSocksPort() {\n        return ProxySettings.getSocksPort();\n    }\n\n    void setSocksPort(String socksPort) {\n        if (!socksPort.equals(getSocksPort())) {\n            getProxyPreferences().put(ProxySettings.PROXY_SOCKS_PORT, validatePort(socksPort) ? socksPort : \"\");\n        }\n    }\n\n    String getOriginalHttpsHost() {\n        return getProxyPreferences().get(ProxySettings.PROXY_HTTPS_HOST, \"\");\n    }\n\n    String getOriginalHttpsPort() {\n        return getProxyPreferences().get(ProxySettings.PROXY_HTTPS_PORT, \"\");\n    }\n\n    String getOriginalSocksHost() {\n        return getProxyPreferences().get(ProxySettings.PROXY_SOCKS_HOST, \"\");\n    }\n\n    String getOriginalSocksPort() {\n        return getProxyPreferences().get(ProxySettings.PROXY_SOCKS_PORT, \"\");\n    }\n\n    String getNonProxyHosts() {\n        return code2view(ProxySettings.getNonProxyHosts());\n    }\n\n    void setNonProxyHosts(String nonProxy) {\n        if (!nonProxy.equals(getNonProxyHosts())) {\n            getProxyPreferences().put(ProxySettings.NOT_PROXY_HOSTS, view2code(nonProxy));\n        }\n    }\n\n    boolean useProxyAuthentication() {\n        return ProxySettings.useAuthentication();\n    }\n\n    void setUseProxyAuthentication(boolean use) {\n        if (use != useProxyAuthentication()) {\n            getProxyPreferences().putBoolean(ProxySettings.USE_PROXY_AUTHENTICATION, use);\n        }\n    }\n\n    boolean useProxyAllProtocols() {\n        return ProxySettings.useProxyAllProtocols();\n    }\n\n    void setUseProxyAllProtocols(boolean use) {\n        if (use != useProxyAllProtocols()) {\n            getProxyPreferences().putBoolean(ProxySettings.USE_PROXY_ALL_PROTOCOLS, use);\n        }\n    }\n\n    String getProxyAuthenticationUsername() {\n        return ProxySettings.getAuthenticationUsername();\n    }\n\n    void setAuthenticationUsername(String username) {\n        getProxyPreferences().put(ProxySettings.PROXY_AUTHENTICATION_USERNAME, username);\n    }\n\n    char[] getProxyAuthenticationPassword() {\n        return ProxySettings.getAuthenticationPassword();\n    }\n\n    void setAuthenticationPassword(char[] password) {\n        ProxySettings.setAuthenticationPassword(password);\n    }\n\n    static boolean usePAC() {\n        String pacUrl = getProxyPreferences().get(ProxySettings.SYSTEM_PAC, \"\"); // NOI18N\n        return pacUrl != null && !pacUrl.isEmpty();\n    }\n\n    static void testConnection(final NetworkOptionsPanel panel, final int proxyType,\n            final String proxyHost, final String proxyPortString, final String nonProxyHosts) {\n        rp.post(new Runnable() {\n\n            @Override\n            public void run() {\n                testProxy(panel, proxyType, proxyHost, proxyPortString, nonProxyHosts);\n            }\n        });\n    }\n\n    // private helper methods ..................................................\n    private static void testProxy(NetworkOptionsPanel panel, int proxyType,\n            String proxyHost, String proxyPortString, String nonProxyHosts) {\n        panel.updateTestConnectionStatus(TestingStatus.WAITING, null);\n\n        TestingStatus status = TestingStatus.FAILED;\n        String message = null;\n        String testingUrlHost;\n        URL testingUrl;\n        Proxy testingProxy;\n\n        try {\n            testingUrl = new URL(ProxySettings.HTTP_CONNECTION_TEST_URL);\n            testingUrlHost = testingUrl.getHost();\n        } catch (MalformedURLException ex) {\n            LOGGER.log(Level.SEVERE, \"Cannot create url from string.\", ex); // NOI18N\n            panel.updateTestConnectionStatus(status, message);\n            return;\n        }\n\n        switch (proxyType) {\n            case ProxySettings.DIRECT_CONNECTION:\n                testingProxy = Proxy.NO_PROXY;\n                break;\n            case ProxySettings.AUTO_DETECT_PROXY:\n            case ProxySettings.AUTO_DETECT_PAC:\n                nonProxyHosts = ProxySettings.getSystemNonProxyHosts();\n                if (isNonProxy(testingUrlHost, nonProxyHosts)) {\n                    testingProxy = Proxy.NO_PROXY;\n                } else {\n                    String host = ProxySettings.getTestSystemHttpHost();\n                    int port = 0;\n                    try {\n                        port = Integer.parseInt(ProxySettings.getTestSystemHttpPort());\n                    } catch (NumberFormatException ex) {\n                        LOGGER.log(Level.INFO, \"Cannot parse port number\", ex); //NOI18N\n                    }\n                    testingProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port));\n                }\n                break;\n            case ProxySettings.MANUAL_SET_PROXY:\n                nonProxyHosts = view2code(nonProxyHosts);\n                if (isNonProxy(testingUrl.getHost(), nonProxyHosts)) {\n                    testingProxy = Proxy.NO_PROXY;\n                } else {\n                    try {\n                        int proxyPort = Integer.parseInt(proxyPortString);\n                        testingProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));\n                    } catch (NumberFormatException ex) {\n                        // shouldn't fall into this code\n                        LOGGER.log(Level.INFO, \"Cannot parse port number\", ex); // NOI18N\n                        status = TestingStatus.FAILED;\n                        message = NbBundle.getMessage(NetworkOptionsModel.class, \"NetworkOptionsModel_PortError\");  // NOI18N\n                        panel.updateTestConnectionStatus(status, message);\n                        return;\n                    }\n                }\n                break;\n            case ProxySettings.MANUAL_SET_PAC:\n            // Never should get here, user cannot set up PAC manually from IDE\n            default:\n                testingProxy = Proxy.NO_PROXY;\n        }\n\n        try {\n            status = testHttpConnection(testingUrl, testingProxy) ? TestingStatus.OK : TestingStatus.FAILED;\n        } catch (IOException ex) {\n            LOGGER.log(Level.INFO, \"Cannot connect via http protocol.\", ex); //NOI18N\n            message = ex.getLocalizedMessage();\n        }\n\n        panel.updateTestConnectionStatus(status, message);\n    }\n\n    private static boolean testHttpConnection(URL url, Proxy proxy) throws IOException {\n        boolean result = false;\n\n        HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection(proxy);\n        // Timeout shorten to 5s\n        httpConnection.setConnectTimeout(5000);\n        httpConnection.connect();\n\n        if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK\n                || httpConnection.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP) {\n            result = true;\n        }\n\n        httpConnection.disconnect();\n\n        return result;\n    }\n\n    // Simplified to use only with supposed netbeans.org host\n    private static boolean isNonProxy(String host, String nonProxyHosts) {\n        boolean isNonProxy = false;\n\n        if (host != null && nonProxyHosts != null) {\n            StringTokenizer st = new StringTokenizer(nonProxyHosts, NON_PROXY_HOSTS_DELIMITER, false);\n            while (st.hasMoreTokens()) {\n                if (st.nextToken().equals(host)) {\n                    isNonProxy = true;\n                    break;\n                }\n            }\n        }\n\n        return isNonProxy;\n    }\n\n    private static boolean validatePort(String port) {\n        if (port.trim().isEmpty()) {\n            return true;\n        }\n\n        boolean ok = false;\n        try {\n            Integer.parseInt(port);\n            ok = true;\n        } catch (NumberFormatException nfe) {\n            assert false : nfe;\n        }\n        return ok;\n    }\n\n    private static String code2view(String code) {\n        return code == null ? code : code.replace(\"|\", \", \"); // NOI18N\n    }\n\n    private static String view2code(String view) {\n        return view == null ? view : view.replace(\", \", \"|\"); // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/options/NetworkOptionsPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.options;\n\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport javax.script.ScriptEngineManager;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.ButtonGroup;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPasswordField;\nimport javax.swing.JRadioButton;\nimport javax.swing.JSpinner;\nimport javax.swing.JTextField;\nimport javax.swing.SpinnerModel;\nimport javax.swing.SpinnerNumberModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.uisupport.JExtendedSpinner;\nimport org.netbeans.modules.autoupdate.ui.api.PluginManager;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass NetworkOptionsPanel extends JPanel {\n    \n    private static final String GRAALJS_CODENAMEBASE = \"org.graalvm.visualvm.modules.graaljs\"; // NOI18N\n    private static final String GRAALJS_DISPLAYNAME  = \"GraalJS\"; // NOI18N\n    \n\n    private final NetworkOptionsPanelController controller;\n    private boolean passwordChanged;\n\n    NetworkOptionsPanel(NetworkOptionsPanelController controller) {\n        this.controller = controller;\n        initComponents();\n        initListeners();\n    }\n\n\n    void update() {\n        NetworkOptionsModel model = controller.getModel();\n\n        switch (model.getProxyType()) {\n            case ProxySettings.DIRECT_CONNECTION:\n                noProxyRadio.setSelected(true);\n                break;\n            case ProxySettings.AUTO_DETECT_PROXY:\n            case ProxySettings.AUTO_DETECT_PAC:\n                systemProxyRadio.setSelected(true);\n                break;\n            case ProxySettings.MANUAL_SET_PROXY:\n                manualProxyRadio.setSelected(true);\n                break;\n            default:\n                throw new IllegalArgumentException(\"Unknown proxy configuration\"); // NOI18N\n        }\n\n        httpProxyField.setText(model.getHttpProxyHost());\n        httpProxySpinnerModel.setValue(Integer.parseInt(model.getHttpProxyPort()));\n\n        sameSettingsCheckBox.setSelected(model.useProxyAllProtocols());\n\n        httpsProxyField.setText(model.getHttpsProxyHost());\n        httpsProxySpinnerModel.setValue(Integer.parseInt(model.getHttpsProxyPort()));\n        socksProxyField.setText(model.getSocksHost());\n        socksProxySpinnerModel.setValue(Integer.parseInt(model.getSocksPort()));\n\n        noProxyField.setText(model.getNonProxyHosts());\n\n        authenticationCheckBox.setSelected(model.useProxyAuthentication());\n        usernameField.setText(model.getProxyAuthenticationUsername());\n        passwordField.setText(new String(model.getProxyAuthenticationPassword()));\n        \n        updateManualSettings(); // #581\n    }\n\n    void applyChanges() {\n        NetworkOptionsModel model = controller.getModel();\n\n        if (noProxyRadio.isSelected()) {\n            model.setProxyType(ProxySettings.DIRECT_CONNECTION);\n        } else if (systemProxyRadio.isSelected()) {\n            model.setProxyType(ProxySettings.AUTO_DETECT_PROXY);\n        } else if (manualProxyRadio.isSelected()) {\n            model.setProxyType(ProxySettings.MANUAL_SET_PROXY);\n        } else {\n            throw new IllegalArgumentException(\"Unknown proxy configuration\"); // NOI18N\n        }\n\n        model.setHttpProxyHost(httpProxyField.getText().trim());\n        model.setHttpProxyPort(httpProxySpinnerModel.getValue().toString());\n        \n        model.setUseProxyAllProtocols(sameSettingsCheckBox.isSelected());\n\n        model.setHttpsProxyHost(httpsProxyField.getText().trim());\n        model.setHttpsProxyPort(httpsProxySpinnerModel.getValue().toString());\n        model.setSocksHost(socksProxyField.getText().trim());\n        model.setSocksPort(socksProxySpinnerModel.getValue().toString());\n\n        model.setNonProxyHosts(noProxyField.getText().trim());\n\n        model.setUseProxyAuthentication(authenticationCheckBox.isSelected());\n        model.setAuthenticationUsername(usernameField.getText());\n        model.setAuthenticationPassword(passwordField.getPassword());\n        passwordChanged = false;\n    }\n\n    void cancel() {\n    }\n\n    boolean dataValid() {\n        return true;\n    }\n\n    boolean isChanged() {\n        NetworkOptionsModel model = controller.getModel();\n        int proxyType = model.getProxyType();\n\n        if (noProxyRadio.isSelected() &&\n            proxyType != ProxySettings.DIRECT_CONNECTION) return true;\n        if (systemProxyRadio.isSelected() &&\n            (proxyType != ProxySettings.AUTO_DETECT_PROXY && proxyType != ProxySettings.AUTO_DETECT_PAC)) return true;\n        if (manualProxyRadio.isSelected() &&\n            proxyType != ProxySettings.MANUAL_SET_PROXY) return true;\n\n        if (!httpProxyField.getText().equals(model.getHttpProxyHost())) return true;\n        if (!httpProxySpinnerModel.getValue().toString().equals(model.getHttpProxyPort())) return true;\n\n        if (sameSettingsCheckBox.isSelected() != model.useProxyAllProtocols()) return true;\n\n        if (!httpsProxyField.getText().equals(model.getHttpsProxyHost())) return true;\n        if (!httpsProxySpinnerModel.getValue().toString().equals(model.getHttpsProxyPort())) return true;\n        if (!socksProxyField.getText().equals(model.getSocksHost())) return true;\n        if (!socksProxySpinnerModel.getValue().toString().equals(model.getSocksPort())) return true;\n\n        if (!noProxyField.getText().equals(model.getNonProxyHosts())) return true;\n\n        if (authenticationCheckBox.isSelected() != model.useProxyAuthentication()) return true;\n        if (!usernameField.getText().equals(model.getProxyAuthenticationUsername())) return true;\n        if (passwordChanged) return true;\n\n        return false;\n    }\n\n\n    private void initComponents() {\n        ButtonGroup radiosGroup = new ButtonGroup();\n        GridBagConstraints c;\n\n        setLayout(new GridBagLayout());\n\n        SectionSeparator sectionSeparator = UISupport.createSectionSeparator(\n                NbBundle.getMessage(NetworkOptionsPanel.class,\n                \"NetworkOptionsPanel_ProxySettingsCaption\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 0;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 5, 0);\n        add(sectionSeparator, c);\n\n        noProxyRadio = new JRadioButton();\n        Mnemonics.setLocalizedText(noProxyRadio, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_NoProxyRadio\")); // NOI18N\n        radiosGroup.add(noProxyRadio);\n        c = new GridBagConstraints();\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(2, 10, 2, 0);\n        add(noProxyRadio, c);\n        \n        JPanel autoProxySettings = new JPanel(null);\n        autoProxySettings.setLayout(new BoxLayout(autoProxySettings, BoxLayout.LINE_AXIS));\n        c = new GridBagConstraints();\n        c.gridy = 2;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(2, 10, 2, 0);\n        add(autoProxySettings, c);\n\n        systemProxyRadio = new JRadioButton() {\n            protected void fireItemStateChanged(ItemEvent e) {\n                super.fireItemStateChanged(e);\n                updateJSEngineNotifier(isSelected());\n            }\n        };\n        Mnemonics.setLocalizedText(systemProxyRadio, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_SystemProxyRadio\")); // NOI18N\n        radiosGroup.add(systemProxyRadio);\n        autoProxySettings.add(systemProxyRadio);\n        \n        if (!hasDefaultJS()) {\n            autoProxySettings.add(Box.createHorizontalStrut(15));\n\n            systemProxyButton = new JButton(\"<html><a href='#'>JavaScript engine may be required</a></html>\") {\n                protected void fireActionPerformed(ActionEvent e) { notifyJSEngine(); }\n                public Dimension getMinimumSize() { return getPreferredSize(); }\n                public Dimension getMaximumSize() { return getPreferredSize(); }\n            };\n            Mnemonics.setLocalizedText(systemProxyButton, \"<html><a href='#'>\" + NbBundle.getMessage(NetworkOptionsPanel.class, // NOI18N\n                                                          \"NetworkOptionsPanel_JavaScript_Required_Msg\") + \"</a></html>\"); // NOI18N\n            systemProxyButton.setToolTipText(NbBundle.getMessage(NetworkOptionsPanel.class,\n                                                          \"NetworkOptionsPanel_JavaScript_Required_Tooltip\")); // NOI18N\n            systemProxyButton.setContentAreaFilled(false);\n            systemProxyButton.setBorderPainted(true);\n            systemProxyButton.setMargin(new Insets(0, 0, 0, 0));\n            systemProxyButton.setBorder(BorderFactory.createEmptyBorder());\n            systemProxyButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n            systemProxyButton.setVisible(false);\n            autoProxySettings.add(systemProxyButton);\n        }\n\n        manualProxyRadio = new JRadioButton();\n        Mnemonics.setLocalizedText(manualProxyRadio, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_ManualProxyRadio\")); // NOI18N\n        radiosGroup.add(manualProxyRadio);\n        c = new GridBagConstraints();\n        c.gridy = 3;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(2, 10, 2, 0);\n        add(manualProxyRadio, c);\n\n        // --- Manual settings -------------------------------------------------\n\n        JPanel manualSettingsPanel = new JPanel(new GridBagLayout());\n        manualSettingsPanel.setBorder(BorderFactory.createEmptyBorder(5, 40, 0, 0));\n\n        // --- Http proxy ---\n\n        httpProxyLabel = new JLabel();\n        Mnemonics.setLocalizedText(httpProxyLabel, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_HttpProxy\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 3, 5);\n        manualSettingsPanel.add(httpProxyLabel, c);\n\n        httpProxyField = new JTextField();\n        httpProxyLabel.setLabelFor(httpProxyField);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.weightx = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 0, 3, 0);\n        manualSettingsPanel.add(httpProxyField, c);\n\n        httpProxyPortLabel = new JLabel();\n        Mnemonics.setLocalizedText(httpProxyPortLabel, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_HttpProxyPort\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 0;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 8, 3, 5);\n        manualSettingsPanel.add(httpProxyPortLabel, c);\n\n        httpProxySpinnerModel = new SpinnerNumberModel(0, 0, 65535, 1);\n        httpProxyPortSpinner = createJSpinner(httpProxySpinnerModel);\n        httpProxyPortLabel.setLabelFor(httpProxyPortSpinner);\n        c = new GridBagConstraints();\n        c.gridx = 3;\n        c.gridy = 0;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 3, 0);\n        manualSettingsPanel.add(httpProxyPortSpinner, c);\n\n        // --- Use same settings ---\n\n        sameSettingsCheckBox = new JCheckBox();\n        Mnemonics.setLocalizedText(sameSettingsCheckBox, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_SameSettingsCheckbox\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        manualSettingsPanel.add(sameSettingsCheckBox, c);\n\n        // --- Https proxy ---\n\n        httpsProxyLabel = new JLabel();\n        Mnemonics.setLocalizedText(httpsProxyLabel, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_HttpsProxy\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 2;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 3, 5);\n        manualSettingsPanel.add(httpsProxyLabel, c);\n\n        httpsProxyField = new JTextField();\n        httpsProxyLabel.setLabelFor(httpsProxyField);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 2;\n        c.weightx = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 0, 3, 0);\n        manualSettingsPanel.add(httpsProxyField, c);\n\n        httpsProxyPortLabel = new JLabel();\n        Mnemonics.setLocalizedText(httpsProxyPortLabel, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_HttpsProxyPort\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 2;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 8, 3, 5);\n        manualSettingsPanel.add(httpsProxyPortLabel, c);\n\n        httpsProxySpinnerModel = new SpinnerNumberModel(0, 0, 65535, 1);\n        httpsProxyPortSpinner = createJSpinner(httpsProxySpinnerModel);\n        httpsProxyPortLabel.setLabelFor(httpsProxyPortSpinner);\n        c = new GridBagConstraints();\n        c.gridx = 3;\n        c.gridy = 2;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 3, 0);\n        manualSettingsPanel.add(httpsProxyPortSpinner, c);\n\n        // --- Socks proxy ---\n\n        socksProxyLabel = new JLabel();\n        Mnemonics.setLocalizedText(socksProxyLabel, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_SocksProxy\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 3;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 3, 5);\n        manualSettingsPanel.add(socksProxyLabel, c);\n\n        socksProxyField = new JTextField();\n        socksProxyLabel.setLabelFor(socksProxyField);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 3;\n        c.weightx = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 0, 3, 0);\n        manualSettingsPanel.add(socksProxyField, c);\n\n        socksProxyPortLabel = new JLabel();\n        Mnemonics.setLocalizedText(socksProxyPortLabel, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_SocksProxyPort\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 3;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 8, 3, 5);\n        manualSettingsPanel.add(socksProxyPortLabel, c);\n\n        socksProxySpinnerModel = new SpinnerNumberModel(0, 0, 65535, 1);\n        socksProxyPortSpinner = createJSpinner(socksProxySpinnerModel);\n        socksProxyPortLabel.setLabelFor(socksProxyPortSpinner);\n        c = new GridBagConstraints();\n        c.gridx = 3;\n        c.gridy = 3;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 3, 0);\n        manualSettingsPanel.add(socksProxyPortSpinner, c);\n\n        // --- No proxy ---\n\n        noProxyLabel = new JLabel();\n        Mnemonics.setLocalizedText(noProxyLabel, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_NoProxyHosts\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 4;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(10, 0, 3, 5);\n        manualSettingsPanel.add(noProxyLabel, c);\n\n        noProxyField = new JTextField();\n        noProxyLabel.setLabelFor(noProxyField);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 4;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.insets = new Insets(10, 0, 3, 0);\n        manualSettingsPanel.add(noProxyField, c);\n\n        JLabel noProxyHintLabel = new JLabel();\n        Mnemonics.setLocalizedText(noProxyHintLabel, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_NoProxyHint\")); // NOI18N\n        noProxyHintLabel.setEnabled(false);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 5;\n        c.anchor = GridBagConstraints.WEST;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        manualSettingsPanel.add(noProxyHintLabel, c);\n\n        // --- Authentication ---\n\n        authenticationCheckBox = new JCheckBox();\n        Mnemonics.setLocalizedText(authenticationCheckBox, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_AuthCheckbox\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 6;\n        c.anchor = GridBagConstraints.WEST;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.insets = new Insets(5, 0, 0, 0);\n        manualSettingsPanel.add(authenticationCheckBox, c);\n        \n        usernameLabel = new JLabel();\n        Mnemonics.setLocalizedText(usernameLabel, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_Username\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 7;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 30, 3, 5);\n        manualSettingsPanel.add(usernameLabel, c);\n\n        usernameField = new JTextField();\n        usernameLabel.setLabelFor(usernameField);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 7;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.insets = new Insets(3, 0, 3, 0);\n        manualSettingsPanel.add(usernameField, c);\n\n        passwordLabel = new JLabel();\n        Mnemonics.setLocalizedText(passwordLabel, NbBundle.getMessage(NetworkOptionsPanel.class,\n                                   \"NetworkOptionsPanel_Password\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 8;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 30, 0, 5);\n        manualSettingsPanel.add(passwordLabel, c);\n\n        passwordField = new JPasswordField();\n        passwordLabel.setLabelFor(passwordField);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 8;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.insets = new Insets(3, 0, 0, 0);\n        manualSettingsPanel.add(passwordField, c);\n\n        // --- Filler ---\n\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 9;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        manualSettingsPanel.add(Spacer.create(), c);\n\n\n        c = new GridBagConstraints();\n        c.gridy = 4;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        add(manualSettingsPanel, c);\n        \n        updateJSEngineNotifier(systemProxyRadio.isSelected());\n    }\n\n    private JExtendedSpinner createJSpinner(SpinnerModel model) {\n        JExtendedSpinner spinner = new JExtendedSpinner(model);\n        JSpinner.NumberEditor seditor = (JSpinner.NumberEditor)spinner.getEditor();\n        seditor.getFormat().setGroupingUsed(false);\n        return spinner;\n    }\n\n    private void initListeners() {\n        manualProxyRadio.addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                updateManualSettings();\n            }\n        });\n        httpProxyField.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) {\n                updateManualSettings();\n            }\n            public void removeUpdate(DocumentEvent e) {\n                updateManualSettings();\n            }\n            public void changedUpdate(DocumentEvent e) {\n                updateManualSettings();\n            }\n        });\n        httpProxySpinnerModel.addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                updateManualSettings();\n            }\n        });\n        sameSettingsCheckBox.addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                updateManualSettings();\n            }\n        });\n        authenticationCheckBox.addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                updateManualSettings();\n            }\n        });\n        passwordField.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) {\n                passwordChanged = true;\n            }\n            public void removeUpdate(DocumentEvent e) {\n                passwordChanged = true;\n            }\n            public void changedUpdate(DocumentEvent e) {\n                passwordChanged = true;\n            }\n        });\n    }\n\n    private void updateManualSettings() {\n        boolean manual = manualProxyRadio.isSelected();\n        boolean shared = sameSettingsCheckBox.isSelected();\n        boolean passwd = authenticationCheckBox.isSelected();\n\n        httpProxyLabel.setEnabled(manual);\n        httpProxyField.setEnabled(manual);\n        httpProxyPortLabel.setEnabled(manual);\n        httpProxyPortSpinner.setEnabled(manual);\n\n        sameSettingsCheckBox.setEnabled(manual);\n\n        httpsProxyLabel.setEnabled(manual && !shared);\n        httpsProxyField.setEnabled(manual && !shared);\n        httpsProxyPortLabel.setEnabled(manual && !shared);\n        httpsProxyPortSpinner.setEnabled(manual && !shared);\n\n        socksProxyLabel.setEnabled(manual && !shared);\n        socksProxyField.setEnabled(manual && !shared);\n        socksProxyPortLabel.setEnabled(manual && !shared);\n        socksProxyPortSpinner.setEnabled(manual && !shared);\n\n        noProxyLabel.setEnabled(manual);\n        noProxyField.setEnabled(manual);\n\n        authenticationCheckBox.setEnabled(manual);\n        usernameLabel.setEnabled(manual && passwd);\n        usernameField.setEnabled(manual && passwd);\n        passwordLabel.setEnabled(manual && passwd);\n        passwordField.setEnabled(manual && passwd);\n\n        if (shared) {\n            String proxy = httpProxyField.getText();\n            Object port  = httpProxySpinnerModel.getValue();\n            httpsProxyField.setText(proxy);\n            httpsProxySpinnerModel.setValue(port);\n            socksProxyField.setText(proxy);\n            socksProxySpinnerModel.setValue(port);\n        }\n    }\n\n    void updateTestConnectionStatus(NetworkOptionsModel.TestingStatus testingStatus, Object object) {\n        throw new UnsupportedOperationException(\"Not supported yet.\");\n    }\n    \n    \n    private RequestProcessor jsEngineNotifierProcessor;\n    \n    private void updateJSEngineNotifier(boolean autoProxySelected) {\n        if (systemProxyButton != null) {\n            if (autoProxySelected) {\n                if (jsEngineNotifierProcessor == null) jsEngineNotifierProcessor = new RequestProcessor(\"JavaScript engine notifier\"); // NOI18N\n                jsEngineNotifierProcessor.post(new Runnable() {\n                    public void run() {\n                        ScriptEngineManager manager = new ScriptEngineManager();\n                        final boolean hasJSEngine = manager.getEngineByName(\"JavaScript\") != null; // NOI18N\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() { systemProxyButton.setVisible(!hasJSEngine); }\n                        });\n                    }\n                });\n            } else {\n                systemProxyButton.setVisible(false);\n            }\n        }\n    }\n    \n    private void notifyJSEngine() {\n        NotifyDescriptor descr = new NotifyDescriptor.Confirmation(\n                NbBundle.getMessage(NetworkOptionsPanel.class, \"NetworkOptionsPanel_JavaScript_Install_Msg\"), // NOI18N\n                NbBundle.getMessage(NetworkOptionsPanel.class, \"NetworkOptionsPanel_JavaScript_Install_Caption\"), // NOI18N\n                NotifyDescriptor.YES_NO_OPTION);\n        if (DialogDisplayer.getDefault().notify(descr) == NotifyDescriptor.YES_OPTION) {\n            PluginManager.installSingle(GRAALJS_CODENAMEBASE, GRAALJS_DISPLAYNAME);\n        }\n    }\n    \n    private static boolean hasDefaultJS() {\n        String javaVersion = System.getProperty(\"java.specification.version\"); // NOI18N\n        if (javaVersion == null) return true;\n        return javaVersion.startsWith(\"1.8\")  // NOI18N\n            || javaVersion.startsWith(\"1.9\") || javaVersion.startsWith(\"9\") // NOI18N\n            || javaVersion.startsWith(\"10\") // NOI18N\n            || javaVersion.startsWith(\"11\") // NOI18N\n            || javaVersion.startsWith(\"12\") // NOI18N\n            || javaVersion.startsWith(\"13\") // NOI18N\n            || javaVersion.startsWith(\"14\"); // NOI18N\n    }\n    \n    \n    private JRadioButton noProxyRadio;\n    private JRadioButton systemProxyRadio;\n    private JRadioButton manualProxyRadio;\n    private JCheckBox sameSettingsCheckBox;\n    private JLabel httpProxyLabel;\n    private JTextField httpProxyField;\n    private JLabel httpProxyPortLabel;\n    private SpinnerModel httpProxySpinnerModel;\n    private JSpinner httpProxyPortSpinner;\n    private JLabel httpsProxyLabel;\n    private JTextField httpsProxyField;\n    private JLabel httpsProxyPortLabel;\n    private SpinnerModel httpsProxySpinnerModel;\n    private JSpinner httpsProxyPortSpinner;\n    private JLabel socksProxyLabel;\n    private JTextField socksProxyField;\n    private JLabel socksProxyPortLabel;\n    private SpinnerModel socksProxySpinnerModel;\n    private JSpinner socksProxyPortSpinner;\n    private JLabel noProxyLabel;\n    private JTextField noProxyField;\n    private JCheckBox authenticationCheckBox;\n    private JLabel usernameLabel;\n    private JTextField usernameField;\n    private JLabel passwordLabel;\n    private JPasswordField passwordField;\n    private JButton systemProxyButton;\n\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/options/NetworkOptionsPanelController.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.options;\n\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport javax.swing.JComponent;\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.netbeans.spi.options.OptionsPanelController;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\n\n@OptionsPanelController.TopLevelRegistration(\n        id = NetworkOptionsPanelController.CATEGORY_ID,\n        categoryName = \"#OptionsCategory_Name_Network\",\n        iconBase = \"org/graalvm/visualvm/modules/appui/options/network.png\",\n        position = 2000\n)\npublic class NetworkOptionsPanelController extends OptionsPanelController {\n\n    public static final String CATEGORY_ID = \"NetworkOptions\";  // NOI18N\n    private NetworkOptionsModel model;\n    private NetworkOptionsPanel panel;\n    private JComponent component;\n    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);\n    private boolean changed;\n\n\n    public void update() {\n        getPanel().update ();\n    }\n\n    public void applyChanges() {\n        getPanel().applyChanges ();\n    }\n\n    public void cancel() {\n        getPanel().cancel ();\n    }\n\n    public boolean isValid() {\n        return getPanel().dataValid ();\n    }\n\n    public boolean isChanged() {\n        return getPanel().isChanged ();\n    }\n\n\n    public HelpCtx getHelpCtx() {\n        return null;\n\n    }\n\n\n    public JComponent getComponent(Lookup masterLookup) {\n        return getComponent();\n    }\n\n    public void addPropertyChangeListener(PropertyChangeListener l) {\n        pcs.addPropertyChangeListener(l);\n    }\n\n    public void removePropertyChangeListener(PropertyChangeListener l) {\n        pcs.removePropertyChangeListener(l);\n    }\n\n\n    NetworkOptionsModel getModel() {\n        if (model == null) model = new NetworkOptionsModel();\n        return model;\n    }\n\n\n    private NetworkOptionsPanel getPanel() {\n        if (panel == null) panel = new NetworkOptionsPanel(this);\n        return panel;\n    }\n\n    private JComponent getComponent() {\n        if (component == null) {\n            component = UISupport.createScrollableContainer(getPanel());\n        }\n        return component;\n    }\n\n    void changed() {\n        if (!changed) {\n            changed = true;\n            pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);\n        }\n        pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/options/ProxySettings.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.options;\n\nimport java.net.*;\nimport java.util.*;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.prefs.PreferenceChangeListener;\nimport java.util.prefs.Preferences;\nimport org.netbeans.api.keyring.Keyring;\nimport org.openide.util.*;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Rechtacek\n */\npublic class ProxySettings {\n    \n    public static final String PROXY_HTTP_HOST = \"proxyHttpHost\";   // NOI18N\n    public static final String PROXY_HTTP_PORT = \"proxyHttpPort\";   // NOI18N\n    public static final String PROXY_HTTPS_HOST = \"proxyHttpsHost\"; // NOI18N\n    public static final String PROXY_HTTPS_PORT = \"proxyHttpsPort\"; // NOI18N\n    public static final String PROXY_SOCKS_HOST = \"proxySocksHost\"; // NOI18N\n    public static final String PROXY_SOCKS_PORT = \"proxySocksPort\"; // NOI18N\n    public static final String NOT_PROXY_HOSTS = \"proxyNonProxyHosts\";  // NOI18N\n    public static final String PROXY_TYPE = \"proxyType\";                // NOI18N\n    public static final String USE_PROXY_AUTHENTICATION = \"useProxyAuthentication\"; // NOI18N\n    public static final String PROXY_AUTHENTICATION_USERNAME = \"proxyAuthenticationUsername\";   // NOI18N\n    public static final String PROXY_AUTHENTICATION_PASSWORD = \"proxyAuthenticationPassword\";   // NOI18N\n    public static final String USE_PROXY_ALL_PROTOCOLS = \"useProxyAllProtocols\";    // NOI18N\n    public static final String DIRECT = \"DIRECT\";   // NOI18N\n    public static final String PAC = \"PAC\";     // NOI18N\n    \n    public static final String SYSTEM_PROXY_HTTP_HOST = \"systemProxyHttpHost\";      // NOI18N\n    public static final String SYSTEM_PROXY_HTTP_PORT = \"systemProxyHttpPort\";      // NOI18N\n    public static final String SYSTEM_PROXY_HTTPS_HOST = \"systemProxyHttpsHost\";    // NOI18N\n    public static final String SYSTEM_PROXY_HTTPS_PORT = \"systemProxyHttpsPort\";    // NOI18N\n    public static final String SYSTEM_PROXY_SOCKS_HOST = \"systemProxySocksHost\";    // NOI18N\n    public static final String SYSTEM_PROXY_SOCKS_PORT = \"systemProxySocksPort\";    // NOI18N\n    public static final String SYSTEM_NON_PROXY_HOSTS = \"systemProxyNonProxyHosts\"; // NOI18N\n    public static final String SYSTEM_PAC = \"systemPAC\";                            // NOI18N\n    \n    // Only for testing purpose (Test connection in General options panel)\n    public static final String TEST_SYSTEM_PROXY_HTTP_HOST = \"testSystemProxyHttpHost\"; // NOI18N\n    public static final String TEST_SYSTEM_PROXY_HTTP_PORT = \"testSystemProxyHttpPort\"; // NOI18N\n    public static final String HTTP_CONNECTION_TEST_URL = \"http://netbeans.org\";        // NOI18N\n    \n    private static String presetNonProxyHosts;\n\n    /** No proxy is used to connect. */\n    public static final int DIRECT_CONNECTION = 0;\n    \n    /** Proxy setting is automatically detect in OS. */\n    public static final int AUTO_DETECT_PROXY = 1; // as default\n    \n    /** Manually set proxy host and port. */\n    public static final int MANUAL_SET_PROXY = 2;\n    \n    /** Proxy PAC file automatically detect in OS. */\n    public static final int AUTO_DETECT_PAC = 3;\n    \n    /** Proxy PAC file manually set. */\n    public static final int MANUAL_SET_PAC = 4;\n    \n    private static final Logger LOGGER = Logger.getLogger(ProxySettings.class.getName());\n    \n    static Preferences getPreferences() {\n        return NbPreferences.root().node(\"org/netbeans/core\");\n    }\n    \n    \n    public static String getHttpHost () {\n        return normalizeProxyHost (getPreferences ().get (PROXY_HTTP_HOST, \"\"));\n    }\n    \n    public static String getHttpPort () {\n        return getPreferences ().get (PROXY_HTTP_PORT, \"0\");    // NOI18N\n    }\n    \n    public static String getHttpsHost () {\n        if (useProxyAllProtocols ()) {\n            return getHttpHost ();\n        } else {\n            return getPreferences ().get (PROXY_HTTPS_HOST, \"\");\n        }\n    }\n    \n    public static String getHttpsPort () {\n        if (useProxyAllProtocols ()) {\n            return getHttpPort ();\n        } else {\n            return getPreferences ().get (PROXY_HTTPS_PORT, \"0\");   // NOI18N\n        }\n    }\n    \n    public static String getSocksHost () {\n        if (useProxyAllProtocols ()) {\n            return getHttpHost ();\n        } else {\n            return getPreferences ().get (PROXY_SOCKS_HOST, \"\");    // NOI18N\n        }\n    }\n    \n    public static String getSocksPort () {\n        if (useProxyAllProtocols ()) {\n            return getHttpPort ();\n        } else {\n            return getPreferences ().get (PROXY_SOCKS_PORT, \"0\");   // NOI18N\n        }\n    }\n    \n    public static String getNonProxyHosts () {\n        String hosts = getPreferences ().get (NOT_PROXY_HOSTS, getDefaultUserNonProxyHosts ());\n        return compactNonProxyHosts(hosts);\n    }\n    \n    public static int getProxyType () {\n        int type = getPreferences ().getInt (PROXY_TYPE, AUTO_DETECT_PROXY);\n        if (AUTO_DETECT_PROXY == type) {\n            type = ProxySettings.getSystemPac() != null ? AUTO_DETECT_PAC : AUTO_DETECT_PROXY;\n        }\n        return type;\n    }\n    \n    \n    public static String getSystemHttpHost() {\n        return getPreferences().get(SYSTEM_PROXY_HTTP_HOST, \"\");\n    }\n    \n    public static String getSystemHttpPort() {\n        return getPreferences().get(SYSTEM_PROXY_HTTP_PORT, \"\");\n    }\n    \n    public static String getSystemHttpsHost() {\n        return getPreferences().get(SYSTEM_PROXY_HTTPS_HOST, \"\");\n    }\n    \n    public static String getSystemHttpsPort() {\n        return getPreferences().get(SYSTEM_PROXY_HTTPS_PORT, \"\");\n    }\n    \n    public static String getSystemSocksHost() {\n        return getPreferences().get(SYSTEM_PROXY_SOCKS_HOST, \"\");\n    }\n    \n    public static String getSystemSocksPort() {\n        return getPreferences().get(SYSTEM_PROXY_SOCKS_PORT, \"\");\n    }\n    \n    public static String getSystemNonProxyHosts() {\n        return getPreferences().get(SYSTEM_NON_PROXY_HOSTS, getModifiedNonProxyHosts(\"\"));\n    }\n    \n    public static String getSystemPac() {\n        return getPreferences().get(SYSTEM_PAC, null);\n    }\n    \n    \n    public static String getTestSystemHttpHost() {\n        return getPreferences().get(TEST_SYSTEM_PROXY_HTTP_HOST, \"\");\n    }\n    \n    public static String getTestSystemHttpPort() {\n        return getPreferences().get(TEST_SYSTEM_PROXY_HTTP_PORT, \"\");\n    }\n    \n    \n    public static boolean useAuthentication () {\n        return getPreferences ().getBoolean (USE_PROXY_AUTHENTICATION, false);\n    }\n    \n    public static boolean useProxyAllProtocols () {\n        return getPreferences ().getBoolean (USE_PROXY_ALL_PROTOCOLS, false);\n    }\n    \n    public static String getAuthenticationUsername () {\n        return getPreferences ().get (PROXY_AUTHENTICATION_USERNAME, \"\");\n    }\n    \n    public static char[] getAuthenticationPassword () {\n        String old = getPreferences().get(PROXY_AUTHENTICATION_PASSWORD, null);\n        if (old != null) {\n            getPreferences().remove(PROXY_AUTHENTICATION_PASSWORD);\n            setAuthenticationPassword(old.toCharArray());\n        }\n        char[] pwd = Keyring.read(PROXY_AUTHENTICATION_PASSWORD);\n        return pwd != null ? pwd : new char[0];\n    }\n    \n    public static void setAuthenticationPassword(char[] password) {\n        Keyring.save(ProxySettings.PROXY_AUTHENTICATION_PASSWORD, password,\n                // XXX consider including getHttpHost and/or getHttpsHost\n                NbBundle.getMessage(ProxySettings.class, \"ProxySettings.password.description\"));    // NOI18N\n    }\n\n    public static void addPreferenceChangeListener (PreferenceChangeListener l) {\n        getPreferences ().addPreferenceChangeListener (l);\n    }\n    \n    public static void removePreferenceChangeListener (PreferenceChangeListener l) {\n        getPreferences ().removePreferenceChangeListener (l);\n    }\n    \n    private static String getPresetNonProxyHosts () {\n        if (presetNonProxyHosts == null) {\n            presetNonProxyHosts = System.getProperty (\"http.nonProxyHosts\", \"\");    // NOI18N\n        }\n        return presetNonProxyHosts;\n    }\n    \n    private static String getDefaultUserNonProxyHosts () {\n        return getModifiedNonProxyHosts (getSystemNonProxyHosts ());\n    }\n\n  \n    private static String concatProxies(String... proxies) {\n        StringBuilder sb = new StringBuilder();\n        for (String n : proxies) {\n            if (n == null) {\n                continue;\n            }\n            n = n.trim();\n            if (n.isEmpty()) {\n                continue;\n            }\n            if (sb.length() > 0 && sb.charAt(sb.length() - 1) != '|') { // NOI18N\n                if (!n.startsWith(\"|\")) {   // NOI18N\n                    sb.append('|');         // NOI18N\n                }\n            }\n            sb.append(n);\n        }\n        return sb.toString();\n    }\n\n    private static String getModifiedNonProxyHosts (String systemPreset) {\n        String fromSystem = systemPreset.replaceAll (\";\", \"|\").replaceAll (\",\", \"|\"); //NOI18N\n        String fromUser = getPresetNonProxyHosts () == null ? \"\" : getPresetNonProxyHosts ().replaceAll (\";\", \"|\").replaceAll (\",\", \"|\"); //NOI18N\n        if (Utilities.isWindows ()) {\n            fromSystem = addRegularToNonProxyHosts(fromSystem);\n        }\n        final String staticNonProxyHosts = NbBundle.getMessage(ProxySettings.class, \"StaticNonProxyHosts\"); // NOI18N\n        String nonProxy = concatProxies(fromUser, fromSystem, staticNonProxyHosts); // NOI18N\n        String localhost;\n        try {\n            localhost = InetAddress.getLocalHost().getHostName();\n            if (!\"localhost\".equals(localhost)) { // NOI18N\n                nonProxy = nonProxy + \"|\" + localhost; // NOI18N\n            } else {\n                // Avoid this error when hostname == localhost:\n                // Error in http.nonProxyHosts system property:  sun.misc.REException: localhost is a duplicate\n            }\n        }\n        catch (UnknownHostException e) {\n            // OK. Sometimes a hostname is assigned by DNS, but a computer\n            // is later pulled off the network. It may then produce a bogus\n            // name for itself which can't actually be resolved. Normally\n            // \"localhost\" is aliased to 127.0.0.1 anyway.\n        }\n        /* per Milan's agreement it's removed. See issue #89868\n        try {\n            String localhost2 = InetAddress.getLocalHost().getCanonicalHostName();\n            if (!\"localhost\".equals(localhost2) && !localhost2.equals(localhost)) { // NOI18N\n                nonProxy = nonProxy + \"|\" + localhost2; // NOI18N\n            } else {\n                // Avoid this error when hostname == localhost:\n                // Error in http.nonProxyHosts system property:  sun.misc.REException: localhost is a duplicate\n            }\n        }\n        catch (UnknownHostException e) {\n            // OK. Sometimes a hostname is assigned by DNS, but a computer\n            // is later pulled off the network. It may then produce a bogus\n            // name for itself which can't actually be resolved. Normally\n            // \"localhost\" is aliased to 127.0.0.1 anyway.\n        }\n         */\n        return compactNonProxyHosts (nonProxy);\n    }\n\n\n    // avoid duplicate hosts\n    private static String compactNonProxyHosts (String hosts) {\n        StringTokenizer st = new StringTokenizer(hosts, \",\"); //NOI18N\n        StringBuilder nonProxyHosts = new StringBuilder();\n        while (st.hasMoreTokens()) {\n            String h = st.nextToken().trim();\n            if (h.isEmpty()) {\n                continue;\n            }\n            if (nonProxyHosts.length() > 0) {\n                nonProxyHosts.append(\"|\"); // NOI18N\n            }\n            nonProxyHosts.append(h);\n        }\n        st = new StringTokenizer (nonProxyHosts.toString(), \"|\"); //NOI18N\n        Set<String> set = new HashSet<> ();\n        StringBuilder compactedProxyHosts = new StringBuilder();\n        while (st.hasMoreTokens ()) {\n            String t = st.nextToken ();\n            if (set.add (t.toLowerCase (Locale.US))) {\n                if (compactedProxyHosts.length() > 0) {\n                    compactedProxyHosts.append('|');    // NOI18N\n                }\n                compactedProxyHosts.append(t);\n            }\n        }\n        return compactedProxyHosts.toString();\n    }\n    \n    private static String addRegularToNonProxyHosts(String nonProxyHost) {\n        StringTokenizer st = new StringTokenizer (nonProxyHost, \"|\");   // NOI18N\n        StringBuilder regularProxyHosts = new StringBuilder();\n        while (st.hasMoreTokens ()) {\n            String t = st.nextToken ();\n            if (t.indexOf ('*') == -1) { //NOI18N\n                t = t + '*'; //NOI18N\n            }\n            if (regularProxyHosts.length() > 0)\n                regularProxyHosts.append('|');  // NOI18N\n            regularProxyHosts.append(t);\n        }\n\n        return regularProxyHosts.toString();\n    }\n\n    public static String normalizeProxyHost (String proxyHost) {\n        if (proxyHost.toLowerCase (Locale.US).startsWith (\"http://\")) { // NOI18N\n            return proxyHost.substring (7);\n        } else {\n            return proxyHost;\n        }\n    }\n    \n    private static InetSocketAddress analyzeProxy(URI uri) {\n        Parameters.notNull(\"uri\", uri);     // NOI18N\n        List<Proxy> proxies = ProxySelector.getDefault().select(uri);\n        assert proxies != null : \"ProxySelector cannot return null for \" + uri;     // NOI18N\n        assert !proxies.isEmpty() : \"ProxySelector cannot return empty list for \" + uri;    // NOI18N\n        String protocol = uri.getScheme();\n        Proxy p = proxies.get(0);\n        if (Proxy.Type.DIRECT == p.type()) {\n            // return null for DIRECT proxy\n            return null;\n        }\n        if (protocol == null\n                || ((protocol.startsWith(\"http\") || protocol.equals(\"ftp\")) && Proxy.Type.HTTP == p.type()) // NOI18N\n                || !(protocol.startsWith(\"http\") || protocol.equals(\"ftp\"))) {  // NOI18N\n            if (p.address() instanceof InetSocketAddress) {\n                // check is\n                //assert ! ((InetSocketAddress) p.address()).isUnresolved() : p.address() + \" must be resolved address.\";\n                return (InetSocketAddress) p.address();\n            } else {\n                LOGGER.log(Level.INFO, p.address() + \" is not instanceof InetSocketAddress but \" + p.address().getClass()); // NOI18N\n                return null;\n            }\n        } else {\n            return null;\n        }\n    }\n    \n    public static void reload() {\n        Reloader reloader = Lookup.getDefault().lookup(Reloader.class);\n        reloader.reload();\n    }\n\n    @ServiceProvider(service = NetworkSettings.ProxyCredentialsProvider.class, position = 1000)\n    public static class NbProxyCredentialsProvider extends NetworkSettings.ProxyCredentialsProvider {\n\n        @Override\n        public String getProxyHost(URI u) {\n            if (getPreferences() == null) {\n                return null;\n            }\n            InetSocketAddress sa = analyzeProxy(u);\n            return sa == null ? null : sa.getHostName();\n        }\n\n        @Override\n        public String getProxyPort(URI u) {\n            if (getPreferences() == null) {\n                return null;\n            }\n            InetSocketAddress sa = analyzeProxy(u);\n            return sa == null ? null : Integer.toString(sa.getPort());\n        }\n\n        @Override\n        protected String getProxyUserName(URI u) {\n            if (getPreferences() == null) {\n                return null;\n            }\n            return ProxySettings.getAuthenticationUsername();\n        }\n\n        @Override\n        protected char[] getProxyPassword(URI u) {\n            if (getPreferences() == null) {\n                return null;\n            }\n            return ProxySettings.getAuthenticationPassword();\n        }\n\n        @Override\n        protected boolean isProxyAuthentication(URI u) {\n            if (getPreferences() == null) {\n                return false;\n            }\n            return getPreferences().getBoolean(USE_PROXY_AUTHENTICATION, false);\n        }\n\n    }\n    \n    /** A bridge between <code>o.n.core</code> and <code>core.network</code>.\n     * An implementation of this class brings a facility to reload Network Proxy Settings\n     * from underlying OS.\n     * The module <code>core.network</code> provides an implementation which may be accessible\n     * via <code>Lookup.getDefault()</code>. It's not guaranteed any implementation is found on all distribution. \n     * \n     * @since 3.40\n     */\n    public abstract static class Reloader {\n        \n        /** Reloads Network Proxy Settings from underlying system.\n         *\n         */\n        public abstract void reload();\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/proxysettings/ProxySettingsHack.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.proxysettings;\n\nimport java.util.logging.Handler;\nimport java.util.logging.Level;\nimport java.util.logging.LogRecord;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.modules.appui.options.NetworkOptionsPanelController;\nimport org.netbeans.api.options.OptionsDisplayer;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ProxySettingsHack {\n\n    private static Logger logger;\n    \n    public static void hackProxySettings() {\n        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n            public void run() {\n                // Bugfix #344, logger must be referenced to prevent it from being GCed\n                logger = Logger.getLogger(OptionsDisplayer.class.getName());\n                logger.addHandler(new Handler() {\n                    public void flush() {}\n                    public void close() throws SecurityException {}\n                    public void publish(LogRecord record) {\n                        if (record.getLevel() == Level.WARNING && record.getMessage().contains(\"Unknown categoryId: General\")) // NOI18N\n                            OptionsDisplayer.getDefault().open(NetworkOptionsPanelController.CATEGORY_ID);\n                    }\n                });\n            }\n        });\n    }\n\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/toolbar/ToolbarProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.modules.appui.toolbar;\n\nimport javax.swing.JComponent;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\n//import org.openide.util.lookup.ServiceProvider;\n\n/**\n * NOTE: disabled since the ProfilerToolbar is transparent by default\n *\n * @author Tomas Hurka\n */\n//@ServiceProvider(service=ProfilerToolbar.Provider.class)\npublic class ToolbarProvider extends ProfilerToolbar.Provider {\n\n    @Override\n    public ProfilerToolbar create(boolean showSeparator) {\n        return new VisualVMImpl(showSeparator);\n    }\n    \n    \n    private static class VisualVMImpl extends ProfilerToolbar.Impl {\n        \n        private VisualVMImpl(boolean showSeparator) {\n            super(showSeparator);\n            \n            JComponent comp = component;\n            if (showSeparator) comp = (JComponent)comp.getComponent(0);\n            \n//            comp.setOpaque(false);\n            comp.setOpaque(true);\n            comp.setBackground(UIUtils.getProfilerResultsBackground());\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/toolbar/VisualVMToolbar.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.modules.appui.toolbar;\n\nimport java.awt.*;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.uisupport.TransparentToolBar;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nclass VisualVMToolbar extends ProfilerToolbar {\n\n    private final JComponent component;\n    private final TransparentToolBar toolbar;\n\n    VisualVMToolbar(boolean showSeparator) {\n        toolbar = new TransparentToolBar();\n\n        if (showSeparator) {\n            component = TransparentToolBar.withSeparator(toolbar);\n        } else {\n            component = toolbar;\n        }\n    }\n\n    @Override\n    public JComponent getComponent() {\n        return component;\n    }\n\n    @Override\n    public Component add(Action action) {\n        return toolbar.addItem(action);\n    }\n\n    @Override\n    public Component add(Component component) {\n        return toolbar.addItem(component);\n    }\n\n    @Override\n    public Component add(Component component, int index) {\n        return toolbar.addItem(component, index);\n    }\n\n    @Override\n    public void addSeparator() {\n        toolbar.addSeparator();\n    }\n\n    @Override\n    public void addSpace(int width) {\n        toolbar.addSpace(width);\n    }\n\n    @Override\n    public void addFiller() {\n        toolbar.addFiller();\n    }\n\n    @Override\n    public void remove(Component component) {\n        toolbar.removeItem(component);\n    }\n\n    @Override\n    public void remove(int index) {\n        toolbar.removeItem(index);\n    }\n\n    @Override\n    public int getComponentCount() {\n        return toolbar.getItemsCount();\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/url/VisualVMURLDisplayer.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.url;\n\nimport java.net.URL;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.JFrame;\nimport javax.swing.SwingWorker;\nimport javax.swing.WindowConstants;\nimport org.graalvm.visualvm.core.ui.DesktopUtils;\nimport org.openide.awt.HtmlBrowser;\nimport org.openide.awt.HtmlBrowser.URLDisplayer;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=URLDisplayer.class,position=1000)\npublic final class VisualVMURLDisplayer extends URLDisplayer {\n    \n    public void showURL(final URL url) {\n        new SwingWorker<Boolean,Object>() {\n            \n            protected Boolean doInBackground() throws Exception {\n                if (DesktopUtils.isBrowseAvailable()) {\n                    try {\n                        DesktopUtils.browse(url.toURI());\n                        return Boolean.TRUE;\n                    } catch (Exception ex) {\n                        Logger.getLogger(VisualVMURLDisplayer.class.getName()).log(Level.INFO, \"Showing: \" + url, ex);\n                    }\n                }\n                return Boolean.FALSE;\n            }\n            \n            protected void done() {\n                try {\n                    if (!get().booleanValue()) {\n                        // Fallback implementation:\n                        HtmlBrowser browser = new HtmlBrowser();\n                        browser.setURL(url);\n                        \n                        JFrame frame = new JFrame();\n                        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);\n                        frame.getContentPane().add(browser);\n                        frame.pack();\n                        frame.setVisible(true);\n                    }\n                } catch (Exception ex) {\n                    Logger.getLogger(VisualVMURLDisplayer.class.getName()).log(Level.INFO, \"Showing: \" + url, ex);\n                }\n            }\n        }.execute();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_Action=Start &Page\n\nLBL_Tab_Title=Start Page\n\nACS_Welcome_DESC=Welcome window providing basic howto information on VisualVM.\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/BundleSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.text.MessageFormat;\nimport javax.swing.JComponent;\nimport org.openide.util.NbBundle;\n\npublic class BundleSupport {\n\n    private static final String BUNDLE_NAME = \"org.graalvm.visualvm.modules.appui.welcome.resources.Bundle\"; // NOI18N\n\n    private static final String LABEL_PREFIX = \"LBL_\"; // NOI18N\n    private static final String URL_PREFIX = \"URL_\"; // NOI18N\n    private static final String CATEGORY_PREFIX = \"CATEGORY_\"; // NOI18N\n    private static final String TEMPLATE_PREFIX = \"TEMPLATE_\"; // NOI18N\n    private static final String ACN_PREFIX = \"ACN_\"; // NOI18N\n    private static final String ACD_PREFIX = \"ACD_\"; // NOI18N\n    private static final String MNM_PREFIX = \"MNM_\"; // NOI18N\n    \n    public static String getLabel(String bundleKey) {\n        return NbBundle.getBundle(BUNDLE_NAME).getString(LABEL_PREFIX + bundleKey);\n    }\n    \n    public static String getURL(String bundleKey) {\n        return NbBundle.getBundle(BUNDLE_NAME).getString(URL_PREFIX + bundleKey);\n    }\n    \n    public static char getMnemonic(String bundleKey) {\n        return NbBundle.getBundle(BUNDLE_NAME).getString(MNM_PREFIX + bundleKey).charAt(0);\n    }\n    \n    public static String getSampleCategory(String bundleKey) {\n        return NbBundle.getBundle(BUNDLE_NAME).getString(CATEGORY_PREFIX + bundleKey);\n    }\n\n    public static String getSampleTemplate(String bundleKey) {\n        return NbBundle.getBundle(BUNDLE_NAME).getString(TEMPLATE_PREFIX + bundleKey);\n    }\n\n    public static String getAccessibilityName(String bundleKey) {\n        return NbBundle.getBundle(BUNDLE_NAME).getString(ACN_PREFIX + bundleKey);\n    }\n    \n    public static String getAccessibilityName(String bundleKey, String param) {\n        return MessageFormat.format( NbBundle.getBundle(BUNDLE_NAME).getString(ACN_PREFIX + bundleKey), param );\n    }\n    \n    public static String getAccessibilityDescription(String bundleKey, String param) {\n        return MessageFormat.format( NbBundle.getBundle(BUNDLE_NAME).getString(ACD_PREFIX + bundleKey), param );\n    }\n    \n    public static void setAccessibilityProperties(JComponent component, String bundleKey) {\n        String aName = NbBundle.getBundle(BUNDLE_NAME).getString(ACN_PREFIX + bundleKey);  \n        String aDescr = NbBundle.getBundle(BUNDLE_NAME).getString(ACD_PREFIX + bundleKey);  \n      \n        component.getAccessibleContext().setAccessibleName(aName);\n        component.getAccessibleContext().setAccessibleDescription(aDescr);\n    }\n    \n    public static String getMessage( String key, Object param ) {\n        return MessageFormat.format( NbBundle.getBundle(BUNDLE_NAME).getString(key), param );\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/CaptionPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.awt.BorderLayout;\nimport java.awt.Image;\nimport javax.swing.JPanel;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass CaptionPanel extends JPanel {\n    \n    private static final String TOP_LEFT_RESOURCE =   \"org/graalvm/visualvm/modules/appui/welcome/resources/welcome-topleft.png\";\n    private static final String TOP_RIGHT_RESOURCE =  \"org/graalvm/visualvm/modules/appui/welcome/resources/welcome-topright.png\";\n    private static final String TOP_MIDDLE_RESOURCE = \"org/graalvm/visualvm/modules/appui/welcome/resources/welcome-topmiddle.png\";\n    \n    \n    CaptionPanel() {\n        initComponents();\n    }\n    \n    \n    private void initComponents() {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n        \n        Image topLeftImage = ImageUtilities.loadImage(TOP_LEFT_RESOURCE, true);\n        Image topRightImage = ImageUtilities.loadImage(TOP_RIGHT_RESOURCE, true);\n        Image topMiddleImage = ImageUtilities.loadImage(TOP_MIDDLE_RESOURCE, true);\n        \n        add(new FixedImagePanel(topLeftImage), BorderLayout.WEST);\n        add(new FixedImagePanel(topRightImage), BorderLayout.EAST);\n        add(new HorizontalImagePanel(topMiddleImage), BorderLayout.CENTER);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/Constants.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.awt.BasicStroke;\nimport java.awt.Font;\nimport java.awt.Stroke;\n\n/**\n *\n * @author S. Aubrecht\n */\npublic interface Constants {\n\n    static final String COLOR_SCREEN_BACKGROUND = \"ScreenBackgroundColor\"; //NOI18N\n    static final String COLOR_SCREEN_BACKGROUND_DARK = \"ScreenBackgroundColorDark\"; //NOI18N\n    static final String COLOR_CONTENT_BACKGROUND = \"ContentBackgroundColor\"; //NOI18N\n    static final String BORDER_COLOR = \"BorderColor\"; //NOI18N\n    \n    \n    static final int FONT_SIZE = Utils.getDefaultFontSize();\n    static final Font BUTTON_FONT = new Font( null, Font.BOLD, FONT_SIZE );\n\n    static final Stroke LINK_IN_FOCUS_STROKE = new BasicStroke(1, BasicStroke.CAP_SQUARE,\n        BasicStroke.JOIN_BEVEL, 0, new float[] {0, 2}, 0);\n    static final String LINK_IN_FOCUS_COLOR = \"LinkInFocusColor\"; //NOI18N\n    static final String LINK_COLOR = \"LinkColor\"; //NOI18N\n    static final String MOUSE_OVER_LINK_COLOR = \"MouseOverLinkColor\"; //NOI18N\n    static final String VISITED_LINK_COLOR = \"VisitedLinkColor\"; //NOI18N\n\n    \n    static final int START_PAGE_MIN_WIDTH = 600;\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/ContentsPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Graphics;\nimport java.awt.GridLayout;\nimport java.awt.Insets;\nimport javax.swing.JPanel;\nimport javax.swing.border.Border;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ContentsPanel extends JPanel implements Constants {\n    \n    ContentsPanel() {\n        initComponents();\n    }\n    \n    \n    private void initComponents() {\n        setLayout(new GridLayout(4, 2, 0, 0));\n        \n        addLink( \"Link1\", true, false, false );\n        addLink( \"Link2\", false, false, true );\n        addLink( \"Link3\", true, false, false );\n        addLink( \"Link4\", false, false, true );\n        addLink( \"Link5\", true, false, false );\n        addLink( \"Link6\", false, false, true );\n        addLink( \"Link7\", true, true, false );\n        addLink( \"Link8\", false, true, true );\n        \n        setBackground(Utils.getColor(COLOR_CONTENT_BACKGROUND));\n    }\n    \n    private void addLink( String resourceKey, boolean includeSource, boolean drawBottom, boolean drawRight ) {\n        JPanel panel = new JPanel(new BorderLayout());\n        panel.setOpaque( false );\n        panel.add( new WebLink(resourceKey, includeSource), BorderLayout.CENTER );\n        panel.setBorder( new MyBorder(drawBottom, drawRight) );\n        add( panel );\n    }\n    \n    private static class MyBorder implements Border {\n        private static final Color COLOR = Utils.getColor(BORDER_COLOR);\n        private boolean drawBottom;\n        private boolean drawRight;\n        MyBorder( boolean drawBottom, boolean drawRight ) {\n            this.drawBottom = drawBottom;\n            this.drawRight = drawRight;\n        }\n        \n        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {\n            g.setColor(COLOR);\n            g.drawLine(x, y, x+width, y);\n            g.drawLine(x, y, x, y+height);\n            if( drawRight ) \n                g.drawLine(x+width-1, y, x+width-1, y+height);\n            if( drawBottom )\n                g.drawLine(x, y+height-1, x+width, y+height-1);\n        }\n\n        public Insets getBorderInsets(Component c) {\n            return new Insets(8,8,8,8);\n        }\n\n        public boolean isBorderOpaque() {\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/FixedImagePanel.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Image;\nimport java.awt.MediaTracker;\nimport javax.swing.JPanel;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass FixedImagePanel extends JPanel {\n    \n    protected Image image;\n    protected Dimension imageSize;\n\n\n    FixedImagePanel(Image img) {\n        try {\n            image = loadImage(img, new MediaTracker(this));\n            imageSize = new Dimension(image.getWidth(null), image.getHeight(null));\n            setOpaque(false);\n        } catch (InterruptedException e) {\n            throw new RuntimeException(\"Failed to load image: \" + e.getMessage()); // NOI18N\n        }\n    }\n\n    \n    public Dimension getPreferredSize() {\n        return imageSize;\n    }\n    \n    public Dimension getMinimumSize() {\n        return getPreferredSize();\n    }\n    \n    public Dimension getMaximumSize() {\n        return getPreferredSize();\n    }\n    \n    \n    protected void paintComponent(Graphics graphics) {\n        graphics.drawImage(image, 0, 0, this);\n    }\n\n    \n    private static Image loadImage(Image image, MediaTracker mTracker) throws InterruptedException {\n        mTracker.addImage(image, 0);\n        mTracker.waitForID(0);\n        mTracker.removeImage(image, 0);\n        return image;\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/FooterPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.awt.BorderLayout;\nimport java.awt.Image;\nimport javax.swing.JPanel;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass FooterPanel extends JPanel {\n    \n    private static final String BOTTOM_LEFT_RESOURCE =    \"org/graalvm/visualvm/modules/appui/welcome/resources/welcome-bottomleft.png\";\n    private static final String BOTTOM__RIGHT_RESOURCE =  \"org/graalvm/visualvm/modules/appui/welcome/resources/welcome-bottomright.png\";\n    private static final String BOTTOM__MIDDLE_RESOURCE = \"org/graalvm/visualvm/modules/appui/welcome/resources/welcome-bottommiddle.png\";\n    \n    \n    FooterPanel() {\n        initComponents();\n    }\n    \n    \n    private void initComponents() {\n        Image bottomLeftImage = ImageUtilities.loadImage(BOTTOM_LEFT_RESOURCE, true);\n        Image bottomRightImage = ImageUtilities.loadImage(BOTTOM__RIGHT_RESOURCE, true);\n        Image bottomMiddleImage = ImageUtilities.loadImage(BOTTOM__MIDDLE_RESOURCE, true);\n        \n        setLayout(new BorderLayout());\n        setOpaque(false);\n        add(new FixedImagePanel(bottomLeftImage), BorderLayout.WEST);\n        add(new FixedImagePanel(bottomRightImage), BorderLayout.EAST);\n        add(new HorizontalImagePanel(bottomMiddleImage), BorderLayout.CENTER);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/HorizontalImagePanel.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Image;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass HorizontalImagePanel extends FixedImagePanel {\n    \n    private Dimension minSize;\n    private Dimension maxSize;\n    \n    HorizontalImagePanel(Image img) {\n        super(img);\n        \n        minSize = new Dimension(0, imageSize.height);\n        maxSize = new Dimension(Integer.MAX_VALUE, imageSize.height);\n    }\n\n    @Override\n    public Dimension getPreferredSize() {\n        Component[] childComponents = getComponents();\n        if (childComponents.length == 0) {\n            return minSize;\n        } else {\n            // TODO: should be computed just when child components are added/removed\n            int minWidth = 0;\n            for (Component component : childComponents) {\n                int minChildComponentWidth = component.getMinimumSize().width;\n                if (minWidth < minChildComponentWidth) minWidth = minChildComponentWidth;\n            }\n            return new Dimension(minWidth, imageSize.height);\n        }\n    }\n    \n    @Override\n    public Dimension getMaximumSize() {\n        return maxSize;\n    }\n    \n    \n    @Override\n    protected void paintComponent(Graphics graphics) {\n        int compEnd = getSize().width;\n        int drawEnd = 0;\n        while (drawEnd < compEnd) {\n            graphics.drawImage(image, drawEnd, 0, this);\n            drawEnd += imageSize.width;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/LinkButton.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.FontMetrics;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionListener;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.FocusListener;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.border.EmptyBorder;\n\n/**\n *\n * @author S. Aubrecht\n */\npublic abstract class LinkButton extends JButton\n        implements Constants, MouseListener, ActionListener, FocusListener {\n\n    private boolean underline = false;\n\n    public LinkButton( String label ) {\n        super( label );\n        setForeground( Utils.getColor(LINK_COLOR) );\n        setFont( BUTTON_FONT );\n        setBorder( new EmptyBorder(1, 1, 1, 1) );\n        setCursor( Cursor.getPredefinedCursor(Cursor.HAND_CURSOR) );\n        setHorizontalAlignment( JLabel.LEFT );\n        addMouseListener(this);\n        setFocusable( true );\n\n        setMargin( new Insets(0, 0, 0, 0) );\n        setBorderPainted( false );\n        setFocusPainted( false );\n        setRolloverEnabled( true );\n        setContentAreaFilled( false );\n\n        addActionListener( this );\n        addFocusListener( this );\n    }\n\n    public void mouseClicked(MouseEvent e) {\n    }\n\n    public void mousePressed(MouseEvent e) {\n    }\n\n    public void mouseReleased(MouseEvent e) {\n    }\n\n    public void mouseEntered(MouseEvent e) {\n        if( isEnabled() ) {\n            underline = true;\n            setForeground( Utils.getColor(LINK_IN_FOCUS_COLOR) );\n            repaint();\n            onMouseEntered( e );\n            setForeground( Utils.getColor( MOUSE_OVER_LINK_COLOR  )  );\n        }\n    }\n\n    public void mouseExited(MouseEvent e) {\n        if( isEnabled() ) {\n            underline = false;\n            setForeground( Utils.getColor(isVisited() ? VISITED_LINK_COLOR : LINK_COLOR) );\n            repaint();\n            onMouseExited( e );\n        }\n    }\n\n    protected void paintComponent(Graphics g) {\n        Graphics2D g2 = Utils.prepareGraphics( g );\n        super.paintComponent(g2);\n\n        Dimension size = getSize();\n        if( hasFocus() && isEnabled() ) {\n            g2.setStroke( LINK_IN_FOCUS_STROKE );\n            g2.setColor( Utils.getColor(LINK_IN_FOCUS_COLOR) );\n            g2.drawRect( 0, 0, size.width - 1, size.height - 1 );\n        }\n    }\n    \n    public void focusLost(FocusEvent e) {\n    }\n\n    public void focusGained(FocusEvent e) {\n        Rectangle rect = getBounds();\n        rect.grow( 0, FONT_SIZE );\n        scrollRectToVisible( rect );\n    }\n\n    protected void onMouseExited(MouseEvent e) {\n    }\n\n    protected void onMouseEntered(MouseEvent e) {\n    }\n\n    @Override\n    public void paint(Graphics g) {\n        super.paint(g);\n        if( underline && isEnabled() ) {\n            Font f = getFont();\n            FontMetrics fm = getFontMetrics(f);\n            int iconWidth = 0;\n            if( null != getIcon() ) {\n                iconWidth = getIcon().getIconWidth()+getIconTextGap();\n            }\n            int x1 = iconWidth;\n            int y1 = fm.getHeight();\n            int x2 = fm.stringWidth(getText()) + iconWidth;\n            if (!getText().isEmpty())\n                g.drawLine(x1, y1, x2, y1);\n        }\n    }\n    \n    protected boolean isVisited() {\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/Logo.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.awt.BorderLayout;\nimport java.awt.Cursor;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author S. Aubrecht\n */\npublic class Logo extends JPanel implements Constants, MouseListener {\n\n    private String url;\n\n//    public static Logo createSunLogo() {\n//        return new Logo( SUN_LOGO_IMAGE, BundleSupport.getURL( \"SunLogo\" ) ); // NOI18N\n//    }\n//\n//    public static Logo createJavaLogo() {\n//        return new Logo( JAVA_LOGO_IMAGE, BundleSupport.getURL( \"JavaLogo\" ) ); // NOI18N\n//    }\n//\n    /** Creates a new instance of RecentProjects */\n    public Logo( String img, String url ) {\n        super( new BorderLayout() );\n        Icon image = new ImageIcon(ImageUtilities.loadImage(img, true));\n        JLabel label = new JLabel( image );\n        label.setBorder( BorderFactory.createEmptyBorder() );\n        label.setOpaque( false );\n        label.addMouseListener( this );\n        setOpaque( false );\n        add( label, BorderLayout.CENTER );\n        setCursor( Cursor.getPredefinedCursor(Cursor.HAND_CURSOR) );\n        this.url = url;\n    }\n\n    public void mouseClicked(MouseEvent e) {\n        Utils.showURL( url );\n    }\n\n    public void mousePressed(MouseEvent e) {\n    }\n\n    public void mouseReleased(MouseEvent e) {\n    }\n\n    public void mouseEntered(MouseEvent e) {\n//        StatusDisplayer.getDefault().setStatusText( url );\n    }\n\n    public void mouseExited(MouseEvent e) {\n//        StatusDisplayer.getDefault().setStatusText( null );\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/ShowNextTime.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport javax.swing.JCheckBox;\nimport javax.swing.JPanel;\n\n/**\n *\n * @author S. Aubrecht\n */\nclass ShowNextTime extends JPanel \n        implements ActionListener, Constants, PropertyChangeListener {\n\n    private JCheckBox button;\n\n    /** Creates a new instance of RecentProjects */\n    ShowNextTime() {\n        super( new BorderLayout() );\n\n        setOpaque( false );\n        \n        button = new JCheckBox( BundleSupport.getLabel( \"ShowOnStartup\" ) ); // NOI18N\n        button.setSelected( WelcomeOptions.getDefault().isShowOnStartup() );\n        button.setOpaque( false );\n        BundleSupport.setAccessibilityProperties( button, \"ShowOnStartup\" ); //NOI18N\n        add( button, BorderLayout.CENTER );\n        button.addActionListener( this );\n    }\n    \n    public void actionPerformed(ActionEvent e) {\n        WelcomeOptions.getDefault().setShowOnStartup( button.isSelected() );\n    }\n\n    @Override\n    public void addNotify() {\n        super.addNotify();\n        WelcomeOptions.getDefault().addPropertyChangeListener( this );\n    }\n\n    @Override\n    public void removeNotify() {\n        super.removeNotify();\n        WelcomeOptions.getDefault().removePropertyChangeListener( this );\n    }\n\n    public void propertyChange(PropertyChangeEvent evt) {\n        button.setSelected( WelcomeOptions.getDefault().isShowOnStartup() );\n    }\n    \n    \n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/ShowWelcomeAction.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.util.Set;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\nimport org.openide.util.actions.CallableSystemAction;\nimport org.openide.windows.TopComponent;\n\n/**\n * Show the welcome screen.\n * @author  Richard Gregor\n */\npublic class ShowWelcomeAction extends CallableSystemAction {\n\n    public ShowWelcomeAction() {\n        putValue(\"noIconInMenu\", Boolean.TRUE); // NOI18N\n    }\n\n    public void performAction() {\n        WelcomeComponent topComp = null;\n        Set<TopComponent> tcs = TopComponent.getRegistry().getOpened();\n        for (TopComponent tc: tcs) {\n            if (tc instanceof WelcomeComponent) {                \n                topComp = (WelcomeComponent) tc;               \n                break;\n            }\n        }\n        if(topComp == null){            \n            topComp = WelcomeComponent.findComp();\n        }\n       \n        topComp.open();\n        topComp.requestActive();\n    }\n    \n    public String getName() {\n        return NbBundle.getMessage(ShowWelcomeAction.class, \"LBL_Action\"); //NOI18N\n    }\n    \n    @Override protected String iconResource() {\n        return \"org/graalvm/visualvm/modules/appui/welcome/resources/welcome.gif\";  //NOI18N\n    }\n    \n    public HelpCtx getHelpCtx() {\n        return HelpCtx.DEFAULT_HELP;\n    }\n    \n    @Override protected boolean asynchronous(){\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/StartPageContent.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.uisupport.UISupport;\n\n/**\n *\n * @author S. Aubrecht\n */\npublic class StartPageContent extends JPanel implements Constants {\n\n    public StartPageContent() {\n        super( new GridBagLayout() );\n        \n        setBackground( !UISupport.isDarkResultsBackground() ?\n                       Utils.getColor( COLOR_SCREEN_BACKGROUND ) :\n                       Utils.getColor( COLOR_SCREEN_BACKGROUND_DARK ) );\n        setMinimumSize( new Dimension(START_PAGE_MIN_WIDTH,100) );\n        \n        add( new JLabel(), new GridBagConstraints(0,0,1,1,0.0,1.0,\n                GridBagConstraints.CENTER,GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0) );\n        add( createMainPanel(), new GridBagConstraints(0,1,1,1,0.0,0.0,\n                GridBagConstraints.CENTER,GridBagConstraints.NONE, new Insets(10,10,10,10), 0,0) );\n        add( new JLabel(), new GridBagConstraints(0,2,1,1,0.0,1.0,\n                GridBagConstraints.CENTER,GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0) );\n        add( new ShowNextTime(), new GridBagConstraints(0,3,1,1,0.0,0.0,\n                GridBagConstraints.SOUTH,GridBagConstraints.NONE, new Insets(10,10,20,10), 0,0) );\n    }\n    \n    private JComponent createMainPanel() {\n        JPanel res = new JPanel();\n        res.setOpaque(false);\n        res.setLayout(new BorderLayout());\n        \n        res.add(new CaptionPanel(), BorderLayout.NORTH);\n        res.add(new ContentsPanel(), BorderLayout.CENTER);\n        res.add(new FooterPanel(), BorderLayout.SOUTH);\n        \n        return res;\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/Utils.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.RenderingHints;\nimport java.awt.Toolkit;\nimport java.net.URL;\nimport java.util.Map;\nimport java.util.ResourceBundle;\nimport java.util.logging.Logger;\nimport javax.swing.JOptionPane;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.core.ui.DesktopUtils;\nimport org.graalvm.visualvm.modules.appui.AboutAction;\nimport org.openide.ErrorManager;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author S. Aubrecht\n */\npublic class Utils {\n    \n    private final static Logger LOGGER = Logger.getLogger(AboutAction.class.getName());\n    \n    /** Creates a new instance of Utils */\n    private Utils() {\n    }\n\n    public static Graphics2D prepareGraphics(Graphics g) {\n        Graphics2D g2 = (Graphics2D) g;\n        Map<?,?> rhints = (Map<?, ?>)(Toolkit.getDefaultToolkit().getDesktopProperty(\"awt.font.desktophints\")); //NOI18N\n        if( rhints == null && Boolean.getBoolean(\"swing.aatext\") ) { //NOI18N\n             g2.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON );\n        } else if( rhints != null ) {\n            g2.addRenderingHints( rhints );\n        }\n        return g2;\n    }\n\n    public static void showURL(String href) {\n        boolean opened = false;\n        \n        if (DesktopUtils.isBrowseAvailable()) {\n            try {\n                URL url = new URL(href);\n                DesktopUtils.browse(url.toURI());\n                opened = true;\n            } catch (Exception e) {\n                LOGGER.throwing(Utils.class.getName(), \"showURL\", e);\n            }\n        }\n        \n        if (!opened)\n            JOptionPane.showMessageDialog(null, \"<html><b>Unable to launch web browser.</b><br><br>\" + \n                    \"Please open the following link manually:<br><code>\" + href +\n                    \"</code></html>\", \"Unable To Launch Web Browser\", JOptionPane.ERROR_MESSAGE);\n    }\n\n    static int getDefaultFontSize() {\n        Integer customFontSize = (Integer)UIManager.get(\"customFontSize\"); // NOI18N\n        if (customFontSize != null) {\n            return customFontSize.intValue();\n        } else {\n            Font systemDefaultFont = UIManager.getFont(\"TextField.font\"); // NOI18N\n            return (systemDefaultFont != null)\n                ? systemDefaultFont.getSize()\n                : 12;\n        }\n    }\n\n    public static Color getColor( String resId ) {\n        ResourceBundle bundle = NbBundle.getBundle(\"org.graalvm.visualvm.modules.appui.welcome.resources.Bundle\"); // NOI18N\n        try {\n            Integer rgb = Integer.decode(bundle.getString(resId));\n            return new Color(rgb.intValue());\n        } catch( NumberFormatException nfE ) {\n            ErrorManager.getDefault().notify( ErrorManager.INFORMATIONAL, nfE );\n            return Color.BLACK;\n        }\n    }\n\n    /**\n     * Try to extract the URL from the given DataObject using reflection.\n     * (The DataObject should be URLDataObject in most cases)\n     */\n//    public static String getUrlString(DataObject dob) {\n//        try {\n//            Method m = dob.getClass().getDeclaredMethod( \"getURLString\", new Class[] {} ); //NOI18N\n//            m.setAccessible( true );\n//            Object res = m.invoke( dob );\n//            if( null != res ) {\n//                return res.toString();\n//            }\n//        } catch (Exception ex) {\n//            //ignore\n//        }\n//        return null;\n//    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/WebLink.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.awt.Frame;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseEvent;\nimport org.openide.awt.StatusDisplayer;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author S. Aubrecht\n */\npublic class WebLink extends LinkButton {\n\n    private static String sourceId;\n    private String url;\n    private boolean includeSource;\n\n    /** Creates a new instance of WebLink */\n    public WebLink( String key ) {\n        this( BundleSupport.getLabel( key ), BundleSupport.getURL( key ), true );\n    }\n    \n    public WebLink( String key, boolean includeSource ) {\n        this( BundleSupport.getLabel( key ), BundleSupport.getURL( key ), includeSource );\n    }\n    \n    public WebLink( String label, String url, boolean includeSource ) {\n        super( label );\n        this.url = url;\n        this.includeSource = includeSource;\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        Utils.showURL( includeSource ? url + getSourceId() : url );\n    }\n    \n    @Override\n    protected void onMouseExited(MouseEvent e) {\n        StatusDisplayer.getDefault().setStatusText( \"\" );\n    }\n\n    @Override\n    protected void onMouseEntered(MouseEvent e) {\n        StatusDisplayer.getDefault().setStatusText( url );\n    }\n    \n    private static synchronized String getSourceId() {\n        if (sourceId == null) {\n            Frame mainWindow = WindowManager.getDefault().getMainWindow();\n            if (mainWindow == null) sourceId = \"VisualVM (Unknown Version)\"; // NOI18N\n            else {\n                String sourceName = mainWindow.getTitle();\n                if (sourceName == null) sourceId = \"VisualVM (Unknown Version)\"; // NOI18N\n                else sourceId = \"?\" + sourceName.trim().replace(\" \", \"_\"); // NOI18N\n            }\n        }\n        \n        return sourceId;\n    }\n}\n\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/WelcomeComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.awt.BorderLayout;\nimport java.lang.ref.WeakReference;\nimport javax.swing.JComponent;\nimport org.openide.ErrorManager;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.TopComponent;\nimport org.openide.windows.WindowManager;\n\n/**\n * The welcome screen.\n * @author  Richard Gregor, S. Aubrecht\n */\npublic class WelcomeComponent extends TopComponent {\n    static final long serialVersionUID=6021472310161712674L;\n    private static final String PREFERRED_ID = \"VisualVMWelcome\";   //NOI18N\n    private static WeakReference<WelcomeComponent> component = new WeakReference<>(null);\n    private JComponent content;\n\n    private boolean initialized = false;\n    \n    private WelcomeComponent(){\n        setLayout(new BorderLayout());\n        setName(NbBundle.getMessage(WelcomeComponent.class, \"LBL_Tab_Title\"));   //NOI18N\n        content = null;\n        initialized = false;\n        putClientProperty( \"activateAtStartup\", Boolean.TRUE ); //NOI18N\n    }\n    \n    @Override protected String preferredID(){\n        return PREFERRED_ID;    //NOI18N\n    }\n    \n    /**\n     * #38900 - lazy addition of GUI components\n     */    \n    \n    private void doInitialize() {\n        initAccessibility();\n        \n        if( null == content ) {\n            content = new StartPageContent();\n\n            add( content, BorderLayout.CENTER );\n            setFocusable( false );\n        }\n    }\n        \n    /* Singleton accessor. As WelcomeComponent is persistent singleton this\n     * accessor makes sure that WelcomeComponent is deserialized by window system.\n     * Uses known unique TopComponent ID \"VisualVMWelcome\" to get WelcomeComponent instance\n     * from window system. \"VisualVMWelcome\" is name of settings file defined in module layer.\n     */\n    public static synchronized WelcomeComponent findComp() {\n        WelcomeComponent wc = component.get();\n        if (wc == null) {\n            TopComponent tc = WindowManager.getDefault().findTopComponent(PREFERRED_ID); // NOI18N\n            if (tc != null) {\n                if (tc instanceof WelcomeComponent) {\n                    wc = (WelcomeComponent)tc;\n                    component = new WeakReference<>(wc);\n                } else {\n                    //Incorrect settings file?\n                    IllegalStateException exc = new IllegalStateException\n                    (\"Incorrect settings file. Unexpected class returned.\" // NOI18N\n                    + \" Expected:\" + WelcomeComponent.class.getName() // NOI18N\n                    + \" Returned:\" + tc.getClass().getName()); // NOI18N\n                    ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, exc);\n                    //Fallback to accessor reserved for window system.\n                    wc = WelcomeComponent.createComp();\n                }\n            } else {\n                //WelcomeComponent cannot be deserialized\n                //Fallback to accessor reserved for window system.\n                wc = WelcomeComponent.createComp();\n            }\n        }       \n        return wc;\n    }\n    \n    /* Singleton accessor reserved for window system ONLY. Used by window system to create\n     * WelcomeComponent instance from settings file when method is given. Use <code>findComp</code>\n     * to get correctly deserialized instance of WelcomeComponent. */\n    public static synchronized  WelcomeComponent createComp() {\n        WelcomeComponent wc = component.get();\n        if(wc == null) {\n            wc = new WelcomeComponent();\n            component = new WeakReference<>(wc);\n        }\n        return wc;\n    }\n    \n    /** Overridden to explicitly set persistence type of WelcomeComponent\n     * to PERSISTENCE_ALWAYS */\n    @Override public int getPersistenceType() {\n        return TopComponent.PERSISTENCE_NEVER;\n    }\n    \n    private void initAccessibility(){\n        getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(WelcomeComponent.class, \"ACS_Welcome_DESC\")); // NOI18N\n    }\n\n    /**\n     * Called when <code>TopComponent</code> is about to be shown.\n     * Shown here means the component is selected or resides in it own cell\n     * in container in its <code>Mode</code>. The container is visible and not minimized.\n     * <p><em>Note:</em> component\n     * is considered to be shown, even its container window\n     * is overlapped by another window.</p>\n     * @since 2.18\n     *\n     * #38900 - lazy addition of GUI components\n     *\n     */\n    @Override protected void componentShowing() {\n        if (!initialized) {\n            initialized = true;\n            doInitialize();\n        }\n        if( null != content && getComponentCount() == 0 ) {\n            //notify components down the hierarchy tree that they should \n            //refresh their content (e.g. RSS feeds)\n            add( content, BorderLayout.CENTER );\n        }\n        super.componentShowing();\n//        setActivatedNodes( new Node[] {} );\n    }\n\n    private static boolean firstTimeOpen = true;\n    @Override \n    protected void componentOpened() {\n        super.componentOpened();\n        if( firstTimeOpen ) {\n            firstTimeOpen = false;\n            if( !WelcomeOptions.getDefault().isShowOnStartup() ) {\n                close();\n            }\n        }\n    }\n    \n    @Override protected void componentHidden() {\n        super.componentHidden();\n        if( null != content ) {\n            //notify components down the hierarchy tree that they no long \n            //need to periodically refresh their content (e.g. RSS feeds)\n            remove( content );\n        }\n    }\n\n    @Override\n    public void requestFocus() {\n        if( null != content )\n            content.requestFocus();\n    }\n\n    @Override\n    public boolean requestFocusInWindow() {\n        if( null != content )\n            return content.requestFocusInWindow();\n        return super.requestFocusInWindow();\n    }\n}\n\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/WelcomeOptions.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.appui.welcome;\n\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport java.util.prefs.Preferences;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author S. Aubrecht\n */\npublic class WelcomeOptions {\n\n    private static WelcomeOptions theInstance;\n    \n    private static final String PROP_SHOW_ON_STARTUP = \"showOnStartup\";\n    \n    private PropertyChangeSupport propSupport;\n    \n    /** Creates a new instance of WelcomeOptions */\n    private WelcomeOptions() {\n    }\n\n    private Preferences prefs() {\n        return NbPreferences.forModule(WelcomeOptions.class);\n    }\n\n    public static synchronized WelcomeOptions getDefault() {\n        if( null == theInstance ) {\n            theInstance = new WelcomeOptions();\n        }\n        return theInstance;\n    }\n \n    public void setShowOnStartup( boolean show ) {\n        boolean oldVal = isShowOnStartup();\n        prefs().putBoolean(PROP_SHOW_ON_STARTUP, show);\n        if( null != propSupport )\n            propSupport.firePropertyChange( PROP_SHOW_ON_STARTUP, oldVal, show );\n    }\n\n    public boolean isShowOnStartup() {\n        return prefs().getBoolean(PROP_SHOW_ON_STARTUP, true);\n    }\n    \n    public void addPropertyChangeListener( PropertyChangeListener l ) {\n        if( null == propSupport )\n            propSupport = new PropertyChangeSupport( this );\n        propSupport.addPropertyChangeListener( l );\n    }\n    \n    public void removePropertyChangeListener( PropertyChangeListener l ) {\n        if( null == propSupport )\n            return;\n        propSupport.removePropertyChangeListener( l );\n    }\n}\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/resources/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n#\n# Other\n#\nLBL_ShowOnStartup=Show On Startup\nACN_ShowOnStartup=Show Welcome Screen on startup\nACD_ShowOnStartup=Checkbox to show or hide the Welcome Screen on next NetBeans startup\n\n\nLBL_Link1=VisualVM Home\nURL_Link1=https://visualvm.github.io\n\nLBL_Link2=GraalVM Home\nURL_Link2=https://www.graalvm.org\n\nLBL_Link3=Getting Started with VisualVM\nURL_Link3=https://visualvm.github.io/gettingstarted.html\n\nLBL_Link4=Getting Started with GraalVM\nURL_Link4=https://www.graalvm.org/docs/getting-started\n\nLBL_Link5=VisualVM Troubleshooting Guide\nURL_Link5=https://visualvm.github.io/troubleshooting.html\n\nLBL_Link6=GraalVM Reference Manual\nURL_Link6=https://www.graalvm.org/docs/reference-manual\n\nLBL_Link7=Getting Started Extending VisualVM\nURL_Link7=https://visualvm.github.io/extending.html\n\nLBL_Link8=GraalVM Tools Reference\nURL_Link8=https://www.graalvm.org/docs/tools\n\n\nURL_OracleLogo=http://www.oracle.com\n#\n# Colors\n#\nScreenBackgroundColor=0xa9c7de\nScreenBackgroundColorDark=0x325067\nContentBackgroundColor=0xeff7fb\nMouseOverLinkColor=0xe76f00\nBorderColor=0x5B83A9\n\n# links & buttons\nButtonTextColor=0x164B7B\n# default text color in RSS panels\nDefaultTextColor=0x000000\n# mouse-over link color\nLinkInFocusColor=0x000000\n# links in RSS feed panels\nLinkColor=0x35556b\n# visited link color\nVisitedLinkColor=0x5591D2\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/resources/VisualVMWelcome.settings",
    "content": "<?xml version=\"1.0\"?>\n<!DOCTYPE settings PUBLIC \"-//NetBeans//DTD Session settings 1.0//EN\" \"http://www.netbeans.org/dtds/sessionsettings-1_0.dtd\">\n<settings version=\"1.0\">\n    <module name=\"org.graalvm.visualvm.modules.appui/1\" spec=\"1.5\"/>\n    <instanceof class=\"javax.accessibility.Accessible\"/>\n    <instanceof class=\"java.awt.image.ImageObserver\"/>\n    <instanceof class=\"javax.swing.JComponent\"/>\n    <instanceof class=\"org.openide.windows.TopComponent\"/>\n    <instanceof class=\"org.graalvm.visualvm.modules.appui.welcome.WelcomeComponent\"/>\n    <instanceof class=\"java.awt.Component\"/>\n    <instanceof class=\"java.io.Externalizable\"/>\n    <instanceof class=\"java.awt.Container\"/>\n    <instanceof class=\"java.io.Serializable\"/>\n    <instanceof class=\"java.awt.MenuContainer\"/>\n    <instanceof class=\"java.lang.Object\"/>\n    <instance class=\"org.graalvm.visualvm.modules.appui.welcome.WelcomeComponent\" method=\"createComp\"/>\n</settings>\n"
  },
  {
    "path": "visualvm/appui/src/org/graalvm/visualvm/modules/appui/welcome/resources/VisualVMWelcome.wstcref",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!DOCTYPE tc-ref PUBLIC\n          \"-//NetBeans//DTD Top Component in Mode Properties 2.0//EN\"\n          \"http://www.netbeans.org/dtds/tc-ref2_0.dtd\">\n\n<tc-ref version=\"2.0\" id=\"VisualVMWelcome\">\n    <module name=\"org.graalvm.visualvm.modules.appui\" />\n    <tc-id id=\"VisualVMWelcome\" />\n    <state opened=\"true\" />\n</tc-ref>\n"
  },
  {
    "path": "visualvm/attach/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.attach\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.attach.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/attach/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.attach/2\nOpenIDE-Module-Install: org/graalvm/visualvm/attach/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/attach/Bundle.properties\nOpenIDE-Module-Provides: org.graalvm.visualvm.attach\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "visualvm/attach/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.attach-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/attach/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=6509c9a4\nbuild.xml.script.CRC32=f89d246c\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=6509c9a4\nnbproject/build-impl.xml.script.CRC32=9db097dd\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/attach/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\njavac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\ncp.extra=${tools.jar}\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nmodule.javadoc.packages=org.graalvm.visualvm.attach\n\n"
  },
  {
    "path": "visualvm/attach/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.attach</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/attach/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/attach/src/org/graalvm/visualvm/attach/AttachModelImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.attach;\n\nimport com.sun.tools.attach.VirtualMachine;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.attach.AttachModel;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.LinkOption;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.TimeoutException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.SwingUtilities;\nimport org.openide.util.Utilities;\nimport sun.tools.attach.HotSpotVirtualMachine;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass AttachModelImpl extends AttachModel {\n    private static final String LIVE_OBJECTS_OPTION = \"-live\";  // NOI18N\n    static final String ALL_OBJECTS_OPTION = \"-all\";    // NOI18N\n    private static final String HEAP_DUMP_NO_SPACE_ID = \"No space left on device\";  // NOI18N\n    private static final String JCMD_VM_COMMAND_LINE = \"VM.command_line\";    // NOI18N\n    static final Logger LOGGER = Logger.getLogger(AttachModelImpl.class.getName());\n    private static final ExecutorService winExec = Executors.newCachedThreadPool();\n\n    String pid;\n    HotSpotVirtualMachine vm;\n    Map<String,String> commandLineMap;\n    \n    AttachModelImpl(Application app) {\n        pid = Integer.toString(app.getPid());\n    }\n    \n    // see JmxModelImpl$LocalVirtualMachine.executeAndWait\n    private static <V> V executeAndWait(Callable<V> call) {\n        if (Utilities.isWindows()) {\n            Future<V> result = winExec.submit(call);\n            try {\n                return result.get(SwingUtilities.isEventDispatchThread() ? 5 : 25, TimeUnit.SECONDS);\n            } catch (InterruptedException | ExecutionException | TimeoutException ex) {\n                LOGGER.log(Level.INFO, \"executeAndWait get\", ex);    // NOI18N\n            }\n            return null;\n        }\n        try {\n            return call.call();\n        } catch (Exception ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n\n    public synchronized Properties getSystemProperties() {\n        return executeAndWait(() -> {\n            try {\n                return getVirtualMachine().getSystemProperties();\n            } catch (IOException ex) {\n                LOGGER.log(Level.INFO,\"getSystemProperties\",ex);    // NOI18N\n            }\n            return null;\n        });\n    }\n    \n    public synchronized boolean takeHeapDump(String fileName) {\n        try {\n            InputStream in = getVirtualMachine().dumpHeap(fileName,LIVE_OBJECTS_OPTION);\n            String out = readToEOF(in);\n            if (!out.isEmpty()) {\n                LOGGER.log(Level.INFO,\"takeHeapDump: {0}\", out);  // NOI18N\n            }\n            Path f = Paths.get(fileName);\n            if (out.contains(HEAP_DUMP_NO_SPACE_ID)) {\n                Files.deleteIfExists(f);\n                return false;\n            }\n            return Files.isRegularFile(f, LinkOption.NOFOLLOW_LINKS) && Files.isReadable(f);\n        } catch (IOException ex) {\n            LOGGER.log(Level.INFO,\"takeHeapDump\",ex);   // NOI18N\n        }\n        return false;\n    }\n    \n    public synchronized String takeThreadDump() {\n        try {\n            InputStream in = getVirtualMachine().remoteDataDump(\"-l\");  // NOI18N\n            return readToEOF(in);\n        } catch (IOException ex) {\n            LOGGER.log(Level.INFO,\"takeThreadDump\",ex);     // NOI18N\n        }\n        return null;\n    }\n    \n    public synchronized String printFlag(String name) {\n        try {\n            InputStream in = getVirtualMachine().printFlag(name);\n            return readToEOF(in);\n        } catch (IOException ex) {\n            LOGGER.log(Level.INFO,\"printFlag\",ex);  // NOI18N\n        }\n        return null;\n    }\n    \n    public synchronized void setFlag(String name, String value) {\n        try {\n            InputStream in = getVirtualMachine().setFlag(name,value);\n            String out = readToEOF(in);\n            if (!out.isEmpty()) {\n                LOGGER.log(Level.INFO,\"setFlag: {0}\",out);   // NOI18N\n            }\n        } catch (IOException ex) {\n            LOGGER.log(Level.INFO,\"setFlag\",ex);    // NOI18N\n        }\n    }\n\n    public synchronized HeapHistogramImpl takeHeapHistogram() {\n        try (InputStream in = getVirtualMachine().heapHisto(ALL_OBJECTS_OPTION)) {\n            return new HeapHistogramImpl(in);\n        } catch (IOException ex) {\n            LOGGER.log(Level.INFO,\"takeHeapHistogram\",ex);  // NOI18N\n        }\n        return null;\n    }\n\n    public String getCommandLine() {\n        Map<String,String> cmdLineMap = getVMCommandLine();\n        if (cmdLineMap != null) {\n            return cmdLineMap.get(\"java_command\");      // NOI18N\n        }\n        return null;\n    }\n    \n    public String getJvmArgs() {\n        Map<String,String> cmdLineMap = getVMCommandLine();\n        if (cmdLineMap != null) {\n            return cmdLineMap.get(\"jvm_args\");          // NOI18N\n        }\n        return null;\n    }\n\n    public String getJvmFlags() {\n        Map<String,String> cmdLineMap = getVMCommandLine();\n        if (cmdLineMap != null) {\n            return cmdLineMap.get(\"jvm_flags\");         // NOI18N\n        }\n        return null;\n    }\n\n    HotSpotVirtualMachine getVirtualMachine() throws IOException {\n        if (vm == null) {\n            try {\n                vm = (HotSpotVirtualMachine) VirtualMachine.attach(pid);\n            } catch (Exception x) {\n                throw new IOException(x.getLocalizedMessage(),x);\n            }\n        }\n        return vm;\n    }\n    \n    public String executeJCmd(String command, Map<String,Object> pars) {\n        StringBuilder commandLine = new StringBuilder(command);\n\n        for (Map.Entry<String,Object> e : pars.entrySet()) {\n            String par;\n            String key = e.getKey();\n            Object val = e.getValue();\n\n            if (val == null) {\n                par = key;\n            } else {\n                par = String.format(\"%s=%s\", key, quoteString(val.toString())); // NOI18N\n            }\n            commandLine.append(' ').append(par);\n        }\n        return executeJCmd(commandLine.toString().trim());\n    }\n\n    private static String quoteString(String val) {\n        if (val.indexOf(' ')>=0) {\n            return \"\\\"\"+val+\"\\\"\";   //NOI18N\n        }\n        return val;\n    }\n\n    private synchronized Map<String,String> getVMCommandLine() {\n        if (commandLineMap == null) {\n            String text = executeJCmd(JCMD_VM_COMMAND_LINE);\n            commandLineMap = new HashMap<>();\n            if (text != null) {\n                String[] lines = text.split(\"\\\\R\"); // NOI18N\n                for (String line : lines) {\n                    int offset = line.indexOf(':');     // NOI18N\n                    if (offset != -1) {\n                        String key = line.substring(0, offset).trim();\n                        String value = line.substring(offset+1).trim();\n                        commandLineMap.put(key, value);\n                    }\n                }\n            }\n        }\n        return commandLineMap;\n    }\n\n    private synchronized String executeJCmd(String command) {\n        return executeAndWait(() -> {\n            try {\n                InputStream in = getVirtualMachine().executeJCmd(command);\n                return readToEOF(in);\n            } catch (IOException ex) {\n                LOGGER.log(Level.INFO, \"executeJCmd\", ex);    // NOI18N\n            }\n            return null;\n        });\n    }\n\n    private String readToEOF(InputStream in) throws IOException {\n        StringBuilder buffer = new StringBuilder(1024);\n        byte b[] = new byte[256];\n        int n;\n        \n        do {\n            n = in.read(b);\n            if (n > 0) {\n                String s = new String(b, 0, n, StandardCharsets.UTF_8);    // NOI18N\n                \n                buffer.append(s);\n            }\n        } while (n > 0);\n        in.close();\n        return buffer.toString();\n    }\n\n    protected void finalize() throws Throwable {\n        if (vm != null) vm.detach();\n        super.finalize();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/attach/src/org/graalvm/visualvm/attach/AttachModelProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.attach;\n\nimport com.sun.tools.attach.VirtualMachine;\nimport com.sun.tools.attach.VirtualMachineDescriptor;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.tools.attach.AttachModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory;\nimport org.openide.util.Utilities;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic final class AttachModelProvider extends AbstractModelProvider<AttachModel, Application>  {\n    \n    AttachModelProvider() {\n    }\n    \n    public AttachModel createModelFor(Application app) {\n        if (app.isLocalApplication()) {\n            JvmJvmstatModel jvmstat = JvmJvmstatModelFactory.getJvmstatModelFor(app);\n            \n            if (jvmstat != null && jvmstat.isAttachable()) {\n                if (Utilities.isWindows()) {\n                    // on Windows Attach API can only attach to the process of the same\n                    // architecture ( 32bit / 64bit )\n                    Boolean this64bitArch = is64BitArchitecture();\n                    Boolean app64bitArch = is64BitArchitecture(jvmstat);\n                    if (this64bitArch != null && app64bitArch != null) {\n                        if (!this64bitArch.equals(app64bitArch)) {\n                            return null;\n                        }\n                    }\n                }\n                // check that application is running under the same user as VisualVM\n                String pid = String.valueOf(app.getPid());\n                for (VirtualMachineDescriptor descr : VirtualMachine.list()) {\n                    if (pid.equals(descr.id())) {\n                        String vmName = jvmstat.getVmName();\n                        if (vmName != null) {\n                            if (\"BEA JRockit(R)\".equals(vmName)) {  // NOI18N\n                                return new JRockitAttachModelImpl(app);\n                            }\n                            if (\"Oracle JRockit(R)\".equals(vmName)) {  // NOI18N\n                                return new OracleJRockitAttachModelImpl(app);\n                            }                            \n                        }\n                        return new AttachModelImpl(app);\n                    }\n                }\n            }\n        }\n        return null;\n    }\n    \n    private static Boolean is64BitArchitecture(JvmJvmstatModel jvmstat) {\n        String name = jvmstat.getVmName();\n        if (name != null) {\n            return name.toLowerCase().contains(\"64-bit\");   // NOI18N\n        }\n        return null;\n    }\n    \n    private static Boolean is64BitArchitecture() {\n        String thisArch = System.getProperty(\"sun.arch.data.model\");    // NOI18N\n        if (thisArch != null) {\n            return Boolean.valueOf(\"64\".equals(thisArch));  // NOI18N\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/attach/src/org/graalvm/visualvm/attach/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Attach\n"
  },
  {
    "path": "visualvm/attach/src/org/graalvm/visualvm/attach/HeapHistogramImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.attach;\n\nimport org.graalvm.visualvm.application.jvm.HeapHistogram;\nimport java.io.InputStream;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Scanner;\nimport java.util.Set;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HeapHistogramImpl extends HeapHistogram {\n    private static final String BOOLEAN_TEXT = \"boolean\"; // NOI18N\n    private static final String CHAR_TEXT = \"char\"; // NOI18N\n    private static final String BYTE_TEXT = \"byte\"; // NOI18N\n    private static final String SHORT_TEXT = \"short\"; // NOI18N\n    private static final String INT_TEXT = \"int\"; // NOI18N\n    private static final String LONG_TEXT = \"long\"; // NOI18N\n    private static final String FLOAT_TEXT = \"float\"; // NOI18N\n    private static final String DOUBLE_TEXT = \"double\"; // NOI18N\n    private static final String VOID_TEXT = \"void\"; // NOI18N\n    private static final char BOOLEAN_CODE = 'Z'; // NOI18N\n    private static final char CHAR_CODE = 'C'; // NOI18N\n    private static final char BYTE_CODE = 'B'; // NOI18N\n    private static final char SHORT_CODE = 'S'; // NOI18N\n    private static final char INT_CODE = 'I'; // NOI18N\n    private static final char LONG_CODE = 'J'; // NOI18N\n    private static final char FLOAT_CODE = 'F'; // NOI18N\n    private static final char DOUBLE_CODE = 'D'; // NOI18N\n    private static final char OBJECT_CODE = 'L'; // NOI18N\n    private static final Map<String,String> permGenNames = new HashMap<>();\n    static {\n        permGenNames.put(\"<methodKlass>\",\"Read-Write Method Metadata\");      // NOI18N\n        permGenNames.put(\"<constMethodKlass>\",\"Read-Only Method Metadata\");     // NOI18N\n        permGenNames.put(\"<methodDataKlass>\",\"Method Profiling Information\");     // NOI18N\n        permGenNames.put(\"<constantPoolKlass>\",\"Constant Pool Metadata\");     // NOI18N\n        permGenNames.put(\"<constantPoolCacheKlass>\",\"Class Resolution Optimization Metadata\");     // NOI18N\n        permGenNames.put(\"<symbolKlass>\",\"VM Symbol Metadata\");     // NOI18N\n        permGenNames.put(\"<compiledICHolderKlass>\",\"Inline Cache Metadata\");     // NOI18N\n        permGenNames.put(\"<instanceKlassKlass>\",\"Instance Class Metadata\");     // NOI18N\n        permGenNames.put(\"<objArrayKlassKlass>\",\"Object Array Class Metadata\");     // NOI18N\n        permGenNames.put(\"<typeArrayKlassKlass>\",\"Scalar Array Class Metadata\");     // NOI18N\n        permGenNames.put(\"<klassKlass>\",\"Base Class Metadata\");     // NOI18N\n        permGenNames.put(\"<arrayKlassKlass>\",\"Base Array Class Metadata\");     // NOI18N\n    }\n    Set<ClassInfo> classes;\n    Set<ClassInfo> permGenClasses;\n    Date time;\n    long totalBytes;\n    long totalInstances;\n    long totalHeapBytes;\n    long totalHeapInstances;\n    long totalPermGenBytes;\n    long totalPermgenInstances;\n    \n    HeapHistogramImpl() {\n    }\n    \n    HeapHistogramImpl(InputStream in) {\n        Map<String,ClassInfoImpl> classesMap = new HashMap<>(1024);\n        Map<String,ClassInfoImpl> permGenMap = new HashMap<>(1024);\n        time = new Date();\n        Scanner sc = new Scanner(in, \"UTF-8\");  // NOI18N\n        sc.useRadix(10);\n        while(!sc.hasNext(\"-+\")) {\n            sc.nextLine();\n        }\n        sc.skip(\"-+\");\n        sc.nextLine();\n\n        \n        while(sc.hasNext(\"[0-9]+:\")) {  // NOI18N\n            ClassInfoImpl newClInfo = new ClassInfoImpl(sc);\n            if (newClInfo.isPermGen()) {\n                storeClassInfo(newClInfo, permGenMap);\n                totalPermGenBytes += newClInfo.getBytes();\n                totalPermgenInstances += newClInfo.getInstancesCount();\n            } else {\n                storeClassInfo(newClInfo, classesMap);\n                totalHeapBytes += newClInfo.getBytes();\n                totalHeapInstances += newClInfo.getInstancesCount();                \n            }\n        }\n        sc.next(\"Total\");   // NOI18N\n        totalInstances = sc.nextLong();\n        totalBytes = sc.nextLong();\n        classes = new HashSet<>(classesMap.values());\n        permGenClasses = new HashSet<>(permGenMap.values());\n    }\n\n    void storeClassInfo(final ClassInfoImpl newClInfo, final Map<String, ClassInfoImpl> map) {\n        ClassInfoImpl oldClInfo = map.get(newClInfo.getName());\n        if (oldClInfo == null) {\n            map.put(newClInfo.getName(),newClInfo);\n        } else {\n            oldClInfo.bytes += newClInfo.getBytes();\n            oldClInfo.instances += newClInfo.getInstancesCount();               \n        }\n    }\n    \n    public Date getTime() {\n        return (Date) time.clone();\n    }\n    \n    public Set<ClassInfo> getHeapHistogram() {\n        return classes;\n    }\n    \n    public long getTotalInstances() {\n        return totalInstances;\n    }\n    \n    public long getTotalBytes() {\n        return totalBytes;\n    }\n\n    public long getTotalHeapInstances() {\n        return totalHeapInstances;\n    }\n\n    public long getTotalHeapBytes() {\n        return totalHeapBytes;\n    }\n\n    public Set<ClassInfo> getPermGenHistogram() {\n        return permGenClasses;\n    }\n\n    public long getTotalPerGenInstances() {\n        return totalPermgenInstances;\n    }\n\n    public long getTotalPermGenHeapBytes() {\n        return totalPermGenBytes;\n    }\n    \n    static class ClassInfoImpl extends ClassInfo {\n        long instances;\n        long bytes;\n        String name;\n        boolean permGen;\n        \n        ClassInfoImpl() {\n        }\n        \n        ClassInfoImpl(Scanner sc) {\n            String jvmName;\n            \n            sc.next();\n            instances = sc.nextLong();\n            bytes = sc.nextLong();\n            jvmName = sc.next();\n            sc.nextLine();  // skip module name on JDK 9\n            permGen = jvmName.charAt(0) == '<';     // NOI18N\n            name = convertJVMName(jvmName);\n        }\n        \n        public String getName() {\n            return name;\n        }\n        \n        public long getInstancesCount() {\n            return instances;\n        }\n        \n        public long getBytes() {\n            return bytes;\n        }\n\n\n        public int hashCode() {\n            return getName().hashCode();\n        }\n\n        public boolean equals(Object obj) {\n            if (obj instanceof ClassInfoImpl) {\n                return getName().equals(((ClassInfoImpl)obj).getName());\n            }\n            return false;\n        }\n\n\n        private boolean isPermGen() {\n            return permGen;\n        }\n        \n        String convertJVMName(String jvmName) {\n            String name = null;\n            int index = jvmName.lastIndexOf('[');     // NOI18N\n            \n            if (index != -1) {\n                switch(jvmName.charAt(index+1)) {\n                    case BOOLEAN_CODE:\n                        name=BOOLEAN_TEXT;\n                        break;\n                    case CHAR_CODE:\n                        name=CHAR_TEXT;\n                        break;\n                    case BYTE_CODE:\n                        name=BYTE_TEXT;\n                        break;\n                    case SHORT_CODE:\n                        name=SHORT_TEXT;\n                        break;\n                    case INT_CODE:\n                        name=INT_TEXT;\n                        break;\n                    case LONG_CODE:\n                        name=LONG_TEXT;\n                        break;\n                    case FLOAT_CODE:\n                        name=FLOAT_TEXT;\n                        break;\n                    case DOUBLE_CODE:\n                        name=DOUBLE_TEXT;\n                        break;\n                    case OBJECT_CODE:\n                        name=jvmName.substring(index+2,jvmName.length()-1);\n                        break;\n                    default:\n                        System.err.println(\"Unknown name \"+jvmName);     // NOI18N\n                        name = jvmName;\n                }\n                for (int i=0;i<=index;i++) {\n                    name+=\"[]\";\n                }\n            } else if (isPermGen()) {\n                name = permGenNames.get(jvmName);\n            }\n            if (name == null) {\n                name = jvmName;\n            }\n            return name.intern();\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/attach/src/org/graalvm/visualvm/attach/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.attach;\n\nimport org.graalvm.visualvm.tools.attach.AttachModelFactory;\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\nfinal class Installer extends ModuleInstall {\n    \n    public void restored() {\n        AttachModelFactory.getDefault().registerProvider(new AttachModelProvider());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/attach/src/org/graalvm/visualvm/attach/JRockitAttachModelImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.attach;\n\nimport org.graalvm.visualvm.application.Application;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JRockitAttachModelImpl extends OracleJRockitAttachModelImpl {\n    \n    JRockitAttachModelImpl(Application app) {\n        super(app);\n    }\n \n    public synchronized boolean takeHeapDump(String fileName) {\n        return false;\n    }   \n}\n\n"
  },
  {
    "path": "visualvm/attach/src/org/graalvm/visualvm/attach/JRockitHeapHistogramImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.attach;\n\nimport java.io.InputStream;\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Scanner;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JRockitHeapHistogramImpl extends HeapHistogramImpl {\n    \n    JRockitHeapHistogramImpl(InputStream in) {\n        Map<String,ClassInfoImpl> classesMap = new HashMap<>(1024);\n        time = new Date();\n        Scanner sc = new Scanner(in, \"UTF-8\");  // NOI18N\n        sc.useRadix(10);\n        sc.nextLine();\n        sc.skip(\"-+\");\n        sc.nextLine();\n\n        while(sc.hasNext(\"[0-9]+\\\\.[0-9]%\")) {  // NOI18N\n            JRockitClassInfoImpl newClInfo = new JRockitClassInfoImpl(sc);\n            storeClassInfo(newClInfo, classesMap);\n            totalHeapBytes += newClInfo.getBytes();\n            totalHeapInstances += newClInfo.getInstancesCount();                \n        }\n        totalInstances = totalHeapInstances;\n        totalBytes = totalHeapBytes;\n        classes = new HashSet<>(classesMap.values());\n        permGenClasses = Collections.emptySet();\n    }\n        \n    static class JRockitClassInfoImpl extends ClassInfoImpl {\n        \n        JRockitClassInfoImpl(Scanner sc) {\n            String jvmName;\n            \n            sc.next();  // skip unused 99.9%\n            bytes = computeBytes(sc.next());\n            instances = sc.nextLong();\n            sc.next(); // diff unused\n            jvmName = sc.next();\n            name = convertJVMName(jvmName.replace('/','.'));     // NOI18N\n        }\n\n        private long computeBytes(String size) {\n            String multi = size.substring(size.length()-1);\n            long bytes = Long.parseLong(size.substring(0,size.length()-1));\n            if (\"K\".equalsIgnoreCase(multi)) {  // NOI18N\n                bytes*=1024;\n            } else if (\"M\".equalsIgnoreCase(multi)) {   // NOI18N\n                bytes*=1024*1024;\n            } else if (\"G\".equalsIgnoreCase(multi)) {   // NOI18N\n                bytes*=1024*1024*1024L;\n            }\n            return bytes;\n        }\n\n    }\n}\n"
  },
  {
    "path": "visualvm/attach/src/org/graalvm/visualvm/attach/OracleJRockitAttachModelImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.attach;\n\nimport org.graalvm.visualvm.application.Application;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.logging.Level;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass OracleJRockitAttachModelImpl extends AttachModelImpl {\n    \n    OracleJRockitAttachModelImpl(Application app) {\n        super(app);\n    }\n    \n    public synchronized HeapHistogramImpl takeHeapHistogram() {\n        try (InputStream in = getVirtualMachine().heapHisto(ALL_OBJECTS_OPTION)) {\n            return new JRockitHeapHistogramImpl(in);\n        } catch (IOException ex) {\n            LOGGER.log(Level.INFO,\"takeHeapHistogram\",ex);  // NOI18N\n        }\n        return null;\n    }\n        \n}\n"
  },
  {
    "path": "visualvm/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\ncurrentVersion=VisualVM Dev\nLBL_splash_window_title=Starting VisualVM\nSPLASH_HEIGHT=310\nSPLASH_WIDTH=530\nSplashProgressBarBounds=0,301,514,6\nSplashRunningTextBounds=29,338,222,11\nSplashRunningTextColor=0xFFFFFF\nSplashShowProgressBar=false\n"
  },
  {
    "path": "visualvm/branding/modules/ext/updater.jar/org/netbeans/updater/Bundle.properties",
    "content": "#\n# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nUpdaterFrame.TextBackground_R=231\nUpdaterFrame.TextBackground_G=240\nUpdaterFrame.TextBackground_B=250\n \nUpdaterFrame.TextForeground_R=53\nUpdaterFrame.TextForeground_G=85\nUpdaterFrame.TextForeground_B=107\n \nUpdaterFrame.Background_R=231\nUpdaterFrame.Background_G=240\nUpdaterFrame.Background_B=250\n \nUpdaterFrame.outerColor_R=231\nUpdaterFrame.outerColor_G=240\nUpdaterFrame.outerColor_B=250\n \nUpdaterFrame.centerColor_R=231\nUpdaterFrame.centerColor_G=240\nUpdaterFrame.centerColor_B=250\n \nUpdaterFrame.isGradient=false\n"
  },
  {
    "path": "visualvm/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/Bundle.properties",
    "content": "Splitter.Respect.MinimumSize.Enabled=false\n"
  },
  {
    "path": "visualvm/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/options/Bundle.properties",
    "content": "#\n# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nHint_RESTART_IDE=Restart VisualVM\nDescr_Restart=<html><a href=\"#\">Click here to restart VisualVM and apply your selected look and feel.\nLafPanel.checkMaximizeNativeLaF.toolTipText=<html>VisualVM uses native UI components when those components offer sufficient\\nfunctionality.  <br>Select this option to force use of native components, even when\\nthat may limit functionality (e.g. standard macOS file chooser).\n\n"
  },
  {
    "path": "visualvm/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nCTL_MainWindow_Title=VisualVM Dev\nCTL_MainWindow_Title_No_Project=VisualVM Dev\n"
  },
  {
    "path": "visualvm/branding/modules/org-netbeans-core.jar/org/netbeans/core/ui/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_ProductInformation=VisualVM\n"
  },
  {
    "path": "visualvm/branding/modules/org-netbeans-modules-autoupdate-ui.jar/org/netbeans/modules/autoupdate/ui/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nsearching_handle_single=Searching for \"{0}\" module on VisualVM Plugins Center...\n\n"
  },
  {
    "path": "visualvm/branding/modules/org-netbeans-modules-profiler.jar/org/netbeans/modules/profiler/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nProfilerModule_ExitingFromAttachMessage=Profiling session is currently in progress\\nDo you want to detach from the target application and exit the VisualVM?\n"
  },
  {
    "path": "visualvm/branding/modules/org-netbeans-modules-profiler.jar/org/netbeans/modules/profiler/heapwalk/model/Bundle.properties",
    "content": "#\n# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nBrowserUtils_OutOfMemoryMsg=<html><b>Out of memory in HeapWalker</b><br><br>To avoid this error please increase the -Xmx value<br>in the etc/visualvm.conf file in VisualVM directory.</html>\n\n"
  },
  {
    "path": "visualvm/branding/modules/org-netbeans-swing-laf-flatlaf.jar/org/netbeans/swing/laf/flatlaf/Bundle.properties",
    "content": "#\n# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nFlatLafOptionsPanel.restartTitle=Restart VisualVM\nFlatLafOptionsPanel.restartDetails=Click here to restart VisualVM and apply your selected accent color.\n\n"
  },
  {
    "path": "visualvm/build-nb.sh",
    "content": "#!/bin/bash\n\n# NetBeans 22 FCS\nREV=0d0bfcf3faf364a2643238f2a44e1bb6eb8217bd\nBRANCH=release220\nBUILD_DATE=`git log -n1 --date=format:'%Y%m%d' $0 | fgrep 'Date' | awk '{print $2}'`\nZIPNAME=nb220_platform_$BUILD_DATE\n\nset -e\n\nmkdir -p build/nb/\ncd build/nb/\nBUILD_ROOT=`pwd`\nif [ -e $BUILD_ROOT/$ZIPNAME.zip ]; then\n  echo \"$BUILD_ROOT/$ZIPNAME.zip is up to date\"\n  exit\nfi\nif [ -e netbeans ]; then\n  cd netbeans\n  git fetch\n  git clean -fdx\nelse\n  git clone https://github.com/apache/netbeans netbeans\n  cd netbeans\nfi\n\ngit checkout $BRANCH\ngit reset --hard $REV\ngit revert --no-edit -n 0a64c810435ade77907e5ddbf2491385a5efab2f\ngit revert --no-edit -n -Xignore-all-space --strategy-option=theirs 7e625c44a472d45a513ada1e6ef7526c6d3a7720\ngit revert --no-edit -n -Xignore-all-space --strategy-option=theirs d55be1aff900a81b22081f7699fd16ab04e42553\ngit cherry-pick -n e390f3305204e6910690e15d0930809e73344506\ngit cherry-pick -n a3253e1c6beb535dc582a6352bb0b712796daf55\ngit restore --staged .github/ apisupport/ harness/ platform/\npatch -p1 <<'EOF'\ndiff --git a/platform/keyring.impl/src/org/netbeans/modules/keyring/impl/KeyringSupport.java b/platform/keyring.impl/src/org/netbeans/modules/keyring/impl/KeyringSupport.java\nindex 23393533ab..ae62351657 100644\n--- a/platform/keyring.impl/src/org/netbeans/modules/keyring/impl/KeyringSupport.java\n+++ b/platform/keyring.impl/src/org/netbeans/modules/keyring/impl/KeyringSupport.java\n@@ -21,11 +21,11 @@ package org.netbeans.modules.keyring.impl;\n public class KeyringSupport {\n \n     public static String getAppName() {\n-        return \"NetBeans IDE\";\n+        return \"VisualVM\";\n     }\n \n     public static String getAppNameMac() {\n-        return \"NetBeans\";\n+        return \"VisualVM\";\n     }\n \n }\ndiff --git a/platform/o.n.swing.laf.flatlaf/src/org/netbeans/swing/laf/flatlaf/FlatLaf.properties b/platform/o.n.swing.laf.flatlaf/src/org/netbeans/swing/laf/flatlaf/FlatLaf.properties\nindex e72a2ab534..450a437731 100644\n--- a/platform/o.n.swing.laf.flatlaf/src/org/netbeans/swing/laf/flatlaf/FlatLaf.properties\n+++ b/platform/o.n.swing.laf.flatlaf/src/org/netbeans/swing/laf/flatlaf/FlatLaf.properties\n@@ -104,7 +104,7 @@ TabControlIcon.foreground=tint(@foreground,40%)\n TabControlIcon.disabledForeground=lighten($TabControlIcon.foreground,27%)\n TabControlIcon.rolloverBackground=$Button.toolbar.hoverBackground\n TabControlIcon.pressedBackground=$Button.toolbar.pressedBackground\n-TabControlIcon.close.rolloverBackground=#c74f50\n+TabControlIcon.close.rolloverBackground=#7d7d7d\n TabControlIcon.close.rolloverForeground=#fff\n TabControlIcon.arc=2\n\ndiff --git a/platform/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/AquaVectorTabControlIcon.java b/platform/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/AquaVectorTabControlIcon.java\nindex f1bbdfaae3..46b7aba999 100644\n--- a/platform/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/AquaVectorTabControlIcon.java\n+++ b/platform/o.n.swing.tabcontrol/src/org/netbeans/swing/tabcontrol/plaf/AquaVectorTabControlIcon.java\n@@ -200,11 +200,11 @@ final class AquaVectorTabControlIcon extends VectorIcon {\n             /* Red, with some transparency to blend onto the background. Chrome would have\n             (244, 65, 54, 255), here, but the value below works better with our expected\n             backgrounds. */\n-            bgColor = new Color(255, 35, 25, 215);\n+            bgColor = new Color(125, 125, 125, 215);\n         } else if (buttonState == TabControlButton.STATE_PRESSED) {\n             fgColor = Color.WHITE;\n             // Slightly darker red. Chrome would have (196, 53, 43, 255) here; see above.\n-            bgColor = new Color(185, 43, 33, 215);\n+            bgColor = new Color(105, 105, 105, 215);\n         } else if (buttonState == TabControlButton.STATE_DISABLED) {\n             // Light grey (via transparent black to work well on any background).\n             fgColor = new Color(0, 0, 0, 60);\ndiff --git a/platform/openide.awt/src/org/openide/awt/AquaVectorCloseButton.java b/platform/openide.awt/src/org/openide/awt/AquaVectorCloseButton.java\nindex 4adfc32095..7712a2f8b3 100644\n--- a/platform/openide.awt/src/org/openide/awt/AquaVectorCloseButton.java\n+++ b/platform/openide.awt/src/org/openide/awt/AquaVectorCloseButton.java\n@@ -57,10 +57,10 @@ final class AquaVectorCloseButton extends VectorIcon {\n         Color fgColor = new Color(0, 0, 0, 168);\n         if (state == State.ROLLOVER) {\n             fgColor = Color.WHITE;\n-            bgColor = new Color(255, 35, 25, 215);\n+            bgColor = new Color(125, 125, 125, 215);\n         } else if (state == State.PRESSED) {\n             fgColor = Color.WHITE;\n-            bgColor = new Color(185, 43, 33, 215);\n+            bgColor = new Color(105, 105, 105, 215);\n         }\n         if (bgColor.getAlpha() > 0) {\n             double circPosX = (width - d) / 2.0;\ndiff --git a/nbbuild/build.properties b/nbbuild/build.properties\nindex 9fd630de70..f30d2bc922 100644\n--- a/nbbuild/build.properties\n+++ b/nbbuild/build.properties\n@@ -134,7 +134,6 @@ config.javadoc.stable=\\\n     api.debugger.jpda,\\\n     project.ant,\\\n     project.ant.ui,\\\n-    api.visual,\\\n     api.java,\\\n     api.java.classpath,\\\n     api.search,\\\n@@ -171,16 +170,12 @@ config.javadoc.forwarded.devel=\\\n     editor.bracesmatching,\\\n     editor.lib,\\\n     editor,\\\n-    lib.uihandler,\\\n-    uihandler,\\\n-    spi.editor.hints,\\\n-    api.dashboard\n+    spi.editor.hints\n \n # List of javadocs under development\n config.javadoc.devel=\\\n     junit,\\\n     core.multitabs,\\\n-    core.netigso,\\\n     gradle,\\\n     gradle.java,\\\n     o.n.swing.outline,\\\ndiff --git a/nbbuild/cluster.properties b/nbbuild/cluster.properties\nindex e1f0f4b544..f212333905 100644\n--- a/nbbuild/cluster.properties\n+++ b/nbbuild/cluster.properties\n@@ -143,7 +143,6 @@ nb.cluster.platform.dir=platform\n nb.cluster.platform.depends=nb.cluster.bootstrap\n nb.cluster.platform=\\\n         api.annotations.common,\\\n-        api.dashboard,\\\n         api.htmlui,\\\n         api.intent,\\\n         api.io,\\\n@@ -164,25 +163,18 @@ nb.cluster.platform=\\\n         core.multitabs,\\\n         core.multiview,\\\n         core.nativeaccess,\\\n-        core.netigso,\\\n         core.network,\\\n-        core.osgi,\\\n         core.output2,\\\n         core.ui,\\\n         core.windows,\\\n         editor.mimelookup,\\\n         editor.mimelookup.impl,\\\n         favorites,\\\n-        htmlui,\\\n-        janitor,\\\n         javahelp,\\\n         junitlib,\\\n         keyring,\\\n         keyring.fallback,\\\n         keyring.impl,\\\n-        lib.uihandler,\\\n-        libs.batik.read,\\\n-        libs.felix,\\\n         libs.flatlaf,\\\n         libs.javafx,\\\n         libs.jna,\\\n@@ -190,7 +182,6 @@ nb.cluster.platform=\\\n         libs.jsr223,\\\n         libs.junit4,\\\n         libs.junit5,\\\n-        libs.osgi,\\\n         libs.testng,\\\n         masterfs,\\\n         masterfs.linux,\\\n@@ -201,19 +192,8 @@ nb.cluster.platform=\\\n         net.java.html,\\\n         net.java.html.boot,\\\n         net.java.html.boot.fx,\\\n-        net.java.html.boot.script,\\\n-        net.java.html.geo,\\\n         net.java.html.json,\\\n-        net.java.html.sound,\\\n-        netbinox,\\\n-        o.apache.commons.codec,\\\n-        o.apache.commons.commons_io,\\\n-        o.apache.commons.lang3,\\\n-        o.apache.commons.logging,\\\n         o.n.core,\\\n-        o.n.html.ko4j,\\\n-        o.n.html.presenters.spi,\\\n-        o.n.html.xhr4j,\\\n         o.n.swing.laf.dark,\\\n         o.n.swing.laf.flatlaf,\\\n         o.n.swing.outline,\\\n@@ -224,16 +204,13 @@ nb.cluster.platform=\\\n         openide.compat,\\\n         openide.dialogs,\\\n         openide.execution,\\\n-        openide.execution.compat8,\\\n         openide.explorer,\\\n-        openide.filesystems.compat8,\\\n         openide.filesystems.nb,\\\n         openide.io,\\\n         openide.loaders,\\\n         openide.nodes,\\\n         openide.options,\\\n         openide.text,\\\n-        openide.util.ui.svg,\\\n         openide.windows,\\\n         options.api,\\\n         options.keymap,\\\n@@ -246,8 +223,7 @@ nb.cluster.platform=\\\n         spi.actions,\\\n         spi.quicksearch,\\\n         templates,\\\n-        templatesui,\\\n-        uihandler\n+        templatesui\n validation.nb.cluster.platform=\\\n         o.n.core,\\\n         core.windows,\\\ndiff --git a/nbbuild/jdk.xml b/nbbuild/jdk.xml\nindex c47694ecae..b09b36a9d3 100644\n--- a/nbbuild/jdk.xml\n+++ b/nbbuild/jdk.xml\n@@ -210,10 +210,10 @@\n         <!-- Define fallback values of some things. -->\n         <property name=\"java.home.parent\" location=\"${java.home}/..\"/>\n         <condition property=\"nbjdk.home\" value=\"${java.home.parent}\">\n-            <available file=\"${java.home.parent}/jmods/java.base.jmod\" type=\"file\"/>\n+            <available file=\"${java.home.parent}/lib/tools.jar\" type=\"file\"/>\n         </condition>\n         <condition property=\"nbjdk.home\" value=\"${java.home}\">\n-            <available file=\"${java.home}/jmods/java.base.jmod\" type=\"file\"/>\n+            <available file=\"${java.home}/lib/tools.jar\" type=\"file\"/>\n         </condition>\n \n         <!-- Mac OS X -->\ndiff --git a/harness/apisupport.harness/nbproject/project.properties b/harness/apisupport.harness/nbproject/project.properties\nindex 7db6d57275..4b8b94fa03 100644\n--- a/harness/apisupport.harness/nbproject/project.properties\n+++ b/harness/apisupport.harness/nbproject/project.properties\n@@ -91,7 +91,10 @@ bundled.tasks=\\\n     org/netbeans/nbbuild/XMLUtil*.class,\\\n     org/netbeans/nbbuild/extlibs/DownloadBinaries*.class,\\\n     org/netbeans/nbbuild/extlibs/ConfigureProxy*.class,\\\n-    org/netbeans/nbbuild/extlibs/MavenCoordinate.class\n+    org/netbeans/nbbuild/extlibs/MavenCoordinate.class,\\\n+    org/netbeans/nbbuild/extlibs/ReleaseFilesCopy*.class,\\\n+    org/netbeans/nbbuild/extlibs/ReleaseFilesExtra*.class,\\\n+    org/netbeans/nbbuild/extlibs/ReleaseFilesLicense*.class\n \n test.unit.cp.extra=${netbeans.dest.dir}/harness/jnlp/jnlp-launcher.jar\n javadoc.arch=${basedir}/arch.xml\ndiff --git a/harness/apisupport.harness/taskdefs.properties b/harness/apisupport.harness/taskdefs.properties\nindex 19a01429c9..0d8b86adef 100644\n--- a/harness/apisupport.harness/taskdefs.properties\n+++ b/harness/apisupport.harness/taskdefs.properties\n@@ -40,3 +40,6 @@ parsemanifest=org.netbeans.nbbuild.ParseManifest\n autoupdate=org.netbeans.nbbuild.AutoUpdate\n downloadbinaries=org.netbeans.nbbuild.extlibs.DownloadBinaries\n processjsannotation=org.netbeans.nbbuild.ProcessJsAnnotationsTask\n+releasefilescopy=org.netbeans.nbbuild.extlibs.ReleaseFilesCopy\n+releasefilesextra=org.netbeans.nbbuild.extlibs.ReleaseFilesExtra\n+releasefileslicense=org.netbeans.nbbuild.extlibs.ReleaseFilesLicense\ndiff --git a/harness/apisupport.harness/release/build.xml b/harness/apisupport.harness/release/build.xml\nindex 9171e4ef9c..b9c0abf73a 100644\n--- a/harness/apisupport.harness/release/build.xml\n+++ b/harness/apisupport.harness/release/build.xml\n@@ -278,6 +278,17 @@\n         </javadoc>\n     </target>\n \n+    <target name=\"javadoc-zip\" depends=\"javadoc\" description=\"Simple javadoc zip creation intended for use in maven repository.\">\n+        <zip zipfile=\"${netbeans.javadoc.dir}/${code.name.base.dashes}.zip\" basedir=\"${netbeans.javadoc.dir}/${code.name.base.dashes}\"/>\n+    </target>\n+\n+    <target name=\"sources-zip\" depends=\"build-init\" description=\"Simple sources zip creation intended for use in maven repository.\">\n+        <mkdir dir=\"${netbeans.zipped.sources.dir}\"/>\n+        <zip zipfile=\"${netbeans.zipped.sources.dir}/${code.name.base.dashes}.zip\">\n+            <zipfileset dir=\"${src.dir}\" />\n+        </zip>\n+    </target>\n+\n     <target name=\"javadoc-nb\" depends=\"init,javadoc\" if=\"netbeans.home\">\n         <nbbrowse file=\"${netbeans.javadoc.dir}/${code.name.base.dashes}/index.html\"/>\n     </target>\ndiff --git a/platform/autoupdate.services/libsrc/org/netbeans/updater/resources/autoupdate-catalog-2_8.dtd b/platform/autoupdate.services/libsrc/org/netbeans/updater/resources/autoupdate-catalog-2_8.dtd\nindex 074e63671515..0901373bf327 100644\n--- a/platform/autoupdate.services/libsrc/org/netbeans/updater/resources/autoupdate-catalog-2_8.dtd\n+++ b/platform/autoupdate.services/libsrc/org/netbeans/updater/resources/autoupdate-catalog-2_8.dtd\n@@ -64,6 +64,7 @@\n                    OpenIDE-Module-Name CDATA #REQUIRED\n                    OpenIDE-Module-Specification-Version CDATA #REQUIRED\n                    OpenIDE-Module-Implementation-Version CDATA #IMPLIED\n+                   OpenIDE-Module-Build-Version CDATA #IMPLIED\n                    OpenIDE-Module-Module-Dependencies CDATA #IMPLIED\n                    OpenIDE-Module-Package-Dependencies CDATA #IMPLIED\n                    OpenIDE-Module-Java-Dependencies CDATA #IMPLIED\ndiff --git a/platform/applemenu/src/org/netbeans/modules/applemenu/CtrlClickHack.java b/platform/applemenu/src/org/netbeans/modules/applemenu/CtrlClickHack.java\ndeleted file mode 100644\nindex 97c2795dc3..0000000000\n--- a/platform/applemenu/src/org/netbeans/modules/applemenu/CtrlClickHack.java\n+++ /dev/null\n@@ -1,106 +0,0 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one\n- * or more contributor license agreements.  See the NOTICE file\n- * distributed with this work for additional information\n- * regarding copyright ownership.  The ASF licenses this file\n- * to you under the Apache License, Version 2.0 (the\n- * \"License\"); you may not use this file except in compliance\n- * with the License.  You may obtain a copy of the License at\n- *\n- *   http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing,\n- * software distributed under the License is distributed on an\n- * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n- * KIND, either express or implied.  See the License for the\n- * specific language governing permissions and limitations\n- * under the License.\n- */\n-\n-package org.netbeans.modules.applemenu;\n-\n-import java.awt.AWTEvent;\n-import java.awt.event.AWTEventListener;\n-import java.awt.event.FocusEvent;\n-import java.awt.event.InputEvent;\n-import java.awt.event.MouseEvent;\n-import java.lang.ref.Reference;\n-import java.lang.ref.WeakReference;\n-import java.lang.reflect.Field;\n-import java.lang.reflect.Method;\n-import javax.swing.text.Caret;\n-import javax.swing.text.JTextComponent;\n-\n-/**\n- * hack for issue #67799, on macosx with single button mouse,\n- * make Ctrl-Click work as right click on multiselections\n- *\n- * Also handles issue #90371 - on Macintosh, JTextComponents\n- * are never sent focus lost events, resulting in multiple\n- * blinking carets.  Hack tracks last known JTextComponent\n- * and sets its cursor to invisible if any other component \n- * gains focus (on Mac OS, getOppositeComponent() \n- * frequently returns null when coming from a JTextComponent)\n- *\n- * @author ttran, Tim Boudreau\n- */\n-public class CtrlClickHack implements AWTEventListener {\n-    private Reference<JTextComponent> lastFocusedTextComponent = null;\n-\n-    public void eventDispatched(AWTEvent e) {\n-        if (!(e instanceof MouseEvent) && !(e instanceof FocusEvent)) {\n-            return;\n-        }\n-        if (e instanceof FocusEvent) {\n-            FocusEvent fe = (FocusEvent) e;\n-            if (fe.getID() == FocusEvent.FOCUS_GAINED) {\n-                if (fe.getOppositeComponent() instanceof JTextComponent) {\n-                    JTextComponent jtc = (JTextComponent) fe.getOppositeComponent();\n-                    if (null != jtc) {\n-                        Caret caret = jtc.getCaret();\n-                        if (null != caret) {\n-                            caret.setVisible(false);\n-                        }\n-                    }\n-                } else {\n-                    JTextComponent jtc = lastFocusedTextComponent == null ? null :\n-                        lastFocusedTextComponent.get();\n-                    if (null != jtc) {\n-                        Caret caret = jtc.getCaret();\n-                        if (null != caret)\n-                            caret.setVisible(false);\n-                    }\n-                }\n-                if (fe.getComponent() instanceof JTextComponent) {\n-                    JTextComponent jtc = (JTextComponent) fe.getComponent();\n-                    lastFocusedTextComponent = new WeakReference<JTextComponent>(jtc);\n-                    if (null != jtc) {\n-                        Caret caret = jtc.getCaret();\n-                        if (null != caret) {\n-                            caret.setVisible(true);\n-                        }\n-                    }\n-                }\n-            }\n-            return;\n-        }\n-        MouseEvent evt = (MouseEvent) e;\n-        if (evt.getModifiers() != (InputEvent.BUTTON1_MASK | InputEvent.CTRL_MASK)) {\n-            return;\n-        }\n-        try {\n-            Field f1 = InputEvent.class.getDeclaredField(\"modifiers\");\n-            Field f2 = MouseEvent.class.getDeclaredField(\"button\");\n-            Method m = MouseEvent.class.getDeclaredMethod(\"setNewModifiers\", new Class[] {});\n-            f1.setAccessible(true);\n-            f1.setInt(evt, InputEvent.BUTTON3_MASK);\n-            f2.setAccessible(true);\n-            f2.setInt(evt, MouseEvent.BUTTON3);\n-            m.setAccessible(true);\n-            m.invoke(evt, new Object[] {});\n-        } catch (Exception ex) {\n-            ex.printStackTrace();\n-        }\n-    }\n-    \n-}\ndiff --git a/platform/applemenu/src/org/netbeans/modules/applemenu/Install.java b/platform/applemenu/src/org/netbeans/modules/applemenu/Install.java\nindex e848b2e4e0..a3d28f8bb9 100644\n--- a/platform/applemenu/src/org/netbeans/modules/applemenu/Install.java\n+++ b/platform/applemenu/src/org/netbeans/modules/applemenu/Install.java\n@@ -31,13 +31,10 @@ import org.openide.util.Utilities;\n  * @author  Tim Boudreau\n  */\n public class Install extends ModuleInstall {\n-    private CtrlClickHack listener;\n     private Class adapter;\n \n     @Override\n     public void restored () {\n-        listener = new CtrlClickHack();\n-        Toolkit.getDefaultToolkit().addAWTEventListener(listener, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK);\n         if (Utilities.isMac() ) {\n             String pn = \"apple.laf.useScreenMenuBar\"; // NOI18N\n             if (System.getProperty(pn) == null) {\n@@ -65,10 +62,6 @@ public class Install extends ModuleInstall {\n     \n     @Override\n     public void uninstalled () {\n-         if (listener != null) {\n-            Toolkit.getDefaultToolkit().removeAWTEventListener(listener);\n-            listener = null;\n-         }\n         if (Utilities.isMac() && adapter != null) {\n             try {\n                 Method m = adapter.getDeclaredMethod(\"uninstall\", new Class[0] );   // NOI18N\nEOF\ngit status\n\nOPTS=-Dbuild.compiler.debuglevel=source,lines\nSHORT_REV=`git rev-parse --short HEAD`\ngit clean -fdX\ncd nbbuild\nant $OPTS -Dname=platform -Dbuildnumber=$BUILD_DATE-$SHORT_REV rebuild-cluster\nant $OPTS -Dname=harness -Dbuildnumber=$BUILD_DATE-$SHORT_REV rebuild-cluster\n\nzip -r $BUILD_ROOT/$ZIPNAME.zip netbeans\n"
  },
  {
    "path": "visualvm/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"visualvm\" basedir=\".\">\n    <description>Builds the module suite visualvm.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n    <target name=\"create-platform\" depends=\"build-zip\">\n        <mkdir dir=\"${visualvm-platform}\"/>\n        <unzip src=\"dist/${app.name}.zip\" dest=\"${visualvm-platform}\"/>\n    </target>\n\n    <target name=\"build-launchers\" depends=\"-init\">\n        <fail unless=\"app.name\">Must have set at least an application name ('app.name')\n        </fail>\n        <pathconvert property=\"zip.platform.update.tracking\">\n            <pathfileset>\n                <path refid=\"cluster.path.id\"/>\n                <filename name=\"**/update_tracking/*.xml\"/>\n            </pathfileset>\n        </pathconvert>\n        <selector id=\"zip.platform.included.files\">\n            <custom classpath=\"${harness.dir}/tasks.jar\" classname=\"org.netbeans.nbbuild.ModuleSelector\">\n                <param name=\"excludeModules\" value=\"${disabled.modules}\"/>\n                <!-- XXX inc/exc clusters -->\n                <param name=\"includeClusters\" value=\"${enabled.clusters}\"/>\n                <param name=\"excludeClusters\" value=\"${disabled.clusters}\"/>\n                <param name=\"updateTrackingFiles\" value=\"${zip.platform.update.tracking}\"/>\n            </custom>\n        </selector>\n\n        <pathconvert property=\"zip.platform.clusters.duplicates\" pathsep=\"&#10;\">\n            <pathfileset>\n                <path refid=\"cluster.path.id\"/>\n                <selector refid=\"zip.platform.included.files\"/>\n            </pathfileset>\n            <chainedmapper>\n                <mapper type=\"regexp\" from=\"(^.+)[/\\\\](config[/\\\\]Modules|(?&lt;=[/\\\\]platform\\d{0,2}[/\\\\])(lib|core))[/\\\\]\" to=\"\\1\"/> <!-- #71849, #185047, #188601 -->\n                <filtermapper>\n                    <linecontainsregexp negate=\"true\">\n                        <regexp pattern=\"update[/\\\\]backup[/\\\\]netbeans[/\\\\]?$\"/>\n                    </linecontainsregexp>\n                </filtermapper>\n            </chainedmapper>\n        </pathconvert>\n        <tempfile property=\"zip.platform.clusters.duplicates.file\" destdir=\"${suite.build.dir}\" deleteonexit=\"true\" prefix=\"duplicates\"/>\n        <echo file=\"${zip.platform.clusters.duplicates.file}\" message=\"${zip.platform.clusters.duplicates}\"/>\n\n        <union id=\"zip.platform.clusters\"> <!-- union removes duplicates -->\n            <files includesfile=\"${zip.platform.clusters.duplicates.file}\"/>\n        </union>\n        <pathconvert property=\"zip.platform.clusters.bare\" pathsep=\"&#10;\"> <!-- #71128: \\n OK on Win but \\r\\n bad on Unix -->\n            <resources refid=\"zip.platform.clusters\"/>\n            <chainedmapper>\n                <filtermapper>\n                    <linecontainsregexp negate=\"true\">\n                        <regexp pattern=\"platform[0-9]*[/\\\\]?$\"/>\n                    </linecontainsregexp>\n                </filtermapper>\n                <mapper type=\"regexp\" from=\"[/\\\\]([^/\\\\]+)([/\\\\]build[/\\\\]cluster)?[/\\\\]?$\" to=\"\\1\"/> <!-- #71849, #179410 -->\n            </chainedmapper>\n        </pathconvert>\n\n        <property name=\"build.launcher.dir\" location=\"${suite.build.dir}/launcher\"/>\n\n        <mkdir dir=\"${build.launcher.dir}/etc\"/>\n        <!-- clean old launchers (platform could be changed) -->\n        <delete dir=\"${build.launcher.dir}/bin\" failonerror=\"false\"/>\n        <mkdir dir=\"${build.launcher.dir}/bin\"/>\n\n        <!-- make sure correct launchers are present - for pre7 platform use old app.exe launchers -->\n        <pathconvert property=\"nbexec.dll.found\" setonempty=\"false\">\n            <pathfileset include=\"lib/nbexec.dll\">\n                <path refid=\"cluster.path.id\"/>\n            </pathfileset>\n        </pathconvert>\n        <condition property=\"app.exe.prefix\" value=\"\" else=\"pre7_\">\n            <isset property=\"nbexec.dll.found\"/>\n        </condition>\n        <copy file=\"launcher/visualvm.exe\" todir=\"${build.launcher.dir}/bin/\"/>\n        <copy file=\"launcher/visualvm\" todir=\"${build.launcher.dir}/bin/\"/>\n        <copy file=\"launcher/visualvm.conf\" todir=\"${build.launcher.dir}/etc/\"/>\n        <copy file=\"launcher/visualvm.icns\" todir=\"${build.launcher.dir}/etc/\"/>\n        <copy file=\"launcher/visualvm.import\" todir=\"${build.launcher.dir}/etc/\"/>\n        <echo message=\"${app.name}\" file=\"${build.launcher.dir}/etc/${app.name}.clusters\"/>\n        <echo message=\"&#10;\" file=\"${build.launcher.dir}/etc/${app.name}.clusters\" append=\"true\"/>\n        <echo message=\"${zip.platform.clusters.bare}\" file=\"${build.launcher.dir}/etc/${app.name}.clusters\" append=\"true\"/>\n        <echo message=\"&#10;\" file=\"${build.launcher.dir}/etc/${app.name}.clusters\" append=\"true\"/>\n    </target>\n\n    <target name=\"build-zip\" depends=\"build,build-launchers\" description=\"Builds a ZIP distribution of the suite, launchers, and selected modules from the platform.\">\n        <mkdir dir=\"${dist.dir}\"/>\n        <!-- pathfileset does not support 'prefix' and 'filemode' parameters,\n             we have to copy them to temp location -->\n        <tempfile property=\"temp.dir.nbexec\" destdir=\"${suite.build.dir}\" deleteonexit=\"true\" prefix=\"nbexec\"/>\n        <tempfile property=\"temp.dir.rest\" destdir=\"${suite.build.dir}\" deleteonexit=\"delete\" prefix=\"rest\"/>\n        <subant genericantfile=\"${harness.dir}/suite.xml\" target=\"copy-cluster\" inheritrefs=\"true\">\n            <property name=\"dest.dir\" value=\"${temp.dir.rest}\"/>\n            <property name=\"nbexec.dir\" value=\"${temp.dir.nbexec}\"/>\n            <property name=\"build.dir\" value=\"${suite.build.dir}\"/>\n            <resources refid=\"zip.platform.clusters\"/>\n        </subant>\n        <zip destfile=\"${dist.dir}/${app.name}.zip\">\n            <zipfileset dir=\"${build.launcher.dir}/bin/\" filemode=\"755\" prefix=\"${app.name}/bin\"/>\n            <zipfileset dir=\"${build.launcher.dir}/etc/\" prefix=\"${app.name}/etc\"/>\n            <zipfileset dir=\"${temp.dir.nbexec}\" filemode=\"755\" prefix=\"${app.name}\"/>\n            <zipfileset dir=\"${temp.dir.rest}\" prefix=\"${app.name}\"/>\n            <zipfileset dir=\"startup/src/org/graalvm/visualvm/modules/startup/\" includes=\"LICENSE.txt\" prefix=\"${app.name}\"/>\n            <zipfileset dir=\"..\" includes=\"THIRDPARTYLICENSE\" prefix=\"${app.name}\"/>\n\n            <!-- Yes, the doubled app.name is a bit ugly, but better than the alternative; cf. #66441: -->\n            <zipfileset dir=\"${cluster}\" prefix=\"${app.name}/${app.name}\">\n                <exclude name=\"config/Modules/*.xml_hidden\"/>\n            </zipfileset>\n        </zip>\n    </target>\n\n    <target name=\"javadoc\" depends=\"-init,branding\">\n        <delete dir=\"build/javadoc\"/>\n\n        <javadoc destdir=\"build/javadoc\" author=\"true\" version=\"true\" use=\"true\" encoding=\"UTF-8\" windowtitle=\"${app.title} API\">\n            \n            <!--group title=\"VisualVM-Application\" packages=\"org.graalvm.visualvm.application*\"/-->\n            <fileset dir=\"application/src\" defaultexcludes=\"yes\">\n                <include name=\"**/*.java\"/>\n                <exclude name=\"org/graalvm/visualvm/application/options/*.java\"/>\n            </fileset>\n\n            <!--group title=\"VisualVM-Application Views\" packages=\"org.graalvm.visualvm.application.views*\"/-->\n            <fileset dir=\"applicationviews/src\" defaultexcludes=\"yes\">\n                <include name=\"*org/graalvm/visualvm/application/views/*.java\"/>\n            </fileset>\n\n            <!--group title=\"VisualVM-Charts\" packages=\"corg.graalvm.visualvm.charts*\"/-->\n            <fileset dir=\"charts/src\" defaultexcludes=\"yes\">\n                <include name=\"**/*.java\"/>\n                <exclude name=\"org/graalvm/visualvm/charts/swing/*.java\"/>\n                <exclude name=\"org/graalvm/visualvm/charts/xy/*.java\"/>\n            </fileset>\n\n            <!--group title=\"VisualVM-Core\" packages=\"org.graalvm.visualvm.core*\"/-->\n            <fileset dir=\"core/src\" defaultexcludes=\"yes\">\n                <include name=\"**/*.java\"/>\n                <exclude name=\"org/graalvm/visualvm/core/*.java\"/>\n                <exclude name=\"org/graalvm/visualvm/core/snapshot/options/*.java\"/>\n            </fileset>\n\n            <!--group title=\"VisualVM-CoreDump\" packages=\"org.graalvm.visualvm.coredump*\"/-->\n            <fileset dir=\"coredump/src\" defaultexcludes=\"yes\">\n                <include name=\"org/graalvm/visualvm/coredump/*.java\"/>\n            </fileset>\n\n            <!--group title=\"VisualVM-HeapDump\" packages=\"org.graalvm.visualvm.heapdump*\"/-->\n            <fileset dir=\"heapdump/src\" defaultexcludes=\"yes\">\n                <include name=\"org/graalvm/visualvm/heapdump/*.java\"/>\n            </fileset>\n\n            <!--group title=\"VisualVM-Host\" packages=\"org.graalvm.visualvm.host*\"/-->\n            <fileset dir=\"host/src\" defaultexcludes=\"yes\">\n                <include name=\"**/*.java\"/>\n                <exclude name=\"org/graalvm/visualvm/host/impl/*.java\"/>\n            </fileset>\n\n            <!--group title=\"VisualVM-Host Views\" packages=\"org.graalvm.visualvm.host.views*\"/-->\n            <fileset dir=\"hostviews/src\" defaultexcludes=\"yes\">\n                <include name=\"*org/graalvm/visualvm/host/views/*.java\"/>\n            </fileset>\n\n            <!--group title=\"VisualVM-JMX\" packages=\"org.graalvm.visualvm.jmx*\"/-->\n            <fileset dir=\"jmx/src\" defaultexcludes=\"yes\">\n                <include name=\"*org/graalvm/visualvm/jmx/*.java\"/>\n            </fileset>\n\n            <!--group title=\"VisualVM-ThreadDump\" packages=\"org.graalvm.visualvm.threaddump*\"/-->\n            <fileset dir=\"threaddump/src\" defaultexcludes=\"yes\">\n                <include name=\"org/graalvm/visualvm/threaddump/*.java\"/>\n            </fileset>\n\n            <!--group title=\"VisualVM-Tools\" packages=\"org.graalvm.visualvm.tools*\"/-->\n            <fileset dir=\"tools/src\" defaultexcludes=\"yes\">\n                <include name=\"**/*.java\"/>\n                <exclude name=\"org/graalvm/visualvm/tools/*.java\"/>\n            </fileset>\n\n            <classpath>\n                <pathelement location=\"netbeans/platform/lib/org-openide-util-lookup.jar\"/>\n                <pathelement location=\"netbeans/platform/lib/org-openide-util.jar\"/>\n                <pathelement location=\"netbeans/platform/modules/org-openide-windows.jar\"/>\n                <pathelement location=\"netbeans/platform/modules/org-openide-awt.jar\"/>\n                <pathelement location=\"netbeans/platform/lib/org-openide-modules.jar\"/>\n                <pathelement location=\"netbeans/platform/core/org-openide-filesystems.jar\"/>\n                <pathelement location=\"netbeans/platform/modules/org-openide-dialogs.jar\"/>\n                <pathelement location=\"netbeans/platform/modules/org-netbeans-api-progress.jar\"/>\n                <pathelement location=\"netbeans/platform/modules/org-netbeans-modules-options-api.jar\"/>\n                <pathelement location=\"netbeans/platform/modules/org-openide-loaders.jar\"/>\n                <pathelement location=\"netbeans/platform/modules/org-openide-nodes.jar\"/>\n                <pathelement location=\"netbeans/profiler/modules/org-graalvm-visualvm-lib-charts.jar\"/>\n                <pathelement location=\"netbeans/profiler/modules/org-graalvm-visualvm-lib-profiler-api.jar\"/>\n                <pathelement location=\"uisupport/build/classes/\"/>\n                <pathelement location=\"applicationviews/build/classes/\"/>\n                <pathelement location=\"charts/build/classes/\"/>\n                <pathelement location=\"coredump/build/classes/\"/>\n                <pathelement location=\"threaddump/build/classes/\"/>\n                <pathelement location=\"heapdump/build/classes/\"/>\n                <pathelement location=\"jmx/build/classes/\"/>\n                <pathelement location=\"host/build/classes/\"/>\n                <pathelement location=\"hostviews/build/classes/\"/>\n            </classpath>\n\n            <link href=\"http://docs.oracle.com/javase/7/docs/api/\"/>\n\n\n            <doctitle><![CDATA[<h1>${app.title} API Specification</h1><p align=\"left\">This document is the API specification for ${app.title}. See the <a href=\"https://visualvm.github.io/api-quickstart.html\">Getting Started Extending VisualVM</a> document for information about developing plugins for VisualVM.</p><br/>]]></doctitle>\n            <header><![CDATA[<b>${app.title} API<br>Specification</b>]]></header>\n\n        </javadoc>\n\n        <nbbrowse file=\"build/javadoc/index.html\"/>\n    </target>\n\n    <!-- build source zips for selected modules - useful for populating maven repository only-->\n    <target name=\"build-source-zips\" depends=\"-init\" description=\"Builds source zips for maven repository inclusion.\">\n        <property name=\"netbeans.zipped.sources.dir\" location=\"${suite.build.dir}/source-zips\" />\n      \n        <subant target=\"sources-zip\" failonerror=\"true\" inheritall=\"true\">\n            <buildpath path=\"${modules.sorted}\"/>\n        </subant>\n    </target>\n\n    <!-- build javadoc zips for selected modules - useful for populating maven repository only-->\n    <target name=\"build-javadoc-zips\" depends=\"-init\" description=\"Builds javadoc zips for maven repository inclusion.\">\n        <property name=\"netbeans.javadoc.dir\" location=\"${suite.build.dir}/javadoc\" />\n      \n        <subant target=\"javadoc-zip\" failonerror=\"true\" inheritall=\"true\">\n            <buildpath path=\"${modules.sorted}\"/>\n        </subant>\n    </target>\n\n</project>\n"
  },
  {
    "path": "visualvm/caching.api/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.api.caching\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.api.caching.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/caching.api/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.api.caching/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/api/caching/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "visualvm/caching.api/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.api.caching-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/caching.api/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=22f1bad2\nbuild.xml.script.CRC32=aac8a00c\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=22f1bad2\nnbproject/build-impl.xml.script.CRC32=0164a76b\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/caching.api/nbproject/project.properties",
    "content": "is.autoload=true\njavac.source=1.8\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/caching.api/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.api.caching</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <test-dependencies>\n                <test-type>\n                    <name>unit</name>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.libs.junit4</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                </test-type>\n            </test-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.api.caching</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/caching.api/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Caching API\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/Cache.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching;\n\n/**\n * An interface for cache\n * <p>\n * A cache is basically a map that can evict its entries according to defined TTL\n * or as a result of the user action\n * @author Jaroslav Bachorik\n */\nabstract public class Cache<K,V> {\n    /**\n     * Retrieves an object from the cache by the given key<br>\n     * If there is no cached version of the object {@linkplain EntryFactory#createEntry(Object)}  is invoked\n     * <p>\n     * To obtain a cache one needs to call one of {@linkplain CacheFactory} methods\n     * </p>\n     * @param key The key identifying the object to be retrieved\n     * @return Returns the cached object or NULL\n     */\n    abstract public V retrieveObject(K key);\n\n    abstract public V invalidateObject(K key);\n\n    /**\n     * Property getter\n     * @return Returns TTL interval in milliseconds\n     */\n    abstract public long getTTL();\n\n    /**\n     * Property setter\n     * @param ttl TTL interval in milliseconds\n     */\n    abstract public void setTTL(long ttl);\n\n}\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/CacheFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching;\n\nimport org.graalvm.visualvm.api.caching.impl.CacheFactoryImpl;\nimport org.openide.util.Lookup;\n\n/**\n * Factory class for various types of {@linkplain Cache}\n * @author Jaroslav Bachorik\n */\nfinal public class CacheFactory {\n    final private static class Singleton {\n        final private static CacheFactory INSTANCE = new CacheFactory();\n    }\n    final private CacheFactoryImpl delegate;\n\n    private CacheFactory() {\n        delegate = Lookup.getDefault().lookup(CacheFactoryImpl.class);\n    }\n\n    public static CacheFactory getInstance() {\n        return Singleton.INSTANCE;\n    }\n\n    public <K,V> Cache<K,V> weakMapCache() {\n        return delegate.weakMapCache();\n    }\n    public <K,V> Cache<K,V> weakMapCache(EntryFactory<K,V> resolver, Persistor<K,V> persistor) {\n        return delegate.weakMapCache(resolver, persistor);\n    }\n    public <K,V> Cache<K,V> weakMapCache(Persistor<K,V> persistor) {\n        return delegate.weakMapCache(persistor);\n    }\n    public <K,V> Cache<K,V> weakMapCache(EntryFactory<K,V> resolver) {\n        return delegate.weakMapCache(resolver);\n    }\n\n    public <K,V> Cache<K,V> softMapCache() {\n        return delegate.softMapCache();\n    }\n    public <K,V> Cache<K,V> softMapCache(EntryFactory<K,V> resolver, Persistor<K,V> persistor) {\n        return delegate.softMapCache(resolver, persistor);\n    }\n    public <K,V> Cache<K,V> softMapCache(Persistor<K,V> persistor) {\n        return delegate.softMapCache(persistor);\n    }\n    public <K,V> Cache<K,V> softMapCache(EntryFactory<K,V> resolver) {\n        return delegate.softMapCache(resolver);\n    }\n}\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/Entry.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.api.caching;\n\nimport java.util.Objects;\n\n/**\n * Generic representation of a cache entry\n * Supports operations based on TTL (time-to-live)\n * @author Jaroslav Bachorik\n */\nfinal public class Entry<T> {\n\n    private long accessTs;\n    private long updateTs;\n    private T object;\n\n    public Entry(T content) {\n        this(content, System.currentTimeMillis());\n    }\n\n    public Entry(T content, long lastModified) {\n        this.object = content;\n        accessTs = lastModified;\n        updateTs = accessTs;\n    }\n\n    /**\n     * \n     * @return Returns the \"last-accessed\" value (in {@linkplain System#currentTimeMillis()} form)\n     */\n    public long getAccessTimeStamp() {\n        return accessTs;\n    }\n\n    public T getContent() {\n        return object;\n    }\n\n    /**\n     * \n     * @return Returns the \"last-updated\" value (in {@linkplain System#currentTimeMillis()} form)\n     */\n    public long getUpdateTimeStamp() {\n        return updateTs;\n    }\n\n    /**\n     * Sets the \"last-accessed\" value (in {@linkplain System#currentTimeMillis()} form)\n     * @param ts Timestamp in {@linkplain System#currentTimeMillis()} form\n     */\n    void setAccessTimeStamp(long ts) {\n        accessTs = ts;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj == null) {\n            return false;\n        }\n        if (getClass() != obj.getClass()) {\n            return false;\n        }\n        final Entry other = (Entry) obj;\n        if (this.accessTs != other.accessTs) {\n            return false;\n        }\n        if (this.updateTs != other.updateTs) {\n            return false;\n        }\n        if (!Objects.equals(object, other.object)) {\n            return false;\n        }\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int hash = 5;\n        hash = 61 * hash + (int) (this.accessTs ^ (this.accessTs >>> 32));\n        hash = 61 * hash + (int) (this.updateTs ^ (this.updateTs >>> 32));\n        hash = 61 * hash + (this.object != null ? this.object.hashCode() : 0);\n        return hash;\n    }\n}\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/EntryFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching;\n\n/**\n * @author Jaroslav Bachorik\n */\npublic interface EntryFactory<K,V> {\n    /**\n     * This method will map the given key value to an entry value\n     * It can return NULL if it's not possible to map the given key to\n     * an instance of {@linkplain Entry}\n     * @param key The key to create entry from\n     * @return Returns the resolved object or NULL\n     **/\n    Entry<V> createEntry(K key);\n\n    final public static EntryFactory DEFAULT = new EntryFactory() {\n\n        @Override\n        public Entry createEntry(Object key) {\n            return new Entry(key);\n        }\n    };\n}\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/Persistor.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching;\n\n/**\n * Generic key/value persistor\n * Supports retrieving a value by the given key and storing a value with the given key\n * @author Jaroslav Bachorik\n */\npublic interface Persistor<K, V> {\n    /**\n     * Retrieves {@linkplain Entry} for the given key\n     * @param key The key to retrieve {@linkplain Entry} instance\n     * @return Returns the retrieved {@linkplain Entry} instance or NULL\n     */\n    Entry<V> retrieve(K key);\n    /**\n     * Stores the {@linkplain Entry} together with its key\n     * @param key The key to be used\n     * @param value The value to be used\n     */\n    void store(K key, Entry<V> value);\n\n    /**\n     * The default (NULL-value) instance\n     */\n    final public static Persistor DEFAULT = new Persistor() {\n\n        @Override\n        public Entry retrieve(Object key) {\n            // do nothing\n            return null;\n        }\n\n        @Override\n        public void store(Object key, Entry value) {\n            // do nothing\n        }\n\n    };\n}\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/impl/CacheFactoryImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching.impl;\n\n\nimport org.graalvm.visualvm.api.caching.Cache;\nimport org.graalvm.visualvm.api.caching.CacheFactory;\nimport org.graalvm.visualvm.api.caching.EntryFactory;\nimport org.graalvm.visualvm.api.caching.Persistor;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n * The implementation of {@linkplain CacheFactory}\n * @author Jaroslav Bachorik\n */\n@ServiceProvider(service=CacheFactoryImpl.class)\npublic class CacheFactoryImpl {\n    public <K,V> Cache<K,V> weakMapCache() {\n        return new CacheImpl<>(new WeakKeyFactory<>());\n    }\n    public <K,V> Cache<K,V> weakMapCache(EntryFactory<K,V> resolver, Persistor<K,V> persistor) {\n        return new CacheImpl<>(resolver, new WeakKeyFactory<>(), persistor);\n    }\n    public <K,V> Cache<K,V> weakMapCache(Persistor<K,V> persistor) {\n        return new CacheImpl<>(new WeakKeyFactory<>(), persistor);\n    }\n    public <K,V> Cache<K,V> weakMapCache(EntryFactory<K,V> resolver) {\n        return new CacheImpl<>(resolver, new WeakKeyFactory<>());\n    }\n\n    public <K,V> Cache<K,V> softMapCache() {\n        return new CacheImpl<>(new SoftKeyFactory<>());\n    }\n    public <K,V> Cache<K,V> softMapCache(EntryFactory<K,V> resolver, Persistor<K,V> persistor) {\n        return new CacheImpl<>(resolver, new SoftKeyFactory<>(), persistor);\n    }\n    public <K,V> Cache<K,V> softMapCache(Persistor<K,V> persistor) {\n        return new CacheImpl<>(new SoftKeyFactory<>(), persistor);\n    }\n    public <K,V> Cache<K,V> softMapCache(EntryFactory<K,V> resolver) {\n        return new CacheImpl<>(resolver, new SoftKeyFactory<>());\n    }\n}\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/impl/CacheImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching.impl;\n\n\nimport org.graalvm.visualvm.api.caching.Cache;\nimport org.graalvm.visualvm.api.caching.Entry;\nimport org.graalvm.visualvm.api.caching.EntryFactory;\nimport org.graalvm.visualvm.api.caching.Persistor;\nimport java.lang.ref.Reference;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Default class implementation - should be used as a base for caching functionality\n * @author Jaroslav Bachorik\n */\nfinal class CacheImpl<K, V> extends Cache<K,V> {\n    final private Map<Reference<K>, Entry<V>> objectCache = new HashMap<>();\n\n    private long update_interval = 60480000; // 7 days in milliseconds\n\n    private Persistor<K, V> persistor = Persistor.DEFAULT;\n    private KeyFactory<K> keyFactory = KeyFactory.DEFAULT;\n    private EntryFactory<K,V> resolver = EntryFactory.DEFAULT;\n\n    CacheImpl() {};\n\n    CacheImpl(EntryFactory<K,V> resolver) {\n        this.resolver = resolver;\n    }\n\n    CacheImpl(Persistor<K,V> persistor) {\n        this.persistor = persistor;\n    }\n\n    CacheImpl(KeyFactory<K> keyFactory) {\n        this.keyFactory = keyFactory;\n    }\n\n    CacheImpl(EntryFactory<K,V> resolver, Persistor<K,V> persistor) {\n        this.resolver = resolver;\n        this.persistor = persistor;\n    }\n\n    CacheImpl(EntryFactory<K,V> resolver, KeyFactory<K> keyFactory) {\n        this.resolver = resolver;\n        this.keyFactory = keyFactory;\n    }\n\n    CacheImpl(KeyFactory<K> keyFactory, Persistor<K,V> persistor) {\n        this.persistor = persistor;\n        this.keyFactory = keyFactory;\n    }\n\n    CacheImpl(EntryFactory<K,V> resolver, KeyFactory<K> keyFactory, Persistor<K,V> persistor) {\n        this.resolver = resolver;\n        this.persistor = persistor;\n        this.keyFactory = keyFactory;\n    }\n\n    /**\n     * Retrieves an object from the cache by the given key\n     * <p>\n     * If there is no cached version then a registered instance of {@linkplain EntryFactory}\n     * is used to invoke its {@linkplain EntryFactory#createEntry(java.lang.Object)} method.<br/>\n     * Also, a {@linkplain Persistor} instance is used to retrieve and store the cached value in\n     * a dedicated storage.\n     * </p>\n     * @param key The key identifying the object to be retrieved\n     * @return Returns the cached object or NULL\n     */\n    @Override\n    final public V retrieveObject(K key) {\n        Reference<K> softKey = keyFactory.createKey(key);\n        synchronized(objectCache) {\n            Entry<V> entry = objectCache.get(softKey);\n            if (entry == null) {\n                entry = persistor.retrieve(key);\n            }\n            if (entry == null) {\n                entry = cacheMiss(key);\n                if (entry != null && entry.getContent() != null) {\n                    persistor.store(key, entry);\n                    objectCache.put(softKey, entry);\n                }\n            } else {\n                long timestamp = System.currentTimeMillis();\n                if ((timestamp - entry.getUpdateTimeStamp()) > update_interval) {\n                    Entry<V> newEntry = cacheMiss(key);\n                    if (newEntry != null && newEntry.getContent() != null) {\n                        persistor.store(key, entry);\n                        objectCache.put(softKey, newEntry);\n                        entry = newEntry;\n                    }\n                }\n            }\n            return entry != null ? entry.getContent() : null;\n        }\n    }\n    \n    @Override\n    final public V invalidateObject(K key) {\n        Reference<K> softKey = keyFactory.createKey(key);\n        synchronized(objectCache) {\n            Entry<V> entry = objectCache.remove(softKey);\n            return entry != null ? entry.getContent() : null;\n        }\n    }\n\n    /**\n     * Property getter\n     * @return Returns TTL interval in milliseconds\n     */\n    @Override\n    final public long getTTL() {\n        return update_interval;\n    }\n\n    /**\n     * Property setter\n     * @param ttl TTL interval in milliseconds\n     */\n    @Override\n    final public void setTTL(long ttl) {\n        this.update_interval = ttl;\n    }\n\n    /**\n     * This method is called in case of cache-miss\n     * It can return NULL if it's not possible to resolve the missing instance\n     * @param key The key of the missing object\n     * @return Returns the resolved object or NULL\n     */\n    private Entry<V> cacheMiss(K key) {\n        return resolver.createEntry(key);\n    }\n}\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/impl/KeyFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching.impl;\n\nimport java.lang.ref.Reference;\n\ninterface KeyFactory<K> {\n\n    Reference<K> createKey(K obj);\n    static final KeyFactory DEFAULT = new KeyFactory() {\n\n        @Override\n        public Reference createKey(Object obj) {\n            return new SoftReferenceEx(obj);\n        }\n    };\n}\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/impl/SoftKeyFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching.impl;\n\nimport java.lang.ref.Reference;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class SoftKeyFactory<K> implements KeyFactory<K> {\n\n    @Override\n    public Reference<K> createKey(K obj) {\n        return new SoftReferenceEx<>(obj);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/impl/SoftReferenceEx.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching.impl;\n\nimport java.lang.ref.ReferenceQueue;\nimport java.lang.ref.SoftReference;\nimport java.util.Objects;\n\n/**\n * Extended {@linkplain SoftReference} to allow euqals() and hashCode()\n * to be computed from the referenced object\n *\n * @author Jaroslav Bachorik\n */\nclass SoftReferenceEx<T> extends SoftReference<T> {\n    private int hashCode;\n\n    SoftReferenceEx(T referent, ReferenceQueue<? super T> q) {\n        super(referent, q);\n        hashCode = referent != null ? referent.hashCode() : 0;\n    }\n\n    SoftReferenceEx(T referent) {\n        super(referent);\n        hashCode = referent != null ? referent.hashCode() : 0;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (!(obj instanceof SoftReferenceEx)) return false;\n        SoftReferenceEx other = (SoftReferenceEx)obj;\n        return Objects.equals(get(), other.get());\n    }\n\n    @Override\n    public int hashCode() {\n        return hashCode;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/impl/WeakKeyFactory.java",
    "content": "/*\n * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching.impl;\n\nimport java.lang.ref.Reference;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class WeakKeyFactory<K> implements KeyFactory<K> {\n\n    @Override\n    public Reference<K> createKey(K obj) {\n        return new WeakReferenceEx<>(obj);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/impl/WeakReferenceEx.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching.impl;\n\nimport java.lang.ref.ReferenceQueue;\nimport java.lang.ref.WeakReference;\nimport java.util.Objects;\n\n/**\n * Extended {@linkplain WeakReference} to allow euqals() and hashCode()\n * to be computed from the referenced object\n *\n * @author Jaroslav Bachorik\n */\nclass WeakReferenceEx<T> extends WeakReference<T> {\n    private int hashCode;\n\n    WeakReferenceEx(T referent, ReferenceQueue<? super T> q) {\n        super(referent, q);\n        hashCode = referent != null ? referent.hashCode() : 0;\n    }\n\n    WeakReferenceEx(T referent) {\n        super(referent);\n        hashCode = referent != null ? referent.hashCode() : 0;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (!(obj instanceof WeakReferenceEx)) return false;\n        WeakReferenceEx other = (WeakReferenceEx)obj;\n        return Objects.equals(get(), other.get());\n    }\n\n    @Override\n    public int hashCode() {\n        return hashCode;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/impl/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Implementation of simple caching framework\n */\npackage org.graalvm.visualvm.api.caching.impl;\n"
  },
  {
    "path": "visualvm/caching.api/src/org/graalvm/visualvm/api/caching/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * API/SPI for unified caching\n */\npackage org.graalvm.visualvm.api.caching;\n"
  },
  {
    "path": "visualvm/caching.api/test/unit/src/com/sun/tools/visualvm/api/caching/CacheImplTest.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching;\n\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport static org.junit.Assert.*;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class CacheImplTest {\n    private Cache<String, String> nullCache;\n    private Cache<String, String> constantCache;\n\n    private boolean cacheMissed = false;\n\n    public CacheImplTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n    }\n\n    @Before\n    public void setUp() {\n        nullCache = CacheFactory.getInstance().softMapCache(new EntryFactory<String, String>() {\n            @Override\n            public Entry<String> createEntry(String key) {\n                cacheMissed = true;\n                return null;\n            }\n        });\n        constantCache = CacheFactory.getInstance().softMapCache(new EntryFactory<String, String>() {\n            @Override\n            public Entry<String> createEntry(String key) {\n                cacheMissed = true;\n                return new Entry<>(\"test\");\n            }\n        });\n    }\n\n    @After\n    public void tearDown() {\n        nullCache = null;\n        constantCache = null;\n    }\n\n    /**\n     * Test of retrieveObject method, of class AbstractCache.\n     */\n    @Test\n    public void testRetrieveObjectNoResolver() {\n        System.out.println(\"retrieveObject - no resolver\");\n        String key = \"key\";\n        String result = nullCache.retrieveObject(key);\n        assertNull(result);\n    }\n\n    /**\n     * Test of retrieveObject method, of class AbstractCache.\n     */\n    @Test\n    public void testRetrieveObjectConstantResolver() {\n        System.out.println(\"retrieveObject - constant resolver\");\n        String key = \"key\";\n        String expected = \"test\";\n        String result = constantCache.retrieveObject(key);\n        assertTrue(cacheMissed);\n        assertEquals(expected, result);\n    }\n\n    /**\n     * Test of retrieveObject method, of class AbstractCache.\n     */\n    @Test\n    public void testRetrieveObjectCached() {\n        System.out.println(\"retrieveObject - cached\");\n        String key = \"key\";\n        String expected = \"test\";\n        constantCache.setTTL(500);\n        String result = constantCache.retrieveObject(key);\n        assertTrue(cacheMissed);\n        cacheMissed = false;\n        result = constantCache.retrieveObject(key);\n        assertFalse(cacheMissed);\n        \n        assertEquals(expected, result);\n    }\n\n    /**\n     * Test of retrieveObject method, of class AbstractCache.\n     */\n    @Test\n    public void testRetrieveObjectEvicted() throws Exception {\n        System.out.println(\"retrieveObject - evicted\");\n        String key = \"key\";\n        String expected = \"test\";\n        constantCache.setTTL(500);\n        String result = constantCache.retrieveObject(key);\n        assertTrue(cacheMissed);\n        cacheMissed = false;\n        Thread.sleep(1000);\n        result = constantCache.retrieveObject(key);\n        assertTrue(cacheMissed);\n\n        assertEquals(expected, result);\n    }\n\n    /**\n     * Test of invalidateObject method, of class AbstractCache.\n     */\n    @Test\n    public void testInvalidateObject() {\n        System.out.println(\"invalidateObject\");\n        String key = \"key\";\n        String expResult = \"test\";\n\n        constantCache.retrieveObject(key);\n        cacheMissed = false;\n        constantCache.invalidateObject(key);\n        String result = constantCache.retrieveObject(key);\n        assertTrue(cacheMissed);\n        assertEquals(expResult, result);\n    }\n\n}"
  },
  {
    "path": "visualvm/caching.api/test/unit/src/com/sun/tools/visualvm/api/caching/impl/SoftReferenceExTest.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching.impl;\n\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport static org.junit.Assert.*;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class SoftReferenceExTest {\n\n    public SoftReferenceExTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    /**\n     * Test of equals method, of class SoftReferenceEx.\n     */\n    @Test\n    public void testEqualsNonEmpty() {\n        System.out.println(\"equals - non empty\");\n        SoftReferenceEx instance1 = new SoftReferenceEx(\"xxx\");\n        SoftReferenceEx instance2 = new SoftReferenceEx(\"xxx\");\n        // equals must yield the equals result of the referrents\n        assertEquals(instance2, instance1);\n        // also, the hashcodes must be the same for equaling references\n        assertEquals(instance2.hashCode(), instance1.hashCode());\n    }\n\n    /**\n     * Test of equals method, of class SoftReferenceEx.\n     */\n    @Test\n    public void testEqualsEmpty() {\n        System.out.println(\"equals - empty\");\n        SoftReferenceEx instance1 = new SoftReferenceEx(\"xxx\");\n        SoftReferenceEx instance2 = new SoftReferenceEx(null);\n        SoftReferenceEx instance3 = new SoftReferenceEx(null);\n        // equals for \"non-null\"x\"null\" must yield FALSE\n        assertFalse(instance2.equals(instance1));\n        // equals for \"null\"x\"null\" must yield FALSE\n        assertFalse(instance2.equals(instance3));\n    }\n\n    @Test\n    public void testNotEqualsNonEmpty() {\n        System.out.println(\"equals - non empty\");\n        SoftReferenceEx instance1 = new SoftReferenceEx(\"xxx\");\n        SoftReferenceEx instance2 = new SoftReferenceEx(\"yyy\");\n        // equals must yield the equals result of the referrents\n        assertFalse(instance2.equals(instance1));\n        // also, the hashcodes must not be the same for non-equaling references\n        assertFalse(instance2.hashCode() == instance1.hashCode());\n    }\n}"
  },
  {
    "path": "visualvm/caching.api/test/unit/src/com/sun/tools/visualvm/api/caching/impl/WeakReferenceExTest.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.api.caching.impl;\n\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport static org.junit.Assert.*;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class WeakReferenceExTest {\n\n    public WeakReferenceExTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    /**\n     * Test of equals method, of class WeakReferenceEx.\n     */\n    @Test\n    public void testEqualsNonEmpty() {\n        System.out.println(\"equals - non empty\");\n        WeakReferenceEx instance1 = new WeakReferenceEx(\"xxx\");\n        WeakReferenceEx instance2 = new WeakReferenceEx(\"xxx\");\n        // equals must yield the equals result of the referrents\n        assertEquals(instance2, instance1);\n        // also, the hashcodes must be the same for equaling references\n        assertEquals(instance2.hashCode(), instance1.hashCode());\n    }\n\n    /**\n     * Test of equals method, of class WeakReferenceEx.\n     */\n    @Test\n    public void testEqualsEmpty() {\n        System.out.println(\"equals - empty\");\n        WeakReferenceEx instance1 = new WeakReferenceEx(\"xxx\");\n        WeakReferenceEx instance2 = new WeakReferenceEx(null);\n        WeakReferenceEx instance3 = new WeakReferenceEx(null);\n        // equals for \"non-null\"x\"null\" must yield FALSE\n        assertFalse(instance2.equals(instance1));\n        // equals for \"null\"x\"null\" must yield FALSE\n        assertFalse(instance2.equals(instance3));\n    }\n\n    @Test\n    public void testNotEqualsNonEmpty() {\n        System.out.println(\"equals - non empty\");\n        WeakReferenceEx instance1 = new WeakReferenceEx(\"xxx\");\n        WeakReferenceEx instance2 = new WeakReferenceEx(\"yyy\");\n        // equals must yield the equals result of the referrents\n        assertFalse(instance2.equals(instance1));\n        // also, the hashcodes must not be the same for non-equaling references\n        assertFalse(instance2.hashCode() == instance1.hashCode());\n    }\n}"
  },
  {
    "path": "visualvm/charts/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.charts\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.charts.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/charts/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.charts/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/charts/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.1\n\n"
  },
  {
    "path": "visualvm/charts/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.charts-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/charts/nbproject/project.properties",
    "content": "auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=8\nauxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=80\nauxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=default\njavac.source=1.8\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/charts/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.charts</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.charts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <test-dependencies>\n                <test-type>\n                    <name>unit</name>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.libs.junit4</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                </test-type>\n            </test-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.charts</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/charts/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Charts\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/ChartFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts;\n\n/**\n * Factory class to create custom charts.\n *\n * @author Jiri Sedlacek\n */\npublic final class ChartFactory {\n\n    /**\n     * Creates an instance of SimpleXYChartSupport representing a simple XY chart.\n     *\n     * @param descriptor chart descriptor\n     * @return instance of SimpleXYChartSupport representing a simple XY chart\n     */\n    public static SimpleXYChartSupport createSimpleXYChart(SimpleXYChartDescriptor descriptor) {\n        return new SimpleXYChartSupport(descriptor.getChartTitle(),\n                                        descriptor.getXAxisDescription(),\n                                        descriptor.getYAxisDescription(),\n                                        descriptor.getChartType(),\n                                        descriptor.getInitialYMargin(),\n                                        descriptor.getItemNames(),\n                                        descriptor.getItemColors(),\n                                        descriptor.getLineWidths(),\n                                        descriptor.getLineColors(),\n                                        descriptor.getFillColors1(),\n                                        descriptor.getFillColors2(),\n                                        descriptor.getMinValue(),\n                                        descriptor.getMaxValue(),\n                                        descriptor.getChartFactor(),\n                                        descriptor.getCustomFormat(),\n                                        descriptor.areItemsHideable(),\n                                        descriptor.getValuesBuffer(),\n                                        descriptor.getDetailsItems(),\n                                        descriptor.getLimitYValue());\n    }\n\n    \n    private ChartFactory() {}\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/ColorFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts;\n\nimport java.awt.Color;\nimport org.graalvm.visualvm.uisupport.UISupport;\n\n/**\n * Utility class to access colors predefined for VisualVM.\n *\n * @author Jiri Sedlacek\n */\nfinal class ColorFactory {\n    \n    private static final Color[] PREDEFINED_COLORS = new Color[] {\n                                                new Color(241, 154,  42),\n                                                new Color( 32, 171, 217),\n                                                new Color(144,  97, 207),\n                                                new Color(158, 156,   0)\n    };\n\n    private static final Color[][] PREDEFINED_GRADIENTS = !UISupport.isDarkResultsBackground() ?\n    new Color[][] {\n        new Color[] { new Color(245, 204, 152), new Color(255, 243, 226) },\n        new Color[] { new Color(151, 223, 246), new Color(227, 248, 255) },\n        new Color[] { new Color(200, 163, 248), new Color(242, 232, 255) },\n        new Color[] { new Color(212, 211, 131), new Color(244, 243, 217) }\n    } :\n    new Color[][] {\n        new Color[] { new Color(145, 104, 52), new Color(155, 143, 126) },\n        new Color[] { new Color(51, 123, 146), new Color(127, 148, 155) },\n        new Color[] { new Color(100, 63, 148), new Color(142, 132, 155) },\n        new Color[] { new Color(112, 111, 31), new Color(144, 143, 117) }\n    };\n    \n\n    /**\n     * Returns number of colors predefined for VisualVM charts.\n     * Always contains at least 4 colors.\n     *\n     * @return number of colors predefined for VisualVM charts\n     */\n    public static int getPredefinedColorsCount() {\n        return PREDEFINED_COLORS.length;\n    }\n\n    /**\n     * Returns a color predefined for VisualVM charts.\n     *\n     * @param index index of the predefined color\n     * @return color predefined for VisualVM charts\n     */\n    public static Color getPredefinedColor(int index) {\n        return PREDEFINED_COLORS[index];\n    }\n\n\n    /**\n     * Returns number of color pairs predefined for VisualVM charts gradients.\n     * Always contains at least 4 color pairs.\n     *\n     * @return number of color pairs predefined for VisualVM charts gradients\n     */\n    public static int getPredefinedGradientsCount() {\n        return PREDEFINED_GRADIENTS.length;\n    }\n\n    /**\n     * Returns a color pair predefined for VisualVM charts gradients.\n     *\n     * @param index index of the predefined color pair\n     * @return color pair predefined for VisualVM charts gradients\n     */\n    public static Color[] getPredefinedGradient(int index) {\n        return PREDEFINED_GRADIENTS[index];\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/SimpleXYChartDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts;\n\nimport org.graalvm.visualvm.charts.xy.SimpleXYChartUtils;\nimport java.awt.Color;\nimport java.text.NumberFormat;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Descriptor to define a simple XY chart.\n *\n * @author Jiri Sedlacek\n */\npublic final class SimpleXYChartDescriptor {\n\n    // --- Predefined constructors ---------------------------------------------\n\n    public static SimpleXYChartDescriptor decimal(long initialYMargin,\n                                                  boolean hideableItems,\n                                                  int valuesBuffer) {\n\n        return decimal(initialYMargin, 1d, hideableItems, valuesBuffer);\n    }\n\n    public static SimpleXYChartDescriptor decimal(long initialYMargin,\n                                                  double chartFactor,\n                                                  boolean hideableItems,\n                                                  int valuesBuffer) {\n\n        return decimal(0, SimpleXYChartSupport.MAX_UNDEFINED, initialYMargin,\n                       chartFactor, hideableItems, valuesBuffer);\n    }\n    \n    public static SimpleXYChartDescriptor decimal(long minValue,\n                                                  long maxValue,\n                                                  long initialYMargin,\n                                                  double chartFactor,\n                                                  boolean hideableItems,\n                                                  int valuesBuffer) {\n\n        return decimal(minValue, maxValue, initialYMargin, chartFactor,\n                       null, hideableItems, valuesBuffer);\n    }\n\n    public static SimpleXYChartDescriptor decimal(long minValue,\n                                                  long maxValue,\n                                                  long initialYMargin,\n                                                  double chartFactor,\n                                                  NumberFormat customFormat,\n                                                  boolean hideableItems,\n                                                  int valuesBuffer) {\n\n        return new SimpleXYChartDescriptor(SimpleXYChartUtils.TYPE_DECIMAL,\n                                           minValue, maxValue,\n                                           initialYMargin, hideableItems,\n                                           chartFactor, customFormat, valuesBuffer);\n    }\n\n\n    public static SimpleXYChartDescriptor bytes(long initialYMargin,\n                                                boolean hideableItems,\n                                                int valuesBuffer) {\n\n        return bytes(0, SimpleXYChartSupport.MAX_UNDEFINED, initialYMargin,\n                     hideableItems, valuesBuffer);\n    }\n\n    public static SimpleXYChartDescriptor bytes(long minValue,\n                                                long maxValue,\n                                                long initialYMargin,\n                                                boolean hideableItems,\n                                                int valuesBuffer) {\n\n        return new SimpleXYChartDescriptor(SimpleXYChartUtils.TYPE_BYTES,\n                                           minValue, maxValue,\n                                           initialYMargin, hideableItems,\n                                           1d, null, valuesBuffer);\n    }\n\n    public static SimpleXYChartDescriptor bitsPerSec(long initialYMargin,\n                                                boolean hideableItems,\n                                                int valuesBuffer) {\n\n        return bitsPerSec(0, SimpleXYChartSupport.MAX_UNDEFINED, initialYMargin,\n                     hideableItems, valuesBuffer);\n    }\n\n    public static SimpleXYChartDescriptor bitsPerSec(long minValue,\n                                                long maxValue,\n                                                long initialYMargin,\n                                                boolean hideableItems,\n                                                int valuesBuffer) {\n\n        return new SimpleXYChartDescriptor(SimpleXYChartUtils.TYPE_BITS_PER_SEC,\n                                           minValue, maxValue,\n                                           initialYMargin, hideableItems,\n                                           1d, null, valuesBuffer);\n    }\n\n    public static SimpleXYChartDescriptor percent(boolean hideableItems,\n                                                  int valuesBuffer) {\n\n        return percent(hideableItems, 1d, valuesBuffer);\n    }\n\n    public static SimpleXYChartDescriptor percent(boolean hideableItems,\n                                                  double chartFactor,\n                                                  int valuesBuffer) {\n\n        return percent(0, 100, 100, hideableItems, chartFactor, valuesBuffer);\n    }\n\n    public static SimpleXYChartDescriptor percent(long minValue,\n                                                  long maxValue,\n                                                  long initialYMargin,\n                                                  boolean hideableItems,\n                                                  double chartFactor,\n                                                  int valuesBuffer) {\n\n        long max = (long)Math.ceil(maxValue / chartFactor);\n        long init = (long)Math.ceil(initialYMargin / chartFactor);\n        return new SimpleXYChartDescriptor(SimpleXYChartUtils.TYPE_PERCENT,\n                                           minValue, max,\n                                           init, hideableItems,\n                                           chartFactor, null, valuesBuffer);\n    }\n\n\n    // --- Items definition ----------------------------------------------------\n\n    public void addLineItems(String... itemNames) {\n        for (String itemName : itemNames) {\n            Color color = getNextItemColor();\n            addItem(itemName, color, 2f, color, null, null);\n        }\n    }\n\n    public void addFillItems(String... itemNames) {\n        for (String itemName : itemNames) {\n            Color[] gradients = getNextItemGradient();\n            addItem(itemName, gradients[0], 2f, null, gradients[0], gradients[1]);\n        }\n    }\n\n    public void addLineFillItems(String... itemNames) {\n        for (String itemName : itemNames) {\n            Color color = getNextItemColor();\n            Color[] gradients = getNextItemGradient();\n            addItem(itemName, color, 2f, color, gradients[0], gradients[1]);\n        }\n    }\n\n\n    public void addItem(String itemName, Color itemColor, float lineWidth,\n                        Color lineColor, Color fillColor1, Color fillColor2) {\n        itemNames.add(itemName);\n        itemColors.add(itemColor);\n        lineWidths.add(lineWidth);\n        lineColors.add(lineColor);\n        fillColors1.add(fillColor1);\n        fillColors2.add(fillColor2);\n    }\n\n\n    private Color getNextItemColor() {\n        int newItemIndex = itemNames.size();\n        int colorsCount  = ColorFactory.getPredefinedColorsCount();\n        Color color = null;\n\n        if (newItemIndex >= colorsCount) {\n            color = ColorFactory.getPredefinedColor(newItemIndex % colorsCount);\n            int darkerFactor = newItemIndex / colorsCount;\n            while (darkerFactor-- > 0) color = color.darker();\n        } else {\n            color = ColorFactory.getPredefinedColor(newItemIndex);\n        }\n\n        return color;\n    }\n\n    private Color[] getNextItemGradient() {\n        int newItemIndex = itemNames.size();\n        int colorsCount  = ColorFactory.getPredefinedColorsCount();\n        Color[] color = null;\n\n        if (newItemIndex >= colorsCount) {\n            color = ColorFactory.getPredefinedGradient(newItemIndex % colorsCount);\n            int darkerFactor = newItemIndex / colorsCount;\n            while (darkerFactor-- > 0) {\n                color[0] = color[0].darker();\n                color[1] = color[1].darker();\n            }\n        } else {\n            color = ColorFactory.getPredefinedGradient(newItemIndex);\n        }\n\n        return color;\n    }\n\n    \n    // --- Details definition --------------------------------------------------\n\n    public void setDetailsItems(String[] detailNames) {\n        this.detailNames = detailNames != null ? detailNames.clone() : null;\n    }\n\n    public void setLimitYValue(long limit) {\n        limitYValue = limit;\n    }\n\n    // --- Axes description ----------------------------------------------------\n\n    public void setChartTitle(String chartTitle) {\n        this.chartTitle = chartTitle;\n    }\n\n    public void setXAxisDescription(String xAxisDescription) {\n        this.xAxisDescription = xAxisDescription;\n    }\n\n    public void setYAxisDescription(String yAxisDescription) {\n        this.yAxisDescription = yAxisDescription;\n    }\n\n\n    // --- Internal interface --------------------------------------------------\n\n    int getChartType() { return chartType; }\n\n    long getMinValue() { return minValue; }\n\n    long getMaxValue() { return maxValue; }\n\n    long getInitialYMargin() { return initialYMargin; }\n\n    boolean areItemsHideable() { return hideableItems; }\n\n    double getChartFactor() { return chartFactor; }\n    \n    NumberFormat getCustomFormat() { return customFormat; }\n\n    int getValuesBuffer() { return valuesBuffer; }\n\n\n    String[] getItemNames() {\n        return itemNames.toArray(new String[0]);\n    }\n\n    Color[] getItemColors() {\n        return itemColors.toArray(new Color[0]);\n    }\n\n    float[] getLineWidths() {\n        if (lineWidths.isEmpty()) return null;\n        float[] floats = new float[lineWidths.size()];\n        for (int i = 0; i < floats.length; i++) floats[i] = lineWidths.get(i);\n        return floats;\n    }\n\n    Color[] getLineColors() {\n        return lineColors.isEmpty() ? null :\n               lineColors.toArray(new Color[0]);\n    }\n\n    Color[] getFillColors1() {\n        return fillColors1.isEmpty() ? null :\n               fillColors1.toArray(new Color[0]);\n    }\n\n    Color[] getFillColors2() {\n        return fillColors2.isEmpty() ? null :\n               fillColors2.toArray(new Color[0]);\n    }\n\n    String[] getDetailsItems() {\n        return detailNames;\n    }\n\n    String getChartTitle() {\n        return chartTitle;\n    }\n\n    String getXAxisDescription() {\n        return xAxisDescription;\n    }\n\n    String getYAxisDescription() {\n        return yAxisDescription;\n    }\n\n    long getLimitYValue() {\n        return limitYValue;\n    }\n\n    // --- Private implementation ----------------------------------------------\n\n    private final int          chartType;\n    private final long         minValue;\n    private final long         maxValue;\n    private final long         initialYMargin;\n    private final boolean      hideableItems;\n    private final double       chartFactor;\n    private final NumberFormat customFormat;\n    private final int          valuesBuffer;\n\n    private final List<String> itemNames  = new ArrayList<>();\n    private final List<Color>  itemColors = new ArrayList<>();\n    private final List<Float>  lineWidths = new ArrayList<>();\n    private final List<Color>  lineColors = new ArrayList<>();\n    private final List<Color>  fillColors1 = new ArrayList<>();\n    private final List<Color>  fillColors2 = new ArrayList<>();\n    private       String[]     detailNames;\n\n    private       String       chartTitle;\n    private       String       xAxisDescription;\n    private       String       yAxisDescription;\n    private       long         limitYValue;\n\n\n    private SimpleXYChartDescriptor(int chartType,\n                                    long minValue,\n                                    long maxValue,\n                                    long initialYMargin,\n                                    boolean hideableItems,\n                                    double chartFactor,\n                                    NumberFormat customFormat,\n                                    int valuesBuffer) {\n\n        this.chartType = chartType;\n        this.minValue = minValue;\n        this.maxValue = maxValue;\n        this.initialYMargin = initialYMargin;\n        this.hideableItems = hideableItems;\n        this.chartFactor = chartFactor;\n        this.customFormat = customFormat;\n        this.valuesBuffer = valuesBuffer;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/SimpleXYChartSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts;\n\nimport org.graalvm.visualvm.charts.xy.SimpleXYChartUtils;\nimport org.graalvm.visualvm.charts.xy.XYPaintersModel;\nimport org.graalvm.visualvm.charts.xy.XYStorage;\nimport java.awt.Color;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.text.NumberFormat;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.JComponent;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\n\n/**\n * Handle to access a simple XY chart. The chart supports adding new data and\n * updating the details area.\n *\n * @author Jiri Sedlacek\n */\npublic final class SimpleXYChartSupport {\n\n    private final static Logger LOGGER = Logger.getLogger(SimpleXYChartSupport.class.getName());\n\n    // --- Public chart boundary constants -------------------------------------\n\n    public static final long MIN_UNDEFINED = Long.MAX_VALUE;\n    public static final long MAX_UNDEFINED = Long.MIN_VALUE;\n\n\n    // --- Instance variables --------------------------------------------------\n\n    private final String chartTitle;\n    private final String xAxisDescription;\n    private final String yAxisDescription;\n\n    private final int chartType;\n    private final boolean hideItems;\n    private final Color[] itemColors;\n    private final long initialYMargin;\n    private final String[] detailsItems;\n    private final double chartFactor;\n    private final NumberFormat customFormat;\n    private final long limitYValue;\n\n    private final XYStorage storage;\n    private final SynchronousXYItemsModel itemsModel;\n    private final XYPaintersModel paintersModel;\n    \n    private JComponent chartUI;\n    private SimpleXYChartUtils.DetailsHandle detailsHandle;\n    private boolean legendVisible;\n    private boolean zoomingEnabled;\n    \n\n    // --- Public interface ----------------------------------------------------\n\n    /**\n     * Returns a JComponent containing the chart.\n     * <br><br><b>Note:</b> This method must be called in the Event Dispatch Thread.\n     *\n     * @return JComponent containing the chart;\n     */\n    public JComponent getChart() {\n        if (chartUI == null) {\n            chartUI = SimpleXYChartUtils.createChartUI(chartTitle, xAxisDescription,\n                                                     yAxisDescription, chartType,\n                                                     itemColors, initialYMargin,\n                                                     hideItems, legendVisible,\n                                                     zoomingEnabled, chartFactor,\n                                                     customFormat, storage,\n                                                     itemsModel, paintersModel,\n                                                     limitYValue);\n            if (detailsItems != null)\n                detailsHandle = SimpleXYChartUtils.createDetailsArea(detailsItems,\n                                                                     chartUI);\n        }\n        return chartUI;\n    }\n\n    /**\n     * Saves chart values into the provided OutputStream. This method should not\n     * be called in the Event Dispatch Thread.\n     *\n     * @param os OutputStream into which to save the chart values\n     * @throws IOException if an I/O error occurs\n     */\n    public void saveValues(OutputStream os) throws IOException {\n        storage.saveValues(os);\n    }\n\n    /**\n     * Loads chart values from the provided InputStream. This method should not\n     * be called in the Event Dispatch Thread.\n     *\n     * @param is InputStream from which to load the chart values\n     * @throws IOException if an I/O error occurs\n     */\n    public void loadValues(InputStream is) throws IOException {\n        storage.loadValues(is);\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                itemsModel.valuesAdded();\n                // Do not catch ProfilerXYItemsModel: new timestamp T1 not greater than previous T0, skipping the values.\n                // Should be synchronized since the originally saved model had to be synchronized\n            }\n        });\n    }\n\n    /**\n     * Adds a packet of values.\n     * <br><br><b>Note:</b> This method can be called from any thread.\n     *\n     * @param timestamp timestamp of the data packet\n     * @param values data packet\n     */\n    public void addValues(final long timestamp, final long[] values) {\n        Runnable valuesUpdater = new Runnable() {\n            public void run() {\n                storage.addValues(timestamp, values);\n                try {\n                    itemsModel.valuesAdded();\n                } catch (IllegalArgumentException e) {\n                    // ProfilerXYItemsModel: new timestamp T1 not greater than previous T0, skipping the values.\n                    LOGGER.log(Level.INFO, \"Results not synchronized\", e); // NOI18N\n                }\n            }\n        };\n        if (SwingUtilities.isEventDispatchThread()) valuesUpdater.run();\n        else SwingUtilities.invokeLater(valuesUpdater);\n    }\n\n    /**\n     * Updates the details area of the chart.\n     * <br><br><b>Note:</b> This method can be called from any thread.\n     *\n     * @param details details packet\n     */\n    public void updateDetails(final String[] details) {\n        Runnable detailsUpdater = new Runnable() {\n            public void run() { detailsHandle.updateDetails(details); }\n        };\n        if (SwingUtilities.isEventDispatchThread()) detailsUpdater.run();\n        else SwingUtilities.invokeLater(detailsUpdater);\n    }\n    \n    \n    /**\n     * Shows or hides legend section of the chart.\n     * <br><br><b>Note:</b> This method can be called from any thread.\n     *\n     * @param visible new visibility of the legend section of the chart\n     */\n    public void setLegendVisible(final boolean visible) {\n        Runnable visibilityUpdater = new Runnable() {\n            public void run() {\n                if (legendVisible == visible) return;\n                legendVisible = visible;\n                if (chartUI != null)\n                    SimpleXYChartUtils.setLegendVisible(chartUI, legendVisible);\n            }\n        };\n        if (SwingUtilities.isEventDispatchThread()) visibilityUpdater.run();\n        else SwingUtilities.invokeLater(visibilityUpdater);\n    }\n    \n    /**\n     * Returns true if legend section of the chart is visible, false otherwise.\n     * <br><br><b>Note:</b> This method must be called in the Event Dispatch Thread.\n     *\n     * @return true if legend section of the chart is visible, false otherwise\n     */\n    public boolean isLegendVisible() {\n        return legendVisible;\n    }\n    \n    \n    /**\n     * Enables or disables zooming the chart data.\n     * <br><br><b>Note:</b> This method can be called from any thread.\n     * <br><br><b>Warning:</b> Displaying live data by a zoomed chart may result\n     * in incorrect appearance once the data buffer starts dropping oldest values.\n     *\n     * @param zooming true if zooming is enabled, false otherwise\n     */\n    public void setZoomingEnabled(final boolean zooming) {\n        Runnable visibilityUpdater = new Runnable() {\n            public void run() {\n                if (zoomingEnabled == zooming) return;\n                zoomingEnabled = zooming;\n                if (chartUI != null)\n                    SimpleXYChartUtils.setZoomingEnabled(chartUI, zoomingEnabled);\n            }\n        };\n        if (SwingUtilities.isEventDispatchThread()) visibilityUpdater.run();\n        else SwingUtilities.invokeLater(visibilityUpdater);\n    }\n    \n    /**\n     * Returns true if charts zooming is enabled, false otherwise.\n     * <br><br><b>Note:</b> This method must be called in the Event Dispatch Thread.\n     *\n     * @return true if charts zooming is enabled, false otherwise\n     */\n    public boolean isZoomingEnabled() {\n        return zoomingEnabled;\n    }\n\n\n    /**\n     * Formats a decimal value to String. Use this method to make sure the value\n     * appears in the same format as used in the chart (tooltip). Useful for\n     * updating details area.\n     * <br><br><b>Note:</b> This method must be called in the Event Dispatch Thread.\n     *\n     * @param value value to be formatted\n     * @return formatted value in the same format as used in the chart\n     */\n    public String formatDecimal(long value) {\n        return SimpleXYChartUtils.formatDecimal(value * chartFactor, customFormat);\n    }\n\n    /**\n     * Formats a bytes value to String. Use this method to make sure the value\n     * appears in the same format as used in the chart (tooltip). Useful for\n     * updating details area.\n     * <br><br><b>Note:</b> This method must be called in the Event Dispatch Thread.\n     *\n     * @param value value to be formatted\n     * @return formatted value in the same format as used in the chart\n     */\n    public String formatBytes(long value) {\n        return SimpleXYChartUtils.formatBytes((long)(value * chartFactor));\n    }\n\n    /**\n     * Formats a percent value to String. Use this method to make sure the value\n     * appears in the same format as used in the chart (tooltip). Useful for\n     * updating details area.\n     * <br><br><b>Note:</b> This method must be called in the Event Dispatch Thread.\n     *\n     * @param value value to be formatted\n     * @return formatted value in the same format as used in the chart\n     */\n    public String formatPercent(long value) {\n        return SimpleXYChartUtils.formatPercent(value * chartFactor);\n    }\n\n    /**\n     * Formats a time value to String. Use this method to make sure the value\n     * appears in the same format as used in the chart (tooltip). Useful for\n     * updating details area.\n     * <br><br><b>Note:</b> This method must be called in the Event Dispatch Thread.\n     *\n     * @param value value to be formatted\n     * @return formatted value in the same format as used in the chart\n     */\n    public String formatTime(long value) {\n        int timestamps = storage.getTimestampsCount();\n        if (timestamps == 0) return SimpleXYChartUtils.formatTime(value, value, value);\n        else return SimpleXYChartUtils.formatTime(value, storage.getTimestamp(0),\n                                                  storage.getTimestamp(timestamps - 1));\n    }\n\n\n    // --- Internal constructors -----------------------------------------------\n\n    SimpleXYChartSupport(String chartTitle, String xAxisDescription, String yAxisDescription,\n                         int chartType, long initialYMargin, String[] itemNames, Color[] itemColors,\n                         float[] lineWidths, Color[] lineColors, Color[] fillColors1, Color[] fillColors2,\n                         long minValue, long maxValue, double chartFactor, NumberFormat customFormat,\n                         boolean hideItems, int valuesBuffer, String[] detailsItems, long limit) {\n\n        this.chartTitle = chartTitle;\n        this.xAxisDescription = xAxisDescription;\n        this.yAxisDescription = yAxisDescription;\n\n        this.chartType = chartType;\n        this.hideItems = hideItems;\n        this.itemColors = itemColors;\n        this.initialYMargin = initialYMargin;\n        this.detailsItems = detailsItems;\n        this.chartFactor = chartFactor;\n        this.customFormat = customFormat;\n        this.limitYValue = limit;\n        \n        storage = SimpleXYChartUtils.createStorage(valuesBuffer);\n        itemsModel = SimpleXYChartUtils.createItemsModel(storage, itemNames, minValue, maxValue);\n        paintersModel = SimpleXYChartUtils.createPaintersModel(lineWidths, lineColors,\n                                            fillColors1, fillColors2, itemsModel);\n        \n        legendVisible = true;\n        zoomingEnabled = false;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Support for custom charts in VisualVM.\n */\npackage org.graalvm.visualvm.charts;\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/swing/RotateLabelUI.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.swing;\n\nimport java.awt.Dimension;\nimport java.awt.FontMetrics;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport java.awt.geom.AffineTransform;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.plaf.basic.BasicHTML;\nimport javax.swing.plaf.basic.BasicLabelUI;\nimport javax.swing.text.View;\n\n/**\n * LabelUI for displaying rotated labels.\n * Based on BasicLabelUI; modified paint(), layout() and get*Size().\n *\n * @author Jiri Sedlacek\n */\npublic class RotateLabelUI extends BasicLabelUI {\n\n    private static final double ROTATE_0   = 0;\n    private static final double ROTATE_90  = Math.PI / 2;\n    private static final double ROTATE_180 = Math.PI;\n    private static final double ROTATE_270 = -Math.PI / 2;\n\n\n    public static final RotateLabelUI R0 = rotate0();\n    public static final RotateLabelUI R90 = rotate90();\n    public static final RotateLabelUI R180 = rotate180();\n    public static final RotateLabelUI R270 = rotate270();\n\n\n    private final double rotation;\n    private final boolean vertical;\n\n\n    private static RotateLabelUI rotate0()   { return new RotateLabelUI(ROTATE_0); }\n    private static RotateLabelUI rotate90()  { return new RotateLabelUI(ROTATE_90); }\n    private static RotateLabelUI rotate180() { return new RotateLabelUI(ROTATE_180); }\n    private static RotateLabelUI rotate270() { return new RotateLabelUI(ROTATE_270); }\n\n    \n    private RotateLabelUI(double rotation) {\n        this.rotation = rotation;\n        this.vertical = rotation == ROTATE_90 || rotation == ROTATE_270;\n    }\n\n\n    private static Rectangle paintIconR = new Rectangle();\n    private static Rectangle paintTextR = new Rectangle();\n    private static Rectangle paintViewR = new Rectangle();\n    private static Insets    paintViewInsets = new Insets(0, 0, 0, 0);\n\n\n    public void paint(Graphics g, JComponent c) {\n        JLabel label = (JLabel)c;\n        String text = label.getText();\n        Icon icon = label.isEnabled() ? label.getIcon() : label.getDisabledIcon();\n\n        if (icon == null && text == null) return;\n\n        Graphics2D g2 = (Graphics2D) g;\n    \tAffineTransform transform = null;\n\n        if (rotation != ROTATE_0) {\n            transform = g2.getTransform();\n            g2.rotate(rotation);\n            \n            if (rotation == ROTATE_90) {\n                g2.translate(0, -c.getWidth());\n            } else if (rotation == ROTATE_180) {\n                g2.translate(-c.getWidth(), -c.getHeight());\n            } else if (rotation == ROTATE_270) {\n                g2.translate(-c.getHeight(), 0);\n            }\n        }\n\n        FontMetrics fm = g.getFontMetrics();\n        String clippedText = layout(label, fm, c.getWidth(), c.getHeight());\n\n        if (icon != null) icon.paintIcon(c, g, paintIconR.x, paintIconR.y);\n\n        if (text != null) {\n\t    View v = (View)c.getClientProperty(BasicHTML.propertyKey);\n\t    if (v != null) {\n\t\tv.paint(g, paintTextR);\n\t    } else {\n\t\tint textX = paintTextR.x;\n\t\tint textY = paintTextR.y + fm.getAscent();\n\n\t\tif (label.isEnabled()) {\n\t\t    paintEnabledText(label, g, clippedText, textX, textY);\n\t\t} else {\n\t\t    paintDisabledText(label, g, clippedText, textX, textY);\n\t\t}\n\t    }\n        }\n\n        if (transform != null) g2.setTransform(transform);\n    }\n\n\n    private String layout(JLabel label, FontMetrics fm, int width, int height) {\n        Insets insets = label.getInsets(paintViewInsets);\n        String text = label.getText();\n        Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon();\n        paintViewR.x = insets.left;\n        paintViewR.y = insets.top;\n\n        if (vertical) {\n            paintViewR.height = width - (insets.left + insets.right);\n            paintViewR.width = height - (insets.top + insets.bottom);\n        } else {\n            paintViewR.width = width - (insets.left + insets.right);\n            paintViewR.height = height - (insets.top + insets.bottom);\n        }\n\n        paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0;\n        paintTextR.x = paintTextR.y = paintTextR.width = paintTextR.height = 0;\n        return layoutCL(label, fm, text, icon, paintViewR, paintIconR, paintTextR);\n    }\n\n\n    public Dimension getPreferredSize(JComponent c) {\n        return getDimension(super.getPreferredSize(c));\n    }\n\n    public Dimension getMinimumSize(JComponent c) {\n        return getDimension(super.getMinimumSize(c));\n    }\n\n    public Dimension getMaximumSize(JComponent c) {\n    \treturn getDimension(super.getMaximumSize(c));\n    }\n\n    \n    private Dimension getDimension(Dimension dimension) {\n        if (!vertical) return dimension;\n        int width = dimension.width;\n        dimension.width = dimension.height;\n        dimension.height = width;\n        return dimension;\n    }\n\n}\n\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nSimpleXYChart_ZoomInString=Zoom In (Mouse Wheel)\nSimpleXYChart_ZoomOutString=Zoom Out (Mouse Wheel)\nSimpleXYChart_FixedScaleString=Fixed Scale (Mouse Wheel Click)\nSimpleXYChart_ScaleToFitString=Scale To Fit (Mouse Wheel Click)\n\n# HTML-formatted message format for chart details items, example: 'Item1: 123'\nSimpleXYChartUtils_DetailsItemFormat=<b>{0}: </b>{1}\n\n# Bytes value formatting, example: '1,234,567 B'\nSimpleXYChartUtils_BytesFormat={0} B\n\n# Bits per sec value formatting, example: '1,234,567 bps'\nSimpleXYChartUtils_BitsPerSecFormat={0} bit/s\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/ColorIcon.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport java.awt.*;\n\n\n/**\n * Copy of org.graalvm.visualvm.lib.ui.components.ColorIcon.\n * \n * @author Jiri Sedlacek\n */\nfinal class ColorIcon implements javax.swing.Icon {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Color borderColor = Color.BLACK;\n    private Color color = Color.BLACK;\n    private int height = 5;\n    private int width = 5;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of ColorIcon */\n    ColorIcon() {\n    }\n\n    ColorIcon(Color color) {\n        this();\n        setColor(color);\n    }\n\n    ColorIcon(Color color, int width, int height) {\n        this(color);\n        setIconWidth(width);\n        setIconHeight(height);\n    }\n\n    ColorIcon(Color color, Color borderColor, int width, int height) {\n        this(color, width, height);\n        setBorderColor(borderColor);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setBorderColor(Color borderColor) {\n        this.borderColor = borderColor;\n    }\n\n    public Color getBorderColor() {\n        return borderColor;\n    }\n\n    public void setColor(Color color) {\n        this.color = color;\n    }\n\n    public Color getColor() {\n        return color;\n    }\n\n    public void setIconHeight(int height) {\n        this.height = height;\n    }\n\n    public int getIconHeight() {\n        return height;\n    }\n\n    public void setIconWidth(int width) {\n        this.width = width;\n    }\n\n    public int getIconWidth() {\n        return width;\n    }\n\n    public void paintIcon(java.awt.Component c, java.awt.Graphics g, int x, int y) {\n        if (color != null) {\n            g.setColor(color);\n            g.fillRect(x, y, width, height);\n        }\n\n        if (borderColor != null) {\n            g.setColor(borderColor);\n            g.drawRect(x, y, width - 1, height - 1);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/SimpleXYChart.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.Icon;\nimport javax.swing.JScrollBar;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChart;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass SimpleXYChart extends SynchronousXYChart {\n    \n    private static final Icon ZOOM_IN_ICON = Icons.getIcon(GeneralIcons.ZOOM_IN);\n    private static final Icon ZOOM_OUT_ICON = Icons.getIcon(GeneralIcons.ZOOM_OUT);\n    private static final Icon FIXED_SCALE_ICON = Icons.getIcon(GeneralIcons.ZOOM);\n    private static final Icon SCALE_TO_FIT_ICON = Icons.getIcon(GeneralIcons.SCALE_TO_FIT);\n    \n    private JScrollBar scroller;\n    \n    private ZoomInAction zoomInAction;\n    private ZoomOutAction zoomOutAction;\n    private ToggleViewAction toggleViewAction;\n    \n    private ChartConfigurationListener listener;\n    \n    \n    SimpleXYChart(SynchronousXYItemsModel itemsModel, PaintersModel paintersModel) {\n        super(itemsModel, paintersModel);\n        setMousePanningEnabled(false);\n    }\n    \n    \n    void setZoomingEnabled(boolean zooming) {\n        if (isZoomingEnabled() == zooming) return;\n        \n        if (zooming) enableZooming();\n        else disableZooming();\n    }\n    \n    boolean isZoomingEnabled() {\n        return listener != null;\n    }\n    \n    \n    JScrollBar getScroller() {\n        return scroller;\n    }\n    \n    Action[] getActions() {\n        return toggleViewAction == null ? new Action[0] :\n               new Action[] { toggleViewAction, zoomInAction, zoomOutAction };\n    }\n    \n    \n    private void enableZooming() {\n        scroller = new JScrollBar(JScrollBar.HORIZONTAL);\n        attachHorizontalScrollBar(scroller);\n        \n        zoomInAction = new ZoomInAction();\n        zoomOutAction = new ZoomOutAction();\n        toggleViewAction = new ToggleViewAction();\n        \n        listener = new VisibleBoundsListener();\n        addConfigurationListener(listener);\n    }\n    \n    private void disableZooming() {\n        removeConfigurationListener(listener);\n        listener = null;\n        \n        detachHorizontalScrollBar();\n        scroller = null;\n        \n        zoomInAction = null;\n        zoomOutAction = null;\n        toggleViewAction = null;\n    }\n    \n    \n    private class ZoomInAction extends AbstractAction {\n\n//        private static final int ONE_SECOND_WIDTH_THRESHOLD = 200;\n\n        ZoomInAction() {\n            super();\n\n            putValue(SHORT_DESCRIPTION, NbBundle.getMessage(SimpleXYChart.class,\n                                        \"SimpleXYChart_ZoomInString\")); // NOI18N\n            putValue(SMALL_ICON, ZOOM_IN_ICON);\n\n            updateAction();\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            boolean followsWidth = currentlyFollowingDataWidth();\n            zoom(getWidth() / 2, getHeight() / 2, 2d);\n            if (followsWidth) setOffset(getMaxOffsetX(), getOffsetY());\n            \n            repaintDirty();\n        }\n\n        private void updateAction() {\n            Timeline timeline = ((SynchronousXYItemsModel)getItemsModel()).getTimeline();\n            setEnabled(timeline.getTimestampsCount() > 1 && !fitsWidth() /*&&\n                       getViewWidth(1000) < ONE_SECOND_WIDTH_THRESHOLD*/);\n            // #165429 - don't disable zoom icons until mouse zoom is also disabled\n        }\n\n    }\n\n    private class ZoomOutAction extends AbstractAction {\n\n//        private static final float USED_CHART_WIDTH_THRESHOLD = 0.33f;\n\n        ZoomOutAction() {\n            super();\n\n            putValue(SHORT_DESCRIPTION, NbBundle.getMessage(SimpleXYChart.class,\n                                        \"SimpleXYChart_ZoomOutString\")); // NOI18N\n            putValue(SMALL_ICON, ZOOM_OUT_ICON);\n\n            updateAction();\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            boolean followsWidth = currentlyFollowingDataWidth();\n            zoom(getWidth() / 2, getHeight() / 2, 0.5d);\n            if (followsWidth) setOffset(getMaxOffsetX(), getOffsetY());\n            \n            repaintDirty();\n        }\n\n        private void updateAction() {\n            Timeline timeline = ((SynchronousXYItemsModel)getItemsModel()).getTimeline();\n            setEnabled(timeline.getTimestampsCount() > 1 && !fitsWidth() /*&&\n                       getContentsWidth() > getWidth() * USED_CHART_WIDTH_THRESHOLD*/);\n            // #165429 - don't disable zoom icons until mouse zoom is also disabled\n        }\n\n    }\n\n    private class ToggleViewAction extends AbstractAction {\n\n        private long origOffsetX  = -1;\n        private double origScaleX = -1;\n\n        ToggleViewAction() {\n            super();\n            updateAction();\n            addMouseListener(new MouseAdapter() {\n                public void mouseClicked(MouseEvent e) {\n                    if (SwingUtilities.isMiddleMouseButton(e))\n                        actionPerformed(null);\n                }\n            });\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            boolean fitsWidth = fitsWidth();\n\n            if (!fitsWidth) {\n                origOffsetX = getOffsetX();\n                if (tracksDataWidth() && origOffsetX == getMaxOffsetX())\n                    origOffsetX = Long.MAX_VALUE;\n                origScaleX  = getScaleX();\n            }\n\n            setFitsWidth(!fitsWidth);\n            \n            if (fitsWidth && origOffsetX != -1 && origScaleX != -1) {\n                setScale(origScaleX, getScaleY());\n                setOffset(origOffsetX, getOffsetY());\n            }\n\n            updateAction();\n            if (zoomInAction != null) zoomInAction.updateAction();\n            if (zoomOutAction != null) zoomOutAction.updateAction();\n            \n            repaintDirty();\n            \n        }\n\n        private void updateAction() {\n            boolean fitsWidth = fitsWidth();\n            Icon icon = fitsWidth ? FIXED_SCALE_ICON : SCALE_TO_FIT_ICON;\n            String name = fitsWidth ? NbBundle.getMessage(SimpleXYChart.class,\n                                      \"SimpleXYChart_FixedScaleString\") : // NOI18N\n                                      NbBundle.getMessage(SimpleXYChart.class,\n                                      \"SimpleXYChart_ScaleToFitString\"); // NOI18N\n            putValue(SHORT_DESCRIPTION, name);\n            putValue(SMALL_ICON, icon);\n            \n            if (scroller != null) scroller.setVisible(!fitsWidth);\n        }\n\n    }\n    \n    \n    private class VisibleBoundsListener extends ChartConfigurationListener.Adapter {\n\n        public void dataBoundsChanged(long dataOffsetX, long dataOffsetY,\n                                      long dataWidth, long dataHeight,\n                                      long oldDataOffsetX, long oldDataOffsetY,\n                                      long oldDataWidth, long oldDataHeight) {\n\n            if (zoomInAction != null) zoomInAction.updateAction();\n            if (zoomOutAction != null) zoomOutAction.updateAction();\n        }\n\n        public void scaleChanged(double oldScaleX, double oldScaleY,\n                                 double newScaleX, double newScaleY) {\n\n            if (zoomInAction != null) zoomInAction.updateAction();\n            if (zoomOutAction != null) zoomOutAction.updateAction();\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/SimpleXYChartUtils.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport org.graalvm.visualvm.charts.swing.RotateLabelUI;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport org.graalvm.visualvm.uisupport.TransparentToolBar;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport org.graalvm.visualvm.uisupport.VerticalLayout;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ComponentAdapter;\nimport java.awt.event.ComponentEvent;\nimport java.text.Format;\nimport java.text.MessageFormat;\nimport java.text.NumberFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.SwingConstants;\nimport javax.swing.plaf.LabelUI;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartDecorator;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartItemChange;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemPainter;\nimport org.graalvm.visualvm.lib.charts.ItemsModel;\nimport org.graalvm.visualvm.lib.charts.axis.AxisComponent;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.BytesMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.BitsPerSecMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimeAxisUtils;\nimport org.graalvm.visualvm.lib.charts.axis.TimeMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimelineMarksComputer;\nimport org.graalvm.visualvm.lib.charts.swing.CrossBorderLayout;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.BytesXYItemMarksComputer;\nimport org.graalvm.visualvm.lib.charts.xy.DecimalXYItemMarksComputer;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class SimpleXYChartUtils {\n    \n    // --- Public chart types constants ----------------------------------------\n\n    public static final int TYPE_DECIMAL = 0;\n    public static final int TYPE_BYTES = 1;\n    public static final int TYPE_PERCENT = 2;\n    public static final int TYPE_BITS_PER_SEC = 3;\n\n\n    // --- Private constants ---------------------------------------------------\n\n    private static final NumberFormat DECIMAL_FORMATTER;\n    private static final NumberFormat PERCENT_FORMATTER;\n\n    private static final int DEFAULT_BUFFER_STEP;\n\n    private static final Color AXIS_FONT_COLOR;\n    private static final Color BACKGROUND_COLOR;\n\n    private static final int VALUES_SPACING;\n    private static final int TIMELINE_SPACING;\n\n    private static       int LEGEND_HEIGHT;\n    private static final int DETAILS_HEIGHT_THRESHOLD;\n\n    private static final Map<String, Format> FORMATS;\n    \n    // --- Static initializer --------------------------------------------------\n\n    static {\n        DECIMAL_FORMATTER = NumberFormat.getNumberInstance();\n        DECIMAL_FORMATTER.setGroupingUsed(true);\n        DECIMAL_FORMATTER.setMaximumFractionDigits(2);\n\n        PERCENT_FORMATTER = NumberFormat.getPercentInstance();\n        PERCENT_FORMATTER.setMinimumFractionDigits(1);\n        PERCENT_FORMATTER.setMaximumIntegerDigits(3);\n\n        DEFAULT_BUFFER_STEP = 50;\n\n        AXIS_FONT_COLOR = !UISupport.isDarkResultsBackground() ? new Color(90, 90, 90) : new Color(165, 165, 165);\n        BACKGROUND_COLOR = UISupport.getDefaultBackground();\n\n        VALUES_SPACING = Math.max(new TimeMarksPainter().getFont().getSize(), 15) + 10;\n        TIMELINE_SPACING = 80;\n\n        LEGEND_HEIGHT = -1;\n        DETAILS_HEIGHT_THRESHOLD = 180;\n\n        FORMATS = new HashMap<>();\n    }\n    \n    \n    // --- Public utils --------------------------------------------------------\n\n    public static XYStorage createStorage(int valuesBuffer) {\n        return new XYStorage(valuesBuffer, DEFAULT_BUFFER_STEP);\n    }\n\n    public static SynchronousXYItemsModel createItemsModel(XYStorage storage,\n                                                           String[] itemNames,\n                                                           long minValue,\n                                                           long maxValue) {\n\n        SynchronousXYItem[] items = new SynchronousXYItem[itemNames.length];\n        for (int i = 0; i < items.length; i++)\n            items[i] = storage.addItem(itemNames[i], minValue, maxValue);\n\n        return new SynchronousXYItemsModel(storage, items);\n    }\n\n    public static XYPaintersModel createPaintersModel(float[] lineWidths,\n                                                      Color[] lineColors,\n                                                      Color[] fillColors1,\n                                                      Color[] fillColors2,\n                                                      ItemsModel itemsModel) {\n\n        ChartItem[] items = new ChartItem[itemsModel.getItemsCount()];\n        for (int i = 0; i < items.length; i++)\n            items[i] = itemsModel.getItem(i);\n\n        ItemPainter[] painters = new ItemPainter[items.length];\n        for (int i = 0; i < painters.length; i++)\n            painters[i] = XYPainter.absolutePainter(lineWidths  == null ? null : lineWidths[i],\n                                                    lineColors  == null ? null : lineColors[i],\n                                                    fillColors1 == null ? null : fillColors1[i],\n                                                    fillColors2 == null ? null : fillColors2[i]);\n        return new XYPaintersModel(items, painters);\n    }\n\n    public static JComponent createChartUI(String chartTitle, String xAxisDescription,\n                                           String yAxisDescription, int chartType,\n                                           Color[] itemColors, long initialYMargin,\n                                           boolean hideItems, boolean legendVisible,\n                                           boolean supportsZooming, double chartFactor,\n                                           NumberFormat customFormat, XYStorage storage,\n                                           SynchronousXYItemsModel itemsModel,\n                                           XYPaintersModel paintersModel,\n                                           long limitYValue) {\n\n        // Chart\n        final boolean hasAxisLabel = xAxisDescription != null || yAxisDescription != null;\n        \n        final XYStorage _storage = storage;\n        SimpleXYChart chart = new SimpleXYChart(itemsModel, paintersModel) {\n            protected void itemsChanged(List<ChartItemChange> itemChanges) {\n                if (_storage.isFull()) updateChart(); // full repaint to handle removed items\n                else super.itemsChanged(itemChanges);\n            }\n            public void setBounds(int x, int y, int w, int h) {\n                super.setBounds(x, y, w, h);\n                \n                JScrollBar scroller = (JScrollBar)getClientProperty(\"scroller\"); // NOI18N\n                if (scroller != null) {\n                    int xpos = getX() - 1;\n                    if (hasAxisLabel) xpos += getParent().getX();\n                    scroller.setBounds(xpos, 0, getWidth() + 1, scroller.getHeight());\n                }\n            }\n        };\n\n        chart.setFitsHeight(true);\n        chart.setFitsWidth(true);\n        chart.setBottomBased(true);\n        chart.setViewInsets(new Insets(10, 0, 0, 0));\n        chart.setInitialDataBounds(new LongRect(System.currentTimeMillis(), 0,\n                                       2500, initialYMargin));\n        \n        chart.addPreDecorator(new XYBackground());\n        if (limitYValue != 0) {\n            chart.addPreDecorator(createMaxHeapDecorator(limitYValue));\n        }\n        \n        // Horizontal axis\n        TimelineMarksComputer hComputer = new TimelineMarksComputer(storage,\n                         chart.getChartContext(), SwingConstants.HORIZONTAL) {\n            protected int getMinMarksDistance() { return TIMELINE_SPACING; }\n        };\n        AxisComponent hAxis =\n                new XYAxisComponent(chart, hComputer, customizeMarksPainter(\n                                    new TimeMarksPainter()), SwingConstants.SOUTH,\n                                    AxisComponent.MESH_FOREGROUND);\n\n        // Vertical axis\n        AxisComponent vAxis = null;\n        if (chartType == TYPE_PERCENT) {\n            SynchronousXYItem item = itemsModel.getItem(0);\n            XYItemPainter painter = (XYItemPainter)paintersModel.getPainter(item);\n            DecimalXYItemMarksComputer vComputer = new DecimalXYItemMarksComputer(\n                         item, painter, chart.getChartContext(),\n                         SwingConstants.VERTICAL) {\n                protected int getMinMarksDistance() { return VALUES_SPACING; }\n            };\n            vAxis = new XYAxisComponent(chart, vComputer, customizeMarksPainter(\n                         new XYPercentMarksPainter(0, 100, chartFactor)),\n                         SwingConstants.WEST, AxisComponent.MESH_FOREGROUND);\n        } else if (chartType == TYPE_BYTES) {\n            SynchronousXYItem item = itemsModel.getItem(0);\n            XYItemPainter painter = (XYItemPainter)paintersModel.getPainter(item);\n            BytesXYItemMarksComputer vComputer = new BytesXYItemMarksComputer(\n                         item, painter, chart.getChartContext(),\n                         SwingConstants.VERTICAL) {\n                protected int getMinMarksDistance() { return VALUES_SPACING; }\n            };\n            vAxis = new XYAxisComponent(chart, vComputer, customizeMarksPainter(\n                         new BytesMarksPainter()), SwingConstants.WEST,\n                         AxisComponent.MESH_FOREGROUND);\n        } else if (chartType == TYPE_BITS_PER_SEC) {\n            SynchronousXYItem item = itemsModel.getItem(0);\n            XYItemPainter painter = (XYItemPainter)paintersModel.getPainter(item);\n            BytesXYItemMarksComputer vComputer = new BytesXYItemMarksComputer(\n                         item, painter, chart.getChartContext(),\n                         SwingConstants.VERTICAL) {\n                protected int getMinMarksDistance() { return VALUES_SPACING; }\n            };\n            vAxis = new XYAxisComponent(chart, vComputer, customizeMarksPainter(new BitsPerSecMarksPainter()), SwingConstants.WEST,\n                         AxisComponent.MESH_FOREGROUND);\n        } else {\n            SynchronousXYItem item = itemsModel.getItem(0);\n            XYItemPainter painter = (XYItemPainter)paintersModel.getPainter(item);\n            final DecimalXYItemMarksComputer vComputer = new DecimalXYItemMarksComputer(\n                         item, painter, chart.getChartContext(),\n                         SwingConstants.VERTICAL) {\n                protected int getMinMarksDistance() { return VALUES_SPACING; }\n            };\n            NumberFormat format = customFormat != null ? customFormat : DECIMAL_FORMATTER;\n            vAxis = new XYAxisComponent(chart, vComputer, customizeMarksPainter(\n                         new XYDecimalMarksPainter(chartFactor, format)),\n                         SwingConstants.WEST, AxisComponent.MESH_FOREGROUND);\n        }\n\n        // Tooltip support\n        XYTooltipPainter tooltipPainter = new XYTooltipPainter(createTooltipModel(\n                                                               chartType,\n                                                               itemColors,\n                                                               chartFactor,\n                                                               customFormat,\n                                                               storage,\n                                                               itemsModel));\n        chart.addOverlayComponent(new XYTooltipOverlay(chart, tooltipPainter));\n        chart.getSelectionModel().setHoverMode(ChartSelectionModel.HOVER_EACH_NEAREST);\n\n        // Hovering support\n        XYSelectionOverlay selectionOverlay = new XYSelectionOverlay();\n        chart.addOverlayComponent(selectionOverlay);\n        selectionOverlay.registerChart(chart);\n        chart.getSelectionModel().setMoveMode(ChartSelectionModel.SELECTION_LINE_V);\n        \n        // Chart panel\n        JPanel chartPanel = new JPanel(new CrossBorderLayout());\n        chartPanel.add(chart, new Integer[] { SwingConstants.CENTER });\n        chartPanel.add(hAxis, new Integer[] { SwingConstants.SOUTH,\n                                              SwingConstants.SOUTH_WEST });\n        chartPanel.add(vAxis, new Integer[] { SwingConstants.WEST,\n                                              SwingConstants.SOUTH_WEST });\n\n        // Chart container\n        JPanel chartContainer = hasAxisLabel ? new JPanel(new BorderLayout()) :\n                                               chartPanel;\n\n        if (hasAxisLabel) {\n            chartPanel.setOpaque(false);\n\n            if (xAxisDescription != null)\n                chartContainer.add(createXAxisLabel(xAxisDescription), BorderLayout.SOUTH);\n            if (yAxisDescription != null)\n                chartContainer.add(createYAxisLabel(yAxisDescription), BorderLayout.WEST);\n\n            chartContainer.add(chartPanel, BorderLayout.CENTER);\n        }\n\n        chartContainer.setBackground(BACKGROUND_COLOR);\n\n        // Caption panel\n        JPanel captionPanel = new JPanel(new BorderLayout());\n        captionPanel.setBackground(BACKGROUND_COLOR);\n        if (chartTitle != null) captionPanel.add(createTitleLabel(chartTitle),\n                                                 BorderLayout.NORTH);\n        \n        // Side panel\n        JPanel sidePanel = new JPanel(new VerticalLayout(false));\n        sidePanel.setOpaque(false);\n        sidePanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 0, 10));\n\n        // Legend panel\n        JComponent legendPanel = createLegendPanel(itemColors, hideItems,\n                                                   itemsModel, paintersModel);\n        legendPanel.setVisible(legendVisible);\n        \n        // Scroller panel\n        JPanel scrollerPanel = new JPanel(null) {\n            public Dimension getPreferredSize() {\n                Component c = getComponentCount() > 0 ? getComponent(0) : null;\n                if (c != null && c.isVisible()) {\n                    Dimension size = c.getSize();\n                    size.width += c.getX();\n                    return size;\n                } else {\n                    return new Dimension();\n                }\n            }\n        };\n        scrollerPanel.setOpaque(false);\n        \n        // Bottom panel\n        JPanel bottomPanel = new JPanel(new BorderLayout());\n        bottomPanel.setOpaque(false);\n        bottomPanel.add(scrollerPanel, BorderLayout.NORTH);\n        bottomPanel.add(legendPanel, BorderLayout.SOUTH);\n        \n        // Chart view\n        JPanel chartView = new JPanel(new BorderLayout());\n        chartView.setBackground(BACKGROUND_COLOR);\n        chartView.add(captionPanel, BorderLayout.NORTH);\n        chartView.add(chartContainer, BorderLayout.CENTER);\n        chartView.add(sidePanel, BorderLayout.EAST);\n        chartView.add(bottomPanel, BorderLayout.SOUTH);\n        \n        chartView.putClientProperty(\"chart\", chart); // NOI18N\n        chartView.putClientProperty(\"sidePanel\", sidePanel); // NOI18N\n        chartView.putClientProperty(\"legendPanel\", legendPanel); // NOI18N\n        chartView.putClientProperty(\"scrollerPanel\", scrollerPanel); // NOI18N\n        \n        if (supportsZooming) setZoomingEnabled(chartView, supportsZooming);\n\n        return chartView;\n    }\n\n    public static DetailsHandle createDetailsArea(final String[] detailsItems,\n                                                  JComponent chartContainer) {        \n        final HTMLTextArea detailsArea = new HTMLTextArea();\n        detailsArea.setBorder(BorderFactory.createEmptyBorder(8, 10, 0, 10));\n        detailsArea.setText(createDetailsString(detailsItems, null));\n\n        BorderLayout containerLayout = (BorderLayout)chartContainer.getLayout();\n        JComponent containerNorth = (JComponent)containerLayout.\n                                    getLayoutComponent(BorderLayout.NORTH);\n        containerNorth.add(detailsArea, BorderLayout.CENTER);\n\n        final JComponent containerCenter = (JComponent)containerLayout.\n                                           getLayoutComponent(BorderLayout.CENTER);\n        containerCenter.setBorder(BorderFactory.createEmptyBorder(6, 10, 0, 0));\n\n        chartContainer.addComponentListener(new ComponentAdapter() {\n            public void componentResized(ComponentEvent e) {\n                boolean visible = e.getComponent().getHeight() > DETAILS_HEIGHT_THRESHOLD;\n                detailsArea.setVisible(visible);\n                containerCenter.setBorder(BorderFactory.createEmptyBorder(\n                                          visible ? 6 : 10, 10, 0, 0));\n            }\n        });\n\n        return new DetailsHandle() {\n            public void updateDetails(String[] details) {\n                try {\n                    int selStart = detailsArea.getSelectionStart();\n                    int selEnd   = detailsArea.getSelectionEnd();\n                    detailsArea.setText(createDetailsString(detailsItems, details));\n                    detailsArea.select(selStart, selEnd);\n                } catch (Exception e) {}\n            }\n        };\n    }\n\n    public static JComponent createLegendPanel(Color[] itemColors, boolean hideItems,\n                                               SynchronousXYItemsModel itemsModel,\n                                               final XYPaintersModel paintersModel) {\n        JPanel legendPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, hideItems ? 5 : 10, 0));\n        legendPanel.setBackground(BACKGROUND_COLOR);\n        \n        for (int i = 0; i < itemColors.length; i++) {\n            final SynchronousXYItem item = itemsModel.getItem(i);\n            ColorIcon icon = new ColorIcon(itemColors[i], Color.DARK_GRAY, 10, 10);\n            JComponent legendItem = null;\n\n            if (hideItems) {\n                final XYPainter painter = (XYPainter)paintersModel.getPainter(item);\n                legendItem = new IconCheckBox(item.getName(), icon, painter.isPainting()) {\n                    public Dimension getPreferredSize() {\n                        Dimension ps = super.getPreferredSize();\n                        ps.height = getLegendHeight();\n                        return ps;\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        painter.setPainting(isSelected());\n                        paintersModel.painterChanged(painter);\n                    }\n                };\n            } else {\n                legendItem = new JLabel(item.getName(), icon, JLabel.HORIZONTAL) {\n                    public Dimension getPreferredSize() {\n                        Dimension ps = super.getPreferredSize();\n                        ps.height = getLegendHeight();\n                        return ps;\n                    }\n                };\n            }\n            \n            legendItem.setOpaque(false);\n            legendPanel.add(legendItem);\n\n        }\n\n        JPanel legendContainer = new JPanel(new FlowLayout(FlowLayout.TRAILING, 0, 0));\n        legendContainer.setOpaque(true);\n        legendContainer.setBackground(BACKGROUND_COLOR);\n        legendContainer.setBorder(BorderFactory.createMatteBorder(\n                                  0, 10, 0, 0, BACKGROUND_COLOR));\n        legendContainer.add(legendPanel);\n\n        return legendContainer;\n    }\n    \n    public static void setZoomingEnabled(JComponent chartUI, boolean enabled) {\n        SimpleXYChart chart = (SimpleXYChart)chartUI.getClientProperty(\"chart\"); // NOI18N\n        \n        if (chart.isZoomingEnabled() == enabled) return;\n        else chart.setZoomingEnabled(enabled);\n        \n        JPanel sidePanel = (JPanel)chartUI.getClientProperty(\"sidePanel\"); // NOI18N\n        JPanel scrollerPanel = (JPanel)chartUI.getClientProperty(\"scrollerPanel\"); // NOI18N\n        \n        if (enabled) {\n            TransparentToolBar toolbar = new TransparentToolBar(false);\n            for (Action action : chart.getActions()) toolbar.addItem(action);\n            sidePanel.add(toolbar);\n            \n            JScrollBar scroller = chart.getScroller();\n            scroller.setSize(scroller.getPreferredSize());\n            scrollerPanel.add(scroller);\n            chart.putClientProperty(\"scroller\", scroller); // NOI18N\n        } else {\n            sidePanel.removeAll();\n            scrollerPanel.removeAll();\n            chart.putClientProperty(\"scroller\", null); // NOI18N\n        }\n        \n        sidePanel.setVisible(enabled);\n        \n        chartUI.doLayout();\n        chartUI.repaint();\n    }\n    \n    public static void setLegendVisible(JComponent chartUI, boolean visible) {\n        JPanel legendPanel = (JPanel)chartUI.getClientProperty(\"legendPanel\"); // NOI18N\n        legendPanel.setVisible(visible);\n        \n        chartUI.doLayout();\n        chartUI.repaint();\n    }\n\n    public static XYTooltipModel createTooltipModel(final int chartType,\n                                                    final Color[] itemColors,\n                                                    final double chartFactor,\n                                                    final NumberFormat customFormat,\n                                                    final XYStorage storage,\n                                                    final SynchronousXYItemsModel itemsModel) {\n\n        return new XYTooltipModel() {\n\n            public String getTimeValue(long timestamp) {\n                int timestamps = storage.getTimestampsCount();\n                if (timestamps == 0) return formatTime(timestamp, timestamp, timestamp);\n                else return formatTime(timestamp, storage.getTimestamp(0),\n                                       storage.getTimestamp(timestamps - 1));\n            }\n\n            public int getRowsCount() {\n                return itemsModel.getItemsCount();\n            }\n\n            public String getRowName(int index) {\n                return itemsModel.getItem(index).getName();\n            }\n\n            public Color getRowColor(int index) {\n                return itemColors[index];\n            }\n\n            public String getRowValue(int index, long itemValue) {\n                double value = itemValue * chartFactor;\n                switch (chartType) {\n                    case TYPE_BYTES  : return formatBytes((long)value);\n                    case TYPE_PERCENT: return formatPercent(value);\n                    case TYPE_BITS_PER_SEC  : return formatBitsPerSec((long)value);\n                    default:           return formatDecimal(value, customFormat);\n                }\n            }\n\n        };\n    }\n\n    public static AxisMarksPainter customizeMarksPainter(AxisMarksPainter.Abstract painter) {\n        painter.setForeground(AXIS_FONT_COLOR);\n        painter.setFont(smallerFont(painter.getFont()));\n        return painter;\n    }\n\n    public static String formatDecimal(double value) {\n        return DECIMAL_FORMATTER.format(value);\n    }\n    \n    public static String formatDecimal(double value, NumberFormat format) {\n        return format != null ? format.format(value) : formatDecimal(value);\n    }\n\n    public static String formatBytes(long value) {\n        String bytesFormat = NbBundle.getMessage(SimpleXYChartUtils.class,\n                                                \"SimpleXYChartUtils_BytesFormat\"); // NOI18N\n        return MessageFormat.format(bytesFormat, formatDecimal(value));\n    }\n\n    public static String formatBitsPerSec(long value) {\n        String bpsFormat = NbBundle.getMessage(SimpleXYChartUtils.class,\n                                                \"SimpleXYChartUtils_BitsPerSecFormat\"); // NOI18N\n        return MessageFormat.format(bpsFormat, formatDecimal(value));\n    }\n\n    public static String formatPercent(double value) {\n        return PERCENT_FORMATTER.format(value / 100);\n    }\n\n    public static String formatTime(long timestamp, long startTime, long endTime) {\n        String formatString = TimeAxisUtils.getFormatString(1000, startTime, endTime);\n        return getFormat(formatString).format(new Date(timestamp));\n    }\n\n    public static Font smallerFont(Font font) {\n        return font.deriveFont((float)font.getSize() - 2);\n    }\n\n    public static Font boldFont(Font font) {\n        return font.deriveFont(Font.BOLD);\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private static String createDetailsString(String[] detailsItems, String[] values) {\n        StringBuilder sb = new StringBuilder();\n        String itemFormat = NbBundle.getMessage(SimpleXYChartUtils.class,\n                                                \"SimpleXYChartUtils_DetailsItemFormat\"); // NOI18N\n\n        sb.append(\"<table border='0' cellpadding='0' cellspacing='3' width='100%'>\"); // NOI18N\n        sb.append(\"<tr>\"); // NOI18N\n        int i = 0;\n        while (i < detailsItems.length) {\n            if (detailsItems.length == 1) sb.append(\"<td><nobr>\"); // NOI18N\n            else sb.append(\"<td width='50%'><nobr>\"); // NOI18N\n            sb.append(MessageFormat.format(itemFormat, detailsItems[i],\n                    values == null ? \"\" : values[i])); // NOI18N\n            sb.append(\"</nobr></td>\"); // NOI18N\n            if (i % 2 == 1 && i + 1 < detailsItems.length) sb.append(\"</tr><tr>\"); // NOI18N\n            i++;\n        }\n        sb.append(\"</tr>\"); // NOI18N\n        sb.append(\"</table>\"); // NOI18N\n\n        return sb.toString();\n    }\n\n    private static synchronized Format getFormat(String formatString) {\n        Format format = FORMATS.get(formatString);\n        if (format == null) {\n            format = new SimpleDateFormat(formatString);\n            FORMATS.put(formatString, format);\n        }\n        return format;\n    }\n\n    private static synchronized int getLegendHeight() {\n        if (LEGEND_HEIGHT == -1)\n            LEGEND_HEIGHT = Math.max(new JLabel(\"X\").getPreferredSize().height, // NOI18N\n                                     new JCheckBox(\"X\").getPreferredSize().height); // NOI18N\n        return LEGEND_HEIGHT;\n    }\n\n    private static JLabel createTitleLabel(String text) {\n        JLabel label = createRotatedLabel(text, RotateLabelUI.R0);\n        label.setBorder(BorderFactory.createEmptyBorder(8, 3, 0, 3));\n        label.setFont(boldFont(label.getFont()));\n        return label;\n    }\n\n    private static JLabel createXAxisLabel(String text) {\n        JLabel label = createRotatedLabel(text, RotateLabelUI.R0);\n        label.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));\n        return label;\n    }\n\n    private static JLabel createYAxisLabel(String text) {\n        JLabel label = createRotatedLabel(text, RotateLabelUI.R270);\n        label.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));\n        return label;\n    }\n\n    private static JLabel createRotatedLabel(String text, final LabelUI labelUI) {\n        return new JLabel(text, SwingConstants.CENTER) {\n            public void updateUI() { if (getUI() != labelUI) setUI(labelUI); }\n        };\n    }\n\n    private static final Color  HEAP_LIMIT_FILL_COLOR = !UISupport.isDarkResultsBackground() ?\n                               new Color(220, 220, 220) : new Color(100, 100, 100);\n\n    private static ChartDecorator createMaxHeapDecorator(final long limitYValue) {\n        return new ChartDecorator() {\n            public void paint(Graphics2D g, Rectangle dirtyArea,\n                              ChartContext context) {\n\n                int limitHeight = Utils.checkedInt(context.getViewY(limitYValue));\n                if (limitHeight <= context.getViewportHeight()) {\n                    g.setColor(HEAP_LIMIT_FILL_COLOR);\n                    if (context.isBottomBased())\n                        g.fillRect(0, 0, context.getViewportWidth(), limitHeight);\n                    else\n                        g.fillRect(0, limitHeight, context.getViewportWidth(),\n                                   context.getViewportHeight() - limitHeight);\n                }\n            }\n        };\n    }\n\n    // --- DetailsHandle -------------------------------------------------------\n\n    public static interface DetailsHandle {\n        public void updateDetails(String[] details);\n    }\n\n\n    // --- IconCheckBox --------------------------------------------------------\n\n    private static class IconCheckBox extends JCheckBox {\n\n        private static final int CHECKBOX_OFFSET = getCheckBoxOffset();\n\n        private final JCheckBox renderer;\n\n        IconCheckBox(String text, Icon icon, boolean selected) {\n            renderer = new JCheckBox(text, icon) {\n                public boolean hasFocus() {\n                    return IconCheckBox.this.hasFocus();\n                }\n            };\n            renderer.setOpaque(false);\n            renderer.setBorderPainted(false);\n            setSelected(selected);\n            setBorderPainted(false);\n        }\n\n        protected void paintComponent(Graphics g) {\n            super.paintComponent(g);\n            g.translate(renderer.getX(), renderer.getY());\n            renderer.paint(g);\n            g.translate(-renderer.getX(), -renderer.getY());\n        }\n\n\n        public void setBounds(int x, int y, int width, int height) {\n            Dimension d = super.getPreferredSize();\n            renderer.setBounds(d.width - CHECKBOX_OFFSET, 0,\n                               width - d.width + CHECKBOX_OFFSET, height);\n            super.setBounds(x, y, width, height);\n        }\n\n        public Dimension getPreferredSize() {\n            Dimension d = super.getPreferredSize();\n            d.width += renderer.getPreferredSize().width - CHECKBOX_OFFSET;\n            return d;\n        }\n\n\n        private static int getCheckBoxOffset() {\n            if (UISupport.isWindowsLookAndFeel()) return 3;\n            else if (UISupport.isNimbusLookAndFeel()) return -3;\n            else if (UISupport.isMetalLookAndFeel()) return 3;\n            else if (UISupport.isAquaLookAndFeel()) return 6;\n            else return 0;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/XYAxisComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.util.Iterator;\nimport org.graalvm.visualvm.lib.charts.ChartComponent;\nimport org.graalvm.visualvm.lib.charts.axis.AxisComponent;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMark;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMarksComputer;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMarksPainter;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class XYAxisComponent extends AxisComponent {\n    \n    private static final Color VERTICAL_MESH_COLOR = Utils.checkedColor(\n                                                        new Color(80, 80, 80, 50));\n    private static final Stroke VERTICAL_MESH_STROKE = new BasicStroke(1,\n                                                        BasicStroke.CAP_SQUARE,\n                                                        BasicStroke.JOIN_BEVEL, 0,\n                                                        new float[] {0, 2}, 0);\n    private static final Stroke VERTICAL_MESH_STROKE_PERF = new BasicStroke(1,\n                                                        BasicStroke.CAP_SQUARE,\n                                                        BasicStroke.JOIN_BEVEL);\n\n    private static final int AXIS_BASIS_EXTENT = 2;\n    private static final Color AXIS_LINE_COLOR = new Color(90, 90, 90);\n\n    private static boolean WORKAROUND_OPENJDK_BUG = false;\n\n\n    private final ChartComponent chart;\n    private final AxisMarksComputer marksComputer;\n\n\n    public XYAxisComponent(ChartComponent chart, AxisMarksComputer marksComputer,\n                         AxisMarksPainter marksPainter, int location, int mesh) {\n        \n        super(chart, marksComputer, marksPainter, location, mesh);\n\n        this.chart = chart;\n        this.marksComputer = marksComputer;\n\n        setForeground(AXIS_LINE_COLOR);\n    }\n\n\n    protected int getAxisBasisExtent() { return AXIS_BASIS_EXTENT; }\n\n    protected void paintVerticalMesh(Graphics2D g, Rectangle clip, Rectangle chartMask) {\n        Iterator<AxisMark> marks = marksComputer.marksIterator(\n                                 chartMask.y, chartMask.y + chartMask.height);\n\n        if (WORKAROUND_OPENJDK_BUG) return;\n\n        g.setPaint(VERTICAL_MESH_COLOR);\n        g.setStroke(Utils.forceSpeed() ? VERTICAL_MESH_STROKE_PERF :\n                                         VERTICAL_MESH_STROKE);\n        \n        int x1 = chartMask.x;\n        int x2 = x1 + chartMask.width;\n        \n        // #VISUALVM-595 correctly align the origin to have stable offset for dotted stroke\n        if (x1 % 2 != chart.getOffsetX() % 2) {\n            x1 -= 1;\n            x2 += 2;\n        }\n\n        while (marks.hasNext()) {\n            AxisMark mark = marks.next();\n            int y = mark.getPosition();\n\n            try {\n                // Workaround for a bug on OpenJDK - when tooltip is displayed\n                // over the chart on mouseMove 'java.lang.ArithmeticException: / by zero'\n                // at 'sun.java2d.pisces.Dasher.lineTo' exception is thrown.\n                g.drawLine(x1, y, x2, y);\n            } catch (ArithmeticException e) {\n                WORKAROUND_OPENJDK_BUG = true;\n                System.err.println(\"'java.lang.ArithmeticException: / by zero' detected in XYAxisComponent.paintVerticalMesh, applying workaround\"); // NOI18N\n                break;\n            }\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/XYBackground.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartDecorator;\nimport java.awt.Color;\nimport java.awt.GradientPaint;\nimport java.awt.Graphics2D;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.uisupport.UISupport;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class XYBackground implements ChartDecorator {\n\n    private static final Color GRADIENT_TOP = !UISupport.isDarkResultsBackground() ?\n                               new Color(240, 240, 240) : new Color(60, 60, 60);\n    private static final Color GRADIENT_BOTTOM = !UISupport.isDarkResultsBackground() ?\n                               new Color(250, 250, 250) : new Color(75, 75, 75);\n\n    public void paint(Graphics2D g, Rectangle dirtyArea, ChartContext context) {\n        if (Utils.forceSpeed()) g.setPaint(GRADIENT_BOTTOM);\n        else g.setPaint(new GradientPaint(\n                        new Point(0, Utils.checkedInt(context.getViewportOffsetY())),\n                        GRADIENT_TOP,\n                        new Point(0, context.getViewportHeight()),\n                        GRADIENT_BOTTOM));\n        g.fill(dirtyArea);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/XYDecimalMarksPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport java.text.NumberFormat;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMark;\nimport org.graalvm.visualvm.lib.charts.axis.LongMark;\nimport org.graalvm.visualvm.lib.charts.axis.SimpleLongMarksPainter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class XYDecimalMarksPainter extends SimpleLongMarksPainter {\n\n    protected final double factor;\n    protected final NumberFormat format;\n\n\n    public XYDecimalMarksPainter(double factor, NumberFormat format) {\n        this.factor = factor;\n        this.format = format;\n    }\n\n\n    protected String formatMark(AxisMark mark) {\n        return format.format(((LongMark)mark).getValue() * factor);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/XYItem.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemChange;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class XYItem extends SynchronousXYItem {\n\n    private int lastIndex;\n    private int lastValuesCount;\n    \n    private final LongRect bounds;\n    private long initialMinY;\n    private long initialMaxY;\n\n    private long minY;\n    private long maxY;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    XYItem(String name) {\n        this(name, Long.MAX_VALUE);\n    }\n\n    XYItem(String name, long initialMinY) {\n        this(name, initialMinY, Long.MIN_VALUE);\n    }\n\n    XYItem(String name, long initialMinY, long initialMaxY) {\n        super(name, initialMinY, initialMaxY);\n        this.initialMinY = initialMinY;\n        this.initialMaxY = initialMaxY;\n        minY = Long.MAX_VALUE;\n        maxY = Long.MIN_VALUE;\n        bounds = new LongRect();\n        lastIndex = -1;\n    }\n\n\n    // --- Item telemetry ------------------------------------------------------\n\n    public XYItemChange valuesChanged() {\n\n        int valuesCount = getValuesCount();\n        int index = valuesCount - 1;\n        XYItemChange change = null;\n\n        if (index > -1) { // New item(s)\n\n            // Save oldBounds, setup dirtyBounds\n            LongRect oldBounds = new LongRect(bounds);\n            LongRect dirtyBounds = new LongRect();\n\n            boolean initBounds = lastIndex == -1;\n            int dirtyIndex = lastIndex == -1 ? 0 : lastIndex;\n\n            // Process other values\n            for (int i = dirtyIndex; i <= index; i++) {\n\n                long timestamp = getXValue(i);\n                long value = getYValue(i);\n\n                // Update item minY/maxY\n                minY = Math.min(value, minY);\n                maxY = Math.max(value, maxY);\n\n                // Process item bounds\n                if (initBounds) {\n                    // Initialize item bounds\n                    bounds.x = timestamp;\n                    bounds.y = Math.min(value, initialMinY);\n                    bounds.width = 0;\n                    bounds.height = Math.max(value, initialMaxY) - bounds.y;\n                    initBounds = false;\n                } else {\n                    // Update item bounds\n                    LongRect.add(bounds, timestamp, value);\n                    if (valuesCount == lastValuesCount) {\n                        bounds.x = getXValue(0);\n                        bounds.width = getXValue(valuesCount - 1) - bounds.x;\n                    }\n                }\n\n                // Process dirty bounds\n                if (i == dirtyIndex) {\n                    // Setup dirty bounds\n                    dirtyBounds.x = timestamp;\n                    dirtyBounds.y = value;\n                    dirtyBounds.width = getXValue(index) - dirtyBounds.x;\n                } else {\n                    // Update dirty y/height\n                    long dirtyY = dirtyBounds.y;\n                    dirtyBounds.y = Math.min(dirtyY, value);\n                    dirtyBounds.height = Math.max(dirtyY, value) - dirtyBounds.y;\n                }\n\n            }\n\n            // Return ItemChange\n            int indexesCount = index - lastIndex;\n            int[] indexes = new int[indexesCount];\n            for (int i = 0; i < indexesCount; i++) indexes[i] = lastIndex + 1 + i;\n            change = new XYItemChange.Default(this, indexes, oldBounds,\n                                              new LongRect(bounds), dirtyBounds);\n\n        } else { // Reset\n\n            minY = Long.MAX_VALUE;\n            maxY = Long.MIN_VALUE;\n\n            // Save oldBounds\n            LongRect oldBounds = new LongRect(bounds);\n            LongRect.set(bounds, 0, 0, 0, 0);\n\n            // Return ItemChange\n            change = new XYItemChange.Default(this, new int[] { -1 }, oldBounds,\n                                            new LongRect(bounds), oldBounds);\n\n        }\n        \n        lastIndex = index;\n        lastValuesCount = valuesCount;\n        return change;\n        \n    }\n\n    public long getMinYValue() { return minY; }\n\n    public long getMaxYValue() { return maxY; }\n    \n    public LongRect getBounds() {\n        if (getValuesCount() > 0) return bounds;\n        else return getInitialBounds();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/XYPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport java.awt.Color;\nimport java.awt.GradientPaint;\nimport java.awt.Graphics2D;\nimport java.awt.Polygon;\nimport java.awt.Rectangle;\nimport java.util.List;\nimport java.util.Locale;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemPainter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class XYPainter extends SynchronousXYItemPainter {\n    \n    private final int mode;\n\n    private final Color fillColor2;\n    private boolean painting;\n\n    \n    // --- Initializer ---------------------------------------------------------\n    \n    {\n        String _mode = System.getProperty(\"visualvm.charts.defaultMode\", \"minmax\").toLowerCase(Locale.ENGLISH); // NOI18N\n        if (\"fast\".equals(_mode)) { // NOI18N\n            mode = 0;\n        } else {\n            mode = 1;\n        }\n    }\n\n    // --- Constructor ---------------------------------------------------------\n\n    public static XYPainter absolutePainter(float lineWidth,\n                                                       Color lineColor,\n                                                       Color fillColor1,\n                                                       Color fillColor2) {\n\n        return new XYPainter(lineWidth, lineColor, fillColor1, fillColor2,\n                                         TYPE_ABSOLUTE, 0);\n    }\n\n    public static XYPainter relativePainter(float lineWidth,\n                                                       Color lineColor,\n                                                       Color fillColor1,\n                                                       Color fillColor2,\n                                                       int maxOffset) {\n\n        return new XYPainter(lineWidth, lineColor, fillColor1, fillColor2,\n                                         TYPE_RELATIVE, maxOffset);\n    }\n\n\n    public XYPainter(float lineWidth, Color lineColor, Color fillColor1,\n                     Color fillColor2, int type, int maxValueOffset) {\n\n        super(lineWidth, lineColor, fillColor1, type, maxValueOffset);\n        this.fillColor2 = Utils.checkedColor(fillColor2);\n        painting = true;\n    }\n\n\n    // --- Public interface ----------------------------------------------------\n\n    public void setPainting(boolean painting) {\n        this.painting = painting;\n    }\n\n    public boolean isPainting() {\n        return painting;\n    }\n\n\n    // --- ItemPainter implementation ------------------------------------------\n\n    public LongRect getSelectionBounds(ItemSelection selection, ChartContext context) {\n\n        XYItemSelection sel = (XYItemSelection)selection;\n        XYItem item  = sel.getItem();\n        int selectedValueIndex = sel.getValueIndex();\n\n        if (selectedValueIndex == -1 ||\n            selectedValueIndex >= item.getValuesCount())\n            // This happens on reset - bounds of the selection are unknown, let's clear whole area\n            return new LongRect(0, 0, context.getViewportWidth(),\n                                context.getViewportHeight());\n        else\n            return getViewBounds(item, new int[] { sel.getValueIndex() }, context);\n    }\n\n    public XYItemSelection getClosestSelection(ChartItem item, int viewX,\n                                               int viewY, ChartContext context) {\n\n        if (mode == 1) return getMinMaxClosestSelection(item, viewX, viewY, context);\n        else if (mode == 0) return getFastClosestSelection(item, viewX, viewY, context);\n        else return null;\n    }\n    \n    private int[][] getPoints(XYItem item, Rectangle dirtyArea,\n                              SynchronousXYChartContext context,\n                              int type, int maxValueOffset) {\n        \n        if (mode == 1) return getMinMaxPoints(item, dirtyArea, context, type, maxValueOffset);\n        else if (mode == 0) return getFastPoints(item, dirtyArea, context, type, maxValueOffset);\n        else return null;\n    }\n\n    protected void paint(XYItem item, List<ItemSelection> highlighted,\n                       List<ItemSelection> selected, Graphics2D g,\n                       Rectangle dirtyArea, SynchronousXYChartContext context) {\n        \n        if (!isPainting()) return;\n        if (item.getValuesCount() < 2) return;\n        if (context.getViewWidth() == 0 || context.getViewHeight() == 0) return;\n\n        int[][] points = getPoints(item, dirtyArea, context, type, maxValueOffset);\n        if (points == null) return;\n\n        int[] xPoints  = points[0];\n        int[] yPoints  = points[1];\n        int npoints = points[2][0];\n        \n        if (fillColor != null) {\n            int zeroY = Utils.checkedInt(context.getViewY(context.getDataOffsetY()));\n            zeroY = Math.max(Utils.checkedInt(context.getViewportOffsetY()), zeroY);\n            zeroY = Math.min(Utils.checkedInt(context.getViewportOffsetY() +\n                                                      context.getViewportHeight()), zeroY);\n\n            Polygon polygon = new Polygon();\n            polygon.xpoints = xPoints;\n            polygon.ypoints = yPoints;\n            polygon.npoints = npoints + 2;\n            polygon.xpoints[npoints] = xPoints[npoints - 1];\n            polygon.ypoints[npoints] = zeroY;\n            polygon.xpoints[npoints + 1] = xPoints[0];\n            polygon.ypoints[npoints + 1] = zeroY;\n            \n            if (fillColor2 == null || Utils.forceSpeed()) g.setPaint(fillColor);\n            else g.setPaint(new GradientPaint(0, context.getViewportOffsetY(),\n                           fillColor, 0, context.getViewportOffsetY() +\n                           context.getViewportHeight(), fillColor2));\n            g.fill(polygon);\n        }\n\n        if (lineColor != null) {\n            g.setPaint(lineColor);\n            g.setStroke(lineStroke);\n            g.drawPolyline(xPoints, yPoints, npoints);\n        }\n\n    }\n    \n    \n    private XYItemSelection getFastClosestSelection(ChartItem item, int viewX,\n                                                    int viewY, ChartContext context) {\n\n        SynchronousXYChartContext contx = (SynchronousXYChartContext)context;\n\n        int nearestTimestampIndex = contx.getNearestTimestampIndex(viewX, viewY);\n        if (nearestTimestampIndex == -1) return null; // item not visible\n\n        SynchronousXYItem xyItem = (SynchronousXYItem)item;\n        return new XYItemSelection.Default(xyItem, nearestTimestampIndex,\n                                           ItemSelection.DISTANCE_UNKNOWN);\n    }\n    \n    private XYItemSelection getMinMaxClosestSelection(ChartItem item, int viewX,\n                                                      int viewY, ChartContext context) {\n\n        SynchronousXYItem xyItem = (SynchronousXYItem)item;\n        if (xyItem.getValuesCount() == 0) return null;\n        \n        SynchronousXYChartContext contx = (SynchronousXYChartContext)context;\n        Rectangle bounds = new Rectangle(0, 0, contx.getViewportWidth(), contx.getViewportHeight());\n        if (bounds.isEmpty()) return null;\n        \n        int[][] visibleBounds = contx.getVisibleBounds(bounds);\n        if (visibleBounds[0][0] == -1 && visibleBounds[0][1] == -1) return null;\n        else if (visibleBounds[1][0] == -1 && visibleBounds[1][1] == -1) return null;\n        \n        int firstVisible = visibleBounds[0][0];\n        if (firstVisible == -1) firstVisible = visibleBounds[0][1];\n        \n        int lastVisible = visibleBounds[1][0];\n        if (lastVisible == -1) lastVisible = visibleBounds[1][1];\n        \n        int idx = firstVisible;\n        int x = getViewX(contx, xyItem, idx);\n        int dist = Math.abs(viewX - x);\n        \n        while (++idx <= lastVisible) {\n            int newX = getViewX(contx, xyItem, idx);\n            int newDist = Math.abs(viewX - newX);\n            if (newDist > dist) {\n                idx--;\n                break;\n            } else {\n                x = newX;\n                dist = newDist;\n            }\n        }\n        \n        if (idx > lastVisible) idx = lastVisible;\n        \n        long maxVal = xyItem.getYValue(idx);\n        int maxIdx = idx;\n        \n        while (--idx >= firstVisible && getViewX(contx, xyItem, idx) == x) {\n            long y = xyItem.getYValue(idx);\n            if (y > maxVal) {\n                maxVal = y;\n                maxIdx = idx;\n            }\n        }\n        \n        return new XYItemSelection.Default(xyItem, maxIdx, dist);\n    }\n    \n    private int[][] getFastPoints(XYItem item, Rectangle dirtyArea,\n                                  SynchronousXYChartContext context,\n                                  int type, int maxValueOffset) {\n\n        int valuesCount = item.getValuesCount();\n        int[][] visibleBounds = context.getVisibleBounds(dirtyArea);\n\n        int firstFirst = visibleBounds[0][0];\n        int firstIndex = firstFirst;\n        if (firstIndex == -1) firstIndex = visibleBounds[0][1];\n        if (firstIndex == -1) return null;\n        if (firstFirst != -1 && firstIndex > 0) firstIndex -= 1;\n\n        int lastFirst = visibleBounds[1][0];\n        int lastIndex = lastFirst;\n        if (lastIndex == -1) lastIndex = visibleBounds[1][1];\n        if (lastIndex == -1) lastIndex = valuesCount - 1;\n        if (lastFirst != -1 && lastIndex < valuesCount - 1) lastIndex += 1;\n\n        int itemsStep = (int)(valuesCount / context.getViewWidth());\n        if (itemsStep == 0) itemsStep = 1;\n\n        int visibleCount = lastIndex - firstIndex + 1;\n\n        if (itemsStep > 1) {\n            int firstMod = firstIndex % itemsStep;\n            firstIndex -= firstMod;\n            int lastMod = lastIndex % itemsStep;\n            lastIndex = lastIndex - lastMod + itemsStep;\n            visibleCount = (lastIndex - firstIndex) / itemsStep + 1;\n            lastIndex = Math.min(lastIndex, valuesCount - 1);\n        }\n\n        int[] xPoints = new int[visibleCount + 2];\n        int[] yPoints = new int[visibleCount + 2];\n\n\n        double itemValueFactor = type == TYPE_RELATIVE ? getItemValueFactor(context,\n                                 maxValueOffset, item.getBounds().height) : 0;\n\n        for (int i = 0; i < visibleCount; i++) {\n            int dataIndex = i == visibleCount - 1 ? lastIndex :\n                                 firstIndex + i * itemsStep;\n            xPoints[i] = Utils.checkedInt(Math.ceil(\n                         context.getViewX(item.getXValue(dataIndex))));\n            yPoints[i] = Utils.checkedInt(Math.ceil(\n                         getYValue(item, dataIndex,\n                         type, context, itemValueFactor)));\n        }\n\n        return new int[][] { xPoints, yPoints, { xPoints.length - 2 } };\n    }\n    \n    private int[][] getMinMaxPoints(XYItem item, Rectangle dirtyArea,\n                                    SynchronousXYChartContext context,\n                                    int type, int maxValueOffset) {\n        \n        if (dirtyArea.isEmpty()) return null;\n        \n        dirtyArea.grow(lineWidth, 0);\n        \n        int[][] visibleBounds = context.getVisibleBounds(dirtyArea);\n        if (visibleBounds[0][0] == -1 && visibleBounds[0][1] == -1) return null;\n        else if (visibleBounds[1][0] == -1 && visibleBounds[1][1] == -1) return null;\n        \n        int valuesCount = item.getValuesCount();\n        \n        int firstIndex = visibleBounds[0][0];\n        if (firstIndex == -1) firstIndex = visibleBounds[0][1];\n        else if (firstIndex > 0) firstIndex--; // must use previous point to draw first line\n        \n        int lastIndex = visibleBounds[1][0];\n        if (lastIndex == -1) lastIndex = visibleBounds[1][1];\n        else if (lastIndex < valuesCount - 1) lastIndex++; // must use next point to draw last line\n        \n//        int firstX = getViewX(context, item, firstIndex);\n//        while (firstIndex > 0 && getViewX(context, item, firstIndex) >= firstX - lineWidth)\n//            firstIndex--;\n//        \n//        int lastX = getViewX(context, item, lastIndex);\n//        while (lastIndex < valuesCount - 1 && getViewX(context, item, lastIndex) <= lastX + lineWidth)\n//            lastIndex++;\n        \n        double itemValueFactor = type == TYPE_RELATIVE ? getItemValueFactor(context,\n                                 maxValueOffset, item.getBounds().height) : 0;\n        \n//        int maxPoints = Math.min((lineWidth + dirtyArea.width + lineWidth) * 4, lastIndex - firstIndex + 1);\n        int maxPoints = Math.min(dirtyArea.width * 4 + 2, lastIndex - firstIndex + 1); // +2 for the extra invisible first & last points\n        \n        int[] xPoints = new int[maxPoints + 2];\n        int[] yPoints = new int[maxPoints + 2];\n        \n        int nPoints = 0;\n        for (int index = firstIndex; index <= lastIndex; index++) {\n            int x = getViewX(context, item, index);\n            int y = Utils.checkedInt(Math.ceil(getYValue(item, index,\n                                     type, context, itemValueFactor)));\n            \n            int nValues = 0;\n            \n            if (nPoints > 0) {\n                if (xPoints[nPoints - 1] == x) nValues = 1;\n                \n                if (nPoints > 1) {\n                    if (xPoints[nPoints - 2] == x) nValues = 2;\n                    \n                    if (nPoints > 2) {\n                        if (xPoints[nPoints - 3] == x) nValues = 3;\n                        \n                        if (nPoints > 3) {\n                            if (xPoints[nPoints - 4] == x) nValues = 4;\n                        }\n                    }\n                }\n            }\n            \n            switch (nValues) {\n                // New point at X\n                case 0:\n                    if (nPoints < 2 || yPoints[nPoints - 1] != y || yPoints[nPoints - 2] != y) { // first, second or new point, create it\n                        xPoints[nPoints] = x;\n                        yPoints[nPoints] = y;\n                        nPoints++;\n                    } else { // repeated point, collapse it\n                        xPoints[nPoints - 1] = x;\n                    }\n                    \n                    break;\n                \n                // Second point at X\n                case 1:\n                    if (yPoints[nPoints - 1] != y) { // only add second point if its value differs from the first point\n                        xPoints[nPoints] = x;\n                        yPoints[nPoints] = y;\n                        nPoints++;\n                    }\n                    \n                    break;\n                \n                // Third point at X\n                case 2:\n                    int y_1_2 = yPoints[nPoints - 1];\n                    if (y_1_2 != y) { // only add third point if its value differs from the second point\n                        if (yPoints[nPoints - 2] < y_1_2 && y_1_2 < y) { // new maximum value, collapse it\n                            yPoints[nPoints - 1] = y;\n                        } else if (yPoints[nPoints - 2] > y_1_2 && y_1_2 > y) { // new minimum value, collapse it\n                            yPoints[nPoints - 1] = y;\n                        } else { // new end value, create it\n                            xPoints[nPoints] = x;\n                            yPoints[nPoints] = y;\n                            nPoints++;\n                        }\n                    }\n                    \n                    break;\n                \n                // Fourth point at X\n                case 3:\n                    int y_1_3 = yPoints[nPoints - 1];\n                    if (y_1_3 != y) { // only add fourth point if its value differs from the third point\n                        int y_2_3 = yPoints[nPoints - 2];\n                        int y_3_3 = yPoints[nPoints - 3];\n                        \n                        int min = y;\n                        int max = y;\n                        \n                        if (y_1_3 < min) min = y_1_3;\n                        else if (y_1_3 > max) max = y_1_3;\n                        \n                        if (y_2_3 < min) min = y_2_3;\n                        else if (y_2_3 > max) max = y_2_3;\n                        \n                        if (y_3_3 < min) min = y_3_3;\n                        else if (y_3_3 > max) max = y_3_3;\n                        \n                        if (y == min) {\n                            if (y_3_3 == max) {\n                                yPoints[nPoints - 2] = y;\n                                nPoints--;\n                            } else {\n                                yPoints[nPoints - 2] = max;\n                                yPoints[nPoints - 1] = y;\n                            }\n                        } else if (y == max) {\n                            if (y_3_3 == min) {\n                                yPoints[nPoints - 2] = y;\n                                nPoints--;\n                            } else {\n                                yPoints[nPoints - 2] = min;\n                                yPoints[nPoints - 1] = y;\n                            }\n                        } else if (y_3_3 == min) {\n                            yPoints[nPoints - 2] = max;\n                            yPoints[nPoints - 1] = y;\n                        } else if (y_3_3 == max) {\n                            yPoints[nPoints - 2] = min;\n                            yPoints[nPoints - 1] = y;\n                        } else {\n                            xPoints[nPoints] = x;\n                            yPoints[nPoints] = y;\n                            nPoints++;\n                        }\n                    }\n                    \n                    break;\n                \n                // Another point at X\n                case 4:\n                    int y_1_4 = yPoints[nPoints - 1];\n                    if (y_1_4 != y) { // only add another point if its value differs from the fourth point\n                        int y_2_4 = yPoints[nPoints - 2];\n                        int y_3_4 = yPoints[nPoints - 3];\n                        int y_4_4 = yPoints[nPoints - 4];\n                        \n                        int min = y;\n                        int max = y;\n                        \n                        if (y_1_4 < min) min = y_1_4;\n                        else if (y_1_4 > max) max = y_1_4;\n                        \n                        if (y_2_4 < min) min = y_2_4;\n                        else if (y_2_4 > max) max = y_2_4;\n                        \n                        if (y_3_4 < min) min = y_3_4;\n                        else if (y_3_4 > max) max = y_3_4;\n                        \n                        if (y_4_4 < min) min = y_4_4;\n                        else if (y_4_4 > max) max = y_4_4;\n                        \n                        if (y == min) {\n                            yPoints[nPoints - 3] = max;\n                            yPoints[nPoints - 2] = y;\n                            nPoints--;\n                        } else if (y == max) {\n                            yPoints[nPoints - 3] = min;\n                            yPoints[nPoints - 2] = y;\n                            nPoints--;\n                        } else {\n                            yPoints[nPoints - 1] = y;\n                        }\n                    }\n            }\n        }\n        \n        return new int[][] { xPoints, yPoints, { nPoints } };\n    }\n    \n    private static int getViewX(SynchronousXYChartContext context, XYItem item, int index) {\n        return Utils.checkedInt(Math.ceil(context.getViewX(item.getXValue(index))));\n    }\n\n    private LongRect getViewBoundsRelative(LongRect dataBounds, XYItem item,\n                                           ChartContext context) {\n        LongRect itemBounds = item.getBounds();\n\n        double itemValueFactor = getItemValueFactor(context, maxValueOffset,\n                                                    itemBounds.height);\n\n        // TODO: fix the math!!!\n        double value1 = context.getDataOffsetY() + itemValueFactor *\n                      (double)(dataBounds.y - itemBounds.y);\n        double value2 = context.getDataOffsetY() + itemValueFactor *\n                      (double)(dataBounds.y + dataBounds.height - itemBounds.y);\n\n        long viewX = (long)Math.ceil(context.getViewX(dataBounds.x));\n        long viewWidth = (long)Math.ceil(context.getViewWidth(dataBounds.width));\n        if (context.isRightBased()) viewX -= viewWidth;\n\n        long viewY1 = (long)Math.ceil(context.getViewY(value1));\n        long viewY2 = (long)Math.ceil(context.getViewY(value2));\n        long viewHeight = context.isBottomBased() ? viewY1 - viewY2 :\n                                                    viewY2 - viewY1;\n        if (!context.isBottomBased()) viewY2 -= viewHeight;\n\n        LongRect viewBounds =  new LongRect(viewX, viewY2, viewWidth, viewHeight);\n        LongRect.addBorder(viewBounds, lineWidth);\n\n        return viewBounds;\n    }\n\n    private LongRect getViewBounds(XYItem item, int[] valuesIndexes, ChartContext context) {\n\n        LongRect dataBounds = new LongRect();\n\n        if (valuesIndexes == null) {\n            LongRect.set(dataBounds, item.getBounds());\n        } else {\n            boolean firstPoint = true;\n            for (int valueIndex : valuesIndexes) {\n                if (valueIndex == -1) continue;\n                long xValue = item.getXValue(valueIndex);\n                long yValue = item.getYValue(valueIndex);\n                if (firstPoint) {\n                    LongRect.set(dataBounds, xValue, yValue, 0, 0);\n                    firstPoint = false;\n                } else {\n                    LongRect.add(dataBounds, xValue, yValue);\n                }\n            }\n        }\n\n        if (type == TYPE_RELATIVE) {\n\n            return getViewBoundsRelative(dataBounds, item, context);\n\n        } else {\n\n            LongRect viewBounds = context.getViewRect(dataBounds);\n            LongRect.addBorder(viewBounds, lineWidth);\n            return viewBounds;\n\n        }\n    }\n\n    private static double getItemValueFactor(ChartContext context,\n                                             double maxValueOffset,\n                                             double itemHeight) {\n        return ((double)context.getDataHeight() -\n               context.getDataHeight(maxValueOffset)) / itemHeight;\n    }\n\n    private static double getYValue(XYItem item, int valueIndex,\n                                  int type, ChartContext context, double itemValueFactor) {\n        if (type == TYPE_ABSOLUTE) {\n            return context.getViewY(item.getYValue(valueIndex));\n        } else {\n            return context.getViewY(context.getDataOffsetY() + (itemValueFactor *\n                        (item.getYValue(valueIndex) - item.getBounds().y)));\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/XYPaintersModel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport java.util.Collections;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ItemPainter;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class XYPaintersModel extends PaintersModel.Default {\n    \n    public XYPaintersModel(ChartItem[] items, ItemPainter[] painters) {\n        super(items, painters);\n    }\n\n    public final void painterChanged(ItemPainter painter) {\n        firePaintersChanged(Collections.singletonList(painter));\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/XYPercentMarksPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport org.graalvm.visualvm.lib.charts.axis.AxisMark;\nimport org.graalvm.visualvm.lib.charts.axis.LongMark;\nimport org.graalvm.visualvm.lib.charts.axis.PercentLongMarksPainter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class XYPercentMarksPainter extends PercentLongMarksPainter {\n\n    protected final double factor;\n\n\n    public XYPercentMarksPainter(long minValue, long maxValue, double factor) {\n        super(minValue, maxValue);\n        this.factor = factor;\n    }\n\n\n    protected String formatMark(AxisMark mark) {\n        if (!(mark instanceof LongMark)) return mark.toString();\n        double value = ((LongMark)mark).getValue();\n        double relValue = (value - minValue) / maxValue * factor;\n        return format.format(relValue);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/XYSelectionOverlay.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport org.graalvm.visualvm.lib.charts.ChartComponent;\nimport org.graalvm.visualvm.lib.charts.ChartOverlay;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionListener;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Paint;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class XYSelectionOverlay extends ChartOverlay {\n\n    private ChartComponent chart;\n\n    private int selectionExtent;\n\n    private final ConfigurationListener configurationListener;\n    private final SelectionListener selectionListener;\n    private final Set<Point> selectedValues;\n\n    private Paint markPaint;\n    private Paint oddPerfPaint;\n    private Paint evenPerfPaint;\n\n    private Stroke markStroke;\n    private Stroke oddPerfStroke;\n    private Stroke evenPerfStroke;\n\n\n    public XYSelectionOverlay() {\n        configurationListener = new ConfigurationListener();\n        selectionListener = new SelectionListener();\n        selectedValues = new HashSet<>();\n        initDefaultValues();\n    }\n    \n\n    // --- Public API ----------------------------------------------------------\n\n    public final void registerChart(ChartComponent chart) {\n        unregisterListener();\n        this.chart = chart;\n        registerListener();\n    }\n\n    public final void unregisterChart(ChartComponent chart) {\n        unregisterListener();\n        this.chart = null;\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void registerListener() {\n        if (chart == null) return;\n        chart.addConfigurationListener(configurationListener);\n        chart.getSelectionModel().addSelectionListener(selectionListener);\n    }\n\n    private void unregisterListener() {\n        if (chart == null) return;\n        chart.removeConfigurationListener(configurationListener);\n        chart.getSelectionModel().removeSelectionListener(selectionListener);\n    }\n\n    private void initDefaultValues() {\n        markPaint = new Color(80, 80, 80);\n        oddPerfPaint = Color.BLACK;\n        evenPerfPaint = Color.WHITE;\n\n        markStroke = new BasicStroke(2.8f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);\n        oddPerfStroke = new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 0, new float[] { 1.0f, 3.0f }, 0);\n        evenPerfStroke = new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 0, new float[] { 1.0f, 3.0f }, 2);\n\n        selectionExtent = 3;\n    }\n\n\n    public void paint(Graphics g) {\n        if (selectedValues.isEmpty()) return;\n\n        Graphics2D g2 = (Graphics2D)g;\n        g2.setRenderingHints(chart.getRenderingHints());\n\n        Iterator<Point> it = selectedValues.iterator();\n        boolean linePainted = false;\n\n        while (it.hasNext()) {\n            Point p = it.next();\n\n            if (!linePainted) {\n                g2.setPaint(evenPerfPaint);\n                g2.setStroke(evenPerfStroke);\n                g2.drawLine(p.x, 0, p.x, getHeight());\n                g2.setPaint(oddPerfPaint);\n                g2.setStroke(oddPerfStroke);\n                g2.drawLine(p.x, 0, p.x, getHeight());\n\n                g2.setPaint(markPaint);\n                g2.setStroke(markStroke);\n\n                linePainted = true;\n            }\n\n            g2.fillOval(p.x - selectionExtent + 1, p.y - selectionExtent + 1,\n                        selectionExtent * 2 - 1, selectionExtent * 2 - 1);\n        }\n\n    }\n\n    private void vLineBoundsChanged(Set<Point> oldSelection, Set<Point> newSelection) {\n        Point oldSel = oldSelection.isEmpty() ? null : oldSelection.iterator().next();\n        Point newSel = newSelection.isEmpty() ? null : newSelection.iterator().next();\n\n        if (oldSel != null) repaint(oldSel.x - selectionExtent, 0,\n                                             selectionExtent * 2, getHeight());\n        if (newSel != null) repaint(newSel.x - selectionExtent, 0,\n                                             selectionExtent * 2, getHeight());\n    }\n\n    private static void updateSelectedValues(Set<Point> selectedValues,\n                                             List<ItemSelection> selectedItems,\n                                             ChartContext context) {\n        selectedValues.clear();\n        for (ItemSelection sel : selectedItems) {\n            XYItemSelection xySel = (XYItemSelection)sel;\n            long xValue = xySel.getItem().getXValue(xySel.getValueIndex());\n            long yValue = xySel.getItem().getYValue(xySel.getValueIndex());\n            selectedValues.add(new Point(Utils.checkedInt(Math.ceil(context.getViewX(xValue))),\n                                         Utils.checkedInt(Math.ceil(context.getViewY(yValue)))));\n        }\n    }\n\n\n    private class ConfigurationListener extends ChartConfigurationListener.Adapter {\n        public void contentsUpdated(long offsetX, long offsetY,\n                                    double scaleX, double scaleY,\n                                    long lastOffsetX, long lastOffsetY,\n                                    double lastScaleX, double lastScaleY,\n                                    int shiftX, int shiftY) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        Set<Point> oldSelectedValues = new HashSet<>(selectedValues);\n                        updateSelectedValues(selectedValues, chart.getSelectionModel().getHighlightedItems(), chart.getChartContext());\n                        vLineBoundsChanged(oldSelectedValues, selectedValues);\n                    }\n                });\n        }\n    }\n\n    private class SelectionListener implements ChartSelectionListener {\n\n        public void selectionModeChanged(int newMode, int oldMode) {}\n\n        public void selectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds) {}\n\n        public void selectedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems) {}\n\n        public void highlightedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n            Set<Point> oldSelectedValues = new HashSet<>(selectedValues);\n            updateSelectedValues(selectedValues, currentItems, chart.getChartContext());\n            vLineBoundsChanged(oldSelectedValues, selectedValues);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/XYStorage.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.Arrays;\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class XYStorage implements Timeline {\n\n    private static final String SNAPSHOT_HEADER = \"XYStorageSnapshot\"; // NOI18N\n    private static final int SNAPSHOT_VERSION = 1;\n\n    public static final long NO_VALUE = Long.MIN_VALUE - 1;\n\n    private final int valuesLimit;\n    private final int bufferStep;\n\n    private int valuesCount;\n    private long[] timestamps;\n    private long[][] values;\n\n    private int cycleIndex;\n\n    \n    public XYStorage(int valuesLimit, int bufferStep) {\n        this.valuesLimit = valuesLimit;\n        this.bufferStep = bufferStep;\n        initialize();\n    }\n\n\n    public synchronized SynchronousXYItem addItem(String name, long minValue, long maxValue) {\n        final int itemIndex = addItemImpl();\n        return new XYItem(name, minValue, maxValue) {\n            public long getYValue(int valueIndex) {\n                return getValue(itemIndex, valueIndex);\n            }\n        };\n    }\n\n\n    public synchronized void addValues(long timestamp, long[] values) {\n        updateStorage();\n\n        setTimestamp(Math.min(valuesCount, valuesLimit - 1), timestamp);\n        for (int i = 0; i < values.length; i++)\n            setValue(i, Math.min(valuesCount, valuesLimit - 1), values[i]);\n\n        if (valuesCount < valuesLimit) valuesCount++;\n    }\n\n    public synchronized void saveValues(OutputStream os) throws IOException {\n        try (DataOutputStream dos = new DataOutputStream(os)) {\n            int icount = values.length;\n            int vcount = getTimestampsCount();\n\n            dos.writeUTF(SNAPSHOT_HEADER); // Snapshot format\n            dos.writeInt(SNAPSHOT_VERSION); // Snapshot version\n            dos.writeInt(icount); // Items count\n            dos.writeInt(vcount); // Values count\n\n            for (int vidx = 0; vidx < vcount; vidx++) {\n                dos.writeLong(getTimestamp(vidx));\n                for (int iidx = 0; iidx < icount; iidx++)\n                    dos.writeLong(getValue(iidx, vidx));\n            }\n        }\n    }\n\n    public synchronized void loadValues(InputStream is) throws IOException {\n        try (DataInputStream dis = new DataInputStream(is)) {\n\n            if (!SNAPSHOT_HEADER.equals(dis.readUTF()))\n                throw new IOException(\"Unknown snapshot format\"); // NOI18N\n            if (SNAPSHOT_VERSION != dis.readInt())\n                throw new IOException(\"Unsupported snapshot version\"); // NOI18N\n            if (values.length != dis.readInt())\n                throw new IOException(\"Snapshot doesn't match number of items\"); // NOI18N\n\n            int vcount = dis.readInt();\n            long[] vals = new long[values.length];\n            \n            for (int vidx = 0; vidx < vcount; vidx++) {\n                long timestamp = dis.readLong();\n                for (int iidx = 0; iidx < vals.length; iidx++)\n                    vals[iidx] = dis.readLong();\n                addValues(timestamp, vals);\n            }\n        }\n    }\n\n\n    private void initialize() {\n        reset();\n    }\n\n    private void reset() {\n        valuesCount = 0;\n        cycleIndex = 0;\n\n        timestamps = null;\n        if (values != null) {\n            if (values.length == 0) values = null;\n            else for (int i = 0; i < values.length; i++)\n                    values[i] = new long[bufferStep];\n        }\n    }\n\n\n    private int addItemImpl() {\n        int itemIndex = 0;\n        if (timestamps == null) {\n            timestamps = new long[bufferStep];\n            values = new long[1][];\n            values[0] = new long[bufferStep];\n        } else {\n            values = extendArray(values, 1);\n            itemIndex = values.length - 1;\n            values[itemIndex] = new long[timestamps.length];\n            if (values[itemIndex].length > 0)\n                Arrays.fill(values[itemIndex], NO_VALUE);\n        }\n        return itemIndex;\n    }\n\n\n    private int getIndex(int index) {\n        if (cycleIndex != 0) {\n            index += cycleIndex;\n            if (index >= valuesCount) index -= valuesCount;\n        }\n        return index;\n    }\n\n    public int getTimestampsCount() {\n        return valuesCount;\n    }\n\n    private void setTimestamp(int index, long value) {\n        timestamps[getIndex(index)] = value;\n    }\n\n    public long getTimestamp(int index) {\n        return timestamps[getIndex(index)];\n    }\n\n    private void setValue(int itemIndex, int valueIndex, long value) {\n        values[itemIndex][getIndex(valueIndex)] = value;\n    }\n\n    private long getValue(int itemIndex, int valueIndex) {\n        return values[itemIndex][getIndex(valueIndex)];\n    }\n\n    \n    boolean isFull() {\n        return valuesCount == valuesLimit;\n    }\n\n    private void updateStorage() {\n        int bufferSize = timestamps.length;\n        if (valuesCount == bufferSize && bufferSize < valuesLimit) {\n            int extent = Math.min(bufferStep, valuesLimit - bufferSize);\n            timestamps = extendArray(timestamps, extent);\n            for (int i = 0; i < values.length; i++)\n                values[i] = extendArray(values[i], extent);\n            cycleIndex = 0;\n        } else if (isFull()) {\n            cycleIndex++;\n            if (cycleIndex == valuesLimit) cycleIndex = 0;\n        }\n    }\n\n    private static long[] extendArray(long[] array, int extraLength) {\n        int originalLength = array.length;\n        long[] newArray = new long[originalLength + extraLength];\n        System.arraycopy(array, 0, newArray, 0, originalLength);\n        return newArray;\n    }\n\n    private static long[][] extendArray(long[][] array, int extraLength) {\n        int originalLength = array.length;\n        long[][] newArray = new long[originalLength + extraLength][];\n        System.arraycopy(array, 0, newArray, 0, originalLength);\n        return newArray;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/XYTooltipModel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport java.awt.Color;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface XYTooltipModel {\n\n    public String getTimeValue      (long timestamp);\n\n    public int    getRowsCount      ();\n    public String getRowName        (int index);\n    public Color  getRowColor       (int index);\n    public String getRowValue       (int index, long itemValue);\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/XYTooltipOverlay.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport org.graalvm.visualvm.lib.charts.ChartComponent;\nimport org.graalvm.visualvm.lib.charts.ChartOverlay;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionListener;\nimport org.graalvm.visualvm.lib.charts.ItemPainter;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport java.awt.Graphics;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseMotionAdapter;\nimport java.util.List;\nimport javax.swing.Timer;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class XYTooltipOverlay extends ChartOverlay implements ActionListener {\n\n    private static final int TOOLTIP_OFFSET = 15;\n    private static final int TOOLTIP_MARGIN = 10;\n    private static final int TOOLTIP_RESPONSE = 50;\n    private static final int ANIMATION_STEPS = 5;\n\n    private XYTooltipPainter tooltipPainter;\n\n    private Timer timer;\n    private int currentStep;\n    private Point mousePosition;\n    private Point targetPosition;\n\n\n    public XYTooltipOverlay(final ChartComponent chart,\n                                    XYTooltipPainter tooltipPainter) {\n        if (chart.getSelectionModel() == null)\n            throw new NullPointerException(\"No ChartSelectionModel set for \" + chart); // NOI18N\n\n        if (!Utils.forceSpeed()) {\n            timer = new Timer(TOOLTIP_RESPONSE / ANIMATION_STEPS, this);\n            timer.setInitialDelay(0);\n        }\n\n        setLayout(null);\n\n        this.tooltipPainter = tooltipPainter;\n        add(tooltipPainter);\n        tooltipPainter.setVisible(false);\n\n        chart.getSelectionModel().addSelectionListener(new ChartSelectionListener() {\n\n            public void selectionModeChanged(int newMode, int oldMode) {}\n\n            public void selectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds) {}\n\n            public void highlightedItemsChanged(List<ItemSelection> currentItems,\n                List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n                updateTooltip(chart);\n            }\n\n            public void selectedItemsChanged(List<ItemSelection> currentItems,\n                List<ItemSelection> addedItems, List<ItemSelection> removedItems) {}\n\n        });\n\n        chart.addConfigurationListener(new ChartConfigurationListener.Adapter() {\n\n            public void contentsUpdated(long offsetX, long offsetY,\n                                    double scaleX, double scaleY,\n                                    long lastOffsetX, long lastOffsetY,\n                                    double lastScaleX, double lastScaleY,\n                                    int shiftX, int shiftY) {\n                updateTooltip(chart);\n            }\n\n        });\n\n        chart.addMouseMotionListener(new MouseMotionAdapter() {\n            public void mouseMoved(MouseEvent e) {\n                mousePosition = e.getPoint();\n                updateTooltip(chart);\n            }\n        });\n    }\n\n    public final void setPosition(Point p) {\n        if (tooltipPainter != null) {\n            if (p == null) {\n                if (tooltipPainter.isVisible()) tooltipPainter.setVisible(false);\n                if (timer != null) timer.stop();\n            } else {\n                if (!tooltipPainter.isVisible() || timer == null) {\n                    tooltipPainter.setVisible(true);\n                    tooltipPainter.setLocation(p);\n                } else {\n                    currentStep = 0;\n                    targetPosition = p;\n                    timer.restart();\n                }\n            }\n        }\n    }\n\n    public final Point getPosition() {\n        if (tooltipPainter == null) return null;\n        return tooltipPainter.getLocation();\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        Point currentPosition = tooltipPainter.getLocation();\n\n        currentPosition.x += (targetPosition.x - currentPosition.x) /\n                             (ANIMATION_STEPS - currentStep);\n        currentPosition.y += (targetPosition.y - currentPosition.y) /\n                             (ANIMATION_STEPS - currentStep);\n        tooltipPainter.setLocation(currentPosition);\n\n        if (++currentStep == ANIMATION_STEPS) timer.stop();\n    }\n\n\n    private void updateTooltip(ChartComponent chart) {\n        if (mousePosition == null) return;\n\n        List<ItemSelection> highlightedItems =\n                chart.getSelectionModel().getHighlightedItems();\n\n        XYItemSelection selection = highlightedItems.isEmpty() ? null :\n                                    (XYItemSelection)highlightedItems.get(0);\n\n        if (selection == null ||\n            selection.getItem().getValuesCount() <= selection.getValueIndex()) {\n            setPosition(null);\n        } else {\n            tooltipPainter.update(highlightedItems);\n            tooltipPainter.setSize(tooltipPainter.getPreferredSize());\n            setPosition(highlightedItems, chart.getPaintersModel(), chart.getChartContext());\n        }\n    }\n\n    private void setPosition(List<ItemSelection> selectedItems, PaintersModel paintersModel, ChartContext chartContext) {\n        int tooltipX = -1;\n        int tooltipY = mousePosition.y;\n        for (ItemSelection selection : selectedItems) {\n            ChartItem item = selection.getItem();\n            ItemPainter painter = paintersModel.getPainter(item);\n            Rectangle bounds = Utils.checkedRectangle(\n                               painter.getSelectionBounds(selection,\n                               chartContext));\n            if (tooltipX == -1) tooltipX += bounds.x + bounds.width / 2;\n        }\n\n        setPosition(normalizePosition(new Point(tooltipX, tooltipY)));\n    }\n\n    private Point normalizePosition(Point basePoint) {\n        int w = getWidth();\n        int h = getHeight();\n        int cw = tooltipPainter.getWidth();\n        int ch = tooltipPainter.getHeight();\n\n        basePoint.x += TOOLTIP_OFFSET;\n        if (basePoint.x + cw + TOOLTIP_MARGIN > w)\n            basePoint.x -= TOOLTIP_OFFSET + cw + TOOLTIP_MARGIN;\n        if (basePoint.x < TOOLTIP_OFFSET)\n            basePoint.x = TOOLTIP_OFFSET;\n\n        basePoint.y -= ch + TOOLTIP_MARGIN;\n        if (basePoint.y + ch + TOOLTIP_MARGIN > h)\n            basePoint.y = h - ch - TOOLTIP_MARGIN;\n        if (basePoint.y < TOOLTIP_MARGIN)\n            basePoint.y = TOOLTIP_MARGIN;\n\n        return basePoint;\n    }\n\n\n    public void paint(Graphics g) {\n        if (tooltipPainter == null) return;\n\n        Rectangle bounds = new Rectangle(0, 0, getWidth(), getHeight());\n        Rectangle clip = g.getClipBounds();\n        if (clip == null) g.setClip(bounds);\n        else g.setClip(clip.intersection(bounds));\n\n        super.paint(g);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/src/org/graalvm/visualvm/charts/xy/XYTooltipPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.charts.xy;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class XYTooltipPainter extends JPanel {\n\n    private static Color BACKGROUND_COLOR = Utils.forceSpeed() ?\n                                            new Color(80, 80, 80) :\n                                            new Color(0, 0, 0, 170);\n\n    private JLabel caption;\n    private JLabel[] valuePainters;\n\n    private XYTooltipModel model;\n\n    private boolean initialized;\n\n\n    public XYTooltipPainter(XYTooltipModel model) {\n\n        this.model = model;\n        initialized = false;\n\n    }\n\n\n    public void update(List<ItemSelection> selectedItems) {\n        if (!initialized) initComponents();\n        \n        int rowsCount = model.getRowsCount();\n        if (selectedItems.size() != rowsCount)\n            throw new IllegalStateException(\"Rows and selected items don't match\"); // NOI18N\n\n        XYItemSelection selection = (XYItemSelection)selectedItems.get(0);\n        long timestamp = selection.getItem().getXValue(selection.getValueIndex());\n        caption.setText(model.getTimeValue(timestamp));\n\n        for (int i = 0; i < rowsCount; i++) {\n            XYItemSelection sel = (XYItemSelection)selectedItems.get(i);\n            long itemValue = sel.getItem().getYValue(sel.getValueIndex());\n            valuePainters[i].setText(model.getRowValue(i, itemValue));\n        }\n    }\n\n\n    protected void paintComponent(Graphics g) {\n        g.setColor(BACKGROUND_COLOR);\n        g.fillRect(0, 0, getWidth(), getHeight());\n        super.paintComponent(g);\n    }\n\n\n    private void initComponents() {\n        setOpaque(false);\n        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));\n\n        setLayout(new GridBagLayout());\n        GridBagConstraints constraints;\n\n        caption = new JLabel();\n        caption.setFont(SimpleXYChartUtils.smallerFont(caption.getFont()));\n        caption.setForeground(Color.WHITE);\n        caption.setOpaque(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 0;\n        constraints.weighty = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.insets = new Insets(0, 0, 0, 0);\n        add(caption, constraints);\n\n        int count = model.getRowsCount();\n        valuePainters = new JLabel[count];\n        for (int i = 0; i < count; i++) {\n\n            JLabel itemLabel = new JLabel();\n            itemLabel.setText(model.getRowName(i));\n            itemLabel.setFont(SimpleXYChartUtils.smallerFont(itemLabel.getFont()));\n            itemLabel.setForeground(Color.WHITE);\n            itemLabel.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = i + 1;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            add(itemLabel, constraints);\n\n            JLabel valueLabel = new JLabel();\n            valuePainters[i] = valueLabel;\n            valueLabel.setFont(SimpleXYChartUtils.smallerFont(valueLabel.getFont()));\n            valueLabel.setForeground(Color.WHITE);\n            valueLabel.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = i + 1;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.insets = new Insets(0, 8, 0, 0);\n            add(valueLabel, constraints);\n\n            final Dimension ZERO = new Dimension(0, 0);\n            JPanel valueSpacer = new JPanel(null) {\n                public Dimension getPreferredSize() { return ZERO; }\n            };\n            valueSpacer.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 2;\n            constraints.gridy = i + 1;\n            constraints.weightx = 1;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            add(valueSpacer, constraints);\n\n        }\n\n        initialized = true;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/charts/test/unit/src/test/Demo.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage test;\n\nimport org.graalvm.visualvm.charts.ChartFactory;\nimport org.graalvm.visualvm.charts.SimpleXYChartDescriptor;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport javax.swing.JFrame;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\n\n/**\n * This is not a test, this is a simple demo frame to manually test/debug the\n * charts in a Swing JFrame without a need to build/start the full VisualVM.\n *\n * @author Jiri Sedlacek\n */\npublic class Demo implements Runnable {\n\n    private static final long SLEEP_TIME = 500;\n    private static final int VALUES_LIMIT = 150;\n    private static final int ITEMS_COUNT = 8;\n\n\n    private SimpleXYChartSupport support;\n\n\n    private void createModels() {\n        SimpleXYChartDescriptor descriptor =\n                SimpleXYChartDescriptor.decimal(0, 1000, 1000, 1d, true, VALUES_LIMIT);\n\n        for (int i = 0; i < ITEMS_COUNT; i++)\n            descriptor.addLineFillItems(\"Item \" + i);\n\n        descriptor.setDetailsItems(new String[] { \"Detail 1\", \"Detail 2\", \"Detail 3\" } );\n        descriptor.setChartTitle(\"<html><font size='+1'><b>Demo Chart</b></font></html>\");\n        descriptor.setXAxisDescription(\"<html>X Axis <i>[time]</i></html>\");\n        descriptor.setYAxisDescription(\"<html>Y Axis <i>[units]</i></html>\");\n\n        support = ChartFactory.createSimpleXYChart(descriptor);\n        \n        new Generator(support).start();\n    }\n\n    private void createUI() {\n        JFrame frame = new JFrame(\"Charts Test\");\n        frame.getContentPane().add(support.getChart());\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.setBounds(100, 200, 800, 600);\n        frame.setVisible(true);\n    }\n\n\n    public void run() {\n        createModels();\n        createUI();\n    }\n\n\n    private static class Generator extends Thread {\n\n        private SimpleXYChartSupport support;\n        \n        public void run() {\n            while(true) try {\n                long[] values = new long[ITEMS_COUNT];\n                for (int i = 0; i < values.length; i++)\n                    values[i] = (long)(1000 * Math.random());\n                support.addValues(System.currentTimeMillis(), values);\n                support.updateDetails(new String[] { 1000 * Math.random() + \"\",\n                                                     1000 * Math.random() + \"\",\n                                                     1000 * Math.random() + \"\"});\n                Thread.sleep(SLEEP_TIME);\n            } catch (Exception e) {\n                e.printStackTrace(System.err);\n            }\n        }\n        \n        private Generator(SimpleXYChartSupport support) {\n            this.support = support;\n        }\n\n    }\n\n\n    public static void main(String[] args) {\n        try {\n            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());\n//            UIManager.setLookAndFeel(\"javax.swing.plaf.metal.MetalLookAndFeel\");\n//            UIManager.setLookAndFeel(\"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel\");\n//            UIManager.setLookAndFeel(\"com.sun.java.swing.plaf.windows.WindowsLookAndFeel\");\n//            UIManager.setLookAndFeel(\"com.sun.java.swing.plaf.gtk.GTKLookAndFeel\");\n//            UIManager.setLookAndFeel(\"com.sun.java.swing.plaf.mac.MacLookAndFeel\");\n//            UIManager.setLookAndFeel(\"com.sun.java.swing.plaf.motif.MotifLookAndFeel\");\n            SwingUtilities.invokeLater(new Demo());\n        } catch (Exception e) {}\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.core\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.core.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/core/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.core/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/core/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/core/Bundle.properties\nOpenIDE-Module-Install: org/graalvm/visualvm/core/Install$Impl.class\nOpenIDE-Module-Specification-Version: 2.4\n\n"
  },
  {
    "path": "visualvm/core/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.core-impl\" basedir=\"..\" xmlns:nbmproject=\"http://www.netbeans.org/ns/nb-module-project/2\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\"/>\n    <nbmproject:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/core/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=35be65f3\nbuild.xml.script.CRC32=ed1a64ac\nbuild.xml.stylesheet.CRC32=05353c81\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=35be65f3\nnbproject/build-impl.xml.script.CRC32=4fae7134\nnbproject/build-impl.xml.stylesheet.CRC32=3f8b4615\n"
  },
  {
    "path": "visualvm/core/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\njavac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/core/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.core</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.common</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.options.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.sendopts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.10</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.11</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.loaders</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.67</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.2</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.nodes</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.2.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.14</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <test-dependencies>\n                <test-type>\n                    <name>unit</name>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.libs.junit4</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                </test-type>\n            </test-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.core</package>\n                <package>org.graalvm.visualvm.core.datasource</package>\n                <package>org.graalvm.visualvm.core.datasource.descriptor</package>\n                <package>org.graalvm.visualvm.core.datasupport</package>\n                <package>org.graalvm.visualvm.core.explorer</package>\n                <package>org.graalvm.visualvm.core.model</package>\n                <package>org.graalvm.visualvm.core.options</package>\n                <package>org.graalvm.visualvm.core.properties</package>\n                <package>org.graalvm.visualvm.core.scheduler</package>\n                <package>org.graalvm.visualvm.core.snapshot</package>\n                <package>org.graalvm.visualvm.core.ui</package>\n                <package>org.graalvm.visualvm.core.ui.actions</package>\n                <package>org.graalvm.visualvm.core.ui.components</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/core/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Core\nOpenIDE-Module-Short-Description=VisualVM main module\norg_graalvm_visualvm_core_update_center=https://visualvm.github.io/uc/dev/updates.xml.gz?{$netbeans.hash.code}\nServices/AutoupdateType/org_graalvm_visualvm_core_update_center.instance=VisualVM Plugins Center\nMenu/Applications=&Applications\nToolbars/Snapshot=&Snapshot\nToolbars/DataSource=&Data Source\nOptionsHandle=Tools | Options\nOptionsHandleMac=VisualVM | Preferences...\nLogfileHandle=Help | About | Logfile\nLogfileHandleMac=VisualVM | About VisualVM | Logfile\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/Install.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core;\n\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsSupport;\nimport java.io.File;\nimport org.openide.modules.ModuleInstall;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass Install {\n    // Class implementing logic on VisualVM module install\n    public static class Impl extends ModuleInstall {\n        \n        @Override\n        public boolean closing() {\n            return VisualVM.getInstance().closing();\n        }\n\n        @Override\n        public void restored() {\n            // NOTE: this has to be called before any of DataSourceProviders initializes\n            cleanupPreviousSession();\n\n            DataSourceRepository.sharedInstance();\n\n            // Initialize snapshots\n            SnapshotsSupport.getInstance();\n        }\n\n        private void cleanupPreviousSession() {\n            File temporaryStorage = new File(Storage.getTemporaryStorageDirectoryString());\n            Utils.delete(temporaryStorage, false);\n        }\n\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/VisualVM.java",
    "content": "/*\n * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core;\n\nimport java.lang.ref.WeakReference;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport org.graalvm.visualvm.core.datasupport.ComparableWeakReference;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.Utilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class VisualVM {\n    \n    private static final VisualVM INSTANCE = new VisualVM();\n    \n    \n    private final int TASK_PROCESSOR_THROUGHPUT_DEFAULT = 30;\n    private final int TASK_PROCESSOR_THROUGHPUT = Integer.getInteger(\"org.graalvm.visualvm.core.taskProcessorThroughput\", // NOI18N\n                                                                     TASK_PROCESSOR_THROUGHPUT_DEFAULT);\n    \n    \n    private final RequestProcessor taskProcessor;\n    \n    private Collection<ComparableWeakReference<Runnable>> closingHandlers;\n    \n    \n    private VisualVM() {\n        taskProcessor = new RequestProcessor(\"VisualVM Shared RequestProcessor\", TASK_PROCESSOR_THROUGHPUT); // NOI18N\n    }\n    \n    \n    public static VisualVM getInstance() { return INSTANCE; }\n    \n    \n    public final void runTask(Runnable task) {\n        taskProcessor.post(task);\n    }\n    \n    public final void runTask(Runnable task, int timeToWait) {\n        taskProcessor.post(task, timeToWait);\n    }\n    \n    \n    /**\n     * Adds a Runnable instance to be notified when the host VisualVM is closing.\n     * Note that the Runnable cannot be explicitly unregistered, it's weakly referenced and will\n     * be notified up to once and then unregistered automatically.\n     * \n     * @param handler Runnable instance to be notified when the host VisualVM is closing.\n     */\n    public synchronized final void notifyWhenClosing(Runnable handler) {\n        if (closingHandlers == null) closingHandlers = new ArrayList<>();\n        closingHandlers.add(new ComparableWeakReference<>(handler));\n    }\n    \n    \n    synchronized boolean closing() {\n        if (closingHandlers != null)\n            for (WeakReference<Runnable> handlerR : closingHandlers) {\n                Runnable handler = handlerR.get();\n                if (handler != null)\n                    try { handler.run(); }\n                    catch (Exception e) { System.err.println(\"Exception handling VisualVM.closing(): \" + e); } // NOI18N\n            }\n        \n        return true;\n    }\n    \n    \n    public final String getOptionsHandle() {\n        return Utilities.isMac() ?\n                NbBundle.getMessage(VisualVM.class, \"OptionsHandleMac\") :       // NOI18N\n                NbBundle.getMessage(VisualVM.class, \"OptionsHandle\");           // NOI18N\n    }\n    \n    public final String getLogfileHandle() {\n        return Utilities.isMac() ?\n                NbBundle.getMessage(VisualVM.class, \"LogfileHandleMac\") :       // NOI18N\n                NbBundle.getMessage(VisualVM.class, \"LogfileHandle\");           // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasource/DataSource.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.datasource;\n\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.datasupport.ComparableWeakReference;\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport java.lang.ref.WeakReference;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.openide.util.RequestProcessor;\n\n/**\n * Abstract implementation of DataSource.\n * DataSource is a base element of all data sources in VisualVM like applications,\n * hosts, thread dumps etc.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class DataSource {\n    \n    /**\n     * Named property for DataSource visibility.\n     */\n    public static final String PROPERTY_VISIBLE = \"prop_visible\";   // NOI18N\n    \n    /**\n     * Event dispatch thread for all DataSource events. All operations on DataSources should be invoked\n     * in this thread - similar to UI operations performed in AWT event dispatch thread.\n     */\n    public static final RequestProcessor EVENT_QUEUE = new RequestProcessor(\"DataSource Event Queue\");  // NOI18N\n    \n    /**\n     * Virtual root of DataSource tree.\n     * ROOT corresponds to invisible root of explorer tree.\n     */\n    public static final DataSource ROOT = new DataSource() {};\n    \n    \n    private DataSource owner;\n    private boolean isRemoved = false;\n    private DataSource master;\n    private boolean visible = true;\n    private Storage storage;\n    private DataSourceContainer repository;\n    private final Object propertiesLock = new Object();\n    private PropertyChangeSupport changeSupport;\n    private Set<ComparableWeakReference<DataRemovedListener>> removedListeners;\n\n\n    /**\n     * Creates new instance of DataSource.\n     */\n    public DataSource() {\n        this(null);\n    }\n\n    /**\n     * Creates new instance of DataSource with defined master.\n     * \n     * @param master master of the DataSource.\n     */\n    public DataSource(DataSource master) {\n        this.master = master;\n    }\n    \n    \n    /**\n     * Returns owner (parent) DataSource of this DataSource.\n     * @return owner (parent) DataSource of this DataSource.\n     */\n    public final DataSource getOwner() {\n        return owner;\n    }\n    \n    /**\n     * Sets visibility of the DataSource.\n     * \n     * @param newVisible visibility of the DataSource.\n     */\n    public final synchronized void setVisible(boolean newVisible) {\n        if (this == DataSource.ROOT && !newVisible) throw new IllegalArgumentException(\"DataSourceRoot cannot be hidden\");  // NOI18N\n        boolean oldVisible = visible;\n        visible = newVisible;\n        getChangeSupport().firePropertyChange(PROPERTY_VISIBLE, oldVisible, newVisible);\n    }\n\n    /**\n     * Returns true if the DataSource is visible, false otherwise.\n     * \n     * @return true if the DataSource is visible, false otherwise.\n     */\n    public final boolean isVisible() {\n        return visible;\n    }\n    \n    /**\n     * Returns master of the DataSource.\n     * \n     * @return master of the DataSource.\n     */\n    public final DataSource getMaster() {\n        return master;\n    }\n    \n    /**\n     * Returns storage for the DataSource.\n     * \n     * @return storage for the DataSource.\n     */\n    public final synchronized Storage getStorage() {\n        if (storage == null) {\n            storage = createStorage();\n            if (storage == null) throw new NullPointerException(\"Storage cannot be null\");  // NOI18N\n        }\n        return storage;\n    }\n\n    /**\n     * Returns repository of the DataSource.\n     * Repository is a container for other DataSources, virtually building a tree\n     * structure of DataSources.\n     * \n     * @return repository of the DataSource.\n     */\n    public final synchronized DataSourceContainer getRepository() {\n        if (repository == null) repository = new DataSourceContainer(this);\n        return repository;\n    }\n\n    /**\n     * Add a PropertyChangeListener to the listener list.\n     * The listener is registered for all properties.\n     * The same listener object may be added more than once, and will be called\n     * as many times as it is added.\n     * If <code>listener</code> is null, no exception is thrown and no action\n     * is taken.\n     *\n     * @param listener  The PropertyChangeListener to be added\n     */\n    public final void addPropertyChangeListener(PropertyChangeListener listener) {\n        getChangeSupport().addPropertyChangeListener(listener);\n    }\n\n    /**\n     * Add a PropertyChangeListener for a specific property.  The listener\n     * will be invoked only when a call on firePropertyChange names that\n     * specific property.\n     * The same listener object may be added more than once.  For each\n     * property,  the listener will be invoked the number of times it was added\n     * for that property.\n     * If <code>propertyName</code> or <code>listener</code> is null, no\n     * exception is thrown and no action is taken.\n     *\n     * @param propertyName  The name of the property to listen on.\n     * @param listener  The PropertyChangeListener to be added\n     */\n    public final void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {\n        getChangeSupport().addPropertyChangeListener(propertyName, listener);\n    }\n\n    /**\n     * Remove a PropertyChangeListener from the listener list.\n     * This removes a PropertyChangeListener that was registered\n     * for all properties.\n     * If <code>listener</code> was added more than once to the same event\n     * source, it will be notified one less time after being removed.\n     * If <code>listener</code> is null, or was never added, no exception is\n     * thrown and no action is taken.\n     *\n     * @param listener  The PropertyChangeListener to be removed\n     */\n    public final void removePropertyChangeListener(PropertyChangeListener listener) {\n        getChangeSupport().removePropertyChangeListener(listener);\n    }\n\n    /**\n     * Remove a PropertyChangeListener for a specific property.\n     * If <code>listener</code> was added more than once to the same event\n     * source for the specified property, it will be notified one less time\n     * after being removed.\n     * If <code>propertyName</code> is null,  no exception is thrown and no\n     * action is taken.\n     * If <code>listener</code> is null, or was never added for the specified\n     * property, no exception is thrown and no action is taken.\n     *\n     * @param propertyName  The name of the property that was listened on.\n     * @param listener  The PropertyChangeListener to be removed\n     */\n    public final void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {\n        getChangeSupport().removePropertyChangeListener(propertyName, listener);\n    }\n    \n    /**\n     * Returns true if the DataSource can be removed using Remove action, false otherwise.\n     * \n     * @return true if the DataSource can be removed using Remove action, false otherwise.\n     */\n    public boolean supportsUserRemove() {\n        return false;\n    }\n    \n    /**\n     * Adds a DataRemovedListener to be notified when the DataSource is removed from the tree.\n     * Note that this listener cannot be explicitly unregistered, it's weakly referenced and will\n     * be notified up to once and then unregistered automatically.\n     * \n     * @param listener DataRemovedListener to be notified when the DataSource is removed from the tree.\n     */\n    public final void notifyWhenRemoved(DataRemovedListener listener) {\n        if (listener == null) throw new IllegalArgumentException(\"Listener cannot be null\");    // NOI18N\n        if (isRemoved()) listener.dataRemoved(this);\n        else synchronized (propertiesLock) {\n            getRemovedListeners().add(new ComparableWeakReference<>(listener));\n        }\n    }\n    \n    /**\n     * Returns true if the DataSource has already been removed from DataSources tree, false otherwise.\n     * @return true if the DataSource has already been removed from DataSources tree, false otherwise.\n     */\n    public final boolean isRemoved() {\n        return isRemoved;\n    }\n    \n    /**\n     * Returns true if the DataSource can be removed in context of removeRoot.\n     * The check is blocking, this is a chance for example to warn the user about\n     * possible data loss when removing the DataSource representing an unsaved snapshot.\n     * \n     * @param removeRoot DataSource which invoked the removal action (topmost DataSource to be removed).\n     * @return true if the DataSource can be removed in context of removeRoot, false otherwise.\n     */\n    public boolean checkRemove(DataSource removeRoot) {\n        return true;\n    }\n    \n    // Implementation of this DataSource removal\n    // Persistent DataSources can remove appropriate entries from their storage\n    protected void remove() {\n        getStorage().deleteCustomPropertiesStorage();\n    }\n    \n    \n    final void addImpl(DataSource owner) {\n        if (isRemoved) throw new UnsupportedOperationException(\"DataSource can be added only once\");    // NOI18N\n        this.owner = owner;\n    }\n    \n    final void removeImpl() {\n        remove();\n        \n        this.owner = null;\n        isRemoved = true;\n        Set<ComparableWeakReference<DataRemovedListener>> listenersCopy;\n        \n        synchronized (propertiesLock) {\n            if (!hasRemovedListeners()) return;\n            Set<ComparableWeakReference<DataRemovedListener>> listeners = getRemovedListeners();\n            listenersCopy = new HashSet<>(listeners);\n            listeners.clear();\n        }\n        for (WeakReference<DataRemovedListener> listenerReference : listenersCopy) {\n            DataRemovedListener listener = listenerReference.get();\n            if (listener != null) listener.dataRemoved(this);\n        }\n    }\n    \n    \n    /**\n     * Creates Storage instance for this DataSource.\n     * This method should never return null.\n     * \n     * @return Storage instance for this DataSource.\n     */\n    protected Storage createStorage() {\n        return new Storage();\n    }\n    \n    /**\n     * Returns instance of PropertyChangeSupport used for processing property changes.\n     * \n     * @return instance of PropertyChangeSupport used for processing property changes.\n     */\n    protected final PropertyChangeSupport getChangeSupport() {\n        synchronized (propertiesLock) {\n            if (changeSupport == null) changeSupport = new PropertyChangeSupport(this);\n            return changeSupport;\n        }\n    }\n    \n    \n    private boolean hasRemovedListeners() {\n        return removedListeners != null;\n    }\n    \n    final Set<ComparableWeakReference<DataRemovedListener>> getRemovedListeners() {\n        synchronized (propertiesLock) {\n            if (!hasRemovedListeners()) removedListeners = new HashSet<>();\n            return removedListeners;\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasource/DataSourceContainer.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.datasource;\n\nimport java.util.Set;\n\n/**\n * Default implementation of DataSourceContainer.\n * This class implements all necessary methods to act as a repository of a DataSource (DataSource.getRepository()).\n *\n * @author Jiri Sedlacek\n */\npublic final class DataSourceContainer extends DataSourceProvider {\n    \n    private final DataSource owner;\n    \n    \n    /**\n     * Default implementation of DataSourceContainer.\n     * DataSources can benefit from using this class which implements\n     * managing created DataSource instances and firing the events to listeners\n     * as their repositories.\n     * \n     * @param owner\n     */\n    DataSourceContainer(DataSource owner) {\n        this.owner = owner;\n    }\n    \n\n    /**\n     * Adds a DataSource to the container.\n     * \n     * @param added DataSource to be added.\n     */\n    public void addDataSource(DataSource added) {\n        registerDataSource(added);\n    }\n\n    /**\n     * Adds several DataSources to the container at once.\n     * \n     * @param added DataSources to be added.\n     */\n    public void addDataSources(Set<? extends DataSource> added) {\n        super.registerDataSources(added);\n    }\n\n    /**\n     * Removes a DataSource from the container.\n     * \n     * @param removed DataSource to be removed.\n     */\n    public void removeDataSource(DataSource removed) {\n        unregisterDataSource(removed);\n    }\n\n    /**\n     * Removes several DataSources from the container at once.\n     * \n     * @param removed DataSources to be removed.\n     */\n    public void removeDataSources(Set<? extends DataSource> removed) {\n        super.unregisterDataSources(removed);\n    }\n    \n    /**\n     * Adds and removes several DataSources to/from the container in a single operation.\n     * \n     * @param added DataSources to be added.\n     * @param removed DataSources to be removed.\n     */\n    public void updateDataSources(Set<? extends DataSource> added, Set<? extends DataSource> removed) {\n        super.changeDataSources(added, removed);\n    }\n    \n    \n    protected void registerDataSourcesImpl(Set<? extends DataSource> added) {\n        for (DataSource dataSource : added) dataSource.addImpl(owner);\n        super.registerDataSourcesImpl(added);\n    }\n    \n    protected void unregisterDataSourcesImpl(Set<? extends DataSource> removed) {\n        for (DataSource dataSource : removed) {\n            DataSourceContainer dataSourceRepository = dataSource.getRepository();\n            dataSourceRepository.unregisterDataSourcesImpl(dataSourceRepository.getDataSources());\n            dataSource.removeImpl();\n        }\n        super.unregisterDataSourcesImpl(removed);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasource/DataSourceProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.datasource;\n\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n/**\n * Default implementation of DataSourceProvider.\n * DataSourceProviders can benefit from extending this class which implements\n * managing created DataSource instances and firing the events to listeners.\n *\n * @author Jiri Sedlacek\n */\npublic class DataSourceProvider {\n\n    private static final boolean SUPPRESS_EXCEPTIONS_UI =\n            Boolean.getBoolean(DataSourceProvider.class.getName() + \".suppressExceptionsUI\"); // NOI18N\n    private static final Logger LOGGER = Logger.getLogger(DataSourceProvider.class.getName());\n\n    private final Set<DataSource> dataSources = Collections.synchronizedSet(new HashSet<>());\n    private final Map<DataChangeListener<? extends DataSource>, Class<? extends DataSource>> listeners = new HashMap<>();\n\n\n    /**\n     * Creates new instance of DataSourceProvider.\n     */\n    DataSourceProvider() {\n    }\n\n\n    /**\n     * Adds a DataChangeListener to listen for added/removed DataSources.\n     *\n     * @param <Y> any DataSource type.\n     * @param listener listener to be added.\n     * @param scope scope of DataSource types for which to get notifications.\n     */\n    public final <Y extends DataSource> void addDataChangeListener(final DataChangeListener<Y> listener, final Class<Y> scope) {\n        DataSource.EVENT_QUEUE.post(new Runnable() {\n            public void run() {\n                if (listeners.containsKey(listener)) {\n                    String msg = \"Listener \" + listener + \" already registered\"; // NOI18N\n                    LOGGER.log(Level.SEVERE, msg, new UnsupportedOperationException(msg));\n                } else {\n                    listeners.put(listener, scope);\n                    fireCurrentState(listener);\n                }\n            }\n        });\n    }\n\n    /**\n     * Removes a DataChange listener.\n     *\n     * @param <Y> any DataSource type.\n     * @param listener listener to be removed.\n     */\n    public final <Y extends DataSource> void removeDataChangeListener(final DataChangeListener<Y> listener) {\n        DataSource.EVENT_QUEUE.post(new Runnable() {\n            public void run() {\n                if (!listeners.containsKey(listener)) {\n                    String msg = \"Listener \" + listener + \" not registered\"; // NOI18N\n                    LOGGER.log(Level.SEVERE, msg, new UnsupportedOperationException(msg));\n                } else {\n                    listeners.remove(listener);\n                }\n            }\n        });\n    }\n\n    /**\n     * Returns DataSources managed by this provider.\n     * @return DataSources managed by this provider.\n     */\n    public final Set<DataSource> getDataSources() {\n        return new HashSet<>(dataSources);\n    }\n\n    /**\n     * Returns DataSources of a certain type managed by this provider.\n     *\n     * @param <Y> any DataSource type.\n     * @param scope DataSource types to return.\n     * @return DataSources of a certain type managed by this provider.\n     */\n    public final <Y extends DataSource> Set<Y> getDataSources(Class<Y> scope) {\n        return Utils.getFilteredSet(getDataSources(), scope);\n    }\n\n\n    /**\n     * Registers added DataSource into this provider.\n     *\n     * @param added added DataSource to register.\n     */\n    protected final void registerDataSource(DataSource added) {\n        registerDataSources(Collections.singleton(added));\n    }\n\n    /**\n     * Registers added DataSources into this provider.\n     *\n     * @param added added DataSources to register.\n     */\n    protected final void registerDataSources(final Set<? extends DataSource> added) {\n        DataSource.EVENT_QUEUE.post(new Runnable() {\n            public void run() {\n                if (!added.isEmpty())\n                    registerDataSourcesImpl(checkAdded(added));\n            }\n        });\n    }\n\n    /**\n     * Unregisters removed DataSource from this provider.\n     *\n     * @param removed removed DataSource to unregister.\n     */\n    protected final void unregisterDataSource(DataSource removed) {\n        unregisterDataSources(Collections.singleton(removed));\n    }\n\n    /**\n     * Unregisters removed DataSources from this provider.\n     *\n     * @param removed removed DataSources to unregister.\n     */\n    protected final void unregisterDataSources(final Set<? extends DataSource> removed) {\n        DataSource.EVENT_QUEUE.post(new Runnable() {\n            public void run() {\n                if (!removed.isEmpty())\n                    unregisterDataSourcesImpl(checkRemoved(removed));\n            }\n        });\n    }\n\n    /**\n     * Registers added DataSources into this provider and unregisters removed DataSources from this provider.\n     *\n     * @param added added DataSources to register.\n     * @param removed removed DataSources to unregister.\n     */\n    protected final void changeDataSources(final Set<? extends DataSource> added, final Set<? extends DataSource> removed) {\n        DataSource.EVENT_QUEUE.post(new Runnable() {\n            public void run() {\n                if (!removed.isEmpty())\n                    unregisterDataSourcesImpl(checkRemoved(removed));\n                if (!added.isEmpty())\n                    registerDataSourcesImpl(checkAdded(added));\n            }\n        });\n    }\n\n    void registerDataSourcesImpl(Set<? extends DataSource> added) {\n        dataSources.addAll(added);\n        fireDataAdded(added);\n    }\n\n    void unregisterDataSourcesImpl(Set<? extends DataSource> removed) {\n        dataSources.removeAll(removed);\n        fireDataRemoved(removed);\n    }\n\n    private Set<? extends DataSource> checkAdded(Set<? extends DataSource> added) {\n        Set<? extends DataSource> uniqueAdded = new HashSet<>(added);\n        Iterator<? extends DataSource> it = uniqueAdded.iterator();\n\n        while(it.hasNext()) {\n            DataSource ds = it.next();\n            if (dataSources.contains(ds)) {\n                it.remove();\n                logUnsupportedOperation(\"DataSource already in repository: \" + ds); // NOI18N\n            }\n        }\n\n        return uniqueAdded;\n    }\n\n    private Set<? extends DataSource> checkRemoved(Set<? extends DataSource> removed) {\n        Set<? extends DataSource> uniqueRemoved = new HashSet<>(removed);\n        Iterator<? extends DataSource> it = uniqueRemoved.iterator();\n\n        while(it.hasNext()) {\n            DataSource ds = it.next();\n            if (!dataSources.contains(ds)) {\n                it.remove();\n                logUnsupportedOperation(\"DataSource not in repository: \" + ds); // NOI18N\n            }\n        }\n\n        return uniqueRemoved;\n    }\n\n\n    private static void logUnsupportedOperation(String msg) {\n        if (SUPPRESS_EXCEPTIONS_UI) LOGGER.severe(msg);\n        else LOGGER.log(Level.SEVERE, msg, new UnsupportedOperationException(msg));\n    }\n\n\n    private void fireCurrentState(DataChangeListener<? extends DataSource> listener) {\n        fireDataChanged(listener, null, null);\n    }\n\n    private void fireDataAdded(Set<? extends DataSource> added) {\n        fireDataChanged(added, Collections.emptySet());\n    }\n\n    private void fireDataRemoved(Set<? extends DataSource> removed) {\n        fireDataChanged(Collections.emptySet(), removed);\n    }\n\n    private void fireDataChanged(Set<? extends DataSource> added, Set<? extends DataSource> removed) {\n        Set<DataChangeListener<? extends DataSource>> listenersSet = listeners.keySet();\n        for (DataChangeListener listener : listenersSet) fireDataChanged(listener, added, removed);\n    }\n\n    private void fireDataChanged(DataChangeListener<? extends DataSource> listener, Set<? extends DataSource> added, Set<? extends DataSource> removed) {\n        Class<? extends DataSource> filter = listeners.get(listener);\n        Set<? extends DataSource> filteredCurrent = Utils.getFilteredSet(dataSources, filter);\n        if (added == null && removed == null) {\n            DataChangeEvent event = new DataChangeEvent(filteredCurrent, filteredCurrent, null);\n            listener.dataChanged(event);\n        } else {\n            Set<? extends DataSource> filteredAdded = added != null ? Utils.getFilteredSet(added, filter) : Collections.emptySet();\n            Set<? extends DataSource> filteredRemoved = removed != null ? Utils.getFilteredSet(removed, filter) : Collections.emptySet();\n            if (!filteredAdded.isEmpty() || !filteredRemoved.isEmpty()) {\n                DataChangeEvent event = new DataChangeEvent(filteredCurrent, filteredAdded, filteredRemoved);\n                listener.dataChanged(event);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasource/DataSourceRepository.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.datasource;\n\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport java.util.Set;\n\n/**\n * Central repository of all known DataSources.\n * Whenever is a new DataSource added to DataSources tree, DataSourceRepository\n * detects it and emits notifications to listeners.\n *\n * @author Jiri Sedlacek\n */\npublic final class DataSourceRepository extends DataSourceProvider {\n\n    private static DataSourceRepository sharedInstance;\n\n    private final Listener dataChangeListener = new Listener();\n\n    /**\n     * Returns singleton instance of DataSourceRepository.\n     * \n     * @return singleton instance of DataSourceRepository.\n     */\n    public synchronized static DataSourceRepository sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new DataSourceRepository();\n        return sharedInstance;\n    }\n\n    \n    void registerDataSourcesImpl(Set<? extends DataSource> added) {\n        super.registerDataSourcesImpl(added);\n        for (DataSource dataSource : added) dataSource.getRepository().addDataChangeListener(dataChangeListener, DataSource.class);\n    }\n    \n    void unregisterDataSourcesImpl(Set<? extends DataSource> removed) {\n        super.unregisterDataSourcesImpl(removed);\n        for (DataSource dataSource : removed) dataSource.getRepository().removeDataChangeListener(dataChangeListener);\n    }\n    \n    \n    private DataSourceRepository() {\n        registerDataSource(DataSource.ROOT);\n    }\n    \n    \n    private class Listener implements DataChangeListener<DataSource> {\n        \n        public void dataChanged(DataChangeEvent<DataSource> event) {\n            Set<DataSource> added = event.getAdded();\n            Set<DataSource> removed = event.getRemoved();\n            if (!added.isEmpty() || !removed.isEmpty()) changeDataSources(added, removed);\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasource/StatefulDataSource.java",
    "content": "/*\n * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core.datasource;\n\nimport org.graalvm.visualvm.core.datasupport.Stateful;\n\n/**\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic abstract class StatefulDataSource extends DataSource implements Stateful {\n\n    private int state = STATE_UNKNOWN;\n    private int modCount;\n    private final Object stateLock = new Object();\n    \n    protected StatefulDataSource() {\n        this(STATE_AVAILABLE);\n    }\n    \n    protected StatefulDataSource(int state) {\n        this.state = state;\n    }\n\n    public final int getState() {\n        synchronized (stateLock) {\n            return state;\n        }\n    }\n\n    public final int getModCount() {\n        synchronized (stateLock) {\n            return modCount;\n        }\n    }\n\n    protected final void setState(final int newState) {\n        synchronized (stateLock) {\n            final int oldState = state;\n            state = newState;\n            if (oldState != newState && newState == STATE_AVAILABLE) {\n                modCount++;\n            }\n            if (DataSource.EVENT_QUEUE.isRequestProcessorThread()) {\n                getChangeSupport().firePropertyChange(PROPERTY_STATE, oldState, newState);\n            } else {\n                DataSource.EVENT_QUEUE.post(new Runnable() {\n                    public void run() {\n                        getChangeSupport().firePropertyChange(PROPERTY_STATE, oldState, newState);\n                    }\n                });\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasource/Storage.java",
    "content": "/*\n *  Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.datasource;\n\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.text.MessageFormat;\nimport java.util.Properties;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n/**\n * Storage for a DataSource.\n *\n * @author Jiri Sedlacek\n */\npublic final class Storage {\n\n    private static final String VISUALVM_TMP_DIR = System.getProperty(\"visualvm.tmpdir\");  // NOI18N\n    private static final String TEMPORARY_STORAGE_DIRNAME = \"visualvm.dat\";  // NOI18N\n    private static final String TEMPORARY_STORAGE_DIRNAME_EX = \"visualvm_{0}.dat\";  // NOI18N\n    private static final String PERSISTENT_STORAGE_DIRNAME = \"repository\";  // NOI18N\n    \n    private static final Logger LOGGER = Logger.getLogger(Storage.class.getName());\n    \n    /**\n     * Default extension for storage file.\n     */\n    public static final String DEFAULT_PROPERTIES_EXT = \".properties\";  // NOI18N\n    \n    private static final Object temporaryStorageDirectoryLock = new Object();\n    // @GuardedBy temporaryStorageDirectory\n    private static File temporaryStorageDirectory;\n    private static final Object temporaryStorageDirectoryStringLock = new Object();\n    // @GuardedBy temporaryStorageDirectoryString\n    private static String temporaryStorageDirectoryString;\n    private static final Object persistentStorageDirectoryLock = new Object();\n    // @GuardedBy persistentStorageDirectory\n    private static File persistentStorageDirectory;\n    private static final Object persistentStorageDirectoryStringLock = new Object();\n    // @GuardedBy persistentStorageDirectoryString\n    private static String persistentStorageDirectoryString;\n    \n    private final File directory;\n    private final File propertiesFile;\n    \n    private Properties properties;\n\n\n    /**\n     * Creates new instance of Storage for storing temporary data. The Storage\n     * directory is initialized by getTemporaryStorageDirectory() value.\n     */\n    public Storage() {\n        this(new File(getTemporaryStorageDirectoryString())); // Do not create immediately\n    }\n    \n    /**\n     * Creates new instance of Storage.\n     * \n     * @param directory directory where storage data will be stored.\n     */\n    public Storage(File directory) {\n        this(directory, null);\n    }\n    \n    /**\n     * Creates new instance of Storage.\n     * \n     * @param directory directory where storage data will be stored.\n     * @param propertiesFile filename of storage file.\n     */\n    public Storage(File directory, String propertiesFile) {\n        if (directory == null) throw new NullPointerException(\"Directory cannot be null\");  // NOI18N\n        if (directory.isFile()) throw new IllegalArgumentException(\"Not a valid directory: \" + directory);  // NOI18N\n        this.directory = directory;\n        this.propertiesFile = propertiesFile != null ? new File(directory, propertiesFile) : null;\n    }\n    \n    \n    /**\n     * Returns true if storage directory exists, false otherwise.\n     * \n     * @return true if storage directory exists, false otherwise.\n     */\n    public synchronized boolean directoryExists() {\n        return directory.exists();\n    }\n    \n    /**\n     * Returns storage directory.\n     * \n     * @return storage directory.\n     */\n    public synchronized File getDirectory() {\n        if (!Utils.prepareDirectory(directory)) throw new IllegalStateException(\"Cannot create storage directory \" + directory);    // NOI18N\n        return directory;\n    }\n    \n    /**\n     * Returns defined custom property.\n     * \n     * @param key property name.\n     * @return defined custom property.\n     */\n    public String getCustomProperty(String key) {\n        return getCustomProperties(new String[] { key })[0];\n    }\n    \n    /**\n     * Returns defined custom properties.\n     * \n     * @param keys property names.\n     * @return defined custom properties.\n     */\n    public synchronized String[] getCustomProperties(String[] keys) {\n        String[] values = new String[keys.length];\n        Properties prop = getCustomProperties(false);\n        if (prop != null)\n            for (int i = 0; i < keys.length; i++)\n                    values[i] = prop.getProperty(keys[i]);\n        return values;\n    }\n    \n    /**\n     * Sets persistent custom property.\n     * Since VisualVM 1.2 clears the property for null value.\n     * \n     * @param key property name.\n     * @param value property value or (since VisualVM 1.2) null\n     */\n    public void setCustomProperty(String key, String value) {\n        setCustomProperties(new String[] { key }, new String[] { value });\n    }\n    \n    /**\n     * Sets persistent custom properties.\n     * Since VisualVM 1.2 a property is cleared for null value.\n     * \n     * @param keys property names.\n     * @param values property values.\n     */\n    public synchronized void setCustomProperties(String[] keys, String[] values) {\n        Properties prop = getCustomProperties(true);\n        for (int i = 0; i < keys.length; i++)\n            if (values[i] != null) prop.put(keys[i], values[i]);\n            else prop.remove(keys[i]);\n        storeCustomProperties(); // NOTE: this could be done lazily if storeCustomProperties() was public\n    }\n\n    /**\n     * Clears custom property.\n     *\n     * @param key property name\n     */\n    public void clearCustomProperty(String key) {\n        clearCustomProperties(new String[] { key });\n    }\n\n    /**\n     * Clears custom properties.\n     *\n     * @param keys property names\n     */\n    public synchronized void clearCustomProperties(String[] keys) {\n        Properties prop = getCustomProperties(false);\n        if (prop != null)\n            for (String key : keys) {\n                prop.remove(key);\n            }\n        storeCustomProperties(); // NOTE: this could be done lazily if storeCustomProperties() was public\n    }\n\n    /**\n     * Returns true if the Storage contains any custom properties, false otherwise.\n     *\n     * @return true if the Storage contains any custom properties, false otherwise\n     */\n    public synchronized boolean hasCustomProperties() {\n        Properties prop = getCustomProperties(false);\n        return prop != null && !prop.isEmpty();\n    }\n    \n    /**\n     * Saves persistent custom properties to a file.\n     * \n     * @param file file where the properties will be saved.\n     */\n    public synchronized void saveCustomPropertiesTo(File file) {\n        if (file == null) throw new NullPointerException(\"File cannot be null\");    // NOI18N\n        if (file.isDirectory()) throw new IllegalArgumentException(\"Not a valid file: \" + file);    // NOI18N\n        \n        Properties prop = getCustomProperties(false);\n        if (prop != null && !prop.isEmpty()) storeProperties(prop, file);\n    }\n    \n    /**\n     * Deletes properties file.\n     */\n    public synchronized void deleteCustomPropertiesStorage() {\n        if (propertiesFile != null && propertiesFile.exists())\n            if (!propertiesFile.delete()) propertiesFile.deleteOnExit();\n    }\n    \n    \n    /**\n     * Returns default storage directory for temporary (runtime) DataSource data\n     * \n     * @return default storage directory for temporary (runtime) DataSource data\n     */\n    public static String getTemporaryStorageDirectoryString() {\n        synchronized(temporaryStorageDirectoryStringLock) {\n            if (temporaryStorageDirectoryString == null) {\n                if (VISUALVM_TMP_DIR != null) {\n                    temporaryStorageDirectoryString = new File(VISUALVM_TMP_DIR).getAbsolutePath() +\n                                                      File.separator + TEMPORARY_STORAGE_DIRNAME;\n                } else {\n                    String tmpDir = System.getProperty(\"java.io.tmpdir\"); // NOI18N\n                    String storageDir;\n                    \n                    String userDir = System.getProperty(\"user.home\"); // NOI18N\n                    if (userDir != null && !userDir.isEmpty()) {\n                        String userName = new File(userDir).getName();\n                        storageDir = MessageFormat.format(TEMPORARY_STORAGE_DIRNAME_EX, userName);\n                    } else {\n                        storageDir = TEMPORARY_STORAGE_DIRNAME;\n                    }\n                    \n                    temporaryStorageDirectoryString = new File(tmpDir).getAbsolutePath() +\n                                                      File.separator + storageDir;\n                }\n            }\n            return temporaryStorageDirectoryString;\n        }\n    }\n    \n    /**\n     * Returns default storage directory for temporary (runtime) DataSource data.\n     * This directory is deleted when VisualVM session finishes, eventually on\n     * new VisualVM session startup.\n     * \n     * @return default storage directory for temporary (runtime) DataSource data\n     */\n    public static File getTemporaryStorageDirectory() {\n        synchronized(temporaryStorageDirectoryLock) {\n            if (temporaryStorageDirectory == null) {\n                String temporaryStorageString = getTemporaryStorageDirectoryString();\n                temporaryStorageDirectory = new File(temporaryStorageString);\n                if (temporaryStorageDirectory.exists() && temporaryStorageDirectory.isFile())\n                    throw new IllegalStateException(\"Cannot create temporary storage directory \" + temporaryStorageString + \", file in the way\");   // NOI18N\n                if (temporaryStorageDirectory.exists() && (!temporaryStorageDirectory.canRead() || !temporaryStorageDirectory.canWrite()))\n                    throw new IllegalStateException(\"Cannot access temporary storage directory \" + temporaryStorageString + \", read&write permission required\");    // NOI18N\n                if (!Utils.prepareDirectory(temporaryStorageDirectory))\n                    throw new IllegalStateException(\"Cannot create temporary storage directory \" + temporaryStorageString); // NOI18N\n            }\n            return temporaryStorageDirectory;\n        }\n    }\n    \n    /**\n     * Returns default storage directory for persistent DataSource data\n     * \n     * @return default storage directory for persistent DataSource data\n     */\n    public static String getPersistentStorageDirectoryString() {\n        synchronized(persistentStorageDirectoryStringLock) {\n            if (persistentStorageDirectoryString == null)\n                persistentStorageDirectoryString = new File(System.getProperty(\"netbeans.user\")).getAbsolutePath() + File.separator + PERSISTENT_STORAGE_DIRNAME;   // NOI18N\n            return persistentStorageDirectoryString;\n        }\n    }\n    \n    /**\n     * Returns default storage directory for persistent DataSource data\n     * \n     * @return default storage directory for persistent DataSource data\n     */\n    public static File getPersistentStorageDirectory() {\n        synchronized(persistentStorageDirectoryLock) {\n            if (persistentStorageDirectory == null) {\n                String persistentStorageString = getPersistentStorageDirectoryString();\n                persistentStorageDirectory = new File(persistentStorageString);\n                if (persistentStorageDirectory.exists() && persistentStorageDirectory.isFile())\n                    throw new IllegalStateException(\"Cannot create persistent storage directory \" + persistentStorageString + \", file in the way\"); // NOI18N\n                if (persistentStorageDirectory.exists() && (!persistentStorageDirectory.canRead() || !persistentStorageDirectory.canWrite()))\n                    throw new IllegalStateException(\"Cannot access persistent storage directory \" + persistentStorageString + \", read&write permission required\");  // NOI18N\n                if (!Utils.prepareDirectory(persistentStorageDirectory))\n                    throw new IllegalStateException(\"Cannot create persistent storage directory \" + persistentStorageString);   // NOI18N\n            }\n            return persistentStorageDirectory;\n        }\n    }\n    \n    /**\n     * Returns true if persistent storage directory exists, false otherwise.\n     * @return true if persistent storage directory exists, false otherwise.\n     */\n    public static boolean persistentStorageDirectoryExists() {\n        return new File(getPersistentStorageDirectoryString()).isDirectory();\n    }\n    \n    \n    private void storeCustomProperties() {\n        if (properties != null && propertiesFile != null) storeProperties(properties, propertiesFile);\n    }\n    \n    private Properties getCustomProperties(boolean createEmpty) {\n        if (properties == null && propertiesFile != null) properties = loadProperties(propertiesFile);\n        if (properties == null && createEmpty) properties = new Properties();\n        return properties;\n    }\n    \n    \n    private static Properties loadProperties(File file) {\n        if (!file.exists() || !file.isFile()) return null;\n            \n        try (InputStream is = new FileInputStream(file);\n             BufferedInputStream bis = new BufferedInputStream(is)) {\n            Properties properties = new Properties();\n            properties.loadFromXML(bis);\n            return properties;\n        } catch (Exception e) {\n            LOGGER.log(Level.SEVERE, \"Error loading properties\", e);    // NOI18N\n            return null;\n        }\n    }\n    \n    private static void storeProperties(Properties properties, File file) {\n        Utils.prepareDirectory(file.getParentFile()); // Directories may not be created yet\n\n        try (OutputStream os = new FileOutputStream(file);\n             BufferedOutputStream bos = new BufferedOutputStream(os)) {\n            properties.storeToXML(bos, null);\n        } catch (Exception e) {\n            LOGGER.log(Level.SEVERE, \"Error storing properties\", e);    // NOI18N\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasource/descriptor/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nCAP_GeneralProperties=General\nDESCR_GeneralProperties=General information\nLBL_GeneralDescr=&Description\\:\n\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasource/descriptor/DataSourceDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.datasource.descriptor;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.core.model.Model;\nimport java.awt.Image;\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport java.util.Comparator;\n\n/**\n * DataSourceDescriptor defines runtime appearance of the DataSource in Applications window.\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic abstract class DataSourceDescriptor<X extends DataSource> extends Model implements Positionable {\n    \n    /**\n     * Named property for DataSource icon.\n     */\n    public static final String PROPERTY_ICON = \"prop_icon\"; // NOI18N\n    /**\n     * Named property for DataSource name.\n     */\n    public static final String PROPERTY_NAME = \"prop_name\"; // NOI18N\n    /**\n     * Named property for DataSource description.\n     */\n    public static final String PROPERTY_DESCRIPTION = \"prop_description\";   // NOI18N\n    /**\n     * Named property for DataSource position within its owner.\n     */\n    public static final String PROPERTY_PREFERRED_POSITION = \"prop_preferred_position\"; // NOI18N\n    /**\n     * Named property for comparator used to sort nested DataSources.\n     */\n    public static final String PROPERTY_CHILDREN_COMPARATOR = \"prop_children_comparator\"; // NOI18N\n    /**\n     * Named property for DataSource expansion policy.\n     */\n    public static final String PROPERTY_EXPANSION_POLICY = \"prop_expansion_policy\"; // NOI18N\n    /**\n     * Expansion policy - DataSource will never expand automatically.\n     */\n    public static final int EXPAND_NEVER = 0;\n    /**\n     * Expansion policy - DataSource will be automatically expanded when first child is added, not more than once.\n     */\n    public static final int EXPAND_ON_FIRST_CHILD = 1;\n    /**\n     * Expansion policy - DataSource will be automatically expanded whenever first child is added, for each first child.\n     */\n    public static final int EXPAND_ON_EACH_FIRST_CHILD = 2;\n    /**\n     * Expansion policy - DataSource will be automatically expanded whenever new child is added.\n     */\n    public static final int EXPAND_ON_EACH_NEW_CHILD = 3;\n    /**\n     * Expansion policy - DataSource will be automatically expanded whenever a child is added or removed.\n     */\n    public static final int EXPAND_ON_EACH_CHILD_CHANGE = 4;\n    \n    private X dataSource;\n    private Image icon;\n    private String name;\n    private String description;\n    private int preferredPosition;\n    private Comparator<DataSource> childrenComparator;\n    private int autoExpansionPolicy;\n    private final PropertyChangeSupport changeSupport;\n    \n    \n    /**\n     * Creates new instance of DataSourceDescriptor.\n     * \n     * @param dataSource DataSource described by the descriptor, cannot be null.\n     */\n    public DataSourceDescriptor(X dataSource) {\n        this(dataSource, dataSource != null ? dataSource.toString() : null, null, null, POSITION_AT_THE_END, EXPAND_ON_FIRST_CHILD);\n    }\n    \n    /**\n     * Creates new instance of DataSourceDescriptor.\n     * \n     * @param ds DataSource described by the descriptor, cannot be null.\n     * @param n DataSource name.\n     * @param desc DataSource description.\n     * @param ic DataSource icon.\n     * @param pos DataSource position.\n     * @param aep DataSource expansion policy.\n     * \n     * @throws NullPointerException if the provided DataSource is null.\n     */\n    public DataSourceDescriptor(X ds, String n, String desc, Image ic, int pos, int aep) {\n        if (ds == null) throw new NullPointerException(\"DataSource cannot be null\");\n        \n        dataSource = ds;\n        changeSupport = new PropertyChangeSupport(dataSource);\n        name = formatName(n); // NOTE: called after dataSource is set, should work fine in subclasses with overridden formatName()\n        description = desc;\n        icon = ic;\n        preferredPosition = pos;\n        autoExpansionPolicy = aep;\n    }\n    \n\n    /**\n     * Returns icon of the DataSource.\n     * \n     * @return icon of the DataSource.\n     */\n    public Image getIcon() {\n        return icon;\n    }\n    \n    /**\n     * Returns true if the DataSource can be renamed using the Rename action, false otherwise.\n     * \n     * @return true if the DataSource can be renamed using the Rename action, false otherwise.\n     */\n    public boolean supportsRename() {\n        return false;\n    }\n    \n    /**\n     * Sets DataSource name.\n     * \n     * @param newName DataSource name.\n     */\n    public void setName(String newName) {\n        setNameImpl(newName, PROPERTY_NAME);\n    }\n    \n    protected void setImplicitName(String newName, String propertyName) {\n        setNameImpl(newName, propertyName);\n    }\n    \n    private void setNameImpl(String newName, String propertyName) {\n        if (!supportsRename()) throw new UnsupportedOperationException(\"Rename not supported for this descriptor\"); // NOI18N\n        if (newName == null) throw new IllegalArgumentException(\"Name cannot be null\"); // NOI18N\n        String oldName = name;\n        name = formatName(newName);\n        if (propertyName != null) getDataSource().getStorage().setCustomProperty(propertyName, newName);\n        getChangeSupport().firePropertyChange(PROPERTY_NAME, oldName, getName());\n    }\n\n    /**\n     * Returns name of the DataSource.\n     * \n     * @return name of the DataSource.\n     */\n    public String getName() {\n        return name;\n    }\n    \n    /**\n     * Enables subclasses to process (format) the provided name of the DataSource.\n     * \n     * @param namePattern name of the DataSource to be processed (formatted)\n     * @return processed (formatted) name of the DataSource.\n     */\n    protected String formatName(String namePattern) {\n        return namePattern;\n    }\n    \n    /**\n     * Returns description of the DataSource.\n     * \n     * @return description of the DataSource.\n     */\n    public String getDescription() {\n        return description;\n    }\n\n    /**\n     * Returns preferred position of the DataSource.\n     * \n     * @return preferred position of the DataSource.\n     */\n    public int getPreferredPosition() {\n        return preferredPosition;\n    }\n\n    /**\n     * Returns comparator used to sort nested DataSources. If defined, it overrides\n     * the default sorting which uses DataSourceDescriptor.getPreferredPosition().\n     * Default implementation returns null.\n     *\n     * @return comparator used to sort nested DataSources or null\n     */\n    public Comparator<DataSource> getChildrenComparator() {\n        return childrenComparator;\n    }\n    \n    /**\n     * Returns expansion policy of the DataSource.\n     * \n     * @return expansion policy of the DataSource.\n     */\n    public int getAutoExpansionPolicy() {\n        return autoExpansionPolicy;\n    }\n\n    /**\n     * Returns true if the General properties section should be available for\n     * the DataSource, false otherwise.\n     *\n     * @return true if the General properties section should be available for\n     * the DataSource, false otherwise\n     */\n    public boolean providesProperties() {\n        return false;\n    }\n    \n    /**\n     * Add a PropertyChangeListener to the listener list.\n     * The listener is registered for all properties.\n     * The same listener object may be added more than once, and will be called\n     * as many times as it is added.\n     * If <code>listener</code> is null, no exception is thrown and no action\n     * is taken.\n     *\n     * @param listener  The PropertyChangeListener to be added\n     */\n    public final void addPropertyChangeListener(PropertyChangeListener listener) {\n        getChangeSupport().addPropertyChangeListener(listener);\n    }\n\n    /**\n     * Add a PropertyChangeListener for a specific property.  The listener\n     * will be invoked only when a call on firePropertyChange names that\n     * specific property.\n     * The same listener object may be added more than once.  For each\n     * property,  the listener will be invoked the number of times it was added\n     * for that property.\n     * If <code>propertyName</code> or <code>listener</code> is null, no\n     * exception is thrown and no action is taken.\n     *\n     * @param propertyName  The name of the property to listen on.\n     * @param listener  The PropertyChangeListener to be added\n     */\n    public final void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {\n        getChangeSupport().addPropertyChangeListener(propertyName, listener);\n    }\n\n    /**\n     * Remove a PropertyChangeListener from the listener list.\n     * This removes a PropertyChangeListener that was registered\n     * for all properties.\n     * If <code>listener</code> was added more than once to the same event\n     * source, it will be notified one less time after being removed.\n     * If <code>listener</code> is null, or was never added, no exception is\n     * thrown and no action is taken.\n     *\n     * @param listener  The PropertyChangeListener to be removed\n     */\n    public final void removePropertyChangeListener(PropertyChangeListener listener) {\n        getChangeSupport().removePropertyChangeListener(listener);\n    }\n\n    /**\n     * Remove a PropertyChangeListener for a specific property.\n     * If <code>listener</code> was added more than once to the same event\n     * source for the specified property, it will be notified one less time\n     * after being removed.\n     * If <code>propertyName</code> is null,  no exception is thrown and no\n     * action is taken.\n     * If <code>listener</code> is null, or was never added for the specified\n     * property, no exception is thrown and no action is taken.\n     *\n     * @param propertyName  The name of the property that was listened on.\n     * @param listener  The PropertyChangeListener to be removed\n     */\n    public final void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {\n        getChangeSupport().removePropertyChangeListener(propertyName, listener);\n    }\n    \n    \n    protected final X getDataSource() {\n        return dataSource;\n    }\n    \n    protected void setDescription(String newDescription) {\n        if (description == null && newDescription == null) return;\n        String oldDescription = description;\n        description = newDescription;\n        getChangeSupport().firePropertyChange(PROPERTY_DESCRIPTION, oldDescription, getDescription());\n    }\n    \n    protected void setIcon(Image newIcon) {\n        if (icon == null && newIcon == null) return;\n        Image oldIcon = icon;\n        icon = newIcon;\n        getChangeSupport().firePropertyChange(PROPERTY_ICON, oldIcon, getIcon());\n    }\n    \n    protected void setPreferredPosition(int newPosition) {\n        int oldPosition = preferredPosition;\n        preferredPosition = newPosition;\n        getChangeSupport().firePropertyChange(PROPERTY_PREFERRED_POSITION, oldPosition, getPreferredPosition());\n    }\n\n    /**\n     * Sets a custom comparator for sorting DataSources within a DataSource.\n     * Use setChildrenComparator(null) to restore the default sorting.\n     *\n     * @param newComparator comparator for sorting DataSources within a DataSource\n     */\n    protected void setChildrenComparator(Comparator<DataSource> newComparator) {\n        Comparator<DataSource> oldComparator = childrenComparator;\n        childrenComparator = newComparator;\n        getChangeSupport().firePropertyChange(PROPERTY_CHILDREN_COMPARATOR, oldComparator, getChildrenComparator());\n    }\n    \n    protected void getAutoExpansionPolicy(int newPolicy) {\n        int oldPolicy = autoExpansionPolicy;\n        autoExpansionPolicy = newPolicy;\n        getChangeSupport().firePropertyChange(PROPERTY_EXPANSION_POLICY, oldPolicy, getAutoExpansionPolicy());\n    }\n    \n    protected final PropertyChangeSupport getChangeSupport() {\n        return changeSupport;\n    }\n\n\n    /**\n     * Returns persisted DataSource name if available in DataSource Storage as\n     * PROPERTY_NAME. Otherwise returns the provided name.\n     *\n     * @param dataSource DataSource for which to resolve the name\n     * @param name name to be used if not available in DataSource Storage\n     * @return persisted DataSource name if available or the provided name\n     */\n    protected static String resolveName(DataSource dataSource, String name) {\n        String persistedName = dataSource.getStorage().getCustomProperty(PROPERTY_NAME);\n        if (persistedName != null) return persistedName;\n        else return name;\n    }\n\n    /**\n     * Returns persisted DataSource position if available in DataSource Storage\n     * as PROPERTY_PREFERRED_POSITION. Otherwise uses the provided position.\n     * Optionally saves the position to DataSource storage which also ensures that\n     * relative positions POSITION_AT_THE_END and POSITION_LAST will be correctly\n     * persisted.\n     *\n     * @param dataSource DataSource for which to resolve the position\n     * @param position position to be used if not available in DataSource Storage\n     * @param savePosition true when the position should be saved to DataSource's Storage\n     * @return persisted DataSource position if available or the provided position\n     */\n    protected static int resolvePosition(DataSource dataSource, int position,\n                                         boolean savePosition) {\n        Storage storage = dataSource.getStorage();\n        String positionS = storage.getCustomProperty(PROPERTY_PREFERRED_POSITION);\n        if (positionS != null) try {\n                position = Integer.parseInt(positionS);\n            } catch (NumberFormatException e) {\n                if (savePosition) storage.setCustomProperty(PROPERTY_PREFERRED_POSITION,\n                                                            Integer.toString(position));\n        } else {\n            if (savePosition) storage.setCustomProperty(PROPERTY_PREFERRED_POSITION,\n                                                        Integer.toString(position));\n        }\n        return position;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasource/descriptor/DataSourceDescriptorFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.datasource.descriptor;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.model.ModelFactory;\nimport org.graalvm.visualvm.core.model.ModelProvider;\nimport org.graalvm.visualvm.core.properties.PropertiesSupport;\n\n/**\n * ModelFactory for DataSourceDescriptors.\n *\n * @author Tomas Hurka\n */\npublic final class DataSourceDescriptorFactory extends ModelFactory<DataSourceDescriptor,DataSource> implements ModelProvider<DataSourceDescriptor,DataSource> {\n    \n    private static DataSourceDescriptorFactory dsDescFactory;\n    \n    private DataSourceDescriptorFactory() {\n    }\n    \n    /**\n     * Returns the singleton instance of DataSourceDescriptorFactory.\n     * \n     * @return singleton instance of DataSourceDescriptorFactory.\n     */\n    public static synchronized DataSourceDescriptorFactory getDefault() {\n        if (dsDescFactory == null) {\n            dsDescFactory = new DataSourceDescriptorFactory();\n            dsDescFactory.registerProvider(dsDescFactory);\n            // Register General properties tab support\n            PropertiesSupport.sharedInstance().registerPropertiesProvider(\n                new GeneralPropertiesProvider(), DataSource.class);\n        }\n        return dsDescFactory;\n    }\n    \n    /**\n     * Returns DataSourceDescriptor for given DataSource.\n     * Use this method to get for example a DataSource name or icon.\n     * \n     * @param ds DataSource for which to get the descriptor.\n     * @return DataSourceDescriptor for given DataSource.\n     */\n    public static <X extends DataSource> DataSourceDescriptor<X> getDescriptor(X ds) {\n        return getDefault().getModel(ds);\n    }\n    \n    /**\n     * Creates DataSourceDescriptor for given DataSource.\n     * This method is used by the ModelFactory framework, typically you need\n     * to use the DataSourceDescriptor.getDescriptor(DataSource) method to get\n     * properties of a DataSource.\n     * \n     * @param ds DataSource for which to create the descriptor.\n     * @return new DataSourceDescriptor for given DataSource.\n     */\n    public DataSourceDescriptor createModelFor(DataSource ds) {\n        return new DefaultDataSourceDescriptor(ds);\n    }\n    \n    private static class DefaultDataSourceDescriptor extends DataSourceDescriptor {\n        \n        DefaultDataSourceDescriptor(DataSource ds) {\n            super(ds);\n        }\n                \n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasource/descriptor/GeneralPropertiesProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.datasource.descriptor;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.properties.PropertiesPanel;\nimport org.graalvm.visualvm.core.properties.PropertiesProvider;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Image;\nimport java.awt.Insets;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextArea;\nimport javax.swing.JTextField;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass GeneralPropertiesProvider extends PropertiesProvider<DataSource> {\n\n    GeneralPropertiesProvider() {\n        super(NbBundle.getMessage(GeneralPropertiesProvider.class, \"CAP_GeneralProperties\"), // NOI18N\n              NbBundle.getMessage(GeneralPropertiesProvider.class, \"DESCR_GeneralProperties\"), // NOI18N\n              CATEGORY_GENERAL, Integer.MIN_VALUE);\n    }\n\n\n    public PropertiesPanel createPanel(DataSource dataSource) {\n        DataSourceDescriptor descriptor =\n                DataSourceDescriptorFactory.getDescriptor(dataSource);\n        \n        GridBagConstraints c;\n\n        PropertiesPanel panel = new PropertiesPanel();\n        panel.setLayout(new GridBagLayout());\n\n        Image icon = descriptor.getIcon();\n        if (icon == null) icon = ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/core/ui/resources/empty.png\"); // NOI18N\n        JButton iconButton = new JButton(new ImageIcon(icon));\n        iconButton.setDisabledIcon(iconButton.getIcon());\n        iconButton.setEnabled(false);\n        iconButton.setMargin(new Insets(3, 3, 3, 3));\n        Dimension size = iconButton.getPreferredSize();\n        size.width = Math.min(size.width, size.height);\n        size.height = size.width;\n        iconButton.setPreferredSize(size);\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(0, 0, 5, 8);\n        panel.add(iconButton, c);\n\n        JTextField nameField = new JTextField(descriptor.getName());\n        nameField.setEditable(false);\n        size = nameField.getPreferredSize();\n        size.width = 1;\n        nameField.setPreferredSize(size);\n        nameField.setMinimumSize(size);\n        nameField.setCaretPosition(0);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.weightx = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 5, 0);\n        panel.add(nameField, c);\n\n        JLabel descriptionLabel = new JLabel();\n        Mnemonics.setLocalizedText(descriptionLabel, NbBundle.getMessage(\n                GeneralPropertiesProvider.class, \"LBL_GeneralDescr\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(2, 0, 3, 0);\n        panel.add(descriptionLabel, c);\n\n        JTextArea descriptionArea = new JTextArea(descriptor.getDescription()) {\n            public Dimension getPreferredSize() {\n                Dimension size = super.getPreferredSize();\n                // Workaround for JDK7 where empty text seems to break preferredSize\n                if (\"\".equals(getText())) { // NOI18N\n                    size.width = 0;\n                    size.height = 0;\n                }\n                return size;\n            }\n        };\n        descriptionLabel.setLabelFor(descriptionArea);\n        descriptionArea.setEditable(false);\n        descriptionArea.setRows(4);\n        descriptionArea.setCaretPosition(0);\n        descriptionArea.setBackground(nameField.getBackground());\n        descriptionArea.setOpaque(true);\n        descriptionArea.setLineWrap(true);\n        descriptionArea.setWrapStyleWord(true);\n        JScrollPane descriptionScroll = new JScrollPane(descriptionArea,\n                                            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                                            JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n        size = descriptionScroll.getPreferredSize();\n        descriptionScroll.getViewport().setPreferredSize(size);\n        descriptionScroll.getViewport().setMinimumSize(size);\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 2;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 5, 0);\n        panel.add(descriptionScroll, c);\n\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 10;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(0, 0, 0, 0);\n        panel.add(Spacer.create(), c);\n        \n        return panel;\n    }\n\n\n    public boolean supportsDataSource(DataSource dataSource) {\n        return dataSource != null &&\n                DataSourceDescriptorFactory.getDescriptor(dataSource).providesProperties();\n    }\n\n    public void propertiesDefined(PropertiesPanel panel, DataSource dataSource) {}\n\n    public void propertiesChanged(PropertiesPanel panel, DataSource dataSource) {}\n\n    public void propertiesCancelled(PropertiesPanel panel, DataSource dataSource) {}\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasource/descriptor/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Definition of DataSourceDescriptor and related core APIs.\n */\npackage org.graalvm.visualvm.core.datasource.descriptor;\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasource/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Definition of DataSource and related core APIs.\n */\npackage org.graalvm.visualvm.core.datasource;\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasupport/AsyncPropertyChangeSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.datasupport;\n\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeSupport;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class AsyncPropertyChangeSupport extends PropertyChangeSupport {\n    private ExecutorService executor = Executors.newSingleThreadExecutor();\n\n    /**\n     * Constructs a AsyncPropertyChangeSupport object.\n     *\n     * @param sourceBean  The bean to be given as the source for any\n     *        events.\n     * @throws NullPointerException if {@code sourceBean} is\n     *         {@code null}\n     */\n    public AsyncPropertyChangeSupport(Object sourceBean) {\n        super(sourceBean);\n    }\n\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p>\n     * The listeners are notified asynchronously but the order of events\n     * is kept.\n     *\n     * @throws NullPointerException if {@code evt} is\n     *         {@code null}\n     */\n    @Override\n    public void firePropertyChange(final PropertyChangeEvent evt) {\n        if (evt == null) {\n            throw new NullPointerException();\n        }\n        if (getPropertyChangeListeners().length>0) {\n            executor.submit(new Runnable() {\n\n                public void run() {\n                    AsyncPropertyChangeSupport.super.firePropertyChange(evt);\n                }\n            });\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasupport/ClassNameComparator.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.datasupport;\n\nimport java.util.Comparator;\n\n/**\n * Comparator based on class names.\n *\n * @author Jiri Sedlacek\n */\npublic final class ClassNameComparator implements Comparator {\n    \n    /**\n     * Shared instance of ClassNameComparator.\n     */\n    public static final ClassNameComparator INSTANCE = new ClassNameComparator();\n\n    public int compare(Object o1, Object o2) {\n        return o1.getClass().getName().compareTo(o2.getClass().getName());\n    }\n    \n    private ClassNameComparator() {}\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasupport/ComparableWeakReference.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core.datasupport;\n\nimport java.lang.ref.ReferenceQueue;\nimport java.lang.ref.WeakReference;\nimport java.util.Objects;\n\n/**\n * WeakReference delegating hashCode() and equals(Object) methods to the referenced object.\n *\n * @author Jaroslav Bachorik\n */\npublic final class ComparableWeakReference<T> extends WeakReference<T> {\n\n    \n    /**\n     * Creates new instance of ComparableWeakReference that refers to the given object and is\n     * registered with the given queue.\n     *\n     * @param referent object the new weak reference will refer to\n     * @param q the queue with which the reference is to be registered,\n     *          or <tt>null</tt> if registration is not required\n     */\n    public ComparableWeakReference(T referent, ReferenceQueue<? super T> q) {\n        super(referent, q);\n    }\n\n    /**\n     * Creates new instance of ComparableWeakReference that refers to the given object.  The new\n     * reference is not registered with any queue.\n     *\n     * @param referent object the new weak reference will refer to\n     */\n    public ComparableWeakReference(T referent) {\n        super(referent);\n    }\n\n    public int hashCode() {\n        return this.get() != null ? this.get().hashCode() : 0;\n    }\n\n    public boolean equals(Object o) {\n        if (this.get() == null && o == null) {\n            return true;\n        }\n        if (o == null) {\n            return false;\n        }\n        if (!(o instanceof ComparableWeakReference)) {\n            return false;\n        }\n        return Objects.equals(get(), ((ComparableWeakReference) o).get());\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasupport/DataChangeEvent.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.datasupport;\n\nimport java.util.Collections;\nimport java.util.Set;\n\n\n/**\n * An event containing information about added, removed and actual items of a monitored repository.\n *\n * @author Tomas Hurka\n */\npublic final class DataChangeEvent<X> {\n\n    private Set<X> current;\n    private Set<X> added;\n    private Set<X> removed;\n\n\n    /**\n     * Creates new DataChangeEvent.\n     * \n     * @param current actual items of a monitored repository,\n     * @param added items recently added to a monitored repository,\n     * @param removed items recently removed from a monitored repository.\n     */\n    public DataChangeEvent(Set<X> current, Set<X> added, Set<X> removed) {\n        this.current = current == null ? Collections.emptySet() : current;\n        this.added = added == null ? Collections.emptySet() : added;\n        this.removed = removed == null ? Collections.emptySet() : removed;\n    }\n\n    /**\n     * Returns actual items of a monitored repository.\n     * \n     * @return actual items of a monitored repository.\n     */\n    public Set<X> getCurrent() {\n        return current;\n    }\n\n    /**\n     * Returns items recently added to a monitored repository,\n     * \n     * @return items recently added to a monitored repository,\n     */\n    public Set<X> getAdded() {\n        return added;\n    }\n\n    /**\n     * Returns items recently removed from a monitored repository.\n     * \n     * @return items recently removed from a monitored repository.\n     */\n    public Set<X> getRemoved() {\n        return removed;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasupport/DataChangeListener.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.datasupport;\n\n/**\n * A listener for receiving changes for a monitored data repository.\n *\n * @author Jiri Sedlacek\n */\npublic interface DataChangeListener<X> {\n\n    /**\n     * Invoked when items of the monitored repository changed.\n     * \n     * @param event event containing added, removed and actual items of monitored repository.\n     */\n    public void dataChanged(DataChangeEvent<X> event);\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasupport/DataChangeSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.datasupport;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport java.util.HashSet;\nimport java.util.Set;\n\n\n/**\n * This is a utility class that can be used by similarly\n * to PropertyChangeSupport. All DataChangeSupport instances \n * uses dedicated thread to for all the work, so all events \n * is processed asynchronously. \n *\n * @author Tomas Hurka\n */\npublic final class DataChangeSupport<X> {\n\n    private ChangeSupport<X> changeSupport;\n\n    /**\n     * Constructs a <code>DataChangeSupport</code> object.\n     */\n    public DataChangeSupport() {\n        changeSupport = new ChangeSupport();\n    }\n\n    /**\n     * Add a DataChangeListener to the listener list.\n     * The same listener object may be added only once.\n     *\n     * @param listener  The DataChangeListener to be added\n     */\n    public void addChangeListener(final DataChangeListener<X> listener) {\n        DataSource.EVENT_QUEUE.post(new Runnable() {\n            public void run() {\n                changeSupport.addChangeListener(listener);\n            }\n        });\n    }\n\n    /**\n     * Remove a DataChangeListener from the listener list.\n     *\n     * @param listener  The DataChangeListener to be removed\n     */\n    public void removeChangeListener(final DataChangeListener<X> listener) {\n        DataSource.EVENT_QUEUE.post(new Runnable() {\n            public void run() {\n                changeSupport.removeChangeListener(listener);\n            }\n        });\n    }\n    \n    /**\n     * Report an update to any registered listeners.\n     *\n     * @param current  the set of currently available objects.\n     * @param added  the set of added objects since last event.\n     * @param removed  the set of removed objects since last event.\n     */\n    public void fireChange(Set<X> current, Set<X> added, Set<X> removed) {\n        final Set<X> currentLocal = current != null ? new HashSet<>(current) : null;\n        final Set<X> addedLocal = added != null ? new HashSet<>(added) : null;\n        final Set<X> removedLocal = removed != null ? new HashSet<>(removed) : null;\n\n        DataSource.EVENT_QUEUE.post(new Runnable() {\n            public void run() {\n                changeSupport.fireChange(currentLocal, addedLocal, removedLocal);\n            }\n        });\n    }\n    \n    private static class ChangeSupport<X> {\n        \n        private Set<DataChangeListener<X>> listeners = new HashSet<>();\n        private Set<X> currentSet;\n        \n        private void addChangeListener(DataChangeListener<X> listener) {\n            if (!listeners.add(listener)) {\n                throw new IllegalArgumentException(\"Listener \" + listener + \" already registered\");     // NOI18N\n            }\n            if (currentSet != null) {\n                DataChangeEvent<X> event = new DataChangeEvent<>(currentSet, currentSet, null);\n                listener.dataChanged(event);\n            }\n        }\n        \n        private void removeChangeListener(DataChangeListener<X> listener) {\n            if (!listeners.remove(listener)) {\n                throw new IllegalArgumentException(\"Listener \" + listener + \" not registered\"); // NOI18N\n            }            \n        }\n        \n        private void fireChange(Set<X> current, Set<X> added, Set<X> removed) {\n            currentSet = current;\n            if (listeners.isEmpty()) {\n                return;\n            }\n            DataChangeEvent<X> event = new DataChangeEvent<>(current, added, removed);\n            for (DataChangeListener<X> listener : listeners) {\n                listener.dataChanged(event);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasupport/DataRemovedListener.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.datasupport;\n\n/**\n * A listener for one-time notifications that the data became finished.\n * After receiving a notification the listener is immediately removed from the list\n * of registered listeners.\n * Note that this listener is referenced by WeakReference in monitored DataSource -\n * be sure that the listener has at least one strong reference.\n *\n * @author Jiri Sedlacek\n */\npublic interface DataRemovedListener<X> {\n\n    /**\n     * Invoked only once when the monitored data became finished.\n     * \n     * @param dataSource item removed from the repository.\n     */\n    public void dataRemoved(X dataSource);\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasupport/Positionable.java",
    "content": "/*\n *  Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.datasupport;\n\nimport java.io.Serializable;\nimport java.util.Comparator;\n\n/**\n * Common interface for entities that can specify their position within other entities.\n *\n * @author Jiri Sedlacek\n */\npublic interface Positionable {\n    \n    /**\n     * Entity will be placed before first entity with POSITION_LAST position or at the current last position if there's no entity with POSITION_LAST position.\n     */\n    public static final int POSITION_AT_THE_END = Integer.MAX_VALUE - 1;\n    \n    /**\n     * Entity will be placed at the current last position.\n     */\n    public static final int POSITION_LAST = Integer.MAX_VALUE;\n    \n    /**\n     * Comparator based on <code>getPreferredPosition()</code> value.\n     * <code>COMPARATOR.compare(Positionable p1, Positionable p2)</code> returns\n     * <code>0</code> only if <code>p1.getPreferredPosition() == p2.getPreferredPosition</code>,\n     * not to be used as a comparator for <code>TreeSet</code> or <code>TreeMap</code>.\n     */\n    public static final Comparator<Positionable> COMPARATOR = new PositionableComparator();\n    \n    /**\n     * Comparator based on <code>getPreferredPosition()</code> value.\n     * <code>COMPARATOR.compare(Positionable p1, Positionable p2)</code> returns\n     * <code>0</code> only if <code>p1.equals(p2)</code>, safe to be used as a\n     * comparator for <code>TreeSet</code> or <code>TreeMap</code>.\n     */\n    public static final Comparator<Positionable> STRONG_COMPARATOR = new StrongPositionableComparator();\n    \n    /**\n     * Returns preferred position of this entity within other entities.\n     * \n     * @return preferred position of this entity within other entities.\n     */\n    public int getPreferredPosition();\n    \n    /**\n     * Implementation of Comparator based on <code>getPreferredPosition()</code> value.\n     * <code>PositionableComparator.compare(Positionable p1, Positionable p2)</code> returns\n     * <code>0</code> only if <code>p1.getPreferredPosition() == p2.getPreferredPosition</code>,\n     * not to be used as a comparator for <code>TreeSet</code> or <code>TreeMap</code>.\n     */\n    static final class PositionableComparator implements Comparator<Positionable>, Serializable {\n        \n        public int compare(Positionable p1, Positionable p2) {\n            int position1 = p1.getPreferredPosition();\n            int position2 = p2.getPreferredPosition();\n\n            return Integer.compare(position1, position2);\n        }\n        \n    }\n    \n    /**\n     * Implementation of Comparator based on <code>getPreferredPosition()</code> value.\n     * <code>StrongPositionableComparator.compare(Positionable p1, Positionable p2)</code>\n     * returns <code>0</code> only if <code>p1.equals(p2)</code>, safe to be used\n     * as a comparator for <code>TreeSet</code> or <code>TreeMap</code>.\n     */\n    static final class StrongPositionableComparator implements Comparator<Positionable>, Serializable {\n        \n        public int compare(Positionable p1, Positionable p2) {\n            int position1 = p1.getPreferredPosition();\n            int position2 = p2.getPreferredPosition();\n            \n            // Compare using getPreferredPosition()\n            if (position1 > position2) return 1;\n            else if (position1 < position2) return -1;\n            \n            // Make sure to return 0 for o1.equals(o2)\n            if (p1.equals(p2)) return 0;\n            \n            // Compare using classname\n            int result = ClassNameComparator.INSTANCE.compare(p1, p2);\n            if (result != 0) return result;\n            \n            // Compare using System.identityHashCode(o)\n            result = Integer.compare(System.identityHashCode(p1), System.identityHashCode(p2));\n            if (result != 0) return result;\n            \n            // Compare using o.hashCode()\n            result = Integer.compare(p1.hashCode(), p2.hashCode());\n            if (result != 0) return result;\n            \n            // Give up, pretend that second number is greater\n            return -1;\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasupport/Stateful.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.datasupport;\n\nimport java.beans.PropertyChangeListener;\n\n/**\n * Common interface for entities that can specify their state.\n *\n * @author Jiri Sedlacek\n */\npublic interface Stateful {\n    \n    /**\n     * Named property for state.\n     */\n    public static final String PROPERTY_STATE = \"prop_state\";   // NOI18N\n    \n    /**\n     * State cannot be determined.\n     */\n    public static final int STATE_UNKNOWN = -1;\n    /**\n     * State is Unavailable.\n     */\n    public static final int STATE_UNAVAILABLE = 0;\n    /**\n     * State is Available.\n     */\n    public static final int STATE_AVAILABLE = 1;\n    \n    \n    /**\n     * Returns current state of an entity.\n     * \n     * @return current state an entity.\n     */\n    public int getState();\n    \n    public int getModCount();\n    \n    /**\n     * Add a PropertyChangeListener to the listener list.\n     * The listener is registered for all properties.\n     * The same listener object may be added more than once, and will be called\n     * as many times as it is added.\n     * If <code>listener</code> is null, no exception is thrown and no action\n     * is taken.\n     *\n     * @param listener  The PropertyChangeListener to be added\n     */\n    public void addPropertyChangeListener(PropertyChangeListener listener);\n    \n    /**\n     * Add a PropertyChangeListener for a specific property.  The listener\n     * will be invoked only when a call on firePropertyChange names that\n     * specific property.\n     * The same listener object may be added more than once.  For each\n     * property,  the listener will be invoked the number of times it was added\n     * for that property.\n     * If <code>propertyName</code> or <code>listener</code> is null, no\n     * exception is thrown and no action is taken.\n     *\n     * @param propertyName  The name of the property to listen on.\n     * @param listener  The PropertyChangeListener to be added\n     */\n    public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener);\n    \n    /**\n     * Remove a PropertyChangeListener from the listener list.\n     * This removes a PropertyChangeListener that was registered\n     * for all properties.\n     * If <code>listener</code> was added more than once to the same event\n     * source, it will be notified one less time after being removed.\n     * If <code>listener</code> is null, or was never added, no exception is\n     * thrown and no action is taken.\n     *\n     * @param listener  The PropertyChangeListener to be removed\n     */\n    public void removePropertyChangeListener(PropertyChangeListener listener);\n    \n    /**\n     * Remove a PropertyChangeListener for a specific property.\n     * If <code>listener</code> was added more than once to the same event\n     * source for the specified property, it will be notified one less time\n     * after being removed.\n     * If <code>propertyName</code> is null,  no exception is thrown and no\n     * action is taken.\n     * If <code>listener</code> is null, or was never added for the specified\n     * property, no exception is thrown and no action is taken.\n     *\n     * @param propertyName  The name of the property that was listened on.\n     * @param listener  The PropertyChangeListener to be removed\n     */\n    public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasupport/Utils.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.datasupport;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport java.awt.Image;\nimport java.awt.Toolkit;\nimport java.awt.image.BufferedImage;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Base64;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\nimport java.util.zip.ZipOutputStream;\nimport javax.imageio.ImageIO;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.Utilities;\n\n/**\n * Utils class encapsulating various helper methods.\n *\n * @author Jiri Sedlacek\n */\npublic final class Utils {\n    \n    /**\n     * Shared RequestProcessor to be used for file operations that need to be synchronized.\n     */\n    public static final RequestProcessor FILE_QUEUE = new RequestProcessor(\"File Queue\");   // NOI18N\n    \n    private static final int COPY_PACKET_SIZE = 16384;\n    private static final Logger LOGGER = Logger.getLogger(Utils.class.getName());\n\n    /**\n     * Returns true if given set contains at least one subclass of provided instance.\n     * \n     * @param <X>\n     * @param <Y>\n     * @param classes Set of classes that will be searched.\n     * @param superclassInstance instance to be searched.\n     * @return true if given set contains at least one subclass of provided instance, false otherwise.\n     */\n    public static <X, Y> boolean containsSubclass(Set<? extends Class<? extends Y>> classes, X superclassInstance) {\n        for (Class<? extends Y> classs : classes) if (classs.isInstance(superclassInstance)) return true;\n        return false;\n    }\n\n    /**\n     * Returns true if given set contains at least one superclass of provided instance.\n     * \n     * @param <X>\n     * @param <Y>\n     * @param classes Set of classes that will be searched.\n     * @param subclassInstance instance to be searched.\n     * @return true if given set contains at least one superclass of provided instance, false otherwise.\n     */\n    public static <X, Y> boolean containsSuperclass(Set<? extends Class<? extends Y>> classes, X subclassInstance) {\n        Class<?> subclass = subclassInstance.getClass();\n        for (Class<? extends Y> classs : classes) if (classs.isAssignableFrom(subclass)) return true;\n        return false;\n    }\n\n    /**\n     * Returns filtered set containing only instances of the given class.\n     * \n     * @param <X>\n     * @param <Y>\n     * @param <Z>\n     * @param set Set to be filtered.\n     * @param filter Class defining the filter.\n     * @return filtered set containing only instances of the given class.\n     */\n    public static <X, Y extends X, Z extends X> Set<Z> getFilteredSet(Set<Y> set, Class<Z> filter) {\n        Set<Z> filteredSet = new HashSet<>();\n        for (Y item : set) if (filter.isInstance(item)) filteredSet.add((Z)item);\n        return filteredSet;\n    }\n    \n    /**\n     * Returns list of given DataSources sorted by distance from DataSource.ROOT.\n     * \n     * @param <X> any DataSource.\n     * @param dataSources DataSources to be sorted.\n     * @return list of given DataSources sorted by distance from DataSource.ROOT.\n     */\n    public static <X extends DataSource> List<X> getSortedDataSources(Set<X> dataSources) {\n        List<DataSourcePath<X>> dataSourcePaths = getSortedDataSourcePaths(dataSources);\n        List<X> sortedDataSources = new ArrayList<>();\n        \n        for (DataSourcePath<X> dataSourcePath : dataSourcePaths)\n            sortedDataSources.add(dataSourcePath.getDataSource());\n        \n        return sortedDataSources;\n    }\n    \n    /**\n     * Returns true if provided DataSources are independent. Independent means that no DataSource\n     * is (super)owner of any other DataSource.\n     * \n     * @param <X> any DataSource.\n     * @param dataSources DataSources to be checked.\n     * @return true if provided DataSources are independent, false otherwise.\n     */\n    public static <X extends DataSource> boolean areDataSourcesIndependent(Set<X> dataSources) {\n        return dataSources.size() == getIndependentDataSources(dataSources).size();\n    }\n    \n    /**\n     * Returns Set of independent DataSources. Independent means that no DataSource\n     * is (super)owner of any other DataSource - this means that (sub)children are removed.\n     * \n     * @param <X> any DataSource.\n     * @param dataSources DataSources to be filtered.\n     * @return Set of independent DataSources.\n     */\n    public static <X extends DataSource> Set<X> getIndependentDataSources(Set<X> dataSources) {\n        Map<Integer, Set<X>> independentDataSourcesMap = new HashMap<>();\n        List<DataSourcePath<X>> dataSourcePaths = getSortedDataSourcePaths(dataSources);\n        \n        for (DataSourcePath<X> dataSourcePath : dataSourcePaths) {\n            boolean independent = true;\n            for (int i = 0; i < dataSourcePath.size(); i++) {\n                DataSource dataSource = dataSourcePath.get(i);\n                Set<X> set = independentDataSourcesMap.get(i);\n                if (set != null && set.contains(dataSource)) {\n                    independent = false;\n                    break;\n                }\n            }\n            \n            if (independent) {\n                Set<X> set = independentDataSourcesMap.get(dataSourcePath.size() - 1);\n                if (set == null) {\n                    set = new HashSet<>();\n                    independentDataSourcesMap.put(dataSourcePath.size() - 1, set);\n                }\n                set.add(dataSourcePath.getDataSource());\n            }\n        }\n        \n        Set<X> independentDataSources = new HashSet<>();\n        Collection<Set<X>> independentSetsCollection = independentDataSourcesMap.values();\n        for (Set<X> independentSet : independentSetsCollection)\n            independentDataSources.addAll(independentSet);\n        return independentDataSources;\n    }\n    \n    private static <X extends DataSource> List<DataSourcePath<X>> getSortedDataSourcePaths(Set<X> dataSources) {\n        List<DataSourcePath<X>> dataSourcePaths = new ArrayList<>();\n        for (DataSource dataSource : dataSources) dataSourcePaths.add(new DataSourcePath(dataSource));\n        Collections.sort(dataSourcePaths);\n        return dataSourcePaths;\n    }\n    \n    private static class DataSourcePath<X extends DataSource> extends ArrayList<DataSource> implements Comparable<DataSourcePath> {\n        \n        DataSourcePath(X dataSource) {\n            super();\n            DataSource ds = dataSource;\n            while(ds != null) {\n                add(0, ds);\n                ds = ds.getOwner();\n            }\n        }\n\n        public int compareTo(DataSourcePath dataSourcePath) {\n            int thisSize = size();\n            return Integer.compare(thisSize, dataSourcePath.size());\n        }\n        \n        public X getDataSource() {\n            return (X)get(size() - 1);\n        }\n        \n    }\n    \n    \n    /**\n     * Returns filename without extension.\n     * \n     * @param fileName file name.\n     * @return filename without extension.\n     */\n    public static String getFileBase(String fileName) {\n        int extIndex = fileName.lastIndexOf('.'); // NOI18N\n        if (extIndex == -1) return fileName;\n        return fileName.substring(0, extIndex);\n    }\n    \n    /**\n     * Returns file extension.\n     * \n     * @param fileName file name.\n     * @return file extension.\n     */\n    public static String getFileExt(String fileName) {\n        int extIndex = fileName.lastIndexOf('.'); // NOI18N\n        if (extIndex == -1) return \"\"; // NOI18N\n        return fileName.substring(extIndex);\n    }\n    \n    /**\n     * Returns new File in provided directory based on the given filename.\n     * NOTE: the query is synchronized, however creating a new file has to be synchronized in custom code\n     * \n     * @param directory directory in which to create the file.\n     * @param file preferred filename.\n     * @return new File in provided directory based on the given filename.\n     */\n    public static File getUniqueFile(File directory, String file) {\n        return getUniqueFile(directory, getFileBase(file), getFileExt(file));\n    }\n    \n    /**\n     * Returns new File in provided directory based on the given filename.\n     * NOTE: the query is synchronized, however creating a new file has to be synchronized in custom code\n     * \n     * @param directory directory in which to create the file.\n     * @param fileName file name.\n     * @param fileExt file extension.\n     * @return new File in provided directory based on the given filename.\n     */\n    public synchronized static File getUniqueFile(File directory, String fileName, String fileExt) {\n        File newFile = new File(directory, fileName + fileExt);\n        while (newFile.exists()) {\n            fileName = fileName + \"_\"; // NOI18N\n            newFile = new File(directory, fileName + fileExt);\n        }\n        return newFile;\n    }\n    \n    /**\n     * Tries to create the directory incl. all super directories, returns true if at the end of the operation the directory exists.\n     * \n     * @param directory directory to be created.\n     * @return true if the directory exists, false otherwise.\n     */\n    public static synchronized boolean prepareDirectory(File directory) {\n        if (directory.exists()) return true;\n        directory.mkdirs();\n        return directory.exists();\n    }\n    \n    /**\n     * Copies source file to the destination file, returns true if the file was successfully copied.\n     * \n     * @param file source file.\n     * @param copy destination file.\n     * @return true if the file was successfully copied, false otherwise.\n     */\n    public static boolean copyFile(File file, File copy) {\n        if (file == null || copy == null) throw new NullPointerException(\"File cannot be null\");    // NOI18N\n        if (!file.isFile() || copy.isDirectory()) throw new IllegalArgumentException(\"Not a valid file\");   // NOI18N       \n        \n        try (FileInputStream fis = new FileInputStream(file);\n             FileOutputStream fos = new FileOutputStream(copy)) {\n            \n            int bytes;\n            byte[] packet = new byte[COPY_PACKET_SIZE];\n            while ((bytes = fis.read(packet, 0, COPY_PACKET_SIZE)) != -1) fos.write(packet, 0, bytes);\n            return true;\n        } catch (Exception e) {\n            LOGGER.log(Level.SEVERE, \"Error copying file\", e);  // NOI18N\n            return false;\n        }\n    }\n    \n    \n    /**\n     * Deletes file or folder.\n     * Optionally invokes deleteOnExit if necessary.\n     * \n     * @param file file or folder to be deleted.\n     * @param deleteOnExit true if deleteOnExit should be invoked on not deleted file or directory.\n     * @return true if the file or folder has been completely deleted, false otherwise.\n     */\n    public static boolean delete(File file, boolean deleteOnExit) {\n        \n        if (file == null) throw new NullPointerException(\"File cannot be null\");    // NOI18N\n        if (!file.exists()) return true;\n        \n        if (file.isDirectory()) {\n            File[] files = file.listFiles();\n            for (File file1 : files) {\n                delete(file1, deleteOnExit);\n            }\n        }\n\n        if (!file.delete()) {\n            if (Utilities.isWindows() && file.isFile()) {\n                for (int i = 0; i < 5; i++) {\n                    System.gc();\n                    if (file.delete()) return true;\n                }\n            }\n            if (deleteOnExit) file.deleteOnExit();\n            return false;\n        }\n        \n        return true;\n        \n    }\n    \n    /**\n     * Creates a zip archive of the given directory. Currently doesn't support\n     * archiving subdirectories (only files are added to the archive).\n     * \n     * @param directory directory to be archived.\n     * @param archive archive file.\n     */\n    public static void createArchive(File directory, File archive) {\n        File[] contents = directory.listFiles();\n        \n        try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(archive))) {\n            for (File file : contents) {\n                if (file.isFile()) {\n                    zos.putNextEntry(new ZipEntry(file.getName()));\n                    try (FileInputStream fis = new FileInputStream(file)) {\n                        int bytes;\n                        byte[] packet = new byte[COPY_PACKET_SIZE];\n                        while ((bytes = fis.read(packet, 0, COPY_PACKET_SIZE)) != -1) zos.write(packet, 0, bytes);\n                    } finally {\n                        if (zos != null) zos.closeEntry();\n                    }\n                } else {\n                    // TODO: process directory\n                }\n            }\n        } catch (Exception e) {\n            LOGGER.log(Level.SEVERE, \"Error creating archive\", e);  // NOI18N\n        }\n    }\n    \n    /**\n     * Extracts given zip archive, returns extracted directory. Currently doesn't support extracting subdirectories,\n     * (only extracts toplevel files).\n     * \n     * @param archive archive to be extracted.\n     * @param destination destination directory.\n     * @return extracted directory or null if extracting the archive failed.\n     */\n    public static File extractArchive(File archive, File destination) {\n        // TODO: implement extracting directories\n        \n        File directory = getUniqueFile(destination, archive.getName());\n        \n        try (ZipFile zipFile = new ZipFile(archive)) {\n            String destinationPath = directory.getCanonicalPath();\n            prepareDirectory(directory);\n            \n            Enumeration<? extends ZipEntry> entries = zipFile.entries();\n            while (entries.hasMoreElements()) {\n                ZipEntry entry = entries.nextElement();\n                File entryFile = new File(directory, entry.getName());\n                \n                String entryFilePath = entryFile.getCanonicalPath();\n                if (!entryFilePath.startsWith(destinationPath))\n                    throw new IllegalStateException(\"Archive entry outside of destination directory: \" + entryFilePath); // NOI18N\n                \n                try (FileOutputStream fos = new FileOutputStream(entryFile);\n                     InputStream is = zipFile.getInputStream(entry)) {\n                    int bytes;\n                    byte[] packet = new byte[COPY_PACKET_SIZE];\n                    while ((bytes = is.read(packet, 0, COPY_PACKET_SIZE)) != -1) fos.write(packet, 0, bytes);\n                }\n            }\n        } catch (Exception e) {\n            LOGGER.log(Level.SEVERE, \"Error extracting archive\", e);    // NOI18N\n            return null;\n        }\n        \n        return directory;\n    }\n    \n    /**\n     * Encodes given string using the Base64 encoding.\n     * \n     * @param value String to be encoded.\n     * @return encoded String.\n     */\n    public static String encodePassword(String value) {\n        return Base64.getEncoder().encodeToString(value.getBytes());\n    }\n    \n    /**\n     * Encodes given char[] using the Base64 encoding. The original parameter value is overwritten.\n     * \n     * @param value char[] to be encoded.\n     * @return encoded char[].\n     */\n    public static char[] encodePassword(char[] value) {\n        byte[] bytes = charsToBytes(value);\n        Arrays.fill(value, (char)0);\n        \n        byte[] bytes2 = Base64.getEncoder().encode(bytes);\n        Arrays.fill(bytes, (byte)0);\n        \n        char[] chars = bytesToChars(bytes2);\n        Arrays.fill(bytes2, (byte)0);\n        \n        return chars;\n    }\n    \n    /**\n     * Decodes given string using the Base64 encoding.\n     * \n     * @param value String to be decoded.\n     * @return decoded String.\n     */\n    public static String decodePassword(String value) {\n        return new String(Base64.getDecoder().decode(value));\n    }\n    \n    /**\n     * Decodes given char[] using the Base64 encoding. The original parameter value is overwritten.\n     * \n     * @param value char[] to be decoded.\n     * @return decoded char[].\n     */\n    public static char[] decodePassword(char[] value) {\n        byte[] bytes = charsToBytes(value);\n        Arrays.fill(value, (char)0);\n        \n        byte[] bytes2 = Base64.getDecoder().decode(bytes);\n        Arrays.fill(bytes, (byte)0);\n        \n        char[] chars = bytesToChars(bytes2);\n        Arrays.fill(bytes2, (byte)0);\n        \n        return chars;\n    }\n    \n    /**\n     * Encodes given image to String using the Base64 encoding.\n     * This is primarily intended to store small images (icons)\n     * in text (properties) files, no compression algorithms are\n     * used.\n     * \n     * @param image Image to be encoded.\n     * @param format image format.\n     * @return String containing the encoded image.\n     */\n    public static String imageToString(Image image, String format) {\n        byte[] imageBytes = imageToBytes(image, format);\n        return imageBytes != null ? Base64.getEncoder().encodeToString(imageBytes) : null;\n    }\n    \n    /**\n     * Decodes an image encoded by imageToString(Image, String) method.\n     * \n     * @param string String to be decoded.\n     * @return decoded Image.\n     */\n    public static Image stringToImage(String string) {\n        return Toolkit.getDefaultToolkit().createImage(Base64.getDecoder().decode(string));\n    }\n    \n    private static BufferedImage imageToBuffered(Image image) {\n        if (image instanceof BufferedImage) return (BufferedImage)image;\n        \n        BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);\n        bufferedImage.createGraphics().drawImage(image, null, null);\n        return bufferedImage;\n    }\n    \n    private static byte[] imageToBytes(Image image, String format) {\n        BufferedImage bufferedImage = imageToBuffered(image);\n        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();\n        \n        try {\n            ImageIO.write(bufferedImage, format, outputStream);\n        } catch (Exception e) {\n            LOGGER.log(Level.WARNING, Utils.class.getName() + \"imageToBytes\", e);  // NOI18N\n            return null;\n        }\n        \n        return outputStream.toByteArray();\n    }\n    \n    private static byte[] charsToBytes(char[] chars) {\n        byte[] bytes = new byte[chars.length * 2];\n        for (int i = 0; i < chars.length; i++) {\n            bytes[i * 2] = (byte)((chars[i] & 0xff00) >> 8);\n            bytes[i * 2 + 1] = (byte)(chars[i] & 0x00ff);\n        }\n        return bytes;\n    }\n    \n    private static char[] bytesToChars(byte[] bytes) {\n        char[] chars = new char[bytes.length / 2];\n        for (int i = 0; i < chars.length; i++) {\n            char ch = (char)(((bytes[i * 2] & 0x00ff) << 8) +\n                              (bytes[i * 2 + 1] & 0x00ff));\n            chars[i] = ch;\n        }\n        return chars;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/datasupport/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Various helper methods and interfaces for manipulations with DataSources.\n */\npackage org.graalvm.visualvm.core.datasupport;\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nCTL_ExplorerTopComponentAction=&Applications\n\nLBL_Applications=Applications\n\nLBL_Computing_description=Computing description...\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/DataSourcesComparator.java",
    "content": "/*\n *  Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.explorer;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport java.util.Comparator;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class DataSourcesComparator implements Comparator<DataSource> {\n\n    public int compare(DataSource d1, DataSource d2) {\n        DataSourceDescriptor dd1 = DataSourceDescriptorFactory.getDescriptor(d1);\n        DataSourceDescriptor dd2 = DataSourceDescriptorFactory.getDescriptor(d2);\n\n        int p1 = dd1.getPreferredPosition();\n        int p2 = dd2.getPreferredPosition();\n\n        if (p1 == Positionable.POSITION_AT_THE_END &&\n            p2 == Positionable.POSITION_AT_THE_END) {\n            p1 = getRelativePosition(d1, Positionable.POSITION_AT_THE_END);\n            p2 = getRelativePosition(d2, Positionable.POSITION_AT_THE_END);\n        } else if (p1 == Positionable.POSITION_LAST &&\n                   p2 == Positionable.POSITION_LAST) {\n            p1 = getRelativePosition(d1, Positionable.POSITION_LAST);\n            p2 = getRelativePosition(d2, Positionable.POSITION_LAST);\n        }\n\n        int result = doCompare(p1, p2);\n        if (result == 0) result = dd1.getName().compareTo(dd2.getName());\n        return result;\n    }\n\n    protected abstract int getRelativePosition(DataSource d, int positionType);\n\n    private int doCompare(int i1, int i2) {\n        return Integer.compare(i1, i2);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/ExplorerComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n\npackage org.graalvm.visualvm.core.explorer;\n\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.Window;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyAdapter;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.WindowEvent;\nimport java.awt.event.WindowFocusListener;\nimport java.util.Set;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTree;\nimport javax.swing.KeyStroke;\nimport javax.swing.ScrollPaneConstants;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.TreeExpansionEvent;\nimport javax.swing.event.TreeWillExpandListener;\nimport javax.swing.tree.ExpandVetoException;\nimport javax.swing.tree.TreePath;\nimport javax.swing.tree.TreeSelectionModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ExplorerComponent extends JPanel {\n\n    private static final Color MAC_TREE_BG_FOCUSED = new Color(214, 221, 229);\n    private static final Color MAC_TREE_BG_NOTFOCUSED = new Color(232, 232, 232);\n    \n    private static ExplorerComponent instance;\n    \n    private JTree explorerTree;\n    private boolean vetoTreeExpansion = false;\n    \n    \n    public static synchronized ExplorerComponent instance() {\n        if (instance == null) instance = new ExplorerComponent();\n        return instance;\n    }\n    \n    private ExplorerComponent() {\n        initComponents();\n    }\n    \n    public JTree getTree() {\n        return explorerTree;\n    }\n\n\n    public boolean requestFocusInWindow() {\n        if (explorerTree != null) return explorerTree.requestFocusInWindow();\n        else return super.requestFocusInWindow();\n    }\n    \n    \n    private void initComponents() {\n        setLayout(new BorderLayout());\n        \n        // explorerTree\n        explorerTree = new JTree(ExplorerModelBuilder.getInstance().getModel()) {\n            protected void processMouseEvent(MouseEvent e) {\n                vetoTreeExpansion = false;\n                if (e.getModifiers() == InputEvent.BUTTON1_MASK && e.getClickCount() >= getToggleClickCount()) {\n                    Set<DataSource> selectedDataSources = ExplorerSupport.sharedInstance().getSelectedDataSources();\n                    if (getDefaultAction(selectedDataSources) != null) vetoTreeExpansion = true;\n                }\n                super.processMouseEvent(e);\n            }\n            public void updateUI() {\n                super.updateUI();\n                setCellRenderer(new ExplorerNodeRenderer());\n            }\n            public void addNotify() {\n                if (UISupport.isAquaLookAndFeel()) setWindow();\n                super.addNotify();\n            }\n            public void removeNotify() {\n                if (UISupport.isAquaLookAndFeel()) resetWindow();\n                super.removeNotify();\n            }\n            private Window window;\n            private WindowFocusListener focusListener;\n            private void setWindow() {\n                window = SwingUtilities.getWindowAncestor(this);\n                if (window != null) {\n                    if (focusListener == null) focusListener = new WindowFocusListener() {\n                        public void windowGainedFocus(WindowEvent e) { repaint(); }\n                        public void windowLostFocus(WindowEvent e)   { repaint(); }\n                    };\n                    window.addWindowFocusListener(focusListener);\n                }\n            }\n            private void resetWindow() {\n                if (window != null && focusListener != null) {\n                    window.removeWindowFocusListener(focusListener);\n                    window = null;\n                }\n            }\n            public Color getBackground() {\n                if (!UISupport.isAquaLookAndFeel()) return super.getBackground();\n                return KeyboardFocusManager.getCurrentKeyboardFocusManager().\n                        getFocusedWindow() == window ? MAC_TREE_BG_FOCUSED :\n                                                       MAC_TREE_BG_NOTFOCUSED;\n            }\n        };\n        explorerTree.setRootVisible(false);\n        explorerTree.setShowsRootHandles(true);\n        explorerTree.setRowHeight(getTreeRowHeight());\n        explorerTree.setCellRenderer(new ExplorerNodeRenderer());\n        explorerTree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);\n        explorerTree.addKeyListener(new ExplorerTreeKeyAdapter());\n        explorerTree.addMouseListener(new ExplorerTreeMouseAdapter());\n        \n        // explorerTreeScrollPane\n        JScrollPane explorerTreeScrollPane = new JScrollPane(explorerTree, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n        explorerTreeScrollPane.setBorder(BorderFactory.createEmptyBorder());\n        explorerTreeScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());\n        \n        // Keyboard actions definition\n        String DEFAULT_ACTION_KEY = \"DEFAULT_ACTION\"; // NOI18N\n        getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), DEFAULT_ACTION_KEY); // NOI18N\n        getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), DEFAULT_ACTION_KEY); // NOI18N\n        getActionMap().put(DEFAULT_ACTION_KEY, new AbstractAction() { public void actionPerformed(ActionEvent e) { performDefaultAction(); }}); // NOI18N\n        \n        // Control tree expansion\n        explorerTree.addTreeWillExpandListener(new TreeWillExpandListener() {\n            public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {\n                if (!vetoTreeExpansion) return;\n                vetoTreeExpansion = false;\n                throw new ExpandVetoException(event);\n            }\n            public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {\n                if (!vetoTreeExpansion) return;\n                vetoTreeExpansion = false;\n                throw new ExpandVetoException(event);\n            }\n        });\n        \n        add(explorerTreeScrollPane, BorderLayout.CENTER);\n    }\n    \n    private static int getTreeRowHeight() {\n//        // NOTE: At least on GTK this returns -1\n//        int rowHeight = UIManager.getInt(\"Tree.rowHeight\");\n//        if (rowHeight != -1) return rowHeight + 2; else \n        return new JLabel(\"XXX\").getPreferredSize().height + 4; // NOI18N\n    }\n    \n    \n    private static Action getDefaultAction(Set<DataSource> dataSources) {\n        return ExplorerContextMenuFactory.instance().getDefaultActionFor(dataSources);\n    }\n    \n    private void performDefaultAction() {\n        Set<DataSource> selectedDataSources = ExplorerSupport.sharedInstance().getSelectedDataSources();\n        Action defaultAction = getDefaultAction(selectedDataSources);\n        if (defaultAction != null) defaultAction.actionPerformed(new ActionEvent(selectedDataSources, 0, \"Default Action\"));    // NOI18N\n    }\n    \n    private void displayContextMenu(int x, int y) {\n        JPopupMenu popupMenu = ExplorerContextMenuFactory.instance().createPopupMenu();\n        if (popupMenu != null) popupMenu.show(explorerTree, x, y);\n    }\n    \n    private class ExplorerTreeKeyAdapter extends KeyAdapter {\n        public void keyPressed(KeyEvent e) {\n            if ((e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU)\n                            || ((e.getKeyCode() == KeyEvent.VK_F10) && (e.getModifiers() == InputEvent.SHIFT_MASK))) {\n                \n                e.consume();\n                \n                int x;\n                int y;\n                TreePath path = explorerTree.getSelectionPath();\n                \n                if (path != null) {\n                    Rectangle pathRect = explorerTree.getPathBounds(path);\n                    x = pathRect.x;\n                    y = pathRect.y;\n                } else {\n                    Point pathPoint = new Point(explorerTree.getWidth() / 3, explorerTree.getHeight() / 3);\n                    x = pathPoint.x;\n                    y = pathPoint.y;\n                }\n                \n                displayContextMenu(x, y);\n            }\n        }\n    }\n    \n    private class ExplorerTreeMouseAdapter extends MouseAdapter {\n        private void updatePathSelection(TreePath path, MouseEvent e) {\n            if (path != null) {\n                if (!explorerTree.isPathSelected(path))\n                    explorerTree.setSelectionPath(path);\n            } else {\n                explorerTree.clearSelection();\n            }\n        }\n\n        public void mousePressed(MouseEvent e) {\n            TreePath path = explorerTree.getPathForLocation(e.getX(), e.getY());\n            updatePathSelection(path, e);\n            if (e.isPopupTrigger()) displayContextMenu(e.getX(), e.getY());\n        }\n        \n        public void mouseReleased(MouseEvent e) {\n            TreePath path = explorerTree.getPathForLocation(e.getX(), e.getY());\n            updatePathSelection(path, e);\n            if (e.isPopupTrigger()) displayContextMenu(e.getX(), e.getY());\n        }\n    \n        public void mouseClicked(MouseEvent e) {\n            if (SwingUtilities.isLeftMouseButton(e) &&\n                    e.getClickCount() == explorerTree.getToggleClickCount()) {\n                performDefaultAction();\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/ExplorerContextMenuFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.explorer;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport java.awt.Font;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.Action;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JSeparator;\nimport org.openide.awt.Mnemonics;\nimport org.openide.cookies.InstanceCookie;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.loaders.DataFolder;\nimport org.openide.loaders.DataObject;\nimport org.openide.util.actions.Presenter;\n\n/**\n * Class responsible for building explorer context menu.\n *\n * @author Jiri Sedlacek\n */\nfinal class ExplorerContextMenuFactory {\n\n    private static final Logger LOGGER = Logger.getLogger(ExplorerContextMenuFactory.class.getName());\n    private static final String SELECTION_ACTIONS_FILE = \"VisualVM/ExplorerPopupSelection\"; // NOI18N\n    private static final String NOSELECTION_ACTIONS_FILE = \"VisualVM/ExplorerPopupNoSelection\"; // NOI18N\n\n    private static ExplorerContextMenuFactory sharedInstance;\n\n\n    /**\n     * Returns singleton instance of ExplorerContextMenuFactory.\n     * \n     * @return singleton instance of ExplorerContextMenuFactory.\n     */\n    static synchronized ExplorerContextMenuFactory instance() {\n        if (sharedInstance == null) sharedInstance = new ExplorerContextMenuFactory();\n        return sharedInstance;\n    }\n\n\n    JPopupMenu createPopupMenu() {\n        // Get actions for the node\n        List<Action>[] actionsArray = getActions();\n        List<Action> defaultActions = actionsArray[0];\n        List<Action> actions = actionsArray[1];\n\n        // Return if there are no actions to display\n        if (defaultActions.isEmpty() && actions.isEmpty()) return null;\n\n        // Create a popup menu\n        JPopupMenu popupMenu = new JPopupMenu();\n\n        // Insert default actions\n        boolean realDefaultAction = true;\n        if (!defaultActions.isEmpty()) {\n            for (Action defaultAction : defaultActions) {\n                JMenuItem defaultItem = new DataSourceItem(defaultAction);\n                if (realDefaultAction) {\n                    defaultItem.setFont(defaultItem.getFont().deriveFont(Font.BOLD));\n                    realDefaultAction = false;\n                }\n                popupMenu.add(defaultItem);\n            }\n        }\n\n        // Insert separator between default action and other actions\n        if (!defaultActions.isEmpty() && !actions.isEmpty()) popupMenu.addSeparator();\n\n        // Insert other actions\n        if (!actions.isEmpty()) {\n            for (Action action : actions) {\n                if (action == null) popupMenu.addSeparator();\n                else popupMenu.add(createItem(action));\n            }\n        }\n        \n        return popupMenu;\n    }\n    \n    \n    Action getDefaultActionFor(Set<DataSource> dataSources) {\n        if (dataSources.isEmpty()) return null;\n        List<Action> defaultActions = getActions()[0];\n        return defaultActions.isEmpty() ? null : defaultActions.get(0);\n    }\n        \n    private List<Action>[] getActions() {\n        if (ExplorerSupport.sharedInstance().getSelectedDataSources().isEmpty())\n            return getNoSelectionActions();\n        else\n            return getSelectionActions();\n    }\n        \n    private List<Action>[] getSelectionActions() {\n        // Find entrypoint into layer\n        FileObject actionsFO = FileUtil.getConfigFile(SELECTION_ACTIONS_FILE);\n        return getActions(actionsFO, true);\n    }\n        \n    private List<Action>[] getNoSelectionActions() {\n        // Find entrypoint into layer\n        FileObject actionsFO = FileUtil.getConfigFile(NOSELECTION_ACTIONS_FILE);\n        return getActions(actionsFO, false);\n    }\n    \n    private List<Action>[] getActions(FileObject actionsFO, boolean allowDefaultActions) {\n        // Init caches for default and regular context menu actions\n        List<Action> defaultActions = new ArrayList<>();\n        List<Action> actions = new ArrayList<>();\n        \n        if (actionsFO != null) {\n            \n            DataFolder actionsDF = DataFolder.findFolder(actionsFO);\n            DataObject[] menuItems = actionsDF.getChildren();\n            \n            for (DataObject menuItemDO : menuItems) {\n                \n                FileObject fobj = menuItemDO.getPrimaryFile();\n                \n                if (fobj.isFolder()) {\n                    LOGGER.log(Level.WARNING, \"Nested menus not supported for Applications context menu: \" + fobj, fobj);   // NOI18N\n                } else {\n                    InstanceCookie menuItemCookie = menuItemDO.getCookie(InstanceCookie.class);\n                    try {\n                        Object menuItem = menuItemCookie.instanceCreate();\n                        \n                        boolean isDefaultAction = false;\n                        Object isDefaultActionObj = fobj.getAttribute(\"default\");   // NOI18N\n                        if (isDefaultActionObj != null) try {\n                            isDefaultAction = (Boolean)isDefaultActionObj;\n                            if (!allowDefaultActions && isDefaultAction)\n                                LOGGER.log(Level.WARNING, \"Default actions not supported for \" + actionsFO.getPath() + \": \" + menuItem, menuItem);  // NOI18N\n                        } catch (Exception e) {\n                            LOGGER.log(Level.WARNING, \"Cannot determine whether context menu action is default: \" + isDefaultActionObj, isDefaultActionObj);    // NOI18N\n                        }\n        \n                        List<Action> actionsList = isDefaultAction ? defaultActions : actions;\n        \n                        if (menuItem instanceof Action) {\n                            Action action = (Action)menuItem;\n                            if (action.isEnabled()) actionsList.add(action);\n                        } else if (menuItem instanceof JSeparator) {\n                            if (isDefaultAction) {\n                                LOGGER.log(Level.WARNING, \"Separator cannot be added to default actions \" + menuItem, menuItem);    // NOI18N\n                            } else {\n                                actionsList.add(null);\n                            }\n                        } else {\n                            LOGGER.log(Level.WARNING, \"Unsupported context menu item: \" + menuItem, menuItem);  // NOI18N\n                        }\n                    } catch (Exception ex) {\n                        LOGGER.log(Level.SEVERE, \"Unable to resolve context menu action: \" + menuItemDO, menuItemDO);   // NOI18N\n                    }\n                }\n            }\n        \n        }\n        \n        // Return actions\n        return new List[] { cleanupActions(defaultActions), cleanupActions(actions) };\n    }\n    \n    \n    private List<Action> cleanupActions(List<Action> actions) {\n        boolean leadingNull = true;\n        Action lastAction = null;\n        List<Action> cleanActions = new ArrayList<>();\n        \n        for (Action action : actions) {\n            if (action == null) {\n                if (!leadingNull && lastAction != null)\n                    cleanActions.add(null);\n            } else {\n                cleanActions.add(action);\n                leadingNull = false;\n            }\n            lastAction = action;\n        }\n    \n        if (!cleanActions.isEmpty()) {\n            int lastItemIndex = cleanActions.size() - 1;\n            Action lastCleanAction = cleanActions.get(lastItemIndex);\n            if (lastCleanAction == null) cleanActions.remove(lastItemIndex);\n        }\n    \n        return cleanActions;\n    }\n    \n    \n    private static JMenuItem createItem(Action action) {\n        if (action instanceof Presenter.Popup) return ((Presenter.Popup)action).getPopupPresenter();\n        else return new DataSourceItem(action);\n    }\n    \n    \n    private static class DataSourceItem extends JMenuItem {\n        DataSourceItem(Action action) {\n            super(action);\n            setIcon(null);\n            setToolTipText(null);\n            String name = (String)action.getValue(Action.NAME);\n            if (name != null) Mnemonics.setLocalizedText(this, name); // NOI18N\n        }\n    }    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/ExplorerExpansionListener.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.explorer;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\n\n/**\n * Listener receiving notifications about explorer tree expansion changes.\n *\n * @author Jiri Sedlacek\n */\npublic interface ExplorerExpansionListener {\n    \n    /**\n     * DataSource node has been expanded.\n     * \n     * @param dataSource expanded DataSource.\n     */\n    public void dataSourceExpanded(DataSource dataSource);\n    \n    /**\n     * DataSource node has been collapsed.\n     * \n     * @param dataSource collapsed DataSource.\n     */\n    public void dataSourceCollapsed(DataSource dataSource);\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/ExplorerModelBuilder.java",
    "content": "/*\n *  Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.explorer;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport java.awt.Image;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.swing.ImageIcon;\nimport javax.swing.SwingUtilities;\nimport javax.swing.tree.DefaultTreeModel;\nimport javax.swing.tree.TreeNode;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ExplorerModelBuilder implements DataChangeListener<DataSource> {\n    \n    private static final RequestProcessor queue = new RequestProcessor(\"Explorer Builder Processor\");   // NOI18N\n    \n    private static ExplorerModelBuilder instance;\n    \n    private final ExplorerNode explorerRoot;\n    private final DefaultTreeModel explorerModel;\n    \n    private final Map<DataSource, ExplorerNode> nodes = new HashMap<>();\n    private final Map<DataSource, PropertyChangeListener> visibilityListeners = new HashMap<>();\n    private final Map<DataSource, PropertyChangeListener> availabilityListeners = new HashMap<>();\n    private final Map<DataSourceDescriptor, PropertyChangeListener> descriptorListeners = new HashMap<>();\n\n    private static final ExplorerNodesComparator RELATIVE_COMPARATOR =\n            new ExplorerNodesComparator(new RelativePositionComparator());\n\n    \n    public static synchronized ExplorerModelBuilder getInstance() {\n        if (instance == null) instance = new ExplorerModelBuilder();\n        return instance;\n    }\n    \n    \n    DefaultTreeModel getModel() {\n        return explorerModel;\n    }\n    \n    ExplorerNode getNodeFor(DataSource dataSource) {\n        return nodes.get(dataSource);\n    }\n\n        \n    public void dataChanged(final DataChangeEvent<DataSource> event) {\n        queue.post(new Runnable() {\n            public void run() {\n                Set<DataSource> removed = event.getRemoved();\n                Set<DataSource> added = event.getAdded();\n\n                if (!removed.isEmpty()) processRemovedDataSources(removed);\n                if (!added.isEmpty()) processAddedDataSources(added);\n            }\n        });\n    }\n    \n    private void processAddedDataSources(Set<DataSource> added) {\n        for (DataSource dataSource : added) {\n            installVisibilityListener(dataSource);\n            installAvailabilityListener(dataSource);\n        }\n        processIndependentAddedDataSources(Utils.getIndependentDataSources(added));\n    }\n    \n    private void processIndependentAddedDataSources(Set<DataSource> added) {\n        Set<DataSource> addedDisplayable = new HashSet<>();\n\n        for (DataSource dataSource : added) {\n            if (isDisplayed(dataSource) && dataSource != DataSource.ROOT) return;\n            if (isDisplayable(dataSource)) addedDisplayable.add(dataSource);\n        }\n\n        if (!addedDisplayable.isEmpty()) processAddedDisplayableDataSources(addedDisplayable);\n    }\n    \n    private void processRemovedDataSources(Set<DataSource> removed) {\n        for (DataSource dataSource : removed) {\n            uninstallVisibilityListener(dataSource);\n            uninstallAvailabilityListener(dataSource);\n        }\n        processIndependentRemovedDataSources(Utils.getIndependentDataSources(removed));\n    }\n    \n    private void processIndependentRemovedDataSources(Set<DataSource> removed) {\n        Set<DataSource> removedDisplayed = new HashSet<>();\n        \n        for (DataSource dataSource : removed)\n            if (isDisplayed(dataSource)) removedDisplayed.add(dataSource);\n        \n        if (!removedDisplayed.isEmpty()) processRemovedDisplayedDataSources(removedDisplayed);\n    }\n    \n    private void processAddedDisplayableDataSources(Set<DataSource> addedDisplayable) {\n        final List<ExplorerNode> addedNodes = new ArrayList<>();\n        final ProgressHandle[] pHandle = new ProgressHandle[1];\n\n        SwingUtilities.invokeLater(new Runnable() {\n\n            public void run() {\n                pHandle[0] = ProgressHandle.createHandle(NbBundle.getMessage(ExplorerModelBuilder.class, \"LBL_Computing_description\"));\n\n                pHandle[0].setInitialDelay(5000);\n                pHandle[0].start();\n            }\n        });\n\n        try {\n            for (DataSource dataSource : addedDisplayable) {\n                if (dataSource != DataSource.ROOT) {\n                    final ExplorerNode node = new ExplorerNode(dataSource);\n                    addedNodes.add(node);\n                    DataSourceDescriptor descriptor = DataSourceDescriptorFactory.getDescriptor(dataSource);\n                    PropertyChangeListener descriptorListener = new PropertyChangeListener() {\n                        public void propertyChange(final PropertyChangeEvent evt) {\n                            queue.post(new Runnable() {\n                                public void run() { updateNode(node, evt); }\n                            });\n                        }\n                    };\n                    descriptor.addPropertyChangeListener(descriptorListener);\n                    descriptorListeners.put(descriptor, descriptorListener);\n                    updateNode(node, descriptor);\n                }\n            }\n        } finally {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { pHandle[0].finish(); }\n            });\n        }\n\n        addedNodes.sort(RELATIVE_COMPARATOR);\n\n        try { SwingUtilities.invokeAndWait(new Runnable() {\n            public void run() { addNodes(addedNodes); }\n        }); } catch (Exception e) {}\n        \n        Set<DataSource> addedChildren = new HashSet<>();\n        for (DataSource dataSource : addedDisplayable)\n            addedChildren.addAll(dataSource.getRepository().getDataSources());\n        if (!addedChildren.isEmpty()) processIndependentAddedDataSources(addedChildren);\n    }\n    \n    private void processRemovedDisplayedDataSources(Set<DataSource> removedDisplayed) {\n        Set<DataSource> removedChildren = new HashSet<>();\n        for (DataSource dataSource : removedDisplayed)\n            removedChildren.addAll(dataSource.getRepository().getDataSources());\n        if (!removedChildren.isEmpty()) processIndependentRemovedDataSources(removedChildren);\n        \n        final Set<ExplorerNode> removedNodes = new HashSet<>();\n        \n        for (DataSource dataSource : removedDisplayed) {\n            DataSourceDescriptor descriptor = DataSourceDescriptorFactory.getDescriptor(dataSource);\n            PropertyChangeListener descriptorListener = descriptorListeners.get(descriptor);\n            descriptor.removePropertyChangeListener(descriptorListener);\n            descriptorListeners.remove(descriptor);\n            \n            ExplorerNode node = nodes.get(dataSource);\n            removedNodes.add(node);\n        }\n        \n        try { SwingUtilities.invokeAndWait(new Runnable() {\n            public void run() { removeNodes(removedNodes); }\n        }); } catch (Exception e) {}\n    }\n    \n    private void updateNode(ExplorerNode node, DataSourceDescriptor descriptor) {\n        node.setName(descriptor.getName());\n        node.setIcon(descriptor.getIcon() == null ? null : new ImageIcon(descriptor.getIcon()));\n        node.setPreferredPosition(descriptor.getPreferredPosition());\n        node.setComparator(descriptor.getChildrenComparator());\n        node.setAutoExpansionPolicy(descriptor.getAutoExpansionPolicy());\n    }\n    \n    private void updateNode(final ExplorerNode node, final PropertyChangeEvent evt) {\n        String property = evt.getPropertyName();\n        Object newValue = evt.getNewValue();\n\n        // Node name needs to be updated\n        if (DataSourceDescriptor.PROPERTY_NAME.equals(property)) {\n            String name = (String)newValue;\n            Runnable updater = node.setName(name) ?\n                new Runnable() {\n                    public void run() { updateContainer(node.getParent()); }\n                } : new Runnable() {\n                    public void run() { explorerModel.nodeChanged(node); }\n                };\n            try { SwingUtilities.invokeAndWait(updater); } catch (Exception e) {}\n        // Node icon needs to be updated\n        } else if (DataSourceDescriptor.PROPERTY_ICON.equals(property)) {\n            Image icon = (Image)newValue;\n            node.setIcon(icon == null ? null : new ImageIcon(icon));\n            try { SwingUtilities.invokeAndWait(new Runnable() {\n                public void run() { explorerModel.nodeChanged(node); }\n            }); } catch (Exception e) {}\n        // Node position within its parent needs to be updated\n        } else if (DataSourceDescriptor.PROPERTY_PREFERRED_POSITION.equals(property)) {\n            Integer preferredPosition = (Integer)newValue;\n            node.setPreferredPosition(preferredPosition);\n            final ExplorerNode parent = (ExplorerNode)node.getParent();\n            if (parent != null) {\n                try { SwingUtilities.invokeAndWait(new Runnable() {\n                    public void run() {\n                        int nodeIndex = parent.getIndex(node);\n                        parent.remove(node);\n                        explorerModel.nodesWereRemoved(parent, new int[] { nodeIndex }, new Object[] { node });\n                        parent.addNode(node);\n                        explorerModel.nodesWereInserted(parent, new int[] { parent.getIndex(node) });\n                    }\n                }); } catch (Exception e) {}\n            }\n        } else if (DataSourceDescriptor.PROPERTY_CHILDREN_COMPARATOR.equals(property)) {\n            final Comparator<DataSource> comparator = (Comparator<DataSource>)newValue;\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    if (node.setComparator(comparator)) updateContainer(node);\n                }\n            });\n        } else if (DataSourceDescriptor.PROPERTY_EXPANSION_POLICY.equals(property)) {\n            node.setAutoExpansionPolicy((Integer)evt.getNewValue());\n        }\n    }\n\n    private void updateContainer(TreeNode node) {\n        // Save selection\n        Set<DataSource> selectedDataSources = ExplorerSupport.sharedInstance().\n                                              getSelectedDataSources();\n        \n        // Save expanded nodes\n        Set<DataSource> expandedDataSources = ExplorerSupport.sharedInstance().\n                                              getExpandedDataSources(((ExplorerNode)node).getUserObject());\n\n        explorerModel.nodeStructureChanged(node);\n\n        // Try to restore expanded nodes\n        ExplorerSupport.sharedInstance().expandDataSources(expandedDataSources);\n        \n        // Try to restore selection\n        ExplorerSupport.sharedInstance().selectDataSources(selectedDataSources);\n    }\n    \n    private void addNodes(List<ExplorerNode> added) {\n        Map<ExplorerNode, List<Integer>> indexes = new HashMap<>();\n        \n        // Save selection\n        Set<DataSource> selectedDataSources = ExplorerSupport.sharedInstance().getSelectedDataSources();\n        \n        // Add nodes and create parent entries\n        for (ExplorerNode node : added) {\n            DataSource dataSource = node.getUserObject();\n            ExplorerNode nodeParent = getNodeFor(dataSource.getOwner());\n            nodes.put(dataSource, node);\n            nodeParent.addNode(node);\n            indexes.put(nodeParent, new ArrayList<>());\n        }\n        \n        // Compute children indexes\n        for (ExplorerNode node : added) {\n            ExplorerNode nodeParent = (ExplorerNode)node.getParent();\n            indexes.get(nodeParent).add(nodeParent.getIndex(node));\n        }\n\n        // Notify tree model\n        // Synchronize relative positions\n        for (Map.Entry<ExplorerNode, List<Integer>> entry : indexes.entrySet()) {\n            List<Integer> indexesList = entry.getValue();\n            Collections.sort(indexesList);\n            int[] indexesArr = new int[indexesList.size()];\n            for (int i = 0; i < indexesArr.length; i++) indexesArr[i] = indexesList.get(i);\n            final ExplorerNode parent = entry.getKey();\n            explorerModel.nodesWereInserted(parent, indexesArr);\n        }\n        \n        // Try to restore selection\n        ExplorerSupport.sharedInstance().selectDataSources(selectedDataSources);\n    }\n\n    private void removeNodes(Set<ExplorerNode> removed) {\n        Map<ExplorerNode, List<IndexNodePair>> pairs = new HashMap<>();\n        \n        // Save selection\n        Set<DataSource> selectedDataSources = ExplorerSupport.sharedInstance().getSelectedDataSources();\n        \n        // Cache indexes and childs\n        for (ExplorerNode node : removed) {\n            ExplorerNode nodeParent = (ExplorerNode)node.getParent();\n            List<IndexNodePair> list = pairs.get(nodeParent);\n            if (list == null) {\n                list = new ArrayList<>();\n                pairs.put(nodeParent, list);\n            }\n            list.add(new IndexNodePair(nodeParent.getIndex(node), node));\n        }\n        \n        // Remove nodes\n        for (ExplorerNode node : removed) {\n            node.removeFromParent();\n            nodes.remove(node.getUserObject());\n        }\n        \n        // Notify tree model\n        // Synchronize relative positions\n        for (Map.Entry<ExplorerNode, List<IndexNodePair>> entry : pairs.entrySet()) {\n            List<IndexNodePair> indexesList = entry.getValue();\n            Collections.sort(indexesList);\n            int[] indexesArr = new int[indexesList.size()];\n            Object[] childsArr = new Object[indexesList.size()];\n            for (int i = 0; i < indexesArr.length; i++) {\n                IndexNodePair pair = indexesList.get(i);\n                indexesArr[i] = pair.index;\n                childsArr[i] = pair.node;\n            }\n            final ExplorerNode parent = entry.getKey();\n            explorerModel.nodesWereRemoved(parent, indexesArr, childsArr);\n        }\n        \n        // Try to restore selection\n        ExplorerSupport.sharedInstance().selectDataSources(selectedDataSources);\n    }\n    \n    private void installVisibilityListener(final DataSource dataSource) {\n        PropertyChangeListener visibilityListener = new PropertyChangeListener() {\n            public void propertyChange(final PropertyChangeEvent evt) {\n                queue.post(new Runnable() {\n                    public void run() {\n                        if ((Boolean)evt.getNewValue()) {\n                            if (isDisplayed(dataSource.getOwner()) && !isDisplayed(dataSource))\n                                processAddedDisplayableDataSources(Collections.singleton(dataSource));\n                        } else {\n                            if (isDisplayed(dataSource))\n                                processRemovedDisplayedDataSources(Collections.singleton(dataSource));\n                        }\n                    }\n                });\n            }\n        };\n        dataSource.addPropertyChangeListener(DataSource.PROPERTY_VISIBLE, visibilityListener);\n        visibilityListeners.put(dataSource, visibilityListener);\n    }\n    \n    private void uninstallVisibilityListener(DataSource dataSource) {\n        PropertyChangeListener visibilityListener = visibilityListeners.get(dataSource);\n        dataSource.removePropertyChangeListener(DataSource.PROPERTY_VISIBLE, visibilityListener);\n        visibilityListeners.remove(dataSource);\n    }\n    \n    private void installAvailabilityListener(final DataSource dataSource) {\n        PropertyChangeListener visibilityListener = new PropertyChangeListener() {\n            public void propertyChange(final PropertyChangeEvent evt) {\n                final ExplorerNode node = getNodeFor(dataSource);\n                if (node != null) SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        ExplorerNode parent = (ExplorerNode)node.getParent();\n                        if (parent != null) {\n                            parent.sortChildren();\n                            updateContainer(parent);\n                        }\n                    }\n                });\n            }\n        };\n        dataSource.addPropertyChangeListener(Stateful.PROPERTY_STATE, visibilityListener);\n        availabilityListeners.put(dataSource, visibilityListener);\n    }\n    \n    private void uninstallAvailabilityListener(DataSource dataSource) {\n        PropertyChangeListener visibilityListener = visibilityListeners.get(dataSource);\n        dataSource.removePropertyChangeListener(Stateful.PROPERTY_STATE, visibilityListener);\n        availabilityListeners.remove(dataSource);\n    }\n    \n    private boolean isDisplayed(DataSource dataSource) {\n        return nodes.get(dataSource) != null;\n    }\n    \n    private boolean isDisplayable(DataSource dataSource) {\n        if (dataSource == DataSource.ROOT) return true;\n        return dataSource.isVisible() && isDisplayed(dataSource.getOwner());\n    }\n    \n    \n    private ExplorerModelBuilder() {\n        explorerRoot = new ExplorerNode(DataSource.ROOT);\n        explorerRoot.setAutoExpansionPolicy(DataSourceDescriptor.EXPAND_ON_EACH_FIRST_CHILD);\n        explorerModel = new DefaultTreeModel(explorerRoot);\n        \n        nodes.put(DataSource.ROOT, explorerRoot);\n        \n        DataSourceRepository.sharedInstance().addDataChangeListener(this, DataSource.class);\n    }\n\n\n    private static class RelativePositionComparator extends DataSourcesComparator {\n\n        protected int getRelativePosition(DataSource d, int positionType) {\n            try {\n                // throws NumberFormatException\n                return Integer.parseInt(d.getStorage().getCustomProperty(\n                                        ExplorerNode.PROPERTY_RELATIVE_POSITION));\n            } catch (Exception e) {\n                return positionType;\n            }\n        }\n\n    }\n\n\n    private static class IndexNodePair implements Comparable<IndexNodePair> {\n        \n        public int index;\n        public ExplorerNode node;\n        \n        IndexNodePair(int index, ExplorerNode node) {\n            this.index = index;\n            this.node = node;\n        }\n\n        public int compareTo(IndexNodePair pair) {\n            return Integer.compare(index, pair.index);\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj == null) {\n                return false;\n            }\n            if (getClass() != obj.getClass()) {\n                return false;\n            }\n            final IndexNodePair other = (IndexNodePair) obj;\n            if (this.index != other.index) {\n                return false;\n            }\n            return true;\n        }\n\n        @Override\n        public int hashCode() {\n            int hash = 7;\n            hash = 37 * hash + this.index;\n            return hash;\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/ExplorerNode.java",
    "content": "/*\n *  Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.explorer;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.Vector;\nimport javax.swing.Icon;\nimport javax.swing.tree.DefaultMutableTreeNode;\nimport javax.swing.tree.MutableTreeNode;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ExplorerNode extends DefaultMutableTreeNode implements Positionable {\n\n    static final String PROPERTY_RELATIVE_POSITION = \"prop_relative_position\"; // NOI18N\n    \n    private String name;\n    private Icon icon;\n    private int preferredPosition;\n    private int autoExpansionPolicy;\n\n    private boolean defaultComparator = true;\n    private ExplorerNodesComparator comparator = new ExplorerNodesComparator(new PositionableComparator());\n\n    private int maxEndPosition = -1;\n    private int maxLastPosition = -1;\n    private final Map<DataSource, Integer> endPositions = Collections.synchronizedMap(new HashMap<>());\n    private final Map<DataSource, Integer> lastPositions = Collections.synchronizedMap(new HashMap<>());\n\n    private boolean firstExpansionFlag = true;\n    \n    \n    ExplorerNode(DataSource dataSource) {\n        super(dataSource);\n    }\n    \n    \n    public String getName() {\n        return name;\n    }\n    \n    public Icon getIcon() {\n        return icon;\n    }\n    \n    public DataSource getUserObject() {\n        return (DataSource)super.getUserObject();\n    }\n    \n    \n    public void addNode(ExplorerNode newChild) {\n        addNodes(Collections.singleton(newChild));\n    }\n    \n    public void addNodes(Set<ExplorerNode> newChildren) {\n        int originalChildCount = getChildCount();\n        \n        for (ExplorerNode child : newChildren) {\n            add(child);\n            checkAddRelativePosition(child);\n        }\n        sortChildren();\n\n        boolean shouldExpand = false;\n        boolean firstChildAdded = originalChildCount == 0 && getChildCount() > 0;\n        switch (autoExpansionPolicy) {\n//            case DataSourceDescriptor.EXPAND_NEVER:\n//                break;\n            case DataSourceDescriptor.EXPAND_ON_FIRST_CHILD:\n                if (firstExpansionFlag && firstChildAdded) shouldExpand = true;\n                firstExpansionFlag = false;\n                break;\n            case DataSourceDescriptor.EXPAND_ON_EACH_FIRST_CHILD:\n                if (firstChildAdded) shouldExpand = true;\n                break;\n            case DataSourceDescriptor.EXPAND_ON_EACH_NEW_CHILD:\n            case DataSourceDescriptor.EXPAND_ON_EACH_CHILD_CHANGE:\n                if (!newChildren.isEmpty()) shouldExpand = true;\n                break;\n        }\n        if (shouldExpand) ExplorerSupport.sharedInstance().expandNode(this);\n    }\n    \n    public void remove(MutableTreeNode aChild) {\n        super.remove(aChild);\n\n        checkRemoveRelativePosition((ExplorerNode)aChild);\n\n        if (autoExpansionPolicy == DataSourceDescriptor.EXPAND_ON_EACH_CHILD_CHANGE)\n            ExplorerSupport.sharedInstance().expandNode(this);\n    }\n    \n    \n    public String toString() {\n        return getName();\n    }\n    \n    \n    public int getPreferredPosition() {\n        return preferredPosition;\n    }\n    \n    \n    boolean setName(String name) {\n        // No parent, no structure changes\n        if (parent == null) {\n            this.name = name;\n            return false;\n        // Name changed\n        } else if (this.name == null || !this.name.equals(name)) {\n            this.name = name;\n            ((ExplorerNode)parent).sortChildren();\n            return true;\n        // Name unchanged\n        } else {\n            return false;\n        }\n    }\n    \n    void setIcon(Icon icon) {\n        this.icon = icon;\n    }\n    \n    void setPreferredPosition(int preferredPosition) {\n        this.preferredPosition = preferredPosition;\n    }\n\n    boolean setComparator(Comparator<DataSource> comparator) {\n        boolean change = false;\n\n        if (comparator == null) {\n            change = !defaultComparator;\n            if (change) this.comparator = new ExplorerNodesComparator(new PositionableComparator());\n            defaultComparator = true;\n        } else {\n            change = defaultComparator || !this.comparator.uses(comparator);\n            if (change) this.comparator = new ExplorerNodesComparator(comparator);\n            defaultComparator = false;\n        }\n\n        if (change) sortChildren();\n        return change;\n    }\n    \n    void setAutoExpansionPolicy(int autoExpansionPolicy) {\n        this.autoExpansionPolicy = autoExpansionPolicy;\n        firstExpansionFlag = true;\n    }\n\n\n    void sortChildren() {\n        if (getChildCount() == 0) return;\n        ((Vector<ExplorerNode>) children).sort(comparator);\n    }\n\n\n    private void checkAddRelativePosition(ExplorerNode node) {\n        int pos = node.getPreferredPosition();\n        DataSource d = node.getUserObject();\n        if (pos == Positionable.POSITION_AT_THE_END) addPosition(d, endPositions);\n        else if (pos == Positionable.POSITION_LAST) addPosition(d, lastPositions);\n    }\n\n    private void addPosition(DataSource node, Map<DataSource, Integer> positions) {\n        Storage s = node.getStorage();\n        String PREF = DataSourceDescriptor.PROPERTY_PREFERRED_POSITION;\n        \n        int nodePos = 0;\n        boolean posDirty = true;\n        try {\n            // throws NullPointerException\n            nodePos = getMaxPosition(positions) + 1;\n            // throws NumberFormatException\n            nodePos = Integer.parseInt(s.getCustomProperty(PROPERTY_RELATIVE_POSITION));\n            posDirty = false;\n        } catch (Exception e) {}\n\n        if (s.getCustomProperty(PREF) != null && posDirty)\n            s.setCustomProperty(PROPERTY_RELATIVE_POSITION, Integer.toString(nodePos));\n\n        positions.put(node, nodePos);\n        updateMaxPosition(positions, nodePos, false);\n    }\n\n    private void checkRemoveRelativePosition(ExplorerNode node) {\n        int pos = node.getPreferredPosition();\n        DataSource d = node.getUserObject();\n        if (pos == Positionable.POSITION_AT_THE_END) removePosition(d, endPositions);\n        else if (pos == Positionable.POSITION_LAST) removePosition(d, lastPositions);\n    }\n\n    private void removePosition(DataSource node, Map<DataSource, Integer> positions) {\n        int nodePos = positions.remove(node);\n        updateMaxPosition(positions, nodePos, true);\n    }\n    \n    private int getMaxPosition(Map<DataSource, Integer> positions) {\n        if (positions == endPositions) return maxEndPosition;\n        else return maxLastPosition;\n    }\n\n    private void setMaxPosition(Map<DataSource, Integer> positions, int newMax) {\n        if (positions == endPositions) maxEndPosition = newMax;\n        else maxLastPosition = newMax;\n    }\n\n    private void updateMaxPosition(Map<DataSource, Integer> positions, int position, boolean remove) {\n        int maxPos = getMaxPosition(positions);\n        if (!remove && maxPos < position)\n            setMaxPosition(positions, position);\n        else if (remove && maxPos == position) {\n            int newMax = -1;\n            Collection<Integer> values = positions.values();\n            for (int i : values) if (i > newMax) newMax = i;\n            setMaxPosition(positions, newMax);\n        }\n    }\n\n\n    private class PositionableComparator extends DataSourcesComparator {\n\n        protected int getRelativePosition(DataSource d, int positionType) {\n            if (positionType == Positionable.POSITION_AT_THE_END)\n                return endPositions.get(d);\n\n            else if (positionType == Positionable.POSITION_LAST)\n                return lastPositions.get(d);\n            \n            else\n                return positionType;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/ExplorerNodeRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.explorer;\n\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport java.awt.Component;\nimport javax.swing.JLabel;\nimport javax.swing.JTree;\nimport javax.swing.tree.DefaultTreeCellRenderer;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ExplorerNodeRenderer extends DefaultTreeCellRenderer {\n\n    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {\n        Component renderer = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);\n        ExplorerNode dsn = (ExplorerNode)value;\n        JLabel rl = (JLabel)renderer;\n        rl.setText(dsn.getName());\n        rl.setIcon(dsn.getIcon());\n        \n        DataSource ds = dsn.getUserObject();\n        if (ds instanceof Stateful) {\n            rl.setEnabled(((Stateful)ds).getState() == Stateful.STATE_AVAILABLE);\n        } else {\n            rl.setEnabled(true);\n        }\n\n        if (UISupport.isGTKLookAndFeel() || UISupport.isNimbusLookAndFeel()) {\n            if (renderer instanceof DefaultTreeCellRenderer) {\n                DefaultTreeCellRenderer dtcr = (DefaultTreeCellRenderer)renderer;\n                dtcr.setBackgroundSelectionColor(null);\n                dtcr.setBorderSelectionColor(null);\n            }\n        } else if (UISupport.isAquaLookAndFeel()) {\n            if (!sel) {\n                rl.setOpaque(true);\n                rl.setBackground(tree.getBackground());\n            } else {\n                rl.setOpaque(false);\n            }\n        }\n\n        return renderer;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/ExplorerNodesComparator.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.explorer;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport java.util.Comparator;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ExplorerNodesComparator implements Comparator<ExplorerNode> {\n\n    private final Comparator<DataSource> impl;\n\n    \n    ExplorerNodesComparator(Comparator<DataSource> impl) {\n        this.impl = impl;\n    }\n\n\n    boolean uses(Comparator<DataSource> impl) {\n        return this.impl == impl;\n    }\n\n    public int compare(ExplorerNode n1, ExplorerNode n2) {\n        return impl.compare(n1.getUserObject(), n2.getUserObject());\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/ExplorerSelectionListener.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.explorer;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport java.util.Set;\n\n/**\n * Listener receiving notifications about explorer tree selection changes.\n *\n * @author Jiri Sedlacek\n */\npublic interface ExplorerSelectionListener {\n    \n    /**\n     * Explorer tree selection changed.\n     * \n     * @param selected selected DataSources or Collections.EMPTY_SET if no DataSource is selected.\n     */\n    public void selectionChanged(Set<DataSource> selected);\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/ExplorerSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.explorer;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.JTree;\nimport javax.swing.event.TreeExpansionEvent;\nimport javax.swing.event.TreeExpansionListener;\nimport javax.swing.event.TreeSelectionEvent;\nimport javax.swing.event.TreeSelectionListener;\nimport javax.swing.tree.TreePath;\nimport org.openide.windows.WindowManager;\n\n/**\n * Class for accessing the explorer tree.\n *\n * @author Jiri Sedlacek\n */\npublic final class ExplorerSupport {\n\n    private static ExplorerSupport sharedInstance;\n\n    private JTree mainTree;\n    \n    private Set<ExplorerSelectionListener> selectionListeners = Collections.synchronizedSet(new HashSet<>());\n    private Set<ExplorerExpansionListener> expansionListeners = Collections.synchronizedSet(new HashSet<>());\n\n\n    /**\n     * Returns singleton instance of ExplorerSupport.\n     * \n     * @return singleton instance of ExplorerSupport.\n     */\n    public static synchronized ExplorerSupport sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new ExplorerSupport();\n        return sharedInstance;\n    }\n\n    \n    /**\n     * Returns current DataSource position within its owner DataSource in explorer tree or -1 if the position cannot be determined.\n     * \n     * @param dataSource DataSource for which to get the position.\n     * @return current DataSource position within its owner DataSource in explorer tree or -1 if the position cannot be determined.\n     */\n    public int getDataSourcePosition(DataSource dataSource) {\n        ExplorerNode node = getNode(dataSource);\n        if (node == null) return -1;\n        ExplorerNode parentNode = (ExplorerNode)node.getParent();\n        if (parentNode == null) return -1;\n        return parentNode.getIndex(node);\n    }\n\n    /**\n     * Selects DataSource in explorer tree.\n     * \n     * @param dataSource DataSource to be selected.\n     */\n    public void selectDataSource(final DataSource dataSource) {\n        if (dataSource == null) return;\n        selectDataSources(Collections.singleton(dataSource));\n    }\n    \n    /**\n     * Selects multiple DataSources in explorer tree.\n     * \n     * @param dataSources DataSources to be selected.\n     */\n    public void selectDataSources(final Set<DataSource> dataSources) {\n        if (dataSources.isEmpty()) return;\n        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n            public void run() {\n                List<TreePath> selectedPaths = new ArrayList<>();\n                for (DataSource dataSource : dataSources) {\n                    ExplorerNode node = getNode(dataSource);\n                    if (node != null) selectedPaths.add(getPath(node));\n                }\n                mainTree.setSelectionPaths(selectedPaths.isEmpty() ? null : selectedPaths.toArray(new TreePath[0]));\n            } \n        });\n    }\n    \n    /**\n     * Clears selection of explorer tree.\n     */\n    public void clearSelection() {\n        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n            public void run() { mainTree.clearSelection(); } \n        });\n    }\n    \n    /**\n     * Returns selected DataSources in explorer tree.\n     * \n     * @return selected DataSources in explorer tree.\n     */\n    public Set<DataSource> getSelectedDataSources() {\n        if (mainTree == null) return Collections.emptySet();\n        \n        TreePath[] selectedPaths = mainTree.getSelectionPaths();\n        if (selectedPaths == null) return Collections.emptySet();\n        \n        Set<DataSource> selectedDataSources = new HashSet<>();\n        for (TreePath treePath : selectedPaths) {\n            DataSource dataSource = getDataSource(treePath);\n            if (dataSource != null) selectedDataSources.add(dataSource);\n        }\n        return selectedDataSources;\n    }\n    \n    /**\n     * Adds a listener to receive notifications about explorer tree selection change.\n     * \n     * @param listener listener to add.\n     */\n    public void addSelectionListener(ExplorerSelectionListener listener) {\n        selectionListeners.add(listener);\n    }\n    \n    /**\n     * Removes explorer tree selection listener.\n     * @param listener listener to remove.\n     */\n    public void removeSelectionListener(ExplorerSelectionListener listener) {\n        selectionListeners.remove(listener);\n    }\n    \n    \n    Set<DataSource> getExpandedDataSources(DataSource origin) {\n        if (mainTree == null) return Collections.emptySet();\n        \n        Enumeration<TreePath> expandedPaths = mainTree.getExpandedDescendants(getPath(getNode(origin)));\n        if (expandedPaths == null) return Collections.emptySet();\n        \n        Set<DataSource> expandedDataSources = new HashSet<>();\n        while (expandedPaths.hasMoreElements()) {\n            DataSource dataSource = getDataSource(expandedPaths.nextElement());\n            if (dataSource != null) expandedDataSources.add(dataSource);\n        }\n        return expandedDataSources;\n    }\n    \n    void expandDataSources(final Set<DataSource> dataSources) {\n        if (dataSources.isEmpty()) return;\n        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n            public void run() {\n                for (DataSource dataSource : dataSources) {\n                    ExplorerNode node = getNode(dataSource);\n                    if (node != null) mainTree.expandPath(getPath(node));\n                }\n            } \n        });\n    }\n    \n    /**\n     * Expands DataSource if displayed and collapsed in explorer tree.\n     * \n     * @param dataSource DataSource to expand.\n     */\n    public void expandDataSource(DataSource dataSource) {\n        expandNode(getNode(dataSource));\n    }\n    \n    void expandNode(final ExplorerNode node) {\n        if (node == null) return;\n        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n            public void run() { \n                TreePath path = getPath(node);\n                // For some reason expanding the path doesn't always work for a single invocation,\n                // invoking twice to be sure\n                mainTree.expandPath(path);\n                mainTree.expandPath(path);\n            } \n        });\n    }\n    \n    /**\n     * Collapses DataSource if displayed and expanded in explorer tree.\n     * \n     * @param dataSource DataSource to collapse.\n     */\n    public void collapseDataSource(DataSource dataSource) {\n        collapseNode(getNode(dataSource));\n    }\n    \n    void collapseNode(final ExplorerNode node) {\n        if (node == null) return;\n        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n            public void run() { mainTree.collapsePath(getPath(node)); } \n        });\n    }\n    \n    /**\n     * Adds a listener to receive notifications about expanded/collapsed explorer tree nodes.\n     * \n     * @param listener listener to add.\n     */\n    public void addExpansionListener(ExplorerExpansionListener listener) {\n        expansionListeners.add(listener);\n    }\n    \n    /**\n     * Removes explorer tree expansion listener.\n     * \n     * @param listener listener to remove.\n     */\n    public void removeExpansionListener(ExplorerExpansionListener listener) {\n        expansionListeners.remove(listener);\n    }\n    \n    \n    DataSource getDataSource(TreePath path) {\n        if (path == null) return null;\n        ExplorerNode node = (ExplorerNode)path.getLastPathComponent();\n        return node.getUserObject();\n    }\n    \n    ExplorerNode getNode(DataSource dataSource) {\n        return ExplorerModelBuilder.getInstance().getNodeFor(dataSource);\n    }\n    \n    TreePath getPath(ExplorerNode node) {\n        return new TreePath(node.getPath());\n    }\n            \n    \n    private ExplorerSupport() {\n        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n            public void run() {\n                mainTree = ExplorerComponent.instance().getTree();\n                mainTree.addTreeSelectionListener(new ExplorerTreeSelectionListener());\n                mainTree.addTreeExpansionListener(new ExplorerTreeExpansionListener());\n            }\n        });\n    }\n    \n    \n    private class ExplorerTreeSelectionListener implements TreeSelectionListener {\n\n        public void valueChanged(TreeSelectionEvent e) {\n            Set<DataSource> selectedDataSources = getSelectedDataSources();\n            Set<ExplorerSelectionListener> listeners = new HashSet<>(selectionListeners);\n            for (ExplorerSelectionListener listener : listeners) listener.selectionChanged(selectedDataSources);\n        }\n        \n    }\n    \n    private class ExplorerTreeExpansionListener implements TreeExpansionListener {\n\n        public void treeExpanded(TreeExpansionEvent event) {\n            DataSource expandedDataSource = getDataSource(event.getPath());\n            if (expandedDataSource != null) {\n                Set<ExplorerExpansionListener> listeners = new HashSet<>(expansionListeners);\n                for (ExplorerExpansionListener listener : listeners) listener.dataSourceExpanded(expandedDataSource);\n            }\n        }\n\n        public void treeCollapsed(TreeExpansionEvent event) {\n            DataSource collapsedDataSource = getDataSource(event.getPath());\n            if (collapsedDataSource != null) {\n                Set<ExplorerExpansionListener> listeners = new HashSet<>(expansionListeners);\n                for (ExplorerExpansionListener listener : listeners) listener.dataSourceCollapsed(collapsedDataSource);\n            }\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/ExplorerTopComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.explorer;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.FocusAdapter;\nimport java.awt.event.FocusEvent;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.Mode;\nimport org.openide.windows.TopComponent;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n// Top component for DataSources explorer\nfinal class ExplorerTopComponent extends TopComponent {\n\n    private static final String PREFERRED_ID = \"ExplorerTopComponent\";  // NOI18N\n    private static final Logger LOGGER = Logger.getLogger(ExplorerTopComponent.class.getName());\n    \n    static final String ICON_PATH = \"org/graalvm/visualvm/core/ui/resources/explorer.png\";    // NOI18N\n\n    private static ExplorerTopComponent instance;\n\n\n    private ExplorerTopComponent() {\n        initComponents();\n        setName(NbBundle.getMessage(ExplorerTopComponent.class, \"LBL_Applications\"));   // NOI18N\n        setToolTipText(NbBundle.getMessage(ExplorerTopComponent.class, \"LBL_Applications\"));    // NOI18N\n        setIcon(ImageUtilities.loadImage(ICON_PATH, true));\n\n        setFocusable(true);\n        setRequestFocusEnabled(true);\n        addFocusListener(new FocusAdapter() {\n            public void focusGained(FocusEvent e) {\n                ExplorerComponent.instance().requestFocusInWindow();\n            }\n        });\n    }\n  \n    private void initComponents() {\n        setLayout(new BorderLayout());\n        add(ExplorerComponent.instance(), BorderLayout.CENTER);\n    }\n    \n    \n    /**\n    * Gets default instance. Do not use directly: reserved for *.settings files only,\n    * i.e. deserialization routines; otherwise you could get a non-deserialized instance.\n    * To obtain the singleton instance, use {@link #findInstance()}.\n    */\n    public static synchronized ExplorerTopComponent getInstance() {\n        if (instance == null) instance = new ExplorerTopComponent();\n        return instance;\n    }\n    \n    /**\n    * Obtain the ExplorerTopComponent instance. Never call {@link #getInstance()} directly!\n    */\n    public static synchronized ExplorerTopComponent findInstance() {\n        TopComponent explorerTopComponent = WindowManager.getDefault().findTopComponent(PREFERRED_ID);\n        if (explorerTopComponent == null) return getInstance();\n        if (explorerTopComponent instanceof ExplorerTopComponent) return (ExplorerTopComponent)explorerTopComponent;\n    \n        if (LOGGER.isLoggable(Level.WARNING)) {\n            LOGGER.warning(\"There seem to be multiple components with the '\" + PREFERRED_ID + \"' ID. That is a potential source of errors and unexpected behavior.\");   // NOI18N\n    }\n        return getInstance();\n    }\n    \n    private boolean needsDocking() {\n        return WindowManager.getDefault().findMode(this) == null;\n    }\n\n    public void open() {\n        if (needsDocking()) {\n            Mode mode = WindowManager.getDefault().findMode(\"explorer\"); // NOI18N\n            if (mode != null) mode.dockInto(this);\n        }\n        super.open();\n    }\n    \n    public int getPersistenceType() {\n        return TopComponent.PERSISTENCE_ALWAYS;\n    }\n  \n    protected String preferredID() {\n        return PREFERRED_ID;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/ExplorerTopComponentAction.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.explorer;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ImageIcon;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * Action which shows ExplorerTopComponent component.\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\nclass ExplorerTopComponentAction extends AbstractAction {\n    \n    private static Action instance;\n    \n    \n    public static synchronized Action instance() {\n        if (instance == null) instance = new ExplorerTopComponentAction();\n        return instance;\n    }\n  \n    public void actionPerformed(ActionEvent evt) {\n        ExplorerTopComponent win = ExplorerTopComponent.findInstance();\n        win.open();\n        win.requestActive();\n    }\n    \n    \n    private ExplorerTopComponentAction() {\n        super(NbBundle.getMessage(ExplorerTopComponentAction.class, \"CTL_ExplorerTopComponentAction\")); // NOI18N\n        putValue(SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(ExplorerTopComponent.ICON_PATH, true)));\n    }\n  \n}\n\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/explorer/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * APIs for accessing explorer tree (Applications tree).\n */\npackage org.graalvm.visualvm.core.explorer;\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.2//EN\" \"http://www.netbeans.org/dtds/filesystem-1_2.dtd\">\n<filesystem>\n    \n    <folder name=\"Actions\">\n        <folder name=\"Other\">\n            <file name=\"org-graalvm-visualvm-core-ui-actions-LoadSnapshotAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.core.ui.actions.LoadSnapshotAction.instance\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-core-ui-actions-SaveSnapshotAsAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.core.ui.actions.SaveSnapshotAsAction.instance\"/>\n            </file>\n        </folder>\n        <folder name=\"Window\">\n            <file name=\"org-graalvm-visualvm-core-explorer-ExplorerTopComponentAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.core.explorer.ExplorerTopComponentAction.instance\"/>\n                <attr name=\"position\" intvalue=\"100\"/>\n            </file>\n        </folder>\n    </folder>\n\n    <folder name=\"Shortcuts\">\n        <file name=\"DELETE.shadow\">\n            <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-core-ui-actions-DeleteSnapshotAction.instance\"/>\n        </file>\n    </folder>\n    \n    <folder name=\"Menu\">\n        \n        <folder name=\"File\">\n            <file name=\"org-graalvm-visualvm-core-ui-actions-LoadSnapshotAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-core-ui-actions-LoadSnapshotAction.instance\"/>\n                <attr name=\"position\" intvalue=\"100\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-core-ui-actions-SaveSnapshotAsAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-core-ui-actions-SaveSnapshotAsAction.instance\"/>\n                <attr name=\"position\" intvalue=\"200\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-core-ui-actions-LoadRecentSnapshot.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.core.ui.actions.LoadRecentSnapshot.instance\"/>\n                <attr name=\"position\" intvalue=\"250\"/>\n            </file>\n            <file name=\"File-Separator-280.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"280\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-core-ui-actions-DeleteSnapshotAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-core-ui-actions-DeleteSnapshotAction.instance\"/>\n                <attr name=\"position\" intvalue=\"300\"/>\n            </file>\n            <file name=\"File-Separator-400.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"400\"/>\n            </file>\n        </folder>\n        \n         <folder name=\"Applications\">\n            <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.graalvm.visualvm.core.Bundle\"/>\n            <attr name=\"position\" intvalue=\"200\"/>\n            <file name=\"org-graalvm-visualvm-core-ui-actions-OpenDataSourceAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-core-ui-actions-OpenDataSourceAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1100\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-core-ui-actions-RenameDataSourceAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-core-ui-actions-RenameDataSourceAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1200\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-core-ui-actions-RemoveDataSourceAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-core-ui-actions-RemoveDataSourceAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1300\"/>\n            </file>\n            <file name=\"Applications-Separator-2000.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"2000\"/>\n            </file>\n        </folder>\n\n        <folder name=\"View\">\n            <file name=\"File-Separator-750.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"750\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-core-snapshot-SnapshotsSorting.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.core.snapshot.SnapshotsSorting.instance\"/>\n                <attr name=\"position\" intvalue=\"950\"/>\n            </file>\n        </folder>\n        \n        <folder name=\"Window\">\n            <file name=\"ExplorerTopComponentAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Window/org-graalvm-visualvm-core-explorer-ExplorerTopComponentAction.instance\"/>\n                <attr name=\"position\" intvalue=\"100\"/>\n            </file>\n        </folder>\n        \n    </folder>\n    \n    <folder name=\"Toolbars\">\n        <folder name=\"Snapshot\">\n            <attr name=\"position\" intvalue=\"100\"/>\n            <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.graalvm.visualvm.core.Bundle\"/>\n            <file name=\"org-graalvm-visualvm-core-ui-actions-LoadSnapshotAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-core-ui-actions-LoadSnapshotAction.instance\"/>\n                <attr name=\"position\" intvalue=\"100\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-core-ui-actions-SaveSnapshotAsAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-core-ui-actions-SaveSnapshotAsAction.instance\"/>\n                <attr name=\"position\" intvalue=\"200\"/>\n            </file>\n        </folder>\n\n        <folder name=\"DataSource\">\n            <attr name=\"position\" intvalue=\"200\"/>\n            <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.graalvm.visualvm.core.Bundle\"/>\n        </folder>\n    </folder>\n    \n    <folder name=\"VisualVM\">\n        <folder name=\"Actions\">\n            <file name=\"org-graalvm-visualvm-core-ui-actions-DeleteSnapshotAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.core.ui.actions.DeleteSnapshotAction.instance\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-core-ui-actions-OpenDataSourceAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.core.ui.actions.OpenDataSourceAction.instance\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-core-ui-actions-RenameDataSourceAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.core.ui.actions.RenameDataSourceAction.instance\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-core-ui-actions-RemoveDataSourceAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.core.ui.actions.RemoveDataSourceAction.instance\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-core-properties-EditPropertiesAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.core.properties.EditPropertiesAction.instance\"/>\n            </file>\n        </folder>\n        \n        <folder name=\"ExplorerPopupSelection\">\n            \n            <file name=\"org-graalvm-visualvm-core-ui-actions-OpenDataSourceAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-core-ui-actions-OpenDataSourceAction.instance\"/>\n                <attr name=\"position\" intvalue=\"0\"/>\n                <attr name=\"default\" boolvalue=\"true\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-core-ui-actions-SaveSnapshotAsAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-core-ui-actions-SaveSnapshotAsAction.instance\"/>\n                <attr name=\"position\" intvalue=\"50\"/>\n                <attr name=\"default\" boolvalue=\"true\"/>\n            </file>\n            \n            <file name=\"ExplorerPopupSelection-Separator-1000.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"1000\"/>\n            </file>\n            \n            <file name=\"ExplorerPopupSelection-Separator-2000.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"2000\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-core-ui-actions-RenameDataSourceAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-core-ui-actions-RenameDataSourceAction.instance\"/>\n                <attr name=\"position\" intvalue=\"2100\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-core-ui-actions-RemoveDataSourceAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-core-ui-actions-RemoveDataSourceAction.instance\"/>\n                <attr name=\"position\" intvalue=\"2200\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-core-ui-actions-DeleteSnapshotAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-core-ui-actions-DeleteSnapshotAction.instance\"/>\n                <attr name=\"position\" intvalue=\"2300\"/>\n            </file>\n\n            <file name=\"ExplorerPopupSelection-Separator-9999.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"9999\"/>\n            </file>\n\n            <file name=\"org-graalvm-visualvm-core-properties-EditPropertiesAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-core-properties-EditPropertiesAction.instance\"/>\n                <attr name=\"position\" intvalue=\"10000\"/>\n            </file>\n            \n        </folder>\n    </folder>\n\n    <folder name=\"Services\">\n        <folder name=\"AutoupdateType\">\n            <file name=\"org_graalvm_visualvm_core_update_center.instance\">\n                <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.core.Bundle#Services/AutoupdateType/org_graalvm_visualvm_core_update_center.instance\"/>\n                <attr name=\"enabled\" boolvalue=\"true\"/>\n                <attr name=\"instanceCreate\" methodvalue=\"org.netbeans.modules.autoupdate.updateprovider.AutoupdateCatalogFactory.createUpdateProvider\"/>\n                <attr name=\"instanceOf\" stringvalue=\"org.netbeans.spi.autoupdate.UpdateProvider\"/>\n                <attr name=\"url\" bundlevalue=\"org.graalvm.visualvm.core.Bundle#org_graalvm_visualvm_core_update_center\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"Windows2\">\n        <folder name=\"Components\">\n            <file name=\"ExplorerTopComponent.settings\" url=\"ui/resources/ExplorerTopComponentSettings.xml\"/>\n        </folder>\n        <folder name=\"Modes\">\n            <folder name=\"explorer\">\n                <file name=\"ExplorerTopComponent.wstcref\" url=\"ui/resources/ExplorerTopComponentWstcref.xml\"/>\n            </folder>\n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/model/AbstractModelProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.model;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\n\n/**\n * Abstract class, which simplifies implementation of {@link ModelProvider}.\n * It uses class hierarchy to compute priority of providers.\n * @author Tomas Hurka\n */\npublic abstract class AbstractModelProvider<M extends Model,B extends DataSource> implements ModelProvider<M,B> {\n    \n    /**\n     * {@inheritDoc}\n     */ \n    public abstract M createModelFor(B app);\n    \n    public int priority() {\n        int depth = 1;\n        Class<?> cls = getClass();\n        \n        for (;!cls.equals(AbstractModelProvider.class);cls=cls.getSuperclass()) {\n            depth++;\n        }\n        return depth;\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/model/Model.java",
    "content": "/*\n * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.model;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\n\n/**\n * This abstract class which serves as root object for\n * all models attached to {@link DataSource} instances\n * using {@link ModelFactory}.\n * @author Tomas Hurka\n */\npublic abstract class Model {\n\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/model/ModelCache.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core.model;\n\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.lang.ref.Reference;\nimport java.lang.ref.SoftReference;\nimport java.lang.ref.WeakReference;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class ModelCache<D extends DataSource, M extends Model> {\n\n    private final static Logger LOGGER = Logger.getLogger(ModelCache.class.getName());\n\n    /**\n     * special marker for null model\n     */\n    final ModelReference<M> NULL_MODEL;\n    private final Map<DataSourceKey<D>, ModelReference<M>> modelCache;\n\n    ModelCache() {\n        modelCache = Collections.synchronizedMap(new HashMap<>());\n        NULL_MODEL = new ModelReference<>(null, 0);\n    }\n\n    Reference<M> get(DataSourceKey<D> key) {\n        ModelReference<M> valueRef = modelCache.get(key);\n        if (valueRef != null && valueRef.modCount < key.modCount) {\n            Reference<M> removed = modelCache.remove(key);\n            LOGGER.finer(\"Invalid mod count \" + key + \" \" + (removed != null ? \"removed\" : \"not removed\"));\n            return null;\n        }\n        return valueRef;\n    }\n\n    Reference<M> put(DataSourceKey<D> key, M value) {\n        ModelReference<M> ref;\n        DataSource ds = key.weakReference.get();\n        if (ds instanceof Stateful && value != null) {\n            ds.addPropertyChangeListener(Stateful.PROPERTY_STATE, new StateListener(key));\n            LOGGER.finer(\"Registered listener for \" + key + \" val \" + value.getClass());\n        }\n        if (value == null) {\n            ref = NULL_MODEL;\n        } else {\n            ref = new ModelReference<>(value, key.modCount);\n        }\n        return modelCache.put(key, ref);\n    }\n\n    void clear() {\n        modelCache.clear();\n    }\n\n    /**\n     * DataSource wrapper object, which weakly reference datasource and uses\n     * reference-equality of DataSources when implementing hashCode and equals\n     * this class is used as keys in modelCache\n     */\n    static class DataSourceKey<D extends DataSource> {\n\n        Reference<D> weakReference;\n        int modCount;\n\n        DataSourceKey(D ds) {\n            weakReference = new WeakReference<>(ds);\n            if (ds instanceof Stateful) {\n                modCount = ((Stateful) ds).getModCount();\n            }\n        }\n\n        public int hashCode() {\n            D ds = weakReference.get();\n            if (ds != null) {\n                return ds.hashCode();\n            }\n            return 0;\n        }\n\n        public boolean equals(Object obj) {\n            if (obj == null) {\n                return false;\n            }\n            if (obj instanceof DataSourceKey) {\n                D ds = weakReference.get();\n                D otherDs = ((DataSourceKey<D>) obj).weakReference.get();\n\n                return ds != null && ds == otherDs;\n            }\n            throw new IllegalArgumentException(obj.getClass().getName());\n        }\n\n        public String toString() {\n            DataSource ds = weakReference.get();\n            return \"DataSourceKey for \" + System.identityHashCode(this) + \" for \" + ds == null ? \"NULL\" : ds.toString();    // NOI18N\n        }\n    }\n\n    private static class ModelReference<T> extends SoftReference<T> {\n\n        private int modCount;\n\n        private ModelReference(T ref, int count) {\n            super(ref);\n            modCount = count;\n        }\n    }\n\n    private class StateListener implements PropertyChangeListener {\n\n        DataSourceKey<D> key;\n\n        StateListener(DataSourceKey<D> k) {\n            key = k;\n        }\n\n        @Override\n        public void propertyChange(PropertyChangeEvent evt) {\n            int newState = (Integer) evt.getNewValue();\n            if (newState == Stateful.STATE_AVAILABLE) {\n                DataSource ds = key.weakReference.get();\n                if (ds != null) {\n                    ds.removePropertyChangeListener(Stateful.PROPERTY_STATE, this);\n                }\n                if (ds == null || key.modCount < ((Stateful)ds).getModCount()) {\n                    Reference<M> removed = modelCache.remove(key);\n                    LOGGER.finer(key + \" \" + (removed != null ? \"removed\" : \"not removed\"));\n                } else {\n                    LOGGER.finer(key + \" newer model found\");\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/model/ModelFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.model;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.ClassNameComparator;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasupport.DataChangeSupport;\nimport java.lang.ref.Reference;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.SortedSet;\nimport java.util.TreeSet;\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.ReadWriteLock;\nimport java.util.concurrent.locks.ReentrantReadWriteLock;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.core.model.ModelCache.DataSourceKey;\n\n/**\n * This is abstract factory class for getting model\n * for datasource. It as two functions. First it serves\n * as cache for the model associated with datasource. \n * Second, ModelFactory uses list of ModelProviders registered \n * via {@link #registerProvider(ModelProvider )} to\n * determine the order of in which they are consulted \n * to obtain the model for dataSource. First model \n * obtained from ModelProvider is associated with\n * dataSource and returned in the future.\n * @author Tomas Hurka\n */\npublic abstract class ModelFactory<M extends Model,D extends DataSource> {\n    final protected static Logger LOGGER = Logger.getLogger(ModelFactory.class.getName());\n    \n    /** set of registered providers */\n    private SortedSet<ModelProvider<M, D>> providers;\n    /** providers cannot be changed, when getModel() is running */\n    private ReadWriteLock providersLock;\n    /** model cache */\n    private ModelCache<D,M> modelCache;\n    /** asynchronous change support */\n    private DataChangeSupport<ModelProvider<M, D>> factoryChange;\n    \n    protected ModelFactory() {\n        providers = new TreeSet<>(new ModelProviderComparator());\n        modelCache = new ModelCache<>();\n        factoryChange = new DataChangeSupport<>();\n        providersLock = new ReentrantReadWriteLock();\n    }\n    \n    /**\n     * Returns model for dataSource. If model is in the cache\n     * return it, otherwise consult registered ModelProviders.\n     * @param dataSource {@link DataSource} for which {@link Model} should be returned\n     * @return model for dataSource or <CODE>null</CODE> \n     * if there is no model associated with this dataSource.\n     */ \n    public final M getModel(D dataSource) {\n        // take a read lock for providers\n        Lock rlock = providersLock.readLock();\n        rlock.lock();\n        try {\n            // allow concurrent access to cache for different instances of DataSource\n            // note that DataSourceKey uses reference-equality in place of object-equality \n            // for DataSource\n            synchronized (dataSource) {\n                DataSourceKey<D> key = new DataSourceKey<>(dataSource);\n                Reference<M> modelRef = modelCache.get(key);\n                M model = null;\n\n                if (modelRef != null) {\n                    if (modelRef == modelCache.NULL_MODEL) {  // cached null model, return null\n                        return null;\n                    }\n                    model = modelRef.get(); // if model is in cache return it,\n                    if (model != null) {    // otherwise get it from providers\n                        return model;\n                    }\n                }\n                // try to get model from registered providers\n                for (ModelProvider<M, D> factory : providers) {\n                    model = factory.createModelFor(dataSource);\n                    if (model != null) {  // we have model, put it into cache\n                        modelCache.put(key,model);\n                        break;\n                    }\n                }\n                if (model == null) {  // model was not found - cache null model\n                    modelCache.put(key,null);\n                }\n                return model;\n            }\n        } finally {\n            rlock.unlock();\n        }\n    }\n    \n    /**\n     * register new {@link ModelProvider}. \n     * Model provider can be registered only once.\n     * @param newProvider to register\n     * @return <CODE>true</CODE> if this ModelFactory does not contain registered provider.\n     */\n    public final boolean registerProvider(ModelProvider<M, D> newProvider) {\n        // take a write lock on providers\n        Lock wlock = providersLock.writeLock();\n        wlock.lock();\n        try {\n            LOGGER.finer(\"Registering \" + newProvider.getClass().getName());    // NOI18N\n            boolean added = providers.add(newProvider);\n            if (added) {\n                modelCache.clear();\n                factoryChange.fireChange(providers,Collections.singleton(newProvider),null);\n            }\n            return added;\n        } finally {\n            wlock.unlock();\n        }\n    }\n    \n    /**\n     * Unregister {@link ModelProvider}.\n     * @param oldProvider provider, which should be unregistered\n     * @return <CODE>true</CODE> if provider was unregistered.\n     */\n    public final boolean unregisterProvider(ModelProvider<M, D> oldProvider) {\n        // take a write lock on providers\n        Lock wlock = providersLock.writeLock();\n        wlock.lock();\n        try {\n            LOGGER.finer(\"Unregistering \" + oldProvider.getClass().getName());  // NOI18N\n            boolean removed = providers.remove(oldProvider);\n            if (removed) {\n                modelCache.clear();\n                factoryChange.fireChange(providers,null,Collections.singleton(oldProvider));\n            }\n            return removed;\n         } finally {\n            wlock.unlock();\n         }\n    }\n    \n    /**\n     * Add data change listener. Data change is fired when \n     * {@link ModelProvider} is registered/unregister. \n     * @param listener {@link DataChangeListener} to be added\n     */\n    public final void addFactoryChangeListener(DataChangeListener<ModelProvider<M, D>> listener) {\n        factoryChange.addChangeListener(listener);\n    }\n    \n    /**\n     * Remove data change listener.\n     * @param listener {@link DataChangeListener} to be removed\n     */\n    public final void removeFactoryChangeListener(DataChangeListener<ModelProvider<M, D>> listener) {\n        factoryChange.removeChangeListener(listener);\n    }\n    \n    /**\n     * Default priority. Subclass of ModelFactory can implement \n     * {@link ModelProvider}. In that case such provider should be\n     * used as last provider. This is ensured by returning -1, since\n     * providers, which subclass {@link AbstractModelProvider}, return \n     * positive numbers. \n     * @return -1\n     */\n    public int priority() {\n        return -1;\n    }\n    \n    /** compare ModelProvider-s using priority. Providers with higher priority\n     * gets precedence over those with lower priority\n     */\n    private class ModelProviderComparator implements Comparator<ModelProvider<M,D>> {\n        \n        public int compare(ModelProvider<M, D> provider1, ModelProvider<M, D> provider2) {\n            int thisVal = provider1.priority();\n            int anotherVal = provider2.priority();\n            \n            if (thisVal<anotherVal) {\n                return 1;\n            }\n            if (thisVal>anotherVal) {\n                return -1;\n            }\n            // same depth -> use class name to create artificial ordering\n            return ClassNameComparator.INSTANCE.compare(provider1, provider2);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/model/ModelProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.model;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\n\n/**\n * This interface should be implemented if you want to extend ModelFactory \n * with your own provider. Implementors of this ModelProvider interface\n * should be registered with appropriate {@link ModelFactory} using\n * {@link ModelFactory#registerProvider(ModelProvider)}\n * @author Tomas Hurka\n */\npublic interface ModelProvider<M extends Model,B extends DataSource> {\n    \n    /**\n     * This is factory method for creating new instance \n     * of Model for DataSource. Implementation of this method\n     * should return <code>null</code> if this model provider \n     * cannot construct model for passed dataSource.\n     * @param dataSource {@link DataSource} for which {@link Model} should be created\n     * @return model subclass for dataSource \n     */ \n    M createModelFor(B dataSource);\n    /**\n     * Priority is used by {@link ModelFactory} to sort registered \n     * {@link ModelProvider}. Model provider with the highest priority\n     * will be invoked first and so no, until non-null value \n     * is returned from {@link #createModelFor(DataSource )}\n     * @return priority of this ModelProvider\n     */\n    int priority();\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/model/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * This package provides generic support for attaching Model to DataSource.\n * \n */\npackage org.graalvm.visualvm.core.model;\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/options/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOptionsCategory_Name_Core=General\nLBL_Monitored_Host=Monitored &Host\\:\nLBL_Sec=sec.\nLBL_Threads=Thread&s\\:\nLBL_Monitored_Data=Monitored &Data\\:\nLBL_Polling=Polling\nLBL_Charts_Cache=Charts Cache\nLBL_Monitored_Host2=Monitored H&ost\\:\nLBL_min=min.\nLBL_Monitored_Data2=Monitored D&ata\\:\nLBL_FinishedApps=Finished Applications\nMSG_FinishedApps=Keep finished applications in the Applications view\\:\nLBL_FinishedAppsOpened=O&pened applications\nLBL_FinishedAppsSnapshot=Applications with s&napshots\nLBL_Miscellaneous=Miscellaneous\nMSG_Do_Not_Show_Again=Reset Do Not Show Again confirmations\\:\nBTN_Reset=&Reset\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/options/GeneralOptionsPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.options;\n\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.uisupport.JExtendedSpinner;\nimport java.awt.BorderLayout;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.ItemListener;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JSpinner;\nimport javax.swing.SpinnerNumberModel;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jaroslav Bachorik\n * @author Jiri Sedlacek\n */\nfinal class GeneralOptionsPanel extends JPanel {\n\n    private final GeneralOptionsPanelController controller;\n\n    transient private final ChangeListener changeListener = new ChangeListener() {\n        public void stateChanged(ChangeEvent e) {\n            controller.changed();\n        }\n    };\n    \n    GeneralOptionsPanel(GeneralOptionsPanelController controller) {\n        this.controller = controller;\n        initComponents();\n        startTrackingChanges();\n    }\n\n\n    private void initComponents() {\n        GridBagConstraints c;\n\n        setLayout(new GridBagLayout());\n\n        // --- Polling ---\n\n        SectionSeparator pollingSection = UISupport.createSectionSeparator(NbBundle.getMessage\n                                          (GeneralOptionsPanel.class, \"LBL_Polling\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 0;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 5, 0);\n        add(pollingSection, c);\n\n        monitoredHostPLabel = new JLabel();\n        Mnemonics.setLocalizedText(monitoredHostPLabel, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"LBL_Monitored_Host\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 0);\n        add(monitoredHostPLabel, c);\n\n        monitoredHostPSpinner = new JExtendedSpinner();\n        monitoredHostPLabel.setLabelFor(monitoredHostPSpinner);\n        monitoredHostPSpinner.setModel(new SpinnerNumberModel(3, 1, 99999, 1));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 40, 3, 4);\n        add(monitoredHostPSpinner, c);\n\n        monitoredHostPUnits = new JLabel();\n        Mnemonics.setLocalizedText(monitoredHostPUnits, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"LBL_Sec\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 3, 0);\n        add(monitoredHostPUnits, c);\n        \n        threadsPLabel = new JLabel();\n        Mnemonics.setLocalizedText(threadsPLabel, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"LBL_Threads\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 2;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 0);\n        add(threadsPLabel, c);\n\n        threadsPSpinner = new JExtendedSpinner();\n        threadsPLabel.setLabelFor(threadsPSpinner);\n        threadsPSpinner.setModel(new SpinnerNumberModel(1, 1, 99999, 1));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 2;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 40, 3, 4);\n        add(threadsPSpinner, c);\n\n        threadsPUnits = new JLabel();\n        Mnemonics.setLocalizedText(threadsPUnits, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"LBL_Sec\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 2;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 3, 0);\n        add(threadsPUnits, c);\n\n        monitoredDataPLabel = new JLabel();\n        Mnemonics.setLocalizedText(monitoredDataPLabel, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"LBL_Monitored_Data\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 3;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 0);\n        add(monitoredDataPLabel, c);\n\n        monitoredDataPSpinner = new JExtendedSpinner();\n        monitoredDataPLabel.setLabelFor(monitoredDataPSpinner);\n        monitoredDataPSpinner.setModel(new SpinnerNumberModel(1, 1, 99999, 1));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 3;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 40, 3, 4);\n        add(monitoredDataPSpinner, c);\n\n        monitoredDataPUnits = new JLabel();\n        Mnemonics.setLocalizedText(monitoredDataPUnits, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"LBL_Sec\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 3;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 3, 0);\n        add(monitoredDataPUnits, c);\n\n        // --- Charts cache ---\n\n        SectionSeparator chartsCacheSection = UISupport.createSectionSeparator(NbBundle.getMessage\n                                          (GeneralOptionsPanel.class, \"LBL_Charts_Cache\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 4;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(15, 0, 5, 0);\n        add(chartsCacheSection, c);\n\n        monitoredHostCLabel = new JLabel();\n        Mnemonics.setLocalizedText(monitoredHostCLabel, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"LBL_Monitored_Host2\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 5;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 0);\n        add(monitoredHostCLabel, c);\n\n        monitoredHostCSpinner = new JExtendedSpinner();\n        monitoredHostCLabel.setLabelFor(monitoredHostCSpinner);\n        monitoredHostCSpinner.setModel(new SpinnerNumberModel(60, 1, 99999, 1));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 5;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 40, 3, 4);\n        add(monitoredHostCSpinner, c);\n\n        monitoredHostCUnits = new JLabel();\n        Mnemonics.setLocalizedText(monitoredHostCUnits, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"LBL_min\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 5;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 3, 0);\n        add(monitoredHostCUnits, c);\n\n        monitoredDataCLabel = new JLabel();\n        Mnemonics.setLocalizedText(monitoredDataCLabel, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"LBL_Monitored_Data2\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 6;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 0);\n        add(monitoredDataCLabel, c);\n\n        monitoredDataCSpinner = new JExtendedSpinner();\n        monitoredDataCLabel.setLabelFor(monitoredDataCSpinner);\n        monitoredDataCSpinner.setModel(new SpinnerNumberModel(60, 1, 99999, 1));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 6;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 40, 3, 4);\n        add(monitoredDataCSpinner, c);\n\n        monitoredDataCUnits = new JLabel();\n        Mnemonics.setLocalizedText(monitoredDataCUnits, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"LBL_min\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 6;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 0, 3, 0);\n        add(monitoredDataCUnits, c);\n        \n        // --- Finished Apps ---\n\n        SectionSeparator appsSection = UISupport.createSectionSeparator(NbBundle.getMessage\n                                          (GeneralOptionsPanel.class, \"LBL_FinishedApps\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 7;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(15, 0, 5, 0);\n        add(appsSection, c);\n        \n        JLabel appsLabel = new JLabel();\n        Mnemonics.setLocalizedText(appsLabel, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"MSG_FinishedApps\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 8;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(6, 15, 6, 0);\n        add(appsLabel, c);\n\n        JPanel appsPanel = new JPanel(null);\n        appsPanel.setLayout(new BoxLayout(appsPanel, BoxLayout.LINE_AXIS));\n        \n        finishedAppsOpen = new JCheckBox();\n        Mnemonics.setLocalizedText(finishedAppsOpen, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"LBL_FinishedAppsOpened\")); // NOI18N\n        appsPanel.add(finishedAppsOpen);\n        \n        appsPanel.add(Box.createHorizontalStrut(10));\n        \n        finishedAppsSnapshots = new JCheckBox();\n        Mnemonics.setLocalizedText(finishedAppsSnapshots, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"LBL_FinishedAppsSnapshot\")); // NOI18N\n        appsPanel.add(finishedAppsSnapshots);\n        \n        c = new GridBagConstraints();\n        c.gridy = 9;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(2, 15, 2, 0);\n        add(appsPanel, c);\n\n        // --- Misc ---\n\n        SectionSeparator profilerSection = UISupport.createSectionSeparator(NbBundle.getMessage\n                                          (GeneralOptionsPanel.class, \"LBL_Miscellaneous\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 10;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(15, 0, 5, 0);\n        add(profilerSection, c);\n\n        JPanel resetDNSAPanel = new JPanel(new BorderLayout());\n\n        resetDNSALabel = new JLabel();\n        Mnemonics.setLocalizedText(resetDNSALabel, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"MSG_Do_Not_Show_Again\")); // NOI18N\n        resetDNSAPanel.add(resetDNSALabel, BorderLayout.CENTER);\n\n        resetDNSAButton = new JButton();\n        Mnemonics.setLocalizedText(resetDNSAButton, NbBundle.getMessage(\n                                   GeneralOptionsPanel.class, \"BTN_Reset\")); // NOI18N\n        resetDNSAPanel.add(resetDNSAButton, BorderLayout.EAST);\n\n        c = new GridBagConstraints();\n        c.gridy = 11;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(2, 15, 2, 0);\n        add(resetDNSAPanel, c);\n\n        // --- Filler ---\n\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 12;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        add(Spacer.create(), c);\n    }\n\n    private void resetDNSAButtonAction() {\n        ProfilerIDESettings.getInstance().clearDoNotShowAgainMap();\n        resetDNSAButton.setEnabled(false);\n    }\n\n    void load() {\n        // TODO read settings and initialize GUI\n        // Example:        \n        // someCheckBox.setSelected(Preferences.userNodeForPackage(CorePanel.class).getBoolean(\"someFlag\", false));\n        // or for org.openide.util with API spec. version >= 7.4:\n        // someCheckBox.setSelected(NbPreferences.forModule(CorePanel.class).getBoolean(\"someFlag\", false));\n        // or:\n        // someTextField.setText(SomeSystemOption.getDefault().getSomeStringProperty());\n        GlobalPreferences preferences = GlobalPreferences.sharedInstance();\n        resetDNSAButton.setEnabled(true);\n        monitoredHostPSpinner.setValue(preferences.getMonitoredHostPoll());\n        monitoredDataPSpinner.setValue(preferences.getMonitoredDataPoll());\n        threadsPSpinner.setValue(preferences.getThreadsPoll());\n        monitoredHostCSpinner.setValue(preferences.getMonitoredHostCache());\n        monitoredDataCSpinner.setValue(preferences.getMonitoredDataCache());\n        finishedAppsOpen.setSelected(!preferences.autoRemoveOpenedFinishedApps());\n        finishedAppsSnapshots.setSelected(!preferences.autoRemoveFinishedAppsWithSnapshots());\n    }\n\n    void store() {\n        // TODO store modified settings\n        // Example:\n        // Preferences.userNodeForPackage(CorePanel.class).putBoolean(\"someFlag\", someCheckBox.isSelected());\n        // or for org.openide.util with API spec. version >= 7.4:\n        // NbPreferences.forModule(CorePanel.class).putBoolean(\"someFlag\", someCheckBox.isSelected());\n        // or:\n        // SomeSystemOption.getDefault().setSomeStringProperty(someTextField.getText());\n        GlobalPreferences preferences = GlobalPreferences.sharedInstance();\n        preferences.setMonitoredHostPoll((Integer) monitoredHostPSpinner.getValue());\n        preferences.setMonitoredDataPoll((Integer) monitoredDataPSpinner.getValue());\n        preferences.setThreadsPoll((Integer) threadsPSpinner.getValue());\n        preferences.setMonitoredHostCache((Integer) monitoredHostCSpinner.getValue());\n        preferences.setMonitoredDataCache((Integer) monitoredDataCSpinner.getValue());\n        preferences.setAutoRemoveOpenedFinishedApps(!finishedAppsOpen.isSelected());\n        preferences.setAutoRemoveFinishedAppsWithSnapshots(!finishedAppsSnapshots.isSelected());\n        preferences.store();\n    }\n\n    boolean valid() {\n        try {\n            int mh = (Integer) monitoredHostPSpinner.getValue();\n            int md = (Integer) monitoredDataPSpinner.getValue();\n            int th = (Integer) threadsPSpinner.getValue();\n            int mhc = (Integer) monitoredHostCSpinner.getValue();\n            int mdc = (Integer) monitoredDataCSpinner.getValue();\n            return mh > 0 && md > 0 && th > 0 && mhc > 0 && mdc > 0;\n        } catch (Exception e) {\n        }\n        return false;\n    }\n\n    private void startTrackingChanges() {\n        monitoredHostPSpinner.getModel().addChangeListener(changeListener);\n        threadsPSpinner.getModel().addChangeListener(changeListener);\n        monitoredDataPSpinner.getModel().addChangeListener(changeListener);\n        monitoredHostCSpinner.getModel().addChangeListener(changeListener);\n        monitoredDataCSpinner.getModel().addChangeListener(changeListener);\n        \n        ItemListener il = new ItemListener() {\n            @Override public void itemStateChanged(ItemEvent e) { controller.changed(); }\n        };\n        finishedAppsOpen.addItemListener(il);\n        finishedAppsSnapshots.addItemListener(il);\n        \n        resetDNSAButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                resetDNSAButtonAction();\n            }\n        });\n    }\n\n\n    private JLabel monitoredHostPLabel;\n    private JSpinner monitoredHostPSpinner;\n    private JLabel monitoredHostPUnits;\n    private JLabel threadsPLabel;\n    private JSpinner threadsPSpinner;\n    private JLabel threadsPUnits;\n    private JLabel monitoredDataPLabel;\n    private JSpinner monitoredDataPSpinner;\n    private JLabel monitoredDataPUnits;\n    private JLabel monitoredHostCLabel;\n    private JSpinner monitoredHostCSpinner;\n    private JLabel monitoredHostCUnits;\n    private JLabel monitoredDataCLabel;\n    private JSpinner monitoredDataCSpinner;\n    private JLabel monitoredDataCUnits;\n    private JCheckBox finishedAppsOpen;\n    private JCheckBox finishedAppsSnapshots;\n    private JLabel resetDNSALabel;\n    private JButton resetDNSAButton;\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/options/GeneralOptionsPanelController.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.options;\n\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport javax.swing.JComponent;\nimport org.netbeans.spi.options.OptionsPanelController;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\n\n@OptionsPanelController.TopLevelRegistration(\n        id = \"GeneralOptions\",\n        categoryName = \"#OptionsCategory_Name_Core\",\n        iconBase = \"org/graalvm/visualvm/core/ui/resources/options.png\",\n        position = 1000\n)\npublic final class GeneralOptionsPanelController extends OptionsPanelController {\n\n    private GeneralOptionsPanel panel;\n    private JComponent component;\n    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);\n    private boolean changed;\n\n    public void update() {\n        getPanel().load();\n        changed = false;\n    }\n\n    public void applyChanges() {\n        getPanel().store();\n        changed = false;\n    }\n\n    public void cancel() {\n        // need not do anything special, if no changes have been persisted yet\n    }\n\n    public boolean isValid() {\n        return getPanel().valid();\n    }\n\n    public boolean isChanged() {\n        return changed;\n    }\n\n    public HelpCtx getHelpCtx() {\n        return null; // new HelpCtx(\"...ID\") if you have a help set\n\n    }\n\n    public JComponent getComponent(Lookup masterLookup) {\n        return getComponent();\n    }\n\n    public void addPropertyChangeListener(PropertyChangeListener l) {\n        pcs.addPropertyChangeListener(l);\n    }\n\n    public void removePropertyChangeListener(PropertyChangeListener l) {\n        pcs.removePropertyChangeListener(l);\n    }\n\n    private GeneralOptionsPanel getPanel() {\n        if (panel == null) {\n            panel = new GeneralOptionsPanel(this);\n        }\n        return panel;\n    }\n\n    private JComponent getComponent() {\n        if (component == null) {\n            component = UISupport.createScrollableContainer(getPanel());\n        }\n        return component;\n    }\n\n    void changed() {\n        if (!changed) {\n            changed = true;\n            pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);\n        }\n        pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/options/GlobalPreferences.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.options;\n\nimport org.graalvm.visualvm.core.datasupport.ComparableWeakReference;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.prefs.BackingStoreException;\nimport java.util.prefs.PreferenceChangeEvent;\nimport java.util.prefs.PreferenceChangeListener;\nimport java.util.prefs.Preferences;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.openide.util.NbPreferences;\n\n/**\n * General VisualVM settings defined in Options.\n *\n * @author Jaroslav Bachorik\n * @author Jiri Sedlacek\n */\npublic final class GlobalPreferences implements PreferenceChangeListener {\n    private final static Logger LOGGER = Logger.getLogger(\"org.graalvm.visualvm.core.options\");   // NOI18N\n\n    private static final String INT_KEY_MONHOST_POLL = \"MonitoredHostPoll\"; // NOI18N\n    private static final String INT_KEY_THREADS_POLL = \"ThreadsPoll\";   // NOI18N\n    private static final String INT_KEY_MONDATA_POLL = \"MonitoredDataPoll\"; // NOI18N\n    private static final String INT_KEY_MONHOST_CACHE = \"MonitoredHostCache\";   // NOI18N\n    private static final String INT_KEY_MONDATA_CACHE = \"MonitoredDataCache\";   // NOI18N\n    \n    private static final String BOOL_KEY_APPS_OPENED = \"FinishedAppsOpened\";   // NOI18N\n    private static final String BOOL_KEY_APPS_SNAPSHOTS = \"FinishedAppsSnapshots\";   // NOI18N\n    \n    private final static int MONHOST_POLL_DEFAULT = 3;\n    private final static int THREADS_POLL_DEFAULT = 1;\n    private final static int MONDATA_POLL_DEFAULT = 1;\n    private final static int MONHOST_CACHE_DEFAULT = 60;\n    private final static int MONDATA_CACHE_DEFAULT = 60;\n    \n    private final static boolean APPS_OPENED_DEFAULT = false;\n    private final static boolean APPS_SNAPSHOTS_DEFAULT = false;\n    \n    private final static GlobalPreferences INSTANCE = new GlobalPreferences();\n    private final Preferences prefs;\n    private final Map<String, Set<ComparableWeakReference<PreferenceChangeListener>>> listenerMap = new HashMap<>();\n\n    private final ExecutorService dispatcher = Executors.newCachedThreadPool();\n    \n    private GlobalPreferences() {\n        prefs =  NbPreferences.forModule(GlobalPreferences.class);\n        prefs.addPreferenceChangeListener(this);\n    }\n    \n    /**\n     * Returns singleton instance of GlobalPreferences.\n     * \n     * @return singleton instance of GlobalPreferences.\n     */\n    public static GlobalPreferences sharedInstance() {\n        return INSTANCE;\n    }\n\n    public void preferenceChange(final PreferenceChangeEvent evt) {\n        synchronized(listenerMap) {\n            Set<ComparableWeakReference<PreferenceChangeListener>> set = listenerMap.get(evt.getKey());\n            if (set != null) {\n                final Set<PreferenceChangeListener> tmpListeners = new HashSet<>();\n                Collection<ComparableWeakReference<PreferenceChangeListener>> deadRefs = new ArrayList<>();\n                for(ComparableWeakReference<PreferenceChangeListener> pclRef : set) {\n                    if (pclRef.get() != null) {\n                        tmpListeners.add(pclRef.get());\n                    } else {\n                        deadRefs.add(pclRef);\n                    }\n                }\n                set.removeAll(deadRefs);\n                dispatcher.submit(new Runnable() {\n                    public void run() {\n                        for(PreferenceChangeListener pcl : tmpListeners) {\n                            pcl.preferenceChange(evt);\n                        }\n                    }\n                });\n            }\n        }\n    }\n\n    /**\n     * Returns polling interval for monitored host.\n     * \n     * @return polling interval for monitored host.\n     */\n    public int getMonitoredHostPoll() {\n        return getPollingInterval(INT_KEY_MONHOST_POLL, MONHOST_POLL_DEFAULT);\n    }\n    \n    /**\n     * Sets polling interval for monitored host.\n     * \n     * @param value polling interval for monitored host.\n     */\n    public void setMonitoredHostPoll(int value) {\n        setPollingInterval(INT_KEY_MONHOST_POLL, value);\n    }\n    \n    /**\n     * Registers a listener for changes of polling interval for monitored host.\n     * \n     * @param pcl listener for changes of polling interval for monitored host.\n     */\n    public void watchMonitoredHostPoll(PreferenceChangeListener pcl) {\n        addListener(INT_KEY_MONHOST_POLL, pcl);\n    }\n    \n    /**\n     * Returns polling interval for threads.\n     * \n     * @return polling interval for threads.\n     */\n    public int getThreadsPoll() {\n        return getPollingInterval(INT_KEY_THREADS_POLL, THREADS_POLL_DEFAULT);\n    }\n    \n    /**\n     * Sets polling interval for threads.\n     * \n     * @param value polling interval for threads.\n     */\n    public void setThreadsPoll(int value) {\n        setPollingInterval(INT_KEY_THREADS_POLL, value);\n    }\n    \n    /**\n     * Registers a listener for changes of polling interval for threads.\n     * \n     * @param pcl listener for changes of polling interval for threads.\n     */\n    public void watchThreadsPoll(PreferenceChangeListener pcl) {\n        addListener(INT_KEY_THREADS_POLL, pcl);\n    }\n    \n    /**\n     * Returns polling interval for monitored data.\n     * \n     * @return polling interval for monitored data.\n     */\n    public int getMonitoredDataPoll() {\n        return getPollingInterval(INT_KEY_MONDATA_POLL, MONDATA_POLL_DEFAULT);\n    }\n    \n    /**\n     * Sets polling interval for monitored data.\n     * \n     * @param value polling interval for monitored data.\n     */\n    public void setMonitoredDataPoll(int value) {\n        setPollingInterval(INT_KEY_MONDATA_POLL, value);\n    }\n    \n    /**\n     * Registers a listener for changes of polling interval for monitored data.\n     * \n     * @param pcl listener for changes of polling interval for monitored data.\n     */\n    public void watchMonitoredDataPoll(PreferenceChangeListener pcl) {\n        addListener(INT_KEY_MONDATA_POLL, pcl);\n    }\n    \n    /**\n     * Returns size of cache for monitored host data.\n     * \n     * @return size of cache for monitored host data.\n     */\n    public int getMonitoredHostCache() {\n        return getPollingInterval(INT_KEY_MONHOST_CACHE, MONHOST_CACHE_DEFAULT);\n    }\n    \n    /**\n     * Sets size of cache for monitored host data.\n     * \n     * @param value size of cache for monitored host data.\n     */\n    public void setMonitoredHostCache(int value) {\n        setPollingInterval(INT_KEY_MONHOST_CACHE, value);\n    }\n    \n    /**\n     * Registers a listener for changes of size of cache for monitored host data.\n     * \n     * @param pcl listener for changes of size of cache for monitored host data.\n     */\n    public void watchMonitoredHostCache(PreferenceChangeListener pcl) {\n        addListener(INT_KEY_MONHOST_CACHE, pcl);\n    }\n    \n    /**\n     * Returns size of cache for monitored data.\n     * \n     * @return size of cache for monitored data.\n     */\n    public int getMonitoredDataCache() {\n        return getPollingInterval(INT_KEY_MONDATA_CACHE, MONDATA_CACHE_DEFAULT);\n    }\n    \n    /**\n     * Sets size of cache for monitored data.\n     * \n     * @param value size of cache for monitored data.\n     */\n    public void setMonitoredDataCache(int value) {\n        setPollingInterval(INT_KEY_MONDATA_CACHE, value);\n    }\n    \n    /**\n     * Registers a listener for changes of size of cache for monitored data.\n     * \n     * @param pcl listener for changes of size of cache for monitored data.\n     */\n    public void watchMonitoredDataCache(PreferenceChangeListener pcl) {\n        addListener(INT_KEY_MONDATA_CACHE, pcl);\n    }\n    \n    /**\n     * Returns true if opened applications can be removed automatically when finished.\n     * \n     * @return true if opened applications can be removed automatically when finished, false otherwise.\n     */\n    public boolean autoRemoveOpenedFinishedApps() {\n        return prefs.getBoolean(BOOL_KEY_APPS_OPENED, APPS_OPENED_DEFAULT);\n    }\n    \n    /**\n     * Sets whether opened applications can be removed automatically when finished.\n     * \n     * @param value flag controlling whether opened applications can be removed automatically when finished.\n     */\n    public void setAutoRemoveOpenedFinishedApps(boolean value) {\n        prefs.putBoolean(BOOL_KEY_APPS_OPENED, value);\n    }\n    \n    /**\n     * Returns true if applications with snapshots can be removed automatically when finished.\n     * \n     * @return true if applications with snapshots can be removed automatically when finished, false otherwise.\n     */\n    public boolean autoRemoveFinishedAppsWithSnapshots() {\n        return prefs.getBoolean(BOOL_KEY_APPS_SNAPSHOTS, APPS_SNAPSHOTS_DEFAULT);\n    }\n    \n    /**\n     * Sets whether applications with snapshots can be removed automatically when finished.\n     * \n     * @param value flag controlling whether applications with snapshots can be removed automatically when finished.\n     */\n    public void setAutoRemoveFinishedAppsWithSnapshots(boolean value) {\n        prefs.putBoolean(BOOL_KEY_APPS_SNAPSHOTS, value);\n    }\n    \n    /**\n     * Persistently stores preferences values. This method is called automatically,\n     * typically you don't need to call it explicitly.\n     * \n     * @return true if the preferences have been stored successfully, false otherwise.\n     */\n    public boolean store() {\n        try {\n            prefs.sync();\n            return true;\n        } catch (BackingStoreException ex) {\n            LOGGER.log(Level.SEVERE, \"Error saving preferences\", ex);   // NOI18N\n        }\n        return false;\n    }\n    \n    private void addListener(String property, PreferenceChangeListener pcl) {\n        synchronized(listenerMap) {\n            if (listenerMap.containsKey(property)) {\n                Set<ComparableWeakReference<PreferenceChangeListener>> set = listenerMap.get(property);\n                set.add(new ComparableWeakReference<>(pcl));\n            } else {\n                Set<ComparableWeakReference<PreferenceChangeListener>> set = new HashSet<>();\n                set.add(new ComparableWeakReference<>(pcl));\n                listenerMap.put(property, set);\n            }\n        }\n    }\n    \n    private int getPollingInterval(String property, int deflt) {\n        int value = -1;\n        synchronized (prefs) {\n            value = prefs.getInt(property, -1);\n            if (value == -1) {\n                value = deflt;\n                prefs.putInt(property, value);\n            }\n        }\n        return value;\n    }\n    \n    private void setPollingInterval(String property, int value) {\n        synchronized(prefs) {\n            prefs.putInt(property, value);\n        }\n    }\n    \n    \n    /**\n     * Allows to set or clear persistent do not show again value associated with given notification identified by the\n     * provided key.\n     *\n     * @param key A key that uniquely identifies the notification\n     * @param value The value that should be used without displaying the notification or null to clear the Do not show\n     *              again (i.e. start displaying the notifications again).\n     */\n    public void setDoNotShowAgain(String key, String value) {\n        ProfilerIDESettings.getInstance().setDoNotShowAgain(key, value);\n    }\n\n    /**\n     * Allows to get persistent do not show again value associated with given notification identified by the provided key.\n     *\n     * @param  key A key that uniquely identifies the notification\n     * @return The value that should be used without displaying the notification or null if the notification should\n     *         be displayed\n     */\n    public String getDoNotShowAgain(String key) {\n        return ProfilerIDESettings.getInstance().getDoNotShowAgain(key);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/options/UISupport.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.options;\n\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JScrollPane;\n\n/**\n * Helper class to create UI components for the Options dialog.\n *\n * @author Jiri Sedlacek\n */\npublic final class UISupport {\n\n    /**\n     * Creates preformated instance of SectionSeparator to be used in Options\n     * dialog.\n     *\n     * @param caption section name\n     * @return preformated instance of SectionSeparator\n     */\n    public static SectionSeparator createSectionSeparator(String caption) {\n        return new SectionSeparator(caption);\n    }\n\n    /**\n     * Creates preformatted instance of ScrollableContainer to be used in Options\n     * dialog. All insets are already initialized to defaults, the client components\n     * should have zero outer insets.\n     * \n     * @param contents component to be displayed\n     * @return preformatted instance of ScrollableContainer\n     */\n    public static ScrollableContainer createScrollableContainer(JComponent contents) {\n        ScrollableContainer container = new ScrollableContainer(contents,\n                                        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                                        JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n        container.setViewportBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));\n        container.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 5));\n        return container;\n    }\n\n\n    private UISupport() {}\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/options/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Access to general VisualVM settings defined in Options.\n */\npackage org.graalvm.visualvm.core.options;\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/properties/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nLBL_OK=OK\n\nACT_Properties=&Properties\n\nDESCR_Properties=Properties\n\nCAP_EditProperties=Properties of {0}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/properties/EditPropertiesAction.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.properties;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport java.awt.event.ActionEvent;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass EditPropertiesAction extends SingleDataSourceAction<DataSource> {\n\n    private static EditPropertiesAction instance;\n\n    public static synchronized EditPropertiesAction instance() {\n        if (instance == null) instance = new EditPropertiesAction();\n        return instance;\n    }\n\n\n    protected void actionPerformed(DataSource dataSource, ActionEvent actionEvent) {\n        PropertiesSupport.sharedInstance().openProperties(dataSource);\n    }\n\n    protected boolean isEnabled(DataSource dataSource) {\n        return PropertiesSupport.sharedInstance().hasProperties(dataSource);\n    }\n\n\n    private EditPropertiesAction() {\n        super(DataSource.class);\n        putValue(NAME, NbBundle.getMessage(EditPropertiesAction.class, \"ACT_Properties\"));   // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(EditPropertiesAction.class, \"DESCR_Properties\"));   // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/properties/PropertiesConfigurator.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.properties;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport java.awt.BorderLayout;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass PropertiesConfigurator extends JPanel {\n\n    private static Dimension MIN_SIZE = new Dimension(400, 300);\n    private static Dimension MAX_SIZE = new Dimension(700, 600);\n\n    private static Map<String, Dimension> SAVED_SIZES = new HashMap<>();\n\n\n    public static void editProperties(DataSource dataSource, int propertiesCategory) {\n        PropertiesCustomizer customizer =\n                PropertiesSupport.sharedInstance().getCustomizer(dataSource, null);\n        customizer.selectCategory(propertiesCategory);\n        PropertiesConfigurator pc = new PropertiesConfigurator(customizer);\n\n        final DialogDescriptor dd = new DialogDescriptor(pc, NbBundle.getMessage(\n                PropertiesConfigurator.class, \"CAP_EditProperties\", new Object[] { // NOI18N\n                DataSourceDescriptorFactory.getDescriptor(dataSource).getName() }),\n                true, new Object[] { pc.okButton, DialogDescriptor.CANCEL_OPTION },\n                pc.okButton, 0, null, null);\n        final Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n        String className = dataSource.getClass().getName();\n        Dimension savedSize = SAVED_SIZES.get(className);\n        if (savedSize != null) pc.setPreferredSize(savedSize);\n        d.pack();\n        d.setVisible(true);\n        SAVED_SIZES.put(className, pc.getSize());\n        pc.cleanup();\n\n        if (dd.getValue() == pc.okButton) customizer.propertiesChanged();\n        else customizer.propertiesCancelled();\n    }\n    \n  \n    private PropertiesConfigurator(PropertiesCustomizer customizer) {\n        this.customizer = customizer;\n        initComponents();\n        update();\n        customizer.addChangeListener(listener);\n    }\n\n\n    private void cleanup() {\n        customizer.removeChangeListener(listener);\n        removeAll();\n    }\n\n  \n    private void update() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                okButton.setEnabled(customizer.settingsValid());\n            }\n        });\n    }\n\n    public Dimension getPreferredSize() {\n        Dimension prefSize = super.getPreferredSize();\n        prefSize.width = Math.max(prefSize.width, MIN_SIZE.width);\n        prefSize.width = Math.min(prefSize.width, MAX_SIZE.width);\n        prefSize.height = Math.max(prefSize.height, MIN_SIZE.height);\n        prefSize.height = Math.min(prefSize.height, MAX_SIZE.height);\n        return prefSize;\n    }\n\n    private void initComponents() {\n        setLayout(new BorderLayout());\n        setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));\n        add(customizer, BorderLayout.CENTER);\n        okButton = new JButton(NbBundle.getMessage(PropertiesConfigurator.class, \"LBL_OK\"));    // NOI18N\n    }\n\n\n    private final PropertiesCustomizer customizer;\n    private final ChangeListener listener = new ChangeListener() {\n                      public void stateChanged(ChangeEvent e) { update(); }\n                  };\n  \n    private JButton okButton;\n  \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/properties/PropertiesCustomizer.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.properties;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JTabbedPane;\nimport javax.swing.UIManager;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\n\n/**\n * UI component for presenting user-customizable properties of a DataSource.\n * This class is to be used by DataSource providers supporting defining the\n * initial DataSource properties. Use PropertiesSupport.getCustomizer(Class)\n * method to get an instance of PropertiesCustomizer for a concrete DataSource\n * type.\n *\n * @author Jiri Sedlacek\n */\npublic final class PropertiesCustomizer<X extends DataSource> extends PropertiesPanel {\n\n    private final X dataSource;\n    private final List<List<PropertiesProvider<X>>> groups;\n    private final List<PropertiesPanel> panels;\n    private final ChangeListener listener = new ChangeListener() {\n                      public void stateChanged(ChangeEvent e) { update(); }\n                  };\n\n    private JTabbedPane tabbedPane;\n    private final Map<Integer, Integer> categories;\n\n\n    PropertiesCustomizer(X dataSource, Class<X> type) {\n        this.dataSource = dataSource;\n\n        groups = createGroups(PropertiesSupport.sharedInstance().getProviders(dataSource, type));\n        panels = createPanels(groups, dataSource);\n\n        categories = new HashMap<>();\n        \n        initComponents();\n        update();\n        registerListeners();\n    }\n\n\n    /**\n     * Invokes PropertiesProvider.propertiesDefined method for every\n     * PropertiesProvider supporting the provided DataSource. To be called by\n     * DataSource providers when the New DataSource dialog displaying editable\n     * properties has been accepted by the user and new DataSource has been\n     * created.\n     *\n     * @param dataSource newly created DataSource\n     */\n    public void propertiesDefined(X dataSource) {\n        unregisterListeners();\n        for (int i = 0; i < groups.size(); i++) {\n            List<PropertiesProvider<X>> providers = groups.get(i);\n            List<PropertiesPanel> categoriesPanels = new ArrayList<>();\n            if (providers.size() == 1) {\n                categoriesPanels.add(panels.get(i));\n            } else {\n                MultiPropertiesPanel multiPanel = (MultiPropertiesPanel)panels.get(i);\n                categoriesPanels.addAll(multiPanel.getPanels());\n            }\n            for (int j = 0; j < providers.size(); j++)\n                providers.get(j).propertiesDefined(categoriesPanels.get(j), dataSource);\n        }\n    }\n\n    /**\n     * Invokes PropertiesProvider.propertiesCancelled method for every\n     * PropertiesProvider supporting the DataSource type defined for this\n     * PropertiesCustomizer. To be called by DataSource providers when the New\n     * DataSource dialog displaying editable properties has been cancelled and\n     * no DataSource has been created.\n     */\n    public void propertiesCancelled() {\n        unregisterListeners();\n        for (int i = 0; i < groups.size(); i++) {\n            List<PropertiesProvider<X>> providers = groups.get(i);\n            List<PropertiesPanel> categoriesPanels = new ArrayList<>();\n            if (providers.size() == 1) {\n                categoriesPanels.add(panels.get(i));\n            } else {\n                MultiPropertiesPanel multiPanel = (MultiPropertiesPanel)panels.get(i);\n                categoriesPanels.addAll(multiPanel.getPanels());\n            }\n            for (int j = 0; j < providers.size(); j++)\n                providers.get(j).propertiesCancelled(categoriesPanels.get(j), dataSource);\n        }\n    }\n    \n\n    void propertiesChanged() {\n        unregisterListeners();\n        for (int i = 0; i < groups.size(); i++) {\n            List<PropertiesProvider<X>> providers = groups.get(i);\n            List<PropertiesPanel> categoriesPanels = new ArrayList<>();\n            if (providers.size() == 1) {\n                categoriesPanels.add(panels.get(i));\n            } else {\n                MultiPropertiesPanel multiPanel = (MultiPropertiesPanel)panels.get(i);\n                categoriesPanels.addAll(multiPanel.getPanels());\n            }\n            for (int j = 0; j < providers.size(); j++)\n                providers.get(j).propertiesChanged(categoriesPanels.get(j), dataSource);\n        }\n    }\n\n\n    void selectCategory(int category) {\n        Integer tabIndex = categories.get(category);\n        if (tabIndex != null) tabbedPane.setSelectedIndex(tabIndex);\n    }\n\n\n    private void registerListeners() {\n        for (PropertiesPanel panel : panels)\n            panel.addChangeListener(listener);\n    }\n\n    private void unregisterListeners() {\n        for (PropertiesPanel panel : panels)\n            panel.removeChangeListener(listener);\n    }\n\n    private void update() {\n        for (PropertiesPanel panel : panels)\n            if (!panel.settingsValid()) {\n                setSettingsValid(false);\n                return;\n            }\n        setSettingsValid(true);\n    }\n\n    private void initComponents() {\n        tabbedPane = new JTabbedPane();\n        tabbedPane.setFocusable(false);\n        for (int i = 0; i < panels.size(); i++) {\n            PropertiesPanel panel = panels.get(i);\n            PropertiesProvider provider = groups.get(i).get(0);\n            ScrollableContainer c = new ScrollableContainer(panel);\n            c.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));\n            c.setViewportBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));\n            categories.put(provider.getPropertiesCategory(), tabbedPane.getTabCount());\n            tabbedPane.addTab(provider.getPropertiesName(), null, c,\n                              provider.getPropertiesDescription());\n        }\n\n        setLayout(new BorderLayout());\n        add(tabbedPane, BorderLayout.CENTER);\n    }\n\n\n    private static <Y extends DataSource> List<List<PropertiesProvider<Y>>>\n            createGroups(List<PropertiesProvider<Y>> providers) {\n        \n        providers.sort(new CategoriesComparator());\n\n        List<List<PropertiesProvider<Y>>> groupedProviders = new ArrayList<>();\n        int currentCategory = -1;\n        List<PropertiesProvider<Y>> currentGroup = null;\n        for (PropertiesProvider<Y> provider : providers) {\n            int providerCategory = provider.getPropertiesCategory();\n            if (currentGroup == null || providerCategory != currentCategory) {\n                currentCategory = providerCategory;\n                if (currentGroup != null)\n                    Collections.sort(currentGroup, Positionable.COMPARATOR);\n                currentGroup = new ArrayList<>();\n                groupedProviders.add(currentGroup);\n            }\n            if (currentGroup != null && currentCategory == providerCategory)\n                currentGroup.add(provider);\n        }\n        if (currentGroup != null)\n            Collections.sort(currentGroup, Positionable.COMPARATOR);\n\n        return groupedProviders;\n    }\n\n    private static <Y extends DataSource> List<PropertiesPanel>\n            createPanels(List<List<PropertiesProvider<Y>>> groups, Y dataSource) {\n\n        List<PropertiesPanel> panels = new ArrayList<>(groups.size());\n\n        for (List<PropertiesProvider<Y>> group : groups)\n            if (group.size() == 1)\n                panels.add(group.get(0).createPanel(dataSource));\n            else\n                panels.add(new MultiPropertiesPanel(group, dataSource));\n\n        return panels;\n    }\n\n\n    private static class MultiPropertiesPanel<Y extends DataSource> extends PropertiesPanel {\n\n        private static final Color separatorColor = separatorColor();\n        private static final Font separatorFont = separatorFont();\n\n        private final List<PropertiesPanel> panels;\n        private final ChangeListener listener = new ChangeListener() {\n                          public void stateChanged(ChangeEvent e) { update(); }\n                      };\n\n\n        MultiPropertiesPanel(List<PropertiesProvider<Y>> providers, Y dataSource) {\n            panels = new ArrayList<>(providers.size());\n            for (PropertiesProvider provider : providers)\n                panels.add(provider.createPanel(dataSource));\n            \n            initComponents(providers);\n            update();\n        }\n\n\n        public List<PropertiesPanel> getPanels() {\n            return panels;\n        }\n\n        \n        private void update() {\n            boolean valid = true;\n            for (PropertiesPanel panel : panels)\n                if (!panel.settingsValid()) {\n                    valid = false;\n                    break;\n                }\n            setSettingsValid(valid);\n        }\n\n        private void initComponents(List<PropertiesProvider<Y>> providers) {\n            setOpaque(false);\n            setBorder(BorderFactory.createEmptyBorder());\n            setLayout(new GridBagLayout());\n\n            int currentRow = 0;\n            int providerIndex = 1;\n            GridBagConstraints constraints;\n\n            for (PropertiesPanel panel : panels) {\n                constraints = createConstraints(currentRow++);\n                add(panel, constraints);\n                panel.addChangeListener(listener);\n\n                if (providerIndex < providers.size()) {\n                    PropertiesProvider provider = providers.get(providerIndex++);\n                    SectionSeparator separator = new SectionSeparator(provider.getPropertiesName());\n                    separator.setForeground(separatorColor);\n                    separator.setFont(separatorFont);\n                    separator.setToolTipText(provider.getPropertiesDescription());\n                    constraints = createConstraints(currentRow++);\n                    constraints.insets = new Insets(10, 0, 5, 0);\n                    add(separator, constraints);\n                }\n            }\n\n            constraints = createConstraints(currentRow++);\n            constraints.weightx = 1;\n            constraints.weighty = 1;\n            add(Spacer.create(), constraints);\n        }\n\n        private static GridBagConstraints createConstraints(int row) {\n            GridBagConstraints c = new GridBagConstraints();\n\n            c.gridx = 0;\n            c.gridy = row;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.fill = GridBagConstraints.BOTH;\n\n            return c;\n        }\n        \n    }\n\n    private static Color separatorColor() {\n        Color color = UIManager.getColor(\"TitledBorder.titleColor\"); // NOI18N\n        if (color == null) color = new JLabel().getForeground();\n        return color;\n    }\n\n    private static Font separatorFont() {\n        Font font = UIManager.getFont(\"TitledBorder.font\"); // NOI18N\n        if (font == null) font = new JLabel().getFont();\n        return font;\n    }\n    \n    private static class CategoriesComparator implements Comparator {\n\n        public int compare(Object o1, Object o2) {\n            PropertiesProvider p1 = (PropertiesProvider)o1;\n            PropertiesProvider p2 = (PropertiesProvider)o2;\n\n            int category1 = p1.getPropertiesCategory();\n            int category2 = p2.getPropertiesCategory();\n\n            if (category1 > category2) return 1;\n            if (category1 < category2) return -1;\n            return p1.getPropertiesName().compareTo(p2.getPropertiesName());\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/properties/PropertiesPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.properties;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.JPanel;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.plaf.PanelUI;\n\n/**\n * UI component to display and modify the properties. Provides validity\n * notification support to correctly handle actual state of the user-provided\n * data - valid or invalid.\n *\n * Note: if using custom JPanel instances in the PropertiesPanel be sure to use\n * JPanel.setOpaque(false) whenever possible to keep the settings UI consistent.\n * For some Look and Feels the PropertiesPanel container doesn't have a standard\n * JPanel background.\n *\n * @author Jiri Sedlacek\n */\npublic class PropertiesPanel extends JPanel {\n\n    private boolean settingsValid = true;\n    private List<ChangeListener> listeners = new ArrayList<>();\n\n\n    /**\n     * Returns true if settings defined by this Panel are valid.\n     * To be called in EDT.\n     *\n     * @return true if settings defined by this Panel are valid\n     */\n    public final boolean settingsValid() {\n        return settingsValid;\n    }\n\n    /**\n     * Add a ChangeListener. Use settingsValid() method to read the state.\n     * To be called in EDT.\n     *\n     * @param listener ChangeListener\n     */\n    public final void addChangeListener(ChangeListener listener) {\n        if (!listeners.contains(listener)) listeners.add(listener);\n    }\n\n    /**\n     * Remove a ChangeListener. To be called in EDT.\n     * @param listener ChangeListener\n     */\n    public final void removeChangeListener(ChangeListener listener) {\n        listeners.remove(listener);\n    }\n\n\n    /**\n     * Notifies the Panel that validity of the user-provided data changed.\n     * To be called in EDT.\n     *\n     * @param valid true if the current settings are valid, false otherwise\n     */\n    protected final void setSettingsValid(boolean valid) {\n        if (settingsValid != valid) {\n            settingsValid = valid;\n            fireStateChanged();\n        }\n    }\n\n\n    public void setUI(PanelUI ui) {\n        super.setUI(ui);\n        setOpaque(false);\n    }\n\n\n    private void fireStateChanged() {\n        for (ChangeListener listener : listeners)\n            listener.stateChanged(new ChangeEvent(this));\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/properties/PropertiesProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.properties;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\n\n/**\n * A provider to provide user-customizable properties for DataSources.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class PropertiesProvider<X extends DataSource> implements Positionable {\n\n    /**\n     * Key for the \"General\" properties category (always first if provided).\n     */\n    public static final int CATEGORY_GENERAL = Integer.MIN_VALUE;\n\n    private final String propertiesName;\n    private final String propertiesDescription;\n    private final int propertiesCategory;\n    private final int preferredPosition;\n\n\n    /**\n     * Creates new instance of PropertiesProvider with the provided name, optional\n     * description, properties category and preferred position of the properties\n     * within the category.<br>\n     * The propertiesCategory value defines position of the category among other\n     * categories. If more providers use the same category their position is\n     * defined by the preferredPosition value. The propertiesName value defines\n     * name of the category if this is the first provider for the category, otherwise\n     * it's used as name for the category section.\n     *\n     * @param propertiesName name of the provided properties\n     * @param propertiesDescription description of the provided properties or null\n     * @param propertiesCategory category of the provided properties\n     * @param preferredPosition preferred position of the properties panel in UI\n     */\n    public PropertiesProvider(String propertiesName, String propertiesDescription,\n                              int propertiesCategory, int preferredPosition) {\n        this.propertiesName = propertiesName;\n        this.propertiesDescription = propertiesDescription;\n        this.propertiesCategory = propertiesCategory;\n        this.preferredPosition = preferredPosition;\n    }\n\n\n    /**\n     * Returns name of the provided properties.\n     *\n     * @return name of the provided properties\n     */\n    public final String getPropertiesName() { return propertiesName; }\n\n    /**\n     * Returns description of the provided properties or null for no description.\n     *\n     * @return description of the provided properties or null for no description\n     */\n    public final String getPropertiesDescription() { return propertiesDescription; }\n\n    /**\n     * Returns category of the provided properties.\n     *\n     * @return category of the provided properties\n     */\n    public final int getPropertiesCategory() { return propertiesCategory; }\n\n    /**\n     * Returns preferred position of the properties section.\n     *\n     * @return preferred position of the properties section\n     */\n    public final int getPreferredPosition() { return preferredPosition; }\n\n\n    /**\n     * Returns true if this PropertiesProvider provides properties for the given\n     * DataSource. Default implementation always returns true. Note that if this\n     * method returns true for a given DataSource instance the createPanel(DataSource)\n     * method for the same instance cannot return null.\n     *\n     * @param dataSource DataSource for which to provide the properties (null means creating new DataSource)\n     * @return true if this PropertiesProvider provides properties for given DataSource, false otherwise\n     */\n    public boolean supportsDataSource(X dataSource) { return true; }\n\n    /**\n     * Returns a PropertiesPanel instance to create or edit the properties. If\n     * the provided DataSource is null it means that the DataSource is being\n     * created and the properties will define the initial state. Otherwise the\n     * DataSource properties are being edited.\n     *\n     * Note: if using custom JPanel instances in the PropertiesPanel be sure to use\n     * JPanel.setOpaque(false) whenever possible to keep the settings UI consistent.\n     * For some Look and Feels the PropertiesPanel container doesn't have a standard\n     * JPanel background.\n     *\n     * @param dataSource DataSource to edit the properties or null\n     * @return PropertiesPanel instance to create or edit the properties\n     */\n    public abstract PropertiesPanel createPanel(X dataSource);\n\n\n    /**\n     * Called when a valid PropertiesPanel has been submitted by the user when\n     * creating a new DataSource. At this point the provider has a chance to\n     * store the properties for the DataSource. The properties should be stored\n     * into the DataSource's storage (use dataSource.getStorage()) to ensure they\n     * will be always available for persistent DataSources.\n     *\n     * @param panel user-submitted PropertiesPanel\n     * @param dataSource newly created DataSource\n     */\n    public abstract void propertiesDefined(PropertiesPanel panel, X dataSource);\n\n    /**\n     * Called when a valid PropertiesPanel has been submitted by the user when\n     * editing an existing DataSource. At this point the provider has a chance\n     * to update the properties for the DataSource. The properties should be stored\n     * into the DataSource's storage (use dataSource.getStorage()) to ensure they\n     * will be always available for persistent DataSources.\n     *\n     * @param panel user-submitted PropertiesPanel\n     * @param dataSource edited existing DataSource\n     */\n    public abstract void propertiesChanged(PropertiesPanel panel, X dataSource);\n\n    /**\n     * Called when a PropertiesPanel has been cancelled by the user. At this point\n     * the provider has a chance to perform eventual cleanup.\n     *\n     * @param panel user-cancelled PropertiesPanel\n     * @param dataSource DataSource for which the panel has been cancelled or null if no DataSource has been created\n     */\n    public abstract void propertiesCancelled(PropertiesPanel panel, X dataSource);\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/properties/PropertiesSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.properties;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * Entrypoint for customization of DataSource properties. PropertiesProvider\n * instances should be registered/unregistered using the registerPropertiesProvider\n * and unregisterPropertiesProvider methods.\n * \n * DataSource providers displaying a dialog supporting user-customizable properties\n * should use getCustomizer(Class) method to get the properties UI.\n *\n * @author Jiri Sedlacek\n */\npublic final class PropertiesSupport {\n\n    private static PropertiesSupport INSTANCE;\n\n    private final Map<PropertiesProvider, Class<? extends DataSource>> providers =\n            Collections.synchronizedMap(new HashMap<>());\n\n\n    /**\n     * Returns singleton instance of PropertiesSupport.\n     *\n     * @return singleton instance of PropertiesSupport\n     */\n    public static synchronized PropertiesSupport sharedInstance() {\n        if (INSTANCE == null) INSTANCE = new PropertiesSupport();\n        return INSTANCE;\n    }\n\n\n    /**\n     * Registers a PropertiesProvider for a concrete DataSource type.\n     *\n     * @param <X> any DataSource type\n     * @param provider PropertiesProvider to be registered\n     * @param scope type of DataSource supported by the PropertiesProvider\n     */\n    public <X extends DataSource> void registerPropertiesProvider(\n                                  PropertiesProvider<X> provider, Class<X> scope) {\n        providers.put(provider, scope);\n    }\n\n    /**\n     * Unregisters the PropertiesProvider.\n     *\n     * @param <X> any DataSource type\n     * @param provider PropertiesProvider to unregister\n     */\n    public <X extends DataSource> void unregisterPropertiesProvider(\n                                  PropertiesProvider<X> provider) {\n        providers.remove(provider);\n    }\n\n\n    /**\n     * Returns true if there's at least one PropertiesProvider providing properties\n     * for the DataSource type, false otherwise.\n     *\n     * @param <X> any DataSource type\n     * @param type type of the DataSource to be checked\n     * @return true if there's at least one PropertiesProvider providing properties for the DataSource type, false otherwise\n     */\n    public <X extends DataSource> boolean hasProperties(Class<X> type) {\n        return hasProperties(null, type);\n    }\n\n    /**\n     * Returns true if there's at least one PropertiesProvider providing properties\n     * for the DataSource, false otherwise.\n     *\n     * @param <X> any DataSource type\n     * @param dataSource DataSource to be checked\n     * @return true if there's at least one PropertiesProvider providing properties for the DataSource, false otherwise\n     */\n    public <X extends DataSource> boolean hasProperties(X dataSource) {\n        if (dataSource == null) throw new IllegalArgumentException(\"DataSource cannot be null\"); // NOI18N\n        return hasProperties(dataSource, (Class<X>)dataSource.getClass());\n    }\n\n    /**\n     * Returns an UI component to display user-customizable properties for the\n     * provided DataSource type. Use hasProperties(Class) method to check if there\n     * are any customizable properties for the given DataSource type. For no\n     * properties available the created PropertiesCustomizer is empty.\n     *\n     * @param <X> any DataSource type\n     * @param type type of the DataSource to customize\n     * @return UI component to display user-customizable properties for the provided DataSource type\n     */\n    public <X extends DataSource> PropertiesCustomizer<X> getCustomizer(Class<X> type) {\n        return getCustomizer(null, type);\n    }\n\n    /**\n     * Opens Properties window of the DataSource. The first category is selected.\n     *\n     * @param dataSource DataSource for which to open the Properties window\n     */\n    public void openProperties(DataSource dataSource) {\n        openProperties(dataSource, PropertiesProvider.CATEGORY_GENERAL);\n    }\n\n    /**\n     * Opens Properties window of the DataSource and selects the provided category\n     * if available.\n     *\n     * @param dataSource DataSource for which to open the Properties window\n     */\n    public void openProperties(DataSource dataSource, int propertiesCategory) {\n        if (dataSource == null) throw new IllegalArgumentException(\"DataSource cannot be null\"); // NOI18N\n        PropertiesConfigurator.editProperties(dataSource, propertiesCategory);\n    }\n\n\n    <X extends DataSource> PropertiesCustomizer<X> getCustomizer(X dataSource, Class<X> type) {\n        return new PropertiesCustomizer<>(dataSource, type);\n    }\n\n\n    <X extends DataSource> List<PropertiesProvider<X>> getProviders(X dataSource, Class<X> type) {\n        Map<PropertiesProvider, Class<? extends DataSource>> providersCopy = new HashMap<>();\n        synchronized(providers) { providersCopy.putAll(providers); }\n\n        if (dataSource != null) type = (Class<X>)dataSource.getClass();\n\n        List<PropertiesProvider<X>> compatibleProviders = new ArrayList<>();\n        Set<Map.Entry<PropertiesProvider,Class<? extends DataSource>>> providersSet = providersCopy.entrySet();\n        for (Map.Entry<PropertiesProvider,Class<? extends DataSource>> entry : providersSet) {\n            PropertiesProvider provider = entry.getKey();\n            if (entry.getValue().isAssignableFrom(type) &&\n                provider.supportsDataSource(dataSource))\n                    compatibleProviders.add(provider);\n        }\n        return compatibleProviders;\n    }\n\n    private <X extends DataSource> boolean hasProperties(X dataSource, Class<X> type) {\n        return !getProviders(dataSource, type).isEmpty();\n    }\n\n\n    private PropertiesSupport() {}\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/properties/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Support for user-customizable properties for DataSources.\n *\n * The properties are meant to provide configuration info for DataSource setup\n * like jstatd connections for a Host or JMX connection setup for JMX applications.\n * <br><br>\n * The main difference between properties and DataSourceView is that the properties\n * define or display configuration of the DataSource whereas the DataSourceView\n * displays state of the DataSource typically obtained using some kind of (more or\n * less slow) connection to the DataSource.\n */\npackage org.graalvm.visualvm.core.properties;\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/scheduler/DefaultScheduledTask.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core.scheduler;\n\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport java.lang.ref.WeakReference;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.locks.ReadWriteLock;\nimport java.util.concurrent.locks.ReentrantReadWriteLock;\n\n\n/**\n * A default implementation of the <code>ScheduledTask</code>\n * @author Jaroslav Bachorik\n */\nclass DefaultScheduledTask implements ScheduledTask, SchedulerTask {\n    static private final Map<Quantum, WeakReference<SchedulingPipe>> pipeMap = new HashMap<>();\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);\n    private final ReadWriteLock intervalLock = new ReentrantReadWriteLock();\n\n    // @GuardedBy intervalLock\n    private Quantum interval;\n    private SchedulerTask delegateTask;\n    private Quantum suspendedFrom = Quantum.SUSPENDED;\n\n    private SchedulingPipe pipe = null;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    DefaultScheduledTask(Quantum interval, SchedulerTask task) {\n        delegateTask = task;\n        setInterval(interval);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    /**\n     * @see org.graalvm.visualvm.core.scheduler.ScheduledTask#setInterval(Quantum)\n     */\n    public void setInterval(Quantum interval) {\n        intervalLock.writeLock().lock();\n\n        Quantum oldInterval = interval;\n\n        try {\n            oldInterval = this.interval;\n\n            synchronized(pipeMap) {\n                WeakReference<SchedulingPipe> oldPipeRef = pipeMap.get(oldInterval);\n                WeakReference<SchedulingPipe> newPipeRef = pipeMap.get(interval);\n\n                SchedulingPipe oldPipe = oldPipeRef != null ? oldPipeRef.get() : null;\n                SchedulingPipe newPipe = newPipeRef != null ? newPipeRef.get() : null;\n                if (oldPipe != null) {\n                    oldPipe.removeTask(this);\n                }\n                if (newPipe == null && interval != Quantum.SUSPENDED) {\n                    newPipe = new SchedulingPipe(interval);\n                    pipeMap.put(interval, new WeakReference<>(newPipe));\n                }\n                if (newPipe != null) {\n                    newPipe.addTask(this);\n                }\n            }\n            this.interval = interval;\n        } finally {\n            intervalLock.writeLock().unlock();\n        }\n\n        pcs.firePropertyChange(INTERVAL_PROPERTY, oldInterval, interval);\n    }\n\n    /**\n     * @see org.graalvm.visualvm.core.scheduler.ScheduledTask#getInterval()\n     */\n    public Quantum getInterval() {\n        intervalLock.readLock().lock();\n\n        try {\n            return interval;\n        } finally {\n            intervalLock.readLock().unlock();\n        }\n    }\n\n    /**\n     * @see PropertyChangeSupport#addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)\n     */\n    public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {\n        pcs.addPropertyChangeListener(propertyName, listener);\n    }\n\n    /**\n     * @see PropertyChangeSupport#addPropertyChangeListener(java.beans.PropertyChangeListener)\n     */\n    public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {\n        pcs.addPropertyChangeListener(listener);\n    }\n\n    /**\n     * @see PropertyChangeSupport#hasListeners(java.lang.String)\n     */\n    public synchronized boolean hasListeners(String propertyName) {\n        return pcs.hasListeners(propertyName);\n    }\n\n    /**\n     * @see PropertyChangeSupport#removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)\n     */\n    public synchronized void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {\n        pcs.removePropertyChangeListener(propertyName, listener);\n    }\n\n    /**\n     * @see PropertyChangeSupport#removePropertyChangeListener(java.beans.PropertyChangeListener)\n     */\n    public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {\n        pcs.removePropertyChangeListener(listener);\n    }\n\n    /**\n     * @see org.graalvm.visualvm.core.scheduler.ScheduledTask#suspend()\n     */\n    public void suspend() {\n        if (suspendedFrom.equals(Quantum.SUSPENDED)) suspendedFrom = getInterval();\n        setInterval(Quantum.SUSPENDED);\n    }\n\n    /**\n     * @see ScheduledTask#resume()\n     */\n    public void resume() {\n        setInterval(suspendedFrom);\n        suspendedFrom = Quantum.SUSPENDED;\n    }\n\n    /**\n     * @see ScheduledTask#isSuspended()\n     */\n    public boolean isSuspended() {\n        return interval.equals(Quantum.SUSPENDED);\n    }\n    \n    /**\n     * @see org.graalvm.visualvm.core.scheduler.SchedulerTask#onSchedule(long)\n     */\n    public void onSchedule(long timeStamp) {\n        delegateTask.onSchedule(timeStamp);\n    }\n\n    void setPipe(SchedulingPipe pipe) {\n        this.pipe = pipe;\n    }\n\n    SchedulingPipe getPipe() {\n        return pipe;\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/scheduler/Quantum.java",
    "content": "/*\n * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.scheduler;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * This class {@linkplain TimeUnit} and provides easy conversion and comparation\n * between various units\n * @author Jaroslav Bachorik\n */\npublic class Quantum {\n    final public static Quantum SUSPENDED = new Quantum(TimeUnit.NANOSECONDS, -1);\n\n    /**\n     * Read-only field - the {@linkplain TimeUnit} used in the Quantum\n     */\n    final public TimeUnit unit;\n    /**\n     * Read-only field - the interval\n     */\n    final public int interval;\n\n    /**\n     * Sets-up a new quantum\n     * @param unit The {@linkplain TimeUnit} to use\n     * @param interval The interval\n     */\n    public Quantum(TimeUnit unit, int interval) {\n        this.unit = unit;\n        this.interval = interval;\n    }\n\n    /**\n     * Factory method - creates a new quantum given the number of seconds\n     * @param interval The number of seconds\n     * @return Returns new instance of {@linkplain Quantum}\n     */\n    public static Quantum seconds(int interval) {\n        return new Quantum(TimeUnit.SECONDS, interval);\n    }\n    \n    @Override\n    public boolean equals(Object obj) {\n        if (obj == null) {\n            return false;\n        }\n        if (getClass() != obj.getClass()) {\n            return false;\n        }\n        final Quantum other = (Quantum) obj;\n        \n        if (this.getNanos() != other.getNanos()) {\n            return false;\n        }\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        return (int)(getNanos() % 321721);\n    }\n    \n    private long getNanos() {\n        long multiplier = 1;\n        switch(unit) {\n            case MICROSECONDS: {\n                multiplier = 1000;\n                break;\n            }\n            case MILLISECONDS: {\n                multiplier = 1000 * 1000;\n                break;\n            }\n            case SECONDS: {\n                multiplier = 1000 * 1000 * 1000;\n                break;\n            }\n            case MINUTES: {\n                multiplier = 60 * 1000 * 1000 * 1000;\n                break;\n            }\n            case HOURS: {\n                multiplier = 60 * 60 * 1000 * 1000 * 1000;\n                break;\n            }\n            case DAYS: {\n                multiplier = 24 * 60 * 1000 * 1000 * 1000;\n                break;\n            }\n        }\n        return interval * multiplier;\n    }\n\n    @Override\n    public String toString() {\n        return interval + unit.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/scheduler/ScheduledTask.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core.scheduler;\n\n\n/**\n * A task scheduled within the <code>Scheduler</code> service\n * @author Jaroslav Bachorik\n */\npublic interface ScheduledTask {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n    /**\n     * Property-change support\n     */\n    public static final String INTERVAL_PROPERTY = \"Task.Interval\"; // NOI18N\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Modifies the interval the task is scheduled to run at\n     * @param quantum The new interval\n     */\n    void setInterval(Quantum quantum);\n\n    /**\n     * The interval the task is scheduled to run at\n     * @return Returns the number of seconds between two runs\n     */\n    Quantum getInterval();\n\n    /**\n     * Suspends the task\n     * A shortcut to calling <code>setInterval(Quantum.SUSPENDED)</code>\n     */\n    void suspend();\n    \n    /**\n     * Resumes a previously suspended task\n     */\n    void resume();\n    \n    /**\n     * Indicates the suspension status of the task\n     * @return Returns the suspension status of the task\n     */\n    boolean isSuspended();\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/scheduler/Scheduler.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core.scheduler;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.logging.Logger;\n\n/**\n * An interval based scheduler service\n * Used to execute various tasks at the predefined interval\n * There is supposed to be only one instance of this class accesible vie <code>getSharedInstance()</code>\n * @author Jaroslav Bachorik\n */\npublic class Scheduler {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n    private static final Logger LOGGER = Logger.getLogger(Scheduler.class.getName());\n    private static final Scheduler INSTANCE = new Scheduler();\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n    private final ExecutorService immediateTaskService = Executors.newCachedThreadPool();\n    \n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n    private Scheduler() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    /**\n     * Singleton accessor\n     * @return Returns the shared instance of scheduler service\n     */\n    public static final Scheduler sharedInstance() {\n        return INSTANCE;\n    }\n\n    /**\n     * Schedules a new task to be executed with the given interval\n     * The newly scheduled task is exeucted out-of-order at the moment of scheduling it\n     * This operation's result should be cached by the caller;otherwise the task will get unscheduled immediately\n     * @param task The task to be executed\n     * @param interval The interval to execute the task\n     * @return Returns an instance of <code>ScheduledTask</code> that can be used to later modify the interval of execution\n     */\n    public final ScheduledTask schedule(SchedulerTask task, Quantum interval) {\n        return schedule(task, interval, true);\n    }\n\n    /**\n     * Schedules a new task to be executed with the given interval\n     * This operation's result should be cached by the caller;otherwise the task will get unscheduled immediately\n     * @param task The task to be executed\n     * @param interval The interval to execute the task\n     * @param immediate Tells whether the newly scheduled task is exeucted out-of-order at the moment of scheduling it\n     * @return Returns an instance of <code>ScheduledTask</code> that can be used to later modify the interval of execution\n     */\n    public final ScheduledTask schedule(final SchedulerTask task, final Quantum interval, boolean immediate) {\n        boolean suspended = interval.equals(Quantum.SUSPENDED);\n        if (immediate && !suspended) {\n            immediateTaskService.submit(new Runnable() {\n                public void run() {\n                    task.onSchedule(System.currentTimeMillis());\n                }\n            });\n        }\n\n        DefaultScheduledTask scheduled = new DefaultScheduledTask(interval, task);\n\n        return scheduled;\n    }\n\n    /**\n     * Unschedules an instance of <code>Scheduled</code> class\n     * @param task The task to be unscheduled\n     */\n    public final void unschedule(final ScheduledTask task) {\n        if (task == null) return;\n        task.suspend();\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/scheduler/SchedulerTask.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core.scheduler;\n\n\n/**\n * This interface represents a task that is accepted by the <code>Scheduler</code> service\n * @author Jaroslav Bachorik\n */\npublic interface SchedulerTask {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Scheduler notification\n     * @param timeStamp The timestamp of the moment the notification has been created\n     */\n    void onSchedule(long timeStamp);\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/scheduler/SchedulingPipe.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.scheduler;\n\nimport java.lang.ref.WeakReference;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Set;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.ScheduledFuture;\nimport java.util.concurrent.locks.ReadWriteLock;\nimport java.util.concurrent.locks.ReentrantReadWriteLock;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n/**\n * Scheduling pipe maintains a list of {@linkplain ScheduledTask} instances\n * for a certain scheduling interval\n * <p>It allows addition and removal of the tasks and takes care of creating\n * and releasing appropriate scheduled executors</p>\n * \n * @author Jaroslav Bachorik <jaroslav.bachorik@sun.com>\n */\nfinal class SchedulingPipe {\n    private static final Logger LOGGER = Logger.getLogger(SchedulingPipe.class.getName());\n\n    final private Object pipeLock = new Object();\n    final private ReadWriteLock tasksLock = new ReentrantReadWriteLock();\n\n    // @GuardedBy pipeLock\n    private ScheduledFuture<?> pipeFuture = null;\n\n    final private static ScheduledExecutorService schedulerService = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());\n    final private static ExecutorService dispatcher = Executors.newCachedThreadPool();\n    \n    // @GuardedBy tasksLock\n    final private Set<WeakReference<DefaultScheduledTask>> tasks = new HashSet<>();\n\n    private Quantum interval;\n\n    SchedulingPipe(Quantum interval) {\n        this.interval = interval;\n    }\n\n    void addTask(DefaultScheduledTask task) {\n        tasksLock.writeLock().lock();\n        try {\n            if (tasks.isEmpty()) {\n                startPipe();\n            }\n            tasks.add(new WeakReference<>(task));\n        } finally {\n            tasksLock.writeLock().unlock();\n        }\n    }\n\n    private void startPipe() {\n        synchronized (pipeLock) {\n            pipeFuture = schedulerService.scheduleAtFixedRate(new Runnable() {\n\n                public void run() {\n                    tasksLock.writeLock().lock();\n                    try {\n                        final long timeStamp = System.currentTimeMillis();\n                        for (Iterator<WeakReference<DefaultScheduledTask>> iter = tasks.iterator(); iter.hasNext();) {\n                            WeakReference<DefaultScheduledTask> ref = iter.next();\n                            final DefaultScheduledTask t = ref.get();\n                            if (t != null) {\n                                dispatcher.submit(new Runnable() {\n\n                                    public void run() {\n                                        try {\n                                            t.onSchedule(timeStamp);\n                                        } catch (Throwable e) {\n                                            LOGGER.log(Level.SEVERE, null, e);\n                                        }\n                                    }\n                                });\n                            } else {\n                                iter.remove();\n                            }\n                        }\n                        if (tasks.isEmpty()) {\n                            synchronized (pipeLock) {\n                                pipeFuture.cancel(false);\n                                pipeFuture = null;\n                            }\n                        }\n                    } finally {\n                        tasksLock.writeLock().unlock();\n                    }\n                }\n            }, interval.interval, interval.interval, interval.unit);\n        }\n    }\n\n    void removeTask(DefaultScheduledTask task) {\n        tasksLock.writeLock().lock();\n        try {\n            for(Iterator<WeakReference<DefaultScheduledTask>> iter = tasks.iterator();iter.hasNext();) {\n                WeakReference<DefaultScheduledTask> ref = iter.next();\n                DefaultScheduledTask t = ref.get();\n                if (t == null || t.equals(task)) {\n                    iter.remove();\n                }\n            }\n        } finally {\n            tasksLock.writeLock().unlock();\n        }\n        if (tasks.isEmpty()) {\n            synchronized(pipeLock) {\n                pipeFuture.cancel(false);\n                pipeFuture = null;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/scheduler/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Support for executing scheduled tasks in given intervals synchronously\n * Eg. all tasks scheduled to execute in 5 minutes interval will be executed\n * in one batch once the interval times-out, thus receiving the same timestamp\n */\npackage org.graalvm.visualvm.core.scheduler;\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_Snapshots=Snapshots\n\nLBL_Saving=Saving {0}...\nLBL_CannotSave=Snapshot cannot be saved.\n\nLBL_SourceProperties=Source\nDESCR_SourceProperties=File or directory of the snapshot\nLBL_File=File\\:\nLBL_Directory=Directory\\:\nLBL_NoFile=<no file>\nLBL_UnavailableFile=<not available>\n\nACT_SortSnapshots=Sort &Snapshots By\nACT_TimeAdded=&Time Added\nACT_DisplayName=&Display Name\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/GeneralPropertiesProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.snapshot;\n\nimport org.graalvm.visualvm.core.properties.PropertiesPanel;\nimport org.graalvm.visualvm.core.properties.PropertiesProvider;\nimport java.awt.BorderLayout;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.io.File;\nimport java.io.IOException;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JTextField;\nimport javax.swing.plaf.TextUI;\nimport javax.swing.plaf.basic.BasicTextFieldUI;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass GeneralPropertiesProvider extends PropertiesProvider<Snapshot> {\n\n    GeneralPropertiesProvider() {\n        super(NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_SourceProperties\"), // NOI18N\n              NbBundle.getMessage(GeneralPropertiesProvider.class, \"DESCR_SourceProperties\"), // NOI18N\n              CATEGORY_GENERAL, 50);\n    }\n\n\n    public PropertiesPanel createPanel(final Snapshot dataSource) {\n        PropertiesPanel panel = new PropertiesPanel();\n        panel.setLayout(new BorderLayout());\n        \n        JLabel l = new JLabel();\n        l.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));\n        panel.add(l, BorderLayout.WEST);\n\n        JTextField f = new JTextField() {\n            public void setUI(TextUI ui) { super.setUI(new BasicTextFieldUI()); }\n        };\n        f.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));\n        f.setEditable(false);\n        f.setOpaque(false);\n        f.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));\n        Dimension size = f.getPreferredSize();\n        size.width = 1;\n        f.setPreferredSize(size);\n        f.setMinimumSize(size);\n        panel.add(f, BorderLayout.CENTER);\n\n        File file = dataSource.getFile();\n        if (file == null) {\n            l.setText(NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_File\")); // NOI18N\n            f.setText(NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_NoFile\")); // NOI18N\n        } else if (file.isFile()) {\n            String path = null;\n            try { path = file.getCanonicalPath(); }\n            catch (IOException e) { path = file.getAbsolutePath(); }\n            l.setText(NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_File\")); // NOI18N\n            f.setText(path);\n        } else if (file.isDirectory()) {\n            String path = null;\n            try { path = file.getCanonicalPath(); }\n            catch (IOException e) { path = file.getAbsolutePath(); }\n            l.setText(NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_Directory\")); // NOI18N\n            f.setText(path);\n        } else {\n            l.setText(NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_File\")); // NOI18N\n            f.setText(NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_UnavailableFile\")); // NOI18N\n        }\n\n        f.setCaretPosition(0);\n        \n        return panel;\n    }\n\n\n    public boolean supportsDataSource(Snapshot dataSource) { return dataSource != null; }\n\n    public void propertiesDefined(PropertiesPanel panel, Snapshot dataSource) {}\n\n    public void propertiesChanged(PropertiesPanel panel, Snapshot dataSource) {}\n\n    public void propertiesCancelled(PropertiesPanel panel, Snapshot dataSource) {}\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/RegisteredSnapshotCategories.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.snapshot;\n\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n// TODO: synchronize\n/**\n * A repository of registered SnapshotCategory instances.\n *\n * @author Jiri Sedlacek\n */\npublic final class RegisteredSnapshotCategories {\n\n    private static RegisteredSnapshotCategories sharedInstance;\n\n    private final Set<SnapshotCategoriesListener> listeners = Collections.synchronizedSet(new HashSet<>());\n    private final Set<SnapshotCategory<?>> categories = Collections.synchronizedSet(new HashSet<>());\n\n\n    /**\n     * Returns singleton instance of RegisteredSnapshotCategories.\n     * \n     * @return singleton instance of RegisteredSnapshotCategories.\n     */\n    public synchronized static RegisteredSnapshotCategories sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new RegisteredSnapshotCategories();\n        return sharedInstance;\n    }\n\n\n    /**\n     * Adds a listener for changes of registered snapshot categories.\n     * \n     * @param listener listener for changes of registered snapshot categories.\n     */\n    public void addCategoriesListener(SnapshotCategoriesListener listener) {\n        listeners.add(listener);\n    }\n    \n    /**\n     * Removes a listener for changes of registered snapshot categories.\n     * \n     * @param listener listener for changes of registered snapshot categories.\n     */\n    public void removeCategoriesListener(SnapshotCategoriesListener listener) {\n        listeners.remove(listener);\n    }\n    \n\n    /**\n     * Registers a SnapshotCategory.\n     * \n     * @param category SnapshotCategory.\n     */\n    public void registerCategory(SnapshotCategory category) {\n        categories.add(category);\n        fireCategoryRegistered(category);\n    }\n\n    /**\n     * Unregisters a SnapshotCategory.\n     * \n     * @param category SnapshotCategory.\n     */\n    public void unregisterCategory(SnapshotCategory category) {\n        categories.remove(category);\n        fireCategoryUnregistered(category);\n    }\n\n    /**\n     * Returns list of registered SnapshotCategory instances to be shown in UI.\n     * \n     * @return list of registered SnapshotCategory instances to be shown in UI.\n     */\n    public List<SnapshotCategory<? extends Snapshot>> getVisibleCategories() {\n        List<SnapshotCategory<?>> allCategories = new ArrayList<>(categories);\n        List<SnapshotCategory<?>> visibleCategories = new ArrayList<>();\n        for (SnapshotCategory category : allCategories)\n            if (category.getPreferredPosition() != SnapshotCategory.POSITION_NONE)\n                visibleCategories.add(category);\n        \n        visibleCategories.sort(Positionable.COMPARATOR);\n        return visibleCategories;\n    }\n    \n    /**\n     * Returns list of registered SnapshotCategory instances capable of opening snapshot files.\n     * \n     * @return list of registered SnapshotCategory instances capable of opening snapshot files.\n     */\n    public List<SnapshotCategory> getOpenSnapshotCategories() {\n        List<SnapshotCategory> allCategories = new ArrayList<>(categories);\n        List<SnapshotCategory> openSnapshotCategories = new ArrayList<>();\n        for (SnapshotCategory category : allCategories)\n            if (category.supportsOpenSnapshot()) openSnapshotCategories.add(category);\n        \n        openSnapshotCategories.sort(Positionable.COMPARATOR);\n        return openSnapshotCategories;\n    }\n    \n    /**\n     * Returns list of all registered SnapshotCategory instances.\n     * \n     * @return list of all registered SnapshotCategory instances.\n     */\n    public List<SnapshotCategory> getAllCategories() {\n        List<SnapshotCategory> allCategories = new ArrayList<>(categories);\n        allCategories.sort(Positionable.COMPARATOR);\n        return allCategories;\n    }\n    \n    \n    private void fireCategoryRegistered(SnapshotCategory category) {\n        Set<SnapshotCategoriesListener> listenersSet = new HashSet<>(listeners);\n        for (SnapshotCategoriesListener listener : listenersSet)\n            listener.categoryRegistered(category);\n    }\n    \n    private void fireCategoryUnregistered(SnapshotCategory category) {\n        Set<SnapshotCategoriesListener> listenersSet = new HashSet<>(listeners);\n        for (SnapshotCategoriesListener listener : listenersSet)\n            listener.categoryUnregistered(category);\n    }\n    \n    \n    private RegisteredSnapshotCategories() {}\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/Snapshot.java",
    "content": "/*\n *  Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.snapshot;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport java.io.File;\nimport java.util.Objects;\n\n/**\n * Abstract implementation of Snapshot.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class Snapshot extends DataSource {\n    \n    /**\n     * Named property for snapshot file.\n     */\n    public static final String PROPERTY_FILE = \"prop_file\"; // NOI18N\n    \n    /**\n     * Named property to control whether the snapshot view will be closable.\n     * \n     * Value true means always closable, value false means never closable,\n     * any other value or property not defined means the default behavior.\n     */\n    protected static final String PROPERTY_VIEW_CLOSABLE = \"prop_view_closable\"; // NOI18N\n    \n    \n    private File file;\n    private final SnapshotCategory category;\n    \n    private String snapshotID;\n    \n    \n    /**\n     * Creates new instance of AbstractSnapshot with the data stored in a file.\n     * \n     * @param file file where snapshot is saved,\n     * @param category category of the snapshot.\n     */\n    public Snapshot(File file, SnapshotCategory category) {\n        this(file, category, null);\n    }\n    \n    /**\n     * Creates new instance of AbstractSnapshot with the data stored in a file and defined master.\n     * \n     * @param file file where snapshot is saved,\n     * @param category category of the snapshot,\n     * @param master DataSource in whose window the snapshot will be displayed.\n     */\n    public Snapshot(File file, SnapshotCategory category, DataSource master) {\n        super(master);\n        this.file = file;\n        this.category = category;\n    }\n    \n\n    /**\n     * Returns snapshot file or null if no file context is defined or snapshot doesn't support saving to file.\n     * \n     * @return snapshot file or null if no file context is defined or snapshot doesn't support saving to file.\n     */\n    public final File getFile() {\n        return file;\n    }\n    \n    /**\n     * Returns snapshot category.\n     * \n     * @return snapshot category.\n     */\n    public final SnapshotCategory getCategory() {\n        return category;\n    }\n    \n    /**\n     * Sets the file where data of this snapshot are stored.\n     * \n     * @param newFile file where data of this snapshot are stored.\n     */\n    protected final void setFile(File newFile) {\n        if (file == null && newFile == null) return;\n        File oldFile = file;\n        file = newFile;\n        if (oldFile == null) snapshotID = null;\n        getChangeSupport().firePropertyChange(PROPERTY_FILE, oldFile, newFile);\n    }\n    \n    /**\n     * Saves the snapshot to a directory.\n     * \n     * @param directory directory where to save the snapshot.\n     */\n    public void save(File directory) {\n        File f = getFile();\n        if (f != null && f.isFile()) {  \n            // File is not null and will be copied to the directory\n            File saveFile = Utils.getUniqueFile(directory, f.getName());    \n            Utils.copyFile(f, saveFile);\n            // If there are any custom properties defined, store them to <file>.properties\n            getStorage().saveCustomPropertiesTo(new File(saveFile.getAbsolutePath() + Storage.DEFAULT_PROPERTIES_EXT));\n        }\n    }\n    \n    /**\n     * Returns true if the snapshot supports saving to an external (user defined) destination, false otherwise.\n     * \n     * @return true if the snapshot supports saving to an external (user defined) destination, false otherwise.\n     */\n    public boolean supportsSaveAs() {\n        return false;\n    }\n    \n    /**\n     * Saves the snapshot to an external (user defined) destination.\n     * Default implementation does nothing, custom implementations should open\n     * a Save File dialog and save the snapshot to selected destination.\n     * Throws an UnsupportedOperationException if supportsSaveAs() returns false.\n     */\n    public void saveAs() {\n        throw new UnsupportedOperationException(\"Save as not supported\");   // NOI18N\n    }\n    \n    /**\n     * Returns true if the snapshot can be deleted by the user from UI, false otherwise.\n     * \n     * @return true if the snapshot can be deleted by the user from UI, false otherwise.\n     */\n    public boolean supportsDelete() {\n        return true;\n    }\n    \n    /**\n     * Deletes the snapshot.\n     */\n    public void delete() {\n        DataSourceWindowManager.sharedInstance().closeDataSource(this);\n        getOwner().getRepository().removeDataSource(this);\n    }\n    \n    \n    protected void remove() {\n        final File f = getFile();\n        if (f != null) Utils.FILE_QUEUE.post(new Runnable() {\n            public void run() { Utils.delete(f, true); }\n        });\n        setFile(null);\n        super.remove();\n    }\n    \n    protected Storage createStorage() {\n        File f = getFile();\n        \n        if (f != null) {\n            String customPropertiesFileName = f.getName() + Storage.DEFAULT_PROPERTIES_EXT;\n            if (f.isDirectory()) {\n                return new Storage(f, customPropertiesFileName);\n//                if (new File(f, customPropertiesFileName).exists()) return new Storage(f, customPropertiesFileName);\n//                else return new Storage(f);\n            } else if (f.isFile()) {\n                File directory = f.getParentFile();\n                return new Storage(directory, customPropertiesFileName);\n//                if (new File(directory, customPropertiesFileName).exists()) return new Storage(directory, customPropertiesFileName);\n//                else return new Storage(directory);\n            }\n        }\n        \n        return super.createStorage();\n    }\n\n    /**\n     * Returns true if the Snapshot is present in other Snapshot's repository, false otherwise.\n     *\n     * @return true if the Snapshot is present in other Snapshot's repository\n     */\n    protected final boolean isInSnapshot() {\n        return getOwner() instanceof Snapshot;\n    }\n    \n    \n    /**\n     * Returns ID of the Snapshot. The ID should be based on the snapshot file\n     * if available and will only be computed for the first non-null file.\n     *\n     * @return ID of the Snapshot\n     */\n    protected String computeSnapshotID() {\n        File f = getFile();\n        return f == null ? super.hashCode() + \"-no_file\" : f.getPath(); // NOI18N\n    }\n    \n    private String getSnapshotID() {\n        if (snapshotID == null) snapshotID = computeSnapshotID();\n        return snapshotID;\n    }\n    \n    \n    public boolean equals(Object o) {\n        if (!(o instanceof Snapshot)) return false;\n        return Objects.equals(getSnapshotID(), ((Snapshot)o).getSnapshotID());\n    }\n    \n    public int hashCode() {\n        return Objects.hashCode(getSnapshotID());\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/SnapshotCategoriesListener.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.snapshot;\n\n/**\n * Listener for changes of registered snapshot categories.\n *\n * @author Jiri Sedlacek\n */\npublic interface SnapshotCategoriesListener {\n    \n    /**\n     * Invoked when new SnapshotCategory is registered in RegisteredSnapshotCategories.\n     * \n     * @param category registered category.\n     */\n    public void categoryRegistered(SnapshotCategory category);\n    \n    /**\n     * Invoked when a SnapshotCategory is unregistered from RegisteredSnapshotCategories.\n     * \n     * @param category unregistered category.\n     */\n    public void categoryUnregistered(SnapshotCategory category);\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/SnapshotCategory.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.snapshot;\n\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport java.io.File;\nimport java.io.FilenameFilter;\nimport javax.swing.filechooser.FileFilter;\n\n\n/**\n * Category describing a snapshot type.\n * Category should return POSITION_NONE for getPreferredPosition() if it's not to be shown in UI.\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic abstract class SnapshotCategory<X extends Snapshot> implements Positionable {\n    \n    private static final String PREFIX_DIVIDER = \"-\";   // NOI18N\n    \n    /**\n     * Category won't be displayed in UI.\n     */\n    public static final int POSITION_NONE = Integer.MIN_VALUE;\n\n    private final String name;\n    private final Class<X> type;\n    private final String prefix;\n    private final String suffix;\n    private final int preferredPosition;\n\n    /**\n     * Creates new instance of SnapshotCategory.\n     * \n     * @param name name of the category,\n     * @param type type of snapshots described by this category,\n     * @param prefix prefix of files containing the snapshots (can be null),\n     * @param suffix suffix of files containing the snapshots (can be null).\n     * @param preferredPosition preferred position of this category within other categories when presented in UI.\n     */\n    public SnapshotCategory(String name, Class<X> type, String prefix, String suffix, int preferredPosition) {\n        super();\n        this.name = name;\n        this.type = type;\n        this.prefix = prefix;\n        this.suffix = suffix;\n        this.preferredPosition = preferredPosition;\n    }\n\n    /**\n     * Returns name of the category.\n     * \n     * @return name of the category.\n     */\n    public final String getName() {\n        return name;\n    }\n\n    /**\n     * Returns type of snapshots described by this category.\n     * \n     * @return type of snapshots described by this category.\n     */\n    public final Class<X> getType() {\n        return type;\n    }\n    \n    /**\n     * Returns preferred position of this category within other categories when presented in UI.\n     * \n     * @return preferred position of this category within other categories when presented in UI.\n     */\n    public final int getPreferredPosition() {\n        return preferredPosition;\n    }\n    \n    /**\n     * Returns true if the category can restore snapshot from a saved file, false otherwise.\n     * \n     * @return true if the category can restore snapshot from a saved file, false otherwise.\n     */\n    public boolean supportsOpenSnapshot() {\n        return false;\n    }\n    \n    /**\n     * Opens a saved snapshot.\n     * Default implementation does nothing, custom implementations should open\n     * an Open File dialog and open the chosen snapshot.\n     * Throws an UnsupportedOperationException if supportsOpenSnapshot() returns false.\n     * \n     * @param file saved snapshot.\n     */\n    public void openSnapshot(File file) {\n        throw new UnsupportedOperationException(\"Open snapshot not supported\"); // NOI18N\n    }\n    \n    \n    /**\n     * Returns prefix of files containing the snapshots.\n     * \n     * @return prefix of files containing the snapshots.\n     */\n    protected final String getPrefix() {\n        return prefix;\n    }\n    \n    /**\n     * Returns suffix of files containing the snapshots.\n     * \n     * @return suffix of files containing the snapshots.\n     */\n    protected final String getSuffix() {\n        return suffix;\n    }\n    \n    protected boolean isSnapshot(File file) {\n//        String pref = getPrefix();\n        String suff = getSuffix();\n        // Fix for #92 - supported snapshot is detected just based on the SUFFIX by default\n//        if (pref != null && !fileName.startsWith(pref + PREFIX_DIVIDER)) return false;\n        if (suff != null && !file.getName().endsWith(suff)) return false;\n        return true;\n    }\n    \n    protected boolean isSnapshot(String fileName) {\n        return isSnapshot(new File(fileName));\n    }\n    \n    protected String getBaseFileName(String fileName) {\n        String pref = getPrefix();\n        String suff = getSuffix();\n        if (pref != null && fileName.startsWith(pref + PREFIX_DIVIDER)) fileName = fileName.substring(pref.length() + 1);\n        if (suff != null && fileName.endsWith(suff)) fileName = fileName.substring(0, fileName.length() - suff.length());\n        return fileName;\n    }\n    \n    protected String getTimeStamp(String fileName) {\n        String timeStamp = null;\n        \n        try {\n            long time = Long.parseLong(getBaseFileName(fileName));\n            return SnapshotsSupport.getInstance().getTimeStamp(time);\n        } catch (NumberFormatException e) {}\n        \n        return timeStamp;\n    }\n    \n    /**\n     * Creates a unique name for a new snapshot.\n     * \n     * @return unique name for a new snapshot.\n     */\n    public String createFileName() {\n        String pref = getPrefix();\n        String suff = getSuffix();\n        String fileName = System.currentTimeMillis() + \"\";\n        if (pref != null) fileName = pref + PREFIX_DIVIDER + fileName;\n        if (suff != null) fileName = fileName + suff;\n        return fileName;\n    }\n    \n    /**\n     * Returns a FilenameFilter for the category.\n     * \n     * @return FilenameFilter for the category.\n     */\n    public FilenameFilter getFilenameFilter() {\n        return new FilenameFilter() {\n            public boolean accept(File dir, String name) {\n                return isSnapshot(new File(dir,name));\n            }\n        };\n    }\n    \n    /**\n     * Returns a FileFilter for the category.\n     * \n     * @return FileFilter for the category.\n     */\n    public FileFilter getFileFilter() {\n        return new FileFilter() {\n            public boolean accept(File f) {\n                return f.isDirectory() || isSnapshot(f);\n            }\n            public String getDescription() {\n                String suff = getSuffix();\n                return getName() + (suff != null ? \" (*\" + suff + \")\" : \"\");    // NOI18N\n            }\n        };\n    }\n    \n//    public FileView getFileView() {\n//        return new FileView() {\n////            public Icon getIcon(File f) {\n////                return new ImageIcon(SnapshotCategory.this.getI);\n////            }\n//            public String getName(File file) {\n//                if (isSnapshot(file)) return getDisplayName(file);\n//                else return null;\n//            }\n//        };\n//    }\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/SnapshotDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.snapshot;\n\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport java.awt.Image;\nimport java.io.File;\nimport org.openide.util.NbBundle;\n\n/**\n * Abstract implementation of DataSourceDescriptor for snapshots.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class SnapshotDescriptor<X extends Snapshot> extends DataSourceDescriptor<X> {\n    \n    /**\n     * Creates new instance of SnapshotDescriptor.\n     * \n     * @param snapshot Snapshot for the descriptor.\n     * @param icon icon for the Snapshot.\n     */\n    public SnapshotDescriptor(X snapshot, Image icon) {\n        this(snapshot, null, icon);\n    }\n\n    /**\n     * Creates new instance of SnapshotDescriptor.\n     *\n     * @param snapshot Snapshot for the descriptor.\n     * @param description description of the snapshot\n     * @param icon icon for the Snapshot.\n     */\n    public SnapshotDescriptor(X snapshot, String description, Image icon) {\n        super(snapshot, resolveSnapshotName(snapshot), description, icon,\n              resolvePosition(snapshot, POSITION_AT_THE_END, snapshot.\n              isInSnapshot()), EXPAND_NEVER);\n    }\n\n    /**\n     * Creates new instance of SnapshotDescriptor.\n     *\n     * @param snapshot snapshot.\n     * @param name snapshot name.\n     * @param description snapshot description.\n     * @param icon snapshot icon.\n     * @param position snapshot position.\n     * @param autoExpansionPolicy snapshot expansion policy.\n     */\n    public SnapshotDescriptor(X snapshot, String name, String description,\n                              Image icon, int position, int autoExpansionPolicy) {\n        super(snapshot, name, description, icon, position, autoExpansionPolicy);\n    }\n\n    /**\n     * Returns Snapshot name if available in Snapshot Storage as PROPERTY_NAME\n     * or generates new name using Snapshot's Category.\n     *\n     * @param snapshot Snapshot for which to resolve the name\n     * @return persisted Snapshot name if available or new generated name\n     */\n    protected static String resolveSnapshotName(Snapshot snapshot) {\n        String persistedName = resolveName(snapshot, null);\n        if (persistedName != null) return persistedName;\n        \n        File file = snapshot.getFile();\n        String fileName = file != null ? file.getName() :\n               NbBundle.getMessage(SnapshotDescriptor.class, \"LBL_NoFile\");    // NOI18N\n        SnapshotCategory category = snapshot.getCategory();\n        String name = \"[\" + category.getPrefix() + \"] \" + fileName; // NOI18N\n        \n        if (file != null && category.isSnapshot(file)) {\n            String timeStamp = category.getTimeStamp(fileName);\n            if (timeStamp != null) name = \"[\" + category.getPrefix() + \"] \" + timeStamp;    // NOI18N\n        }\n        \n        return name;\n    }\n    \n    /**\n     * Returns true if the snapshot can be renamed from UI, false otherwise.\n     * \n     * @return true if the snapshot can be renamed from UI, false otherwise\n     */\n    public boolean supportsRename() {\n        return true;\n    }\n\n    public boolean providesProperties() {\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/SnapshotView.java",
    "content": "/*\n * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core.snapshot;\n\nimport java.awt.Image;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\n\n/**\n * Abstract superclass of DataSourceView for a Snapshot.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class SnapshotView extends DataSourceView {\n    \n    public SnapshotView(Snapshot snapshot, String name, Image icon, int preferredPosition) {\n        super(snapshot, name, icon, preferredPosition, isClosableView(snapshot));\n    }\n    \n    public SnapshotView(Snapshot snapshot, String name, Image icon, int preferredPosition, boolean isClosable) {\n        super(snapshot, name, icon, preferredPosition, isClosable);\n    }\n    \n    \n    private static boolean isClosableView(Snapshot snapshot) {\n        String closable = snapshot.getStorage().getCustomProperty(Snapshot.PROPERTY_VIEW_CLOSABLE);\n        if (Boolean.TRUE.toString().equals(closable)) return true;\n        if (Boolean.FALSE.toString().equals(closable)) return false;\n        \n        // ProfilerSnapshot invisible\n        if (!snapshot.isVisible()) return false;\n        \n        // ProfilerSnapshot not in DataSources tree\n        DataSource owner = snapshot.getOwner();\n        if (owner == null) return false;\n        \n        while (owner != null && owner != DataSource.ROOT) {\n            // Subtree containing ProfilerSnapshot invisible\n            if (!owner.isVisible()) return false;\n            owner = owner.getOwner();\n        }\n        \n        // ProfilerSnapshot visible in DataSources tree\n        if (owner == DataSource.ROOT) return true;\n        \n        // ProfilerSnapshot not in DataSources tree\n        return false;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/SnapshotsContainer.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.snapshot;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\n/**\n * Toplevel node Snapshots in Applications window.\n *\n * @author Jiri Sedlacek\n */\npublic final class SnapshotsContainer extends DataSource {\n\n    private static SnapshotsContainer sharedInstance;\n\n    /**\n     * Returns singleton instance of SnapshotsContainer.\n     *\n     * @return singleton instance of SnapshotsContainer.\n     */\n    public static synchronized SnapshotsContainer sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new SnapshotsContainer();\n        return sharedInstance;\n    }\n\n\n    private SnapshotsContainer() {\n        DataSourceDescriptorFactory.getDefault().registerProvider(\n            new AbstractModelProvider<DataSourceDescriptor,DataSource>() {\n                public DataSourceDescriptor createModelFor(DataSource ds) {\n                    if (SnapshotsContainer.sharedInstance().equals(ds))\n                        return new SnapshotsContainerDescriptor();\n                    else return null;\n                }\n            }\n        );\n        DataSource.ROOT.getRepository().addDataSource(this);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/SnapshotsContainerDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.core.snapshot;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport java.awt.Image;\nimport java.util.Comparator;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * DataSourceDescriptor for Snapshots node in Applications window.\n *\n * @author Jiri Sedlacek\n */\npublic final class SnapshotsContainerDescriptor extends DataSourceDescriptor<SnapshotsContainer> {\n\n    private static final Image NODE_ICON = ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/core/ui/resources/snapshots.png\", true);  // NOI18N\n\n    SnapshotsContainerDescriptor() {\n        super(SnapshotsContainer.sharedInstance(), NbBundle.getMessage(\n              SnapshotsContainer.class, \"LBL_Snapshots\"), null, NODE_ICON, 30, // NOI18N\n              EXPAND_ON_EACH_FIRST_CHILD);\n        \n        // Initialize sorting\n        setChildrenComparator(SnapshotsSorting.instance().getInitialSorting());\n    }\n\n    /**\n     * Sets a custom comparator for sorting DataSources within the SnapshotsContainer.\n     * Use setChildrenComparator(null) to restore the default sorting.\n     *\n     * @param newComparator comparator for sorting DataSources within the SnapshotsContainer\n     */\n    public void setChildrenComparator(Comparator<DataSource> newComparator) {\n        super.setChildrenComparator(newComparator);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/SnapshotsSorting.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.snapshot;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport java.awt.Component;\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.prefs.Preferences;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JRadioButtonMenuItem;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.actions.Presenter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class SnapshotsSorting implements Presenter.Menu {\n\n    private static final String PROP_SNAPSHOTS_SORTING = \"Snapshots.sorting\"; // NOI18N\n\n    private static SnapshotsSorting instance;\n    \n    private static final Comparator<DataSource> BY_TIME_COMPARATOR = byTimeComparator();\n    private static final Comparator<DataSource> BY_NAME_COMPARATOR = byNameComparator();\n    private static final List<Comparator<DataSource>> COMPARATORS = new ArrayList<>();\n    static { COMPARATORS.add(BY_TIME_COMPARATOR); COMPARATORS.add(BY_NAME_COMPARATOR); }\n\n    private final Preferences prefs;\n\n    private JMenuItem presenter;\n    private final Sorter sorter;\n\n\n    public static synchronized SnapshotsSorting instance() {\n        if (instance == null) instance = new SnapshotsSorting();\n        return instance;\n    }\n\n    public JMenuItem getMenuPresenter() {\n        if (presenter == null) presenter = createPresenter();\n        return presenter;\n    }\n\n\n    Comparator<DataSource> getInitialSorting() {\n        return COMPARATORS.get(prefs.getInt(PROP_SNAPSHOTS_SORTING, COMPARATORS.\n                                            indexOf(BY_TIME_COMPARATOR)));\n    }\n\n\n    private JMenuItem createPresenter() {\n        final JMenu menu = new JMenu() {\n            protected void fireMenuSelected() {\n                Component[] items = getMenuComponents();\n                for (Component item : items)\n                    if (item instanceof SortAction)\n                        ((SortAction)item).updateAction();\n            }\n        };\n        Mnemonics.setLocalizedText(menu, NbBundle.getMessage(SnapshotsSorting.class,\n                                   \"ACT_SortSnapshots\")); // NOI18N\n\n        menu.add(new SortAction(NbBundle.getMessage(SnapshotsSorting.class,\n                                \"ACT_TimeAdded\"), BY_TIME_COMPARATOR, sorter)); // NOI18N\n        menu.add(new SortAction(NbBundle.getMessage(SnapshotsSorting.class,\n                                \"ACT_DisplayName\"), BY_NAME_COMPARATOR, sorter)); // NOI18N\n\n        return menu;\n    }\n    \n    private static Comparator<DataSource> byTimeComparator() {\n        return null;\n    }\n\n    private static Comparator<DataSource> byNameComparator() {\n        return new Comparator<DataSource>() {\n            public int compare(DataSource d1, DataSource d2) {\n                DataSourceDescriptor dd1 = DataSourceDescriptorFactory.getDescriptor(d1);\n                DataSourceDescriptor dd2 = DataSourceDescriptorFactory.getDescriptor(d2);\n\n                return dd1.getName().compareTo(dd2.getName());\n            }\n        };\n    }\n\n    private SnapshotsSorting() {\n        prefs = NbPreferences.forModule(SnapshotsSorting.class);\n\n        sorter = new Sorter() {\n            public void sort(Comparator<DataSource> comparator) {\n                DataSourceDescriptor d = DataSourceDescriptorFactory.getDescriptor(\n                                         SnapshotsContainer.sharedInstance());\n                if (d instanceof SnapshotsContainerDescriptor) {\n                    ((SnapshotsContainerDescriptor)d).setChildrenComparator(comparator);\n                    prefs.putInt(PROP_SNAPSHOTS_SORTING, COMPARATORS.indexOf(comparator));\n                }\n            }\n        };\n    }\n\n\n    private static class SortAction extends JRadioButtonMenuItem {\n\n        private final Sorter sorter;\n        private final Comparator<DataSource> comparator;\n        private boolean currentlySelected;\n\n        SortAction(String name, Comparator<DataSource> comparator, Sorter sorter) {\n            Mnemonics.setLocalizedText(this, name);\n            this.comparator = comparator;\n            this.sorter = sorter;\n        }\n\n        void updateAction() {\n            DataSourceDescriptor d = DataSourceDescriptorFactory.getDescriptor(\n                                     SnapshotsContainer.sharedInstance());\n            setEnabled(d instanceof SnapshotsContainerDescriptor);\n            currentlySelected = d.getChildrenComparator() == comparator;\n            setSelected(currentlySelected);\n        }\n\n        protected void fireActionPerformed(ActionEvent e) {\n            if (!currentlySelected) sorter.sort(comparator);\n        }\n\n    }\n\n    private static interface Sorter {\n\n        void sort(Comparator<DataSource> comparator);\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/SnapshotsSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.snapshot;\n\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.properties.PropertiesSupport;\nimport java.awt.Image;\nimport java.io.File;\nimport java.util.Date;\nimport javax.swing.JFileChooser;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n * Support for snapshots in VisualVM.\n *\n * @author Jiri Sedlacek\n */\npublic final class SnapshotsSupport {\n    \n    private static final Image SNAPSHOT_BADGE = ImageUtilities.loadImage(\"org/graalvm/visualvm/core/ui/resources/snapshotBadge.png\", true);    // NOI18N\n    \n    private static SnapshotsSupport instance;\n\n\n    /**\n     * Returns singleton instance of SnapshotsSupport.\n     * \n     * @return singleton instance of SnapshotsSupport.\n     */\n    public static synchronized SnapshotsSupport getInstance() {\n        if (instance == null) instance = new SnapshotsSupport();\n        return instance;\n    }\n    \n    \n    /**\n     * Saves the snapshot to a used-defined file (opens Save File dialog with defined caption).\n     * \n     * @param snapshot Snapshot to be saved.\n     * @param dialogTitle Save File dialog caption.\n     */\n    public void saveAs(final Snapshot snapshot, String dialogTitle) {\n        final File file = snapshot.getFile();\n        if (file == null) {\n            ProfilerDialogs.displayError(NbBundle.getMessage(SnapshotsSupport.class, \"LBL_CannotSave\"));  // NOI18N\n        } else {\n            JFileChooser chooser = new JFileChooser();\n            chooser.setDialogTitle(dialogTitle);\n            chooser.setSelectedFile(new File(snapshot.getFile().getName()));\n            chooser.setAcceptAllFileFilterUsed(false);\n            chooser.setFileFilter(snapshot.getCategory().getFileFilter());\n    //        chooser.setFileView(category.getFileView());\n            if (chooser.showSaveDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) {\n                String categorySuffix = snapshot.getCategory().getSuffix();\n                String filePath = chooser.getSelectedFile().getAbsolutePath();\n                if (!filePath.endsWith(categorySuffix)) filePath += categorySuffix;\n                final File copy = new File(filePath);\n                VisualVM.getInstance().runTask(new Runnable() {\n                    public void run() {\n                        ProgressHandle pHandle = null;\n                        try {\n                            pHandle = ProgressHandle.createHandle(NbBundle.getMessage(SnapshotsSupport.class, \"LBL_Saving\",DataSourceDescriptorFactory.getDescriptor(snapshot).getName()));  // NOI18N\n                            pHandle.setInitialDelay(0);\n                            pHandle.start();\n                            Utils.copyFile(file, copy);\n                        } finally {\n                            final ProgressHandle pHandleF = pHandle;\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() { if (pHandleF != null) pHandleF.finish(); }\n                            });\n                        }\n                    }\n                });\n            }\n        }\n    }\n    \n    /**\n     * Creates a timestamp String (typically used in Snaphshot filename).\n     * \n     * @param time the milliseconds since January 1, 1970, 00:00:00 GMT.\n     * @return timestamp String (typically used in Snaphshot filename).\n     */\n    public String getTimeStamp(long time) {\n        return StringUtils.formatUserDate(new Date(time));\n    }\n    \n    /**\n     * Creates icon for a snapshot by adding a snapshot badge to the provided image.\n     * \n     * @param icon original image.\n     * @return image with snapshot badge.\n     */\n    public Image createSnapshotIcon(Image icon) {\n        return ImageUtilities.mergeImages(icon, SNAPSHOT_BADGE, 0, 0);\n    }\n    \n    \n    private SnapshotsSupport() {\n        PropertiesSupport.sharedInstance().registerPropertiesProvider(\n                new GeneralPropertiesProvider(), Snapshot.class);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/options/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nMSG_NO_CATEGORY_FILE=Cannot open file {0}\n\nMSG_OPENFILE=open file specified by <arg>, file can be .apps Application snapshot, .nps Sampler/Profiler snapshot, .tdump thread dump, HPROF heap dump, or a .jfr recording\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/options/Openfile.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core.snapshot.options;\n\nimport org.graalvm.visualvm.core.snapshot.RegisteredSnapshotCategories;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategoriesListener;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.File;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.swing.Timer;\nimport javax.swing.filechooser.FileFilter;\nimport org.netbeans.api.sendopts.CommandException;\nimport org.netbeans.spi.sendopts.Env;\nimport org.netbeans.spi.sendopts.Option;\nimport org.netbeans.spi.sendopts.OptionProcessor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n * Handling of --openfile commandline option\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=OptionProcessor.class)\npublic final class Openfile extends OptionProcessor {\n    private Option openfile = Option.requiredArgument(Option.NO_SHORT_NAME,\"openfile\");    // NOI18N\n    private static final int TIMEOUT = 5000;\n    \n    public Openfile() {\n        openfile = Option.shortDescription(openfile, \"org.graalvm.visualvm.core.snapshot.options.Bundle\", \"MSG_OPENFILE\");\n    }\n    \n    protected Set<Option> getOptions() {\n        return Collections.singleton(openfile);\n    }\n\n    protected void process(Env env, Map<Option, String[]> optionValues) throws CommandException {\n        String[] files = optionValues.get(openfile);\n        String fileStr = files[0];\n        File file = new File(fileStr);\n        if (!file.isAbsolute()) {\n            file = new File(env.getCurrentDirectory(),fileStr);\n        }\n        RegisteredSnapshotCategories cats = RegisteredSnapshotCategories.sharedInstance();\n        List<SnapshotCategory> snapshotList = cats.getOpenSnapshotCategories();\n        if (openSnapshot(file, snapshotList)) {\n            return;\n        }\n        Listener l = new Listener(file);\n        cats.addCategoriesListener(l);\n    }\n\n    private boolean openSnapshot(final File file, final List<SnapshotCategory> snapshots) {\n        if (file.isFile()) {\n            for (SnapshotCategory s : snapshots) {\n                FileFilter filter = s.getFileFilter();\n\n                if (filter.accept(file)) {\n                    s.openSnapshot(file);\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    private class Listener implements SnapshotCategoriesListener, ActionListener {\n        private final File file;\n        private volatile boolean removed;\n        private final Timer timer;\n        \n        private Listener(File f) {\n            file = f;\n            timer = new Timer(TIMEOUT,this);\n            timer.start();\n        }\n\n        public synchronized void actionPerformed(ActionEvent e) {\n            if (!removed) {\n                RegisteredSnapshotCategories.sharedInstance().removeCategoriesListener(this);\n                removed = true;\n                String msg = NbBundle.getMessage(Openfile.class,\"MSG_NO_CATEGORY_FILE\",new Object[] {file.getAbsolutePath()});    // NOI18N\n                NotifyDescriptor desc = new NotifyDescriptor.Message(msg,NotifyDescriptor.WARNING_MESSAGE);\n                DialogDisplayer.getDefault().notifyLater(desc);\n            }\n        }\n\n        public void categoryRegistered(SnapshotCategory category) {\n            if (openSnapshot(file,Collections.singletonList(category))) {\n                if (!removed) {\n                    RegisteredSnapshotCategories.sharedInstance().removeCategoriesListener(this);\n                    removed = true;\n                    timer.stop();\n                }\n            }\n        }\n\n        public void categoryUnregistered(SnapshotCategory category) {\n        }\n\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/snapshot/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * APIs for snapshots in VisualVM.\n */\npackage org.graalvm.visualvm.core.snapshot;\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_Opening=Opening {0}...\n\nDataSourceCaption_LBL_Reload=The view is not up to date, click to reload obsolete data\\:\nDataSourceCaption_BTN_Reload=Reload\nDataSourceCaption_MSG_Reloading=Reloading view...\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/DataSourceCaption.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class DataSourceCaption<X extends DataSource> extends JPanel implements PropertyChangeListener, DataRemovedListener<DataSource> {\n\n    private static final boolean ANIMATE = Boolean.getBoolean(\"org.graalvm.visualvm.core.ui.DataSourceCaption.animate\");  // NOI18N\n    private static final int ANIMATION_RATE = Integer.getInteger(\"org.graalvm.visualvm.core.ui.DataSourceCaption.animationRate\", 80); // NOI18N\n\n    private static final Color DISABLED_CAPTION = new Color(128, 128, 128);\n    \n    private static final String APPLICATION_PID_PREFIX = \"(pid\";    // NOI18N\n    private static final String APPLICATION_PID_SUFFIX = \")\";   // NOI18N\n    \n    private final DataSource dataSourceMaster;\n    private final DataSourceDescriptor<? extends DataSource> dataSourceMasterDescriptor;\n    \n    private final boolean tracksChanges;\n    private boolean isAvailable;\n    private boolean isDirty = false;\n    private String name;\n    private String description;\n    private boolean finished = false;\n    \n    \n    DataSourceCaption(X dataSource) {\n        initComponents();\n        \n        this.dataSourceMaster = DataSourceWindowManager.getViewMaster(dataSource);\n        \n        tracksChanges = dataSource == dataSourceMaster;\n        dataSourceMaster.addPropertyChangeListener(this);\n        \n        dataSourceMasterDescriptor = DataSourceDescriptorFactory.getDescriptor(dataSourceMaster);\n        dataSourceMasterDescriptor.addPropertyChangeListener(this);\n        \n        initAvailable();\n        name = dataSourceMasterDescriptor.getName();\n        description = dataSourceMasterDescriptor.getDescription();\n        \n        updateCaption();\n        updateDescription();\n        updateAvailable();\n        \n        dataSourceMaster.notifyWhenRemoved(this);\n    }\n\n    \n    public void propertyChange(final PropertyChangeEvent evt) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                String propertyName = evt.getPropertyName();\n                if (Stateful.PROPERTY_STATE.equals(propertyName)) {\n                    int state = (Integer)evt.getNewValue();\n                    isAvailable = state == Stateful.STATE_AVAILABLE;\n                    if (tracksChanges && !isDirty && isAvailable && (Integer)evt.getOldValue() == Stateful.STATE_UNAVAILABLE) isDirty = true;\n                    updateAvailable();\n                    updateCaption();\n                } else if (DataSourceDescriptor.PROPERTY_NAME.equals(propertyName)) {\n                    name = (String)evt.getNewValue();\n                    updateCaption();\n                } else if (DataSourceDescriptor.PROPERTY_DESCRIPTION.equals(propertyName)) {\n                    description = (String)evt.getNewValue();\n                    updateDescription();\n                } else if (DataSourceDescriptor.PROPERTY_ICON.equals(propertyName)) {\n                    // Could display datasource icon instead of progress icon\n                    // setIcon(new ImageIcon((Image)evt.getNewValue()));\n                }\n            }\n        });\n    }\n    \n    \n    public void dataRemoved(DataSource dataSource) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                finish();\n                isAvailable = false;\n                updateAvailable();\n                updateCaption();\n            }\n        });\n    }\n    \n    public synchronized void finish() {\n        if (finished) return;\n        finished = true;\n        dataSourceMaster.removePropertyChangeListener(this);\n        dataSourceMasterDescriptor.removePropertyChangeListener(this);\n    }\n    \n    \n    private void updateAvailable() {\n        if (isAvailable) {\n            if (ANIMATE) {\n                busyIconIndex = 0;\n                if (busyIconTimer == null) createTimer();\n                busyIconTimer.start();\n            } else {\n                presenter1.setIcon(new ImageIcon(getClass().getResource(\"/org/graalvm/visualvm/core/ui/resources/busy-icon4.png\")));   // NOI18N\n            }\n        } else {\n            if (busyIconTimer != null) busyIconTimer.stop(); // Stop previous animation if still running\n            presenter1.setIcon(new ImageIcon(getClass().getResource(\"/org/graalvm/visualvm/core/ui/resources/idle-icon.png\")));    // NOI18N\n        }\n        \n        if (isDirty && !isOpaque()) {        \n            JLabel l = new JLabel(NbBundle.getMessage(DataSourceCaption.class, \"DataSourceCaption_LBL_Reload\")) { // NOI18N\n                public Dimension getMinimumSize() {\n                    Dimension dim = super.getMinimumSize();\n                    dim.height = super.getPreferredSize().height;\n                    return dim;\n                }\n            };\n            GridBagConstraints c = new GridBagConstraints();\n            c.gridx = 2;\n            c.gridy = 0;\n            c.weighty = 1;\n            c.anchor = GridBagConstraints.BELOW_BASELINE;\n            c.insets = new Insets(0, 16, 0, 0);\n            c.fill = GridBagConstraints.NONE;\n            add(l, c);\n\n            JButton b = new JButton(NbBundle.getMessage(DataSourceCaption.class, \"DataSourceCaption_BTN_Reload\")) { // NOI18N\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    DataSourceWindowManager.sharedInstance().reopenDataSource(dataSourceMaster);\n                }\n                public Dimension getMinimumSize() {\n                    Dimension dim = super.getMinimumSize();\n                    dim.height = super.getPreferredSize().height;\n                    return dim;\n                }\n            };\n            c = new GridBagConstraints();\n            c.gridx = 3;\n            c.gridy = 0;\n            c.weighty = 0;\n            c.anchor = GridBagConstraints.BELOW_BASELINE;\n            c.insets = new Insets(0, 8, 0, 0);\n            c.fill = GridBagConstraints.NONE;\n            add(b, c);\n\n            setOpaque(true);\n            setBackground(UISupport.isDarkResultsBackground() ? new Color(150, 0, 0) : Color.YELLOW);\n            \n            invalidate();\n            revalidate();\n            doLayout();\n            repaint();\n        }\n    }\n    \n    private void updateCaption() {\n        // TODO: mask all html-specific characters\n        name = name.replace(\">\", \"&gt;\");   // NOI18N\n        name = name.replace(\"<\", \"&lt;\");   // NOI18N\n\n        Color textColor = isAvailable ? UIManager.getColor(\"Label.foreground\") : DISABLED_CAPTION;    // NOI18N\n        presenter1.setForeground(textColor);\n        presenter2.setForeground(textColor);\n        \n        if (name.contains(APPLICATION_PID_PREFIX) && name.contains(APPLICATION_PID_SUFFIX)) {\n            // Hack to customize default Application displayname containing \"(pid XXX)\"\n            int startPid = name.indexOf(APPLICATION_PID_PREFIX);\n            presenter1.setText(name.substring(0, startPid));\n            presenter2.setText(name.substring(startPid));\n        } else {\n            presenter1.setText(name);\n            presenter2.setText(\"\"); // NOI18N\n        }\n    }\n    \n    private void updateDescription() {\n        if (description == null || description.trim().isEmpty()) {\n            presenter1.setToolTipText(null);\n            presenter2.setToolTipText(null);\n        } else {\n            presenter1.setToolTipText(description);\n            presenter2.setToolTipText(description);\n        }\n    }\n    \n    private void createTimer() {\n        final Icon[] busyIcons = new Icon[15];\n\n        for (int i = 0; i < busyIcons.length; i++) busyIcons[i] = new ImageIcon(getClass().getResource(\"/org/graalvm/visualvm/core/ui/resources/busy-icon\" + i + \".png\"));    // NOI18N\n        busyIconTimer = new Timer(ANIMATION_RATE, new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                if (!ANIMATE) {\n                    if (busyIconTimer != null) busyIconTimer.stop(); // Stop animation\n                    presenter1.setIcon(new ImageIcon(getClass().getResource(\"/org/graalvm/visualvm/core/ui/resources/busy-icon4.png\")));   // NOI18N\n                } else {\n                    busyIconIndex = (busyIconIndex + 1) % busyIcons.length;\n                    if (!DataSourceCaption.this.isShowing()) return;\n                    presenter1.setIcon(busyIcons[busyIconIndex]);\n                }\n            }\n        });\n    }\n    \n    \n    private void initAvailable() {\n        if (dataSourceMaster instanceof Stateful) {\n            Stateful statefulDataSource = (Stateful)dataSourceMaster;\n            isAvailable = statefulDataSource.getState() == Stateful.STATE_AVAILABLE;\n        } else {\n            isAvailable = true;\n        }\n    }\n    \n    private void initComponents() {\n        setLayout(new GridBagLayout());\n        \n        presenter1 = new JLabel(\"XXX\") { // NOI18N\n            public Dimension getMinimumSize() {\n                Dimension dim = super.getMinimumSize();\n                dim.height = super.getPreferredSize().height;\n                return dim;\n            }\n        };\n        Font f = presenter1.getFont();\n        presenter1.setFont(f.deriveFont(Font.BOLD, f.getSize2D() * 1.2f));\n        presenter1.setIconTextGap(6);\n        GridBagConstraints c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.BELOW_BASELINE;\n        c.fill = GridBagConstraints.NONE;\n        add(presenter1, c);\n        \n        presenter2 = new JLabel(\"(123)\") { // NOI18N\n            public Dimension getMinimumSize() {\n                Dimension dim = super.getMinimumSize();\n                dim.height = super.getPreferredSize().height;\n                return dim;\n            }\n        };\n        presenter2.setFont(presenter2.getFont().deriveFont(presenter1.getFont().getSize2D()));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.BELOW_BASELINE;\n        c.fill = GridBagConstraints.NONE;\n        add(presenter2, c);\n        \n        JLabel l = new JLabel(NbBundle.getMessage(DataSourceCaption.class, \"DataSourceCaption_LBL_Reload\")) { // NOI18N\n            public Dimension getMinimumSize() {\n                Dimension dim = super.getMinimumSize();\n                dim.height = super.getPreferredSize().height;\n                return dim;\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 0;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.BELOW_BASELINE;\n        c.insets = new Insets(0, 16, 0, 0);\n        c.fill = GridBagConstraints.NONE;\n        add(l, c);\n        \n        JButton b = new JButton(NbBundle.getMessage(DataSourceCaption.class, \"DataSourceCaption_BTN_Reload\")) { // NOI18N\n            public Dimension getMinimumSize() {\n                Dimension dim = super.getMinimumSize();\n                dim.height = super.getPreferredSize().height;\n                return dim;\n            }\n//            protected void fireActionPerformed(ActionEvent e) {\n//                super.fireActionPerformed(e);\n//                DataSourceWindowManager.sharedInstance().reopenDataSource(dataSource);\n//            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 3;\n        c.gridy = 0;\n        c.weighty = 0;\n        c.anchor = GridBagConstraints.BELOW_BASELINE;\n        c.insets = new Insets(0, 8, 0, 0);\n        c.fill = GridBagConstraints.NONE;\n        add(b, c);\n        \n        final Dimension fixedDim = new Dimension(0, getPreferredSize().height);\n        JPanel spacer = new JPanel(null) {\n            { setOpaque(false); }\n            public Dimension getPreferredSize() { return fixedDim; }\n            public Dimension getMinimumSize() { return fixedDim; }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 100;\n        c.gridy = 0;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.BELOW_BASELINE;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        add(spacer, c);\n        \n//        fixedHeight = super.getPreferredSize().height;\n        \n//        fixedHeight = Math.max(presenter1.getPreferredSize().height, presenter2.getPreferredSize().height);\n//        fixedHeight = Math.max(fixedHeight, new JButton(NbBundle.getMessage(DataSourceCaption.class, \"DataSourceCaption_BTN_Reload\")).getPreferredSize().height);\n        \n        setOpaque(false);\n        \n        remove(l);\n        remove(b);\n    }\n    \n    \n//    public Dimension getPreferredSize() {\n//        Dimension dim = super.getPreferredSize();\n//        dim.height = fixedHeight;\n//        return dim;\n//    }\n//    \n//    public Dimension getMinimumSize() {\n//        Dimension dim = super.getMinimumSize();\n//        dim.height = fixedHeight;\n//        return dim;\n//    }\n//    \n//    public Dimension getMaximumSize() {\n//        Dimension dim = super.getMaximumSize();\n//        dim.height = fixedHeight;\n//        return dim;\n//    }\n//    \n//    public Dimension getSize() {\n//        Dimension dim = super.getSize();\n//        dim.height = fixedHeight;\n//        return dim;\n//    }\n    \n    \n    private JLabel presenter1;\n    private JLabel presenter2;\n    private Timer busyIconTimer;\n    private int busyIconIndex;\n    \n    \n//    private int fixedHeight = -1;\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/DataSourceView.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport java.awt.Image;\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\n\n/**\n * Definition of a subtab representing a concrete view of a DataSource in DataSource Window.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class DataSourceView implements Positionable {\n\n    protected static enum Alert { ERROR, WARNING, OK }\n    protected static final String ALERT_PROP = \"Alert\"; // NOI18N\n    protected static final String ALERT_STRING_PROP = \"Alert String\"; // NOI18N\n    \n    private DataSource dataSource;\n    private String name;\n    private Image icon;\n    private int preferredPosition;\n    private boolean isClosable;\n    private DataViewComponent component;\n    private DataSourceViewProvider controller;\n    private Alert alert;\n    private String alertText;\n    private PropertyChangeSupport propertyChangeSupport;\n    \n    /**\n     * Creates new DataSourceView.\n     * \n     * Order of the notifications/queries is as follows:\n     * willBeAdded() -&gt; getView() -&gt; added() -&gt; removed()\n     * \n     * @param dataSource dataSource of the view\n     * @param name name of the view as it appears in the subtab,\n     * @param icon icon of the view as it appears in the subtab,\n     * @param preferredPosition preferred position of the view among all other views for the DataSource,\n     * @param isClosable true if the user is allowed to close the view, false otherwise.\n     */\n    public DataSourceView(DataSource dataSource, String name, Image icon, int preferredPosition, boolean isClosable) {\n        if (dataSource == null) throw new IllegalArgumentException(\"DataSource cannot be null\");    // NOI18N\n        if (name == null) throw new IllegalArgumentException(\"Name cannot be null\");    // NOI18N\n        if (icon == null) throw new IllegalArgumentException(\"Icon cannot be null\");    // NOI18N\n\n        this.dataSource = dataSource;\n        this.name = name;\n        this.icon = icon;\n        this.preferredPosition = preferredPosition;\n        this.isClosable = isClosable;\n        propertyChangeSupport = new PropertyChangeSupport(this);\n    }\n\n\n    /**\n     * Returns dataSource of the view.\n     * \n     * @return dataSource of the view.\n     */\n    public final DataSource getDataSource() {\n        return dataSource;\n    }\n\n    /**\n     * Returns name of the view as it appears in the subtab.\n     * \n     * @return name of the view as it appears in the subtab.\n     */\n    public final String getName() {\n        return name;\n    }\n\n    /**\n     * Returns icon of the view as it appears in the subtab.\n     * \n     * @return icon of the view as it appears in the subtab.\n     */\n    public final Image getImage() {\n        return icon;\n    }\n    \n    /**\n     * Returns DataViewComponent implementing the view.\n     * Called from EDT.\n     * \n     * @return DataViewComponent implementing the view.\n     */\n    protected abstract DataViewComponent createComponent();\n\n    /**\n     * Returns preferred position of the view among all other views for the DataSource.\n     * \n     * @return preferred position of the view among all other views for the DataSource.\n     */\n    public final int getPreferredPosition() {\n        return preferredPosition;\n    }\n  \n    /**\n     * Returns true if the user is allowed to close the view, false otherwise.\n     * \n     * @return true if the user is allowed to close the view, false otherwise.\n     */\n    public final boolean isClosable() {\n        return isClosable;\n    }\n    \n    protected void setAlert(Alert newAlert, String newText) {\n        Alert oldAlert = alert;\n        String oldText = newText;\n        \n        alert = newAlert;\n        alertText = newText;\n        propertyChangeSupport.firePropertyChange(ALERT_PROP, oldAlert, alert);\n        propertyChangeSupport.firePropertyChange(ALERT_STRING_PROP, oldText, newText);\n    }\n    \n    /**\n     * Notification when the view is about to be added to DataSourceWindow.\n     * This notification comes from a thread other than EDT and its main intention\n     * is to provide a possibility to do some models inits before the actual UI is displayed.\n     * This call is blocking (blocks opening the view, progress bar is shown) but long-running initializations should\n     * still use separate thread and update the UI after the models are ready.\n     */\n    protected void willBeAdded() {\n    }\n    \n    /**\n     * Notification when the view has been added to DataSourceWindow.\n     * This notification comes from a thread other than EDT.\n     */\n    protected void added() {\n    }\n    \n    /**\n     * Notification when the view is about to be either programmatically removed from tabbed pane or closed by the user by clicking the X.\n     * This notification comes from the EDT thread and its main intention is to\n     * provide a possibility to save any view data before the view is closed, if\n     * needed. Long-running operations should use a separate thread to not block\n     * EDT closing the view.\n     */\n    protected void willBeRemoved() {\n    }\n    \n    /**\n     * Notification when the view has been either programatically removed from tabbed pane or closed by the user by clicking the X.\n     * This notification comes from a thread other than EDT\n     */\n    protected void removed() {\n    }\n    \n    Alert getAlert() {\n        return alert;\n    }\n    \n    void addPropertyChangeListener(PropertyChangeListener l) {\n        propertyChangeSupport.addPropertyChangeListener(l);\n    }\n    \n    void removePropertyChangeListener(PropertyChangeListener l) {\n        propertyChangeSupport.removePropertyChangeListener(l);\n    }\n      \n    DataViewComponent getView() {\n        if (component == null) {\n            component = createComponent();\n            if (component == null) throw new NullPointerException(\"Null view component from \" + this);  // NOI18N\n            controller.processCreatedComponent(this, component);\n        }\n        return component;\n    }\n    \n    boolean hasComponent() {\n        return component != null;\n    }\n\n    void viewWillBeAdded() {\n        willBeAdded();\n        controller.viewWillBeAdded(this);\n    }\n    \n    void viewAdded() {\n        added();\n        controller.viewAdded(this);\n    }\n    \n    private boolean willBeRemovedNotified;\n    void viewWillBeRemoved() {\n        if (willBeRemovedNotified) return;\n        \n        willBeRemoved();\n        willBeRemovedNotified = true;\n        controller.viewWillBeRemoved(this);\n    }\n    \n    void viewRemoved() {\n        removed();\n        controller.viewRemoved(this);\n    }\n    \n    void setController(DataSourceViewProvider controller) {\n        this.controller = controller;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/DataSourceViewPlugin.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\n\n/**\n * Plugin to an existing DataSourceView which adds an additional view.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class DataSourceViewPlugin {\n    \n    private DataSource dataSource;\n    private DataSourceViewPluginProvider controller;\n    \n    \n    /**\n     * Creates new DataSourceViewPlugin for a DataSource.\n     * \n     * @param dataSource DataSource, for which to add the plugin.\n     */\n    public DataSourceViewPlugin(DataSource dataSource) {\n        this.dataSource = dataSource;\n    }\n    \n    \n    /**\n     * Returns DataSource for the plugin.\n     * \n     * @return DataSource for the plugin.\n     */\n    public final DataSource getDataSource() {\n        return dataSource;\n    }\n    \n    /**\n     * Creates DataViewComponent.DetailsView which will be plugged into the DataSourceView.\n     * \n     * @param location location where the DataViewComponent.DetailsView will be added.\n     * @return DataViewComponent.DetailsView of the plugin for the location or null.\n     */\n    public abstract DataViewComponent.DetailsView createView(int location);\n    \n\n    /**\n     * Notification when the view is about to be added to DataSourceWindow.\n     * This notification comes from a thread other than EDT and its main intention\n     * is to provide a possibility to do some models inits before the actual UI is displayed.\n     * This call is blocking (blocks opening the view, progress bar is shown) but long-running initializations should\n     * still use separate thread and update the UI after the models are ready.\n     */\n    protected void willBeAdded() {\n    }\n    \n    /**\n     * Notification when the view has been added to DataSourceWindow.\n     * This notification comes from a thread other than EDT.\n     */\n    protected void added() {\n    }\n    \n    /**\n     * Notification when the view has been either programatically removed from tabbed pane or closed by the user by clicking the X.\n     * This notification comes from a thread other than EDT\n     */\n    protected void removed() {\n    }\n    \n    \n    void pluginWillBeAdded() {\n        willBeAdded();\n        controller.pluginWillBeAdded(this);\n    }\n    \n    void pluginAdded() {\n        added();\n        controller.pluginAdded(this);\n    }\n    \n    void pluginRemoved() {\n        removed();\n        controller.pluginRemoved(this);\n    }\n    \n    void setController(DataSourceViewPluginProvider controller) {\n        this.controller = controller;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/DataSourceViewPluginProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Provider of DataSourceViewPlugin for a DataSource.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class DataSourceViewPluginProvider<X extends DataSource> {\n    \n    private final Map<X, DataSourceViewPlugin> pluginsCache = new HashMap<>();\n    \n    \n    /**\n     * Returns true if the plugin provider provides a plugin for the DataSource.\n     * \n     * @param dataSource DataSource for which to provide the plugin.\n     * @return true if the plugin provider provides a plugin for the DataSource, false otherwise.\n     */\n    protected abstract boolean supportsPluginFor(X dataSource);\n\n    /**\n     * Returns DataSourceViewPlugin instance for the DataSource.\n     * \n     * @param dataSource DataSource for which to create the plugin.\n     * @return DataSourceViewPlugin instance for the DataSource.\n     */\n    protected abstract DataSourceViewPlugin createPlugin(X dataSource);\n    \n    /**\n     * Returns true if the plugin provider supports saving DataSourceViewPlugin for the DataSource into\n     * the Snapshot type.\n     * \n     * @param dataSource DataSource for which to save the plugin.\n     * @param snapshotClass snapshot type into which to save the plugin.\n     * @return true if the plugin provider supports saving DataSourceViewPlugin for the DataSource, false otherwise.\n     */\n    protected boolean supportsSavePluginFor(X dataSource, Class<? extends Snapshot> snapshotClass) { return false; }\n    \n    /**\n     * Saves DataSourceViewPlugin for the DataSource into the Snapshot.\n     * \n     * @param dataSource DataSource for which to save the plugin.\n     * @param snapshot Snapshot into which to save the plugin.\n     */\n    protected void savePlugin(X dataSource, Snapshot snapshot) {}\n    \n    \n    /**\n     * Returns DataSourceViewPlugin for the DataSource if already created (cached).\n     * \n     * @param dataSource DataSource of the plugin.\n     * @return DataSourceViewPlugin for the DataSource if already created (cached), null otherwise.\n     */\n    protected final DataSourceViewPlugin getCachedPlugin(X dataSource) {\n        synchronized(pluginsCache) {\n            return pluginsCache.get(dataSource);\n        }\n    }\n    \n    \n    void pluginWillBeAdded(DataSourceViewPlugin plugin) {\n    }\n    \n    void pluginAdded(DataSourceViewPlugin plugin) {\n    }\n    \n    void pluginRemoved(DataSourceViewPlugin plugin) {\n        synchronized(pluginsCache) {\n            pluginsCache.remove((X)plugin.getDataSource());\n        }\n    }\n    \n    /**\n     * Returns DataSourceViewPlugin for the DataSource. Tries to resolve already\n     * created plugin from cache, creates new DataSourceViewPlugin instance using\n     * the createPlugin(DataSource) method if needed.\n     * \n     * @param dataSource\n     * @return DataSourceViewPlugin for the DataSource.\n     */\n    protected final DataSourceViewPlugin getPlugin(X dataSource) {\n        synchronized(pluginsCache) {\n            DataSourceViewPlugin plugin = getCachedPlugin(dataSource);\n            if (plugin == null) {\n                plugin = createPlugin(dataSource);\n                if (plugin == null) throw new NullPointerException(\"DataSourceViewPluginProvider provides null plugin: \" + this);   // NOI18N\n                plugin.setController(this);\n                pluginsCache.put(dataSource, plugin);\n            }\n            return plugin;\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/DataSourceViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Provider of DataSourceView for a DataSource.\n * \n * @author Jiri Sedlacek\n */\npublic abstract class DataSourceViewProvider<X extends DataSource> {\n    \n    private final Map<X, DataSourceView> viewsCache = new HashMap<>();\n    \n\n    /**\n     * Returns true if the view provider provides a view for the DataSource.\n     * \n     * @param dataSource DataSource for which to provide the view.\n     * @return true if the view provider provides a view for the DataSource, false otherwise.\n     */\n    protected abstract boolean supportsViewFor(X dataSource);\n\n    /**\n     * Returns DataSourceView instance for the DataSource.\n     * \n     * @param dataSource DataSource for which to create the view.\n     * @return DataSourceView instance for the DataSource.\n     */\n    protected abstract DataSourceView createView(X dataSource);\n    \n    /**\n     * Returns true if the view provider supports saving DataSourceView for the DataSource into\n     * the Snapshot type.\n     * \n     * @param dataSource DataSource for which to save the view.\n     * @param snapshotClass snapshot type into which to save the view.\n     * @return true if the view provider supports saving DataSourceView for the DataSource, false otherwise.\n     */\n    protected boolean supportsSaveViewFor(X dataSource, Class<? extends Snapshot> snapshotClass) { return false; }\n    \n    /**\n     * Saves DataSourceView for the DataSource into the Snapshot.\n     * \n     * @param dataSource DataSource for which to save the view.\n     * @param snapshot Snapshot into which to save the view.\n     */\n    protected void saveView(X dataSource, Snapshot snapshot) {}\n    \n    /**\n     * Returns DataSourceView for the DataSource if already created (cached).\n     * \n     * @param dataSource DataSource of the plugin.\n     * @return DataSourceView for the DataSource if already created (cached), null otherwise.\n     */\n    protected final DataSourceView getCachedView(X dataSource) {\n        synchronized(viewsCache) {\n            return viewsCache.get(dataSource);\n        }\n    }\n    \n    \n    /**\n     * Returns DataSourceView for the DataSource. Tries to resolve already\n     * created view from cache, creates new DataSourceView instance using\n     * the createView(DataSource) method if needed.\n     * \n     * @param dataSource\n     * @return DataSourceView for the DataSource.\n     */\n    protected final DataSourceView getView(X dataSource) {\n        synchronized(viewsCache) {\n            DataSourceView view = getCachedView(dataSource);\n            if (view == null) {\n                view = createView(dataSource);\n                if (view == null) throw new NullPointerException(\"DataSourceViewProvider provides null view: \" + this); // NOI18N\n                view.setController(this);\n                viewsCache.put(dataSource, view);\n            }\n            return view;\n        }\n    }\n    \n    void viewSaveView(X dataSource, Snapshot snapshot) {\n        saveView(dataSource, snapshot);\n    }\n    \n    void processCreatedComponent(DataSourceView view, DataViewComponent component) {\n    }\n        \n    void viewWillBeAdded(DataSourceView view) {\n    }\n    \n    void viewAdded(DataSourceView view) {\n    }\n    \n    void viewWillBeRemoved(DataSourceView view) {\n    }\n    \n    void viewRemoved(DataSourceView view) {\n        synchronized(viewsCache) {\n            viewsCache.remove((X)view.getDataSource());\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/DataSourceViewsManager.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * Class responsible for resolving DataSourceViews for DataSources.\n *\n * @author Jiri Sedlacek\n */\npublic final class DataSourceViewsManager {\n    \n    private static final String APP_OVERVIEW_CLASS_workaround =\n            \"org.graalvm.visualvm.application.views.overview.ApplicationOverviewViewProvider\"; // NOI18N\n\n    private static DataSourceViewsManager sharedInstance;\n\n    // TODO: implement some better data structure for cheaper providers query\n    private final Map<DataSourceViewProvider, Class<? extends DataSource>> providers = Collections.synchronizedMap(new HashMap<>());\n    \n    \n    /**\n     * Returns singleton instance of DataSourceViewsManager.\n     * \n     * @return singleton instance of DataSourceViewsManager.\n     */\n    public static synchronized DataSourceViewsManager sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new DataSourceViewsManager();\n        return sharedInstance;\n    }\n    \n    \n    /**\n     * Registers new DataSourceViewProvider for given DataSource scope.\n     * \n     * @param provider DataSourceViewProvider to be added,\n     * @param scope scope of DataSource types for which the provider provides views.\n     */\n    public void addViewProvider(DataSourceViewProvider provider, Class<? extends DataSource> scope) {\n        providers.put(provider, scope);\n    }\n    \n    /**\n     * Unregisters DataSourceViewProvider.\n     * \n     * @param provider DataSourceViewProvider to be removed.\n     */\n    public void removeViewProvider(DataSourceViewProvider provider) {\n        providers.remove(provider);\n    }\n    \n    /**\n     * Returns true if there's at least one DataSourceView for the DataSource which can\n     * be saved into the Snapshot type.\n     * \n     * @param dataSource DataSource for which to save the views.\n     * @param snapshotClass Snapshot type into which to save the views.\n     * @return true if there's at least one DataSourceView for the DataSource which can\n     * be saved into the Snapshot type, false otherwise.\n     */\n    public boolean canSaveViewsFor(DataSource dataSource, Class<? extends Snapshot> snapshotClass) {\n        Set<DataSourceViewProvider> compatibleProviders = getCompatibleProviders(dataSource);\n        if (compatibleProviders.isEmpty()) return false;\n        // Workaround for #109 to not block synchronous actions updating in EDT\n        for (DataSourceViewProvider compatibleProvider : compatibleProviders)\n            if (APP_OVERVIEW_CLASS_workaround.equals(compatibleProvider.getClass().getName())) return true;\n        // --------------------------------------------------------------------\n        for (DataSourceViewProvider compatibleProvider : compatibleProviders)\n            if (compatibleProvider.supportsViewFor(dataSource) && compatibleProvider.supportsSaveViewFor(dataSource, snapshotClass))\n                return true;\n        return false;\n    }\n    \n    /**\n     * Saves views for the DataSource into the Snapshot.\n     * \n     * @param dataSource DataSource for which to save the views.\n     * @param snapshot Snapshot into which to save the views.\n     */\n    public void saveViewsFor(DataSource dataSource, Snapshot snapshot) {\n        Set<DataSourceViewProvider> compatibleProviders = getCompatibleProviders(dataSource);\n        for (DataSourceViewProvider compatibleProvider : compatibleProviders)\n            if (compatibleProvider.supportsViewFor(dataSource) && compatibleProvider.supportsSaveViewFor(dataSource, snapshot.getClass()))\n                compatibleProvider.viewSaveView(dataSource, snapshot);\n    }\n    \n    boolean hasViewsFor(DataSource dataSource) {\n        Set<DataSourceViewProvider> compatibleProviders = getCompatibleProviders(dataSource);\n        if (compatibleProviders.isEmpty()) return false;\n        // Workaround for #109 to not block synchronous actions updating in EDT\n        for (DataSourceViewProvider compatibleProvider : compatibleProviders)\n            if (APP_OVERVIEW_CLASS_workaround.equals(compatibleProvider.getClass().getName())) return true;\n        // --------------------------------------------------------------------\n        for (DataSourceViewProvider compatibleProvider : compatibleProviders)\n            if (compatibleProvider.supportsViewFor(dataSource)) return true;\n        return false;\n    }\n    \n    List<? extends DataSourceView> getViews(DataSource dataSource) {\n        List<DataSourceView> views = new ArrayList<>();\n        Set<DataSourceViewProvider> compatibleProviders = getCompatibleProviders(dataSource);\n        for (DataSourceViewProvider compatibleProvider : compatibleProviders)\n            if (compatibleProvider.supportsViewFor(dataSource))\n                views.add(compatibleProvider.getView(dataSource));\n        views.sort(Positionable.COMPARATOR);\n        return views;\n    }\n    \n    private Set<DataSourceViewProvider> getCompatibleProviders(DataSource dataSource) {\n        Set<DataSourceViewProvider> compatibleProviders = new HashSet<>();\n        Set<DataSourceViewProvider> providersSet = providers.keySet();\n        for (DataSourceViewProvider provider : providersSet)\n            if (providers.get(provider).isInstance(dataSource))\n                compatibleProviders.add(provider);\n        return compatibleProviders;\n    }\n    \n    \n    private DataSourceViewsManager() {\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/DataSourceWindow.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.ui.DataSourceView.Alert;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Image;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.WeakListeners;\nimport org.openide.windows.TopComponent;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass DataSourceWindow extends TopComponent implements PropertyChangeListener {\n\n    private static final RequestProcessor PROCESSOR =\n            new RequestProcessor(\"DataSourceWindow Processor\", 5); // NOI18N\n    \n    private static final Logger LOGGER = Logger.getLogger(DataSourceWindow.class.getName());\n    \n    private int viewsCount = 0;\n    private DataSource dataSource;\n    private DataSourceDescriptor dataSourceDescriptor;\n    private DataSourceWindowTabbedPane.ViewContainer singleViewContainer;\n    private JPanel multiViewContainer;\n    private AlertListener alertListener;\n\n    DataSourceWindow(DataSource dataSource) {\n        this.dataSource = dataSource;\n        initAppearance();\n        initComponents();\n    }\n    \n    \n    public DataSource getDataSource() {\n        return dataSource;\n    }\n\n    public void addView(DataSourceView view) {\n        if (viewsCount == 0) {\n            singleViewContainer = new DataSourceWindowTabbedPane.ViewContainer(new DataSourceCaption(view.getDataSource()), view);\n            add(singleViewContainer, BorderLayout.CENTER);\n            doLayout();\n            alertListener = new AlertListener();\n        } else if (viewsCount == 1) {\n            remove(singleViewContainer);\n\n            add(multiViewContainer, BorderLayout.CENTER);\n            tabbedContainer.addView(dataSource, singleViewContainer.getView());\n            tabbedContainer.addView(dataSource, view);\n            doLayout();\n            singleViewContainer.getCaption().finish();\n            singleViewContainer = null;\n        } else {\n            tabbedContainer.addView(dataSource, view);\n        }\n        viewsCount++;\n        view.addPropertyChangeListener(WeakListeners.propertyChange(alertListener,view));\n    }\n    \n    private void insertView(DataSourceView view, int index) {\n        if (viewsCount == 0) {\n            singleViewContainer = new DataSourceWindowTabbedPane.ViewContainer(new DataSourceCaption(view.getDataSource()), view);\n            add(singleViewContainer, BorderLayout.CENTER);\n            doLayout();\n            alertListener = new AlertListener();\n        } else if (viewsCount == 1) {\n            remove(singleViewContainer);\n\n            add(multiViewContainer, BorderLayout.CENTER);\n            tabbedContainer.addView(dataSource, singleViewContainer.getView());\n            tabbedContainer.insertView(dataSource, view, index);\n            doLayout();\n            singleViewContainer.getCaption().finish();\n            singleViewContainer = null;\n        } else {\n            tabbedContainer.insertView(dataSource, view, index);\n        }\n        viewsCount++;\n        view.addPropertyChangeListener(WeakListeners.propertyChange(alertListener,view));\n    }\n    \n    public void selectView(DataSourceView view) {\n        if (viewsCount > 1) {\n            int viewIndex = indexOf(view);\n            if (viewIndex == -1) throw new RuntimeException(\"View \" + view + \" not present in DataSourceWindow \" + this);   // NOI18N\n            else tabbedContainer.setViewIndex(viewIndex);\n        }\n    }\n    \n    public void removeView(final DataSourceView view) {\n        if (viewsCount == 1) {\n            if (view != singleViewContainer.getView()) throw new RuntimeException(\"View \" + view + \" not present in DataSourceWindow \" + this); // NOI18N\n            view.viewWillBeRemoved();\n            remove(singleViewContainer);\n            singleViewContainer.getCaption().finish();\n            singleViewContainer = null;\n        } else {\n            int viewIndex = indexOf(view);\n            if (viewIndex == -1) throw new RuntimeException(\"View \" + view + \" not present in DataSourceWindow \" + this);   // NOI18N\n            view.viewWillBeRemoved();\n            tabbedContainer.removeView(viewIndex);\n            \n            if (viewsCount == 2) {\n                DataSourceView remaining = tabbedContainer.getViews().get(0);\n                singleViewContainer = new DataSourceWindowTabbedPane.ViewContainer(new DataSourceCaption(remaining.getDataSource()), remaining);\n                remove(multiViewContainer);\n                tabbedContainer.removeView(0);\n                add(singleViewContainer, BorderLayout.CENTER);\n                doLayout();\n            }\n        }\n        \n        PROCESSOR.post(new Runnable() {\n            public void run() {\n                try { view.viewRemoved(); }\n                catch (Exception e) { LOGGER.log(Level.WARNING, \"Failed notifying removed view \" + view, e); } // NOI18N\n            }\n        });\n        \n        DataSourceWindowManager.sharedInstance().unregisterClosedView(view);\n        viewsCount--;\n        if (viewsCount == 0 && isOpened()) close();\n    }\n    \n    void clearView(final DataSourceView view, RequestProcessor notificationProcessor) {\n        if (viewsCount == 1 && Objects.equals(singleViewContainer.getName(), view.getName())) {\n            view.viewWillBeRemoved();\n            singleViewContainer.removeAll();\n            if (singleViewContainer.getCaption() != null) singleViewContainer.getCaption().finish();\n            singleViewContainer.setReloading();\n            singleViewContainer.doLayout();\n            singleViewContainer.repaint();\n        } else {\n            int viewIndex = indexOf(view);\n            if (viewIndex == -1) return;\n\n            view.viewWillBeRemoved();\n            tabbedContainer.clearView(viewIndex);\n        }\n        \n        notificationProcessor.post(new Runnable() {\n            public void run() {\n                try { view.viewRemoved(); }\n                catch (Exception e) { LOGGER.log(Level.WARNING, \"Failed notifying removed view \" + view, e); } // NOI18N\n            }\n        });\n    }\n    \n    void updateView(final DataSourceView view, int index) {\n        if (viewsCount == 1 && Objects.equals(singleViewContainer.getName(), view.getName())) {\n            singleViewContainer.removeAll();\n            singleViewContainer.setCaption(new DataSourceCaption(view.getDataSource()));\n            singleViewContainer.setView(view);\n            singleViewContainer.doLayout();\n            singleViewContainer.repaint();\n        } else {\n            DataSourceWindowTabbedPane.ViewContainer container = tabbedContainer.getContainer(view);\n            if (container != null) {\n                container.removeAll();\n                container.setCaption(new DataSourceCaption(view.getDataSource()));\n                container.setView(view);\n                container.doLayout();\n                container.repaint();\n            } else {\n                insertView(view, index);\n            }\n        }\n        \n        PROCESSOR.post(new Runnable() {\n            public void run() {\n                try { view.viewAdded(); }\n                catch (Exception e) { LOGGER.log(Level.WARNING, \"Failed post-initialize view \" + view, e); } // NOI18N\n            }\n        });\n    }\n    \n    void closeUnregisteredView(final DataSourceView view) {\n        if (viewsCount == 1) {\n            if (view != singleViewContainer.getView()) throw new RuntimeException(\"View \" + view + \" not present in DataSourceWindow \" + this); // NOI18N\n            remove(singleViewContainer);\n            singleViewContainer.getCaption().finish();\n            singleViewContainer = null;\n        } else {\n            int viewIndex = indexOf(view);\n            if (viewIndex == -1) throw new RuntimeException(\"View \" + view + \" not present in DataSourceWindow \" + this);   // NOI18N\n            else tabbedContainer.removeView(viewIndex);\n            \n            if (viewsCount == 2) {\n                DataSourceView remaining = tabbedContainer.getViews().get(0);\n                singleViewContainer = new DataSourceWindowTabbedPane.ViewContainer(new DataSourceCaption(remaining.getDataSource()), remaining);\n                remove(multiViewContainer);\n                tabbedContainer.removeView(0);\n                add(singleViewContainer, BorderLayout.CENTER);\n                doLayout();\n            }\n        }\n        \n        viewsCount--;\n        if (viewsCount == 0 && isOpened()) close();\n    }\n    \n    public void removeAllViews() {\n        List<DataSourceView> views = getViews();\n        for (DataSourceView view : views) removeView(view);\n    }\n    \n    public List<DataSourceView> getViews() {\n        if (viewsCount == 1) {\n            return Collections.singletonList(singleViewContainer.getView());\n        } else {\n            return tabbedContainer.getViews();\n        }\n    }\n    \n    public boolean containsView(DataSourceView view) {\n        return indexOf(view) != -1;\n    }\n    \n    \n    private int indexOf(DataSourceView view) {\n        if (viewsCount == 1) {\n            return view == singleViewContainer.getView() ? 0 : -1;\n        } else {\n            return tabbedContainer.indexOfView(view);\n        }\n    }\n\n\n    protected final void componentActivated() {\n        super.componentActivated();\n        if (singleViewContainer != null) singleViewContainer.requestFocusInWindow();\n        else if (getComponentCount() > 0) getComponent(0).requestFocusInWindow();\n    }\n    \n    public final boolean canClose() {\n        for (DataSourceView view : getViews()) view.viewWillBeRemoved();\n        \n        return true;\n    }\n    \n    protected final void componentClosed() {\n        dataSourceDescriptor.removePropertyChangeListener(this);\n        removeAllViews();\n        DataSourceWindowManager.sharedInstance().unregisterClosedWindow(this);\n        super.componentClosed();\n    }\n    \n    \n    public void propertyChange(final PropertyChangeEvent evt) {\n        String propertyName = evt.getPropertyName();\n        if (DataSourceDescriptor.PROPERTY_NAME.equals(propertyName)) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { setName((String)evt.getNewValue()); }\n            });\n        } else if (DataSourceDescriptor.PROPERTY_ICON.equals(propertyName)) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { setIcon((Image)evt.getNewValue()); }\n            });\n        }\n    }\n    \n    \n    private void initAppearance() {\n        dataSourceDescriptor = DataSourceDescriptorFactory.getDescriptor(dataSource);\n        \n        dataSourceDescriptor.addPropertyChangeListener(this);\n        \n        setName(dataSourceDescriptor.getName());\n        setIcon(dataSourceDescriptor.getIcon());\n    }\n    \n    private void initComponents() {\n        setLayout(new BorderLayout());\n\n        // tabbedContainer\n        tabbedContainer = new DataSourceWindowTabbedPane() {\n            @Override\n            protected void closeView(DataSourceWindowTabbedPane.ViewContainer view) {\n                DataSourceWindow.this.removeView(tabbedContainer.getView(view));\n            }\n            \n        };\n\n        // multiViewContainer\n        multiViewContainer = new JPanel(new BorderLayout());\n        if (UISupport.isAquaLookAndFeel()) {\n            multiViewContainer.setOpaque(true);\n            multiViewContainer.setBackground(UISupport.getDefaultBackground());\n        }\n        multiViewContainer.add(tabbedContainer, BorderLayout.CENTER);\n\n        add(multiViewContainer, BorderLayout.CENTER);\n    }\n    \n    private void setAlert(DataSourceView view, Alert alert) {\n        int viewIndex = tabbedContainer.indexOfView(view);\n        \n        tabbedContainer.setViewBackground(viewIndex,getAlertColor(alert));\n        if (alert != Alert.OK) {\n            requestAttention(false);\n        } else if (getApplicationAlert(alert) == Alert.OK) {\n            cancelRequestAttention();\n        }\n    }\n\n    private Color getAlertColor(final Alert alert) {\n        Color color = null;\n        \n        switch (alert) {\n            case ERROR: \n                color = Color.RED;\n                break;\n            case WARNING:\n                color = Color.YELLOW;\n                break;\n            case OK:\n                color = null;\n                break;\n        }\n        return color;\n    }\n\n    private Alert getApplicationAlert(Alert alert) {\n        if (alert == Alert.ERROR) {\n            return alert;\n        }\n        for (DataSourceView view : getViews()) {\n            Alert a = view.getAlert();\n            if (a == Alert.ERROR) {\n                return a;\n            }\n            if (a == Alert.WARNING) {\n                alert = a;\n            }\n        }\n        return alert;\n    }\n    \n    private DataSourceWindowTabbedPane tabbedContainer;\n    \n    \n    public int getPersistenceType() { return TopComponent.PERSISTENCE_NEVER; }\n    protected String preferredID() { return getClass().getName(); }\n\n    private class AlertListener implements PropertyChangeListener {\n\n        public void propertyChange(PropertyChangeEvent evt) {\n            if (DataSourceView.ALERT_PROP.equals(evt.getPropertyName())) {\n                setAlert((DataSourceView) evt.getSource(), (Alert) evt.getNewValue());\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/DataSourceWindowListener.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core.ui;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\n\n/**\n * Listener for tracking opening and closing window of a DataSource.\n * \n * @param <X> DataSource type\n *\n * @author Jiri Sedlacek\n */\npublic interface DataSourceWindowListener<X extends DataSource> {\n    \n    public default void windowOpened(X dataSource) {}\n    \n    public default void windowClosed(X dataSource) {}\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/DataSourceWindowManager.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.WeakHashMap;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n * Class responsible for DataSourceViews manipulation.\n *\n * @author Jiri Sedlacek\n */\npublic final class DataSourceWindowManager {\n    \n    private static final RequestProcessor processor = new RequestProcessor(\"DataSourceWindowManager Processor\");    // NOI18N\n    private static final Logger LOGGER = Logger.getLogger(DataSourceWindowManager.class.getName());\n    \n    private static DataSourceWindowManager sharedInstance;\n    \n    private final Map<DataSource, List<DataSourceWindowListener>> windowListeners = new WeakHashMap<>();\n\n    private final Map<DataSource, DataSourceWindow> openedWindows = Collections.synchronizedMap(new HashMap<>());\n    private final Map<DataSource, Set<DataSourceView>> openedViews = Collections.synchronizedMap(new HashMap<>());\n    \n    private final Runnable closingHandler;\n\n\n    /**\n     * Returns singleton instance of DataSourceWindowManager.\n     * \n     * @return singleton instance of DataSourceWindowManager.\n     */\n    public static synchronized DataSourceWindowManager sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new DataSourceWindowManager();\n        return sharedInstance;\n    }\n    \n    \n    /**\n     * Returns true if there is at least one provider providing at least one view for given DataSource, false otherwise.\n     * \n     * @param dataSource DataSource to open.\n     * @return true if there is at least one provider providing at least one view for given DataSource, false otherwise.\n     */\n    public boolean canOpenDataSource(DataSource dataSource) {\n        return DataSourceViewsManager.sharedInstance().hasViewsFor(dataSource);\n    }\n    \n    /**\n     * Opens the DataSource and selects the view.\n     * \n     * @param dataSource DataSource to open\n     */\n    public void openDataSource(final DataSource dataSource) {\n        openDataSource(dataSource, true);\n    }\n\n    /**\n     * Opens the DataSource and optionally selects the view.\n     *\n     * @param dataSource DataSource to open\n     * @param selectView true if the view should be selected, false otherwise\n     */\n    public void openDataSource(final DataSource dataSource, final boolean selectView) {\n        processor.post(new Runnable() {\n            public void run() {\n                openDataSource(dataSource, selectView, 0);\n            }\n        });\n    }\n    \n    /**\n     * Opens the DataSource and optionally selects the view.\n     *\n     * @param dataSource DataSource to open\n     * @param selectView true if the view should be selected, false otherwise\n     * @param viewIndex index of the view to select\n     */\n    public void openDataSource(final DataSource dataSource, final boolean selectView, final int viewIndex) {\n        processor.post(new Runnable() {\n            public void run() {\n                openWindowAndAddView(dataSource, null, viewIndex, selectView, selectView, selectView);\n            }\n        });\n    }\n    \n    /**\n     * Checks whether the DataSource window is currently opened.\n     *\n     * @param dataSource DataSource to check\n     * @return true if the DataSource window is currently opened, false otherwise.\n     */\n    public boolean isDataSourceOpened(DataSource dataSource) {\n        return openedWindows.get(dataSource) != null;\n    }\n    \n    public <D extends DataSource> void addWindowListener(D dataSource, DataSourceWindowListener<D> listener) {\n        synchronized (windowListeners) {\n            List<DataSourceWindowListener> listeners = windowListeners.get(dataSource);\n            if (listeners == null) {\n                listeners = new ArrayList<>();\n                windowListeners.put(dataSource, listeners);\n            }\n            listeners.add(listener);\n        }\n    }\n    \n    public <D extends DataSource> void removeWindowListener(D dataSource, DataSourceWindowListener<D> listener) {\n        synchronized (windowListeners) {\n            List<DataSourceWindowListener> listeners = windowListeners.get(dataSource);\n            if (listeners != null) listeners.remove(listener);\n        }\n    }\n    \n    private <D extends DataSource> void notifyWindowOpened(D dataSource) {\n        synchronized (windowListeners) {\n            List<DataSourceWindowListener> listeners = windowListeners.get(dataSource);\n            if (listeners != null)\n                for (DataSourceWindowListener listener : new ArrayList<>(listeners))\n                    listener.windowOpened(dataSource);\n        }\n    }\n    \n    private <D extends DataSource> void notifyWindowClosed(D dataSource) {\n        synchronized (windowListeners) {\n            List<DataSourceWindowListener> listeners = windowListeners.get(dataSource);\n            if (listeners != null)\n                for (DataSourceWindowListener listener : new ArrayList<>(listeners))\n                    listener.windowClosed(dataSource);\n        }\n    }\n    \n    /**\n     * Closes the DataSource.\n     * \n     * @param dataSource DataSource to close.\n     */\n    public void closeDataSource(final DataSource dataSource) {\n        processor.post(new Runnable() {\n            public void run() {\n                // Resolve viewmaster\n                DataSource viewMaster = getViewMaster(dataSource);\n\n                // Resolve cached window\n                final DataSourceWindow window = openedWindows.get(viewMaster);\n                if (window == null) return; // Window not opened\n                \n                if (dataSource == viewMaster) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            window.removeAllViews();\n                        }\n                    });\n                } else {\n                    // Remove all views of the dataSource\n                    Set<DataSourceView> views = openedViews.get(dataSource);\n                    if (views != null) {\n                        final Set<DataSourceView> viewsF = new HashSet<>(views);\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                for (DataSourceView view : viewsF)\n                                    if (window.containsView(view)) window.removeView(view);\n                            }\n                        });\n                    }\n                }\n            }\n        });\n    }\n    \n    /**\n     * Opens the DataSource if needed and selects the DataSourceView.\n     * \n     * @param view DataSourceView to select.\n     */\n    public void selectView(final DataSourceView view) {\n        processor.post(new Runnable() {\n            public void run() {\n                openWindowAndAddView(view.getDataSource(), view, 0, true, true, true);\n            }\n        });\n    }\n    \n    \n    private boolean reloadingView;\n    \n    private void openWindowAndAddView(DataSource dataSource, DataSourceView view, int viewIndex, final boolean selectView, final boolean selectWindow, final boolean windowToFront) {\n        // Resolve viewmaster\n        final DataSource viewMaster = getViewMaster(dataSource);\n\n        // Resolve cached window\n        final DataSourceWindow[] window = new DataSourceWindow[1];\n        window[0] = openedWindows.get(viewMaster);\n        final boolean wasOpened = window[0] != null;\n        \n        final ProgressHandle pHandle = !wasOpened || reloadingView ?\n            ProgressHandle.createHandle(NbBundle.getMessage(DataSourceWindowManager.class, \"LBL_Opening\",    // NOI18N\n            DataSourceDescriptorFactory.getDescriptor(dataSource).getName())) : null;\n        \n        try {\n\n            // Viewmaster's window not cached (opened), create\n            if (!wasOpened || reloadingView) {\n                // Setup progress\n                pHandle.setInitialDelay(0);\n                pHandle.start();\n                \n                if (!reloadingView) {\n                    try {\n                        SwingUtilities.invokeAndWait(new Runnable() {\n                            public void run() {\n                                window[0] = new DataSourceWindow(viewMaster);\n                            }\n                        });\n                    } catch (Exception e) {\n                        LOGGER.severe(\"Failed to create window for \" + dataSource); // NOI18N\n                    }\n                    openedWindows.put(viewMaster, window[0]);\n                } else {\n                    reloadingView = false;\n                }\n\n                List<? extends DataSourceView> views = DataSourceViewsManager.sharedInstance().getViews(viewMaster);\n                addViews(window[0], views);\n            }\n\n            // Viewmaster opened, add views for the dataSource\n            if (dataSource != viewMaster) {\n                List<? extends DataSourceView> views = DataSourceViewsManager.sharedInstance().getViews(dataSource);\n                addViews(window[0], views);\n                if (selectView && view == null && viewIndex >= 0) {\n                    if (viewIndex >= views.size()) viewIndex = -1;\n                    if (viewIndex != -1) view = views.get(viewIndex);\n                }\n            }\n\n            // Resolve view to select\n            if (selectView && view == null && viewIndex > 0) {\n                List<DataSourceView> views = window[0].getViews();\n                if (viewIndex >= views.size()) viewIndex = -1;\n                if (viewIndex != -1) view = views.get(viewIndex);\n            }\n            \n            // Open window\n            final DataSourceView viewToSelectF = selectView ? view : null;\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    if (viewToSelectF != null) {\n                        if (window[0].containsView(viewToSelectF)) {\n                            window[0].selectView(viewToSelectF);\n                        } else {\n                            if (LOGGER.isLoggable(Level.WARNING)) {\n                                LOGGER.warning(\"Tried to select not opened view \" + viewToSelectF); // NOI18N\n                            }\n                        }\n                    }\n                    if (!wasOpened) window[0].open();\n                    if (selectWindow) window[0].requestActive();\n                    if (windowToFront) window[0].toFront();\n                    \n                    if (!wasOpened) notifyWindowOpened(dataSource);\n                }\n            });\n        \n        } finally {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { if (pHandle != null) pHandle.finish(); }\n            });\n        }\n    }\n    \n    \n    static DataSource getViewMaster(DataSource dataSource) {\n        DataSource master = dataSource.getMaster();\n        while (master != null && master != DataSource.ROOT) {\n            dataSource = master;\n            master = dataSource.getMaster();\n        }\n        return dataSource;\n    }\n    \n    \n    private <X extends DataSourceView> void addViews(final DataSourceWindow window, final List<X> views) {\n        // Compute views to add\n        final List<X> newViews = new ArrayList<>();\n        for (X view : views)\n            if (!window.containsView(view))\n                newViews.add(view);\n        \n        // Blocking notification that the view will be added\n        for (DataSourceView view : newViews) {\n            try {\n                DataSource dataSource = view.getDataSource();\n                Set<DataSourceView> cachedViews = openedViews.get(dataSource);\n                if (cachedViews == null) {\n                    cachedViews = new HashSet<>();\n                    openedViews.put(dataSource, cachedViews);\n                }\n                cachedViews.add(view);\n\n                view.viewWillBeAdded();\n            } catch (Exception e) {\n                LOGGER.log(Level.SEVERE, \"Failed to pre-initialize view \" + view, e);    // NOI18N\n            }\n        }\n\n        try {\n            SwingUtilities.invokeAndWait(new Runnable() {\n                public void run() {\n                    // Blocking adding of views to the window\n                    for (DataSourceView view : newViews) {\n                        try {\n                            window.addView(view);\n                        } catch (Exception e) {\n                            LOGGER.log(Level.SEVERE, \"Failed to initialize view \" + view, e);    // NOI18N\n                        }\n                    }\n                }\n            });\n        } catch (Exception e) {\n            LOGGER.log(Level.SEVERE, \"Failed to initialize views for \" + window.getDataSource(), e);    // NOI18N\n        }\n\n        // Blocking notification that the view has been added\n        for (DataSourceView view : newViews) {\n            try {\n                view.viewAdded();\n            } catch (Exception e) {\n                LOGGER.log(Level.SEVERE, \"Failed to post-initialize view \" + view, e);    // NOI18N\n            }\n        }\n    }\n    \n    \n    void reopenDataSource(final DataSource dataSource) {\n        processor.post(new Runnable() {\n            public void run() {\n                DataSource viewMaster = getViewMaster(dataSource);\n                final DataSourceWindow window = viewMaster == null ? null : openedWindows.get(viewMaster);\n                \n                if (window == null) return;\n                \n                Set<DataSourceView> _views = openedViews.get(dataSource);\n                if (_views == null) return;\n                \n                final Map<String, DataSourceView> oldViews = new HashMap<>();\n                for (DataSourceView view : _views) oldViews.put(view.getName(), view);\n                SwingUtilities.invokeLater(new Runnable () {\n                    public void run() {\n                        final Set<DataSourceView> opened = openedViews.get(dataSource);\n                        for (DataSourceView view : oldViews.values()) {\n                            window.clearView(view, processor);\n                            opened.remove(view);\n                        }\n                        \n                        processor.post(new Runnable() {\n                            public void run() {\n                                final List<? extends DataSourceView> newViews = DataSourceViewsManager.sharedInstance().getViews(dataSource);\n                                for (DataSourceView view : newViews) {\n                                    opened.add(view);\n                                    try { view.viewWillBeAdded(); }\n                                    catch (Exception e) { LOGGER.log(Level.SEVERE, \"Failed to pre-initialize view \" + view, e); } // NOI18N\n                                    oldViews.remove(view.getName());\n                                }\n                                if (opened.isEmpty()) openedViews.remove(dataSource);\n                                \n                                SwingUtilities.invokeLater(new Runnable() {\n                                    public void run() {\n                                        for (DataSourceView view : oldViews.values()) window.closeUnregisteredView(view);\n                                        for (int i = 0; i < newViews.size(); i++) window.updateView(newViews.get(i), i);\n                                    }\n                                });\n                            }\n                        });\n                    }\n                });\n            }\n        });\n    }\n    \n    \n    void unregisterClosedWindow(DataSourceWindow window) {\n        DataSource dataSource = window.getDataSource();\n        openedWindows.remove(dataSource);\n        notifyWindowClosed(dataSource);\n    }\n    \n    void unregisterClosedView(DataSourceView view) {\n        DataSource dataSource = view.getDataSource();\n        Set<DataSourceView> views = openedViews.get(dataSource);\n        if (views != null) {\n            views.remove(view);\n            if (views.isEmpty()) openedViews.remove(dataSource);\n        } else if (LOGGER.isLoggable(Level.WARNING)) {\n            LOGGER.warning(\"Tried to unregister not opened view \" + view);  // NOI18N\n        }\n    }\n    \n    \n    private DataSourceWindowManager() {\n        closingHandler = new Runnable() {\n            public void run() {\n                Collection<Set<DataSourceView>> allViews = openedViews.values();\n                for (Set<DataSourceView> dataSourceViews : allViews)\n                    for (DataSourceView view : dataSourceViews)\n                        view.viewWillBeRemoved();\n            }\n        };\n        VisualVM.getInstance().notifyWhenClosing(closingHandler);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/DataSourceWindowTabbedPane.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Insets;\nimport javax.swing.ImageIcon;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.uisupport.ProfilerTabbedPane;\nimport org.openide.util.NbBundle;\n\n/**\n * TabbedPane container allowing to control if tabs can be closed or not\n *\n * @author Jiri Sedlacek\n *\n */\nabstract class DataSourceWindowTabbedPane extends JPanel {\n\n  private final ProfilerTabbedPane tabpane;\n  \n  // --- Workaround to use the correct Close button on Windows 10 --------------\n  \n//    static {\n//        if (isWindows10() && isWindowsXPLaF()) {\n//            UIManager.put( \"nb.close.tab.icon.enabled.name\", \"org/openide/awt/resources/win8_bigclose_enabled.png\"); // NOI18N\n//            UIManager.put( \"nb.close.tab.icon.pressed.name\", \"org/openide/awt/resources/win8_bigclose_pressed.png\"); // NOI18N\n//            UIManager.put( \"nb.close.tab.icon.rollover.name\", \"org/openide/awt/resources/win8_bigclose_rollover.png\"); // NOI18N\n//        }\n//    }\n\n//    private static boolean isWindows10() {\n//        String osName = System.getProperty (\"os.name\"); // NOI18N\n//        return osName.indexOf(\"Windows 10\") >= 0 // NOI18N\n//            || (osName.equals( \"Windows NT (unknown)\" ) && \"10.0\".equals( System.getProperty(\"os.version\") )); // NOI18N\n//    }\n\n//    private static boolean isWindowsXPLaF() {\n//        Boolean isXP = (Boolean)Toolkit.getDefaultToolkit().\n//                        getDesktopProperty(\"win.xpstyle.themeActive\"); // NOI18N\n//        return isWindowsLaF() && (isXP == null ? false : isXP.booleanValue());\n//    }\n    \n//    private static boolean isWindowsLaF () {\n//        String lfID = UIManager.getLookAndFeel().getID();\n//        return lfID.endsWith(\"Windows\"); // NOI18N\n//    }\n    \n  // ---------------------------------------------------------------------------\n  \n  \n  DataSourceWindowTabbedPane() {\n    super(new BorderLayout());\n    \n    tabpane = new ProfilerTabbedPane() {\n        @Override\n        protected void closeTab(Component component) {\n            closeView((ViewContainer)component);\n        }\n    };\n//    tabpane.setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT);\n    \n    // GH-52 - true would break Tab navigation\n    tabpane.setFocusCycleRoot(false);\n      \n    // Clear default border for fill up the entire DataSourceWindow\n    tabpane.setOpaque(false);\n    \n    if (UIManager.getLookAndFeel().getID().equals(\"Aqua\")) { // NOI18N\n        tabpane.setBorder(BorderFactory.createEmptyBorder(0, -11, -13, -10));\n    } else {\n        tabpane.setBorder(BorderFactory.createEmptyBorder());\n        Insets i = UIManager.getInsets(\"TabbedPane.contentBorderInsets\"); // NOI18N\n        if (i != null) tabpane.setBorder(BorderFactory.createEmptyBorder(0, -i.left, -i.bottom, -i.right));\n    }\n    \n    add(tabpane, BorderLayout.CENTER);\n  }\n\n\n  public final boolean requestFocusInWindow() {\n      Component sel = tabpane.getSelectedComponent();\n      if (sel != null) return sel.requestFocusInWindow();\n      else return super.requestFocusInWindow();\n  }\n  \n  public void addView(DataSource dataSource, DataSourceView view) {\n      ViewContainer container = new ViewContainer(new DataSourceCaption(view.getDataSource()), view);\n      tabpane.addTab(view.getName(), new ImageIcon(view.getImage()), container, null, view.isClosable());\n  }\n  \n  public void insertView(DataSource dataSource, DataSourceView view, int index) {\n      ViewContainer container = new ViewContainer(new DataSourceCaption(view.getDataSource()), view);\n      tabpane.insertTab(view.getName(), new ImageIcon(view.getImage()), container, null, view.isClosable(), index);\n  }\n  \n  public void removeView(int index) {\n      ViewContainer container = (ViewContainer)tabpane.getComponentAt(index);\n      tabpane.removeTabAt(index);\n      container.getCaption().finish();\n  }\n  \n  void clearView(int index) {\n      ViewContainer container = (ViewContainer)tabpane.getComponentAt(index);\n      container.removeAll();\n      if (container.caption != null) container.caption.finish();\n      container.setReloading();\n      container.doLayout();\n      container.repaint();\n  }\n  \n  ViewContainer getContainer(DataSourceView view) {\n      String name = view.getName();\n//      int position = view.getPreferredPosition();\n\n      for (int i = 0; i < tabpane.getTabCount(); i++)\n        if (tabpane.getTitleAt(i).equals(name))\n            return (ViewContainer)tabpane.getComponentAt(i);\n      \n      return null;\n  }\n  \n  public DataSourceView getView(ViewContainer container) {\n      return container.getView();\n  }\n  \n  public int indexOfView(final DataSourceView view) {\n      if (!view.hasComponent()) return -1;\n      final int[] index = new int[1];\n      index[0] = -1;\n      UISupport.runInEventDispatchThreadAndWait(new Runnable() {\n          public void run() {\n              for (int i = 0; i < tabpane.getTabCount(); i++)\n                  if (((ViewContainer)tabpane.getComponentAt(i)).getViewComponent() == view.getView()) index[0] = i;\n          }\n      });\n      return index[0];\n  }\n  \n  public List<DataSourceView> getViews() {\n      List<DataSourceView> views = new ArrayList<>();\n      \n      for (int i = 0; i < tabpane.getTabCount(); i++) {\n          ViewContainer container = (ViewContainer)tabpane.getComponentAt(i);\n          views.add(container.getView());\n      }\n      \n      return views;\n  }\n  \n  public void setViewIndex(int index) {\n    tabpane.setSelectedIndex(index);\n  }\n  \n  public void setViewBackground(int index, Color background) {\n      tabpane.setBackgroundAt(index, background);\n  }\n  \n  \n  protected abstract void closeView(DataSourceWindowTabbedPane.ViewContainer view);\n  \n  \n  static class ViewContainer extends JPanel {\n      \n      private DataSourceCaption caption;\n      private DataSourceView view;\n      private DataViewComponent viewComponent;\n      \n      ViewContainer(DataSourceCaption caption, DataSourceView view) {\n          Color backgroundColor = UISupport.getDefaultBackground();\n          \n          setLayout(new BorderLayout());\n          setBorder(BorderFactory.createMatteBorder(0, 5, 5, 5, backgroundColor));\n          setBackground(backgroundColor);\n          setFocusable(false);\n\n          setView(view);\n          setCaption(caption);\n      }\n\n      public final boolean requestFocusInWindow() {\n        if (getComponentCount() > 0) return getComponent(0).requestFocusInWindow();\n        else return super.requestFocusInWindow();\n      }\n      \n      final void setCaption(DataSourceCaption caption) {\n          this.caption = caption;\n          if (caption != null) {\n              caption.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0));\n              add(caption, BorderLayout.NORTH);\n          }\n      }\n      \n      public DataSourceCaption getCaption() { return caption; }\n      \n      final void setView(DataSourceView view) {\n          this.view = view;\n          this.viewComponent = view.getView();\n          add(viewComponent, BorderLayout.CENTER);\n          setName(view.getName());\n      }\n      \n      public DataSourceView getView() { return view; }\n      \n      public DataViewComponent getViewComponent() { return viewComponent; }\n      \n      final void setReloading() {\n        JLabel l = new JLabel(NbBundle.getMessage(DataSourceWindowTabbedPane.class, \"DataSourceCaption_MSG_Reloading\"), JLabel.CENTER); // NOI18N\n        l.setEnabled(false);        \n        add(l, BorderLayout.CENTER);\n      }\n  }\n  \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/DesktopUtils.java",
    "content": "/*\n/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui;\n\nimport java.awt.Desktop;\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.URI;\n\n/**\n * Support for java.awt.Desktop\n *\n * @author Jiri Sedlacek\n */\npublic final class DesktopUtils {\n\n    private static final Object allowDesktopOpen = System.getProperty(\"org.graalvm.visualvm.core.ui.DesktopUtils.allowDesktopOpen\");  // NOI18N\n\n    private static boolean desktopSupported;\n    private static boolean desktopSupportedInitialized = false;\n    private static boolean browseAvailable;\n    private static boolean browseAvailableInitialized = false;\n    private static boolean openAvailable;\n    private static boolean openAvailableInitialized = false;\n\n\n    /**\n     * Returns true if java.awt.Desktop is supported on host platform.\n     * \n     * @return true if java.awt.Desktop is supported on host platform, false otherwise.\n     */\n    public synchronized static boolean isDesktopSupported() {\n        if (!desktopSupportedInitialized) {\n            desktopSupported = Desktop.isDesktopSupported();\n            desktopSupportedInitialized = true;\n        }\n        return desktopSupported;\n    }\n    \n    // NOTE: should always return true if in NetBeans IDE (uses its own user-customizable mechanism)\n    /**\n     * Returns true if opening a www address in a web browser is supported on host platform.\n     * \n     * @return true if opening a www address in a web browser is supported on host platform, false otherwise.\n     */\n    public synchronized static boolean isBrowseAvailable() {\n        if (!browseAvailableInitialized) {\n            if (!isDesktopSupported()) browseAvailable = false;\n            else browseAvailable = Desktop.getDesktop().isSupported(Desktop.Action.BROWSE);\n            browseAvailableInitialized = true;\n        }\n        return browseAvailable;\n    }\n    \n    /**\n     * Returns true if opening a file in native displayer is supported on host platform.\n     * \n     * @return true if opening a file in native displayer is supported on host platform, false otherwise.\n     */\n    public synchronized static boolean isOpenAvailable() {\n        if (!openAvailableInitialized) {\n             // NOTE: Open is disabled by default, crashes the VM at least on Windows\n            if (\"true\".equals(allowDesktopOpen) && isDesktopSupported()) openAvailable = Desktop.getDesktop().isSupported(Desktop.Action.OPEN); // NOI18N\n            else openAvailable = false;\n            openAvailableInitialized = true;\n        }\n        return openAvailable;\n    }\n    \n    // NOTE: If in NetBeans IDE use HtmlBrowser.URLDisplayer.showURL(URL u)\n    /**\n     * Performs Desktop.getDesktop().browse(URI).\n     * \n     * @param uri URI to open.\n     * @throws java.io.IOException\n     */\n    public static void browse(URI uri) throws IOException {\n        Desktop.getDesktop().browse(uri);\n    }\n    \n    /**\n     * Performs Desktop.getDesktop().open(File).\n     * \n     * @param file File to open.\n     * @throws java.io.IOException\n     */\n    public static void open(File file) throws IOException {\n        Desktop.getDesktop().open(file);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/PluggableDataSourceViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * Extensible DataSourceViewProvider with support for customizations via DataSourceViewPluginProvider.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class PluggableDataSourceViewProvider<X extends DataSource> extends DataSourceViewProvider<X> {\n    \n    /**\n     * Set defining all pluggable locations.\n     */\n    public static final Set<Integer> ALL_LOCATIONS;\n    static {\n        ALL_LOCATIONS = new HashSet<>();\n        ALL_LOCATIONS.add(DataViewComponent.TOP_LEFT);\n        ALL_LOCATIONS.add(DataViewComponent.TOP_RIGHT);\n        ALL_LOCATIONS.add(DataViewComponent.BOTTOM_LEFT);\n        ALL_LOCATIONS.add(DataViewComponent.BOTTOM_RIGHT);\n    }\n    \n    private final Set<DataSourceViewPluginProvider<X>> pluginProviders =\n            Collections.synchronizedSet(new HashSet<>());\n    private final Map<X, Set<DataSourceViewPluginProvider<X>>> pluginProvidersCache =\n            Collections.synchronizedMap(new HashMap<>());\n    \n    \n    /**\n     * Registers new DataSourceViewPluginProvider.\n     * \n     * @param pluginProvider DataSourceViewPluginProvider to register.\n     */\n    public final void registerPluginProvider(DataSourceViewPluginProvider<X> pluginProvider) {\n        pluginProviders.add(pluginProvider);\n    }\n    \n    /**\n     * Unregisters DataSourceViewPluginProvider.\n     * \n     * @param pluginProvider DataSourceViewPluginProvider to unregister.\n     */\n    public final void unregisterPluginProvider(DataSourceViewPluginProvider<X> pluginProvider) {\n        pluginProviders.remove(pluginProvider);\n    }\n    \n    /**\n     * Returns Set of all locations of the DataSourceView which can be customized by DataSourceViewPluginProviders.\n     * \n     * @param view DataSourceView to be customized.\n     * @return Set of all locations of the DataSourceView which can be customized by DataSourceViewPluginProviders.\n     */\n    public abstract Set<Integer> getPluggableLocations(DataSourceView view);\n    \n    \n    /**\n     * Saves the DataSourceView for the DataSource into the Snapshot.\n     * \n     * @param dataSource DataSource for which to save the view.\n     * @param snapshot Snapshot into which to save the view.\n     */\n    protected void saveView(X dataSource, Snapshot snapshot) { }\n    \n    \n    void viewSaveView(X dataSource, Snapshot snapshot) {\n        super.viewSaveView(dataSource, snapshot);\n        Set<DataSourceViewPluginProvider<X>> providers = getProviders(dataSource, false);\n        for (DataSourceViewPluginProvider<X> provider : providers)\n            if (provider.supportsSavePluginFor(dataSource, snapshot.getClass()))\n                provider.savePlugin(dataSource, snapshot);\n    }\n    \n    void processCreatedComponent(DataSourceView view, DataViewComponent component) {\n        X dataSource = (X)view.getDataSource();\n        Set<DataSourceViewPluginProvider<X>> providers = getProviders(dataSource, true);\n        for (DataSourceViewPluginProvider<X> provider : providers) {\n            Set<Integer> pluggableLocations = getPluggableLocations(view);\n            DataSourceViewPlugin plugin = provider.getPlugin(dataSource);\n            for (int pluggableLocation : pluggableLocations) {\n                DataViewComponent.DetailsView pluginView = plugin.createView(pluggableLocation);\n                if (pluginView != null) component.addDetailsView(pluginView, pluggableLocation);\n            }\n        }\n    }\n    \n    void viewWillBeAdded(DataSourceView view) {\n        X dataSource = (X)view.getDataSource();\n        Set<DataSourceViewPluginProvider<X>> providers = getProviders(dataSource, true);\n        for (DataSourceViewPluginProvider<X> provider : providers)\n            provider.getPlugin(dataSource).pluginWillBeAdded();\n    }\n    \n    void viewAdded(DataSourceView view) {\n        X dataSource = (X)view.getDataSource();\n        Set<DataSourceViewPluginProvider<X>> providers = getProviders(dataSource, true);\n        for (DataSourceViewPluginProvider<X> provider : providers)\n            provider.getPlugin(dataSource).pluginAdded();\n    }\n    \n    void viewRemoved(DataSourceView view) {\n        X dataSource = (X)view.getDataSource();\n        Set<DataSourceViewPluginProvider<X>> providers = getProviders(dataSource, true);\n        for (DataSourceViewPluginProvider<X> provider : providers)\n            provider.getPlugin(dataSource).pluginRemoved();\n        pluginProvidersCache.remove(dataSource);\n        super.viewRemoved(view);\n    }\n    \n    \n    private Set<DataSourceViewPluginProvider<X>> getProviders(X dataSource, boolean cache) {\n        Set<DataSourceViewPluginProvider<X>> providers = pluginProvidersCache.get(dataSource);\n        if (providers != null) return providers;\n        providers = new HashSet<>(pluginProviders);\n        Set<DataSourceViewPluginProvider<X>> compatibleProviders = new HashSet<>();\n        for (DataSourceViewPluginProvider<X> provider : providers)\n            if (provider.supportsPluginFor(dataSource))\n                compatibleProviders.add(provider);\n        if (cache) pluginProvidersCache.put(dataSource, compatibleProviders);\n        return compatibleProviders;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/ActionUtils.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui.actions;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.explorer.ExplorerSupport;\nimport java.util.Collections;\nimport java.util.Set;\n\n/**\n * Utils class providing useful methods mostly for Actions implementation.\n *\n * @author Jiri Sedlacek\n */\npublic final class ActionUtils {\n    \n    /**\n     * Returns selected DataSource is exactly one DataSource is selected in Applications window, null otherwise.\n     * @return selected DataSource is exactly one DataSource is selected in Applications window, null otherwise.\n     */\n    public static DataSource getSelectedDataSource() {\n        Set<DataSource> selectedDataSources = getSelectedDataSources();\n        return (selectedDataSources.size() == 1 ? selectedDataSources.iterator().next() : null);\n    }\n    \n    /**\n     * Returns selected DataSource is exactly one DataSource of a certain type is selected in Applications window, null otherwise.\n     * \n     * @param <X> any DataSource.\n     * @param scope DataSource type.\n     * @return selected DataSource is exactly one DataSource of a certain type is selected in Applications window, null otherwise.\n     */\n    public static <X extends DataSource> X getSelectedDataSource(Class<X> scope) {\n        Set<X> selectedDataSources = getSelectedDataSources(scope);\n        return (selectedDataSources.size() == 1 ? selectedDataSources.iterator().next() : null);\n    }\n    \n    /**\n     * Returns Set of selected DataSources in Applications window or empty Set for no selection.\n     * \n     * @return Set of selected DataSources in Applications window or empty Set for no selection.\n     */\n    public static Set<DataSource> getSelectedDataSources() {\n        Set<DataSource> selectedDataSources = ExplorerSupport.sharedInstance().getSelectedDataSources();\n        return selectedDataSources;\n    }\n    \n    /**\n     * Returns Set of selected DataSources of a certain type in Applications window or empty Set if no DataSource of this type is selected.\n     * \n     * @param <X> any DataSource.\n     * @param scope DataSource type.\n     * @return Set of selected DataSources of a certain type in Applications window or empty Set if no DataSource of this type is selected.\n     */\n    public static <X extends DataSource> Set<X> getSelectedDataSources(Class<X> scope) {\n        Set<DataSource> selectedDataSources = getSelectedDataSources();\n        Set<X> filteredSelectedDataSources = Utils.getFilteredSet(selectedDataSources, scope);\n        return selectedDataSources.size() == filteredSelectedDataSources.size() ?\n            filteredSelectedDataSources : Collections.emptySet();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nMSG_Cannot_perform_action_in_this_context=Cannot perform action in this context\n\nLBL_Delete=&Delete\n\nLBL_Delete_Snapshot=Delete Snapshot\n\nLBL_Load=Load\n\nMSG_Selected_file_does_not_exist=Selected file does not exist.\n\nMSG_Selected_file_does_not_match_snapshot_type=Selected file does not match snapshot type.\n\nLBL_Load1=&Load...\n\nLBL_Load_Snapshot=Load Snapshot\n\nLBL_Open=&Open\n\nDESCR_Open=Open\n\nLBL_All_Snapshots=All Supported Files\n\nLBL_Remove=&Remove\n\nDESCR_Remove=Remove\n\nLBL_Rename=Rename\n\nLBL_New_Name=New Name:\n\nLBL_OK=OK\n\nLBL_Rename1=Re&name...\n\nLBL_Save_As=&Save As...\n\nLBL_Save_Snapshot_As=Save Snapshot As\n\n\nLoadRecentSnapshot_LoadRecentItem=Load &Recent\nLoadRecentSnapshot_NoRecentSnapshots=No Recent Snapshots\nLoadRecentSnapshot_ClearRecentSnapshots=&Clear Recent Snapshots\nLoadRecentSnapshot_CannotLoadMsg=Snapshot {0} cannot be loaded.\nLoadRecentSnapshot_NotAvailableMsg=Snapshot {0} is not available.\n\n# if no file dropped on the editor could be opened\nMSG_could_not_open_any_file=The files could not be opened for the following reasons:\n# if some of the files dropped on the editor could be opened, but some not\nMSG_could_not_open_some_files=Some of the files could not be opened for the following reasons:\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/DataSourceAction.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui.actions;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.explorer.ExplorerSelectionListener;\nimport org.graalvm.visualvm.core.explorer.ExplorerSupport;\nimport java.beans.PropertyChangeListener;\nimport java.util.Collections;\nimport java.util.Set;\nimport javax.swing.AbstractAction;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\n\n/**\n * Abstract Action which can be used as a basis for any DataSource-aware action.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class DataSourceAction<X extends DataSource> extends AbstractAction {\n\n    private final Class<X> scope;\n    private boolean initialized = false;\n\n\n    /**\n     * Creates new instance of DataSourceAction available for defined DataSource type.\n     * \n     * @param scope DataSource type for the action.\n     */\n    public DataSourceAction(Class<X> scope) {\n        this.scope = scope;\n    }\n    \n    \n    /**\n     * Updates enabled state based on currently selected DataSources in Applications window.\n     * \n     * @param selectedDataSources currently selected DataSources in Applications window.\n     */\n    protected abstract void updateState(Set<X> selectedDataSources);\n\n    /**\n     * Displays a dialog that the action cannot be invoked in current context.\n     */\n    protected void notifyCannotPerform() {\n        DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(\n                NbBundle.getMessage(DataSourceAction.class,\n                \"MSG_Cannot_perform_action_in_this_context\"), // NOI18N\n                NotifyDescriptor.ERROR_MESSAGE));\n    }\n    \n    /**\n     * Initializes the action.\n     * By default registers selection listener which invokes\n     * {@link #updateState(Set) updateState(Set&lt;DataSource&gt;)} on selection change.\n     */\n    protected void initialize() {\n        ExplorerSupport.sharedInstance().addSelectionListener(new ExplorerSelectionListener() {\n            public void selectionChanged(Set<DataSource> selected) {\n                Set<X> selectedFiltered = Utils.getFilteredSet(selected, getScope());\n                if (selectedFiltered.size() == selected.size()) DataSourceAction.this.updateState(selectedFiltered);\n                else updateState(Collections.emptySet());\n            }\n        });\n        \n        updateState(ActionUtils.getSelectedDataSources(getScope()));\n    }\n    \n    public final Object getValue(String key) {\n        doInitialize();\n        return super.getValue(key);\n    }\n    \n    public final boolean isEnabled() {\n        doInitialize();\n        return super.isEnabled();\n    }\n    \n    public final void addPropertyChangeListener(PropertyChangeListener listener) {\n        doInitialize();\n        super.addPropertyChangeListener(listener);\n    }\n\n\n    /**\n     * Returns DataSource type for this action.\n     * \n     * @return DataSource type for this action.\n     */\n    public final Class<X> getScope() {\n        return scope;\n    }\n    \n    \n    private synchronized void doInitialize() {\n        if (initialized) return;\n        initialized = true;\n        initialize();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/DeleteSnapshotAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.core.ui.actions;\n\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport java.awt.event.ActionEvent;\nimport java.util.Set;\nimport org.openide.util.NbBundle;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass DeleteSnapshotAction extends MultiDataSourceAction<Snapshot> {\n    \n//    private static final Image ICON_16 =  Utilities.loadImage(\"org/graalvm/visualvm/core/ui/resources/saveSnapshot.png\");\n//    private static final Image ICON_24 =  Utilities.loadImage(\"org/graalvm/visualvm/core/ui/resources/saveSnapshot24.png\");\n    \n    private static DeleteSnapshotAction instance;\n    \n    public static DeleteSnapshotAction instance() {\n        if (instance == null) \n            instance = new DeleteSnapshotAction();\n        return instance;\n    }\n    \n    \n    protected void actionPerformed(Set<Snapshot> snapshots, ActionEvent actionEvent) {\n        for (Snapshot snapshot : snapshots) snapshot.delete();\n    }\n\n    protected boolean isEnabled(Set<Snapshot> snapshots) {\n        for (Snapshot snapshot : snapshots)\n            if (!snapshot.supportsDelete()) return false;\n        return Utils.areDataSourcesIndependent(snapshots);\n    }\n    \n    \n    private DeleteSnapshotAction() {\n        super(Snapshot.class);\n        putValue(NAME, NbBundle.getMessage(DeleteSnapshotAction.class, \"LBL_Delete\"));  // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(DeleteSnapshotAction.class, \"LBL_Delete_Snapshot\")); // NOI18N\n//        putValue(SMALL_ICON, new ImageIcon(ICON_16));\n//        putValue(\"iconBase\", new ImageIcon(ICON_24));\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/LoadRecentSnapshot.java",
    "content": "/*\n *  Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.core.ui.actions;\n\nimport org.graalvm.visualvm.core.snapshot.RegisteredSnapshotCategories;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport java.awt.event.ActionEvent;\nimport java.io.File;\nimport java.text.MessageFormat;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.prefs.Preferences;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.SwingUtilities;\nimport javax.swing.filechooser.FileFilter;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.openide.awt.Mnemonics;\nimport org.openide.awt.StatusDisplayer;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.actions.Presenter;\n\n/**\n * Support for reopening already opened snapshots.\n *\n * @author Jiri Sedlacek\n */\nclass LoadRecentSnapshot implements Presenter.Menu {\n    \n    private static final String PROP_LOAD_RECENT = \"LoadRecentSnapshot.item.\"; // NOI18N\n    \n    private static final int MAX_RECENT_ITEMS = 9;\n    \n    private static LoadRecentSnapshot INSTANCE;\n    \n    private final Preferences prefs;\n    private final List<String> files;\n    \n    private JMenu menu;\n    \n    \n    public static synchronized LoadRecentSnapshot instance() {\n        if (INSTANCE == null) INSTANCE = new LoadRecentSnapshot();\n        return INSTANCE;\n    }\n    \n    void setupMenu() {\n        assert SwingUtilities.isEventDispatchThread();\n        menu.removeAll();\n        if (files.isEmpty()) {\n            menu.add(new JMenuItem(NbBundle.getMessage(LoadRecentSnapshot.class, \"LoadRecentSnapshot_NoRecentSnapshots\")) {{ setEnabled(false); }}); // NOI18N\n        } else {\n            int i = 0;\n            for (String file : files) menu.add(new RecentFileItem(file, ++i));\n            menu.addSeparator();\n            menu.add(new ClearRecentItem());\n        }\n    }\n\n    @Override\n    public JMenuItem getMenuPresenter() {\n        if (menu == null) {\n            menu = new JMenu();\n            Mnemonics.setLocalizedText(menu, NbBundle.getMessage(LoadRecentSnapshot.class, \"LoadRecentSnapshot_LoadRecentItem\")); // NOI18N\n        }\n        setupMenu();\n        return menu;\n    }\n    \n    \n    void addFile(File file) {\n        String path = file.getAbsolutePath();\n        \n        if (files.contains(path)) {\n            files.remove(path);\n            files.add(0, path);\n        } else {\n            if (files.size() == MAX_RECENT_ITEMS) files.remove(MAX_RECENT_ITEMS - 1);\n            files.add(0, path);\n        }\n        \n        saveFiles(prefs, files);\n        SwingUtilities.invokeLater(this::setupMenu);\n    }\n    \n    \n    private static List<String> loadFiles(Preferences p) {\n        List<String> f = new ArrayList<>(MAX_RECENT_ITEMS);\n        \n        int i = 0;\n        String s = p.get(PROP_LOAD_RECENT + i, null);\n        while (s != null && i < MAX_RECENT_ITEMS) {\n            f.add(s);\n            s = p.get(PROP_LOAD_RECENT + ++i, null);\n        }\n        \n        return f;\n    }\n    \n    private static void saveFiles(Preferences p, List<String> f) {\n        int i = 0;\n        while (p.get(PROP_LOAD_RECENT + i, null) != null) p.remove(PROP_LOAD_RECENT + i++);\n        \n        i = 0;\n        for (String s : f) p.put(PROP_LOAD_RECENT + i++, s);\n    }\n    \n    \n    private LoadRecentSnapshot() {\n        prefs = NbPreferences.forModule(LoadRecentSnapshot.class);\n        files = loadFiles(prefs);\n    }\n    \n    \n    private class RecentFileItem extends JMenuItem {\n        \n        private final String f;\n        private final File file;\n        \n        RecentFileItem(String f, int idx) {\n            this.f = f;\n            file = new File(f);\n            Mnemonics.setLocalizedText(this, \"&\" + idx + \". \" + file.getName()); // NOI18N\n        }\n        \n        @Override\n        protected void fireStateChanged() {\n            boolean active = isSelected() || isArmed();\n            StatusDisplayer.getDefault().setStatusText(active ? file.getAbsolutePath() : null);\n            super.fireStateChanged();\n        }\n        \n        @Override\n        protected void fireActionPerformed(ActionEvent e) {\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    if (file.exists()) {\n                        List<SnapshotCategory> categories = RegisteredSnapshotCategories.sharedInstance().getOpenSnapshotCategories();\n                        List<FileFilter> fileFilters = new ArrayList<>();\n                        for (SnapshotCategory category : categories) fileFilters.add(category.getFileFilter());\n                        \n                        for (FileFilter ff : fileFilters) if (ff.accept(file)) {\n                            categories.get(fileFilters.indexOf(ff)).openSnapshot(file);\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    files.remove(f);\n                                    files.add(0, f);\n                                    saveFiles(prefs, files);\n                                    setupMenu();\n                                }\n                            });\n                            return;\n                        }\n                        \n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                // NOTE: this happens when the appropriate SnapshotCategory is not registered\n                                //       should the snapshot be kept in the list?\n                                files.remove(f);\n                                saveFiles(prefs, files);\n                                setupMenu();\n                                ProfilerDialogs.displayError(MessageFormat.format(NbBundle.getMessage(LoadRecentSnapshot.class, \"LoadRecentSnapshot_CannotLoadMsg\"), file.getName()));\n                            }\n                        });\n                    } else {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                files.remove(f);\n                                saveFiles(prefs, files);\n                                setupMenu();\n                                ProfilerDialogs.displayError(MessageFormat.format(NbBundle.getMessage(LoadRecentSnapshot.class, \"LoadRecentSnapshot_NotAvailableMsg\"), file.getName()));\n                            }\n                        });\n                    }\n                }\n            });\n        }\n        \n    }\n    \n    private class ClearRecentItem extends JMenuItem {\n        \n        ClearRecentItem() {\n            Mnemonics.setLocalizedText(this, NbBundle.getMessage(LoadRecentSnapshot.class, \"LoadRecentSnapshot_ClearRecentSnapshots\")); // NOI18N\n        }\n        \n        @Override\n        protected void fireActionPerformed(ActionEvent e) {\n            files.clear();\n            saveFiles(prefs, files);\n            setupMenu();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/LoadSnapshotAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.core.ui.actions;\n\nimport org.graalvm.visualvm.core.snapshot.RegisteredSnapshotCategories;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategoriesListener;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport java.awt.Image;\nimport java.awt.event.ActionEvent;\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.AbstractAction;\nimport javax.swing.ImageIcon;\nimport javax.swing.JFileChooser;\nimport javax.swing.filechooser.FileFilter;\nimport javax.swing.plaf.basic.BasicFileChooserUI;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\nclass LoadSnapshotAction extends AbstractAction {\n    \n    private static final String ICON_PATH = \"org/graalvm/visualvm/core/ui/resources/loadSnapshot.png\";    // NOI18N\n    private static final Image ICON =  ImageUtilities.loadImage(ICON_PATH);\n    \n    private String lastFile = null;\n    private String lastFilter = null;\n    \n    \n    private static LoadSnapshotAction instance;\n        \n    public static synchronized LoadSnapshotAction instance() {\n        if (instance == null) {\n            instance = new LoadSnapshotAction();\n\n            instance.updateEnabled(true);\n            RegisteredSnapshotCategories.sharedInstance().addCategoriesListener(new SnapshotCategoriesListener() {\n                public void categoryRegistered(SnapshotCategory category) { instance.updateEnabled(false); }\n                public void categoryUnregistered(SnapshotCategory category) { instance.updateEnabled(false); }\n        });\n    }\n        return instance;\n    }\n    \n    public void actionPerformed(ActionEvent e) {\n        List<SnapshotCategory> categories = RegisteredSnapshotCategories.sharedInstance().getOpenSnapshotCategories();\n        if (categories.isEmpty()) return; // TODO: should display a notification dialog\n        \n        final List<FileFilter> fileFilters = new ArrayList<>();\n        for (SnapshotCategory category : categories) fileFilters.add(category.getFileFilter());\n        \n        JFileChooser chooser = new JFileChooser() {\n            public void setSelectedFile(File file) {\n                super.setSelectedFile(file);\n\n                // safety check\n                if (!(getUI() instanceof BasicFileChooserUI)) {\n                    return;\n                }\n\n                // grab the ui and set the filename\n                BasicFileChooserUI ui = (BasicFileChooserUI) getUI();\n                ui.setFileName(file == null ? \"\" : file.getName());  // NOI18N\n            }            \n        };\n        chooser.setDialogTitle(NbBundle.getMessage(LoadSnapshotAction.class, \"LBL_Load\"));  // NOI18N\n        chooser.setAcceptAllFileFilterUsed(false);\n        FileFilter allFilesFilter = new FileFilter() {\n            @Override\n            public boolean accept(File f) {\n                for (FileFilter ff : fileFilters)\n                    if (ff.accept(f)) return true;\n                return false;\n            }\n            @Override\n            public String getDescription() {\n                return NbBundle.getMessage(LoadSnapshotAction.class, \"LBL_All_Snapshots\");  // NOI18N\n            }\n            \n        };\n        chooser.addChoosableFileFilter(allFilesFilter);\n        int filterIndex = -1;\n        for (int i = 0; i < fileFilters.size(); i++) {\n            FileFilter fileFilter = fileFilters.get(i);\n            chooser.addChoosableFileFilter(fileFilter);\n            if (fileFilter.getDescription().equals(lastFilter)) filterIndex = i;\n        }\n        if (lastFile != null) chooser.setSelectedFile(new File(lastFile));\n        chooser.setFileFilter(filterIndex == -1 ? allFilesFilter : fileFilters.get(filterIndex));\n        if (chooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) {\n            File selectedFile = chooser.getSelectedFile();\n            if (selectedFile == null || !selectedFile.exists()) {\n                DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(\n                                            NbBundle.getMessage(LoadSnapshotAction.class,\n                                            \"MSG_Selected_file_does_not_exist\"), // NOI18N\n                                            NotifyDescriptor.ERROR_MESSAGE));\n            } else {\n                FileFilter fileFilter = chooser.getFileFilter();\n                if (fileFilter == allFilesFilter) {\n                    for (FileFilter ff : fileFilters)\n                        if (ff.accept(selectedFile)) {\n                            lastFile = selectedFile.getAbsolutePath();\n                            lastFilter = null;\n                            categories.get(fileFilters.indexOf(ff)).openSnapshot(selectedFile);\n                            LoadRecentSnapshot.instance().addFile(selectedFile);\n                            return;\n                        }\n                } else if (fileFilter.accept(selectedFile)) {\n                    lastFile = selectedFile.getAbsolutePath();\n                    lastFilter = fileFilter.getDescription();\n                    categories.get(fileFilters.indexOf(fileFilter)).openSnapshot(selectedFile);\n                    LoadRecentSnapshot.instance().addFile(selectedFile);\n                    return;\n                }\n                DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(\n                                        NbBundle.getMessage(LoadSnapshotAction.class,\n                                        \"MSG_Selected_file_does_not_match_snapshot_type\"), // NOI18N\n                                        NotifyDescriptor.ERROR_MESSAGE));\n            }\n        }\n    }\n    \n    private void updateEnabled(boolean lazily) {\n        final boolean isEnabled = !RegisteredSnapshotCategories.sharedInstance().getOpenSnapshotCategories().isEmpty();\n        \n        Runnable updater = new Runnable() {\n            public void run() { setEnabled(isEnabled); }\n        };\n        if (lazily) UISupport.runInEventDispatchThread(updater);\n        else UISupport.runInEventDispatchThreadAndWait(updater);\n    }\n    \n    \n    private LoadSnapshotAction() {\n        putValue(NAME, NbBundle.getMessage(LoadSnapshotAction.class, \"LBL_Load1\")); // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(LoadSnapshotAction.class, \"LBL_Load_Snapshot\"));    // NOI18N\n        putValue(SMALL_ICON, new ImageIcon(ICON));\n        putValue(\"iconBase\", ICON_PATH);    // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/MultiDataSourceAction.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui.actions;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport java.awt.event.ActionEvent;\nimport java.util.Set;\n\n/**\n * Abstract DataSourceAction which can be used as a basis for any action available (enabled) just for one or more selected DataSources in Applications window..\n *\n * @author Jiri Sedlacek\n */\npublic abstract class MultiDataSourceAction<X extends DataSource> extends DataSourceAction<X> {\n        \n    /**\n     * Creates new instance of MultiDataSourceAction available for defined DataSource type.\n     * \n     * @param scope DataSource type for the action.\n     */\n    public MultiDataSourceAction(Class<X> scope) {\n       super(scope);\n    }\n        \n        \n    public final void actionPerformed(ActionEvent e) {\n        if (isEnabled()) {\n            actionPerformed(ActionUtils.getSelectedDataSources(getScope()), e);\n        } else {\n            notifyCannotPerform();\n        }\n    }\n        \n        \n    /**\n     * Performs the action for the DataSources.\n     * \n     * @param dataSources Set of DataSources for which to perform the action.\n     * @param actionEvent ActionEvent for the action.\n     */\n    protected abstract void actionPerformed(Set<X> dataSources, ActionEvent actionEvent);\n        \n    /**\n     * Returns true if the action is available (enabled) for the DataSources, false otherwise.\n     * \n     * @param dataSources Set of DataSources for the action.\n     * @return true if the action is available (enabled) for the DataSources, false otherwise.\n     */\n    protected abstract boolean isEnabled(Set<X> dataSources);\n        \n    protected void updateState(Set<X> selectedDataSources) {\n        final boolean isEnabled = selectedDataSources.isEmpty() ? false : isEnabled(selectedDataSources);\n\n        UISupport.runInEventDispatchThreadAndWait(new Runnable() {\n            public void run() { setEnabled(isEnabled); }\n        });\n    }\n        \n }\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/OpenDataSourceAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.core.ui.actions;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport java.awt.event.ActionEvent;\nimport java.util.List;\nimport java.util.Set;\nimport org.openide.util.NbBundle;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass OpenDataSourceAction extends MultiDataSourceAction<DataSource> {\n    \n    private static OpenDataSourceAction instance;\n    \n    public static synchronized OpenDataSourceAction instance() {\n        if (instance == null) \n            instance = new OpenDataSourceAction();\n        return instance;\n    }\n    \n    \n    protected void actionPerformed(Set<DataSource> dataSources, ActionEvent actionEvent) {\n        List<DataSource> sortedDataSources = Utils.getSortedDataSources(dataSources);\n        for (DataSource dataSource : sortedDataSources)\n            DataSourceWindowManager.sharedInstance().openDataSource(dataSource);\n    }\n\n    protected boolean isEnabled(Set<DataSource> dataSources) {\n        for (DataSource dataSource : dataSources)\n            if (!DataSourceWindowManager.sharedInstance().canOpenDataSource(dataSource)) return false;\n        return true;\n    }\n    \n    \n    private OpenDataSourceAction() {\n        super(DataSource.class);\n        putValue(NAME, NbBundle.getMessage(OpenDataSourceAction.class, \"LBL_Open\"));    // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(OpenDataSourceAction.class, \"DESCR_Open\"));   // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/RemoveDataSourceAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.core.ui.actions;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport java.awt.event.ActionEvent;\nimport java.util.Set;\nimport org.openide.util.NbBundle;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass RemoveDataSourceAction extends MultiDataSourceAction<DataSource> {\n    \n    private static RemoveDataSourceAction instance;\n    \n    public static synchronized RemoveDataSourceAction instance() {\n        if (instance == null) \n            instance = new RemoveDataSourceAction();\n        return instance;\n    }\n    \n    \n    protected void actionPerformed(Set<DataSource> dataSources, ActionEvent actionEvent) {\n        for (DataSource dataSource : dataSources)\n            if (checkRemove(dataSource))\n                dataSource.getOwner().getRepository().removeDataSource(dataSource);\n    }\n\n    protected boolean isEnabled(Set<DataSource> dataSources) {\n        for (DataSource dataSource : dataSources)\n            if (!dataSource.supportsUserRemove()) return false;\n        return Utils.areDataSourcesIndependent(dataSources);\n    }\n    \n    \n    private static boolean checkRemove(DataSource dataSource) {\n        // Check if the DataSource can be removed\n        if (!dataSource.checkRemove(dataSource)) return false;\n        \n        // Check if all repository DataSources can be removed\n        Set<? extends DataSource> repositoryDataSources = dataSource.getRepository().getDataSources();\n        for (DataSource repositoryDataSource : repositoryDataSources)\n            if (!repositoryDataSource.checkRemove(dataSource)) return false;\n        return true;\n    }\n    \n    \n    private RemoveDataSourceAction() {\n        super(DataSource.class);\n        putValue(NAME, NbBundle.getMessage(RemoveDataSourceAction.class, \"LBL_Remove\"));    // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(RemoveDataSourceAction.class, \"DESCR_Remove\"));   // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/RenameConfigurator.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui.actions;\n\nimport org.graalvm.visualvm.core.datasource.descriptor.*;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTextField;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * \n */\nclass RenameConfigurator extends JPanel {\n\n  public static RenameConfigurator defineName(DataSource dataSource) {\n    RenameConfigurator hc = getDefault();\n    hc.setupDefineName(dataSource);\n    \n    final DialogDescriptor dd = new DialogDescriptor(hc, NbBundle.getMessage(RenameConfigurator.class, \"LBL_Rename\"), true, new Object[] {  // NOI18N\n      hc.okButton, DialogDescriptor.CANCEL_OPTION }, hc.okButton, 0, null, null);\n    final Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n    d.pack();\n    d.setVisible(true);\n    \n    if (dd.getValue() == hc.okButton) return hc;\n    else return null;\n  }\n  \n  public String getDisplayName() {\n      return nameField.getText().trim();\n  }\n  \n  private static RenameConfigurator defaultInstance;\n  \n  private RenameConfigurator() {\n    initComponents();\n    update();\n  }\n  \n  private static RenameConfigurator getDefault() {\n    if (defaultInstance == null) defaultInstance = new RenameConfigurator();\n    return defaultInstance;\n  }\n  \n  private void setupDefineName(DataSource dataSource) {\n    nameField.setText(DataSourceDescriptorFactory.getDescriptor(dataSource).getName());\n    nameField.selectAll();\n  }\n  \n  private void update() {\n    SwingUtilities.invokeLater(new Runnable() {\n      public void run() {\n        okButton.setEnabled(!getDisplayName().isEmpty());\n      }\n    });\n  }\n\n  private void initComponents() {\n    setLayout(new GridBagLayout());\n    GridBagConstraints constraints;\n    \n    // nameLabel\n    nameLabel = new JLabel(NbBundle.getMessage(RenameConfigurator.class, \"LBL_New_Name\"));  // NOI18N\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 0;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.EAST;\n    constraints.insets = new Insets(15, 10, 0, 0);\n    add(nameLabel, constraints);\n    \n    // coreDumpFileField\n    nameField = new JTextField();\n    nameField.setPreferredSize(new Dimension(220, nameField.getPreferredSize().height));\n    nameField.getDocument().addDocumentListener(new DocumentListener() {\n      public void insertUpdate(DocumentEvent e)  { update(); }\n      public void removeUpdate(DocumentEvent e)  { update(); }\n      public void changedUpdate(DocumentEvent e) { update(); }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 1;\n    constraints.gridy = 0;\n    constraints.weightx = 1;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.HORIZONTAL;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(15, 5, 0, 10);\n    add(nameField, constraints);\n    \n    // spacer\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 1;\n    constraints.weighty = 1;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.BOTH;\n    constraints.anchor = GridBagConstraints.NORTHWEST;\n    constraints.insets = new Insets(0, 0, 15, 0);\n    add(Spacer.create(), constraints);\n    \n    // okButton\n    okButton = new JButton(NbBundle.getMessage(RenameConfigurator.class, \"LBL_OK\"));    // NOI18N\n  }\n  \n  private JLabel nameLabel;\n  private JTextField nameField;\n  \n  private JButton okButton;\n  \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/RenameDataSourceAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.core.ui.actions;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport java.awt.event.ActionEvent;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass RenameDataSourceAction extends SingleDataSourceAction<DataSource> {\n    \n    private static RenameDataSourceAction instance;\n    \n    public static synchronized RenameDataSourceAction instance() {\n        if (instance == null) \n            instance = new RenameDataSourceAction();\n        return instance;\n    }\n\n    \n    protected void actionPerformed(DataSource dataSource, ActionEvent actionEvent) {\n        RenameConfigurator configurator = RenameConfigurator.defineName(dataSource);\n        if (configurator != null)\n            DataSourceDescriptorFactory.getDescriptor(dataSource).setName(configurator.getDisplayName());\n    }\n\n    protected boolean isEnabled(DataSource dataSource) {\n        return DataSourceDescriptorFactory.getDescriptor(dataSource).supportsRename();\n    }\n    \n    \n    private RenameDataSourceAction() {\n        super(DataSource.class);\n        putValue(NAME, NbBundle.getMessage(RenameDataSourceAction.class, \"LBL_Rename1\"));   // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(RenameDataSourceAction.class, \"LBL_Rename\"));   // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/SaveSnapshotAsAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.core.ui.actions;\n\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport java.awt.Image;\nimport java.awt.event.ActionEvent;\nimport javax.swing.ImageIcon;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass SaveSnapshotAsAction extends SingleDataSourceAction<Snapshot> {\n    \n    private static final String ICON_PATH = \"org/graalvm/visualvm/core/ui/resources/saveSnapshot.png\";    // NOI18N\n    private static final Image ICON = ImageUtilities.loadImage(ICON_PATH);\n    \n    private static SaveSnapshotAsAction instance;\n    \n    public static synchronized SaveSnapshotAsAction instance() {\n        if (instance == null) \n            instance = new SaveSnapshotAsAction();\n        return instance;\n    }\n    \n    \n    protected void actionPerformed(Snapshot snapshot, ActionEvent actionEvent) {\n        snapshot.saveAs();\n    }\n\n    protected boolean isEnabled(Snapshot snapshot) {\n        return snapshot.supportsSaveAs();\n    }\n    \n    \n    private SaveSnapshotAsAction() {\n        super(Snapshot.class);\n        putValue(NAME, NbBundle.getMessage(SaveSnapshotAsAction.class, \"LBL_Save_As\")); // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(SaveSnapshotAsAction.class, \"LBL_Save_Snapshot_As\"));   // NOI18N\n        putValue(SMALL_ICON, new ImageIcon(ICON));\n        putValue(\"iconBase\", ICON_PATH);    // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/SingleDataSourceAction.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui.actions;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport java.awt.event.ActionEvent;\nimport java.util.Set;\n\n/**\n * Abstract DataSourceAction which can be used as a basis for any action available (enabled) just for single selected DataSource in Applications window.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class SingleDataSourceAction<X extends DataSource> extends DataSourceAction<X> {\n        \n    /**\n     * Creates new instance of SingleDataSourceAction available for defined DataSource type.\n     * \n     * @param scope DataSource type for the action.\n     */\n    public SingleDataSourceAction(Class<X> scope) {\n        super(scope);\n    }\n\n\n    public final void actionPerformed(ActionEvent e) {\n        if (isEnabled()) {\n            actionPerformed(ActionUtils.getSelectedDataSource(getScope()), e);\n        } else {\n            notifyCannotPerform();\n        }\n    }\n\n\n    /**\n     * Performs the action for the DataSource.\n     * \n     * @param dataSource DataSource for which to perform the action.\n     * @param actionEvent ActionEvent for the action.\n     */\n    protected abstract void actionPerformed(X dataSource, ActionEvent actionEvent);\n\n    /**\n     * Returns true if the action is available (enabled) for the DataSource, false otherwise.\n     * \n     * @param dataSource DataSource for the action.\n     * @return true if the action is available (enabled) for the DataSource, false otherwise.\n     */\n    protected abstract boolean isEnabled(X dataSource);\n\n    protected void updateState(Set<X> selectedDataSources) {\n        X selectedDataSource = selectedDataSources.size() == 1 ? selectedDataSources.iterator().next() : null;\n        final boolean isEnabled = selectedDataSource != null ? isEnabled(selectedDataSource) : false;\n\n        UISupport.runInEventDispatchThreadAndWait(new Runnable() {\n            public void run() { setEnabled(isEnabled); }\n        });\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/VisualVMDropHandler.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core.ui.actions;\n\nimport java.awt.Component;\nimport java.awt.datatransfer.DataFlavor;\nimport java.awt.datatransfer.Transferable;\nimport java.awt.datatransfer.UnsupportedFlavorException;\nimport java.awt.dnd.DropTargetDragEvent;\nimport java.awt.dnd.DropTargetDropEvent;\nimport java.awt.dnd.InvalidDnDOperationException;\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.URI;\nimport java.text.MessageFormat;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.StringTokenizer;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.core.snapshot.RegisteredSnapshotCategories;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.openide.DialogDisplayer;\nimport org.openide.ErrorManager;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.windows.ExternalDropHandler;\nimport org.openide.windows.TopComponent;\n\n/**\n *\n * @author S. Aubrecht\n * @author Tomas Hurka\n */\n@ServiceProvider(service = ExternalDropHandler.class, position = 1000)\npublic class VisualVMDropHandler extends ExternalDropHandler {\n\n    private static final Logger LOG = Logger.getLogger(VisualVMDropHandler.class.getName());\n\n    @Override\n    public boolean canDrop(DropTargetDragEvent e) {\n        return canDrop(e.getCurrentDataFlavors());\n    }\n\n    @Override\n    public boolean canDrop(DropTargetDropEvent e) {\n        return canDrop(e.getCurrentDataFlavors());\n    }\n\n    private boolean canDrop(DataFlavor[] flavors) {\n        for (DataFlavor df : flavors) {\n            if (DataFlavor.javaFileListFlavor.equals(df)\n                    || getUriListDataFlavor().equals(df)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    @Override\n    public boolean handleDrop(DropTargetDropEvent e) {\n        Transferable t = e.getTransferable();\n        if (t == null) {\n            return false;\n        }\n        List<File> fileList = getFileList(t);\n        if ((fileList == null) || fileList.isEmpty()) {\n            return false;\n        }\n\n        //#158473: Activate target TC to inform winsys in which mode new editor\n        //component should be opened. It assumes that openFile opens new editor component\n        //in some editor mode. If there would be problem with activating another TC first\n        //then another way how to infrom winsys must be used.\n        Component c = e.getDropTargetContext().getComponent();\n        while (c != null) {\n            if (c instanceof TopComponent) {\n                ((TopComponent) c).requestActive();\n                break;\n            }\n            c = c.getParent();\n        }\n\n        Object errMsg = null;\n        if (fileList.size() == 1) {\n            errMsg = openFile(fileList.get(0));\n        } else {\n            boolean hasSomeSuccess = false;\n            List<String> fileErrs = null;\n            for (File file : fileList) {\n                String fileErr = openFile(file);\n                if (fileErr == null) {\n                    hasSomeSuccess = true;\n                } else {\n                    if (fileErrs == null) {\n                        fileErrs = new ArrayList<>();\n                    }\n                    fileErrs.add(fileErr);\n                }\n            }\n            if (fileErrs != null) {         //some file could not be opened\n                String mainMsgKey;\n                if (hasSomeSuccess) {\n                    mainMsgKey = \"MSG_could_not_open_some_files\";       //NOI18N\n                } else {\n                    mainMsgKey = \"MSG_could_not_open_any_file\";         //NOI18N\n                }\n                String mainMsg = NbBundle.getMessage(VisualVMDropHandler.class, mainMsgKey);\n                JComponent msgPanel = new JPanel();\n                msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));\n                msgPanel.add(new JLabel(mainMsg));\n                msgPanel.add(Box.createVerticalStrut(12));\n                for (String fileErr : fileErrs) {\n                    msgPanel.add(new JLabel(fileErr));\n                }\n                errMsg = msgPanel;\n            }\n        }\n        if (errMsg != null) {\n            showWarningMessageFileNotOpened(errMsg);\n            return false;\n        }\n        return true;\n    }\n\n    private static void showWarningMessageFileNotOpened(Object errMsg) {\n        DialogDisplayer.getDefault().notify(\n                new NotifyDescriptor.Message(\n                        errMsg,\n                        NotifyDescriptor.WARNING_MESSAGE));\n    }\n\n    private List<File> getFileList(Transferable t) {\n        try {\n            if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {\n                //windows & mac\n                try {\n                    return (List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);\n                } catch (InvalidDnDOperationException ex) { // #212390\n                    LOG.log(Level.FINE, null, ex);\n                }\n            }\n            if (t.isDataFlavorSupported(getUriListDataFlavor())) {\n                //linux\n                String uriList = (String) t.getTransferData(getUriListDataFlavor());\n                return textURIListToFileList(uriList);\n            }\n        } catch (UnsupportedFlavorException ex) {\n            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);\n        } catch (IOException ex) {\n            // Ignore. Can be just \"Owner timed out\" from sun.awt.X11.XSelection.getData.\n            LOG.log(Level.FINE, null, ex);\n        }\n        return null;\n    }\n\n    /**\n     * Opens the given file.\n     *\n     * If the file doesn't open in a reasonable time (2 seconds), let's assume\n     * it will open successfully later (return null).\n     *\n     * @param file file to be opened\n     * @return {@code null} if the file was successfully opened; or a localized\n     * error message in case of failure\n     */\n    private String openFile(final File file) {\n        if (file.exists() && file.canRead() && file.isFile()) {\n            List<SnapshotCategory> categories = RegisteredSnapshotCategories.sharedInstance().getOpenSnapshotCategories();\n\n            for (SnapshotCategory category : categories) {\n                if (category.getFileFilter().accept(file)) {\n                    category.openSnapshot(file);\n                    LoadRecentSnapshot.instance().addFile(file);\n                    return null;\n                }\n            }\n            return MessageFormat.format(NbBundle.getMessage(VisualVMDropHandler.class, \"LoadRecentSnapshot_CannotLoadMsg\"), file.getName());\n        }\n        return MessageFormat.format(NbBundle.getMessage(VisualVMDropHandler.class, \"LoadRecentSnapshot_NotAvailableMsg\"), file.getName());\n    }\n\n    private static DataFlavor uriListDataFlavor;\n\n    private DataFlavor getUriListDataFlavor() {\n        if (null == uriListDataFlavor) {\n            try {\n                uriListDataFlavor = new DataFlavor(\"text/uri-list;class=java.lang.String\");\n            } catch (ClassNotFoundException cnfE) {\n                //cannot happen\n                throw new AssertionError(cnfE);\n            }\n        }\n        return uriListDataFlavor;\n    }\n\n    private List<File> textURIListToFileList(String data) {\n        List<File> list = new ArrayList<>();\n        StringTokenizer st = new StringTokenizer(data,\"\\r\\n\\u0000\");\n\n        while (st.hasMoreTokens()) {\n            String s = st.nextToken();\n\n            if (s.startsWith(\"#\")) {\n                // the line is a comment (as per the RFC 2483)\n                continue;\n            }\n            try {\n                File file = new File(new URI(s));\n                list.add(file);\n            } catch (java.net.URISyntaxException e) {\n                // malformed URI\n            } catch (IllegalArgumentException e) {\n                // the URI is not a valid 'file:' URI\n            }\n        }\n        return list;\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/actions/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * APIs for UI actions in VisualVM.\n */\npackage org.graalvm.visualvm.core.ui.actions;\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/components/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nToolTip_Hide=Hide\n\nToolTip_ShowSection=Show {0}\n\nToolTip_HideSection=Hide {0}\n\nMSG_application=application\n\nMSG_JVM=JVM\n\nMSG_host=host\n\nMSG_OS=OS\n\nMSG_Not_supported=Not supported for this {0}.\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/components/DataViewComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui.components;\n\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JSplitPane;\nimport javax.swing.plaf.basic.BasicSplitPaneDivider;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\n\n/**\n * UI component displaying single subtab for opened DataSource.\n *\n * @author Jiri Sedlacek\n */\npublic final class DataViewComponent extends JPanel {\n\n    /**\n     * Top left details area of the view.\n     */\n    public static final int TOP_LEFT = 1;\n    /**\n     * Top right details area of the view.\n     */\n    public static final int TOP_RIGHT = 2;\n    /**\n     * Bottom left details area of the view.\n     */\n    public static final int BOTTOM_LEFT = 3;\n    /**\n     * Bottom right details area of the view.\n     */\n    public static final int BOTTOM_RIGHT = 4;\n\n    private boolean isMasterViewResizable;\n\n    private JPanel masterPanel;\n    private JPanel detailsPanel;\n\n    private JExtendedSplitPane detailsTopHorizontalSplitter;\n    private JExtendedSplitPane detailsBottomHorizontalSplitter;\n    private JExtendedSplitPane detailsVerticalSplitter;\n\n    private DisplayArea masterArea;\n    private DisplayArea detailsTopLeftArea;\n    private DisplayArea detailsTopRightArea;\n    private DisplayArea detailsBottomLeftArea;\n    private DisplayArea detailsBottomRightArea;\n\n    private static final Color BACKGROUND_COLOR;\n    private static final Color HIGHLIGHT_BACKGROUND;\n\n\n    static {\n        BACKGROUND_COLOR = UISupport.getDefaultBackground();\n\n        int darkerR = BACKGROUND_COLOR.getRed() - 20;\n        if (darkerR < 0) darkerR += 40;\n        int darkerG = BACKGROUND_COLOR.getGreen() - 20;\n        if (darkerG < 0) darkerG += 40;\n        int darkerB = BACKGROUND_COLOR.getBlue() - 20;\n        if (darkerB < 0) darkerB += 40;\n\n        HIGHLIGHT_BACKGROUND = new Color(darkerR, darkerG, darkerB);\n    }\n    \n    \n    /**\n     * Creates new instance of DataViewComponent.\n     * \n     * @param masterView MasterView for the component.\n     * @param masterAreaConfiguration MasterAreaConfiguration for the component.\n     */\n    public DataViewComponent(MasterView masterView, MasterViewConfiguration masterAreaConfiguration) {\n        initComponents();\n        createMasterView(masterView);\n        configureMasterView(masterAreaConfiguration);\n    }\n    \n    \n    private void configureMasterView(MasterViewConfiguration masterViewConfiguration) {\n        setMasterViewResizable(masterViewConfiguration.isMasterViewResizable());\n    }\n    \n    /**\n     * Configures properties of the details view.\n     * \n     * @param detailsViewConfiguration configuration for the details view.\n     */\n    public void configureDetailsView(DetailsViewConfiguration detailsViewConfiguration) {\n        double topHorizontalDividerResizeWeight = detailsViewConfiguration.getTopHorizontalDividerResizeWeight();\n        if (topHorizontalDividerResizeWeight != -1) detailsTopHorizontalSplitter.setResizeWeight(topHorizontalDividerResizeWeight);\n        double topHorizontalDividerLocation = detailsViewConfiguration.getTopHorizontalDividerLocation();\n        if (topHorizontalDividerLocation != -1) detailsTopHorizontalSplitter.setDividerLocation(topHorizontalDividerLocation);\n        \n        double bottomHorizontalDividerResizeWeight = detailsViewConfiguration.getBottomHorizontalDividerResizeWeight();\n        if (bottomHorizontalDividerResizeWeight != -1) detailsBottomHorizontalSplitter.setResizeWeight(bottomHorizontalDividerResizeWeight);\n        double bottomHorizontalDividerLocation = detailsViewConfiguration.getBottomHorizontalDividerLocation();\n        if (bottomHorizontalDividerLocation != -1) detailsBottomHorizontalSplitter.setDividerLocation(bottomHorizontalDividerLocation);\n        \n        double verticalDividerResizeWeight = detailsViewConfiguration.getVerticalDividerResizeWeight();\n        if (verticalDividerResizeWeight != -1) detailsVerticalSplitter.setResizeWeight(verticalDividerResizeWeight);\n        double verticalDividerLocation = detailsViewConfiguration.getVerticalDividerLocation();\n        if (verticalDividerLocation != -1) detailsVerticalSplitter.setDividerLocation(verticalDividerLocation);\n    }\n    \n    /**\n     * Shows details area on provided location.\n     * \n     * @param location location to be shown.\n     */\n    public void showDetailsArea(int location) {\n        DisplayArea displayArea = getDisplayArea(location);\n        if (displayArea != null) displayArea.setVisible(true);\n    }\n    \n    /**\n     * Hides details area on provided location.\n     * \n     * @param location location to be hidden.\n     */\n    public void hideDetailsArea(int location) {\n        DisplayArea displayArea = getDisplayArea(location);\n        if (displayArea != null) displayArea.setVisible(false);\n    }\n    \n    /**\n     * Returns true if the details area on provided location is currently shown, false otherwise.\n     * @param location location to be checked.\n     * @return true if the details area on provided location is currently shown, false otherwise.\n     */\n    public boolean isDetailsAreaShown(int location) {\n        DisplayArea displayArea = getDisplayArea(location);\n        return displayArea != null ? displayArea.isVisible() : false;\n    }\n    \n    /**\n     * Configures properties of the details area.\n     * \n     * @param detailsAreaConfiguration configuration for the details area.\n     * @param location location of the details area to be configured.\n     */\n    public void configureDetailsArea(DetailsAreaConfiguration detailsAreaConfiguration, int location) {\n        DisplayArea displayArea = getDisplayArea(location);\n        if (displayArea != null) {\n            displayArea.setCaption(detailsAreaConfiguration.getName());\n            displayArea.setClosable(detailsAreaConfiguration.isClosable());\n        }\n    }\n    \n    private void createMasterView(MasterView masterView) {\n        masterPanel.setVisible(true);\n        JComponent[] options = new JComponent[] { detailsTopLeftArea.getPresenter(), detailsTopRightArea.getPresenter(), detailsBottomLeftArea.getPresenter(), detailsBottomRightArea.getPresenter() };\n        masterArea.addTab(new DisplayArea.Tab(masterView.getName(), masterView.getDescription(), 0, masterView.getView(), options));\n    }\n    \n    /**\n     * Adds new details view.\n     * \n     * @param detailsView DetailsView to be added.\n     * @param location location where the DetailsView will be added.\n     */\n    public void addDetailsView(DetailsView detailsView, int location) {\n        DisplayArea displayArea = getDisplayArea(location);\n        if (displayArea != null) {\n            if (\"\".equals(displayArea.getCaption())) displayArea.setCaption(detailsView.getTab().getName());\n            displayArea.addTab(detailsView.getTab());\n            revalidate();\n            repaint();\n        }\n    }\n    \n    /**\n     * Removes details view.\n     * \n     * @param detailsView DetailsView to be removed.\n     */\n    public void removeDetailsView(DetailsView detailsView) {\n        DisplayArea displayArea = getDisplayArea(detailsView.getTab());\n        if (displayArea != null) displayArea.removeTab(detailsView.getTab());\n    }\n    \n    /**\n     * Returns true if DataViewComponent contains the DetailsView, false otherwise.\n     * \n     * @param detailsView DetailsView to check.\n     * @return true if DataViewComponent contains the DetailsView, false otherwise.\n     */\n    public boolean containsDetailsView(DetailsView detailsView) {\n        return getDisplayArea(detailsView.getTab()) != null;\n    }\n    \n    /**\n     * Selects the DetailsView.\n     * \n     * @param detailsView DetailsView to be selected.\n     */\n    public void selectDetailsView(DetailsView detailsView) {\n        DisplayArea displayArea = getDisplayArea(detailsView.getTab());\n        if (displayArea != null) displayArea.setSelectedTab(detailsView.getTab());\n    }\n    \n    \n    private void setMasterViewResizable(boolean isMasterViewResizable) {            \n        this.isMasterViewResizable = isMasterViewResizable;\n        masterArea.setIgnoresContentsHeight(isMasterViewResizable);\n        JComponent contents = null;\n\n        if (isMasterViewResizable) {\n            final CustomizedSplitPaneUI mainVerticalSplitterUI = new CustomizedSplitPaneUI();\n            JExtendedSplitPane mainVerticalSplitter = new JExtendedSplitPane(JSplitPane.VERTICAL_SPLIT, masterPanel, detailsPanel){\n                public void updateUI() {\n                    if (getUI() != mainVerticalSplitterUI)\n                        setUI(mainVerticalSplitterUI);\n\n                    setBorder(null);\n                    setOpaque(false);\n                    setDividerSize(6);\n                    setContinuousLayout(true);\n\n                    final BasicSplitPaneDivider divider = ((BasicSplitPaneUI) getUI()).getDivider();\n                    divider.setBackground(BACKGROUND_COLOR);\n                    divider.setBorder(null);\n\n                    divider.addMouseListener(new MouseAdapter() {\n                        public void mouseEntered(MouseEvent e) {\n                            divider.setBackground(HIGHLIGHT_BACKGROUND);\n                            divider.repaint();\n                        }\n                        public void mouseExited(MouseEvent e) {\n                            divider.setBackground(BACKGROUND_COLOR);\n                            divider.repaint();\n                        }\n                    });\n                }\n            };\n            mainVerticalSplitter.setDividerLocation(0.5d);\n\n            contents = mainVerticalSplitter;\n        } else {\n            JPanel containerPanel = new JPanel(new BorderLayout());\n            containerPanel.setOpaque(false);\n            containerPanel.add(masterPanel, BorderLayout.NORTH);\n            containerPanel.add(detailsPanel, BorderLayout.CENTER);\n\n            contents = containerPanel;\n        }\n\n        synchronized (getTreeLock()) {\n            removeAll();\n            add(contents, BorderLayout.CENTER);\n        }\n        \n        revalidate();\n        repaint();\n    }\n\n    private boolean isMasterAreaResizable() {\n        return isMasterViewResizable;\n    }\n    \n    \n    private DisplayArea getDisplayArea(int location) {\n        switch (location) {\n            case TOP_LEFT:      return detailsTopLeftArea;\n            case TOP_RIGHT:     return detailsTopRightArea;\n            case BOTTOM_LEFT:   return detailsBottomLeftArea;\n            case BOTTOM_RIGHT:  return detailsBottomRightArea;\n            default:            return null;\n        }\n    }\n    \n    private DisplayArea getDisplayArea(DisplayArea.Tab tab) {\n        if (detailsTopLeftArea.containsTab(tab)) return detailsTopLeftArea;\n        if (detailsTopRightArea.containsTab(tab)) return detailsTopRightArea;\n        if (detailsBottomLeftArea.containsTab(tab)) return detailsBottomLeftArea;\n        if (detailsBottomRightArea.containsTab(tab)) return detailsBottomRightArea;\n        \n        return null;\n    }\n    \n\n    private void initComponents() {\n\n        // Top details area\n\n        detailsTopLeftArea = new DisplayArea();\n        detailsTopRightArea = new DisplayArea();\n\n        final JPanel detailsTopPanel = new JPanel(new BorderLayout());\n        detailsTopPanel.setOpaque(false);\n        \n        final CustomizedSplitPaneUI detailsTopHorizontalSplitterUI = new CustomizedSplitPaneUI();\n        detailsTopHorizontalSplitter = new JExtendedSplitPane(JSplitPane.HORIZONTAL_SPLIT, detailsTopLeftArea, detailsTopRightArea) {\n            public void setVisible(boolean visible) {\n                super.setVisible(visible);\n                detailsTopPanel.setVisible(visible);\n                revalidate();\n                repaint();\n            }\n            public void updateUI() {\n                if (getUI() != detailsTopHorizontalSplitterUI)\n                    setUI(detailsTopHorizontalSplitterUI);\n                \n                setBorder(null);\n                setOpaque(false);\n                setDividerSize(6);\n                setContinuousLayout(true);\n\n                final BasicSplitPaneDivider divider = ((BasicSplitPaneUI) getUI()).getDivider();\n                divider.setBackground(BACKGROUND_COLOR);\n                divider.setBorder(null);\n                \n                divider.addMouseListener(new MouseAdapter() {\n                    public void mouseEntered(MouseEvent e) {\n                        divider.setBackground(HIGHLIGHT_BACKGROUND);\n                        divider.repaint();\n                    }\n                    public void mouseExited(MouseEvent e) {\n                        divider.setBackground(BACKGROUND_COLOR);\n                        divider.repaint();\n                    }\n                });\n            }\n        };\n        detailsTopHorizontalSplitter.setResizeWeight(0.5d);\n        detailsTopHorizontalSplitter.setDividerLocation(0.5d);\n        detailsTopPanel.add(detailsTopHorizontalSplitter, BorderLayout.CENTER);\n        \n\n        // Bottom details area\n\n        detailsBottomLeftArea = new DisplayArea();\n        detailsBottomRightArea = new DisplayArea();\n\n        final JPanel detailsBottomPanel = new JPanel(new BorderLayout());            \n        detailsBottomPanel.setOpaque(false);\n        \n        final CustomizedSplitPaneUI detailsBottomHorizontalSplitterUI = new CustomizedSplitPaneUI();\n        detailsBottomHorizontalSplitter = new JExtendedSplitPane(JSplitPane.HORIZONTAL_SPLIT, detailsBottomLeftArea, detailsBottomRightArea) {\n            public void setVisible(boolean visible) {\n                super.setVisible(visible);\n                detailsBottomPanel.setVisible(visible);\n                revalidate();\n                repaint();\n            }\n            public void updateUI() {\n                if (getUI() != detailsBottomHorizontalSplitterUI)\n                    setUI(detailsBottomHorizontalSplitterUI);\n                \n                setBorder(null);\n                setOpaque(false);\n                setDividerSize(6);\n                setContinuousLayout(true);\n\n                final BasicSplitPaneDivider divider = ((BasicSplitPaneUI) getUI()).getDivider();\n                divider.setBackground(BACKGROUND_COLOR);\n                divider.setBorder(null);\n                \n                divider.addMouseListener(new MouseAdapter() {\n                    public void mouseEntered(MouseEvent e) {\n                        divider.setBackground(HIGHLIGHT_BACKGROUND);\n                        divider.repaint();\n                    }\n                    public void mouseExited(MouseEvent e) {\n                        divider.setBackground(BACKGROUND_COLOR);\n                        divider.repaint();\n                    }\n                });\n            }\n        };\n        detailsBottomHorizontalSplitter.setResizeWeight(0.5d);\n        detailsBottomHorizontalSplitter.setDividerLocation(0.5d);\n        detailsBottomPanel.add(detailsBottomHorizontalSplitter, BorderLayout.CENTER);\n        \n\n        // Details area\n\n        detailsPanel = new JPanel(new BorderLayout());\n        detailsPanel.setOpaque(false);\n        detailsPanel.setVisible(false);\n\n        final CustomizedSplitPaneUI detailsVerticalSplitterUI = new CustomizedSplitPaneUI();\n        detailsVerticalSplitter = new JExtendedSplitPane(JSplitPane.VERTICAL_SPLIT, detailsTopPanel, detailsBottomPanel) {\n            public void setVisible(boolean visible) {\n                super.setVisible(visible);\n                detailsPanel.setVisible(visible);\n                revalidate();\n                repaint();\n            }\n            public void updateUI() {\n                if (getUI() != detailsVerticalSplitterUI)\n                    setUI(detailsVerticalSplitterUI);\n                \n                setBorder(null);\n                setOpaque(false);\n                setDividerSize(6);\n                setContinuousLayout(true);\n\n                final BasicSplitPaneDivider divider = ((BasicSplitPaneUI) getUI()).getDivider();\n                divider.setBackground(BACKGROUND_COLOR);\n                divider.setBorder(null);\n                \n                divider.addMouseListener(new MouseAdapter() {\n                    public void mouseEntered(MouseEvent e) {\n                        divider.setBackground(HIGHLIGHT_BACKGROUND);\n                        divider.repaint();\n                    }\n                    public void mouseExited(MouseEvent e) {\n                        divider.setBackground(BACKGROUND_COLOR);\n                        divider.repaint();\n                    }\n                });\n            }\n        };\n        detailsVerticalSplitter.setResizeWeight(0.5d);\n        detailsVerticalSplitter.setDividerLocation(0.5d);\n        detailsPanel.add(detailsVerticalSplitter, BorderLayout.CENTER);\n\n\n        // Master area\n\n        masterArea = new DisplayArea();\n        masterArea.setClosable(false);\n\n        masterPanel = new JPanel(new BorderLayout());\n        masterPanel.setOpaque(false);\n        masterPanel.setVisible(false);\n        masterPanel.add(masterArea, BorderLayout.CENTER);\n        \n        \n        // DataView\n        \n        setOpaque(true);\n        setBackground(BACKGROUND_COLOR);\n        setLayout(new BorderLayout());\n    }\n    \n    private static class CustomizedSplitPaneUI extends BasicSplitPaneUI {\n        public BasicSplitPaneDivider createDefaultDivider() {\n            return new BasicSplitPaneDivider(this) {\n                public void paint(Graphics g) {\n                    Dimension size = getSize();\n                    g.setColor(getBackground());\n                    g.fillRect(0, 0, size.width, size.height);\n                }\n            };\n        }\n    }\n    \n    /**\n     * Master view of DataViewComponent. This is the upper part of the component showing the master contents and/or\n     * controls for details views. Master view is always shown for each DataViewComponent.\n     */\n    public static class MasterView {\n        \n        private String name;\n        private String description;\n        private JComponent view;\n        \n        /**\n         * Creates new instance of MasterView.\n         * \n         * @param name name of the view.\n         * @param description description of the view.\n         * @param view UI component to be shown.\n         */\n        public MasterView(String name, String description, JComponent view) {\n            this.name = name;\n            this.description = description;\n            this.view = view;\n        }\n        \n        private String getName() { return name; }\n        private String getDescription() { return description; }\n        private JComponent getView() { return view; }\n        \n    }\n    \n    /**\n     * Details view of DataViewComponent. This is an optional view of the DataViewComponent which can be hidden or\n     * not used at all.\n     */\n    public static class DetailsView {\n        \n        private DisplayArea.Tab tab;\n        \n        /**\n         * Creates new instance of DetailsView.\n         * \n         * @param name name of the view.\n         * @param description description of the view.\n         * @param preferredPosition preferred position of the view among other views.\n         * @param view UI component to be shown.\n         * @param options components to be shown in view's caption.\n         */\n        public DetailsView(String name, String description, int preferredPosition, JComponent view, JComponent[] options) {\n            tab = new DisplayArea.Tab(name, description, preferredPosition, view, options);\n        }\n        \n        private DisplayArea.Tab getTab() { return tab; }\n        \n    }\n    \n    /**\n     * Configuration of the MasterView.\n     */\n    public static class MasterViewConfiguration {\n        \n        private boolean isMasterViewResizable;\n        \n        /**\n         * Creates new instance of MasterViewConfiguration.\n         * \n         * @param isMasterAreaResizable controls if master area can be dynamically resized in the UI (effective only if at least one details view is displayed).\n         */\n        public MasterViewConfiguration(boolean isMasterAreaResizable) {\n            this.isMasterViewResizable = isMasterAreaResizable;\n        }\n        \n        private boolean isMasterViewResizable() { return isMasterViewResizable; }\n        \n    }\n    \n    /**\n     * Configuration of the DetailsView.\n     */\n    public static class DetailsViewConfiguration {\n        \n        private double topHorizontalDividerLocation;\n        private double topHorizontalDividerResizeWeight;\n        private double bottomHorizontalDividerLocation;\n        private double bottomHorizontalDividerResizeWeight;\n        private double verticalDividerLocation;\n        private double verticalDividerResizeWeight;\n        \n        /**\n         * Creates new instance of DetailsViewConfiguration.\n         * \n         * @param topHorizontalDividerLocation preferred relative location of top horizontal divider.\n         * @param topHorizontalDividerResizeWeight preferred resize weight of top horizontal divider.\n         * @param bottomHorizontalDividerLocation preferred relative location of bottom horizontal divider.\n         * @param bottomHorizontalDividerResizeWeight preferred resize weight of bottom horizontal divider.\n         * @param verticalDividerLocation preferred location of vertical divider.\n         * @param verticalDividerResizeWeight preferred resize weight of vertical divider.\n         */\n        public DetailsViewConfiguration(double topHorizontalDividerLocation, double topHorizontalDividerResizeWeight, double bottomHorizontalDividerLocation,\n                                        double bottomHorizontalDividerResizeWeight, double verticalDividerLocation, double verticalDividerResizeWeight) {\n            this.topHorizontalDividerLocation = topHorizontalDividerLocation;\n            this.topHorizontalDividerResizeWeight = topHorizontalDividerResizeWeight;\n            this.bottomHorizontalDividerLocation = bottomHorizontalDividerLocation;\n            this.bottomHorizontalDividerResizeWeight = bottomHorizontalDividerResizeWeight;\n            this.verticalDividerLocation = verticalDividerLocation;\n            this.verticalDividerResizeWeight = verticalDividerResizeWeight;\n        }\n        \n        /**\n         * Returns preferred relative location of top horizontal divider.\n         * @return preferred relative location of top horizontal divider.\n         */\n        public double getTopHorizontalDividerLocation() { return topHorizontalDividerLocation; }\n        /**\n         * Returns preferred resize weight of top horizontal divider.\n         * @return preferred resize weight of top horizontal divider.\n         */\n        public double getTopHorizontalDividerResizeWeight() { return topHorizontalDividerResizeWeight; }\n        /**\n         * Returns preferred relative location of bottom horizontal divider.\n         * @return preferred relative location of bottom horizontal divider.\n         */\n        public double getBottomHorizontalDividerLocation() { return bottomHorizontalDividerLocation; }\n        /**\n         * Returns preferred resize weight of bottom horizontal divider.\n         * @return preferred resize weight of bottom horizontal divider.\n         */\n        public double getBottomHorizontalDividerResizeWeight() { return bottomHorizontalDividerResizeWeight; }\n        /**\n         * Returns preferred relative location of vertical divider.\n         * @return preferred relative location of vertical divider.\n         */\n        public double getVerticalDividerLocation() { return verticalDividerLocation; }\n        /**\n         * Returns preferred resize weight of vertical divider.\n         * @return preferred resize weight of vertical divider.\n         */\n        public double getVerticalDividerResizeWeight() { return verticalDividerResizeWeight; }\n        \n    }\n    \n    /**\n     * Configuration for details area.\n     */\n    public static class DetailsAreaConfiguration {\n        \n        private String name;\n        private boolean closable;\n        \n        /**\n         * Creates new instance of DetailsAreaConfiguration.\n         * \n         * @param name name of the details area.\n         * @param closable controls if the details area is closable or always shown.\n         */\n        public DetailsAreaConfiguration(String name, boolean closable) {\n            this.name = name;\n            this.closable = closable;\n        }\n        \n        private String getName() { return name; }\n        private boolean isClosable() { return closable; }\n        \n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/components/DisplayArea.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core.ui.components;\n\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport java.awt.BorderLayout;\nimport java.awt.CardLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.swing.BorderFactory;\nimport javax.swing.BoxLayout;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.openide.awt.CloseButtonFactory;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass DisplayArea extends JComponent {\n\n    private boolean ignoresContentsHeight = true;\n\n    DisplayArea() {\n        initComponents();\n        setClosable(true);\n        setVisible(false); // No tabs added yet\n    }\n\n    void setCaption(String caption) {\n        this.caption = caption;\n        if (presenter != null) presenter.setCaption(caption);\n    }\n\n    String getCaption() {\n        return caption;\n    }\n\n    void setClosable(boolean closable) {\n        optionsContainer.setClosable(closable);\n        updatePresenter();\n    }\n\n    boolean isClosable() {\n        return optionsContainer.isClosable();\n    }\n\n    void setIgnoresContentsHeight(boolean ignoresContentsHeight) {\n        this.ignoresContentsHeight = ignoresContentsHeight;\n    }\n\n    boolean ignoresContentsHeight() {\n        return ignoresContentsHeight;\n    }\n\n    Presenter getPresenter() {\n        if (presenter == null) {\n            presenter = createPresenter();\n            updatePresenter();\n        }\n        return presenter;\n    }\n\n    void addTab(Tab tab) {\n        final DisplayAreaSupport.TabButton tabButton = tabsContainer.addTab(tab);\n        if (tabButton != null) {\n            optionsContainer.addOptions(tab);\n            updateTabbed();\n            if (tabsContainer.indexOfTab(tab) == 0) setSelectedTab(tab);\n            final Tab tabF = tab;\n            tabButton.addMouseListener(new MouseAdapter() {\n                public void mousePressed(MouseEvent e) {\n                    if (tabButton.isEnabled() && SwingUtilities.isLeftMouseButton(e))\n                        setSelectedTab(tabF);\n                }\n            });\n            tabButton.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) { setSelectedTab(tabF); }\n            });\n        }\n\n        if (tabsContainer.getTabsCount() > 0) setVisible(true);\n        updatePresenter();\n    }\n\n    void removeTab(Tab tab) {\n        Tab toSelect = null;\n        boolean wasSelected = getSelectedTab() == tab;\n        if (wasSelected) {\n            toSelect = tabsContainer.getPreviousTab(tab);\n            if (toSelect == null) toSelect = tabsContainer.getNextTab(tab);\n        }\n\n        if (tabsContainer.removeTab(tab)) {\n            optionsContainer.removeOptions(tab);\n\n            if (wasSelected) {\n                if (toSelect != null) setSelectedTab(toSelect);\n                else viewContainer.setSelectedView(null);\n            }\n\n            updateTabbed();\n        }\n\n        if (tabsContainer.getTabsCount() == 0) setVisible(false);\n        updatePresenter();\n    }\n\n    boolean containsTab(Tab tab) {\n        return tabsContainer.containsTab(tab);\n    }\n\n    void setSelectedTab(Tab tab) {\n        if (tabsContainer.getSelectedTab() == tab) return;\n\n        tabsContainer.setSelectedTab(tab);\n        optionsContainer.setSelectedOptions(tab);\n        viewContainer.setSelectedView(tab.getView());\n    }\n\n    Tab getSelectedTab() {\n        return tabsContainer.getSelectedTab();\n    }\n\n\n    public Dimension getPreferredSize() {\n        if (ignoresContentsHeight()) return new Dimension(0, tabsContainer.getPreferredSize().height);\n        else return super.getPreferredSize();\n    }\n\n    public Dimension getMinimumSize() {\n        if (ignoresContentsHeight()) return getPreferredSize();\n        else return super.getMinimumSize();\n    }\n\n\n    private void updatePresenter() {\n        if (presenter == null) return;\n        presenter.setVisible(tabsContainer.getTabsCount() > 0 && isClosable());\n    }\n\n    private void updateTabbed() {\n        boolean tabbed = tabsContainer.getTabsCount() > 1;\n        middleSpacer.updateTabbed(tabbed);\n        optionsContainer.updateTabbed(tabbed);\n    }\n\n    private Presenter createPresenter() {\n        final Presenter presenter = new Presenter();\n        presenter.setCaption(caption);\n        presenter.setOpaque(false);\n        final boolean[] internalChange = new boolean[1];\n        internalChange[0] = false;\n\n        presenter.addActionListener(new ActionListener() {\n           public void actionPerformed(ActionEvent e) {\n               internalChange[0] = true;\n               setVisible(presenter.isSelected());\n               internalChange[0] = false;\n           }\n        });\n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    boolean isShowing = isShowing();\n                    presenter.setToolTipText(isShowing ? NbBundle.getMessage(\n                            DisplayArea.class, \"ToolTip_HideSection\", caption) : // NOI18N\n                            NbBundle.getMessage(DisplayArea.class,\n                            \"ToolTip_ShowSection\", caption)); // NOI18N\n                    if (!internalChange[0]) presenter.setSelected(isShowing);\n                }\n            }\n        });\n\n        return presenter;\n    }\n\n    private void initComponents() {\n        viewContainer = new ViewArea();\n\n        tabsContainer = new TabsContainer();\n        middleSpacer = new MiddleSpacer();\n        optionsContainer = new OptionsContainer();\n\n        JPanel captionArea = new JPanel();\n        captionArea.setLayout(new BorderLayout());\n        captionArea.setOpaque(false);\n\n        captionArea.add(tabsContainer, BorderLayout.WEST);\n        captionArea.add(middleSpacer, BorderLayout.CENTER);\n        captionArea.add(optionsContainer, BorderLayout.EAST);\n\n        setLayout(new BorderLayout());\n        add(captionArea, BorderLayout.NORTH);\n        add(viewContainer, BorderLayout.CENTER);\n    }\n\n    private String caption = \"\"; // NOI18N\n    private Presenter presenter;\n\n    private ViewArea viewContainer;\n\n    private TabsContainer tabsContainer;\n    private MiddleSpacer middleSpacer;\n    private OptionsContainer optionsContainer;\n\n\n    static class Presenter extends JCheckBox {\n\n        void setCaption(String caption) { setText(caption); }\n        String getCaption() { return getText(); }\n\n        void setDescription(String description) { setToolTipText(description); }\n        String getDescription() { return getToolTipText(); }\n\n    }\n\n\n    static class Tab implements Positionable {\n\n        private String name;\n        private String description;\n        private int preferredPosition;\n        private JComponent view;\n        private JComponent[] options;\n\n        Tab(String name, JComponent view) { this(name, null, POSITION_AT_THE_END, view, null); }\n        Tab(String name, String description, int preferredPosition, JComponent view, JComponent[] options) {\n            setName(name);\n            setDescription(description);\n            setPreferredPosition(preferredPosition);\n            setView(view);\n            setOptions(options);\n        }\n\n        void setName(String name) { this.name = name; }\n        String getName() { return name; }\n\n        void setDescription(String description) { this.description = description; }\n        String getDescription() { return description; }\n\n        void setPreferredPosition(int preferredPosition) { this.preferredPosition = preferredPosition; }\n        public int getPreferredPosition() { return preferredPosition; }\n\n        void setView(JComponent view) { this.view = view; }\n        JComponent getView() { return view; }\n\n        void setOptions(JComponent[] options) { this.options = options != null ? options.clone() : null; }\n        JComponent[] getOptions() { return options != null ? options.clone() : null; }\n\n    }\n\n\n    private static class TabsContainer extends JPanel {\n\n        private List<Tab> tabs = new ArrayList<>();\n        private Tab selectedTab;\n\n        private TabsContainer() {\n            setLayout(null);\n            setOpaque(true);\n            setBackground(DisplayAreaSupport.BACKGROUND_COLOR_NORMAL);\n        }\n\n\n        private DisplayAreaSupport.TabButton addTab(Tab tab) {\n            if (tabs.contains(tab)) return null;\n\n            if (getLayout() == null) setLayout(new BoxLayout(this, BoxLayout.X_AXIS));\n            tabs.add(tab);\n            tabs.sort(Positionable.COMPARATOR);\n\n            DisplayAreaSupport.TabButton tabButton = new DisplayAreaSupport.TabButton(tab.getName(), tab.getDescription());\n            DisplayAreaSupport.TabButtonContainer tabButtonContainer = new DisplayAreaSupport.TabButtonContainer(tabButton);\n            tabButtonContainer.setAlignmentY(JComponent.TOP_ALIGNMENT);\n            add(tabButtonContainer, tabs.indexOf(tab));\n\n            updateTabButtons();\n\n            return tabButton;\n        }\n\n        private int indexOfTab(Tab tab) {\n            return tabs.indexOf(tab);\n        }\n\n        private boolean removeTab(Tab tab) {\n            int index = indexOfTab(tab);\n            if (index != -1) {\n                tabs.remove(index);\n                remove(index);\n                if (tab == selectedTab) selectedTab = null;\n                updateTabButtons();\n\n                return true;\n            }\n\n            return false;\n        }\n\n        private boolean containsTab(Tab tab) {\n            return tabs.contains(tab);\n        }\n\n        private void setSelectedTab(Tab tab) {\n            selectedTab = tab;\n            updateTabButtons();\n        }\n\n        private Tab getSelectedTab() {\n            return selectedTab;\n        }\n\n        private Tab getPreviousTab(Tab tab) {\n            int index = tabs.indexOf(tab);\n            return index > 0 ? tabs.get(--index) : null;\n        }\n\n        private Tab getNextTab(Tab tab) {\n            int index = tabs.indexOf(tab);\n            return index < tabs.size() - 1 ? tabs.get(++index) : null;\n        }\n\n        private int getTabsCount() {\n            return tabs.size();\n        }\n\n        private void updateTabButtons() {\n            int tabIndex = tabs.indexOf(selectedTab);\n            Component[] components = getComponents();\n            int componentsCount = components.length;\n            for (int i = 0; i < componentsCount; i++) ((DisplayAreaSupport.TabButtonContainer)components[i]).updateTabButton(i, tabIndex, componentsCount);\n        }\n\n    }\n\n    private static class MiddleSpacer extends JPanel {\n\n        private MiddleSpacer() {\n            setLayout(null);\n            setOpaque(true);\n            setBackground(DisplayAreaSupport.BACKGROUND_COLOR_NORMAL);\n        }\n\n        private void updateTabbed(boolean tabbed) {\n            if (tabbed)\n                setBorder(DisplayAreaSupport.TabbedCaptionBorder.get(\n                    DisplayAreaSupport.BORDER_COLOR_NORMAL, DisplayAreaSupport.COLOR_NONE,\n                    DisplayAreaSupport.BORDER_COLOR_HIGHLIGHT, DisplayAreaSupport.COLOR_NONE));\n            else\n                setBorder(DisplayAreaSupport.TabbedCaptionBorder.get(\n                    DisplayAreaSupport.BORDER_COLOR_NORMAL, DisplayAreaSupport.COLOR_NONE,\n                    DisplayAreaSupport.BACKGROUND_COLOR_NORMAL, DisplayAreaSupport.COLOR_NONE));\n        }\n\n    }\n\n    private static class OptionsContainer extends JPanel {\n\n        private JPanel contentsPanel;\n        private JButton closeButton;\n        private CardLayout layout = new CardLayout(0, 0);\n        private Map<Tab, JPanel> tabsMapper = new HashMap<>();\n\n        private OptionsContainer() {\n            initComponents();\n        }\n\n        private void setClosable(boolean closable) {\n            closeButton.setVisible(closable);\n        }\n\n        private boolean isClosable() {\n            return closeButton.isVisible();\n        }\n\n        private void addOptions(Tab tab) {\n            JPanel optionsContainer = new JPanel();\n            optionsContainer.setLayout(new BoxLayout(optionsContainer, BoxLayout.X_AXIS));\n            optionsContainer.setOpaque(false);\n\n            JComponent[] options = tab.getOptions();\n            if (options != null) for (JComponent option : options) {\n                option.setBorder(BorderFactory.createEmptyBorder(3, 5, 2, DisplayAreaSupport.TABBUTTON_MARGIN_RIGHT));\n                option.setAlignmentY(JComponent.CENTER_ALIGNMENT);\n                optionsContainer.add(option);\n            }\n\n            tabsMapper.put(tab, optionsContainer);\n            contentsPanel.add(optionsContainer, tab.getName());\n        }\n\n        private void removeOptions(Tab tab) {\n            JPanel optionsContainer = tabsMapper.remove(tab);\n            if (optionsContainer != null) contentsPanel.remove(optionsContainer);\n        }\n\n        private void setSelectedOptions(Tab tab) {\n            layout.show(contentsPanel, tab.getName());\n        }\n\n        private void updateTabbed(boolean tabbed) {\n            if (tabbed)\n                setBorder(DisplayAreaSupport.TabbedCaptionBorder.get(\n                    DisplayAreaSupport.BORDER_COLOR_NORMAL, DisplayAreaSupport.COLOR_NONE,\n                    DisplayAreaSupport.BORDER_COLOR_HIGHLIGHT, DisplayAreaSupport.BORDER_COLOR_NORMAL));\n            else\n                setBorder(DisplayAreaSupport.TabbedCaptionBorder.get(\n                    DisplayAreaSupport.BORDER_COLOR_NORMAL, DisplayAreaSupport.COLOR_NONE,\n                    DisplayAreaSupport.COLOR_NONE, DisplayAreaSupport.BORDER_COLOR_NORMAL));\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(true);\n            setBackground(DisplayAreaSupport.BACKGROUND_COLOR_NORMAL);\n\n//            ImageIcon closeIcon = new ImageIcon(DisplayArea.class.getResource(\"/org/graalvm/visualvm/core/ui/resources/closePanel.png\")); // NOI18N\n//            closeButton = new DisplayAreaSupport.ImageIconButton(closeIcon);\n            closeButton = CloseButtonFactory.createBigCloseButton();\n            closeButton.setFocusable(true); // GH-52 - enable closing the view using keyboard\n            closeButton.setToolTipText(NbBundle.getMessage(DisplayArea.class, \"ToolTip_Hide\")); // NOI18N\n            closeButton.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { getParent().getParent().setVisible(false); }\n            });\n\n            contentsPanel = new JPanel(layout);\n            contentsPanel.setOpaque(false);\n            add(contentsPanel, BorderLayout.WEST);\n            add(closeButton, BorderLayout.EAST);\n        }\n\n    }\n\n    private static class ViewArea extends JPanel {\n\n        private ViewArea() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n        }\n\n        private void setSelectedView(JComponent component) {\n            synchronized (getTreeLock()) {\n                removeAll();\n                if (component != null) add(component, BorderLayout.CENTER);\n                revalidate();\n                repaint();\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/components/DisplayAreaSupport.java",
    "content": "/*\n * TabbedCaptionSupport.java\n *\n * Created on Dec 11, 2007, 2:20:48 PM\n *\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui.components;\n\nimport java.awt.BasicStroke;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.FlowLayout;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Insets;\nimport java.awt.Stroke;\nimport java.awt.Toolkit;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport java.awt.image.FilteredImageSource;\nimport java.awt.image.ImageProducer;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultButtonModel;\nimport javax.swing.GrayFilter;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JPanel;\nimport javax.swing.UIManager;\nimport javax.swing.border.BevelBorder;\nimport javax.swing.border.Border;\nimport org.graalvm.visualvm.uisupport.UISupport;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass DisplayAreaSupport {\n\n    static final Color BORDER_COLOR_NORMAL = !UISupport.isDarkResultsBackground() ? new Color(192, 192, 192) : new Color(64, 64, 64);\n    static final Color BORDER_COLOR_HIGHLIGHT = !UISupport.isDarkResultsBackground() ? new Color(128, 128, 128) : new Color(90, 90, 90);\n    static final Color BACKGROUND_COLOR_NORMAL = !UISupport.isDarkResultsBackground() ? new Color(245, 245, 245) : new Color(50, 50, 50);\n    static final Color BACKGROUND_COLOR_HIGHLIGHT = !UISupport.isDarkResultsBackground() ? new Color(235, 235, 235) : new Color(55, 55, 55);\n\n    static final Color COLOR_NONE = new Color(0, 0, 0);\n    static final Color TABS_SEPARATOR = new Color(UIManager.getColor(\"Label.foreground\").getRGB()); // NOI18N\n\n    static final int TABBUTTON_MARGIN_TOP = 3;\n    static final int TABBUTTON_MARGIN_LEFT = 8;\n    static final int TABBUTTON_MARGIN_BOTTOM = 3;\n    static final int TABBUTTON_MARGIN_RIGHT = 8;\n\n    private static final Color TABBUTTON_FOCUS_COLOR = Color.BLACK;\n    private static final Stroke TABBUTTON_FOCUS_STROKE = new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 0, new float[] {0, 2}, 0);\n\n    static class TabButton extends JButton {\n\n        TabButton(String text, String description) {\n            super(text);\n            setModel(new DefaultButtonModel() {\n                public boolean isPressed() { return false; }\n            });\n            setOpaque(false);\n            setFocusPainted(false);\n            setBorderPainted(false);\n            setContentAreaFilled(false);\n            setBorder(BorderFactory.createEmptyBorder(TABBUTTON_MARGIN_TOP, TABBUTTON_MARGIN_LEFT, TABBUTTON_MARGIN_BOTTOM, TABBUTTON_MARGIN_RIGHT));\n            setToolTipText(description);\n        }\n\n        protected void paintComponent(Graphics g) {\n            super.paintComponent(g);\n\n            Dimension size = getSize();\n            Graphics2D g2 = (Graphics2D)g;\n            if( hasFocus() && isEnabled() ) {\n                g2.setStroke(TABBUTTON_FOCUS_STROKE);\n                g2.setColor(TABBUTTON_FOCUS_COLOR);\n                g2.drawRect(2, 2, size.width - 5, size.height - 5);\n            }\n        }\n\n    }\n\n    static class TabButtonContainer extends JPanel {\n\n        private TabButton tabButton;\n\n        TabButtonContainer(TabButton tabButton) {\n            this.tabButton = tabButton;\n            setOpaque(true);\n            setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0));\n            setBackground(BACKGROUND_COLOR_NORMAL);\n            setBorder(TabbedCaptionBorder.get(null, null, null, null));\n            add(tabButton, BorderLayout.CENTER);\n        }\n\n        public void setEnabled(boolean enabled) {\n            super.setEnabled(enabled);\n            tabButton.setEnabled(enabled);\n        }\n\n        void updateTabButton(int index, int selectedIndex, int buttonsCount) {\n            if (buttonsCount == 1) {\n                tabButton.setFocusable(false);\n                tabButton.setCursor(Cursor.getDefaultCursor());\n                setBackground(BACKGROUND_COLOR_NORMAL);\n                setBorder(TabbedCaptionBorder.get(BORDER_COLOR_NORMAL, BORDER_COLOR_NORMAL, COLOR_NONE, COLOR_NONE));\n            } else if (index == selectedIndex) {\n                tabButton.setFocusable(true);\n                tabButton.setCursor(Cursor.getDefaultCursor());\n                setBackground(BACKGROUND_COLOR_HIGHLIGHT);\n                setBorder(TabbedCaptionBorder.get(BORDER_COLOR_HIGHLIGHT, BORDER_COLOR_HIGHLIGHT, COLOR_NONE, BORDER_COLOR_HIGHLIGHT));\n            } else {\n                tabButton.setFocusable(true);\n                tabButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n                setBackground(BACKGROUND_COLOR_NORMAL);\n                Color topColor = BORDER_COLOR_NORMAL;\n                Color leftColor = index == 0 ? BORDER_COLOR_NORMAL : null;\n                Color bottomColor = BORDER_COLOR_HIGHLIGHT;\n                Color rightColor = index == selectedIndex - 1 ? null : index == buttonsCount - 1 ? COLOR_NONE : TABS_SEPARATOR;\n                setBorder(TabbedCaptionBorder.get(topColor, leftColor, bottomColor, rightColor));\n            }\n        }\n\n    }\n\n    static class TabbedCaptionBorder implements Border {\n\n        private static final Set<TabbedCaptionBorder> borders = new HashSet<>();\n\n        private Color COLOR_TOP;\n        private Color COLOR_LEFT;\n        private Color COLOR_BOTTOM;\n        private Color COLOR_RIGHT;\n        private Insets insets;\n\n\n        static TabbedCaptionBorder get(Color colorTop, Color colorLeft, Color colorBottom, Color colorRight) {\n            for (TabbedCaptionBorder border : borders)\n                // Note: identity must be used for the comparison!\n                if (border.COLOR_TOP == colorTop &&\n                    border.COLOR_LEFT == colorLeft &&\n                    border.COLOR_BOTTOM == colorBottom &&\n                    border.COLOR_RIGHT == colorRight) return border;\n\n            TabbedCaptionBorder border = new TabbedCaptionBorder(colorTop, colorLeft, colorBottom, colorRight);\n            borders.add(border);\n            return border;\n        }\n\n        private TabbedCaptionBorder(Color colorTop, Color colorLeft, Color colorBottom, Color colorRight) {\n            COLOR_TOP = colorTop;\n            COLOR_LEFT = colorLeft;\n            COLOR_BOTTOM = colorBottom;\n            COLOR_RIGHT = colorRight;\n\n            insets = new Insets(\n                    COLOR_TOP == null ? 0 : 1,\n                    COLOR_LEFT == null ? 0 : 1,\n                    COLOR_BOTTOM == null ? 0 : 1,\n                    COLOR_RIGHT == null ? 0 : 1);\n        }\n\n\n        public Insets getBorderInsets(Component c) { return insets; }\n\n        public boolean isBorderOpaque() { return true; }\n\n        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {\n            if (COLOR_LEFT != null && COLOR_LEFT != COLOR_NONE) {\n                g.setColor(COLOR_LEFT);\n                if (COLOR_LEFT == TABS_SEPARATOR) {\n                    g.drawLine(x, y + TABBUTTON_MARGIN_TOP + 2, x, y + height - TABBUTTON_MARGIN_BOTTOM - 4);\n                } else {\n                    g.drawLine(x, y, x, y + height - 1);\n                }\n            }\n            if (COLOR_RIGHT != null && COLOR_RIGHT != COLOR_NONE) {\n                g.setColor(COLOR_RIGHT);\n                if (COLOR_RIGHT == TABS_SEPARATOR) {\n                    g.drawLine(x + width - 1, y + TABBUTTON_MARGIN_TOP + 2, x + width - 1, y + height - TABBUTTON_MARGIN_BOTTOM - 4);\n                } else {\n                    g.drawLine(x + width - 1, y, x + width - 1, y + height - 1);\n                }\n            }\n            if (COLOR_TOP != null && COLOR_TOP != COLOR_NONE) {\n                g.setColor(COLOR_TOP);\n                g.drawLine(x, y, x + width - 1, y);\n            }\n            if (COLOR_BOTTOM != null && COLOR_BOTTOM != COLOR_NONE) {\n                g.setColor(COLOR_BOTTOM);\n                g.drawLine(x, y + height - 1, x + width - 1, y + height - 1);\n            }\n        }\n\n    }\n\n    private static class ThinBevelBorder extends BevelBorder {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        private ThinBevelBorder(int bevelType, Color highlight, Color shadow) {\n            super(bevelType, highlight.brighter(), highlight, shadow, shadow.brighter());\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public Insets getBorderInsets(Component c) {\n            return new Insets(1, 1, 1, 1);\n        }\n\n        public Insets getBorderInsets(Component c, Insets insets) {\n            insets.left = insets.top = insets.right = insets.bottom = 1;\n\n            return insets;\n        }\n\n        protected void paintLoweredBevel(Component c, Graphics g, int x, int y, int width, int height) {\n            if (!c.isEnabled()) {\n                return;\n            }\n\n            Color oldColor = g.getColor();\n            int h = height;\n            int w = width;\n\n            g.translate(x, y);\n\n            g.setColor(getShadowOuterColor(c));\n            g.drawLine(0, 0, 0, h - 1);\n            g.drawLine(1, 0, w - 1, 0);\n\n            g.setColor(getHighlightInnerColor(c));\n            g.drawLine(1, h - 1, w - 1, h - 1);\n            g.drawLine(w - 1, 1, w - 1, h - 2);\n\n            g.translate(-x, -y);\n            g.setColor(oldColor);\n        }\n\n        protected void paintRaisedBevel(Component c, Graphics g, int x, int y, int width, int height) {\n            if (!c.isEnabled()) {\n                return;\n            }\n\n            Color oldColor = g.getColor();\n            int h = height;\n            int w = width;\n\n            g.translate(x, y);\n\n            g.setColor(getHighlightInnerColor(c));\n            g.drawLine(0, 0, 0, h - 1);\n            g.drawLine(1, 0, w - 1, 0);\n\n            g.setColor(getShadowOuterColor(c));\n            g.drawLine(0, h - 1, w - 1, h - 1);\n            g.drawLine(w - 1, 0, w - 1, h - 2);\n\n            g.translate(-x, -y);\n            g.setColor(oldColor);\n        }\n    }\n\n    static class ImageIconButton extends JButton implements MouseListener {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private static final Border EMPTY_BORDER = BorderFactory.createEmptyBorder(1, 1, 1, 1);\n        private static final Border LOWERED_BORDER = new ThinBevelBorder(BevelBorder.LOWERED, Color.WHITE, Color.GRAY);\n        private static final Border RAISED_BORDER = new ThinBevelBorder(BevelBorder.RAISED, Color.WHITE, Color.GRAY);\n        private boolean rollover = false;\n        private boolean pressed = false;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ImageIconButton(ImageIcon icon) {\n            super();\n\n            GrayFilter enabledFilter = new GrayFilter(true, 35);\n            ImageProducer prod = new FilteredImageSource(icon.getImage().getSource(), enabledFilter);\n            Icon grayIcon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(prod));\n            GrayFilter disabledFilter = new GrayFilter(true, 60);\n            prod = new FilteredImageSource(icon.getImage().getSource(), disabledFilter);\n\n            Icon disabledIcon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(prod));\n\n            setIcon(grayIcon);\n            setRolloverIcon(icon);\n            setPressedIcon(icon);\n            setDisabledIcon(disabledIcon);\n            setIconTextGap(0);\n            setBorder(EMPTY_BORDER);\n            setFocusPainted(false);\n            setContentAreaFilled(false);\n\n            addMouseListener(this);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void mouseClicked(MouseEvent e) {\n        }\n\n        public void mouseEntered(MouseEvent e) {\n            rollover = true;\n\n            if (pressed) {\n                setBorder(LOWERED_BORDER);\n            } else {\n                setBorder(RAISED_BORDER);\n            }\n        }\n\n        public void mouseExited(MouseEvent e) {\n            rollover = false;\n            setBorder(EMPTY_BORDER);\n        }\n\n        public void mousePressed(MouseEvent e) {\n            pressed = true;\n            setBorder(LOWERED_BORDER);\n        }\n\n        public void mouseReleased(MouseEvent e) {\n            pressed = false;\n\n            if (rollover) {\n                setBorder(RAISED_BORDER);\n            } else {\n                setBorder(EMPTY_BORDER);\n            }\n        }\n\n        public Dimension getPreferredSize() {\n            return new Dimension(TABBUTTON_MARGIN_LEFT + TABBUTTON_MARGIN_RIGHT, TABBUTTON_MARGIN_LEFT + TABBUTTON_MARGIN_RIGHT);\n        }\n\n        protected void paintComponent(Graphics g) {\n            super.paintComponent(g);\n\n            Dimension size = getSize();\n            Graphics2D g2 = (Graphics2D)g;\n            if( hasFocus() && isEnabled() ) {\n                g2.setStroke(TABBUTTON_FOCUS_STROKE);\n                g2.setColor(TABBUTTON_FOCUS_COLOR);\n                g2.drawRect(2, 2, size.width - 5, size.height - 5);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/components/JExtendedSplitPane.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui.components;\n\nimport java.awt.Component;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport javax.swing.JSplitPane;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JExtendedSplitPane extends JSplitPane {\n\n    private HierarchyListener leftComponentListener;\n    private HierarchyListener rightComponentListener;\n    \n    private double dividerLocation;\n    private int customDividerSize;\n    private double requestedDividerLocation = -1;\n\n    \n    JExtendedSplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent) {\n        this(newOrientation, false, newLeftComponent, newRightComponent);\n    }\n\n    JExtendedSplitPane(int newOrientation, boolean newContinuousLayout, Component newLeftComponent,\n                              Component newRightComponent) {\n        super(newOrientation, newContinuousLayout, newLeftComponent, newRightComponent);\n\n        updateVisibility();\n\n        if (!newLeftComponent.isVisible())\n            computeDividerLocationWhenInitiallyHidden(newLeftComponent);\n\n        if (!newRightComponent.isVisible())\n            computeDividerLocationWhenInitiallyHidden(newRightComponent);\n    }\n\n\n    public void setDividerSize(int newSize) {\n        super.setDividerSize(newSize);\n        customDividerSize = newSize;\n    }\n\n    public void setDividerLocation(double requestedDividerLocation) {\n        Component divider = getDivider();\n        if (isVisible() && divider.isVisible()) { // SplitPane fully visible\n            super.setDividerLocation(requestedDividerLocation);\n            dividerLocation = requestedDividerLocation;\n        } else if (isVisible()) { // Divider not visible, will be updated in updateVisibility()\n            dividerLocation = requestedDividerLocation;\n        } else if (!isVisible()) { // SplitPane not visible, dividerLocation will be set on first reasonable getSize()\n            this.requestedDividerLocation = requestedDividerLocation;\n        }\n    }\n\n\n    public void setLeftComponent(Component newLeftComponent) {\n        if (leftComponent != null) {\n            leftComponent.removeHierarchyListener(leftComponentListener);\n            leftComponentListener = null;\n        }\n\n        super.setLeftComponent(newLeftComponent);\n\n        if (getLeftComponent() != null) {\n            leftComponentListener = new VisibilityListener(newLeftComponent);\n            newLeftComponent.addHierarchyListener(leftComponentListener);\n        }\n\n        updateVisibility();\n    }\n\n    public void setRightComponent(Component newRightComponent) {\n        if (rightComponent != null) {\n            rightComponent.removeHierarchyListener(rightComponentListener);\n            rightComponentListener = null;\n        }\n\n        super.setRightComponent(newRightComponent);\n\n        if (getRightComponent() != null) {\n            rightComponentListener = new VisibilityListener(newRightComponent);\n            newRightComponent.addHierarchyListener(rightComponentListener);\n        }\n\n        updateVisibility();\n    }\n    \n\n    public void reshape(int x, int y, int width, int height) {\n        super.reshape(x, y, width, height);\n        if (width > 0 && height > 0 && requestedDividerLocation != -1) {\n            super.setDividerLocation(requestedDividerLocation);\n            dividerLocation = requestedDividerLocation;\n            // SplitPaneUI.paint() needs to be invoked here to set the\n            // BasicSplitPaneUI.painted flag to enable resizing the divider\n            // even if the component hasn't been shown yet.\n            getUI().paint(getGraphics(), this);\n            requestedDividerLocation = -1;\n        }\n    }\n\n    \n    private Component getDivider() {\n        if (ui == null) return null;\n        return ((BasicSplitPaneUI)ui).getDivider();\n    }\n\n    private void computeDividerLocationWhenHidden(Component hiddenComponent) {\n        if (leftComponent.isVisible() || rightComponent.isVisible()) {\n            boolean horiz = getOrientation() == JSplitPane.HORIZONTAL_SPLIT;\n            double size  = horiz ? getSize().getWidth() :\n                                   getSize().getHeight();\n            double csize = horiz ? hiddenComponent.getSize().getWidth() :\n                                   hiddenComponent.getSize().getHeight();\n            computeDividerLocation(hiddenComponent, size, csize);\n        }\n    }\n\n    private void computeDividerLocationWhenInitiallyHidden(Component hiddenComponent) {\n        if (leftComponent.isVisible() || rightComponent.isVisible()) {\n            boolean horiz = getOrientation() == JSplitPane.HORIZONTAL_SPLIT;\n            double size  = horiz ? getPreferredSize().getWidth() :\n                                   getPreferredSize().getHeight();\n            double csize = horiz ? hiddenComponent.getPreferredSize().getWidth() :\n                                   hiddenComponent.getPreferredSize().getHeight();\n            computeDividerLocation(hiddenComponent, size, csize);\n        }\n    }\n\n    private void computeDividerLocation(Component hiddenComponent, double size, double csize) {\n        if (hiddenComponent == leftComponent) {\n            dividerLocation = csize / (size - customDividerSize);\n        } else {\n            dividerLocation = (size - customDividerSize - csize) / (size - customDividerSize);\n        }\n    }\n\n    private void updateVisibility() {\n        Component divider = getDivider(); // null UI, not yet set\n        if (divider == null) return;\n\n        if (leftComponent == null || rightComponent == null) return;\n\n        boolean leftVisible = leftComponent.isVisible();\n        boolean rightVisible = rightComponent.isVisible();\n\n        if (leftVisible && rightVisible) {\n            if (!divider.isVisible()) {\n                JExtendedSplitPane.super.setDividerSize(customDividerSize);\n                divider.setVisible(true);\n                setDividerLocation(dividerLocation);\n            }\n            if (!isVisible()) setVisible(true);\n        } else if (!leftVisible && !rightVisible) {\n            if (isVisible()) setVisible(false);\n        } else {\n            if (divider.isVisible()) {\n                JExtendedSplitPane.super.setDividerSize(0);\n                divider.setVisible(false);\n                setDividerLocation(0);\n            }\n            if (!isVisible()) setVisible(true);\n        }\n\n        if (getParent() != null) getParent().doLayout();\n    }\n\n\n    private class VisibilityListener implements HierarchyListener {\n\n        private boolean wasVisible;\n        private final Component c;\n\n        VisibilityListener(Component c) {\n            this.c = c;\n            wasVisible = c.isVisible();\n        }\n\n        public void hierarchyChanged(HierarchyEvent e) {\n            if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 ||\n                (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) {\n                \n                boolean visible = c.isVisible();\n                if (wasVisible == visible) return;\n\n                wasVisible = visible;\n\n                if (visible) componentShown();\n                else componentHidden(c);\n            }\n        }\n\n        private void componentHidden(Component c) {\n            computeDividerLocationWhenHidden(c);\n\n            // Make sure the component is visible when shown\n            if ((dividerLocation <= 0) || (dividerLocation >= 1))\n                dividerLocation = 0.5;\n\n            updateVisibility();\n        }\n\n        private void componentShown() {\n            updateVisibility();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/components/LevelIndicator.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui.components;\n\nimport java.awt.AWTException;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.GradientPaint;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.ImageCapabilities;\nimport java.awt.Insets;\nimport java.awt.image.VolatileImage;\nimport javax.accessibility.AccessibleContext;\nimport javax.accessibility.AccessibleRole;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.border.BevelBorder;\n\n\n/**\n * Graphical component for fall-off level indicator\n * @author Jaroslav Bachorik\n */\npublic class LevelIndicator extends JComponent {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Insets NULL_INSETS = new Insets(0, 0, 0, 0);\n    private static final Dimension PREFERRED_SIZE = new Dimension(40, 20);\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Color maximumColor = Color.RED;\n    private Color minimumColor = Color.GREEN;\n    private Color peakColor = null;\n    private Dimension canvasDimension = null;\n    private Insets canvasInsets = NULL_INSETS;\n    private boolean autoRepaint = true;\n    private boolean followPeak;\n    private int peakMarkSize = 8; // peak mark size in pixels\n    private long max = 0;\n    private long min = 0;\n    private long peak = Long.MIN_VALUE;\n    private long val = min;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public LevelIndicator() {\n        setPreferredSize(PREFERRED_SIZE);\n        setMinimumSize(PREFERRED_SIZE);\n        setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Sets the auto repainting of the component on/off\n     * @param autoRepaint The auto repainting on/off\n     */\n    public void setAutoRepaint(boolean autoRepaint) {\n        this.autoRepaint = autoRepaint;\n    }\n\n    /**\n     * Status of the component auto repainting\n     * @return Returns the status of the component auto repainting\n     */\n    public boolean isAutoRepaint() {\n        return autoRepaint;\n    }\n\n    /**\n     * When set, the component will mark the so-far highest value\n     * @param markPeaks Set peak following on/off\n     */\n    public void setFollowPeak(boolean markPeaks) {\n        this.followPeak = markPeaks;\n    }\n\n    /**\n     * Status of the follow-peak\n     * @return Returns the status of the follow-peak property\n     */\n    public boolean isFollowPeak() {\n        return followPeak;\n    }\n\n    /**\n     * Sets the component maximum value\n     * Will repaint the component if {@linkplain #isAutoRepaint() } is on\n     * @param max The maximum value the component would display\n     */\n    public void setMaximum(long max) {\n        this.max = max;\n\n        if (autoRepaint) {\n            repaint();\n        }\n    }\n\n    /**\n     * Returns the component maximum value\n     * @return Returns the component maximum value\n     */\n    public long getMaximum() {\n        return max;\n    }\n\n    /**\n     * With this property you can control the {@linkplain Color} of the highest value\n     * Will repaint the component if {@linkplain #isAutoRepaint() } is on\n     * @param maximumColor The {@linkplain Color} to be used for the highest values\n     */\n    public void setMaximumColor(Color maximumColor) {\n        this.maximumColor = maximumColor;\n    }\n\n    /**\n     * Returns the {@linkplain Color} of the highest values\n     * @return Returns the {@linkplain Color} of the highest values\n     */\n    public Color getMaximumColor() {\n        return maximumColor;\n    }\n\n    /**\n     * Sets the minimum displayable value of the component\n     * Will repaint the component if {@linkplain #isAutoRepaint() } is on\n     * @param min The minimal value that should be displayed\n     */\n    public void setMinimum(long min) {\n        this.min = min;\n\n        if (autoRepaint) {\n            repaint();\n        }\n    }\n\n    /**\n     * Returns the component minimal value\n     * @return Returns the component minimal value\n     */\n    public long getMinimum() {\n        return min;\n    }\n\n    /**\n     * Sets the {@linkplain Color} for the minimal value\n     * Will repaint the component if {@linkplain #isAutoRepaint() } is on\n     * @param minimumColor The {@linkplain Color} to use for the minimal value\n     */\n    public void setMinimumColor(Color minimumColor) {\n        this.minimumColor = minimumColor;\n    }\n\n    /**\n     * Returns the {@linkplain Color} used for the minimal value\n     * @return Returns the {@linkplain Color} used for the minimal value\n     */\n    public Color getMinimumColor() {\n        return minimumColor;\n    }\n\n    /**\n     * Manually sets the actual value as the peak\n     * Will repaint the component if {@linkplain #isAutoRepaint() } is on\n     */\n    public void setPeak() {\n        peak = val;\n\n        if (autoRepaint) {\n            repaint();\n        }\n    }\n\n    /**\n     * Manually sets the peak\n     * Will repaint the component if {@linkplain #isAutoRepaint() } is on\n     * @param value The value to set as the peak\n     */\n    public void setPeak(long value) {\n        if (peak <= max) {\n            peak = value;\n\n            if (autoRepaint) {\n                repaint();\n            }\n        }\n    }\n\n    /**\n     * Returns the current peak value\n     * @return Returns the current peak value\n     */\n    public long getPeak() {\n        return peak;\n    }\n\n    /**\n     * Sets the peak mark size in pixels\n     * The peak mark is rendered in the indicator at the place of peak value\n     * @param peakMarkSize The peak mark size in pixels\n     */\n    public void setPeakMarkSize(int peakMarkSize) {\n        this.peakMarkSize = peakMarkSize;\n\n        if (autoRepaint) {\n            repaint();\n        }\n    }\n\n    /**\n     * Returns the peak mark size in pixels\n     * The peak mark is rendered in the indicator at the place of peak value\n     * @return Returns the peak mark size in pixels\n     */\n    public int getPeakMarkSize() {\n        return peakMarkSize;\n    }\n\n    /**\n     * Sets the current value of the indicator\n     * @param value The current value\n     */\n    public void setValue(long value) {\n        val = Math.max(Math.min(value, max), 0);\n\n        if (followPeak && (val > peak)) {\n            peak = this.val;\n        }\n\n        if (autoRepaint) {\n            repaint();\n        }\n    }\n\n    /**\n     * Returns the current value\n     * @return Returns the current value\n     */\n    public long getValue() {\n        return val;\n    }\n\n    @Override\n    public void doLayout() {\n        super.doLayout();\n\n        canvasInsets = getInsets();\n\n        canvasDimension = new Dimension(getBounds().width - (canvasInsets.left + canvasInsets.right),\n                                        getBounds().height - (canvasInsets.top + canvasInsets.bottom));\n    }\n\n    @Override\n    public void paintComponent(Graphics g) {\n        if (canvasDimension == null) {\n            return;\n        }\n\n        if ((canvasDimension.getHeight() < 0) || (canvasDimension.getWidth() < 0)) {\n            return; // no rendering if dimensions are negative\n        }\n\n        try {\n            VolatileImage img = createVolatileImage(getBounds().width - (canvasInsets.left + canvasInsets.right),\n                                                    getBounds().height - (canvasInsets.top + canvasInsets.bottom),\n                                                    new ImageCapabilities(true));\n            Graphics2D gr = img.createGraphics();\n            renderLevel(gr, img);\n            renderPeak(gr);\n\n            gr.dispose();\n            g.drawImage(img, canvasInsets.left, canvasInsets.top, this);\n\n            //\n            //            if (getBorder() != null) {\n            //                getBorder().paintBorder(this, g, 0, 0, getBounds().width, getBounds().height);\n            //            }\n        } catch (AWTException e) {\n        }\n    }\n\n    /**\n     * Cleans the peak mark\n     * Will repaint the component\n     */\n    public void unsetPeak() {\n        peak = Integer.MIN_VALUE;\n        repaint();\n    }\n\n\n    /**\n     * Gets a dummy AccessibleContext associated with this LevelIndicator.\n     *\n     * @return a dummy AccessibleContext associated with this LevelIndicator\n     */\n    public AccessibleContext getAccessibleContext() {\n        if (accessibleContext == null) {\n            accessibleContext = new AccessibleLevelIndicator();\n        }\n        return accessibleContext;\n    }\n\n\n    private Color getColorAt(VolatileImage img, int x, int y) {\n        if ((x <= 0) || (y < 0) || (x > img.getWidth()) || (y > img.getHeight())) {\n            return null;\n        }\n\n        int RGB = img.getSnapshot().getRGB(x - 1, 0);\n        int red = (RGB & 0x00ff0000) >> 16;\n        int green = (RGB & 0x0000ff00) >> 8;\n        int blue = RGB & 0x000000ff;\n\n        // and the Java Color is ...\n        return new Color(red, green, blue);\n    }\n\n    private int getPosition(long value) {\n        float ratio = (float) value / (float) (max - min);\n\n        return Math.round((float) (ratio * canvasDimension.getWidth()));\n    }\n\n    private void renderLevel(Graphics2D gr, VolatileImage img) {\n        gr.setPaint(new GradientPaint(0, 0, minimumColor, canvasDimension.width, 0, maximumColor));\n        gr.fillRect(0, 0, canvasDimension.width, canvasDimension.height);\n\n        if (peak > Integer.MIN_VALUE) {\n            peakColor = getColorAt(img, getPosition(peak), 0);\n        }\n\n        int position = getPosition(val);\n\n        gr.setPaint(getBackground());\n        gr.fillRect(position, 0, canvasDimension.width - position + 1, canvasDimension.height);\n    }\n\n    private void renderPeak(Graphics2D gr) {\n        if (peakColor == null) {\n            return;\n        }\n\n        int position = getPosition(peak);\n\n        int decrement = 0;\n        int left = 0;\n        int right = 0;\n\n        do {\n            left = Math.round(position - ((peakMarkSize - decrement) / 2f));\n            right = Math.round(left + ((peakMarkSize - decrement) / 2f));\n\n            if (left < 0) {\n                right += Math.abs(left);\n                left = 0;\n            }\n\n            if (right > canvasDimension.getWidth()) {\n                left -= (right - canvasDimension.getWidth());\n                right = (int) canvasDimension.getWidth();\n            }\n\n            decrement++;\n        } while (((left < 0) || (right > canvasDimension.getWidth())) && (left != right));\n\n        gr.setPaint(peakColor);\n        gr.fillRect(left, 0, right - left + 1, canvasDimension.height);\n    }\n\n\n    /**\n     * Dummy AccessibleContext implementation for the LevelIndicator.\n     */\n    private class AccessibleLevelIndicator extends AccessibleJComponent {\n\n        /**\n         * Get the role of this object.\n         *\n         * @return an instance of AccessibleRole describing the role of the\n         * object\n         */\n        public AccessibleRole getAccessibleRole() {\n            return AccessibleRole.SWING_COMPONENT;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/components/NotSupportedDisplayer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui.components;\n\nimport java.awt.BorderLayout;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingConstants;\nimport org.openide.util.NbBundle;\n\n/**\n * JPanel showing a predefined message.\n *\n * @author Jiri Sedlacek\n */\npublic final class NotSupportedDisplayer extends JPanel {\n\n    /**\n     * Not supported for this application.\n     */\n    public static final String APPLICATION = NbBundle.getMessage(NotSupportedDisplayer.class, \"MSG_application\");   // NOI18N\n    /**\n     * Not supported for this JVM.\n     */\n    public static final String JVM = NbBundle.getMessage(NotSupportedDisplayer.class, \"MSG_JVM\");   // NOI18N\n    /**\n     * Not supported for this host.\n     */\n    public static final String HOST = NbBundle.getMessage(NotSupportedDisplayer.class, \"MSG_host\"); // NOI18N\n    /**\n     * Not supported for this OS.\n     */\n    public static final String OS = NbBundle.getMessage(NotSupportedDisplayer.class, \"MSG_OS\"); // NOI18N\n\n    /**\n     * Creates new instance of NotSupportedDisplayer.\n     * \n     * @param object type of the not supported object (any string or predefined constant).\n     */\n    public NotSupportedDisplayer(String object) {\n        JLabel notSupportedLabel = new JLabel(NbBundle.getMessage(NotSupportedDisplayer.class, \"MSG_Not_supported\", object), SwingConstants.CENTER);    // NOI18N\n        notSupportedLabel.setEnabled(false);\n\n        setLayout(new BorderLayout());\n        setOpaque(false);\n        \n        add(notSupportedLabel, BorderLayout.CENTER);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/components/ScrollableContainer.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui.components;\n\nimport java.awt.BorderLayout;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Rectangle;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JViewport;\nimport javax.swing.Scrollable;\n\n/**\n * Predefined JScrollPane to be used in VisualVM, for example in details views.\n * Use UISupport.createScrollableContainer() method instead of instantiating\n * this class directly if creating scrollable container for the Options panel.\n *\n * @author Jiri Sedlacek\n */\npublic final class ScrollableContainer extends JScrollPane {\n\n    /**\n     * Creates new instance of ScrollableContainer.\n     * \n     * @param view component to be displayed\n     */\n    public ScrollableContainer(JComponent view) {\n        this(view, VERTICAL_SCROLLBAR_AS_NEEDED,\n             HORIZONTAL_SCROLLBAR_AS_NEEDED);\n    }\n\n    /**\n     * Creates new instance of ScrollableContainer.\n     *\n     * @param view component to be displayed\n     * @param vsbPolicy policy flag for the vertical scrollbar\n     * @param hsbPolicy policy flag for the horizontal scrollbar\n     */\n    public ScrollableContainer(JComponent view, int vsbPolicy, int hsbPolicy) {\n        setViewportView(new ScrollableContents(view));\n\n        setVerticalScrollBarPolicy(vsbPolicy);\n        setHorizontalScrollBarPolicy(hsbPolicy);\n\n        setBorder(BorderFactory.createEmptyBorder());\n        setViewportBorder(BorderFactory.createEmptyBorder());\n\n        getViewport().setOpaque(false);\n        setOpaque(false);\n    }\n\n\n    // --- Scrollable container ------------------------------------------------\n\n    private class ScrollableContents extends JPanel implements Scrollable {\n\n        private ScrollableContents(JComponent contents) {\n            super(new BorderLayout());\n            setOpaque(false);\n            add(contents, BorderLayout.CENTER);\n        }\n\n        public Dimension getPreferredScrollableViewportSize() {\n            return getPreferredSize();\n        }\n\n        public int getScrollableUnitIncrement(Rectangle visibleRect,\n                                              int orientation, int direction) {\n            return 20;\n        }\n\n        public int getScrollableBlockIncrement(Rectangle visibleRect,\n                                               int orientation, int direction) {\n            return (int)(visibleRect.height * 0.9d);\n        }\n\n        public boolean getScrollableTracksViewportWidth() {\n            if (getHorizontalScrollBarPolicy() == HORIZONTAL_SCROLLBAR_NEVER)\n                return true;\n\n            Container parent = getParent();\n            if (!(parent instanceof JViewport)) return false;\n            return getMinimumSize().width < parent.getWidth();\n        }\n\n        public boolean getScrollableTracksViewportHeight() {\n            if (getVerticalScrollBarPolicy() == VERTICAL_SCROLLBAR_NEVER)\n                return true;\n\n            Container parent = getParent();\n            if (!(parent instanceof JViewport)) return false;\n            return getMinimumSize().height < parent.getHeight();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/components/SectionSeparator.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui.components;\n\nimport org.graalvm.visualvm.uisupport.SeparatorLine;\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\n\n/**\n * Separator-like component to be used instead of TitledBorder to keep the UI\n * lightweight. Use UISupport.createSectionSeparator() method instead of instantiating\n * this class directly if creating sections for the Options panel.\n *\n * @author Jiri Sedlacek\n */\npublic final class SectionSeparator extends JPanel {\n\n    /**\n     * Creates new instance of SectionSeparator. Uses bold font by default.\n     *\n     * @param text separator text\n     */\n    public SectionSeparator(String text) {\n        this(text, null);\n    }\n\n    /**\n     * Creates new instance of SectionSeparator. Uses the provided font or default\n     * font if no font is provided.\n     *\n     * @param text separator text\n     * @param font font for the caption text or null for default font\n     */\n    public SectionSeparator(String text, Font font) {\n        if (text == null) throw new IllegalArgumentException(\"Text cannot be null\"); // NOI18N\n        initComponents(text, font);\n    }\n\n    public void setForeground(Color foreground) {\n        if (label == null) super.setForeground(foreground);\n        else label.setForeground(foreground);\n    }\n\n    public Color getForeground() {\n        if (label == null) return super.getForeground();\n        else return label.getForeground();\n    }\n\n    public void setFont(Font font) {\n        if (label == null) super.setFont(font);\n        else label.setFont(font);\n    }\n\n    public Font getFont() {\n        if (label == null) return super.getFont();\n        else return label.getFont();\n    }\n\n    private void initComponents(String text, Font font) {\n        setBorder(BorderFactory.createEmptyBorder());\n        setLayout(new GridBagLayout());\n        setOpaque(false);\n\n        label = new JLabel(text);\n        label.setForeground(getForeground());\n        if (font != null) label.setFont(font);\n        else label.setFont(label.getFont().deriveFont(Font.BOLD));\n        GridBagConstraints c1 = new GridBagConstraints();\n        c1.weighty = 1d;\n        add(label, c1);\n\n        GridBagConstraints c2 = new GridBagConstraints();\n        c2.weightx = 1d;\n        c2.fill = GridBagConstraints.HORIZONTAL;\n        c2.insets = new Insets(1, 4, 0, 0);\n        add(new SeparatorLine(), c2);\n    }\n\n    private JLabel label;\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/components/Spacer.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.ui.components;\n\nimport java.awt.Dimension;\nimport javax.swing.JPanel;\n\n/**\n * Subclass of a JPanel to be used as a spacer in GridBagLayout. Creates a\n * non-opaque JPanel with null Layout and zero preferred size.\n *\n * @author Jiri Sedlacek\n */\npublic final class Spacer extends JPanel {\n    \n    private static final Dimension DIMENSION_ZERO = new Dimension(0, 0);\n\n\n    /**\n     * Creates new instance of Spacer.\n     *\n     * @return new instance of Spacer\n     */\n    public static Spacer create() { return new Spacer(); }\n\n\n    public Dimension getPreferredSize() { return DIMENSION_ZERO; }\n\n    private Spacer() {\n        super(null);\n        setOpaque(false);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/components/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Custom UI components used in VisualVM.\n */\npackage org.graalvm.visualvm.core.ui.components;\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/options/Bundle.properties",
    "content": "#\n# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nArgument_WindowToFront_ShortDescr=bring VisualVM window to front\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/options/WindowToFront.java",
    "content": "package org.graalvm.visualvm.core.ui.options;\n/*\n * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n\nimport java.awt.Frame;\nimport java.util.Collections;\nimport java.util.Map;\nimport java.util.Set;\nimport org.netbeans.api.sendopts.CommandException;\nimport org.netbeans.spi.sendopts.Env;\nimport org.netbeans.spi.sendopts.Option;\nimport org.netbeans.spi.sendopts.OptionProcessor;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.windows.WindowManager;\n\n/**\n * Command line option --window-to-front to bring the VisualVM window to front\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=OptionProcessor.class)\npublic final class WindowToFront extends OptionProcessor {\n    \n    private static final String LONG_NAME = \"window-to-front\";                  // NOI18N\n    private static final Option ARGUMENT = Option.shortDescription(Option.withoutArgument(Option.NO_SHORT_NAME, LONG_NAME), \"org.graalvm.visualvm.core.ui.options.Bundle\", \"Argument_WindowToFront_ShortDescr\"); // NOI18N\n    \n    @Override\n    protected Set<Option> getOptions() {\n        return Collections.singleton(ARGUMENT);\n    }\n    \n    @Override\n    protected void process(Env env, Map<Option, String[]> maps) throws CommandException {\n        String[] opts = maps.get(ARGUMENT);\n        if (opts != null) {\n            WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n                public void run() {\n                    Frame f = WindowManager.getDefault().getMainWindow();\n                    f.setVisible(true);\n                    f.setExtendedState(f.getExtendedState() & ~Frame.ICONIFIED);\n                    f.setAlwaysOnTop(true);\n                    f.toFront();\n                    f.requestFocus();\n                    f.setAlwaysOnTop(false);\n                }\n            });\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * APIs for VisualVM UI.\n */\npackage org.graalvm.visualvm.core.ui;\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/resources/ExplorerTopComponentSettings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE settings PUBLIC \"-//NetBeans//DTD Session settings 1.0//EN\" \"http://www.netbeans.org/dtds/sessionsettings-1_0.dtd\">\n<settings version=\"1.0\">\n  <module name=\"org.graalvm.visualvm.core\" spec=\"1.0\"/>\n  <instanceof class=\"org.openide.windows.TopComponent\"/>\n  <instanceof class=\"org.graalvm.visualvm.core.explorer.ExplorerTopComponent\"/>\n  <instance class=\"org.graalvm.visualvm.core.explorer.ExplorerTopComponent\" method=\"getInstance\"/>\n</settings>\n"
  },
  {
    "path": "visualvm/core/src/org/graalvm/visualvm/core/ui/resources/ExplorerTopComponentWstcref.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE tc-ref PUBLIC \"-//NetBeans//DTD Top Component in Mode Properties 2.0//EN\" \"http://www.netbeans.org/dtds/tc-ref2_0.dtd\">\n<tc-ref version=\"2.0\" >\n  <module name=\"org.graalvm.visualvm.core\" spec=\"1.0\"/>\n  <tc-id id=\"ExplorerTopComponent\"/>\n  <state opened=\"true\"/>\n</tc-ref>\n"
  },
  {
    "path": "visualvm/core/test/unit/src/com/sun/tools/visualvm/core/scheduler/DefaultScheduledTaskTest.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.scheduler;\n\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport static org.junit.Assert.*;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class DefaultScheduledTaskTest {\n    private SchedulerTask dummyTask = new SchedulerTask() {\n\n        public void onSchedule(long timeStamp) {\n            // do nothing\n        }\n    };\n    \n    private DefaultScheduledTask instance;\n    final private static Quantum DEFAULT_INTERVAL = Quantum.seconds(10);\n    \n    public DefaultScheduledTaskTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n    }\n\n    @Before\n    public void setUp() {\n        instance = new DefaultScheduledTask(DEFAULT_INTERVAL, dummyTask);\n    }\n\n    @After\n    public void tearDown() {\n        instance = null;\n    }\n\n    /**\n     * Test of setInterval method, of class DefaultScheduledTask.\n     */\n    @Test\n    public void setInterval() {\n        System.out.println(\"setInterval\");\n        Quantum interval = Quantum.SUSPENDED;\n        assertEquals(DEFAULT_INTERVAL, instance.getInterval());\n        instance.setInterval(interval);\n        assertEquals(interval, instance.getInterval());\n    }\n\n    /**\n     * Test of suspend method, of class DefaultScheduledTask.\n     */\n    @Test\n    public void suspend() {\n        System.out.println(\"suspend\");\n        instance.suspend();\n        assertEquals(Quantum.SUSPENDED, instance.getInterval());        \n    }\n\n    /**\n     * Test of resume method, of class DefaultScheduledTask.\n     */\n    @Test\n    public void resume() {\n        System.out.println(\"resume\");\n        instance.suspend();\n        instance.resume();\n        assertEquals(DEFAULT_INTERVAL, instance.getInterval());\n    }\n\n    /**\n     * Test of isSuspended method, of class DefaultScheduledTask.\n     */\n    @Test\n    public void isSuspended() {\n        System.out.println(\"isSuspended\");\n        assertFalse(instance.isSuspended());\n        instance.suspend();\n        assertTrue(instance.isSuspended());\n        instance.resume();\n        assertFalse(instance.isSuspended());\n    }\n}"
  },
  {
    "path": "visualvm/core/test/unit/src/com/sun/tools/visualvm/core/scheduler/QuantumTest.java",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.core.scheduler;\n\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport static org.junit.Assert.*;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class QuantumTest {\n\n    public QuantumTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    /**\n     * Test of equals method, of class Quantum.\n     */\n    @Test\n    public void equalsBasic() {\n        System.out.println(\"basic equals\");\n        Quantum instance1 = Quantum.seconds(10);\n        Quantum instance2 = Quantum.seconds(10);\n        Quantum instance3 = Quantum.seconds(20);\n        \n        assertFalse(instance1 == instance2 || instance2 == instance3 || instance1 == instance3);\n        assertTrue(instance1.equals(instance2));\n        assertTrue(instance2.equals(instance1));\n        assertFalse(instance2.equals(instance3));\n        assertFalse(instance3.equals(instance2));\n        assertFalse(instance1.equals(instance3));\n        assertFalse(instance3.equals(instance1));\n    }\n}"
  },
  {
    "path": "visualvm/core/test/unit/src/com/sun/tools/visualvm/core/scheduler/SchedulerTest.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.core.scheduler;\n\nimport java.beans.PropertyChangeEvent;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.CyclicBarrier;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport static org.junit.Assert.*;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class SchedulerTest {\n    private final Collection<ScheduledTask> stasks = new  ArrayList<>();\n    \n    public SchedulerTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n    }\n\n    @Before\n    public void setUp() {\n        stasks.clear();\n    }\n\n    @After\n    public void tearDown() {\n        for(ScheduledTask stask : stasks) {\n            Scheduler.sharedInstance().unschedule(stask);\n        }\n    }\n\n    /**\n     * Test of sharedInstance method, of class Scheduler.\n     */\n    @Test\n    public void sharedInstance() {\n        System.out.println(\"sharedInstance\");\n\n        Scheduler result1 = Scheduler.sharedInstance();\n        Scheduler result2 = Scheduler.sharedInstance();\n        assertTrue(result1 == result2); // shared instance MUST remain the same across all calls        \n    }\n\n    /**\n     * Test of schedule method, immediate execution, of class Scheduler.\n     */\n    @Test\n    public void scheduleImmediate() {\n        System.out.println(\"schedule, immediate\");\n        final CountDownLatch barrier = new CountDownLatch(1);\n        SchedulerTask task = new SchedulerTask() {\n\n            public void onSchedule(long timeStamp) {\n                barrier.countDown();\n            }\n        };\n        Quantum interval = Quantum.seconds(2000);\n        Scheduler instance = Scheduler.sharedInstance();\n        ScheduledTask scheduled = instance.schedule(task, interval, true);\n        stasks.add(scheduled);\n        try {\n            boolean executed = barrier.await(1000, TimeUnit.SECONDS);\n            assertTrue(executed);\n        } catch (InterruptedException e) {\n            fail(e.getMessage());\n        }\n    }\n\n    /**\n     * Test of schedule method, immediate execution, blocking in the scheduled task, of class Scheduler.\n     */\n    @Test\n    public void scheduleImmediateBlocking() {\n        System.out.println(\"schedule, immediate, blocking\");\n        final CountDownLatch barrier = new CountDownLatch(1);\n        SchedulerTask task = new SchedulerTask() {\n\n            public void onSchedule(long timeStamp) {\n                try {\n                    barrier.countDown();\n                    Thread.sleep(10000000);\n                } catch (InterruptedException e) {\n                    Thread.currentThread().interrupt();\n                }\n            }\n        };\n        Quantum interval = Quantum.seconds(2000);\n        Scheduler instance = Scheduler.sharedInstance();\n        ScheduledTask scheduled = instance.schedule(task, interval, true);\n        stasks.add(scheduled);\n        try {\n            boolean executed = barrier.await(1000, TimeUnit.SECONDS);\n            assertTrue(executed);\n        } catch (InterruptedException e) {\n            fail(e.getMessage());\n        }\n    }\n\n    /**\n     * Test of schedule method of class Scheduler.\n     */\n    @Test\n    public void schedule() {\n        System.out.println(\"schedule\");\n        final CountDownLatch barrier = new CountDownLatch(1);\n        SchedulerTask task = new SchedulerTask() {\n\n            public void onSchedule(long timeStamp) {\n                barrier.countDown();\n            }\n        };\n        Quantum interval = Quantum.seconds(5);\n        Scheduler instance = Scheduler.sharedInstance();\n        ScheduledTask scheduled = instance.schedule(task, interval, false);\n        stasks.add(scheduled);\n        try {\n            boolean executed = barrier.await(8, TimeUnit.SECONDS);\n            assertTrue(executed);\n        } catch (InterruptedException e) {\n            fail(e.getMessage());\n        }\n    }\n\n    /**\n     * Test of unschedule method, of class Scheduler.\n     */\n    @Test\n    public void unschedule() {\n        System.out.println(\"unschedule\");\n        final AtomicBoolean executed = new AtomicBoolean(false);\n        SchedulerTask task = new SchedulerTask() {\n\n            public void onSchedule(long timeStamp) {\n                executed.set(true);\n            }\n        };\n        Scheduler instance = Scheduler.sharedInstance();\n        ScheduledTask scheduled = instance.schedule(task, Quantum.seconds(3), false);\n        instance.unschedule(scheduled);\n\n        try {\n            Thread.sleep(5000);\n        } catch (InterruptedException e) {\n            fail(e.getMessage());\n        }\n        assertFalse(executed.get());\n    }\n\n    /**\n     * Test of dynamic rescheduling capability of class Scheduler.\n     */\n    @Test\n    public void dynamicReschedule() {\n        System.out.println(\"dynamicReschedule\");\n        final CountDownLatch barrier1 = new CountDownLatch(1);\n        final CountDownLatch barrier2 = new CountDownLatch(2);\n\n        SchedulerTask task = new SchedulerTask() {\n\n            public void onSchedule(long timeStamp) {\n                System.out.println(\"dynamicReschedule; executing periodic task\");\n                barrier1.countDown();\n                barrier2.countDown();\n            }\n        };\n\n        final ScheduledTask scheduled = Scheduler.sharedInstance().schedule(task, Quantum.seconds(7), false);\n        stasks.add(scheduled);\n        try {\n            if (!barrier1.await(10, TimeUnit.SECONDS)) {\n                fail();\n            }\n            scheduled.setInterval(Quantum.seconds(2));\n            if (!barrier2.await(5, TimeUnit.SECONDS)) {\n                fail();\n            }\n        } catch (InterruptedException e) {\n            fail(e.getMessage());\n        }\n    }\n\n    @Test\n    public void dynamicRescheduleSuspended() {\n        System.out.println(\"dynamicReschedule suspended\");\n        final CountDownLatch barrier1 = new CountDownLatch(1);\n        final CountDownLatch barrier2 = new CountDownLatch(5);\n\n        SchedulerTask task = new SchedulerTask() {\n\n            public void onSchedule(long timeStamp) {\n                System.out.println(\"dynamicReschedule; executing periodic task\");\n                barrier1.countDown();\n                barrier2.countDown();\n            }\n        };\n\n        final ScheduledTask scheduled = Scheduler.sharedInstance().schedule(task, Quantum.SUSPENDED, false);\n        stasks.add(scheduled);\n        try {\n            if (barrier1.await(5, TimeUnit.SECONDS)) {\n                fail();\n            }\n            scheduled.resume();\n            if (barrier2.await(2, TimeUnit.SECONDS)) {\n                fail();\n            }\n            scheduled.setInterval(Quantum.seconds(1));\n            if (!barrier2.await(8, TimeUnit.SECONDS)) {\n                fail();\n            }\n        } catch (InterruptedException e) {\n            fail(e.getMessage());\n        }\n    }\n\n    @Test\n    public void suspendResume() {\n        System.out.println(\"suspend-resume\");\n        final CountDownLatch barrier1 = new CountDownLatch(1);\n        final CountDownLatch barrier2 = new CountDownLatch(5);\n\n        SchedulerTask task = new SchedulerTask() {\n\n            public void onSchedule(long timeStamp) {\n                barrier1.countDown();\n                barrier2.countDown();\n            }\n        };\n\n        final ScheduledTask scheduled = Scheduler.sharedInstance().schedule(task, Quantum.seconds(2), false);\n        stasks.add(scheduled);\n        try {\n            if (!barrier1.await(3, TimeUnit.SECONDS)) {\n                fail();\n            }\n            scheduled.suspend();\n            if (barrier2.await(3, TimeUnit.SECONDS)) {\n                fail();\n            }\n            scheduled.resume();\n            if (!barrier2.await(10, TimeUnit.SECONDS)) {\n                fail();\n            }\n        } catch (InterruptedException e) {\n            fail(e.getMessage());\n        }\n    }\n\n    @Test\n    public void suspendSuspend() {\n        System.out.println(\"suspend-suspend\");\n        final CountDownLatch barrier1 = new CountDownLatch(1);\n        final CountDownLatch barrier2 = new CountDownLatch(2);\n\n        SchedulerTask task = new SchedulerTask() {\n\n            public void onSchedule(long timeStamp) {\n                barrier1.countDown();\n                barrier2.countDown();\n            }\n        };\n\n        final ScheduledTask scheduled = Scheduler.sharedInstance().schedule(task, Quantum.seconds(2), false);\n        stasks.add(scheduled);\n        try {\n            if (!barrier1.await(3, TimeUnit.SECONDS)) {\n                fail();\n            }\n            scheduled.suspend();\n            if (barrier2.await(3, TimeUnit.SECONDS)) {\n                fail();\n            }\n            scheduled.suspend();\n            if (barrier2.await(3, TimeUnit.SECONDS)) {\n                fail();\n            }\n        } catch (InterruptedException e) {\n            fail(e.getMessage());\n        }\n    }\n\n    @Test\n    public void suspendSuspendResume() {\n        System.out.println(\"suspend-suspend-resume\");\n        final CountDownLatch barrier1 = new CountDownLatch(1);\n        final CountDownLatch barrier2 = new CountDownLatch(2);\n\n        SchedulerTask task = new SchedulerTask() {\n\n            public void onSchedule(long timeStamp) {\n                barrier1.countDown();\n                barrier2.countDown();\n            }\n        };\n\n        final ScheduledTask scheduled = Scheduler.sharedInstance().schedule(task, Quantum.seconds(2), false);\n        stasks.add(scheduled);\n        try {\n            if (!barrier1.await(3, TimeUnit.SECONDS)) {\n                fail();\n            }\n            scheduled.suspend();\n            if (barrier2.await(3, TimeUnit.SECONDS)) {\n                fail();\n            }\n            scheduled.suspend();\n            if (barrier2.await(3, TimeUnit.SECONDS)) {\n                fail();\n            }\n            scheduled.resume();\n            if (!barrier2.await(3, TimeUnit.SECONDS)) {\n                fail();\n            }\n        } catch (InterruptedException e) {\n            fail(e.getMessage());\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/coredump/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.coredump\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.coredump.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/coredump/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.coredump/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/coredump/resources/layer.xml\nOpenIDE-Module-Install: org/graalvm/visualvm/coredump/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/coredump/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.1\n\n"
  },
  {
    "path": "visualvm/coredump/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.coredump-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/coredump/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=5b5e6a52\nbuild.xml.script.CRC32=5c1f58b0\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=5b5e6a52\nnbproject/build-impl.xml.script.CRC32=b16dc954\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/coredump/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/coredump/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.coredump</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.11.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.18.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.coredump</package>\n                <package>org.graalvm.visualvm.coredump.overview</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/coredump/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-CoreDump\n\nLBL_Save_Core_Dump_As=Save Core Dump As\n\nLBL_VM_Coredumps=VM Coredumps\n\nDESCR_CoreDump=Core dump.\n\nACT_SortCoreDumps=Sort &Core Dumps By\nACT_TimeAdded=&Time Added\nACT_DisplayName=&Display Name\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/CoreDump.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.coredump;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsSupport;\nimport java.io.File;\nimport java.io.IOException;\nimport org.openide.util.NbBundle;\nimport org.openide.util.Utilities;\n\n/**\n * Abstract implementation of CoreDump.\n * Each coredump is defined by a coredump file and JDK_HOME directory of the JDK\n * which was running the original application.\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic abstract class CoreDump extends Snapshot {\n    \n    private final File jdkHome;\n    \n    \n    /**\n     * Creates new instance of a coredump.\n     * \n     * @param file coredump file.\n     * @param jdkHome JDK_HOME directory of the JDK which was running the original application.\n     * @throws java.io.IOException if file or jdkHome are invalid.\n     */\n    public CoreDump(File file, File jdkHome) throws IOException {\n        this(file, jdkHome, null);\n    }\n    \n    /**\n     * Creates new instance of a coredump.\n     * \n     * @param file coredump file.\n     * @param jdkHome JDK_HOME directory of the JDK which was running the original application.\n     * @param master master DataSource for the coredump.\n     * @throws java.io.IOException if file or jdkHome are invalid.\n     */\n    public CoreDump(File file, File jdkHome, DataSource master) throws IOException {\n        super(file, CoreDumpSupport.getCategory(), master);\n        \n        if (!file.exists() || !file.isFile())\n            throw new IOException(\"File \" + file.getAbsolutePath() + \" does not exist\");    // NOI18N\n        \n        if (jdkHome != null) {\n            if (!jdkHome.exists() || !jdkHome.isDirectory())\n                throw new IOException(\"Java Home \" + jdkHome.getAbsolutePath() + \" does not exist\");    // NOI18N\n            this.jdkHome = jdkHome;\n        } else {\n            this.jdkHome = new File(System.getProperty(\"java.home\")).getCanonicalFile();    // NOI18N\n        }\n    }\n    \n    /**\n     * Returns the Java executable of the JDK which was running the original application.\n     * \n     * @return the Java executable of the JDK which was running the original application.\n     */\n    public final String getExecutable() {\n        String home = getJDKHome();\n        \n        String exec = home+File.separatorChar+\"bin\"+File.separatorChar+\"java\";  // NOI18N\n        if (Utilities.isWindows()) {\n            exec +=\".exe\";  // NOI18N\n        }\n        return exec;\n    }\n    \n    /**\n     * Returns JDK_HOME directory of the JDK which was running the original application.\n     * \n     * @return JDK_HOME directory of the JDK which was running the original application.\n     */\n    public final String getJDKHome() {\n        return jdkHome.getAbsolutePath();\n    }\n    \n    public boolean supportsSaveAs() {\n        return getFile() != null;\n    }\n    \n    public void saveAs() {\n        SnapshotsSupport.getInstance().saveAs(this, NbBundle.getMessage(CoreDump.class, \"LBL_Save_Core_Dump_As\"));  // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/CoreDumpDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.coredump;\n\nimport org.graalvm.visualvm.core.snapshot.SnapshotDescriptor;\nimport java.awt.Image;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * DataSourceDescriptor for CoreDump.\n *\n * @author Jiri Sedlacek\n */\npublic class CoreDumpDescriptor extends SnapshotDescriptor<CoreDump> {\n\n    private static final Image ICON = ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/coredump/resources/coredump.png\", true);  // NOI18N\n\n    /**\n     * Creates new instance of CoreDumpDescriptor.\n     * \n     * @param coreDump CoreDump for the descriptor.\n     */\n    public CoreDumpDescriptor(CoreDump coreDump) {\n        super(coreDump, resolveSnapshotName(coreDump), NbBundle.getMessage(\n              CoreDumpDescriptor.class, \"DESCR_CoreDump\"), ICON, // NOI18N\n              resolvePosition(coreDump, POSITION_AT_THE_END, true), EXPAND_NEVER);\n    }\n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/CoreDumpSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.coredump;\n\nimport org.graalvm.visualvm.coredump.impl.CoreDumpCategory;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.snapshot.RegisteredSnapshotCategories;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\nimport org.graalvm.visualvm.coredump.impl.CoreDumpDescriptorProvider;\nimport org.graalvm.visualvm.coredump.impl.CoreDumpOverviewViewProvider;\nimport org.graalvm.visualvm.coredump.impl.CoreDumpProvider;\nimport java.io.File;\n\n/**\n * Support for coredumps in VisualVM.\n *\n * @author Tomas Hurka\n */\npublic final class CoreDumpSupport {\n    \n    private static final String COREDUMPS_STORAGE_DIRNAME = \"coredumps\";    // NOI18N\n    \n    private static final Object coredumpsStorageDirectoryLock = new Object();\n    // @GuardedBy coredumpsStorageDirectoryLock\n    private static File coredumpsStorageDirectory;\n    private static final Object coredumpsStorageDirectoryStringLock = new Object();\n    // @GuardedBy coredumpsStorageDirectoryStringLock\n    private static String coredumpsStorageDirectoryString;\n    \n    private static CoreDumpOverviewViewProvider viewProvider = new CoreDumpOverviewViewProvider();\n    private static CoreDumpCategory category = new CoreDumpCategory();\n    private static final Object currentJDKHomeLock = new Object();\n    // @GuardedBy currentJDKHomeLock\n    private static String currentJDKHome;\n    \n    \n    /**\n     * Returns PluggableDataSourceViewProvider for Overview coredump subtab.\n     * \n     * @return PluggableDataSourceViewProvider for Overview coredump subtab.\n     */\n    public static PluggableDataSourceViewProvider<CoreDump> getOverviewView() {\n        return viewProvider;\n    } \n    \n    /**\n     * Returns SnapshotCategory instance for coredumps.\n     * \n     * @return SnapshotCategory instance for coredumps.\n     */\n    public static SnapshotCategory<CoreDump> getCategory() {\n        return category;\n    }\n    \n    // TODO: should be moved to some public Utils class\n    /**\n     * Returns JDK_HOME for JDK running the actual VisualVM instance.\n     * \n     * @return JDK_HOME for JDK running the actual VisualVM instance.\n     */\n    public static String getCurrentJDKHome() {\n        synchronized(currentJDKHomeLock) {\n            if (currentJDKHome == null) {\n                currentJDKHome = System.getProperty(\"java.home\");   // NOI18N\n                String jreSuffix = File.separator + \"jre\";  // NOI18N\n                if (currentJDKHome.endsWith(jreSuffix)) currentJDKHome = currentJDKHome.substring(0, currentJDKHome.length() - jreSuffix.length());\n            }\n            return currentJDKHome;\n        }\n    }\n    \n    static String getStorageDirectoryString() {\n        synchronized(coredumpsStorageDirectoryStringLock) {\n            if (coredumpsStorageDirectoryString == null)\n                coredumpsStorageDirectoryString = Storage.getPersistentStorageDirectoryString() + File.separator + COREDUMPS_STORAGE_DIRNAME;\n            return coredumpsStorageDirectoryString;\n        }\n    }\n    \n    /**\n     * Returns storage directory for coredumps.\n     * \n     * @return storage directory for coredumps.\n     */\n    public static File getStorageDirectory() {\n        synchronized(coredumpsStorageDirectoryLock) {\n            if (coredumpsStorageDirectory == null) {\n                String snapshotsStorageString = getStorageDirectoryString();\n                coredumpsStorageDirectory = new File(snapshotsStorageString);\n                if (coredumpsStorageDirectory.exists() && coredumpsStorageDirectory.isFile())\n                    throw new IllegalStateException(\"Cannot create coredumps storage directory \" + snapshotsStorageString + \", file in the way\");   // NOI18N\n                if (coredumpsStorageDirectory.exists() && (!coredumpsStorageDirectory.canRead() || !coredumpsStorageDirectory.canWrite()))\n                    throw new IllegalStateException(\"Cannot access coredumps storage directory \" + snapshotsStorageString + \", read&write permission required\");    // NOI18N\n                if (!Utils.prepareDirectory(coredumpsStorageDirectory))\n                    throw new IllegalStateException(\"Cannot create coredumps storage directory \" + snapshotsStorageString); // NOI18N\n            }\n            return coredumpsStorageDirectory;\n        }\n    }\n\n    /**\n     * Returns true if the storage directory for coredumps already exists, false otherwise.\n     * \n     * @return true if the storage directory for coredumps already exists, false otherwise.\n     */\n    public static boolean storageDirectoryExists() {\n        return new File(getStorageDirectoryString()).isDirectory();\n    }\n\n    \n    static void register() {\n        DataSourceDescriptorFactory.getDefault().registerProvider(new CoreDumpDescriptorProvider());\n        CoreDumpsContainer.sharedInstance();\n        CoreDumpProvider.register();\n        RegisteredSnapshotCategories.sharedInstance().registerCategory(category);\n        DataSourceViewsManager.sharedInstance().addViewProvider(viewProvider, CoreDump.class);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/CoreDumpsContainer.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.coredump;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\n/**\n * Toplevel node VM Coredumps in Applications window.\n *\n * @author Jiri Sedlacek\n */\npublic final class CoreDumpsContainer extends DataSource {\n    \n    private static CoreDumpsContainer sharedInstance;\n    \n    \n    /**\n     * Returns singleton instance of CoreDumpsContainer.\n     * \n     * @return singleton instance of CoreDumpsContainer.\n     */\n    public static synchronized CoreDumpsContainer sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new CoreDumpsContainer();\n        return sharedInstance;\n    }\n\n\n    private CoreDumpsContainer() {\n        DataSourceDescriptorFactory.getDefault().registerProvider(\n            new AbstractModelProvider<DataSourceDescriptor,DataSource>() {\n                public DataSourceDescriptor createModelFor(DataSource ds) {\n                    if (CoreDumpsContainer.sharedInstance().equals(ds))\n                        return new CoreDumpsContainerDescriptor();\n                    else return null;\n                }\n            }\n        );\n        DataSource.ROOT.getRepository().addDataSource(this);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/CoreDumpsContainerDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.coredump;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport java.awt.Image;\nimport java.util.Comparator;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * DataSourceDescriptor for VM Coredumps node in Applications window.\n *\n * @author Jiri Sedlacek\n */\npublic final class CoreDumpsContainerDescriptor extends DataSourceDescriptor<CoreDumpsContainer> {\n\n    private static final Image NODE_ICON = ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/coredump/resources/coredumps.png\", true);  // NOI18N\n\n    CoreDumpsContainerDescriptor() {\n        super(CoreDumpsContainer.sharedInstance(), NbBundle.getMessage(\n              CoreDumpsContainerDescriptor.class, \"LBL_VM_Coredumps\"), null, // NOI18N\n              NODE_ICON, 20, EXPAND_ON_EACH_NEW_CHILD);\n        \n        // Initialize sorting\n        setChildrenComparator(CoreDumpsSorting.instance().getInitialSorting());\n    }\n\n    /**\n     * Sets a custom comparator for sorting DataSources within the CoreDumpsContainer.\n     * Use setChildrenComparator(null) to restore the default sorting.\n     *\n     * @param newComparator comparator for sorting DataSources within the CoreDumpsContainer\n     */\n    public void setChildrenComparator(Comparator<DataSource> newComparator) {\n        super.setChildrenComparator(newComparator);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/CoreDumpsSorting.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.coredump;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport java.awt.Component;\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.prefs.Preferences;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JRadioButtonMenuItem;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.actions.Presenter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class CoreDumpsSorting implements Presenter.Menu {\n\n    private static final String PROP_HOSTS_SORTING = \"CoreDumps.sorting\"; // NOI18N\n\n    private static CoreDumpsSorting instance;\n    \n    private static final Comparator<DataSource> BY_TIME_COMPARATOR = byTimeComparator();\n    private static final Comparator<DataSource> BY_NAME_COMPARATOR = byNameComparator();\n    private static final List<Comparator<DataSource>> COMPARATORS = new ArrayList<>();\n    static { COMPARATORS.add(BY_TIME_COMPARATOR); COMPARATORS.add(BY_NAME_COMPARATOR); }\n\n    private final Preferences prefs;\n\n    private JMenuItem presenter;\n    private final Sorter sorter;\n\n\n    public static synchronized CoreDumpsSorting instance() {\n        if (instance == null) instance = new CoreDumpsSorting();\n        return instance;\n    }\n\n    public JMenuItem getMenuPresenter() {\n        if (presenter == null) presenter = createPresenter();\n        return presenter;\n    }\n\n\n    Comparator<DataSource> getInitialSorting() {\n        return COMPARATORS.get(prefs.getInt(PROP_HOSTS_SORTING, COMPARATORS.\n                                            indexOf(BY_TIME_COMPARATOR)));\n    }\n\n\n    private JMenuItem createPresenter() {\n        final JMenu menu = new JMenu() {\n            protected void fireMenuSelected() {\n                Component[] items = getMenuComponents();\n                for (Component item : items)\n                    if (item instanceof SortAction)\n                        ((SortAction)item).updateAction();\n            }\n        };\n        Mnemonics.setLocalizedText(menu, NbBundle.getMessage(CoreDumpsSorting.class,\n                                   \"ACT_SortCoreDumps\")); // NOI18N\n        \n        menu.add(new SortAction(NbBundle.getMessage(CoreDumpsSorting.class,\n                                \"ACT_TimeAdded\"), BY_TIME_COMPARATOR, sorter)); // NOI18N\n        menu.add(new SortAction(NbBundle.getMessage(CoreDumpsSorting.class,\n                                \"ACT_DisplayName\"), BY_NAME_COMPARATOR, sorter)); // NOI18N\n\n        return menu;\n    }\n    \n    private static Comparator<DataSource> byTimeComparator() {\n        return null;\n    }\n\n    private static Comparator<DataSource> byNameComparator() {\n        return new Comparator<DataSource>() {\n            public int compare(DataSource d1, DataSource d2) {\n                DataSourceDescriptor dd1 = DataSourceDescriptorFactory.getDescriptor(d1);\n                DataSourceDescriptor dd2 = DataSourceDescriptorFactory.getDescriptor(d2);\n\n                return dd1.getName().compareTo(dd2.getName());\n            }\n        };\n    }\n\n    private CoreDumpsSorting() {\n        prefs = NbPreferences.forModule(CoreDumpsSorting.class);\n\n        sorter = new Sorter() {\n            public void sort(Comparator<DataSource> comparator) {\n                DataSourceDescriptor d = DataSourceDescriptorFactory.getDescriptor(\n                                         CoreDumpsContainer.sharedInstance());\n                if (d instanceof CoreDumpsContainerDescriptor) {\n                    ((CoreDumpsContainerDescriptor)d).setChildrenComparator(comparator);\n                    prefs.putInt(PROP_HOSTS_SORTING, COMPARATORS.indexOf(comparator));\n                }\n            }\n        };\n    }\n\n\n    private static class SortAction extends JRadioButtonMenuItem {\n\n        private final Sorter sorter;\n        private final Comparator<DataSource> comparator;\n        private boolean currentlySelected;\n\n        SortAction(String name, Comparator<DataSource> comparator, Sorter sorter) {\n            Mnemonics.setLocalizedText(this, name);\n            this.comparator = comparator;\n            this.sorter = sorter;\n        }\n\n        void updateAction() {\n            DataSourceDescriptor d = DataSourceDescriptorFactory.getDescriptor(\n                                     CoreDumpsContainer.sharedInstance());\n            setEnabled(d instanceof CoreDumpsContainerDescriptor);\n            currentlySelected = d.getChildrenComparator() == comparator;\n            setSelected(currentlySelected);\n        }\n\n        protected void fireActionPerformed(ActionEvent e) {\n            if (!currentlySelected) sorter.sort(comparator);\n        }\n\n    }\n\n    private static interface Sorter {\n\n        void sort(Comparator<DataSource> comparator);\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.coredump;\n\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\nfinal class Installer extends ModuleInstall {\n    \n    public void restored() {\n        CoreDumpSupport.register();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/impl/AddVMCoredumpAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.coredump.impl;\n\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport org.graalvm.visualvm.coredump.CoreDumpsContainer;\nimport java.awt.Image;\nimport java.awt.event.ActionEvent;\nimport javax.swing.ImageIcon;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n    \n/**\n *\n * @author Jiri Sedlacek\n */\nclass AddVMCoredumpAction extends SingleDataSourceAction<CoreDumpsContainer> {\n    \n    private static final String ICON_PATH = \"org/graalvm/visualvm/coredump/resources/addCoredump.png\";    // NOI18N\n    private static final Image ICON =  ImageUtilities.loadImage(ICON_PATH);\n    \n    private boolean tracksSelection = false;\n    \n    private static AddVMCoredumpAction alwaysEnabled;\n    private static AddVMCoredumpAction selectionAware;\n    \n    \n    public static synchronized AddVMCoredumpAction alwaysEnabled() {\n        if (alwaysEnabled == null) {\n            alwaysEnabled = new AddVMCoredumpAction();\n            alwaysEnabled.putValue(SMALL_ICON, new ImageIcon(ICON));\n            alwaysEnabled.putValue(\"iconBase\", ICON_PATH);  // NOI18N\n        }\n        return alwaysEnabled;\n    }\n    \n    public static synchronized AddVMCoredumpAction selectionAware() {\n        if (selectionAware == null) {\n            selectionAware = new AddVMCoredumpAction();\n            selectionAware.tracksSelection = true;\n        }\n        return selectionAware;\n    }\n    \n    public void actionPerformed(CoreDumpsContainer container, ActionEvent e) {\n        CoreDumpConfigurator newCoreDumpConfiguration = CoreDumpConfigurator.defineCoreDump();\n        if (newCoreDumpConfiguration != null) {\n            CoreDumpProvider.createCoreDump(newCoreDumpConfiguration.getCoreDumpFile(),\n                    newCoreDumpConfiguration.getDisplayname(), newCoreDumpConfiguration.getJavaHome(),\n                    newCoreDumpConfiguration.deleteSourceFile());\n        }\n    }\n    \n    \n    protected boolean isEnabled(CoreDumpsContainer container) {\n        return true;\n    }\n    \n    protected void initialize() {\n        if (tracksSelection) super.initialize();\n    }\n    \n    \n    private AddVMCoredumpAction() {\n        super(CoreDumpsContainer.class);\n        putValue(NAME, NbBundle.getMessage(AddVMCoredumpAction.class, \"LBL_Add_VM_Coredump\"));  // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(AddVMCoredumpAction.class, \"ToolTip_Add_VM_Coredump\")); // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/impl/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nLBL_Add_VM_Coredump=Add VM C&oredump...\n\nToolTip_Add_VM_Coredump=Add VM Coredump\n\nLBL_Core_Dumps=Core Dumps\n\nTitle_Add_VM_Coredump=Add VM Coredump\n\nLBL_Select_JDK_Home=Select JDK Home\n\nLBL_Select_VM_Coredump=Select VM Coredump\n\nLBL_VM_Coredump_file=VM &Coredump file\\:\n\nLBL_Browse=&Browse...\n\nLBL_Browse1=B&rowse...\n\nLBL_JDK_home=&JDK home\\:\n\nLBL_Display_name=Display &name\\:\n\nLBL_Delete_source_file=&Delete source file\n\nLBL_OK=OK\n\nLBL_Overview=Overview\n\nLBL_Saved_data=Saved data\n\nLBL_Details=Details\n\nLBL_Main_class=Main class\n\nLBL_Arguments=Arguments\n\nLBL_none=&lt;none&gt;\n\nLBL_JVM=JVM\n\nLBL_Java_Home=Java Home\n\nLBL_Java=Java\n\nLBL_Java_Version=version\n\nLBL_Java_Vendor=vendor\n\nLBL_JVM_Flags=JVM Flags\n\nLBL_Inspecting_core_dump=Inspecting core dump\n\nMSG_not_valid_core_dump={0} is not a valid core dump!\n\nMSG_Core_dump_already_added=<html>Core dump {0} already added as {1}</html>\n\nMSG_Adding=Adding {0}...\n\nLBL_JVM_arguments=JVM arguments\n\nLBL_System_properties=System properties\n\nTitle_Unresolved_CoreDumps=Could Not Load Core Dump\n\nMSG_Unresolved_CoreDumps=<html><b>These core dumps could not be found:</b><br>Do you want to load them on next VisualVM session?<br><br></html>\n\nMSG_CoreDump_Failed=<b>Failed to read the VM coredump file.</b><br><br>Check the VisualVM logfile ({0}).\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/impl/CoreDumpCategory.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.coredump.impl;\n\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class CoreDumpCategory extends SnapshotCategory<CoreDump> {\n    \n    private static final String NAME = NbBundle.getMessage(CoreDumpCategory.class, \"LBL_Core_Dumps\");   // NOI18N\n    private static final String PREFIX = null;\n    private static final String SUFFIX = null;\n    \n    public CoreDumpCategory() {\n        super(NAME, CoreDump.class, PREFIX, SUFFIX, POSITION_NONE);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/impl/CoreDumpConfigurator.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.coredump.impl;\n\nimport org.graalvm.visualvm.coredump.CoreDumpSupport;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.File;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTextField;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n * \n */\nclass CoreDumpConfigurator extends JPanel {\n\n  private boolean internalChange = false;\n\n  public static CoreDumpConfigurator defineCoreDump() {\n    CoreDumpConfigurator hc = getDefault();\n    hc.setupDefineCoreDump();\n    \n    final DialogDescriptor dd = new DialogDescriptor(hc, NbBundle.getMessage(CoreDumpConfigurator.class, \"Title_Add_VM_Coredump\"), true, new Object[] { // NOI18N\n      hc.okButton, DialogDescriptor.CANCEL_OPTION }, hc.okButton, 0, null, null);\n    final Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n    d.pack();\n    d.setVisible(true);\n    \n    if (dd.getValue() == hc.okButton) return hc;\n    else return null;\n  }\n  \n  public String getCoreDumpFile() {\n    return coreDumpFileField.getText().trim();\n  }\n  \n  public String getDisplayname() {\n    return displaynameField.getText().trim();\n  }\n  \n  public String getJavaHome() {\n    return javaHomeFileField.getText().trim();\n  }\n  \n  public boolean deleteSourceFile() {\n      return deleteSourceCheckbox.isSelected();\n  }\n  \n  private static CoreDumpConfigurator defaultInstance;\n  \n  private CoreDumpConfigurator() {\n    initComponents();\n    update();\n  }\n  \n  private static CoreDumpConfigurator getDefault() {\n    if (defaultInstance == null) defaultInstance = new CoreDumpConfigurator();\n    return defaultInstance;\n  }\n  \n  private void setupDefineCoreDump() {\n    coreDumpFileField.setEnabled(true);\n    displaynameCheckbox.setSelected(false);\n    displaynameCheckbox.setEnabled(true);\n    coreDumpFileField.setText(\"\");\n    displaynameField.setText(\"\");\n    javaHomeFileField.setText(CoreDumpSupport.getCurrentJDKHome());\n    javaHomeFileField.setEnabled(true);\n    deleteSourceCheckbox.setSelected(false);\n  }\n  \n  private void update() {\n    if (internalChange) return;\n    SwingUtilities.invokeLater(new Runnable() {\n      public void run() {\n        String coreDumpname = getCoreDumpFile();\n        File coreDumpFile = new File(coreDumpname);\n        \n        String jdkHome = getJavaHome();\n        File jdkHomeFile = new File(jdkHome);\n        \n        if (!displaynameCheckbox.isSelected()) {\n          internalChange = true;\n          File file = new File(coreDumpname);\n          if (file.isFile()) displaynameField.setText(file.getName());\n          internalChange = false;\n        }\n        \n        String displayname = getDisplayname();\n        displaynameField.setEnabled(displaynameCheckbox.isSelected());\n        \n        okButton.setEnabled(coreDumpFile.exists() && coreDumpFile.isFile() &&\n                jdkHomeFile.exists() && jdkHomeFile.isDirectory() && !displayname.isEmpty());\n      }\n    });\n  }\n  \n  private void chooseJavaHome() {\n      JFileChooser chooser = new JFileChooser(new File(getJavaHome()));\n      chooser.setDialogTitle(NbBundle.getMessage(CoreDumpConfigurator.class, \"LBL_Select_JDK_Home\"));   // NOI18N\n      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\n      int returnVal = chooser.showOpenDialog(WindowManager.getDefault().getMainWindow());\n      if (returnVal == JFileChooser.APPROVE_OPTION) {\n          javaHomeFileField.setText(chooser.getSelectedFile().getAbsolutePath());\n      }\n  }\n\n  private void chooseCoreDump() {\n      JFileChooser chooser = new JFileChooser(new File(getCoreDumpFile()));\n      chooser.setDialogTitle(NbBundle.getMessage(CoreDumpConfigurator.class, \"LBL_Select_VM_Coredump\"));    // NOI18N\n      chooser.setAcceptAllFileFilterUsed(false);\n      chooser.setFileFilter(CoreDumpSupport.getCategory().getFileFilter());\n      int returnVal = chooser.showOpenDialog(WindowManager.getDefault().getMainWindow());\n      if (returnVal == JFileChooser.APPROVE_OPTION) {\n          coreDumpFileField.setText(chooser.getSelectedFile().getAbsolutePath());\n      }\n  }\n  \n  private void initComponents() {\n    setLayout(new GridBagLayout());\n    GridBagConstraints constraints;\n    \n    // coreDumpFileLabel\n    coreDumpFileLabel = new JLabel();\n    Mnemonics.setLocalizedText(coreDumpFileLabel, NbBundle.getMessage(CoreDumpConfigurator.class, \"LBL_VM_Coredump_file\")); // NOI18N\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 0;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.EAST;\n    constraints.insets = new Insets(15, 10, 0, 0);\n    add(coreDumpFileLabel, constraints);\n    \n    // coreDumpFileField\n    coreDumpFileField = new JTextField();\n    coreDumpFileLabel.setLabelFor(coreDumpFileField);\n    coreDumpFileField.setPreferredSize(new Dimension(220, coreDumpFileField.getPreferredSize().height));\n    coreDumpFileField.getDocument().addDocumentListener(new DocumentListener() {\n      public void insertUpdate(DocumentEvent e)  { update(); }\n      public void removeUpdate(DocumentEvent e)  { update(); }\n      public void changedUpdate(DocumentEvent e) { update(); }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 1;\n    constraints.gridy = 0;\n    constraints.weightx = 1;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.HORIZONTAL;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(15, 5, 0, 0);\n    add(coreDumpFileField, constraints);\n    \n    // coreDumpFileButton\n    coreDumpFileButton = new JButton();\n    Mnemonics.setLocalizedText(coreDumpFileButton, NbBundle.getMessage(CoreDumpConfigurator.class, \"LBL_Browse\")); // NOI18N\n    coreDumpFileButton.addActionListener(new ActionListener() {\n        public void actionPerformed(ActionEvent e) {\n            chooseCoreDump();\n        }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 2;\n    constraints.gridy = 0;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(15, 5, 0, 10);\n    add(coreDumpFileButton, constraints);    \n    \n    // javaHomeFileLabel\n    javaHomeFileLabel = new JLabel();\n    Mnemonics.setLocalizedText(javaHomeFileLabel, NbBundle.getMessage(CoreDumpConfigurator.class, \"LBL_JDK_home\")); // NOI18N\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 1;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.EAST;\n    constraints.insets = new Insets(8, 10, 0, 0);\n    add(javaHomeFileLabel, constraints);\n    \n    // javaHomeFileField\n    javaHomeFileField = new JTextField();\n    javaHomeFileLabel.setLabelFor(javaHomeFileField);\n    javaHomeFileField.setPreferredSize(new Dimension(220, javaHomeFileField.getPreferredSize().height));\n    javaHomeFileField.getDocument().addDocumentListener(new DocumentListener() {\n      public void insertUpdate(DocumentEvent e)  { update(); }\n      public void removeUpdate(DocumentEvent e)  { update(); }\n      public void changedUpdate(DocumentEvent e) { update(); }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 1;\n    constraints.gridy = 1;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.HORIZONTAL;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(8, 5, 0, 0);\n    add(javaHomeFileField, constraints);\n    \n    // javaHomeFileButton\n    javaHomeFileButton = new JButton();\n    Mnemonics.setLocalizedText(javaHomeFileButton, NbBundle.getMessage(CoreDumpConfigurator.class, \"LBL_Browse1\")); // NOI18N\n    javaHomeFileButton.addActionListener(new ActionListener() {\n        public void actionPerformed(ActionEvent e) {\n            chooseJavaHome();\n        }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 2;\n    constraints.gridy = 1;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(8, 5, 0, 10);\n    add(javaHomeFileButton, constraints);        \n    \n    // displaynameCheckbox\n    displaynameCheckbox = new JCheckBox();\n    Mnemonics.setLocalizedText(displaynameCheckbox, NbBundle.getMessage(CoreDumpConfigurator.class, \"LBL_Display_name\")); // NOI18N\n    displaynameCheckbox.addActionListener(new ActionListener() {\n      public void actionPerformed(ActionEvent e) { update(); }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 2;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(8, 10, 0, 0);\n    add(displaynameCheckbox, constraints);\n    \n    // displaynameField\n    displaynameField = new JTextField();\n    displaynameField.setPreferredSize(new Dimension(220, displaynameField.getPreferredSize().height));\n    displaynameField.getDocument().addDocumentListener(new DocumentListener() {\n      public void insertUpdate(DocumentEvent e)  { update(); }\n      public void removeUpdate(DocumentEvent e)  { update(); }\n      public void changedUpdate(DocumentEvent e) { update(); }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 1;\n    constraints.gridy = 2;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.HORIZONTAL;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(8, 5, 0, 10);\n    add(displaynameField, constraints);\n    \n    // deleteSourceCheckbox\n    deleteSourceCheckbox = new JCheckBox();\n    Mnemonics.setLocalizedText(deleteSourceCheckbox, NbBundle.getMessage(CoreDumpConfigurator.class, \"LBL_Delete_source_file\")); // NOI18N\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 3;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(18, 10, 0, 0);\n    add(deleteSourceCheckbox, constraints);\n    \n    // spacer\n    JPanel spacer = new JPanel(null);\n    spacer.setOpaque(false);\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 4;\n    constraints.weighty = 1;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.BOTH;\n    constraints.anchor = GridBagConstraints.NORTHWEST;\n    constraints.insets = new Insets(0, 0, 15, 0);\n    add(spacer, constraints);\n    \n    // okButton\n    okButton = new JButton(NbBundle.getMessage(CoreDumpConfigurator.class, \"LBL_OK\"));  // NOI18N\n    \n    // UI tweaks\n    displaynameCheckbox.setBorder(coreDumpFileLabel.getBorder());\n    deleteSourceCheckbox.setBorder(coreDumpFileLabel.getBorder());\n  }\n  \n  private JLabel coreDumpFileLabel;\n  private JTextField coreDumpFileField;\n  private JButton coreDumpFileButton;\n  private JLabel javaHomeFileLabel;\n  private JTextField javaHomeFileField;\n  private JButton javaHomeFileButton;\n  private JCheckBox displaynameCheckbox;\n  private JTextField displaynameField;\n  private JCheckBox deleteSourceCheckbox;\n  \n  private JButton okButton;\n  \n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/impl/CoreDumpDescriptorProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.coredump.impl;\n\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.coredump.CoreDumpDescriptor;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class CoreDumpDescriptorProvider extends AbstractModelProvider<DataSourceDescriptor,DataSource> {\n    \n    public DataSourceDescriptor createModelFor(DataSource ds) {\n        if (ds instanceof CoreDump) {\n            return new CoreDumpDescriptor((CoreDump) ds);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/impl/CoreDumpImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.coredump.impl;\n\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.coredump.CoreDumpSupport;\nimport java.io.File;\nimport java.io.IOException;\n\n/**\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\nclass CoreDumpImpl extends CoreDump {\n    \n    private Storage storage;\n    \n    \n    CoreDumpImpl(File file, File javaHomeName, Storage storage) throws IOException {\n        super(file, javaHomeName);\n        this.storage = storage;\n    }\n    \n    public boolean supportsDelete() {\n        return false;\n    }\n    \n    \n    protected Storage createStorage() {\n        return storage;\n    }\n\n    public boolean supportsUserRemove() {\n        return true;\n    }\n    \n    \n    protected void remove() {\n        File file = getFile();\n        if (CoreDumpSupport.getStorageDirectory().equals(file.getParentFile())) Utils.delete(file, true);\n        setFile(null);\n        getStorage().deleteCustomPropertiesStorage();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/impl/CoreDumpOverviewView.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.coredump.impl;\n\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.tools.sa.SaModel;\nimport org.graalvm.visualvm.tools.sa.SaModelFactory;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport java.awt.BorderLayout;\nimport java.util.Properties;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass CoreDumpOverviewView extends DataSourceView {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/coredump/resources/overview.png\";  // NOI18N\n    \n    \n    CoreDumpOverviewView(CoreDump coreDump) {\n        super(coreDump, NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_Overview\"), new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 0, false);    // NOI18N\n    }\n    \n    protected DataViewComponent createComponent() {\n        CoreDump coreDump = (CoreDump)getDataSource();\n        SaModel saAgent = SaModelFactory.getSAAgentFor(coreDump);\n        \n        DataViewComponent dvc = new DataViewComponent(\n                new MasterViewSupport(saAgent).getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(false));\n        \n        if (saAgent != null) {\n            Properties jvmProperties = saAgent.getSystemProperties();\n            String jvmargs = saAgent.getJvmArgs();\n\n            dvc.configureDetailsView(new DataViewComponent.DetailsViewConfiguration(0.25, 0, -1, -1, -1, -1));\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_Saved_data\"), true), DataViewComponent.TOP_LEFT);  // NOI18N\n            dvc.addDetailsView(new OverviewViewSupport.SnapshotsViewSupport(coreDump).getDetailsView(), DataViewComponent.TOP_LEFT);\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_Details\"), true), DataViewComponent.TOP_RIGHT);    // NOI18N \n            dvc.addDetailsView(new OverviewViewSupport.JVMArgumentsViewSupport(jvmargs).getDetailsView(), DataViewComponent.TOP_RIGHT);\n            dvc.addDetailsView(new OverviewViewSupport.SystemPropertiesViewSupport(jvmProperties).getDetailsView(), DataViewComponent.TOP_RIGHT);\n        }\n        \n        return dvc;\n    }\n    \n    \n    // --- General data --------------------------------------------------------\n    \n    private static class MasterViewSupport extends JPanel  {\n        \n        MasterViewSupport(SaModel saAgent) {\n            initComponents(saAgent);\n        }\n        \n        \n        public DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_Overview\"), null, this);   // NOI18N\n        }\n        \n        \n        private void initComponents(SaModel saAgent) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            HTMLTextArea area = new HTMLTextArea(\"<nobr>\" + getGeneralProperties(saAgent) + \"</nobr>\");    // NOI18N\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n            \n            // TODO: implement listener for CoreDump.oomeHeapDumpEnabled\n            \n            add(area, BorderLayout.CENTER);\n        }\n        \n        private String getGeneralProperties(SaModel saAgent) {\n            StringBuilder data = new StringBuilder();\n            \n            if (saAgent != null) {\n                // CoreDump information\n                String commandLine = saAgent.getJavaCommand();\n\n                if (commandLine != null) {\n                    // Application information\n                    int firstSpace = commandLine.indexOf(' ');\n                    String mainClass;\n                    String mainArgs = null;\n                    if (firstSpace == -1) {\n                        mainClass = commandLine;\n                    } else {\n                        mainClass = commandLine.substring(0,firstSpace);\n                        mainArgs = commandLine.substring(firstSpace+1);\n                    }\n                    String mainClassLbl = NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_Main_class\");    // NOI18N\n                    String argsLbl = NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_Arguments\");  // NOI18N\n                    data.append(\"<b>\"+mainClassLbl+\":</b> \" + mainClass + \"<br>\");  // NOI18N\n                    data.append(\"<b>\"+argsLbl+\":</b> \" + (mainArgs == null ? NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_none\") : mainArgs) + \"<br>\"); // NOI18N\n                }\n\n                // JVM information\n                String jvmFlags = saAgent.getJvmFlags();\n                String jvmLbl = NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_JVM\"); // NOI18N\n                String jLbl = NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_Java\"); // NOI18N\n                String verLbl = NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_Java_Version\"); // NOI18N\n                String vendorLbl = NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_Java_Vendor\"); // NOI18N\n                String jhLbl = NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_Java_Home\");    // NOI18N\n                String flagsLbl = NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_JVM_Flags\"); // NOI18N\n                data.append(\"<br>\");    // NOI18N\n                data.append(\"<b>\"+jvmLbl+\":</b> \" + saAgent.getVmName() + \" (\" + saAgent.getVmVersion() + \", \" + saAgent.getVmInfo() + \")<br>\");    // NOI18N\n                Properties props = saAgent.getSystemProperties();\n                if (props != null) {\n                    String javaVersion = props.getProperty(\"java.version\"); // NOI18N\n                    String javaVendor = props.getProperty(\"java.vendor\"); // NOI18N\n                    if (javaVersion != null || javaVendor != null) {\n                        data.append(\"<b>\"+jLbl+\":</b>\");\n                        if (javaVersion != null) {\n                            data.append(\" \"+verLbl+\" \" + javaVersion);   // NOI18N\n                        }\n                        if (javaVendor != null) {\n                            if (javaVersion != null) data.append(\",\");\n                            data.append(\" \"+vendorLbl+\" \" + javaVendor);   // NOI18N\n                        }\n                        data.append(\"<br>\");\n                    }\n                }\n                data.append(\"<b>\"+jhLbl+\":</b> \" + saAgent.getJavaHome() + \"<br>\"); // NOI18N\n                data.append(\"<b>\"+flagsLbl+\":</b> \" + (jvmFlags == null || jvmFlags.isEmpty() ? NbBundle.getMessage(CoreDumpOverviewView.class, \"LBL_none\") : jvmFlags) + \"<br><br>\");  // NOI18N\n            } else {\n                data.append(NbBundle.getMessage(CoreDumpOverviewView.class, \"MSG_CoreDump_Failed\", VisualVM.getInstance().getLogfileHandle())); // NOI18N\n            }\n            \n            return data.toString();\n            \n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/impl/CoreDumpOverviewViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.coredump.impl;\n\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\nimport java.util.Set;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class CoreDumpOverviewViewProvider extends PluggableDataSourceViewProvider<CoreDump>{\n    \n    protected boolean supportsViewFor(CoreDump coreDump) {\n        return true;\n    }\n\n    protected DataSourceView createView(CoreDump coreDump) {\n        return new CoreDumpOverviewView(coreDump);\n    }\n    \n    public Set<Integer> getPluggableLocations(DataSourceView view) {\n        return ALL_LOCATIONS;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/impl/CoreDumpProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.coredump.impl;\n\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.explorer.ExplorerSupport;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.coredump.CoreDumpSupport;\nimport org.graalvm.visualvm.coredump.CoreDumpsContainer;\nimport org.graalvm.visualvm.tools.sa.SaModel;\nimport org.graalvm.visualvm.tools.sa.SaModelFactory;\nimport java.awt.BorderLayout;\nimport java.io.File;\nimport java.io.FilenameFilter;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.graalvm.visualvm.lib.ui.SwingWorker;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic class CoreDumpProvider {\n    private static final Logger LOGGER = Logger.getLogger(CoreDumpProvider.class.getName());\n    \n    private static final String SNAPSHOT_VERSION = \"snapshot_version\";  // NOI18N\n    private static final String SNAPSHOT_VERSION_DIVIDER = \".\"; // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = \"1\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MINOR = \"0\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION = CURRENT_SNAPSHOT_VERSION_MAJOR + SNAPSHOT_VERSION_DIVIDER + CURRENT_SNAPSHOT_VERSION_MINOR;\n    \n    private static final String PROPERTY_JAVA_HOME = \"prop_java_home\";  // NOI18N\n    \n    private static class CoreDumpAdder extends SwingWorker {\n        volatile private ProgressHandle ph = null;\n        volatile private boolean success = false;\n        private CoreDumpImpl newCoreDump;\n        private Storage storage;\n        private String[] propNames, propValues;\n        \n        CoreDumpAdder(CoreDumpImpl newCoreDump, Storage storage, String[] propNames, String[] propValues) {\n            this.newCoreDump = newCoreDump;\n            this.storage = storage;\n            this.propValues = propValues;\n            this.propNames = propNames;\n        }\n        \n        @Override\n        protected void doInBackground() {\n            SaModel model = SaModelFactory.getSAAgentFor(newCoreDump);\n            if (model != null) {\n                storage.setCustomProperties(propNames, propValues);\n                CoreDumpsContainer.sharedInstance().getRepository().addDataSource(newCoreDump);\n\n                success = true;\n            }\n        }\n\n        @Override\n        protected void nonResponding() {\n            ph = ProgressHandle.createHandle(NbBundle.getMessage(CoreDumpProvider.class, \"LBL_Inspecting_core_dump\"));   // NOI18N\n            ph.start();\n        }\n\n        @Override\n        protected void done() {\n            if (ph != null) {\n                ph.finish();\n            }\n            if (!success) {\n                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(NbBundle.getMessage(CoreDumpProvider.class, \"MSG_not_valid_core_dump\", newCoreDump.getFile().getAbsolutePath())));  // NOI18N\n            }\n        }\n    }\n    \n    static void createCoreDump(final String coreDumpFile, final String displayName, final String jdkHome, final boolean deleteCoreDump) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                createCoreDumpImpl(coreDumpFile, displayName, jdkHome, deleteCoreDump);\n            }\n        });\n    }\n    \n    private static void createCoreDumpImpl(String coreDumpFile, final String displayName, String jdkHome, boolean deleteCoreDump) {\n        \n        // TODO: check if the same coredump isn't already imported (can happen for moved coredumps)\n        \n        final CoreDumpImpl knownCoreDump = getCoreDumpByFile(new File(coreDumpFile));\n        if (knownCoreDump != null) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    ExplorerSupport.sharedInstance().selectDataSource(knownCoreDump);\n                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.\n                            Message(NbBundle.getMessage(CoreDumpProvider.class,\n                            \"MSG_Core_dump_already_added\", new Object[] {displayName, // NOI18N\n                            DataSourceDescriptorFactory.getDescriptor(knownCoreDump).\n                            getName()}), NotifyDescriptor.ERROR_MESSAGE));\n                }\n            });\n            return;\n        }\n        \n        if (deleteCoreDump) {\n            ProgressHandle pHandle = null;\n            try {\n                pHandle = ProgressHandle.createHandle(NbBundle.getMessage(CoreDumpProvider.class, \"MSG_Adding\", displayName));   // NOI18N\n                pHandle.setInitialDelay(0);\n                pHandle.start();\n                \n                File file = new File(coreDumpFile);\n                File copy = Utils.getUniqueFile(CoreDumpSupport.getStorageDirectory(), file.getName());\n                if (Utils.copyFile(file, copy)) {\n                    coreDumpFile = copy.getAbsolutePath();\n                    if (!file.delete()) file.deleteOnExit();\n                }\n            } finally {\n                final ProgressHandle pHandleF = pHandle;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { if (pHandleF != null) pHandleF.finish(); }\n                });\n            }\n        }\n        \n        final String[] propNames = new String[] {\n            SNAPSHOT_VERSION,\n            Snapshot.PROPERTY_FILE,\n            DataSourceDescriptor.PROPERTY_NAME,\n            PROPERTY_JAVA_HOME };\n        final String[] propValues = new String[] {\n            CURRENT_SNAPSHOT_VERSION,\n            coreDumpFile,\n            displayName,\n            jdkHome\n        };\n\n        File customPropertiesStorage = Utils.getUniqueFile(CoreDumpSupport.getStorageDirectory(), new File(coreDumpFile).getName(), Storage.DEFAULT_PROPERTIES_EXT);\n        Storage storage = new Storage(customPropertiesStorage.getParentFile(), customPropertiesStorage.getName());\n        \n        try {\n            CoreDumpImpl newCoreDump = new CoreDumpImpl(new File(coreDumpFile), new File(jdkHome), storage);\n            if (newCoreDump != null) {\n                new CoreDumpAdder(newCoreDump, storage, propNames, propValues).execute();\n            }\n        } catch (Exception e) {\n            LOGGER.log(Level.SEVERE, \"Error creating coredump\", e); // NOI18N\n            return;\n        }\n    }\n    \n    private static CoreDumpImpl getCoreDumpByFile(File file) {\n        if (!file.isFile()) return null;\n        Set<CoreDumpImpl> knownCoredumps = DataSourceRepository.sharedInstance().getDataSources(CoreDumpImpl.class);\n        for (CoreDumpImpl knownCoredump : knownCoredumps)\n            if (knownCoredump.getFile().equals(file)) return knownCoredump;\n        return null;\n    }\n    \n    private void initPersistedCoreDumps() {\n        if (!CoreDumpSupport.storageDirectoryExists()) return;\n        \n        File[] files = CoreDumpSupport.getStorageDirectory().listFiles(new FilenameFilter() {\n            public boolean accept(File dir, String name) {\n                return name.endsWith(Storage.DEFAULT_PROPERTIES_EXT);\n            }\n        });\n        \n        Set<File> unresolvedCoreDumpsF = new HashSet<>();\n        Set<String> unresolvedCoreDumpsS = new HashSet<>();\n        Set<CoreDumpImpl> coredumps = new HashSet<>();\n        for (File file : files) {\n            Storage storage = new Storage(file.getParentFile(), file.getName());\n            String[] propNames = new String[] {\n                Snapshot.PROPERTY_FILE,\n                PROPERTY_JAVA_HOME\n            };\n            String[] propValues = storage.getCustomProperties(propNames);\n            if (propValues[0] == null || propValues[1] == null) continue;\n                \n            CoreDumpImpl persistedCoredump = null;\n            try {\n                persistedCoredump = new CoreDumpImpl(new File(propValues[0]), new File(propValues[1]), storage);\n            } catch (Exception e) {\n                LOGGER.log(Level.INFO, \"Error loading persisted coredump\", e);    // NOI18N\n                unresolvedCoreDumpsF.add(file);\n                unresolvedCoreDumpsS.add(propValues[0]);\n            }\n            \n            if (persistedCoredump != null) coredumps.add(persistedCoredump);\n        }\n        \n        if (!unresolvedCoreDumpsF.isEmpty()) notifyUnresolvedCoreDumps(unresolvedCoreDumpsF, unresolvedCoreDumpsS);\n        \n        if (!coredumps.isEmpty())\n            CoreDumpsContainer.sharedInstance().getRepository().addDataSources(coredumps);\n    }\n\n    private static void notifyUnresolvedCoreDumps(final Set<File> unresolvedCoreDumpsF, final Set<String> unresolvedCoreDumpsS) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                JPanel messagePanel = new JPanel(new BorderLayout(5, 5));\n                messagePanel.add(new JLabel(NbBundle.getMessage(CoreDumpProvider.class, \"MSG_Unresolved_CoreDumps\")), BorderLayout.NORTH); // NOI18N\n                JList<Object> list = new JList<>(unresolvedCoreDumpsS.toArray());\n                list.setVisibleRowCount(4);\n                messagePanel.add(new JScrollPane(list), BorderLayout.CENTER);\n                NotifyDescriptor dd = new NotifyDescriptor(\n                        messagePanel, NbBundle.getMessage(CoreDumpProvider.class, \"Title_Unresolved_CoreDumps\"), // NOI18N\n                        NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.ERROR_MESSAGE,\n                        null, NotifyDescriptor.YES_OPTION);\n                if (DialogDisplayer.getDefault().notify(dd) == NotifyDescriptor.NO_OPTION)\n                    for (File file : unresolvedCoreDumpsF) Utils.delete(file, true);\n\n                unresolvedCoreDumpsF.clear();\n                unresolvedCoreDumpsS.clear();\n            }\n        }, 1000);\n    }\n\n    \n    CoreDumpProvider() {\n    }\n    \n    public static void register() {\n        final CoreDumpProvider provider = new CoreDumpProvider();\n        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n            public void run() {\n                VisualVM.getInstance().runTask(provider::initPersistedCoreDumps);\n            }\n        });\n    }\n  \n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/impl/OverviewViewSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.coredump.impl;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.core.snapshot.RegisteredSnapshotCategories;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.NotSupportedDisplayer;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport java.awt.BorderLayout;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.Set;\nimport java.util.StringTokenizer;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport org.openide.util.NbBundle;\n\n/**\n * A public entrypoint to the Overview subtab.\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic final class OverviewViewSupport {\n\n // --- Snapshots -----------------------------------------------------------\n    \n    static class SnapshotsViewSupport extends JPanel  {\n        \n        private static final String LINK_TOGGLE_CATEGORY = \"file:/toggle_category\"; // NOI18N\n        private static final String LINK_OPEN_SNAPSHOT = \"file:/open_snapshot\"; // NOI18N\n        \n        private final Map<Integer, Snapshot> snapshotsMap = new HashMap<>();\n        private final Map<String, Boolean> expansionMap = new HashMap<>();\n        \n        SnapshotsViewSupport(DataSource ds) {\n            initComponents(ds);\n        }        \n        \n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(OverviewViewSupport.class, \"LBL_Saved_data\"), null, 10, this, null);   // NOI18N\n        }\n        \n        private void initComponents(final DataSource ds) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            final HTMLTextArea area = new HTMLTextArea() {\n                protected void showURL(URL url) {\n                    String link = url.toString();\n                    if (link.startsWith(LINK_TOGGLE_CATEGORY)) {\n                        link = link.substring(LINK_TOGGLE_CATEGORY.length());\n                        toggleExpanded(link); \n                        setText(getSavedData(ds));\n                    } else if (link.startsWith(LINK_OPEN_SNAPSHOT)) {\n                        link = link.substring(LINK_OPEN_SNAPSHOT.length());\n                        Snapshot s = snapshotsMap.get(Integer.parseInt(link));\n                        if (s != null) DataSourceWindowManager.sharedInstance().openDataSource(s);\n                    }\n                }\n            };\n            area.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n            \n            ds.getRepository().addDataChangeListener(new DataChangeListener<Snapshot>() {\n                public void dataChanged(DataChangeEvent<Snapshot> event) {\n                    area.setText(getSavedData(ds));\n                }                \n            }, Snapshot.class);\n            \n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n        }\n        \n        private String getSavedData(DataSource dataSource) {\n            snapshotsMap.clear();\n            StringBuilder data = new StringBuilder();\n            \n            List<SnapshotCategory<? extends Snapshot>> snapshotCategories = RegisteredSnapshotCategories.sharedInstance().getVisibleCategories();\n            for (SnapshotCategory<? extends Snapshot> category : snapshotCategories) {\n                Set<? extends Snapshot> snapshots = dataSource.getRepository().getDataSources(category.getType());\n                if (snapshots.isEmpty()) {\n                    data.append(\"<b>\" + category.getName() + \":</b> \" + snapshots.size() + \"<br>\"); // NOI18N\n                } else {\n                    String categoryName = category.getName();\n                    data.append(\"<b>\" + categoryName + \":</b> <a href='\" + (LINK_TOGGLE_CATEGORY + categoryName) + \"'>\" + snapshots.size() + \"</a><br>\"); // NOI18N\n                    \n                    if (isExpanded(categoryName)) {\n                        List<DataSourceDescriptor<? extends Snapshot>> descriptors = new ArrayList<>();\n                        Map<DataSourceDescriptor<? extends Snapshot>, Snapshot> dataSources = new HashMap<>();\n\n                        for (Snapshot s : snapshots) {\n                            DataSourceDescriptor<? extends Snapshot> dsd = DataSourceDescriptorFactory.getDescriptor(s);\n                            descriptors.add(dsd);\n                            dataSources.put(dsd, s);\n                        }\n                        descriptors.sort(Positionable.STRONG_COMPARATOR);\n\n                        int size = snapshotsMap.size();\n                        for (int i = 0; i < descriptors.size(); i++) {\n                            DataSourceDescriptor<? extends Snapshot> dsd = descriptors.get(i);\n                            Snapshot s = dataSources.get(dsd);\n                            snapshotsMap.put(i + size, s);\n                            data.append(\"&nbsp;&nbsp;&nbsp;<a href='\" + LINK_OPEN_SNAPSHOT + (i + size) + \"'>\" + dsd.getName() + \"</a><br>\"); // NOI18N\n                        }\n                        data.append(\"<br>\"); // NOI18N\n                    }\n                }\n            }            \n            \n            return \"<nobr>\" + data.toString() + \"</nobr>\";   // NOI18N\n        }\n        \n        private boolean isExpanded(String categoryName) {\n            Boolean expanded = expansionMap.computeIfAbsent(categoryName, k -> false);\n            return expanded.booleanValue();\n        }\n        \n        private void toggleExpanded(String categoryName) {\n            expansionMap.put(categoryName, !isExpanded(categoryName));\n        }\n        \n    }\n    \n    \n    // --- JVM arguments -------------------------------------------------------\n    \n    static class JVMArgumentsViewSupport extends JPanel  {\n        \n        JVMArgumentsViewSupport(String jvmargs) {\n            initComponents(jvmargs);\n        }        \n        \n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(OverviewViewSupport.class, \"LBL_JVM_arguments\"), null, 10, this, null);    // NOI18N\n        }\n        \n        private void initComponents(String jvmargs) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            JComponent contents;\n            \n            if (jvmargs != null) {\n                HTMLTextArea area = new HTMLTextArea(\"<nobr>\" + formatJVMArgs(jvmargs) + \"</nobr>\");    // NOI18N\n                area.setCaretPosition(0);\n                area.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n                contents = area;\n            } else {\n                contents = new NotSupportedDisplayer(NotSupportedDisplayer.JVM);\n            }\n            \n            add(new ScrollableContainer(contents), BorderLayout.CENTER);\n        }\n        \n        private String formatJVMArgs(String jvmargs) {\n            String mangledString = \" \".concat(jvmargs).replace(\" -\",\"\\n\");  // NOI18N\n            StringTokenizer tok = new StringTokenizer(mangledString,\"\\n\");  // NOI18N\n            StringBuilder text = new StringBuilder(100);\n\n            while(tok.hasMoreTokens()) {\n                String arg = tok.nextToken().replace(\" \",\"&nbsp;\"); // NOI18N\n                int equalsSign = arg.indexOf('=');\n\n                text.append(\"<b>\"); // NOI18N\n                text.append(\"-\");   // NOI18N\n                if (equalsSign != -1) {\n                text.append(arg, 0, equalsSign);\n                text.append(\"</b>\");    // NOI18N\n                text.append(arg.substring(equalsSign));\n                } else {\n                text.append(arg);\n                text.append(\"</b>\");    // NOI18N\n                }\n                text.append(\"<br>\");    // NOI18N\n            }\n            return text.toString();\n        }\n        \n    }\n    \n    \n    // --- System properties ---------------------------------------------------\n    \n    static class SystemPropertiesViewSupport extends JPanel  {\n        \n        SystemPropertiesViewSupport(Properties properties) {\n            initComponents(properties);\n        }        \n        \n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(OverviewViewSupport.class, \"LBL_System_properties\"), null, 20, this, null);    // NOI18N\n        }\n        \n        private void initComponents(Properties properties) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            JComponent contents;\n            \n            if (properties != null) {\n                HTMLTextArea area = new HTMLTextArea(\"<nobr>\" + formatSystemProperties(properties) + \"</nobr>\");    // NOI18N\n                area.setCaretPosition(0);\n                area.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n                contents = area;\n            } else {\n                contents = new NotSupportedDisplayer(NotSupportedDisplayer.JVM);\n            }\n            \n            add(new ScrollableContainer(contents), BorderLayout.CENTER);\n        }\n        \n        private String formatSystemProperties(Properties properties) {\n            StringBuilder text = new StringBuilder(200);\n            List<Object> keys = new ArrayList<>();\n            Enumeration<?> en = properties.propertyNames();\n            Iterator<Object> keyIt;\n\n            while (en.hasMoreElements()) {\n                keys.add(en.nextElement());\n            }\n\n            keys.sort(null);\n            keyIt = keys.iterator();\n            while (keyIt.hasNext()) {\n                String key = (String) keyIt.next();\n                String val = properties.getProperty(key);\n\n                if (\"line.separator\".equals(key) && val != null) {  // NOI18N\n                    val = val.replace(\"\\n\", \"\\\\n\"); // NOI18N\n                    val = val.replace(\"\\r\", \"\\\\r\"); // NOI18N\n                }\n\n                text.append(\"<b>\"); // NOI18N\n                text.append(key);\n                text.append(\"</b>=\");   // NOI18N\n                text.append(val);\n                text.append(\"<br>\");    // NOI18N\n            }\n            return text.toString();\n        }\n        \n    }\n}\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Support for core dumps in VisualVM.\n */\npackage org.graalvm.visualvm.coredump;\n"
  },
  {
    "path": "visualvm/coredump/src/org/graalvm/visualvm/coredump/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    \n    <folder name=\"Actions\">\n        <folder name=\"Other\">\n            <file name=\"org-graalvm-visualvm-coredump-impl-AddVMCoredumpAction-alwaysEnabled.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.coredump.impl.AddVMCoredumpAction.alwaysEnabled\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"Menu\">\n        <folder name=\"File\">\n            <file name=\"org-graalvm-visualvm-coredump-impl-AddVMCoredumpAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-coredump-impl-AddVMCoredumpAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"700\"/>\n            </file>\n        </folder>\n        <folder name=\"View\">\n            <file name=\"org-graalvm-visualvm-coredump-CoreDumpsSorting.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.coredump.CoreDumpsSorting.instance\"/>\n                <attr name=\"position\" intvalue=\"900\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"Toolbars\">\n        <folder name=\"DataSource\">\n            <file name=\"org-graalvm-visualvm-coredump-impl-AddVMCoredumpAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-coredump-impl-AddVMCoredumpAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"300\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"VisualVM\">\n        <folder name=\"ExplorerPopupSelection\">\n            \n            <file name=\"org-graalvm-visualvm-coredump-impl-AddVMCoredumpAction-selectionAware.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.coredump.impl.AddVMCoredumpAction.selectionAware\"/>\n                <attr name=\"position\" intvalue=\"0\"/>\n                <attr name=\"default\" boolvalue=\"true\"/>\n            </file>\n            \n        </folder>\n        \n        <folder name=\"ExplorerPopupNoSelection\">\n            \n            <file name=\"org-graalvm-visualvm-coredump-impl-AddVMCoredumpAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-coredump-impl-AddVMCoredumpAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"300\"/>\n            </file>\n            \n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "visualvm/gotosource/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.gotosource\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.gotosource.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/gotosource/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: false\nOpenIDE-Module: org.graalvm.visualvm.gotosource/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/gotosource/resources/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "visualvm/gotosource/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.core-impl\" basedir=\"..\" xmlns:nbmproject=\"http://www.netbeans.org/ns/nb-module-project/2\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\"/>\n    <nbmproject:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/gotosource/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=35be65f3\nbuild.xml.script.CRC32=ed1a64ac\nbuild.xml.stylesheet.CRC32=05353c81\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=35be65f3\nnbproject/build-impl.xml.script.CRC32=4fae7134\nnbproject/build-impl.xml.stylesheet.CRC32=3f8b4615\n"
  },
  {
    "path": "visualvm/gotosource/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\njavac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/gotosource/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.gotosource</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.2</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.options.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.sendopts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.10</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.11</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.14</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.gotosource</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/gotosource/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/SourceHandle.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource;\n\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"SourceHandle_Language=Source Language\",                                    // NOI18N\n    \"SourceHandle_ClassName=Class Name\",                                        // NOI18N\n    \"SourceHandle_MethodName=Method Name\",                                      // NOI18N\n    \"SourceHandle_MethodSignature=Method Signature\",                            // NOI18N\n    \"SourceHandle_SourceLine=Source Line\",                                      // NOI18N\n    \"SourceHandle_SourceColumn=Source Column\",                                  // NOI18N\n    \"SourceHandle_SourceOffset=Source Offset\",                                  // NOI18N\n    \"SourceHandle_SourceText=Source Text\",                                      // NOI18N\n    \"SourceHandle_SourceUri=Source URI\",                                        // NOI18N\n    \"SourceHandle_SourceFile=Source File\"                                       \n})\npublic abstract class SourceHandle {\n    \n    public static final SourceHandle EMPTY = new Empty();\n    \n    \n    public static enum Feature {\n        \n        LANGUAGE(\"{lang}\", Bundle.SourceHandle_Language()) {},                  // NOI18N\n\n        CLASS(\"{class}\", Bundle.SourceHandle_ClassName()) {},                   // NOI18N\n        METHOD(\"{method}\", Bundle.SourceHandle_MethodName()) {},                // NOI18N\n        SIGNATURE(\"{sig}\", Bundle.SourceHandle_MethodSignature()) {},           // NOI18N\n\n        LINE(\"{line}\", Bundle.SourceHandle_SourceLine()) {},                    // NOI18N\n        COLUMN(\"{column}\", Bundle.SourceHandle_SourceColumn()) {},              // NOI18N\n        OFFSET(\"{offset}\", Bundle.SourceHandle_SourceOffset()) {},              // NOI18N\n\n        TEXT(\"{text}\", Bundle.SourceHandle_SourceText()) {},                    // NOI18N\n\n        URI(\"{uri}\", Bundle.SourceHandle_SourceUri()) {},                       // NOI18N\n        FILE(\"{file}\", Bundle.SourceHandle_SourceFile()) {};                    // NOI18N\n        \n        \n        private final String code;\n        private final String name;\n        \n        Feature(String code, String name) {\n            this.code = code;\n            this.name = name;\n        }\n        \n        public String getCode() { return code; }\n        public String getName() { return name; }\n        \n        @Override public String toString() { return getName(); }\n        \n    }\n\n\n    public abstract String getLanguage();\n    \n    \n    public abstract String getClassName();\n    \n    public abstract String getMethodName();\n    \n    public abstract String getMethodSignature();\n    \n    \n    public abstract int getLine();\n    \n    public abstract int getColumn();\n    \n    public abstract int getOffset();\n    \n    public          int getEndOffset() { return getOffset(); }\n    \n    \n    public abstract String getText();\n    \n    \n    public abstract String getSourceUri();\n    \n    public abstract String getSourceFile();\n    \n    \n    public final String expandFeatures(String command) {\n        String lang = Feature.LANGUAGE.getCode();\n        int index = command.indexOf(lang);\n        if (index > -1) command = command.replace(lang, getLanguage());\n        \n        String code = Feature.CLASS.getCode();\n        index = command.indexOf(code);\n        if (index > -1) command = command.replace(code, getClassName());\n        \n        code = Feature.METHOD.getCode();\n        index = command.indexOf(code);\n        if (index > -1) command = command.replace(code, getMethodName());\n        \n        code = Feature.SIGNATURE.getCode();\n        index = command.indexOf(code);\n        if (index > -1) command = command.replace(code, getMethodSignature());\n        \n        \n        code = Feature.LINE.getCode();\n        index = command.indexOf(code);\n        if (index > -1) command = command.replace(code, Integer.toString(getLine()));\n        \n        code = Feature.COLUMN.getCode();\n        index = command.indexOf(code);\n        if (index > -1) command = command.replace(code, Integer.toString(getColumn()));\n        \n        code = Feature.OFFSET.getCode();\n        index = command.indexOf(code);\n        if (index > -1) command = command.replace(code, Integer.toString(getOffset()));\n        \n        \n        code = Feature.TEXT.getCode();\n        index = command.indexOf(code);\n        if (index > -1) command = command.replace(code, getText());\n        \n        \n        code = Feature.URI.getCode();\n        index = command.indexOf(code);\n        if (index > -1) command = command.replace(code, getSourceUri());\n        \n        code = Feature.FILE.getCode();\n        index = command.indexOf(code);\n        if (index > -1) command = command.replace(code, getSourceFile());\n        \n        \n        return command;\n    }\n\n\n    protected abstract void close();\n    \n    \n    private static final String FILE_PREFIX = \"file:///\";                       // NOI18N\n    \n    public static String simpleUri(String uri) {\n        int fileIndex = uri.indexOf(FILE_PREFIX);\n        return fileIndex == -1 ? uri : uri.substring(fileIndex + FILE_PREFIX.length());\n    }\n    \n    \n    private static final class Empty extends SourceHandle {\n\n        @Override public String getLanguage() { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public String getClassName() { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public String getMethodName() { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public String getMethodSignature() { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public int getLine() { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public int getColumn() { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public int getOffset() { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public String getText() { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public String getSourceUri() { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public String getSourceFile() { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override protected void close() { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/SourceHandleProvider.java",
    "content": "/*\n * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class SourceHandleProvider {\n    \n    public abstract SourceHandle createHandle(String className, String methodName, String signature, int line);\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/SourceHandleUtils.java",
    "content": "/*\n * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class SourceHandleUtils {\n    \n    private static final char CH_CR     = '\\r';                                 // NOI18N\n    private static final char CH_LF     = '\\n';                                 // NOI18N\n    \n    private static final String CR      = new String(new char[] { CH_CR });\n    private static final String LF      = new String(new char[] { CH_LF });\n    private static final String CRLF    = new String(new char[] { CH_CR, CH_LF });\n    \n    \n    private SourceHandleUtils() {}\n    \n    \n    public static int lineToOffset(String text, int line) {\n        int offset = 0;\n            \n        if (line > 1) {\n            String breakString = CRLF;\n            int breakIndex = text.indexOf(breakString);\n            \n            if (breakIndex == -1) {\n                breakString = LF;\n                breakIndex = text.indexOf(breakString);\n                \n                if (breakIndex == -1) {\n                    breakString = CR;\n                    breakIndex = text.indexOf(breakString);\n                }\n            }\n            \n            int _line = 1;\n            while (breakIndex > -1 && _line < line) {\n                offset = breakIndex + breakString.length();\n                breakIndex = text.indexOf(breakString, offset);\n                _line++;\n            }\n        }\n        \n        return offset;\n    }\n    \n    public static int[] offsetToLineColumn(String text, int offset) {\n        int line = 1;\n        int column = 1;\n        \n        boolean crlf = text.contains(CRLF);\n        boolean newlinePending = false;\n        \n        offset = Math.min(offset, text.length());\n        \n        for (int pos = 0; pos < offset; pos++) {\n            if (newlinePending) {\n                line++;\n                column = 1;\n                newlinePending = false;\n            }\n            \n            char ch = text.charAt(pos);\n            \n            switch (ch) {\n                case CH_CR:\n                    if (crlf) pos++;\n                    newlinePending = true;\n                    break;\n                case CH_LF:\n                    newlinePending = true;\n                    break;\n                default:\n                    column++;\n                    break;\n            }\n        }\n        \n        return new int[] { line, column };\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/SourcePathHandle.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource;\n\nimport java.io.IOException;\nimport java.nio.charset.Charset;\nimport java.nio.file.Files;\nimport java.nio.file.LinkOption;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.nio.file.StandardCopyOption;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.core.datasource.Storage;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class SourcePathHandle {\n        \n    private static final String EXTRACTED_DIR = \"extracted_sources\";            // NOI18N\n    \n    private static final Logger LOGGER = Logger.getLogger(SourcePathHandle.class.getName());\n\n\n    private final Path path;\n    private final boolean archive;\n    private final Charset encoding;\n\n    private Path regularPath;\n\n\n    SourcePathHandle(Path path, boolean archive, Charset encoding) {\n        this.path = path;\n        this.archive = archive;\n        this.encoding = encoding;\n    }\n\n\n    public Path getPath() {\n        return path;\n    }\n\n    public Path getRegularPath() {\n        if (archive) {\n            if (regularPath == null) try {\n                regularPath = extractArchivePath(path);\n            } catch (Exception e) {\n                LOGGER.log(Level.INFO, \"Failed extracting archived path \" + path, e); // NOI18N\n                regularPath = path;\n            }\n            return regularPath;\n        } else {\n            return path;\n        }\n    }\n\n    public String readText() {\n        try {\n            return new String(Files.readAllBytes(path), encoding);\n        } catch (IOException ex) {\n            LOGGER.log(Level.INFO, \"Failed resolving source text \" + path.toAbsolutePath().toString(), ex); // NOI18N\n            return null;\n        }\n    }\n\n    public void close() {            \n        if (archive) try {\n            path.getFileSystem().close();\n        } catch (IOException e) {\n            LOGGER.log(Level.INFO, \"Failed closing filesystem for \" + path, e); // NOI18N\n        }\n    }\n\n\n    private static Path extractArchivePath(Path archive) throws Exception {\n        Path extracted = Paths.get(Storage.getTemporaryStorageDirectoryString(), EXTRACTED_DIR, archive.toString());\n        Files.createDirectories(extracted.getParent());\n        Files.copy(archive, extracted, LinkOption.NOFOLLOW_LINKS, StandardCopyOption.REPLACE_EXISTING);\n        return extracted;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/SourcesRoot.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource;\n\nimport java.io.File;\nimport java.nio.charset.Charset;\nimport java.nio.charset.StandardCharsets;\nimport org.graalvm.visualvm.gotosource.impl.SourceRoots;\nimport java.nio.file.FileSystem;\nimport java.nio.file.FileSystems;\nimport java.nio.file.Files;\nimport java.nio.file.LinkOption;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.stream.Collectors;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class SourcesRoot {\n    \n    // Special mask for selecting possibly modularized (e.g. JDK) sources using a single source root\n    public static final String MODULES_SUBPATH  = \"*modules*\";                  // NOI18N\n    \n    private static final String SUBPATHS_PREFIX = \"[subpaths=\";                  // NOI18N\n    private static final String SUBPATHS_SUFFIX = \"]\";                           // NOI18N\n    \n    private static final String ENCODING_PREFIX = \"[encoding=\";                  // NOI18N\n    private static final String ENCODING_SUFFIX = \"]\";                           // NOI18N\n    \n    \n    private static final Logger LOGGER = Logger.getLogger(SourcesRoot.class.getName());\n    \n    \n    private final String rootPath;\n    private final String[] subPaths;\n    private final Charset encoding;\n    \n    \n    private SourcesRoot(String rootPath) {\n        Object[] resolved = resolve(rootPath);\n        this.rootPath = (String)resolved[0];\n        this.subPaths = (String[])resolved[1];\n        this.encoding = (Charset)resolved[2];\n    }\n    \n    \n    private SourcePathHandle getSourceHandle(String resourcePath) {\n        Path root = Paths.get(rootPath);\n        \n        try {\n            if (Files.isDirectory(root)) return getHandleInDirectory(root, resourcePath, subPaths, encoding);\n            else if (Files.isRegularFile(root)) return getHandleInArchive(root, resourcePath, subPaths, encoding);\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Failed resolving source file \" + resourcePath + \" in \" + root, t); // NOI18N\n        }\n        \n        return null;\n    }\n    \n    private static SourcePathHandle getHandleInDirectory(Path directory, String sourcePath, String[] subPaths, Charset encoding) throws Throwable {\n        if (subPaths == null) {\n            Path sourceFile = directory.resolve(sourcePath);\n            return isFile(sourceFile) ? new SourcePathHandle(sourceFile, false, encoding) : null;\n        } else {\n            if (subPaths.length == 1 && MODULES_SUBPATH.equals(subPaths[0])) {              \n                List<Path> subfolders = Files.walk(directory, 1).filter(Files::isDirectory).collect(Collectors.toList());\n                for (Path subfolder : subfolders) {\n                    Path sourceFile = subfolder.resolve(sourcePath);\n                    if (isFile(sourceFile)) return new SourcePathHandle(sourceFile, false, encoding);\n                }\n            } else for (String subPath : subPaths) {\n                Path sourceFile = directory.resolve(subPath + \"/\" + sourcePath); // NOI18N\n                if (isFile(sourceFile)) return new SourcePathHandle(sourceFile, false, encoding);\n            }\n            return null;\n        }\n    }\n    \n    private static SourcePathHandle getHandleInArchive(Path archive, String sourcePath, String[] subPaths, Charset encoding) throws Throwable {\n        try (FileSystem archiveFileSystem = FileSystems.newFileSystem(archive, (ClassLoader)null)) {\n            if (subPaths == null) {\n                Path sourceFile = archiveFileSystem.getPath(sourcePath);\n                return isFile(sourceFile) ? new SourcePathHandle(sourceFile, true, encoding) : null;\n            } else {\n                if (subPaths.length == 1 && MODULES_SUBPATH.equals(subPaths[0])) {\n                    Path path = archiveFileSystem.getRootDirectories().iterator().next();\n                    List<Path> subfolders = Files.walk(path, 1).filter(Files::isDirectory).collect(Collectors.toList());\n                    for (Path subfolder : subfolders) {\n                        Path sourceFile = subfolder.resolve(sourcePath);\n                        if (isFile(sourceFile)) return new SourcePathHandle(sourceFile, true, encoding);\n                    }\n                } else for (String subPath : subPaths) {\n                    Path sourceFile = archiveFileSystem.getPath(subPath, sourcePath);\n                    if (isFile(sourceFile)) return new SourcePathHandle(sourceFile, true, encoding);\n                }\n                return null;\n            }\n        }\n    }\n    \n    \n    public boolean equals(Object o) { return o instanceof SourcesRoot && rootPath.equals(((SourcesRoot) o).rootPath); }\n    \n    public int hashCode() { return rootPath.hashCode(); }\n    \n    public String toString() { return rootPath; }\n    \n    \n    public static SourcePathHandle getPathHandle(String resourcePath) {\n        for (String rootPath : SourceRoots.getRoots()) {\n            SourcesRoot root = new SourcesRoot(rootPath);\n            SourcePathHandle handle = root.getSourceHandle(resourcePath);\n            if (handle != null) return handle;\n        }\n        \n        return null;\n    }\n    \n    \n    public static String createString(String rootPath, String[] subPaths, String encoding) {\n        if ((subPaths == null || subPaths.length == 0) && encoding == null) return rootPath;\n        \n        StringBuilder sb = new StringBuilder();\n        \n        if (subPaths != null && subPaths.length > 0) {\n            normalizeSubpaths(subPaths);\n            \n            for (String subPath : subPaths) {\n                if (sb.length() > 0) sb.append(\":\");                            // NOI18N\n                sb.append(subPath);\n            }\n            \n            sb.insert(0, SUBPATHS_PREFIX);\n            sb.append(SUBPATHS_SUFFIX);\n        }\n        \n        if (StandardCharsets.UTF_8.name().equals(encoding)) encoding = null;\n        if (encoding != null) sb.append(ENCODING_PREFIX).append(encoding).append(ENCODING_SUFFIX);\n        \n        sb.insert(0, rootPath);\n        \n        return sb.toString();\n    }\n    \n    \n    private static boolean isFile(Path path) {\n        return Files.isRegularFile(path, LinkOption.NOFOLLOW_LINKS);\n    }\n    \n    \n    private static Object[] resolve(String root) {\n        int idx = root.indexOf('[');                                            // NOI18N\n        String[] subpaths = null;\n        Charset encoding = StandardCharsets.UTF_8;\n        \n        if (idx != -1) {\n            String params = root.substring(idx);\n            root = root.substring(0, idx);\n            \n            String[] paramsArr = params.split(\"\\\\]\\\\[\");                        // NOI18N\n            for (String paramS : paramsArr) {\n                if (!paramS.startsWith(\"[\")) paramS = \"[\" + paramS;             // NOI18N\n                paramS = paramS.replace(\"]\", \"\");                               // NOI18N\n                \n                if (paramS.startsWith(SUBPATHS_PREFIX)) {\n                    paramS = paramS.substring(SUBPATHS_PREFIX.length());\n                    subpaths = subpaths(paramS);\n                } else if (paramS.startsWith(ENCODING_PREFIX)) {\n                    paramS = paramS.substring(ENCODING_PREFIX.length());\n                    encoding = charset(paramS);\n                }\n            }\n        }\n        \n        return new Object[] { root, subpaths, encoding };\n    }\n    \n    private static String[] subpaths(String subpaths) {\n        if (subpaths.isEmpty()) return null;\n        \n        String[] paths = subpaths.split(\":\");                                   // NOI18N\n        normalizeSubpaths(paths);\n        \n        return paths;\n    }\n    \n    private static void normalizeSubpaths(String[] subpaths) {\n        for (int i = 0; i < subpaths.length; i++) {\n            String path = subpaths[i];\n            \n            if (!\"/\".equals(File.separator)) path = path.replace(File.separator, \"/\"); // NOI18N\n            if (path.startsWith(\"/\")) path = path.substring(1);                 // NOI18N\n            if (path.endsWith(\"/\")) path = path.substring(0, path.length() - 1); // NOI18N\n            \n            subpaths[i] = path;\n        }\n    }\n    \n    private static Charset charset(String charset) {\n        try { return Charset.forName(charset); }\n        catch (Exception e) { return StandardCharsets.UTF_8; }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/SourcesViewer.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource;\n\nimport javax.swing.JComponent;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class SourcesViewer {\n    \n    private final String id;\n    private final String name;\n    private final String description;\n    \n    \n    protected SourcesViewer(String id, String name, String description) {\n        this.id = id;\n        this.name = name;\n        this.description = description;\n    }\n    \n    \n    public abstract boolean open(SourceHandle handle);\n    \n    \n    public final String getID() { return id; }\n    \n    public final String getName() { return name; }\n    \n    public final String getDescription() { return description; }\n\n\n    public void loadSettings() {}\n    \n    public void saveSettings() {}\n    \n    public boolean settingsDirty() { return false; }\n    \n    public JComponent getSettingsComponent() { return null; }\n    \n    \n    public final boolean equals(Object o) { return o instanceof SourcesViewer && id.equals(((SourcesViewer) o).id); }\n    \n    public final int hashCode() { return id.hashCode(); }\n    \n    public final String toString() { return name; }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/VisualVMGoToSource.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource;\n\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.spi.java.GoToSourceProvider;\nimport org.graalvm.visualvm.gotosource.impl.SourceHandles;\nimport org.graalvm.visualvm.gotosource.impl.SourceRoots;\nimport org.graalvm.visualvm.gotosource.impl.SourceViewers;\nimport org.netbeans.api.options.OptionsDisplayer;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"VisualVMGoToSource_NoSourceRootsCaption=Go To Source\",                     // NOI18N\n    \"VisualVMGoToSource_NoSourceRoots=<html><br><b>Source roots have not been defined yet.</b><br><br>Use Options | Sources | Definitions to define the directories or archives containing the sources.</html>\", // NOI18N\n    \"# {0} - class name\",\n    \"VisualVMGoToSource_ClassSourceNotFound=No source found for {0}\",           // NOI18N\n    \"# {0} - class name\",\n    \"# {1} - method name\",\n    \"VisualVMGoToSource_MethodSourceNotFound=No source found for {0}.{1}\",      // NOI18N\n    \"# {0} - file name\",\n    \"VisualVMGoToSource_OpenSourceFailed=Failed to open source for {0}\"         // NOI18N\n})\nfinal class VisualVMGoToSource {\n    \n    private static final Logger LOGGER = Logger.getLogger(VisualVMGoToSource.class.getName());\n    \n\n    private static boolean openSourceImpl(SourceHandle handle) {\n        try {\n            if (!SourceViewers.getSelectedViewer().open(handle))\n                ProfilerDialogs.displayError(Bundle.VisualVMGoToSource_OpenSourceFailed(SourceHandle.simpleUri(handle.getSourceUri())));\n            return true;\n        } catch (Throwable t) {\n            ProfilerDialogs.displayError(Bundle.VisualVMGoToSource_OpenSourceFailed(SourceHandle.simpleUri(handle.getSourceUri())));\n            LOGGER.log(Level.INFO, \"Failed to open source \" + handle.toString(), t); // NOI18N\n            return false;\n        } finally {\n            try { handle.close(); }\n            catch (Throwable t) { LOGGER.log(Level.INFO, \"Failed to close source \" + handle.toString(), t); } // NOI18N\n        }\n    }\n    \n    \n    @ServiceProvider(service=GoToSourceProvider.class)\n    public static final class Provider extends GoToSourceProvider {\n        \n        @Override\n        public boolean openSource(Lookup.Provider project, String className, String methodName, String signature, int line) {\n            if (SourceRoots.getRoots().length == 0) {\n                ProfilerDialogs.displayWarning(Bundle.VisualVMGoToSource_NoSourceRoots(), Bundle.VisualVMGoToSource_NoSourceRootsCaption(), null);\n                OptionsDisplayer.getDefault().open(\"SourcesOptions\");           // NOI18N\n            } else {\n                for (SourceHandleProvider provider : SourceHandles.registeredProviders()) {\n                    SourceHandle handle = provider.createHandle(className, methodName, signature, line);\n                    if (handle != null) return handle == SourceHandle.EMPTY || openSourceImpl(handle);\n                }\n\n                if (methodName == null || methodName.isEmpty() || \"*\".equals(methodName)) { // NOI18N\n                    ProfilerDialogs.displayError(Bundle.VisualVMGoToSource_ClassSourceNotFound(className));\n                } else {\n                    ProfilerDialogs.displayError(Bundle.VisualVMGoToSource_MethodSourceNotFound(className, methodName));\n                }\n            }\n            \n            return true;\n        }\n\n        @Override\n        public boolean openFile(FileObject srcFile, int offset) {\n            throw new UnsupportedOperationException(\"GoToSource: openFile not supported in VisualVM\"); // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/arguments/Bundle.properties",
    "content": "#\n# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nArgument_SourceViewer_ShortDescr=set the source viewer command to be executed by Go To Source\nArgument_SourceRoots_ShortDescr=set the source roots to be searched by Go To Source\nArgument_SourceConfig_ShortDescr=set the path to sources configuration file containing source roots and viewer definition\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/arguments/SourceArguments.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.arguments;\n\nimport java.util.Collections;\nimport java.util.Map;\nimport java.util.Set;\nimport org.netbeans.api.sendopts.CommandException;\nimport org.netbeans.spi.sendopts.Env;\nimport org.netbeans.spi.sendopts.Option;\nimport org.netbeans.spi.sendopts.OptionGroups;\nimport org.netbeans.spi.sendopts.OptionProcessor;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=OptionProcessor.class)\npublic final class SourceArguments extends OptionProcessor {\n    \n    @Override\n    protected Set<Option> getOptions() {\n        return Collections.singleton(OptionGroups.anyOf(SourceRootsArgument.ARGUMENT, SourceViewerArgument.ARGUMENT, SourceConfigArgument.ARGUMENT));\n    }\n    \n    @Override\n    protected void process(Env env, Map<Option, String[]> maps) throws CommandException {\n        String[] sourceRoots = maps.get(SourceRootsArgument.ARGUMENT);\n        String[] sourceViewer = maps.get(SourceViewerArgument.ARGUMENT);\n        String[] sourceConfig = maps.get(SourceConfigArgument.ARGUMENT);\n        \n        if (sourceConfig != null) SourceConfigArgument.process(sourceConfig, sourceRoots, sourceViewer);\n        if (sourceRoots != null) SourceRootsArgument.process(sourceRoots);\n        if (sourceViewer != null) SourceViewerArgument.process(sourceViewer);\n    }\n    \n    \n    static String decode(String value) {\n        value = value.replace(\"%27\", \"'\");                                     // NOI18N\n        value = value.replace(\"%22\", \"\\\"\");                                     // NOI18N\n        value = value.replace(\"%20\", \" \");                                      // NOI18N\n        return value;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/arguments/SourceConfigArgument.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.arguments;\n\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Properties;\nimport org.netbeans.api.sendopts.CommandException;\nimport org.netbeans.spi.sendopts.Option;\n\n/**\n * Implementation of the --source-config argument\n *\n * @author Jiri Sedlacek\n */\nclass SourceConfigArgument {\n    \n    static final String LONG_NAME = \"source-config\";                            // NOI18N\n    \n    static final Option ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, LONG_NAME), \"org.graalvm.visualvm.gotosource.arguments.Bundle\", \"Argument_SourceConfig_ShortDescr\"); // NOI18N\n    \n    \n    static void process(String[] values, String[] rootsValues, String[] viewerValues) throws CommandException {\n        if (rootsValues != null || viewerValues != null)\n            throw new CommandException(0, \"--\" + LONG_NAME +                    // NOI18N\n                    \" not allowed with --\" + SourceRootsArgument.LONG_NAME +    // NOI18N\n                    \" or --\" + SourceViewerArgument.LONG_NAME);                 // NOI18N\n        \n        if (values.length == 1) setValue(values[0]);\n        else throw new CommandException(0, \"--\" + LONG_NAME + \" requires exactly one value\"); // NOI18N\n    }\n    \n    \n    private static void setValue(String value) throws CommandException {\n        if (value != null) value = value.trim();\n        if (value == null || value.isEmpty()) {\n            SourceRootsArgument.setValue(null);\n            SourceViewerArgument.setValue(null);\n        } else {\n            value = SourceArguments.decode(value);\n            try (InputStreamReader isr = new InputStreamReader(new FileInputStream(value), StandardCharsets.UTF_8)) {\n                Properties props = new Properties();\n                props.load(isr);\n\n                String sourceRoots = props.getProperty(SourceRootsArgument.LONG_NAME);\n                if (sourceRoots != null) SourceRootsArgument.setValue(sourceRoots);\n\n                String sourceViewer = props.getProperty(SourceViewerArgument.LONG_NAME);\n                if (sourceViewer != null) SourceViewerArgument.setValue(sourceViewer);\n            } catch (IOException e) {\n                throw new CommandException(0, \"--\" + LONG_NAME + \" failed to read config \" + value + \": \" + e.getMessage()); // NOI18N\n            }\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/arguments/SourceRootsArgument.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.arguments;\n\nimport org.graalvm.visualvm.gotosource.impl.SourceRoots;\nimport org.netbeans.api.sendopts.CommandException;\nimport org.netbeans.spi.sendopts.Option;\n\n/**\n * Implementation of the --source-roots argument\n *\n * @author Jiri Sedlacek\n */\nfinal class SourceRootsArgument {\n    \n    static final String LONG_NAME = \"source-roots\";                             // NOI18N\n    \n    static final Option ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, LONG_NAME), \"org.graalvm.visualvm.gotosource.arguments.Bundle\", \"Argument_SourceRoots_ShortDescr\"); // NOI18N\n    \n\n    static void process(String[] values) throws CommandException {\n        if (values.length == 1) setValue(values[0]);\n        else throw new CommandException(0, \"--\" + LONG_NAME + \" requires exactly one value\"); // NOI18N\n    }\n    \n    \n    static void setValue(String value) {\n        if (value != null) value = value.trim();\n        if (value == null || value.isEmpty()) SourceRoots.forceRoots(null);\n        else SourceRoots.forceRoots(SourceRoots.splitRoots(SourceArguments.decode(value)));\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/arguments/SourceViewerArgument.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.arguments;\n\nimport org.graalvm.visualvm.gotosource.impl.SourceViewers;\nimport org.netbeans.api.sendopts.CommandException;\nimport org.netbeans.spi.sendopts.Option;\n\n/**\n * Implementation of the --external-viewer argument\n *\n * @author Jiri Sedlacek\n */\nfinal class SourceViewerArgument {\n    \n    static final String LONG_NAME = \"source-viewer\";                            // NOI18N\n    \n    static final Option ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, LONG_NAME), \"org.graalvm.visualvm.gotosource.arguments.Bundle\", \"Argument_SourceViewer_ShortDescr\"); // NOI18N\n    \n    \n    static void process(String[] values) throws CommandException {\n        if (values.length == 1) setValue(values[0]);\n        else throw new CommandException(0, \"--\" + LONG_NAME + \" requires exactly one value\"); // NOI18N\n    }\n    \n    \n    static void setValue(String value) {\n        if (value != null) value = value.trim();\n        if (value == null || value.isEmpty()) SourceViewers.forceExternalViewer(null);\n        else SourceViewers.forceExternalViewer(SourceArguments.decode(value));\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/impl/SourceHandles.java",
    "content": "/*\n * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.impl;\n\nimport java.util.Collection;\nimport org.graalvm.visualvm.gotosource.SourceHandleProvider;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class SourceHandles {\n    \n    private SourceHandles() {}\n    \n    \n    public static Collection<? extends SourceHandleProvider> registeredProviders() {\n        return Lookup.getDefault().lookupAll(SourceHandleProvider.class);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/impl/SourceRoots.java",
    "content": "/*\n * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.impl;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.regex.Pattern;\nimport org.graalvm.visualvm.gotosource.SourcesRoot;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class SourceRoots {\n    \n    private static final String PROP_SAVED_ROOTS = \"prop_SourceRoots_saved\";    // NOI18N\n    \n    private static final String ROOTS_DELIMITER = \"|\";                          // NOI18N\n    \n    \n    private static String[] FORCED_ROOTS;\n    \n    \n    private SourceRoots() {}\n    \n    \n    public static String[] getRoots() {\n        if (areForcedRoots()) return FORCED_ROOTS;\n        \n        String definedString = NbPreferences.forModule(SourcesRoot.class).get(PROP_SAVED_ROOTS, \"\"); // NOI18N\n        return definedString.isEmpty() ? new String[0] : definedString.split(Pattern.quote(ROOTS_DELIMITER));\n    }\n    \n    public static void saveRoots(String[] roots) {\n        if (areForcedRoots()) return;\n        \n        String joinedString = String.join(ROOTS_DELIMITER, roots);\n        NbPreferences.forModule(SourceRoots.class).put(PROP_SAVED_ROOTS, joinedString);\n    }\n    \n    \n    public static void forceRoots(String[] roots) {\n        FORCED_ROOTS = roots == null || roots.length == 0 ? null : roots;\n    }\n    \n    public static boolean areForcedRoots() {\n        return FORCED_ROOTS != null;\n    }\n    \n    \n    public static String[] splitRoots(String rootsString) {\n        List<String> roots = new ArrayList<>();\n        \n        int position = 0;\n        int length = rootsString.length();\n        \n        boolean inBlock = false;\n        StringBuilder sb = new StringBuilder();\n\n        while (position < length) {\n            char currentChar = rootsString.charAt(position);\n            \n            if (currentChar == '[') {                                           // NOI18N\n                inBlock = true;\n            } else if (currentChar == ']') {                                    // NOI18N\n                inBlock = false;\n            }\n            \n            if (!inBlock && currentChar == File.pathSeparatorChar) {\n                roots.add(sb.toString());\n                sb.setLength(0);\n            } else {\n                sb.append(currentChar);\n                if (position == length - 1) roots.add(sb.toString());\n            }\n            \n            position++;\n        }\n        \n        return roots.toArray(new String[0]);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/impl/SourceViewers.java",
    "content": "/*\n * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.impl;\n\nimport java.util.Collection;\nimport java.util.Collections;\nimport org.graalvm.visualvm.gotosource.viewer.ExternalSourcesViewer;\nimport org.graalvm.visualvm.gotosource.SourcesViewer;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class SourceViewers {\n    \n    private static final String PROP_SELECTED_VIEWER = \"prop_SourceViewers_selected\"; // NOI18N\n    \n    private static final String DEFAULT_VIEWER_ID = ExternalSourcesViewer.ID;\n    \n    \n    private static SourcesViewer FORCED_VIEWER;\n    \n    \n    private SourceViewers() {}\n    \n    \n    public static Collection<? extends SourcesViewer> getRegisteredViewers() {\n        if (isForcedViewer()) return Collections.singletonList(FORCED_VIEWER);\n        \n        return Lookup.getDefault().lookupAll(SourcesViewer.class);\n    }\n    \n    public static SourcesViewer getSelectedViewer() {\n        if (isForcedViewer()) return FORCED_VIEWER;\n        \n        String selectedID = NbPreferences.forModule(SourcesViewer.class).get(PROP_SELECTED_VIEWER, DEFAULT_VIEWER_ID);\n        \n        if (selectedID != null)\n            for (SourcesViewer registered : getRegisteredViewers())\n                if (selectedID.equals(registered.getID()))\n                    return registered;\n        \n        return null;\n    }\n    \n    public static void saveSelectedViewer(SourcesViewer selected) {\n        if (isForcedViewer()) return;\n        \n        NbPreferences.forModule(SourcesViewer.class).put(PROP_SELECTED_VIEWER, selected.getID());\n    }\n    \n    \n    public static void forceExternalViewer(String command) {\n        FORCED_VIEWER = command == null || command.isEmpty() ? null : new ExternalSourcesViewer(command);\n    }\n    \n    public static boolean isForcedViewer() {\n        return FORCED_VIEWER != null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/java/JavaClass.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.java;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JavaClass {\n    \n    private final String name;\n    \n    private final String source;\n    \n    private final int nameStart;\n    private final int bodyStart;\n    private final int bodyEnd;\n    \n    private List<JavaClass> namedClasses;\n    private List<JavaClass> anonymousClasses;\n    \n    \n    private JavaClass(String name, String source, int nameStart, int bodyStart, int bodyEnd) {\n        this.name = name;\n        \n        this.source = source;\n        \n        this.nameStart = nameStart;\n        this.bodyStart = bodyStart;\n        this.bodyEnd = bodyEnd;\n    }\n    \n    \n    String getName() { return name; }\n    \n    \n    int getNameStart() { return nameStart; }\n    \n    int getBodyStart() { return bodyStart; }\n    \n    int getBodyEnd() { return bodyEnd; }\n    \n    \n    String getSource() {\n        return source;\n    }\n    \n    \n    JavaClass getClass(String className) {\n        if (className == null || className.isEmpty()) return null;\n        \n        // TODO: lambdas not supported yet!\n        if (className.startsWith(JavaSourceUtils.LAMBDA_CLASS_PREFIX_MASK)) return null;\n        \n        String cIndex = null;\n        String cName  = null;\n        \n        if (Character.isDigit(className.charAt(0))) {\n            Pattern p = Pattern.compile(JavaSourceUtils.ANONYMOUS_LOCAL_CLASSNAME_REGEX);\n            Matcher m = p.matcher(className);\n            if (m.matches()) {\n                cIndex = m.group(JavaSourceUtils.REGEX_GROUP_INDEX);\n                cName = m.group(JavaSourceUtils.REGEX_GROUP_NAME);\n                if (cName.isEmpty()) cName = null;\n            }\n        }\n        \n        int searchCount = cName == null ? 1 : Integer.parseInt(cIndex);\n        String searchClass = cName == null ? className : cName;\n        \n        List<JavaClass> classes = cIndex == null || cName != null ? getNamedClasses() : getAnonymousClasses();\n        \n        for (JavaClass cls : classes)\n            if (searchClass.equals(cls.getName()))\n                if (--searchCount == 0)\n                    return cls;\n        \n        return null;\n    }\n    \n    private List<JavaClass> getNamedClasses() {\n        if (namedClasses == null) namedClasses = populateNamedClasses(source, bodyStart, bodyEnd);\n        return namedClasses;\n    }\n    \n    private List<JavaClass> getAnonymousClasses() {\n        if (anonymousClasses == null) anonymousClasses = populateAnonymousClasses(source, getNamedClasses(), bodyStart, bodyEnd);\n        return anonymousClasses;\n    }\n    \n    \n    JavaMethod getMethod(String methodName, String methodSignature) {\n        return JavaMethod.findMethod(methodName, methodSignature, this);\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return nameStart;\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        if (!(o instanceof JavaClass)) return false;\n        if (o == this) return true;\n        return ((JavaClass)o).nameStart == nameStart;\n    }\n    \n    @Override\n    public String toString() {\n        return \"class \" + name /*+ \" (nameStart=\" + nameStart + \", bodyStart=\" + bodyStart + \", bodyEnd=\" + bodyEnd + \")\"*/; // NOI18N\n    }\n    \n    \n    static JavaClass fromSource(String source, String className) {\n        List<JavaClass> classes = fromSource(source);\n        \n        for (JavaClass cls : classes)\n            if (className.equals(cls.getName()))\n                return cls;\n        \n        return null;\n    }\n    \n    private static List<JavaClass> fromSource(String source) {\n        return populateNamedClasses(source, 0, source.length());\n    }\n    \n    \n    private static List<JavaClass> populateNamedClasses(String source, int startOffset, int endOffset) {\n        List<JavaClass> classes = new ArrayList<>();\n        \n        Pattern pattern = Pattern.compile(JavaSourceUtils.CLASS_REGEX);\n        Matcher matcher = pattern.matcher(source);\n        \n        while (startOffset <= endOffset && matcher.find(startOffset)) {\n            int offset = matcher.end() - 1;\n            \n            String name = matcher.group(JavaSourceUtils.REGEX_GROUP_NAME);\n            int nameStart = offset - name.length();\n            \n            int[] bodyOffsets = JavaSourceUtils.getBlockBounds(source, offset, '{', '}'); // NOI18N\n            if (bodyOffsets[0] == -1 || bodyOffsets[1] == -1 || bodyOffsets[1] > endOffset) break;\n            \n            classes.add(new JavaClass(name, source, nameStart, bodyOffsets[0], bodyOffsets[1]));\n            \n            startOffset = bodyOffsets[1] + 1;\n        }\n        \n        return classes;\n    }\n    \n    private static List<JavaClass> populateAnonymousClasses(String source, List<JavaClass> innerClasses, int startOffset, int endOffset) {\n        List<JavaClass> classes = new ArrayList<>();\n        \n        String _source = JavaSourceUtils.maskClasses(source, innerClasses);\n//        System.err.println(_source);\n\n        Pattern pattern = Pattern.compile(JavaSourceUtils.ANONYMOUS_CLASS_START_REGEX);\n        Matcher startMatcher = pattern.matcher(_source);\n        Matcher endMatcher = null;\n        \n        populateAnonymousClassesImpl(_source, classes, startMatcher, endMatcher, startOffset, endOffset);\n//        Collections.reverse(classes);\n        System.err.println(\">>> Anonymous of \" + innerClasses + \" -- \" + classes);\n        return classes;\n    }\n    \n    private static void populateAnonymousClassesImpl(String source, List<JavaClass> classes, Matcher startMatcher, Matcher endMatcher, int startOffset, int endOffset) {\n        while (startOffset <= endOffset && startMatcher.find(startOffset)) {\n            startOffset = startMatcher.end();\n//////            System.err.println(\">>> matched start at |\" + source.substring(startOffset, startOffset + 15));\n            // Generics\n            if (source.charAt(startOffset - 1) == '<') {                        // NOI18N\n//////                System.err.println(\">>> matched generics at |\" + source.substring(startOffset, startOffset + 15));\n                startOffset = JavaSourceUtils.skipBlock(source, startOffset - 1, '<', '>'); // NOI18N\n//////                System.err.println(\">>> skipped generics at |\" + source.substring(startOffset, startOffset + 15));\n            }\n            \n            if (endMatcher == null) {\n                Pattern pattern = Pattern.compile(JavaSourceUtils.ANONYMOUS_CLASS_END_REGEX);\n                endMatcher = pattern.matcher(source);\n            }\n            \n            if (endMatcher.find(startOffset)) {\n                startOffset = endMatcher.end();\n//////                System.err.println(\">>> matched end at |\" + source.substring(startOffset, startOffset + 15));\n                // Generics\n                if (source.charAt(startOffset) == '<') {                        // NOI18N\n//////                    System.err.println(\">>> matched generics at |\" + source.substring(startOffset, startOffset + 15));\n                    startOffset = JavaSourceUtils.skipBlock(source, startOffset, '<', '>'); // NOI18N\n                    startOffset = JavaSourceUtils.skipWhiteSpaces(source, startOffset);\n//////                    System.err.println(\">>> skipped generics at |\" + source.substring(startOffset, startOffset + 15));\n                }\n\n                // Array definition\n                if (source.charAt(startOffset) == '[') {                           // NOI18N\n//////                    System.err.println(\">>> matched array at |\" + source.substring(startOffset, startOffset + 15));\n                    while (source.charAt(startOffset) == '[' && startOffset < endOffset) // NOI18N\n                        startOffset = JavaSourceUtils.skipBlock(source, startOffset, '[', ']'); // NOI18N\n                    startOffset = JavaSourceUtils.skipWhiteSpaces(source, startOffset);\n                // Anonymous class\n                } else {\n                    // Not expected\n                    if (source.charAt(startOffset) != '(') {                       // NOI18N\n//////                        System.err.println(\">>> NOT matched bracket at |\" + source.substring(startOffset, startOffset + 15));\n                        // nothing we can do here, just search again\n                    } else {\n                        // TODO do not skipBlock to search the parameters as well\n                        // but the numbering of anonymous classes becomes broken\n//////                        System.err.println(\">>> reading brackes at |\" + source.substring(startOffset, startOffset + 15));\n                        int[] paramsOffsets = JavaSourceUtils.getBlockBounds(source, startOffset, '(', ')'); // NOI18N\n                        \n//                        if (paramsOffsets[1] - paramsOffsets[0] >= JavaSourceUtils.SHORTEST_ANNONYMOUS_LENGTH) {\n//                            System.err.println(\">>> ------------ STEP IN ----------------------------------\");\n//                            System.err.println(source.substring(paramsOffsets[0] + 1, paramsOffsets[1]));\n//                            System.err.println(\">>> .......................................................\");\n//                            populateAnonymousClassesImpl(source, classes, startMatcher, endMatcher, paramsOffsets[0], paramsOffsets[1] - 1);\n//                            System.err.println(\">>> ------------ STEP OUT ---------------------------------\");\n//                        }\n                        \n                        startOffset = paramsOffsets[1] + 1;\n                        \n//                        System.err.println(\">>> paramsOffsets[0] \" + source.charAt(paramsOffsets[0]) + \" -- paramsOffsets[1] \" + source.charAt(paramsOffsets[1]));\n//////                        System.err.println(\">>> skipped bracket at |\" + source.substring(startOffset, startOffset + 5));\n                        startOffset = JavaSourceUtils.skipWhiteSpaces(source, startOffset);\n//////                        System.err.println(\">>> skipped whitespace at |\" + source.substring(startOffset, startOffset + 5));\n                        // Object creation only\n                        if (source.charAt(startOffset) != '{') {                   // NOI18N\n//////                            System.err.println(\">>> object creation only at |\" + source.substring(startOffset, startOffset + 5));\n                            // nothing we can do here, just search again\n                        // Anonymous class\n                        } else {\n//////                            System.err.println(\">>> matched anonymous at |\" + source.substring(startOffset, startOffset + 5));\n                            int[] bodyOffsets = JavaSourceUtils.getBlockBounds(source, startOffset, '{', '}'); // NOI18N\n                            if (bodyOffsets[0] == -1 || bodyOffsets[1] == -1 || bodyOffsets[1] > endOffset) break;\n\n                            classes.add(new JavaClass(Integer.toString(classes.size() + 1), source, endMatcher.start(JavaSourceUtils.REGEX_GROUP_NAME), bodyOffsets[0], bodyOffsets[1]));\n\n                            startOffset = bodyOffsets[1] + 1;\n                        }\n                        \n                        if (paramsOffsets[1] - paramsOffsets[0] >= JavaSourceUtils.SHORTEST_ANONYMOUS_LENGTH) {\n//////                            System.err.println(\">>> ------------ STEP IN ----------------------------------\");\n                            System.err.println(source.substring(paramsOffsets[0] + 1, paramsOffsets[1]));\n//////                            System.err.println(\">>> .......................................................\");\n                            populateAnonymousClassesImpl(source, classes, startMatcher, endMatcher, paramsOffsets[0], paramsOffsets[1] - 1);\n//////                            System.err.println(\">>> ------------ STEP OUT ---------------------------------\");\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/java/JavaMethod.java",
    "content": "/*\n * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.java;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JavaMethod {\n    \n    private final String name;\n    private final String signature;\n    \n//    private final String source;\n    \n    private final int nameStart;\n    private final int bodyStart;\n    private final int bodyEnd;\n    \n    \n    private JavaMethod(String name, String signature, String source, int nameStart, int bodyStart, int bodyEnd) {\n        this.name = name;\n        this.signature = signature;\n        \n//        this.source = source;\n        \n        this.nameStart = nameStart;\n        this.bodyStart = bodyStart;\n        this.bodyEnd = bodyEnd;\n    }\n    \n    \n    String getName() { return name; }\n    \n    String getSignature() { return signature; }\n    \n    \n    int getNameStart() { return nameStart; }\n    \n    int getBodyStart() { return bodyStart; }\n    \n    int getBodyEnd() { return bodyEnd; }\n    \n    \n    @Override\n    public int hashCode() {\n        return nameStart;\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        if (!(o instanceof JavaMethod)) return false;\n        if (o == this) return true;\n        return ((JavaMethod)o).nameStart == nameStart;\n    }\n    \n    @Override\n    public String toString() {\n        return \"method \" + name + \" (nameStart=\" + nameStart + \", bodyStart=\" + bodyStart + \", bodyEnd=\" + bodyEnd + \")\"; // NOI18N\n    }\n    \n    \n    static JavaMethod findMethod(String methodName, String methodSignature, JavaClass cls) {\n        // TODO: lambdas not supported yet!\n        if (methodName.contains(\"lambda$\")) return null;                        // NOI18N\n        \n        String source = JavaSourceUtils.maskNonBlock(cls.getSource(), '{', '}', cls.getBodyStart(), cls.getBodyEnd()); // NOI18N\n        \n        if (\"<clinit>\".equals(methodName)) return findClassInitializer(cls, source); // NOI18N\n        else if (\"<init>\".equals(methodName)) return findInstanceInitializer(cls, methodSignature, source); // NOI18N\n        \n        // Regular method with body\n        JavaMethod method = findMethodWithBody(methodName, methodName, methodSignature, cls, source);\n        if (method != null) return method;\n        \n        // Native method without body (abstract & interface methods not displayed in results)\n        return findMethodWithoutBody(methodName, methodSignature, cls, source);\n    }\n    \n    private static JavaMethod findClassInitializer(JavaClass cls, String source) {\n        int offset = cls.getBodyStart() + 1;\n        \n        String patternS = JavaSourceUtils.CLASS_INITIALIZER_REGEX;\n        Pattern pattern = Pattern.compile(patternS);\n        Matcher matcher = pattern.matcher(source);\n        \n        if (!matcher.find(offset)) return null;\n        \n        int bodyEnd = cls.getBodyEnd();\n        offset = matcher.end();\n        if (offset > bodyEnd) return null;\n        \n        offset--; // CLASS_INITIALIZER_REGEX matched the opening '{'\n        int[] bodyOffsets = JavaSourceUtils.getBlockBounds(source, offset, '{', '}'); // NOI18N\n        if (bodyOffsets[0] == -1 || bodyOffsets[1] == -1 || bodyOffsets[1] > bodyEnd) return null;\n        \n        return new JavaMethod(\"<clinit>\", null, source, offset, bodyOffsets[0], bodyOffsets[1]); // NOI18N\n    }\n    \n    private static JavaMethod findInstanceInitializer(JavaClass cls, String methodSignature, String source) {\n        JavaMethod constructor = findMethod(cls.getName(), \"<init>\", methodSignature, cls, source, // NOI18N\n                                            JavaSourceUtils.DEFINED_METHOD_WITHBODY_START_REGEX,\n                                            JavaSourceUtils.DEFINED_METHOD_WITHBODY_END_REGEX, false);\n        if (constructor != null) return constructor;\n        \n        int offset = cls.getBodyStart();\n        \n        String patternS = JavaSourceUtils.INSTANCE_INITIALIZER_REGEX;\n        Pattern pattern = Pattern.compile(patternS);\n        Matcher matcher = pattern.matcher(source);\n        \n        if (!matcher.find(offset)) return null;\n        \n        int bodyEnd = cls.getBodyEnd();\n        offset = matcher.end();\n        if (offset > bodyEnd) return null;\n        \n        offset--; // INSTANCE_INITIALIZER_REGEX matched the opening '{'\n        int[] bodyOffsets = JavaSourceUtils.getBlockBounds(source, offset, '{', '}'); // NOI18N\n        if (bodyOffsets[0] == -1 || bodyOffsets[1] == -1 || bodyOffsets[1] > bodyEnd) return null;\n        \n        return new JavaMethod(\"<init>\", null, source, offset, bodyOffsets[0], bodyOffsets[1]); // NOI18N\n    }\n    \n    private static JavaMethod findMethodWithBody(String methodName, String modelName, String methodSignature, JavaClass cls, String source) {\n        return findMethod(methodName, modelName, methodSignature, cls, source,\n                          JavaSourceUtils.DEFINED_METHOD_WITHBODY_START_REGEX,\n                          JavaSourceUtils.DEFINED_METHOD_WITHBODY_END_REGEX, false);\n    }\n    \n    private static JavaMethod findMethodWithoutBody(String methodName, String methodSignature, JavaClass cls, String source) {\n        return findMethod(methodName, methodName, methodSignature, cls, source,\n                          JavaSourceUtils.DEFINED_METHOD_WITHOUTBODY_START_REGEX,\n                          JavaSourceUtils.DEFINED_METHOD_WITHOUTBODY_END_REGEX, true);\n    }\n    \n    private static JavaMethod findMethod(String methodName, String modelName, String methodSignature, JavaClass cls, String source, String startRegEx, String endRegEx, boolean withoutBody) {\n        int offset = cls.getBodyStart() + 1;\n        int bodyEnd = cls.getBodyEnd();\n        \n        String patternS = startRegEx.replace(JavaSourceUtils.REGEX_PARAMETER_0, methodName);\n        Pattern pattern = Pattern.compile(patternS);\n        Matcher startMatcher = pattern.matcher(source);\n        Matcher endMatcher = null;\n        \n        while (startMatcher.find(offset) && offset < bodyEnd) {\n            int nameStart = startMatcher.start() + startMatcher.group(JavaSourceUtils.REGEX_GROUP_PREFIX).length();\n             \n            offset = startMatcher.end() - 1;\n            if (offset > bodyEnd) return null;\n            \n            // Skip method parameters\n            offset = JavaSourceUtils.skipBlock(source, offset, '(', ')');       // NOI18N\n            if (offset > bodyEnd) return null;\n            \n            if (endMatcher == null) {\n                pattern = Pattern.compile(endRegEx);\n                endMatcher = pattern.matcher(source);\n            }\n            \n            // Search for method declaration\n            if (endMatcher.find(offset)) {\n                offset = endMatcher.end() - 1;\n                if (offset > bodyEnd) return null;\n\n                if (withoutBody && ';' == source.charAt(offset)) return new JavaMethod(methodName, methodSignature, source, nameStart, -1, -1); // NOI18N\n\n                // Search for method body\n                int[] bodyOffsets = JavaSourceUtils.getBlockBounds(source, offset, '{', '}'); // NOI18N\n                if (bodyOffsets[0] == -1 || bodyOffsets[1] == -1 || bodyOffsets[1] > bodyEnd) return null;\n\n                return new JavaMethod(modelName, methodSignature, source, nameStart, bodyOffsets[0], bodyOffsets[1]); // NOI18N\n            }\n        }\n        \n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/java/JavaSourceHandle.java",
    "content": "/*\n * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.java;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport org.graalvm.visualvm.gotosource.SourceHandle;\nimport org.graalvm.visualvm.gotosource.SourceHandleUtils;\nimport org.graalvm.visualvm.gotosource.SourcePathHandle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JavaSourceHandle extends SourceHandle {\n    \n    private static final String LANGUAGE_ID = \"java\";                           // NOI18N\n    \n    private final String className;\n    private final String methodName;\n    private final String methodSignature;\n    \n    private String text;\n    private int line;\n    private int column;\n    private int offset;\n    private int endOffset;\n    \n    private final SourcePathHandle pathHandle;\n    \n    \n    JavaSourceHandle(String className, String methodName, String methodSignature, int line, SourcePathHandle pathHandle) {\n        this.className = className;\n        this.methodName = methodName;\n        this.methodSignature = methodSignature;\n        \n        this.line = line;\n        \n        this.offset = -1;\n        this.endOffset = -1;\n        this.column = -1;\n        \n        this.pathHandle = pathHandle;\n    }\n    \n    \n    @Override\n    public String getLanguage() {\n        return LANGUAGE_ID;\n    }\n    \n\n    @Override\n    public String getClassName() {\n        return className;\n    }\n\n    @Override\n    public String getMethodName() {\n        return methodName;\n    }\n\n    @Override\n    public String getMethodSignature() {\n        return methodSignature;\n    }\n\n    \n    @Override\n    public int getLine() {\n        if (line == -1) {\n            int[] line_column = SourceHandleUtils.offsetToLineColumn(getText(), getOffset());\n            line = line_column[0];\n            column = line_column[1];\n        }\n        return line;\n    }\n    \n    @Override\n    public int getColumn() {\n        if (column == -1) {\n            int[] line_column = SourceHandleUtils.offsetToLineColumn(getText(), getOffset());\n            line = line_column[0];\n            column = line_column[1];\n        }\n        return column;\n    }\n\n    @Override\n    public int getOffset() {\n        if (offset == -1) {\n            if (methodName == null || methodName.isEmpty() || methodName.startsWith(\"*\")) { // NOI18N\n                offset = JavaSourceUtils.classDefinitionOffset(getText(), className, false);\n            } else {\n                offset = JavaSourceUtils.methodDefinitionOffset(getText(), className, methodName, methodSignature, false);\n            }\n            if (offset == -1) offset = 0;\n        }\n        return offset;\n    }\n    \n    @Override\n    public int getEndOffset() {\n        if (endOffset == -1) {\n            int _offset = getOffset();\n            String _text = getText();\n\n            if (_text.charAt(_offset) == '{') {                                 // NOI18N\n                endOffset = _offset + 1;\n            } else {\n                Pattern pattern = Pattern.compile(JavaSourceUtils.FULLY_QUALIFIED_IDENTIFIER_REGEX);\n                Matcher matcher = pattern.matcher(_text);\n                endOffset = _offset + (matcher.find(_offset) ? matcher.group().length() : 0);\n            }\n        }\n        return endOffset;\n    }\n\n    \n    @Override\n    public String getText() {\n        if (text == null) text = pathHandle.readText();\n        return text;\n    }\n\n    \n    @Override\n    public String getSourceUri() {\n        return pathHandle.getPath().toUri().toString();\n    }\n\n    @Override\n    public String getSourceFile() {\n        return pathHandle.getRegularPath().toAbsolutePath().toString();\n    }\n\n    \n    @Override\n    protected void close() {\n        pathHandle.close();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/java/JavaSourceHandleProvider.java",
    "content": "/*\n * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.java;\n\nimport org.graalvm.visualvm.gotosource.SourceHandle;\nimport org.graalvm.visualvm.gotosource.SourceHandleProvider;\nimport org.graalvm.visualvm.gotosource.SourcePathHandle;\nimport org.graalvm.visualvm.gotosource.SourcesRoot;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=SourceHandleProvider.class, position = 100)\npublic final class JavaSourceHandleProvider extends SourceHandleProvider {\n    \n    @Override\n    public SourceHandle createHandle(String className, String methodName, String methodSignature, int line) {\n        String toplevelClassName = JavaSourceUtils.toplevelClassName(className);\n        String toplevelClassFile = JavaSourceUtils.toplevelClassFile(toplevelClassName);\n        \n        SourcePathHandle pathHandle = SourcesRoot.getPathHandle(toplevelClassFile);\n        return pathHandle == null ? null : new JavaSourceHandle(className, methodName, methodSignature, line, pathHandle);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/java/JavaSourceUtils.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.java;\n\nimport java.util.List;\nimport java.util.regex.Pattern;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JavaSourceUtils {\n    \n    private static final char COMMENT_MASK_CHAR = ' ';                          // NOI18N\n    private static final char STRING_MASK_CHAR = '+';                           // NOI18N\n    private static final char NONBLOCK_MASK_CHAR = '=';                         // NOI18N\n    private static final char CLASS_MASK_CHAR = '_';                            // NOI18N\n    \n    private static final String LAMBDA_CLASS_PREFIX = \"$Lambda$\";               // NOI18N\n    static final String LAMBDA_CLASS_PREFIX_MASK = \"-Lambda-\";                  // NOI18N\n    \n    static final String IDENTIFIER_REGEX = \"\\\\p{javaJavaIdentifierStart}\\\\p{javaJavaIdentifierPart}*\"; // NOI18N\n    static final String FULLY_QUALIFIED_IDENTIFIER_REGEX = \"(\" + IDENTIFIER_REGEX + \"\\\\.)*\" + IDENTIFIER_REGEX; // NOI18N\n    private static final String THROWS_REGEX = \"throws\\\\s+(\" + FULLY_QUALIFIED_IDENTIFIER_REGEX + \"\\\\s*,\\\\s*)*\" + FULLY_QUALIFIED_IDENTIFIER_REGEX; // NOI18N\n    \n    \n    static final String REGEX_PARAMETER_0 = \"{#$0#}\";                           // NOI18N\n    \n    static final String REGEX_GROUP_NAME = \"name\";                              // NOI18N\n    static final String REGEX_GROUP_INDEX = \"index\";                            // NOI18N\n    static final String REGEX_GROUP_PREFIX = \"prefix\";                          // NOI18N\n    \n    \n    static final String ANONYMOUS_LOCAL_CLASSNAME_REGEX = \"(?<\" + REGEX_GROUP_INDEX + \">[\\\\d]+)(?<\" + REGEX_GROUP_NAME + \">[\\\\D]*)\"; // NOI18N\n    static final String CLASS_REGEX = \"(^|[\\\\W&&[^.]])(class|interface|enum)\\\\s+(?<\" + REGEX_GROUP_NAME + \">\" + IDENTIFIER_REGEX + \")[^\\\\p{javaJavaIdentifierPart}]\"; // NOI18N\n    static final String ANONYMOUS_CLASS_START_REGEX = \"\\\\Wnew\\\\s*(\\\\s|\\\\<)\"; // NOI18N\n    static final String ANONYMOUS_CLASS_END_REGEX = \"\\\\G\\\\s*(?<\" + REGEX_GROUP_NAME + \">\" + FULLY_QUALIFIED_IDENTIFIER_REGEX + \")\\\\s*\"; // NOI18N\n    static final String ANONYMOUS_CLASS_METHOD_REGEX = \"\\\\G\\\\s*.s*\\\\(\";         // NOI18N\n    \n    static final int SHORTEST_ANONYMOUS_LENGTH = \"new X(){}\".length();\n    \n    static final String CLASS_INITIALIZER_REGEX = \"\\\\Wstatic\\\\s*\\\\{\";           // NOI18N\n    static final String INSTANCE_INITIALIZER_REGEX = \"[\\\\{\\\\};]\\\\s*\\\\{\";        // NOI18N\n    \n    static final String DEFINED_METHOD_WITHBODY_START_REGEX = \"(?<\" + REGEX_GROUP_PREFIX + \">[\\\\s\\\\>])\" + REGEX_PARAMETER_0 + \"\\\\s*\\\\(\"; // NOI18N\n    static final String DEFINED_METHOD_WITHBODY_END_REGEX = \"\\\\G\\\\s*(\" + THROWS_REGEX + \")??\\\\s*\\\\{\"; // NOI18N\n    /* TODO: review */ static final String DEFINED_METHOD_WITHOUTBODY_START_REGEX = \"(?<\" + REGEX_GROUP_PREFIX + \">\\\\Wnative[\\\\s\\\\S&&[^;]&&[^\\\\(]]*?[\\\\s\\\\>])\" + REGEX_PARAMETER_0 + \"\\\\s*\\\\(\"; // NOI18N\n    static final String DEFINED_METHOD_WITHOUTBODY_END_REGEX = \"\\\\G\\\\s*(\" + THROWS_REGEX + \")??\\\\s*;\"; // NOI18N\n    \n    \n    private JavaSourceUtils() {}\n    \n    \n    static String toplevelClassName(String className) {\n        className = className.replace(\"[]\", \"\");                                // NOI18N\n        int innerIndex = className.indexOf('$');                                // NOI18N\n        return innerIndex == -1 ? className : className.substring(0, innerIndex);\n    }\n    \n    static String toplevelClassFile(String toplevelClassName) {\n        return toplevelClassName.replace(\".\", \"/\") + \".java\";                   // NOI18N\n    }\n    \n    \n    static String plainClassName(String className) {\n        int index = className.lastIndexOf('.');                                 // NOI18N\n        return index == -1 ? className : className.substring(index + 1);\n    }\n    \n    private static String[] classNameComponents(String className) {\n        String pureClassName = className.replace(\"[]\", \"\");                     // NOI18N\n        String plainClassName = plainClassName(pureClassName);\n        \n        plainClassName = plainClassName.replace(LAMBDA_CLASS_PREFIX, LAMBDA_CLASS_PREFIX_MASK);\n        \n        return plainClassName.split(Pattern.quote(\"$\"));                        // NOI18N\n    }\n    \n    \n    static int classDefinitionOffset(String text, String className, boolean exactOnly) {\n        text = maskNonCode(text);\n        \n        String[] classNameComponents = classNameComponents(className);\n        \n        JavaClass cls = getJavaClass(text, classNameComponents, exactOnly);\n        return cls == null ? -1 : cls.getNameStart();\n    }\n    \n    \n    private static JavaClass getJavaClass(String text, String[] plainClassNames, boolean exactOnly) {\n        JavaClass cls = null;\n        JavaClass foundClass = null;\n        \n        for (String classNameComponent : plainClassNames) {\n            if (cls == null) cls = JavaClass.fromSource(text, classNameComponent);\n            else cls = cls.getClass(classNameComponent);\n            \n            if (cls != null) foundClass = cls;\n            else return exactOnly ? null : foundClass;\n        }\n        \n        return foundClass;\n    }\n    \n    static int methodDefinitionOffset(String text, String className, String methodName, String methodSignature, boolean exactOnly) {\n        text = maskNonCode(text);\n        \n        String[] classNameComponents = classNameComponents(className);\n        \n        JavaClass cls = getJavaClass(text, classNameComponents, true);\n        if (cls == null) {\n            if (!exactOnly) cls = getJavaClass(text, classNameComponents, false);\n            return cls == null ? -1 : cls.getNameStart();\n        }\n        \n        JavaMethod method = cls.getMethod(methodName, methodSignature);\n        if (method == null) return exactOnly ? -1 : cls.getNameStart();\n        \n        return method.getNameStart();\n    }\n    \n    \n    // TODO: all leading & trailing non-code characters should be preserved: /* */ // \"\"\n    static String maskNonCode(String text) {\n        char[] newText = new char[text.length()];\n        \n        boolean lineComment = false;\n        boolean blockComment = false;\n        \n        boolean chardef = false;\n        boolean string = false;\n        int escapes = 0;\n        \n        char lastChar = ' ';                                                    // NOI18N\n        \n        for (int position = 0; position < newText.length; position++) {\n            char currentChar = text.charAt(position);\n            \n            if (!lineComment && !chardef && !string) {\n                if (!blockComment && '/' == lastChar && '*' == currentChar) {   // NOI18N\n                    newText[position - 1] = COMMENT_MASK_CHAR;\n                    blockComment = true;\n                }\n            }\n            \n            if (!blockComment && !chardef && !string) {\n                if (!lineComment && '/' == lastChar && '/' == currentChar) {    // NOI18N\n                    newText[position - 1] = COMMENT_MASK_CHAR;\n                    lineComment = true;\n                } else if (lineComment && ('\\r' == currentChar || '\\n' == currentChar)) { // NOI18N\n                    lineComment = false;\n                }\n            }\n            \n            if (!lineComment && !blockComment && !string) {\n                if (!chardef && '\\'' == currentChar) {                            // NOI18N\n                    chardef = true;\n                } else if (chardef) {                                            // NOI18N\n                    if ('\\\\' == currentChar) {\n                        escapes++;\n                    } else if ('\\'' == currentChar) {                            // NOI18N\n                        chardef = escapes % 2 != 0;\n                        escapes = 0;\n                    } else {\n                        escapes = 0;\n                    }\n                }\n            }\n            \n            if (!lineComment && !blockComment && !chardef) {\n                if (!string && '\"' == currentChar) {                            // NOI18N\n                    string = true;\n                } else if (string) {                                            // NOI18N\n                    if ('\\\\' == currentChar) {\n                        escapes++;\n                    } else if ('\"' == currentChar) {                            // NOI18N\n                        string = escapes % 2 != 0;\n                        escapes = 0;\n                    } else {\n                        escapes = 0;\n                    }\n                }\n            }\n            \n            if (string || chardef) newText[position] = STRING_MASK_CHAR;\n            else if (Character.isWhitespace(currentChar)) newText[position] = currentChar; // NOI18N\n            else if (lineComment || blockComment) newText[position] = COMMENT_MASK_CHAR;\n            else newText[position] = currentChar;\n            \n            if (!lineComment && !chardef && !string) {\n                if (blockComment && '*' == lastChar && '/' == currentChar) {    // NOI18N\n                    blockComment = false;\n                }\n            }\n            \n            lastChar = currentChar;\n        }\n        \n        return new String(newText);\n    }\n    \n    \n    static String maskNonBlock(String text, char startDelimiter, char endDelimiter, int startPosition, int endPosition) {\n        char[] newText = new char[text.length()];\n        \n        int currentCount = 0;        \n        \n        while (startPosition <= endPosition) {\n            char currentChar = text.charAt(startPosition);\n            \n            if (startDelimiter == currentChar) currentCount++;\n            \n            newText[startPosition] = currentCount == 1 || (currentCount == 2 && (currentChar == startDelimiter || currentChar == endDelimiter)) || Character.isWhitespace(currentChar) ? currentChar : NONBLOCK_MASK_CHAR;\n            \n            if (endDelimiter == currentChar) currentCount--;\n            \n            startPosition++;\n        }\n        \n        return new String(newText);\n    }\n    \n    static String maskClasses(String text, List<JavaClass> classes) {\n        char[] newText = text.toCharArray();\n        \n        for (JavaClass cls : classes) {\n            for (int position = cls.getBodyStart() + 1; position < cls.getBodyEnd(); position++) {\n                char currentChar = text.charAt(position);\n                newText[position] = Character.isWhitespace(currentChar) ? currentChar : CLASS_MASK_CHAR;\n            }\n        }\n        \n        return new String(newText);\n    }\n    \n    static int skipBlock(String text, int position, char startDelimiter, char endDelimiter) {\n        return skipBlockImpl(text, position, startDelimiter, endDelimiter, true)[1];\n    }\n    \n    static int[] getBlockBounds(String text, int position, char startDelimiter, char endDelimiter) {\n        return skipBlockImpl(text, position, startDelimiter, endDelimiter, false);\n    }\n    \n    private static int[] skipBlockImpl(String text, int position, char startDelimiter, char endDelimiter, boolean moveToNext) {\n        int start = -1;\n        \n        int currentCount = 0;        \n        boolean found = false;\n\n        while (position < text.length()) {\n            char currentChar = text.charAt(position);\n            \n            if (currentChar == endDelimiter) {\n                currentCount--;\n            } else if (currentChar == startDelimiter) {\n                if (start == -1) start = position;\n                currentCount++;\n                found = true;\n            }\n            \n            if (found && currentCount == 0) break;\n            \n            position++;\n        }\n        \n        return new int[] { start, moveToNext ? position + 1 : position };\n    }\n    \n    static int skipWhiteSpaces(String text, int position) {\n        while (position < text.length() && Character.isWhitespace(text.charAt(position))) position++;\n        return position;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/options/SourcesOptions.java",
    "content": "/*\n * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.options;\n\nimport java.beans.PropertyChangeListener;\nimport javax.swing.JComponent;\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.netbeans.spi.options.OptionsPanelController;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@OptionsPanelController.TopLevelRegistration(\n        id = \"SourcesOptions\",                                                  // NOI18N\n        categoryName = \"#SourcesOptions_Name\",                                  // NOI18N\n        iconBase = \"org/graalvm/visualvm/gotosource/resources/gotosource32.png\",      // NOI18N\n        position = 1530)\n@NbBundle.Messages({\n        \"SourcesOptions_Name=Sources\"                                           // NOI18N\n})\npublic final class SourcesOptions extends OptionsPanelController {\n    \n    private static final HelpCtx HELP_CTX = null;\n    \n    \n    private SourcesOptionsPanel optionsPanel;\n    private JComponent optionsComponent;\n    \n\n    @Override\n    public void update() {\n        if (optionsPanel == null) return;\n        optionsPanel.load(NbPreferences.forModule(SourcesOptions.class));\n    }\n\n    @Override\n    public void applyChanges() {\n        if (optionsPanel == null) return;\n        optionsPanel.save(NbPreferences.forModule(SourcesOptions.class));\n    }\n\n    @Override\n    public void cancel() {\n        if (optionsPanel == null) return;\n        optionsPanel.cancel();\n    }\n\n    @Override\n    public boolean isValid() {\n        return true;\n    }\n\n    @Override\n    public boolean isChanged() {\n        if (optionsPanel == null) return false;\n        return optionsPanel.dirty(NbPreferences.forModule(SourcesOptions.class));\n    }\n\n    @Override\n    public JComponent getComponent(Lookup lkp) {\n        if (optionsComponent == null) optionsComponent = UISupport.createScrollableContainer(getPanel());\n        return optionsComponent;\n    }\n\n    @Override\n    public HelpCtx getHelpCtx() {\n        return HELP_CTX;\n    }\n\n    @Override\n    public void addPropertyChangeListener(PropertyChangeListener pl) {\n    }\n\n    @Override\n    public void removePropertyChangeListener(PropertyChangeListener pl) {\n    }\n    \n    \n    private SourcesOptionsPanel getPanel() {\n        if (optionsPanel == null) optionsPanel = new SourcesOptionsPanel();\n        return optionsPanel;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/options/SourcesOptionsPanel.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.options;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.FocusAdapter;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.ItemListener;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.io.File;\nimport java.nio.charset.Charset;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.FileSystem;\nimport java.nio.file.FileSystems;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.prefs.Preferences;\nimport java.util.stream.Collectors;\nimport javax.swing.ButtonGroup;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.DefaultListCellRenderer;\nimport javax.swing.DefaultListModel;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JComboBox;\nimport javax.swing.JComponent;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JRadioButton;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextField;\nimport javax.swing.ListModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.filechooser.FileFilter;\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.swing.SmallButton;\nimport org.graalvm.visualvm.gotosource.SourcesRoot;\nimport org.graalvm.visualvm.gotosource.impl.SourceRoots;\nimport org.graalvm.visualvm.gotosource.impl.SourceViewers;\nimport org.graalvm.visualvm.gotosource.SourcesViewer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.RequestProcessor;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"SourcesOptionsPanel_DefinitionsCaption=Definitions\",                       // NOI18N\n    \"SourcesOptionsPanel_Sources=&Source Roots:\",                               // NOI18N\n    \"SourcesOptionsPanel_ViewerCaption=Viewer\",                                 // NOI18N\n    \"SourcesOptionsPanel_OpenIn=&Open sources in:\",                             // NOI18N\n    \"SourcesOptionsPanel_Config=Viewer settings:\",                              // NOI18N\n    \"SourcesOptionsPanel_Add=Add new source root(s)\",                              // NOI18N\n    \"SourcesOptionsPanel_Delete=Delete selected source root(s)\",                  // NOI18N\n    \"SourcesOptionsPanel_MoveUp=Move selected source root up\",                  // NOI18N\n    \"SourcesOptionsPanel_MoveDown=Move selected source root down\",              // NOI18N\n    \"SourcesOptionsPanel_SelectRootsCaption=Select Source Roots\",               // NOI18N\n    \"SourcesOptionsPanel_SelectButton=Select\",                                  // NOI18N\n    \"SourcesOptionsPanel_SourceDirectoriesFilter=Directories or Archives\",      // NOI18N\n    \"SourcesOptionsPanel_ForcedRoots=Source roots have been set automatically for this session\", // NOI18N\n    \"SourcesOptionsPanel_ForcedViewer=Sources viewer has been set automatically for this session\", // NOI18N\n    \"SourcesOptionsPanel_SourcesLocation=Sources Location:\",                    // NOI18N\n    \"SourcesOptionsPanel_SelectedRootsChoice=&Selected root(s)\",                // NOI18N\n    \"SourcesOptionsPanel_SelectedRootsToolTip=Sources are directly in the source root(s)\",// NOI18N\n    \"SourcesOptionsPanel_SubdirectoriesChoice=S&ubdirectories:\",                // NOI18N\n    \"SourcesOptionsPanel_SubdirectoriesToolTip=Sources are in the selected subdirectories of the source root(s)\", // NOI18N\n    \"SourcesOptionsPanel_CustomSubpathsChoice=&Custom subpaths:\",               // NOI18N\n    \"# {0} - module path\",\n    \"SourcesOptionsPanel_CustomSubpathsToolTip=<html>Sources are in the defined subpaths of the source root(s) - no wildcards allowed<br>Use <code>{0}</code> to search source root(s) including module subfolders</html>\", // NOI18N\n    \"SourcesOptionsPanel_SourcesEncoding=Sources Encoding:\"                     // NOI18N\n})\nfinal class SourcesOptionsPanel extends JPanel {\n    \n    private static final String PROP_LAST_SOURCES_DIR = \"prop_SourcesOptionsPanel_lastDir\"; // NOI18N\n    \n    \n    SourcesOptionsPanel() {\n        initUI();\n    }\n    \n    \n    void load(Preferences settings) {\n        rootsForcedHint.setVisible(SourceRoots.areForcedRoots());\n        \n        rootsListModel = new DefaultListModel<>();\n        for (String root : SourceRoots.getRoots()) rootsListModel.addElement(root);\n        rootsList.setModel(rootsListModel);\n        rootsList.setEnabled(!rootsForcedHint.isVisible());\n        updateRootsButtons();\n        \n        \n        viewerForcedHint.setVisible(SourceViewers.isForcedViewer());\n        \n        Collection<? extends SourcesViewer> viewers = SourceViewers.getRegisteredViewers();\n        viewerSelector.setModel(new DefaultComboBoxModel<>(viewers.toArray(new SourcesViewer[0])));\n        viewerSelector.setEnabled(!viewerForcedHint.isVisible());\n        \n        SourcesViewer selected = SourceViewers.getSelectedViewer();\n        if (selected == null && !viewers.isEmpty()) {\n            selected = viewers.iterator().next();\n            SourceViewers.saveSelectedViewer(selected);\n        }\n        \n        for (int i = 0; i < viewerSelector.getItemCount(); i++)\n            viewerSelector.getItemAt(i).loadSettings();\n        \n        if (selected != null) {\n            viewerSelector.setSelectedItem(selected);\n            viewerSelected(selected);\n        }\n    }\n    \n    void save(Preferences settings) {\n        if (!SourceRoots.areForcedRoots()) SourceRoots.saveRoots(getDefinedRoots());\n        \n        if (!SourceViewers.isForcedViewer()) {\n            SourceViewers.saveSelectedViewer(getSelectedViewer());\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    for (int i = 0; i < viewerSelector.getItemCount(); i++)\n                        viewerSelector.getItemAt(i).saveSettings();\n                }\n            });\n        }\n    }\n    \n    void cancel() {}\n    \n    boolean dirty(Preferences settings) {\n        if (!SourceRoots.areForcedRoots()) {\n            String[] definedStrings = SourceRoots.getRoots();\n            String[] currentStrings = getDefinedRoots();\n            if (!Arrays.equals(definedStrings, currentStrings)) return true;\n        }\n        \n        if (!SourceViewers.isForcedViewer()) {\n            SourcesViewer selectedViewer = SourceViewers.getSelectedViewer();\n            String selectedViewerID = selectedViewer == null ? null : selectedViewer.getID();\n            SourcesViewer currentlySelectedViewer = getSelectedViewer();\n            String currentlySelectedViewerID = currentlySelectedViewer == null ? null : currentlySelectedViewer.getID();\n            if (!Objects.equals(selectedViewerID, currentlySelectedViewerID)) return true;\n\n            for (int i = 0; i < viewerSelector.getItemCount(); i++)\n                if (viewerSelector.getItemAt(i).settingsDirty())\n                    return true;\n        }\n        \n        return false;\n    }\n    \n    \n    private String[] getDefinedRoots() {\n        String[] roots = new String[rootsListModel.size()];\n        rootsListModel.copyInto(roots);\n        return roots;\n    }\n    \n    \n    private SourcesViewer getSelectedViewer() {\n        return (SourcesViewer)viewerSelector.getSelectedItem();\n    }\n    \n    \n    private void viewerSelected(SourcesViewer viewer) {\n        viewerDescription.setText(viewer.getDescription());\n        \n        viewerSettings.removeAll();\n        JComponent settingsComponent = viewer.getSettingsComponent();\n        if (settingsComponent != null) viewerSettings.add(settingsComponent, BorderLayout.NORTH);\n\n        \n        validate();\n        repaint();\n    }\n    \n    \n    private void updateRootsButtons() {\n        if (rootsForcedHint.isVisible()) {\n            addButton.setEnabled(false);\n            removeButton.setEnabled(false);\n            upButton.setEnabled(false);\n            downButton.setEnabled(false);\n        } else {\n            int[] selectedRows = rootsList.getSelectedIndices();\n            int selectedRow = selectedRows.length == 1 ? selectedRows[0] : -1;\n\n            addButton.setEnabled(true);\n            removeButton.setEnabled(selectedRows.length > 0);\n\n            if (selectedRow == -1) {\n                upButton.setEnabled(false);\n                downButton.setEnabled(false);\n            } else {\n                Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();\n\n                upButton.setEnabled(selectedRow > 0);\n                downButton.setEnabled(selectedRow < rootsListModel.size() - 1);\n\n                if (upButton == focusOwner && !upButton.isEnabled() && downButton.isEnabled()) downButton.requestFocusInWindow();\n                else if (downButton == focusOwner && !downButton.isEnabled() && upButton.isEnabled()) upButton.requestFocusInWindow();\n            }\n        }\n    }\n    \n    \n    private void initUI() {\n        setLayout(new GridBagLayout());\n        \n        GridBagConstraints c;\n        int y = 0;\n        int htab = 15;\n        int vgap = 5;\n        \n        SectionSeparator definitionsSection = UISupport.createSectionSeparator(Bundle.SourcesOptionsPanel_DefinitionsCaption());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = y++;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, vgap * 3, 0);\n        add(definitionsSection, c);\n        \n        JLabel definitionsCaption = new JLabel();\n        Mnemonics.setLocalizedText(definitionsCaption, Bundle.SourcesOptionsPanel_Sources());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = y++;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(0, htab, vgap, 0);\n        add(definitionsCaption, c);\n        \n        rootsListModel = new DefaultListModel<>();\n        rootsList = new JList<>(rootsListModel);\n        rootsList.setVisibleRowCount(0);\n        definitionsCaption.setLabelFor(rootsList);\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = y++;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.gridheight = 5;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(0, htab, vgap * 3, 0);\n        add(new JScrollPane(rootsList), c);\n        \n        addButton = new SmallButton(Icons.getIcon(GeneralIcons.ADD)) {\n            {\n                setToolTipText(Bundle.SourcesOptionsPanel_Add());\n            }\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                \n                JFileChooser fileChooser = new JFileChooser((String)null);\n                fileChooser.setDialogTitle(Bundle.SourcesOptionsPanel_SelectRootsCaption());\n                fileChooser.setApproveButtonText(Bundle.SourcesOptionsPanel_SelectButton());\n                fileChooser.setMultiSelectionEnabled(true);\n                fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);\n                fileChooser.setAcceptAllFileFilterUsed(false);\n                fileChooser.addChoosableFileFilter(new FileFilter() {\n                    @Override\n                    public boolean accept(File f) {\n                        return f.isDirectory() || f.getName().endsWith(\".zip\") || f.getName().endsWith(\".jar\"); // NOI18N\n                    }\n                    @Override\n                    public String getDescription() {\n                        return Bundle.SourcesOptionsPanel_SourceDirectoriesFilter() + \" (*.zip, *.jar)\"; // NOI18N\n                    }\n                });\n                \n                String aFile = System.getProperties().getProperty(\"netbeans.home\"); // NOI18N\n                Icon fileIcon = fileChooser.getIcon(new File(aFile));\n                SourceRootsCustomizer customizer = new SourceRootsCustomizer(fileIcon);\n                fileChooser.setAccessory(customizer);\n                fileChooser.addPropertyChangeListener(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY, customizer);\n\n                String lastDirS = NbPreferences.forModule(SourcesOptionsPanel.class).get(PROP_LAST_SOURCES_DIR, null);\n                File lastDir = lastDirS == null ? null : new File(lastDirS);\n                if (lastDir != null && lastDir.isDirectory()) fileChooser.setCurrentDirectory(lastDir);\n\n                if (fileChooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) {\n                    String first = null;\n                    String firstC = null;\n                    for (File selected : fileChooser.getSelectedFiles()) {\n                        String path = selected.getAbsolutePath();\n                        String pathC = customizer.createRootString(path);\n                        \n                        if (first == null) {\n                            first = path;\n                            firstC = pathC;\n                        }\n                        \n                        if (!rootsListModel.contains(pathC)) rootsListModel.addElement(pathC);\n                    }\n                    if (first != null) {\n                        rootsList.setSelectedValue(firstC, true);\n                        \n                        File dir = new File(first).getParentFile();\n                        String dirS = dir.isDirectory() ? dir.getAbsolutePath() : null;\n                        if (dirS != null) NbPreferences.forModule(SourcesOptionsPanel.class).put(PROP_LAST_SOURCES_DIR, dirS);\n                    }\n                }\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = y++;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, htab, 0, 0);\n        add(addButton, c);\n        \n        removeButton = new SmallButton(Icons.getIcon(GeneralIcons.REMOVE)) {\n            {\n                setToolTipText(Bundle.SourcesOptionsPanel_Delete());\n            }\n            protected void fireActionPerformed(ActionEvent e) {\n                for (Object selected : rootsList.getSelectedValuesList())\n                    rootsListModel.removeElement(selected);\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = y++;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, htab, vgap * 2, 0);\n        add(removeButton, c);\n        \n        final boolean[] internalSelectionChange = new boolean[] { false };\n        \n        upButton = new SmallButton(Icons.getIcon(GeneralIcons.UP)) {\n            {\n                setToolTipText(Bundle.SourcesOptionsPanel_MoveUp());\n            }\n            protected void fireActionPerformed(ActionEvent e) {\n                int selected = rootsList.getSelectedIndex();\n                if (selected < 1) return;\n                \n                String selectedRoot = rootsListModel.get(selected);\n                internalSelectionChange[0] = true;\n                try {\n                    rootsListModel.remove(selected);\n                    rootsListModel.add(selected - 1, selectedRoot);\n                } finally {\n                    internalSelectionChange[0] = false;\n                }\n                rootsList.setSelectedValue(selectedRoot, true);\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = y++;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, htab, 0, 0);\n        add(upButton, c);\n        \n        downButton = new SmallButton(Icons.getIcon(GeneralIcons.DOWN)) {\n            {\n                setToolTipText(Bundle.SourcesOptionsPanel_MoveDown());\n            }\n            protected void fireActionPerformed(ActionEvent e) {\n                int selected = rootsList.getSelectedIndex();\n                if (selected == -1 || selected > rootsListModel.size() - 2) return;\n                \n                String selectedRoot = rootsListModel.get(selected);\n                internalSelectionChange[0] = true;\n                try {\n                    rootsListModel.remove(selected);\n                    rootsListModel.add(selected + 1, selectedRoot);\n                } finally {\n                    internalSelectionChange[0] = false;\n                }\n                rootsList.setSelectedValue(selectedRoot, true);\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = y++;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, htab, 0, 0);\n        add(downButton, c);\n        \n        rootsForcedHint = new JLabel(Bundle.SourcesOptionsPanel_ForcedRoots(), Icons.getIcon(GeneralIcons.INFO), JLabel.LEADING);\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = y++;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(-vgap, htab, vgap * 3, 0);\n        add(rootsForcedHint, c);\n        \n        SectionSeparator gotoSection = UISupport.createSectionSeparator(Bundle.SourcesOptionsPanel_ViewerCaption());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = y++;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, vgap * 3, 0);\n        add(gotoSection, c);\n        \n        final JPanel chooserPanel = new JPanel(new GridBagLayout());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = y++;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, htab, vgap * 2, 0);\n        add(chooserPanel, c);\n        \n        JLabel openInLabel = new JLabel();\n        Mnemonics.setLocalizedText(openInLabel, Bundle.SourcesOptionsPanel_OpenIn());\n        chooserPanel.add(openInLabel);\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(0, 0, 0, vgap);\n        chooserPanel.add(openInLabel, c);\n        \n        viewerSelector = new JComboBox<>();\n        openInLabel.setLabelFor(viewerSelector);\n        viewerSelector.addItemListener(new ItemListener() {\n            @Override\n            public void itemStateChanged(ItemEvent e) {\n                if (e.getStateChange() == ItemEvent.SELECTED) viewerSelected((SourcesViewer)e.getItem());\n            }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(0, 0, 0, htab);\n        chooserPanel.add(viewerSelector, c);        \n        \n        viewerDescription = new JLabel();\n        viewerDescription.setEnabled(false);\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 0;\n        c.weightx = 1.0;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 0, 0);\n        chooserPanel.add(viewerDescription, c);\n        \n        viewerSettings = new JPanel(new BorderLayout()) {\n            public Dimension getMinimumSize() {\n                Dimension dim = super.getMinimumSize();\n                dim.height = getPreferredSize().height;\n                return dim;\n            }\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.height = Math.max(dim.height, chooserPanel.getPreferredSize().height + 10);\n                return dim;\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = y++;\n        c.weightx = 1.0;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, htab, 0, 0);\n        add(viewerSettings, c);\n        \n        viewerForcedHint = new JLabel(Bundle.SourcesOptionsPanel_ForcedViewer(), Icons.getIcon(GeneralIcons.INFO), JLabel.LEADING);\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = y++;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, htab, 0, 0);\n        add(viewerForcedHint, c);\n        \n        \n        ListSelectionListener selection = new ListSelectionListener() {\n            public void valueChanged(ListSelectionEvent e) {\n                if (!internalSelectionChange[0] && !e.getValueIsAdjusting()) updateRootsButtons();\n            }\n        };\n        rootsList.addListSelectionListener(selection);\n        updateRootsButtons();\n    }\n    \n    \n    private DefaultListModel<String> rootsListModel;\n    private JList<String> rootsList;\n    private JButton addButton, removeButton, upButton, downButton;\n    private JLabel rootsForcedHint;\n    \n    private JComboBox<SourcesViewer> viewerSelector;\n    private JLabel viewerDescription;\n    private JPanel viewerSettings;\n    private JLabel viewerForcedHint;\n    \n    \n    private static final class SourceRootsCustomizer extends JPanel implements PropertyChangeListener {\n        \n        private static final String PREDEFINED_JDKSRC_DIR1 = \"java.base\";       // NOI18N\n        private static final String PREDEFINED_JDKSRC_DIR2 = \"java.se\";         // NOI18N\n        \n        private static final String PREDEFINED_SRC_DIR = \"src\";                 // NOI18N\n        \n        \n        private RequestProcessor processor;\n        \n        \n        SourceRootsCustomizer(Icon fileIcon) {\n            super(null);\n            \n            initUI(fileIcon);\n        }\n        \n        \n        String createRootString(String root) {\n            String[] subpaths;\n            if (commonFolderChoice.isSelected()) {\n                subpaths = subdirectoryList.getSelectedValuesList().toArray(new String[0]);\n            } else if (customFolderChoice.isSelected()) {\n                subpaths = customFolderField.getText().trim().replace(File.separator, \"/\") // NOI18N\n                                                             .replace(File.pathSeparator, \":\") // NOI18N\n                                                             .split(\":\");        // NOI18N\n            } else {\n                subpaths = null;\n            }\n            \n            String encoding = encodingSelector.getEditor().getItem().toString().trim();\n            \n            return SourcesRoot.createString(root, subpaths, encoding);\n        }\n        \n        \n        private void initUI(Icon fileIcon) {\n            setLayout(new GridBagLayout());\n            \n            GridBagConstraints c;\n            int y = 0;\n            int htab = 15;\n            int vgap = 5;\n            \n            SectionSeparator foldersSection = UISupport.createSectionSeparator(Bundle.SourcesOptionsPanel_SourcesLocation());\n            foldersSection.setFont(foldersSection.getFont().deriveFont(Font.PLAIN));\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, htab, htab - vgap, vgap);\n            add(foldersSection, c);\n            \n            selectedFolderChoice = new JRadioButton();\n            Mnemonics.setLocalizedText(selectedFolderChoice, Bundle.SourcesOptionsPanel_SelectedRootsChoice());\n            selectedFolderChoice.setToolTipText(Bundle.SourcesOptionsPanel_SelectedRootsToolTip());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, htab, vgap, vgap);\n            add(selectedFolderChoice, c);\n            \n            int htab2 = htab + 16 + selectedFolderChoice.getIconTextGap(); // 16 is typical icon width\n            \n            commonFolderChoice = new JRadioButton();\n            Mnemonics.setLocalizedText(commonFolderChoice, Bundle.SourcesOptionsPanel_SubdirectoriesChoice());\n            commonFolderChoice.setToolTipText(Bundle.SourcesOptionsPanel_SubdirectoriesToolTip());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, htab, 0, vgap);\n            add(commonFolderChoice, c);\n            \n            subdirectoryList = new JList<>();\n            DefaultListCellRenderer renderer = new DefaultListCellRenderer() {\n                @Override public void setIcon(Icon icon) { if (icon != null) super.setIcon(icon); }\n            };\n            renderer.setIcon(fileIcon);\n            subdirectoryList.setCellRenderer(renderer);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.weightx = 1;\n            c.weighty = 1;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.fill = GridBagConstraints.BOTH;\n            c.insets = new Insets(0, htab2, htab - vgap, vgap);\n            add(new JScrollPane(subdirectoryList), c);\n            \n            customFolderChoice = new JRadioButton();\n            Mnemonics.setLocalizedText(customFolderChoice, Bundle.SourcesOptionsPanel_CustomSubpathsChoice());\n            customFolderChoice.setToolTipText(Bundle.SourcesOptionsPanel_CustomSubpathsToolTip(SourcesRoot.MODULES_SUBPATH));\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, htab, 0, vgap);\n            add(customFolderChoice, c);\n            \n            customFolderField = new JTextField();\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, htab2, htab + vgap, vgap);\n            add(customFolderField, c);\n            \n            SectionSeparator encodingSection = UISupport.createSectionSeparator(Bundle.SourcesOptionsPanel_SourcesEncoding());\n            encodingSection.setFont(foldersSection.getFont());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, htab, htab - vgap, vgap);\n            add(encodingSection, c);\n            \n            encodingSelector = new JComboBox<>(Charset.availableCharsets().keySet().toArray());\n            encodingSelector.setSelectedItem(StandardCharsets.UTF_8.name());\n            encodingSelector.setEditable(true);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, htab2, htab + vgap, vgap);\n            add(encodingSelector, c);\n            \n            ButtonGroup bg = new ButtonGroup();\n            bg.add(selectedFolderChoice);\n            bg.add(commonFolderChoice);\n            bg.add(customFolderChoice);\n            \n            selectedFolderChoice.setSelected(true);\n            \n            subdirectoryList.addFocusListener(new FocusAdapter() {\n                @Override public void focusGained(FocusEvent e) { commonFolderChoice.setSelected(true); }\n            });\n            \n            customFolderField.addFocusListener(new FocusAdapter() {\n                @Override public void focusGained(FocusEvent e) { customFolderChoice.setSelected(true); }\n            });\n        }\n\n        @Override\n        public void propertyChange(PropertyChangeEvent evt) {\n            boolean empty = subdirectoryList.getModel().getSize() == 0;\n            final List<String> selected = empty ? null : subdirectoryList.getSelectedValuesList();\n            subdirectoryList.setEnabled(false);\n            \n            final File[] subdirs = (File[])evt.getNewValue();\n            \n            if (processor == null) processor = new RequestProcessor(\"Source Roots Subfoldes Processor\"); // NOI18N\n            \n            processor.post(new Runnable() {\n                public void run() {\n                    final List<String> subdirsL = getCommonSubDirs(subdirs);\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            subdirectoryList.setListData(subdirsL.toArray(new String[0]));\n                            subdirectoryList.setEnabled(true);\n                            \n                            if (selected != null && !selected.isEmpty()) {\n                                List<Integer> sel = new ArrayList<>();\n                                ListModel<String> model = subdirectoryList.getModel();\n                                for (int i = 0; i < model.getSize(); i++)\n                                    if (selected.contains(model.getElementAt(i)))\n                                        sel.add(i);\n\n                                int[] selidx = new int[sel.size()];\n                                for (int i = 0; i < selidx.length; i++)\n                                    selidx[i] = sel.get(i);\n\n                                subdirectoryList.setSelectedIndices(selidx);\n                            }\n                            \n                            // Predefined patterns\n                            if (subdirectoryList.getSelectedValue() == null) {\n                                // JDK 9+ sources\n                                if (subdirsL.contains(PREDEFINED_JDKSRC_DIR1) &&\n                                    subdirsL.contains(PREDEFINED_JDKSRC_DIR2)) {\n                                    subdirectoryList.setSelectionInterval(0, subdirectoryList.getModel().getSize() - 1);\n                                // src subfolder\n                                } else if (subdirsL.contains(PREDEFINED_SRC_DIR)) {\n                                    subdirectoryList.setSelectedValue(PREDEFINED_SRC_DIR, false);\n                                }\n                            }\n                        }\n                    });\n                }\n            });\n        }\n        \n        \n        private static List<String> getCommonSubDirs(File[] roots) {\n            if (roots == null || roots.length == 0) return Collections.emptyList();\n            \n            List<String> subdirs = null;\n            \n            for (File root : roots) {\n                List<String> rootSubdirs = getSubDirs(root);\n                Collections.sort(rootSubdirs);\n                if (subdirs == null) subdirs = rootSubdirs;\n                else subdirs.retainAll(rootSubdirs);\n            }\n            \n            return subdirs == null ? Collections.emptyList() : subdirs;\n        }\n        \n        private static List<String> getSubDirs(File root) {\n            if (root.isDirectory()) return getFolderSubDirs(root);\n            else if (root.isFile()) return getArchiveSubDirs(root);\n            else return Collections.emptyList();\n        }\n        \n        private static List<String> getFolderSubDirs(File root) {\n            List<String> rootSubdirs = new ArrayList<>();\n            \n            File[] rootSubdirsF = root.listFiles(File::isDirectory);\n            \n            for (File f : rootSubdirsF) rootSubdirs.add(f.getName());\n            \n            return rootSubdirs;\n        }\n        \n        private static List<String> getArchiveSubDirs(File root) {\n            try (FileSystem archiveFileSystem = FileSystems.newFileSystem(root.toPath(), (ClassLoader)null)) {\n                Path archive = archiveFileSystem.getRootDirectories().iterator().next();\n                List<Path> subfolders = Files.walk(archive, 1).filter(Files::isDirectory).collect(Collectors.toList());\n\n                List<String> rootSubDirs = new ArrayList<>();\n                for (Path path : subfolders) rootSubDirs.add(path.toString().replace(\"/\", \"\")); // NOI18N\n                rootSubDirs.remove(0); // remove root\n\n                return rootSubDirs;\n            } catch (Exception e) {\n                return Collections.emptyList();\n            }\n        }\n        \n        \n        private JRadioButton selectedFolderChoice;\n        private JRadioButton commonFolderChoice;\n        private JRadioButton customFolderChoice;\n        \n        private JList<String> subdirectoryList;\n        private JTextField customFolderField;\n        \n        private JComboBox<Object> encodingSelector;\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/resources/Bundle.properties",
    "content": "#\n# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-GoToSource\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/truffle/TruffleSourceHandle.java",
    "content": "/*\n * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.truffle;\n\nimport org.graalvm.visualvm.gotosource.SourceHandle;\nimport org.graalvm.visualvm.gotosource.SourceHandleUtils;\nimport org.graalvm.visualvm.gotosource.SourcePathHandle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TruffleSourceHandle extends SourceHandle {\n    \n    private final String language;\n\n    private final String className;\n    private final String methodName;\n    private final String methodSignature;\n    \n    private final int line;\n    \n    private String text;\n    \n    private int column;\n    private int offset;\n    \n    private final SourcePathHandle pathHandle;\n    \n    \n    TruffleSourceHandle(String language, String className, String methodName, String methodSignature, int line, SourcePathHandle pathHandle) {\n        this.language = language;\n        \n        this.className = className;\n        this.methodName = methodName;\n        this.methodSignature = methodSignature;\n        \n        this.line = line;\n        \n        this.offset = -1;\n        this.column = -1;\n        \n        this.pathHandle = pathHandle;\n    }\n    \n    \n    @Override\n    public String getLanguage() {\n        return language;\n    }\n    \n\n    @Override\n    public String getClassName() {\n        return className;\n    }\n\n    @Override\n    public String getMethodName() {\n        return methodName;\n    }\n\n    @Override\n    public String getMethodSignature() {\n        return methodSignature;\n    }\n\n    \n    @Override\n    public int getLine() {\n        return line;\n    }\n    \n    @Override\n    public int getColumn() {\n        if (column == -1) {\n            column = 1;\n        }\n        return column;\n    }\n\n    @Override\n    public int getOffset() {\n        if (offset == -1) offset = SourceHandleUtils.lineToOffset(getText(), getLine());\n        return offset;\n    }\n\n    \n    @Override\n    public String getText() {\n        if (text == null) text = pathHandle.readText();\n        return text;\n    }\n\n    \n    @Override\n    public String getSourceUri() {\n        return pathHandle.getPath().toUri().toString();\n    }\n\n    @Override\n    public String getSourceFile() {\n        return pathHandle.getRegularPath().toAbsolutePath().toString();\n    }\n\n    \n    @Override\n    protected void close() {\n        pathHandle.close();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/truffle/TruffleSourceHandleProvider.java",
    "content": "/*\n * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.truffle;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.gotosource.SourceHandle;\nimport org.graalvm.visualvm.gotosource.SourceHandleProvider;\nimport org.graalvm.visualvm.gotosource.SourcePathHandle;\nimport org.graalvm.visualvm.gotosource.SourcesRoot;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"# {0} - language\",\n    \"TruffleSourceHandleProvider_ObjectsNotSupported=Opening {0} objects source not supported yet.\" // NOI18N\n})\n@ServiceProvider(service=SourceHandleProvider.class, position = 50)\npublic final class TruffleSourceHandleProvider extends SourceHandleProvider {\n    \n    // {<truffle language prefix>, <language id>}\n    private static final String[] JS_LANG_ID = new String[]     {\"js\", \"javascript\"};   // NOI18N\n    private static final String[] RUBY_LANG_ID = new String[]   {\"ruby\", \"ruby\"};       // NOI18N\n    private static final String[] R_LANG_ID = new String[]      {\"R\", \"r\"};             // NOI18N\n    private static final String[] PYTHON_LANG_ID = new String[] {\"python\", \"python\"};   // NOI18N\n    \n    private static final Map<String, String> SUPPORTED_LANGUAGES = new HashMap<>();\n    static {\n        SUPPORTED_LANGUAGES.put(JS_LANG_ID[0],      JS_LANG_ID[1]);\n        SUPPORTED_LANGUAGES.put(RUBY_LANG_ID[0],    RUBY_LANG_ID[1]);\n        SUPPORTED_LANGUAGES.put(R_LANG_ID[0],       R_LANG_ID[1]);\n        SUPPORTED_LANGUAGES.put(PYTHON_LANG_ID[0],  PYTHON_LANG_ID[1]);\n    }\n    \n    \n    @Override\n    public SourceHandle createHandle(String className, String methodName, String methodSignature, int line) {        \n        int langIdIdx = className.indexOf('.');                                 // NOI18N\n        String langId = langIdIdx == -1 ? className : className.substring(0, langIdIdx);\n        String language = SUPPORTED_LANGUAGES.get(langId);\n        \n        if (language != null) {\n//            if (langIdIdx != -1) className = className.substring(langIdIdx + 1);\n            if (langIdIdx != -1) {\n                ProfilerDialogs.displayError(Bundle.TruffleSourceHandleProvider_ObjectsNotSupported(language));\n                return SourceHandle.EMPTY;\n            }\n            \n            String fileLine = methodSignature.substring(2, methodSignature.length() - 4);\n            String[] fileAndLine = fileLine.split(\":\");                         // NOI18N\n            \n            SourcePathHandle pathHandle = SourcesRoot.getPathHandle(fileAndLine[0]);\n            return pathHandle == null ? null : new TruffleSourceHandle(language, className, methodName, methodSignature, Integer.parseInt(fileAndLine[1]), pathHandle);\n        }\n        \n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/viewer/ExternalSourcesViewer.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.viewer;\n\nimport org.graalvm.visualvm.gotosource.SourcesViewer;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.JComponent;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JTextField;\nimport javax.swing.SwingConstants;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.Document;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.SmallButton;\nimport org.graalvm.visualvm.gotosource.SourceHandle;\nimport org.netbeans.api.options.OptionsDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ExternalSourcesViewer_CommandHint=<select a predefined command or define a custom one>\", // NOI18N\n    \"ExternalSourcesViewer_Name=External Viewer\",                               // NOI18N\n    \"ExternalSourcesViewer_Description=custom command to launch an external viewer\", // NOI18N\n    \"ExternalSourcesViewer_NotConfiguredCaption=Go To Source\",     // NOI18N\n    \"ExternalSourcesViewer_NotConfigured=<html><br><b>Sources viewer has not been configured yet.</b><br><br>Use Options | Sources | Viewer to define the external IDE or editor to open the sources.<br><br>Customize a predefined template from the popup list or define a custom command using<br>the available parameters to launch the external sources viewer.<br><br>Alternatively choose to use a viewer registered in the OS (preselecting line not supported).</html>\",     // NOI18N\n    \"# {0} - error message\",\n    \"ExternalSourcesViewer_CommandFailed=Failed to open source in external viewer.\\n\\n{0}\", // NOI18N\n    \"ExternalSourcesViewer_CommandLabel=&Command:\",                             // NOI18N\n    \"ExternalSourcesViewer_RootsDialogCaption=Select File Or Directory\",        // NOI18N\n    \"ExternalSourcesViewer_RootsDialogButton=Select\",                           // NOI18N\n    \"ExternalSourcesViewer_OpenRootsDialogToolTip=Insert file or directory\",    // NOI18N\n    \"ExternalSourcesViewer_InsertCommandToolTip=Insert predefined command or parameter\" // NOI18N\n})\n@ServiceProvider(service=SourcesViewer.class, position = 300)\npublic final class ExternalSourcesViewer extends SourcesViewer {\n    \n    private static final Logger LOGGER = Logger.getLogger(ExternalSourcesViewer.class.getName());\n    \n    public static final String ID = \"ExternalSourcesViewer\";                    // NOI18N\n    \n    private static final String PROP_COMMAND = \"prop_ExternalSourcesViewer_command\"; // NOI18N\n    private static final String DEFAULT_COMMAND = Bundle.ExternalSourcesViewer_CommandHint();\n    \n    \n    private static enum IdePreset {\n        \n        NETBEANS(\"NetBeans\", \"netbeans \" + SourceHandle.Feature.FILE.getCode() + \":\" + SourceHandle.Feature.LINE.getCode()), // NOI18N\n        ECLIPSE(\"Eclipse\", \"eclipse \" + SourceHandle.Feature.FILE.getCode() + \":\" + SourceHandle.Feature.LINE.getCode()), // NOI18N\n        IDEA(\"IntelliJ IDEA\", \"idea --line \" + SourceHandle.Feature.LINE.getCode() + \" --column \" + SourceHandle.Feature.COLUMN.getCode() + \" \" + SourceHandle.Feature.FILE.getCode()), // NOI18N\n        VSCODE(\"Visual Studio Code\", \"code -g \" + SourceHandle.Feature.FILE.getCode() + \":\" + SourceHandle.Feature.LINE.getCode()), // NOI18N\n        XCODE(\"Xcode\", \"open -a Xcode \" + SourceHandle.Feature.FILE.getCode()); // NOI18N\n        \n        private final String name;\n        private final String command;\n        \n        IdePreset(String name, String command) {\n            this.name = name;\n            this.command = command;\n        }\n        \n        String getName() { return name; }\n        String getCommand() { return command; }\n        \n        @Override public String toString() { return getName(); }\n        \n        static IdePreset[] sorted() {\n            IdePreset[] commands = values();\n            Arrays.sort(commands, new Comparator<IdePreset>() {\n                @Override\n                public int compare(IdePreset c1, IdePreset c2) {\n                    return c1.name.compareTo(c2.name);\n                }\n            });\n            return commands;\n        }\n        \n    }\n\n    private static enum ToolPreset {\n        \n        NOTEPAD(\"Notepad\", \"notepad.exe \" + SourceHandle.Feature.FILE.getCode()), // NOI18N\n        NOTEPADPP(\"Notepad++\", \"notepad++ -p\" + SourceHandle.Feature.OFFSET.getCode() + \" \" + SourceHandle.Feature.FILE.getCode()), // NOI18N\n        GEDIT(\"Gedit\", \"gedit +\" + SourceHandle.Feature.LINE.getCode() + \" \" + SourceHandle.Feature.FILE.getCode()), // NOI18N\n        EMACS(\"Emacs\", \"emacs +\" + SourceHandle.Feature.LINE.getCode() + \":\" + SourceHandle.Feature.COLUMN.getCode() + \" \" + SourceHandle.Feature.FILE.getCode()), // NOI18N\n        KATE(\"Kate\", \"kate -l \" + SourceHandle.Feature.LINE.getCode() + \" -c \" + SourceHandle.Feature.COLUMN.getCode() + \" \" + SourceHandle.Feature.FILE.getCode()); // NOI18N\n        \n        private final String name;\n        private final String command;\n        \n        ToolPreset(String name, String command) {\n            this.name = name;\n            this.command = command;\n        }\n        \n        String getName() { return name; }\n        String getCommand() { return command; }\n        \n        @Override public String toString() { return getName(); }\n        \n        static ToolPreset[] sorted() {\n            ToolPreset[] commands = values();\n            Arrays.sort(commands, new Comparator<ToolPreset>() {\n                @Override\n                public int compare(ToolPreset c1, ToolPreset c2) {\n                    return c1.name.compareTo(c2.name);\n                }\n            });\n            return commands;\n        }\n        \n    }\n\n\n    private final String forcedCommand;\n    \n    private JPanel settingsPanel;\n    private JTextField commandField;\n    \n    \n    public ExternalSourcesViewer() {\n        this(null);\n    }\n    \n    public ExternalSourcesViewer(String forcedCommand) {\n        super(ID, Bundle.ExternalSourcesViewer_Name(), Bundle.ExternalSourcesViewer_Description());\n        this.forcedCommand = forcedCommand;\n    }\n\n    \n    @Override\n    public boolean open(SourceHandle handle) {\n        String command = getCommand();\n        \n        if (command.isEmpty() || command.equals(DEFAULT_COMMAND)) configureCommand();\n        else executeCommand(handle, command);\n                \n        return true;\n    }\n    \n    \n    @Override\n    public void loadSettings() {\n        if (forcedCommand == null && settingsPanel != null) commandField.setText(getCommand());\n    }\n    \n    @Override\n    public void saveSettings() {\n        if (forcedCommand == null && settingsPanel != null) saveCommand(commandField.getText().trim());\n    }\n    \n    @Override\n    public boolean settingsDirty() {\n        return forcedCommand == null && settingsPanel != null && !commandField.getText().trim().equals(getCommand());\n    }\n    \n    \n    private void saveCommand(String command) {\n        if (forcedCommand == null) NbPreferences.forModule(ExternalSourcesViewer.class).put(PROP_COMMAND, command);\n    }\n    \n    private String getCommand() {\n        return forcedCommand == null ? NbPreferences.forModule(ExternalSourcesViewer.class).get(PROP_COMMAND, DEFAULT_COMMAND).trim() : forcedCommand;\n    }\n    \n    \n    private static void configureCommand() {\n        ProfilerDialogs.displayWarning(Bundle.ExternalSourcesViewer_NotConfigured(), Bundle.ExternalSourcesViewer_NotConfiguredCaption(), null);\n        OptionsDisplayer.getDefault().open(\"SourcesOptions\");                   // NOI18N\n    }\n    \n    private static void executeCommand(SourceHandle handle, String commandS) {\n        List<String> commandL = ExternalViewerLauncher.getCommandStrings(commandS);\n\n        for (int i = 0; i < commandL.size(); i++) {\n            String commandI = commandL.get(i);\n            if (i == 0) { // first command should be path to viewer executable\n                if ((commandI.startsWith(\"'\") && commandI.endsWith(\"'\")) ||   // NOI18N\n                    (commandI.startsWith(\"\\\"\") && commandI.endsWith(\"\\\"\"))) {   // NOI18N\n                    commandI = commandI.substring(1, commandI.length() - 1);\n                    commandL.set(i, commandI);\n                }\n            } else { // other commands may be feature wildcards\n                commandI = handle.expandFeatures(commandI);\n                commandL.set(i, commandI);\n            }\n        }\n\n        new ExternalViewerLauncher(commandL) {\n            @Override protected void failed(IOException e)     {\n                ProfilerDialogs.displayError(Bundle.ExternalSourcesViewer_CommandFailed(e.getMessage()));\n                LOGGER.log(Level.INFO, \"Opening external sources viewer failed\", e); // NOI18N\n            }\n        }.run();\n    }\n    \n    \n    @Override\n    public JComponent getSettingsComponent() {\n        if (settingsPanel == null) {\n            settingsPanel = new JPanel(null);\n            settingsPanel.setLayout(new BoxLayout(settingsPanel, BoxLayout.LINE_AXIS));\n            settingsPanel.setOpaque(false);\n            \n            int tab = 15;\n            int gap = 5;\n            \n            JLabel parametersCaption = new JLabel();\n            Mnemonics.setLocalizedText(parametersCaption, Bundle.ExternalSourcesViewer_CommandLabel());\n            settingsPanel.add(parametersCaption);\n            \n            settingsPanel.add(Box.createHorizontalStrut(gap));\n            \n            commandField = new JTextField(getCommand());\n            parametersCaption.setLabelFor(commandField);\n            settingsPanel.add(commandField);\n            \n            settingsPanel.add(Box.createHorizontalStrut(gap));\n            \n            SmallButton fileChooser = new SmallButton(\"...\") {                  // NOI18N\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    \n                    JFileChooser fileChooser = new JFileChooser((String)null);\n                    fileChooser.setDialogTitle(Bundle.ExternalSourcesViewer_RootsDialogCaption());\n                    fileChooser.setApproveButtonText(Bundle.ExternalSourcesViewer_RootsDialogButton());\n                    fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);\n                    \n                    if (fileChooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION)\n                        insertFile(commandField, fileChooser.getSelectedFile());\n                }\n            };\n            fileChooser.setToolTipText(Bundle.ExternalSourcesViewer_OpenRootsDialogToolTip());\n            settingsPanel.add(fileChooser);\n            \n            settingsPanel.add(Box.createHorizontalStrut(gap));\n            \n            PopupButton parametersPopup = new PopupButton() {\n                protected void populatePopup(JPopupMenu popup) {\n                    IdePreset[] ides = IdePreset.sorted();\n                    for (IdePreset ide : ides) {\n                        final String command = ide.getCommand();\n                        JMenuItem item = new JMenuItem(ide.getName()) {\n                            protected void fireActionPerformed(ActionEvent e) {\n                                super.fireActionPerformed(e);\n                                commandField.setText(command);\n                            }\n                        };\n                        popup.add(item);\n                    }\n                    \n                    popup.addSeparator();\n                    \n                    ToolPreset[] tools = ToolPreset.sorted();\n                    for (ToolPreset tool : tools) {\n                        final String command = tool.getCommand();\n                        JMenuItem item = new JMenuItem(tool.getName()) {\n                            protected void fireActionPerformed(ActionEvent e) {\n                                super.fireActionPerformed(e);\n                                commandField.setText(command);\n                            }\n                        };\n                        popup.add(item);\n                    }\n                    \n                    popup.addSeparator();\n                    \n                    SourceHandle.Feature[] features = SourceHandle.Feature.values();\n                    \n                    int longestCode = 0;\n                    for (SourceHandle.Feature feature : features)\n                        longestCode = Math.max(longestCode, feature.getCode().length());\n                    \n                    for (SourceHandle.Feature feature : features) {\n                        final String parameter = feature.getCode();\n                        String val = \"<html><code>\" + appendSpaces(parameter, longestCode) + \"&nbsp;&nbsp;</code>\" + feature.getName() + \"</html>\"; // NOI18N\n                        JMenuItem item = new JMenuItem(val) {\n                            protected void fireActionPerformed(ActionEvent e) {\n                                super.fireActionPerformed(e);\n                                insertParameter(commandField, parameter);\n                            }\n                        };\n                        popup.add(item);\n                    }\n                }\n            };\n            parametersPopup.setToolTipText(Bundle.ExternalSourcesViewer_InsertCommandToolTip());\n            parametersPopup.setPopupAlign(SwingConstants.NORTH);\n            settingsPanel.add(parametersPopup);\n            \n            Dimension dim = parametersPopup.getPreferredSize();\n            fileChooser.setPreferredSize(dim);\n            fileChooser.setMinimumSize(dim);\n            fileChooser.setMaximumSize(dim);\n\n            if (forcedCommand != null) {\n                commandField.setEditable(false);\n                fileChooser.setEnabled(false);\n                parametersPopup.setEnabled(false);\n            }\n        }\n        \n        return settingsPanel;\n    }\n    \n    \n    private static String appendSpaces(String string, int targetLength) {\n        int spacesToAdd = targetLength - string.length();\n        for (int i = 0; i < spacesToAdd; i++) string += \"&nbsp;\";               // NOI18N\n        return string;\n    }\n    \n    private static void insertFile(JTextField textField, File file) {\n        String path = file.getAbsolutePath();\n        if (path.contains(\" \")) path = \"\\\"\" + path + \"\\\"\";                      // NOI18N\n        \n//        try { textField.getDocument().insertString(textField.getCaretPosition(), path, null); }\n        try {\n            textField.getDocument().insertString(0, path, null);\n            textField.select(0, path.length());\n            textField.requestFocusInWindow();\n        } catch (BadLocationException ex) {}\n    }\n    \n    private static void insertParameter(JTextField textField, String parameter) {\n        Document document = textField.getDocument();\n        int length = document.getLength();\n        int position = textField.getCaretPosition();\n        \n        try { \n            if (position > 0 && !\" \".equals(document.getText(position - 1, 1))) // NOI18N\n                parameter = \" \" + parameter;                                    // NOI18N\n            if (position < length - 1 && !\" \".equals(document.getText(position, 1))) // NOI18N\n                parameter = parameter + \" \";                                    // NOI18N\n            \n            textField.getDocument().insertString(position, parameter, null);\n        } catch (BadLocationException ex) {}\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/viewer/ExternalViewerLauncher.java",
    "content": "/*\n * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.viewer;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport org.graalvm.visualvm.core.datasource.Storage;\n\n/**\n * @author Jiri Sedlacek\n */\nclass ExternalViewerLauncher implements Runnable {\n    \n    private static final String COMMAND_STRINGS_REGEX = \"\\'[^\\']*\\'|\\\"[^\\\"]*\\\"|\\\\S+\"; // NOI18N\n    \n    \n    private final List<String> command;\n    \n    \n    ExternalViewerLauncher(List<String> command) {\n        this.command = command;\n    }\n    \n    \n    public final void run() {\n        ProcessBuilder builder = new ProcessBuilder();\n        builder.command(command);\n        builder.directory(Storage.getTemporaryStorageDirectory());\n        \n        try { builder.start(); }\n        catch (IOException e) { failed(e); }\n    }\n    \n        \n    protected void failed(IOException e) {}\n    \n    \n    public static List<String> getCommandStrings(String commandString) {\n        List<String> command = new ArrayList<>();\n        \n        Pattern pattern = Pattern.compile(COMMAND_STRINGS_REGEX);\n        Matcher matcher = pattern.matcher(commandString);\n        while (matcher.find()) command.add(matcher.group());\n        \n        return command;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/viewer/RegisteredSourcesViewer.java",
    "content": "/*\n * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.viewer;\n\nimport org.graalvm.visualvm.gotosource.SourcesViewer;\nimport java.awt.Desktop;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.ButtonGroup;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JRadioButton;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.gotosource.SourceHandle;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"RegisteredSourcesViewer_Name=Registered Viewer\",                           // NOI18N\n    \"RegisteredSourcesViewer_Description=viewer registered in the operating system\", // NOI18N\n    \"# {0} - error message\",\n    \"RegisteredSourcesViewer_CommandFailed=Failed to open source in registered viewer.\\n\\n{0}\", // NOI18N\n    \"RegisteredSourcesViewer_ModeLabel=Mode:\",                                  // NOI18N\n    \"RegisteredSourcesViewer_OpenChoice=O&pen\",                                 // NOI18N\n    \"RegisteredSourcesViewer_EditChoice=&Edit\"                                  // NOI18N\n})\n@ServiceProvider(service=SourcesViewer.class, position = 200)\npublic final class RegisteredSourcesViewer extends SourcesViewer {\n    \n    private static final Logger LOGGER = Logger.getLogger(RegisteredSourcesViewer.class.getName());\n    \n    private static final String ID = \"RegisteredSourcesViewer\";                 // NOI18N\n    \n    private static final String PROP_MODE = \"prop_RegisteredSourcesViewer_mode\"; // NOI18N\n    private static final boolean DEFAULT_MODE = Boolean.FALSE;\n    \n    \n    private JPanel settingsPanel;\n    private JRadioButton openChoice;\n    private JRadioButton editChoice;\n    \n    \n    public RegisteredSourcesViewer() {\n        super(ID, Bundle.RegisteredSourcesViewer_Name(), Bundle.RegisteredSourcesViewer_Description());\n    }\n\n    \n    @Override\n    public boolean open(SourceHandle handle) {\n        try {\n            if (isEdit()) Desktop.getDesktop().edit(new File(handle.getSourceFile()));\n            else Desktop.getDesktop().open(new File(handle.getSourceFile()));\n        } catch (IOException ex) {\n            ProfilerDialogs.displayError(Bundle.RegisteredSourcesViewer_CommandFailed(ex.getMessage()));\n            LOGGER.log(Level.INFO, \"Failed to open source \" + handle.getSourceFile(), ex); // NOI18N\n        }\n        \n        return true;\n    }\n    \n    \n    @Override\n    public void loadSettings() {\n        if (settingsPanel != null) {\n            boolean edit = isEdit();\n            openChoice.setSelected(!edit);\n            editChoice.setSelected(edit);\n        }\n    }\n    \n    @Override\n    public void saveSettings() {\n        if (settingsPanel != null) saveEdit(editChoice.isSelected());\n    }\n    \n    @Override\n    public boolean settingsDirty() {\n        return settingsPanel != null && isEdit() != editChoice.isSelected();\n    }\n    \n    \n    private void saveEdit(boolean edit) {\n        NbPreferences.forModule(RegisteredSourcesViewer.class).putBoolean(PROP_MODE, edit);\n    }\n    \n    private boolean isEdit() {\n        return NbPreferences.forModule(RegisteredSourcesViewer.class).getBoolean(PROP_MODE, DEFAULT_MODE);\n    }\n    \n    \n    @Override\n    public JComponent getSettingsComponent() {\n        if (settingsPanel == null) {\n            settingsPanel = new JPanel(null);\n            settingsPanel.setLayout(new BoxLayout(settingsPanel, BoxLayout.LINE_AXIS));\n            settingsPanel.setOpaque(false);\n            \n            int tab = 15;\n            int gap = 5;\n            \n            JLabel modeCaption = new JLabel();\n            Mnemonics.setLocalizedText(modeCaption, Bundle.RegisteredSourcesViewer_ModeLabel());\n            settingsPanel.add(modeCaption);\n            \n            settingsPanel.add(Box.createHorizontalStrut(gap));\n            \n            openChoice = new JRadioButton();\n            Mnemonics.setLocalizedText(openChoice, Bundle.RegisteredSourcesViewer_OpenChoice());\n            settingsPanel.add(openChoice);\n            \n            settingsPanel.add(Box.createHorizontalStrut(gap));\n            \n            editChoice = new JRadioButton();\n            Mnemonics.setLocalizedText(editChoice, Bundle.RegisteredSourcesViewer_EditChoice());\n            settingsPanel.add(editChoice);\n            \n            ButtonGroup bg = new ButtonGroup();\n            bg.add(openChoice);\n            bg.add(editChoice);\n            \n            boolean edit = isEdit();\n            openChoice.setSelected(!edit);\n            editChoice.setSelected(edit);\n        }\n        \n        return settingsPanel;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/viewer/internal/InternalSourceAppearance.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.viewer.internal;\n\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GraphicsEnvironment;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport java.util.prefs.Preferences;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.JComboBox;\nimport javax.swing.JComponent;\nimport javax.swing.JFormattedTextField;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JSpinner;\nimport javax.swing.JTextArea;\nimport javax.swing.SpinnerNumberModel;\nimport javax.swing.text.DefaultFormatter;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"InternalSourceAppearance_FontPlain=Plain\",                                 // NOI18N\n    \"InternalSourceAppearance_FontBold=Bold\",                                   // NOI18N\n    \"InternalSourceAppearance_FontItalic=Italic\",                               // NOI18N\n    \"InternalSourceAppearance_FontBoldItalic=Bold Italic\",                      // NOI18N\n    \"InternalSourceAppearance_FontLabel=&Font:\",                                // NOI18N\n    \"InternalSourceAppearance_StyleLabel=S&tyle:\",                              // NOI18N\n    \"InternalSourceAppearance_SizeLabel=S&ize:\"                                 // NOI18N\n})\nfinal class InternalSourceAppearance {\n    \n    private static final String PROP_FONT_NAME = \"prop_InternalSourceAppearance_fontName\";      // NOI18N\n    private static final String PROP_FONT_STYLE = \"prop_InternalSourceAppearance_fontStyle\";    // NOI18N\n    private static final String PROP_FONT_SIZE = \"prop_InternalSourceAppearance_fontSize\";      // NOI18N\n    \n    private static final int DEFAULT_FONT_STYLE = Font.PLAIN;\n    private static final int DEFAULT_FONT_SIZE = new JTextArea().getFont().getSize();\n    private static final String DEFAULT_FONT_NAME = new Font(Font.MONOSPACED, DEFAULT_FONT_STYLE, DEFAULT_FONT_SIZE).getName();\n    \n    \n    private static enum FontStyle {\n        \n        PLAIN(Font.PLAIN, Bundle.InternalSourceAppearance_FontPlain()),\n        BOLD(Font.BOLD, Bundle.InternalSourceAppearance_FontBold()),\n        ITALIC(Font.ITALIC, Bundle.InternalSourceAppearance_FontItalic()),\n        BOLD_ITALIC(Font.BOLD | Font.ITALIC, Bundle.InternalSourceAppearance_FontBoldItalic());\n        \n        \n        private final int style;\n        private final String name;\n        \n        FontStyle(int style, String name) {\n            this.style = style;\n            this.name = name;\n        }\n        \n        int getStyle() { return style; }\n        String getName() { return name; }\n        \n        @Override public String toString() { return getName(); }\n        \n        static FontStyle fromStyle(int style) {\n            switch (style) {\n                case Font.PLAIN: return PLAIN;\n                case Font.BOLD: return BOLD;\n                case Font.ITALIC: return ITALIC;\n                default: return BOLD_ITALIC;\n            }\n        }\n        \n    }\n    \n    \n    private final PropertyChangeSupport changeSupport;\n    \n    private JPanel settingsPanel;\n    \n    \n    InternalSourceAppearance() {\n        changeSupport = new PropertyChangeSupport(this);\n    }\n    \n    \n    Font getFont() {\n        Preferences preferences = NbPreferences.forModule(InternalSourceAppearance.class);\n        return new Font(savedFontName(preferences), savedFontStyle(preferences), savedFontSize(preferences));\n    }\n    \n    \n    void addListener(PropertyChangeListener listener) {\n        changeSupport.addPropertyChangeListener(listener);\n    }\n    \n    void removeListener(PropertyChangeListener listener) {\n        changeSupport.removePropertyChangeListener(listener);\n    }\n    \n    \n    void loadSettings() {\n        if (settingsPanel == null) return;\n        \n        Preferences settings = NbPreferences.forModule(InternalSourceAppearance.class);\n        fontSelect.setSelectedItem(savedFontName(settings));\n        styleSelect.setSelectedItem(FontStyle.fromStyle(savedFontStyle(settings)));\n        sizeSelect.setValue(Integer.valueOf(savedFontSize(settings)));\n    }\n    \n    void saveSettings() {\n        if (settingsPanel == null || !currentSettingsDirty()) return;\n        \n        Preferences settings = NbPreferences.forModule(InternalSourceAppearance.class);\n        settings.put(PROP_FONT_NAME, currentFontName());\n        settings.putInt(PROP_FONT_STYLE, currentFontStyle());\n        settings.putInt(PROP_FONT_SIZE, currentFontSize());\n        \n        changeSupport.firePropertyChange(new PropertyChangeEvent(this, \"appearance\", null, null)); // NOI18N\n    }\n    \n    boolean currentSettingsDirty() {\n        if (settingsPanel == null) return false;\n        \n        Preferences settings = NbPreferences.forModule(InternalSourceAppearance.class);\n        if (!currentFontName().equals(savedFontName(settings))) return true;\n        if (currentFontStyle() != savedFontStyle(settings)) return true;\n        if (currentFontSize() != savedFontSize(settings)) return true;\n        \n        return false;\n    }\n    \n    \n    private String savedFontName(Preferences preferences) {\n        return preferences.get(PROP_FONT_NAME, DEFAULT_FONT_NAME).trim();\n    }\n    \n    private String currentFontName() {\n        return fontSelect.getEditor().getItem().toString().trim();\n    }\n    \n    private int savedFontStyle(Preferences preferences) {\n        return preferences.getInt(PROP_FONT_STYLE, DEFAULT_FONT_STYLE);\n    }\n    \n    private int currentFontStyle() {\n        return ((FontStyle)styleSelect.getSelectedItem()).getStyle();\n    }\n    \n    private int savedFontSize(Preferences preferences) {\n        return preferences.getInt(PROP_FONT_SIZE, DEFAULT_FONT_SIZE);\n    }\n    \n    private int currentFontSize() {\n        try {\n            return Integer.parseInt(((JSpinner.DefaultEditor)sizeSelect.getEditor()).getTextField().getText().trim());\n        } catch (Exception e) {\n            return ((Integer)sizeSelect.getValue()).intValue();\n        }\n    }\n    \n    \n    JComponent getSettingsComponent() {\n        if (settingsPanel == null) {\n            settingsPanel = new JPanel(null);\n            settingsPanel.setLayout(new BoxLayout(settingsPanel, BoxLayout.LINE_AXIS));\n            settingsPanel.setOpaque(false);\n            \n            int tab = 15;\n            int gap = 5;\n            \n            JLabel fontCaption = new JLabel();\n            Mnemonics.setLocalizedText(fontCaption, Bundle.InternalSourceAppearance_FontLabel());\n            settingsPanel.add(fontCaption);\n            \n            settingsPanel.add(Box.createHorizontalStrut(gap));\n            \n            fontSelect = new JComboBox<>(getAvailableFonts(false));\n            fontSelect.setSelectedItem(new Font(Font.MONOSPACED, Font.PLAIN, 12).getName());\n            Dimension dim = fontSelect.getMinimumSize();\n            dim.width = 20;\n            fontSelect.setMinimumSize(dim);\n            fontSelect.setMaximumSize(fontSelect.getPreferredSize());\n            fontSelect.setEditable(true);\n            fontCaption.setLabelFor(fontSelect);\n            settingsPanel.add(fontSelect);\n            \n            settingsPanel.add(Box.createHorizontalStrut(tab));\n            \n            JLabel styleCaption = new JLabel();\n            Mnemonics.setLocalizedText(styleCaption, Bundle.InternalSourceAppearance_StyleLabel());\n            settingsPanel.add(styleCaption);\n            \n            settingsPanel.add(Box.createHorizontalStrut(gap));\n            \n            styleSelect = new JComboBox<>(FontStyle.values());\n            styleSelect.setPreferredSize(styleSelect.getMinimumSize());\n            styleSelect.setMaximumSize(styleSelect.getMinimumSize());\n            styleCaption.setLabelFor(styleSelect);\n            settingsPanel.add(styleSelect);\n            \n            settingsPanel.add(Box.createHorizontalStrut(tab));\n            \n            JLabel sizeCaption = new JLabel();\n            Mnemonics.setLocalizedText(sizeCaption, Bundle.InternalSourceAppearance_SizeLabel());\n            settingsPanel.add(sizeCaption);\n            \n            settingsPanel.add(Box.createHorizontalStrut(gap));\n            \n            sizeSelect = new JSpinner(new SpinnerNumberModel(sizeCaption.getFont().getSize(), 1, 99, 1));\n            try {\n                JFormattedTextField editor = ((JSpinner.DefaultEditor)sizeSelect.getEditor()).getTextField();\n                ((DefaultFormatter)editor.getFormatter()).setAllowsInvalid(false);\n            } catch (Exception e) {}\n            sizeSelect.setPreferredSize(sizeSelect.getMinimumSize());\n            sizeSelect.setMaximumSize(sizeSelect.getMinimumSize());\n            sizeCaption.setLabelFor(sizeSelect);\n            settingsPanel.add(sizeSelect);\n            \n            loadSettings();\n        }\n        \n        return settingsPanel;\n    }\n    \n    \n    private static String[] getAvailableFonts(boolean monospaced) {\n        return GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();\n    }\n    \n    \n    private JComboBox<String> fontSelect;\n    private JComboBox<FontStyle> styleSelect;\n    private JSpinner sizeSelect;\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/viewer/internal/InternalSourceViewerComponent.java",
    "content": "/*\n * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.viewer.internal;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport java.awt.Shape;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTable;\nimport javax.swing.JTextArea;\nimport javax.swing.JViewport;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.CaretEvent;\nimport javax.swing.event.CaretListener;\nimport javax.swing.table.AbstractTableModel;\nimport javax.swing.table.DefaultTableCellRenderer;\nimport javax.swing.table.TableModel;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.DefaultHighlighter;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.View;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class InternalSourceViewerComponent extends JPanel implements PropertyChangeListener {\n    \n    private InternalSourceAppearance appearance;\n    \n    private final SourceArea sourceArea;\n    private final LineNumbers lineNumbers;\n    private final JViewport lineNumbersViewport;\n    private final JPanel lineNumbersPanel;\n    \n    \n    public InternalSourceViewerComponent(String text, int offset, int endOffset, InternalSourceAppearance appearance) {\n        super(new BorderLayout());\n        \n        sourceArea = new SourceArea();\n        \n        this.appearance = appearance;\n        appearance.addListener(this);\n        propertyChange(null);\n        \n        sourceArea.setText(text);\n        setOffset(offset, endOffset);\n        \n        lineNumbersPanel = new JPanel(new BorderLayout());\n        lineNumbersPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 10));\n        lineNumbers = new LineNumbers(sourceArea);\n        lineNumbersPanel.add(lineNumbers, BorderLayout.EAST);\n        \n        lineNumbersViewport = new JViewport();\n        lineNumbersViewport.setView(lineNumbersPanel);\n        lineNumbersViewport.setPreferredSize(lineNumbersPanel.getPreferredSize());\n        \n        JScrollPane scrollPane = new JScrollPane(sourceArea);\n        scrollPane.setBorder(BorderFactory.createEmptyBorder());\n        scrollPane.setViewportBorder(BorderFactory.createEmptyBorder());\n        scrollPane.setRowHeader(lineNumbersViewport);\n        \n        add(scrollPane, BorderLayout.CENTER);\n    }\n    \n    \n    @Override\n    public void propertyChange(PropertyChangeEvent evt) {\n        sourceArea.setFont(appearance.getFont());\n        if (lineNumbers != null) {\n            lineNumbers.updateAppearance(sourceArea);\n            lineNumbersViewport.setPreferredSize(lineNumbersPanel.getPreferredSize());\n            validate();\n            repaint();\n        }\n    }\n    \n    \n    void setOffset(final int offset, final int endOffset) {\n        sourceArea.setOffset(offset);\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { sourceArea.select(offset, endOffset); }\n        });\n    }\n    \n    \n    void cleanup() {\n        appearance.removeListener(this);\n        appearance = null;\n    }\n    \n    \n    Component defaultFocusOwner() {\n        return sourceArea;\n    }\n    \n    \n    private static class SourceArea extends JTextArea implements CaretListener {\n        \n        private int pendingOffset = -1;\n        \n        private Object rowHighlight;\n        private final LineHighlightPainter highlightPainter;\n        \n        \n        SourceArea() {\n            super();\n        \n            setEditable(false);\n            setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 5));\n            \n            highlightPainter = new LineHighlightPainter();\n            addCaretListener(this);\n            \n            MouseAdapter adapter = new MouseAdapter() {\n                public void mousePressed(MouseEvent e) {\n                    setHighlight(SourceArea.this.getCaret().getDot());\n                }\n                public void mouseDragged(MouseEvent e) {\n                    setHighlight(SourceArea.this.getCaret().getDot());\n                }\n            };\n            \n            addMouseListener(adapter);\n            addMouseMotionListener(adapter);\n        }\n        \n        protected int getRowHeight() {\n            return super.getRowHeight();\n        }\n        \n        void setOffset(int offset) {\n            setCaretPosition(offset);\n            scrollToOffset(offset);\n        }\n        \n        private void scrollToOffset(int offset) {\n            if (isValid()) {\n                try {\n                    Rectangle offsetRect = modelToView(offset);\n                    if (offsetRect != null) {\n                        int rowHeight = getRowHeight();\n                        int currentHeight = getVisibleRect().height;\n                        int margin = (currentHeight - rowHeight) / 2;\n                        offsetRect.y -= margin;\n                        offsetRect.height += (margin * 2);\n                        scrollRectToVisible(offsetRect);\n                    }\n                } catch (BadLocationException ex) {}\n            } else {\n                pendingOffset = offset;\n            }\n        }\n        \n        public void validate() {\n            super.validate();\n            if (pendingOffset != -1) {\n                scrollToOffset(pendingOffset);\n                pendingOffset = -1;\n            }\n        }\n        \n        public void requestFocus() {\n            super.requestFocus();\n            setHighlight(getCaretPosition());\n        }\n\n        \n        @Override\n        public void caretUpdate(CaretEvent e) {\n            setHighlight(e.getDot());\n        }\n        \n        \n        public void setHighlight(final int dot) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    if (rowHighlight != null) getHighlighter().removeHighlight(rowHighlight);\n            \n                    int currentLine = getLineFromOffset(SourceArea.this, dot);\n                    int startOffset = getLineStartOffsetForLine(SourceArea.this, currentLine);\n                    int endOffset = getLineEndOffsetForLine(SourceArea.this, currentLine);\n                    \n                    try {\n                        rowHighlight = getHighlighter().addHighlight(startOffset, endOffset, highlightPainter);\n                    } catch (BadLocationException ex) {\n                        Exceptions.printStackTrace(ex);\n                    }\n\n                    repaint();\n                }\n            });\n        }\n\n        public int getLineFromOffset(JTextComponent component, int offset) {\n            return component.getDocument().getDefaultRootElement().getElementIndex(offset);\n        }\n\n        public int getLineStartOffsetForLine(JTextComponent component, int line) {\n            return component.getDocument().getDefaultRootElement().getElement(line).getStartOffset();\n        }\n\n        public int getLineEndOffsetForLine(JTextComponent component, int line) {\n            return component.getDocument().getDefaultRootElement().getElement(line).getEndOffset();\n        }\n        \n        \n        static final class LineHighlightPainter extends DefaultHighlighter.DefaultHighlightPainter {\n        \n            LineHighlightPainter() {\n                super(new Color(233, 239, 248));\n            }\n            \n            public Shape paintLayer(Graphics g, int offs0, int offs1,\n                                Shape bounds, JTextComponent c, View view) {\n                try {\n                    Rectangle r = c.modelToView(offs0);\n                    r.x = 0;\n                    r.width = c.getWidth();\n                    \n                    g.setColor(getColor());\n                    ((Graphics2D)g).fill(r);\n                    \n                    return r;\n                } catch (BadLocationException ex) {\n                    return null;\n                }\n            }\n\n        }\n        \n    }\n    \n    private static class LineNumbers extends JTable {\n        \n        private int currentLine;\n        \n        LineNumbers(final SourceArea sourceArea) {\n            super(createModel(sourceArea));\n            \n            setShowGrid(false);\n            setShowHorizontalLines(false);\n            setShowVerticalLines(false);\n            setOpaque(false);\n            setFocusable(false);\n            setCellSelectionEnabled(false);\n            setRowSelectionAllowed(false);\n            setColumnSelectionAllowed(false);\n            setIntercellSpacing(new Dimension(0, 0));\n            setBackground(new JPanel().getBackground());\n            setBorder(BorderFactory.createEmptyBorder());\n            \n            updateAppearance(sourceArea);\n            \n            DefaultTableCellRenderer renderer = new DefaultTableCellRenderer() {\n                public Component getTableCellRendererComponent(JTable table, Object value,\n                          boolean isSelected, boolean hasFocus, int row, int column) {\n                    Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);\n                    comp.setEnabled(row == currentLine);\n                    return comp;\n                }\n            };\n            renderer.setHorizontalAlignment(JLabel.TRAILING);\n            renderer.setEnabled(false);\n            setDefaultRenderer(Number.class, renderer);\n            \n            currentLine = sourceArea.getLineFromOffset(sourceArea, sourceArea.getCaret().getDot());\n            sourceArea.addCaretListener(new CaretListener() {\n                @Override\n                public void caretUpdate(CaretEvent e) {\n                    currentLine = sourceArea.getLineFromOffset(sourceArea, e.getDot());\n                    repaint();\n                }\n            });\n            MouseAdapter adapter = new MouseAdapter() {\n                public void mousePressed(MouseEvent e) {\n                    currentLine = sourceArea.getLineFromOffset(sourceArea, sourceArea.getCaret().getDot());\n                    repaint();\n                }\n                public void mouseDragged(MouseEvent e) {\n                    currentLine = sourceArea.getLineFromOffset(sourceArea, sourceArea.getCaret().getDot());\n                    repaint();\n                }\n            };\n            \n            sourceArea.addMouseListener(adapter);\n            sourceArea.addMouseMotionListener(adapter);\n        }\n        \n        void updateAppearance(SourceArea sourceArea) {\n            setRowHeight(sourceArea.getRowHeight());\n            setFont(sourceArea.getFont());\n            \n            DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)getDefaultRenderer(Number.class);\n            renderer.setFont(sourceArea.getFont());\n            renderer.setText(Integer.toString(sourceArea.getLineCount()));\n            Dimension dim = sourceArea.getPreferredSize();\n            dim.width = renderer.getPreferredSize().width;\n            setPreferredSize(dim);\n        }\n        \n        private static TableModel createModel(SourceArea sourceArea) {\n            final int rowCount = sourceArea.getLineCount();\n            return new AbstractTableModel() {\n                @Override public int getRowCount() { return rowCount; }\n                @Override public int getColumnCount() { return 1; }\n                @Override public Class<?> getColumnClass(int columnIndex) { return Number.class; }\n                @Override public Object getValueAt(int rowIndex, int columnIndex) { return rowIndex + 1; }\n            };\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/viewer/internal/InternalSourceViewerTopComponent.java",
    "content": "/*\n * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.viewer.internal;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.KeyboardFocusManager;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.io.File;\nimport org.graalvm.visualvm.gotosource.SourceHandle;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.ImageUtilities;\nimport org.openide.windows.TopComponent;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class InternalSourceViewerTopComponent extends TopComponent {\n    \n    private static final String ICON_PATH = \"org/graalvm/visualvm/gotosource/resources/gotosource.png\"; // NOI18N\n    \n    \n    private final InternalSourceViewerComponent viewerComponent;\n    \n    \n    static void showSource(String uri, String text, int offset, int endOffset, InternalSourceAppearance appearance) {\n        String file = SourceHandle.simpleUri(uri);\n        InternalSourceViewerTopComponent container = findOpened(file);\n        \n        if (container == null) {\n            container = new InternalSourceViewerTopComponent(file, text, offset, endOffset, appearance);\n            container.open();\n        } else {\n            container.setOffset(offset, endOffset);\n        }\n        \n        container.requestActive();\n    }\n    \n    private static InternalSourceViewerTopComponent findOpened(String file) {\n        for (TopComponent opened : WindowManager.getDefault().getRegistry().getOpened())\n            if (opened instanceof InternalSourceViewerTopComponent && file.equals(opened.getToolTipText()))\n                return (InternalSourceViewerTopComponent)opened;\n        return null;\n    }\n    \n    \n    private InternalSourceViewerTopComponent(String file, String text, int offset, int endOffset, InternalSourceAppearance appearance) {\n        super();\n        \n        setDisplayName(new File(file).getName());\n        setIcon(ImageUtilities.loadImage(ICON_PATH, true));\n        setToolTipText(file);\n        \n        viewerComponent = new InternalSourceViewerComponent(text, offset, endOffset, appearance);\n        \n        setLayout(new BorderLayout());\n        add(viewerComponent, BorderLayout.CENTER);\n    }\n    \n    \n    private void setOffset(int offset, int endOffset) {\n        viewerComponent.setOffset(offset, endOffset);\n    }\n    \n    \n    protected void componentClosed() {\n        super.componentClosed();\n        viewerComponent.cleanup();\n    }\n    \n    \n    public int getPersistenceType() {\n        return PERSISTENCE_NEVER;\n    }\n    \n    protected String preferredID() {\n        return getDisplayName();\n    }\n    \n    public HelpCtx getHelpCtx() {\n        return null;\n    }\n    \n    \n    private Component lastFocusOwner;\n    \n    private final PropertyChangeListener focusListener = new PropertyChangeListener() {\n        public void propertyChange(PropertyChangeEvent evt) {\n            Component c = evt.getNewValue() instanceof Component ?\n                    (Component)evt.getNewValue() : null;\n            processFocusedComponent(c);\n        }\n        private void processFocusedComponent(Component c) {\n            Component cc = c;\n            while (c != null) {\n                if (c == InternalSourceViewerTopComponent.this) {\n                    lastFocusOwner = cc;\n                    return;\n                }\n                c = c.getParent();\n            }\n        }\n    };\n    \n    protected void componentActivated() {\n        super.componentActivated();\n        if (lastFocusOwner != null) {\n            lastFocusOwner.requestFocus();\n        } else {\n            Component defaultFocusOwner = defaultFocusOwner();\n            if (defaultFocusOwner != null) defaultFocusOwner.requestFocus();\n        }\n        KeyboardFocusManager.getCurrentKeyboardFocusManager().\n                addPropertyChangeListener(\"focusOwner\", focusListener);         // NOI18N\n    }\n\n    protected void componentDeactivated() {\n        KeyboardFocusManager.getCurrentKeyboardFocusManager().\n                removePropertyChangeListener(\"focusOwner\", focusListener);      // NOI18N\n        super.componentDeactivated();\n    }\n    \n    protected Component defaultFocusOwner() {\n        return viewerComponent.defaultFocusOwner();\n    }\n    \n    public Dimension getMinimumSize() {\n        return new Dimension(0, 0);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/gotosource/src/org/graalvm/visualvm/gotosource/viewer/internal/InternalSourcesViewer.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.gotosource.viewer.internal;\n\nimport javax.swing.JComponent;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.gotosource.SourceHandle;\nimport org.graalvm.visualvm.gotosource.SourcesViewer;\nimport org.openide.util.NbBundle;\n//import org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"InternalSourcesViewer_Name=Internal Viewer\",                               // NOI18N\n    \"InternalSourcesViewer_Description=simple built-in text viewer\"             // NOI18N                                 \n})\n//@ServiceProvider(service=SourcesViewer.class, position = 100)\npublic final class InternalSourcesViewer extends SourcesViewer {\n    \n    private static final String ID = \"InternalSourcesViewer\";                   // NOI18N\n    \n    \n    private InternalSourceAppearance appearance;\n    \n    \n    public InternalSourcesViewer() {\n        super(ID, Bundle.InternalSourcesViewer_Name(), Bundle.InternalSourcesViewer_Description());\n    }\n    \n    \n    @Override\n    public boolean open(SourceHandle handle) {\n        final String uri = handle.getSourceUri();\n        final String text = handle.getText();\n        final int offset  = handle.getOffset();\n        final int endOffset = handle.getEndOffset();\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                InternalSourceViewerTopComponent.showSource(uri, text, offset == -1 ? 0 : offset, offset == -1 ? 0 : endOffset, getAppearance());\n            }\n        });\n        \n        return true;\n    }\n    \n    \n    @Override\n    public void loadSettings() { if (appearance != null) appearance.loadSettings(); }\n    \n    @Override\n    public void saveSettings() { if (appearance != null) appearance.saveSettings(); }\n    \n    @Override\n    public boolean settingsDirty() { return appearance != null && appearance.currentSettingsDirty(); }\n    \n    \n    @Override\n    public JComponent getSettingsComponent() { return getAppearance().getSettingsComponent(); }\n    \n    \n    private InternalSourceAppearance getAppearance() {\n        if (appearance == null) appearance = new InternalSourceAppearance();\n        return appearance;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/graalvm/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.graalvm\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.graalvm.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/graalvm/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.graalvm/2\nOpenIDE-Module-Install: org/graalvm/visualvm/graalvm/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/graalvm/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "visualvm/graalvm/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.graalvm-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/graalvm/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=45d87257\nbuild.xml.script.CRC32=4bbd8550\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=45d87257\nnbproject/build-impl.xml.script.CRC32=5ea5e3c3\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/graalvm/nbproject/project.properties",
    "content": "javac.source=1.8\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nmodule.javadoc.packages=org.graalvm.visualvm.graalvm.*\n"
  },
  {
    "path": "visualvm/graalvm/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.graalvm</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application.views</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.charts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.49</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/graalvm/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/Bundle.properties",
    "content": "#\n# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-GraalVM Extensions\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.graalvm;\n\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.graalvm.application.type.GraalVMApplicationTypeFactory;\nimport org.graalvm.visualvm.graalvm.libgraal.MemorySnapshotViewPluginProvider;\nimport org.graalvm.visualvm.graalvm.libgraal.MemoryViewPluginProvider;\nimport org.graalvm.visualvm.graalvm.svm.SVMJvmProvider;\nimport org.openide.modules.ModuleInstall;\n\npublic class Installer extends ModuleInstall {\n\n    @Override\n    public void restored() {\n        ApplicationTypeFactory.getDefault().registerProvider(new GraalVMApplicationTypeFactory());\n        \n        // NOTE: adds [native image] suffix to native-image processes\n//        DataSourceDescriptorFactory.getDefault().registerProvider(new NativeImageApplicationDescriptorProvider());\n        \n        JvmFactory.getDefault().registerProvider(new SVMJvmProvider());\n        MemorySnapshotViewPluginProvider.initialize();\n        MemoryViewPluginProvider.initialize();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/application/descriptor/NativeImageApplicationDescriptor.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.graalvm.application.descriptor;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.ApplicationDescriptor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass NativeImageApplicationDescriptor extends ApplicationDescriptor {    \n    \n    protected NativeImageApplicationDescriptor(Application application) {\n        super(application);\n    }\n    \n    public String getName() {\n        return super.getName() + \" [native image]\";\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/application/descriptor/NativeImageApplicationDescriptorProvider.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.graalvm.application.descriptor;\n\nimport java.util.Properties;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class NativeImageApplicationDescriptorProvider extends\n        AbstractModelProvider<DataSourceDescriptor, DataSource> {\n\n    public DataSourceDescriptor createModelFor(DataSource ds) {\n        if (ds instanceof Application) {\n            Jvm jvm = JvmFactory.getJVMFor((Application)ds);\n            if (jvm.isGetSystemPropertiesSupported()) {\n                Properties prop = jvm.getSystemProperties();\n                if (\"Substrate VM\".equals(prop.getProperty(\"java.vm.name\"))) // NOI18N\n                    return new NativeImageApplicationDescriptor((Application)ds);\n            }\n        }\n        return null;\n    }\n    \n    public int priority() {\n        return 10;\n    }\n}\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/application/type/Bundle.properties",
    "content": "#\n# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nDESCR_GraalVMBasedApplicationType=Graal is a just-in-time compiler for the JVM focused on peak performance and multi-language support. Graal offers performance advantages not only to Java code, but also to scripting languages such as JavaScript, Python, Ruby, and R.\nLBL_GraalVM=GraalVM\nDESCR_GraalVM=GraalVM application.\nLBL_Graalvm_Javascript=JavaScript\nLBL_Graalvm_R=R\nLBL_Graalvm_Rscript=Rscript\nLBL_Graalvm_Ruby=Ruby\nLBL_Graalvm_Nodejs=Node.js\nLBL_Graalvm_Python=Python\nLBL_Graalvm_LLVM=Sulong\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/application/type/GraalVMApplicationType.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.graalvm.application.type;\n\nimport java.awt.Image;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * This {@link ApplicationType} represents application based on GraalVM.\n *\n * @author Tomas Hurka\n */\npublic class GraalVMApplicationType extends ApplicationType {\n\n    private Application application;\n    private String name;\n\n    GraalVMApplicationType(Application app, Jvm jvm, String n) {\n        application = app;\n        name = n;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    public String getName() {\n        return name;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    public String getVersion() {\n        return getMessage(\"LBL_Unknown\");  // NOI18N\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    public String getDescription() {\n        return getMessage(\"DESCR_GraalVMBasedApplicationType\"); // NOI18N\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    public Image getIcon() {\n        String iconPath = \"org/graalvm/visualvm/graalvm/application/type/GraalVM.png\";   // NOI18N\n        return ImageUtilities.loadImage(iconPath, true);\n    }\n\n    String getMessage(String string) {\n        return NbBundle.getMessage(GraalVMApplicationType.class, string);\n    }\n}\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/application/type/GraalVMApplicationTypeFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.graalvm.application.type;\n\nimport java.util.Properties;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.graalvm.visualvm.application.type.MainClassApplicationTypeFactory;\nimport org.openide.util.NbBundle;\n\n/**\n * Factory which recognizes GraalVM and some applications based on GraalVM\n *\n * @author Tomas Hurka\n */\npublic class GraalVMApplicationTypeFactory extends MainClassApplicationTypeFactory {\n\n    private static final String MAIN_CLASS = \"com.oracle.graalvm.Main\"; // NOI18N\n    private static final String LEGACY_MAIN_CLASS = \"com.oracle.graalvm.launcher.LegacyLauncher\"; // NOI18N\n    private static final String JAVASCRIPT_MAIN_CLASS = \"com.oracle.truffle.js.shell.JSLauncher\";   // NOI18N\n    private static final String R_LEGACY_MAIN_CLASS = \"com.oracle.truffle.r.legacylauncher.LegacyLauncher\"; // NOI18N\n    private static final String R_MAIN_CLASS = \"com.oracle.truffle.r.launcher.RMain\"; // NOI18N\n    private static final String RUBY_MAIN_CLASS = \"org.truffleruby.launcher.RubyLauncher\"; // NOI18N\n    private static final String PYTHON_MAIN_CLASS = \"com.oracle.graal.python.shell.GraalPythonMain\"; // NOI18N\n    private static final String PYTHON_EE_MAIN_CLASS = \"com.oracle.graal.python.enterprise.shell.GraalPythonEnterpriseMain\"; // NOI18N\n    private static final String LLVM_MAIN_CLASS = \"com.oracle.truffle.llvm.launcher.LLVMLauncher\"; // NOI18N\n    private static final String GRAAL_SYSPROP_ID = \"graalvm.home\"; // NOI18N\n    private static final String GRAAL_SYSPROP1_ID = \"org.graalvm.home\"; // NOI18N\n    private static final String LAUNCHER_SYSPROP_ID = \"org.graalvm.launcher.class\";  // NOI18N\n    private static final String JVM_ARG_GRAAL_ID = \"-D\"+GRAAL_SYSPROP_ID+\"=\"; // NOI18N\n    private static final String JVM_ARG_GRAAL1_ID = \"-Dgraal.CompilerConfiguration=\"; // NOI18N\n    private static final String ARG_GRAAL_ID = \"--\"; // NOI18N\n    private static final String JVM_ARG_NODEJS_ID = \"-Dtruffle.js.DirectByteBuffer=true\";  // NOI18N\n    private static final String JVM_ARG_NODEJS1_ID = \"-Dtruffle.js.DebugPropertyName=GraalJsDebug\";  // NOI18N\n\n    private static final String JAVASCRIPT_ID = \"com.oracle.truffle.js.shell.Shell\"; // NOI18N\n    private static final String R_ID = \"com.oracle.truffle.r.engine.shell.RCommand\";    // NOI18N\n    private static final String LEGACY_RSCRIPT_ID = \"com.oracle.truffle.r.launcher.RscriptCommand\"; // NOI18N\n    private static final String LEGACY_R_ID = \"com.oracle.truffle.r.launcher.RCommand\"; // NOI18N\n    private static final String RUBY_ID = \"org.truffleruby.Main\"; // NOI18N;\n    private static final String NODEJS_ID = \"node.js\"; // NOI18N;\n    private static final String PYTHON_ID = \"GraalPythonMain\"; // NOI18N\n    private static final String LLVM_ID = \"LLVM\"; // NOI18N\n\n    private boolean isGraalVM(Jvm jvm, String mainClass) {\n        if (MAIN_CLASS.equals(mainClass) || LEGACY_MAIN_CLASS.equals(mainClass)) {\n            return true;\n        }\n        if (JAVASCRIPT_MAIN_CLASS.equals(mainClass)) {\n            return true;\n        }\n        if (R_MAIN_CLASS.equals(mainClass)) {\n            return true;\n        }\n        if (R_LEGACY_MAIN_CLASS.equals(mainClass)) {\n            return true;\n        }\n        if (RUBY_MAIN_CLASS.equals(mainClass)) {\n            return true;\n        }\n        if (PYTHON_MAIN_CLASS.equals(mainClass)) {\n            return true;\n        }\n        if (PYTHON_EE_MAIN_CLASS.equals(mainClass)) {\n            return true;\n        }\n        if (LLVM_MAIN_CLASS.equals(mainClass)) {\n            return true;\n        }\n        if (mainClass == null || mainClass.isEmpty()) {    // there is no main class - detect native GraalVM launcher\n            String args = jvm.getJvmArgs();\n            if (args != null) {\n                if (args.contains(JVM_ARG_GRAAL_ID) || args.contains(JVM_ARG_GRAAL1_ID) || args.contains(JVM_ARG_NODEJS_ID)) {\n                    return true;\n                }\n            }\n            if (jvm.isGetSystemPropertiesSupported()) {\n                Properties sysProp = jvm.getSystemProperties();\n\n                if (sysProp != null) {\n                    if (sysProp.getProperty(GRAAL_SYSPROP_ID) != null\n                            || sysProp.getProperty(GRAAL_SYSPROP1_ID) != null\n                            || sysProp.getProperty(LAUNCHER_SYSPROP_ID) != null) {\n                        return true;\n                    }\n                }\n            }\n        }\n        return false;\n    }\n\n    private String getLangID(Jvm jvm) {\n        String args = jvm.getMainArgs();\n        String mainClass = jvm.getMainClass();\n\n        if ((mainClass == null || mainClass.isEmpty()) && jvm.isGetSystemPropertiesSupported()) {\n            Properties sysProp = jvm.getSystemProperties();\n\n            if (sysProp != null) {\n                mainClass = sysProp.getProperty(LAUNCHER_SYSPROP_ID);\n            }\n        }\n        if (LEGACY_MAIN_CLASS.equals(mainClass)) {\n            if (args != null) {\n                String[] argArr = args.split(\" +\");\n                if (argArr.length > 1) {\n                    return argArr[1];\n                }\n            }\n        }\n        if (JAVASCRIPT_MAIN_CLASS.equals(mainClass)) {\n            return JAVASCRIPT_ID;\n        }\n        if (R_MAIN_CLASS.equals(mainClass)) {\n            return R_ID;\n        }\n        if (R_LEGACY_MAIN_CLASS.equals(mainClass)) {\n            return R_ID;\n        }\n        if (RUBY_MAIN_CLASS.equals(mainClass)) {\n            return RUBY_ID;\n        }\n        if (PYTHON_MAIN_CLASS.equals(mainClass)) {\n            return PYTHON_ID;\n        }\n        if (PYTHON_EE_MAIN_CLASS.equals(mainClass)) {\n            return PYTHON_ID;\n        }\n        if (LLVM_MAIN_CLASS.equals(mainClass)) {\n            return LLVM_ID;\n        }\n        if (args != null) {\n            String[] argArr = args.split(\" +\");\n            if (argArr.length > 2) {\n                if (ARG_GRAAL_ID.equals(argArr[1])) {\n                    return argArr[2];\n                }\n            }\n        }\n        return null;\n    }\n\n    private String getName(String lang) {\n        if (lang == null) {\n            return getMessage(\"LBL_GraalVM\");\n        }\n        switch (lang) {\n            case JAVASCRIPT_ID:\n                return getMessage(\"LBL_Graalvm_Javascript\");    // NOI18N\n            case R_ID:\n            case LEGACY_R_ID:\n                return getMessage(\"LBL_Graalvm_R\");     // NOI18N\n            case LEGACY_RSCRIPT_ID:\n                return getMessage(\"LBL_Graalvm_Rscript\");     // NOI18N\n            case RUBY_ID:\n                return getMessage(\"LBL_Graalvm_Ruby\");  // NOI18N\n            case NODEJS_ID:\n                return getMessage(\"LBL_Graalvm_Nodejs\");  // NOI18N                \n            case PYTHON_ID:\n                return getMessage(\"LBL_Graalvm_Python\");  // NOI18N\n            case LLVM_ID:\n                return getMessage(\"LBL_Graalvm_LLVM\");  // NOI18N\n            default:\n                return lang;\n        }\n    }\n\n    String getMessage(String string) {\n        return NbBundle.getMessage(GraalVMApplicationTypeFactory.class, string);\n    }\n\n    @Override\n    public ApplicationType createApplicationTypeFor(Application app, Jvm jvm, String mainClass) {\n        if (isGraalVM(jvm, mainClass)) {\n            String langId = getLangID(jvm);\n\n            if (langId == null && (mainClass == null || mainClass.isEmpty())) {  // nodejs ???\n                String jvmArgs = jvm.getJvmArgs();\n                if (jvmArgs.contains(JVM_ARG_NODEJS_ID) || jvmArgs.contains(JVM_ARG_NODEJS1_ID)) {\n                    langId = NODEJS_ID;\n                }\n            }\n            String name = getName(langId);\n            return new GraalVMApplicationType(app, jvm, name);\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/libgraal/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n# HTML-formatted: <unknown> (&lt; and &gt; must remain!)\nLBL_Unknown=&lt;unknown&gt;\n\n\nLBL_Memory=Memory\n\nLBL_Heap=Heap\n\n\nLBL_Heap_size=Size\n\nLBL_Used_heap=Used\n\nLBL_Heap_size_leg={0} size\n\nLBL_Used_heap_leg=Used {0}\n\nLBL_Max_Heap=Max\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/libgraal/MemoryModel.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.graalvm.libgraal;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.lang.management.MemoryUsage;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.Attribute;\nimport javax.management.MBeanServerConnection;\nimport javax.management.ObjectName;\nimport javax.management.openmbean.CompositeData;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.application.jvm.MonitoredDataListener;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class MemoryModel {\n    private static final Logger LOGGER = Logger.getLogger(MemoryModel.class.getName());\n\n    private static final String PROP_PREFIX = \"LibgraalModel_\";  // NOI18N\n    private static final String USAGE_ATTRIBUTE = \"Usage\"; // NOI18N\n    private static final String PEAK_USAGE_ATTRIBUTE = \"PeakUsage\"; // NOI18N\n\n    private static final String SNAPSHOT_VERSION = PROP_PREFIX + \"version\"; // NOI18N\n    private static final String SNAPSHOT_VERSION_DIVIDER = \".\"; // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = \"1\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MINOR = \"0\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION = CURRENT_SNAPSHOT_VERSION_MAJOR + SNAPSHOT_VERSION_DIVIDER + CURRENT_SNAPSHOT_VERSION_MINOR;\n\n    private static final String PROP_NOT_DEFINED = \"<not defined>\"; // NOI18N\n\n    private static final String PROP_CHART_CACHE = PROP_PREFIX + \"chart_cache\";    // NOI18N\n    private static final String PROP_HEAP_NAME = PROP_PREFIX + \"heap_name\"; // NOI18N\n    private static final String PROP_HEAP_CAPACITY = PROP_PREFIX + \"heap_capacity\"; // NOI18N\n    private static final String PROP_HEAP_USED = PROP_PREFIX + \"heap_used\"; // NOI18N\n    private static final String PROP_MAX_HEAP = PROP_PREFIX + \"max_heap\"; // NOI18N\n    private static final String CHART_STORAGE = PROP_PREFIX + \"monitor_libgraal.dat\"; // NOI18N\n\n    private boolean initialized;\n    private DataSource source;\n    private boolean live;\n\n    private final List<ChangeListener> listeners;\n    private SimpleXYChartSupport heapChartSupport;\n    private MonitoredDataListener monitoredDataListener;\n\n    private Jvm jvm;\n    private ObjectName libgraalName;\n    private MBeanServerConnection connection;\n\n    private int chartCache = -1;\n\n    private long timestamp = -1;\n\n    private String heapName;\n    private long heapCapacity = -1;\n    private long heapUsed = -1;\n    private long maxHeap = -1;\n\n    static MemoryModel create(Application application, String name, ObjectName libgraalName) {\n        return new MemoryModel(application, name, libgraalName);\n    }\n\n    static MemoryModel create(DataSource ds, String name) {\n        return new MemoryModel(ds, name);\n    }\n\n    DataSource getSource() {\n        return source;\n    }\n\n    boolean isLive() {\n        return live;\n    }\n\n    long getTimestamp() {\n        return timestamp;\n    }\n\n    int getChartCache() {\n        return chartCache;\n    }\n\n    String getHeapName() {\n        return heapName;\n    }\n\n    long getHeapCapacity() {\n        return heapCapacity;\n    }\n\n    long getHeapUsed() {\n        return heapUsed;\n    }\n\n    long getMaxHeap() {\n        return maxHeap;\n    }\n\n    synchronized void initialize() {\n        if (initialized) {\n            return;\n        }\n        initialized = true;\n        if (source instanceof Application) {\n            initialize((Application) source);\n        } else {\n            initialize((Snapshot) source);\n        }\n    }\n\n    void registerHeapChartSupport(final SimpleXYChartSupport heapChartSupport) {\n        this.heapChartSupport = heapChartSupport;\n        if (heapChartSupport != null && source instanceof Snapshot) {\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    File file = new File(source.getStorage().getDirectory(), CHART_STORAGE);\n                    if (file.isFile() && file.canRead()) {\n                        loadChartSupport(heapChartSupport, file);\n                    }\n                }\n            });\n        }\n    }\n\n    synchronized void cleanup() {\n        listeners.clear();\n        if (!initialized) {\n            return;\n        }\n        if (jvm != null && monitoredDataListener != null) {\n            jvm.removeMonitoredDataListener(monitoredDataListener);\n        }\n        connection = null;\n    }\n\n    void addChangeListener(ChangeListener listener) {\n        if (live) {\n            listeners.add(listener);\n        }\n    }\n\n    void removeChangeListener(ChangeListener listener) {\n        if (live) {\n            listeners.remove(listener);\n        }\n    }\n\n    void save(Snapshot snapshot) {\n\n        initialize();\n\n        Storage storage = snapshot.getStorage();\n\n        setProperty(storage, SNAPSHOT_VERSION, CURRENT_SNAPSHOT_VERSION);\n\n        setProperty(storage, PROP_CHART_CACHE, Integer.toString(chartCache));\n\n        setProperty(storage, PROP_HEAP_NAME, heapName);\n        setProperty(storage, PROP_HEAP_CAPACITY, Long.toString(heapCapacity));\n        setProperty(storage, PROP_HEAP_USED, Long.toString(heapUsed));\n        setProperty(storage, PROP_MAX_HEAP, Long.toString(maxHeap));\n\n        File dir = storage.getDirectory();\n\n        saveChartSupport(heapChartSupport, new File(dir, CHART_STORAGE));\n    }\n\n    private static void saveChartSupport(SimpleXYChartSupport chartSupport, File file) {\n        if (chartSupport == null) {\n            return;\n        }\n\n        try (OutputStream os = new FileOutputStream(file)) {\n            chartSupport.saveValues(os);\n        } catch (Exception e) {\n            LOGGER.log(Level.INFO, \"saveChartSupport\", e);   // NOI18N\n        }\n    }\n\n    private static void loadChartSupport(SimpleXYChartSupport chartSupport, File file) {\n        try (InputStream is = new FileInputStream(file)) {\n            chartSupport.loadValues(is);\n        } catch (Exception e) {\n            LOGGER.log(Level.INFO, \"loadChartSupport\", e);   // NOI18N\n        }\n    }\n\n    private void initialize(Snapshot snapshot) {\n        // TODO: if some property cannot be loaded for current snapshot version, FAIL initializing the snapshot!\n        Storage storage = snapshot.getStorage();\n\n        String version = getProperty(storage, SNAPSHOT_VERSION);\n        heapName = getProperty(storage, PROP_HEAP_NAME);\n        chartCache = Integer.parseInt(getProperty(storage, PROP_CHART_CACHE));\n        heapCapacity = Long.parseLong(getProperty(storage, PROP_HEAP_CAPACITY));\n        heapUsed = Long.parseLong(getProperty(storage, PROP_HEAP_USED));\n        maxHeap = Long.parseLong(getProperty(storage, PROP_MAX_HEAP));\n    }\n\n    private static void setProperty(Storage storage, String property, String value) {\n        storage.setCustomProperty(property, value == null ? PROP_NOT_DEFINED : value);\n    }\n\n    private static String getProperty(Storage storage, String property) {\n        String value = storage.getCustomProperty(property);\n        return PROP_NOT_DEFINED.equals(value) ? null : value;\n    }\n\n    private void initialize(Application application) {\n        GlobalPreferences preferences = GlobalPreferences.sharedInstance();\n        chartCache = preferences.getMonitoredDataCache() * 60\n                / preferences.getMonitoredDataPoll();\n\n        jvm = JvmFactory.getJVMFor(application);\n        connection = getConnection(application);\n        if (connection != null) {\n            updateValues(System.currentTimeMillis(), getData());\n\n            if (live) {\n                monitoredDataListener = new MonitoredDataListener() {\n                    long lastTimestamp = -1;\n\n                    public void monitoredDataEvent(final MonitoredData data) {\n                        long timestamp = System.currentTimeMillis();\n                        final long timestampF = lastTimestamp < timestamp\n                                ? lastTimestamp = timestamp : ++lastTimestamp;\n                        final Object[] values = getData();\n\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                updateValues(timestampF, values);\n                                fireChange();\n                            }\n                        });\n                    }\n                };\n                jvm.addMonitoredDataListener(monitoredDataListener);\n            }\n        }\n    }\n\n    private Object[] getAttributes(String... names) {\n        try {\n            List<Attribute> attrs = connection.getAttributes(libgraalName, names).asList();\n            Object[] values = new Object[attrs.size()];\n            \n            for (int i = 0; i < values.length; i++) {\n                values[i] = attrs.get(i).getValue();\n            }\n            return values;\n        } catch (Exception ex) {\n            LOGGER.log(Level.INFO, \"getAttributes\", ex);   // NOI18N\n        }\n        return null;\n    }\n\n    private Object[] getData() {\n        if (live && connection != null) {\n            Object[] values =  getAttributes(USAGE_ATTRIBUTE, PEAK_USAGE_ATTRIBUTE);\n\n            if (values == null) {\n                connection = null;\n            }\n            return values;\n        }\n        return null;\n    }\n\n    private void updateValues(final long time, Object[] values) {\n        if (values != null) {\n            CompositeData usageData = (CompositeData) values[0];\n            CompositeData peakData = (CompositeData) values[1];\n            if (usageData != null && peakData != null) {\n                MemoryUsage mem = MemoryUsage.from(usageData);\n                MemoryUsage peak = MemoryUsage.from(peakData);\n                heapUsed = mem.getUsed();\n                heapCapacity = peak.getUsed();\n                maxHeap = mem.getMax();\n                timestamp = time;\n            }\n        }\n    }\n\n    private void fireChange() {\n        final List<ChangeListener> list = new ArrayList<>();\n        synchronized (listeners) {\n            list.addAll(listeners);\n        }\n        for (ChangeListener l : list) {\n            l.stateChanged(new ChangeEvent(this));\n        }\n    }\n\n    private MemoryModel() {\n        initialized = false;\n        listeners = Collections.synchronizedList(new ArrayList<>());\n    }\n\n    private MemoryModel(DataSource src, String name) {\n        this();\n        source = src;\n        heapName = name;\n        live = false;\n    }\n\n    private MemoryModel(DataSource src, String name, ObjectName mbeanName) {\n        this(src, name);\n        live = true;\n        libgraalName = mbeanName;\n    }\n\n    private static MBeanServerConnection getConnection(Application app) {\n        JmxModel jmxModel = JmxModelFactory.getJmxModelFor(app);\n        if (jmxModel != null && jmxModel.getConnectionState() == JmxModel.ConnectionState.CONNECTED) {\n            return jmxModel.getMBeanServerConnection();\n        }\n        return null;\n    }\n\n    static boolean isInStapshot(ApplicationSnapshot snapshot) {\n        String version = getProperty(snapshot.getStorage(), SNAPSHOT_VERSION);\n        \n        return version != null;\n    }\n}\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/libgraal/MemorySnapshotViewPluginProvider.java",
    "content": "/*\n * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.graalvm.libgraal;\n\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.application.views.ApplicationViewsSupport;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class MemorySnapshotViewPluginProvider extends DataSourceViewPluginProvider<ApplicationSnapshot> {\n\n    protected DataSourceViewPlugin createPlugin(ApplicationSnapshot snapshot) {\n        return new MemoryViewPlugin(snapshot, MemoryModel.create(snapshot, MemoryViewPluginProvider.LIBGRAAL_HEAP));\n    }\n\n    protected boolean supportsPluginFor(ApplicationSnapshot snapshot) {\n        return MemoryModel.isInStapshot(snapshot);\n    }\n\n    private MemorySnapshotViewPluginProvider() {\n    }\n\n    public static void initialize() {\n        ApplicationViewsSupport.sharedInstance().getSnapshotMonitorView().\n                registerPluginProvider(new MemorySnapshotViewPluginProvider());\n    }\n}\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/libgraal/MemoryViewComponent.java",
    "content": "/*\n * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.graalvm.libgraal;\n\nimport java.awt.BorderLayout;\nimport javax.swing.JPanel;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.charts.ChartFactory;\nimport org.graalvm.visualvm.charts.SimpleXYChartDescriptor;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.NotSupportedDisplayer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass MemoryViewComponent extends JPanel {\n\n    private static final String UNKNOWN = NbBundle.getMessage(MemoryViewComponent.class, \"LBL_Unknown\"); // NOI18N\n\n    private boolean liveModel;\n    private boolean memoryMonitoringSupported;\n    private String heapName;\n\n    private SimpleXYChartSupport chartSupport;\n\n    MemoryViewComponent(MemoryModel model) {\n        initModels(model);\n        initComponents();\n        refresh(model);\n    }\n\n    DataViewComponent.DetailsView getDetailsView() {\n        return new DataViewComponent.DetailsView(heapName, null, 10, this, null);\n    }\n\n    private void refresh(MemoryModel model) {\n        if (memoryMonitoringSupported) {\n            long heapCapacity = model.getHeapCapacity();\n            long heapUsed = model.getHeapUsed();\n            long maxHeap = model.getMaxHeap();\n\n            if (liveModel) {\n                chartSupport.addValues(model.getTimestamp(), new long[]{heapCapacity, heapUsed});\n            }\n            chartSupport.updateDetails(new String[]{chartSupport.formatBytes(heapCapacity),\n                chartSupport.formatBytes(heapUsed),\n                chartSupport.formatBytes(maxHeap)});\n        }\n    }\n\n    private void initModels(final MemoryModel model) {\n        liveModel = model.isLive();\n        memoryMonitoringSupported = true;\n        heapName = memoryMonitoringSupported ? model.getHeapName() : NbBundle.getMessage(MemoryViewComponent.class, \"LBL_Memory\"); // NOI18N\n\n        if (memoryMonitoringSupported) {\n            String HEAP_SIZE = NbBundle.getMessage(MemoryViewComponent.class, \"LBL_Heap_size\"); // NOI18N\n            String HEAP_SIZE_LEG = NbBundle.getMessage(MemoryViewComponent.class, \"LBL_Heap_size_leg\", heapName); // NOI18N\n            String USED_HEAP = NbBundle.getMessage(MemoryViewComponent.class, \"LBL_Used_heap\"); // NOI18N\n            String USED_HEAP_LEG = NbBundle.getMessage(MemoryViewComponent.class, \"LBL_Used_heap_leg\", heapName.toLowerCase()); // NOI18N\n            String MAX_HEAP = NbBundle.getMessage(MemoryViewComponent.class, \"LBL_Max_Heap\");   // NOI18N\n\n            SimpleXYChartDescriptor chartDescriptor\n                    = SimpleXYChartDescriptor.bytes(10 * 1024 * 1024, false, model.getChartCache());\n\n            chartDescriptor.addLineFillItems(HEAP_SIZE_LEG, USED_HEAP_LEG);\n            chartDescriptor.setDetailsItems(new String[]{HEAP_SIZE, USED_HEAP, MAX_HEAP});\n            chartDescriptor.setLimitYValue(model.getMaxHeap());\n\n            chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n            model.registerHeapChartSupport(chartSupport);\n\n            chartSupport.setZoomingEnabled(!liveModel);\n\n            model.addChangeListener(new ChangeListener() {\n                public void stateChanged(ChangeEvent e) {\n                    refresh(model);\n                }\n            });\n        }\n    }\n\n    private void initComponents() {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n\n        if (memoryMonitoringSupported) {\n            add(chartSupport.getChart(), BorderLayout.CENTER);\n            chartSupport.updateDetails(new String[]{UNKNOWN, UNKNOWN, UNKNOWN});\n        } else {\n            add(new NotSupportedDisplayer(NotSupportedDisplayer.JVM),\n                    BorderLayout.CENTER);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/libgraal/MemoryViewPlugin.java",
    "content": "/*\n * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.graalvm.libgraal;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class MemoryViewPlugin extends DataSourceViewPlugin {\n\n    private final MemoryModel model;\n    private MemoryViewComponent view;\n\n    @Override\n    public DataViewComponent.DetailsView createView(int location) {\n        switch (location) {\n            case DataViewComponent.TOP_RIGHT:\n                view = new MemoryViewComponent(model);\n                return view.getDetailsView();\n            default:\n                return null;\n        }\n    }\n\n    protected void willBeAdded() {\n        model.initialize();\n    }\n\n    @Override\n    protected void removed() {\n        model.cleanup();\n    }\n\n    MemoryModel getModel() {\n        return model;\n    }\n\n    MemoryViewPlugin(DataSource dataSource, MemoryModel model) {\n        super(dataSource);\n        this.model = model;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/libgraal/MemoryViewPluginProvider.java",
    "content": "/*\n * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.graalvm.libgraal;\n\nimport java.io.IOException;\nimport java.lang.management.ManagementFactory;\nimport javax.management.MBeanServerConnection;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.application.views.ApplicationViewsSupport;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPlugin;\nimport org.graalvm.visualvm.core.ui.DataSourceViewPluginProvider;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class MemoryViewPluginProvider extends DataSourceViewPluginProvider<Application> {\n\n    static final String LIBGRAAL_HEAP = \"Libgraal\";  // NOI18N\n\n    private final ObjectName libgraalName;\n\n    @Override\n    protected DataSourceViewPlugin createPlugin(Application application) {\n        return new MemoryViewPlugin(application, MemoryModel.create(application, LIBGRAAL_HEAP, libgraalName));\n    }\n\n    @Override\n    protected boolean supportsPluginFor(Application t) {\n        return isSupported(t);\n    }\n\n    @Override\n    protected boolean supportsSavePluginFor(Application application, Class<? extends Snapshot> snapshotClass) {\n        return ApplicationSnapshot.class.isAssignableFrom(snapshotClass);\n    }\n\n    @Override\n    protected void savePlugin(Application application, Snapshot snapshot) {\n        MemoryViewPlugin view = (MemoryViewPlugin) getCachedPlugin(application);\n        if (view != null) {\n            view.getModel().save(snapshot);\n        } else {\n            MemoryModel.create(application, LIBGRAAL_HEAP).save(snapshot);\n        }\n    }\n\n    private MemoryViewPluginProvider() {\n        libgraalName = getLibgraalName();\n    }\n\n    public static void initialize() {\n        ApplicationViewsSupport.sharedInstance().getMonitorView().\n                registerPluginProvider(new MemoryViewPluginProvider());\n    }\n\n    private static ObjectName getLibgraalName() {\n        try {\n            return new ObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE + \",name=\" + LIBGRAAL_HEAP);\n        } catch (MalformedObjectNameException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n\n    private static MBeanServerConnection getConnection(Application app) {\n        JmxModel jmxModel = JmxModelFactory.getJmxModelFor(app);\n        if (jmxModel != null && jmxModel.getConnectionState() == JmxModel.ConnectionState.CONNECTED) {\n            return jmxModel.getMBeanServerConnection();\n        }\n        return null;\n    }\n\n    private boolean isSupported(Application app) {\n        try {\n            MBeanServerConnection conn = getConnection(app);\n            if (conn != null) {\n                return conn.isRegistered(libgraalName);\n            }\n        } catch (IOException ex) {\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/svm/SVMJVMImpl.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.graalvm.svm;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.FileSystems;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.nio.file.StandardWatchEventKinds;\nimport java.nio.file.WatchEvent;\nimport java.nio.file.WatchKey;\nimport java.nio.file.WatchService;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Properties;\nimport java.util.Set;\nimport java.util.concurrent.TimeUnit;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.application.jvm.MonitoredDataListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatListener;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.MonitoredValue;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class SVMJVMImpl extends Jvm implements JvmstatListener {\n\n    private static final String USER_DIR_COUNTER_NAME = \"java.property.user.dir\";\n    private static final String PROCESSORS_COUNTER_NAME = \"com.oracle.svm.processors\";\n    private static final String SVM_HEAP_DUMP_PREFIX = \"svm-heapdump-\";\n    private static final String SVM_HEAP_DUMP_SUFFIX = \".hprof\";\n    private static final String SYSTEM_PROPERTY_PREFIX = \"java.property.\";\n    private static final String SYSTEM_PROPERTY_REG_EXPR = SYSTEM_PROPERTY_PREFIX.replace(\".\", \"\\\\.\")+\".*\"; // NOI18N\n    private static final String MEMORY_COUNTER_REG_EXPR = \"sun\\\\.gc\\\\.generation\\\\..*\";\n\n    Application application;\n    JvmstatModel monitoredVm;\n    JvmJvmstatModel jvmstatModel;\n    Set<MonitoredDataListener> listeners;\n\n    // static JVM data\n    private boolean staticDataInitialized;\n    private final Object staticDataLock = new Object();\n    private String commandLine;\n    private String jvmArgs;\n    private String jvmFlags;\n    private String mainArgs;\n    private String mainClass;\n    private String vmVersion;\n    private String javaVersion;\n    private String javaHome;\n    private String vmInfo;\n    private String vmName;\n    private String vmVendor;\n\n\n    SVMJVMImpl(Application app,JvmstatModel jvms) {\n        application = app;\n        monitoredVm = jvms;\n        jvmstatModel = JvmJvmstatModelFactory.getJvmstatModelFor(app);\n        listeners = new HashSet<>();\n    }\n\n    public boolean isAttachable() {\n        return false;\n    }\n\n    public boolean isBasicInfoSupported() {\n        return true;\n    }\n\n    public String getCommandLine() {\n        initStaticData();\n        return commandLine;\n    }\n\n    public String getJvmArgs() {\n        initStaticData();\n        return jvmArgs;\n    }\n\n    public String getJvmFlags() {\n        initStaticData();\n        return jvmFlags;\n    }\n\n    public String getMainArgs() {\n        initStaticData();\n        return mainArgs;\n    }\n\n    public String getMainClass() {\n        initStaticData();\n        return mainClass;\n    }\n\n    public String getVmVersion() {\n        initStaticData();\n        return vmVersion;\n    }\n\n    public String getJavaVersion() {\n        initStaticData();\n        if (javaVersion != null) {\n            return javaVersion;\n        }\n        return vmVersion;\n    }\n\n    public String getJavaHome() {\n        initStaticData();\n        return javaHome;\n    }\n\n    public String getVmInfo() {\n        initStaticData();\n        return vmInfo;\n    }\n\n    public String getVmName() {\n        initStaticData();\n        return vmName;\n    }\n\n    public String getVmVendor() {\n        initStaticData();\n        return vmVendor;\n    }\n\n    public boolean is14() {\n        return false;\n    }\n\n    public boolean is15() {\n        return false;\n    }\n\n    public boolean is16() {\n        return false;\n    }\n\n    public boolean is17() {\n        return false;\n    }\n\n    public boolean is18() {\n        String ver = getJavaVersion();\n        if (ver != null && ver.startsWith(\"1.8.\")) {\n            return true;\n        }\n        return false;\n    }\n\n    public boolean is19() {\n        String ver = getJavaVersion();\n        if (ver != null && javaVersion != null && (ver.startsWith(\"1.9.\") || (ver.equals(\"9\")) || (ver.startsWith(\"9.\")))) {    // NOI18N\n            return true;\n        }\n        return false;\n    }\n\n    public boolean is100() {\n        String ver = getJavaVersion();\n        if (ver != null && javaVersion != null && (ver.equals(\"10\") || ver.startsWith(\"10.\"))) {    // NOI18N\n            return true;\n        }\n        return false;\n    }\n\n    public boolean is110() {\n        String ver = getJavaVersion();\n        if (ver != null && javaVersion != null && (ver.equals(\"11\") || ver.equals(\"11-ea\") || ver.startsWith(\"11.\"))) {    // NOI18N\n            return true;\n        }\n        return false;\n    }\n\n    public boolean isDumpOnOOMEnabled() {\n        return false;\n    }\n\n    public void addMonitoredDataListener(MonitoredDataListener l) {\n        synchronized (listeners) {\n            if (listeners.add(l)) {\n                if (monitoredVm != null) {\n                    monitoredVm.addJvmstatListener(this);\n                }\n            }\n        }\n    }\n\n    public void removeMonitoredDataListener(MonitoredDataListener l) {\n        synchronized (listeners) {\n            if (listeners.remove(l)) {\n                if (listeners.isEmpty()) {\n                    if (monitoredVm != null) {\n                        monitoredVm.removeJvmstatListener(this);\n                    }\n                }\n            }\n        }\n    }\n\n    public String[] getGenName() {\n        if (jvmstatModel != null) {\n            return jvmstatModel.getGenName();\n        }\n        throw new UnsupportedOperationException();\n    }\n\n    public boolean isMonitoringSupported() {\n        return isClassMonitoringSupported() || isThreadMonitoringSupported() || isMemoryMonitoringSupported();\n    }\n\n    public boolean isClassMonitoringSupported() {\n        return monitoredVm != null;\n    }\n\n    public boolean isThreadMonitoringSupported() {\n        return monitoredVm != null;\n    }\n\n    public boolean isMemoryMonitoringSupported() {\n        if (monitoredVm != null) {\n            List<String> vals = monitoredVm.findByPattern(MEMORY_COUNTER_REG_EXPR);\n\n            return vals != null && !vals.isEmpty();\n        }\n        return false;\n    }\n\n    public boolean isGetSystemPropertiesSupported() {\n        return true;\n    }\n\n    @Override\n    public int getAvailableProcessors() {\n        MonitoredValue procs = monitoredVm.findMonitoredValueByName(PROCESSORS_COUNTER_NAME);\n\n        if (procs != null) {\n            return ((Long)procs.getValue()).intValue();\n        }\n        // default\n        return 1;\n    }\n\n    public Properties getSystemProperties() {\n        Properties p = new Properties();\n        for (MonitoredValue val : monitoredVm.findMonitoredValueByPattern(SYSTEM_PROPERTY_REG_EXPR)) {\n            p.put(val.getName().substring(SYSTEM_PROPERTY_PREFIX.length()), val.getValue());\n        }\n        return p;\n    }\n\n    public boolean isDumpOnOOMEnabledSupported() {\n        return false;\n    }\n\n    public synchronized void setDumpOnOOMEnabled(boolean enabled) {\n    }\n\n    public boolean isTakeHeapDumpSupported() {\n        if (application.isLocalApplication()) {\n            return monitoredVm.findByName(USER_DIR_COUNTER_NAME) != null;\n        }\n        return false;\n    }\n\n    public boolean takeHeapDump(File outputFile) throws IOException {\n        if (!isTakeHeapDumpSupported()) {\n            throw new UnsupportedOperationException();\n        }\n        String cwd = monitoredVm.findByName(USER_DIR_COUNTER_NAME);\n        Path applicationCwd = Paths.get(cwd);\n        WatchService watchService = FileSystems.getDefault().newWatchService();\n        WatchKey key = applicationCwd.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);\n        Runtime.getRuntime().exec(new String[] {\"kill\", \"-USR1\", String.valueOf(application.getPid())});\n        try {\n            Path name = findHeapDumpFile(key);\n            if (name == null) {\n                key = watchService.poll(20, TimeUnit.SECONDS);\n                name = findHeapDumpFile(key);\n            }\n            watchService.close();\n            if (name == null) {\n                return false;\n            }\n            Path dumpPath = applicationCwd.resolve(name);\n            Path outputPath = outputFile.toPath();\n            waitDumpDone(dumpPath);\n            Files.move(dumpPath, outputPath);\n            return true;\n        } catch (InterruptedException ex) {\n            watchService.close();\n            return false;\n        }\n    }\n\n    private Path findHeapDumpFile(WatchKey key) {\n        for (WatchEvent<?> event : key.pollEvents()) {\n            WatchEvent.Kind<?> kind = event.kind();\n            if (kind == StandardWatchEventKinds.OVERFLOW) {\n                continue;\n            }\n            WatchEvent<Path> ev = (WatchEvent<Path>)event;\n            Path filename = ev.context();\n            String name = filename.toString();\n            if (name.endsWith(SVM_HEAP_DUMP_SUFFIX) && name.startsWith(SVM_HEAP_DUMP_PREFIX)) {\n                return filename;\n            }\n        }\n        return null;\n    }\n\n    public boolean isTakeThreadDumpSupported() {\n        return false;\n    }\n\n    public String takeThreadDump() {\n        throw new UnsupportedOperationException();\n    }\n\n    public HeapHistogram takeHeapHistogram() {\n        return null;\n    }\n\n    public boolean isCpuMonitoringSupported() {\n        return true;\n    }\n\n    public boolean isCollectionTimeSupported() {\n        return false;\n    }\n\n    public boolean isJfrAvailable() {\n        return false;\n    }\n\n    public List<Long> jfrCheck() {\n        return Collections.emptyList();\n    }\n\n    public String takeJfrDump(long recording, String fileName) {\n        throw new UnsupportedOperationException();\n    }\n\n    public boolean startJfrRecording(String name, String[] settings, String delay,\n            String duration, Boolean disk, String path, String maxAge, String maxSize,\n            Boolean dumpOnExit) {\n        throw new UnsupportedOperationException();\n    }\n\n    public boolean stopJfrRecording() {\n        throw new UnsupportedOperationException();\n    }\n\n    public MonitoredData getMonitoredData() {\n        if (application.getState() == Stateful.STATE_AVAILABLE) {\n            if (monitoredVm != null) {\n                return new SVMMonitoredDataImpl(this, monitoredVm, jvmstatModel);\n            }\n        }\n        return null;\n    }\n\n    protected void initStaticData() {\n        synchronized (staticDataLock) {\n            if (staticDataInitialized) {\n                return;\n            }\n            if (jvmstatModel != null) {\n                commandLine = jvmstatModel.getCommandLine();\n                jvmArgs = jvmstatModel.getJvmArgs();\n                jvmFlags = jvmstatModel.getJvmFlags();\n                mainArgs = jvmstatModel.getMainArgs();\n                mainClass = jvmstatModel.getMainClass();\n                vmVersion = jvmstatModel.getVmVersion();\n                javaVersion = jvmstatModel.getJavaVersion();\n                javaHome = jvmstatModel.getJavaHome();\n                vmInfo = jvmstatModel.getVmInfo();\n                vmName = jvmstatModel.getVmName();\n                vmVendor = jvmstatModel.getVmVendor();\n            }\n            staticDataInitialized = true;\n        }\n    }\n\n    public void dataChanged(JvmstatModel stat) {\n        assert stat == monitoredVm;\n        MonitoredData data = new SVMMonitoredDataImpl(this, monitoredVm, jvmstatModel);\n        notifyListeners(data);\n    }\n\n    void notifyListeners(final MonitoredData data) {\n        List<MonitoredDataListener> listenersCopy;\n        synchronized (listeners) {\n            listenersCopy = new ArrayList<>(listeners);\n        }\n        for (MonitoredDataListener listener : listenersCopy) {\n            listener.monitoredDataEvent(data);\n        }\n    }\n\n    private void waitDumpDone(Path name) throws IOException {\n        long size;\n        long newSize = Files.size(name);\n        do {\n            size = newSize;\n            try {\n                Thread.sleep(1000);\n            } catch (InterruptedException ex) {\n                return;\n            }\n            newSize = Files.size(name);\n        } while (size != newSize);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/svm/SVMJvmProvider.java",
    "content": "/*\n * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.graalvm.svm;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class SVMJvmProvider extends AbstractModelProvider<Jvm, Application> {\n    private static final String SVM_VM_NAME = \"Substrate VM\"; // NOI18N\n    private static final String VM_NAME = \"java.property.java.vm.name\"; // NOI18N\n\n    @Override\n    public int priority() {\n        return 10;\n    }\n\n    @Override\n    public Jvm createModelFor(Application app) {\n        Jvm jvm = null;\n        JvmstatModel jvmstat = JvmstatModelFactory.getJvmstatFor(app);\n\n        if (jvmstat != null) {\n            String vmName = jvmstat.findByName(VM_NAME);\n            if (SVM_VM_NAME.equals(vmName)) {\n                jvm = new SVMJVMImpl(app, jvmstat);\n            }\n        }\n        return jvm;\n    }\n}\n"
  },
  {
    "path": "visualvm/graalvm/src/org/graalvm/visualvm/graalvm/svm/SVMMonitoredDataImpl.java",
    "content": "/*\n * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.graalvm.svm;\n\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.MonitoredValue;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class SVMMonitoredDataImpl extends MonitoredData {\n    private static final String ProcessCPUTime_COUNTER_NAME = \"com.oracle.svm.processCPUTime\";   // NOI18N\n\n  SVMMonitoredDataImpl(Jvm jvm, JvmstatModel monitoredVm, JvmJvmstatModel jvmstatModel) {\n    this.monitoredVm = jvm;\n    loadedClasses = jvmstatModel.getLoadedClasses();\n    sharedLoadedClasses = jvmstatModel.getSharedLoadedClasses();\n    sharedUnloadedClasses = jvmstatModel.getSharedUnloadedClasses();\n    unloadedClasses = jvmstatModel.getUnloadedClasses();\n    threadsDaemon = jvmstatModel.getThreadsDaemon();\n    threadsLive = jvmstatModel.getThreadsLive();\n    threadsLivePeak = jvmstatModel.getThreadsLivePeak();\n    threadsStarted = jvmstatModel.getThreadsStarted();\n    applicationTime = jvmstatModel.getApplicationTime()/(jvmstatModel.getOsFrequency()/1000);\n    upTime = jvmstatModel.getUpTime()/(jvmstatModel.getOsFrequency()/1000);\n    genCapacity = jvmstatModel.getGenCapacity();\n    genUsed = jvmstatModel.getGenUsed();\n    genMaxCapacity = jvmstatModel.getGenMaxCapacity();\n    MonitoredValue cpuTimeVal = monitoredVm.findMonitoredValueByName(ProcessCPUTime_COUNTER_NAME);\n    if (cpuTimeVal != null) {\n        processCpuTime = ((Long)cpuTimeVal.getValue()).longValue();\n    }\n  }\n\n}\n"
  },
  {
    "path": "visualvm/heapdump/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.heapdump\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.heapdump.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/heapdump/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.heapdump/2\nOpenIDE-Module-Install: org/graalvm/visualvm/heapdump/Installer.class\nOpenIDE-Module-Layer: org/graalvm/visualvm/heapdump/resources/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/heapdump/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.1\n\n"
  },
  {
    "path": "visualvm/heapdump/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.heapdump-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/heapdump/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=5428a1b3\nbuild.xml.script.CRC32=c00ae7ac\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=5428a1b3\nnbproject/build-impl.xml.script.CRC32=f1cff99d\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/heapdump/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/heapdump/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.heapdump</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.2</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.coredump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.heapviewer</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.2</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.heapwalker</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.sendopts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.43</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.23.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.13.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.11</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.34</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.18.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.heapdump</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/heapdump/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-HeapDump\n\nLBL_Save_Heap_Dump_As=Save Heap Dump As\n\nDESCR_HeapDump=Heap dump.\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/HeapDump.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.heapdump;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsSupport;\nimport java.io.File;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.openide.util.NbBundle;\n\n/**\n * Abstract implementation of HeapDump.\n * Each heapdump is defined by a heapdump file.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class HeapDump extends Snapshot {\n    \n    private static final String HWCACHE_EXT = \".hwcache\"; // NOI18N\n    \n    /**\n     * Creates new instance of HeapDump with the data stored in a file.\n     * \n     * @param file file where heap dump is saved.\n     */\n    public HeapDump(File file) {\n        this(file, null);\n    }\n    \n    /**\n     * Creates new instance of HeapDump with the data stored in a file and defined master.\n     * \n     * @param file file where heap dump is saved,\n     * @param master DataSource in whose window the heap dump will be displayed.\n     */\n    public HeapDump(File file, DataSource master) {\n        super(file, HeapDumpSupport.getInstance().getCategory(), master);\n    }\n    \n    public boolean supportsSaveAs() {\n        return getFile() != null;\n    }\n    \n    public void saveAs() {\n        SnapshotsSupport.getInstance().saveAs(this, NbBundle.getMessage(HeapDump.class, \"LBL_Save_Heap_Dump_As\"));  // NOI18N\n    }\n    \n    protected void remove() {\n        final File f = getFile();\n        \n        // #GH-111: delete the corresponding .hwcache directory\n        if (f != null) Utils.FILE_QUEUE.post(new Runnable() {\n            public void run() {\n                File ff = new File(f.getParent(), f.getName() + HWCACHE_EXT);\n                if (ff.isDirectory()) Utils.delete(ff, true);\n            }\n        });\n        \n        super.remove();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/HeapDumpDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.heapdump;\n\nimport org.graalvm.visualvm.core.snapshot.SnapshotDescriptor;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsSupport;\nimport java.awt.Image;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n\n/**\n * DataSourceDescriptor for HeapDump.\n *\n * @author Jiri Sedlacek\n */\npublic class HeapDumpDescriptor extends SnapshotDescriptor<HeapDump> {\n\n    private static final Image ICON = SnapshotsSupport.getInstance().createSnapshotIcon(\n            ImageUtilities.loadImage(\"org/graalvm/visualvm/heapdump/resources/heapdumpBase.png\", true)); // NOI18N\n\n    /**\n     * Creates new instance of HeapDumpDescriptor.\n     * \n     * @param heapDump HeapDump for the descriptor.\n     */\n    public HeapDumpDescriptor(HeapDump heapDump) {\n        super(heapDump, NbBundle.getMessage(HeapDumpDescriptor.class,\n              \"DESCR_HeapDump\"), ICON); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/HeapDumpSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapdump;\n\nimport org.graalvm.visualvm.heapdump.impl.HeapDumpDescriptorProvider;\nimport org.graalvm.visualvm.heapdump.impl.HeapDumpCategory;\nimport org.graalvm.visualvm.heapdump.impl.HeapDumpViewProvider;\nimport org.graalvm.visualvm.heapdump.impl.HeapDumpProvider;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.snapshot.RegisteredSnapshotCategories;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\n\n/**\n * Support for heap dumps in VisualVM.\n *\n * @author Jiri Sedlacek\n */\npublic final class HeapDumpSupport {\n\n    private static HeapDumpSupport instance;\n\n    private final SnapshotCategory<HeapDump> category = new HeapDumpCategory();\n    private final HeapDumpProvider heapDumpProvider;\n    private final HeapDumpViewProvider heapDumpViewProvider;\n\n\n    /**\n     * Returns singleton instance of HeapDumpSupport.\n     * \n     * @return singleton instance of HeapDumpSupport.\n     */\n    public static synchronized HeapDumpSupport getInstance() {\n        if (instance == null) instance = new HeapDumpSupport();\n        return instance;\n    }\n    \n    \n    /**\n     * Returns SnapshotCategory instance for heap dumps.\n     * \n     * @return SnapshotCategory instance for heap dumps.\n     */\n    public SnapshotCategory<HeapDump> getCategory() {\n        return category;\n    }\n    \n    /**\n     * Returns true if taking heap dumps is supported for the application, false otherwise.\n     * \n     * @param application application from which to take the heap dump.\n     * @return true if taking heap dumps is supported for the application, false otherwise.\n     */\n    public boolean supportsHeapDump(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        return JvmFactory.getJVMFor(application).isTakeHeapDumpSupported();\n    }\n    \n    /**\n     * Takes heap dump from Application.\n     * \n     * @param application Application to take the heap dump,\n     * @param openView true if taken heap dump should be opened, false otherwise.\n     */\n    public void takeHeapDump(Application application, boolean openView) {\n        heapDumpProvider.createHeapDump(application, openView);\n    }\n    \n    /**\n     * Returns true if taking heap dumps is supported for the remote application.\n     * \n     * @param application remote application from which to take the heap dump\n     * @return true if taking heap dumps is supported for the remote application, false otherwise\n     */\n    public boolean supportsRemoteHeapDump(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        if (application.isLocalApplication()) return false; // Should be allowed???\n        JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);\n        return jmxModel != null && jmxModel.isTakeHeapDumpSupported();\n    }\n    \n    /**\n     * Takes heap dump from remote Application.\n     * \n     * @param application remote Application to take the heap dump\n     * @param dumpFile target dump file on the remote machine\n     * @param customizeDumpFile true if the dumpFile customization dialog should be displayed, false otherwise\n     */\n    public void takeRemoteHeapDump(Application application, String dumpFile,\n                                   boolean customizeDumpFile) {\n        heapDumpProvider.createRemoteHeapDump(application, dumpFile, customizeDumpFile);\n    }\n    \n    /**\n     * Takes heap dump from CoreDump.\n     * \n     * @param coreDump CoreDump to take the heap dump,\n     * @param openView true if taken heap dump should be opened, false otherwise.\n     */\n    public void takeHeapDump(CoreDump coreDump, boolean openView) {\n        heapDumpProvider.createHeapDump(coreDump, openView);\n    }\n    \n    \n    /**\n     * Returns PluggableDataSourceViewProvider for heap dumps.\n     * \n     * @return PluggableDataSourceViewProvider for heap dumps.\n     */\n    public PluggableDataSourceViewProvider<HeapDump> getHeapDumpView() {\n        return heapDumpViewProvider;\n    }\n\n\n    private HeapDumpSupport() {\n        DataSourceDescriptorFactory.getDefault().registerProvider(new HeapDumpDescriptorProvider());\n        heapDumpProvider = new HeapDumpProvider();\n        heapDumpProvider.initialize();\n        \n        heapDumpViewProvider = new HeapDumpViewProvider();\n        RegisteredSnapshotCategories.sharedInstance().registerCategory(category);\n\n        heapDumpViewProvider.initialize();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapdump;\n\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\nfinal class Installer extends ModuleInstall {\n    \n    public void restored() {\n        HeapDumpSupport.getInstance();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/impl/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nMSG_Heap_Dump=&Heap Dump\n\nLBL_Heap_Dump=Heap Dump\n\nLBL_Heap_Dumps=Heap Dumps\n\nLBL_Heap_Dump_on_OOME=Heap Dump on &OOME\n\nDESCR_Heap_Dump_on_OOME=Control whether to dump heap when an OOME occurs\n\n#LBL_Disable_Heap_Dump_on_OOME=&Disable Heap Dump on OOME\n\n#DESCR_Disable_Heap_Dump_on_OOME=Disable Heap Dump on OOME\n\n#LBL_Enable_Heap_Dump_on_OOME=&Enable Heap Dump on OOME\n\n#DESCR_Enable_Heap_Dump_on_OOME=Enable Heap Dump on OOME\n\nMSG_Cannot_take_heap_dump=Cannot take heap dump for \n\nLBL_Creating_Heap_Dump=Creating Heap Dump...\n\nLBL_Loading_Heap_Dump=Loading heap dump...\n\nLBL_Loading_Heap_Dump_failed=Loading Heap Dump failed.\n\nLBL_Loading_Heap_Dump_failed2=Loading failed: {0}\n\nMSG_Opening_Heap_Dump=Opening Heap Dump...\n\nMSG_Opening_Heap_Dump_failed=Opening heap dump failed.\n\nCAPTION_Remote_heap_dump=Remote Heap Dump\n\nMSG_Remote_heap_dump=&Heap dump file to be created on the remote system\\:\n\nMSG_Dump_failed=Failed to take remote heap dump for this application.\n\nMSG_Dump_save_failed=Failed to create remote heap dump and save it\\:\\n{0}\n\nMSG_Dump_ok=Heap dump has been created and saved on the remote system:\\n{0}\\n\\nMove the file to the local system and use File | Load... action to open it.\n\nArgument_ShortDescr=take heap dump of the provided process\n\nMSG_NO_APP_PID = Cannot find application with pid {0}.\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/impl/HeapDumpAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.heapdump.impl;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.core.ui.actions.MultiDataSourceAction;\nimport org.graalvm.visualvm.heapdump.HeapDumpSupport;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.openide.util.NbBundle;\n\n    \n/**\n *\n * @author Jiri Sedlacek\n */\nclass HeapDumpAction extends MultiDataSourceAction<DataSource> {\n    \n    private Set<Application> lastSelectedApplications = new HashSet<>();\n    private final PropertyChangeListener stateListener = new PropertyChangeListener() {\n        public void propertyChange(PropertyChangeEvent evt) {\n            updateState(ActionUtils.getSelectedDataSources());\n        }\n    };\n    \n    private static HeapDumpAction INSTANCE;\n    \n    public static synchronized HeapDumpAction instance() {\n        if (INSTANCE == null) INSTANCE = new HeapDumpAction();\n        return INSTANCE;\n    }\n    \n    \n    protected void actionPerformed(Set<DataSource> dataSources, ActionEvent actionEvent) {\n        HeapDumpSupport support = HeapDumpSupport.getInstance();\n        for (DataSource dataSource : dataSources) {\n            if (dataSource instanceof Application) {\n                Application application = (Application)dataSource;\n                boolean tagged = (actionEvent.getModifiers() & Toolkit.\n                        getDefaultToolkit().getMenuShortcutKeyMask()) != 0;\n                if (application.isLocalApplication()) {\n                    support.takeHeapDump(application, !tagged); \n                } else {\n                    support.takeRemoteHeapDump(application, null, !tagged);\n                }\n            } else if (dataSource instanceof CoreDump) {\n                CoreDump coreDump = (CoreDump)dataSource;\n                support.takeHeapDump(coreDump, (actionEvent.getModifiers() &\n                        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n            }\n        }\n    }\n    \n    protected boolean isEnabled(Set<DataSource> dataSources) {\n        HeapDumpSupport support = HeapDumpSupport.getInstance();\n        for (DataSource dataSource : dataSources)\n            if (dataSource instanceof Application) {\n                // TODO: Listener should only be registered when heap dump is supported for the application\n                Application application = (Application)dataSource;\n                lastSelectedApplications.add(application);\n                application.addPropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n                if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n                if (application.isLocalApplication()) {\n                    if (!support.supportsHeapDump(application)) return false;\n                } else {\n                    if (!support.supportsRemoteHeapDump(application)) return false;\n                }\n            } else if (!(dataSource instanceof CoreDump)) return false;\n        return true;\n    }\n    \n    protected void updateState(Set<DataSource> dataSources) {\n        if (!lastSelectedApplications.isEmpty())\n            for (Application application : lastSelectedApplications)\n                application.removePropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n        lastSelectedApplications.clear();\n        super.updateState(dataSources);\n    }\n    \n    \n    private HeapDumpAction() {\n        super(DataSource.class);\n        putValue(NAME, NbBundle.getMessage(HeapDumpAction.class, \"MSG_Heap_Dump\")); // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(HeapDumpAction.class, \"LBL_Heap_Dump\"));    // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/impl/HeapDumpArgument.java",
    "content": "/*\n * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapdump.impl;\n\nimport java.util.Collections;\nimport java.util.Map;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.ApplicationFinder;\nimport org.graalvm.visualvm.heapdump.HeapDumpSupport;\nimport org.netbeans.api.sendopts.CommandException;\nimport org.netbeans.spi.sendopts.Env;\nimport org.netbeans.spi.sendopts.Option;\nimport org.netbeans.spi.sendopts.OptionProcessor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=OptionProcessor.class)\npublic final class HeapDumpArgument extends OptionProcessor {\n    \n    private static final String LONG_NAME = \"heapdump\";                         // NOI18N\n    private static final Option ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, LONG_NAME), \"org.graalvm.visualvm.heapdump.impl.Bundle\", \"Argument_ShortDescr\"); // NOI18N\n    \n    \n    @Override\n    protected Set<Option> getOptions() {\n        return Collections.singleton(ARGUMENT);\n    }\n    \n    @Override\n    protected void process(Env env, Map<Option, String[]> maps) throws CommandException {\n        String[] pids = maps.get(ARGUMENT);\n        if (pids != null && pids.length == 1) {\n            try {\n                int pid = Integer.valueOf(pids[0]);\n                new ApplicationFinder(pid) {\n                    @Override\n                    public void found(Application application) {\n                        HeapDumpSupport.getInstance().takeHeapDump(application, true);\n                    }\n                    @Override\n                    public void notFound(int pid, String id) {\n                        NotifyDescriptor desc = new NotifyDescriptor.Message(NbBundle.getMessage(HeapDumpArgument.class, \"MSG_NO_APP_PID\", new Object[] { Integer.toString(pid) }), NotifyDescriptor.WARNING_MESSAGE);\n                        DialogDisplayer.getDefault().notifyLater(desc);\n                    }\n                }.find();\n            } catch (NumberFormatException e) {\n                throw new CommandException(0, \"Incorrect pid format for --\" + LONG_NAME + \": \" + e.getMessage()); // NOI18N\n            }\n        } else {\n            throw new CommandException(0, \"--\" + LONG_NAME + \" requires exactly one value\"); // NOI18N\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/impl/HeapDumpCategory.java",
    "content": "/*\n *  Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.heapdump.impl;\n\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.heapdump.HeapDump;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\nimport javax.swing.filechooser.FileFilter;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic class HeapDumpCategory extends SnapshotCategory<HeapDump> {\n    \n    private static final String HPROF_HEADER = \"JAVA PROFILE 1.0\";  // NOI18N\n    private static final long MIN_HPROF_SIZE = 1024*1024L;\n    private static final String NAME = NbBundle.getMessage(HeapDumpCategory.class, \"LBL_Heap_Dumps\");   // NOI18N\n    private static final String PREFIX = \"heapdump\";    // NOI18N\n    private static final String SUFFIX = \".hprof\";  // NOI18N\n    \n    public HeapDumpCategory() {\n        super(NAME, HeapDump.class, PREFIX, SUFFIX, 20);\n    }\n    \n    public boolean supportsOpenSnapshot() {\n        return true;\n    }\n    \n    public void openSnapshot(File file) {\n        DataSourceWindowManager.sharedInstance().openDataSource(new HeapDumpImpl(file, null)); // TODO: instance should be created by HeapDumpProvider!\n    }\n\n    protected boolean isSnapshot(File file) {\n        if (super.isSnapshot(file)) {\n            return true;\n        }\n        return checkHprofFile(file);\n    }\n\n    private boolean checkHprofFile(File file) {\n        if (file.isFile() && file.canRead() && file.length()>MIN_HPROF_SIZE) { // heap dump must be 1M and bigger\n            try (RandomAccessFile raf = new RandomAccessFile(file,\"r\")) {   // NOI18N\n                byte[] prefix = new byte[HPROF_HEADER.length()+4];\n                raf.readFully(prefix);\n                if (new String(prefix).startsWith(HPROF_HEADER)) {\n                    return true;\n                }\n            } catch (IOException ex) {\n                return false;\n            }\n        }\n        return false;\n    }\n\n    public FileFilter getFileFilter() {\n        return new FileFilter() {\n            public boolean accept(File f) {\n                return f.isDirectory() || isSnapshot(f);\n            }\n            public String getDescription() {\n                String suff = getSuffix();\n                return getName() + (suff != null ? \" (*\" + suff +\", *.*\"+ \")\" : \"\");    // NOI18N\n            }\n        };\n    }    \n    \n}\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/impl/HeapDumpDescriptorProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapdump.impl;\n\nimport org.graalvm.visualvm.heapdump.*;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class HeapDumpDescriptorProvider extends AbstractModelProvider<DataSourceDescriptor,DataSource> {\n    \n    public DataSourceDescriptor createModelFor(DataSource ds) {\n        if (ds instanceof HeapDump) {\n            return new HeapDumpDescriptor((HeapDump) ds);\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/impl/HeapDumpImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapdump.impl;\n\nimport org.graalvm.visualvm.heapdump.HeapDump;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport java.io.File;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal public class HeapDumpImpl extends HeapDump {\n\n    public HeapDumpImpl(File file, DataSource master) {\n        super(file, master);\n    }\n    \n    \n    void forceViewClosable(boolean closable) {\n        getStorage().setCustomProperty(PROPERTY_VIEW_CLOSABLE, Boolean.toString(closable));\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/impl/HeapDumpOnOOMEAction.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapdump.impl;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport java.awt.event.ActionEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.Set;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JMenuItem;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.actions.Presenter;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n * @author Luis-Miguel Alventosa\n */\nclass HeapDumpOnOOMEAction extends SingleDataSourceAction<Application> implements Presenter.Popup {\n    \n    private boolean oomeEnabled;\n    private Application lastSelectedApplication;\n    private final PropertyChangeListener stateListener = new PropertyChangeListener() {\n        public void propertyChange(PropertyChangeEvent evt) {\n            updateState(ActionUtils.getSelectedDataSources(Application.class));\n        }\n    };\n    \n    private static HeapDumpOnOOMEAction instance;\n    \n    public static synchronized HeapDumpOnOOMEAction instance() {\n        if (instance == null) \n            instance = new HeapDumpOnOOMEAction();\n        return instance;\n    }\n    \n\n    protected void actionPerformed(Application application, ActionEvent actionEvent) {\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        jvm.setDumpOnOOMEnabled(!oomeEnabled);\n        updateState(jvm);\n    }\n\n    protected boolean isEnabled(Application application) {\n        lastSelectedApplication = application;\n        lastSelectedApplication.addPropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        if (!jvm.isDumpOnOOMEnabledSupported()) return false;\n        updateState(jvm);\n        return true;\n    }\n    \n    \n    private void updateState(Jvm jvm) {\n        oomeEnabled = jvm.isDumpOnOOMEnabled();\n    }\n    \n    protected void updateState(Set<Application> applications) {\n        if (lastSelectedApplication != null) {\n            lastSelectedApplication.removePropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n            lastSelectedApplication = null;\n        }\n        super.updateState(applications);\n    }\n    \n    \n    @Override\n    public JMenuItem getPopupPresenter() {\n        JMenuItem presenter = new JCheckBoxMenuItem(this);\n        Mnemonics.setLocalizedText(presenter, NbBundle.getMessage(HeapDumpOnOOMEAction.class, \"LBL_Heap_Dump_on_OOME\")); // NOI18N\n        presenter.setSelected(oomeEnabled);\n        return presenter;\n    }\n    \n    \n    private HeapDumpOnOOMEAction() {\n        super(Application.class);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/impl/HeapDumpProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapdump.impl;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.heapdump.HeapDumpSupport;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.sa.SaModel;\nimport org.graalvm.visualvm.tools.sa.SaModelFactory;\nimport java.awt.BorderLayout;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.HashSet;\nimport java.util.Properties;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTextField;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic class HeapDumpProvider {\n    \n    private final static Logger LOGGER = Logger.getLogger(HeapDumpProvider.class.getName());\n    \n    public void createHeapDump(final Application application, final boolean openView) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                Jvm jvm = JvmFactory.getJVMFor(application);\n                if (!jvm.isTakeHeapDumpSupported()) {\n                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.\n                            Message(NbBundle.getMessage(HeapDumpProvider.class,\n                            \"MSG_Cannot_take_heap_dump\") + DataSourceDescriptorFactory. // NOI18N\n                            getDescriptor(application).getName(), NotifyDescriptor.ERROR_MESSAGE));\n                    return;\n                }\n                \n                ProgressHandle pHandle = null;\n                try {\n                    pHandle = ProgressHandle.createHandle(NbBundle.getMessage(\n                            HeapDumpProvider.class, \"LBL_Creating_Heap_Dump\"));    // NOI18N\n                    pHandle.setInitialDelay(0);\n                    pHandle.start();\n                    try {\n                        File snapshotDir = application.getStorage().getDirectory();\n                        String name = HeapDumpSupport.getInstance().getCategory().createFileName();\n                        File file = new File(snapshotDir,name);\n                        if (jvm.takeHeapDump(file) && file.isFile()) {\n                            final HeapDumpImpl heapDump = new HeapDumpImpl(file, application);\n                            application.getRepository().addDataSource(heapDump);\n                            if (openView) DataSource.EVENT_QUEUE.post(new Runnable() {\n                                public void run() { DataSourceWindowManager.sharedInstance().openDataSource(heapDump); }\n                            });\n                        } else {\n                            notifyHeapDumpFailed(application);\n                        }\n                    } catch (IOException ex) {\n                        LOGGER.log(Level.INFO, \"createHeapDump-Application\", ex); // NOI18N\n                        notifyHeapDumpFailed(application);\n                    }\n                } finally {\n                    final ProgressHandle pHandleF = pHandle;\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { if (pHandleF != null) pHandleF.finish(); }\n                    });\n                }\n            }\n        });\n    }\n    \n    public void createRemoteHeapDump(final Application application, final String dumpFile,\n                                     final boolean customizeDumpFile) {\n        \n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                JmxModel model = JmxModelFactory.getJmxModelFor(application);\n                if (model == null || !model.isTakeHeapDumpSupported()) {\n                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.\n                            Message(NbBundle.getMessage(HeapDumpProvider.class,\n                            \"MSG_Dump_failed\"), NotifyDescriptor.ERROR_MESSAGE)); // NOI18N\n                    return;\n                }\n                \n                String file = dumpFile;\n                if (file == null) file = defineRemoteFile(model, customizeDumpFile);\n                if (file == null) return;\n\n                if (model.takeHeapDump(file)) {\n                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.\n                            Message(NbBundle.getMessage(HeapDumpProvider.class,\n                            \"MSG_Dump_ok\", file), NotifyDescriptor.INFORMATION_MESSAGE)); // NOI18N\n                } else {\n                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.\n                            Message(NbBundle.getMessage(HeapDumpProvider.class,\n                            \"MSG_Dump_save_failed\", file), NotifyDescriptor.ERROR_MESSAGE)); // NOI18N\n                }\n            }\n        });\n    }\n    \n    private static String defineRemoteFile(JmxModel model, boolean customizeDumpFile) {\n        final String[] path = new String[1];\n        path[0] = defaultHeapDumpPath(model);\n        \n        if (customizeDumpFile) try {\n            SwingUtilities.invokeAndWait(new Runnable() {\n                public void run() {\n                    JLabel label = new JLabel();\n                    Mnemonics.setLocalizedText(label, NbBundle.getMessage(\n                            HeapDumpProvider.class, \"MSG_Remote_heap_dump\")); // NOI18N\n                    label.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));\n                    JTextField field = new JTextField();\n                    label.setLabelFor(field);\n                    field.setText(path[0]);\n                    Dimension dim = field.getPreferredSize();\n                    dim.width = 350;\n                    field.setPreferredSize(dim);\n                    field.selectAll();\n                    JPanel selector = new JPanel(new BorderLayout());\n                    selector.setBorder(BorderFactory.createEmptyBorder(15, 10, 5, 10));\n                    selector.add(label, BorderLayout.NORTH);\n                    selector.add(field, BorderLayout.SOUTH);\n\n                    DialogDescriptor dd = new DialogDescriptor(selector,\n                            NbBundle.getMessage(HeapDumpProvider.class,\n                            \"CAPTION_Remote_heap_dump\"), true, null); // NOI18N\n                    Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n                    d.pack();\n                    d.setVisible(true);\n\n                    path[0] = dd.getValue() == DialogDescriptor.OK_OPTION ?\n                                               field.getText() : null;\n                }\n            });\n        } catch (Throwable t) {\n            path[0] = null;\n        }\n        \n        return path[0];\n    }\n    \n    private static String defaultHeapDumpPath(JmxModel model) {\n        String fileName = HeapDumpSupport.getInstance().getCategory().createFileName();\n        \n        Properties sysprops = model.getSystemProperties();\n        if (sysprops == null) return fileName;\n        String heapDumpTarget = getHeapDumpTarget(sysprops);\n        if (heapDumpTarget == null || heapDumpTarget.isEmpty()) return fileName;\n        \n        String pathsep = sysprops.getProperty(\"file.separator\"); // NOI18N\n        if (!heapDumpTarget.endsWith(pathsep)) heapDumpTarget += pathsep;\n        return heapDumpTarget + fileName;\n    }\n    \n    // OS codes listed in org.graalvm.visualvm.lib.jfluid.global.Platform.getOperatingSystem()\n    private static String getHeapDumpTarget(Properties sysprops) {\n        String targetDir = null;\n        \n        // Select directory based on target OS\n        String osName = sysprops.getProperty(\"os.name\"); // NOI18N\n        if (osName != null) {\n            if (osName.equals(\"Solaris\") || osName.startsWith(\"SunOS\")) // NOI18N\n                targetDir = sysprops.getProperty(\"user.home\"); // NOI18N\n            else\n                targetDir = sysprops.getProperty(\"java.io.tmpdir\"); // NOI18N\n        }\n        \n        // Fallback to current working directory\n        if (targetDir == null) targetDir = sysprops.getProperty(\"user.dir\"); // NOI18N\n        \n        return targetDir;\n    }\n    \n    public void createHeapDump(final CoreDump coreDump, final boolean openView) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                ProgressHandle pHandle = null;\n                try {\n                    pHandle = ProgressHandle.createHandle(NbBundle.getMessage(\n                            HeapDumpProvider.class, \"LBL_Creating_Heap_Dump\"));    // NOI18N\n                    pHandle.setInitialDelay(0);\n                    pHandle.start();\n                    File snapshotDir = coreDump.getStorage().getDirectory();\n                    String name = HeapDumpSupport.getInstance().getCategory().createFileName();\n                    File dumpFile = new File(snapshotDir,name);\n                    SaModel saAget = SaModelFactory.getSAAgentFor(coreDump);\n                    try {\n                        if (saAget.takeHeapDump(dumpFile.getAbsolutePath())) {\n                            final HeapDumpImpl heapDump = new HeapDumpImpl(dumpFile, coreDump);\n                            coreDump.getRepository().addDataSource(heapDump);\n                            if (openView) DataSource.EVENT_QUEUE.post(new Runnable() {\n                                public void run() { DataSourceWindowManager.sharedInstance().openDataSource(heapDump); }\n                            });\n                        } else {\n                            notifyHeapDumpFailed(coreDump);\n                        }\n                    } catch (Exception ex) {\n                        LOGGER.log(Level.INFO, \"createHeapDump-CoreDump\", ex); // NOI18N\n                        notifyHeapDumpFailed(coreDump);\n                    }\n                } finally {\n                    final ProgressHandle pHandleF = pHandle;\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { if (pHandleF != null) pHandleF.finish(); }\n                    });\n                }\n            }\n        });\n    }\n    \n    public void initialize() {\n        DataSourceRepository.sharedInstance().addDataChangeListener(new SnapshotListener(), Snapshot.class);\n        DataSourceRepository.sharedInstance().addDataChangeListener(new ApplicationListener(), Application.class);\n    }\n    \n    \n    private void processNewSnapshot(Snapshot snapshot) {\n        if (snapshot instanceof HeapDumpImpl) return;\n        boolean appSnapshot = snapshot instanceof ApplicationSnapshot;\n        File snapshotFile = snapshot.getFile();\n        if (snapshotFile != null && snapshotFile.isDirectory()) {\n            File[] files = snapshotFile.listFiles(HeapDumpSupport.getInstance().getCategory().getFilenameFilter());\n            if (files == null) return;\n            Set<HeapDumpImpl> heapDumps = new HashSet<>();\n            for (File file : files) {\n                HeapDumpImpl heapDump = new HeapDumpImpl(file, snapshot);\n                if (appSnapshot) heapDump.forceViewClosable(true);\n                heapDumps.add(heapDump);\n            }\n            snapshot.getRepository().addDataSources(heapDumps);\n        }\n    }\n    \n    private void processNewApplication(Application application) {\n        Storage storage = application.getStorage();\n        if (storage.directoryExists()) {\n            File[] files = storage.getDirectory().listFiles(HeapDumpSupport.getInstance().getCategory().getFilenameFilter());\n            if (files == null) return;\n            Set<HeapDumpImpl> heapDumps = new HashSet<>();\n            for (File file : files) heapDumps.add(new HeapDumpImpl(file, application));\n            application.getRepository().addDataSources(heapDumps);\n        }\n    }\n    \n    private void notifyHeapDumpFailed(final DataSource dataSource) {\n        String displayName = DataSourceDescriptorFactory.getDescriptor(dataSource).getName();\n        DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.\n                Message(NbBundle.getMessage(HeapDumpProvider.class,\n                \"MSG_Cannot_take_heap_dump\") + displayName, // NOI18N\n                NotifyDescriptor.ERROR_MESSAGE));\n    }\n    \n    \n    private class SnapshotListener implements DataChangeListener<Snapshot> {\n        \n        public void dataChanged(DataChangeEvent<Snapshot> event) {\n            final Set<Snapshot> snapshots = event.getAdded();\n            if (!snapshots.isEmpty()) VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    for (Snapshot snapshot : snapshots) processNewSnapshot(snapshot);\n                }\n            });\n        }\n        \n    }\n    \n    private class ApplicationListener implements DataChangeListener<Application> {\n        \n        public void dataChanged(DataChangeEvent<Application> event) {\n            final Set<Application> applications = event.getAdded();\n            if (!applications.isEmpty()) VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    for (Application application : applications) processNewApplication(application);\n                }\n            });\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/impl/HeapDumpView.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapdump.impl;\n\nimport java.awt.BorderLayout;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.snapshot.SnapshotView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.heapdump.HeapDump;\nimport org.graalvm.visualvm.heapviewer.HeapViewer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nclass HeapDumpView extends SnapshotView {\n    \n    private final static Logger LOGGER = Logger.getLogger(HeapDumpView.class.getName());\n    \n    \n    private MasterViewSupport mvs;\n    \n    \n    HeapDumpView(HeapDump heapDump) {\n        this(heapDump, DataSourceDescriptorFactory.getDescriptor(heapDump));\n    }\n    \n    private HeapDumpView(HeapDump heapDump, DataSourceDescriptor descriptor) {\n        super(heapDump, descriptor.getName(), descriptor.getIcon(), 0);\n    }\n    \n        \n    protected DataViewComponent createComponent() {\n        HeapDump heapDump = (HeapDump)getDataSource();\n        mvs = new MasterViewSupport(heapDump);\n        DataViewComponent dvc = new DataViewComponent(mvs.getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(true));\n        \n        return dvc;\n    }\n    \n    protected void willBeRemoved() {\n        if (mvs != null) mvs.willBeRemoved();\n    }\n    \n    protected void removed() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { if (mvs != null) mvs.closed(); }\n        });\n    }\n    \n    \n    // --- General data --------------------------------------------------------\n    \n    private static class MasterViewSupport extends JPanel  {\n        \n        private JLabel progressLabel;\n        private JPanel contentsPanel;\n        \n        private HeapViewer heapViewer;\n        \n        MasterViewSupport(HeapDump heapDump) {\n            File file = heapDump.getFile();\n            initComponents(file != null);\n            if (file != null) loadHeap(file);\n        }\n        \n        \n        public DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(HeapDumpView.class, \"LBL_Heap_Dump\"), null, new ScrollableContainer(this)); // NOI18N\n        }\n        \n        \n        void willBeRemoved() {\n            if (heapViewer != null) heapViewer.willBeRemoved();\n        }\n        \n        void closed() {\n            if (heapViewer != null) heapViewer.closed();\n        }\n        \n        \n        private void initComponents(boolean hasDump) {\n            setLayout(new BorderLayout());\n            \n            String label = hasDump ? NbBundle.getMessage(HeapDumpView.class, \"LBL_Loading_Heap_Dump\") :    // NOI18N\n                                     NbBundle.getMessage(HeapDumpView.class, \"LBL_Loading_Heap_Dump_failed\");    // NOI18N\n            progressLabel = new JLabel(label, SwingConstants.CENTER);\n        \n            contentsPanel = new JPanel(new BorderLayout());\n            contentsPanel.add(progressLabel, BorderLayout.CENTER);\n            contentsPanel.setOpaque(false);\n            \n            add(contentsPanel, BorderLayout.CENTER);\n            setOpaque(false);\n        }\n        \n        private void loadHeap(final File file) {\n          VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n              try {\n                final HeapViewer _heapViewer = new HeapViewer(file);\n                SwingUtilities.invokeLater(new Runnable() { public void run() {\n                    heapViewer = _heapViewer;\n                    contentsPanel.remove(progressLabel);\n                    contentsPanel.add(heapViewer.getComponent(), BorderLayout.CENTER);\n                    contentsPanel.revalidate();\n                    contentsPanel.repaint();\n                } });\n              } catch (final IOException ex) {\n                SwingUtilities.invokeLater(new Runnable() { public void run() {\n                  progressLabel.setText(NbBundle.getMessage(HeapDumpView.class, \"LBL_Loading_Heap_Dump_failed2\", ex.getMessage()));\n                  contentsPanel.revalidate();\n                  contentsPanel.repaint();\n                } });\n                LOGGER.log(Level.INFO, \"Failed to load heap dump\", ex);  // NOI18N\n              }\n            }\n          });\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/impl/HeapDumpViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapdump.impl;\n\nimport org.graalvm.visualvm.heapdump.HeapDump;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\nimport java.util.Set;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class HeapDumpViewProvider extends PluggableDataSourceViewProvider<HeapDump>{\n    \n    protected boolean supportsViewFor(HeapDump heapDump) {\n        return true;\n    }\n\n    protected DataSourceView createView(HeapDump heapDump) {\n        return new HeapDumpView(heapDump);\n    }\n    \n    public Set<Integer> getPluggableLocations(DataSourceView view) {\n        return ALL_LOCATIONS;\n    }\n    \n\n    public void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(this, HeapDump.class);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Support for heap dumps in VisualVM.\n */\npackage org.graalvm.visualvm.heapdump;\n"
  },
  {
    "path": "visualvm/heapdump/src/org/graalvm/visualvm/heapdump/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    \n    <folder name=\"Menu\">\n         <folder name=\"Applications\">\n            <file name=\"org-graalvm-visualvm-heapdump-impl-HeapDumpAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-heapdump-impl-HeapDumpAction.instance\"/>\n                <attr name=\"position\" intvalue=\"2200\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"VisualVM\">\n        <folder name=\"Actions\">\n            <file name=\"org-graalvm-visualvm-heapdump-impl-HeapDumpAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.heapdump.impl.HeapDumpAction.instance\"/>\n            </file>\n        </folder>\n\n        <folder name=\"ExplorerPopupSelection\">\n            \n            <file name=\"org-graalvm-visualvm-heapdump-impl-HeapDumpAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-heapdump-impl-HeapDumpAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1200\"/>\n            </file>\n            \n            <file name=\"HeapDumpOnOOMEAction-Separator-1940.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"1940\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-heapdump-impl-HeapDumpOnOOMEAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.heapdump.impl.HeapDumpOnOOMEAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1950\"/>\n            </file>\n            \n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "visualvm/heapviewer/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.heapviewer\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.heapviewer.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/heapviewer/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.heapviewer/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/heapviewer/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.8\n\n"
  },
  {
    "path": "visualvm/heapviewer/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.heapviewer-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/heapviewer/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=7733c9dd\nbuild.xml.script.CRC32=018997e7\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=7733c9dd\nnbproject/build-impl.xml.script.CRC32=98bf6af8\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/heapviewer/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n"
  },
  {
    "path": "visualvm/heapviewer/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.heapviewer</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.2</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid.heap</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.heapwalker</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.2</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.oql</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.autoupdate.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.53</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.options.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.46</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.68</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.43</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.11</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.34</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.77</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.heapdump</friend>\n                <friend>org.graalvm.visualvm.heapviewer.console</friend>\n                <friend>org.graalvm.visualvm.heapviewer.truffle</friend>\n                <package>org.graalvm.visualvm.heapviewer</package>\n                <package>org.graalvm.visualvm.heapviewer.java</package>\n                <package>org.graalvm.visualvm.heapviewer.model</package>\n                <package>org.graalvm.visualvm.heapviewer.ui</package>\n                <package>org.graalvm.visualvm.heapviewer.utils</package>\n                <package>org.graalvm.visualvm.heapviewer.utils.counters</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/heapviewer/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/Bundle.properties",
    "content": "#\n# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-HeapViewer\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/HeapContext.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class HeapContext {\n    \n    private final File file;\n    private final Lookup.Provider project;\n    private final HeapFragment fragment;\n    \n    private Collection<HeapContext> otherContexts;\n    \n    \n    private HeapContext(File file, Lookup.Provider project, HeapFragment fragment) {\n        this.file = file;\n        this.project = project;\n        this.fragment = fragment;\n    }\n    \n    public File getFile() {\n        return file;\n    }\n    \n    \n    public Lookup.Provider getProject() {\n        return project;\n    }\n    \n    public HeapFragment getFragment() {\n        return fragment;\n    }\n    \n    \n    public Collection<HeapContext> getOtherContexts() {\n        return otherContexts;\n    }\n    \n    \n    public static HeapContext[] allContexts(HeapViewer heapViewer) {\n        File file = heapViewer.getFile();\n        Lookup.Provider project = heapViewer.getProject();\n        \n        List<HeapFragment> fragments = heapViewer.getFragments();\n        List<HeapContext> contexts = new ArrayList<>(fragments.size());\n        \n        for (HeapFragment fragment : fragments)\n            contexts.add(new HeapContext(file, project, fragment));\n        \n        for (HeapContext context : contexts) {\n            List<HeapContext> otherContexts = new ArrayList<>(contexts);\n            otherContexts.remove(context);\n            context.otherContexts = Collections.unmodifiableCollection(otherContexts);\n        }\n        \n        return contexts.toArray(new HeapContext[0]);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/HeapFragment.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class HeapFragment {\n    \n    protected final String id;\n    protected final String name;\n    protected final String description;\n\n    protected final Heap heap;\n\n\n    public HeapFragment(String id, String name, String description, Heap heap) {\n        this.id = id;\n        this.name = name;\n        this.description = description;\n        this.heap = heap;\n    }\n\n\n    public String getID() { return id; }\n\n    public String getName() { return name; }\n\n    public String getDescription() { return description; }\n\n    public Heap getHeap() { return heap; }\n\n    public static abstract class Provider {\n    \n        public abstract List<HeapFragment> getFragments(File heapDumpFile, Lookup.Provider heapDumpProject, Heap heap) throws IOException;\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/HeapViewer.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\nimport javax.swing.JComponent;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.ui.components.NotSupportedDisplayer;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerComponent;\nimport org.graalvm.visualvm.heapviewer.utils.HeapOperations;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.HeapFactory;\nimport org.graalvm.visualvm.lib.jfluid.heap.HeapProgress;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"HeapViewer_LoadingDumpMsg=Loading Heap Dump...\",\n    \"HeapViewer_HeapDumpEmpty=heap dump (no content)\", // Displays 'Not supported for this heap dump (no content)'\n    \"HeapViewer_HeapDumpOOME=heap dump (not enough memory)\" // Displays 'Not supported for this heap dump (not enough memory)'\n})\npublic final class HeapViewer {\n\n    private final File heapDumpFile;\n    private final Lookup.Provider heapDumpProject;\n    \n    private final List<HeapFragment> heapFragments;\n    \n    private JComponent component;\n    \n    \n    public HeapViewer(File file) throws IOException {\n        assert !SwingUtilities.isEventDispatchThread();\n        \n        heapDumpFile = file;\n        heapDumpProject = null;\n        \n        heapFragments = computeHeapFragments(heapDumpFile, heapDumpProject, createHeap(heapDumpFile));\n    }\n\n    \n    public File getFile() {\n        return heapDumpFile;\n    }\n\n    public Lookup.Provider getProject() {\n        return heapDumpProject;\n    }\n    \n    \n    public List<HeapFragment> getFragments() {\n        return heapFragments;\n    }\n    \n    \n    public JComponent getComponent() {\n        if (component == null) {\n            if (heapFragments == null) component = new NotSupportedDisplayer(Bundle.HeapViewer_HeapDumpOOME());\n            else if (heapFragments.isEmpty()) component = new NotSupportedDisplayer(Bundle.HeapViewer_HeapDumpEmpty());\n            else component = new HeapViewerComponent(this);\n        }\n        return component;\n    }\n    \n    \n    public void willBeRemoved() {\n        if (component instanceof HeapViewerComponent)\n            ((HeapViewerComponent)component).willBeClosed();\n    }\n    \n    public void closed() {\n        if (component instanceof HeapViewerComponent)\n            ((HeapViewerComponent)component).closed();\n    }\n\n    \n    private static Heap createHeap(File heapFile) throws IOException {\n        assert !SwingUtilities.isEventDispatchThread();\n        \n        HeapOperations.OpProgressHandle pHandle = null;\n\n        try {\n            pHandle = new HeapOperations.OpProgressHandle(Bundle.HeapViewer_LoadingDumpMsg());\n            pHandle.setInitialDelay(1000);\n            pHandle.start(HeapProgress.PROGRESS_MAX*2);\n            \n            pHandle.setProgress(0);\n            Heap heap = HeapFactory.createHeap(heapFile);\n            \n            pHandle.setProgress(HeapProgress.PROGRESS_MAX);\n            heap.getSummary(); // Precompute HeapSummary within the progress\n\n            return heap;\n        } catch (OutOfMemoryError e) {\n            System.err.println(\"Out of memory in HeapViewer.createHeap: \" + e.getMessage()); // NOI18N\n            HeapUtils.handleOOME(false, e);\n            return null;\n        } finally {\n            if (pHandle != null) pHandle.finish();\n        }\n    }\n    \n    private static List<HeapFragment> computeHeapFragments(File heapDumpFile, Lookup.Provider heapDumpProject, Heap heap) throws IOException {\n        if (heap == null) return null;\n        \n        Collection<? extends HeapFragment.Provider> providers = Lookup.getDefault().lookupAll(HeapFragment.Provider.class);\n        \n        List<HeapFragment> fragments = new ArrayList<>(providers.size());\n        for (HeapFragment.Provider provider : providers) {\n            List<HeapFragment> fragmentsL = provider.getFragments(heapDumpFile, heapDumpProject, heap);\n            if (fragmentsL != null) fragments.addAll(fragmentsL);\n        }\n        return Collections.unmodifiableList(fragments);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/ClassNode.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport java.util.Iterator;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ClassNode extends HeapViewerNode {\n    \n    private final JavaClass jclass;\n    \n    private String name;\n    \n    \n    public ClassNode(JavaClass jclass) {\n        this.jclass = jclass;\n    }\n    \n    \n    public JavaClass getJavaClass() {\n        return jclass;\n    }\n    \n    public Iterator<Instance> getInstancesIterator() {\n        return jclass.getInstancesIterator();\n    }\n    \n    public String getName() {\n        if (name == null) name = jclass.getName();\n        return name;\n    }\n    \n    public int getInstancesCount() {\n        return jclass.getInstancesCount();\n    }\n    \n    public long getOwnSize() {\n        return jclass.getAllInstancesSize();\n    }\n    \n    public long getRetainedSize(Heap heap) {\n        return DataType.RETAINED_SIZE.valuesAvailable(heap) ?\n               jclass.getRetainedSizeByClass() : DataType.RETAINED_SIZE.getNotAvailableValue();\n    }\n    \n    \n    public boolean isLeaf() {\n        return jclass.getInstancesCount() == 0 || super.isLeaf();\n    }\n    \n    public String toString() {\n        return getName();\n    }\n    \n    \n    public boolean equals(Object o) {\n        if (o == this) return true;\n        if (!(o instanceof ClassNode)) return false;\n        return jclass.equals(((ClassNode)o).jclass);\n    }\n    \n    public int hashCode() {\n        return jclass.hashCode();\n    }\n    \n    \n    protected Object getValue(DataType type, Heap heap) {\n        if (type == DataType.NAME) return getName();\n        if (type == DataType.COUNT) return getInstancesCount();\n        if (type == DataType.OWN_SIZE) return getOwnSize();\n        if (type == DataType.RETAINED_SIZE) return getRetainedSize(heap);\n        \n        if (type == DataType.CLASS) return getJavaClass();\n        \n        if (type == DataType.OBJECT_ID) return getJavaClass().getJavaClassId();\n        \n        if (type == DataType.INSTANCES_WRAPPER) return new InstancesWrapper.Simple(getJavaClass(), getInstancesCount()) {\n            @Override\n            public Iterator<Instance> getInstancesIterator() {\n                return ClassNode.this.getInstancesIterator();\n            }\n        };\n        \n        return super.getValue(type, heap);\n    }\n    \n    \n    public ClassNode createCopy() {\n        ClassNode copy = new ClassNode(getJavaClass());\n        setupCopy(copy);\n        return copy;\n    }\n    \n    protected void setupCopy(ClassNode copy) {\n        super.setupCopy(copy);\n        copy.name = name;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/ClassNodeRenderer.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ClassNodeRenderer extends JavaNameRenderer implements HeapViewerRenderer {\n    \n    public ClassNodeRenderer(Heap heap) {\n        this(Icons.getIcon(LanguageIcons.CLASS), heap);\n    }\n    \n    public ClassNodeRenderer(Icon icon, Heap heap) {\n        super(icon);\n    }\n    \n    \n    public void setValue(Object value, int row) {\n        super.setValue(value, row);\n        if (value == null) setIcon(null);\n    }\n    \n    \n    public String getShortName() {\n        return getBoldValue();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/ClassesContainer.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport org.graalvm.visualvm.heapviewer.model.ContainerNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ClassesContainer_MoreNodes=<another {0} classes left>\",\n    \"ClassesContainer_SamplesContainer=<sample {0} classes>\",\n    \"ClassesContainer_NodesContainer=<classes {0}-{1}>\"\n})\npublic final class ClassesContainer {\n    \n    private ClassesContainer() {}\n    \n    \n    private static String getMoreNodesString(String moreNodesCount)  {\n        return Bundle.ClassesContainer_MoreNodes(moreNodesCount);\n    }\n    \n    private static String getSamplesContainerString(String objectsCount)  {\n        return Bundle.ClassesContainer_SamplesContainer(objectsCount);\n    }\n    \n    private static String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n        return Bundle.ClassesContainer_NodesContainer(firstNodeIdx, lastNodeIdx);\n    }\n    \n    \n    public static class Objects extends ContainerNode<JavaClass> {\n    \n        public Objects(String name) {\n            this(name, UIThresholds.MAX_CONTAINER_CLASSES);\n        }\n\n        public Objects(String name, int maxItems) {\n            super(name, maxItems);\n        }\n\n        protected int getCount(JavaClass item, Heap heap) {\n            return item.getInstancesCount();\n        }\n\n        protected long getOwnSize(JavaClass item, Heap heap) {\n            return item.getAllInstancesSize();\n        }\n\n        protected long getRetainedSize(JavaClass item, Heap heap) {\n            return DataType.RETAINED_SIZE.valuesAvailable(heap) ?\n                   item.getRetainedSizeByClass(): DataType.RETAINED_SIZE.getNotAvailableValue();\n        }\n\n        protected ClassNode createNode(JavaClass javaClass) {\n            return new ClassNode(javaClass);\n        }\n        \n        protected String getMoreNodesString(String moreNodesCount)  {\n            return ClassesContainer.getMoreNodesString(moreNodesCount);\n        }\n        \n        protected String getSamplesContainerString(String objectsCount)  {\n            return ClassesContainer.getSamplesContainerString(objectsCount);\n        }\n        \n        protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n            return ClassesContainer.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n        }\n\n    }\n    \n    \n    public static class Nodes extends ContainerNode.Nodes<ClassNode> {\n        \n        public Nodes(String name) {\n            this(name, UIThresholds.MAX_CONTAINER_CLASSES);\n        }\n\n        public Nodes(String name, int maxItems) {\n            super(name, maxItems);\n        }\n        \n        \n        protected String getMoreNodesString(String moreNodesCount)  {\n            return ClassesContainer.getMoreNodesString(moreNodesCount);\n        }\n        \n        protected String getSamplesContainerString(String objectsCount)  {\n            return ClassesContainer.getSamplesContainerString(objectsCount);\n        }\n        \n        protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n            return ClassesContainer.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n        }\n        \n    }\n    \n    \n    public static class ContainerNodes extends ContainerNode.Nodes<InstancesContainer.Objects> {\n        \n        public ContainerNodes(String name) {\n            this(name, Integer.MAX_VALUE);\n        }\n\n        public ContainerNodes(String name, int maxItems) {\n            super(name, maxItems);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/InstanceNode.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.Objects;\nimport java.util.Set;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.lib.jfluid.heap.GCRoot;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"InstanceNode_GCRootFlag={0} [GC root - {1}]\"\n})\npublic class InstanceNode extends HeapViewerNode {\n    \n    public static enum Mode {\n        NONE,\n        OUTGOING_REFERENCE,\n        INCOMING_REFERENCE\n    }\n    \n    \n    private final Instance instance;\n    \n    private String name;\n    private String logicalValue;\n    \n    // Internal-only flag initialized during computeName()\n    private boolean isGCRoot;\n    \n    \n    public InstanceNode(Instance instance) {\n        this.instance = instance;\n    }\n    \n    \n    public String toString() {\n        return getName(); // TODO: should not be called directly when sorting the tree\n    }\n    \n    \n    public Mode getMode() {\n        return Mode.NONE;\n    }\n    \n    \n    public Instance getInstance() {\n        return instance;\n    }\n    \n    public int getGCRoots() {\n        Heap heap = instance.getJavaClass().getHeap();\n        return heap.getGCRoots(instance).size();\n    }\n\n    public JavaClass getJavaClass() {\n        return instance.getJavaClass();\n    }\n    \n    public String getName() {\n        if (name == null) {\n            Heap heap = instance.getJavaClass().getHeap();\n            Collection<GCRoot> gcRoots = heap.getGCRoots(instance);\n            isGCRoot = !gcRoots.isEmpty();\n            name = computeName(heap, instance, gcRoots);\n        }\n        return name;\n    }\n    \n    public String getLogicalValue() {\n        if (logicalValue == null) logicalValue = computeLogicalValue(instance);\n        return logicalValue;\n    }\n    \n    public long getOwnSize() {\n        return instance.getSize();\n    }\n    \n    public long getRetainedSize(Heap heap) {\n        return DataType.RETAINED_SIZE.valuesAvailable(heap) ?\n               instance.getRetainedSize() : DataType.RETAINED_SIZE.getNotAvailableValue();\n    }\n    \n    \n    public boolean equals(Object o) {\n        if (o == this) return true;\n        if (!(o instanceof InstanceNode)) return false;\n        return instance.equals(((InstanceNode)o).instance);\n    }\n    \n    public int hashCode() {\n        return instance.hashCode();\n    }\n    \n    \n    boolean isGCRoot() {\n        return isGCRoot;\n    }\n    \n    \n    static String computeName(Instance instance) {\n        Heap heap = instance.getJavaClass().getHeap();\n        Collection<GCRoot> gcroots = heap == null ? Collections.emptyList() : heap.getGCRoots(instance);\n        return computeName(heap, instance, gcroots);\n    }\n    \n    private static String computeName(Heap heap, Instance instance, Collection<GCRoot> gcroots) {\n        String name = null;\n        String className = instance.getJavaClass().getName();\n        if (heap != null && Class.class.getName().equals(className)) {\n            JavaClass jcls = heap.getJavaClassByID(instance.getInstanceId());\n            if (jcls != null) {\n                name = \"class \"+jcls.getName();     // NOI18N\n            }\n        }\n        if (name == null) {\n            name = className + \"#\" + instance.getInstanceNumber(); // NOI18N\n        }\n        if (!gcroots.isEmpty()) {\n            Set<String> gcKinds = new HashSet<>();\n\n            for (GCRoot gcroot : gcroots) {\n                gcKinds.add(gcroot.getKind());\n            }\n            String kind = String.join(\", \", gcKinds);       // NOI18N\n            name = Bundle.InstanceNode_GCRootFlag(name, kind);\n        }\n        return name;\n    }\n    \n    static String computeLogicalValue(Instance instance) {\n        String detail = DetailsSupport.getDetailsString(instance);\n        return detail == null ? \"\" : detail; // NOI18N\n    }\n    \n    \n    protected Object getValue(DataType type, Heap heap) {\n        if (type == DataType.NAME) return getName();\n        if (type == DataType.OWN_SIZE) return getOwnSize();\n        if (type == DataType.RETAINED_SIZE) return getRetainedSize(heap);\n        \n        if (type == DataType.INSTANCE) return getInstance();\n        if (type == DataType.CLASS) return getJavaClass();\n        \n        if (type == DataType.LOGICAL_VALUE) return getLogicalValue();\n        if (type == DataType.GCROOTS) return getGCRoots();\n        \n        if (type == DataType.OBJECT_ID) {\n            Instance i = getInstance();\n            return i == null ? DataType.OBJECT_ID.getNoValue() : i.getInstanceId();\n        }\n        \n        return super.getValue(type, heap);\n    }\n    \n    \n    public InstanceNode createCopy() {\n        if (instance == null) return null;\n        \n        InstanceNode copy = new InstanceNode(instance);\n        setupCopy(copy);\n        return copy;\n    }\n    \n    protected void setupCopy(InstanceNode copy) {\n        super.setupCopy(copy);\n        copy.name = name;\n        copy.logicalValue = logicalValue;\n    }\n    \n    \n    public static class IncludingNull extends InstanceNode {\n        \n        public IncludingNull(Instance instance) {\n            super(instance);\n        }\n        \n        public JavaClass getJavaClass() {\n            if (getInstance() == null) return null;\n            else return super.getJavaClass();\n        }\n        \n        public String getName() {\n            if (getInstance() == null) return \"null\"; // NOI18N\n            else return super.getName();\n        }\n\n        public int getGCRoots() {\n            if (getInstance() == null) return DataType.GCROOTS.getNoValue();\n            else return super.getGCRoots();\n        }\n\n        public String getLogicalValue() {\n            if (getInstance() == null) return DataType.LOGICAL_VALUE.getNoValue();\n            else return super.getLogicalValue();\n        }\n        \n        public long getOwnSize() {\n            if (getInstance() == null) return DataType.OWN_SIZE.getNoValue();\n            else return super.getOwnSize();\n        }\n\n        public long getRetainedSize(Heap heap) {\n            if (getInstance() == null) return DataType.RETAINED_SIZE.valuesAvailable(heap) ?\n                                       DataType.RETAINED_SIZE.getNoValue() : DataType.RETAINED_SIZE.getNotAvailableValue();\n            else return super.getRetainedSize(heap);\n        }\n        \n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof InstanceNode)) return false;\n            return Objects.equals(getInstance(), ((InstanceNode)o).getInstance());\n        }\n\n        public int hashCode() {\n            return getInstance() == null ? 37 : super.hashCode();\n        }\n        \n        public boolean isLeaf() {\n            return getInstance() == null || super.isLeaf();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/InstanceNodeRenderer.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport java.awt.Image;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class InstanceNodeRenderer extends JavaNameRenderer implements HeapViewerRenderer {\n    \n    private static final ImageIcon ICON_INSTANCE = Icons.getImageIcon(LanguageIcons.INSTANCE);\n    private static final ImageIcon ICON_ARRAY = Icons.getImageIcon(LanguageIcons.ARRAY);\n    \n    private static final Image IMAGE_LOOP = Icons.getImage(HeapWalkerIcons.LOOP);\n    \n    public InstanceNodeRenderer(Heap heap) {\n    }\n    \n    public void setValue(Object value, int row) {\n        if (value == null) {\n            super.setValue(null, row);\n            return;\n        }\n        \n        InstanceNode node = (InstanceNode)value;\n        \n        String name = node.getName();\n        if (name != null && !\"null\".equals(name)) { // NOI18N\n            super.setValue(name, row);\n        } else {\n            super.setValue(null, row);\n            super.setNormalValue(\"null\"); // NOI18N\n        }\n        \n        String log = node.getLogicalValue();\n        if (log != null && !log.isEmpty()) setGrayValue(\" : \" + log); // NOI18N\n        \n        ImageIcon icon = getIcon(node.getInstance(), node.isGCRoot());\n        setIcon(icon);\n        setIconTextGap(1);\n        \n        ((LabelRenderer)valueRenderers()[0]).setMargin(3, 0, 3, 0);\n    }\n    \n    public void flagLoopTo() {\n        ImageIcon icon = (ImageIcon)getIcon();\n        icon = new ImageIcon(ImageUtilities.mergeImages(icon.getImage(), IMAGE_LOOP, 0, 0));\n        setIcon(icon);\n        setIconTextGap(4);\n        \n        ((LabelRenderer)valueRenderers()[0]).setMargin(3, 1, 3, 0);\n    }\n    \n    public String getShortName() {\n        return getBoldValue();\n    }\n    \n    \n    protected boolean supportsCustomGrayForeground() {\n        return false;\n    }\n    \n    \n    protected ImageIcon getIcon(Instance instance, boolean isGCRoot) {\n        return instance == null || !instance.getJavaClass().isArray() ? ICON_INSTANCE : ICON_ARRAY;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/InstanceReferenceNode.java",
    "content": "/*\n * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Value;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class InstanceReferenceNode extends InstanceNode.IncludingNull {\n    \n    private final Mode mode;\n    private final Value value;\n    private String fieldName;\n\n    \n    public InstanceReferenceNode(Value value, Instance instance, boolean incoming) {\n        super(instance);\n        this.value = value;\n        this.mode = incoming ? Mode.INCOMING_REFERENCE : Mode.OUTGOING_REFERENCE;\n    }\n    \n    \n    public static InstanceReferenceNode outgoing(Value value) {\n        return reference(value, false);\n    }\n    \n    public static InstanceReferenceNode incoming(Value value) {\n        return reference(value, true);\n    }\n    \n    public static InstanceReferenceNode reference(Value value, boolean incoming) {\n        if (value instanceof ObjectFieldValue) return new Field((ObjectFieldValue)value, incoming);\n        else if (value instanceof ArrayItemValue) return new ArrayItem((ArrayItemValue)value, incoming);\n        \n        return null;\n    }\n\n    \n    public Mode getMode() {\n        return mode;\n    }\n\n    public Value getValue() {\n        return value;\n    }\n\n    public String getFieldName() {\n        if (fieldName == null) {\n            fieldName = computeFieldName();\n        }\n        return fieldName;\n    }\n\n    protected abstract String computeFieldName();\n\n    \n    public String toString() {\n        // TODO: should not be called directly when sorting the tree\n        if (Mode.INCOMING_REFERENCE.equals(mode)) return getFieldName() + \" in \" + getName(); // NOI18N\n        else return getFieldName() + \" = \" + getName(); // NOI18N\n    }\n\n    public boolean equals(Object o) {\n        if (o == this) return true;\n        if (!(o instanceof InstanceReferenceNode)) return false;\n        InstanceReferenceNode r = (InstanceReferenceNode)o;\n        return mode == r.mode && value.equals(r.value);\n    }\n\n    public int hashCode() {\n        return value.hashCode();\n    }\n    \n    \n    public static class Field extends InstanceReferenceNode {\n        \n        public Field(ObjectFieldValue value, boolean incoming) {\n            super(value, incoming ? value.getDefiningInstance() : value.getInstance(), incoming);\n        }\n        \n        public ObjectFieldValue getValue() {\n            return (ObjectFieldValue)super.getValue();\n        }\n        \n        protected String computeFieldName() {\n            org.graalvm.visualvm.lib.jfluid.heap.Field field = getValue().getField();\n            return (field.isStatic() ? \"static \" : \"\") + field.getName(); // NOI18N\n        }\n        \n    }\n    \n    public static class ArrayItem extends InstanceReferenceNode {\n        \n        public ArrayItem(ArrayItemValue value, boolean incoming) {\n            super(value, incoming ? value.getDefiningInstance() : value.getInstance(), incoming);\n        } \n        \n        public ArrayItemValue getValue() {\n            return (ArrayItemValue)super.getValue();\n        }\n        \n        protected String computeFieldName() {\n            return \"[\" + getValue().getIndex() + \"]\"; // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/InstanceReferenceNodeRenderer.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.MultiRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"InstanceReferenceNodeRenderer_LoopTo=loop to\"\n})\npublic class InstanceReferenceNodeRenderer extends MultiRenderer implements HeapViewerRenderer {\n    \n    protected static final Icon ICON_PRIMITIVE = Icons.getIcon(LanguageIcons.PRIMITIVE);\n    protected static final Icon ICON_INSTANCE = Icons.getIcon(LanguageIcons.INSTANCE);\n    protected static final Icon ICON_ARRAY = Icons.getIcon(LanguageIcons.ARRAY);\n    \n    protected final NormalBoldGrayRenderer nameRenderer;\n    protected final LabelRenderer equalsRenderer;\n    \n    private final LabelRenderer loopToRenderer;\n    \n    private final InstanceNodeRenderer instanceRenderer;\n    private final ProfilerRenderer[] renderers;\n    \n    protected final Heap heap;\n\n    \n    public InstanceReferenceNodeRenderer(Heap heap) {\n        this.heap = heap;\n        nameRenderer = new NormalBoldGrayRenderer() {\n            public void setValue(Object value, int row) {\n                InstanceReferenceNode node = (InstanceReferenceNode) value;\n                String name = node.getFieldName();\n                if (name.startsWith(\"static \")) { // NOI18N\n                    setNormalValue(\"static \"); // NOI18N\n                    setBoldValue(name.substring(\"static \".length())); // NOI18N\n                } else {\n                    setNormalValue(\"\"); // NOI18N\n                    setBoldValue(name);\n                }\n                setIcon(Icons.getIcon(InstanceNode.Mode.INCOMING_REFERENCE.equals(node.getMode()) ? ProfilerIcons.NODE_REVERSE : ProfilerIcons.NODE_FORWARD));\n            }\n        };\n        equalsRenderer = new LabelRenderer() {\n            public void setValue(Object value, int row) {\n                InstanceReferenceNode node = (InstanceReferenceNode) value;\n                if (InstanceNode.Mode.INCOMING_REFERENCE.equals(node.getMode())) {\n                    setText(\"in\"); // NOI18N\n                    setMargin(3, 2, 3, 0);\n                } else {\n                    setText(\"=\"); // NOI18N\n                    setMargin(3, 0, 3, 0);\n                }\n            }\n            public String toString() {\n                return \" \" + getText() + \" \"; // NOI18N\n            }\n        };\n        loopToRenderer = new LabelRenderer() {\n            public void setValue(Object value, int row) {\n                setVisible(value != null);\n            }\n            public String toString() {\n                return getText() + \" \"; // NOI18N\n            }\n        };\n        loopToRenderer.setText(Bundle.InstanceReferenceNodeRenderer_LoopTo());\n        instanceRenderer = new InstanceNodeRenderer(heap);\n        renderers = new ProfilerRenderer[]{nameRenderer, equalsRenderer, loopToRenderer, instanceRenderer};\n    }\n\n    public Icon getIcon() {\n        return nameRenderer.getIcon();\n    }\n\n    public String getShortName() {\n        return nameRenderer.toString();\n    }\n\n    protected ProfilerRenderer[] valueRenderers() {\n        return renderers;\n    }\n\n    public void setValue(Object value, int row) {\n        HeapViewerNode node = (HeapViewerNode) value;\n        HeapViewerNode loop = HeapViewerNode.getValue(node, DataType.LOOP, heap);\n        if (loop != null) node = loop;\n        \n        nameRenderer.setValue(node, row);\n        equalsRenderer.setValue(node, row);\n        loopToRenderer.setValue(loop, row);\n        instanceRenderer.setValue(node, row);\n        \n        if (loopToRenderer.isVisible()) instanceRenderer.flagLoopTo();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/InstancesContainer.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport java.util.Iterator;\nimport org.graalvm.visualvm.heapviewer.model.ContainerNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"InstancesContainer_MoreNodes=<another {0} instances left>\",\n    \"InstancesContainer_SamplesContainer=<sample {0} instances>\",\n    \"InstancesContainer_NodesContainer=<instances {0}-{1}>\"\n})\npublic final class InstancesContainer {\n    \n    public static class Objects extends ContainerNode<Instance> {\n        \n        private final JavaClass javaClass;\n    \n        public Objects(String name, JavaClass javaClass) {\n            this(name, javaClass, UIThresholds.MAX_CONTAINER_INSTANCES);\n        }\n\n        public Objects(String name, JavaClass javaClass, int maxItems) {\n            super(name, maxItems);\n            this.javaClass = javaClass;\n        }\n        \n        public JavaClass getJavaClass() {\n            return javaClass;\n        }\n        \n        public Iterator<Instance> getInstancesIterator() {\n            return getItems().iterator();\n        }\n\n        protected int getCount(Instance item, Heap heap) {\n            return 1;\n        }\n\n        protected long getOwnSize(Instance item, Heap heap) {\n            return item.getSize();\n        }\n\n        protected long getRetainedSize(Instance item, Heap heap) {\n            return DataType.RETAINED_SIZE.valuesAvailable(heap) ?\n                   item.getRetainedSize() : DataType.RETAINED_SIZE.getNotAvailableValue();\n        }\n\n        protected InstanceNode createNode(Instance instance) {\n            return new InstanceNode(instance);\n        }\n\n        protected String getMoreNodesString(String moreNodesCount)  {\n            return InstancesContainer.getMoreNodesString(moreNodesCount);\n        }\n        \n        protected String getSamplesContainerString(String objectsCount)  {\n            return InstancesContainer.getSamplesContainerString(objectsCount);\n        }\n        \n        protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n            return InstancesContainer.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n        }\n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.CLASS) return getJavaClass();\n            \n            if (type == DataType.INSTANCES_WRAPPER) return new InstancesWrapper.Simple(getJavaClass(), getCount()) {\n                @Override\n                public Iterator<Instance> getInstancesIterator() {\n                    return Objects.this.getInstancesIterator();\n                }\n            };\n\n            return super.getValue(type, heap);\n        }\n\n    }\n    \n    \n    public static class Nodes extends ContainerNode.Nodes<InstanceNode> {\n        \n        private final JavaClass javaClass;\n        \n        public Nodes(String name, JavaClass javaClass) {\n            this(name, javaClass, UIThresholds.MAX_CONTAINER_INSTANCES);\n        }\n\n        public Nodes(String name, JavaClass javaClass, int maxItems) {\n            super(name, maxItems);\n            this.javaClass = javaClass;\n        }\n        \n        protected String getMoreNodesString(String moreNodesCount)  {\n            return InstancesContainer.getMoreNodesString(moreNodesCount);\n        }\n        \n        protected String getSamplesContainerString(String objectsCount)  {\n            return InstancesContainer.getSamplesContainerString(objectsCount);\n        }\n        \n        protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n            return InstancesContainer.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n        }\n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.CLASS) return javaClass;\n\n            return super.getValue(type, heap);\n        }\n        \n    }\n    \n    \n    private InstancesContainer() {}\n    \n    \n    private static String getMoreNodesString(String moreNodesCount)  {\n        return Bundle.InstancesContainer_MoreNodes(moreNodesCount);\n    }\n    \n    private static String getSamplesContainerString(String objectsCount)  {\n        return Bundle.InstancesContainer_SamplesContainer(objectsCount);\n    }\n    \n    private static String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n        return Bundle.InstancesContainer_NodesContainer(firstNodeIdx, lastNodeIdx);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/InstancesWrapper.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport java.util.Iterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class InstancesWrapper {\n    \n    public abstract JavaClass getJavaClass();\n    \n    public abstract int getInstancesCount();\n    \n    public abstract Iterator<Instance> getInstancesIterator();\n    \n    \n    public static abstract class Simple extends InstancesWrapper {\n        \n        private final JavaClass jclass;\n        \n        private final int instancesCount;\n        \n        \n        public Simple(JavaClass jclass, int instancesCount) {\n            this.jclass = jclass;\n            this.instancesCount = instancesCount;\n        }\n        \n        \n        @Override\n        public final JavaClass getJavaClass() {\n            return jclass;\n        }\n        \n        @Override\n        public final int getInstancesCount() {\n            return instancesCount;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/JavaGoToSourceAction.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport java.awt.event.ActionEvent;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapViewerNodeAction.Provider.class)\n@NbBundle.Messages({\n    \"JavaGoToSourceAction_GoToSource=Go to Source\"\n})\npublic class JavaGoToSourceAction extends HeapViewerNodeAction.Provider {\n\n    public boolean supportsView(HeapContext context, String viewID) {\n        return GoToSource.isAvailable() && JavaHeapFragment.isJavaHeap(context);\n    }\n\n    public HeapViewerNodeAction[] getActions(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n        HeapViewerNodeAction action;\n        \n        if (node instanceof StackFrameNode) {\n            action = new GoToSourceAction((StackFrameNode)node);\n        } else {\n            JavaClass javaClass = HeapViewerNode.getValue(node, DataType.CLASS, context.getFragment().getHeap());\n            action = new GoToSourceAction(javaClass);\n        }\n        \n        return new HeapViewerNodeAction[] { action };\n    }\n    \n    \n    private static class GoToSourceAction extends HeapViewerNodeAction {\n        \n        private final String className;\n        private final String methodName;\n        private final int line;\n        \n        \n        private GoToSourceAction(JavaClass javaClass) {\n            super(Bundle.JavaGoToSourceAction_GoToSource(), 210);\n            \n            className = javaClass == null ? null : javaClass.getName();\n            methodName = null;\n            line = -1;\n            \n            setEnabled(className != null);\n        }\n        \n        private GoToSourceAction(StackFrameNode sfNode) {\n            super(Bundle.JavaGoToSourceAction_GoToSource(), 210);\n            \n            String name = sfNode.getName();\n            \n            int fileIdx = name.indexOf('('); // NOI18N\n            String methodName = name.substring(0, fileIdx);\n            String fileName = name.substring(fileIdx);\n            \n            int classIdx = methodName.lastIndexOf('.'); // NOI18N\n            className = methodName.substring(0, classIdx);\n            this.methodName = methodName.substring(classIdx + 1);\n            \n            int lineIdxS = fileName.indexOf(':'); // can be 'Native Method' instead of '<file name>:<line number>'  // NOI18N\n            int lineIdxE = fileName.indexOf(')'); // NOI18N\n            line = lineIdxS == -1 ? -1 : Integer.parseInt(fileName.substring(lineIdxS + 1, lineIdxE));\n            \n            setEnabled(true);\n        }\n        \n        public void actionPerformed(ActionEvent e) {\n            if (line == -1) GoToSource.openSource(null, className, methodName, null);\n            else GoToSource.openSource(null, className, methodName, line);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/JavaHeapFragment.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport java.io.IOException;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.HeapFragment;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaHeapFragment_Name=Java Heap\",\n    \"JavaHeapFragment_Description=Java Heap\",\n    \"JavaHeapFragment_NameSegment=Java Heap (Segment {0})\",\n    \"JavaHeapFragment_DescriptionSegment=Java Heap (Segment {0})\"\n})\npublic class JavaHeapFragment extends HeapFragment {\n    \n    public JavaHeapFragment(Heap heap) throws IOException {\n        super(\"java_heap\", Bundle.JavaHeapFragment_Name(), Bundle.JavaHeapFragment_Description(), heap); // NOI18N\n    }\n    \n    public JavaHeapFragment(Heap heap, int segment) throws IOException {\n        super(\"java_heap\", Bundle.JavaHeapFragment_NameSegment(segment), Bundle.JavaHeapFragment_DescriptionSegment(segment), heap); // NOI18N\n    }\n    \n    public static boolean isJavaHeap(HeapContext context) {\n        return \"java_heap\".equals(context.getFragment().getID()); // NOI18N\n    }\n    \n    public static HeapContext getJavaContext(HeapContext context) {\n        if (isJavaHeap(context)) return context;\n        \n        for (HeapContext otherContext : context.getOtherContexts())\n            if (isJavaHeap(otherContext)) return otherContext;\n        \n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/LocalObjectNode.java",
    "content": "/*\n * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"LocalObjectNode_LocalObject=local object\",\n    \"LocalObjectNode_UnknownLocalObject=unknown local object\",\n    \"LocalObjectNode_Unknown=<unknown>\"\n})\npublic class LocalObjectNode extends InstanceNode {\n    \n    private final String localObjectName;\n    \n    \n    public LocalObjectNode(Instance instance) {\n        this(instance, Bundle.LocalObjectNode_LocalObject());\n    }\n    \n    public LocalObjectNode(Instance instance, String localObjectName) {\n        super(instance);\n        this.localObjectName = localObjectName;\n    }\n    \n    \n    public String getLocalObjectName() {\n        return localObjectName;\n    }\n    \n    \n    public static class Unknown extends LocalObjectNode {\n        \n        public Unknown() {\n            super(null, Bundle.LocalObjectNode_UnknownLocalObject());\n        }\n        \n        public String getName() {\n            return Bundle.LocalObjectNode_Unknown();\n        }\n        \n        public boolean equals(Object o) {\n            return o == this;\n        }\n\n        public int hashCode() {\n            return System.identityHashCode(this);\n        }\n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.OWN_SIZE) return DataType.OWN_SIZE.getNoValue();\n            if (type == DataType.RETAINED_SIZE) return DataType.RETAINED_SIZE.getNoValue();\n\n            if (type == DataType.INSTANCE) return DataType.INSTANCE.getNoValue();\n            if (type == DataType.CLASS) return DataType.CLASS.getNoValue();\n\n            if (type == DataType.LOGICAL_VALUE) return DataType.LOGICAL_VALUE.getNoValue();\n\n            return super.getValue(type, heap);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/LocalObjectNodeRenderer.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.MultiRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class LocalObjectNodeRenderer extends MultiRenderer implements HeapViewerRenderer {\n    \n    private final LabelRenderer lvRenderer;\n    private final InstanceNodeRenderer instanceRenderer;\n    private final ProfilerRenderer[] renderers;\n\n    \n    public LocalObjectNodeRenderer(Heap heap) {\n        lvRenderer = new LabelRenderer() {\n            public String toString() {\n                return getText() + \" \"; // NOI18N\n            }\n        };\n        lvRenderer.setMargin(3, 3, 3, 1);\n        instanceRenderer = new InstanceNodeRenderer(heap);\n        renderers = new ProfilerRenderer[]{lvRenderer, instanceRenderer};\n    }\n\n    \n    protected ProfilerRenderer[] valueRenderers() {\n        return renderers;\n    }\n\n    \n    public void setValue(Object value, int row) {\n        lvRenderer.setText(((LocalObjectNode)value).getLocalObjectName());\n        instanceRenderer.setValue(value, row);\n    }\n    \n    public Icon getIcon() {\n        return instanceRenderer.getIcon();\n    }\n    \n    public String getShortName() {\n        String name = instanceRenderer.getShortName();\n        int nameIdx = name.lastIndexOf('['); // NOI18N\n        if (nameIdx != -1) name = name.substring(0, nameIdx).trim();\n        return /*lvRenderer + \" \" +*/ name;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/PackageNodeRenderer.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class PackageNodeRenderer extends JavaNameRenderer implements HeapViewerRenderer {\n    \n    public PackageNodeRenderer(Heap heap) {\n        super(Icons.getIcon(LanguageIcons.PACKAGE));\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/PrimitiveNode.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport java.util.Objects;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class PrimitiveNode extends HeapViewerNode {\n    \n    private String fieldName;\n    \n    \n    public String getFieldName() {\n        if (fieldName == null) fieldName = computeFieldName();\n        return fieldName;\n    }\n    \n    protected abstract String computeFieldName();\n    \n    public abstract String getType();\n    \n    public abstract String getValue();\n    \n    \n    private String getName() {\n        return getFieldName() + \" = \" + getType() + \" \" + getValue(); // NOI18N\n    }\n    \n    public String toString() {\n        return getName();\n    }\n    \n    protected Object getValue(DataType type, Heap heap) {\n        if (type == DataType.NAME) return getName();\n        if (type == DataType.OWN_SIZE) return DataType.OWN_SIZE.getNoValue();\n        if (type == DataType.RETAINED_SIZE) return DataType.RETAINED_SIZE.getNoValue();\n        if (type == DataType.OBJECT_ID) return DataType.OBJECT_ID.getNoValue();\n        \n        return super.getValue(type, heap);\n    }\n    \n    \n    \n    public boolean isLeaf() {\n        return true;\n    }\n    \n    \n    public static class Field extends PrimitiveNode {\n        \n        private final FieldValue field;\n        \n        public Field(FieldValue field) {\n            this.field = field;\n        }\n        \n        public String getType() {\n            return field.getField().getType().getName();\n        }\n        \n        public String getValue() {\n            return field.getValue();\n        }\n        \n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof Field)) return false;\n            return field.equals(((Field)o).field);\n        }\n\n        public int hashCode() {\n            return field.hashCode();\n        }\n        \n        protected String computeFieldName() {\n            return (field.getField().isStatic() ? \"static \" : \"\") + field.getField().getName(); // NOI18N\n        }\n    }\n    \n    public static class ArrayItem extends PrimitiveNode {\n        \n        private final int index;\n        private final String type;\n        private final String value;\n        private final Instance owner;\n        \n        public ArrayItem(int index, String type, String value, Instance owner) {\n            this.index = index;\n            this.type = type;\n            this.value = value;\n            this.owner = owner;\n        }\n        \n        public String getType() {\n            return type;\n        }\n        \n        public String getValue() {\n            return value;\n        }\n        \n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof ArrayItem)) return false;\n\n            ArrayItem oo = (ArrayItem)o;\n            return owner.equals(oo.owner) && index == oo.index;\n        }\n\n        public int hashCode() {\n            return Objects.hash(owner, index);\n        }\n        \n        protected String computeFieldName() {\n            return \"[\" + index + \"]\"; // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/PrimitiveNodeRenderer.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.MultiRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class PrimitiveNodeRenderer extends MultiRenderer implements HeapViewerRenderer {\n    \n    private final NormalBoldGrayRenderer nameRenderer;\n    private final LabelRenderer equalsRenderer;\n    private final NormalBoldGrayRenderer valueRenderer;\n    private final ProfilerRenderer[] renderers;\n    \n    public PrimitiveNodeRenderer() {\n        nameRenderer = new NormalBoldGrayRenderer() {\n            public void setValue(Object value, int row) {\n                String name = ((PrimitiveNode)value).getFieldName();\n                if (name.startsWith(\"static \")) { // NOI18N\n                    setNormalValue(\"static \"); // NOI18N\n                    setBoldValue(name.substring(\"static \".length())); // NOI18N\n                } else {\n                    setNormalValue(\"\"); // NOI18N\n                    setBoldValue(name);\n                }\n                setIcon(Icons.getIcon(ProfilerIcons.NODE_FORWARD));\n            }\n        };\n        \n        equalsRenderer = new LabelRenderer() {\n            public String toString() {\n                return \" \" + getText() + \" \"; // NOI18N\n            }\n        };\n        equalsRenderer.setText(\"=\"); // NOI18N\n        equalsRenderer.setMargin(3, 0, 3, 0);\n        \n        valueRenderer = new NormalBoldGrayRenderer() {\n            public void setValue(Object value, int row) {\n                PrimitiveNode node = (PrimitiveNode)value;\n\n                setNormalValue(node.getType());\n                setBoldValue(node.getValue());\n\n                setIcon(Icons.getIcon(LanguageIcons.PRIMITIVE));\n                setIconTextGap(1);\n\n                ((LabelRenderer)valueRenderers()[0]).setMargin(3, 0, 3, 3);\n            }\n            public String toString() {\n                return getNormalValue() + \" \" + getBoldValue(); // NOI18N\n            }\n        };\n\n        renderers = new ProfilerRenderer[] { nameRenderer, equalsRenderer, valueRenderer };\n    }\n    \n    public Icon getIcon() {\n        return nameRenderer.getIcon();\n    }\n\n    public String getShortName() {\n        return nameRenderer.toString();\n    }\n    \n    protected ProfilerRenderer[] valueRenderers() { return renderers; }\n        \n    public void setValue(Object value, int row) {\n        nameRenderer.setValue(value, row);\n        valueRenderer.setValue(value, row);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/StackFrameNode.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.NodesCache;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class StackFrameNode extends HeapViewerNode {\n    \n    private final String name;\n    \n    \n    public StackFrameNode(String name, HeapViewerNode[] children) {\n        this.name = name;\n        setChildren(children);\n    }\n    \n    \n    public String getName() {\n        return name;\n    }\n\n\n    public String toString() {\n        return getName();\n    }\n    \n    \n    protected void resetChildren() {}\n   \n    public void forgetChildren(NodesCache cache) {}\n    \n    \n    protected Object getValue(DataType type, Heap heap) {\n        if (type == DataType.NAME) return getName();\n        if (type == DataType.COUNT) return DataType.COUNT.getUnsupportedValue();\n        if (type == DataType.OWN_SIZE) return DataType.OWN_SIZE./*getNoValue()*/getUnsupportedValue();\n        if (type == DataType.RETAINED_SIZE) return DataType.RETAINED_SIZE./*getNoValue()*/getUnsupportedValue();\n\n        if (type == DataType.INSTANCE) return DataType.INSTANCE./*getNoValue()*/getUnsupportedValue();\n        if (type == DataType.CLASS) return DataType.CLASS./*getNoValue()*/getUnsupportedValue();\n\n        if (type == DataType.LOGICAL_VALUE) return DataType.LOGICAL_VALUE./*getNoValue()*/getUnsupportedValue();\n\n        return super.getValue(type, heap);\n    }    \n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/StackFrameNodeRenderer.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.MultiRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class StackFrameNodeRenderer extends MultiRenderer implements HeapViewerRenderer {\n    \n    private final LabelRenderer atRenderer;\n    private final JavaNameRenderer methodRenderer;\n    private final ProfilerRenderer[] renderers;\n\n    \n    public StackFrameNodeRenderer() {\n        atRenderer = new LabelRenderer() {\n            public String toString() {\n                return getText() + \" \"; // NOI18N\n            }\n        };\n        atRenderer.setText(\"at\"); // NOI18N\n        atRenderer.setMargin(3, 3, 3, 0);\n        methodRenderer = new JavaNameRenderer();\n        renderers = new ProfilerRenderer[] { atRenderer, methodRenderer };\n    }\n\n    \n    protected ProfilerRenderer[] valueRenderers() {\n        return renderers;\n    }\n\n    \n    public void setValue(Object value, int row) {\n        methodRenderer.setValue(value, row);\n    }\n    \n    public String getShortName() {\n        String name = methodRenderer.toString();\n        int nameIdx = name.indexOf('('); // NOI18N\n        if (nameIdx == -1) return atRenderer + \" \" + name; // NOI18N\n        \n        String method = name.substring(0, nameIdx);\n        int dotIdx = method.lastIndexOf('.'); // NOI18N\n        if (dotIdx == -1) return atRenderer + \" \" + name; // NOI18N\n        \n        String cls = method.substring(0, dotIdx);\n        dotIdx = cls.lastIndexOf('.'); // NOI18N\n        return atRenderer + \" \" + method.substring(dotIdx + 1) + name.substring(nameIdx); // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/ThreadNode.java",
    "content": "/*\n * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ThreadNode_UnknownThread=unknown thread\"\n})\npublic class ThreadNode extends InstanceNode implements CCTNode.DoNotSortChildren {\n    \n    private final String name;\n    private final boolean isOOME;\n    private final Thread.State state;\n    \n    \n    public ThreadNode(String name, Instance instance) {\n        this(name, null, false, instance);\n    }\n\n    public ThreadNode(String name, Thread.State state, Instance instance) {\n        this(name, state, false, instance);\n    }\n    \n    public ThreadNode(String name, Thread.State state, boolean isOOME, Instance instance) {\n        super(instance);\n        this.name = name;\n        this.isOOME = isOOME;\n        this.state = state;\n    }\n    \n    \n    public String getName() {\n        return name;\n    }\n    \n    public boolean isOOMEThread() {\n        return isOOME;\n    }\n    \n    public Thread.State getState() {\n        return state;\n    }\n    \n    public static class Unknown extends ThreadNode {\n        \n        public Unknown() {\n            super(Bundle.ThreadNode_UnknownThread(), null, null);\n        }\n        \n        public boolean equals(Object o) {\n            return o == this;\n        }\n\n        public int hashCode() {\n            return System.identityHashCode(this);\n        }\n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.OWN_SIZE) return DataType.OWN_SIZE.getNoValue();\n            if (type == DataType.RETAINED_SIZE) return DataType.RETAINED_SIZE.getNoValue();\n\n            if (type == DataType.INSTANCE) return DataType.INSTANCE.getNoValue();\n            if (type == DataType.CLASS) return DataType.CLASS.getNoValue();\n\n            if (type == DataType.LOGICAL_VALUE) return DataType.LOGICAL_VALUE.getNoValue();\n            if (type == DataType.NAME) return DataType.NAME.getNoValue();\n\n            return super.getValue(type, heap);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/ThreadNodeRenderer.java",
    "content": "/*\n * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ThreadNodeRenderer extends LabelRenderer implements HeapViewerRenderer {\n    \n    private static final Icon ICON = Icons.getIcon(ProfilerIcons.THREAD);\n    \n    protected final Heap heap;\n\n    private Color customForeground;\n    \n    \n    public ThreadNodeRenderer(Heap heap) {\n        this.heap = heap;\n        \n        setIcon(ICON);\n        setFont(getFont().deriveFont(Font.BOLD));\n    }\n    \n    \n    public void setValue(Object value, int row) {\n        ThreadNode node = (ThreadNode)value;\n        setText(node.getName());\n        setCustomForeground(node.isOOMEThread() ? Color.RED : null);\n    }\n    \n    public String getShortName() {\n        String name = getText();\n        int nameIdx = name.indexOf('\"') + 1; // NOI18N\n        if (nameIdx > 0) name = name.substring(nameIdx, name.indexOf('\"', nameIdx)); // NOI18N\n        return name;\n    }\n    \n    \n    public void setForeground(Color foreground) {\n        if (customForeground != null && Objects.equals(foreground, UIUtils.getDefaultTableForeground())) {\n            super.setForeground(customForeground);\n        } else {\n            super.setForeground(foreground);\n        }\n    }\n    \n    private void setCustomForeground(Color foreground) {\n        customForeground = foreground;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/ThreadStateNode.java",
    "content": "/*\n * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.NodesCache;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class ThreadStateNode extends HeapViewerNode {\n    private final Thread.State state;\n\n    public ThreadStateNode(Thread.State state, List<HeapViewerNode> children) {\n        this.state = state;\n        setChildren(children.toArray(NO_NODES));\n    }\n\n    public String getName() {\n        if (state == null) return \"Undefined\";  // NOI18N\n        return state.toString();\n    }\n\n    public Thread.State getState() {\n        return state;\n    }\n\n    public String toString() {\n        return getName();\n    }\n\n    protected void resetChildren() {}\n\n    public void forgetChildren(NodesCache cache) {}\n\n    protected Object getValue(DataType type, Heap heap) {\n        if (type == DataType.NAME) return getName();\n        if (type == DataType.COUNT) return DataType.COUNT.getUnsupportedValue();\n        if (type == DataType.OWN_SIZE) return DataType.OWN_SIZE./*getNoValue()*/getUnsupportedValue();\n        if (type == DataType.RETAINED_SIZE) return DataType.RETAINED_SIZE./*getNoValue()*/getUnsupportedValue();\n\n        if (type == DataType.INSTANCE) return DataType.INSTANCE./*getNoValue()*/getUnsupportedValue();\n        if (type == DataType.CLASS) return DataType.CLASS./*getNoValue()*/getUnsupportedValue();\n\n        if (type == DataType.LOGICAL_VALUE) return DataType.LOGICAL_VALUE./*getNoValue()*/getUnsupportedValue();\n\n        return super.getValue(type, heap);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/ThreadStateNodeRenderer.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.java;\n\nimport java.awt.Font;\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.threads.ThreadStateIcon;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class ThreadStateNodeRenderer extends LabelRenderer implements HeapViewerRenderer {\n\n    private static final Icon ICON = Icons.getIcon(ProfilerIcons.THREAD);\n\n    public ThreadStateNodeRenderer() {\n        setIcon(ICON);\n        setFont(getFont().deriveFont(Font.BOLD));\n    }\n\n\n    public void setValue(Object value, int row) {\n        ThreadStateNode node = (ThreadStateNode)value;\n        setText(node.getName());\n        setIcon(getIcon(node.getState()));\n    }\n\n    public String getShortName() {\n        return getText();\n    }\n\n    private static final int THREAD_ICON_SIZE = 9;\n    private static final Map<Thread.State, Icon> STATE_ICONS_CACHE = new HashMap<>();\n\n    private static Icon getIcon(Thread.State state) {\n        Icon icon = STATE_ICONS_CACHE.get(state);\n\n        if (icon == null) {\n            int pState;\n            switch (state) {\n                case RUNNABLE:\n                    pState = CommonConstants.THREAD_STATUS_RUNNING;\n                    break;\n                case BLOCKED:\n                    pState = CommonConstants.THREAD_STATUS_MONITOR;\n                    break;\n                case WAITING:\n                    pState = CommonConstants.THREAD_STATUS_WAIT;\n                    break;\n                case TIMED_WAITING:\n                    pState = CommonConstants.THREAD_STATUS_SLEEPING;\n                    break;\n                default:\n                    pState = CommonConstants.THREAD_STATUS_UNKNOWN;\n                    break;\n            }\n            icon = new ThreadStateIcon(pState, THREAD_ICON_SIZE, THREAD_ICON_SIZE);\n            STATE_ICONS_CACHE.put(state, icon);\n        }\n        return icon;\n    }\n\n\n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/ClassHierarchyPlugin.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.JComponent;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ClassHierarchyPlugin_Name=Hierarchy\",\n    \"ClassHierarchyPlugin_Description=Hierarchy\",\n    \"ClassHierarchyPlugin_NoSelection=<no class or instance selected>\",\n    \"ClassHierarchyPlugin_NoInformation=<no superclass information>\"\n})\npublic class ClassHierarchyPlugin extends HeapViewPlugin {\n    \n    private static final JavaClass NO_CLASS = new FakeClass();\n    private static final JavaClass EMPTY_CLASS = new FakeClass();\n    \n    private final Heap heap;\n    private JavaClass selected;\n    \n    private final TreeTableView objectsView;\n    \n    \n    public ClassHierarchyPlugin(HeapContext context, HeapViewerActions actions) {\n        super(Bundle.ClassHierarchyPlugin_Name(), Bundle.ClassHierarchyPlugin_Description(), Icons.getIcon(HeapWalkerIcons.CLASSES));\n        \n        heap = context.getFragment().getHeap();\n        \n        objectsView = new TreeTableView(\"java_objects_hierarchy\", context, actions, TreeTableViewColumn.classesPlain(heap)) { // NOI18N\n            protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                JavaClass javaClass;\n                synchronized (objectsView) { javaClass = selected; }\n                \n                if (javaClass != null) {\n                    \n                    if (javaClass == EMPTY_CLASS) return new HeapViewerNode[] { new TextNode(Bundle.ClassHierarchyPlugin_NoInformation()) };\n                    \n                    if (javaClass.isArray()) {\n                        String className = javaClass.getName().replace(\"[]\", \"\"); // NOI18N\n                        JavaClass plainClass = heap.getJavaClassByName(className);\n                        if (plainClass != null) javaClass = plainClass;\n                    }\n                    \n                    SuperClassNode node = null;\n                    SuperClassNode firstNode = null;\n                    SuperClassNode previousNode = null;\n\n                    Thread worker = Thread.currentThread();\n                    while (javaClass != null) {\n                        node = new SuperClassNode(javaClass);\n                        if (firstNode == null) firstNode = node;\n                        else previousNode.setChildren(new HeapViewerNode[] { node });\n\n                        javaClass = javaClass.getSuperClass();\n\n                        previousNode = node;\n                        \n                        if (worker.isInterrupted()) throw new InterruptedException();\n                    }\n\n                    node.setChildren(HeapViewerNode.NO_NODES);\n                    return new HeapViewerNode[] { firstNode };\n                }\n                \n                return new HeapViewerNode[] { new TextNode(Bundle.ClassHierarchyPlugin_NoSelection()) };\n            }\n            protected void childrenChanged() {\n                HeapViewerNode root = getRoot();\n                while (root != null) {\n                    expandNode(root);\n                    root = root.getNChildren() > 0 ? root.getChild(0) : null;\n                }\n            }\n        };\n    }\n    \n    protected JComponent createComponent() {\n        return objectsView.getComponent();\n    }\n    \n    \n    @Override\n    protected void closed() {\n        synchronized (objectsView) { selected = NO_CLASS; }\n        objectsView.closed();\n    }\n    \n    \n    protected void nodeSelected(HeapViewerNode node, boolean adjusting) {\n        JavaClass sel = node == null ? null : HeapViewerNode.getValue(node, DataType.CLASS, heap);\n        \n        // Do not handle artificial classes without superclass (Diff view)\n        if (sel != null && sel.getSuperClass() == null && !\"java.lang.Object\".equals(sel.getName())) // NOI18N\n            sel = EMPTY_CLASS;\n        \n        synchronized (objectsView) {\n            if (Objects.equals(selected, sel)) return;\n            else selected = sel;\n        }\n        \n        objectsView.reloadView();\n    }\n    \n    \n    private static class SuperClassNode extends ClassNode {\n        \n        SuperClassNode(JavaClass javaClass) {\n            super(javaClass);\n        }\n        \n        protected void setChildren(HeapViewerNode[] ch) {\n            super.setChildren(ch);\n        }\n        \n        public boolean isLeaf() {\n            return getChildCount() == 0;\n        }\n        \n    }\n    \n    \n    private static class FakeClass implements JavaClass {\n        @Override public Object getValueOfStaticField(String name)  { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public long getAllInstancesSize()                 { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public boolean isArray()                          { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public Instance getClassLoader()                  { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public ObjectArrayInstance getSigners()           { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public Instance getProtectionDomain()             { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public List<Field> getFields()                           { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public int getInstanceSize()                      { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public List<Instance> getInstances()                        { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public Iterator<Instance> getInstancesIterator()            { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public int getInstancesCount()                    { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public long getRetainedSizeByClass()              { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public long getJavaClassId()                      { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public String getName()                           { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public List<FieldValue> getStaticFieldValues()                { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public Collection<JavaClass> getSubClasses()                 { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public JavaClass getSuperClass()                  { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public Heap getHeap()                             { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        \n        @Override public boolean equals(Object o)                   { return o == this; }\n        @Override public int hashCode()                             { return -1; }\n    }\n    \n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 500)\n    public static class Provider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (JavaHeapFragment.isJavaHeap(context)) return new ClassHierarchyPlugin(context, actions); // NOI18N\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/EditableHistoryCombo.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.JComboBox;\nimport javax.swing.JTextField;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.JTextComponent;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass EditableHistoryCombo extends JComboBox {\n    \n    private Runnable onTextChange;\n    \n    EditableHistoryCombo() {\n        super(new ComboHistoryModel(10));\n        \n        setEditable(true);\n//        putClientProperty(\"JComboBox.isTableCellEditor\", Boolean.TRUE); // NOI18N\n        \n        setPrototypeDisplayValue(\"org.graalvm.visualvm.lib.ui.swing.XXXXXXXXXXXXXXXXXXXX\"); // NOI18N\n        Dimension dim = getPreferredSize();\n        dim.height = !UIUtils.isNimbusLookAndFeel() ? getMinimumSize().height :\n                     new JTextField(\"X\").getPreferredSize().height; // NOI18N\n        \n        setMinimumSize(dim);\n        setPreferredSize(dim);\n        setMaximumSize(dim);\n        \n        JTextComponent comp = getTextComponent();\n        if (comp != null) comp.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e)  { onChange(); }\n            public void removeUpdate(DocumentEvent e)  { onChange(); }\n            public void changedUpdate(DocumentEvent e) { onChange(); }\n            private void onChange() { if (onTextChange != null) onTextChange.run(); }\n        });\n    }\n    \n    \n    JTextComponent getTextComponent() {\n        Component comp = getEditor().getEditorComponent();\n        return comp instanceof JTextComponent ? (JTextComponent)comp : null;\n    }\n    \n    String getText() {\n        JTextComponent textC = getTextComponent();\n        return textC != null ? textC.getText() : getSelectedItem().toString();\n    }\n    \n    void setOnTextChangeHandler(Runnable handler) {\n        onTextChange = handler;\n    }\n    \n    \n    private static class ComboHistoryModel extends DefaultComboBoxModel {\n        \n        private final int historySize;\n        \n        \n        ComboHistoryModel(int historySize) {\n            this.historySize = historySize;\n        }\n        \n        \n        public void addElement(Object item) {\n            insertElementAt(item, 0);\n        }\n        \n        public void insertElementAt(Object item, int index) {\n            int current = getIndexOf(item);\n            if (current == index) return;\n            \n            if (current != -1) removeElementAt(current);\n            super.insertElementAt(item, index);\n            \n            if (getSize() > historySize) removeElementAt(historySize);\n            \n            setSelectedItem(item);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/FilterUtils.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.KeyEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.Icon;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.JToolBar;\nimport javax.swing.KeyStroke;\nimport javax.swing.RowFilter;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.text.JTextComponent;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableView;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.filters.TextFilter;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.CloseButton;\nimport org.graalvm.visualvm.lib.ui.results.ColoredFilter;\nimport org.graalvm.visualvm.lib.ui.results.PackageColorer;\nimport org.graalvm.visualvm.lib.ui.swing.InvisibleToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaFilterUtils_ActionFilter=Filter\",\n    \"JavaFilterUtils_SidebarCaption=Class Filter:\",\n    \"JavaFilterUtils_FilterResults=Filter results ({0})\",\n    \"JavaFilterUtils_MatchCase=Match case\",\n    \"JavaFilterUtils_Close=Close Filter sidebar ({0})\",\n    \"JavaFilterUtils_InvalidRegexp=Entered regular expression is invalid:\\n{0}\",\n    \"JavaFilterUtils_FilterContains=Contains\",\n    \"JavaFilterUtils_FilterNotContains=Does Not Contain\",\n    \"JavaFilterUtils_FilterRegExp=Regular Expression\",\n    \"JavaFilterUtils_FilterSubclass=Subclass Of\",\n    \"JavaFilterUtils_FilterType=Filter type: {0}\",\n    \"JavaFilterUtils_InsertFilter=Insert Defined Filter\",\n    \"JavaFilterUtils_HideZeroInstances=Hide Classes With No Instances\"\n})\nfinal class FilterUtils {\n    \n    private static final String FILTER_ACTION_KEY = \"filter-action-key\"; // NOI18N\n    \n    private static final String FILTER_CHANGED = \"filter-changed\"; // NOI18N\n    \n    private static final Icon ICON_CLASS_NO_INSTANCES = ImageUtilities.image2Icon(ImageUtilities.loadImage(FilterUtils.class.getPackage().getName().replace('.', '/') + \"/classWithoutInstances.png\", true));\n    \n    \n    private static final int FILTER_INSTANCEOF = 100;\n    \n    \n//    public static boolean filterContains(ProfilerTable table, String filter) {\n//        return filterContains(table, filter, false, null);\n//    }\n//    \n//    public static boolean filterContains(ProfilerTable table, String filter, boolean matchCase, RowFilter excludes) {\n//        return filter(table, new TextFilter(filter, TextFilter.TYPE_INCLUSIVE, matchCase), excludes);\n//    }\n//    \n//    public static boolean filterNotContains(ProfilerTable table, String filter, boolean matchCase, RowFilter excludes) {\n//        return filter(table, new TextFilter(filter, TextFilter.TYPE_EXCLUSIVE, matchCase), excludes);\n//    }\n//    \n//    public static boolean filterRegExp(ProfilerTable table, String filter, RowFilter excludes) {\n//        return filter(table, new TextFilter(filter, TextFilter.TYPE_REGEXP, false), excludes);\n//    }\n    \n    public static boolean filter(TreeTableView view, final GenericFilter textFilter, final RowFilter excludesFilter, final boolean zeroClassesFilter) {\n        if (!zeroClassesFilter && textFilter.isAll()) {\n            view.setViewFilter(null);\n            return false;\n        }\n        \n        view.setViewFilter(new HeapViewerNodeFilter() {\n            public boolean passes(HeapViewerNode node, Heap heap) {\n//                if (!(node instanceof ClassNode)) return true;\n//\n//                JavaClass javaClass = ((ClassNode)node).getJavaClass();\n\n                JavaClass javaClass = HeapViewerNode.getValue(node, DataType.CLASS, heap);\n                if (javaClass == null) return true;\n                // NOTE: must compare DataType.COUNT to support also diffs\n                if (zeroClassesFilter && HeapViewerNode.getValue(node, DataType.COUNT, heap) == 0) return false;\n\n                String className = javaClass.getName();\n                if (textFilter.getType() != FILTER_INSTANCEOF) return textFilter.passes(className);\n                else {\n                    for (String value : textFilter.getValues())\n                        if (isInstanceOf(javaClass, value)) return true;\n                    return false;\n                }\n            }\n\n\n            private boolean isInstanceOf(JavaClass javaClass, String className) {\n                if (javaClass != null) {\n//                    JavaClass superCls = javaClass.getSuperClass();\n                    JavaClass cls = javaClass;\n                    for (; cls != null; cls = cls.getSuperClass())\n                        if (cls.getName().equals(className)) return true;\n                }\n                return false;\n            }\n        });\n        return true;\n    }\n    \n    public static void filterSubclasses(String className, JComponent filterPanel) {\n        Object filterString = filterPanel.getClientProperty(\"FILTER_STRING\"); // NOI18N\n        if (filterString instanceof JTextComponent) {\n            ((JTextComponent)filterString).setText(className);\n        } else {\n            return;\n        }\n\n        Object filterType = filterPanel.getClientProperty(\"FILTER_TYPE\"); // NOI18N\n        if (filterType instanceof FilterType) {\n            ((FilterType)filterType).filterImpl(FILTER_INSTANCEOF, Icons.getIcon(LanguageIcons.CLASS), Bundle.JavaFilterUtils_FilterSubclass());\n        } else {\n            return;\n        }\n\n        Object filterAction = filterPanel.getClientProperty(\"FILTER_ACTION\"); // NOI18N\n        if (filterAction instanceof AbstractAction) {\n            ((AbstractAction)filterAction).actionPerformed(null);\n        } else {\n            return;\n        }\n    }\n    \n    public static JComponent createFilterPanel(final TreeTableView view) {\n        return createFilterPanel(view, null);\n    }\n    \n    public static JComponent createFilterPanel(final TreeTableView view, final RowFilter excludesFilter) {\n        return createFilterPanel(view, excludesFilter, null);\n    }\n    \n    public static JComponent createFilterPanel(final TreeTableView view, final RowFilter excludesFilter, Component[] options) {\n        JToolBar toolbar = new InvisibleToolbar();\n        if (UIUtils.isWindowsModernLookAndFeel())\n            toolbar.setBorder(BorderFactory.createEmptyBorder(2, 2, 1, 2));\n        else if (!UIUtils.isNimbusLookAndFeel() && !UIUtils.isAquaLookAndFeel())\n            toolbar.setBorder(BorderFactory.createEmptyBorder(1, 2, 1, 2));\n        \n        toolbar.add(Box.createHorizontalStrut(6));\n        toolbar.add(new JLabel(Bundle.JavaFilterUtils_SidebarCaption()));\n        toolbar.add(Box.createHorizontalStrut(3));\n        \n        final EditableHistoryCombo combo = new EditableHistoryCombo();        \n        final JTextComponent textC = combo.getTextComponent();\n        \n        JPanel comboContainer = new JPanel(new BorderLayout());\n        comboContainer.add(combo, BorderLayout.CENTER);\n        comboContainer.setMinimumSize(combo.getMinimumSize());\n        comboContainer.setPreferredSize(combo.getPreferredSize());\n        comboContainer.setMaximumSize(combo.getMaximumSize());\n        \n        toolbar.add(comboContainer);\n        \n        if (PackageColorer.hasRegisteredColors()) {\n            toolbar.add(new PopupButton() {\n                {\n                    setToolTipText(Bundle.JavaFilterUtils_InsertFilter());\n                }\n//                protected void displayPopup() {\n//                    JPopupMenu menu = new JPopupMenu();\n//                    populatePopup(menu);\n//                    if (menu.getComponentCount() > 0) {\n//                        Dimension size = menu.getPreferredSize();\n//                        size.width = Math.max(size.width, getWidth());\n//                        menu.setPreferredSize(size);\n//                        menu.show(this, 0, -size.height);\n//                    }\n//                }\n                protected void populatePopup(JPopupMenu popup) {\n                    for (final ColoredFilter color : PackageColorer.getRegisteredColors()) {\n                        if (color.getValue().trim().isEmpty()) continue;\n                        Icon icon = color.getColor() == null ? null : color.getIcon(12, 12);\n                        popup.add(new JMenuItem(color.getName(), icon) {\n                            protected void fireActionPerformed(ActionEvent event) {\n                                String current = getFilterString(combo);\n                                if (current == null) current = \"\"; // NOI18N\n                                if (!current.isEmpty()) current += \" \"; // NOI18N\n                                current += color.getValue();\n                                textC.setText(current);\n                                combo.requestFocusInWindow();\n                            }\n                        });\n                    }\n                }\n            });\n        }\n        \n        toolbar.add(Box.createHorizontalStrut(5));\n        \n        KeyStroke escKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);\n        KeyStroke filterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);\n        \n        final TextFilter activeFilter = new TextFilter() {\n            protected void handleInvalidFilter(String invalidValue, RuntimeException e) {\n                ProfilerDialogs.displayError(Bundle.JavaFilterUtils_InvalidRegexp(invalidValue));\n            }\n        };\n        final TextFilter currentFilter = new TextFilter();\n        \n        final JToggleButton zeroClasses = new JToggleButton(ICON_CLASS_NO_INSTANCES) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                final boolean selected = isSelected();\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        filter(view, activeFilter, excludesFilter, selected);\n                    }\n                });\n            }\n        };\n        zeroClasses.setToolTipText(Bundle.JavaFilterUtils_HideZeroInstances());\n        \n        final JButton filter = new JButton(Bundle.JavaFilterUtils_ActionFilter(), Icons.getIcon(GeneralIcons.FILTER)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                final JButton _this = this;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        activeFilter.copyFrom(currentFilter);\n                        if (filter(view, activeFilter, excludesFilter, zeroClasses.isSelected()))\n                            combo.addItem(activeFilter.getValue());\n                        putClientProperty(FILTER_CHANGED, null);\n                        updateFilterButton(_this, currentFilter, activeFilter);\n                    }\n                });\n            }\n        };\n        String filterAccelerator = ActionsSupport.keyAcceleratorString(filterKey);\n        filter.setToolTipText(Bundle.JavaFilterUtils_FilterResults(filterAccelerator));\n        filter.putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n        \n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(final ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        if (filter.isEnabled()) {\n                            filter.doClick();\n                            combo.requestFocusInWindow();\n                        }\n                    }\n                });\n            }\n        };\n        installAction(filter, filterAction, filterKey, FILTER_ACTION_KEY);\n        toolbar.add(filter);\n        \n        updateFilterButton(filter, currentFilter, activeFilter);\n        \n        toolbar.add(Box.createHorizontalStrut(2));\n        \n        toolbar.addSeparator();\n        \n        toolbar.add(Box.createHorizontalStrut(1));\n        \n        final JToggleButton matchCase = new JToggleButton(Icons.getIcon(GeneralIcons.MATCH_CASE)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                if (isEnabled()) SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        currentFilter.setCaseSensitive(isSelected());\n                        updateFilterButton(filter, currentFilter, activeFilter);\n                    }\n                });\n            }\n        };\n        matchCase.setToolTipText(Bundle.JavaFilterUtils_MatchCase());\n        installAction(matchCase, filterAction, filterKey, FILTER_ACTION_KEY);\n        \n        FilterType filterType = new FilterType(Icons.getIcon(GeneralIcons.FILTER_CONTAINS)) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new JMenuItem(Bundle.JavaFilterUtils_FilterContains(), Icons.getIcon(GeneralIcons.FILTER_CONTAINS)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(TextFilter.TYPE_INCLUSIVE, getIcon(), getText());\n                    }\n                });\n                popup.add(new JMenuItem(Bundle.JavaFilterUtils_FilterNotContains(), Icons.getIcon(GeneralIcons.FILTER_NOT_CONTAINS)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(TextFilter.TYPE_EXCLUSIVE, getIcon(), getText());\n                    }\n                });\n                popup.add(new JMenuItem(Bundle.JavaFilterUtils_FilterRegExp(), Icons.getIcon(GeneralIcons.FILTER_REG_EXP)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(TextFilter.TYPE_REGEXP, getIcon(), getText());\n                    }\n                });\n                popup.add(new JMenuItem(Bundle.JavaFilterUtils_FilterSubclass(), Icons.getIcon(LanguageIcons.CLASS)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(FILTER_INSTANCEOF, getIcon(), getText());\n                    }\n                });\n            }\n            protected void filterImpl(final int type, final Icon icon, final String name) {\n                if (type == TextFilter.TYPE_REGEXP || type == FILTER_INSTANCEOF) {\n                    matchCase.setEnabled(false);\n                    matchCase.setSelected(false);\n                } else {\n                    if (!matchCase.isEnabled()) {\n                        matchCase.setSelected(currentFilter.isCaseSensitive());\n                        matchCase.setEnabled(true);\n                    }\n                }\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setIcon(icon);\n                        setToolTipText(Bundle.JavaFilterUtils_FilterType(name));\n                        currentFilter.setType(type);\n                        updateFilterButton(filter, currentFilter, activeFilter);\n                    }\n                });\n            }\n        };\n        filterType.setToolTipText(Bundle.JavaFilterUtils_FilterType(Bundle.JavaFilterUtils_FilterContains()));\n        installAction(filterType, filterAction, filterKey, FILTER_ACTION_KEY);\n        toolbar.add(filterType);\n        \n        toolbar.add(matchCase);\n        \n        toolbar.add(Box.createHorizontalStrut(2));\n        \n        toolbar.addSeparator();\n        \n        toolbar.add(Box.createHorizontalStrut(1));\n        \n        toolbar.add(zeroClasses);\n        \n        if (options != null) for (Component option : options) toolbar.add(option);\n        \n        toolbar.add(Box.createHorizontalStrut(2));\n        \n        combo.setOnTextChangeHandler(new Runnable() {\n            public void run() {\n                currentFilter.setValue(getFilterString(combo));\n                updateFilterButton(filter, currentFilter, activeFilter);\n            }\n        });\n        \n        final JPanel panel = new JPanel(new BorderLayout()) {\n            public void setVisible(boolean visible) {\n                super.setVisible(visible);\n                if (!visible) view.getComponent().requestFocusInWindow();\n            }\n            public boolean requestFocusInWindow() {\n                if (textC != null) textC.selectAll();\n                return combo.requestFocusInWindow();\n            }\n        };\n        panel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UIManager.getColor(\"controlShadow\"))); // NOI18N\n        panel.add(toolbar, BorderLayout.CENTER);\n        \n        final Runnable hider = new Runnable() {\n            public void run() {\n                boolean wasAll = activeFilter.isAll() && !zeroClasses.isSelected();\n                activeFilter.setValue(\"\"); // NOI18N\n                updateFilterButton(filter, currentFilter, activeFilter);\n                if (!wasAll) filter(view, activeFilter, excludesFilter, false);\n                zeroClasses.setSelected(false);\n                panel.setVisible(false);\n            }\n        };\n        JButton closeButton = CloseButton.create(hider);\n        closeButton.setFocusable(true);\n        String escAccelerator = ActionsSupport.keyAcceleratorString(escKey);\n        closeButton.setToolTipText(Bundle.JavaFilterUtils_Close(escAccelerator));\n        panel.add(closeButton, BorderLayout.EAST);\n        \n        String HIDE = \"hide-action\"; // NOI18N\n        InputMap map = panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        Action hiderAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { hider.run(); }\n        };\n        panel.getActionMap().put(HIDE, hiderAction);\n        map.put(escKey, HIDE);\n        \n        if (textC != null) {\n            map = textC.getInputMap();\n            Action _filterAction = new AbstractAction() {\n                public void actionPerformed(final ActionEvent e) {\n                    if (combo.isPopupVisible()) combo.hidePopup();\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { if (filter.isEnabled()) filter.doClick(); }\n                    });\n                }\n            };\n            textC.getActionMap().put(FILTER_ACTION_KEY, _filterAction);\n            map.put(filterKey, FILTER_ACTION_KEY);\n        }\n        \n        panel.putClientProperty(\"SET_FILTER_CHANGED\", new AbstractAction() { // NOI18N\n            public void actionPerformed(final ActionEvent e) {\n                filter.putClientProperty(FILTER_CHANGED, Boolean.TRUE);\n                updateFilterButton(filter, currentFilter, activeFilter);\n            }\n        });\n        \n        panel.putClientProperty(\"FILTER_STRING\", textC); // NOI18N\n        panel.putClientProperty(\"FILTER_TYPE\", filterType); // NOI18N\n        panel.putClientProperty(\"FILTER_ACTION\", filterAction); // NOI18N\n        \n        return panel;\n    }\n    \n    private static abstract class FilterType extends PopupButton {\n        FilterType(Icon icon) { super(icon); }\n        protected abstract void filterImpl(final int type, final Icon icon, final String name);\n    }\n    \n    private static void installAction(JComponent comp, Action action, KeyStroke keyStroke, String actionKey) {\n        comp.getActionMap().put(actionKey, action);\n        comp.getInputMap().put(keyStroke, actionKey);\n    }\n    \n    private static String getFilterString(EditableHistoryCombo combo) {\n        String filter = combo.getText();\n        return filter == null ? null : filter.trim();\n    }\n    \n    private static void updateFilterButton(JButton button, TextFilter currentFilter, TextFilter activeFilter) {\n        if (Boolean.TRUE.equals(button.getClientProperty(FILTER_CHANGED))) button.setEnabled(true);\n        else button.setEnabled(!currentFilter.equals(activeFilter));\n    }\n    \n    private static abstract class Filter extends RowFilter {\n\n        public boolean equals(Object o) {\n            return o instanceof Filter;\n        }\n        \n        public int hashCode() {\n            return Integer.MAX_VALUE;\n        }\n    \n    }\n    \n    \n    // Do not create instances of this class\n    private FilterUtils() {}\n    \n    \n//    // Default keybinding Ctrl+G for Filter action\n//    private static interface Support { @ServiceProvider(service=ActionsSupportProvider.class, position=100)\n//        public static final class FilterActionProvider extends ActionsSupportProvider {\n//            public KeyStroke registerAction(String actionKey, Action action, ActionMap actionMap, InputMap inputMap) {\n//                if (!FILTER_ACTION_KEY.equals(actionKey)) return null;\n//                \n//                KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.CTRL_MASK);\n//                actionMap.put(actionKey, action);\n//                inputMap.put(ks, actionKey);\n//\n//                return ks;\n//            }\n//        }\n//    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/GCTypeNode.java",
    "content": "/*\n * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.Font;\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstancesContainer;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.GCRoot;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ClassesContainer_MoreNodes=<another {0} GC roots left>\",\n    \"ClassesContainer_SamplesContainer=<sample {0} GC roots>\",\n    \"ClassesContainer_NodesContainer=<GC roots {0}-{1}>\"\n})\nclass GCTypeNode extends InstancesContainer.Objects {\n    \n    private int gcRoots;\n    private Map<Instance,Long> gcRootMap;\n\n    GCTypeNode(String name) {\n        super(name, DataType.CLASS.getUnsupportedValue());\n        gcRootMap = new HashMap<>();\n    }\n    \n    \n    protected String getMoreNodesString(String moreNodesCount)  {\n        return Bundle.ClassesContainer_MoreNodes(moreNodesCount);\n    }\n    \n    protected String getSamplesContainerString(String objectsCount)  {\n        return Bundle.ClassesContainer_SamplesContainer(objectsCount);\n    }\n    \n    protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n        return Bundle.ClassesContainer_NodesContainer(firstNodeIdx, lastNodeIdx);\n    }\n    \n    void addRoot(GCRoot gcroot, Instance i, Heap heap) {\n        gcRoots++;\n        Long count = gcRootMap.get(i);\n        if (count == null) {\n            count = 1L;\n            add(i, heap);\n        } else {\n            count++;\n        }\n        gcRootMap.put(i, count);\n    }\n\n    @Override\n    protected InstanceNode createNode(Instance instance) {\n        return new GCInstanceNode(instance);\n    }\n\n    @Override\n    protected Object getValue(DataType type, Heap heap) {\n        if (type == DataType.GCROOTS) return gcRoots;\n\n        return super.getValue(type, heap);\n    }\n    \n    static class Renderer extends LabelRenderer implements HeapViewerRenderer {\n        \n        Renderer() {\n            setIcon(Icons.getIcon(ProfilerIcons.RUN_GC));\n            setFont(getFont().deriveFont(Font.BOLD));\n        }\n        \n    }\n    \n    private class GCInstanceNode extends InstanceNode {\n\n        private GCInstanceNode(Instance instance) {\n            super(instance);\n        }\n\n        @Override\n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.GCROOTS) return gcRootMap.get(getInstance());\n\n            return super.getValue(type, heap);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/HeapPatterns.java",
    "content": "/*\n * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class HeapPatterns {\n\n    static PathToGCRootPlugin.SkipNode processGCRootReference(ObjectFieldValue reference) {\n        ObjectFieldValue ref = reference;\n        int skipped = 0;\n        for (; ;skipped++) {\n            Instance i = ref.getDefiningInstance();\n            Instance path = i.getNearestGCRootPointer();\n            if (!i.getJavaClass().equals(path.getJavaClass())) {\n                break;\n            }\n            ObjectFieldValue oval = getValueOfField(path, ref.getField());\n            if (oval == null || !i.equals(oval.getInstance())) {\n                break;\n            }\n            ref = oval;\n        }\n        if (skipped>1) {\n            return new PathToGCRootPlugin.SkipNode(ref, skipped);\n        }\n        return null;\n    }\n\n    private static ObjectFieldValue getValueOfField(Instance i, Field f) {\n        for (FieldValue val : i.getFieldValues()) {\n            if (val instanceof ObjectFieldValue) {\n                ObjectFieldValue oval = (ObjectFieldValue) val;\n                if (oval.getField().equals(f)) {\n                    return oval;\n                }\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaArrayItemsProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceReferenceNode;\nimport org.graalvm.visualvm.heapviewer.java.PrimitiveNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapViewerNode.Provider.class, position = 300)\n@NbBundle.Messages({\n    \"JavaArrayItemsProvider_Name=items\",\n    \"JavaArrayItemsProvider_MoreNodes=<another {0} items left>\",\n    \"JavaArrayItemsProvider_SamplesContainer=<sample {0} items>\",\n    \"JavaArrayItemsProvider_NodesContainer=<items {0}-{1}>\"\n})\npublic class JavaArrayItemsProvider extends HeapViewerNode.Provider {\n    \n    public String getName() {\n        return Bundle.JavaArrayItemsProvider_Name();\n    }\n    \n    public boolean supportsView(Heap heap, String viewID) {\n        return viewID.startsWith(\"java_\"); // NOI18N\n    }\n    \n    public boolean supportsNode(HeapViewerNode parent, Heap heap, String viewID) {\n        if (parent instanceof InstanceNode && !InstanceNode.Mode.INCOMING_REFERENCE.equals(((InstanceNode)parent).getMode())) {\n            Instance instance = ((InstanceNode)parent).getInstance();\n            return instance != null && instance.getJavaClass().isArray();\n        } else {\n            return false;\n        }\n    }\n    \n    public HeapViewerNode[] getNodes(final HeapViewerNode parent, final Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        final Instance instance = HeapViewerNode.getValue(parent, DataType.INSTANCE, heap);\n        if (instance == null) return null;\n        \n        if (instance instanceof PrimitiveArrayInstance) {\n            final String type = instance.getJavaClass().getName().replace(\"[]\", \"\"); // NOI18N\n            final List<String> items = ((PrimitiveArrayInstance)instance).getValues();\n            \n            NodesComputer<Integer> computer = new NodesComputer<Integer>(items.size(), UIThresholds.MAX_ARRAY_ITEMS) {\n                protected boolean sorts(DataType dataType) {\n                    if (DataType.COUNT == dataType || DataType.OWN_SIZE == dataType || DataType.RETAINED_SIZE == dataType) return false;\n                    return true;\n                }\n                protected HeapViewerNode createNode(Integer index) {\n                    return new PrimitiveNode.ArrayItem(index, type, items.get(index), instance);\n                }\n                protected ProgressIterator<Integer> objectsIterator(int index, Progress progress) {\n                    Iterator<Integer> iterator = integerIterator(index, items.size());\n                    return new ProgressIterator<>(iterator, index, false, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.JavaArrayItemsProvider_MoreNodes(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.JavaArrayItemsProvider_SamplesContainer(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.JavaArrayItemsProvider_NodesContainer(firstNodeIdx, lastNodeIdx);\n                }\n            };\n        \n            return computer.computeNodes(parent, heap, viewID, null, dataTypes, sortOrders, progress);\n        } else if (instance instanceof ObjectArrayInstance) {\n            final List<ArrayItemValue> items = ((ObjectArrayInstance)instance).getItems();\n            \n            NodesComputer<Integer> computer = new NodesComputer<Integer>(items.size(), UIThresholds.MAX_ARRAY_ITEMS) {\n                protected boolean sorts(DataType dataType) {\n                    return !DataType.COUNT.equals(dataType);\n                }\n                protected HeapViewerNode createNode(Integer index) {\n                    return new InstanceReferenceNode.ArrayItem(items.get(index), false);\n                }\n                protected ProgressIterator<Integer> objectsIterator(int index, Progress progress) {\n                    Iterator<Integer> iterator = integerIterator(index, items.size());\n                    return new ProgressIterator<>(iterator, index, false, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.JavaArrayItemsProvider_MoreNodes(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.JavaArrayItemsProvider_SamplesContainer(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.JavaArrayItemsProvider_NodesContainer(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            \n            return computer.computeNodes(parent, heap, viewID, null, dataTypes, sortOrders, progress);\n        }\n        \n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaClassesProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.stream.Collectors;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.ClassesContainer;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstancesContainer;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.GCRoot;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JavaClassesProvider {\n    \n    @NbBundle.Messages({\n        \"Classes_Messages_MoreNodes=<another {0} classes left>\",\n        \"Classes_Messages_SamplesContainer=<sample {0} classes>\",\n        \"Classes_Messages_NodesContainer=<classes {0}-{1}>\",\n        \"Classes_Messages_NoClasses=<no classes>\",\n        \"Classes_Messages_NoClassesFilter=<no classes matching the filter>\",\n        \"Classes_Messages_NoPackages=<no packages>\",\n        \"Classes_Messages_NoPackagesFilter=<no packages matching the filter>\"\n    })\n    static final class Classes_Messages {\n        static String getMoreNodesString(String moreNodesCount)  {\n            return Bundle.Classes_Messages_MoreNodes(moreNodesCount);\n        }\n        static String getSamplesContainerString(String objectsCount)  {\n            return Bundle.Classes_Messages_SamplesContainer(objectsCount);\n        }\n        static String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n            return Bundle.Classes_Messages_NodesContainer(firstNodeIdx, lastNodeIdx);\n        }\n        static String getNoClassesString(HeapViewerNodeFilter viewFilter) {\n            return viewFilter == null ? Bundle.Classes_Messages_NoClasses() : Bundle.Classes_Messages_NoClassesFilter();\n        }\n        static String getNoPackagesString(HeapViewerNodeFilter viewFilter) {\n            return viewFilter == null ? Bundle.Classes_Messages_NoPackages() : Bundle.Classes_Messages_NoPackagesFilter();\n        }\n    }\n    \n    public static HeapViewerNode[] getHeapClasses(HeapViewerNode parent, final Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        NodesComputer<JavaClass> computer = new NodesComputer<JavaClass>(heap.getAllClasses().size(), UIThresholds.MAX_TOPLEVEL_CLASSES) {\n            protected boolean sorts(DataType dataType) {\n                return true;\n            }\n            protected HeapViewerNode createNode(JavaClass javaClass) {\n                return new ClassNode(javaClass);\n            }\n            protected ProgressIterator<JavaClass> objectsIterator(int index, Progress progress) {\n                Iterator<JavaClass> iterator = heap.getAllClasses().listIterator(index);\n                return new ProgressIterator<>(iterator, index, false, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return Classes_Messages.getMoreNodesString(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return Classes_Messages.getSamplesContainerString(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return Classes_Messages.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n            }\n        };\n//        System.err.println(\">>> COMPUTED \" + java.util.Arrays.toString(computer.computeNodes(parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress)));\n        HeapViewerNode[] nodes = computer.computeNodes(parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n        return nodes.length == 0 ? new HeapViewerNode[] { new TextNode(Classes_Messages.getNoClassesString(viewFilter)) } : nodes;\n    }\n    \n\n    public static HeapViewerNode[] getHeapPackages(HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        List<HeapViewerNode> nodes = new ArrayList<>();\n        Map<String, ClassesContainer.Objects> packages = new HashMap<>();\n        \n        Thread worker = Thread.currentThread();\n        \n        List<JavaClass> classes = heap.getAllClasses();\n        for (JavaClass cls : classes) {\n            String className = cls.getName();\n            int nameIdx = className.lastIndexOf('.');\n            if (nameIdx == -1) {\n                ClassNode clsn = new ClassNode(cls);\n                if (viewFilter == null || viewFilter.passes(clsn, heap)) nodes.add(clsn);\n            } else {\n                if (viewFilter != null && !viewFilter.passes(new ClassNode(cls), heap)) continue;\n                \n                String pkgName = className.substring(0, nameIdx);\n                ClassesContainer.Objects node = packages.get(pkgName);\n                if (node == null) {\n                    node = new ClassesContainer.Objects(pkgName);\n                    nodes.add(node);\n                    packages.put(pkgName, node);\n                }\n                node.add(cls, heap);\n            }\n            if (worker.isInterrupted()) throw new InterruptedException();\n        }\n        \n        return nodes.isEmpty() ? new HeapViewerNode[] { new TextNode(Classes_Messages.getNoPackagesString(viewFilter)) } :\n                                 nodes.toArray(HeapViewerNode.NO_NODES);\n    }\n    \n\n    @NbBundle.Messages({\n        \"GCRoots_Messages_MoreNodes=<another {0} GC roots left>\",\n        \"GCRoots_Messages_SamplesContainer=<sample {0} GC roots>\",\n        \"GCRoots_Messages_NodesContainer=<GC roots {0}-{1}>\",\n        \"GCRoots_Messages_NoGCRoots=<no GC roots>\",\n        \"GCRoots_Messages_NoGCRootsFilter=<no GC roots matching the filter>\"\n    })\n    private static final class GCRoots_Messages {\n        private static String getMoreNodesString(String moreNodesCount)  {\n            return Bundle.GCRoots_Messages_MoreNodes(moreNodesCount);\n        }\n        private static String getSamplesContainerString(String objectsCount)  {\n            return Bundle.GCRoots_Messages_SamplesContainer(objectsCount);\n        }\n        private static String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n            return Bundle.GCRoots_Messages_NodesContainer(firstNodeIdx, lastNodeIdx);\n        }\n        private static String getNoItemsString(HeapViewerNodeFilter viewFilter) {\n            return viewFilter == null ? Bundle.GCRoots_Messages_NoGCRoots() : Bundle.GCRoots_Messages_NoGCRootsFilter();\n        }\n    }\n    \n    public static HeapViewerNode[] getHeapGCRoots(HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress, int aggregation) throws InterruptedException {\n        final Collection<GCRoot> gcroots = heap.getGCRoots();\n        final List<Instance> gcrootInstances = gcroots.stream()\n                .map(GCRoot::getInstance)\n                .filter(i -> i != null)\n                .distinct()\n                .collect(Collectors.toList());\n        \n        if (aggregation == 0) {\n            NodesComputer<Instance> computer = new NodesComputer<Instance>(gcrootInstances.size(), UIThresholds.MAX_TOPLEVEL_INSTANCES) {\n                protected boolean sorts(DataType dataType) {\n                    return !DataType.COUNT.equals(dataType);\n                }\n                protected HeapViewerNode createNode(Instance gcRootInstance) {\n                    return new InstanceNode(gcRootInstance);\n                }\n                protected ProgressIterator<Instance> objectsIterator(int index, Progress progress) {\n                    Iterator<Instance> iterator = gcrootInstances.listIterator(index);\n                    return new ProgressIterator<>(iterator, index, false, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return GCRoots_Messages.getMoreNodesString(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return GCRoots_Messages.getSamplesContainerString(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return GCRoots_Messages.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            HeapViewerNode[] nodes = computer.computeNodes(parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n            return nodes.length == 0 ? new HeapViewerNode[] { new TextNode(GCRoots_Messages.getNoItemsString(viewFilter)) } : nodes;\n        } else {\n            if (viewFilter != null) {\n                Iterator<Instance> gcrootsI = gcrootInstances.iterator();\n                while (gcrootsI.hasNext())\n                    if (!viewFilter.passes(new InstanceNode(gcrootsI.next()), heap))\n                        gcrootsI.remove();\n            }\n            \n            if (aggregation == 3) {\n                Map<String, GCTypeNode> types = new HashMap<>();\n                for (Instance instance : gcrootInstances) {\n                    Collection<GCRoot> igcroots = heap.getGCRoots(instance);\n                    for (GCRoot gcroot : igcroots) {\n                        String tname = gcroot.getKind();\n                        GCTypeNode tnode = types.get(tname);\n\n                        if (tnode == null) {\n                            tnode = new GCTypeNode(tname);\n                            types.put(tname, tnode);\n                        }\n                        tnode.addRoot(gcroot, instance, heap);\n                    }\n                }\n                return types.isEmpty() ? new HeapViewerNode[] { new TextNode(GCRoots_Messages.getNoItemsString(viewFilter)) } :\n                                          types.values().toArray(HeapViewerNode.NO_NODES);\n            } else {\n                List<InstancesContainer.Objects> cnodes = new ArrayList<>();\n                Map<String, InstancesContainer.Objects> classes = new HashMap<>();\n                for (Instance instance : gcrootInstances) {\n                    JavaClass javaClass = instance.getJavaClass();\n                    String className = javaClass.getName();\n                    InstancesContainer.Objects cnode = classes.get(className);\n                    if (cnode == null) {\n                        cnode = new InstancesContainer.Objects(className, javaClass) {\n                            protected String getMoreNodesString(String moreNodesCount)  {\n                                return GCRoots_Messages.getMoreNodesString(moreNodesCount);\n                            }\n                            protected String getSamplesContainerString(String objectsCount)  {\n                                return GCRoots_Messages.getSamplesContainerString(objectsCount);\n                            }\n                            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                                return GCRoots_Messages.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n                            }\n                        };\n                        classes.put(className, cnode);\n                        cnodes.add(cnode);\n                    }\n                    cnode.add(instance, heap);\n                }\n\n                if (aggregation == 1) {\n                    return cnodes.isEmpty() ? new HeapViewerNode[] { new TextNode(GCRoots_Messages.getNoItemsString(viewFilter)) } :\n                                              cnodes.toArray(HeapViewerNode.NO_NODES);\n                }\n\n                List<HeapViewerNode> pnodes = new ArrayList<>();\n                Map<String, ClassesContainer.ContainerNodes> packages = new HashMap<>();\n                for (InstancesContainer.Objects cnode : cnodes) {\n                    String className = cnode.getName();\n                    int nameIdx = className.lastIndexOf('.'); // NOI18N\n                    if (nameIdx == -1) {\n                        pnodes.add(cnode);\n                    } else {\n                        String pkgName = className.substring(0, nameIdx);\n                        ClassesContainer.ContainerNodes node = packages.get(pkgName);\n                        if (node == null) {\n                            node = new ClassesContainer.ContainerNodes(pkgName);\n                            pnodes.add(node);\n                            packages.put(pkgName, node);\n                        }\n                        node.add(cnode, heap);\n                    }\n                }\n\n                return pnodes.isEmpty() ? new HeapViewerNode[] { new TextNode(GCRoots_Messages.getNoItemsString(viewFilter)) } :\n                                          pnodes.toArray(HeapViewerNode.NO_NODES);\n            }\n        }\n    }\n    \n    \n    @NbBundle.Messages({\n        \"Dominators_Messages_MoreNodes=<another {0} dominators left>\",\n        \"Dominators_Messages_SamplesContainer=<sample {0} dominators>\",\n        \"Dominators_Messages_NodesContainer=<dominators {0}-{1}>\",\n        \"Dominators_Messages_NoDominators=<no dominators>\",\n        \"Dominators_Messages_NoDominatorsFilter=<no dominators matching the filter>\",\n        \"Dominators_Messages_NoRetainedSizes=<retained sizes not computed yet>\"\n    })\n    private static final class Dominators_Messages {\n        private static String getMoreNodesString(String moreNodesCount)  {\n            return Bundle.Dominators_Messages_MoreNodes(moreNodesCount);\n        }\n        private static String getSamplesContainerString(String objectsCount)  {\n            return Bundle.Dominators_Messages_SamplesContainer(objectsCount);\n        }\n        private static String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n            return Bundle.Dominators_Messages_NodesContainer(firstNodeIdx, lastNodeIdx);\n        }\n        private static String getNoItemsString(HeapViewerNodeFilter viewFilter) {\n            return viewFilter == null ? Bundle.Dominators_Messages_NoDominators() : Bundle.Dominators_Messages_NoDominatorsFilter();\n        }\n    }\n    \n    public static HeapViewerNode[] getHeapDominators(HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress, int aggregation) throws InterruptedException {\n        if (!DataType.RETAINED_SIZE.valuesAvailable(heap))\n            return new HeapViewerNode[] { new TextNode(Bundle.Dominators_Messages_NoRetainedSizes()) };\n        \n        List<Instance> dominators = new ArrayList<>(getDominatorRoots(heap));\n        \n        if (aggregation == 0) {\n            NodesComputer<Instance> computer = new NodesComputer<Instance>(dominators.size(), UIThresholds.MAX_TOPLEVEL_INSTANCES) {\n                protected boolean sorts(DataType dataType) {\n                    return !DataType.COUNT.equals(dataType);\n                }\n                protected HeapViewerNode createNode(Instance instance) {\n                    return new InstanceNode(instance);\n                }\n                protected ProgressIterator<Instance> objectsIterator(int index, Progress progress) {\n                    Iterator<Instance> iterator = dominators.listIterator(index);\n                    return new ProgressIterator<>(iterator, index, false, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Dominators_Messages.getMoreNodesString(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Dominators_Messages.getSamplesContainerString(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Dominators_Messages.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            HeapViewerNode[] nodes = computer.computeNodes(parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n            return nodes.length == 0 ? new HeapViewerNode[] { new TextNode(Dominators_Messages.getNoItemsString(viewFilter)) } : nodes;\n        } else {\n            if (viewFilter != null) {\n                Iterator<Instance> dominatorsI = dominators.iterator();\n                while (dominatorsI.hasNext())\n                    if (!viewFilter.passes(new InstanceNode(dominatorsI.next()), heap))\n                        dominatorsI.remove();\n            }\n            \n            List<InstancesContainer.Objects> cnodes = new ArrayList<>();\n            Map<String, InstancesContainer.Objects> classes = new HashMap<>();\n            for (Instance instance : dominators) {\n                JavaClass javaClass = instance.getJavaClass();\n                String className = javaClass.getName();\n                InstancesContainer.Objects cnode = classes.get(className);\n                if (cnode == null) {\n                    cnode = new InstancesContainer.Objects(className, javaClass) {\n                        protected String getMoreNodesString(String moreNodesCount)  {\n                            return Dominators_Messages.getMoreNodesString(moreNodesCount);\n                        }\n                        protected String getSamplesContainerString(String objectsCount)  {\n                            return Dominators_Messages.getSamplesContainerString(objectsCount);\n                        }\n                        protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                            return Dominators_Messages.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n                        }\n                    };\n                    classes.put(className, cnode);\n                    cnodes.add(cnode);\n                }\n                cnode.add(instance, heap);\n            }\n            \n            if (aggregation == 1) {\n                return cnodes.isEmpty() ? new HeapViewerNode[] { new TextNode(Dominators_Messages.getNoItemsString(viewFilter)) } :\n                                          cnodes.toArray(HeapViewerNode.NO_NODES);\n            }\n            \n            List<HeapViewerNode> pnodes = new ArrayList<>();\n            Map<String, ClassesContainer.ContainerNodes> packages = new HashMap<>();\n            for (InstancesContainer.Objects cnode : cnodes) {\n                String className = cnode.getName();\n                int nameIdx = className.lastIndexOf('.'); // NOI18N\n                if (nameIdx == -1) {\n                    pnodes.add(cnode);\n                } else {\n                    String pkgName = className.substring(0, nameIdx);\n                    ClassesContainer.ContainerNodes node = packages.get(pkgName);\n                    if (node == null) {\n                        node = new ClassesContainer.ContainerNodes(pkgName);\n                        pnodes.add(node);\n                        packages.put(pkgName, node);\n                    }\n                    node.add(cnode, heap);\n                }\n            }\n            \n            return pnodes.isEmpty() ? new HeapViewerNode[] { new TextNode(Dominators_Messages.getNoItemsString(viewFilter)) } :\n                                          pnodes.toArray(HeapViewerNode.NO_NODES);\n        }\n    }\n\n    static Set<Instance> getDominatorRoots(Heap heap) {\n        int searchScope = 1000;\n        List<Instance> searchInstances = heap.getBiggestObjectsByRetainedSize(searchScope);\n                \n        Set<Instance> dominators = new HashSet<>(searchInstances);\n        Set<Instance> removed = new HashSet<>();\n\n        for (Instance instance : searchInstances) {\n            if (dominators.contains(instance)) {\n                Instance dom = instance;\n                long retainedSize = instance.getRetainedSize();\n\n                while (!instance.isGCRoot()) {\n                    instance = instance.getNearestGCRootPointer();\n                    if (dominators.contains(instance) && instance.getRetainedSize()>=retainedSize) {\n                        dominators.remove(dom);\n                        removed.add(dom);\n                        dom = instance;\n                        retainedSize = instance.getRetainedSize();\n                    }\n                    if (removed.contains(instance)) {\n                        dominators.remove(dom);\n                        removed.add(dom);\n                        break;\n                    }\n                }\n            }\n        }\n        return dominators;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaDiffClassesProvider.java",
    "content": "/*\n * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport javax.accessibility.AccessibleContext;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.SortOrder;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.ClassNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.ClassesContainer;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JavaDiffClassesProvider {\n    \n    static HeapViewerNode[] getDiffHeapClasses(HeapViewerNode parent, final Heap heap1, List<ClassNode> diffClasses, boolean retained, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        NodesComputer<ClassNode> computer = new NodesComputer<ClassNode>(diffClasses.size(), UIThresholds.MAX_TOPLEVEL_CLASSES) {\n            protected boolean sorts(DataType dataType) {\n                return true;\n            }\n            protected HeapViewerNode createNode(ClassNode javaClass) {\n                return javaClass;\n            }\n            protected ProgressIterator<ClassNode> objectsIterator(int index, Progress progress) {\n                Iterator<ClassNode> iterator = diffClasses.listIterator(index);\n                return new ProgressIterator<>(iterator, index, false, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return JavaClassesProvider.Classes_Messages.getMoreNodesString(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return JavaClassesProvider.Classes_Messages.getSamplesContainerString(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return JavaClassesProvider.Classes_Messages.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n            }\n        };\n        \n        HeapViewerNode[] nodes = computer.computeNodes(parent, heap1, viewID, viewFilter, dataTypes, sortOrders, progress);\n        return nodes.length == 0 ? new HeapViewerNode[] { new TextNode(JavaClassesProvider.Classes_Messages.getNoClassesString(viewFilter)) } : nodes;\n    }\n    \n    static HeapViewerNode[] getDiffHeapPackages(HeapViewerNode parent, Heap heap1, List<ClassNode> diffClasses, boolean retained, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        List<HeapViewerNode> nodes = new ArrayList<>();\n        Map<String, DiffPackageNode> packages = new HashMap<>();\n        \n        Thread worker = Thread.currentThread();\n        \n        for (ClassNode cls : diffClasses) {\n            String className = cls.getName();\n            int nameIdx = className.lastIndexOf('.'); // NOI18N\n            if (nameIdx == -1) {\n                if (viewFilter == null || viewFilter.passes(cls, heap1)) nodes.add(cls);\n            } else {\n                if (viewFilter != null && !viewFilter.passes(cls, heap1)) continue;\n                \n                String pkgName = className.substring(0, nameIdx);\n                DiffPackageNode node = packages.get(pkgName);\n                if (node == null) {\n                    node = new DiffPackageNode(pkgName, retained);\n                    nodes.add(node);\n                    packages.put(pkgName, node);\n                }\n                node.add(cls, heap1);\n            }\n            if (worker.isInterrupted()) throw new InterruptedException();\n        }\n        \n        return nodes.isEmpty() ? new HeapViewerNode[] { new TextNode(JavaClassesProvider.Classes_Messages.getNoPackagesString(viewFilter)) } :\n                                 nodes.toArray(HeapViewerNode.NO_NODES);\n    }\n    \n    \n    static List<ClassNode> createDiffClasses(Heap h1, Heap h2, final boolean retained) {\n        if (retained) {\n            if (!DataType.RETAINED_SIZE.valuesAvailable(h1))\n                DataType.RETAINED_SIZE.computeValuesImmediately(h1);\n            \n            if (!DataType.RETAINED_SIZE.valuesAvailable(h2))\n                DataType.RETAINED_SIZE.computeValuesImmediately(h2);\n        }\n        \n        Map<JavaClassID, DiffClassNode> classes = new HashMap<>();\n        \n        List<JavaClass> classes1 = h1.getAllClasses();\n        for (JavaClass jc1 : classes1) {\n            JavaClassID id1 = JavaClassID.create(jc1);\n            DiffClassNode djc1 = classes.get(id1);\n            if (djc1 == null) {\n                djc1 = DiffClassNode.own(jc1, retained);\n                classes.put(id1, djc1);\n            } else {\n                djc1.mergeOwn(jc1);\n            }\n        }\n        \n        List<JavaClass> classes2 = h2.getAllClasses();\n        for (JavaClass jc2 : classes2) {\n            JavaClassID id2 = JavaClassID.create(jc2);\n            DiffClassNode djc2 = classes.get(id2);\n            if (djc2 == null) {\n                djc2 = DiffClassNode.external(new ExternalJavaClass(jc2, retained), retained);\n                classes.put(id2, djc2);\n            } else {\n                djc2.mergeExternal(jc2);\n            }\n        }\n        \n        return new ArrayList<>(classes.values());\n    }\n    \n    private static class JavaClassID {\n        \n        static JavaClassID create(JavaClass jc) {\n            return new JavaClassID(jc);\n        }\n        \n        \n        private final String id;\n        \n        private JavaClassID(JavaClass jc) {\n            id = jc.getName();\n        }\n        \n        @Override\n        public boolean equals(Object o) {\n            if (!(o instanceof JavaClassID)) return false;\n            return id.equals(((JavaClassID)o).id);\n        }\n\n        @Override\n        public int hashCode() {\n            return id.hashCode();\n        }\n        \n    }\n    \n    private static class DiffClassNode extends ClassNode {\n        \n        private final boolean trackRetained;\n        \n        private final boolean ownClass;\n        \n        private int instancesCount;\n        private long ownSize;\n        private long retainedSize;\n        \n        \n        static DiffClassNode own(JavaClass ownClass, boolean trackRetained) {\n            DiffClassNode dClass = new DiffClassNode(ownClass, true, trackRetained);\n            dClass.mergeOwn(ownClass);\n            return dClass;\n        }\n        \n        static DiffClassNode external(JavaClass externalClass, boolean trackRetained) {\n            DiffClassNode dClass = new DiffClassNode(externalClass, false, trackRetained);\n            dClass.mergeExternal(externalClass);\n            return dClass;\n        }\n        \n        \n        private DiffClassNode(JavaClass jClass, boolean ownClass, boolean trackRetained) {\n            super(jClass);\n            \n            this.trackRetained = trackRetained;\n            this.ownClass = ownClass;\n            \n            setChildren(NO_NODES);\n        }\n        \n        \n        boolean isOwnClass() {\n            return this.ownClass;\n        }\n        \n        \n        void mergeOwn(JavaClass ownClass) {\n            instancesCount += ownClass.getInstancesCount();\n            ownSize += ownClass.getAllInstancesSize();\n            if (trackRetained) retainedSize += ownClass.getRetainedSizeByClass();\n        }\n        \n        void mergeExternal(JavaClass externalClass) {\n            instancesCount -= externalClass.getInstancesCount();\n            ownSize -= externalClass.getAllInstancesSize();\n            if (trackRetained) retainedSize -= externalClass.getRetainedSizeByClass();\n        }\n        \n        \n        // NOTE: returning null breaks filtering\n//        public JavaClass getJavaClass() {\n//            return isOwnClass() ? super.getJavaClass() : null;\n//        }\n        \n        public int getInstancesCount() {\n            return instancesCount;\n        }\n\n        public long getOwnSize() {\n            return ownSize;\n        }\n\n        public long getRetainedSize(Heap heap) {\n            return trackRetained ? retainedSize : DataType.RETAINED_SIZE.getNotAvailableValue();\n        }\n        \n        \n        public boolean isLeaf() {\n            return true;\n        }\n        \n        public ClassNode createCopy() {\n            return ownClass ? super.createCopy() : null;\n        }\n        \n        @Override\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof ClassNode)) return false;\n            return getName().equals(((ClassNode)o).getName());\n        }\n\n        @Override\n        public int hashCode() {\n            return getName().hashCode();\n        }\n        \n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.NAME) return getName();\n            if (type == DataType.COUNT) return getInstancesCount();\n            if (type == DataType.OWN_SIZE) return getOwnSize();\n            if (type == DataType.RETAINED_SIZE) return getRetainedSize(heap);\n\n            if (type == DataType.CLASS) return getJavaClass();\n\n            return type.getNotAvailableValue();\n        }\n        \n    }\n    \n    private static class DiffPackageNode extends ClassesContainer.Nodes {\n        \n        private final boolean trackRetained;\n        \n        DiffPackageNode (String name, boolean trackRetained) {\n            super(name);\n            \n            this.trackRetained = trackRetained;\n            \n            count = 0;\n            ownSize = 0;\n            if (trackRetained) retainedSize = 0;\n        }\n        \n        public void add(ClassNode item, Heap heap) {\n            items.add(item);\n\n            count += getCount(item, heap);\n            ownSize += getOwnSize(item, heap);\n            if (trackRetained) retainedSize += getRetainedSize(item, heap);\n        }\n        \n    }\n    \n    private static class DiffClassNodeRenderer implements HeapViewerRenderer {\n        \n        private final Heap heap;\n\n        private ClassNodeRenderer currentRenderer;\n        private ClassNodeRenderer ownRenderer;\n        private ClassNodeRenderer externalRenderer;\n        \n        \n        DiffClassNodeRenderer(Heap heap) {\n            this.heap = heap;\n        }\n        \n        \n\n        @Override\n        public Icon getIcon() {\n            return currentRenderer.getIcon();\n        }\n\n        @Override\n        public String getShortName() {\n            return currentRenderer.getShortName();\n        }\n\n        \n        @Override\n        public void setValue(Object o, int i) {\n            if (o == null) return;\n            \n            DiffClassNode cdn = (DiffClassNode)o;\n            currentRenderer = cdn.isOwnClass() ? ownRenderer() : externalRenderer();\n            \n            currentRenderer.setValue(o, i);\n        }\n\n        @Override\n        public int getHorizontalAlignment() {\n            return currentRenderer.getHorizontalAlignment();\n        }\n\n        @Override\n        public JComponent getComponent() {\n            return currentRenderer.getComponent();\n        }\n\n        @Override\n        public void move(int i, int i1) {\n            currentRenderer.move(i, i1);\n        }\n\n        @Override\n        public AccessibleContext getAccessibleContext() {\n            return currentRenderer.getAccessibleContext();\n        }\n        \n        \n        @Override\n        public String toString() {\n            return currentRenderer == null ? \"\" : currentRenderer.toString(); // NOI18N\n        }\n        \n        \n        private ClassNodeRenderer ownRenderer() {\n            if (ownRenderer == null) ownRenderer = new ClassNodeRenderer(heap);\n            return ownRenderer;\n        }\n        \n        private ClassNodeRenderer externalRenderer() {\n            if (externalRenderer == null) {\n//                Image dis = GrayFilter.createDisabledImage(Icons.getImage(LanguageIcons.CLASS));\n//                Icon dis = ImageUtilities.createDisabledIcon(Icons.getIcon(LanguageIcons.CLASS));\n                Icon dis = UIManager.getLookAndFeel().getDisabledIcon(new JLabel(), Icons.getIcon(LanguageIcons.CLASS));\n                externalRenderer = new ClassNodeRenderer(dis, heap);\n            }\n            return externalRenderer;\n        }\n        \n    }\n    \n    @ServiceProvider(service=HeapViewerRenderer.Provider.class)\n    public static class DiffClassNodeRendererProvider extends HeapViewerRenderer.Provider {\n\n        public boolean supportsView(HeapContext context, String viewID) {\n            return viewID.startsWith(\"diff\") && JavaHeapFragment.isJavaHeap(context); // NOI18N\n        }\n\n        public void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers, HeapContext context) {\n            Heap heap = context.getFragment().getHeap();\n\n            DiffClassNodeRenderer dcnRenderer = new DiffClassNodeRenderer(heap);\n            renderers.put(DiffClassNode.class, dcnRenderer);\n        }\n\n    }\n    \n    private static class ExternalJavaClass implements JavaClass {\n        \n        private final long allInstancesSize;\n        private final boolean isArray;\n        private final int instanceSize;\n        private final int instancesCount;\n        private final long retainedSizeByClass;\n        private final long javaClassId;\n        private final String name;\n        \n        ExternalJavaClass(JavaClass javaClass, boolean retained) {\n            allInstancesSize = javaClass.getAllInstancesSize();\n            isArray = javaClass.isArray();\n            instanceSize = javaClass.getInstanceSize();\n            instancesCount = javaClass.getInstancesCount();\n            retainedSizeByClass = retained ? javaClass.getRetainedSizeByClass() : DataType.RETAINED_SIZE.getNotAvailableValue();\n            javaClassId = javaClass.getJavaClassId();\n            name = javaClass.getName();\n        }\n\n        @Override\n        public Object getValueOfStaticField(String string) {\n            return null;\n        }\n\n        @Override\n        public long getAllInstancesSize() {\n            return allInstancesSize;\n        }\n\n        @Override\n        public boolean isArray() {\n            return isArray;\n        }\n\n        @Override\n        public Instance getClassLoader() {\n            return null;\n        }\n\n        @Override\n        public ObjectArrayInstance getSigners() {\n            return null;\n        }\n\n        @Override\n        public Instance getProtectionDomain() {\n            return null;\n        }\n\n        @Override\n        public List<Field> getFields() {\n            return null;\n        }\n\n        @Override\n        public int getInstanceSize() {\n            return instanceSize;\n        }\n\n        @Override\n        public List<Instance> getInstances() {\n            return null;\n        }\n\n        @Override\n        public Iterator<Instance> getInstancesIterator() {\n            return null;\n        }\n\n        @Override\n        public int getInstancesCount() {\n            return instancesCount;\n        }\n\n        @Override\n        public long getRetainedSizeByClass() {\n            return retainedSizeByClass;\n        }\n\n        @Override\n        public long getJavaClassId() {\n            return javaClassId;\n        }\n\n        @Override\n        public String getName() {\n            return name;\n        }\n\n        @Override\n        public List<FieldValue> getStaticFieldValues() {\n            return null;\n        }\n\n        @Override\n        public Collection<JavaClass> getSubClasses() {\n            return null;\n        }\n\n        @Override\n        public JavaClass getSuperClass() {\n            return null;\n        }\n        \n        @Override\n        public Heap getHeap() {\n            return null;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof JavaClass)) return false;\n            return getName().equals(((JavaClass)o).getName());\n        }\n\n        @Override\n        public int hashCode() {\n            return getName().hashCode();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaDiffDumpSelector.java",
    "content": "/*\n * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.ItemListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\nimport java.util.ArrayList;\nimport java.util.Date;\nimport javax.swing.ButtonGroup;\nimport javax.swing.DefaultListCellRenderer;\nimport javax.swing.DefaultListModel;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JRadioButton;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextField;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.filechooser.FileFilter;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerStorage;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"CompareSnapshotsHelper_HeapSnapshotDisplayName=[heap] {0}\",\n    \"CompareSnapshotsHelper_SelectDialogCaption=Select Heap Dump to Compare\",\n    \"CompareSnapshotsHelper_OpenChooserCaption=Open Heap Dump\",\n    \"CompareSnapshotsHelper_OpenChooserFilter=Heap Dump Files\",\n    \"CompareSnapshotsHelper_NoComparableSnapshotsFoundMsg=<no comparable heap dumps found>\",\n    \"CompareSnapshotsHelper_ComparingSameSnapshotsMsg=The heap dump cannot be compared to itself.\",\n    \"CompareSnapshotsHelper_InvalidFileMsg=Invalid heap dump file\",\n    \"CompareSnapshotsHelper_EnterFileMsg=Enter heap dump file\",\n    \"CompareSnapshotsHelper_OkButtonText=OK\",\n    \"CompareSnapshotsHelper_SelectSnapshotString=<html><b><nobr>Select heap dump to compare:</nobr></b></html>\",\n    \"CompareSnapshotsHelper_FromProjectRadioText=From &project:\",\n    \"CompareSnapshotsHelper_FromCurrentLocationRadioText=From &current location:\",\n    \"CompareSnapshotsHelper_FromFileRadioText=From &file:\",\n    \"CompareSnapshotsHelper_BrowseButtonText=&Browse\",\n    \"CompareSnapshotsHelper_BrowseButtonAccessDescr=Select heap dump file\",\n    \"CompareSnapshotsHelper_SnapshotsListAccessDescr=List of comparable heap dumps in current project\",\n    \"CompareSnapshotsHelper_CompareRetainedRadio=Compare &retained sizes\",\n    \"CompareSnapshotsHelper_CompareRetainedRadioAccessDescr=Compute and compare retained sizes by class\",\n    \"CompareSnapshotsHelper_CompareRetainedHint=Comparing retained sizes can take a significant amount of time!\",\n    \"CompareSnapshotsHelper_CaptionWarning=Warning\",\n    \"CompareSnapshotsHelper_DifferentObjectSize=<html><b>Object sizes are different.</b><br><br>Size of the same objects differ for each heap dump and their comparison is invalid.<br>The heap dumps have likely been taken on different architectures (32bit vs. 64bit).</html>\"\n})\nclass JavaDiffDumpSelector {\n    \n    private class SelectSecondSnapshotPanel extends JPanel {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private JButton externalFileButton;\n        private JButton okButton;\n        private JLabel externalFileHintLabel;\n        private JLabel projectSnapshotsHintLabel;\n        private JLabel selectSnapshotLabel;\n        private JList projectSnapshotsList;\n        private JRadioButton fromFileRadio;\n        private JRadioButton fromProjectRadio;\n        private JTextField externalFileField;\n        private JCheckBox compareRetainedCheckBox;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        SelectSecondSnapshotPanel() {\n            initComponents();\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        JButton getOKButton() {\n            return okButton;\n        }\n\n        File getSnapshot() {\n            if (fromProjectRadio.isSelected()) {\n                Object selectedItem = projectSnapshotsList.getSelectedValue();\n\n                if (!(selectedItem instanceof FileObject)) {\n                    return null;\n                }\n\n                return FileUtil.toFile((FileObject)selectedItem);\n            } else if (fromFileRadio.isSelected()) {\n                String sf = externalFileField.getText();\n\n                if (!sf.isEmpty()) {\n                    File s = new File(sf);\n\n                    if (s.exists() && s.isFile()) {\n                        return s;\n                    }\n                }\n\n                return null;\n            } else {\n                return null;\n            }\n        }\n        \n        boolean computeRetained() {\n            return compareRetainedCheckBox.isSelected();\n        }\n\n        void populateSnapshotsList() {\n            // Get list model\n            DefaultListModel listModel = (DefaultListModel) projectSnapshotsList.getModel();\n\n            // Clear the list\n            listModel.removeAllElements();\n\n            // Add saved snapshots\n//            final Lookup.Provider project = heapWalker.getHeapDumpProject();\n            File heapdumpFile = context.getFile();\n            final File heapdumpDir = heapdumpFile != null ? heapdumpFile.getParentFile() : null;\n            FileObject[] snapshotsOnDisk = listSavedHeapdumps(heapdumpDir);\n            FileObject snapshotFile = (heapdumpFile != null) ? FileUtil.toFileObject(heapdumpFile) : null;\n\n            for (FileObject snapshotsOnDisk1 : snapshotsOnDisk) {\n                if (!snapshotsOnDisk1.equals(snapshotFile)) {\n                    listModel.addElement(snapshotsOnDisk1);\n                }\n            }\n\n            if (listModel.getSize() == 0) {\n                listModel.addElement(Bundle.CompareSnapshotsHelper_NoComparableSnapshotsFoundMsg());\n                fromFileRadio.setSelected(true);\n                externalFileField.addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && externalFileField.isShowing()) {\n                            externalFileField.removeHierarchyListener(this);\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    externalFileField.requestFocusInWindow();\n                                }\n                            });\n                        }\n                    }\n                });\n            } else {\n                projectSnapshotsList.setSelectedIndex(0);\n                projectSnapshotsList.addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && externalFileField.isShowing()) {\n                            projectSnapshotsList.removeHierarchyListener(this);\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    projectSnapshotsList.requestFocusInWindow();\n                                }\n                            });\n                        }\n                    }\n                });\n            }\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n//                    if (project != null) {\n//                        org.openide.awt.Mnemonics.setLocalizedText(fromProjectRadio, Bundle.CompareSnapshotsHelper_FromProjectRadioText());\n//                        fromProjectRadio.setToolTipText(null);\n//                    } else {\n                        org.openide.awt.Mnemonics.setLocalizedText(fromProjectRadio, Bundle.CompareSnapshotsHelper_FromCurrentLocationRadioText());\n                        fromProjectRadio.setToolTipText(heapdumpDir != null ?\n                                heapdumpDir.getAbsolutePath() : null);\n//                    }\n                }\n            });\n        }\n\n        private void initComponents() {\n            okButton = new JButton(Bundle.CompareSnapshotsHelper_OkButtonText());\n\n            setLayout(new GridBagLayout());\n\n            GridBagConstraints c;\n            ButtonGroup group = new ButtonGroup();\n\n            selectSnapshotLabel = new JLabel(Bundle.CompareSnapshotsHelper_SelectSnapshotString());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 0;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(15, 10, 8, 10);\n            add(selectSnapshotLabel, c);\n\n            fromProjectRadio = new JRadioButton();\n            org.openide.awt.Mnemonics.setLocalizedText(fromProjectRadio, Bundle.CompareSnapshotsHelper_FromProjectRadioText());\n            group.add(fromProjectRadio);\n            fromProjectRadio.getAccessibleContext().setAccessibleDescription(Bundle.CompareSnapshotsHelper_SelectSnapshotString() + Bundle.CompareSnapshotsHelper_FromProjectRadioText());\n            fromProjectRadio.setSelected(true);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 1;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(0, 15, 0, 10);\n            add(fromProjectRadio, c);\n\n            projectSnapshotsList = new JList(new DefaultListModel());\n            projectSnapshotsList.getAccessibleContext().setAccessibleName(Bundle.CompareSnapshotsHelper_SnapshotsListAccessDescr());\n            projectSnapshotsList.setVisibleRowCount(5);\n            projectSnapshotsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n\n            JScrollPane projectSnapshotsListScroll = new JScrollPane(projectSnapshotsList,\n                                                                     JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                                                                     JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n            projectSnapshotsListScroll.setPreferredSize(new Dimension(1, projectSnapshotsListScroll.getPreferredSize().height));\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 2;\n            c.weighty = 1d;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.fill = GridBagConstraints.BOTH;\n            c.insets = new Insets(0, 15 + new JRadioButton(\"\").getPreferredSize().width, 5, 10); // NOI18N\n            add(projectSnapshotsListScroll, c);\n\n            projectSnapshotsHintLabel = new JLabel(\" \"); // NOI18N\n            projectSnapshotsHintLabel.setForeground(Color.darkGray);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 3;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(0, 15 + new JRadioButton(\"\").getPreferredSize().width, 5, 10); // NOI18N\n            add(projectSnapshotsHintLabel, c);\n\n            fromFileRadio = new JRadioButton(Bundle.CompareSnapshotsHelper_FromFileRadioText());\n            org.openide.awt.Mnemonics.setLocalizedText(fromFileRadio, Bundle.CompareSnapshotsHelper_FromFileRadioText());\n            group.add(fromFileRadio);\n            fromProjectRadio.getAccessibleContext().setAccessibleDescription(Bundle.CompareSnapshotsHelper_SelectSnapshotString() + Bundle.CompareSnapshotsHelper_FromFileRadioText());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 4;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(5, 15, 0, 10);\n            add(fromFileRadio, c);\n\n            externalFileField = new JTextField();\n            externalFileField.setPreferredSize(new Dimension(250, externalFileField.getPreferredSize().height));\n            externalFileField.setEnabled(false);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 5;\n            c.weightx = 1d;\n            c.gridwidth = 2;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, 15 + new JRadioButton(\"\").getPreferredSize().width, 5, 5); // NOI18N\n            add(externalFileField, c);\n\n            externalFileButton = new JButton();\n            org.openide.awt.Mnemonics.setLocalizedText(externalFileButton, Bundle.CompareSnapshotsHelper_BrowseButtonText());\n            externalFileButton.getAccessibleContext().setAccessibleDescription(Bundle.CompareSnapshotsHelper_BrowseButtonAccessDescr());\n            externalFileButton.setEnabled(false);\n            c = new GridBagConstraints();\n            c.gridx = 2;\n            c.gridy = 5;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(0, 5, 5, 10);\n            add(externalFileButton, c);\n\n            externalFileHintLabel = new JLabel(\" \"); // NOI18N\n            externalFileHintLabel.setForeground(Color.darkGray);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 6;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(0, 15 + new JRadioButton(\"\").getPreferredSize().width, 5, 10); // NOI18N\n            add(externalFileHintLabel, c);\n            \n            compareRetainedCheckBox = new JCheckBox();\n            org.openide.awt.Mnemonics.setLocalizedText(compareRetainedCheckBox, Bundle.CompareSnapshotsHelper_CompareRetainedRadio());\n            compareRetainedCheckBox.getAccessibleContext().setAccessibleDescription(Bundle.CompareSnapshotsHelper_CompareRetainedRadioAccessDescr());\n            compareRetainedCheckBox.setSelected(compareRetained);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 7;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(5, 15, 0, 10);\n            add(compareRetainedCheckBox, c);\n            \n            if (!compareRetained) {\n                JLabel compareRetainedHintLabel = new JLabel(Bundle.CompareSnapshotsHelper_CompareRetainedHint());\n                compareRetainedHintLabel.setForeground(Color.darkGray);\n                c = new GridBagConstraints();\n                c.gridx = 0;\n                c.gridy = 8;\n                c.gridwidth = GridBagConstraints.REMAINDER;\n                c.anchor = GridBagConstraints.WEST;\n                c.insets = new Insets(0, 15 + new JRadioButton(\"\").getPreferredSize().width, 5, 10); // NOI18N\n                add(compareRetainedHintLabel, c);\n            }\n\n            projectSnapshotsList.setCellRenderer(new DefaultListCellRenderer() {\n                    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,\n                                                                  boolean cellHasFocus) {\n                        JLabel c = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);\n\n                        if (value instanceof FileObject) {\n                            FileObject fo = (FileObject) value;\n                            c.setIcon(memoryIcon);\n                            c.setText(getHeapDumpDisplayName(fo.getName()));\n\n//                            File f = FileUtil.toFile(fo);\n//                            Set<TopComponent> tcs = WindowManager.getDefault().getRegistry().getOpened();\n//                            for (TopComponent tc : tcs) {\n//                                if (f.equals(tc.getClientProperty(ProfilerTopComponent.RECENT_FILE_KEY))) {\n//                                    c.setFont(c.getFont().deriveFont(Font.BOLD));\n//                                    break;\n//                                }\n//                            }\n                        }\n\n                        return c;\n                    }\n                });\n\n            projectSnapshotsList.addListSelectionListener(new ListSelectionListener() {\n                    public void valueChanged(ListSelectionEvent e) {\n                        updateOKButton();\n                    }\n                });\n\n            projectSnapshotsList.addMouseListener(new MouseAdapter() {\n                    public void mousePressed(MouseEvent e) {\n                        if ((e.getButton() == MouseEvent.BUTTON1) && (e.getClickCount() == 2)\n                                && (projectSnapshotsList.getSelectedValue() != null)) {\n                            SwingUtilities.invokeLater(new Runnable() {\n                                    public void run() {\n                                        okButton.doClick();\n                                    }\n                                });\n                        }\n                    }\n                });\n\n            fromProjectRadio.addItemListener(new ItemListener() {\n                    public void itemStateChanged(ItemEvent e) {\n                        projectSnapshotsList.setEnabled(fromProjectRadio.isSelected());\n                        projectSnapshotsHintLabel.setText(\" \"); // NOI18N\n                        updateOKButton();\n                    }\n                });\n\n            fromFileRadio.addItemListener(new ItemListener() {\n                    public void itemStateChanged(ItemEvent e) {\n                        externalFileField.setEnabled(fromFileRadio.isSelected());\n                        externalFileButton.setEnabled(fromFileRadio.isSelected());\n\n                        if (!fromFileRadio.isSelected()) {\n                            externalFileHintLabel.setText(\" \"); // NOI18N\n                        }\n\n                        updateOKButton();\n                    }\n                });\n\n            DocumentListener documentListener = new DocumentListener() {\n                public void insertUpdate(DocumentEvent e) {\n                    updateOKButton();\n                }\n\n                public void removeUpdate(DocumentEvent e) {\n                    updateOKButton();\n                }\n\n                public void changedUpdate(DocumentEvent e) {\n                    updateOKButton();\n                }\n            };\n\n            externalFileField.getDocument().addDocumentListener(documentListener);\n\n            externalFileButton.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        JFileChooser snapshotChooser = JavaDiffDumpSelector.getSnapshotFileChooser();\n                        snapshotChooser.setCurrentDirectory(new File(externalFileField.getText()));\n\n                        if (snapshotChooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == 0) {\n                            File file = snapshotChooser.getSelectedFile();\n\n                            if (file != null) {\n                                externalFileField.setText(file.getAbsolutePath());\n                            }\n                        }\n                    }\n                });\n\n            updateOKButton();\n        }\n\n        private void updateOKButton() {\n            if (fromProjectRadio.isSelected()) {\n                // Snapshot from project\n                Object selectedItem = projectSnapshotsList.getSelectedValue();\n                okButton.setEnabled((selectedItem != null) && !(selectedItem instanceof String));\n            } else if (fromFileRadio.isSelected()) {\n                // Snapshot from file\n                String sf = externalFileField.getText();\n\n                if (!sf.isEmpty()) {\n                    // filename not empty string\n                    File s = new File(sf);\n\n                    if (s.exists() && checkHprofFile(s)) {\n                        // file exists\n                        if (s.equals(context.getFile())) {\n                            // comparing snapshot with itself\n                            externalFileHintLabel.setText(Bundle.CompareSnapshotsHelper_ComparingSameSnapshotsMsg());\n                            okButton.setEnabled(false);\n                        } else {\n                            // comparing different snapshots\n                            externalFileHintLabel.setText(\" \"); // NOI18N\n                            okButton.setEnabled(true);\n                        }\n                    } else {\n                        // file doesn't exist or not a .hprof file\n                        externalFileHintLabel.setText(Bundle.CompareSnapshotsHelper_InvalidFileMsg());\n                        okButton.setEnabled(false);\n                    }\n                } else {\n                    // filename is empty string\n                    externalFileHintLabel.setText(Bundle.CompareSnapshotsHelper_EnterFileMsg());\n                    okButton.setEnabled(false);\n                }\n            } else {\n                okButton.setEnabled(false);\n            }\n        }\n    }\n    \n    static class Result {\n        private File file;\n        private boolean compareRetained;\n        \n        Result(File file, boolean compareRetained) {\n            this.file = file;\n            this.compareRetained = compareRetained;\n        }\n        \n        File getFile() { return file; }\n        boolean compareRetained() { return compareRetained; }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Icon memoryIcon = Icons.getIcon(ProfilerIcons.HEAP_DUMP);\n    private static JFileChooser snapshotFileChooser;\n//    private static HelpCtx HELP_CTX = new HelpCtx(\"SelectSecondSnapshot.HelpCtx\"); // NOI18N\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private HeapContext context;\n    private boolean compareRetained;\n    private SelectSecondSnapshotPanel secondSnapshotSelector;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private JavaDiffDumpSelector(HeapContext context, boolean compareRetained) {\n        this.context = context;\n        this.compareRetained = compareRetained;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    static void checkObjectSizes(Heap heap1, Heap heap2) {\n        JavaClass objcls1 = heap1.getJavaClassByName(\"java.lang.Object\"); // NOI18N\n        JavaClass objcls2 = heap2.getJavaClassByName(\"java.lang.Object\"); // NOI18N\n        \n        if (objcls1.getInstanceSize() != objcls2.getInstanceSize())\n            ProfilerDialogs.displayWarningDNSA(Bundle.CompareSnapshotsHelper_DifferentObjectSize(),\n                                               Bundle.CompareSnapshotsHelper_CaptionWarning(), null,\n                                               \"CompareSnapshotsHelper.checkObjectSizes\", false); // NOI18N\n    }\n\n    static Result selectSnapshot(HeapContext context, boolean compareRetained) {\n        JavaDiffDumpSelector helper = new JavaDiffDumpSelector(context, compareRetained);\n        SelectSecondSnapshotPanel panel = helper.getSecondSnapshotSelector();\n        panel.populateSnapshotsList();\n\n        DialogDescriptor desc = new DialogDescriptor(panel, Bundle.CompareSnapshotsHelper_SelectDialogCaption(), true,\n                                                     new Object[] {\n                                                         panel.getOKButton(), DialogDescriptor.CANCEL_OPTION\n                                                     }, DialogDescriptor.OK_OPTION, 0, /*HELP_CTX*/null, null);\n        Object res = DialogDisplayer.getDefault().notify(desc);\n\n        return !res.equals(panel.getOKButton()) ? null :\n                new Result(panel.getSnapshot(), panel.computeRetained());\n    }\n\n    private static JFileChooser getSnapshotFileChooser() {\n        if (snapshotFileChooser == null) {\n            snapshotFileChooser = new JFileChooser();\n            snapshotFileChooser.setAcceptAllFileFilterUsed(false);\n            snapshotFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);\n            snapshotFileChooser.setMultiSelectionEnabled(false);\n            snapshotFileChooser.setDialogType(JFileChooser.OPEN_DIALOG);\n            snapshotFileChooser.setDialogTitle(Bundle.CompareSnapshotsHelper_OpenChooserCaption());\n            snapshotFileChooser.setFileFilter(new FileFilter() {\n                    public boolean accept(File f) {\n                        return f.isDirectory() || checkHprofFile(f);\n                    }\n\n                    public String getDescription() {\n                        return Bundle.CompareSnapshotsHelper_OpenChooserFilter();\n                    }\n                });\n        }\n\n        return snapshotFileChooser;\n    }\n    \n    private SelectSecondSnapshotPanel getSecondSnapshotSelector() {\n        if (secondSnapshotSelector == null) {\n            secondSnapshotSelector = new SelectSecondSnapshotPanel();\n        }\n\n        return secondSnapshotSelector;\n    }\n    \n    \n    // --- ResultsManager utils ------------------------------------------------\n    \n    private static final String HPROF_HEADER = \"JAVA PROFILE 1.0\"; // NOI18H\n    private static final long MIN_HPROF_SIZE = 1024*1024L;\n    static boolean checkHprofFile(File file) {\n        if (file.isFile() && file.canRead() && file.length()>MIN_HPROF_SIZE) { // heap dump must be 1M and bigger\n            byte[] prefix = new byte[HPROF_HEADER.length()+4];\n            try (RandomAccessFile raf = new RandomAccessFile(file,\"r\")) {       // NOI18N\n                raf.readFully(prefix);\n                if (new String(prefix).startsWith(HPROF_HEADER)) {\n                    return true;\n                }\n            } catch (IOException ex) {\n                return false;\n            }\n        }\n        return false;\n    }\n    \n    static FileObject[] listSavedHeapdumps(File directory) {\n        try {\n            FileObject snapshotsFolder = null;\n                    \n            if (directory != null) {\n                snapshotsFolder = FileUtil.toFileObject(directory);\n            } else {\n                snapshotsFolder = ProfilerStorage.getGlobalFolder(false);\n            }\n\n            if (snapshotsFolder == null) {\n                return new FileObject[0];\n            }\n\n            snapshotsFolder.refresh();\n\n            FileObject[] children = snapshotsFolder.getChildren();\n\n            ArrayList<FileObject> files = new ArrayList<>();\n\n            for (FileObject child : children) {\n                if (checkHprofFile(FileUtil.toFile(child))) {\n                    files.add(child);\n                }\n            }\n\n            files.sort((FileObject o1, FileObject o2) -> o1.getName().compareTo(o2.getName()));\n\n            return files.toArray(new FileObject[0]);\n        } catch (IOException e) {\n//            LOGGER.log(Level.SEVERE, Bundle.ResultsManager_ObtainSavedSnapshotsFailedMsg(e.getMessage()), e);\n\n            return new FileObject[0];\n        }\n    }\n    \n    private static final String HEAPDUMP_PREFIX = \"heapdump-\";  // NOI18N // should differ from generated OOME heapdumps not to be detected as OOME\n    private static final long MINIMAL_TIMESTAMP = 946684800000L; // Sat, 01 Jan 2000 00:00:00 GMT in milliseconds since 01 Jan 1970\n    static String getHeapDumpDisplayName(String fileName) {\n        String displayName;\n        if (fileName.startsWith(HEAPDUMP_PREFIX)) {\n            String time = fileName.substring(HEAPDUMP_PREFIX.length());\n            try {\n                long timeStamp = Long.parseLong(time);\n                if (timeStamp > MINIMAL_TIMESTAMP) {\n                    displayName = StringUtils.formatUserDate(new Date(timeStamp));\n                } else {\n                    // file name is probably customized\n                    displayName = fileName;                    \n                }\n            } catch (NumberFormatException e) {\n                // file name is probably customized\n                displayName = fileName;\n            }\n        } else {\n            displayName = fileName;\n        }\n        \n        return displayName;\n//        return Bundle.ResultsManager_HeapSnapshotDisplayName(displayName);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaDiffObjectsView.java",
    "content": "/*\n * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.List;\nimport javax.swing.ButtonGroup;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.HeapViewer;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.ProgressNode;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.PluggableTreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.RelativeRenderer;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n * TODO:\n *  - gray out classes only present in the heap dump being compared (no super/subclasses information available)\n *  - use HeapDump & DataSourceDescriptor to resolve heap dump names\n *  - enable opening the heap dump being compared\n *  - allow to switch compare order heap1 | heap2\n *  - allow opening classes in either or both heap dumps / viewers\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaDiffObjectsView_Name=Comparison\",\n    \"JavaDiffObjectsView_NamePrefix=Comparison with {0}\",\n    \"JavaDiffObjectsView_Details=Details:\",\n    \"JavaDiffObjectsView_LoadingProgress=loading heap dump...\",\n    \"JavaDiffObjectsView_ComparingProgress=comparing heap dumps...\",\n    \"JavaDiffObjectsView_CompareNoJava=No comparable Java heap found\",\n    \"JavaDiffObjectsView_CompareNoJavaStatus=<no comparable heap found>\",\n    \"JavaDiffObjectsView_CompareFailed=Failed to load heap dump\",\n    \"JavaDiffObjectsView_CompareFailedStatus=<failed to load heap dump>\"\n})\nclass JavaDiffObjectsView extends HeapView {\n    \n    private static enum Aggregation {\n        PACKAGES (Bundle.JavaObjectsView_Packages(), Icons.getIcon(LanguageIcons.PACKAGE)),\n        CLASSES (Bundle.JavaObjectsView_Classes(), Icons.getIcon(LanguageIcons.CLASS));\n        \n        private final String aggregationName;\n        private final Icon aggregationIcon;\n        private Aggregation(String aggregationName, Icon aggregationIcon) { this.aggregationName = aggregationName; this.aggregationIcon = aggregationIcon; }\n        public String toString() { return aggregationName; }\n        public Icon getIcon() { return aggregationIcon; }\n    }\n    \n    private final File file2;\n    private final String file2Name;\n    private final String file2Path;\n    \n    private final Object statusLock = new Object();\n    private HeapViewerNode status;\n    private List<ClassNode> diffClasses;\n    \n    private int maxDiffCount = 0;\n    private long maxDiffSize = 0;\n    private long maxDiffRetained = 0;\n    \n    private final PluggableTreeTableView objectsView;\n    private ProfilerToolbar toolbar;\n    private JComponent component;\n    \n    private Aggregation aggregation;\n    \n    private JToggleButton tbPackages;\n    private JToggleButton tbClasses;\n    \n        \n    JavaDiffObjectsView(HeapContext context1, File file2, final boolean compareRetained, HeapViewerActions actions) {\n        super(Bundle.JavaDiffObjectsView_NamePrefix(formattedName(file2)),\n              Bundle.JavaDiffObjectsView_NamePrefix(file2.getAbsolutePath()),\n              Icons.getIcon(ProfilerIcons.SNAPSHOTS_COMPARE));\n        \n        this.file2 = file2;\n        file2Name = formattedName(file2);\n        file2Path = file2.getAbsolutePath();\n        \n        final Heap heap = context1.getFragment().getHeap();\n        \n        final TreeTableViewColumn countC = new TreeTableViewColumn.Count(heap, true, true) {\n            public int getPreferredWidth() { return ((HideableBarRenderer)getRenderer()).getOptimalWidth(); }\n        };\n        final TreeTableViewColumn sizeC = new TreeTableViewColumn.OwnSize(heap, true, false);\n        final TreeTableViewColumn retainedC = compareRetained ? new TreeTableViewColumn.RetainedSize(heap) : null;\n        \n        TreeTableViewColumn[] columns = compareRetained ?\n                new TreeTableViewColumn[] {\n                    new TreeTableViewColumn.Name(),\n//                    new TreeTableViewColumn.LogicalValue(heap),\n                    countC,\n                    sizeC,\n                    retainedC\n                } :\n                new TreeTableViewColumn[] {\n                    new TreeTableViewColumn.Name(),\n//                    new TreeTableViewColumn.LogicalValue(heap),\n                    countC,\n                    sizeC\n                };\n        \n        for (TreeTableViewColumn column : columns) {\n            ProfilerRenderer renderer = column.getRenderer();\n            if (renderer instanceof RelativeRenderer) ((RelativeRenderer)renderer).setDiffMode(true);\n        }\n        \n        status = new ProgressNode(Bundle.JavaDiffObjectsView_LoadingProgress());\n        new RequestProcessor(\"Compare Heap Dumps Worker\").post(new Runnable() { // NOI18N\n            public void run() {\n                computeDiffClasses(heap, compareRetained);\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        ((HideableBarRenderer)countC.getRenderer()).setMaxValue(maxDiffCount);\n                        ((HideableBarRenderer)sizeC.getRenderer()).setMaxValue(maxDiffSize);\n                        if (compareRetained) ((HideableBarRenderer)retainedC.getRenderer()).setMaxValue(maxDiffRetained);\n                        if (objectsView != null) objectsView.getComponent().repaint();\n                    }\n                });\n            }\n        });\n        \n        objectsView = new PluggableTreeTableView(\"diff_java_objects\", context1, actions, columns) { // NOI18N\n            protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                synchronized (statusLock) {\n                    if (diffClasses == null) return new HeapViewerNode[] { status };\n                }\n                \n                switch (getAggregation()) {\n                    case PACKAGES:\n                        return JavaDiffClassesProvider.getDiffHeapPackages(root, heap, diffClasses, compareRetained, viewID, viewFilter, dataTypes, sortOrders, progress);\n                    case CLASSES:\n                        return JavaDiffClassesProvider.getDiffHeapClasses(root, heap, diffClasses, compareRetained, viewID, viewFilter, dataTypes, sortOrders, progress);\n                    default:\n                        return null;\n                }\n            }\n            protected JComponent createComponent() {\n                JComponent comp = super.createComponent();\n\n                setFilterComponent(FilterUtils.createFilterPanel(this));\n\n                return comp;\n            }\n            protected void populatePopupLast(HeapViewerNode node, JPopupMenu popup) {\n                super.populatePopupLast(node, popup);\n                JavaClass javaClass = HeapViewerNode.getValue(node, DataType.CLASS, heap);\n                final String className = javaClass == null || javaClass.isArray() ? null : javaClass.getName();\n                popup.add(new JMenuItem(Bundle.JavaObjectsView_FilterSubclasses()) {\n                    {\n                        setEnabled(className != null);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        JComponent filterComponent = getFilterComponent();\n                        filterComponent.setVisible(true);\n                        FilterUtils.filterSubclasses(className, filterComponent);\n                    }\n                });\n            }\n        };\n        objectsView.setViewName(Bundle.JavaDiffObjectsView_Name());\n    }\n    \n\n    public JComponent getComponent() {\n        if (toolbar == null) initUI();\n        return component;\n    }\n\n    public ProfilerToolbar getToolbar() {\n        if (toolbar == null) initUI();\n        return toolbar;\n    }\n    \n    \n    @Override\n    protected void closed() {\n        objectsView.closed();\n    }\n    \n    \n    private synchronized void setAggregation(Aggregation aggregation) {\n        this.aggregation = aggregation;\n        objectsView.reloadView();\n    }\n    \n    private synchronized Aggregation getAggregation() {\n        return aggregation;\n    }\n    \n    \n    private void initUI() {        \n        toolbar = ProfilerToolbar.create(false);\n        \n        toolbar.addSpace(3);\n        JLabel refPresenter = new JLabel(file2Name, Icons.getIcon(ProfilerIcons.SNAPSHOTS_COMPARE), JLabel.LEADING);\n        refPresenter.setToolTipText(file2Path);\n        toolbar.add(refPresenter);\n        toolbar.addSpace(5);\n\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n        toolbar.add(new GrayLabel(Bundle.JavaObjectsView_Aggregation()));\n        toolbar.addSpace(2);\n        \n        final ButtonGroup aggregationBG = new ButtonGroup();\n        class AggregationButton extends JToggleButton {\n            private final Aggregation aggregation;\n            AggregationButton(Aggregation aggregation) {\n                super(aggregation.getIcon());\n                this.aggregation = aggregation;\n                setToolTipText(aggregation.toString());\n                aggregationBG.add(this);\n            }\n            protected void fireItemStateChanged(ItemEvent e) {\n                if (e.getStateChange() == ItemEvent.SELECTED) setAggregation(aggregation);\n            }\n        }\n        \n        tbPackages = new AggregationButton(Aggregation.PACKAGES);\n        tbPackages.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        tbPackages.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        toolbar.add(tbPackages);\n        \n        tbClasses = new AggregationButton(Aggregation.CLASSES);\n        tbClasses.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        tbClasses.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n        toolbar.add(tbClasses);\n        \n        tbClasses.setSelected(true);\n        aggregation = Aggregation.CLASSES;\n\n\n        \n        if (objectsView.hasPlugins()) {\n            toolbar.addSpace(8);\n\n            toolbar.add(new GrayLabel(Bundle.JavaDiffObjectsView_Details()));\n            toolbar.addSpace(2);\n            \n            toolbar.add(objectsView.getToolbar());\n        }\n        \n        component = new ViewContainer(objectsView.getComponent(), file2);\n    }\n    \n    \n    private void computeDiffClasses(Heap heap, final boolean compareRetained) {\n        try {\n            HeapViewer otherViewer = new HeapViewer(file2);\n            \n            synchronized (statusLock) { status = new ProgressNode(Bundle.JavaDiffObjectsView_ComparingProgress()); }\n            objectsView.reloadView();\n            \n            for (HeapContext otherContext : HeapContext.allContexts(otherViewer)) {\n                if (JavaHeapFragment.isJavaHeap(otherContext)) {\n                    Heap diffHeap = otherContext.getFragment().getHeap();\n                    synchronized (statusLock) {\n                        diffClasses = JavaDiffClassesProvider.createDiffClasses(heap, diffHeap, compareRetained);\n                        \n                        for (ClassNode node : diffClasses) {\n                            int count = Math.abs(node.getInstancesCount());\n                            maxDiffCount = Math.max(maxDiffCount, count);\n                            long size = Math.abs(node.getOwnSize());\n                            maxDiffSize = Math.max(maxDiffSize, size);\n                            if (compareRetained) {\n                                long retained = Math.abs(node.getRetainedSize(heap));\n                                maxDiffRetained = Math.max(maxDiffRetained, retained);\n                            }\n                        }\n                        \n                        status = null;\n                    }\n                    objectsView.reloadView();\n                    return;\n                }\n            }\n            \n            synchronized (statusLock) { status = new TextNode(Bundle.JavaDiffObjectsView_CompareNoJavaStatus()); }\n            objectsView.reloadView();\n            \n            ProfilerDialogs.displayError(Bundle.JavaDiffObjectsView_CompareNoJava());\n        } catch (IOException e) {\n            ProfilerDialogs.displayError(Bundle.JavaDiffObjectsView_CompareFailed());\n            \n            synchronized (statusLock) { status = new TextNode(Bundle.JavaDiffObjectsView_CompareFailedStatus()); }\n            objectsView.reloadView();\n            \n            Exceptions.printStackTrace(e);\n        }\n    }\n    \n    \n    private static String formattedName(File file) {\n        String name = file.getName();\n        int extIdx = name.lastIndexOf('.'); // NOI18N\n        if (extIdx != -1) name = name.substring(0, extIdx);\n        return JavaDiffDumpSelector.getHeapDumpDisplayName(name);\n    }\n    \n    \n    private static class ViewContainer extends JPanel {\n        \n        private final File file;\n        \n        ViewContainer(JComponent view, File file) {\n            super(new BorderLayout());\n            \n            this.file = file;\n            \n            setOpaque(false);\n            setFocusable(false);\n            add(view, BorderLayout.CENTER);\n        }\n        \n        public boolean requestFocusInWindow() {\n            if (getComponentCount() == 0) return super.requestFocusInWindow();\n            else return getComponent(0).requestFocusInWindow();\n        }\n        \n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof ViewContainer)) return false;\n            return file.equals(((ViewContainer)o).file);\n        }\n\n        public int hashCode() {\n            return file.hashCode();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaFieldsPlugin.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.event.ActionEvent;\nimport java.text.Format;\nimport java.text.NumberFormat;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JComponent;\nimport javax.swing.JMenu;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstancesWrapper;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.ErrorNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.ExcludingIterator;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.heapviewer.utils.InterruptibleIterator;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.heapviewer.utils.counters.InstanceCounter;\nimport org.graalvm.visualvm.heapviewer.utils.counters.PrimitiveCounter;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Type;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaFieldsPlugin_Name=Fields\",\n    \"JavaFieldsPlugin_Description=Fields\",\n    \"JavaFieldsPlugin_NoFields=<no fields>\",\n    \"JavaFieldsPlugin_NoFieldsFiltered=<no fields - instance or class fields disabled>\",\n    \"JavaFieldsPlugin_NoSelection=<no class or instance selected>\",\n    \"JavaFieldsPlugin_FieldsContainerMoreNodes=<another {0} fields left>\",\n    \"JavaFieldsPlugin_FieldsContainerSamplesContainer=<sample {0} fields>\",\n    \"JavaFieldsPlugin_FieldsContainerNodesContainer=<fields {0}-{1}>\",\n    \"JavaFieldsPlugin_FieldHistogramMoreNodes=<another {0} values left>\",\n    \"JavaFieldsPlugin_FieldHistogramSamplesContainer=<sample {0} values>\",\n    \"JavaFieldsPlugin_MenuShowInstance=Show (Instance)\",\n    \"JavaFieldsPlugin_MenuShowClass=Show (Class)\",\n    \"JavaFieldsPlugin_MenuFields=Fields\",\n    \"JavaFieldsPlugin_MenuStaticFields=Static Fields\",\n    \"JavaFieldsPlugin_MenuFieldsHisto=Fields Histogram\",\n    \"JavaFieldsPlugin_ValuesCountHint=({0} values)\",\n    \"JavaFieldsPlugin_FieldHistogramNodesContainer=<values {0}-{1}>\"\n})\nclass JavaFieldsPlugin extends HeapViewPlugin {\n    \n    private static final String KEY_INSTANCE_FIELDS = \"iFields\"; // NOI18N\n    private static final String KEY_INSTANCE_STATIC_FIELDS = \"iStaticFields\"; // NOI18N\n    private static final String KEY_CLASS_FIELDS_HISTOGRAM = \"cFieldsHisto\"; // NOI18N\n    private static final String KEY_CLASS_STATIC_FIELDS = \"cStaticFields\"; // NOI18N\n    \n    private volatile boolean iFields = readItem(KEY_INSTANCE_FIELDS, true);\n    private volatile boolean iStaticFields = readItem(KEY_INSTANCE_STATIC_FIELDS, true);\n    private volatile boolean cFieldsHisto = readItem(KEY_CLASS_FIELDS_HISTOGRAM, true);\n    private volatile boolean cStaticFields = readItem(KEY_CLASS_STATIC_FIELDS, true);\n    \n    \n    private static final Format VALUES_COUNT_FORMAT = NumberFormat.getInstance();\n    \n    \n    private static final TreeTableView.ColumnConfiguration CCONF_CLASS = new TreeTableView.ColumnConfiguration(DataType.COUNT, null, DataType.COUNT, SortOrder.DESCENDING, Boolean.FALSE);\n    private static final TreeTableView.ColumnConfiguration CCONF_INSTANCE = new TreeTableView.ColumnConfiguration(null, DataType.COUNT, DataType.NAME, SortOrder.UNSORTED, null);\n    \n    \n    private final Heap heap;\n    private HeapViewerNode selected;\n    \n    private final TreeTableView objectsView;\n    \n\n    JavaFieldsPlugin(HeapContext context, HeapViewerActions actions) {\n        super(Bundle.JavaFieldsPlugin_Name(), Bundle.JavaFieldsPlugin_Description(), Icons.getIcon(ProfilerIcons.NODE_FORWARD));\n        \n        heap = context.getFragment().getHeap();\n        \n        TreeTableViewColumn count;\n        TreeTableViewColumn[] columns = new TreeTableViewColumn[] {\n            new TreeTableViewColumn.Name(),\n            new TreeTableViewColumn.LogicalValue(),\n            count = new TreeTableViewColumn.Count(heap, true, true),\n            new TreeTableViewColumn.OwnSize(heap, false, false),\n            new TreeTableViewColumn.RetainedSize(heap, false, false),\n            new TreeTableViewColumn.ObjectID()\n        };\n        objectsView = new TreeTableView(\"java_objects_fields\", context, actions, columns) { // NOI18N\n            @Override\n            protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                HeapViewerNode _selected;\n                synchronized (objectsView) { _selected = selected; }\n                \n                if (_selected != null) {\n                    boolean filtered = false;\n                    HeapViewerNode[] nodes = null;\n                    \n                    InstancesWrapper wrapper = HeapViewerNode.getValue(_selected, DataType.INSTANCES_WRAPPER, heap);\n                    if (wrapper != null) {\n                        List<HeapViewerNode> fieldNodes = new ArrayList<>();\n                        \n                        if (cFieldsHisto) {\n                            ((HideableBarRenderer)count.getRenderer()).setMaxValue(wrapper.getInstancesCount());\n                            HeapViewerNode[] histo = getClassFieldsHistogram(wrapper, root, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n                            fieldNodes.addAll(Arrays.asList(histo));\n                        } else {\n                            filtered = true;\n                        }\n                        \n                        if (cStaticFields) {\n                            JavaClass jclass = wrapper.getJavaClass();\n                            if (jclass != null) { // Note: GCTypeNode returns null here\n                                List<FieldValue> fields = jclass.getStaticFieldValues();\n                                fieldNodes.addAll(Arrays.asList(JavaFieldsProvider.getNodes(fields, root, heap, viewID, viewFilter, dataTypes, sortOrders, progress)));\n                            }\n                        } else {\n                            filtered = true;\n                        }\n                        \n                        nodes = fieldNodes.toArray(HeapViewerNode.NO_NODES);\n                        \n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                if (!cFieldsHisto && !CCONF_INSTANCE.equals(objectsView.getCurrentColumnConfiguration()))\n                                        objectsView.configureColumns(CCONF_INSTANCE);\n                                else if (cFieldsHisto && !CCONF_CLASS.equals(objectsView.getCurrentColumnConfiguration()))\n                                    objectsView.configureColumns(CCONF_CLASS);\n                            }\n                        });\n                    } else {\n                        Instance instance = HeapViewerNode.getValue(_selected, DataType.INSTANCE, heap);\n                        if (instance != null) {\n                            List<FieldValue> fields = new ArrayList<>();\n\n                            if (iFields) fields.addAll(instance.getFieldValues());\n                            else filtered = true;\n\n                            if (iStaticFields) fields.addAll(instance.getStaticFieldValues());\n                            else filtered = true;\n\n                            nodes = JavaFieldsProvider.getNodes(fields, root, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n                            \n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    if (!CCONF_INSTANCE.equals(objectsView.getCurrentColumnConfiguration()))\n                                        objectsView.configureColumns(CCONF_INSTANCE);\n                                }\n                            });\n                        }\n                    }\n\n                    return nodes == null || nodes.length == 0 ? new HeapViewerNode[] { new TextNode(filtered ? Bundle.JavaFieldsPlugin_NoFieldsFiltered() : Bundle.JavaFieldsPlugin_NoFields()) } : nodes;\n                }\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        if (!CCONF_INSTANCE.equals(objectsView.getCurrentColumnConfiguration()))\n                            objectsView.configureColumns(CCONF_INSTANCE);\n                    }\n                });\n                \n                return new HeapViewerNode[] { new TextNode(Bundle.JavaFieldsPlugin_NoSelection()) };\n            }\n            @Override\n            protected void populatePopup(HeapViewerNode node, JPopupMenu popup) {\n                if (popup.getComponentCount() > 0) popup.addSeparator();\n                \n                JMenu mInstance = new JMenu(Bundle.JavaFieldsPlugin_MenuShowInstance());\n                mInstance.add(new JCheckBoxMenuItem(Bundle.JavaFieldsPlugin_MenuFields(), iFields) {\n                    @Override\n                    protected void fireActionPerformed(ActionEvent event) {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            @Override\n                            public void run() {\n                                iFields = isSelected();\n                                storeItem(KEY_INSTANCE_FIELDS, iFields); // NOI18N\n                                reloadView();\n                            }\n                        });\n                    }\n                });\n                mInstance.add(new JCheckBoxMenuItem(Bundle.JavaFieldsPlugin_MenuStaticFields(), iStaticFields) {\n                    @Override\n                    protected void fireActionPerformed(ActionEvent event) {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            @Override\n                            public void run() {\n                                iStaticFields = isSelected();\n                                storeItem(KEY_INSTANCE_STATIC_FIELDS, iStaticFields);\n                                reloadView();\n                            }\n                        });\n                    }\n                });\n                popup.add(mInstance);\n                \n                JMenu mClass = new JMenu(Bundle.JavaFieldsPlugin_MenuShowClass());\n                mClass.add(new JCheckBoxMenuItem(Bundle.JavaFieldsPlugin_MenuFieldsHisto(), cFieldsHisto) {\n                    @Override\n                    protected void fireActionPerformed(ActionEvent event) {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            @Override\n                            public void run() {\n                                cFieldsHisto = isSelected();\n                                storeItem(KEY_CLASS_FIELDS_HISTOGRAM, cFieldsHisto);\n                                reloadView();\n                            }\n                        });\n                    }\n                });\n                mClass.add(new JCheckBoxMenuItem(Bundle.JavaFieldsPlugin_MenuStaticFields(), cStaticFields) {\n                    @Override\n                    protected void fireActionPerformed(ActionEvent event) {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            @Override\n                            public void run() {\n                                cStaticFields = isSelected();\n                                storeItem(KEY_CLASS_STATIC_FIELDS, cStaticFields);\n                                reloadView();\n                            }\n                        });\n                    }\n                });\n                popup.add(mClass);\n            }\n        };\n    }\n\n    protected JComponent createComponent() {\n        return objectsView.getComponent();\n    }\n    \n    \n    @Override\n    protected void closed() {\n        synchronized (objectsView) { selected = objectsView.getRoot(); }\n        objectsView.closed();\n    }\n    \n    \n    private HeapViewerNode[] getClassFieldsHistogram(final InstancesWrapper instances, HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        final List<Field> fields = getAllInstanceFields(instances.getJavaClass());\n        NodesComputer<Field> computer = new NodesComputer<Field>(fields.size(), UIThresholds.MAX_INSTANCE_FIELDS) {\n            protected boolean sorts(DataType dataType) {\n                return true;\n            }\n            protected HeapViewerNode createNode(Field field) {\n                return new FieldHistogramNode(field) {\n                    @Override\n                    InterruptibleIterator<Instance> instancesIterator() {\n                        return new InterruptibleIterator<>(instances.getInstancesIterator());\n                    }\n                    @Override\n                    int instancesCount() {\n                        return instances.getInstancesCount();\n                    }\n                };\n            }\n            protected ProgressIterator<Field> objectsIterator(int index, Progress progress) {\n                Iterator<Field> iterator = fields.listIterator(index);\n                return new ProgressIterator<>(iterator, index, false, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return Bundle.JavaFieldsPlugin_FieldsContainerMoreNodes(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return Bundle.JavaFieldsPlugin_FieldsContainerSamplesContainer(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return Bundle.JavaFieldsPlugin_FieldsContainerNodesContainer(firstNodeIdx, lastNodeIdx);\n            }\n        };\n        return computer.computeNodes(parent, heap, viewID, null, dataTypes, sortOrders, progress);\n    }\n    \n    \n    static abstract class FieldHistogramNode extends HeapViewerNode {\n        \n        private final String fieldName;\n        private final Type fieldType;\n        private int valuesCount = -1;\n        \n        FieldHistogramNode(Field field) {\n            this.fieldName = field.getName();\n            this.fieldType = field.getType();\n        }\n        \n        String getFieldName() {\n            return fieldName;\n        }\n        \n        Type getFieldType() {\n            return fieldType;\n        }\n        \n        int getValuesCount() {\n            return valuesCount;\n        }\n        \n        \n        private String getName() {\n            if (valuesCount == -1) return fieldName;\n            else return fieldName + \" \" + Bundle.JavaFieldsPlugin_ValuesCountHint(valuesCount); // NOI18N\n        }\n        \n        \n        abstract int instancesCount();\n        \n        abstract InterruptibleIterator<Instance> instancesIterator();\n        \n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            try {\n                int instancesCount = instancesCount();\n                String fieldTypeName = fieldType.getName();\n\n                if (\"object\".equals(fieldTypeName)) { // NOI18N\n                    final InstanceCounter values = new InstanceCounter(instancesCount);\n\n                    try {\n                        progress.setupKnownSteps(instancesCount);\n\n                        Iterator<Instance> instances = instancesIterator();\n                        while (instances.hasNext()) {\n                            Instance instance = instances.next();\n                            progress.step();\n                            FieldValue value = getValueOfField(instance, fieldName);\n                            if (value instanceof ObjectFieldValue)\n                                values.count(((ObjectFieldValue)value).getInstance());\n                        }\n                        if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n                    } finally {\n                        progress.finish();\n                    }\n\n                    valuesCount = values.size();\n\n                    NodesComputer<InstanceCounter.Record> computer = new NodesComputer<InstanceCounter.Record>(valuesCount, UIThresholds.MAX_MERGED_OBJECTS) {\n                        protected boolean sorts(DataType dataType) {\n                            return true;\n                        }\n                        protected HeapViewerNode createNode(InstanceCounter.Record object) {\n                            return new InstanceFieldValueNode(object.getInstance(heap), object.getCount()) {\n                                @Override\n                                String fieldName() { return fieldName; }\n                                @Override\n                                InterruptibleIterator<Instance> instancesIterator() { return FieldHistogramNode.this.instancesIterator(); }\n                            };\n                        }\n                        protected ProgressIterator<InstanceCounter.Record> objectsIterator(int index, Progress progress) {\n                            Iterator<InstanceCounter.Record> iterator = values.iterator();\n                            return new ProgressIterator<>(iterator, index, true, progress);\n                        }\n                        protected String getMoreNodesString(String moreNodesCount)  {\n                            return Bundle.JavaFieldsPlugin_FieldHistogramMoreNodes(moreNodesCount);\n                        }\n                        protected String getSamplesContainerString(String objectsCount)  {\n                            return Bundle.JavaFieldsPlugin_FieldHistogramSamplesContainer(objectsCount);\n                        }\n                        protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                            return Bundle.JavaFieldsPlugin_FieldHistogramNodesContainer(firstNodeIdx, lastNodeIdx);\n                        }\n                    };\n\n                    return computer.computeNodes(FieldHistogramNode.this, heap, viewID, null, dataTypes, sortOrders, progress);\n                } else {\n                    final PrimitiveCounter counter = PrimitiveCounter.create(fieldTypeName, instancesCount);\n\n                    try {\n                        progress.setupKnownSteps(instancesCount);\n\n                        Iterator<Instance> instances = instancesIterator();\n                        while (instances.hasNext()) {\n                            Instance instance = instances.next();\n                            progress.step();\n                            FieldValue value = getValueOfField(instance, fieldName);\n                            if (value != null) counter.count(getValueOfField(instance, fieldName).getValue());\n                        }\n                        if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n                    } finally {\n                        progress.finish();\n                    }\n\n                    valuesCount = counter.size();\n\n                    NodesComputer<PrimitiveCounter.Record> computer = new NodesComputer<PrimitiveCounter.Record>(valuesCount, UIThresholds.MAX_MERGED_OBJECTS) {\n                        protected boolean sorts(DataType dataType) {\n                            return true;\n                        }\n                        protected HeapViewerNode createNode(PrimitiveCounter.Record object) {\n                            return new PrimitiveFieldValueNode(object.getValue(), fieldType.getName(), object.getCount()) {\n                                @Override\n                                String fieldName() { return fieldName; }\n                                @Override\n                                InterruptibleIterator<Instance> instancesIterator() { return FieldHistogramNode.this.instancesIterator(); }\n                            };\n                        }\n                        protected ProgressIterator<PrimitiveCounter.Record> objectsIterator(int index, Progress progress) {\n                            Iterator<? extends PrimitiveCounter.Record> iterator = counter.iterator();\n                            return new ProgressIterator(iterator, index, true, progress);\n                        }\n                        protected String getMoreNodesString(String moreNodesCount)  {\n                            return Bundle.JavaFieldsPlugin_FieldHistogramMoreNodes(moreNodesCount);\n                        }\n                        protected String getSamplesContainerString(String objectsCount)  {\n                            return Bundle.JavaFieldsPlugin_FieldHistogramSamplesContainer(objectsCount);\n                        }\n                        protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                            return Bundle.JavaFieldsPlugin_FieldHistogramNodesContainer(firstNodeIdx, lastNodeIdx);\n                        }\n                    };\n\n                    return computer.computeNodes(FieldHistogramNode.this, heap, viewID, null, dataTypes, sortOrders, progress);\n                }\n            } catch (OutOfMemoryError e) {\n                System.err.println(\"Out of memory in JavaFieldsPlugin: \" + e.getMessage()); // NOI18N\n                HeapUtils.handleOOME(true, e);\n                return new HeapViewerNode[] { new ErrorNode.OOME() };\n            }\n            \n        }\n        \n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.NAME) return getName();\n\n            return super.getValue(type, heap);\n        }\n        \n        \n        public String toString() {\n            return getName();\n        }\n        \n    }\n    \n    \n    static abstract class PrimitiveFieldValueNode extends HeapViewerNode {\n        \n        private final String fieldValue;\n        private final String fieldType;\n        private final int valuesCount;\n        \n        \n        PrimitiveFieldValueNode(String fieldValue, String fieldType, int valuesCount) {\n            this.fieldValue = fieldValue;\n            this.fieldType = fieldType;\n            this.valuesCount = valuesCount;\n        }\n        \n\n        public String getType() {\n            return fieldType;\n        }\n\n        public String getValue() {\n            return fieldValue;\n        }\n        \n        public int getValuesCount() {\n            return valuesCount;\n        }\n        \n        \n        abstract String fieldName();\n        \n        abstract InterruptibleIterator<Instance> instancesIterator();\n        \n        \n        public String getName() {\n             return getType() + \" \" + getValue();\n        }\n        \n        public String toString() {\n            return getName();\n        }\n        \n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.NAME) return getName();\n            if (type == DataType.COUNT) return getValuesCount();\n\n            return super.getValue(type, heap);\n        }\n        \n        \n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            final String fieldName = fieldName();\n\n            NodesComputer<Instance> computer = new NodesComputer<Instance>(valuesCount, UIThresholds.MAX_MERGED_OBJECTS) {\n                protected boolean sorts(DataType dataType) {\n                    return true;\n                }\n                protected HeapViewerNode createNode(Instance object) {\n                    return new InstanceNode(object) {\n                        public boolean isLeaf() {\n                            return true;\n                        }\n                    };\n                }\n                protected ProgressIterator<Instance> objectsIterator(int index, final Progress _progress) {\n                    _progress.setupUnknownSteps();\n                    Iterator<Instance> fieldInstanceIterator = new ExcludingIterator<Instance>(instancesIterator()) {\n                        @Override\n                        protected boolean exclude(Instance instance) {\n                            _progress.step();\n                            FieldValue value = getValueOfField(instance, fieldName);\n                            return value == null || !fieldValue.equals(value.getValue());\n                        }\n                    };\n                    return new ProgressIterator<>(fieldInstanceIterator, index, true, _progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.JavaFieldsPlugin_FieldHistogramMoreNodes(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.JavaFieldsPlugin_FieldHistogramSamplesContainer(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.JavaFieldsPlugin_FieldHistogramNodesContainer(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            \n            return computer.computeNodes(PrimitiveFieldValueNode.this, heap, viewID, null, dataTypes, sortOrders, progress);\n            \n        }\n        \n    }\n    \n    static abstract class InstanceFieldValueNode extends InstanceNode.IncludingNull {\n        \n        private final int valuesCount;\n        \n        \n        InstanceFieldValueNode(Instance instance, int valuesCount) {\n            super(instance);\n            this.valuesCount = valuesCount;\n        }\n        \n        \n        public int getValuesCount() {\n            return valuesCount;\n        }\n        \n        \n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof InstanceFieldValueNode)) return false;\n            return Objects.equals(getInstance(), ((InstanceFieldValueNode)o).getInstance());\n        }\n\n        public int hashCode() {\n            return getInstance() == null ? 37 : super.hashCode();\n        }\n        \n        public boolean isLeaf() {\n            return valuesCount == 0;\n        }\n        \n        abstract String fieldName();\n        \n        abstract InterruptibleIterator<Instance> instancesIterator();\n        \n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.COUNT) return getValuesCount();\n\n            return super.getValue(type, heap);\n        }\n        \n        \n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            final String fieldName = fieldName();\n            \n            NodesComputer<Instance> computer = new NodesComputer<Instance>(valuesCount, UIThresholds.MAX_MERGED_OBJECTS) {\n                protected boolean sorts(DataType dataType) {\n                    return true;\n                }\n                protected HeapViewerNode createNode(Instance object) {\n                    return new InstanceNode(object) {\n                        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                            List<FieldValue> fields = JavaFieldsProvider.InstanceFieldsProvider.getFields(this, heap, true, true);\n                            return JavaFieldsProvider.getNodes(fields, this, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n                        }\n                    };\n                }\n                protected ProgressIterator<Instance> objectsIterator(int index, final Progress _progress) {\n                    final Instance _instance = getInstance();\n                    _progress.setupUnknownSteps();\n                    Iterator<Instance> fieldInstanceIterator = new ExcludingIterator<Instance>(instancesIterator()) {\n                        @Override\n                        protected boolean exclude(Instance instance) {\n                            _progress.step();\n                            FieldValue value = getValueOfField(instance, fieldName);\n                            if (value == null) return _instance != null;\n                            if (!(value instanceof ObjectFieldValue)) return true;\n                            return !Objects.equals(_instance, ((ObjectFieldValue)value).getInstance());\n                        }\n                    };\n                    return new ProgressIterator<>(fieldInstanceIterator, index, true, _progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.JavaFieldsPlugin_FieldHistogramMoreNodes(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.JavaFieldsPlugin_FieldHistogramSamplesContainer(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.JavaFieldsPlugin_FieldHistogramNodesContainer(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            \n            return computer.computeNodes(InstanceFieldValueNode.this, heap, viewID, null, dataTypes, sortOrders, progress);\n            \n        }\n        \n    }\n    \n    \n    // TODO: make JavaClass.getAllInstanceFields() public?\n    private static List<Field> getAllInstanceFields(JavaClass jclass) {\n        List<Field> fields = new ArrayList<>(50);\n\n        for (JavaClass jcls = jclass; jcls != null; jcls = jcls.getSuperClass()) {\n            fields.addAll(jcls.getFields());\n        }\n\n        return fields;\n    }\n    \n    private static FieldValue getValueOfField(Instance instance, String name) {\n        List<FieldValue> fieldValues = instance.getFieldValues();\n        \n        for (int i = fieldValues.size() - 1; i >= 0; i--) {\n            FieldValue fieldValue = fieldValues.get(i);\n            if (fieldValue.getField().getName().equals(name)) {\n                return fieldValue;\n            }\n        }\n        \n        return null; // happens for java.lang.Class instances in GC Roots preset\n    }\n    \n    \n    private static boolean readItem(String itemName, boolean initial) {\n        return NbPreferences.forModule(JavaFieldsPlugin.class).getBoolean(\"JavaFieldsPlugin.\" + itemName, initial); // NOI18N\n    }\n\n    private static void storeItem(String itemName, boolean value) {\n        NbPreferences.forModule(JavaFieldsPlugin.class).putBoolean(\"JavaFieldsPlugin.\" + itemName, value); // NOI18N\n    }\n    \n    \n    private static class FieldHistogramNodeRenderer extends NormalBoldGrayRenderer implements HeapViewerRenderer {\n        \n        public void setValue(Object value, int row) {\n            FieldHistogramNode n = (FieldHistogramNode)value;\n            if (n != null) {\n//                setNormalValue(n.getFieldType().getName() + \" \"); // TODO: remove field type!\n                setBoldValue(n.getFieldName());\n                setGrayValue(n.getValuesCount() == -1 ? \"\" : \" \" + Bundle.JavaFieldsPlugin_ValuesCountHint(VALUES_COUNT_FORMAT.format(n.getValuesCount()))); // NOI18N\n            } else {\n                setBoldValue(\"\"); // NOI18N\n                setGrayValue(\"\"); // NOI18N\n            }\n            setIcon(Icons.getIcon(ProfilerIcons.NODE_FORWARD));\n        }\n\n\n        public String getShortName() {\n            return getBoldValue();\n        }\n        \n    }\n    \n    private static class PrimitiveFieldValueNodeRenderer extends NormalBoldGrayRenderer implements HeapViewerRenderer {\n        \n        public void setValue(Object value, int row) {\n            PrimitiveFieldValueNode n = (PrimitiveFieldValueNode)value;\n            if (n != null) {\n                setNormalValue(n.getType() + \" \"); // NOI18N\n                setBoldValue(n.getValue());\n            } else {\n                setNormalValue(\"\"); // NOI18N\n                setBoldValue(\"\"); // NOI18N\n            }\n            setIcon(Icons.getIcon(LanguageIcons.PRIMITIVE));\n        }\n\n\n        public String getShortName() {\n            return getBoldValue();\n        }\n        \n    }\n    \n    \n    @ServiceProvider(service=HeapViewerRenderer.Provider.class)\n    public static class FieldsHistogramRendererProvider extends HeapViewerRenderer.Provider {\n\n        @Override\n        public boolean supportsView(HeapContext context, String viewID) {\n            return \"java_objects_fields\".equals(viewID); // NOI18N\n        }\n\n        @Override\n        public void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers, HeapContext context) {\n            renderers.put(FieldHistogramNode.class, new FieldHistogramNodeRenderer());\n            renderers.put(PrimitiveFieldValueNode.class, new PrimitiveFieldValueNodeRenderer());\n        }\n        \n    }\n    \n    \n    protected void nodeSelected(HeapViewerNode node, boolean adjusting) {\n        synchronized (objectsView) {\n            if (Objects.equals(selected, node)) return;\n            selected = node;\n        }\n        \n        objectsView.reloadView();\n    }\n    \n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 200)\n    public static class Provider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!viewID.startsWith(\"diff\") && JavaHeapFragment.isJavaHeap(context)) return new JavaFieldsPlugin(context, actions); // NOI18N\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaFieldsProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceReferenceNode;\nimport org.graalvm.visualvm.heapviewer.java.PrimitiveNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaFieldsProvider_MoreNodes=<another {0} fields left>\",\n    \"JavaFieldsProvider_SamplesContainer=<sample {0} fields>\",\n    \"JavaFieldsProvider_NodesContainer=<fields {0}-{1}>\"\n})\npublic abstract class JavaFieldsProvider extends HeapViewerNode.Provider {\n    \n    public HeapViewerNode[] getNodes(HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        List<FieldValue> fields = getFields(parent, heap);\n        return getNodes(fields, parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n    }\n    \n    static HeapViewerNode[] getNodes(final List<FieldValue> fields, final HeapViewerNode parent, final Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        if (fields == null) return null;\n        \n        NodesComputer<Integer> computer = new NodesComputer<Integer>(fields.size(), UIThresholds.MAX_INSTANCE_FIELDS) {\n            protected boolean sorts(DataType dataType) {\n                return !DataType.COUNT.equals(dataType);\n            }\n            protected HeapViewerNode createNode(Integer index) {\n                FieldValue field = fields.get(index);\n                return field instanceof ObjectFieldValue ?\n                        new InstanceReferenceNode.Field((ObjectFieldValue)field, false) :\n                        new PrimitiveNode.Field(field);\n            }\n            protected ProgressIterator<Integer> objectsIterator(int index, Progress progress) {\n                Iterator<Integer> iterator = integerIterator(index, fields.size());\n                return new ProgressIterator<>(iterator, index, false, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return Bundle.JavaFieldsProvider_MoreNodes(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return Bundle.JavaFieldsProvider_SamplesContainer(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return Bundle.JavaFieldsProvider_NodesContainer(firstNodeIdx, lastNodeIdx);\n            }\n        };\n\n        return computer.computeNodes(parent, heap, viewID, null, dataTypes, sortOrders, progress);\n    }\n    \n    \n    protected abstract List<FieldValue> getFields(HeapViewerNode parent, Heap heap);\n    \n    \n    @ServiceProvider(service=HeapViewerNode.Provider.class, position = 200)\n    @NbBundle.Messages({\n        \"InstanceFieldsProvider_Name=fields\"\n    })\n    public static class InstanceFieldsProvider extends JavaFieldsProvider {\n        \n        // TODO: will be configurable, ideally by instance\n        private boolean includeStaticFields = true;\n        private boolean includeInstanceFields = true;\n        \n        public String getName() {\n            return Bundle.InstanceFieldsProvider_Name();\n        }\n\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"java_\"); // NOI18N\n        }\n\n        public boolean supportsNode(HeapViewerNode parent, Heap heap, String viewID) {\n            if (parent instanceof InstanceNode && !InstanceNode.Mode.INCOMING_REFERENCE.equals(((InstanceNode)parent).getMode())) {\n                Instance instance = ((InstanceNode)parent).getInstance();\n                if (instance == null) return false;\n                JavaClass jcls = instance.getJavaClass();\n                if (jcls.isArray()) return false;\n                if (Class.class.getName().equals(jcls.getName())) {\n                    JavaClass jclass = heap.getJavaClassByID(instance.getInstanceId());\n                    return jclass == null;\n                }\n                return true;\n            } else {\n                return false;\n            }\n        }\n\n        \n        protected List<FieldValue> getFields(HeapViewerNode parent, Heap heap) {\n            return getFields(parent, heap, includeInstanceFields, includeStaticFields);\n        }\n        \n        static List<FieldValue> getFields(HeapViewerNode parent, Heap heap, boolean instanceFields, boolean staticFields) {\n            Instance instance = HeapViewerNode.getValue(parent, DataType.INSTANCE, heap);\n            if (instance == null) return null;\n            \n            if (staticFields == instanceFields) {\n                List<FieldValue> fields = new ArrayList<>(instance.getFieldValues());\n                fields.addAll(instance.getStaticFieldValues());\n                return fields;\n            } else if (instanceFields) {\n                return instance.getFieldValues();\n            } else {\n                return instance.getStaticFieldValues();\n            }\n        }\n        \n    }\n    \n    @ServiceProvider(service=HeapViewerNode.Provider.class, position = 250)\n    @NbBundle.Messages({\n        \"ClassFieldsProvider_Name=static fields\"\n    })\n    public static class ClassFieldsProvider extends JavaFieldsProvider {\n        \n        public String getName() {\n            return Bundle.ClassFieldsProvider_Name();\n        }\n\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"java_\"); // NOI18N\n        }\n\n        public boolean supportsNode(HeapViewerNode parent, Heap heap, String viewID) {\n            if (parent instanceof InstanceNode && !InstanceNode.Mode.INCOMING_REFERENCE.equals(((InstanceNode)parent).getMode())) {\n                Instance instance = ((InstanceNode)parent).getInstance();\n                if (instance == null) return false;\n                JavaClass jcls = instance.getJavaClass();\n                if (jcls.isArray()) return false;\n                if (Class.class.getName().equals(jcls.getName())) {\n                    JavaClass jclass = heap.getJavaClassByID(instance.getInstanceId());\n                    return jclass != null;\n                }\n            }\n            return false;\n        }\n        \n        protected List<FieldValue> getFields(HeapViewerNode parent, Heap heap) {\n            Instance instance = HeapViewerNode.getValue(parent, DataType.INSTANCE, heap);\n            if (instance == null) return null;\n            JavaClass jclass = heap.getJavaClassByID(instance.getInstanceId());\n            return jclass == null ? null : jclass.getStaticFieldValues();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaHeapFragmentProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.HeapFragment;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.HeapFactory;\nimport org.openide.util.Lookup;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapFragment.Provider.class, position = 100)\npublic class JavaHeapFragmentProvider extends HeapFragment.Provider {\n    \n    public List<HeapFragment> getFragments(File heapDumpFile, Lookup.Provider heapDumpProject, Heap heap) throws IOException {\n        if (heap.getJavaClassByName(\"java.lang.Object\") == null) return null; // NOI18N\n        \n        List<HeapFragment> fragments = new ArrayList<>();\n        int segments = HeapFactory.getTotalNumberOfSegments(heap);\n        \n        if (segments == 1) {\n            fragments.add(new JavaHeapFragment(heap));\n        } else {\n            fragments.add(new JavaHeapFragment(heap, 0));\n            for (int segment = 1; segment < segments; segment++) {\n                Heap segmentHeap = HeapFactory.createHeap(heapDumpFile, segment);\n                fragments.add(new JavaHeapFragment(segmentHeap, segment));\n            }\n        }\n        \n        return fragments;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaInstancesProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapViewerNode.Provider.class, position = 100)\n@NbBundle.Messages({\n    \"JavaInstancesProvider_Name=instances\",\n    \"JavaInstancesProvider_MoreNodes=<another {0} instances left>\",\n    \"JavaInstancesProvider_SamplesContainer=<sample {0} instances>\",\n    \"JavaInstancesProvider_NodesContainer=<instances {0}-{1}>\",\n    \"JavaInstancesProvider_NoInstances=<no instances>\",\n    \"JavaInstancesProvider_NoInstancesFilter=<no instances matching the filter>\"\n})\npublic class JavaInstancesProvider extends HeapViewerNode.Provider {\n\n    public String getName() {\n        return Bundle.JavaInstancesProvider_Name();\n    }\n    \n    public boolean supportsView(Heap heap, String viewID) {\n        return !viewID.startsWith(\"diff\"); // NOI18N\n    }\n    \n    public boolean supportsNode(HeapViewerNode parent, Heap heap, String viewID) {\n        return parent instanceof ClassNode;\n    }\n\n    public HeapViewerNode[] getNodes(final HeapViewerNode parent, final Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        JavaClass jclass = HeapViewerNode.getValue(parent, DataType.CLASS, heap);\n        if (jclass == null) return null;\n        \n        NodesComputer<Instance> computer = new NodesComputer<Instance>(jclass.getInstancesCount(), UIThresholds.MAX_CLASS_INSTANCES) {\n            protected boolean sorts(DataType dataType) {\n                if (DataType.COUNT.equals(dataType) || (DataType.OWN_SIZE.equals(dataType) && !jclass.isArray())) return false;\n                return true;\n            }\n            protected HeapViewerNode createNode(Instance instance) {\n                return new InstanceNode(instance);\n            }\n            protected ProgressIterator<Instance> objectsIterator(int index, Progress progress) {\n                Iterator<Instance> iterator = jclass.getInstancesIterator();\n                return new ProgressIterator<>(iterator, index, true, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return Bundle.JavaInstancesProvider_MoreNodes(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return Bundle.JavaInstancesProvider_SamplesContainer(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return Bundle.JavaInstancesProvider_NodesContainer(firstNodeIdx, lastNodeIdx);\n            }\n        };\n        \n        return computer.computeNodes(parent, heap, viewID, null, dataTypes, sortOrders, progress);\n    }\n    \n    \n    public static HeapViewerNode[] getHeapInstances(final HeapViewerNode parent, final Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        // TODO: might be faster to process just instances of the classes matching viewFilter, if defined\n        \n        long totalInstancesL = heap.getSummary().getTotalLiveInstances();\n        int totalInstancesI = totalInstancesL < 0 || totalInstancesL > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)totalInstancesL;\n        \n//        int totalInstancesI = Integer.MAX_VALUE;\n//        System.err.println(\">>> Computing \" + heap.getSummary().getTotalLiveInstances() + \" instances\");\n        \n        NodesComputer<Instance> computer = new NodesComputer<Instance>(totalInstancesI, UIThresholds.MAX_TOPLEVEL_INSTANCES) {\n            protected boolean sorts(DataType dataType) {\n                return !DataType.COUNT.equals(dataType);\n            }\n            protected HeapViewerNode createNode(Instance instance) {\n                return new InstanceNode(instance);\n            }\n            protected ProgressIterator<Instance> objectsIterator(int index, Progress progress) {\n                Iterator<Instance> iterator = heap.getAllInstancesIterator();\n                return new ProgressIterator<>(iterator, index, true, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return Bundle.JavaInstancesProvider_MoreNodes(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return Bundle.JavaInstancesProvider_SamplesContainer(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return Bundle.JavaInstancesProvider_NodesContainer(firstNodeIdx, lastNodeIdx);\n            }\n        };\n        \n        HeapViewerNode[] nodes = computer.computeNodes(parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n        return nodes.length == 0 ? new HeapViewerNode[] { new TextNode(getNoInstancesString(viewFilter)) } : nodes;\n    }\n    \n    private static String getNoInstancesString(HeapViewerNodeFilter viewFilter) {\n        return viewFilter == null ? Bundle.JavaInstancesProvider_NoInstances() :\n                                    Bundle.JavaInstancesProvider_NoInstancesFilter();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaNodesRendererProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.util.Map;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.ClassNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.ClassesContainer;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.InstanceReferenceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceReferenceNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.InstancesContainer;\nimport org.graalvm.visualvm.heapviewer.java.LocalObjectNode;\nimport org.graalvm.visualvm.heapviewer.java.LocalObjectNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.PackageNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.PrimitiveNode;\nimport org.graalvm.visualvm.heapviewer.java.PrimitiveNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.StackFrameNode;\nimport org.graalvm.visualvm.heapviewer.java.StackFrameNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.ThreadNode;\nimport org.graalvm.visualvm.heapviewer.java.ThreadNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.ThreadStateNode;\nimport org.graalvm.visualvm.heapviewer.java.ThreadStateNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapViewerRenderer.Provider.class)\npublic class JavaNodesRendererProvider extends HeapViewerRenderer.Provider {\n    \n    public boolean supportsView(HeapContext context, String viewID) {\n        return true;\n    }\n\n    public void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers, HeapContext context) {\n        Heap heap = context.getFragment().getHeap();\n        \n        // packages\n        PackageNodeRenderer packageRenderer = new PackageNodeRenderer(heap);\n        renderers.put(ClassesContainer.Objects.class, packageRenderer);\n        renderers.put(ClassesContainer.Nodes.class, packageRenderer);\n        renderers.put(ClassesContainer.ContainerNodes.class, packageRenderer);\n        \n        // classes\n        ClassNodeRenderer classRenderer = new ClassNodeRenderer(heap);\n        renderers.put(ClassNode.class, classRenderer);\n        renderers.put(InstancesContainer.Objects.class, classRenderer);\n        renderers.put(InstancesContainer.Nodes.class, classRenderer);\n        \n        // instances\n        renderers.put(InstanceNode.class, new InstanceNodeRenderer(heap));\n        \n        // object fields & items\n        renderers.put(InstanceReferenceNode.class, new InstanceReferenceNodeRenderer(heap));\n        \n        // primitive fields & items\n        renderers.put(PrimitiveNode.class, new PrimitiveNodeRenderer());\n        \n        // threads\n        renderers.put(ThreadNode.class, new ThreadNodeRenderer(heap));\n        \n        // stack frames\n        renderers.put(StackFrameNode.class, new StackFrameNodeRenderer());\n\n        // thread state\n        renderers.put(ThreadStateNode.class, new ThreadStateNodeRenderer());\n        \n        // local variables\n        renderers.put(LocalObjectNode.class, new LocalObjectNodeRenderer(heap));\n        \n        \n        // GC types\n        renderers.put(GCTypeNode.class, new GCTypeNode.Renderer());\n        renderers.put(PathToGCRootPlugin.GCRootNode.class, new PathToGCRootPlugin.GCRootNode.Renderer(heap));\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaObjectView.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.NodeObjectsView;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JavaObjectView extends NodeObjectsView {\n    \n    public JavaObjectView(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n        super(\"java_objects\", node, context, actions); // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaObjectsSummary.java",
    "content": "/*\n * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.FocusAdapter;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.PriorityQueue;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.ClassNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.swing.LinkButton;\nimport org.graalvm.visualvm.heapviewer.swing.Splitter;\nimport org.graalvm.visualvm.heapviewer.ui.HeapView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.SummaryView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.graalvm.visualvm.uisupport.SeparatorLine;\nimport org.graalvm.visualvm.uisupport.VerticalLayout;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaObjectsSummary_Name=Statistics\",\n    \"JavaObjectsSummary_Description=Statistics\",\n    \"JavaObjectsSummary_HeapSection=Heap\",\n    \"JavaObjectsSummary_ClassesInstancesCount=Classes by Number of Instances\",\n    \"JavaObjectsSummary_ClassesInstancesSize=Classes by Size of Instances\",\n    \"JavaObjectsSummary_InstancesSize=Instances by Size\",\n    \"JavaObjectsSummary_DominatorsRetainedSize=Dominators by Retained Size\",\n    \"JavaObjectsSummary_ComputeRetainedSizesLbl=Retained sizes must be computed first:\",\n    \"JavaObjectsSummary_ComputeRetainedSizesBtn=Compute Retained Sizes\",\n    \"JavaObjectsSummary_ComputingRetainedSizes=computing retained sizes...\",\n    \"JavaObjectsSummary_ComputingProgress=computing...\",\n    \"JavaObjectsSummary_ViewAll=view all\",\n    \"JavaObjectsSummary_NameColumn=Name\",\n    \"JavaObjectsSummary_ValueColumn=Value\"\n})\nclass JavaObjectsSummary extends HeapView {\n    \n    private static final int PREVIEW_ITEMS = 5;\n    \n    private final HeapContext context;\n    private final HeapViewerActions actions;\n    private final Collection<HeapViewerNodeAction.Provider> actionProviders;\n    \n    private JComponent component;\n    \n    \n    private JavaObjectsSummary(HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n        super(Bundle.JavaObjectsSummary_Name(), Bundle.JavaObjectsSummary_Description());\n        \n        this.context = context;\n        this.actions = actions;\n        this.actionProviders = actionProviders;\n    }\n    \n\n    @Override\n    public JComponent getComponent() {\n        if (component == null) init();\n        return component;\n    }\n\n    @Override\n    public ProfilerToolbar getToolbar() {\n        return null;\n    }\n    \n    \n    private void init() {\n        final Heap heap = context.getFragment().getHeap();\n        final ClassNodeRenderer classRenderer = new ClassNodeRenderer(heap);\n        final InstanceNodeRenderer instanceRenderer = new InstanceNodeRenderer(heap);\n        \n        TreeTableViewColumn sizeColumn = new TreeTableViewColumn.OwnSize(heap);\n        final HideableBarRenderer sizeRenderer = (HideableBarRenderer)sizeColumn.getRenderer();\n        \n        TreeTableViewColumn classesByCountColumn = new TreeTableViewColumn.Count(heap);\n        final HideableBarRenderer classesByCountRenderer = (HideableBarRenderer)classesByCountColumn.getRenderer();\n        \n        Runnable classesByCountDisplayer = new Runnable() {\n            public void run() {\n                JavaObjectsView objectsView = actions.findFeature(JavaObjectsView.class);\n                if (objectsView != null) {\n                    objectsView.configureClassesByInstancesCount();\n                    actions.selectFeature(objectsView);\n                }\n            }\n        };\n        final ResultsSnippet classesByCount = new ResultsSnippet(Bundle.JavaObjectsSummary_ClassesInstancesCount(), classesByCountDisplayer) {\n            protected void setupTable(ProfilerTable table) {\n                table.setColumnRenderer(0, classRenderer);\n                table.setColumnRenderer(1, classesByCountRenderer);\n                table.setDefaultColumnWidth(1, classesByCountRenderer.getNoBarWidth() + 10);\n            }\n        };\n        \n        Runnable classesBySizeDisplayer = new Runnable() {\n            public void run() {\n                JavaObjectsView objectsView = actions.findFeature(JavaObjectsView.class);\n                if (objectsView != null) {\n                    objectsView.configureClassesByInstancesSize();\n                    actions.selectFeature(objectsView);\n                }\n            }\n        };\n        final ResultsSnippet classesBySize = new ResultsSnippet(Bundle.JavaObjectsSummary_ClassesInstancesSize(), classesBySizeDisplayer) {\n            protected void setupTable(ProfilerTable table) {\n                table.setColumnRenderer(0, classRenderer);\n                table.setColumnRenderer(1, sizeRenderer);\n                table.setDefaultColumnWidth(1, sizeRenderer.getNoBarWidth() + 10);\n            }\n        };\n        \n        Splitter classesRow = new Splitter(Splitter.HORIZONTAL_SPLIT, classesByCount, classesBySize);\n        \n        Runnable instancesBySizeDisplayer = new Runnable() {\n            public void run() {\n                JavaObjectsView objectsView = actions.findFeature(JavaObjectsView.class);\n                if (objectsView != null) {\n                    objectsView.configureInstancesBySize();\n                    actions.selectFeature(objectsView);\n                }\n            }\n        };\n        final ResultsSnippet instancesBySize = new ResultsSnippet(Bundle.JavaObjectsSummary_InstancesSize(), instancesBySizeDisplayer) {\n            protected void setupTable(ProfilerTable table) {\n                table.setColumnRenderer(0, instanceRenderer);\n                table.setColumnRenderer(1, sizeRenderer);\n                table.setDefaultColumnWidth(1, sizeRenderer.getNoBarWidth() + 10);\n            }\n        };\n        \n        final boolean retainedAvailable = DataType.RETAINED_SIZE.valuesAvailable(heap);\n        Runnable dominatorsByRetainedSizeDisplayer = new Runnable() {\n            public void run() {\n                JavaObjectsView objectsView = actions.findFeature(JavaObjectsView.class);\n                if (objectsView != null) {\n                    objectsView.configureDominatorsByRetainedSize();\n                    actions.selectFeature(objectsView);\n                }\n            }\n        };\n        final ResultsSnippet dominatorsByRetainedSize = new ResultsSnippet(Bundle.JavaObjectsSummary_DominatorsRetainedSize(), dominatorsByRetainedSizeDisplayer) {\n            private Runnable retainedSizesUpdater;\n            protected JComponent createComponent() {\n                if (retainedAvailable) {\n                    return super.createComponent();\n                } else {\n                    final JPanel p = new JPanel(new GridBagLayout());\n                    p.setOpaque(false);\n                    \n                    final JLabel l = new JLabel(Bundle.JavaObjectsSummary_ComputeRetainedSizesLbl(), JLabel.LEADING);\n                    GridBagConstraints c = new GridBagConstraints();\n                    c.gridx = 0;\n                    c.gridy = 0;\n                    c.fill = GridBagConstraints.NONE;\n                    c.anchor = GridBagConstraints.NORTHWEST;\n                    c.insets = new Insets(2, 2, 2, 2);\n                    p.add(l, c);\n                    \n                    c = new GridBagConstraints();\n                    c.gridx = 1;\n                    c.gridy = 0;\n                    c.weightx = 1d;\n                    c.fill = GridBagConstraints.HORIZONTAL;\n                    c.anchor = GridBagConstraints.NORTHWEST;\n                    c.insets = new Insets(0, 0, 0, 0);\n                    p.add(UIUtils.createFillerPanel(), c);\n                    \n                    c = new GridBagConstraints();\n                    c.gridx = 0;\n                    c.gridy = 1;\n                    c.fill = GridBagConstraints.NONE;\n                    c.anchor = GridBagConstraints.NORTHWEST;\n                    c.insets = new Insets(2, 2, 2, 2);\n                    \n                    JButton lb = new JButton(Bundle.JavaObjectsSummary_ComputeRetainedSizesBtn()) {\n                        protected void fireActionPerformed(ActionEvent e) {\n                            if (DataType.RETAINED_SIZE.computeValues(heap, null)) {\n                                p.remove(this);\n                                l.setText(Bundle.JavaObjectsSummary_ComputingRetainedSizes());\n                                l.setIcon(Icons.getIcon(HeapWalkerIcons.PROGRESS));\n                                p.invalidate();\n                                p.revalidate();\n                                p.repaint();\n                            }\n                        }\n                    };\n                    \n                    final ResultsSnippet rs = this;\n                    retainedSizesUpdater = new Runnable() {\n                        public void run() {\n                            new RequestProcessor(\"Objects Summary Retained Sizes Worker\").post(new Runnable() { // NOI18N\n                                public void run() {\n                                    computeDominators(heap, rs);\n                                    retainedSizesUpdater = null;\n                                }\n                            });\n                        }\n                    };\n                    DataType.RETAINED_SIZE.notifyWhenAvailable(heap, retainedSizesUpdater);\n                    \n                    p.add(lb, c);\n                    \n                    c = new GridBagConstraints();\n                    c.gridx = 1;\n                    c.gridy = 1;\n                    c.weightx = 1d;\n                    c.fill = GridBagConstraints.HORIZONTAL;\n                    c.anchor = GridBagConstraints.NORTHWEST;\n                    c.insets = new Insets(0, 0, 0, 0);\n                    p.add(UIUtils.createFillerPanel(), c);\n                    \n                    c = new GridBagConstraints();\n                    c.gridx = 0;\n                    c.gridy = 2;\n                    c.weightx = 1d;\n                    c.weighty = 1d;\n                    c.fill = GridBagConstraints.BOTH;\n                    c.anchor = GridBagConstraints.NORTHWEST;\n                    c.insets = new Insets(0, 0, 0, 0);\n                    p.add(UIUtils.createFillerPanel(), c);\n                    \n                    return p;\n                }\n            }\n            protected void setupTable(ProfilerTable table) {\n                table.setColumnRenderer(0, instanceRenderer);\n                \n                TreeTableViewColumn dominatorsByRetainedSizeColumn = new TreeTableViewColumn.RetainedSize(heap);\n                HideableBarRenderer retainedRenderer = (HideableBarRenderer)dominatorsByRetainedSizeColumn.getRenderer();\n                table.setColumnRenderer(1, retainedRenderer);\n                table.setDefaultColumnWidth(1, retainedRenderer.getNoBarWidth() + 10);\n            }\n        };\n        \n        Splitter instancesRow = new Splitter(Splitter.HORIZONTAL_SPLIT, instancesBySize, dominatorsByRetainedSize);\n        \n        \n        component = new JPanel(new VerticalLayout(false, 5)) {\n            public Dimension getMinimumSize() {\n                Dimension dim = super.getMinimumSize();\n                dim.width = 0;\n                return dim;\n            }\n\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.width = 100;\n                return dim;\n            }\n        };\n        component.setOpaque(false);\n        \n        component.add(classesRow);\n        component.add(instancesRow);\n        \n        new RequestProcessor(\"Objects Summary Worker\").post(new Runnable() { // NOI18N\n            public void run() {\n                List<JavaClass> allClasses = new ArrayList<>(heap.getAllClasses());\n                \n                // --- Classes by Instances Count ------------------------------\n                allClasses.sort((JavaClass c1, JavaClass c2) -> Integer.compare(c2.getInstancesCount(), c1.getInstancesCount()));\n                int items = Math.min(PREVIEW_ITEMS, allClasses.size());\n                JavaClass[] classesByCountArr = allClasses.subList(0, items).toArray(new JavaClass[0]);\n                Object[][] classesByCountData = new Object[classesByCountArr.length][2];\n                for (int i = 0; i < classesByCountData.length; i++) {\n                    classesByCountData[i][0] = new ClassNode(classesByCountArr[i]);\n                    classesByCountData[i][1] = classesByCountArr[i].getInstancesCount();\n                }\n                configureSnippet(classesByCount, classesByCountData);\n                \n                \n                // --- Classes by Instances Size -------------------------------\n                allClasses.sort((JavaClass c1, JavaClass c2) -> Long.compare(c2.getAllInstancesSize(), c1.getAllInstancesSize()));\n                JavaClass[] classesBySizeArr = allClasses.subList(0, items).toArray(new JavaClass[0]);\n                Object[][] classesBySizeData = new Object[classesBySizeArr.length][2];\n                for (int i = 0; i < classesBySizeData.length; i++) {\n                    classesBySizeData[i][0] = new ClassNode(classesBySizeArr[i]);\n                    classesBySizeData[i][1] = classesBySizeArr[i].getAllInstancesSize();\n                }\n                configureSnippet(classesBySize, classesBySizeData);\n                \n                \n                // --- Instances by Size ---------------------------------------\n                \n                items = (int)Math.min(PREVIEW_ITEMS, heap.getSummary().getTotalLiveInstances());\n                PriorityQueue<Instance> pqBySize = new PriorityQueue<>(items, (Instance i1, Instance i2) -> Long.compare(i1.getSize(), i2.getSize()));\n                Iterator<Instance> allInstances = heap.getAllInstancesIterator();\n                while (allInstances.hasNext()) {\n                    Instance in = allInstances.next();\n                    if (pqBySize.size() < items || pqBySize.peek().getSize() < in.getSize()) {\n                        if (pqBySize.size() == items) pqBySize.remove();\n                        pqBySize.add(in);\n                    }\n                }\n                Instance[] instancesBySizeArr = new Instance[pqBySize.size()];\n                for (int i = instancesBySizeArr.length - 1; i >= 0; i--)\n                    instancesBySizeArr[i] = pqBySize.poll();\n                Object[][] instancesBySizeData = new Object[instancesBySizeArr.length][2];\n                for (int i = 0; i < instancesBySizeData.length; i++) {\n                    instancesBySizeData[i][0] = new InstanceNode(instancesBySizeArr[i]);\n                    instancesBySizeData[i][1] = instancesBySizeArr[i].getSize();\n                }\n                configureSnippet(instancesBySize, instancesBySizeData);\n                \n                \n                // --- Dominators by Retained Size -----------------------------\n                if (retainedAvailable) computeDominators(heap, dominatorsByRetainedSize);\n            }\n        });\n    }\n    \n    \n    private void computeDominators(Heap heap, ResultsSnippet dominatorsByRetainedSize) {\n        List<Instance> dominators = new ArrayList<>(JavaClassesProvider.getDominatorRoots(heap));\n        dominators.sort((Instance i1, Instance i2) -> Long.compare(i2.getRetainedSize(), i1.getRetainedSize()));\n        int items = Math.min(PREVIEW_ITEMS, dominators.size());\n        Instance[] dominatorsByRetainedSizeArr = dominators.subList(0, items).toArray(new Instance[0]);\n        Object[][] dominatorsByRetainedSizeData = new Object[dominatorsByRetainedSizeArr.length][2];\n        for (int i = 0; i < dominatorsByRetainedSizeData.length; i++) {\n            dominatorsByRetainedSizeData[i][0] = new InstanceNode(dominatorsByRetainedSizeArr[i]);\n            dominatorsByRetainedSizeData[i][1] = dominatorsByRetainedSizeArr[i].getRetainedSize();\n        }\n        configureSnippet(dominatorsByRetainedSize, dominatorsByRetainedSizeData);\n    }\n    \n    \n    private void configureSnippet(final ResultsSnippet snippet, final Object[][] data) {\n        final TableModel model = new DefaultTableModel(data, new Object[] {\n                                            Bundle.JavaObjectsSummary_NameColumn(),\n                                            Bundle.JavaObjectsSummary_ValueColumn() }) {\n            public boolean isCellEditable(int row, int column) { return false; }\n        };\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                snippet.setRealModel(model);\n            }\n        });\n    }\n    \n    \n    private class ResultsSnippet extends JPanel {\n        \n        private final LinkButton link;\n        private ProfilerTable table;\n        private boolean keepSelection;\n        \n        ResultsSnippet(String text, final Runnable allDisplayer) {\n            super(new BorderLayout(0, 6));\n            setOpaque(false);\n            setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 5));\n            \n            JPanel sectionSeparator = new JPanel(new GridBagLayout());\n            sectionSeparator.setOpaque(false);\n            \n            JLabel caption = new JLabel(text);\n            caption.setFont(caption.getFont().deriveFont(Font.BOLD));\n            GridBagConstraints c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 0;\n            c.weighty = 1d;\n            sectionSeparator.add(caption, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = 0;\n            c.insets = new Insets(0, 5, 0, 0);\n            sectionSeparator.add(new JLabel(\"[\"), c); // NOI18N\n            \n            link = new LinkButton(Bundle.JavaObjectsSummary_ViewAll()) {\n                @Override\n                protected void clicked() {\n                    SwingUtilities.invokeLater(allDisplayer);\n                }\n            };\n            link.setEnabled(false);\n            c = new GridBagConstraints();\n            c.gridx = 2;\n            c.gridy = 0;\n            c.insets = new Insets(0, 0, 0, 0);\n            sectionSeparator.add(link, c);\n            \n            c = new GridBagConstraints();\n            c.gridx = 3;\n            c.gridy = 0;\n            c.insets = new Insets(0, 0, 0, 0);\n            sectionSeparator.add(new JLabel(\"]\"), c); // NOI18N\n\n            c = new GridBagConstraints();\n            c.gridx = 4;\n            c.gridy = 0;\n            c.weightx = 1d;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(1, 4, 0, 0);\n            sectionSeparator.add(new SeparatorLine(), c);\n            \n            add(sectionSeparator, BorderLayout.NORTH);\n\n            JComponent comp = createComponent();\n            \n            if (comp instanceof ProfilerTable) table = (ProfilerTable)comp;\n            if (comp != null) add(comp, BorderLayout.CENTER);\n        }\n        \n        public Dimension getMinimumSize() {\n            Dimension dim = super.getMinimumSize();\n            dim.width = 0;\n            return dim;\n        }\n        \n        public Dimension getPreferredSize() {\n            Dimension dim = super.getPreferredSize();\n            dim.width = 100;\n            return dim;\n        }\n        \n        protected JComponent createComponent() {\n            TableModel model = new DefaultTableModel(PREVIEW_ITEMS, 1) {\n                { setValueAt(Bundle.JavaObjectsSummary_ComputingProgress(), 0, 0); }\n                public boolean isCellEditable(int row, int column) { return false; }\n            };\n\n            ProfilerRenderer renderer = new LabelRenderer() {\n                public void setValue(Object o, int i) {\n                    super.setValue(o, i);\n                    setIcon(o == null || o.toString().isEmpty() ? null : Icons.getIcon(HeapWalkerIcons.PROGRESS));\n                }\n            };\n\n            ProfilerTable t = createTable(model);\n            t.setDefaultRenderer(Object.class, renderer);\n            \n            return t;\n        }\n        \n        void setRealModel(TableModel model) {\n            if (table == null) {\n                BorderLayout bl = (BorderLayout)getLayout();\n                Component c = bl.getLayoutComponent(BorderLayout.CENTER);\n                if (c != null) remove(c);\n                \n                table = createTable(model);\n                add(table, BorderLayout.CENTER);\n                \n                getParent().invalidate();\n                getParent().revalidate();\n                getParent().repaint();\n            }\n            \n            table.setModel(model);\n            setupTable(table);\n            enableTableEvents(table);\n            \n            link.setEnabled(true);\n        }\n        \n        protected void setupTable(ProfilerTable table) {}\n        \n        private ProfilerTable createTable(TableModel model) {\n            ProfilerTable t = new SummaryView.SimpleTable(model, 0) {\n                protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                    if (!(value instanceof HeapViewerNode)) return;\n                    \n                    requestFocusInWindow(); // TODO: should be done by ProfilerTable on selectRow(...) in processMouseEvent(...)\n                    \n                    HeapViewerNode node = (HeapViewerNode)value;\n                    HeapViewerNodeAction.Actions nodeActions = HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions);\n                    nodeActions.populatePopup(popup);\n\n                    if (popup.getComponentCount() > 0) popup.addSeparator();\n                    popup.add(createCopyMenuItem());\n                }\n                public void performDefaultAction(ActionEvent e) {\n                    if (!getRowSelectionAllowed()) return;\n                    \n                    int row = getSelectedRow();\n                    if (row == -1) return;\n\n                    Object value = getValueForRow(row);\n                    if (!(value instanceof HeapViewerNode)) return;\n\n                    HeapViewerNodeAction.Actions nodeActions =\n                            HeapViewerNodeAction.Actions.forNode((HeapViewerNode)value, actionProviders, context, actions);\n                    nodeActions.performDefaultAction(e);\n                }\n                protected void popupShowing() {\n                    keepSelection = true;\n                }\n                protected void popupHidden() {\n                    keepSelection = false;\n\n                    new Timer(100, new ActionListener() {\n                        @Override\n                        public void actionPerformed(ActionEvent e) {\n                            if (!isFocusOwner()) clearSelection();\n                        }\n                    }) { { setRepeats(false); } }.start();\n                }\n            };\n            \n            return t;\n        }\n        \n        private void enableTableEvents(ProfilerTable t) {\n            t.setRowSelectionAllowed(true);\n            t.addFocusListener(new FocusAdapter() {\n                public void focusLost(FocusEvent e) {\n                    if (!keepSelection) t.clearSelection();\n                    else keepSelection = false;\n                }\n            });\n            t.providePopupMenu(true);\n            t.setSelectionOnMiddlePress(true);\n            t.addMouseListener(new MouseAdapter() {\n                public void mouseClicked(MouseEvent e) {\n                    if (SwingUtilities.isMiddleMouseButton(e)) {\n                        int row = t.getSelectedRow();\n                        if (row == -1) return;\n\n                        Object value = t.getValueForRow(row);\n                        if (!(value instanceof HeapViewerNode)) return;\n\n                        HeapViewerNode node = (HeapViewerNode)value;\n                        HeapViewerNodeAction.Actions nodeActions = HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions);\n                        ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), \"middle button\", e.getWhen(), e.getModifiers()); // NOI18N\n                        nodeActions.performMiddleButtonAction(ae);\n                    }\n                }\n            });\n        }\n        \n    }\n    \n    \n    @ServiceProvider(service=SummaryView.ContentProvider.class, position = 300)\n    public static class Provider extends SummaryView.ContentProvider {\n\n        @Override\n        public HeapView createSummary(String viewID, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n            if (JavaHeapFragment.isJavaHeap(context)) return new JavaObjectsSummary(context, actions, actionProviders);\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaObjectsView.java",
    "content": "/*\n * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport java.util.List;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ButtonGroup;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.graalvm.visualvm.heapviewer.ui.PluggableTreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.ActionPopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaObjectsView_Name=Objects\",\n    \"JavaObjectsView_Description=Objects\",\n    \"JavaObjectsView_Compare=Compare with another heap dump...\",\n    \"JavaObjectsView_AllObjects=All Objects\",\n    \"JavaObjectsView_Dominators=Dominators\",\n    \"JavaObjectsView_GcRoots=GC Roots\",\n    \"JavaObjectsView_Types=Types\",\n    \"JavaObjectsView_Packages=Packages\",\n    \"JavaObjectsView_Classes=Classes\",\n    \"JavaObjectsView_Instances=Instances\",\n    \"JavaObjectsView_FilterSubclasses=Filter Subclasses\",\n    \"JavaObjectsView_Preset=Preset:\",\n    \"JavaObjectsView_Aggregation=Aggregation:\",\n    \"JavaObjectsView_Details=Details:\"\n})\npublic class JavaObjectsView extends HeapViewerFeature {\n    \n    private static final TreeTableView.ColumnConfiguration CCONF_CLASS = new TreeTableView.ColumnConfiguration(DataType.COUNT, DataType.GCROOTS, DataType.COUNT, SortOrder.DESCENDING, Boolean.FALSE);\n    private static final TreeTableView.ColumnConfiguration CCONF_GCROOT = new TreeTableView.ColumnConfiguration(DataType.GCROOTS, null, DataType.GCROOTS, SortOrder.DESCENDING, Boolean.TRUE);\n    private static final TreeTableView.ColumnConfiguration CCONF_INSTANCE = new TreeTableView.ColumnConfiguration(null, DataType.COUNT, DataType.OWN_SIZE, SortOrder.DESCENDING, null);\n    \n    private static final TreeTableView.ColumnConfiguration CCONF_PRES1 = new TreeTableView.ColumnConfiguration(DataType.COUNT, null, DataType.COUNT, SortOrder.DESCENDING, Boolean.TRUE);\n    private static final TreeTableView.ColumnConfiguration CCONF_PRES2 = new TreeTableView.ColumnConfiguration(DataType.OWN_SIZE, null, DataType.OWN_SIZE, SortOrder.DESCENDING, Boolean.TRUE); // TODO: COUNT should also be visible!\n    private static final TreeTableView.ColumnConfiguration CCONF_PRES3 = new TreeTableView.ColumnConfiguration(DataType.OWN_SIZE, DataType.COUNT, DataType.OWN_SIZE, SortOrder.DESCENDING, Boolean.TRUE);\n    private static final TreeTableView.ColumnConfiguration CCONF_PRES4 = new TreeTableView.ColumnConfiguration(DataType.RETAINED_SIZE, DataType.COUNT, DataType.RETAINED_SIZE, SortOrder.DESCENDING, Boolean.TRUE);\n    \n    private static enum Preset {\n        ALL_OBJECTS (Bundle.JavaObjectsView_AllObjects()),\n        DOMINATORS (Bundle.JavaObjectsView_Dominators()),\n        GC_ROOTS (Bundle.JavaObjectsView_GcRoots());\n        \n        private final String presetName;\n        private Preset(String presetName) { this.presetName = presetName; }\n        public String toString() { return presetName; } \n    }\n    \n    private static enum Aggregation {\n        TYPES (Bundle.JavaObjectsView_Types(), Icons.getIcon(ProfilerIcons.RUN_GC)),\n        PACKAGES (Bundle.JavaObjectsView_Packages(), Icons.getIcon(LanguageIcons.PACKAGE)),\n        CLASSES (Bundle.JavaObjectsView_Classes(), Icons.getIcon(LanguageIcons.CLASS)),\n        INSTANCES (Bundle.JavaObjectsView_Instances(), Icons.getIcon(LanguageIcons.INSTANCE));\n        \n        private final String aggregationName;\n        private final Icon aggregationIcon;\n        private Aggregation(String aggregationName, Icon aggregationIcon) { this.aggregationName = aggregationName; this.aggregationIcon = aggregationIcon; }\n        public String toString() { return aggregationName; }\n        public Icon getIcon() { return aggregationIcon; }\n    }\n    \n    private static final String FEATURE_ID = \"java_objects\"; // NOI18N\n    \n    private final HeapContext context;\n    private final HeapViewerActions actions;\n    \n    private final PluggableTreeTableView objectsView;\n    private ProfilerToolbar toolbar;\n    \n    private Preset preset = Preset.ALL_OBJECTS;\n    private Aggregation aggregation = Aggregation.CLASSES;\n    \n    private ActionPopupButton apbPreset;\n    \n    private JToggleButton tbType;\n    private JToggleButton tbPackages;\n    private JToggleButton tbClasses;\n    private JToggleButton tbInstances;\n    \n    \n    public JavaObjectsView(HeapContext context, HeapViewerActions actions) {\n        super(FEATURE_ID, Bundle.JavaObjectsView_Name(), Bundle.JavaObjectsView_Description(), Icons.getIcon(LanguageIcons.CLASS), 200);\n        \n        this.context = context;\n        this.actions = actions;\n        \n        Heap heap = context.getFragment().getHeap();\n        \n        objectsView = new PluggableTreeTableView(FEATURE_ID, context, actions, TreeTableViewColumn.classes(heap, true)) {\n            protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                switch (getPreset()) {\n                    case ALL_OBJECTS:\n                        switch (getAggregation()) {\n                            case PACKAGES:\n                                return JavaClassesProvider.getHeapPackages(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n                            case CLASSES:\n                                return JavaClassesProvider.getHeapClasses(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n                            default:\n                                return JavaInstancesProvider.getHeapInstances(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n                        }\n                    case DOMINATORS:\n                        switch (getAggregation()) {\n                            case PACKAGES:\n                                return JavaClassesProvider.getHeapDominators(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress, 2);\n                            case CLASSES:\n                                return JavaClassesProvider.getHeapDominators(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress, 1);\n                            default:\n                                return JavaClassesProvider.getHeapDominators(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress, 0);\n                        }\n                    case GC_ROOTS:\n                        switch (getAggregation()) {\n                            case TYPES:\n                                return JavaClassesProvider.getHeapGCRoots(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress, 3);\n                            case PACKAGES:\n                                return JavaClassesProvider.getHeapGCRoots(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress, 2);\n                            case CLASSES:\n                                return JavaClassesProvider.getHeapGCRoots(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress, 1);\n                            default:\n                                return JavaClassesProvider.getHeapGCRoots(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress, 0);\n                        }\n                    default:\n                        return HeapViewerNode.NO_NODES;\n                }\n            }\n            protected JComponent createComponent() {\n                JComponent comp = super.createComponent();\n\n                setFilterComponent(FilterUtils.createFilterPanel(this));\n\n                return comp;\n            }\n            protected void populatePopupLast(HeapViewerNode node, JPopupMenu popup) {\n                super.populatePopupLast(node, popup);\n                JavaClass javaClass = HeapViewerNode.getValue(node, DataType.CLASS, heap);\n                final String className = javaClass == null || javaClass.isArray() ? null : javaClass.getName();\n                popup.add(new JMenuItem(Bundle.JavaObjectsView_FilterSubclasses()) {\n                    {\n                        setEnabled(className != null);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        JComponent filterComponent = getFilterComponent();\n                        filterComponent.setVisible(true);\n                        FilterUtils.filterSubclasses(className, filterComponent);\n                    }\n                });\n            }\n        };\n    }\n    \n\n    public JComponent getComponent() {\n        if (toolbar == null) init();\n        return objectsView.getComponent();\n    }\n\n    public ProfilerToolbar getToolbar() {\n        if (toolbar == null) init();\n        return toolbar;\n    }\n    \n    \n    @Override\n    protected void closed() {\n        objectsView.closed();\n    }\n    \n    \n    private volatile boolean skipReload = false;\n    \n    void configureClassesByInstancesCount() {\n        try {\n            objectsView.configureColumns(CCONF_PRES1);\n            \n            if (apbPreset == null) {\n                preset = Preset.ALL_OBJECTS;\n            } else if (preset != Preset.ALL_OBJECTS) {\n                skipReload = true;\n                setPreset(Preset.ALL_OBJECTS);\n                apbPreset.selectAction(preset.ordinal());\n            }\n\n            if (tbClasses == null) {\n                skipReload = true;\n                setAggregation(Aggregation.CLASSES, null);\n            } else if (!tbClasses.isSelected()) {\n                skipReload = true;\n                tbClasses.setSelected(true);\n            }\n            \n            if (skipReload) objectsView.reloadView();\n        } finally {\n            skipReload = false;\n        }\n    }\n    \n    void configureClassesByInstancesSize() {\n        try {\n            objectsView.configureColumns(CCONF_PRES2);\n            \n            if (apbPreset == null) {\n                preset = Preset.ALL_OBJECTS;\n            } else if (preset != Preset.ALL_OBJECTS) {\n                skipReload = true;\n                setPreset(Preset.ALL_OBJECTS);\n                apbPreset.selectAction(preset.ordinal());\n            }\n\n            if (tbClasses == null) {\n                skipReload = true;\n                setAggregation(Aggregation.CLASSES, null);\n            } else if (!tbClasses.isSelected()) {\n                skipReload = true;\n                tbClasses.setSelected(true);\n            }\n            \n            if (skipReload) objectsView.reloadView();\n        } finally {\n            skipReload = false;\n        }\n    }\n    \n    void configureInstancesBySize() {\n        try {\n            objectsView.configureColumns(CCONF_PRES3);\n            \n            if (apbPreset == null) {\n                preset = Preset.ALL_OBJECTS;\n            } else if (preset != Preset.ALL_OBJECTS) {\n                skipReload = true;\n                setPreset(Preset.ALL_OBJECTS);\n                apbPreset.selectAction(preset.ordinal());\n            }\n\n            if (tbInstances == null) {\n                skipReload = true;\n                setAggregation(Aggregation.INSTANCES, null);\n            } else if (!tbInstances.isSelected()) {\n                objectsView.configureColumns(CCONF_PRES3);\n                skipReload = true;\n                tbInstances.setSelected(true);\n            }\n            \n            if (skipReload) objectsView.reloadView();\n        } finally {\n            skipReload = false;\n        }\n    }\n    \n    void configureDominatorsByRetainedSize() {\n        try {\n            objectsView.configureColumns(CCONF_PRES4);\n            \n            if (apbPreset == null) {\n                preset = Preset.DOMINATORS;\n            } else if (preset != Preset.DOMINATORS) {\n                skipReload = true;\n                setPreset(Preset.DOMINATORS);\n                apbPreset.selectAction(preset.ordinal());\n            }\n\n            if (tbInstances == null) {\n                skipReload = true;\n                setAggregation(Aggregation.INSTANCES, null);\n            } else if (!tbInstances.isSelected()) {\n                skipReload = true;\n                tbInstances.setSelected(true);\n            }\n            \n            if (skipReload) objectsView.reloadView();\n        } finally {\n            skipReload = false;\n        }\n    }\n    \n    \n    private Runnable dominatorsRefresher;\n    \n    private synchronized void setPreset(Preset preset) {\n        if (preset == Preset.DOMINATORS) {\n            final Heap heap = context.getFragment().getHeap();\n            if (!DataType.RETAINED_SIZE.valuesAvailable(heap)) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        dominatorsRefresher = new Runnable() {\n                            public void run() {\n                                if (getPreset() == Preset.DOMINATORS) objectsView.reloadView();\n                                dominatorsRefresher = null;\n                            }\n                        };\n                        DataType.RETAINED_SIZE.notifyWhenAvailable(heap, dominatorsRefresher);\n                        DataType.RETAINED_SIZE.computeValues(heap, null);\n                    }\n                });\n            }\n        }\n        \n        this.preset = preset;\n        objectsView.setViewName(preset.toString());\n        tbType.setVisible(preset == Preset.GC_ROOTS);\n        if (tbType.isSelected() && !tbType.isVisible()) tbClasses.setSelected(true);\n        else if (!skipReload) objectsView.reloadView();\n    }\n    \n    private synchronized Preset getPreset() {\n        return preset;\n    }\n    \n    private synchronized void setAggregation(Aggregation aggregation, TreeTableView.ColumnConfiguration cconfig) {\n        this.aggregation = aggregation;\n        \n        if (cconfig != null && !cconfig.equals(objectsView.getCurrentColumnConfiguration()))\n            objectsView.configureColumns(cconfig);\n        \n        if (!skipReload) objectsView.reloadView();\n    }\n    \n    private synchronized Aggregation getAggregation() {\n        return aggregation;\n    }\n        \n    \n    private void init() {\n        toolbar = ProfilerToolbar.create(false);\n        \n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(2);\n        \n        JButton compareButton = new JButton(Icons.getIcon(ProfilerIcons.SNAPSHOTS_COMPARE)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        final JavaDiffDumpSelector.Result r = JavaDiffDumpSelector.selectSnapshot(context, false);\n                        if (r != null) VisualVM.getInstance().runTask(new Runnable() {\n                            public void run() {\n                                HeapView v = new JavaDiffObjectsView(context, r.getFile(), r.compareRetained(), actions);\n                                actions.addView(v, true);\n                            }\n                        });\n                    }\n                });\n            }\n        };\n        compareButton.setToolTipText(Bundle.JavaObjectsView_Compare());\n        toolbar.add(compareButton);\n        \n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n        \n        toolbar.add(new GrayLabel(Bundle.JavaObjectsView_Preset()));\n        toolbar.addSpace(2);\n        \n        class PresetAction extends AbstractAction {\n            final Preset preset;\n            PresetAction(Preset preset) {\n                this.preset = preset;\n                putValue(NAME, preset.toString());\n            }\n            public void actionPerformed(ActionEvent e) {\n                setPreset(preset);\n            }\n        }\n        Preset[] presetItems = Preset.values();\n        Action[] presetActions = new PresetAction[presetItems.length];\n        for (int i = 0; i < presetItems.length; i++) presetActions[i] = new PresetAction(presetItems[i]);\n        apbPreset = new ActionPopupButton(0, presetActions);\n        apbPreset.selectAction(preset.ordinal());\n        toolbar.add(apbPreset);\n        \n        toolbar.addSpace(8);\n        \n        toolbar.add(new GrayLabel(Bundle.JavaObjectsView_Aggregation()));\n        toolbar.addSpace(2);\n        \n        final ButtonGroup aggregationBG = new ButtonGroup();\n        class AggregationButton extends JToggleButton {\n            private final Aggregation aggregation;\n            AggregationButton(Aggregation aggregation, boolean selected) {\n                super(aggregation.getIcon(), selected);\n                this.aggregation = aggregation;\n                setToolTipText(aggregation.toString());\n                aggregationBG.add(this);\n            }\n            protected void fireItemStateChanged(ItemEvent e) {\n                // invoked also from constructor: super(aggregation.getIcon(), selected)\n                // in this case aggregation is still null, ignore the event...\n                if (e.getStateChange() == ItemEvent.SELECTED && aggregation != null) {\n                    TreeTableView.ColumnConfiguration cconf;\n                    switch (aggregation) {\n                        case INSTANCES:\n                            cconf = CCONF_INSTANCE;\n                            break;\n                        case CLASSES:\n                        case PACKAGES:\n                            cconf = CCONF_CLASS;\n                            break;\n                        case TYPES:\n                            cconf = CCONF_GCROOT;\n                            break;\n                        default:\n                            throw new IllegalArgumentException(aggregation.toString());\n                    }\n                    setAggregation(aggregation, cconf);\n                }\n            }\n        }\n        \n        tbType = new AggregationButton(Aggregation.TYPES, Aggregation.TYPES.equals(aggregation)) {\n            public void setVisible(boolean b) {\n                super.setVisible(b);\n                if (tbPackages != null) tbPackages.putClientProperty(\"JButton.segmentPosition\", // NOI18N\n                                        b ? \"middle\" : \"first\"); // NOI18N\n            }\n        };\n        tbType.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        tbType.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        toolbar.add(tbType);\n        \n        tbPackages = new AggregationButton(Aggregation.PACKAGES, Aggregation.PACKAGES.equals(aggregation));\n        tbPackages.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        tbPackages.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        toolbar.add(tbPackages);\n        \n        tbClasses = new AggregationButton(Aggregation.CLASSES, Aggregation.CLASSES.equals(aggregation));\n        tbClasses.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        tbClasses.putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n        toolbar.add(tbClasses);\n        \n        tbInstances = new AggregationButton(Aggregation.INSTANCES, Aggregation.INSTANCES.equals(aggregation));\n        tbInstances.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        tbInstances.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n        toolbar.add(tbInstances);\n\n        setPreset(preset); // updates tbType visibility and sets objectsView name\n        \n        if (objectsView.hasPlugins()) {\n            toolbar.addSpace(8);\n\n            toolbar.add(new GrayLabel(Bundle.JavaObjectsView_Details()));\n            toolbar.addSpace(2);\n            \n            toolbar.add(objectsView.getToolbar());\n        }\n    }\n    \n    \n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class Provider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (JavaHeapFragment.isJavaHeap(context))\n                return new JavaObjectsView(context, actions);\n\n            return null;\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaOpenNodeAction.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.NodeObjectsView;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapViewerNodeAction.Provider.class)\n@NbBundle.Messages({\n    \"JavaOpenNodeAction_OpenClassTab=Open Class in New Tab\"\n})\npublic class JavaOpenNodeAction extends HeapViewerNodeAction.Provider {\n    \n    public boolean supportsView(HeapContext context, String viewID) {\n        return (viewID.startsWith(\"java_\") || viewID.startsWith(\"diff_java_\")) && JavaHeapFragment.getJavaContext(context) != null; // NOI18N\n    }\n\n    public HeapViewerNodeAction[] getActions(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n        HeapContext javaContext = JavaHeapFragment.getJavaContext(context);\n        \n        List<HeapViewerNodeAction> actionsList = new ArrayList<>(2);\n        \n        HeapViewerNode nodeCopy = node.createCopy();\n        actionsList.add(new OpenNodeAction(nodeCopy, javaContext, actions));\n        \n        Instance instance = HeapViewerNode.getValue(node, DataType.INSTANCE, javaContext.getFragment().getHeap());\n        HeapViewerNode classNode = instance == null ? null : new ClassNode(instance.getJavaClass());\n        if (classNode != null) actionsList.add(new OpenClassAction(classNode, javaContext, actions));\n        \n        return actionsList.toArray(new HeapViewerNodeAction[0]);\n    }\n    \n    \n    private static NodeObjectsView createView(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n        return new JavaObjectView(node, context, actions);\n    }\n    \n    \n    private static class OpenNodeAction extends NodeObjectsView.DefaultOpenAction {\n        \n        private OpenNodeAction(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n            super(node, context, actions);\n        }\n\n        public NodeObjectsView createView(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n            return JavaOpenNodeAction.createView(node, context, actions);\n        }\n        \n    }\n    \n    private static class OpenClassAction extends NodeObjectsView.OpenAction {\n        \n        private OpenClassAction(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n            super(Bundle.JavaOpenNodeAction_OpenClassTab(), 1, node, context, actions);\n        }\n\n        public NodeObjectsView createView(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n            return JavaOpenNodeAction.createView(node, context, actions);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaOverviewSummary.java",
    "content": "/*\n * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport java.awt.event.MouseWheelEvent;\nimport java.awt.event.MouseWheelListener;\nimport java.text.NumberFormat;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.Set;\nimport java.util.SortedSet;\nimport java.util.TreeSet;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.JScrollPane;\nimport javax.swing.JViewport;\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.TableModel;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.Caret;\nimport javax.swing.text.JTextComponent;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.swing.LinkButton;\nimport org.graalvm.visualvm.heapviewer.swing.Splitter;\nimport org.graalvm.visualvm.heapviewer.ui.HeapView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.SummaryView;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.HeapSummary;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextAreaSearchUtils;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.uisupport.SeparatorLine;\nimport org.graalvm.visualvm.uisupport.VerticalLayout;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaOverviewSummary_Name=Overview\",\n    \"JavaOverviewSummary_Description=Overview\",\n    \"JavaOverviewSummary_HeapSection=Heap\",\n    \"JavaOverviewSummary_EnvironmentSection=Environment\",\n    \"JavaOverviewSummary_NotAvailableMsg=&lt;not available&gt;\",\n    \"JavaOverviewSummary_SystemPropertiesString=System Properties:\",\n    \"JavaOverviewSummary_SummaryString=Basic Info:\",\n    \"JavaOverviewSummary_EnvironmentString=Environment:\",\n    \"JavaOverviewSummary_SizeItemString=Size:\",\n    \"JavaOverviewSummary_ClassesItemString=Classes:\",\n    \"JavaOverviewSummary_InstancesItemString=Instances:\",\n    \"JavaOverviewSummary_ClassloadersItemString=Classloaders:\",\n    \"JavaOverviewSummary_GcRootsItemString=GC Roots:\",\n    \"JavaOverviewSummary_FinalizersItemString=Objects Pending for Finalization:\",\n    \"JavaOverviewSummary_OsItemString=System\",\n    \"JavaOverviewSummary_ArchitectureItemString=Architecture:\",\n    \"JavaOverviewSummary_JavaHomeItemString=Java Home:\",\n    \"JavaOverviewSummary_JavaVersionItemString=Java Version:\",\n    \"JavaOverviewSummary_JvmItemString=Java Name:\",\n    \"JavaOverviewSummary_JavaVendorItemString=Java Vendor:\",\n    \"JavaOverviewSummary_VmArgsSection=JVM Arguments\",\n    \"JavaOverviewSummary_ModulesSection=Enabled Modules\",\n    \"JavaOverviewSummary_SysPropsSection=System Properties\",\n    \"JavaOverviewSummary_LinkShow=show\",\n    \"JavaOverviewSummary_LinkHide=hide\",\n    \"JavaOverviewSummary_UptimeItemString=JVM Uptime:\",\n    \"JavaOverviewSummary_FORMAT_hms={0} hrs {1} min {2} sec\",\n    \"JavaOverviewSummary_FORMAT_ms={0} min {1} sec\",\n    \"JavaOverviewSummary_NotAvailable=n/a\",\n    \"JavaOverviewSummary_NameColumn=Name\",\n    \"JavaOverviewSummary_ValueColumn=Value\",\n    \"JavaOverviewSummary_NoJvmArguments=<no JVM arguments>\"\n})\nclass JavaOverviewSummary extends HeapView {\n    \n    private final Object[][] heapData;\n    private final Object[][] environmentData;\n    \n    private final String vmArgsData;\n    private final String modulesData;\n    private final String syspropsData;\n    \n    private JComponent component;\n    \n    \n    private JavaOverviewSummary(HeapContext context) {\n        super(Bundle.JavaOverviewSummary_Name(), Bundle.JavaOverviewSummary_Description());\n        \n        Heap heap = context.getFragment().getHeap();        \n        Properties sysprops = heap.getSystemProperties();\n        \n        heapData = computeHeapData(heap);\n        environmentData = computeEnvironmentData(heap, sysprops);\n        vmArgsData = computeVMArgs(heap);\n        modulesData = computeModules(heap);\n        syspropsData = computeSyspropsData(sysprops);\n    }\n    \n\n    @Override\n    public JComponent getComponent() {\n        if (component == null) init();\n        return component;\n    }\n\n    @Override\n    public ProfilerToolbar getToolbar() {\n        return null;\n    }\n    \n    \n    private void init() {\n        ResultsSnippet heapSnippet = new ResultsSnippet(Bundle.JavaOverviewSummary_HeapSection(), heapData, 0);\n        ResultsSnippet environmentSnippet = new ResultsSnippet(Bundle.JavaOverviewSummary_EnvironmentSection(), environmentData, 1);\n        Splitter overviewRow = new Splitter(Splitter.HORIZONTAL_SPLIT, heapSnippet, environmentSnippet);\n        \n        Snippet modulesSnippet = modulesData == null ? null : new Snippet(Bundle.JavaOverviewSummary_ModulesSection(), modulesData);\n        Snippet vmArgsSnippet = vmArgsData == null ? null : new Snippet(Bundle.JavaOverviewSummary_VmArgsSection(), vmArgsData);\n        Snippet syspropsSnippet = new Snippet(Bundle.JavaOverviewSummary_SysPropsSection(), syspropsData);\n        syspropsSnippet.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));\n        \n        component = new JPanel(new VerticalLayout(false)) {\n            public Dimension getMinimumSize() {\n                Dimension dim = super.getMinimumSize();\n                dim.width = 0;\n                return dim;\n            }\n\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.width = 100;\n                return dim;\n            }\n        };\n        component.setOpaque(false);\n        \n        component.add(overviewRow);\n        if (vmArgsSnippet != null) component.add(vmArgsSnippet);\n        if (modulesSnippet != null) component.add(modulesSnippet);\n        component.add(syspropsSnippet);\n    }\n    \n    \n    private static Object[][] computeHeapData(Heap heap) {\n        NumberFormat numberFormat = (NumberFormat)NumberFormat.getInstance().clone();\n        numberFormat.setMaximumFractionDigits(1);\n        \n        HeapSummary hsummary = heap.getSummary();\n        \n        int nclassloaders;\n        JavaClass cl = heap.getJavaClassByName(\"java.lang.ClassLoader\"); // NOI18N\n        if (cl != null) {\n            nclassloaders = cl.getInstancesCount();\n            Collection<JavaClass> jcs = cl.getSubClasses();\n            for (JavaClass jc : jcs) nclassloaders += jc.getInstancesCount();\n        } else {\n            nclassloaders = -1;\n        }\n        \n        int gcroots = heap.getGCRoots().size();\n        if (gcroots < 1) gcroots = -1;\n        \n        return new Object[][] { { Bundle.JavaOverviewSummary_SizeItemString(), format(hsummary.getTotalLiveBytes(), numberFormat, \" B\") },\n                                { Bundle.JavaOverviewSummary_ClassesItemString(), format(heap.getAllClasses().size(), numberFormat, null) },\n                                { Bundle.JavaOverviewSummary_InstancesItemString(), format(hsummary.getTotalLiveInstances(), numberFormat, null) },\n                                { Bundle.JavaOverviewSummary_ClassloadersItemString(), format(nclassloaders, numberFormat, null) },\n                                { Bundle.JavaOverviewSummary_GcRootsItemString(), format(gcroots, numberFormat, null) },\n                                { Bundle.JavaOverviewSummary_FinalizersItemString(), format(computeFinalizers(heap), numberFormat, null) }};\n    }\n    \n    private static Object[][] computeEnvironmentData(Heap heap, Properties sysprops) {\n        HeapSummary hsummary = heap.getSummary();\n        \n        long startupTime = computeStartupTime(heap);\n        String uptime = startupTime == -1 ? format(startupTime, null, null) :\n                                            getTime(hsummary.getTime() - startupTime);\n        \n        if (sysprops == null) {\n            return new Object[][] { { Bundle.JavaOverviewSummary_OsItemString(), Bundle.JavaOverviewSummary_NotAvailable() },\n                                    { Bundle.JavaOverviewSummary_ArchitectureItemString(), Bundle.JavaOverviewSummary_NotAvailable() },\n                                    { Bundle.JavaOverviewSummary_JavaHomeItemString(), Bundle.JavaOverviewSummary_NotAvailable() },\n                                    { Bundle.JavaOverviewSummary_JavaVersionItemString(), Bundle.JavaOverviewSummary_NotAvailable() },\n                                    { Bundle.JavaOverviewSummary_JvmItemString(), Bundle.JavaOverviewSummary_NotAvailable() },\n                                    { Bundle.JavaOverviewSummary_JavaVendorItemString(), Bundle.JavaOverviewSummary_NotAvailable() },\n                                    { Bundle.JavaOverviewSummary_UptimeItemString(), uptime }};\n        } else {\n            String os = sysprops.getProperty(\"os.name\", Bundle.JavaOverviewSummary_NotAvailable()); // NOI18N\n            String os_ver = sysprops.getProperty(\"os.version\", \"\"); // NOI18N\n            if (!os_ver.isEmpty()) os += \" (\" + os_ver + \")\"; // NOI18N\n            String os_patch = sysprops.getProperty(\"sun.os.patch.level\", \"\"); // NOI18N\n            if (!os_patch.isEmpty() && !\"unknown\".equals(os_patch)) os += \" \" + os_patch; // NOI18N\n\n            String arch = sysprops.getProperty(\"os.arch\", Bundle.JavaOverviewSummary_NotAvailable()); // NOI18N\n            arch += \" \" + sysprops.getProperty(\"sun.arch.data.model\", \"?\") + \"bit\"; // NOI18N\n\n            String home = sysprops.getProperty(\"java.home\", Bundle.JavaOverviewSummary_NotAvailable()); // NOI18N\n\n            String name_ver = sysprops.getProperty(\"java.vm.version\", \"\"); // NOI18N\n            String version = sysprops.getProperty(\"java.version\", Bundle.JavaOverviewSummary_NotAvailable()); // NOI18N\n            if (\"0\".equals(version)) version = Bundle.JavaOverviewSummary_NotAvailable(); // NOI18N\n            else {\n                String relDate = sysprops.getProperty(\"java.version.date\", \"\");         // NOI18N\n                if (!relDate.isEmpty()) version += \" \" + relDate;\n                if (name_ver.contains(\"LTS\")) version += \" LTS\";           // NOI18N\n            }\n\n            String name = sysprops.getProperty(\"java.vm.name\", Bundle.JavaOverviewSummary_NotAvailable()); // NOI18N\n            String name_info = sysprops.getProperty(\"java.vm.info\", \"\"); // NOI18N\n            if (name_ver.isEmpty() || name_info.isEmpty()) {\n                if (name_ver.isEmpty()) name += \" (\" + name_info + \")\"; // NOI18N\n                else name += \" (\" + name_ver + \")\"; // NOI18N\n            } else {\n                name += \" (\" + name_ver + \", \" + name_info + \")\"; // NOI18N\n            }\n\n            String vendor = sysprops.getProperty(\"java.vendor\", Bundle.JavaOverviewSummary_NotAvailable()); // NOI18N\n\n            return new Object[][] { { Bundle.JavaOverviewSummary_OsItemString(), os },\n                                    { Bundle.JavaOverviewSummary_ArchitectureItemString(), arch },\n                                    { Bundle.JavaOverviewSummary_JavaHomeItemString(), home },\n                                    { Bundle.JavaOverviewSummary_JavaVersionItemString(), version },\n                                    { Bundle.JavaOverviewSummary_JvmItemString(), name },\n                                    { Bundle.JavaOverviewSummary_JavaVendorItemString(), vendor },\n                                    { Bundle.JavaOverviewSummary_UptimeItemString(), uptime }};\n        }\n        \n    }\n    \n    private static String computeSyspropsData(Properties sysprops) {\n        if (sysprops == null) return null;\n//        if (sysprops == null) return new Object[][] { { \"System properties not available\", \"\" }};\n        \n        Set<Map.Entry<Object, Object>> entries = new TreeSet<>(new Comparator<Map.Entry<Object, Object>>() {\n            @Override\n            public int compare(Map.Entry<Object, Object> e1, Map.Entry<Object, Object> e2) {\n                return e1.getKey().toString().compareTo(e2.getKey().toString());\n            }\n        });\n        entries.addAll(sysprops.entrySet());\n        \n        boolean oddRow = false;\n        Color oddRowBackground = UIUtils.getDarker(\n                                 UIUtils.getProfilerResultsBackground());\n        String oddRowBackgroundString =\n               \"rgb(\" + oddRowBackground.getRed() + \",\" + //NOI18N\n                        oddRowBackground.getGreen() + \",\" + //NOI18N\n                        oddRowBackground.getBlue() + \")\"; //NOI18N\n        \n        StringBuilder sb = new StringBuilder(\"<table border='0' cellpadding='2' cellspacing='0' width='100%'>\"); // NOI18N\n        \n        for (Map.Entry<Object, Object> entry : entries) {\n            sb.append(oddRow ?\n                \"<tr><td style='background-color: \" + // NOI18N\n                oddRowBackgroundString + \";'>\" : \"<tr><td>\"); // NOI18N\n            oddRow = !oddRow;\n            \n            String key = entry.getKey().toString();\n            String val = entry.getValue() == null ? null : entry.getValue().toString();\n            \n            if (val != null) {\n                if (\"line.separator\".equals(key)) {  // NOI18N\n                    val = val.replace(\"\\n\", \"\\\\n\"); // NOI18N\n                    val = val.replace(\"\\r\", \"\\\\r\"); // NOI18N\n                }\n                \n                sb.append(\"<b>\"); // NOI18N\n                sb.append(key);\n                sb.append(\"</b>=\");   // NOI18N\n                sb.append(val);\n            } else {\n                sb.append(\"<b>\"); // NOI18N\n                sb.append(key);\n                sb.append(\"</b>\");   // NOI18N\n            }\n            \n            sb.append(\"</td></tr>\"); // NOI18N\n        }\n        \n        sb.append(\"</table>\"); // NOI18N\n        \n        return expandInvalidXMLChars(sb);\n    }\n    \n    \n    private static long computeFinalizers(Heap heap) {\n        JavaClass finalizerClass = heap.getJavaClassByName(\"java.lang.ref.Finalizer\"); // NOI18N\n        if (finalizerClass != null) {\n            Instance queue = (Instance)finalizerClass.getValueOfStaticField(\"queue\"); // NOI18N\n            if (queue != null) {\n                Long len = (Long)queue.getValueOfField(\"queueLength\"); // NOI18N\n                if (len != null) return len.longValue();\n            }\n        }\n        return -1;\n    }\n    \n    private static long computeStartupTime(Heap heap) {\n        JavaClass jmxFactoryClass = heap.getJavaClassByName(\"sun.management.ManagementFactoryHelper\"); // NOI18N\n        if (jmxFactoryClass == null) {\n            jmxFactoryClass = heap.getJavaClassByName(\"sun.management.ManagementFactory\"); // NOI18N\n        }\n        if (jmxFactoryClass != null) {\n            Instance runtimeImpl = (Instance)jmxFactoryClass.getValueOfStaticField(\"runtimeMBean\"); // NOI18N\n            if (runtimeImpl != null) {\n                Long len = (Long)runtimeImpl.getValueOfField(\"vmStartupTime\"); // NOI18N\n                if (len != null) return len.longValue();\n            }\n        }\n        return -1;\n    }\n    \n    private String computeModules(Heap heap) {\n        JavaClass resolvedModulesClass = heap.getJavaClassByName(\"java.lang.module.ResolvedModule\"); // NOI18N\n        if (resolvedModulesClass != null) {\n            SortedSet<String> resolvedModules = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);\n            List<Instance> modules = resolvedModulesClass.getInstances();\n\n            for (Instance module : modules) {\n                resolvedModules.add(DetailsSupport.getDetailsString(module));\n            }\n            if (resolvedModules.isEmpty()) return null;\n            return formatModules(resolvedModules);\n        }\n        return null;\n    }\n\n    private String computeVMArgs(Heap heap) {\n        List<String> vmArgsList = new ArrayList<>();\n        JavaClass vmManagementClass = heap.getJavaClassByName(\"sun.management.VMManagementImpl\"); // NOI18N\n\n        if (vmManagementClass != null) {\n            if (vmManagementClass.getInstancesCount()>0) {\n                Instance vmManagement = vmManagementClass.getInstancesIterator().next();\n                Object vma = vmManagement.getValueOfField(\"vmArgs\"); // NOI18N\n\n                if (vma instanceof Instance) {\n                    Instance vmargs = (Instance) vma;\n                    Object list = vmargs.getValueOfField(\"list\"); // NOI18N\n                    Object arr;\n                    Object size = null;\n\n                    if (list instanceof Instance) {\n                        arr = ((Instance)list).getValueOfField(\"a\"); // NOI18N\n                    } else {\n                        size = vmargs.getValueOfField(\"size\"); // NOI18N\n                        arr = vmargs.getValueOfField(\"elementData\"); // NOI18N\n                    }\n                    if (arr instanceof ObjectArrayInstance) {\n                        ObjectArrayInstance vmArgsArr = (ObjectArrayInstance) arr;\n                        int length = vmArgsArr.getLength();\n                        List<Instance> elements = vmArgsArr.getValues();\n\n                        if (size instanceof Integer) {\n                            length = ((Integer)size).intValue();\n                        }\n                        for (int i = 0; i < length; i++) {\n                            Instance arg = elements.get(i);\n\n                            vmArgsList.add(DetailsSupport.getDetailsString(arg));\n                        }\n                        \n                        return vmArgsList.isEmpty() ? Bundle.JavaOverviewSummary_NoJvmArguments() :\n                                                      formatVMArgs(vmArgsList);\n                    }\n                }\n            }\n        }\n        return null;\n    }\n\n    private String formatModules(Collection<String> data) {\n        boolean oddRow = false;\n        Color oddRowBackground = UIUtils.getDarker(\n                                 UIUtils.getProfilerResultsBackground());\n        String oddRowBackgroundString =\n               \"rgb(\" + oddRowBackground.getRed() + \",\" + //NOI18N\n                        oddRowBackground.getGreen() + \",\" + //NOI18N\n                        oddRowBackground.getBlue() + \")\"; //NOI18N\n        StringBuilder sb = new StringBuilder(\"<table border='0' cellpadding='2' cellspacing='0' width='100%'>\"); // NOI18N\n\n        for (String string : data) {\n            sb.append(oddRow ?\n                \"<tr><td style='background-color: \" + // NOI18N\n                oddRowBackgroundString + \";'>\" : \"<tr><td>\"); // NOI18N\n            oddRow = !oddRow;\n            sb.append(string.replace(\" \", \"&nbsp;\"));   // NOI18N\n            sb.append(\"</td></tr>\"); // NOI18N\n        }\n        sb.append(\"</table>\"); // NOI18N\n        return expandInvalidXMLChars(sb);\n    }\n    \n    private final String formatVMArgs(List<String> data) {\n        boolean oddRow = false;\n        Color oddRowBackground = UIUtils.getDarker(\n                                 UIUtils.getProfilerResultsBackground());\n        String oddRowBackgroundString =\n               \"rgb(\" + oddRowBackground.getRed() + \",\" + //NOI18N\n                        oddRowBackground.getGreen() + \",\" + //NOI18N\n                        oddRowBackground.getBlue() + \")\"; //NOI18N\n        \n        StringBuilder sb = new StringBuilder(\"<table border='0' cellpadding='2' cellspacing='0' width='100%'>\"); // NOI18N\n        \n        for (String string : data) {\n            sb.append(oddRow ?\n                \"<tr><td style='background-color: \" + // NOI18N\n                oddRowBackgroundString + \";'>\" : \"<tr><td>\"); // NOI18N\n            oddRow = !oddRow;\n            \n            String key = string;\n            \n            int equals = key.indexOf('='); // NOI18N\n            if (equals > 0) {\n                key = string.substring(0, equals);\n                String val = string.substring(equals + 1); // ??\n                \n                sb.append(\"<b>\"); // NOI18N\n                sb.append(key);\n                sb.append(\"</b>=\");   // NOI18N\n                sb.append(val);\n            } else {\n                sb.append(\"<b>\"); // NOI18N\n                sb.append(key);\n                sb.append(\"</b>\");   // NOI18N\n            }\n            \n            sb.append(\"</td></tr>\"); // NOI18N\n        }\n        \n        sb.append(\"</table>\"); // NOI18N\n        \n        return expandInvalidXMLChars(sb);\n    }\n    \n    private static String expandInvalidXMLChars(CharSequence chars) {\n        StringBuilder text = new StringBuilder(chars.length());\n        char ch;\n        \n        for (int i = 0; i < chars.length(); i++) {\n            ch = chars.charAt(i);\n            text.append(isValidXMLChar(ch) ? ch :\n                    \"&lt;0x\" + Integer.toHexString(0x10000 | ch).substring(1).toUpperCase() + \"&gt;\"); // NOI18N\n        }\n        \n        return text.toString();\n    }\n    \n    private static boolean isValidXMLChar(char ch) {\n        return (ch == 0x9 || ch == 0xA || ch == 0xD ||\n              ((ch >= 0x20) && (ch <= 0xD7FF)) ||\n              ((ch >= 0xE000) && (ch <= 0xFFFD)) ||\n              ((ch >= 0x10000) && (ch <= 0x10FFFF)));\n    }\n\n    private static String getTime(long millis) {\n        // Hours\n        long hours = millis / 3600000;\n        String sHours = (hours == 0 ? \"\" : \"\" + hours); // NOI18N\n        millis = millis % 3600000;\n\n        // Minutes\n        long minutes = millis / 60000;\n        String sMinutes = (((hours > 0) && (minutes < 10)) ? \"0\" + minutes : \"\" + minutes); // NOI18N\n        millis = millis % 60000;\n\n        // Seconds\n        long seconds = millis / 1000;\n        String sSeconds = ((seconds < 10) ? \"0\" + seconds : \"\" + seconds); // NOI18N\n\n        if (sHours.isEmpty()) {\n            return Bundle.JavaOverviewSummary_FORMAT_ms(sMinutes, sSeconds);\n        } else {\n            return Bundle.JavaOverviewSummary_FORMAT_hms(sHours, sMinutes, sSeconds);\n        }\n    }\n    \n    private static String format(Number number, NumberFormat format, String suffix) {\n        return number.longValue() == -1 ? Bundle.JavaOverviewSummary_NotAvailable() :\n                                          format.format(number) + (suffix == null ? \"\" : suffix); // NOI18N\n    }\n    \n    \n    private static class ResultsSnippet extends JPanel {\n        \n        ResultsSnippet(String text, Object[][] data, int fillerColumn) {\n            super(new BorderLayout(0, 6));\n            \n            setOpaque(false);\n            setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 5));\n            \n            add(new SectionSeparator(text), BorderLayout.NORTH);\n            \n            TableModel model = new DefaultTableModel(data, new Object[] { Bundle.JavaOverviewSummary_NameColumn(),\n                                                                          Bundle.JavaOverviewSummary_ValueColumn() }) {\n                public boolean isCellEditable(int row, int column) { return false; }\n            };\n            SummaryView.SimpleTable table = new SummaryView.SimpleTable(model, fillerColumn);\n            table.setFocusable(false);\n            LabelRenderer r1 = new LabelRenderer();\n            r1.setFont(r1.getFont().deriveFont(Font.BOLD));\n            table.setColumnRenderer(0, r1, fillerColumn != 0);\n            LabelRenderer r2 = new LabelRenderer();\n            r2.setHorizontalAlignment(LabelRenderer.RIGHT);\n            table.setColumnRenderer(1, r2, fillerColumn != 1);\n            add(table, BorderLayout.CENTER);\n        }\n        \n        public Dimension getMinimumSize() {\n            Dimension dim = super.getMinimumSize();\n            dim.width = 0;\n            return dim;\n        }\n        \n        public Dimension getPreferredSize() {\n            Dimension dim = super.getPreferredSize();\n            dim.width = 100;\n            return dim;\n        }\n        \n    }\n\n    private static class Snippet extends JPanel {\n        \n        Snippet(String label, final String data) {\n            super(new GridBagLayout());\n            \n            setOpaque(false);\n            setBorder(BorderFactory.createEmptyBorder(0, 5, 15, 5));\n            \n            JLabel caption = new JLabel(label);\n            caption.setFont(caption.getFont().deriveFont(Font.BOLD));\n            GridBagConstraints c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 0;\n            c.weighty = 1d;\n            add(caption, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = 0;\n            c.insets = new Insets(0, 5, 0, 0);\n            add(new JLabel(\"[\"), c); // NOI18N\n            \n            if (data != null) {\n                HTMLTextArea htmlArea = new HTMLTextArea(data);\n                \n                final JPanel view = new JPanel(new BorderLayout());\n                view.setOpaque(false);\n                view.add(new HorizontalScroller(htmlArea), BorderLayout.CENTER);\n                view.add(HTMLTextAreaSearchUtils.createSearchPanel(htmlArea), BorderLayout.SOUTH);\n\n                LinkButton lb = new LinkButton() {\n                    {\n                        clicked(); // sets link text, hides properties table\n                    }\n                    @Override\n                    protected void clicked() {\n                        if (view.isVisible()) {\n                            setText(Bundle.JavaOverviewSummary_LinkShow());\n                            view.setVisible(false);\n                        } else {\n                            setText(Bundle.JavaOverviewSummary_LinkHide());\n                            view.setVisible(true);\n                        }\n                    }\n                };\n                c = new GridBagConstraints();\n                c.gridx = 2;\n                c.gridy = 0;\n                c.insets = new Insets(0, 0, 0, 0);\n                add(lb, c);\n                \n                c = new GridBagConstraints();\n                c.gridx = 0;\n                c.gridy = 1;\n                c.gridwidth = GridBagConstraints.REMAINDER;\n                c.weightx = 1d;\n                c.weighty = 1d;\n                c.anchor = GridBagConstraints.NORTHWEST;\n                c.fill = GridBagConstraints.BOTH;\n                c.insets = new Insets(6, 0, 0, 0);\n                add(view, c);\n            } else {\n                JLabel nal = new JLabel(Bundle.JavaOverviewSummary_NotAvailable());\n                nal.setBorder(new LinkButton().getBorder());\n                c = new GridBagConstraints();\n                c.gridx = 2;\n                c.insets = new Insets(0, 0, 0, 0);\n                add(nal, c);\n            }\n            \n            c = new GridBagConstraints();\n            c.gridx = 3;\n            c.gridy = 0;\n            c.insets = new Insets(0, 0, 0, 0);\n            add(new JLabel(\"]\"), c); // NOI18N\n\n            c = new GridBagConstraints();\n            c.gridx = 4;\n            c.gridy = 0;\n            c.weightx = 1d;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(1, 4, 0, 0);\n            add(new SeparatorLine(), c);\n        }\n        \n        public Dimension getMinimumSize() {\n            Dimension dim = super.getMinimumSize();\n            dim.width = 0;\n            return dim;\n        }\n        \n        public Dimension getPreferredSize() {\n            Dimension dim = super.getPreferredSize();\n            dim.width = 100;\n            return dim;\n        }\n        \n    }\n    \n    private static class HorizontalScroller extends JScrollPane {\n        \n        HorizontalScroller(JComponent view) {\n            super(view, VERTICAL_SCROLLBAR_NEVER, HORIZONTAL_SCROLLBAR_AS_NEEDED);\n\n            setBorder(BorderFactory.createEmptyBorder());\n            setViewportBorder(BorderFactory.createEmptyBorder());\n\n            getViewport().setOpaque(false);\n            setOpaque(false);\n            \n            super.addMouseWheelListener(new MouseWheelListener() {\n                @Override\n                public void mouseWheelMoved(MouseWheelEvent e) {\n                    if (e.getModifiers() == MouseWheelEvent.SHIFT_MASK) {\n                        scroll(getHorizontalScrollBar(), e);\n                    } else {\n                        getParent().dispatchEvent(e);\n                    }\n                }\n                \n            });\n        }\n        \n        public Dimension getMinimumSize() {\n            return getPreferredSize();\n        }\n        \n        public Dimension getPreferredSize() {\n            Dimension size = getViewport().getView().getPreferredSize();\n            if (getHorizontalScrollBar().isVisible()) size.height += getHorizontalScrollBar().getPreferredSize().height;\n            return size;\n        }\n        \n        public void addMouseWheelListener(MouseWheelListener l) {}\n        \n        private static void scroll(JScrollBar scroller, MouseWheelEvent event) {\n            if (event.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {\n                int unitsToScroll = event.getUnitsToScroll();\n                if (unitsToScroll != 0) {\n                    int direction = unitsToScroll < 0 ? -1 : 1;\n                    int increment = scroller.getUnitIncrement(direction);\n    //                int amount = event.getScrollAmount();\n                    int amount = 1;\n                    int oldValue = scroller.getValue();\n                    int newValue = oldValue + increment * amount * direction;\n                    if (oldValue != newValue) scroller.setValue(newValue);\n                }\n                event.consume();\n            }\n        }\n        \n        protected JViewport createViewport() {\n            return new JViewport() {\n                public void scrollRectToVisible(Rectangle aRect) {\n                    if (getView() instanceof JTextComponent) {\n                        try {\n                            JTextComponent tc = (JTextComponent)getView();\n                            \n                            Caret caret = tc.getCaret();\n                            Rectangle selStart = tc.modelToView(Math.min(caret.getDot(), caret.getMark()));\n                            Rectangle selEnd = tc.modelToView(Math.max(caret.getDot(), caret.getMark()));\n                            \n                            int x = Math.min(selStart.x, selEnd.x);\n                            int xx = Math.max(selStart.x + selStart.width, selEnd.x + selEnd.width);\n                            int y = Math.min(selStart.y, selEnd.y);\n                            int yy = Math.max(selStart.y + selStart.height, selEnd.y + selEnd.height);\n                            Rectangle r = new Rectangle(x, y, xx - x, yy - y);\n                            \n                            super.scrollRectToVisible(SwingUtilities.convertRectangle(tc, r, this));\n                        } catch (BadLocationException ex) {\n                            Exceptions.printStackTrace(ex);\n                        }\n                    } else {\n                        super.scrollRectToVisible(aRect);\n                    }\n                    \n                    aRect = SwingUtilities.convertRectangle(this, aRect, getParent());\n                    ((JComponent)getParent()).scrollRectToVisible(aRect);\n                }\n            };\n        }\n        \n    }\n    \n    \n    @ServiceProvider(service=SummaryView.ContentProvider.class, position = 100)\n    public static class Provider extends SummaryView.ContentProvider {\n\n        @Override\n        public HeapView createSummary(String viewID, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n            if (JavaHeapFragment.isJavaHeap(context)) return new JavaOverviewSummary(context);\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaPreviewPlugin.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaPreviewPlugin_Name=Preview\",\n    \"JavaPreviewPlugin_Description=Preview\",\n    \"JavaPreviewPlugin_NoDetails=<no details>\"\n})\nclass JavaPreviewPlugin extends HeapViewPlugin {\n    \n    private final Heap heap;\n    \n    private InstanceScrollPane component;\n    \n\n    JavaPreviewPlugin(HeapContext context) {\n        super(Bundle.JavaPreviewPlugin_Name(), Bundle.JavaPreviewPlugin_Description(), Icons.getIcon(HeapWalkerIcons.PROPERTIES));\n        heap = context.getFragment().getHeap();\n    }\n\n    \n    @Override\n    protected void closed() {\n        // TODO: should cancel the preview\n    }\n    \n    protected void nodeSelected(HeapViewerNode node, boolean adjusting) {\n        component.showInstance(node == null ? null : HeapViewerNode.getValue(node, DataType.INSTANCE, heap));\n    }\n    \n    \n    protected JComponent createComponent() {\n        if (component == null) component = new InstanceScrollPane();\n        return component;\n    }\n    \n    \n    private static class InstanceScrollPane extends JScrollPane {\n        \n        private Instance selectedInstance = null;\n        private boolean instancePending = false;\n        \n        \n        InstanceScrollPane() {\n            setBorder(BorderFactory.createEmptyBorder());\n            setViewportBorder(BorderFactory.createEmptyBorder());\n//            setViewportBorder(BorderFactory.createLineBorder(\n//                    UIManager.getLookAndFeel().getID().equals(\"Metal\") ? // NOI18N\n//                    UIManager.getColor(\"Button.darkShadow\") : // NOI18N\n//                    UIManager.getColor(\"Button.shadow\"))); // NOI18N\n            \n            addHierarchyListener(new HierarchyListener() {\n                public void hierarchyChanged(HierarchyEvent e) {\n                    if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                        if (instancePending && isShowing()) showInstanceImpl();\n                    }\n                }\n            });\n            \n            showInstanceImpl();\n        }\n        \n        \n        void showInstance(Instance instance) {\n            if (selectedInstance == instance) return;\n            selectedInstance = instance;\n            if (isShowing()) showInstanceImpl();\n            else instancePending = true;\n        }\n        \n        private void showInstanceImpl() {\n            JComponent instanceView = selectedInstance == null ? null :\n                       DetailsSupport.getDetailsView(selectedInstance);\n            if (instanceView == null) {\n                JLabel noDetails = new JLabel(Bundle.JavaPreviewPlugin_NoDetails(), JLabel.CENTER);\n                noDetails.setEnabled(false);\n                \n                instanceView = new JPanel(new BorderLayout());\n                instanceView.setOpaque(true);\n                instanceView.setBackground(UIUtils.getProfilerResultsBackground());\n                instanceView.add(noDetails, BorderLayout.CENTER);\n            }\n            setViewportView(instanceView);\n            //doLayout();\n            instancePending = false;\n        }\n        \n    }\n    \n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 100)\n    public static class Provider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!viewID.startsWith(\"diff\") && JavaHeapFragment.isJavaHeap(context)) return new JavaPreviewPlugin(context); // NOI18N\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaReferencesPlugin.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.InstanceReferenceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstancesWrapper;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.ErrorNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.swing.LinkButton;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.ExcludingIterator;\nimport org.graalvm.visualvm.heapviewer.utils.HeapOperations;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.heapviewer.utils.InterruptibleIterator;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.Value;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaReferencesPlugin_Name=References\",\n    \"JavaReferencesPlugin_Description=References\",\n    \"JavaReferencesPlugin_NoReferences=<no references>\",\n//    \"JavaReferencesPlugin_NoReferencesFiltered=<merged references disabled>\",\n    \"JavaReferencesPlugin_NoSelection=<no class or instance selected>\",\n    \"JavaReferencesPlugin_MoreNodes=<another {0} references left>\",\n    \"JavaReferencesPlugin_SamplesContainer=<sample {0} references>\",\n    \"JavaReferencesPlugin_NodesContainer=<references {0}-{1}>\",\n    \"JavaReferencesPlugin_IMoreNodes=<another {0} instances left>\",\n    \"JavaReferencesPlugin_ISamplesContainer=<sample {0} instances>\",\n    \"JavaReferencesPlugin_INodesContainer=<instances {0}-{1}>\",\n    \"JavaReferencesPlugin_ComputeMergedReferencesLbl=Compute Merged References\",\n    \"JavaReferencesPlugin_ComputeMergedReferencesTtp=Compute merged references for the selected class\",\n    \"JavaReferencesPlugin_AutoComputeMergedReferencesLbl=Compute Merged References Automatically\",\n    \"JavaReferencesPlugin_AutoComputeMergedReferencesTtp=Compute merged references automatically for each selected class\",\n    \"JavaReferencesPlugin_MenuShowLogicalReferences=Show Logical References\"\n})\nclass JavaReferencesPlugin extends HeapViewPlugin {\n    \n    private static final TreeTableView.ColumnConfiguration CCONF_CLASS = new TreeTableView.ColumnConfiguration(DataType.COUNT, null, DataType.COUNT, SortOrder.DESCENDING, Boolean.FALSE);\n    private static final TreeTableView.ColumnConfiguration CCONF_INSTANCE = new TreeTableView.ColumnConfiguration(null, DataType.COUNT, DataType.NAME, SortOrder.UNSORTED, null);\n    \n    private final Heap heap;\n    private HeapViewerNode selected;\n    \n    private volatile boolean mergedRequest;\n    \n    private final TreeTableView objectsView;\n    \n\n    JavaReferencesPlugin(HeapContext context, HeapViewerActions actions, final JavaReferencesProvider provider) {\n        super(Bundle.JavaReferencesPlugin_Name(), Bundle.JavaReferencesPlugin_Description(), Icons.getIcon(ProfilerIcons.NODE_REVERSE));\n        \n        heap = context.getFragment().getHeap();\n        \n        TreeTableViewColumn count;\n        TreeTableViewColumn[] columns = new TreeTableViewColumn[] {\n            new TreeTableViewColumn.Name(),\n            new TreeTableViewColumn.LogicalValue(),\n            count = new TreeTableViewColumn.Count(heap, true, true),\n            new TreeTableViewColumn.OwnSize(heap, false, false),\n            new TreeTableViewColumn.RetainedSize(heap, false, false),\n            new TreeTableViewColumn.ObjectID()\n        };\n        objectsView = new TreeTableView(\"java_objects_references\", context, actions, columns) { // NOI18N\n            protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                if (mergedRequest) return HeapViewerNode.NO_NODES;\n                \n                HeapViewerNode _selected;\n                synchronized (objectsView) { _selected = selected; }\n                \n                if (_selected == null) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            if (!CCONF_INSTANCE.equals(objectsView.getCurrentColumnConfiguration()))\n                                objectsView.configureColumns(CCONF_INSTANCE);\n                        }\n                    });\n                    \n                    return new HeapViewerNode[] { new TextNode(Bundle.JavaReferencesPlugin_NoSelection()) };\n                }\n                \n                InstancesWrapper wrapper = HeapViewerNode.getValue(_selected, DataType.INSTANCES_WRAPPER, heap);\n                if (wrapper != null) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n//                            if (!mergedReferences && !CCONF_INSTANCE.equals(objectsView.getCurrentColumnConfiguration()))\n//                                objectsView.configureColumns(CCONF_INSTANCE);\n//                            else if (mergedReferences && !CCONF_CLASS.equals(objectsView.getCurrentColumnConfiguration()))\n//                                objectsView.configureColumns(CCONF_CLASS);\n                            if (!CCONF_CLASS.equals(objectsView.getCurrentColumnConfiguration()))\n                                objectsView.configureColumns(CCONF_CLASS);\n                        }\n                    });\n\n//                    if (!mergedReferences) return new HeapViewerNode[] { new TextNode(Bundle.JavaReferencesPlugin_NoReferencesFiltered()) };\n                    \n                    ((HideableBarRenderer)count.getRenderer()).setMaxValue(wrapper.getInstancesCount());\n                    return computeInstancesReferences(wrapper, root, heap, viewID, null, dataTypes, sortOrders, progress);\n                } else {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            if (!CCONF_INSTANCE.equals(objectsView.getCurrentColumnConfiguration()))\n                                objectsView.configureColumns(CCONF_INSTANCE);\n                        }\n                    });\n                    \n                    Instance instance = HeapViewerNode.getValue(_selected, DataType.INSTANCE, heap);\n\n                    if (instance != null) {\n                        HeapViewerNode[] nodes = provider.getNodes(instance, root, heap, viewID, null, dataTypes, sortOrders, progress);\n                        return nodes == null || nodes.length == 0 ? new HeapViewerNode[] { new TextNode(Bundle.JavaReferencesPlugin_NoReferences()) } : nodes;\n                    }\n\n                    return new HeapViewerNode[] { new TextNode(Bundle.JavaReferencesPlugin_NoSelection()) };\n                }\n            }\n            \n            @Override\n            protected void populatePopup(HeapViewerNode node, JPopupMenu popup) {\n                if (popup.getComponentCount() > 0) popup.addSeparator();\n                \n                popup.add(new JCheckBoxMenuItem(Bundle.JavaReferencesPlugin_AutoComputeMergedReferencesLbl(), isAutoMerge()) {\n                    @Override\n                    protected void fireActionPerformed(ActionEvent event) {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            @Override\n                            public void run() {\n                                setAutoMerge(isSelected());\n                            }\n                        });\n                    }\n                });\n                \n                if (!CCONF_INSTANCE.equals(objectsView.getCurrentColumnConfiguration())) popup.add(new JCheckBoxMenuItem(Bundle.JavaReferencesPlugin_MenuShowLogicalReferences(), isLogicalReferences()) {\n                    @Override\n                    protected void fireActionPerformed(ActionEvent event) {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            @Override\n                            public void run() {\n                                setLogicalReferences(isSelected());\n                                if (CCONF_CLASS.equals(objectsView.getCurrentColumnConfiguration())) { // only update view for class selection\n                                    reloadView();\n                                }\n                            }\n                        });\n                    }\n                });\n            }\n        };\n    }\n    \n    \n    private JComponent component;\n    \n    private void showObjectsView() {\n        JComponent c = objectsView.getComponent();\n        if (c.isVisible()) return;\n        \n        c.setVisible(true);\n        \n        component.removeAll();\n        component.add(c, BorderLayout.CENTER);\n        \n        mergedRequest = false;\n        \n        component.invalidate();\n        component.revalidate();\n        component.repaint();\n    }\n    \n    private void showMergedView() {\n        JComponent c = objectsView.getComponent();\n        if (!c.isVisible()) return;\n        \n        c.setVisible(false);\n        \n        component.removeAll();\n        \n        JButton jb = new JButton(Bundle.JavaReferencesPlugin_ComputeMergedReferencesLbl(), Icons.getIcon(ProfilerIcons.NODE_REVERSE)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                showObjectsView();\n                objectsView.reloadView();\n            }\n        };\n        jb.setIconTextGap(jb.getIconTextGap() + 2);\n        jb.setToolTipText(Bundle.JavaReferencesPlugin_ComputeMergedReferencesTtp());\n        Insets margin = jb.getMargin();\n        if (margin != null) jb.setMargin(new Insets(margin.top + 3, margin.left + 3, margin.bottom + 3, margin.right + 3));\n        \n        \n        LinkButton lb = new LinkButton(Bundle.JavaReferencesPlugin_AutoComputeMergedReferencesLbl()) {\n            protected void fireActionPerformed(ActionEvent e) {\n                setAutoMerge(true);\n                showObjectsView();\n                objectsView.reloadView();\n            }\n        };\n        lb.setToolTipText(Bundle.JavaReferencesPlugin_AutoComputeMergedReferencesTtp());\n                \n        \n        JPanel p = new JPanel(new GridBagLayout());\n        p.setOpaque(false);\n        GridBagConstraints g;\n        \n        g = new GridBagConstraints();\n        g.fill = GridBagConstraints.HORIZONTAL;\n        g.gridy = 0;\n        p.add(jb, g);\n        \n        g = new GridBagConstraints();\n        g.fill = GridBagConstraints.HORIZONTAL;\n        g.gridy = 1;\n        g.insets = new Insets(10, 0, 0, 0);\n        p.add(lb, g);\n        \n        component.add(p);\n        \n        mergedRequest = true;\n\n        component.invalidate();\n        component.revalidate();\n        component.repaint();\n    }\n\n    protected JComponent createComponent() {\n        component = new JPanel(new BorderLayout());\n        component.setOpaque(true);\n        component.setBackground(UIUtils.getProfilerResultsBackground());\n        \n        objectsView.getComponent().setVisible(false); // force init in showObjectsView()\n        showObjectsView();\n        \n        return component;\n    }\n    \n    \n    @Override\n    protected void closed() {\n        synchronized (objectsView) { selected = objectsView.getRoot(); }\n        objectsView.closed();\n    }\n    \n    \n    private static InterruptibleIterator<Instance> instancesIterator(InstancesWrapper instances) {\n        return new InterruptibleIterator<>(instances.getInstancesIterator());\n    }\n    \n    private HeapViewerNode[] computeInstancesReferences(final InstancesWrapper instances, RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        HeapOperations.initializeReferences(heap);\n        \n        final Map<Long, Integer> values = new HashMap<>();\n        \n        try {        \n            progress.setupKnownSteps(instances.getInstancesCount());\n\n            InterruptibleIterator<Instance> instancesI = instancesIterator(instances);\n            while (instancesI.hasNext()) {\n                Instance instance = instancesI.next();\n                progress.step();\n                List<Value> references = instance.getReferences();\n                Set<Instance> referers = new HashSet<>();\n                if (references.isEmpty()) {\n                    referers.add(null);\n                } else for (Value reference : references) {\n                    referers.add(logicalReferer(reference.getDefiningInstance()));\n                }\n                for (Instance referer : referers) {\n                    long refererID = referer == null ? -1 : referer.getInstanceId();\n                    Integer count = values.get(refererID);\n                    if (count == null) count = 0;\n                    values.put(refererID, ++count);\n                }\n            }\n            if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n        } catch (OutOfMemoryError e) {\n            System.err.println(\"Out of memory in JavaReferencesPlugin: \" + e.getMessage()); // NOI18N\n            HeapUtils.handleOOME(true, e);\n            return new HeapViewerNode[] { new ErrorNode.OOME() };\n        } finally {\n            progress.finish();\n        }\n        \n        if (values.isEmpty()) return new HeapViewerNode[] { new TextNode(Bundle.JavaReferencesPlugin_NoReferences()) };\n        \n        NodesComputer<Map.Entry<Long, Integer>> computer = new NodesComputer<Map.Entry<Long, Integer>>(values.size(), UIThresholds.MAX_CLASS_INSTANCES) {\n            protected boolean sorts(DataType dataType) {\n                return true;\n            }\n            protected HeapViewerNode createNode(final Map.Entry<Long, Integer> node) {\n                long refererID = node.getKey();\n                return new ReferenceNode(refererID == -1 ? null : heap.getInstanceByID(refererID)) {\n                    @Override\n                    int getCount() { return node.getValue(); }\n                    @Override\n                    InterruptibleIterator<Instance> instancesIterator() { return JavaReferencesPlugin.instancesIterator(instances); }\n                };\n            }\n            protected ProgressIterator<Map.Entry<Long, Integer>> objectsIterator(int index, Progress progress) {\n                Iterator<Map.Entry<Long, Integer>> iterator = values.entrySet().iterator();\n                return new ProgressIterator<>(iterator, index, true, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return Bundle.JavaReferencesPlugin_MoreNodes(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return Bundle.JavaReferencesPlugin_SamplesContainer(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return Bundle.JavaReferencesPlugin_NodesContainer(firstNodeIdx, lastNodeIdx);\n            }\n        };\n\n        return computer.computeNodes(root, heap, viewID, null, dataTypes, sortOrders, progress);\n    }\n    \n    \n    protected void nodeSelected(HeapViewerNode node, boolean adjusting) {\n        synchronized (objectsView) {\n            if (Objects.equals(selected, node)) return;\n            selected = node;\n        }\n        \n        if (selected != null && !isAutoMerge() && HeapViewerNode.getValue(selected, DataType.INSTANCES_WRAPPER, heap) != null) showMergedView();\n        else showObjectsView();\n        \n        objectsView.reloadView();\n    }\n    \n    \n    private static final String KEY_MERGED_REFERENCES = \"HeapViewer.autoMergedReferences\"; // NOI18N\n    private static final String KEY_LOGICAL_REFERENCES = \"HeapViewer.logicalReferences\"; // NOI18N\n    \n    private boolean isAutoMerge() {\n        return NbPreferences.root().getBoolean(KEY_MERGED_REFERENCES, false);\n    }\n\n    private void setAutoMerge(boolean value) {\n        NbPreferences.root().putBoolean(KEY_MERGED_REFERENCES, value);\n    }\n    \n    private boolean isLogicalReferences() {\n        return NbPreferences.root().getBoolean(KEY_LOGICAL_REFERENCES, false);\n    }\n\n    private void setLogicalReferences(boolean value) {\n        NbPreferences.root().putBoolean(KEY_LOGICAL_REFERENCES, value);\n    }\n    \n    \n    @NbBundle.Messages({\n        \"ReferenceNode_MoreNodes=<another {0} instances left>\",\n        \"ReferenceNode_SamplesContainer=<sample {0} instances>\",\n        \"ReferenceNode_NodesContainer=<instances {0}-{1}>\"\n    })\n    private abstract class ReferenceNode extends InstanceNode.IncludingNull {\n        \n        ReferenceNode(Instance reference) {\n            super(reference);\n        }\n        \n        \n        abstract int getCount();\n        \n        abstract InterruptibleIterator<Instance> instancesIterator();\n\n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            HeapOperations.initializeReferences(heap);\n            \n            NodesComputer<Instance> computer = new NodesComputer<Instance>(getCount(), UIThresholds.MAX_MERGED_OBJECTS) {\n                protected boolean sorts(DataType dataType) {\n                    return !DataType.COUNT.equals(dataType);\n                }\n                @Override\n                protected HeapViewerNode createNode(Instance object) {\n                    return new ReferredInstanceNode(object) {\n                        @Override\n                        Instance getReferer() { return ReferenceNode.this.getInstance(); }\n                    };\n                }\n                protected ProgressIterator<Instance> objectsIterator(int index, final Progress _progress) {\n                    final Instance _instance = getInstance();\n                    _progress.setupUnknownSteps();\n                    Iterator<Instance> fieldInstanceIterator = new ExcludingIterator<Instance>(instancesIterator()) {\n                        @Override\n                        protected boolean exclude(Instance instance) {\n                            _progress.step();\n                            List<Value> references = instance.getReferences();\n                            if (_instance == null) return !references.isEmpty();\n                            for (Value reference : references)\n                                if (_instance.equals(logicalReferer(reference.getDefiningInstance())))\n                                    return false;\n                            return true;\n                        }\n                    };\n                    return new ProgressIterator<>(fieldInstanceIterator, index, true, _progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.JavaReferencesPlugin_IMoreNodes(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.JavaReferencesPlugin_ISamplesContainer(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.JavaReferencesPlugin_INodesContainer(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            \n            return computer.computeNodes(ReferenceNode.this, heap, viewID, null, dataTypes, sortOrders, progress);\n        }\n        \n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.COUNT) return getCount();\n\n            return super.getValue(type, heap);\n        }\n        \n        public boolean isLeaf() {\n            return false;\n        }\n        \n    }\n    \n    private static class ReferenceNodeRenderer extends InstanceNodeRenderer {\n            \n        private static final ImageIcon ICON = Icons.getImageIcon(ProfilerIcons.NODE_FORWARD);\n\n        ReferenceNodeRenderer(Heap heap) {\n            super(heap);\n        }\n        \n        @Override\n        public void setValue(Object value, int row) {\n            if (value != null) {\n                ReferenceNode node = (ReferenceNode)value;\n                if (node.getInstance() == null) {\n                    setNormalValue(Bundle.JavaReferencesPlugin_NoReferences());\n                    setBoldValue(\"\"); // NOI18N\n                    setGrayValue(\"\"); // NOI18N\n                    setIcon(ICON);\n                    return;\n                }\n            }\n            super.setValue(value, row);\n            \n            setIconTextGap(4);\n            ((LabelRenderer)valueRenderers()[0]).setMargin(3, 3, 3, 0);\n        }\n\n        @Override\n        protected ImageIcon getIcon(Instance instance, boolean isGCRoot) {\n            return ICON;\n        }\n\n    }\n    \n    private abstract class ReferredInstanceNode extends InstanceNode {\n        \n        ReferredInstanceNode(Instance instance) {\n            super(instance);\n        }\n        \n        abstract Instance getReferer();\n        \n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            HeapOperations.initializeReferences(heap);\n            \n            Instance referer = getReferer();\n            if (referer == null) return HeapViewerNode.NO_NODES;\n            \n            final List<Value> references = getInstance().getReferences();\n            Iterator<Value> referencesI = references.iterator();\n                while (referencesI.hasNext())\n                    if (!referer.equals(logicalReferer(referencesI.next().getDefiningInstance())))\n                        referencesI.remove();\n            \n            NodesComputer<Value> computer = new NodesComputer<Value>(references.size(), UIThresholds.MAX_MERGED_OBJECTS) {\n                protected boolean sorts(DataType dataType) {\n                    return !DataType.COUNT.equals(dataType);\n                }\n                protected HeapViewerNode createNode(Value object) {\n                    return InstanceReferenceNode.incoming(object);\n                }\n                protected ProgressIterator<Value> objectsIterator(int index, Progress progress) {\n                    Iterator<Value> iterator = references.listIterator(index);\n                    return new ProgressIterator<>(iterator, index, false, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.JavaReferencesPlugin_MoreNodes(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.JavaReferencesPlugin_SamplesContainer(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.JavaReferencesPlugin_NodesContainer(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            \n            return computer.computeNodes(ReferredInstanceNode.this, heap, viewID, null, dataTypes, sortOrders, progress);\n        }\n        \n        public boolean isLeaf() {\n            return getReferer() == null;\n        }\n        \n    }\n    \n    \n    private static final Set<String> COLLAPSED_ITEMS = new HashSet<>(Arrays.asList(\"java.util.HashMap$Node\", // NOI18N\n            \"java.util.WeakHashMap$Entry\" // NOI18N\n    ));\n    \n    private Instance logicalReferer(Instance realReferer) {\n        if (realReferer == null) return null;\n        return isLogicalReferences() ? logicalRefererImpl(realReferer) : realReferer;\n    }\n    \n    private Instance logicalRefererImpl(Instance realReferer) {\n        JavaClass jclass = realReferer.getJavaClass();\n        \n        if (jclass.isArray()) {\n            Value reference = getDirectReferrer(realReferer);\n            if (reference != null) return logicalRefererImpl(reference.getDefiningInstance());\n        }\n        \n        if (COLLAPSED_ITEMS.contains(jclass.getName())) {\n            Value reference = getDirectReferrer(realReferer);\n            if (reference != null) return logicalRefererImpl(reference.getDefiningInstance());\n        }\n        \n        return realReferer;\n    }\n    \n    private static Value getDirectReferrer(Instance instance) {\n        List<Value> references = instance.getReferences();\n        return references.size() == 1 ? references.get(0) : null;\n    }\n    \n    \n    @ServiceProvider(service=HeapViewerRenderer.Provider.class)\n    public static class JavaReferencesRendererProvider extends HeapViewerRenderer.Provider {\n\n        @Override\n        public boolean supportsView(HeapContext context, String viewID) {\n            return \"java_objects_references\".equals(viewID); // NOI18N\n        }\n\n        @Override\n        public void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers, HeapContext context) {\n            renderers.put(ReferenceNode.class, new ReferenceNodeRenderer(context.getFragment().getHeap()));\n        }\n        \n    }\n    \n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 300)\n    public static class Provider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!viewID.startsWith(\"diff\") && JavaHeapFragment.isJavaHeap(context)) { // NOI18N\n                JavaReferencesProvider provider = Lookup.getDefault().lookup(JavaReferencesProvider.class);\n                return new JavaReferencesPlugin(context, actions, provider);\n            }\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaReferencesProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceReferenceNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.HeapOperations;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.Value;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.util.lookup.ServiceProviders;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaReferencesProvider_Name=references\",\n    \"JavaReferencesProvider_MoreNodes=<another {0} references left>\",\n    \"JavaReferencesProvider_SamplesContainer=<sample {0} references>\",\n    \"JavaReferencesProvider_NodesContainer=<references {0}-{1}>\"\n})\n@ServiceProviders(value={\n    @ServiceProvider(service=HeapViewerNode.Provider.class, position = 400),\n    @ServiceProvider(service=JavaReferencesProvider.class, position = 400)}\n)\npublic class JavaReferencesProvider extends HeapViewerNode.Provider {\n    \n    public String getName() {\n        return Bundle.JavaReferencesProvider_Name();\n    }\n    \n    public boolean supportsView(Heap heap, String viewID) {\n        return viewID.startsWith(\"java_\"); // NOI18N\n    }\n    \n    public boolean supportsNode(HeapViewerNode parent, Heap heap, String viewID) {\n        return parent instanceof InstanceNode && !InstanceNode.Mode.OUTGOING_REFERENCE.equals(((InstanceNode)parent).getMode());\n    }\n    \n    public HeapViewerNode[] getNodes(HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        return getNodes(((InstanceNode)parent).getInstance(), parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n    }\n    \n    HeapViewerNode[] getNodes(Instance instance, final HeapViewerNode parent, final Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        if (instance == null) return null;\n        \n        HeapOperations.initializeReferences(heap);\n        \n        final List<Value> references = instance.getReferences();\n        \n        NodesComputer<Value> computer = new NodesComputer<Value>(references.size(), UIThresholds.MAX_INSTANCE_REFERENCES) {\n            protected boolean sorts(DataType dataType) {\n                return !DataType.COUNT.equals(dataType);\n            }\n            protected HeapViewerNode createNode(Value reference) {\n                return InstanceReferenceNode.incoming(reference);\n            }\n            protected ProgressIterator<Value> objectsIterator(int index, Progress progress) {\n                Iterator<Value> iterator = references.listIterator(index);\n                return new ProgressIterator<>(iterator, index, false, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return Bundle.JavaReferencesProvider_MoreNodes(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return Bundle.JavaReferencesProvider_SamplesContainer(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return Bundle.JavaReferencesProvider_NodesContainer(firstNodeIdx, lastNodeIdx);\n            }\n        };\n        \n        return computer.computeNodes(parent, heap, viewID, null, dataTypes, sortOrders, progress);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaSummaryProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapViewerFeature.Provider.class)\npublic class JavaSummaryProvider extends HeapViewerFeature.Provider {\n    \n    public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n        if (JavaHeapFragment.isJavaHeap(context)) \n            return new JavaSummaryView(context, actions);\n\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaSummaryView.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport javax.swing.JComponent;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.graalvm.visualvm.heapviewer.ui.SummaryView;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaSummaryView_Name=Summary\",\n    \"JavaSummaryView_Description=Summary\"\n})\npublic class JavaSummaryView extends HeapViewerFeature {\n    \n    private static final String VIEW_ID = \"java_summary\"; // NOI18N\n    \n    private final SummaryView summaryView;\n    \n    \n    public JavaSummaryView(HeapContext context, HeapViewerActions actions) {\n        super(VIEW_ID, Bundle.JavaSummaryView_Name(), Bundle.JavaSummaryView_Description(),\n               Icons.getIcon(HeapWalkerIcons.PROPERTIES), 100); // NOI18N\n        \n        summaryView = new SummaryView(VIEW_ID, context, actions);\n    }\n    \n    \n    public boolean isDefault() {\n        return true;\n    }\n    \n    public JComponent getComponent() {\n        return summaryView.getComponent();\n    }\n\n    public ProfilerToolbar getToolbar() {\n        return summaryView.getToolbar();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaThreadsProvider.java",
    "content": "/*\n * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.LocalObjectNode;\nimport org.graalvm.visualvm.heapviewer.java.StackFrameNode;\nimport org.graalvm.visualvm.heapviewer.java.ThreadNode;\nimport org.graalvm.visualvm.heapviewer.java.ThreadStateNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.lib.jfluid.heap.GCRoot;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaFrameGCRoot;\nimport org.graalvm.visualvm.lib.jfluid.heap.JniLocalGCRoot;\nimport org.graalvm.visualvm.lib.jfluid.heap.ThreadObjectGCRoot;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaThreadsProvider_LocalVariable=local variable\",\n    \"JavaThreadsProvider_UnknownLocalVariable=unknown local variable\",\n    \"JavaThreadsProvider_JniLocal=JNI local\",\n    \"JavaThreadsProvider_UnknownJniLocal=unknown JNI local\",\n    \"JavaThreadsProvider_UnknownThread=unknown thread\",\n    \"JavaThreadsProvider_CannotResolveClassMsg=Cannot resolve class\",\n    \"JavaThreadsProvider_CannotResolveInstanceMsg=Cannot resolve instance\"\n})\nclass JavaThreadsProvider {\n    \n    private static final String OPEN_THREADS_URL = \"file:/stackframe/\";     // NOI18N\n    private static final String LOCAL_VARIABLE = Bundle.JavaThreadsProvider_LocalVariable();\n    private static final String JNI_LOCAL = Bundle.JavaThreadsProvider_JniLocal();\n\n    private static class ThreadInfo {\n\n        String threadName;\n        Long threadId;\n        Boolean daemon;\n        Integer priority;\n        Thread.State threadState;\n        String virtualName;\n\n        ThreadInfo(JavaClass vtClass, Instance instance) {\n            if (isVirtualThread(vtClass, instance)) {\n                virtualName = \"Virtual Thread \"+DetailsSupport.getDetailsString(instance); // NOI18N\n                return;\n            }\n            threadName = getThreadInstanceName(instance);\n            threadId = (Long) instance.getValueOfField(\"tid\");    // NOI18N\n            daemon = (Boolean) instance.getValueOfField(\"daemon\"); // NOI18N\n            priority = (Integer) instance.getValueOfField(\"priority\"); // NOI18N\n            Integer threadStatus = (Integer) instance.getValueOfField(\"threadStatus\"); // NOI18N\n\n            if (daemon == null) {\n                Instance holder = (Instance) instance.getValueOfField(\"holder\");  // NOI18N\n                if (holder != null) {\n                    daemon = (Boolean) holder.getValueOfField(\"daemon\"); // NOI18N\n                    priority = (Integer) holder.getValueOfField(\"priority\"); // NOI18N\n                    threadStatus = (Integer) holder.getValueOfField(\"threadStatus\"); // NOI18N\n                }\n            }\n            if (threadStatus != null) {\n                threadState = toThreadState(threadStatus.intValue());\n            }\n        }\n\n        Thread.State getThreadState() {\n            return threadState;\n        }\n\n        public String toString() {\n            if (virtualName != null) {\n                return virtualName;\n            }\n            String tName = \"\\\"\" + threadName + \"\\\"\" + (daemon.booleanValue() ? \" daemon\" : \"\") + \" prio=\" + priority; // NOI18N\n            if (threadId != null) tName += \" tid=\" + threadId; // NOI18N\n            if (threadState != null) tName += \" \" + threadState; // NOI18N\n\n            return tName;\n        }\n    }\n\n    static String getThreadName(JavaClass vtClass, Instance instance) {\n        return new ThreadInfo(vtClass, instance).toString();\n    }\n    \n    static ThreadObjectGCRoot getOOMEThread(Heap heap) {\n        Collection<GCRoot> roots = heap.getGCRoots();\n\n        for (GCRoot root : roots) {\n            if(root.getKind().equals(GCRoot.THREAD_OBJECT)) {\n                ThreadObjectGCRoot threadRoot = (ThreadObjectGCRoot)root;\n                StackTraceElement[] stackTrace = threadRoot.getStackTrace();\n                \n                if (stackTrace!=null && stackTrace.length>=1) {\n                    StackTraceElement ste = stackTrace[0];\n                    \n                    if (OutOfMemoryError.class.getName().equals(ste.getClassName()) && \"<init>\".equals(ste.getMethodName())) {  // NOI18N\n                        return threadRoot;\n                    }\n                }\n            }\n        }\n        return null;\n    }\n    \n    static HeapViewerNode getNode(URL url, HeapContext context) {\n        String urls = url.toString();\n                \n        if (HeapUtils.isInstance(urls)) {\n            final Instance instance = HeapUtils.instanceFromHtml(urls, context.getFragment().getHeap());\n            if (instance != null) return new InstanceNode(instance);\n            else ProfilerDialogs.displayError(Bundle.JavaThreadsProvider_CannotResolveInstanceMsg());\n        } else if (HeapUtils.isClass(urls)) {\n            JavaClass javaClass = HeapUtils.classFromHtml(urls, context.getFragment().getHeap());\n            if (javaClass != null) return new ClassNode(javaClass);\n            else ProfilerDialogs.displayError(Bundle.JavaThreadsProvider_CannotResolveClassMsg());\n        }\n\n        return null;\n    }\n    \n    static HeapViewerNode[] getStateNodes(RootNode root, Heap heap) throws InterruptedException {\n        HeapViewerNode[] stateNodes;\n        HeapViewerNode[] threadsNodes = getThreadsNodes(root, heap);\n        Map<Thread.State,List<HeapViewerNode>> states = new HashMap<>();\n        for (HeapViewerNode n : threadsNodes) {\n            Thread.State s = ((ThreadNode)n).getState();\n            List<HeapViewerNode> nodes = states.computeIfAbsent(s, k -> new ArrayList<>());\n            nodes.add(n);\n        }\n        int i = 0;\n        stateNodes = new HeapViewerNode[states.size()];\n        for (Map.Entry<Thread.State, List<HeapViewerNode>> stateEntry : states.entrySet()) {\n            Thread.State state = stateEntry.getKey();\n            ThreadStateNode stateNode = new ThreadStateNode(state, stateEntry.getValue());\n            stateNodes[i++] = stateNode;\n        }\n        return stateNodes;\n    }\n        \n    static HeapViewerNode[] getThreadsNodes(RootNode rootNode, Heap heap) throws InterruptedException {\n        List<HeapViewerNode> threadNodes = new ArrayList<>();\n        \n        Collection<GCRoot> roots = heap.getGCRoots();\n        JavaClass vtClass = heap.getJavaClassByName(\"java.lang.VirtualThread\");    // NOI18N\n        Map<ThreadObjectGCRoot,Map<Integer,List<GCRoot>>> javaFrameMap = computeJavaFrameMap(roots);\n        ThreadObjectGCRoot oome = JavaThreadsProvider.getOOMEThread(heap);\n        \n        Thread worker = Thread.currentThread();\n        \n        for (GCRoot root : roots) {\n            if (root.getKind().equals(GCRoot.THREAD_OBJECT)) {\n                ThreadObjectGCRoot threadRoot = (ThreadObjectGCRoot)root;\n                Instance threadInstance = threadRoot.getInstance();\n                if (threadInstance != null) {\n                    StackTraceElement stack[] = threadRoot.getStackTrace();\n                    Map<Integer,List<GCRoot>> localsMap = javaFrameMap.get(threadRoot);\n\n                    ThreadInfo ti = new ThreadInfo(vtClass, threadInstance);\n                    final List<HeapViewerNode> stackFrameNodes = new ArrayList<>();\n                    ThreadNode threadNode = new ThreadNode(ti.toString(), ti.getThreadState(), threadRoot.equals(oome), threadInstance) {\n                        protected HeapViewerNode[] computeChildren(RootNode root) {\n                            return stackFrameNodes.toArray(HeapViewerNode.NO_NODES);\n                        }\n                    };\n\n                    // -------------------------------------------------------------------\n                    if(stack != null) {\n                        for(int i = 0; i < stack.length; i++) {\n                            final List<HeapViewerNode> localVariableNodes = new ArrayList<>();\n                            if (localsMap != null) {\n                                List<GCRoot> locals = localsMap.get(i);\n                                if (locals != null) {\n                                    for (GCRoot local : locals) {\n                                        Instance localInstance = local.getInstance();\n                                        if (localInstance != null) {\n                                            String text = \"\";\n                                            if (GCRoot.JAVA_FRAME.equals(local.getKind())) {\n                                                text = LOCAL_VARIABLE;\n                                            } else if (GCRoot.JNI_LOCAL.equals(local.getKind())) {\n                                                text = JNI_LOCAL;\n                                            }\n                                            localVariableNodes.add(new LocalObjectNode(localInstance, text));\n                                        } else {\n                                            localVariableNodes.add(new LocalObjectNode.Unknown());                                              \n                                        }\n                                    }\n                                }\n                            }\n                            \n                            StackTraceElement stackElement = stack[i];\n                            StackFrameNode stackFrameNode = new StackFrameNode(stackElement.toString(), localVariableNodes.toArray(HeapViewerNode.NO_NODES));\n                            stackFrameNodes.add(stackFrameNode);\n                            \n                            if (worker.isInterrupted()) throw new InterruptedException();\n                        }\n                    }\n\n                    threadNodes.add(threadNode);\n                } else {\n                    threadNodes.add(new ThreadNode.Unknown());\n                }\n            }\n        }\n        \n        return threadNodes.toArray(HeapViewerNode.NO_NODES);\n    }\n    \n    static String getThreadsHTML(HeapContext context) {        \n//        boolean gotoSourceAvailable = context.getProject() != null && GoToSource.isAvailable();\n        boolean gotoSourceAvailable = false;\n        StringBuilder sb = new StringBuilder();\n        Heap heap = context.getFragment().getHeap();\n        Collection<GCRoot> roots = heap.getGCRoots();\n        Map<ThreadObjectGCRoot,Map<Integer,List<GCRoot>>> javaFrameMap = computeJavaFrameMap(roots);\n        ThreadObjectGCRoot oome = JavaThreadsProvider.getOOMEThread(heap);\n        JavaClass javaClassClass = heap.getJavaClassByName(Class.class.getName());\n        JavaClass vtClass = heap.getJavaClassByName(\"java.lang.VirtualThread\");    // NOI18N\n        // Use this to enable VisualVM color scheme for threads dumps:\n        // sw.append(\"<pre style='color: #cc3300;'>\"); // NOI18N\n        sb.append(\"<head><style>span.g {color: #666666;}</style></head>\");\n        sb.append(\"<pre>\"); // NOI18N\n        for (GCRoot root : roots) {\n            if(root.getKind().equals(GCRoot.THREAD_OBJECT)) {\n                ThreadObjectGCRoot threadRoot = (ThreadObjectGCRoot)root;\n                Instance threadInstance = threadRoot.getInstance();\n                if (threadInstance != null) {\n                    String threadName = JavaThreadsProvider.getThreadName(vtClass, threadInstance);\n                    StackTraceElement stack[] = threadRoot.getStackTrace();\n                    Map<Integer,List<GCRoot>> localsMap = javaFrameMap.get(threadRoot);\n                    String style=\"\"; // NOI18N\n\n                    if (threadRoot.equals(oome)) {\n                        style=\"style=\\\"color: #FF0000\\\"\"; // NOI18N\n                    }                        \n                    // --- Use this to enable VisualVM color scheme for threads dumps: ---\n                    // sw.append(\"<span style=\\\"color: #0033CC\\\">\"); // NOI18N\n                    sb.append(\"<a name='\").append(threadInstance.getInstanceId()).append(\"'><b \").append(style).append(\">\");   // NOI18N\n                    // -------------------------------------------------------------------\n                    sb.append(HeapUtils.htmlize(threadName));\n                    // --- Use this to enable VisualVM color scheme for threads dumps: ---\n                    // sw.append(\"</span><br>\"); // NOI18N\n                    sb.append(\"</b></a><br>\");   // NOI18N\n                    // -------------------------------------------------------------------\n                    if(stack != null) {\n                        for(int i = 0; i < stack.length; i++) {\n                            String stackElHref;\n                            StackTraceElement stackElement = stack[i];\n                            String stackElementText = HeapUtils.htmlize(stackElement.toString());\n\n                            if (gotoSourceAvailable) {\n                                String className = stackElement.getClassName();\n                                String method = stackElement.getMethodName();\n                                int lineNo = stackElement.getLineNumber();\n                                String stackUrl = OPEN_THREADS_URL+className+\"|\"+method+\"|\"+lineNo; // NOI18N\n\n                                // --- Use this to enable VisualVM color scheme for threads dumps: ---\n                                // stackElHref = \"<a style=\\\"color: #CC3300;\\\" href=\\\"\"+stackUrl+\"\\\">\"+stackElement+\"</a>\"; // NOI18N\n                                stackElHref = \"<a href=\\\"\"+stackUrl+\"\\\">\"+stackElementText+\"</a>\";    // NOI18N\n                                // -------------------------------------------------------------------\n                            } else {\n                                stackElHref = stackElementText;\n                            }\n                            sb.append(\"    at \").append(stackElHref).append(\"<br>\");  // NOI18N\n                            if (localsMap != null) {\n                                List<GCRoot> locals = localsMap.get(Integer.valueOf(i));\n\n                                if (locals != null) {\n                                    for (GCRoot local : locals) {\n                                        Instance localInstance = local.getInstance();\n\n                                        if (localInstance != null) {\n                                            String text = \"\";\n                                            if (GCRoot.JAVA_FRAME.equals(local.getKind())) {\n                                                text = LOCAL_VARIABLE;\n                                            } else if (GCRoot.JNI_LOCAL.equals(local.getKind())) {\n                                                text = JNI_LOCAL;\n                                            }\n                                            sb.append(\"       <span class=\\\"g\\\">\" + text + \":</span> \").append(HeapUtils.instanceToHtml(localInstance, false, javaClassClass)).append(\"<br>\"); // NOI18N\n                                        } else {\n                                            String text = \"\";\n                                            if (GCRoot.JAVA_FRAME.equals(local.getKind())) {\n                                                text = Bundle.JavaThreadsProvider_UnknownLocalVariable();\n                                            } else if (GCRoot.JNI_LOCAL.equals(local.getKind())) {\n                                                text = Bundle.JavaThreadsProvider_UnknownJniLocal();\n                                            }\n                                            sb.append(\"       <span class=\\\"g\\\">\" + text + \"</span><br>\"); // NOI18N\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                } else {\n                    sb.append(Bundle.JavaThreadsProvider_UnknownThread() + \"<br>\"); // NOI18N\n                }\n                sb.append(\"<br>\");  // NOI18N\n            }\n        }\n        sb.append(\"</pre>\"); // NOI18N\n        \n        return sb.toString();\n    }\n    \n    \n    private static String getThreadInstanceName(Instance threadInstance) {\n        Object threadName = threadInstance.getValueOfField(\"name\");  // NOI18N\n        if (threadName == null) return \"*null*\"; // NOI18N\n        return DetailsSupport.getDetailsString((Instance)threadName);\n    }\n    \n    private static boolean isVirtualThread(JavaClass vtClass, Instance threadInstance) {\n        if (vtClass != null) {\n            JavaClass threadClass = threadInstance.getJavaClass();\n            for (;threadClass != null; threadClass = threadClass.getSuperClass()) {\n                if (threadClass.equals(vtClass)) return true;\n            }\n        }\n        return false;\n    }\n\n    private static Map<ThreadObjectGCRoot,Map<Integer,List<GCRoot>>> computeJavaFrameMap(Collection<GCRoot> roots) {\n        Map<ThreadObjectGCRoot,Map<Integer,List<GCRoot>>> javaFrameMap = new HashMap<>();\n        \n        for (GCRoot root : roots) {\n            ThreadObjectGCRoot threadObj;\n            Integer frameNo;\n\n            if (GCRoot.JAVA_FRAME.equals(root.getKind())) {\n                JavaFrameGCRoot frameGCroot = (JavaFrameGCRoot) root;\n                threadObj = frameGCroot.getThreadGCRoot();\n                frameNo = frameGCroot.getFrameNumber();\n            } else if (GCRoot.JNI_LOCAL.equals(root.getKind())) {\n                JniLocalGCRoot jniGCroot = (JniLocalGCRoot) root;\n                threadObj = jniGCroot.getThreadGCRoot();\n                frameNo = jniGCroot.getFrameNumber();\n            } else {\n                continue;\n            }\n\n            Map<Integer,List<GCRoot>> stackMap = javaFrameMap.get(threadObj);\n            List<GCRoot> locals;\n\n            if (stackMap == null) {\n                stackMap = new HashMap<>();\n                javaFrameMap.put(threadObj,stackMap);\n            }\n            locals = stackMap.computeIfAbsent(frameNo, k -> new ArrayList<>(2));\n            locals.add(root);\n        }\n        return javaFrameMap;\n    }\n    \n    /** taken from sun.misc.VM\n     * \n     * Returns Thread.State for the given threadStatus\n     */\n    private static Thread.State toThreadState(int threadStatus) {\n        if ((threadStatus & JVMTI_THREAD_STATE_RUNNABLE) != 0) {\n            return Thread.State.RUNNABLE;\n        } else if ((threadStatus & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) != 0) {\n            return Thread.State.BLOCKED;\n        } else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) != 0) {\n            return Thread.State.WAITING;\n        } else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) != 0) {\n            return Thread.State.TIMED_WAITING;\n        } else if ((threadStatus & JVMTI_THREAD_STATE_TERMINATED) != 0) {\n            return Thread.State.TERMINATED;\n        } else if ((threadStatus & JVMTI_THREAD_STATE_ALIVE) == 0) {\n            return Thread.State.NEW;\n        } else {\n            return Thread.State.RUNNABLE;\n        }\n    }\n    \n     /* The threadStatus field is set by the VM at state transition\n     * in the hotspot implementation. Its value is set according to\n     * the JVM TI specification GetThreadState function.\n     */\n    private final static int JVMTI_THREAD_STATE_ALIVE = 0x0001;\n    private final static int JVMTI_THREAD_STATE_TERMINATED = 0x0002;\n    private final static int JVMTI_THREAD_STATE_RUNNABLE = 0x0004;\n    private final static int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400;\n    private final static int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010;\n    private final static int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaThreadsSummary.java",
    "content": "/*\n * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.FocusAdapter;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.util.Collection;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.java.ThreadNode;\nimport org.graalvm.visualvm.heapviewer.java.ThreadNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.swing.LinkButton;\nimport org.graalvm.visualvm.heapviewer.ui.HeapView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.SummaryView;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ThreadObjectGCRoot;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.graalvm.visualvm.uisupport.SeparatorLine;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaThreadsSummary_Name=OutOfMemoryError Thread\",\n    \"JavaThreadsSummary_Description=OutOfMemoryError Thread\",\n    \"JavaThreadsSummary_Hint=This heap dump has been created automatically on an OutOfMemoryError thrown in this thread:\",\n    \"JavaThreadsSummary_ViewAll=view all\",\n    \"JavaThreadsSummary_NameColumn=Name\"\n})\nclass JavaThreadsSummary extends HeapView {\n    \n    private final HeapContext context;\n    private final HeapViewerActions actions;\n    private final Collection<HeapViewerNodeAction.Provider> actionProviders;\n    \n    private JComponent component;\n    \n    private final Object[][] threadData;\n    private boolean keepSelection;\n    \n    \n    private JavaThreadsSummary(Instance oomeInstance, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n        super(Bundle.JavaThreadsSummary_Name(), Bundle.JavaThreadsSummary_Description());\n        \n        this.context = context;\n        this.actions = actions;\n        this.actionProviders = actionProviders;\n        \n        JavaClass vtClass = oomeInstance.getJavaClass().getHeap().getJavaClassByName(\"java.lang.VirtualThread\");    // NOI18N\n        String threadName = JavaThreadsProvider.getThreadName(vtClass, oomeInstance);\n        threadData = new Object[][] {{ new ThreadNode(threadName, null, true, oomeInstance) }};\n    }\n    \n    \n    @Override\n    public JComponent getComponent() {\n        if (component == null) init();\n        return component;\n    }\n\n    @Override\n    public ProfilerToolbar getToolbar() {\n        return null;\n    }\n    \n    \n    private void init() {\n        component = new JPanel(new GridBagLayout()) {\n            public Dimension getMinimumSize() {\n                Dimension dim = super.getMinimumSize();\n                dim.width = 0;\n                return dim;\n            }\n\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.width = 0;\n                return dim;\n            }\n        };\n        component.setOpaque(false);\n        component.setBorder(BorderFactory.createEmptyBorder(12, 5, 0, 5));\n        \n        JLabel caption = new JLabel(Bundle.JavaThreadsSummary_Name());\n        caption.setFont(caption.getFont().deriveFont(Font.BOLD));\n        GridBagConstraints c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.weighty = 1d;\n        c.insets = new Insets(0, 0, 0, 0);\n        component.add(caption, c);\n\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.insets = new Insets(0, 5, 0, 0);\n        component.add(new JLabel(\"[\"), c); // NOI18N\n\n        LinkButton link = new LinkButton(Bundle.JavaThreadsSummary_ViewAll()) {\n            @Override\n            protected void clicked() {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        JavaThreadsView threadsView = actions.findFeature(JavaThreadsView.class);\n                        if (threadsView != null) {\n                            threadsView.configureAllThreads();\n                            actions.selectFeature(threadsView);\n                        }\n                    }\n                });\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 0;\n        c.insets = new Insets(0, 0, 0, 0);\n        component.add(link, c);\n\n        c = new GridBagConstraints();\n        c.gridx = 3;\n        c.gridy = 0;\n        c.insets = new Insets(0, 0, 0, 0);\n        component.add(new JLabel(\"]\"), c); // NOI18N\n\n        c = new GridBagConstraints();\n        c.gridx = 4;\n        c.gridy = 0;\n        c.weightx = 1d;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(1, 4, 0, 0);\n        component.add(new SeparatorLine(), c);\n        \n        \n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(8, 1, 3, 0);\n        component.add(new JLabel(Bundle.JavaThreadsSummary_Hint(), JLabel.LEADING), c);\n        \n        final TableModel model = new DefaultTableModel(threadData, new Object[] {\n                                            Bundle.JavaThreadsSummary_NameColumn() }) {\n            public boolean isCellEditable(int row, int column) { return false; }\n        };\n        ProfilerTable thread = createTable(model);\n        ProfilerRenderer renderer = new ThreadNodeRenderer(context.getFragment().getHeap());\n        thread.setColumnRenderer(0, renderer);\n        Dimension dim = thread.getPreferredSize();\n        renderer.setValue(threadData[0][0], 0);\n        dim.width = renderer.getComponent().getPreferredSize().width + 4;\n        thread.setPreferredSize(dim);\n        thread.setMinimumSize(dim);\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 2;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(0, 0, 0, 0);\n        component.add(thread, c);\n    }\n    \n    \n    private ProfilerTable createTable(TableModel model) {\n        ProfilerTable t = new SummaryView.SimpleTable(model, 0) {\n            public void setBounds(int x, int y, int w, int h) {\n                Container parent = getParent();\n                if (parent != null) w = Math.min(w, parent.getWidth());\n                super.setBounds(x, y, w, h);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                requestFocusInWindow(); // TODO: should be done by ProfilerTable on selectRow(...) in processMouseEvent(...)\n\n                HeapViewerNode node = (HeapViewerNode)value;\n                HeapViewerNodeAction.Actions nodeActions = HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions);\n                nodeActions.populatePopup(popup);\n\n                if (popup.getComponentCount() > 0) popup.addSeparator();\n                popup.add(createCopyMenuItem());\n            }\n            public void performDefaultAction(ActionEvent e) {\n                int row = getSelectedRow();\n                if (row == -1) return;\n\n                Object value = getValueForRow(row);\n                if (!(value instanceof HeapViewerNode)) return;\n\n                HeapViewerNodeAction.Actions nodeActions =\n                        HeapViewerNodeAction.Actions.forNode((HeapViewerNode)value, actionProviders, context, actions);\n                nodeActions.performDefaultAction(e);\n            }\n            protected void popupShowing() {\n                keepSelection = true;\n            }\n            protected void popupHidden() {\n                keepSelection = false;\n                \n                new Timer(100, new ActionListener() {\n                    @Override\n                    public void actionPerformed(ActionEvent e) {\n                        if (!isFocusOwner()) clearSelection();\n                    }\n                }) { { setRepeats(false); } }.start();\n            }\n        };\n        t.setRowSelectionAllowed(true);\n        t.addFocusListener(new FocusAdapter() {\n            public void focusLost(FocusEvent e) {\n                if (!keepSelection) t.clearSelection();\n                else keepSelection = false;\n            }\n        });\n        t.providePopupMenu(true);\n        t.setSelectionOnMiddlePress(true);\n        t.addMouseListener(new MouseAdapter() {\n            public void mouseClicked(MouseEvent e) {\n                if (SwingUtilities.isMiddleMouseButton(e)) {\n                    int row = t.getSelectedRow();\n                    if (row == -1) return;\n\n                    Object value = t.getValueForRow(row);\n                    if (!(value instanceof HeapViewerNode)) return;\n\n                    HeapViewerNode node = (HeapViewerNode)value;\n                    HeapViewerNodeAction.Actions nodeActions = HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions);\n                    ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), \"middle button\", e.getWhen(), e.getModifiers()); // NOI18N\n                    nodeActions.performMiddleButtonAction(ae);\n                }\n            }\n        });\n\n        return t;\n    }\n    \n    \n    @ServiceProvider(service=SummaryView.ContentProvider.class, position = 200)\n    public static class Provider extends SummaryView.ContentProvider {\n\n        @Override\n        public HeapView createSummary(String viewID, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n            if (!JavaHeapFragment.isJavaHeap(context)) return null;\n            \n            ThreadObjectGCRoot oomeThread = JavaThreadsProvider.getOOMEThread(context.getFragment().getHeap());\n            Instance oomeInstance = oomeThread == null ? null : oomeThread.getInstance();\n            if (oomeInstance == null) return null;\n            \n            return new JavaThreadsSummary(oomeInstance, context, actions, actionProviders);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaThreadsView.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.CardLayout;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport java.net.URL;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.List;\nimport javax.swing.AbstractAction;\nimport javax.swing.ButtonGroup;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.ui.HTMLView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.PluggableTreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.heap.GCRoot;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaFrameGCRoot;\nimport org.graalvm.visualvm.lib.jfluid.heap.JniLocalGCRoot;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.threads.ThreadStateIcon;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaThreadsView_Name=Threads\",\n    \"JavaThreadsView_Description=Threads\",\n    \"JavaThreadsView_ComputingThreads=<br>&nbsp;&nbsp;&lt;computing threads...&gt;\",\n    \"JavaThreadsView_Results=Results:\",\n    \"JavaThreadsView_TooltipObjects=Objects\",\n    \"JavaThreadsView_TooltipHTML=HTML\",\n    \"JavaThreadsView_Details=Details:\",\n    \"JavaThreadsView_SelectAction=Select in Threads\",\n    \"JavaThreadsView_ExpandAction=Expand All Threads\",\n    \"JavaThreadsView_CollapseAction=Collapse All Threads\",\n    \"JavaThreadsView_Aggregation=Aggregation:\",\n    \"JavaThreadsView_TName=Thread name\",\n    \"JavaThreadsView_TState=Thread state\"\n})\npublic class JavaThreadsView extends HeapViewerFeature {\n    \n    private static final String FEATURE_ID = \"java_threads\"; // NOI18N\n    private static final String VIEW_OBJECTS_ID = FEATURE_ID + \"_objects\"; // NOI18N\n    private static final String VIEW_HTML_ID = FEATURE_ID + \"_html\"; // NOI18N\n\n    private static enum Aggregation {\n        NAMES (Bundle.JavaThreadsView_TName(), Icons.getIcon(ProfilerIcons.THREAD)),\n        STATES (Bundle.JavaThreadsView_TState(), new ThreadStateIcon(CommonConstants.THREAD_STATUS_RUNNING, 15, 15));\n\n        private final String aggregationName;\n        private final Icon aggregationIcon;\n        private Aggregation(String aggregationName, Icon aggregationIcon) { this.aggregationName = aggregationName; this.aggregationIcon = aggregationIcon; }\n        public String toString() { return aggregationName; }\n        public Icon getIcon() { return aggregationIcon; }\n    }\n    \n//    private final HeapContext context;\n//    private final HeapViewerActions actions;\n    \n    private Aggregation aggregation = Aggregation.NAMES;\n\n    private JComponent component;\n    private ProfilerToolbar toolbar;\n    private ProfilerToolbar aggregToolbar;\n    private ProfilerToolbar pluginsToolbar;\n    \n    private final HTMLView htmlView;\n    private final PluggableTreeTableView objectsView;\n    \n    private JToggleButton rObjects;\n    private JToggleButton rHTML;\n\n    private JToggleButton tbName;\n    private JToggleButton tbState;\n    \n    public JavaThreadsView(HeapContext context, HeapViewerActions actions) {\n        super(FEATURE_ID, Bundle.JavaThreadsView_Name(), Bundle.JavaThreadsView_Description(), Icons.getIcon(ProfilerIcons.WINDOW_THREADS), 300);\n        \n//        this.context = context;\n//        this.actions = actions;\n        \n        Heap heap = context.getFragment().getHeap();\n        \n        objectsView = new PluggableTreeTableView(VIEW_OBJECTS_ID, context, actions, TreeTableViewColumn.instances(heap, false)) {\n            protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                switch (getAggregation()) {\n                    case NAMES:\n                        return JavaThreadsProvider.getThreadsNodes(root, heap);\n                    case STATES:\n                        return JavaThreadsProvider.getStateNodes(root, heap);\n                    default:\n                        throw new IllegalArgumentException(getAggregation().toString());\n                }\n            }\n            protected void childrenChanged() {\n                setupDefault();\n            }\n            @Override\n            protected void populatePopup(HeapViewerNode node, JPopupMenu popup) {\n                if (popup.getComponentCount() > 0) popup.addSeparator();\n                \n                popup.add(new AbstractAction(Bundle.JavaThreadsView_ExpandAction()) {\n                    @Override\n                    public void actionPerformed(ActionEvent e) {\n                        SwingUtilities.invokeLater(JavaThreadsView.this::setupDefault);\n                    }\n                });\n                \n                popup.add(new AbstractAction(Bundle.JavaThreadsView_CollapseAction()) {\n                    @Override\n                    public void actionPerformed(ActionEvent e) {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            @Override\n                            public void run() {\n                                collapseChildren((HeapViewerNode)getRoot());\n                            }\n                        });\n                    }\n                });\n            }\n        };\n        objectsView.setViewName(Bundle.JavaThreadsView_Name());\n        \n        htmlView = new HTMLView(VIEW_HTML_ID, context, actions, Bundle.JavaThreadsView_ComputingThreads()) {\n            protected String computeData(HeapContext context, String viewID) {\n                return JavaThreadsProvider.getThreadsHTML(context);\n            }\n            protected HeapViewerNode nodeForURL(URL url, HeapContext context) {\n                return JavaThreadsProvider.getNode(url, context);\n            }\n        };\n    }\n    \n    \n    public JComponent getComponent() {\n        if (component == null) init();\n        return component;\n    }\n\n    public ProfilerToolbar getToolbar() {\n        if (toolbar == null) init();\n        return toolbar;\n    }\n    \n    \n    @Override\n    protected void closed() {\n        objectsView.closed();\n    }\n    \n    \n    void selectInstance(long instanceID, String viewID) {\n        if (rHTML == null) init();\n        \n        rHTML.setSelected(true);\n        htmlView.selectReference(Long.toString(instanceID));\n    }\n    \n    void configureAllThreads() {\n        if (component != null) {\n            rObjects.setSelected(true);\n            SwingUtilities.invokeLater(new Runnable() {\n                @Override\n                public void run() {\n                    objectsView.collapseChildren(objectsView.getRoot());\n                    setupDefault();\n                }\n            });\n        }\n    }\n    \n    private static final int MAX_EXPAND_SIZE = 1000;\n    private static final int DEFAULT_EXPAND_SIZE = 800;\n    \n    private void setupDefault() {\n        CCTNode[] children = objectsView.getRoot().getChildren();\n        if (children.length > MAX_EXPAND_SIZE) {\n            children = Arrays.copyOf(children, DEFAULT_EXPAND_SIZE);\n        }\n        for (CCTNode child : children) objectsView.expandNode((HeapViewerNode)child);\n    }\n    \n    private synchronized void setAggregation(Aggregation aggregation) {\n        this.aggregation = aggregation;\n\n//        if (!skipReload) objectsView.reloadView();\n        objectsView.reloadView();\n    }\n    \n    private synchronized Aggregation getAggregation() {\n        return aggregation;\n    }\n\n    private void init() {\n        toolbar = ProfilerToolbar.create(false);\n        \n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n        \n        toolbar.add(new GrayLabel(Bundle.JavaThreadsView_Results()));\n        toolbar.addSpace(3);\n        \n        ButtonGroup resultsBG = new ButtonGroup();\n        \n        rObjects = new JToggleButton(Icons.getIcon(ProfilerIcons.TAB_HOTSPOTS), true) {\n            protected void fireItemStateChanged(ItemEvent e) {\n                if (e.getStateChange() == ItemEvent.SELECTED) {\n                    if (component != null) ((CardLayout)component.getLayout()).first(component);\n                    if (aggregToolbar != null) aggregToolbar.getComponent().setVisible(true);\n                    if (pluginsToolbar != null) pluginsToolbar.getComponent().setVisible(true);\n                }\n            }\n        };\n        rObjects.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        rObjects.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        rObjects.setToolTipText(Bundle.JavaThreadsView_TooltipObjects());\n        resultsBG.add(rObjects);\n        toolbar.add(rObjects);\n        \n        rHTML = new JToggleButton(Icons.getIcon(HeapWalkerIcons.PROPERTIES)) {\n            protected void fireItemStateChanged(ItemEvent e) {\n                if (e.getStateChange() == ItemEvent.SELECTED) {\n                    if (component != null) ((CardLayout)component.getLayout()).last(component);\n                    if (aggregToolbar != null) aggregToolbar.getComponent().setVisible(false);\n                    if (pluginsToolbar != null) pluginsToolbar.getComponent().setVisible(false);\n                }\n            }\n        };\n        rHTML.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        rHTML.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n        rHTML.setToolTipText(Bundle.JavaThreadsView_TooltipHTML());\n        resultsBG.add(rHTML);\n        toolbar.add(rHTML);\n        \n        aggregToolbar = ProfilerToolbar.create(false);\n        aggregToolbar.addSpace(8);\n        aggregToolbar.add(new GrayLabel(Bundle.JavaObjectsView_Aggregation()));\n        aggregToolbar.addSpace(2);\n\n        final ButtonGroup aggregationBG = new ButtonGroup();\n        class AggregationButton extends JToggleButton {\n            private final Aggregation aggregation;\n            AggregationButton(Aggregation aggregation, boolean selected) {\n                super(aggregation.getIcon(), selected);\n                this.aggregation = aggregation;\n                setToolTipText(aggregation.toString());\n                aggregationBG.add(this);\n            }\n            protected void fireItemStateChanged(ItemEvent e) {\n                // invoked also from constructor: super(aggregation.getIcon(), selected)\n                // in this case aggregation is still null, ignore the event...\n                if (e.getStateChange() == ItemEvent.SELECTED && aggregation != null) {\n                    setAggregation(aggregation);\n                }\n            }\n        }\n\n        tbName = new AggregationButton(Aggregation.NAMES, Aggregation.NAMES.equals(aggregation));\n        tbName.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        tbName.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        aggregToolbar.add(tbName);\n        tbState = new AggregationButton(Aggregation.STATES, Aggregation.STATES.equals(aggregation));\n        tbState.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        tbState.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n        aggregToolbar.add(tbState);\n        toolbar.add(aggregToolbar);\n\n        if (objectsView.hasPlugins()) {\n            pluginsToolbar = ProfilerToolbar.create(false);\n//            detailsToolbar.addSpace(2);\n//            detailsToolbar.addSeparator();\n            pluginsToolbar.addSpace(8);\n\n            pluginsToolbar.add(new GrayLabel(Bundle.JavaThreadsView_Details()));\n            pluginsToolbar.addSpace(2);\n            \n            pluginsToolbar.add(objectsView.getToolbar());\n            \n            toolbar.add(pluginsToolbar);\n        }\n\n        component = new JPanel(new CardLayout());\n        component.add(objectsView.getComponent());\n        component.add(htmlView.getComponent());\n    }\n    \n    \n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class Provider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (JavaHeapFragment.isJavaHeap(context))\n                return new JavaThreadsView(context, actions);\n            \n            return null;\n        }\n\n    }\n    \n    \n    private static class SelectInstanceAction extends HeapViewerNodeAction {\n        \n        private final long id;\n        private final HeapViewerActions actions;\n        \n        SelectInstanceAction(long id, HeapViewerActions actions) {\n            super(Bundle.JavaThreadsView_SelectAction(), 205);\n            this.id = id;\n            this.actions = actions;\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            JavaThreadsView threadsView = actions.findFeature(JavaThreadsView.class);\n            if (threadsView != null) {\n                actions.selectFeature(threadsView);\n                threadsView.selectInstance(id, VIEW_HTML_ID);\n            }\n        }\n        \n    }\n    \n    @ServiceProvider(service=HeapViewerNodeAction.Provider.class)\n    public static class SelectInstanceActionProvider extends HeapViewerNodeAction.Provider {\n        \n        public boolean supportsView(HeapContext context, String viewID) {\n            return !viewID.startsWith(FEATURE_ID) && JavaHeapFragment.isJavaHeap(context);\n        }\n\n        public HeapViewerNodeAction[] getActions(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n            Heap heap = context.getFragment().getHeap();\n            \n            Instance instance = HeapViewerNode.getValue(node, DataType.INSTANCE, heap);\n            if (instance == null) return null;\n            \n            Collection<GCRoot> gcRoots = heap.getGCRoots(instance);\n            \n            for (GCRoot gcRoot : gcRoots) {\n                String gcRootKind = gcRoot.getKind();\n\n                if (GCRoot.JAVA_FRAME.equals(gcRootKind)) {\n                    JavaFrameGCRoot frameVar = (JavaFrameGCRoot)gcRoot;\n                    if (frameVar.getFrameNumber() != -1) {\n                        return new HeapViewerNodeAction[] { new SelectInstanceAction(instance.getInstanceId(), actions) };\n                    }\n                } else if (GCRoot.JNI_LOCAL.equals(gcRootKind)) {\n                    JniLocalGCRoot frameJni = (JniLocalGCRoot)gcRoot;\n                    if (frameJni.getFrameNumber() != -1) {\n                        return new HeapViewerNodeAction[] { new SelectInstanceAction(instance.getInstanceId(), actions) };\n                    }\n                } else if (GCRoot.THREAD_OBJECT.equals(gcRootKind)) {\n    //                ThreadObjectGCRoot thread = (ThreadObjectGCRoot)gcRoot;\n                    return new HeapViewerNodeAction[] { new SelectInstanceAction(instance.getInstanceId(), actions) };\n                }\n            }\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/JavaWindowsView.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Image;\nimport java.awt.RenderingHints;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ContainerEvent;\nimport java.awt.event.ContainerListener;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.geom.AffineTransform;\nimport java.awt.image.BufferedImage;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Enumeration;\nimport java.util.Iterator;\nimport javax.swing.AbstractButton;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.ButtonGroup;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaWindowsView_Name=Windows\",\n    \"JavaWindowsView_Description=Application Windows\",\n    \"JavaWindowsView_ComputingWindows=computing windows...\",\n    \"JavaWindowsView_Preview=Preview:\",\n    \"JavaWindowsView_150px=150px\",\n    \"JavaWindowsView_Tooltip150px=Window preview height: 150px\",\n    \"JavaWindowsView_300px=300px\",\n    \"JavaWindowsView_Tooltip300px=Window preview height: 300px\",\n    \"JavaWindowsView_600px=600px\",\n    \"JavaWindowsView_Tooltip600px=Window preview height: 600px\",\n    \"JavaWindowsView_50pc=50%\",\n    \"JavaWindowsView_Tooltip50pc=Window preview size: 50%\",\n    \"JavaWindowsView_100pc=100%\",\n    \"JavaWindowsView_Tooltip100pc=Window preview size: 100%\",\n    \"JavaWindowsView_NoPreview=<no preview>\"\n})\nclass JavaWindowsView extends HeapViewerFeature {\n    \n    private static final String FEATURE_ID = \"java_windows\"; // NOI18N\n    \n    private final HeapContext context;\n    private final HeapViewerActions actions;\n    \n    private final Collection<HeapViewerNodeAction.Provider> actionProviders;\n    \n    private JComponent component;\n    private ProfilerToolbar toolbar;\n    \n    private int height;\n    private double scale;\n    \n    private final int estWindowCount;\n    \n    \n    JavaWindowsView(HeapContext context, HeapViewerActions actions, int estWindowCount) {\n        super(FEATURE_ID, Bundle.JavaWindowsView_Name(), Bundle.JavaWindowsView_Description(), Icons.getIcon(HeapWalkerIcons.WINDOW), 400);\n        \n        this.context = context;\n        this.actions = actions;\n        \n        this.estWindowCount = estWindowCount;\n        \n        actionProviders = new ArrayList<>();\n        for (HeapViewerNodeAction.Provider provider : Lookup.getDefault().lookupAll(HeapViewerNodeAction.Provider.class))\n            if (provider.supportsView(context, FEATURE_ID)) actionProviders.add(provider);\n    }\n\n    \n    public JComponent getComponent() {\n        if (component == null) init();\n        return component;\n    }\n\n    public ProfilerToolbar getToolbar() {\n        if (toolbar == null) init();\n        return toolbar;\n    }\n    \n    \n    @Override\n    protected void closed() {\n        // TODO: should cancel the preview\n    }\n    \n    \n    private void init() {\n        component = new JPanel(null);\n        component.setLayout(new BorderLayout());\n        \n        component.setOpaque(false);\n        \n        JLabel progress = new JLabel(Bundle.JavaWindowsView_ComputingWindows(), JLabel.LEADING);\n        progress.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n        final int labelHeight = progress.getPreferredSize().height;\n        component.add(progress, BorderLayout.NORTH);\n        \n        toolbar = ProfilerToolbar.create(false);\n        \n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n        \n        toolbar.add(new GrayLabel(Bundle.JavaWindowsView_Preview()));\n        toolbar.addSpace(3);\n        \n        final ButtonGroup sizes = new ButtonGroup();\n        \n        toolbar.add(new JToggleButton(Bundle.JavaWindowsView_150px()) {\n            {\n                sizes.add(this);\n                putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n                putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n                setToolTipText(Bundle.JavaWindowsView_Tooltip150px());\n            }\n            protected void fireItemStateChanged(ItemEvent event) {\n                if (isSelected()) {\n                    scale = -1;\n                    height = 150;\n                    computeWindows();\n                }\n            }\n        });\n        toolbar.add(new JToggleButton(Bundle.JavaWindowsView_300px()) {\n            {\n                sizes.add(this);\n                putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n                putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n                setToolTipText(Bundle.JavaWindowsView_Tooltip300px());\n            }\n            protected void fireItemStateChanged(ItemEvent event) {\n                if (isSelected()) {\n                    scale = -1;\n                    height = 300;\n                    computeWindows();\n                }\n            }\n        });\n        toolbar.add(new JToggleButton(Bundle.JavaWindowsView_600px()) {\n            {\n                sizes.add(this);\n                putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n                putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n                setToolTipText(Bundle.JavaWindowsView_Tooltip600px());\n            }\n            protected void fireItemStateChanged(ItemEvent event) {\n                if (isSelected()) {\n                    scale = -1;\n                    height = 600;\n                    computeWindows();\n                }\n            }\n        });\n        toolbar.add(new JToggleButton(Bundle.JavaWindowsView_50pc()) {\n            {\n                sizes.add(this);\n                putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n                putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n                setToolTipText(Bundle.JavaWindowsView_Tooltip50pc());\n            }\n            protected void fireItemStateChanged(ItemEvent event) {\n                if (isSelected()) {\n                    scale = 0.5d;\n                    height = -1;\n                    computeWindows();\n                }\n            }\n        });\n        toolbar.add(new JToggleButton(Bundle.JavaWindowsView_100pc()) {\n            {\n                sizes.add(this);\n                putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n                putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n                setToolTipText(Bundle.JavaWindowsView_Tooltip100pc());\n            }\n            protected void fireItemStateChanged(ItemEvent event) {\n                if (isSelected()) {\n                    scale = 1d;\n                    height = -1;\n                    computeWindows();\n                }\n            }\n        });\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                Enumeration<AbstractButton> buttons = sizes.getElements();\n                AbstractButton selected = buttons.nextElement();\n                \n                int height = component.getHeight();\n                int wcount = Math.min(estWindowCount, 3);\n                \n                if (wcount * (labelHeight + 300) <= height) selected = buttons.nextElement();\n                if (wcount * (labelHeight + 600) <= height) selected = buttons.nextElement();\n                \n                selected.setSelected(true);\n            }\n        });\n    }\n    \n    private void computeWindows() {\n        new RequestProcessor(\"Heap Windows Processor\").post(new Runnable() { // NOI18N\n            public void run() {\n                final Heap heap = context.getFragment().getHeap();\n\n                final Collection<Instance> windows = new ArrayList<>();\n                windows.addAll(getVisibleFrames(heap));\n                windows.addAll(getVisibleDialogs(heap));\n\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        JComponent container = new JPanel(null) {\n                            {\n                                setOpaque(true);\n                                setBackground(UIUtils.getProfilerResultsBackground());\n                            }\n                            public Dimension getMinimumSize() {\n                                return getPreferredSize();\n                            }\n                        };\n                        container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS));\n\n                        for (Instance window : windows) {\n                            InstanceNode windowNode = new InstanceNode(window);\n                            \n                            ActionsHandler handler = new ActionsHandler(windowNode);\n                            \n                            WindowPresenter presenter = new WindowPresenter(windowNode, heap);\n                            container.add(new MarginContainer(presenter, BorderLayout.WEST, 15, 10, 0, 10));\n                            handler.install(presenter);\n\n                            WindowPreview preview = new WindowPreview(window, heap, scale, height);\n                            container.add(new MarginContainer(preview, BorderLayout.WEST, 10, 27, 30, 10));\n                            handler.install(preview);\n\n                            container.add(new MarginContainer(UIUtils.createHorizontalSeparator(), 0, 15, 0, 10));\n                        }\n\n                        container.remove(container.getComponentCount() - 1); // remove the last separator\n\n                        container.add(Box.createVerticalGlue());\n\n                        component.removeAll();\n                        component.add(new ScrollableContainer(container), BorderLayout.CENTER);\n\n                        component.invalidate();\n                        Container parent = component.getParent();\n                        if (parent != null) parent.revalidate();\n                        component.repaint();\n                    }\n                });\n            }\n        });\n    }\n    \n    \n    private class ActionsHandler extends MouseAdapter {\n        \n        private final InstanceNode windowNode;\n        \n        \n        ActionsHandler(InstanceNode windowNode) {\n            this.windowNode = windowNode;\n        }\n        \n        \n        public void mouseClicked(MouseEvent e) {\n            if (SwingUtilities.isLeftMouseButton(e)) handleClick(e);\n            if (SwingUtilities.isMiddleMouseButton(e)) handleMiddleClick(e);\n        }\n        \n        public void mousePressed(MouseEvent e) {\n            if (e.isPopupTrigger()) handleShowPopup(e);\n        }\n        \n        public void mouseReleased(MouseEvent e) {\n            if (e.isPopupTrigger()) handleShowPopup(e);\n        }\n        \n        \n        void install(Component c) {\n            c.addMouseListener(this);\n        }\n        \n        \n        private void handleClick(MouseEvent e) {\n            HeapViewerNodeAction.Actions nodeActions = HeapViewerNodeAction.Actions.forNode(windowNode, actionProviders, context, actions);\n            ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), \"left button\", e.getWhen(), e.getModifiers()); // NOI18N\n            nodeActions.performDefaultAction(ae);\n        }\n        \n        private void handleMiddleClick(MouseEvent e) {\n            HeapViewerNodeAction.Actions nodeActions = HeapViewerNodeAction.Actions.forNode(windowNode, actionProviders, context, actions);\n            ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), \"middle button\", e.getWhen(), e.getModifiers()); // NOI18N\n            nodeActions.performMiddleButtonAction(ae);\n        }\n        \n        private void handleShowPopup(MouseEvent e) {\n            JPopupMenu popup = new JPopupMenu();\n            \n            HeapViewerNodeAction.Actions nodeActions = HeapViewerNodeAction.Actions.forNode(windowNode, actionProviders, context, actions);\n            nodeActions.populatePopup(popup);\n            \n            if (popup.getComponentCount() > 0) popup.show((Component)e.getSource(), e.getX(), e.getY());\n        }\n        \n    }\n    \n    \n    private static class MarginContainer extends JPanel {\n        \n        MarginContainer(Component comp, int top, int left, int bottom, int right) {\n            this(comp, BorderLayout.CENTER, top, left, bottom, right);\n        }\n        \n        MarginContainer(Component comp, Object position, int top, int left, int bottom, int right) {\n            super(new BorderLayout());\n            setOpaque(false);\n            setBorder(BorderFactory.createEmptyBorder(top, left, bottom, right));\n            add(comp, position);\n        }\n        \n        public Dimension getMaximumSize() {\n            return new Dimension(super.getMaximumSize().width, super.getPreferredSize().height);\n        }\n        \n    }\n    \n    \n    private static class WindowPresenter extends JPanel {\n        \n        WindowPresenter(InstanceNode windowNode, Heap heap) {\n            super(new BorderLayout());\n            \n            setOpaque(false);\n            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n            \n            InstanceNodeRenderer renderer = new InstanceNodeRenderer(heap);\n            renderer.setValue(windowNode, -1);\n            \n            JComponent rendererC = renderer.getComponent();\n            rendererC.setOpaque(false);\n            add(rendererC, BorderLayout.WEST);\n        }\n        \n    }\n    \n    \n    private static class WindowPreview extends JPanel {\n        \n        private final Instance windowInstance;\n        private final Heap heap;\n        \n        private final double scale;\n        \n        private final int prefHeight;\n        private int realHeight;\n        private int realWidth;\n        \n        private Image windowImage;\n        \n        \n        WindowPreview(Instance windowInstance, Heap heap, double scale, int prefHeight) {\n            super(new BorderLayout());\n            \n            setOpaque(false);\n            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n            \n            this.windowInstance = windowInstance;\n            this.heap = heap;\n            \n            this.scale = scale;\n            \n            this.prefHeight = prefHeight;\n            this.realHeight = prefHeight;\n            this.realWidth = -1;\n            \n            createPreview();\n        }\n        \n        \n        public void paint(Graphics g) {\n            if (windowImage != null) {\n                g.drawImage(windowImage, 0, 0, null);\n            } else {\n                super.paint(g);\n            }\n        }\n        \n        \n        public Dimension getPreferredSize() {\n            int width = realWidth == -1 ? super.getPreferredSize().width : realWidth;\n            return new Dimension(width, realHeight);\n        }\n        \n        \n        public Dimension getMinimumSize() {\n            return new Dimension(0, realHeight);\n        }\n        \n        public Dimension getMaximumSize() {\n            return new Dimension(Integer.MAX_VALUE, realHeight);\n        }\n        \n        \n        private void createPreview() {\n            final JComponent windowComponent = DetailsSupport.getDetailsView(windowInstance);\n            if (windowComponent != null) {\n                final Component progress = windowComponent.getComponent(0);\n                \n                windowComponent.addContainerListener(new ContainerListener() {\n                    private boolean progressRemoved = false;\n\n                    // handle adding the actual preview\n                    public void componentAdded(ContainerEvent e) {\n                        if (progressRemoved && windowComponent.getComponentCount() == 2) {\n                            windowComponent.removeContainerListener(this);\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    Component c = windowComponent.getComponent(1);\n                                    c.setMinimumSize(c.getPreferredSize());\n                                    \n                                    c.invalidate();\n                                    Container parent = c.getParent();\n                                    if (parent != null) parent.revalidate();\n                                    c.doLayout();\n\n                                    double ratio;\n                                    Dimension winSize = c.getSize();\n                                    if (scale > 0 && scale < 1) { // scaled window\n                                        ratio = scale;\n                                        realHeight = (int)(ratio * winSize.height) + 1;\n                                        realWidth = (int)(ratio * winSize.width) + 1;\n                                    } else if (scale >= 1 || winSize.height <= prefHeight) { // real window\n                                        ratio = 1;\n                                        realHeight = winSize.height;\n                                        realWidth = winSize.width;\n                                    } else { // fixed-height window\n                                        ratio = (double)prefHeight / winSize.height;\n                                        realHeight = prefHeight;\n                                        realWidth = (int)(ratio * winSize.width) + 1;\n                                    }\n                                    \n                                    // WindowPreview.this.createImage correctly renders text, BufferedImage does better interpolation\n                                    windowImage = ratio == 1 ? WindowPreview.this.createImage(realWidth, realHeight) :\n                                                  new BufferedImage(realWidth, realHeight, BufferedImage.TYPE_INT_ARGB);\n                                    \n                                    Graphics g = windowImage.getGraphics();\n                                    if (g instanceof Graphics2D) {\n                                        Graphics2D g2 = (Graphics2D)g;\n                                        g2.setTransform(AffineTransform.getScaleInstance(ratio, ratio));\n                                        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);\n                                    }\n                                    c.paint(g);\n                                    g.dispose();\n                                    \n                                    WindowPreview.this.removeAll();\n                                    WindowPreview.this.repaint();\n                                }\n                            });\n                        }\n                    }\n\n                    // handle removing the progress label\n                    public void componentRemoved(ContainerEvent e) {\n                        if (e.getChild() == progress) progressRemoved = true;\n                    }\n                });\n                \n                add(windowComponent, BorderLayout.WEST);\n            } else {\n                JLabel noPreview = new JLabel(Bundle.JavaWindowsView_NoPreview(), JLabel.LEADING);\n                noPreview.setBorder(BorderFactory.createEmptyBorder(5, 20, 5, 20));\n                noPreview.setEnabled(false);\n                \n                Dimension pref = noPreview.getPreferredSize();\n                realWidth = pref.width;\n                realHeight = pref.height;\n                add(noPreview, BorderLayout.CENTER);\n            }\n        }\n        \n    }\n    \n    \n    private static Collection<Instance> getVisibleFrames(Heap heap) {\n        Collection<JavaClass> framesC = HeapUtils.getSubclasses(heap, \"java.awt.Frame\"); // NOI18N\n        \n        Collection<Instance> framesI = new ArrayList<>();\n        for (JavaClass frameC : framesC) framesI.addAll(frameC.getInstances());\n        \n        return onlyVisible(framesI);\n    }\n    \n    private static Collection<Instance> getVisibleDialogs(Heap heap) {\n        Collection<JavaClass> dialogsC = HeapUtils.getSubclasses(heap, \"java.awt.Dialog\"); // NOI18N\n        \n        Collection<Instance> dialogsI = new ArrayList<>();\n        for (JavaClass dialogC : dialogsC) dialogsI.addAll(dialogC.getInstances());\n        \n        return onlyVisible(dialogsI);\n    }\n    \n    private static Collection<Instance> onlyVisible(Collection<Instance> instances) {\n        Iterator<Instance> framesIt = instances.iterator();\n        while (framesIt.hasNext())\n            if (!DetailsUtils.getBooleanFieldValue(framesIt.next(), \"visible\", false)) // NOI18N\n                framesIt.remove();\n        return instances;\n    }\n    \n    \n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class Provider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (!JavaHeapFragment.isJavaHeap(context)) return null;\n            \n            Heap heap = context.getFragment().getHeap();\n            int estWindowsCount = getVisibleFrames(heap).size();\n            if (estWindowsCount <= 1) estWindowsCount += getVisibleDialogs(heap).size();\n            \n            return estWindowsCount == 0 ? null : new JavaWindowsView(context, actions, estWindowsCount);\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/java/impl/PathToGCRootPlugin.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.java.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.text.NumberFormat;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.ClassNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNodeRenderer;\nimport org.graalvm.visualvm.heapviewer.java.InstanceReferenceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstancesWrapper;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.ErrorNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.swing.LinkButton;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.HeapOperations;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Value;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.MultiRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"PathToGCRootPlugin_Name=GC Root\",\n    \"PathToGCRootPlugin_Description=GC Root\",\n    \"PathToGCRootPlugin_NoRoot=<no GC root>\",\n    \"PathToGCRootPlugin_IsRoot=<node is GC root>\",\n    \"PathToGCRootPlugin_NoSelection=<no class or instance selected>\",\n    \"PathToGCRootPlugin_MoreNodes=<another {0} GC roots left>\",\n    \"PathToGCRootPlugin_SamplesContainer=<sample {0} GC roots>\",\n    \"PathToGCRootPlugin_NodesContainer=<GC roots {0}-{1}>\",\n    \"PathToGCRootPlugin_ComputeMergedRootsLbl=Compute Merged GC Roots\",\n    \"PathToGCRootPlugin_ComputeMergedRootsTtp=Compute merged GC roots for the selected class\",\n    \"PathToGCRootPlugin_AutoComputeMergedRootsLbl=Compute Merged GC Roots Automatically\",\n    \"PathToGCRootPlugin_AutoComputeMergedRootsTtp=Compute merged GC roots automatically for each selected class\"\n})\npublic class PathToGCRootPlugin extends HeapViewPlugin {\n    \n    private static final TreeTableView.ColumnConfiguration CCONF_CLASS = new TreeTableView.ColumnConfiguration(DataType.COUNT, null, DataType.COUNT, SortOrder.DESCENDING, Boolean.FALSE);\n    private static final TreeTableView.ColumnConfiguration CCONF_INSTANCE = new TreeTableView.ColumnConfiguration(null, DataType.COUNT, DataType.NAME, SortOrder.UNSORTED, null);\n    \n    private final Heap heap;\n    private HeapViewerNode selected;\n    \n    private volatile boolean mergedRequest;\n    \n    private final TreeTableView objectsView;\n    \n    private volatile boolean showingClass;\n    \n    \n    public PathToGCRootPlugin(HeapContext context, HeapViewerActions actions) {\n        super(Bundle.PathToGCRootPlugin_Name(), Bundle.PathToGCRootPlugin_Description(), Icons.getIcon(ProfilerIcons.RUN_GC));\n        \n        heap = context.getFragment().getHeap();\n        \n        TreeTableViewColumn count;\n        TreeTableViewColumn[] columns = new TreeTableViewColumn[] {\n            new TreeTableViewColumn.Name(),\n            new TreeTableViewColumn.LogicalValue(),\n            count = new TreeTableViewColumn.Count(heap, true, true),\n            new TreeTableViewColumn.OwnSize(heap, false, false),\n            new TreeTableViewColumn.RetainedSize(heap, false, false),\n            new TreeTableViewColumn.ObjectID()\n        };\n        objectsView = new TreeTableView(\"java_objects_gcroots\", context, actions, columns) { // NOI18N\n            protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                if (mergedRequest) return HeapViewerNode.NO_NODES;\n                \n                HeapViewerNode _selected;\n                synchronized (objectsView) { _selected = selected; }\n\n                if (_selected == null) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            if (!CCONF_INSTANCE.equals(objectsView.getCurrentColumnConfiguration()))\n                                objectsView.configureColumns(CCONF_INSTANCE);\n                        }\n                    });\n                    \n                    return new HeapViewerNode[] { new TextNode(Bundle.PathToGCRootPlugin_NoSelection()) };\n                }\n\n                Instance instance;\n                InstancesWrapper wrapper = HeapViewerNode.getValue(_selected, DataType.INSTANCES_WRAPPER, heap);\n                if (wrapper != null) {\n                    instance = null;\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n//                            if (!mergedRoots && !CCONF_INSTANCE.equals(objectsView.getCurrentColumnConfiguration()))\n//                                objectsView.configureColumns(CCONF_INSTANCE);\n//                            else if (mergedRoots && !CCONF_CLASS.equals(objectsView.getCurrentColumnConfiguration()))\n//                                objectsView.configureColumns(CCONF_CLASS);\n                            if (!CCONF_CLASS.equals(objectsView.getCurrentColumnConfiguration()))\n                                objectsView.configureColumns(CCONF_CLASS);\n                        }\n                    });\n\n//                    if (!mergedRoots) return new HeapViewerNode[] { new TextNode(\"<merged GC roots disabled>\") };\n                } else {\n                    instance = HeapViewerNode.getValue(_selected, DataType.INSTANCE, heap);\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            if (!CCONF_INSTANCE.equals(objectsView.getCurrentColumnConfiguration()))\n                                objectsView.configureColumns(CCONF_INSTANCE);\n                        }\n                    });\n\n                    if (instance == null) return new HeapViewerNode[] { new TextNode(Bundle.PathToGCRootPlugin_NoSelection()) };\n                }\n                \n                HeapOperations.initializeGCRoots(heap);\n\n                Collection<HeapViewerNode> data;\n                if (instance != null) {\n                    data = computeInstanceRoots(instance, progress);\n                    if (data != null) showingClass = false;\n                } else {\n                    ((HideableBarRenderer)count.getRenderer()).setMaxValue(wrapper.getInstancesCount());\n                    data = computeInstancesRoots(wrapper.getInstancesIterator(), wrapper.getInstancesCount(), progress);\n                    if (data != null) showingClass = true;\n                }\n\n                if (data == null) return null;\n                if (data.size() == 1) return new HeapViewerNode[] { data.iterator().next() };\n\n                final Collection<HeapViewerNode> _data = data;\n                NodesComputer<HeapViewerNode> computer = new NodesComputer<HeapViewerNode>(_data.size(), UIThresholds.MAX_MERGED_OBJECTS) {\n                    protected boolean sorts(DataType dataType) {\n                        return true;\n                    }\n                    protected HeapViewerNode createNode(HeapViewerNode node) {\n                        return node;\n                    }\n                    protected ProgressIterator<HeapViewerNode> objectsIterator(int index, Progress progress) {\n                        Iterator<HeapViewerNode> iterator = _data.iterator();\n                        return new ProgressIterator<>(iterator, index, true, progress);\n                    }\n                    protected String getMoreNodesString(String moreNodesCount)  {\n                        return Bundle.PathToGCRootPlugin_MoreNodes(moreNodesCount);\n                    }\n                    protected String getSamplesContainerString(String objectsCount)  {\n                        return Bundle.PathToGCRootPlugin_SamplesContainer(objectsCount);\n                    }\n                    protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                        return Bundle.PathToGCRootPlugin_NodesContainer(firstNodeIdx, lastNodeIdx);\n                    }\n                };\n\n                return computer.computeNodes(root, heap, viewID, null, dataTypes, sortOrders, progress);\n            }\n            @Override\n            protected void populatePopup(HeapViewerNode node, JPopupMenu popup) {\n                if (popup.getComponentCount() > 0) popup.addSeparator();\n                \n                popup.add(new JCheckBoxMenuItem(Bundle.PathToGCRootPlugin_AutoComputeMergedRootsLbl(), isAutoMerge()) {\n                    @Override\n                    protected void fireActionPerformed(ActionEvent event) {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            @Override\n                            public void run() {\n                                setAutoMerge(isSelected());\n                            }\n                        });\n                    }\n                });\n            }\n            protected void childrenChanged() {\n                if (!showingClass) fullyExpandNode(getRoot());\n            }\n            protected void nodeExpanded(HeapViewerNode node) {\n                if (showingClass && node instanceof GCInstanceNode) fullyExpandNode(node);\n            }\n            private void fullyExpandNode(HeapViewerNode node) {\n                while (node != null) {\n                    expandNode(node);\n                    node = node.getNChildren() > 0 ? node.getChild(0) : null;\n                }\n            }\n        };\n    }\n    \n    \n    private JComponent component;\n    \n    private void showObjectsView() {\n        JComponent c = objectsView.getComponent();\n        if (c.isVisible()) return;\n        \n        c.setVisible(true);\n        \n        component.removeAll();\n        component.add(c, BorderLayout.CENTER);\n        \n        mergedRequest = false;\n        \n        component.invalidate();\n        component.revalidate();\n        component.repaint();\n    }\n    \n    private void showMergedView() {\n        JComponent c = objectsView.getComponent();\n        if (!c.isVisible()) return;\n        \n        c.setVisible(false);\n        \n        component.removeAll();\n        \n        JButton jb = new JButton(Bundle.PathToGCRootPlugin_ComputeMergedRootsLbl(), Icons.getIcon(ProfilerIcons.RUN_GC)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                showObjectsView();\n                objectsView.reloadView();\n            }\n        };\n        jb.setIconTextGap(jb.getIconTextGap() + 2);\n        jb.setToolTipText(Bundle.PathToGCRootPlugin_ComputeMergedRootsTtp());\n        Insets margin = jb.getMargin();\n        if (margin != null) jb.setMargin(new Insets(margin.top + 3, margin.left + 3, margin.bottom + 3, margin.right + 3));\n        \n        \n        LinkButton lb = new LinkButton(Bundle.PathToGCRootPlugin_AutoComputeMergedRootsLbl()) {\n            protected void fireActionPerformed(ActionEvent e) {\n                setAutoMerge(true);\n                showObjectsView();\n                objectsView.reloadView();\n            }\n        };\n        lb.setToolTipText(Bundle.PathToGCRootPlugin_AutoComputeMergedRootsTtp());\n                \n        \n        JPanel p = new JPanel(new GridBagLayout());\n        p.setOpaque(false);\n        GridBagConstraints g;\n        \n        g = new GridBagConstraints();\n        g.fill = GridBagConstraints.HORIZONTAL;\n        g.gridy = 0;\n        p.add(jb, g);\n        \n        g = new GridBagConstraints();\n        g.fill = GridBagConstraints.HORIZONTAL;\n        g.gridy = 1;\n        g.insets = new Insets(10, 0, 0, 0);\n        p.add(lb, g);\n        \n        component.add(p);\n        \n        mergedRequest = true;\n\n        component.invalidate();\n        component.revalidate();\n        component.repaint();\n    }\n\n    protected JComponent createComponent() {\n        component = new JPanel(new BorderLayout());\n        component.setOpaque(true);\n        component.setBackground(UIUtils.getProfilerResultsBackground());\n        \n        objectsView.getComponent().setVisible(false); // force init in showObjectsView()\n        showObjectsView();\n        \n        return component;\n    }\n        \n    @Override\n    protected void nodeSelected(final HeapViewerNode node, boolean adjusting) {\n        synchronized (objectsView) {\n            if (Objects.equals(selected, node)) return;\n            selected = node;\n        }\n        \n        if (selected != null && !isAutoMerge() && HeapViewerNode.getValue(selected, DataType.INSTANCES_WRAPPER, heap) != null) showMergedView();\n        else showObjectsView();\n        \n        objectsView.reloadView();\n    }\n    \n    \n    @Override\n    protected void closed() {\n        synchronized (objectsView) { selected = objectsView.getRoot(); }\n        objectsView.closed();\n    }\n    \n    \n    private static Collection<HeapViewerNode> computeInstanceRoots(Instance instance, Progress progress) throws InterruptedException {\n        Instance nextInstance = instance.getNearestGCRootPointer();\n                    \n        if (nextInstance == null) {\n            return Collections.singleton(new TextNode(Bundle.PathToGCRootPlugin_NoRoot()));\n        } else if (nextInstance == instance) {\n            return Collections.singleton(new TextNode(Bundle.PathToGCRootPlugin_IsRoot()));\n        } else {\n            ToRoot node = null;\n            ToRoot firstNode = null;\n            ToRoot previousNode = null;\n            \n            try {\n                progress.setupUnknownSteps();\n                \n                Thread current = Thread.currentThread();\n                while (!current.isInterrupted() && instance != nextInstance) {\n                    List<Value> references = instance.getReferences();\n                    for (Value reference : references) {\n                        if (nextInstance.equals(reference.getDefiningInstance())) {\n                            if (reference instanceof ObjectFieldValue) {\n                                ObjectFieldValue ref = (ObjectFieldValue)reference;\n                                SkipNode snode = HeapPatterns.processGCRootReference(ref);\n                                if (snode != null) {\n                                    ref = snode.getValue();\n                                    nextInstance = ref.getDefiningInstance();\n                                    node = snode;\n                                    if (firstNode == null) firstNode = node;\n                                    else previousNode.setChildren(new HeapViewerNode[] { (HeapViewerNode)node });\n                                    previousNode = node;\n                                }\n                                node = new FieldToRoot(ref);\n                            } else if (reference instanceof ArrayItemValue) {\n                                node = new ArrayItemToRoot((ArrayItemValue)reference);\n                            }\n\n                            if (firstNode == null) firstNode = node;\n                            else previousNode.setChildren(new HeapViewerNode[] { (HeapViewerNode)node });\n\n                            break;\n                        }\n                    }\n\n                    instance = nextInstance;\n                    nextInstance = instance.getNearestGCRootPointer();\n                    progress.step();\n\n                    previousNode = node;\n                }\n                if (current.isInterrupted()) throw new InterruptedException();\n                \n                if (node != null) node.setChildren(HeapViewerNode.NO_NODES);\n            } finally {           \n                progress.finish();\n            }\n            \n            return Collections.singleton((HeapViewerNode) firstNode);\n        }\n    }\n    \n    private static Collection<HeapViewerNode> computeInstancesRoots(Iterator<Instance> instances, int count, Progress progress) throws InterruptedException {\n        Map<Instance, HeapViewerNode> gcRoots = new HashMap<>();\n        Map<Instance,Instance> gcRootCache = new HashMap<>();\n        \n        try {\n            progress.setupKnownSteps(count);\n            \n            Thread current = Thread.currentThread();\n            while (!current.isInterrupted() && instances.hasNext()) {\n                Instance instance = instances.next();\n                Instance gcRoot = getGCRoot(instance, current, gcRootCache);\n                GCRootNode gcRootNode = (GCRootNode)gcRoots.get(gcRoot);\n                if (gcRootNode == null) {\n                    gcRootNode = new GCRootNode(gcRoot);\n                    gcRoots.put(gcRoot, gcRootNode);\n                }\n                gcRootNode.addInstance(instance);\n                progress.step();\n            }\n            if (current.isInterrupted()) throw new InterruptedException();\n        } catch (OutOfMemoryError e) {\n            System.err.println(\"Out of memory in PathToGCRootPlugin: \" + e.getMessage()); // NOI18N\n            HeapUtils.handleOOME(true, e);\n            return Collections.singleton(new ErrorNode.OOME());\n        } finally {\n            progress.finish();\n        }\n        \n        if (!gcRoots.isEmpty()) return gcRoots.values();\n        else return Collections.singleton(new TextNode(Bundle.PathToGCRootPlugin_NoRoot()));\n    }\n    \n    private static final int MARKER_DISTANCE = 1000;\n    private static Instance getGCRoot(Instance instance, Thread current, Map<Instance,Instance> cache) {\n        List<Instance> markers = new ArrayList<>();\n        int i = 1;\n        while (!instance.isGCRoot()) {\n            // check cache first\n            Instance gcRoot = cache.get(instance);\n            if (gcRoot != null) {\n                instance = gcRoot;\n                break;\n            }\n            if (i++ % MARKER_DISTANCE == 0) markers.add(instance);\n            instance = instance.getNearestGCRootPointer();\n            if (current.isInterrupted() || instance == null) return null;\n        }\n        for (Instance m : markers) {\n            cache.put(m, instance);\n        }\n        return instance;\n    }\n    \n    \n    private static final String KEY_MERGED_GCROOTS = \"HeapViewer.autoMergedGcRoots\"; // NOI18N\n    \n    private boolean isAutoMerge() {\n        return NbPreferences.root().getBoolean(KEY_MERGED_GCROOTS, false);\n    }\n\n    private void setAutoMerge(boolean value) {\n        NbPreferences.root().putBoolean(KEY_MERGED_GCROOTS, value);\n    }\n    \n    \n    @NbBundle.Messages({\n        \"GCRootNode_MoreNodes=<another {0} instances left>\",\n        \"GCRootNode_SamplesContainer=<sample {0} instances>\",\n        \"GCRootNode_NodesContainer=<instances {0}-{1}>\"\n    })\n    static class GCRootNode extends InstanceNode.IncludingNull {\n        \n//        private final int maxNodes = UIThresholds.MAX_MERGED_OBJECTS;\n        \n        private final List<Instance> instances = new ArrayList<>();\n        \n        \n        GCRootNode(Instance gcRoot) {\n            super(gcRoot);\n        }\n        \n        \n        void addInstance(Instance instance) {\n            instances.add(instance);\n        }\n        \n        \n        public int getCount() {\n            return instances.size();\n        }\n        \n        \n//        protected HeapViewerNode[] computeChildren(RootNode root) {\n//            int itemsCount = instances.size();\n//            if (itemsCount <= maxNodes) {\n//                HeapViewerNode[] nodes = new HeapViewerNode[itemsCount];\n//                for (int i = 0; i < itemsCount; i++) nodes[i] = createNode(instances.get(i));\n//                return nodes;\n//            } else {\n//                return super.computeChildren(root);\n//            }\n//        }\n\n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            final Instance gcRoot = getInstance();\n            final boolean isArray = gcRoot != null && gcRoot.getJavaClass().isArray();\n            NodesComputer<Instance> computer = new NodesComputer<Instance>(instances.size(), UIThresholds.MAX_MERGED_OBJECTS) {\n                protected boolean sorts(DataType dataType) {\n                    if (DataType.COUNT.equals(dataType) || (DataType.OWN_SIZE.equals(dataType) && !isArray)) return false;\n                    return true;\n                }\n                protected HeapViewerNode createNode(Instance object) {\n                    return new GCInstanceNode(object) {\n                        public boolean isLeaf() { return gcRoot == null; }\n                    };\n                }\n                protected ProgressIterator<Instance> objectsIterator(int index, Progress progress) {\n                    Iterator<Instance> iterator = instances.listIterator(index);\n                    return new ProgressIterator<>(iterator, index, false, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.GCRootNode_MoreNodes(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.GCRootNode_SamplesContainer(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.GCRootNode_NodesContainer(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            return computer.computeNodes(GCRootNode.this, heap, viewID, null, dataTypes, sortOrders, progress);\n        }\n        \n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.COUNT) return getCount();\n\n            return super.getValue(type, heap);\n        }\n        \n        \n        public boolean isLeaf() {\n            return false;\n        }\n        \n        \n        static class Renderer extends InstanceNodeRenderer {\n            \n            private static final ImageIcon ICON = Icons.getImageIcon(ProfilerIcons.NODE_FORWARD);\n        \n            Renderer(Heap heap) {\n                super(heap);\n            }\n            \n            @Override\n            public void setValue(Object value, int row) {\n                if (value != null) {\n                    GCRootNode node = (GCRootNode)value;\n                    if (node.getInstance() == null) {\n                        setNormalValue(Bundle.PathToGCRootPlugin_NoRoot());\n                        setBoldValue(\"\"); // NOI18N\n                        setGrayValue(\"\"); // NOI18N\n                        setIcon(ICON);\n                        return;\n                    }\n                }\n                super.setValue(value, row);\n                \n                setIconTextGap(4);\n                ((LabelRenderer)valueRenderers()[0]).setMargin(3, 3, 3, 0);\n            }\n            \n            @Override\n            protected ImageIcon getIcon(Instance instance, boolean isGCRoot) {\n                return ICON;\n            }\n\n        }\n        \n    }\n    \n    private static class GCInstanceNode extends InstanceNode {\n    \n        GCInstanceNode(Instance instance) {\n            super(instance);\n        }\n        \n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            Collection<HeapViewerNode> nodes = PathToGCRootPlugin.computeInstanceRoots(getInstance(), progress);\n            return nodes == null ? null : nodes.toArray(HeapViewerNode.NO_NODES);\n        }\n    \n    }\n    \n    private static interface ToRoot {\n        \n        public void setChildren(HeapViewerNode[] ch);\n        \n    }\n    \n    private static class FieldToRoot extends InstanceReferenceNode.Field implements ToRoot {\n        \n        FieldToRoot(ObjectFieldValue value) {\n            super(value, true);\n        }\n        \n        public void setChildren(HeapViewerNode[] ch) {\n            super.setChildren(ch);\n        }\n        \n    }\n    \n    private static class ArrayItemToRoot extends InstanceReferenceNode.ArrayItem implements ToRoot {\n        \n        ArrayItemToRoot(ArrayItemValue value) {\n            super(value, true);\n        } \n        \n        public void setChildren(HeapViewerNode[] ch) {\n            super.setChildren(ch);\n        }\n        \n    }\n    \n    static class SkipNode extends FieldToRoot {\n\n        private int skipped;\n\n        SkipNode(ObjectFieldValue ref, int sk) {\n            super(ref);\n            skipped = sk;\n        }\n    }\n\n    @NbBundle.Messages({\n        \"# {0} - number of skipped nodes\",\n        \"SkipNodeRenderer_Instances=in {0} collapsed instances of \"\n    })\n    static class SkipNodeRenderer extends MultiRenderer implements HeapViewerRenderer {\n\n        private final NormalBoldGrayRenderer nameRenderer;\n        private final LabelRenderer equalsRenderer;\n        private final ClassNodeRenderer classRenderer;\n        private final ProfilerRenderer[] renderers;\n        private final Heap heap;\n\n        SkipNodeRenderer(Heap heap) {\n            this.heap = heap;\n            nameRenderer = new NormalBoldGrayRenderer() {\n                public void setValue(Object value, int row) {\n                    SkipNode node = (SkipNode) value;\n                    String name = node.getFieldName();\n                    if (name.startsWith(\"static \")) { // NOI18N\n                        setNormalValue(\"static \"); // NOI18N\n                        setBoldValue(name.substring(\"static \".length())); // NOI18N\n                    } else {\n                        setNormalValue(\"\"); // NOI18N\n                        setBoldValue(name);\n                    }\n                    setIcon(Icons.getIcon(ProfilerIcons.NODE_REVERSE));\n                }\n            };\n            equalsRenderer = new LabelRenderer() {\n                public void setValue(Object value, int row) {\n                    SkipNode node = (SkipNode) value;\n                    setText(Bundle.SkipNodeRenderer_Instances(NumberFormat.getInstance().format(node.skipped)));\n                    setMargin(3, 2, 3, 0);\n                }\n\n                public String toString() {\n                    return \" \" + getText() + \" \"; // NOI18N\n                }\n            };\n            classRenderer = new ClassNodeRenderer(heap);\n            renderers = new ProfilerRenderer[]{nameRenderer, equalsRenderer, classRenderer};\n        }\n\n        public Icon getIcon() {\n            return nameRenderer.getIcon();\n        }\n\n        public String getShortName() {\n            return nameRenderer.toString();\n        }\n\n        protected ProfilerRenderer[] valueRenderers() {\n            return renderers;\n        }\n\n        public void setValue(Object value, int row) {\n            HeapViewerNode node = (HeapViewerNode) value;\n\n            nameRenderer.setValue(node, row);\n            equalsRenderer.setValue(node, row);\n            classRenderer.setValue(new ClassNode(((SkipNode) node).getJavaClass()), row);\n        }\n    }\n\n    @ServiceProvider(service = HeapViewerRenderer.Provider.class)\n    public static class PathToGCRootRendererProvider extends HeapViewerRenderer.Provider {\n\n        @Override\n        public boolean supportsView(HeapContext context, String viewID) {\n            return \"java_objects_gcroots\".equals(viewID); // NOI18N\n        }\n\n        @Override\n        public void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers, HeapContext context) {\n            renderers.put(SkipNode.class, new SkipNodeRenderer(context.getFragment().getHeap()));\n        }\n\n    }\n\n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 400)\n    public static class Provider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!viewID.startsWith(\"diff\") && JavaHeapFragment.isJavaHeap(context)) return new PathToGCRootPlugin(context, actions); // NOI18N\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/ContainerNode.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.model;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ContainerNode_MoreNodes=<another {0} nodes left>\",\n    \"ContainerNode_SamplesContainer=<sample {0} nodes>\",\n    \"ContainerNode_NodesContainer=<nodes {0}-{1}>\"\n})\npublic abstract class ContainerNode<T> extends HeapViewerNode {\n    \n    protected final int maxNodes;\n    protected final List<T> items;\n    \n    protected final String name;\n    \n    protected int count = DataType.COUNT.getUnsupportedValue();\n    protected long ownSize = DataType.OWN_SIZE.getUnsupportedValue();\n    protected long retainedSize = DataType.RETAINED_SIZE.getUnsupportedValue();\n    \n    \n    public ContainerNode(String name) {\n        this(name, Integer.MAX_VALUE);\n    }\n\n    public ContainerNode(String name, int maxNodes) {\n        this.name = name;\n        this.maxNodes = maxNodes;\n        \n        items = new ArrayList<>();\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public int getCount() {\n        return count;\n    }\n\n    public long getOwnSize() {\n        return ownSize;\n    }\n\n    public long getRetainedSize(Heap heap) {\n        if (retainedSize == DataType.RETAINED_SIZE.getNotAvailableValue().longValue() &&\n            DataType.RETAINED_SIZE.valuesAvailable(heap)) {\n            retainedSize = 0;\n            for (T item : items) retainedSize += getRetainedSize(item, heap);\n        }\n        return retainedSize;\n    }\n    \n    \n    protected abstract HeapViewerNode createNode(T item);\n    \n    \n    protected int getCount(T item, Heap heap) {\n        return DataType.COUNT.getUnsupportedValue();\n    }\n    \n    protected long getOwnSize(T item, Heap heap) {\n        return DataType.OWN_SIZE.getUnsupportedValue();\n    }\n    \n    protected long getRetainedSize(T item, Heap heap) {\n        return DataType.RETAINED_SIZE.getUnsupportedValue();\n    }\n    \n    \n    protected boolean sorts(DataType dataType) {\n        return true;\n    }\n    \n    protected String getMoreNodesString(String moreNodesCount)  {\n        return Bundle.ContainerNode_MoreNodes(moreNodesCount);\n    }\n    \n    protected String getSamplesContainerString(String objectsCount)  {\n        return Bundle.ContainerNode_SamplesContainer(objectsCount);\n    }\n    \n    protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n        return Bundle.ContainerNode_NodesContainer(firstNodeIdx, lastNodeIdx);\n    }\n\n    \n    public String toString() {\n        return name;\n    }\n    \n    \n    public void add(T item, Heap heap) {\n        items.add(item);\n        \n        int _count = getCount(item, heap);\n        if (_count >= 0) { // NOTE: assumes that any positive value is not a special value\n            if (count < 0) count = 0;\n            count += _count;\n        }\n\n        long _ownSize = getOwnSize(item, heap);\n        if (_ownSize >= 0) { // NOTE: assumes that any positive value is not a special value\n            if (ownSize < 0) ownSize = 0;\n            ownSize += _ownSize;\n        }\n        \n        if (retainedSize != DataType.RETAINED_SIZE.getNotAvailableValue().longValue()) {\n            long _retainedSize = getRetainedSize(item, heap);\n            if (_retainedSize >= 0) { // NOTE: assumes that any positive value is not a special value\n                if (retainedSize < 0) retainedSize = 0;\n                retainedSize += _retainedSize;\n            } else if (_retainedSize == DataType.RETAINED_SIZE.getNotAvailableValue().longValue()) {\n                retainedSize = _retainedSize;\n            }\n        }\n    }\n    \n    public List<T> getItems() {\n        return Collections.unmodifiableList(items);\n    }\n    \n    \n    protected HeapViewerNode[] computeChildren(RootNode root) {\n        int itemsCount = items.size();\n        if (itemsCount <= maxNodes) {\n            HeapViewerNode[] nodes = new HeapViewerNode[itemsCount];\n            for (int i = 0; i < itemsCount; i++) nodes[i] = createNode(items.get(i));\n            return nodes;\n        } else {\n            return super.computeChildren(root);\n        }\n    }\n\n    protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        NodesComputer<T> computer = new NodesComputer<T>(items.size(), maxNodes) {\n            protected boolean sorts(DataType dataType) {\n                return ContainerNode.this.sorts(dataType);\n            }\n            protected HeapViewerNode createNode(T object) {\n                return ContainerNode.this.createNode(object);\n            }\n            protected ProgressIterator<T> objectsIterator(int index, Progress progress) {\n                Iterator<T> iterator = items.listIterator(index);\n                return new ProgressIterator<>(iterator, index, false, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return ContainerNode.this.getMoreNodesString(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return ContainerNode.this.getSamplesContainerString(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return ContainerNode.this.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n            }\n        };\n        return computer.computeNodes(ContainerNode.this, heap, viewID, null, dataTypes, sortOrders, progress);\n    }\n    \n    \n    public boolean equals(Object o) {\n        if (o == this) return true;\n        if (!(o instanceof ContainerNode)) return false;\n        return name.equals(((ContainerNode)o).name);\n    }\n    \n    public int hashCode() {\n        return name.hashCode();\n    }\n    \n\n    public boolean isLeaf() {\n        return items.isEmpty();\n    }\n    \n    \n    protected Object getValue(DataType type, Heap heap) {\n        if (type == DataType.NAME) return getName();\n        if (type == DataType.COUNT) return getCount();\n        if (type == DataType.OWN_SIZE) return getOwnSize();\n        if (type == DataType.RETAINED_SIZE) return getRetainedSize(heap);\n        \n        return super.getValue(type, heap);\n    }\n    \n    \n    public static class Nodes<T extends HeapViewerNode> extends ContainerNode<T> {\n        \n        public Nodes(String name) {\n            this(name, Integer.MAX_VALUE);\n        }\n        \n        public Nodes(String name, int maxNodes) {\n            super(name, maxNodes);\n        }\n        \n        protected int getCount(T item, Heap heap) {\n            return HeapViewerNode.getValue(item, DataType.COUNT, heap);\n        }\n\n        protected long getOwnSize(T item, Heap heap) {\n            return HeapViewerNode.getValue(item, DataType.OWN_SIZE, heap);\n        }\n\n        protected long getRetainedSize(T item, Heap heap) {\n            return HeapViewerNode.getValue(item, DataType.RETAINED_SIZE, heap);\n        }\n        \n        protected HeapViewerNode[] computeChildren(RootNode root) {\n            if (items.size() <= maxNodes) {\n                return items.toArray(HeapViewerNode.NO_NODES);\n            } else {\n                return super.computeChildren(root);\n            }\n        }\n\n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            NodesComputer<T> computer = new NodesComputer<T>(items.size(), maxNodes) {\n                protected boolean sorts(DataType dataType) {\n                    return ContainerNode.Nodes.this.sorts(dataType);\n                }\n                protected HeapViewerNode createNode(T object) {\n                    return object;\n                }\n                protected ProgressIterator<T> objectsIterator(int index, Progress progress) {\n                    Iterator<T> iterator = items.listIterator(index);\n                    return new ProgressIterator<>(iterator, index, false, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return ContainerNode.Nodes.this.getMoreNodesString(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return ContainerNode.Nodes.this.getSamplesContainerString(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return ContainerNode.Nodes.this.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            return computer.computeNodes(ContainerNode.Nodes.this, heap, viewID, null, dataTypes, sortOrders, progress);\n        }\n\n        protected HeapViewerNode createNode(HeapViewerNode item) {\n            throw new UnsupportedOperationException(\"Not supported\"); // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/DataType.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.model;\n\nimport java.lang.ref.WeakReference;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.WeakHashMap;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.heapviewer.java.InstancesWrapper;\nimport org.graalvm.visualvm.heapviewer.utils.HeapOperations;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DataType<T> {\n    \n    public static final String NO_VALUE_STRING = new String();\n    public static final String UNSUPPORTED_VALUE_STRING = new String();\n    public static final String NOT_AVAILABLE_VALUE_STRING = new String();\n    \n    public static final Integer NO_VALUE_INTEGER = new Integer(Integer.MIN_VALUE + 10);\n    public static final Integer UNSUPPORTED_VALUE_INTEGER = new Integer(Integer.MIN_VALUE + 11);\n    public static final Integer NOT_AVAILABLE_VALUE_INTEGER = new Integer(Integer.MIN_VALUE + 12);\n    \n    public static final Long NO_VALUE_LONG = new Long(Long.MIN_VALUE + 10);\n    public static final Long UNSUPPORTED_VALUE_LONG = new Long(Long.MIN_VALUE + 11);\n    public static final Long NOT_AVAILABLE_VALUE_LONG = new Long(Long.MIN_VALUE + 12);\n    \n    public static final DataType<String> NAME = new DataType<>(String.class, NO_VALUE_STRING, UNSUPPORTED_VALUE_STRING);\n    public static final DataType<Integer> COUNT = new DataType<>(Integer.class, NO_VALUE_INTEGER, UNSUPPORTED_VALUE_INTEGER);\n    public static final DataType<Integer> GCROOTS = new DataType<>(Integer.class, NO_VALUE_INTEGER, UNSUPPORTED_VALUE_INTEGER);\n    public static final DataType<Long> OWN_SIZE = new DataType<>(Long.class, NO_VALUE_LONG, UNSUPPORTED_VALUE_LONG);\n    \n    public static final DataType<Long> RETAINED_SIZE = new RetainedSize();\n    \n    public static final DataType<String> LOGICAL_VALUE = new DataType<>(String.class, NO_VALUE_STRING, UNSUPPORTED_VALUE_STRING);\n    \n    public static final DataType<Long> OBJECT_ID = new DataType<>(Long.class, NO_VALUE_LONG, UNSUPPORTED_VALUE_LONG);\n    \n    public static final DataType<JavaClass> CLASS = new DataType<>(JavaClass.class, null, null);\n    public static final DataType<Instance> INSTANCE = new DataType<>(Instance.class, null, null);\n    public static final DataType<InstancesWrapper> INSTANCES_WRAPPER = new DataType<>(InstancesWrapper.class, null, null);\n    \n    public static final DataType<HeapViewerNode> LOOP = new DataType<>(HeapViewerNode.class, null, null);\n    public static final DataType<HeapViewerNode> LOOP_ORIGIN = new DataType<>(HeapViewerNode.class, null, null);\n    \n    \n    static final Set<DataType> DEFAULT_TYPES = new HashSet<>(Arrays.asList(\n        NAME, COUNT, OWN_SIZE, RETAINED_SIZE, LOGICAL_VALUE, OBJECT_ID,\n        CLASS, INSTANCE, INSTANCES_WRAPPER, LOOP, LOOP_ORIGIN\n    ));\n    \n    \n    private final Class<T> type;\n    private final T noValue;\n    private final T unsupportedValue;\n\n    \n    public DataType(Class<T> type, T noValue, T unsupportedValue) {\n        this.type = type;\n        this.noValue = noValue;\n        this.unsupportedValue = unsupportedValue;\n    }\n\n\n    public Class<T> getType() { return type; }\n\n    public T getNoValue() { return noValue; }\n\n    public T getUnsupportedValue() { return unsupportedValue; }\n    \n    \n    public boolean valuesAvailable(Heap heap) { return true; }\n    \n    public boolean computeValues(Heap heap, Runnable whenComputed) { return true; }\n    \n    public void computeValuesImmediately(Heap heap) {}\n    \n    public void notifyWhenAvailable(Heap heap, Runnable target) {}\n    \n    public T getNotAvailableValue() { return null; }\n    \n    \n    public static abstract class Lazy<T> extends DataType<T> {\n        \n        private final T notAvailableValue;\n        private Map<Heap, Set<WeakReference<Runnable>>> notifyTargets;\n        \n        public Lazy(Class<T> type, T noValue, T unsupportedValue, T notAvailableValue) {\n            super(type, noValue, unsupportedValue);\n            this.notAvailableValue = notAvailableValue;\n        }\n        \n        public abstract boolean valuesAvailable(Heap heap);\n    \n        public abstract boolean computeValues(Heap heap, Runnable whenComputed);\n        \n        public abstract void computeValuesImmediately(Heap heap);\n        \n        protected void valuesComputed(Heap heap, Runnable whenComputed) {\n            if (whenComputed != null) whenComputed.run();\n            \n            if (notifyTargets != null) {\n                Set<WeakReference<Runnable>> targetRefs = notifyTargets.remove(heap);\n                if (targetRefs != null) {\n                    for (WeakReference<Runnable> targetRef : targetRefs) {\n                        Runnable target = targetRef.get();\n                        if (target != null) target.run();\n                    }\n                    targetRefs.clear();\n                }\n            }\n        }\n        \n        public void notifyWhenAvailable(Heap heap, Runnable target) {\n            if (notifyTargets == null) notifyTargets = new WeakHashMap<>();\n            Set<WeakReference<Runnable>> targetRefs = notifyTargets.computeIfAbsent(heap, k -> new HashSet<>());\n            targetRefs.add(new WeakReference<>(target));\n        }\n\n        public T getNotAvailableValue() { return notAvailableValue; }\n        \n    }\n    \n    \n    public static abstract class ValueProvider {\n    \n        public abstract boolean supportsView(Heap heap, String viewID);\n\n        public abstract <T> T getValue(HeapViewerNode node, DataType<T> type, Heap heap);\n\n    }\n    \n    \n    @NbBundle.Messages({\n        \"RetainedSize_ComputeRetainedMsg=<html><b>Retained sizes will be computed.</b><br><br>For large heap dumps this operation can take a significant<br>amount of time. Do you want to continue?</html>\",\n        \"RetainedSize_ComputeRetainedCaption=Compute Retained Sizes\"\n    })\n    private static class RetainedSize extends Lazy<Long> {\n        \n        private volatile boolean computing;\n        \n        private RetainedSize() {\n            super(Long.class, NO_VALUE_LONG, UNSUPPORTED_VALUE_LONG, NOT_AVAILABLE_VALUE_LONG);\n        }\n        \n        public boolean valuesAvailable(Heap heap) {\n            return heap.isRetainedSizeComputed() && heap.isRetainedSizeByClassComputed();\n        }\n        \n        public boolean computeValues(final Heap heap, Runnable whenComputed) {\n            if (computing) return true;\n            \n            if (!ProfilerDialogs.displayConfirmationDNSA(Bundle.RetainedSize_ComputeRetainedMsg(), \n                                                         Bundle.RetainedSize_ComputeRetainedCaption(),\n                                                         null, \"HeapFragmentWalker.computeRetainedSizes\", false)) // NOI18N\n                return false;\n            \n            computing = true;\n            new RequestProcessor(\"Retained Sizes Computer\").post(new Runnable() { // NOI18N\n                public void run() { computeValuesImmediately(heap, whenComputed); }\n            });\n            return true;\n        }\n        \n        public void computeValuesImmediately(Heap heap) {\n            if (computing) return;\n            \n            computing = true;\n            computeValuesImmediately(heap, null);\n        }\n        \n        public void computeValuesImmediately(Heap heap, final Runnable whenComputed) {\n            try {\n                HeapOperations.initializeRetainedSizes(heap);\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { valuesComputed(heap, whenComputed); }\n                });\n            } catch (InterruptedException ex) {\n                // requesting thread has been interrupted, any subsequent requests will wait for the result as well\n            } finally {\n                computing = false;\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/ErrorNode.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.model;\n\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ErrorNode_OOME=<not enough memory>\"\n})\npublic class ErrorNode extends TextNode {\n    \n    public ErrorNode(String text) {\n        super(text);\n    }\n    \n    \n    public static final class OOME extends ErrorNode {\n        \n        public OOME() { super(Bundle.ErrorNode_OOME()); }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/HeapViewerNode.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.model;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.IdentityHashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.TimeoutException;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingWorker;\nimport javax.swing.tree.TreeNode;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.openide.util.Exceptions;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class HeapViewerNode extends CCTNode {\n    \n    public static final HeapViewerNode[] NO_NODES = new HeapViewerNode[0];\n    \n    private int indexInParent;\n    private HeapViewerNode parent;\n    \n    private HeapViewerNode[] children;\n    \n    \n    // --- CCTNode ---------------------------------------------------------\n    \n    public final HeapViewerNode getParent() {\n        return parent;\n    }\n\n    public HeapViewerNode getChild(int index) {\n        HeapViewerNode[] ch = resolveChildren();\n        return ch[index];\n    }\n\n    public HeapViewerNode[] getChildren() {\n        return resolveChildren();\n    }\n\n    public int getIndexOfChild(Object child) {\n        HeapViewerNode node = (HeapViewerNode)child;\n        return node.getParent() == this ? node.indexInParent : -1;\n    }\n\n    public int getNChildren() {\n        HeapViewerNode[] ch = resolveChildren();\n        return ch.length;\n    }\n    \n    public boolean isLeaf() {\n        return children != null && getNChildren() == 0;\n    }\n    \n    \n    // --- Children logic --------------------------------------------------\n    \n    protected void setChildren(HeapViewerNode[] ch) {\n        for (int i = 0; i < ch.length; i++) {\n            ch[i].parent = this;\n            ch[i].indexInParent = i;\n        }\n        children = ch;\n    }\n    \n    protected void resetChildren() {\n        forgetChildren(null);\n        children = null;\n    }\n   \n    public void forgetChildren(NodesCache cache) {\n        synchronized (this) {\n            if (currentWorker != null) {\n                currentWorker.interrupt();\n                currentWorker = null;\n            }\n        }\n        \n        if (children != null && children.length > 0) {\n            for (HeapViewerNode node : children) {\n                node.forgetChildren(cache);\n                if (cache == null) node.parent = null;\n            }\n            if (cache != null && childrenComputed()) cache.storeChildren(this, children);\n            children = null;\n        }\n    }\n    \n    private boolean childrenComputed() {\n        if (children == null) return false;\n        if (children.length == 0 || children.length > 1) return true;\n        return !(children[0] instanceof ProgressNode);\n    }\n    \n    \n    private HeapViewerNode[] resolveChildren() {\n        if (children != null) return children;\n\n        RootNode root = RootNode.get(this);\n        if (root == null) return NO_NODES;\n        \n        try {\n            children = root.retrieveChildren(this);\n\n            if (children == null) {\n                HeapViewerNode[] ch = computeChildren(root);\n                setChildren(ch == null ? NO_NODES : ch);\n            }\n        } catch (OutOfMemoryError e) {\n            handleOOME(e);\n            setChildren(new HeapViewerNode[] { new ErrorNode.OOME() });\n        }\n\n        return children;\n    }\n    \n    \n    private Thread currentWorker;\n    \n    protected HeapViewerNode[] computeChildren(final RootNode root) {\n//        if (this == root) {\n//            System.err.println(\">>> COMPUTING CHILDREN OF ROOT in \" + Thread.currentThread());\n//            Thread.dumpStack();\n//        }\n        final Progress progress = new Progress();\n        \n        SwingWorker<HeapViewerNode[], HeapViewerNode[]> worker = new SwingWorker<HeapViewerNode[], HeapViewerNode[]>() {\n            protected HeapViewerNode[] doInBackground() throws Exception {\n//                long t = System.currentTimeMillis();\n                synchronized (HeapViewerNode.this) {\n                    if (currentWorker != null) {\n                        currentWorker.interrupt();\n//                        System.err.println(\">>> Cancelling children of \" + currentWorker);\n                    }\n                    currentWorker = Thread.currentThread();\n//                    System.err.println(\">>> Computing children in \" + Thread.currentThread() + \"...\");\n                }\n                \n                HeapViewerNode[] ret;\n                try {\n                    ret = lazilyComputeChildren(root.getContext().getFragment().getHeap(), root.getViewID(), root.getViewFilter(), root.getDataTypes(), root.getSortOrders(), progress);\n                } catch (InterruptedException ex) {\n                    ret = null;\n                } catch (OutOfMemoryError e) {\n                    handleOOME(e);\n                    ret = new HeapViewerNode[] { new ErrorNode.OOME() };\n                }\n                if (Thread.interrupted()) ret = null; // make sure the interrupted flag is handled & reset in all circumstances\n                \n                synchronized (HeapViewerNode.this) {\n                    if (currentWorker == Thread.currentThread()) currentWorker = null;\n                    else ret = null; // probably not needed, just to be sure we don't overwrite newer results\n                }\n                \n//                if (ret == null) System.err.println(\">>> Cancelled children in \" + Thread.currentThread() + \" time \" + (System.currentTimeMillis() - t));\n//                else System.err.println(\">>> Computed children in \" + Thread.currentThread() + \" time \" + (System.currentTimeMillis() - t));\n                \n                return ret;\n            }\n            protected void done() {\n                synchronized (HeapViewerNode.this) {\n                    if (currentWorker == null) try {\n                        HeapViewerNode[] newChildren = get();\n                        // newChildren may be null, for example if the worker thread has been interrupted\n                        if (newChildren != null) {\n                            setChildren(newChildren);\n                            root.updateChildren(HeapViewerNode.this);\n                        }\n                    } catch (Exception ex) {\n                        Exceptions.printStackTrace(ex);\n                    }\n                }\n            }\n        };\n        worker.execute();\n        try {\n            return worker.get(UIThresholds.MODEL_CHILDREN, TimeUnit.MILLISECONDS);\n        } catch (InterruptedException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (ExecutionException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (TimeoutException ex) {\n            return new HeapViewerNode[] { new ProgressNode(progress) };\n        }\n\n        return null;\n    }\n\n    protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n\n        List<HeapViewerNode> nodes = new ArrayList<>();\n        Collection<? extends Provider> providers;\n        \n        RootNode root = RootNode.get(this);\n        if (root != null) providers = new ArrayList<>(root.getNodeProviders());\n        else providers = new ArrayList<>(Lookup.getDefault().lookupAll(Provider.class));\n\n        Iterator<? extends Provider> iproviders = providers.iterator();\n        while (iproviders.hasNext())\n            if (!iproviders.next().supportsNode(HeapViewerNode.this, heap, viewID))\n                iproviders.remove();\n        \n        if (providers.size() == 1) {\n            HeapViewerNode[] n = providers.iterator().next().getNodes(this, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n            if (n != null) nodes.addAll(Arrays.asList(checkForLoops(this, n)));\n        } else {\n            for (Provider provider : providers) nodes.add(new ChildrenContainer(provider));\n        }\n        \n        return nodes.toArray(NO_NODES);\n    }\n    \n    \n    private static HeapViewerNode[] checkForLoops(HeapViewerNode parent, HeapViewerNode[] nodes) {\n        Map<HeapViewerNode, HeapViewerNode> pathToRoot = new HashMap<>();\n        while (parent != null) {\n            pathToRoot.put(parent, parent);\n            parent = parent.getParent();\n        }\n        \n        for (int i = 0; i < nodes.length; i++) {\n            HeapViewerNode loopOrigin = pathToRoot.get(nodes[i]);\n            if (loopOrigin != null) nodes[i] = new LoopNode(nodes[i], loopOrigin);\n        }\n        \n        return nodes;\n    }\n    \n    \n    protected void handleOOME(OutOfMemoryError e) {\n        RootNode root = RootNode.get(this);\n        if (root != null) root.handleOOME(e);\n        else System.err.println(\"Out of memory in \" + toString() + \": \" + e.getMessage()); // NOI18N\n    }\n    \n    \n    // --- Values --------------------------------------------------------------\n    \n    private static final Object NO_VALUE = new Object();\n    private Map<DataType, Object> foreignValues;\n\n    protected <T> T getValue(DataType<T> type, Heap heap) {\n        return DataType.DEFAULT_TYPES.contains(type) ? type.getUnsupportedValue() : null;\n    }\n    \n    public static <T> T getValue(HeapViewerNode node, DataType<T> type, Heap heap) {\n        return getValue(node, type, heap, null);\n    }\n    \n    // To be used for \"temporary\" nodes out of the tree structure (like providers returning first N nodes)\n    public static <T> T getValue(HeapViewerNode node, DataType<T> type, Heap heap, HeapViewerNode parent) {\n        T value = node.getValue(type, heap);\n        if (Objects.equals(value, type.getUnsupportedValue())) return value;\n        if (value != null || type.getNoValue() == null) return value;\n        \n        if (!type.valuesAvailable(heap)) return type.getNotAvailableValue();\n        \n        if (node.foreignValues != null) {\n            value = (T) node.foreignValues.get(type);\n            if (value != null) return value == NO_VALUE ? null : value;\n        }\n        \n        RootNode root = RootNode.get(parent != null ? parent : node);\n        Iterator<? extends DataType.ValueProvider> providers = root != null ?\n                root.getValueProviders().iterator() : \n                Lookup.getDefault().lookupAll(DataType.ValueProvider.class).iterator();\n\n        if (providers.hasNext()) {\n            while (value == null && providers.hasNext())\n                value = providers.next().getValue(node, type, heap);\n        }\n        \n        if (node.foreignValues == null) node.foreignValues = new IdentityHashMap<>(1);\n        node.foreignValues.put(type, value == null ? NO_VALUE : value);\n        \n        return value;\n    }\n    \n    \n    // --- Sorting support -----------------------------------------------------\n    \n    public final void willBeSorted() {\n        if (updateChildrenOnSort()) forgetChildren(null);\n    }\n    \n    private boolean updateChildrenOnSort() {\n        // GH-113: make sure the ongoing children computation is restarted when sorting changes\n        synchronized (this) { if (currentWorker != null) return true; }\n        \n        return children != null && children.length > 1 && children[children.length - 1] instanceof MoreNodesNode;\n    }\n    \n    \n    // --- Cloning support -----------------------------------------------------\n    \n    public HeapViewerNode createCopy() {\n        return null;\n    }\n    \n    protected void setupCopy(HeapViewerNode copy) {\n    }\n            \n            \n    // --- Utils ---------------------------------------------------------------\n    \n    public static TreePath fromNode(TreeNode node) {\n        return fromNode(node, null);\n    }\n    \n    public static TreePath fromNode(TreeNode node, TreeNode root) {\n        List<TreeNode> l = new ArrayList<>();\n        while (node != root) {\n            l.add(0, node);\n            node = node.getParent();\n        }\n        if (node != null) l.add(0, node);\n        return new TreePath(l.toArray(new Object[0]));\n    }\n    \n    \n    private static class ChildrenContainer extends TextNode {\n        \n        private final Provider provider;\n        \n        ChildrenContainer(Provider provider) {\n            super(\"<\" + provider.getName() + \">\"); // NOI18N\n            resetChildren();\n            \n            this.provider = provider;\n        }\n        \n        @Override\n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            HeapViewerNode parent = getParent();\n            HeapViewerNode[] n = provider.getNodes(parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n            return n != null ? checkForLoops(parent, n) : NO_NODES;\n        }\n        \n    }\n    \n    \n    // --- SPI -----------------------------------------------------------------\n    \n    public static abstract class Provider {\n    \n        public abstract String getName();\n\n        public abstract boolean supportsView(Heap heap, String viewID);\n\n        public abstract boolean supportsNode(HeapViewerNode parent, Heap heap, String viewID);\n\n        public abstract HeapViewerNode[] getNodes(HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException;\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/HeapViewerNodeFilter.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.model;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class HeapViewerNodeFilter {\n    \n    public abstract boolean passes(HeapViewerNode node, Heap heap);\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/HeapViewerNodeWrapper.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.model;\n\nimport java.util.Objects;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class HeapViewerNodeWrapper extends HeapViewerNode {\n        \n    private final HeapViewerNode node;\n\n\n    public HeapViewerNodeWrapper(HeapViewerNode node) {\n        this.node = node;\n    }\n\n\n    public final HeapViewerNode getNode() {\n        return node;\n    }\n\n\n    @Override\n    public boolean equals(Object o) {\n        if (o == this) return true;\n        if (!(o instanceof HeapViewerNodeWrapper)) return false;\n        return Objects.equals(node, ((HeapViewerNodeWrapper)o).node);\n    }\n\n    @Override\n    public int hashCode() {\n        return node.hashCode();\n    }\n\n\n    @Override\n    public String toString() {\n        return node.toString();\n    }\n\n\n    @Override\n    protected <T> T getValue(DataType<T> type, Heap heap) {\n        return node.getValue(type, heap);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/LoopNode.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.model;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"LoopNode_Name={0} (loop to {1})\"\n})\npublic class LoopNode extends HeapViewerNode {\n    \n    private final HeapViewerNode loopNode;\n    private final HeapViewerNode loopOrigin;\n\n    LoopNode(HeapViewerNode loopNode, HeapViewerNode loopOrigin) {\n        this.loopNode = loopNode;\n        this.loopOrigin = loopOrigin;\n        setChildren(NO_NODES);\n    }\n    \n    public String toString() {\n        return Bundle.LoopNode_Name(loopNode.toString(), loopOrigin.toString());\n    }\n\n    protected Object getValue(DataType type, Heap heap) {\n        if (type == DataType.LOOP) return loopNode;\n        if (type == DataType.LOOP_ORIGIN) return loopOrigin;\n        \n        return loopNode.getValue(type, heap);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/MoreNodesNode.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.model;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class MoreNodesNode extends TextNode {    \n    \n    public MoreNodesNode(String text) {\n        super(text);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/NodesCache.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.model;\n\nimport java.lang.ref.Reference;\nimport java.lang.ref.WeakReference;\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class NodesCache {\n    \n    private Reference<Map<NodeKey, HeapViewerNode[]>> cache;\n    \n    \n    public void storeChildren(HeapViewerNode node, HeapViewerNode[] children) {\n        getCache().put(new NodeKey(node), children);\n    }\n    \n    public HeapViewerNode[] retrieveChildren(HeapViewerNode node) {\n        return getCache().remove(new NodeKey(node));\n    }\n    \n    \n    public void clear() {\n        cache = null;\n    }\n    \n    \n    private Map<NodeKey, HeapViewerNode[]> getCache() {\n        Map<NodeKey, HeapViewerNode[]> c = cache == null ? null : cache.get();\n        if (c == null) {\n            c = new HashMap<>();\n            cache = new WeakReference<>(c);\n        }\n        return c;\n    }\n    \n    \n    private static final class NodeKey {\n        \n        private final HeapViewerNode node;\n        private int distance;\n        private int hashCode;\n\n        NodeKey(HeapViewerNode node) {\n            this.node = node;\n            \n            distance = 0;\n            hashCode = 1;\n            \n            while (node != null) {\n                hashCode = 31 * hashCode + node.hashCode();\n                distance++;\n                node = node.getParent();\n            }\n        }\n\n        public final int hashCode() {\n            return hashCode;\n        }\n        \n        public final boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof NodeKey)) return false;\n            \n            NodeKey nk = (NodeKey)o;\n            if (distance != nk.distance) return false;\n            \n            CCTNode n = nk.node;\n            CCTNode t = node;\n            while (t != null) {\n                if (!t.equals(n)) return false;\n                t = t.getParent();\n                n = n.getParent();\n            }\n            \n            return true;\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/Progress.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.model;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport javax.swing.event.ChangeEvent;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class Progress {\n    \n    private volatile Set<Listener> listeners;\n    \n    private long totalSteps;\n    private long currentStep;\n    \n    private boolean finished;\n    \n    private volatile long lastTick;\n    private volatile long currentTick;\n    \n    private Timer timer;\n    \n    \n    public Progress() {}\n    \n    \n    public void setupUnknownSteps() {\n        finished = false;\n        \n        currentStep = 0;\n        totalSteps = -1;\n        \n        init();\n        \n        fireChange();\n    }\n    \n    public void setupKnownSteps(long totalSteps) {\n        setupKnownSteps(0, totalSteps);\n    }\n    \n    public void setupKnownSteps(long currentStep, long totalSteps) {\n        finished = false;\n        \n        this.currentStep = currentStep;\n        this.totalSteps = totalSteps;\n        \n        init();\n        \n        fireChange();\n    }\n    \n    \n    public void step() {\n        steps(1);\n    }\n    \n    public void steps(long steps) {\n        setCurrentStep(currentStep + steps);\n    }\n    \n    public void setCurrentStep(long currentStep) {\n        if (finished) return;\n        \n        this.currentStep = currentStep;\n        \n        if (lastTick != currentTick) fireChange();\n    }\n    \n    \n    public void finish() {\n        if (finished) return;\n        finished = true;\n        \n        if (timer != null) {\n            timer.stop();\n            timer = null;\n        }\n        \n        if (totalSteps != -1) currentStep = totalSteps;\n        \n        fireChange();\n    }\n    \n    \n    long getCurrentStep() {\n        return currentStep;\n    }\n    \n    long getTotalSteps() {\n        return totalSteps;\n    }\n    \n    \n    public void addChangeListener(final Listener listener) {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                if (listeners == null) listeners = new HashSet<>();\n                listeners.add(listener);\n            }\n        });\n    }\n    \n    public void removeChangeListener(final Listener listener) {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                if (listeners != null) {\n                    listeners.remove(listener);\n                    if (listeners.isEmpty()) listeners = null;\n                }\n            }\n        });\n    }\n    \n    \n    private void init() {\n        lastTick = Long.MIN_VALUE;\n        currentTick = Long.MIN_VALUE;\n        \n        if (timer == null) {\n            timer = new Timer(UIThresholds.PROGRESS_REFRESH_RATE, new ActionListener() {\n                public void actionPerformed(ActionEvent e) { currentTick++; }\n            });\n            timer.setInitialDelay(UIThresholds.PROGRESS_INITIAL_DELAY);\n            timer.start();\n        }\n    }\n    \n    private void fireChange() {\n        if (listeners == null) return;\n        \n        final long _currentStep = currentStep;\n        final long _totalSteps = totalSteps;\n        final boolean _finished = finished;\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (listeners == null || listeners.isEmpty()) return;\n                Event event = new Event(this, _currentStep, _totalSteps, _finished);\n                for (Listener listener : listeners) listener.progressChanged(event);\n            }\n        });\n        \n        lastTick = currentTick;\n    }\n    \n    \n    public static final class Event extends ChangeEvent {\n        \n        private final long currentStep;\n        private final long totalSteps;\n        private final boolean finished;\n        \n        private Event(Object source, long currentStep, long totalSteps, boolean finished) {\n            super(source);\n            this.currentStep = currentStep;\n            this.totalSteps = totalSteps;\n            this.finished = finished;\n        }\n        \n        public long getCurrentStep() {\n            return currentStep;\n        }\n        \n        public long getTotalSteps() {\n            return totalSteps;\n        }\n        \n        public boolean isKnownSteps() {\n            return totalSteps != -1;\n        }\n        \n        public boolean isFinished() {\n            return finished;\n        }\n        \n        public String toString() {\n            if (isFinished()) return \"finished\"; // NOI18N\n            else if (!isKnownSteps()) return \"step \" + currentStep; // NOI18N\n            else return \"step \" + currentStep + \" of \" + totalSteps; // NOI18N\n        }\n        \n    }\n    \n    \n    public static interface Listener {\n        \n        public void progressChanged(Event event);\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/ProgressNode.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.model;\n\nimport java.text.NumberFormat;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ProgressNode_Computing=computing...\",\n    \"ProgressNode_Processing=processing object {0}\",\n    \"ProgressNode_DoneProcessing=done processing {0} objects\",\n    \"ProgressNode_Done0pc=0% done\",\n    \"ProgressNode_Done100pc=100% done\",\n    \"ProgressNode_DoneProcessingPc={0} done, processing object {1}\"\n})\npublic class ProgressNode extends TextNode {\n    \n    private static NumberFormat PERCENT_FORMAT;\n    \n    private String progressText;\n    \n    \n    public ProgressNode() {\n        this(Bundle.ProgressNode_Computing());\n    }\n    \n    public ProgressNode(String text) {\n        this(text, null);\n    }\n    \n    public ProgressNode(Progress progress) {\n        this(Bundle.ProgressNode_Computing(), progress);\n    }\n    \n    public ProgressNode(String text, Progress progress) {\n        super(text);\n        \n        if (progress != null) {\n            progress.addChangeListener(new Progress.Listener() {\n                public void progressChanged(Progress.Event e) {\n                    progressText = getProgressText(e);\n                    RootNode root = RootNode.get(ProgressNode.this);\n                    if (root != null) root.refreshNode(root);\n                }\n            });\n        }\n    }\n    \n    \n    public String getProgressText() {\n        return progressText;\n    }\n    \n    \n    protected String getProgressText(Progress.Event e) {\n        if (e.isKnownSteps()) {\n            if (e.isFinished()) return formatPercent(e.getTotalSteps(), e.getTotalSteps());\n            else return formatPercent(e.getCurrentStep(), e.getTotalSteps());\n        } else {\n            if (e.isFinished()) return Bundle.ProgressNode_DoneProcessing(formatNumber(e.getCurrentStep()));\n            else return Bundle.ProgressNode_Processing(formatNumber(e.getCurrentStep()));\n        }\n    }\n    \n    \n    protected static String formatNumber(long number) {\n        return Formatters.numberFormat().format(number);\n    }\n    \n    protected static String formatPercent(long value, long maxValue) {\n        if (value == maxValue) return Bundle.ProgressNode_Done100pc();\n        if (value == 0) return Bundle.ProgressNode_Done0pc();\n        \n        if (PERCENT_FORMAT == null) {\n            PERCENT_FORMAT = NumberFormat.getPercentInstance();\n            PERCENT_FORMAT.setMaximumFractionDigits(0);\n            PERCENT_FORMAT.setMinimumFractionDigits(0);\n        }\n        \n        return Bundle.ProgressNode_DoneProcessingPc(PERCENT_FORMAT.format(value / (float)maxValue), formatNumber(value));\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/RootNode.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.model;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class RootNode extends HeapViewerNode {\n    \n//    public abstract void repaintView();\n        \n//    public abstract void refreshView();\n\n    \n    public abstract HeapContext getContext();\n    \n    \n    public abstract String getViewID();\n    \n    public abstract HeapViewerNodeFilter getViewFilter();\n    \n    \n    public abstract List<DataType> getDataTypes();\n    \n    public abstract List<SortOrder> getSortOrders();\n    \n    \n    public abstract void refreshNode(HeapViewerNode node);\n    \n    \n    public abstract void updateChildren(HeapViewerNode node);\n    \n    public abstract HeapViewerNode[] retrieveChildren(HeapViewerNode node);\n    \n    \n    public abstract HeapViewerRenderer resolveRenderer(HeapViewerNode node);\n    \n    \n    protected void handleOOME(OutOfMemoryError e) {\n        System.err.println(\"Out of memory in \" + getViewID() + \": \" + e.getMessage()); // NOI18N\n    }\n    \n    \n//    public RootNode() {\n//        this(NO_NODES);\n//    }\n//    \n//    public RootNode(HeapViewerNode[] children) {\n//        super.setChildren(children);\n//    }\n        \n    \n//    public void setChildren(HeapViewerNode[] children) {\n//        super.setChildren(children);\n////        updateChildren(this);\n//    }\n    \n    \n    public void reset(boolean makeEmpty) {\n        super.resetChildren();\n        if (makeEmpty) super.setChildren(HeapViewerNode.NO_NODES);\n        updateChildren(null);\n    }\n    \n    \n    public boolean equals(Object o) {\n        return o instanceof RootNode && toString().equals(o.toString());\n    }\n    \n    public int hashCode() {\n        return toString().hashCode();\n    }\n    \n    \n    public String toString() {\n        return \"root of \" + getViewID(); // NOI18N\n    }\n    \n    \n    protected abstract HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException;\n    \n    \n    private Collection<? extends HeapViewerNode.Provider> nodeProviders;\n        \n    synchronized Collection<? extends HeapViewerNode.Provider> getNodeProviders() {\n        if (nodeProviders == null) {\n            nodeProviders = Lookup.getDefault().lookupAll(HeapViewerNode.Provider.class);\n            if (!nodeProviders.isEmpty()) {\n                nodeProviders = new ArrayList<>(nodeProviders);\n                Iterator<? extends HeapViewerNode.Provider> providers = nodeProviders.iterator();\n                Heap heap = getContext().getFragment().getHeap();\n                String viewID = getViewID();\n                while (providers.hasNext())\n                    if (!providers.next().supportsView(heap, viewID))\n                        providers.remove();\n            }\n        }\n        return nodeProviders;\n    }\n    \n    private Collection<? extends DataType.ValueProvider> valueProviders;\n        \n    synchronized Collection<? extends DataType.ValueProvider> getValueProviders() {\n        if (valueProviders == null) {\n            valueProviders = Lookup.getDefault().lookupAll(DataType.ValueProvider.class);\n            if (!valueProviders.isEmpty()) {\n                valueProviders = new ArrayList<>(valueProviders);\n                Iterator<? extends DataType.ValueProvider> providers = valueProviders.iterator();\n                Heap heap = getContext().getFragment().getHeap();\n                String viewID = getViewID();\n                while (providers.hasNext())\n                    if (!providers.next().supportsView(heap, viewID))\n                        providers.remove();\n            }\n        }\n        return valueProviders;\n    }\n\n\n    public static RootNode get(HeapViewerNode node) {\n        while (node != null) {\n            if (node instanceof RootNode) return (RootNode)node;\n            node = node.getParent();\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/model/TextNode.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.model;\n\nimport java.util.Objects;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class TextNode extends HeapViewerNode implements CCTNode.AlwaysLast {\n    \n    private final String text;\n        \n    \n    public TextNode(String text) {\n        this.text = text;\n        setChildren(NO_NODES);\n    }\n    \n    \n    public String getText() {\n        return text;\n    }\n\n    public String toString() {\n        return getText();\n    }\n    \n    \n    public boolean equals(Object o) {\n        return o instanceof TextNode && ((TextNode)o).text.equals(text);\n    }\n\n    public int hashCode() {\n        return Objects.hash(getParent(), text);\n    }\n    \n    \n    protected Object getValue(DataType type, Heap heap) {\n        if (type == DataType.NAME) return getText();\n        \n        return type.getUnsupportedValue();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/options/HeapViewerOptionsCategory.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.options;\n\nimport java.beans.PropertyChangeListener;\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.JComponent;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.graalvm.visualvm.heapviewer.oql.CustomOQLQueries;\nimport org.graalvm.visualvm.heapviewer.oql.OQLQuery;\nimport org.netbeans.spi.options.OptionsPanelController;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@OptionsPanelController.TopLevelRegistration(\n        id = HeapViewerOptionsCategory.OPTIONS_HANDLE,\n        categoryName = \"#HeapViewerOptionsCategory_Name\", \n        iconBase = \"org/graalvm/visualvm/heapviewer/options/heapViewer32.png\",\n        position = 1525)\n@NbBundle.Messages({\n        \"HeapViewerOptionsCategory_Name=Heap Viewer\"\n}) \npublic final class HeapViewerOptionsCategory extends OptionsPanelController {\n    \n    private static final HelpCtx HELP_CTX = null;\n//    private static final HelpCtx HELP_CTX = new HelpCtx(\"HeapViewerOptions.Help\"); // NOI18N\n    \n    public static final String OPTIONS_HANDLE = \"HeapViewerOptions\"; // NOI18N\n    \n    private HeapViewerOptionsPanel settingsPanel;\n    private JComponent settingsComponent;\n\n    \n    private HeapViewerOptionsPanel getPanel() {\n        if (settingsPanel == null) settingsPanel = new HeapViewerOptionsPanel();\n        return settingsPanel;\n    }\n    \n    public JComponent getComponent(Lookup lookup) {\n        if (settingsComponent == null) settingsComponent = UISupport.createScrollableContainer(getPanel());\n        return settingsComponent;\n    }\n\n    public HelpCtx getHelpCtx() {\n        return HELP_CTX;\n    }\n    \n    public boolean isChanged() {\n        if (settingsPanel == null) return false;\n        \n        List<OQLQuery> master = CustomOQLQueries.instance().list();\n        List<OQLQuery> edited = getPanel().getQueries();\n        \n        if (master.size() != edited.size()) return true;\n        \n        for (int i = 0; i < master.size(); i++)\n            if (!sameQuery(master.get(i), edited.get(i))) return true;\n        \n        return false;\n    }\n\n    public boolean isValid() {\n        return true;\n    }\n\n    public void applyChanges() {\n        if (settingsPanel == null) return;\n        CustomOQLQueries.instance().set(getPanel().getQueries());\n    }\n\n    public void cancel() {\n    }\n\n    public void update() {\n        new RequestProcessor(\"OQL Scripts Loader\").post(new Runnable() { // NOI18N\n            public void run() {\n                final List<OQLQuery> queries = CustomOQLQueries.instance().list();\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        getPanel().setQueries(queries);\n                    }\n                });\n            }\n        });\n    }\n    \n    public void addPropertyChangeListener(PropertyChangeListener l) {\n    }\n    \n    public void removePropertyChangeListener(PropertyChangeListener l) {\n    }\n    \n    \n    private static boolean sameQuery(OQLQuery query1, OQLQuery query2) {\n        if (!Objects.equals(query1.getName(), query2.getName())) return false;\n        if (!Objects.equals(query1.getDescription(), query2.getDescription())) return false;\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/options/HeapViewerOptionsPanel.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.options;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.GridLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.util.Arrays;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultListModel;\nimport javax.swing.DefaultListSelectionModel;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextArea;\nimport javax.swing.JTextField;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.heapviewer.oql.OQLEditorComponent;\nimport org.graalvm.visualvm.heapviewer.oql.OQLQuery;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"HeapViewerOptionsPanel_CustomScript=Custom Script\",\n    \"HeapViewerOptionsPanel_CustomScripts=Custom OQL Scripts\",\n    \"HeapViewerOptionsPanel_LoadingScripts=<loading scripts>\",\n    \"HeapViewerOptionsPanel_NoSavedScripts=<no saved scripts>\",\n    \"HeapViewerOptionsPanel_DeleteScriptTooltip=Delete selected script\",\n    \"HeapViewerOptionsPanel_MoveScriptUpTooltip=Move selected script up\",\n    \"HeapViewerOptionsPanel_MoveScriptDownTooltip=Move selected script down\",\n    \"HeapViewerOptionsPanel_NameLabel=&Name:\",\n    \"HeapViewerOptionsPanel_DescriptionLabel=&Description (optional):\",\n    \"HeapViewerOptionsPanel_PreviewLabel=&Preview:\",\n    \"HeapViewerOptionsPanel_HintLabel=To add custom script, use the Save OQL Script action in Heap Viewer | OQL Console.\"\n}) \nfinal class HeapViewerOptionsPanel extends JPanel {\n    \n    private boolean loaded;\n    \n    private final Model model;\n\n    private boolean internalChange;\n\n\n    HeapViewerOptionsPanel() {\n        model = new Model();\n        initComponents();\n    }\n    \n    void setQueries(List<OQLQuery> queries) {\n        model.clear();\n        for (OQLQuery query : queries) model.addElement(query);\n        loaded = true;\n        model.fireChange();\n        \n        if (model.isEmpty()) updateSelection();\n        else list.setSelectedIndex(0);\n    }\n    \n    List<OQLQuery> getQueries() {\n        OQLQuery[] queries = new OQLQuery[model.size()];\n        model.copyInto(queries);\n        return Arrays.asList(queries);\n    }\n\n\n    private void updateSelection() {\n        int selectedIndex = model.isEmpty() ? -1 : list.getSelectedIndex();\n        if (selectedIndex == model.getSize()) return; // isAdjusting\n        \n        removeButton.setEnabled(selectedIndex != -1);\n        upButton.setEnabled(selectedIndex > 0);\n        downButton.setEnabled(selectedIndex < model.getSize() - 1);\n\n        refreshPreset(selectedIndex);\n    }\n\n    private void deleteQuery() {\n        int selectedIndex = list.getSelectedIndex();\n        model.remove(selectedIndex);\n        if (model.getSize() > 0) {\n            list.setSelectedIndex(selectedIndex == model.getSize() ?\n                                  selectedIndex - 1 : selectedIndex);\n        } else {\n            updateSelection();\n        }\n        model.fireChange();\n    }\n\n    private void moveQueryUp() {\n        int selectedIndex = list.getSelectedIndex();\n        OQLQuery query = model.elementAt(selectedIndex);\n        model.remove(selectedIndex);\n        model.add(selectedIndex - 1, query);\n        list.setSelectedIndex(selectedIndex - 1);\n    }\n\n    private void moveQueryDown() {\n        int selectedIndex = list.getSelectedIndex();\n        OQLQuery query = model.elementAt(selectedIndex);\n        model.remove(selectedIndex);\n        model.add(selectedIndex + 1, query);\n        list.setSelectedIndex(selectedIndex + 1);\n    }\n\n    private void refreshPreset(int index) {\n        OQLQuery query = index == -1 ? null : model.get(index);\n\n        internalChange = true;\n        \n        nameField.setText(query == null ? \"\" : query.getName()); // NOI18N\n        try { nameField.setCaretPosition(0); } catch (IllegalArgumentException e) {}\n        descrArea.setText(query == null ? \"\" : query.getDescription()); // NOI18N\n        try { descrArea.setCaretPosition(0); } catch (IllegalArgumentException e) {}\n        previewArea.setScript(query == null ? \"\" : query.getScript()); // NOI18N\n        internalChange = false;\n\n        presetsPanel.setEnabled(index != -1);\n    }\n\n    private void updatePreset() {\n        if (internalChange) return;\n        \n        int index = list.getSelectedIndex();\n        OQLQuery query = index == -1 ? null : model.get(index);\n        \n        if (query == null) return;\n\n        query.setName(uniqueName(nameField.getText().trim(), index));\n        query.setDescription(descrArea.getText().trim());\n        \n        model.fireChange();\n    }\n    \n    private String uniqueName(String name, int index) {\n        if (name.isEmpty()) name = Bundle.HeapViewerOptionsPanel_CustomScript();\n        String baseName = name;\n        \n        int nameExt = 0;\n        while (containsQuery(name, index)) name = baseName + \" \" + ++nameExt; // NOI18N\n        \n        return name;\n    }\n    \n    private boolean containsQuery(String name, int index) {\n        for (int i = 0; i < model.size(); i++)\n            if (i != index && name.equals(model.get(i).getName()))\n                return true;\n        return false;\n    }\n\n    private void initComponents() {\n        final boolean nimbusLaF = org.graalvm.visualvm.uisupport.UISupport.isNimbusLookAndFeel();\n\n        GridBagConstraints c;\n\n        setLayout(new GridBagLayout());\n\n        SectionSeparator presetsSection = UISupport.createSectionSeparator(Bundle.HeapViewerOptionsPanel_CustomScripts());\n        c = new GridBagConstraints();\n        c.gridy = 0;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 5, 0);\n        add(presetsSection, c);\n\n        JPanel listPanel = new JPanel(new BorderLayout());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 1;\n        c.gridwidth = 1;\n        c.weighty = 0.5;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(3, 15, 3, 0);\n        add(listPanel, c);\n\n        list = new JList(model);\n        list.setSelectionModel(new DefaultListSelectionModel() {\n            public void setSelectionInterval(int index0, int index1) {\n                super.setSelectionInterval(index0, index1);\n                updateSelection();\n            }\n            public void removeSelectionInterval(int i1, int i2) {}\n        });\n        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        final Dimension oneDim = new Dimension(1, 1);\n        final JLabel loadingScriptsLabel = new JLabel(Bundle.HeapViewerOptionsPanel_LoadingScripts(), JLabel.CENTER);\n        loadingScriptsLabel.setEnabled(false);\n        loadingScriptsLabel.setSize(loadingScriptsLabel.getPreferredSize());\n        final JLabel noScriptsLabel = new JLabel(Bundle.HeapViewerOptionsPanel_NoSavedScripts(), JLabel.CENTER);\n        noScriptsLabel.setEnabled(false);\n        noScriptsLabel.setSize(noScriptsLabel.getPreferredSize());\n        JScrollPane listScroll = new JScrollPane(list) {\n            public Dimension getPreferredSize() {\n                return oneDim;\n            }\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void paintChildren(Graphics g) {\n                super.paintChildren(g);\n                if (model.isEmpty()) {\n                    JLabel hint = loaded ? noScriptsLabel : loadingScriptsLabel;\n                    int x = (getWidth() - hint.getWidth()) / 2;\n                    int y = (getHeight() - hint.getHeight()) / 2;\n                    g.translate(x, y);\n                    hint.paint(g);\n                    g.translate(-x, -y);\n                }\n            }\n        };\n        listPanel.add(listScroll, BorderLayout.CENTER);\n        \n        removeButton = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                deleteQuery();\n            }\n        };\n        removeButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/profiler/resources/remove.png\", true)));   // NOI18N\n        Insets margin = removeButton.getMargin();\n        int mar = nimbusLaF ? 0 : 8;\n        margin.left = mar;\n        margin.right = mar;\n        removeButton.setToolTipText(Bundle.HeapViewerOptionsPanel_DeleteScriptTooltip());\n        removeButton.setMargin(margin);\n        upButton = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                moveQueryUp();\n            }\n        };\n        upButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/profiler/resources/up.png\", true)));   // NOI18N\n        upButton.setToolTipText(Bundle.HeapViewerOptionsPanel_MoveScriptUpTooltip()); // NOI18N\n        upButton.setMargin(margin);\n        downButton = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                moveQueryDown();\n            }\n        };\n        downButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/profiler/resources/down.png\", true)));   // NOI18N\n        downButton.setToolTipText(Bundle.HeapViewerOptionsPanel_MoveScriptDownTooltip());\n        downButton.setMargin(margin);\n\n        JPanel controlsPanel = new JPanel(new GridLayout(1, 4, 5, 0)) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents())\n                    c.setEnabled(enabled);\n            }\n        };\n        controlsPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));\n        controlsPanel.add(removeButton);\n        controlsPanel.add(new JPanel(null));\n        controlsPanel.add(upButton);\n        controlsPanel.add(downButton);\n        listPanel.add(controlsPanel, BorderLayout.SOUTH);\n\n        presetsPanel = new JPanel(new GridBagLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents())\n                    c.setEnabled(enabled);\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 1;\n        c.weightx = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(3, 8, 3, 0);\n        add(presetsPanel, c);\n        \n        JLabel nameLabel = new JLabel();\n        Mnemonics.setLocalizedText(nameLabel, Bundle.HeapViewerOptionsPanel_NameLabel());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 3, 3, 0);\n        presetsPanel.add(nameLabel, c);\n\n        nameField = new JTextField() {\n            public void setBackground(Color bg) {\n                super.setBackground(bg);\n                if (descrArea != null) descrArea.setBackground(bg);\n            }\n        };\n        nameLabel.setLabelFor(nameField);\n        nameField.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) { updatePreset(); }\n            public void removeUpdate(DocumentEvent e) { updatePreset(); }\n            public void changedUpdate(DocumentEvent e) { updatePreset(); }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 5, 3, 0);\n        presetsPanel.add(nameField, c);\n        \n        JLabel descrLabel = new JLabel();\n        Mnemonics.setLocalizedText(descrLabel, Bundle.HeapViewerOptionsPanel_DescriptionLabel());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(10, 3, 3, 0);\n        presetsPanel.add(descrLabel, c);\n        \n        descrArea = new JTextArea();\n        descrLabel.setLabelFor(descrArea);\n        descrArea.setLineWrap(true);\n        descrArea.setWrapStyleWord(true);\n        descrArea.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) { updatePreset(); }\n            public void removeUpdate(DocumentEvent e) { updatePreset(); }\n            public void changedUpdate(DocumentEvent e) { updatePreset(); }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 2;\n        c.weightx = 1;\n        c.weighty = 0.3;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(3, 5, 3, 0);\n        JScrollPane descrScroll = new JScrollPane(descrArea) {\n            public Dimension getPreferredSize() {\n                return getMinimumSize();\n            }\n            public void setEnabled(boolean b) {\n                super.setEnabled(b);\n                descrArea.setEnabled(b);\n            }\n        };\n        presetsPanel.add(descrScroll, c);\n        \n        JLabel previewLabel = new JLabel();\n        Mnemonics.setLocalizedText(previewLabel, Bundle.HeapViewerOptionsPanel_PreviewLabel());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 3;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(10, 3, 3, 0);\n        presetsPanel.add(previewLabel, c);\n        \n        previewArea = new OQLEditorComponent(null);\n        previewArea.setEditable(false);\n        previewLabel.setLabelFor(previewArea);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 4;\n        c.weightx = 1;\n        c.weighty = 0.7;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(3, 5, 3, 0);\n        presetsPanel.add(previewArea, c);\n        \n        \n        JLabel hint = new JLabel(Bundle.HeapViewerOptionsPanel_HintLabel());\n        hint.setEnabled(false);\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 2;\n        c.weightx = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(8, 15, 3, 0);\n        add(hint, c);\n        \n        updateSelection();\n    }\n\n\n    private JPanel presetsPanel;\n    private JList list;\n    private JButton removeButton;\n    private JButton upButton;\n    private JButton downButton;\n    private JTextField nameField;\n    private JTextArea descrArea;\n    private OQLEditorComponent previewArea;\n    \n    \n    private static class Model extends DefaultListModel<OQLQuery> {\n        \n        void fireChange() {\n            super.fireContentsChanged(this, 0, getSize() - 1);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/oql/CustomOQLQueries.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.oql;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Properties;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerStorage;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"CustomOQLQueries_SaveFailed=Failed to save OQL scripts.\",\n    \"CustomOQLQueries_LoadFailed=Failed to load saved OQL scripts.\"\n}) \npublic final class CustomOQLQueries {\n    \n    private static final String SAVED_OQL_QUERIES_FILENAME = \"oqlqueries\"; // NOI18N\n    \n    private static final String PROP_QUERY_NAME_KEY = \"query-name\"; // NOI18N\n    private static final String PROP_QUERY_DESCR_KEY = \"query-descr\"; // NOI18N\n    private static final String PROP_QUERY_SCRIPT_KEY = \"query-script\"; // NOI18N\n    \n    \n    private static CustomOQLQueries INSTANCE;\n    \n    private List<OQLQuery> customQueries;\n    \n    \n    public static synchronized CustomOQLQueries instance() {\n        if (INSTANCE == null) INSTANCE = new CustomOQLQueries();\n        return INSTANCE;\n    }\n    \n    \n    public synchronized boolean isEmpty() {\n        return customQueries.isEmpty();\n    }\n    \n    public synchronized void add(OQLQuery query) {\n        customQueries.add(0, query);\n        save();\n    }\n    \n    public synchronized void save(OQLQuery query) {\n        for (OQLQuery q : customQueries) {\n            if (q.getName().equals(query.getName())) {\n                q.setScript(query.getScript());\n                save();\n                break;\n            }\n        }\n    }\n    \n    public synchronized void set(List<OQLQuery> queries) {\n        customQueries.clear();\n        customQueries.addAll(queries);\n        save();\n    }\n    \n    public synchronized List<OQLQuery> list() {\n        List<OQLQuery> list = new ArrayList<>();\n        for (OQLQuery query : customQueries)\n            list.add(new OQLQuery(query.getScript(), query.getName(), query.getDescription()));\n        return list;\n    }\n    \n    \n    private void save() {\n        new RequestProcessor(\"OQL Scripts Saver\").post(new Runnable() { // NOI18N\n            public void run() {\n                try {\n                    Properties p = listToProperties(list());\n                    ProfilerStorage.saveGlobalProperties(p, SAVED_OQL_QUERIES_FILENAME);\n                } catch (Exception e) {\n                    ProfilerDialogs.displayError(Bundle.CustomOQLQueries_SaveFailed());\n                    Exceptions.printStackTrace(e);\n                }\n            }\n        });\n    }\n    \n    \n    private static List<OQLQuery> propertiesToList(List<OQLQuery> queries, Properties properties) {\n        int i = 0;\n        while (properties.containsKey(PROP_QUERY_NAME_KEY + \"-\" + i)) { // NOI18N\n            String name = properties.getProperty(PROP_QUERY_NAME_KEY + \"-\" + i); // NOI18N\n            String description = properties.getProperty(PROP_QUERY_DESCR_KEY + \"-\" + i, null); // NOI18N\n            String script = properties.getProperty(PROP_QUERY_SCRIPT_KEY + \"-\" + i, \"\"); // NOI18N\n            \n            if (name != null && script != null) queries.add(new OQLQuery(script, name, description));\n            \n            i++;\n        }\n        \n        return queries;\n    }\n\n    private static Properties listToProperties(List<OQLQuery> queries) {\n        Properties properties = new Properties();\n        \n        int i = 0;\n        for (OQLQuery query : queries) {\n            properties.put(PROP_QUERY_NAME_KEY + \"-\" + i, query.getName().trim()); // NOI18N\n            properties.put(PROP_QUERY_SCRIPT_KEY + \"-\" + i, query.getScript().trim()); // NOI18N\n            \n            String descr = query.getDescription();\n            if (descr != null) properties.put(PROP_QUERY_DESCR_KEY + \"-\" + i, descr); // NOI18N\n            \n            i++;\n        }\n\n        return properties;\n    }\n    \n    \n    private CustomOQLQueries() {\n        assert !SwingUtilities.isEventDispatchThread();\n        \n        customQueries = new ArrayList<>();\n        \n        try {\n            Properties p = new Properties();\n            ProfilerStorage.loadGlobalProperties(p, SAVED_OQL_QUERIES_FILENAME);\n            propertiesToList(customQueries, p);\n        } catch (Exception e) {\n            ProfilerDialogs.displayError(Bundle.CustomOQLQueries_LoadFailed());\n            Exceptions.printStackTrace(e);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/oql/EditableHistoryCombo.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.oql;\n\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.JComboBox;\nimport javax.swing.JTextField;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.JTextComponent;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass EditableHistoryCombo extends JComboBox {\n    \n    private Runnable onTextChange;\n    \n    EditableHistoryCombo() {\n        super(new ComboHistoryModel(10));\n        \n        setEditable(true);\n//        putClientProperty(\"JComboBox.isTableCellEditor\", Boolean.TRUE); // NOI18N\n        \n        setPrototypeDisplayValue(\"org.graalvm.visualvm.lib.ui.swing.XXXXXXXXXXXXXXXXXXXX\"); // NOI18N\n        Dimension dim = getPreferredSize();\n        dim.height = !UIUtils.isNimbusLookAndFeel() ? getMinimumSize().height :\n                     new JTextField(\"X\").getPreferredSize().height; // NOI18N\n        \n        setMinimumSize(dim);\n        setPreferredSize(dim);\n        setMaximumSize(dim);\n        \n        JTextComponent comp = getTextComponent();\n        if (comp != null) comp.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e)  { onChange(); }\n            public void removeUpdate(DocumentEvent e)  { onChange(); }\n            public void changedUpdate(DocumentEvent e) { onChange(); }\n            private void onChange() { if (onTextChange != null) onTextChange.run(); }\n        });\n    }\n    \n    \n    JTextComponent getTextComponent() {\n        Component comp = getEditor().getEditorComponent();\n        return comp instanceof JTextComponent ? (JTextComponent)comp : null;\n    }\n    \n    String getText() {\n        JTextComponent textC = getTextComponent();\n        return textC != null ? textC.getText() : getSelectedItem().toString();\n    }\n    \n    void setOnTextChangeHandler(Runnable handler) {\n        onTextChange = handler;\n    }\n    \n    \n    private static class ComboHistoryModel extends DefaultComboBoxModel {\n        \n        private final int historySize;\n        \n        \n        ComboHistoryModel(int historySize) {\n            this.historySize = historySize;\n        }\n        \n        \n        public void addElement(Object item) {\n            insertElementAt(item, 0);\n        }\n        \n        public void insertElementAt(Object item, int index) {\n            int current = getIndexOf(item);\n            if (current == index) return;\n            \n            if (current != -1) removeElementAt(current);\n            super.insertElementAt(item, index);\n            \n            if (getSize() > historySize) removeElementAt(historySize);\n            \n            setSelectedItem(item);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/oql/FilterUtils.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.oql;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.KeyEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.Icon;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.JToolBar;\nimport javax.swing.KeyStroke;\nimport javax.swing.RowFilter;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.text.JTextComponent;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableView;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.filters.TextFilter;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.CloseButton;\nimport org.graalvm.visualvm.lib.ui.results.ColoredFilter;\nimport org.graalvm.visualvm.lib.ui.results.PackageColorer;\nimport org.graalvm.visualvm.lib.ui.swing.InvisibleToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"OQLFilterUtils_ActionFilter=Filter\",\n    \"OQLFilterUtils_SidebarCaption=Object Filter:\",\n    \"OQLFilterUtils_FilterResults=Filter results ({0})\",\n    \"OQLFilterUtils_MatchCase=Match case\",\n    \"OQLFilterUtils_Close=Close Filter sidebar ({0})\",\n    \"OQLFilterUtils_InvalidRegexp=Entered regular expression is invalid:\\n{0}\",\n    \"OQLFilterUtils_FilterContains=Contains\",\n    \"OQLFilterUtils_FilterNotContains=Does Not Contain\",\n    \"OQLFilterUtils_FilterRegExp=Regular Expression\",\n    \"OQLFilterUtils_FilterSubclass=Subclass Of\",\n    \"OQLFilterUtils_FilterType=Filter type: {0}\",\n    \"OQLFilterUtils_InsertFilter=Insert Defined Filter\"\n})\nfinal class FilterUtils {\n    \n    private static final String FILTER_ACTION_KEY = \"filter-action-key\"; // NOI18N\n    \n    private static final String FILTER_CHANGED = \"filter-changed\"; // NOI18N\n    \n    \n    private static final int FILTER_INSTANCEOF = 100;\n    \n    \n//    public static boolean filterContains(ProfilerTable table, String filter) {\n//        return filterContains(table, filter, false, null);\n//    }\n//    \n//    public static boolean filterContains(ProfilerTable table, String filter, boolean matchCase, RowFilter excludes) {\n//        return filter(table, new TextFilter(filter, TextFilter.TYPE_INCLUSIVE, matchCase), excludes);\n//    }\n//    \n//    public static boolean filterNotContains(ProfilerTable table, String filter, boolean matchCase, RowFilter excludes) {\n//        return filter(table, new TextFilter(filter, TextFilter.TYPE_EXCLUSIVE, matchCase), excludes);\n//    }\n//    \n//    public static boolean filterRegExp(ProfilerTable table, String filter, RowFilter excludes) {\n//        return filter(table, new TextFilter(filter, TextFilter.TYPE_REGEXP, false), excludes);\n//    }\n    \n    public static boolean filter(TreeTableView view, final GenericFilter textFilter, final RowFilter excludesFilter) {\n        if (textFilter.isAll()) {\n            view.setViewFilter(null);\n            return false;\n        }\n        \n        view.setViewFilter(new HeapViewerNodeFilter() {\n            public boolean passes(HeapViewerNode node, Heap heap) {\n                if (textFilter.getType() != FILTER_INSTANCEOF) {\n                    String name = HeapViewerNode.getValue(node, DataType.NAME, heap);\n                    return name != null && textFilter.passes(name);\n                } else {\n                    JavaClass javaClass = HeapViewerNode.getValue(node, DataType.CLASS, heap);\n                    if (javaClass != null)\n                        for (String value : textFilter.getValues())\n                            if (isInstanceOf(javaClass, value)) return true;\n                    return false;\n                }\n            }\n\n\n            private boolean isInstanceOf(JavaClass javaClass, String className) {\n                if (javaClass != null) {\n//                    JavaClass superCls = javaClass.getSuperClass();\n                    JavaClass cls = javaClass;\n                    for (; cls != null; cls = cls.getSuperClass())\n                        if (cls.getName().equals(className)) return true;\n                }\n                return false;\n            }\n        });\n        return true;\n    }\n    \n    public static void filterSubclasses(String className, JComponent filterPanel) {\n        Object filterString = filterPanel.getClientProperty(\"FILTER_STRING\"); // NOI18N\n        if (filterString instanceof JTextComponent) {\n            ((JTextComponent)filterString).setText(className);\n        } else {\n            return;\n        }\n\n        Object filterType = filterPanel.getClientProperty(\"FILTER_TYPE\"); // NOI18N\n        if (filterType instanceof FilterType) {\n            ((FilterType)filterType).filterImpl(FILTER_INSTANCEOF, Icons.getIcon(LanguageIcons.CLASS), Bundle.OQLFilterUtils_FilterSubclass());\n        } else {\n            return;\n        }\n\n        Object filterAction = filterPanel.getClientProperty(\"FILTER_ACTION\"); // NOI18N\n        if (filterAction instanceof AbstractAction) {\n            ((AbstractAction)filterAction).actionPerformed(null);\n        } else {\n            return;\n        }\n    }\n    \n    public static JComponent createFilterPanel(final TreeTableView view) {\n        return createFilterPanel(view, null);\n    }\n    \n    public static JComponent createFilterPanel(final TreeTableView view, final RowFilter excludesFilter) {\n        return createFilterPanel(view, excludesFilter, null);\n    }\n    \n    public static JComponent createFilterPanel(final TreeTableView view, final RowFilter excludesFilter, Component[] options) {\n        JToolBar toolbar = new InvisibleToolbar();\n        if (UIUtils.isWindowsModernLookAndFeel())\n            toolbar.setBorder(BorderFactory.createEmptyBorder(2, 2, 1, 2));\n        else if (!UIUtils.isNimbusLookAndFeel() && !UIUtils.isAquaLookAndFeel())\n            toolbar.setBorder(BorderFactory.createEmptyBorder(1, 2, 1, 2));\n        \n        toolbar.add(Box.createHorizontalStrut(6));\n        toolbar.add(new JLabel(Bundle.OQLFilterUtils_SidebarCaption()));\n        toolbar.add(Box.createHorizontalStrut(3));\n        \n        final EditableHistoryCombo combo = new EditableHistoryCombo();        \n        final JTextComponent textC = combo.getTextComponent();\n        \n        JPanel comboContainer = new JPanel(new BorderLayout());\n        comboContainer.add(combo, BorderLayout.CENTER);\n        comboContainer.setMinimumSize(combo.getMinimumSize());\n        comboContainer.setPreferredSize(combo.getPreferredSize());\n        comboContainer.setMaximumSize(combo.getMaximumSize());\n        \n        toolbar.add(comboContainer);\n        \n        if (PackageColorer.hasRegisteredColors()) {\n            toolbar.add(new PopupButton() {\n                {\n                    setToolTipText(Bundle.OQLFilterUtils_InsertFilter());\n                }\n//                protected void displayPopup() {\n//                    JPopupMenu menu = new JPopupMenu();\n//                    populatePopup(menu);\n//                    if (menu.getComponentCount() > 0) {\n//                        Dimension size = menu.getPreferredSize();\n//                        size.width = Math.max(size.width, getWidth());\n//                        menu.setPreferredSize(size);\n//                        menu.show(this, 0, -size.height);\n//                    }\n//                }\n                protected void populatePopup(JPopupMenu popup) {\n                    for (final ColoredFilter color : PackageColorer.getRegisteredColors()) {\n                        if (color.getValue().trim().isEmpty()) continue;\n                        Icon icon = color.getColor() == null ? null : color.getIcon(12, 12);\n                        popup.add(new JMenuItem(color.getName(), icon) {\n                            protected void fireActionPerformed(ActionEvent event) {\n                                String current = getFilterString(combo);\n                                if (current == null) current = \"\"; // NOI18N\n                                if (!current.isEmpty()) current += \" \"; // NOI18N\n                                current += color.getValue();\n                                textC.setText(current);\n                                combo.requestFocusInWindow();\n                            }\n                        });\n                    }\n                }\n            });\n        }\n        \n        toolbar.add(Box.createHorizontalStrut(5));\n        \n        KeyStroke escKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);\n        KeyStroke filterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);\n        \n        final TextFilter activeFilter = new TextFilter() {\n            protected void handleInvalidFilter(String invalidValue, RuntimeException e) {\n                ProfilerDialogs.displayError(Bundle.OQLFilterUtils_InvalidRegexp(invalidValue));\n            }\n        };\n        final TextFilter currentFilter = new TextFilter();\n        \n        final JButton filter = new JButton(Bundle.OQLFilterUtils_ActionFilter(), Icons.getIcon(GeneralIcons.FILTER)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                final JButton _this = this;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        activeFilter.copyFrom(currentFilter);\n                        if (filter(view, activeFilter, excludesFilter))\n                            combo.addItem(activeFilter.getValue());\n                        putClientProperty(FILTER_CHANGED, null);\n                        updateFilterButton(_this, currentFilter, activeFilter);\n                    }\n                });\n            }\n        };\n        String filterAccelerator = ActionsSupport.keyAcceleratorString(filterKey);\n        filter.setToolTipText(Bundle.OQLFilterUtils_FilterResults(filterAccelerator));\n        filter.putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n        \n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(final ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        if (filter.isEnabled()) {\n                            filter.doClick();\n                            combo.requestFocusInWindow();\n                        }\n                    }\n                });\n            }\n        };\n        installAction(filter, filterAction, filterKey, FILTER_ACTION_KEY);\n        toolbar.add(filter);\n        \n        updateFilterButton(filter, currentFilter, activeFilter);\n        \n        toolbar.add(Box.createHorizontalStrut(2));\n        \n        toolbar.addSeparator();\n        \n        toolbar.add(Box.createHorizontalStrut(1));\n        \n        final JToggleButton matchCase = new JToggleButton(Icons.getIcon(GeneralIcons.MATCH_CASE)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                if (isEnabled()) SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        currentFilter.setCaseSensitive(isSelected());\n                        updateFilterButton(filter, currentFilter, activeFilter);\n                    }\n                });\n            }\n        };\n        matchCase.setToolTipText(Bundle.OQLFilterUtils_MatchCase());\n        installAction(matchCase, filterAction, filterKey, FILTER_ACTION_KEY);\n        \n        FilterType filterType = new FilterType(Icons.getIcon(GeneralIcons.FILTER_CONTAINS)) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new JMenuItem(Bundle.OQLFilterUtils_FilterContains(), Icons.getIcon(GeneralIcons.FILTER_CONTAINS)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(TextFilter.TYPE_INCLUSIVE, getIcon(), getText());\n                    }\n                });\n                popup.add(new JMenuItem(Bundle.OQLFilterUtils_FilterNotContains(), Icons.getIcon(GeneralIcons.FILTER_NOT_CONTAINS)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(TextFilter.TYPE_EXCLUSIVE, getIcon(), getText());\n                    }\n                });\n                popup.add(new JMenuItem(Bundle.OQLFilterUtils_FilterRegExp(), Icons.getIcon(GeneralIcons.FILTER_REG_EXP)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(TextFilter.TYPE_REGEXP, getIcon(), getText());\n                    }\n                });\n                popup.add(new JMenuItem(Bundle.OQLFilterUtils_FilterSubclass(), Icons.getIcon(LanguageIcons.CLASS)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(FILTER_INSTANCEOF, getIcon(), getText());\n                    }\n                });\n            }\n            protected void filterImpl(final int type, final Icon icon, final String name) {\n                if (type == TextFilter.TYPE_REGEXP || type == FILTER_INSTANCEOF) {\n                    matchCase.setEnabled(false);\n                    matchCase.setSelected(false);\n                } else {\n                    if (!matchCase.isEnabled()) {\n                        matchCase.setSelected(currentFilter.isCaseSensitive());\n                        matchCase.setEnabled(true);\n                    }\n                }\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setIcon(icon);\n                        setToolTipText(Bundle.OQLFilterUtils_FilterType(name));\n                        currentFilter.setType(type);\n                        updateFilterButton(filter, currentFilter, activeFilter);\n                    }\n                });\n            }\n        };\n        filterType.setToolTipText(Bundle.OQLFilterUtils_FilterType(Bundle.OQLFilterUtils_FilterContains()));\n        installAction(filterType, filterAction, filterKey, FILTER_ACTION_KEY);\n        toolbar.add(filterType);\n        \n        toolbar.add(matchCase);\n        \n        if (options != null) for (Component option : options) toolbar.add(option);\n        \n        toolbar.add(Box.createHorizontalStrut(2));\n        \n        combo.setOnTextChangeHandler(new Runnable() {\n            public void run() {\n                currentFilter.setValue(getFilterString(combo));\n                updateFilterButton(filter, currentFilter, activeFilter);\n            }\n        });\n        \n        final JPanel panel = new JPanel(new BorderLayout()) {\n            {\n                super.setVisible(false);\n            }\n            public void setVisible(boolean visible) {\n                super.setVisible(visible);\n                if (!visible) view.getComponent().requestFocusInWindow();\n            }\n            public boolean requestFocusInWindow() {\n                if (textC != null) textC.selectAll();\n                return combo.requestFocusInWindow();\n            }\n        };\n        panel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UIManager.getColor(\"controlShadow\"))); // NOI18N\n        panel.add(toolbar, BorderLayout.CENTER);\n        \n        final Runnable hider = new Runnable() {\n            public void run() {\n                boolean wasAll = activeFilter.isAll();\n                activeFilter.setValue(\"\"); // NOI18N\n                updateFilterButton(filter, currentFilter, activeFilter);\n                if (!wasAll) filter(view, activeFilter, excludesFilter);\n                panel.setVisible(false);\n            }\n        };\n        JButton closeButton = CloseButton.create(hider);\n        closeButton.setFocusable(true);\n        String escAccelerator = ActionsSupport.keyAcceleratorString(escKey);\n        closeButton.setToolTipText(Bundle.OQLFilterUtils_Close(escAccelerator));\n        panel.add(closeButton, BorderLayout.EAST);\n        \n        String HIDE = \"hide-action\"; // NOI18N\n        InputMap map = panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        Action hiderAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { hider.run(); }\n        };\n        panel.getActionMap().put(HIDE, hiderAction);\n        map.put(escKey, HIDE);\n        \n        if (textC != null) {\n            map = textC.getInputMap();\n            Action _filterAction = new AbstractAction() {\n                public void actionPerformed(final ActionEvent e) {\n                    if (combo.isPopupVisible()) combo.hidePopup();\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { if (filter.isEnabled()) filter.doClick(); }\n                    });\n                }\n            };\n            textC.getActionMap().put(FILTER_ACTION_KEY, _filterAction);\n            map.put(filterKey, FILTER_ACTION_KEY);\n        }\n        \n        panel.putClientProperty(\"SET_FILTER_CHANGED\", new AbstractAction() { // NOI18N\n            public void actionPerformed(final ActionEvent e) {\n                filter.putClientProperty(FILTER_CHANGED, Boolean.TRUE);\n                updateFilterButton(filter, currentFilter, activeFilter);\n            }\n        });\n        \n        panel.putClientProperty(\"FILTER_STRING\", textC); // NOI18N\n        panel.putClientProperty(\"FILTER_TYPE\", filterType); // NOI18N\n        panel.putClientProperty(\"FILTER_ACTION\", filterAction); // NOI18N\n        \n        return panel;\n    }\n    \n    private static abstract class FilterType extends PopupButton {\n        FilterType(Icon icon) { super(icon); }\n        protected abstract void filterImpl(final int type, final Icon icon, final String name);\n    }\n    \n    private static void installAction(JComponent comp, Action action, KeyStroke keyStroke, String actionKey) {\n        comp.getActionMap().put(actionKey, action);\n        comp.getInputMap().put(keyStroke, actionKey);\n    }\n    \n    private static String getFilterString(EditableHistoryCombo combo) {\n        String filter = combo.getText();\n        return filter == null ? null : filter.trim();\n    }\n    \n    private static void updateFilterButton(JButton button, TextFilter currentFilter, TextFilter activeFilter) {\n        if (Boolean.TRUE.equals(button.getClientProperty(FILTER_CHANGED))) button.setEnabled(true);\n        else button.setEnabled(!currentFilter.equals(activeFilter));\n    }\n    \n    private static abstract class Filter extends RowFilter {\n\n        public boolean equals(Object o) {\n            return o instanceof Filter;\n        }\n        \n        public int hashCode() {\n            return Integer.MAX_VALUE;\n        }\n    \n    }\n    \n    \n    // Do not create instances of this class\n    private FilterUtils() {}\n    \n    \n//    // Default keybinding Ctrl+G for Filter action\n//    private static interface Support { @ServiceProvider(service=ActionsSupportProvider.class, position=100)\n//        public static final class FilterActionProvider extends ActionsSupportProvider {\n//            public KeyStroke registerAction(String actionKey, Action action, ActionMap actionMap, InputMap inputMap) {\n//                if (!FILTER_ACTION_KEY.equals(actionKey)) return null;\n//                \n//                KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.CTRL_MASK);\n//                actionMap.put(actionKey, action);\n//                inputMap.put(ks, actionKey);\n//\n//                return ks;\n//            }\n//        }\n//    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/oql/OQLConsoleProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.oql;\n\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapViewerFeature.Provider.class)\npublic class OQLConsoleProvider extends HeapViewerFeature.Provider {\n    \n    public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n        if (JavaHeapFragment.isJavaHeap(context))\n            return new OQLConsoleView(context, actions);\n\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/oql/OQLConsoleView.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.oql;\n\nimport java.awt.BorderLayout;\nimport java.awt.CardLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ItemEvent;\nimport java.net.URL;\nimport java.text.Format;\nimport java.text.NumberFormat;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.TreeSet;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.BoundedRangeModel;\nimport javax.swing.ButtonGroup;\nimport javax.swing.DefaultBoundedRangeModel;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JComboBox;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JProgressBar;\nimport javax.swing.JTabbedPane;\nimport javax.swing.JToggleButton;\nimport javax.swing.JToolBar;\nimport javax.swing.KeyStroke;\nimport javax.swing.ListCellRenderer;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.plaf.basic.BasicSplitPaneDivider;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.options.HeapViewerOptionsCategory;\nimport org.graalvm.visualvm.heapviewer.ui.HTMLView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.graalvm.visualvm.heapviewer.ui.PluggableTreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.OQLEngine;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedSplitPane;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.netbeans.api.options.OptionsDisplayer;\nimport org.netbeans.modules.autoupdate.ui.api.PluginManager;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.TopComponent;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"OQLConsoleView_Name=OQL Console\",\n    \"OQLConsoleView_Description=OQL Console\",\n    \"OQLConsoleView_CannotResolveClassMsg=Cannot resolve class\",\n    \"OQLConsoleView_CannotResolveInstanceMsg=Cannot resolve instance\",\n    \"OQLConsoleView_ViewName=Results\",\n    \"OQLConsoleView_OQLQuery=OQL Query:\",\n    \"OQLConsoleView_RunAction=Run\",\n    \"OQLConsoleView_RunActionTooltip=Execute OQL script - Ctrl+R\",\n    \"OQLConsoleView_CancelAction=Cancel\",\n    \"OQLConsoleView_CancelActionTooltip=Cancel OQL script execution\",\n    \"OQLConsoleView_LoadAction=Load Script\",\n    \"OQLConsoleView_LoadActionTooltip=Load OQL script\",\n    \"OQLConsoleView_SaveAction=Save Script\",\n    \"OQLConsoleView_SaveActionTooltip=Save OQL script\",\n    \"OQLConsoleView_EditAction=Edit Scripts\",\n    \"OQLConsoleView_EditActionTooltip=Edit Custom OQL scripts\",\n    \"OQLConsoleView_ExecutingProgress=Executing...\",\n    \"OQLConsoleView_Results=Results:\",\n    \"OQLConsoleView_ObjectsTooltip=Objects\",\n    \"OQLConsoleView_HTMLTooltip=HTML\",\n    \"OQLConsoleView_Details=Details:\",\n    \"OQLConsoleView_InitializingEngine=<initializing OQL engine...>\",\n    \"OQLConsoleView_EngineNotAvailable=<OQL engine not available>\",\n    \"OQLConsoleView_EngineFailed=<OQL engine failed to initialize>\",\n    \"OQLConsoleView_NoJSEngine=Required JavaScript engine not available in host JDK.\",\n    \"OQLConsoleView_InstallJSEngine=Download & install the GraalJS engine\",\n    \"OQLConsoleView_Packages=Packages\",\n    \"OQLConsoleView_Classes=Classes\",\n    \"OQLConsoleView_Instances=Instances\",\n    \"OQLConsoleView_Aggregation=Aggregation:\",\n    \"OQLConsoleView_ResultsLimit=Results Limit:\",\n    \"OQLConsoleView_SaveOnClosingCaption=OQL Script Not Saved\",\n    \"OQLConsoleView_SaveOnClosingMsg=<html><b>The OQL script has been modified.</b><br><br>Save it before closing the heap viewer?</html>\",\n    \"OQLConsoleView_NoSaveOnCloseBtn=Close Without Saving\"\n})\npublic class OQLConsoleView extends HeapViewerFeature {\n    \n    private static final int RESULTS_LIMIT = Integer.getInteger(\"OQLController.limitResults\", 100); // NOI18N\n    \n    \n    private static final String GRAALJS_CODENAMEBASE = \"org.graalvm.visualvm.modules.graaljs\"; // NOI18N\n    private static final String GRAALJS_DISPLAYNAME  = \"GraalJS\"; // NOI18N\n    \n    \n    private static enum Aggregation {\n        PACKAGES (Bundle.OQLConsoleView_Packages(), Icons.getIcon(LanguageIcons.PACKAGE)),\n        CLASSES (Bundle.OQLConsoleView_Classes(), Icons.getIcon(LanguageIcons.CLASS)),\n        INSTANCES (Bundle.OQLConsoleView_Instances(), Icons.getIcon(LanguageIcons.INSTANCE));\n        \n        private final String aggregationName;\n        private final Icon aggregationIcon;\n        private Aggregation(String aggregationName, Icon aggregationIcon) { this.aggregationName = aggregationName; this.aggregationIcon = aggregationIcon; }\n        public String toString() { return aggregationName; }\n        public Icon getIcon() { return aggregationIcon; }\n    }\n    \n    \n    private static final Color SEPARATOR_COLOR = UIManager.getColor(\"Separator.foreground\"); // NOI18N\n    \n    private final HeapContext context;\n    private final HeapViewerActions actions;\n    \n    private ProfilerToolbar toolbar;\n    private ProfilerToolbar objectsToolbar;\n    private ProfilerToolbar pluginsToolbar;\n    private ProfilerToolbar htmlToolbar;\n    private ProfilerToolbar resultsToolbar;\n    private ProfilerToolbar progressToolbar;\n    \n    private JComponent component;\n    \n    private Action runAction;\n    private Action cancelAction;\n    private Action loadAction;\n    private Action saveAction;\n    private Action editAction;\n    \n    private JLabel progressLabel;\n    private JProgressBar progressBar;\n    \n    private JComboBox limitCombo;\n    \n    private OQLEditorComponent editor;\n    \n    private JPanel resultsContainer;\n    private HTMLView htmlView;\n    private PluggableTreeTableView objectsView;\n    \n    private JToggleButton rObjects;\n    private JToggleButton rHTML;\n    \n    private Aggregation aggregation = Aggregation.INSTANCES;\n    \n    private JToggleButton tbPackages;\n    private JToggleButton tbClasses;\n    private JToggleButton tbInstances;\n    \n    private OQLQueryExecutor oqlExecutor;\n    \n    private boolean queryValid;\n    \n    private OQLQuery currentQuery;\n    \n    \n    public OQLConsoleView(HeapContext context, HeapViewerActions actions) {\n        super(\"java_objects_oql\", Bundle.OQLConsoleView_Name(), Bundle.OQLConsoleView_Description(), Icons.getIcon(HeapWalkerIcons.OQL_CONSOLE), 1000); // NOI18N\n        \n        this.context = context;\n        this.actions = actions;\n    }\n    \n    public JComponent getComponent() {\n        if (component == null) init();\n        return component;\n    }\n\n    public ProfilerToolbar getToolbar() {\n        if (toolbar == null) init();\n        return toolbar;\n    }\n    \n    \n    protected void willBeClosed(Runnable viewSelector) {\n        if (editor != null && editor.isChanged() && !editor.getScript().isEmpty() && saveAction.isEnabled()) {\n            viewSelector.run();\n            \n            Container c = editor;\n            while (c != null) {\n                Container p = c.getParent();\n                if (p instanceof JTabbedPane) {\n                    ((JTabbedPane)p).setSelectedComponent(c);\n                } else if (p instanceof TopComponent) {\n                    ((TopComponent)p).requestActive();\n                    break;\n                }\n                c = p;\n            }\n            \n            \n            JButton saveButton = new JButton(saveAction) {\n                public void addActionListener(ActionListener l) {\n                    if (l == saveAction) super.addActionListener(l);\n                }\n                public void removeActionListener(ActionListener l) {\n                    if (l == saveAction) super.removeActionListener(l);\n                }\n            };\n            JButton closeButton = new JButton(Bundle.OQLConsoleView_NoSaveOnCloseBtn());\n            DialogDescriptor dd = new DialogDescriptor(Bundle.OQLConsoleView_SaveOnClosingMsg(), Bundle.OQLConsoleView_SaveOnClosingCaption(), true, new Object[] { saveButton, closeButton }, saveButton, DialogDescriptor.DEFAULT_ALIGN, null, null);\n            dd.setMessageType(NotifyDescriptor.QUESTION_MESSAGE);\n            Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n            saveAction.putValue(\"NOTIFIER\", new Runnable() { // NOI18N\n                public void run() {\n                    saveAction.putValue(\"NOTIFIER\", null); // NOI18N\n                    d.setVisible(false);\n                }\n            });\n            d.setVisible(true);\n        }\n    }\n    \n    @Override\n    protected void closed() {\n        if (objectsView != null) objectsView.closed();\n    }\n    \n    \n    private void init() {\n        toolbar = ProfilerToolbar.create(false);\n        \n        component = new JPanel(new BorderLayout());\n        component.setOpaque(true);\n        component.setBackground(UIUtils.getProfilerResultsBackground());\n        \n        JLabel l = new JLabel(Bundle.OQLConsoleView_InitializingEngine(), JLabel.CENTER);\n        l.setEnabled(false);\n        l.setOpaque(false);\n        component.add(l, BorderLayout.CENTER);\n        \n        VisualVM.getInstance().runTask(new Runnable() {\n            @Override\n            public void run() {\n                Heap heap = context.getFragment().getHeap();\n                \n                if (!OQLEngine.isOQLSupported()) {\n                    notifyFailedOQL(false);\n                } else try {\n                    final OQLEngine oqlEngine = new OQLEngine(heap);\n                    oqlExecutor = new OQLQueryExecutor(oqlEngine) {\n                        @Override\n                        protected void queryStarted(BoundedRangeModel model) {\n                            OQLConsoleView.this.queryStarted(model);\n                        }\n                        @Override\n                        protected void queryFinished(boolean hasObjectsResults, boolean hasHTMLResults, String errorMessage) {\n                            OQLConsoleView.this.queryFinished(hasObjectsResults, hasHTMLResults, errorMessage);\n                        }\n                    };\n                    \n                    TreeTableViewColumn[] ownColumns = new TreeTableViewColumn[] {\n                        new TreeTableViewColumn.Name(),\n                        new TreeTableViewColumn.Count(heap, false, false),\n                        new TreeTableViewColumn.OwnSize(heap, true, true),\n                        new TreeTableViewColumn.RetainedSize(heap, true, false)\n                    };\n\n                    objectsView = new PluggableTreeTableView(\"java_objects_oql\", context, actions, ownColumns) { // NOI18N\n                        protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                            int aggr = Aggregation.INSTANCES.equals(aggregation) ? 0 :\n                                       Aggregation.CLASSES.equals(aggregation) ? 1 : 2;\n                            return oqlExecutor.getQueryObjects(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress, aggr);\n                        }\n                        protected JComponent createComponent() {\n                            JComponent comp = super.createComponent();\n\n                            setFilterComponent(FilterUtils.createFilterPanel(this));\n\n                            return comp;\n                        }\n                    };\n                    objectsView.setViewName(Bundle.OQLConsoleView_ViewName());\n\n                    htmlView = new HTMLView(\"java_objects_oql\", context, actions, oqlExecutor.getQueryHTML()) { // NOI18N\n                        protected HeapViewerNode nodeForURL(URL url, HeapContext context) {\n                            return OQLConsoleView.getNode(url, context);\n                        }\n                    };\n                    \n                    SwingUtilities.invokeLater(new Runnable() {\n                        @Override\n                        public void run() {\n//                            toolbar.addSpace(2);\n//                            toolbar.addSeparator();\n//                            toolbar.addSpace(5);\n//\n//                            toolbar.add(new GrayLabel(Bundle.OQLConsoleView_OQLQuery()));\n//                            toolbar.addSpace(2);\n\n                            runAction = new RunAction();\n\n                            JButton runButton = new JButton(runAction) {\n                                public Dimension getPreferredSize() {\n                                    Dimension d = super.getPreferredSize();\n                                    d.width += 6;\n                                    return d;\n                                }\n                                public Dimension getMinimumSize() {\n                                    return getPreferredSize();\n                                }\n                                public Dimension getMaximumSize() {\n                                    return getPreferredSize();\n                                }\n                            };\n                            runButton.putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n\n                            cancelAction = new AbstractAction(Bundle.OQLConsoleView_CancelAction(), Icons.getIcon(GeneralIcons.STOP)) {\n                                {\n                                    putValue(Action.SHORT_DESCRIPTION, Bundle.OQLConsoleView_CancelActionTooltip());\n                                }\n                                public void actionPerformed(ActionEvent e) {\n                                    cancelQuery();\n                                }\n                            };\n\n                            JButton cancelButton = new JButton(cancelAction);\n                            cancelButton.setHideActionText(true);\n\n                            loadAction = new AbstractAction(Bundle.OQLConsoleView_LoadAction(), OQLQueries.ICON_LOAD) {\n                                {\n                                    putValue(Action.SHORT_DESCRIPTION, Bundle.OQLConsoleView_LoadActionTooltip());\n                                }\n                                public void actionPerformed(ActionEvent e) {\n                                    if (e.getSource() instanceof JComponent) {\n                                        JPopupMenu p = new JPopupMenu();\n                                        OQLQueries.instance().populateLoadQuery(p, currentQuery, new OQLQueries.Handler() {\n                                            protected void querySelected(OQLQuery query) {\n                                                currentQuery = query;\n                                                if (editor != null) editor.setScript(currentQuery.getScript());\n                                            }\n                                        });\n\n                                        JComponent c = (JComponent)e.getSource();\n                                        if (p.getComponentCount() > 0) {\n                                            if (c.getClientProperty(\"POPUP_LEFT\") != null) p.show(c, c.getWidth() + 1, 0); // NOI18N\n                                            else p.show(c, 0, c.getHeight() + 1);\n                                        }\n\n                                    }\n                                }\n                            };\n\n                            JButton loadButton = new JButton(loadAction);\n                            loadButton.setHideActionText(true);\n\n                            saveAction = new AbstractAction(Bundle.OQLConsoleView_SaveAction(), OQLQueries.ICON_SAVE) {\n                                {\n                                    putValue(Action.SHORT_DESCRIPTION, Bundle.OQLConsoleView_SaveActionTooltip());\n                                }\n                                public void actionPerformed(ActionEvent e) {\n                                    if (e.getSource() instanceof JComponent) {\n                                        JPopupMenu p = new JPopupMenu();\n                                        OQLQueries.instance().populateSaveQuery(p, currentQuery, editor.getScript(), new OQLQueries.Handler() {\n                                            protected void querySelected(OQLQuery query) {\n                                                currentQuery = query;\n                                                editor.clearChanged();\n                                                \n                                                Object notifier = saveAction.getValue(\"NOTIFIER\"); // NOI18N\n                                                if (notifier instanceof Runnable) ((Runnable)notifier).run();\n                                            }\n                                        });\n\n                                        JComponent c = (JComponent)e.getSource();\n                                        if (p.getComponentCount() > 0) {\n                                            if (c.getClientProperty(\"POPUP_LEFT\") != null) p.show(c, c.getWidth() + 1, 0); // NOI18N\n                                            else p.show(c, 0, c.getHeight() + 1);\n                                        }\n\n                                    }\n                                }\n                            };\n\n                            JButton saveButton = new JButton(saveAction);\n                            saveButton.setHideActionText(true);\n\n                            editAction = new AbstractAction(Bundle.OQLConsoleView_EditAction(), Icons.getIcon(HeapWalkerIcons.RULES)) {\n                                {\n                                    putValue(Action.SHORT_DESCRIPTION, Bundle.OQLConsoleView_EditActionTooltip());\n                                }\n                                public void actionPerformed(ActionEvent e) {\n                                    OptionsDisplayer.getDefault().open(HeapViewerOptionsCategory.OPTIONS_HANDLE);\n                                }\n                            };\n\n                            JButton editButton = new JButton(editAction);\n                            editButton.setHideActionText(true);\n\n\n                            progressToolbar = ProfilerToolbar.create(false);\n                            progressToolbar.getComponent().setVisible(false);\n\n                            progressToolbar.addSpace(2);\n                            progressToolbar.addSeparator();\n                            progressToolbar.addSpace(5);\n\n                            progressLabel = new GrayLabel(Bundle.OQLConsoleView_ExecutingProgress());\n                            progressToolbar.add(progressLabel);\n\n                            progressToolbar.addSpace(8);\n\n                            progressBar = new JProgressBar(JProgressBar.HORIZONTAL) {\n                                public Dimension getPreferredSize() {\n                                    Dimension dim = super.getMinimumSize();\n                                    dim.width = 120;\n                                    return dim;\n                                }\n                                public Dimension getMinimumSize() {\n                                    return getPreferredSize();\n                                }\n                                public Dimension getMaximumSize() {\n                                    return getPreferredSize();\n                                }\n                            };\n                            progressToolbar.add(progressBar);\n\n//                            toolbar.add(runButton);\n//                    //        toolbar.addSpace(2);\n//                            toolbar.add(cancelButton);\n//\n//                            toolbar.addSpace(5);\n//\n//                            toolbar.add(loadButton);\n//                            toolbar.add(saveButton);\n//                            toolbar.add(editButton);\n\n                            resultsToolbar = ProfilerToolbar.create(false);\n\n                            resultsToolbar.addSpace(2);\n                            resultsToolbar.addSeparator();\n                            resultsToolbar.addSpace(5);\n\n                            resultsToolbar.add(new GrayLabel(Bundle.OQLConsoleView_Results()));\n                            resultsToolbar.addSpace(3);\n\n                            ButtonGroup resultsBG = new ButtonGroup();\n\n                            rObjects = new JToggleButton(Icons.getIcon(ProfilerIcons.TAB_HOTSPOTS), true) {\n                                protected void fireItemStateChanged(ItemEvent e) {\n                                    if (e.getStateChange() == ItemEvent.SELECTED) {\n                                        if (resultsContainer != null) ((CardLayout)resultsContainer.getLayout()).first(resultsContainer);\n                                        if (objectsToolbar != null) objectsToolbar.getComponent().setVisible(true);\n                                        if (pluginsToolbar != null) pluginsToolbar.getComponent().setVisible(true);\n                                        if (htmlToolbar != null) htmlToolbar.getComponent().setVisible(false);\n                                    }\n                                }\n                            };\n                            rObjects.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n                            rObjects.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n                            rObjects.setToolTipText(Bundle.OQLConsoleView_ObjectsTooltip());\n                            resultsBG.add(rObjects);\n                            resultsToolbar.add(rObjects);\n\n                            rHTML = new JToggleButton(Icons.getIcon(HeapWalkerIcons.PROPERTIES)) {\n                                protected void fireItemStateChanged(ItemEvent e) {\n                                    if (e.getStateChange() == ItemEvent.SELECTED) {\n                                        if (resultsContainer != null) ((CardLayout)resultsContainer.getLayout()).last(resultsContainer);\n                                        if (objectsToolbar != null) objectsToolbar.getComponent().setVisible(false);\n                                        if (pluginsToolbar != null) pluginsToolbar.getComponent().setVisible(false);\n                                        if (htmlToolbar != null) htmlToolbar.getComponent().setVisible(true);\n                                    }\n                                }\n                            };\n                            rHTML.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n                            rHTML.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n                            rHTML.setToolTipText(Bundle.OQLConsoleView_HTMLTooltip());\n                            resultsBG.add(rHTML);\n                            resultsToolbar.add(rHTML);\n                            \n                            objectsToolbar = ProfilerToolbar.create(false);\n                            objectsToolbar.addSpace(8);\n                            objectsToolbar.add(new GrayLabel(Bundle.OQLConsoleView_Aggregation()));\n                            objectsToolbar.addSpace(2);\n\n                            final ButtonGroup aggregationBG = new ButtonGroup();\n                            class AggregationButton extends JToggleButton {\n                                private final Aggregation aggregation;\n                                AggregationButton(Aggregation aggregation, boolean selected) {\n                                    super(aggregation.getIcon(), selected);\n                                    this.aggregation = aggregation;\n                                    setToolTipText(aggregation.toString());\n                                    aggregationBG.add(this);\n                                }\n                                protected void fireItemStateChanged(ItemEvent e) {\n                                    // invoked also from constructor: super(aggregation.getIcon(), selected)\n                                    // in this case aggregation is still null, ignore the event...\n                                    if (e.getStateChange() == ItemEvent.SELECTED && aggregation != null) setAggregation(aggregation);\n                                }\n                            }\n\n                            tbPackages = new AggregationButton(Aggregation.PACKAGES, Aggregation.PACKAGES.equals(aggregation));\n                            tbPackages.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n                            tbPackages.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n                            objectsToolbar.add(tbPackages);\n\n                            tbClasses = new AggregationButton(Aggregation.CLASSES, Aggregation.CLASSES.equals(aggregation));\n                            tbClasses.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n                            tbClasses.putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n                            objectsToolbar.add(tbClasses);\n\n                            tbInstances = new AggregationButton(Aggregation.INSTANCES, Aggregation.INSTANCES.equals(aggregation));\n                            tbInstances.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n                            tbInstances.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n                            objectsToolbar.add(tbInstances);\n                            \n                            resultsToolbar.add(objectsToolbar);\n\n                            if (objectsView.hasPlugins()) {\n                                pluginsToolbar = ProfilerToolbar.create(false);\n                    //            detailsToolbar.addSpace(2);\n                    //            detailsToolbar.addSeparator();\n                                pluginsToolbar.addSpace(8);\n\n                                pluginsToolbar.add(new GrayLabel(Bundle.OQLConsoleView_Details()));\n                                pluginsToolbar.addSpace(2);\n\n                                pluginsToolbar.add(objectsView.getToolbar());\n\n                                resultsToolbar.add(pluginsToolbar);\n                            }\n                            \n                            htmlToolbar = ProfilerToolbar.create(false);\n                            htmlToolbar.getComponent().setVisible(false);\n                            htmlToolbar.addSpace(8);\n                            htmlToolbar.add(new GrayLabel(Bundle.OQLConsoleView_ResultsLimit()));\n                            htmlToolbar.addSpace(3);\n                            \n                            Set<Integer> limits = new TreeSet<>();\n                            limits.add(10);\n                            limits.add(100);\n                            limits.add(1000);\n//                            limits.add(10000);\n                            limits.add(RESULTS_LIMIT);\n                            limitCombo = new JComboBox(limits.toArray());\n                            limitCombo.setSelectedItem(RESULTS_LIMIT);\n                            final Format numberFormat = NumberFormat.getNumberInstance();\n                            final ListCellRenderer rendererImpl = limitCombo.getRenderer();\n                            ListCellRenderer renderer = new ListCellRenderer() {\n                                @Override\n                                public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {\n                                    return rendererImpl.getListCellRendererComponent(list, numberFormat.format(value), index, isSelected, cellHasFocus);\n                                }\n                            };\n                            limitCombo.setRenderer(renderer);\n                            htmlToolbar.add(limitCombo);\n                            \n                            resultsToolbar.add(htmlToolbar);\n\n                            toolbar.add(resultsToolbar);\n\n                            toolbar.add(progressToolbar);\n\n                            editor = new OQLEditorComponent(oqlEngine) {\n                                protected void validityChanged(boolean valid) {\n                                    queryValid = valid;\n                                    updateUIState();\n                                }\n                            };\n\n                            resultsContainer = new JPanel(new CardLayout());\n                            resultsContainer.add(objectsView.getComponent());\n                            resultsContainer.add(new ResultsView(htmlView.getComponent()));\n\n                            JExtendedSplitPane masterSplit = new JExtendedSplitPane(JExtendedSplitPane.VERTICAL_SPLIT, true, resultsContainer, new EditorView(editor));\n                            BasicSplitPaneDivider masterDivider = ((BasicSplitPaneUI)masterSplit.getUI()).getDivider();\n                            masterDivider.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, SEPARATOR_COLOR));\n                            masterDivider.setDividerSize(6);\n                            masterSplit.setBorder(BorderFactory.createEmptyBorder());\n                            masterSplit.setResizeWeight(0.70d);\n\n                            component.removeAll();\n                            component.add(masterSplit, BorderLayout.CENTER);\n                            \n                            Container parent = component.getParent();\n                            if (parent != null) {\n                                parent.invalidate();\n                                parent.revalidate();\n                                parent.repaint();\n                            }\n                            \n                            JComponent toolbarComp = toolbar.getComponent();\n                            setShortcut(runAction, toolbarComp);\n                            setShortcut(runAction, component);\n                            toolbarComp.repaint();\n\n                            updateUIState();\n                        }\n                    });\n                } catch (Exception e) {\n                    notifyFailedOQL(true);\n                }\n            }\n        });\n    }\n    \n    private void setShortcut(Action a, JComponent jc) {\n        Object actionName = a.getValue(Action.ACTION_COMMAND_KEY);\n        KeyStroke shortcut = (KeyStroke) a.getValue(Action.ACCELERATOR_KEY);\n        jc.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(shortcut, actionName);\n        jc.getActionMap().put(actionName, a);\n    }\n\n    private void notifyFailedOQL(final boolean available) {\n        SwingUtilities.invokeLater(new Runnable() {\n            @Override\n            public void run() {\n                if (available || hasDefaultJS()) {\n                    String s = available ? Bundle.OQLConsoleView_EngineFailed() : Bundle.OQLConsoleView_EngineNotAvailable();\n                    JLabel l = new JLabel(s, JLabel.CENTER);\n                    l.setEnabled(false);\n                    l.setOpaque(false);\n\n                    component.removeAll();\n                    component.add(l, BorderLayout.CENTER);\n                } else {\n                    JLabel l = new JLabel(Bundle.OQLConsoleView_NoJSEngine(), JLabel.CENTER);\n                    l.setEnabled(false);\n                    l.setOpaque(false);\n                    JButton b = new JButton() {\n                        protected void fireActionPerformed(ActionEvent e) {\n                            super.fireActionPerformed(e);\n                            PluginManager.installSingle(GRAALJS_CODENAMEBASE, GRAALJS_DISPLAYNAME);\n                        }\n                    };\n                    Mnemonics.setLocalizedText(b, Bundle.OQLConsoleView_InstallJSEngine());\n                    JPanel p = new JPanel(new GridBagLayout());\n                    p.setOpaque(false);\n                    GridBagConstraints c = new GridBagConstraints();\n                    c.gridy = 0;\n                    c.insets = new Insets(0, 0, 8, 0);\n                    p.add(l, c);\n                    c = new GridBagConstraints();\n                    c.gridy = 1;\n                    p.add(b, c);\n                    component.removeAll();\n                    component.add(p, BorderLayout.CENTER);\n                }\n\n                Container parent = component.getParent();\n                if (parent != null) {\n                    parent.invalidate();\n                    parent.revalidate();\n                    parent.repaint();\n                }\n            }\n        });\n    }\n    \n    private static boolean hasDefaultJS() {\n        String javaVersion = System.getProperty(\"java.specification.version\"); // NOI18N\n        if (javaVersion == null) return true;\n        return javaVersion.startsWith(\"1.8\")  // NOI18N\n            || javaVersion.startsWith(\"1.9\") || javaVersion.startsWith(\"9\") // NOI18N\n            || javaVersion.startsWith(\"10\") // NOI18N\n            || javaVersion.startsWith(\"11\") // NOI18N\n            || javaVersion.startsWith(\"12\") // NOI18N\n            || javaVersion.startsWith(\"13\") // NOI18N\n            || javaVersion.startsWith(\"14\"); // NOI18N\n    }\n    \n    \n    private volatile boolean countVisible1 = true;\n    private volatile boolean countVisible2 = false;\n    \n    private synchronized void setAggregation(Aggregation aggregation) {\n        boolean instancesInvolved = Aggregation.INSTANCES.equals(aggregation) ||\n                                    Aggregation.INSTANCES.equals(this.aggregation);\n        \n        this.aggregation = aggregation;\n        \n        if (instancesInvolved) {\n            // TODO: having Count visible for Instances aggregation resets the column width!\n            boolean countVisible = objectsView.isColumnVisible(DataType.COUNT);\n            if (Aggregation.INSTANCES.equals(aggregation)) {\n                countVisible1 = countVisible;\n                objectsView.setColumnVisible(DataType.COUNT, countVisible2);\n            } else {\n                countVisible2 = countVisible;\n                objectsView.setColumnVisible(DataType.COUNT, countVisible1);\n            }\n        }\n        \n        objectsView.reloadView();\n    }\n    \n    private synchronized Aggregation getAggregation() {\n        return aggregation;\n    }\n    \n    \n    private void executeQuery() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                oqlExecutor.runQuery(editor.getScript(), true, true, (int)limitCombo.getSelectedItem());\n            }\n        });\n    }\n    \n    private void cancelQuery() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                oqlExecutor.cancelQuery();\n            }\n        });\n    }\n    \n    private void queryStarted(final BoundedRangeModel model) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                updateUIState();\n                resultsToolbar.getComponent().setVisible(false);\n                progressToolbar.getComponent().setVisible(true);\n                progressBar.setModel(model);\n                \n                objectsView.reloadView();\n                htmlView.setText(oqlExecutor.getQueryHTML());\n            }\n        });\n    }\n\n    private void queryFinished(final boolean hasObjectsResults, final boolean hasHTMLResults, final String errorMessage) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                updateUIState();\n                progressToolbar.getComponent().setVisible(false);\n                resultsToolbar.getComponent().setVisible(true);\n                progressBar.setModel(new DefaultBoundedRangeModel(0, 0, 0, 0));\n                \n                objectsView.reloadView();\n                \n                String queryHTML = oqlExecutor.getQueryHTML();\n                htmlView.setText(errorMessage != null ? errorMessage : queryHTML);\n                \n                if (errorMessage != null || (!hasObjectsResults && hasHTMLResults)) {\n                    rHTML.setSelected(true);\n                }\n            }\n        });\n    }\n    \n    \n    private void updateUIState() {\n        int scriptLength = editor.getScript().trim().length();\n        \n        saveAction.setEnabled(scriptLength > 0);\n        \n        if (oqlExecutor.isQueryRunning()) {\n            runAction.setEnabled(false);\n            cancelAction.setEnabled(true);\n            loadAction.setEnabled(false);\n            editor.setEditable(false);\n        } else {\n            runAction.setEnabled(scriptLength > 0 && queryValid);\n            cancelAction.setEnabled(false);\n            loadAction.setEnabled(true);\n            editor.setEditable(true);\n        }\n    }\n    \n    private static HeapViewerNode getNode(URL url, HeapContext context) {\n        String urls = url.toString();\n                \n        if (HeapUtils.isInstance(urls)) {\n            final Instance instance = HeapUtils.instanceFromHtml(urls, context.getFragment().getHeap());\n            if (instance != null) return new InstanceNode(instance);\n            else ProfilerDialogs.displayError(Bundle.OQLConsoleView_CannotResolveInstanceMsg());\n        } else if (HeapUtils.isClass(urls)) {\n            JavaClass javaClass = HeapUtils.classFromHtml(urls, context.getFragment().getHeap());\n            if (javaClass != null) return new ClassNode(javaClass);\n            else ProfilerDialogs.displayError(Bundle.OQLConsoleView_CannotResolveClassMsg());\n        }\n\n        return null;\n    }\n    \n    private final class RunAction extends AbstractAction {\n        private static final String ACTION_NAME  = \"runScript_Action\";     // NOI18N\n        private final KeyStroke shortcut = KeyStroke.getKeyStroke(\"ctrl R\");  // NOI18N\n\n        private RunAction() {\n            super(Bundle.OQLConsoleView_RunAction(), Icons.getIcon(GeneralIcons.START));\n            putValue(Action.SHORT_DESCRIPTION, Bundle.OQLConsoleView_RunActionTooltip());\n            putValue(Action.ACTION_COMMAND_KEY, ACTION_NAME);\n            putValue(Action.ACCELERATOR_KEY, shortcut);\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            executeQuery();\n        }\n    }\n\n    private class EditorView extends JPanel {\n        \n        EditorView(OQLEditorComponent editor) {\n            super(new BorderLayout());\n            \n            editor.clearScrollBorders();\n            add(editor, BorderLayout.CENTER);\n//            add(new ScrollableContainer(editorContainer), BorderLayout.CENTER);\n\n            JToolBar controls = new JToolBar(JToolBar.VERTICAL);\n            controls.setFloatable(false);\n            controls.setBorderPainted(false);\n            controls.add(runAction);\n            controls.add(cancelAction);\n            controls.addSeparator();\n            controls.add(loadAction).putClientProperty(\"POPUP_LEFT\", Boolean.TRUE); // NOI18N\n            controls.add(saveAction).putClientProperty(\"POPUP_LEFT\", Boolean.TRUE); // NOI18N\n            controls.add(editAction).putClientProperty(\"POPUP_LEFT\", Boolean.TRUE); // NOI18N\n            \n            JPanel controlsContainer = new JPanel(new BorderLayout());\n            controlsContainer.setOpaque(false);\n            controlsContainer.setBorder(BorderFactory.createCompoundBorder(\n                    BorderFactory.createMatteBorder(0, 0, 0, 1, UIManager.getColor(\"Separator.foreground\")), // NOI18N\n                    BorderFactory.createEmptyBorder(1, 1, 1, 1)));\n            controlsContainer.add(controls, BorderLayout.CENTER);\n            add(controlsContainer, BorderLayout.WEST);\n            \n            // size to always show Run and Stop buttons\n            int h = controls.getComponent(0).getPreferredSize().height;\n            h += controls.getComponent(1).getPreferredSize().height + 2;\n            setMinimumSize(new Dimension(0, h));\n        }\n        \n    }\n    \n    \n    private static class ResultsView extends JPanel {\n        \n        ResultsView(JComponent results) {\n            super(new BorderLayout());\n            add(new ScrollableContainer(results), BorderLayout.CENTER);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/oql/OQLEditorComponent.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.oql;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.JEditorPane;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextField;\nimport javax.swing.UIManager;\nimport javax.swing.border.Border;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.Caret;\nimport javax.swing.text.DefaultEditorKit;\nimport javax.swing.text.Document;\nimport javax.swing.text.EditorKit;\nimport javax.swing.text.Element;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.PlainView;\nimport javax.swing.text.StyleConstants;\nimport javax.swing.text.View;\nimport javax.swing.text.ViewFactory;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.OQLEngine;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.OQLException;\nimport org.graalvm.visualvm.lib.profiler.oql.spi.OQLEditorImpl;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.NoCaret;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport org.openide.awt.StatusDisplayer;\nimport org.openide.util.Exceptions;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jaroslav Bachorik\n * @author Jiri Sedlacek\n */\npublic class OQLEditorComponent extends JPanel {\n\n    private static final String VALIDITY_PROPERTY = OQLEditorImpl.VALIDITY_PROPERTY;\n    \n    private volatile boolean lexervalid;\n    private volatile boolean parserValid;\n    private volatile boolean oldValidity;\n    \n    \n    private final OQLEngine engine;\n    \n    private JEditorPane queryEditor;\n    private JScrollBar verticalScroller;\n\n    private Color lastBgColor;\n    private Caret lastCaret;\n    \n    private boolean changed;\n\n    \n    public OQLEditorComponent(OQLEngine engine) {\n        this.engine = engine;\n        init();\n    }\n    \n    \n    public void setScript(String script) {\n        queryEditor.setText(script);\n        clearChanged();\n        try { queryEditor.setCaretPosition(0); } catch (IllegalArgumentException e) {}\n        scrollRectToVisible(new Rectangle());\n    }\n\n    public String getScript() {\n        return queryEditor.getText();\n    }\n    \n    \n    protected void validityChanged(boolean valid) {}\n    \n    \n    final void clearChanged() {\n        changed = false;\n    }\n    \n    public final boolean isChanged() {\n        return changed;\n    }\n\n    \n    public void setEnabled(boolean b) {\n        super.setEnabled(b);\n        if (verticalScroller != null) updateScroller(verticalScroller);\n    }\n    \n    public void setBackground(Color bg) {\n        super.setBackground(bg);\n        if (queryEditor != null) queryEditor.setBackground(bg);\n    }\n\n    public void setOpaque(boolean isOpaque) {\n        super.setOpaque(isOpaque);\n        if (queryEditor != null) queryEditor.setOpaque(isOpaque);\n    }\n\n    public void requestFocus() {\n        if (queryEditor != null) queryEditor.requestFocus();\n    }    \n\n    public void setEditable(boolean b) {\n        if (queryEditor.isEditable() == b) return;\n        \n        queryEditor.setEditable(b);\n\n        if (b) {\n            if (lastBgColor != null) queryEditor.setBackground(lastBgColor);\n            if (lastCaret != null) queryEditor.setCaret(lastCaret);\n        } else {\n            lastBgColor = queryEditor.getBackground();\n            lastCaret = queryEditor.getCaret();\n            \n            Color disabledBackground = UIUtils.isGTKLookAndFeel() ?\n                  UIManager.getLookAndFeel().getDefaults().getColor(\"desktop\") : // NOI18N\n                  UIManager.getColor(\"TextField.disabledBackground\"); // NOI18N\n            queryEditor.setBackground(disabledBackground);\n            queryEditor.setCaret(new NoCaret());\n        }\n    }\n\n    public boolean isEditable() {\n        return queryEditor.isEditable();\n    }\n    \n    public void clearScrollBorders() {\n        if (getComponentCount() > 0) {\n            Component c = getComponent(0);\n            if (c instanceof JScrollPane) {\n                ((JScrollPane)c).setBorder(BorderFactory.createEmptyBorder());\n                ((JScrollPane)c).setViewportBorder(BorderFactory.createEmptyBorder());\n            }\n        }\n    }\n    \n    \n    private void init() {\n        setOpaque(true);\n        setBackground(UIUtils.getProfilerResultsBackground());\n        \n        OQLEditorImpl impl = Lookup.getDefault().lookup(OQLEditorImpl.class);\n        if (impl != null) {\n            queryEditor = impl.getEditorPane();\n            queryEditor.getDocument().putProperty(OQLEngine.class, engine);\n            queryEditor.getDocument().putProperty(OQLEditorImpl.ValidationCallback.class, new OQLEditorImpl.ValidationCallback() {\n                public void callback(boolean lexingResult) {\n                    lexervalid = lexingResult;\n                    validateScript();\n                }\n            });\n            \n            queryEditor.getCaret().addChangeListener(new ChangeListener() {\n                public void stateChanged(ChangeEvent e) {\n                    try {\n                        Rectangle edit = queryEditor == null ? null :\n                                         queryEditor.getUI().modelToView(\n                                         queryEditor, queryEditor.getCaretPosition());\n                        if (edit != null) queryEditor.scrollRectToVisible(edit);\n                    } catch (BadLocationException ex) {\n                        Exceptions.printStackTrace(ex);\n                    }\n                }\n            });\n            \n            Element root = queryEditor.getDocument().getDefaultRootElement();\n            String family = StyleConstants.getFontFamily(root.getAttributes());\n            queryEditor.setFont(new Font(family, Font.PLAIN, new JEditorPane().getFont().getSize()));\n        } else {\n            final DocumentListener listener = new DocumentListener() {\n                public void insertUpdate(DocumentEvent e)  { validateScript(); }\n                public void removeUpdate(DocumentEvent e)  { validateScript(); }\n                public void changedUpdate(DocumentEvent e) { validateScript(); }\n            };\n            final DocumentListener editHandler = new DocumentListener() {\n                public void insertUpdate(DocumentEvent e)  { handleEdit(); }\n                public void removeUpdate(DocumentEvent e)  { handleEdit(); }\n                public void changedUpdate(DocumentEvent e) { handleEdit(); }\n                private void handleEdit() { changed = true; }\n            };\n            \n            queryEditor = new JEditorPane() {\n                protected EditorKit createDefaultEditorKit() {\n                    return new OQLEditorKit();\n                }\n                public void setText(String text) {\n                    Document doc = getDocument();\n                    if (doc != null) {\n                        doc.removeDocumentListener(listener);\n                        doc.removeDocumentListener(editHandler);\n                    }\n                    setDocument(getEditorKit().createDefaultDocument());\n                    doc = getDocument();\n                    if (doc != null) doc.addDocumentListener(listener);\n                    super.setText(text);\n                    if (doc != null) doc.addDocumentListener(editHandler);\n                }\n            };\n            \n            queryEditor.setFont(Font.decode(Font.MONOSPACED + \" \" + queryEditor.getFont().getSize())); // NOI18N\n            lexervalid = true; // no lexer info available; assume the lexing info is valid\n        }\n\n        // IMPORTANT: setText() is required to register document listener/validity check!\n        queryEditor.setText(\"\");\n        \n        queryEditor.setOpaque(isOpaque());\n        queryEditor.setBackground(getBackground());\n        \n        // Do not display NB TopComponent switcher, let the focus subsystem transfer the focus out of the editor\n        queryEditor.putClientProperty(\"nb.ctrltab.popupswitcher.disable\", Boolean.TRUE); // NOI18N\n        \n        int rowSize = queryEditor.getFontMetrics(queryEditor.getFont()).getHeight();\n        \n        final JScrollPane editorScroll = new JScrollPane(queryEditor,\n                        JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,\n                        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n        editorScroll.getHorizontalScrollBar().setUnitIncrement(rowSize);\n        verticalScroller = editorScroll.getVerticalScrollBar();\n        verticalScroller.setUnitIncrement(rowSize);\n        verticalScroller.getModel().addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) { updateScroller(verticalScroller); }\n        });\n        \n        JTextField tf = new JTextField(\" 999 \"); // NOI18N\n        tf.setBorder(BorderFactory.createEmptyBorder());\n        tf.setMargin(new Insets(0, 0, 0, 0));\n        tf.setFont(queryEditor.getFont());\n        final int w = tf.getPreferredSize().width;\n\n        final JEditorPane rows = new JEditorPane() {\n            {\n                setEditorKit(queryEditor.getEditorKit());\n                setFont(queryEditor.getFont());\n            }\n            public Dimension getPreferredSize() {\n                Dimension dim = new Dimension(w, 0);\n                int refHeight = queryEditor.getPreferredSize().height;\n                int viewHeight = editorScroll.getViewport().getExtentSize().height;\n                dim.height = Math.max(refHeight, viewHeight);\n                return dim;\n            }\n            public void setBackground(Color c) {\n                super.setBackground(!UISupport.isDarkResultsBackground() ? new Color(245, 245, 245) : new Color(55, 55, 55));\n            }\n        };\n\n        rows.setCaret(new FollowingCaret(queryEditor));\n        StringBuilder sb = new StringBuilder();\n        for (int i = 1; i < 1000; i++) {\n            if (i < 1000) sb.append(\" \"); // NOI18N\n            if (i < 100) sb.append(\" \"); // NOI18N\n            if (i < 10) sb.append(\" \"); // NOI18N\n            sb.append(Integer.toString(i) + \" \\n\"); // NOI18N\n        }\n        rows.setText(sb.toString());\n        rows.setEditable(false);\n        rows.setEnabled(false);\n\n        Insets margin = queryEditor.getMargin();\n        if (margin == null) margin = new Insets(0, 0, 0, 0);\n        rows.setMargin(new Insets(margin.top, 0, margin.bottom, 0));\n\n        Border border = queryEditor.getBorder();\n        if (border != null) {\n            margin = border.getBorderInsets(queryEditor);\n            if (margin == null) margin = new Insets(0, 0, 0, 0);\n            rows.setBorder(BorderFactory.createEmptyBorder(margin.top, -1, margin.bottom, 0));\n        }\n        \n        editorScroll.setRowHeaderView(rows);\n        \n        setLayout(new BorderLayout());\n        add(editorScroll, BorderLayout.CENTER);\n    }\n    \n    private void updateScroller(JScrollBar scroll) {\n        scroll.setEnabled(isEnabled() && scroll.getVisibleAmount() < scroll.getMaximum());\n    }\n    \n    private void validateScript() {\n        if (engine == null) return;\n        \n        if (lexervalid || !parserValid) {\n            // only parse the query if there are no errors from lexer\n            try {\n                engine.parseQuery(getScript());\n                parserValid = true;\n            } catch (OQLException e) {\n                StatusDisplayer.getDefault().setStatusText(e.getLocalizedMessage());\n                parserValid = false;\n            }\n        }\n\n        firePropertyChange(VALIDITY_PROPERTY, oldValidity, lexervalid && parserValid);\n        oldValidity = lexervalid && parserValid;\n        \n        validityChanged(oldValidity);\n    }\n    \n    \n    private static class OQLEditorKit extends DefaultEditorKit {\n        \n        private static final ViewFactory FACTORY = new ViewFactory() {\n            public View create(Element elem) { return new PlainView(elem); }\n        };\n        \n        public String getContentType() {\n            return \"text/x-oql\"; // NOI18N\n        }\n        \n        public ViewFactory getViewFactory() {\n            return FACTORY;\n        }\n        \n    }\n    \n    private static class FollowingCaret implements Caret {\n                \n        private final List<ChangeListener> listeners = new ArrayList<>();\n        private int dot;\n\n        FollowingCaret(final JTextComponent tc) {\n            tc.getCaret().addChangeListener(new ChangeListener() {\n                public void stateChanged(ChangeEvent e) {\n                    setDot(followedPosition(tc));\n                }\n            });\n            setDot(followedPosition(tc));\n        }\n\n        private static int followedPosition(JTextComponent tc) {\n            Element root = tc.getDocument().getDefaultRootElement();\n            return root.getElementIndex(tc.getCaretPosition()) * 6;\n        }\n\n        public void install(JTextComponent c) {}\n        public void deinstall(JTextComponent c) {}\n        public void paint(Graphics g) {}\n        public void addChangeListener(ChangeListener l) { listeners.add(l); }\n        public void removeChangeListener(ChangeListener l) { listeners.remove(l); }\n        public boolean isVisible() { return false; }\n        public void setVisible(boolean v) {}\n        public boolean isSelectionVisible() { return false; }\n        public void setSelectionVisible(boolean v) {}\n        public void setMagicCaretPosition(Point p) {}\n        public Point getMagicCaretPosition() { return new Point(0, 0); }\n        public void setBlinkRate(int rate) {}\n        public int getBlinkRate() { return 1; }\n        public int getDot() { return dot; }\n        public int getMark() { return dot; }\n        public void moveDot(int dot) {}\n        \n        public void setDot(int dot) {\n            this.dot = dot;\n            ChangeEvent e = new ChangeEvent(this);\n            for (ChangeListener l : listeners) l.stateChanged(e);\n        }\n        \n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/oql/OQLQueries.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.oql;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Locale;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SwingUtilities;\nimport javax.swing.filechooser.FileFilter;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.profiler.oql.repository.api.OQLQueryCategory;\nimport org.graalvm.visualvm.lib.profiler.oql.repository.api.OQLQueryDefinition;\nimport org.graalvm.visualvm.lib.profiler.oql.repository.api.OQLQueryRepository;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.openide.awt.StatusDisplayer;\nimport org.openide.util.Exceptions;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"OQLQueries_LoadingProgress=Loading Saved OQL scripts...\",\n//    \"OQLQueries_PopupCaptionLoad=<html><b>Load OQL Script</b>: Select Source</html>\",\n    \"OQLQueries_PopupLoadCustomScript=Load Custom Script:\",\n    \"OQLQueries_PopupSaveCustomScript=Save Custom Script:\",\n    \"OQLQueries_PopupNoSaved=<no saved scripts>\",\n    \"OQLQueries_PopupLoadExternalScript=Load External Script:\",\n    \"OQLQueries_PopupSaveExternalScript=Save External Script:\",\n    \"OQLQueries_PopupLoadFromFile=Load From File...\",\n    \"OQLQueries_PopupLoadPredefinedScript=Load Predefined Script:\",\n    \"OQLQueries_PopupLoadingScripts=Loading Saved OQL scripts...\",\n//    \"OQLQueries_PopupCaptionSave=<html><b>Save OQL Script</b>: Select Target</html>\",\n    \"OQLQueries_PopupSaveNew=Save As New...\",\n    \"OQLQueries_PopupSaveFile=Save To New File...\",\n    \"OQLQueries_LoadExternalCaption=Load External OQL Script\",\n    \"OQLQueries_OQLFileFilter=OQL Script Files ({0})\",\n    \"OQLQueries_InvalidScript=Invalid OQL script file.\",\n    \"OQLQueries_LoadFailed=Failed to load OQL script.\",\n    \"OQLQueries_SaveFailed=Failed to save OQL script.\",\n    \"OQLQueries_SaveExternalCaption=Save External OQL Script\",\n    \"OQLQueries_CurrentScriptFlag=[current]\"\n        \n})\nfinal class OQLQueries {\n    \n    static final Icon ICON_LOAD = ImageUtilities.image2Icon(ImageUtilities.loadImage(OQLConsoleView.class.getPackage().getName().replace('.', '/') + \"/loadOQL.png\", true));\n    static final Icon ICON_SAVE = Icons.getIcon(GeneralIcons.SAVE);\n    private static final Icon ICON_EMPTY = Icons.getIcon(GeneralIcons.EMPTY);\n    \n    private static final int EXTERNAL_QUERIES_CACHE = 5;\n    \n    \n    private static OQLQueries INSTANCE;\n    \n    private CustomOQLQueries customQueries;\n    private List<? extends OQLQueryCategory> predefinedCategories;\n    \n    private List<OQLQuery> externalQueries;\n    \n    private JPopupMenu tempPopup;\n    private OQLQuery tempCurrentQuery;\n    private String tempQueryText;\n    private Handler tempHandler;\n    private boolean tempLoad;\n    \n    \n    public static synchronized OQLQueries instance() {\n        if (INSTANCE == null) INSTANCE = new OQLQueries();\n        return INSTANCE;\n    }\n    \n    \n    public void populateLoadQuery(JPopupMenu popup, OQLQuery currentQuery, final Handler handler) {\n        if (customQueries == null || predefinedCategories == null) {\n            JMenuItem progressItem = new JMenuItem(Bundle.OQLQueries_LoadingProgress(), Icons.getIcon(HeapWalkerIcons.PROGRESS));\n            progressItem.setEnabled(false);\n            popup.add(progressItem);\n            \n            tempPopup = popup;\n            tempCurrentQuery = currentQuery;\n            tempHandler = handler;\n            \n            tempLoad = true;\n            \n            return;\n        }\n        \n        tempPopup = null;\n        tempCurrentQuery = null;\n        tempQueryText = null;\n        tempHandler = null;\n\n//        popup.add(new PopupCaption(Bundle.OQLQueries_PopupCaptionLoad()));\n        \n//        popup.add(new PopupSpacer(3));\n        popup.add(new PopupSeparator(Bundle.OQLQueries_PopupLoadCustomScript()));\n        \n        if (customQueries.isEmpty()) {\n            JMenuItem noItems = new JMenuItem(Bundle.OQLQueries_PopupNoSaved(), ICON_EMPTY);\n            noItems.setEnabled(false);\n            popup.add(noItems);\n        } else {\n            for (final OQLQuery query : customQueries.list())\n                popup.add(new QueryMenuItem(query, currentQuery, ICON_LOAD, null, handler));\n        }\n        \n        popup.add(new PopupSpacer(5));\n        popup.add(new PopupSeparator(Bundle.OQLQueries_PopupLoadExternalScript()));\n        popup.add(new JMenuItem(Bundle.OQLQueries_PopupLoadFromFile(), ICON_EMPTY) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { loadFromFile(handler); }\n                });\n            }\n        });\n        if (externalQueries != null && !externalQueries.isEmpty()) {\n            popup.add(new PopupSpacer(5));\n            for (final OQLQuery query : externalQueries)\n                popup.add(new QueryMenuItem(query, currentQuery, ICON_LOAD, null, handler));\n        }\n        \n        if (!predefinedCategories.isEmpty()) {\n            popup.add(new PopupSpacer(5));\n            popup.add(new PopupSeparator(Bundle.OQLQueries_PopupLoadPredefinedScript()));\n            \n            for (OQLQueryCategory category : predefinedCategories) {\n                final JMenu categoryMenu = new JMenu(category.getName()) {\n                    protected void fireStateChanged() {\n                        boolean active = isSelected() || isArmed();\n                        StatusDisplayer.getDefault().setStatusText(active ? category.getDescription() : null);\n                        super.fireStateChanged();\n                    }\n                };\n//                categoryMenu.setToolTipText(category.getDescription());\n                popup.add(categoryMenu);\n                \n                List<? extends OQLQueryDefinition> queries = category.listQueries();\n                for (final OQLQueryDefinition queryDef : queries)\n                    categoryMenu.add(new QueryMenuItem(new OQLQuery(queryDef), currentQuery, ICON_LOAD, categoryMenu, handler));\n            }\n        }\n    }\n    \n    public void populateSaveQuery(JPopupMenu popup, final OQLQuery currentQuery, final String queryText, final Handler handler) {\n        if (customQueries == null) {\n            JMenuItem progressItem = new JMenuItem(Bundle.OQLQueries_PopupLoadingScripts(), Icons.getIcon(HeapWalkerIcons.PROGRESS));\n            progressItem.setEnabled(false);\n            popup.add(progressItem);\n            \n            tempPopup = popup;\n            tempCurrentQuery = currentQuery;\n            tempQueryText = queryText;\n            tempHandler = handler;\n            \n            tempLoad = false;\n            \n            return;\n        }\n        \n        tempPopup = null;\n        tempCurrentQuery = null;\n        tempQueryText = null;\n        tempHandler = null;\n        \n//        popup.add(new PopupCaption(Bundle.OQLQueries_PopupCaptionSave()));\n        \n//        popup.add(new PopupSpacer(3));\n        popup.add(new PopupSeparator(Bundle.OQLQueries_PopupSaveCustomScript()));\n        \n        popup.add(new JMenuItem(Bundle.OQLQueries_PopupSaveNew(), ICON_EMPTY) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                \n                OQLQuery query = OQLQueryCustomizer.saveCustomizer(currentQuery, queryText);\n                if (query == null) return;\n                \n                String name = query.getName();\n                int nameExt = 0;\n                while (containsQuery(customQueries.list(), query))\n                    query.setName(name + \" \" + ++nameExt); // NOI18N\n                \n                customQueries.add(query);\n                \n                if (handler != null) handler.querySelected(query);\n            }\n        });\n        \n        if (!customQueries.isEmpty()) {\n            popup.add(new PopupSpacer(5));\n            for (final OQLQuery query : customQueries.list())\n                popup.add(new QueryMenuItem(query, currentQuery, ICON_SAVE, null, handler) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        query.setScript(queryText);\n                        customQueries.save(query);\n                        super.fireActionPerformed(e);\n                    }\n                });\n        }\n        \n        popup.add(new PopupSpacer(5));\n        popup.add(new PopupSeparator(Bundle.OQLQueries_PopupSaveExternalScript()));\n        popup.add(new JMenuItem(Bundle.OQLQueries_PopupSaveFile(), ICON_EMPTY) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { saveToFile(currentQuery, queryText, handler); }\n                });\n            }\n        });\n        if (externalQueries != null && !externalQueries.isEmpty()) {\n            popup.add(new PopupSpacer(5));\n            for (final OQLQuery query : externalQueries)\n                popup.add(new QueryMenuItem(query, currentQuery, ICON_SAVE, null, handler) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        query.setScript(queryText);\n                        saveToQuery(query, null); // handler will be notified later\n                        super.fireActionPerformed(e);\n                    }\n                });\n        }  \n    }\n    \n    \n    private void loadAllQueries() {\n        VisualVM.getInstance().runTask(new Runnable() { // NOI18N\n            public void run() {\n                customQueries = CustomOQLQueries.instance();\n                predefinedCategories = OQLQueryRepository.getInstance().listCategories();\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        if (tempPopup != null && tempPopup.isShowing()) {\n                            JPopupMenu popup = tempPopup;\n                            popup.removeAll();\n                            if (tempLoad) populateLoadQuery(popup, tempCurrentQuery, tempHandler);\n                            else populateSaveQuery(popup, tempCurrentQuery, tempQueryText, tempHandler);\n                            popup.pack();\n                        }\n                    }\n                });\n            }\n        });\n    }\n    \n    \n    private File lastDirectory;\n    \n    private void loadFromFile(final Handler handler) {\n        JFileChooser chooser = new JFileChooser();\n\n        if (lastDirectory != null) chooser.setCurrentDirectory(lastDirectory);\n\n        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);\n        chooser.setMultiSelectionEnabled(false);\n        chooser.setAcceptAllFileFilterUsed(false);\n        chooser.setDialogTitle(Bundle.OQLQueries_LoadExternalCaption());\n        chooser.setFileFilter(new FileFilter() {\n            public boolean accept(File f) {\n                if (f.isDirectory()) return true;\n                String fname = f.getName().toLowerCase(Locale.ENGLISH);\n                if (fname.endsWith(\".oql\") || fname.endsWith(\".txt\")) return true; // NOI18N\n                return false;\n            }\n            public String getDescription() {\n                return Bundle.OQLQueries_OQLFileFilter(\"*.oql, *.txt\"); // NOI18N\n            }\n        });\n\n        if (chooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) {\n            final File file = chooser.getSelectedFile();\n            lastDirectory = file.getParentFile();\n            \n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    try {\n                        if (!file.isFile() || !file.canRead()) {\n                            ProfilerDialogs.displayError(Bundle.OQLQueries_InvalidScript());\n                            return;\n                        }\n                        \n                        String script = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);\n                        String name = file.getName();\n                        String description = file.getAbsolutePath();\n                        final OQLQuery query = new OQLQuery(script, name, description);\n                        \n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                handler.querySelected(query);\n                        \n                                if (externalQueries == null) externalQueries = new ArrayList<>(EXTERNAL_QUERIES_CACHE);\n                                if (containsQuery(externalQueries, query)) return;\n\n                                if (externalQueries.size() == EXTERNAL_QUERIES_CACHE)\n                                    externalQueries.remove(externalQueries.size() - 1);\n\n                                externalQueries.add(0, query);\n                            }\n                        });\n                    } catch (IOException ex) {\n                        ProfilerDialogs.displayError(Bundle.OQLQueries_LoadFailed());\n                        Exceptions.printStackTrace(ex);\n                    }\n                }\n            });\n        }\n    }\n    \n    private void saveToFile(OQLQuery query, String queryText, Handler handler) {\n        JFileChooser chooser = new JFileChooser();\n        \n        if (query == null) {\n            String name = \"query.oql\"; // NOI18N\n            String descr = lastDirectory == null ? null : new File(lastDirectory, name).getPath();\n            query = new OQLQuery(queryText, name, descr);\n        }\n        \n        String descr = query.getDescription();\n        File defaultFile = descr == null ? null : new File(descr);\n        if (defaultFile != null && defaultFile.isFile()) {\n            chooser.setSelectedFile(defaultFile);\n        } else {\n            if (lastDirectory == null) defaultFile = new File(query.getName());\n            else defaultFile = new File(lastDirectory, query.getName());\n            if (lastDirectory != null) chooser.setCurrentDirectory(lastDirectory);\n            chooser.setSelectedFile(defaultFile);\n        }\n\n        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);\n        chooser.setMultiSelectionEnabled(false);\n        chooser.setAcceptAllFileFilterUsed(false);\n        chooser.setDialogTitle(Bundle.OQLQueries_SaveExternalCaption());\n        chooser.setFileFilter(new FileFilter() {\n            public boolean accept(File f) {\n                if (f.isDirectory()) return true;\n                String fname = f.getName().toLowerCase(Locale.ENGLISH);\n                if (fname.endsWith(\".oql\") || fname.endsWith(\".txt\")) return true; // NOI18N\n                return false;\n            }\n            public String getDescription() {\n                return Bundle.OQLQueries_OQLFileFilter(\"*.oql, *.txt\"); // NOI18N\n            }\n        });\n\n        if (chooser.showSaveDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) {\n            File file = chooser.getSelectedFile();\n            lastDirectory = file.getParentFile();\n            \n            String fname = file.getName().toLowerCase(Locale.ENGLISH);\n            if (!fname.endsWith(\".oql\") && !fname.endsWith(\".txt\")) // NOI18N\n                file = new File(file.getParentFile(), file.getName() + \".oql\"); // NOI18N\n            \n            String script = query.getScript();\n            String name = file.getName();\n            String description = file.getAbsolutePath();\n            \n            saveToQuery(new OQLQuery(script, name, description), handler);\n        }\n    }\n    \n    private void saveToQuery(final OQLQuery query, final Handler handler) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                try {\n                    File file = new File(query.getDescription());\n                    \n                    if (file.isFile() && !file.canWrite()) {\n                        ProfilerDialogs.displayError(Bundle.OQLQueries_InvalidScript());\n                        return;\n                    }\n\n                    Files.write(file.toPath(), query.getScript().getBytes());\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            if (handler != null) handler.querySelected(query);\n\n                            if (externalQueries == null) externalQueries = new ArrayList<>(EXTERNAL_QUERIES_CACHE);\n                            if (containsQuery(externalQueries, query)) return;\n\n                            if (externalQueries.size() == EXTERNAL_QUERIES_CACHE)\n                                externalQueries.remove(externalQueries.size() - 1);\n\n                            externalQueries.add(0, query);\n                        }\n                    });\n                } catch (IOException ex) {\n                    ProfilerDialogs.displayError(Bundle.OQLQueries_SaveFailed());\n                    Exceptions.printStackTrace(ex);\n                }\n            }\n        });\n    }\n    \n    \n    private static boolean sameQuery(OQLQuery query1, OQLQuery query2) {\n        if (query1 == null || query2 == null) return false;\n        return query1.getName().equals(query2.getName());\n    }\n    \n    private static boolean containsQuery(List<OQLQuery> queries, OQLQuery query) {\n        for (OQLQuery q : queries)\n            if (sameQuery(q, query)) return true;\n        return false;\n    }\n    \n    \n    private OQLQueries() {\n        loadAllQueries();\n    }\n    \n    \n    static class Handler {\n        \n        protected void querySelected(OQLQuery query) {}\n        \n    }\n    \n    \n//    private static class PopupCaption extends JPanel {\n//        \n//        PopupCaption(String caption) {\n//            super(new BorderLayout());\n//            \n//            setOpaque(true);\n//            setBackground(UIUtils.getUnfocusedSelectionBackground());\n////            setBackground(UIUtils.getProfilerResultsBackground());\n////            setBackground(UIManager.getColor(\"InternalFrame.borderHighlight\"));\n////            setBackground(UIManager.getColor(\"ToolTip.background\"));\n//            \n//            JLabel captionL = new JLabel(caption);\n//            captionL.setForeground(UIUtils.getUnfocusedSelectionForeground());\n////            captionL.setForeground(UIManager.getColor(\"InternalFrame.activeTitleForeground\"));\n////            captionL.setBorder(BorderFactory.createEmptyBorder(3, 3, 4, 3));\n//            captionL.setBorder(BorderFactory.createEmptyBorder(7, 5, 7, 40));\n//            add(captionL, BorderLayout.CENTER);\n//            \n////            add(UIUtils.createHorizontalSeparator(), BorderLayout.SOUTH);\n////            setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIUtils.getDisabledLineColor().brighter()));\n//        }\n//        \n//    }\n    \n    private static class PopupSpacer extends JPanel {\n        \n        private final int size;\n        \n        PopupSpacer(int size) {\n            this.size = size;\n            setOpaque(false);\n        }\n        \n        public Dimension getMinimumSize() {\n            return new Dimension(0, size);\n        }\n        \n        public Dimension getPreferredSize() {\n            return getMinimumSize();\n        }\n        \n    }\n    \n    private static class PopupSeparator extends JPanel {\n    \n        PopupSeparator(String text) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            JLabel l = new JLabel(text);\n            l.setBorder(BorderFactory.createEmptyBorder(5, 5, 3, 3));\n            if (UIUtils.isWindowsLookAndFeel()) l.setOpaque(true);\n            l.setFont(l.getFont().deriveFont(Font.BOLD, l.getFont().getSize2D() - 1));\n            if (UIUtils.isWindowsLookAndFeel()) l.setForeground(UIUtils.getDisabledLineColor());\n\n            add(l, BorderLayout.WEST);\n\n            if (UIUtils.isGTKLookAndFeel()) {\n                add(UIUtils.createHorizontalSeparator(), BorderLayout.CENTER);\n            } else {\n                JComponent sep = new JPopupMenu.Separator();\n                add(sep, BorderLayout.CENTER);\n\n                if (UIUtils.isOracleLookAndFeel()) {\n                    setOpaque(true);\n                    setBackground(sep.getBackground());\n                    l.setForeground(sep.getForeground());\n                }\n            }\n        }\n\n        public void doLayout() {\n            super.doLayout();\n            Component c = getComponent(1);\n\n            int h = c.getPreferredSize().height;\n            Rectangle b = c.getBounds();\n\n            b.y = (b.height - h) / 2 + 1;\n            b.height = h;\n            c.setBounds(b);\n        }\n\n        public Dimension getPreferredSize() {\n            Dimension d = getComponent(0).getPreferredSize();\n            d.width += 75;\n            return d;\n        }\n\n    }\n    \n    private static class QueryMenuItem extends JMenuItem {\n        \n        private final OQLQuery query;\n        private final Icon icon;\n        private final Handler handler;\n        \n        QueryMenuItem(OQLQuery query, OQLQuery current, Icon icon, JMenu owner, Handler handler) {\n            super(getName(query, current, owner), ICON_EMPTY);\n            \n            this.query = query;\n            this.icon = icon;\n            this.handler = handler;\n        }\n        \n        protected void fireActionPerformed(ActionEvent e) {\n            super.fireActionPerformed(e);\n            if (handler != null) handler.querySelected(query);\n        }\n        \n        protected void fireStateChanged() {\n            boolean active = isSelected() || isArmed();\n            setIcon(active ? icon : ICON_EMPTY);\n            StatusDisplayer.getDefault().setStatusText(active ? query.getDescription() : null);\n            super.fireStateChanged();\n        }\n        \n        private static String getName(OQLQuery query, OQLQuery current, JMenu owner) {\n            String name = query.getName();\n            if (sameQuery(query, current)) {\n                name = \"<html><b>\" + name + \"</b>&nbsp;<span style='color: gray;'>\" + Bundle.OQLQueries_CurrentScriptFlag() + \"</span></html>\"; // NOI18N\n                if (owner != null) owner.setText(\"<html><b>\" + owner.getText() + \"</b></html>\"); // NOI18N\n            }\n            return name;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/oql/OQLQuery.java",
    "content": "/*\n * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.oql;\n\nimport org.graalvm.visualvm.lib.profiler.oql.repository.api.OQLQueryDefinition;\n\n/**\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic final class OQLQuery {\n\n    private String script;\n    private String name;\n    private String description;\n\n    public OQLQuery(OQLQueryDefinition qdef) {\n        this(qdef.getContent(), qdef.getName(), qdef.getDescription());\n    }\n\n    public OQLQuery(String script, String name, String description) {\n        setScript(script);\n        setName(name);\n        setDescription(description);\n    }\n\n    public void setScript(String script) {\n        if (script == null) {\n            throw new IllegalArgumentException(\"Script cannot be null\"); // NOI18N\n        }\n        this.script = script;\n    }\n\n    public String getScript() {\n        return script;\n    }\n\n    public void setName(String name) {\n        this.name = normalizeString(name);\n        if (this.name == null) {\n            throw new IllegalArgumentException(\"Name cannot be null\"); // NOI18N\n        }\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setDescription(String description) {\n        this.description = normalizeString(description);\n    }\n\n    public String getDescription() {\n        return description;\n    }\n\n    public String toString() {\n        return name;\n    }\n\n    private static String normalizeString(String string) {\n        String normalizedString = null;\n        if (string != null) {\n            normalizedString = string.trim();\n            if (normalizedString.isEmpty()) {\n                normalizedString = null;\n            }\n        }\n        return normalizedString;\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/oql/OQLQueryCustomizer.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.oql;\n\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.io.File;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextArea;\nimport javax.swing.JTextField;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"OQLQueryCustomizer_OkButtonText=OK\",\n    \"OQLQueryCustomizer_CloseButtonText=Close\",\n    \"OQLQueryCustomizer_SaveQueryCaption=Save Custom OQL Script\",\n    \"OQLQueryCustomizer_NameLabelText=&Name:\",\n    \"OQLQueryCustomizer_DefaultQueryName=Custom Script\",\n    \"OQLQueryCustomizer_DescriptionLabelText=&Description (optional):\"\n})\npublic class OQLQueryCustomizer {\n//    private static HelpCtx HELP_CTX_SAVE_QUERY = new HelpCtx(\"OQLQueryCustomizer.SaveQuery.HelpCtx\");  //NOI18N\n//    private static HelpCtx HELP_CTX_QUERY_PROPS = new HelpCtx(\"OQLQueryCustomizer.QueryProps.HelpCtx\");//NOI18N\n\n\n    public static OQLQuery saveCustomizer(OQLQuery query, String script) {\n        JButton okButton = new JButton();\n        Mnemonics.setLocalizedText(okButton, Bundle.OQLQueryCustomizer_OkButtonText());\n        \n        String name = query == null ? Bundle.OQLQueryCustomizer_DefaultQueryName() : query.getName();\n        String description = query == null ? null : query.getDescription();\n        if (description != null && new File(description).isFile()) description = null;\n\n        CustomizerPanel customizer = new CustomizerPanel(name, description, okButton);\n        final DialogDescriptor dd = new DialogDescriptor(customizer,\n                                            Bundle.OQLQueryCustomizer_SaveQueryCaption(), true,\n                                            new Object[] { okButton,\n                                            DialogDescriptor.CANCEL_OPTION },\n                                            okButton, 0, null, null);\n        final Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n        d.pack();\n        d.setVisible(true);\n\n        if (dd.getValue() == okButton) {\n            return new OQLQuery(script, customizer.name(), customizer.description());\n        } else {\n            return null;\n        }\n    }\n    \n\n    private static class CustomizerPanel extends JPanel {\n\n        private final JComponent submitComponent;\n\n\n        CustomizerPanel(String name, String description, JComponent submitComponent) {\n            this.submitComponent = submitComponent;\n\n            initComponents(name, description, false);\n            updateComponents();\n        }\n\n        public String name() {\n            return nameField.getText().trim();\n        }\n\n        public String description() {\n            String description = descriptionArea.getText().trim();\n            return description.isEmpty() ? null : description;\n        }\n\n\n        private void updateComponents() {\n            submitComponent.setEnabled(!nameField.getText().trim().isEmpty());\n        }\n\n\n        private void initComponents(String name, String description, boolean readOnly) {\n            setLayout(new GridBagLayout());\n            GridBagConstraints c;\n\n            nameLabel = new JLabel();\n            Mnemonics.setLocalizedText(nameLabel, Bundle.OQLQueryCustomizer_NameLabelText());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 1;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(16, 16, 8, 8);\n            add(nameLabel, c);\n\n            nameField = new JTextField();\n            nameLabel.setLabelFor(nameField);\n            nameField.setText(name);\n            nameField.getDocument().addDocumentListener(new DocumentListener() {\n                public void insertUpdate(DocumentEvent e) {  updateComponents(); }\n                public void removeUpdate(DocumentEvent e) {  updateComponents(); }\n                public void changedUpdate(DocumentEvent e) {  updateComponents(); }\n            });\n            nameField.setEditable(!readOnly);\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = 1;\n            c.weightx = 1;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(16, 0, 8, 16);\n            add(nameField, c);\n\n            descriptionLabel = new JLabel();\n            Mnemonics.setLocalizedText(descriptionLabel, Bundle.OQLQueryCustomizer_DescriptionLabelText());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 2;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(8, 16, 8, 8);\n            add(descriptionLabel, c);\n\n            descriptionArea = new JTextArea(description);\n            descriptionLabel.setLabelFor(descriptionArea);\n            descriptionArea.setLineWrap(true);\n            descriptionArea.setWrapStyleWord(true);\n            descriptionArea.setFont(descriptionLabel.getFont());\n            descriptionArea.setRows(5);\n            final int prefWidth = new JLabel(\"A lengthy string serving as OQL script description sizer\").getPreferredSize().width; // NOI18N\n            JScrollPane descriptionAreaScroll = new JScrollPane(descriptionArea,\n                                        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                                        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) {\n                public Dimension getPreferredSize() {\n                    return new Dimension(prefWidth, super.getPreferredSize().height);\n                }\n            };\n            descriptionArea.setEditable(!readOnly);\n            if (readOnly) descriptionArea.setBackground(nameField.getBackground());\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = 3;\n            c.weighty = 1;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.fill = GridBagConstraints.BOTH;\n            c.insets = new Insets(0, 0, 16, 16);\n            add(descriptionAreaScroll, c);\n\n            addHierarchyListener(new HierarchyListener() {\n                public void hierarchyChanged(HierarchyEvent e) {\n                    if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                        if (isShowing()) {\n                            removeHierarchyListener(this);\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    nameField.requestFocus();\n                                    nameField.selectAll();\n                                }\n                            });\n                        }\n                    }\n                }\n            });\n\n        }\n\n\n        private JLabel nameLabel;\n        private JTextField nameField;\n        private JLabel descriptionLabel;\n        private JTextArea descriptionArea;\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/oql/OQLQueryExecutor.java",
    "content": "/*\n * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.oql;\n\nimport java.awt.Color;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BoundedRangeModel;\nimport javax.swing.DefaultBoundedRangeModel;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.ClassesContainer;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstancesContainer;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.ProgressNode;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.OQLEngine;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.OQLException;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.ReferenceChain;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"OQLQueryExecutor_MoreNodes=<another {0} objects left>\",\n    \"OQLQueryExecutor_SamplesContainer=<sample {0} objects>\",\n    \"OQLQueryExecutor_NodesContainer=<objects {0}-{1}>\",\n    \"OQLQueryExecutor_NoClasses=<no objects>\",\n    \"OQLQueryExecutor_NoClassesFilter=<no objects matching the filter>\",\n    \"OQLQueryExecutor_NoResults=<no results>\",\n    \"OQLQueryExecutor_TooManyResults=showing first {0} results\",\n    \"OQLQueryExecutor_QueryError=Query error\",\n    \"OQLQueryExecutor_BadQuery=Bad OQL query\",\n    \"OQLQueryExecutor_NothingExecuted=<no script executed yet>\",\n    \"OQLQueryExecutor_QueryRunning=<query running...>\",\n    \"OQLQueryExecutor_ObjectsNotCollected=<objects results not collected>\",\n    \"OQLQueryExecutor_HTMLNotCollected=<HTML results not collected>\"\n})\nclass OQLQueryExecutor {\n    \n    private final OQLEngine engine;\n    \n    private boolean collectObjects = true;\n    private volatile boolean hasObjectsResults;\n    private Set<Object> queryObjects;\n    \n    private boolean collectHTML = true;\n    private int htmlResultsLimit;\n    private volatile boolean hasHTMLResults;\n    private String queryHTML;\n    \n    private final AtomicBoolean queryRunning;\n    private final ExecutorService progressUpdater;\n    \n    \n    OQLQueryExecutor(OQLEngine engine) {\n        this.engine = engine;\n        \n        queryHTML = htmlize(Bundle.OQLQueryExecutor_NothingExecuted()); // NOI18N\n        \n        queryRunning = new AtomicBoolean(false);\n        progressUpdater = Executors.newSingleThreadExecutor();\n    }\n    \n    \n    void runQuery(String queryString, boolean collectObjects, boolean collectHTML, int htmlResultsLimit) {\n        this.collectObjects = collectObjects;\n        \n        this.collectHTML = collectHTML;\n        this.htmlResultsLimit = htmlResultsLimit;\n        \n        runQuery(queryString);\n    }\n    \n    void cancelQuery() {\n        String errorMessage = null;\n        \n        try {\n            engine.cancelQuery();\n        } catch (OQLException e) {\n            errorMessage = e.getLocalizedMessage().replace(\"\\n\", \"<br>\").replace(\"\\r\", \"<br>\"); // NOI18N\n        }\n        \n        queryRunning.compareAndSet(true, false);\n//        htmlCollecting.compareAndSet(true, false);\n        queryFinished(hasObjectsResults, hasHTMLResults, errorMessage);\n    }\n    \n    boolean isQueryRunning() {\n        return queryRunning.get();\n    }\n    \n    \n    protected void queryStarted(BoundedRangeModel model) {}\n    \n    protected void queryFinished(boolean hasObjectsResults, boolean hasHTMLResults, String errorMessage) {}\n    \n    \n    HeapViewerNode[] getQueryObjects(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress, int aggregation) throws InterruptedException {\n        if (!collectObjects) return new HeapViewerNode[] { new TextNode(Bundle.OQLQueryExecutor_ObjectsNotCollected()) };\n        else if (queryObjects == null) return new HeapViewerNode[] { new TextNode(Bundle.OQLQueryExecutor_NothingExecuted()) };\n        else if (isQueryRunning()) return new HeapViewerNode[] { new ProgressNode(Bundle.OQLQueryExecutor_QueryRunning()) };\n        else return getObjects(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress, aggregation);\n    }\n    \n    String getQueryHTML() {\n        return queryHTML;\n    }\n    \n    \n    private static class Messages {\n        static String getMoreNodesString(String moreNodesCount)  {\n            return Bundle.OQLQueryExecutor_MoreNodes(moreNodesCount);\n        }\n        static String getSamplesContainerString(String objectsCount)  {\n            return Bundle.OQLQueryExecutor_SamplesContainer(objectsCount);\n        }\n        static String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n            return Bundle.OQLQueryExecutor_NodesContainer(firstNodeIdx, lastNodeIdx);\n        }\n        static String getNoObjectsString(HeapViewerNodeFilter viewFilter) {\n            return viewFilter == null ? Bundle.OQLQueryExecutor_NoClasses() :\n                                        Bundle.OQLQueryExecutor_NoClassesFilter();\n        }\n    }\n    \n    private HeapViewerNode[] getObjects(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress, int aggregation) throws InterruptedException {\n        if (aggregation == 0) {\n            NodesComputer<Object> computer = new NodesComputer<Object>(queryObjects.size(), UIThresholds.MAX_OQL_TOPLEVEL_INSTANCES) {\n                protected boolean sorts(DataType dataType) {\n                    return true;\n                }\n                protected HeapViewerNode createNode(Object object) {\n                    return object instanceof Instance ? new InstanceNode((Instance)object) :\n                                                        new ClassNode((JavaClass)object);\n                }\n                protected ProgressIterator<Object> objectsIterator(int index, Progress progress) {\n                    Iterator<Object> iterator = queryObjects.iterator();\n                    return new ProgressIterator<>(iterator, index, true, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Messages.getMoreNodesString(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Messages.getSamplesContainerString(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Messages.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            HeapViewerNode[] nodes = computer.computeNodes(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n            return nodes.length == 0 ? new HeapViewerNode[] { new TextNode(Messages.getNoObjectsString(viewFilter)) } : nodes;\n        } else {\n            try {\n                progress.setupUnknownSteps();\n                \n                List<InstancesContainer.Objects> cnodes = new ArrayList<>();\n                Map<String, InstancesContainer.Objects> classes = new HashMap<>();\n                for (Object object : queryObjects) {\n                    progress.step();\n\n                    Instance instance = object instanceof Instance ? (Instance)object : null;\n                    JavaClass javaClass = instance != null ? instance.getJavaClass() : (JavaClass)object;\n                    if (viewFilter != null && !viewFilter.passes(new ClassNode(javaClass), heap)) continue;\n\n                    String className = javaClass.getName();\n                    InstancesContainer.Objects cnode = classes.get(className);\n                    if (cnode == null) {\n                        cnode = new InstancesContainer.Objects(className, javaClass) {\n                            protected String getMoreNodesString(String moreNodesCount)  {\n                                return Messages.getMoreNodesString(moreNodesCount);\n                            }\n                            protected String getSamplesContainerString(String objectsCount)  {\n                                return Messages.getSamplesContainerString(objectsCount);\n                            }\n                            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                                return Messages.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n                            }\n                        };\n                        classes.put(className, cnode);\n                        cnodes.add(cnode);\n                    }\n                    if (instance != null) cnode.add(instance, heap);\n                }\n\n                if (aggregation == 1) {\n                    return cnodes.isEmpty() ? new HeapViewerNode[] { new TextNode(Messages.getNoObjectsString(viewFilter)) } :\n                                                  cnodes.toArray(HeapViewerNode.NO_NODES);\n                } else {\n                    List<HeapViewerNode> pnodes = new ArrayList<>();\n                    Map<String, ClassesContainer.ContainerNodes> packages = new HashMap<>();\n                    for (InstancesContainer.Objects cnode : cnodes) {\n                        // progress.step(); // NOTE: aggregating classes by package should be fast\n                        String className = cnode.getName();\n                        int nameIdx = className.lastIndexOf('.'); // NOI18N\n                        if (nameIdx == -1) {\n                            pnodes.add(cnode);\n                        } else {\n                            String pkgName = className.substring(0, nameIdx);\n                            ClassesContainer.ContainerNodes node = packages.get(pkgName);\n                            if (node == null) {\n                                node = new ClassesContainer.ContainerNodes(pkgName);\n                                pnodes.add(node);\n                                packages.put(pkgName, node);\n                            }\n                            node.add(cnode, heap);\n                        }\n                    }\n\n                    return pnodes.isEmpty() ? new HeapViewerNode[] { new TextNode(Messages.getNoObjectsString(viewFilter)) } :\n                                                  pnodes.toArray(HeapViewerNode.NO_NODES);\n                }\n            } finally {\n                progress.finish();\n            }\n        }\n    }\n    \n    \n    private void runQuery(String queryString) {\n        new RequestProcessor(\"OQL Query Processor\").post(new Runnable() { // NOI18N\n            public void run() {\n                if (queryObjects == null) queryObjects = new HashSet<>();\n                queryObjects.clear();\n                hasObjectsResults = false;\n                \n                queryHTML = !collectHTML ? (htmlize(Bundle.OQLQueryExecutor_ObjectsNotCollected())) :\n                                           (htmlize(Bundle.OQLQueryExecutor_QueryRunning()));\n                hasHTMLResults = false;\n                \n                BoundedRangeModel progressModel = new DefaultBoundedRangeModel(0, 10, 0, 100);\n                \n                final AtomicInteger counter = new AtomicInteger(htmlResultsLimit);\n                progressModel.setMaximum(100);\n\n                final StringBuilder sb = new StringBuilder();\n                final boolean[] oddRow = new boolean[1];\n                Color oddRowBackground = UIUtils.getDarker(\n                                UIUtils.getProfilerResultsBackground());\n                final String oddRowBackgroundString =\n                        \"rgb(\" + oddRowBackground.getRed() + \",\" + //NOI18N\n                                 oddRowBackground.getGreen() + \",\" + //NOI18N\n                                 oddRowBackground.getBlue() + \")\"; //NOI18N\n\n                sb.append(\"<table border='0' width='100%'>\"); // NOI18N\n\n                try {\n                    queryRunning.compareAndSet(false, true);\n                    queryStarted(progressModel);\n                    progressUpdater.submit(new ProgressUpdater(progressModel));\n                    engine.executeQuery(queryString, new OQLEngine.ObjectVisitor() {\n                        public boolean visit(Object o) {\n//                                    System.err.println(\">>> Visiting object \" + o);\n                            boolean collectingHtml = collectHTML && counter.decrementAndGet() >= 0;\n\n                            if (collectingHtml) {\n                                sb.append(oddRow[0] ?\n                                    \"<tr><td style='background-color: \" + // NOI18N\n                                    oddRowBackgroundString + \";'>\" : \"<tr><td>\"); // NOI18N\n                                oddRow[0] = !oddRow[0];\n                            }\n                            \n                            dump(o, collectingHtml ? sb : null);\n                            \n                            if (collectingHtml) sb.append(\"</td></tr>\"); // NOI18N\n                            \n//                            boolean htmlFull = counter.decrementAndGet() == 0;\n//                            if (htmlFull) htmlCollecting.compareAndSet(true, false);\n                            \n                            return engine.isCancelled();\n//                            return counter.decrementAndGet() == 0 || (!queryRunning.get() && !engine.isCancelled()); // process all hits while the analysis is running\n                            \n                        }\n                    });\n                    \n                    int count = counter.get();\n\n                    if (count < 0) { // Some results are missing\n                        sb.append(\"<tr><td>\");  // NOI18N\n                        sb.append(\"&lt;\" + Bundle.OQLQueryExecutor_TooManyResults(htmlResultsLimit) + \"&gt;\");      // NOI18N\n                        sb.append(\"</td></tr>\");   // NOI18N\n                    }\n\n                    sb.append(\"</table>\"); // NOI18N\n\n                    queryHTML = count != htmlResultsLimit ? sb.toString() :\n                                htmlize(Bundle.OQLQueryExecutor_NoResults()); // Query returned no results\n                    \n                    queryRunning.compareAndSet(true, false);\n//                    htmlCollecting.compareAndSet(true, false);\n                    queryFinished(hasObjectsResults, hasHTMLResults, null);\n                } catch (OQLException oQLException) {\n                    Logger.getLogger(OQLQueryExecutor.class.getName()).log(Level.INFO, \"Error executing OQL\", oQLException);   // NOI18N\n                    StringBuilder errorMessage = new StringBuilder();\n                    errorMessage.append(\"<h2>\").append(Bundle.OQLQueryExecutor_QueryError()).append(\"</h2>\"); // NOI18N\n                    errorMessage.append(Bundle.OQLQueryExecutor_BadQuery()); // NOI18N\n                    errorMessage.append(\"<hr>\"); // NOI18N\n                    errorMessage.append(oQLException.getLocalizedMessage().replace(\"\\n\", \"<br>\").replace(\"\\r\", \"<br>\")); // NOI18N\n\n                    queryRunning.compareAndSet(true, false);\n//                    htmlCollecting.compareAndSet(true, false);\n                    queryFinished(hasObjectsResults, hasHTMLResults, errorMessage.toString());\n                }\n            }\n\n        });\n    }\n    \n    private void dump(Object o, StringBuilder sb) {\n        if (o == null) {\n            return;\n        }        \n        if (o instanceof Instance) {\n            Instance i = (Instance)o;\n            queryObjects.add(i);\n            hasObjectsResults = true;\n            if (sb != null) {\n                sb.append(HeapUtils.instanceToHtml(i, true, null));\n                hasHTMLResults = true;\n            }\n        } else if (o instanceof JavaClass) {\n            JavaClass c = (JavaClass)o;\n            queryObjects.add(c);\n            hasObjectsResults = true;\n            if (sb != null) {\n                sb.append(HeapUtils.classToHtml(c));\n                hasHTMLResults = true;\n            }\n        } else if (o instanceof ReferenceChain) {\n            ReferenceChain rc = (ReferenceChain) o;\n            boolean first = true;\n            while (rc != null) {\n                if (!first) {\n                    if (sb != null) sb.append(\"-&gt;\"); // NOI18N\n                } else {\n                    first = false;\n                }\n                o = rc.getObj();\n                if (o instanceof Instance) {\n                    Instance i = (Instance)o;\n                    queryObjects.add(i);\n                    hasObjectsResults = true;\n                    if (sb != null) {\n                        sb.append(HeapUtils.instanceToHtml(i, true, null));\n                        hasHTMLResults = true;\n                    }\n                } else if (o instanceof JavaClass) {\n                    JavaClass c = (JavaClass)o;\n                    queryObjects.add(c);\n                    hasObjectsResults = true;\n                    if (sb != null) {\n                        sb.append(HeapUtils.classToHtml(c));\n                        hasHTMLResults = true;\n                    }\n                }\n                rc = rc.getNext();\n            }\n        } else if (o instanceof Map) {\n            Set<Map.Entry> entries = ((Map)o).entrySet();\n            if (sb != null) {\n                sb.append(\"<span><b>{</b><br/>\"); // NOI18N\n                hasHTMLResults = true;\n            }\n            boolean first = true;\n            for(Map.Entry entry : entries) {\n                if (!first) {\n                    if (sb != null) sb.append(\",<br/>\"); // NOI18N\n                } else {\n                    first = false;\n                }\n                if (sb != null) {\n                    sb.append(entry.getKey().toString().replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\")); // NOI18N\n                    sb.append(\" = \"); // NOI18N\n                }\n                dump(unwrap(entry.getValue()), sb);\n            }\n            if (sb != null) sb.append(\"<br/><b>}</b></span>\"); // NOI18N\n        } else if (o instanceof Object[]) {\n            if (sb != null) {\n                sb.append(\"<span><b>[</b>&nbsp;\"); // NOI18N\n                hasHTMLResults = true;\n            }\n            boolean first = true;\n            for (Object obj1 : (Object[]) o) {\n                if (!first) {\n                    if (sb != null) sb.append(\", \"); // NOI18N\n                } else {\n                    first = false;\n                }\n                dump(unwrap(obj1), sb);\n            }\n            if (sb != null) sb.append(\"&nbsp;<b>]</b></span>\"); // NOI18N\n        } else {\n            String s = o.toString();\n            if (sb != null) {\n                sb.append(s);\n                hasHTMLResults = true;\n            }\n            if (collectObjects) extractObjects(s);\n        }\n    }\n    \n    private static final String INSTANCE_LINK_PREFIX = \"<a href='file://instance/\"; // NOI18N\n    private static final String STRING_INSTANCE_LINK_NAME_PREFIX = \"' name='\"; // NOI18N\n    private static final String INSTANCE_LINK_SUFFIX = \"</a>\"; // NOI18N\n    private static final String CLASS_LINK_PREFIX = \"<a href='file://class/\"; // NOI18N\n    private static final String STRING_CLASS_LINK_NAME_PREFIX = \"' name='\"; // NOI18N\n    private static final String CLASS_LINK_SUFFIX = \"</a>\"; // NOI18N\n    private void extractObjects(String s) {\n        int instanceIdx = s.indexOf(INSTANCE_LINK_PREFIX);\n        int classIdx = instanceIdx != -1 ? -1 : s.indexOf(CLASS_LINK_PREFIX);\n        \n        while (instanceIdx != -1 || classIdx != -1) {\n            if (instanceIdx != -1) {\n                s = s.substring(instanceIdx + INSTANCE_LINK_PREFIX.length());\n                String instanceNumber = s.substring(0, s.indexOf(STRING_INSTANCE_LINK_NAME_PREFIX));\n                s = s.substring(s.indexOf(INSTANCE_LINK_SUFFIX) + INSTANCE_LINK_SUFFIX.length());\n\n                long instanceID = Long.parseLong(instanceNumber);\n                Instance i = engine.getHeap().getInstanceByID(instanceID);\n                if (i != null) { queryObjects.add(i); hasObjectsResults = true; }\n            } else {\n                s = s.substring(classIdx + CLASS_LINK_PREFIX.length());\n                String classNumber = s.substring(0, s.indexOf(STRING_CLASS_LINK_NAME_PREFIX));\n                s = s.substring(s.indexOf(CLASS_LINK_SUFFIX) + CLASS_LINK_SUFFIX.length());\n\n                long classID = Long.parseLong(classNumber);\n                JavaClass c = engine.getHeap().getJavaClassByID(classID);\n                if (c != null) { queryObjects.add(c); hasObjectsResults = true; }\n            }\n\n            instanceIdx = s.indexOf(INSTANCE_LINK_PREFIX);\n            classIdx = instanceIdx != -1 ? -1 : s.indexOf(CLASS_LINK_PREFIX);\n        }\n    }\n    \n    private Object unwrap(Object obj1) {\n        Object obj2 = engine.unwrapJavaObject(obj1, true);\n        return obj2 != null ? obj2 : obj1;\n    }\n    \n    \n    private static String htmlize(String s) {\n        return \"<p>&nbsp;&nbsp\" + s.replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\") + \"</p>\"; // NOI18N\n    }\n    \n    \n    private class ProgressUpdater implements Runnable {\n\n        private final BoundedRangeModel progressModel;\n\n        ProgressUpdater(BoundedRangeModel model) {\n            progressModel = model;\n        }\n\n        public void run() {\n            while (queryRunning.get()) {\n                final int newVal;\n                int val = progressModel.getValue() + 10;\n                \n                if (val > progressModel.getMaximum()) {\n                    val = progressModel.getMinimum();\n                }\n                newVal = val;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        progressModel.setValue(newVal);\n                    }\n                });\n                try {\n                    Thread.sleep(200);\n                } catch (InterruptedException e) {\n                    Thread.currentThread().interrupt();\n                }\n            }\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/swing/HTMLTextComponent.java",
    "content": "/*\n * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.swing;\n\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.util.Arrays;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.Document;\nimport javax.swing.text.EditorKit;\nimport javax.swing.text.Segment;\nimport javax.swing.text.html.HTMLDocument;\nimport javax.swing.text.html.HTMLEditorKit;\nimport javax.swing.text.html.StyleSheet;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class HTMLTextComponent extends HTMLTextArea {\n    \n    private boolean neverDisplayed = true;\n    \n    \n    public HTMLTextComponent() {\n        super();\n    }\n    \n    public HTMLTextComponent(String text) {\n        super(text);\n    }\n    \n    \n    public void addNotify() {\n        super.addNotify();\n        \n        if (neverDisplayed) {\n            if (isShowing()) {\n                neverDisplayed = false;\n                firstDisplayed();\n            } else {\n                addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && HTMLTextComponent.this.isShowing()) {\n                            neverDisplayed = false;\n                            HTMLTextComponent.this.removeHierarchyListener(this);\n                            HTMLTextComponent.this.firstDisplayed();\n                        }\n                    }\n                });\n            }\n        }\n    }\n    \n    public final boolean neverDisplayed() {\n        return neverDisplayed;\n    }\n    \n    protected void firstDisplayed() {}\n    \n    \n    public EditorKit getEditorKitForContentType(String type) {\n        // Always assumes \"text/html\" as this is a HTML displayer\n        return new CustomHtmlEditorKit();\n    }\n    \n    \n    private static class CustomHtmlEditorKit extends HTMLEditorKit {\n\n        public Document createDefaultDocument() {\n            StyleSheet styles = getStyleSheet();\n            StyleSheet ss = new StyleSheet();\n\n            ss.addStyleSheet(styles);\n\n            HTMLDocument doc = new CustomHTMLDocument(ss);\n            doc.setParser(getParser());\n            doc.setAsynchronousLoadPriority(4);\n            doc.setTokenThreshold(100);\n            return doc;\n        }\n        \n    }\n\n    private static class CustomHTMLDocument extends HTMLDocument {\n\n        private static final int CACHE_BOUNDARY = 1000;\n        private char[] segArray;\n        private int segOffset;\n        private int segCount;\n        private boolean segPartialReturn;\n        private int lastOffset;\n        private int lastLength;\n\n        private CustomHTMLDocument(StyleSheet ss) {\n            super(ss);\n            lastOffset = -1;\n            lastLength = -1;\n            putProperty(\"multiByte\", Boolean.TRUE);      // NOI18N\n        }\n\n        public void getText(int offset, int length, Segment txt) throws BadLocationException {\n            if (lastOffset == offset && lastLength == length) {\n                txt.array = segArray;\n                txt.offset = segOffset;\n                txt.count = segCount;\n                txt.setPartialReturn(segPartialReturn);\n                return;\n            }\n            super.getText(offset, length, txt);\n            if (length > CACHE_BOUNDARY || lastLength <= CACHE_BOUNDARY) {\n                segArray = Arrays.copyOf(txt.array, txt.array.length);\n                segOffset = txt.offset;\n                segCount = txt.count;\n                segPartialReturn = txt.isPartialReturn();\n                lastOffset = offset;\n                lastLength = length;\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/swing/LinkButton.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.swing;\n\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.FocusAdapter;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SwingUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class LinkButton extends JButton {\n    \n    private boolean mouseOver;\n    private boolean focused;\n    private String text;\n    \n    public LinkButton() {\n        super();\n        tweak();\n    }\n    \n    public LinkButton(String text) {\n        super(text);\n        tweak();\n    }\n    \n    public LinkButton(String text, Icon icon) {\n        super(text, icon);\n        tweak();\n    }\n    \n    \n    public void setText(String text) {\n        this.text = text.replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\").replace(\" \", \"&nbsp;\"); // NOI18N\n        if (isEnabled() && (mouseOver || focused)) super.setText(\"<html><a href='#'>\" + this.text + \"</a></html>\"); // NOI18N\n        else super.setText(\"<html>\" + this.text + \"</html>\"); // NOI18N\n    }\n    \n    protected void fireActionPerformed(ActionEvent e) {\n        super.fireActionPerformed(e);\n        clicked();\n    }\n    \n    public Dimension getMinimumSize() {\n        return getPreferredSize();\n    }\n    \n    public Dimension getMaximumSize() {\n        return getPreferredSize();\n    }\n    \n    protected void clicked() {}\n    \n    protected void middleClicked(MouseEvent e) {}\n    \n    protected void populatePopup(JPopupMenu popup) {}\n    \n    \n    protected void processKeyEvent(KeyEvent e) {\n        int code = e.getKeyCode();\n        if (code == KeyEvent.VK_CONTEXT_MENU ||\n           (code == KeyEvent.VK_F10 && e.getModifiers() == InputEvent.SHIFT_MASK)) {\n            e.consume();\n            showPopupMenu(null);\n        }\n        \n        super.processKeyEvent(e);\n    }\n    \n    \n    private void tweak() {\n        putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n        setBorder(BorderFactory.createEmptyBorder(2, 3, 2, 3));\n        setOpaque(false);\n        setContentAreaFilled(false);\n        setFocusPainted(false);\n        setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n        MouseAdapter mouse = new MouseAdapter() {\n            public void mouseEntered(MouseEvent e) {\n                mouseOver = true;\n                setText(text);\n            }\n            public void mouseExited(MouseEvent e) {\n                mouseOver = false;\n                setText(text);\n            }\n            public void mouseMoved(MouseEvent e) {\n                if (!mouseOver) {\n                    mouseOver = true;\n                    setText(text);\n                }\n            }\n            public void mousePressed(MouseEvent e) {\n                if (e.isPopupTrigger()) showPopupMenu(e);\n            }\n            public void mouseReleased(MouseEvent e) {\n                if (e.isPopupTrigger()) showPopupMenu(e);\n            }\n            public void mouseClicked(MouseEvent e) {\n                if (SwingUtilities.isMiddleMouseButton(e)) middleClicked(e);\n            }\n        };\n        addMouseListener(mouse);\n        addMouseMotionListener(mouse);\n        addFocusListener(new FocusAdapter() {\n            public void focusGained(FocusEvent e) {\n                focused = true;\n                setText(text);\n            }\n            public void focusLost(FocusEvent e) {\n                focused = false;\n                mouseOver = false;\n                setText(text);\n            }\n        });\n    }\n    \n    private void showPopupMenu(MouseEvent e) {\n        JPopupMenu popup = new JPopupMenu();\n        populatePopup(popup);\n        \n        if (popup.getComponentCount() > 0) {\n            Dimension pref = popup.getPreferredSize();\n            if (e == null) {\n                popup.show(this, getWidth() / 2, -pref.height);\n            } else {\n                popup.show(this, e.getX(), e.getY() - pref.height);\n            }\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/swing/MenuButton.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.swing;\n\nimport java.awt.Color;\nimport java.awt.event.FocusAdapter;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.KeyAdapter;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.JMenuItem;\nimport javax.swing.JToggleButton;\nimport javax.swing.MenuElement;\nimport javax.swing.MenuSelectionManager;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class MenuButton extends JMenuItem implements ChangeListener {\n    \n    private static final String CONSUME_EVENT_KEY = \"PopupMenu.consumeEventOnClose\"; // NOI18N\n    private Object originalConsumeEvent;\n    \n    private final Color foreground;\n    private final Color background;\n    private final boolean opaque;\n    \n    private boolean listening;\n    private boolean hovered;\n    \n    private boolean skipGainedFocus;\n    \n    \n    public MenuButton(String text) {\n        this(text, false);\n    }\n    \n    public MenuButton(String text, final boolean selectable) {\n        super(text);\n        \n        \n        foreground = getForeground();\n        background = getBackground();\n        opaque = isOpaque();\n        \n        setModel(new JToggleButton.ToggleButtonModel() {\n//            private boolean fromGroup;\n            public void setSelected(boolean b) {\n                if (!selectable) return;\n//                System.err.println(\">>> Selecting \" + getText() + \" from \" + isSelected() + \" to \" + b);\n                boolean selected = isSelected();\n                if (selected == b) return;\n                super.setSelected(b);\n                if (selected != isSelected())\n                    if (selected) {\n                        setForeground(foreground);\n                        setBackground(background);\n                        setOpaque(opaque);\n                        repaint();\n                        deselected();\n                    } else {\n//                        setForeground(UIManager.getColor(\"List.selectionForeground\"));\n                        setForeground(Color.WHITE);\n                        setBackground(UIManager.getColor(\"List.selectionBackground\")); // NOI18N\n                        setOpaque(true);\n                        repaint();\n                        selected();\n                    }\n            }\n        });\n        \n        setFocusable(true);\n        setRolloverEnabled(true);\n        setBorder(BorderFactory.createEmptyBorder(0, -11, 0, 0));\n        \n        MouseAdapter ml = new MouseAdapter() {\n            public void mouseEntered(MouseEvent e) {\n//                System.err.println(\">>> mouseEntered\");\n                if (!canSelect()) return;\n                hovered = true;\n                showHover();\n            }\n            public void mouseMoved(MouseEvent e) {\n//                System.err.println(\">>> mouseMoved\");\n                if (!canSelect()) return;\n                hovered = true;\n                showHover();\n            }\n            public void mouseExited(MouseEvent e) {\n//                System.err.println(\">>> mouseExited\");\n                hovered = false;\n                if (!canSelect()) return;\n                hideHover();\n            }\n            public void mousePressed(MouseEvent e) {\n                if (!canSelect()) return;\n                requestFocusInWindow();\n                showHover();\n            }\n            public void mouseReleased(MouseEvent e) {\n                if (!canSelect()) return;\n                requestFocusInWindow();\n                showHover();\n            }\n            public void mouseClicked(MouseEvent e) {\n                if (SwingUtilities.isLeftMouseButton(e)) {\n                    clicked();\n                    if (selectable) setSelected(true);\n                }\n            }\n        };\n        addMouseListener(ml);\n        addMouseMotionListener(ml);\n        \n        \n        addKeyListener(new KeyAdapter() {\n            public void keyTyped(KeyEvent e) {\n                if (e.getKeyChar() == ' ' || e.getKeyChar() == '\\n') { // NOI18N\n                    clicked();\n                    if (selectable) setSelected(true);\n                }\n            }\n        });\n        \n        addFocusListener(new FocusAdapter() {\n            public void focusGained(FocusEvent e) {\n                if (skipGainedFocus) {\n                    skipGainedFocus = false;\n                } else {\n                    if (!canSelect()) return;\n                    showHover();\n                    scrollRectToVisible(getBounds());\n                }\n            }\n            public void focusLost(FocusEvent e) {\n//                System.err.println(\">>> focusLost\");\n                hovered = false;\n                if (!canSelect()) return;\n                hideHover();\n            }\n        });\n    }\n    \n    \n    public void requestFocus() {\n//        skipGainedFocus = true;\n        super.requestFocus();\n    }\n    \n    \n//    public void addNotify() {\n//        super.addNotify();\n//        MenuSelectionManager.defaultManager().addChangeListener(this);\n//    }\n//    \n//    public void removeNotify() {\n//        MenuSelectionManager.defaultManager().removeChangeListener(this);\n//        super.removeNotify();\n//    }\n    \n    public void stateChanged(ChangeEvent e) {\n//                System.err.println(\">>> change \" + hovered + \" - \" + Arrays.toString(MenuSelectionManager.defaultManager().getSelectedPath()));\n//        System.err.println(\">>> State changed at \" + getText());\n        if (MenuSelectionManager.defaultManager().getSelectedPath().length == 0 && hovered) {\n            if (isFocusOwner()) {\n                SwingUtilities.invokeLater(this::showHover);\n            } else {\n                showHover();\n            }\n        }\n    }\n    \n    \n    protected void processMouseEvent(MouseEvent e) {\n        if (canSelect()) super.processMouseEvent(e);\n    }\n    \n    \n    protected void clicked() { /*System.err.println(\">>> clicked \" + getText());*/ }\n    \n    protected void selected() { /*System.err.println(\">>> selected \" + getText());*/ }\n    \n    protected void deselected() { /*System.err.println(\">>> deselected \" + getText());*/ }\n    \n    \n    private void showHover() {\n        originalConsumeEvent = UIManager.get(CONSUME_EVENT_KEY);\n        UIManager.put(CONSUME_EVENT_KEY, Boolean.FALSE);\n        MenuSelectionManager msm = MenuSelectionManager.defaultManager();\n        msm.setSelectedPath(new MenuElement[] { MenuButton.this });\n        if (!listening) {\n            msm.addChangeListener(this);\n            listening = true;\n        }\n        repaint();\n    }\n    \n    private void hideHover() {\n        MenuSelectionManager msm = MenuSelectionManager.defaultManager();\n        if (listening) {\n            msm.removeChangeListener(this);\n            listening = false;\n        }\n        msm.clearSelectedPath();\n        UIManager.put(CONSUME_EVENT_KEY, originalConsumeEvent);\n        repaint();\n    }\n    \n    private boolean canSelect() {\n        MenuElement[] sel = MenuSelectionManager.defaultManager().getSelectedPath();\n//        System.err.println(\">>> Window \" + SwingUtilities.getWindowAncestor(this).getName() + \" sel \" + Arrays.toString(sel));\n//        return false;\n        if (sel.length == 0) return true;\n        return sel[0] instanceof MenuButton;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/swing/MultiSplitContainer.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.swing;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.swing.JPanel;\nimport javax.swing.UIManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class MultiSplitContainer extends JPanel {\n    \n    private static final int DIVIDER_SIZE = 6;\n    private static final Color SEPARATOR_COLOR = UIManager.getColor(\"Separator.foreground\"); // NOI18N\n    \n    private final Map<Component, Double> componentsWeights = new HashMap<>();\n    private final List<Integer> dividerOffsets = new ArrayList<>();\n    private final List<Component> visibleComponents = new ArrayList<>();\n    \n    private final MouseHandler mHandler;\n    \n    \n    public MultiSplitContainer() {\n        super(null);\n        \n        mHandler = new MouseHandler();\n        addMouseListener(mHandler);\n        addMouseMotionListener(mHandler);\n    }\n    \n    public void doLayout() {\n        if (visibleComponents.isEmpty()) return;\n       \n        Insets insets = getInsets();        \n        int visiblesCount = visibleComponents.size();\n        \n        if (visiblesCount == 1) {\n            visibleComponents.get(0).setBounds(insets.left, insets.top, getWidth() - insets.left - insets.right, getHeight() - insets.top - insets.bottom);\n        } else {\n            Dimension size = getSize();     \n            int h = size.height - insets.top - insets.bottom;\n            \n            int x = insets.left;\n            Component comp;\n        \n            int dividersCount = dividerOffsets.size();\n            for (int i = 0; i < dividersCount; i++) {\n                int xx = dividerOffsets.get(i);\n                comp = visibleComponents.get(i);\n                comp.setBounds(x, insets.top, xx - x, h);\n                comp.validate();\n                x = xx + DIVIDER_SIZE;\n            }\n            \n            x = dividerOffsets.get(dividersCount - 1) + DIVIDER_SIZE;\n            comp = visibleComponents.get(visiblesCount - 1);\n            comp.setBounds(x, insets.top, getWidth() - insets.right - x, h);\n            comp.validate();\n        }\n    }\n    \n    public void invalidate() {\n        super.invalidate();\n        setupLayout();\n        doLayout();\n        repaint();\n    }\n    \n    \n    public void paint(Graphics g) {\n        super.paint(g);\n        \n        if (!dividerOffsets.isEmpty()) {\n            Insets i = getInsets();\n            g.setColor(SEPARATOR_COLOR);\n            for (int o : dividerOffsets) {\n                g.drawLine(o, i.top, o, getHeight() - i.bottom);\n                o += DIVIDER_SIZE - 1;\n                g.drawLine(o, i.top, o, getHeight() - i.bottom);\n            }\n        }\n    }\n    \n    \n    protected void addImpl(Component comp, Object constraints, int index) {\n        componentsWeights.put(comp, constraints instanceof Number ? ((Number)constraints).doubleValue() : 0.5d);\n        super.addImpl(comp, constraints, index);\n        invalidate();\n    }\n    \n    public void remove(int index) {\n        Component comp = getComponent(index);\n        super.remove(index);\n        componentsWeights.remove(comp);\n        invalidate();\n    }\n    \n    \n    private void setupLayout() {\n        if (mHandler.canDrag) return;\n        \n        dividerOffsets.clear();\n        visibleComponents.clear();\n            \n        Dimension size = getSize();\n        if (size.height == 0 || size.width == 0) return; // container too small\n        \n        double visRel = 0;\n        \n        for (Component c : getComponents()) {\n            if (c.isVisible()) {\n                visibleComponents.add(c);\n                visRel += componentsWeights.get(c);\n            }\n        }\n        \n        int visiblesCount = visibleComponents.size();\n        if (visiblesCount < 2) return; // no visible divider\n        \n        Insets insets = getInsets();\n        int w = size.width - insets.left - insets.right - ((visiblesCount - 1) * DIVIDER_SIZE);\n        \n        int x = insets.left;\n        \n        for (int i = 0; i < visiblesCount - 1; i++) {\n            x += (w / visRel * componentsWeights.get(visibleComponents.get(i)));\n            dividerOffsets.add(x);\n            x += DIVIDER_SIZE;\n        }\n    }\n    \n    \n    private class MouseHandler extends MouseAdapter {\n        \n        private boolean inDivider;\n        private int cursor;\n        private boolean canDrag;\n        private int offsetIdx;\n        private int dragX;\n        private int offsetX;\n        \n        private int minX;\n        private int maxX;\n        private Component c1;\n        private Component c2;\n        private double relWidth;\n        \n        public void mouseEntered(MouseEvent e) {\n            if (!canDrag) updateMouse(e, true);\n        }\n        \n        public void mouseExited(MouseEvent e) {\n            if (!canDrag) updateMouse(e, false);\n        }\n        \n        public void mouseMoved(MouseEvent e) {\n            updateMouse(e, true);\n        }\n        \n        public void mouseDragged(MouseEvent e) {\n            if (canDrag) {\n                int oldX = dividerOffsets.get(offsetIdx);\n                \n                int dx = dragX - e.getX();\n                int newX = oldX - dx;\n                newX = Math.max(newX, minX);\n                newX = Math.min(newX, maxX);\n                dividerOffsets.set(offsetIdx, newX);\n                \n                double c1width = c1.getWidth();\n                double c1Rel = c1width * relWidth / (c1width + c2.getWidth());\n                componentsWeights.put(c1, c1Rel);\n                componentsWeights.put(c2, relWidth - c1Rel);\n                \n                dragX = newX + offsetX;\n                \n                doLayout();\n                repaint();\n            }\n        }\n        \n        public void mousePressed(MouseEvent e) {\n            if (inDivider) {\n                canDrag = true;\n                dragX = e.getX();\n                offsetX = dragX - dividerOffsets.get(offsetIdx);\n                \n                Insets insets = getInsets();\n                minX = offsetIdx == 0 ? insets.left : dividerOffsets.get(offsetIdx - 1) + DIVIDER_SIZE;\n                maxX = offsetIdx == dividerOffsets.size() - 1 ? getWidth() - insets.right - DIVIDER_SIZE :\n                                                                dividerOffsets.get(offsetIdx + 1) - DIVIDER_SIZE;\n                \n                c1 = visibleComponents.get(offsetIdx);\n                c2 = visibleComponents.get(offsetIdx + 1);\n                relWidth = componentsWeights.get(c1) + componentsWeights.get(c2);\n            }\n        }\n        \n        public void mouseReleased(MouseEvent e) {\n            canDrag = false;\n            offsetIdx = -1;\n            c1 = null;\n            c2 = null;\n            updateMouse(e, inDivider);\n        }\n        \n        \n        private void updateMouse(MouseEvent e, boolean onContainer) {\n            inDivider = false;\n            int origCursor = cursor;\n            cursor = Cursor.DEFAULT_CURSOR;\n            if (onContainer) {\n                int x = e.getX();\n                for (int i = 0; i < dividerOffsets.size(); i++) {\n                    int divx = dividerOffsets.get(i);\n                    if (x >= divx && x <= divx + DIVIDER_SIZE - 1) {\n                        inDivider = true;\n                        offsetIdx = i;\n                        cursor = Cursor.E_RESIZE_CURSOR;\n                        break;\n                    }\n                }\n            }\n            if (origCursor != cursor) setCursor(Cursor.getPredefinedCursor(cursor));\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/swing/Splitter.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.swing;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.JSplitPane;\nimport javax.swing.SwingUtilities;\nimport javax.swing.plaf.basic.BasicSplitPaneDivider;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\nimport org.graalvm.visualvm.uisupport.UISupport;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class Splitter extends JSplitPane {\n    \n    private CustomizedSplitPaneUI splitterUI;\n\n    private HierarchyListener leftComponentListener;\n    private HierarchyListener rightComponentListener;\n    \n    private double dividerLocation;\n    private int customDividerSize;\n    private double requestedDividerLocation = -1;\n    \n    private static final Color BACKGROUND_COLOR;\n    private static final Color HIGHLIGHT_BACKGROUND;\n\n\n    static {\n        BACKGROUND_COLOR = UISupport.getDefaultBackground();\n\n        int darkerR = BACKGROUND_COLOR.getRed() - 20;\n        if (darkerR < 0) darkerR += 40;\n        int darkerG = BACKGROUND_COLOR.getGreen() - 20;\n        if (darkerG < 0) darkerG += 40;\n        int darkerB = BACKGROUND_COLOR.getBlue() - 20;\n        if (darkerB < 0) darkerB += 40;\n\n        HIGHLIGHT_BACKGROUND = new Color(darkerR, darkerG, darkerB);\n    }\n\n    \n    public Splitter(int newOrientation, Component newLeftComponent, Component newRightComponent) {\n        this(newOrientation, false, newLeftComponent, newRightComponent);\n    }\n\n    public Splitter(int newOrientation, boolean newContinuousLayout, Component newLeftComponent,\n                              Component newRightComponent) {\n        super(newOrientation, newContinuousLayout, newLeftComponent, newRightComponent);\n\n        updateVisibility();\n\n        if (!newLeftComponent.isVisible())\n            computeDividerLocationWhenInitiallyHidden(newLeftComponent);\n\n        if (!newRightComponent.isVisible())\n            computeDividerLocationWhenInitiallyHidden(newRightComponent);\n        \n        setResizeWeight(0.5d);\n        setDividerLocation(0.5d);\n    }\n\n\n    public void setDividerSize(int newSize) {\n        super.setDividerSize(newSize);\n        customDividerSize = newSize;\n    }\n\n    public void setDividerLocation(double requestedDividerLocation) {\n        Component divider = getDivider();\n        if (isVisible() && divider.isVisible()) { // SplitPane fully visible\n            super.setDividerLocation(requestedDividerLocation);\n            dividerLocation = requestedDividerLocation;\n        } else if (isVisible()) { // Divider not visible, will be updated in updateVisibility()\n            dividerLocation = requestedDividerLocation;\n        } else if (!isVisible()) { // SplitPane not visible, dividerLocation will be set on first reasonable getSize()\n            this.requestedDividerLocation = requestedDividerLocation;\n        }\n    }\n\n\n    public void setLeftComponent(Component newLeftComponent) {\n        if (leftComponent != null) {\n            leftComponent.removeHierarchyListener(leftComponentListener);\n            leftComponentListener = null;\n        }\n\n        super.setLeftComponent(newLeftComponent);\n\n        if (getLeftComponent() != null) {\n            leftComponentListener = new VisibilityListener(newLeftComponent);\n            newLeftComponent.addHierarchyListener(leftComponentListener);\n        }\n\n        updateVisibility();\n    }\n\n    public void setRightComponent(Component newRightComponent) {\n        if (rightComponent != null) {\n            rightComponent.removeHierarchyListener(rightComponentListener);\n            rightComponentListener = null;\n        }\n\n        super.setRightComponent(newRightComponent);\n\n        if (getRightComponent() != null) {\n            rightComponentListener = new VisibilityListener(newRightComponent);\n            newRightComponent.addHierarchyListener(rightComponentListener);\n        }\n\n        updateVisibility();\n    }\n    \n\n    public void reshape(int x, int y, int width, int height) {\n        super.reshape(x, y, width, height);\n        if (width > 0 && height > 0 && requestedDividerLocation != -1) {\n            super.setDividerLocation(requestedDividerLocation);\n            dividerLocation = requestedDividerLocation;\n            // SplitPaneUI.paint() needs to be invoked here to set the\n            // BasicSplitPaneUI.painted flag to enable resizing the divider\n            // even if the component hasn't been shown yet.\n            getUI().paint(getGraphics(), this);\n            requestedDividerLocation = -1;\n        }\n    }\n\n    \n    private Component getDivider() {\n        if (ui == null) return null;\n        return ((BasicSplitPaneUI)ui).getDivider();\n    }\n\n    private void computeDividerLocationWhenHidden(Component hiddenComponent) {\n        if (leftComponent.isVisible() || rightComponent.isVisible()) {\n            boolean horiz = getOrientation() == JSplitPane.HORIZONTAL_SPLIT;\n            double size  = horiz ? getSize().getWidth() :\n                                   getSize().getHeight();\n            double csize = horiz ? hiddenComponent.getSize().getWidth() :\n                                   hiddenComponent.getSize().getHeight();\n            computeDividerLocation(hiddenComponent, size, csize);\n        }\n    }\n\n    private void computeDividerLocationWhenInitiallyHidden(Component hiddenComponent) {\n        if (leftComponent.isVisible() || rightComponent.isVisible()) {\n            boolean horiz = getOrientation() == JSplitPane.HORIZONTAL_SPLIT;\n            double size  = horiz ? getPreferredSize().getWidth() :\n                                   getPreferredSize().getHeight();\n            double csize = horiz ? hiddenComponent.getPreferredSize().getWidth() :\n                                   hiddenComponent.getPreferredSize().getHeight();\n            computeDividerLocation(hiddenComponent, size, csize);\n        }\n    }\n\n    private void computeDividerLocation(Component hiddenComponent, double size, double csize) {\n        if (hiddenComponent == leftComponent) {\n            dividerLocation = csize / (size - customDividerSize);\n        } else {\n            dividerLocation = (size - customDividerSize - csize) / (size - customDividerSize);\n        }\n    }\n\n    private void updateVisibility() {\n        Component divider = getDivider(); // null UI, not yet set\n        if (divider == null) return;\n\n        if (leftComponent == null || rightComponent == null) return;\n\n        boolean leftVisible = leftComponent.isVisible();\n        boolean rightVisible = rightComponent.isVisible();\n\n        if (leftVisible && rightVisible) {\n            if (!divider.isVisible()) {\n                Splitter.super.setDividerSize(customDividerSize);\n                divider.setVisible(true);\n                setDividerLocation(dividerLocation);\n            }\n            if (!isVisible()) setVisible(true);\n        } else if (!leftVisible && !rightVisible) {\n            if (isVisible()) setVisible(false);\n        } else {\n            if (divider.isVisible()) {\n                Splitter.super.setDividerSize(0);\n                divider.setVisible(false);\n                setDividerLocation(0);\n            }\n            if (!isVisible()) setVisible(true);\n        }\n\n        if (getParent() != null) getParent().doLayout();\n    }\n    \n    \n    public void updateUI() {\n        if (getUI() != customUI()) setUI(customUI());\n\n        setBorder(null);\n        setOpaque(false);\n        setDividerSize(6);\n        setContinuousLayout(true);\n\n        final BasicSplitPaneDivider divider = ((BasicSplitPaneUI) getUI()).getDivider();\n        divider.setBackground(BACKGROUND_COLOR);\n        divider.setBorder(null);\n\n        divider.addMouseListener(new MouseAdapter() {\n            public void mouseEntered(MouseEvent e) {\n                divider.setBackground(HIGHLIGHT_BACKGROUND);\n                divider.repaint();\n            }\n            public void mouseExited(MouseEvent e) {\n                divider.setBackground(BACKGROUND_COLOR);\n                divider.repaint();\n            }\n            public void mouseClicked(MouseEvent e) {\n                if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {\n                    setResizeWeight(0.5d);\n                    setDividerLocation(0.5d);\n                }\n            }\n        });\n    }\n    \n    private CustomizedSplitPaneUI customUI() {\n        if (splitterUI == null) splitterUI = new CustomizedSplitPaneUI();\n        return splitterUI;\n    }\n    \n    \n    private static class CustomizedSplitPaneUI extends BasicSplitPaneUI {\n        public BasicSplitPaneDivider createDefaultDivider() {\n            return new BasicSplitPaneDivider(this) {\n                public void paint(Graphics g) {\n                    Dimension size = getSize();\n                    g.setColor(getBackground());\n                    g.fillRect(0, 0, size.width, size.height);\n                }\n            };\n        }\n    }\n\n\n    private class VisibilityListener implements HierarchyListener {\n\n        private boolean wasVisible;\n        private final Component c;\n\n        VisibilityListener(Component c) {\n            this.c = c;\n            wasVisible = c.isVisible();\n        }\n\n        public void hierarchyChanged(HierarchyEvent e) {\n            if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 ||\n                (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) {\n                \n                boolean visible = c.isVisible();\n                if (wasVisible == visible) return;\n\n                wasVisible = visible;\n\n                if (visible) componentShown();\n                else componentHidden(c);\n            }\n        }\n\n        private void componentHidden(Component c) {\n            computeDividerLocationWhenHidden(c);\n\n            // Make sure the component is visible when shown\n            if ((dividerLocation <= 0) || (dividerLocation >= 1))\n                dividerLocation = 0.5;\n\n            updateVisibility();\n        }\n\n        private void componentShown() {\n            updateVisibility();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/BreadCrumbsNavigator.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.awt.Component;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.swing.LinkButton;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author JiriSedlacek\n */\n@NbBundle.Messages({\n    \"BreadCrumbsNavigator_Pin=Pin\",\n    \"BreadCrumbsNavigator_ResetPin=Reset Pin\",\n    \"BreadCrumbsNavigator_Class=class\",\n    \"BreadCrumbsNavigator_SelectNode=Select {0}\",\n    \"BreadCrumbsNavigator_ResetPinSelectNode=Reset Pin and Select {0}\",\n    \"BreadCrumbsNavigator_ResetView=Reset View\"\n})\nabstract class BreadCrumbsNavigator {\n    \n    private static final Icon ICON_SEPARATOR = ImageUtilities.image2Icon(ImageUtilities.loadImage(BreadCrumbsNavigator.class.getPackage().getName().replace('.', '/') + \"/separator.png\", true));\n    private static final Icon ICON_PIN = ImageUtilities.image2Icon(ImageUtilities.loadImage(BreadCrumbsNavigator.class.getPackage().getName().replace('.', '/') + \"/pin.png\", true));\n    private static final Icon ICON_PIN_SELECTED = ImageUtilities.image2Icon(ImageUtilities.loadImage(BreadCrumbsNavigator.class.getPackage().getName().replace('.', '/') + \"/pin_selected.png\", true));\n    \n    \n    BreadCrumbsNavigator() {\n    }\n    \n    \n    private JComponent component;\n    \n    \n    abstract void nodeClicked(HeapViewerNode node);\n    \n    abstract void nodePinned(HeapViewerNode node);\n    \n    abstract void openNode(HeapViewerNode node);\n    \n    \n    abstract HeapViewerRenderer getRenderer(HeapViewerNode node);\n    \n    \n    abstract HeapViewerNodeAction.Actions getNodeActions(HeapViewerNode node);\n    \n    \n    Component getComponent() {\n        if (component == null) init();\n        return component;\n    }\n    \n    \n    void setNode(HeapViewerNode node, HeapViewerNode pinnedNode, HeapViewerNode root, String viewName) {\n        if (component == null) init();\n        setNodeImpl(node, pinnedNode, root, viewName);\n    }\n    \n    private void setNodeImpl(HeapViewerNode node, final HeapViewerNode pinnedNode, HeapViewerNode root, String viewName) {\n        component.removeAll();\n        \n        HeapViewerNode visitedPinnedNode = null;\n        \n        while (node != null && !(node instanceof RootNode)) {\n            component.add(createSeparator(), 0);\n            \n            final HeapViewerNode nodeF = node;\n            \n            if (viewName != null || node != root) if (!node.isLeaf()) { // NOTE: may it make sense to pin empty nodes?\n                \n                component.add(Box.createHorizontalStrut(2), 0);\n                \n                PinButton pb = new PinButton() {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        nodePinned(isSelected() ? nodeF : null);\n                    }\n                };\n                pb.setSelected(node.equals(pinnedNode));\n                pb.setToolTipText(pb.isSelected() ? Bundle.BreadCrumbsNavigator_ResetPin() : Bundle.BreadCrumbsNavigator_Pin());\n                if (pb.isSelected()) visitedPinnedNode = pinnedNode;\n                component.add(pb, 0);\n                component.add(Box.createHorizontalStrut(3), 0);\n            }\n            \n            HeapViewerRenderer renderer = getRenderer(node);\n            \n            LinkButton lb = new LinkButton(renderer.getShortName(), renderer.getIcon()) {\n                protected void clicked() {\n                    nodeClicked(nodeF);\n                }\n                protected void middleClicked(MouseEvent e) {\n                    HeapViewerNodeAction.Actions nodeActions = getNodeActions(nodeF);\n                    ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), \"middle button\", e.getWhen(), e.getModifiers()); // NOI18N\n                    nodeActions.performMiddleButtonAction(ae);\n                }\n                protected void populatePopup(JPopupMenu popup) {\n                    HeapViewerNodeAction.Actions nodeActions = getNodeActions(nodeF);\n                    nodeActions.populatePopup(popup);\n                }\n            };\n            boolean beforePinnedNode = visitedPinnedNode != null && visitedPinnedNode != node;\n            if (beforePinnedNode) lb.setForeground(UIUtils.getDisabledLineColor());\n            lb.setToolTipText(beforePinnedNode ? Bundle.BreadCrumbsNavigator_ResetPinSelectNode(renderer.toString()) : Bundle.BreadCrumbsNavigator_SelectNode(renderer.toString()));\n            lb.addMouseListener(new MouseAdapter() {\n                public void mouseClicked(MouseEvent e) {\n                    if (SwingUtilities.isMiddleMouseButton(e)) openNode(nodeF);\n                }\n            });\n\n            component.add(lb, 0);\n            \n            node = node.getParent();\n        }\n        \n        if (viewName != null) {\n            component.add(createSeparator(), 0);\n\n            LinkButton lb = new LinkButton(viewName) {\n                protected void clicked() { nodeClicked(null); }\n            };\n            if (visitedPinnedNode != null) lb.setForeground(UIUtils.getDisabledLineColor());\n            lb.setToolTipText(Bundle.BreadCrumbsNavigator_ResetView());\n            component.add(lb, 0);\n        \n            component.add(Box.createHorizontalStrut(4), 0);\n        }\n        \n        component.invalidate();\n        component.revalidate();\n        component.repaint();\n    }\n    \n    private static JComponent createSeparator() {\n        JLabel sepL = new JLabel(ICON_SEPARATOR);\n        sepL.setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 0));\n        return sepL;\n    }\n    \n    \n    private void init() {\n        final int refHeight = new LinkButton(\"XXX\", Icons.getIcon(LanguageIcons.CLASS)).getPreferredSize().height + 3; // NOI18N\n        component = new JPanel(null) {\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.height = refHeight;\n                return dim;\n            }\n            public Dimension getMinimumSize() {\n                Dimension dim = super.getMinimumSize();\n                dim.height = refHeight;\n                return dim;\n            }\n        };\n        component.setLayout(new BoxLayout(component, BoxLayout.LINE_AXIS));\n        component.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UIManager.getColor(\"Separator.foreground\"))); // NOI18N\n    }\n    \n    \n    private static class PinButton extends JToggleButton {\n        PinButton() {\n            super(ICON_PIN);\n            setSelectedIcon(ICON_PIN_SELECTED);\n            setRolloverIcon(ICON_PIN_SELECTED);\n            setPressedIcon(ICON_PIN_SELECTED);\n            setOpaque(false);\n            setBorderPainted(false);\n            setContentAreaFilled(false);\n            setBorder(BorderFactory.createEmptyBorder());\n            setFocusPainted(false);\n            setMargin(new Insets(1, 2, 1, 2));\n            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/HTMLView.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.InputEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Objects;\nimport java.util.concurrent.ExecutionException;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SwingUtilities;\nimport javax.swing.SwingWorker;\nimport javax.swing.text.AttributeSet;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.DefaultCaret;\nimport javax.swing.text.Document;\nimport javax.swing.text.html.HTML;\nimport javax.swing.text.html.HTMLDocument;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.swing.HTMLTextComponent;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextAreaSearchUtils;\nimport org.openide.util.Exceptions;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class HTMLView {\n    \n    private final String viewID;\n    \n    private final HeapContext context;\n    private final HeapViewerActions actions;\n    \n    private Collection<HeapViewerNodeAction.Provider> actionProviders;\n    \n    private JComponent component;\n    private HTMLTextComponent htmlComponent;\n    \n    private String currentText;\n    \n    private boolean pendingText = true;\n    private String pendingReference;\n    \n    \n    public HTMLView(String viewID, HeapContext context, HeapViewerActions actions) {\n        this(viewID, context, actions, null);\n    }\n    \n    public HTMLView(String viewID, HeapContext context, HeapViewerActions actions, String initialText) {\n        this.viewID = viewID;\n        this.context = context;\n        this.actions = actions;\n        this.currentText = initialText;\n        \n        actionProviders = new ArrayList<>();\n        for (HeapViewerNodeAction.Provider provider : Lookup.getDefault().lookupAll(HeapViewerNodeAction.Provider.class))\n            if (provider.supportsView(context, viewID)) actionProviders.add(provider);\n    }\n    \n    \n    protected String computeData(HeapContext context, String viewID) {\n        return currentText;\n    }\n    \n    protected HeapViewerNode nodeForURL(URL url, HeapContext context) {\n        return null;\n    }\n    \n    \n    public void setText(String text) {\n        currentText = text;\n        if (htmlComponent != null) {\n            htmlComponent.setText(currentText);\n            HTMLTextAreaSearchUtils.textChanged(htmlComponent);\n            String _text = htmlComponent.getText();\n            if (_text != null && !_text.isEmpty()) try {\n                htmlComponent.setCaretPosition(0);\n            } catch (Exception e) {}\n        }\n    }\n    \n    public void selectReference(String reference) {\n        if (htmlComponent == null || pendingText) {\n            pendingReference = reference;\n        } else {\n            Document d = htmlComponent.getDocument();\n            if (d instanceof HTMLDocument) {\n                HTMLDocument doc = (HTMLDocument)d;\n                HTMLDocument.Iterator iter = doc.getIterator(HTML.Tag.A);\n                for (; iter.isValid(); iter.next()) {\n                    AttributeSet a = iter.getAttributes();\n                    String nm = (String) a.getAttribute(HTML.Attribute.NAME);\n                    if (Objects.equals(reference, nm)) {\n                        selectReference(iter);\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    private void selectReference(HTMLDocument.Iterator iter) {\n        htmlComponent.requestFocus();\n        \n        int start = iter.getStartOffset();\n        htmlComponent.select(start, iter.getEndOffset());\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                try {\n                    Rectangle rect = htmlComponent.modelToView(start);\n                    if (rect != null) {\n                        rect.x -= htmlComponent.getInsets().left + component.getInsets().left;\n                        rect.height = htmlComponent.getVisibleRect().height;\n                        htmlComponent.scrollRectToVisible(rect);\n                    }\n                } catch (BadLocationException e) {}\n            }\n        });\n    }\n    \n    \n    public JComponent getComponent() {\n        if (component == null) initUI();\n        return component;\n    }\n    \n    String getViewID() {\n        return viewID;\n    }\n    \n    HeapContext getContext() {\n        return context;\n    }\n    \n    \n    private void initUI() {\n        htmlComponent = new HTMLTextComponent() {\n            protected void firstDisplayed() {\n                super.firstDisplayed();\n                \n                htmlComponent.addMouseListener(new MouseAdapter() {\n                    public void mouseClicked(MouseEvent e) {\n                        if (SwingUtilities.isMiddleMouseButton(e)) {\n                            URL link = htmlComponent.getActiveLink();\n                            if (link != null) HTMLView.this.invokeMiddleButtonAction(link, e);\n                        }\n                    }\n                });\n                \n                new SwingWorker<String, String>() {\n                    protected String doInBackground() throws Exception {\n                        return computeData(context, viewID);\n                    }\n                    protected void done() {\n                        try {\n                            HTMLView.this.setText(get());\n                            pendingText = false;\n                            if (pendingReference != null) {\n                                SwingUtilities.invokeLater(new Runnable() {\n                                    public void run() {\n                                        selectReference(pendingReference);\n                                        pendingReference = null;\n                                    }\n                                });\n                                \n                            }\n                        } catch (InterruptedException ex) {\n                            Exceptions.printStackTrace(ex);\n                        } catch (ExecutionException ex) {\n                            Exceptions.printStackTrace(ex);\n                        }\n                    }\n                }.execute();\n            }\n            protected void showURL(URL url, InputEvent e) {\n                HTMLView.this.invokeDefaultAction(url, e);\n            }\n            protected void populatePopup(JPopupMenu popup) {\n                URL link = htmlComponent.getActiveLink();\n                if (link != null) HTMLView.this.populatePopup(link, popup);\n                \n                if (popup.getComponentCount() > 0) popup.addSeparator();\n                popup.add(createCopyMenuItem());\n                popup.add(createSelectAllMenuItem());\n                \n                Action find = getActionMap().get(HTMLTextAreaSearchUtils.FIND_ACTION_KEY); \n                if (find != null) {\n                    popup.addSeparator();\n                    popup.add(new JMenuItem(find));\n                }\n            }\n        };\n        \n        //----------------------------------------------------------------------\n        // NOTE: uncomment to allow the selection to survive focusLost\n        htmlComponent.setCaret(new DefaultCaret() {\n            public void setSelectionVisible(boolean visible) {\n               super.setSelectionVisible(true);\n            }\n        });\n        //----------------------------------------------------------------------\n        \n        if (currentText != null) htmlComponent.setText(currentText);\n                \n        JPanel container = new JPanel(new BorderLayout());\n        container.setBackground(htmlComponent.getBackground());\n        container.add(htmlComponent, BorderLayout.CENTER);\n        container.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));\n        \n        component = new JPanel(new BorderLayout());\n        component.add(new ScrollableContainer(container), BorderLayout.CENTER);\n        component.add(HTMLTextAreaSearchUtils.createSearchPanel(htmlComponent), BorderLayout.SOUTH);\n    }\n    \n    \n    private void invokeDefaultAction(URL url, InputEvent e) {\n        HeapViewerNode node = nodeForURL(url, context);\n        if (node == null) return;\n\n        HeapViewerNodeAction.Actions nodeActions = HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions);\n        ActionEvent ae = e == null ? new ActionEvent(htmlComponent, ActionEvent.ACTION_PERFORMED, \"link\"): // NO18N\n                                     new ActionEvent(e.getSource(), e.getID(), \"link\", e.getWhen(), e.getModifiers()); // NO18N\n        nodeActions.performDefaultAction(ae);\n    }\n    \n    private void invokeMiddleButtonAction(URL url, InputEvent e) {\n        HeapViewerNode node = nodeForURL(url, context);\n        if (node == null) return;\n\n        HeapViewerNodeAction.Actions nodeActions = HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions);\n        ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), \"middle button\", e.getWhen(), e.getModifiers()); // NO18N\n        nodeActions.performMiddleButtonAction(ae);\n    }\n    \n    private void populatePopup(URL url, JPopupMenu popup) {\n        HeapViewerNode node = nodeForURL(url, context);\n        if (node == null) return;\n        \n        HeapViewerNodeAction.Actions nodeActions = HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions);\n        nodeActions.populatePopup(popup);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/HeapDumpInfoAction.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.io.File;\nimport java.text.NumberFormat;\nimport java.util.Date;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.TimeoutException;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.SwingWorker;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.heapviewer.HeapViewer;\nimport org.graalvm.visualvm.lib.jfluid.heap.HeapSummary;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\n\n@NbBundle.Messages({\n    \"HeapDumpInfoAction_ActionName=Heap dump information\",\n    \"HeapDumpInfoAction_ActionDescr=Display heap dump information\",\n    \"HeapDumpInfoAction_WindowCaption=Heap Dump Information\",\n    \"HeapDumpInfoAction_SummaryString=Summary:\",\n    \"HeapDumpInfoAction_NotAvailableMsg=&lt;not available&gt;\",\n    \"HeapDumpInfoAction_FileItemString=<b>File: </b>{0}\",\n    \"HeapDumpInfoAction_FileSizeItemString=<b>File Size: </b>{0}\",\n    \"HeapDumpInfoAction_DateTakenItemString=<b>Date Taken: </b>{0}\",\n    \"HeapDumpInfoAction_ComputingInfo=computing heap dump information...\"\n})\nclass HeapDumpInfoAction extends AbstractAction {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final HeapViewer heapViewer;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HeapDumpInfoAction(HeapViewer heapViewer) {\n        putValue(Action.NAME, Bundle.HeapDumpInfoAction_ActionName());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.HeapDumpInfoAction_ActionDescr());\n        putValue(Action.SMALL_ICON, Icons.getIcon(GeneralIcons.INFO));\n        putValue(\"iconBase\", Icons.getResource(GeneralIcons.INFO)); // NOI18N\n        this.heapViewer = heapViewer;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void actionPerformed(ActionEvent e) {\n        DialogDescriptor dd = new DialogDescriptor(infoComponent(heapViewer),\n                              Bundle.HeapDumpInfoAction_WindowCaption(), true,\n                              new Object[] { DialogDescriptor.OK_OPTION }, \n                              DialogDescriptor.OK_OPTION, DialogDescriptor.DEFAULT_ALIGN,\n                              null, null);\n        DialogDisplayer.getDefault().createDialog(dd).setVisible(true);\n    }\n    \n    \n    private static JComponent infoComponent(final HeapViewer heapViewer) {\n        HTMLTextArea text = new HTMLTextArea();\n        text.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));\n        createInfo(text, heapViewer);\n        \n        ScrollableContainer textScroll = new ScrollableContainer(text);\n        textScroll.setPreferredSize(new Dimension(500, 175));\n        return textScroll;\n    }\n    \n    private static void createInfo(final HTMLTextArea text, final HeapViewer heapViewer) {\n        SwingWorker<String, String> worker = new SwingWorker<String, String>() {\n            protected String doInBackground() throws Exception {\n                return computeInfo(heapViewer);\n            }\n            protected void done() {\n                try {\n                    text.setText(get());\n                    text.setCaretPosition(0);\n                } catch (InterruptedException ex) {\n                    Exceptions.printStackTrace(ex);\n                } catch (ExecutionException ex) {\n                    Exceptions.printStackTrace(ex);\n                }\n            }\n        };\n        worker.execute();\n        try {\n            worker.get(UIThresholds.VIEW_LOAD, TimeUnit.MILLISECONDS);\n        } catch (InterruptedException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (ExecutionException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (TimeoutException ex) {\n            text.setText(SUMMARY_SECTION_PREFIX + \"<div style='margin-left: 10px;'>\" + Bundle.HeapDumpInfoAction_ComputingInfo() + \"</div>\"); // NOI18N\n            text.setCaretPosition(0);\n        }\n    }\n    \n    private static final String SUMMARY_SECTION_PREFIX = \"<b><img border='0' align='bottom' src='nbresloc:/\" + // NO18N\n                                                         Icons.getResource(GeneralIcons.INFO) +\n                                                         \"'>&nbsp;&nbsp;\" + Bundle.HeapDumpInfoAction_SummaryString() + // NO18N\n                                                         \"</b><br><hr>\"; // NO18N\n    \n    private static String computeInfo(HeapViewer heapViewer) {\n        File file = heapViewer.getFile();\n        HeapSummary hsummary = heapViewer.getFragments().get(0).getHeap().getSummary();\n        NumberFormat numberFormat = (NumberFormat)NumberFormat.getInstance().clone();\n        numberFormat.setMaximumFractionDigits(1);\n        \n        String filename = Bundle.HeapDumpInfoAction_FileItemString(\n                    file != null && file.exists() ? file.getAbsolutePath() : Bundle.HeapDumpInfoAction_NotAvailableMsg());\n        \n        String filesize = Bundle.HeapDumpInfoAction_FileSizeItemString(\n                    file != null && file.exists() ? numberFormat.format(file.length()/(1024 * 1024.0)) + \" MB\" : // NOI18N\n                        Bundle.HeapDumpInfoAction_NotAvailableMsg());\n        \n        String dateTaken = Bundle.HeapDumpInfoAction_DateTakenItemString(new Date(hsummary.getTime()).toString());\n        \n        return SUMMARY_SECTION_PREFIX + \"<div style='margin-left: 10px;'>\" + dateTaken + \"<br>\" + filename + \"<br>\" + filesize + \"</div>\"; // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/HeapView.java",
    "content": "/*\n * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class HeapView {\n    \n    public static final String PROP_KEY = \"HeapView\"; // NOI18N\n    \n    \n    private final String name;\n    private final String description;\n    private final Icon icon;\n\n\n    public HeapView(String name, String description) {\n        this(name, description, null);\n    }\n\n    public HeapView(String name, String description, Icon icon) {\n        this.name = name;\n        this.description = description;\n        this.icon = icon;\n    }\n\n\n    public String getName() { return name; }\n\n    public String getDescription() { return description; }\n\n    public Icon getIcon() { return icon; }\n    \n    \n    public abstract JComponent getComponent();\n    \n    public abstract ProfilerToolbar getToolbar();\n    \n    \n    protected void showing() {}\n    \n    protected void hidden() {}\n    \n    protected void willBeClosed(Runnable viewSelector) {}\n    \n    protected void closed() {}\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/HeapViewPlugin.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class HeapViewPlugin extends HeapView {\n    \n    private boolean showing;\n    \n    private HeapViewerNode currentNode;\n    private boolean currentAdjusting;\n    \n    private JComponent component;\n    \n    \n    public HeapViewPlugin(String name, String description, Icon icon) {\n        super(name, description, icon);\n    }\n    \n    \n    protected boolean acceptsAdjustingSelection() { return false; }\n    \n    \n    protected abstract JComponent createComponent();\n    \n    protected void nodeSelected(HeapViewerNode node, boolean adjusting) {}\n    \n    \n    public final JComponent getComponent() {\n        if (component == null) {\n            component = new JPanel(new BorderLayout());\n            component.setOpaque(false);\n            component.add(createComponent());\n            \n            component.addHierarchyListener(new HierarchyListener() {\n                public void hierarchyChanged(HierarchyEvent e) {\n                    if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                        showing = component.isShowing();\n                        if (showing) doNodeSelectedImpl(currentNode, currentAdjusting);\n                    }\n                }\n            });\n        }\n        return component;\n    }\n    \n    public final ProfilerToolbar getToolbar() {\n        // TODO: eventually can be enabled to provide actions for title pane\n        return null;\n    }\n        \n    \n    void doNodeSelected(HeapViewerNode node, boolean adjusting) {\n        currentNode = node;\n        currentAdjusting = adjusting;\n        if (showing) doNodeSelectedImpl(currentNode, currentAdjusting);\n    }\n    \n    private void doNodeSelectedImpl(HeapViewerNode node, boolean adjusting) {\n        if (!adjusting || acceptsAdjustingSelection()) nodeSelected(node, adjusting);\n    }\n    \n    \n    public static abstract class Provider {\n        \n        public abstract HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID);\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/HeapViewerActions.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class HeapViewerActions {\n    \n    HeapViewerActions() {}\n    \n    \n    public abstract HeapViewerFeature findFeature(String id);\n    \n    public abstract <T extends HeapViewerFeature> T findFeature(Class<T> featureClass);\n    \n    public abstract void selectFeature(HeapViewerFeature feature);\n    \n    \n    public abstract void selectView(HeapView view);\n    \n    public abstract void addView(HeapView view, boolean select);\n   \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/HeapViewerComponent.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport java.io.File;\nimport java.util.Collection;\nimport java.util.Set;\nimport java.util.TreeSet;\nimport javax.swing.ButtonGroup;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JTextArea;\nimport javax.swing.MenuElement;\nimport javax.swing.MenuSelectionManager;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.HeapViewer;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerPopupMenu;\nimport org.graalvm.visualvm.lib.ui.swing.StayOpenPopupMenu;\nimport org.graalvm.visualvm.uisupport.ProfilerTabbedView;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"HeapViewerComponent_LoadingProgress=Opening heap dump...\",\n    \"HeapViewerComponent_Scope=Scope:\",\n    \"HeapViewerComponent_View=View:\"\n})\npublic final class HeapViewerComponent extends JPanel {\n    \n    private final HeapViewer heapViewer;\n    private HeapContext[] contexts;\n    \n    private HeapViewerFeature[][] features;\n    \n    \n    public HeapViewerComponent(HeapViewer heapViewer) {\n        super(new BorderLayout());\n        setOpaque(false);\n        \n        this.heapViewer = heapViewer;\n        \n        add(new JLabel(Bundle.HeapViewerComponent_LoadingProgress(), JLabel.CENTER), BorderLayout.CENTER);\n        \n        File file = heapViewer.getFile();\n        String name = file == null ? \"<no heap dump file>\" : file.getName(); // NOI18N\n        // NOI18N\n        new RequestProcessor(\"HPROF initializer for \" + name).post(this::initImpl);\n    }\n    \n    public Dimension getMinimumSize() {\n        return new Dimension(0, 0);\n    }\n    \n    private void initImpl() {\n        contexts = HeapContext.allContexts(heapViewer);\n        \n        HeapViewerActions actions = new HeapViewerActions() {\n            public HeapViewerFeature findFeature(String id) {\n                for (HeapViewerFeature[] featureArr : features)\n                    for (HeapViewerFeature feature : featureArr)\n                        if (feature.getID().equals(id)) return feature;\n                return null;\n            }\n            public <T extends HeapViewerFeature> T findFeature(Class<T> featureClass) {\n                for (HeapViewerFeature[] featureArr : features)\n                    for (HeapViewerFeature feature : featureArr)\n                        if (feature.getClass() == featureClass) return (T)feature;\n                return null;\n            }\n            public void selectFeature(HeapViewerFeature feature) {\n                HeapViewerComponent.this.selectView(mainView);\n                mainView.selectFeature(contexts[feature.getScope()], feature);\n            }\n            public void selectView(HeapView view) {\n                HeapViewerComponent.this.selectView(view);\n            }\n            public void addView(HeapView view, boolean select) {\n                HeapViewerComponent.this.addView(view, select, true);\n            }\n        };\n        \n        Collection<? extends HeapViewerFeature.Provider> providers = Lookup.getDefault().lookupAll(HeapViewerFeature.Provider.class);\n        \n        features = new HeapViewerFeature[contexts.length][];\n        \n        for (int i = 0; i < contexts.length; i++) {\n            Set<HeapViewerFeature> featuresS = new TreeSet<>((HeapViewerFeature f1, HeapViewerFeature f2) -> Integer.compare(f1.getPosition(), f2.getPosition()));\n            for (HeapViewerFeature.Provider provider : providers) {\n                HeapViewerFeature feature = provider.getFeature(contexts[i], actions);\n                if (feature != null) {\n                    feature.setScope(i);\n                    featuresS.add(feature);\n                }\n            }\n            features[i] = featuresS.toArray(new HeapViewerFeature[0]);\n        }\n        \n        SwingUtilities.invokeLater(this::initComponents);\n    }\n\n    \n//    protected Component defaultFocusOwner() {\n//        return currentView == null ? this : currentView.getComponent();\n//    }\n\n    // --- UI definition ---------------------------------------------------------\n    \n    private ProfilerTabbedView views;\n    \n    private ProfilerToolbar toolbar;\n    private ProfilerToolbar viewToolbar;\n    \n    private HeapView currentView;\n    private ProfilerToolbar currentViewToolbar;\n    \n    private MainView mainView;\n    \n    private void initComponents() {\n        removeAll();\n        \n        toolbar = ProfilerToolbar.create(true);\n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        \n        // Reserve space for views toolbars\n        viewToolbar = ProfilerToolbar.create(false);\n        toolbar.add(viewToolbar);\n        \n        // Add the info action at the end of the toolbar\n        toolbar.addFiller();\n        toolbar.add(new HeapDumpInfoAction(heapViewer));\n        \n        \n        // Create tabbed view and update the toolbar based on current view\n        views = ProfilerTabbedView.createBottom(true, true, new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                final JComponent newComponent = views.getSelectedView();\n                if (newComponent != null) viewSelected(getView(newComponent));\n            }\n        });\n        views.addViewListener(new ProfilerTabbedView.Listener() {\n            public void viewRemoved(JComponent view) {\n                HeapViewerComponent.this.viewClosed(getView(view));\n            }\n        });\n        add(views.getComponent(), BorderLayout.CENTER);\n        views.setFocusMaster(this);\n        \n        // Create the main view\n        mainView = new MainView();\n        addView(mainView, false, false);\n    }\n    \n    \n    private void selectView(HeapView view) {\n        // TODO: not selecting features in mainView!\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                views.selectView(view.getComponent());\n            }\n        });\n    }\n    \n    \n    private void addView(final HeapView view, final boolean select, final boolean closable) {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                JComponent component = view.getComponent();\n                \n                if (views.containsView(component)) {\n                    if (select) views.selectView(component);\n                    else views.highlightView(component);\n                } else {\n                    component.putClientProperty(HeapView.PROP_KEY, view);\n                    views.addView(view.getName(), view.getIcon(), view.getDescription(), component, closable);\n                    if (select) views.selectView(component);\n\n                    invalidate();\n                    revalidate();\n                    doLayout();\n                    repaint();\n                }\n            }\n        });\n    }\n    \n    private static HeapView getView(JComponent component) {\n        return (HeapView)component.getClientProperty(HeapView.PROP_KEY);\n    }\n    \n    private void viewSelected(HeapView newView) {\n        if (currentView == newView) return;\n        \n        if (currentViewToolbar != null) viewToolbar.remove(currentViewToolbar);\n        if (currentView != null) currentView.hidden();\n        \n        currentView = newView;\n        currentView.showing();\n        \n        currentViewToolbar = currentView.getToolbar();\n        if (currentViewToolbar != null) viewToolbar.add(currentViewToolbar);\n    }\n    \n    private void viewClosed(HeapView view) {\n        view.closed();\n    }\n    \n    private void updateViewTab(HeapView view) {\n        if (views.getViewsCount() > 0) views.updateView(view.getComponent(), view.getName(), view.getIcon(), view.getDescription());\n    }\n    \n    \n    public void willBeClosed() {\n        if (mainView != null) mainView.willBeClosed(null);\n    }\n    \n    public void closed() {\n        if (views != null) views.removeAllViews();\n    }\n    \n    \n    private class MainView extends HeapView {\n        \n        private PopupButton featureChooser;\n        \n        private ProfilerToolbar toolbar;\n        private JComponent component;\n        \n        private HeapContext selectedContext;\n        private HeapViewerFeature selectedFeature;\n        \n        MainView() {\n            super(null, null);\n            \n            int i = 0;\n            while (selectedFeature == null && i < features.length) {\n                int j = 0;\n                while (selectedFeature == null && j < features[i].length) {\n                    if (features[i][j].isDefault()) {\n                        selectedContext = contexts[i];\n                        selectedFeature = features[i][j];\n                    }\n                    j++;\n                }\n                i++;\n            }\n            if (selectedFeature == null) {\n                selectedContext = contexts[0];\n                selectedFeature = features[0][0];\n            }\n        }\n\n        public JComponent getComponent() {\n            if (component == null) initUI();\n            return component;\n        }\n\n        public ProfilerToolbar getToolbar() {\n            if (toolbar == null) initUI();\n            return toolbar;\n        }\n        \n        \n        public String getName() {\n            return selectedFeature.getName();\n        }\n\n        public String getDescription() {\n            return contexts.length == 1 ? selectedFeature.getName() :\n                   (selectedContext.getFragment().getName() + \": \" + // NOI18N\n                   selectedFeature.getName());\n        }\n\n        public Icon getIcon() {\n            return selectedFeature.getIcon();\n        }\n        \n        \n        protected void showing() {\n            selectedFeature.showing();\n        }\n    \n        protected void hidden() {\n            selectedFeature.hidden();\n        }\n        \n        \n        @Override\n        protected void willBeClosed(Runnable viewSelector) {\n            for (int i = 0; i < features.length; i++) {\n                final HeapContext context = contexts[i];\n                HeapViewerFeature[] featureArr = features[i];\n                for (final HeapViewerFeature feature : featureArr) {\n                    Runnable _viewSelector = new Runnable() {\n                        public void run() { selectFeature(context, feature); }\n                    };\n                    feature.willBeClosed(_viewSelector);\n                }\n            }\n        }\n        \n        @Override\n        protected void closed() {\n            for (HeapViewerFeature[] featureArr : features)\n                    for (HeapViewerFeature feature : featureArr)\n                        feature.closed();\n        }\n        \n        \n        void selectFeature(HeapContext context, HeapViewerFeature feature) {\n            if (selectedFeature != null) selectedFeature.hidden();\n            \n            selectedContext = context;\n            selectedFeature = feature;\n            \n            selectedFeature.showing();\n\n            featureChooser.setText(getName());\n            featureChooser.setToolTipText(getDescription());\n            featureChooser.setIcon(getIcon());\n\n            featureChooser.invalidate();\n            Container parent = featureChooser.getParent();\n            if (parent != null) {\n                parent.revalidate();\n                parent.repaint();\n            }\n    \n            component.removeAll();\n            component.add(feature.getComponent(), BorderLayout.CENTER);\n            component.invalidate();\n            parent = component.getParent();\n            if (parent != null) {\n                parent.revalidate();\n                parent.repaint();\n            }\n    \n            while (toolbar.getComponentCount() > 1) toolbar.remove(1);\n            ProfilerToolbar featureToolbar = feature.getToolbar();\n            if (featureToolbar != null) toolbar.add(featureToolbar);\n\n//            viewSelected(this);\n            \n            updateViewTab(this);\n        }\n        \n        \n//        private void updateFocus(final JComponent invoker) {\n//            SwingUtilities.invokeLater(new Runnable() {\n//                public void run() {\n//                    Component focused = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();\n//\n//                    // Do not change focus for these special cases:\n//                    if (focused != null) {\n//    //                    if (profilePopupVisible) return; // focus in the Profile popup\n//                        if (ProfilerPopup.isInPopup(focused)) return; // focus in a profiler popup\n//                        if (HeapViewerComponent.this.isAncestorOf(focused)) return; // focus inside the ProfilerWindow\n//                    }\n//\n//                    SwingUtilities.invokeLater(new Runnable() {\n//                        public void run() { invoker.requestFocusInWindow(); }\n//                    });\n//                }\n//            });\n//        }\n        \n        private void displayPopupImpl(final JComponent invoker) {\n            final ProfilerPopupMenu popup = new StayOpenPopupMenu() {\n//                public void setVisible(boolean visible) {\n//                    super.setVisible(visible);\n//                    if (!visible) updateFocus(invoker);\n//                }\n            };\n            popup.setLayout(new GridBagLayout());\n            if (!UIUtils.isAquaLookAndFeel()) {\n                popup.setForceBackground(true);\n                Color background = UIUtils.getProfilerResultsBackground();\n                popup.setBackground(new Color(background.getRGB())); // JPopupMenu doesn't seem to follow ColorUIResource\n                Color foreground = new JLabel().getForeground();\n                if (foreground == null) foreground = new JTextArea().getForeground();\n                if (foreground == null) foreground = UIUtils.isDarkResultsBackground() ? Color.WHITE : Color.BLACK;\n                popup.setForeground(new Color(foreground.getRGB())); // JPopupMenu doesn't seem to follow ColorUIResource\n            }\n\n            boolean scopes = contexts.length > 1;\n            final boolean[] skipChange = new boolean[1];\n\n            int topl = 8;\n            int labl = 8;\n            final int left = scopes ? 12 : 4;\n            int y = 0;\n            GridBagConstraints c;\n\n            class ViewsUpdater {\n                int viewsIdx = Integer.MAX_VALUE;\n                MenuElement preselect = null;\n                void updateViews(final HeapContext context, HeapViewerFeature[] features) {\n                    int count = popup.getComponentCount();\n                    for (int i = viewsIdx; i < count; i++) popup.remove(viewsIdx);\n\n                    GridBagConstraints c;\n                    int y = viewsIdx;\n\n                    for (final HeapViewerFeature feature : features) {\n                        c = new GridBagConstraints();\n                        c.gridx = 0;\n                        c.gridy = y++;\n                        c.insets = new Insets(contexts.length == 1 && y == 1 ? 4 : 0, left, 0, 5);\n                        c.fill = GridBagConstraints.HORIZONTAL;\n                        JMenuItem mi = new JMenuItem(feature.getName(), feature.getIcon()) {\n                            protected void fireActionPerformed(ActionEvent e) {\n                                selectFeature(context, feature);\n                            }\n                        };\n                        if (selectedFeature == feature) preselect = mi;\n                        popup.add(mi, c);\n                    }\n\n                    JPanel footer = new JPanel(null);\n                    footer.setOpaque(false);\n                    c = new GridBagConstraints();\n                    c.gridx = 0;\n                    c.gridy = y++;\n                    c.weightx = 1;\n                    c.weighty = 1;\n                    c.insets = new Insets(3, 0, 0, 0);\n                    c.anchor = GridBagConstraints.NORTHWEST;\n                    c.fill = GridBagConstraints.BOTH;\n                    popup.add(footer, c);\n\n                    popup.pack();\n                }\n            }\n            final ViewsUpdater updater = new ViewsUpdater();\n\n            if (scopes) {\n                JLabel scopeL = new JLabel(Bundle.HeapViewerComponent_Scope(), JLabel.LEADING);\n                scopeL.setFont(popup.getFont().deriveFont(Font.BOLD));\n                c = new GridBagConstraints();\n                c.gridx = 0;\n                c.gridy = y++;\n                c.insets = new Insets(5, labl, 5, 5);\n                c.fill = GridBagConstraints.HORIZONTAL;\n                popup.add(scopeL, c);    \n                \n                // Prevent leaking-alike behavior of structures referenced by StayOpenPopupMenu.RadioButtonItem instances\n                MultiResolutionImageHack.hackIcon(\"RadioButtonMenuItem.checkIcon\"); // NOI18N\n\n                JMenuItem toSelect = null;\n                final ButtonGroup bg = new ButtonGroup();\n                for (int i = 0; i < contexts.length; i++) {\n                    c = new GridBagConstraints();\n                    c.gridx = 0;\n                    c.gridy = y++;\n                    c.insets = new Insets(0, left, 0, 5);\n                    c.fill = GridBagConstraints.HORIZONTAL;\n                    final int ii = i;\n                    JMenuItem mi = new StayOpenPopupMenu.RadioButtonItem(contexts[i].getFragment().getName()) {\n                        protected void fireItemStateChanged(ItemEvent event) {\n                            if (isSelected()) {\n                                updater.updateViews(contexts[ii], features[ii]);\n                                if (!skipChange[0]) selectFeature(contexts[ii], features[ii][0]);\n                                else skipChange[0] = false;\n                            }\n                        }\n                    };\n                    if (selectedContext == contexts[ii]) toSelect = mi;\n                    bg.add(mi);\n                    popup.add(mi, c);\n                }\n\n                JLabel viewL = new JLabel(Bundle.HeapViewerComponent_View(), JLabel.LEADING);\n                viewL.setFont(popup.getFont().deriveFont(Font.BOLD));\n                c = new GridBagConstraints();\n                c.gridx = 0;\n                c.gridy = y++;\n                c.insets = new Insets(topl, labl, 5, 5);\n                c.fill = GridBagConstraints.HORIZONTAL;\n                popup.add(viewL, c);\n\n                updater.viewsIdx = y;\n\n                if (toSelect != null) {\n                    skipChange[0] = true;\n                    toSelect.setSelected(true);\n                }\n            } else {\n                updater.viewsIdx = 0;\n                updater.updateViews(contexts[0], features[0]);\n            }\n\n            popup.show(invoker, 0, invoker.getHeight());\n\n            if (updater.preselect != null) MenuSelectionManager.defaultManager().setSelectedPath(\n                                           new MenuElement[] { popup, updater.preselect });\n\n        }\n        \n        \n        private void initUI() {\n            toolbar = ProfilerToolbar.create(false);\n            \n            featureChooser = new PopupButton() {\n                protected void displayPopup() { displayPopupImpl(featureChooser); }\n                public int getIconTextGap() { return 5; }\n    //            public Dimension getPreferredSize() { Dimension dim = super.getPreferredSize(); dim.width += 10; return dim; }\n            };\n            toolbar.add(featureChooser);\n            \n            component = new JPanel(new BorderLayout()) {\n                public boolean requestFocusInWindow() {\n                    if (getComponentCount() == 0) return super.requestFocusInWindow();\n                    else return getComponent(0).requestFocusInWindow();\n                }\n            };\n            component.setOpaque(false);\n            \n            selectFeature(selectedContext, selectedFeature);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/HeapViewerFeature.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class HeapViewerFeature extends HeapView {\n   \n    private final String id;\n    private final int position;\n    \n    private int scope;\n        \n    \n    public HeapViewerFeature(String id, String name, String description, Icon icon, int position) {\n        super(name, description, icon);\n        this.id = id;\n        this.position = position;\n    }\n\n    \n    public String getID() {\n        return id;\n    }\n    \n    public int getPosition() {\n        return position;\n    }\n    \n    public boolean isDefault() {\n        return false;\n    }\n    \n    \n    void setScope(int scope) {\n        this.scope = scope;\n    }\n    \n    int getScope() {\n        return scope;\n    }\n    \n    \n    public static abstract class Provider {\n    \n        public abstract HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions);\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/HeapViewerNodeAction.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.awt.Font;\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\nimport javax.swing.AbstractAction;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPopupMenu;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class HeapViewerNodeAction extends AbstractAction {\n    \n    private final int position;\n    \n    public HeapViewerNodeAction(String name, int position) {\n        putValue(NAME, name);\n        this.position = position;\n    }\n    \n    public int getPosition() {\n        return position;\n    }\n    \n    public boolean isDefault() {\n        return false;\n    }\n    \n    public boolean isMiddleButtonDefault(ActionEvent e) {\n        return false;\n    }\n    \n    \n    public static abstract class Provider {\n        \n        public abstract boolean supportsView(HeapContext context, String viewID);\n\n        public abstract HeapViewerNodeAction[] getActions(HeapViewerNode node, HeapContext context, HeapViewerActions actions);\n        \n    }\n    \n    \n    public static final class Actions {\n        \n        private final List<HeapViewerNodeAction> actions;\n        \n        private Actions(List<HeapViewerNodeAction> actions) {\n            this.actions = actions;\n        }\n        \n        public static Actions forNode(HeapViewerNode node, Collection<HeapViewerNodeAction.Provider> actionProviders,\n                               HeapContext context, HeapViewerActions actions, HeapViewerNodeAction... additionalActions) {\n            HeapViewerNode loop = HeapViewerNode.getValue(node, DataType.LOOP, context.getFragment().getHeap());\n            if (loop != null) node = loop;\n            \n            List<HeapViewerNodeAction> actionsList = new ArrayList<>();\n            for (HeapViewerNodeAction.Provider provider : actionProviders) {\n                HeapViewerNodeAction[] providerActions = provider.getActions(node, context, actions);\n                if (providerActions != null) Collections.addAll(actionsList, providerActions);\n            }\n            if (additionalActions != null) Collections.addAll(actionsList, additionalActions);\n            actionsList.sort((HeapViewerNodeAction a1, HeapViewerNodeAction a2) -> Integer.compare(a1.getPosition(), a2.getPosition()));\n            return new Actions(actionsList);\n        }\n        \n        \n        public void performDefaultAction(ActionEvent e) {\n            for (HeapViewerNodeAction action : actions) {\n                if (action.isDefault()) {\n                    if (action.isEnabled()) action.actionPerformed(e);\n                    return; // return for the first default action\n                }\n            }\n        }\n        \n        public void performMiddleButtonAction(ActionEvent e) {\n            for (HeapViewerNodeAction action : actions) {\n                if (action.isMiddleButtonDefault(e)) {\n                    if (action.isEnabled()) {\n                        action.actionPerformed(e);\n                        return; // return for the first enabled middleButton action\n                    }\n                }\n            }\n        }\n        \n        public void populatePopup(JPopupMenu popup) {\n            int lastPosition = -1;\n            for (HeapViewerNodeAction action : actions) {\n                int position = action.getPosition() / 100;\n                if (position > lastPosition && lastPosition != -1) popup.addSeparator();\n                JMenuItem mi = new JMenuItem(action);\n                if (action.isDefault()) mi.setFont(mi.getFont().deriveFont(Font.BOLD));\n                popup.add(mi);\n                lastPosition = position;\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/HeapViewerNumberRenderer.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.text.Format;\nimport java.util.Objects;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class HeapViewerNumberRenderer extends NumberPercentRenderer {\n    \n    private final DataType dataType;\n    \n    \n    public static HeapViewerNumberRenderer decimalInstance(DataType dataType) {\n        return new HeapViewerNumberRenderer(null, dataType);\n    }\n    \n    public static HeapViewerNumberRenderer bytesInstance(DataType dataType) {\n        return new HeapViewerNumberRenderer(Formatters.bytesFormat(), dataType);\n    }\n    \n    \n    private HeapViewerNumberRenderer(Format format, DataType dataType) {\n        super(createNumberRenderer(format, dataType));\n        this.dataType = dataType;\n    }\n    \n    \n    public void setValue(Object value, int row) {\n        super.setValue(value, row);\n        \n        boolean showsPercents = !isDiffMode() &&\n                                !(Objects.equals(value, dataType.getNoValue())) &&\n                                !(Objects.equals(value, dataType.getUnsupportedValue())) &&\n                                !(Objects.equals(value, dataType.getNotAvailableValue()));\n        valueRenderers()[1].getComponent().setVisible(showsPercents);\n    }\n    \n    \n    private static ProfilerRenderer createNumberRenderer(Format customFormat, final DataType dataType) {\n        NumberRenderer numberRenderer = new NumberRenderer(customFormat) {\n            protected String getValueString(Object value, int row, Format format) {\n                if (Objects.equals(value, dataType.getNoValue())) return \"-\"; // NOI18N\n                if (Objects.equals(value, dataType.getUnsupportedValue())) return \"\"; // NOI18N\n                if (Objects.equals(value, dataType.getNotAvailableValue())) return \"n/a\"; // NOI18N\n                return super.getValueString(value, row, format);\n            }\n        };\n        numberRenderer.setMargin(3, 3, 3, 3);\n        return numberRenderer;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/HeapViewerRenderer.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.util.Map;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface HeapViewerRenderer extends ProfilerRenderer {\n    \n    default Icon getIcon() {\n        return null;\n    }\n    \n    default String getShortName() {\n        return toString();\n    }\n    \n    \n    public static abstract class Provider {\n        \n        public abstract boolean supportsView(HeapContext context, String viewID);\n    \n        public abstract void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers, HeapContext context);\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/HeapViewerRendererWrapper.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport javax.accessibility.AccessibleContext;\nimport javax.swing.JComponent;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class HeapViewerRendererWrapper implements HeapViewerRenderer {\n        \n    private HeapViewerRenderer renderer;\n\n    @Override\n    public void setValue(Object value, int row) {\n        renderer = getRenderer(value, row);\n    }\n\n    @Override\n    public int getHorizontalAlignment() {\n        return renderer.getHorizontalAlignment();\n    }\n\n    @Override\n    public JComponent getComponent() {\n        return renderer.getComponent();\n    }\n\n    @Override\n    public void move(int x, int y) {\n        renderer.move(x, y);\n    }\n    \n    @Override\n    public String toString() {\n        return renderer.toString();\n    }\n    \n    @Override\n    public String getShortName() {\n        return renderer.getShortName();\n    }\n\n    @Override\n    public AccessibleContext getAccessibleContext() {\n        return renderer.getAccessibleContext();\n    }\n\n\n    protected abstract HeapViewerRenderer getRenderer(Object value, int row);\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/HeapViewerTreeTable.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.RowSorter;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.tree.TreeNode;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass HeapViewerTreeTable extends ProfilerTreeTable {   \n    \n    private volatile boolean initializing = true;\n    \n    private boolean sorting;\n    \n    \n    HeapViewerTreeTable(ProfilerTreeTableModel model, List<? extends RowSorter.SortKey> sortKeys) {\n        super(model, true, true, new int[] { 0 });\n        \n        setRootVisible(false);\n        setShowsRootHandles(true);\n        \n        setShadeUnfocusedSelection(true);\n        \n        setForgetPreviouslyExpanded(true);\n        \n        setAllowsThreeStateColumns(true);\n        getRowSorter().setSortKeys(sortKeys);\n        \n        getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n            private HeapViewerNode currentSelected;\n            private boolean currentAdjusting;\n            private boolean adjustingNull;\n            public void valueChanged(ListSelectionEvent e) {\n//                System.err.println(\">>> selected \" + getSelectedNode() + \" adjusting \" + e.getValueIsAdjusting());\n                \n                // Ignore changes during sorting, will be handled separately in willBeSorted()\n                if (sorting) return;\n                \n                HeapViewerNode node = getSelectedNode();\n                boolean adjusting = e.getValueIsAdjusting();\n                \n                // workaround for noise created by restoring selection on internal model updates\n                // leading nulls which are adjusting mean that following non-adjusting null should be skipped\n                if (node == null) {\n                    if (adjusting) {\n                        adjustingNull = true;\n                        return;\n                    } else if (adjustingNull) {\n                        adjustingNull = false;\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                // No node selected after leading adjusting nulls, selection not restored\n                                if (getSelectedNode() == null) nodeSelected(null, false);\n                            }\n                        });\n                        return;\n                    }\n                } else {\n                    adjustingNull = false;\n                }\n                \n                // workaround for noise created by restoring selection on internal model updates\n                // ignore the same selection which is a result of clearing noise nulls\n                if (Objects.equals(currentSelected, node) && currentAdjusting == adjusting) return;\n                \n                currentSelected = node;\n                currentAdjusting = adjusting;\n                \n                nodeSelected(node, adjusting);\n            }\n        });\n        \n        initializing = false;\n    }\n    \n    \n    protected final boolean isInitializing() { return initializing; }\n    \n    \n    protected void nodeSelected(HeapViewerNode node, boolean adjusting) {}\n    \n    protected void forgetChildren(HeapViewerNode node) {}\n    \n    \n    protected void nodeCollapsed(final TreeNode node) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { forgetChildren((HeapViewerNode)node); }\n        });\n    }\n    \n    \n    protected void willBeSorted(List<? extends RowSorter.SortKey> sortKeys) {\n        sorting = true;\n        final HeapViewerNode beforeSortingSelected = getSelectedNode();\n        \n        final UIState uiState = getUIState();\n        \n        try {\n        \n            Enumeration<TreePath> expanded = getExpandedNodes();\n            clearSelection();\n//            resetExpandedNodes();\n            if (expanded != null) while (expanded.hasMoreElements()) {\n                HeapViewerNode node = (HeapViewerNode)expanded.nextElement().getLastPathComponent();\n//                System.err.println(\">>> willBeSorted - \" + node.toString());\n                node.willBeSorted();\n            }\n\n        } catch (Throwable t) {\n            Exceptions.printStackTrace(t);\n        }\n        \n//        if (getTreeModel() != null) getTreeModel().reload();\n//        \n//        resetExpandedNodes();\n        \n        resetPath(null);\n\n        if (uiState != null) {\n            restoreSelectedNodes(uiState);\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n//                        resetPath(null);\n//                        resetExpandedNodes();\n                    restoreExpandedNodes(uiState);\n//                        restoreSelectedNodes(uiState);\n                    sorting = false;\n                    HeapViewerNode afterSortingSelected = getSelectedNode();\n                    if (!Objects.equals(beforeSortingSelected, afterSortingSelected))\n                        nodeSelected(afterSortingSelected, false);\n                }\n            });\n        } else {\n            sorting = false;\n            HeapViewerNode afterSortingSelected = getSelectedNode();\n            if (!Objects.equals(beforeSortingSelected, afterSortingSelected))\n                nodeSelected(afterSortingSelected, false);\n        }\n    }\n    \n    \n    private HeapViewerNode getSelectedNode() {\n        int row = getSelectedRow();\n        return row == -1 ? null : (HeapViewerNode)getValueForRow(row);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/MultiResolutionImageHack.java",
    "content": "/*\n * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.awt.Image;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JPanel;\nimport javax.swing.UIManager;\nimport javax.swing.plaf.IconUIResource;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\n\n/**\n * Components painting multi-resolution icons without image observers are stored in sun.awt.image.MultiResolutionToolkitImage.ObserverCache.\n * This cache uses SoftReferences transitively holding structures referenced by the components for an unnecessary amount of time,\n * causing slow downs due to heavy GC activity.\n * \n * Causes a memleak-alike behavior by referencing StayOpenPopupMenu.RadioButtonItem instances and transitively HprofHeap instances.\n *\n * @author Jiri Sedlacek\n */\nclass MultiResolutionImageHack {\n    \n    // NOTE: to be invoked for a global hack\n//    static void hack() {\n//        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n//            public void run() {\n//                SwingUtilities.invokeLater(new Runnable() {\n//                    public void run() {\n//                        hackIcon(\"RadioButtonMenuItem.checkIcon\"); // NOI18N\n//                    }\n//                });\n//            }\n//        });\n//    }\n    \n    static void hackIcon(String uiKey) {\n        ImageIcon checkIcon = getCheckIcon(uiKey);\n        if (checkIcon != null) hackIcon(checkIcon);\n    }\n    \n    private static ImageIcon getCheckIcon(String uiKey) {\n        Icon icon = UIManager.getIcon(uiKey);\n        if (!(icon instanceof ImageIcon)) return null; // Icon must be ImageIcon\n        \n        Image image = ((ImageIcon)icon).getImage();\n        if (image == null || !image.getClass().getName().contains(\"MultiResolution\")) return null; // NOI18N\n        \n        return (ImageIcon)icon;\n    }\n    \n    private static void hackIcon(ImageIcon icon) {\n        try {\n            // Create a dummy image observer\n            JPanel p = new JPanel();\n            \n            // Set the image observer to the multi-resolution image\n            icon.setImageObserver(p);\n            \n            // macOS specific\n            if (Platform.isMac()) {\n                Method getInvertedIcon = icon.getClass().getMethod(\"getInvertedIcon\"); // NOI18N\n                getInvertedIcon.setAccessible(true);\n                IconUIResource invertedIcon = (IconUIResource)getInvertedIcon.invoke(icon);\n                Field delegate = invertedIcon.getClass().getDeclaredField(\"delegate\"); // NOI18N\n                delegate.setAccessible(true);\n                ImageIcon imageIcon = (ImageIcon)delegate.get(invertedIcon);\n                // Set the image observer to the inverted multi-resolution image\n                imageIcon.setImageObserver(p);\n            }\n        } catch (Throwable t) {\n            Logger logger = Logger.getLogger(MultiResolutionImageHack.class.getName());\n            logger.log(Level.FINE, \"Failed to apply MultiResolutionToolkitImageCacheHack\", t); // NOI18N\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/NodeObjectsView.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.ActionEvent;\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"NodeObjectsView_Details=Details:\",\n    \"NodeObjectsView_NewTab=Open in New Tab\"\n})\npublic class NodeObjectsView extends HeapView {\n    \n    private final HeapViewerNode viewNode;\n    \n    private String name;\n    private String description;\n    private Icon icon;\n    \n    private final PluggableTreeTableView objectsView;\n    private ProfilerToolbar toolbar;\n    private JComponent component;\n    \n        \n    public NodeObjectsView(String viewID, HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n        super(null, null);\n        \n        viewNode = node;\n        \n        Heap heap = context.getFragment().getHeap();\n        \n        Integer count = HeapViewerNode.getValue(node, DataType.COUNT, heap);\n        boolean hasCount = !Objects.equals(count, DataType.COUNT.getUnsupportedValue());\n        TreeTableViewColumn[] columns = hasCount ? TreeTableViewColumn.classes(heap, true) :\n                                                   TreeTableViewColumn.instances(heap, true);\n        \n        objectsView = new PluggableTreeTableView(viewID, context, actions, columns) {\n            protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                return new HeapViewerNode[] { viewNode };\n            }\n            protected void childrenChanged() {\n                CCTNode[] children = getRoot().getChildren();\n                for (CCTNode child : children) expandNode((HeapViewerNode)child);\n            }\n        };\n    }\n    \n    \n    public String getName() {\n        if (toolbar == null) initUI();\n        return name;\n    }\n\n    public String getDescription() {\n        if (toolbar == null) initUI();\n        return description;\n    }\n\n    public Icon getIcon() {\n        if (toolbar == null) initUI();\n        return icon;\n    }\n    \n\n    public JComponent getComponent() {\n        if (toolbar == null) initUI();\n        return component;\n    }\n\n    public ProfilerToolbar getToolbar() {\n        if (toolbar == null) initUI();\n        return toolbar;\n    }\n    \n    \n    @Override\n    protected void closed() {\n        objectsView.closed();\n    }\n    \n    \n    private void initUI() {\n        HeapViewerRenderer renderer = objectsView.getNodeRenderer(viewNode);\n        name = renderer.getShortName();\n        description = renderer.toString();\n        icon = renderer.getIcon();\n        \n        toolbar = ProfilerToolbar.create(false);\n        \n        toolbar.addSpace(3);\n        JLabel nodePresenter = new JLabel(name, icon, JLabel.LEADING);\n        nodePresenter.setToolTipText(description);\n        toolbar.add(nodePresenter);\n        toolbar.addSpace(5);\n        \n        if (objectsView.hasPlugins()) {\n            toolbar.addSeparator();\n            toolbar.addSpace(5);\n\n            toolbar.add(new GrayLabel(Bundle.NodeObjectsView_Details()));\n            toolbar.addSpace(2);\n            \n            toolbar.add(objectsView.getToolbar());\n        }\n        \n        component = new ViewContainer(objectsView.getComponent(), viewNode);\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                objectsView.selectNode(viewNode);\n                objectsView.getComponent().requestFocusInWindow();\n            }\n        });\n    }\n    \n    \n    private static class ViewContainer extends JPanel {\n        \n        private final HeapViewerNode node;\n        \n        ViewContainer(JComponent view, HeapViewerNode viewNode) {\n            super(new BorderLayout());\n            node = viewNode;\n            setOpaque(false);\n            setFocusable(false);\n            add(view, BorderLayout.CENTER);\n        }\n        \n        public boolean requestFocusInWindow() {\n            if (getComponentCount() == 0) return super.requestFocusInWindow();\n            else return getComponent(0).requestFocusInWindow();\n        }\n        \n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof ViewContainer)) return false;\n            return node.equals(((ViewContainer)o).node);\n        }\n\n        public int hashCode() {\n            return node.hashCode();\n        }\n        \n    }\n    \n    \n    public static abstract class OpenAction extends HeapViewerNodeAction {\n        \n        private final HeapViewerNode node;\n        private final HeapContext context;\n        private final HeapViewerActions actions;\n        \n        public OpenAction(String name, int position, HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n            super(name, position);\n            this.node = node;\n            this.context = context;\n            this.actions = actions;\n            setEnabled(node != null);\n        }\n        \n        \n        public abstract NodeObjectsView createView(HeapViewerNode node, HeapContext context, HeapViewerActions actions);\n        \n        \n        public void actionPerformed(ActionEvent e) {\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    NodeObjectsView view = createView(node, context, actions);\n                    actions.addView(view, (e.getModifiers() & ActionEvent.SHIFT_MASK) == 0);\n                }\n            });\n        }\n        \n    }\n    \n    public static abstract class DefaultOpenAction extends OpenAction {\n        \n        public DefaultOpenAction(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n            super(Bundle.NodeObjectsView_NewTab(), 0, node, context, actions);\n        }\n        \n        public boolean isDefault() {\n            return true;\n        }\n        \n        public boolean isMiddleButtonDefault(ActionEvent e) {\n            return (e.getModifiers() & ActionEvent.CTRL_MASK) != ActionEvent.CTRL_MASK;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/PluggableTreeTableView.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.event.ItemEvent;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.UIManager;\nimport javax.swing.plaf.basic.BasicSplitPaneDivider;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.swing.MultiSplitContainer;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.CloseButton;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedSplitPane;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class PluggableTreeTableView extends TreeTableView {\n    \n    private static final Color SEPARATOR_COLOR = UIManager.getColor(\"Separator.foreground\"); // NOI18N\n    \n    private final List<HeapViewPlugin> plugins;\n//    private Collection<? extends HeapViewPlugin.Provider> pluginProviders;\n    \n    private ProfilerToolbar toolbar;\n    private JComponent pluginsComponent;\n    \n    \n    public PluggableTreeTableView(String viewID, HeapContext context, HeapViewerActions actions, TreeTableViewColumn... columns) {\n        this(viewID, context, actions, true, true, columns);\n    }\n    \n    public PluggableTreeTableView(String viewID, HeapContext context, HeapViewerActions actions, boolean useBreadCrumbs, boolean pluggableColumns, TreeTableViewColumn... columns) {\n        super(viewID, context, actions, useBreadCrumbs, pluggableColumns, columns);\n        \n        plugins = new ArrayList<>();\n        Collection<? extends HeapViewPlugin.Provider> pluginProviders = Lookup.getDefault().lookupAll(HeapViewPlugin.Provider.class);\n        for (HeapViewPlugin.Provider provider : pluginProviders) {\n            HeapViewPlugin plugin = provider.createPlugin(context, actions, viewID);\n            if (plugin != null) plugins.add(plugin);\n        }\n    }\n    \n    \n    public boolean hasPlugins() {\n        return !plugins.isEmpty();\n    }\n    \n    public ProfilerToolbar getToolbar() {\n        if (toolbar == null) init();\n        return toolbar;\n    }\n    \n    \n    protected void nodeSelected(HeapViewerNode node, boolean adjusting) {\n        super.nodeSelected(node, adjusting);\n        for (HeapViewPlugin plugin : plugins) plugin.doNodeSelected(node, adjusting);\n    }\n    \n    protected JComponent createComponent() {\n        final JComponent comp = super.createComponent();\n        \n        if (toolbar == null) init();\n        \n        JExtendedSplitPane contentSplit = new JExtendedSplitPane(JExtendedSplitPane.VERTICAL_SPLIT, true, comp, pluginsComponent) {\n            public boolean requestFocusInWindow() {\n                return comp.requestFocusInWindow();\n            }\n        };\n        BasicSplitPaneDivider contentDivider = ((BasicSplitPaneUI)contentSplit.getUI()).getDivider();\n        contentDivider.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, SEPARATOR_COLOR));\n        contentDivider.setDividerSize(5);\n        contentSplit.setBorder(BorderFactory.createEmptyBorder());\n        contentSplit.setResizeWeight(0.7d);\n        \n        return contentSplit;\n    }\n    \n    \n    public void closed() {\n        if (pluginsComponent != null && pluginsComponent.isVisible()) {\n            for (Component comp : pluginsComponent.getComponents())\n                if (comp.isVisible()) comp.setVisible(false); // PluginContainer.setVisible(false) calls plugin.closed()\n        }\n        super.closed();\n    }\n    \n    \n    private void init() {\n        toolbar = ProfilerToolbar.create(false);\n        \n        pluginsComponent = new MultiSplitContainer();\n        pluginsComponent.setPreferredSize(new Dimension(300, 300));\n        \n        int pcount = plugins.size();\n        for (int i = 0; i < pcount; i++) {\n            HeapViewPlugin plugin = plugins.get(i);\n            final PluginContainer[] container = new PluginContainer[1];\n            PluginPresenter presenter = new PluginPresenter(plugin) {\n                @Override\n                Container getPluginContainer() { return container[0]; }\n            };\n            presenter.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            if (i == 0) presenter.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n            else if (i == pcount - 1) presenter.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n            else presenter.putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n            container[0] = new PluginContainer(plugin, presenter);\n            toolbar.add(presenter);\n            pluginsComponent.add(container[0]);\n        }\n        \n        checkVisibility(pluginsComponent);\n    }\n    \n    private static void checkVisibility(JComponent comp) {\n        if (comp == null) return;\n\n        comp.invalidate();\n        comp.revalidate();\n        comp.doLayout();\n        comp.repaint();\n\n        for (Component c : comp.getComponents())\n            if (c.isVisible()) {\n                comp.setVisible(true);\n\n                return;\n            }\n\n        comp.setVisible(false);\n    }\n    \n    \n    private static abstract class PluginPresenter extends JToggleButton {\n        \n        PluginPresenter(HeapViewPlugin plugin) {\n            super(plugin.getName(), plugin.getIcon());\n            setToolTipText(plugin.getDescription());\n            putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n        }\n        \n        abstract Container getPluginContainer();\n        \n        protected void fireItemStateChanged(ItemEvent e) {\n            Container container = getPluginContainer();\n            container.setVisible(e.getStateChange() == ItemEvent.SELECTED);\n            checkVisibility((JComponent)container.getParent());\n        }\n        \n    }\n    \n    \n    private static class PluginContainer extends JPanel {\n        \n        private final HeapViewPlugin plugin;\n        \n        PluginContainer(HeapViewPlugin plugin, final PluginPresenter pluginPresenter) {\n            super(new BorderLayout());\n            \n            this.plugin = plugin;\n            \n            JButton closeButton = CloseButton.create(new Runnable() {\n                public void run() { pluginPresenter.setSelected(false); }\n            });\n            closeButton.setFocusable(true);\n            \n            JPanel detailHeader = new JPanel(null);\n            detailHeader.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, SEPARATOR_COLOR));\n            detailHeader.setLayout(new BoxLayout(detailHeader, BoxLayout.LINE_AXIS));\n            detailHeader.setBackground(UIUtils.getDarker(UIUtils.getProfilerResultsBackground()));\n            JLabel captionL = new JLabel(plugin.getName(), plugin.getIcon(), JLabel.LEADING);\n            captionL.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));\n            detailHeader.add(captionL);            \n            detailHeader.add(Box.createGlue());\n            detailHeader.add(closeButton);\n            \n            add(detailHeader, BorderLayout.NORTH);\n            setVisible(pluginPresenter.isSelected());\n        }\n        \n        public void setVisible(boolean visible) {\n            boolean firstTime = getComponentCount() < 2;\n            \n            if (visible && firstTime) add(plugin.getComponent(), BorderLayout.CENTER);\n            super.setVisible(visible);\n            \n            if (!visible && !firstTime) plugin.closed();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/SummaryView.java",
    "content": "/*\n * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.graalvm.visualvm.uisupport.VerticalLayout;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class SummaryView {\n    \n    private final String viewID;\n    \n    private final HeapContext context;\n    private final HeapViewerActions actions;\n    \n    private final Collection<HeapViewerNodeAction.Provider> actionProviders;\n    \n    private List<HeapView> content;\n    \n    private JComponent component;\n    private ProfilerToolbar toolbar;\n    \n    \n    public SummaryView(String viewID, HeapContext context, HeapViewerActions actions) {\n        this.viewID = viewID;\n        this.context = context;\n        this.actions = actions;\n        \n        actionProviders = new ArrayList<>();\n        for (HeapViewerNodeAction.Provider provider : Lookup.getDefault().lookupAll(HeapViewerNodeAction.Provider.class))\n            if (provider.supportsView(context, viewID)) actionProviders.add(provider);\n        \n        content = new ArrayList<>();\n        Collection<? extends ContentProvider> providers = Lookup.getDefault().lookupAll(ContentProvider.class);\n        for (ContentProvider provider : providers) {\n            HeapView summary = provider.createSummary(this.viewID, this.context, this.actions, this.actionProviders);\n            if (summary != null) content.add(summary);\n        }\n    }\n    \n    \n    public JComponent getComponent() {\n        if (component == null) initUI();\n        return component;\n    }\n    \n    public ProfilerToolbar getToolbar() {\n        if (toolbar == null) initUI();\n        return toolbar;\n    }\n    \n    \n    protected HeapView createDefaultSummary() { return null; }\n    \n    protected void uiCreated(List<HeapView> views) {}\n    \n    \n    private void initUI() {\n        toolbar = ProfilerToolbar.create(false);\n        \n        \n        JPanel p = new JPanel(new VerticalLayout(false, 6));\n        p.setOpaque(true);\n        p.setBackground(UIUtils.getProfilerResultsBackground());\n        \n        HeapView defaultContent = createDefaultSummary();\n        if (defaultContent != null) content.add(0, defaultContent);\n        \n        for (HeapView view : content) {\n            p.add(new ContentContainer(view));\n            ProfilerToolbar viewToolbar = view.getToolbar();\n            if (viewToolbar != null) toolbar.add(viewToolbar);\n        }\n        \n        uiCreated(new ArrayList<>(content));\n        \n        component = new ScrollableContainer(p);\n        \n        content.clear();\n        content = null;\n    }\n    \n    \n    public static class SimpleTable extends ProfilerTable {\n        \n        private static final int COLUMN_MARGIN = 5;\n        \n        public SimpleTable(TableModel tm, int fillerColumn) {\n            super(tm, false, false, null);\n            setShowHorizontalLines(false);\n            setShowVerticalLines(false);\n            setIntercellSpacing(new Dimension());\n            setRowSelectionAllowed(false);\n            setColumnSelectionAllowed(false);\n            setFitWidthColumn(fillerColumn);\n        }\n        \n        public void setColumnRenderer(int column, ProfilerRenderer renderer, boolean fixedWidth) {\n            super.setColumnRenderer(column, renderer);\n            \n            if (fixedWidth) {\n                int w = 0;\n                int rc = getRowCount();\n                for (int row = 0; row < rc; row++) {\n                    renderer.setValue(getValueAt(row, column), column);\n                    w = Math.max(w, renderer.getComponent().getPreferredSize().width);\n                }\n\n                setDefaultColumnWidth(column, w + COLUMN_MARGIN);\n            }\n        }\n        \n    }\n    \n    \n    private static class ContentContainer extends JPanel {\n        \n        ContentContainer(HeapView view) {\n            super(new BorderLayout());\n            setOpaque(false);\n            setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));\n            \n            /*JLabel captionL = new JLabel(view.getName(), JLabel.LEADING);\n//            captionL.setToolTipText(view.getDescription());\n            captionL.setOpaque(false);\n            captionL.setBorder(BorderFactory.createEmptyBorder(TABBUTTON_MARGIN_TOP, TABBUTTON_MARGIN_LEFT, TABBUTTON_MARGIN_BOTTOM, TABBUTTON_MARGIN_RIGHT));\n\n            caption = new JPanel(new BorderLayout());\n            caption.setOpaque(true);\n            caption.setBackground(BACKGROUND_COLOR_NORMAL);\n            caption.setBorder(BorderFactory.createMatteBorder(1, 1, 0, 1, BORDER_COLOR_NORMAL));\n            caption.add(captionL, BorderLayout.CENTER);\n            \n            add(caption, BorderLayout.NORTH);*/\n            \n            add(view.getComponent(), BorderLayout.CENTER);\n        }\n        \n    }\n    \n    \n    public static abstract class ContentProvider {\n        \n        public abstract HeapView createSummary(String viewID, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders);\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/TreeTableView.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.InputMap;\nimport javax.swing.JComponent;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JTree;\nimport javax.swing.RowSorter;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.TableColumn;\nimport javax.swing.tree.TreeNode;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.NodesCache;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TreeTableView_FilteredFlag={0} (filtered)\",\n    \"TreeTableView_Filter=Filter\",\n    \"TreeTableView_Pin=Pin\",\n    \"TreeTableView_ResetPin=Reset Pin\",\n    \"TreeTableView_SortToGet=sort to get\"\n})\npublic class TreeTableView {\n    \n    private final String viewID;\n    \n    private final HeapContext context;\n    private final HeapViewerActions actions;\n    \n    private final List<TreeTableViewColumn> columns;\n    private final RootNode root;\n    private HeapViewerNode currentRoot;\n    \n    private Model model;\n    private NodesCache nodesCache;\n    private HeapViewerTreeTable treeTable;\n    \n    private List<DataType> dataTypes;\n    private List<SortOrder> sortOrders;\n    \n    private Collection<HeapViewerRenderer.Provider> rendererProviders;\n    private TreeTableViewRenderer nodesRenderer;\n    \n    private Collection<HeapViewerNodeAction.Provider> actionProviders;\n    \n    private JComponent component;\n    private BreadCrumbsNavigator navigator;\n    \n    private HeapViewerNodeFilter filter;\n    private JComponent filterComponent;\n    \n    private boolean hasSelection;\n    \n    private DataType initialSortColumn;\n    private SortOrder initialSortOrder;\n    \n    private ColumnConfiguration initialColumnConfiguration;\n    private ColumnConfiguration currentColumnConfiguration;\n    \n    \n    public TreeTableView(String viewID, HeapContext context, HeapViewerActions actions, TreeTableViewColumn... columns) {\n        this(viewID, context, actions, false, true, columns);\n    }\n    \n    public TreeTableView(String viewID, HeapContext context, HeapViewerActions actions, boolean useBreadCrumbs, boolean pluggableColumns, TreeTableViewColumn... columns) {\n        assert(!SwingUtilities.isEventDispatchThread());\n        \n        if (columns == null || columns.length == 0) throw new IllegalArgumentException(\"View must have at least one column defined\"); // NOI18N\n        \n        this.viewID = viewID;\n        this.context = context;\n        this.actions = actions;\n        \n        root = new RootNode() {\n            public HeapContext getContext() { return TreeTableView.this.context; }\n            public String getViewID() { return TreeTableView.this.viewID; }\n            public HeapViewerNodeFilter getViewFilter() { return TreeTableView.this.filter; }\n            public List<DataType> getDataTypes() { return dataTypes; }\n            public List<SortOrder> getSortOrders() { return sortOrders; }\n            public void refreshNode(HeapViewerNode node) { if (treeTable != null) treeTable.repaint(); }\n            public void updateChildren(HeapViewerNode node) { if (model != null) model.childrenChanged(root); childrenChanged(); /*if (treeTable != null) treeTable.resetExpandedNodes();*/ }\n            public HeapViewerNode[] retrieveChildren(HeapViewerNode node) { return nodesCache.retrieveChildren(node); }\n            protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException { return TreeTableView.this.computeData(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress); }\n            public HeapViewerRenderer resolveRenderer(HeapViewerNode node) { return TreeTableView.this.resolveNodeRenderer(node); }\n            protected void handleOOME(OutOfMemoryError e) { super.handleOOME(e); TreeTableView.this.handleOOME(e); }\n        };\n        currentRoot = root;\n        \n        this.columns = new ArrayList<>();\n        \n        // Add own columns defined in constructor\n        if (columns != null) Collections.addAll(this.columns, columns);\n        \n        // Add additional columns defined by plugins\n        if (pluggableColumns) {\n            Heap heap = context.getFragment().getHeap();\n            for (TreeTableViewColumn.Provider provider : Lookup.getDefault().lookupAll(TreeTableViewColumn.Provider.class))\n                Collections.addAll(this.columns, provider.getColumns(heap, TreeTableView.this.viewID));\n        }\n        \n        this.columns.sort((TreeTableViewColumn column1, TreeTableViewColumn column2) -> Integer.compare(column1.getPosition(), column2.getPosition()));\n        \n        rendererProviders = new ArrayList<>();\n        for (HeapViewerRenderer.Provider provider : Lookup.getDefault().lookupAll(HeapViewerRenderer.Provider.class))\n            if (provider.supportsView(context, viewID)) rendererProviders.add(provider);\n        \n        actionProviders = new ArrayList<>();\n        for (HeapViewerNodeAction.Provider provider : Lookup.getDefault().lookupAll(HeapViewerNodeAction.Provider.class))\n            if (provider.supportsView(context, viewID)) actionProviders.add(provider);\n        \n        if (useBreadCrumbs) navigator = new BreadCrumbsNavigator() {\n            void nodeClicked(HeapViewerNode node) {\n                TreeTableView.this.selectExistingNode(node);\n            }\n            void nodePinned(HeapViewerNode node) {\n                TreeTableView.this.pinNode(node);\n            }\n            void openNode(HeapViewerNode node) {\n            }\n            HeapViewerRenderer getRenderer(HeapViewerNode node) {\n                return getNodeRenderer(node);\n            }\n            HeapViewerNodeAction.Actions getNodeActions(HeapViewerNode node) {\n                return HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions);\n            }\n        };\n    }\n    \n    \n    private String viewName;\n    \n    public void setViewName(String viewName) {\n        this.viewName = viewName;\n        if (component != null && !hasSelection) nodeSelected(null, false);\n    }\n    \n    public void setViewFilter(HeapViewerNodeFilter filter) {\n        this.filter = filter;\n        setViewName(viewName); // update (filtered) flag in breadcrumbs if needed\n        reloadView();\n    }\n    \n    \n    public JComponent getComponent() {\n        if (component == null) init();\n        return component;\n    }\n    \n//    public void setData(HeapViewerNode[] data) {\n//        root.setChildren(data);\n//    }\n    \n    String getViewID() {\n        return viewID;\n    }\n    \n    HeapContext getContext() {\n        return context;\n    }\n    \n    public RootNode getRoot() {\n        if (component == null) init();\n        return root;\n    }\n    \n    public void reloadView() {\n        if (component != null) {\n            if (root != currentRoot) pinNode(null);\n            root.reset(false);\n        }\n    }\n    \n    \n    public void closed() {\n        if (component != null) {\n            if (root != currentRoot) pinNode(null);\n            root.reset(true);\n        }\n    }\n    \n    \n    public void setSortColumn(DataType dataType, SortOrder sortOrder) {\n        if (treeTable == null) {\n            initialSortColumn = dataType;\n            initialSortOrder = sortOrder;\n        } else {\n            int column = getColumn(dataType);\n            if (column == -1) return;\n            \n            if (sortOrder == null) sortOrder = SortOrder.UNSORTED;\n            \n            List<? extends RowSorter.SortKey> sortKeys = treeTable.getRowSorter().getSortKeys();\n            if (sortKeys != null && sortKeys.size() == 1) {\n                RowSorter.SortKey sortKey = sortKeys.get(0);\n                if (sortKey.getColumn() == column && sortOrder.equals(sortKey.getSortOrder())) return;\n            }\n\n            treeTable.setSorting(column, sortOrder);\n        }\n    }\n    \n//    public DataType getSortColumn() {\n//        if (treeTable == null) return initialSortColumn;\n//        \n//        int sortColumn = treeTable.getSortColumn();\n//        return sortColumn == -1 ? null : columns.get(sortColumn).getDataType();\n//    }\n    \n    public void setColumnVisible(DataType dataType, boolean visible) {\n        int column = getColumn(dataType);\n        if (column == -1) return;\n        \n        if (treeTable == null) return;\n        treeTable.setColumnVisibility(column, visible);\n    }\n    \n    public boolean isColumnVisible(DataType dataType) {\n        int column = getColumn(dataType);\n        if (column == -1) return false;\n        \n        if (treeTable == null) return true; // assume initially visible\n        return treeTable.isColumnVisible(column);\n    }\n    \n    private int getColumn(DataType dataType) {\n        for (int i = 0; i < columns.size(); i++) {\n            TreeTableViewColumn col = columns.get(i);\n            if (col.getDataType() == dataType) return i;\n        }\n        return -1;\n    }\n    \n    \n    protected void initializeColumns(DataType initialSortColumn, SortOrder initialSortOrder, ColumnConfiguration initialColumnConfiguration) {\n        if (initialSortColumn != null) {\n            SortOrder sortOder = initialSortOrder == null ? SortOrder.UNSORTED : initialSortOrder;\n            setSortColumn(initialSortColumn, sortOder);\n        }\n        \n        if (initialColumnConfiguration != null)\n            configureColumns(initialColumnConfiguration);\n    }\n    \n    public void configureColumns(ColumnConfiguration configuration) {\n        if (treeTable == null) {\n            initialColumnConfiguration = configuration;\n        } else {\n            currentColumnConfiguration = configuration;\n            \n            boolean sortColumnHidden = false;\n            \n            if (configuration.alwaysShown != null) {\n                int column = getColumn(configuration.alwaysShown);\n                if (column != -1) treeTable.setColumnVisibility(column, true);\n            }\n            \n            if (configuration.neverShown != null) {\n                int column = getColumn(configuration.neverShown);\n                \n                if (column != -1) {\n                    int sortC = treeTable.getSortColumn();\n                    if (sortC != -1) sortC = treeTable.convertColumnIndexToModel(sortC);\n                    sortColumnHidden = column == sortC;\n                    \n                    treeTable.setColumnVisibility(column, false);\n                }\n            }\n            \n            if (configuration.sortColumn != null) {\n                if (configuration.sortMode != null || sortColumnHidden) {\n                    int column = getColumn(configuration.sortColumn);\n                    \n                    if (Boolean.FALSE.equals(configuration.sortMode)) {\n                        List<? extends RowSorter.SortKey> sortKeys = treeTable.getRowSorter().getSortKeys();\n                        if (sortKeys != null && sortKeys.size() == 1) {\n                            RowSorter.SortKey sortKey = sortKeys.get(0);\n                            if (!SortOrder.UNSORTED.equals(sortKey.getSortOrder())) return;\n                        }\n                    }\n                    \n                    if (configuration.sortOrder == null) {\n                        treeTable.setSortColumn(column);\n                    } else {\n                        treeTable.setSorting(column, configuration.sortOrder);\n                    }\n                }\n            }\n        }\n    }\n    \n    public ColumnConfiguration getCurrentColumnConfiguration() {\n        return treeTable == null ? initialColumnConfiguration :\n                                   currentColumnConfiguration;\n    }\n    \n    \n    public void selectNode(HeapViewerNode node) {\n        // TODO: implement correctly for lazy model\n        treeTable.selectPath(HeapViewerNode.fromNode(node, currentRoot), true);\n    }\n    \n    public void expandNode(HeapViewerNode node) {\n        if (treeTable == null) return;\n        treeTable.expandPath(HeapViewerNode.fromNode(node));\n    }\n    \n    public void collapseChildren(HeapViewerNode node) {\n        if (treeTable == null) return;\n        treeTable.collapseChildren(HeapViewerNode.fromNode(node));\n    }\n    \n    \n//    protected void willBeSorted(List<RowSorter.SortKey> sortKeys) {}\n    \n    protected void nodeSelected(HeapViewerNode node, boolean adjusting) {\n        hasSelection = node != null;\n        if (navigator != null) updateNavigator(node);\n    }\n    \n    protected void nodeExpanding(HeapViewerNode node) {}\n    \n    protected void nodeExpanded(HeapViewerNode node) {}\n\n    protected void nodeCollapsing(HeapViewerNode node) {}\n\n    protected void nodeCollapsed(HeapViewerNode node) {}\n    \n    protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        return HeapViewerNode.NO_NODES;\n    }\n    \n    protected void childrenChanged() {}\n    \n    \n    private TreeTableViewRenderer getNodesRenderer() {\n        if (nodesRenderer == null) {\n            Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> map = new HashMap<>();\n            nodesRenderer = new TreeTableViewRenderer();\n            for (HeapViewerRenderer.Provider provider : rendererProviders) {\n                map.clear();\n                provider.registerRenderers(map, context);\n                nodesRenderer.registerRenderers(map);\n            }\n            rendererProviders = null;\n        }\n        return nodesRenderer;\n    }\n    \n    private HeapViewerRenderer resolveNodeRenderer(HeapViewerNode node) {\n        TreeTableViewRenderer viewRenderer = getNodesRenderer();\n        return viewRenderer.resolve(node.getClass());\n    }\n    \n    public HeapViewerRenderer getNodeRenderer(HeapViewerNode node) {\n        HeapViewerRenderer nodeRenderer = resolveNodeRenderer(node);\n        nodeRenderer.setValue(node, -1);\n        return nodeRenderer;\n    }\n    \n    // --- OOME handling -------------------------------------------------------\n    \n    protected void handleOOME(OutOfMemoryError e) {\n        HeapUtils.handleOOME(true, e);\n    }\n    \n    // --- BreadCrumbs prototype -----------------------------------------------\n    \n    private void setRoot(HeapViewerNode newRoot) {\n        nodesCache.clear();\n        \n        model.setRoot(newRoot);\n        currentRoot = newRoot;\n        \n        treeTable.setRootVisible(currentRoot != root);\n    }\n    \n    void selectExistingNode(HeapViewerNode node) {\n        if (node == null) {\n            treeTable.clearSelection();\n            setRoot(root);\n            treeTable.collapseAll();\n            treeTable.expandPath(new TreePath(model.getRoot()));\n            treeTable.scrollRectToVisible(new Rectangle());\n        } else {\n            if (!inPinnedView(node)) setRoot(root);\n            treeTable.selectPath(HeapViewerNode.fromNode(node, currentRoot), true);\n            treeTable.collapseChildren(HeapViewerNode.fromNode(node, currentRoot));\n        }\n        \n        treeTable.requestFocusInWindow();\n    }\n    \n    protected void pinNode(HeapViewerNode node) {\n        int row = treeTable.getSelectedRow();\n        HeapViewerNode sel = row == -1 ? null : (HeapViewerNode)treeTable.getValueForRow(row);\n        \n        if (node == null) {\n            setRoot(root);\n            if (sel != null) treeTable.selectPath(HeapViewerNode.fromNode(sel, currentRoot), true);\n        } else {\n            setRoot(node);\n            if (sel != null) treeTable.selectPath(HeapViewerNode.fromNode(sel, currentRoot), true);\n            if (treeTable.getSelectedValue(0) == null) treeTable.selectRow(0, true);\n        }\n        updateNavigator();\n        treeTable.requestFocusInWindow();\n    }\n    \n    private boolean inPinnedView(HeapViewerNode node) {\n        while (node != root && node != null) {\n            if (node == currentRoot) return true;\n            node = node.getParent();\n        }\n        return false;\n    }\n    \n    private void updateNavigator() {\n        int row = treeTable.getSelectedRow();\n        HeapViewerNode sel = row == -1 ? null : (HeapViewerNode)treeTable.getValueForRow(row);\n        updateNavigator(sel);\n    }\n    \n    private void updateNavigator(HeapViewerNode node) {\n        String _viewName = viewName;\n        if (_viewName != null && filter != null) _viewName = Bundle.TreeTableView_FilteredFlag(_viewName);\n        navigator.setNode(node, currentRoot == root ? null : currentRoot, getRoot(), _viewName);\n    }\n    \n    // -------------------------------------------------------------------------\n    \n    \n    private void init() {\n        model = new Model();\n        nodesCache = new NodesCache();\n        component = createComponent();\n    }\n    \n    protected JComponent createComponent() {\n        int sortingColumn = -1;\n        for (int i = 0; i < columns.size(); i++) {\n            TreeTableViewColumn column = columns.get(i);\n            if (column.initiallyVisible() && column.initiallySorting()) {\n                sortingColumn = i;\n                break;\n            }\n        }\n        \n        List<? extends RowSorter.SortKey> sortKeys;\n        if (sortingColumn != -1) {\n            RowSorter.SortKey sortKey = new RowSorter.SortKey(sortingColumn, SortOrder.DESCENDING); // TODO: resolve the right SortOrder\n//        List<? extends RowSorter.SortKey> sortKeys = Collections.singletonList(sortKey);\n            sortKeys = Collections.singletonList(sortKey);\n        } else {\n            sortKeys = Collections.emptyList();\n        }\n        updateSortInfo(sortKeys);\n        \n        treeTable = new HeapViewerTreeTable(model, sortKeys) {\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                HeapViewerNode node = (HeapViewerNode)value;\n                HeapViewerNodeAction.Actions nodeActions = navigator == null ?\n                        HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions) :\n                        HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions, new PinAction(node), new ResetPinAction());\n                nodeActions.populatePopup(popup);\n                \n                TreeTableView.this.populatePopup(node, popup);\n                \n                if (popup.getComponentCount() > 0) popup.addSeparator();\n                popup.add(treeTable.createCopyMenuItem());\n                TreeTableView.this.populatePopupLast(node, popup);\n            }\n            public void performDefaultAction(ActionEvent e) {\n                int row = getSelectedRow();\n                if (row == -1) return;\n\n                Object value = getValueForRow(row);\n                if (!(value instanceof HeapViewerNode)) return;\n                \n                HeapViewerNodeAction.Actions nodeActions =\n                        HeapViewerNodeAction.Actions.forNode((HeapViewerNode)value, actionProviders, context, actions);\n                nodeActions.performDefaultAction(e);\n            }\n            protected void nodeSelected(HeapViewerNode node, boolean adjusting) {\n                TreeTableView.this.nodeSelected(node, adjusting);\n            }\n            protected void forgetChildren(HeapViewerNode node) {\n                node.forgetChildren(nodesCache);\n            }\n            protected void willBeSorted(List<? extends RowSorter.SortKey> sortKeys) {\n                if (!isInitializing() && !sortKeys.isEmpty()) {\n                    int col = sortKeys.get(0).getColumn();\n                    DataType type = columns.get(col).getDataType();\n                    Heap heap = context.getFragment().getHeap();\n                    if (!type.valuesAvailable(heap)) type.computeValues(heap, null);\n                }\n                \n                updateSortInfo(sortKeys);\n                nodesCache.clear();\n                \n                super.willBeSorted(sortKeys);\n                \n//                TreeTableView.this.willBeSorted(sortKeys);\n            }\n            protected void nodeExpanding(TreeNode node) { super.nodeExpanding(node); if (node instanceof HeapViewerNode) TreeTableView.this.nodeExpanding((HeapViewerNode)node); }\n    \n            protected void nodeExpanded(TreeNode node) { super.nodeExpanded(node); if (node instanceof HeapViewerNode) TreeTableView.this.nodeExpanded((HeapViewerNode)node); }\n\n            protected void nodeCollapsing(TreeNode node) { super.nodeCollapsing(node); if (node instanceof HeapViewerNode) TreeTableView.this.nodeCollapsing((HeapViewerNode)node); }\n\n            protected void nodeCollapsed(TreeNode node) { super.nodeCollapsed(node); if (node instanceof HeapViewerNode) TreeTableView.this.nodeCollapsed((HeapViewerNode)node); }\n        };\n        \n        treeTable.setTreeCellRenderer(getNodesRenderer());\n\n        for (int i = 0; i < columns.size(); i++) {\n            TreeTableViewColumn column = columns.get(i);\n            \n            if (i > 0) treeTable.setColumnRenderer(i, getRenderer(column));\n            \n            int width = column.getPreferredWidth();\n            if (width > -1) treeTable.setDefaultColumnWidth(i, width);\n            \n            if (!column.initiallyVisible()) treeTable.setColumnVisibility(i, false);\n        }\n        \n        initializeColumns(initialSortColumn, initialSortOrder, initialColumnConfiguration);\n        initialSortColumn = null;\n        initialSortOrder = null;\n        initialColumnConfiguration = null;\n        \n        treeTable.providePopupMenu(true);\n        \n        treeTable.setSelectionOnMiddlePress(true);\n        treeTable.addMouseListener(new MouseAdapter() {\n            public void mouseClicked(MouseEvent e) {\n                if (SwingUtilities.isMiddleMouseButton(e)) {\n                    int row = treeTable.getSelectedRow();\n                    if (row == -1) return;\n                    \n                    Object value = treeTable.getValueForRow(row);\n                    if (!(value instanceof HeapViewerNode)) return;\n                    \n                    HeapViewerNode node = (HeapViewerNode)value;\n                    HeapViewerNodeAction.Actions nodeActions = navigator == null ?\n                        HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions) :\n                        HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions, new PinAction(node), new ResetPinAction());\n                    ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), \"middle button\", e.getWhen(), e.getModifiers()); // NOI18N\n                    nodeActions.performMiddleButtonAction(ae);\n                }\n            }\n        });\n        \n        JComponent comp = new JPanel(new BorderLayout()) {\n            public boolean requestFocusInWindow() {\n                return treeTable.requestFocusInWindow();\n            }\n        };\n        comp.add(new ProfilerTableContainer(treeTable, false, null), BorderLayout.CENTER);\n        \n        JComponent toolsContainer = new JPanel(new GridBagLayout());\n        comp.add(toolsContainer, BorderLayout.SOUTH);\n        \n        GridBagConstraints c;\n        \n        if (navigator != null) {\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 0;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.weightx = 1f;\n            toolsContainer.add(navigator.getComponent(), c);\n        }\n        \n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.weightx = 1f;\n        filterComponent = new JPanel(new BorderLayout());\n        filterComponent.setVisible(false);\n        toolsContainer.add(filterComponent, c);\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { nodeSelected(null, false); }\n        });\n        \n        return comp;\n    }\n    \n    protected void populatePopup(HeapViewerNode node, JPopupMenu popup) {\n    }\n    \n    protected void populatePopupLast(HeapViewerNode node, JPopupMenu popup) {\n        if (filterComponent.getComponentCount() > 0) {\n            popup.addSeparator();\n            popup.add(new JMenuItem(Bundle.TreeTableView_Filter()) {\n                protected void fireActionPerformed(ActionEvent e) { activateFilter(); }\n            });\n        }\n    }\n    \n    protected void setFilterComponent(JComponent filter) {\n        filterComponent.add(filter, BorderLayout.CENTER);\n        filterComponent.setVisible(true);\n        registerActions();\n    }\n    \n    protected JComponent getFilterComponent() {\n        return filterComponent.getComponentCount() == 0 ? null :\n               (JComponent)filterComponent.getComponent(0);\n    }\n    \n    private void activateFilter() {\n        Component filterComp = getFilterComponent();\n        if (filterComp != null) {\n            filterComp.setVisible(true);\n            filterComp.requestFocusInWindow();\n        }\n    }\n    \n    private void registerActions() {\n        InputMap inputMap = treeTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        ActionMap actionMap = treeTable.getActionMap();\n        \n        final String filterKey = FilterUtils.FILTER_ACTION_KEY;\n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { activateFilter(); }\n        };\n        ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);\n    }\n    \n    private void updateSortInfo(List<? extends RowSorter.SortKey> sortKeys) {\n        if (sortKeys == null) {\n            dataTypes = null;\n            sortOrders = null;\n        } else {\n            dataTypes = new ArrayList<>(sortKeys.size());\n            sortOrders = new ArrayList<>(sortKeys.size());\n\n            for (RowSorter.SortKey sortKey : sortKeys) {\n                // TODO: find out the root cause - java.lang.IndexOutOfBoundsException: Index: 2, Size: 2\n                if (columns.size() > sortKey.getColumn()) {\n                    dataTypes.add(columns.get(sortKey.getColumn()).getDataType());\n                    sortOrders.add(sortKey.getSortOrder());\n                }\n            }\n        }\n    }\n    \n    \n    private static ProfilerRenderer getRenderer(TreeTableViewColumn column) {\n        ProfilerRenderer renderer = column.getRenderer();\n        if (renderer != null) return renderer;\n        \n        Class columnClass = column.getDataType().getType();\n        if (Number.class.isAssignableFrom(columnClass)) return new NumberRenderer();\n        else return new LabelRenderer();\n    }\n    \n    \n    private class PinAction extends HeapViewerNodeAction {\n        \n        private final HeapViewerNode node;\n        \n        PinAction(HeapViewerNode node) {\n            super(Bundle.TreeTableView_Pin(), 110);\n            this.node = node;\n            setEnabled(node != currentRoot && !node.isLeaf());\n        }\n        \n        public boolean isMiddleButtonDefault(ActionEvent e) {\n            int modifiers = e.getModifiers();\n            return (modifiers & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK &&\n                   (modifiers & ActionEvent.SHIFT_MASK) != ActionEvent.SHIFT_MASK;\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            TreeTableView.this.pinNode(node);\n        }\n        \n    }\n    \n    private class ResetPinAction extends HeapViewerNodeAction {\n        \n        ResetPinAction() {\n            super(Bundle.TreeTableView_ResetPin(), 111);\n            setEnabled(root != currentRoot);\n        }\n        \n        public boolean isMiddleButtonDefault(ActionEvent e) {\n            int modifiers = e.getModifiers();\n            return (modifiers & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK &&\n                   (modifiers & ActionEvent.SHIFT_MASK) == ActionEvent.SHIFT_MASK;\n        }\n        \n        public void actionPerformed(ActionEvent e) {\n            TreeTableView.this.pinNode(null);\n        }\n        \n    }\n    \n    \n    private final class Model extends ProfilerTreeTableModel.Abstract {\n        \n        private Runnable[] dataTypeListeners;\n        \n        private Model() {\n            super(root);\n            \n            dataTypeListeners = new Runnable[getColumnCount()];\n            for (int i = 0; i < dataTypeListeners.length; i++) {\n                final TreeTableViewColumn viewColumn = columns.get(i);\n                DataType dataType = viewColumn.getDataType();\n                if (dataType.valuesAvailable(context.getFragment().getHeap())) {\n                    dataTypeListeners[i] = null;\n                } else {\n                    final int ii = i;\n                    dataTypeListeners[ii] = new Runnable() {\n                        public void run() {\n                            dataTypeListeners[ii] = null;\n                            TableColumn tableColumn = treeTable.getColumnModel().getColumn(ii);\n                            tableColumn.setHeaderValue(getColumnName(ii));\n                            TreeTableView.this.component.repaint();\n                            if (dataTypes != null && dataTypes.contains(dataType)) {\n                                TreeTableView.this.reloadView();\n                            }\n                        }\n                    };\n                    dataType.notifyWhenAvailable(context.getFragment().getHeap(), dataTypeListeners[ii]);\n                }\n            }\n        }\n\n        public int getColumnCount() {\n            return columns.size();\n        }\n\n        public Class<?> getColumnClass(int column) {\n            if (column == 0) return JTree.class;\n            return columns.get(column).getDataType().getType();\n        }\n\n        public String getColumnName(int column) {\n            String columnName = columns.get(column).getHeaderValue().toString();\n            return dataTypeListeners[column] == null ? columnName :\n                   \"<html><nobr>\" + columnName + \" <small style='color: gray;'>(\" + Bundle.TreeTableView_SortToGet() + \")</small></nobr></html>\"; // NOI18N\n        }\n        \n        public Object getValueAt(TreeNode node, int column) {\n            return HeapViewerNode.getValue((HeapViewerNode)node, columns.get(column).getDataType(), context.getFragment().getHeap());\n        }\n        \n\n        public void setValueAt(Object aValue, TreeNode node, int column) {}\n\n        public boolean isCellEditable(TreeNode node, int column) { return false; }\n        \n    }\n    \n    \n    public static final class ColumnConfiguration {\n        \n        final DataType alwaysShown;\n        final DataType neverShown;\n        \n        final DataType sortColumn;\n        final SortOrder sortOrder;\n        final Boolean sortMode;\n        \n        public ColumnConfiguration(DataType alwaysShown, DataType neverShown, DataType sortColumn, SortOrder sortOrder, Boolean sortMode) {\n            this.alwaysShown = alwaysShown;\n            this.neverShown = neverShown;\n            \n            this.sortColumn = sortColumn;\n            this.sortOrder = sortOrder;\n            this.sortMode = sortMode;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/TreeTableViewColumn.java",
    "content": "/*\n * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.util.Objects;\nimport javax.swing.SwingConstants;\nimport javax.swing.table.TableColumn;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TreeTableViewColumn_ColName=Name\",\n    \"TreeTableViewColumn_ColLogicalValue=Logical Value\",\n    \"TreeTableViewColumn_ColCount=Count\",\n    \"TreeTableViewColumn_ColSize=Size\",\n    \"TreeTableViewColumn_ColRetained=Retained\",\n    \"TreeTableViewColumn_ColObjectId=Object ID\",\n    \"TreeTableViewColumn_GCRoots=GC Roots\"\n})\npublic class TreeTableViewColumn extends TableColumn {\n    \n    private final int position;\n    private final DataType dataType;\n\n    private final boolean initiallyVisible;\n    private final boolean initiallySorting;\n\n\n    public TreeTableViewColumn(String name, int position, DataType dataType, boolean sortingColumn) {\n        this(name, position, dataType, true, sortingColumn);\n    }\n\n    public TreeTableViewColumn(String name, int position, DataType dataType, boolean initiallyVisible, boolean initiallySorting) {\n        this.position = position;\n        this.dataType = dataType;\n\n        this.initiallyVisible = initiallyVisible;\n        this.initiallySorting = initiallySorting;\n\n        setHeaderValue(name);\n    }\n\n\n    public int getPosition() { return position; }\n\n    public DataType getDataType() { return dataType; }\n    \n    public boolean initiallyVisible() { return initiallyVisible; }\n    \n    public boolean initiallySorting() { return initiallySorting; }\n    \n    \n    public int getPreferredWidth() { return -1; }\n    \n    public ProfilerRenderer getRenderer() { return null; }\n    \n    \n    public static TreeTableViewColumn[] classes(Heap heap, boolean sort) {\n        return new TreeTableViewColumn[] {\n            new Name(),\n            new LogicalValue(),\n            new Count(heap),\n            new OwnSize(heap, true, sort),\n            new RetainedSize(heap),\n            new ObjectID(),\n            new GCRoots(heap,false,false)\n        };\n    }\n    \n    public static TreeTableViewColumn[] classesMinimal(Heap heap, boolean sort) {\n        return new TreeTableViewColumn[] {\n            new Name(),\n            new LogicalValue(),\n            new Count(heap, false, false),\n            new OwnSize(heap, false, false),\n            new RetainedSize(heap, true, sort),\n            new ObjectID()\n        };\n    }\n    \n    public static TreeTableViewColumn[] classesPlain(Heap heap) {\n        return new TreeTableViewColumn[] {\n            new Name(),\n            new LogicalValue(),\n            new Count(heap, false, false),\n            new OwnSize(heap, false, false),\n            new RetainedSize(heap, false, false),\n            new ObjectID()\n        };\n    }\n    \n    public static TreeTableViewColumn[] instances(Heap heap, boolean sort) {\n        return new TreeTableViewColumn[] {\n            new Name(),\n            new LogicalValue(),\n            new OwnSize(heap, true, sort),\n            new RetainedSize(heap),\n            new ObjectID()\n        };\n    }\n    \n    public static TreeTableViewColumn[] instancesMinimal(Heap heap, boolean sort) {\n        return new TreeTableViewColumn[] {\n            new Name(),\n            new LogicalValue(),\n            new OwnSize(heap, false, false),\n            new RetainedSize(heap, true, sort),\n            new ObjectID()\n        };\n    }\n    \n    public static TreeTableViewColumn[] instancesPlain(Heap heap) {\n        return new TreeTableViewColumn[] {\n            new Name(),\n            new LogicalValue(),\n            new OwnSize(heap, false, false),\n            new RetainedSize(heap, false, false),\n            new ObjectID()\n        };\n    }\n    \n    \n    public static class Name extends TreeTableViewColumn {\n        \n        public Name() {\n            this(false);\n        }\n        \n        public Name(boolean initiallySorting) {\n            super(Bundle.TreeTableViewColumn_ColName(), 100, DataType.NAME, true, initiallySorting);\n        }\n        \n    }\n    \n    public static class LogicalValue extends TreeTableViewColumn {\n        \n        private final LabelRenderer renderer;\n        private final int preferredWidth;\n        \n        public LogicalValue() {\n            this(false, false);\n        }\n        \n        public LogicalValue(boolean initiallyVisible, boolean initiallySorting) {\n            super(Bundle.TreeTableViewColumn_ColLogicalValue(), 150, DataType.LOGICAL_VALUE, initiallyVisible, initiallySorting);\n            \n            renderer = new LabelRenderer() {\n                public void setValue(Object value, int row) {\n                    if (Objects.equals(value, DataType.OBJECT_ID.getNoValue())) setText(\"-\"); // NOI18N\n                    else if (Objects.equals(value, DataType.OBJECT_ID.getUnsupportedValue())) setText(\"\"); // NOI18N\n                    else if (Objects.equals(value, DataType.OBJECT_ID.getNotAvailableValue())) setText(\"n/a\"); // NOI18N\n                    else super.setValue(value, row);\n                }\n            };\n            renderer.setValue(\"A typical-length logical value to setup the column width\", -1); // NOI18N\n            preferredWidth = renderer.getPreferredSize().width + 20;\n        }\n        \n        public int getPreferredWidth() { return preferredWidth; }\n        \n        public ProfilerRenderer getRenderer() { return renderer; }\n        \n    }\n    \n    public static class Count extends TreeTableViewColumn {\n        \n        private final HideableBarRenderer renderer;\n        private final int preferredWidth;\n        \n        public Count(Heap heap) {\n            this(heap, true, false);\n        }\n        \n        public Count(Heap heap, boolean initiallyVisible, boolean initiallySorting) {\n            super(Bundle.TreeTableViewColumn_ColCount(), 200, DataType.COUNT, initiallyVisible, initiallySorting);\n            \n            renderer = new HideableBarRenderer(HeapViewerNumberRenderer.decimalInstance(DataType.COUNT));\n            renderer.setMaxValue(Integer.MAX_VALUE / 1000);\n            preferredWidth = renderer.getMaxNoBarWidth() - 20;\n            renderer.setMaxValue(heap.getSummary().getTotalLiveInstances());\n        }\n        \n        public int getPreferredWidth() { return preferredWidth; }\n        \n        public ProfilerRenderer getRenderer() { return renderer; }\n        \n    }\n    \n    public static class GCRoots extends TreeTableViewColumn {\n\n        private final HideableBarRenderer renderer;\n        private final int preferredWidth;\n\n        public GCRoots(Heap heap) {\n            this(heap, true, false);\n        }\n\n        public GCRoots(Heap heap, boolean initiallyVisible, boolean initiallySorting) {\n            super(Bundle.TreeTableViewColumn_GCRoots(), 190, DataType.GCROOTS, initiallyVisible, initiallySorting);\n\n            renderer = new HideableBarRenderer(HeapViewerNumberRenderer.decimalInstance(DataType.GCROOTS));\n            renderer.setMaxValue(Integer.MAX_VALUE / 1000);\n            preferredWidth = renderer.getMaxNoBarWidth() - 20;\n            renderer.setMaxValue(heap.getGCRoots().size());\n        }\n\n        public int getPreferredWidth() { return preferredWidth; }\n\n        public ProfilerRenderer getRenderer() { return renderer; }\n    }\n\n    public static class OwnSize extends TreeTableViewColumn {\n        \n        private final HideableBarRenderer renderer;\n        private final int preferredWidth;\n        \n        public OwnSize(Heap heap) {\n            this(heap, true, true);\n        }\n        \n        public OwnSize(Heap heap, boolean initiallyVisible, boolean initiallySorting) {\n            super(Bundle.TreeTableViewColumn_ColSize(), 300, DataType.OWN_SIZE, initiallyVisible, initiallySorting);\n            \n            renderer = new HideableBarRenderer(HeapViewerNumberRenderer.bytesInstance(DataType.OWN_SIZE));\n            renderer.setMaxValue(Integer.MAX_VALUE / 100);\n            preferredWidth = renderer.getMaxNoBarWidth() - 20;\n            renderer.setMaxValue(heap.getSummary().getTotalLiveBytes());\n        }\n        \n        public int getPreferredWidth() { return preferredWidth; }\n        \n        public ProfilerRenderer getRenderer() { return renderer; }\n        \n    }\n    \n    public static class RetainedSize extends TreeTableViewColumn {\n        \n        private final HideableBarRenderer renderer;\n        private final int preferredWidth;\n        \n        public RetainedSize(Heap heap) {\n            this(heap, true, false);\n        }\n        \n        public RetainedSize(Heap heap, boolean initiallyVisible, boolean initiallySorting) {\n            super(Bundle.TreeTableViewColumn_ColRetained(), 400, DataType.RETAINED_SIZE, initiallyVisible, initiallySorting);\n            \n            renderer = new HideableBarRenderer(HeapViewerNumberRenderer.bytesInstance(DataType.RETAINED_SIZE));\n            renderer.setMaxValue(Integer.MAX_VALUE / 100);\n            preferredWidth = renderer.getMaxNoBarWidth() - 20;\n            renderer.setMaxValue(heap.getSummary().getTotalLiveBytes());\n        }\n        \n        public int getPreferredWidth() { return preferredWidth; }\n        \n        public ProfilerRenderer getRenderer() { return renderer; }\n        \n    }\n    \n    public static class ObjectID extends TreeTableViewColumn {\n        \n        private final LabelRenderer renderer;\n        private final int preferredWidth;\n        \n        public ObjectID() {\n            this(false, false);\n        }\n        \n        public ObjectID(boolean initiallyVisible, boolean initiallySorting) {\n            super(Bundle.TreeTableViewColumn_ColObjectId(), 500, DataType.OBJECT_ID, initiallyVisible, initiallySorting);\n            \n            renderer = new LabelRenderer() {\n                public void setValue(Object value, int row) {\n                    if (value == null) setText(\"\"); // NOI18N\n                    else if (Objects.equals(value, DataType.OBJECT_ID.getNoValue())) setText(\"-\"); // NOI18N\n                    else if (Objects.equals(value, DataType.OBJECT_ID.getUnsupportedValue())) setText(\"\"); // NOI18N\n                    else if (Objects.equals(value, DataType.OBJECT_ID.getNotAvailableValue())) setText(\"n/a\"); // NOI18N\n                    else setText(\"0x\" + Long.toHexString((Long)value)); // NOI18N\n                }\n            };\n            renderer.setHorizontalAlignment(SwingConstants.TRAILING);\n            renderer.setValue(Long.MAX_VALUE - 123, -1);\n            preferredWidth = renderer.getPreferredSize().width + 20;\n        }\n        \n        public int getPreferredWidth() { return preferredWidth; }\n        \n        public ProfilerRenderer getRenderer() { return renderer; }\n        \n    }\n    \n    \n    public static abstract class Provider {\n    \n        public abstract TreeTableViewColumn[] getColumns(Heap heap, String viewID);\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/TreeTableViewRenderer.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.accessibility.AccessibleContext;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.ErrorNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.LoopNode;\nimport org.graalvm.visualvm.heapviewer.model.ProgressNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TreeTableViewRenderer_Loop=loop to {0}\"\n})\nclass TreeTableViewRenderer implements ProfilerRenderer {\n    \n    // Don't make this static, leaks the last rendered value -> model -> UI -> Universe\n    private /*static*/ final HeapViewerRenderer FALLBACK = new FallbackRenderer();\n    \n    private final Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> lookup = new HashMap<>();\n    \n    private ProfilerRenderer current = FALLBACK;\n    \n    \n    {\n        lookup.put(LoopNode.class, new LoopNodeRenderer());\n        lookup.put(ProgressNode.class, new ProgressNodeRenderer());\n        lookup.put(ErrorNode.class, new ErrorNodeRenderer());\n    }\n    \n    \n    void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers) {\n        lookup.putAll(renderers);\n    }\n    \n    \n    public void setValue(Object value, int row) {\n        current = resolve(value.getClass());\n        current.setValue(value, row);\n    }\n\n    public int getHorizontalAlignment() {\n        return current.getHorizontalAlignment();\n    }\n\n    public JComponent getComponent() {\n        return current.getComponent();\n    }\n\n    public void move(int x, int y) {\n        current.move(x, y);\n    }\n\n    public AccessibleContext getAccessibleContext() {\n        return current.getAccessibleContext();\n    }\n    \n    public String toString() {\n        return current.toString();\n    }\n    \n    \n    HeapViewerRenderer resolve(Class cls) {\n        HeapViewerRenderer renderer = lookup.get(cls);\n        while (renderer == null && cls != null) {\n            cls = cls.getSuperclass();\n            renderer = lookup.get(cls);\n        }\n        return renderer != null ? renderer : FALLBACK;\n    }\n    \n    \n    private class LoopNodeRenderer implements HeapViewerRenderer {\n        \n        private HeapViewerRenderer impl;\n    \n        \n        public void setValue(Object value, int row) {\n            HeapViewerNode loop = HeapViewerNode.getValue((HeapViewerNode)value, DataType.LOOP, null);\n            impl = resolve(loop.getClass());\n            impl.setValue(value, row);\n        }\n\n        public int getHorizontalAlignment() {\n            return impl.getHorizontalAlignment();\n        }\n\n        public JComponent getComponent() {\n            return impl.getComponent();\n        }\n\n        public void move(int x, int y) {\n            impl.move(x, y);\n        }\n\n        public AccessibleContext getAccessibleContext() {\n            return impl.getAccessibleContext();\n        }\n        \n        public Icon getIcon() {\n            return impl.getIcon();\n        }\n\n        public String getShortName() {\n            return Bundle.TreeTableViewRenderer_Loop(impl.getShortName());\n        }\n        \n        public String toString() {\n            return impl.toString();\n        }\n\n    }\n    \n    private static class ProgressNodeRenderer extends NormalBoldGrayRenderer implements HeapViewerRenderer {\n    \n        ProgressNodeRenderer() {\n            setNormalValue(\"X\"); // NOI18N\n            setBoldValue(\"  \"); // NOI18N\n            setIcon(Icons.getIcon(HeapWalkerIcons.PROGRESS));\n        }\n        \n        public void setValue(Object value, int row) {\n            ProgressNode node = (ProgressNode)value;\n            \n            String text = node.getText();\n            String progressText = node.getProgressText();\n            \n            setNormalValue(text);\n            setGrayValue(progressText);\n        }\n        \n        public String getShortName() {\n            return getNormalValue();\n        }\n\n    }\n    \n    private static class ErrorNodeRenderer extends LabelRenderer implements HeapViewerRenderer {\n    \n        ErrorNodeRenderer() {\n            setIcon(Icons.getIcon(GeneralIcons.ERROR));\n        }\n        \n        public void setValue(Object value, int row) {\n            setText(value == null ? \"\" : value.toString()); // NOI18N\n        }\n        \n        public String getShortName() {\n            return getText();\n        }\n\n    }\n    \n    private static class FallbackRenderer extends LabelRenderer implements HeapViewerRenderer {}\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/ui/UIThresholds.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.ui;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class UIThresholds {\n    \n    // Non-responding threshold for populating the Tools menu\n    public static final int TOOLS_LOAD = Integer.getInteger(\"heapviewer.toolsLoadThreshold\", 100); // NOI18N\n    \n    // Non-responding threshold for populating views (Heap Summary, System Information etc.)\n    public static final int VIEW_LOAD = Integer.getInteger(\"heapviewer.viewDataLoadThreshold\", 50); // NOI18N\n    \n    // Non-responding threshold for populating children nodes in treetable views (Objects, Threads etc.)\n    public static final int MODEL_CHILDREN = Integer.getInteger(\"heapviewer.modelChildrenLoadThreshold\", 50); // NOI18N\n    \n    \n    // Initial delay before ProgressNode starts displaying progress details\n    public static final int PROGRESS_INITIAL_DELAY = Integer.getInteger(\"heapviewer.progressInitialDelay\", 1000); // NOI18N\n    \n    // ProgressNode progress details update rate\n    public static final int PROGRESS_REFRESH_RATE = Integer.getInteger(\"heapviewer.progressRefreshRate\", 500); // NOI18N\n    \n    \n    // Maximum number of classes displayed as roots in the Objects view\n    public static final int MAX_TOPLEVEL_CLASSES = Integer.getInteger(\"heapviewer.toplevelClassesThreshold\", 100000); // NOI18N\n    \n    // Maximum number of classes displayed as children of a class container in the Objects view\n    public static final int MAX_CONTAINER_CLASSES = Integer.getInteger(\"heapviewer.containerClassesThreshold\", 100); // NOI18N\n    \n    // Maximum number of instances displayed as roots in the Objects view\n    public static final int MAX_TOPLEVEL_INSTANCES = Integer.getInteger(\"heapviewer.toplevelInstancesThreshold\", 300); // NOI18N\n    \n    // Maximum number of instances displayed as children of a class in the Objects view\n    public static final int MAX_CLASS_INSTANCES = Integer.getInteger(\"heapviewer.classInstancesThreshold\", 100); // NOI18N\n    \n    // Maximum number of instances displayed as children of a class container in the Objects view\n    public static final int MAX_CONTAINER_INSTANCES = Integer.getInteger(\"heapviewer.containerInstancesThreshold\", 100); // NOI18N\n    \n    // Maximum number of items displayed as children of an array in the Objects view\n    public static final int MAX_ARRAY_ITEMS = Integer.getInteger(\"heapviewer.arrayItemsThreshold\", 100); // NOI18N\n    \n    // Maximum number of fields displayed as children of an instance in the Objects view\n    public static final int MAX_INSTANCE_FIELDS = Integer.getInteger(\"heapviewer.instanceFieldsThreshold\", 200); // NOI18N\n    \n    // Maximum number of references displayed as children of an instance in the Objects view\n    public static final int MAX_INSTANCE_REFERENCES = Integer.getInteger(\"heapviewer.instanceReferencesThreshold\", 100); // NOI18N\n    \n    // Maximum number of instances displayed as roots in the OQL Objects view\n    public static final int MAX_OQL_TOPLEVEL_INSTANCES = Integer.getInteger(\"heapviewer.toplevelOQLInstancesThreshold\", 300); // NOI18N\n    \n    // Maximum number of items displayed as children of a merged view (fields, references, GC roots etc.)\n    public static final int MAX_MERGED_OBJECTS = Integer.getInteger(\"heapviewer.mergedObjectsThreshold\", 20); // NOI18N\n    \n    \n    // Number of sample objects\n    public static final int SAMPLE_OBJECTS_COUNT = 100;\n    \n    // Minimum number of objects for which the sample objects node is created\n    public static final int SAMPLE_OBJECTS_THRESHOLD = 1000;\n    \n    \n    private UIThresholds() {}\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/ExcludingIterator.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.utils;\n\nimport java.util.Iterator;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ExcludingIterator<T> implements Iterator<T> {\n    \n    private final Iterator<T> iterator;\n    private T next;\n\n    \n    protected ExcludingIterator(Iterator<T> iterator) {\n        this.iterator = iterator;\n        computeNext();\n    }\n    \n    \n    protected abstract boolean exclude(T item);\n    \n\n    @Override\n    public boolean hasNext() {\n        return next != null;\n    }\n\n    @Override\n    public T next() {\n        T ret = next;\n        computeNext();\n        return ret;\n    }\n\n    private void computeNext() {\n        while (iterator.hasNext()) {\n            next = iterator.next();\n            if (!exclude(next)) return;\n        }\n        next = null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/HeapOperations.java",
    "content": "/*\n * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.utils;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.WeakHashMap;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.HeapProgress;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"HeapOperations_ComputingReferences=Computing References...\",\n    \"HeapOperations_ComputingGCRoots=Computing GC Roots...\",\n    \"HeapOperations_ComputingRetainedSizes=Computing Retained Sizes...\"\n})\npublic final class HeapOperations {\n    \n    private static Map<Heap, HeapOperations> INSTANCES;\n    \n    \n    private HeapOperations() {}\n    \n    \n    private static synchronized HeapOperations get(Heap heap) {\n        if (INSTANCES == null) INSTANCES = new WeakHashMap<>();\n\n        HeapOperations instance = INSTANCES.computeIfAbsent(heap, k -> new HeapOperations());\n\n        return instance;\n    }\n    \n    \n    public static void initializeReferences(Heap heap) throws InterruptedException {\n        get(heap).initializeReferencesImpl(heap);\n    }\n    \n    public static void initializeGCRoots(Heap heap) throws InterruptedException {\n        get(heap).initializeGCRootsImpl(heap);\n    }\n    \n    public static void initializeRetainedSizes(Heap heap) throws InterruptedException {\n        get(heap).initializeRetainedSizesImpl(heap);\n    }\n    \n    \n    // --- References ----------------------------------------------------------\n    \n    private volatile boolean referencesInitialized;\n    private volatile RequestProcessor.Task referencesComputer;\n    \n    private void initializeReferencesImpl(Heap heap) throws InterruptedException {\n        RequestProcessor.Task _referencesComputer;\n        \n        synchronized (this) {\n            if (referencesInitialized) return;\n            \n            if (referencesComputer == null) {\n                Runnable workerR = new Runnable() {\n                    public void run() {\n                        OpProgressHandle pHandle = null;\n\n                        try {\n                            pHandle = new OpProgressHandle(Bundle.HeapOperations_ComputingReferences());\n                            pHandle.setInitialDelay(1000);\n                            pHandle.start(HeapProgress.PROGRESS_MAX);\n\n                            pHandle.setProgress(0);\n\n                            Instance dummy = heap.getAllInstancesIterator().next();\n                            dummy.getReferences();\n                        } finally {\n                            if (pHandle != null) pHandle.finish();\n                        }\n\n                        synchronized (HeapOperations.this) {\n                            referencesInitialized = true;\n                            referencesComputer = null;\n                        }\n                    }\n                };\n                referencesComputer = new RequestProcessor(\"References Computer\").post(workerR); // NO18N\n                _referencesComputer = referencesComputer;\n            } else {\n                _referencesComputer = referencesComputer;\n            }\n        }\n        \n        assert !SwingUtilities.isEventDispatchThread();\n\n        _referencesComputer.waitFinished(0);\n    }\n    \n    \n    // --- GC Roots ------------------------------------------------------------\n    \n    private volatile boolean gcrootsInitialized;\n    private volatile RequestProcessor.Task gcrootsComputer;\n    \n    private void initializeGCRootsImpl(Heap heap) throws InterruptedException {\n        initializeReferencesImpl(heap);\n        \n        RequestProcessor.Task _gcrootsComputer;\n        \n        synchronized (this) {\n            if (gcrootsInitialized) return;\n            \n            if (gcrootsComputer == null) {\n                Runnable workerR = new Runnable() {\n                    public void run() {\n                        OpProgressHandle pHandle = null;\n\n                        try {\n                            pHandle = new OpProgressHandle(Bundle.HeapOperations_ComputingGCRoots());\n                            pHandle.setInitialDelay(1000);\n                            pHandle.start(HeapProgress.PROGRESS_MAX);\n\n                            pHandle.setProgress(0);\n\n                            Instance dummy = heap.getAllInstancesIterator().next();\n                            dummy.getNearestGCRootPointer();\n                        } finally {\n                            if (pHandle != null) pHandle.finish();\n                        }\n\n                        synchronized (HeapOperations.this) {\n                            gcrootsInitialized = true;\n                            gcrootsComputer = null;\n                        }\n                    }\n                };\n                gcrootsComputer = new RequestProcessor(\"GC Roots Computer\").post(workerR); // NO18N\n                _gcrootsComputer = gcrootsComputer;\n            } else {\n                _gcrootsComputer = gcrootsComputer;\n            }\n        }\n        \n        assert !SwingUtilities.isEventDispatchThread();\n\n        _gcrootsComputer.waitFinished(0);\n    }\n    \n    // --- Retained Sizes ------------------------------------------------------------\n    \n    private volatile boolean retainedInitialized;\n    private volatile RequestProcessor.Task retainedComputer;\n    \n    private void initializeRetainedSizesImpl(Heap heap) throws InterruptedException {\n        initializeGCRootsImpl(heap);\n        \n        RequestProcessor.Task _retainedComputer;\n        \n        synchronized (this) {\n            if (retainedInitialized) return;\n            \n            if (retainedComputer == null) {\n                Runnable workerR = new Runnable() {\n                    public void run() {\n                        OpProgressHandle pHandle = null;\n\n                        try {\n                            pHandle = new OpProgressHandle(Bundle.HeapOperations_ComputingRetainedSizes());\n                            pHandle.setInitialDelay(1000);\n                            pHandle.start();\n\n                            pHandle.setRetainedSizesProgress(HeapProgress.PROGRESS_MAX, 3*HeapProgress.PROGRESS_MAX);\n\n                            Instance dummy = heap.getAllInstancesIterator().next();\n                            dummy.getRetainedSize();\n\n                            pHandle.setProgress(2*HeapProgress.PROGRESS_MAX);\n\n                            List<JavaClass> classes = heap.getAllClasses();\n                            if (!classes.isEmpty()) classes.get(0).getRetainedSizeByClass();\n                        } finally {\n                            if (pHandle != null) pHandle.finish();\n                        }\n\n                        synchronized (HeapOperations.this) {\n                            retainedInitialized = true;\n                            retainedComputer = null;\n                        }\n                    }\n                };\n                retainedComputer = new RequestProcessor(\"Retained Sizes Computer\").post(workerR); // NO18N\n                _retainedComputer = retainedComputer;\n            } else {\n                _retainedComputer = retainedComputer;\n            }\n        }\n        \n        assert !SwingUtilities.isEventDispatchThread();\n\n        _retainedComputer.waitFinished(0);\n    }\n\n    public static class OpProgressHandle {\n\n        private final ProgressHandle handle;\n        private Timer timer;\n\n        public OpProgressHandle(String displayName) {\n            handle = ProgressHandle.createHandle(displayName);\n        }\n\n        public void setInitialDelay(int millis) {\n            handle.setInitialDelay(millis);\n        }\n\n        public void start() {\n            handle.start();\n        }\n\n        public void start(int workunits) {\n            handle.start(workunits);\n        }\n\n        public void setProgress(final int offset) {\n            final long progressId = HeapProgress.getProgressId();\n\n            if (timer != null) timer.stop();\n            timer = new Timer(1500, new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    int value = HeapProgress.getProgressValue(progressId);\n                    if (value >= 0) {\n                        handle.progress(value + offset);\n                    } else {\n                        timer.stop();\n                    }\n                }\n            });\n            timer.start();\n        }\n\n        private void setRetainedSizesProgress(final int offset, final int workunits) {\n            final long progressId = HeapProgress.getProgressId();\n\n            timer = new Timer(1500, new ActionListener() {\n                boolean switchedToDeterminate;\n\n                public void actionPerformed(ActionEvent e) {\n                    if (!switchedToDeterminate) {\n                        handle.switchToDeterminate(workunits);\n                        switchedToDeterminate = true;\n                    }\n                    int value = HeapProgress.getProgressValue(progressId);\n                    if (value >= 0) {\n                        handle.progress(value + offset);\n                    } else {\n                        timer.stop();\n                    }\n                }\n            });\n            timer.start();\n        }\n\n        public void finish() {\n            if (timer != null) timer.stop();\n            handle.finish();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/HeapUtils.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.utils;\n\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"HeapUtils_UnknownClass=unknown class\",\n    \"HeapUtils_UnknownInstance=unknown instance\",\n    \"HeapUtils_Class=class\",\n    \"HeapUtils_OomeCaption=Out Of Memory\",\n    \"HeapUtils_OomeMsg=<html><b>Not enough memory to finish the operation.</b><br/><br/>To avoid this error please increase the -Xmx value<br>in the etc/visualvm.conf file in VisualVM directory.</html>\"\n}) \npublic final class HeapUtils {\n    \n   // --- Heap utils ----------------------------------------------------------\n    \n    public static Collection<JavaClass> getSubclasses(Heap heap, String baseClass) {\n        Set<JavaClass> subclasses = new HashSet<>();\n\n        String escapedClassName = \"\\\\Q\" + baseClass + \"\\\\E\"; // NOI18N\n        Collection<JavaClass> jClasses = heap.getJavaClassesByRegExp(escapedClassName);\n\n        for (JavaClass jClass : jClasses) {\n            subclasses.add(jClass);\n            subclasses.addAll(jClass.getSubClasses());\n        }\n        \n        return subclasses;\n    }\n    \n    public static Iterator<Instance> instancesIterator(Collection<JavaClass> classes) {\n        return new InstancesIterator(classes);\n    }\n    \n//    public static Map<String, Object> getValuesOfFields(Instance instance, String... fields) {\n//        Map<String, Object> values = new HashMap<>();\n//        for (String field : fields) values.put(field, null);\n//        \n//        List<FieldValue> fieldValues = instance.getFieldValues();\n//        for (FieldValue fieldValue : fieldValues) {\n//            String fieldName = fieldValue.getField().getName();\n//            if (values.containsKey(fieldName)) {\n//                Object value = fieldValue instanceof ObjectFieldValue ? ((ObjectFieldValue)fieldValue).getInstance() : fieldValue.getValue();\n//                values.put(fieldName, value);\n//            }\n////            Object value = fieldValue instanceof ObjectFieldValue ? ((ObjectFieldValue)fieldValue).getInstance() : fieldValue.getValue();\n////            values.replace(fieldValue.getField().getName(), value);\n//        }\n//    \n//        return values;\n//    }\n    \n    \n    public static Object[] getValuesOfFields(Instance instance, String... fields) {\n        Object[] values = new Object[fields.length];\n        \n        Map<String, Integer> fieldsM = new HashMap<>();\n        for (int i = 0; i < fields.length; i++) fieldsM.put(fields[i], i);\n        \n        List<FieldValue> fieldValues = instance.getFieldValues();\n        for (int i = fieldValues.size() - 1; i >= 0; i--) {\n            FieldValue fieldValue = fieldValues.get(i);\n            String fieldName = fieldValue.getField().getName();\n            Integer valueIdx = fieldsM.remove(fieldName);\n            if (valueIdx != null) {\n                Object value = fieldValue instanceof ObjectFieldValue ? ((ObjectFieldValue)fieldValue).getInstance() : fieldValue.getValue();\n                values[valueIdx] = value;\n                if (fieldsM.isEmpty()) break;\n            }\n//            Object value = fieldValue instanceof ObjectFieldValue ? ((ObjectFieldValue)fieldValue).getInstance() : fieldValue.getValue();\n//            values.replace(fieldValue.getField().getName(), value);\n        }\n        \n        return values;\n    }\n    \n    \n    // --- Heap <-> HTML utils -------------------------------------------------\n    \n    private static final String CLASS_URL_PREFIX = \"file://class/\"; // NOI18N\n    private static final String INSTANCE_URL_PREFIX = \"file://instance/\"; // NOI18N\n    \n    \n    public static String classToHtml(JavaClass javaClass) {\n        return classToHtml(javaClass, null);\n    }\n    \n    private static String classToHtml(JavaClass javaClass, String prefix) {\n        if (javaClass == null) return Bundle.HeapUtils_UnknownClass();\n\n        long id = javaClass.getJavaClassId();\n        return \"<a href='\" + CLASS_URL_PREFIX + id + \"' name='\" + id + \"'>\" + (prefix == null ? \"\" : prefix) + javaClass.getName() + \"</a>\"; // NOI18N\n    }\n    \n    public static boolean isClass(String html) {\n        return html.startsWith(CLASS_URL_PREFIX);\n    }\n    \n    public static JavaClass classFromHtml(String html, Heap heap) {\n//        if (!isClass(html)) return null;\n        String classIdS = html.substring(CLASS_URL_PREFIX.length());\n        try {\n            long classId = Long.parseLong(classIdS);\n            return heap.getJavaClassByID(classId);\n        } catch (NumberFormatException e) {\n            return null;\n        }\n    }\n    \n    public static String instanceToHtml(Instance instance, boolean logicalValue, JavaClass javaClassClass) {\n        if (instance == null) return Bundle.HeapUtils_UnknownInstance();\n        \n        JavaClass jcls = instance.getJavaClass();\n        if (jcls == null) return Bundle.HeapUtils_UnknownInstance() + \" #\" + instance.getInstanceId(); // NOI18N\n        \n        if (jcls.equals(javaClassClass)) {\n            Heap heap = jcls.getHeap();\n            JavaClass javaClass = heap.getJavaClassByID(instance.getInstanceId());\n            if (javaClass != null) return classToHtml(javaClass, Bundle.HeapUtils_Class() + \" \"); // NOI18N\n        }\n        \n        long id = instance.getInstanceId();\n        String instanceHtml = \"<a href='\" + INSTANCE_URL_PREFIX + id + \"' name='\" + id + \"'>\" + jcls.getName() + '#' + instance.getInstanceNumber() + \"</a>\"; // NOI18N\n        if (!logicalValue) return instanceHtml;\n        \n        String details = DetailsUtils.getInstanceString(instance);\n        if (details == null) return instanceHtml;\n        \n        details = \"<span style=\\\"color: #666666\\\"> : \" + htmlize(details) + \"</span>\"; // NOI18N\n        return instanceHtml + details;\n    }\n    \n    public static boolean isInstance(String html) {\n        return html.startsWith(INSTANCE_URL_PREFIX);\n    }\n    \n    public static Instance instanceFromHtml(String html, Heap heap) {\n//        if (!isInstance(html)) return null;\n        String classIdS = html.substring(INSTANCE_URL_PREFIX.length());\n        try {\n            long classId = Long.parseLong(classIdS);\n            return heap.getInstanceByID(classId);\n        } catch (NumberFormatException e) {\n            return null;\n        }\n    }\n    \n    \n    public static String htmlize(String text) {\n        if (text == null) return null;\n        return text.replace(\">\", \"&gt;\").replace(\"<\", \"&lt;\"); // NOI18N\n    }\n    \n    \n    // --- OOME handling -------------------------------------------------------\n    \n    private static boolean OOME_NOTIFIED = false;\n    \n    public static void handleOOME(final boolean skipSuccessive, OutOfMemoryError e) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (!OOME_NOTIFIED || !skipSuccessive) {\n                    OOME_NOTIFIED = true;\n                    ProfilerDialogs.displayError(Bundle.HeapUtils_OomeMsg(), Bundle.HeapUtils_OomeCaption(), null);\n                    // NOTE: might update the Xmx automatically and/or lower MoreObjectsNode.MAX_BUFFER_SIZE\n                    //                                              (won't work for OOMEs from merged references etc.)\n                }\n            }\n        });\n    }\n    \n    \n    // --- Private stuff -------------------------------------------------------\n    \n    private HeapUtils() {}\n    \n    \n    private static class InstancesIterator implements Iterator<Instance> {\n        \n        private final Iterator<JavaClass> classIt;\n        private Iterator<Instance> instanceIt;\n\n        InstancesIterator(Collection<JavaClass> cls) {\n            classIt = cls.iterator();\n            instanceIt = Collections.EMPTY_LIST.iterator();\n        }\n\n        @Override\n        public boolean hasNext() {\n            if (instanceIt.hasNext()) return true;\n            if (!classIt.hasNext()) return false;\n            \n            instanceIt = classIt.next().getInstancesIterator();\n            return hasNext();\n        }\n\n        @Override\n        public Instance next() {\n            return instanceIt.next();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/InterruptibleIterator.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.utils;\n\nimport java.util.Iterator;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class InterruptibleIterator<T> implements Iterator<T> {\n    \n    private final Iterator<T> iterator;\n    \n    \n    public InterruptibleIterator(Iterator<T> iterator) {\n        this.iterator = iterator;\n    }\n\n    \n    @Override\n    public boolean hasNext() {\n        return !Thread.currentThread().isInterrupted() && iterator.hasNext();\n    }\n\n    @Override\n    public T next() {\n        return iterator.next();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/MoreObjectsNode.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.utils;\n\nimport java.awt.event.ActionEvent;\nimport java.text.Format;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Random;\nimport java.util.SortedSet;\nimport java.util.TreeSet;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.MoreNodesNode;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"MoreObjectsNode_SamplesContainer=<sample {0} objects>\",\n    \"MoreObjectsNode_NodesContainer=<objects {0}-{1}>\"\n})\nabstract class MoreObjectsNode<T> extends MoreNodesNode {\n    \n    private static final int AGGREGATION = 1000;\n    private static final int MAX_BUFFER_SIZE = 1000000;\n    \n    private T[] previousObjects;\n    private final T previousObject;\n    private final int previousObjectOffset;\n    private int lastKnownPreviousObjectIndex;\n    \n    private final int objectsCount;\n    private final int iteratorObjectsCount;\n    \n    private final int nodesCount;\n    private final int nodesOffset;\n    \n    \n    MoreObjectsNode(String text, int objectsCount, int iteratorObjectsCount, T previousObject, int previousObjectOffset) {\n        super(text);\n        \n        this.objectsCount = objectsCount;\n        this.iteratorObjectsCount = iteratorObjectsCount;\n        \n        this.nodesCount = (int)Math.ceil((objectsCount - previousObjectOffset + 1) / (double)AGGREGATION);\n        nodesOffset = (int)Math.floor((previousObjectOffset + 1) / (double)AGGREGATION);\n        \n        this.previousObject = previousObject;\n        this.previousObjectOffset = previousObjectOffset;\n        \n        resetChildren();\n    }\n    \n    \n    protected abstract boolean sorts(DataType dataType);\n    \n    protected abstract HeapViewerNode createNode(T object);\n    \n    // Preferably a ProgressIterator or its wrapper updating the progress\n    protected abstract Iterator<T> objectsIterator(int index, Progress progress);\n    \n    \n    protected String getSamplesContainerString(String objectsCount)  {\n        return Bundle.MoreObjectsNode_SamplesContainer(objectsCount);\n    }\n    \n    protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n        return Bundle.MoreObjectsNode_NodesContainer(firstNodeIdx, lastNodeIdx);\n    }\n    \n    \n    protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        lastKnownPreviousObjectIndex = -1;\n        \n        if (nodesCount == 1) {\n            return computeChildren(-1, heap, viewID, null, dataTypes, sortOrders, progress);\n        } else {\n            previousObjects = (T[])new Object[nodesCount - 1];\n            \n            Format format = Formatters.numberFormat();\n            \n            int containersOffset = objectsCount >= UIThresholds.SAMPLE_OBJECTS_THRESHOLD ? 1 : 0;\n            HeapViewerNode[] nodes = new HeapViewerNode[nodesCount + containersOffset];\n            \n            for (int i = 0; i < nodesCount; i++) {\n                int firstItem = getFirstItemIndex(i) + 1;\n                int lastItem = getLastItemIndex(i) + 1;\n                nodes[i + containersOffset] = new ObjectsContainer(getNodesContainerString(format.format(firstItem), format.format(lastItem)), i);\n            }\n            \n            if (containersOffset > 0) nodes[0] = new SampleContainer(getSamplesContainerString(format.format(UIThresholds.SAMPLE_OBJECTS_COUNT)), UIThresholds.SAMPLE_OBJECTS_COUNT);\n            \n            return nodes;\n        }\n    }\n    \n    \n    private T getPreviousObject(int containerIndex, Heap heap, HeapViewerNodeFilter viewFilter, DataType dataType, SortOrder sortOrder, Progress progress) throws InterruptedException {\n        if (containerIndex <= 0) return previousObject;\n        \n        T object = previousObjects[containerIndex - 1];\n        if (object != null) return object;\n        \n        int steps = containerIndex - lastKnownPreviousObjectIndex - 1; /*System.err.println(\">>> steps \" + steps);*/\n        int bufferSize = (steps + nodesOffset) * AGGREGATION;\n        if (lastKnownPreviousObjectIndex == -1) bufferSize -= (previousObjectOffset + 1); /*System.err.println(\">>> bufferSize \" + bufferSize);*/\n//        System.err.println(\">>>   XXX bufferSize \" + bufferSize);\n        \n        if (bufferSize > MAX_BUFFER_SIZE) {\n            // -----------------------------------------------------------------\n            // --- TODO:\n            // ---  - improve to minimize bufferIterations (include the result for long[] getInstanceIDs)\n            // ---  - improve to revert the sortOrder for second half of the results\n            // -----------------------------------------------------------------\n            \n//            System.err.println(\">>> bufferSize \" + bufferSize + \", MAX_BUFFER_SIZE \" + MAX_BUFFER_SIZE);\n            int bufferIterations = bufferSize / MAX_BUFFER_SIZE;\n            if (bufferIterations * MAX_BUFFER_SIZE < bufferSize) bufferIterations += 1;\n//            System.err.println(\">>> containerIndex \" + containerIndex + \", lastInstanceIDIndex \" + lastInstanceIDIndex + \", bufferSize \" + bufferSize + \", bufferIterations \" + bufferIterations);\n            int bufferDelta = steps / bufferIterations;\n//            System.err.println(\">>> bufferDelta \" + bufferDelta);\n\n            Thread worker = Thread.currentThread();\n            \n            int lastInstanceIDIndexX = lastKnownPreviousObjectIndex;\n            for (int i = 1; i <= bufferIterations; i++) {\n                getPreviousObject(lastInstanceIDIndexX + bufferDelta * i, heap, viewFilter, dataType, sortOrder, progress);\n                if (worker.isInterrupted()) throw new InterruptedException();\n            }\n            \n            return getPreviousObject(containerIndex, heap, viewFilter, dataType, sortOrder, progress);\n        } else {\n            object = lastKnownPreviousObjectIndex == -1 ? previousObject : previousObjects[lastKnownPreviousObjectIndex]; /*System.err.println(\">>> instance \" + new InstanceNode(heap.getInstanceByID(instance)));*/\n\n            SortedObjectsBuffer<T> buffer = new SortedObjectsBuffer<T>(bufferSize, object, dataType, sortOrder, viewFilter, heap, getParent()) {\n                protected boolean sorts(DataType dataType) { return MoreObjectsNode.this.sorts(dataType); }\n                protected HeapViewerNode createNode(T object) { return MoreObjectsNode.this.createNode(object); }\n            };\n            \n//            progress.setupKnownSteps(iteratorObjectsCount);\n            \n            Iterator<T> objectsIt = objectsIterator(0, progress);\n            while (objectsIt.hasNext()) buffer.add(objectsIt.next());\n            \n            if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n            \n            T[] objects = buffer.getObjects();\n            \n//            progress.finish();\n            \n            int offset = lastKnownPreviousObjectIndex == -1 ? -previousObjectOffset - 1 : 0; /*System.err.println(\">>> offset in results \" + offset);*/\n            for (int i = 0; i < steps; i++) {\n                int resultsIndex = (i + 1 + nodesOffset) * AGGREGATION + offset - 1; /*System.err.println(\">>>    resultsIndex \" + resultsIndex);*/\n                int updatedIndex = lastKnownPreviousObjectIndex + 1 + i; /*System.err.println(\">>>    updatedIndex \" + updatedIndex);*/\n                previousObjects[updatedIndex] = objects[resultsIndex];\n            }\n\n            lastKnownPreviousObjectIndex = containerIndex - 1; /*System.err.println(\">>> lastInstanceIDIndex \" + lastInstanceIDIndex);*/\n            return previousObjects[containerIndex - 1];\n        }\n    }\n    \n    private T[] getObjects(int containerIndex, Heap heap, HeapViewerNodeFilter viewFilter, DataType dataType, SortOrder sortOrder, Progress progress) throws InterruptedException {\n        int start = MoreObjectsNode.this.getFirstItemIndex(containerIndex);\n        int end = MoreObjectsNode.this.getLastItemIndex(containerIndex);\n        \n        T object;\n        \n        try {\n            progress.setupUnknownSteps();\n            \n            object = getPreviousObject(containerIndex, heap, viewFilter, dataType, sortOrder, progress);\n        } finally {\n            progress.finish();\n        }\n        \n        SortedObjectsBuffer<T> buffer = new SortedObjectsBuffer<T>(end - start + 1, object, dataType, sortOrder, viewFilter, heap, getParent()) {\n            protected boolean sorts(DataType dataType) { return MoreObjectsNode.this.sorts(dataType); }\n            protected HeapViewerNode createNode(T object) { return MoreObjectsNode.this.createNode(object); }\n        };\n        \n        T[] objects;\n        \n        try {\n            progress.setupKnownSteps(iteratorObjectsCount);\n            \n            Iterator<T> objectsIt = objectsIterator(0, progress);\n            while (objectsIt.hasNext()) buffer.add(objectsIt.next());\n            \n            if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n            \n            objects = buffer.getObjects();\n        } finally {        \n            progress.finish();\n        }\n        \n        if (containerIndex >= 0 && containerIndex < nodesCount - 1) {\n            if (previousObjects[containerIndex] == null) {\n                previousObjects[containerIndex] = objects[objects.length - 1];\n                lastKnownPreviousObjectIndex = containerIndex;\n            }\n        }\n        \n        return objects;\n    }\n    \n    private int getFirstItemIndex(int containerIndex) {\n        return containerIndex <= 0 ? previousObjectOffset + 1 : AGGREGATION * (containerIndex + nodesOffset);\n    }\n    \n    private int getLastItemIndex(int containerIndex) {\n        return containerIndex >= 0 && containerIndex < nodesCount - 1 ? AGGREGATION * (containerIndex + 1 + nodesOffset) - 1 : objectsCount - 1;\n    }\n    \n    private HeapViewerNode[] loadChildren(int containerIndex, Progress progress) throws InterruptedException {\n        int start = MoreObjectsNode.this.getFirstItemIndex(containerIndex);\n        int end = MoreObjectsNode.this.getLastItemIndex(containerIndex);\n        \n        HeapViewerNode[] nodes;\n        \n        try {\n            progress.setupKnownSteps(end);\n            \n            int i = 0;\n            nodes = new HeapViewerNode[end - start + 1];\n            Iterator<T> objectsIt = objectsIterator(start, progress);\n            while (i < nodes.length && objectsIt.hasNext()) nodes[i++] = createNode(objectsIt.next());\n            \n            if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n        } finally {        \n            progress.finish();\n        }\n\n        return nodes;\n    }\n    \n    private HeapViewerNode[] computeChildren(int containerIndex, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {            \n//        long start = System.currentTimeMillis();\n//        try {\n        \n        // No sorting - plain fetch\n        SortOrder sortOrder = sortOrders == null || sortOrders.isEmpty() ? null : sortOrders.get(0);\n        if (sortOrder == null || sortOrder.equals(SortOrder.UNSORTED)) return MoreObjectsNode.this.loadChildren(containerIndex, progress);\n\n        // Sorting by count or own size - plain fetch\n        DataType dataType = dataTypes == null || dataTypes.isEmpty() ? null : dataTypes.get(0);\n        if (dataType == null || !sorts(dataType)) return MoreObjectsNode.this.loadChildren(containerIndex, progress);\n\n        // Sorting - must resolve instanceIDs\n        T[] objects = MoreObjectsNode.this.getObjects(containerIndex, heap, null, dataType, sortOrder, progress);\n        \n//        System.err.println(\">>> Children: \" + Arrays.toString(objects));\n        Thread worker = Thread.currentThread();\n        HeapViewerNode[] nodes = new HeapViewerNode[objects.length];\n        for (int i = 0; i < nodes.length; i++) {\n//            System.err.println(\">>> Creating node at idx \" + i + \" from object \" + objects[i]);\n            nodes[i] = createNode(objects[i]);\n            if (worker.isInterrupted()) throw new InterruptedException();\n        }\n\n        return nodes;\n        \n//        } finally {\n//            System.err.println(\">>> Container \" + containerIndex + \" computed in \" + (System.currentTimeMillis() - start));\n//        }\n    }\n    \n    private HeapViewerNode[] computeSampleChildren(int type, int count, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        // TODO: use random-access for indexable version\n        int index = 0;\n        int step = objectsCount / (count - 1);\n        \n        HeapViewerNode[] nodes;\n        \n        try {\n            progress.setupKnownSteps(iteratorObjectsCount);\n            \n            int i = 0;\n            Integer[] indexes = new Integer[count];\n            if (type == 0) {\n                int hitIndex = 0;\n                for (int j = 0; j < count; j++) {\n                    indexes[j] = hitIndex;\n                    hitIndex = j == count - 2 ? objectsCount - 1 : hitIndex + step;\n                }\n            } else {\n                Random r = new Random(type*7);\n                SortedSet<Integer> idSet = new TreeSet<>();\n                while (idSet.size() < count) {\n                     idSet.add(r.nextInt(objectsCount));\n                }\n                idSet.toArray(indexes);\n            }\n            nodes = new HeapViewerNode[count];\n            Iterator<T> objectsIt = objectsIterator(0, progress);\n            while (index < count && i < objectsCount && objectsIt.hasNext()) {\n                T object = objectsIt.next();\n\n                if (i == indexes[index]) {\n                    nodes[index++] = createNode(object);\n                }\n                \n                i++;\n            }\n\n            if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n        } finally {\n            progress.finish();\n        }\n        \n        return nodes;\n    }\n    \n    \n    private class SampleContainer extends TextNode {\n        \n        private final int count;\n        private int type;\n        \n        SampleContainer(String text, int count) {\n            super(text);\n            this.count = count;\n            resetChildren();\n        }\n        \n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {            \n            return MoreObjectsNode.this.computeSampleChildren(type, count, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n        }\n        \n        void incrementType() {\n            type++;\n            resetChildren();\n            RootNode root = RootNode.get(this);\n            if (root != null) {\n                // clear node cache\n                root.retrieveChildren(this);\n                root.updateChildren(root);\n            }\n        }\n    }\n    \n    @ServiceProvider(service=HeapViewerNodeAction.Provider.class)\n    public static class ShuffleActionProvider extends HeapViewerNodeAction.Provider {\n\n        @Override\n        public boolean supportsView(HeapContext context, String viewID) {\n            return true;\n        }\n\n        @Override\n        public HeapViewerNodeAction[] getActions(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n            if (node instanceof MoreObjectsNode.SampleContainer) {\n                return new HeapViewerNodeAction[]{new ShuffleAction((MoreObjectsNode.SampleContainer)node)};\n            }\n            return null;\n        }\n    }\n\n    @NbBundle.Messages(\"MoreObjectsNode_ShuffleAction=Different Sample\")\n    private static class ShuffleAction extends HeapViewerNodeAction {\n\n        private final MoreObjectsNode.SampleContainer node;\n\n        ShuffleAction(MoreObjectsNode.SampleContainer node) {\n            super(org.graalvm.visualvm.heapviewer.utils.Bundle.MoreObjectsNode_ShuffleAction(), 110);\n            this.node = node;\n            setEnabled(!node.isLeaf());\n        }\n\n        public boolean isMiddleButtonDefault(ActionEvent e) {\n            int modifiers = e.getModifiers();\n            return (modifiers & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK &&\n                   (modifiers & ActionEvent.SHIFT_MASK) != ActionEvent.SHIFT_MASK;\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            node.incrementType();\n        }\n    }\n\n    private class ObjectsContainer extends TextNode {\n        \n        private final int containerIndex;\n    \n        ObjectsContainer(String text, int containerIndex) {\n            super(text);\n            this.containerIndex = containerIndex;\n            resetChildren();\n        }\n        \n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {            \n            return MoreObjectsNode.this.computeChildren(containerIndex, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n        }\n    \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/NodesComputer.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.utils;\n\nimport java.text.Format;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"NodesComputer_MoreNodes=<another {0} objects left>\",\n    \"NodesComputer_SamplesContainer=<sample {0} objects>\",\n    \"NodesComputer_NodesContainer=<objects {0}-{1}>\"\n})\npublic abstract class NodesComputer<T> {\n    \n    private static final int EXTRA_ALLOWED_ITEMS = 10;\n    \n    private final int itemsCount;\n    private final int maxItemsCount;\n    \n    \n    public NodesComputer(int maxItemsCount) {\n        this(Integer.MAX_VALUE, maxItemsCount);\n    }\n    \n    // TODO: itemsCount may be long, disable random access and provide just <next N objects>\n    public NodesComputer(int itemsCount, int maxItemsCount) {\n        this.itemsCount = itemsCount;\n        this.maxItemsCount = maxItemsCount;\n    }\n    \n    \n    protected abstract boolean sorts(DataType dataType);\n    \n    protected abstract HeapViewerNode createNode(T object);\n    \n    protected abstract ProgressIterator<T> objectsIterator(int index, Progress progress);\n    \n    \n    protected String getMoreNodesString(String moreNodesCount)  {\n        return Bundle.NodesComputer_MoreNodes(moreNodesCount);\n    }\n    \n    protected String getSamplesContainerString(String objectsCount)  {\n        return Bundle.NodesComputer_SamplesContainer(objectsCount);\n    }\n    \n    protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n        return Bundle.NodesComputer_NodesContainer(firstNodeIdx, lastNodeIdx);\n    }\n    \n    \n    public HeapViewerNode[] computeNodes(HeapViewerNode parent, final Heap heap, String viewID, final HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        if (itemsCount <= (maxItemsCount + EXTRA_ALLOWED_ITEMS)) {\n            // All objects unsorted\n            int i = 0;\n            HeapViewerNode[] nodes = new HeapViewerNode[itemsCount];\n            Iterator<HeapViewerNode> nodesIt = nodesIterator(0, viewFilter, heap, progress);\n            // Do not count progress, expected to perform fast\n            while (nodesIt.hasNext()) nodes[i++] = nodesIt.next();\n            \n            if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n            \n            if (i < itemsCount) nodes = Arrays.copyOf(nodes, i);\n            return nodes;\n        } else {\n            // First N objects\n            DataType dataType = dataTypes == null || dataTypes.isEmpty() ? null : dataTypes.get(0);\n            if (dataType != null && !sorts(dataType)) dataType = null;\n            \n            SortOrder sortOrder = dataType == null || sortOrders == null || sortOrders.isEmpty() ? null : sortOrders.get(0);\n            \n            if (itemsCount < Integer.MAX_VALUE && viewFilter == null && (dataType == null || sortOrder == null || SortOrder.UNSORTED.equals(sortOrder))) {\n                // First N objects unsorted\n                int i = 0;\n                HeapViewerNode[] nodes = new HeapViewerNode[maxItemsCount + 1];\n                NodesIterator nodesIt = nodesIterator(0, viewFilter, heap, progress);\n                // Do not count progress, expected to perform fast\n                while (i < maxItemsCount && nodesIt.hasNext()) nodes[i++] = nodesIt.next();\n                \n                if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n                \n                Format format = Formatters.numberFormat();\n                String moreNodesString = getMoreNodesString(format.format(itemsCount - maxItemsCount));\n                nodes[maxItemsCount] = new MoreObjectsNode<T>(moreNodesString, itemsCount, itemsCount, nodesIt.nextObject, maxItemsCount - 1) {\n                    protected boolean sorts(DataType dataType) {\n                        return NodesComputer.this.sorts(dataType);\n                    }\n                    protected HeapViewerNode createNode(T object) {\n                        return NodesComputer.this.createNode(object);\n                    }\n                    protected Iterator<T> objectsIterator(int index, Progress progress) {\n                        return NodesComputer.this.objectsIterator(index, 0, -1, viewFilter, heap, progress);\n                    }\n                    protected String getSamplesContainerString(String objectsCount)  {\n                        return NodesComputer.this.getSamplesContainerString(objectsCount);\n                    }\n                    protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                        return NodesComputer.this.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n                    }\n                };\n                \n                return nodes;\n            } else {\n                // First N objects according to the provided sorting\n                SortedObjectsBuffer<T> buffer = new SortedObjectsBuffer<T>(maxItemsCount, null, dataType, sortOrder, null, heap, parent) {\n                    protected boolean sorts(DataType dataType) { return NodesComputer.this.sorts(dataType); }\n                    protected HeapViewerNode createNode(T object) { return NodesComputer.this.createNode(object); }\n                };\n                \n                ObjectsIterator objectsIt;\n                T[] objects;\n                \n                try {\n                    if (itemsCount == Integer.MAX_VALUE) progress.setupUnknownSteps();\n                    else progress.setupKnownSteps(itemsCount);\n                    \n                    objectsIt = objectsIterator(0, 0, -1, viewFilter, heap, progress);\n                    while (objectsIt.hasNext()) buffer.add(objectsIt.next());\n\n                    if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n\n                    objects = buffer.getObjects();\n                } finally {                \n                    progress.finish();\n                }\n                \n                int objectsCount = objects.length;\n//                final int totalObjectsCount = buffer.getTotalObjects();\n                final int totalOwnItems = objectsIt.getTotalOwnItems();\n                if (objectsCount == totalOwnItems) {\n                    // No MoreNodesNode needed\n                    HeapViewerNode[] nodes = new HeapViewerNode[objectsCount];\n                    for (int i = 0; i < objectsCount; i++) nodes[i] = createNode(objects[i]);\n                    return nodes;\n                } else {\n                    // ModeNodesNode needed\n                    HeapViewerNode[] nodes = new HeapViewerNode[objectsCount + 1];\n                    T lastObject = null;\n                    for (int i = 0; i < objectsCount; i++) {\n                        nodes[i] = createNode(objects[i]);\n                        if (i == maxItemsCount - 1) lastObject = objects[i];\n                    }\n                    \n                    final int firstOwnItem = objectsIt.getFirstOwnItem();\n\n                    Format format = Formatters.numberFormat();\n                    String moreNodesString = getMoreNodesString(format.format(totalOwnItems - maxItemsCount));\n                    nodes[objectsCount] = new MoreObjectsNode<T>(moreNodesString, totalOwnItems, objectsIt.getTotalItems(), lastObject, objectsCount - 1) {\n                        protected boolean sorts(DataType dataType) {\n                            return NodesComputer.this.sorts(dataType);\n                        }\n                        protected HeapViewerNode createNode(T object) {\n                            return NodesComputer.this.createNode(object);\n                        }\n                        protected Iterator<T> objectsIterator(int index, Progress progress) {\n                            return NodesComputer.this.objectsIterator(index, firstOwnItem, totalOwnItems, viewFilter, heap, progress);\n                        }\n                        protected String getSamplesContainerString(String objectsCount)  {\n                            return NodesComputer.this.getSamplesContainerString(objectsCount);\n                        }\n                        protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                            return NodesComputer.this.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n                        }\n                    };\n\n                    return nodes;\n                }\n            }\n        }\n    }\n    \n    \n    public static Iterator<Integer> integerIterator(final int start, final int end) {\n        return new Iterator<Integer>() {\n            private int value = start;\n            private final int endValue = end;\n            public boolean hasNext() { return value < endValue; }\n            public Integer next() { return value++; }\n        };\n    }\n    \n    \n    private ObjectsIterator objectsIterator(int index, int knownInnerStart, int knownOuterCount, HeapViewerNodeFilter viewFilter, Heap heap, Progress progress) {\n        return viewFilter == null ? new PlainObjectsIterator(index, progress) :\n               new FilteredObjectsIterator(index, knownInnerStart <= 0 ? 0 : knownInnerStart - 1, knownOuterCount, viewFilter, heap, progress);\n    }\n    \n    private NodesIterator nodesIterator(int index, HeapViewerNodeFilter viewFilter, Heap heap, Progress progress) {\n        return viewFilter == null ? new PlainNodesIterator(index, progress) :\n               new FilteredNodesIterator(index, viewFilter, heap, progress);\n    }\n    \n    \n    private abstract class ObjectsIterator implements Iterator<T> {\n        \n        int totalItems;\n        \n        int firstOwnItem;\n        int totalOwnItems;\n        \n        int getTotalItems() { return totalItems; }\n        \n        int getFirstOwnItem() { return firstOwnItem; }\n        int getTotalOwnItems() { return totalOwnItems; }\n    }\n    \n    private class PlainObjectsIterator extends ObjectsIterator {\n        \n        private final Iterator<T> iterator;\n        \n        PlainObjectsIterator(int index, Progress progress) {\n            this.iterator = new InterruptibleIterator<>(objectsIterator(index, progress));\n            totalItems = index;\n            firstOwnItem = index;\n        }\n        \n        public boolean hasNext() {\n            return iterator.hasNext();\n        }\n        \n        public T next() {\n            totalItems++;\n            totalOwnItems++;\n            return iterator.next();\n        }\n        \n    }\n    \n    private class FilteredObjectsIterator extends ObjectsIterator {\n        \n        private final Iterator<T> iterator;\n        private final int knownTotalOwnItems;\n        \n        private final HeapViewerNodeFilter viewFilter;\n        private final Heap heap;\n        \n        private T nextObject;\n        \n        FilteredObjectsIterator(int index, int knownFirstOwnItem, int knownTotalOwnItems, HeapViewerNodeFilter viewFilter, Heap heap, Progress progress) {\n            this.iterator = new InterruptibleIterator<>(objectsIterator(knownFirstOwnItem, progress));\n            this.knownTotalOwnItems = knownTotalOwnItems;\n            \n            this.viewFilter = viewFilter;\n            this.heap = heap;\n            \n            firstOwnItem = -1;\n            while (index-- > 0) hasNext();\n        }\n        \n        // NOTE: must always be called before next() to compute the next value!\n        public boolean hasNext() {\n            if (knownTotalOwnItems >= 0 && knownTotalOwnItems == totalOwnItems) return false;\n            nextObject = nextObject();\n            return nextObject != null;\n        }\n        \n        public T next() {\n            totalOwnItems++;\n            return nextObject;\n        }\n        \n        private T nextObject() {\n            while (iterator.hasNext()) {\n                totalItems++;\n                T object = iterator.next();\n                HeapViewerNode node = createNode(object);\n                if (viewFilter.passes(node, heap)) {\n                    if (firstOwnItem == -1) firstOwnItem = totalItems;\n                    return object;\n                }\n            }\n            return null;\n        }\n        \n    }\n    \n    \n    private abstract class NodesIterator implements Iterator<HeapViewerNode> {\n        \n        T nextObject;\n        \n        T nextObject() { return nextObject; }\n        \n    }\n    \n    private class PlainNodesIterator extends NodesIterator {\n        \n        private final Iterator<T> iterator;\n        \n        PlainNodesIterator(int index, Progress progress) {\n            this.iterator = new InterruptibleIterator<>(objectsIterator(index, progress));\n        }\n        \n        public boolean hasNext() {\n            return iterator.hasNext();\n        }\n        \n        public HeapViewerNode next() {\n            nextObject = iterator.next();\n            return createNode(nextObject);\n        }\n        \n    }\n    \n    private class FilteredNodesIterator extends NodesIterator {\n        \n        private final Iterator<T> iterator;\n        \n        private final HeapViewerNodeFilter viewFilter;\n        private final Heap heap;\n        \n        private HeapViewerNode nextNode;\n        \n        FilteredNodesIterator(int index, HeapViewerNodeFilter viewFilter, Heap heap, Progress progress) {\n            this.iterator = new InterruptibleIterator<>(objectsIterator(0, progress));\n            \n            this.viewFilter = viewFilter;\n            this.heap = heap;\n            \n            while (index-- > 0) hasNext();\n        }\n        \n        // NOTE: must always be called before next() to compute the next value!\n        public boolean hasNext() {\n            nextNode = nextNode();\n            return nextNode != null;\n        }\n        \n        public HeapViewerNode next() {\n            return nextNode;\n        }\n        \n        private HeapViewerNode nextNode() {\n            while (iterator.hasNext()) {\n                nextObject = iterator.next();\n                HeapViewerNode node = createNode(nextObject);\n                if (viewFilter.passes(node, heap)) return node;\n            }\n            nextObject = null;\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/ProgressIterator.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.utils;\n\nimport java.util.Iterator;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ProgressIterator<T> implements Iterator<T> {\n    \n    private final Iterator<T> iterator;\n    private final Progress progress;\n    \n    \n    public ProgressIterator(Iterator<T> iterator, Progress progress) {\n        this(iterator, 0, false, progress);\n    }\n    \n    public ProgressIterator(Iterator<T> iterator, int index, boolean needsForward, Progress progress) {\n        this.iterator = iterator;\n        this.progress = progress;\n        \n        if (index > 0) {\n            if (needsForward) forward(index);\n            else progress.steps(index);\n        }\n    }\n    \n    \n    public boolean hasNext() {\n        return iterator.hasNext();\n    }\n\n    public T next() {\n        progress.step();\n        return iterator.next();\n    }\n    \n    \n    private void forward(int steps) {\n        while (steps-- > 0)\n            if (hasNext()) next();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/SortedObjectsBuffer.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.utils;\n\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class SortedObjectsBuffer<T> {\n    \n    private final int cacheSize;\n    private long totalObjects;\n    \n    private final Wrapper<T>[] elements;\n    \n    private final boolean sorting;\n    private final boolean ascending;\n    \n    private final DataType dataType;\n    private final Heap heap;\n    private final HeapViewerNode parent;\n    \n    private final HeapViewerNodeFilter filter;\n    \n    private boolean notFull;\n    private int currentIndex;\n    \n    private final T previousObject;\n    private boolean previousObjectSeen;\n    private final Object previousObjectValue;\n    private Object maxObjectValue;\n    private int wrapperSerialId;\n    \n    \n    SortedObjectsBuffer(int nodesCount, T previousObject, DataType dataType, SortOrder sortOrder, HeapViewerNodeFilter filter, Heap heap, HeapViewerNode parent) {\n        cacheSize = nodesCount;\n        \n        elements = new Wrapper[cacheSize*2];\n        \n        sorting = sortOrder != null && !SortOrder.UNSORTED.equals(sortOrder) && dataType != null && sorts(dataType);\n        ascending = SortOrder.ASCENDING.equals(sortOrder);\n        \n        this.dataType = dataType;\n        this.heap = heap;\n        this.parent = parent;\n        \n        this.filter = filter;\n        \n        notFull = true;\n        currentIndex = -1;\n        \n        this.previousObject = previousObject;\n        previousObjectSeen = previousObject == null;\n        previousObjectValue = previousObjectSeen ? null : HeapViewerNode.getValue(createNode(previousObject), dataType, heap, parent);\n    }\n    \n    \n    protected abstract boolean sorts(DataType dataType);\n    \n    protected abstract HeapViewerNode createNode(T object);\n    \n    \n    void add(T object) {\n        HeapViewerNode node = createNode(object);\n        \n        if (filter != null && !filter.passes(node, heap)) return;\n        \n        totalObjects++;\n        \n        // --- not sorting, just adding first N items\n        if (!sorting) {\n            if (notFull) {\n                currentIndex++;\n                elements[currentIndex] = createWrapper(object, null);\n                if (currentIndex == cacheSize - 1) notFull = false;\n            }\n            return;\n        }\n        // ---------------------------------------------------------------------\n        \n        Object value = HeapViewerNode.getValue(node, dataType, heap, parent);\n        \n        if (previousObjectValue != null) {\n            int comp = compare(value, previousObjectValue);\n            if (comp < 0) { /*System.err.println(\">>>     skipping \" + object + \" because lower than \" + previousObjectValue);*/ return; }\n\n            if (comp == 0 && !previousObjectSeen) {\n                if (previousObject.equals(object)) previousObjectSeen = true;\n//                System.err.println(\">>>     skipping \" + object + \" because previous \" + previousObject + \" just seen \" + previousObjectSeen);\n                return;\n            }\n        }\n        \n        if (maxObjectValue != null) {\n            int comp = compare(value, maxObjectValue);\n            if (comp >= 0) { /*System.err.println(\">>>     skipping \" + object + \" because higher than \" + maxObjectValue);*/ return; }\n        }\n        currentIndex++;\n        elements[currentIndex] = createWrapper(object, value);\n        if (currentIndex < elements.length - 1) {\n            return;\n        }\n        Arrays.sort(elements, new WrapperComparator());\n        int middleIndex = elements.length/2-1;\n        maxObjectValue = elements[middleIndex].value;\n        currentIndex = middleIndex;\n    }\n    \n    T[] getObjects() {\n        if (sorting) {\n            Arrays.fill(elements, currentIndex+1, elements.length-1, null);\n            Arrays.sort(elements, new WrapperComparator());\n        }\n        int size = Math.min(currentIndex+1,elements.length/2);\n        T[] objects = (T[]) new Object[size];\n\n        for (int i = 0; i < objects.length; i++) {\n            objects[i] = elements[i].object;\n        }\n        return objects;\n    }\n    \n    long getTotalObjects() {\n        return totalObjects;\n    }\n    \n    private Wrapper<T> createWrapper(T obj, Object val) {\n        return new Wrapper<>(wrapperSerialId++, obj,val);\n    }\n    \n    private int compare(Object value1, Object value2) {\n        if (value1 == value2) return 0;\n        if (value1 == null) return ascending ? -1 : 1;\n        if (value2 == null) return ascending ? 1 : -1;\n        return ((Comparable)value1).compareTo(value2) * (ascending ? 1 : -1);\n    }\n    \n    private class WrapperComparator implements Comparator<Wrapper<T>> {\n\n        @Override\n        public int compare(Wrapper<T> o1, Wrapper<T> o2) {\n            if (o1 == o2) return 0;\n            if (o1 == null) return  1;\n            if (o2 == null) return -1;\n            int comp = SortedObjectsBuffer.this.compare(o1.value, o2.value);\n            if (comp == 0) {\n                if (o1.serialId > o2.serialId) return 1;\n                if (o1.serialId < o2.serialId) return -1;\n            }\n            return comp;\n        }\n    }\n\n    private static class Wrapper<T> {\n        private final T object;\n        private final Object value;\n        private final int serialId;\n\n        private Wrapper(int id, T obj, Object val) {\n            serialId = id;\n            object = obj;\n            value = val;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/counters/BooleanCounter.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.utils.counters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class BooleanCounter extends PrimitiveCounter {\n    \n    private int size;\n    \n    private final int[] counts;\n    \n    \n    public BooleanCounter() {\n        counts = new int[2];\n    }\n    \n    \n    public void count(boolean key) {\n        int index = key ? 1 : 0;\n        if (counts[index] == 0) size++;\n        counts[index]++;\n    }\n    \n    @Override\n    public void count(String value) {\n        count(Boolean.parseBoolean(value));\n    }\n    \n    @Override\n    public Iterator iterator() {\n        return new Iterator();\n    }\n    \n    @Override\n    public int size() {\n        return size;\n    }\n    \n    \n    public static final class Record extends PrimitiveCounter.Record {\n        \n        private boolean value;\n        private int count;\n        \n        private Record() {}\n        \n        public boolean getPrimitive() {\n            return value;\n        }\n        \n        @Override\n        public String getValue() {\n            return Boolean.toString(value);\n        }\n        \n        @Override\n        public int getCount() {\n            return count;\n        }\n        \n        @Override\n        public int hashCode() {\n            return Boolean.hashCode(value);\n        }\n        \n        @Override\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof Record)) return false;\n            return value == ((Record)o).value;\n        }\n        \n    }\n    \n    \n    public final class Iterator implements java.util.Iterator<Record> {\n        \n        private int index;\n        private int count;\n        \n        private Iterator() {}\n\n        @Override\n        public boolean hasNext() {\n            return count < size;\n        }\n\n        @Override\n        public Record next() {\n            Record entry = new Record();\n            \n            entry.count = counts[index];\n            while (entry.count == 0) entry.count = counts[++index];\n            entry.value = 1 == index++;\n            \n            count++;\n            \n            return entry;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/counters/ByteCounter.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.utils.counters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ByteCounter extends PrimitiveCounter {\n    \n    private int size;\n    \n    private final int[] counts;\n    \n    \n    public ByteCounter() {\n        counts = new int[Byte.MAX_VALUE - Byte.MIN_VALUE + 1];\n    }\n    \n    \n    public void count(byte key) {\n        int index = key - Byte.MIN_VALUE;\n        if (counts[index] == 0) size++;\n        counts[index]++;\n    }\n    \n    @Override\n    public void count(String value) {\n        count(Byte.parseByte(value));\n    }\n    \n    @Override\n    public Iterator iterator() {\n        return new Iterator();\n    }\n    \n    @Override\n    public int size() {\n        return size;\n    }\n    \n    \n    public static final class Record extends PrimitiveCounter.Record {\n        \n        private byte value;\n        private int count;\n        \n        private Record() {}\n        \n        public byte getPrimitive() {\n            return value;\n        }\n        \n        @Override\n        public String getValue() {\n            return Byte.toString(value);\n        }\n        \n        @Override\n        public int getCount() {\n            return count;\n        }\n        \n        @Override\n        public int hashCode() {\n            return Byte.hashCode(value);\n        }\n        \n        @Override\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof Record)) return false;\n            return value == ((Record)o).value;\n        }\n        \n    }\n    \n    \n    public final class Iterator implements java.util.Iterator<Record> {\n        \n        private int index;\n        private int count;\n        \n        private Iterator() {\n        }\n\n        @Override\n        public boolean hasNext() {\n            return count < size;\n        }\n\n        @Override\n        public Record next() {\n            Record entry = new Record();\n            \n            entry.count = counts[index];\n            while (entry.count == 0) entry.count = counts[++index];\n            entry.value = (byte)(index++ + Byte.MIN_VALUE);\n            \n            count++;\n            \n            return entry;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/counters/CharCounter.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.utils.counters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class CharCounter extends PrimitiveCounter {\n    \n    private int size;\n    \n    private final int[] counts;\n    \n    \n    public CharCounter() {\n        counts = new int[Character.MAX_VALUE - Character.MIN_VALUE + 1];\n    }\n    \n    \n    public void count(char key) {\n        if (counts[key] == 0) size++;\n        counts[key]++;\n    }\n    \n    @Override\n    public void count(String value) {\n        count(value.charAt(0));\n    }\n    \n    @Override\n    public Iterator iterator() {\n        return new Iterator();\n    }\n    \n    @Override\n    public int size() {\n        return size;\n    }\n    \n    \n    public static final class Record extends PrimitiveCounter.Record {\n        \n        private char value;\n        private int count;\n        \n        private Record() {}\n        \n        public char getPrimitive() {\n            return value;\n        }\n        \n        @Override\n        public String getValue() {\n            return Character.toString(value);\n        }\n        \n        @Override\n        public int getCount() {\n            return count;\n        }\n        \n        @Override\n        public int hashCode() {\n            return Character.hashCode(value);\n        }\n        \n        @Override\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof Record)) return false;\n            return value == ((Record)o).value;\n        }\n        \n    }\n    \n    \n    public final class Iterator implements java.util.Iterator<Record> {\n        \n        private int index;\n        private int count;\n        \n        private Iterator() {\n        }\n\n        @Override\n        public boolean hasNext() {\n            return count < size;\n        }\n\n        @Override\n        public Record next() {\n            Record entry = new Record();\n            \n            entry.count = counts[index];\n            while (entry.count == 0) entry.count = counts[++index];\n            entry.value = (char)index++;\n            \n            count++;\n            \n            return entry;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/counters/DoubleCounter.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.utils.counters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class DoubleCounter extends PrimitiveCounter {\n    \n    private int size; \n    \n    private final long[] keys;\n    private final int[] counts;\n    \n    \n    public DoubleCounter(int bufferSize) {\n        bufferSize = (bufferSize * 9) / 8;\n        keys = new long[bufferSize];\n        counts = new int[bufferSize];\n    }\n    \n    \n    public void count(double dkey) {\n        long key = Double.doubleToRawLongBits(dkey);\n        \n        int idx = hash(key);\n        int index = idx;\n\n        while (keys[index] != key && counts[index] != 0) {\n            index = incIndex(index);\n            if (index == idx) throw new RuntimeException(\"Full when counting \" + dkey); // NOI18N\n        }\n\n        if (counts[index] == 0) {\n            keys[index] = key;\n            size++;\n        }\n\n        counts[index]++;\n    }\n    \n    @Override\n    public void count(String value) {\n        count(Double.parseDouble(value));\n    }\n    \n    @Override\n    public Iterator iterator() {\n        return new Iterator();\n    }\n    \n    @Override\n    public int size() {\n        return size;\n    }\n    \n    \n    private int hash(long key) {\n        return (int)Math.abs(key % keys.length);\n    }\n    \n    private int incIndex(int index) {\n        return ++index < keys.length ? index : 0;\n    }\n    \n    \n    public static final class Record extends PrimitiveCounter.Record {\n        \n        private long value;\n        private int count;\n        \n        private Record() {}\n        \n        public double getPrimitive() {\n            return Double.longBitsToDouble(value);\n        }\n        \n        @Override\n        public String getValue() {\n            return Double.toString(getPrimitive());\n        }\n        \n        @Override\n        public int getCount() {\n            return count;\n        }\n        \n        @Override\n        public int hashCode() {\n            return Long.hashCode(value);\n        }\n        \n        @Override\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof Record)) return false;\n            return value == ((Record)o).value;\n        }\n        \n    }\n    \n    \n    public final class Iterator implements java.util.Iterator<Record> {\n        \n        private int index;\n        private int count;\n        \n        private Iterator() {\n        }\n\n        @Override\n        public boolean hasNext() {\n            return count < size;\n        }\n\n        @Override\n        public Record next() {\n            Record entry = new Record();\n            \n            entry.count = counts[index];\n            while (entry.count == 0) entry.count = counts[++index];\n            entry.value = keys[index++];\n            \n            count++;\n            \n            return entry;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/counters/FloatCounter.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.utils.counters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class FloatCounter extends PrimitiveCounter {\n    \n    private int size; \n    \n    private final int[] keys;\n    private final int[] counts;\n    \n    \n    public FloatCounter(int bufferSize) {\n        bufferSize = (bufferSize * 9) / 8;\n        keys = new int[bufferSize];\n        counts = new int[bufferSize];\n    }\n    \n    \n    public void count(float fkey) {\n        int key = Float.floatToRawIntBits(fkey);\n        \n        int idx = hash(key);\n        int index = idx;\n\n        while (keys[index] != key && counts[index] != 0) {\n            index = incIndex(index);\n            if (index == idx) throw new RuntimeException(\"Full when counting \" + fkey); // NOI18N\n        }\n\n        if (counts[index] == 0) {\n            keys[index] = key;\n            size++;\n        }\n\n        counts[index]++;\n    }\n    \n    @Override\n    public void count(String value) {\n        count(Float.parseFloat(value));\n    }\n    \n    @Override\n    public Iterator iterator() {\n        return new Iterator();\n    }\n    \n    @Override\n    public int size() {\n        return size;\n    }\n    \n    \n    private int hash(int key) {\n        return (int)Math.abs(key % keys.length);\n    }\n    \n    private int incIndex(int index) {\n        return ++index < keys.length ? index : 0;\n    }\n    \n    \n    public static final class Entry extends PrimitiveCounter.Record {\n        \n        private int value;\n        private int count;\n        \n        private Entry() {}\n        \n        public float getPrimitive() {\n            return Float.intBitsToFloat(value);\n        }\n        \n        @Override\n        public String getValue() {\n            return Float.toString(getPrimitive());\n        }\n        \n        @Override\n        public int getCount() {\n            return count;\n        }\n        \n        @Override\n        public int hashCode() {\n            return Integer.hashCode(value);\n        }\n        \n        @Override\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof Entry)) return false;\n            return value == ((Entry)o).value;\n        }\n        \n    }\n    \n    \n    public final class Iterator implements java.util.Iterator<Entry> {\n        \n        private int index;\n        private int count;\n        \n        private Iterator() {\n        }\n\n        @Override\n        public boolean hasNext() {\n            return count < size;\n        }\n\n        @Override\n        public Entry next() {\n            Entry entry = new Entry();\n            \n            entry.count = counts[index];\n            while (entry.count == 0) entry.count = counts[++index];\n            entry.value = keys[index++];\n            \n            count++;\n            \n            return entry;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/counters/InstanceCounter.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.utils.counters;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class InstanceCounter {\n    \n    private int size;\n    \n    private int nullCount;    \n    \n    private final long[] keys;\n    private final int[] counts;\n    \n    \n    public InstanceCounter(int bufferSize) {\n        bufferSize = (bufferSize * 9) / 8;\n        keys = new long[bufferSize];\n        counts = new int[bufferSize];\n    }\n    \n    \n    public void count(Instance ikey) {\n        if (ikey == null) {\n            nullCount++;\n        } else {\n            long key = ikey.getInstanceId();           \n            \n            int idx = hash(key);\n            int index = idx;\n\n            while (keys[index] != key && counts[index] != 0) {\n                index = incIndex(index);\n                if (index == idx) throw new RuntimeException(\"Full when counting \" + ikey);\n            }\n\n            if (counts[index] == 0) {\n                keys[index] = key;\n                size++;\n            }\n\n            counts[index]++;\n        }\n    }\n    \n    public Iterator iterator() {\n        return new Iterator();\n    }\n    \n    public int size() {\n        return size + (nullCount > 0 ? 1 : 0);\n    }\n    \n    \n    private int hash(long key) {\n        return (int)Math.abs(key % keys.length);\n    }\n    \n    private int incIndex(int index) {\n        return ++index < keys.length ? index : 0;\n    }\n    \n    \n    public static final class Record {\n        \n        private long value;\n        private int count;\n        \n        private Record() {}\n        \n        public Instance getInstance(Heap heap) {\n            return value == -1 ? null : heap.getInstanceByID(value);\n        }\n        \n        public int getCount() {\n            return count;\n        }\n        \n        @Override\n        public int hashCode() {\n            return Long.hashCode(value);\n        }\n        \n        @Override\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof Record)) return false;\n            return value == ((Record)o).value;\n        }\n        \n    }\n    \n    \n    public final class Iterator implements java.util.Iterator<Record> {\n        \n        private final boolean hasNullCount;\n        \n        private int index;\n        private int count;\n        \n        private Iterator() {\n            hasNullCount = nullCount > 0;\n        }\n\n        @Override\n        public boolean hasNext() {\n            return hasNullCount ? count <= size : count < size;\n        }\n\n        @Override\n        public Record next() {\n            Record entry = new Record();\n            if (count == size) {\n                entry.value = -1;\n                entry.count = nullCount;\n            } else {\n                entry.count = counts[index];\n                while (entry.count == 0) entry.count = counts[++index];\n                entry.value = keys[index++];\n            }\n            \n            count++;\n            \n            return entry;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/counters/IntCounter.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.utils.counters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class IntCounter extends PrimitiveCounter {\n    \n    private int size; \n    \n    private final int[] keys;\n    private final int[] counts;\n    \n    \n    public IntCounter(int bufferSize) {\n        bufferSize = (bufferSize * 9) / 8;\n        keys = new int[bufferSize];\n        counts = new int[bufferSize];\n    }\n    \n    \n    public void count(int key) {\n        int idx = hash(key);\n        int index = idx;\n\n        while (keys[index] != key && counts[index] != 0) {\n            index = incIndex(index);\n            if (index == idx) throw new RuntimeException(\"Full when counting \" + key); // NOI18N\n        }\n\n        if (counts[index] == 0) {\n            keys[index] = key;\n            size++;\n        }\n\n        counts[index]++;\n    }\n    \n    @Override\n    public void count(String value) {\n        count(Integer.parseInt(value));\n    }\n    \n    @Override\n    public Iterator iterator() {\n        return new Iterator();\n    }\n    \n    @Override\n    public int size() {\n        return size;\n    }\n    \n    \n    private int hash(int key) {\n        return (int)Math.abs(key % keys.length);\n    }\n    \n    private int incIndex(int index) {\n        return ++index < keys.length ? index : 0;\n    }\n    \n    \n    public static final class Record extends PrimitiveCounter.Record {\n        \n        private int value;\n        private int count;\n        \n        private Record() {}\n        \n        public int getPrimitive() {\n            return value;\n        }\n        \n        @Override\n        public String getValue() {\n            return Integer.toString(value);\n        }\n        \n        @Override\n        public int getCount() {\n            return count;\n        }\n        \n        @Override\n        public int hashCode() {\n            return Integer.hashCode(value);\n        }\n        \n        @Override\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof Record)) return false;\n            return value == ((Record)o).value;\n        }\n        \n    }\n    \n    \n    public final class Iterator implements java.util.Iterator<Record> {\n        \n        private int index;\n        private int count;\n        \n        private Iterator() {}\n\n        @Override\n        public boolean hasNext() {\n            return count < size;\n        }\n\n        @Override\n        public Record next() {\n            Record entry = new Record();\n            \n            entry.count = counts[index];\n            while (entry.count == 0) entry.count = counts[++index];\n            entry.value = keys[index++];\n            \n            count++;\n            \n            return entry;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/counters/LongCounter.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.utils.counters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class LongCounter extends PrimitiveCounter {\n    \n    private int size; \n    \n    private final long[] keys;\n    private final int[] counts;\n    \n    \n    public LongCounter(int bufferSize) {\n        bufferSize = (bufferSize * 9) / 8;\n        keys = new long[bufferSize];\n        counts = new int[bufferSize];\n    }\n    \n    \n    public void count(long key) {\n        int idx = hash(key);\n        int index = idx;\n\n        while (keys[index] != key && counts[index] != 0) {\n            index = incIndex(index);\n            if (index == idx) throw new RuntimeException(\"Full when counting \" + key); // NOI18N\n        }\n\n        if (counts[index] == 0) {\n            keys[index] = key;\n            size++;\n        }\n\n        counts[index]++;\n    }\n    \n    @Override\n    public void count(String value) {\n        count(Long.parseLong(value));\n    }\n    \n    @Override\n    public Iterator iterator() {\n        return new Iterator();\n    }\n    \n    @Override\n    public int size() {\n        return size;\n    }\n    \n    \n    private int hash(long key) {\n        return (int)Math.abs(key % keys.length);\n    }\n    \n    private int incIndex(int index) {\n        return ++index < keys.length ? index : 0;\n    }\n    \n    \n    public static final class Record extends PrimitiveCounter.Record {\n        \n        private long value;\n        private int count;\n        \n        private Record() {}\n        \n        public long getPrimitive() {\n            return value;\n        }\n        \n        @Override\n        public String getValue() {\n            return Long.toString(value);\n        }\n        \n        @Override\n        public int getCount() {\n            return count;\n        }\n        \n        @Override\n        public int hashCode() {\n            return Long.hashCode(value);\n        }\n        \n        @Override\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof Record)) return false;\n            return value == ((Record)o).value;\n        }\n        \n    }\n    \n    \n    public final class Iterator implements java.util.Iterator<Record> {\n        \n        private int index;\n        private int count;\n        \n        private Iterator() {}\n\n        @Override\n        public boolean hasNext() {\n            return count < size;\n        }\n\n        @Override\n        public Record next() {\n            Record entry = new Record();\n            \n            entry.count = counts[index];\n            while (entry.count == 0) entry.count = counts[++index];\n            entry.value = keys[index++];\n            \n            count++;\n            \n            return entry;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/counters/PrimitiveCounter.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.utils.counters;\n\nimport java.util.Iterator;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class PrimitiveCounter {\n    \n    public static PrimitiveCounter create(String type, int instancesCount) {\n        switch (type) {\n            case \"boolean\": // NOI18N\n                return new BooleanCounter();\n            case \"char\": // NOI18N\n                return new CharCounter();\n            case \"byte\": // NOI18N\n                return new ByteCounter();\n            case \"short\": // NOI18N\n                return new ShortCounter();\n            case \"int\": // NOI18N\n                return new IntCounter(instancesCount);\n            case \"long\": // NOI18N\n                return new LongCounter(instancesCount);\n            case \"float\": // NOI18N\n                return new FloatCounter(instancesCount);\n            case \"double\": // NOI18N\n                return new DoubleCounter(instancesCount);\n            default:\n                throw new IllegalArgumentException(\"Unknown primitive type \" + type); // NOI18N\n        }\n    }\n    \n    \n    public abstract void count(String value);\n    \n    public abstract int size();\n    \n    public abstract Iterator<? extends Record> iterator();\n    \n    \n    public static abstract class Record {\n        \n        public abstract String getValue();\n        \n        public abstract int getCount();\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer/src/org/graalvm/visualvm/heapviewer/utils/counters/ShortCounter.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.utils.counters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ShortCounter extends PrimitiveCounter {\n    \n    private int size;\n    \n    private final int[] counts;\n    \n    \n    public ShortCounter() {\n        counts = new int[Short.MAX_VALUE - Short.MIN_VALUE + 1];\n    }\n    \n    \n    public void count(short key) {\n        int index = key - Short.MIN_VALUE;\n        if (counts[index] == 0) size++;\n        counts[index]++;\n    }\n    \n    @Override\n    public void count(String value) {\n        count(Short.parseShort(value));\n    }\n    \n    @Override\n    public Iterator iterator() {\n        return new Iterator();\n    }\n    \n    @Override\n    public int size() {\n        return size;\n    }\n    \n    \n    public static final class Record extends PrimitiveCounter.Record {\n        \n        private short value;\n        private int count;\n        \n        private Record() {}\n        \n        public short getPrimitive() {\n            return value;\n        }\n        \n        @Override\n        public String getValue() {\n            return Short.toString(value);\n        }\n        \n        public int getCount() {\n            return count;\n        }\n        \n        @Override\n        public int hashCode() {\n            return Short.hashCode(value);\n        }\n        \n        @Override\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof Record)) return false;\n            return value == ((Record)o).value;\n        }\n        \n    }\n    \n    \n    public final class Iterator implements java.util.Iterator<Record> {\n        \n        private int index;\n        private int count;\n        \n        private Iterator() {\n        }\n\n        @Override\n        public boolean hasNext() {\n            return count < size;\n        }\n\n        @Override\n        public Record next() {\n            Record entry = new Record();\n            \n            entry.count = counts[index];\n            while (entry.count == 0) entry.count = counts[++index];\n            entry.value = (short)(index++ + Short.MIN_VALUE);\n            \n            count++;\n            \n            return entry;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.heapviewer.console\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.heapviewer.console.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n\n    <target name=\"compile\" depends=\"projectized-common.compile\">\n        <delete dir=\"${build.classes.dir}/org/graalvm/polyglot\"/> <!-- just stubs -->\n    </target>\n\n</project>\n"
  },
  {
    "path": "visualvm/heapviewer.console/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.heapviewer.console/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/heapviewer/console/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "visualvm/heapviewer.console/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.heapviewer.console-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/heapviewer.console/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=126920c3\nbuild.xml.script.CRC32=95901e97\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=126920c3\nnbproject/build-impl.xml.script.CRC32=4df4472b\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/heapviewer.console/nbproject/project.properties",
    "content": "javac.source=1.8\njavac.compilerargs=-Xlint -Xlint:-serial\nmodule.javadoc.packages=org.graalvm.visualvm.heapviewer.console.r.*\n"
  },
  {
    "path": "visualvm/heapviewer.console/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.heapviewer.console</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.2</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.heapviewer</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.2</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid.heap</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.68</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.43</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.34</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.77</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/heapviewer.console/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/polyglot/Context.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/* This is stub code written based on org.graalvm.polyglot package javadoc\n * published for GraalVM. It makes possible to compile code, which uses\n * GraalVM features on JDK 8. The compiled stub classes should never be\n * included in the final product.\n */\n\npackage org.graalvm.polyglot;\n\nimport java.io.OutputStream;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class Context {\n\n    public static Builder newBuilder(String... permittedLanguages) {return null;}\n    public Value eval(String languageId, CharSequence source) {return null;}\n    public Value getPolyglotBindings() {return null;}\n\n    public final class Builder {\n\n        public Builder allowAllAccess(boolean b) {return null;}\n        public Builder out(OutputStream outStream) {return null;}\n        public Context build() {return null;}\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/polyglot/Value.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/* This is stub code written based on org.graalvm.polyglot package javadoc\n * published for GraalVM. It makes possible to compile code, which uses\n * GraalVM features on JDK 8. The compiled stub classes should never be\n * included in the final product.\n */\n\npackage org.graalvm.polyglot;\n\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class Value {\n\n    public Value execute(Object... arguments) {return null;}\n    public void putMember(String name, Object value) {}\n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/polyglot/proxy/ProxyArray.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/* This is stub code written based on org.graalvm.polyglot package javadoc\n * published for GraalVM. It makes possible to compile code, which uses\n * GraalVM features on JDK 8. The compiled stub classes should never be\n * included in the final product.\n */\n\npackage org.graalvm.polyglot.proxy;\n\nimport org.graalvm.polyglot.Value;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic interface ProxyArray {\n\n    public Object get(long index);\n    public void set(long index, Value value);\n    public long getSize();\n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/Bundle.properties",
    "content": "#\n# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Name=VisualVM-HeapViewer-Console\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/CustomRQueries.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.console.r;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Properties;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerStorage;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"CustomRQueries_SaveFailed=Failed to save R scripts.\",\n    \"CustomRQueries_LoadFailed=Failed to load saved R scripts.\"\n}) \npublic final class CustomRQueries {\n    \n    private static final String SAVED_R_QUERIES_FILENAME = \"rqueries\"; // NOI18N\n    \n    private static final String PROP_QUERY_NAME_KEY = \"r-query-name\"; // NOI18N\n    private static final String PROP_QUERY_DESCR_KEY = \"r-query-descr\"; // NOI18N\n    private static final String PROP_QUERY_SCRIPT_KEY = \"r-query-script\"; // NOI18N\n    \n    \n    private static CustomRQueries INSTANCE;\n    \n    private List<RQueries.Query> customQueries;\n    \n    \n    public static synchronized CustomRQueries instance() {\n        if (INSTANCE == null) INSTANCE = new CustomRQueries();\n        return INSTANCE;\n    }\n    \n    \n    public synchronized boolean isEmpty() {\n        return customQueries.isEmpty();\n    }\n    \n    public synchronized void add(RQueries.Query query) {\n        customQueries.add(0, query);\n        save();\n    }\n    \n    public synchronized void save(RQueries.Query query) {\n        for (RQueries.Query q : customQueries) {\n            if (q.getName().equals(query.getName())) {\n                q.setScript(query.getScript());\n                save();\n                break;\n            }\n        }\n    }\n    \n    public synchronized void set(List<RQueries.Query> queries) {\n        customQueries.clear();\n        customQueries.addAll(queries);\n        save();\n    }\n    \n    public synchronized List<RQueries.Query> list() {\n        List<RQueries.Query> list = new ArrayList<>();\n        for (RQueries.Query query : customQueries)\n            list.add(new RQueries.Query(query.getScript(), query.getName(), query.getDescription()));\n        return list;\n    }\n    \n    \n    private void save() {\n        new RequestProcessor(\"R Scripts Saver\").post(new Runnable() { // NOI18N\n            public void run() {\n                try {\n                    Properties p = listToProperties(list());\n                    ProfilerStorage.saveGlobalProperties(p, SAVED_R_QUERIES_FILENAME);\n                } catch (Exception e) {\n                    ProfilerDialogs.displayError(Bundle.CustomRQueries_SaveFailed());\n                    Exceptions.printStackTrace(e);\n                }\n            }\n        });\n    }\n    \n    \n    private static List<RQueries.Query> propertiesToList(List<RQueries.Query> queries, Properties properties) {\n        int i = 0;\n        while (properties.containsKey(PROP_QUERY_NAME_KEY + \"-\" + i)) { // NOI18N\n            String name = properties.getProperty(PROP_QUERY_NAME_KEY + \"-\" + i); // NOI18N\n            String description = properties.getProperty(PROP_QUERY_DESCR_KEY + \"-\" + i, null); // NOI18N\n            String script = properties.getProperty(PROP_QUERY_SCRIPT_KEY + \"-\" + i, \"\"); // NOI18N\n            \n            if (name != null && script != null) queries.add(new RQueries.Query(script, name, description));\n            \n            i++;\n        }\n        \n        return queries;\n    }\n\n    private static Properties listToProperties(List<RQueries.Query> queries) {\n        Properties properties = new Properties();\n        \n        int i = 0;\n        for (RQueries.Query query : queries) {\n            properties.put(PROP_QUERY_NAME_KEY + \"-\" + i, query.getName().trim()); // NOI18N\n            properties.put(PROP_QUERY_SCRIPT_KEY + \"-\" + i, query.getScript().trim()); // NOI18N\n            \n            String descr = query.getDescription();\n            if (descr != null) properties.put(PROP_QUERY_DESCR_KEY + \"-\" + i, descr); // NOI18N\n            \n            i++;\n        }\n\n        return properties;\n    }\n    \n    \n    private CustomRQueries() {\n        assert !SwingUtilities.isEventDispatchThread();\n        \n        customQueries = new ArrayList<>();\n        \n        try {\n            Properties p = new Properties();\n            ProfilerStorage.loadGlobalProperties(p, SAVED_R_QUERIES_FILENAME);\n            propertiesToList(customQueries, p);\n        } catch (Exception e) {\n            ProfilerDialogs.displayError(Bundle.CustomRQueries_LoadFailed());\n            Exceptions.printStackTrace(e);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/MultiSplitContainer.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.console.r;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.swing.JPanel;\nimport javax.swing.UIManager;\n\n/**\n * Copy of org.graalvm.visualvm.heapviewer.swing.MultiSplitContainer\n * TODO: make this a public class and share it to prevent duplication.\n *\n * @author Jiri Sedlacek\n */\nclass MultiSplitContainer extends JPanel {\n    \n    private static final int DIVIDER_SIZE = 6;\n    private static final Color SEPARATOR_COLOR = UIManager.getColor(\"Separator.foreground\"); // NOI18N\n    \n    private final Map<Component, Double> componentsWeights = new HashMap<>();\n    private final List<Integer> dividerOffsets = new ArrayList<>();\n    private final List<Component> visibleComponents = new ArrayList<>();\n    \n    \n    MultiSplitContainer() {\n        super(null);\n        \n        MouseHandler mHandler = new MouseHandler();\n        addMouseListener(mHandler);\n        addMouseMotionListener(mHandler);\n    }\n    \n    public void doLayout() {\n        if (visibleComponents.isEmpty()) return;\n       \n        Insets insets = getInsets();        \n        int visiblesCount = visibleComponents.size();\n        \n        if (visiblesCount == 1) {\n            visibleComponents.get(0).setBounds(insets.left, insets.top, getWidth() - insets.left - insets.right, getHeight() - insets.top - insets.bottom);\n        } else {\n            Dimension size = getSize();     \n            int h = size.height - insets.top - insets.bottom;\n            \n            int x = insets.left;\n            Component comp;\n        \n            int dividersCount = dividerOffsets.size();\n            for (int i = 0; i < dividersCount; i++) {\n                int xx = dividerOffsets.get(i);\n                comp = visibleComponents.get(i);\n                comp.setBounds(x, insets.top, xx - x, h);\n                comp.validate();\n                x = xx + DIVIDER_SIZE;\n            }\n            \n            x = dividerOffsets.get(dividersCount - 1) + DIVIDER_SIZE;\n            comp = visibleComponents.get(visiblesCount - 1);\n            comp.setBounds(x, insets.top, getWidth() - insets.right - x, h);\n            comp.validate();\n        }\n    }\n    \n    public void invalidate() {\n        super.invalidate();\n        setupLayout();\n        doLayout();\n        repaint();\n    }\n    \n    \n    public void paint(Graphics g) {\n        super.paint(g);\n        \n        if (!dividerOffsets.isEmpty()) {\n            Insets i = getInsets();\n            g.setColor(SEPARATOR_COLOR);\n            for (int o : dividerOffsets) {\n                g.drawLine(o, i.top, o, getHeight() - i.bottom);\n                o += DIVIDER_SIZE - 1;\n                g.drawLine(o, i.top, o, getHeight() - i.bottom);\n            }\n        }\n    }\n    \n    \n    protected void addImpl(Component comp, Object constraints, int index) {\n        componentsWeights.put(comp, constraints instanceof Number ? ((Number)constraints).doubleValue() : 0.5d);\n        super.addImpl(comp, constraints, index);\n        invalidate();\n    }\n    \n    public void remove(int index) {\n        Component comp = getComponent(index);\n        super.remove(index);\n        componentsWeights.remove(comp);\n        invalidate();\n    }\n    \n    \n    private void setupLayout() {\n        dividerOffsets.clear();\n        visibleComponents.clear();\n            \n        Dimension size = getSize();\n        if (size.height == 0 || size.width == 0) return; // container too small\n        \n        double visRel = 0;\n        \n        for (Component c : getComponents()) {\n            if (c.isVisible()) {\n                visibleComponents.add(c);\n                visRel += componentsWeights.get(c);\n            }\n        }\n        \n        int visiblesCount = visibleComponents.size();\n        if (visiblesCount < 2) return; // no visible divider\n        \n        Insets insets = getInsets();\n        int w = size.width - insets.left - insets.right - ((visiblesCount - 1) * DIVIDER_SIZE);\n        \n        int x = insets.left;\n        \n        for (int i = 0; i < visiblesCount - 1; i++) {\n            x += (w / visRel * componentsWeights.get(visibleComponents.get(i)));\n            dividerOffsets.add(x);\n            x += DIVIDER_SIZE;\n        }\n    }\n    \n    \n    private class MouseHandler extends MouseAdapter {\n        \n        private boolean inDivider;\n        private int cursor;\n        private boolean canDrag;\n        private int offsetIdx;\n        private int dragX;\n        private int offsetX;\n        \n        private int minX;\n        private int maxX;\n        private Component c1;\n        private Component c2;\n        private double relWidth;\n        \n        public void mouseEntered(MouseEvent e) {\n            if (!canDrag) updateMouse(e, true);\n        }\n        \n        public void mouseExited(MouseEvent e) {\n            if (!canDrag) updateMouse(e, false);\n        }\n        \n        public void mouseMoved(MouseEvent e) {\n            updateMouse(e, true);\n        }\n        \n        public void mouseDragged(MouseEvent e) {\n            if (canDrag) {\n                int oldX = dividerOffsets.get(offsetIdx);\n                \n                int dx = dragX - e.getX();\n                int newX = oldX - dx;\n                newX = Math.max(newX, minX);\n                newX = Math.min(newX, maxX);\n                dividerOffsets.set(offsetIdx, newX);\n                \n                double c1width = c1.getWidth();\n                double c1Rel = c1width * relWidth / (c1width + c2.getWidth());\n                componentsWeights.put(c1, c1Rel);\n                componentsWeights.put(c2, relWidth - c1Rel);\n                \n                dragX = newX + offsetX;\n                \n                doLayout();\n                repaint();\n            }\n        }\n        \n        public void mousePressed(MouseEvent e) {\n            if (inDivider) {\n                canDrag = true;\n                dragX = e.getX();\n                offsetX = dragX - dividerOffsets.get(offsetIdx);\n                \n                Insets insets = getInsets();\n                minX = offsetIdx == 0 ? insets.left : dividerOffsets.get(offsetIdx - 1) + DIVIDER_SIZE;\n                maxX = offsetIdx == dividerOffsets.size() - 1 ? getWidth() - insets.right - DIVIDER_SIZE :\n                                                                dividerOffsets.get(offsetIdx + 1) - DIVIDER_SIZE;\n                \n                c1 = visibleComponents.get(offsetIdx);\n                c2 = visibleComponents.get(offsetIdx + 1);\n                relWidth = componentsWeights.get(c1) + componentsWeights.get(c2);\n            }\n        }\n        \n        public void mouseReleased(MouseEvent e) {\n            canDrag = false;\n            offsetIdx = -1;\n            c1 = null;\n            c2 = null;\n            updateMouse(e, inDivider);\n        }\n        \n        \n        private void updateMouse(MouseEvent e, boolean onContainer) {\n            inDivider = false;\n            int origCursor = cursor;\n            cursor = Cursor.DEFAULT_CURSOR;\n            if (onContainer) {\n                int x = e.getX();\n                for (int i = 0; i < dividerOffsets.size(); i++) {\n                    int divx = dividerOffsets.get(i);\n                    if (x >= divx && x <= divx + DIVIDER_SIZE - 1) {\n                        inDivider = true;\n                        offsetIdx = i;\n                        cursor = Cursor.E_RESIZE_CURSOR;\n                        break;\n                    }\n                }\n            }\n            if (origCursor != cursor) setCursor(Cursor.getPredefinedCursor(cursor));\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/RConsoleProvider.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.console.r;\n\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapViewerFeature.Provider.class)\npublic class RConsoleProvider extends HeapViewerFeature.Provider {\n    \n    public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n        if (JavaHeapFragment.isJavaHeap(context))\n            return new RConsoleView(context, actions);\n\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/RConsoleView.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.console.r;\n\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.console.r.engine.REngine;\nimport org.graalvm.visualvm.heapviewer.console.r.engine.REngine.ObjectVisitor;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.ui.HTMLView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport java.awt.BorderLayout;\nimport java.awt.CardLayout;\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Image;\nimport java.awt.RenderingHints;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ItemEvent;\nimport java.net.URL;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.Action;\nimport javax.swing.AbstractAction;\nimport javax.swing.BorderFactory;\nimport javax.swing.BoundedRangeModel;\nimport javax.swing.DefaultBoundedRangeModel;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JProgressBar;\nimport javax.swing.JTabbedPane;\nimport javax.swing.JToggleButton;\nimport javax.swing.JToolBar;\nimport javax.swing.KeyStroke;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.plaf.basic.BasicSplitPaneDivider;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\nimport org.graalvm.polyglot.Context;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedSplitPane;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.ActionPopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.windows.TopComponent;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"RConsoleView_Name=R Console\",\n    \"RConsoleView_Description=R Console\",\n    \"RConsoleView_CannotResolveClassMsg=Cannot resolve class\",\n    \"RConsoleView_CannotResolveInstanceMsg=Cannot resolve instance\",\n    \"RConsoleView_NothingExecuted=<no script executed yet>\",\n//    \"OQLConsoleView_NoResults=<no results>\",\n//    \"OQLConsoleView_ViewName=Results\",\n    \"RConsoleView_RQuery=R Query:\",\n    \"RConsoleView_RunAction=Run\",\n    \"RConsoleView_RunActionTooltip=Execute R script - Crtl+R\",\n    \"RConsoleView_CancelAction=Cancel\",\n    \"RConsoleView_CancelActionTooltip=Cancel R script execution\",\n    \"RConsoleView_LoadAction=Load Script\",\n    \"RConsoleView_LoadActionTooltip=Load R script\",\n    \"RConsoleView_SaveAction=Save Script\",\n    \"RConsoleView_SaveActionTooltip=Save R script\",\n    \"RConsoleView_EditAction=Edit Scripts\",\n    \"RConsoleView_EditActionTooltip=Edit Custom R scripts\",\n    \"RConsoleView_ExecutingProgress=Executing...\",\n    \"RConsoleView_ResultsLimit=Results Limit:\",\n    \"RConsoleView_SaveOnClosingCaption=R Script Not Saved\",\n    \"RConsoleView_SaveOnClosingMsg=<html><b>The R script has been modified.</b><br><br>Save it before closing the heap viewer?</html>\",\n    \"RConsoleView_NoSaveOnCloseBtn=Close Without Saving\"\n//    \"OQLConsoleView_Results=Results:\",\n//    \"OQLConsoleView_ObjectsTooltip=Objects\",\n//    \"OQLConsoleView_HTMLTooltip=Results:\",\n//    \"OQLConsoleView_Details=Details:\",\n//    \"OQLConsoleView_EngineNotAvailable=<R engine not available>\"\n})\nclass RConsoleView extends HeapViewerFeature {\n    \n    private static final Color SEPARATOR_COLOR = UIManager.getColor(\"Separator.foreground\"); // NOI18N\n\n    private static final Logger LOGGER = Logger.getLogger(RConsoleView.class.getName());\n    \n    private static final Icon ICON_EDIT = ImageUtilities.image2Icon(ImageUtilities.loadImage(RQueries.class.getPackage().getName().replace('.', '/') + \"/rules.png\", true));\n    \n    private final HeapContext context;\n    \n    private ProfilerToolbar toolbar;\n//    private ProfilerToolbar pluginsToolbar;\n//    private ProfilerToolbar resultsToolbar;\n    private ProfilerToolbar graphsToolbar;\n    private ProfilerToolbar progressToolbar;\n    \n    private JComponent component;\n    \n    private Action runAction;\n    private Action cancelAction;\n    private Action loadAction;\n    private Action saveAction;\n    private Action editAction;\n    \n    private JLabel progressLabel;\n    private JProgressBar progressBar;\n    \n    private REngine engine;\n    private REditorComponent editor;\n    \n    private JPanel resultsContainer;\n    private final HTMLView htmlView;\n//    private final PluggableTreeTableView objectsView;\n    \n    private JPanel graphsContainer;\n    private RPlotPanel graphsPanel;\n    \n    private JToggleButton rResults;\n    private JToggleButton rGraphs;\n    \n    private final AtomicBoolean analysisRunning = new AtomicBoolean(false);\n    private final ExecutorService progressUpdater = Executors.newSingleThreadExecutor();\n    private boolean queryValid;\n//    \n//    // TODO: synchronize!\n    private Set<HeapViewerNode> nodeResults;\n    \n    private RQueries.Query currentQuery;\n    \n    \n    RConsoleView(HeapContext context, HeapViewerActions actions) {\n        super(\"java_objects_rconsole\", Bundle.RConsoleView_Name(), Bundle.RConsoleView_Description(), createIcon(), 1100); // NOI18N\n        \n        this.context = context;\n        Heap heap = context.getFragment().getHeap();\n        \n//        engine = null;\n//        if (REngine.isSupported()) try {\n//            engine = new REngine(heap);\n//        } catch (Exception e) {\n//            LOGGER.log(Level.INFO, \"Error initializing REngine\", e);   // NOI18N\n//        }\n        \n//        if (engine != null) {\n//            TreeTableViewColumn[] ownColumns = new TreeTableViewColumn[] {\n//                new TreeTableViewColumn.Name(heap),\n//                new TreeTableViewColumn.Count(heap, false, false),\n//                new TreeTableViewColumn.OwnSize(heap, true, true),\n//                new TreeTableViewColumn.RetainedSize(heap, true, false)\n//            };\n//\n//            objectsView = new PluggableTreeTableView(\"java_objects_oql\", context, actions, ownColumns) { // NOI18N\n//                protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) {\n//                    if (nodeResults == null) return new HeapViewerNode[] { new TextNode(Bundle.OQLConsoleView_NothingExecuted()) };\n//                    else if (nodeResults.isEmpty()) return new HeapViewerNode[] { new TextNode(Bundle.OQLConsoleView_NoResults()) };\n//                    else return nodeResults.toArray(HeapViewerNode.NO_NODES);\n//                }\n//            };\n//            objectsView.setViewName(Bundle.OQLConsoleView_ViewName());\n\n            String htmlS = \"<initializing R engine...>\".replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\"); // NOI18N\n            htmlView = new HTMLView(\"java_objects_rconsole\", context, actions, \"<p>&nbsp;&nbsp;\" + htmlS + \"</p>\") { // NOI18N\n                @Override\n                protected String computeData(HeapContext context, String viewID) {\n                    if (REngine.isSupported()) try {\n                        engine = new REngine(heap);\n                    } catch (Exception e) {\n                        LOGGER.log(Level.INFO, \"Error initializing REngine\", e);   // NOI18N\n                    }\n                    \n                    updateUIState();\n                    \n                    if (engine != null) {\n//                        SwingUtilities.invokeLater(new Runnable() {\n//                            public void run() { graphsPanel.setContext(engine.getContext()); graphsPanel.repaint(); }\n//                        });\n                        \n                        String htmlS = Bundle.RConsoleView_NothingExecuted().replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\"); // NOI18N\n                        return \"<p>&nbsp;&nbsp;\" + htmlS + \"</p>\"; // NOI18N\n                    } else {\n                        String htmlS = \"<R engine not available>\".replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\"); // NOI18N\n                        return \"<p>&nbsp;&nbsp;\" + htmlS + \"</p>\"; // NOI18N\n                    }\n                }\n                protected HeapViewerNode nodeForURL(URL url, HeapContext context) {\n                    return RConsoleView.getNode(url, context);\n                }\n            };\n//        } else {\n////            objectsView = null;\n//            htmlView = null;\n//        }\n    }\n\n    \n    public JComponent getComponent() {\n        if (component == null) init();\n        return component;\n    }\n\n    public ProfilerToolbar getToolbar() {\n        if (toolbar == null) init();\n        return toolbar;\n    }\n    \n    \n    protected void willBeClosed(Runnable viewSelector) {\n        if (editor != null && editor.isChanged() && !editor.getScript().isEmpty() && saveAction.isEnabled()) {\n            viewSelector.run();\n            \n            Container c = editor;\n            while (c != null) {\n                Container p = c.getParent();\n                if (p instanceof JTabbedPane) {\n                    ((JTabbedPane)p).setSelectedComponent(c);\n                } else if (p instanceof TopComponent) {\n                    ((TopComponent)p).requestActive();\n                    break;\n                }\n                c = p;\n            }\n            \n            \n            JButton saveButton = new JButton(saveAction) {\n                public void addActionListener(ActionListener l) {\n                    if (l == saveAction) super.addActionListener(l);\n                }\n                public void removeActionListener(ActionListener l) {\n                    if (l == saveAction) super.removeActionListener(l);\n                }\n            };\n            JButton closeButton = new JButton(Bundle.RConsoleView_NoSaveOnCloseBtn());\n            DialogDescriptor dd = new DialogDescriptor(Bundle.RConsoleView_SaveOnClosingMsg(), Bundle.RConsoleView_SaveOnClosingCaption(), true, new Object[] { saveButton, closeButton }, saveButton, DialogDescriptor.DEFAULT_ALIGN, null, null);\n            dd.setMessageType(NotifyDescriptor.QUESTION_MESSAGE);\n            Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n            saveAction.putValue(\"NOTIFIER\", new Runnable() { // NOI18N\n                public void run() {\n                    saveAction.putValue(\"NOTIFIER\", null); // NOI18N\n                    d.setVisible(false);\n                }\n            });\n            d.setVisible(true);\n        }\n    }\n    \n    \n    private void executeQuery() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (nodeResults == null) nodeResults = new HashSet<>();\n                else nodeResults.clear();\n//                requestFocus();\n                executeQueryImpl(editor.getScript());\n            }\n        });\n    }\n    \n    private void cancelQuery() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                try {\n                    engine.cancelQuery();\n                } catch (Exception e) {\n\n                }\n                finalizeQuery(null);\n            }\n        });\n    }\n    \n    public void queryStarted(final BoundedRangeModel model) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                updateUIState();\n                graphsToolbar.getComponent().setVisible(false);\n                progressToolbar.getComponent().setVisible(true);\n                progressBar.setModel(model);\n            }\n        });\n    }\n\n    public void queryFinished(final String result) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                updateUIState();\n                progressToolbar.getComponent().setVisible(false);\n                graphsToolbar.getComponent().setVisible(rGraphs.isSelected());\n                progressBar.setModel(new DefaultBoundedRangeModel(0, 0, 0, 0));\n//                objectsView.reloadView();\n                \n                if (result != null) {\n                    htmlView.setText(result);\n//                    if (result.length() > 0 && nodeResults.isEmpty()) rHTML.setSelected(true);\n                }\n            }\n        });\n    }\n    \n    private void finalizeQuery(String result) {\n        analysisRunning.compareAndSet(true, false);\n        queryFinished(result);\n    }\n    \n    \n    private void updateUIState() {\n        int scriptLength = editor.getScript().trim().length();\n        \n//        saveAction.setEnabled(scriptLength > 0);\n        \n        if (analysisRunning.get()) {\n            runAction.setEnabled(false);\n            cancelAction.setEnabled(true);\n            loadAction.setEnabled(false);\n            editor.setEditable(false);\n        } else {\n            runAction.setEnabled(engine != null && scriptLength > 0 && queryValid);\n            cancelAction.setEnabled(false);\n            loadAction.setEnabled(true);\n            editor.setEditable(true);\n        }\n    }\n    \n    \n    private void executeQueryImpl(final String rQuery) {\n        Color b = graphsPanel.getBackground();\n        final String rgb = \"rgb(\" + b.getRed() + \", \" + b.getGreen() + \", \" + b.getBlue() + \", maxColorValue = 255)\";\n        \n        final BoundedRangeModel progressModel = new DefaultBoundedRangeModel(0, 10, 0, 100);\n\n//        SwingUtilities.invokeLater(new Runnable() {\n//            public void run() {\n                new RequestProcessor(\"R Query Processor\").post(new Runnable() { // NOI18N\n                    public void run() {\n                        final AtomicInteger counter = new AtomicInteger(100);\n                        progressModel.setMaximum(100);\n\n                        final StringBuilder sb = new StringBuilder();\n                        final boolean[] oddRow = new boolean[1];\n                        Color oddRowBackground = UIUtils.getDarker(\n                                        UIUtils.getProfilerResultsBackground());\n                        final String oddRowBackgroundString =\n                                \"rgb(\" + oddRowBackground.getRed() + \",\" + //NOI18N\n                                         oddRowBackground.getGreen() + \",\" + //NOI18N\n                                         oddRowBackground.getBlue() + \")\"; //NOI18N\n\n                        sb.append(\"<table border='0' width='100%'>\"); // NOI18N\n\n                        try {\n                            analysisRunning.compareAndSet(false, true);\n                            queryStarted(progressModel);\n                            progressUpdater.submit(new ProgressUpdater(progressModel));\n                            \n                            Context rContext = engine.getContext();\n                            \n                            Image rImage = graphsPanel.createPlotImage();\n                            Graphics rGraphics = rImage.getGraphics();\n                            int rImageW = rImage.getWidth(graphsPanel);\n                            int rImageH = rImage.getHeight(graphsPanel);\n                            \n                            Boolean renderingQuality = graphsPanel.getRenderingQuality();\n                            if (renderingQuality != null && rGraphics instanceof Graphics2D) {\n                                Graphics2D g2 = (Graphics2D)rGraphics;\n                                Object antialiasing = renderingQuality ? RenderingHints.VALUE_ANTIALIAS_ON :\n                                                                         RenderingHints.VALUE_ANTIALIAS_OFF;\n                                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antialiasing);\n                                Object text_antialiasing = renderingQuality ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON :\n                                                                              RenderingHints.VALUE_TEXT_ANTIALIAS_OFF;\n                                g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, text_antialiasing);\n                            }\n                            \n                            rContext.eval(\"R\", \"function(g, w, h) { grDevices:::awt(w, h, g); }\").execute(rGraphics, rImageW, rImageH);\n                            \n                            rContext.eval(\"R\",\"library(grid); grid.rect(width = 1, height = 1, gp = gpar(col = \" + rgb + \", fill = \" + rgb + \"));\");\n                            \n                            engine.executeQuery(rQuery, new ObjectVisitor() {\n                                public boolean visit(Object o) {\n                                    sb.append(oddRow[0] ?\n                                        \"<tr><td style='background-color: \" + // NOI18N\n                                        oddRowBackgroundString + \";'>\" : \"<tr><td>\"); // NOI18N\n                                    oddRow[0] = !oddRow[0];\n                                    dump(o, sb);\n                                    sb.append(\"</td></tr>\"); // NOI18N\n                                    return counter.decrementAndGet() == 0 || (!analysisRunning.get() && !engine.isCancelled()); // process all hits while the analysis is running\n                                }\n                            });\n                            \n                            rContext.eval(\"R\",\"dev.off();\");\n                            rGraphics.dispose();\n                            \n                            graphsPanel.repaint();\n\n                            if (counter.get() == 0) {\n                                sb.append(\"<tr><td>\");  // NOI18N\n                                sb.append(\"&lt;too many results&gt\");      // NOI18N\n                                sb.append(\"</td></tr>\");   // NOI18N\n                            } else if (counter.get() == 100) {\n                                sb.append(\"<tr><td>\"); // NOI18N\n                                sb.append(\"&lt;no results&gt\"); // NOI18N\n                                sb.append(\"</td></tr>\" ); // NOI18N\n                            }\n\n                            sb.append(\"</table>\"); // NOI18N\n\n                            finalizeQuery(sb.toString());\n                        } catch (Exception oQLException) {\n                            LOGGER.log(Level.INFO, \"Error executing R\", oQLException);   // NOI18N\n                            StringBuilder errorMessage = new StringBuilder();\n                            String exceptionMsg = oQLException.getLocalizedMessage();\n                            errorMessage.append(\"<h2>\").append(\"Query error\").append(\"</h2>\"); // NOI18N\n                            errorMessage.append(\"Bad R query\"); // NOI18N\n                            errorMessage.append(\"<hr>\"); // NOI18N\n                            if (exceptionMsg != null) {\n                                errorMessage.append(exceptionMsg.replace(\"\\n\", \"<br>\").replace(\"\\r\", \"<br>\"));  // NOI18N\n                            }\n                            finalizeQuery(errorMessage.toString());\n                        }\n                    }\n\n                });\n//            }\n//        });\n    }\n    \n    \n    private void dump(Object o, StringBuilder sb) {\n        String text = o.toString();\n        \n        text = text.replace(\" \", \"&nbsp;\");\n        sb.append(\"<code>\").append(text).append(\"</code>\\n\");\n    }\n\n    private void init() {\n        toolbar = ProfilerToolbar.create(false);\n//        if (engine != null) {\n            toolbar.addSpace(2);\n            toolbar.addSeparator();\n            toolbar.addSpace(5);\n\n            toolbar.add(new GrayLabel(Bundle.RConsoleView_RQuery()));\n            toolbar.addSpace(2);\n            \n            runAction = new RunAction();\n\n            JButton runButton = new JButton(runAction) {\n                public Dimension getPreferredSize() {\n                    Dimension d = super.getPreferredSize();\n                    d.width += 6;\n                    return d;\n                }\n                public Dimension getMinimumSize() {\n                    return getPreferredSize();\n                }\n                public Dimension getMaximumSize() {\n                    return getPreferredSize();\n                }\n            };\n            runButton.putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n            \n            cancelAction = new AbstractAction(Bundle.RConsoleView_CancelAction(), Icons.getIcon(GeneralIcons.STOP)) {\n                {\n                    putValue(Action.SHORT_DESCRIPTION, Bundle.RConsoleView_CancelActionTooltip());\n                }\n                public void actionPerformed(ActionEvent e) {\n                    cancelQuery();\n                }\n            };\n\n            JButton cancelButton = new JButton(cancelAction);\n            cancelButton.setHideActionText(true);\n            \n            loadAction = new AbstractAction(Bundle.RConsoleView_LoadAction(), RQueries.ICON_LOAD) {\n                {\n                    putValue(Action.SHORT_DESCRIPTION, Bundle.RConsoleView_LoadActionTooltip());\n                }\n                public void actionPerformed(ActionEvent e) {\n                    if (e.getSource() instanceof JComponent) {\n                        JPopupMenu p = new JPopupMenu();\n                        RQueries.instance().populateLoadQuery(p, currentQuery, new RQueries.Handler() {\n                            protected void querySelected(RQueries.Query query) {\n                                currentQuery = query;\n                                if (editor != null) editor.setScript(currentQuery.getScript());\n                            }\n                        });\n                        \n                        JComponent c = (JComponent)e.getSource();\n                        if (p.getComponentCount() > 0) {\n                            if (c.getClientProperty(\"POPUP_LEFT\") != null) p.show(c, c.getWidth() + 1, 0); // NOI18N\n                            else p.show(c, 0, c.getHeight() + 1);\n                        }\n                        \n                    }\n                }\n            };\n            \n            JButton loadButton = new JButton(loadAction);\n            loadButton.setHideActionText(true);\n            \n            saveAction = new AbstractAction(Bundle.RConsoleView_SaveAction(), RQueries.ICON_SAVE) {\n                {\n                    putValue(Action.SHORT_DESCRIPTION, Bundle.RConsoleView_SaveActionTooltip());\n                }\n                public void actionPerformed(ActionEvent e) {\n                    if (e.getSource() instanceof JComponent) {\n                        JPopupMenu p = new JPopupMenu();\n                        RQueries.instance().populateSaveQuery(p, currentQuery, editor.getScript(), new RQueries.Handler() {\n                            protected void querySelected(RQueries.Query query) {\n                                currentQuery = query;\n                                editor.clearChanged();\n                                                \n                                Object notifier = saveAction.getValue(\"NOTIFIER\"); // NOI18N\n                                if (notifier instanceof Runnable) ((Runnable)notifier).run();\n                            }\n                        });\n                        \n                        JComponent c = (JComponent)e.getSource();\n                        if (p.getComponentCount() > 0) {\n                            if (c.getClientProperty(\"POPUP_LEFT\") != null) p.show(c, c.getWidth() + 1, 0); // NOI18N\n                            else p.show(c, 0, c.getHeight() + 1);\n                        }\n                        \n                    }\n                }\n            };\n            \n            JButton saveButton = new JButton(saveAction);\n            saveButton.setHideActionText(true);\n//            \n            editAction = new AbstractAction(Bundle.RConsoleView_EditAction(), ICON_EDIT) {\n                {\n                    putValue(Action.SHORT_DESCRIPTION, Bundle.RConsoleView_EditActionTooltip());\n                }\n                public void actionPerformed(ActionEvent e) {\n                    if (e.getSource() instanceof JComponent) {\n                        JPopupMenu p = new JPopupMenu();\n                        RQueries.instance().populateEditQuery(p, currentQuery);\n                        \n                        JComponent c = (JComponent)e.getSource();\n                        if (p.getComponentCount() > 0) {\n                            if (c.getClientProperty(\"POPUP_LEFT\") != null) p.show(c, c.getWidth() + 1, 0); // NOI18N\n                            else p.show(c, 0, c.getHeight() + 1);\n                        }\n                        \n                    }\n                }\n            };\n            \n            JButton editButton = new JButton(editAction);\n            editButton.setHideActionText(true);\n\n            graphsPanel = new RPlotPanel();\n            \n            graphsToolbar = ProfilerToolbar.create(false);\n\n            graphsToolbar.addSpace(2);\n            graphsToolbar.addSeparator();\n            graphsToolbar.addSpace(5);\n\n            graphsToolbar.add(new GrayLabel(\"Rendering Quality:\"));\n            graphsToolbar.addSpace(2);\n            \n            Action defaultA = new AbstractAction(\"Default\") {\n                @Override\n                public void actionPerformed(ActionEvent e) {\n                    graphsPanel.setRenderingQuality(null);\n                }\n            };\n            Action highA = new AbstractAction(\"High\") {\n                @Override\n                public void actionPerformed(ActionEvent e) {\n                    graphsPanel.setRenderingQuality(Boolean.TRUE);\n                }\n            };\n            Action lowA = new AbstractAction(\"Low\") {\n                @Override\n                public void actionPerformed(ActionEvent e) {\n                    graphsPanel.setRenderingQuality(Boolean.FALSE);\n                }\n            };\n            \n            graphsToolbar.add(new ActionPopupButton(defaultA, highA, lowA));\n            \n            progressToolbar = ProfilerToolbar.create(false);\n            progressToolbar.getComponent().setVisible(false);\n            \n            progressToolbar.addSpace(2);\n            progressToolbar.addSeparator();\n            progressToolbar.addSpace(5);\n            \n            progressLabel = new GrayLabel(Bundle.RConsoleView_ExecutingProgress());\n            progressToolbar.add(progressLabel);\n            \n            progressToolbar.addSpace(8);\n\n            progressBar = new JProgressBar(JProgressBar.HORIZONTAL) {\n                public Dimension getPreferredSize() {\n                    Dimension dim = super.getMinimumSize();\n                    dim.width = 120;\n                    return dim;\n                }\n                public Dimension getMinimumSize() {\n                    return getPreferredSize();\n                }\n                public Dimension getMaximumSize() {\n                    return getPreferredSize();\n                }\n            };\n            progressToolbar.add(progressBar);\n\n            toolbar.add(runButton);\n    //        toolbar.addSpace(2);\n            toolbar.add(cancelButton);\n            \n            toolbar.addSpace(5);\n            \n            toolbar.add(loadButton);\n            toolbar.add(saveButton);\n            toolbar.add(editButton);\n\n//            resultsToolbar = ProfilerToolbar.create(false);\n//\n            toolbar.addSpace(2);\n            toolbar.addSeparator();\n            toolbar.addSpace(5);\n\n            toolbar.add(new GrayLabel(\"Results:\"));\n            toolbar.addSpace(3);\n\n//            ButtonGroup resultsBG = new ButtonGroup();\n\n            String rResultsPath = RConsoleView.class.getPackage().getName().replace('.', '/') + \"/properties.png\";\n            Image rResultsImage = ImageUtilities.loadImage(rResultsPath, true);\n            rResults = new JToggleButton(new ImageIcon(rResultsImage), true) {\n                protected void fireItemStateChanged(ItemEvent e) {\n//                    if (e.getStateChange() == ItemEvent.SELECTED) {\n                        if (resultsContainer != null) resultsContainer.setVisible(isSelected());\n//                    }\n                }\n            };\n            rResults.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            rResults.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n            rResults.setToolTipText(\"Text\");\n//            resultsBG.add(rResults);\n            toolbar.add(rResults);\n            \n            String rGraphsPath = RConsoleView.class.getPackage().getName().replace('.', '/') + \"/showGraphs.png\";\n            Image rGraphsImage = ImageUtilities.loadImage(rGraphsPath, true);\n            rGraphs = new JToggleButton(new ImageIcon(rGraphsImage), true) {\n                protected void fireItemStateChanged(ItemEvent e) {\n//                    if (e.getStateChange() == ItemEvent.SELECTED) {\n                        if (graphsContainer != null) {\n                            boolean selected = isSelected();\n                            graphsToolbar.getComponent().setVisible(selected && !progressToolbar.getComponent().isVisible());\n                            graphsContainer.setVisible(selected);\n                        }\n//                    }\n                }\n            };\n            rGraphs.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            rGraphs.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n            rGraphs.setToolTipText(\"Graphs\");\n//            resultsBG.add(rGraphs);\n            toolbar.add(rGraphs);\n//\n//            if (objectsView.hasPlugins()) {\n//                pluginsToolbar = ProfilerToolbar.create(false);\n//    //            detailsToolbar.addSpace(2);\n//    //            detailsToolbar.addSeparator();\n//                pluginsToolbar.addSpace(8);\n//\n//                pluginsToolbar.add(new GrayLabel(Bundle.OQLConsoleView_Details()));\n//                pluginsToolbar.addSpace(2);\n//\n//                pluginsToolbar.add(objectsView.getToolbar());\n//\n//                resultsToolbar.add(pluginsToolbar);\n//            }\n//\n//            toolbar.add(resultsToolbar);\n\n            toolbar.add(graphsToolbar);\n            \n            toolbar.add(progressToolbar);\n\n            editor = new REditorComponent(/*engine*/) {\n                protected void validityChanged(boolean valid) {\n                    queryValid = valid;\n                    updateUIState();\n                }\n            };\n\n            resultsContainer = new JPanel(new CardLayout());\n//            resultsContainer.add(objectsView.getComponent());\n            resultsContainer.add(new ResultsView(htmlView.getComponent()));\n            \n//            graphsPanel = new RPlotPanel();\n            graphsContainer = new JPanel(new BorderLayout());\n            graphsContainer.add(graphsPanel, BorderLayout.CENTER);\n            \n            MultiSplitContainer resultsSplit = new MultiSplitContainer();\n            resultsSplit.add(resultsContainer);\n            resultsSplit.add(graphsContainer);\n\n            JExtendedSplitPane masterSplit = new JExtendedSplitPane(JExtendedSplitPane.VERTICAL_SPLIT, true, resultsSplit, new EditorView(editor));\n            BasicSplitPaneDivider masterDivider = ((BasicSplitPaneUI)masterSplit.getUI()).getDivider();\n            masterDivider.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, SEPARATOR_COLOR));\n            masterDivider.setDividerSize(6);\n            masterSplit.setBorder(BorderFactory.createEmptyBorder());\n            masterSplit.setResizeWeight(0.70d);\n\n            component = new JPanel(new BorderLayout());\n            component.add(masterSplit, BorderLayout.CENTER);\n\n            JComponent toolbarComp = toolbar.getComponent();\n            setShortcut(runAction, toolbarComp);\n            setShortcut(runAction, component);\n            toolbarComp.repaint();\n            updateUIState();\n//        } else {\n//            component = new JPanel(new BorderLayout());\n//            component.setOpaque(true);\n//            component.setBackground(UIUtils.getProfilerResultsBackground());\n//            \n//            JLabel l = new JLabel(Bundle.OQLConsoleView_EngineNotAvailable(), JLabel.CENTER);\n//            l.setEnabled(false);\n//            l.setOpaque(false);\n//            component.add(l, BorderLayout.CENTER);\n//        }\n    }\n    \n    private void setShortcut(Action a, JComponent jc) {\n        Object actionName = a.getValue(Action.ACTION_COMMAND_KEY);\n        KeyStroke shortcut = (KeyStroke) a.getValue(Action.ACCELERATOR_KEY);\n        jc.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(shortcut, actionName);\n        jc.getActionMap().put(actionName, a);\n    }\n\n    \n    private static HeapViewerNode getNode(URL url, HeapContext context) {\n        String urls = url.toString();\n                \n        if (HeapUtils.isInstance(urls)) {\n            final Instance instance = HeapUtils.instanceFromHtml(urls, context.getFragment().getHeap());\n            if (instance != null) return new InstanceNode(instance);\n            else ProfilerDialogs.displayError(Bundle.RConsoleView_CannotResolveInstanceMsg());\n        } else if (HeapUtils.isClass(urls)) {\n            JavaClass javaClass = HeapUtils.classFromHtml(urls, context.getFragment().getHeap());\n            if (javaClass != null) return new ClassNode(javaClass);\n            else ProfilerDialogs.displayError(Bundle.RConsoleView_CannotResolveClassMsg());\n        }\n\n        return null;\n    }\n    \n    \n    private static ImageIcon createIcon() {\n        String consolePath = RConsoleView.class.getPackage().getName().replace('.', '/') + \"/rConsole.png\";\n        Image consoleImage = ImageUtilities.loadImage(consolePath, true);\n        \n        String badgePath = RConsoleView.class.getPackage().getName().replace('.', '/') + \"/rBadge.png\";\n        Image badgeImage = ImageUtilities.loadImage(badgePath, true);\n        \n        return new ImageIcon(ImageUtilities.mergeImages(consoleImage, badgeImage, 0, 0));\n    }\n    \n    \n    private class ProgressUpdater implements Runnable {\n\n        private final BoundedRangeModel progressModel;\n\n        ProgressUpdater(BoundedRangeModel model) {\n            progressModel = model;\n        }\n\n        public void run() {\n            while (analysisRunning.get()) {\n                final int newVal;\n                int val = progressModel.getValue() + 10;\n                \n                if (val > progressModel.getMaximum()) {\n                    val = progressModel.getMinimum();\n                }\n                newVal = val;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        progressModel.setValue(newVal);\n                    }\n                });\n                try {\n                    Thread.sleep(200);\n                } catch (InterruptedException e) {\n                    Thread.currentThread().interrupt();\n                }\n            }\n        }\n    }\n    \n    private final class RunAction extends AbstractAction {\n        private static final String ACTION_NAME  = \"runScript_Action\";     // NOI18N\n        private final KeyStroke shortcut = KeyStroke.getKeyStroke(\"ctrl R\");  // NOI18N\n\n        private RunAction() {\n            super(Bundle.RConsoleView_RunAction(), Icons.getIcon(GeneralIcons.START));\n            putValue(Action.SHORT_DESCRIPTION, Bundle.RConsoleView_RunActionTooltip());\n            putValue(Action.ACTION_COMMAND_KEY, ACTION_NAME);\n            putValue(Action.ACCELERATOR_KEY, shortcut);\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            executeQuery();\n        }\n    }\n\n    \n    private class EditorView extends JPanel {\n        \n        EditorView(REditorComponent editor) {\n            super(new BorderLayout());\n            \n            editor.clearScrollBorders();\n            add(editor, BorderLayout.CENTER);\n//            add(new ScrollableContainer(editorContainer), BorderLayout.CENTER);\n\n            JToolBar controls = new JToolBar(JToolBar.VERTICAL);\n            controls.setFloatable(false);\n            controls.setBorderPainted(false);\n            controls.add(runAction);\n            controls.add(cancelAction);\n            controls.addSeparator();\n            controls.add(loadAction).putClientProperty(\"POPUP_LEFT\", Boolean.TRUE); // NOI18N\n            controls.add(saveAction).putClientProperty(\"POPUP_LEFT\", Boolean.TRUE); // NOI18N\n            controls.add(editAction).putClientProperty(\"POPUP_LEFT\", Boolean.TRUE); // NOI18N\n            \n            JPanel controlsContainer = new JPanel(new BorderLayout());\n            controlsContainer.setOpaque(false);\n            controlsContainer.setBorder(BorderFactory.createCompoundBorder(\n                    BorderFactory.createMatteBorder(0, 0, 0, 1, UIManager.getColor(\"Separator.foreground\")), // NOI18N\n                    BorderFactory.createEmptyBorder(1, 1, 1, 1)));\n            controlsContainer.add(controls, BorderLayout.CENTER);\n            add(controlsContainer, BorderLayout.WEST);\n            \n            // size to always show Run and Stop buttons\n            int h = controls.getComponent(0).getPreferredSize().height;\n            h += controls.getComponent(1).getPreferredSize().height + 2;\n            setMinimumSize(new Dimension(0, h));\n        }\n        \n    }\n    \n    \n    private static class ResultsView extends JPanel {\n        \n        ResultsView(JComponent results) {\n            super(new BorderLayout());\n            add(new ScrollableContainer(results), BorderLayout.CENTER);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/REditorComponent.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.console.r;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.JEditorPane;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextField;\nimport javax.swing.UIManager;\nimport javax.swing.border.Border;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.Caret;\nimport javax.swing.text.DefaultEditorKit;\nimport javax.swing.text.Document;\nimport javax.swing.text.EditorKit;\nimport javax.swing.text.Element;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.PlainView;\nimport javax.swing.text.View;\nimport javax.swing.text.ViewFactory;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.NoCaret;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass REditorComponent extends JPanel {\n\n    private static final String VALIDITY_PROPERTY = \"document#valid\";\n//    \n//    private volatile boolean lexervalid;\n//    private volatile boolean parserValid;\n    private volatile boolean oldValidity;\n//    \n//    \n//    private final OQLEngine engine;\n    \n    private JEditorPane queryEditor;\n    private JScrollBar verticalScroller;\n\n    private Color lastBgColor;\n    private Caret lastCaret;\n    \n    private boolean changed;\n\n    \n    REditorComponent(/*OQLEngine engine*/) {\n//        this.engine = engine;\n        init();\n    }\n    \n    \n    public void setScript(String script) {\n        queryEditor.setText(script);\n        clearChanged();\n        try { queryEditor.setCaretPosition(0); } catch (IllegalArgumentException e) {}\n        scrollRectToVisible(new Rectangle());\n    }\n\n    public String getScript() {\n        return queryEditor.getText();\n    }\n    \n    \n    protected void validityChanged(boolean valid) {}\n    \n    \n    final void clearChanged() {\n        changed = false;\n    }\n    \n    public final boolean isChanged() {\n        return changed;\n    }\n\n    \n    public void setEnabled(boolean b) {\n        super.setEnabled(b);\n        if (verticalScroller != null) updateScroller(verticalScroller);\n    }\n    \n    public void setBackground(Color bg) {\n        super.setBackground(bg);\n        if (queryEditor != null) queryEditor.setBackground(bg);\n    }\n\n    public void setOpaque(boolean isOpaque) {\n        super.setOpaque(isOpaque);\n        if (queryEditor != null) queryEditor.setOpaque(isOpaque);\n    }\n\n    public void requestFocus() {\n        if (queryEditor != null) queryEditor.requestFocus();\n    }    \n\n    public void setEditable(boolean b) {\n        if (queryEditor.isEditable() == b) return;\n        \n        queryEditor.setEditable(b);\n\n        if (b) {\n            if (lastBgColor != null) queryEditor.setBackground(lastBgColor);\n            if (lastCaret != null) queryEditor.setCaret(lastCaret);\n        } else {\n            lastBgColor = queryEditor.getBackground();\n            lastCaret = queryEditor.getCaret();\n            \n            Color disabledBackground = UIUtils.isGTKLookAndFeel() ?\n                  UIManager.getLookAndFeel().getDefaults().getColor(\"desktop\") : // NOI18N\n                  UIManager.getColor(\"TextField.disabledBackground\"); // NOI18N\n            queryEditor.setBackground(disabledBackground);\n            queryEditor.setCaret(new NoCaret());\n        }\n    }\n\n    public boolean isEditable() {\n        return queryEditor.isEditable();\n    }\n    \n    public void clearScrollBorders() {\n        if (getComponentCount() > 0) {\n            Component c = getComponent(0);\n            if (c instanceof JScrollPane) {\n                ((JScrollPane)c).setBorder(BorderFactory.createEmptyBorder());\n                ((JScrollPane)c).setViewportBorder(BorderFactory.createEmptyBorder());\n            }\n        }\n    }\n    \n    \n    private void init() {\n        setOpaque(true);\n        setBackground(UIUtils.getProfilerResultsBackground());\n        \n//        OQLEditorImpl impl = Lookup.getDefault().lookup(OQLEditorImpl.class);\n//        if (impl != null) {\n//            queryEditor = impl.getEditorPane();\n//            queryEditor.getDocument().putProperty(OQLEngine.class, engine);\n//            queryEditor.getDocument().putProperty(OQLEditorImpl.ValidationCallback.class, new OQLEditorImpl.ValidationCallback() {\n//                public void callback(boolean lexingResult) {\n//                    lexervalid = lexingResult;\n//                    validateScript();\n//                }\n//            });\n//            \n//            queryEditor.getCaret().addChangeListener(new ChangeListener() {\n//                public void stateChanged(ChangeEvent e) {\n//                    try {\n//                        Rectangle edit = queryEditor == null ? null :\n//                                         queryEditor.getUI().modelToView(\n//                                         queryEditor, queryEditor.getCaretPosition());\n//                        if (edit != null) queryEditor.scrollRectToVisible(edit);\n//                    } catch (BadLocationException ex) {\n//                        Exceptions.printStackTrace(ex);\n//                    }\n//                }\n//            });\n//            \n//            Element root = queryEditor.getDocument().getDefaultRootElement();\n//            String family = StyleConstants.getFontFamily(root.getAttributes());\n//            queryEditor.setFont(new Font(family, Font.PLAIN, new JEditorPane().getFont().getSize()));\n//        } else {\n            final DocumentListener listener = new DocumentListener() {\n                public void insertUpdate(DocumentEvent e)  { validateScript(); }\n                public void removeUpdate(DocumentEvent e)  { validateScript(); }\n                public void changedUpdate(DocumentEvent e) { validateScript(); }\n            };\n            final DocumentListener editHandler = new DocumentListener() {\n                public void insertUpdate(DocumentEvent e)  { handleEdit(); }\n                public void removeUpdate(DocumentEvent e)  { handleEdit(); }\n                public void changedUpdate(DocumentEvent e) { handleEdit(); }\n                private void handleEdit() { changed = true; }\n            };\n            \n            queryEditor = new JEditorPane() {\n                protected EditorKit createDefaultEditorKit() {\n                    return new OQLEditorKit();\n                }\n                public void setText(String text) {\n                    Document doc = getDocument();\n                    if (doc != null) {\n                        doc.removeDocumentListener(listener);\n                        doc.removeDocumentListener(editHandler);\n                    }\n                    setDocument(getEditorKit().createDefaultDocument());\n                    doc = getDocument();\n                    if (doc != null) doc.addDocumentListener(listener);\n                    super.setText(text);\n                    if (doc != null) doc.addDocumentListener(editHandler);\n                }\n            };\n            \n            queryEditor.setFont(Font.decode(Font.MONOSPACED + \" \" + queryEditor.getFont().getSize())); // NOI18N\n//            lexervalid = true; // no lexer info available; assume the lexing info is valid\n//        }\n\n        // IMPORTANT: setText() is required to register document listener/validity check!\n        queryEditor.setText(\"\");\n        \n        queryEditor.setOpaque(isOpaque());\n        queryEditor.setBackground(getBackground());\n        \n        // Do not display NB TopComponent switcher, let the focus subsystem transfer the focus out of the editor\n        queryEditor.putClientProperty(\"nb.ctrltab.popupswitcher.disable\", Boolean.TRUE); // NOI18N\n        \n        int rowSize = queryEditor.getFontMetrics(queryEditor.getFont()).getHeight();\n        \n        final JScrollPane editorScroll = new JScrollPane(queryEditor,\n                        JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,\n                        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n        editorScroll.getHorizontalScrollBar().setUnitIncrement(rowSize);\n        verticalScroller = editorScroll.getVerticalScrollBar();\n        verticalScroller.setUnitIncrement(rowSize);\n        verticalScroller.getModel().addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) { updateScroller(verticalScroller); }\n        });\n        \n        JTextField tf = new JTextField(\" 999 \"); // NOI18N\n        tf.setBorder(BorderFactory.createEmptyBorder());\n        tf.setMargin(new Insets(0, 0, 0, 0));\n        tf.setFont(queryEditor.getFont());\n        final int w = tf.getPreferredSize().width;\n\n        final JEditorPane rows = new JEditorPane() {\n            {\n                setEditorKit(queryEditor.getEditorKit());\n                setFont(queryEditor.getFont());\n            }\n            public Dimension getPreferredSize() {\n                Dimension dim = new Dimension(w, 0);\n                int refHeight = queryEditor.getPreferredSize().height;\n                int viewHeight = editorScroll.getViewport().getExtentSize().height;\n                dim.height = Math.max(refHeight, viewHeight);\n                return dim;\n            }\n            public void setBackground(Color c) {\n                super.setBackground(new Color(245, 245, 245));\n            }\n        };\n\n        rows.setCaret(new FollowingCaret(queryEditor));\n        StringBuilder sb = new StringBuilder();\n        for (int i = 1; i < 1000; i++) {\n            if (i < 1000) sb.append(\" \"); // NOI18N\n            if (i < 100) sb.append(\" \"); // NOI18N\n            if (i < 10) sb.append(\" \"); // NOI18N\n            sb.append(Integer.toString(i) + \" \\n\"); // NOI18N\n        }\n        rows.setText(sb.toString());\n        rows.setEditable(false);\n        rows.setEnabled(false);\n\n        Insets margin = queryEditor.getMargin();\n        if (margin == null) margin = new Insets(0, 0, 0, 0);\n        rows.setMargin(new Insets(margin.top, 0, margin.bottom, 0));\n\n        Border border = queryEditor.getBorder();\n        if (border != null) {\n            margin = border.getBorderInsets(queryEditor);\n            if (margin == null) margin = new Insets(0, 0, 0, 0);\n            rows.setBorder(BorderFactory.createEmptyBorder(margin.top, -1, margin.bottom, 0));\n        }\n        \n        editorScroll.setRowHeaderView(rows);\n        \n        setLayout(new BorderLayout());\n        add(editorScroll, BorderLayout.CENTER);\n    }\n    \n    private void updateScroller(JScrollBar scroll) {\n        scroll.setEnabled(isEnabled() && scroll.getVisibleAmount() < scroll.getMaximum());\n    }\n    \n    private void validateScript() {\n//        if (engine == null) return;\n//        \n//        if (lexervalid || !parserValid) {\n//            // only parse the query if there are no errors from lexer\n//            try {\n//                engine.parseQuery(getScript());\n//                parserValid = true;\n//            } catch (OQLException e) {\n//                StatusDisplayer.getDefault().setStatusText(e.getLocalizedMessage());\n//                parserValid = false;\n//            }\n//        }\n//\n        String script = getScript();\n        boolean valid = script != null && !script.isEmpty();\n\n        firePropertyChange(VALIDITY_PROPERTY, oldValidity, valid);\n        oldValidity = valid;\n        \n        validityChanged(oldValidity);\n    }\n    \n    \n    private static class OQLEditorKit extends DefaultEditorKit {\n        \n        private static final ViewFactory FACTORY = new ViewFactory() {\n            public View create(Element elem) { return new PlainView(elem); }\n        };\n        \n        public String getContentType() {\n            return \"text/x-oql\"; // NOI18N\n        }\n        \n        public ViewFactory getViewFactory() {\n            return FACTORY;\n        }\n        \n    }\n    \n    private static class FollowingCaret implements Caret {\n                \n        private final List<ChangeListener> listeners = new ArrayList<>();\n        private int dot;\n\n        FollowingCaret(final JTextComponent tc) {\n            tc.getCaret().addChangeListener(new ChangeListener() {\n                public void stateChanged(ChangeEvent e) {\n                    setDot(followedPosition(tc));\n                }\n            });\n            setDot(followedPosition(tc));\n        }\n\n        private static int followedPosition(JTextComponent tc) {\n            Element root = tc.getDocument().getDefaultRootElement();\n            return root.getElementIndex(tc.getCaretPosition()) * 6;\n        }\n\n        public void install(JTextComponent c) {}\n        public void deinstall(JTextComponent c) {}\n        public void paint(Graphics g) {}\n        public void addChangeListener(ChangeListener l) { listeners.add(l); }\n        public void removeChangeListener(ChangeListener l) { listeners.remove(l); }\n        public boolean isVisible() { return false; }\n        public void setVisible(boolean v) {}\n        public boolean isSelectionVisible() { return false; }\n        public void setSelectionVisible(boolean v) {}\n        public void setMagicCaretPosition(Point p) {}\n        public Point getMagicCaretPosition() { return new Point(0, 0); }\n        public void setBlinkRate(int rate) {}\n        public int getBlinkRate() { return 1; }\n        public int getDot() { return dot; }\n        public int getMark() { return dot; }\n        public void moveDot(int dot) {}\n        \n        public void setDot(int dot) {\n            this.dot = dot;\n            ChangeEvent e = new ChangeEvent(this);\n            for (ChangeListener l : listeners) l.stateChanged(e);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/RPlotPanel.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.console.r;\n\nimport java.awt.AWTException;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Image;\nimport java.awt.ImageCapabilities;\nimport java.awt.RenderingHints;\nimport java.util.Objects;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass RPlotPanel extends JPanel {\n    \n    private Image offscreenImage;\n    \n    private Boolean renderingQuality;\n    \n    \n    RPlotPanel() {\n        setOpaque(true);\n        setBackground(UIUtils.getProfilerResultsBackground());\n    }\n    \n    \n    final void setRenderingQuality(Boolean renderingQuality) {\n        boolean change = !Objects.equals(this.renderingQuality, renderingQuality);\n        this.renderingQuality = renderingQuality;\n        if (change) repaint();\n    }\n    \n    final Boolean getRenderingQuality() {\n        return renderingQuality;\n    }\n    \n    \n    Image createPlotImage() {\n        int w = getWidth();\n        int h = getHeight();\n        \n        if (w <= 0 || h <= 0) {\n            offscreenImage = null;\n        } else {\n            try {\n                offscreenImage = createVolatileImage(getWidth(), getHeight(), new ImageCapabilities(true));\n            } catch (AWTException e1) {\n                try {\n                    offscreenImage = createVolatileImage(getWidth(), getHeight(), new ImageCapabilities(false));\n                } catch (AWTException e2) {\n                    offscreenImage = createImage(getWidth(), getHeight());\n                }\n            }\n        }\n        \n        return offscreenImage;\n    }\n    \n    \n    @Override\n    public void paint(Graphics g) {\n        super.paint(g);\n        \n        int w = getWidth();\n        int h = getHeight();\n        \n        if (renderingQuality != null && g instanceof Graphics2D) {\n            Object interpolation = renderingQuality ? RenderingHints.VALUE_INTERPOLATION_BICUBIC :\n                                                      RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;\n            ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolation);\n        }\n        \n        Image img = offscreenImage; // not synchronized, createPlotImage() called from worker thread\n        if (img != null && w > 0 && h > 0) g.drawImage(img, 0, 0, w, h, null);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/RQueries.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.console.r;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Locale;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SwingUtilities;\nimport javax.swing.filechooser.FileFilter;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.openide.awt.StatusDisplayer;\nimport org.openide.util.Exceptions;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"RQueries_LoadingProgress=Loading Saved R scripts...\",\n//    \"RQueries_PopupCaptionLoad=<html><b>Load R Script</b>: Select Source</html>\",\n    \"RQueries_PopupLoadCustomScript=Load Custom Script:\",\n    \"RQueries_PopupSaveCustomScript=Save Custom Script:\",\n    \"RQueries_PopupNoSaved=<no saved scripts>\",\n    \"RQueries_PopupNoCustom=<no custom scripts>\",\n    \"RQueries_PopupLoadExternalScript=Load External Script:\",\n    \"RQueries_PopupSaveExternalScript=Save External Script:\",\n    \"RQueries_PopupLoadFromFile=Load From File...\",\n    \"RQueries_PopupLoadPredefinedScript=Load Predefined Script:\",\n    \"RQueries_PopupLoadingScripts=Loading Saved R scripts...\",\n//    \"RQueries_PopupCaptionSave=<html><b>Save R Script</b>: Select Target</html>\",\n    \"RQueries_PopupSaveNew=Save As New...\",\n    \"RQueries_PopupSaveFile=Save To New File...\",\n    \"RQueries_LoadExternalCaption=Load External R Script\",\n    \"# {0} - R files\",\n    \"RQueries_RFileFilter=R Script Files ({0})\",\n    \"RQueries_InvalidScript=Invalid R script file.\",\n    \"RQueries_LoadFailed=Failed to load R script.\",\n    \"RQueries_SaveFailed=Failed to save R script.\",\n    \"RQueries_SaveExternalCaption=Save External R Script\",\n    \"RQueries_PopupLoadSampleScript=Load Sample Script:\",\n    \"RQueries_PopupEditCustom=Edit Properties\",\n    \"RQueries_PopupDeleteCustom=Delete\",\n    \"RQueries_PopupDeleteAllCustom=Delete All Custom Scripts\",\n    \"RQueries_CurrentScriptFlag=[current]\"\n        \n})\nfinal class RQueries {\n    \n    private static final Icon ICON_PROGRESS = ImageUtilities.image2Icon(ImageUtilities.loadImage(RQueries.class.getPackage().getName().replace('.', '/') + \"/progress.png\", true)); // NOI18N\n    \n    static final Icon ICON_LOAD = ImageUtilities.image2Icon(ImageUtilities.loadImage(RQueries.class.getPackage().getName().replace('.', '/') + \"/rLoad.png\", true)); // NOI18N\n    static final Icon ICON_SAVE = Icons.getIcon(GeneralIcons.SAVE);\n    private static final Icon ICON_EMPTY = Icons.getIcon(GeneralIcons.EMPTY);\n    \n    private static final int EXTERNAL_QUERIES_CACHE = 5;\n    \n    \n    private static RQueries INSTANCE;\n    \n    private CustomRQueries customQueries;\n//    private List<? extends RQueryCategory> predefinedCategories;\n    \n    private List<Query> externalQueries;\n    \n    private JPopupMenu tempPopup;\n    private Query tempCurrentQuery;\n    private String tempQueryText;\n    private Handler tempHandler;\n    private boolean tempLoad;\n    \n    \n    public static synchronized RQueries instance() {\n        if (INSTANCE == null) INSTANCE = new RQueries();\n        return INSTANCE;\n    }\n    \n    \n    public void populateLoadQuery(JPopupMenu popup, Query currentQuery, final Handler handler) {\n        if (customQueries == null /*|| predefinedCategories == null*/) {\n            JMenuItem progressItem = new JMenuItem(Bundle.RQueries_LoadingProgress(), ICON_PROGRESS);\n            progressItem.setEnabled(false);\n            popup.add(progressItem);\n            \n            tempPopup = popup;\n            tempCurrentQuery = currentQuery;\n            tempHandler = handler;\n            \n            tempLoad = true;\n            \n            return;\n        }\n        \n        tempPopup = null;\n        tempCurrentQuery = null;\n        tempQueryText = null;\n        tempHandler = null;\n\n//        popup.add(new PopupCaption(Bundle.RQueries_PopupCaptionLoad()));\n        \n//        popup.add(new PopupSpacer(3));\n        popup.add(new PopupSeparator(Bundle.RQueries_PopupLoadCustomScript()));\n        \n        if (customQueries.isEmpty()) {\n            JMenuItem noItems = new JMenuItem(Bundle.RQueries_PopupNoSaved(), ICON_EMPTY);\n            noItems.setEnabled(false);\n            popup.add(noItems);\n        } else {\n            for (final Query query : customQueries.list())\n                popup.add(new QueryMenuItem(query, currentQuery, ICON_LOAD, null, handler));\n        }\n        \n        popup.add(new PopupSpacer(5));\n        popup.add(new PopupSeparator(Bundle.RQueries_PopupLoadExternalScript()));\n        popup.add(new JMenuItem(Bundle.RQueries_PopupLoadFromFile(), ICON_EMPTY) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { loadFromFile(handler); }\n                });\n            }\n        });\n        if (externalQueries != null && !externalQueries.isEmpty()) {\n            popup.add(new PopupSpacer(5));\n            for (final Query query : externalQueries)\n                popup.add(new QueryMenuItem(query, currentQuery, ICON_LOAD, null, handler));\n        }\n        \n        // --- Sample Scripts - just for test/debug purposes -------------------\n        popup.add(new PopupSpacer(5));\n        popup.add(new PopupSeparator(Bundle.RQueries_PopupLoadSampleScript()));\n        \n        String script1 = \"grid.rect(width = 0.5, height = 0.45, gp=gpar(col=\\\"blue\\\",lwd=3))\\n\" + // NOI18N\n                         \"grid.circle(x = 0.5, y = 0.5, r = 0.45, gp=gpar(col=\\\"red\\\",lwd=10))\\n\" + // NOI18N\n                         \"grid.text(\\\"Box and Circle\\\")\"; // NOI18N\n        Query sample1 = new Query(script1, \"Simple Graphics\", \"Sample script drawing blue rectangle and red circle\"); // NOI18N\n        popup.add(new QueryMenuItem(sample1, currentQuery, ICON_LOAD, null, handler));\n        \n        String script2 = \"s<-HeapClasses[order(HeapClasses$Instances,decreasing=TRUE),];\\n\" + // NOI18N\n                         \"x<-s[1:15,];\\n\" + // NOI18N\n                         \"print(x);\"; // NOI18N\n        Query sample2 = new Query(script2, \"Classes by Instances Count\", \"Sorts classes by number of instances and displays first 15 rows\"); // NOI18N\n        popup.add(new QueryMenuItem(sample2, currentQuery, ICON_LOAD, null, handler));\n        // ---------------------------------------------------------------------\n        \n//        if (!predefinedCategories.isEmpty()) {\n//            popup.add(new PopupSpacer(5));\n//            popup.add(new PopupSeparator(Bundle.RQueries_PopupLoadPredefinedScript()));\n//            \n//            for (RQueryCategory category : predefinedCategories) {\n//                final JMenu categoryMenu = new JMenu(category.getName()) {\n//                    protected void fireStateChanged() {\n//                        boolean active = isSelected() || isArmed();\n//                        StatusDisplayer.getDefault().setStatusText(active ? category.getDescription() : null);\n//                        super.fireStateChanged();\n//                    }\n//                };\n////                categoryMenu.setToolTipText(category.getDescription());\n//                popup.add(categoryMenu);\n//                \n//                List<? extends RQueryDefinition> queries = category.listQueries();\n//                for (final RQueryDefinition queryDef : queries)\n//                    categoryMenu.add(new QueryMenuItem(new Query(queryDef), currentQuery, ICON_LOAD, categoryMenu, handler));\n//            }\n//        }\n    }\n    \n    public void populateSaveQuery(JPopupMenu popup, final Query currentQuery, final String queryText, final Handler handler) {\n        if (customQueries == null) {\n            JMenuItem progressItem = new JMenuItem(Bundle.RQueries_PopupLoadingScripts(), ICON_PROGRESS);\n            progressItem.setEnabled(false);\n            popup.add(progressItem);\n            \n            tempPopup = popup;\n            tempCurrentQuery = currentQuery;\n            tempQueryText = queryText;\n            tempHandler = handler;\n            \n            tempLoad = false;\n            \n            return;\n        }\n        \n        tempPopup = null;\n        tempCurrentQuery = null;\n        tempQueryText = null;\n        tempHandler = null;\n        \n//        popup.add(new PopupCaption(Bundle.RQueries_PopupCaptionSave()));\n        \n//        popup.add(new PopupSpacer(3));\n        popup.add(new PopupSeparator(Bundle.RQueries_PopupSaveCustomScript()));\n        \n        popup.add(new JMenuItem(Bundle.RQueries_PopupSaveNew(), ICON_EMPTY) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                \n                Query query = RQueryCustomizer.saveCustomizer(currentQuery, queryText);\n                if (query == null) return;\n                \n                String name = query.getName();\n                int nameExt = 0;\n                while (containsQuery(customQueries.list(), query))\n                    query.setName(name + \" \" + ++nameExt); // NOI18N\n                \n                customQueries.add(query);\n                \n                if (handler != null) handler.querySelected(query);\n            }\n        });\n        \n        if (!customQueries.isEmpty()) {\n            popup.add(new PopupSpacer(5));\n            for (final Query query : customQueries.list())\n                popup.add(new QueryMenuItem(query, currentQuery, ICON_SAVE, null, handler) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        query.setScript(queryText);\n                        customQueries.save(query);\n                        super.fireActionPerformed(e);\n                    }\n                });\n        }\n        \n        popup.add(new PopupSpacer(5));\n        popup.add(new PopupSeparator(Bundle.RQueries_PopupSaveExternalScript()));\n        popup.add(new JMenuItem(Bundle.RQueries_PopupSaveFile(), ICON_EMPTY) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { saveToFile(currentQuery, queryText, handler); }\n                });\n            }\n        });\n        if (externalQueries != null && !externalQueries.isEmpty()) {\n            popup.add(new PopupSpacer(5));\n            for (final Query query : externalQueries)\n                popup.add(new QueryMenuItem(query, currentQuery, ICON_SAVE, null, handler) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        query.setScript(queryText);\n                        saveToQuery(query, null); // handler will be notified later\n                        super.fireActionPerformed(e);\n                    }\n                });\n        }  \n    }\n    \n    \n    public void populateEditQuery(JPopupMenu popup, final Query currentQuery) {\n        if (customQueries == null) {\n            JMenuItem progressItem = new JMenuItem(Bundle.RQueries_PopupLoadingScripts(), ICON_PROGRESS);\n            progressItem.setEnabled(false);\n            popup.add(progressItem);\n            \n            return;\n        }\n        \n        if (customQueries.isEmpty()) {\n            JMenuItem emptyItem = new JMenuItem(Bundle.RQueries_PopupNoCustom());\n            emptyItem.setEnabled(false);\n            popup.add(emptyItem);\n            \n            return;\n        }\n        \n        for (final Query query : customQueries.list()) {\n            JMenu queryM = new JMenu(QueryMenuItem.getName(query, currentQuery, null)) {\n                protected void fireStateChanged() {\n                    boolean active = isSelected() || isArmed();\n                    StatusDisplayer.getDefault().setStatusText(active ? query.getDescription() : null);\n                    super.fireStateChanged();\n                }\n            };\n            popup.add(queryM);\n            \n            queryM.add(new JMenuItem(Bundle.RQueries_PopupEditCustom()) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            List<Query> l = customQueries.list();\n                            for (Query q : l) {\n                                if (sameQuery(query, q)) {\n                                    Query qq = RQueryCustomizer.editCustomizer(query, \"\"); // NOI18N\n                                    if (qq == null) return;\n                                    \n                                    q.setName(qq.getName());\n                                    q.setDescription(qq.getDescription());\n                                    \n                                    customQueries.set(l);\n                                    break;\n                                }\n                            }\n                            \n                        }\n                    });\n                }\n            });\n            \n            \n            queryM.add(new JMenuItem(Bundle.RQueries_PopupDeleteCustom()) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            List<Query> l = customQueries.list();\n                            Iterator<Query> i = l.iterator();\n                            while (i.hasNext()) {\n                                if (sameQuery(query, i.next())) {\n                                    i.remove();\n                                    \n                                    customQueries.set(l);\n                                    break;\n                                }\n                            }\n                        }\n                    });\n                }\n            });\n        }\n        \n        popup.addSeparator();\n        \n        popup.add(new JMenuItem(Bundle.RQueries_PopupDeleteAllCustom()) {\n            protected void fireActionPerformed(ActionEvent e) {\n                customQueries.set(Collections.emptyList());\n            }\n        });\n    }\n    \n    \n    private void loadAllQueries() {\n        VisualVM.getInstance().runTask(new Runnable() { // NOI18N\n            public void run() {\n                customQueries = CustomRQueries.instance();\n//                predefinedCategories = RQueryRepository.getInstance().listCategories();\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        if (tempPopup != null && tempPopup.isShowing()) {\n                            JPopupMenu popup = tempPopup;\n                            popup.removeAll();\n                            if (tempLoad) populateLoadQuery(popup, tempCurrentQuery, tempHandler);\n                            else populateSaveQuery(popup, tempCurrentQuery, tempQueryText, tempHandler);\n                            popup.pack();\n                        }\n                    }\n                });\n            }\n        });\n    }\n    \n    \n    private File lastDirectory;\n    \n    private void loadFromFile(final Handler handler) {\n        JFileChooser chooser = new JFileChooser();\n\n        if (lastDirectory != null) chooser.setCurrentDirectory(lastDirectory);\n\n        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);\n        chooser.setMultiSelectionEnabled(false);\n        chooser.setAcceptAllFileFilterUsed(false);\n        chooser.setDialogTitle(Bundle.RQueries_LoadExternalCaption());\n        chooser.setFileFilter(new FileFilter() {\n            public boolean accept(File f) {\n                if (f.isDirectory()) return true;\n                String fname = f.getName().toLowerCase(Locale.ENGLISH);\n                if (fname.endsWith(\".r\") || fname.endsWith(\".txt\")) return true; // NOI18N\n                return false;\n            }\n            public String getDescription() {\n                return Bundle.RQueries_RFileFilter(\"*.r, *.txt\"); // NOI18N\n            }\n        });\n\n        if (chooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) {\n            final File file = chooser.getSelectedFile();\n            lastDirectory = file.getParentFile();\n            \n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    try {\n                        if (!file.isFile() || !file.canRead()) {\n                            ProfilerDialogs.displayError(Bundle.RQueries_InvalidScript());\n                            return;\n                        }\n                        \n                        String script = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);\n                        String name = file.getName();\n                        String description = file.getAbsolutePath();\n                        final Query query = new Query(script, name, description);\n                        \n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                handler.querySelected(query);\n                        \n                                if (externalQueries == null) externalQueries = new ArrayList<>(EXTERNAL_QUERIES_CACHE);\n                                if (containsQuery(externalQueries, query)) return;\n\n                                if (externalQueries.size() == EXTERNAL_QUERIES_CACHE)\n                                    externalQueries.remove(externalQueries.size() - 1);\n\n                                externalQueries.add(0, query);\n                            }\n                        });\n                    } catch (IOException ex) {\n                        ProfilerDialogs.displayError(Bundle.RQueries_LoadFailed());\n                        Exceptions.printStackTrace(ex);\n                    }\n                }\n            });\n        }\n    }\n    \n    private void saveToFile(Query query, String queryText, Handler handler) {\n        JFileChooser chooser = new JFileChooser();\n        \n        if (query == null) {\n            String name = \"query.r\"; // NOI18N\n            String descr = lastDirectory == null ? null : new File(lastDirectory, name).getPath();\n            query = new Query(queryText, name, descr);\n        }\n        \n        String descr = query.getDescription();\n        File defaultFile = descr == null ? null : new File(descr);\n        if (defaultFile != null && defaultFile.isFile()) {\n            chooser.setSelectedFile(defaultFile);\n        } else {\n            if (lastDirectory == null) defaultFile = new File(query.getName());\n            else defaultFile = new File(lastDirectory, query.getName());\n            if (lastDirectory != null) chooser.setCurrentDirectory(lastDirectory);\n            chooser.setSelectedFile(defaultFile);\n        }\n\n        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);\n        chooser.setMultiSelectionEnabled(false);\n        chooser.setAcceptAllFileFilterUsed(false);\n        chooser.setDialogTitle(Bundle.RQueries_SaveExternalCaption());\n        chooser.setFileFilter(new FileFilter() {\n            public boolean accept(File f) {\n                if (f.isDirectory()) return true;\n                String fname = f.getName().toLowerCase(Locale.ENGLISH);\n                if (fname.endsWith(\".r\") || fname.endsWith(\".txt\")) return true; // NOI18N\n                return false;\n            }\n            public String getDescription() {\n                return Bundle.RQueries_RFileFilter(\"*.r, *.txt\"); // NOI18N\n            }\n        });\n\n        if (chooser.showSaveDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) {\n            File file = chooser.getSelectedFile();\n            lastDirectory = file.getParentFile();\n            \n            String fname = file.getName().toLowerCase(Locale.ENGLISH);\n            if (!fname.endsWith(\".r\") && !fname.endsWith(\".txt\")) // NOI18N\n                file = new File(file.getParentFile(), file.getName() + \".r\"); // NOI18N\n            \n            String script = query.getScript();\n            String name = file.getName();\n            String description = file.getAbsolutePath();\n            \n            saveToQuery(new Query(script, name, description), handler);\n        }\n    }\n    \n    private void saveToQuery(final Query query, final Handler handler) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                try {\n                    File file = new File(query.getDescription());\n                    \n                    if (file.isFile() && !file.canWrite()) {\n                        ProfilerDialogs.displayError(Bundle.RQueries_InvalidScript());\n                        return;\n                    }\n\n                    Files.write(file.toPath(), query.getScript().getBytes());\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            if (handler != null) handler.querySelected(query);\n\n                            if (externalQueries == null) externalQueries = new ArrayList<>(EXTERNAL_QUERIES_CACHE);\n                            if (containsQuery(externalQueries, query)) return;\n\n                            if (externalQueries.size() == EXTERNAL_QUERIES_CACHE)\n                                externalQueries.remove(externalQueries.size() - 1);\n\n                            externalQueries.add(0, query);\n                        }\n                    });\n                } catch (IOException ex) {\n                    ProfilerDialogs.displayError(Bundle.RQueries_SaveFailed());\n                    Exceptions.printStackTrace(ex);\n                }\n            }\n        });\n    }\n    \n    \n    private static boolean sameQuery(Query query1, Query query2) {\n        if (query1 == null || query2 == null) return false;\n        return query1.getName().equals(query2.getName());\n    }\n    \n    private static boolean containsQuery(List<Query> queries, Query query) {\n        for (Query q : queries)\n            if (sameQuery(q, query)) return true;\n        return false;\n    }\n    \n    \n    private RQueries() {\n        loadAllQueries();\n    }\n    \n    \n    static class Handler {\n        \n        protected void querySelected(Query query) {}\n        \n    }\n    \n    \n//    private static class PopupCaption extends JPanel {\n//        \n//        PopupCaption(String caption) {\n//            super(new BorderLayout());\n//            \n//            setOpaque(true);\n//            setBackground(UIUtils.getUnfocusedSelectionBackground());\n////            setBackground(UIUtils.getProfilerResultsBackground());\n////            setBackground(UIManager.getColor(\"InternalFrame.borderHighlight\"));\n////            setBackground(UIManager.getColor(\"ToolTip.background\"));\n//            \n//            JLabel captionL = new JLabel(caption);\n//            captionL.setForeground(UIUtils.getUnfocusedSelectionForeground());\n////            captionL.setForeground(UIManager.getColor(\"InternalFrame.activeTitleForeground\"));\n////            captionL.setBorder(BorderFactory.createEmptyBorder(3, 3, 4, 3));\n//            captionL.setBorder(BorderFactory.createEmptyBorder(7, 5, 7, 40));\n//            add(captionL, BorderLayout.CENTER);\n//            \n////            add(UIUtils.createHorizontalSeparator(), BorderLayout.SOUTH);\n////            setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIUtils.getDisabledLineColor().brighter()));\n//        }\n//        \n//    }\n    \n    private static class PopupSpacer extends JPanel {\n        \n        private final int size;\n        \n        PopupSpacer(int size) {\n            this.size = size;\n            setOpaque(false);\n        }\n        \n        public Dimension getMinimumSize() {\n            return new Dimension(0, size);\n        }\n        \n        public Dimension getPreferredSize() {\n            return getMinimumSize();\n        }\n        \n    }\n    \n    private static class PopupSeparator extends JPanel {\n    \n        PopupSeparator(String text) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            JLabel l = new JLabel(text);\n            l.setBorder(BorderFactory.createEmptyBorder(5, 5, 3, 3));\n            if (UIUtils.isWindowsLookAndFeel()) l.setOpaque(true);\n            l.setFont(l.getFont().deriveFont(Font.BOLD, l.getFont().getSize2D() - 1));\n            if (UIUtils.isWindowsLookAndFeel()) l.setForeground(UIUtils.getDisabledLineColor());\n\n            add(l, BorderLayout.WEST);\n\n            if (UIUtils.isGTKLookAndFeel()) {\n                add(UIUtils.createHorizontalSeparator(), BorderLayout.CENTER);\n            } else {\n                JComponent sep = new JPopupMenu.Separator();\n                add(sep, BorderLayout.CENTER);\n\n                if (UIUtils.isOracleLookAndFeel()) {\n                    setOpaque(true);\n                    setBackground(sep.getBackground());\n                    l.setForeground(sep.getForeground());\n                }\n            }\n        }\n\n        public void doLayout() {\n            super.doLayout();\n            Component c = getComponent(1);\n\n            int h = c.getPreferredSize().height;\n            Rectangle b = c.getBounds();\n\n            b.y = (b.height - h) / 2 + 1;\n            b.height = h;\n            c.setBounds(b);\n        }\n\n        public Dimension getPreferredSize() {\n            Dimension d = getComponent(0).getPreferredSize();\n            d.width += 75;\n            return d;\n        }\n\n    }\n    \n    private static class QueryMenuItem extends JMenuItem {\n        \n        private final Query query;\n        private final Icon icon;\n        private final Handler handler;\n        \n        QueryMenuItem(Query query, Query current, Icon icon, JMenu owner, Handler handler) {\n            super(getName(query, current, owner), ICON_EMPTY);\n            \n            this.query = query;\n            this.icon = icon;\n            this.handler = handler;\n        }\n        \n        protected void fireActionPerformed(ActionEvent e) {\n            super.fireActionPerformed(e);\n            if (handler != null) handler.querySelected(query);\n        }\n        \n        protected void fireStateChanged() {\n            boolean active = isSelected() || isArmed();\n            setIcon(active ? icon : ICON_EMPTY);\n            StatusDisplayer.getDefault().setStatusText(active ? query.getDescription() : null);\n            super.fireStateChanged();\n        }\n        \n        private static String getName(Query query, Query current, JMenu owner) {\n            String name = query.getName();\n            if (sameQuery(query, current)) {\n                name = \"<html><b>\" + name + \"</b>&nbsp;<span style='color: gray;'>\" + Bundle.RQueries_CurrentScriptFlag() + \"</span></html>\"; // NOI18N\n                if (owner != null) owner.setText(\"<html><b>\" + owner.getText() + \"</b></html>\"); // NOI18N\n            }\n            return name;\n        }\n        \n    }\n    \n    \n    // copied from Query\n    public static final class Query {\n\n        private String script;\n        private String name;\n        private String description;\n        \n\n        public Query(String script, String name, String description) {\n            setScript(script);\n            setName(name);\n            setDescription(description);\n        }\n\n\n        public void setScript(String script) {\n            if (script == null)\n                throw new IllegalArgumentException(\"Script cannot be null\"); // NOI18N\n            this.script = script;\n        }\n\n        public String getScript() {\n            return script;\n        }\n\n        public void setName(String name) {\n            this.name = normalizeString(name);\n            if (this.name == null)\n                throw new IllegalArgumentException(\"Name cannot be null\"); // NOI18N\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setDescription(String description) {\n            this.description = normalizeString(description);\n        }\n\n        public String getDescription() {\n            return description;\n        }\n\n        public String toString() {\n            return name;\n        }\n\n        private static String normalizeString(String string) {\n            String normalizedString = null;\n            if (string != null) {\n                normalizedString = string.trim();\n                if (normalizedString.isEmpty()) normalizedString = null;\n            }\n            return normalizedString;\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/RQueryCustomizer.java",
    "content": "/*\n * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.console.r;\n\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.io.File;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextArea;\nimport javax.swing.JTextField;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"RQueryCustomizer_OkButtonText=OK\",\n    \"RQueryCustomizer_CloseButtonText=Close\",\n    \"RQueryCustomizer_SaveQueryCaption=Save Custom R Script\",\n    \"RQueryCustomizer_EditQueryCaption=Edit Custom R Script Properties\",\n    \"RQueryCustomizer_NameLabelText=&Name:\",\n    \"RQueryCustomizer_DefaultQueryName=Custom Script\",\n    \"RQueryCustomizer_DescriptionLabelText=&Description (optional):\"\n})\npublic class RQueryCustomizer {\n//    private static HelpCtx HELP_CTX_SAVE_QUERY = new HelpCtx(\"OQLQueryCustomizer.SaveQuery.HelpCtx\");  //NOI18N\n//    private static HelpCtx HELP_CTX_QUERY_PROPS = new HelpCtx(\"OQLQueryCustomizer.QueryProps.HelpCtx\");//NOI18N\n\n\n    public static RQueries.Query saveCustomizer(RQueries.Query query, String script) {\n        return customizer(query, script, Bundle.RQueryCustomizer_SaveQueryCaption());\n    }\n    \n    public static RQueries.Query editCustomizer(RQueries.Query query, String script) {\n        return customizer(query, script, Bundle.RQueryCustomizer_EditQueryCaption());\n    }\n    \n    public static RQueries.Query customizer(RQueries.Query query, String script, String caption) {\n        JButton okButton = new JButton();\n        Mnemonics.setLocalizedText(okButton, Bundle.RQueryCustomizer_OkButtonText());\n        \n        String name = query == null ? Bundle.RQueryCustomizer_DefaultQueryName() : query.getName();\n        String description = query == null ? null : query.getDescription();\n        if (description != null && new File(description).isFile()) description = null;\n\n        CustomizerPanel customizer = new CustomizerPanel(name, description, okButton);\n        final DialogDescriptor dd = new DialogDescriptor(customizer, caption, true,\n                                            new Object[] { okButton, DialogDescriptor.CANCEL_OPTION },\n                                            okButton, 0, null, null);\n        final Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n        d.pack();\n        d.setVisible(true);\n\n        if (dd.getValue() == okButton) {\n            return new RQueries.Query(script, customizer.name(), customizer.description());\n        } else {\n            return null;\n        }\n    }\n    \n\n    private static class CustomizerPanel extends JPanel {\n\n        private final JComponent submitComponent;\n\n\n        CustomizerPanel(String name, String description, JComponent submitComponent) {\n            this.submitComponent = submitComponent;\n\n            initComponents(name, description, false);\n            updateComponents();\n        }\n\n        public String name() {\n            return nameField.getText().trim();\n        }\n\n        public String description() {\n            String description = descriptionArea.getText().trim();\n            return description.isEmpty() ? null : description;\n        }\n\n\n        private void updateComponents() {\n            submitComponent.setEnabled(!nameField.getText().trim().isEmpty());\n        }\n\n\n        private void initComponents(String name, String description, boolean readOnly) {\n            setLayout(new GridBagLayout());\n            GridBagConstraints c;\n\n            nameLabel = new JLabel();\n            Mnemonics.setLocalizedText(nameLabel, Bundle.RQueryCustomizer_NameLabelText());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 1;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(16, 16, 8, 8);\n            add(nameLabel, c);\n\n            nameField = new JTextField();\n            nameLabel.setLabelFor(nameField);\n            nameField.setText(name);\n            nameField.getDocument().addDocumentListener(new DocumentListener() {\n                public void insertUpdate(DocumentEvent e) {  updateComponents(); }\n                public void removeUpdate(DocumentEvent e) {  updateComponents(); }\n                public void changedUpdate(DocumentEvent e) {  updateComponents(); }\n            });\n            nameField.setEditable(!readOnly);\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = 1;\n            c.weightx = 1;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(16, 0, 8, 16);\n            add(nameField, c);\n\n            descriptionLabel = new JLabel();\n            Mnemonics.setLocalizedText(descriptionLabel, Bundle.RQueryCustomizer_DescriptionLabelText());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 2;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(8, 16, 8, 8);\n            add(descriptionLabel, c);\n\n            descriptionArea = new JTextArea(description);\n            descriptionLabel.setLabelFor(descriptionArea);\n            descriptionArea.setLineWrap(true);\n            descriptionArea.setWrapStyleWord(true);\n            descriptionArea.setFont(descriptionLabel.getFont());\n            descriptionArea.setRows(5);\n            final int prefWidth = new JLabel(\"A lengthy string serving as OQL script description sizer\").getPreferredSize().width; // NOI18N\n            JScrollPane descriptionAreaScroll = new JScrollPane(descriptionArea,\n                                        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                                        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) {\n                public Dimension getPreferredSize() {\n                    return new Dimension(prefWidth, super.getPreferredSize().height);\n                }\n            };\n            descriptionArea.setEditable(!readOnly);\n            if (readOnly) descriptionArea.setBackground(nameField.getBackground());\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = 3;\n            c.weighty = 1;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.fill = GridBagConstraints.BOTH;\n            c.insets = new Insets(0, 0, 16, 16);\n            add(descriptionAreaScroll, c);\n\n            addHierarchyListener(new HierarchyListener() {\n                public void hierarchyChanged(HierarchyEvent e) {\n                    if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                        if (isShowing()) {\n                            removeHierarchyListener(this);\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    nameField.requestFocus();\n                                    nameField.selectAll();\n                                }\n                            });\n                        }\n                    }\n                }\n            });\n\n        }\n\n\n        private JLabel nameLabel;\n        private JTextField nameField;\n        private JLabel descriptionLabel;\n        private JTextArea descriptionArea;\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/engine/ClassIDArray.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.console.r.engine;\n\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ClassIDArray extends ClassesArray {\n\n    ClassIDArray(List<JavaClass> cl) {\n        super(cl);\n    }\n\n    @Override\n    public Object get(long index) {\n        return Long.toHexString(getJClass(index).getJavaClassId());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/engine/ClassesArray.java",
    "content": "/*\n * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.console.r.engine;\n\nimport java.util.List;\nimport org.graalvm.polyglot.Value;\nimport org.graalvm.polyglot.proxy.ProxyArray;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\n\n/**\n *\n * @author Tomas Hurka\n */\nabstract class ClassesArray implements ProxyArray {\n\n    List<JavaClass> classes;\n    \n    ClassesArray(List<JavaClass> cl) {\n        classes = cl;\n    }\n\n    JavaClass getJClass(long index) {\n        return classes.get((int) index);\n    }\n    \n    @Override\n    abstract public Object get(long index);\n\n    @Override\n    public void set(long index, Value value) {\n        throw new UnsupportedOperationException(\"Not supported yet.\"); //To change body of generated methods, choose Tools | Templates.\n    }\n\n    @Override\n    public long getSize() {\n        return classes.size();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/engine/InstancesArray.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.console.r.engine;\n\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\n\n/**\n *\n * @author thurka\n */\nclass InstancesArray extends ClassesArray {\n    \n    InstancesArray(List<JavaClass> cl) {\n        super(cl);\n    }\n\n    @Override\n    public Object get(long index) {\n        JavaClass jcls = getJClass(index);\n        return Integer.valueOf(jcls.getInstancesCount());\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/engine/InstancesSizeArray.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.console.r.engine;\n\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass InstancesSizeArray extends ClassesArray {\n\n    InstancesSizeArray(List<JavaClass> cl) {\n        super(cl);\n    }\n\n    @Override\n    public Object get(long index) {\n        return Long.valueOf(getJClass(index).getAllInstancesSize());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/engine/NamesArray.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.console.r.engine;\n\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass NamesArray extends ClassesArray {\n    \n    NamesArray(List<JavaClass> cl) {\n        super(cl);\n    }\n\n    @Override\n    public Object get(long index) {\n        return getJClass(index).getName();\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.console/src/org/graalvm/visualvm/heapviewer/console/r/engine/REngine.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.console.r.engine;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.util.List;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.polyglot.Context;\nimport org.graalvm.polyglot.Value;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class REngine {\n    final private static Logger LOGGER = Logger.getLogger(REngine.class.getName());\n    private static Boolean supported;\n    \n    private AtomicBoolean cancelled;\n    private final Heap heap;\n    private Context rContext;\n    private Value javaToDf;\n    private ROut outStream;\n\n    public static synchronized boolean isSupported() {\n        if (supported == null) {\n            try {\n                Context c = Context.newBuilder(\"R\").allowAllAccess(true).build();\n                c.eval(\"R\", \"invisible(42)\");\n                supported = Boolean.TRUE;\n            } catch (Exception e) {\n                LOGGER.log(Level.INFO, \"REngine isSupported\", e); // NOI18N\n                supported = Boolean.FALSE;\n            } catch (NoClassDefFoundError e) {\n                LOGGER.log(Level.INFO, \"REngine isSupported\", e); // NOI18N\n                supported = Boolean.FALSE;\n            }\n        }\n        return supported.booleanValue();\n    }\n\n    public REngine(Heap h) {\n        heap = h;\n        initRContext();\n    }\n\n    private void initRContext() {\n        cancelled = new AtomicBoolean(false);\n        outStream = new ROut();\n        rContext = Context.newBuilder(\"R\").allowAllAccess(true).out(outStream).build();\n        String javaToDfSrc =\n                \"function(c1, c2, c3, c4) { \" +\n                \"   data.frame(ClassName=as.vector(c1, 'character'),\" +\n                \"              ClassId=as.vector(c2, 'character'),\" +\n                \"              Instances=as.vector(c3, 'integer'),\" +\n                \"              InstancesSize=as.vector(c4, 'integer'),\" +\n                \"stringsAsFactors = F)\" +\n                \"}\";\n        javaToDf = rContext.eval(\"R\", javaToDfSrc);\n        List<JavaClass> classes = heap.getAllClasses();\n        exportSymbol(rContext, \"HeapClasses\", javaToDf.execute(\n                new NamesArray(classes),\n                new ClassIDArray(classes),\n                new InstancesArray(classes),\n                new InstancesSizeArray(classes)));\n        rContext.eval(\"R\", \"HeapClasses <- import('HeapClasses');\");\n        exportSymbol(rContext, \"heap\", heap);\n        rContext.eval(\"R\", \"heap <- import('heap');\");\n        rContext.eval(\"R\", \"options(width=256)\");\n    }\n\n    private void exportSymbol(Context ctx, String name, Object value) {\n        ctx.getPolyglotBindings().putMember(name, value);\n    }\n\n    public synchronized void cancelQuery() {\n        cancelled.set(true);\n    }\n\n    public synchronized boolean isCancelled() {\n        return cancelled.get();\n    }\n\n    public void executeQuery(String rQuery, ObjectVisitor objectVisitor) {\n        if (rContext == null) {\n            initRContext();\n        }\n        cancelled.set(false);\n        outStream.setVisitor(objectVisitor);\n        rContext.eval(\"R\", rQuery);\n    }\n    \n    public Context getContext() {\n        return rContext;\n    }\n\n    public static interface ObjectVisitor {\n\n        // return true to terminate the result set callback earlier\n        public boolean visit(Object o);\n\n        public static final ObjectVisitor DEFAULT = new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                if (o != null && LOGGER.isLoggable(Level.FINEST)) {\n                    LOGGER.finest(o.toString());\n                }\n\n                return true; // prevent calling \"visit\" for the rest of the result set\n            }\n        };\n    }\n    \n    private static class ROut extends OutputStream {\n\n        private ObjectVisitor visitor;\n        private StringBuilder output;\n\n        private ROut() {\n            output = new StringBuilder();\n        }\n        \n        \n        @Override\n        public void write(int b) throws IOException {\n            if (b == '\\n') {\n                visitor.visit(output.toString());\n                output = new StringBuilder();\n            } else {\n                output.append((char) b);\n            }\n        }\n\n        private void setVisitor(ObjectVisitor objectVisitor) {\n            visitor = objectVisitor;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.heapviewer.truffle\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.heapviewer.truffle.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.heapviewer.truffle/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/heapviewer/truffle/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.1\n\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.heapviewer.truffle-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=40f14d42\nbuild.xml.script.CRC32=95901e97\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=40f14d42\nnbproject/build-impl.xml.script.CRC32=4df4472b\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/nbproject/project.properties",
    "content": "javac.source=1.8\njavac.compilerargs=-Xlint -Xlint:-serial\nmodule.javadoc.packages=org.graalvm.visualvm.heapviewer.truffle.*\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.heapviewer.truffle</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.heapviewer</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.7</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid.heap</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.heapwalker</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.34</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/Bundle.properties",
    "content": "#\n# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Name=VisualVM-HeapViewer-Truffle\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleFrame.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveType;\nimport org.graalvm.visualvm.lib.jfluid.heap.Type;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class TruffleFrame {\n\n    private static final String TRUFFLE_FRAME_FQN = \"com.oracle.truffle.api.impl.DefaultVirtualFrame\";  // NOI18N\n    private static final String COMPILER_FRAME_NOBOX_FQN = \"org.graalvm.compiler.truffle.FrameWithoutBoxing\"; // NOI18N\n    private static final String ENT_COMPILER_FRAME_NOBOX_FQN = \"com.oracle.graal.truffle.FrameWithoutBoxing\"; // NOI18N\n    private static final String COMPILER_FRAME_NOBOX1_FQN = \"org.graalvm.compiler.truffle.runtime.FrameWithoutBoxing\"; // NOI18N\n    private static final String COMPILER_FRAME_NOBOX2_FQN = \"com.oracle.truffle.api.impl.FrameWithoutBoxing\"; // NOI18N\n    private static final String COMPILER_FRAME_BOX_FQN = \"org.graalvm.compiler.truffle.FrameWithBoxing\"; // NOI18N\n    private static final String ENT_COMPILER_FRAME_BOX_FQN = \"com.oracle.graal.truffle.FrameWithBoxing\"; // NOI18N\n    private static final String COMPILER_FRAME_BOX1_FQN = \"org.graalvm.compiler.truffle.runtime.FrameWithBoxing\"; // NOI18N\n    private static final String ARG_PREFIX = \"arg\";         // NOI18N\n    private static final String LOCAL_UNDEFINED = \"undefined\"; // NOI18N\n\n    private static final byte OBJECT_TAG = 0;\n    private static final byte LONG_TAG = 1;\n    private static final byte INT_TAG = 2;\n    private static final byte DOUBLE_TAG = 3;\n    private static final byte FLOAT_TAG = 4;\n    private static final byte BOOLEAN_TAG = 5;\n    private static final byte BYTE_TAG = 6;\n    private static final byte ILLEGAL_TAG = 7;\n    private static final byte STATIC_TAG = 8;\n\n    private List<FieldValue> values;\n    private List<FieldValue> localValues;\n    private boolean isTruffleFrame;\n\n    public TruffleFrame(Instance truffleFrame) {\n        values = Collections.emptyList();\n        localValues = Collections.emptyList();\n        if (isTruffleFrameSubClass(truffleFrame)) {\n            List<Instance> locals = getObjectArray(truffleFrame, \"indexedLocals\");         // NOI18N\n            List<String> primitiveLocals = getPrimitiveArray(truffleFrame, \"indexedPrimitiveLocals\");  // NOI18N\n            List<Instance> arguments = getObjectArray(truffleFrame, \"arguments\");   // NOI18N\n            Instance descriptor = getValueOfFields(truffleFrame, \"descriptor\");   // NOI18N\n            List<String> tags = getPrimitiveArray(descriptor, \"indexedSlotTags\");   // NOI18N\n            List<Instance> names = getObjectArray(descriptor, \"indexedSlotNames\");  // NOI18N\n            Instance defaultValue = getValueOfFields(truffleFrame, \"descriptor\", \"defaultValue\"); // NOI18N\n\n            if (locals != null && arguments != null && tags != null) {\n                List<FieldValue> vals = new ArrayList<>(arguments.size() + locals.size());\n                List<FieldValue> locs = new ArrayList<>(locals.size());\n                createArguments(truffleFrame, arguments, vals);\n                createLocals(truffleFrame, locals, primitiveLocals, tags, names, defaultValue, locs);\n                vals.addAll(locs);\n                values = Collections.unmodifiableList(vals);\n                localValues = Collections.unmodifiableList(locs);\n                isTruffleFrame = true;\n            } else {\n                depricatedFrame(truffleFrame);\n            }\n        }\n    }\n\n    private void depricatedFrame(Instance truffleFrame) {\n        List<Instance> locals = getObjectArray(truffleFrame, \"locals\");         // NOI18N\n        List<String> primitiveLocals = getPrimitiveArray(truffleFrame, \"primitiveLocals\");  // NOI18N\n        List<Instance> arguments = getObjectArray(truffleFrame, \"arguments\");   // NOI18N\n        Instance slotArr = getValueOfFields(truffleFrame, \"descriptor\", \"slots\");   // NOI18N\n        List<Instance> slots = getObjectArray(slotArr, \"elementData\");  // NOI18N\n        Instance defaultValue = getValueOfFields(truffleFrame, \"descriptor\", \"defaultValue\"); // NOI18N\n\n        if (locals != null && arguments != null && slots != null) {\n            Instance[] frameSlots = createFrameSlots(slots, locals.size());\n            List<FieldValue> vals = new ArrayList<>(arguments.size() + locals.size());\n            List<FieldValue> locs = new ArrayList<>(locals.size());\n            createArguments(truffleFrame, arguments, vals);\n            createLocals(truffleFrame, locals, primitiveLocals, frameSlots, defaultValue, locs);\n            vals.addAll(locs);\n            values = Collections.unmodifiableList(vals);\n            localValues = Collections.unmodifiableList(locs);\n            isTruffleFrame = true;\n        }\n    }\n\n    public List<FieldValue> getFieldValues() {\n        return values;\n    }\n\n    public List<FieldValue> getLocalFieldValues() {\n        return localValues;\n    }\n\n\n    public boolean isTruffleFrame() {\n        return isTruffleFrame;\n    }\n\n    private static boolean isTruffleFrameSubClass(Instance truffleFrame) {\n        return isSubClassOf(truffleFrame, TRUFFLE_FRAME_FQN)\n                || isSubClassOf(truffleFrame, COMPILER_FRAME_NOBOX_FQN)\n                || isSubClassOf(truffleFrame, COMPILER_FRAME_NOBOX1_FQN)\n                || isSubClassOf(truffleFrame, COMPILER_FRAME_NOBOX2_FQN)\n                || isSubClassOf(truffleFrame, ENT_COMPILER_FRAME_NOBOX_FQN)\n                || isSubClassOf(truffleFrame, COMPILER_FRAME_BOX_FQN)\n                || isSubClassOf(truffleFrame, COMPILER_FRAME_BOX1_FQN)\n                || isSubClassOf(truffleFrame, ENT_COMPILER_FRAME_BOX_FQN);\n    }\n\n    private static boolean isSubClassOf(Instance i, String superClassName) {\n        if (i != null) {\n            JavaClass superCls = i.getJavaClass();\n\n            for (; superCls != null; superCls = superCls.getSuperClass()) {\n                if (superCls.getName().equals(superClassName)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n    \n    public static boolean isTruffleFrame(Instance truffleFrame) {\n        return isTruffleFrameSubClass(truffleFrame);\n    }\n\n    private static Instance getValueOfFields(Instance instance, String... fields) {\n        if (instance != null) {\n            for (String field : fields) {\n                Object val = instance.getValueOfField(field);\n                if (val == null || !(val instanceof Instance)) {\n                    return null;\n                }\n                instance = (Instance) val;\n            }\n        }\n        return instance;\n    }\n\n    private List<Instance> getObjectArray(Instance instance, String field) {\n        if (instance != null) {\n            Object localsInst = instance.getValueOfField(field);\n\n            if (localsInst instanceof ObjectArrayInstance) {\n                return ((ObjectArrayInstance) localsInst).getValues();\n            }\n        }\n        return null;\n    }\n\n    private List<String> getPrimitiveArray(Instance instance, String field) {\n        Object localsInst = instance.getValueOfField(field);\n\n        if (localsInst instanceof PrimitiveArrayInstance) {\n            return ((PrimitiveArrayInstance) localsInst).getValues();\n        }\n        return null;\n    }\n\n    private void createArguments(Instance truffleFrame, List<Instance> arguments, List<FieldValue> values) {\n        for (int i = 0; i < arguments.size(); i++) {\n            values.add(new TruffleObjectField(truffleFrame, arguments.get(i), ARG_PREFIX + i));\n        }\n    }\n\n    private void createLocals(Instance truffleFrame, List<Instance> locals, List<String> primitiveLocals, Instance[] frameSlots,\n            Instance defaultValue, List<FieldValue> vals) {\n        for (int i = 0; i < locals.size(); i++) {\n            Instance frameSlot = frameSlots[i];\n            Instance nameInst = (Instance) frameSlot.getValueOfField(\"identifier\"); // NOI18N\n            String name = getDetails(nameInst);\n            Type type = getVauleType(frameSlot);\n            String primitiveLocal = primitiveLocals != null ? primitiveLocals.get(i) : null;\n            FieldValue fieldVal = creatField(truffleFrame, type, name, locals.get(i), primitiveLocal, defaultValue);\n\n            vals.add(fieldVal);\n        }\n    }\n\n    private void createLocals(Instance truffleFrame, List<Instance> locals, List<String> primitiveLocals, List<String> tags, List<Instance> names, Instance defaultValue, List<FieldValue> vals) {\n        for (int i = 0; i < locals.size(); i++) {\n            String name;\n            if (names != null) {\n                Instance nameInst = names.get(i);\n                name = getDetails(nameInst);\n            } else {\n                name = Integer.toString(i);\n            }\n            Type type = getTypeFromByte(Byte.parseByte(tags.get(i)));\n            String primitiveLocal = primitiveLocals != null ? primitiveLocals.get(i) : null;\n            FieldValue fieldVal = creatField(truffleFrame, type, name, locals.get(i), primitiveLocal, defaultValue);\n\n            vals.add(fieldVal);\n        }\n    }\n\n    private FieldValue creatField(Instance truffleFrame, Type type, String name, Instance local, String primitiveLocal, Instance defaultValue) {\n        if (ObjType.OBJECT.equals(type)) {\n            return new TruffleObjectField(truffleFrame, local, name);\n        } else { // primitive type\n            if (primitiveLocal != null) {\n                String value = convertValue(primitiveLocal, type);\n                return new TruffleField(truffleFrame, value, name, type);\n            } else {\n                if (local.equals(defaultValue)) {\n                    return new TruffleField(truffleFrame, LOCAL_UNDEFINED, name, type);\n                } else {\n                    String value = getDetails(local);\n                    return new TruffleField(truffleFrame, value, name, type);\n                }\n            }\n        }\n    }\n\n    private Instance[] createFrameSlots(List<Instance> slots, int size) {\n        Instance[] names = new Instance[size];\n\n        for (int i = 0; i < size; i++) {\n            Instance frameSlot = slots.get(i);\n            Integer index = (Integer) frameSlot.getValueOfField(\"index\"); // NOI18N\n\n            names[index.intValue()] = frameSlot;\n        }\n        return names;\n    }\n\n    private Type getVauleType(Instance frameSlot) {\n        Instance kind = (Instance) frameSlot.getValueOfField(\"kind\"); // NOI18N\n        return getTypeFromByte((Byte) kind.getValueOfField(\"tag\"));     // NOI18N\n    }\n\n    private Type getTypeFromByte(Byte tag) throws IllegalArgumentException {\n        switch (tag) {\n            case OBJECT_TAG:\n                return ObjType.OBJECT;\n            case LONG_TAG:\n                return PType.LONG;\n            case INT_TAG:\n                return PType.INT;\n            case DOUBLE_TAG:\n                return PType.DOUBLE;\n            case FLOAT_TAG:\n                return PType.FLOAT;\n            case BOOLEAN_TAG:\n                return PType.BOOLEAN;\n            case BYTE_TAG:\n                return PType.BYTE;\n            case ILLEGAL_TAG:\n                return ObjType.OBJECT;\n            case STATIC_TAG:\n                return ObjType.OBJECT;\n            default:\n                throw new IllegalArgumentException(\"Unknown type:\" + tag); // NOI18N\n        }\n    }\n\n    private String convertValue(String val, Type type) {\n        if (!PType.LONG.equals(type)) {\n            long originalLong = Long.parseLong(val);\n\n            if (PType.INT.equals(type)) {\n                return String.valueOf((int) originalLong);\n            }\n            if (PType.DOUBLE.equals(type)) {\n                return String.valueOf(Double.longBitsToDouble(originalLong));\n            }\n            if (PType.FLOAT.equals(type)) {\n                return String.valueOf(Float.intBitsToFloat((int) originalLong));\n            }\n            if (PType.BOOLEAN.equals(type)) {\n                return String.valueOf((int) originalLong != 0);\n            }\n            if (PType.BYTE.equals(type)) {\n                return String.valueOf((byte) originalLong);\n            }\n        }\n        return val;\n    }\n\n    private String getDetails(Instance i) {\n        final String className = i.getJavaClass().getName();\n        if (className.startsWith(\"java.lang.\")) {  // NOI18N\n            return DetailsUtils.getInstanceString(i);\n        }\n        if (className.equals(\"com.oracle.truffle.api.strings.TruffleString\")) {  // NOI18N\n            return DetailsUtils.getInstanceString(i);\n        }\n        return \"N/A\";   // NOI18N\n    }\n\n    private class TruffleField implements FieldValue {\n\n        private final Instance definingInstance;\n        private final Field field;\n        private final String value;\n\n        private TruffleField(Instance defI, String val, String name, Type type) {\n            definingInstance = defI;\n            value = val;\n            field = new FrameField(defI.getJavaClass(), name, type);\n        }\n\n        @Override\n        public Field getField() {\n            return field;\n        }\n\n        @Override\n        public Instance getDefiningInstance() {\n            return definingInstance;\n        }\n\n        @Override\n        public String getValue() {\n            return value;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof TruffleField) {\n                TruffleField tfv = (TruffleField) obj;\n                return definingInstance.equals(tfv.definingInstance)\n                    && field.equals(tfv.field);\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            return 31 * definingInstance.hashCode() + field.hashCode();\n        }\n    }\n\n    private class TruffleObjectField extends TruffleField implements ObjectFieldValue {\n\n        private final Instance instanceValue;\n\n        private TruffleObjectField(Instance defI, Instance val, String name) {\n            super(defI, val == null ? null : String.valueOf(val.getInstanceId()), name, ObjType.OBJECT);\n            instanceValue = val;\n        }\n\n        @Override\n        public Instance getInstance() {\n            return instanceValue;\n        }\n    }\n\n    private static class FrameField implements Field {\n\n        private final JavaClass definingClass;\n        private final String name;\n        private final Type type;\n\n        private FrameField(JavaClass cls, String n, Type t) {\n            definingClass = cls;\n            name = n;\n            type = t;\n        }\n\n        @Override\n        public JavaClass getDeclaringClass() {\n            return definingClass;\n        }\n\n        @Override\n        public String getName() {\n            return name;\n        }\n\n        @Override\n        public boolean isStatic() {\n            return false;\n        }\n\n        @Override\n        public Type getType() {\n            return type;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof FrameField) {\n                FrameField ff = (FrameField) obj;\n\n                return definingClass.equals(ff.definingClass)\n                    && name.equals(ff.name);\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            return 31 * definingClass.hashCode() + name.hashCode();\n        }\n    }\n\n    private static class ObjType implements Type {\n\n        static final Type OBJECT = new ObjType();\n\n        @Override\n        public String getName() {\n            return \"object\";    // NOI18N\n        }\n    }\n\n    private static class PType implements PrimitiveType {\n\n        static final PrimitiveType BOOLEAN = new PType(\"boolean\"); //NOI18N\n        static final PrimitiveType CHAR = new PType(\"char\"); //NOI18N\n        static final PrimitiveType FLOAT = new PType(\"float\"); //NOI18N\n        static final PrimitiveType DOUBLE = new PType(\"double\"); //NOI18N\n        static final PrimitiveType BYTE = new PType(\"byte\"); //NOI18N\n        static final PrimitiveType SHORT = new PType(\"short\"); //NOI18N\n        static final PrimitiveType INT = new PType(\"int\"); //NOI18N\n        static final PrimitiveType LONG = new PType(\"long\"); //NOI18N\n\n        private String name;\n\n        PType(String n) {\n            name = n;\n        }\n\n        @Override\n        public String getName() {\n            return name;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleInstancePropertyProvider.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectArrayItemNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TerminalJavaNodes;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.HeapOperations;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.HeapProgress;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleInstancePropertyProvider_ComputingNodes=<computing {0}...>\", // <computing items...>\n    \"TruffleInstancePropertyProvider_MoreNodes=<another {0} {1} left>\", // <another 1234 items left>\n    \"TruffleInstancePropertyProvider_SamplesContainer=<sample {0} {1}>\", // <sample 1234 items>\n    \"TruffleInstancePropertyProvider_NodesContainer=<{2} {0}-{1}>\" // <items 1001 - 2000>\n})\npublic abstract class TruffleInstancePropertyProvider<O extends TruffleObject, T extends TruffleType<O>, F extends TruffleLanguageHeapFragment<O, T>, L extends TruffleLanguage<O, T, F>, I> extends HeapViewerNode.Provider {\n    \n    private final L language;\n    \n    private final String propertyName;\n    private final int maxPropertyItems;\n    \n    private final boolean displaysProgress;\n    private final boolean filtersProperties;\n    \n    \n    protected TruffleInstancePropertyProvider(String propertyName, L language, boolean displaysProgress, boolean filtersProperties, int maxPropertyItems) {\n        this.language = language;\n        this.propertyName = propertyName;\n        this.maxPropertyItems = maxPropertyItems;\n        this.displaysProgress = displaysProgress;\n        this.filtersProperties = filtersProperties;\n    }\n    \n\n    @Override\n    public String getName() {\n        return propertyName;\n    }\n    \n    \n    protected final L getLanguage() {\n        return language;\n    }\n\n    \n    @Override\n    public abstract boolean supportsView(Heap heap, String viewID);\n\n    @Override\n    public abstract boolean supportsNode(HeapViewerNode node, Heap heap, String viewID);\n    \n    \n    protected abstract Collection<I> getPropertyItems(Instance instance);\n    \n    protected boolean includeItem(I item) { return true; }\n    \n    protected abstract HeapViewerNode createNode(I item, Heap heap);\n\n    \n    @Override\n    public final HeapViewerNode[] getNodes(HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        Instance instance = HeapViewerNode.getValue(parent, DataType.INSTANCE, heap);\n        return instance == null ? null : getNodes(instance, parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n    }\n    \n    final HeapViewerNode[] getNodes(Instance instance, HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        Collection<I> itemsC = null;\n        \n        if (!displaysProgress) {\n            itemsC = getPropertyItems(instance);\n        } else {\n            HeapOperations.OpProgressHandle pHandle = new HeapOperations.OpProgressHandle(Bundle.TruffleInstancePropertyProvider_ComputingNodes(propertyName));\n            pHandle.setInitialDelay(1000);\n            pHandle.start(HeapProgress.PROGRESS_MAX);\n            pHandle.setProgress(0);\n\n            try { itemsC = getPropertyItems(instance); }\n            finally { pHandle.finish(); }\n        }\n        \n        if (itemsC == null) return null;\n        \n        final List<I> items = new ArrayList<>(itemsC);\n        \n        if (filtersProperties) {\n            Iterator<I> itemsIt = items.iterator();\n            while (itemsIt.hasNext()) if (!includeItem(itemsIt.next())) itemsIt.remove();\n        }\n        \n        NodesComputer<Integer> computer = new NodesComputer<Integer>(items.size(), maxPropertyItems) {\n            protected boolean sorts(DataType dataType) {\n                return !DataType.COUNT.equals(dataType);\n            }\n            protected HeapViewerNode createNode(Integer index) {\n                return TruffleInstancePropertyProvider.this.createNode(items.get(index), heap);\n            }\n            protected ProgressIterator<Integer> objectsIterator(int index, Progress progress) {\n                Iterator<Integer> iterator = integerIterator(index, items.size());\n                return new ProgressIterator<>(iterator, index, false, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return Bundle.TruffleInstancePropertyProvider_MoreNodes(moreNodesCount, propertyName);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return Bundle.TruffleInstancePropertyProvider_SamplesContainer(objectsCount, propertyName);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return Bundle.TruffleInstancePropertyProvider_NodesContainer(firstNodeIdx, lastNodeIdx, propertyName);\n            }\n        };\n\n        return computer.computeNodes(parent, heap, viewID, null, dataTypes, sortOrders, progress);\n    }\n    \n    \n    public static abstract class ArrayItems<O extends TruffleObject, T extends TruffleType<O>, F extends TruffleLanguageHeapFragment<O, T>, L extends TruffleLanguage<O, T, F>> extends TruffleInstancePropertyProvider<O, T, F, L, ArrayItemValue> {\n        \n        public ArrayItems(String propertyName, L language, boolean filtersProperties) {\n            super(propertyName, language, false, filtersProperties, UIThresholds.MAX_ARRAY_ITEMS);\n        }\n        \n        \n        @Override\n        public boolean supportsNode(HeapViewerNode parent, Heap heap, String viewID) {\n            if (parent instanceof InstanceNode && !InstanceNode.Mode.INCOMING_REFERENCE.equals(((InstanceNode)parent).getMode())) {\n                Instance instance = ((InstanceNode)parent).getInstance();\n                return instance instanceof ObjectArrayInstance;\n            } else {\n                return false;\n            }\n        }\n        \n        @Override\n        protected Collection<ArrayItemValue> getPropertyItems(Instance instance) {\n            return ((ObjectArrayInstance)instance).getItems();\n        }\n        \n        \n        protected abstract HeapViewerNode createObjectArrayItemNode(O object, String type, ArrayItemValue item);\n        \n        \n        @Override\n        protected boolean includeItem(ArrayItemValue item) {\n            Instance instance = item.getInstance();\n\n            // display null fields\n            if (instance == null) return true;\n            \n            // display primitive arrays\n            if (instance instanceof PrimitiveArrayInstance) return true;\n            \n            // display language objects\n            if (getLanguage().isLanguageObject(instance)) return true;\n\n            // display DynamicObject fields\n            if (DynamicObject.isDynamicObject(instance)) return true;\n\n            // display selected Java fields\n            return includeInstance(instance);\n        }\n        \n        protected boolean includeInstance(Instance instance) { return true; }\n        \n        @Override\n        protected final HeapViewerNode createNode(ArrayItemValue item, Heap heap) {\n            Instance instance = item.getInstance();\n            if (getLanguage().isLanguageObject(instance)) {\n                O object = getLanguage().createObject(instance);\n                return createObjectArrayItemNode(object, object.getType(), item);\n            } else {\n                return createForeignArrayItemNode(instance, item, heap);\n            }\n        }\n        \n        protected HeapViewerNode createForeignArrayItemNode(Instance instance, ArrayItemValue item, Heap heap) {\n            if (DynamicObject.isDynamicObject(instance)) {\n                DynamicObject dobj = new DynamicObject(instance);\n                return new DynamicObjectArrayItemNode<>(dobj, dobj.getType(), item);\n            } else {\n                return new TerminalJavaNodes.ArrayItem(item, false);\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleLanguage.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.awt.Image;\nimport java.io.File;\nimport java.lang.ref.Reference;\nimport java.lang.ref.WeakReference;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.WeakHashMap;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.heapviewer.HeapFragment;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleLocalObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleTypeNode;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class TruffleLanguage<O extends TruffleObject, T extends TruffleType<O>, F extends TruffleLanguageHeapFragment<O, T>> extends HeapFragment.Provider {\n    \n    private final Map<Heap, Reference<F>> fragments = new WeakHashMap<>();\n    \n    protected abstract F createFragment(Heap heap);\n    \n    // HeapFragment.Provider implementation, not to be used by client code\n    public final List<HeapFragment> getFragments(File heapDumpFile, Lookup.Provider heapDumpProject, Heap heap) {\n        HeapFragment fragment = fragmentFromHeap(heap);\n        return fragment == null ? null : Collections.singletonList(fragment);\n    }\n    \n    public synchronized final F fragmentFromHeap(Heap heap) {\n        Reference<F> fragmentRef = fragments.get(heap);\n        if (fragmentRef == null) {\n            F fragment = createFragment(heap);\n            if (fragment == null) return null;\n            \n            fragments.put(heap, new WeakReference<>(fragment));\n            return fragment;\n        } else {\n            return fragmentRef.get();\n        }\n    }\n    \n    \n    public abstract String getID();\n    \n    \n    private Image badgeImage;\n    protected synchronized Image badgeImage() {\n        if (badgeImage == null) {\n            String path = getClass().getPackage().getName().replace('.', '/') + \"/\" + getID() + \"_badge.png\"; // NOI18N\n            badgeImage = ImageUtilities.loadImage(path, true);\n        }\n        return badgeImage;\n    }\n    \n    public Icon createLanguageIcon(Icon icon) {\n        return new ImageIcon(ImageUtilities.mergeImages(ImageUtilities.icon2Image(icon), badgeImage(), 0, 0));\n    }\n    \n    \n    public abstract Class<O> getLanguageObjectClass();\n    \n    \n    public abstract boolean isLanguageObject(Instance instance);\n    \n    public abstract O createObject(Instance instance);\n    \n    public abstract T createType(String name);\n    \n    \n    public abstract TruffleObjectNode<O> createObjectNode(O object, String type);\n    \n    public abstract TruffleLocalObjectNode<O> createLocalObjectNode(O object, String type);\n    \n    public abstract TruffleTypeNode<O, T> createTypeNode(T type, Heap heap);\n    \n    \n    private static final String LANGUAGE_INFO_FQN = \"com.oracle.truffle.api.nodes.LanguageInfo\"; // NOI18N\n    private static final String LANGUAGE_CACHE_FQN = \"com.oracle.truffle.api.vm.LanguageCache\"; // NOI18N\n    private static final String LANGUAGE_CACHE1_FQN = \"com.oracle.truffle.polyglot.LanguageCache\"; // NOI18N\n    private static final String NAME_FIELD = \"name\";    // NOI18N\n    \n    protected static Instance getLanguageInfo(Heap heap, String languageID) {\n        // check for DynamicObject\n        if (!DynamicObject.hasDynamicObject(heap)) return null;\n        \n        // check for LanguageInfo\n        JavaClass langInfoClass = heap.getJavaClassByName(LANGUAGE_INFO_FQN);\n        if (!checkLangClass(langInfoClass)) {\n            langInfoClass = heap.getJavaClassByName(LANGUAGE_CACHE_FQN);\n            if (!checkLangClass(langInfoClass)) {\n                langInfoClass = heap.getJavaClassByName(LANGUAGE_CACHE1_FQN);\n                if (!checkLangClass(langInfoClass)) return null;\n            }\n        }\n        \n        // search the language\n        List<Instance> langInfos = langInfoClass.getInstances();\n        for (Instance langInfo : langInfos) {\n            String langName = DetailsUtils.getInstanceFieldString(langInfo, \"name\");    // NOI18N\n            if (languageID.equals(langName)) return langInfo;\n        }\n        \n        return null;\n    }\n    \n    private static boolean checkLangClass(JavaClass infoClass) {\n        if (infoClass != null) {\n            List<Field> fields = infoClass.getFields();\n            for (Field field : fields)\n                if (NAME_FIELD.equals(field.getName())) return true;\n        }\n        return false;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleLanguageHeapFragment.java",
    "content": "/*\n * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.HeapFragment;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n// O: type of base language objects (JavaScriptDynamicObject, RubyDynamicObject, PythonObject, RObject)\n// T: TruffleType or its subclass aggregating O objects\n@NbBundle.Messages({\n    \"TruffleLanguageHeapFragment_Language=Language\",\n    \"TruffleLanguageHeapFragment_InitializingLanguageModel=Initializing {0} Model...\"\n})\npublic abstract class TruffleLanguageHeapFragment<O extends TruffleObject, T extends TruffleType<O>> extends HeapFragment {\n    \n    private final TruffleLanguage<O, T, ? extends TruffleLanguageHeapFragment<O, T>> language;\n    \n    private long heapSize;\n    private long objectsCount;\n    private List<T> types;\n    private final Object statisticsLock = new Object();\n    \n    private Progress statisticsProgress;\n    private boolean ownProgress;\n    private final Object statisticsProgressLock = new Object();\n    \n    \n    protected TruffleLanguageHeapFragment(String ID, String name, String description, TruffleLanguage<O, T, ? extends TruffleLanguageHeapFragment<O, T>> language, Heap heap) {\n        super(ID, name, description, heap);\n        this.language = language;\n    }\n    \n    \n    public static boolean isTruffleHeap(HeapContext context) {\n        return context.getFragment() instanceof TruffleLanguageHeapFragment; // NOI18N\n    }\n    \n    \n    public long getHeapSize(Progress progress) {\n        checkInitialized(progress);\n        return heapSize;\n    }\n    \n    public long getObjectsCount(Progress progress) {\n        checkInitialized(progress);\n        return objectsCount;\n    }\n    \n    public List<T> getTypes(Progress progress) {\n        checkInitialized(progress);\n        return types;\n    }\n    \n    public T getType(String name, Progress progress) {\n        List<T> _types = getTypes(progress);\n        for (T type : _types) if (name.equals(type.getName())) return type;\n        return null;\n    }\n    \n    \n    public abstract Iterator<Instance> getInstancesIterator();\n    \n    public Iterator<O> getObjectsIterator() {\n        return new ObjectsIterator(getInstancesIterator());\n    }\n    \n    \n    private void checkInitialized(Progress progress) {\n        Progress.Listener progressListener = null;\n        \n        if (progress != null) {\n            synchronized (statisticsProgressLock) {\n                if (statisticsProgress != null) {\n                    statisticsProgress.addChangeListener(new Progress.Listener() {\n                        @Override\n                        public void progressChanged(Progress.Event event) {\n                            progress.setCurrentStep(event.getCurrentStep());\n                        }\n                    });\n                }\n            }\n        }\n        \n        synchronized (statisticsLock) {\n            if (types == null) computeStatistics(progress);\n        }\n\n        if (progressListener != null) {\n            synchronized (statisticsProgressLock) {\n                if (statisticsProgress != null) {\n                    statisticsProgress.removeChangeListener(progressListener);\n                }\n            }\n        }\n    }\n    \n    private void computeStatistics(Progress progress) {\n        if (statisticsProgress == null) {\n            synchronized (statisticsProgressLock) {\n                if (progress != null) {\n                    statisticsProgress = progress;\n                } else {\n                    ownProgress = true;\n                    statisticsProgress = new Progress();\n                    statisticsProgress.setupUnknownSteps();\n                }\n            }\n        }\n        \n        int verIdx = getDescription().indexOf(\" (\"); // NOI18N\n        String langName = verIdx != -1 ? getDescription().substring(0, verIdx) : Bundle.TruffleLanguageHeapFragment_Language();\n        ProgressHandle pHandle = ProgressHandle.createHandle(Bundle.TruffleLanguageHeapFragment_InitializingLanguageModel(langName));\n        pHandle.setInitialDelay(1000);\n        pHandle.start();\n        \n        TruffleType.TypesComputer<O, T> computer = new TruffleType.TypesComputer<O, T>(language, heap) {\n            @Override\n            protected void addingObject(long size, long retained, String type) {\n                objectsCount++;\n                heapSize += size;\n            }\n        };\n        \n        Iterator<O> objects = getObjectsIterator();\n        try {\n            while (objects.hasNext()) {\n                computer.addObject(objects.next());\n                if (statisticsProgress != null) statisticsProgress.step();\n            }\n        } finally {\n            if (statisticsProgress != null && ownProgress) statisticsProgress.finish();\n            pHandle.finish();\n        }\n        \n        types = computer.getTypes();\n    }\n    \n\n    protected final Iterator<Instance> instancesIterator(String javaClassFqn) {\n        return HeapUtils.instancesIterator(HeapUtils.getSubclasses(heap, javaClassFqn));\n    }\n    \n    protected final Iterator<Instance> instancesIterator(String[] javaClassFqns) {\n        List<JavaClass> classes = new ArrayList<>();\n        for (String fqn : javaClassFqns)\n            classes.addAll(HeapUtils.getSubclasses(heap, fqn));\n        return HeapUtils.instancesIterator(classes);\n    }    \n\n    \n    protected static String fragmentDescription(Instance langID) {\n        return DetailsSupport.getDetailsString(langID);\n    }\n\n    \n    protected class ObjectsIterator implements Iterator<O> {\n        private final Iterator<Instance> instancesIter;\n        \n        public ObjectsIterator(Iterator<Instance> iter) {\n            instancesIter = iter;\n        }\n\n        public ObjectsIterator(Collection<JavaClass> cls) {\n            instancesIter = HeapUtils.instancesIterator(cls);\n        }\n\n        @Override\n        public boolean hasNext() {\n            return instancesIter.hasNext();\n        }\n\n        @Override\n        public O next() {\n            return language.createObject(instancesIter.next());\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleObject.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.truffle;\n\n\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class TruffleObject {\n    \n    public static final DataType<TruffleObject> DATA_TYPE = new DataType<>(TruffleObject.class, null, null);\n    \n    \n    public abstract long getSize();\n    \n    public abstract long getRetainedSize();\n    \n    public abstract String getType();\n    \n    public abstract long getTypeId();\n    \n    public static abstract class InstanceBased extends TruffleObject {\n        \n        public abstract Instance getInstance();\n        \n        @Override\n        public boolean equals(Object o) {\n            if (o == this) {\n                return true;\n            }\n            if (!(o instanceof InstanceBased)) {\n                return false;\n            }\n            return getInstance().equals(((InstanceBased) o).getInstance());\n        }\n\n        @Override\n        public int hashCode() {\n            return getInstance().hashCode();\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleObjectMergedFields.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.text.Format;\nimport java.text.NumberFormat;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.ErrorNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeWrapper;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRendererWrapper;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.ExcludingIterator;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.heapviewer.utils.InterruptibleIterator;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.heapviewer.utils.counters.InstanceCounter;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class TruffleObjectMergedFields<O extends TruffleObject> {\n    \n    private final Heap heap;\n    private final TruffleObjectsWrapper<O> objects;\n    \n    \n    TruffleObjectMergedFields(TruffleObjectsWrapper<O> objects, Heap heap) {\n        this.objects = objects;\n        this.heap = heap;\n    }\n    \n    \n    protected abstract String getMoreNodesString(String moreNodesCount);\n    protected abstract String getSamplesContainerString(String objectsCount);\n    protected abstract String getNodesContainerString(String firstNodeIdx, String lastNodeIdx);\n    \n    protected abstract TruffleLanguage getLanguage();\n    \n    protected abstract boolean filtersFields();\n    protected abstract boolean includeField(FieldValue field);\n    protected abstract Collection<FieldValue> getFields(O object) throws InterruptedException;\n    \n    \n    private int objectsCount() { return objects.getObjectsCount(); }\n    private Iterator<O> objectsIterator() { return new InterruptibleIterator<>(objects.getObjectsIterator()); }\n    \n    private HeapViewerNode createObjectNode(O object) {\n        return (HeapViewerNode)getLanguage().createObjectNode(object, object.getType());\n    }\n    \n    \n    HeapViewerNode[] getNodes(HeapViewerNode parent, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        try {\n            final Set<FieldDescriptor> fields = getAllObjectsFields(progress);\n            NodesComputer<FieldDescriptor> computer = new NodesComputer<FieldDescriptor>(fields.size(), UIThresholds.MAX_INSTANCE_FIELDS) {\n                protected boolean sorts(DataType dataType) {\n                    return true;\n                }\n                protected HeapViewerNode createNode(FieldDescriptor field) {\n                    return new MergedObjectFieldNode(field);\n                }\n                protected ProgressIterator<FieldDescriptor> objectsIterator(int index, Progress progress) {\n                    Iterator<FieldDescriptor> iterator = fields.iterator();\n                    return new ProgressIterator<>(iterator, index, true, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return TruffleObjectMergedFields.this.getMoreNodesString(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return TruffleObjectMergedFields.this.getSamplesContainerString(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return TruffleObjectMergedFields.this.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            return computer.computeNodes(parent, heap, viewID, null, dataTypes, sortOrders, progress);\n        } catch (OutOfMemoryError e) {\n            System.err.println(\"Out of memory in TruffleObjectMergedFields: \" + e.getMessage()); // NOI18N\n            HeapUtils.handleOOME(true, e);\n            return new HeapViewerNode[] { new ErrorNode.OOME() };\n        }\n    }\n    \n    \n    private Set<FieldDescriptor> getAllObjectsFields(Progress progress) throws InterruptedException {\n        boolean filtersProperties = filtersFields();\n\n        Set<FieldDescriptor> allFields = new HashSet<>();\n        Iterator<O> objectsI = objectsIterator();\n        \n        try {\n            progress.setupKnownSteps(objects.getObjectsCount());\n            \n            while (objectsI.hasNext()) {\n                progress.step();\n                \n                Collection<FieldValue> fields = getFields(objectsI.next());\n                if (fields != null) for (FieldValue field : fields) {\n                    if (!filtersProperties || includeField(field)) {\n                        Field f = field.getField();\n                        String fname = f.isStatic() ? \"static \" + f.getName() : f.getName(); // NOI18N\n                        int ftype = field instanceof ObjectFieldValue ? 0 : -1;\n                        allFields.add(new FieldDescriptor(fname, ftype));\n                    }\n                }\n            }\n            if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n        } finally {\n            progress.finish();\n        }\n\n        return allFields;\n    }\n    \n    private FieldValue getValueOfField(O object, String name) {\n        try {\n            Collection<FieldValue> fieldValues = getFields(object);\n            if (fieldValues == null) return null;\n\n            ArrayList<FieldValue> fieldValuesArr = fieldValues instanceof ArrayList ?\n                                  (ArrayList<FieldValue>)fieldValues : new ArrayList<>(fieldValues);\n\n            for (int i = fieldValuesArr.size() - 1; i >= 0; i--) {\n                FieldValue fv = fieldValuesArr.get(i);\n                Field field = fv.getField();\n                String fieldN = field.getName();\n                if (field.isStatic()) fieldN = \"static \" + fieldN; // NOI18N\n                if (fieldN.equals(name)) return fv;\n            }\n        } catch (InterruptedException e) {}\n\n        return null;\n    }\n    \n    \n    private class MergedObjectFieldNode extends HeapViewerNode {\n        \n        private final String fieldName;\n        private final int fieldType;\n        private int valuesCount = -1;\n        \n        \n        MergedObjectFieldNode(FieldDescriptor fieldDescriptor) {\n            this.fieldName = fieldDescriptor.name;\n            this.fieldType = fieldDescriptor.type;\n        }\n        \n        \n        String getFieldName() {\n            return fieldName;\n        }\n        \n        int getValuesCount() {\n            return valuesCount;\n        }\n        \n        \n        private String getName() {\n            return valuesCount == -1 ? fieldName : fieldName + \" \" + // NOI18N\n                   Bundle.TruffleObjectPropertyProvider_ValuesCountHint(valuesCount);\n        }\n        \n        \n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            if (fieldType == 0) {\n                final InstanceCounter values = new InstanceCounter(objectsCount());\n\n                Iterator<O> objects = objectsIterator();\n                try {\n                    progress.setupKnownSteps(objectsCount());\n                    \n                    while (objects.hasNext()) {\n                        O o = objects.next();\n                        progress.step();\n                        FieldValue value = getValueOfField(o, fieldName);\n                        if (value instanceof ObjectFieldValue)\n                            values.count(((ObjectFieldValue)value).getInstance());\n                    }\n                    if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n                } catch (OutOfMemoryError e) {\n                    System.err.println(\"Out of memory in TruffleObjectMergedFields: \" + e.getMessage()); // NOI18N\n                    HeapUtils.handleOOME(true, e);\n                    return new HeapViewerNode[] { new ErrorNode.OOME() };\n                } finally {\n                    progress.finish();\n                }\n\n                valuesCount = values.size();            \n\n                final TruffleLanguage language = getLanguage();\n\n                NodesComputer<InstanceCounter.Record> computer = new NodesComputer<InstanceCounter.Record>(valuesCount, UIThresholds.MAX_MERGED_OBJECTS) {\n                    protected boolean sorts(DataType dataType) {\n                        return true;\n                    }\n                    protected HeapViewerNode createNode(InstanceCounter.Record record) {\n                        Instance instance = record.getInstance(heap);\n                        HeapViewerNode node;\n\n                        if (language.isLanguageObject(instance)) {\n                            O object = (O)language.createObject(instance);\n                            node = (HeapViewerNode)language.createObjectNode(object, object.getType());\n                        } else {\n                            if (DynamicObject.isDynamicObject(instance)) {\n                                DynamicObject pbject = new DynamicObject(instance);\n                                node = new DynamicObjectNode<>(pbject, pbject.getType());\n                            } else {\n                                node = new InstanceNode.IncludingNull(instance);\n                            }\n                        }\n\n                        return new ObjectFieldValueNode(node, record.getCount()) {\n                            @Override\n                            String fieldName() { return fieldName; }\n                        };\n                    }\n                    protected ProgressIterator<InstanceCounter.Record> objectsIterator(int index, Progress progress) {\n                        Iterator<InstanceCounter.Record> iterator = values.iterator();\n                        return new ProgressIterator(iterator, index, true, progress);\n                    }\n                    protected String getMoreNodesString(String moreNodesCount)  {\n                        return Bundle.TruffleObjectPropertyProvider_FieldHistogramMoreNodes(moreNodesCount);\n                    }\n                    protected String getSamplesContainerString(String objectsCount)  {\n                        return Bundle.TruffleObjectPropertyProvider_FieldHistogramSamplesContainer(objectsCount);\n                    }\n                    protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                        return Bundle.TruffleObjectPropertyProvider_FieldHistogramNodesContainer(firstNodeIdx, lastNodeIdx);\n                    }\n                };\n\n                return computer.computeNodes(MergedObjectFieldNode.this, heap, viewID, null, dataTypes, sortOrders, progress);\n            } else {\n                final Map<String, Integer> values = new HashMap<>();\n\n                Iterator<O> objects = objectsIterator();\n                try {\n                    progress.setupKnownSteps(objectsCount());\n                    \n                    while (objects.hasNext()) {\n                        O o = objects.next();\n                        progress.step();\n                        FieldValue value = getValueOfField(o, fieldName);\n                        if (value != null) {\n                            String val = value.getValue();\n                            Integer count = values.get(val);\n                            if (count == null) count = 0;\n                            values.put(val, ++count);\n                        }\n                    }\n                    if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n                } catch (OutOfMemoryError e) {\n                    System.err.println(\"Out of memory in TruffleObjectMergedFields: \" + e.getMessage()); // NOI18N\n                    HeapUtils.handleOOME(true, e);\n                    return new HeapViewerNode[] { new ErrorNode.OOME() };\n                } finally {\n                    progress.finish();\n                }\n\n                valuesCount = values.size(); \n                \n                NodesComputer<Map.Entry<String, Integer>> computer = new NodesComputer<Map.Entry<String, Integer>>(valuesCount, UIThresholds.MAX_MERGED_OBJECTS) {\n                    protected boolean sorts(DataType dataType) {\n                        return true;\n                    }\n                    protected HeapViewerNode createNode(Map.Entry<String, Integer> record) {\n                        return new PrimitiveFieldValueNode(record.getKey(), \"object\", record.getValue()) { // NOI18N\n                            @Override\n                            String fieldName() { return fieldName; }\n                        };\n                    }\n                    protected ProgressIterator<Map.Entry<String, Integer>> objectsIterator(int index, Progress progress) {\n                        Iterator<Map.Entry<String, Integer>> iterator = values.entrySet().iterator();\n                        return new ProgressIterator(iterator, index, true, progress);\n                    }\n                    protected String getMoreNodesString(String moreNodesCount)  {\n                        return Bundle.TruffleObjectPropertyProvider_FieldHistogramMoreNodes(moreNodesCount);\n                    }\n                    protected String getSamplesContainerString(String objectsCount)  {\n                        return Bundle.TruffleObjectPropertyProvider_FieldHistogramSamplesContainer(objectsCount);\n                    }\n                    protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                        return Bundle.TruffleObjectPropertyProvider_FieldHistogramNodesContainer(firstNodeIdx, lastNodeIdx);\n                    }\n                };\n\n                return computer.computeNodes(MergedObjectFieldNode.this, heap, viewID, null, dataTypes, sortOrders, progress);\n            }\n        }\n        \n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.NAME) return getName();\n\n            return super.getValue(type, heap);\n        }\n        \n        \n        public String toString() {\n            return getName();\n        }\n        \n    }\n    \n    \n    private abstract class ObjectFieldValueNode extends HeapViewerNodeWrapper {\n        \n        private final int valuesCount;\n        \n        \n        ObjectFieldValueNode(HeapViewerNode node, int valuesCount) {\n            super(node);\n            this.valuesCount = valuesCount;\n        }\n        \n        \n        public int getValuesCount() {\n            return valuesCount;\n        }\n        \n        \n        abstract String fieldName();\n        \n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.COUNT) return getValuesCount();\n\n            return super.getValue(type, heap);\n        }\n        \n        \n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            final String fieldName = fieldName();\n            NodesComputer<O> computer = new NodesComputer<O>(valuesCount, UIThresholds.MAX_MERGED_OBJECTS) {\n                protected boolean sorts(DataType dataType) {\n                    return true;\n                }\n                protected HeapViewerNode createNode(O object) {\n                    return TruffleObjectMergedFields.this.createObjectNode(object);\n                }\n                protected ProgressIterator<O> objectsIterator(int index, Progress progress) {\n                    final Instance _instance = HeapViewerNode.getValue(ObjectFieldValueNode.this.getNode(), DataType.INSTANCE, heap);\n                    progress.setupUnknownSteps();\n                    Iterator<O> fieldInstanceIterator = new ExcludingIterator<O>(new InterruptibleIterator(TruffleObjectMergedFields.this.objectsIterator())) {\n                        @Override\n                        protected boolean exclude(O object) {\n                            progress.step();\n                            FieldValue value = getValueOfField(object, fieldName);\n                            if (!(value instanceof ObjectFieldValue)) return true;\n                            return !Objects.equals(_instance, ((ObjectFieldValue)value).getInstance());\n                        }\n                    };\n                    return new ProgressIterator(fieldInstanceIterator, index, true, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.TruffleObjectPropertyProvider_IMoreNodes(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.TruffleObjectPropertyProvider_ISamplesContainer(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.TruffleObjectPropertyProvider_INodesContainer(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            \n            HeapViewerNode[] result = computer.computeNodes(ObjectFieldValueNode.this, heap, viewID, null, dataTypes, sortOrders, progress);\n            \n            return result;\n            \n        }\n        \n    }\n    \n    \n    private abstract class PrimitiveFieldValueNode extends HeapViewerNode {\n        \n        private final String fieldValue;\n        private final String fieldType;\n        private final int valuesCount;\n        \n        \n        PrimitiveFieldValueNode(String fieldValue, String fieldType, int valuesCount) {\n            this.fieldValue = fieldValue;\n            this.fieldType = fieldType;\n            this.valuesCount = valuesCount;\n        }\n        \n        \n        public String getType() {\n            return fieldType;\n        }\n\n        public String getValue() {\n            return fieldValue;\n        }\n        \n        public int getValuesCount() {\n            return valuesCount;\n        }\n        \n        \n        abstract String fieldName();\n        \n        \n        public String getName() {\n             return getType() + \" \" + getValue();\n        }\n        \n        public String toString() {\n            return getName();\n        }\n        \n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.NAME) return getName();\n            if (type == DataType.COUNT) return getValuesCount();\n\n            return super.getValue(type, heap);\n        }\n        \n        \n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            final String fieldName = fieldName();\n            NodesComputer<O> computer = new NodesComputer<O>(valuesCount, UIThresholds.MAX_MERGED_OBJECTS) {\n                protected boolean sorts(DataType dataType) {\n                    return true;\n                }\n                protected HeapViewerNode createNode(O object) {\n                    return TruffleObjectMergedFields.this.createObjectNode(object);\n                }\n                protected ProgressIterator<O> objectsIterator(int index, Progress progress) {\n                    progress.setupUnknownSteps();\n                    Iterator<O> fieldInstanceIterator = new ExcludingIterator<O>(new InterruptibleIterator(TruffleObjectMergedFields.this.objectsIterator())) {\n                        @Override\n                        protected boolean exclude(O object) {\n                            progress.step();\n                            FieldValue value = getValueOfField(object, fieldName);\n                            if (value == null || value instanceof ObjectFieldValue) return true;\n                            return !Objects.equals(fieldValue, value.getValue());\n                        }\n                    };\n                    return new ProgressIterator(fieldInstanceIterator, index, true, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.TruffleObjectPropertyProvider_IMoreNodes(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.TruffleObjectPropertyProvider_ISamplesContainer(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.TruffleObjectPropertyProvider_INodesContainer(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            \n            HeapViewerNode[] result = computer.computeNodes(PrimitiveFieldValueNode.this, heap, viewID, null, dataTypes, sortOrders, progress);\n            \n            return result;\n            \n        }\n        \n    }\n    \n    \n    private static class MergedObjectFieldNodeRenderer extends NormalBoldGrayRenderer implements HeapViewerRenderer {\n        \n        private static final Format VALUES_COUNT_FORMAT = NumberFormat.getInstance();\n        \n        public void setValue(Object value, int row) {\n            TruffleObjectMergedFields.MergedObjectFieldNode n = (TruffleObjectMergedFields.MergedObjectFieldNode)value;\n            if (n != null) {\n                String name = n.getFieldName();\n                if (name.startsWith(\"static \")) { // NOI18N\n                    setNormalValue(\"static \"); // NOI18N\n                    setBoldValue(name.substring(\"static \".length())); // NOI18N\n                } else {\n                    setNormalValue(\"\"); // NOI18N\n                    setBoldValue(name);\n                }\n                setGrayValue(n.getValuesCount() == -1 ? \"\" : \" \" + Bundle.TruffleObjectPropertyProvider_ValuesCountHint(VALUES_COUNT_FORMAT.format(n.getValuesCount()))); // NOI18N\n            } else {\n                setBoldValue(\"\"); // NOI18N\n                setGrayValue(\"\"); // NOI18N\n            }\n            setIcon(Icons.getIcon(ProfilerIcons.NODE_FORWARD));\n        }\n\n\n        public String getShortName() {\n            return getBoldValue();\n        }\n        \n    }\n    \n    private static class ObjectFieldValueNodeRenderer extends HeapViewerRendererWrapper {\n        \n        @Override\n        protected HeapViewerRenderer getRenderer(Object value, int row) {\n            TruffleObjectMergedFields.ObjectFieldValueNode vnode = (TruffleObjectMergedFields.ObjectFieldValueNode)value;\n            HeapViewerNode node = vnode.getNode();\n            HeapViewerRenderer renderer = RootNode.get(vnode).resolveRenderer(node);\n            renderer.setValue(node, row);\n            return renderer;\n        }\n        \n    }\n    \n    private static class PrimitiveFieldValueNodeRenderer extends NormalBoldGrayRenderer implements HeapViewerRenderer {\n        \n        public void setValue(Object value, int row) {\n            TruffleObjectMergedFields.PrimitiveFieldValueNode n = (TruffleObjectMergedFields.PrimitiveFieldValueNode)value;\n            if (n != null) {\n                setNormalValue(n.getType() + \" \"); // NOI18N\n                setBoldValue(n.getValue());\n            } else {\n                setNormalValue(\"\"); // NOI18N\n                setBoldValue(\"\"); // NOI18N\n            }\n            setIcon(Icons.getIcon(LanguageIcons.PRIMITIVE));\n        }\n\n\n        public String getShortName() {\n            return getBoldValue();\n        }\n        \n    }\n    \n    \n    private static class FieldDescriptor {\n            \n        final String name;\n        final int type; // temporary solution, 0 for ObjectFieldValue, -1 for generic values\n\n        FieldDescriptor(String name, int type) {\n            this.name = name;\n            this.type = type;\n        }\n\n        @Override\n        public int hashCode() {\n            return 31 * type + name.hashCode();\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof FieldDescriptor)) return false;\n\n            FieldDescriptor fd = (FieldDescriptor)o;\n            return type == fd.type && Objects.equals(name, fd.name);\n        }\n\n    }\n    \n    \n    @ServiceProvider(service=HeapViewerRenderer.Provider.class)\n    public static class MergedFieldsNodeRendererProvider extends HeapViewerRenderer.Provider {\n\n        @Override\n        public boolean supportsView(HeapContext context, String viewID) {\n            return true;\n        }\n\n        @Override\n        public void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers, HeapContext context) {\n            renderers.put(TruffleObjectMergedFields.MergedObjectFieldNode.class, new MergedObjectFieldNodeRenderer());\n            renderers.put(TruffleObjectMergedFields.ObjectFieldValueNode.class, new ObjectFieldValueNodeRenderer());\n            renderers.put(TruffleObjectMergedFields.PrimitiveFieldValueNode.class, new PrimitiveFieldValueNodeRenderer());\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleObjectMergedReferences.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.ErrorNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeWrapper;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectReferenceNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.ExcludingIterator;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.heapviewer.utils.InterruptibleIterator;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleObjectMergedReferences_NoReferences=<no references>\"\n})\nabstract class TruffleObjectMergedReferences<O extends TruffleObject> {\n    \n    private final Heap heap;\n    private final TruffleObjectsWrapper<O> objects;\n    \n    \n    TruffleObjectMergedReferences(TruffleObjectsWrapper<O> objects, Heap heap) {\n        this.objects = objects;\n        this.heap = heap;\n    }\n    \n    \n    protected abstract String getMoreNodesString(String moreNodesCount);\n    protected abstract String getSamplesContainerString(String objectsCount);\n    protected abstract String getNodesContainerString(String firstNodeIdx, String lastNodeIdx);\n    \n    protected abstract TruffleLanguage getLanguage();\n    \n    protected abstract boolean filtersReferences();\n    protected abstract boolean includeReference(FieldValue field);\n    protected abstract Collection<FieldValue> getReferences(O object) throws InterruptedException;\n    \n    protected abstract HeapViewerNode createForeignReferenceNode(Instance instance, FieldValue field);\n    \n    \n    private int objectsCount() { return objects.getObjectsCount(); }\n    private Iterator<O> objectsIterator() { return new InterruptibleIterator(objects.getObjectsIterator()); }\n    \n    private HeapViewerNode createObjectNode(O object) {\n        return (HeapViewerNode)getLanguage().createObjectNode(object, object.getType());\n    }\n    \n    protected HeapViewerNode[] getNodes(HeapViewerNode parent, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        boolean filtersReferences = filtersReferences();\n\n        final Map<Long, Integer> values = new HashMap<>();\n        FieldValue refFV = null;\n        \n        Iterator<O> objectsI = objectsIterator();\n\n        try {\n            progress.setupKnownSteps(objectsCount());\n            \n            while (objectsI.hasNext()) {\n                O object = objectsI.next();\n                progress.step();\n                Collection<FieldValue> references = getReferences(object);\n                Set<Instance> referers = new HashSet<>();\n                if (references.isEmpty()) {\n                    referers.add(null);\n                } else for (FieldValue reference : references) {\n                    if (refFV == null) refFV = reference;\n                    if (!filtersReferences || includeReference(reference))\n                        referers.add(reference.getDefiningInstance());\n                }\n                for (Instance referer : referers) {\n                    long refererID = referer == null ? -1 : referer.getInstanceId();\n                    Integer count = values.get(refererID);\n                    if (count == null) count = 0;\n                    values.put(refererID, ++count);\n                }\n            }\n            if (Thread.currentThread().isInterrupted()) throw new InterruptedException();\n        } catch (OutOfMemoryError e) {\n            System.err.println(\"Out of memory in TruffleObjectMergedReferences: \" + e.getMessage()); // NOI18N\n            HeapUtils.handleOOME(true, e);\n            return new HeapViewerNode[] { new ErrorNode.OOME() };\n        } finally {\n            progress.finish();\n        }\n\n        final TruffleLanguage language = getLanguage();\n        final FieldValue refFVF = refFV;\n\n        NodesComputer<Map.Entry<Long, Integer>> computer = new NodesComputer<Map.Entry<Long, Integer>>(values.size(), UIThresholds.MAX_CLASS_INSTANCES) {\n            protected boolean sorts(DataType dataType) {\n                return true;\n            }\n            protected HeapViewerNode createNode(final Map.Entry<Long, Integer> node) {\n                long refererID = node.getKey();\n                final Instance instance = refererID == -1 ? null : heap.getInstanceByID(refererID);\n                HeapViewerNode ref;\n                if (instance == null) {\n                    ref = new InstanceNode.IncludingNull(null);\n                } else if (language.isLanguageObject(instance)) {\n                    ref = createObjectNode((O)language.createObject(instance));\n                } else {\n                    // see for example RObjectProperties.ReferencesProvider.createForeignReferenceNode\n                    ref = createForeignReferenceNode(instance, refFVF);\n                    if (ref instanceof TruffleObjectReferenceNode.InstanceBased) {\n                        Instance i = ((TruffleObjectReferenceNode.InstanceBased)ref).getInstance();\n                        ref = createObjectNode((O)language.createObject(i));\n                    } else {\n                        ref = new InstanceNode(instance);\n                    }\n                }\n\n                return new MergedObjectReferenceNode(ref) {\n                    @Override\n                    public Instance getInstance() { return instance; }\n                    @Override\n                    public int getCount() { return node.getValue(); }\n                };\n            }\n            protected ProgressIterator<Map.Entry<Long, Integer>> objectsIterator(int index, Progress progress) {\n                Iterator<Map.Entry<Long, Integer>> iterator = values.entrySet().iterator();\n                return new ProgressIterator(iterator, index, true, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return TruffleObjectMergedReferences.this.getMoreNodesString(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return TruffleObjectMergedReferences.this.getSamplesContainerString(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return TruffleObjectMergedReferences.this.getNodesContainerString(firstNodeIdx, lastNodeIdx);\n            }\n        };\n\n        return computer.computeNodes(parent, heap, viewID, null, dataTypes, sortOrders, progress);\n    }\n    \n    \n    private abstract class MergedObjectReferenceNode extends HeapViewerNodeWrapper {        \n        \n        MergedObjectReferenceNode(HeapViewerNode reference) {\n            super(reference);\n        }\n        \n        \n        public abstract Instance getInstance();\n        \n        public abstract int getCount();\n        \n        \n        protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            NodesComputer<O> computer = new NodesComputer<O>(getCount(), UIThresholds.MAX_MERGED_OBJECTS) {\n                protected boolean sorts(DataType dataType) {\n                    return !DataType.COUNT.equals(dataType);\n                }\n                @Override\n                protected HeapViewerNode createNode(O object) {\n                    return createObjectNode(object);\n                }\n                protected ProgressIterator<O> objectsIterator(int index, Progress _progress) {\n                    final Instance referer = getInstance();\n                    progress.setupUnknownSteps();\n                    Iterator<O> referencesIt = new ExcludingIterator<O>(new InterruptibleIterator(TruffleObjectMergedReferences.this.objectsIterator())) {\n                        @Override\n                        protected boolean exclude(O object) {\n                            progress.step();\n                            try {\n                                Collection<FieldValue> references = getReferences(object);\n                                if (referer == null) return !references.isEmpty();\n                                for (FieldValue reference : references) {\n                                    if (referer.equals(reference.getDefiningInstance()))\n                                        return false;\n                                }\n                            } catch (InterruptedException e) {}\n                            return true;\n                        }\n                    };\n                    return new ProgressIterator(referencesIt, index, true, _progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.TruffleObjectPropertyProvider_IMoreNodes(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.TruffleObjectPropertyProvider_ISamplesContainer(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.TruffleObjectPropertyProvider_INodesContainer(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            \n            return computer.computeNodes(MergedObjectReferenceNode.this, heap, viewID, null, dataTypes, sortOrders, progress);\n        }\n        \n        protected Object getValue(DataType type, Heap heap) {\n            if (type == DataType.COUNT) return getCount();\n            \n            return super.getValue(type, heap);\n        }\n        \n    }\n    \n    \n    private static class MergedObjectReferenceNodeRenderer extends NormalBoldGrayRenderer implements HeapViewerRenderer {\n        \n        private HeapViewerRenderer renderer;\n\n        @Override\n        public void setValue(Object value, int row) {\n            TruffleObjectMergedReferences.MergedObjectReferenceNode vnode = (TruffleObjectMergedReferences.MergedObjectReferenceNode)value;\n            HeapViewerNode node = vnode.getNode();\n            renderer = RootNode.get(vnode).resolveRenderer(node);\n            renderer.setValue(node, row);\n            \n            if (node instanceof InstanceNode.IncludingNull) {\n                setNormalValue(Bundle.TruffleObjectMergedReferences_NoReferences());\n                setBoldValue(\"\"); // NOI18N\n                setGrayValue(\"\"); // NOI18N\n            } else if (renderer instanceof NormalBoldGrayRenderer) {\n                NormalBoldGrayRenderer r = (NormalBoldGrayRenderer)renderer;\n                setNormalValue(r.getNormalValue());\n                setBoldValue(r.getBoldValue());\n                setGrayValue(r.getGrayValue());\n            } else {\n                HeapViewerRenderer r = (HeapViewerRenderer)renderer;\n                setNormalValue(r.getShortName());\n                setBoldValue(\"\"); // NOI18N\n                setGrayValue(\"\"); // NOI18N\n            }\n            setIcon(Icons.getIcon(ProfilerIcons.NODE_FORWARD));\n        }\n\n        @Override\n        public int getHorizontalAlignment() {\n            return renderer.getHorizontalAlignment();\n        }\n        \n//        @Override\n//        public String toString() {\n//            return renderer.toString();\n//        }\n//\n//        @Override\n//        public String getShortName() {\n//            return renderer.getShortName();\n//        }\n//\n//        @Override\n//        public AccessibleContext getAccessibleContext() {\n//            return renderer.getAccessibleContext();\n//        }\n        \n    }\n    \n    \n    @ServiceProvider(service=HeapViewerRenderer.Provider.class)\n    public static class MergedReferencesNodeRendererProvider extends HeapViewerRenderer.Provider {\n\n        @Override\n        public boolean supportsView(HeapContext context, String viewID) {\n            return true;\n        }\n\n        @Override\n        public void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers, HeapContext context) {\n            renderers.put(TruffleObjectMergedReferences.MergedObjectReferenceNode.class, new MergedObjectReferenceNodeRenderer());\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleObjectPreviewPlugin.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewPlugin;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleObjectPreviewPlugin_Name=Preview\",\n    \"TruffleObjectPreviewPlugin_Description=Preview\",\n    \"TruffleObjectPreviewPlugin_NoDetails=<no details>\"\n})\npublic abstract class TruffleObjectPreviewPlugin extends HeapViewPlugin {\n    \n    private final Heap heap;\n    \n    private InstanceScrollPane component;\n    \n    \n    public TruffleObjectPreviewPlugin(HeapContext context) {\n        super(Bundle.TruffleObjectPreviewPlugin_Name(), Bundle.TruffleObjectPreviewPlugin_Description(), Icons.getIcon(HeapWalkerIcons.PROPERTIES));\n        heap = context.getFragment().getHeap();\n    }\n    \n    \n    protected abstract boolean supportsNode(HeapViewerNode node);\n    \n    protected abstract Instance getPreviewInstance(HeapViewerNode node);\n    \n    \n    @Override\n    protected void closed() {\n        // TODO: should cancel the preview\n    }\n    \n    @Override\n    protected void nodeSelected(HeapViewerNode node, boolean adjusting) {\n        component.showInstance(supportsNode(node) ? getPreviewInstance(node) : null);\n    }\n    \n    \n    @Override\n    protected JComponent createComponent() {\n        if (component == null) component = new InstanceScrollPane();\n        return component;\n    }\n    \n    \n    private static class InstanceScrollPane extends JScrollPane {\n        \n        private Instance selectedInstance = null;\n        private boolean instancePending = false;\n        \n        \n        InstanceScrollPane() {\n            setBorder(BorderFactory.createEmptyBorder());\n            setViewportBorder(BorderFactory.createEmptyBorder());\n//            setViewportBorder(BorderFactory.createLineBorder(\n//                    UIManager.getLookAndFeel().getID().equals(\"Metal\") ? // NOI18N\n//                    UIManager.getColor(\"Button.darkShadow\") : // NOI18N\n//                    UIManager.getColor(\"Button.shadow\"))); // NOI18N\n            \n            addHierarchyListener(new HierarchyListener() {\n                public void hierarchyChanged(HierarchyEvent e) {\n                    if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                        if (instancePending && isShowing()) showInstanceImpl();\n                    }\n                }\n            });\n            \n            showInstanceImpl();\n        }\n        \n        \n        void showInstance(Instance instance) {\n            if (selectedInstance == instance) return;\n            selectedInstance = instance;\n            if (isShowing()) showInstanceImpl();\n            else instancePending = true;\n        }\n        \n        private void showInstanceImpl() {\n            JComponent instanceView = selectedInstance == null ? null :\n                       DetailsSupport.getDetailsView(selectedInstance);\n            if (instanceView == null) {\n                JLabel noDetails = new JLabel(Bundle.TruffleObjectPreviewPlugin_NoDetails(), JLabel.CENTER);\n                noDetails.setEnabled(false);\n                \n                instanceView = new JPanel(new BorderLayout());\n                instanceView.setOpaque(true);\n                instanceView.setBackground(UIUtils.getProfilerResultsBackground());\n                instanceView.add(noDetails, BorderLayout.CENTER);\n            }\n            setViewportView(instanceView);\n            //doLayout();\n            instancePending = false;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleObjectPropertyPlugin.java",
    "content": "/*\n * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.awt.BorderLayout;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.truffle.swing.LinkButton;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleObjectPropertyPlugin_NoSelection=<no object selected>\",\n    \"TruffleObjectPropertyPlugin_NoSelectionEx=<no object or type selected>\",\n    \"TruffleObjectPropertyPlugin_NoItems=<no {0}>\", // <no items>\n    \"TruffleObjectPropertyPlugin_AutoShowMergedSwitch=Compute merged {0} automatically\",\n    \"TruffleObjectPropertyPlugin_ComputeMergedReferencesLbl=Compute Merged {0}\",\n    \"TruffleObjectPropertyPlugin_ComputeMergedReferencesTtp=Compute merged {0} for the selected type\",\n    \"TruffleObjectPropertyPlugin_AutoComputeMergedReferencesLbl=Compute Merged {0} Automatically\",\n    \"TruffleObjectPropertyPlugin_AutoComputeMergedReferencesTtp=Compute merged {0} automatically for each selected type\"\n})\npublic class TruffleObjectPropertyPlugin<O extends TruffleObject, T extends TruffleType<O>, F extends TruffleLanguageHeapFragment<O, T>, L extends TruffleLanguage<O, T, F>> extends HeapViewPlugin {\n    \n    private static final TreeTableView.ColumnConfiguration CCONF_TYPE = new TreeTableView.ColumnConfiguration(DataType.COUNT, null, DataType.COUNT, SortOrder.DESCENDING, Boolean.FALSE);\n    private static final TreeTableView.ColumnConfiguration CCONF_OBJECT = new TreeTableView.ColumnConfiguration(null, DataType.COUNT, DataType.NAME, SortOrder.UNSORTED, null);\n    \n    private final TruffleObjectPropertyProvider<O, T, F, L, ? extends Object> provider;\n    \n    private final Heap heap;\n    \n    private HeapViewerNode selected;\n    \n    private volatile boolean mergedRequest;\n    \n    private final TreeTableView objectsView;\n    \n    \n    public TruffleObjectPropertyPlugin(String name, String description, Icon icon, String viewID, HeapContext context, HeapViewerActions actions, TruffleObjectPropertyProvider<O, T, F, L, ? extends Object> provider) {\n        super(name, description, icon);\n        \n        this.provider = provider;\n        \n        final String mergedPropertiesKey = provider.getMergedPropertiesKey();\n        \n        heap = context.getFragment().getHeap();\n        \n        TreeTableViewColumn[] columns = mergedPropertiesKey == null ?\n            new TreeTableViewColumn[] {\n                new TreeTableViewColumn.Name(),\n                new TreeTableViewColumn.LogicalValue(),\n                new TreeTableViewColumn.OwnSize(heap, false, false),\n                new TreeTableViewColumn.RetainedSize(heap, false, false),\n                new TreeTableViewColumn.ObjectID()\n            } : new TreeTableViewColumn[] {\n                new TreeTableViewColumn.Name(),\n                new TreeTableViewColumn.LogicalValue(),\n                new TreeTableViewColumn.Count(heap, true, true),\n                new TreeTableViewColumn.OwnSize(heap, false, false),\n                new TreeTableViewColumn.RetainedSize(heap, false, false),\n                new TreeTableViewColumn.ObjectID()\n            };\n        objectsView = new TreeTableView(viewID, context, actions, columns) {\n            protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                if (mergedRequest) return HeapViewerNode.NO_NODES;\n                \n                HeapViewerNode _selected;\n                synchronized (objectsView) { _selected = selected; }\n                \n                if (_selected == null) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            if (!CCONF_OBJECT.equals(objectsView.getCurrentColumnConfiguration()))\n                                objectsView.configureColumns(CCONF_OBJECT);\n                        }\n                    });\n                    \n                    return new HeapViewerNode[] { new TextNode(noSelectionString()) };\n                }\n                \n                HeapViewerNode[] nodes;\n                TruffleObjectsWrapper wrapper = mergedPropertiesKey == null ? null : HeapViewerNode.getValue(_selected, TruffleObjectsWrapper.DATA_TYPE, heap);\n                if (wrapper != null) {\n                    nodes = provider.getNodes(wrapper, _selected, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            if (!CCONF_TYPE.equals(objectsView.getCurrentColumnConfiguration()))\n                                objectsView.configureColumns(CCONF_TYPE);\n                        }\n                    });\n                } else {\n                    O selectedO = provider.getObject(_selected, heap);\n                    if (selectedO != null) nodes = provider.getNodes(selectedO, root, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n                    else nodes = new HeapViewerNode[] { new TextNode(noSelectionString()) };\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            if (!CCONF_OBJECT.equals(objectsView.getCurrentColumnConfiguration()))\n                                objectsView.configureColumns(CCONF_OBJECT);\n                        }\n                    });\n                }\n                    \n                return nodes == null || nodes.length == 0 ? new HeapViewerNode[] { new TextNode(Bundle.TruffleObjectPropertyPlugin_NoItems(provider.getName())) } : nodes;\n            }\n            @Override\n            protected void populatePopup(HeapViewerNode node, JPopupMenu popup) {\n                if (provider.getMergedPropertiesKey() == null) return;\n                \n                if (popup.getComponentCount() > 0) popup.addSeparator();\n                \n                popup.add(new JCheckBoxMenuItem(Bundle.TruffleObjectPropertyPlugin_AutoShowMergedSwitch(provider.getName()), isAutoMerge()) {\n                    @Override\n                    protected void fireActionPerformed(ActionEvent event) {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            @Override\n                            public void run() {\n                                setAutoMerge(isSelected());\n                            }\n                        });\n                    }\n                });\n            }\n        };\n    }\n    \n    private String noSelectionString() {\n        return provider.getMergedPropertiesKey() == null ? Bundle.TruffleObjectPropertyPlugin_NoSelection() :\n                                                           Bundle.TruffleObjectPropertyPlugin_NoSelectionEx();\n    }\n    \n    private JComponent component;\n    \n    private void showObjectsView() {\n        JComponent c = objectsView.getComponent();\n        if (c.isVisible()) return;\n        \n        c.setVisible(true);\n        \n        component.removeAll();\n        component.add(c, BorderLayout.CENTER);\n        \n        mergedRequest = false;\n        \n        component.invalidate();\n        component.revalidate();\n        component.repaint();\n    }\n    \n    private void showMergedView() {\n        JComponent c = objectsView.getComponent();\n        if (!c.isVisible()) return;\n        \n        c.setVisible(false);\n        \n        component.removeAll();\n        \n        String name = provider.getName();\n        String _name = name.substring(0, 1).toUpperCase() + name.substring(1);\n        \n        JButton jb = new JButton(Bundle.TruffleObjectPropertyPlugin_ComputeMergedReferencesLbl(_name), getIcon()) {\n            protected void fireActionPerformed(ActionEvent e) {\n                showObjectsView();\n                objectsView.reloadView();\n            }\n        };\n        jb.setIconTextGap(jb.getIconTextGap() + 2);\n        jb.setToolTipText(Bundle.TruffleObjectPropertyPlugin_ComputeMergedReferencesTtp(name));\n        Insets margin = jb.getMargin();\n        if (margin != null) jb.setMargin(new Insets(margin.top + 3, margin.left + 3, margin.bottom + 3, margin.right + 3));\n        \n        \n        LinkButton lb = new LinkButton(Bundle.TruffleObjectPropertyPlugin_AutoComputeMergedReferencesLbl(_name)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                setAutoMerge(true);\n                showObjectsView();\n                objectsView.reloadView();\n            }\n        };\n        lb.setToolTipText(Bundle.TruffleObjectPropertyPlugin_AutoComputeMergedReferencesTtp(name));\n                \n        \n        JPanel p = new JPanel(new GridBagLayout());\n        p.setOpaque(false);\n        GridBagConstraints g;\n        \n        g = new GridBagConstraints();\n        g.fill = GridBagConstraints.HORIZONTAL;\n        g.gridy = 0;\n        p.add(jb, g);\n        \n        g = new GridBagConstraints();\n        g.fill = GridBagConstraints.HORIZONTAL;\n        g.gridy = 1;\n        g.insets = new Insets(10, 0, 0, 0);\n        p.add(lb, g);\n        \n        component.add(p);\n        \n        mergedRequest = true;\n\n        component.invalidate();\n        component.revalidate();\n        component.repaint();\n    }\n\n    protected JComponent createComponent() {\n        component = new JPanel(new BorderLayout());\n        component.setOpaque(true);\n        component.setBackground(UIUtils.getProfilerResultsBackground());\n        \n        objectsView.getComponent().setVisible(false); // force init in showObjectsView()\n        showObjectsView();\n        \n        return component;\n    }\n    \n    \n    @Override\n    protected void closed() {\n        synchronized (objectsView) { selected = objectsView.getRoot(); }\n        objectsView.closed();\n    }\n    \n    \n    protected void nodeSelected(HeapViewerNode node, boolean adjusting) {\n        synchronized (objectsView) {\n            if (Objects.equals(selected, node)) return;\n            selected = node;\n        }\n        \n        if (selected != null && provider.getMergedPropertiesKey() != null && !isAutoMerge() && HeapViewerNode.getValue(selected, TruffleObjectsWrapper.DATA_TYPE, heap) != null) showMergedView();\n        else showObjectsView();\n        \n        objectsView.reloadView();\n    }\n    \n    \n    private boolean isAutoMerge() {\n        return NbPreferences.root().getBoolean(provider.getMergedPropertiesKey(), false);\n    }\n\n    private void setAutoMerge(boolean value) {\n        NbPreferences.root().putBoolean(provider.getMergedPropertiesKey(), value);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleObjectPropertyProvider.java",
    "content": "/*\n * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.java.PrimitiveNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectFieldNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectReferenceNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TerminalJavaNodes;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.HeapOperations;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.HeapProgress;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleObjectPropertyProvider_ComputingNodes=<computing {0}...>\", // <computing items...>\n    \"TruffleObjectPropertyProvider_MoreNodes=<another {0} {1} left>\", // <another 1234 items left>\n    \"TruffleObjectPropertyProvider_SamplesContainer=<sample {0} {1}>\", // <sample 1234 items>\n    \"TruffleObjectPropertyProvider_NodesContainer=<{2} {0}-{1}>\", // <items 1001 - 2000>\n    \"TruffleObjectPropertyProvider_IMoreNodes=<another {0} objects left>\",\n    \"TruffleObjectPropertyProvider_ISamplesContainer=<sample {0} objects>\",\n    \"TruffleObjectPropertyProvider_INodesContainer=<objects {0}-{1}>\",\n    \"TruffleObjectPropertyProvider_ValuesCountHint=({0} values)\",\n    \"TruffleObjectPropertyProvider_FieldHistogramMoreNodes=<another {0} values left>\",\n    \"TruffleObjectPropertyProvider_FieldHistogramSamplesContainer=<sample {0} values>\",\n    \"TruffleObjectPropertyProvider_FieldHistogramNodesContainer=<values {0}-{1}>\"\n})\npublic abstract class TruffleObjectPropertyProvider<O extends TruffleObject, T extends TruffleType<O>, F extends TruffleLanguageHeapFragment<O, T>, L extends TruffleLanguage<O, T, F>, I> extends HeapViewerNode.Provider {\n    \n    private final Class<O> objectClass;\n    \n    private final L language;\n    \n    private final String propertyName;\n    private final int maxPropertyItems;\n    \n    private final boolean displaysProgress;\n    private final boolean filtersProperties;\n    \n    \n    protected TruffleObjectPropertyProvider(String propertyName, L language, boolean displaysProgress, boolean filtersProperties, int maxPropertyItems) {\n        this.language = language;\n        this.objectClass = language.getLanguageObjectClass();\n        this.propertyName = propertyName;\n        this.maxPropertyItems = maxPropertyItems;\n        this.displaysProgress = displaysProgress;\n        this.filtersProperties = filtersProperties;\n    }\n    \n\n    @Override\n    public String getName() {\n        return propertyName;\n    }\n    \n    \n    protected final L getLanguage() {\n        return language;\n    }\n\n    \n    @Override\n    public abstract boolean supportsView(Heap heap, String viewID);\n\n    @Override\n    public abstract boolean supportsNode(HeapViewerNode node, Heap heap, String viewID);\n    \n    \n    protected abstract Collection<I> getPropertyItems(O object) throws InterruptedException;\n    \n    protected boolean includeItem(I item) { return true; }\n    \n    protected abstract HeapViewerNode createNode(I item, Heap heap);\n    \n    \n    protected String getMergedPropertiesKey() { return null; }\n    \n    \n    protected final boolean filtersProperties() { return filtersProperties; }\n    \n    protected final String moreNodesString(String moreNodesCount) { return Bundle.TruffleObjectPropertyProvider_MoreNodes(moreNodesCount, propertyName); }\n    protected final String samplesContainerString(String objectsCount) { return Bundle.TruffleObjectPropertyProvider_SamplesContainer(objectsCount, propertyName); }\n    protected final String nodesContainerString(String firstNodeIdx, String lastNodeIdx) { return Bundle.TruffleObjectPropertyProvider_NodesContainer(firstNodeIdx, lastNodeIdx, propertyName); }\n\n    \n    @Override\n    public final HeapViewerNode[] getNodes(HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        O object = getObject(parent, heap);\n        return object == null ? null : getNodes(object, parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n    }\n    \n    final HeapViewerNode[] getNodes(O object, HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        Collection<I> itemsC = null;\n        \n        if (!displaysProgress) {\n            itemsC = getPropertyItems(object);\n        } else {\n            HeapOperations.OpProgressHandle pHandle = new HeapOperations.OpProgressHandle(Bundle.TruffleObjectPropertyProvider_ComputingNodes(propertyName));\n            pHandle.setInitialDelay(1000);\n            pHandle.start(HeapProgress.PROGRESS_MAX);\n            pHandle.setProgress(0);\n\n            try { itemsC = getPropertyItems(object); }\n            finally { pHandle.finish(); }\n        }\n        \n        if (itemsC == null) return null;\n        \n        final List<I> items = new ArrayList(itemsC);\n        \n        if (filtersProperties) {\n            Iterator<I> itemsIt = items.iterator();\n            while (itemsIt.hasNext()) if (!includeItem(itemsIt.next())) itemsIt.remove();\n        }\n        \n        NodesComputer<Integer> computer = new NodesComputer<Integer>(items.size(), maxPropertyItems) {\n            protected boolean sorts(DataType dataType) {\n                return !DataType.COUNT.equals(dataType);\n            }\n            protected HeapViewerNode createNode(Integer index) {\n                return TruffleObjectPropertyProvider.this.createNode(items.get(index), heap);\n            }\n            protected ProgressIterator<Integer> objectsIterator(int index, Progress progress) {\n                Iterator<Integer> iterator = integerIterator(index, items.size());\n                return new ProgressIterator(iterator, index, false, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  { return moreNodesString(moreNodesCount); }\n            protected String getSamplesContainerString(String objectsCount)  { return samplesContainerString(objectsCount); }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  { return nodesContainerString(firstNodeIdx, lastNodeIdx); }\n        };\n\n        return computer.computeNodes(parent, heap, viewID, null, dataTypes, sortOrders, progress);\n    }\n    \n    protected HeapViewerNode[] getNodes(TruffleObjectsWrapper<O> objects, HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        return null;\n    }\n    \n    final O getObject(HeapViewerNode node, Heap heap) {\n        if (node == null) return null;\n            \n        TruffleObject object = HeapViewerNode.getValue(node, TruffleObject.DATA_TYPE, heap);\n        if (object == null || !objectClass.isInstance(object)) return null;\n        \n        return (O)object;\n    }\n    \n    \n    public static abstract class Fields<O extends TruffleObject, T extends TruffleType<O>, F extends TruffleLanguageHeapFragment<O, T>, L extends TruffleLanguage<O, T, F>> extends TruffleObjectPropertyProvider<O, T, F, L, FieldValue> {\n        \n        protected Fields(String propertyName, L language, boolean filtersProperties) {\n            super(propertyName, language, false, filtersProperties, UIThresholds.MAX_INSTANCE_FIELDS);\n        }\n        \n        \n//        protected abstract boolean isLanguageObject(Instance instance);\n//        \n//        protected abstract O createObject(Instance instance);\n    \n        protected abstract HeapViewerNode createObjectFieldNode(O object, String type, FieldValue field);\n        \n        \n        @Override\n        protected boolean includeItem(FieldValue field) {\n            // display primitive fields\n            if (!(field instanceof ObjectFieldValue)) return true;\n\n            Instance instance = ((ObjectFieldValue)field).getInstance();\n\n            // display null fields\n            if (instance == null) return true;\n            \n            // display primitive arrays\n            if (instance instanceof PrimitiveArrayInstance) return true;\n            \n            // display language objects\n            if (getLanguage().isLanguageObject(instance)) return true;\n\n            // display DynamicObject fields\n            if (DynamicObject.isDynamicObject(instance)) return true;\n\n            // display selected Java fields\n            return includeInstance(instance);\n        }\n        \n        protected boolean includeInstance(Instance instance) { return true; }\n        \n        @Override\n        protected final HeapViewerNode createNode(FieldValue field, Heap heap) {\n            if (field instanceof ObjectFieldValue) {\n                Instance instance = ((ObjectFieldValue)field).getInstance();\n                if (getLanguage().isLanguageObject(instance)) {\n                    O object = getLanguage().createObject(instance);\n                    return createObjectFieldNode(object, object.getType(), field);\n                } else {\n                    return createForeignFieldNode(instance, field, heap);\n                }\n            } else {\n                return new PrimitiveNode.Field(field);\n            }\n        }\n        \n        protected HeapViewerNode createForeignFieldNode(Instance instance, FieldValue field, Heap heap) {\n            if (DynamicObject.isDynamicObject(instance)) {\n                DynamicObject dobj = new DynamicObject(instance);\n                return new DynamicObjectFieldNode(dobj, dobj.getType(), field);\n            } else {\n                return new TerminalJavaNodes.Field((ObjectFieldValue)field, false);\n            }\n        }\n        \n        \n        @Override\n        protected String getMergedPropertiesKey() {\n            return \"HeapViewer.autoMergedFields\"; // NOI18N\n        }\n        \n        \n        @Override\n        protected HeapViewerNode[] getNodes(TruffleObjectsWrapper<O> objects, HeapViewerNode parent, final Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            if (getMergedPropertiesKey() == null) return null;\n            \n            return new TruffleObjectMergedFields<O>(objects, heap) {\n                protected String getMoreNodesString(String moreNodesCount) { return moreNodesString(moreNodesCount); }\n                protected String getSamplesContainerString(String objectsCount) { return samplesContainerString(objectsCount); }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx) { return nodesContainerString(firstNodeIdx, lastNodeIdx); }\n                protected TruffleLanguage getLanguage() { return Fields.this.getLanguage(); }\n                protected boolean filtersFields() { return filtersProperties(); }\n                protected boolean includeField(FieldValue field) { return includeItem(field); }\n                protected Collection<FieldValue> getFields(O object) throws InterruptedException { return getPropertyItems(object); }\n            }.getNodes(parent, viewID, viewFilter, dataTypes, sortOrders, progress);\n        }\n        \n    }\n    \n    \n    public static abstract class References<O extends TruffleObject, T extends TruffleType<O>, F extends TruffleLanguageHeapFragment<O, T>, L extends TruffleLanguage<O, T, F>> extends TruffleObjectPropertyProvider<O, T, F, L, FieldValue> {\n        \n        protected References(String propertyName, L language, boolean filtersProperties) {\n            super(propertyName, language, false, filtersProperties, UIThresholds.MAX_INSTANCE_REFERENCES);\n        }\n        \n        \n        protected abstract HeapViewerNode createObjectReferenceNode(O object, String type, FieldValue field);\n        \n        \n        @Override\n        protected boolean includeItem(FieldValue field) {\n            Instance instance = field.getDefiningInstance();\n\n            // should not happen\n            if (instance == null) return false;\n            \n            // display language references\n            if (getLanguage().isLanguageObject(instance)) return true;\n\n            // display DynamicObject references\n            if (DynamicObject.isDynamicObject(instance)) return true;\n\n            // display selected Java references\n            return includeInstance(instance);\n        }\n        \n        protected boolean includeInstance(Instance instance) { return true; }\n        \n        @Override\n        protected final HeapViewerNode createNode(FieldValue field, Heap heap) {\n            Instance instance = field.getDefiningInstance();\n            if (getLanguage().isLanguageObject(instance)) {\n                O object = getLanguage().createObject(instance);\n                return createObjectReferenceNode(object, object.getType(), field);\n            } else {\n                return createForeignReferenceNode(instance, field, heap);\n            }\n        }\n        \n        protected HeapViewerNode createForeignReferenceNode(Instance instance, FieldValue field, Heap heap) {\n            if (DynamicObject.isDynamicObject(instance)) {\n                DynamicObject dobj = new DynamicObject(instance);\n                return new DynamicObjectReferenceNode(dobj, dobj.getType(), field);\n            } else {\n                return new TerminalJavaNodes.Field((ObjectFieldValue)field, true);\n            }\n        }\n        \n        \n        @Override\n        protected String getMergedPropertiesKey() {\n            return \"HeapViewer.autoMergedReferences\"; // NOI18N // Shared with org.graalvm.visualvm.heapviewer.java.impl.JavaReferencesPlugin\n        }\n        \n        \n        @Override\n        protected HeapViewerNode[] getNodes(final TruffleObjectsWrapper<O> objects, HeapViewerNode parent, final Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n            if (getMergedPropertiesKey() == null) return null;\n            \n            return new TruffleObjectMergedReferences<O>(objects, heap) {\n                protected String getMoreNodesString(String moreNodesCount) { return moreNodesString(moreNodesCount); }\n                protected String getSamplesContainerString(String objectsCount) { return samplesContainerString(objectsCount); }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx) { return nodesContainerString(firstNodeIdx, lastNodeIdx); }\n                protected TruffleLanguage getLanguage() { return References.this.getLanguage(); }\n                protected boolean filtersReferences() { return filtersProperties(); }\n                protected boolean includeReference(FieldValue field) { return includeItem(field); }\n                protected Collection<FieldValue> getReferences(O object) throws InterruptedException { return getPropertyItems(object); }\n                protected HeapViewerNode createForeignReferenceNode(Instance instance, FieldValue field) { return References.this.createForeignReferenceNode(instance, field, heap); }\n            }.getNodes(parent, viewID, viewFilter, dataTypes, sortOrders, progress);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleObjectsProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.stream.Collectors;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.GCRoot;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleObjectsProvider_MoreNodesObjects=<another {0} objects left>\",\n    \"TruffleObjectsProvider_SamplesContainerObjects=<sample {0} objects>\",\n    \"TruffleObjectsProvider_NodesContainerObjects=<objects {0}-{1}>\",\n    \"TruffleObjectsProvider_NoObjects=<no objects found>\",\n    \"TruffleObjectsProvider_MoreNodesTypes=<another {0} types left>\",\n    \"TruffleObjectsProvider_SamplesContainerTypes=<sample {0} types>\",\n    \"TruffleObjectsProvider_NodesContainerTypes=<types {0}-{1}>\",\n    \"TruffleObjectsProvider_NoRetainedSizes=<retained sizes not computed yet>\",\n    \"TruffleObjectsProvider_MoreNodesDominators=<another {0} dominators left>\",\n    \"TruffleObjectsProvider_SamplesContainerDominators=<sample {0} dominators>\",\n    \"TruffleObjectsProvider_NodesContainerDominators=<dominators {0}-{1}>\",\n    \"TruffleObjectsProvider_NoDominators=<no dominators found>\",\n    \"TruffleObjectsProvider_MoreNodesGcRoots=<another {0} GC roots left>\",\n    \"TruffleObjectsProvider_SamplesContainerGcRoots=<sample {0} GC roots>\",\n    \"TruffleObjectsProvider_NodesContainerGcRoots=<GC roots {0}-{1}>\",\n    \"TruffleObjectsProvider_NoGcRoots=<no GC roots found>\"\n})\npublic class TruffleObjectsProvider<O extends TruffleObject, T extends TruffleType<O>, F extends TruffleLanguageHeapFragment<O, T>, L extends TruffleLanguage<O, T, F>> {\n    \n    private final L language;\n    \n    \n    public TruffleObjectsProvider(L language) {\n        this.language = language;\n    }\n    \n    \n    public HeapViewerNode[] getAllObjects(HeapViewerNode parent, HeapContext context, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress, int aggregation) throws InterruptedException {\n        final TruffleLanguageHeapFragment fragment = (TruffleLanguageHeapFragment)context.getFragment();\n        final Heap heap = fragment.getHeap();\n        \n        HeapViewerNode[] nodes;\n        if (aggregation == 0) {\n            NodesComputer<O> computer = new NodesComputer<O>(UIThresholds.MAX_TOPLEVEL_INSTANCES) {\n                protected boolean sorts(DataType dataType) {\n                    return !DataType.COUNT.equals(dataType);\n                }\n                protected HeapViewerNode createNode(O object) {\n                    return (HeapViewerNode)language.createObjectNode(object, object.getType());\n                }\n                protected ProgressIterator<O> objectsIterator(int index, Progress progress) {\n                    Iterator<O> objects = fragment.getObjectsIterator();\n                    return new ProgressIterator(objects, index, true, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.TruffleObjectsProvider_MoreNodesObjects(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.TruffleObjectsProvider_SamplesContainerObjects(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.TruffleObjectsProvider_NodesContainerObjects(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            \n            nodes = computer.computeNodes(parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n        } else {\n            NodesComputer<T> computer = new NodesComputer<T>(UIThresholds.MAX_TOPLEVEL_CLASSES) {\n                protected boolean sorts(DataType dataType) {\n                    return true;\n                }\n                protected HeapViewerNode createNode(T type) {\n                    return language.createTypeNode(type, heap);\n                }\n                protected ProgressIterator<T> objectsIterator(int index, Progress progress) {\n                    List<T> types = fragment.getTypes(progress);\n                    Iterator<T> typesI = types.listIterator(index);\n                    return new ProgressIterator(typesI, index, false, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.TruffleObjectsProvider_MoreNodesTypes(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.TruffleObjectsProvider_SamplesContainerTypes(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.TruffleObjectsProvider_NodesContainerTypes(firstNodeIdx, lastNodeIdx);\n                }\n            };\n\n            nodes = computer.computeNodes(parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n        }\n        \n        return nodes == null || nodes.length > 0 ? nodes : new HeapViewerNode[] { new TextNode(Bundle.TruffleObjectsProvider_NoObjects()) };\n    }\n    \n    public HeapViewerNode[] getDominators(HeapViewerNode parent, HeapContext context, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress, int aggregation) throws InterruptedException {\n        final Heap heap = context.getFragment().getHeap();\n        \n        if (!DataType.RETAINED_SIZE.valuesAvailable(heap))\n            return new HeapViewerNode[] { new TextNode(Bundle.TruffleObjectsProvider_NoRetainedSizes()) };\n        \n        int maxSearchInstances = 10000;\n        \n        List<Instance> searchInstances = heap.getBiggestObjectsByRetainedSize(maxSearchInstances);\n        Iterator<Instance> searchInstancesIt = searchInstances.iterator();\n        \n        try {\n            progress.setupKnownSteps(searchInstances.size());\n            \n            while (searchInstancesIt.hasNext()) {\n                Instance instance = searchInstancesIt.next();\n                progress.step();\n                if (!language.isLanguageObject(instance)) searchInstancesIt.remove();\n            }\n        } finally {\n            progress.finish();\n        }\n        \n        final List<Instance> dominators = new ArrayList(getDominatorRoots(searchInstances));\n        \n        HeapViewerNode[] nodes;\n        if (aggregation == 0) {\n            NodesComputer<Instance> computer = new NodesComputer<Instance>(UIThresholds.MAX_TOPLEVEL_INSTANCES) {\n                protected boolean sorts(DataType dataType) {\n                    return !DataType.COUNT.equals(dataType);\n                }\n                protected HeapViewerNode createNode(Instance instance) {\n                    O object = language.createObject(instance);\n                    return (HeapViewerNode)language.createObjectNode(object, object.getType());\n                }\n                protected ProgressIterator<Instance> objectsIterator(int index, Progress progress) {\n                    Iterator<Instance> dominatorsIt = dominators.listIterator(index);\n                    return new ProgressIterator(dominatorsIt, index, false, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.TruffleObjectsProvider_MoreNodesDominators(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.TruffleObjectsProvider_SamplesContainerDominators(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.TruffleObjectsProvider_NodesContainerDominators(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            \n            nodes = computer.computeNodes(parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n        } else {\n            TruffleType.TypesComputer<O, T> tcomputer = new TruffleType.TypesComputer(language, heap);\n            \n            try {\n                progress.setupKnownSteps(dominators.size());\n                \n                for (Instance dominator : dominators) {\n                    progress.step();\n                    tcomputer.addObject(language.createObject(dominator));\n                }\n            } finally {\n                progress.finish();\n            }\n            \n            final List<T> types = tcomputer.getTypes();\n            \n            NodesComputer<T> computer = new NodesComputer<T>(UIThresholds.MAX_TOPLEVEL_INSTANCES) {\n                protected boolean sorts(DataType dataType) {\n                    return true;\n                }\n                protected HeapViewerNode createNode(T type) {\n                    return language.createTypeNode(type, heap);\n                }\n                protected ProgressIterator<T> objectsIterator(int index, Progress progress) {\n                    Iterator<T> typesIt = types.listIterator(index);\n                    return new ProgressIterator(typesIt, index, false, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.TruffleObjectsProvider_MoreNodesDominators(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.TruffleObjectsProvider_SamplesContainerDominators(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.TruffleObjectsProvider_NodesContainerDominators(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            \n            nodes = computer.computeNodes(parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n        }\n        \n        return nodes.length > 0 ? nodes : new HeapViewerNode[] { new TextNode(Bundle.TruffleObjectsProvider_NoDominators()) };\n    }\n    \n    public HeapViewerNode[] getGCRoots(HeapViewerNode parent, HeapContext context, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress, int aggregation) throws InterruptedException {\n        final Heap heap = context.getFragment().getHeap();\n        final Collection<GCRoot> gcroots = heap.getGCRoots();\n        final List<Instance> gcrootInstances = gcroots.stream()\n                .map(GCRoot::getInstance)\n                .distinct()\n                .collect(Collectors.toList());\n        try {\n            progress.setupUnknownSteps();\n            \n            Iterator<Instance> gcrootsI = gcrootInstances.iterator();\n            while (gcrootsI.hasNext()) {\n                Instance instance = gcrootsI.next();\n                if (!language.isLanguageObject(instance)) gcrootsI.remove();\n                progress.step();\n            }\n        } finally {\n            progress.finish();\n        }\n        \n        HeapViewerNode[] nodes;\n        if (aggregation == 0) {\n            NodesComputer<Instance> computer = new NodesComputer<Instance>(UIThresholds.MAX_TOPLEVEL_INSTANCES) {\n                protected boolean sorts(DataType dataType) {\n                    return !DataType.COUNT.equals(dataType);\n                }\n                protected HeapViewerNode createNode(Instance gcRootInstance) {\n                    O object = language.createObject(gcRootInstance);\n                    return (HeapViewerNode)language.createObjectNode(object, object.getType());\n                }\n                protected ProgressIterator<Instance> objectsIterator(int index, Progress progress) {\n                    Iterator<Instance> iterator = gcrootInstances.listIterator(index);\n                    return new ProgressIterator(iterator, index, false, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.TruffleObjectsProvider_MoreNodesGcRoots(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.TruffleObjectsProvider_SamplesContainerGcRoots(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.TruffleObjectsProvider_NodesContainerGcRoots(firstNodeIdx, lastNodeIdx);\n                }\n            };\n\n            nodes = computer.computeNodes(parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n        } else {\n            TruffleType.TypesComputer<O, T> tcomputer = new TruffleType.TypesComputer(language, heap);\n            \n            try {            \n                progress.setupUnknownSteps();\n                \n                for (Instance gcroot : gcrootInstances) {\n                    tcomputer.addObject(language.createObject(gcroot));\n                    progress.step();\n                }\n            } finally {\n                progress.finish();\n            }\n            \n            final List<T> types = tcomputer.getTypes();\n            \n            NodesComputer<T> computer = new NodesComputer<T>(UIThresholds.MAX_TOPLEVEL_INSTANCES) {\n                protected boolean sorts(DataType dataType) {\n                    return true;\n                }\n                protected HeapViewerNode createNode(T type) {\n                    return language.createTypeNode(type, heap);\n                }\n                protected ProgressIterator<T> objectsIterator(int index, Progress progress) {\n                    Iterator<T> typesIt = types.listIterator(index);\n                    return new ProgressIterator(typesIt, index, false, progress);\n                }\n                protected String getMoreNodesString(String moreNodesCount)  {\n                    return Bundle.TruffleObjectsProvider_MoreNodesGcRoots(moreNodesCount);\n                }\n                protected String getSamplesContainerString(String objectsCount)  {\n                    return Bundle.TruffleObjectsProvider_SamplesContainerGcRoots(objectsCount);\n                }\n                protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                    return Bundle.TruffleObjectsProvider_NodesContainerGcRoots(firstNodeIdx, lastNodeIdx);\n                }\n            };\n            \n            nodes = computer.computeNodes(parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n        }\n        \n        return nodes.length > 0 ? nodes : new HeapViewerNode[] { new TextNode(Bundle.TruffleObjectsProvider_NoGcRoots()) };\n    }\n    \n    \n    public static Set<Instance> getDominatorRoots(List<Instance> searchInstances) {\n        Set<Instance> dominators = new HashSet(searchInstances);\n        Set<Instance> removed = new HashSet<>();\n\n        for (Instance instance : searchInstances) {\n            if (dominators.contains(instance)) {\n                Instance dom = instance;\n                long retainedSize = instance.getRetainedSize();\n\n                while (!instance.isGCRoot()) {\n                    instance = instance.getNearestGCRootPointer();\n                    if (dominators.contains(instance) && instance.getRetainedSize()>=retainedSize) {\n                        dominators.remove(dom);\n                        removed.add(dom);\n                        dom = instance;\n                        retainedSize = instance.getRetainedSize();\n                    }\n                    if (removed.contains(instance)) {\n                        dominators.remove(dom);\n                        removed.add(dom);\n                        break;\n                    }\n                }\n            }\n        }\n        \n        return dominators;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleObjectsWrapper.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.util.Iterator;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class TruffleObjectsWrapper<O extends TruffleObject> {\n    \n    public static final DataType<TruffleObjectsWrapper> DATA_TYPE = new DataType<>(TruffleObjectsWrapper.class, null, null);\n    \n    \n    public abstract String getType();\n    \n    public abstract int getObjectsCount();\n    \n    public abstract Iterator<O> getObjectsIterator();\n    \n    \n    public static abstract class Simple<O extends TruffleObject> extends TruffleObjectsWrapper<O> {\n        \n        private final String type;\n        \n        private final int objectsCount;\n        \n        \n        public Simple(String type, int objectsCount) {\n            this.type = type;\n            this.objectsCount = objectsCount;\n        }\n        \n        \n        @Override\n        public final String getType() {\n            return type;\n        }\n        \n        @Override\n        public final int getObjectsCount() {\n            return objectsCount;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleStackTraces.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.GCRoot;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaFrameGCRoot;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ThreadObjectGCRoot;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class TruffleStackTraces {\n\n    private Collection<StackTrace> truffleStackTraces;\n\n    public TruffleStackTraces(Heap heap) {\n        DefaultTruffleRuntime defaultImpl = new DefaultTruffleRuntime(heap);\n\n        if (defaultImpl.isDefaultTruffleRuntime()) {\n            truffleStackTraces = defaultImpl.getStackTraces();\n        }\n\n        HotSpotTruffleRuntime hotSpotImpl = new HotSpotTruffleRuntime(heap);\n\n        if (hotSpotImpl.isHotSpotTruffleRuntime()) {\n            truffleStackTraces = hotSpotImpl.getStackTraces();\n        }\n    }\n\n    public Collection<StackTrace> getStackTraces() {\n        return truffleStackTraces;\n    }\n\n    public abstract static class StackTrace {\n\n        private final Instance thread;\n        private StackTrace(Instance t) {\n            thread = t;\n        }\n\n        public Instance getThread() {\n            return thread;\n        }\n\n        public abstract List<Frame> getFrames();\n    }\n\n    public static class Frame {\n\n        private final String name;\n        private final List<FieldValue> fieldValues;\n\n        private Frame(Instance callTarget, TruffleFrame localFrame) {\n            name = getFrameName(callTarget);\n            fieldValues = localFrame.getFieldValues();\n        }\n\n        private Frame(Instance callTarget, Instance localFrame) {\n            name = getFrameName(callTarget);\n            fieldValues = new TruffleFrame(localFrame).getFieldValues();\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public List<FieldValue> getFieldValues() {\n            return fieldValues;\n        }\n\n        private static String getFrameName(Instance callTarget) {\n            Instance rootNode = (Instance) callTarget.getValueOfField(\"rootNode\"); // NOI18N\n\n            if (rootNode != null) {\n                String name = DetailsUtils.getInstanceString(rootNode);\n                Instance sourceSection = getSourceSection(rootNode);\n                if (sourceSection != null) {\n                    Instance source = (Instance) sourceSection.getValueOfField(\"source\"); // NOI18N\n                    if (source != null) {\n                        String fileName = getFileName(source);\n                        return name+\" (\"+fileName+\":\"+getLineNumber(sourceSection, source)+\")\"; // NOI18N\n                    }\n                }\n                return name;\n            }\n            return DetailsUtils.getInstanceString(callTarget);\n        }\n    }\n\n    private static String getFileName(Instance source) {\n        Object key = source.getValueOfField(\"key\"); // NOI18N\n        if (key instanceof Instance) {\n            source = (Instance) key;\n        }\n        String fileName = DetailsUtils.getInstanceFieldString(source, \"name\"); // NOI18N\n        int slash = fileName.lastIndexOf('/'); // NOI18N\n\n        if (slash != -1) {\n            fileName = fileName.substring(slash+1);\n        }\n        return fileName;\n    }\n\n    private static Instance getSourceSection(Instance rootNode) {\n        if (rootNode == null) return null;\n        for (FieldValue fieldVal : rootNode.getFieldValues()) {\n\n            if (\"sourceSection\".equals(fieldVal.getField().getName())) { // NOI18N\n                Instance sc = ((ObjectFieldValue)fieldVal).getInstance();\n\n                if (sc != null) {\n                    return sc;\n                }\n            }\n        }\n        return null;\n    }\n\n    private static String getLineNumber(Instance sourceSection, Instance source) {\n        Integer charIndex = (Integer) sourceSection.getValueOfField(\"charIndex\"); // NOI18N\n        Instance textmap = (Instance) source.getValueOfField(\"textMap\"); // NOI18N\n        if (textmap != null) {\n            PrimitiveArrayInstance nlOffsets = (PrimitiveArrayInstance) textmap.getValueOfField(\"nlOffsets\"); // NOI18N\n            List<String> vals = nlOffsets.getValues();\n\n            for (int i=0; i<vals.size(); i++) {\n                Integer off = Integer.valueOf(vals.get(i));\n\n                if (off>=charIndex) {\n                    return String.valueOf(i);\n                }\n            }\n            return String.valueOf(vals.size());\n        }\n        return \"1\"; // NOI18N\n    }\n\n    private static Instance getSingleton(Heap heap, String... fqns) {\n        for (String fqn : fqns) {\n            Instance i = getSingleton(heap, fqn);\n\n            if (i != null) return i;\n        }\n        return null;\n    }\n\n    private static Instance getSingleton(Heap heap, String javaClass) {\n        JavaClass jcls = heap.getJavaClassByName(javaClass);\n\n        if (jcls != null) {\n            Collection<JavaClass> subClasses = jcls.getSubClasses();\n            subClasses.add(jcls);\n\n            for (JavaClass jc : subClasses) {\n                List<Instance> instances = jc.getInstances();\n\n                if (instances.size() == 1) {\n                    return instances.get(0);\n                }\n            }\n        }\n        return null;\n    }\n\n    private static JavaClass getJavaClass(Heap heap, String... fqns) {\n        for (String fqn : fqns) {\n            JavaClass jcls = heap.getJavaClassByName(fqn);\n\n            if (jcls != null) return jcls;\n        }\n        return null;\n    }\n\n    // implementation for DefaultTruffleRuntime\n    private static class DefaultTruffleRuntime {\n\n        private static final String TRUFFLE_RUNTIME_FQN = \"com.oracle.truffle.api.impl.DefaultTruffleRuntime\"; // NOI18N\n        private static final String THREAD_FQN = \"java.lang.Thread\"; // NOI18N\n\n        private Collection<StackTrace> truffleStackTraces;\n\n        private DefaultTruffleRuntime(Heap heap) {\n            Instance runtime = getSingleton(heap, TRUFFLE_RUNTIME_FQN);\n\n            if (runtime != null) {\n                Instance stackTraces = (Instance) runtime.getValueOfField(\"stackTraces\"); // NOI18N\n\n                truffleStackTraces = getStackTraces(heap, stackTraces);\n            }\n        }\n\n        private boolean isDefaultTruffleRuntime() {\n            return truffleStackTraces != null;\n        }\n\n        private Collection<StackTrace> getStackTraces() {\n            return truffleStackTraces;\n        }\n\n        private Collection<StackTrace> getStackTraces(Heap heap, Instance stackTraces) {\n            Collection<StackTrace> traces = new ArrayList<>();\n            JavaClass threadCls = heap.getJavaClassByName(THREAD_FQN);\n            Collection<JavaClass> allThreadCls = threadCls.getSubClasses();\n\n            allThreadCls.add(threadCls);\n\n            for (JavaClass threadSubCls : allThreadCls) {\n                List<Instance> threads = threadSubCls.getInstances();\n\n                for (Instance thread : threads) {\n                    Instance topFrame = getTruffleFrameInstance(thread, stackTraces);\n\n                    if (topFrame != null) {\n                        traces.add(new DefaultStackTrace(thread, topFrame));\n                    }\n                }\n            }\n            return Collections.unmodifiableCollection(traces);\n        }\n\n        private Instance getTruffleFrameInstance(Instance thread, Instance stackTraces) {\n            Instance threadLocals = (Instance) thread.getValueOfField(\"threadLocals\"); // NOI18N\n\n            if (threadLocals != null) {\n                List<Instance> mapTable = getObjectArray(threadLocals, \"table\"); // NOI18N\n\n                return searchTable(mapTable, stackTraces);\n            }\n            return null;\n        }\n\n        private Instance searchTable(List<Instance> entries, Instance item) {\n            for (Instance entry : entries) {\n                for (; entry != null; entry = (Instance) entry.getValueOfField(\"next\")) { // NOI18N\n                    Instance key = (Instance) entry.getValueOfField(\"referent\"); // NOI18N\n\n                    if (item.equals(key)) {\n                        return (Instance) entry.getValueOfField(\"value\"); // NOI18N\n                    }\n                }\n            }\n            return null;\n        }\n\n        private List<Instance> getObjectArray(Instance instance, String field) {\n            Object localsInst = instance.getValueOfField(field);\n\n            if (localsInst instanceof ObjectArrayInstance) {\n                return ((ObjectArrayInstance) localsInst).getValues();\n            }\n            return null;\n        }\n    }\n\n    private static class DefaultStackTrace extends StackTrace {\n\n        private final Instance topFrame;\n        private List<Frame> frames;\n\n        private DefaultStackTrace(Instance t, Instance f) {\n            super(t);\n            topFrame = f;\n        }\n\n        public synchronized List<Frame> getFrames() {\n            if (frames == null) {\n                Instance frame = topFrame;\n                frames = new ArrayList<>();\n\n                do {\n                    frames.add(new DefaultFrame(frame));\n                    frame = (Instance) frame.getValueOfField(\"callerFrame\"); // NOI18N\n                } while (frame != null);\n            }\n            return frames;\n        }\n    }\n\n    private static class DefaultFrame extends Frame {\n\n        private DefaultFrame(Instance frame) {\n            super((Instance) frame.getValueOfField(\"target\"), // NOI18N\n                  (Instance) frame.getValueOfField(\"frame\") // NOI18N\n            );\n        }\n    }\n\n    // implementation for org.graalvm.compiler.truffle.hotspot.HotSpotTruffleRuntime\n    private static class HotSpotTruffleRuntime {\n\n        private static final String HOTSPOT_TRUFFLE_RUNTIME_FQN = \"org.graalvm.compiler.truffle.hotspot.HotSpotTruffleRuntime\"; // NOI18N\n        private static final String HOTSPOT_TRUFFLE_RUNTIME1_FQN = \"org.graalvm.compiler.truffle.runtime.hotspot.HotSpotTruffleRuntime\"; // NOI18N\n        private static final String GRAAL_TRUFFLE_RUNTIME_FQN = \"org.graalvm.compiler.truffle.runtime.GraalTruffleRuntime\"; // NOI18N\n\n        private static final String DEFAULT_CALL_TARGET_FQN = \"com.oracle.truffle.api.impl.DefaultCallTarget\";   // NOI18N\n        private static final String OPTIMIZED_CALL_TARGET_FQN = \"org.graalvm.compiler.truffle.OptimizedCallTarget\"; //NOI18N\n        private static final String ENT_OPTIMIZED_CALL_TARGET_FQN = \"com.oracle.graal.truffle.OptimizedCallTarget\"; // NOI18N\n\n        private static final String OPTIMIZED_CALL_TARGET1_FQN = \"org.graalvm.compiler.truffle.runtime.OptimizedCallTarget\"; // NOI18N\n        private static final String OPTIMIZED_CALL_TARGET2_FQN = \"org.graalvm.compiler.truffle.runtime.hotspot.HotSpotOptimizedCallTarget\";    // NOI18N\n\n        private Collection<StackTrace> truffleStackTraces;\n        private Instance hotSpotRuntime;\n        private Heap heap;\n\n        private HotSpotTruffleRuntime(Heap h) {\n            heap = h;\n            hotSpotRuntime = getSingleton(heap, HOTSPOT_TRUFFLE_RUNTIME_FQN,\n                    HOTSPOT_TRUFFLE_RUNTIME1_FQN, GRAAL_TRUFFLE_RUNTIME_FQN);\n        }\n\n        private boolean isHotSpotTruffleRuntime() {\n            return hotSpotRuntime != null;\n        }\n\n        private void computeStackTrace(Heap heap, FrameVisitor visitor) {\n            Collection<GCRoot> roots = heap.getGCRoots();\n            Map<ThreadObjectGCRoot, Map<Integer, List<JavaFrameGCRoot>>> javaFrameMap = computeJavaFrameMap(roots);\n            for (GCRoot root : roots) {\n                if (root.getKind().equals(GCRoot.THREAD_OBJECT)) {\n                    ThreadObjectGCRoot threadRoot = (ThreadObjectGCRoot) root;\n                    Instance threadInstance = threadRoot.getInstance();\n\n                    if (threadInstance != null) {\n                        StackTraceElement stack[] = threadRoot.getStackTrace();\n\n                        if (stack != null) {\n                            Map<Integer, List<JavaFrameGCRoot>> localsMap = javaFrameMap.get(threadRoot);\n\n                            if (localsMap != null) {\n                                HotSpotStackTrace hsStackTrace = new HotSpotStackTrace(threadInstance);\n                                for (int i = 0; i < stack.length; i++) {\n                                    StackTraceElement stackElement = stack[i];\n                                    List<JavaFrameGCRoot> locals = localsMap.get(Integer.valueOf(i));\n                                    Frame frame = visitor.visitFrame(stackElement, locals);\n\n                                    if (frame != null) {\n                                        hsStackTrace.addFrame(frame);\n                                    }\n                                }\n                                if (!hsStackTrace.getFrames().isEmpty()) {\n                                    truffleStackTraces.add(hsStackTrace);\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        private Map<ThreadObjectGCRoot, Map<Integer, List<JavaFrameGCRoot>>> computeJavaFrameMap(Collection<GCRoot> roots) {\n            Map<ThreadObjectGCRoot, Map<Integer, List<JavaFrameGCRoot>>> javaFrameMap = new HashMap<>();\n\n            for (GCRoot root : roots) {\n                if (GCRoot.JAVA_FRAME.equals(root.getKind())) {\n                    JavaFrameGCRoot frameGCroot = (JavaFrameGCRoot) root;\n                    ThreadObjectGCRoot threadObj = frameGCroot.getThreadGCRoot();\n                    Integer frameNo = Integer.valueOf(frameGCroot.getFrameNumber());\n                    Map<Integer, List<JavaFrameGCRoot>> stackMap = javaFrameMap.get(threadObj);\n                    List<JavaFrameGCRoot> locals;\n\n                    if (stackMap == null) {\n                        stackMap = new HashMap<>();\n                        javaFrameMap.put(threadObj, stackMap);\n                    }\n                    locals = stackMap.get(frameNo);\n                    if (locals == null) {\n                        locals = new ArrayList(2);\n                        stackMap.put(frameNo, locals);\n                    }\n                    locals.add(frameGCroot);\n                }\n            }\n            return javaFrameMap;\n        }\n\n        private Instance findLocalInstance(List<JavaFrameGCRoot> locals, String... classes) {\n            if (locals != null) {\n                for (JavaFrameGCRoot local : locals) {\n                    Instance i = local.getInstance();\n                    String className = i.getJavaClass().getName();\n\n                    for (String cls : classes) {\n                        if (cls.equals(className)) {\n                            return i;\n                        }\n                    }\n                }\n            }\n            return null;\n        }\n\n        private TruffleFrame findLocalFrame(List<JavaFrameGCRoot> locals) {\n            if (locals != null) {\n                for (JavaFrameGCRoot local : locals) {\n                    Instance i = local.getInstance();\n                    TruffleFrame localFrame = new TruffleFrame(i);\n\n                    if (localFrame.isTruffleFrame()) {\n                        return localFrame;\n                    }\n                }\n            }\n            return null;\n        }\n\n        private Frame visitFrame(List<JavaFrameGCRoot> callTargetFrame, List<JavaFrameGCRoot> callNodeFrame) {\n            Instance callTarget = findLocalInstance(callTargetFrame,\n                                    DEFAULT_CALL_TARGET_FQN, OPTIMIZED_CALL_TARGET_FQN, ENT_OPTIMIZED_CALL_TARGET_FQN,\n                                    OPTIMIZED_CALL_TARGET1_FQN, OPTIMIZED_CALL_TARGET2_FQN);\n            TruffleFrame localFrame = findLocalFrame(callTargetFrame);\n            if (localFrame == null)\n                localFrame = findLocalFrame(callNodeFrame);\n\n            if (callTarget != null && localFrame != null) {\n                return new Frame(callTarget, localFrame);\n            }\n            callTarget = findLocalInstance(callNodeFrame,\n                                    DEFAULT_CALL_TARGET_FQN, OPTIMIZED_CALL_TARGET_FQN, ENT_OPTIMIZED_CALL_TARGET_FQN,\n                                    OPTIMIZED_CALL_TARGET1_FQN, OPTIMIZED_CALL_TARGET2_FQN);\n            localFrame = findLocalFrame(callTargetFrame);\n            if (callTarget != null && localFrame != null) {\n                return new Frame(callTarget, localFrame);\n            }\n            return null;\n        }\n\n        private synchronized Collection<StackTrace> getStackTraces() {\n            if (isHotSpotTruffleRuntime() && truffleStackTraces == null) {\n                FrameVisitor visitor = new FrameVisitor(this, heap, 0);\n\n                truffleStackTraces = new ArrayList<>();\n\n                computeStackTrace(heap, visitor);\n            }\n            return truffleStackTraces;\n        }\n\n    }\n\n    private static class HotSpotStackTrace extends StackTrace {\n\n        List<Frame> frames;\n\n        HotSpotStackTrace(Instance t) {\n            super(t);\n            frames = new ArrayList<>();\n        }\n\n        @Override\n        public List<Frame> getFrames() {\n            return frames;\n        }\n\n        private void addFrame(Frame frame) {\n            frames.add(frame);\n        }\n    }\n\n    private static class JavaMethod {\n\n        private final String className;\n        private final String methodName;\n        private final String signature;\n\n        private JavaMethod() {\n            className = null;\n            methodName = null;\n            signature = null;\n        }\n\n        private JavaMethod(String name, String method, String sig) {\n            className = name;\n            methodName = method;\n            signature = sig;\n        }\n\n        private JavaMethod(Heap heap, JavaClass frameClass, String field) {\n            this(heap, (Instance) frameClass.getValueOfStaticField(field));\n        }\n\n        private JavaMethod(Heap heap, Instance method) {\n            if (method != null) {\n                Instance javaClass = (Instance) method.getValueOfField(\"clazz\");   // NOI18N\n                className = heap.getJavaClassByID(javaClass.getInstanceId()).getName();\n                methodName = DetailsUtils.getInstanceFieldString(method, \"name\"); // NOI18N\n                signature = DetailsUtils.getInstanceFieldString(method, \"signature\"); // NOI18N\n            } else {\n                className = null;\n                methodName = null;\n                signature = null;\n            }\n        }\n\n        private boolean isMethod(StackTraceElement frame) {\n            if (className == null) {\n                return frame.getMethodName().equals(methodName);\n            }\n            return frame.getClassName().equals(className) && frame.getMethodName().equals(methodName);\n        }\n    }\n\n    private static final class FrameVisitor {\n\n        private static final String GRAAL_FRAME_INSTANCE_FQN = \"org.graalvm.compiler.truffle.GraalFrameInstance\"; // NOI18N\n        private static final String GRAAL_FRAME_INSTANCE1_FQN = \"org.graalvm.compiler.truffle.runtime.GraalFrameInstance\";  // NOI18N\n        private static final String GRAAL_RUNTIME_SUPPORT = \"org.graalvm.compiler.truffle.runtime.GraalRuntimeSupport\"; // NOI18N\n\n        private final HotSpotTruffleRuntime visitor;\n        private final JavaMethod callOSRMethod;\n        private final JavaMethod callTargetMethod;\n\n        private final JavaMethod callNodeMethod;\n\n        private final JavaMethod callDirectMethod;\n        private final JavaMethod callIndirectMethod;\n        private final JavaMethod callInlinedMethod;\n        private final JavaMethod callInlinedCallMethod;\n        private final JavaMethod callInlinedAgnosticMethod;\n        private final JavaMethod callInliningForcedMethod;\n        private int skipFrames;\n        private List<JavaFrameGCRoot> callNodeFrame;\n\n        FrameVisitor(HotSpotTruffleRuntime visitor, Heap heap, int skip) {\n            this.visitor = visitor;\n            JavaClass frameClass = getFrameClass(heap);\n            if (frameClass != null) {\n                callOSRMethod = new JavaMethod(heap, frameClass, \"CALL_OSR_METHOD\");  // NOI18N\n                callTargetMethod = new JavaMethod(heap, frameClass, \"CALL_TARGET_METHOD\");  // NOI18N\n\n                callNodeMethod = new JavaMethod(heap, frameClass, \"CALL_NODE_METHOD\");  // NOI18N\n\n                callDirectMethod = new JavaMethod(heap, frameClass, \"CALL_DIRECT\");  // NOI18N\n                callIndirectMethod = new JavaMethod(heap, frameClass, \"CALL_INDIRECT\");  // NOI18N\n                callInlinedMethod = new JavaMethod(heap, frameClass, \"CALL_INLINED\");  // NOI18N\n                callInlinedCallMethod = new JavaMethod(heap, frameClass, \"CALL_INLINED_CALL\");  // NOI18N\n                callInlinedAgnosticMethod = new JavaMethod(heap, frameClass, \"CALL_INLINED_AGNOSTIC\");  // NOI18N\n                callInliningForcedMethod = new JavaMethod(heap, frameClass, \"CALL_INLINED_FORCED\");  // NOI18N\n            } else {\n                JavaClass callTargetClass = getJavaClass(heap,\n                        HotSpotTruffleRuntime.OPTIMIZED_CALL_TARGET_FQN,\n                        HotSpotTruffleRuntime.ENT_OPTIMIZED_CALL_TARGET_FQN,\n                        HotSpotTruffleRuntime.OPTIMIZED_CALL_TARGET1_FQN,\n                        HotSpotTruffleRuntime.OPTIMIZED_CALL_TARGET2_FQN);\n                String callTargetFqn = callTargetClass == null ? null : callTargetClass.getName();\n                callOSRMethod = new JavaMethod(null, \"callProxy\", \"\");  // NOI18N\n                callTargetMethod = new JavaMethod(callTargetFqn, \"executeRootNode\", \"\");  // NOI18N\n\n                callNodeMethod = new JavaMethod();  // NOI18N\n\n                callDirectMethod = new JavaMethod(callTargetFqn, \"callDirect\", \"\");  // NOI18N\n                callIndirectMethod = new JavaMethod(callTargetFqn, \"callIndirect\", \"\");  // NOI18N\n                callInlinedMethod = new JavaMethod(callTargetFqn, \"callInlined\", \"\");  // NOI18N\n                JavaClass runtimeSupport = heap.getJavaClassByName(GRAAL_RUNTIME_SUPPORT);\n                if (runtimeSupport != null) {\n                    Object val = runtimeSupport.getValueOfStaticField(\"CALL_INLINED_METHOD_NAME\");  // NOI18N\n\n                    if (val instanceof Instance) {\n                        String methodName = DetailsUtils.getInstanceString((Instance) val);\n                        callInlinedCallMethod = new JavaMethod(GRAAL_RUNTIME_SUPPORT, methodName, \"\");  // NOI18N\n                    } else {\n                        callInlinedCallMethod = new JavaMethod();\n                    }\n                } else {\n                    callInlinedCallMethod = new JavaMethod();\n                }\n                callInlinedAgnosticMethod = new JavaMethod();\n                callInliningForcedMethod = new JavaMethod();\n            }\n            skipFrames = skip;\n        }\n\n        private static JavaClass getFrameClass(Heap heap) {\n            return getJavaClass(heap, GRAAL_FRAME_INSTANCE_FQN, GRAAL_FRAME_INSTANCE1_FQN);\n        }\n\n        private Frame visitFrame(StackTraceElement frame, List<JavaFrameGCRoot> locals) {\n            if (callOSRMethod.isMethod(frame)) {\n                // we ignore OSR frames.\n                skipFrames++;\n            } else if (callTargetMethod.isMethod(frame)) {\n                if (skipFrames == 0) {\n                    try {\n                        return visitor.visitFrame(locals, callNodeFrame);\n                    } finally {\n                        callNodeFrame = null;\n                    }\n                } else {\n                    skipFrames--;\n                }\n            } else if (callNodeMethod.isMethod(frame) || callDirectMethod.isMethod(frame)\n                    || callIndirectMethod.isMethod(frame) || callInlinedMethod.isMethod(frame)\n                    || callInlinedCallMethod.isMethod(frame)\n                    || callInlinedAgnosticMethod.isMethod(frame) || callInliningForcedMethod.isMethod(frame)) {\n                callNodeFrame = locals;\n            }\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleThreadsProvider.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.ClassNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.LocalObjectNode;\nimport org.graalvm.visualvm.heapviewer.java.ThreadNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.LocalDynamicObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleStackFrameNode;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleThreadsProvider_Unknown=<unknown>\",\n    \"TruffleThreadsProvider_ThreadNotAvailable=Thread not available\",\n    \"# {0} - thread name\",\n    \"TruffleThreadsProvider_ThreadNamePrefix=Thread \\\"{0}\\\"\",\n    \"TruffleThreadsProvider_StackFramePrefix=at\",\n    \"TruffleThreadsProvider_LocalObjectPrefix=local object:\",\n    \"TruffleThreadsProvider_CannotResolveClassMsg=Cannot resolve class\",\n    \"TruffleThreadsProvider_CannotResolveInstanceMsg=Cannot resolve instance\"\n})\npublic class TruffleThreadsProvider<O extends TruffleObject, T extends TruffleType<O>, F extends TruffleLanguageHeapFragment<O, T>, L extends TruffleLanguage<O, T, F>> {\n    \n    private final L language;\n    \n    \n    public TruffleThreadsProvider(L language) {\n        this.language = language;\n    }\n    \n    \n    public HeapViewerNode[] getThreadsObjects(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        List<HeapViewerNode> threadNodes = new ArrayList<>();\n        \n        TruffleStackTraces tst = new TruffleStackTraces(heap);\n        Collection<TruffleStackTraces.StackTrace> threads = tst.getStackTraces();\n        \n        if (threads != null) {\n            Thread worker = Thread.currentThread();\n            \n            for (TruffleStackTraces.StackTrace st : threads) {\n                Instance threadInstance = st.getThread();\n                String threadName = Bundle.TruffleThreadsProvider_ThreadNamePrefix(DetailsSupport.getDetailsString(threadInstance));\n                if (threadName == null /*|| !threadName.startsWith(RUBY_THREAD_NAME_PREFIX)*/) continue;\n                \n                final List<HeapViewerNode> stackFrameNodes = new ArrayList<>();\n                ThreadNode threadNode = new ThreadNode(threadName, threadInstance) {\n                    protected HeapViewerNode[] computeChildren(RootNode root) {\n                        return stackFrameNodes.toArray(HeapViewerNode.NO_NODES);\n                    }\n                };\n                threadNodes.add(threadNode);\n\n                for (TruffleStackTraces.Frame f : st.getFrames()) {\n                    Set<HeapViewerNode> localObjects = new HashSet<>();\n                    for (FieldValue fv : f.getFieldValues()) {\n                        if (worker.isInterrupted()) throw new InterruptedException();\n                        \n                        if (!(fv instanceof ObjectFieldValue)) continue;\n\n                        Instance instance = ((ObjectFieldValue)fv).getInstance();\n                        if (instance == null) continue;\n                        \n                        if (language.isLanguageObject(instance)) {\n                            O object = language.createObject(instance);\n                            localObjects.add((HeapViewerNode)language.createLocalObjectNode(object, object.getType()));\n                        } else if (DynamicObject.isDynamicObject(instance)) {\n                            DynamicObject dobj = new DynamicObject(instance);\n                            localObjects.add(new LocalDynamicObjectNode<>(dobj, dobj.getType()));\n                        } else {\n                            localObjects.add(new LocalObjectNode(instance));\n                        }\n                    }\n                    \n                    String stackFrameName = f.getName();\n                    if (stackFrameName == null) stackFrameName = Bundle.TruffleThreadsProvider_Unknown();\n                    stackFrameNodes.add(new TruffleStackFrameNode(stackFrameName, localObjects.toArray(HeapViewerNode.NO_NODES)));\n                }\n            }\n        } else {\n            threadNodes.add(new TextNode(Bundle.TruffleThreadsProvider_ThreadNotAvailable()));\n        }\n        \n        return threadNodes.toArray(HeapViewerNode.NO_NODES);\n    }\n    \n    public HeapViewerNode getNodeForURL(URL url, HeapContext context) {\n        String urls = url.toString();\n                \n        if (HeapUtils.isInstance(urls)) {\n            Heap heap = context.getFragment().getHeap();\n            Instance instance = HeapUtils.instanceFromHtml(urls, heap);\n            \n            if (language.isLanguageObject(instance)) {\n                O object = language.createObject(instance);\n                return (HeapViewerNode)language.createObjectNode(object, object.getType());\n            } else if (DynamicObject.isDynamicObject(instance)) {\n                DynamicObject dobj = new DynamicObject(instance);\n                return new LocalDynamicObjectNode<>(dobj, dobj.getType());\n            } else if (instance != null) {\n                return new InstanceNode(instance);\n            } else {\n                ProfilerDialogs.displayError(Bundle.TruffleThreadsProvider_CannotResolveInstanceMsg());\n            }\n        } else if (HeapUtils.isClass(urls)) {\n            JavaClass javaClass = HeapUtils.classFromHtml(urls, context.getFragment().getHeap());\n            if (javaClass != null) return new ClassNode(javaClass);\n            else ProfilerDialogs.displayError(Bundle.TruffleThreadsProvider_CannotResolveClassMsg());\n        }\n\n        return null;\n    }\n    \n    public String getThreadsHTML(HeapContext context) {\n        StringBuilder sb = new StringBuilder();\n        \n        Heap heap = context.getFragment().getHeap();\n        JavaClass javaClassClass = heap.getJavaClassByName(Class.class.getName());\n        \n        TruffleStackTraces tst = new TruffleStackTraces(heap);\n        Collection<TruffleStackTraces.StackTrace> threads = tst.getStackTraces();\n        \n        sb.append(\"<pre>\"); // NOI18N\n\n        if (threads != null) {\n            for (TruffleStackTraces.StackTrace st : threads) {\n                sb.append(\"<b>&nbsp;&nbsp;\" + Bundle.TruffleThreadsProvider_ThreadNamePrefix(DetailsSupport.getDetailsString(st.getThread())) + \"</b>\"); // NOI18N\n                sb.append(\"<br>\");  // NOI18N\n\n                List<TruffleStackTraces.Frame> frames = st.getFrames();\n                for (TruffleStackTraces.Frame f : frames) {\n                    List<FieldValue> fields = f.getFieldValues();\n                    String fname = f.getName();\n                    if (fname == null) fname = Bundle.TruffleThreadsProvider_Unknown();\n                    sb.append(\"    \" + Bundle.TruffleThreadsProvider_StackFramePrefix() + \" \" + HeapUtils.htmlize(fname)); // NOI18N\n                    sb.append(\"<br>\");  // NOI18N\n\n                    for (FieldValue fv : fields) {\n                        if (!(fv instanceof ObjectFieldValue)) continue;\n                        Instance instance = ((ObjectFieldValue)fv).getInstance();\n                        if (instance == null) continue;\n                        sb.append(\"       <span style=\\\"color: #666666\\\">\" + Bundle.TruffleThreadsProvider_LocalObjectPrefix() + \"</span> \" + printInstance(instance, javaClassClass)); // NOI18N\n                        sb.append(\"<br>\");  // NOI18N\n                    }\n                }\n            }\n        } else {\n            sb.append(\"<b>&nbsp;&nbsp;\" + Bundle.TruffleThreadsProvider_ThreadNotAvailable()); // NOI18N\n        }\n        \n        sb.append(\"<br>\");  // NOI18N\n        sb.append(\"</pre>\"); // NOI18N\n        \n        return sb.toString();\n    }\n    \n    private String printInstance(Instance instance, JavaClass javaClassClass) {\n        if (language.isLanguageObject(instance)) {\n            O object = language.createObject(instance);\n            TruffleObjectNode<?> node = language.createObjectNode(object, object.getType());\n            String instanceString = HeapUtils.instanceToHtml(instance, false, javaClassClass);\n            String type = node.getTypeName();\n            instanceString = instanceString.replace(\">\" + instance.getJavaClass().getName() + \"#\", \">\" + HeapUtils.htmlize(type) + \"#\"); // NOI18N\n            String logValue = node.getLogicalValue();\n            if (logValue != null) instanceString += \" <span style=\\\"color: #666666\\\">: \" + HeapUtils.htmlize(logValue) + \"</span>\"; // NOI18N\n            return instanceString;\n        } else if (DynamicObject.isDynamicObject(instance)) {\n            DynamicObject dobj = new DynamicObject(instance);\n            TruffleObjectNode<?> node = new DynamicObjectNode<>(dobj, dobj.getType());\n            String instanceString = HeapUtils.instanceToHtml(instance, false, javaClassClass);\n            String type = node.getTypeName();\n            instanceString = instanceString.replace(\">\" + instance.getJavaClass().getName() + \"#\", \">\" + HeapUtils.htmlize(type) + \"#\"); // NOI18N\n            String logValue = node.getLogicalValue();\n            if (logValue != null) instanceString += \" <span style=\\\"color: #666666\\\">: \" + HeapUtils.htmlize(logValue) + \"</span>\"; // NOI18N\n            return instanceString;\n        } else {\n            return HeapUtils.instanceToHtml(instance, true, javaClassClass);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/TruffleType.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class TruffleType<O extends TruffleObject> {\n    \n    public static final DataType<String> TYPE_NAME = new DataType<>(String.class, null, null);\n    \n    private final String name;\n    \n    protected int count;\n    protected long size;\n    protected long retained = DataType.RETAINED_SIZE.getNotAvailableValue();\n\n\n    public TruffleType(String name) {\n        this.name = name;\n    }\n\n\n    public String getName() { return name; }\n\n    public int getObjectsCount() { return count; }\n\n    public long getAllObjectsSize() { return size; }\n    \n    // TODO: slow objectsIterator called in EDT, resolve somehow!\n    public long getRetainedSizeByType(Heap heap) {\n        if (retained < 0 && DataType.RETAINED_SIZE.valuesAvailable(heap)) {\n            retained = 0;\n            Iterator<O> objects = getObjectsIterator();\n            while (objects.hasNext()) retained += objects.next().getRetainedSize();\n        }\n        return retained;\n    }\n\n    \n    public abstract Iterator<O> getObjectsIterator();\n\n\n    protected void addObject(O object, long objectSize, long objectRetainedSize) {\n        count++;\n        this.size += objectSize;\n        if (objectRetainedSize >= 0) {\n            if (this.retained < 0) this.retained = 0;\n            this.retained += objectRetainedSize;\n        }\n    }\n\n\n    public int hashCode() {\n        return name.hashCode();\n    }\n\n    public boolean equals(Object o) {\n        if (o == this) return true;\n        if (!(o instanceof TruffleType)) return false;\n        return name.equals(((TruffleType)o).name);\n    }\n    \n    \n    public static abstract class InstanceBased<O extends TruffleObject.InstanceBased> extends TruffleType<O> {\n        \n        private final List<Instance> instances;\n        \n        \n        public InstanceBased(String name) {\n            super(name);\n            this.instances = new ArrayList<>();\n        }\n        \n        \n        protected abstract O createObject(Instance i);\n        \n        \n        @Override\n        protected void addObject(O object, long objectSize, long objectRetainedSize) {\n            super.addObject(object, objectSize, objectRetainedSize);\n            instances.add(object.getInstance());\n        }\n        \n        @Override\n        public Iterator<O> getObjectsIterator() {\n            return new Iterator<O>() {\n                private final Iterator<Instance> i = instances.iterator();\n                @Override public boolean hasNext() { return i.hasNext(); }\n                @Override public O next() { return createObject(i.next()); }\n            };\n        }\n        \n    }\n    \n    \n    public static class TypesComputer<O extends TruffleObject, T extends TruffleType<O>> {\n        \n        private final boolean retainedAvailable;\n        \n        private final TruffleLanguage<O, T, ? extends TruffleLanguageHeapFragment<O, T>> language;\n        \n        private final Heap heap;\n        private final Map<String, T> cache;\n        private final Map<Long,String> typeCache;\n        \n        \n        public TypesComputer(TruffleLanguage<O, T, ? extends TruffleLanguageHeapFragment<O, T>> language, Heap heap) {\n            this.language = language;\n            this.heap = heap;\n            cache = new HashMap<>();\n            typeCache = new HashMap<>();\n            retainedAvailable = DataType.RETAINED_SIZE.valuesAvailable(heap);\n        }\n        \n        \n        protected void addingObject(long size, long retained, String type) {}\n        \n        \n        public final void addObject(O object) {\n            long objectSize = object.getSize();\n            long objectRetainedSize = retainedAvailable ? object.getRetainedSize() :\n                                      DataType.RETAINED_SIZE.getNotAvailableValue();\n            String typeName = getTypeName(object);\n            \n            addingObject(objectSize, objectRetainedSize, typeName);\n            \n            T type = cache.get(typeName);\n            if (type == null) {\n                type = language.createType(typeName);\n                cache.put(typeName, type);\n            }\n            \n            type.addObject(object, objectSize, objectRetainedSize);\n        }\n        \n        public final List<T> getTypes() {\n            return Collections.unmodifiableList(new ArrayList<>(cache.values()));\n        }\n\n        private String getTypeName(O object) {\n            Long typeId = Long.valueOf(object.getTypeId());\n            String typeName = typeCache.get(typeId);\n\n            if (typeName == null) {\n                typeName = object.getType();\n                typeCache.put(typeId, typeName);\n            }\n            return typeName;\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/details/SourceDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.details;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic class SourceDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String FSOURCE_NAME_MASK = \"com.oracle.truffle.api.source.FileSourceImpl\";    // NOI18N\n    private static final String CONTENT_NAME_MASK = \"com.oracle.truffle.api.source.Content+\";    // NOI18N\n    private static final String SOURCE_NAME_MASK = \"com.oracle.truffle.api.source.Source+\";     // NOI18N\n    private static final String SOURCEIMPL_KEY_MASK = \"com.oracle.truffle.api.source.SourceImpl$Key+\";   // NOI18N\n    private static final String SOURCE_SECTION_MASK = \"com.oracle.truffle.api.source.SourceSection+\";    // NOI18N\n    private static final String ASSUMPTION_MASK = \"com.oracle.truffle.api.impl.AbstractAssumption+\";    // NOI18N\n    private static final String HIDDEN_KEY_MASK = \"com.oracle.truffle.api.object.HiddenKey\"; // NOI18N\n    private static final String PROPERTY_MASK = \"com.oracle.truffle.object.PropertyImpl\";    // NOI18N\n    private static final String FRAMESLOT_MASK = \"com.oracle.truffle.api.frame.FrameSlot\";  // NOI18N\n    private static final String BP_ENABLED_MASK = \"com.oracle.truffle.api.profiles.BranchProfile$Enabled\";    // NOI18N\n    private static final String CP_BINARY_MASK = \"com.oracle.truffle.api.profiles.ConditionProfile$Binary\";    // NOI18N\n\n    public SourceDetailsProvider() {\n        super(FSOURCE_NAME_MASK,CONTENT_NAME_MASK,SOURCE_NAME_MASK,SOURCEIMPL_KEY_MASK, SOURCE_SECTION_MASK,\n                ASSUMPTION_MASK,HIDDEN_KEY_MASK,PROPERTY_MASK,FRAMESLOT_MASK,\n                BP_ENABLED_MASK,CP_BINARY_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case FSOURCE_NAME_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"path\");     // NOI18N\n            case ASSUMPTION_MASK: {\n                Object val = instance.getValueOfField(\"isValid\");   // NOI18N\n                if (val instanceof Boolean) {\n                    boolean isValid = ((Boolean)val).booleanValue();\n                    return DetailsUtils.getInstanceFieldString(instance, \"name\") + \" (\" + (isValid ? \"valid\" : \"invalid\") + \")\";  // NOI18N\n                }\n                break;\n            }\n            case CONTENT_NAME_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"code\");     // NOI18N\n            case SOURCEIMPL_KEY_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\");  // NOI18N\n                String mimeType = DetailsUtils.getInstanceFieldString(instance, \"mimeType\");  // NOI18N\n                return name + \" (\"+mimeType+\")\";    // NOI18N\n            }\n            case SOURCE_NAME_MASK: {\n                Object key = instance.getValueOfField(\"key\");   // NOI18N\n                if (key instanceof Instance) {\n                    return DetailsUtils.getInstanceString((Instance) key);\n                }\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\");  // NOI18N\n                String mimeType = DetailsUtils.getInstanceFieldString(instance, \"mimeType\");  // NOI18N\n                return name + \" (\"+mimeType+\")\";    // NOI18N\n            }\n            case HIDDEN_KEY_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"name\")+\" (hidden)\";     // NOI18N\n            case PROPERTY_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"key\");     // NOI18N\n            case SOURCE_SECTION_MASK: {\n                Integer charIndex = (Integer) instance.getValueOfField(\"charIndex\");    // NOI18N\n                Integer charLength = (Integer) instance.getValueOfField(\"charLength\");  // NOI18N\n                if (charIndex != null && charLength != null) {\n                    return DetailsUtils.getInstanceFieldString(instance, \"source\")+ \" [\"+charIndex+\",\"+(charIndex+charLength)+\"]\"; // NOI18N\n                }\n                break;\n            }\n            case FRAMESLOT_MASK: {\n                Integer index = (Integer) instance.getValueOfField(\"index\");    // NOI18N\n                String identifier = DetailsUtils.getInstanceFieldString(instance, \"identifier\");    // NOI18N\n                String kind = DetailsUtils.getInstanceFieldString(instance, \"kind\");    // NOI18N\n                return \"[\" + index + \",\" + identifier + \",\" + kind + \"]\"; // NOI18N\n            }\n            case BP_ENABLED_MASK: {\n                Object val = instance.getValueOfField(\"visited\");   // NOI18N\n                if (val instanceof Boolean) {\n                    boolean visited = ((Boolean)val).booleanValue();\n                    return visited ? \"VISITED\" : \"UNINITIALIZED\";   // NOI18N\n                }\n                break;\n            }\n            case CP_BINARY_MASK: {\n                Object val = instance.getValueOfField(\"wasTrue\");   // NOI18N\n                Object val1 = instance.getValueOfField(\"wasFalse\");   // NOI18N\n                if (val instanceof Boolean && val1 instanceof Boolean) {\n                    boolean wasTrue = ((Boolean)val).booleanValue();\n                    boolean wasFalse = ((Boolean)val1).booleanValue();\n                    return \"wasTrue=\"+wasTrue+\", wasFalse=\"+wasFalse; // NOI18N\n                }\n                break;\n            }\n            default:\n                break;\n        }\n        return null;\n    }\n\n    public View getDetailsView(String className, Instance instance) {\n        if (CONTENT_NAME_MASK.equals(className)) {\n            Object val = instance.getValueOfField(\"code\");  // NOI18N\n            if (val instanceof Instance) {\n                Instance text = (Instance) val;\n                return DetailsSupport.getDetailsView(text);\n            }\n            return null;\n        }\n        if (SOURCEIMPL_KEY_MASK.equals(className)) {\n            Object val = instance.getValueOfField(\"characters\");  // NOI18N\n            if (val instanceof Instance) {\n                Instance text = (Instance) val;\n                return DetailsSupport.getDetailsView(text);\n            }\n            val = instance.getValueOfField(\"content\");  // NOI18N\n            if (val instanceof Instance) {\n                Instance text = (Instance) val;\n                return DetailsSupport.getDetailsView(text);\n            }\n            return null;\n        }\n        if (SOURCE_NAME_MASK.equals(className)) {\n            Object val = instance.getValueOfField(\"content\");  // NOI18N\n            if (val instanceof Instance) {\n                Instance content = (Instance) val;\n                return DetailsSupport.getDetailsView(content);\n            }\n            val = instance.getValueOfField(\"key\");  // NOI18N\n            if (val instanceof Instance) {\n                Instance content = (Instance) val;\n                return DetailsSupport.getDetailsView(content);\n            }\n            return null;\n        }\n        if (SOURCE_SECTION_MASK.equals(className)) {\n            Integer charIndex = (Integer) instance.getValueOfField(\"charIndex\");    // NOI18N\n            Integer charLength = (Integer) instance.getValueOfField(\"charLength\");  // NOI18N\n            Instance source = (Instance) instance.getValueOfField(\"source\");     // NOI18N\n            Instance content = (Instance) source.getValueOfField(\"content\");     // NOI18N\n            Instance code;\n\n            if (charIndex != null && charLength != null) {\n                if (content != null) {\n                    code = (Instance) content.getValueOfField(\"code\");     // NOI18N\n\n                    // Likely a native method\n                    // TODO: handle differently?\n                    if (charLength == -1) code = (Instance) source.getValueOfField(\"name\");     // NOI18N\n                } else {\n                    Instance key = (Instance) source.getValueOfField(\"key\");     // NOI18N\n\n                    code = (Instance) key.getValueOfField(\"characters\");  // NOI18N\n                    if (code == null) {\n                        code = (Instance) key.getValueOfField(\"content\"); // NOI18N\n                    }\n                    // Likely a native method\n                    // TODO: handle differently?\n                    if (charLength == -1) code = (Instance) key.getValueOfField(\"name\");     // NOI18N\n                }\n                return new SourceSectionView(className, code, charIndex.intValue(), charLength.intValue());\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/details/SourceSectionView.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.details;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextPane;\nimport javax.swing.JViewport;\nimport javax.swing.Scrollable;\nimport javax.swing.SwingUtilities;\nimport javax.swing.text.MutableAttributeSet;\nimport javax.swing.text.SimpleAttributeSet;\nimport javax.swing.text.StyleConstants;\nimport javax.swing.text.StyledDocument;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.ExportAction;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.StringDecoder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\n@NbBundle.Messages({\n    \"SourceSectionView_Truncated=... <truncated>\",                                     // NOI18N\n    \"SourceSectionView_Value=Value:\",                                                  // NOI18N\n    \"SourceSectionView_All=Show All\",                                                  // NOI18N\n    \"SourceSectionView_Save=Save to File\",                                             // NOI18N\n    \"SourceSectionView_OutOfMemory=Out of memory - value too long.\"                    // NOI18N\n})\npublic final class SourceSectionView extends DetailsProvider.View implements Scrollable, ExportAction.ExportProvider {\n\n    private static final int MAX_PREVIEW_LENGTH = 256;\n    private static final int MAX_ARRAY_ITEMS = 1000;\n    private static final int MAX_CHARARRAY_ITEMS = 500000;\n    private static final String TRUNCATED = Bundle.SourceSectionView_Truncated();\n\n    private JTextPane view;\n    private JButton all;\n\n    private String caption;\n    private Heap heap;\n    private List<String> values;\n    private byte coder = -1;\n    private int offset;\n    private int count;\n    private int sectionOffset;\n    private int sectionSize;\n    private boolean chararray;\n    private String instanceIdentifier;\n\n    public SourceSectionView(String className, Instance instance, int offset, int size) {\n        super(instance);\n        sectionOffset = offset;\n        sectionSize = size;\n    }\n\n    protected void computeView(Instance instance) {\n\n        offset = DetailsUtils.getIntFieldValue(instance, \"offset\", 0);          // NOI18N\n        count = DetailsUtils.getIntFieldValue(instance, \"count\", -1);           // NOI18N\n        coder = DetailsUtils.getByteFieldValue(instance, \"coder\", (byte) -1);   // NOI18N\n        values = DetailsUtils.getPrimitiveArrayFieldValues(instance, \"value\");  // NOI18N\n        caption = Bundle.SourceSectionView_Value();\n        heap = instance.getJavaClass().getHeap();\n        instanceIdentifier=instance.getJavaClass().getName()+\"#\"+instance.getInstanceNumber(); // NOI18N\n        final String preview = getString(true);\n\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));\n                setBackground(UIUtils.getProfilerResultsBackground());\n                setOpaque(true);\n\n                removeAll();\n\n                JLabel l = new JLabel(caption, JLabel.LEADING);\n                l.setBorder(BorderFactory.createEmptyBorder(0, 0, 3, 0));\n                add(l, BorderLayout.NORTH);\n\n                view = new JTextPane();\n                l.setLabelFor(view);\n                view.setEditable(false);\n                view.setText(preview);\n                try { view.setCaretPosition(0); } catch (IllegalArgumentException e) {}\n\n                JScrollPane viewScroll = new JScrollPane(view,\n                        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                        JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n                add(viewScroll, BorderLayout.CENTER);\n\n                JPanel p = new JPanel(new GridBagLayout());\n                p.setOpaque(false);\n\n                all = htmlButton(Bundle.SourceSectionView_All(), count < (chararray ? MAX_CHARARRAY_ITEMS : MAX_ARRAY_ITEMS), new Runnable() {\n                    public void run() { showAll(); }\n                });\n                GridBagConstraints c = new GridBagConstraints();\n                c.gridx = 0;\n                c.insets = new Insets(3, 0, 0, 5);\n                p.add(all, c);\n\n                JButton save = htmlButton(Bundle.SourceSectionView_Save(), !preview.isEmpty(), new Runnable() {\n                    public void run() {\n                        new ExportAction(SourceSectionView.this).actionPerformed(null);\n                    }\n                });\n                c = new GridBagConstraints();\n                c.gridx = 1;\n                c.insets = new Insets(3, 0, 0, 0);\n                p.add(save, c);\n\n                JPanel f = new JPanel(null);\n                f.setOpaque(false);\n                c = new GridBagConstraints();\n                c.gridx = 2;\n                c.weightx = 1;\n                c.fill = GridBagConstraints.HORIZONTAL;\n                p.add(f, c);\n\n                add(p, BorderLayout.SOUTH);\n\n                revalidate();\n                doLayout();\n                repaint();\n                \n                // Likely a native method\n                // TODO: handle differently?\n                if (sectionSize == -1) showAll();\n            }\n        });\n    }\n\n    private void showAll() {\n        all.setEnabled(false);\n        view.setEnabled(false);\n        new RequestProcessor(\"SourceSection Details\").post(new Runnable() { // NOI18N // TODO: use a HeapWalker processor once the API is available\n            public void run() {\n                String _preview = null;\n                try {\n                    _preview = getString(false);\n                } catch (OutOfMemoryError e) {\n                    ProfilerDialogs.displayError(Bundle.SourceSectionView_OutOfMemory());\n                    return;\n                }\n\n                final String preview = _preview;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        try {\n                            view.setText(preview);\n                            view.setEnabled(true);\n                            MutableAttributeSet attrs = new SimpleAttributeSet();\n                            StyleConstants.setBackground(attrs, Color.YELLOW);\n                            StyledDocument doc = view.getStyledDocument();\n                            doc.setCharacterAttributes(sectionOffset, sectionSize, attrs, false);\n                            view.setCaretPosition(Math.min(sectionOffset+64, preview.length()));\n                        } catch (OutOfMemoryError e) {\n                            ProfilerDialogs.displayError(Bundle.SourceSectionView_OutOfMemory());\n                        }\n                    }\n                });\n            }\n        });\n    }\n\n\n    private String getString(boolean preview) {\n        if (values == null) return \"\";                                              // NOI18N\n        StringDecoder decoder = new StringDecoder(heap, coder, values);\n        int valuesCount = count < 0 ? decoder.getStringLength() - offset : count;\n        int estimatedSize = (int)Math.min((long)valuesCount * 2, MAX_PREVIEW_LENGTH + TRUNCATED.length());\n        StringBuilder value = new StringBuilder(estimatedSize);\n        int lastValue = offset + (preview ? sectionOffset + sectionSize - 1 : valuesCount - 1);\n        int firstValue = offset + (preview ? sectionOffset : 0);\n        for (int i = firstValue; i <= lastValue; i++) {\n            value.append(decoder.getValueAt(i));\n            if (preview && value.length() >= MAX_PREVIEW_LENGTH) {\n                value.append(TRUNCATED);\n                break;\n            }\n        }\n        return value.toString();\n    }\n\n\n    public Dimension getPreferredScrollableViewportSize() {\n        return null;\n    }\n\n    public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {\n        // Scroll almost one screen\n        Container parent = getParent();\n        if ((parent == null) || !(parent instanceof JViewport)) return 50;\n        return (int)(((JViewport)parent).getHeight() * 0.95f);\n    }\n\n    public boolean getScrollableTracksViewportHeight() {\n        // Allow dynamic vertical enlarging of the panel but request the vertical scrollbar when needed\n        Container parent = getParent();\n        if ((parent == null) || !(parent instanceof JViewport)) return false;\n        return getMinimumSize().height < ((JViewport)parent).getHeight();\n    }\n\n    public boolean getScrollableTracksViewportWidth() {\n        // Allow dynamic horizontal enlarging of the panel but request the vertical scrollbar when needed\n        Container parent = getParent();\n        if ((parent == null) || !(parent instanceof JViewport)) return false;\n        return getMinimumSize().width < ((JViewport)parent).getWidth();\n    }\n\n    public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {\n        return 20;\n    }\n\n\n    private static JButton htmlButton(final String text, final boolean enabled, final Runnable handler) {\n        JButton b = new JButton() {\n            public void setEnabled(boolean b) {\n                setText(!b ? text : \"<html><nobr><a href='#'>\" + text + \"</a></nobr></html>\"); // NOI18N\n                setCursor(!b ? Cursor.getDefaultCursor() : Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n                super.setEnabled(b);\n            }\n        };\n        b.setOpaque(false);\n        b.setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 1));\n        b.setBorderPainted(false);\n        b.setContentAreaFilled(false);\n        b.setEnabled(enabled);\n        b.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { handler.run(); }\n        });\n        return b;\n    }\n\n    @Override\n    public void exportData(int exportedFileType, ExportDataDumper eDD) {\n        String comma = \",\"; // NOI18N\n        if (values != null) {\n            StringDecoder decoder = new StringDecoder(heap, coder, values);\n            int valuesCount = count < 0 ? decoder.getStringLength() - offset : count;\n            int lastValue = offset + valuesCount - 1;\n            for (int i = offset; i <= lastValue; i++) {\n                String value = decoder.getValueAt(i);\n\n                switch (exportedFileType) {\n                    case ExportAction.MODE_CSV:\n                        eDD.dumpData(value);\n                        eDD.dumpData(comma);\n                        break;\n                    case ExportAction.MODE_TXT:\n                        eDD.dumpData(value);\n                        break;\n                    case ExportAction.MODE_BIN:\n                        byte b = Byte.valueOf(value);\n                        eDD.dumpByte(b);\n                        break;\n                    default:\n                        throw new IllegalArgumentException(); //Illegal export type\n                }\n            }\n        }\n        eDD.close();\n    }\n\n    @Override\n    public String getViewName() {\n        return instanceIdentifier;\n    }\n\n    @Override\n    public boolean hasRawData() {\n        return false;\n    }\n\n    @Override\n    public boolean hasBinaryData() {\n        return false;\n    }\n\n    @Override\n    public boolean hasText() {\n        return true;\n    }\n\n    @Override\n    public boolean isExportable() {\n        return hasText() || hasBinaryData() || hasRawData();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/details/TruffleDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.details;\n\nimport java.io.UnsupportedEncodingException;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.WeakHashMap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service = DetailsProvider.class)\npublic class TruffleDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String DEFAULT_CALL_TARGET_MASK = \"com.oracle.truffle.api.impl.DefaultCallTarget\";   // NOI18N\n    private static final String OPTIMIZED_CALL_TARGET_MASK = \"org.graalvm.compiler.truffle.OptimizedCallTarget\"; //NOI18N\n    private static final String OPTIMIZED_CALL_TARGET1_MASK = \"org.graalvm.compiler.truffle.runtime.OptimizedCallTarget+\"; // NOI18N\n    private static final String ENT_OPTIMIZED_CALL_TARGET_MASK = \"com.oracle.graal.truffle.OptimizedCallTarget\"; // NOI18N\n    private static final String LANG_INFO_MASK = \"com.oracle.truffle.api.nodes.LanguageInfo\"; // NOI18N\n    private static final String LANG_CACHE_MASK = \"com.oracle.truffle.api.vm.LanguageCache\"; // NOI18N\n    private static final String LANG_CACHE1_MASK = \"com.oracle.truffle.polyglot.LanguageCache\"; // NOI18N\n    private static final String POLYGLOT_MASK = \"com.oracle.truffle.api.vm.PolyglotLanguage\";   // NOI18N\n    private static final String INSTRUMENT_INFO_MASK = \"com.oracle.truffle.api.InstrumentInfo\"; // NOI18N\n    private static final String NATIVE_ROOT_MASK = \"com.oracle.truffle.nfi.LibFFIFunctionMessageResolutionForeign$ExecuteLibFFIFunctionSubNode$EXECUTERootNode\"; // NOI18N\n    private static final String NODE_MASK = \"com.oracle.truffle.api.nodes.Node+\"; // NOI18N\n    private static final String TSTRING_MASK = \"com.oracle.truffle.api.strings.AbstractTruffleString+\"; // NOI18N\n    private static final String TS_LONG_MASK = \"com.oracle.truffle.api.strings.AbstractTruffleString$LazyLong\"; // NOI18N\n    private static final String TS_CONCAT_MASK = \"com.oracle.truffle.api.strings.AbstractTruffleString$LazyConcat\"; // NOI18N\n    private static final String LLVM_NODE_MASK = \"com.oracle.truffle.llvm.runtime.nodes.func.LLVMFunctionStartNode\"; // NOI18N\n    private static final String LLVM_FOREIGN_NODE_MASK = \"com.oracle.truffle.llvm.runtime.interop.LLVMForeignFunctionCallNode\"; // NOI18N\n    private static final String TS_ENCODING_CLASS = \"com.oracle.truffle.api.strings.TruffleString$Encoding\"; // NOI18N\n    private static final Object CACHE_LOCK = new Object();\n    private static WeakHashMap<Heap,Map<Byte,Encoding>> CACHE;\n\n    public TruffleDetailsProvider() {\n        super(DEFAULT_CALL_TARGET_MASK, OPTIMIZED_CALL_TARGET_MASK, OPTIMIZED_CALL_TARGET1_MASK,\n                ENT_OPTIMIZED_CALL_TARGET_MASK, LANG_INFO_MASK, LANG_CACHE_MASK,\n                LANG_CACHE1_MASK, POLYGLOT_MASK, INSTRUMENT_INFO_MASK, NATIVE_ROOT_MASK,\n                NODE_MASK, TSTRING_MASK, TS_LONG_MASK, TS_CONCAT_MASK, LLVM_NODE_MASK,\n                LLVM_FOREIGN_NODE_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case DEFAULT_CALL_TARGET_MASK: {\n                String rootNode = DetailsUtils.getInstanceFieldString(instance, \"rootNode\"); // NOI18N\n\n                if (rootNode != null) {\n                    return rootNode;\n                }\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            }\n            case OPTIMIZED_CALL_TARGET_MASK:\n            case OPTIMIZED_CALL_TARGET1_MASK:\n            case ENT_OPTIMIZED_CALL_TARGET_MASK: {\n                String rootNode = DetailsUtils.getInstanceFieldString(instance, \"rootNode\"); // NOI18N\n\n                if (rootNode != null) {\n                    Object entryPoint = instance.getValueOfField(\"entryPoint\"); // NOI18N\n\n                    if (entryPoint instanceof Long && ((Long) entryPoint).longValue() != 0) {\n                        rootNode += \" <opt>\"; // NOI18N\n                    }\n                    if (instance.getValueOfField(\"sourceCallTarget\") != null) { // NOI18N\n                        rootNode += \" <split-\" + Long.toHexString(instance.getInstanceId()) + \">\"; // NOI18N\n                    }\n                    return rootNode;\n                } else {\n                    return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n                }\n            }\n            case LANG_INFO_MASK:\n            case LANG_CACHE_MASK:\n            case LANG_CACHE1_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n                String version = DetailsUtils.getInstanceFieldString(instance, \"version\"); // NOI18N\n\n                if (name != null && version != null) {\n                    return name + \" (version \" + version + \")\"; // NOI18N\n                }\n                return name;\n            }\n            case POLYGLOT_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"info\"); // NOI18N\n            case INSTRUMENT_INFO_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n                String version = DetailsUtils.getInstanceFieldString(instance, \"version\"); // NOI18N\n\n                if (name != null && !name.isEmpty() && version != null && !version.isEmpty()) {\n                    return name + \" (version \" + version + \")\"; // NOI18N\n                }\n                if (name == null || name.isEmpty()) {\n                    return DetailsUtils.getInstanceFieldString(instance, \"id\"); // NOI18N\n                }\n                return name;\n            }\n            case NATIVE_ROOT_MASK:\n                return \"native call\"; // NOI18N\n            case NODE_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"sourceSection\");\n            case TSTRING_MASK: {\n                Instance next = instance;\n                do {\n                    String str = getString(next);\n                    if (str != null) {\n                        return str;\n                    }\n                    next = (Instance) next.getValueOfField(\"next\"); // NOI18N\n                } while (next != null && !instance.equals(next));\n                Object data = instance.getValueOfField(\"data\");\n                if (data instanceof PrimitiveArrayInstance) {\n                    Encoding encoding = getEncoding(instance);\n                    Byte stride = (Byte)instance.getValueOfField(\"stride\"); // NOI18N\n                    if (stride != null && encoding != null) {\n                        byte[] bytes = convertBytes((PrimitiveArrayInstance)data, encoding.naturalStride, stride);\n                        try {\n                            if (\"BYTES\".equals(encoding.name)) {\n                                return new String(bytes, \"ISO-8859-1\");\n                            }\n                            return new String(bytes, encoding.name);\n                        } catch (UnsupportedEncodingException ex) {\n                            try {\n                                return new String(bytes, encoding.name.replace('_', '-'));\n                            } catch (UnsupportedEncodingException ex1) {\n                                return new String(bytes);\n                            }\n                        }\n                    }\n                } else {\n                    return DetailsUtils.getInstanceString((Instance) data);\n                }\n                break;\n            }\n            case TS_LONG_MASK:\n                return String.valueOf(DetailsUtils.getLongFieldValue(instance, \"value\", 0));    // NOI18N\n            case TS_CONCAT_MASK: {\n                Object vall = instance.getValueOfField(\"left\");   // NOI18N\n                Object valr = instance.getValueOfField(\"right\");   // NOI18N\n                String left = DetailsUtils.getInstanceString((Instance)vall);\n\n                if (left == null) {\n                    return DetailsUtils.getInstanceString((Instance)valr);\n                }\n                if (valr == null || left.length() > DetailsUtils.MAX_ARRAY_LENGTH) {\n                    return left;\n                }\n                String value = left + DetailsUtils.getInstanceString((Instance)valr);\n\n                if (value.length() > DetailsUtils.MAX_ARRAY_LENGTH) {\n                    return value.substring(0, DetailsUtils.MAX_ARRAY_LENGTH) + \"...\"; // NOI18N\n                }\n                return value;\n            }\n            case LLVM_NODE_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"originalName\"); // NOI18N\n                if (name == null) name = DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n                return name;\n            }\n            case LLVM_FOREIGN_NODE_MASK: {\n                Instance classNode = (Instance) instance.getValueOfField(\"callNode\"); // NOI18N\n                if (classNode != null) {\n                    String value = DetailsUtils.getInstanceFieldString(classNode, \"callTarget\");    // NOI18N\n                    if (value != null) return \"LLVM: \"+value;        // NOI18N\n                }\n                break;\n            }\n            default:\n                break;\n        }\n        return null;\n    }\n\n    public View getDetailsView(String className, Instance instance) {\n        if (NODE_MASK.equals(className)) {\n            Object val = instance.getValueOfField(\"sourceSection\");  // NOI18N\n            if (val instanceof Instance) {\n                Instance sourceSection = (Instance) val;\n                return DetailsSupport.getDetailsView(sourceSection);\n            }\n        }\n        return null;\n    }\n\n    private String getString(Instance truffleString) {\n        Object data = truffleString.getValueOfField(\"data\");    // NOI18N\n        if (data instanceof Instance) {\n            Instance idata = (Instance) data;\n            if (idata.getJavaClass().getName().equals(String.class.getName())) {\n                return DetailsUtils.getInstanceString(idata);\n            }\n        }\n        return null;\n    }\n\n    private Encoding getEncoding(Instance truffleString) {\n        Byte encodingId = (Byte) truffleString.getValueOfField(\"encoding\"); // NOI18N\n\n        Map<Byte, Encoding> heapCache = getEncodingCache(truffleString);\n        Encoding cachedEncoding = heapCache.get(encodingId);\n        if (cachedEncoding == null && encodingId != null) {\n            Heap heap = truffleString.getJavaClass().getHeap();\n            JavaClass encodingClass = heap.getJavaClassByName(TS_ENCODING_CLASS);\n            for (Instance encoding : encodingClass.getInstances()) {\n                Byte id = (Byte) encoding.getValueOfField(\"id\");    // NOI18N\n\n                if (id.equals(encodingId)) {\n                    cachedEncoding = new Encoding(encoding);\n                    heapCache.put(encodingId, cachedEncoding);\n                }\n            }\n        }\n        return cachedEncoding;\n    }\n\n    private Map<Byte, Encoding> getEncodingCache(Instance truffleString) {\n        synchronized (CACHE_LOCK) {\n            if (CACHE == null) {\n                CACHE = new WeakHashMap();\n            }\n            Heap heap = truffleString.getJavaClass().getHeap();\n            Map<Byte, Encoding> heapCache = CACHE.get(heap);\n            if (heapCache == null) {\n                heapCache = Collections.synchronizedMap(new HashMap<>());\n                CACHE.put(heap, heapCache);\n            }\n            return heapCache;\n        }\n    }\n\n    private byte[] convertBytes(PrimitiveArrayInstance data, byte naturalStride, byte stride) {\n        int inCharSize = 1 << stride;\n        int outCharSize = 1 << naturalStride;\n        int padding = outCharSize - inCharSize;\n        byte[] bytes = new byte[(data.getLength() / inCharSize) * outCharSize];\n        List<String> values = data.getValues();\n        int op = 0;\n\n        for (int ip = 0; ip < values.size();) {\n            for (int j = 0; j < inCharSize; j++) {\n                bytes[op++] = Byte.valueOf(values.get(ip++));\n            }\n            op += padding;\n        }\n        return bytes;\n    }\n\n    private static class Encoding {\n\n        byte encId;\n        String name;\n        byte naturalStride;\n\n        Encoding(Instance encoding) {\n            encId = (Byte) encoding.getValueOfField(\"id\");  // NOI18N\n            name = DetailsUtils.getInstanceFieldString(encoding, \"name\");   // NOI18N\n            naturalStride = (Byte) encoding.getValueOfField(\"naturalStride\");   // NOI18N\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/dynamicobject/DynamicObject.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.dynamicobject;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveType;\nimport org.graalvm.visualvm.lib.jfluid.heap.Type;\nimport org.graalvm.visualvm.lib.jfluid.heap.Value;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic class DynamicObject extends TruffleObject.InstanceBased {\n\n    static final String DYNAMIC_OBJECT_FQN = \"com.oracle.truffle.api.object.DynamicObject\"; // NOI18N\n    private static final String LOCATION_FQN = \"com.oracle.truffle.api.object.Location\"; // NOI18N\n    private static final String ENTERPRISE_PACKAGE = \"com.oracle.truffle.object.enterprise\"; // NOI18N\n    private static final String ENTERPRISE_LOCATION_TOP_CLASS = ENTERPRISE_PACKAGE+\".EnterpriseLocations\"; // NOI18N\n    private static final String ENTERPRISE_FIELD_LOCATION_FQN = ENTERPRISE_LOCATION_TOP_CLASS+\"$FieldLocation\"; // NOI18N\n    private static final String ENTERPRISE_FIELD_INFO_FQN = ENTERPRISE_PACKAGE + \".EnterpriseLayout$FieldInfo\"; // NOI18N\n    private static final String PROPERTY_MAP_FQN = \"com.oracle.truffle.object.ConsListPropertyMap\"; // NOI18N\n    private static final String TRIE_PROPERTY_MAP_FQN = \"com.oracle.truffle.object.TriePropertyMap\"; // NOI18N\n    private static final String PROPERTY_FQN = \"com.oracle.truffle.object.PropertyImpl\"; // NOI18N\n    private static final String OBJECT_TYPE_FQN = \"com.oracle.truffle.api.object.ObjectType\"; // NOI18N\n\n    private final Instance instance;\n    \n    private Instance shape;\n    private String type;\n    \n    private long size = -1;\n    \n//    private List<Property> properties;\n    private List<FieldValue> values;\n    private List<FieldValue> staticValues;\n\n    public DynamicObject(Instance instance) {\n        this(null, instance);\n    }\n    \n    public DynamicObject(String type, Instance instance) {\n        if (instance == null) throw new IllegalArgumentException(\"Instance cannot be null\"); // NOI18N\n        \n        this.instance = instance;\n        this.type = type;\n    }\n    \n    @Override\n    public Instance getInstance() {\n        return instance;\n    }\n    \n    public List<FieldValue> getReferences() {\n        List<FieldValue> dynObjRefs = new ArrayList<>();\n\n        if (getShape() != null) {\n            List<Value> refs = instance.getReferences();\n            Set<Instance> foundRefs = new HashSet<>();\n\n            for (Value ref : refs) {\n                Instance instanceRef = ref.getDefiningInstance();\n                if (ref instanceof ObjectFieldValue) {\n                    if (foundRefs.add(instanceRef)) {\n                        addReferences(instanceRef, dynObjRefs);\n                    }\n                }\n                if (ref instanceof ArrayItemValue) {\n                    List<Value> arrRefs = instanceRef.getReferences();\n\n                    for (Value arrRef : arrRefs) {\n                        Instance arrInstanceRef = arrRef.getDefiningInstance();\n                        if (foundRefs.add(arrInstanceRef)) {\n                            addReferences(instanceRef, arrInstanceRef, dynObjRefs);\n                        }\n                    }\n                }\n            }\n        }\n        return Collections.unmodifiableList(dynObjRefs);\n    }\n\n    public List<FieldValue> getFieldValues() {\n        if (values == null) initFields();\n        return values;\n    }\n    \n    public FieldValue getFieldValue(String name) {\n        for (FieldValue value : getFieldValues())\n            if (name.equals(value.getField().getName()))\n                    return value;\n        return null;\n    }\n    \n    public FieldValue[] getFieldValues(String... names) {\n        FieldValue[] values = new FieldValue[names.length];\n        for (FieldValue value : getFieldValues())\n            for (int i = 0; i < names.length; i++)\n                if (names[i].equals(value.getField().getName()))\n                    values[i] = value;\n        return values;\n    }\n\n    public List<FieldValue> getStaticFieldValues() {\n        if (staticValues == null) initFields();\n        return staticValues;\n    }\n\n    public Instance getShape() {\n        if (shape == null) shape = getShape(instance);\n        return shape;\n    }\n    \n    public static Instance getShape(Instance instance) {\n        return (Instance)instance.getValueOfField(\"shape\"); // NOI18N\n    }\n    \n    @Override\n    public String getType() {\n        if (type == null) {\n            type = computeType();\n            if (type == null) type = \"<unknown type>\"; // NOI18N\n        }\n        return type;\n    }\n\n    @Override\n    public long getTypeId() {\n        return getShape().getInstanceId();\n    }\n    \n    protected String computeType() {\n        return DetailsSupport.getDetailsString(getShape());\n    }\n    \n    public static String getType(Instance instance) {\n        Instance shape = getShape(instance);\n        return DetailsSupport.getDetailsString(shape);\n    }\n    \n    @Override\n    public long getSize() {\n        if (size == -1) {\n            size = instance.getSize();\n\n            for (Object fv : instance.getFieldValues()) {\n                if (fv instanceof ObjectFieldValue) {\n                    ObjectFieldValue ofv = (ObjectFieldValue) fv;\n                    Instance value = ofv.getInstance();\n\n                    if (value instanceof ObjectArrayInstance) {\n                        size += value.getSize();\n                    }\n                    if (value instanceof PrimitiveArrayInstance) {\n                        size += value.getSize();\n                    }\n                }\n            }\n        }\n        return size;\n    }\n    \n    @Override\n    public long getRetainedSize() {\n        return instance.getRetainedSize();\n    }\n    \n    public JavaClass getLanguageId() {\n        return getLanguageIdFromShape(getShape());\n    }\n    \n    public static JavaClass getLanguageId(Instance instance) {\n        return getLanguageIdFromShape(getShape(instance));\n    }\n    \n    \n    \n    private void initFields() {\n        Instance propertyMap = getValueofFields(instance, \"shape\", \"fastMapRef\", \"referent\"); // NOI18N\n        if (propertyMap == null) propertyMap = getValueofFields(instance, \"shape\", \"propertyMap\"); // NOI18N\n        if (propertyMap != null) {\n//            properties = new ArrayList();\n            values = new ArrayList<>();\n            staticValues = new ArrayList<>();\n            boolean hasExtRef = hasField(instance.getJavaClass(), \"extRef\");    // NOI18N\n            boolean hasShortNames = hasField(instance.getJavaClass(), \"o0\");    // NOI18N\n\n            for (Instance ip : getMapValues(propertyMap)) {\n                Property p = new Property(ip, hasExtRef, hasShortNames);\n//                properties.add(p);\n                if (p.isStatic()) staticValues.add(p.getValue(instance));\n                else values.add(p.getValue(instance));\n            }\n        } else {\n            values = Collections.EMPTY_LIST;\n            staticValues = Collections.EMPTY_LIST;\n        }\n    }\n\n    private void addReferences(Instance instanceRef, List dynObjRefs) {\n        addReferences(null, instanceRef, dynObjRefs);\n    }\n\n    private void addReferences(Instance baseInstance, Instance instanceRef, List dynObjRefs) {\n        if (DynamicObject.isDynamicObject(instanceRef)) {\n            DynamicObject dynObj = new DynamicObject(instanceRef);\n\n            List<FieldValue> fieldValues = dynObj.getFieldValues();\n            for (FieldValue fieldVal : fieldValues) {\n                if (fieldVal instanceof ObjectFieldValue) {\n                    ObjectFieldValue fieldValObj = (ObjectFieldValue) fieldVal;\n\n                    if (instance.equals(fieldValObj.getInstance())) {\n                        dynObjRefs.add(fieldVal);\n                    }\n                    if (baseInstance != null && baseInstance.equals(fieldValObj.getInstance())) {\n                        dynObjRefs.add(fieldVal);\n                    }\n                }\n            }\n        }\n    }\n\n    private boolean hasField(JavaClass jcls, String name) {\n        List<Field> fields = jcls.getFields();\n\n        for (int i = fields.size()-1; i>=0; i--) {\n            Field f = fields.get(i);\n\n            if (f.getName().equals(name)) {\n                return true;\n            }\n        }\n        jcls = jcls.getSuperClass();\n        if (jcls != null) {\n            return hasField(jcls, name);\n        }\n        return false;\n    }\n\n    static JavaClass getLanguageIdFromShape(Instance sh) {\n        if (sh != null) {\n            Instance objectType = (Instance) sh.getValueOfField(\"objectType\"); // NOI18N\n            if (objectType != null) {\n                JavaClass objTypeCls = objectType.getJavaClass();\n\n                while (objTypeCls != null) {\n                    JavaClass superObjType = objTypeCls.getSuperClass();\n\n                    if (superObjType == null\n                       || OBJECT_TYPE_FQN.equals(superObjType.getName())\n                       || Object.class.getName().equals(superObjType.getName())) {\n                        return objTypeCls;\n                    }\n                    objTypeCls = superObjType;\n                }\n            }\n        }\n        return null;\n    }\n\n    private static Instance getValueofFields(Instance instance, String... fields) {\n        if (instance != null) {\n            for (String field : fields) {\n                Object val = instance.getValueOfField(field);\n                if (val == null || !(val instanceof Instance)) {\n                    return null;\n                }\n                instance = (Instance) val;\n            }\n        }\n        return instance;\n    }\n\n    private static List<Instance> getMapValues(Instance propertyMap) {\n        if (propertyMap != null) {\n            String mapClass = propertyMap.getJavaClass().getName();\n            if (mapClass.equals(HashMap.class.getName())) {\n                return getHashMapValues(propertyMap);\n            }\n            if (mapClass.equals(PROPERTY_MAP_FQN)) {\n                return getConsListValues(propertyMap);\n            }\n            if (mapClass.equals(TRIE_PROPERTY_MAP_FQN)) {\n                return getTrieValues(propertyMap);\n            }\n        }\n        return null;\n    }\n\n    private static List<Instance> getHashMapValues(Instance propertyMap) {\n        List<Instance> mapValues = new ArrayList<>();\n        Object val = propertyMap.getValueOfField(\"table\");  // NOI18N\n\n        if (val != null && val instanceof ObjectArrayInstance) {\n            ObjectArrayInstance table = (ObjectArrayInstance) val;\n\n            for (Object el : table.getValues()) {\n                for (Instance node = (Instance) el; node != null; node = (Instance) node.getValueOfField(\"next\")) {    // NOI18N\n                    Object value = node.getValueOfField(\"value\");   // NOI18N\n\n                    if (value != null && value instanceof Instance) {\n                        mapValues.add((Instance) value);\n                    }\n                }\n            }\n        }\n        return mapValues;\n    }\n\n    private static List<Instance> getConsListValues(Instance propertyMap) {\n        List<Instance> mapValues = new ArrayList<>();\n\n        for (Instance node = propertyMap; node != null; node = (Instance) node.getValueOfField(\"car\")) {    // NOI18N\n            Object value = node.getValueOfField(\"cdr\"); // NOI18N\n\n            if (value != null && value instanceof Instance) {\n                mapValues.add((Instance) value);\n            }\n        }\n        return mapValues;\n    }\n\n    private static List<Instance> getTrieValues(Instance propertyMap) {\n        List<Instance> mapValues = new ArrayList<>();\n        Object root = propertyMap.getValueOfField(\"root\");  // NOI18N\n\n        getNodeValues(root, mapValues);\n        return mapValues;\n    }\n\n    private static boolean getNodeValues(Object nodeObject, List<Instance>nodeValues) {\n        if (nodeObject instanceof Instance) {\n            Instance node = (Instance) nodeObject;\n            Object entries = node.getValueOfField(\"entries\");  // NOI18N\n\n            if (entries instanceof ObjectArrayInstance) {\n                ObjectArrayInstance table = (ObjectArrayInstance) entries;\n\n                for (Instance entry : table.getValues()) {\n                    if (!getNodeValues(entry, nodeValues)) {\n                        Object value = entry.getValueOfField(\"value\");  // NOI18N\n                        if (value instanceof Instance) {\n                            nodeValues.add((Instance) value);\n                        }\n                    }\n                }\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private static String getShortInstanceId(Instance instance) {\n        if (instance == null) {\n            return \"null\";  // NOI18N\n        }\n        String name = instance.getJavaClass().getName();\n        int last = name.lastIndexOf('.'); // NOI18N\n\n        if (last != -1) {\n            name = name.substring(last + 1);\n        }\n        return name + \"#\" + instance.getInstanceNumber();   // NOI18N\n    }\n\n    private static boolean isSubClassOf(Instance i, String superClassName) {\n        if (i != null) {\n            JavaClass superCls = i.getJavaClass().getSuperClass();\n\n            for (; superCls != null; superCls = superCls.getSuperClass()) {\n                if (superCls.getName().equals(superClassName)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    public static boolean isDynamicObject(Instance dynObj) {\n        return isSubClassOf(dynObj, DYNAMIC_OBJECT_FQN);\n    }\n\n    public static boolean hasDynamicObject(Heap heap) {\n        JavaClass dynClass = heap.getJavaClassByName(DYNAMIC_OBJECT_FQN);\n\n        return dynClass != null;\n    }\n\n    private static boolean isLocationObjSubClass(Instance dynObj) {\n        return isSubClassOf(dynObj, LOCATION_FQN);\n    }\n\n    private static boolean isEterpriseFieldLocationObjSubClass(Instance dynObj) {\n        return isSubClassOf(dynObj, ENTERPRISE_FIELD_LOCATION_FQN);\n    }\n\n    private static boolean isEterpriseFieldInfoObjSubClass(Instance dynObj) {\n        if (dynObj != null)\n            return ENTERPRISE_FIELD_INFO_FQN.equals(dynObj.getJavaClass().getName());\n        return false;\n    }\n\n    private static boolean hasFieldInfo(Instance loc) {\n        for (FieldValue fv : loc.getFieldValues()) {\n            if (fv instanceof ObjectFieldValue) {\n                Instance fi = ((ObjectFieldValue)fv).getInstance();\n                if (isEterpriseFieldInfoObjSubClass(fi)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    private static class Property implements Field {\n\n        Instance property;\n        Instance location;\n        String propertyName;\n        boolean isStatic;\n        boolean hasExtRef;\n        boolean hasShortNames;\n\n        private Property(Instance p, boolean extRef, boolean shortNames) {\n            assert p.getJavaClass().getName().equals(PROPERTY_FQN);\n            property = p;\n            propertyName = DetailsUtils.getInstanceString(p);\n            location = (Instance) property.getValueOfField(\"location\"); // NOI18N\n            hasExtRef = extRef;\n            hasShortNames = shortNames;\n        }\n\n        String getPropertyName() {\n            return propertyName;\n        }\n\n        FieldValue getValue(Instance dynamicObject) {\n            return getValueImpl(location, dynamicObject);\n        }\n\n        FieldValue getValueImpl(Instance loc, final Instance dynamicObject) {\n            JavaClass locClass = loc.getJavaClass();\n            final String className = locClass.getName();\n\n            if (className.contains(\"Constant\")) {   // NOI18N\n                isStatic = true;\n                return getInstanceFieldValue(dynamicObject, loc, \"value\");  // NOI18N\n            }\n            if (className.contains(\"Declared\")) {   // NOI18N\n                isStatic = true;\n                return getInstanceFieldValue(dynamicObject, loc, \"value\");  // NOI18N\n            }\n            if (className.startsWith(ENTERPRISE_PACKAGE)) {\n                FieldValue val = getEnterpriseValue(loc,className,dynamicObject);\n\n                if (val != null) {\n                    return val;\n                }\n            } else {\n                if (className.endsWith(\"Decorator\")) {  // NOI18N\n                    Instance actualLoc = (Instance) loc.getValueOfField(\"longLocation\");    // NOI18N\n                    FieldValue longValue = getValueImpl(actualLoc, dynamicObject);\n                    String valString = longValue.getValue();\n\n                    if (className.contains(\"DoubleLocation\")) { // NOI18N\n                        Double d = Double.longBitsToDouble(Long.parseLong(valString));\n                        valString = d.toString();\n                    }\n                    if (className.contains(\"BooleanLocation\")) {    // NOI18N\n                        valString = Boolean.toString(Long.parseLong(valString) != 0);\n                    }\n                    return getFieldValue(dynamicObject, valString);\n                }\n                if (className.contains(\"ObjectArrayLocation\")) {    // NOI18N\n                    Integer index = (Integer) loc.getValueOfField(\"index\"); // NOI18N\n                    // Instance actualLoc = (Instance) loc.getValueOfField(\"arrayLocation\");\n                    ObjectArrayInstance arr = getObjectStore(dynamicObject);\n\n                    return getObjectFieldValue(dynamicObject, arr.getValues().get(index));\n                }\n                if (className.contains(\"LongArrayLocation\")) {  // NOI18N\n                    Integer index = (Integer) loc.getValueOfField(\"index\"); // NOI18N\n                    // Instance actualLoc = (Instance) loc.getValueOfField(\"arrayLocation\");\n                    PrimitiveArrayInstance arr;\n                    if (hasExtRef) {\n                        // extVal is int[]\n                        arr = (PrimitiveArrayInstance) dynamicObject.getValueOfField(\"extVal\"); // NOI18N\n                        return getFieldValue(dynamicObject, Long.toString(getLong(arr, index)));\n                    } else {\n                        // primext is long[]\n                        arr = (PrimitiveArrayInstance) dynamicObject.getValueOfField(\"primext\"); // NOI18N\n                        return getFieldValue(dynamicObject, arr.getValues().get(index));\n                    }\n                }\n            }\n            String superClassName = locClass.getSuperClass().getName();\n            if (superClassName.contains(\"SimpleObjectFieldLocation\")) { // NOI18N\n                Integer index = (Integer) loc.getValueOfField(\"index\"); // NOI18N\n                return getObjectInstanceFieldValue(dynamicObject, index);\n            }\n            if (superClassName.contains(\"SimpleLongFieldLocation\")) {   // NOI18N\n                Integer index = (Integer) loc.getValueOfField(\"index\"); // NOI18N\n                return getPrimitiveInstanceFieldValue(dynamicObject, index);\n            }\n            if (superClassName.contains(\"BasicObjectFieldLocation\")) { // NOI18N\n                Integer index = (Integer) loc.getValueOfField(\"index\"); // NOI18N\n                return getObjectInstanceFieldValue(dynamicObject, index);\n            }\n            if (superClassName.contains(\"BasicLongFieldLocation\")) {   // NOI18N\n                Integer index = (Integer) loc.getValueOfField(\"index\"); // NOI18N\n                return getPrimitiveInstanceFieldValue(dynamicObject,index);\n            }\n            return new DynObjFieldValue(dynamicObject, this) {\n                @Override\n                public String getValue() {\n                    return \"Not implemented for \" + className; // NOI18N\n                }\n            };\n        }\n\n        private ObjectArrayInstance getObjectStore(final Instance dynamicObject) {\n            String fieldName = hasExtRef ? \"extRef\" : \"objext\"; // NOI18N\n\n            return (ObjectArrayInstance) dynamicObject.getValueOfField(fieldName);\n        }\n\n        private FieldValue getObjectInstanceFieldValue(Instance dynObj, int index) {\n            String fieldName = getObjectFieldName(index);\n            return getInstanceFieldValue(dynObj, dynObj, fieldName);\n        }\n\n        private FieldValue getPrimitiveInstanceFieldValue(Instance dynObj, int index) {\n            String fieldName = getPrimitiveFieldName(index);\n            return getInstanceFieldValue(dynObj, dynObj, fieldName);\n        }\n\n        private FieldValue getInstanceFieldValue(Instance dynObj, String fieldName) {\n            return getInstanceFieldValue(dynObj, dynObj, fieldName);\n        }\n\n        private FieldValue getInstanceFieldValue(Instance dynObj, Instance i, String fieldName) {\n            for (FieldValue fieldValue : i.getFieldValues()) {\n\n                if (fieldValue.getField().getName().equals(fieldName)) {\n                    return createFieldValue(dynObj, fieldValue);\n                }\n            }\n            return null;\n        }\n\n        @Override\n        public boolean isStatic() {\n            return isStatic;\n        }\n\n        @Override\n        public JavaClass getDeclaringClass() {\n            throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n        }\n\n        @Override\n        public String getName() {\n            return propertyName;\n        }\n\n        @Override\n        public Type getType() {\n            String locationClassName = location.getJavaClass().getName();\n            if (locationClassName.contains(\"Object\")) {  // NOI18N\n                return ObjType.OBJECT;\n            }\n            if (locationClassName.contains(\"Boolean\")) {  // NOI18N\n                return PType.BOOLEAN;\n            }\n            if (locationClassName.contains(\"Byte\")) {  // NOI18N\n                return PType.BYTE;\n            }\n            if (locationClassName.contains(\"Char\")) {  // NOI18N\n                return PType.CHAR;\n            }\n            if (locationClassName.contains(\"Double\")) {  // NOI18N\n                return PType.DOUBLE;\n            }\n            if (locationClassName.contains(\"Float\")) {  // NOI18N\n                return PType.FLOAT;\n            }\n            if (locationClassName.contains(\"Int\")) {  // NOI18N\n                return PType.INT;\n            }\n            if (locationClassName.contains(\"Long\")) {  // NOI18N\n                return PType.LONG;\n            }\n            if (locationClassName.contains(\"Short\")) {  // NOI18N\n                return PType.SHORT;\n            }\n            return ObjType.OBJECT;\n            // throw new IllegalArgumentException(locationClassName);\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof Property) {\n                Property p = (Property) obj;\n\n                return property.equals(p.property);\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            return property.hashCode();\n        }\n\n        private FieldValue createFieldValue(final Instance i, final FieldValue fieldValue) {\n            if (fieldValue instanceof ObjectFieldValue) {\n                return new DynObjObjectFieldValue(i, this) {\n                    @Override\n                    public Instance getInstance() {\n                        return ((ObjectFieldValue) fieldValue).getInstance();\n                    }\n                    @Override\n                    public String getValue() {\n                        return fieldValue.getValue();\n                    }\n                };\n            }\n            return new DynObjFieldValue(i, this) {\n                @Override\n                public String getValue() {\n                    return fieldValue.getValue();\n                }\n            };\n        }\n\n        private FieldValue getFieldValue(final Instance dynamicObject, final String value) {\n            return new DynObjFieldValue(dynamicObject, this) {\n                @Override\n                public String getValue() {\n                    return value;\n                }\n            };\n        }\n\n        private ObjectFieldValue getObjectFieldValue(final Instance dynamicObject, final Instance value) {\n            return new DynObjObjectFieldValue(dynamicObject, this) {\n                @Override\n                public Instance getInstance() {\n                    return value;\n                }\n\n                @Override\n                public String getValue() {\n                    return String.valueOf(value.getInstanceId());\n                }\n            };\n        }\n\n        private FieldValue getEnterpriseValue(Instance loc, String className, Instance dynamicObject) {\n            if (className.length()-ENTERPRISE_PACKAGE.length() < 5) {   // obfuscated enterprise classes\n                return getObfuscatedEnperpriseValue(loc, className, dynamicObject);\n            }\n            if (className.length()-ENTERPRISE_LOCATION_TOP_CLASS.length() < 4) { // obfuscated enterprise inner classes\n                return getObfuscatedEnperpriseValue(loc, className, dynamicObject);\n            }\n            if (className.endsWith(\"Decorator\")) {  // NOI18N\n                Instance actualLoc = (Instance) loc.getValueOfField(\"actualLocation\");  // NOI18N\n                return getValueImpl(actualLoc, dynamicObject);\n            }\n            if (className.contains(\"ObjectFieldLocation\")               // NOI18N\n                || className.contains(\"ExtensionArrayLocation\")) {      // NOI18N\n                String fName = getEnterpriseObjectFieldName(loc);\n                FieldValue ret = getInstanceFieldValue(dynamicObject, fName);\n                if (ret == null) {\n                    // extVal is encoded as non-existing index\n                    return getObjectFieldValue(dynamicObject, (Instance) dynamicObject.getValueOfField(\"extVal\"));  // NOI18N\n                }\n                return ret;\n            }\n            if (className.contains(\"IntFieldLocation\")) { // NOI18N\n                String fName = getEnterprisePrimitiveFieldName(loc);\n                return getInstanceFieldValue(dynamicObject, fName);\n            }\n            if (className.contains(\"BooleanFieldLocation\")) {   // NOI18N\n                String fName = getEnterprisePrimitiveFieldName(loc);\n                Integer i1 = (Integer) dynamicObject.getValueOfField(fName);\n                return getFieldValue(dynamicObject, Boolean.toString(i1.intValue() != 0));\n            }\n            if (className.contains(\"DoubleFieldLocation\")        // NOI18N\n                || className.contains(\"LongFieldLocation\")) {    // NOI18N\n                String fName = getEnterprisePrimitiveFieldName(loc);\n                Number i1 = (Number) dynamicObject.getValueOfField(fName);\n                long val;\n                String valString;\n\n                if (i1 instanceof Long) {\n                    val = i1.longValue();\n                } else {\n                    Integer i2 = (Integer) getValueOfNextField(dynamicObject, fName);\n                    val = getLong(i1.intValue(), i2);\n                }\n                if (className.contains(\"LongFieldLocation\")) {      // NOI18N\n                    valString = Long.toString(val);\n                } else {\n                    valString = getDouble(val);\n                }\n                return getFieldValue(dynamicObject, valString);\n            }\n            if (className.contains(\"ObjectArrayLocation\")) {    // NOI18N\n                Integer index = (Integer) loc.getValueOfField(\"index\"); // NOI18N\n                ObjectArrayInstance arr = getEnterpriseObjectStore(dynamicObject);\n                return getObjectFieldValue(dynamicObject, arr.getValues().get(index));\n            }\n            if (className.contains(\"IntArrayLocation\")) {   // NOI18N\n                Integer index = (Integer) loc.getValueOfField(\"index\"); // NOI18N\n                PrimitiveArrayInstance arr = getPrimitiveArray(loc, dynamicObject);\n                return getFieldValue(dynamicObject, arr.getValues().get(index));\n            }\n            if (className.contains(\"DoubleArrayLocation\")) {    // NOI18N\n                Integer index = (Integer) loc.getValueOfField(\"index\"); // NOI18N\n                PrimitiveArrayInstance arr = getPrimitiveArray(loc, dynamicObject);\n                return getFieldValue(dynamicObject, getDouble(getLong(arr, index)));\n            }\n            if (className.contains(\"LongArrayLocation\")) {    // NOI18N\n                Integer index = (Integer) loc.getValueOfField(\"index\"); // NOI18N\n                PrimitiveArrayInstance arr = getPrimitiveArray(loc, dynamicObject);\n                return getFieldValue(dynamicObject, Long.toString(getLong(arr, index)));\n            }\n            return null;\n        }\n\n        private PrimitiveArrayInstance getPrimitiveArray(Instance loc, Instance dynamicObject) {\n            Instance actualLoc = (Instance) loc.getValueOfField(\"arrayLocation\");   // NOI18N\n            PrimitiveArrayInstance arr;\n            if (actualLoc == null) {\n                arr =  (PrimitiveArrayInstance) dynamicObject.getValueOfField(\"extVal\");    // NOI18N\n            } else {\n                ObjectFieldValue arrayVal = (ObjectFieldValue) getValueImpl(actualLoc, dynamicObject);\n                arr = (PrimitiveArrayInstance)arrayVal.getInstance();\n            }\n            return arr;\n        }\n\n        private Object getValueOfNextField(Instance dynamicObject, String fieldName) {\n            int i = fieldName.length()-1;\n            for (; i>=0 && Character.isDigit(fieldName.charAt(i)); i--);\n            assert i < fieldName.length()-1 : \"Invalid fname \"+fieldName;\n            int fIndex = Integer.parseInt(fieldName.substring(++i));\n\n            return dynamicObject.getValueOfField(fieldName.substring(0,i)+(fIndex+1));\n        }\n\n        private String getEnterpriseObjectFieldName(Instance location) {\n            String fName = getEnterpriseFieldNameFromFieldInfo(location);\n            if (fName == null) {\n                Integer index = (Integer) location.getValueOfField(\"index\"); // NOI18N\n                int objectIndex = hasExtRef ? index : index + 2;\n                String prefix = hasShortNames ? \"o\" : \"object\";         // NOI18N\n                fName = prefix + objectIndex;\n            }\n            return fName;\n        }\n\n        private String getEnterprisePrimitiveFieldName(Instance location) {\n            String fName = getEnterpriseFieldNameFromFieldInfo(location);\n            if (fName == null) {\n                Integer index = (Integer) location.getValueOfField(\"index\"); // NOI18N\n                int objectIndex = hasExtRef ? index : index + 1;\n                String prefix = hasShortNames ? \"p\" : \"primitive\";      // NOI18N\n                fName = prefix + objectIndex;\n            }\n            return fName;\n        }\n\n        private String getEnterpriseFieldNameFromFieldInfo(Instance location) {\n            Object fieldInfo = location.getValueOfField(\"field\");     // NOI18N\n            if (fieldInfo instanceof Instance) {\n                for (Object fv : ((Instance)fieldInfo).getFieldValues()) {\n                    if (fv instanceof ObjectFieldValue) {\n                        Instance ifv = ((ObjectFieldValue)fv).getInstance();\n                        if (String.class.getName().equals(ifv.getJavaClass().getName())) {\n                            return DetailsSupport.getDetailsString(ifv);\n                        }\n                    }\n                }\n            }\n            return null;\n        }\n\n        private ObjectArrayInstance getEnterpriseObjectStore(Instance dynamicObject) {\n            String fieldName = hasExtRef ? \"extRef\" : \"object1\"; // NOI18N\n\n            return (ObjectArrayInstance) dynamicObject.getValueOfField(fieldName);\n        }\n\n        private FieldValue getObfuscatedEnperpriseValue(Instance loc, String className, Instance dynamicObject) {\n            List<FieldValue> fields = loc.getFieldValues();\n\n            if (fields.size() == 2) {\n                FieldValue v0 = fields.get(0);\n                FieldValue v1 = fields.get(1);\n                Type t0 = v0.getField().getType();\n                Type t1 = v1.getField().getType();\n\n                if (t0.getName().equals(\"object\") && t1.getName().equals(\"object\")) { // Decorator  // NOI18N\n                    Instance i0 = ((ObjectFieldValue)v0).getInstance();\n                    Instance i1 = ((ObjectFieldValue)v1).getInstance();\n\n                    if (isLocationObjSubClass(i0)) {\n                        return getValueImpl(i0, dynamicObject);\n                    }\n                    if (isLocationObjSubClass(i1)) {\n                        return getValueImpl(i1, dynamicObject);\n                    }\n                }\n            }\n            if (loc.getValueOfField(\"arrayLocation\") != null && loc.getValueOfField(\"index\") != null) { // NOI18N\n                Integer index = (Integer) loc.getValueOfField(\"index\"); // NOI18N\n                Instance actualLoc = (Instance) loc.getValueOfField(\"arrayLocation\");   // NOI18N\n                Boolean allowInt = (Boolean) loc.getValueOfField(\"allowInt\");   // NOI18N\n\n                return getObfuscatedEnterpriseArrayLocation(dynamicObject, index, actualLoc, allowInt);\n            }\n            if (loc.getValueOfField(\"index\") != null && loc.getValueOfField(\"offset\") != null) {    // NOI18N\n                Integer index = (Integer)loc.getValueOfField(\"index\");   // NOI18N\n                Instance type = (Instance)loc.getValueOfField(\"type\");   // NOI18N\n                Boolean allowInt = (Boolean) loc.getValueOfField(\"allowInt\");   // NOI18N\n\n                return getObfuscatedEnterpriseFieldLocation(dynamicObject, loc, index, type, allowInt);\n            }\n            if (isEterpriseFieldLocationObjSubClass(loc) && loc.getValueOfField(\"offset\") != null) {   // NOI18N\n                Integer locIndex = null;\n                Instance locType = null;\n                Boolean locAllowInt = null;\n\n                for (Object obj : fields) {\n                    FieldValue fv = (FieldValue) obj;\n                    Field f = fv.getField();\n                    String typeName = f.getType().getName();\n\n                    if (\"object\".equals(typeName) && !f.getName().equals(\"tclass\")) {   // NOI18N\n                        locType = ((ObjectFieldValue)fv).getInstance();\n                    }\n                    if (\"boolean\".equals(typeName) && fields.size()==3 && f.getDeclaringClass().getSubClasses().size()==1) {\n                        locAllowInt = (Boolean) loc.getValueOfField(f.getName());\n                    }\n                    if (\"int\".equals(typeName) && !f.getName().equals(\"offset\")) {   // NOI18N\n                        locIndex = (Integer) loc.getValueOfField(f.getName());\n                    }\n                }\n                if (locIndex != null) {\n                    return getObfuscatedEnterpriseFieldLocation(dynamicObject, loc, locIndex, locType, locAllowInt);\n                }\n            }\n            if (hasFieldInfo(loc)) {\n                Integer locIndex = null;\n                Instance finfo = null;\n                Boolean locAllowInt = null;\n\n                for (Object obj : fields) {\n                    FieldValue fv = (FieldValue) obj;\n                    Field f = fv.getField();\n                    String typeName = f.getType().getName();\n\n                    if (\"object\".equals(typeName)) {   // NOI18N\n                        Instance val = ((ObjectFieldValue)fv).getInstance();\n                        if (isEterpriseFieldInfoObjSubClass(val)) {\n                            finfo = val;\n                        }\n                    } else if (\"boolean\".equals(typeName) && fields.size()==3 && f.getDeclaringClass().getSubClasses().size()==1) {\n                        locAllowInt = (Boolean) loc.getValueOfField(f.getName());\n                    } else if (\"int\".equals(typeName)) {   // NOI18N\n                        locIndex = (Integer) loc.getValueOfField(f.getName());\n                    }\n                }\n                if (locIndex != null && finfo != null) {\n                    return getObfuscatedEnterpriseFieldLocation(dynamicObject, loc, locIndex, finfo, locAllowInt);\n                }\n            }\n            if (fields.size() >= 2) {\n                // ArrayLocation\n                Integer locIndex = null;\n                Instance locArrayLocation = null;\n                Boolean locAllowInt = null;\n\n                for (Object obj : fields) {\n                    FieldValue fv = (FieldValue) obj;\n                    Field f = fv.getField();\n                    String typeName = f.getType().getName();\n\n                    if (\"object\".equals(typeName)) {   // NOI18N\n                        Instance val = ((ObjectFieldValue)fv).getInstance();\n                        if (isLocationObjSubClass(val)) {\n                            locArrayLocation = val;\n                        }\n                    } else if (\"boolean\".equals(typeName) && fields.size()==3 && f.getDeclaringClass().getSubClasses().size()==2) {\n                        locAllowInt = (Boolean) loc.getValueOfField(f.getName());\n                    } else if (\"int\".equals(typeName)) {   // NOI18N\n                        locIndex = (Integer) loc.getValueOfField(f.getName());\n                    }\n                }\n                if (locIndex != null) {\n                    return getObfuscatedEnterpriseArrayLocation(dynamicObject, locIndex, locArrayLocation, locAllowInt);\n                }\n            }\n            if (fields.size() == 1) {\n                // obfuscated static property location\n                isStatic = true;\n                FieldValue staticFieldVal = fields.get(0);\n                return createFieldValue(dynamicObject, staticFieldVal);\n            }\n            return null;\n        }\n\n        private FieldValue getObfuscatedEnterpriseArrayLocation(Instance dynamicObject, Integer index, Instance actualLoc, Boolean allowInt) {\n            Instance array;\n            if (actualLoc != null) {\n                ObjectFieldValue arrayVal = (ObjectFieldValue) getValueImpl(actualLoc, dynamicObject);\n                array = arrayVal.getInstance();\n            } else {\n                array = getEnterpriseObjectStore(dynamicObject);\n            }\n            if (array instanceof PrimitiveArrayInstance) {\n                PrimitiveArrayInstance arr = (PrimitiveArrayInstance) array;\n                if (allowInt != null) {\n                    // long, double\n                    return getFieldValue(dynamicObject, getDouble(getLong(arr, index)));\n                }\n                return getFieldValue(dynamicObject, arr.getValues().get(index));\n            }\n            if (array instanceof ObjectArrayInstance) {\n                ObjectArrayInstance arr = (ObjectArrayInstance) array;\n                return getObjectFieldValue(dynamicObject, arr.getValues().get(index));\n            }\n            return null;\n        }\n\n        private FieldValue getObfuscatedEnterpriseFieldLocation(Instance dynamicObject, Instance loc, Integer index, Instance field_type, Boolean allowInt) {\n            Instance type = field_type;\n            if (isEterpriseFieldInfoObjSubClass(field_type)) {\n                String fieldName = null;\n                JavaClass fieldType = null;\n                for (FieldValue fv : field_type.getFieldValues()) {\n                    if (fv instanceof ObjectFieldValue) {\n                        Instance val = ((ObjectFieldValue)fv).getInstance();\n                        if (val == null) continue;\n                        String valName = val.getJavaClass().getName();\n                        if (valName.equals(String.class.getName())) {\n                            fieldName = DetailsSupport.getDetailsString(val);\n                        } else if (\"tclass\".equals(fv.getField().getName())) {\n                            type = val;\n                        } else if (valName.equals(Class.class.getName())) {\n                            fieldType = val.getJavaClass().getHeap().getJavaClassByID(val.getInstanceId());\n                        }\n                    }\n                }\n                assert type.getInstanceId() == dynamicObject.getJavaClass().getJavaClassId();\n                if (fieldName != null)\n                    return getDynamicObjectField(dynamicObject, fieldName, fieldType);\n            }\n            if (type != null) { // TypedObjectFieldLocation\n                if (index.intValue() == 0) { // test for type Object[]\n                    long typeClassId = type.getInstanceId();  // NOI18N\n                    ObjectFieldValue val = (ObjectFieldValue) getDynamicObjectField(dynamicObject, index+1);\n                    Instance value = val.getInstance();\n                    if (value != null) {\n                        // test for the same class as type or subclasses\n                        for (JavaClass valueClass = value.getJavaClass(); valueClass != null; valueClass = valueClass.getSuperClass()) {\n                            if (valueClass.getJavaClassId() == typeClassId) {\n                                // special case for detecting EnterpriseLayout.objectArrayLocation\n                                if (isLayoutObjectArrayLocation(loc, valueClass, dynamicObject)) break;\n                                return val;\n                            }\n                        }\n                    }\n                    // we should have Object[]\n                    ObjectFieldValue valarr = (ObjectFieldValue) getDynamicObjectField(dynamicObject, index);\n                    Instance valueArr = valarr.getInstance();\n                    if (valueArr != null) {\n                        // test for Object[]\n                        if (valueArr.getJavaClass().getJavaClassId() == typeClassId) {\n                            return valarr;\n                        }\n                    }\n                    // fallback in case \"type\" is interface\n                    return val;\n                }\n                return getDynamicObjectField(dynamicObject, index+1);\n            }\n            if (loc.getFieldValues().size() > 2) {\n                if (allowInt != null) {\n                    // primitive FieldLocation, long double\n                    FieldValue fv1 = getDynamicObjectPrimitiveField(dynamicObject, index);\n                    FieldValue fv2 = getDynamicObjectPrimitiveField(dynamicObject, index+1);\n                    Integer i1 = Integer.valueOf(fv1.getValue());\n                    Integer i2 = Integer.valueOf(fv2.getValue());\n                    return getFieldValue(dynamicObject, getDouble(getLong(i1, i2)));\n                }\n                if (loc.getFieldValues().size() == 3 && loc.getValueOfField(\"tclass\") != null) {\n                    // primitive FieldLocation\n                    return getDynamicObjectPrimitiveField(dynamicObject, index);\n                }\n                // ObjectFieldLocation without type\n                return getDynamicObjectField(dynamicObject, index+1);\n            }\n            // primitive FieldLocation\n            return getDynamicObjectPrimitiveField(dynamicObject, index);\n        }\n\n        private boolean isLayoutObjectArrayLocation(Instance location, JavaClass valueClass, Instance dynamicObject) {\n            if (valueClass.isArray() && \"java.lang.Object[]\".equals(valueClass.getName())) {\n                Instance layout = (Instance) DynamicObject.getShape(dynamicObject).getValueOfField(\"layout\");\n                for (Object fv : layout.getFieldValues()) {\n                    if (fv instanceof ObjectFieldValue) {\n                        if (location.equals(((ObjectFieldValue) fv).getInstance())) {\n                            return true;\n                        }\n                    }\n                }\n            }\n            return false;\n        }\n\n        private FieldValue getDynamicObjectField(Instance dynamicObject, String fname, JavaClass fieldType) {\n             for (FieldValue fv : dynamicObject.getFieldValues()) {\n                 if (fv.getField().getName().equals(fname)) {\n                     return createFieldValue(dynamicObject, fv);\n                 }\n             }\n             throw new IllegalArgumentException(fname);\n        }\n\n        private FieldValue getDynamicObjectPrimitiveField(Instance dynamicObject, int index) {\n            return getDynamicObjectField(dynamicObject, index, false);\n        }\n\n        private FieldValue getDynamicObjectField(Instance dynamicObject, int index) {\n            return getDynamicObjectField(dynamicObject, index, true);\n        }\n\n        private FieldValue getDynamicObjectField(Instance dynamicObject, int index, boolean objectType) {\n            List<Field> fields = dynamicObject.getJavaClass().getFields();\n\n            for (int i = fields.size()-1; i>=0; i--) {\n                Field f = fields.get(i);\n\n                if (f.getType().getName().equals(\"object\") == objectType) { // NOI18N\n                    if (index == 0) {\n                        return createFieldValue(dynamicObject, getValueOfField(dynamicObject, f));\n                    }\n                    index--;\n                }\n            }\n            throw new IllegalArgumentException();\n        }\n\n        private FieldValue getValueOfField(Instance dynamicObject, Field field) {\n             List<FieldValue> fieldVals = dynamicObject.getFieldValues();\n\n             for (FieldValue fv : fieldVals) {\n\n                 if (fv.getField().equals(field)) {\n                     return fv;\n                 }\n             }\n             throw new IllegalArgumentException(field.getName());\n        }\n\n        private static long getLong(Integer i1, Integer i2) {\n            return i2.longValue()<<32 | (i1.longValue() & 0xFFFFFFFFL);\n        }\n\n        private static long getLong(PrimitiveArrayInstance arr, int index) {\n            List<String> vals = arr.getValues();\n            Integer i1 = Integer.valueOf(vals.get(index));\n            Integer i2 = Integer.valueOf(vals.get(index+1));\n\n            return getLong(i1, i2);\n        }\n\n        private static String getDouble(long l) {\n            double d = Double.longBitsToDouble(l);\n\n            return Double.toString(d);\n        }\n\n        private String getObjectFieldName(int index) {\n            if (hasShortNames) {\n                return \"o\"+(index);     // NOI18N\n            }\n            return \"object\"+(index+1);  // NOI18N\n        }\n\n        private String getPrimitiveFieldName(int index) {\n            if (hasShortNames) {\n                return \"p\"+(index); // NOI18N\n            }\n            return \"primitive\"+(index+1);   // NOI18N\n        }\n    }\n\n    private static class ObjType implements Type {\n\n        static final Type OBJECT = new ObjType();\n\n        @Override\n        public String getName() {\n            return \"object\";    // NOI18N\n        }\n\n    }\n\n    private static class PType implements PrimitiveType {\n\n        static final PrimitiveType BOOLEAN = new PType(\"boolean\"); //NOI18N\n        static final PrimitiveType CHAR = new PType(\"char\"); //NOI18N\n        static final PrimitiveType FLOAT = new PType(\"float\"); //NOI18N\n        static final PrimitiveType DOUBLE = new PType(\"double\"); //NOI18N\n        static final PrimitiveType BYTE = new PType(\"byte\"); //NOI18N\n        static final PrimitiveType SHORT = new PType(\"short\"); //NOI18N\n        static final PrimitiveType INT = new PType(\"int\"); //NOI18N\n        static final PrimitiveType LONG = new PType(\"long\"); //NOI18N\n\n        private String name;\n\n        PType(String n) {\n            name = n;\n        }\n\n        @Override\n        public String getName() {\n            return name;\n        }\n    }\n\n    private abstract static class DynObjFieldValue implements FieldValue {\n        Instance definingInstance;\n        Property field;\n\n        private DynObjFieldValue(Instance i, Property p) {\n            definingInstance = i;\n            field = p;\n        }\n\n        @Override\n        public Field getField() {\n            return field;\n        }\n\n        @Override\n        public Instance getDefiningInstance() {\n            return definingInstance;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof DynObjFieldValue) {\n                DynObjFieldValue dfv = (DynObjFieldValue) obj;\n\n                return definingInstance.equals(dfv.definingInstance)\n                    && field.equals(dfv.field);\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            return 31 * definingInstance.hashCode() + field.hashCode();\n        }\n    }\n\n    private abstract static class DynObjObjectFieldValue extends DynObjFieldValue implements ObjectFieldValue {\n        private DynObjObjectFieldValue(Instance i, Property p) {\n            super(i,p);\n        }\n    }\n}\n\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/dynamicobject/DynamicObjectArrayItemNode.java",
    "content": "/*\n * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.dynamicobject;\n\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectArrayItemNode;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DynamicObjectArrayItemNode<O extends DynamicObject> extends TruffleObjectArrayItemNode.InstanceBased<O> {\n    \n    public DynamicObjectArrayItemNode(O object, String type, ArrayItemValue item) {\n        super(object, type, item);\n    }\n    \n    \n    // TODO: make this an internal API similar to DetailsSupport.getDetailsString\n    protected String computeLogicalValue(O object, String type) {\n        return DynamicObjectNode.defaultLogicalValue(object, type);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/dynamicobject/DynamicObjectDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.dynamicobject;\n\nimport java.util.Map;\nimport java.util.WeakHashMap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service = DetailsProvider.class)\npublic class DynamicObjectDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String DYNAMIC_OBJECT_MASK = \"com.oracle.truffle.api.object.DynamicObject+\"; // NOI18N\n    private static final String SHAPE_MASK = \"com.oracle.truffle.api.object.Shape+\";    // NOI18N\n    private static final String JS_UNDEFIED_CLASS_FQN = \"com.oracle.truffle.js.runtime.objects.Undefined\";     // NOI18N\n    private static final String JS_NULL_CLASS_FQN = \"com.oracle.truffle.js.runtime.objects.Null\";     // NOI18N\n    private Map<Heap,Long> jsUndefidedId;\n    private Map<Heap,Long> jsNullId;\n\n    public DynamicObjectDetailsProvider() {\n        super(DYNAMIC_OBJECT_MASK,SHAPE_MASK);\n        jsUndefidedId = new WeakHashMap();\n        jsNullId = new WeakHashMap();\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case DYNAMIC_OBJECT_MASK: {\n                StringBuilder buf = new StringBuilder();\n                Heap heap = instance.getJavaClass().getHeap();\n                Long undefinedId = getJSUdefined(heap);\n                Long nullId = getJSNull(heap);\n                if (instance.getInstanceId() == undefinedId.longValue()) {\n                    buf.append(\"undefined\");       // NOI18N\n                } else if (instance.getInstanceId() == nullId.longValue()) {\n                    buf.append(\"null\");       // NOI18N\n                } else {\n                    Instance shape = (Instance) instance.getValueOfField(\"shape\");  // NOI18N\n                    Instance objectType = (Instance) shape.getValueOfField(\"objectType\");   // NOI18N\n                    buf.append('(').append(getSimpleClassName(objectType)).append(')'); // NOI18N\n                    buf.append(' ').append(getShortInstanceId(shape)); // NOI18N\n                }\n                return buf.toString();\n            }\n            case SHAPE_MASK: {\n                Instance objectType = (Instance) instance.getValueOfField(\"objectType\");   // NOI18N\n                String name = DetailsSupport.getDetailsString(objectType);\n\n                if (name == null) {\n                    name = getSimpleClassName(objectType);\n                }\n                return name;\n            }\n            default:\n                break;\n        }\n        return null;\n    }\n\n    private static String getShortInstanceId(Instance instance) {\n        if (instance == null) return \"null\"; // NOI18N\n        return getSimpleClassName(instance) + \"#\" + instance.getInstanceNumber(); // NOI18N\n    }\n\n    private static String getSimpleClassName(Instance instance) {\n        String name = instance.getJavaClass().getName();\n        int last = name.lastIndexOf('.'); // NOI18N\n        if (last != -1) {\n            name = name.substring(last + 1);\n        }\n        return name;\n    }\n\n    private Long getJSUdefined(Heap heap) {\n        return getInstanceId(jsUndefidedId, heap, JS_UNDEFIED_CLASS_FQN);\n    }\n\n    private Long getJSNull(Heap heap) {\n        return getInstanceId(jsNullId, heap, JS_NULL_CLASS_FQN);\n    }\n\n    private Long getInstanceId(Map<Heap,Long> objectId, Heap heap, String classFqn) {\n        if (heap == null) {\n            return Long.valueOf(0);\n        }\n        Long undef = objectId.get(heap);\n\n        if (undef == null) {\n            JavaClass undefinedClass = heap.getJavaClassByName(classFqn);\n\n            if (undefinedClass != null) {\n                Instance undefinedInstance = (Instance) undefinedClass.getValueOfStaticField(\"instance\");   // NOI18N\n\n                if (undefinedInstance != null) {\n                    undef = new Long(undefinedInstance.getInstanceId());\n                }\n            }\n            if (undef == null) {\n                undef = Long.valueOf(0);\n            }\n            objectId.put(heap, undef);\n        }\n        return undef;\n    }\n\n }\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/dynamicobject/DynamicObjectFieldNode.java",
    "content": "/*\n * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.dynamicobject;\n\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectFieldNode;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DynamicObjectFieldNode<O extends DynamicObject> extends TruffleObjectFieldNode.InstanceBased<O> {\n    \n    public DynamicObjectFieldNode(O object, String type, FieldValue field) {\n        super(object, type, field);\n    }\n    \n    \n    // TODO: make this an internal API similar to DetailsSupport.getDetailsString\n    protected String computeLogicalValue(O object, String type) {\n        return DynamicObjectNode.defaultLogicalValue(object, type);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/dynamicobject/DynamicObjectLanguageHeapFragment.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.dynamicobject;\n\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.Map;\nimport java.util.NoSuchElementException;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguage;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguageHeapFragment;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleType;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class DynamicObjectLanguageHeapFragment<D extends DynamicObject, T extends TruffleType<D>> extends TruffleLanguageHeapFragment<D, T> {\n    \n    private final Map<Instance, JavaClass> languageIDsCache;\n    \n    \n    protected DynamicObjectLanguageHeapFragment(String ID, String name, String description, TruffleLanguage<D, T, ? extends TruffleLanguageHeapFragment<D, T>> language, Heap heap) {\n        super(ID, name, description, language, heap);\n        \n        languageIDsCache = new HashMap<>();\n    }\n    \n    \n    protected final Iterator<Instance> languageInstancesIterator(String languageID) {\n        Iterator<Instance> instIt = HeapUtils.instancesIterator(HeapUtils.getSubclasses(heap, DynamicObject.DYNAMIC_OBJECT_FQN));\n\n        return new LanguageInstanceFilterIterator(instIt, languageID);\n    }\n\n    protected final Iterator<D> languageObjectsIterator(String languageID) {\n        Iterator<D> dynIt = new ObjectsIterator(HeapUtils.getSubclasses(heap, DynamicObject.DYNAMIC_OBJECT_FQN));\n\n        return new LanguageFilterIterator(dynIt, languageID);\n    }\n    \n    \n    private JavaClass getLanguageID(Instance shape) {\n        JavaClass langID = languageIDsCache.get(shape);\n        if (langID == null) {\n            langID = DynamicObject.getLanguageIdFromShape(shape);\n            languageIDsCache.put(shape, langID);\n        }\n        return langID;\n    }\n\n\n    private class LanguageFilterIterator implements Iterator<D> {\n        private final String languageID;\n        private final Iterator<D> objIterator;\n        private D next;\n\n        private LanguageFilterIterator(Iterator<D> oit, String langID) {\n            objIterator = oit;\n            languageID = langID;\n        }\n\n        @Override\n        public boolean hasNext() {\n            if (next != null) {\n                return true;\n            }\n            while (objIterator.hasNext()) {\n                D dobj = objIterator.next();\n                Instance shape = dobj.getShape();\n                if (languageID.equals(DynamicObjectLanguageHeapFragment.this.getLanguageID(shape).getName())) {\n                    next = dobj;\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        @Override\n        public D next() {\n            if (hasNext()) {\n                D dobj = next;\n                next = null;\n                return dobj;\n            }\n            throw new NoSuchElementException();\n        }\n    }\n\n    \n    private class LanguageInstanceFilterIterator implements Iterator<Instance> {\n        private final String languageID;\n        private final Iterator<Instance> instancesIterator;\n        private Instance next;\n\n        private LanguageInstanceFilterIterator(Iterator<Instance> instIt, String langID) {\n            instancesIterator = instIt;\n            languageID = langID;\n        }\n\n        @Override\n        public boolean hasNext() {\n            if (next != null) {\n                return true;\n            }\n            while (instancesIterator.hasNext()) {\n                Instance inst = instancesIterator.next();\n                Instance shape = DynamicObject.getShape(inst);\n                JavaClass langId = DynamicObjectLanguageHeapFragment.this.getLanguageID(shape);\n                if (langId != null && languageID.equals(langId.getName())) {\n                    next = inst;\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        @Override\n        public Instance next() {\n            if (hasNext()) {\n                Instance inst = next;\n                next = null;\n                return inst;\n            }\n            throw new NoSuchElementException();\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/dynamicobject/DynamicObjectNode.java",
    "content": "/*\n * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.dynamicobject;\n\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectNode;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DynamicObjectNode<O extends DynamicObject> extends TruffleObjectNode.InstanceBased<O> {\n    \n    public DynamicObjectNode(O dobject, String type) {\n        super(dobject, type);\n    }\n    \n    \n    // TODO: make this an internal API similar to DetailsSupport.getDetailsString\n    protected String computeLogicalValue(O object, String type) {\n        return defaultLogicalValue(object, type);\n    }\n    \n    protected void setupCopy(DynamicObjectNode copy) {\n        super.setupCopy(copy);\n    }\n    \n    \n    protected static String defaultLogicalValue(DynamicObject object, String type) {\n        String val = DetailsSupport.getDetailsString(object.getInstance());\n        if (val != null && val.startsWith(\"(\") && val.contains(\"#\")) val = null; // NOI18N\n        return val != null ? val : \"shape #\" + object.getShape().getInstanceNumber(); // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/dynamicobject/DynamicObjectReferenceNode.java",
    "content": "/*\n * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.dynamicobject;\n\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectReferenceNode;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DynamicObjectReferenceNode<O extends DynamicObject> extends TruffleObjectReferenceNode.InstanceBased<O> {\n    \n    public DynamicObjectReferenceNode(O object, String type, FieldValue field) {\n        super(object, type, field);\n    }\n    \n    \n    // TODO: make this an internal API similar to DetailsSupport.getDetailsString\n    protected String computeLogicalValue(O object, String type) {\n        return DynamicObjectNode.defaultLogicalValue(object, type);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/dynamicobject/LocalDynamicObjectNode.java",
    "content": "/*\n * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.dynamicobject;\n\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleLocalObjectNode;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class LocalDynamicObjectNode<O extends DynamicObject> extends TruffleLocalObjectNode.InstanceBased<O> {\n    \n    public LocalDynamicObjectNode(O object, String type) {\n        super(object, type);\n    }\n    \n    \n    // TODO: make this an internal API similar to DetailsSupport.getDetailsString\n    protected String computeLogicalValue(O object, String type) {\n        return DynamicObjectNode.defaultLogicalValue(object, type);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/javaext/TruffleFieldsProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.javaext;\n\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.PrimitiveNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleFrame;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectFieldNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectReferenceNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TerminalJavaNodes;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleFieldsProvider_Name=truffle fields\",\n    \"# {0} - number of fields\",\n    \"TruffleFieldsProvider_MoreNodes=<another {0} truffle fields left>\",\n    \"# {0} - number of fields\",\n    \"TruffleFieldsProvider_SamplesContainer=<sample {0} truffle fields>\",\n    \"# {0} - first index\",\n    \"# {1} - last index\",\n    \"TruffleFieldsProvider_NodesContainer=<truffle fields {0}-{1}>\"\n})\nabstract class TruffleFieldsProvider extends HeapViewerNode.Provider {\n    \n    public HeapViewerNode[] getNodes(HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        List<FieldValue> fields = getFields(parent, heap);\n        return getNodes(fields, parent, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n    }\n    \n    static HeapViewerNode[] getNodes(final List<FieldValue> fields, final HeapViewerNode parent, final Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        if (fields == null) return null;\n        \n        NodesComputer<Integer> computer = new NodesComputer<Integer>(fields.size(), UIThresholds.MAX_INSTANCE_FIELDS) {\n            protected boolean sorts(DataType dataType) {\n                return !DataType.COUNT.equals(dataType);\n            }\n            protected HeapViewerNode createNode(Integer index) {\n                return TruffleFieldsProvider.createNode(fields.get(index), heap);\n            }\n            protected ProgressIterator<Integer> objectsIterator(int index, Progress progress) {\n                Iterator<Integer> iterator = integerIterator(index, fields.size());\n                return new ProgressIterator(iterator, index, false, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return Bundle.TruffleFieldsProvider_MoreNodes(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return Bundle.TruffleFieldsProvider_SamplesContainer(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return Bundle.TruffleFieldsProvider_NodesContainer(firstNodeIdx, lastNodeIdx);\n            }\n        };\n\n        return computer.computeNodes(parent, heap, viewID, null, dataTypes, sortOrders, progress);\n    }\n    \n    private static HeapViewerNode createNode(FieldValue field, Heap heap) {\n        if (field instanceof ObjectFieldValue) {\n            ObjectFieldValue objectField = (ObjectFieldValue)field;\n            Instance fieldInstance = objectField.getInstance();\n            if (DynamicObject.isDynamicObject(fieldInstance)) {\n                DynamicObject dobject = new DynamicObject(fieldInstance);\n                return new DynamicObjectFieldNode(dobject, dobject.getType(), field);\n            } else {\n                return new TerminalJavaNodes.Field(objectField, false);\n            }\n        } else {\n            return new PrimitiveNode.Field(field);\n        }\n    }\n    \n    \n    protected abstract List<FieldValue> getFields(HeapViewerNode parent, Heap heap);\n    \n    \n    @ServiceProvider(service=HeapViewerNode.Provider.class, position = 100)\n    public static class InstanceFieldsProvider extends TruffleFieldsProvider {\n        \n        // TODO: will be configurable, ideally by instance\n        private boolean includeStaticFields = true;\n        private boolean includeInstanceFields = true;\n        \n        public String getName() {\n            return Bundle.TruffleFieldsProvider_Name();\n        }\n\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.equals(\"truffle_objects_javaext\"); // NOI18N\n        }\n\n        public boolean supportsNode(HeapViewerNode parent, Heap heap, String viewID) {\n            if (parent instanceof InstanceNode && !(parent instanceof DynamicObjectReferenceNode)) {\n                InstanceNode node = (InstanceNode)parent;\n                if (InstanceNode.Mode.INCOMING_REFERENCE.equals(node.getMode())) return false;\n                \n                Instance instance = node.getInstance();\n                return DynamicObject.isDynamicObject(instance) ||\n                       TruffleFrame.isTruffleFrame(instance);\n            } else {\n                return false;\n            }\n        }\n\n        \n        protected List<FieldValue> getFields(HeapViewerNode parent, Heap heap) {\n            Instance instance = HeapViewerNode.getValue(parent, DataType.INSTANCE, heap);\n            \n            if (DynamicObject.isDynamicObject(instance)) {\n                DynamicObject dobj = new DynamicObject(instance);\n                if (includeStaticFields == includeInstanceFields) {\n                    List<FieldValue> fields = new ArrayList(dobj.getFieldValues());\n                    fields.addAll(dobj.getStaticFieldValues());\n                    return fields;\n                } else if (includeInstanceFields) {\n                    return dobj.getFieldValues();\n                } else {\n                    return dobj.getStaticFieldValues();\n                }\n            } else if (TruffleFrame.isTruffleFrame(instance)) {\n                TruffleFrame tframe = new TruffleFrame(instance);\n                return new ArrayList(tframe.getFieldValues());\n            }\n            \n            return null;\n        }\n        \n    }\n    \n//    @ServiceProvider(service=HeapViewerNode.Provider.class, position = 250)\n//    public static class ClassFieldsProvider extends TruffleFieldsProvider {\n//        \n//        public String getName() {\n//            return \"static fields\";\n//        }\n//\n//        public boolean supportsView(Heap heap, String viewID) {\n//            return viewID.startsWith(\"java_objects\");\n//        }\n//\n//        public boolean supportsNode(HeapViewerNode parent, Heap heap, String viewID) {\n//            if (parent instanceof ClassNode) {\n//                JavaClass javaClass = ((ClassNode)parent).getJavaClass();\n//                return javaClass != null && !javaClass.isArray();\n//            } else {\n//                return false;\n//            }\n//        }\n//\n//        \n//        protected List<FieldValue> getFields(HeapViewerNode parent, Heap heap) {\n//            JavaClass jclass = HeapViewerNode.getValue(parent, DataType.CLASS, heap);\n//            return jclass == null ? null : jclass.getStaticFieldValues();\n//        }\n//        \n//    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/javaext/TruffleJavaViewPlugin.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.javaext;\n\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.JComponent;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguageHeapFragment;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleJavaViewPlugin_Name=Java Object\",\n    \"TruffleJavaViewPlugin_Description=Java Object\",\n    \"TruffleJavaViewPlugin_NoSelection=<no object selected>\"\n})\npublic class TruffleJavaViewPlugin extends HeapViewPlugin {\n    \n    private final Heap heap;\n    private Instance selected;\n    \n    private final TreeTableView objectsView;\n    \n    \n    public TruffleJavaViewPlugin(HeapContext context, HeapViewerActions actions) {\n        super(Bundle.TruffleJavaViewPlugin_Name(), Bundle.TruffleJavaViewPlugin_Description(), Icons.getIcon(GeneralIcons.JAVA_PROCESS));\n        \n        heap = context.getFragment().getHeap();\n        \n        objectsView = new TreeTableView(\"java_objects_truffleext\", context, actions, TreeTableViewColumn.instancesPlain(heap)) { // NOI18N\n            protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                InstanceNode instanceNode = selected == null ? null : new InstanceNode(selected);\n                HeapViewerNode result = instanceNode == null ? new TextNode(Bundle.TruffleJavaViewPlugin_NoSelection()) : instanceNode;\n                return new HeapViewerNode[] { result };\n            }\n            protected void childrenChanged() {\n                HeapViewerNode[] children = getRoot().getChildren();\n                for (HeapViewerNode child : children) expandNode(child);\n                \n                if (children.length > 0) {\n                    children = children[0].getChildren();\n                    if (children.length > 0 && children[0] instanceof TextNode) expandNode(children[0]);\n                }\n            }\n        };\n    }\n\n    \n    protected JComponent createComponent() {\n        return objectsView.getComponent();\n    }\n    \n    \n    @Override\n    protected void closed() {\n        synchronized (objectsView) { selected = TruffleViewPlugin.NO_INSTANCE; }\n        objectsView.closed();\n    }\n    \n    \n    protected void nodeSelected(HeapViewerNode node, boolean adjusting) {\n        Instance selectedInstance = node == null ? null : HeapViewerNode.getValue(node, DataType.INSTANCE, heap);\n        if (Objects.equals(selected, selectedInstance)) return;\n\n        selected = selectedInstance;\n        \n        objectsView.reloadView();\n    }\n    \n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 1000)\n    public static class Provider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (TruffleLanguageHeapFragment.isTruffleHeap(context))\n                return new TruffleJavaViewPlugin(context, actions);\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/javaext/TrufflePrimitiveArrayItemsProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.javaext;\n\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.PrimitiveNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TrufflePrimitiveArrayItemsProvider_Name=items\",\n    \"# {0} - number of nodes\",\n    \"TrufflePrimitiveArrayItemsProvider_MoreNodes=<another {0} items left>\",\n    \"# {0} - number of nodes\",\n    \"TrufflePrimitiveArrayItemsProvider_SamplesContainer=<sample {0} items>\",\n    \"# {0} - first index\",\n    \"# {1} - last index\",\n    \"TrufflePrimitiveArrayItemsProvider_NodesContainer=<items {0}-{1}>\"\n})\n@ServiceProvider(service=HeapViewerNode.Provider.class, position = 300)\npublic class TrufflePrimitiveArrayItemsProvider extends HeapViewerNode.Provider {\n    \n    public String getName() {\n        return Bundle.TrufflePrimitiveArrayItemsProvider_Name();\n    }\n    \n    public boolean supportsView(Heap heap, String viewID) {\n        // TODO: fix to cover just the Truffle heaps!\n        return !viewID.startsWith(\"java_\"); // NOI18N\n    }\n    \n    public boolean supportsNode(HeapViewerNode parent, Heap heap, String viewID) {\n        if (parent instanceof InstanceNode && !InstanceNode.Mode.INCOMING_REFERENCE.equals(((InstanceNode)parent).getMode())) {\n            Instance instance = ((InstanceNode)parent).getInstance();\n            return instance instanceof PrimitiveArrayInstance;\n        } else {\n            return false;\n        }\n    }\n    \n    public HeapViewerNode[] getNodes(final HeapViewerNode parent, final Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        final Instance instance = HeapViewerNode.getValue(parent, DataType.INSTANCE, heap);\n//        if (!(instance instanceof PrimitiveArrayInstance)) return null;\n        \n        final String type = instance.getJavaClass().getName().replace(\"[]\", \"\"); // NOI18N\n        final List<String> items = ((PrimitiveArrayInstance)instance).getValues();\n\n        NodesComputer<Integer> computer = new NodesComputer<Integer>(items.size(), UIThresholds.MAX_ARRAY_ITEMS) {\n            protected boolean sorts(DataType dataType) {\n                if (DataType.COUNT == dataType || DataType.OWN_SIZE == dataType || DataType.RETAINED_SIZE == dataType) return false;\n                return true;\n            }\n            protected HeapViewerNode createNode(Integer index) {\n                return new PrimitiveNode.ArrayItem(index, type, items.get(index), instance);\n            }\n            protected ProgressIterator<Integer> objectsIterator(int index, Progress progress) {\n                Iterator<Integer> iterator = integerIterator(index, items.size());\n                return new ProgressIterator(iterator, index, false, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return Bundle.TrufflePrimitiveArrayItemsProvider_MoreNodes(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return Bundle.TrufflePrimitiveArrayItemsProvider_SamplesContainer(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return Bundle.TrufflePrimitiveArrayItemsProvider_NodesContainer(firstNodeIdx, lastNodeIdx);\n            }\n        };\n\n        return computer.computeNodes(parent, heap, viewID, null, dataTypes, sortOrders, progress);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/javaext/TruffleReferencesProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.javaext;\n\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectFieldNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectReferenceNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TerminalJavaNodes;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleReferencesProvider_Name=truffle references\",\n    \"# {0} - number of refs\",\n    \"TruffleReferencesProvider_MoreNodes=<another {0} truffle references left>\",\n    \"# {0} - number of refs\",\n    \"TruffleReferencesProvider_SamplesContainer=<sample {0} truffle references>\",\n    \"# {0} - first index\",\n    \"# {1} - last index\",\n    \"TTruffleReferencesProvider_NodesContainer=<truffle references {0}-{1}>\"\n})\n@ServiceProvider(service=HeapViewerNode.Provider.class, position = 200)\npublic class TruffleReferencesProvider extends HeapViewerNode.Provider {\n    \n    public String getName() {\n        return Bundle.TruffleReferencesProvider_Name();\n    }\n    \n    public boolean supportsView(Heap heap, String viewID) {\n        return viewID.equals(\"truffle_objects_javaext\"); // NOI18N\n    }\n    \n    public boolean supportsNode(HeapViewerNode parent, Heap heap, String viewID) {\n        if (parent instanceof InstanceNode && !(parent instanceof DynamicObjectFieldNode)) {\n            InstanceNode node = (InstanceNode)parent;\n            if (InstanceNode.Mode.OUTGOING_REFERENCE.equals(node.getMode())) return false;\n            \n            Instance instance = node.getInstance();\n            return DynamicObject.isDynamicObject(instance);\n        } else {\n            return false;\n        }\n    }\n    \n    public HeapViewerNode[] getNodes(HeapViewerNode parent, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        return getNodes(getReferences(parent, heap), parent, heap, viewID, dataTypes, sortOrders, progress);\n    }\n    \n    static HeapViewerNode[] getNodes(List<FieldValue> references, HeapViewerNode parent, Heap heap, String viewID, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        if (references == null) return null;\n        \n        NodesComputer<Integer> computer = new NodesComputer<Integer>(references.size(), UIThresholds.MAX_INSTANCE_REFERENCES) {\n            protected boolean sorts(DataType dataType) {\n                return !DataType.COUNT.equals(dataType);\n            }\n            protected HeapViewerNode createNode(Integer index) {\n                return TruffleReferencesProvider.createNode(references.get(index), heap);\n            }\n            protected ProgressIterator<Integer> objectsIterator(int index, Progress progress) {\n                Iterator<Integer> iterator = integerIterator(index, references.size());\n                return new ProgressIterator(iterator, index, false, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return Bundle.TruffleReferencesProvider_MoreNodes(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return Bundle.TruffleReferencesProvider_SamplesContainer(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return Bundle.TTruffleReferencesProvider_NodesContainer(firstNodeIdx, lastNodeIdx);\n            }\n        };\n\n        return computer.computeNodes(parent, heap, viewID, null, dataTypes, sortOrders, progress);\n    }\n    \n    private static HeapViewerNode createNode(FieldValue field, Heap heap) {\n        Instance instance = field.getDefiningInstance();\n        if (DynamicObject.isDynamicObject(instance)) {\n            DynamicObject dobject = new DynamicObject(instance);\n            return new DynamicObjectReferenceNode(dobject, dobject.getType(), field);\n        } else {\n            return TerminalJavaNodes.incomingReference(field);\n        }\n    }\n    \n    protected List<FieldValue> getReferences(HeapViewerNode parent, Heap heap) {\n        Instance instance = HeapViewerNode.getValue(parent, DataType.INSTANCE, heap);\n\n        if (DynamicObject.isDynamicObject(instance)) {\n            DynamicObject dobject = new DynamicObject(instance);\n            return dobject.getReferences();\n        }\n\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/javaext/TruffleViewPlugin.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.javaext;\n\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JComponent;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.JavaHeapFragment;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.model.TextNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleFrame;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleViewPlugin_Name=Truffle Object\",\n    \"TruffleViewPlugin_Description=Truffle Object\",\n    \"TruffleViewPlugin_NoSelection=<no DynamicObject or TruffleFrame selected>\"\n})\nclass TruffleViewPlugin extends HeapViewPlugin {\n    \n    static final Instance NO_INSTANCE = new FakeInstance();\n    \n    \n    private final Heap heap;\n    private Instance selected;\n    \n    private final TreeTableView objectsView;\n    \n\n    TruffleViewPlugin(HeapContext context, HeapViewerActions actions) {\n        super(Bundle.TruffleViewPlugin_Name(), Bundle.TruffleViewPlugin_Description(), graalIcon());\n        \n        heap = context.getFragment().getHeap();\n        \n        objectsView = new TreeTableView(\"truffle_objects_javaext\", context, actions, TreeTableViewColumn.instancesPlain(heap)) { // NOI18N\n            protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                if (DynamicObject.isDynamicObject(selected)) {\n                    DynamicObject dobject = new DynamicObject(selected);\n                    return new HeapViewerNode[] { new DynamicObjectNode(dobject, dobject.getType()) };\n                } else if (TruffleFrame.isTruffleFrame(selected)) {\n                    return new HeapViewerNode[] { new InstanceNode(selected) };\n                } else {\n                    return new HeapViewerNode[] { new TextNode(Bundle.TruffleViewPlugin_NoSelection()) };\n                }\n            }\n            protected void childrenChanged() {\n                HeapViewerNode[] children = getRoot().getChildren();\n                for (HeapViewerNode child : children) expandNode(child);\n                \n                if (children.length > 0) {\n                    children = children[0].getChildren();\n                    if (children.length > 0 && children[0] instanceof TextNode) expandNode(children[0]);\n                }\n            }\n        };\n    }\n\n    protected JComponent createComponent() {\n        return objectsView.getComponent();\n    }\n    \n    \n    @Override\n    protected void closed() {\n        synchronized (objectsView) { selected = NO_INSTANCE; }\n        objectsView.closed();\n    }\n    \n    \n    protected void nodeSelected(HeapViewerNode node, boolean adjusting) {\n        Instance instance = node == null ? null : HeapViewerNode.getValue(node, DataType.INSTANCE, heap);\n        \n        if (Objects.equals(instance, selected)) return;\n        selected = instance;\n        \n        objectsView.reloadView();\n    }\n    \n    \n    private static Icon graalIcon() {\n        String path = TruffleViewPlugin.class.getPackage().getName().replace('.', '/') + \"/GraalVM.png\"; // NOI18N\n        return new ImageIcon(ImageUtilities.loadImage(path, true));\n    }\n    \n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 1000)\n    public static class Provider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!JavaHeapFragment.isJavaHeap(context)) return null;\n            if (!DynamicObject.hasDynamicObject(context.getFragment().getHeap())) return null;\n            return new TruffleViewPlugin(context, actions);\n        }\n        \n    }\n    \n    \n    private static class FakeInstance implements Instance {\n        @Override public List getFieldValues()                      { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public boolean isGCRoot()                         { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public long getInstanceId()                       { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public int getInstanceNumber()                    { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public JavaClass getJavaClass()                   { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public Instance getNearestGCRootPointer()         { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public long getReachableSize()                    { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public List getReferences()                       { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public long getRetainedSize()                     { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public long getSize()                             { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public List getStaticFieldValues()                { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        @Override public Object getValueOfField(String name)        { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n        \n        @Override public boolean equals(Object o)                   { return o == this; }\n        @Override public int hashCode()                             { return -1; }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/javascript/JavaScriptDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.javascript;\n\nimport java.util.Locale;\nimport org.graalvm.visualvm.heapviewer.truffle.details.SourceSectionView;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic class JavaScriptDetailsProvider extends DetailsProvider.Basic {\n    private static final String SYMBOL_MASK = \"com.oracle.truffle.js.runtime.Symbol\";   // NOI18N\n    private static final String JS_NODE_MASK = \"com.oracle.truffle.js.nodes.JavaScriptNode+\";    // NOI18N\n    private static final String JS_STRING_MASK = \"com.oracle.truffle.js.runtime.objects.JSLazyString\";  // NOI18N\n    private static final String JS_INT_MASK = \"com.oracle.truffle.js.runtime.objects.JSLazyString$JSLazyIntWrapper\";    // NOI18N\n    private static final String JS_FUNCTION_MASK = \"com.oracle.truffle.js.runtime.builtins.JSFunctionObject+\";  // NOI18N\n    private static final String JS_FDATA_MASK = \"com.oracle.truffle.js.runtime.builtins.JSFunctionData\";  // NOI18N\n    private static final String JS_FUNCTION_ROOT_NODE_MASK = \"com.oracle.truffle.js.nodes.function.FunctionRootNode\"; // NOI18N\n    private static final String JS_CONSTRUCTOR_ROOT_NODE_MASK = \"com.oracle.truffle.js.nodes.function.ConstructorRootNode\"; // NOI18N\n    private static final String JS_NEW_TARGET_ROOT_NODE_MASK = \"com.oracle.truffle.js.nodes.function.NewTargetRootNode+\"; // NOI18N\n    private static final String JS_NATIVE_FUNCTION_ROOT_NODE_MASK = \"com.oracle.truffle.trufflenode.node.ExecuteNativeFunctionNode$NativeFunctionRootNode\"; // NOI18N\n    private static final String JS_FUNCTION_TEMPLATE_MASK = \"com.oracle.truffle.trufflenode.info.FunctionTemplate\"; // NOI18N\n    private static final String JS_REGEX_NODE_MASK = \"com.oracle.truffle.regex.RegexNode+\"; // NOI18N\n    private static final String JS_TREGEX_NODE_MASK = \"com.oracle.truffle.regex.tregex.TRegexRootNode+\"; // NOi18N\n    private static final String JS_JAVA_PACKAGE_MASK = \"com.oracle.truffle.js.runtime.java.JavaPackageObject\";  // NOI18N\n\n    private static final String SOURCE_SECTION = \"com.oracle.truffle.api.source.SourceSection\";\n\n    public JavaScriptDetailsProvider() {\n        super(SYMBOL_MASK, JS_NODE_MASK, JS_STRING_MASK, JS_INT_MASK, JS_FUNCTION_MASK,\n                JS_FDATA_MASK, JS_FUNCTION_ROOT_NODE_MASK, JS_CONSTRUCTOR_ROOT_NODE_MASK,\n                JS_NEW_TARGET_ROOT_NODE_MASK, JS_NATIVE_FUNCTION_ROOT_NODE_MASK,\n                JS_FUNCTION_TEMPLATE_MASK, JS_REGEX_NODE_MASK, JS_TREGEX_NODE_MASK,\n                JS_JAVA_PACKAGE_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case SYMBOL_MASK: {\n                String description = DetailsUtils.getInstanceFieldString(instance, \"description\");     // NOI18N\n\n                if (description != null) {\n                    return description;\n                }\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            }\n            case JS_STRING_MASK: {\n                Object val = instance.getValueOfField(\"length\");   // NOI18N\n                Object vall = instance.getValueOfField(\"left\");   // NOI18N\n                Object valr = instance.getValueOfField(\"right\");   // NOI18N\n                if (val instanceof Integer) {\n                    String left = DetailsUtils.getInstanceString((Instance)vall);\n\n                    if (valr == null || left.length() > DetailsUtils.MAX_ARRAY_LENGTH) {\n                        return left;\n                    }\n                    return left + DetailsUtils.getInstanceString((Instance)valr);\n                }\n                break;\n            }\n            case JS_INT_MASK: {\n                int value = DetailsUtils.getIntFieldValue(instance, \"value\", 0);        // NOI18N\n                return Integer.toString(value);\n            }\n            case JS_FUNCTION_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"functionData\"); // NOI18N\n            case JS_FDATA_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n                if (name == null || name.isEmpty()) {\n                    name = DetailsUtils.getInstanceFieldString(instance, \"lazyInit\"); // NOI18N\n                }\n                if (name == null || name.isEmpty()) {\n                    // fallback to callTarget and\n                    // remove everything after first space\n                    String callTargetName = DetailsUtils.getInstanceFieldString(instance, \"callTarget\"); // NOI18N\n                    int spaceIndex = callTargetName == null ? -1 : callTargetName.indexOf(' ');\n\n                    if (spaceIndex > 0) {\n                        name = callTargetName.substring(0,spaceIndex);\n                    } else {\n                        name = callTargetName;\n                    }\n                }\n                return name;\n            }\n            case JS_FUNCTION_ROOT_NODE_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"internalFunctionName\");    // NOI18N\n\n                if (name != null) {\n                    return name;\n                }\n                return DetailsUtils.getInstanceFieldString(instance, \"functionData\"); // NOI18N\n            }\n            case JS_CONSTRUCTOR_ROOT_NODE_MASK: {\n                Object val = getValueOfField(instance, \"callTarget\", instance.getJavaClass());    // NOI18N\n                if (val instanceof Instance) {\n                    String name = DetailsUtils.getInstanceString((Instance) val);\n                    if (name != null) {\n                        return \"[Construct] \" + name; // NOI18N\n                    }\n                }\n                break;\n            }\n            case JS_NEW_TARGET_ROOT_NODE_MASK: {\n                Object val = getValueOfField(instance, \"callTarget\", instance.getJavaClass().getSuperClass());    // NOI18N\n                if (val instanceof Instance) {\n                    String name = DetailsUtils.getInstanceString((Instance) val);\n                    if (name != null) {\n                        return \"[NewTarget] \" + name; // NOI18N\n                    }\n                }\n                break;\n            }\n            case JS_NATIVE_FUNCTION_ROOT_NODE_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"template\"); // NOI18N\n            case JS_FUNCTION_TEMPLATE_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"className\"); // NOI18N\n            case JS_REGEX_NODE_MASK: {\n                String regexClass = instance.getJavaClass().getName();\n                String regexSimpleName = regexClass.substring(regexClass.lastIndexOf('.') + 1, regexClass.length()); // NOI18N\n                String engineLabel = regexSimpleName.substring(0, regexSimpleName.indexOf(\"RegexNode\"));    // NOI18N\n                if (engineLabel != null) {\n                    String pattern = DetailsUtils.getInstanceFieldString(instance, \"pattern\");    // NOI18N\n                    if (pattern == null) {\n                        pattern = DetailsUtils.getInstanceFieldString(instance, \"node\");    // NOI18N\n                    }\n                    if (engineLabel != null && pattern != null) {\n                        return engineLabel.toLowerCase(Locale.US) + \": \" + pattern;    // NOI18N\n                    }\n                }\n                break;\n            }\n            case JS_TREGEX_NODE_MASK: {\n                String patternSource = DetailsUtils.getInstanceFieldString(instance, \"patternSource\");    // NOI18N\n                if (patternSource != null) {\n                    return \"TRegex fwd \" + patternSource;    // NOI18N\n                }\n                break;\n            }\n            case JS_JAVA_PACKAGE_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"packageName\"); // NOI18N\n            default:\n                break;\n        }\n        return null;\n    }\n\n    public View getDetailsView(String className, Instance instance) {\n        if (JS_NODE_MASK.equals(className)) {\n            Instance source = (Instance) instance.getValueOfField(\"source\");     // NOI18N\n            if (source == null) return null;\n            if (isSourceSection(source)) {\n                return DetailsSupport.getDetailsView(source);\n            }\n            Integer charIndexInt = (Integer) instance.getValueOfField(\"charIndex\");    // NOI18N\n            Integer charLengthInt = (Integer) instance.getValueOfField(\"charLength\");  // NOI18N\n            Instance code = getCodeString(source);\n            if (code == null) return null;\n            int charIndex = charIndexInt.intValue() & 0x3FFFFFFF;\n            int charLength = charLengthInt.intValue() & 0x3FFFFFFF;\n\n            return new SourceSectionView(className, code, charIndex, charLength);\n        }\n        return null;\n    }\n\n    private Instance getCodeString(Instance source) {\n        Instance content = (Instance) source.getValueOfField(\"content\");     // NOI18N\n        if (content instanceof Instance) {\n            return (Instance) content.getValueOfField(\"code\");     // NOI18N\n        }\n        Instance key = (Instance) source.getValueOfField(\"key\");     // NOI18N\n        if (key instanceof Instance) {\n            return (Instance) key.getValueOfField(\"content\");     // NOI18N\n        }\n        return null;\n    }\n\n    private Object getValueOfField(Instance instance, String name, JavaClass jcls) {\n        for (FieldValue fieldValue : instance.getFieldValues()) {\n            Field f = fieldValue.getField();\n\n            if (f.getName().equals(name) && f.getDeclaringClass().equals(jcls)) {\n                if (fieldValue instanceof ObjectFieldValue) {\n                    return ((ObjectFieldValue) fieldValue).getInstance();\n                } else {\n                    return fieldValue.getValue();\n                }\n            }\n        }\n        return null;\n    }\n\n    private boolean isSourceSection(Instance source) {\n        for (JavaClass jcls = source.getJavaClass(); jcls != null; jcls = jcls.getSuperClass()) {\n            if (SOURCE_SECTION.equals(jcls.getName())) {\n                return true;\n            }\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/javascript/JavaScriptHeapFragment.java",
    "content": "/*\n * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.javascript;\n\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectLanguageHeapFragment;\nimport org.graalvm.visualvm.heapviewer.utils.ExcludingIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaScriptHeapFragment_Name=JavaScript Heap\",\n    \"JavaScriptHeapFragment_UnknownType=<unknown type>\",\n    \"JavaScriptHeapFragment_NoPrototype=<no prototype>\",\n    \"JavaScriptHeapFragment_AnonymousPrototype=<anonymous prototype>\",\n    \"JavaScriptHeapFragment_UnknownPrototype=<unknown prototype>\"\n})\nclass JavaScriptHeapFragment extends DynamicObjectLanguageHeapFragment<JavaScriptObject, JavaScriptType> {\n    \n    static final String JS_LANG_ID = \"com.oracle.truffle.js.runtime.builtins.JSClass\"; // NOI18N\n    \n    private static final String JS_HEAP_ID = \"javascript_heap\"; // NOI18N\n    \n    // Copied from DynamicObjectDetailsProvider, unify!\n    private static final String JS_NULL_CLASS_FQN = \"com.oracle.truffle.js.runtime.objects.Null\";     // NOI18N\n    private static final String JS_UNDEFIED_CLASS_FQN = \"com.oracle.truffle.js.runtime.objects.Undefined\";     // NOI18N\n    \n    \n    final Instance nullInstance;\n    final Instance undefinedInstance;\n    \n    private final Map<Instance, String> typesCache;\n    \n    \n    JavaScriptHeapFragment(JavaScriptLanguage language, Instance langID, Heap heap) {\n        super(JS_HEAP_ID, Bundle.JavaScriptHeapFragment_Name(), fragmentDescription(langID), language, heap);\n        \n        JavaClass nullClass = heap.getJavaClassByName(JS_NULL_CLASS_FQN);\n        nullInstance = (Instance)nullClass.getValueOfStaticField(\"instance\"); // NOI18N\n        \n        JavaClass undefinedClass = heap.getJavaClassByName(JS_UNDEFIED_CLASS_FQN);\n        undefinedInstance = (Instance)undefinedClass.getValueOfStaticField(\"instance\"); // NOI18N\n        \n        typesCache = new HashMap<>();\n    }\n    \n    \n    static JavaScriptHeapFragment fromContext(HeapContext context) {\n        return (JavaScriptHeapFragment)context.getFragment();\n    }\n    \n    static boolean isJavaScriptHeap(HeapContext context) {\n        return JS_HEAP_ID.equals(context.getFragment().getID());\n    }\n    \n    \n    @Override\n    public Iterator<Instance> getInstancesIterator() {\n        return new ExcludingIterator<Instance>(languageInstancesIterator(JS_LANG_ID)) {\n            @Override\n            protected boolean exclude(Instance instance) {\n                return (Objects.equals(nullInstance, instance) || Objects.equals(undefinedInstance, instance));\n            }\n        };\n//        return languageInstancesIterator(JS_LANG_ID);\n    }\n\n    @Override\n    public Iterator<JavaScriptObject> getObjectsIterator() {\n        return new ExcludingIterator<JavaScriptObject>(languageObjectsIterator(JS_LANG_ID)) {\n            @Override\n            protected boolean exclude(JavaScriptObject object) {\n                Instance instance = object.getInstance();\n                return (Objects.equals(nullInstance, instance) || Objects.equals(undefinedInstance, instance));\n            }\n        };\n//        return super.getObjectsIterator();\n//        return languageObjectsIterator(JS_LANG_ID);\n    }\n    \n    \n    String getObjectType(Instance instance) {\n        return getObjectType(instance, null);\n    }\n    \n    String getObjectType(Instance instance, Instance shape) {\n        if (shape == null) shape = JavaScriptObject.getShape(instance);\n        String type = typesCache.get(shape);\n\n        if (type == null) {\n            Instance prototype = getPrototype(instance);\n\n            type = typesCache.get(prototype);\n            if (type == null) {\n                type = getJSType(prototype, this);\n                typesCache.put(prototype, type);\n            }\n            typesCache.put(shape, type);\n        }\n        \n        return type;\n    }\n    \n    private static Instance getPrototype(Instance instance) {\n        JavaScriptObject jsobj = new JavaScriptObject(instance);\n        Instance prototype = getPrototype(jsobj.getStaticFieldValues());\n\n        if (prototype != null) {\n            return prototype;\n        }\n        return getPrototype(jsobj.getFieldValues());\n    }\n\n    private static Instance getPrototype(List<FieldValue> fields) {\n        for (FieldValue field : fields) {\n            String fieldName = field.getField().getName();\n            if (\"__proto__ (hidden)\".equals(fieldName) ||     // NOI18N\n                \"[[Prototype]] (hidden)\".equals(fieldName)) { // NOI18N\n                return ((ObjectFieldValue)field).getInstance();\n            }\n        }\n        return null;\n    }\n\n    private static String getJSType(Instance prototype, JavaScriptHeapFragment fragment) {\n        if (prototype == null) return Bundle.JavaScriptHeapFragment_UnknownType();\n        \n        if (Objects.equals(fragment.nullInstance, prototype)) return Bundle.JavaScriptHeapFragment_NoPrototype();\n        \n        Heap heap = fragment.getHeap();\n        \n        JavaScriptObject dprototype = new JavaScriptObject(prototype);\n        ObjectFieldValue constructorValue = (ObjectFieldValue)dprototype.getFieldValue(\"constructor\"); // NOI18N\n        if (constructorValue != null) {\n            Instance constructor = constructorValue.getInstance();\n            JavaScriptObject dconstructor = new JavaScriptObject(constructor);\n            String dconstructorT = DynamicObject.getType(constructor);\n            String type = JavaScriptNodes.getLogicalValue(dconstructor, dconstructorT);\n            if (type == null) return Bundle.JavaScriptHeapFragment_AnonymousPrototype();\n            return type.endsWith(\"()\") ? type.substring(0, type.length() - 2) : type; // NOI18N\n        } else {\n            return Bundle.JavaScriptHeapFragment_UnknownPrototype();\n        }\n    }\n    \n    \n//    public static HeapContext getJavaScriptContext(HeapContext context) {\n//        if (isJavaScriptHeap(context)) return context;\n//        \n//        for (HeapContext otherContext : context.getOtherContexts())\n//            if (isJavaScriptHeap(otherContext)) return otherContext;\n//        \n//        return null;\n//    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/javascript/JavaScriptLanguage.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.javascript;\n\nimport org.graalvm.visualvm.heapviewer.HeapFragment;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguage;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.openide.util.Lookup;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.util.lookup.ServiceProviders;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProviders(value={\n    @ServiceProvider(service=HeapFragment.Provider.class, position = 200),\n    @ServiceProvider(service=JavaScriptLanguage.class, position = 200)}\n)\npublic class JavaScriptLanguage extends TruffleLanguage<JavaScriptObject, JavaScriptType, JavaScriptHeapFragment> {\n    \n    private static final String ID = \"javascript\"; // NOI18N\n    \n    private static final String JS_LANGINFO_ID = \"JS\";  // NOI18N\n    private static final String JAVASCRIPT_LANGINFO_ID = \"JavaScript\";  // NOI18N\n    \n    \n    private static JavaScriptLanguage INSTANCE; \n    static synchronized JavaScriptLanguage instance() {\n        if (INSTANCE == null) Lookup.getDefault().lookup(JavaScriptLanguage.class);\n        return INSTANCE;\n    }\n    public JavaScriptLanguage() { INSTANCE = this; }\n    \n    \n    public String getID() { return ID; }\n    \n    \n    @Override\n    protected JavaScriptHeapFragment createFragment(Heap heap) {\n        Instance langID = getLanguageInfo(heap, JS_LANGINFO_ID);\n        if (langID == null) langID = getLanguageInfo(heap, JAVASCRIPT_LANGINFO_ID);\n        if (langID == null) return null;\n        \n        JavaClass JSMainClass = heap.getJavaClassByName(JavaScriptHeapFragment.JS_LANG_ID);\n        if (JSMainClass == null) return null;\n\n        return new JavaScriptHeapFragment(this, langID, heap);\n    }\n    \n    \n    @Override\n    public Class<JavaScriptObject> getLanguageObjectClass() {\n        return JavaScriptObject.class;\n    }\n    \n\n    @Override\n    public boolean isLanguageObject(Instance instance) {\n        return JavaScriptObject.isJavaScriptObject(instance);\n    }\n    \n    @Override\n    public JavaScriptObject createObject(Instance instance) {\n        return new JavaScriptObject(instance);\n    }\n    \n    @Override\n    public JavaScriptType createType(String name) {\n        return new JavaScriptType(name);\n    }\n    \n    \n    @Override\n    public JavaScriptNodes.JavaScriptObjectNode createObjectNode(JavaScriptObject object, String type) {\n        return new JavaScriptNodes.JavaScriptObjectNode(object, type);\n    }\n    \n    @Override\n    public JavaScriptNodes.JavaScriptLocalObjectNode createLocalObjectNode(JavaScriptObject object, String type) {\n        return new JavaScriptNodes.JavaScriptLocalObjectNode(object, type);\n    }\n    \n    @Override\n    public JavaScriptNodes.JavaScriptTypeNode createTypeNode(JavaScriptType type, Heap heap) {\n        return new JavaScriptNodes.JavaScriptTypeNode(type);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/javascript/JavaScriptNodes.java",
    "content": "/*\n * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.javascript;\n\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectArrayItemNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectFieldNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectReferenceNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.LocalDynamicObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleLocalObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectArrayItemNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectFieldNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectReferenceNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleOpenNodeActionProvider;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleTypeNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapViewerNodeAction.Provider.class)\npublic class JavaScriptNodes extends TruffleOpenNodeActionProvider<JavaScriptObject, JavaScriptType, JavaScriptHeapFragment, JavaScriptLanguage> {\n    \n    @Override\n    public boolean supportsView(HeapContext context, String viewID) {\n        return JavaScriptHeapFragment.isJavaScriptHeap(context);\n    }\n\n    @Override\n    protected boolean supportsNode(HeapViewerNode node) {\n        return node instanceof JavaScriptNodes.JavaScriptNode;\n    }\n\n    @Override\n    protected JavaScriptLanguage getLanguage() {\n        return JavaScriptLanguage.instance();\n    }\n    \n    \n    private static final int MAX_LOGVALUE_LENGTH = 160;\n        \n    static String getLogicalValue(JavaScriptObject object, String type) {\n        String logicalValue = null;\n        \n        if (\"Function\".equals(type) || \"JSFunction\".equals(type)) { // NOI18N\n            FieldValue dataField = object.getFieldValue(\"functionData (hidden)\"); // NOI18N\n            Instance data = dataField instanceof ObjectFieldValue ? ((ObjectFieldValue)dataField).getInstance() : null;\n//                Instance data = (Instance)getInstance().getValueOfField(\"object2\");\n            logicalValue = data == null ? null : DetailsSupport.getDetailsString(data);\n            if (logicalValue != null) logicalValue += \"()\";\n            else logicalValue = DetailsSupport.getDetailsString(object.getInstance());\n        } else if (\"JavaPackage\".equals(type)) { // NOI18N\n            FieldValue nameField = object.getFieldValue(\"packageName (hidden)\"); // NOI18N\n            Instance name = nameField instanceof ObjectFieldValue ? ((ObjectFieldValue)nameField).getInstance() : null;\n//                Instance name = (Instance)getInstance().getValueOfField(\"object2\");\n            logicalValue = name == null ? null : DetailsSupport.getDetailsString(name);\n            if (logicalValue == null) logicalValue = DetailsSupport.getDetailsString(object.getInstance());\n        } else if (\"Object\".equals(type) || \"JSObject\".equals(type)) { // NOI18N\n            String head = \"properties [\"; // NOI18N\n            String sep = \", \"; // NOI18N\n            \n            StringBuilder sb = new StringBuilder();\n            sb.append(head);\n            \n            List<FieldValue> fields = object.getFieldValues();\n            for (FieldValue field : fields) {\n                String name = field.getField().getName();\n                if (!name.contains(\"(hidden)\")) sb.append(name).append(sep); // NOI18N\n            }\n            \n            int length = sb.length();\n            if (length > head.length()) sb.delete(length - sep.length(), length);\n            sb.append(\"]\"); // NOI18N\n            \n            logicalValue = sb.toString();\n        } else if (\"Array\".equals(type) || \"JSArray\".equals(type)) { // NOI18N\n            FieldValue lengthField = object.getFieldValue(\"length (hidden)\"); // NOI18N\n            if (lengthField == null) {\n                lengthField = object.getFieldValue(\"usedLength (hidden)\"); // NOI18N\n            }\n            Integer length;\n            if (lengthField != null) {\n                length = Integer.parseInt(lengthField.getValue());\n            } else {\n                length = (Integer) object.getInstance().getValueOfField(\"length\");\n            }\n            if (length != null) {\n                logicalValue = Formatters.numberFormat().format(length) + (length == 1 ? \" item\" : \" items\"); // NOI18N\n            }\n        } else if (\"Null$NullClass\".equals(type)) { // NOI18N\n            logicalValue = DetailsSupport.getDetailsString(object.getInstance());\n        } else if (\"Date\".equals(type) || \"JSDate\".equals(type)) { // NOI18N\n            FieldValue timeField = object.getFieldValue(\"timeMillis (hidden)\"); // NOI18N\n            if (timeField != null) {\n                double time = Double.parseDouble(timeField.getValue());\n                logicalValue = new Date((long)time).toString();\n            }\n        } else if (\"JSBoolean\".equals(type) || \"JSNumber\".equals(type)) { // NOI18N\n            FieldValue valueField = object.getFieldValue(\"value (hidden)\"); // NOI18N\n\n            if (valueField != null) {\n                if (valueField instanceof ObjectFieldValue) {\n                    Instance val = ((ObjectFieldValue)valueField).getInstance();\n                    logicalValue = DetailsSupport.getDetailsString(val);\n                } else {\n                    logicalValue = valueField.getValue();\n                }\n            }\n        } else if (\"String\".equals(type) || \"JSString\".equals(type)) { // NOI18N\n            FieldValue stringField = object.getFieldValue(\"string (hidden)\"); // NOI18N\n            if (stringField instanceof ObjectFieldValue) {\n                Instance val = ((ObjectFieldValue)stringField).getInstance();\n                logicalValue = DetailsSupport.getDetailsString(val);\n            }\n        } else if (\"Error\".equals(type)) { // NOI18N\n            FieldValue valueField = object.getFieldValue(\"name\"); // NOI18N\n\n            if (valueField != null) {\n                if (valueField instanceof ObjectFieldValue) {\n                    Instance val = ((ObjectFieldValue)valueField).getInstance();\n                    logicalValue = DetailsSupport.getDetailsString(val);\n                } else {\n                    logicalValue = valueField.getValue();\n                }\n            }\n        } else {\n            String rawType = DynamicObject.getType(object.getInstance());\n\n            if (!Objects.equals(type, rawType)) {\n                return getLogicalValue(object, rawType);\n            }\n        }\n        \n        if (logicalValue != null && logicalValue.length() > MAX_LOGVALUE_LENGTH)\n            logicalValue = logicalValue.substring(0, MAX_LOGVALUE_LENGTH) + \"...\"; // NOI18N\n\n        return logicalValue;\n    }\n    \n    \n    private static String computeObjectName(TruffleObjectNode.InstanceBased<JavaScriptObject> node) {\n        return node.getTruffleObject().computeDisplayType() + \"#\" + node.getInstance().getInstanceNumber(); // NOI18N\n    }\n    \n    private static JavaScriptObjectNode createCopy(TruffleObjectNode.InstanceBased<JavaScriptObject> node) {\n        return new JavaScriptObjectNode(node.getTruffleObject(), node.getTypeName());\n    }\n    \n    \n    static interface JavaScriptNode {}\n    \n    \n    static class JavaScriptObjectNode extends DynamicObjectNode<JavaScriptObject> implements JavaScriptNode {\n        \n        JavaScriptObjectNode(JavaScriptObject object, String type) {\n            super(object, type);\n        }\n        \n        \n        @Override\n        protected String computeObjectName() {\n            return JavaScriptNodes.computeObjectName(this);\n        }\n        \n        protected String computeLogicalValue(JavaScriptObject object, String type) {\n            String logicalValue = JavaScriptNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public JavaScriptObjectNode createCopy() {\n            JavaScriptObjectNode copy = JavaScriptNodes.createCopy(this);\n            setupCopy(copy);\n            return copy;\n        }\n\n        protected void setupCopy(JavaScriptObjectNode copy) {\n            super.setupCopy(copy);\n        }\n        \n    }\n    \n    static class JavaScriptTypeNode extends TruffleTypeNode<JavaScriptObject, JavaScriptType> implements JavaScriptNode {\n        \n        JavaScriptTypeNode(JavaScriptType type) {\n            super(type);\n        }\n\n        @Override\n        public HeapViewerNode createNode(JavaScriptObject object) {\n            String type = getType().getName();\n            return !type.startsWith(\"<\") ? new JavaScriptObjectNode(object, type) : // NOI18N\n                    new JavaScriptObjectNode(object, object.getType());\n        }\n\n        @Override\n        public TruffleTypeNode createCopy() {\n            JavaScriptTypeNode copy = new JavaScriptTypeNode(getType());\n            setupCopy(copy);\n            return copy;\n        }\n        \n        protected void setupCopy(JavaScriptTypeNode copy) {\n            super.setupCopy(copy);\n        }\n        \n    }\n    \n    static class JavaScriptObjectFieldNode extends DynamicObjectFieldNode<JavaScriptObject> implements JavaScriptNode {\n        \n        JavaScriptObjectFieldNode(JavaScriptObject object, String type, FieldValue field) {\n            super(object, type, field);\n        }\n        \n        @Override\n        protected String computeObjectName() {\n            return JavaScriptNodes.computeObjectName(this);\n        }\n        \n        protected String computeLogicalValue(JavaScriptObject object, String type) {\n            String logicalValue = JavaScriptNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public JavaScriptObjectNode createCopy() {\n            return JavaScriptNodes.createCopy(this);\n        }\n        \n    }\n    \n    static class JavaScriptObjectArrayItemNode extends DynamicObjectArrayItemNode<JavaScriptObject> implements JavaScriptNode {\n        \n        JavaScriptObjectArrayItemNode(JavaScriptObject object, String type, ArrayItemValue item) {\n            super(object, type, item);\n        }\n        \n        @Override\n        protected String computeObjectName() {\n            return JavaScriptNodes.computeObjectName(this);\n        }\n        \n        protected String computeLogicalValue(JavaScriptObject object, String type) {\n            String logicalValue = JavaScriptNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public JavaScriptObjectNode createCopy() {\n            return JavaScriptNodes.createCopy(this);\n        }\n        \n    }\n        \n    \n    static class JavaScriptObjectReferenceNode extends DynamicObjectReferenceNode<JavaScriptObject> implements JavaScriptNode {\n        \n        JavaScriptObjectReferenceNode(JavaScriptObject object, String type, FieldValue value) {\n            super(object, type, value);\n        }\n        \n        @Override\n        protected String computeObjectName() {\n            return JavaScriptNodes.computeObjectName(this);\n        }\n        \n        protected String computeLogicalValue(JavaScriptObject object, String type) {\n            String logicalValue = JavaScriptNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public JavaScriptObjectNode createCopy() {\n            return JavaScriptNodes.createCopy(this);\n        }\n        \n    }\n    \n    static class JavaScriptLocalObjectNode extends LocalDynamicObjectNode<JavaScriptObject> implements JavaScriptNode {\n        \n        JavaScriptLocalObjectNode(JavaScriptObject object, String type) {\n            super(object, type);\n        }\n        \n        @Override\n        protected String computeObjectName() {\n            return JavaScriptNodes.computeObjectName(this);\n        }\n        \n        protected String computeLogicalValue(JavaScriptObject object, String type) {\n            String logicalValue = JavaScriptNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public JavaScriptObjectNode createCopy() {\n            return JavaScriptNodes.createCopy(this);\n        }\n        \n    }\n    \n    \n    @ServiceProvider(service=HeapViewerRenderer.Provider.class)\n    public static class JavaScriptNodesRendererProvider extends HeapViewerRenderer.Provider {\n\n        public boolean supportsView(HeapContext context, String viewID) {\n            return true;\n        }\n\n        public void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers, HeapContext context) {\n            JavaScriptLanguage language = JavaScriptLanguage.instance();\n            Icon instanceIcon = language.createLanguageIcon(Icons.getIcon(LanguageIcons.INSTANCE));\n            Icon packageIcon = language.createLanguageIcon(Icons.getIcon(LanguageIcons.PACKAGE));\n\n            Heap heap = context.getFragment().getHeap();\n\n            renderers.put(JavaScriptNodes.JavaScriptObjectNode.class, new TruffleObjectNode.Renderer(heap, instanceIcon));\n\n            renderers.put(JavaScriptNodes.JavaScriptTypeNode.class, new TruffleTypeNode.Renderer(packageIcon));\n\n            renderers.put(JavaScriptNodes.JavaScriptObjectFieldNode.class, new TruffleObjectFieldNode.Renderer(heap, instanceIcon));\n\n            renderers.put(JavaScriptNodes.JavaScriptObjectArrayItemNode.class, new TruffleObjectArrayItemNode.Renderer(heap, instanceIcon));\n\n            renderers.put(JavaScriptNodes.JavaScriptObjectReferenceNode.class, new TruffleObjectReferenceNode.Renderer(heap, instanceIcon));\n\n            renderers.put(JavaScriptNodes.JavaScriptLocalObjectNode.class, new TruffleLocalObjectNode.Renderer(heap, instanceIcon));\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/javascript/JavaScriptObject.java",
    "content": "/*\n * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.javascript;\n\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JavaScriptObject extends DynamicObject {    \n    \n    JavaScriptObject(Instance instance) {\n        super(instance);\n    }\n    \n    JavaScriptObject(String type, Instance instance) {\n        super(type, instance); // NOI18N\n    }\n    \n    \n    @Override\n    protected String computeType() {\n        Heap heap = getInstance().getJavaClass().getHeap();\n        return JavaScriptLanguage.instance().fragmentFromHeap(heap).getObjectType(getInstance(), getShape());\n    }\n    \n    String computeDisplayType() {\n        String type = getType();\n        if (type.startsWith(\"<\")) { // NOI18N\n            type = super.computeType();\n            if (type.startsWith(\"JS\")) type = type.substring(2); // NOI18N\n        }\n        return type;\n    }\n    \n    \n    boolean isJavaScriptObject() {\n        return JavaScriptHeapFragment.JS_LANG_ID.equals(getLanguageId().getName());\n    }\n    \n    static boolean isJavaScriptObject(Instance instance) {\n        return DynamicObject.isDynamicObject(instance) &&\n               JavaScriptHeapFragment.JS_LANG_ID.equals(DynamicObject.getLanguageId(instance).getName());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/javascript/JavaScriptObjectProperties.java",
    "content": "/*\n * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.javascript;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleInstancePropertyProvider;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObjectPropertyProvider;\nimport org.graalvm.visualvm.heapviewer.utils.HeapOperations;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.util.lookup.ServiceProviders;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaScriptObjectProperties_Properties=properties\",\n    \"JavaScriptObjectProperties_Items=items\",\n    \"JavaScriptObjectProperties_References=references\"\n})\nfinal class JavaScriptObjectProperties {\n    \n    // -------------------------------------------------------------------------\n    // --- Fields --------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProviders(value={\n        @ServiceProvider(service=HeapViewerNode.Provider.class, position = 200),\n        @ServiceProvider(service=FieldsProvider.class, position = 200)}\n    )\n    public static class FieldsProvider extends TruffleObjectPropertyProvider.Fields<JavaScriptObject, JavaScriptType, JavaScriptHeapFragment, JavaScriptLanguage> {\n\n        public FieldsProvider() {\n            super(Bundle.JavaScriptObjectProperties_Properties(), JavaScriptLanguage.instance(), true);\n        }\n\n\n        @Override\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"javascript_\") && !viewID.endsWith(\"_references\"); // NOI18N\n        }\n\n        @Override\n        public boolean supportsNode(HeapViewerNode node, Heap heap, String viewID) {\n            return node instanceof JavaScriptNodes.JavaScriptNode && !(node instanceof JavaScriptNodes.JavaScriptObjectReferenceNode);\n        }\n\n        @Override\n        protected HeapViewerNode createObjectFieldNode(JavaScriptObject object, String type, FieldValue field) {\n            return new JavaScriptNodes.JavaScriptObjectFieldNode(object, type, field);\n        }\n\n        @Override\n        protected Collection<FieldValue> getPropertyItems(JavaScriptObject object) {\n            List<FieldValue> fields = new ArrayList<>();\n\n            fields.addAll(object.getFieldValues());\n            fields.addAll(object.getStaticFieldValues());\n\n            return fields;\n        }\n\n        @Override\n        protected boolean includeInstance(Instance instance) {\n            String className = instance.getJavaClass().getName();\n\n            if (className.startsWith(\"java.lang.\") || // NOI18N\n                className.startsWith(\"java.math.\") || // NOI18N\n                className.startsWith(\"com.oracle.truffle.js.runtime.objects.\") || // NOI18N\n                className.startsWith(\"com.oracle.truffle.api.object.DynamicObject[]\") || // NOI18N\n                className.startsWith(\"com.oracle.truffle.api.strings.\"))             // NOI18N\n                return true;\n\n            return false;\n        }\n\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Items ---------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewerNode.Provider.class, position = 300)\n    public static class ArrayItemsProvider extends TruffleInstancePropertyProvider.ArrayItems<JavaScriptObject, JavaScriptType, JavaScriptHeapFragment, JavaScriptLanguage> {\n\n        public ArrayItemsProvider() {\n            super(Bundle.JavaScriptObjectProperties_Items(), JavaScriptLanguage.instance(), false);\n        }\n\n\n        @Override\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"javascript_\"); // NOI18N\n        }\n\n\n        @Override\n        protected HeapViewerNode createObjectArrayItemNode(JavaScriptObject object, String type, ArrayItemValue item) {\n            return new JavaScriptNodes.JavaScriptObjectArrayItemNode(object, type, item);\n        }\n\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- References ----------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProviders(value={\n        @ServiceProvider(service=HeapViewerNode.Provider.class, position = 400),\n        @ServiceProvider(service=ReferencesProvider.class, position = 400)}\n    )\n    public static class ReferencesProvider extends TruffleObjectPropertyProvider.References<JavaScriptObject, JavaScriptType, JavaScriptHeapFragment, JavaScriptLanguage> {\n\n        public ReferencesProvider() {\n            super(Bundle.JavaScriptObjectProperties_References(), JavaScriptLanguage.instance(), false);\n        }\n\n\n        @Override\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"javascript_\") && !viewID.endsWith(\"_fields\"); // NOI18N\n        }\n\n        @Override\n        public boolean supportsNode(HeapViewerNode node, Heap heap, String viewID) {\n            return node instanceof JavaScriptNodes.JavaScriptNode && !(node instanceof JavaScriptNodes.JavaScriptObjectFieldNode || node instanceof JavaScriptNodes.JavaScriptObjectArrayItemNode);\n        }\n\n        @Override\n        protected HeapViewerNode createObjectReferenceNode(JavaScriptObject object, String type, FieldValue field) {\n            return new JavaScriptNodes.JavaScriptObjectReferenceNode(object, type, field);\n        }\n\n        @Override\n        protected Collection<FieldValue> getPropertyItems(JavaScriptObject object) throws InterruptedException {\n            HeapOperations.initializeReferences(object.getInstance().getJavaClass().getHeap());\n            return object.getReferences();\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/javascript/JavaScriptType.java",
    "content": "/*\n * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.javascript;\n\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleType;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JavaScriptType extends TruffleType.InstanceBased<JavaScriptObject> {\n    \n    JavaScriptType(String name) {\n        super(name);\n    }\n\n    \n    @Override\n    protected JavaScriptObject createObject(Instance i) {\n        return new JavaScriptObject(getName(), i);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/javascript/JavaScriptViewPlugins.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.javascript;\n\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObjectPreviewPlugin;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObjectPropertyPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaScriptViewPlugins_PropertiesName=Properties\",\n    \"JavaScriptViewPlugins_PropertiesDescription=Properties\",\n    \"JavaScriptViewPlugins_ReferencesName=References\",\n    \"JavaScriptViewPlugins_ReferencesDescription=References\"\n})\nfinal class JavaScriptViewPlugins {\n    \n    // -------------------------------------------------------------------------\n    // --- Preview -------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    static class PreviewPlugin extends TruffleObjectPreviewPlugin {\n    \n        PreviewPlugin(HeapContext context) {\n            super(context);\n        }\n\n\n        @Override\n        protected boolean supportsNode(HeapViewerNode node) {\n            return node instanceof JavaScriptNodes.JavaScriptObjectNode;\n        }\n\n        @Override\n        protected Instance getPreviewInstance(HeapViewerNode node) {\n            JavaScriptNodes.JavaScriptObjectNode jsnode = (JavaScriptNodes.JavaScriptObjectNode)node;\n            if (\"Function\".equals(jsnode.getTypeName()) || \"JSFunction\".equals(jsnode.getTypeName())) { // NOI18N\n                JavaScriptObject jsobj = jsnode.getTruffleObject();\n                FieldValue dataField = jsobj.getFieldValue(\"functionData (hidden)\"); // NOI18N\n                Instance data = dataField instanceof ObjectFieldValue ? ((ObjectFieldValue)dataField).getInstance() : null;\n                if (data == null) return null;\n\n                Object rootNode = ((Instance)data).getValueOfField(\"lazyInit\"); // NOI18N\n                if (!(rootNode instanceof Instance)) {\n                    Object callTarget = data.getValueOfField(\"callTarget\"); // NOI18N\n                    if (!(callTarget instanceof Instance)) return null;\n\n                    rootNode = ((Instance)callTarget).getValueOfField(\"rootNode\"); // NOI18N\n                    if (!(rootNode instanceof Instance)) return null;\n                }\n\n                Instance sourceSection = null;\n                List<FieldValue> rootNodeFields = ((Instance)rootNode).getFieldValues();\n                for (FieldValue field : rootNodeFields) {\n                    if (\"sourceSection\".equals(field.getField().getName()) && field instanceof ObjectFieldValue) { // NOI18N\n                        Instance instance = ((ObjectFieldValue)field).getInstance();\n                        if (instance != null) {\n                            sourceSection = instance;\n                            break;\n                        }\n                    }\n                }\n\n                if (!(sourceSection instanceof Instance)) {\n                    Object nnode = ((Instance)rootNode).getValueOfField(\"node\"); // NOI18N\n                    if (!(nnode instanceof Instance)) return null;\n\n                    Object ssourceSection = ((Instance)nnode).getValueOfField(\"source\"); // NOI18N\n                    if (!(ssourceSection instanceof Instance)) return null;\n\n                    sourceSection = (Instance)ssourceSection;\n                }\n\n                return (Instance)sourceSection;\n            } else {\n                return null;\n            }\n        }\n    \n    }\n    \n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 100)\n    public static class PreviewPluginProvider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (JavaScriptHeapFragment.isJavaScriptHeap(context))\n                return new PreviewPlugin(context);\n            return null;\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Fields --------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 200)\n    public static class FieldsPluginProvider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!JavaScriptHeapFragment.isJavaScriptHeap(context)) return null;\n            \n            JavaScriptObjectProperties.FieldsProvider fieldsProvider = Lookup.getDefault().lookup(JavaScriptObjectProperties.FieldsProvider.class);\n            return new TruffleObjectPropertyPlugin(Bundle.JavaScriptViewPlugins_PropertiesName(), Bundle.JavaScriptViewPlugins_PropertiesDescription(), Icons.getIcon(ProfilerIcons.NODE_FORWARD), \"javascript_objects_fields\", context, actions, fieldsProvider); // NOI18N\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- References ----------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 400)\n    public static class ReferencesPluginProvider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!JavaScriptHeapFragment.isJavaScriptHeap(context)) return null;\n            \n            JavaScriptObjectProperties.ReferencesProvider fieldsProvider = Lookup.getDefault().lookup(JavaScriptObjectProperties.ReferencesProvider.class);\n            return new TruffleObjectPropertyPlugin(Bundle.JavaScriptViewPlugins_ReferencesName(), Bundle.JavaScriptViewPlugins_ReferencesDescription(), Icons.getIcon(ProfilerIcons.NODE_REVERSE), \"javascript_objects_references\", context, actions, fieldsProvider); // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/javascript/JavaScriptViews.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.javascript;\n\nimport java.util.Collection;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.truffle.ui.TruffleObjectsView;\nimport org.graalvm.visualvm.heapviewer.truffle.ui.TruffleSummaryView;\nimport org.graalvm.visualvm.heapviewer.truffle.ui.TruffleThreadsView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.SummaryView;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JavaScriptViews_Platform=Platform:\",\n    \"JavaScriptViews_NotPresent=<not present>\",\n    \"JavaScriptViews_Unknown=<unknown>\"\n})\nfinal class JavaScriptViews {\n    \n    // -------------------------------------------------------------------------\n    // --- Summary -------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class SummaryViewProvider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (JavaScriptHeapFragment.isJavaScriptHeap(context))\n                return new TruffleSummaryView(JavaScriptLanguage.instance(), context, actions);\n\n            return null;\n        }\n\n    }\n    \n    \n    @ServiceProvider(service=SummaryView.ContentProvider.class, position = 100)\n    public static class SummaryOverviewProvider extends SummaryView.ContentProvider {\n\n        @Override\n        public HeapView createSummary(String viewID, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n            if (JavaScriptHeapFragment.isJavaScriptHeap(context))\n                return new SummaryOverview(context);\n            \n            return null;\n        }\n        \n    }\n    \n    private static class SummaryOverview extends TruffleSummaryView.OverviewSection {\n        \n        SummaryOverview(HeapContext context) {\n            super(context, 3, 3);\n        }\n        \n        protected void computeEnvironmentData(Object[][] environmentData) {\n            super.computeEnvironmentData(environmentData);\n            \n            environmentData[1][0] = \"Node.js:\"; // NOI18N\n            environmentData[2][0] = Bundle.JavaScriptViews_Platform();\n            \n            JavaScriptHeapFragment fragment = (JavaScriptHeapFragment)getContext().getFragment();\n            JavaScriptType processType = fragment.getType(\"process\", null); // NOI18N\n            JavaScriptObject process = processType == null || processType.getObjectsCount() == 0 ?\n                                              null : processType.getObjectsIterator().next();\n            \n            if (process == null) {\n                environmentData[1][1] = Bundle.JavaScriptViews_NotPresent();\n                environmentData[2][1] = Bundle.JavaScriptViews_Unknown();\n            } else {\n                Heap heap = fragment.getHeap();\n                \n                FieldValue releaseFV = process.getFieldValue(\"release\"); // NOI18N\n                if (releaseFV instanceof ObjectFieldValue) {\n                    Instance releaseI = ((ObjectFieldValue)releaseFV).getInstance();\n                    if (JavaScriptObject.isJavaScriptObject(releaseI)) {\n                        JavaScriptObject releaseO = new JavaScriptObject(releaseI);\n                        if (\"node\".equals(fieldValue(releaseO, \"name\", heap))) { // NOI18N\n                            String versionFV = fieldValue(process, \"version\", heap); // NOI18N\n                            String node = versionFV != null ? \"node \" + versionFV : Bundle.JavaScriptViews_Unknown(); // NOI18N\n                            String ltsFV = fieldValue(releaseO, \"lts\", heap); // NOI18N\n                            if (ltsFV != null) node += \" (\" + ltsFV + \")\"; // NOI18N\n                            environmentData[1][1] = node;\n                            \n                            String platformFV = fieldValue(process, \"platform\", heap); // NOI18N\n                            String archFV = fieldValue(process, \"arch\", heap); // NOI18N\n                            if (platformFV == null && archFV == null) {\n                                environmentData[2][1] = Bundle.JavaScriptViews_Unknown();\n                            } else {\n                                String platform = platformFV;\n                                if (archFV != null) {\n                                    if (platform != null) platform += \" \"; else platform = \"\"; // NOI18N\n                                    platform += archFV;\n                                }\n                                environmentData[2][1] = platform;\n                            }\n\n                            return;\n                        }                        \n                    }\n                    \n                    environmentData[1][1] = Bundle.JavaScriptViews_Unknown();\n                    environmentData[2][1] = Bundle.JavaScriptViews_Unknown();\n                    \n                    return;\n                }\n                \n                environmentData[1][1] = Bundle.JavaScriptViews_NotPresent();\n                environmentData[2][1] = Bundle.JavaScriptViews_Unknown();\n            }\n        }\n        \n        \n        private static String fieldValue(JavaScriptObject object, String field, Heap heap) {\n            FieldValue value = object == null ? null : object.getFieldValue(field);\n            Instance instance = value instanceof ObjectFieldValue ? ((ObjectFieldValue)value).getInstance() : null;\n            return instance == null ? null : DetailsSupport.getDetailsString(instance);\n        }\n\n    }\n    \n    \n    @ServiceProvider(service=SummaryView.ContentProvider.class, position = 300)\n    public static class SummaryObjectsProvider extends SummaryView.ContentProvider {\n\n        @Override\n        public HeapView createSummary(String viewID, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n            if (JavaScriptHeapFragment.isJavaScriptHeap(context))\n                return new TruffleSummaryView.ObjectsSection(JavaScriptLanguage.instance(), context, actions, actionProviders);\n            \n            return null;\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Objects -------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class ObjectsViewProvider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (JavaScriptHeapFragment.isJavaScriptHeap(context))\n                return new TruffleObjectsView(JavaScriptLanguage.instance(), context, actions);\n            \n            return null;\n        }\n\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Threads -------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class ThreadsViewProvider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (JavaScriptHeapFragment.isJavaScriptHeap(context))\n                return new TruffleThreadsView(JavaScriptLanguage.instance(), context, actions);\n            \n            return null;\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/python/PythonDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.python;\n\nimport java.util.List;\nimport java.util.UnknownFormatConversionException;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service = DetailsProvider.class)\npublic class PythonDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String PCLASS_MASK = \"com.oracle.graal.python.builtins.objects.type.PythonClass+\";   // NOI18N\n    private static final String PMANAGEDCLASS_MASK = \"com.oracle.graal.python.builtins.objects.type.PythonManagedClass+\";   // NOI18N\n    private static final String PFUNCTION_MASK = \"com.oracle.graal.python.builtins.objects.function.PFunction+\";   // NOI18N\n    private static final String PBUILTIN_FUNCTION_MASK = \"com.oracle.graal.python.builtins.objects.function.PBuiltinFunction\";   // NOI18N\n    private static final String PBUILTIN_METHOD_MASK = \"com.oracle.graal.python.builtins.objects.method.PBuiltinMethod\";   // NOI18N\n    private static final String PMETHOD_MASK = \"com.oracle.graal.python.builtins.objects.method.PMethod\";   // NOI18N\n    private static final String PDECORATEDMETHOD_MASK = \"com.oracle.graal.python.builtins.objects.method.PDecoratedMethod\";   // NOI18N\n    private static final String PCELL_MASK = \"com.oracle.graal.python.builtins.objects.cell.PCell\";   // NOI18N\n    private static final String PNONE_MASK = \"com.oracle.graal.python.builtins.objects.PNone\";   // NOI18N\n    private static final String PLIST_MASK = \"com.oracle.graal.python.builtins.objects.list.PList\";   // NOI18N\n    private static final String PSTRING_MASK = \"com.oracle.graal.python.builtins.objects.str.PString\"; // NOI18N\n    private static final String BASIC_STORAGE_MASK = \"com.oracle.graal.python.runtime.sequence.storage.BasicSequenceStorage+\";   // NOI18N\n    private static final String EMPTY_STORAGE_MASK = \"com.oracle.graal.python.runtime.sequence.storage.EmptySequenceStorage\"; // NOI18N\n    private static final String BYTE_STORAGE_MASK = \"com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage\"; // NOI18N\n    private static final String PTUPLE_MASK = \"com.oracle.graal.python.builtins.objects.tuple.PTuple\"; // NOI18N\n    private static final String PMODULE_MASK = \"com.oracle.graal.python.builtins.objects.module.PythonModule\"; // NOI18N\n    private static final String PBYTES_MASK = \"com.oracle.graal.python.builtins.objects.bytes.PBytes\"; // NOI18N\n    private static final String PCOMPLEX_MASK = \"com.oracle.graal.python.builtins.objects.complex.PComplex\"; // NOI18N\n    private static final String PINT_MASK = \"com.oracle.graal.python.builtins.objects.ints.PInt\"; // NOI18N\n    private static final String PEXCEPTION_MASK = \"com.oracle.graal.python.runtime.exception.PException\"; // NOI18N\n    private static final String PBASEEXCEPTION_MASK = \"com.oracle.graal.python.builtins.objects.exception.PBaseException\"; // NOI18N\n    private static final String GETSET_DESCRIPTOR_MASK = \"com.oracle.graal.python.builtins.objects.getsetdescriptor.GetSetDescriptor\"; // NOI18N\n    private static final String PBUILTIN_CLASSTYPE_MASK = \"com.oracle.graal.python.builtins.PythonBuiltinClassType\"; // NOI18N\n    private static final String PLAZY_STRING_MASK = \"com.oracle.graal.python.builtins.objects.str.LazyString\"; // NOI18N\n    private static final String PRANGE_MASK = \"com.oracle.graal.python.builtins.objects.range.PRange\"; // NOI18N\n    private static final String PSOCKET_MASK = \"com.oracle.graal.python.builtins.objects.socket.PSocket\"; // NOI18N\n    private static final String PFROOT_MASK = \"com.oracle.graal.python.nodes.function.FunctionRootNode\";    // NOI18N\n    private static final String PBFROOT_MASK = \"com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode\";    // NOI18N\n    private static final String PMFROOT_MASK = \"com.oracle.graal.python.nodes.ModuleRootNode\";                      // NOI18N\n    private static final String PGFROOT_MASK = \"com.oracle.graal.python.nodes.generator.GeneratorFunctionRootNode\"; // NOI18N\n    private static final String PTFROOT_MASK = \"com.oracle.graal.python.nodes.control.TopLevelExceptionHandler\";    // NOI18N\n    private static final String DICT_KEY_MASK = \"com.oracle.graal.python.builtins.objects.common.EconomicMapStorage$DictKey\";   // NOI18N\n    private static final String METHOD_NODE_MASK = \"com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes$MethodDescriptorRoot+\"; //NOI18N\n\n    public PythonDetailsProvider() {\n        super(PCLASS_MASK,PMANAGEDCLASS_MASK,PFUNCTION_MASK,PNONE_MASK,PLIST_MASK,\n              PSTRING_MASK,BASIC_STORAGE_MASK, PTUPLE_MASK,PMODULE_MASK,PBYTES_MASK,\n              EMPTY_STORAGE_MASK,PINT_MASK, PCOMPLEX_MASK,PEXCEPTION_MASK,\n              PBASEEXCEPTION_MASK, PBUILTIN_FUNCTION_MASK, PBUILTIN_METHOD_MASK,\n              PMETHOD_MASK, PDECORATEDMETHOD_MASK, PCELL_MASK, BYTE_STORAGE_MASK,\n              GETSET_DESCRIPTOR_MASK,PBUILTIN_CLASSTYPE_MASK, PLAZY_STRING_MASK,\n              PRANGE_MASK, PSOCKET_MASK, PFROOT_MASK, PBFROOT_MASK, PMFROOT_MASK,\n              PGFROOT_MASK, PTFROOT_MASK, DICT_KEY_MASK, METHOD_NODE_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case PCLASS_MASK:\n            case PMANAGEDCLASS_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n                if (name != null) {\n                    return name;\n                }\n                return DetailsUtils.getInstanceFieldString(instance, \"className\"); // NOI18N\n            }\n            case PBUILTIN_FUNCTION_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            case PBUILTIN_METHOD_MASK: {\n                Object moduleO = instance.getValueOfField(\"self\"); // NOI18N\n                if (!(moduleO instanceof Instance)) moduleO = null;\n                else if (!((Instance)moduleO).getJavaClass().getName().equals(PMODULE_MASK)) moduleO = null;\n                String module = moduleO == null ? null : DetailsUtils.getInstanceString((Instance)moduleO);\n                String function = DetailsUtils.getInstanceFieldString(instance, \"function\");    // NOI18N\n                if (function != null) return module != null ? module + \".\" + function : function;\n                break;\n            }\n            case PMETHOD_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"function\"); // NOI18N\n            case PDECORATEDMETHOD_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"callable\"); // NOI18N\n            case PCELL_MASK: {\n                Object refO = instance.getValueOfField(\"ref\");      // NOI18N\n                if (!(refO instanceof Instance)) refO = null;\n                else if (((Instance)refO).getJavaClass().getName().equals(PLIST_MASK)) refO = null;\n                else if (((Instance)refO).getJavaClass().getName().equals(PTUPLE_MASK)) refO = null;\n                return refO == null ? null : DetailsUtils.getInstanceString((Instance)refO);\n            }\n            case PFUNCTION_MASK: {\n                String enclName = DetailsUtils.getInstanceFieldString(instance, \"enclosingClassName\");    // NOI18N\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n\n                if (enclName != null && !enclName.isEmpty()) {\n                    if (name != null) {\n                        return enclName+\".\"+name; // NOI18N\n                    }\n                }\n                return name;\n            }\n            case PSTRING_MASK: {\n                String val = DetailsUtils.getInstanceFieldString(instance, \"materializedValue\");    // NOI18N\n                if (val != null) return val;\n                return DetailsUtils.getInstanceFieldString(instance, \"value\");    // NOI18N\n            }\n            case PBUILTIN_CLASSTYPE_MASK: {\n                // get name field of PythonBuiltinClassType - there is a conflict with name field from Enum\n                for (Object fv : instance.getFieldValues()) {\n                    if (fv instanceof ObjectFieldValue) {\n                        ObjectFieldValue ofv = (ObjectFieldValue) fv;\n                        if (\"name\".equals(ofv.getField().getName())) { // NOI18N\n                            return DetailsUtils.getInstanceString(ofv.getInstance());\n                        }\n                    }\n                }\n                break;\n            }\n            case PNONE_MASK:\n                return \"None\"; // NOI18N\n            case PLIST_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"store\");    // NOI18N\n            case BASIC_STORAGE_MASK:\n                return DetailsUtils.getIntFieldValue(instance, \"length\", 0) + \" items\"; // NOI18N\n            case EMPTY_STORAGE_MASK:\n                return \"0 items\"; // NOI18N\n            case PTUPLE_MASK: {\n                String value = DetailsUtils.getInstanceFieldString(instance, \"array\");    // NOI18N\n                if (value == null) {\n                    return DetailsUtils.getInstanceFieldString(instance, \"store\");    // NOI18N\n                }\n                return value;\n            }\n            case PMODULE_MASK: {\n                String value = DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n                if (value == null) {\n                    Instance storageInst = (Instance) instance.getValueOfField(\"storage\");   // NOI18N\n                    if (storageInst == null && DynamicObject.isDynamicObject(instance)) {\n                        storageInst = instance;\n                    }\n                    if (storageInst != null) {\n                        DynamicObject attrubutes = new DynamicObject(storageInst);\n                        FieldValue nameAttr = attrubutes.getFieldValue(\"__name__\"); // NOI18N\n                        if (nameAttr instanceof ObjectFieldValue) {\n                            Instance moduleName = ((ObjectFieldValue)nameAttr).getInstance();\n                            return DetailsSupport.getDetailsString(moduleName);\n                        }\n                    }\n                }\n                break;\n            }\n            case PBYTES_MASK: {\n                String bytes = DetailsUtils.getPrimitiveArrayFieldString(instance, \"bytes\", 0, -1, \",\", \"...\"); // NOI18N\n                if (bytes == null) {\n                    return DetailsUtils.getInstanceFieldString(instance, \"store\"); // NOI18N\n                }\n                break;\n            }\n            case PCOMPLEX_MASK: {\n                Double realObj = (Double) instance.getValueOfField(\"real\");    // NOI18N\n                Double imagObj = (Double) instance.getValueOfField(\"imag\");    // NOI18N\n                if (realObj != null && imagObj != null) {\n                    return complexToString(realObj.doubleValue(), imagObj.doubleValue());\n                }\n                break;\n            }\n            case PINT_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"value\"); // NOI18N\n            case PEXCEPTION_MASK: {\n                String message = DetailsUtils.getInstanceFieldString(instance, \"message\"); // NOI18N\n                return message != null ? message : DetailsUtils.getInstanceFieldString(instance, \"pythonException\"); // NOI18N\n            }\n            case PBASEEXCEPTION_MASK: {\n                String message = DetailsUtils.getInstanceFieldString(instance, \"messageFormat\"); // NOI18N\n                if (message != null) {\n                    Object args = instance.getValueOfField(\"messageArgs\"); // NOI18N\n                    if (args instanceof ObjectArrayInstance) {\n                        List<Instance> vals = ((ObjectArrayInstance)args).getValues();\n                        Object[] params = new String[vals.size()];\n                        for (int i = 0; i < params.length; i++)\n                            params[i] = DetailsUtils.getInstanceString(vals.get(i));\n                        message = safeFormatString(3, message, params);\n                    }\n                    return message;\n                }\n\n                Object args = instance.getValueOfField(\"args\"); // NOI18N\n                if (args instanceof Instance) {\n                    Object store = ((Instance)args).getValueOfField(\"store\"); // NOI18N\n                    if (store instanceof Instance) {\n                        Object values = ((Instance)store).getValueOfField(\"values\"); // NOI18N\n                        if (values instanceof ObjectArrayInstance) {\n                            ObjectArrayInstance arr = (ObjectArrayInstance)values;\n                            if (arr.getLength() > 0) {\n                                Instance val = arr.getValues().get(0);\n                                if (val != null) return DetailsUtils.getInstanceString(val);\n                            }\n                        }\n                    }\n                }\n                break;\n            }\n            case BYTE_STORAGE_MASK:\n                return DetailsUtils.getPrimitiveArrayFieldString(instance, \"values\", 0, -1, \",\", \"...\"); // NOI18N\n            case GETSET_DESCRIPTOR_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            case PLAZY_STRING_MASK: {\n                Object vall = instance.getValueOfField(\"left\");   // NOI18N\n                Object valr = instance.getValueOfField(\"right\");   // NOI18N\n                String left = DetailsUtils.getInstanceString((Instance)vall);\n\n                if (valr == null || left.length() > DetailsUtils.MAX_ARRAY_LENGTH) {\n                    return left;\n                }\n                return left + DetailsUtils.getInstanceString((Instance)valr);\n            }\n            case PRANGE_MASK: {\n                int start = DetailsUtils.getIntFieldValue(instance, \"start\", 0); // NOI18N\n                int stop = DetailsUtils.getIntFieldValue(instance, \"stop\", 0); // NOI18N\n                int step = DetailsUtils.getIntFieldValue(instance, \"step\", 1); // NOI18N\n                return \"[\" + start + \", \" + stop + \", \" + step + \"]\"; // NOI18N\n            }\n            case PSOCKET_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"address\"); // NOI18N\n            case PFROOT_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"functionName\"); // NOI18N\n            case PBFROOT_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            case PMFROOT_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            case PGFROOT_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"originalName\"); // NOI18N\n            case PTFROOT_MASK:\n                return \"<module __main__>\"; // NOI18N\n            case DICT_KEY_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"value\"); // NOI18N\n            case METHOD_NODE_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            default:\n                break;\n        }\n        return null;\n    }\n\n    private static String complexToString(double real, double imag) {\n        if (Double.compare(real, 0.0) == 0) {\n            return toString(imag) + \"j\"; // NOI18N\n        } else {\n            String realString = toString(real);\n            if (real == 0.0) {\n                // special case where real is actually -0.0\n                realString = \"-0\";  // NOI18N\n            }\n            if (Double.compare(imag, 0.0) >= 0) {\n                return String.format(\"(%s+%sj)\", realString, toString(imag));   // NOI18N\n            } else {\n                return String.format(\"(%s-%sj)\", realString, toString(-imag));  // NOI18N\n            }\n        }\n    }\n\n    private static String toString(double value) {\n        if (value == Math.floor(value) && value <= Long.MAX_VALUE && value >= Long.MIN_VALUE) {\n            return Long.toString((long) value);\n        } else {\n            return Double.toString(value);\n        }\n    }\n    \n    private static String safeFormatString(int maxIterations, String format, Object... args) {\n        while (maxIterations-- > 0) {\n            try {\n                return String.format(format, args);\n            } catch (UnknownFormatConversionException e) {\n                format = format.replace(\"%\" + e.getConversion(), \"%s\"); // NOI18N\n            }\n        }\n        return format;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/python/PythonHeapFragment.java",
    "content": "/*\n * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.python;\n\nimport java.util.Iterator;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguageHeapFragment;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\n@NbBundle.Messages({\n    \"PythonHeapFragment_Name=Python Heap\"\n})\npublic class PythonHeapFragment extends TruffleLanguageHeapFragment<PythonObject, PythonType> {\n\n    private static final String PYTHON_HEAP_ID = \"python_heap\"; // NOI18N\n\n\n    PythonHeapFragment(PythonLanguage language, Instance langID, Heap heap) {\n        super(PYTHON_HEAP_ID, Bundle.PythonHeapFragment_Name(), fragmentDescription(langID), language, heap);\n    }\n    \n    \n    static PythonHeapFragment fromContext(HeapContext context) {\n        return (PythonHeapFragment)context.getFragment();\n    }\n    \n    static boolean isPythonHeap(HeapContext context) {\n        return PYTHON_HEAP_ID.equals(context.getFragment().getID());\n    }\n    \n    \n    @Override\n    public Iterator<Instance> getInstancesIterator() {\n        return instancesIterator(PythonObject.PYTHON_OBJECT_FQN);\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/python/PythonLanguage.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.python;\n\nimport org.graalvm.visualvm.heapviewer.HeapFragment;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguage;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.openide.util.Lookup;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.util.lookup.ServiceProviders;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProviders(value={\n    @ServiceProvider(service=HeapFragment.Provider.class, position = 300),\n    @ServiceProvider(service=PythonLanguage.class, position = 300)}\n)\npublic class PythonLanguage extends TruffleLanguage<PythonObject, PythonType, PythonHeapFragment> {\n    \n    private static final String ID = \"python\"; // NOI18N\n    \n    private static final String PYTHON_LANGINFO_ID_OLD = \"python\";  // NOI18N\n    private static final String PYTHON_LANGINFO_ID = \"Python\";  // NOI18N\n        \n    \n    private static PythonLanguage INSTANCE; \n    static synchronized PythonLanguage instance() {\n        if (INSTANCE == null) Lookup.getDefault().lookup(PythonLanguage.class);\n        return INSTANCE;\n    }\n    public PythonLanguage() { INSTANCE = this; }\n    \n    \n    public String getID() { return ID; }\n    \n    \n    @Override\n    protected PythonHeapFragment createFragment(Heap heap) {\n        Instance langID = getLanguageInfo(heap, PYTHON_LANGINFO_ID);\n        if (langID == null) langID = getLanguageInfo(heap, PYTHON_LANGINFO_ID_OLD);\n        if (langID == null) return null;\n        \n        JavaClass pythonMainClass = heap.getJavaClassByName(PythonObject.PYTHON_OBJECT_FQN);\n        if (pythonMainClass == null) return null;\n\n        return new PythonHeapFragment(this, langID, heap);\n    }\n    \n    \n    @Override\n    public Class<PythonObject> getLanguageObjectClass() {\n        return PythonObject.class;\n    }\n    \n\n    @Override\n    public boolean isLanguageObject(Instance instance) {\n        return PythonObject.isPythonObject(instance);\n    }\n    \n    @Override\n    public PythonObject createObject(Instance instance) {\n        return new PythonObject(instance);\n    }\n    \n    @Override\n    public PythonType createType(String name) {\n        return new PythonType(name);\n    }\n    \n    \n    @Override\n    public PythonNodes.PythonObjectNode createObjectNode(PythonObject object, String type) {\n        return new PythonNodes.PythonObjectNode(object, type);\n    }\n    \n    @Override\n    public PythonNodes.PythonLocalObjectNode createLocalObjectNode(PythonObject object, String type) {\n        return new PythonNodes.PythonLocalObjectNode(object, type);\n    }\n    \n    @Override\n    public PythonNodes.PythonTypeNode createTypeNode(PythonType type, Heap heap) {\n        return new PythonNodes.PythonTypeNode(type);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/python/PythonNodes.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.python;\n\nimport java.math.BigDecimal;\nimport java.math.BigInteger;\nimport java.util.List;\nimport java.util.Map;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleLocalObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectFieldNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectReferenceNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleOpenNodeActionProvider;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleTypeNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapViewerNodeAction.Provider.class)\npublic class PythonNodes extends TruffleOpenNodeActionProvider<PythonObject, PythonType, PythonHeapFragment, PythonLanguage> {\n    \n    @Override\n    public boolean supportsView(HeapContext context, String viewID) {\n        return PythonHeapFragment.isPythonHeap(context);\n    }\n    \n    @Override\n    protected boolean supportsNode(HeapViewerNode node) {\n        return node instanceof PythonNodes.PythonNode;\n    }\n\n    @Override\n    protected PythonLanguage getLanguage() {\n        return PythonLanguage.instance();\n    }\n    \n    \n    private static final int MAX_LOGVALUE_LENGTH = 160;\n    \n    static String getLogicalValue(PythonObject object, String type) {\n        String logicalValue = null;\n        \n        if (\"ModuleSpec\".equals(type)) { // NOI18N\n            List<FieldValue> attributes = object.getAttributes();\n            for (FieldValue attribute : attributes) {\n                if (\"name\".equals(attribute.getField().getName()) && attribute instanceof ObjectFieldValue) { // NOI18N\n                    Instance attributeI = ((ObjectFieldValue)attribute).getInstance();\n                    logicalValue = DetailsSupport.getDetailsString(attributeI);\n                    break;\n                }\n            }\n        } else if (\"SourceFileLoader\".equals(type)) { // NOI18N\n            List<FieldValue> attributes = object.getAttributes();\n            for (FieldValue attribute : attributes) {\n                if (\"path\".equals(attribute.getField().getName()) && attribute instanceof ObjectFieldValue) { // NOI18N\n                    Instance attributeI = ((ObjectFieldValue)attribute).getInstance();\n                    logicalValue = DetailsSupport.getDetailsString(attributeI);\n                    break;\n                }\n            }\n        } else if (\"mappingproxy\".equals(type)) { // NOI18N\n            List<FieldValue> attributes = object.getAttributes();\n            for (FieldValue attribute : attributes) {\n                if (\"__name__\".equals(attribute.getField().getName()) && attribute instanceof ObjectFieldValue) { // NOI18N\n                    Instance attributeI = ((ObjectFieldValue)attribute).getInstance();\n                    logicalValue = DetailsSupport.getDetailsString(attributeI);\n                    break;\n                }\n            }\n        } else if (\"generator\".equals(type)) { // NOI18N\n            logicalValue = DetailsUtils.getInstanceFieldString(object.getInstance(), \"name\"); // NOI18N\n        } else if (\"FileIO\".equals(type)) { // NOI18N\n            List<FieldValue> attributes = object.getAttributes();\n            for (FieldValue attribute : attributes) {\n                if (\"name\".equals(attribute.getField().getName()) && attribute instanceof ObjectFieldValue) { // NOI18N\n                    Instance attributeI = ((ObjectFieldValue)attribute).getInstance();\n                    logicalValue = DetailsSupport.getDetailsString(attributeI);\n                    break;\n                }\n            }\n        } else if (\"super\".equals(type)) { // NOI18N\n            Object moduleO = object.getInstance().getValueOfField(\"type\"); // NOI18N\n            if (!(moduleO instanceof Instance)) moduleO = null;\n            else if (!((Instance)moduleO).getJavaClass().getName().equals(\"com.oracle.graal.python.builtins.objects.type.PythonClass\")) moduleO = null; // NOI18N\n            logicalValue = moduleO == null ? null : DetailsUtils.getInstanceString((Instance)moduleO);\n        } else if (\"code\".equals(type)) { // NOI18N\n            Object callTarget = object.getInstance().getValueOfField(\"callTarget\"); // NOI18N\n            if (callTarget instanceof Instance) {\n                Object rootNode = ((Instance)callTarget).getValueOfField(\"rootNode\"); // NOI18N\n                if (rootNode instanceof Instance) {\n                    logicalValue = DetailsUtils.getInstanceFieldString((Instance)rootNode, \"functionName\"); // NOI18N\n                }\n            }\n        } else if (\"FileFinder\".equals(type)) { // NOI18N\n            List<FieldValue> attributes = object.getAttributes();\n            for (FieldValue attribute : attributes) {\n                if (\"path\".equals(attribute.getField().getName()) && attribute instanceof ObjectFieldValue) { // NOI18N\n                    Instance attributeI = ((ObjectFieldValue)attribute).getInstance();\n                    logicalValue = DetailsSupport.getDetailsString(attributeI);\n                    break;\n                }\n            }\n        } else if (\"BufferedReader\".equals(type) || \"BufferedWriter\".equals(type)) { // NOI18N\n            List<FieldValue> attributes = object.getAttributes();\n            for (FieldValue attribute : attributes) {\n                if (\"_raw\".equals(attribute.getField().getName()) && attribute instanceof ObjectFieldValue) { // NOI18N\n                    Instance attributeI = ((ObjectFieldValue)attribute).getInstance();\n                    if (PythonObject.isPythonObject(attributeI)) {\n                        logicalValue = getLogicalValue(new PythonObject(attributeI), \"FileIO\"); // NOI18N\n                        break;\n                    }\n                }\n            }\n        } else if (\"TextIOWrapper\".equals(type)) { // NOI18N\n            List<FieldValue> attributes = object.getAttributes();\n            for (FieldValue attribute : attributes) {\n                if (\"_buffer\".equals(attribute.getField().getName()) && attribute instanceof ObjectFieldValue) { // NOI18N\n                    Instance attributeI = ((ObjectFieldValue)attribute).getInstance();\n                    if (PythonObject.isPythonObject(attributeI)) {\n                        logicalValue = getLogicalValue(new PythonObject(attributeI), \"BufferedWriter\"); // NOI18N\n                        break;\n                    }\n                }\n            }\n        } else if (\"TemplateFormatter\".equals(type)) { // NOI18N\n            List<FieldValue> attributes = object.getAttributes();\n            for (FieldValue attribute : attributes) {\n                if (\"template\".equals(attribute.getField().getName()) && attribute instanceof ObjectFieldValue) { // NOI18N\n                    Instance attributeI = ((ObjectFieldValue)attribute).getInstance();\n                    logicalValue = DetailsSupport.getDetailsString(attributeI);\n                    break;\n                }\n            }\n        } else if (\"_Printer\".equals(type)) { // NOI18N\n            List<FieldValue> attributes = object.getAttributes();\n            for (FieldValue attribute : attributes) {\n                if (\"__name\".equals(attribute.getField().getName()) && attribute instanceof ObjectFieldValue) { // NOI18N\n                    Instance attributeI = ((ObjectFieldValue)attribute).getInstance();\n                    logicalValue = DetailsSupport.getDetailsString(attributeI);\n                    break;\n                }\n            }\n        } else if (\"Quitter\".equals(type)) { // NOI18N\n            List<FieldValue> attributes = object.getAttributes();\n            for (FieldValue attribute : attributes) {\n                if (\"name\".equals(attribute.getField().getName()) && attribute instanceof ObjectFieldValue) { // NOI18N\n                    Instance attributeI = ((ObjectFieldValue)attribute).getInstance();\n                    logicalValue = DetailsSupport.getDetailsString(attributeI);\n                    break;\n                }\n            }\n        } else if (\"CodecInfo\".equals(type)) { // NOI18N\n            List<FieldValue> attributes = object.getAttributes();\n            for (FieldValue attribute : attributes) {\n                if (\"name\".equals(attribute.getField().getName()) && attribute instanceof ObjectFieldValue) { // NOI18N\n                    Instance attributeI = ((ObjectFieldValue)attribute).getInstance();\n                    logicalValue = DetailsSupport.getDetailsString(attributeI);\n                    break;\n                }\n            }\n        } else if (\"dict\".equals(type)) { // NOI18N\n            List<FieldValue> attributes = object.getAttributes();\n            logicalValue = attributes.size() + \" pairs\"; // NOI18N\n        } else if (\"Decimal\".equals(type)) { // NOI18N\n            String _int = null;\n            String _exp = null;\n            String _sig = null;\n            String _is_special = null;\n\n            for (FieldValue attribute : object.getAttributes()) {\n                String attrName = attribute.getField().getName();\n\n                if (\"_int (hidden)\".equals(attrName)) { // NOI18N\n                    _int = getAttributeValue(attribute);\n                } else if (\"_exp (hidden)\".equals(attrName)) { // NOI18N\n                    _exp = getAttributeValue(attribute);\n                } else if (\"_sign (hidden)\".equals(attrName)) { // NOI18N\n                    _sig = getAttributeValue(attribute);\n                } else if (\"_is_special (hidden)\".equals(attrName)) { // NOI18N\n                    _is_special = getAttributeValue(attribute);\n                }\n            }\n            if (_int != null && _exp != null && _sig != null && _is_special != null) {\n                int _sigObj = Integer.valueOf(_sig);\n\n                if (_is_special.equals(Boolean.TRUE.toString())) {\n                    // special values\n                    String sign = _sigObj == 1 ? \"-\" : \"\";      // NOI18N\n                    if (\"F\".equals(_exp)) {                     // NOI18N\n                        return sign + \"Infinity\";               // NOI18N\n                    } else if (\"n\".equals(_exp)) {              // NOI18N\n                        return sign + \"NaN\" + _int;             // NOI18N\n                    } else if (\"N\".equals(_exp)) {              // NOI18N\n                        return sign + \"sNaN\" + _int;            // NOI18N\n                    }\n                }\n                BigInteger _intObj = new BigInteger(_int);\n                int _expObj = Integer.valueOf(_exp);\n                if (_sigObj == 1) {\n                    _intObj = _intObj.negate();\n                }\n                return new BigDecimal(_intObj, -_expObj).toString();\n            }\n        }\n        \n        if (logicalValue != null && logicalValue.length() > MAX_LOGVALUE_LENGTH)\n            logicalValue = logicalValue.substring(0, MAX_LOGVALUE_LENGTH) + \"...\"; // NOI18N\n        \n        return logicalValue != null ? logicalValue :\n               DetailsSupport.getDetailsString(object.getInstance());\n    }\n    \n    private static String getAttributeValue(FieldValue attribute) {\n        if (attribute instanceof ObjectFieldValue) {\n            Instance attributeI = ((ObjectFieldValue)attribute).getInstance();\n            return DetailsSupport.getDetailsString(attributeI);\n        }\n        return attribute.getValue();\n    }\n    \n    private static String computeObjectName(TruffleObjectNode.InstanceBased<PythonObject> node) {\n        String typeString = node.getTypeName();\n        return typeString.substring(typeString.lastIndexOf('.') + 1) + \"#\" + node.getInstance().getInstanceNumber(); // NOI18N\n    }\n    \n    private static PythonObjectNode createCopy(TruffleObjectNode.InstanceBased<PythonObject> node) {\n        return new PythonObjectNode(node.getTruffleObject(), node.getTypeName());\n    }\n    \n    \n    static interface PythonNode {}\n    \n    \n    static class PythonObjectNode extends TruffleObjectNode.InstanceBased<PythonObject> implements PythonNode {\n        \n        PythonObjectNode(PythonObject object) {\n            this(object, object.getType());\n        }\n\n        PythonObjectNode(PythonObject robject, String type) {\n            super(robject, type);\n        }\n        \n        \n        @Override\n        protected String computeObjectName() {\n            return PythonNodes.computeObjectName(this);\n        }\n        \n        protected String computeLogicalValue(PythonObject object, String type) {\n            String logicalValue = PythonNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public PythonObjectNode createCopy() {\n            PythonObjectNode copy = PythonNodes.createCopy(this);\n            setupCopy(copy);\n            return copy;\n        }\n\n        protected void setupCopy(PythonObjectNode copy) {\n            super.setupCopy(copy);\n        }\n        \n    }\n    \n    static class PythonLocalObjectNode extends TruffleLocalObjectNode.InstanceBased<PythonObject> implements PythonNode {\n        \n        PythonLocalObjectNode(PythonObject object, String type) {\n            super(object, type);\n        }\n        \n        @Override\n        protected String computeObjectName() {\n            return PythonNodes.computeObjectName(this);\n        }\n        \n        protected String computeLogicalValue(PythonObject object, String type) {\n            String logicalValue = PythonNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public PythonObjectNode createCopy() {\n            return PythonNodes.createCopy(this);\n        }\n        \n    }\n    \n    static class PythonTypeNode extends TruffleTypeNode<PythonObject, PythonType> implements PythonNode {\n        \n        PythonTypeNode(PythonType type) {\n            super(type);\n        }\n\n        @Override\n        public HeapViewerNode createNode(PythonObject object) {\n            String type = getType().getName();\n            return new PythonNodes.PythonObjectNode(object, type);\n        }\n\n        @Override\n        public TruffleTypeNode createCopy() {\n            PythonTypeNode copy = new PythonTypeNode(getType());\n            setupCopy(copy);\n            return copy;\n        }\n        \n        protected void setupCopy(PythonTypeNode copy) {\n            super.setupCopy(copy);\n        }\n        \n    }\n    \n    \n    static class PythonObjectFieldNode extends TruffleObjectFieldNode.InstanceBased<PythonObject> implements PythonNode {\n        \n        PythonObjectFieldNode(PythonObject object, String type, FieldValue field) {\n            super(object, type, field);\n        }\n        \n        @Override\n        protected String computeObjectName() {\n            return PythonNodes.computeObjectName(this); // NOI18N\n        }\n        \n        protected String computeLogicalValue(PythonObject object, String type) {\n            String logicalValue = PythonNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public PythonObjectNode createCopy() {\n            return PythonNodes.createCopy(this);\n        }\n        \n    }\n    \n    static class PythonObjectReferenceNode extends TruffleObjectReferenceNode.InstanceBased<PythonObject> implements PythonNode {\n        \n        PythonObjectReferenceNode(PythonObject object, String type, FieldValue value) {\n            super(object, type, value);\n        }\n        \n        @Override\n        protected String computeObjectName() {\n            return PythonNodes.computeObjectName(this);\n        }\n        \n        protected String computeLogicalValue(PythonObject object, String type) {\n            String logicalValue = PythonNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public PythonObjectNode createCopy() {\n            return PythonNodes.createCopy(this);\n        }\n        \n    }\n    \n    static class PythonObjectAttributeReferenceNode extends TruffleObjectReferenceNode.InstanceBased<PythonObject> implements PythonNode {\n        \n        PythonObjectAttributeReferenceNode(PythonObject object, String type, FieldValue value) {\n            super(object, type, value);\n        }\n        \n        @Override\n        protected String computeObjectName() {\n            return PythonNodes.computeObjectName(this);\n        }\n        \n        protected String computeLogicalValue(PythonObject object, String type) {\n            String logicalValue = PythonNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public PythonObjectNode createCopy() {\n            return PythonNodes.createCopy(this);\n        }\n        \n    }\n    \n    \n    @ServiceProvider(service=HeapViewerRenderer.Provider.class)\n    public static class PythonNodesRendererProvider extends HeapViewerRenderer.Provider {\n\n        public boolean supportsView(HeapContext context, String viewID) {\n            return true;\n        }\n\n        public void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers, HeapContext context) {\n            PythonLanguage language = PythonLanguage.instance();\n            Icon instanceIcon = language.createLanguageIcon(Icons.getIcon(LanguageIcons.INSTANCE));\n            Icon packageIcon = language.createLanguageIcon(Icons.getIcon(LanguageIcons.PACKAGE));\n\n            Heap heap = context.getFragment().getHeap();\n\n            renderers.put(PythonNodes.PythonObjectNode.class, new TruffleObjectNode.Renderer(heap, instanceIcon));\n\n            renderers.put(PythonNodes.PythonTypeNode.class, new TruffleTypeNode.Renderer(packageIcon));\n\n            renderers.put(PythonNodes.PythonObjectFieldNode.class, new TruffleObjectFieldNode.Renderer(heap, instanceIcon));\n\n            renderers.put(PythonNodes.PythonObjectReferenceNode.class, new TruffleObjectReferenceNode.Renderer(heap, instanceIcon));\n\n            renderers.put(PythonNodes.PythonObjectAttributeReferenceNode.class, new TruffleObjectReferenceNode.Renderer(heap, instanceIcon, \"attribute in\")); // NOI18N\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/python/PythonObject.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.python;\n\nimport java.util.AbstractList;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.Type;\nimport org.graalvm.visualvm.lib.jfluid.heap.Value;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass PythonObject extends TruffleObject.InstanceBased {\n\n//    public static final DataType<PythonObject> DATA_TYPE = new DataType<PythonObject>(PythonObject.class, null, null);\n\n    static final String PYTHON_OBJECT_FQN = \"com.oracle.graal.python.builtins.objects.object.PythonObject\"; // NOI18N\n    static final String PYTHON_LIST_FQN = \"com.oracle.graal.python.builtins.objects.list.PList\"; // NOI18N\n    static final String TREEMAP_ENTRY_FQN = \"java.util.TreeMap$Entry\";  // NOI18N\n    static final String TREEMAP_FQN = \"java.util.TreeMap\";  // NOI18N\n    private static final String HASHING_STORAGE_FQN = \"com.oracle.graal.python.builtins.objects.common.HashingStorage\";     // NOI18N\n\n    private final Instance instance;\n    private final Instance storage;\n    private final Instance store;\n    private final Instance dictStorage;\n    private final ObjectArrayInstance array;\n    private final Instance map;\n    private final Instance set;\n    private final Instance pythonClass;\n    private String listType;\n    private boolean isPrimitiveList;\n    \n    private String type;\n    \n    \n    PythonObject(Instance instance) {\n        this(null, instance);\n    }\n\n    PythonObject(String type, Instance instance) {\n        if (instance == null) throw new IllegalArgumentException(\"Instance cannot be null\"); // NOI18N\n        \n        this.instance = instance;\n        this.type = type;\n        \n        Object[] values = HeapUtils.getValuesOfFields(instance, \"storage\", \"pythonClass\",   // NOI18N\n                                    \"storedPythonClass\", \"initialPythonClass\",              // NOI18N\n                                    \"store\", \"array\", \"map\", \"set\", \"dictStorage\");         // NOI18N\n        \n        storage = computeStorage((Instance) values[0], instance);\n        pythonClass = computePythonClass((Instance) values[1], (Instance) values[2], (Instance) values[3], storage);\n        store = (Instance) values[4];\n        array = (ObjectArrayInstance) values[5];\n        map = (Instance) values[6];\n        set = (Instance) values[7];\n        dictStorage = computeDict((Instance) values[8], storage);\n    }\n    \n    private static Instance computeStorage(Instance storage, Instance pythonInstance) {\n        if (storage != null) return storage;\n        if (DynamicObject.isDynamicObject(pythonInstance)) return pythonInstance;\n        return null;\n    }\n    \n    private static Instance computeDict(Instance dict, Instance storage) {\n        if (dict != null) return dict;\n        if (isSubClassOf(storage, HASHING_STORAGE_FQN)) {\n            return storage;\n        }\n        return null;\n    }\n\n    private static Instance computePythonClass(Instance pythonClass, Instance storedPythonClass, Instance initialPythonClass, Instance storage) {\n        if (pythonClass != null) return pythonClass;\n        if (storedPythonClass != null) return storedPythonClass;\n        if (initialPythonClass != null) return initialPythonClass;\n        \n        // GR-16716\n        if (storage != null) {\n            Object shape = storage.getValueOfField(\"shape\"); // NOI18N\n            if (shape instanceof Instance) {\n                Object objectType = ((Instance)shape).getValueOfField(\"objectType\"); // NOI18N\n                if (objectType instanceof Instance) {\n                    Object lazyPythonClass = ((Instance)objectType).getValueOfField(\"lazyPythonClass\"); // NOI18N\n                    if (lazyPythonClass instanceof Instance) return (Instance)lazyPythonClass;\n                }\n            }\n        }\n        return null;\n    }\n\n    static boolean isPythonObject(Instance rObj) {\n        return isSubClassOf(rObj, PYTHON_OBJECT_FQN);\n    }\n\n    List<FieldValue> getItems() {\n        if (store != null || array != null) {\n            return getListFields();\n        }\n        return Collections.EMPTY_LIST;\n    }\n\n    List<FieldValue> getAttributes() {\n        if (map != null) {\n            return getMapFields();\n        }\n        if (set != null) {\n            return getSetFields();\n        }\n        if (dictStorage != null) {\n            return getDictFields();\n        }\n        return new DynamicObject(storage).getFieldValues();\n    }\n\n    @Override\n    public Instance getInstance() {\n        return instance;\n    }\n\n    @Override\n    public String getType() {\n        if (type == null) {\n            type = pythonClass == null ? null : DetailsUtils.getInstanceString(pythonClass);\n            if (type == null) type = \"<unknown type>\"; // NOI18N\n        }\n        return type;\n    }\n\n    @Override\n    public long getTypeId() {\n        return pythonClass == null ? Long.MIN_VALUE : pythonClass.getInstanceId();\n    }\n\n    @Override\n    public long getSize() {\n        long size = instance.getSize();\n        if (storage != null) {\n            size += storage.getSize();\n        }\n        if (store != null) {\n            size += store.getSize();\n        }\n        if (array != null) {\n            size += array.getSize();\n        }\n        return size;\n    }\n    \n    @Override\n    public long getRetainedSize() {\n        return instance.getRetainedSize();\n    }\n\n    List<FieldValue> getReferences() {\n        List<Value> refs = instance.getReferences();\n        List<FieldValue> robjRefs = new ArrayList<>();\n\n        for (Value ref : refs) {\n            Instance defInstance = ref.getDefiningInstance();\n            if (ref instanceof ArrayItemValue) {\n                if (defInstance instanceof ObjectArrayInstance) {\n                    List<Value> arrRefs = defInstance.getReferences();\n\n                    for (Value arrRef : arrRefs) {\n                        Instance pInstance = arrRef.getDefiningInstance();\n\n                        if (PythonObject.isPythonObject(pInstance)) {\n                            addItem(pInstance, ref, robjRefs);\n                        } else {\n                            Instance store = getReference(pInstance, PYTHON_OBJECT_FQN, \"store\"); // NOI18N\n                            if (PythonObject.isPythonObject(store)) {\n                                addItem(store, ref, robjRefs);\n                            }\n                        }\n                        addAttribute(pInstance, robjRefs);\n                    }\n                }\n            }\n            if (defInstance != null && defInstance.getJavaClass().getName().equals(TREEMAP_ENTRY_FQN)) {\n                FieldValue rootReference = findRootPMap(defInstance);\n\n                robjRefs.add(rootReference);\n            }\n            addAttribute(defInstance, robjRefs);\n        }\n        return robjRefs;\n    }\n\n    private void addItem(Instance pInstance, Value ref, List<FieldValue> robjRefs) {\n        PythonObject pobject = new PythonObject(pInstance);\n        int index = ((ArrayItemValue)ref).getIndex();\n        List<FieldValue> items = pobject.getItems();\n\n        if (index < items.size()) {\n            FieldValue fv = items.get(index);\n            if (fv instanceof ObjectFieldValue) {\n                ObjectFieldValue ofv = (ObjectFieldValue) fv;\n                if (instance.equals(ofv.getInstance())) {\n                    robjRefs.add(fv);\n                }\n            }\n        }\n    }\n\n    private FieldValue findRootPMap(Instance mapEntry) {\n        for (Instance parent = getParentTreeEntry(mapEntry); parent != null; parent = getParentTreeEntry(parent)) {\n            mapEntry = parent;\n        }\n        // top TreeMap$Entry\n        Instance treeMap = getReference(mapEntry, TREEMAP_FQN, \"root\"); // NOI18N\n        Instance pythonObject = getReference(treeMap, PYTHON_OBJECT_FQN, \"map\"); // NOI18N\n\n        if (isPythonObject(pythonObject)) {\n            for (FieldValue fv : new PythonObject(pythonObject).getAttributes()) {\n                if (fv instanceof ObjectFieldValue) {\n                    ObjectFieldValue ofv = (ObjectFieldValue) fv;\n                    if (instance.equals(ofv.getInstance())) {\n                        return fv;\n                    }\n                }\n            }\n        }\n        return null;\n    }\n\n    private Instance getParentTreeEntry(Instance treeEntry) {\n        return (Instance) treeEntry.getValueOfField(\"parent\"); // NOI18N\n    }\n\n    private Instance getReference(Instance instance, String definingClass, String fieldName) {\n        if (instance == null) return null;\n        List<Value> refs = instance.getReferences();\n        for (Value ref : refs) {\n            if (ref instanceof ObjectFieldValue) {\n               ObjectFieldValue fval = (ObjectFieldValue) ref;\n               Instance parent = fval.getDefiningInstance();\n\n               if (fval.getField().getName().equals(fieldName) && isSubClassOf(parent, definingClass)) {\n                   return parent;\n               }\n            }\n        }\n        return null;\n    }\n\n    private void addAttribute(Instance dynObjInstance, List<FieldValue> robjRefs) {\n        if (DynamicObject.isDynamicObject(dynObjInstance)) {\n            if (PythonObject.isPythonObject(dynObjInstance)) {\n                findAndAddAttribute(dynObjInstance, dynObjInstance, robjRefs);\n            } else {\n                List<Value> refs = dynObjInstance.getReferences();\n\n                for (Value ref : refs) {\n                    Instance defInstance = ref.getDefiningInstance();\n                    if (PythonObject.isPythonObject(defInstance)) {\n                        findAndAddAttribute(defInstance, dynObjInstance, robjRefs);\n                    }\n                }\n            }\n        }\n    }\n\n    private void findAndAddAttribute(Instance defInstance, Instance dynObjInstance, List<FieldValue> robjRefs) {\n        PythonObject pobject = new PythonObject(defInstance);\n\n        if (pobject.storage.equals(dynObjInstance)) {\n            for (FieldValue fv : pobject.getAttributes()) {\n                if (fv instanceof ObjectFieldValue) {\n                    ObjectFieldValue ofv = (ObjectFieldValue) fv;\n\n                    if (ofv.getInstance().equals(instance)) {\n                        robjRefs.add(fv);\n                    }\n                }\n            }\n        }\n    }\n\n    private List getValues() {\n        Instance vals = null;\n\n        if (store != null) {\n            vals = (Instance)store.getValueOfField(\"values\"); // NOI18N\n        }\n        if (array != null) {\n            vals = array;\n        }\n        if (vals != null) {\n            listType = vals.getJavaClass().getName().replace(\"[]\", \"\"); // NOI18N\n            if (vals instanceof ObjectArrayInstance) {\n                return ((ObjectArrayInstance)vals).getValues();\n            }\n            if (vals instanceof PrimitiveArrayInstance) {\n                isPrimitiveList = true;\n                return ((PrimitiveArrayInstance)vals).getValues();\n            }\n        }\n        return Collections.emptyList();\n    }\n\n    private int getLength() {\n        if (store != null) {\n            Integer len = (Integer) store.getValueOfField(\"length\"); // NOI18N\n\n            if (len != null) {\n                return len.intValue();\n            }\n            return 0;\n        }\n        if (array != null) {\n            return array.getLength();\n        }\n        return 0;\n    }\n\n    private static boolean isSubClassOf(Instance i, String superClassName) {\n        if (i != null) {\n            JavaClass superCls = i.getJavaClass();\n\n            for (; superCls != null; superCls = superCls.getSuperClass()) {\n                if (superCls.getName().equals(superClassName)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    private List<FieldValue> getListFields() {\n        return new LazyFieldValues(getValues());\n    }\n\n    private List<FieldValue> getMapFields() {\n        return getEntriesFromTreeMap(false, map);\n    }\n\n    private List<FieldValue> getDictFields() {\n        Instance fastStore = (Instance) dictStorage.getValueOfField(\"store\"); // NOI18N\n\n        if (DynamicObject.isDynamicObject(fastStore)) {\n            return new DynamicObject(fastStore).getFieldValues();\n        }\n        Instance keywords = (Instance) dictStorage.getValueOfField(\"keywords\"); // NOI18N\n        if (keywords instanceof ObjectArrayInstance) {\n            return getEntriesFromKeywords((ObjectArrayInstance) keywords);\n        }\n        return getEntriesFromEconomicMapStorage(false, dictStorage);\n    }\n\n    private List<FieldValue> getSetFields() {\n        Instance m = (Instance) set.getValueOfField(\"m\"); // NOI18N\n        if (m != null) {    // TreeMap\n            return getEntriesFromTreeMap(true, m);\n        }\n        // EconomicMapStorage\n        return getEntriesFromEconomicMapStorage(true, set);\n    }\n\n    private List<FieldValue> getEntriesFromKeywords(ObjectArrayInstance keywords) {\n        List<FieldValue> fields = new ArrayList<>();\n\n        for (Instance keyword : keywords.getValues()) {\n            if (keyword != null) {\n                fields.add(new PythonKeywordEntryFieldValue(false, keyword));\n            }\n        }\n        return fields;\n    }\n\n    private List<FieldValue> getEntriesFromEconomicMapStorage(boolean isSet, Instance economicMapStorage) {\n        Instance entries;\n        List<FieldValue> fields = new ArrayList<>();\n        Instance economicMap = (Instance) economicMapStorage.getValueOfField(\"map\"); // NOI18N\n        if (economicMap instanceof Instance) {\n            economicMapStorage = economicMap;\n        }\n        entries = (Instance) economicMapStorage.getValueOfField(\"entries\"); // NOI18N\n\n        if (entries instanceof ObjectArrayInstance) {\n            ObjectArrayInstance entriesArr = (ObjectArrayInstance) entries;\n            String mapClassName = economicMapStorage.getJavaClass().getName();\n            int size = entriesArr.getLength();\n            List<Instance> entriesList = entriesArr.getValues();\n\n            for (int i = 0; i < size; i+=2) {\n                Instance key = entriesList.get(i);\n                Instance value = entriesList.get(i+1);\n                if (key != null) {\n                    if (isSet) {\n                        fields.add(new PythonEconomicEntryFieldValue(key));\n                    } else {    // Map\n                        if (value instanceof Instance) {\n                            Instance ival = ((Instance)value);\n                            if (ival.getJavaClass().getName().startsWith(mapClassName)) {\n                                Instance linkValue = (Instance) ival.getValueOfField(\"value\"); // NOI18N\n                                if (linkValue != null) value = linkValue;\n                            }\n                        }\n                        fields.add(new PythonEconomicEntryFieldValue(key, value));\n                    }\n                }\n            }\n        }\n        return fields;\n    }\n\n    private List<FieldValue> getEntriesFromTreeMap(boolean isSet, Instance treeMap) {\n        List<FieldValue> fields = new ArrayList<>();\n        Instance rootEntry = (Instance) treeMap.getValueOfField(\"root\"); // NOI18N\n\n        getEntries(isSet, rootEntry, fields);\n        return fields;\n    }\n\n    private void getEntries(boolean isSet, Instance entry, List fields) {\n        if (entry != null) {\n            getEntries(isSet, (Instance) entry.getValueOfField(\"left\"), fields); // NOI18N\n            fields.add(new PythonMapEntryFieldValue(isSet, entry));\n            getEntries(isSet, (Instance) entry.getValueOfField(\"right\"), fields); // NOI18N\n        }\n    }\n\n    private class PythonEconomicEntryFieldValue extends AbstractPythonMapEntryFieldValue {\n        Instance key;\n        Instance value;\n\n        private PythonEconomicEntryFieldValue(Instance k) {\n            super(true);\n            key = k;\n        }\n\n        private PythonEconomicEntryFieldValue(Instance k, Instance v) {\n            super(false);\n            key = k;\n            value = v;\n        }\n\n        @Override\n        Instance getEntryKey() {\n            return key;\n        }\n\n        @Override\n        Instance getEntryValue() {\n            return value;\n        }\n    }\n\n    private class PythonKeywordEntryFieldValue extends AbstractPythonMapEntryFieldValue {\n        Instance keyword;\n\n        private PythonKeywordEntryFieldValue(boolean set, Instance k) {\n            super(set);\n            keyword = k;\n        }\n\n        @Override\n        Instance getEntryKey() {\n            return (Instance) keyword.getValueOfField(\"name\");  // NOI18N\n        }\n\n        @Override\n        Instance getEntryValue() {\n            return (Instance) keyword.getValueOfField(\"value\");  // NOI18N\n        }\n    }\n\n    private class PythonMapEntryFieldValue extends AbstractPythonMapEntryFieldValue {\n        Instance entry;\n\n        private PythonMapEntryFieldValue(boolean set, Instance e) {\n            super(set);\n            entry = e;\n        }\n\n        @Override\n        Instance getEntryKey() {\n            return (Instance) entry.getValueOfField(\"key\");  // NOI18N\n        }\n\n        @Override\n        Instance getEntryValue() {\n            return (Instance) entry.getValueOfField(\"value\");  // NOI18N\n        }\n    }\n\n    private abstract class AbstractPythonMapEntryFieldValue implements ObjectFieldValue {\n\n        boolean isSet;\n\n        private AbstractPythonMapEntryFieldValue(boolean set) {\n            isSet = set;\n        }\n\n        abstract Instance getEntryKey();\n        abstract Instance getEntryValue();\n\n        @Override\n        public Instance getInstance() {\n            if (isSet) {\n                return getEntryKey();\n            }\n            return getEntryValue();\n        }\n\n        @Override\n        public Field getField() {\n            if (isSet) {\n                return new PythonMapEntryField(\"item\"); // NOI18N\n            }\n            Instance key = getEntryKey();\n            String name = DetailsUtils.getInstanceString(key);\n            return new PythonMapEntryField(name);\n        }\n\n        @Override\n        public String getValue() {\n            return String.valueOf(getInstance().getInstanceId());\n        }\n\n        @Override\n        public Instance getDefiningInstance() {\n            return instance;\n        }\n\n    }\n\n    private class PythonMapEntryField extends PythonField {\n\n        String name;\n\n        private PythonMapEntryField(String n) {\n            super(0);\n            name = n;\n        }\n\n        @Override\n        public String getName() {\n            return name;\n        }\n    }\n\n    private class PythonFieldValue implements FieldValue {\n        private int index;\n        Object value;\n\n        private PythonFieldValue(int i, Object val) {\n            index = i;\n            value = val;\n        }\n\n        @Override\n        public Field getField() {\n            return new PythonField(index);\n        }\n\n        @Override\n        public String getValue() {\n            return (String)value;\n        }\n\n        @Override\n        public Instance getDefiningInstance() {\n            return instance;\n        }\n\n    }\n\n    private class PythonObjectFieldValue extends PythonFieldValue implements ObjectFieldValue {\n\n        private PythonObjectFieldValue(int i, Instance val) {\n            super(i,val);\n        }\n\n        @Override\n        public String getValue() {\n            return String.valueOf(getInstance().getInstanceId());\n        }\n\n        @Override\n        public Instance getInstance() {\n            return (Instance)value;\n        }\n    }\n\n    private class PythonField implements Field {\n\n        private int index;\n\n        private PythonField(int i) {\n            index = i;\n        }\n\n        @Override\n        public JavaClass getDeclaringClass() {\n            return instance.getJavaClass();\n        }\n\n        @Override\n        public String getName() {\n            return  \"[\"+index+\"]\"; // NOI18N\n        }\n\n        @Override\n        public boolean isStatic() {\n            return false;\n        }\n\n        @Override\n        public Type getType() {\n            return new PFieldType(listType);\n        }\n    }\n\n    private static class PFieldType implements Type {\n\n        private final String name;\n\n        PFieldType(String n) {\n            name = n;\n        }\n\n        @Override\n        public String getName() {\n            return name;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof PFieldType) {\n                return getName().equals(((PFieldType)obj).getName());\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            return getName().hashCode();\n        }\n    }\n\n    private class LazyFieldValues extends AbstractList<FieldValue> {\n\n        List values;\n\n        private LazyFieldValues(List vals) {\n            values = vals;\n        }\n\n        @Override\n        public FieldValue get(int index) {\n            if (isPrimitiveList) {\n                return new PythonFieldValue(index, values.get(index));\n            }\n            return new PythonObjectFieldValue(index, (Instance) values.get(index));\n        }\n\n        @Override\n        public int size() {\n            return getLength();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/python/PythonObjectProperties.java",
    "content": "/*\n * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.python;\n\nimport java.util.Collection;\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObjectPropertyProvider;\nimport org.graalvm.visualvm.heapviewer.utils.HeapOperations;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.Value;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.util.lookup.ServiceProviders;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"PythonObjectProperties_Properties=attributes\",\n    \"PythonObjectProperties_Items=items\",\n    \"PythonObjectProperties_References=references\"\n})\nfinal class PythonObjectProperties {\n    \n    // -------------------------------------------------------------------------\n    // --- Attributes ----------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProviders(value={\n        @ServiceProvider(service=HeapViewerNode.Provider.class, position = 200),\n        @ServiceProvider(service=AttributesProvider.class, position = 200)}\n    )\n    public static class AttributesProvider extends TruffleObjectPropertyProvider.Fields<PythonObject, PythonType, PythonHeapFragment, PythonLanguage> {\n\n        public AttributesProvider() {\n            super(Bundle.PythonObjectProperties_Properties(), PythonLanguage.instance(), true);\n        }\n\n\n        @Override\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"python_\") && !viewID.endsWith(\"_references\"); // NOI18N\n        }\n\n        @Override\n        public boolean supportsNode(HeapViewerNode node, Heap heap, String viewID) {\n            if (node instanceof PythonNodes.PythonNode && !(node instanceof PythonNodes.PythonObjectReferenceNode || node instanceof PythonNodes.PythonObjectAttributeReferenceNode)) {\n                TruffleObject object = HeapViewerNode.getValue(node, TruffleObject.DATA_TYPE, heap);\n                PythonObject pyobject = object instanceof PythonObject ? (PythonObject)object : null;\n                if (pyobject != null) return !getPropertyItems(pyobject).isEmpty();\n            }\n            return false;\n        }\n\n        @Override\n        protected HeapViewerNode createObjectFieldNode(PythonObject object, String type, FieldValue field) {\n            return new PythonNodes.PythonObjectFieldNode(object, type, field);\n        }\n\n        @Override\n        protected Collection<FieldValue> getPropertyItems(PythonObject object) {\n            return object.getAttributes();\n        }\n\n        @Override\n        protected boolean includeInstance(Instance instance) {\n            String className = instance.getJavaClass().getName();\n\n            if (className.startsWith(\"java.lang.\") || // NOI18N\n                className.startsWith(\"java.math.\") || // NOI18N\n                className.startsWith(\"com.oracle.graal.python.runtime.datatype.\") || // NOI18N\n                className.startsWith(\"com.oracle.truffle.api.strings.\"))             // NOI18N\n                return true;\n\n            return false;\n        }\n\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Items ---------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProviders(value={\n        @ServiceProvider(service=HeapViewerNode.Provider.class, position = 300),\n        @ServiceProvider(service=ItemsProvider.class, position = 300)}\n    )\n    public static class ItemsProvider extends TruffleObjectPropertyProvider.Fields<PythonObject, PythonType, PythonHeapFragment, PythonLanguage> {\n\n        public ItemsProvider() {\n            super(Bundle.PythonObjectProperties_Items(), PythonLanguage.instance(), true);\n        }\n\n\n        @Override\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"python_\") && !viewID.endsWith(\"_references\"); // NOI18N\n        }\n\n        @Override\n        public boolean supportsNode(HeapViewerNode node, Heap heap, String viewID) {\n            if (node instanceof PythonNodes.PythonNode && !(node instanceof PythonNodes.PythonObjectReferenceNode || node instanceof PythonNodes.PythonObjectAttributeReferenceNode)) {\n                TruffleObject object = HeapViewerNode.getValue(node, TruffleObject.DATA_TYPE, heap);\n                PythonObject pyobject = object instanceof PythonObject ? (PythonObject)object : null;\n                if (pyobject != null) return !getPropertyItems(pyobject).isEmpty();\n            }\n            return false;\n        }\n\n        @Override\n        protected HeapViewerNode createObjectFieldNode(PythonObject object, String type, FieldValue field) {\n            return new PythonNodes.PythonObjectFieldNode(object, type, field);\n        }\n\n        @Override\n        protected Collection<FieldValue> getPropertyItems(PythonObject object) {\n            return object.getItems();\n        }\n\n        @Override\n        protected boolean includeInstance(Instance instance) {\n            String className = instance.getJavaClass().getName();\n\n            if (className.startsWith(\"java.lang.\") || // NOI18N\n                className.startsWith(\"java.math.\") || // NOI18N\n                className.startsWith(\"com.oracle.graal.python.runtime.datatype.\") || // NOI18N\n                className.startsWith(\"com.oracle.truffle.api.strings.\"))             // NOI18N\n                return true;\n\n            return false;\n        }\n        \n        @Override\n        protected String getMergedPropertiesKey() {\n            return null;\n        }\n\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- References ----------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProviders(value={\n        @ServiceProvider(service=HeapViewerNode.Provider.class, position = 400),\n        @ServiceProvider(service=ReferencesProvider.class, position = 400)}\n    )\n    public static class ReferencesProvider extends TruffleObjectPropertyProvider.References<PythonObject, PythonType, PythonHeapFragment, PythonLanguage> {\n\n        public ReferencesProvider() {\n            super(Bundle.PythonObjectProperties_References(), PythonLanguage.instance(), false);\n        }\n\n\n        @Override\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"python_\") && !viewID.endsWith(\"_attributes\"); // NOI18N\n        }\n\n        @Override\n        public boolean supportsNode(HeapViewerNode node, Heap heap, String viewID) {\n            return node instanceof PythonNodes.PythonNode && !(node instanceof PythonNodes.PythonObjectFieldNode);\n        }\n\n        @Override\n        protected HeapViewerNode createObjectReferenceNode(PythonObject object, String type, FieldValue field) {\n            return new PythonNodes.PythonObjectReferenceNode(object, type, field);\n        }\n\n        @Override\n        protected HeapViewerNode createForeignReferenceNode(Instance instance, FieldValue field, Heap heap) {\n            List<Value> references = instance.getReferences();\n            for (Value reference : references) {\n                instance = reference.getDefiningInstance();\n                if (getLanguage().isLanguageObject(instance)) {\n                    PythonObject robj = getLanguage().createObject(instance);\n                    return new PythonNodes.PythonObjectAttributeReferenceNode(robj, robj.getType(), field);\n                }\n            }\n\n            return super.createForeignReferenceNode(instance, field, heap);\n        }\n\n        @Override\n        protected Collection<FieldValue> getPropertyItems(PythonObject object) throws InterruptedException {\n            HeapOperations.initializeReferences(object.getInstance().getJavaClass().getHeap());\n            return object.getReferences();\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/python/PythonType.java",
    "content": "/*\n * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.python;\n\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleType;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass PythonType extends TruffleType.InstanceBased<PythonObject> {\n    \n    PythonType(String name) {\n        super(name);\n    }\n    \n    \n    @Override\n    protected PythonObject createObject(Instance i) {\n        return new PythonObject(getName(), i);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/python/PythonViewPlugins.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.python;\n\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObjectPropertyPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"PythonViewPlugins_PropertiesName=Attributes\",\n    \"PythonViewPlugins_PropertiesDescription=Attributes\",\n    \"PythonViewPlugins_ItemsName=Items\",\n    \"PythonViewPlugins_ItemsDescription=Items\",\n    \"PythonViewPlugins_ReferencesName=References\",\n    \"PythonViewPlugins_ReferencesDescription=References\"\n})\nfinal class PythonViewPlugins {\n    \n    // -------------------------------------------------------------------------\n    // --- Attributes ----------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 200)\n    public static class AttributesPluginProvider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!PythonHeapFragment.isPythonHeap(context)) return null;\n            \n            PythonObjectProperties.AttributesProvider fieldsProvider = Lookup.getDefault().lookup(PythonObjectProperties.AttributesProvider.class);\n            return new TruffleObjectPropertyPlugin(Bundle.PythonViewPlugins_PropertiesName(), Bundle.PythonViewPlugins_PropertiesDescription(), Icons.getIcon(ProfilerIcons.NODE_FORWARD), \"python_objects_attributes\", context, actions, fieldsProvider); // NOI18N\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Items ---------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 300)\n    public static class ItemsPluginProvider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!PythonHeapFragment.isPythonHeap(context)) return null;\n            \n            PythonObjectProperties.ItemsProvider fieldsProvider = Lookup.getDefault().lookup(PythonObjectProperties.ItemsProvider.class);\n            return new TruffleObjectPropertyPlugin(Bundle.PythonViewPlugins_ItemsName(), Bundle.PythonViewPlugins_ItemsDescription(), Icons.getIcon(ProfilerIcons.NODE_FORWARD), \"python_objects_items\", context, actions, fieldsProvider); // NOI18N\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- References ----------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 400)\n    public static class ReferencesPluginProvider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!PythonHeapFragment.isPythonHeap(context)) return null;\n            \n            PythonObjectProperties.ReferencesProvider fieldsProvider = Lookup.getDefault().lookup(PythonObjectProperties.ReferencesProvider.class);\n            return new TruffleObjectPropertyPlugin(Bundle.PythonViewPlugins_ReferencesName(), Bundle.PythonViewPlugins_ReferencesDescription(), Icons.getIcon(ProfilerIcons.NODE_REVERSE), \"python_objects_references\", context, actions, fieldsProvider); // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/python/PythonViews.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.python;\n\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.truffle.ui.TruffleObjectsView;\nimport org.graalvm.visualvm.heapviewer.truffle.ui.TruffleSummaryView;\nimport org.graalvm.visualvm.heapviewer.truffle.ui.TruffleThreadsView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.SummaryView;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"PythonViews_Version=Version:\",\n    \"PythonViews_Platform=Platform:\",\n    \"PythonViews_Unknown=<unknown>\"\n})\nfinal class PythonViews {\n    \n    // -------------------------------------------------------------------------\n    // --- Summary -------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class SummaryViewProvider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (PythonHeapFragment.isPythonHeap(context))\n                return new TruffleSummaryView(PythonLanguage.instance(), context, actions);\n\n            return null;\n        }\n\n    }\n    \n    \n    @ServiceProvider(service=SummaryView.ContentProvider.class, position = 100)\n    public static class SummaryOverviewProvider extends SummaryView.ContentProvider {\n\n        @Override\n        public HeapView createSummary(String viewID, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n            if (PythonHeapFragment.isPythonHeap(context))\n                return new SummaryOverview(context);\n            \n            return null;\n        }\n        \n    }\n    \n    private static class SummaryOverview extends TruffleSummaryView.OverviewSection {\n        \n        SummaryOverview(HeapContext context) {\n            super(context, 3, 3);\n        }\n        \n        protected void computeEnvironmentData(Object[][] environmentData) {\n            super.computeEnvironmentData(environmentData);\n            \n            environmentData[1][0] = Bundle.PythonViews_Version();\n            environmentData[2][0] = Bundle.PythonViews_Platform();\n            \n            PythonHeapFragment fragment = (PythonHeapFragment)getContext().getFragment();\n            PythonType moduleType = fragment.getType(\"module\", null); // NOI18N\n            \n            if (moduleType != null) {\n                PythonObject sysModule = null;\n                Iterator<PythonObject> objects = moduleType.getObjectsIterator();\n                while (objects.hasNext()) {\n                    PythonObject object = objects.next();\n                    if (\"sys\".equals(DetailsSupport.getDetailsString(object.getInstance()))) { // NOI18N\n                        sysModule = object;\n                        break;\n                    }\n                }\n                if (sysModule != null) {\n                    String version = attributeValue(sysModule, \"version\"); // NOI18N\n                    int graalInfoIdx = version == null ? -1 : version.indexOf('['); // NOI18N\n                    if (graalInfoIdx != -1) version = version.substring(0, graalInfoIdx);\n                    environmentData[1][1] = version;\n                    environmentData[2][1] = attributeValue(sysModule, \"platform\"); // NOI18N\n                    \n                    PythonObject implementation = attributeObject(sysModule, \"implementation\");      // NOI18N               \n                    if (implementation != null) {\n                        PythonObject _ns_ = attributeObject(implementation, \"__ns__\"); // NOI18N\n                        if (_ns_ != null) {\n                            environmentData[1][1] = attributeValue(_ns_, \"name\") + \" \" + version; // NOI18N\n                            environmentData[2][1] = attributeValue(_ns_, \"_multiarch\"); // NOI18N\n                        }\n                    }\n                }\n            }\n            \n            if (environmentData[1][1] == null) environmentData[1][1] = Bundle.PythonViews_Unknown();\n            if (environmentData[2][1] == null) environmentData[2][1] = Bundle.PythonViews_Unknown();\n        }\n        \n        private static PythonObject attributeObject(PythonObject object, String attribute) {\n            List<FieldValue> attributes = object.getAttributes();\n            for (FieldValue attr : attributes) {\n                if (attribute.equals(attr.getField().getName())) {\n                    Instance instance = attr instanceof ObjectFieldValue ? ((ObjectFieldValue)attr).getInstance() : null;\n                    return PythonObject.isPythonObject(instance) ? new PythonObject(instance) : null;\n                }\n            }\n            return null;\n        }\n        \n        private static String attributeValue(PythonObject object, String attribute) {\n            List<FieldValue> attributes = object.getAttributes();\n            for (FieldValue attr : attributes) {\n                if (attribute.equals(attr.getField().getName())) {\n                    Instance instance = attr instanceof ObjectFieldValue ? ((ObjectFieldValue)attr).getInstance() : null;\n                    return instance == null ? null : DetailsSupport.getDetailsString(instance);\n                }\n            }\n            return null;\n        }\n\n    }\n    \n    \n    @ServiceProvider(service=SummaryView.ContentProvider.class, position = 300)\n    public static class SummaryObjectsProvider extends SummaryView.ContentProvider {\n\n        @Override\n        public HeapView createSummary(String viewID, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n            if (PythonHeapFragment.isPythonHeap(context))\n                return new TruffleSummaryView.ObjectsSection(PythonLanguage.instance(), context, actions, actionProviders);\n            \n            return null;\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Objects -------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class ObjectsViewProvider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (PythonHeapFragment.isPythonHeap(context))\n                return new TruffleObjectsView(PythonLanguage.instance(), context, actions);\n\n            return null;\n        }\n\n    }\n\n\n    // -------------------------------------------------------------------------\n    // --- Threads -------------------------------------------------------------\n    // -------------------------------------------------------------------------\n\n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class ThreadsViewProvider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (PythonHeapFragment.isPythonHeap(context))\n                return new TruffleThreadsView(PythonLanguage.instance(), context, actions);\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/r/RDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.r;\n\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service = DetailsProvider.class)\npublic class RDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String RVECTOR_MASK = \"com.oracle.truffle.r.runtime.data.RVector+\";   // NOI18N\n    private static final String RABSTRACT_VECTOR_MASK = \"com.oracle.truffle.r.runtime.data.model.RAbstractVector+\";   // NOI18N\n    private static final String RSCALAR_VECTOR_MASK = \"com.oracle.truffle.r.runtime.data.RScalarVector+\";     // NOI18N\n    private static final String RLOGICAL_VECTOR_FQN = \"com.oracle.truffle.r.runtime.data.RLogicalVector\";   // NOI18N\n    private static final String RLOGICAL_FQN = \"com.oracle.truffle.r.runtime.data.RLogical\";   // NOI18N\n    private static final String RCOMPLEX_VECTOR_FQN = \"com.oracle.truffle.r.runtime.data.RComplexVector\";   // NOI18N\n    private static final String RINT_SEQUENCE_FQN = \"com.oracle.truffle.r.runtime.data.RIntSequence\";   // NOI18N\n    private static final String RINT_SEQUENCE1_FQN = \"com.oracle.truffle.r.runtime.data.RIntSeqVectorData\";   // NOI18N\n    private static final String RDOUBLE_SEQUENCE_FQN = \"com.oracle.truffle.r.runtime.data.RDoubleSequence\";   // NOI18N\n    private static final String RDOUBLE_SEQUENCE1_FQN = \"com.oracle.truffle.r.runtime.data.RDoubleSeqVectorData\";   // NOI18N\n    private static final String RSTRING_SEQUENCE_FQN = \"com.oracle.truffle.r.runtime.data.RStringSequence\";   // NOI18N\n    private static final String RSTRING_SEQUENCE1_FQN = \"com.oracle.truffle.r.runtime.data.RStringSeqVectorData\";   // NOI18N\n    private static final String REXPRESSION_FQN = \"com.oracle.truffle.r.runtime.data.RExpression\";   // NOI18N\n    private static final String RWRAPPER_MASK = \"com.oracle.truffle.r.runtime.data.RForeignWrapper+\";  // NOI18N\n    private static final String RSYMBOL_MASK = \"com.oracle.truffle.r.runtime.data.RSymbol\"; //NOI18N\n    private static final String RFUNCTION_MASK = \"com.oracle.truffle.r.runtime.data.RFunction\"; //NOI18N\n    private static final String RS4OBJECT_MASK = \"com.oracle.truffle.r.runtime.data.RS4Object\"; // NOI18N\n    private static final String RNULL_MASK = \"com.oracle.truffle.r.runtime.data.RNull\"; // NOI18N\n    private static final String RENVIRONMENT_MASK = \"com.oracle.truffle.r.runtime.env.REnvironment+\";    // NOI18N\n    private static final String CHARSXPWRAPPER_FQN = \"com.oracle.truffle.r.runtime.data.CharSXPWrapper\";    // NOI18N\n\n    private static final byte LOGICAL_TRUE = 1;\n    private static final byte LOGICAL_FALSE = 0;\n    private static final byte LOGICAL_NA = -1;\n\n    public RDetailsProvider() {\n        super(RVECTOR_MASK, RABSTRACT_VECTOR_MASK, RSCALAR_VECTOR_MASK, RINT_SEQUENCE_FQN,\n              RINT_SEQUENCE1_FQN, RDOUBLE_SEQUENCE_FQN, RDOUBLE_SEQUENCE1_FQN,\n              RSTRING_SEQUENCE_FQN, RSTRING_SEQUENCE1_FQN, RWRAPPER_MASK, RSYMBOL_MASK,\n              RFUNCTION_MASK, RS4OBJECT_MASK, RNULL_MASK, RENVIRONMENT_MASK, CHARSXPWRAPPER_FQN);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case RVECTOR_MASK:\n            case RABSTRACT_VECTOR_MASK: {\n                Object rawData = RObject.findDataField(instance);\n\n                if (rawData != null) {\n                    int size;\n\n                    if (rawData instanceof ObjectArrayInstance) {\n                        ObjectArrayInstance data = (ObjectArrayInstance) rawData;\n                        size = data.getLength();\n                        if (size == 1) {\n                            Instance obj = data.getValues().get(0);\n                            if (REXPRESSION_FQN.equals(instance.getJavaClass().getName()) && obj != null) {\n                                String str = DetailsUtils.getInstanceFieldString(obj, \"type\"); // NOI18N\n                                if (str != null) return \"[\" + str + \"]\"; // NOI18N\n                            }\n                            return getValue(obj, false);\n                        }\n                    } else if (rawData instanceof PrimitiveArrayInstance) {\n                        PrimitiveArrayInstance data = (PrimitiveArrayInstance) rawData;\n                        size = data.getLength();\n                        if (size == 1) {\n                            boolean isLogical = RLOGICAL_VECTOR_FQN.equals(instance.getJavaClass().getName());\n                            return getValue(data.getValues().get(0), isLogical);\n                        }\n                        if (RCOMPLEX_VECTOR_FQN.equals(instance.getJavaClass().getName())) {\n                            size /= 2;\n                            if (size == 1) {\n                                List vals = data.getValues();\n                                return \"[\"+vals.get(0)+\"+\"+vals.get(1)+\"i]\"; // NOI18N\n                            }\n                        }\n                    } else {\n                        return null;\n                    }\n                    Boolean complete = getCompleteField(instance);\n                    Integer refCount = (Integer) instance.getValueOfField(\"refCount\"); // NOI18N\n                    String refString;\n\n                    switch (refCount.intValue()) {\n                        case 0:\n                            refString = \", temporary\"; // NOI18N\n                            break;\n                        case 1:\n                            refString = \"\"; // NOI18N\n                            break;\n                        case Integer.MAX_VALUE:\n                            refString = \", shared permanent\"; // NOI18N\n                            break;\n                        default:\n                            refString = \", shared\"; // NOI18N\n                    }\n                    return \"Size: \" + size + (complete && size>0 ? \", no NAs\" : \"\") +  refString; // NOI18N\n                }\n                String scalar = getScalar(instance);\n                if (scalar != null) {\n                    return scalar;\n                }\n                return DetailsUtils.getInstanceFieldString(instance, \"data\");\n            }\n            case RSYMBOL_MASK: {\n                Instance name = (Instance) instance.getValueOfField(\"name\");   // NOI18N\n                if (name != null) {\n                    return DetailsSupport.getDetailsString(name);\n                } else {\n                    name = (Instance) instance.getValueOfField(\"nameWrapper\");   // NOI18N\n                    return name == null ? null : DetailsUtils.getInstanceFieldString(name, \"contents\"); // NOI18N\n                }\n            }\n            case RFUNCTION_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\");\n                String packageName = DetailsUtils.getInstanceFieldString(instance, \"packageName\");\n\n                if (name != null && !name.isEmpty()) {\n                    if (packageName != null && !packageName.isEmpty()) {\n                        return packageName+\":::\"+name;\n                    }\n                    return name;\n                }\n                String value = DetailsUtils.getInstanceFieldString(instance, \"target\");     // NOI18N\n                return value == null || value.isEmpty() ? null : value;\n            }\n            case RSCALAR_VECTOR_MASK:\n                return getScalar(instance);\n            case RINT_SEQUENCE_FQN:\n            case RINT_SEQUENCE1_FQN: {\n                String val =  logicalValueForIntSeq(instance);\n                if (val != null) {\n                    return val;\n                }\n                break;\n            }\n            case RDOUBLE_SEQUENCE_FQN:\n            case RDOUBLE_SEQUENCE1_FQN: {\n                Double stride = (Double) instance.getValueOfField(\"stride\"); // NOI18N\n                Double start = (Double) instance.getValueOfField(\"start\"); // NOI18N\n                Integer len = (Integer) instance.getValueOfField(\"length\"); // NOI18N\n                if (stride != null && start != null & len != null) {\n                    int length = len.intValue();\n                    if (length == 0) {  // empty vector\n                        return \"[]\";    // NOI18N\n                    }\n                    double end = start.doubleValue()+ (length-1) * stride.doubleValue();\n                    return \"seq(\"+start+\",\"+end+\",\"+stride+\")\";     // NOI18N\n                }\n                break;\n            }\n            case RSTRING_SEQUENCE_FQN:\n            case RSTRING_SEQUENCE1_FQN: {\n                String val = logicalValueForIntSeq(instance);\n                if (val != null) {\n                    String prefix = DetailsUtils.getInstanceFieldString(instance, \"prefix\");  // NOI18N\n                    String suffix = DetailsUtils.getInstanceFieldString(instance, \"suffix\");  // NOI18N\n\n                    if (prefix != null && suffix != null) {\n                        return \"paste0(\\\"\"+prefix+\"\\\", \"+val+\", \\\"\"+suffix+\"\\\")\";\n                    }\n                }\n                break;\n            }\n            case RS4OBJECT_MASK:\n                return getRClassName(instance);\n            case RNULL_MASK:\n                return \"NULL\"; // NOI18N\n            case RWRAPPER_MASK: {\n                Instance delegate = (Instance) instance.getValueOfField(\"delegate\"); // NOI18N\n                if (delegate != null) {\n                    Instance proxy = (Instance) delegate.getValueOfField(\"proxy\"); // NOI18N\n\n                    if (proxy != null) {\n                        Object rawData = proxy.getValueOfField(\"val$values\"); // NOI18N\n\n                        if (rawData instanceof ObjectArrayInstance) {\n                            ObjectArrayInstance data = (ObjectArrayInstance) rawData;\n                            int size = data.getLength();\n                            if (size == 1) {\n                                return getValue(data.getValues().get(0), false)+\", foreign\"; // NOI18N\n                            }\n                            return \"Size: \" + size+\", foreign\"; // NOI18N\n                        }\n                    }\n                }\n                break;\n            }\n            case RENVIRONMENT_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\");  // NOI18N\n                if (name != null && !name.isEmpty()) {\n                    return name;\n                }\n                break;\n            }\n            case CHARSXPWRAPPER_FQN:\n                return DetailsUtils.getInstanceFieldString(instance, \"contents\");  // NOI18N\n            default:\n                break;\n        }\n         return null;\n    }\n\n    private String logicalValueForIntSeq(Instance instance) {\n        Integer stride = (Integer) instance.getValueOfField(\"stride\"); // NOI18N\n        Integer start = (Integer) instance.getValueOfField(\"start\"); // NOI18N\n        Integer len = (Integer) instance.getValueOfField(\"length\"); // NOI18N\n\n        if (stride != null && start != null & len != null) {\n            int length = len.intValue();\n            if (length == 0) {  // empty vector\n                return \"[]\";    // NOI18N\n            }\n            int end = start.intValue() + (length-1) * stride.intValue();\n            if (stride.intValue() == 1) {\n                return \"[\"+start.intValue()+\":\"+end+\"]\";    // NOI18N\n            }\n            return \"seq(\"+start+\",\"+end+\",\"+stride+\")\";     // NOI18N\n        }\n        return null;\n    }\n\n    private String getRClassName(Instance instance) {\n        Instance attributesInst = (Instance) instance.getValueOfField(\"attributes\");   // NOI18N\n        if (attributesInst != null) {\n            DynamicObject  attributes = new DynamicObject(attributesInst);\n            FieldValue classAttr = attributes.getFieldValue(\"class\"); // NOI18N\n            if (classAttr instanceof ObjectFieldValue) {\n                Instance classAttrName = ((ObjectFieldValue)classAttr).getInstance();\n                return \"Class: \" + DetailsSupport.getDetailsString(classAttrName); // NOI18N\n            } else {\n                classAttr = attributes.getFieldValue(\".S3Class\"); // NOI18N\n                if (classAttr instanceof ObjectFieldValue) {\n                    Instance classAttrName = ((ObjectFieldValue)classAttr).getInstance();\n                    if (RObject.isRObject(classAttrName)) {\n                        StringBuilder classes = new StringBuilder(\"S3Class: [\"); // NOI18N\n                        RObject vector = new RObject(classAttrName);\n                        List values = vector.getValues();\n\n                        for (int i=0; i<values.size(); i++) {\n                            Instance str = (Instance) values.get(i);\n                            classes.append(DetailsSupport.getDetailsString((Instance) str));\n                            if (i<values.size()-1) {\n                                classes.append(\", \"); // NOI18N\n                            }\n                        }\n                        return classes.append(']').toString(); // NOI18N\n                    }\n                    return \"S3Class: \" + DetailsSupport.getDetailsString(classAttrName); // NOI18N\n                }\n            }\n        }\n        return null;\n    }\n\n    private static String getValue(Object value, boolean isLogical) {\n        String valString;\n\n        if (value instanceof Instance) {\n            valString = DetailsSupport.getDetailsString((Instance) value);\n        } else {\n            valString = value.toString();\n        }\n        if (isLogical) {\n            int val = Integer.parseInt(valString);\n\n            if (val == LOGICAL_FALSE) {\n                valString = \"FALSE\"; // NOI18N\n            } else if (val == LOGICAL_TRUE) {\n                valString = \"TRUE\"; // NOI18N\n            } else if (val == LOGICAL_NA) {\n                valString = \"NA\"; // NOI18N\n            }\n        }\n        return \"[\"+valString+\"]\"; // NOI18N\n    }\n\n    private String getScalar(Instance instance) {\n        Object rawData = instance.getValueOfField(\"value\"); // NOI18N\n\n        if (rawData != null) {\n            boolean isLogical = RLOGICAL_FQN.equals(instance.getJavaClass().getName());\n            return getValue(rawData, isLogical);\n        }\n        Double realPart = (Double) instance.getValueOfField(\"realPart\");    // NOI18N\n        Double imaginaryPart = (Double) instance.getValueOfField(\"imaginaryPart\"); // NOI18N\n\n        if (realPart != null && imaginaryPart != null) {\n            return \"[\"+realPart+\"+\"+imaginaryPart+\"i]\"; // NOI18N\n        }\n        return null;\n    }\n\n    private static Boolean getCompleteField(Instance instance) {\n        Boolean complete = (Boolean) instance.getValueOfField(\"complete\"); // NOI18N\n        if (complete == null) {\n            Instance data = (Instance) instance.getValueOfField(\"data\"); // NOI18N\n            if (data != null) {\n                complete = (Boolean) data.getValueOfField(\"complete\"); // NOI18N\n            }\n        }\n        return complete == null ? Boolean.FALSE : complete;\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/r/RHeapFragment.java",
    "content": "/*\n * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.r;\n\nimport java.util.Iterator;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguageHeapFragment;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"RHeapFragment_Name=R Heap\"\n})\nclass RHeapFragment extends TruffleLanguageHeapFragment<RObject, RType> {\n    \n    private static final String R_HEAP_ID = \"r_heap\"; // NOI18N\n    \n    \n    RHeapFragment(RLanguage language, Instance langID, Heap heap) {\n        super(R_HEAP_ID, Bundle.RHeapFragment_Name(), fragmentDescription(langID), language, heap);\n    }\n    \n    \n    static RHeapFragment fromContext(HeapContext context) {\n        return (RHeapFragment)context.getFragment();\n    }\n    \n    \n    @Override\n    public Iterator<Instance> getInstancesIterator() {\n        String[] topClasses = new String[] { RObject.R_OBJECT_FQN, RObject.R_SCALAR_FQN, RObject.R_WRAPPER_FQN };\n        return instancesIterator(topClasses);\n    }\n    \n    @Override\n    public Iterator<RObject> getObjectsIterator() {\n        return super.getObjectsIterator();\n    }\n    \n    \n    static boolean isRHeap(HeapContext context) {\n        return R_HEAP_ID.equals(context.getFragment().getID());\n    }\n    \n    public static HeapContext getRContext(HeapContext context) {\n        if (isRHeap(context)) return context;\n        \n        for (HeapContext otherContext : context.getOtherContexts())\n            if (isRHeap(otherContext)) return otherContext;\n        \n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/r/RLanguage.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.r;\n\nimport org.graalvm.visualvm.heapviewer.HeapFragment;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguage;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.openide.util.Lookup;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.util.lookup.ServiceProviders;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProviders(value={\n    @ServiceProvider(service=HeapFragment.Provider.class, position = 400),\n    @ServiceProvider(service=RLanguage.class, position = 400)}\n)\npublic class RLanguage extends TruffleLanguage<RObject, RType, RHeapFragment> {\n    \n    private static final String ID = \"r\"; // NOI18N\n    \n    private static final String R_LANGINFO_ID = \"R\";  // NOI18N\n        \n    \n    private static RLanguage INSTANCE; \n    static synchronized RLanguage instance() {\n        if (INSTANCE == null) Lookup.getDefault().lookup(RLanguage.class);\n        return INSTANCE;\n    }\n    public RLanguage() { INSTANCE = this; }\n    \n    \n    public String getID() { return ID; }\n    \n    \n    @Override\n    protected RHeapFragment createFragment(Heap heap) {\n        Instance langID = getLanguageInfo(heap, R_LANGINFO_ID);\n        if (langID == null) return null;\n        \n        JavaClass rMainClass = heap.getJavaClassByName(RObject.R_OBJECT_FQN);\n        if (rMainClass == null) return null;\n\n        return new RHeapFragment(this, langID, heap);\n    }\n    \n    \n    @Override\n    public Class<RObject> getLanguageObjectClass() {\n        return RObject.class;\n    }\n    \n\n    @Override\n    public boolean isLanguageObject(Instance instance) {\n        return RObject.isRObject(instance);\n    }\n    \n    @Override\n    public RObject createObject(Instance instance) {\n        return new RObject(instance);\n    }\n    \n    @Override\n    public RType createType(String name) {\n        return new RType(name);\n    }\n    \n    \n    @Override\n    public RNodes.RObjectNode createObjectNode(RObject object, String type) {\n        return new RNodes.RObjectNode(object, type);\n    }\n    \n    @Override\n    public RNodes.RLocalObjectNode createLocalObjectNode(RObject object, String type) {\n        return new RNodes.RLocalObjectNode(object, type);\n    }\n    \n    @Override\n    public RNodes.RTypeNode createTypeNode(RType type, Heap heap) {\n        return new RNodes.RTypeNode(type);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/r/RNodes.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.r;\n\nimport java.util.Map;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleLocalObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectFieldNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectReferenceNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleOpenNodeActionProvider;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleTypeNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapViewerNodeAction.Provider.class)\npublic class RNodes extends TruffleOpenNodeActionProvider<RObject, RType, RHeapFragment, RLanguage> {\n    \n    @Override\n    public boolean supportsView(HeapContext context, String viewID) {\n        return RHeapFragment.isRHeap(context);\n    }\n    \n    @Override\n    protected boolean supportsNode(HeapViewerNode node) {\n        return node instanceof RNodes.RNode;\n    }\n\n    @Override\n    protected RLanguage getLanguage() {\n        return RLanguage.instance();\n    }\n    \n    \n    static String getLogicalValue(RObject object, String type) {\n        return DetailsSupport.getDetailsString(object.getInstance());\n    }\n    \n    \n    private static String computeObjectName(TruffleObjectNode.InstanceBased<RObject> node) {\n        if (\"com.oracle.truffle.r.runtime.data.RLogical\".equals(node.getInstance().getJavaClass().getName())) { // NOI18N\n            String valueString = node.getLogicalValue();\n            return \"logical#\" + valueString.substring(1, valueString.length() - 1); // NOI18N\n        } else {\n            String typeString = node.getTypeName();\n            return typeString.substring(typeString.lastIndexOf('.') + 1) + \"#\" + node.getInstance().getInstanceNumber(); // NOI18N\n        }\n    }\n    \n    private static RObjectNode createCopy(TruffleObjectNode.InstanceBased<RObject> node) {\n        return new RObjectNode(node.getTruffleObject(), node.getTypeName());\n    }\n    \n    \n    static interface RNode {}\n    \n    \n    static class RObjectNode extends TruffleObjectNode.InstanceBased<RObject> implements RNode {\n        \n        RObjectNode(RObject robject) {\n            this(robject, robject.getType());\n        }\n\n        RObjectNode(RObject robject, String type) {\n            super(robject, type);\n        }\n        \n        \n        @Override\n        protected String computeObjectName() {\n            return RNodes.computeObjectName(this);\n        }\n        \n        protected String computeLogicalValue(RObject object, String type) {\n            String logicalValue = RNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public RObjectNode createCopy() {\n            RObjectNode copy = RNodes.createCopy(this);\n            setupCopy(copy);\n            return copy;\n        }\n\n        protected void setupCopy(RObjectNode copy) {\n            super.setupCopy(copy);\n        }\n        \n    }\n    \n    static class RLocalObjectNode extends TruffleLocalObjectNode.InstanceBased<RObject> implements RNode {\n        \n        RLocalObjectNode(RObject object, String type) {\n            super(object, type);\n        }\n        \n        \n        @Override\n        protected String computeObjectName() {\n            return RNodes.computeObjectName(this);\n        }\n        \n        protected String computeLogicalValue(RObject object, String type) {\n            String logicalValue = RNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public RObjectNode createCopy() {\n            return RNodes.createCopy(this);\n        }\n        \n    }\n    \n    static class RTypeNode extends TruffleTypeNode<RObject, RType> implements RNode {\n        \n        RTypeNode(RType type) {\n            super(type);\n        }\n\n        @Override\n        public HeapViewerNode createNode(RObject object) {\n            String type = getType().getName();\n            return new RNodes.RObjectNode(object, type);\n        }\n\n        @Override\n        public TruffleTypeNode createCopy() {\n            RTypeNode copy = new RTypeNode(getType());\n            setupCopy(copy);\n            return copy;\n        }\n        \n        protected void setupCopy(RTypeNode copy) {\n            super.setupCopy(copy);\n        }\n        \n    }\n    \n    \n    static class RObjectFieldNode extends TruffleObjectFieldNode.InstanceBased<RObject> implements RNode {\n        \n        RObjectFieldNode(RObject object, String type, FieldValue field) {\n            super(object, type, field);\n        }\n        \n        @Override\n        protected String computeObjectName() {\n            return RNodes.computeObjectName(this); // NOI18N\n        }\n        \n        protected String computeLogicalValue(RObject object, String type) {\n            String logicalValue = RNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public RObjectNode createCopy() {\n            return RNodes.createCopy(this);\n        }\n        \n    }\n    \n    static class RObjectReferenceNode extends TruffleObjectReferenceNode.InstanceBased<RObject> implements RNode {\n        \n        RObjectReferenceNode(RObject object, String type, FieldValue value) {\n            super(object, type, value);\n        }\n        \n        @Override\n        protected String computeObjectName() {\n            return RNodes.computeObjectName(this);\n        }\n        \n        protected String computeLogicalValue(RObject object, String type) {\n            String logicalValue = RNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public RObjectNode createCopy() {\n            return RNodes.createCopy(this);\n        }\n        \n    }\n    \n    static class RObjectAttributeReferenceNode extends TruffleObjectReferenceNode.InstanceBased<RObject> implements RNode {\n        \n        RObjectAttributeReferenceNode(RObject object, String type, FieldValue value) {\n            super(object, type, value);\n        }\n        \n        @Override\n        protected String computeObjectName() {\n            return RNodes.computeObjectName(this);\n        }\n        \n        protected String computeLogicalValue(RObject object, String type) {\n            String logicalValue = RNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public RObjectNode createCopy() {\n            return RNodes.createCopy(this);\n        }\n        \n    }\n    \n    \n    @ServiceProvider(service=HeapViewerRenderer.Provider.class)\n    public static class RNodesRendererProvider extends HeapViewerRenderer.Provider {\n\n        public boolean supportsView(HeapContext context, String viewID) {\n            return true;\n        }\n\n        public void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers, HeapContext context) {\n            RLanguage language = RLanguage.instance();\n            Icon instanceIcon = language.createLanguageIcon(Icons.getIcon(LanguageIcons.INSTANCE));\n            Icon packageIcon = language.createLanguageIcon(Icons.getIcon(LanguageIcons.PACKAGE));\n\n            Heap heap = context.getFragment().getHeap();\n\n            renderers.put(RNodes.RObjectNode.class, new TruffleObjectNode.Renderer(heap, instanceIcon));\n\n            renderers.put(RNodes.RTypeNode.class, new TruffleTypeNode.Renderer(packageIcon));\n\n            renderers.put(RNodes.RObjectFieldNode.class, new TruffleObjectFieldNode.Renderer(heap, instanceIcon));\n\n            renderers.put(RNodes.RObjectReferenceNode.class, new TruffleObjectReferenceNode.Renderer(heap, instanceIcon));\n\n            renderers.put(RNodes.RObjectAttributeReferenceNode.class, new TruffleObjectReferenceNode.Renderer(heap, instanceIcon, \"attribute in\")); // NOI18N\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/r/RObject.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.r;\n\nimport java.util.AbstractList;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleFrame;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.heapviewer.utils.HeapUtils;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.Type;\nimport org.graalvm.visualvm.lib.jfluid.heap.Value;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass RObject extends TruffleObject.InstanceBased {\n    \n//    public static final DataType<RObject> DATA_TYPE = new DataType<RObject>(RObject.class, null, null);\n    \n    static final String R_OBJECT_FQN = \"com.oracle.truffle.r.runtime.data.RBaseObject\"; // NOI18N\n    static final String R_SCALAR_FQN = \"com.oracle.truffle.r.runtime.data.RScalarVector\";   // NOI18N\n    static final String R_WRAPPER_FQN = \"com.oracle.truffle.r.runtime.data.RForeignWrapper\";  // NOI18N\n    private static final String RLOGICAL_VECTOR_FQN = \"com.oracle.truffle.r.runtime.data.RLogicalVector\";   // NOI18N\n    private static final String RCOMPLEX_VECTOR_FQN = \"com.oracle.truffle.r.runtime.data.RComplexVector\";   // NOI18N\n    private static final String RPAIR_LIST_FQN = \"com.oracle.truffle.r.runtime.data.RPairList\";   // NOI18N\n    private static final String RNULL_FQN = \"com.oracle.truffle.r.runtime.data.RNull\"; // NOI18N\n    private static final String[] typeMaping = new String[] {\n        \"RRawVector\", \"raw\", // NOI18N\n        \"RRaw\", \"raw\", // NOI18N\n        \"RLogicalVector\", \"logical\", // NOI18N\n        \"RLogical\", \"logical\", // NOI18N\n        \"RIntVector\", \"integer\", // NOI18N\n        \"RInteger\", \"integer\", // NOI18N\n        \"RForeignIntWrapper\", \"integer\", // NOI18N\n        \"RIntSequence\", \"integer\", // NOI18N\n        \"RDoubleVector\", \"double\", // NOI18N\n        \"RDouble\", \"double\", // NOI18N\n        \"RForeignDoubleWrapper\", \"double\", // NOI18N\n        \"RComplexVector\", \"complex\", // NOI18N\n        \"RComplex\", \"complex\", // NOI18N\n        \"RStringVector\", \"character\", // NOI18N\n        \"RString\", \"character\", // NOI18N\n        \"RForeignStringWrapper\", \"character\", // NOI18N\n        \"RList\", \"list\", // NOI18N\n        \"RScalarList\", \"list\", // NOI18N\n        \"RExpression\", \"expression\", // NOI18N\n        \"RFunction\", \"closure\", // NOI18N\n        \"RSymbol\", \"symbol\", // NOI18N\n        \"REnvironment\", \"environment\", // NOI18N\n        \"RPairList\", \"pairlist\", // NOI18N\n        \"RArgsValuesAndNames\", \"pairlist\", // NOI18N\n        \"RLanguage\", \"language\", // NOI18N\n        \"RPromise\", \"promise\", // NOI18N\n        \"RExternalPtr\", \"externalptr\", // NOI18N\n        \"StdConnections\", \"connection\", // NOI18N\n        \"RS4Object\", \"S4\", // NOI18N\n        \"CharSXPWrapper\", \"charsxp_wrapper\"}; // NOI18N\n\n    private static Map<String,String> typeMap;\n\n    static {\n        typeMap = new HashMap<>();\n        for (int i=0; i<typeMaping.length; i+=2) {\n            typeMap.put(typeMaping[i], typeMaping[i+1]);\n        }\n    }\n\n    private final Instance instance;\n    private Instance data;\n    private final Boolean complete;\n    private final Integer refCount;\n    private final Instance attributesInstance;\n    private final String className;\n    private final Instance frameInstance;\n    private final String dataType;\n    private DynamicObject attributes;\n    private final List<FieldValue> fieldValues;\n    private boolean namesComputed;\n    private List<String> names;\n    private boolean dimComputed;\n    private List<Integer> dim;\n    private TruffleFrame frame;\n    \n    private String type;\n\n\n    RObject(Instance instance) {\n        this(null, instance);\n    }\n\n    RObject(String type, Instance instance) {\n        this.instance = instance;\n        this.type = type;\n\n        data = findDataField(instance);\n\n        Object[] values = HeapUtils.getValuesOfFields(instance, \"complete\", \"refCount\", \"attributes\", \"frameAccess\"); // NOI18N\n\n        Object completeO = values[0];\n        complete = completeO == null ? null : Boolean.parseBoolean(completeO.toString());\n        \n        Object refCountO = values[1];\n        refCount = refCountO == null ? null : Integer.parseInt(refCountO.toString());\n        \n        attributesInstance = (Instance) values[2];\n        className = instance.getJavaClass().getName();\n        dataType = data == null ? null : data.getJavaClass().getName().replace(\"[]\", \"\"); // NOI18N\n        fieldValues = new LazyFieldValues();\n        Instance frameAccess = (Instance) values[3];\n        if (frameAccess != null) {\n            frameInstance = (Instance) frameAccess.getValueOfField(\"frame\");    // NOI18N\n        } else {\n            frameInstance = null;\n        }\n        if (data == null && RPAIR_LIST_FQN.equals(className)) {\n            data = new RPairList(instance);\n        }\n        if (data == null && isSubClassOf(instance, R_WRAPPER_FQN)) {\n            data = getDataFromWrapper(instance);\n        }\n    }\n    \n    \n    public static boolean isRObject(Instance rObj) {\n        return isSubClassOf(rObj, R_OBJECT_FQN) || isSubClassOf(rObj, R_SCALAR_FQN)\n                || isSubClassOf(rObj, R_WRAPPER_FQN);\n    }\n    \n    private static boolean isSubClassOf(Instance i, String superClassName) {\n        if (i != null) {\n            JavaClass superCls = i.getJavaClass().getSuperClass();\n\n            for (; superCls != null; superCls = superCls.getSuperClass()) {\n                if (superCls.getName().equals(superClassName)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n    \n    \n    @Override\n    public Instance getInstance() {\n        return instance;\n    }\n    \n    @Override\n    public String getType() {\n        if (type == null) type = getType(className);\n        return type;\n    }\n\n    @Override\n    public long getTypeId() {\n        return instance.getJavaClass().getJavaClassId();\n    }\n    \n    static String getRType(Instance instance) {\n        return getType(instance.getJavaClass().getName());\n    }\n    \n    private static String getType(String className) {\n        String type = className.substring(className.lastIndexOf('.') + 1); // NOI18N\n        int dindex = type.indexOf('$'); // NOI18N\n        if (dindex>0) {\n            type = type.substring(0, dindex);\n        }\n        String convertedType = typeMap.get(type);\n\n        if (convertedType != null) {\n            return convertedType;\n        }\n        return type;\n    }\n\n    @Override\n    public long getSize() {\n        long size = instance.getSize();\n        if (data != null) {\n            size += data.getSize();\n        }\n        return size;\n    }\n    \n    @Override\n    public long getRetainedSize() {\n        return instance.getRetainedSize();\n    }\n    \n    public List getValues() {\n        if (data != null) {\n            if (data instanceof PrimitiveArrayInstance) {\n                return ((PrimitiveArrayInstance)data).getValues();\n            }\n            if (data instanceof ObjectArrayInstance) {\n                return ((ObjectArrayInstance)data).getValues();\n            }\n        }\n        return Collections.emptyList();\n    }\n\n    public int getLength() {\n        if (data != null) {\n            if (data instanceof PrimitiveArrayInstance) {\n                int len = ((PrimitiveArrayInstance)data).getLength();\n                if (RCOMPLEX_VECTOR_FQN.equals(className)) {\n                    return len/2;\n                }\n                return len;\n            }\n            if (data instanceof ObjectArrayInstance) {\n                return ((ObjectArrayInstance)data).getLength();\n            }\n        }\n        return 0;\n    }\n\n    public boolean isPrimitiveArray() {\n        return data instanceof PrimitiveArrayInstance;\n    }\n    \n    public final boolean isTemporary() {\n        return refCount == 0;\n    }\n\n    public final boolean isShared() {\n        return refCount > 1;\n    }\n\n    public final boolean isComplete() {\n        return complete;\n    }\n    \n    public List<String> names() {\n        if (namesComputed) {\n            return names;\n        }\n        DynamicObject attrs = getAttributes();\n        namesComputed = true;\n        if (attrs != null) {\n            FieldValue nameValue = attrs.getFieldValue(\"names\");   // NOI18N\n            if (nameValue instanceof ObjectFieldValue) {\n                Instance nameInst = ((ObjectFieldValue)nameValue).getInstance();\n                List namesArr = new RObject(nameInst).getValues();\n                names = new ArrayList(namesArr.size());\n\n                for (Object name : namesArr) {\n                    Instance string = (Instance) name;\n\n                    names.add(DetailsUtils.getInstanceString(string));\n                }\n                return names;\n            }\n        }\n        return null;\n    }\n\n    public List<Integer> getDim() {\n        if (dimComputed) {\n            return dim;\n        }\n        DynamicObject attrs = getAttributes();\n        dimComputed = true;\n        if (attrs != null) {\n            FieldValue dimsValue = attrs.getFieldValue(\"dim\");   // NOI18N\n            if (dimsValue instanceof ObjectFieldValue) {\n                Instance dimsInst = ((ObjectFieldValue)dimsValue).getInstance();\n                List dimsArr = new RObject(dimsInst).getValues();\n                dim = new ArrayList(dimsArr.size());\n\n                for (Object string : dimsArr) {\n                    dim.add(Integer.valueOf((String)string));\n                }\n                return dim;\n            }\n        }\n        return null;\n    }\n\n    List<FieldValue> getFieldValues() {\n        return fieldValues;\n    }\n\n    DynamicObject getAttributes() {\n        if (attributes == null && attributesInstance != null) {\n            attributes = new DynamicObject(attributesInstance);\n        }\n        return attributes;\n    }\n\n    TruffleFrame getFrame() {\n        if (frame == null && frameInstance != null) {\n            frame = new TruffleFrame(frameInstance);\n        }\n        return frame;\n    }\n\n    List<FieldValue> getReferences() {\n        List<Value> refs = instance.getReferences();\n        List<FieldValue> robjRefs = new ArrayList<>();\n\n        for (Value ref : refs) {\n            Instance defInstance = ref.getDefiningInstance();\n            if (ref instanceof ArrayItemValue) {\n                if (defInstance instanceof ObjectArrayInstance) {\n                    List<Value> arrRefs = defInstance.getReferences();\n\n                    for (Value arrRef : arrRefs) {\n                        Instance rInstance = arrRef.getDefiningInstance();\n\n                        if (RObject.isRObject(rInstance)) {\n                            RObject robject = new RObject(rInstance);\n                            int index = ((ArrayItemValue)ref).getIndex();\n\n                            robjRefs.add(robject.getFieldValues().get(index));\n                        } else if (TruffleFrame.isTruffleFrame(rInstance)) {\n                            if (arrRef instanceof ObjectFieldValue) {\n                                ObjectFieldValue arrRefFV = (ObjectFieldValue) arrRef;\n                                if (arrRefFV.getField().getName().equals(\"locals\")) {\n                                    List<Instance> frefs = getObjectFieldValueRefs(rInstance, \"frame\"); // NOI18N\n\n                                    for (Instance fref : frefs) {\n                                        List<Instance> farefs = getObjectFieldValueRefs(fref, \"frameAccess\");   // NOI18N\n\n                                        for (Instance rObj : farefs) {\n                                            if (RObject.isRObject(rObj)) {\n                                                RObject refRObj = new RObject(rObj);\n                                                TruffleFrame refFrame = refRObj.getFrame();\n\n                                                if (refFrame != null) {\n                                                    for (FieldValue fv : refFrame.getLocalFieldValues()) {\n                                                        if (fv instanceof ObjectFieldValue) {\n                                                            ObjectFieldValue ofv = (ObjectFieldValue) fv;\n                                                            if (getInstance().equals(ofv.getInstance())) {\n                                                                robjRefs.add(new FrameFieldValue(rObj, ofv));\n                                                            }\n                                                        }\n                                                    }\n                                                }\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        addAttribute(rInstance, robjRefs);\n                    }\n                }\n            }\n            if (defInstance != null && defInstance.getJavaClass().getName().equals(RPAIR_LIST_FQN)) {\n                FieldValue rootReference = findRootRPairList(defInstance);\n\n                robjRefs.add(rootReference);\n            }\n            addAttribute(defInstance, robjRefs);\n        }\n        return robjRefs;\n    }\n\n    private List<Instance> getObjectFieldValueRefs(Instance refInstance, String fieldName) {\n        List<Instance> foundRefs = new ArrayList<>();\n        List<Value> refs = refInstance.getReferences();\n\n        for (Value ref : refs) {\n            if (ref instanceof ObjectFieldValue) {\n                ObjectFieldValue refo = (ObjectFieldValue) ref;\n                if (fieldName.equals(refo.getField().getName())) {\n                    foundRefs.add(refo.getDefiningInstance());\n                }\n            }\n        }\n        return foundRefs;\n    }\n\n    private void addAttribute(Instance dynObjInstance, List<FieldValue> robjRefs) {\n        if (DynamicObject.isDynamicObject(dynObjInstance)) {\n            List<Value> refs = dynObjInstance.getReferences();\n\n            for (Value ref : refs) {\n                Instance defInstance = ref.getDefiningInstance();\n\n                if (RObject.isRObject(defInstance)) {\n                    RObject robject = new RObject(defInstance);\n                    DynamicObject attrs = robject.getAttributes();\n\n                    if (attrs != null && attrs.getInstance().equals(dynObjInstance)) {\n                        for (FieldValue fv : attrs.getFieldValues()) {\n                            if (fv instanceof ObjectFieldValue) {\n                                ObjectFieldValue ofv = (ObjectFieldValue) fv;\n\n                                if (ofv.getInstance().equals(instance)) {\n                                    robjRefs.add(fv);\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private FieldValue findRootRPairList(Instance pairList) {\n        int index = 0;\n\n        for (Instance parent = getParentRlist(pairList); parent != null; parent = getParentRlist(parent)) {\n            index++;\n            pairList = parent;\n        }\n        return new RObject(pairList).getFieldValues().get(index);\n    }\n\n    private Instance getParentRlist(Instance pairList) {\n        List<Value> refs = pairList.getReferences();\n\n        if (refs.size() == 1) {\n           Value val = refs.get(0);\n\n           if (val instanceof ObjectFieldValue) {\n               ObjectFieldValue fval = (ObjectFieldValue) val;\n               Instance parent = fval.getDefiningInstance();\n\n               if (parent.getJavaClass().getName().equals(RPAIR_LIST_FQN) && fval.getField().getName().equals(\"cdr\")) { // NOI18N\n                   return parent;\n               }\n           }\n        }\n        return null;\n    }\n\n    static Instance getDataFromWrapper(Instance instance) {\n        Instance delegate = (Instance) instance.getValueOfField(\"delegate\"); // NOI18N\n\n        if (delegate != null) {\n            Instance proxy = (Instance) delegate.getValueOfField(\"proxy\"); // NOI18N\n\n            if (proxy != null) {\n                return (Instance) proxy.getValueOfField(\"val$values\"); // NOI18N\n            }\n        }\n        return null;\n    }\n\n    static Instance findDataField(Instance instance) {\n        for (FieldValue fv : instance.getFieldValues()) {\n\n            if (fv instanceof ObjectFieldValue && \"data\".equals(fv.getField().getName())) { // NOI18N\n                Instance data = ((ObjectFieldValue)fv).getInstance();\n\n                if (data != null && !instance.equals(data)) {\n                    if (data.getJavaClass().isArray()) {\n                        return data;\n                    }\n                    return findDataField(data);\n                }\n            }\n        }\n        return null;\n    }\n\n    private class RPairList implements ObjectArrayInstance {\n\n        private Instance pairListInstance;\n        private int length;\n        private int size;\n        private List values;\n\n        private RPairList(Instance instance) {\n            pairListInstance = instance;\n            length = -1;\n        }\n\n        private void initData() {\n            if (length == -1) {\n                JavaClass pairListClass = pairListInstance.getJavaClass();\n                boolean hasNames = false;\n\n                length = 0;\n                values = new ArrayList();\n                List<String> nameList = new ArrayList<>();\n                for (Instance cdr = pairListInstance;\n                   cdr != null && cdr.getJavaClass().equals(pairListClass);\n                   cdr = (Instance) cdr.getValueOfField(\"cdr\")) { // NOI18N\n                    String name = getName((Instance)cdr.getValueOfField(\"tag\")); // NOI18N\n                    length++;\n                    values.add(cdr.getValueOfField(\"car\")); // NOI18N\n                    if (name != null) {\n                        hasNames = true;\n                    }\n                    nameList.add(name);\n                    size+=cdr.getSize();\n                }\n                if (hasNames) {\n                    namesComputed = true;\n                    names = nameList;\n                }\n            }\n        }\n\n        @Override\n        public int getLength() {\n            initData();\n            return length;\n        }\n\n        @Override\n        public List getValues() {\n            initData();\n            return values;\n        }\n\n        @Override\n        public List getItems() {\n            throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n        }\n\n        @Override\n        public List getFieldValues() {\n            throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n        }\n\n        @Override\n        public boolean isGCRoot() {\n            return pairListInstance.isGCRoot();\n        }\n\n        @Override\n        public long getInstanceId() {\n            return pairListInstance.getInstanceId()+1;\n        }\n\n        @Override\n        public int getInstanceNumber() {\n            return pairListInstance.getInstanceNumber();\n        }\n\n        @Override\n        public JavaClass getJavaClass() {\n            return pairListInstance.getJavaClass();\n        }\n\n        @Override\n        public Instance getNearestGCRootPointer() {\n            throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n        }\n\n        @Override\n        public long getReachableSize() {\n            throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n        }\n\n        @Override\n        public List getReferences() {\n            throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n        }\n\n        @Override\n        public long getRetainedSize() {\n            throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n        }\n\n        @Override\n        public long getSize() {\n            initData();\n            return size;\n        }\n\n        @Override\n        public List getStaticFieldValues() {\n            throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n        }\n\n        @Override\n        public Object getValueOfField(String string) {\n            throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof RPairList) {\n                RPairList rlist = (RPairList) obj;\n                return pairListInstance.equals(rlist.pairListInstance);\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            return pairListInstance.hashCode();\n        }\n\n        private String getName(Instance tag) {\n            if (tag != null) {\n                if (tag.getJavaClass().getName().equals(RNULL_FQN)) {\n                    return null;\n                }\n                return DetailsSupport.getDetailsString(tag);\n            }\n            return null;\n        }\n    }\n    \n    private class LazyFieldValues extends AbstractList<FieldValue> {\n\n        @Override\n        public FieldValue get(int index) {\n            if (isPrimitiveArray()) {\n                if (RLOGICAL_VECTOR_FQN.equals(className)) {\n                    return new RLogicalFieldValue(index);\n                } else if (RCOMPLEX_VECTOR_FQN.equals(className)) {\n                    return new RComplexFieldValue(index);\n                }\n                return new RFieldValue(index);\n            }\n            return new RObjectFieldValue(index);\n        }\n\n        @Override\n        public int size() {\n            return getLength();\n        }\n    }\n    \n    private class RFieldValue implements FieldValue {\n\n        int index;\n\n        private RFieldValue(int i) {\n            index = i;\n        }\n        \n        @Override\n        public Field getField() {\n            return new RField(index);\n        }\n\n        @Override\n        public String getValue() {\n            return (String) getValues().get(index);\n        }\n\n        @Override\n        public Instance getDefiningInstance() {\n            return instance;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof RFieldValue) {\n                RFieldValue rfv = (RFieldValue) obj;\n\n                return instance.equals(rfv.getDefiningInstance())\n                     && index == rfv.index;\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            return 31 * instance.hashCode() + index;\n        }\n    }\n\n    private class RLogicalFieldValue extends RFieldValue {\n\n        RLogicalFieldValue(int i) {\n            super(i);\n        }\n\n        @Override\n        public Field getField() {\n            return new RNamedField(\"logical\", index); // NOI18N\n        }\n\n        @Override\n        public String getValue() {\n            String valString = (String) getValues().get(index);\n            int val = Integer.parseInt(valString);\n\n            if (val == 0) {\n                valString = \"FALSE\"; // NOI18N\n            } else if (val == 1) {\n                valString = \"TRUE\"; // NOI18N\n            }\n            return valString;\n        }\n    }\n\n    private class RComplexFieldValue extends RFieldValue {\n\n        RComplexFieldValue(int i) {\n            super(i);\n        }\n\n        @Override\n        public Field getField() {\n            return new RNamedField(\"complex\", index); // NOI18N\n        }\n\n        @Override\n        public String getValue() {\n            List vals = getValues();\n            return vals.get(2*index)+\"+\"+vals.get(2*index+1)+\"i\"; // NOI18N\n        }\n    }\n    \n    private class RObjectFieldValue implements ObjectFieldValue {\n\n        private int index;\n        \n        private RObjectFieldValue(int i) {\n            index = i;\n        }\n\n        @Override\n        public Instance getInstance() {\n            return (Instance) getValues().get(index);\n        }\n\n        @Override\n        public Field getField() {\n            return new RField(index);\n        }\n\n        @Override\n        public String getValue() {\n            return String.valueOf(getInstance().getInstanceId());\n        }\n\n        @Override\n        public Instance getDefiningInstance() {\n            return instance;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof RObjectFieldValue) {\n                RObjectFieldValue rfv = (RObjectFieldValue) obj;\n\n                return instance.equals(rfv.getDefiningInstance())\n                     && index == rfv.index;\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            return 31 * instance.hashCode() + index;\n        }\n    }\n    \n    private static class FrameFieldValue implements ObjectFieldValue {\n\n        final ObjectFieldValue frameValue;\n        final Instance rObject;\n\n        private FrameFieldValue(Instance ro, ObjectFieldValue fv) {\n            rObject = ro;\n            frameValue = fv;\n        }\n\n        @Override\n        public Instance getInstance() {\n            return frameValue.getInstance();\n        }\n\n        @Override\n        public Field getField() {\n            return frameValue.getField();\n        }\n\n        @Override\n        public String getValue() {\n            return frameValue.getValue();\n        }\n\n        @Override\n        public Instance getDefiningInstance() {\n            return rObject;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (this == obj) {\n                return true;\n            }\n            if (obj instanceof FrameFieldValue) {\n                return frameValue.equals(obj);\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            return frameValue.hashCode();\n        }\n    }\n\n    private class RField implements Field {\n\n        private int index;\n\n        private RField(int i) {\n            index = i;\n        }\n        \n        @Override\n        public JavaClass getDeclaringClass() {\n            return instance.getJavaClass();\n        }\n\n        @Override\n        public String getName() {\n            List<Integer> dims = getDim();\n            if (dims != null) {\n                int rindex = index;\n                StringBuilder name = new StringBuilder();\n\n                for (Integer dim : dims) {\n                    int offset = rindex % dim;\n                    rindex /= dim;\n                    name.append(offset+1).append(','); // NOI18N\n                }\n                return '['+name.substring(0, name.length()-1)+']'; // NOI18N\n            }\n            List<String> names = names();\n            String name = \"[\"+(index+1)+\"]\"; // NOI18N\n            if (names != null) {\n                return name+\" (\"+names.get(index)+\")\"; // NOI18N\n            }\n            return name;\n        }\n\n        @Override\n        public boolean isStatic() {\n            return false;\n        }\n\n        @Override\n        public Type getType() {\n            return new RFieldType(dataType);\n        }\n    }\n\n    private class RNamedField extends RField {\n\n        private final String name;\n\n        private RNamedField(String n, int i) {\n            super(i);\n            name = n;\n        }\n\n        @Override\n        public Type getType() {\n            return new RFieldType(name);\n        }\n    }\n\n    private static class RFieldType implements Type {\n\n        private final String name;\n\n        RFieldType(String n) {\n            name = n;\n        }\n\n        @Override\n        public String getName() {\n            return name;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof RFieldType) {\n                return getName().equals(((RFieldType)obj).getName());\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            return getName().hashCode();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/r/RObjectProperties.java",
    "content": "/*\n * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.r;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleFrame;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObjectPropertyProvider;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.heapviewer.utils.HeapOperations;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.Value;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.util.lookup.ServiceProviders;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"RObjectProperties_Properties=attributes\",\n    \"RObjectProperties_Items=items\",\n    \"RObjectProperties_References=references\"\n})\nfinal class RObjectProperties {\n    \n    // -------------------------------------------------------------------------\n    // --- Attributes ----------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProviders(value={\n        @ServiceProvider(service=HeapViewerNode.Provider.class, position = 200),\n        @ServiceProvider(service=AttributesProvider.class, position = 200)}\n    )\n    public static class AttributesProvider extends TruffleObjectPropertyProvider.Fields<RObject, RType, RHeapFragment, RLanguage> {\n\n        public AttributesProvider() {\n            super(Bundle.RObjectProperties_Properties(), RLanguage.instance(), true);\n        }\n\n\n        @Override\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"r_\") && !viewID.endsWith(\"_references\"); // NOI18N\n        }\n\n        @Override\n        public boolean supportsNode(HeapViewerNode node, Heap heap, String viewID) {\n            if (node instanceof RNodes.RNode && !(node instanceof RNodes.RObjectReferenceNode || node instanceof RNodes.RObjectAttributeReferenceNode)) {\n                TruffleObject object = HeapViewerNode.getValue(node, TruffleObject.DATA_TYPE, heap);\n                RObject robject = object instanceof RObject ? (RObject)object : null;\n                if (robject != null && robject.getAttributes() != null) return true;\n            }\n            return false;\n        }\n\n        @Override\n        protected HeapViewerNode createObjectFieldNode(RObject object, String type, FieldValue field) {\n            return new RNodes.RObjectFieldNode(object, type, field);\n        }\n\n        @Override\n        protected Collection<FieldValue> getPropertyItems(RObject object) {\n            DynamicObject attributes = object.getAttributes();\n            if (attributes == null) return null;\n\n            List<FieldValue> fields = new ArrayList<>();\n\n            fields.addAll(attributes.getFieldValues());\n            fields.addAll(attributes.getStaticFieldValues());\n\n            return fields;\n        }\n\n        @Override\n        protected boolean includeInstance(Instance instance) {\n            String className = instance.getJavaClass().getName();\n\n            if (className.startsWith(\"java.lang.\") || // NOI18N\n                className.startsWith(\"java.math.\") ||  // NOI18N\n                className.startsWith(\"com.oracle.truffle.api.strings.\"))    // NOI18N\n                return true;\n\n            return false;\n        }\n\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Items ---------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProviders(value={\n        @ServiceProvider(service=HeapViewerNode.Provider.class, position = 250),\n        @ServiceProvider(service=ItemsProvider.class, position = 250)}\n    )\n    public static class ItemsProvider extends TruffleObjectPropertyProvider.Fields<RObject, RType, RHeapFragment, RLanguage> {\n\n        public ItemsProvider() {\n            super(Bundle.RObjectProperties_Items(), RLanguage.instance(), true);\n        }\n\n\n        @Override\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"r_\") && !viewID.endsWith(\"_references\"); // NOI18N\n        }\n\n        @Override\n        public boolean supportsNode(HeapViewerNode node, Heap heap, String viewID) {\n            if (node instanceof RNodes.RNode && !(node instanceof RNodes.RObjectReferenceNode || node instanceof RNodes.RObjectAttributeReferenceNode)) {\n                TruffleObject object = HeapViewerNode.getValue(node, TruffleObject.DATA_TYPE, heap);\n                RObject robject = object instanceof RObject ? (RObject)object : null;\n                if (robject != null) {\n                    if (robject.getFieldValues().isEmpty()) {\n                        TruffleFrame frame = robject.getFrame();\n                        return frame != null && frame.isTruffleFrame();\n                    }\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        @Override\n        protected HeapViewerNode createObjectFieldNode(RObject object, String type, FieldValue field) {\n            return new RNodes.RObjectFieldNode(object, type, field);\n        }\n\n        @Override\n        protected Collection<FieldValue> getPropertyItems(RObject object) {\n            List<FieldValue> fields = object.getFieldValues();\n            if (fields.isEmpty()) {\n                TruffleFrame frame = object.getFrame();\n                fields = frame == null ? null : frame.getLocalFieldValues();\n            }\n\n            return fields;\n        }\n\n        @Override\n        protected boolean includeInstance(Instance instance) {\n            String className = instance.getJavaClass().getName();\n\n            if (className.startsWith(\"java.lang.\") || // NOI18N\n                className.startsWith(\"java.math.\") || // NOI18N\n                className.startsWith(\"com.oracle.truffle.r.runtime.data.\")) // NOI18N\n                return true;\n\n            return false;\n        }\n        \n        @Override\n        protected String getMergedPropertiesKey() {\n            return null;\n        }\n\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- References ----------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProviders(value={\n        @ServiceProvider(service=HeapViewerNode.Provider.class, position = 300),\n        @ServiceProvider(service=ReferencesProvider.class, position = 300)}\n    )\n    public static class ReferencesProvider extends TruffleObjectPropertyProvider.References<RObject, RType, RHeapFragment, RLanguage> {\n\n        public ReferencesProvider() {\n            super(Bundle.RObjectProperties_References(), RLanguage.instance(), false);\n        }\n\n\n        @Override\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"r_\") && !viewID.endsWith(\"_attributes\"); // NOI18N\n        }\n\n        @Override\n        public boolean supportsNode(HeapViewerNode node, Heap heap, String viewID) {\n            return node instanceof RNodes.RNode && !(node instanceof RNodes.RObjectFieldNode);\n        }\n\n        @Override\n        protected HeapViewerNode createObjectReferenceNode(RObject object, String type, FieldValue field) {\n            return new RNodes.RObjectReferenceNode(object, type, field);\n        }\n\n        @Override\n        protected HeapViewerNode createForeignReferenceNode(Instance instance, FieldValue field, Heap heap) {\n            List<Value> references = (List<Value>)instance.getReferences();\n            for (Value reference : references) {\n                instance = reference.getDefiningInstance();\n                if (getLanguage().isLanguageObject(instance)) {\n                    RObject robj = getLanguage().createObject(instance);\n                    return new RNodes.RObjectAttributeReferenceNode(robj, robj.getType(), field);\n                }\n            }\n\n            return super.createForeignReferenceNode(instance, field, heap);\n        }\n\n        @Override\n        protected Collection<FieldValue> getPropertyItems(RObject object) throws InterruptedException {\n            HeapOperations.initializeReferences(object.getInstance().getJavaClass().getHeap());\n            return object.getReferences();\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/r/RType.java",
    "content": "/*\n * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.r;\n\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleType;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass RType extends TruffleType.InstanceBased<RObject> {\n    \n    RType(String name) {\n        super(name);\n    }\n    \n    \n    @Override\n    protected RObject createObject(Instance i) {\n        return new RObject(getName(), i);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/r/RViewPlugins.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.r;\n\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObjectPropertyPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"RViewPlugins_PropertiesName=Attributes\",\n    \"RViewPlugins_PropertiesDescription=Attributes\",\n    \"RViewPlugins_ItemsName=Items\",\n    \"RViewPlugins_ItemsDescription=Items\",\n    \"RViewPlugins_ReferencesName=References\",\n    \"RViewPlugins_ReferencesDescription=References\"\n})\nfinal class RViewPlugins {\n    \n    // -------------------------------------------------------------------------\n    // --- Attributes ----------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 200)\n    public static class AttributesPluginProvider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!RHeapFragment.isRHeap(context)) return null;\n            \n            RObjectProperties.AttributesProvider fieldsProvider = Lookup.getDefault().lookup(RObjectProperties.AttributesProvider.class);\n            return new TruffleObjectPropertyPlugin(Bundle.RViewPlugins_PropertiesName(), Bundle.RViewPlugins_PropertiesDescription(), Icons.getIcon(ProfilerIcons.NODE_FORWARD), \"r_objects_attributes\", context, actions, fieldsProvider); // NOI18N\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Items ---------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 300)\n    public static class ItemsPluginProvider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!RHeapFragment.isRHeap(context)) return null;\n            \n            RObjectProperties.ItemsProvider fieldsProvider = Lookup.getDefault().lookup(RObjectProperties.ItemsProvider.class);\n            return new TruffleObjectPropertyPlugin(Bundle.RViewPlugins_ItemsName(), Bundle.RViewPlugins_ItemsDescription(), Icons.getIcon(ProfilerIcons.NODE_FORWARD), \"r_objects_items\", context, actions, fieldsProvider); // NOI18N\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- References ----------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 400)\n    public static class ReferencesPluginProvider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!RHeapFragment.isRHeap(context)) return null;\n            \n            RObjectProperties.ReferencesProvider fieldsProvider = Lookup.getDefault().lookup(RObjectProperties.ReferencesProvider.class);\n            return new TruffleObjectPropertyPlugin(Bundle.RViewPlugins_ReferencesName(), Bundle.RViewPlugins_ReferencesDescription(), Icons.getIcon(ProfilerIcons.NODE_REVERSE), \"r_objects_references\", context, actions, fieldsProvider); // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/r/RViews.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.r;\n\nimport java.util.Collection;\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleFrame;\nimport org.graalvm.visualvm.heapviewer.truffle.ui.TruffleObjectsView;\nimport org.graalvm.visualvm.heapviewer.truffle.ui.TruffleSummaryView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.SummaryView;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"RViews_Version=Version:\",\n    \"RViews_Platform=Platform:\",\n    \"RViews_Unknown=<unknown>\"\n})\nfinal class RViews {\n    \n    // -------------------------------------------------------------------------\n    // --- Summary -------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class SummaryViewProvider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (RHeapFragment.isRHeap(context))\n                return new TruffleSummaryView(RLanguage.instance(), context, actions);\n\n            return null;\n        }\n\n    }\n    \n    \n    @ServiceProvider(service=SummaryView.ContentProvider.class, position = 100)\n    public static class SummaryOverviewProvider extends SummaryView.ContentProvider {\n\n        @Override\n        public HeapView createSummary(String viewID, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n            if (RHeapFragment.isRHeap(context))\n                return new SummaryOverview(context);\n            \n            return null;\n        }\n        \n    }\n    \n    private static class SummaryOverview extends TruffleSummaryView.OverviewSection {\n        \n        SummaryOverview(HeapContext context) {\n            super(context, 3, 3);\n        }\n        \n        protected void computeEnvironmentData(Object[][] environmentData) {\n            super.computeEnvironmentData(environmentData);\n            \n            environmentData[1][0] = Bundle.RViews_Version();\n            environmentData[2][0] = Bundle.RViews_Platform();\n            \n            RHeapFragment fragment = (RHeapFragment)getContext().getFragment();\n            Heap heap = fragment.getHeap();\n            \n            JavaClass envClass = heap.getJavaClassByName(\"com.oracle.truffle.r.runtime.env.REnvironment$Base\"); // NOI18N\n            if (envClass != null && envClass.getInstancesCount() > 0) {\n                Instance envInstance = envClass.getInstancesIterator().next();\n                if (RObject.isRObject(envInstance)) {\n                    RObject envObj = new RObject(envInstance);\n                    TruffleFrame envFrame = envObj.getFrame();\n                    if (envFrame != null && envFrame.isTruffleFrame()) {\n                        List<FieldValue> fields = envFrame.getLocalFieldValues();\n                        for (FieldValue field : fields) {\n                            String fieldName = field.getField().getName();\n                            if ((\"R.version\".equals(fieldName) || \"version\".equals(fieldName)) && field instanceof ObjectFieldValue) { // NOI18N\n                                Instance envI = ((ObjectFieldValue)field).getInstance();\n                                if (RObject.isRObject(envI)) {\n                                    RObject env = new RObject(envI);\n                                    environmentData[1][1] = itemValue(env, \"version.string\", heap); // NOI18N\n                                    environmentData[2][1] = itemValue(env, \"system\", heap); // NOI18N\n                                }\n                                                                \n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (environmentData[1][1] == null) environmentData[1][1] = Bundle.RViews_Unknown();\n            if (environmentData[2][1] == null) environmentData[2][1] = Bundle.RViews_Unknown();\n        }\n        \n        private static String itemValue(RObject object, String item, Heap heap) {\n            item = \"(\" + item + \")\"; // NOI18N\n            List<FieldValue> items = object.getFieldValues();\n            for (FieldValue itemv : items) {\n                String itemn = itemv.getField().getName();\n                if (itemn != null && itemn.contains(item)) {\n                    Instance instance = itemv instanceof ObjectFieldValue ? ((ObjectFieldValue)itemv).getInstance() : null;\n                    return instance == null ? null : DetailsSupport.getDetailsString(instance);\n                }\n            }\n            return null;\n        }\n\n    }\n    \n    \n    @ServiceProvider(service=SummaryView.ContentProvider.class, position = 300)\n    public static class SummaryObjectsProvider extends SummaryView.ContentProvider {\n\n        @Override\n        public HeapView createSummary(String viewID, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n            if (RHeapFragment.isRHeap(context))\n                return new TruffleSummaryView.ObjectsSection(RLanguage.instance(), context, actions, actionProviders);\n            \n            return null;\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Objects -------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class ObjectsViewProvider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (RHeapFragment.isRHeap(context))\n                return new TruffleObjectsView(RLanguage.instance(), context, actions);\n            \n            return null;\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/ruby/RubyDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.ruby;\n\nimport java.io.UnsupportedEncodingException;\nimport java.nio.charset.Charset;\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service = DetailsProvider.class)\npublic class RubyDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String RUBY_OBJECT_TYPE_MASK = \"org.truffleruby.language.RubyObjectType+\";   // NOI18N\n    private static final String ASCII_ROPE_MASK = \"org.truffleruby.core.rope.AsciiOnlyLeafRope\";   // NOI18N\n    private static final String CONCAT_ROPE_MASK = \"org.truffleruby.core.rope.ConcatRope\"; // NOI18N\n    private static final String SUB_ROPE_MASK = \"org.truffleruby.core.rope.SubstringRope\";  // NOI18N\n    private static final String INVALID_ROPE_MASK = \"org.truffleruby.core.rope.InvalidLeafRope\";    // NOI18N\n    private static final String VALID_ROPE_MASK = \"org.truffleruby.core.rope.ValidLeafRope\";    // NOI18N\n    private static final String INT_ROPE_MASK = \"org.truffleruby.core.rope.LazyIntRope\"; // NOI18N\n    private static final String ROPE_TABLE_KEY_MASK = \"org.truffleruby.core.rope.RopeTable$Key\"; // NOI18N\n    private static final String ENCODING_MASK = \"org.jcodings.Encoding+\";   // NOI18N\n    private static final String MODULE_FIELDS_MASK = \"org.truffleruby.core.module.ModuleFields\"; // NOI18N\n    private static final String BASIC_LAYOUT_MASK= \"org.truffleruby.core.basicobject.BasicObjectLayoutImpl$BasicObjectType+\"; // NI18N\n    private static final String METHOD_INFO_MASK = \"org.truffleruby.language.methods.SharedMethodInfo\"; // NOi18N\n    private static final String RUBY_ROOT_NODE_MASK = \"org.truffleruby.language.RubyRootNode\"; // NOI18N\\\n    private static final String RUBY_MODULE_MASK = \"org.truffleruby.core.module.RubyModule+\";   // NOI18N\n    private static final String RUBY_PROC_MASK = \"org.truffleruby.core.proc.RubyProc\"; // NOI18N\n    private static final String RUBY_STRING_MASK = \"org.truffleruby.core.string.RubyString\"; // NOI18N\n    private static final String RUBY_ISTRING_MASK = \"org.truffleruby.core.string.ImmutableRubyString\"; // NOI18N\n    private static final String RUBY_ARRAY_MASK = \"org.truffleruby.core.array.RubyArray\";   // NOI18N\n    private static final String RUBY_SYMBOL_MASK = \"org.truffleruby.core.symbol.RubySymbol\"; // NOI18N\n    private static final String RUBY_HASH_MASK = \"org.truffleruby.core.hash.RubyHash\"; // NOI18N\n    private static final String RUBY_ENCODING_MASK = \"org.truffleruby.core.encoding.RubyEncoding\"; // NOI18N\n    private static final String RUBY_REGEXP_MASK = \"org.truffleruby.core.regexp.RubyRegexp\"; // NOI18N\n\n    public RubyDetailsProvider() {\n        super(RUBY_OBJECT_TYPE_MASK,ASCII_ROPE_MASK,CONCAT_ROPE_MASK,SUB_ROPE_MASK,\n                ROPE_TABLE_KEY_MASK,INVALID_ROPE_MASK,VALID_ROPE_MASK,\n                INT_ROPE_MASK, ENCODING_MASK, MODULE_FIELDS_MASK,\n                BASIC_LAYOUT_MASK, METHOD_INFO_MASK, RUBY_ROOT_NODE_MASK,\n                RUBY_MODULE_MASK, RUBY_PROC_MASK, RUBY_STRING_MASK,\n                RUBY_ISTRING_MASK, RUBY_ARRAY_MASK,RUBY_SYMBOL_MASK,\n                RUBY_HASH_MASK, RUBY_ENCODING_MASK,\n                RUBY_REGEXP_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case RUBY_OBJECT_TYPE_MASK: {\n                String name = instance.getJavaClass().getName();\n                int index = name.lastIndexOf('$'); // NOI18N\n\n                if (index == -1) {\n                    index = name.lastIndexOf('.'); // NOI18N\n                }\n                return name.substring(index+1);\n            }\n            case ASCII_ROPE_MASK: {\n                Integer len = (Integer) instance.getValueOfField(\"byteLength\"); // NOI18N\n                return getByteArrayFieldString(instance, \"bytes\", 0, len.intValue(), \"...\"); // NOI18N\n            }\n            case CONCAT_ROPE_MASK: {\n                Object vall = instance.getValueOfField(\"left\");   // NOI18N\n                Object valr = instance.getValueOfField(\"right\");   // NOI18N\n\n                if (vall == null && valr == null) {\n                    // string in 'bytes' similarly to ASCII_ROPE\n                    Integer len = (Integer) instance.getValueOfField(\"byteLength\"); // NOI18N\n                    return getByteArrayFieldString(instance, \"bytes\", 0, len.intValue(), \"...\"); // NOI18N\n                }\n                String left = DetailsUtils.getInstanceString((Instance)vall);\n\n                if (left == null) {\n                    return DetailsUtils.getInstanceString((Instance)valr);\n                }\n                if (valr == null || left.length() > DetailsUtils.MAX_ARRAY_LENGTH) {\n                    return left;\n                }\n                String value = left + DetailsUtils.getInstanceString((Instance)valr);\n\n                if (value.length() > DetailsUtils.MAX_ARRAY_LENGTH) {\n                    return value.substring(0, DetailsUtils.MAX_ARRAY_LENGTH) + \"...\"; // NOI18N\n                }\n                return value;\n            }\n            case SUB_ROPE_MASK: {\n                Object offset = instance.getValueOfField(\"byteOffset\");   // NOI18N\n                Object child = instance.getValueOfField(\"child\");   // NOI18N\n                String childString = DetailsUtils.getInstanceString((Instance) child);\n                int byteOffset;\n                if (offset == null) {\n                    offset = instance.getValueOfField(\"offset\");   // NOI18N\n                }       byteOffset = ((Integer) offset).intValue();\n                Object length = instance.getValueOfField(\"byteLength\");\n                int byteLength = ((Integer) length).intValue();\n                if (childString.length() > byteOffset && childString.length() >= byteOffset + byteLength) {\n                    return childString.substring(byteOffset, byteOffset + byteLength);\n                }\n                break;\n            }\n            case ENCODING_MASK:\n                return getByteArrayFieldString(instance, \"name\", 0, -1, \"...\"); // NOI18N\n            case ROPE_TABLE_KEY_MASK: {\n                byte[] bytes = getByteArrayFieldString(instance, \"bytes\", 0, -1); // NOI18N\n                String encodingString = DetailsUtils.getInstanceFieldString(instance, \"encoding\"); // NOI18N\n\n                return getString(bytes, encodingString, \"...\"); // NOI18N\n            }\n            case INVALID_ROPE_MASK: {\n                byte[] bytes = getByteArrayFieldString(instance, \"bytes\", 0, -1); // NOI18N\n                String encodingString = DetailsUtils.getInstanceFieldString(instance, \"encoding\"); // NOI18N\n\n                return getString(bytes, encodingString, \"...\"); // NOI18N\n            }\n            case VALID_ROPE_MASK: {\n                byte[] bytes = getByteArrayFieldString(instance, \"bytes\", 0, -1); // NOI18N\n                String encodingString = DetailsUtils.getInstanceFieldString(instance, \"encoding\"); // NOI18N\n\n                return getString(bytes, encodingString, \"...\"); // NOI18N\n            }\n            case INT_ROPE_MASK:\n                return Integer.toString(DetailsUtils.getIntFieldValue(instance, \"value\", 0)); // NOI18N\n            case MODULE_FIELDS_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            case BASIC_LAYOUT_MASK: {\n                Instance logicalClassInst = (Instance) instance.getValueOfField(\"logicalClass\"); // NOI18N\n                if (DynamicObject.isDynamicObject(logicalClassInst)) {\n                    DynamicObject logicalClass = new DynamicObject(logicalClassInst);\n                    ObjectFieldValue fields = (ObjectFieldValue) logicalClass.getFieldValue(\"fields (hidden)\"); // NOI18N\n\n                    return DetailsUtils.getInstanceString(fields.getInstance());\n                }\n                break;\n            }\n            case METHOD_INFO_MASK: {\n                Instance name = (Instance) instance.getValueOfField(\"name\");   // NOI18N\n\n                if (name == null) {\n                    name = (Instance) instance.getValueOfField(\"notes\");   // NOI18N\n                }\n                return DetailsUtils.getInstanceString(name);\n            }\n            case RUBY_ROOT_NODE_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"sharedMethodInfo\"); // NOI18N\n            case RUBY_MODULE_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"fields\"); // NOI18N\n            case RUBY_PROC_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"sharedMethodInfo\"); // NOI18N\n            case RUBY_ISTRING_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"tstring\"); // NOI18N\n            case RUBY_STRING_MASK:\n                String s = DetailsUtils.getInstanceFieldString(instance, \"tstring\"); // NOI18N\n                if (s == null) s = DetailsUtils.getInstanceFieldString(instance, \"rope\"); // NOI18N\n                return s;\n            case RUBY_ARRAY_MASK:\n            case RUBY_HASH_MASK: {\n                Integer length = (Integer) instance.getValueOfField(\"size\");\n                if (length != null) {\n                    return Formatters.numberFormat().format(length) + (length == 1 ? \" item\" : \" items\"); // NOI18N\n                }\n                break;\n            }\n            case RUBY_SYMBOL_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"string\"); // NOI18N\n            case RUBY_ENCODING_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            case RUBY_REGEXP_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"source\"); // NOI18N\n            default:\n                break;\n        }\n        return null;\n    }\n\n    private byte[] getByteArrayFieldString(Instance instance, String field, int offset, int count) {\n        Object fieldVal = instance.getValueOfField(field);\n        if (fieldVal instanceof PrimitiveArrayInstance) {\n            PrimitiveArrayInstance array = (PrimitiveArrayInstance)fieldVal;\n            List<String> values = array.getValues();\n            if (values != null) {\n                int valuesCount = count < 0 ? values.size() - offset :\n                                  Math.min(count, values.size() - offset);\n                int estimatedSize = Math.min(valuesCount, DetailsUtils.MAX_ARRAY_LENGTH + 1);\n                byte bytes[] = new byte[estimatedSize];\n                int lastValue = offset + valuesCount - 1;\n                for (int i = offset; i <= lastValue; i++) {\n                    bytes[i-offset] = Byte.parseByte(values.get(i));\n                    if (i-offset+1 >= DetailsUtils.MAX_ARRAY_LENGTH) {\n                        break;\n                    }\n                }\n                return bytes;\n            }\n        }\n        return null;\n    }\n\n    private String getByteArrayFieldString(Instance instance, String field, int offset, int count, String trailer) {\n        byte[] bytes = getByteArrayFieldString(instance, field, offset, count);\n\n        return getString(bytes, Charset.defaultCharset().name(), trailer);\n    }\n\n    private String getString(byte[] bytes, String encodingString, String trailer) {\n        if (bytes != null) {\n            String val;\n            int len = Math.min(bytes.length, DetailsUtils.MAX_ARRAY_LENGTH);\n            try {\n                val = new String(bytes, 0, len, encodingString);\n            } catch (UnsupportedEncodingException ex) {\n                val = new String(bytes, 0, len);\n            }\n            if (bytes.length > DetailsUtils.MAX_ARRAY_LENGTH) {\n                return val + trailer;\n            }\n            return val;\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/ruby/RubyHeapFragment.java",
    "content": "/*\n * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.ruby;\n\nimport java.util.Iterator;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectLanguageHeapFragment;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"RubyHeapFragment_Name=Ruby Heap\"\n})\nclass RubyHeapFragment extends DynamicObjectLanguageHeapFragment<RubyObject, RubyType> {\n    \n    static final String RUBY_LANG_ID = \"org.truffleruby.language.RubyObjectType\"; // NOI18N\n    static final String RUBY_LANG_ID1 = \"org.truffleruby.interop.RubyObjectType\"; // NOI18N\n    static final String RUBY_LANG_ID2 = \"org.truffleruby.language.objects.RubyObjectType\"; // NOI18N\n    \n    private static final String RUBY_HEAP_ID = \"ruby_heap\"; // NOI18N\n    \n    private final String rubyLangId;\n    \n    RubyHeapFragment(RubyLanguage language, JavaClass rubyLangIdClass, Instance langID, Heap heap) {\n        super(RUBY_HEAP_ID, Bundle.RubyHeapFragment_Name(), fragmentDescription(langID), language, heap);\n        rubyLangId = rubyLangIdClass.getName();\n    }\n    \n    \n    static RubyHeapFragment fromContext(HeapContext context) {\n        return (RubyHeapFragment)context.getFragment();\n    }\n    \n    \n    @Override\n    public Iterator<Instance> getInstancesIterator() {\n        return languageInstancesIterator(rubyLangId);\n    }\n    \n    @Override\n    public Iterator<RubyObject> getObjectsIterator() {\n        return languageObjectsIterator(rubyLangId);\n    }\n\n    \n    static boolean isRubyHeap(HeapContext context) {\n        return RUBY_HEAP_ID.equals(context.getFragment().getID());\n    }\n    \n//    public static HeapContext getRubyContext(HeapContext context) {\n//        if (isRubyHeap(context)) return context;\n//        \n//        for (HeapContext otherContext : context.getOtherContexts())\n//            if (isRubyHeap(otherContext)) return otherContext;\n//        \n//        return null;\n//    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/ruby/RubyLanguage.java",
    "content": "/*\n * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.ruby;\n\nimport org.graalvm.visualvm.heapviewer.HeapFragment;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguage;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.openide.util.Lookup;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.util.lookup.ServiceProviders;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProviders(value={\n    @ServiceProvider(service=HeapFragment.Provider.class, position = 500),\n    @ServiceProvider(service=RubyLanguage.class, position = 500)}\n)\npublic class RubyLanguage extends TruffleLanguage<RubyObject, RubyType, RubyHeapFragment> {\n    \n    private static final String ID = \"ruby\"; // NOI18N\n    \n    private static final String RUBY_LANGINFO_ID = \"Ruby\";  // NOI18N\n    \n    \n    private static RubyLanguage INSTANCE; \n    static synchronized RubyLanguage instance() {\n        if (INSTANCE == null) Lookup.getDefault().lookup(RubyLanguage.class);\n        return INSTANCE;\n    }\n    public RubyLanguage() { INSTANCE = this; }\n    \n    \n    public String getID() { return ID; }\n    \n    \n    @Override\n    protected RubyHeapFragment createFragment(Heap heap) {\n        Instance langID = getLanguageInfo(heap, RUBY_LANGINFO_ID);\n        if (langID == null) return null;\n        \n        JavaClass rubyMainClass = heap.getJavaClassByName(RubyHeapFragment.RUBY_LANG_ID2);\n        if (rubyMainClass == null) {\n            rubyMainClass = heap.getJavaClassByName(RubyHeapFragment.RUBY_LANG_ID1);\n            if (rubyMainClass == null) {\n                rubyMainClass = heap.getJavaClassByName(RubyHeapFragment.RUBY_LANG_ID);\n                if (rubyMainClass == null) {\n                    return null;\n                }\n            }\n        }\n\n        return new RubyHeapFragment(this, rubyMainClass, langID, heap);\n    }\n    \n    \n    @Override\n    public Class<RubyObject> getLanguageObjectClass() {\n        return RubyObject.class;\n    }\n    \n\n    @Override\n    public boolean isLanguageObject(Instance instance) {\n        return RubyObject.isRubyObject(instance);\n    }\n    \n    @Override\n    public RubyObject createObject(Instance instance) {\n        return new RubyObject(instance);\n    }\n    \n    @Override\n    public RubyType createType(String name) {\n        return new RubyType(name);\n    }\n    \n    \n    @Override\n    public RubyNodes.RubyObjectNode createObjectNode(RubyObject object, String type) {\n        return new RubyNodes.RubyObjectNode(object, type);\n    }\n    \n    @Override\n    public RubyNodes.RubyLocalObjectNode createLocalObjectNode(RubyObject object, String type) {\n        return new RubyNodes.RubyLocalObjectNode(object, type);\n    }\n    \n    @Override\n    public RubyNodes.RubyTypeNode createTypeNode(RubyType type, Heap heap) {\n        return new RubyNodes.RubyTypeNode(type);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/ruby/RubyNodes.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.ruby;\n\nimport java.util.List;\nimport java.util.Map;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectArrayItemNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectFieldNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObjectReferenceNode;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.LocalDynamicObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleLocalObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectArrayItemNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectFieldNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectReferenceNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleOpenNodeActionProvider;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleTypeNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapViewerNodeAction.Provider.class)\npublic class RubyNodes extends TruffleOpenNodeActionProvider<RubyObject, RubyType, RubyHeapFragment, RubyLanguage> {\n    \n    @Override\n    public boolean supportsView(HeapContext context, String viewID) {\n        return RubyHeapFragment.isRubyHeap(context);\n    }\n    \n    @Override\n    protected boolean supportsNode(HeapViewerNode node) {\n        return node instanceof RubyNodes.RubyNode;\n    }\n\n    @Override\n    protected RubyLanguage getLanguage() {\n        return RubyLanguage.instance();\n    }\n    \n    \n    private static final int MAX_LOGVALUE_LENGTH = 160;\n    \n    static String getLogicalValue(RubyObject object, String type) {\n        String logicalValue = null;\n\n        if (\"Proc\".equals(type)) { // NOI18N\n            FieldValue infoField = object.getFieldValue(\"sharedMethodInfo (hidden)\"); // NOI18N\n            Instance info = infoField instanceof ObjectFieldValue ? ((ObjectFieldValue)infoField).getInstance() : null;\n            if (info != null) {\n                String name = DetailsUtils.getInstanceFieldString(info, \"name\"); // NOI18N\n                String notes = DetailsUtils.getInstanceFieldString(info, \"notes\"); // NOI18N\n                \n                if (name != null && notes != null) logicalValue = name + \" (\" + notes + \")\"; // NOI18N\n                else if (name != null) logicalValue = name;\n                else if (notes != null) logicalValue = notes;\n            }\n        } else if (\"Method\".equals(type) || \"UnboundMethod\".equals(type)) { // NOI18N\n            FieldValue methodField = object.getFieldValue(\"method (hidden)\"); // NOI18N\n            Instance method = methodField instanceof ObjectFieldValue ? ((ObjectFieldValue)methodField).getInstance() : null;\n            \n            Object infoField = method == null ? null : method.getValueOfField(\"sharedMethodInfo\"); // NOI18N\n            Instance info = infoField instanceof Instance ? (Instance)infoField : null;\n            \n            if (info != null) {\n                String name = DetailsUtils.getInstanceFieldString(info, \"name\"); // NOI18N\n                String notes = DetailsUtils.getInstanceFieldString(info, \"notes\"); // NOI18N\n                \n                if (name != null && notes != null) logicalValue = name + \" (\" + notes + \")\"; // NOI18N\n                else if (name != null) logicalValue = name;\n                else if (notes != null) logicalValue = notes;\n            }\n        } else if (\"Symbol\".equals(type)) { // NOI18N\n            FieldValue symbolField = object.getFieldValue(\"string (hidden)\"); // NOI18N\n            Instance symbol = symbolField instanceof ObjectFieldValue ? ((ObjectFieldValue)symbolField).getInstance() : null;\n            \n            if (symbol != null) logicalValue = DetailsUtils.getInstanceString(symbol);\n        } else if (\"Class\".equals(type) || \"Module\".equals(type)) { // NOI18N\n            FieldValue fieldsField = object.getFieldValue(\"fields (hidden)\"); // NOI18N\n            Instance fields = fieldsField instanceof ObjectFieldValue ? ((ObjectFieldValue)fieldsField).getInstance() : null;\n            \n            Object nameField = fields == null ? null : fields.getValueOfField(\"name\"); // NOI18N\n            Instance name = nameField instanceof Instance ? (Instance)nameField : null;\n            \n            if (name != null) logicalValue = DetailsUtils.getInstanceString(name);\n        } else if (\"BasicObject\".equals(type)) { // NOI18N\n            String head = \"fields [\"; // NOI18N\n            String sep = \", \"; // NOI18N\n            \n            StringBuilder sb = new StringBuilder();\n            sb.append(head);\n            \n            List<FieldValue> fields = object.getFieldValues();\n            for (FieldValue field : fields) {\n                String name = field.getField().getName();\n                if (!name.contains(\"(hidden)\")) sb.append(name).append(sep); // NOI18N\n            }\n            \n            int length = sb.length();\n            if (length > head.length()) sb.delete(length - sep.length(), length);\n            sb.append(\"]\"); // NOI18N\n            \n            logicalValue = sb.toString();\n        } else if (\"Array\".equals(type)) { // NOI18N\n            FieldValue sizeField = object.getFieldValue(\"size (hidden)\"); // NOI18N\n            if (sizeField != null) {\n                Integer size = Integer.parseInt(sizeField.getValue());\n                logicalValue = Formatters.numberFormat().format(size) + (size == 1 ? \" item\" : \" items\"); // NOI18N\n            }\n        } else if (\"String\".equals(type)) { // NOI18N\n            FieldValue ropeField = object.getFieldValue(\"rope (hidden)\"); // NOI18N\n            Instance rope = ropeField instanceof ObjectFieldValue ? ((ObjectFieldValue)ropeField).getInstance() : null;\n            if (rope != null) logicalValue = DetailsUtils.getInstanceString(rope);\n        } else if (\"Regexp\".equals(type)) { // NOI18N\n            FieldValue sourceField = object.getFieldValue(\"source (hidden)\"); // NOI18N\n            Instance source = sourceField instanceof ObjectFieldValue ? ((ObjectFieldValue)sourceField).getInstance() : null;\n            if (source != null) logicalValue = DetailsUtils.getInstanceString(source);\n        } else if (\"Encoding\".equals(type)) { // NOI18N\n            FieldValue encodingField = object.getFieldValue(\"encoding (hidden)\"); // NOI18N\n            Instance encoding = encodingField instanceof ObjectFieldValue ? ((ObjectFieldValue)encodingField).getInstance() : null;\n            if (encoding != null) logicalValue = DetailsUtils.getInstanceString(encoding);\n        } else if (\"Integer\".equals(type)) { // NOI18N\n            FieldValue valueField = object.getFieldValue(\"value (hidden)\"); // NOI18N\n            Instance value = valueField instanceof ObjectFieldValue ? ((ObjectFieldValue)valueField).getInstance() : null;\n            if (value != null) logicalValue = DetailsUtils.getInstanceString(value);\n        } else if (\"Rational\".equals(type)) { // NOI18N\n            FieldValue numField = object.getFieldValue(\"@numerator\"); // NOI18N\n            Instance numerator = numField instanceof ObjectFieldValue ? ((ObjectFieldValue)numField).getInstance() : null;\n            FieldValue denomField = object.getFieldValue(\"@denominator\"); // NOI18N\n            Instance denominator = denomField instanceof ObjectFieldValue ? ((ObjectFieldValue)denomField).getInstance() : null;\n            if (numField != null && denomField != null) {\n                String numeratorValue;\n                String denominatorValue;\n\n                if (numerator != null) {\n                    numeratorValue = DetailsUtils.getInstanceString(numerator);\n                } else {\n                    numeratorValue = numField.getValue();\n                }\n                if (denominator != null) {\n                    denominatorValue = DetailsUtils.getInstanceString(denominator);\n                } else {\n                    denominatorValue = denomField.getValue();\n                }\n                if (numeratorValue != null && denominatorValue != null) {\n                    logicalValue = \"(\"+numeratorValue+\"/\"+denominatorValue+\")\";\n                }\n            }\n        } else if (\"Complex\".equals(type)) { // NOI18N\n            FieldValue realField = object.getFieldValue(\"@real\"); // NOI18N\n            String real = realField != null ? realField.getValue() : null;\n            FieldValue imagField = object.getFieldValue(\"@imag\"); // NOI18N\n            String imag = imagField != null ? imagField.getValue() : null;\n            if (real != null && imag != null) logicalValue = \"(\" + real + (imag.startsWith(\"-\") ? imag : \"+\" + imag) + \"i)\"; // NOI18N\n        } else if (\"Range\".equals(type)) { // NOI18N\n            FieldValue beginField = object.getFieldValue(\"begin (hidden)\"); // NOI18N\n            FieldValue endField = object.getFieldValue(\"end (hidden)\"); // NOI18N\n            FieldValue excludedField = object.getFieldValue(\"excludedEnd (hidden)\"); // NOI18N\n            if (beginField != null && endField != null && excludedField != null) {\n                Instance beginInstance = beginField instanceof ObjectFieldValue ? ((ObjectFieldValue)beginField).getInstance() : null;\n                String begin = beginInstance != null ? logicalValue(beginInstance) : beginField.getValue();\n                \n                Instance endInstance = endField instanceof ObjectFieldValue ? ((ObjectFieldValue)endField).getInstance() : null;\n                String end = endInstance != null ? logicalValue(endInstance) : endField.getValue();\n                \n                boolean excluded = \"1\".equals(excludedField.getValue()); // NOI18N\n                \n                logicalValue = \"(\" + begin + (excluded ? \"...\" : \"..\") + end + \")\"; // NOI18N\n            }\n        }\n        \n        if (logicalValue != null && logicalValue.length() > MAX_LOGVALUE_LENGTH)\n            logicalValue = logicalValue.substring(0, MAX_LOGVALUE_LENGTH) + \"...\"; // NOI18N\n\n        return logicalValue;\n    }\n    \n    private static String logicalValue(Instance instance) {\n        if (RubyObject.isRubyObject(instance)) {\n            RubyObject object = new RubyObject(instance);\n            return getLogicalValue(object, object.getType());\n        } else {\n            return DetailsUtils.getInstanceString(instance);\n        }\n    }\n    \n    \n    // TODO: uncomment once types caching is available for RubyHeapFragment\n//    private static String computeName(TruffleObjectNode.InstanceBased<RubyDynamicObject> node, Heap heap) {\n//        return node.getTruffleObject().computeDisplayType(heap) + \"#\" + node.getInstance().getInstanceNumber(); // NOI18N\n//    }\n    \n    private static RubyObjectNode createCopy(TruffleObjectNode.InstanceBased<RubyObject> node) {\n        return new RubyObjectNode(node.getTruffleObject(), node.getTypeName());\n    }\n    \n    \n    static interface RubyNode {}\n    \n    \n    static class RubyObjectNode extends DynamicObjectNode<RubyObject> implements RubyNode {\n        \n        RubyObjectNode(RubyObject object, String type) {\n            super(object, type);\n        }\n        \n        \n        // TODO: uncomment once types caching is available for RubyHeapFragment\n//        @Override\n//        protected String computeObjectName(Heap heap) {\n//            return RubyNodes.computeObjectName(this, heap);\n//        }\n        \n        protected String computeLogicalValue(RubyObject object, String type) {\n            String logicalValue = RubyNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public RubyObjectNode createCopy() {\n            RubyObjectNode copy = RubyNodes.createCopy(this);\n            setupCopy(copy);\n            return copy;\n        }\n\n        protected void setupCopy(RubyObjectNode copy) {\n            super.setupCopy(copy);\n        }\n        \n    }\n    \n    static class RubyLocalObjectNode extends LocalDynamicObjectNode<RubyObject> implements RubyNode {\n        \n        RubyLocalObjectNode(RubyObject object, String type) {\n            super(object, type);\n        }\n        \n        \n        // TODO: uncomment once types caching is available for RubyHeapFragment\n//        @Override\n//        protected String computeObjectName(Heap heap) {\n//            return RubyNodes.computeObjectName(this, heap);\n//        }\n        \n        protected String computeLogicalValue(RubyObject object, String type) {\n            String logicalValue = RubyNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public RubyObjectNode createCopy() {\n            return RubyNodes.createCopy(this);\n        }\n        \n    }\n    \n    static class RubyTypeNode extends TruffleTypeNode<RubyObject, RubyType> implements RubyNode {\n        \n        RubyTypeNode(RubyType type) {\n            super(type);\n        }\n\n        @Override\n        public HeapViewerNode createNode(RubyObject object) {\n            String type = getType().getName();\n            return new RubyObjectNode(object, type);\n        }\n\n        @Override\n        public TruffleTypeNode createCopy() {\n            RubyTypeNode copy = new RubyTypeNode(getType());\n            setupCopy(copy);\n            return copy;\n        }\n        \n        protected void setupCopy(RubyTypeNode copy) {\n            super.setupCopy(copy);\n        }\n        \n    }\n    \n    \n    static class RubyObjectFieldNode extends DynamicObjectFieldNode<RubyObject> implements RubyNode {\n        \n        RubyObjectFieldNode(RubyObject object, String type, FieldValue field) {\n            super(object, type, field);\n        }\n        \n        \n        // TODO: uncomment once types caching is available for RubyHeapFragment\n//        @Override\n//        protected String computeObjectName(Heap heap) {\n//            return RubyNodes.computeObjectName(this, heap);\n//        }\n        \n        protected String computeLogicalValue(RubyObject object, String type) {\n            String logicalValue = RubyNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public RubyObjectNode createCopy() {\n            return RubyNodes.createCopy(this);\n        }\n        \n    }\n    \n    static class RubyObjectArrayItemNode extends DynamicObjectArrayItemNode<RubyObject> implements RubyNode {\n        \n        RubyObjectArrayItemNode(RubyObject object, String type, ArrayItemValue item) {\n            super(object, type, item);\n        }\n        \n        \n        // TODO: uncomment once types caching is available for RubyHeapFragment\n//        @Override\n//        protected String computeObjectName(Heap heap) {\n//            return RubyNodes.computeObjectName(this, heap);\n//        }\n        \n        protected String computeLogicalValue(RubyObject object, String type) {\n            String logicalValue = RubyNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public RubyObjectNode createCopy() {\n            return RubyNodes.createCopy(this);\n        }\n        \n    }\n    \n    static class RubyObjectReferenceNode extends DynamicObjectReferenceNode<RubyObject> implements RubyNode {\n        \n        RubyObjectReferenceNode(RubyObject object, String type, FieldValue value) {\n            super(object, type, value);\n        }\n        \n        \n        // TODO: uncomment once types caching is available for RubyHeapFragment\n//        @Override\n//        protected String computeObjectName(Heap heap) {\n//            return RubyNodes.computeObjectName(this, heap);\n//        }\n        \n        protected String computeLogicalValue(RubyObject object, String type) {\n            String logicalValue = RubyNodes.getLogicalValue(object, type);\n            return logicalValue != null ? logicalValue : super.computeLogicalValue(object, type);\n        }\n        \n        \n        public RubyObjectNode createCopy() {\n            return RubyNodes.createCopy(this);\n        }\n        \n    }\n    \n    \n    @ServiceProvider(service=HeapViewerRenderer.Provider.class)\n    public static class RubyNodesRendererProvider extends HeapViewerRenderer.Provider {\n\n        public boolean supportsView(HeapContext context, String viewID) {\n            return true;\n        }\n\n        public void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers, HeapContext context) {\n            RubyLanguage language = RubyLanguage.instance();\n            Icon instanceIcon = language.createLanguageIcon(Icons.getIcon(LanguageIcons.INSTANCE));\n            Icon packageIcon = language.createLanguageIcon(Icons.getIcon(LanguageIcons.PACKAGE));\n\n            Heap heap = context.getFragment().getHeap();\n\n            renderers.put(RubyNodes.RubyObjectNode.class, new TruffleObjectNode.Renderer(heap, instanceIcon));\n\n            renderers.put(RubyNodes.RubyTypeNode.class, new TruffleTypeNode.Renderer(packageIcon));\n\n            renderers.put(RubyNodes.RubyObjectFieldNode.class, new TruffleObjectFieldNode.Renderer(heap, instanceIcon));\n\n            renderers.put(RubyNodes.RubyObjectArrayItemNode.class, new TruffleObjectArrayItemNode.Renderer(heap, instanceIcon));\n\n            renderers.put(RubyNodes.RubyObjectReferenceNode.class, new TruffleObjectReferenceNode.Renderer(heap, instanceIcon));\n\n            renderers.put(RubyNodes.RubyLocalObjectNode.class, new TruffleLocalObjectNode.Renderer(heap, instanceIcon));\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/ruby/RubyObject.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.ruby;\n\nimport java.util.AbstractList;\nimport java.util.Collections;\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.truffle.dynamicobject.DynamicObject;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.Type;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass RubyObject extends DynamicObject {\n\n    private boolean isPrimitiveList;\n    private String listType;\n    private Instance array;\n\n    RubyObject(Instance instance) {\n        this(null, instance);\n    }\n    \n    RubyObject(String type, Instance instance) {\n        super(type, instance);\n        Object storage = (Instance) instance.getValueOfField(\"store\");\n        if (storage instanceof ObjectArrayInstance || storage instanceof PrimitiveArrayInstance) {\n            array =  (Instance) storage;\n        }\n    }\n    \n    boolean isRubyObject() {\n        return isRubyLangId(getLanguageId());\n    }\n\n    @Override\n    protected String computeType() {\n        Instance metaClass = (Instance) getInstance().getValueOfField(\"metaClass\");\n        if (metaClass == null) {\n            return super.computeType();\n        }\n        return DetailsUtils.getInstanceFieldString(metaClass, \"nonSingletonClass\");\n    }\n\n    List<FieldValue> getItems() {\n        if (array != null) {\n            return getListFields();\n        }\n        return Collections.EMPTY_LIST;\n    }\n\n    private List<FieldValue> getListFields() {\n        return new LazyFieldValues(getValues());\n    }\n\n    private List getValues() {\n        if (array != null) {\n            listType = array.getJavaClass().getName().replace(\"[]\", \"\"); // NOI18N\n            if (array instanceof ObjectArrayInstance) {\n                return ((ObjectArrayInstance)array).getValues();\n            }\n            if (array instanceof PrimitiveArrayInstance) {\n                isPrimitiveList = true;\n                return ((PrimitiveArrayInstance)array).getValues();\n            }\n        }\n        return Collections.emptyList();\n    }\n\n    static boolean isRubyObject(Instance instance) {\n        return DynamicObject.isDynamicObject(instance) &&\n               isRubyLangId(DynamicObject.getLanguageId(instance));\n    }\n    \n    private static boolean isRubyLangId(JavaClass langIdClass) {\n        String className = langIdClass.getName();\n\n        return RubyHeapFragment.RUBY_LANG_ID.equals(className)\n               || RubyHeapFragment.RUBY_LANG_ID1.equals(className)\n               || RubyHeapFragment.RUBY_LANG_ID2.equals(className);\n    }\n\n    private class LazyFieldValues extends AbstractList<FieldValue> {\n\n        private List values;\n\n        private LazyFieldValues(List vals) {\n            values = vals;\n        }\n\n        @Override\n        public FieldValue get(int index) {\n            if (isPrimitiveList) {\n                return new RubyFieldValue(index, values.get(index));\n            }\n            return new RubyObjectFieldValue(index, (Instance) values.get(index));\n        }\n\n        @Override\n        public int size() {\n            Object size = getInstance().getValueOfField(\"size\");        // NOI18N\n            if (size instanceof Integer) {\n                return ((Integer)size).intValue();\n            }\n            return 0;\n        }\n    }\n\n    private class RubyFieldValue implements FieldValue {\n        private int index;\n        Object value;\n\n        private RubyFieldValue(int i, Object val) {\n            index = i;\n            value = val;\n        }\n\n        @Override\n        public Field getField() {\n            return new RubyField(index);\n        }\n\n        @Override\n        public String getValue() {\n            return (String)value;\n        }\n\n        @Override\n        public Instance getDefiningInstance() {\n            return getInstance();\n        }\n\n    }\n\n    private class RubyObjectFieldValue extends RubyFieldValue implements ObjectFieldValue {\n\n        private RubyObjectFieldValue(int i, Instance val) {\n            super(i,val);\n        }\n\n        @Override\n        public String getValue() {\n            return String.valueOf(getInstance().getInstanceId());\n        }\n\n        @Override\n        public Instance getInstance() {\n            return (Instance)value;\n        }\n    }\n\n    private class RubyField implements Field {\n\n        private int index;\n\n        private RubyField(int i) {\n            index = i;\n        }\n\n        @Override\n        public JavaClass getDeclaringClass() {\n            return getInstance().getJavaClass();\n        }\n\n        @Override\n        public String getName() {\n            return  \"[\"+index+\"]\"; // NOI18N\n        }\n\n        @Override\n        public boolean isStatic() {\n            return false;\n        }\n\n        @Override\n        public Type getType() {\n            return new RFieldType(listType);\n        }\n    }\n\n    private static class RFieldType implements Type {\n\n        private final String name;\n\n        private RFieldType(String n) {\n            name = n;\n        }\n\n        @Override\n        public String getName() {\n            return name;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof RFieldType) {\n                return getName().equals(((RFieldType)obj).getName());\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            return getName().hashCode();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/ruby/RubyObjectProperties.java",
    "content": "/*\n * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.ruby;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleInstancePropertyProvider;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObjectPropertyProvider;\nimport org.graalvm.visualvm.heapviewer.utils.HeapOperations;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.util.lookup.ServiceProviders;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"RubyObjectProperties_Properties=variables\",\n    \"RubyObjectProperties_Items=items\",\n    \"RubyObjectProperties_References=references\"\n})\nfinal class RubyObjectProperties {\n    \n    // -------------------------------------------------------------------------\n    // --- Fields --------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProviders(value={\n        @ServiceProvider(service=HeapViewerNode.Provider.class, position = 200),\n        @ServiceProvider(service=FieldsProvider.class, position = 200)}\n    )\n    public static class FieldsProvider extends TruffleObjectPropertyProvider.Fields<RubyObject, RubyType, RubyHeapFragment, RubyLanguage> {\n\n        public FieldsProvider() {\n            super(Bundle.RubyObjectProperties_Properties(), RubyLanguage.instance(), true);\n        }\n\n\n        @Override\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"ruby_\") && !viewID.endsWith(\"_references\"); // NOI18N\n        }\n\n        @Override\n        public boolean supportsNode(HeapViewerNode node, Heap heap, String viewID) {\n            return node instanceof RubyNodes.RubyNode && !(node instanceof RubyNodes.RubyObjectReferenceNode);\n        }\n\n        @Override\n        protected HeapViewerNode createObjectFieldNode(RubyObject object, String type, FieldValue field) {\n            return new RubyNodes.RubyObjectFieldNode(object, type, field);\n        }\n\n        @Override\n        protected Collection<FieldValue> getPropertyItems(RubyObject object) {\n            List<FieldValue> fields = new ArrayList<>();\n\n            fields.addAll(object.getFieldValues());\n            fields.addAll(object.getStaticFieldValues());\n\n            return fields;\n        }\n\n        @Override\n        protected boolean includeInstance(Instance instance) {\n            String className = instance.getJavaClass().getName();\n\n            if (className.startsWith(\"java.lang.\") || // NOI18N\n                className.startsWith(\"java.math.\") || // NOI18N\n                className.startsWith(\"org.truffleruby.core.rope.\") || // NOI18N\n                className.startsWith(\"com.oracle.truffle.api.strings.\"))    // NOI18N\n                return true;\n\n            return false;\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Items ---------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewerNode.Provider.class, position = 300)\n    public static class ArrayItemsProvider extends TruffleInstancePropertyProvider.ArrayItems<RubyObject, RubyType, RubyHeapFragment, RubyLanguage> {\n\n        public ArrayItemsProvider() {\n            super(Bundle.RubyObjectProperties_Items(), RubyLanguage.instance(), false);\n        }\n\n\n        @Override\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"ruby_\"); // NOI18N\n        }\n\n\n        @Override\n        protected HeapViewerNode createObjectArrayItemNode(RubyObject object, String type, ArrayItemValue item) {\n            return new RubyNodes.RubyObjectArrayItemNode(object, type, item);\n        }\n\n    }\n    \n     // -------------------------------------------------------------------------\n    // --- Items ---------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProviders(value={\n        @ServiceProvider(service=HeapViewerNode.Provider.class, position = 250),\n        @ServiceProvider(service=ItemsProvider.class, position = 250)}\n    )\n    public static class ItemsProvider extends TruffleObjectPropertyProvider.Fields<RubyObject, RubyType, RubyHeapFragment, RubyLanguage> {\n\n        public ItemsProvider() {\n            super(Bundle.RubyObjectProperties_Items(), RubyLanguage.instance(), true);\n        }\n\n\n        @Override\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"ruby_\") && !viewID.endsWith(\"_references\"); // NOI18N\n        }\n\n        @Override\n        public boolean supportsNode(HeapViewerNode node, Heap heap, String viewID) {\n            if (node instanceof RubyNodes.RubyNode && !(node instanceof RubyNodes.RubyObjectReferenceNode)) {\n                TruffleObject object = HeapViewerNode.getValue(node, TruffleObject.DATA_TYPE, heap);\n                RubyObject robject = object instanceof RubyObject ? (RubyObject)object : null;\n                if (robject != null) return !getPropertyItems(robject).isEmpty();\n            }\n            return false;\n        }\n\n        @Override\n        protected HeapViewerNode createObjectFieldNode(RubyObject object, String type, FieldValue field) {\n            return new RubyNodes.RubyObjectFieldNode(object, type, field);\n        }\n\n        @Override\n        protected Collection<FieldValue> getPropertyItems(RubyObject object) {\n            return object.getItems();\n        }\n\n        @Override\n        protected boolean includeInstance(Instance instance) {\n            String className = instance.getJavaClass().getName();\n\n            if (className.startsWith(\"java.lang.\") || // NOI18N\n                className.startsWith(\"java.math.\") || // NOI18N\n                className.startsWith(\"org.truffleruby.core.rope.\") || // NOI18N\n                className.startsWith(\"com.oracle.truffle.api.strings.\"))    // NOI18N\n                return true;\n\n            return false;\n        }\n\n        @Override\n        protected String getMergedPropertiesKey() {\n            return null;\n        }\n    }\n\n    // -------------------------------------------------------------------------\n    // --- References ----------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProviders(value={\n        @ServiceProvider(service=HeapViewerNode.Provider.class, position = 300),\n        @ServiceProvider(service=ReferencesProvider.class, position = 300)}\n    )\n    public static class ReferencesProvider extends TruffleObjectPropertyProvider.References<RubyObject, RubyType, RubyHeapFragment, RubyLanguage> {\n\n        public ReferencesProvider() {\n            super(Bundle.RubyObjectProperties_References(), RubyLanguage.instance(), false);\n        }\n\n\n        @Override\n        public boolean supportsView(Heap heap, String viewID) {\n            return viewID.startsWith(\"ruby_\") && !viewID.endsWith(\"_fields\"); // NOI18N\n        }\n\n        @Override\n        public boolean supportsNode(HeapViewerNode node, Heap heap, String viewID) {\n            return node instanceof RubyNodes.RubyNode && !(node instanceof RubyNodes.RubyObjectFieldNode || node instanceof RubyNodes.RubyObjectArrayItemNode);\n        }\n\n        @Override\n        protected HeapViewerNode createObjectReferenceNode(RubyObject object, String type, FieldValue field) {\n            return new RubyNodes.RubyObjectReferenceNode(object, type, field);\n        }\n\n        @Override\n        protected Collection<FieldValue> getPropertyItems(RubyObject object) throws InterruptedException {\n            HeapOperations.initializeReferences(object.getInstance().getJavaClass().getHeap());\n            return object.getReferences();\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/ruby/RubyType.java",
    "content": "/*\n * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.ruby;\n\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleType;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass RubyType extends TruffleType.InstanceBased<RubyObject> {\n    \n    RubyType(String name) {\n        super(name);\n    }\n    \n    \n    @Override\n    protected RubyObject createObject(Instance i) {\n        return new RubyObject(getName(), i);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/ruby/RubyViewPlugins.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.ruby;\n\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObjectPreviewPlugin;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObjectPropertyPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewPlugin;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"RubyViewPlugins_PropertiesName=Variables\",\n    \"RubyViewPlugins_PropertiesDescription=Variables\",\n    \"RubyViewPlugins_ReferencesName=References\",\n    \"RubyViewPlugins_ReferencesDescription=References\"\n})\nfinal class RubyViewPlugins {\n    \n    // -------------------------------------------------------------------------\n    // --- Preview -------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    static class PreviewPlugin extends TruffleObjectPreviewPlugin {\n    \n        PreviewPlugin(HeapContext context) {\n            super(context);\n        }\n\n\n        @Override\n        protected boolean supportsNode(HeapViewerNode node) {\n            return node instanceof RubyNodes.RubyObjectNode;\n        }\n\n        @Override\n        protected Instance getPreviewInstance(HeapViewerNode node) {\n            RubyNodes.RubyObjectNode dnode = (RubyNodes.RubyObjectNode)node;\n            if (\"Proc\".equals(dnode.getTypeName())) { // NOI18N\n                RubyObject rbobj = dnode.getTruffleObject();\n                FieldValue dataField = rbobj.getFieldValue(\"sharedMethodInfo (hidden)\"); // NOI18N\n                Instance data = dataField instanceof ObjectFieldValue ? ((ObjectFieldValue)dataField).getInstance() : null;\n                if (data == null) return null;\n\n                Object sourceSection = ((Instance)data).getValueOfField(\"sourceSection\"); // NOI18N\n                if (!(sourceSection instanceof Instance)) return null;\n\n                return (Instance)sourceSection;\n            } else {\n                return null;\n            }\n        }\n    \n    }\n    \n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 100)\n    public static class PreviewPluginProvider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (RubyHeapFragment.isRubyHeap(context))\n                return new PreviewPlugin(context);\n            return null;\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Fields --------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 200)\n    public static class FieldsPluginProvider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!RubyHeapFragment.isRubyHeap(context)) return null;\n            \n            RubyObjectProperties.FieldsProvider fieldsProvider = Lookup.getDefault().lookup(RubyObjectProperties.FieldsProvider.class);\n            return new TruffleObjectPropertyPlugin(Bundle.RubyViewPlugins_PropertiesName(), Bundle.RubyViewPlugins_PropertiesDescription(), Icons.getIcon(ProfilerIcons.NODE_FORWARD), \"ruby_objects_fields\", context, actions, fieldsProvider); // NOI18N\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- References ----------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewPlugin.Provider.class, position = 400)\n    public static class ReferencesPluginProvider extends HeapViewPlugin.Provider {\n\n        public HeapViewPlugin createPlugin(HeapContext context, HeapViewerActions actions, String viewID) {\n            if (!RubyHeapFragment.isRubyHeap(context)) return null;\n            \n            RubyObjectProperties.ReferencesProvider fieldsProvider = Lookup.getDefault().lookup(RubyObjectProperties.ReferencesProvider.class);\n            return new TruffleObjectPropertyPlugin(Bundle.RubyViewPlugins_ReferencesName(), Bundle.RubyViewPlugins_ReferencesDescription(), Icons.getIcon(ProfilerIcons.NODE_REVERSE), \"ruby_objects_references\", context, actions, fieldsProvider); // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/lang/ruby/RubyViews.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.lang.ruby;\n\nimport java.util.Collection;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.truffle.ui.TruffleObjectsView;\nimport org.graalvm.visualvm.heapviewer.truffle.ui.TruffleSummaryView;\nimport org.graalvm.visualvm.heapviewer.truffle.ui.TruffleThreadsView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.SummaryView;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"RubyViews_Platform=Platform:\",\n    \"RubyViews_Unknown=<unknown>\"\n})\nfinal class RubyViews {\n    \n    // -------------------------------------------------------------------------\n    // --- Summary -------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class SummaryViewProvider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (RubyHeapFragment.isRubyHeap(context))\n                return new TruffleSummaryView(RubyLanguage.instance(), context, actions);\n\n            return null;\n        }\n\n    }\n    \n    \n    @ServiceProvider(service=SummaryView.ContentProvider.class, position = 100)\n    public static class SummaryOverviewProvider extends SummaryView.ContentProvider {\n\n        @Override\n        public HeapView createSummary(String viewID, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n            if (RubyHeapFragment.isRubyHeap(context))\n                return new SummaryOverview(context);\n            \n            return null;\n        }\n        \n    }\n    \n    private static class SummaryOverview extends TruffleSummaryView.OverviewSection {\n        \n        SummaryOverview(HeapContext context) {\n            super(context, 3, 2);\n        }\n        \n        protected void computeEnvironmentData(Object[][] environmentData) {\n            super.computeEnvironmentData(environmentData);\n            \n            environmentData[1][0] = Bundle.RubyViews_Platform();\n            \n            RubyHeapFragment fragment = (RubyHeapFragment)getContext().getFragment();\n            RubyType gemPlatform = fragment.getType(\"Gem::Platform\", null); // NOI18N\n            RubyObject platformO = gemPlatform == null || gemPlatform.getObjectsCount() == 0 ?\n                                         null : gemPlatform.getObjectsIterator().next();\n            \n            if (platformO != null) {\n                Heap heap = fragment.getHeap();\n                \n                String osFV = variableValue(platformO, \"@os\", heap); // NOI18N\n                String cpuFV = variableValue(platformO, \"@cpu\", heap); // NOI18N\n                if (osFV != null || cpuFV != null) {\n                    String platform = osFV;\n                    if (cpuFV != null) {\n                        if (platform != null) platform += \" \"; else platform = \"\"; // NOI18N\n                        platform += cpuFV;\n                    }\n                    environmentData[1][1] = platform;\n                }\n            }\n            \n            if (environmentData[1][1] == null) environmentData[1][1] = Bundle.RubyViews_Unknown();\n        }\n        \n        private static String variableValue(RubyObject object, String field, Heap heap) {\n            FieldValue value = object == null ? null : object.getFieldValue(field);\n            Instance instance = value instanceof ObjectFieldValue ? ((ObjectFieldValue)value).getInstance() : null;\n            if (instance == null || !RubyObject.isRubyObject(instance)) return null;\n            RubyObject variableO = new RubyObject(instance);\n            return RubyNodes.getLogicalValue(variableO, variableO.getType());\n        }\n\n    }\n    \n    \n    @ServiceProvider(service=SummaryView.ContentProvider.class, position = 300)\n    public static class SummaryObjectsProvider extends SummaryView.ContentProvider {\n\n        @Override\n        public HeapView createSummary(String viewID, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n            if (RubyHeapFragment.isRubyHeap(context))\n                return new TruffleSummaryView.ObjectsSection(RubyLanguage.instance(), context, actions, actionProviders);\n            \n            return null;\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Objects -------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class ObjectsViewProvider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (RubyHeapFragment.isRubyHeap(context))\n                return new TruffleObjectsView(RubyLanguage.instance(), context, actions);\n            \n            return null;\n        }\n\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // --- Threads -------------------------------------------------------------\n    // -------------------------------------------------------------------------\n    \n    @ServiceProvider(service=HeapViewerFeature.Provider.class)\n    public static class ThreadsViewProvider extends HeapViewerFeature.Provider {\n\n        public HeapViewerFeature getFeature(HeapContext context, HeapViewerActions actions) {\n            if (RubyHeapFragment.isRubyHeap(context))\n                return new TruffleThreadsView(RubyLanguage.instance(), context, actions);\n            \n            return null;\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/nodes/TerminalJavaNodes.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.nodes;\n\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.java.InstanceReferenceNode;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Value;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class TerminalJavaNodes {\n    \n    public static class Instance extends InstanceNode {\n        \n        public Instance(org.graalvm.visualvm.lib.jfluid.heap.Instance instance) {\n            super(instance);\n            setChildren(NO_NODES);\n        }\n        \n        public boolean isLeaf() {\n            return true;\n        }\n        \n    }\n    \n    public static class Field extends InstanceReferenceNode.Field {\n        \n        private final boolean isArray;\n        \n        public Field(ObjectFieldValue value, boolean incoming) {\n            super(value, incoming);\n            \n            org.graalvm.visualvm.lib.jfluid.heap.Instance instance = getInstance();\n            isArray = instance != null && instance.getJavaClass().isArray();\n            \n            if (!isArray) setChildren(NO_NODES);\n        }\n        \n        public boolean isLeaf() {\n            return isArray ? super.isLeaf() : true;\n        }\n        \n    }\n    \n    public static class ArrayItem extends InstanceReferenceNode.ArrayItem {\n\n        public ArrayItem(ArrayItemValue value, boolean incoming) {\n            super(value, incoming);\n            setChildren(NO_NODES);\n        }\n        \n        public boolean isLeaf() {\n            return true;\n        }\n        \n    }\n    \n    \n    public static InstanceReferenceNode outgoingReference(Value value) {\n        return reference(value, false);\n    }\n    \n    public static InstanceReferenceNode incomingReference(Value value) {\n        return reference(value, true);\n    }\n    \n    public static InstanceReferenceNode reference(Value value, boolean incoming) {\n        if (value instanceof ObjectFieldValue) return new Field((ObjectFieldValue)value, incoming);\n        else if (value instanceof ArrayItemValue) return new ArrayItem((ArrayItemValue)value, incoming);\n        \n        return null;\n    }\n    \n    \n    private TerminalJavaNodes() {}\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/nodes/TruffleLocalObjectNode.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.nodes;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.MultiRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface TruffleLocalObjectNode<O extends TruffleObject> extends TruffleObjectNode<O> {\n    \n    \n    public class InstanceBased<O extends TruffleObject.InstanceBased> extends TruffleObjectNode.InstanceBased<O> implements TruffleLocalObjectNode<O> {\n        \n        public InstanceBased(O object, String type) {\n            super(object, type);\n        }\n        \n        \n        @Override\n        public String getName() {\n            return \"local object \" + getObjectName(); // NOI18N\n        }\n\n\n        public InstanceNode createCopy() {\n            return null;\n        }\n        \n        protected void setupCopy(TruffleLocalObjectNode.InstanceBased copy) {\n            super.setupCopy(copy);\n        }\n        \n    }\n    \n    \n    public static class Renderer extends MultiRenderer implements HeapViewerRenderer {\n        \n        private final LabelRenderer lvRenderer;\n        private final TruffleObjectNode.Renderer dobjectRenderer;\n        \n        private final ProfilerRenderer[] renderers;\n        \n        public Renderer(Heap heap, Icon icon) {\n            lvRenderer = new LabelRenderer() {\n                public String toString() {\n                    return getText() + \" \"; // NOI18N\n                }\n            };\n            lvRenderer.setText(\"local object\"); // NOI18N\n            lvRenderer.setMargin(3, 3, 3, 1);\n            \n            dobjectRenderer = new TruffleObjectNode.Renderer(heap, icon);\n            \n            renderers = new ProfilerRenderer[] { lvRenderer, dobjectRenderer };\n        }\n        \n        protected ProfilerRenderer[] valueRenderers() { return renderers; }\n        \n        public void setValue(Object value, int row) {\n            dobjectRenderer.setValue(value, row);\n        }\n        \n        public Icon getIcon() {\n            return dobjectRenderer.getIcon();\n        }\n\n        public String getShortName() {\n            String name = dobjectRenderer.getShortName();\n            int nameIdx = name.lastIndexOf('['); // NOI18N\n            if (nameIdx != -1) name = name.substring(0, nameIdx).trim();\n            return /*lvRenderer + \" \" +*/ name;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/nodes/TruffleNodesRendererProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.nodes;\n\nimport java.util.Map;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=HeapViewerRenderer.Provider.class)\npublic class TruffleNodesRendererProvider extends HeapViewerRenderer.Provider {\n    \n    public boolean supportsView(HeapContext context, String viewID) {\n        return true;\n    }\n\n    public void registerRenderers(Map<Class<? extends HeapViewerNode>, HeapViewerRenderer> renderers, HeapContext context) {\n        Heap heap = context.getFragment().getHeap();\n        Icon instanceIcon = Icons.getIcon(LanguageIcons.INSTANCE);\n//        Icon packageIcon = Icons.getIcon(LanguageIcons.PACKAGE);\n        \n        renderers.put(TruffleObjectNode.InstanceBased.class, new TruffleObjectNode.Renderer(heap, instanceIcon));\n        \n        renderers.put(TruffleObjectFieldNode.InstanceBased.class, new TruffleObjectFieldNode.Renderer(heap, instanceIcon));\n        \n        renderers.put(TruffleObjectReferenceNode.InstanceBased.class, new TruffleObjectReferenceNode.Renderer(heap, instanceIcon));\n        \n        renderers.put(TruffleLocalObjectNode.InstanceBased.class, new TruffleLocalObjectNode.Renderer(heap, instanceIcon));\n        \n        renderers.put(TruffleStackFrameNode.class, new TruffleStackFrameNode.Renderer());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/nodes/TruffleObjectArrayItemNode.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.nodes;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.MultiRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface TruffleObjectArrayItemNode<O extends TruffleObject> {\n    \n    public ArrayItemValue getItem();\n    \n    public String getItemName();\n    \n    \n    public static abstract class InstanceBased<O extends TruffleObject.InstanceBased> extends TruffleObjectNode.InstanceBased<O> implements TruffleObjectArrayItemNode<O> {\n        \n        private ArrayItemValue item;\n        \n        \n        public InstanceBased(O object, String type, ArrayItemValue item) {\n            super(object, type);\n            this.item = item;\n        }\n        \n        \n        @Override\n        public String getName() {\n            return getItemName() + \" = \" + getObjectName(); // NOI18N\n        }\n        \n        \n        public String getItemName() {\n            return \"[\" + item.getIndex() + \"]\"; // NOI18N\n        }\n\n        public ArrayItemValue getItem() {\n            return item;\n        }\n\n\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof TruffleObjectArrayItemNode.InstanceBased)) return false;\n            return item.equals(((TruffleObjectArrayItemNode.InstanceBased)o).item);\n        }\n\n        public int hashCode() {\n            return item.hashCode();\n        }\n\n\n        public InstanceNode createCopy() {\n            return null;\n        }\n        \n        protected void setupCopy(TruffleObjectArrayItemNode.InstanceBased copy) {\n            super.setupCopy(copy);\n            copy.item = item;\n        }\n        \n    }\n    \n    \n    public static class Renderer extends MultiRenderer implements HeapViewerRenderer {\n        \n        private final NormalBoldGrayRenderer fieldRenderer;\n        private final LabelRenderer equalsRenderer;\n        private final TruffleObjectNode.Renderer dobjectRenderer;\n        private final ProfilerRenderer[] renderers;\n        \n        private final Heap heap;\n        \n        public Renderer(Heap heap, Icon icon) {\n            this(heap, icon, \"=\"); // NOI18N\n        }\n        \n        public Renderer(Heap heap, Icon icon, String divider) {\n            this.heap = heap;\n            \n            fieldRenderer = new NormalBoldGrayRenderer() {\n                public void setValue(Object value, int row) {\n                    TruffleObjectArrayItemNode node = (TruffleObjectArrayItemNode)value;\n                    String name = node.getItemName();\n                    if (name.startsWith(\"static \")) { // NOI18N\n                        setNormalValue(\"static \"); // NOI18N\n                        setBoldValue(name.substring(\"static \".length())); // NOI18N\n                    } else {\n                        setNormalValue(\"\"); // NOI18N\n                        setBoldValue(name);\n                    }\n                    setIcon(Icons.getIcon(ProfilerIcons.NODE_FORWARD));\n                }\n            };\n            \n            equalsRenderer = new LabelRenderer() {\n                public String toString() {\n                    return \" \" + getText() + \" \"; // NOI18N\n                }\n            };\n            equalsRenderer.setText(divider);\n            equalsRenderer.setMargin(3, 0, 3, 0);\n            \n            dobjectRenderer = new TruffleObjectNode.Renderer(heap, icon);\n            \n            renderers = new ProfilerRenderer[] { fieldRenderer, equalsRenderer, dobjectRenderer };\n        }\n\n        protected ProfilerRenderer[] valueRenderers() {\n            return renderers;\n        }\n        \n        public void setValue(Object value, int row) {\n            HeapViewerNode node = (HeapViewerNode)value;\n            HeapViewerNode loop = HeapViewerNode.getValue(node, DataType.LOOP, heap);\n            if (loop != null) node = loop;\n            \n            fieldRenderer.setValue(node, row);\n            dobjectRenderer.setValue(value, row);\n        }\n        \n        \n        public Icon getIcon() {\n            return fieldRenderer.getIcon();\n        }\n        \n        public String getShortName() {\n            return fieldRenderer.toString();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/nodes/TruffleObjectFieldNode.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.nodes;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.MultiRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface TruffleObjectFieldNode<O extends TruffleObject> {\n    \n    public FieldValue getField();\n    \n    public String getFieldName();\n    \n    \n    public static abstract class InstanceBased<O extends TruffleObject.InstanceBased> extends TruffleObjectNode.InstanceBased<O> implements TruffleObjectFieldNode<O> {\n        \n        private FieldValue field;\n    \n        private String fieldName;\n        \n        \n        public InstanceBased(O object, String type, FieldValue field) {\n            super(object, type);\n            this.field = field;\n        }\n        \n        \n        @Override\n        public String getName() {\n            return getFieldName() + \" = \" + getObjectName(); // NOI18N\n        }\n        \n        \n        public FieldValue getField() {\n            return field;\n        }\n        \n        public String getFieldName() {\n            if (fieldName == null) fieldName = computeFieldName(field);\n            return fieldName;\n        }\n        \n        protected String computeFieldName(FieldValue field) {\n            return (field.getField().isStatic() ? \"static \" : \"\") + field.getField().getName(); // NOI18N\n        }\n\n\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof TruffleObjectFieldNode.InstanceBased)) return false;\n            return field.equals(((TruffleObjectFieldNode.InstanceBased)o).field);\n        }\n\n        public int hashCode() {\n            return field.hashCode();\n        }\n\n\n        public InstanceNode createCopy() {\n            return null;\n        }\n        \n        protected void setupCopy(TruffleObjectFieldNode.InstanceBased copy) {\n            super.setupCopy(copy);\n            copy.field = field;\n            copy.fieldName = fieldName;\n        }\n        \n    }\n    \n    \n    @NbBundle.Messages({\n        \"TruffleObjectFieldNodeRenderer_LoopTo=loop to\"\n    })\n    public static class Renderer extends MultiRenderer implements HeapViewerRenderer {\n        \n        private final NormalBoldGrayRenderer fieldRenderer;\n        private final LabelRenderer equalsRenderer;\n        private final LabelRenderer loopToRenderer;\n        private final TruffleObjectNode.Renderer dobjectRenderer;\n        private final ProfilerRenderer[] renderers;\n        \n        private final Heap heap;\n        \n        public Renderer(Heap heap, Icon icon) {\n            this(heap, icon, \"=\"); // NOI18N\n        }\n        \n        public Renderer(Heap heap, Icon icon, String divider) {\n            this.heap = heap;\n            \n            fieldRenderer = new NormalBoldGrayRenderer() {\n                public void setValue(Object value, int row) {\n                    TruffleObjectFieldNode node = (TruffleObjectFieldNode)value;\n                    String name = node.getFieldName();\n                    if (name.startsWith(\"static \")) { // NOI18N\n                        setNormalValue(\"static \"); // NOI18N\n                        setBoldValue(name.substring(\"static \".length())); // NOI18N\n                    } else {\n                        setNormalValue(\"\"); // NOI18N\n                        setBoldValue(name);\n                    }\n                    setIcon(Icons.getIcon(ProfilerIcons.NODE_FORWARD));\n                }\n            };\n            \n            equalsRenderer = new LabelRenderer() {\n                public String toString() {\n                    return \" \" + getText() + \" \"; // NOI18N\n                }\n            };\n            equalsRenderer.setText(divider);\n            equalsRenderer.setMargin(3, 0, 3, 0);\n            \n            loopToRenderer = new LabelRenderer() {\n                public void setValue(Object value, int row) {\n                    setVisible(value != null);\n                }\n                public String toString() {\n                    return getText() + \" \"; // NOI18N\n                }\n            };\n            loopToRenderer.setText(Bundle.TruffleObjectFieldNodeRenderer_LoopTo());\n            \n            dobjectRenderer = new TruffleObjectNode.Renderer(heap, icon);\n            \n            renderers = new ProfilerRenderer[] { fieldRenderer, equalsRenderer, loopToRenderer, dobjectRenderer };\n        }\n\n        protected ProfilerRenderer[] valueRenderers() {\n            return renderers;\n        }\n        \n        public void setValue(Object value, int row) {\n            HeapViewerNode node = (HeapViewerNode)value;\n            HeapViewerNode loop = HeapViewerNode.getValue(node, DataType.LOOP, heap);\n            if (loop != null) node = loop;\n            \n            fieldRenderer.setValue(node, row);\n            loopToRenderer.setValue(loop, row);\n            dobjectRenderer.setValue(node, row);\n            \n            if (loopToRenderer.isVisible()) dobjectRenderer.flagLoopTo();\n        }\n        \n        \n        public Icon getIcon() {\n            return fieldRenderer.getIcon();\n        }\n        \n        public String getShortName() {\n            return fieldRenderer.toString();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/nodes/TruffleObjectNode.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.nodes;\n\nimport java.awt.Image;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleType;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.ui.results.PackageColorer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface TruffleObjectNode<O extends TruffleObject> {\n    \n    public O getTruffleObject();\n    \n    public String getName();\n    \n    public String getObjectName();\n    \n    public String getTypeName();\n    \n    public String getLogicalValue();\n        \n        \n    public static abstract class InstanceBased<O extends TruffleObject.InstanceBased> extends InstanceNode implements TruffleObjectNode<O> {\n    \n        private final O object;\n        private final String typeName;\n\n        private String objectNameString;\n        private String logicalValue;\n\n\n        public InstanceBased(O object, String typeName) {\n            super(object.getInstance());\n            this.object = object;\n            this.typeName = typeName;\n        }\n\n\n        public O getTruffleObject() {\n            return object;\n        }\n        \n        public String getName() {\n            return getObjectName();\n        }\n\n        public String getObjectName() {\n            if (objectNameString == null) objectNameString = computeObjectName();\n            return objectNameString;\n        }\n\n        protected String computeObjectName() {\n            return getTypeName() + \"#\" + getInstance().getInstanceNumber(); // NOI18N\n        }\n\n        public String getTypeName() {\n            return typeName;\n        }\n\n        public String getLogicalValue() {\n            if (logicalValue == null) {\n                logicalValue = computeLogicalValue(object, typeName);\n                if (logicalValue == null) logicalValue = \"\"; // NOI18N\n            }\n            return logicalValue.isEmpty() ? null : logicalValue;\n        }\n\n        // TODO: make this an internal API similar to DetailsSupport.getDetailsString\n        protected String computeLogicalValue(O object, String type) {\n            return DetailsSupport.getDetailsString(object.getInstance());\n        }\n\n        public long getOwnSize() {\n            return object.getSize();\n        }\n        \n        public long getRetainedSize(Heap heap) {\n            return DataType.RETAINED_SIZE.valuesAvailable(heap) ?\n               object.getRetainedSize() : DataType.RETAINED_SIZE.getNotAvailableValue();\n        }\n\n\n        protected Object getValue(DataType type, Heap heap) {\n            if (type == TruffleType.TYPE_NAME) return getTypeName();\n            if (type == TruffleObject.DATA_TYPE) return getTruffleObject();\n\n            return super.getValue(type, heap);\n        }\n\n\n//        public InstanceNode createCopy() {\n//            TruffleObjectNode copy = new TruffleObjectNode(object, type);\n//            setupCopy(copy);\n//            return copy;\n//        }\n\n        protected void setupCopy(TruffleObjectNode.InstanceBased copy) {\n            super.setupCopy(copy);\n            copy.objectNameString = objectNameString;\n            copy.logicalValue = logicalValue;\n        }\n    \n    }\n    \n    \n    public static class Renderer extends NormalBoldGrayRenderer implements HeapViewerRenderer {\n        \n        private static final Image IMAGE_LOOP = Icons.getImage(HeapWalkerIcons.LOOP);\n        \n        private final Icon icon;\n        \n        private final Heap heap;\n        \n        public Renderer(Heap heap, Icon icon) {\n            this.heap = heap;\n            this.icon = icon;\n        }\n        \n        public void setValue(Object value, int row) {\n            TruffleObjectNode node = (TruffleObjectNode)value;\n            \n            String name = node == null ? \"\" : node.getObjectName(); // NOI18N\n            if (name != null && !\"null\".equals(name)) { // NOI18N\n                super.setNormalValue(\"\"); // NOI18N\n                super.setBoldValue(name);\n            } else {\n                super.setNormalValue(\"null\"); // NOI18N\n                super.setBoldValue(null);\n            }\n            \n            String logValue = node == null ? null : node.getLogicalValue();\n            setGrayValue(logValue == null ? \"\" : \" : \" + logValue); // NOI18N\n            \n            setIcon(icon);   \n            \n            setIconTextGap(0);\n            ((LabelRenderer)valueRenderers()[0]).setMargin(3, 0, 3, 0);\n            \n            setCustomForeground(PackageColorer.getForeground(getBoldValue()));\n        }\n        \n        public void flagLoopTo() {\n            Image loopImage = ImageUtilities.icon2Image(getIcon());\n            setIcon(new ImageIcon(ImageUtilities.mergeImages(loopImage, IMAGE_LOOP, 0, 0)));\n            setIconTextGap(4);\n\n            ((LabelRenderer)valueRenderers()[0]).setMargin(3, 1, 3, 0);\n        }\n        \n        public String getShortName() {\n            return getBoldValue();\n        }\n        \n        \n        protected boolean supportsCustomGrayForeground() {\n            return false;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/nodes/TruffleObjectReferenceNode.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.nodes;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.heapviewer.java.InstanceNode;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.MultiRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface TruffleObjectReferenceNode<O extends TruffleObject> {\n    \n    public FieldValue getField();\n    \n    public String getFieldName();\n    \n    \n    public static abstract class InstanceBased<O extends TruffleObject.InstanceBased> extends TruffleObjectNode.InstanceBased<O> implements TruffleObjectReferenceNode<O> {\n        \n        private FieldValue field;\n    \n        private String fieldName;\n\n        \n        public InstanceBased(O object, String type, FieldValue value) {\n            super(object, type);\n            this.field = value;\n        }\n        \n        \n        @Override\n        public String getName() {\n            return getFieldName() + \" in \" + getObjectName(); // NOI18N\n        }\n\n        \n        public FieldValue getField() {\n            return field;\n        }\n\n        public String getFieldName() {\n            if (fieldName == null) fieldName = (field.getField().isStatic() ? \"static \" : \"\") + field.getField().getName(); // NOI18N\n            return fieldName;\n        }\n\n\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof TruffleObjectReferenceNode.InstanceBased)) return false;\n            return field.equals(((TruffleObjectReferenceNode.InstanceBased)o).field);\n        }\n\n        public int hashCode() {\n            return field.hashCode();\n        }\n\n\n        public InstanceNode createCopy() {\n            return null;\n        }\n        \n        protected void setupCopy(TruffleObjectReferenceNode.InstanceBased copy) {\n            super.setupCopy(copy);\n            copy.field = field;\n            copy.fieldName = fieldName;\n        }\n                \n    }\n    \n    \n    @NbBundle.Messages({\n        \"TruffleObjectReferenceNodeRenderer_LoopTo=loop to\"\n    })\n    public static class Renderer extends MultiRenderer implements HeapViewerRenderer {\n        \n        private final NormalBoldGrayRenderer fieldRenderer;\n        private final LabelRenderer inRenderer;\n        private final LabelRenderer loopToRenderer;\n        private final TruffleObjectNode.Renderer dobjectRenderer;\n        private final ProfilerRenderer[] renderers;\n        \n        private final Heap heap;\n        \n        public Renderer(Heap heap, Icon icon) {\n            this(heap, icon, \"in\"); // NOI18N\n        }\n        \n        public Renderer(Heap heap, Icon icon, String divider) {\n            this.heap = heap;\n            \n            fieldRenderer = new NormalBoldGrayRenderer() {\n                public void setValue(Object value, int row) {\n                    TruffleObjectReferenceNode node = (TruffleObjectReferenceNode)value;\n                    String name = node.getFieldName();\n                    if (name.startsWith(\"static \")) { // NOI18N\n                        setNormalValue(\"static \"); // NOI18N\n                        setBoldValue(name.substring(\"static \".length())); // NOI18N\n                    } else {\n                        setNormalValue(\"\"); // NOI18N\n                        setBoldValue(name);\n                    }\n                    setIcon(Icons.getIcon(ProfilerIcons.NODE_REVERSE));\n                }\n            };\n            \n            inRenderer = new LabelRenderer() {\n                public String toString() {\n                    return \" \" + getText() + \" \"; // NOI18N\n                }\n            };\n            inRenderer.setText(divider);\n            inRenderer.setMargin(3, 0, 3, 0);\n            \n            loopToRenderer = new LabelRenderer() {\n                public void setValue(Object value, int row) {\n                    setVisible(value != null);\n                }\n                public String toString() {\n                    return getText() + \" \"; // NOI18N\n                }\n            };\n            loopToRenderer.setText(Bundle.TruffleObjectReferenceNodeRenderer_LoopTo());\n            \n            dobjectRenderer = new TruffleObjectNode.Renderer(heap, icon);\n            \n            renderers = new ProfilerRenderer[] { fieldRenderer, inRenderer, loopToRenderer, dobjectRenderer };\n        }\n\n        protected ProfilerRenderer[] valueRenderers() {\n            return renderers;\n        }\n        \n        public void setValue(Object value, int row) {\n            HeapViewerNode node = (HeapViewerNode)value;\n            HeapViewerNode loop = HeapViewerNode.getValue(node, DataType.LOOP, heap);\n            if (loop != null) node = loop;\n            \n            fieldRenderer.setValue(node, row);\n            loopToRenderer.setValue(loop, row);\n            dobjectRenderer.setValue(node, row);\n            \n            if (loopToRenderer.isVisible()) dobjectRenderer.flagLoopTo();\n        }\n        \n        \n        public Icon getIcon() {\n            return fieldRenderer.getIcon();\n        }\n        \n        public String getShortName() {\n            return fieldRenderer.toString();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/nodes/TruffleOpenNodeActionProvider.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.nodes;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguage;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguageHeapFragment;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleType;\nimport org.graalvm.visualvm.heapviewer.truffle.ui.TruffleObjectView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.NodeObjectsView;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleOpenNodeActionProvider_OpenTypeTab=Open Type in New Tab\"\n})\npublic abstract class TruffleOpenNodeActionProvider<O extends TruffleObject, T extends TruffleType<O>, F extends TruffleLanguageHeapFragment<O, T>, L extends TruffleLanguage<O, T, F>> extends HeapViewerNodeAction.Provider {\n    \n    protected abstract boolean supportsNode(HeapViewerNode node);\n    \n    protected abstract L getLanguage();\n    \n    \n    public HeapViewerNodeAction[] getActions(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n        if (!supportsNode(node)) return null;\n        \n        Heap heap = context.getFragment().getHeap();\n        List<HeapViewerNodeAction> actionsList = new ArrayList(2);\n        \n        final L language = getLanguage();\n        \n        // Open in New Tab action\n        actionsList.add(new NodeObjectsView.DefaultOpenAction(node.createCopy(), context, actions) {\n            public NodeObjectsView createView(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n                return TruffleOpenNodeActionProvider.this.createView(language, node, context, actions);\n            }\n        });\n        \n        // Open Type in New Tab action\n        Instance instance = HeapViewerNode.getValue(node, DataType.INSTANCE, heap);\n        if (instance != null && language.isLanguageObject(instance)) {\n            O object = language.createObject(instance);\n            F fragment = language.fragmentFromHeap(heap);\n            T type = fragment.getType(object.getType(), null);\n            if (type != null) {\n                HeapViewerNode typeNode = language.createTypeNode(type, heap);\n                actionsList.add(new NodeObjectsView.OpenAction(Bundle.TruffleOpenNodeActionProvider_OpenTypeTab(), 1, typeNode, context, actions) {\n                    public NodeObjectsView createView(HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n                        return TruffleOpenNodeActionProvider.this.createView(language, node, context, actions);\n                    }\n                });\n            }\n        }\n        \n        return actionsList.toArray(new HeapViewerNodeAction[0]);\n    }\n    \n    \n    private NodeObjectsView createView(L language, HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n        return new TruffleObjectView(language, node, context, actions);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/nodes/TruffleStackFrameNode.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.nodes;\n\nimport org.graalvm.visualvm.heapviewer.java.StackFrameNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.MultiRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleStackFrameNode_Unknown=<unknown>\"\n})\npublic class TruffleStackFrameNode extends StackFrameNode {\n    \n    public TruffleStackFrameNode(String name, HeapViewerNode[] children) {\n        super(name, children);\n    }\n    \n    \n    // NOTE: temporary solution, should probably be implemented for each Truffle language separately\n    static class Renderer extends MultiRenderer implements HeapViewerRenderer {\n    \n        private final LabelRenderer atRenderer;\n        private final NormalBoldGrayRenderer frameRenderer;\n        private final ProfilerRenderer[] renderers;\n        \n        private String name1;\n        private String name2;\n        private String detail;\n\n\n        Renderer() {\n            atRenderer = new LabelRenderer() {\n                public String toString() {\n                    return getText() + \" \"; // NOI18N\n                }\n            };\n            atRenderer.setText(\"at\"); // NOI18N\n            atRenderer.setMargin(3, 3, 3, 0);\n            frameRenderer = new NormalBoldGrayRenderer() {\n                public void setValue(Object value, int row) {\n                    if (value == null) {\n                        setNormalValue(\"\"); // NOI18N\n                        setBoldValue(\"\"); // NOI18N\n                        setGrayValue(\"\"); // NOI18N\n                    } else {\n                        setNormalValue(((Object[])value)[0].toString());\n                        setBoldValue(((Object[])value)[1].toString());\n                        setGrayValue(((Object[])value)[2].toString());\n                    }\n                }\n            };\n            renderers = new ProfilerRenderer[] { atRenderer, frameRenderer };\n        }\n\n\n        protected ProfilerRenderer[] valueRenderers() {\n            return renderers;\n        }\n\n\n        public void setValue(Object value, int row) {\n            if (value == null) {\n                // no value - fallback to <unknown>\n                name1 = \"\"; // NOI18N\n                name2 = Bundle.TruffleStackFrameNode_Unknown();\n                detail = \"\"; // NOI18N\n            } else {\n                String val = value.toString();\n                \n                int idx = val.lastIndexOf(' '); // NOI18N\n                if (idx != -1) { // multiple strings\n                    detail = val.substring(idx);\n                    if (detail.startsWith(\" (\")) { // NOI18N\n                        val = val.substring(0, idx); // detail contains source:line\n                    } else {\n                        detail = \"\"; // no detail available // NOI18N\n                    }\n                    \n                    idx = val.startsWith(\"<\") ? -1 : val.lastIndexOf(' '); // NOI18N\n                    if (idx != -1) { // multiple strings - last bold\n                        name2 = val.substring(idx + 1);\n                        name1 = val.substring(0, idx + 1);\n                    } else { // single string or meta value - all bold\n                        name1 = \"\"; // NOI18N\n                        name2 = val;\n                    }\n                    \n                    idx = name2.lastIndexOf('.'); // NOI18N\n                    if (idx != -1) { // class.method detected in last string - only method bold\n                        if (!name1.isEmpty()) name1 += \" \"; // NOI18N\n                        name1 = name1 + name2.substring(0, idx + 1);\n                        name2 = name2.substring(idx + 1);\n                    }\n                } else { // single string - all bold\n                    name1 = \"\"; // NOI18N\n                    name2 = val;\n                    detail = \"\"; // NOI18N\n                }\n            }\n            \n            frameRenderer.setValue(new Object[] { name1, name2, detail }, row);\n        }\n\n        public String getShortName() {\n            return \"at \" + name2 + \" \" + detail; // NOI18N\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/nodes/TruffleTypeNode.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.nodes;\n\nimport java.awt.Font;\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.Icon;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObjectsWrapper;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleType;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerRenderer;\nimport org.graalvm.visualvm.heapviewer.ui.UIThresholds;\nimport org.graalvm.visualvm.heapviewer.utils.NodesComputer;\nimport org.graalvm.visualvm.heapviewer.utils.ProgressIterator;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"# {0} - number of objects\",\n    \"TruffleTypeNode_MoreNodes=<another {0} objects left>\", // <another 1234 objects left>\n    \"# {0} - number of objects\",\n    \"TruffleTypeNode_SamplesContainer=<sample {0} objects>\", // <sample 1234 objects>\n    \"# {0} - first index\",\n    \"# {1} - last index\",\n    \"TruffleTypeNode_NodesContainer=<objects {0}-{1}>\" // <objects 1001 - 2000>\n})\npublic abstract class TruffleTypeNode<O extends TruffleObject, T extends TruffleType<O>> extends HeapViewerNode {\n    \n    private final T type;\n    \n    \n    protected TruffleTypeNode(T type) {\n        this.type = type;\n    }\n    \n    \n    public abstract HeapViewerNode createNode(O object);\n    \n    public abstract TruffleTypeNode<O,T> createCopy();\n    \n    \n    public T getType() {\n        return type;\n    }\n    \n    \n    public String getName() {\n        return type.getName();\n    }\n    \n    public int getObjectsCount() {\n        return type.getObjectsCount();\n    }\n    \n    public long getOwnSize() {\n        return type.getAllObjectsSize();\n    }\n    \n    public long getRetainedSize(Heap heap) {\n        return type.getRetainedSizeByType(heap);\n    }\n    \n    \n    public TruffleObjectsWrapper<O> getObjectsWrapper() {\n        return new TruffleObjectsWrapper<O>() {\n            @Override\n            public String getType() {\n                return TruffleTypeNode.this.getName();\n            }\n\n            @Override\n            public int getObjectsCount() {\n                return TruffleTypeNode.this.getObjectsCount();\n            }\n\n            @Override\n            public Iterator<O> getObjectsIterator() {\n                return type.getObjectsIterator();\n            }\n        };\n    }\n    \n    \n    public boolean isLeaf() {\n        return type.getObjectsCount() == 0 ? true : super.isLeaf();\n    }\n    \n    public String toString() {\n        return getName();\n    }\n    \n    \n    protected HeapViewerNode[] computeChildren(RootNode root) {\n        int itemsCount = type.getObjectsCount();\n        if (itemsCount <= UIThresholds.MAX_CLASS_INSTANCES) {\n            Heap heap = root.getContext().getFragment().getHeap();\n            HeapViewerNode[] nodes = new HeapViewerNode[itemsCount];\n            Iterator<O> iterator = type.getObjectsIterator();\n            int i = 0;\n            while (iterator.hasNext()) {\n                O object = iterator.next();\n                nodes[i++] = createNode(object);\n            }\n            return nodes;\n        } else {\n            return super.computeChildren(root);\n        }\n    }\n    \n    protected HeapViewerNode[] lazilyComputeChildren(Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n        NodesComputer<O> computer = new NodesComputer<O>(type.getObjectsCount(), UIThresholds.MAX_CLASS_INSTANCES) {\n            protected boolean sorts(DataType dataType) {\n                return !DataType.COUNT.equals(dataType);\n            }\n            protected HeapViewerNode createNode(O object) {\n                return TruffleTypeNode.this.createNode(object);\n            }\n            protected ProgressIterator<O> objectsIterator(int index, Progress progress) {\n                Iterator<O> iterator = type.getObjectsIterator();\n                return new ProgressIterator<>(iterator, index, true, progress);\n            }\n            protected String getMoreNodesString(String moreNodesCount)  {\n                return Bundle.TruffleTypeNode_MoreNodes(moreNodesCount);\n            }\n            protected String getSamplesContainerString(String objectsCount)  {\n                return Bundle.TruffleTypeNode_SamplesContainer(objectsCount);\n            }\n            protected String getNodesContainerString(String firstNodeIdx, String lastNodeIdx)  {\n                return Bundle.TruffleTypeNode_NodesContainer(firstNodeIdx, lastNodeIdx);\n            }\n        };\n        return computer.computeNodes(this, heap, viewID, null, dataTypes, sortOrders, progress);\n    }\n    \n    \n    public boolean equals(Object o) {\n        if (o == this) return true;\n        if (!(o instanceof TruffleTypeNode)) return false;\n        return getName().equals(((TruffleTypeNode)o).getName());\n    }\n    \n    public int hashCode() {\n        return getName().hashCode();\n    }\n    \n    \n    protected Object getValue(DataType type, Heap heap) {\n        if (type == DataType.NAME) return getName();\n        if (type == DataType.COUNT) return getObjectsCount();\n        if (type == DataType.OWN_SIZE) return getOwnSize();\n        if (type == DataType.RETAINED_SIZE) return getRetainedSize(heap);\n        \n        if (type == TruffleType.TYPE_NAME) return getName();\n        if (type == TruffleObjectsWrapper.DATA_TYPE) return getObjectsWrapper();\n        \n        if (type == DataType.LOGICAL_VALUE) return DataType.LOGICAL_VALUE.getNoValue();\n        if (type == DataType.OBJECT_ID) return DataType.OBJECT_ID.getNoValue();\n        \n        return super.getValue(type, heap);\n    }\n    \n    \n    protected void setupCopy(TruffleTypeNode<O,T> copy) {\n        super.setupCopy(copy);\n    }\n    \n    \n    public static class Renderer extends LabelRenderer implements HeapViewerRenderer {\n        \n        public Renderer(Icon icon) {\n            setIcon(icon);\n            setFont(getFont().deriveFont(Font.BOLD));\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/swing/EditableHistoryCombo.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.truffle.swing;\n\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.JComboBox;\nimport javax.swing.JTextField;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.JTextComponent;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class EditableHistoryCombo extends JComboBox {\n    \n    private Runnable onTextChange;\n    \n    public EditableHistoryCombo() {\n        super(new ComboHistoryModel(10));\n        \n        setEditable(true);\n//        putClientProperty(\"JComboBox.isTableCellEditor\", Boolean.TRUE); // NOI18N\n        \n        setPrototypeDisplayValue(\"org.graalvm.visualvm.lib.ui.swing.XXXXXXXXXXXXXXXXXXXX\"); // NOI18N\n        Dimension dim = getPreferredSize();\n        dim.height = !UIUtils.isNimbusLookAndFeel() ? getMinimumSize().height :\n                     new JTextField(\"X\").getPreferredSize().height; // NOI18N\n        \n        setMinimumSize(dim);\n        setPreferredSize(dim);\n        setMaximumSize(dim);\n        \n        JTextComponent comp = getTextComponent();\n        if (comp != null) comp.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e)  { onChange(); }\n            public void removeUpdate(DocumentEvent e)  { onChange(); }\n            public void changedUpdate(DocumentEvent e) { onChange(); }\n            private void onChange() { if (onTextChange != null) onTextChange.run(); }\n        });\n    }\n    \n    \n    public JTextComponent getTextComponent() {\n        Component comp = getEditor().getEditorComponent();\n        return comp instanceof JTextComponent ? (JTextComponent)comp : null;\n    }\n    \n    public String getText() {\n        JTextComponent textC = getTextComponent();\n        return textC != null ? textC.getText() : getSelectedItem().toString();\n    }\n    \n    public void setOnTextChangeHandler(Runnable handler) {\n        onTextChange = handler;\n    }\n    \n    \n    private static class ComboHistoryModel extends DefaultComboBoxModel {\n        \n        private final int historySize;\n        \n        \n        ComboHistoryModel(int historySize) {\n            this.historySize = historySize;\n        }\n        \n        \n        public void addElement(Object item) {\n            insertElementAt(item, 0);\n        }\n        \n        public void insertElementAt(Object item, int index) {\n            int current = getIndexOf(item);\n            if (current == index) return;\n            \n            if (current != -1) removeElementAt(current);\n            super.insertElementAt(item, index);\n            \n            if (getSize() > historySize) removeElementAt(historySize);\n            \n            setSelectedItem(item);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/swing/LinkButton.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.truffle.swing;\n\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.FocusAdapter;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SwingUtilities;\n\n/**\n * Copied from org.graalvm.visualvm.heapviewer.swing.LinkButton\n *\n * @author Jiri Sedlacek\n */\npublic class LinkButton extends JButton {\n    \n    private boolean mouseOver;\n    private boolean focused;\n    private String text;\n    \n    public LinkButton() {\n        super();\n        tweak();\n    }\n    \n    public LinkButton(String text) {\n        super(text);\n        tweak();\n    }\n    \n    public LinkButton(String text, Icon icon) {\n        super(text, icon);\n        tweak();\n    }\n    \n    \n    public void setText(String text) {\n        this.text = text.replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\").replace(\" \", \"&nbsp;\"); // NOI18N\n        if (isEnabled() && (mouseOver || focused)) super.setText(\"<html><a href='#'>\" + this.text + \"</a></html>\"); // NOI18N\n        else super.setText(\"<html>\" + this.text + \"</html>\"); // NOI18N\n    }\n    \n    protected void fireActionPerformed(ActionEvent e) {\n        super.fireActionPerformed(e);\n        clicked();\n    }\n    \n    public Dimension getMinimumSize() {\n        return getPreferredSize();\n    }\n    \n    public Dimension getMaximumSize() {\n        return getPreferredSize();\n    }\n    \n    protected void clicked() {}\n    \n    protected void middleClicked(MouseEvent e) {}\n    \n    protected void populatePopup(JPopupMenu popup) {}\n    \n    \n    protected void processKeyEvent(KeyEvent e) {\n        int code = e.getKeyCode();\n        if (code == KeyEvent.VK_CONTEXT_MENU ||\n           (code == KeyEvent.VK_F10 && e.getModifiers() == InputEvent.SHIFT_MASK)) {\n            e.consume();\n            showPopupMenu(null);\n        }\n        \n        super.processKeyEvent(e);\n    }\n    \n    \n    private void tweak() {\n        setBorder(BorderFactory.createEmptyBorder(2, 3, 2, 3));\n        setOpaque(false);\n        setContentAreaFilled(false);\n        setFocusPainted(false);\n        setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n        MouseAdapter mouse = new MouseAdapter() {\n            public void mouseEntered(MouseEvent e) {\n                mouseOver = true;\n                setText(text);\n            }\n            public void mouseExited(MouseEvent e) {\n                mouseOver = false;\n                setText(text);\n            }\n            public void mouseMoved(MouseEvent e) {\n                if (!mouseOver) {\n                    mouseOver = true;\n                    setText(text);\n                }\n            }\n            public void mousePressed(MouseEvent e) {\n                if (e.isPopupTrigger()) showPopupMenu(e);\n            }\n            public void mouseReleased(MouseEvent e) {\n                if (e.isPopupTrigger()) showPopupMenu(e);\n            }\n            public void mouseClicked(MouseEvent e) {\n                if (SwingUtilities.isMiddleMouseButton(e)) middleClicked(e);\n            }\n        };\n        addMouseListener(mouse);\n        addMouseMotionListener(mouse);\n        addFocusListener(new FocusAdapter() {\n            public void focusGained(FocusEvent e) {\n                focused = true;\n                setText(text);\n            }\n            public void focusLost(FocusEvent e) {\n                focused = false;\n                mouseOver = false;\n                setText(text);\n            }\n        });\n    }\n    \n    private void showPopupMenu(MouseEvent e) {\n        JPopupMenu popup = new JPopupMenu();\n        populatePopup(popup);\n        \n        if (popup.getComponentCount() > 0) {\n            Dimension pref = popup.getPreferredSize();\n            if (e == null) {\n                popup.show(this, getWidth() / 2, -pref.height);\n            } else {\n                popup.show(this, e.getX(), e.getY() - pref.height);\n            }\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/swing/Splitter.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.truffle.swing;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.JSplitPane;\nimport javax.swing.SwingUtilities;\nimport javax.swing.plaf.basic.BasicSplitPaneDivider;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\nimport org.graalvm.visualvm.uisupport.UISupport;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class Splitter extends JSplitPane {\n    \n    private CustomizedSplitPaneUI splitterUI;\n\n    private HierarchyListener leftComponentListener;\n    private HierarchyListener rightComponentListener;\n    \n    private double dividerLocation;\n    private int customDividerSize;\n    private double requestedDividerLocation = -1;\n    \n    private static final Color BACKGROUND_COLOR;\n    private static final Color HIGHLIGHT_BACKGROUND;\n\n\n    static {\n        BACKGROUND_COLOR = UISupport.getDefaultBackground();\n\n        int darkerR = BACKGROUND_COLOR.getRed() - 20;\n        if (darkerR < 0) darkerR += 40;\n        int darkerG = BACKGROUND_COLOR.getGreen() - 20;\n        if (darkerG < 0) darkerG += 40;\n        int darkerB = BACKGROUND_COLOR.getBlue() - 20;\n        if (darkerB < 0) darkerB += 40;\n\n        HIGHLIGHT_BACKGROUND = new Color(darkerR, darkerG, darkerB);\n    }\n\n    \n    public Splitter(int newOrientation, Component newLeftComponent, Component newRightComponent) {\n        this(newOrientation, false, newLeftComponent, newRightComponent);\n    }\n\n    public Splitter(int newOrientation, boolean newContinuousLayout, Component newLeftComponent,\n                              Component newRightComponent) {\n        super(newOrientation, newContinuousLayout, newLeftComponent, newRightComponent);\n\n        updateVisibility();\n\n        if (!newLeftComponent.isVisible())\n            computeDividerLocationWhenInitiallyHidden(newLeftComponent);\n\n        if (!newRightComponent.isVisible())\n            computeDividerLocationWhenInitiallyHidden(newRightComponent);\n        \n        setResizeWeight(0.5d);\n        setDividerLocation(0.5d);\n    }\n\n\n    public void setDividerSize(int newSize) {\n        super.setDividerSize(newSize);\n        customDividerSize = newSize;\n    }\n\n    public void setDividerLocation(double requestedDividerLocation) {\n        Component divider = getDivider();\n        if (isVisible() && divider.isVisible()) { // SplitPane fully visible\n            super.setDividerLocation(requestedDividerLocation);\n            dividerLocation = requestedDividerLocation;\n        } else if (isVisible()) { // Divider not visible, will be updated in updateVisibility()\n            dividerLocation = requestedDividerLocation;\n        } else if (!isVisible()) { // SplitPane not visible, dividerLocation will be set on first reasonable getSize()\n            this.requestedDividerLocation = requestedDividerLocation;\n        }\n    }\n\n\n    public void setLeftComponent(Component newLeftComponent) {\n        if (leftComponent != null) {\n            leftComponent.removeHierarchyListener(leftComponentListener);\n            leftComponentListener = null;\n        }\n\n        super.setLeftComponent(newLeftComponent);\n\n        if (getLeftComponent() != null) {\n            leftComponentListener = new VisibilityListener(newLeftComponent);\n            newLeftComponent.addHierarchyListener(leftComponentListener);\n        }\n\n        updateVisibility();\n    }\n\n    public void setRightComponent(Component newRightComponent) {\n        if (rightComponent != null) {\n            rightComponent.removeHierarchyListener(rightComponentListener);\n            rightComponentListener = null;\n        }\n\n        super.setRightComponent(newRightComponent);\n\n        if (getRightComponent() != null) {\n            rightComponentListener = new VisibilityListener(newRightComponent);\n            newRightComponent.addHierarchyListener(rightComponentListener);\n        }\n\n        updateVisibility();\n    }\n    \n\n    public void reshape(int x, int y, int width, int height) {\n        super.reshape(x, y, width, height);\n        if (width > 0 && height > 0 && requestedDividerLocation != -1) {\n            super.setDividerLocation(requestedDividerLocation);\n            dividerLocation = requestedDividerLocation;\n            // SplitPaneUI.paint() needs to be invoked here to set the\n            // BasicSplitPaneUI.painted flag to enable resizing the divider\n            // even if the component hasn't been shown yet.\n            ((BasicSplitPaneUI)getUI()).paint(getGraphics(), this);\n            requestedDividerLocation = -1;\n        }\n    }\n\n    \n    private Component getDivider() {\n        if (ui == null) return null;\n        return ((BasicSplitPaneUI)ui).getDivider();\n    }\n\n    private void computeDividerLocationWhenHidden(Component hiddenComponent) {\n        if (leftComponent.isVisible() || rightComponent.isVisible()) {\n            boolean horiz = getOrientation() == JSplitPane.HORIZONTAL_SPLIT;\n            double size  = horiz ? getSize().getWidth() :\n                                   getSize().getHeight();\n            double csize = horiz ? hiddenComponent.getSize().getWidth() :\n                                   hiddenComponent.getSize().getHeight();\n            computeDividerLocation(hiddenComponent, size, csize);\n        }\n    }\n\n    private void computeDividerLocationWhenInitiallyHidden(Component hiddenComponent) {\n        if (leftComponent.isVisible() || rightComponent.isVisible()) {\n            boolean horiz = getOrientation() == JSplitPane.HORIZONTAL_SPLIT;\n            double size  = horiz ? getPreferredSize().getWidth() :\n                                   getPreferredSize().getHeight();\n            double csize = horiz ? hiddenComponent.getPreferredSize().getWidth() :\n                                   hiddenComponent.getPreferredSize().getHeight();\n            computeDividerLocation(hiddenComponent, size, csize);\n        }\n    }\n\n    private void computeDividerLocation(Component hiddenComponent, double size, double csize) {\n        if (hiddenComponent == leftComponent) {\n            dividerLocation = csize / (size - customDividerSize);\n        } else {\n            dividerLocation = (size - customDividerSize - csize) / (size - customDividerSize);\n        }\n    }\n\n    private void updateVisibility() {\n        Component divider = getDivider(); // null UI, not yet set\n        if (divider == null) return;\n\n        if (leftComponent == null || rightComponent == null) return;\n\n        boolean leftVisible = leftComponent.isVisible();\n        boolean rightVisible = rightComponent.isVisible();\n\n        if (leftVisible && rightVisible) {\n            if (!divider.isVisible()) {\n                Splitter.super.setDividerSize(customDividerSize);\n                divider.setVisible(true);\n                setDividerLocation(dividerLocation);\n            }\n            if (!isVisible()) setVisible(true);\n        } else if (!leftVisible && !rightVisible) {\n            if (isVisible()) setVisible(false);\n        } else {\n            if (divider.isVisible()) {\n                Splitter.super.setDividerSize(0);\n                divider.setVisible(false);\n                setDividerLocation(0);\n            }\n            if (!isVisible()) setVisible(true);\n        }\n\n        if (getParent() != null) getParent().doLayout();\n    }\n    \n    \n    public void updateUI() {\n        if (getUI() != customUI()) setUI(customUI());\n\n        setBorder(null);\n        setOpaque(false);\n        setDividerSize(6);\n        setContinuousLayout(true);\n\n        final BasicSplitPaneDivider divider = ((BasicSplitPaneUI) getUI()).getDivider();\n        divider.setBackground(BACKGROUND_COLOR);\n        divider.setBorder(null);\n\n        divider.addMouseListener(new MouseAdapter() {\n            public void mouseEntered(MouseEvent e) {\n                divider.setBackground(HIGHLIGHT_BACKGROUND);\n                divider.repaint();\n            }\n            public void mouseExited(MouseEvent e) {\n                divider.setBackground(BACKGROUND_COLOR);\n                divider.repaint();\n            }\n            public void mouseClicked(MouseEvent e) {\n                if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {\n                    setResizeWeight(0.5d);\n                    setDividerLocation(0.5d);\n                }\n            }\n        });\n    }\n    \n    private CustomizedSplitPaneUI customUI() {\n        if (splitterUI == null) splitterUI = new CustomizedSplitPaneUI();\n        return splitterUI;\n    }\n    \n    \n    private static class CustomizedSplitPaneUI extends BasicSplitPaneUI {\n        public BasicSplitPaneDivider createDefaultDivider() {\n            return new BasicSplitPaneDivider(this) {\n                public void paint(Graphics g) {\n                    Dimension size = getSize();\n                    g.setColor(getBackground());\n                    g.fillRect(0, 0, size.width, size.height);\n                }\n            };\n        }\n    }\n\n\n    private class VisibilityListener implements HierarchyListener {\n\n        private boolean wasVisible;\n        private final Component c;\n\n        VisibilityListener(Component c) {\n            this.c = c;\n            wasVisible = c.isVisible();\n        }\n\n        public void hierarchyChanged(HierarchyEvent e) {\n            if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 ||\n                (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) {\n                \n                boolean visible = c.isVisible();\n                if (wasVisible == visible) return;\n\n                wasVisible = visible;\n\n                if (visible) componentShown();\n                else componentHidden(c);\n            }\n        }\n\n        private void componentHidden(Component c) {\n            computeDividerLocationWhenHidden(c);\n\n            // Make sure the component is visible when shown\n            if ((dividerLocation <= 0) || (dividerLocation >= 1))\n                dividerLocation = 0.5;\n\n            updateVisibility();\n        }\n\n        private void componentShown() {\n            updateVisibility();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/ui/FilterUtils.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.heapviewer.truffle.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.KeyEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.Icon;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.JToolBar;\nimport javax.swing.KeyStroke;\nimport javax.swing.RowFilter;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.text.JTextComponent;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleType;\nimport org.graalvm.visualvm.heapviewer.truffle.swing.EditableHistoryCombo;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableView;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.filters.TextFilter;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.CloseButton;\nimport org.graalvm.visualvm.lib.ui.results.ColoredFilter;\nimport org.graalvm.visualvm.lib.ui.results.PackageColorer;\nimport org.graalvm.visualvm.lib.ui.swing.InvisibleToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleFilterUtils_ActionFilter=Filter\",\n    \"TruffleFilterUtils_TypeFilter=Type Filter:\",\n    \"# {0} - accelerator\",\n    \"TruffleFilterUtils_FilterResults=Filter results ({0})\",\n    \"TruffleFilterUtils_MatchCase=Match case\",\n    \"# {0} - accelerator\",\n    \"TruffleFilterUtils_Close=Close Filter sidebar ({0})\",\n    \"# {0} - invalid text\",\n    \"TruffleFilterUtils_InvalidRegexp=Entered regular expression is invalid:\\n{0}\",\n    \"TruffleFilterUtils_FilterContains=Contains\",\n    \"TruffleFilterUtils_FilterNotContains=Does Not Contain\",\n    \"TruffleFilterUtils_FilterRegExp=Regular Expression\",\n    \"# {0} - name\",\n    \"TruffleFilterUtils_FilterType=Filter type: {0}\",\n    \"TruffleFilterUtils_InsertFilter=Insert Defined Filter\"\n})\nfinal class FilterUtils {\n    \n    private static final String FILTER_ACTION_KEY = \"filter-action-key\"; // NOI18N\n    \n    private static final String FILTER_CHANGED = \"filter-changed\"; // NOI18N\n    \n    \n//    public static boolean filterContains(ProfilerTable table, String filter) {\n//        return filterContains(table, filter, false, null);\n//    }\n//    \n//    public static boolean filterContains(ProfilerTable table, String filter, boolean matchCase, RowFilter excludes) {\n//        return filter(table, new TextFilter(filter, TextFilter.TYPE_INCLUSIVE, matchCase), excludes);\n//    }\n//    \n//    public static boolean filterNotContains(ProfilerTable table, String filter, boolean matchCase, RowFilter excludes) {\n//        return filter(table, new TextFilter(filter, TextFilter.TYPE_EXCLUSIVE, matchCase), excludes);\n//    }\n//    \n//    public static boolean filterRegExp(ProfilerTable table, String filter, RowFilter excludes) {\n//        return filter(table, new TextFilter(filter, TextFilter.TYPE_REGEXP, false), excludes);\n//    }\n    \n    public static boolean filter(TreeTableView view, final GenericFilter textFilter, final RowFilter excludesFilter) {\n        if (textFilter.isAll()) {\n            view.setViewFilter(null);\n            return false;\n        }\n        \n        view.setViewFilter(new HeapViewerNodeFilter() {\n            public boolean passes(HeapViewerNode node, Heap heap) {\n                String typeName = HeapViewerNode.getValue(node, TruffleType.TYPE_NAME, heap);\n                return typeName == null ? true : textFilter.passes(typeName);\n            }\n        });\n        return true;\n    }\n    \n    public static JComponent createFilterPanel(final TreeTableView view) {\n        return createFilterPanel(view, null);\n    }\n    \n    public static JComponent createFilterPanel(final TreeTableView view, final RowFilter excludesFilter) {\n        return createFilterPanel(view, excludesFilter, null);\n    }\n    \n    public static JComponent createFilterPanel(final TreeTableView view, final RowFilter excludesFilter, Component[] options) {\n        JToolBar toolbar = new InvisibleToolbar();\n        if (UIUtils.isWindowsModernLookAndFeel())\n            toolbar.setBorder(BorderFactory.createEmptyBorder(2, 2, 1, 2));\n        else if (!UIUtils.isNimbusLookAndFeel() && !UIUtils.isAquaLookAndFeel())\n            toolbar.setBorder(BorderFactory.createEmptyBorder(1, 2, 1, 2));\n        \n        toolbar.add(Box.createHorizontalStrut(6));\n        toolbar.add(new JLabel(Bundle.TruffleFilterUtils_TypeFilter()));\n        toolbar.add(Box.createHorizontalStrut(3));\n        \n        final EditableHistoryCombo combo = new EditableHistoryCombo();        \n        final JTextComponent textC = combo.getTextComponent();\n        \n        JPanel comboContainer = new JPanel(new BorderLayout());\n        comboContainer.add(combo, BorderLayout.CENTER);\n        comboContainer.setMinimumSize(combo.getMinimumSize());\n        comboContainer.setPreferredSize(combo.getPreferredSize());\n        comboContainer.setMaximumSize(combo.getMaximumSize());\n        \n        toolbar.add(comboContainer);\n        \n        if (PackageColorer.hasRegisteredColors()) {\n            toolbar.add(new PopupButton() {\n                {\n                    setToolTipText(Bundle.TruffleFilterUtils_InsertFilter());\n                }\n//                protected void displayPopup() {\n//                    JPopupMenu menu = new JPopupMenu();\n//                    populatePopup(menu);\n//                    if (menu.getComponentCount() > 0) {\n//                        Dimension size = menu.getPreferredSize();\n//                        size.width = Math.max(size.width, getWidth());\n//                        menu.setPreferredSize(size);\n//                        menu.show(this, 0, -size.height);\n//                    }\n//                }\n                protected void populatePopup(JPopupMenu popup) {\n                    for (final ColoredFilter color : PackageColorer.getRegisteredColors()) {\n                        if (color.getValue().trim().isEmpty()) continue;\n                        Icon icon = color.getColor() == null ? null : color.getIcon(12, 12);\n                        popup.add(new JMenuItem(color.getName(), icon) {\n                            protected void fireActionPerformed(ActionEvent event) {\n                                String current = getFilterString(combo);\n                                if (current == null) current = \"\"; // NOI18N\n                                if (!current.isEmpty()) current += \" \"; // NOI18N\n                                current += color.getValue();\n                                textC.setText(current);\n                                combo.requestFocusInWindow();\n                            }\n                        });\n                    }\n                }\n            });\n        }\n        \n        toolbar.add(Box.createHorizontalStrut(5));\n        \n        KeyStroke escKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);\n        KeyStroke filterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);\n        \n        final TextFilter activeFilter = new TextFilter() {\n            protected void handleInvalidFilter(String invalidValue, RuntimeException e) {\n                ProfilerDialogs.displayError(Bundle.TruffleFilterUtils_InvalidRegexp(invalidValue));\n            }\n        };\n        final TextFilter currentFilter = new TextFilter();\n        \n        final JButton filter = new JButton(Bundle.TruffleFilterUtils_ActionFilter(), Icons.getIcon(GeneralIcons.FILTER)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                final JButton _this = this;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        activeFilter.copyFrom(currentFilter);\n                        if (filter(view, activeFilter, excludesFilter))\n                            combo.addItem(activeFilter.getValue());\n                        putClientProperty(FILTER_CHANGED, null);\n                        updateFilterButton(_this, currentFilter, activeFilter);\n                    }\n                });\n            }\n        };\n        String filterAccelerator = ActionsSupport.keyAcceleratorString(filterKey);\n        filter.setToolTipText(Bundle.TruffleFilterUtils_FilterResults(filterAccelerator));\n        filter.putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n        \n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(final ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        if (filter.isEnabled()) {\n                            filter.doClick();\n                            combo.requestFocusInWindow();\n                        }\n                    }\n                });\n            }\n        };\n        installAction(filter, filterAction, filterKey, FILTER_ACTION_KEY);\n        toolbar.add(filter);\n        \n        updateFilterButton(filter, currentFilter, activeFilter);\n        \n        toolbar.add(Box.createHorizontalStrut(2));\n        \n        toolbar.addSeparator();\n        \n        toolbar.add(Box.createHorizontalStrut(1));\n        \n        final JToggleButton matchCase = new JToggleButton(Icons.getIcon(GeneralIcons.MATCH_CASE)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                if (isEnabled()) SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        currentFilter.setCaseSensitive(isSelected());\n                        updateFilterButton(filter, currentFilter, activeFilter);\n                    }\n                });\n            }\n        };\n        matchCase.setToolTipText(Bundle.TruffleFilterUtils_MatchCase());\n        installAction(matchCase, filterAction, filterKey, FILTER_ACTION_KEY);\n        \n        FilterType filterType = new FilterType(Icons.getIcon(GeneralIcons.FILTER_CONTAINS)) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new JMenuItem(Bundle.TruffleFilterUtils_FilterContains(), Icons.getIcon(GeneralIcons.FILTER_CONTAINS)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(TextFilter.TYPE_INCLUSIVE, getIcon(), getText());\n                    }\n                });\n                popup.add(new JMenuItem(Bundle.TruffleFilterUtils_FilterNotContains(), Icons.getIcon(GeneralIcons.FILTER_NOT_CONTAINS)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(TextFilter.TYPE_EXCLUSIVE, getIcon(), getText());\n                    }\n                });\n                popup.add(new JMenuItem(Bundle.TruffleFilterUtils_FilterRegExp(), Icons.getIcon(GeneralIcons.FILTER_REG_EXP)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(TextFilter.TYPE_REGEXP, getIcon(), getText());\n                    }\n                });\n            }\n            protected void filterImpl(final int type, final Icon icon, final String name) {\n                if (type == TextFilter.TYPE_REGEXP) {\n                    matchCase.setEnabled(false);\n                    matchCase.setSelected(false);\n                } else {\n                    if (!matchCase.isEnabled()) {\n                        matchCase.setSelected(currentFilter.isCaseSensitive());\n                        matchCase.setEnabled(true);\n                    }\n                }\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setIcon(icon);\n                        setToolTipText(Bundle.TruffleFilterUtils_FilterType(name));\n                        currentFilter.setType(type);\n                        updateFilterButton(filter, currentFilter, activeFilter);\n                    }\n                });\n            }\n        };\n        filterType.setToolTipText(Bundle.TruffleFilterUtils_FilterType(Bundle.TruffleFilterUtils_FilterContains()));\n        installAction(filterType, filterAction, filterKey, FILTER_ACTION_KEY);\n        toolbar.add(filterType);\n        \n        toolbar.add(matchCase);\n        \n        if (options != null) for (Component option : options) toolbar.add(option);\n        \n        toolbar.add(Box.createHorizontalStrut(2));\n        \n        combo.setOnTextChangeHandler(new Runnable() {\n            public void run() {\n                currentFilter.setValue(getFilterString(combo));\n                updateFilterButton(filter, currentFilter, activeFilter);\n            }\n        });\n        \n        final JPanel panel = new JPanel(new BorderLayout()) {\n            public void setVisible(boolean visible) {\n                super.setVisible(visible);\n                if (!visible) view.getComponent().requestFocusInWindow();\n            }\n            public boolean requestFocusInWindow() {\n                if (textC != null) textC.selectAll();\n                return combo.requestFocusInWindow();\n            }\n        };\n        panel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UIManager.getColor(\"controlShadow\"))); // NOI18N\n        panel.add(toolbar, BorderLayout.CENTER);\n        \n        final Runnable hider = new Runnable() {\n            public void run() {\n                boolean wasAll = activeFilter.isAll();\n                activeFilter.setValue(\"\"); // NOI18N\n                updateFilterButton(filter, currentFilter, activeFilter);\n                if (!wasAll) filter(view, activeFilter, excludesFilter);\n                panel.setVisible(false);\n            }\n        };\n        JButton closeButton = CloseButton.create(hider);\n        closeButton.setFocusable(true);\n        String escAccelerator = ActionsSupport.keyAcceleratorString(escKey);\n        closeButton.setToolTipText(Bundle.TruffleFilterUtils_Close(escAccelerator));\n        panel.add(closeButton, BorderLayout.EAST);\n        \n        String HIDE = \"hide-action\"; // NOI18N\n        InputMap map = panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        Action hiderAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { hider.run(); }\n        };\n        panel.getActionMap().put(HIDE, hiderAction);\n        map.put(escKey, HIDE);\n        \n        if (textC != null) {\n            map = textC.getInputMap();\n            Action _filterAction = new AbstractAction() {\n                public void actionPerformed(final ActionEvent e) {\n                    if (combo.isPopupVisible()) combo.hidePopup();\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { if (filter.isEnabled()) filter.doClick(); }\n                    });\n                }\n            };\n            textC.getActionMap().put(FILTER_ACTION_KEY, _filterAction);\n            map.put(filterKey, FILTER_ACTION_KEY);\n        }\n        \n        panel.putClientProperty(\"SET_FILTER_CHANGED\", new AbstractAction() { // NOI18N\n            public void actionPerformed(final ActionEvent e) {\n                filter.putClientProperty(FILTER_CHANGED, Boolean.TRUE);\n                updateFilterButton(filter, currentFilter, activeFilter);\n            }\n        });\n        \n        panel.putClientProperty(\"FILTER_STRING\", textC); // NOI18N\n        panel.putClientProperty(\"FILTER_TYPE\", filterType); // NOI18N\n        panel.putClientProperty(\"FILTER_ACTION\", filterAction); // NOI18N\n        \n        return panel;\n    }\n    \n    private static abstract class FilterType extends PopupButton {\n        FilterType(Icon icon) { super(icon); }\n        protected abstract void filterImpl(final int type, final Icon icon, final String name);\n    }\n    \n    private static void installAction(JComponent comp, Action action, KeyStroke keyStroke, String actionKey) {\n        comp.getActionMap().put(actionKey, action);\n        comp.getInputMap().put(keyStroke, actionKey);\n    }\n    \n    private static String getFilterString(EditableHistoryCombo combo) {\n        String filter = combo.getText();\n        return filter == null ? null : filter.trim();\n    }\n    \n    private static void updateFilterButton(JButton button, TextFilter currentFilter, TextFilter activeFilter) {\n        if (Boolean.TRUE.equals(button.getClientProperty(FILTER_CHANGED))) button.setEnabled(true);\n        else button.setEnabled(!currentFilter.equals(activeFilter));\n    }\n    \n    private static abstract class Filter extends RowFilter {\n\n        public boolean equals(Object o) {\n            return o instanceof Filter;\n        }\n        \n        public int hashCode() {\n            return Integer.MAX_VALUE;\n        }\n    \n    }\n    \n    \n    // Do not create instances of this class\n    private FilterUtils() {}\n    \n    \n//    // Default keybinding Ctrl+G for Filter action\n//    private static interface Support { @ServiceProvider(service=ActionsSupportProvider.class, position=100)\n//        public static final class FilterActionProvider extends ActionsSupportProvider {\n//            public KeyStroke registerAction(String actionKey, Action action, ActionMap actionMap, InputMap inputMap) {\n//                if (!FILTER_ACTION_KEY.equals(actionKey)) return null;\n//                \n//                KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.CTRL_MASK);\n//                actionMap.put(actionKey, action);\n//                inputMap.put(ks, actionKey);\n//\n//                return ks;\n//            }\n//        }\n//    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/ui/TruffleObjectView.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.ui;\n\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguage;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.NodeObjectsView;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class TruffleObjectView extends NodeObjectsView {\n    \n    private static final String VIEW_ID = \"objects\"; // NOI18N\n    \n    \n    public TruffleObjectView(TruffleLanguage language, HeapViewerNode node, HeapContext context, HeapViewerActions actions) {\n        super(idFromLanguage(language), node, context, actions);\n    }\n    \n    \n    static String idFromLanguage(TruffleLanguage language) {\n        return language.getID() + \"_\" + VIEW_ID; // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/ui/TruffleObjectsView.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.ui;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport java.util.List;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ButtonGroup;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JToggleButton;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguage;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObjectsProvider;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.graalvm.visualvm.heapviewer.ui.PluggableTreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.ActionPopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleObjectsView_Name=Objects\",\n    \"TruffleObjectsView_Description=Objects\",\n    \"TruffleObjectsView_Compare=Compare with another heap dump...\",\n    \"TruffleObjectsView_AllObjects=All Objects\",\n    \"TruffleObjectsView_Dominators=Dominators\",\n    \"TruffleObjectsView_GcRoots=GC Roots\",\n    \"TruffleObjectsView_Types=Types\",\n    \"TruffleObjectsView_Objects=Objects\",\n    \"TruffleObjectsView_FilterSubclasses=Filter Subclasses\",\n    \"TruffleObjectsView_Preset=Preset:\",\n    \"TruffleObjectsView_Aggregation=Aggregation:\",\n    \"TruffleObjectsView_Details=Details:\"\n})\npublic class TruffleObjectsView extends HeapViewerFeature {\n    \n    private static final String FEATURE_ID = \"objects\"; // NOI18N\n    \n    protected static enum Preset {\n        ALL_OBJECTS (Bundle.TruffleObjectsView_AllObjects()),\n        DOMINATORS (Bundle.TruffleObjectsView_Dominators()),\n        GC_ROOTS (Bundle.TruffleObjectsView_GcRoots());\n        \n        private final String presetName;\n        private Preset(String presetName) { this.presetName = presetName; }\n        public String toString() { return presetName; } \n    }\n    \n    protected static enum Aggregation {\n        TYPES (Bundle.TruffleObjectsView_Types(), Icons.getIcon(LanguageIcons.PACKAGE)),\n        OBJECTS (Bundle.TruffleObjectsView_Objects(), Icons.getIcon(LanguageIcons.INSTANCE));\n        \n        private final String aggregationName;\n        private final Icon aggregationIcon;\n        private Aggregation(String aggregationName, Icon aggregationIcon) { this.aggregationName = aggregationName; this.aggregationIcon = aggregationIcon; }\n        public String toString() { return aggregationName; }\n        public Icon getIcon() { return aggregationIcon; }\n    }\n    \n    \n    private final TruffleLanguage language;\n    \n    private final HeapContext context;\n    \n    private ProfilerToolbar toolbar;\n    private final PluggableTreeTableView objectsView;\n    private JComponent component;\n    \n    private Preset preset = Preset.ALL_OBJECTS;\n    private Aggregation aggregation = Aggregation.TYPES;\n    \n    private ActionPopupButton apbPreset;\n    \n    private JToggleButton tbType;\n    private JToggleButton tbObject;\n    \n    \n    public TruffleObjectsView(TruffleLanguage language, HeapContext context, HeapViewerActions actions) {\n        super(idFromLanguage(language), Bundle.TruffleObjectsView_Name(), Bundle.TruffleObjectsView_Description(), iconFromLanguage(language), 200);\n        \n        this.language = language;\n        this.context = context;\n        Heap heap = context.getFragment().getHeap();\n        \n        final TruffleObjectsProvider objectsProvider = new TruffleObjectsProvider(language);\n        \n        objectsView = new PluggableTreeTableView(getID(), context, actions, TreeTableViewColumn.classes(heap, true)) {\n            protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                switch (getPreset()) {\n                    case ALL_OBJECTS:\n                        switch (getAggregation()) {\n                            case TYPES:\n                                return objectsProvider.getAllObjects(root, context, viewID, viewFilter, dataTypes, sortOrders, progress, 1);\n                            default:\n                                return objectsProvider.getAllObjects(root, context, viewID, viewFilter, dataTypes, sortOrders, progress, 0);\n                        }\n                    case DOMINATORS:\n                        switch (getAggregation()) {\n                            case TYPES:\n                                return objectsProvider.getDominators(root, context, viewID, viewFilter, dataTypes, sortOrders, progress, 1);\n                            default:\n                                return objectsProvider.getDominators(root, context, viewID, viewFilter, dataTypes, sortOrders, progress, 0);\n                        }\n                    case GC_ROOTS:\n                        switch (getAggregation()) {\n                            case TYPES:\n                                return objectsProvider.getGCRoots(root, context, viewID, viewFilter, dataTypes, sortOrders, progress, 1);\n                            default:\n                                return objectsProvider.getGCRoots(root, context, viewID, viewFilter, dataTypes, sortOrders, progress, 0);\n                        }\n                    default:\n                        return HeapViewerNode.NO_NODES;\n                }\n            }\n            protected JComponent createComponent() {\n                if (component == null) {\n                    component = super.createComponent();\n                    setFilterComponent(FilterUtils.createFilterPanel(this));\n                }\n\n                return component;\n            }\n        };\n    }\n    \n    \n    static String idFromLanguage(TruffleLanguage language) {\n        return language.getID() + \"_\" + FEATURE_ID; // NOI18N\n    }\n    \n    static Icon iconFromLanguage(TruffleLanguage language) {\n        return language.createLanguageIcon(Icons.getIcon(LanguageIcons.CLASS));\n    }\n    \n    \n    public JComponent getComponent() {\n        if (toolbar == null) init();\n        return objectsView.getComponent();\n    }\n\n    public ProfilerToolbar getToolbar() {\n        if (toolbar == null) init();\n        return toolbar;\n    }\n    \n    \n    private volatile boolean skipReload = false;\n    \n    public void configureTypesByObjectsCount() {\n        try {\n            objectsView.setSortColumn(DataType.COUNT, SortOrder.DESCENDING);\n            \n            if (apbPreset == null) {\n                preset = Preset.ALL_OBJECTS;\n            } else if (preset != Preset.ALL_OBJECTS) {\n                skipReload = true;\n                setPreset(Preset.ALL_OBJECTS);\n                apbPreset.selectAction(preset.ordinal());\n            }\n\n            if (tbType == null) {\n                skipReload = true;\n                setAggregation(Aggregation.TYPES);\n            } else if (!tbType.isSelected()) {\n                skipReload = true;\n                tbType.setSelected(true);\n            }\n            \n            if (skipReload) objectsView.reloadView();\n        } finally {\n            skipReload = false;\n        }\n    }\n    \n    public void configureTypesByObjectsSize() {\n        try {\n            objectsView.setSortColumn(DataType.OWN_SIZE, SortOrder.DESCENDING);\n            \n            if (apbPreset == null) {\n                preset = Preset.ALL_OBJECTS;\n            } else if (preset != Preset.ALL_OBJECTS) {\n                skipReload = true;\n                setPreset(Preset.ALL_OBJECTS);\n                apbPreset.selectAction(preset.ordinal());\n            }\n\n            if (tbType == null) {\n                skipReload = true;\n                setAggregation(Aggregation.TYPES);\n            } else if (!tbType.isSelected()) {\n                skipReload = true;\n                tbType.setSelected(true);\n            }\n            \n            if (skipReload) objectsView.reloadView();\n        } finally {\n            skipReload = false;\n        }\n    }\n    \n    public void configureObjectsBySize() {\n        try {\n            objectsView.setSortColumn(DataType.OWN_SIZE, SortOrder.DESCENDING);\n            \n            if (apbPreset == null) {\n                preset = Preset.ALL_OBJECTS;\n            } else if (preset != Preset.ALL_OBJECTS) {\n                skipReload = true;\n                setPreset(Preset.ALL_OBJECTS);\n                apbPreset.selectAction(preset.ordinal());\n            }\n\n            if (tbObject == null) {\n                skipReload = true;\n                setAggregation(Aggregation.OBJECTS);\n            } else if (!tbObject.isSelected()) {\n                skipReload = true;\n                tbObject.setSelected(true);\n            }\n            \n            if (skipReload) objectsView.reloadView();\n        } finally {\n            skipReload = false;\n        }\n    }\n    \n    public void configureDominatorsByRetainedSize() {\n        try {\n            objectsView.setSortColumn(DataType.RETAINED_SIZE, SortOrder.DESCENDING);\n            \n            if (apbPreset == null) {\n                preset = Preset.DOMINATORS;\n            } else if (preset != Preset.DOMINATORS) {\n                skipReload = true;\n                setPreset(Preset.DOMINATORS);\n                apbPreset.selectAction(preset.ordinal());\n            }\n\n            if (tbObject == null) {\n                skipReload = true;\n                setAggregation(Aggregation.OBJECTS);\n            } else if (!tbObject.isSelected()) {\n                skipReload = true;\n                tbObject.setSelected(true);\n            }\n            \n            if (skipReload) objectsView.reloadView();\n        } finally {\n            skipReload = false;\n        }\n    }\n    \n    \n    private Runnable dominatorsRefresher;\n    \n    synchronized void setPreset(Preset preset) {\n        if (preset == Preset.DOMINATORS) {\n            final Heap heap = context.getFragment().getHeap();\n            if (!DataType.RETAINED_SIZE.valuesAvailable(heap)) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        dominatorsRefresher = new Runnable() {\n                            public void run() {\n                                if (getPreset() == Preset.DOMINATORS) objectsView.reloadView();\n                                dominatorsRefresher = null;\n                            }\n                        };\n                        DataType.RETAINED_SIZE.notifyWhenAvailable(heap, dominatorsRefresher);\n                        DataType.RETAINED_SIZE.computeValues(heap, null);\n                    }\n                });\n            }\n        }\n        \n        this.preset = preset;\n        objectsView.setViewName(preset.toString());\n        if (!skipReload) objectsView.reloadView();\n    }\n    \n    private synchronized Preset getPreset() {\n        return preset;\n    }\n    \n    private volatile boolean countVisible1 = true;\n    private volatile boolean countVisible2 = false;\n    \n    synchronized void setAggregation(Aggregation aggregation) {\n        boolean objectsInvolved = Aggregation.OBJECTS.equals(aggregation) ||\n                                  Aggregation.OBJECTS.equals(this.aggregation);\n        \n        this.aggregation = aggregation;\n        \n        if (objectsInvolved) {\n            // TODO: having Count visible for Instances aggregation resets the column width!\n            objectsView.getComponent(); // Make sure objectsView is initialized before accessing its columns\n            boolean countVisible = objectsView.isColumnVisible(DataType.COUNT);\n            if (Aggregation.OBJECTS.equals(aggregation)) {\n                countVisible1 = countVisible;\n                objectsView.setColumnVisible(DataType.COUNT, countVisible2);\n            } else {\n                countVisible2 = countVisible;\n                objectsView.setColumnVisible(DataType.COUNT, countVisible1);\n            }\n        }\n        \n        if (!skipReload) objectsView.reloadView();\n    }\n    \n    private synchronized Aggregation getAggregation() {\n        return aggregation;\n    }\n        \n    \n    private void init() {\n        toolbar = ProfilerToolbar.create(false);\n        \n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n        \n        toolbar.add(new GrayLabel(Bundle.TruffleObjectsView_Preset()));\n        toolbar.addSpace(2);\n        \n        class PresetAction extends AbstractAction {\n            final Preset preset;\n            PresetAction(Preset preset) {\n                this.preset = preset;\n                putValue(NAME, preset.toString());\n            }\n            public void actionPerformed(ActionEvent e) {\n                setPreset(preset);\n            }\n        }\n        Preset[] presetItems = Preset.values();\n        Action[] presetActions = new PresetAction[presetItems.length];\n        for (int i = 0; i < presetItems.length; i++) presetActions[i] = new PresetAction(presetItems[i]);\n        apbPreset = new ActionPopupButton(0, presetActions);\n        apbPreset.selectAction(preset.ordinal());\n        toolbar.add(apbPreset);\n        \n        toolbar.addSpace(8);\n        \n        toolbar.add(new GrayLabel(Bundle.TruffleObjectsView_Aggregation()));\n        toolbar.addSpace(2);\n        \n        final ButtonGroup aggregationBG = new ButtonGroup();\n        class AggregationButton extends JToggleButton {\n            private final Aggregation aggregation;\n            AggregationButton(Aggregation aggregation, boolean selected) {\n                super(language.createLanguageIcon(aggregation.getIcon()), selected);\n                this.aggregation = aggregation;\n                setToolTipText(aggregation.toString());\n                aggregationBG.add(this);\n            }\n            protected void fireItemStateChanged(ItemEvent e) {\n                // invoked also from constructor: super(aggregation.getIcon(), selected)\n                // in this case aggregation is still null, ignore the event...\n                if (e.getStateChange() == ItemEvent.SELECTED && aggregation != null) setAggregation(aggregation);\n            }\n        }\n        \n        tbType = new AggregationButton(Aggregation.TYPES, Aggregation.TYPES.equals(aggregation));\n        tbType.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        tbType.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        toolbar.add(tbType);\n        \n        tbObject = new AggregationButton(Aggregation.OBJECTS, Aggregation.OBJECTS.equals(aggregation));\n        tbObject.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        tbObject.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n        toolbar.add(tbObject);\n        \n        setPreset(preset);\n        \n        if (objectsView.hasPlugins()) {\n            toolbar.addSpace(8);\n\n            toolbar.add(new GrayLabel(Bundle.TruffleObjectsView_Details()));\n            toolbar.addSpace(2);\n            \n            toolbar.add(objectsView.getToolbar());\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/ui/TruffleSummaryView.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.FocusAdapter;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.text.NumberFormat;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.PriorityQueue;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguage;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguageHeapFragment;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObject;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleObjectsProvider;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleType;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleObjectNode;\nimport org.graalvm.visualvm.heapviewer.truffle.nodes.TruffleTypeNode;\nimport org.graalvm.visualvm.heapviewer.truffle.swing.LinkButton;\nimport org.graalvm.visualvm.heapviewer.truffle.swing.Splitter;\nimport org.graalvm.visualvm.heapviewer.ui.HeapView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerNodeAction;\nimport org.graalvm.visualvm.heapviewer.ui.SummaryView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.graalvm.visualvm.uisupport.SeparatorLine;\nimport org.graalvm.visualvm.uisupport.VerticalLayout;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleSummaryView_Name=Summary\",\n    \"TruffleSummaryView_Description=Summary\",\n    \"TruffleSummaryView_ComputingProgress=computing...\",\n    \"TruffleSummaryView_NameColumn=Name\",\n    \"TruffleSummaryView_ValueColumn=Value\"\n})\npublic class TruffleSummaryView extends HeapViewerFeature {\n    \n    private static final String FEATURE_ID = \"summary\"; // NOI18N\n    \n    private final SummaryView summaryView;\n    \n    \n    public TruffleSummaryView(TruffleLanguage language, HeapContext context, HeapViewerActions actions) {\n        super(idFromLanguage(language), Bundle.TruffleSummaryView_Name(), Bundle.TruffleSummaryView_Description(), iconFromLanguage(language), 100);\n        \n        summaryView = new SummaryView(getID(), context, actions) {\n            @Override\n            protected void uiCreated(List<HeapView> views) {\n                if (!views.isEmpty()) new RequestProcessor(\"Truffle Summary Worker\").post(new Runnable() { // NOI18N\n                    public void run() {\n                        for (HeapView view : views)\n                            if (view instanceof TruffleSummarySection)\n                                ((TruffleSummarySection) view).computeData();\n                    }\n                });\n            }\n        };\n    }\n    \n    \n    static String idFromLanguage(TruffleLanguage language) {\n        return language.getID() + \"_\" + FEATURE_ID; // NOI18N\n    }\n    \n    static Icon iconFromLanguage(TruffleLanguage language) {\n        return language.createLanguageIcon(Icons.getIcon(HeapWalkerIcons.PROPERTIES));\n    }\n    \n\n    @Override\n    public boolean isDefault() {\n        return true;\n    }\n    \n    @Override\n    public JComponent getComponent() {\n        return summaryView.getComponent();\n    }\n\n    @Override\n    public ProfilerToolbar getToolbar() {\n        return summaryView.getToolbar();\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // =========================================================================\n    // -------------------------------------------------------------------------\n    \n    public static abstract class TruffleSummarySection extends HeapView {\n        \n        public TruffleSummarySection(String name, String description) {\n            super(name, description);\n        }\n        \n        protected void computeData() {}\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // =========================================================================\n    // -------------------------------------------------------------------------\n    \n    @NbBundle.Messages({\n        \"TruffleOverviewSection_Name=Overview\",\n        \"TruffleOverviewSection_Description=Overview\",\n        \"TruffleOverviewSection_HeapSection=Heap\",\n        \"TruffleOverviewSection_EnvironmentSection=Environment\",\n        \"TruffleOverviewSection_SizeItem=Size:\",\n        \"TruffleOverviewSection_TypesItem=Types:\",\n        \"TruffleOverviewSection_ObjectsItem=Objects:\",\n        \"TruffleOverviewSection_LanguageItem=Language:\"\n    })\n    public static abstract class OverviewSection extends TruffleSummarySection {\n        \n        private final HeapContext context;\n        \n        private final int heapItemsCount;\n        private final int environmentItemsCount;\n        \n        private JComponent component;\n        \n        private TruffleOverviewSnippet heapSnippet;\n        private TruffleOverviewSnippet environmentSnippet;\n        \n        \n        public OverviewSection(HeapContext context) {\n            this(context, 3, 1);\n        }\n        \n        public OverviewSection(HeapContext context, int heapItemsCount, int languageItemsCount) {\n            super(Bundle.TruffleOverviewSection_Name(), Bundle.TruffleOverviewSection_Description());\n            \n            this.context = context;\n            \n            \n            this.heapItemsCount = heapItemsCount;\n            this.environmentItemsCount = languageItemsCount;\n        }\n\n        \n        @Override\n        public JComponent getComponent() {\n            if (component == null) init();\n            return component;\n        }\n\n        @Override\n        public ProfilerToolbar getToolbar() {\n            return null;\n        }\n        \n        \n        protected HeapContext getContext() {\n            return context;\n        }\n        \n        \n        @Override\n        protected final void computeData() {\n            Object[][] heapData = new Object[heapItemsCount][2];\n            computeHeapData(heapData);\n            heapSnippet.setData(heapData);\n            \n            Object[][] environmentData = new Object[environmentItemsCount][2];\n            computeEnvironmentData(environmentData);\n            environmentSnippet.setData(environmentData);\n        }\n        \n        protected void computeHeapData(Object[][] heapData) {\n            TruffleLanguageHeapFragment fragment = (TruffleLanguageHeapFragment)context.getFragment();\n            \n            NumberFormat numberFormat = NumberFormat.getInstance();\n            \n            heapData[0][0] = Bundle.TruffleOverviewSection_SizeItem();\n            heapData[0][1] = numberFormat.format(fragment.getHeapSize(null)) + \" B\"; // NOI18N\n            \n            heapData[1][0] = Bundle.TruffleOverviewSection_TypesItem();\n            heapData[1][1] = numberFormat.format(fragment.getTypes(null).size());\n            \n            heapData[2][0] = Bundle.TruffleOverviewSection_ObjectsItem();\n            heapData[2][1] = numberFormat.format(fragment.getObjectsCount(null));\n        }\n        \n        protected void computeEnvironmentData(Object[][] environmentData) {\n            environmentData[0][0] = Bundle.TruffleOverviewSection_LanguageItem();\n            environmentData[0][1] = getContext().getFragment().getDescription();\n        }\n        \n        \n        private void init() {\n            heapSnippet = new TruffleOverviewSnippet(Bundle.TruffleOverviewSection_HeapSection(), heapItemsCount, 0);\n            environmentSnippet = new TruffleOverviewSnippet(Bundle.TruffleOverviewSection_EnvironmentSection(), environmentItemsCount, 1);\n            Splitter overviewRow = new Splitter(Splitter.HORIZONTAL_SPLIT, heapSnippet, environmentSnippet);\n\n            component = new JPanel(new VerticalLayout(false)) {\n                public Dimension getMinimumSize() {\n                    Dimension dim = super.getMinimumSize();\n                    dim.width = 0;\n                    return dim;\n                }\n\n                public Dimension getPreferredSize() {\n                    Dimension dim = super.getPreferredSize();\n                    dim.width = 100;\n                    return dim;\n                }\n            };\n            component.setOpaque(false);\n\n            component.add(overviewRow);\n        }\n        \n    }\n    \n    private static class TruffleOverviewSnippet extends JPanel {\n        \n        private final int fillerColumn;\n        private final SummaryView.SimpleTable table;\n        \n        TruffleOverviewSnippet(String text, int itemsCount, int fillerColumn) {\n            super(new BorderLayout(0, 6));\n            \n            setOpaque(false);\n            setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 5));\n            \n            add(new SectionSeparator(text), BorderLayout.NORTH);\n            \n            \n            TableModel model = new DefaultTableModel(itemsCount, 2) {\n                { setValueAt(Bundle.TruffleSummaryView_ComputingProgress(), 0, 0); }\n                public boolean isCellEditable(int row, int column) { return false; }\n            };\n\n            ProfilerRenderer renderer = new LabelRenderer() {\n                public void setValue(Object o, int i) {\n                    super.setValue(o, i);\n                    setIcon(o == null || o.toString().isEmpty() ? null : Icons.getIcon(HeapWalkerIcons.PROGRESS));\n                }\n            };\n            \n            this.fillerColumn = fillerColumn;\n\n            table = new SummaryView.SimpleTable(model, fillerColumn);\n            table.setColumnRenderer(0, renderer, fillerColumn != 0);\n            table.setColumnRenderer(1, renderer, fillerColumn != 1);\n            \n            table.setFocusable(false);\n            \n            add(table, BorderLayout.CENTER);\n        }\n        \n        void setData(Object[][] data) {\n            final TableModel model = new DefaultTableModel(data, new Object[] { Bundle.TruffleSummaryView_NameColumn(),\n                                                                                Bundle.TruffleSummaryView_ValueColumn() }) {\n                public boolean isCellEditable(int row, int column) { return false; }\n            };\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    table.setModel(model);\n                    \n                    LabelRenderer r1 = new LabelRenderer();\n                    r1.setFont(r1.getFont().deriveFont(Font.BOLD));\n                    table.setColumnRenderer(0, r1, fillerColumn != 0);\n                    LabelRenderer r2 = new LabelRenderer();\n                    r2.setHorizontalAlignment(LabelRenderer.RIGHT);\n                    table.setColumnRenderer(1, r2, fillerColumn != 1);\n                }\n            });\n        }\n        \n        public Dimension getMinimumSize() {\n            Dimension dim = super.getMinimumSize();\n            dim.width = 0;\n            return dim;\n        }\n        \n        public Dimension getPreferredSize() {\n            Dimension dim = super.getPreferredSize();\n            dim.width = 100;\n            return dim;\n        }\n        \n    }\n    \n    \n    // -------------------------------------------------------------------------\n    // =========================================================================\n    // -------------------------------------------------------------------------\n    \n    @NbBundle.Messages({\n        \"TruffleObjectsSection_Name=Statistics\",\n        \"TruffleObjectsSection_Description=Statistics\",\n        \"TruffleObjectsSection_HeapSection=Heap\",\n        \"TruffleObjectsSection_ClassesInstancesCount=Types by Number of Objects\",\n        \"TruffleObjectsSection_ClassesInstancesSize=Types by Size of Objects\",\n        \"TruffleObjectsSection_InstancesSize=Objects by Size\",\n        \"TruffleObjectsSection_DominatorsRetainedSize=Dominators by Retained Size\",\n        \"TruffleObjectsSection_ComputeRetainedSizesLbl=Retained sizes must be computed first:\",\n        \"TruffleObjectsSection_ComputeRetainedSizesBtn=Compute Retained Sizes\",\n        \"TruffleObjectsSection_ComputingRetainedSizes=computing retained sizes...\",\n        \"TruffleObjectsSection_ComputingProgress=computing...\",\n        \"TruffleObjectsSection_ViewAll=view all\",\n        \"TruffleObjectsSection_NameColumn=Name\",\n        \"TruffleObjectsSection_ValueColumn=Value\",\n        \"TruffleObjectsSection_NoDominators=<no dominators found>\"\n    })\n    public static class ObjectsSection<O extends TruffleObject, T extends TruffleType<O>, F extends TruffleLanguageHeapFragment<O, T>, L extends TruffleLanguage<O, T, F>> extends TruffleSummarySection {\n\n        private static final int PREVIEW_ITEMS = 5;\n        \n        private final L language;\n        \n        private final HeapContext context;\n        private final HeapViewerActions actions;\n        private final Collection<HeapViewerNodeAction.Provider> actionProviders;\n\n        private JComponent component;\n        \n        private ResultsSnippet typesByCount;\n        private ResultsSnippet typesBySize;\n        private ResultsSnippet objectsBySize;\n        private ResultsSnippet dominatorsByRetainedSize;\n        \n        private boolean retainedAvailable;\n\n\n        public ObjectsSection(L language, HeapContext context, HeapViewerActions actions, Collection<HeapViewerNodeAction.Provider> actionProviders) {\n            super(Bundle.TruffleObjectsSection_Name(), Bundle.TruffleObjectsSection_Description());\n            \n            this.language = language;\n            \n            this.context = context;\n            this.actions = actions;\n            this.actionProviders = actionProviders;\n        }\n        \n        \n        @Override\n        public JComponent getComponent() {\n            if (component == null) init();\n            return component;\n        }\n\n        @Override\n        public ProfilerToolbar getToolbar() {\n            return null;\n        }\n        \n        \n        @Override\n        protected final void computeData() {\n            TruffleLanguageHeapFragment<O, T> fragment = (TruffleLanguageHeapFragment)context.getFragment();\n            Heap heap = fragment.getHeap();\n            \n            List<TruffleType> allTypes = new ArrayList(fragment.getTypes(null));\n\n            // --- Classes by Instances Count ------------------------------\n            Collections.sort(allTypes, new Comparator<TruffleType>() {\n                @Override\n                public int compare(TruffleType t1, TruffleType t2) {\n                    return Integer.compare(t2.getObjectsCount(), t1.getObjectsCount());\n                }\n            });\n            int items = Math.min(PREVIEW_ITEMS, allTypes.size());\n            TruffleType[] typesByCountArr = allTypes.subList(0, items).toArray(new TruffleType[0]);\n            Object[][] typesByCountData = new Object[typesByCountArr.length][2];\n            for (int i = 0; i < typesByCountData.length; i++) {\n                typesByCountData[i][0] = language.createTypeNode((T)typesByCountArr[i], heap);\n                typesByCountData[i][1] = typesByCountArr[i].getObjectsCount();\n            }\n            configureSnippet(typesByCount, typesByCountData);\n\n\n            // --- Classes by Instances Size -------------------------------\n            Collections.sort(allTypes, new Comparator<TruffleType>() {\n                @Override\n                public int compare(TruffleType t1, TruffleType t2) {\n                    return Long.compare(t2.getAllObjectsSize(), t1.getAllObjectsSize());\n                }\n            });\n            TruffleType[] typesBySizeArr = allTypes.subList(0, items).toArray(new TruffleType[0]);\n            Object[][] typesBySizeData = new Object[typesBySizeArr.length][2];\n            for (int i = 0; i < typesBySizeData.length; i++) {\n                typesBySizeData[i][0] = language.createTypeNode((T)typesBySizeArr[i], heap);\n                typesBySizeData[i][1] = typesBySizeArr[i].getAllObjectsSize();\n            }\n            configureSnippet(typesBySize, typesBySizeData);\n\n\n            // --- Instances by Size ---------------------------------------\n\n            items = (int)Math.min(PREVIEW_ITEMS, heap.getSummary().getTotalLiveInstances());\n            PriorityQueue<TruffleObject> pqBySize = new PriorityQueue(items, new Comparator<TruffleObject>() {\n                @Override\n                public int compare(TruffleObject o1, TruffleObject o2) {\n                    return Long.compare(o1.getSize(), o2.getSize());\n                }\n            });\n            Iterator<O> allObjects = fragment.getObjectsIterator();\n            while (allObjects.hasNext()) {\n                O in = allObjects.next();\n                if (pqBySize.size() < items || pqBySize.peek().getSize() < in.getSize()) {\n                    if (pqBySize.size() == items) pqBySize.remove();\n                    pqBySize.add(in);\n                }\n            }\n            TruffleObject[] objectsBySizeArr = new TruffleObject[pqBySize.size()];\n            for (int i = objectsBySizeArr.length - 1; i >= 0; i--)\n                objectsBySizeArr[i] = pqBySize.poll();\n            Object[][] instancesBySizeData = new Object[objectsBySizeArr.length][2];\n            for (int i = 0; i < instancesBySizeData.length; i++) {\n                O object = (O)objectsBySizeArr[i];\n                instancesBySizeData[i][0] = language.createObjectNode(object, object.getType());\n                instancesBySizeData[i][1] = objectsBySizeArr[i].getSize();\n            }\n            configureSnippet(objectsBySize, instancesBySizeData);\n\n\n            // --- Dominators by Retained Size -----------------------------\n            if (retainedAvailable) computeDominators(dominatorsByRetainedSize);\n        }\n\n\n        private void init() {\n            Heap heap = context.getFragment().getHeap();\n            \n            Icon typeIcon = language.createLanguageIcon(Icons.getIcon(LanguageIcons.PACKAGE));\n            final ProfilerRenderer typeRenderer = new TruffleTypeNode.Renderer(typeIcon);\n            \n            Icon instanceIcon = language.createLanguageIcon(Icons.getIcon(LanguageIcons.INSTANCE));\n            final ProfilerRenderer objectRenderer = new TruffleObjectNode.Renderer(heap, instanceIcon);\n\n            TreeTableViewColumn sizeColumn = new TreeTableViewColumn.OwnSize(heap);\n            final HideableBarRenderer sizeRenderer = (HideableBarRenderer)sizeColumn.getRenderer();\n\n            TreeTableViewColumn classesByCountColumn = new TreeTableViewColumn.Count(heap);\n            final HideableBarRenderer classesByCountRenderer = (HideableBarRenderer)classesByCountColumn.getRenderer();\n\n            Runnable typesByCountDisplayer = new Runnable() {\n                public void run() {\n                    TruffleObjectsView objectsView = (TruffleObjectsView)actions.findFeature(TruffleObjectsView.idFromLanguage(language));\n                    if (objectsView != null) {\n                        objectsView.configureTypesByObjectsCount();\n                        actions.selectFeature(objectsView);\n                    }\n                }\n            };\n            typesByCount = new ResultsSnippet(Bundle.TruffleObjectsSection_ClassesInstancesCount(), typesByCountDisplayer) {\n                protected void setupTable(ProfilerTable table) {\n                    table.setColumnRenderer(0, typeRenderer);\n                    table.setColumnRenderer(1, classesByCountRenderer);\n                    table.setDefaultColumnWidth(1, classesByCountRenderer.getNoBarWidth() + 10);\n                }\n            };\n\n            Runnable typesBySizeDisplayer = new Runnable() {\n                public void run() {\n                    TruffleObjectsView objectsView = (TruffleObjectsView)actions.findFeature(TruffleObjectsView.idFromLanguage(language));\n                    if (objectsView != null) {\n                        objectsView.configureTypesByObjectsSize();\n                        actions.selectFeature(objectsView);\n                    }\n                }\n            };\n            typesBySize = new ResultsSnippet(Bundle.TruffleObjectsSection_ClassesInstancesSize(), typesBySizeDisplayer) {\n                protected void setupTable(ProfilerTable table) {\n                    table.setColumnRenderer(0, typeRenderer);\n                    table.setColumnRenderer(1, sizeRenderer);\n                    table.setDefaultColumnWidth(1, sizeRenderer.getNoBarWidth() + 10);\n                }\n            };\n\n            Splitter classesRow = new Splitter(Splitter.HORIZONTAL_SPLIT, typesByCount, typesBySize);\n\n            Runnable objectsBySizeDisplayer = new Runnable() {\n                public void run() {\n                    TruffleObjectsView objectsView = (TruffleObjectsView)actions.findFeature(TruffleObjectsView.idFromLanguage(language));\n                    if (objectsView != null) {\n                        objectsView.configureObjectsBySize();\n                        actions.selectFeature(objectsView);\n                    }\n                }\n            };\n            objectsBySize = new ResultsSnippet(Bundle.TruffleObjectsSection_InstancesSize(), objectsBySizeDisplayer) {\n                protected void setupTable(ProfilerTable table) {\n                    table.setColumnRenderer(0, objectRenderer);\n                    table.setColumnRenderer(1, sizeRenderer);\n                    table.setDefaultColumnWidth(1, sizeRenderer.getNoBarWidth() + 10);\n                }\n            };\n\n            retainedAvailable = DataType.RETAINED_SIZE.valuesAvailable(heap);\n            Runnable dominatorsByRetainedSizeDisplayer = new Runnable() {\n                public void run() {\n                    TruffleObjectsView objectsView = (TruffleObjectsView)actions.findFeature(TruffleObjectsView.idFromLanguage(language));\n                    if (objectsView != null) {\n                        objectsView.configureDominatorsByRetainedSize();\n                        actions.selectFeature(objectsView);\n                    }\n                }\n            };\n            dominatorsByRetainedSize = new ResultsSnippet(Bundle.TruffleObjectsSection_DominatorsRetainedSize(), dominatorsByRetainedSizeDisplayer) {\n                private Runnable retainedSizesUpdater;\n                protected JComponent createComponent() {\n                    if (retainedAvailable) {\n                        return super.createComponent();\n                    } else {\n                        final JPanel p = new JPanel(new GridBagLayout());\n                        p.setOpaque(false);\n\n                        final JLabel l = new JLabel(Bundle.TruffleObjectsSection_ComputeRetainedSizesLbl(), JLabel.LEADING);\n                        GridBagConstraints c = new GridBagConstraints();\n                        c.gridx = 0;\n                        c.gridy = 0;\n                        c.fill = GridBagConstraints.NONE;\n                        c.anchor = GridBagConstraints.NORTHWEST;\n                        c.insets = new Insets(2, 2, 2, 2);\n                        p.add(l, c);\n\n                        c = new GridBagConstraints();\n                        c.gridx = 1;\n                        c.gridy = 0;\n                        c.weightx = 1d;\n                        c.fill = GridBagConstraints.HORIZONTAL;\n                        c.anchor = GridBagConstraints.NORTHWEST;\n                        c.insets = new Insets(0, 0, 0, 0);\n                        p.add(UIUtils.createFillerPanel(), c);\n\n                        c = new GridBagConstraints();\n                        c.gridx = 0;\n                        c.gridy = 1;\n                        c.fill = GridBagConstraints.NONE;\n                        c.anchor = GridBagConstraints.NORTHWEST;\n                        c.insets = new Insets(2, 2, 2, 2);\n\n                        JButton lb = new JButton(Bundle.TruffleObjectsSection_ComputeRetainedSizesBtn()) {\n                            protected void fireActionPerformed(ActionEvent e) {\n                                if (DataType.RETAINED_SIZE.computeValues(heap, null)) {\n                                    p.remove(this);\n                                    l.setText(Bundle.TruffleObjectsSection_ComputingRetainedSizes());\n                                    l.setIcon(Icons.getIcon(HeapWalkerIcons.PROGRESS));\n                                    p.invalidate();\n                                    p.revalidate();\n                                    p.repaint();\n                                }\n                            }\n                        };\n\n                        final ResultsSnippet rs = this;\n                        retainedSizesUpdater = new Runnable() {\n                            public void run() {\n                                new RequestProcessor(\"Objects Summary Retained Sizes Worker\").post(new Runnable() { // NOI18N\n                                    public void run() {\n                                        computeDominators(rs);\n                                        retainedAvailable = true;\n                                        retainedSizesUpdater = null;\n                                    }\n                                });\n                            }\n                        };\n                        DataType.RETAINED_SIZE.notifyWhenAvailable(heap, retainedSizesUpdater);\n\n                        p.add(lb, c);\n\n                        c = new GridBagConstraints();\n                        c.gridx = 1;\n                        c.gridy = 1;\n                        c.weightx = 1d;\n                        c.fill = GridBagConstraints.HORIZONTAL;\n                        c.anchor = GridBagConstraints.NORTHWEST;\n                        c.insets = new Insets(0, 0, 0, 0);\n                        p.add(UIUtils.createFillerPanel(), c);\n\n                        c = new GridBagConstraints();\n                        c.gridx = 0;\n                        c.gridy = 2;\n                        c.weightx = 1d;\n                        c.weighty = 1d;\n                        c.fill = GridBagConstraints.BOTH;\n                        c.anchor = GridBagConstraints.NORTHWEST;\n                        c.insets = new Insets(0, 0, 0, 0);\n                        p.add(UIUtils.createFillerPanel(), c);\n\n                        return p;\n                    }\n                }\n                protected void setupTable(ProfilerTable table) {\n                    table.setColumnRenderer(0, objectRenderer);\n\n                    TreeTableViewColumn dominatorsByRetainedSizeColumn = new TreeTableViewColumn.RetainedSize(heap);\n                    HideableBarRenderer retainedRenderer = (HideableBarRenderer)dominatorsByRetainedSizeColumn.getRenderer();\n                    table.setColumnRenderer(1, retainedRenderer);\n                    table.setDefaultColumnWidth(1, retainedRenderer.getNoBarWidth() + 10);\n                }\n                void setRealModel(TableModel model) {\n                    if (model.getRowCount() == 0) {\n                        if (table == null) {\n                            BorderLayout bl = (BorderLayout)getLayout();\n                            Component c = bl.getLayoutComponent(BorderLayout.CENTER);\n                            if (c != null) remove(c);\n                            \n                            TableModel _model = new DefaultTableModel(1, 1) {\n                                { setValueAt(Bundle.TruffleObjectsSection_NoDominators(), 0, 0); }\n                                public boolean isCellEditable(int row, int column) { return false; }\n                            };\n\n                            table = createTable(_model);\n                            table.setDefaultRenderer(Object.class, new LabelRenderer());\n                            add(table, BorderLayout.CENTER);\n\n                            Container parent = getParent();\n                            if (parent != null) {\n                                parent.invalidate();\n                                parent.revalidate();\n                                parent.repaint();\n                            }\n                        } else {\n                            DefaultTableModel dmodel = (DefaultTableModel)table.getModel();\n                            table.setDefaultRenderer(Object.class, new LabelRenderer());\n                            dmodel.setValueAt(Bundle.TruffleObjectsSection_NoDominators(), 0, 0);\n                            dmodel.fireTableDataChanged();\n                        }\n                    } else {\n                        super.setRealModel(model);\n                    }\n                }\n            };\n\n            Splitter instancesRow = new Splitter(Splitter.HORIZONTAL_SPLIT, objectsBySize, dominatorsByRetainedSize);\n\n\n            component = new JPanel(new VerticalLayout(false, 5)) {\n                public Dimension getMinimumSize() {\n                    Dimension dim = super.getMinimumSize();\n                    dim.width = 0;\n                    return dim;\n                }\n\n                public Dimension getPreferredSize() {\n                    Dimension dim = super.getPreferredSize();\n                    dim.width = 100;\n                    return dim;\n                }\n            };\n            component.setOpaque(false);\n\n            component.add(classesRow);\n            component.add(instancesRow);\n        }\n\n\n        private void computeDominators(ResultsSnippet dominatorsByRetainedSize) {\n            TruffleLanguageHeapFragment fragment = (TruffleLanguageHeapFragment)context.getFragment();\n            Heap heap = fragment.getHeap();\n            \n            List<? extends TruffleObject> dominators = dominators((TruffleLanguageHeapFragment)context.getFragment());\n            Collections.sort(dominators, new Comparator<TruffleObject>() {\n                @Override\n                public int compare(TruffleObject o1, TruffleObject o2) {\n                    return Long.compare(o2.getRetainedSize(), o1.getRetainedSize());\n                }\n            });\n            int items = Math.min(PREVIEW_ITEMS, dominators.size());\n            TruffleObject[] dominatorsByRetainedSizeArr = dominators.subList(0, items).toArray(new TruffleObject[0]);\n            Object[][] dominatorsByRetainedSizeData = new Object[dominatorsByRetainedSizeArr.length][2];\n            for (int i = 0; i < dominatorsByRetainedSizeData.length; i++) {\n                O object = (O)dominatorsByRetainedSizeArr[i];\n                dominatorsByRetainedSizeData[i][0] = language.createObjectNode(object, object.getType());\n                dominatorsByRetainedSizeData[i][1] = dominatorsByRetainedSizeArr[i].getRetainedSize();\n            }\n            configureSnippet(dominatorsByRetainedSize, dominatorsByRetainedSizeData);\n        }\n        \n        \n        private List<? extends TruffleObject> dominators(TruffleLanguageHeapFragment heapFragment) {\n            int maxSearchInstances = 10000;\n\n            List<Instance> searchInstances = heapFragment.getHeap().getBiggestObjectsByRetainedSize(maxSearchInstances);\n            Iterator<Instance> searchInstancesI = searchInstances.iterator();\n            while (searchInstancesI.hasNext()) {\n                Instance instance = searchInstancesI.next();\n                if (!language.isLanguageObject(instance)) searchInstancesI.remove();\n            }\n            \n            Set<Instance> rootInstances = TruffleObjectsProvider.getDominatorRoots(searchInstances);\n            List<O> rootObjects = new ArrayList<>();\n            for (Instance root : rootInstances) rootObjects.add(language.createObject(root));\n            \n            return rootObjects;\n        }\n\n\n        private void configureSnippet(final ResultsSnippet snippet, final Object[][] data) {\n            final TableModel model = new DefaultTableModel(data, new Object[] {\n                                                Bundle.TruffleObjectsSection_NameColumn(),\n                                                Bundle.TruffleObjectsSection_ValueColumn() }) {\n                public boolean isCellEditable(int row, int column) { return false; }\n            };\n\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    snippet.setRealModel(model);\n                }\n            });\n        }\n\n\n        private class ResultsSnippet extends JPanel {\n\n            private final LinkButton link;\n            protected ProfilerTable table;\n            private boolean keepSelection;\n\n            ResultsSnippet(String text, final Runnable allDisplayer) {\n                super(new BorderLayout(0, 6));\n                setOpaque(false);\n                setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 5));\n\n                JPanel sectionSeparator = new JPanel(new GridBagLayout());\n                sectionSeparator.setOpaque(false);\n\n                JLabel caption = new JLabel(text);\n                caption.setFont(caption.getFont().deriveFont(Font.BOLD));\n                GridBagConstraints c = new GridBagConstraints();\n                c.gridx = 0;\n                c.gridy = 0;\n                c.weighty = 1d;\n                sectionSeparator.add(caption, c);\n\n                c = new GridBagConstraints();\n                c.gridx = 1;\n                c.gridy = 0;\n                c.insets = new Insets(0, 5, 0, 0);\n                sectionSeparator.add(new JLabel(\"[\"), c); // NOI18N\n\n                link = new LinkButton(Bundle.TruffleObjectsSection_ViewAll()) {\n                    @Override\n                    protected void clicked() {\n                        SwingUtilities.invokeLater(allDisplayer);\n                    }\n                };\n                link.setEnabled(false);\n                c = new GridBagConstraints();\n                c.gridx = 2;\n                c.gridy = 0;\n                c.insets = new Insets(0, 0, 0, 0);\n                sectionSeparator.add(link, c);\n\n                c = new GridBagConstraints();\n                c.gridx = 3;\n                c.gridy = 0;\n                c.insets = new Insets(0, 0, 0, 0);\n                sectionSeparator.add(new JLabel(\"]\"), c); // NOI18N\n\n                c = new GridBagConstraints();\n                c.gridx = 4;\n                c.gridy = 0;\n                c.weightx = 1d;\n                c.fill = GridBagConstraints.HORIZONTAL;\n                c.insets = new Insets(1, 4, 0, 0);\n                sectionSeparator.add(new SeparatorLine(), c);\n\n                add(sectionSeparator, BorderLayout.NORTH);\n\n                JComponent comp = createComponent();\n\n                if (comp instanceof ProfilerTable) table = (ProfilerTable)comp;\n                if (comp != null) add(comp, BorderLayout.CENTER);\n            }\n\n            public Dimension getMinimumSize() {\n                Dimension dim = super.getMinimumSize();\n                dim.width = 0;\n                return dim;\n            }\n\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.width = 100;\n                return dim;\n            }\n\n            protected JComponent createComponent() {\n                TableModel model = new DefaultTableModel(PREVIEW_ITEMS, 1) {\n                    { setValueAt(Bundle.TruffleObjectsSection_ComputingProgress(), 0, 0); }\n                    public boolean isCellEditable(int row, int column) { return false; }\n                };\n\n                ProfilerRenderer renderer = new LabelRenderer() {\n                    public void setValue(Object o, int i) {\n                        super.setValue(o, i);\n                        setIcon(o == null || o.toString().isEmpty() ? null : Icons.getIcon(HeapWalkerIcons.PROGRESS));\n                    }\n                };\n\n                ProfilerTable t = createTable(model);\n                t.setDefaultRenderer(Object.class, renderer);\n\n                return t;\n            }\n\n            void setRealModel(TableModel model) {\n                if (table == null) {\n                    BorderLayout bl = (BorderLayout)getLayout();\n                    Component c = bl.getLayoutComponent(BorderLayout.CENTER);\n                    if (c != null) remove(c);\n\n                    table = createTable(model);\n                    add(table, BorderLayout.CENTER);\n\n                    Container parent = getParent();\n                    if (parent != null) {\n                        parent.invalidate();\n                        parent.revalidate();\n                        parent.repaint();\n                    }\n                } else {\n                    table.setModel(model);\n                }\n\n                setupTable(table);\n                enableTableEvents(table);\n\n                link.setEnabled(true);\n            }\n\n            protected void setupTable(ProfilerTable table) {}\n\n            protected ProfilerTable createTable(TableModel model) {\n                ProfilerTable t = new SummaryView.SimpleTable(model, 0) {\n                    protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                        if (!(value instanceof HeapViewerNode)) return;\n                        \n                        requestFocusInWindow(); // TODO: should be done by ProfilerTable on selectRow(...) in processMouseEvent(...)\n\n                        HeapViewerNode node = (HeapViewerNode)value;\n                        HeapViewerNodeAction.Actions nodeActions = HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions);\n                        nodeActions.populatePopup(popup);\n\n                        if (popup.getComponentCount() > 0) popup.addSeparator();\n                        popup.add(createCopyMenuItem());\n                    }\n                    public void performDefaultAction(ActionEvent e) {\n                        if (!getRowSelectionAllowed()) return;\n                        \n                        int row = getSelectedRow();\n                        if (row == -1) return;\n\n                        Object value = getValueForRow(row);\n                        if (!(value instanceof HeapViewerNode)) return;\n\n                        HeapViewerNodeAction.Actions nodeActions =\n                                HeapViewerNodeAction.Actions.forNode((HeapViewerNode)value, actionProviders, context, actions);\n                        nodeActions.performDefaultAction(e);\n                    }\n                    protected void popupShowing() {\n                        keepSelection = true;\n                    }\n                    protected void popupHidden() {\n                        keepSelection = false;\n\n                        new Timer(100, new ActionListener() {\n                            @Override\n                            public void actionPerformed(ActionEvent e) {\n                                if (!isFocusOwner()) clearSelection();\n                            }\n                        }) { { setRepeats(false); } }.start();\n                    }\n                };\n                \n                return t;\n            }\n            \n            private void enableTableEvents(ProfilerTable t) {\n                t.setRowSelectionAllowed(true);\n                t.addFocusListener(new FocusAdapter() {\n                    public void focusLost(FocusEvent e) {\n                        if (!keepSelection) t.clearSelection();\n                        else keepSelection = false;\n                    }\n                });\n                t.providePopupMenu(true);\n                t.setSelectionOnMiddlePress(true);\n                t.addMouseListener(new MouseAdapter() {\n                    public void mouseClicked(MouseEvent e) {\n                        if (SwingUtilities.isMiddleMouseButton(e)) {\n                            int row = t.getSelectedRow();\n                            if (row == -1) return;\n\n                            Object value = t.getValueForRow(row);\n                            if (!(value instanceof HeapViewerNode)) return;\n\n                            HeapViewerNode node = (HeapViewerNode)value;\n                            HeapViewerNodeAction.Actions nodeActions = HeapViewerNodeAction.Actions.forNode(node, actionProviders, context, actions);\n                            ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), \"middle button\", e.getWhen(), e.getModifiers()); // NOI18N\n                            nodeActions.performMiddleButtonAction(ae);\n                        }\n                    }\n                });\n            }\n\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/heapviewer.truffle/src/org/graalvm/visualvm/heapviewer/truffle/ui/TruffleThreadsView.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.heapviewer.truffle.ui;\n\nimport java.awt.CardLayout;\nimport java.awt.event.ItemEvent;\nimport java.net.URL;\nimport java.util.List;\nimport javax.swing.ButtonGroup;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.SortOrder;\nimport org.graalvm.visualvm.heapviewer.HeapContext;\nimport org.graalvm.visualvm.heapviewer.model.DataType;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNode;\nimport org.graalvm.visualvm.heapviewer.model.HeapViewerNodeFilter;\nimport org.graalvm.visualvm.heapviewer.model.Progress;\nimport org.graalvm.visualvm.heapviewer.model.RootNode;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleLanguage;\nimport org.graalvm.visualvm.heapviewer.truffle.TruffleThreadsProvider;\nimport org.graalvm.visualvm.heapviewer.ui.HTMLView;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerActions;\nimport org.graalvm.visualvm.heapviewer.ui.HeapViewerFeature;\nimport org.graalvm.visualvm.heapviewer.ui.PluggableTreeTableView;\nimport org.graalvm.visualvm.heapviewer.ui.TreeTableViewColumn;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"TruffleThreadsView_Name=Threads\",\n    \"TruffleThreadsView_Description=Threads\",\n    \"TruffleThreadsView_ComputingThreads=computing threads...\",\n    \"TruffleThreadsView_Results=Results:\",\n    \"TruffleThreadsView_ViewObjects=Objects\",\n    \"TruffleThreadsView_ViewHtml=HTML\",\n    \"TruffleThreadsView_Details=Details:\"\n})\npublic class TruffleThreadsView extends HeapViewerFeature {\n    \n    private static final String FEATURE_ID = \"threads\"; // NOI18N\n    \n    private static final String OBJECTS_ID = \"_objects\"; // NOI18N\n    private static final String HTML_ID = \"_html\"; // NOI18N\n    \n    private JComponent component;\n    private ProfilerToolbar toolbar;\n    private ProfilerToolbar pluginsToolbar;\n    \n    private final HTMLView htmlView;\n    private final PluggableTreeTableView objectsView;\n    \n    \n    public TruffleThreadsView(TruffleLanguage language, HeapContext context, HeapViewerActions actions) {\n        super(idFromLanguage(language), Bundle.TruffleThreadsView_Name(), Bundle.TruffleThreadsView_Description(), iconFromLanguage(language), 300);\n        \n        Heap heap = context.getFragment().getHeap();\n        \n        final TruffleThreadsProvider<?,?,?,?> threadsProvider = new TruffleThreadsProvider<>(language);\n        \n        objectsView = new PluggableTreeTableView(getID() + OBJECTS_ID, context, actions, TreeTableViewColumn.instances(heap, false)) {\n            @Override\n            protected HeapViewerNode[] computeData(RootNode root, Heap heap, String viewID, HeapViewerNodeFilter viewFilter, List<DataType> dataTypes, List<SortOrder> sortOrders, Progress progress) throws InterruptedException {\n                return threadsProvider.getThreadsObjects(root, heap, viewID, viewFilter, dataTypes, sortOrders, progress);\n            }\n            protected void childrenChanged() {\n                CCTNode[] children = getRoot().getChildren();\n                for (CCTNode child : children) expandNode((HeapViewerNode)child);\n            }\n        };\n        objectsView.setViewName(getName());\n        \n        htmlView = new HTMLView(getID() + HTML_ID, context, actions, \"<br>&nbsp;&nbsp;\" + Bundle.TruffleThreadsView_ComputingThreads()) { // NOI18N\n            protected String computeData(HeapContext context, String viewID) {\n                return threadsProvider.getThreadsHTML(context);\n            }\n            protected HeapViewerNode nodeForURL(URL url, HeapContext context) {\n                return threadsProvider.getNodeForURL(url, context);\n            }\n        };\n    }\n    \n    \n    static String idFromLanguage(TruffleLanguage<?,?,?> language) {\n        return language.getID() + \"_\" + FEATURE_ID; // NOI18N\n    }\n    \n    static Icon iconFromLanguage(TruffleLanguage<?,?,?> language) {\n        return language.createLanguageIcon(Icons.getIcon(ProfilerIcons.WINDOW_THREADS));\n    }\n    \n\n    public JComponent getComponent() {\n        if (component == null) init();\n        return component;\n    }\n\n    public ProfilerToolbar getToolbar() {\n        if (toolbar == null) init();\n        return toolbar;\n    }\n    \n    \n    private void init() {\n        toolbar = ProfilerToolbar.create(false);\n        \n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n        \n        toolbar.add(new GrayLabel(Bundle.TruffleThreadsView_Results()));\n        toolbar.addSpace(3);\n        \n        ButtonGroup resultsBG = new ButtonGroup();\n        \n        JToggleButton rObjects = new JToggleButton(Icons.getIcon(ProfilerIcons.TAB_HOTSPOTS), true) {\n            protected void fireItemStateChanged(ItemEvent e) {\n                if (e.getStateChange() == ItemEvent.SELECTED) {\n                    if (component != null) ((CardLayout)component.getLayout()).first(component);\n                    if (pluginsToolbar != null) pluginsToolbar.getComponent().setVisible(true);\n                }\n            }\n        };\n        rObjects.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        rObjects.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        rObjects.setToolTipText(Bundle.TruffleThreadsView_ViewObjects());\n        resultsBG.add(rObjects);\n        toolbar.add(rObjects);\n        \n        JToggleButton rHTML = new JToggleButton(Icons.getIcon(HeapWalkerIcons.PROPERTIES)) {\n            protected void fireItemStateChanged(ItemEvent e) {\n                if (e.getStateChange() == ItemEvent.SELECTED) {\n                    if (component != null) ((CardLayout)component.getLayout()).last(component);\n                    if (pluginsToolbar != null) pluginsToolbar.getComponent().setVisible(false);\n                }\n            }\n        };\n        rHTML.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        rHTML.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n        rHTML.setToolTipText(Bundle.TruffleThreadsView_ViewHtml());\n        resultsBG.add(rHTML);\n        toolbar.add(rHTML);\n\n        if (objectsView.hasPlugins()) {\n            pluginsToolbar = ProfilerToolbar.create(false);\n//            detailsToolbar.addSpace(2);\n//            detailsToolbar.addSeparator();\n            pluginsToolbar.addSpace(8);\n\n            pluginsToolbar.add(new GrayLabel(Bundle.TruffleThreadsView_Details()));\n            pluginsToolbar.addSpace(2);\n            \n            pluginsToolbar.add(objectsView.getToolbar());\n            \n            toolbar.add(pluginsToolbar);\n        }\n        \n        component = new JPanel(new CardLayout());\n        component.add(objectsView.getComponent());\n        component.add(htmlView.getComponent());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/host/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.host\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.host.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/host/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.host/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/host/resources/layer.xml\nOpenIDE-Module-Install: org/graalvm/visualvm/host/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/host/Bundle.properties\nOpenIDE-Module-Recommends: org.graalvm.visualvm.jvm\nOpenIDE-Module-Specification-Version: 2.1\n\n"
  },
  {
    "path": "visualvm/host/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.host-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/host/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=5108f9bf\nbuild.xml.script.CRC32=ec09540f\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=5108f9bf\nnbproject/build-impl.xml.script.CRC32=31d6b952\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/host/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/host/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.host</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.11.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.18.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.host</package>\n                <package>org.graalvm.visualvm.host.model</package>\n                <package>org.graalvm.visualvm.host.overview</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/host/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/AddRemoteHostAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.host;\n\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport org.graalvm.visualvm.host.impl.HostCustomizer;\nimport org.graalvm.visualvm.host.impl.HostProperties;\nimport java.awt.Image;\nimport java.awt.event.ActionEvent;\nimport java.util.Set;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n    \n/**\n *\n * @author Jiri Sedlacek\n */\nclass AddRemoteHostAction extends SingleDataSourceAction<RemoteHostsContainer> {\n    \n    private static final String ICON_PATH = \"org/graalvm/visualvm/host/resources/addRemoteHost.png\";  // NOI18N\n    private static final Image ICON =  ImageUtilities.loadImage(ICON_PATH);\n    \n    private boolean tracksSelection = false;\n    \n    private static AddRemoteHostAction alwaysEnabled;\n    private static AddRemoteHostAction selectionAware;\n    \n    \n    public static synchronized AddRemoteHostAction alwaysEnabled() {\n        if (alwaysEnabled == null) {\n            alwaysEnabled = new AddRemoteHostAction();\n            alwaysEnabled.putValue(SMALL_ICON, new ImageIcon(ICON));\n            alwaysEnabled.putValue(\"iconBase\", ICON_PATH);  // NOI18N\n        }\n        return alwaysEnabled;\n    }\n    \n    public static synchronized AddRemoteHostAction selectionAware() {\n        if (selectionAware == null) {\n            selectionAware = new AddRemoteHostAction();\n            selectionAware.tracksSelection = true;\n        }\n        return selectionAware;\n    }\n    \n    \n    protected void actionPerformed(RemoteHostsContainer remoteHostsContainer, ActionEvent actionEvent) {\n        final HostProperties hostDescriptor = HostCustomizer.defineHost();\n        if (hostDescriptor != null) {\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    HostsSupport.getInstance().createHost(hostDescriptor, true, true);\n                }\n            });\n        }\n    }\n    \n    protected boolean isEnabled(RemoteHostsContainer remoteHostsContainer) {\n        return true;\n    }\n    \n    protected void updateState(Set<RemoteHostsContainer> remoteHostsContainerSet) {\n        if (tracksSelection) super.updateState(remoteHostsContainerSet);\n    }\n    \n    \n    private AddRemoteHostAction() {\n        super(RemoteHostsContainer.class);\n        putValue(NAME, NbBundle.getMessage(AddRemoteHostAction.class, \"LBL_Add_Remote_Host\"));  // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(AddRemoteHostAction.class, \"ToolTip_Add_Remote_Host\")); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Host\n\nLBL_Local=Local\n\nLBL_Remote=Remote\n\nLBL_Unknown_Host=<Unknown Host>\n\nLBL_Unknown=<Unknown>\n\nLBL_Add_Remote_Host=Add Remote &Host...\n\nToolTip_Add_Remote_Host=Add Remote Host\n\nDESCR_Local=Local system.\nDESCR_Remote=Remote host.\nDESCR_Unknown=Container for applications running on an unknown host.\n\nACT_SortHosts=Sort &Hosts By\nACT_TimeAdded=&Time Added\nACT_DisplayName=&Display Name\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/Host.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host;\n\nimport java.net.InetAddress;\nimport java.net.UnknownHostException;\nimport org.graalvm.visualvm.core.datasource.StatefulDataSource;\n\n/**\n * Abstract implementation of Host.\n * Each host is defined by a hostname/ip if resolvable or hostname/ip and InetAddress.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class Host extends StatefulDataSource {\n    \n    /**\n     * Instance representing the localhost.\n     */\n    public static final Host LOCALHOST = HostsSupport.getInstance().createLocalHost();\n    \n    /**\n     * Instance representing an unknown host (placeholder node in Applications window, hidden if not used).\n     */\n    public static final Host UNKNOWN_HOST = HostsSupport.getInstance().createUnknownHost();\n\n    private final String hostName;\n    private InetAddress inetAddress;\n\n\n    /**\n     * Creates new instance of Host defined by hostName.\n     * \n     * @param hostName name or IP of the host.\n     * @throws java.net.UnknownHostException if host cannot be resolved using provided hostName/IP.\n     */\n    public Host(String hostName) throws UnknownHostException {\n        this(hostName, InetAddress.getByName(hostName));\n    }\n\n    /**\n     * Creates new instance of Host defined by hostName and InetAddress instance for the host.\n     * \n     * @param hostName name or IP of the host,\n     * @param inetAddress InetAddress instance for the host.\n     */\n    public Host(String hostName, InetAddress inetAddress) {\n        if (hostName == null) throw new IllegalArgumentException(\"Host name cannot be null\");   // NOI18N\n        if (inetAddress == null) throw new IllegalArgumentException(\"InetAddress cannot be null\");  // NOI18N\n        \n        this.hostName = hostName;\n        this.inetAddress = inetAddress;\n    }\n    \n    \n    /**\n     * Returns hostname of the host.\n     * \n     * @return hostname of the host.\n     */\n    public String getHostName() {\n        return hostName;\n    }\n    \n    /**\n     * Returns InetAddress instance of the host.\n     * \n     * @return InetAddress instance of the host.\n     */\n    public final InetAddress getInetAddress() {\n        return inetAddress;\n    }\n    \n    public int hashCode() {\n        if (Host.UNKNOWN_HOST == this) return super.hashCode();\n        InetAddress address = getInetAddress();\n        if (this == LOCALHOST) return address.hashCode();\n        if (address.isLoopbackAddress()) return LOCALHOST.hashCode();\n        else return address.hashCode();\n    }\n\n    public boolean equals(Object obj) {\n        if (!(obj instanceof Host)) return false;\n        if (Host.UNKNOWN_HOST == this) return obj == this;\n        Host host = (Host)obj;\n        InetAddress thisAddress = getInetAddress();\n        InetAddress otherAddress = host.getInetAddress();\n        if (thisAddress.isLoopbackAddress() && otherAddress.isLoopbackAddress()) return true;\n        return thisAddress.equals(otherAddress);\n    }\n\n    public String toString() {\n        return getHostName() + \" [IP: \" + getInetAddress().getHostAddress() + \"]\";  // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/HostsSorting.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport java.awt.Component;\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.prefs.Preferences;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JRadioButtonMenuItem;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.actions.Presenter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class HostsSorting implements Presenter.Menu {\n\n    private static final String PROP_HOSTS_SORTING = \"Hosts.sorting\"; // NOI18N\n\n    private static HostsSorting instance;\n    \n    private static final Comparator<DataSource> BY_TIME_COMPARATOR = byTimeComparator();\n    private static final Comparator<DataSource> BY_NAME_COMPARATOR = byNameComparator();\n    private static final List<Comparator<DataSource>> COMPARATORS = new ArrayList<>();\n    static { COMPARATORS.add(BY_TIME_COMPARATOR); COMPARATORS.add(BY_NAME_COMPARATOR); }\n\n    private final Preferences prefs;\n\n    private JMenuItem presenter;\n    private final Sorter sorter;\n\n\n    public static synchronized HostsSorting instance() {\n        if (instance == null) instance = new HostsSorting();\n        return instance;\n    }\n\n    public JMenuItem getMenuPresenter() {\n        if (presenter == null) presenter = createPresenter();\n        return presenter;\n    }\n\n\n    Comparator<DataSource> getInitialSorting() {\n        return COMPARATORS.get(prefs.getInt(PROP_HOSTS_SORTING, COMPARATORS.\n                                            indexOf(BY_TIME_COMPARATOR)));\n    }\n\n\n    private JMenuItem createPresenter() {\n        final JMenu menu = new JMenu() {\n            protected void fireMenuSelected() {\n                Component[] items = getMenuComponents();\n                for (Component item : items)\n                    if (item instanceof SortAction)\n                        ((SortAction)item).updateAction();\n            }\n        };\n        Mnemonics.setLocalizedText(menu, NbBundle.getMessage(HostsSorting.class,\n                                   \"ACT_SortHosts\")); // NOI18N\n\n        menu.add(new SortAction(NbBundle.getMessage(HostsSorting.class,\n                                \"ACT_TimeAdded\"), BY_TIME_COMPARATOR, sorter)); // NOI18N\n        menu.add(new SortAction(NbBundle.getMessage(HostsSorting.class,\n                                \"ACT_DisplayName\"), BY_NAME_COMPARATOR, sorter)); // NOI18N\n\n        return menu;\n    }\n    \n    private static Comparator<DataSource> byTimeComparator() {\n        return null;\n    }\n\n    private static Comparator<DataSource> byNameComparator() {\n        return new Comparator<DataSource>() {\n            public int compare(DataSource d1, DataSource d2) {\n                if (d1 == Host.UNKNOWN_HOST) return -1;\n                if (d2 == Host.UNKNOWN_HOST) return 1;\n\n                DataSourceDescriptor dd1 = DataSourceDescriptorFactory.getDescriptor(d1);\n                DataSourceDescriptor dd2 = DataSourceDescriptorFactory.getDescriptor(d2);\n\n                return dd1.getName().compareTo(dd2.getName());\n            }\n        };\n    }\n\n    private HostsSorting() {\n        prefs = NbPreferences.forModule(HostsSorting.class);\n\n        sorter = new Sorter() {\n            public void sort(Comparator<DataSource> comparator) {\n                DataSourceDescriptor d = DataSourceDescriptorFactory.getDescriptor(\n                                         RemoteHostsContainer.sharedInstance());\n                if (d instanceof RemoteHostsContainerDescriptor) {\n                    ((RemoteHostsContainerDescriptor)d).setChildrenComparator(comparator);\n                    prefs.putInt(PROP_HOSTS_SORTING, COMPARATORS.indexOf(comparator));\n                }\n            }\n        };\n    }\n\n\n    private static class SortAction extends JRadioButtonMenuItem {\n\n        private final Sorter sorter;\n        private final Comparator<DataSource> comparator;\n        private boolean currentlySelected;\n\n        SortAction(String name, Comparator<DataSource> comparator, Sorter sorter) {\n            Mnemonics.setLocalizedText(this, name);\n            this.comparator = comparator;\n            this.sorter = sorter;\n        }\n\n        void updateAction() {\n            DataSourceDescriptor d = DataSourceDescriptorFactory.getDescriptor(\n                                     RemoteHostsContainer.sharedInstance());\n            setEnabled(d instanceof RemoteHostsContainerDescriptor);\n            currentlySelected = d.getChildrenComparator() == comparator;\n            setSelected(currentlySelected);\n        }\n\n        protected void fireActionPerformed(ActionEvent e) {\n            if (!currentlySelected) sorter.sort(comparator);\n        }\n\n    }\n\n    private static interface Sorter {\n\n        void sort(Comparator<DataSource> comparator);\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/HostsSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.host.impl.HostDescriptorProvider;\nimport org.graalvm.visualvm.host.impl.HostProperties;\nimport org.graalvm.visualvm.host.impl.HostProvider;\nimport org.graalvm.visualvm.host.impl.HostsSupportImpl;\nimport java.io.File;\nimport java.net.InetAddress;\n\n/**\n * Support for hosts in VisualVM.\n *\n * @author Jiri Sedlacek\n */\npublic final class HostsSupport {\n    \n    private static final Object hostsStorageDirectoryLock = new Object();\n    // @GuardedBy hostsStorageDirectoryLock\n    private static File hostsStorageDirectory;\n    \n    private static HostsSupport instance;\n\n    private final HostProvider hostProvider = new HostProvider();\n\n\n    /**\n     * Returns singleton instance of HostsSupport.\n     * \n     * @return singleton instance of HostsSupport.\n     */\n    public static synchronized HostsSupport getInstance() {\n        if (instance == null) instance = new HostsSupport();\n        return instance;\n    }\n    \n\n    /**\n     * Creates new host from provided hostname. Displays a popup dialog if wrong\n     * hostname is provided or the host has already been defined.\n     * \n     * @param hostname hostname of the host to be created.\n     * @return new host from provided hostname or null if the hostname could not be resolved.\n     */\n    public Host createHost(String hostname) {\n        return createHost(new HostProperties(hostname, hostname, null), true, true);\n    }\n    \n    /**\n     * Creates new host from provided hostname and display name. Displays a popup\n     * dialog if wrong hostname is provided or the host has already been defined.\n     * \n     * @param hostname hostname of the host to be created.\n     * @param displayname displayname of the host to be created.\n     * @return new host from provided hostname or null if the hostname could not be resolved.\n     */\n    public Host createHost(String hostname, String displayname) {\n        return createHost(new HostProperties(hostname, displayname, null), true, true);\n    }\n\n    /**\n     * Returns an existing Host instance or creates a new Host if needed.\n     *\n     * @param hostname hostname of the host to be created\n     * @param interactive true if any failure should be visually presented to the user, false otherwise.\n     * @return an existing or a newly created Host\n     */\n    public Host getOrCreateHost(String hostname, boolean interactive) {\n        return createHost(new HostProperties(hostname, hostname, null), false, interactive);\n    }\n\n    Host createHost(HostProperties properties, boolean createOnly, boolean interactive) {\n        return hostProvider.createHost(properties, createOnly, interactive);\n    }\n    \n    /**\n     * Returns already known Host instance with the same InetAddress or null.\n     * \n     * @param inetAddress InetAddress to search.\n     * @return already known Host instance with the same InetAddress or null.\n     */\n    public Host getHostByAddress(InetAddress inetAddress) {\n        return hostProvider.getHostByAddress(inetAddress);\n    }\n    \n    /**\n     * Returns storage directory for defined hosts.\n     * \n     * @return storage directory for defined hosts.\n     */\n    public static File getStorageDirectory() {\n        synchronized(hostsStorageDirectoryLock) {\n            if (hostsStorageDirectory == null) {\n                String snapshotsStorageString = HostsSupportImpl.getStorageDirectoryString();\n                hostsStorageDirectory = new File(snapshotsStorageString);\n                if (hostsStorageDirectory.exists() && hostsStorageDirectory.isFile())\n                    throw new IllegalStateException(\"Cannot create hosts storage directory \" + snapshotsStorageString + \", file in the way\");   // NOI18N\n                if (hostsStorageDirectory.exists() && (!hostsStorageDirectory.canRead() || !hostsStorageDirectory.canWrite()))\n                    throw new IllegalStateException(\"Cannot access hosts storage directory \" + snapshotsStorageString + \", read&write permission required\");    // NOI18N\n                if (!Utils.prepareDirectory(hostsStorageDirectory))\n                    throw new IllegalStateException(\"Cannot create hosts storage directory \" + snapshotsStorageString); // NOI18N\n            }\n            return hostsStorageDirectory;\n        }\n    }\n    \n    /**\n     * Returns true if the storage directory for defined hosts already exists, false otherwise.\n     * \n     * @return true if the storage directory for defined hosts already exists, false otherwise.\n     */\n    public static boolean storageDirectoryExists() {\n        return new File(HostsSupportImpl.getStorageDirectoryString()).isDirectory();\n    }\n    \n    \n    Host createLocalHost() {\n        return hostProvider.createLocalHost();\n    }\n    \n    Host createUnknownHost() {\n        return hostProvider.createUnknownHost();\n    }\n\n\n    private HostsSupport() {\n        DataSourceDescriptorFactory.getDefault().registerProvider(new HostDescriptorProvider());\n        \n        RemoteHostsContainer container = RemoteHostsContainer.sharedInstance();\n        DataSource.ROOT.getRepository().addDataSource(container);\n        \n        hostProvider.initialize();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.host;\n\nimport org.graalvm.visualvm.core.properties.PropertiesSupport;\nimport org.graalvm.visualvm.host.impl.GeneralPropertiesProvider;\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\nclass Installer extends ModuleInstall {\n\n    public void restored() {\n        HostsSupport.getInstance();\n        PropertiesSupport.sharedInstance().registerPropertiesProvider(\n                new GeneralPropertiesProvider(), Host.class);\n    }\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/LocalHostDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.host;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport java.awt.Image;\nimport java.util.Comparator;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * DataSourceDescriptor for Host.LOCALHOST.\n * \n * @author Jiri Sedlacek\n */\npublic class LocalHostDescriptor extends DataSourceDescriptor<Host> {\n\n    private static final Image NODE_ICON = ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/host/resources/localHost.png\", true);    // NOI18N\n\n    /**\n     * Creates new instance of LocalHostDescriptor.\n     */\n    public LocalHostDescriptor() {\n        super(Host.LOCALHOST, NbBundle.getMessage(LocalHostDescriptor.class, \"LBL_Local\"),\n              NbBundle.getMessage(LocalHostDescriptor.class, \"DESCR_Local\"), NODE_ICON, 0,\n              EXPAND_ON_FIRST_CHILD);  // NOI18N\n    }\n\n    \n    /**\n     * Sets a custom comparator for sorting DataSources within the Host.LOCALHOST.\n     * Use setChildrenComparator(null) to restore the default sorting.\n     *\n     * @param newComparator comparator for sorting DataSources within the Host.LOCALHOST\n     */\n    public void setChildrenComparator(Comparator<DataSource> newComparator) {\n        super.setChildrenComparator(newComparator);\n    }\n\n    public Comparator<DataSource> getChildrenComparator() {\n        return super.getChildrenComparator();\n    }\n\n    public boolean providesProperties() {\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/RemoteHostDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.host;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport java.awt.Image;\nimport java.util.Comparator;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * DataSourceDescriptor for remote hosts.\n *\n * @author Jiri Sedlacek\n */\npublic class RemoteHostDescriptor extends DataSourceDescriptor<Host> {\n\n    private static final Image NODE_ICON = ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/host/resources/remoteHost.png\", true);   // NOI18N\n\n    /**\n     * Creates new instance of RemoteHostDescriptor for a given host.\n     * \n     * @param host Host for which to create the descriptor.\n     */\n    public RemoteHostDescriptor(Host host) {\n        super(host, resolveName(host, host.getHostName()), NbBundle.getMessage(\n              RemoteHostDescriptor.class, \"DESCR_Remote\"), NODE_ICON, // NOI18N\n              resolvePosition(host, POSITION_AT_THE_END, true), EXPAND_ON_EACH_FIRST_CHILD);\n\n        setChildrenComparator(DataSourceDescriptorFactory.getDescriptor(\n                              Host.LOCALHOST).getChildrenComparator());\n    }\n\n\n    /**\n     * Sets a custom comparator for sorting DataSources within a Host.\n     * Use setChildrenComparator(null) to restore the default sorting.\n     *\n     * @param newComparator comparator for sorting DataSources within a Host\n     */\n    public void setChildrenComparator(Comparator<DataSource> newComparator) {\n        super.setChildrenComparator(newComparator);\n    }\n\n    public boolean supportsRename() {\n        return true;\n    }\n\n    public boolean providesProperties() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/RemoteHostsContainer.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.host;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\n/**\n * Toplevel node Remote in Applications window.\n *\n * @author Jiri Sedlacek\n */\npublic final class RemoteHostsContainer extends DataSource {\n\n    private static RemoteHostsContainer sharedInstance;\n\n    /**\n     * Returns singleton instance of RemoteHostsContainer.\n     *\n     * @return singleton instance of RemoteHostsContainer.\n     */\n    public static synchronized RemoteHostsContainer sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new RemoteHostsContainer();\n        return sharedInstance;\n    }\n\n    \n    private RemoteHostsContainer() {\n        DataSourceDescriptorFactory.getDefault().registerProvider(\n            new AbstractModelProvider<DataSourceDescriptor,DataSource>() {\n                public DataSourceDescriptor createModelFor(DataSource ds) {\n                    if (RemoteHostsContainer.sharedInstance().equals(ds))\n                        return new RemoteHostsContainerDescriptor();\n                    else return null;\n                }\n            }\n        );\n    }\n\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/RemoteHostsContainerDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.host;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport java.awt.Image;\nimport java.util.Comparator;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * DataSourceDescriptor for Remote node in Applications window.\n *\n * @author Jiri Sedlacek\n */\npublic final class RemoteHostsContainerDescriptor extends DataSourceDescriptor<RemoteHostsContainer> {\n\n    private static final Image NODE_ICON = ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/host/resources/remoteHosts.png\", true);  // NOI18N\n\n    RemoteHostsContainerDescriptor() {\n        super(RemoteHostsContainer.sharedInstance(), NbBundle.getMessage(\n              RemoteHostsContainerDescriptor.class, \"LBL_Remote\"), null, NODE_ICON, 10, // NOI18N\n              EXPAND_ON_EACH_NEW_CHILD);\n        \n        // Initialize sorting\n        setChildrenComparator(HostsSorting.instance().getInitialSorting());\n    }\n\n    /**\n     * Sets a custom comparator for sorting DataSources within the RemoteHostsContainer.\n     * Use setChildrenComparator(null) to restore the default sorting.\n     *\n     * @param newComparator comparator for sorting DataSources within the RemoteHostsContainer\n     */\n    public void setChildrenComparator(Comparator<DataSource> newComparator) {\n        super.setChildrenComparator(newComparator);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/UnknownHostDescriptor.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.host;\n\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport java.awt.Image;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * DataSourceDescriptor for Host.UNKNOWN_HOST.\n * \n * @author Jiri Sedlacek\n */\npublic class UnknownHostDescriptor extends DataSourceDescriptor {\n\n    private static final Image NODE_ICON = ImageUtilities.loadImage(\"org/graalvm/visualvm/host/resources/remoteHosts.png\", true);  // NOI18N\n\n    /**\n     * Creates new instance of UnknownHostDescriptor.\n     */\n    public UnknownHostDescriptor() {\n        super(Host.UNKNOWN_HOST, NbBundle.getMessage(UnknownHostDescriptor.class, \"LBL_Unknown_Host\"),\n              NbBundle.getMessage(UnknownHostDescriptor.class, \"DESCR_Unknown\"), NODE_ICON,\n              POSITION_LAST, EXPAND_ON_FIRST_CHILD);  // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/impl/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nTitle_Add_Remote_Host=Add Remote Host\n\nLBL_Host_name=&Host name\\:\n\nLBL_Display_name=&Display name\\:\n\nBTN_AdvancedSettings=&Advanced Settings\n\nLBL_OK=OK\n\nLBL_Searching_for_host=Searching for host \n\nMSG_Wrong_Host=<html><b>Cannot resolve host {0}</b><br><br>Make sure you have entered correct<br>host name or address.</html>\n\nMSG_Already_Monitored=<html>Host {0} already monitored as {1}</html>\n\nTitle_Unresolved_Hosts=Could Not Resolve Hosts\n\nMSG_Unresolved_Hosts=<html><b>These hosts could not be resolved:</b><br>Do you want to resolve them on next VisualVM session?<br><br></html>\n\nLBL_HostProperties=Host\nDESCR_HostProperties=Basic host information\nLBL_Resolving=resolving...\nLBL_DnsName=DNS name\\:\nLBL_IpAddress=IP address\\:\n\nLBL_RememberAction=&Remember selected action\nTTP_RememberAction=Select to perform the action automatically on subsequent sessions. Can be reset using {0} | General | Reset Do Not Show Again confirmations.\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/impl/GeneralPropertiesProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.impl;\n\nimport org.graalvm.visualvm.core.properties.PropertiesPanel;\nimport org.graalvm.visualvm.core.properties.PropertiesProvider;\nimport org.graalvm.visualvm.host.Host;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.net.InetAddress;\nimport javax.swing.BorderFactory;\nimport javax.swing.JTextArea;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class GeneralPropertiesProvider extends PropertiesProvider<Host> {\n\n    public GeneralPropertiesProvider() {\n        super(NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_HostProperties\"), // NOI18N\n              NbBundle.getMessage(GeneralPropertiesProvider.class, \"DESCR_HostProperties\"), // NOI18N\n              CATEGORY_GENERAL, 50);\n    }\n\n\n    public PropertiesPanel createPanel(final Host dataSource) {\n        PropertiesPanel panel = new PropertiesPanel();\n        panel.setLayout(new BorderLayout());\n        final JTextArea textArea = new JTextArea() {\n            public Dimension getMinimumSize() {\n                Dimension prefSize = getPreferredSize();\n                Dimension minSize = super.getMinimumSize();\n                prefSize.width = 0;\n                if (minSize.height < prefSize.height) return prefSize;\n                else return minSize;\n            }\n        };\n        textArea.setBorder(BorderFactory.createEmptyBorder());\n        textArea.setOpaque(false);\n        // Nimbus LaF doesn't respect setOpaque(false), this is a workaround.\n        // May cause delays for remote X sessions due to color transparency.\n        if (UIManager.getLookAndFeel().getID().equals(\"Nimbus\")) // NOI18N\n            textArea.setBackground(new Color(0, 0, 0, 0));\n        textArea.setEditable(false);\n        textArea.setLineWrap(true);\n        textArea.setWrapStyleWord(true);\n        String resolving = NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_Resolving\"); // NOI18N\n        updateProperties(textArea, resolving, resolving);\n        textArea.setMinimumSize(new Dimension(1, 1));\n        panel.add(textArea, BorderLayout.CENTER);\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                InetAddress address = dataSource.getInetAddress();\n                final String hostname = address.getCanonicalHostName();\n                final String ip = address.getHostAddress();\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        updateProperties(textArea, hostname, ip);\n                    }\n                });\n            }\n        });\n        return panel;\n    }\n\n    private static void updateProperties(JTextArea textArea, String hostname, String ip) {\n        String dnsName = NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_DnsName\"); // NOI18N\n        String ipAddress = NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_IpAddress\"); // NOI18N\n        textArea.setText(dnsName + \" \" + hostname + \"\\n\" + ipAddress + \" \" + ip); // NOI18N\n        textArea.setCaretPosition(0);\n    }\n\n\n    public boolean supportsDataSource(Host dataSource) { return dataSource != null; }\n\n    public void propertiesDefined(PropertiesPanel panel, Host dataSource) {}\n\n    public void propertiesChanged(PropertiesPanel panel, Host dataSource) {}\n\n    public void propertiesCancelled(PropertiesPanel panel, Host dataSource) {}\n\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/impl/HostCustomizer.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.impl;\n\nimport org.graalvm.visualvm.core.properties.PropertiesCustomizer;\nimport org.graalvm.visualvm.core.properties.PropertiesSupport;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.host.Host;\nimport java.awt.BorderLayout;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.Window;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTextField;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class HostCustomizer extends JPanel {\n\n  private static Dimension MIN_PROPERTIES_SIZE = new Dimension(400, 200);\n  private static Dimension MAX_PROPERTIES_SIZE = new Dimension(700, 400);\n\n  private boolean internalChange = false;\n\n  \n  public static HostProperties defineHost() {\n    HostCustomizer hc = getInstance();\n    hc.setup();\n\n    ScrollableContainer sc = new ScrollableContainer(hc,\n            ScrollableContainer.VERTICAL_SCROLLBAR_AS_NEEDED,\n            ScrollableContainer.HORIZONTAL_SCROLLBAR_NEVER);\n    sc.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));\n    sc.setViewportBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));\n    \n    final DialogDescriptor dd = new DialogDescriptor(sc, NbBundle.getMessage(\n            HostCustomizer.class, \"Title_Add_Remote_Host\"), true, new Object[] {   // NOI18N\n            hc.okButton, DialogDescriptor.CANCEL_OPTION }, hc.okButton, 0, null, null);\n    dd.setAdditionalOptions(new Object[] { hc.settingsButton });\n    final Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n    d.pack();\n    d.setVisible(true);\n\n    if (dd.getValue() == hc.okButton) {\n        HostProperties hp = new HostProperties(hc.getHostName(), hc.getDisplayName(),\n                                               hc.getPropertiesCustomizer());\n        hc.accepted();\n        return hp;\n    } else {\n        hc.cancelled();\n        return null;\n    }\n  }\n  \n  \n  private static HostCustomizer instance;\n  \n  private HostCustomizer() {\n    initComponents();\n    update();\n  }\n  \n  private static HostCustomizer getInstance() {\n    if (instance == null) instance = new HostCustomizer();\n    return instance;\n  }\n  \n  private String getHostName() {\n      return hostnameField.getText().trim();\n  }\n  \n  private String getDisplayName() {\n      return displaynameField.getText().trim();\n  }\n\n  private PropertiesCustomizer<Host> getPropertiesCustomizer() {\n      return settingsPanel;\n  }\n  \n  private void setup() {\n    hostnameField.setEnabled(true);\n    displaynameCheckbox.setSelected(false);\n    displaynameCheckbox.setEnabled(true);\n    hostnameField.setText(\"\"); // NOI18N\n    displaynameField.setText(\"\"); // NOI18N\n\n    PropertiesSupport support = PropertiesSupport.sharedInstance();\n    settingsPanel = !support.hasProperties(Host.class) ? null :\n                     support.getCustomizer(Host.class);\n    if (settingsPanel != null) settingsPanel.addChangeListener(listener);\n    settingsButton.setVisible(settingsPanel != null);\n    if (!settingsButton.isVisible()) settingsButton.setSelected(false);\n    else settingsButton.setSelected(!settingsPanel.settingsValid());\n\n    updateSettings();\n  }\n\n  private void accepted() {\n      cleanup();\n  }\n\n  private void cancelled() {\n      if (settingsPanel != null) settingsPanel.propertiesCancelled();\n      cleanup();\n  }\n\n  private void cleanup() {\n      if (settingsPanel != null) settingsPanel.removeChangeListener(listener);\n      settingsContainer.removeAll();\n      settingsPanel = null;\n  }\n  \n  private void update() {\n    if (internalChange) return;\n    SwingUtilities.invokeLater(new Runnable() {\n      public void run() {\n        String hostname = getHostName();\n        \n        if (!displaynameCheckbox.isSelected()) {\n          internalChange = true;\n          displaynameField.setText(hostname);\n          internalChange = false;\n        }\n        \n        String displayname = getDisplayName();\n        displaynameField.setEnabled(displaynameCheckbox.isSelected());\n\n        boolean hostValid = !hostname.isEmpty() && !displayname.isEmpty();\n        boolean settingsValid = settingsPanel == null || settingsPanel.settingsValid();\n        \n        okButton.setEnabled(hostValid && settingsValid);\n      }\n    });\n  }\n\n  private void updateSettings() {\n      SwingUtilities.invokeLater(new Runnable() {\n          public void run() {\n              if (settingsButton.isSelected()) {\n                  settingsContainer.add(settingsPanel, BorderLayout.CENTER);\n                  settingsContainer.setBorder(BorderFactory.\n                          createEmptyBorder(10, 0, 0, 0));\n\n                  Dimension prefSize = settingsPanel.getPreferredSize();\n//                  prefSize.width = Math.max(prefSize.width, MIN_PROPERTIES_SIZE.width);\n//                  prefSize.width = Math.min(prefSize.width, MAX_PROPERTIES_SIZE.width);\n                  prefSize.height = Math.max(prefSize.height, MIN_PROPERTIES_SIZE.height);\n                  prefSize.height = Math.min(prefSize.height, MAX_PROPERTIES_SIZE.height);\n                  settingsPanel.setPreferredSize(prefSize);\n\n              } else {\n                  settingsContainer.removeAll();\n                  settingsContainer.setBorder(BorderFactory.createEmptyBorder());\n              }\n              Window w = SwingUtilities.getWindowAncestor(HostCustomizer.this);\n              if (w != null) w.pack();\n              update();\n          }\n      });\n  }\n  \n  private void initComponents() {\n    setLayout(new GridBagLayout());\n    GridBagConstraints constraints;\n    \n    // hostnameLabel\n    hostnameLabel = new JLabel();\n    Mnemonics.setLocalizedText(hostnameLabel, NbBundle.getMessage(HostCustomizer.class, \"LBL_Host_name\")); // NOI18N\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 0;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.EAST;\n    constraints.insets = new Insets(5, 0, 0, 0);\n    add(hostnameLabel, constraints);\n    \n    // hostnameField\n    hostnameField = new JTextField();\n    hostnameLabel.setLabelFor(hostnameField);\n    hostnameField.setPreferredSize(new Dimension(250, hostnameField.getPreferredSize().height));\n    hostnameField.getDocument().addDocumentListener(new DocumentListener() {\n      public void insertUpdate(DocumentEvent e)  { update(); }\n      public void removeUpdate(DocumentEvent e)  { update(); }\n      public void changedUpdate(DocumentEvent e) { update(); }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 1;\n    constraints.gridy = 0;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.HORIZONTAL;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(5, 5, 0, 0);\n    add(hostnameField, constraints);\n    \n    // displaynameCheckbox\n    displaynameCheckbox = new JCheckBox();\n    Mnemonics.setLocalizedText(displaynameCheckbox, NbBundle.getMessage(HostCustomizer.class, \"LBL_Display_name\")); // NOI18N\n    displaynameCheckbox.addActionListener(new ActionListener() {\n      public void actionPerformed(ActionEvent e) { update(); }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 1;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.EAST;\n    constraints.insets = new Insets(8, 0, 5, 0);\n    add(displaynameCheckbox, constraints);\n    \n    // displaynameField\n    displaynameField = new JTextField();\n    displaynameField.setPreferredSize(new Dimension(250, displaynameField.getPreferredSize().height));\n    displaynameField.getDocument().addDocumentListener(new DocumentListener() {\n      public void insertUpdate(DocumentEvent e)  { update(); }\n      public void removeUpdate(DocumentEvent e)  { update(); }\n      public void changedUpdate(DocumentEvent e) { update(); }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 1;\n    constraints.gridy = 1;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.HORIZONTAL;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(8, 5, 5, 0);\n    add(displaynameField, constraints);\n    \n    // spacer\n    settingsContainer = new JPanel(new BorderLayout(0, 0));\n    settingsContainer.setOpaque(false);\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 2;\n    constraints.weightx = 1;\n    constraints.weighty = 1;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.BOTH;\n    constraints.anchor = GridBagConstraints.NORTHWEST;\n    constraints.insets = new Insets(0, 0, 0, 0);\n    add(settingsContainer, constraints);\n    \n    // okButton\n    okButton = new JButton();\n    Mnemonics.setLocalizedText(okButton, NbBundle.getMessage(\n            HostCustomizer.class, \"LBL_OK\")); // NOI18N\n\n    settingsButton = new JToggleButton() {\n        protected void fireActionPerformed(ActionEvent e) {\n            updateSettings();\n        }\n    };\n    Mnemonics.setLocalizedText(settingsButton, NbBundle.getMessage(\n            HostCustomizer.class, \"BTN_AdvancedSettings\")); // NOI18N\n    \n    // UI tweaks\n    displaynameCheckbox.setBorder(hostnameLabel.getBorder());\n  }\n  \n  private JLabel hostnameLabel;\n  private JTextField hostnameField;\n  private JCheckBox displaynameCheckbox;\n  private JTextField displaynameField;\n  private JPanel settingsContainer;\n\n  private PropertiesCustomizer<Host> settingsPanel;\n  \n  private JButton okButton;\n  private JToggleButton settingsButton;\n\n  private final ChangeListener listener = new ChangeListener() {\n                    public void stateChanged(ChangeEvent e) { update(); }\n                };\n  \n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/impl/HostDescriptorProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.impl;\n\nimport org.graalvm.visualvm.host.UnknownHostDescriptor;\nimport org.graalvm.visualvm.host.LocalHostDescriptor;\nimport org.graalvm.visualvm.host.RemoteHostDescriptor;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class HostDescriptorProvider extends AbstractModelProvider<DataSourceDescriptor,DataSource> {\n    \n    public DataSourceDescriptor createModelFor(DataSource ds) {\n        if (ds instanceof Host) {\n            Host host = (Host) ds;\n            if (Host.LOCALHOST.equals(ds)) {\n                return new LocalHostDescriptor();\n            }\n            if (Host.UNKNOWN_HOST.equals(ds)) {\n                return new UnknownHostDescriptor();\n            }\n            return new RemoteHostDescriptor(host);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/impl/HostProperties.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.impl;\n\nimport org.graalvm.visualvm.core.properties.PropertiesCustomizer;\nimport org.graalvm.visualvm.host.Host;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class HostProperties {\n\n    private final String hostName;\n    private final String displayName;\n    private final PropertiesCustomizer<Host> customizer;\n\n\n    public HostProperties(String hostName, String displayName,\n                          PropertiesCustomizer<Host> customizer) {\n        this.customizer = customizer;\n        this.hostName = hostName;\n        this.displayName = displayName;\n    }\n\n\n    public String getHostName() { return hostName; }\n\n    public String getDisplayName() { return displayName; }\n\n    public PropertiesCustomizer<Host> getPropertiesCustomizer() { return customizer; }\n\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/impl/HostProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.impl;\n\nimport org.graalvm.visualvm.host.HostsSupport;\nimport org.graalvm.visualvm.host.RemoteHostsContainer;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.DataSourceContainer;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.explorer.ExplorerSupport;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport java.awt.BorderLayout;\nimport java.io.File;\nimport java.io.FilenameFilter;\nimport java.net.InetAddress;\nimport java.net.UnknownHostException;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.concurrent.Semaphore;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.JCheckBox;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n// A provider for Hosts\npublic class HostProvider {\n    private static final Logger LOGGER = Logger.getLogger(HostProvider.class.getName());\n\n    private static final String SNAPSHOT_VERSION = \"snapshot_version\";  // NOI18N\n    private static final String SNAPSHOT_VERSION_DIVIDER = \".\";\n    private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = \"1\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MINOR = \"0\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION = CURRENT_SNAPSHOT_VERSION_MAJOR + SNAPSHOT_VERSION_DIVIDER + CURRENT_SNAPSHOT_VERSION_MINOR;\n\n    private static final String PROPERTY_HOSTNAME = \"prop_hostname\";    // NOI18N\n    \n    private static final String DNSA_KEY = \"HostProvider_NotifyUnresolved\"; // NOI18N\n\n    private static InetAddress localhostAddress2;\n\n\n    private Semaphore hostsLockedSemaphore = new Semaphore(1);\n\n\n    public Host createHost(final HostProperties hostDescriptor, final boolean createOnly, final boolean interactive) {\n        try {\n\n            lockHosts();\n\n            final String hostName = hostDescriptor.getHostName();\n            InetAddress inetAddress = null;\n            ProgressHandle pHandle = null;\n\n            try {\n                pHandle = ProgressHandle.createHandle(NbBundle.getMessage(HostProvider.class, \"LBL_Searching_for_host\") + hostName); // NOI18N\n                pHandle.setInitialDelay(0);\n                pHandle.start();\n                try {\n                    inetAddress = InetAddress.getByName(hostName);\n                } catch (UnknownHostException e) {\n                    if (interactive) {\n                        DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.\n                                Message(NbBundle.getMessage(HostProvider.class,\n                                \"MSG_Wrong_Host\", hostName), NotifyDescriptor. // NOI18N\n                                ERROR_MESSAGE));\n                    }\n                }\n            } finally {\n                final ProgressHandle pHandleF = pHandle;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { if (pHandleF != null) pHandleF.finish(); }\n                });\n            }\n\n            if (inetAddress != null) {\n                final Host knownHost = getHostByAddressImpl(inetAddress);\n                if (knownHost != null) {\n                    if (interactive && createOnly) {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                ExplorerSupport.sharedInstance().selectDataSource(knownHost);\n                                DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.\n                                Message(NbBundle.getMessage(HostProvider.class,\n                                        \"MSG_Already_Monitored\",new Object[] // NOI18N\n                                        {hostName,DataSourceDescriptorFactory.\n                                        getDescriptor(knownHost).getName()}),\n                                        NotifyDescriptor.WARNING_MESSAGE));\n                            }\n                        });\n                    }\n                    return knownHost;\n                } else {\n                    String ipString = inetAddress.getHostAddress();\n\n                    String[] propNames = new String[] {\n                        SNAPSHOT_VERSION,\n                        PROPERTY_HOSTNAME,\n                        DataSourceDescriptor.PROPERTY_NAME };\n                    String[] propValues = new String[] {\n                        CURRENT_SNAPSHOT_VERSION,\n                        hostName,\n                        hostDescriptor.getDisplayName() };\n\n                    File customPropertiesStorage = Utils.getUniqueFile(HostsSupport.getStorageDirectory(), ipString, Storage.DEFAULT_PROPERTIES_EXT);\n                    Storage storage = new Storage(customPropertiesStorage.getParentFile(), customPropertiesStorage.getName());\n                    storage.setCustomProperties(propNames, propValues);\n\n                    Host newHost = null;\n                    try {\n                        newHost = new RemoteHostImpl(hostName, storage);\n                    } catch (Exception e) {\n                        LOGGER.log(Level.SEVERE, \"Error creating host\", e); // Should never happen  // NOI18N\n                    }\n\n                    if (newHost != null) {\n                        DataSourceContainer remoteHosts = RemoteHostsContainer.sharedInstance().getRepository();\n                        Set<Host> remoteHostsSet = remoteHosts.getDataSources(Host.class);\n                        if (!createOnly && remoteHostsSet.contains(newHost)) {\n                            storage.deleteCustomPropertiesStorage();\n                            for (Host existingHost : remoteHostsSet) {\n                                if (existingHost.equals(newHost)) {\n                                    newHost = existingHost;\n                                    break;\n                                }\n                            }\n                        } else {\n                            if (hostDescriptor.getPropertiesCustomizer() != null)\n                                hostDescriptor.getPropertiesCustomizer().propertiesDefined(newHost);\n                            remoteHosts.addDataSource(newHost);\n                        }\n                    }\n                    return newHost;\n                }\n            }\n            return null;\n\n        } catch (InterruptedException ex) {\n            LOGGER.throwing(HostProvider.class.getName(), \"createHost\", ex);    // NOI18N\n            return null;\n        } finally {\n            unlockHosts();\n        }\n    }\n\n    void removeHost(RemoteHostImpl host, boolean interactive) {\n        try {\n            lockHosts();\n\n            // TODO: if interactive, show a Do-Not-Show-Again confirmation dialog\n            DataSource owner = host.getOwner();\n            if (owner != null) owner.getRepository().removeDataSource(host);\n\n        } catch (InterruptedException ex) {\n            LOGGER.throwing(HostProvider.class.getName(), \"removeHost\", ex);    // NOI18N\n        } finally {\n            unlockHosts();\n        }\n    }\n\n    public Host getHostByAddress(InetAddress inetAddress) {\n        try {\n            lockHosts();\n            return getHostByAddressImpl(inetAddress);\n        } catch (InterruptedException ex) {\n            LOGGER.throwing(HostProvider.class.getName(), \"getHostByAddress\", ex);    // NOI18N\n            return null;\n        } finally {\n            unlockHosts();\n        }\n    }\n\n    private Host getHostByAddressImpl(InetAddress inetAddress) {\n        Set<RemoteHostImpl> knownHosts = DataSourceRepository.sharedInstance().getDataSources(RemoteHostImpl.class);\n        for (RemoteHostImpl knownHost : knownHosts)\n            if (knownHost.getInetAddress().equals(inetAddress)) return knownHost;\n\n        if (inetAddress.equals(Host.LOCALHOST.getInetAddress())) return Host.LOCALHOST;\n        if (inetAddress.equals(localhostAddress2)) return Host.LOCALHOST;\n        if (inetAddress.isLoopbackAddress()) return Host.LOCALHOST;\n\n        return null;\n    }\n\n    public Host createLocalHost() {\n        try {\n            return new LocalHostImpl();\n        } catch (UnknownHostException e) {\n            LOGGER.severe(\"Critical failure: cannot resolve localhost\");    // NOI18N\n            return null;\n        }\n    }\n\n    public Host createUnknownHost() {\n        try {\n            return new Host(\"unknown\", InetAddress.getByAddress(new byte[] { 0, 0, 0, 0 })) {}; // NOI18N\n        } catch (UnknownHostException e) {\n            LOGGER.severe(\"Failure: cannot resolve <unknown> host\");    // NOI18N\n            return null;\n        }\n    }\n\n    private void initLocalHost() {\n        try {\n            localhostAddress2 = InetAddress.getLocalHost();\n        } catch (java.net.UnknownHostException e) {}\n\n        if (Host.LOCALHOST != null)\n            DataSource.ROOT.getRepository().addDataSource(Host.LOCALHOST);\n    }\n\n    private void initUnknownHost() {\n        final Host unknownhost = Host.UNKNOWN_HOST;\n        if (unknownhost != null) {\n            unknownhost.getRepository().addDataChangeListener(new DataChangeListener<DataSource>() {\n                public void dataChanged(DataChangeEvent<DataSource> event) {\n                    unknownhost.setVisible(!event.getCurrent().isEmpty());\n                }\n            }, DataSource.class);\n            RemoteHostsContainer.sharedInstance().getRepository().addDataSource(unknownhost);\n        }\n    }\n\n    private void initPersistedHosts() {\n        if (HostsSupport.storageDirectoryExists()) {\n            File storageDir = HostsSupport.getStorageDirectory();\n            File[] files = storageDir.listFiles(new FilenameFilter() {\n                public boolean accept(File dir, String name) {\n                    return name.endsWith(Storage.DEFAULT_PROPERTIES_EXT);\n                }\n            });\n\n            Set<File> unresolvedHostsF = new HashSet<>();\n            Set<String> unresolvedHostsS = new HashSet<>();\n\n            Set<RemoteHostImpl> hosts = new HashSet<>();\n            for (File file : files) {\n                if (HostsSupportImpl.LOCALHOST_PROPERTIES_FILENAME.equals(file.getName()))\n                    continue;\n\n                Storage storage = new Storage(storageDir, file.getName());\n                String hostName = storage.getCustomProperty(PROPERTY_HOSTNAME);\n\n                RemoteHostImpl persistedHost = null;\n                try {\n                    persistedHost = new RemoteHostImpl(hostName, storage);\n                } catch (Exception e) {\n                    LOGGER.throwing(HostProvider.class.getName(), \"initPersistedHosts\", e);    // NOI18N\n                    unresolvedHostsF.add(file);\n                    unresolvedHostsS.add(hostName);\n                }\n\n                if (persistedHost != null) hosts.add(persistedHost);\n            }\n\n            if (!unresolvedHostsF.isEmpty()) notifyUnresolvedHosts(unresolvedHostsF, unresolvedHostsS);\n\n            RemoteHostsContainer.sharedInstance().getRepository().addDataSources(hosts);\n        }\n    }\n\n    private static void notifyUnresolvedHosts(final Set<File> unresolvedHostsF, final Set<String> unresolvedHostsS) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                String s = GlobalPreferences.sharedInstance().getDoNotShowAgain(DNSA_KEY);\n                Boolean b = s == null ? null : Boolean.parseBoolean(s);\n                \n                if (b == null) {\n                    JPanel messagePanel = new JPanel(new BorderLayout(5, 5));\n                    messagePanel.add(new JLabel(NbBundle.getMessage(HostProvider.class, \"MSG_Unresolved_Hosts\")), BorderLayout.NORTH); // NOI18N\n                    JList<Object> list = new JList<>(unresolvedHostsS.toArray());\n                    list.setVisibleRowCount(4);\n                    messagePanel.add(new JScrollPane(list), BorderLayout.CENTER);\n                    JCheckBox dnsa = new JCheckBox();\n                    Mnemonics.setLocalizedText(dnsa, NbBundle.getMessage(HostProvider.class, \"LBL_RememberAction\")); // NOI18N\n                    dnsa.setToolTipText(NbBundle.getMessage(HostProvider.class, \"TTP_RememberAction\", VisualVM.getInstance().getOptionsHandle())); // NOI18N\n                    JPanel p = new JPanel(new BorderLayout());\n                    p.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 20));\n                    p.add(dnsa, BorderLayout.WEST);\n                    messagePanel.add(p, BorderLayout.SOUTH);\n                    NotifyDescriptor dd = new NotifyDescriptor(\n                            messagePanel, NbBundle.getMessage(HostProvider.class, \"Title_Unresolved_Hosts\"), // NOI18N\n                            NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.ERROR_MESSAGE,\n                            null, NotifyDescriptor.YES_OPTION);\n                    Object ret = DialogDisplayer.getDefault().notify(dd);\n                    \n                    if (ret == NotifyDescriptor.NO_OPTION) b = Boolean.FALSE;\n                    else if (ret == NotifyDescriptor.YES_OPTION) b = Boolean.TRUE;\n                    \n                    if (dnsa.isSelected() && b != null) GlobalPreferences.sharedInstance().setDoNotShowAgain(DNSA_KEY, b.toString());\n                }\n                \n                if (Boolean.FALSE.equals(b))\n                    for (File file : unresolvedHostsF) Utils.delete(file, true);\n\n                unresolvedHostsF.clear();\n                unresolvedHostsS.clear();\n            }\n        }, 1000);\n    }\n\n\n    private void lockHosts() throws InterruptedException {\n        hostsLockedSemaphore.acquire();\n    }\n\n    private void unlockHosts() {\n        DataSource.EVENT_QUEUE.post(new Runnable() {\n            public void run() {\n                hostsLockedSemaphore.release();\n            }\n        });\n    }\n\n\n    public void initialize() {\n        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n            public void run() {\n                VisualVM.getInstance().runTask(new Runnable() {\n                    public void run() {\n                        initLocalHost();\n                        initUnknownHost();\n                        initPersistedHosts();\n                        unlockHosts();\n                    }\n                });\n            }\n        });\n    }\n\n\n    public HostProvider() {\n        try {\n            lockHosts(); // Immediately lock the hosts, will be released after initialize()\n        } catch (InterruptedException ex) {\n            LOGGER.throwing(HostProvider.class.getName(), \"<init>\", ex);    // NOI18N\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/impl/HostsSupportImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.impl;\n\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport java.io.File;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class HostsSupportImpl {\n\n    public static final String LOCALHOST_PROPERTIES_FILENAME = \"localhost\" + Storage.DEFAULT_PROPERTIES_EXT; // NOI18N\n\n    private static final String HOSTS_STORAGE_DIRNAME = \"hosts\";    // NOI18N\n    private static final Object hostsStorageDirectoryStringLock = new Object();\n    // @GuardedBy hostsStorageDirectoryStringLock\n    private static String hostsStorageDirectoryString;\n\n\n    public static String getStorageDirectoryString() {\n        synchronized(hostsStorageDirectoryStringLock) {\n            if (hostsStorageDirectoryString == null)\n                hostsStorageDirectoryString = Storage.getPersistentStorageDirectoryString() +\n                        File.separator + HOSTS_STORAGE_DIRNAME;\n            return hostsStorageDirectoryString;\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/impl/LocalHostImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.impl;\n\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport java.io.File;\nimport java.net.UnknownHostException;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class LocalHostImpl extends Host {\n\n\n    LocalHostImpl() throws UnknownHostException {\n        super(\"localhost\"); // NOI18N\n    }\n    \n    \n    protected Storage createStorage() {\n        return new Storage(new File(HostsSupportImpl.getStorageDirectoryString()),\n                HostsSupportImpl.LOCALHOST_PROPERTIES_FILENAME);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/impl/Ping.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.impl;\n\nimport java.io.IOException;\nimport java.net.InetAddress;\nimport java.net.InetSocketAddress;\nimport java.nio.channels.SelectionKey;\nimport java.nio.channels.Selector;\nimport java.nio.channels.SocketChannel;\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class Ping {\n  \n  // The default daytime port\n  static int RMIREGISTRY_PORT = 1099;\n  \n  // The port we'll actually use\n  int port = RMIREGISTRY_PORT;\n  List<InetAddress> foundHosts;\n  \n  // Representation of a ping target\n  //\n  class Target {\n    \n    InetSocketAddress address;\n    SocketChannel channel;\n    boolean failure;\n    long connectStart;\n    long connectFinish = 0;\n    Boolean status;\n    \n    Target(InetAddress host,int port) {\n      address = new InetSocketAddress(host,port);\n    }\n    \n    private void done() {\n      status = Boolean.valueOf(connectFinish != 0);\n      if (status.booleanValue()) {\n        foundHosts.add(address.getAddress());\n      }\n    }\n    \n    private void status() {\n      if (status == null) {\n        System.out.println(\"Status: \"+address.getAddress().getHostAddress()+\" no status\");\n      } else {\n        System.out.println(\"Status: \"+address.getHostName()+\" \"+status);\n      }\n    }\n  }\n  \n  \n  // Thread for printing targets as they're heard from\n  //\n  \n  \n  // Thread for connecting to all targets in parallel via a single selector\n  //\n  static class Connector\n      extends Thread {\n    Selector sel;\n    \n    // List of pending targets.  We use this list because if we try to\n    // register a channel with the selector while the connector thread is\n    // blocked in the selector then we will block.\n    //\n    LinkedList<Target> pending = new LinkedList<>();\n    \n    Connector() throws IOException {\n      sel = Selector.open();\n      setName(\"Connector\"); // NOI18N\n    }\n    \n    // Initiate a connection sequence to the given target and add the\n    // target to the pending-target list\n    //\n    void add(Target t) {\n      SocketChannel sc = null;\n      try {\n        \n        // Open the channel, set it to non-blocking, initiate connect\n        sc = SocketChannel.open();\n        sc.configureBlocking(false);\n        sc.connect(t.address);\n        \n        // Record the time we started\n        t.channel = sc;\n        t.connectStart = System.currentTimeMillis();\n        \n        // Add the new channel to the pending list\n        synchronized (pending) {\n          pending.add(t);\n        }\n        \n        // Nudge the selector so that it will process the pending list\n        sel.wakeup();\n        \n      } catch (IOException x) {\n        if (sc != null) {\n          try {\n            sc.close();\n          } catch (IOException xx) { }\n        }\n        t.failure = true;\n        t.done();\n      }\n    }\n    \n    // Process any targets in the pending list\n    //\n    void processPendingTargets() throws IOException {\n      synchronized (pending) {\n        while (!pending.isEmpty()) {\n          Target t = pending.removeFirst();\n          try {\n            \n            // Register the channel with the selector, indicating\n            // interest in connection completion and attaching the\n            // target object so that we can get the target back\n            // after the key is added to the selector's\n            // selected-key set\n            t.channel.register(sel, SelectionKey.OP_CONNECT, t);\n            \n          } catch (IOException x) {\n            \n            // Something went wrong, so close the channel and\n            // record the failure\n            t.channel.close();\n            t.failure = true;\n            t.done();\n          }\n          \n        }\n      }\n    }\n    \n    // Process keys that have become selected\n    //\n    void processSelectedKeys() throws IOException {\n      for (Iterator<SelectionKey> i = sel.selectedKeys().iterator(); i.hasNext();) {\n        \n        // Retrieve the next key and remove it from the set\n        SelectionKey sk = i.next();\n        i.remove();\n        \n        // Retrieve the target and the channel\n        Target t = (Target)sk.attachment();\n        SocketChannel sc = (SocketChannel)sk.channel();\n        \n        // Attempt to complete the connection sequence\n        try {\n          if (sc.finishConnect()) {\n            sk.cancel();\n            t.connectFinish = System.currentTimeMillis();\n            sc.close();\n            t.done();\n          }\n        } catch (IOException x) {\n          sc.close();\n          t.failure = true;\n          t.done();\n        }\n      }\n    }\n    \n    volatile boolean shutdown = false;\n    \n    // Invoked by the main thread when it's time to shut down\n    //\n    void shutdown() {\n      shutdown = true;\n      sel.wakeup();\n    }\n    \n    // Connector loop\n    //\n    public void run() {\n      for (;;) {\n        try {\n          int n = sel.select();\n          if (n > 0)\n            processSelectedKeys();\n          processPendingTargets();\n          if (shutdown) {\n            sel.close();\n            return;\n          }\n        } catch (IOException x) {\n          x.printStackTrace();\n        }\n      }\n    }\n    \n  }\n  \n  \n  public List<InetAddress> getActiveHosts()\n      throws InterruptedException, IOException {\n    port = RMIREGISTRY_PORT;\n    InetAddress localAdd = InetAddress.getLocalHost();\n    //System.out.println(\"Local Address :\"+localAdd.getHostAddress());\n    byte[] addr = localAdd.getAddress();\n    foundHosts = new ArrayList<>();\n    \n    // Create the threads and start them up\n    Connector connector = new Connector();\n    connector.start();\n\n    // Create the targets and add them to the connector\n    for (int i=1;i<255;i++) {\n      addr[addr.length-1]=(byte)i;\n      Target t = new Target(InetAddress.getByAddress(addr),port);\n      connector.add(t);\n    }\n    \n    // Wait for everything to finish\n    Thread.sleep(2000);\n    connector.shutdown();\n    connector.join();\n    foundHosts.remove(localAdd);\n    return foundHosts;\n  }\n  \n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/impl/RemoteHostImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.impl;\n\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport java.net.UnknownHostException;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class RemoteHostImpl extends Host {\n    \n    private Storage givenStorage;\n    \n    \n    RemoteHostImpl(String hostName, Storage givenStorage) throws UnknownHostException {\n        super(hostName);\n        this.givenStorage = givenStorage;\n    }\n    \n    \n    public boolean supportsUserRemove() {\n        return true;\n    }\n    \n    protected Storage createStorage() {\n        return givenStorage;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/model/HostOverview.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.model;\n\nimport org.graalvm.visualvm.core.model.Model;\n\n/**\n * This class uses available JVM APIs to obtain various information about operating system and host\n * on which the Java virtual machine is running.\n *\n * @author Tomas Hurka\n */\npublic abstract class HostOverview extends Model  {\n    \n    /**\n     * Returns the operating system architecture.\n     * This method is equivalent to <tt>System.getProperty(\"os.arch\")</tt>.\n     *\n     * @return the operating system architecture.\n     * @see java.lang.System#getProperty\n     */\n    public abstract String getArch();\n    \n    /**\n     * Returns the number of processors available to the Java virtual machine.\n     * This method is equivalent to the {@link Runtime#availableProcessors()}\n     * method.\n     * <p> This value may change during a particular invocation of\n     * the virtual machine.\n     *\n     * @return  the number of processors available to the virtual\n     *          machine; never smaller than one.\n     */\n    public abstract int getAvailableProcessors();\n    \n    /**\n     * The number of currently available bytes of physical memory.\n     * \n     * @return  the number of currently available bytes of physical memory;\n     * never smaller than one. \n     */ \n    public abstract long getFreePhysicalMemorySize();\n    \n    /**\n     * The number of currently available bytes of swap space.\n     * \n     * @return  the number of currently available bytes of swap space;\n     * never smaller than one. \n     */ \n    public abstract long getFreeSwapSpaceSize();\n    \n    /**\n     * Returns the operating system name. \n     * This method is equivalent to <tt>System.getProperty(\"os.name\")</tt>.\n     *\n     * @return the operating system name.\n     *\n     * @see java.lang.System#getProperty\n     */\n    public abstract String getName();\n    \n    /**\n     * Returns the system load average for the last minute.\n     * The system load average is the sum of the number of runnable entities\n     * queued to the {@linkplain #getAvailableProcessors available processors}\n     * and the number of runnable entities running on the available processors\n     * averaged over a period of time.\n     * The way in which the load average is calculated is operating system\n     * specific but is typically a damped time-dependent average.\n     * <p>\n     * If the load average is not available, a negative value is returned.\n     * <p>\n     * This method is designed to provide a hint about the system load\n     * and may be queried frequently.\n     * The load average is not available on Windows platform.\n     *\n     * @return the system load average; or a negative value if not available.\n     */\n    public abstract double getSystemLoadAverage();\n    \n    /**\n     * The total number of bytes of physical memory.\n     * \n     * @return  the total number of bytes of physical memory;\n     * never smaller than one. \n     */ \n    public abstract long getTotalPhysicalMemorySize();\n    \n    /**\n     * The total number of bytes of swap space.\n     * \n     * @return  the total number of bytes of swap space;\n     * never smaller than one. \n     */ \n    public abstract long getTotalSwapSpaceSize();\n    \n    /**\n     * Returns the operating system version.\n     * This method is equivalent to <tt>System.getProperty(\"os.version\")</tt>.\n     *\n     * @return the operating system version.\n     *\n     * @see java.lang.System#getProperty\n     */\n    public abstract String getVersion();\n    \n    /**\n     * Returns the hostname for this host. \n     *\n     * @return the hostname.\n     */\n    public abstract String getHostName();\n    \n    /**\n     * Returns the operating system patch level. \n     *\n     * @return the operating system patch level.\n     */\n    public abstract String getPatchLevel();\n    \n    /**\n     * Returns the textual representation of the IP address of this host.\n     * \n     * @return the textual representation of the IP address\n     */ \n    public abstract String getHostAddress();\n    \n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/model/HostOverviewFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.model;\n\nimport org.graalvm.visualvm.core.model.ModelFactory;\nimport org.graalvm.visualvm.core.model.ModelProvider;\nimport org.graalvm.visualvm.host.Host;\n\n/**\n * The HostOverviewFactory class is a factory class for getting the\n * {@link HostOverview} representation for the {@link Host}.\n *\n * @author Tomas Hurka\n */\npublic final class HostOverviewFactory extends ModelFactory<HostOverview,Host> implements ModelProvider<HostOverview,Host> {\n    \n    private static HostOverviewFactory overviewFactory;\n    \n    private HostOverviewFactory() {\n    }\n    \n    /**\n     * Getter for the default version of the HostOverviewFactory.\n     * @return instance of {@link HostOverviewFactory}.\n     */\n    public static synchronized HostOverviewFactory getDefault() {\n        if (overviewFactory == null) {\n            overviewFactory = new HostOverviewFactory();\n            overviewFactory.registerProvider(overviewFactory);\n        }\n        return overviewFactory;\n    }\n    \n    /**\n     * Factory method for obtaining {@link HostOverview} for {@link Host}. Note that there\n     * is only one instance of {@link HostOverview} for a concrete application. This {@link HostOverview}\n     * instance is cached. This method can return <CODE>null</CODE> if there is no HostOverview\n     * available\n     * @param host host\n     * @return {@link HostOverview} instance or <CODE>null</CODE> if there is no\n     * {@link HostOverview}\n     */\n    public static HostOverview getSystemOverviewFor(Host host) {\n        return getDefault().getModel(host);\n    }\n    \n    /**\n     * Default {@link ModelProvider} implementation, which creates \n     * HostOverview for localhost. If you want to extend HostOverviewFactory use \n     * {@link HostOverviewFactory#registerProvider(ModelProvider)} to register the new instances\n     * of {@link ModelProvider} for the different types of {@link Host}.\n     * @param host host\n     * @return instance of {@link HostOverview} for localhost\n     */\n    public HostOverview createModelFor(Host host) {\n        if (Host.LOCALHOST.equals(host)) {\n            return new LocalHostOverview();\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/model/LocalHostOverview.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.model;\n\nimport com.sun.management.OperatingSystemMXBean;\nimport org.graalvm.visualvm.host.Host;\nimport java.lang.management.ManagementFactory;\nimport java.net.InetAddress;\nimport java.net.UnknownHostException;\nimport org.openide.util.NbBundle;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass LocalHostOverview extends HostOverview  {\n  private OperatingSystemMXBean osMXBean;\n  private boolean loadAverageAvailable;\n\n  LocalHostOverview() {\n    osMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();\n    loadAverageAvailable = osMXBean.getSystemLoadAverage() >= 0;\n  }\n\n  public String getName() {\n    return osMXBean.getName();\n  }\n\n  public String getVersion() {\n    return osMXBean.getVersion();\n  }\n\n  public String getPatchLevel() {\n    return System.getProperty(\"sun.os.patch.level\", \"\"); // NOI18N\n  }\n  \n  public int getAvailableProcessors() {\n    return osMXBean.getAvailableProcessors();\n  }\n  \n  public String getArch() {\n    String arch = osMXBean.getArch();\n    String bits = System.getProperty(\"sun.arch.data.model\"); // NOI18N\n    if (bits != null) {\n      arch += \" \"+bits+\"bit\";   // NOI18N\n    }\n    return arch;\n  }\n  \n  public String getHostName() {\n    try {\n      return InetAddress.getLocalHost().getHostName();\n    } catch (UnknownHostException ex) {\n      return NbBundle.getMessage(Host.class, \"LBL_Unknown\");   // NOI18N\n    }\n  }\n  \n  public double getSystemLoadAverage() {\n    if (loadAverageAvailable)\n      return osMXBean.getSystemLoadAverage();\n    return -1;\n  }\n  \n  public long getTotalPhysicalMemorySize() {\n    return osMXBean.getTotalPhysicalMemorySize();\n  }\n  \n  public long getFreePhysicalMemorySize() {\n    return osMXBean.getFreePhysicalMemorySize();\n  }\n  \n  public long getTotalSwapSpaceSize() {\n    return osMXBean.getTotalSwapSpaceSize();\n  }\n  \n  public long getFreeSwapSpaceSize() {\n    return osMXBean.getFreeSwapSpaceSize();\n  }\n\n  public String getHostAddress() {\n    try {\n      return InetAddress.getLocalHost().getHostAddress();\n    } catch (UnknownHostException ex) {\n      return \"127.0.0.1\";   // NOI18N\n    }\n  }\n\n}\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/model/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Model for various statistics related to Host (memory, OS, etc.)\n */\npackage org.graalvm.visualvm.host.model;\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Support for hosts in VisualVM.\n */\npackage org.graalvm.visualvm.host;\n"
  },
  {
    "path": "visualvm/host/src/org/graalvm/visualvm/host/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    \n    <folder name=\"Actions\">\n        <folder name=\"Other\">\n            <file name=\"org-graalvm-visualvm-host-AddRemoteHostAction-alwaysEnabled.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.host.AddRemoteHostAction.alwaysEnabled\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"Menu\">\n        <folder name=\"File\">\n            <file name=\"org-graalvm-visualvm-host-AddRemoteHostAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-host-AddRemoteHostAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"500\"/>\n            </file>\n        </folder>\n        <folder name=\"View\">\n            <file name=\"org-graalvm-visualvm-host-HostsSorting.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.host.HostsSorting.instance\"/>\n                <attr name=\"position\" intvalue=\"800\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"Toolbars\">\n        <folder name=\"DataSource\">\n            <file name=\"org-graalvm-visualvm-host-AddRemoteHostAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-host-AddRemoteHostAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"100\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"VisualVM\">\n        <folder name=\"ExplorerPopupSelection\">\n            \n            <file name=\"org-graalvm-visualvm-host-AddRemoteHostAction-selectionAware.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.host.AddRemoteHostAction.selectionAware\"/>\n                <attr name=\"position\" intvalue=\"0\"/>\n                <attr name=\"default\" boolvalue=\"true\"/>\n            </file>\n            \n        </folder>\n        \n        <folder name=\"ExplorerPopupNoSelection\">\n            \n            <file name=\"org-graalvm-visualvm-host-AddRemoteHostAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-host-AddRemoteHostAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"100\"/>\n            </file>\n            \n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "visualvm/hostremote/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.host.remote\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.host.remote.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/hostremote/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.host.remote/2\nOpenIDE-Module-Install: org/graalvm/visualvm/host/remote/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/host/remote/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "visualvm/hostremote/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.hostremote-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/hostremote/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\ncp.extra=${tools.jar}\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nmodule.javadoc.packages=org.graalvm.visualvm.host.remote.*\n\n"
  },
  {
    "path": "visualvm/hostremote/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.host.remote</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/hostremote/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/hostremote/src/org/graalvm/visualvm/host/remote/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Host Remote\n"
  },
  {
    "path": "visualvm/hostremote/src/org/graalvm/visualvm/host/remote/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.remote;\n\nimport org.graalvm.visualvm.host.model.HostOverviewFactory;\nimport org.graalvm.visualvm.host.remote.model.RemoteHostModelProvider;\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\npublic class Installer extends ModuleInstall {\n    \n    public void restored() {\n        HostOverviewFactory.getDefault().registerProvider(new RemoteHostModelProvider());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/hostremote/src/org/graalvm/visualvm/host/remote/model/RemoteHostModelProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.remote.model;\n\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.host.model.HostOverview;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class RemoteHostModelProvider extends AbstractModelProvider<HostOverview, Host> {\n    \n    public HostOverview createModelFor(Host host) {\n        if (!Host.LOCALHOST.equals(host)) {\n            return new RemoteHostOverview(host);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/hostremote/src/org/graalvm/visualvm/host/remote/model/RemoteHostOverview.java",
    "content": "/*\n * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.remote.model;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.host.model.HostOverview;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport java.io.IOException;\nimport java.lang.management.ManagementFactory;\nimport java.lang.management.OperatingSystemMXBean;\nimport java.lang.reflect.UndeclaredThrowableException;\nimport java.rmi.ConnectException;\nimport java.util.Properties;\nimport java.util.Set;\nimport javax.management.AttributeNotFoundException;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.MBeanException;\nimport javax.management.MBeanServerConnection;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\nimport javax.management.ReflectionException;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass RemoteHostOverview extends HostOverview  {\n    private static final ObjectName osMXBeanName = getOperatingSystemMXBeanName();\n    private static final String TotalPhysicalMemorySizeAttr = \"TotalPhysicalMemorySize\";    // NOI18N\n    private static final String TotalPhysicalMemorySizeAttr1 = \"TotalPhysicalMemory\";       // NOI18N\n    private static final String FreePhysicalMemorySizeAttr = \"FreePhysicalMemorySize\";      // NOI18N\n    private static final String TotalSwapSpaceSizeAttr = \"TotalSwapSpaceSize\";              // NOI18N\n    private static final String FreeSwapSpaceSizeAttr = \"FreeSwapSpaceSize\";                // NOI18N\n    \n    private volatile OperatingSystemMXBean osMXBean;\n    private volatile MBeanServerConnection connection;\n    private volatile boolean loadAverageAvailable;\n    private volatile Application jmxApp;\n    private String totalPhysicalMemorySizeAttr;\n    private Host remoteHost;\n    private boolean staticDataInitialized;\n    private String name;\n    private String version;\n    private String patchLevel;\n    private String arch;\n    \n    RemoteHostOverview(Host h) {\n        remoteHost = h;\n    }\n    \n    public String getName() {\n        initStaticData();\n        return name;\n    }\n    \n    public String getVersion() {\n        initStaticData();\n        return version;\n    }\n    \n    public String getPatchLevel() {\n        initStaticData();\n        return patchLevel;\n    }\n    \n    public String getArch() {\n        initStaticData();\n        return arch;\n    }\n    \n    public int getAvailableProcessors() {\n        checkJmxApp();\n        if (jmxApp == null) {\n            return -1;\n        }\n        try {\n            return osMXBean.getAvailableProcessors();\n        } catch (UndeclaredThrowableException ex) {\n            if (ex.getCause() instanceof ConnectException) {\n                jmxApp = null;\n                return getAvailableProcessors();\n            }\n            throw ex;\n        }\n    }\n    \n    public String getHostName() {\n        return remoteHost.getHostName();\n    }\n    \n    public double getSystemLoadAverage() {\n        if (loadAverageAvailable) {\n            checkJmxApp();\n            if (jmxApp == null) {\n                return -1;\n            }\n            try {\n                return osMXBean.getSystemLoadAverage();\n            } catch (UndeclaredThrowableException ex) {\n                if (ex.getCause() instanceof ConnectException) {\n                    jmxApp = null;\n                    return getSystemLoadAverage();\n                }\n                throw ex;\n            }\n        }\n        return -1;\n    }\n    \n    public long getTotalPhysicalMemorySize() {\n        checkJmxApp();\n        if (jmxApp == null) {\n            return -1;\n        }\n        try {\n            return getAttribute(totalPhysicalMemorySizeAttr);\n        } catch (IOException ex) {\n            jmxApp = null;\n            return getTotalPhysicalMemorySize();            \n        }\n    }\n    \n    public long getFreePhysicalMemorySize() {\n        checkJmxApp();\n        if (jmxApp == null) {\n            return -1;\n        }\n        try {\n            return getAttribute(FreePhysicalMemorySizeAttr);\n        } catch (IOException ex) {\n            jmxApp = null;\n            return getTotalPhysicalMemorySize();            \n        }\n    }\n    \n    public long getTotalSwapSpaceSize() {\n        checkJmxApp();\n        if (jmxApp == null) {\n            return -1;\n        }\n        try {\n            return getAttribute(TotalSwapSpaceSizeAttr);\n        } catch (IOException ex) {\n            jmxApp = null;\n            return getTotalPhysicalMemorySize();            \n        }\n    }\n    \n    public long getFreeSwapSpaceSize() {\n        checkJmxApp();\n        if (jmxApp == null) {\n            return -1;\n        }\n        try {\n            return getAttribute(FreeSwapSpaceSizeAttr);\n        } catch (IOException ex) {\n            jmxApp = null;\n            return getTotalPhysicalMemorySize();            \n        }\n    }\n    \n    public String getHostAddress() {\n        return remoteHost.getInetAddress().getHostAddress();\n    }\n    \n    private synchronized void initStaticData() {\n        if (staticDataInitialized) return;\n        checkJmxApp();\n        if (jmxApp == null) return;\n        Properties sysProp = JvmFactory.getJVMFor(jmxApp).getSystemProperties();\n        name = osMXBean.getName();\n        version = osMXBean.getVersion();\n        patchLevel = sysProp.getProperty(\"sun.os.patch.level\", \"\"); // NOI18N\n        arch = osMXBean.getArch();\n        String bits = sysProp.getProperty(\"sun.arch.data.model\"); // NOI18N\n        if (bits != null) {\n            arch += \" \"+bits+\"bit\";   // NOI18N\n        }\n        staticDataInitialized = true;\n    }\n    \n    private Application getJMXApplication() {\n        Set<Application> apps = remoteHost.getRepository().getDataSources(Application.class);\n        \n        for (Application app : apps) {\n            if (app.getState() != Stateful.STATE_AVAILABLE) continue;\n            JmxModel jmx = JmxModelFactory.getJmxModelFor(app);\n            \n            if (jmx != null && jmx.getConnectionState().equals(JmxModel.ConnectionState.CONNECTED)) {\n                JvmMXBeans mxbeans = jmx.getJvmMXBeans();\n                connection = jmx.getMBeanServerConnection();\n                \n                if (mxbeans != null && connection != null) {\n                    osMXBean = mxbeans.getOperatingSystemMXBean();\n                    loadAverageAvailable = false;\n                    try {\n                        loadAverageAvailable = osMXBean.getSystemLoadAverage() >= 0;\n                    } catch (UndeclaredThrowableException ex) {\n                        Throwable cause = ex.getCause();\n                        if (!(cause instanceof AttributeNotFoundException)) {\n                            throw ex;\n                        }\n                    }\n                    try {\n                        connection.getAttribute(osMXBeanName, TotalPhysicalMemorySizeAttr);\n                        totalPhysicalMemorySizeAttr = TotalPhysicalMemorySizeAttr;\n                    } catch (AttributeNotFoundException ex) {\n                        totalPhysicalMemorySizeAttr = TotalPhysicalMemorySizeAttr1;\n                    } catch (InstanceNotFoundException ex) {\n                        throw new RuntimeException(ex);\n                    } catch (ReflectionException ex) {\n                        throw new RuntimeException(ex);\n                    } catch (MBeanException ex) {\n                        throw new RuntimeException(ex);\n                    } catch (IOException ex) {\n                        throw new RuntimeException(ex);\n                    }\n                    return app;\n                }\n            }\n        }\n        return null;\n    }\n    \n    private synchronized void checkJmxApp() {\n        if (jmxApp == null || jmxApp.getState() != Stateful.STATE_AVAILABLE) {\n            jmxApp = getJMXApplication();\n        }\n    }\n    \n    private long getAttribute(String name) throws IOException {\n        Object val = null;\n        try {\n            val = connection.getAttribute(osMXBeanName, name);\n        } catch (AttributeNotFoundException ex) {\n            return -1;\n        } catch (InstanceNotFoundException ex) {\n            throw new RuntimeException(ex);\n        } catch (MBeanException ex) {\n            throw new RuntimeException(ex);\n        } catch (ReflectionException ex) {\n            throw new RuntimeException(ex);\n        }\n        if (val instanceof Number) {\n            return ((Number)val).longValue();\n        }\n        return -1;\n    }\n    \n    private static ObjectName getOperatingSystemMXBeanName() {\n        try {\n            return new ObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME);\n        } catch (MalformedObjectNameException ex) {\n            throw new IllegalArgumentException(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/hostviews/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.host.views\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.host.views.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/hostviews/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.host.views/2\nOpenIDE-Module-Install: org/graalvm/visualvm/host/views/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/host/views/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "visualvm/hostviews/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.host.views-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/hostviews/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/hostviews/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.host.views</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.charts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.host.views</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/hostviews/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/hostviews/src/org/graalvm/visualvm/host/views/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Host Views\n"
  },
  {
    "path": "visualvm/hostviews/src/org/graalvm/visualvm/host/views/HostViewsSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.views;\n\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.host.views.overview.HostOverviewViewProvider;\n\n/**\n * Support for built-in host views in VisualVM.\n * Currently publishes Overview subtab for Host.\n *\n * @author Jiri Sedlacek\n */\npublic final class HostViewsSupport {\n    \n    private static HostViewsSupport sharedInstance;\n    \n    private HostOverviewViewProvider viewProvider = new HostOverviewViewProvider();\n    \n    \n    /**\n     * Returns singleton instance of HostViewsSupport.\n     * \n     * @return singleton instance of HostViewsSupport.\n     */\n    public static synchronized HostViewsSupport sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new HostViewsSupport();\n        return sharedInstance;\n    }\n    \n    /**\n     * Returns PluggableDataSourceViewProvider for Overview host subtab.\n     * \n     * @return PluggableDataSourceViewProvider for Overview host subtab.\n     */\n    public PluggableDataSourceViewProvider<Host> getOverviewView() {\n        return viewProvider;\n    }\n    \n    \n    private HostViewsSupport() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(viewProvider, Host.class);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/hostviews/src/org/graalvm/visualvm/host/views/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.views;\n\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\nfinal class Installer extends ModuleInstall {\n\n    public void restored() {\n        HostViewsSupport.sharedInstance();\n    }\n}\n"
  },
  {
    "path": "visualvm/hostviews/src/org/graalvm/visualvm/host/views/overview/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_Load_average=Load average\n\nLBL_Used_memory=Used\n\nLBL_Used_memory_leg=Used memory\n\nLBL_Used_swap=Used\n\nLBL_Used_swap_leg=Used swap\n\nLBL_Overview=Overview\n\nLBL_CPU=CPU\n\nLBL_Memory=Memory\n\nLBL_Host_IP=Host IP\n\nLBL_Hostname=Hostname\n\nLBL_OS=OS\n\nLBL_Architecture=Architecture\n\nLBL_Processors=Processors\n\nLBL_Total_memory_size=Total physical memory size\n\nLBL_Swap_size=Swap size\n\nLBL_MB=MB\n\nLBL_CPU_load=CPU load\n\nLBL_Physical_memory=Physical memory\n\nLBL_Total_memory=Total\n\nLBL_Total_swap=Total\n\nLBL_Swap_memory=Swap memory\n"
  },
  {
    "path": "visualvm/hostviews/src/org/graalvm/visualvm/host/views/overview/HostOverviewView.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.views.overview;\n\nimport java.awt.BorderLayout;\nimport java.text.NumberFormat;\nimport java.util.Timer;\nimport java.util.TimerTask;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.charts.ChartFactory;\nimport org.graalvm.visualvm.charts.SimpleXYChartDescriptor;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.NotSupportedDisplayer;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.host.model.HostOverview;\nimport org.graalvm.visualvm.host.model.HostOverviewFactory;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass HostOverviewView extends DataSourceView implements DataRemovedListener<Host> {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/host/views/resources/overview.png\";    // NOI18N\n\n    private Timer timer;\n    private HostOverview hostOverview;\n    \n\n    HostOverviewView(Host host) {\n        super(host, NbBundle.getMessage(HostOverviewView.class, \"LBL_Overview\"), new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 0, false);    // NOI18N\n    }\n    \n    protected void willBeAdded() {\n        hostOverview = HostOverviewFactory.getSystemOverviewFor((Host)getDataSource());\n    }\n        \n    protected void removed() {\n        timer.cancel();\n    }\n    \n    public void dataRemoved(Host dataSource) {\n        timer.cancel();\n    }\n    \n    \n    protected DataViewComponent createComponent() {\n        GlobalPreferences preferences = GlobalPreferences.sharedInstance();\n        int chartCache = preferences.getMonitoredHostCache() * 60 /\n                         preferences.getMonitoredHostPoll();\n\n        DataViewComponent dvc = new DataViewComponent(\n                new MasterViewSupport((Host)getDataSource()).getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(false));\n\n        boolean cpuSupported = hostOverview.getSystemLoadAverage() >= 0;\n        final CpuLoadViewSupport cpuLoadViewSupport = new CpuLoadViewSupport(hostOverview, cpuSupported, chartCache);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(HostOverviewView.class, \"LBL_CPU\"), true), DataViewComponent.TOP_LEFT); // NOI18N\n        dvc.addDetailsView(cpuLoadViewSupport.getDetailsView(), DataViewComponent.TOP_LEFT);\n        if (!cpuSupported) dvc.hideDetailsArea(DataViewComponent.TOP_LEFT);\n\n        final PhysicalMemoryViewSupport physicalMemoryViewSupport = new PhysicalMemoryViewSupport(chartCache);\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(HostOverviewView.class, \"LBL_Memory\"), true), DataViewComponent.TOP_RIGHT); // NOI18N\n        dvc.addDetailsView(physicalMemoryViewSupport.getDetailsView(), DataViewComponent.TOP_RIGHT);\n\n        final SwapMemoryViewSupport swapMemoryViewSupport = new SwapMemoryViewSupport(chartCache);\n        dvc.addDetailsView(swapMemoryViewSupport.getDetailsView(), DataViewComponent.TOP_RIGHT);\n\n        timer = new Timer();\n        timer.schedule(new TimerTask() {\n            public void run() {\n                final long time = System.currentTimeMillis();\n                cpuLoadViewSupport.refresh(hostOverview, time);\n                physicalMemoryViewSupport.refresh(hostOverview, time);\n                swapMemoryViewSupport.refresh(hostOverview, time);\n            }\n        }, 800, 2000);\n        getDataSource().notifyWhenRemoved(this);\n        \n        return dvc;\n    }\n    \n    \n    // --- General data --------------------------------------------------------\n    \n    private static class MasterViewSupport extends JPanel {\n        \n        MasterViewSupport(Host host) {\n            initComponents(host);\n        }\n        \n        \n        public DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(HostOverviewView.class, \"LBL_Overview\"), null, this);   // NOI18N\n        }\n        \n        \n        private void initComponents(Host host) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            HTMLTextArea area = new HTMLTextArea(\"<nobr>\" + getGeneralInfo(host) + \"</nobr>\");  // NOI18N\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n            \n            add(area, BorderLayout.CENTER);\n        }\n        \n        String getGeneralInfo(Host host) {\n            HostOverview so = HostOverviewFactory.getSystemOverviewFor(host);\n            StringBuilder data = new StringBuilder();\n            String hostIp = NbBundle.getMessage(HostOverviewView.class, \"LBL_Host_IP\"); // NOI18N\n            data.append(\"<b>\"+ hostIp + \":</b> \"+ so.getHostAddress() + \"<br>\"); // NOI18N\n            \n            String hostname = NbBundle.getMessage(HostOverviewView.class, \"LBL_Hostname\");  // NOI18N\n            data.append(\"<b>\"+ hostname + \":</b> \" + so.getHostName() + \"<br><br>\"); // NOI18N\n\n            String name = so.getName();\n            String ver = so.getVersion();\n            String patch = so.getPatchLevel();\n\n            patch = \"unknown\".equals(patch) ? \"\" : patch;   // NOI18N\n            String os = NbBundle.getMessage(HostOverviewView.class, \"LBL_OS\");  // NOI18N\n            String arch = NbBundle.getMessage(HostOverviewView.class, \"LBL_Architecture\");  // NOI18N\n            String proc = NbBundle.getMessage(HostOverviewView.class, \"LBL_Processors\");    // NOI18N\n            String memory = NbBundle.getMessage(HostOverviewView.class, \"LBL_Total_memory_size\");    // NOI18N\n            String swap = NbBundle.getMessage(HostOverviewView.class, \"LBL_Swap_size\"); // NOI18N\n            String mb = NbBundle.getMessage(HostOverviewView.class, \"LBL_MB\");  // NOI18N\n            data.append(\"<b>\"+os+\":</b> \" + name + \" (\" + ver + \")\" + \" \" + patch + \"<br>\");    // NOI18N\n            data.append(\"<b>\"+arch+\":</b> \" + so.getArch() + \"<br>\");   // NOI18N\n            data.append(\"<b>\"+proc+\":</b> \" + so.getAvailableProcessors() + \"<br><br>\");    // NOI18N\n            data.append(\"<b>\"+memory+\":</b> \" + formatBytes(so.getTotalPhysicalMemorySize()) + \" \"+mb+\"<br>\");  // NOI18N\n            data.append(\"<b>\"+swap+\":</b> \" + formatBytes(so.getTotalSwapSpaceSize()) + \" \"+mb+\"<br>\"); // NOI18N\n\n            return data.toString();\n        }\n        \n        private String formatBytes(long l) {\n            return NumberFormat.getInstance().format(((10*l)/1024/1024)/10.0);\n        }\n        \n    }\n    \n    \n    // --- CPU load ------------------------------------------------------------\n\n    private static class CpuLoadViewSupport extends JPanel {\n\n        private boolean cpuMonitoringSupported;\n        \n        private static final String LOAD_AVERAGE = NbBundle.getMessage(HostOverviewView.class, \"LBL_Load_average\"); // NOI18N\n\n        private SimpleXYChartSupport chartSupport;\n\n        CpuLoadViewSupport(HostOverview hostOverview, boolean cpuSupported, int chartCache) {\n            cpuMonitoringSupported = cpuSupported;\n            initModels(chartCache);\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(HostOverviewView.class, \"LBL_CPU_load\"), null, 10, this, null);    // NOI18N\n        }\n\n        public void refresh(HostOverview hostOverview, long time) {\n            if (cpuMonitoringSupported) {\n                long load = (long)(hostOverview.getSystemLoadAverage() * 1000);\n                \n                chartSupport.addValues(time, new long[] { load });\n                chartSupport.updateDetails(new String[] { chartSupport.formatDecimal(load) });\n            }\n        }\n\n        private void initModels(int chartCache) {\n            SimpleXYChartDescriptor chartDescriptor =\n                    SimpleXYChartDescriptor.decimal(1, 0.001d, false, chartCache);\n\n            chartDescriptor.addLineItems(LOAD_AVERAGE);\n            chartDescriptor.setDetailsItems(new String[] { LOAD_AVERAGE });\n\n            chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (cpuMonitoringSupported) {\n                add(chartSupport.getChart(), BorderLayout.CENTER);\n            } else {\n                add(new NotSupportedDisplayer(NotSupportedDisplayer.HOST),\n                    BorderLayout.CENTER);\n            }\n        }\n\n    }\n\n\n    // --- Physical memory -----------------------------------------------------\n\n    private static class PhysicalMemoryViewSupport extends JPanel {\n\n        private static String USED_MEMORY = NbBundle.getMessage(HostOverviewView.class, \"LBL_Used_memory\"); // NOI18N\n        private static String USED_MEMORY_LEG = NbBundle.getMessage(HostOverviewView.class, \"LBL_Used_memory_leg\"); // NOI18N\n        private static String TOTAL_MEMORY = NbBundle.getMessage(HostOverviewView.class, \"LBL_Total_memory\");   // NOI18N\n\n        private SimpleXYChartSupport chartSupport;\n\n        PhysicalMemoryViewSupport(int chartCache) {\n            initModels(chartCache);\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(HostOverviewView.class, \"LBL_Physical_memory\"), null, 10, this, null); // NOI18N\n        }\n\n        public void refresh(HostOverview hostOverview, long time) {\n            long memoryMax = hostOverview.getTotalPhysicalMemorySize();\n            long memoryUsed = memoryMax - hostOverview.getFreePhysicalMemorySize();\n\n            chartSupport.addValues(time, new long[] { memoryUsed });\n            chartSupport.updateDetails(new String[] { chartSupport.formatBytes(memoryUsed),\n                                                      chartSupport.formatBytes(memoryMax) });\n        }\n\n        private void initModels(int chartCache) {\n            SimpleXYChartDescriptor chartDescriptor =\n                    SimpleXYChartDescriptor.bytes(128 * 1024 * 1024, false, chartCache);\n\n            chartDescriptor.addLineFillItems(USED_MEMORY_LEG);\n            chartDescriptor.setDetailsItems(new String[] { USED_MEMORY, TOTAL_MEMORY });\n\n            chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            add(chartSupport.getChart(), BorderLayout.CENTER);\n        }\n\n    }\n\n\n    // --- Swap memory ---------------------------------------------------------\n\n    private static class SwapMemoryViewSupport extends JPanel {\n\n        private static final String USED_SWAP = NbBundle.getMessage(HostOverviewView.class, \"LBL_Used_swap\");   // NOI18N\n        private static final String USED_SWAP_LEG = NbBundle.getMessage(HostOverviewView.class, \"LBL_Used_swap_leg\");   // NOI18N\n        private static final String TOTAL_SWAP = NbBundle.getMessage(HostOverviewView.class, \"LBL_Total_swap\"); // NOI18N\n\n        private SimpleXYChartSupport chartSupport;\n\n        SwapMemoryViewSupport(int chartCache) {\n            initModels(chartCache);\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(HostOverviewView.class, \"LBL_Swap_memory\"), null, 20, this, null); // NOI18N\n        }\n\n        public void refresh(HostOverview hostOverview, long time) {\n            long memorySwapMax = hostOverview.getTotalSwapSpaceSize();\n            long memorySwapUsed = memorySwapMax - hostOverview.getFreeSwapSpaceSize();\n\n            chartSupport.addValues(time, new long[] { memorySwapUsed });\n            chartSupport.updateDetails(new String[] { chartSupport.formatBytes(memorySwapUsed),\n                                                      chartSupport.formatBytes(memorySwapMax) });\n        }\n\n        private void initModels(int chartCache) {\n            SimpleXYChartDescriptor chartDescriptor =\n                    SimpleXYChartDescriptor.bytes(128 * 1024 * 1024, false, chartCache);\n\n            chartDescriptor.addLineFillItems(USED_SWAP_LEG);\n            chartDescriptor.setDetailsItems(new String[] { USED_SWAP, TOTAL_SWAP });\n\n            chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            add(chartSupport.getChart(), BorderLayout.CENTER);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/hostviews/src/org/graalvm/visualvm/host/views/overview/HostOverviewViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.host.views.overview;\n\nimport java.util.Set;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.host.model.HostOverviewFactory;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class HostOverviewViewProvider extends PluggableDataSourceViewProvider<Host> {\n    \n    protected boolean supportsViewFor(Host host) {\n        return HostOverviewFactory.getSystemOverviewFor(host).getName() != null;\n    }\n\n    protected DataSourceView createView(Host host) {\n        return new HostOverviewView(host);\n    }\n    \n    public Set<Integer> getPluggableLocations(DataSourceView view) {\n        return ALL_LOCATIONS;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/hostviews/src/org/graalvm/visualvm/host/views/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Support for views (subtabs) for hosts.\n */\npackage org.graalvm.visualvm.host.views;\n"
  },
  {
    "path": "visualvm/jfr/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.jfr\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.jfr.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/jfr/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.jfr/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/jfr/resources/layer.xml\nOpenIDE-Module-Install: org/graalvm/visualvm/jfr/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/jfr/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.3\nOpenIDE-Module-Recommends: jfr.implementation\n"
  },
  {
    "path": "visualvm/jfr/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.jfr-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/jfr/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=f890864d\nbuild.xml.script.CRC32=8bce95d6\nbuild.xml.stylesheet.CRC32=15ca8a54@2.88\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=f890864d\nnbproject/build-impl.xml.script.CRC32=82070b0d\nnbproject/build-impl.xml.stylesheet.CRC32=49aa68b0@2.88\n"
  },
  {
    "path": "visualvm/jfr/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jiri Sedlacek\n"
  },
  {
    "path": "visualvm/jfr/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.jfr</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.2</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.charts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.threaddump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.sendopts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.43</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.11.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.49</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.34</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.18.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.jfr.generic</friend>\n                <friend>org.graalvm.visualvm.jfr.jdk11</friend>\n                <friend>org.graalvm.visualvm.jfr.jdk9</friend>\n                <package>org.graalvm.visualvm.jfr</package>\n                <package>org.graalvm.visualvm.jfr.model</package>\n                <package>org.graalvm.visualvm.jfr.utils</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/jfr/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/Bundle.properties",
    "content": "#\n# Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Long-Description=Framework and UI to visualize JFR snapshots in VisualVM.\n#<BR><BR>Requires at least one of the following JFR loaders to be installed:<BR><BR><B>VisualVM-JFR-Generic:</B> Generic JFR loader reading all JFR snapshots (slightly worse performance and higher memory consumption than the other loaders)<BR>.\\\n#<BR><B>VisualVM-JFR-JDK9:</B> Support for the JFR loader bundled with JDK 9 and JDK 10 (requires running VisualVM on JDK 9/10) reading JFR snapshots created from JDK 9 and JDK 10.\\\n#<BR><BR><B>VisualVM-JFR-JDK11:</B> Support for the JFR loader bundled with JDK 11 and newer (requires running VisualVM on JDK 11+) reading JFR snapshots created from JDK 9 and newer. Requires VisualVM-JFR-JDK9 to be installed as well.\nOpenIDE-Module-Name=VisualVM-JFR\n\nLBL_Save_JFR_As=Save JFR Snapshot As\n\nLBL_VM_Coredumps=JFR Snapshots\n\nDESCR_CoreDump=JDK Flight Recorder Snapshot.\n\nCaption_CommercialFeatures=Using Commercial Features\nMsg_CommercialFeatures=JFR for this process might require a commercial license\\nfor use in production.\\n\\nTo learn more about commercial features please visit\\nhttps://www.oracle.com/technetwork/java/javaseproducts/.\\n\\n\n\nACT_SortCoreDumps=Sort &JFR Snapshots By\nACT_TimeAdded=&Time Added\nACT_DisplayName=&Display Name\nOpenIDE-Module-Short-Description=Framework and UI to visualize JFR snapshots in VisualVM\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/Installer.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr;\n\nimport org.graalvm.visualvm.jfr.model.impl.JfrModelProvider;\nimport org.graalvm.visualvm.tools.jfr.JfrModelFactory;\nimport org.openide.modules.ModuleInstall;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class Installer extends ModuleInstall {\n    \n    public void restored() {\n        JFRSnapshotSupport.register();\n        JfrModelFactory.getDefault().registerProvider(new JfrModelProvider());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/JFRSnapshot.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr;\n\nimport java.io.File;\nimport java.io.IOException;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsSupport;\nimport org.openide.util.NbBundle;\n\n/**\n * Abstract implementation of JFRSnapshot.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JFRSnapshot extends Snapshot {\n    \n    public JFRSnapshot(File file) throws IOException {\n        this(file, null);\n    }\n    \n    public JFRSnapshot(File file, DataSource master) throws IOException {\n        super(file, JFRSnapshotSupport.getCategory(), master);\n        \n        if (!file.exists() || !file.isFile())\n            throw new IOException(\"File \" + file.getAbsolutePath() + \" does not exist\");    // NOI18N\n    }\n    \n    public boolean supportsSaveAs() {\n        return getFile() != null;\n    }\n    \n    public void saveAs() {\n        SnapshotsSupport.getInstance().saveAs(this, NbBundle.getMessage(JFRSnapshot.class, \"LBL_Save_JFR_As\"));  // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/JFRSnapshotDescriptor.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr;\n\nimport java.awt.Image;\nimport org.graalvm.visualvm.core.snapshot.SnapshotDescriptor;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsSupport;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * DataSourceDescriptor for JFRSnapshot.\n *\n * @author Jiri Sedlacek\n */\npublic class JFRSnapshotDescriptor extends SnapshotDescriptor<JFRSnapshot> {\n\n    private static final Image ICON = SnapshotsSupport.getInstance().createSnapshotIcon(\n            ImageUtilities.loadImage(\"org/graalvm/visualvm/jfr/resources/jfrSnapshot.png\", true)); // NOI18N\n\n    /**\n     * Creates new instance of JFRSnapshotDescriptor.\n     * \n     * @param snapshot JFRSnapshot for the descriptor.\n     */\n    public JFRSnapshotDescriptor(JFRSnapshot snapshot) {\n        super(snapshot, resolveSnapshotName(snapshot), NbBundle.getMessage(JFRSnapshotDescriptor.class, \"DESCR_CoreDump\"), ICON, // NOI18N\n              resolvePosition(snapshot, POSITION_AT_THE_END, true), EXPAND_NEVER);\n    }\n    \n    \n    private static String resolveName(JFRSnapshot snapshot) {\n        String persistedName = resolveName(snapshot, null);\n        return persistedName != null ? persistedName : snapshot.getFile().getName();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/JFRSnapshotSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr;\n\nimport java.io.File;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.snapshot.RegisteredSnapshotCategories;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.jfr.impl.JFRRecordingProvider;\nimport org.graalvm.visualvm.jfr.impl.JFRSnapshotCategory;\nimport org.graalvm.visualvm.jfr.impl.JFRSnapshotDescriptorProvider;\nimport org.graalvm.visualvm.jfr.impl.JFRSnapshotProvider;\nimport org.graalvm.visualvm.jfr.view.JFRViewProvider;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.tools.jfr.JfrModel;\nimport org.graalvm.visualvm.tools.jfr.JfrModelFactory;\nimport org.openide.util.NbBundle;\n\n/**\n * Support for JFR snapshots in VisualVM.\n *\n * @author Jiri Sedlacek\n */\npublic final class JFRSnapshotSupport {\n    \n    private static final String JFRSNAPSHOTS_STORAGE_DIRNAME = \"jfrsnapshots\";    // NOI18N\n    \n    private static final Object jfrSnapshotsStorageDirectoryLock = new Object();\n    // @GuardedBy jfrSnapshotsStorageDirectoryLock\n    private static File jfrSnapshotsStorageDirectory;\n    private static final Object jfrSnapshotsStorageDirectoryStringLock = new Object();\n    // @GuardedBy jfrSnapshotsStorageDirectoryStringLock\n    private static String jfrSnapshotsStorageDirectoryString;\n    \n    private static final JFRSnapshotCategory category = new JFRSnapshotCategory();\n    private static JFRRecordingProvider jfrDumpProvider;\n    \n    \n    /**\n     * Returns SnapshotCategory instance for JFR snapshots.\n     * \n     * @return SnapshotCategory instance for JFR snapshots.\n     */\n    public static SnapshotCategory<JFRSnapshot> getCategory() {\n        return category;\n    }\n    \n    static String getStorageDirectoryString() {\n        synchronized(jfrSnapshotsStorageDirectoryStringLock) {\n            if (jfrSnapshotsStorageDirectoryString == null)\n                jfrSnapshotsStorageDirectoryString = Storage.getPersistentStorageDirectoryString() + File.separator + JFRSNAPSHOTS_STORAGE_DIRNAME;\n            return jfrSnapshotsStorageDirectoryString;\n        }\n    }\n    \n    /**\n     * Returns storage directory for JFR snapshots.\n     * \n     * @return storage directory for JFR snapshots.\n     */\n    public static File getStorageDirectory() {\n        synchronized(jfrSnapshotsStorageDirectoryLock) {\n            if (jfrSnapshotsStorageDirectory == null) {\n                String snapshotsStorageString = getStorageDirectoryString();\n                jfrSnapshotsStorageDirectory = new File(snapshotsStorageString);\n                if (jfrSnapshotsStorageDirectory.exists() && jfrSnapshotsStorageDirectory.isFile())\n                    throw new IllegalStateException(\"Cannot create JFR snapshots storage directory \" + snapshotsStorageString + \", file in the way\");   // NOI18N\n                if (jfrSnapshotsStorageDirectory.exists() && (!jfrSnapshotsStorageDirectory.canRead() || !jfrSnapshotsStorageDirectory.canWrite()))\n                    throw new IllegalStateException(\"Cannot access JFR snapshots storage directory \" + snapshotsStorageString + \", read&write permission required\");    // NOI18N\n                if (!Utils.prepareDirectory(jfrSnapshotsStorageDirectory))\n                    throw new IllegalStateException(\"Cannot create JFR snapshots storage directory \" + snapshotsStorageString); // NOI18N\n            }\n            return jfrSnapshotsStorageDirectory;\n        }\n    }\n\n    /**\n     * Returns true if the storage directory for JFR snapshots already exists, false otherwise.\n     * \n     * @return true if the storage directory for JFR snapshots already exists, false otherwise.\n     */\n    public static boolean storageDirectoryExists() {\n        return new File(getStorageDirectoryString()).isDirectory();\n    }\n\n    \n    static void register() {\n        DataSourceDescriptorFactory.getDefault().registerProvider(new JFRSnapshotDescriptorProvider());\n        JFRSnapshotsContainer.sharedInstance();\n        JFRSnapshotProvider.register();\n        RegisteredSnapshotCategories.sharedInstance().registerCategory(category);\n        \n        DataSourceViewsManager views = DataSourceViewsManager.sharedInstance();\n        views.addViewProvider(new JFRViewProvider(), JFRSnapshot.class);\n        jfrDumpProvider = new JFRRecordingProvider();\n        jfrDumpProvider.initialize();\n    }\n\n    public static void takeJfrDump(Application application, boolean stopJfr, boolean openView) {\n        jfrDumpProvider.createJfrDump(application, stopJfr, openView);\n    }\n\n    public static void takeRemoteJfrDump(Application application, String dumpFile, boolean customizeDumpFile) {\n        jfrDumpProvider.createRemoteJfrDump(application, dumpFile, customizeDumpFile);\n    }\n\n    public static boolean supportsJfrDump(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        if (!jvm.isJfrAvailable()) return false;\n        return !jvm.jfrCheck().isEmpty();\n    }\n\n    public static boolean supportsRemoteJfrDump(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        if (application.isLocalApplication()) return false; // Should be allowed???\n        JfrModel jfrModel = JfrModelFactory.getJFRFor(application);\n        if (jfrModel == null) return false;\n        return !jfrModel.jfrCheck().isEmpty();\n    }\n\n    public static void jfrStartRecording(Application application) {\n        jfrStartRecording(application, null);\n    }\n    \n    public static void jfrStartRecording(Application application, String params) {\n        checkNotifyCommercialFeatures(application);\n        jfrDumpProvider.jfrStartRecording(application, params);\n    }\n\n    public static void remoteJfrStartRecording(Application application) {\n        checkNotifyCommercialFeatures(application);\n        jfrDumpProvider.remoteJfrStartRecording(application);\n    }\n\n    public static boolean supportsJfrStart(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        if (!jvm.isJfrAvailable()) return false;\n        return jvm.jfrCheck().isEmpty();\n    }\n\n    public static boolean supportsRemoteJfrStart(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        if (application.isLocalApplication()) return false; // Should be allowed???\n        JfrModel jfrModel = JfrModelFactory.getJFRFor(application);\n        if (jfrModel == null) return false;\n        return jfrModel.jfrCheck().isEmpty();\n    }\n\n    public static void jfrStopRecording(Application application) {\n        jfrDumpProvider.jfrStopRecording(application);\n    }\n\n    public static void remoteJfrStopRecording(Application application) {\n        jfrDumpProvider.remoteJfrStopRecording(application);\n    }\n\n    public static boolean supportsJfrStop(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        if (!jvm.isJfrAvailable()) return false;\n        return !jvm.jfrCheck().isEmpty();\n    }\n\n    public static boolean supportsRemoteJfrStop(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        if (application.isLocalApplication()) return false; // Should be allowed???\n        JfrModel jfrModel = JfrModelFactory.getJFRFor(application);\n        if (jfrModel == null) return false;\n        return !jfrModel.jfrCheck().isEmpty();\n    }\n    \n    \n    public static void checkNotifyCommercialFeatures(Application application) {\n        if (requiresUnlockCommercialFeatures(application))\n            displayUnlockCommercialFeaturesNotification(application);\n    }\n    \n    public static boolean requiresUnlockCommercialFeatures(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        if (!jvm.is18() && !jvm.is19() && !jvm.is100()) return false;\n        String vmVendor = jvm.getVmVendor();\n        return vmVendor != null && vmVendor.contains(\"Oracle\");                 // NOI18N\n    }\n    \n    private static void displayUnlockCommercialFeaturesNotification(Application application) {\n        ProfilerDialogs.displayWarningDNSA(NbBundle.getMessage(JFRSnapshotSupport.class, \"Msg_CommercialFeatures\"), // NOI18N\n                                           NbBundle.getMessage(JFRSnapshotSupport.class, \"Caption_CommercialFeatures\"), // NOI18N\n                                           null, \"JFRSnapshotSupport_NotifyCommercialFeatures\", true); // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/JFRSnapshotsContainer.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\n/**\n * Toplevel node JFR Snapshots in Applications window.\n *\n * @author Jiri Sedlacek\n */\npublic final class JFRSnapshotsContainer extends DataSource {\n    \n    private static JFRSnapshotsContainer sharedInstance;\n    \n    \n    /**\n     * Returns singleton instance of JFRSnapshotsContainer.\n     * \n     * @return singleton instance of JFRSnapshotsContainer.\n     */\n    public static synchronized JFRSnapshotsContainer sharedInstance() {\n        if (sharedInstance == null) sharedInstance = new JFRSnapshotsContainer();\n        return sharedInstance;\n    }\n\n\n    private JFRSnapshotsContainer() {\n        DataSourceDescriptorFactory.getDefault().registerProvider(new AbstractModelProvider<DataSourceDescriptor,DataSource>() {\n                public DataSourceDescriptor createModelFor(DataSource ds) {\n                    if (JFRSnapshotsContainer.sharedInstance().equals(ds))\n                        return new JFRSnapshotsContainerDescriptor();\n                    else return null;\n                }\n            }\n        );\n        DataSource.ROOT.getRepository().addDataSource(this);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/JFRSnapshotsContainerDescriptor.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr;\n\nimport java.awt.Image;\nimport java.util.Comparator;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * DataSourceDescriptor for JFR Snapshots node in Applications window.\n *\n * @author Jiri Sedlacek\n */\npublic final class JFRSnapshotsContainerDescriptor extends DataSourceDescriptor<JFRSnapshotsContainer> {\n\n    private static final Image NODE_ICON = ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/jfr/resources/jfrSnapshots.png\", true);  // NOI18N\n\n    JFRSnapshotsContainerDescriptor() {\n        super(JFRSnapshotsContainer.sharedInstance(), NbBundle.getMessage(JFRSnapshotsContainerDescriptor.class, \"LBL_VM_Coredumps\"), null, // NOI18N\n              NODE_ICON, 28, EXPAND_ON_EACH_NEW_CHILD);\n        \n        // Initialize sorting\n        setChildrenComparator(JFRSnapshotsSorting.instance().getInitialSorting());\n    }\n\n    /**\n     * Sets a custom comparator for sorting DataSources within the JFRSnapshotsContainer.\n     * Use setChildrenComparator(null) to restore the default sorting.\n     *\n     * @param newComparator comparator for sorting DataSources within the JFRSnapshotsContainer\n     */\n    public void setChildrenComparator(Comparator<DataSource> newComparator) {\n        super.setChildrenComparator(newComparator);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/JFRSnapshotsSorting.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr;\n\nimport java.awt.Component;\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.prefs.Preferences;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JRadioButtonMenuItem;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.actions.Presenter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRSnapshotsSorting implements Presenter.Menu {\n\n    private static final String PROP_HOSTS_SORTING = \"JFRSnapshot.sorting\"; // NOI18N\n\n    private static JFRSnapshotsSorting instance;\n    \n    private static final Comparator<DataSource> BY_TIME_COMPARATOR = byTimeComparator();\n    private static final Comparator<DataSource> BY_NAME_COMPARATOR = byNameComparator();\n    private static final List<Comparator<DataSource>> COMPARATORS = new ArrayList<>();\n    static { COMPARATORS.add(BY_TIME_COMPARATOR); COMPARATORS.add(BY_NAME_COMPARATOR); }\n\n    private final Preferences prefs;\n\n    private JMenuItem presenter;\n    private final Sorter sorter;\n\n\n    public static synchronized JFRSnapshotsSorting instance() {\n        if (instance == null) instance = new JFRSnapshotsSorting();\n        return instance;\n    }\n\n    public JMenuItem getMenuPresenter() {\n        if (presenter == null) presenter = createPresenter();\n        return presenter;\n    }\n\n\n    Comparator<DataSource> getInitialSorting() {\n        return COMPARATORS.get(prefs.getInt(PROP_HOSTS_SORTING, COMPARATORS.\n                                            indexOf(BY_TIME_COMPARATOR)));\n    }\n\n\n    private JMenuItem createPresenter() {\n        final JMenu menu = new JMenu() {\n            protected void fireMenuSelected() {\n                Component[] items = getMenuComponents();\n                for (Component item : items)\n                    if (item instanceof SortAction)\n                        ((SortAction)item).updateAction();\n            }\n        };\n        Mnemonics.setLocalizedText(menu, NbBundle.getMessage(JFRSnapshotsSorting.class,\n                                   \"ACT_SortCoreDumps\")); // NOI18N\n        \n        menu.add(new SortAction(NbBundle.getMessage(JFRSnapshotsSorting.class,\n                                \"ACT_TimeAdded\"), BY_TIME_COMPARATOR, sorter)); // NOI18N\n        menu.add(new SortAction(NbBundle.getMessage(JFRSnapshotsSorting.class,\n                                \"ACT_DisplayName\"), BY_NAME_COMPARATOR, sorter)); // NOI18N\n\n        return menu;\n    }\n    \n    private static Comparator<DataSource> byTimeComparator() {\n        return null;\n    }\n\n    private static Comparator<DataSource> byNameComparator() {\n        return new Comparator<DataSource>() {\n            public int compare(DataSource d1, DataSource d2) {\n                DataSourceDescriptor dd1 = DataSourceDescriptorFactory.getDescriptor(d1);\n                DataSourceDescriptor dd2 = DataSourceDescriptorFactory.getDescriptor(d2);\n\n                return dd1.getName().compareTo(dd2.getName());\n            }\n        };\n    }\n\n    private JFRSnapshotsSorting() {\n        prefs = NbPreferences.forModule(JFRSnapshotsSorting.class);\n\n        sorter = new Sorter() {\n            public void sort(Comparator<DataSource> comparator) {\n                DataSourceDescriptor d = DataSourceDescriptorFactory.getDescriptor(\n                                         JFRSnapshotsContainer.sharedInstance());\n                if (d instanceof JFRSnapshotsContainerDescriptor) {\n                    ((JFRSnapshotsContainerDescriptor)d).setChildrenComparator(comparator);\n                    prefs.putInt(PROP_HOSTS_SORTING, COMPARATORS.indexOf(comparator));\n                }\n            }\n        };\n    }\n\n\n    private static class SortAction extends JRadioButtonMenuItem {\n\n        private final Sorter sorter;\n        private final Comparator<DataSource> comparator;\n        private boolean currentlySelected;\n\n        SortAction(String name, Comparator<DataSource> comparator, Sorter sorter) {\n            Mnemonics.setLocalizedText(this, name);\n            this.comparator = comparator;\n            this.sorter = sorter;\n        }\n\n        void updateAction() {\n            DataSourceDescriptor d = DataSourceDescriptorFactory.getDescriptor(\n                                     JFRSnapshotsContainer.sharedInstance());\n            setEnabled(d instanceof JFRSnapshotsContainerDescriptor);\n            currentlySelected = d.getChildrenComparator() == comparator;\n            setSelected(currentlySelected);\n        }\n\n        protected void fireActionPerformed(ActionEvent e) {\n            if (!currentlySelected) sorter.sort(comparator);\n        }\n\n    }\n\n    private static interface Sorter {\n\n        void sort(Comparator<DataSource> comparator);\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/AddJFRSnapshotAction.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.impl;\n\nimport java.awt.Image;\nimport java.awt.event.ActionEvent;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport org.graalvm.visualvm.jfr.JFRSnapshotsContainer;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n    \n/**\n *\n * @author Jiri Sedlacek\n */\nclass AddJFRSnapshotAction extends SingleDataSourceAction<JFRSnapshotsContainer> {\n    \n    private static final String ICON_PATH = \"org/graalvm/visualvm/jfr/resources/addJFRSnapshot.png\";    // NOI18N\n    private static final Image ICON =  ImageUtilities.loadImage(ICON_PATH);\n    \n    private boolean tracksSelection = false;\n    \n    private static AddJFRSnapshotAction alwaysEnabled;\n    private static AddJFRSnapshotAction selectionAware;\n    \n    \n    public static synchronized AddJFRSnapshotAction alwaysEnabled() {\n        if (alwaysEnabled == null) {\n            alwaysEnabled = new AddJFRSnapshotAction();\n            alwaysEnabled.putValue(SMALL_ICON, new ImageIcon(ICON));\n            alwaysEnabled.putValue(\"iconBase\", ICON_PATH);  // NOI18N\n        }\n        return alwaysEnabled;\n    }\n    \n    public static synchronized AddJFRSnapshotAction selectionAware() {\n        if (selectionAware == null) {\n            selectionAware = new AddJFRSnapshotAction();\n            selectionAware.tracksSelection = true;\n        }\n        return selectionAware;\n    }\n    \n    public void actionPerformed(JFRSnapshotsContainer container, ActionEvent e) {\n        JFRSnapshotConfigurator newSnapshotConfiguration = JFRSnapshotConfigurator.defineJFRSnapshot();\n        if (newSnapshotConfiguration != null) {\n            JFRSnapshotProvider.createJFRSnapshot(newSnapshotConfiguration.getJFRSnapshotFile(),\n                    newSnapshotConfiguration.getDisplayname(),\n                    newSnapshotConfiguration.deleteSourceFile());\n        }\n    }\n    \n    \n    protected boolean isEnabled(JFRSnapshotsContainer container) {\n        return true;\n    }\n    \n    protected void initialize() {\n        if (tracksSelection) super.initialize();\n    }\n    \n    \n    private AddJFRSnapshotAction() {\n        super(JFRSnapshotsContainer.class);\n        putValue(NAME, NbBundle.getMessage(AddJFRSnapshotAction.class, \"LBL_Add_VM_Coredump\"));  // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(AddJFRSnapshotAction.class, \"ToolTip_Add_VM_Coredump\")); // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/Bundle.properties",
    "content": "#\n# Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nLBL_Add_VM_Coredump=Add &JFR Snapshot...\n\nToolTip_Add_VM_Coredump=Add JFR Snapshot\n\nLBL_Core_Dumps=JFR Snapshots\n\nTitle_Add_VM_Coredump=Add JFR Snapshot\n\nLBL_Select_VM_Coredump=Select JFR Snapshot\n\nLBL_VM_Coredump_file=&JFR Snapshot file\\:\n\nLBL_Browse=&Browse...\n\nLBL_Display_name=Display &name\\:\n\nLBL_Delete_source_file=&Delete source file\n\nLBL_OK=OK\n\nLBL_Inspecting_core_dump=Inspecting JFR Snapshot\n\nMSG_not_valid_core_dump={0} is not a valid JFR snapshot!\n\nMSG_Core_dump_already_added=<html>JFR snapshot {0} already added as {1}</html>\n\nMSG_Adding=Adding {0}...\n\nTitle_Unresolved_CoreDumps=Could Not Load JFR Snapshot\n\nMSG_Unresolved_CoreDumps=<html><b>These JFR snapshots could not be found:</b><br>Do you want to load them on next VisualVM session?<br><br></html>\n\n\nMSG_JFR_Dump=&Dump JFR\n\nLBL_JFR_Dump=Dump JFR Data\n\nMSG_Cannot_Take_JFR_dump=Cannot take JFR dump for {0}\n\nMSG_Cannot_Stop_JFR=Cannot stop JFR recording for {0}\n\nLBL_Creating_JFR_Dump=Creating JFR Dump...\n\nLBL_Loading_JFR_Dump=Loading JFR dump...\n\nLBL_Loading_JFR_Dump_failed=Loading JFR Dump failed.\n\nLBL_Loading_JFR_Dump_failed2=Loading failed: {0}\n\nMSG_Opening_JFR_Dump=Opening JFR Dump...\n\nMSG_Opening_JFR_dump_failed=Opening JFR dump failed.\n\nCAPTION_Remote_JFR_Dump=Remote JFR Dump\n\nMSG_Remote_JFR_dump=&JFR dump file to be created on the remote system\\:\n\nMSG_Dump_failed=Failed to take remote JFR dump for this application.\n\nMSG_Dump_save_failed=Failed to create remote JFR dump and save it\\:\\n{0}\n\nMSG_Dump_ok=JFR dump has been created and saved on the remote system:\\n{0}\\n\\nMove the file to the local system and use File | Load... action to open it.\n\nMSG_JFR_Start=Start &JFR\n\nLBL_JFR_Start=Start JFR Recording\n\nLBL_Starting_JFR_Recording=Starting JFR Recording...\n\nMSG_JFR_Stop=Stop J&FR\n\nLBL_JFR_Stop=Stop JFR Recording\n\nLBL_Stopping_JFR_Recording=Stopping JFR Recording...\n\nArgument_Start_ShortDescr=start JFR of the provided process\n\nArgument_Dump_ShortDescr=dump JFR data of the provided process\n\nArgument_Stop_ShortDescr=stop JFR of the provided process\n\nMSG_NO_APP_PID = Cannot find application with pid {0}.\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/JFRArguments.java",
    "content": "/*\n * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.impl;\n\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.ApplicationFinder;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.jfr.JFRSnapshotSupport;\nimport org.netbeans.api.sendopts.CommandException;\nimport org.netbeans.spi.sendopts.Env;\nimport org.netbeans.spi.sendopts.Option;\nimport org.netbeans.spi.sendopts.OptionProcessor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=OptionProcessor.class)\npublic class JFRArguments extends OptionProcessor {\n    \n    private static final String START_LONG_NAME = \"start-jfr\";                  // NOI18N\n    private static final Option START_JFR_ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, START_LONG_NAME), \"org.graalvm.visualvm.jfr.impl.Bundle\", \"Argument_Start_ShortDescr\"); // NOI18N\n    private static final String DUMP_LONG_NAME = \"dump-jfr\";                    // NOI18N\n    private static final Option DUMP_JFR_ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, DUMP_LONG_NAME), \"org.graalvm.visualvm.jfr.impl.Bundle\", \"Argument_Dump_ShortDescr\"); // NOI18N\n    private static final String STOP_LONG_NAME = \"stop-jfr\";                    // NOI18N\n    private static final Option STOP_JFR_ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, STOP_LONG_NAME), \"org.graalvm.visualvm.jfr.impl.Bundle\", \"Argument_Stop_ShortDescr\"); // NOI18N\n    \n    \n    @Override\n    protected Set<Option> getOptions() {\n        Set<Option> options = new HashSet<>();\n        options.add(START_JFR_ARGUMENT);\n        options.add(DUMP_JFR_ARGUMENT);\n        options.add(STOP_JFR_ARGUMENT);\n        return options;\n    }\n    \n    @Override\n    protected void process(Env env, Map<Option, String[]> maps) throws CommandException {\n        String[] startJFR = maps.get(START_JFR_ARGUMENT);\n        if (startJFR != null) {\n            final String[] _startJFR = startJFR.length == 1 ? startJFR[0].split(\"@\") : null; // NOI18N\n            if (_startJFR != null && _startJFR.length == 2) startJFR[0] = _startJFR[0];\n            new Finder(startJFR, START_LONG_NAME) {\n                @Override\n                public void found(final Application application) {\n                    VisualVM.getInstance().runTask(new Runnable() {\n                        public void run() {\n                            if (JFRSnapshotSupport.supportsJfrStart(application)) {\n                                String params = _startJFR != null && _startJFR.length == 2 ? _startJFR[1] : null;\n                                JFRSnapshotSupport.jfrStartRecording(application, params);\n                            }\n                        }\n                    });\n                }\n            }.find();\n            return;\n        }\n        \n        final String[] dumpJFR = maps.get(DUMP_JFR_ARGUMENT);\n        final String[] stopJFR = maps.get(STOP_JFR_ARGUMENT);\n        if (dumpJFR != null) {\n            new Finder(dumpJFR, DUMP_LONG_NAME) {\n                @Override\n                public void found(final Application application) {\n                    VisualVM.getInstance().runTask(new Runnable() {\n                        public void run() {\n                            if (JFRSnapshotSupport.supportsJfrDump(application)) {\n                                boolean stop = stopJFR != null && stopJFR.length == 1 && stopJFR[0].equals(dumpJFR[0]);\n                                if (stop && !JFRSnapshotSupport.supportsJfrStop(application)) stop = false;\n                                JFRSnapshotSupport.takeJfrDump(application, stop, true);\n                            }\n                        }\n                    });\n                }\n            }.find();\n            return;\n        }\n        \n        if (stopJFR != null) {\n            new Finder(stopJFR, STOP_LONG_NAME) {\n                @Override\n                public void found(final Application application) {\n                    VisualVM.getInstance().runTask(new Runnable() {\n                        public void run() {\n                            if (JFRSnapshotSupport.supportsJfrStop(application)) {\n                                JFRSnapshotSupport.jfrStopRecording(application);\n                            }\n                        }\n                    });\n                }\n            }.find();\n        }\n    }\n    \n    \n    private static abstract class Finder extends ApplicationFinder {\n        \n        Finder(String[] pids, String longName) throws CommandException {\n            super(resolvePid(pids, longName));\n        }\n        \n        \n        public final void notFound(int pid, String id) {\n            NotifyDescriptor desc = new NotifyDescriptor.Message(NbBundle.getMessage(JFRArguments.class, \"MSG_NO_APP_PID\", new Object[] { Integer.toString(pid) }), NotifyDescriptor.WARNING_MESSAGE); // NOI18N\n            DialogDisplayer.getDefault().notifyLater(desc);\n        }\n        \n        \n        private static int resolvePid(String[] pids, String longName) throws CommandException {\n            if (pids.length == 1) {\n                try {\n                    return Integer.valueOf(pids[0]);\n                } catch (NumberFormatException e) {\n                    throw new CommandException(0, \"Incorrect pid format for --\" + longName + \": \" + e.getMessage()); // NOI18N\n                }\n            } else {\n                throw new CommandException(0, \"--\" + longName + \" requires exactly one value\"); // NOI18N\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/JFRDumpAction.java",
    "content": "/*\n * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.impl;\n\n/**\n *\n * @author Tomas Hurka\n */\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.core.ui.actions.MultiDataSourceAction;\nimport org.graalvm.visualvm.jfr.JFRSnapshotSupport;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nclass JFRDumpAction extends MultiDataSourceAction<DataSource> {\n\n    private Set<Application> lastSelectedApplications = new HashSet<>();\n    private final PropertyChangeListener stateListener = new PropertyChangeListener() {\n        public void propertyChange(PropertyChangeEvent evt) {\n            updateState(ActionUtils.getSelectedDataSources());\n        }\n    };\n\n    private static JFRDumpAction INSTANCE;\n\n    public static synchronized JFRDumpAction instance() {\n        if (INSTANCE == null) {\n            INSTANCE = new JFRDumpAction();\n        }\n        return INSTANCE;\n    }\n\n    protected void actionPerformed(Set<DataSource> dataSources, ActionEvent actionEvent) {\n        for (DataSource dataSource : dataSources) {\n            if (dataSource instanceof Application) {\n                Application application = (Application) dataSource;\n                boolean tagged = (actionEvent.getModifiers() & Toolkit.\n                        getDefaultToolkit().getMenuShortcutKeyMask()) != 0;\n                if (application.isLocalApplication()) {\n                    JFRSnapshotSupport.takeJfrDump(application, false, !tagged);\n                } else {\n                    JFRSnapshotSupport.takeRemoteJfrDump(application, null, !tagged);\n                }\n            }\n        }\n    }\n\n    protected boolean isEnabled(Set<DataSource> dataSources) {\n        for (DataSource dataSource : dataSources) {\n            if (dataSource instanceof Application) {\n                // TODO: Listener should only be registered when JFR dump is supported for the application\n                Application application = (Application) dataSource;\n                lastSelectedApplications.add(application);\n                application.addPropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n                if (application.getState() != Stateful.STATE_AVAILABLE) {\n                    return false;\n                }\n                if (application.isLocalApplication()) {\n                    if (!JFRSnapshotSupport.supportsJfrDump(application)) {\n                        return false;\n                    }\n                } else {\n                    if (!JFRSnapshotSupport.supportsRemoteJfrDump(application)) {\n                        return false;\n                    }\n                }\n            } else {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    protected void updateState(Set<DataSource> dataSources) {\n        if (!lastSelectedApplications.isEmpty()) {\n            for (Application application : lastSelectedApplications) {\n                application.removePropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n            }\n        }\n        lastSelectedApplications.clear();\n        super.updateState(dataSources);\n    }\n\n    private JFRDumpAction() {\n        super(DataSource.class);\n        putValue(NAME, NbBundle.getMessage(JFRDumpAction.class, \"MSG_JFR_Dump\")); // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(JFRDumpAction.class, \"LBL_JFR_Dump\"));    // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/JFRDumpImpl.java",
    "content": "/*\n * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.impl;\n\nimport java.io.File;\nimport java.io.IOException;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JFRDumpImpl extends JFRSnapshot {\n\n    JFRDumpImpl(File file, DataSource master) throws IOException {\n        super(file, master);\n    }\n\n    void forceViewClosable(boolean closable) {\n        getStorage().setCustomProperty(PROPERTY_VIEW_CLOSABLE, Boolean.toString(closable));\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/JFRParameters.java",
    "content": "/*\n * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.impl;\n\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRParameters {\n    \n    private static final Logger LOGGER = Logger.getLogger(JFRParameters.class.getName());\n    \n    \n    private static final String FILE = \"settings-file\";                         // NOI18N\n    \n    static final String NAME = \"name\";                                          // NOI18N\n    static final String SETTINGS = \"settings\";                                  // NOI18N\n    \n    \n    private final Map<String, String> parameters;\n    \n    \n    private JFRParameters(String parametersS) {\n        if (parametersS == null || parametersS.isEmpty()) {\n            parameters = null;\n        } else {\n            parameters = new HashMap<>();\n            parseParameters(parametersS, parameters);\n        }\n    }\n    \n    \n    static JFRParameters parse(String parameters) {\n        return new JFRParameters(parameters);\n    }\n    \n    \n    String get(String key) {\n        return parameters == null ? null : parameters.get(key);\n    }\n    \n    \n    public String toString() {\n        return parameters == null ? \"[no parameters]\" : parameters.toString();  // NOI18N\n    }\n    \n    \n    private static void parseParameters(String parametersS, Map<String, String> parameters) {\n        if (parametersS.startsWith(FILE + \"=\")) {                               // NOI18N\n            // settings defined in file\n            parseParametersFile(decode(parametersS.substring(FILE.length() + 1)), parameters);\n        } else {\n            for (String parameter : parametersS.split(\",\")) {                   // NOI18N\n\n                // name\n                int idx = parameter.indexOf(NAME + \"=\");                        // NOI18N\n                if (idx == 0) parameters.put(NAME, decode(parameter.substring(NAME.length() + 1)));\n\n                // settings\n                idx = parameter.indexOf(SETTINGS + \"=\");                        // NOI18N\n                if (idx == 0) parameters.put(SETTINGS, decode(parameter.substring(SETTINGS.length() + 1)));\n\n            }\n        }\n    }\n    \n    private static void parseParametersFile(String file, Map<String, String> parameters) {\n        Properties properties = loadProperties(file);\n        \n        // name\n        String prop = properties.getProperty(NAME);\n        if (prop != null) parameters.put(NAME, decode(prop));\n        \n        // settings\n        prop = properties.getProperty(SETTINGS);\n        if (prop != null) parameters.put(SETTINGS, decode(prop));\n    }\n    \n    protected static Properties loadProperties(String file) {\n        Properties properties = new Properties();\n        \n        try (InputStreamReader isr = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) {\n            properties.load(isr);\n        } catch (IOException e) {\n            LOGGER.log(Level.WARNING, \"Failed to read JFR parameters\", e);      // NOI18N\n        }\n        \n        return properties;\n    }\n    \n    private static String decode(String value) {\n        value = value.replace(\"%27\", \"'\");                                      // NOI18N\n        value = value.replace(\"%22\", \"\\\"\");                                     // NOI18N\n        value = value.replace(\"%20\", \" \");                                      // NOI18N\n        value = value.replace(\"%2C\", \",\");                                      // NOI18N\n        return value;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/JFRRecordingProvider.java",
    "content": "/*\n * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Properties;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTextField;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.jfr.JFRSnapshotSupport;\nimport org.graalvm.visualvm.tools.jfr.JfrModel;\nimport org.graalvm.visualvm.tools.jfr.JfrModelFactory;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic class JFRRecordingProvider {\n\n    private final static Logger LOGGER = Logger.getLogger(JFRRecordingProvider.class.getName());\n\n    public void jfrStartRecording(Application application) {\n        jfrStartRecording(application, null);\n    }\n    \n    public void jfrStartRecording(Application application, String params) {\n        JFRParameters parameters = JFRParameters.parse(params);\n        jfrStartRecording(application,\n                          parameters.get(JFRParameters.NAME),\n                          parameters.get(JFRParameters.SETTINGS),\n                          null, // delay\n                          null, // duration\n                          null, // disk\n                          null, // path\n                          null, // maxAge\n                          null, // maxSize\n                          null  // dumpOnExit\n                         );\n    }\n    \n    public void jfrStartRecording(final Application application, final String name,\n                                  final String settings, final String delay,\n                                  final String duration, final Boolean disk,\n                                  final String path, final String maxAge,\n                                  final String maxSize, final Boolean dumpOnExit) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                Jvm jvm = JvmFactory.getJVMFor(application);\n                ProgressHandle pHandle = null;\n                try {\n                    pHandle = ProgressHandle.createHandle(NbBundle.getMessage(JFRRecordingProvider.class, \"LBL_Starting_JFR_Recording\"));    // NOI18N\n                    pHandle.setInitialDelay(0);\n                    pHandle.start();\n                    String[] _settings = settings == null ? null : new String[] { settings };\n                    if (!jvm.startJfrRecording(name, _settings, delay, duration,\n                            disk, path, maxAge, maxSize, dumpOnExit)) {\n                        notifyJfrDumpFailed(application);\n                    } else {\n                        Set<DataSource> ds = ActionUtils.getSelectedDataSources();\n                        JFRDumpAction.instance().updateState(ds);\n                        JFRStartAction.instance().updateState(ds);\n                        JFRStopAction.instance().updateState(ds);\n                    }\n                } finally {\n                    if (pHandle != null) {\n                        SwingUtilities.invokeLater(pHandle::finish);\n                    }\n                }\n            }\n        });\n    }\n\n    public void remoteJfrStartRecording(Application application) {\n        jfrStartRecording(application);\n    }\n\n    public void jfrStopRecording(Application application) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                Jvm jvm = JvmFactory.getJVMFor(application);\n                ProgressHandle pHandle = null;\n                try {\n                    pHandle = ProgressHandle.createHandle(NbBundle.getMessage(JFRRecordingProvider.class, \"LBL_Stopping_JFR_Recording\"));    // NOI18N\n                    pHandle.setInitialDelay(0);\n                    pHandle.start();\n                    if (!jvm.stopJfrRecording()) {\n                        notifyJfrStopFailed(application);\n                    } else {\n                        Set<DataSource> ds = ActionUtils.getSelectedDataSources();\n                        JFRDumpAction.instance().updateState(ds);\n                        JFRStartAction.instance().updateState(ds);\n                        JFRStopAction.instance().updateState(ds);\n                    }\n                } finally {\n                    if (pHandle != null) {\n                        SwingUtilities.invokeLater(pHandle::finish);\n                    }\n                }\n            }\n        });\n    }\n\n    public void remoteJfrStopRecording(Application application) {\n        jfrStopRecording(application);\n    }\n\n    public void createJfrDump(final Application application, final boolean stopJfr, final boolean openView) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                Jvm jvm = JvmFactory.getJVMFor(application);\n                List<Long> recordings = Collections.emptyList();\n                if (jvm != null) {\n                    recordings = jvm.jfrCheck();\n                }\n                if (recordings.isEmpty()) {\n                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(NbBundle.getMessage(JFRRecordingProvider.class,\n                            \"MSG_Cannot_Take_JFR_dump\", DataSourceDescriptorFactory. // NOI18N\n                                    getDescriptor(application).getName()), NotifyDescriptor.ERROR_MESSAGE));\n                    return;\n                }\n\n                ProgressHandle pHandle = null;\n                try {\n                    pHandle = ProgressHandle.createHandle(NbBundle.getMessage(JFRRecordingProvider.class, \"LBL_Creating_JFR_Dump\"));    // NOI18N\n                    pHandle.setInitialDelay(0);\n                    pHandle.start();\n                    try {\n                        File snapshotDir = application.getStorage().getDirectory();\n                        String name = JFRSnapshotSupport.getCategory().createFileName();\n                        File file = new File(snapshotDir, name);\n                        jvm.takeJfrDump(recordings.get(0), file.getAbsolutePath());\n                        if (file.isFile()) {\n                            final JFRDumpImpl jfrDump = new JFRDumpImpl(file, application);\n                            application.getRepository().addDataSource(jfrDump);\n                            if (openView) {\n                                DataSourceWindowManager.sharedInstance().openDataSource(jfrDump);\n                            }\n                            if (stopJfr) jfrStopRecording(application);\n                        } else {\n                            notifyJfrDumpFailed(application);\n                        }\n                    } catch (IOException ex) {\n                        LOGGER.log(Level.INFO, \"createJFRDump-Application\", ex); // NOI18N\n                        notifyJfrDumpFailed(application);\n                    }\n                } finally {\n                    if (pHandle != null) {\n                        SwingUtilities.invokeLater(pHandle::finish);\n                    }\n                }\n            }\n        });\n    }\n\n    public void createRemoteJfrDump(final Application application, final String dumpFile,\n            final boolean customizeDumpFile) {\n\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                JfrModel model = JfrModelFactory.getJFRFor(application);\n                if (model == null) {\n                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(NbBundle.getMessage(JFRRecordingProvider.class,\n                            \"MSG_Dump_failed\"), NotifyDescriptor.ERROR_MESSAGE)); // NOI18N\n                    return;\n                }\n                List<Long> recordings = model.jfrCheck();\n                if (recordings.isEmpty()) {\n                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(NbBundle.getMessage(JFRRecordingProvider.class,\n                            \"MSG_Cannot_Take_JFR_dump\", DataSourceDescriptorFactory. // NOI18N\n                                    getDescriptor(application).getName()), NotifyDescriptor.ERROR_MESSAGE));\n                    return;\n                }\n                String file = dumpFile;\n                if (file == null) {\n                    file = defineRemoteFile(application, customizeDumpFile);\n                }\n                if (file == null) {\n                    return;\n                }\n\n                if (model.takeJfrDump(recordings.get(0), file) != null) {\n                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(NbBundle.getMessage(JFRRecordingProvider.class,\n                            \"MSG_Dump_ok\", file), NotifyDescriptor.INFORMATION_MESSAGE)); // NOI18N\n                } else {\n                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(NbBundle.getMessage(JFRRecordingProvider.class,\n                            \"MSG_Dump_save_failed\", file), NotifyDescriptor.ERROR_MESSAGE)); // NOI18N\n                }\n            }\n        });\n    }\n\n    private static String defineRemoteFile(Application app, boolean customizeDumpFile) {\n        final String[] path = new String[1];\n        path[0] = defaultJfrDumpPath(app);\n\n        if (customizeDumpFile) {\n            try {\n                SwingUtilities.invokeAndWait(new Runnable() {\n                    public void run() {\n                        JLabel label = new JLabel();\n                        Mnemonics.setLocalizedText(label, NbBundle.getMessage(JFRRecordingProvider.class, \"MSG_Remote_JFR_dump\")); // NOI18N\n                        label.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));\n                        JTextField field = new JTextField();\n                        label.setLabelFor(field);\n                        field.setText(path[0]);\n                        Dimension dim = field.getPreferredSize();\n                        dim.width = 350;\n                        field.setPreferredSize(dim);\n                        field.selectAll();\n                        JPanel selector = new JPanel(new BorderLayout());\n                        selector.setBorder(BorderFactory.createEmptyBorder(15, 10, 5, 10));\n                        selector.add(label, BorderLayout.NORTH);\n                        selector.add(field, BorderLayout.SOUTH);\n\n                        DialogDescriptor dd = new DialogDescriptor(selector,\n                                NbBundle.getMessage(JFRRecordingProvider.class,\n                                        \"CAPTION_Remote_JFR_Dump\"), true, null); // NOI18N\n                        Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n                        d.pack();\n                        d.setVisible(true);\n\n                        path[0] = dd.getValue() == DialogDescriptor.OK_OPTION\n                                ? field.getText() : null;\n                    }\n                });\n            } catch (Throwable t) {\n                path[0] = null;\n            }\n        }\n\n        return path[0];\n    }\n\n    private static String defaultJfrDumpPath(Application app) {\n        String fileName = JFRSnapshotSupport.getCategory().createFileName();\n\n        Jvm jvm = JvmFactory.getJVMFor(app);\n        if (jvm == null) return fileName;\n        Properties sysprops = jvm.getSystemProperties();\n        if (sysprops == null) return fileName;\n        String jfrDumpTarget = getJfrDumpTarget(sysprops);\n        if (jfrDumpTarget == null || jfrDumpTarget.isEmpty()) {\n            return fileName;\n        }\n\n        String pathsep = sysprops.getProperty(\"file.separator\"); // NOI18N\n        if (!jfrDumpTarget.endsWith(pathsep)) {\n            jfrDumpTarget += pathsep;\n        }\n        return jfrDumpTarget + fileName;\n    }\n\n    // OS codes listed in org.graalvm.visualvm.lib.jfluid.global.Platform.getOperatingSystem()\n    private static String getJfrDumpTarget(Properties sysprops) {\n        String targetDir = null;\n\n        // Select directory based on target OS\n        String osName = sysprops.getProperty(\"os.name\"); // NOI18N\n        if (osName != null) {\n            if (osName.equals(\"Solaris\") || osName.startsWith(\"SunOS\")) // NOI18N\n            {\n                targetDir = sysprops.getProperty(\"user.home\"); // NOI18N\n            } else {\n                targetDir = sysprops.getProperty(\"java.io.tmpdir\"); // NOI18N\n            }\n        }\n\n        // Fallback to current working directory\n        if (targetDir == null) {\n            targetDir = sysprops.getProperty(\"user.dir\"); // NOI18N\n        }\n        return targetDir;\n    }\n\n    public void initialize() {\n        DataSourceRepository.sharedInstance().addDataChangeListener(new SnapshotListener(), Snapshot.class);\n        DataSourceRepository.sharedInstance().addDataChangeListener(new ApplicationListener(), Application.class);\n    }\n\n    private void processNewSnapshot(Snapshot snapshot) {\n        if (snapshot instanceof JFRSnapshotImpl) {\n            return;\n        }\n        boolean appSnapshot = snapshot instanceof ApplicationSnapshot;\n        File snapshotFile = snapshot.getFile();\n        if (snapshotFile != null && snapshotFile.isDirectory()) {\n            File[] files = snapshotFile.listFiles(JFRSnapshotSupport.getCategory().getFilenameFilter());\n            if (files == null) {\n                return;\n            }\n            Set<JFRDumpImpl> jfrDumps = new HashSet<>();\n            for (File file : files) {\n                try {\n                    JFRDumpImpl jfrDump = new JFRDumpImpl(file, snapshot);\n                    if (appSnapshot) {\n                        jfrDump.forceViewClosable(true);\n                    }\n                    jfrDumps.add(jfrDump);\n                } catch (IOException ex) {\n\n                }\n            }\n            snapshot.getRepository().addDataSources(jfrDumps);\n        }\n    }\n\n    private void processNewApplication(Application application) {\n        Storage storage = application.getStorage();\n        if (storage.directoryExists()) {\n            File[] files = storage.getDirectory().listFiles(JFRSnapshotSupport.getCategory().getFilenameFilter());\n            if (files == null) {\n                return;\n            }\n            Set<JFRDumpImpl> jfrDumps = new HashSet<>();\n            for (File file : files) {\n                try {\n                    jfrDumps.add(new JFRDumpImpl(file, application));\n                } catch (IOException ex) {\n\n                }\n            }\n            application.getRepository().addDataSources(jfrDumps);\n        }\n    }\n\n    private void notifyJfrDumpFailed(final DataSource dataSource) {\n        String displayName = DataSourceDescriptorFactory.getDescriptor(dataSource).getName();\n        DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(NbBundle.getMessage(JFRRecordingProvider.class,\n                \"MSG_Cannot_Take_JFR_dump\", displayName), // NOI18N\n                NotifyDescriptor.ERROR_MESSAGE));\n    }\n\n    private void notifyJfrStopFailed(final DataSource dataSource) {\n        String displayName = DataSourceDescriptorFactory.getDescriptor(dataSource).getName();\n        DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(NbBundle.getMessage(JFRRecordingProvider.class,\n                \"MSG_Cannot_Stop_JFR\", displayName), // NOI18N\n                NotifyDescriptor.ERROR_MESSAGE));\n    }\n\n    private class SnapshotListener implements DataChangeListener<Snapshot> {\n\n        public void dataChanged(DataChangeEvent<Snapshot> event) {\n            final Set<Snapshot> snapshots = event.getAdded();\n            if (!snapshots.isEmpty()) {\n                VisualVM.getInstance().runTask(new Runnable() {\n                    public void run() {\n                        for (Snapshot snapshot : snapshots) {\n                            processNewSnapshot(snapshot);\n                        }\n                    }\n                });\n            }\n        }\n\n    }\n\n    private class ApplicationListener implements DataChangeListener<Application> {\n\n        public void dataChanged(DataChangeEvent<Application> event) {\n            final Set<Application> applications = event.getAdded();\n            if (!applications.isEmpty()) {\n                VisualVM.getInstance().runTask(new Runnable() {\n                    public void run() {\n                        for (Application application : applications) {\n                            processNewApplication(application);\n                        }\n                    }\n                });\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/JFRSnapshotCategory.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr.impl;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JFRSnapshotCategory extends SnapshotCategory<JFRSnapshot> {\n    \n    private static final Logger LOGGER = Logger.getLogger(JFRSnapshotCategory.class.getName());\n    \n    private static final String NAME = NbBundle.getMessage(JFRSnapshotCategory.class, \"LBL_Core_Dumps\");   // NOI18N\n    private static final String PREFIX = \"jfr\";   // NOI18N\n    private static final String SUFFIX = \".jfr\";  // NOI18N\n    \n    \n    public JFRSnapshotCategory() {\n        super(NAME, JFRSnapshot.class, PREFIX, SUFFIX, 40);\n    }\n    \n    \n    @Override\n    public boolean supportsOpenSnapshot() {\n        return true;\n    }\n    \n    @Override\n    public void openSnapshot(File file) {\n        try {\n            JFRSnapshot snapshot = new JFRSnapshotImpl(file);\n            DataSourceWindowManager.sharedInstance().openDataSource(snapshot); // TODO: instance should be created by JFRSnapshotProvider!\n        } catch (IOException ex) {\n            LOGGER.log(Level.SEVERE, \"Error opening JFR snapshot\", ex); // NOI18N\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/JFRSnapshotConfigurator.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr.impl;\n\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.File;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTextField;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.jfr.JFRSnapshotSupport;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n * \n */\nclass JFRSnapshotConfigurator extends JPanel {\n\n  private boolean internalChange = false;\n\n  public static JFRSnapshotConfigurator defineJFRSnapshot() {\n    JFRSnapshotConfigurator hc = getDefault();\n    hc.setupDefineJFRSnapshot();\n    \n    final DialogDescriptor dd = new DialogDescriptor(hc, NbBundle.getMessage(JFRSnapshotConfigurator.class, \"Title_Add_VM_Coredump\"), true, new Object[] { // NOI18N\n      hc.okButton, DialogDescriptor.CANCEL_OPTION }, hc.okButton, 0, null, null);\n    final Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n    d.pack();\n    d.setVisible(true);\n    \n    if (dd.getValue() == hc.okButton) return hc;\n    else return null;\n  }\n  \n  public String getJFRSnapshotFile() {\n    return jfrSnapshotFileField.getText().trim();\n  }\n  \n  public String getDisplayname() {\n    return displaynameField.getText().trim();\n  }\n  \n  public boolean deleteSourceFile() {\n      return deleteSourceCheckbox.isSelected();\n  }\n  \n  private static JFRSnapshotConfigurator defaultInstance;\n  \n  private JFRSnapshotConfigurator() {\n    initComponents();\n    update();\n  }\n  \n  private static JFRSnapshotConfigurator getDefault() {\n    if (defaultInstance == null) defaultInstance = new JFRSnapshotConfigurator();\n    return defaultInstance;\n  }\n  \n  private void setupDefineJFRSnapshot() {\n    jfrSnapshotFileField.setEnabled(true);\n    displaynameCheckbox.setSelected(false);\n    displaynameCheckbox.setEnabled(true);\n    jfrSnapshotFileField.setText(\"\");\n    displaynameField.setText(\"\");\n    deleteSourceCheckbox.setSelected(false);\n  }\n  \n  private void update() {\n    if (internalChange) return;\n    SwingUtilities.invokeLater(new Runnable() {\n      public void run() {\n        String jfrSnapshotName = getJFRSnapshotFile();\n        File jfrSnapshotFile = new File(jfrSnapshotName);\n        \n        if (!displaynameCheckbox.isSelected()) {\n          internalChange = true;\n          File file = new File(jfrSnapshotName);\n          if (file.isFile()) displaynameField.setText(file.getName());\n          internalChange = false;\n        }\n        \n        String displayname = getDisplayname();\n        displaynameField.setEnabled(displaynameCheckbox.isSelected());\n        \n        okButton.setEnabled(jfrSnapshotFile.exists() && jfrSnapshotFile.isFile() && !displayname.isEmpty());\n      }\n    });\n  }\n\n  private void chooseJFRSnapshot() {\n      JFileChooser chooser = new JFileChooser(new File(getJFRSnapshotFile()));\n      chooser.setDialogTitle(NbBundle.getMessage(JFRSnapshotConfigurator.class, \"LBL_Select_VM_Coredump\"));    // NOI18N\n      chooser.setAcceptAllFileFilterUsed(false);\n      chooser.setFileFilter(JFRSnapshotSupport.getCategory().getFileFilter());\n      int returnVal = chooser.showOpenDialog(WindowManager.getDefault().getMainWindow());\n      if (returnVal == JFileChooser.APPROVE_OPTION) {\n          jfrSnapshotFileField.setText(chooser.getSelectedFile().getAbsolutePath());\n      }\n  }\n  \n  private void initComponents() {\n    setLayout(new GridBagLayout());\n    GridBagConstraints constraints;\n    \n    // jfrSnapshotFileLabel\n    jfrSnapshotFileLabel = new JLabel();\n    Mnemonics.setLocalizedText(jfrSnapshotFileLabel, NbBundle.getMessage(JFRSnapshotConfigurator.class, \"LBL_VM_Coredump_file\")); // NOI18N\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 0;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.EAST;\n    constraints.insets = new Insets(15, 10, 0, 0);\n    add(jfrSnapshotFileLabel, constraints);\n    \n    // jfrSnapshotFileField\n    jfrSnapshotFileField = new JTextField();\n    jfrSnapshotFileLabel.setLabelFor(jfrSnapshotFileField);\n    jfrSnapshotFileField.setPreferredSize(new Dimension(220, jfrSnapshotFileField.getPreferredSize().height));\n    jfrSnapshotFileField.getDocument().addDocumentListener(new DocumentListener() {\n      public void insertUpdate(DocumentEvent e)  { update(); }\n      public void removeUpdate(DocumentEvent e)  { update(); }\n      public void changedUpdate(DocumentEvent e) { update(); }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 1;\n    constraints.gridy = 0;\n    constraints.weightx = 1;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.HORIZONTAL;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(15, 5, 0, 0);\n    add(jfrSnapshotFileField, constraints);\n    \n    // jfrSnapshotFileButton\n    jfrSnapshotFileButton = new JButton();\n    Mnemonics.setLocalizedText(jfrSnapshotFileButton, NbBundle.getMessage(JFRSnapshotConfigurator.class, \"LBL_Browse\")); // NOI18N\n    jfrSnapshotFileButton.addActionListener(new ActionListener() {\n        public void actionPerformed(ActionEvent e) {\n            chooseJFRSnapshot();\n        }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 2;\n    constraints.gridy = 0;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(15, 5, 0, 10);\n    add(jfrSnapshotFileButton, constraints);\n    \n    // displaynameCheckbox\n    displaynameCheckbox = new JCheckBox();\n    Mnemonics.setLocalizedText(displaynameCheckbox, NbBundle.getMessage(JFRSnapshotConfigurator.class, \"LBL_Display_name\")); // NOI18N\n    displaynameCheckbox.addActionListener(new ActionListener() {\n      public void actionPerformed(ActionEvent e) { update(); }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 2;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(8, 10, 0, 0);\n    add(displaynameCheckbox, constraints);\n    \n    // displaynameField\n    displaynameField = new JTextField();\n    displaynameField.setPreferredSize(new Dimension(220, displaynameField.getPreferredSize().height));\n    displaynameField.getDocument().addDocumentListener(new DocumentListener() {\n      public void insertUpdate(DocumentEvent e)  { update(); }\n      public void removeUpdate(DocumentEvent e)  { update(); }\n      public void changedUpdate(DocumentEvent e) { update(); }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 1;\n    constraints.gridy = 2;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.HORIZONTAL;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(8, 5, 0, 10);\n    add(displaynameField, constraints);\n    \n    // deleteSourceCheckbox\n    deleteSourceCheckbox = new JCheckBox();\n    Mnemonics.setLocalizedText(deleteSourceCheckbox, NbBundle.getMessage(JFRSnapshotConfigurator.class, \"LBL_Delete_source_file\")); // NOI18N\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 3;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(18, 10, 0, 0);\n    add(deleteSourceCheckbox, constraints);\n    \n    // spacer\n    JPanel spacer = new JPanel(null);\n    spacer.setOpaque(false);\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 4;\n    constraints.weighty = 1;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.BOTH;\n    constraints.anchor = GridBagConstraints.NORTHWEST;\n    constraints.insets = new Insets(0, 0, 15, 0);\n    add(spacer, constraints);\n    \n    // okButton\n    okButton = new JButton(NbBundle.getMessage(JFRSnapshotConfigurator.class, \"LBL_OK\"));  // NOI18N\n    \n    // UI tweaks\n    displaynameCheckbox.setBorder(jfrSnapshotFileLabel.getBorder());\n    deleteSourceCheckbox.setBorder(jfrSnapshotFileLabel.getBorder());\n  }\n  \n  private JLabel jfrSnapshotFileLabel;\n  private JTextField jfrSnapshotFileField;\n  private JButton jfrSnapshotFileButton;\n  private JCheckBox displaynameCheckbox;\n  private JTextField displaynameField;\n  private JCheckBox deleteSourceCheckbox;\n  \n  private JButton okButton;\n  \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/JFRSnapshotDescriptorProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr.impl;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.JFRSnapshotDescriptor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JFRSnapshotDescriptorProvider extends AbstractModelProvider<DataSourceDescriptor,DataSource> {\n    \n    public DataSourceDescriptor createModelFor(DataSource ds) {\n        if (ds instanceof JFRSnapshot) {\n            return new JFRSnapshotDescriptor((JFRSnapshot)ds);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/JFRSnapshotImpl.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr.impl;\n\nimport java.io.File;\nimport java.io.IOException;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.JFRSnapshotSupport;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JFRSnapshotImpl extends JFRSnapshot {\n    \n    private final Storage storage;\n    \n    \n    JFRSnapshotImpl(File file) throws IOException {\n        this(file, new Storage());\n    }\n    \n    JFRSnapshotImpl(File file, Storage storage) throws IOException {\n        super(file);\n        this.storage = storage;\n    }\n    \n    public boolean supportsDelete() {\n        return false;\n    }\n    \n    \n    protected Storage createStorage() {\n        return storage;\n    }\n\n    public boolean supportsUserRemove() {\n        return true;\n    }\n    \n    \n    protected void remove() {\n        File file = getFile();\n        if (JFRSnapshotSupport.getStorageDirectory().equals(file.getParentFile())) Utils.delete(file, true);\n        setFile(null);\n        getStorage().deleteCustomPropertiesStorage();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/JFRSnapshotProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr.impl;\n\nimport java.awt.BorderLayout;\nimport java.io.File;\nimport java.io.FilenameFilter;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.explorer.ExplorerSupport;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.jfr.JFRSnapshotSupport;\nimport org.graalvm.visualvm.jfr.JFRSnapshotsContainer;\nimport org.graalvm.visualvm.lib.ui.SwingWorker;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JFRSnapshotProvider {\n    private static final Logger LOGGER = Logger.getLogger(JFRSnapshotProvider.class.getName());\n    \n    private static final String SNAPSHOT_VERSION = \"snapshot_version\";  // NOI18N\n    private static final String SNAPSHOT_VERSION_DIVIDER = \".\"; // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = \"1\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MINOR = \"0\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION = CURRENT_SNAPSHOT_VERSION_MAJOR + SNAPSHOT_VERSION_DIVIDER + CURRENT_SNAPSHOT_VERSION_MINOR;\n    \n    private static class SnapshotAdder extends SwingWorker {\n        volatile private ProgressHandle ph = null;\n        volatile private boolean success = false;\n        private JFRSnapshotImpl newSnapshot;\n        private Storage storage;\n        private String[] propNames, propValues;\n        \n        SnapshotAdder(JFRSnapshotImpl newSnapshot, Storage storage, String[] propNames, String[] propValues) {\n            this.newSnapshot = newSnapshot;\n            this.storage = storage;\n            this.propValues = propValues;\n            this.propNames = propNames;\n        }\n        \n        @Override\n        protected void doInBackground() {\n//            SaModel model = SaModelFactory.getSAAgentFor(newSnapshot);\n//            if (model != null) {\n                storage.setCustomProperties(propNames, propValues);\n                JFRSnapshotsContainer.sharedInstance().getRepository().addDataSource(newSnapshot);\n\n                success = true;\n//            }\n        }\n\n        @Override\n        protected void nonResponding() {\n            ph = ProgressHandle.createHandle(NbBundle.getMessage(JFRSnapshotProvider.class, \"LBL_Inspecting_core_dump\"));   // NOI18N\n            ph.start();\n        }\n\n        @Override\n        protected void done() {\n            if (ph != null) {\n                ph.finish();\n            }\n            if (!success) {\n                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(NbBundle.getMessage(JFRSnapshotProvider.class, \"MSG_not_valid_core_dump\", newSnapshot.getFile().getAbsolutePath())));  // NOI18N\n            }\n        }\n    }\n    \n    static void createJFRSnapshot(final String jfrSnapshotFile, final String displayName, final boolean deleteJFRSnapshot) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                createJFRSnapshotImpl(jfrSnapshotFile, displayName, deleteJFRSnapshot);\n            }\n        });\n    }\n    \n    private static void createJFRSnapshotImpl(String jfrSnapshotFile, final String displayName, boolean deleteJFRSnapshot) {\n        // TODO: check if the same JFR snapshot isn't already imported (can happen for moved coredumps)\n        final JFRSnapshotImpl knownJFRSnapshot = getJFRSnapshotByFile(new File(jfrSnapshotFile));\n        if (knownJFRSnapshot != null) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    ExplorerSupport.sharedInstance().selectDataSource(knownJFRSnapshot);\n                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.\n                            Message(NbBundle.getMessage(JFRSnapshotProvider.class,\n                            \"MSG_Core_dump_already_added\", new Object[] {displayName, // NOI18N\n                            DataSourceDescriptorFactory.getDescriptor(knownJFRSnapshot).\n                            getName()}), NotifyDescriptor.ERROR_MESSAGE));\n                }\n            });\n            return;\n        }\n        \n        if (deleteJFRSnapshot) {\n            ProgressHandle pHandle = null;\n            try {\n                pHandle = ProgressHandle.createHandle(NbBundle.getMessage(JFRSnapshotProvider.class, \"MSG_Adding\", displayName));   // NOI18N\n                pHandle.setInitialDelay(0);\n                pHandle.start();\n                \n                File file = new File(jfrSnapshotFile);\n                File copy = Utils.getUniqueFile(JFRSnapshotSupport.getStorageDirectory(), file.getName());\n                if (Utils.copyFile(file, copy)) {\n                    jfrSnapshotFile = copy.getAbsolutePath();\n                    if (!file.delete()) file.deleteOnExit();\n                }\n            } finally {\n                final ProgressHandle pHandleF = pHandle;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { if (pHandleF != null) pHandleF.finish(); }\n                });\n            }\n        }\n        \n        final String[] propNames = new String[] {\n            SNAPSHOT_VERSION,\n            Snapshot.PROPERTY_FILE,\n            DataSourceDescriptor.PROPERTY_NAME };\n        final String[] propValues = new String[] {\n            CURRENT_SNAPSHOT_VERSION,\n            jfrSnapshotFile,\n            displayName\n        };\n\n        File customPropertiesStorage = Utils.getUniqueFile(JFRSnapshotSupport.getStorageDirectory(), new File(jfrSnapshotFile).getName(), Storage.DEFAULT_PROPERTIES_EXT);\n        Storage storage = new Storage(customPropertiesStorage.getParentFile(), customPropertiesStorage.getName());\n        \n        try {\n            JFRSnapshotImpl newJFRSnapshot = new JFRSnapshotImpl(new File(jfrSnapshotFile), storage);\n            new SnapshotAdder(newJFRSnapshot, storage, propNames, propValues).execute();\n        } catch (Exception e) {\n            LOGGER.log(Level.SEVERE, \"Error creating JFR snapshot\", e); // NOI18N\n        }\n    }\n    \n    private static JFRSnapshotImpl getJFRSnapshotByFile(File file) {\n        if (!file.isFile()) return null;\n        Set<JFRSnapshotImpl> knownJFRSnapshots = DataSourceRepository.sharedInstance().getDataSources(JFRSnapshotImpl.class);\n        for (JFRSnapshotImpl knownJFRSnapshot : knownJFRSnapshots)\n            if (knownJFRSnapshot.getFile().equals(file)) return knownJFRSnapshot;\n        return null;\n    }\n    \n    private void initPersistedJFRSnapshots() {\n        if (!JFRSnapshotSupport.storageDirectoryExists()) return;\n        \n        File[] files = JFRSnapshotSupport.getStorageDirectory().listFiles(new FilenameFilter() {\n            public boolean accept(File dir, String name) {\n                return name.endsWith(Storage.DEFAULT_PROPERTIES_EXT);\n            }\n        });\n        \n        Set<File> unresolvedJFRSnapshotsF = new HashSet<>();\n        Set<String> unresolvedJFRSnapshotsS = new HashSet<>();\n        Set<JFRSnapshotImpl> snapshots = new HashSet<>();\n        for (File file : files) {\n            Storage storage = new Storage(file.getParentFile(), file.getName());\n            String[] propNames = new String[] {\n                Snapshot.PROPERTY_FILE\n            };\n            String[] propValues = storage.getCustomProperties(propNames);\n            if (propValues[0] == null) continue;\n                \n            JFRSnapshotImpl persistedSnapshot = null;\n            try {\n                persistedSnapshot = new JFRSnapshotImpl(new File(propValues[0]), storage);\n            } catch (Exception e) {\n                LOGGER.log(Level.INFO, \"Error loading persisted JFR snapshot\", e);    // NOI18N\n                unresolvedJFRSnapshotsF.add(file);\n                unresolvedJFRSnapshotsS.add(propValues[0]);\n            }\n            \n            if (persistedSnapshot != null) snapshots.add(persistedSnapshot);\n        }\n        \n        if (!unresolvedJFRSnapshotsF.isEmpty()) notifyUnresolvedJFRSnapshots(unresolvedJFRSnapshotsF, unresolvedJFRSnapshotsS);\n        \n        if (!snapshots.isEmpty())\n            JFRSnapshotsContainer.sharedInstance().getRepository().addDataSources(snapshots);\n    }\n\n    private static void notifyUnresolvedJFRSnapshots(final Set<File> unresolvedJFRSnapshotsF, final Set<String> unresolvedJFRSnapshotsS) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                JPanel messagePanel = new JPanel(new BorderLayout(5, 5));\n                messagePanel.add(new JLabel(NbBundle.getMessage(JFRSnapshotProvider.class, \"MSG_Unresolved_CoreDumps\")), BorderLayout.NORTH); // NOI18N\n                JList<String> list = new JList<>(unresolvedJFRSnapshotsS.toArray(new String[0]));\n                list.setVisibleRowCount(4);\n                messagePanel.add(new JScrollPane(list), BorderLayout.CENTER);\n                NotifyDescriptor dd = new NotifyDescriptor(\n                        messagePanel, NbBundle.getMessage(JFRSnapshotProvider.class, \"Title_Unresolved_CoreDumps\"), // NOI18N\n                        NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.ERROR_MESSAGE,\n                        null, NotifyDescriptor.YES_OPTION);\n                if (DialogDisplayer.getDefault().notify(dd) == NotifyDescriptor.NO_OPTION)\n                    for (File file : unresolvedJFRSnapshotsF) Utils.delete(file, true);\n\n                unresolvedJFRSnapshotsF.clear();\n                unresolvedJFRSnapshotsS.clear();\n            }\n        }, 1000);\n    }\n\n    \n    JFRSnapshotProvider() {\n    }\n    \n    public static void register() {\n        final JFRSnapshotProvider provider = new JFRSnapshotProvider();\n        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n            public void run() {\n                VisualVM.getInstance().runTask(provider::initPersistedJFRSnapshots);\n            }\n        });\n    }\n  \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/JFRStartAction.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.impl;\n\nimport java.awt.event.ActionEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.core.ui.actions.MultiDataSourceAction;\nimport org.graalvm.visualvm.jfr.JFRSnapshotSupport;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n *\n */\nclass JFRStartAction extends MultiDataSourceAction<DataSource> {\n    private static JFRStartAction INSTANCE;\n    public static synchronized JFRStartAction instance() {\n        if (INSTANCE == null) {\n            INSTANCE = new JFRStartAction();\n        }\n        return INSTANCE;\n    }\n\n    private Set<Application> lastSelectedApplications = new HashSet<>();\n    private final PropertyChangeListener stateListener = new PropertyChangeListener() {\n        public void propertyChange(PropertyChangeEvent evt) {\n            updateState(ActionUtils.getSelectedDataSources());\n        }\n    };\n\n    private JFRStartAction() {\n        super(DataSource.class);\n        putValue(NAME, NbBundle.getMessage(JFRStartAction.class, \"MSG_JFR_Start\")); // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(JFRStartAction.class, \"LBL_JFR_Start\"));    // NOI18N\n    }\n\n    protected void actionPerformed(Set<DataSource> dataSources, ActionEvent actionEvent) {\n        for (DataSource dataSource : dataSources) {\n            if (dataSource instanceof Application) {\n                Application application = (Application) dataSource;\n                if (application.isLocalApplication()) {\n                    JFRSnapshotSupport.jfrStartRecording(application);\n                } else {\n                    JFRSnapshotSupport.remoteJfrStartRecording(application);\n                }\n                updateState(dataSources);\n            }\n        }\n    }\n\n    protected boolean isEnabled(Set<DataSource> dataSources) {\n        for (DataSource dataSource : dataSources) {\n            if (dataSource instanceof Application) {\n                // TODO: Listener should only be registered when JFR dump is supported for the application\n                Application application = (Application) dataSource;\n                lastSelectedApplications.add(application);\n                application.addPropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n                if (application.getState() != Stateful.STATE_AVAILABLE) {\n                    return false;\n                }\n                if (application.isLocalApplication()) {\n                    if (!JFRSnapshotSupport.supportsJfrStart(application)) {\n                        return false;\n                    }\n                } else {\n                    if (!JFRSnapshotSupport.supportsRemoteJfrStart(application)) {\n                        return false;\n                    }\n                }\n            } else {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    protected void updateState(Set<DataSource> dataSources) {\n        if (!lastSelectedApplications.isEmpty()) {\n            for (Application application : lastSelectedApplications) {\n                application.removePropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n            }\n        }\n        lastSelectedApplications.clear();\n        super.updateState(dataSources);\n    }\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/impl/JFRStopAction.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.impl;\n\nimport java.awt.event.ActionEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.core.ui.actions.MultiDataSourceAction;\nimport org.graalvm.visualvm.jfr.JFRSnapshotSupport;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n *\n */\nclass JFRStopAction extends MultiDataSourceAction<DataSource> {\n    private static JFRStopAction INSTANCE;\n    public static synchronized JFRStopAction instance() {\n        if (INSTANCE == null) {\n            INSTANCE = new JFRStopAction();\n        }\n        return INSTANCE;\n    }\n\n    private Set<Application> lastSelectedApplications = new HashSet<>();\n    private final PropertyChangeListener stateListener = new PropertyChangeListener() {\n        public void propertyChange(PropertyChangeEvent evt) {\n            updateState(ActionUtils.getSelectedDataSources());\n        }\n    };\n\n    private JFRStopAction() {\n        super(DataSource.class);\n        putValue(NAME, NbBundle.getMessage(JFRStopAction.class, \"MSG_JFR_Stop\")); // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(JFRStopAction.class, \"LBL_JFR_Stop\"));    // NOI18N\n    }\n\n    protected void actionPerformed(Set<DataSource> dataSources, ActionEvent actionEvent) {\n        for (DataSource dataSource : dataSources) {\n            if (dataSource instanceof Application) {\n                Application application = (Application) dataSource;\n                if (application.isLocalApplication()) {\n                    JFRSnapshotSupport.jfrStopRecording(application);\n                } else {\n                    JFRSnapshotSupport.remoteJfrStopRecording(application);\n                }\n                updateState(dataSources);\n            }\n        }\n    }\n\n    protected boolean isEnabled(Set<DataSource> dataSources) {\n        for (DataSource dataSource : dataSources) {\n            if (dataSource instanceof Application) {\n                // TODO: Listener should only be registered when JFR dump is supported for the application\n                Application application = (Application) dataSource;\n                lastSelectedApplications.add(application);\n                application.addPropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n                if (application.getState() != Stateful.STATE_AVAILABLE) {\n                    return false;\n                }\n                if (application.isLocalApplication()) {\n                    if (!JFRSnapshotSupport.supportsJfrStop(application)) {\n                        return false;\n                    }\n                } else {\n                    if (!JFRSnapshotSupport.supportsRemoteJfrStop(application)) {\n                        return false;\n                    }\n                }\n            } else {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    protected void updateState(Set<DataSource> dataSources) {\n        if (!lastSelectedApplications.isEmpty()) {\n            for (Application application : lastSelectedApplications) {\n                application.removePropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n            }\n        }\n        lastSelectedApplications.clear();\n        super.updateState(dataSources);\n    }\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFRClass.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JFRClass {\n    \n    public abstract String getName();\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFRDataDescriptor.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\nimport java.text.Format;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class JFRDataDescriptor {\n    \n    private final String dataName;\n    private final String dataDescription;\n    \n    private final Format dataFormat;\n    private final Format dataDetailFormat;\n    \n    private final boolean isNumericData;\n    \n    \n    public JFRDataDescriptor(String dataName, String dataDescription, Format dataFormat, Format dataDetailFormat, boolean isNumericData) {\n        this.dataName = dataName;\n        this.dataDescription = dataDescription;\n        this.dataFormat = dataFormat;\n        this.dataDetailFormat = dataDetailFormat;\n        this.isNumericData = isNumericData;\n    }\n    \n    \n    public String getDataName() {\n        return dataName;\n    }\n    \n    public String getDataDescription() {\n        return dataDescription;\n    }\n    \n    public Format getDataFormat() {\n        return dataFormat;\n    }\n    \n    public Format getDataDetailFormat() {\n        return dataDetailFormat;\n    }\n    \n    public boolean isNumericData() {\n        return isNumericData;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFREvent.java",
    "content": "/*\n * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\nimport java.time.Duration;\nimport java.time.Instant;\nimport java.util.List;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JFREvent {\n    \n    private final long id;\n    \n    \n    protected JFREvent(long id) {\n        this.id = id;\n    }\n    \n    \n    public final long getID() {\n        return id;\n    }\n    \n    \n    public boolean getBoolean(String key) throws JFRPropertyNotAvailableException {\n        Object value = getValue(key);\n        if (value instanceof Boolean) return (Boolean)value;\n        else throw new JFRPropertyNotAvailableException(\"No boolean value available: \" + key);\n    }\n\n    public byte getByte(String key) throws JFRPropertyNotAvailableException {\n        Object value = getValue(key);\n        if (value instanceof Number) return ((Number)value).byteValue();\n        else throw new JFRPropertyNotAvailableException(\"No byte value available: \" + key);\n    }\n\n    public char getChar(String key) throws JFRPropertyNotAvailableException {\n        Object value = getValue(key);\n        if (value instanceof Character) return (Character)value;\n        else throw new JFRPropertyNotAvailableException(\"No char value available: \" + key);\n    }\n\n    public double getDouble(String key) throws JFRPropertyNotAvailableException {\n        Object value = getValue(key);\n        if (value instanceof Number) return ((Number)value).doubleValue();\n        else throw new JFRPropertyNotAvailableException(\"No double value available: \" + key);\n    }\n\n    public float getFloat(String key) throws JFRPropertyNotAvailableException {\n        Object value = getValue(key);\n        if (value instanceof Number) return ((Number)value).floatValue();\n        else throw new JFRPropertyNotAvailableException(\"No float value available: \" + key);\n    }\n\n    public int getInt(String key) throws JFRPropertyNotAvailableException {\n        Object value = getValue(key);\n        if (value instanceof Number) return ((Number)value).intValue();\n        else throw new JFRPropertyNotAvailableException(\"No int value available: \" + key);\n    }\n\n    public long getLong(String key) throws JFRPropertyNotAvailableException {\n        Object value = getValue(key);\n        if (value instanceof Number) return ((Number)value).longValue();\n        else throw new JFRPropertyNotAvailableException(\"No long value available: \" + key);\n    }\n\n    public short getShort(String key) throws JFRPropertyNotAvailableException {\n        Object value = getValue(key);\n        if (value instanceof Number) return ((Number)value).shortValue();\n        else throw new JFRPropertyNotAvailableException(\"No short value available: \" + key);\n    }\n    \n    public String getString(String key) throws JFRPropertyNotAvailableException {\n        Object value = getValue(key);\n        if (value instanceof String) return (String)value;\n        else if (value == null) return null;\n        else throw new JFRPropertyNotAvailableException(\"No string value available: \" + key);\n    }\n    \n    \n    public abstract Instant getInstant(String key) throws JFRPropertyNotAvailableException;\n    \n    public abstract Duration getDuration(String key) throws JFRPropertyNotAvailableException;\n    \n    \n    public abstract JFRClass getClass(String key) throws JFRPropertyNotAvailableException;\n    \n    public abstract JFRThread getThread(String key) throws JFRPropertyNotAvailableException;\n    \n    public abstract JFRStackTrace getStackTrace(String key) throws JFRPropertyNotAvailableException;\n    \n    \n    public abstract Object getValue(String key) throws JFRPropertyNotAvailableException;\n    \n    \n    public abstract List<Comparable<?>> getDisplayableValues(boolean includeExperimental);\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFREventChecker.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JFREventChecker {\n    \n    private final Set<String> types;\n    \n    \n    protected JFREventChecker(String[] eventTypes) {\n        types = new HashSet<>(Arrays.asList(eventTypes));\n    }\n    \n    \n    final boolean checksEventType(String eventType) {\n        return types.contains(eventType);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFREventType.java",
    "content": "/*\n * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\nimport java.util.List;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JFREventType {\n    \n    public abstract long getId();\n    \n    public abstract String getName();\n    \n    public abstract String getDisplayName();\n    \n    public abstract String getDescription();\n    \n    public abstract List<String> getCategory();\n    \n    \n    public abstract boolean isExperimental();\n    \n    \n    public abstract List<JFRDataDescriptor> getDisplayableDataDescriptors(boolean includeExperimental);\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFREventTypeVisitor.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface JFREventTypeVisitor {\n    \n    // Called before visiting starts\n    public default void initTypes() {}\n    \n    // Returns true when the result is found and following event types may be skipped\n    public boolean visitType(String typeName, JFREventType eventType);\n    \n    // Called after visiting finished\n    public default void doneTypes() {}\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFREventVisitor.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface JFREventVisitor {\n    \n    // Called before visiting starts\n    public default void init() {}\n    \n    // Returns true when the result is found and following events may be skipped\n    public boolean visit(String typeName, JFREvent event);\n    \n    // Called after visiting finished\n    public default void done() {}\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFRMethod.java",
    "content": "/*\n * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JFRMethod {\n    \n    public abstract String getName();\n    \n    public abstract String getDescriptor();\n    \n    public abstract JFRClass getType();\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFRModel.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\nimport java.time.Duration;\nimport java.time.Instant;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.core.model.Model;\nimport org.graalvm.visualvm.jfr.utils.ValuesConverter;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JFRModel extends Model {\n    \n    private static final Logger LOGGER = Logger.getLogger(JFRModel.class.getName());\n    \n    private final String id;\n    \n    \n    protected JFRModel(String id) {\n        this.id = id;\n    }\n    \n    \n    protected String getID() {\n        return id;\n    }\n    \n    \n    public abstract void visitEvents(JFREventVisitor... visitors);\n    \n    public abstract void visitEventTypes(JFREventTypeVisitor... visitors);\n    \n    \n    private Instant jvmStartTime;\n    private Instant jvmShutdownTime;\n    private String jvmShutdownReason;\n    \n    private Instant firstEventTime;\n    private Instant lastEventTime;\n    private long eventsCount = 0;\n    private long experimentalCount = 0;\n    \n    private long firstEventTimeMs;\n    \n    private String jvmFlags;\n    private String jvmArgs;\n    private String javaArgs;\n    private Properties sysProps;\n    \n    \n    private Map<String, Boolean> checkedEvents;\n    \n    public boolean containsEvent(Class<? extends JFREventChecker> eventCheckerClass) {\n        Boolean contains = checkedEvents == null ? null : checkedEvents.get(eventCheckerClass.getName());\n        return Boolean.TRUE.equals(contains);\n    }\n    \n    \n    public JFREvent getEvent(final long eventID) {\n        final JFREvent[] foundEvent = new JFREvent[] { null };\n        \n        visitEvents(new JFREventVisitor() {\n            @Override\n            public boolean visit(String typeName, JFREvent event) {\n                boolean found = eventID == event.getID();\n                if (found) foundEvent[0] = event;\n                return found;\n            }\n        });\n        \n        return foundEvent[0];\n    }\n    \n    \n    public Instant getJvmStartTime() {\n        return jvmStartTime;\n    }\n\n    public Instant getJvmShutdownTime() {\n        return jvmShutdownTime;\n    }\n\n    public String getJvmShutdownReason() {\n        return jvmShutdownReason;\n    }\n    \n    \n    public Instant getFirstEventTime() {\n        return firstEventTime;\n    }\n\n    public Instant getLastEventTime() {\n        return lastEventTime;\n    }\n    \n    public long getEventsCount() {\n        return eventsCount;\n    }\n    \n    public long getExperimentalEventsCount() {\n        return experimentalCount;\n    }\n    \n\n    public Properties getSystemProperties() {\n        return sysProps;\n    }\n\n    public String getJvmFlags() {\n        return jvmFlags;\n    }\n\n    public String getJvmArgs() {\n        return jvmArgs;\n    }\n\n    public String getJavaCommand() {\n        return javaArgs;\n    }\n    \n    \n    public String getVmVersion() {\n        return findByName(\"java.vm.version\"); // NOI18N\n    }\n    \n    public String getJavaHome() {\n        return findByName(\"java.home\"); // NOI18N\n    }\n    \n    public String getVmInfo() {\n        return findByName(\"java.vm.info\"); // NOI18N\n    }\n    \n    public String getVmName() {\n        return findByName(\"java.vm.name\"); // NOI18N\n    }\n    \n    private String findByName(String key) {\n        Properties p = getSystemProperties();\n        return p == null ? null : p.getProperty(key);\n    }\n    \n    \n    // To be used for times related to snapshot, can be safely stored to long\n    public Duration toRelativeTime(Instant absoluteTime) {\n        return Duration.between(firstEventTime, absoluteTime);\n    }\n    \n    // To be used for relative times created using toRelativeTime(Instant)\n    public Instant toAbsoluteTime(Duration relativeTime) {\n        return firstEventTime.plus(relativeTime);\n    }\n    \n    // To be used for relative times created using toRelativeTime(Instant)\n    public Instant nsToAbsoluteTime(long nanos) {\n        return firstEventTime.plusNanos(nanos);\n    }\n    \n    // To be used for relative times created using toRelativeTime(Instant)\n    public long nsToAbsoluteMillis(long nanos) {\n        return firstEventTimeMs + ValuesConverter.nanosToMillis(nanos);\n    }\n    \n    \n    protected final void initialize() {\n        sysProps = new Properties();\n        \n        final Set<String> experimentalTypes = new HashSet<>();\n        visitEventTypes(new JFREventTypeVisitor() {\n            @Override\n            public boolean visitType(String typeName, JFREventType eventType) {\n                if (eventType.isExperimental()) experimentalTypes.add(typeName);\n                return false;\n            }\n        });\n\n        visitEvents(new JFREventVisitor() {\n            private List<? extends JFREventChecker> checkers;\n            @Override\n            public void init() {\n                checkedEvents = new HashMap<>();\n                checkers = new ArrayList<>(Lookup.getDefault().lookupAll(JFREventChecker.class));\n            }\n            @Override\n            public boolean visit(String typeName, JFREvent event) {\n                eventsCount++;\n                if (experimentalTypes.contains(typeName)) experimentalCount++;\n                \n                if (!checkers.isEmpty()) {\n                    Iterator<? extends JFREventChecker> checkersI = checkers.iterator();\n                    while (checkersI.hasNext()) {\n                        JFREventChecker checker = checkersI.next();\n                        if (checker.checksEventType(typeName)) {\n                            checkersI.remove();\n                            checkedEvents.put(checker.getClass().getName(), Boolean.TRUE);\n                        }\n                    }\n                }\n\n                try {\n                    Instant eventTime = event.getInstant(\"eventTime\"); // NOI18N\n                    if (firstEventTime == null) {\n                        firstEventTime = eventTime;\n                        lastEventTime = eventTime;\n                    } else {\n                        if (firstEventTime.isAfter(eventTime)) firstEventTime = eventTime;\n                        if (lastEventTime.isBefore(eventTime)) lastEventTime = eventTime;\n                    }\n                } catch (JFRPropertyNotAvailableException e) {}\n\n                try {\n                    switch (typeName) {\n                        case TYPE_JVM_INFORMATION:\n                            jvmStartTime = event.getInstant(\"jvmStartTime\"); // NOI18N\n                            jvmFlags = event.getString(\"jvmFlags\"); // NOI18N\n                            jvmArgs = event.getString(\"jvmArguments\"); // NOI18N\n                            javaArgs = event.getString(\"javaArguments\"); // NOI18N\n                            break;\n                            \n                        case TYPE_SYSTEM_PROPERTY:\n                            sysProps.put(event.getString(\"key\"), event.getString(\"value\")); // NOI18N\n                            break;\n                            \n                        case TYPE_SHUTDOWN:\n                            jvmShutdownTime = event.getInstant(\"eventTime\"); // NOI18N\n                            jvmShutdownReason = event.getString(\"reason\"); // NOI18N\n                            break;\n                    }\n                } catch (JFRPropertyNotAvailableException e) {\n                    LOGGER.log(Level.INFO, \"JFR model initialization info (\" + getID()+ \")\", e); // NOI18N\n                }\n\n                return false;\n            }\n        });\n        \n        firstEventTimeMs = ValuesConverter.instantToMillis(firstEventTime);\n    }\n    \n    private static final String TYPE_JVM_INFORMATION = \"jdk.JVMInformation\"; // NOI18N\n    private static final String TYPE_SYSTEM_PROPERTY = \"jdk.InitialSystemProperty\"; // NOI18N\n    private static final String TYPE_SHUTDOWN = \"jdk.Shutdown\"; // NOI18N\n    \n    \n    // --- Workaround until GH-141 is available ---\n    static final JFRModel OOME = new JFRModel(\"OOME\") { // NOI18N\n        @Override public void visitEvents(JFREventVisitor... visitors) {}\n        @Override public void visitEventTypes(JFREventTypeVisitor... visitors) {}\n    };\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFRModelFactory.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\nimport java.util.Set;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.core.model.ModelFactory;\nimport org.graalvm.visualvm.core.model.ModelProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class JFRModelFactory extends ModelFactory<JFRModel, DataSource> {\n    \n    private static JFRModelFactory FACTORY;\n    \n    private boolean hasProviders;\n    private boolean hasGenericProvider;\n    \n\n    private JFRModelFactory() {\n        addFactoryChangeListener(new DataChangeListener<ModelProvider<JFRModel, DataSource>>() {\n            @Override\n            public void dataChanged(DataChangeEvent<ModelProvider<JFRModel, DataSource>> dce) {\n                Set<ModelProvider<JFRModel, DataSource>> providers = dce.getCurrent();\n                hasProviders = !providers.isEmpty();\n                hasGenericProvider = hasProviders && providers.toString().contains(\"generic loader\"); // NOI18N\n            }\n        });\n    }\n    \n    \n    public static synchronized JFRModelFactory getDefault() {\n        if (FACTORY == null) FACTORY = new JFRModelFactory();\n        return FACTORY;\n    }\n    \n    public static JFRModel getJFRModelFor(DataSource app) {\n        JFRModel model = getDefault().getModel(app);\n        return model == JFRModel.OOME ? null : model;\n    }\n    \n    \n    public final boolean hasProviders() {\n        return hasProviders;\n    }\n    \n    public final boolean hasGenericProvider() {\n        return hasGenericProvider;\n    }\n    \n    \n    // WORKAROUND to clean up the model after closing the snapshot view\n    // Currently the JFRModel is kept on heap using a SoftReference, eventually\n    // reused on subsequent snapshot open. Takes too much space for JFRModelImpl.\n    @Deprecated public static void cleanupModel__Workaround(JFRModel model) {\n        // Dummy JFRModelProvider with no functionality\n        ModelProvider<JFRModel, DataSource> workaround = new AbstractModelProvider<JFRModel, DataSource>() {\n            @Override public JFRModel createModelFor(DataSource b) { return null; }\n        };\n        // Registering/unregistering ModelProvider clears the Model cache\n        JFRModelFactory.getDefault().registerProvider(workaround);\n        JFRModelFactory.getDefault().unregisterProvider(workaround);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFRModelProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\nimport java.io.File;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JFRModelProvider extends AbstractModelProvider<JFRModel, DataSource> {\n    \n    private static final Logger LOGGER = Logger.getLogger(JFRModelProvider.class.getName());\n    \n    \n    private final String id;\n    private final int priority;\n    \n    \n    protected JFRModelProvider(String id, int priority) {\n        this.id = id;\n        this.priority = priority;\n    }\n    \n    \n    protected abstract JFRModel createModel(String id, File file) throws Exception;\n    \n    \n    @Override\n    public final JFRModel createModelFor(final DataSource dataSource) {\n        if (dataSource instanceof JFRSnapshot) {\n            JFRSnapshot snapshot = (JFRSnapshot)dataSource;\n            File file = snapshot.getFile();\n            try {\n                return createModel(id, file);\n            } catch (OutOfMemoryError e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        DataSourceWindowManager.sharedInstance().closeDataSource(dataSource);\n                        ProfilerDialogs.displayError(\"<html><br><b>Not enough memory to open JFR snapshot.</b><br><br>Please increase VisualVM heap size using the -Xmx parameter.</html>\", \"Out Of Memory\", null);\n                    }\n                });\n                \n                LOGGER.log(Level.SEVERE, \"Not enough memory to load JFR snapshot (\" + id + \"): \" + file);   // NOI18N\n                \n                return JFRModel.OOME;\n            } catch (Exception e) {\n                LOGGER.log(Level.INFO, \"Could not load JFR snapshot (\" + id + \"): \" + file, e);   // NOI18N\n            }\n        }\n        \n        return null;\n    }\n    \n    \n    @Override\n    public final int priority() {\n        return priority;\n    }\n    \n    @Override\n    public final String toString() {\n        return id;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFRPropertyNotAvailableException.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class JFRPropertyNotAvailableException extends Exception {\n    \n    public JFRPropertyNotAvailableException(String message) {\n        super(message);\n    }\n    \n    public JFRPropertyNotAvailableException(Throwable cause) {\n        super(cause);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFRStackFrame.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JFRStackFrame {\n    \n    public abstract JFRMethod getMethod();\n    \n    public abstract int getLine();\n    \n    public abstract int getBCI();\n    \n    public abstract String getType();\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFRStackTrace.java",
    "content": "/*\n * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\nimport java.util.List;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JFRStackTrace {\n    \n    public abstract List<JFRStackFrame> getFrames();\n    \n    public abstract boolean isTruncated();\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/JFRThread.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JFRThread {\n    \n    public abstract long getId();\n    \n    public abstract String getName();\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/impl/JfrModelImpl.java",
    "content": "/*\n * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model.impl;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.tools.attach.AttachModel;\nimport org.graalvm.visualvm.tools.jfr.JfrModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class JfrModelImpl extends JfrModel {\n\n    private static final int ATTACH_CMD = 0;\n    private static final int JMX_CMD = 1;\n    private static final String[] JCMD_JFR_DUMP = new String[]{\"JFR.dump\", \"jfrDump\"};    // NOI18N\n    private static final String JCMD_JFR_DUMP_FILENAME = \"filename\";    // NOI18N\n    private static final String JCMD_JFR_DUMP_RECORDING = \"recording\";    // NOI18N\n    private static final String JCMD_JFR_DUMP_NAME = \"name\";    // NOI18N\n    private static final String[] JCMD_JFR_CHECK = new String[]{\"JFR.check\", \"jfrCheck\"};   // NOI18N\n    private static final String JCMD_JFR_CHECK_RECORDING_ID = \"recording=\";     // NOI18N\n    private static final String JCMD_JFR_CHECK_RECORDING_ID1 = \"Recording \";     // NOI18N\n    private static final String JCMD_JFR_CHECK_HELP_OPTIONS_ID = \"Options: \";        // NOI18N\n    private static final String JCMD_JFR_CHECK_HELP_RECORDING_ID = \"recording : \";        // NOI18N\n    private static final String[] JCMD_JFR_START = new String[]{\"JFR.start\", \"jfrStart\"};   // NOI18N\n    private static final String JCMD_JFR_START_NAME = \"name\"; // NOI18N\n    private static final String JCMD_JFR_START_SETTINGS = \"settings\"; // NOI18N\n    private static final String JCMD_JFR_START_DELAY = \"delay\"; // NOI18N\n    private static final String JCMD_JFR_START_DURATION = \"duration\"; // NOI18N\n    private static final String JCMD_JFR_START_DISK = \"disk\"; // NOI18N\n    private static final String JCMD_JFR_START_FILENAME = \"filename\"; // NOI18N\n    private static final String JCMD_JFR_START_MAXAGE = \"maxage\"; // NOI18N\n    private static final String JCMD_JFR_START_MAXSIZE = \"maxsize\"; // NOI18N\n    private static final String JCMD_JFR_START_DUMPONEXIT = \"dumponexit\"; // NOI18N\n    private static final String[] JCMD_JFR_STOP = new String[]{\"JFR.stop\", \"jfrStop\"};   // NOI18N\n    private static final String JCMD_JFR_STOP_NAME = \"name\";   // NOI18N\n    private static final String JCMD_JFR_UNLOCK_ID = \"Use VM.unlock_commercial_features to enable\"; // NOI18N\n    private static final String[] JCMD_UNLOCK_CF = new String[]{\"VM.unlock_commercial_features\", \"vmUnlockCommercialFeatures\"}; // NOI18N\n    private static final String[] JCMD_HELP = new String[]{\"help\", \"help\"};                 // NOI18N\n    private static final String JCMD_CF_ID = \" unlocked.\";   // NOI18N\n    private static final String JCMD_JFR_UNKNOWN_COMMAND = \"Unknown diagnostic command\";   // NOI18N\n    private static final Map<String, Object> EMPTY_PARS = Collections.singletonMap(\"\", null);\n\n    private boolean oldJFR;\n    private AttachModel attach;\n    private JmxModel jmx;\n\n    JfrModelImpl(AttachModel attachModel) {\n        attach = attachModel;\n    }\n\n    JfrModelImpl(JmxModel jmxModel) {\n        jmx = jmxModel;\n    }\n\n    boolean isJfrAvailable() {\n        boolean jfrAvailable;\n        String recordings = executeJCmd(JCMD_JFR_CHECK, EMPTY_PARS);\n        if (recordings == null) {\n            return false;\n        } else {\n            if (recordings.contains(JCMD_JFR_UNLOCK_ID)) {\n                jfrAvailable = unlockCommercialFeature();\n            } else if (recordings.contains(JCMD_JFR_UNKNOWN_COMMAND)) {\n                jfrAvailable = false;\n            } else {\n                jfrAvailable = true;\n            }\n        }\n        if (jfrAvailable) {\n            oldJFR = checkForOldJFR();\n        }\n        return jfrAvailable;\n    }\n\n    public List<Long> jfrCheck() {\n        String recordings = executeJCmd(JCMD_JFR_CHECK, EMPTY_PARS);\n        if (recordings == null) {\n            return Collections.emptyList();\n        }\n        String[] lines = recordings.split(\"\\\\r?\\\\n\");       // NOI18N\n        List<Long> recNumbers = new ArrayList<>(lines.length);\n\n        for (String line : lines) {\n            int index = line.indexOf(JCMD_JFR_CHECK_RECORDING_ID);\n            if (index >= 0) {\n                int recStart = index + JCMD_JFR_CHECK_RECORDING_ID.length();\n                int recEnd = line.indexOf(' ', recStart);\n\n                if (recEnd > recStart) {\n                    String recordingNum = line.substring(recStart, recEnd);\n                    recNumbers.add(Long.valueOf(recordingNum));\n                }\n            } else if (line.startsWith(JCMD_JFR_CHECK_RECORDING_ID1)) {\n                int recStart = JCMD_JFR_CHECK_RECORDING_ID1.length();\n                int recEnd = line.indexOf(':', recStart);\n\n                if (recEnd > recStart) {\n                    String recordingNum = line.substring(recStart, recEnd);\n                    recNumbers.add(Long.valueOf(recordingNum));\n                }\n            }\n        }\n        return recNumbers;\n    }\n\n    public String takeJfrDump(long recording, String fileName) {\n        Map<String, Object> pars = new HashMap<>();\n        pars.put(JCMD_JFR_DUMP_FILENAME, fileName);\n        pars.put(oldJFR ? JCMD_JFR_DUMP_RECORDING : JCMD_JFR_DUMP_NAME, recording);\n        return executeJCmd(JCMD_JFR_DUMP, pars);\n    }\n\n    public boolean startJfrRecording(String name, String[] settings, String delay,\n            String duration, Boolean disk, String path, String maxAge, String maxSize,\n            Boolean dumpOnExit) {\n        Map<String, Object> pars = new HashMap<>();\n        if (name != null) {\n            pars.put(JCMD_JFR_START_NAME, name);\n        }\n        if (settings != null) {\n            for (String setting : settings) {\n                pars.put(JCMD_JFR_START_SETTINGS, setting);\n            }\n        }\n        if (delay != null) {\n            pars.put(JCMD_JFR_START_DELAY, delay);\n        }\n        if (duration != null) {\n            pars.put(JCMD_JFR_START_DURATION, duration);\n        }\n        if (maxAge != null) {\n            pars.put(JCMD_JFR_START_MAXAGE, maxAge);\n        }\n        if (maxSize != null) {\n            pars.put(JCMD_JFR_START_MAXSIZE, maxSize);\n        }\n        if (dumpOnExit != null) {\n            pars.put(JCMD_JFR_START_DUMPONEXIT, dumpOnExit);\n        }\n        if (path != null) {\n            pars.put(JCMD_JFR_START_FILENAME, path);\n        }\n        if (disk != null && !oldJFR) {\n            pars.put(JCMD_JFR_START_DISK, disk);\n        }\n\n        if (pars.isEmpty()) {\n            pars = EMPTY_PARS;\n        }\n        executeJCmd(JCMD_JFR_START, pars);\n        return true;\n    }\n\n    public boolean stopJfrRecording() {\n        String recKey = oldJFR ? JCMD_JFR_DUMP_RECORDING : JCMD_JFR_STOP_NAME;\n        for (Long recording : jfrCheck()) {\n            Map<String, Object> pars = Collections.singletonMap(recKey, recording);\n            executeJCmd(JCMD_JFR_STOP, pars);\n        }\n        return true;\n    }\n\n    private boolean checkForOldJFR() {\n        String ret = getJCmdHelp(JCMD_JFR_CHECK);\n\n        if (ret != null) {\n            int options = ret.indexOf(JCMD_JFR_CHECK_HELP_OPTIONS_ID);\n            int recording = ret.indexOf(JCMD_JFR_CHECK_HELP_RECORDING_ID);\n\n            return options != -1 && options < recording;\n        }\n        return false;\n    }\n\n    private boolean unlockCommercialFeature() {\n        String ret = executeJCmd(JCMD_UNLOCK_CF);\n        return ret.contains(JCMD_CF_ID);\n    }\n\n    private String getJCmdHelp(String[] command) {\n        // help command needs Attach API style commands on JMX\n        return executeJCmd(JCMD_HELP, Collections.singletonMap(command[ATTACH_CMD], null));\n    }\n\n    private String executeJCmd(String[] command, Map<String, Object> pars) {\n        if (attach != null) {\n            return attach.executeJCmd(command[ATTACH_CMD], pars);\n        }\n        return jmx.executeJCmd(command[JMX_CMD], pars);\n    }\n\n    private String executeJCmd(String[] string) {\n        return executeJCmd(string, Collections.emptyMap());\n    }\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/model/impl/JfrModelProvider.java",
    "content": "/*\n * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.model.impl;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.tools.attach.AttachModel;\nimport org.graalvm.visualvm.tools.attach.AttachModelFactory;\nimport org.graalvm.visualvm.tools.jfr.JfrModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class JfrModelProvider extends AbstractModelProvider<JfrModel, Application> {\n\n    public JfrModel createModelFor(Application app) {\n        JfrModelImpl jfr = getJFRModel(app);\n        if (jfr != null && jfr.isJfrAvailable()) {\n            return jfr;\n        }\n        return null;\n    }\n\n    private static JfrModelImpl getJFRModel(Application app) {\n        AttachModel attach = AttachModelFactory.getAttachFor(app);\n        if (attach != null) {\n            return new JfrModelImpl(attach);\n        }\n        JmxModel jmxModel = JmxModelFactory.getJmxModelFor(app);\n        if (jmxModel != null && jmxModel.getConnectionState() == JmxModel.ConnectionState.CONNECTED) {\n            return new JfrModelImpl(jmxModel);\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    \n    <folder name=\"Actions\">\n        <folder name=\"Other\">\n            <file name=\"org-graalvm-visualvm-jfr-impl-AddJFRSnapshotAction-alwaysEnabled.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.jfr.impl.AddJFRSnapshotAction.alwaysEnabled\"/>\n            </file>\n            <!--file name=\"org-graalvm-visualvm-jfr-application-JFRRecordingAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.jfr.application.JFRRecordingAction.instance\"/>\n            </file-->\n        </folder>\n    </folder>\n    \n    <folder name=\"Menu\">\n        <folder name=\"File\">\n            <file name=\"org-graalvm-visualvm-jfr-impl-AddJFRSnapshotAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-jfr-impl-AddJFRSnapshotAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"710\"/>\n            </file>\n        </folder>\n        <folder name=\"Applications\">\n            <file name=\"JFRRecordingAction-Separator-1600.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"1600\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-jfr-impl-JFRStartAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-jfr-impl-JFRStartAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1610\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-jfr-impl-JFRDumpAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-jfr-impl-JFRDumpAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1620\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-jfr-impl-JFRStopAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-jfr-impl-JFRStopAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1630\"/>\n            </file>\n            <!--file name=\"org-graalvm-visualvm-jfr-application-JFRRecordingAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-jfr-application-JFRRecordingAction.instance\"/>\n                <attr name=\"position\" intvalue=\"2600\"/>\n            </file-->\n        </folder>\n        <folder name=\"View\">\n            <file name=\"org-graalvm-visualvm-jfr-JFRSnapshotsSorting.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.jfr.JFRSnapshotsSorting.instance\"/>\n                <attr name=\"position\" intvalue=\"910\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"Toolbars\">\n        <folder name=\"DataSource\">\n            <file name=\"org-graalvm-visualvm-jfr-impl-AddJFRSnapshotAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-jfr-impl-AddJFRSnapshotAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"310\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"VisualVM\">\n        <folder name=\"Actions\">\n            <file name=\"org-graalvm-visualvm-jfr-impl-JFRDumpAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.jfr.impl.JFRDumpAction.instance\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-jfr-impl-JFRStartAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.jfr.impl.JFRStartAction.instance\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-jfr-impl-JFRStopAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.jfr.impl.JFRStopAction.instance\"/>\n            </file>\n        </folder>\n        <folder name=\"ExplorerPopupSelection\">\n            \n            <file name=\"org-graalvm-visualvm-jfr-impl-AddJFRSnapshotAction-selectionAware.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.jfr.impl.AddJFRSnapshotAction.selectionAware\"/>\n                <attr name=\"position\" intvalue=\"0\"/>\n                <attr name=\"default\" boolvalue=\"true\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-jfr-impl-JFRStartAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-jfr-impl-JFRStartAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1050\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-jfr-impl-JFRDumpAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-jfr-impl-JFRDumpAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1053\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-jfr-impl-JFRStopAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-jfr-impl-JFRStopAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1055\"/>\n            </file>\n            \n            <file name=\"JFRRecordingAction-Separator-1060.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"1060\"/>\n            </file>\n            \n            <!--file name=\"org-graalvm-visualvm-jfr-application-JFRRecordingAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-jfr-application-JFRRecordingAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1600\"/>\n            </file-->\n            \n        </folder>\n        \n        <folder name=\"ExplorerPopupNoSelection\">\n            \n            <file name=\"org-graalvm-visualvm-jfr-impl-AddJFRSnapshotAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-jfr-impl-AddJFRSnapshotAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"310\"/>\n            </file>\n            \n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/utils/DurationFormatter.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.utils;\n\nimport java.text.DecimalFormat;\nimport java.text.NumberFormat;\nimport java.time.Duration;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class DurationFormatter {\n    \n    private static final NumberFormat DECIMAL_LZ_FORMAT;\n    private static final NumberFormat DECIMAL_NLZ_FORMAT;\n    \n    private static final NumberFormat DURATION_MS_FORMAT;\n    \n    static {\n        DECIMAL_LZ_FORMAT = new DecimalFormat(\"00\"); // NOI18N\n        DECIMAL_NLZ_FORMAT = new DecimalFormat(\"#0\"); // NOI18N\n        \n        DURATION_MS_FORMAT = NumberFormat.getNumberInstance();\n        DURATION_MS_FORMAT.setMaximumFractionDigits(3);\n        DURATION_MS_FORMAT.setMinimumFractionDigits(3);\n    }\n    \n    \n    private DurationFormatter() {}\n    \n    \n    public static String format(Duration d) {\n        return format(d, new StringBuffer()).toString();\n    }\n    \n    public static StringBuffer format(Duration d, StringBuffer b) {\n        if (ValuesChecker.isMaxDuration(d)) return b.append(\"∞\"); // NOI18N\n            \n        long s = d.getSeconds();\n        if (s > 0) formatSeconds(s, b);\n\n        int n = d.getNano();\n        return b.append(DURATION_MS_FORMAT.format(n / 1000000f)).append(\" ms\"); // NOI18N\n    }\n\n    private static StringBuffer formatSeconds(long seconds, StringBuffer b) {\n        // Hours\n        long hours = seconds / 3600;\n        if (hours > 0) b.append(DECIMAL_NLZ_FORMAT.format(hours)).append(\" h \"); // NOI18N\n        seconds %= 3600;\n\n        // Minutes\n        long minutes = seconds / 60;\n        if (minutes > 0 || hours > 0) b.append((hours > 0 ? DECIMAL_LZ_FORMAT : DECIMAL_NLZ_FORMAT).format(minutes)).append(\" m \"); // NOI18N\n        seconds %= 60;\n\n        // Seconds\n        return b.append((minutes > 0 || hours > 0 ? DECIMAL_LZ_FORMAT : DECIMAL_NLZ_FORMAT).format(seconds)).append(\" s \"); // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/utils/InstantFormatter.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.utils;\n\nimport java.text.DateFormat;\nimport java.text.SimpleDateFormat;\nimport java.time.Instant;\nimport java.util.Date;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class InstantFormatter {\n    \n    private static final DateFormat TIME_FORMAT;\n    \n    static {\n        TIME_FORMAT = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);\n    }\n    \n    \n    private InstantFormatter() {}\n    \n    \n    public static String format(Instant i) {\n        return format(i, new StringBuffer()).toString();\n    }\n    \n    public static StringBuffer format(Instant i, StringBuffer b) {\n        try {\n            return b.append(TIME_FORMAT.format(new Date(ValuesConverter.instantToMillis(i)))); // milliseconds precision!\n        } catch (ArithmeticException e) {\n            return b.append(i.toString()); // TODO: handle differently!\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/utils/TimeRecord.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.utils;\n\nimport java.util.Comparator;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class TimeRecord {\n    \n    public static Comparator<TimeRecord> COMPARATOR = new Comparator<TimeRecord>() {\n        @Override public int compare(TimeRecord r1, TimeRecord r2) {\n            return Long.compare(r1.time, r2.time);\n        }\n    };\n    \n    \n    public final long time;\n    \n    \n    public TimeRecord(JFREvent event, JFRModel model) throws JFRPropertyNotAvailableException {\n        time = getTime(event, model);\n    }\n    \n    \n    public static long getTime(JFREvent event, JFRModel model) throws JFRPropertyNotAvailableException {\n        return ValuesConverter.instantToRelativeNanos(event.getInstant(\"eventTime\"), model); // NOI18N\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return Long.hashCode(time);\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        if (o == this) return true;\n        if (o instanceof TimeRecord) return time == ((TimeRecord)o).time;\n        return false;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/utils/ValuesChecker.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.utils;\n\nimport java.time.Duration;\nimport java.time.Instant;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ValuesChecker {\n    \n    private ValuesChecker() {}\n    \n    \n    public static boolean isNAValue(Object o) {\n        if (o instanceof Number) {\n            if (o instanceof Long) return isNALong((Long)o);\n            if (o instanceof Integer) return isNAInteger((Integer)o);\n            if (o instanceof Double) return isNADouble((Double)o);\n            if (o instanceof Float) return isNAFloat(((Float)o));\n            if (o instanceof Short) return isNAShort((Short)o);\n            if (o instanceof Byte) isNAByte((Byte)o);\n        } else if (o instanceof Instant) {\n            return isNAInstant((Instant)o);\n        } else if (o instanceof Duration) {\n            return isNADuration((Duration)o);\n        }\n        \n        return false;\n    }\n    \n    \n    public static boolean isNALong(Long val) { return Long.MIN_VALUE == val; }\n    \n    public static boolean isNAInteger(Integer val) { return Integer.MIN_VALUE == val; }\n    \n    public static boolean isNADouble(Double val) { return Double.NEGATIVE_INFINITY == val || Double.isNaN(val); }\n    \n    public static boolean isNAFloat(Float val) { return Float.NEGATIVE_INFINITY == val || Float.isNaN(val); }\n    \n    public static boolean isNAShort(Short val) { return Short.MIN_VALUE == val; }\n    \n    public static boolean isNAByte(Byte val) { return Byte.MIN_VALUE == val; }\n    \n    \n    public static boolean isNAInstant(Instant val) { return Instant.MIN.equals(val); }\n    \n    public static boolean isNADuration(Duration val) { return Long.MIN_VALUE == val.getSeconds(); }\n    \n    public static boolean isMaxDuration(Duration val) { return 9223372036854775l == val.getSeconds() && 807000000 == val.getNano(); }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/utils/ValuesConverter.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.utils;\n\nimport java.time.Duration;\nimport java.time.Instant;\nimport java.util.concurrent.TimeUnit;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ValuesConverter {\n    \n    private ValuesConverter() {}\n    \n    \n    public static long instantToNanos(Instant instant) {\n        return TimeUnit.SECONDS.toNanos(instant.getEpochSecond()) + instant.getNano();\n    }\n    \n    public static long instantToRelativeNanos(Instant instant, JFRModel model) {\n        return durationToNanos(model.toRelativeTime(instant));\n    }\n    \n    public static long instantToMillis(Instant instant) {\n        return instant.toEpochMilli();\n    }\n    \n    public static long instantToRelativeMillis(Instant instant, JFRModel model) {\n        return durationToMillis(model.toRelativeTime(instant));\n    }\n\n    public static long durationToNanos(Duration duration) {\n        return duration.toNanos();\n    }\n    \n    public static long durationToMicros(Duration duration) {\n        long micros = duration.getSeconds() * 1000000;\n        micros += duration.getNano() / 1000;\n        return micros;\n    }\n    \n    public static long durationToMillis(Duration duration) {\n        return duration.toMillis();\n    }\n\n    public static long nanosToMillis(long nanos) {\n        return nanos / 1000000;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/view/Bundle.properties",
    "content": "#\n# Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_JFR_Snapshot=JFR Snapshot\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/view/JFRView.java",
    "content": "/*\n * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.view;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.ImageIcon;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.core.snapshot.SnapshotView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.model.JFRModelFactory;\nimport org.graalvm.visualvm.uisupport.ProfilerTabbedView;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JFRView extends SnapshotView {\n    \n    private static final Logger LOGGER = Logger.getLogger(JFRView.class.getName());\n    \n    \n    private final List<JFRViewTab> tabViews = new ArrayList<>();\n    \n    private JFRModel model;\n    \n    \n    JFRView(JFRSnapshot jfrSnapshot, Collection<? extends JFRViewTabProvider> tabProviders) {\n        this(jfrSnapshot, DataSourceDescriptorFactory.getDescriptor(jfrSnapshot), tabProviders);\n    }\n    \n    private JFRView(JFRSnapshot jfrSnapshot, DataSourceDescriptor descriptor, Collection<? extends JFRViewTabProvider> tabProviders) {\n        super(jfrSnapshot, descriptor.getName(), descriptor.getIcon(), 0);\n        \n        for (JFRViewTabProvider tabProvider : tabProviders) {\n            tabViews.add(tabProvider.createView(jfrSnapshot));\n        }\n        tabViews.sort(Positionable.COMPARATOR);\n    }\n    \n\n    @Override\n    protected DataViewComponent createComponent() {\n        JFRSnapshot jfrSnapshot = (JFRSnapshot)getDataSource();\n        DataViewComponent dvc = new DataViewComponent(\n                new MasterViewSupport(jfrSnapshot, tabViews).getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(true));\n        \n        return dvc;\n    }\n    \n    \n    @Override\n    protected void willBeAdded() {\n        JFRSnapshot snapshot = (JFRSnapshot)getDataSource();\n        model = JFRModelFactory.getJFRModelFor(snapshot);\n        \n        if (model == null) LOGGER.log(Level.SEVERE, \"No JFR model for \" + snapshot.getFile()); // NOI18N\n        \n        for (JFRViewTab tabView : tabViews) {\n            tabView.setModel(model);\n        }\n    }\n    \n    @Override\n    protected void removed() {\n        // also called for null model - OOME etc.\n        JFRModelFactory.cleanupModel__Workaround(model);\n    }\n    \n    \n    private static class MasterViewSupport extends JPanel {\n        \n        private ProfilerTabbedView views;\n        \n        MasterViewSupport(JFRSnapshot jfrSnapshot, List<JFRViewTab> tabViews) {\n            initComponents(tabViews);\n        }\n        \n        public DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(JFRView.class, \"LBL_JFR_Snapshot\"), null, this);  // NOI18N\n        }\n        \n        \n        private void initComponents(List<JFRViewTab> tabViews) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            views = ProfilerTabbedView.createBottom(true, true, null);\n            views.setShowsTabPopup(false);\n            views.setFocusMaster(this);\n            add(views.getComponent(), BorderLayout.CENTER);\n            \n            for (JFRViewTab tabView : tabViews) {\n                views.addView(tabView.getName(), new ImageIcon(tabView.getImage()), null, tabView.createComponent(), false);\n            }\n        }\n        \n        \n        public void addNotify() {\n            super.addNotify();\n            tweakUI();\n        }\n        \n        private void tweakUI() {\n            try {\n                // Ugly hack to hide the \"JFR Snapshot\" caption added by the toplevel DisplayArea\n                Container DisplayArea_ViewArea = getParent();\n                Container DisplayArea = DisplayArea_ViewArea.getParent();\n                Component DisplayArea_captionArea = DisplayArea.getComponent(0);\n                if (DisplayArea_captionArea instanceof JPanel) DisplayArea_captionArea.setVisible(false);\n            } catch (Exception e) {\n                LOGGER.log(Level.WARNING, \"Failed to tweak UI for JFRView\", e); // NOI18N\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/view/JFRViewProvider.java",
    "content": "/*\n * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.view;\n\nimport java.util.Collection;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JFRViewProvider extends DataSourceViewProvider<JFRSnapshot> {\n\n    @Override\n    protected boolean supportsViewFor(JFRSnapshot dataSource) {\n        return true;\n    }\n\n    @Override\n    protected DataSourceView createView(JFRSnapshot dataSource) {\n        Collection<? extends JFRViewTabProvider> tabProviders = Lookup.getDefault().lookupAll(JFRViewTabProvider.class);\n        return new JFRView(dataSource, tabProviders);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/view/JFRViewTab.java",
    "content": "/*\n * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.view;\n\nimport java.awt.Image;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JFRViewTab extends DataSourceView {\n    \n    private JFRModel model;\n    \n    \n    protected JFRViewTab(JFRSnapshot snapshot, String name, Image icon, int preferredPosition) {\n        super(snapshot, name, icon, preferredPosition, false);\n    }\n\n    \n    @Override\n    protected abstract DataViewComponent createComponent();\n    \n    \n    final void setModel(JFRModel model) {\n        this.model = model;\n    }\n    \n    protected final JFRModel getModel() {\n        return model;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/view/JFRViewTabProvider.java",
    "content": "/*\n * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.view;\n\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JFRViewTabProvider extends DataSourceViewProvider<JFRSnapshot> {\n    \n    @Override\n    protected boolean supportsViewFor(JFRSnapshot jfrSnapshot) {\n        return true;\n    }\n    \n    @Override\n    protected abstract JFRViewTab createView(JFRSnapshot jfrSnapshot);\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/browser/BrowserNode.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.browser;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventType;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class BrowserNode extends CCTNode {\n    \n    private static final BrowserNode[] NO_NODES = new BrowserNode[0];\n    \n    private final BrowserNode parent;\n    private final List<BrowserNode> children;\n    \n    final String name;\n    final Icon icon;\n    \n    long eventsCount;\n    \n    \n    BrowserNode(String name, Icon icon, BrowserNode parent, List<BrowserNode> children) {\n        this.parent = parent;\n        this.children = children;\n        \n        this.name = name;\n        this.icon = icon;\n    }\n    \n    \n    BrowserNode getChild(String name) {\n        if (children != null)\n            for (BrowserNode child : children)\n                if (Objects.equals(name, child.name))\n                    return child;\n        return null;\n    }\n    \n    void addEvent() {\n        eventsCount++;\n        if (parent != null) parent.addEvent();\n    }\n    \n    \n    @Override\n    public BrowserNode getChild(int index) {\n        return children == null ? null : children.get(index);\n    }\n\n    @Override\n    public BrowserNode[] getChildren() {\n        return children == null ? NO_NODES : children.toArray(NO_NODES);\n    }\n\n    @Override\n    public int getIndexOfChild(Object child) {\n        return children == null ? -1 : children.indexOf(child);\n    }\n\n    @Override\n    public int getNChildren() {\n        return children == null ? 0 : children.size();\n    }\n    \n    @Override\n    public boolean isLeaf() {\n        return children == null || children.isEmpty();\n    }\n\n    @Override\n    public BrowserNode getParent() {\n        return parent;\n    }\n\n    \n    protected void addChild(BrowserNode child) {\n        if (children != null) children.add(child);\n    }\n    \n    protected void removeAllChildren() {\n        if (children != null) children.clear();\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return name.hashCode();\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (!(o instanceof BrowserNode)) return false;\n        return Objects.equals(name, ((BrowserNode)o).name);\n    }\n    \n    @Override\n    public String toString() {\n        return name;\n    }\n    \n    \n    static final class EventType extends BrowserNode {\n        \n        final String typeName;\n        final JFREventType type;\n        \n        \n        EventType(String typeName, JFREventType type, BrowserNode parent) {\n            super(typeName == null ? \"loading...\" : type.getName(), null, parent, new ArrayList<>());\n            \n            this.typeName = typeName;\n            this.type = type;\n            \n            if (type != null) {\n                eventsCount++;\n                parent.addEvent();\n            }\n        }\n        \n\n        @Override\n        public String toString() {\n            return type == null ? name : type.getDisplayName();\n        }\n        \n    }\n    \n    \n    static final class Category extends BrowserNode {\n        \n        Category(String name, BrowserNode parent) {\n            super(name, null, parent, new ArrayList<>());\n        }\n        \n    }\n    \n    \n    static class Root extends BrowserNode implements JFREventVisitor {        \n        \n        Root(String name) {\n            this();\n            EventType e = new EventType(null, null, this);\n            addChild(e);\n        }\n        \n        Root() {\n            super(null, null, null, new ArrayList<>());\n        }\n        \n        \n        JFREventType type(String typeName) { return null; }\n        \n\n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            JFREventType type = type(typeName);\n            if (type == null) return false; // experimental type not resolved\n            \n            String eventName = type.getName();\n\n            BrowserNode categoryNode = getOrCreateCategory(this, type.getCategory());\n            BrowserNode eventNode = categoryNode.getChild(eventName);\n            if (eventNode == null) {\n                eventNode = new EventType(typeName, type, categoryNode);\n                categoryNode.addChild(eventNode);\n            } else {\n                eventNode.addEvent();\n            }\n            \n            return false;\n        }\n        \n        \n        private static BrowserNode getOrCreateCategory(BrowserNode parent, List<String> category) {\n            List<String> names = new ArrayList<>(category);\n            \n            while (!names.isEmpty()) {\n                String name = names.remove(0);\n                BrowserNode node = parent.getChild(name);\n                if (node == null) {\n                    node = new Category(name, parent);\n                    parent.addChild(node);\n                }\n                parent = node;\n            }\n            \n            return parent;\n        }\n        \n        \n        @Override\n        public int hashCode() {\n            return 37;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            return o instanceof Root;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/browser/BrowserRenderers.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.browser;\n\nimport javax.swing.JLabel;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class BrowserRenderers {\n    \n    private static int getMinimumWidth(String valueName) {\n        return new JLabel(valueName).getPreferredSize().width + 30;\n    }\n    \n    \n    static class NameRenderer extends NormalBoldGrayRenderer {\n        \n        private boolean showsCount;\n        \n        void setShowsCount(boolean showsCount) {\n            this.showsCount = showsCount;\n        }\n            \n        public void setValue(Object value, int row) {\n            if (value instanceof BrowserNode) {\n                BrowserNode node = (BrowserNode)value;\n                boolean cat = node instanceof BrowserNode.Category;\n                setNormalValue(cat ? null : node.toString());\n                setBoldValue(cat ? node.toString() : null);\n                setGrayValue(showsCount ? (node.eventsCount == 1 ? \" (1 event)\" : \" (\" + node.eventsCount + \" events)\") : null);\n            } else {\n                super.setValue(value, row);\n            }\n        }\n\n        static String getDisplayName() {\n            return \"Name\";\n        }\n\n    }\n    \n    \n    static class TypeIDRenderer extends LabelRenderer {\n        \n        static String getDisplayName() {\n            return \"ID\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n//            setText(\"com.oracle.jdk.MetaspaceChunkFreeListSummary\"); // NOI18N\n            setText(\"jdk.MetaspaceChunkFreeListSummary\"); // NOI18N\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n\n    }\n    \n    \n    static class EventsCountRenderer extends NumberRenderer {\n        \n        static String getDisplayName() {\n            return \"Count\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(1234567, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/browser/BrowserViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.browser;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.text.Format;\nimport java.text.NumberFormat;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JSeparator;\nimport javax.swing.JTree;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.AbstractTableModel;\nimport javax.swing.tree.TreeNode;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.jfr.model.JFRDataDescriptor;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventType;\nimport org.graalvm.visualvm.jfr.model.JFREventTypeVisitor;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRMethod;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.jfr.model.JFRStackFrame;\nimport org.graalvm.visualvm.jfr.model.JFRStackTrace;\nimport org.graalvm.visualvm.jfr.views.components.MessageComponent;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.DefaultMethodNameFormatter;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextAreaSearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.FormattedLabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class BrowserViewSupport {\n    \n    private static final int ITEMS_LIMIT = Integer.getInteger(\"jfrviewer.browserItemsLimit\", 100); // NOI18N\n    private static final String ITEMS_LIMIT_STR = NumberFormat.getInstance().format(ITEMS_LIMIT);\n    \n    static enum EventsFilter {\n        ALL { @Override public String toString() { return \"All Events\"; } },\n        FIRST_N { @Override public String toString() { return \"First \" + ITEMS_LIMIT_STR + \" Events\"; } },\n        MIDDLE_N { @Override public String toString() { return \"Middle \" + ITEMS_LIMIT_STR + \" Events\"; } },\n        LAST_N { @Override public String toString() { return \"Last \" + ITEMS_LIMIT_STR + \" Events\"; } },\n        SAMPLE_N { @Override public String toString() { return \"Sample \" + ITEMS_LIMIT_STR + \" Events\"; } },\n    }\n\n    static abstract class MasterViewSupport extends JPanel implements JFREventVisitor {\n        \n        private EventsFilter lastPrimary;\n        private boolean lastExperimental;\n        \n\n        MasterViewSupport(JFRModel model) {\n            initComponents(model);\n        }\n        \n        \n        abstract void firstShown();\n        \n        abstract void eventsFilterChanged(EventsFilter newFilter);\n        \n        abstract void includeExperimentalChanged(boolean newExperimental);\n        \n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            return false;\n        }\n\n        @Override\n        public void done() {\n        }\n        \n\n        DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(\"Browser\", null, this);  // NOI18N\n        }\n        \n        \n        private void updateFilterHint() {\n            thirdLabel.setVisible(!EventsFilter.ALL.equals(lastPrimary) && !EventsFilter.SAMPLE_N.equals(lastPrimary));\n        }\n        \n        private void updateUpdateButton() {\n            if (updateButton != null) updateButton.setEnabled(lastExperimental != (secondChoice != null && secondChoice.isSelected()));\n        }\n        \n        \n        private int prefHeight = -1;\n        public Dimension getPreferredSize() {\n            Dimension pref = super.getPreferredSize();\n            if (prefHeight == -1) prefHeight = pref.height;\n            else pref.height = prefHeight;\n            return pref;\n        }\n        \n\n        private void initComponents(JFRModel model) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            if (model == null) {\n                add(MessageComponent.notAvailable(), BorderLayout.CENTER);\n            } else {\n                setLayout(new GridBagLayout());\n                setBorder(BorderFactory.createEmptyBorder(11, 5, 20, 5));\n\n                GridBagConstraints constraints;\n\n                // firstLabel\n                firstLabel = new JLabel();\n                firstLabel.setText(\"Display:\");\n                firstLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 0;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(firstLabel, constraints);\n\n                // firstCombo\n                firstCombo = new JComboBox<>(new EventsFilter[] { EventsFilter.ALL, EventsFilter.FIRST_N, EventsFilter.MIDDLE_N, EventsFilter.LAST_N, EventsFilter.SAMPLE_N });\n                firstCombo.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        if (lastPrimary != firstCombo.getSelectedItem()) {\n                            lastPrimary = (EventsFilter)firstCombo.getSelectedItem();\n                            updateFilterHint();\n                            eventsFilterChanged(lastPrimary);\n                        }\n                    }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 1;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(firstCombo, constraints);\n                \n                // secondLabel\n                secondLabel = new JLabel();\n                secondLabel.setText(\"of the selected type\");\n                secondLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 2;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(secondLabel, constraints);\n                \n                // thirdLabel\n                thirdLabel = new JLabel();\n                thirdLabel.setText(\"(by position in the file)\");\n                thirdLabel.setToolTipText(\"<html>Events might not be ordered in the file by their creation time.<br>First/Middle/Last means position in the file, not the creation time.</html>\");\n                thirdLabel.setOpaque(false);\n                thirdLabel.setEnabled(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 3;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 5, 0, 0);\n                add(thirdLabel, constraints);\n                \n                lastPrimary = (EventsFilter)firstCombo.getSelectedItem();\n                updateFilterHint();\n                eventsFilterChanged(lastPrimary);\n\n                if (model.getExperimentalEventsCount() > 0) {\n                    // updateSeparator\n                    JSeparator updateSeparator = new JSeparator(JSeparator.VERTICAL);\n                    updateSeparator.setOpaque(false);\n                    constraints = new GridBagConstraints();\n                    constraints.gridx = 4;\n                    constraints.gridy = 2;\n                    constraints.gridwidth = 1;\n                    constraints.fill = GridBagConstraints.NONE;\n                    constraints.anchor = GridBagConstraints.WEST;\n                    constraints.insets = new Insets(4, secondChoice == null ? 16 : 12, 0, 0);\n                    add(updateSeparator, constraints);\n                    \n                    secondChoice = new JCheckBox(\"Display experimental items\");\n                    secondChoice.setOpaque(false);\n                    secondChoice.addActionListener(new ActionListener() {\n                        public void actionPerformed(ActionEvent e) { updateUpdateButton(); }\n                    });\n                    constraints = new GridBagConstraints();\n                    constraints.gridx = 5;\n                    constraints.gridy = 2;\n                    constraints.gridwidth = 1;\n                    constraints.fill = GridBagConstraints.NONE;\n                    constraints.anchor = GridBagConstraints.WEST;\n                    constraints.insets = new Insets(4, 10, 0, 0);\n                    add(secondChoice, constraints);\n                    \n                    // updateButton\n                    updateButton = new JButton(\"Update Data\");\n                    updateButton.addActionListener(new ActionListener() {\n                        public void actionPerformed(ActionEvent e) {\n                            updateButton.setEnabled(false);\n                            \n                            if (lastExperimental != secondChoice.isSelected()) {\n                                lastExperimental = secondChoice.isSelected();\n                                includeExperimentalChanged(lastExperimental);\n                            }\n                        }\n                    });\n                    constraints = new GridBagConstraints();\n                    constraints.gridx = 6;\n                    constraints.gridy = 2;\n                    constraints.gridwidth = 1;\n                    constraints.fill = GridBagConstraints.NONE;\n                    constraints.anchor = GridBagConstraints.WEST;\n                    constraints.insets = new Insets(4, 12, 0, 0);\n                    add(updateButton, constraints);\n                    \n                    Dimension cpuD = firstCombo.getPreferredSize();\n                    Dimension sepD = updateSeparator.getPreferredSize();\n                    sepD.height = cpuD.height - 2;\n                    sepD.width = 5;\n                    updateSeparator.setPreferredSize(sepD);\n                    updateSeparator.setMinimumSize(sepD);\n                    \n                    lastExperimental = secondChoice != null && secondChoice.isSelected();\n                    updateUpdateButton();\n                }\n\n                // filler1\n                constraints = new GridBagConstraints();\n                constraints.gridx = 7;\n                constraints.gridy = 2;\n                constraints.weightx = 1;\n                constraints.weighty = 1;\n                constraints.gridwidth = GridBagConstraints.REMAINDER;\n                constraints.fill = GridBagConstraints.BOTH;\n                constraints.anchor = GridBagConstraints.NORTHWEST;\n                constraints.insets = new Insets(0, 0, 0, 0);\n                add(Spacer.create(), constraints);\n                \n                addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                            if (isShowing()) {\n                                removeHierarchyListener(this);\n                                SwingUtilities.invokeLater(MasterViewSupport.this::firstShown);\n                            }\n                        }\n                    }\n                });\n            }\n        }\n        \n        private JLabel firstLabel;\n        private JLabel secondLabel;\n        private JLabel thirdLabel;\n        private JComboBox<EventsFilter> firstCombo;\n        private JCheckBox secondChoice;\n        private JButton updateButton;\n\n    }\n    \n    \n    static abstract class EventsTreeViewSupport extends JPanel implements JFREventTypeVisitor {\n        \n        private boolean includeExperimental;\n        \n        private Map<String, JFREventType> types;\n        \n        private DataModel tableModel;\n        private ProfilerTreeTable table;\n        \n        private boolean selectionPaused = false;\n        \n\n        EventsTreeViewSupport(long eventsCount) {\n            initComponents(eventsCount);\n        }\n        \n        \n        abstract void eventsSelected(String eventType, long eventsCount, List<JFRDataDescriptor> dataDescriptors);\n        \n        \n        void pauseSelection() {\n            selectionPaused = true;\n        }\n        \n        void refreshSelection() {\n            if (selectionPaused) return;\n            \n            BrowserNode node = getSelectedNode();\n            BrowserNode.EventType typeNode = node instanceof BrowserNode.EventType ? (BrowserNode.EventType)node : null;\n            if (typeNode == null) eventsSelected(null, -1, null);\n            else eventsSelected(typeNode.typeName, typeNode.eventsCount, typeNode.type.getDisplayableDataDescriptors(includeExperimental));\n        }\n        \n        \n        void setIncludeExperimental(boolean experimental) {\n            includeExperimental = experimental;\n        }\n        \n        \n        public void initTypes() {\n            types = new HashMap<>();\n        }\n    \n        public boolean visitType(String typeName, JFREventType eventType) {\n            if (includeExperimental || !eventType.isExperimental()) types.put(typeName, eventType);\n            return false;\n        }\n        \n        \n        JFREventVisitor getVisitor() {\n            return new BrowserNode.Root() {\n                @Override\n                public void done() {\n                    super.done();\n                    \n                    tableModel.setRoot(this);\n                    initialExpand(table, this);\n                    \n                    selectionPaused = false;\n                    refreshSelection();\n                }\n                @Override\n                JFREventType type(String typeName) {\n                    return types.get(typeName);\n                }\n            };\n        }\n        \n\n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Types\", null, 10, this, null);  // NOI18N\n        }\n\n        \n        private void initComponents(long eventsCount) {\n            tableModel = new DataModel();\n            table = new ProfilerTreeTable(tableModel, true, true, new int[] { 0 });\n            \n            table.setRootVisible(false);\n            table.setShowsRootHandles(true);\n\n            table.setMainColumn(0);\n            table.setFitWidthColumn(0);\n\n            table.setDefaultSortOrder(SortOrder.ASCENDING);\n            table.setDefaultSortOrder(2, SortOrder.DESCENDING);\n            table.setSortColumn(0);\n            \n            final BrowserRenderers.NameRenderer nameRenderer = new BrowserRenderers.NameRenderer();\n            nameRenderer.setShowsCount(!BrowserRenderers.EventsCountRenderer.isInitiallyVisible());\n            table.setTreeCellRenderer(nameRenderer);\n            \n            BrowserRenderers.TypeIDRenderer typeIDRenderer = new BrowserRenderers.TypeIDRenderer();\n            table.setColumnRenderer(1, typeIDRenderer);\n            table.setDefaultColumnWidth(1, typeIDRenderer.getPreferredWidth());\n            table.setColumnVisibility(1, BrowserRenderers.TypeIDRenderer.isInitiallyVisible());\n            \n            BrowserRenderers.EventsCountRenderer eventsCountRenderer = new BrowserRenderers.EventsCountRenderer();\n            HideableBarRenderer eventsCountRendererH = new HideableBarRenderer(eventsCountRenderer, eventsCountRenderer.getPreferredWidth());\n            eventsCountRendererH.setMaxValue(eventsCount);\n            table.setColumnRenderer(2, eventsCountRendererH);\n            table.setDefaultColumnWidth(2, eventsCountRendererH.getOptimalWidth());\n            table.setColumnVisibility(2, BrowserRenderers.EventsCountRenderer.isInitiallyVisible());\n            \n            table.getColumnModel().getColumn(2).addPropertyChangeListener(new PropertyChangeListener() {\n                @Override\n                public void propertyChange(PropertyChangeEvent evt) {\n                    if (\"maxWidth\".equals(evt.getPropertyName())) { // NOI18N\n                        nameRenderer.setShowsCount(Integer.valueOf(0).equals(evt.getNewValue()));\n                        table.repaint();\n                    }\n                }\n            });\n\n            table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n                @Override\n                public void valueChanged(ListSelectionEvent e) {\n                    if (!e.getValueIsAdjusting()) refreshSelection();\n                }\n            });\n            \n            setLayout(new BorderLayout());\n            add(new ProfilerTableContainer(table, false, null), BorderLayout.CENTER);\n        }\n        \n        private BrowserNode getSelectedNode() {\n            int row = table.getSelectedRow();\n            return row == -1 ? null : (BrowserNode)table.getValueForRow(row);\n        }\n        \n        \n        private static void initialExpand(ProfilerTreeTable table, BrowserNode root) {\n            TreePath path = new TreePath(root);\n            for (BrowserNode node : root.getChildren())\n                table.expandPath(path.pathByAddingChild(node));\n        }\n        \n        \n        private static class DataModel extends ProfilerTreeTableModel.Abstract {\n            \n            DataModel() {\n                super(new BrowserNode.Root(\"reading data...\") {});\n            }\n            \n            \n            @Override\n            public int getColumnCount() {\n                return 3;\n            }\n\n            @Override\n            public Class<?> getColumnClass(int column) {\n                switch (column) {\n                    case 0: return JTree.class;\n                    case 1: return String.class;\n                    case 2: return Long.class;\n                    default: return null;\n                }\n            }\n\n            @Override\n            public String getColumnName(int column) {\n                switch (column) {\n                    case 0: return BrowserRenderers.NameRenderer.getDisplayName();\n                    case 1: return BrowserRenderers.TypeIDRenderer.getDisplayName();\n                    case 2: return BrowserRenderers.EventsCountRenderer.getDisplayName();\n                    default: return null;\n                }\n            }\n\n            @Override\n            public Object getValueAt(TreeNode node, int column) {\n                if (node == null) return null;\n                BrowserNode rnode = (BrowserNode)node;\n                \n                switch (column) {\n                    case 0: return rnode;\n                    case 1: return rnode instanceof BrowserNode.EventType && ((BrowserNode.EventType)rnode).type != null ? ((BrowserNode.EventType)rnode).type.getName() : null;\n                    case 2: return rnode.eventsCount == 0 ? null : rnode.eventsCount;\n                    default: return null;\n                }\n            }\n            \n            @Override\n            public void setValueAt(Object o, TreeNode node, int column) {}\n\n            @Override\n            public boolean isCellEditable(TreeNode node, int column) { return false; }\n            \n        }\n\n    }\n    \n    \n    static abstract class EventsTableViewSupport extends JPanel {\n        \n        private EventsFilter eventsFilter;\n        private boolean includeExperimental;\n        \n        private String[] names;\n        private Comparable[][] values;\n        private long[] ids;\n        \n        private EventsTableModel tableModel;\n        private ProfilerTable table;\n        \n        \n        EventsTableViewSupport() {\n            initComponents();\n        }\n        \n        \n        abstract void idSelected(long id);\n        \n        \n        void setEventsFilter(EventsFilter filter) {\n            eventsFilter = filter;\n        }\n        \n        void setIncludeExperimental(boolean experimental) {\n            includeExperimental = experimental;\n        }\n        \n        \n        JFREventVisitor getVisitor(final String eventType, final long eventsCount, final List<JFRDataDescriptor> dataDescriptors) {\n            return new JFREventVisitor() {\n                private final EventsFilter filter;\n                \n                private final int totalEvents;\n                private final int displayedEvents;\n                \n                private final Comparable[][] newValues;\n                private final long[] newIds;\n\n                private final Comparable[] COMPARABLE_ARR = new Comparable[0];\n                \n                private int dataIndex;\n                private int eventIndex;\n                private int startIndex;\n                \n                private double nextIndex;\n                private double step;\n                \n                {\n                    totalEvents = eventsCount == -1 ? 0 : (int)Math.min(eventsCount, Integer.MAX_VALUE); // NOTE: won't display more than Integer.MAX_VALUE events!\n                    \n                    filter = totalEvents <= ITEMS_LIMIT ? EventsFilter.ALL : eventsFilter;\n                    displayedEvents = EventsFilter.ALL.equals(filter) ? totalEvents : Math.min(totalEvents, ITEMS_LIMIT);\n                \n                    newValues = dataDescriptors == null ? null : new Comparable[displayedEvents][dataDescriptors.size()];\n                    newIds = totalEvents == 0 ? null : new long[displayedEvents];\n                }\n            \n                @Override\n                public void init() {\n                    dataIndex = 0;\n                    eventIndex = -1; // incremented before first access\n                    \n                    switch (filter) {\n                        case ALL: // no filtering\n                        case FIRST_N: // covered by the return condition\n                            startIndex = 0;\n                            break;\n                        case MIDDLE_N:\n                            if (totalEvents <= ITEMS_LIMIT + 1) startIndex = 0;\n                            else startIndex = (totalEvents - ITEMS_LIMIT) / 2;\n                            break;\n                        case LAST_N:\n                            if (totalEvents <= ITEMS_LIMIT) startIndex = 0;\n                            else startIndex = totalEvents - ITEMS_LIMIT;\n                            break;\n                        case SAMPLE_N:\n                            nextIndex = 0;\n                            step = (totalEvents - 1) / (double)(ITEMS_LIMIT - 1);\n                            break;\n                    }\n                    \n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            names = null;\n                            values = dataDescriptors == null ? null : new Comparable[][] { null };\n                            tableModel.fireTableStructureChanged();\n                        }\n                    });\n                }\n                \n                @Override\n                public boolean visit(String typeName, JFREvent event) {\n                    if (eventType == null) return true;\n                    \n                    if (eventType.equals(typeName)) {\n                        eventIndex++;\n                        \n                        switch (filter) {\n                            case ALL: // no filtering\n                            case FIRST_N: // covered by the return condition\n                                break;\n                            case MIDDLE_N:\n                            case LAST_N:\n                                if (eventIndex < startIndex) return false;\n                                break;\n                            case SAMPLE_N:\n                                if (eventIndex == Math.round(nextIndex) || eventIndex == totalEvents - 1) nextIndex += step; // extra check for last item (might miss last event due to rounding bias)\n                                else return false;\n                                break;\n                        }\n                        \n                        newIds[dataIndex] = event.getID();\n                        newValues[dataIndex++] = event.getDisplayableValues(includeExperimental).toArray(COMPARABLE_ARR);\n                    }\n                    \n                    return dataIndex == displayedEvents;\n                }\n                \n                @Override\n                public void done() {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            List<String> tooltips = new ArrayList<>();\n                            List<ProfilerRenderer> renderers = new ArrayList<>();\n                            \n                            if (dataDescriptors != null) {\n                                int namesIndex = 0;\n                                names = new String[dataDescriptors.size()];\n                                for (JFRDataDescriptor descriptor : dataDescriptors) {\n                                    String dataName = descriptor.getDataName();\n                                    names[namesIndex++] = dataName;\n                                    \n                                    String dataDescription = descriptor.getDataDescription();\n                                    tooltips.add(dataDescription != null && !dataDescription.isEmpty() ? dataDescription : dataName);\n                                    \n                                    Format format = descriptor.getDataFormat();\n                                    LabelRenderer renderer = format == null ? new LabelRenderer() : new FormattedLabelRenderer(format);\n                                    if (descriptor.isNumericData()) renderer.setHorizontalAlignment(LabelRenderer.TRAILING);\n                                    renderers.add(renderer);\n                                }\n                            }\n                            \n                            values = newValues;\n                            ids = newIds;\n                            tableModel.fireTableStructureChanged();\n                            \n                            table.setSortColumn(0);\n                            \n                            table.setColumnToolTips(tooltips.toArray(new String[0]));\n                            \n                            for (int column = 0; column < renderers.size(); column++)\n                                table.setColumnRenderer(column, renderers.get(column));\n                        }\n                    });\n                }\n            };\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Events\", null, 10, this, null);  // NOI18N\n        }\n        \n        \n        private void initComponents() {\n            tableModel = new EventsTableModel();\n            table = new ProfilerTable(tableModel, true, true, null);\n\n            table.setFitWidthColumn(-1);\n            table.setSorting(0, SortOrder.UNSORTED);\n            table.setDefaultSortOrder(SortOrder.ASCENDING);\n            table.setDefaultRenderer(Comparable.class, new LabelRenderer());\n            \n            table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent e) {\n                    if (!e.getValueIsAdjusting()) {\n                        int selected = table.getSelectedRow();\n                        if (selected == 0 && values[0] == null) selected = -1; // \"loading events...\"\n                        idSelected(selected == -1 ? -1 : ids[table.convertRowIndexToModel(selected)]);\n                    }\n                }\n            });\n            \n            setLayout(new BorderLayout());\n            add(new ProfilerTableContainer(table, false, null), BorderLayout.CENTER);\n        }\n        \n        \n        private class EventsTableModel extends AbstractTableModel {\n        \n            public String getColumnName(int columnIndex) {\n                return names == null ? \" \" : names[columnIndex];\n            }\n\n            public Class<?> getColumnClass(int columnIndex) {\n                return Comparable.class;\n            }\n\n            public int getRowCount() {\n                return values == null ? 0 : values.length;\n            }\n\n            public int getColumnCount() {\n                return names == null ? 1 : names.length;\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                Comparable[] row = values[rowIndex];\n                if (row == null) return columnIndex == 0 ? \"loading events...\" : \"\";\n                else return row[columnIndex];\n            }\n\n        }\n        \n    }\n    \n    \n    static abstract class StackTraceViewSupport extends JPanel {\n        \n        private static final RequestProcessor PROCESSOR = new RequestProcessor(\"JFR StackTrace Processor\"); // NOI18N\n        \n        private static final DefaultMethodNameFormatter METHOD_FORMAT = new DefaultMethodNameFormatter();\n        \n        private HTMLTextArea area;\n        \n        private boolean showing; // accessed in EDT only\n        private long pendingID = -1; // accessed in EDT only\n        \n        private long currentID = Long.MIN_VALUE; // accessed in EDT only\n        private RequestProcessor.Task currentTask; // accessed in EDT only\n        \n        \n        StackTraceViewSupport() {\n            initComponents();\n            \n            addHierarchyListener(new HierarchyListener() {\n                public void hierarchyChanged(HierarchyEvent e) {\n                    if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                        showing = StackTraceViewSupport.this.isShowing();\n                        if (showing && pendingID != Long.MIN_VALUE) {\n                            idSelected(pendingID);\n                            pendingID = Long.MIN_VALUE;\n                        }\n                    }\n                }\n            });\n        }\n        \n        abstract JFREvent getEvent(long id);\n        \n        // invoked in EDT\n        void idSelected(final long id) {\n            if (!showing) {\n                pendingID = id;\n                return;\n            }\n            \n            if (id == currentID) return;\n            \n            if (id == -1) {\n                currentID = -1;\n                setText(\"<nobr>&lt;no event selected&gt;</nobr>\");\n            } else {\n                currentID = id;\n                setText(\"<nobr>&lt;reading stack trace...&gt;</nobr>\");\n                \n                if (currentTask != null) currentTask.cancel();\n                \n                currentTask = PROCESSOR.post(new Runnable() {\n                    public void run() {\n                        JFREvent event = getEvent(id);\n                        \n                        JFRStackTrace stack;\n                        try {\n                            stack = event.getStackTrace(\"eventStackTrace\"); // NOI18N\n                        } catch (JFRPropertyNotAvailableException e) {\n                            stack = null;\n                        }\n                        \n                        final String stackTrace = formatStackTrace(stack);\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                if (currentID == id) {\n                                    setText(stackTrace);\n                                    currentTask = null;\n                                }\n                            }\n                        });\n                    }\n                });\n            }\n        }\n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Stack Trace\", null, 10, this, null);  // NOI18N\n        }\n        \n        private static String formatStackTrace(JFRStackTrace stack) {\n            if (stack == null) return \"<nobr>&lt;no stack trace&gt;</nobr>\";\n            \n            StringBuilder sb = new StringBuilder();\n            \n            String header = \"<nobr><code>\"; // NOI18N\n            sb.append(header);\n            \n            for (JFRStackFrame frame : stack.getFrames())\n                sb.append(formatStackFrame(frame)).append(\"<br>\"); // NOI18N\n            \n            if (sb.length() == header.length()) return \"<nobr>&lt;empty stack trace&gt;</nobr>\";\n            \n            if (stack.isTruncated()) sb.append(\"&lt;...truncated...&gt;\").append(\"<br>\");\n            \n            sb.append(\"</code></nobr>\"); // NOI18N\n            \n            return sb.toString();\n        }\n        \n        private static String formatStackFrame(JFRStackFrame frame) {\n            JFRMethod method = frame.getMethod();\n            int line = frame.getLine();\n            int bci = frame.getBCI();\n            String type = frame.getType();\n            \n            String fullName = METHOD_FORMAT.formatMethodName(method.getType().getName(), method.getName(), method.getDescriptor()).toFormatted();\n            int idx = fullName.indexOf(\" : \"); // NOI18N\n            String methodName = idx == -1 ? fullName : fullName.substring(0, idx);\n//            String returnName = fullName.substring(idx);\n\n            String ret = methodName;\n            if (line != -1) ret += \":\" + line; // NOI18N\n            ret += \"; \"; // NOI18N\n            if (bci > 0) ret += \"bci=\" + bci + \", \"; // NOI18N\n            ret += type;\n            \n            return ret.replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\"); // NOI18N\n        }\n        \n        private void setText(String text) {\n            area.setText(text);\n            area.setCaretPosition(0);\n        }\n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea();\n            area.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));\n\n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n            add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/browser/JFRSnapshotBrowserView.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.browser;\n\nimport java.util.List;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFRDataDescriptor;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventTypeVisitor;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JFRSnapshotBrowserView extends JFRViewTab {\n    \n    JFRSnapshotBrowserView(JFRSnapshot snapshot) {\n        super(snapshot, \"Browser\", Icons.getImage(GeneralIcons.FIND), 80);    // NOI18N\n    }\n    \n    \n    @Override\n    protected DataViewComponent createComponent() {\n        JFRModel model = getModel();\n        \n        if (model == null) {\n            BrowserViewSupport.MasterViewSupport masterView = new BrowserViewSupport.MasterViewSupport(model) {\n                @Override\n                void firstShown() {}\n                @Override\n                void eventsFilterChanged(BrowserViewSupport.EventsFilter newFilter) {}\n                @Override\n                void includeExperimentalChanged(boolean newExperimental) {}\n            };\n\n            return new DataViewComponent(\n                    masterView.getMasterView(),\n                    new DataViewComponent.MasterViewConfiguration(true));\n        } else {\n            final BrowserViewSupport.StackTraceViewSupport stackTracePane = new BrowserViewSupport.StackTraceViewSupport() {\n                @Override\n                JFREvent getEvent(long id) {\n                    return model.getEvent(id);\n                }\n            };\n            \n            final BrowserViewSupport.EventsTableViewSupport eventsTable = new BrowserViewSupport.EventsTableViewSupport() {\n                @Override\n                void idSelected(long id) {\n                    stackTracePane.idSelected(id);\n                }\n            };\n            eventsTable.setIncludeExperimental(false);\n            eventsTable.setEventsFilter(BrowserViewSupport.EventsFilter.ALL);\n\n            final BrowserViewSupport.EventsTreeViewSupport eventsTree = new BrowserViewSupport.EventsTreeViewSupport(model.getEventsCount()) {\n                @Override\n                void eventsSelected(String eventType, long eventsCount, List<JFRDataDescriptor> dataDescriptors) {\n                    initialize(null, eventsTable.getVisitor(eventType, eventsCount, dataDescriptors));\n                }\n            };\n            eventsTree.setIncludeExperimental(false);\n\n            BrowserViewSupport.MasterViewSupport masterView = new BrowserViewSupport.MasterViewSupport(model) {\n                @Override\n                void firstShown() {\n                    initialize(eventsTree, this, eventsTree.getVisitor());\n                }\n                @Override\n                void eventsFilterChanged(BrowserViewSupport.EventsFilter newFilter) {\n                    eventsTable.setEventsFilter(newFilter);\n                    eventsTree.refreshSelection();\n                }\n                @Override\n                void includeExperimentalChanged(boolean newExperimental) {\n                    eventsTree.setIncludeExperimental(newExperimental);                        \n                    eventsTable.setIncludeExperimental(newExperimental);\n                    \n                    eventsTree.pauseSelection();\n                    initialize(eventsTree, this, eventsTree.getVisitor());\n                }\n            };\n\n            DataViewComponent dvc = new DataViewComponent(\n                    masterView.getMasterView(),\n                    new DataViewComponent.MasterViewConfiguration(false));\n\n            dvc.configureDetailsView(new DataViewComponent.DetailsViewConfiguration(0.35, 0, -1, -1, 0.65, 1));\n\n            dvc.addDetailsView(eventsTree.getDetailsView(), DataViewComponent.TOP_LEFT);\n            dvc.addDetailsView(eventsTable.getDetailsView(), DataViewComponent.TOP_RIGHT);\n            dvc.addDetailsView(stackTracePane.getDetailsView(), DataViewComponent.BOTTOM_RIGHT);\n            \n            dvc.hideDetailsArea(DataViewComponent.BOTTOM_RIGHT);\n\n            return dvc;\n        }\n    }\n    \n    \n    private void initialize(final JFREventTypeVisitor typeVisitor, final JFREventVisitor... visitors) {\n        new RequestProcessor(\"JFR Events Browser Initializer\").post(new Runnable() { // NOI18N\n            public void run() {\n                if (typeVisitor != null) getModel().visitEventTypes(typeVisitor);\n                getModel().visitEvents(visitors);\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/browser/JFRSnapshotBrowserViewProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.browser;\n\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.jfr.view.JFRViewTabProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=JFRViewTabProvider.class)\npublic class JFRSnapshotBrowserViewProvider extends JFRViewTabProvider {\n\n    @Override\n    protected JFRViewTab createView(JFRSnapshot jfrSnapshot) {\n        return new JFRSnapshotBrowserView(jfrSnapshot);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/components/MessageComponent.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.components;\n\nimport java.awt.BorderLayout;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class MessageComponent extends JPanel {\n    \n    public MessageComponent(String message) {\n        JLabel notSupportedLabel = new JLabel(message, SwingConstants.CENTER);    // NOI18N\n        notSupportedLabel.setEnabled(false);\n\n        setLayout(new BorderLayout());\n        setOpaque(false);\n        \n        add(notSupportedLabel, BorderLayout.CENTER);\n    }\n    \n    public static JComponent notAvailable() {\n        return new MessageComponent(\"Not available for this JFR snapshot.\");\n    }\n    \n    public static JComponent scrollable(String message) {\n        MessageComponent cm = new MessageComponent(message);\n        cm.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n        return new ScrollableContainer(cm);\n    }\n    \n    public static JComponent noData(String viewName, String[] eventTypes) {\n        StringBuilder sb = new StringBuilder();\n        boolean first = true;\n        for (String eventType : eventTypes) {\n            if (!first) sb.append(\", \");\n            else first = false;\n            sb.append(eventType);\n        }\n        \n        return scrollable(\"<html><b>No \" + viewName + \" data recorded.</b><br><br><br>\" +\n                          \"To analyze the \" + viewName + \" data make sure the JFR snapshot contains events of the following type(s):<br><br>\" +\n                          \"<code>\" + sb.toString() + \"</code></html>\");\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/environment/EnvironmentViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.environment;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.text.NumberFormat;\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.TreeMap;\nimport java.util.TreeSet;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.charts.ChartFactory;\nimport org.graalvm.visualvm.charts.SimpleXYChartDescriptor;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.jfr.utils.TimeRecord;\nimport org.graalvm.visualvm.jfr.views.components.MessageComponent;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextAreaSearchUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class EnvironmentViewSupport {\n    \n    static abstract class MasterViewSupport extends JPanel implements JFREventVisitor {\n\n        private String osInfo = \"<nobr><b>OS:</b> &lt;unknown&gt;</nbsp>\";\n        private String cpuInfo = \"<nobr><b>CPU:</b> &lt;unknown&gt;</nbsp>\";\n        private String memInfo = \"<nobr><b>Memory:</b> &lt;unknown&gt;</nbsp>\";\n        \n        private HTMLTextArea area;\n\n        \n        MasterViewSupport(JFRModel model) {\n            initComponents(model);\n        }\n        \n        \n        abstract void firstShown();\n\n        \n        DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(\"Environment\", null, this);\n        }\n        \n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (JFRSnapshotEnvironmentViewProvider.EVENT_OS_INFO.equals(typeName)) { // NOI18N\n                try {\n                    osInfo = formatOSInfo(event.getString(\"osVersion\")); // NOI18N\n                } catch (JFRPropertyNotAvailableException e) {\n                    osInfo = \"<not available>\";\n                }\n            } else if (JFRSnapshotEnvironmentViewProvider.EVENT_CPU_INFO.equals(typeName)) { // NOI18N\n                try {\n                    cpuInfo = formatCPUInfo(event.getString(\"description\")); // NOI18N\n                } catch (JFRPropertyNotAvailableException e) {\n                    osInfo = \"<nobr><b>OS:</b> &lt;not available&gt;</nbsp>\";\n                }\n            } else if (JFRSnapshotEnvironmentViewProvider.EVENT_PHYSICAL_MEMORY.equals(typeName)) { // NOI18N\n                try {\n                    memInfo = formatMemInfo(event.getLong(\"totalSize\")); // NOI18N\n                } catch (JFRPropertyNotAvailableException e) {\n                    memInfo = \"<nobr><b>Memory:</b> &lt;not available&gt;</nbsp>\";\n                }\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    area.setText(cpuInfo + \"<br>\" + memInfo + \"<br>\" + osInfo);\n                    \n                    osInfo = null;\n                    cpuInfo = null;\n                    memInfo = null;\n                }\n            });\n        }\n        \n        \n        private static String formatOSInfo(String os) {\n            String[] s = os.split(\"\\\\r?\\\\n\"); // NOI18N\n            \n//            // TODO: String.lines() only available in Java 11+, change to support 8!\n//            os.lines().forEach(new Consumer<String>() {\n//                @Override\n//                public void accept(String t) {\n//                    if (s[0] == null && !t.isBlank()) s[0] = t.trim();\n//                }\n//            });\n\n            s[0] = s[0].trim();\n            \n            if (s[0].startsWith(\"OS:\")) s[0] = s[0].substring(\"OS:\".length()).trim(); // NOI18N\n            if (s[0].startsWith(\"uname:\")) s[0] = s[0].substring(\"uname:\".length()).trim(); // NOI18N\n            if (s[0].startsWith(\"Bsduname:\")) s[0] = s[0].substring(\"Bsduname:\".length()).trim(); // NOI18N\n            if (s[0].startsWith(\"DISTRIB_ID=\")) s[0] = s[0].substring(\"DISTRIB_ID=\".length()).trim(); // NOI18N\n            \n            if (s[0].isEmpty() && s.length >= 2) s[0] = s[1];\n\n            int i = s[0].indexOf(';'); // NOI18N\n            if (i > 0) s[0] = s[0].substring(0, i).trim();\n            \n            return \"<nobr><b>OS:</b> \" + s[0] + \"</nbsp>\";\n        }\n        \n        private static String formatCPUInfo(String cpu) {\n            String[] s = cpu.split(\"\\\\r?\\\\n\"); // NOI18N\n            \n//            cpu.lines().forEach(new Consumer<String>() {\n//                @Override\n//                public void accept(String t) {\n//                    if (s[0] == null && !t.isBlank()) s[0] = t.trim();\n//                }\n//            });\n\n            s[0] = s[0].trim();\n            \n            if (s[0].startsWith(\"Brand:\")) s[0] = s[0].substring(\"Brand:\".length()).trim(); // NOI18N\n            else return \"<nobr><b>CPU:</b> \" + s[0] + \"</nbsp>\";\n            \n            int i = s[0].indexOf(','); // NOI18N\n            if (i > 0) s[0] = s[0].substring(0, i).trim();\n            \n            return \"<nobr><b>CPU:</b> \" + s[0] + \"</nbsp>\";\n        }\n        \n        private static String formatMemInfo(Long mem) {\n            String s = NumberFormat.getInstance().format(Math.ceil(mem / 1024d / 1024 / 1024)) + \" GB\";\n            return \"<nobr><b>Memory:</b> \" + s + \" (\" + Formatters.bytesFormat().format(new Object[] { mem }) + \")</nbsp>\";\n        }\n        \n\n        private void initComponents(JFRModel model) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            if (model == null) {\n                add(MessageComponent.notAvailable(), BorderLayout.CENTER);\n            } else if (!model.containsEvent(JFRSnapshotEnvironmentViewProvider.EventChecker.class)) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.noData(\"Environment\", JFRSnapshotEnvironmentViewProvider.EventChecker.checkedTypes()), BorderLayout.CENTER);\n            } else {\n                area = new HTMLTextArea(\"<nobr><b>Progress:</b> reading data...</nobr><br><br><br>\");\n                area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n                add(area, BorderLayout.CENTER);\n\n                addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                            if (isShowing()) {\n                                removeHierarchyListener(this);\n                                SwingUtilities.invokeLater(MasterViewSupport.this::firstShown);\n                            }\n                        }\n                    }\n                });\n            }\n        }\n    }\n    \n    \n    static class CPUUtilizationSupport extends JPanel implements JFREventVisitor {\n        \n        private final JFRModel jfrModel;\n        \n        private SimpleXYChartSupport chartSupport;\n        \n        \n        CPUUtilizationSupport(JFRModel jfrModel) {\n            this.jfrModel = jfrModel;\n            \n            initModels();\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"CPU utilization\", null, 10, this, null);\n        }\n        \n        \n        private static final class CPU extends TimeRecord {\n            final long value;\n            CPU(JFREvent event, JFRModel jfrModel) throws JFRPropertyNotAvailableException {\n                super(event, jfrModel);\n                value = Math.round(event.getFloat(\"machineTotal\") * 1000); // NOI18N\n            }\n        }\n        \n        private List<CPU> records;\n        \n        @Override\n        public void init() {\n            records = new ArrayList<>();\n        }\n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {            \n            if (JFRSnapshotEnvironmentViewProvider.EVENT_CPU_LOAD.equals(typeName)) // NOI18N\n                 try { records.add(new CPU(event, jfrModel)); }\n                 catch (JFRPropertyNotAvailableException e) {}\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            records.sort(TimeRecord.COMPARATOR);\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    long lastTime = Long.MIN_VALUE + 1;\n                    for (final CPU record : records) {\n                        long time = jfrModel.nsToAbsoluteMillis(record.time);\n                        if (time <= lastTime) time = lastTime + 1;\n                        chartSupport.addValues(time, new long[] { record.value });\n                        lastTime = time;\n                    }\n\n                    if (!records.isEmpty()) {\n                        CPU last = records.get(records.size() - 1);\n                        records.clear();\n                        \n                        String cpuDetail = chartSupport.formatPercent(last.value);\n                        chartSupport.updateDetails(new String[] { cpuDetail });\n                    }\n                    \n                    records = null;\n                }\n            });\n        }\n\n        private void initModels() {\n            SimpleXYChartDescriptor chartDescriptor =\n                    SimpleXYChartDescriptor.percent(false, 0.1d, Integer.MAX_VALUE);\n\n            chartDescriptor.addLineItems(\"Machine\");\n            chartDescriptor.setDetailsItems(new String[] { \"Machine\" });\n\n            chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n\n            chartSupport.setZoomingEnabled(true);\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            add(chartSupport.getChart(), BorderLayout.CENTER);\n            chartSupport.updateDetails(new String[] { \"&lt;unknown&gt;\" });\n        }\n        \n    }\n    \n    \n    static class NetworkUtilizationSupport extends JPanel implements JFREventVisitor {\n        \n        private final JFRModel jfrModel;\n        \n        private SimpleXYChartSupport chartSupport;\n        \n        \n        NetworkUtilizationSupport(JFRModel jfrModel) {\n            this.jfrModel = jfrModel;\n            \n            initModels();\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Network utilization\", null, 20, this, null);\n        }\n        \n        \n        private static final class Network extends TimeRecord {\n            long read;\n            long write;\n            Network(JFREvent event, JFRModel jfrModel) throws JFRPropertyNotAvailableException {\n                super(event, jfrModel);\n                read = event.getLong(\"readRate\"); // NOI18N\n                write = event.getLong(\"writeRate\"); // NOI18N\n            }\n            void add(JFREvent event) {\n                try {\n                    long readRate = event.getLong(\"readRate\"); // NOI18N\n                    long writeRate = event.getLong(\"writeRate\"); // NOI18N\n                    read += readRate;\n                    write += writeRate;\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n        }\n        \n        private Map<Long, Network> records;\n        \n        @Override\n        public void init() {\n            records = new TreeMap<>();\n        }\n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {            \n            if (JFRSnapshotEnvironmentViewProvider.EVENT_NETWORK_UTILIZATION.equals(typeName)) { // NOI18N\n                try {\n                    long time = TimeRecord.getTime(event, jfrModel);\n                    Network network = records.get(time);\n                    if (network == null) records.put(time, new Network(event, jfrModel));\n                    else network.add(event);\n                } catch (JFRPropertyNotAvailableException e) {}\n                \n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    Network last = null;\n                    long lastTime = Long.MIN_VALUE + 1;\n                    \n                    for (final Network record : records.values()) {\n                        last = record;\n                        long time = jfrModel.nsToAbsoluteMillis(record.time);\n                        if (time <= lastTime) time = lastTime + 1;\n                        chartSupport.addValues(time, new long[] { record.read, record.write });\n                        lastTime = time;\n                    }\n\n                    if (last != null) {\n                        records.clear();\n                        \n                        String readDetail = chartSupport.formatBytes(last.read);\n                        String writeDetail = chartSupport.formatBytes(last.write);\n                        chartSupport.updateDetails(new String[] { readDetail, writeDetail });\n                    }\n                    \n                    records = null;\n                }\n            });\n        }\n\n        private void initModels() {\n            SimpleXYChartDescriptor chartDescriptor =\n                    SimpleXYChartDescriptor.bytes(10 * 1024 * 1024, false, Integer.MAX_VALUE);\n\n            chartDescriptor.addLineItems(\"Read rate\", \"Write rate\");\n            chartDescriptor.setDetailsItems(new String[] { \"Read rate\", \"Write rate\" });\n\n            chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n\n            chartSupport.setZoomingEnabled(true);\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            add(chartSupport.getChart(), BorderLayout.CENTER);\n            chartSupport.updateDetails(new String[] { \"&lt;unknown&gt;\", \"&lt;unknown&gt;\" });\n        }\n        \n    }\n    \n    \n    static class MemoryUsageSupport extends JPanel implements JFREventVisitor {\n        \n        private final JFRModel jfrModel;\n        \n        private SimpleXYChartSupport chartSupport;\n        \n        \n        MemoryUsageSupport(JFRModel jfrModel) {\n            this.jfrModel = jfrModel;\n            \n            initModels();\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Memory usage\", null, 10, this, null);\n        }\n        \n        \n        private static final class Memory extends TimeRecord {\n            final long value;\n            Memory(JFREvent event, JFRModel jfrModel) throws JFRPropertyNotAvailableException {\n                super(event, jfrModel);\n                value = event.getLong(\"usedSize\"); // NOI18N\n            }\n        }\n        \n        private List<Memory> records;\n        private JFREvent lastEvent;\n        private long lastEventTime = Long.MIN_VALUE;\n        \n        @Override\n        public void init() {\n            records = new ArrayList<>();\n        }\n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {            \n            if (JFRSnapshotEnvironmentViewProvider.EVENT_PHYSICAL_MEMORY.equals(typeName)) { // NOI18N\n                try {\n                    Memory record = new Memory(event, jfrModel);\n                    records.add(record);\n                    \n                    if (lastEventTime < record.time) {\n                        lastEvent = event;\n                        lastEventTime = record.time;\n                    }\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            records.sort(TimeRecord.COMPARATOR);\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    long lastTime = Long.MIN_VALUE + 1;\n                    for (final Memory record : records) {\n                        long time = jfrModel.nsToAbsoluteMillis(record.time);\n                        if (time <= lastTime) time = lastTime + 1;\n                        chartSupport.addValues(time, new long[] { record.value });\n                        lastTime = time;\n                    }\n\n                    if (!records.isEmpty()) {\n                        records.clear();\n                        \n                        try {\n                            long usedSize = lastEvent.getLong(\"usedSize\"); // NOI18N\n                            long totalSize = lastEvent.getLong(\"totalSize\"); // NOI18N\n                            chartSupport.updateDetails(new String[] { chartSupport.formatBytes(usedSize),    \n                                                                      chartSupport.formatBytes(totalSize) }); \n                        } catch (JFRPropertyNotAvailableException e) {}\n                    }\n                    \n                    records = null;\n                    lastEvent = null;\n                    \n                    records = null;\n                }\n            });\n        }\n\n        private void initModels() {\n            SimpleXYChartDescriptor chartDescriptor =\n                    SimpleXYChartDescriptor.bytes(10 * 1024 * 1024, false, Integer.MAX_VALUE);\n\n            chartDescriptor.addLineFillItems(\"Used\");\n            chartDescriptor.setDetailsItems(new String[] { \"Used\", \"Total\" });\n\n            chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n\n            chartSupport.setZoomingEnabled(true);\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            add(chartSupport.getChart(), BorderLayout.CENTER);\n            chartSupport.updateDetails(new String[] { \"&lt;unknown&gt;\" });\n        }\n        \n    }\n    \n    \n    static class CPUDetailsSupport extends JPanel implements JFREventVisitor {\n        \n        private volatile boolean initialized = false;\n        \n        private HTMLTextArea area;\n        \n        \n        CPUDetailsSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"CPU details\", null, 10, this, null);\n        }\n        \n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (JFRSnapshotEnvironmentViewProvider.EVENT_CPU_INFO.equals(typeName)) { // NOI18N\n                try {\n                    final String type = event.getString(\"cpu\"); // NOI18N\n                    final int sockets = event.getInt(\"sockets\"); // NOI18N\n                    final int cores = event.getInt(\"cores\"); // NOI18N\n                    final int threads = event.getInt(\"hwThreads\"); // NOI18N\n                    final String description = formatDescription(event.getString(\"description\")); // NOI18N\n                    \n                    initialized = true;\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            area.setText(\n                                    \"<b>Chips:</b>&nbsp;\" + sockets + \"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\" +\n                                    \"<b>Cores:</b>&nbsp;\" + cores + \"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\" +\n                                    \"<b>Threads:</b>&nbsp;\" + threads + \"<br><br>\" +\n                                    \"<b>Type:</b>&nbsp;\" + type + \"<br><br>\" +\n                                    /*\"<b>Details:</b>&nbsp;\" +*/ description\n                            );\n                            area.setCaretPosition(0);\n                        }\n                    });\n                } catch (JFRPropertyNotAvailableException e) {}\n                \n                return true;\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            if (!initialized) SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    area.setText(\"&lt;unknown&gt;\");\n                    area.setCaretPosition(0);\n                    initialized = true;\n                }\n            });\n        }\n        \n        \n        private static String formatDescription(String description) {\n            if (description.startsWith(\"Brand: \")) { // NOI18N\n                String[] parts = description.split(\"Supports: \"); // NOI18N\n                if (parts != null && parts.length == 2) {\n                    return parts[0].replaceAll(\"((((?m)^)|(, ))(\\\\p{Upper}[^:,]+): )\", \"$2<b>$5:</b> \") + // NOI18N\n                           \"<b>Supports:</b> \" + parts[1]; // NOI18N\n                }\n            }\n            \n            return description;\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n            add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n    }\n    \n    \n    static class OSDetailsSupport extends JPanel implements JFREventVisitor {\n        \n        private volatile boolean initialized = false;\n        \n        private HTMLTextArea area;\n        \n        \n        OSDetailsSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"OS details\", null, 20, this, null);\n        }\n        \n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (JFRSnapshotEnvironmentViewProvider.EVENT_OS_INFO.equals(typeName)) { // NOI18N\n                try {\n                    final String version = event.getString(\"osVersion\"); // NOI18N\n                    \n                    initialized = true;\n                \n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            area.setText(version);\n                            area.setCaretPosition(0);\n                        }\n                    });\n                } catch (JFRPropertyNotAvailableException e) {}\n                \n                return true;\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            if (!initialized) SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    area.setText(\"&lt;unknown&gt;\");\n                    area.setCaretPosition(0);\n                    initialized = true;\n                }\n            });\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n            add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n    }\n    \n    \n    static class NetworkDetailsSupport extends JPanel implements JFREventVisitor {\n        \n        private Set<String> data;\n        \n        private HTMLTextArea area;\n        \n        \n        NetworkDetailsSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Network details\", null, 30, this, null);\n        }\n        \n        \n        @Override\n        public void init() {\n            data = new TreeSet<>();\n        }\n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (JFRSnapshotEnvironmentViewProvider.EVENT_NETWORK_UTILIZATION.equals(typeName)) { // NOI18N\n                try {\n                    data.add(event.getString(\"networkInterface\")); // NOI18N\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            final StringBuilder s = new StringBuilder();\n            \n            Iterator<String> it = data.iterator();\n            if (!it.hasNext()) {\n                s.append(\"&lt;unknown&gt;\");\n            } else {\n                s.append(\"<nobr><b>Network interfaces:</b></nobr><br>\");\n                while (it.hasNext()) {\n                    s.append(it.next());\n                    if (it.hasNext()) s.append(\"<br>\"); // NOI18N\n                }\n            }\n            \n            data.clear();\n            data = null;\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    area.setText(s.toString());\n                    area.setCaretPosition(0);\n                }\n            });\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n            add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n    }\n    \n    \n    static class EnvVarSupport extends JPanel implements JFREventVisitor {\n        \n        private Map<String, String> data;\n        \n        private HTMLTextArea area;\n        \n        \n        EnvVarSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Environment variables\", null, 40, this, null);\n        }\n        \n        \n        @Override\n        public void init() {\n            data = new TreeMap<>();\n        }\n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (JFRSnapshotEnvironmentViewProvider.EVENT_ENVIRONMENT_VARIABLE.equals(typeName)) { // NOI18N\n                try {\n                    data.put(event.getString(\"key\"), event.getString(\"value\")); // NOI18N\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            final StringBuilder s = new StringBuilder();\n            \n            Iterator<Map.Entry<String, String>> it = data.entrySet().iterator();\n            if (!it.hasNext()) {\n                s.append(\"&lt;unknown&gt;\");\n            } else {\n                while (it.hasNext()) {\n                    Map.Entry<String, String> entry = it.next();\n                    s.append(\"<nobr><b>\" + entry.getKey() + \"</b>=\" + entry.getValue() + \"</nobr>\"); // NOI18N\n                    if (it.hasNext()) s.append(\"<br>\"); // NOI18N\n                }\n            }\n            \n            data.clear();\n            data = null;\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    area.setText(s.toString());\n                    area.setCaretPosition(0);\n                }\n            });\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n            add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n    }\n    \n    \n    static class ProcessesSupport extends JPanel implements JFREventVisitor {\n        \n        private Map<Long, String> data;\n        \n        private HTMLTextArea area;\n        \n        \n        ProcessesSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"System processes\", null, 50, this, null);\n        }\n        \n        \n        @Override\n        public void init() {\n            data = new TreeMap<>();\n        }\n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (JFRSnapshotEnvironmentViewProvider.EVENT_SYSTEM_PROCESS.equals(typeName)) { // NOI18N\n                try {\n                    data.put(Long.parseLong(event.getString(\"pid\")), event.getString(\"commandLine\")); // NOI18N\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            final StringBuilder s = new StringBuilder();\n            \n            \n            \n            if (data.isEmpty()) {\n                s.append(\"&lt;unknown&gt;\");\n            } else {\n                s.append(\"<table border='0' cellpadding='0' cellspacing='0' width='100%'>\");\n                s.append(\"<tr><th align='right' style='margin-bottom:5px;'>PID&nbsp;&nbsp;&nbsp;</th><th align='left' style='margin-bottom:5px;'>Command Line</th></tr>\"); // NOI18N\n                \n                for (Map.Entry<Long, String> entry : data.entrySet()) {\n                    s.append(\"<tr><td align='right'>\"); // NOI18N\n                    s.append(\"<b>\" + entry.getKey() + \"</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\" + entry.getValue()); // NOI18N\n                    s.append(\"</td></tr>\"); // NOI18N\n                }\n                \n                s.append(\"</table>\"); // NOI18N\n            }\n            \n            data.clear();\n            data = null;\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    area.setText(s.toString());\n                    area.setCaretPosition(0);\n                }\n            });\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n            add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/environment/JFRSnapshotEnvironmentView.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.environment;\n\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRSnapshotEnvironmentView extends JFRViewTab {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/environment.png\";  // NOI18N\n    \n    \n    JFRSnapshotEnvironmentView(JFRSnapshot dataSource) {\n        super(dataSource, \"Environment\", new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 90);   // NOI18N\n    }\n\n    \n    @Override\n    protected DataViewComponent createComponent() {\n        JFRModel model = getModel();\n        \n        boolean hasEvents = model != null && model.containsEvent(JFRSnapshotEnvironmentViewProvider.EventChecker.class);\n        \n        if (!hasEvents) {\n            EnvironmentViewSupport.MasterViewSupport masterView = new EnvironmentViewSupport.MasterViewSupport(model) {\n                @Override\n                void firstShown() {}\n            };\n            return new DataViewComponent(masterView.getMasterView(), new DataViewComponent.MasterViewConfiguration(true));\n        } else {\n            EnvironmentViewSupport.CPUUtilizationSupport cpuUtilizationView = new EnvironmentViewSupport.CPUUtilizationSupport(model);\n            EnvironmentViewSupport.NetworkUtilizationSupport networkUtilizationView = new EnvironmentViewSupport.NetworkUtilizationSupport(model);\n            EnvironmentViewSupport.MemoryUsageSupport memoryUsageView = new EnvironmentViewSupport.MemoryUsageSupport(model);\n            EnvironmentViewSupport.CPUDetailsSupport cpuDetailsView = new EnvironmentViewSupport.CPUDetailsSupport();\n            EnvironmentViewSupport.OSDetailsSupport osDetailsView = new EnvironmentViewSupport.OSDetailsSupport();\n            EnvironmentViewSupport.NetworkDetailsSupport networkDetailsView = new EnvironmentViewSupport.NetworkDetailsSupport();\n            EnvironmentViewSupport.EnvVarSupport envVarView = new EnvironmentViewSupport.EnvVarSupport();\n            EnvironmentViewSupport.ProcessesSupport processesView = new EnvironmentViewSupport.ProcessesSupport();\n\n            EnvironmentViewSupport.MasterViewSupport masterView = new EnvironmentViewSupport.MasterViewSupport(model) {\n                @Override\n                void firstShown() { initialize(this, cpuUtilizationView, networkUtilizationView, memoryUsageView, cpuDetailsView, osDetailsView, networkDetailsView, envVarView, processesView); }\n            };\n            DataViewComponent dvc = new DataViewComponent(masterView.getMasterView(), new DataViewComponent.MasterViewConfiguration(false));\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"CPU & Network\", true), DataViewComponent.TOP_LEFT);\n            dvc.addDetailsView(cpuUtilizationView.getDetailsView(), DataViewComponent.TOP_LEFT);\n            dvc.addDetailsView(networkUtilizationView.getDetailsView(), DataViewComponent.TOP_LEFT);\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Memory\", true), DataViewComponent.TOP_RIGHT);\n            dvc.addDetailsView(memoryUsageView.getDetailsView(), DataViewComponent.TOP_RIGHT);\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Details\", true), DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(cpuDetailsView.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(osDetailsView.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(networkDetailsView.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(envVarView.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(processesView.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n\n            return dvc;\n        }\n    }\n    \n    \n    private void initialize(final JFREventVisitor... visitors) {\n        new RequestProcessor(\"JFR Environment Initializer\").post(new Runnable() { // NOI18N\n            public void run() { getModel().visitEvents(visitors); }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/environment/JFRSnapshotEnvironmentViewProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.environment;\n\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREventChecker;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.jfr.view.JFRViewTabProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=JFRViewTabProvider.class)\npublic class JFRSnapshotEnvironmentViewProvider extends JFRViewTabProvider {\n    \n    static final String EVENT_CPU_INFO = \"jdk.CPUInformation\"; // NOI18N\n    static final String EVENT_PHYSICAL_MEMORY = \"jdk.PhysicalMemory\"; // NOI18N\n    static final String EVENT_OS_INFO = \"jdk.OSInformation\"; // NOI18N\n    static final String EVENT_CPU_LOAD = \"jdk.CPULoad\"; // NOI18N\n    static final String EVENT_NETWORK_UTILIZATION = \"jdk.NetworkUtilization\"; // NOI18N\n    static final String EVENT_ENVIRONMENT_VARIABLE = \"jdk.InitialEnvironmentVariable\"; // NOI18N\n    static final String EVENT_SYSTEM_PROCESS = \"jdk.SystemProcess\"; // NOI18N\n    \n    \n    @Override\n    protected JFRViewTab createView(JFRSnapshot jfrSnapshot) {\n        return new JFRSnapshotEnvironmentView(jfrSnapshot);\n    }\n    \n    \n    @ServiceProvider(service=JFREventChecker.class)\n    public static final class EventChecker extends JFREventChecker {\n        \n        public EventChecker() {\n            super(checkedTypes());\n        }\n        \n        static String[] checkedTypes() {\n            return new String[] {\n                EVENT_CPU_INFO, EVENT_PHYSICAL_MEMORY, EVENT_OS_INFO, EVENT_CPU_LOAD, EVENT_NETWORK_UTILIZATION, EVENT_ENVIRONMENT_VARIABLE, EVENT_SYSTEM_PROCESS\n            };\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/exceptions/ExceptionsNode.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.exceptions;\n\nimport java.time.Duration;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class ExceptionsNode extends CCTNode {\n    \n    private static final ExceptionsNode[] NO_NODES = new ExceptionsNode[0];\n    \n    private final ExceptionsNode parent;\n    private final List<ExceptionsNode> children;\n    \n    final String name;\n    final Icon icon;\n    \n    long count = 0;\n    Duration duration, durationMax;\n    \n    \n    ExceptionsNode(String name, Icon icon, ExceptionsNode parent, List<ExceptionsNode> children) {\n        this.parent = parent;\n        this.children = children;\n        \n        this.name = name;\n        this.icon = icon;\n    }\n    \n    \n    final void processData(Duration duration) {\n        if (parent != null) {\n            count++;\n            if (duration != null) { // .jfr v0 doesn't track Duration\n                if (this.duration == null) this.duration = duration; else this.duration = this.duration.plus(duration);\n                if (durationMax == null || durationMax.compareTo(duration) < 0) durationMax = duration;\n            }\n            \n            parent.processData(duration);\n        } else {\n            if (duration != null && this instanceof Root) ((Root)this).tracksDuration = true;\n        }\n    }\n    \n    \n    ExceptionsNode getChild(String name) {\n        if (children != null)\n            for (ExceptionsNode child : children)\n                if (Objects.equals(name, child.name))\n                    return child;\n        return null;\n    }\n    \n    \n    @Override\n    public ExceptionsNode getChild(int index) {\n        return children == null ? null : children.get(index);\n    }\n\n    @Override\n    public ExceptionsNode[] getChildren() {\n        return children == null ? NO_NODES : children.toArray(NO_NODES);\n    }\n\n    @Override\n    public int getIndexOfChild(Object child) {\n        return children == null ? -1 : children.indexOf(child);\n    }\n\n    @Override\n    public int getNChildren() {\n        return children == null ? 0 : children.size();\n    }\n    \n    @Override\n    public boolean isLeaf() {\n        return children == null || children.isEmpty();\n    }\n\n    @Override\n    public ExceptionsNode getParent() {\n        return parent;\n    }\n\n    \n    protected void addChild(ExceptionsNode child) {\n        if (children != null) children.add(child);\n    }\n    \n    protected void removeAllChildren() {\n        if (children != null) children.clear();\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return name.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        if (!(o instanceof ExceptionsNode)) return false;\n        return Objects.equals(name, ((ExceptionsNode)o).name);\n    }\n    \n    @Override\n    public String toString() {\n        return name;\n    }\n    \n    \n    static final class Class extends ExceptionsNode {\n        \n        Class(String name, ExceptionsNode parent, boolean terminal) {\n            super(name, Icons.getIcon(LanguageIcons.CLASS), parent, terminal ? null : new ArrayList<>());\n        }\n        \n    }\n    \n    static final class Error extends ExceptionsNode {\n        \n        private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/error.png\";  // NOI18N\n        private static final Icon ICON = new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true));\n        \n        Error(String name, ExceptionsNode parent, boolean terminal) {\n            super(name, ICON, parent, terminal ? null : new ArrayList<>());\n        }\n        \n    }\n    \n    static final class Exception extends ExceptionsNode {\n        \n        private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/exception.png\";  // NOI18N\n        private static final Icon ICON = new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true));\n        \n        Exception(String name, ExceptionsNode parent, boolean terminal) {\n            super(name, ICON, parent, terminal ? null : new ArrayList<>());\n        }\n        \n    }\n    \n    \n    static final class Thread extends ExceptionsNode {\n        \n        Thread(String name, ExceptionsNode parent, boolean terminal) {\n            super(name, Icons.getIcon(ProfilerIcons.THREAD), parent, terminal ? null : new ArrayList<>());\n        }\n        \n    }\n    \n    \n    static final class Label extends ExceptionsNode {\n        \n        Label(String label, ExceptionsNode parent) {\n            super(label, null, parent, null);\n        }\n        \n        static Label createNoData(ExceptionsNode parent) {\n            return new Label(\"<no data>\", parent);\n        }\n        \n    }\n    \n    \n    static final class Root extends ExceptionsNode implements JFREventVisitor {\n        \n        private final int mode;\n        private final ExceptionsViewSupport.Aggregation primary;\n        private final ExceptionsViewSupport.Aggregation secondary;\n        \n        boolean tracksDuration = false;\n            \n        \n        Root() {\n            this(0, null, null);\n        }\n        \n        Root(int mode, ExceptionsViewSupport.Aggregation primary, ExceptionsViewSupport.Aggregation secondary) {\n            super(null, null, null, primary == null && secondary == null ? null : new ArrayList<>());\n            \n            this.mode = mode;\n            this.primary = primary;\n            this.secondary = ExceptionsViewSupport.Aggregation.NONE.equals(secondary) ? null : secondary;\n        }\n        \n\n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            Boolean rw;\n            if (mode != 2 && JFRSnapshotExceptionsViewProvider.EVENT_JAVA_ERROR.equals(typeName)) rw = Boolean.FALSE; // NOI18N\n            else if (mode != 1 && JFRSnapshotExceptionsViewProvider.EVENT_JAVA_EXCEPTION.equals(typeName)) rw = Boolean.TRUE; // NOI18N\n            else rw = null;\n            \n            if (rw != null) {\n                String primaryName = getName(primary, event);\n                if (primaryName == null) primaryName = \"<unknown>\";\n\n                ExceptionsNode primaryNode = getChild(primaryName);\n                if (primaryNode == null) {\n                    primaryNode = createNode(primaryName, primary, this, secondary == null);\n                    addChild(primaryNode);\n                }\n\n                if (secondary != null) {\n                    String secondaryName = getName(secondary, event);\n                    if (secondaryName == null) secondaryName = \"<unknown>\";\n\n\n                    ExceptionsNode secondaryNode = primaryNode.getChild(secondaryName);\n                    if (secondaryNode == null) {\n                        secondaryNode = createNode(secondaryName, secondary, primaryNode, true);\n                        primaryNode.addChild(secondaryNode);\n                    }\n\n                    Duration eventDuration;\n                    try { eventDuration = getDuration(event); }\n                    catch (JFRPropertyNotAvailableException e) { eventDuration = null; } // .jfr v0\n                    secondaryNode.processData(eventDuration);\n                } else {\n                    Duration eventDuration;\n                    try { eventDuration = getDuration(event); }\n                    catch (JFRPropertyNotAvailableException e) { eventDuration = null; } // .jfr v0\n                    primaryNode.processData(eventDuration);\n                }\n            }\n            \n            return false;\n        }\n        \n        \n        @Override\n        public int hashCode() {\n            return 37;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            return o instanceof Root;\n        }\n        \n        \n        private Boolean durationMode;\n        \n        private Duration getDuration(JFREvent event) throws JFRPropertyNotAvailableException {\n            if (Boolean.TRUE.equals(durationMode)) {                // v1+\n                return event.getDuration(\"eventDuration\");                      // NOI18N\n            } else if (Boolean.FALSE.equals(durationMode)) {        // v0\n                return null;                                                    // NOI18N\n            } else {                                                // not initialized yet\n                try {\n                    Duration eventDuration = event.getDuration(\"eventDuration\");// NOI18N\n                    durationMode = Boolean.TRUE;\n                    return eventDuration;\n                } catch (JFRPropertyNotAvailableException e) {\n                    durationMode = Boolean.FALSE;\n                    return null;                                                // NOI18N\n                }\n            }\n        }\n        \n        \n        private static String getName(ExceptionsViewSupport.Aggregation aggregation, JFREvent event) {\n            try {\n                if (ExceptionsViewSupport.Aggregation.CLASS.equals(aggregation)) return decodeClassName(event.getClass(\"thrownClass\").getName()); // NOI18N\n                if (ExceptionsViewSupport.Aggregation.MESSAGE.equals(aggregation)) return decodeMessage(event.getString(\"message\")); // NOI18N\n                if (ExceptionsViewSupport.Aggregation.CLASS_MESSAGE.equals(aggregation)) return decodeClassName(event.getClass(\"thrownClass\").getName()) + \" : \" + decodeMessage(event.getString(\"message\")); // NOI18N\n                if (ExceptionsViewSupport.Aggregation.THREAD.equals(aggregation)) return event.getThread(\"eventThread\").getName(); // NOI18N\n            } catch (JFRPropertyNotAvailableException e) {}\n            return null;\n        }\n        \n        private ExceptionsNode createNode(String name, ExceptionsViewSupport.Aggregation aggregation, ExceptionsNode parent, boolean terminal) {\n            if (ExceptionsViewSupport.Aggregation.CLASS.equals(aggregation)) return new ExceptionsNode.Class(name, parent, terminal);\n            if (ExceptionsViewSupport.Aggregation.MESSAGE.equals(aggregation)) return new ExceptionsNode.Exception(name, parent, terminal);\n            if (ExceptionsViewSupport.Aggregation.CLASS_MESSAGE.equals(aggregation)) return new ExceptionsNode.Class(name, parent, terminal);\n            if (ExceptionsViewSupport.Aggregation.THREAD.equals(aggregation)) return new ExceptionsNode.Thread(name, parent, terminal);\n            return null;\n        }\n        \n        \n        private static String decodeClassName(String className) {\n            className = StringUtils.userFormClassName(className);\n            \n            if (className.startsWith(\"L\") && className.contains(\";\")) // NOI18N\n                className = className.substring(1).replace(\";\", \"\"); // NOI18N\n            \n            return className;\n        }\n        \n        private static String decodeMessage(String message) {\n            return message == null || message.isEmpty() ? \"<no message>\" : message;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/exceptions/ExceptionsRenderers.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.exceptions;\n\nimport java.awt.Font;\nimport java.time.Duration;\nimport javax.swing.JLabel;\nimport org.graalvm.visualvm.jfr.utils.ValuesConverter;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.McsTimeRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.MultiRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ExceptionsRenderers {\n    \n    private static int getMinimumWidth(String valueName) {\n        return new JLabel(valueName).getPreferredSize().width + 30;\n    }\n    \n    \n    static class NameRenderer extends MultiRenderer {\n        \n        private static Font regular;\n        private static Font bold;\n        \n        private final JavaNameRenderer javaRenderer;\n        private final LabelRenderer simpleRenderer;\n        \n        private final ProfilerRenderer[] renderers;\n        \n        \n        NameRenderer() {\n            javaRenderer = new JavaNameRenderer(Icons.getIcon(LanguageIcons.CLASS));\n            simpleRenderer = new LabelRenderer();\n            \n            renderers = new ProfilerRenderer[] { javaRenderer, simpleRenderer };\n        }\n        \n        \n        @Override\n        protected ProfilerRenderer[] valueRenderers() {\n            return renderers;\n        }\n        \n        \n        public void setValue(Object value, int row) {\n            ExceptionsNode node = (value instanceof ExceptionsNode) ? (ExceptionsNode)value : null;\n            if (node instanceof ExceptionsNode.Class) {\n                javaRenderer.setVisible(true);\n                String name = node.name;\n                int colon = name.indexOf(':');                                  // NOI18N\n                if (colon > 0) {\n                    javaRenderer.setValue(name.substring(0, colon).trim(), row);\n                    simpleRenderer.setVisible(true);\n                    simpleRenderer.setFont(regular());\n                    simpleRenderer.setText(name.substring(colon).trim());\n                    simpleRenderer.setIcon(null);\n                } else {\n                    javaRenderer.setValue(name, row);\n                    simpleRenderer.setVisible(false);\n                }\n            } else {\n                javaRenderer.setVisible(false);\n                simpleRenderer.setVisible(true);\n                if (node != null) {\n                    ExceptionsNode parent = node.getParent();\n                    simpleRenderer.setFont((parent == null || parent.getParent() == null) && !(value instanceof ExceptionsNode.Label) ? bold() : regular());\n                    simpleRenderer.setText(node.name);\n                    simpleRenderer.setIcon(node.icon);\n                } else {\n                    simpleRenderer.setFont(regular());\n                    simpleRenderer.setValue(value, row);\n                }\n            }\n        }\n        \n\n        static String getDisplayName() {\n            return \"Name\";\n        }\n        \n        private static Font regular() {\n            if (regular == null) regular = new LabelRenderer().getFont();\n            return regular;\n        }\n        \n        private static Font bold() {\n            if (bold == null) bold = new LabelRenderer().getFont().deriveFont(Font.BOLD);\n            return bold;\n        }\n\n    }\n    \n    \n    static class CountRenderer extends NumberRenderer {\n        \n        static String getDisplayName() {\n            return \"Count\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class TotalTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Total Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class MaxTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Max Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    \n    private static class TimeRenderer extends McsTimeRenderer {\n        \n        @Override\n        public void setValue(Object value, int row) {\n            if (value instanceof Duration) {\n                long micros = ValuesConverter.durationToMicros((Duration)value);\n                if (micros == 0) setText(\"< 0.001 ms\"); // NOI18N\n                else super.setValue(micros, row);\n            } else {\n                setText(\"-\"); // NOI18N\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/exceptions/ExceptionsViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.exceptions;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.time.Duration;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.JButton;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JSeparator;\nimport javax.swing.JTree;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.tree.TreeNode;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.views.components.MessageComponent;\nimport org.graalvm.visualvm.lib.ui.components.HTMLLabel;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ExceptionsViewSupport {\n    \n    static enum Aggregation {\n        NONE { @Override public String toString() { return \"None\"; } },\n        CLASS { @Override public String toString() { return \"Class\"; } },\n        MESSAGE { @Override public String toString() { return \"Message\"; } },\n        CLASS_MESSAGE { @Override public String toString() { return \"Class : Message\"; } },\n        THREAD { @Override public String toString() { return \"Thread\"; } }\n    }\n\n    static abstract class MasterViewSupport extends JPanel {\n        \n        private int lastMode;\n        private Aggregation lastPrimary, lastSecondary;\n        \n        \n        MasterViewSupport(JFRModel model) {\n            initComponents(model);\n        }\n        \n        \n        DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(\"Exceptions\", null, this);\n        }\n        \n        \n        abstract void firstShown();\n        \n        abstract void changeAggregation(int mode, Aggregation primary, Aggregation secondary);\n        \n        \n        void showProgress() {\n            updateButton.setEnabled(false);\n            updateButton.setVisible(false);\n            statusValueLabel.setVisible(true);\n        }\n        \n        void hideProgress() {\n            statusValueLabel.setVisible(false);\n            updateButton.setVisible(true);\n        }\n        \n        \n        private void handleAggregationChanged(boolean updateSecondary) {\n            if (updateSecondary) {\n                DefaultComboBoxModel<Aggregation> model = (DefaultComboBoxModel<Aggregation>)secondCombo.getModel();\n                while (model.getSize() > 1) model.removeElementAt(1);\n                \n                if (!Aggregation.CLASS.equals(firstCombo.getSelectedItem()) &&\n                    !Aggregation.CLASS_MESSAGE.equals(firstCombo.getSelectedItem()))\n                        model.addElement(Aggregation.CLASS);\n                \n                if (!Aggregation.MESSAGE.equals(firstCombo.getSelectedItem()) &&\n                    !Aggregation.CLASS_MESSAGE.equals(firstCombo.getSelectedItem()))\n                        model.addElement(Aggregation.MESSAGE);\n                \n                if (!Aggregation.CLASS.equals(firstCombo.getSelectedItem()) &&\n                    !Aggregation.MESSAGE.equals(firstCombo.getSelectedItem()) &&\n                    !Aggregation.CLASS_MESSAGE.equals(firstCombo.getSelectedItem()))\n                        model.addElement(Aggregation.CLASS_MESSAGE);\n                \n                if (!Aggregation.THREAD.equals(firstCombo.getSelectedItem()))\n                    model.addElement(Aggregation.THREAD);\n            }\n            \n            updateButton.setEnabled(lastMode != modeCombo.getSelectedIndex() ||\n                                    lastPrimary != firstCombo.getSelectedItem() ||\n                                    lastSecondary != secondCombo.getSelectedItem());\n            \n        }\n        \n        \n        private int prefHeight = -1;\n        public Dimension getPreferredSize() {\n            Dimension pref = super.getPreferredSize();\n            if (prefHeight == -1) prefHeight = pref.height;\n            else pref.height = prefHeight;\n            return pref;\n        }\n        \n        \n        private void initComponents(JFRModel model) {\n            setOpaque(false);\n            \n            if (model == null) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.notAvailable(), BorderLayout.CENTER);\n            } else if (!model.containsEvent(JFRSnapshotExceptionsViewProvider.EventChecker.class)) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.noData(\"Exceptions\", JFRSnapshotExceptionsViewProvider.EventChecker.checkedTypes()), BorderLayout.CENTER);\n            } else {\n                setLayout(new GridBagLayout());\n                setBorder(BorderFactory.createEmptyBorder(11, 5, 20, 5));\n\n                GridBagConstraints constraints;\n                \n                // modeLabel\n                JLabel modeLabel = new JLabel();\n                modeLabel.setText(\"Display:\");\n                modeLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 0;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(modeLabel, constraints);\n\n                // modeCombo\n                modeCombo = new JComboBox<>(new String[] { \"Errors & Exceptions\", \"Errors\", \"Exceptions\" });\n                modeCombo.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleAggregationChanged(false); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 1;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(modeCombo, constraints);\n\n                // modeSeparator\n                JSeparator modeSeparator = new JSeparator(JSeparator.VERTICAL);\n                modeSeparator.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 2;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 16, 0, 0);\n                add(modeSeparator, constraints);\n\n                // modeLabel\n                firstLabel = new JLabel();\n                firstLabel.setText(\"Aggregation:\");\n                firstLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 3;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(firstLabel, constraints);\n\n                // cpuButton\n                firstCombo = new JComboBox<>(new Aggregation[] { Aggregation.CLASS, Aggregation.MESSAGE, Aggregation.CLASS_MESSAGE, Aggregation.THREAD });\n                firstCombo.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleAggregationChanged(true); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 4;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(firstCombo, constraints);\n\n                // modeLabel\n                secondLabel = new JLabel();\n                secondLabel.setText(\"secondary:\");\n                secondLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 5;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 12, 0, 0);\n                add(secondLabel, constraints);\n\n                // memoryButton\n                secondCombo = new JComboBox<>(new Aggregation[] { Aggregation.NONE, Aggregation.MESSAGE, Aggregation.THREAD });\n                secondCombo.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleAggregationChanged(false); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 6;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(secondCombo, constraints);\n                \n                lastMode = modeCombo.getSelectedIndex();\n                lastPrimary = (Aggregation)firstCombo.getSelectedItem();\n                lastSecondary = (Aggregation)secondCombo.getSelectedItem();\n                \n                // updateSeparator\n                JSeparator updateSeparator = new JSeparator(JSeparator.VERTICAL);\n                updateSeparator.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 7;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 16, 0, 0);\n                add(updateSeparator, constraints);\n\n                // updateButton\n                updateButton = new JButton(\"Update Data\");\n                updateButton.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        updateButton.setEnabled(false);\n                        lastMode = modeCombo.getSelectedIndex();\n                        lastPrimary = (Aggregation)firstCombo.getSelectedItem();\n                        lastSecondary = (Aggregation)secondCombo.getSelectedItem();\n                        changeAggregation(lastMode, lastPrimary, lastSecondary);\n                    }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 8;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 12, 0, 0);\n                add(updateButton, constraints);\n\n                // statusValueLabel\n                statusValueLabel = new HTMLLabel(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n                constraints = new GridBagConstraints();\n                constraints.gridx = 9;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 20, 0, 0);\n                add(statusValueLabel, constraints);\n                statusValueLabel.setVisible(false);\n\n                // filler1\n                constraints = new GridBagConstraints();\n                constraints.gridx = 10;\n                constraints.gridy = 2;\n                constraints.weightx = 1;\n                constraints.weighty = 1;\n                constraints.gridwidth = GridBagConstraints.REMAINDER;\n                constraints.fill = GridBagConstraints.BOTH;\n                constraints.anchor = GridBagConstraints.NORTHWEST;\n                constraints.insets = new Insets(0, 0, 0, 0);\n                add(Spacer.create(), constraints);\n\n                Dimension cpuD     = firstCombo.getPreferredSize();\n                Dimension memoryD  = secondCombo.getPreferredSize();\n                Dimension stopD    = modeCombo.getPreferredSize();\n\n                Dimension maxD = new Dimension(Math.max(cpuD.width, memoryD.width), Math.max(cpuD.height, memoryD.height));\n                maxD = new Dimension(Math.max(maxD.width, 0), Math.max(maxD.height, stopD.height));\n\n                firstCombo.setPreferredSize(maxD);\n                firstCombo.setMinimumSize(maxD);\n                secondCombo.setPreferredSize(maxD);\n                secondCombo.setMinimumSize(maxD);\n\n                stopD.height = maxD.height;\n                modeCombo.setPreferredSize(stopD);\n                modeCombo.setMinimumSize(stopD);\n    \n                Dimension sepD = modeSeparator.getPreferredSize();\n                sepD.height = maxD.height - 2;\n                sepD.width = 5;\n                modeSeparator.setPreferredSize(sepD);\n                modeSeparator.setMinimumSize(sepD);\n\n                Dimension sepD2 = updateSeparator.getPreferredSize();\n                sepD2.height = maxD.height - 2;\n                sepD2.width = 5;\n                updateSeparator.setPreferredSize(sepD2);\n                updateSeparator.setMinimumSize(sepD2);\n\n                addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                            if (isShowing()) {\n                                removeHierarchyListener(this);\n                                SwingUtilities.invokeLater(MasterViewSupport.this::firstShown);\n                            }\n                        }\n                    }\n                });\n            }\n        }\n\n        private JLabel firstLabel;\n        private JLabel secondLabel;\n        private JComboBox<String> modeCombo;\n        private JComboBox<Aggregation> firstCombo;\n        private JComboBox<Aggregation> secondCombo;\n        private JButton updateButton;\n        private HTMLLabel statusValueLabel;\n        \n    }\n    \n    \n    static final class DataViewSupport extends JPanel {\n        \n        private DataModel tableModel;\n        private ProfilerTreeTable table;\n        \n        \n        DataViewSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Data\", null, 10, this, null); // NOI18N\n        }\n        \n        \n        void setData(ExceptionsNode root, boolean twoAggregations) {\n            tableModel.setRoot(root);\n            table.setShowsRootHandles(twoAggregations);\n            \n            if (((ExceptionsNode.Root)root).tracksDuration)\n                table.setColumnVisibility(2, true);\n        }\n        \n        \n        private void initComponents() {\n            tableModel = new DataModel();\n            table = new ProfilerTreeTable(tableModel, true, true, new int[] { 0 });\n            \n            table.setRootVisible(false);\n            table.setShowsRootHandles(true);\n\n            table.setMainColumn(0);\n            table.setFitWidthColumn(0);\n\n            table.setSortColumn(1);\n            table.setDefaultSortOrder(SortOrder.DESCENDING);\n            table.setDefaultSortOrder(0, SortOrder.ASCENDING);\n            \n            ExceptionsRenderers.NameRenderer nameRenderer = new ExceptionsRenderers.NameRenderer();\n            table.setTreeCellRenderer(nameRenderer);\n            \n            ExceptionsRenderers.CountRenderer countRenderer = new ExceptionsRenderers.CountRenderer();\n            table.setColumnRenderer(1, countRenderer);\n            table.setDefaultColumnWidth(1, countRenderer.getPreferredWidth());\n            table.setColumnVisibility(1, ExceptionsRenderers.CountRenderer.isInitiallyVisible());\n            \n            ExceptionsRenderers.TotalTimeRenderer totalTimeRenderer = new ExceptionsRenderers.TotalTimeRenderer();\n            table.setColumnRenderer(2, totalTimeRenderer);\n            table.setDefaultColumnWidth(2, totalTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(2, ExceptionsRenderers.TotalTimeRenderer.isInitiallyVisible());\n            \n            ExceptionsRenderers.MaxTimeRenderer maxTimeRenderer = new ExceptionsRenderers.MaxTimeRenderer();\n            table.setColumnRenderer(3, maxTimeRenderer);\n            table.setDefaultColumnWidth(3, maxTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(3, ExceptionsRenderers.MaxTimeRenderer.isInitiallyVisible());\n            \n            setLayout(new BorderLayout());\n            add(new ProfilerTableContainer(table, false, null), BorderLayout.CENTER);\n        }\n        \n        \n        private static class DataModel extends ProfilerTreeTableModel.Abstract {\n            \n            DataModel() {\n                super(new ExceptionsNode.Root());\n            }\n            \n            \n            @Override\n            public int getColumnCount() {\n                return 4;\n            }\n\n            @Override\n            public Class<?> getColumnClass(int column) {\n                switch (column) {\n                    case 0: return JTree.class;\n                    case 1: return Long.class;\n                    case 2: return Duration.class;\n                    case 3: return Duration.class;\n                    default: return null;\n                }\n            }\n\n            @Override\n            public String getColumnName(int column) {\n                switch (column) {\n                    case 0: return ExceptionsRenderers.NameRenderer.getDisplayName();\n                    case 1: return ExceptionsRenderers.CountRenderer.getDisplayName();\n                    case 2: return ExceptionsRenderers.TotalTimeRenderer.getDisplayName();\n                    case 3: return ExceptionsRenderers.MaxTimeRenderer.getDisplayName();\n                    default: return null;\n                }\n            }\n\n            @Override\n            public Object getValueAt(TreeNode node, int column) {\n                if (node == null) return null;\n                ExceptionsNode fnode = (ExceptionsNode)node;\n                \n                switch (column) {\n                    case 0: return fnode;\n                    case 1: return toLong(fnode.count);\n                    case 2: return fnode.duration;\n                    case 3: return fnode.durationMax;\n                    default: return null;\n                }\n            }\n            \n            @Override\n            public void setValueAt(Object o, TreeNode node, int column) {}\n\n            @Override\n            public boolean isCellEditable(TreeNode node, int column) { return false; }\n            \n            \n            private Long toLong(long value) {\n                return value == 0 ? null : Long.valueOf(value);\n            }\n            \n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/exceptions/JFRSnapshotExceptionsView.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.exceptions;\n\nimport javax.swing.ImageIcon;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRSnapshotExceptionsView extends JFRViewTab {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/exception.png\"; // NOI18N\n    \n    \n    JFRSnapshotExceptionsView(JFRSnapshot jfrSnapshot) {\n        super(jfrSnapshot, \"Exceptions\", new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 50);\n\n    }\n    \n    \n    private DataViewComponent dvc;\n    private ExceptionsViewSupport.MasterViewSupport masterView;\n    private ExceptionsViewSupport.DataViewSupport dataView;\n    \n    \n    protected DataViewComponent createComponent() {\n        JFRModel model = getModel();\n        \n        masterView = new ExceptionsViewSupport.MasterViewSupport(model) {\n            @Override\n            void firstShown() {\n                changeAggregation(0, ExceptionsViewSupport.Aggregation.CLASS, ExceptionsViewSupport.Aggregation.NONE);\n            }\n            @Override\n            void changeAggregation(int mode, ExceptionsViewSupport.Aggregation primary, ExceptionsViewSupport.Aggregation secondary) {\n                JFRSnapshotExceptionsView.this.setAggregation(mode, primary, secondary);\n            }\n        };\n        \n        boolean hasEvents = model != null && model.containsEvent(JFRSnapshotExceptionsViewProvider.EventChecker.class);\n        \n        dvc = new DataViewComponent(\n                masterView.getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(!hasEvents));\n        \n        if (hasEvents) {\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Data\", false), DataViewComponent.TOP_LEFT);\n\n            dataView = new ExceptionsViewSupport.DataViewSupport();\n            dvc.addDetailsView(dataView.getDetailsView(), DataViewComponent.TOP_LEFT);\n        }\n\n        return dvc;\n    }\n    \n    \n    private void setAggregation(final int mode, final ExceptionsViewSupport.Aggregation primary, final ExceptionsViewSupport.Aggregation secondary) {\n        masterView.showProgress();\n        dataView.setData(new ExceptionsNode.Root(), false);\n        \n        new RequestProcessor(\"JFR Exceptions Initializer\").post(new Runnable() { // NOI18N\n            public void run() {\n                final ExceptionsNode.Root root = new ExceptionsNode.Root(mode, primary, secondary);\n                getModel().visitEvents(root);\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        if (root.getNChildren() == 0) root.addChild(ExceptionsNode.Label.createNoData(root));\n                        dataView.setData(root, !ExceptionsViewSupport.Aggregation.NONE.equals(secondary));\n                        masterView.hideProgress();\n                    }\n                });\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/exceptions/JFRSnapshotExceptionsViewProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.exceptions;\n\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREventChecker;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.jfr.view.JFRViewTabProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=JFRViewTabProvider.class)\npublic final class JFRSnapshotExceptionsViewProvider extends JFRViewTabProvider {\n    \n    static final String EVENT_JAVA_ERROR = \"jdk.JavaErrorThrow\"; // NOI18N\n    static final String EVENT_JAVA_EXCEPTION = \"jdk.JavaExceptionThrow\"; // NOI18N\n    \n    \n    protected JFRViewTab createView(JFRSnapshot jfrSnapshot) {\n        return new JFRSnapshotExceptionsView(jfrSnapshot);\n    }\n    \n    \n    @ServiceProvider(service=JFREventChecker.class)\n    public static final class EventChecker extends JFREventChecker {\n        \n        public EventChecker() {\n            super(checkedTypes());\n        }\n        \n        static String[] checkedTypes() {\n            return new String[] {\n                EVENT_JAVA_ERROR, EVENT_JAVA_EXCEPTION\n            };\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/fileio/FileIONode.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.fileio;\n\nimport java.time.Duration;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class FileIONode extends CCTNode {\n    \n    private static final FileIONode[] NO_NODES = new FileIONode[0];\n    \n    private final FileIONode parent;\n    private final List<FileIONode> children;\n    \n    final String name;\n    final Icon icon;\n    \n    long countR, countW = 0;\n    long bytesR, bytesW = 0;\n    Duration durationR, durationRMax, durationW, durationWMax;\n    \n    \n    FileIONode(String name, Icon icon, FileIONode parent, List<FileIONode> children) {\n        this.parent = parent;\n        this.children = children;\n        \n        this.name = name;\n        this.icon = icon;\n    }\n    \n    \n    final void processRead(Duration duration, long bytes) {\n        if (parent != null) {\n            countR++;\n            bytesR += bytes;\n            if (durationR == null) durationR = duration; else durationR = durationR.plus(duration);\n            if (durationRMax == null || durationRMax.compareTo(duration) < 0) durationRMax = duration;\n            \n            parent.processRead(duration, bytes);\n        }\n    }\n    \n    final void processWrite(Duration duration, long bytes) {\n        if (parent != null) {\n            countW++;\n            bytesW += bytes;\n            if (durationW == null) durationW = duration; else durationW = durationW.plus(duration);\n            if (durationWMax == null || durationWMax.compareTo(duration) < 0) durationWMax = duration;\n            \n            parent.processWrite(duration, bytes);\n        }\n    }\n    \n    \n    FileIONode getChild(String name) {\n        if (children != null)\n            for (FileIONode child : children)\n                if (Objects.equals(name, child.name))\n                    return child;\n        return null;\n    }\n    \n    \n    @Override\n    public FileIONode getChild(int index) {\n        return children == null ? null : children.get(index);\n    }\n\n    @Override\n    public FileIONode[] getChildren() {\n        return children == null ? NO_NODES : children.toArray(NO_NODES);\n    }\n\n    @Override\n    public int getIndexOfChild(Object child) {\n        return children == null ? -1 : children.indexOf(child);\n    }\n\n    @Override\n    public int getNChildren() {\n        return children == null ? 0 : children.size();\n    }\n    \n    @Override\n    public boolean isLeaf() {\n        return children == null || children.isEmpty();\n    }\n\n    @Override\n    public FileIONode getParent() {\n        return parent;\n    }\n\n    \n    protected void addChild(FileIONode child) {\n        if (children != null) children.add(child);\n    }\n    \n    protected void removeAllChildren() {\n        if (children != null) children.clear();\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return name.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        if (!(o instanceof FileIONode)) return false;\n        return Objects.equals(name, ((FileIONode)o).name);\n    }\n    \n    @Override\n    public String toString() {\n        return name;\n    }\n    \n    \n    static final class File extends FileIONode {\n        \n        private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/file.png\";  // NOI18N\n        private static final Icon ICON = new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true));\n        \n        File(String name, FileIONode parent, boolean terminal) {\n            super(name, ICON, parent, terminal ? null : new ArrayList<>());\n        }\n        \n    }\n    \n    \n    static final class Thread extends FileIONode {\n        \n        Thread(String name, FileIONode parent, boolean terminal) {\n            super(name, Icons.getIcon(ProfilerIcons.THREAD), parent, terminal ? null : new ArrayList<>());\n        }\n        \n    }\n    \n    \n    static final class Root extends FileIONode implements JFREventVisitor {\n        \n        private final FileIOViewSupport.Aggregation primary;\n        private final FileIOViewSupport.Aggregation secondary;\n    \n        \n        Root() {\n            this(null, null);\n        }\n        \n        Root(FileIOViewSupport.Aggregation primary, FileIOViewSupport.Aggregation secondary) {\n            super(null, null, null, primary == null && secondary == null ? null : new ArrayList<>());\n            \n            this.primary = primary;\n            this.secondary = FileIOViewSupport.Aggregation.NONE.equals(secondary) ? null : secondary;\n        }\n        \n\n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            Boolean rw;\n            if (JFRSnapshotFileIOViewProvider.EVENT_FILE_READ.equals(typeName)) rw = Boolean.FALSE; // NOI18N\n            else if (JFRSnapshotFileIOViewProvider.EVENT_FILE_WRITE.equals(typeName)) rw = Boolean.TRUE; // NOI18N\n            else rw = null;\n            \n            if (rw != null) {\n                String primaryName = getName(primary, event);\n                if (primaryName == null) primaryName = \"<unknown>\";\n                \n                FileIONode primaryNode = getChild(primaryName);\n                if (primaryNode == null) {\n                    primaryNode = createNode(primaryName, primary, this, secondary == null);\n                    addChild(primaryNode);\n                }\n                \n                if (secondary != null) {\n                    String secondaryName = getName(secondary, event);\n                    if (secondaryName == null) secondaryName = \"<unknown>\";\n\n                    \n                    FileIONode secondaryNode = primaryNode.getChild(secondaryName);\n                    if (secondaryNode == null) {\n                        secondaryNode = createNode(secondaryName, secondary, primaryNode, true);\n                        primaryNode.addChild(secondaryNode);\n                    }\n                    \n                    processEvent(secondaryNode, event, rw);\n                } else {\n                    processEvent(primaryNode, event, rw);\n                }\n            }\n            \n            return false;\n        }\n        \n        \n        private static void processEvent(FileIONode node, JFREvent event, Boolean rw) {\n            try {\n                if (Boolean.FALSE.equals(rw)) node.processRead(event.getDuration(\"eventDuration\"), event.getLong(\"bytesRead\")); // NOI18N\n                else node.processWrite(event.getDuration(\"eventDuration\"), event.getLong(\"bytesWritten\")); // NOI18N\n            } catch (JFRPropertyNotAvailableException e) {}\n        }\n        \n        \n        @Override\n        public int hashCode() {\n            return 37;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            return o instanceof Root;\n        }\n        \n        \n        private static String getName(FileIOViewSupport.Aggregation aggregation, JFREvent event) {\n            try {\n                if (FileIOViewSupport.Aggregation.FILE.equals(aggregation)) return event.getString(\"path\"); // NOI18N\n                if (FileIOViewSupport.Aggregation.THREAD.equals(aggregation)) return event.getThread(\"eventThread\").getName();\n            } catch (JFRPropertyNotAvailableException e) {}\n            return null;\n        }\n        \n        private FileIONode createNode(String name, FileIOViewSupport.Aggregation aggregation, FileIONode parent, boolean terminal) {\n            if (FileIOViewSupport.Aggregation.FILE.equals(aggregation)) return new FileIONode.File(name, parent, terminal);\n            if (FileIOViewSupport.Aggregation.THREAD.equals(aggregation)) return new FileIONode.Thread(name, parent, terminal);\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/fileio/FileIORenderers.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.fileio;\n\nimport java.awt.Font;\nimport java.time.Duration;\nimport javax.swing.JLabel;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.jfr.utils.ValuesConverter;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.FormattedLabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.McsTimeRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class FileIORenderers {\n    \n    private static int getMinimumWidth(String valueName) {\n        return new JLabel(valueName).getPreferredSize().width + 30;\n    }\n    \n    \n    static class NameRenderer extends LabelRenderer {\n        \n        private static Font regular;\n        private static Font bold;\n            \n        public void setValue(Object value, int row) {\n            if (value instanceof FileIONode) {\n                FileIONode node = (FileIONode)value;\n                FileIONode parent = node.getParent();\n                setFont(parent == null || parent.getParent() == null ? bold() : regular());\n                setText(node.name);\n                setIcon(node.icon);\n            } else {\n                super.setValue(value, row);\n            }\n        }\n\n        static String getDisplayName() {\n            return \"Name\";\n        }\n        \n        private static Font regular() {\n            if (regular == null) regular = new LabelRenderer().getFont();\n            return regular;\n        }\n        \n        private static Font bold() {\n            if (bold == null) bold = new LabelRenderer().getFont().deriveFont(Font.BOLD);\n            return bold;\n        }\n\n    }\n    \n    \n    static class TotalTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Total Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class ReadTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Read Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class MaxReadTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Max Read Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class WriteTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Write Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class MaxWriteTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Max Write Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class TotalCountRenderer extends NumberRenderer {\n        \n        static String getDisplayName() {\n            return \"Total Count\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class ReadCountRenderer extends NumberRenderer {\n        \n        static String getDisplayName() {\n            return \"Read Count\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class WriteCountRenderer extends NumberRenderer {\n        \n        static String getDisplayName() {\n            return \"Write Count\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class ReadBytesRenderer extends BytesRenderer {\n        \n        static String getDisplayName() {\n            return \"Read Bytes\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(99999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class WriteBytesRenderer extends BytesRenderer {\n        \n        static String getDisplayName() {\n            return \"Write Bytes\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(99999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    \n    private static class TimeRenderer extends McsTimeRenderer {\n        \n        @Override\n        public void setValue(Object value, int row) {\n            if (value instanceof Duration) {\n                long micros = ValuesConverter.durationToMicros((Duration)value);\n                if (micros == 0) setText(\"< 0.001 ms\"); // NOI18N\n                else super.setValue(micros, row);\n            } else {\n                setText(\"-\"); // NOI18N\n            }\n        }\n        \n    }\n    \n    private static class BytesRenderer extends FormattedLabelRenderer {\n        \n        BytesRenderer() {\n            super(Formatters.bytesFormat());\n            setHorizontalAlignment(SwingConstants.TRAILING);\n        }\n        \n        @Override\n        public void setValue(Object value, int row) {\n            if (value == null) setText(\"-\");\n            else super.setValue(value, row);\n        }\n                \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/fileio/FileIOViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.fileio;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.time.Duration;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.JButton;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JSeparator;\nimport javax.swing.JTree;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.tree.TreeNode;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.views.components.MessageComponent;\nimport org.graalvm.visualvm.lib.ui.components.HTMLLabel;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class FileIOViewSupport {\n    \n    static enum Aggregation {\n        NONE { @Override public String toString() { return \"None\"; } },\n        FILE { @Override public String toString() { return \"File\"; } },\n        THREAD { @Override public String toString() { return \"Thread\"; } }\n    }\n\n    static abstract class MasterViewSupport extends JPanel {\n        \n        private Aggregation lastPrimary, lastSecondary;\n        \n        \n        MasterViewSupport(JFRModel model) {\n            initComponents(model);\n        }\n        \n        \n        DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(\"File IO\", null, this);\n        }\n        \n        \n        abstract void firstShown();\n        \n        abstract void changeAggregation(Aggregation primary, Aggregation secondary);\n        \n        \n        void showProgress() {\n            updateButton.setEnabled(false);\n            updateButton.setVisible(false);\n            statusValueLabel.setVisible(true);\n        }\n        \n        void hideProgress() {\n            statusValueLabel.setVisible(false);\n            updateButton.setVisible(true);\n        }\n        \n        \n        private void handleAggregationChanged(boolean updateSecondary) {\n            if (updateSecondary) {\n                if (Aggregation.FILE.equals(firstCombo.getSelectedItem())) {\n                    if (Aggregation.FILE.equals(secondCombo.getItemAt(1))) {\n                        int sel = secondCombo.getSelectedIndex();\n                        DefaultComboBoxModel<Aggregation> model = (DefaultComboBoxModel<Aggregation>)secondCombo.getModel();\n                        model.removeElementAt(1);\n                        model.addElement(Aggregation.THREAD);\n                        secondCombo.setSelectedIndex(sel);\n                    }\n                } else if (Aggregation.THREAD.equals(firstCombo.getSelectedItem())) {\n                    if (Aggregation.THREAD.equals(secondCombo.getItemAt(1))) {\n                        int sel = secondCombo.getSelectedIndex();\n                        DefaultComboBoxModel<Aggregation> model = (DefaultComboBoxModel<Aggregation>)secondCombo.getModel();\n                        model.removeElementAt(1);\n                        model.addElement(Aggregation.FILE);\n                        secondCombo.setSelectedIndex(sel);\n                    }\n                }\n            }\n            \n            updateButton.setEnabled(lastPrimary != firstCombo.getSelectedItem() ||\n                                    lastSecondary != secondCombo.getSelectedItem());\n            \n        }\n        \n        \n        private int prefHeight = -1;\n        public Dimension getPreferredSize() {\n            Dimension pref = super.getPreferredSize();\n            if (prefHeight == -1) prefHeight = pref.height;\n            else pref.height = prefHeight;\n            return pref;\n        }\n        \n        \n        private void initComponents(JFRModel model) {\n            setOpaque(false);\n            \n            if (model == null) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.notAvailable(), BorderLayout.CENTER);\n            } else if (!model.containsEvent(JFRSnapshotFileIOViewProvider.EventChecker.class)) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.noData(\"File IO\", JFRSnapshotFileIOViewProvider.EventChecker.checkedTypes()), BorderLayout.CENTER);\n            } else {\n                setLayout(new GridBagLayout());\n                setBorder(BorderFactory.createEmptyBorder(11, 5, 20, 5));\n\n                GridBagConstraints constraints;\n\n                // modeLabel\n                firstLabel = new JLabel();\n                firstLabel.setText(\"Aggregation:\");\n                firstLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 0;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(firstLabel, constraints);\n\n                // cpuButton\n                firstCombo = new JComboBox<>(new Aggregation[] { Aggregation.FILE, Aggregation.THREAD });\n                firstCombo.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleAggregationChanged(true); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 1;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(firstCombo, constraints);\n\n                // modeLabel\n                secondLabel = new JLabel();\n                secondLabel.setText(\"secondary:\");\n                secondLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 2;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 12, 0, 0);\n                add(secondLabel, constraints);\n\n                // memoryButton\n                secondCombo = new JComboBox<>(new Aggregation[] { Aggregation.NONE, Aggregation.THREAD });\n                secondCombo.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleAggregationChanged(false); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 3;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(secondCombo, constraints);\n                \n                lastPrimary = (Aggregation)firstCombo.getSelectedItem();\n                lastSecondary = (Aggregation)secondCombo.getSelectedItem();\n                \n                // updateSeparator\n                JSeparator updateSeparator = new JSeparator(JSeparator.VERTICAL);\n                updateSeparator.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 4;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 16, 0, 0);\n                add(updateSeparator, constraints);\n\n                // updateButton\n                updateButton = new JButton(\"Update Data\");\n                updateButton.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        updateButton.setEnabled(false);\n                        lastPrimary = (Aggregation)firstCombo.getSelectedItem();\n                        lastSecondary = (Aggregation)secondCombo.getSelectedItem();\n                        changeAggregation((Aggregation)firstCombo.getSelectedItem(), (Aggregation)secondCombo.getSelectedItem());\n                    }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 5;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 12, 0, 0);\n                add(updateButton, constraints);\n\n                // statusValueLabel\n                statusValueLabel = new HTMLLabel(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n                constraints = new GridBagConstraints();\n                constraints.gridx = 6;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 20, 0, 0);\n                add(statusValueLabel, constraints);\n                statusValueLabel.setVisible(false);\n\n                // filler1\n                constraints = new GridBagConstraints();\n                constraints.gridx = 7;\n                constraints.gridy = 2;\n                constraints.weightx = 1;\n                constraints.weighty = 1;\n                constraints.gridwidth = GridBagConstraints.REMAINDER;\n                constraints.fill = GridBagConstraints.BOTH;\n                constraints.anchor = GridBagConstraints.NORTHWEST;\n                constraints.insets = new Insets(0, 0, 0, 0);\n                add(Spacer.create(), constraints);\n\n                Dimension cpuD     = firstCombo.getPreferredSize();\n                Dimension memoryD  = secondCombo.getPreferredSize();\n    //            Dimension stopD    = stopButton.getPreferredSize();\n\n                Dimension maxD = new Dimension(Math.max(cpuD.width, memoryD.width), Math.max(cpuD.height, memoryD.height));\n    //            maxD = new Dimension(Math.max(maxD.width, stopD.width), Math.max(maxD.height, stopD.height));\n\n                firstCombo.setPreferredSize(maxD);\n                firstCombo.setMinimumSize(maxD);\n                secondCombo.setPreferredSize(maxD);\n                secondCombo.setMinimumSize(maxD);\n    //            stopButton.setPreferredSize(maxD);\n    //            stopButton.setMinimumSize(maxD);\n    \n                Dimension sepD = updateSeparator.getPreferredSize();\n                sepD.height = maxD.height - 2;\n                sepD.width = 5;\n                updateSeparator.setPreferredSize(sepD);\n                updateSeparator.setMinimumSize(sepD);\n\n                addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                            if (isShowing()) {\n                                removeHierarchyListener(this);\n                                SwingUtilities.invokeLater(MasterViewSupport.this::firstShown);\n                            }\n                        }\n                    }\n                });\n            }\n        }\n\n        private JLabel firstLabel;\n        private JLabel secondLabel;\n        private JComboBox<Aggregation> firstCombo;\n        private JComboBox<Aggregation> secondCombo;\n        private JButton updateButton;\n        private HTMLLabel statusValueLabel;\n        \n    }\n    \n    \n    static final class DataViewSupport extends JPanel {\n        \n        private DataModel tableModel;\n        private ProfilerTreeTable table;\n        \n        \n        DataViewSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Data\", null, 10, this, null); // NOI18N\n        }\n        \n        \n        void setData(FileIONode root, boolean twoAggregations) {\n            tableModel.setRoot(root);\n            table.setShowsRootHandles(twoAggregations);\n        }\n        \n        \n        private void initComponents() {\n            tableModel = new DataModel();\n            table = new ProfilerTreeTable(tableModel, true, true, new int[] { 0 });\n            \n            table.setRootVisible(false);\n            table.setShowsRootHandles(true);\n\n            table.setMainColumn(0);\n            table.setFitWidthColumn(0);\n\n            table.setSortColumn(1);\n            table.setDefaultSortOrder(SortOrder.DESCENDING);\n            table.setDefaultSortOrder(0, SortOrder.ASCENDING);\n            \n            FileIORenderers.NameRenderer nameRenderer = new FileIORenderers.NameRenderer();\n            table.setTreeCellRenderer(nameRenderer);\n            \n            FileIORenderers.TotalTimeRenderer totalTimeRenderer = new FileIORenderers.TotalTimeRenderer();\n            table.setColumnRenderer(1, totalTimeRenderer);\n            table.setDefaultColumnWidth(1, totalTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(1, FileIORenderers.TotalTimeRenderer.isInitiallyVisible());\n            \n            FileIORenderers.ReadTimeRenderer readTimeRenderer = new FileIORenderers.ReadTimeRenderer();\n            table.setColumnRenderer(2, readTimeRenderer);\n            table.setDefaultColumnWidth(2, readTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(2, FileIORenderers.ReadTimeRenderer.isInitiallyVisible());\n            \n            FileIORenderers.MaxReadTimeRenderer maxReadTimeRenderer = new FileIORenderers.MaxReadTimeRenderer();\n            table.setColumnRenderer(3, maxReadTimeRenderer);\n            table.setDefaultColumnWidth(3, maxReadTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(3, FileIORenderers.MaxReadTimeRenderer.isInitiallyVisible());\n            \n            FileIORenderers.WriteTimeRenderer writeTimeRenderer = new FileIORenderers.WriteTimeRenderer();\n            table.setColumnRenderer(4, writeTimeRenderer);\n            table.setDefaultColumnWidth(4, writeTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(4, FileIORenderers.WriteTimeRenderer.isInitiallyVisible());\n            \n            FileIORenderers.MaxWriteTimeRenderer maxWriteTimeRenderer = new FileIORenderers.MaxWriteTimeRenderer();\n            table.setColumnRenderer(5, maxWriteTimeRenderer);\n            table.setDefaultColumnWidth(5, maxWriteTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(5, FileIORenderers.MaxWriteTimeRenderer.isInitiallyVisible());\n            \n            FileIORenderers.TotalCountRenderer totalCountRenderer = new FileIORenderers.TotalCountRenderer();\n            table.setColumnRenderer(6, totalCountRenderer);\n            table.setDefaultColumnWidth(6, totalCountRenderer.getPreferredWidth());\n            table.setColumnVisibility(6, FileIORenderers.TotalCountRenderer.isInitiallyVisible());\n            \n            FileIORenderers.ReadCountRenderer readCountRenderer = new FileIORenderers.ReadCountRenderer();\n            table.setColumnRenderer(7, readCountRenderer);\n            table.setDefaultColumnWidth(7, readCountRenderer.getPreferredWidth());\n            table.setColumnVisibility(7, FileIORenderers.ReadCountRenderer.isInitiallyVisible());\n            \n            FileIORenderers.WriteCountRenderer writeCountRenderer = new FileIORenderers.WriteCountRenderer();\n            table.setColumnRenderer(8, writeCountRenderer);\n            table.setDefaultColumnWidth(8, writeCountRenderer.getPreferredWidth());\n            table.setColumnVisibility(8, FileIORenderers.WriteCountRenderer.isInitiallyVisible());\n            \n            FileIORenderers.ReadBytesRenderer readBytesRenderer = new FileIORenderers.ReadBytesRenderer();\n            table.setColumnRenderer(9, readBytesRenderer);\n            table.setDefaultColumnWidth(9, readBytesRenderer.getPreferredWidth());\n            table.setColumnVisibility(9, FileIORenderers.ReadBytesRenderer.isInitiallyVisible());\n            \n            FileIORenderers.WriteBytesRenderer writeBytesRenderer = new FileIORenderers.WriteBytesRenderer();\n            table.setColumnRenderer(10, writeBytesRenderer);\n            table.setDefaultColumnWidth(10, writeBytesRenderer.getPreferredWidth());\n            table.setColumnVisibility(10, FileIORenderers.WriteBytesRenderer.isInitiallyVisible());\n            \n            setLayout(new BorderLayout());\n            add(new ProfilerTableContainer(table, false, null), BorderLayout.CENTER);\n        }\n        \n        \n        private static class DataModel extends ProfilerTreeTableModel.Abstract {\n            \n            DataModel() {\n                super(new FileIONode.Root());\n            }\n            \n            \n            @Override\n            public int getColumnCount() {\n                return 11;\n            }\n\n            @Override\n            public Class<?> getColumnClass(int column) {\n                switch (column) {\n                    case 0: return JTree.class;\n                    case 1: return Duration.class;\n                    case 2: return Duration.class;\n                    case 3: return Duration.class;\n                    case 4: return Duration.class;\n                    case 5: return Duration.class;\n                    case 6: return Long.class;\n                    case 7: return Long.class;\n                    case 8: return Long.class;\n                    case 9: return Long.class;\n                    case 10: return Long.class;\n                    default: return null;\n                }\n            }\n\n            @Override\n            public String getColumnName(int column) {\n                switch (column) {\n                    case 0: return FileIORenderers.NameRenderer.getDisplayName();\n                    case 1: return FileIORenderers.TotalTimeRenderer.getDisplayName();\n                    case 2: return FileIORenderers.ReadTimeRenderer.getDisplayName();\n                    case 3: return FileIORenderers.MaxReadTimeRenderer.getDisplayName();\n                    case 4: return FileIORenderers.WriteTimeRenderer.getDisplayName();\n                    case 5: return FileIORenderers.MaxWriteTimeRenderer.getDisplayName();\n                    case 6: return FileIORenderers.TotalCountRenderer.getDisplayName();\n                    case 7: return FileIORenderers.ReadCountRenderer.getDisplayName();\n                    case 8: return FileIORenderers.WriteCountRenderer.getDisplayName();\n                    case 9: return FileIORenderers.ReadBytesRenderer.getDisplayName();\n                    case 10: return FileIORenderers.WriteBytesRenderer.getDisplayName();\n                    default: return null;\n                }\n            }\n\n            @Override\n            public Object getValueAt(TreeNode node, int column) {\n                if (node == null) return null;\n                FileIONode fnode = (FileIONode)node;\n                \n                switch (column) {\n                    case 0: return fnode;\n                    case 1: return toDuration(fnode.durationR, fnode.durationW);\n                    case 2: return fnode.durationR;\n                    case 3: return fnode.durationRMax;\n                    case 4: return fnode.durationW;\n                    case 5: return fnode.durationWMax;\n                    case 6: return toLong(fnode.countR + fnode.countW);\n                    case 7: return toLong(fnode.countR);\n                    case 8: return toLong(fnode.countW);\n                    case 9: return toLong(fnode.bytesR);\n                    case 10: return toLong(fnode.bytesW);\n                    default: return null;\n                }\n            }\n            \n            @Override\n            public void setValueAt(Object o, TreeNode node, int column) {}\n\n            @Override\n            public boolean isCellEditable(TreeNode node, int column) { return false; }\n            \n            \n            private Long toLong(long value) {\n                return value == 0 ? null : Long.valueOf(value);\n            }\n            \n            private Duration toDuration(Duration duration1, Duration duration2) {\n                if (duration1 == null && duration2 == null) return null;\n                if (duration2 == null) return duration1;\n                if (duration1 == null) return duration2;\n                return duration1.plus(duration2);\n            }\n            \n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/fileio/JFRSnapshotFileIOView.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.fileio;\n\nimport javax.swing.ImageIcon;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRSnapshotFileIOView extends JFRViewTab {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/fileio.png\"; // NOI18N\n    \n    \n    JFRSnapshotFileIOView(JFRSnapshot jfrSnapshot) {\n        super(jfrSnapshot, \"File IO\", new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 30);\n\n    }\n    \n    \n    private DataViewComponent dvc;\n    private FileIOViewSupport.MasterViewSupport masterView;\n    private FileIOViewSupport.DataViewSupport dataView;\n    \n    \n    protected DataViewComponent createComponent() {\n        JFRModel model = getModel();\n        \n        masterView = new FileIOViewSupport.MasterViewSupport(model) {\n            @Override\n            void firstShown() {\n                changeAggregation(FileIOViewSupport.Aggregation.FILE, FileIOViewSupport.Aggregation.NONE);\n            }\n            @Override\n            void changeAggregation(FileIOViewSupport.Aggregation primary, FileIOViewSupport.Aggregation secondary) {\n                JFRSnapshotFileIOView.this.setAggregation(primary, secondary);\n            }\n        };\n        \n        boolean hasEvents = model != null && model.containsEvent(JFRSnapshotFileIOViewProvider.EventChecker.class);\n        \n        dvc = new DataViewComponent(\n                masterView.getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(!hasEvents));\n        \n        if (hasEvents) {\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Data\", false), DataViewComponent.TOP_LEFT);\n\n            dataView = new FileIOViewSupport.DataViewSupport();\n            dvc.addDetailsView(dataView.getDetailsView(), DataViewComponent.TOP_LEFT);\n        }\n\n        return dvc;\n    }\n    \n    \n    private void setAggregation(final FileIOViewSupport.Aggregation primary, final FileIOViewSupport.Aggregation secondary) {\n        masterView.showProgress();\n        dataView.setData(new FileIONode.Root(), false);\n        \n        new RequestProcessor(\"JFR FileIO Initializer\").post(new Runnable() { // NOI18N\n            public void run() {\n                final FileIONode.Root root = new FileIONode.Root(primary, secondary);\n                getModel().visitEvents(root);\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        dataView.setData(root, !FileIOViewSupport.Aggregation.NONE.equals(secondary));\n                        masterView.hideProgress();\n                    }\n                });\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/fileio/JFRSnapshotFileIOViewProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.fileio;\n\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREventChecker;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.jfr.view.JFRViewTabProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=JFRViewTabProvider.class)\npublic final class JFRSnapshotFileIOViewProvider extends JFRViewTabProvider {\n    \n    static final String EVENT_FILE_READ = \"jdk.FileRead\"; // NOI18N\n    static final String EVENT_FILE_WRITE = \"jdk.FileWrite\"; // NOI18N\n    \n    \n    protected JFRViewTab createView(JFRSnapshot jfrSnapshot) {\n        return new JFRSnapshotFileIOView(jfrSnapshot);\n    }\n    \n    \n    @ServiceProvider(service=JFREventChecker.class)\n    public static final class EventChecker extends JFREventChecker {\n        \n        public EventChecker() {\n            super(checkedTypes());\n        }\n        \n        static String[] checkedTypes() {\n            return new String[] {\n                EVENT_FILE_READ, EVENT_FILE_WRITE\n            };\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/gc/GcNode.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.gc;\n\nimport java.time.Duration;\nimport java.time.Instant;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class GcNode extends CCTNode {\n    \n    private static final GcNode[] NO_NODES = new GcNode[0];\n    \n    private final GcNode parent;\n    private final List<GcNode> children;\n    \n    final String name;\n    final Icon icon;\n    \n    String cause;\n    long gcid = -1;\n    long count = 0;\n    \n    Duration sumOfPauses;\n    Duration longestPause;\n    \n    \n    GcNode(String name, Icon icon, GcNode parent, List<GcNode> children) {\n        this.parent = parent;\n        this.children = children;\n        \n        this.name = name;\n        this.icon = icon;\n    }\n    \n    \n    final void processData(Duration _sumOfPauses, Duration _longestPause, JFREvent event) throws JFRPropertyNotAvailableException {\n        if (parent != null) {\n            processDataImpl(event);\n            \n            if (sumOfPauses == null) sumOfPauses = _sumOfPauses; else sumOfPauses = sumOfPauses.plus(_sumOfPauses);\n            if (longestPause == null || longestPause.compareTo(_longestPause) < 0) longestPause = _longestPause;\n            \n            parent.processData(_sumOfPauses, _longestPause, event);\n        }\n    }\n    \n    protected void processDataImpl(JFREvent event) throws JFRPropertyNotAvailableException {}\n    \n    \n    GcNode getChild(String name) {\n        if (children != null)\n            for (GcNode child : children)\n                if (Objects.equals(name, child.name))\n                    return child;\n        return null;\n    }\n    \n    \n    @Override\n    public GcNode getChild(int index) {\n        return children == null ? null : children.get(index);\n    }\n\n    @Override\n    public GcNode[] getChildren() {\n        return children == null ? NO_NODES : children.toArray(NO_NODES);\n    }\n\n    @Override\n    public int getIndexOfChild(Object child) {\n        return children == null ? -1 : children.indexOf(child);\n    }\n\n    @Override\n    public int getNChildren() {\n        return children == null ? 0 : children.size();\n    }\n    \n    @Override\n    public boolean isLeaf() {\n        return children == null || children.isEmpty();\n    }\n\n    @Override\n    public GcNode getParent() {\n        return parent;\n    }\n\n    \n    protected void addChild(GcNode child) {\n        if (children != null) children.add(child);\n    }\n    \n    protected void removeAllChildren() {\n        if (children != null) children.clear();\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return Objects.hash(name, gcid);\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        if (o == this) return true;\n        if (!(o instanceof GcNode)) return false;\n        if (gcid == -1 && ((GcNode)o).gcid == -1) return Objects.equals(name, ((GcNode)o).name);\n        else return gcid == ((GcNode)o).gcid && Objects.equals(name, ((GcNode)o).name);\n    }\n    \n    @Override\n    public String toString() {\n        return name;\n    }\n    \n    \n    static final class Name extends GcNode {\n        \n        Name(String name, GcNode parent, boolean terminal) {\n            super(name, null, parent, terminal ? null : new ArrayList<>());\n        }\n        \n        protected void processDataImpl(JFREvent event) throws JFRPropertyNotAvailableException {\n            count++;\n        }\n        \n    }\n    \n    static final class Cause extends GcNode {\n        \n        Cause(String cause, GcNode parent, boolean terminal) {\n            super(cause, null, parent, terminal ? null : new ArrayList<>());\n        }\n        \n        protected void processDataImpl(JFREvent event) throws JFRPropertyNotAvailableException {\n            count++;\n        }\n        \n    }\n    \n    \n    static final class Event extends GcNode {\n        \n        Event(String name, GcNode parent, boolean terminal) {\n            super(name, Icons.getIcon(ProfilerIcons.RUN_GC), parent, terminal ? null : new ArrayList<>());\n        }\n        \n        protected void processDataImpl(JFREvent event) throws JFRPropertyNotAvailableException {\n            cause = event.getString(\"cause\"); // NOI18N\n            gcid = event.getLong(\"gcId\"); // NOI18N\n        }\n        \n    }\n    \n    static final class Phase extends GcNode {\n        \n        private final int idx;\n        \n        Phase(String name, Duration duration, int idx, GcNode parent) {\n            super(name, null, parent, null);\n            sumOfPauses = duration;\n            this.idx = idx;\n        }\n        \n        @Override\n        public int hashCode() {\n            return idx;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof GcNode.Phase)) return false;\n            return idx == ((GcNode.Phase)o).idx;\n        }\n        \n    }\n    \n    \n    static final class Label extends GcNode {\n        \n        Label(String label, GcNode parent) {\n            super(label, null, parent, null);\n        }\n        \n        static Label createNoData(GcNode parent) {\n            return new Label(\"<no data>\", parent);\n        }\n        \n    }\n    \n    \n    static final class Root extends GcNode implements JFREventVisitor {\n        \n        private final GcViewSupport.Aggregation primary;\n        private final GcViewSupport.Aggregation secondary;\n    \n        \n        Root() {\n            this(null, null);\n        }\n        \n        Root(GcViewSupport.Aggregation primary, GcViewSupport.Aggregation secondary) {\n            super(null, null, null, primary == null && secondary == null ? null : new ArrayList<>());\n            \n            this.primary = primary;\n            this.secondary = secondary;\n        }\n        \n        \n        private static class PhaseRecord {\n            final Instant time;\n            final String name;\n            final Duration duration;\n            \n            PhaseRecord(Instant time, String name, Duration duration) {\n                this.time = time;\n                this.name = name;\n                this.duration = duration;\n            }\n            \n            static String phaseName(String typeName) {\n                if (JFRSnapshotGcViewProvider.EVENT_GCPHASE_CONCURRENT.equals(typeName)) return \"[concurrent]\";\n                if (JFRSnapshotGcViewProvider.EVENT_GCPHASE_PARALLEL.equals(typeName)) return \"[parallel]\";\n                if (JFRSnapshotGcViewProvider.EVENT_GCPHASE_PAUSE.equals(typeName)) return \"[pause]\";\n                if (JFRSnapshotGcViewProvider.EVENT_GCPHASE_PAUSE_LVL1.equals(typeName)) return \"[pause level 1]\";\n                if (JFRSnapshotGcViewProvider.EVENT_GCPHASE_PAUSE_LVL2.equals(typeName)) return \"[pause level 2]\";\n                if (JFRSnapshotGcViewProvider.EVENT_GCPHASE_PAUSE_LVL3.equals(typeName)) return \"[pause level 3]\";\n                if (JFRSnapshotGcViewProvider.EVENT_GCPHASE_PAUSE_LVL4.equals(typeName)) return \"[pause level 4]\";\n                return \"[unknown phase]\";\n            }\n        }\n        \n        \n        private List<GcNode.Event> events;\n        private Map<Long, List<PhaseRecord>> records;\n        \n        @Override\n        public void init() {\n            if (GcViewSupport.Aggregation.PHASE.equals(secondary)) {\n                events = new ArrayList<>();\n                records = new HashMap<>();\n            }\n        }\n\n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (JFRSnapshotGcViewProvider.EVENT_GARBAGE_COLLECTION.equals(typeName)) {\n                String primaryName = getName(primary, event);\n                if (primaryName == null) primaryName = \"<unknown>\";\n                \n                if (GcViewSupport.Aggregation.NONE.equals(primary)) {\n                    GcNode.Event node = new GcNode.Event(primaryName, this, events == null);\n                    addChild(node);\n                    if (events != null) events.add(node);\n                    try {\n                        node.processData(event.getDuration(\"sumOfPauses\"), event.getDuration(\"longestPause\"), event); // NOI18N\n                    } catch (JFRPropertyNotAvailableException e) {}\n                } else {\n                    GcNode primaryNode = getChild(primaryName);\n                    if (primaryNode == null) {\n                        primaryNode = createNode(primaryName, primary, this, false);\n                        addChild(primaryNode);\n                    }\n\n//                    if (secondary != null) {\n                        String secondaryName = getName(GcViewSupport.Aggregation.NONE, event);\n                        if (secondaryName == null) secondaryName = \"<unknown>\";\n\n\n//                        GcNode secondaryNode = primaryNode.getChild(secondaryName);\n//                        if (secondaryNode == null) {\n//                            secondaryNode = createNode(secondaryName, GcViewSupport.Aggregation.NONE, primaryNode, true);\n                            GcNode.Event secondaryNode = new GcNode.Event(secondaryName, primaryNode, events == null);\n                            primaryNode.addChild(secondaryNode);\n                            if (events != null) events.add(secondaryNode);\n//                        }\n\n                        try {\n                            secondaryNode.processData(event.getDuration(\"sumOfPauses\"), event.getDuration(\"longestPause\"), event); // NOI18N\n                        } catch (JFRPropertyNotAvailableException e) {}\n//                    } else {\n//                        try {\n//                            primaryNode.processData(event.getDuration(\"sumOfPauses\"), event.getDuration(\"longestPause\"), event); // NOI18N\n//                        } catch (JFRPropertyNotAvailableException e) {}\n//                    }\n                }\n            } else if (records != null && typeName != null && typeName.startsWith(JFRSnapshotGcViewProvider.PREFIX_GCPHASE)) {\n                try {\n                    long gcId = event.getLong(\"gcId\"); // NOI18N\n                    List<PhaseRecord> prlist = records.computeIfAbsent(gcId, k -> new ArrayList<>());\n\n                    Instant ptime = event.getInstant(\"eventTime\"); // NOI18N\n                    String pname = PhaseRecord.phaseName(typeName) + \" - \" + event.getString(\"name\"); // NOI18N\n                    Duration pduration = event.getDuration(\"eventDuration\"); // NOI18N\n                    prlist.add(new PhaseRecord(ptime, pname, pduration));\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n            \n            return false;\n        }\n        \n        @Override\n        public void done() {\n            if (records != null) {\n                for (GcNode.Event event : events) {\n                    List<PhaseRecord> precords = records.get(event.gcid);\n                    if (precords != null) {\n                        precords.sort((PhaseRecord pr1, PhaseRecord pr2) -> pr1.time.compareTo(pr2.time));\n                        \n                        int idx = 0;\n                        for (PhaseRecord precord : precords)\n                            event.addChild(new GcNode.Phase(precord.name, precord.duration, idx++, event));\n                    }\n                }\n                \n                events.clear();\n                events = null;\n                \n                records.clear();\n                records = null;\n            }\n        }\n        \n        \n        @Override\n        public int hashCode() {\n            return 37;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            return o instanceof Root;\n        }\n        \n        \n        private static String getName(GcViewSupport.Aggregation aggregation, JFREvent event) {\n            try {\n                if (GcViewSupport.Aggregation.NONE.equals(aggregation)) return event.getString(\"name\") + \" - \" + event.getString(\"cause\"); // NOI18N\n                if (GcViewSupport.Aggregation.NAME.equals(aggregation)) return event.getString(\"name\"); // NOI18N\n                if (GcViewSupport.Aggregation.CAUSE.equals(aggregation)) return event.getString(\"cause\"); // NOI18N\n            } catch (JFRPropertyNotAvailableException e) {}\n            return null;\n        }\n        \n        private GcNode createNode(String name, GcViewSupport.Aggregation aggregation, GcNode parent, boolean terminal) {\n            if (GcViewSupport.Aggregation.NONE.equals(aggregation)) return new GcNode.Event(name, parent, terminal);\n            if (GcViewSupport.Aggregation.NAME.equals(aggregation)) return new GcNode.Name(name, parent, terminal);\n            if (GcViewSupport.Aggregation.CAUSE.equals(aggregation)) return new GcNode.Cause(name, parent, terminal);\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/gc/GcRenderers.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.gc;\n\nimport java.awt.Font;\nimport java.time.Duration;\nimport javax.swing.JLabel;\nimport org.graalvm.visualvm.jfr.utils.ValuesConverter;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.McsTimeRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class GcRenderers {\n    \n    private static int getMinimumWidth(String valueName) {\n        return new JLabel(valueName).getPreferredSize().width + 30;\n    }\n    \n    \n    static class NameRenderer extends LabelRenderer {\n        \n        private static Font regular;\n        private static Font bold;\n            \n        public void setValue(Object value, int row) {\n            if (value instanceof GcNode) {\n                GcNode node = (GcNode)value;\n                GcNode parent = node.getParent();\n                setFont((parent == null || parent.getParent() == null) && !(value instanceof GcNode.Label) ? bold() : regular());\n                setText(node.name);\n                setIcon(node.icon);\n            } else {\n                super.setValue(value, row);\n            }\n        }\n\n        static String getDisplayName() {\n            return \"Name\";\n        }\n        \n        private static Font regular() {\n            if (regular == null) regular = new LabelRenderer().getFont();\n            return regular;\n        }\n        \n        private static Font bold() {\n            if (bold == null) bold = new LabelRenderer().getFont().deriveFont(Font.BOLD);\n            return bold;\n        }\n\n    }\n    \n    \n    static class GcIdRenderer extends NumberRenderer {\n        \n        static String getDisplayName() {\n            return \"GC ID\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n        public void setText(String text) {\n            if (\"-\".equals(text)) text = \"\"; // NOI18N\n            super.setText(text);\n        }\n        \n    }\n    \n    static class LongestPauseRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Longest Pause\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class SumOfPausesRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Sum Of Pauses\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class CountRenderer extends NumberRenderer {\n        \n        static String getDisplayName() {\n            return \"Count\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n        public void setText(String text) {\n            if (\"-\".equals(text)) text = \"\"; // NOI18N\n            super.setText(text);\n        }\n        \n    }\n    \n    \n    private static class TimeRenderer extends McsTimeRenderer {\n        \n        @Override\n        public void setValue(Object value, int row) {\n            if (value instanceof Duration) {\n                long micros = ValuesConverter.durationToMicros((Duration)value);\n                if (micros == 0) setText(\"< 0.001 ms\"); // NOI18N\n                else super.setValue(micros, row);\n            } else {\n                setText(\"-\"); // NOI18N\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/gc/GcViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.gc;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.time.Duration;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JSeparator;\nimport javax.swing.JTree;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.tree.TreeNode;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.jfr.views.components.MessageComponent;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.components.HTMLLabel;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextAreaSearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class GcViewSupport {\n    \n    static enum Aggregation {\n        NONE { @Override public String toString() { return \"None\"; } },\n        NAME { @Override public String toString() { return \"Name\"; } },\n        CAUSE { @Override public String toString() { return \"Cause\"; } },\n        PHASE { @Override public String toString() { return \"GC Phase\"; } },\n    }\n\n    static abstract class MasterViewSupport extends JPanel {\n        \n        private Aggregation lastPrimary/*, lastSecondary*/;\n        private boolean lastPhase;\n        \n        \n        MasterViewSupport(JFRModel model) {\n            initComponents(model);\n        }\n        \n        \n        DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(\"GC\", null, this);\n        }\n        \n        \n        abstract void firstShown();\n        \n        abstract void changeAggregation(Aggregation primary, Aggregation secondary);\n        \n        \n        void showProgress() {\n            updateButton.setEnabled(false);\n            updateButton.setVisible(false);\n            statusValueLabel.setVisible(true);\n        }\n        \n        void hideProgress() {\n            statusValueLabel.setVisible(false);\n            updateButton.setVisible(true);\n        }\n        \n        \n        private void handleAggregationChanged(boolean updateSecondary) {\n            if (updateSecondary) {\n                DefaultComboBoxModel<Aggregation> model = (DefaultComboBoxModel<Aggregation>)secondCombo.getModel();\n                while (model.getSize() > 1) model.removeElementAt(1);\n                \n//                if (!Aggregation.CLASS.equals(firstCombo.getSelectedItem()) &&\n//                    !Aggregation.CLASS_MESSAGE.equals(firstCombo.getSelectedItem()))\n//                        model.addElement(Aggregation.CLASS);\n//                \n//                if (!Aggregation.MESSAGE.equals(firstCombo.getSelectedItem()) &&\n//                    !Aggregation.CLASS_MESSAGE.equals(firstCombo.getSelectedItem()))\n//                        model.addElement(Aggregation.MESSAGE);\n//                \n//                if (!Aggregation.CLASS.equals(firstCombo.getSelectedItem()) &&\n//                    !Aggregation.MESSAGE.equals(firstCombo.getSelectedItem()) &&\n//                    !Aggregation.CLASS_MESSAGE.equals(firstCombo.getSelectedItem()))\n//                        model.addElement(Aggregation.CLASS_MESSAGE);\n//                \n//                if (!Aggregation.THREAD.equals(firstCombo.getSelectedItem()))\n//                    model.addElement(Aggregation.THREAD);\n            }\n            \n            updateButton.setEnabled(lastPrimary != firstCombo.getSelectedItem() ||\n                                    lastPhase != secondChoice.isSelected());\n            \n        }\n        \n        \n        private int prefHeight = -1;\n        public Dimension getPreferredSize() {\n            Dimension pref = super.getPreferredSize();\n            if (prefHeight == -1) prefHeight = pref.height;\n            else pref.height = prefHeight;\n            return pref;\n        }\n        \n        \n        private void initComponents(JFRModel model) {\n            setOpaque(false);\n            \n            if (model == null) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.notAvailable(), BorderLayout.CENTER);\n            } else if (!model.containsEvent(JFRSnapshotGcViewProvider.EventChecker.class)) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.noData(\"GC\", JFRSnapshotGcViewProvider.EventChecker.checkedTypes()), BorderLayout.CENTER);\n            } else {\n                setLayout(new GridBagLayout());\n                setBorder(BorderFactory.createEmptyBorder(11, 5, 20, 5));\n\n                GridBagConstraints constraints;\n\n                // modeLabel\n                firstLabel = new JLabel();\n                firstLabel.setText(\"Aggregation:\");\n                firstLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 0;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(firstLabel, constraints);\n\n                // cpuButton\n                firstCombo = new JComboBox<>(new Aggregation[] { Aggregation.NONE, Aggregation.NAME, Aggregation.CAUSE });\n                firstCombo.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleAggregationChanged(true); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 1;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(firstCombo, constraints);\n\n                // modeLabel\n//                secondLabel = new JLabel();\n//                secondLabel.setText(\"secondary:\");\n//                secondLabel.setOpaque(false);\n//                constraints = new GridBagConstraints();\n//                constraints.gridx = 2;\n//                constraints.gridy = 2;\n//                constraints.gridwidth = 1;\n//                constraints.fill = GridBagConstraints.NONE;\n//                constraints.anchor = GridBagConstraints.WEST;\n//                constraints.insets = new Insets(4, 12, 0, 0);\n//                add(secondLabel, constraints);\n//\n//                // memoryButton\n                secondCombo = new JComboBox<>(new Aggregation[] { Aggregation.NONE, Aggregation.NAME, Aggregation.CAUSE });\n//                secondCombo.addActionListener(new ActionListener() {\n//                    public void actionPerformed(ActionEvent e) { handleAggregationChanged(false); }\n//                });\n//                constraints = new GridBagConstraints();\n//                constraints.gridx = 3;\n//                constraints.gridy = 2;\n//                constraints.gridwidth = 1;\n//                constraints.fill = GridBagConstraints.NONE;\n//                constraints.anchor = GridBagConstraints.WEST;\n//                constraints.insets = new Insets(4, 8, 0, 0);\n//                add(secondCombo, constraints);\n\n                // pause levels choice\n                boolean hasPhases = model.containsEvent(JFRSnapshotGcViewProvider.EventChecker_Phases.class);\n                secondChoice = new JCheckBox(hasPhases ? \"Show GC Phases\" : \"Show GC Phases (no phases recorded)\");\n                secondChoice.setOpaque(false);\n                secondChoice.setEnabled(hasPhases);\n                secondChoice.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleAggregationChanged(false); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 3;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 12, 0, 0);\n                add(secondChoice, constraints);\n                \n                lastPrimary = (Aggregation)firstCombo.getSelectedItem();\n                lastPhase = secondChoice.isSelected();\n//                lastSecondary = (Aggregation)secondCombo.getSelectedItem();\n\n                // updateSeparator\n                JSeparator updateSeparator = new JSeparator(JSeparator.VERTICAL);\n                updateSeparator.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 4;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 12, 0, 0);\n                add(updateSeparator, constraints);\n\n                // updateButton\n                updateButton = new JButton(\"Update Data\");\n                updateButton.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        updateButton.setEnabled(false);\n                        lastPrimary = (Aggregation)firstCombo.getSelectedItem();\n                        lastPhase = secondChoice.isSelected();\n//                        lastSecondary = (Aggregation)secondCombo.getSelectedItem();\n//                        changeAggregation((Aggregation)firstCombo.getSelectedItem(), (Aggregation)secondCombo.getSelectedItem());\n                        changeAggregation((Aggregation)firstCombo.getSelectedItem(), secondChoice.isSelected() ? Aggregation.PHASE : Aggregation.NONE);\n                    }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 5;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 12, 0, 0);\n                add(updateButton, constraints);\n\n                // statusValueLabel\n                statusValueLabel = new HTMLLabel(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n                constraints = new GridBagConstraints();\n                constraints.gridx = 6;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 20, 0, 0);\n                add(statusValueLabel, constraints);\n                statusValueLabel.setVisible(false);\n\n                // filler1\n                constraints = new GridBagConstraints();\n                constraints.gridx = 7;\n                constraints.gridy = 2;\n                constraints.weightx = 1;\n                constraints.weighty = 1;\n                constraints.gridwidth = GridBagConstraints.REMAINDER;\n                constraints.fill = GridBagConstraints.BOTH;\n                constraints.anchor = GridBagConstraints.NORTHWEST;\n                constraints.insets = new Insets(0, 0, 0, 0);\n                add(Spacer.create(), constraints);\n\n                Dimension cpuD     = firstCombo.getPreferredSize();\n                Dimension memoryD  = secondCombo.getPreferredSize();\n    //            Dimension stopD    = stopButton.getPreferredSize();\n\n                Dimension maxD = new Dimension(Math.max(cpuD.width, memoryD.width), Math.max(cpuD.height, memoryD.height));\n    //            maxD = new Dimension(Math.max(maxD.width, stopD.width), Math.max(maxD.height, stopD.height));\n\n                firstCombo.setPreferredSize(maxD);\n                firstCombo.setMinimumSize(maxD);\n                secondCombo.setPreferredSize(maxD);\n                secondCombo.setMinimumSize(maxD);\n    //            stopButton.setPreferredSize(maxD);\n    //            stopButton.setMinimumSize(maxD);\n    \n                Dimension sepD = updateSeparator.getPreferredSize();\n                sepD.height = maxD.height - 2;\n                sepD.width = 5;\n                updateSeparator.setPreferredSize(sepD);\n                updateSeparator.setMinimumSize(sepD);\n\n                addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                            if (isShowing()) {\n                                removeHierarchyListener(this);\n                                SwingUtilities.invokeLater(MasterViewSupport.this::firstShown);\n                            }\n                        }\n                    }\n                });\n            }\n        }\n\n        private JLabel firstLabel;\n//        private JLabel secondLabel;\n        private JComboBox<Aggregation> firstCombo;\n        private JComboBox<Aggregation> secondCombo;\n        private JCheckBox secondChoice;\n        private JButton updateButton;\n        private HTMLLabel statusValueLabel;\n        \n    }\n    \n    \n    static final class DataViewSupport extends JPanel {\n        \n        private DataModel tableModel;\n        private ProfilerTreeTable table;\n        \n        \n        DataViewSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Data\", null, 10, this, null); // NOI18N\n        }\n        \n        \n        void setData(GcNode root, boolean aggregated, boolean phases) {\n            tableModel.setRoot(root);\n             \n            if (root.getChildCount() > 0) {\n                table.setShowsRootHandles(aggregated || phases);\n                \n                if (aggregated) {\n                    if (!table.isColumnVisible(4)) table.setColumnVisibility(4, true);\n//                    if (table.getSortColumn() == 1) table.setSortColumn(3);\n                } else {\n//                    if (table.getSortColumn() == 4) table.setSortColumn(2);\n                    if (table.isColumnVisible(4)) table.setColumnVisibility(4, false);\n                }\n            }\n        }\n        \n        \n        private void initComponents() {\n            tableModel = new DataModel();\n            table = new ProfilerTreeTable(tableModel, true, true, new int[] { 0 });\n            \n            table.setRootVisible(false);\n            table.setShowsRootHandles(true);\n\n            table.setMainColumn(0);\n            table.setFitWidthColumn(0);\n\n            table.setSortColumn(1);\n            table.setDefaultSortOrder(SortOrder.DESCENDING);\n            table.setDefaultSortOrder(0, SortOrder.ASCENDING);\n            \n            GcRenderers.NameRenderer nameRenderer = new GcRenderers.NameRenderer();\n            table.setTreeCellRenderer(nameRenderer);\n            \n            GcRenderers.GcIdRenderer gcidRenderer = new GcRenderers.GcIdRenderer();\n            table.setColumnRenderer(1, gcidRenderer);\n            table.setDefaultSortOrder(1, SortOrder.ASCENDING);\n            table.setDefaultColumnWidth(1, gcidRenderer.getPreferredWidth());\n            table.setColumnVisibility(1, GcRenderers.GcIdRenderer.isInitiallyVisible());\n            table.setSortColumn(1);\n            \n            GcRenderers.LongestPauseRenderer longestPauseRenderer = new GcRenderers.LongestPauseRenderer();\n            table.setColumnRenderer(2, longestPauseRenderer);\n            table.setDefaultColumnWidth(2, longestPauseRenderer.getPreferredWidth());\n            table.setColumnVisibility(2, GcRenderers.LongestPauseRenderer.isInitiallyVisible());\n            \n            GcRenderers.SumOfPausesRenderer sumOfPausesRenderer = new GcRenderers.SumOfPausesRenderer();\n            table.setColumnRenderer(3, sumOfPausesRenderer);\n            table.setDefaultColumnWidth(3, sumOfPausesRenderer.getPreferredWidth());\n            table.setColumnVisibility(3, GcRenderers.SumOfPausesRenderer.isInitiallyVisible());\n            \n            GcRenderers.CountRenderer countRenderer = new GcRenderers.CountRenderer();\n            table.setColumnRenderer(4, countRenderer);\n            table.setDefaultColumnWidth(4, countRenderer.getPreferredWidth());\n            table.setColumnVisibility(4, GcRenderers.CountRenderer.isInitiallyVisible());\n            \n            setLayout(new BorderLayout());\n            add(new ProfilerTableContainer(table, false, null), BorderLayout.CENTER);\n        }\n        \n        \n        private static class DataModel extends ProfilerTreeTableModel.Abstract {\n            \n            DataModel() {\n                super(new GcNode.Root());\n            }\n            \n            \n            @Override\n            public int getColumnCount() {\n                return 5;\n            }\n\n            @Override\n            public Class<?> getColumnClass(int column) {\n                switch (column) {\n                    case 0: return JTree.class;\n                    case 1: return Long.class;\n                    case 2: return Duration.class;\n                    case 3: return Duration.class;\n                    case 4: return Long.class;\n                    default: return null;\n                }\n            }\n\n            @Override\n            public String getColumnName(int column) {\n                switch (column) {\n                    case 0: return GcRenderers.NameRenderer.getDisplayName();\n                    case 1: return GcRenderers.GcIdRenderer.getDisplayName();\n                    case 2: return GcRenderers.LongestPauseRenderer.getDisplayName();\n                    case 3: return GcRenderers.SumOfPausesRenderer.getDisplayName();\n                    case 4: return GcRenderers.CountRenderer.getDisplayName();\n                    default: return null;\n                }\n            }\n\n            @Override\n            public Object getValueAt(TreeNode node, int column) {\n                if (node == null) return null;\n                GcNode fnode = (GcNode)node;\n                \n                switch (column) {\n                    case 0: return fnode;\n                    case 1: return toLong(fnode.gcid, -1);\n                    case 2: return fnode.longestPause;\n                    case 3: return fnode.sumOfPauses;\n                    case 4: return toLong(fnode.count, 0);\n                    default: return null;\n                }\n            }\n            \n            @Override\n            public void setValueAt(Object o, TreeNode node, int column) {}\n\n            @Override\n            public boolean isCellEditable(TreeNode node, int column) { return false; }\n            \n            \n            private Long toLong(long value, long noValue) {\n                return value == noValue ? null : Long.valueOf(value);\n            }\n            \n        }\n        \n    }\n    \n    \n    static class GcConfigurationSupport extends JPanel implements JFREventVisitor {\n        \n        private volatile boolean initialized = false;\n        \n        private HTMLTextArea area;\n        \n        \n        GcConfigurationSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"GC configuration\", null, 10, this, null);\n        }\n        \n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (JFRSnapshotGcViewProvider.EVENT_GC_CONFIGURATION.equals(typeName)) { // NOI18N\n                try {\n                    final StringBuilder s = new StringBuilder();\n                    \n                    s.append(\"<table border='0' cellpadding='0' cellspacing='0' width='100%'>\");\n                \n                    s.append(\"<tr><td nowrap><b>Young GC:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(event.getString(\"youngCollector\")).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Old GC:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(event.getString(\"oldCollector\")).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Concurrent Threads:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.numberFormat().format(event.getLong(\"concurrentGCThreads\"))).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Parallel Threads:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.numberFormat().format(event.getLong(\"parallelGCThreads\"))).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>System.gc() Disabled:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(event.getBoolean(\"isExplicitGCDisabled\")).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>System.gc() Concurrent:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(event.getBoolean(\"isExplicitGCConcurrent\")).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Uses Dynamic Threads:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(event.getBoolean(\"usesDynamicGCThreads\")).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>GC Time Ratio:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.numberFormat().format(event.getLong(\"gcTimeRatio\"))).append(\"</td></tr>\"); // NOI18N\n                    \n                \n                    s.append(\"</table>\"); // NOI18N\n                    \n                    initialized = true;\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            area.setText(s.toString());\n                            area.setCaretPosition(0);\n                        }\n                    });\n                } catch (JFRPropertyNotAvailableException e) {}\n                \n                return true;\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            if (!initialized) SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    area.setText(\"&lt;unknown&gt;\");\n                    area.setCaretPosition(0);\n                    initialized = true;\n                }\n            });\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n            add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n    }\n    \n    static class GcHeapConfigurationSupport extends JPanel implements JFREventVisitor {\n        \n        private volatile boolean initialized = false;\n        \n        private HTMLTextArea area;\n        \n        \n        GcHeapConfigurationSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Heap configuration\", null, 20, this, null);\n        }\n        \n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (JFRSnapshotGcViewProvider.EVENT_HEAP_CONFIGURATION.equals(typeName)) { // NOI18N\n                try {\n                    final StringBuilder s = new StringBuilder();\n                    \n                    s.append(\"<table border='0' cellpadding='0' cellspacing='0' width='100%'>\");\n                \n                    s.append(\"<tr><td nowrap><b>Initial Size:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.bytesFormat().format(new Object[] { event.getLong(\"initialSize\") })).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Minimum Size:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.bytesFormat().format(new Object[] { event.getLong(\"minSize\") })).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Maximum Size:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.bytesFormat().format(new Object[] { event.getLong(\"maxSize\") })).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Compressed Oops:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(event.getBoolean(\"usesCompressedOops\")).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Compressed Oops Mode:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(event.getString(\"compressedOopsMode\")).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Address Size:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.numberFormat().format(event.getLong(\"heapAddressBits\"))).append(\" bits</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Object Alignment:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.bytesFormat().format(new Object[] { event.getLong(\"objectAlignment\") })).append(\"</td></tr>\"); // NOI18N\n                    \n                \n                    s.append(\"</table>\"); // NOI18N\n                    \n                    initialized = true;\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            area.setText(s.toString());\n                            area.setCaretPosition(0);\n                        }\n                    });\n                } catch (JFRPropertyNotAvailableException e) {}\n                \n                return true;\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            if (!initialized) SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    area.setText(\"&lt;unknown&gt;\");\n                    area.setCaretPosition(0);\n                    initialized = true;\n                }\n            });\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n            add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n    }\n    \n    static class GcYoungGenConfigurationSupport extends JPanel implements JFREventVisitor {\n        \n        private volatile boolean initialized = false;\n        \n        private HTMLTextArea area;\n        \n        \n        GcYoungGenConfigurationSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Young Generation configuration\", null, 30, this, null);\n        }\n        \n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (JFRSnapshotGcViewProvider.EVENT_YOUNG_GEN_CONFIGURATION.equals(typeName)) { // NOI18N\n                try {\n                    final StringBuilder s = new StringBuilder();\n                    \n                    s.append(\"<table border='0' cellpadding='0' cellspacing='0' width='100%'>\");\n                \n                    s.append(\"<tr><td nowrap><b>Minimum Size:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.bytesFormat().format(new Object[] { event.getLong(\"minSize\") })).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Maximum Size:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.bytesFormat().format(new Object[] { event.getLong(\"maxSize\") })).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Yount Generation Ratio:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.numberFormat().format(event.getLong(\"newRatio\"))).append(\"</td></tr>\"); // NOI18N\n                    \n                \n                    s.append(\"</table>\"); // NOI18N\n                    \n                    initialized = true;\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            area.setText(s.toString());\n                            area.setCaretPosition(0);\n                        }\n                    });\n                } catch (JFRPropertyNotAvailableException e) {}\n                \n                return true;\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            if (!initialized) SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    area.setText(\"&lt;unknown&gt;\");\n                    area.setCaretPosition(0);\n                    initialized = true;\n                }\n            });\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n            add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n    }\n    \n    static class GcSurvivorConfigurationSupport extends JPanel implements JFREventVisitor {\n        \n        private volatile boolean initialized = false;\n        \n        private HTMLTextArea area;\n        \n        \n        GcSurvivorConfigurationSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Survivor configuration\", null, 40, this, null);\n        }\n        \n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (JFRSnapshotGcViewProvider.EVENT_SURVIVOR_CONFIGURATION.equals(typeName)) { // NOI18N\n                try {\n                    final StringBuilder s = new StringBuilder();\n                    \n                    s.append(\"<table border='0' cellpadding='0' cellspacing='0' width='100%'>\");\n                \n                    s.append(\"<tr><td nowrap><b>Initial Tenuring Threshold:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.numberFormat().format(event.getLong(\"initialTenuringThreshold\"))).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Maximum Tenuring Threshold:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.numberFormat().format(event.getLong(\"maxTenuringThreshold\"))).append(\"</td></tr>\"); // NOI18N\n                    \n                \n                    s.append(\"</table>\"); // NOI18N\n                    \n                    initialized = true;\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            area.setText(s.toString());\n                            area.setCaretPosition(0);\n                        }\n                    });\n                } catch (JFRPropertyNotAvailableException e) {}\n                \n                return true;\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            if (!initialized) SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    area.setText(\"&lt;unknown&gt;\");\n                    area.setCaretPosition(0);\n                    initialized = true;\n                }\n            });\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n            add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n    }\n    \n    static class GcTlabConfigurationSupport extends JPanel implements JFREventVisitor {\n        \n        private volatile boolean initialized = false;\n        \n        private HTMLTextArea area;\n        \n        \n        GcTlabConfigurationSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"TLAB configuration\", null, 50, this, null);\n        }\n        \n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (JFRSnapshotGcViewProvider.EVENT_TLAB_CONFIGURATION.equals(typeName)) { // NOI18N\n                try {\n                    final StringBuilder s = new StringBuilder();\n                    \n                    s.append(\"<table border='0' cellpadding='0' cellspacing='0' width='100%'>\");\n                \n                    s.append(\"<tr><td nowrap><b>TLABs Used:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(event.getBoolean(\"usesTLABs\")).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>Minimum TLAB Size:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.bytesFormat().format(new Object[] { event.getLong(\"minTLABSize\") })).append(\"</td></tr>\"); // NOI18N\n                    s.append(\"<tr><td nowrap><b>TLAB Refill Waste Limit:</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td width='100%'>\").append(Formatters.bytesFormat().format(new Object[] { event.getLong(\"tlabRefillWasteLimit\") })).append(\"</td></tr>\"); // NOI18N\n                    \n                \n                    s.append(\"</table>\"); // NOI18N\n                    \n                    initialized = true;\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            area.setText(s.toString());\n                            area.setCaretPosition(0);\n                        }\n                    });\n                } catch (JFRPropertyNotAvailableException e) {}\n                \n                return true;\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            if (!initialized) SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    area.setText(\"&lt;unknown&gt;\");\n                    area.setCaretPosition(0);\n                    initialized = true;\n                }\n            });\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n            add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/gc/JFRSnapshotGcView.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.gc;\n\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRSnapshotGcView extends JFRViewTab {\n    \n    JFRSnapshotGcView(JFRSnapshot jfrSnapshot) {\n        super(jfrSnapshot, \"GC\", Icons.getImage(ProfilerIcons.RUN_GC), 60);\n\n    }\n    \n    \n    private GcViewSupport.MasterViewSupport masterView;\n    private GcViewSupport.DataViewSupport dataView;\n    \n    \n    protected DataViewComponent createComponent() {\n        JFRModel model = getModel();\n        \n        boolean hasEvents = model != null && model.containsEvent(JFRSnapshotGcViewProvider.EventChecker.class);\n        \n        if (!hasEvents) {\n            masterView = new GcViewSupport.MasterViewSupport(model) {\n                @Override void firstShown() {}\n                @Override void changeAggregation(GcViewSupport.Aggregation primary, GcViewSupport.Aggregation secondary) {}\n            };\n            return new DataViewComponent(masterView.getMasterView(), new DataViewComponent.MasterViewConfiguration(true));\n        } else {\n            final GcViewSupport.GcConfigurationSupport gcConfigurationView = new GcViewSupport.GcConfigurationSupport();\n            final GcViewSupport.GcHeapConfigurationSupport gcHeapConfigurationView = new GcViewSupport.GcHeapConfigurationSupport();\n            final GcViewSupport.GcYoungGenConfigurationSupport gcYoungGenConfigurationView = new GcViewSupport.GcYoungGenConfigurationSupport();\n            final GcViewSupport.GcSurvivorConfigurationSupport gcSurvivorConfigurationView = new GcViewSupport.GcSurvivorConfigurationSupport();\n            final GcViewSupport.GcTlabConfigurationSupport gcTlabConfigurationView = new GcViewSupport.GcTlabConfigurationSupport();\n        \n            masterView = new GcViewSupport.MasterViewSupport(model) {\n                @Override\n                void firstShown() {\n                    changeAggregation(GcViewSupport.Aggregation.NONE, GcViewSupport.Aggregation.NONE);\n                    initialize(gcConfigurationView, gcHeapConfigurationView, gcYoungGenConfigurationView, gcSurvivorConfigurationView, gcTlabConfigurationView);\n                }\n                @Override\n                void changeAggregation(GcViewSupport.Aggregation primary, GcViewSupport.Aggregation secondary) {\n                    JFRSnapshotGcView.this.setAggregation(primary, secondary);\n                }\n            };\n            \n            DataViewComponent dvc = new DataViewComponent(masterView.getMasterView(), new DataViewComponent.MasterViewConfiguration(false));\n            \n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Data\", false), DataViewComponent.TOP_LEFT);\n\n            dataView = new GcViewSupport.DataViewSupport();\n            dvc.addDetailsView(dataView.getDetailsView(), DataViewComponent.TOP_LEFT);\n            \n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Configuration\", true), DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(gcConfigurationView.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(gcHeapConfigurationView.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(gcYoungGenConfigurationView.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(gcSurvivorConfigurationView.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(gcTlabConfigurationView.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n            \n            return dvc;\n        }\n    }\n    \n    \n    private void setAggregation(GcViewSupport.Aggregation primary, GcViewSupport.Aggregation secondary) {\n        masterView.showProgress();\n        dataView.setData(new GcNode.Root(), false, false);\n        \n        new RequestProcessor(\"JFR GC Initializer\").post(new Runnable() { // NOI18N\n            public void run() {\n                final GcNode.Root root = new GcNode.Root(primary, secondary);\n                getModel().visitEvents(root);\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        if (root.getNChildren() == 0) root.addChild(GcNode.Label.createNoData(root));\n                        dataView.setData(root, !GcViewSupport.Aggregation.NONE.equals(primary), GcViewSupport.Aggregation.PHASE.equals(secondary));\n                        masterView.hideProgress();\n                    }\n                });\n            }\n        });\n    }\n    \n    private void initialize(final JFREventVisitor... visitors) {\n        new RequestProcessor(\"JFR GC Initializer\").post(new Runnable() { // NOI18N\n            public void run() { getModel().visitEvents(visitors); }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/gc/JFRSnapshotGcViewProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.gc;\n\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREventChecker;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.jfr.view.JFRViewTabProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=JFRViewTabProvider.class)\npublic final class JFRSnapshotGcViewProvider extends JFRViewTabProvider {\n    \n    static final String EVENT_GARBAGE_COLLECTION = \"jdk.GarbageCollection\"; // NOI18N\n    static final String EVENT_GC_CONFIGURATION = \"jdk.GCConfiguration\"; // NOI18N\n    static final String EVENT_HEAP_CONFIGURATION = \"jdk.GCHeapConfiguration\"; // NOI18N\n    static final String EVENT_YOUNG_GEN_CONFIGURATION = \"jdk.YoungGenerationConfiguration\"; // NOI18N\n    static final String EVENT_SURVIVOR_CONFIGURATION = \"jdk.GCSurvivorConfiguration\"; // NOI18N\n    static final String EVENT_TLAB_CONFIGURATION = \"jdk.GCTLABConfiguration\"; // NOI18N\n    \n    static final String PREFIX_GCPHASE = \"jdk.GCPhase\"; // NOI18\n    static final String EVENT_GCPHASE_CONCURRENT = \"jdk.GCPhaseConcurrent\"; // NOI18\n    static final String EVENT_GCPHASE_PARALLEL = \"jdk.GCPhaseParallel\"; // NOI18\n    static final String EVENT_GCPHASE_PAUSE = \"jdk.GCPhasePause\"; // NOI18N\n    static final String EVENT_GCPHASE_PAUSE_LVL1 = \"jdk.GCPhasePauseLevel1\"; // NOI18N\n    static final String EVENT_GCPHASE_PAUSE_LVL2 = \"jdk.GCPhasePauseLevel2\"; // NOI18N\n    static final String EVENT_GCPHASE_PAUSE_LVL3 = \"jdk.GCPhasePauseLevel3\"; // NOI18N\n    static final String EVENT_GCPHASE_PAUSE_LVL4 = \"jdk.GCPhasePauseLevel4\"; // NOI18N\n    \n    \n    protected JFRViewTab createView(JFRSnapshot jfrSnapshot) {\n        return new JFRSnapshotGcView(jfrSnapshot);\n    }\n    \n    \n    @ServiceProvider(service=JFREventChecker.class)\n    public static final class EventChecker extends JFREventChecker {\n        \n        public EventChecker() {\n            super(checkedTypes());\n        }\n        \n        static String[] checkedTypes() {\n            return new String[] {\n                EVENT_GARBAGE_COLLECTION,\n                EVENT_GC_CONFIGURATION,\n                EVENT_YOUNG_GEN_CONFIGURATION,\n                EVENT_SURVIVOR_CONFIGURATION,\n                EVENT_TLAB_CONFIGURATION\n            };\n        }\n        \n    }\n    \n    @ServiceProvider(service=JFREventChecker.class)\n    public static final class EventChecker_Phases extends JFREventChecker {\n        \n        public EventChecker_Phases() {\n            super(checkedTypes());\n        }\n        \n        static String[] checkedTypes() {\n            return new String[] {\n                EVENT_GCPHASE_CONCURRENT,\n                EVENT_GCPHASE_PARALLEL,\n                EVENT_GCPHASE_PAUSE,\n                EVENT_GCPHASE_PAUSE_LVL1,\n                EVENT_GCPHASE_PAUSE_LVL2,\n                EVENT_GCPHASE_PAUSE_LVL3,\n                EVENT_GCPHASE_PAUSE_LVL4\n            };\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/locks/JFRSnapshotLocksView.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.locks;\n\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRSnapshotLocksView extends JFRViewTab {\n    \n    JFRSnapshotLocksView(JFRSnapshot jfrSnapshot) {\n        super(jfrSnapshot, \"Locks\", Icons.getImage(ProfilerIcons.WINDOW_LOCKS), 32);\n\n    }\n    \n    \n    private DataViewComponent dvc;\n    private LocksViewSupport.MasterViewSupport masterView;\n    private LocksViewSupport.DataViewSupport dataView;\n    \n    \n    protected DataViewComponent createComponent() {\n        JFRModel model = getModel();\n        \n        masterView = new LocksViewSupport.MasterViewSupport(model) {\n            @Override\n            void firstShown() {\n                changeAggregation(0, LocksViewSupport.Aggregation.CLASS, LocksViewSupport.Aggregation.NONE);\n            }\n            @Override\n            void changeAggregation(int mode, LocksViewSupport.Aggregation primary, LocksViewSupport.Aggregation secondary) {\n                JFRSnapshotLocksView.this.setAggregation(mode, primary, secondary);\n            }\n        };\n        \n        boolean hasEvents = model != null && model.containsEvent(JFRSnapshotLocksViewProvider.EventChecker.class);\n        \n        dvc = new DataViewComponent(\n                masterView.getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(!hasEvents));\n        \n        if (hasEvents) {\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Data\", false), DataViewComponent.TOP_LEFT);\n            \n            dataView = new LocksViewSupport.DataViewSupport();\n            dvc.addDetailsView(dataView.getDetailsView(), DataViewComponent.TOP_LEFT);\n        }\n\n        return dvc;\n    }\n    \n    \n    private void setAggregation(final int mode, final LocksViewSupport.Aggregation primary, final LocksViewSupport.Aggregation secondary) {\n        masterView.showProgress();\n        dataView.setData(new LocksNode.Root(), false);\n        \n        new RequestProcessor(\"JFR Locks Initializer\").post(new Runnable() { // NOI18N\n            public void run() {\n                final LocksNode.Root root = new LocksNode.Root(mode, primary, secondary);\n                getModel().visitEvents(root);\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        if (root.getNChildren() == 0) root.addChild(LocksNode.Label.createNoData(root));\n                        dataView.setData(root, !LocksViewSupport.Aggregation.NONE.equals(secondary));\n                        masterView.hideProgress();\n                    }\n                });\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/locks/JFRSnapshotLocksViewProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.locks;\n\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREventChecker;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.jfr.view.JFRViewTabProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class JFRSnapshotLocksViewProvider extends JFRViewTabProvider {\n    \n    static final String EVENT_MONITOR_ENTER = \"jdk.JavaMonitorEnter\"; // NOI18N\n    static final String EVENT_MONITOR_WAIT = \"jdk.JavaMonitorWait\"; // NOI18N\n    \n    \n    protected JFRViewTab createView(JFRSnapshot jfrSnapshot) {\n        return new JFRSnapshotLocksView(jfrSnapshot);\n    }\n    \n    \n    @ServiceProvider(service=JFREventChecker.class)\n    public static final class EventChecker extends JFREventChecker {\n        \n        public EventChecker() {\n            super(checkedTypes());\n        }\n        \n        static String[] checkedTypes() {\n            return new String[] {\n                EVENT_MONITOR_ENTER, EVENT_MONITOR_WAIT\n            };\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/locks/LocksNode.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.locks;\n\nimport java.time.Duration;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.jfr.model.JFRThread;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class LocksNode extends CCTNode {\n    \n    private static final LocksNode[] NO_NODES = new LocksNode[0];\n    \n    private final LocksNode parent;\n    private final List<LocksNode> children;\n    \n    final String name;\n    final Icon icon;\n    \n    long count = 0;\n    Duration duration, durationMax;\n    \n    \n    LocksNode(String name, Icon icon, LocksNode parent, List<LocksNode> children) {\n        this.parent = parent;\n        this.children = children;\n        \n        this.name = name;\n        this.icon = icon;\n    }\n    \n    \n    final void processData(Duration duration) {\n        if (parent != null) {\n            count++;\n            if (this.duration == null) this.duration = duration; else this.duration = this.duration.plus(duration);\n            if (durationMax == null || durationMax.compareTo(duration) < 0) durationMax = duration;\n            \n            parent.processData(duration);\n        }\n    }\n    \n    \n    LocksNode getChild(String name) {\n        if (children != null)\n            for (LocksNode child : children)\n                if (Objects.equals(name, child.name))\n                    return child;\n        return null;\n    }\n    \n    \n    @Override\n    public LocksNode getChild(int index) {\n        return children == null ? null : children.get(index);\n    }\n\n    @Override\n    public LocksNode[] getChildren() {\n        return children == null ? NO_NODES : children.toArray(NO_NODES);\n    }\n\n    @Override\n    public int getIndexOfChild(Object child) {\n        return children == null ? -1 : children.indexOf(child);\n    }\n\n    @Override\n    public int getNChildren() {\n        return children == null ? 0 : children.size();\n    }\n    \n    @Override\n    public boolean isLeaf() {\n        return children == null || children.isEmpty();\n    }\n\n    @Override\n    public LocksNode getParent() {\n        return parent;\n    }\n\n    \n    protected void addChild(LocksNode child) {\n        if (children != null) children.add(child);\n    }\n    \n    protected void removeAllChildren() {\n        if (children != null) children.clear();\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return name.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        if (!(o instanceof LocksNode)) return false;\n        return Objects.equals(name, ((LocksNode)o).name);\n    }\n    \n    @Override\n    public String toString() {\n        return name;\n    }\n    \n    \n    static final class LockClass extends LocksNode {\n        \n        LockClass(String name, LocksNode parent, boolean terminal) {\n            super(name, Icons.getIcon(LanguageIcons.CLASS), parent, terminal ? null : new ArrayList<>());\n        }\n        \n    }\n    \n    static final class LockObject extends LocksNode {\n        \n        private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/lock.png\";  // NOI18N\n        private static final Icon ICON = new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true));\n        \n        LockObject(String name, LocksNode parent, boolean terminal) {\n            super(name, ICON, parent, terminal ? null : new ArrayList<>());\n        }\n        \n    }\n    \n    \n    static final class Thread extends LocksNode {\n        \n        final boolean blocking;\n        \n        Thread(String name, boolean blocking, LocksNode parent, boolean terminal) {\n            super(name, \"<timed out>\".equals(name) ? null : Icons.getIcon(ProfilerIcons.THREAD), parent, terminal ? null : new ArrayList<>());\n            this.blocking = blocking;\n        }\n        \n    }\n    \n    \n    static final class Label extends LocksNode {\n        \n        Label(String label, LocksNode parent) {\n            super(label, null, parent, null);\n        }\n        \n        static Label createNoData(LocksNode parent) {\n            return new Label(\"<no data>\", parent);\n        }\n        \n    }\n    \n    \n    static final class Root extends LocksNode implements JFREventVisitor {\n        \n        private final int mode;\n        private final LocksViewSupport.Aggregation primary;\n        private final LocksViewSupport.Aggregation secondary;\n    \n        \n        Root() {\n            this(0, null, null);\n        }\n        \n        Root(int mode, LocksViewSupport.Aggregation primary, LocksViewSupport.Aggregation secondary) {\n            super(null, null, null, primary == null && secondary == null ? null : new ArrayList<>());\n            \n            this.mode = mode;\n            this.primary = primary;\n            this.secondary = LocksViewSupport.Aggregation.NONE.equals(secondary) ? null : secondary;\n        }\n        \n\n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            Boolean rw;\n            if (mode != 2 && JFRSnapshotLocksViewProvider.EVENT_MONITOR_ENTER.equals(typeName)) rw = Boolean.FALSE; // NOI18N\n            else if (mode != 1 && JFRSnapshotLocksViewProvider.EVENT_MONITOR_WAIT.equals(typeName)) rw = Boolean.TRUE; // NOI18N\n            else rw = null;\n            \n            if (rw != null) {\n                String primaryName = getName(primary, event, rw);\n                if (primaryName == null) primaryName = \"<unknown>\";\n                \n                LocksNode primaryNode = getChild(primaryName);\n                if (primaryNode == null) {\n                    primaryNode = createNode(primaryName, primary, this, secondary == null);\n                    addChild(primaryNode);\n                }\n                \n                if (secondary != null) {\n                    String secondaryName = getName(secondary, event, rw);\n                    if (secondaryName == null) secondaryName = \"<unknown>\";\n                    \n                    LocksNode secondaryNode = primaryNode.getChild(secondaryName);\n                    if (secondaryNode == null) {\n                        secondaryNode = createNode(secondaryName, secondary, primaryNode, true);\n                        primaryNode.addChild(secondaryNode);\n                    }\n                    \n                    try {\n                        secondaryNode.processData(event.getDuration(\"eventDuration\"));\n                    } catch (JFRPropertyNotAvailableException e) {}\n                } else {\n                    try {\n                        primaryNode.processData(event.getDuration(\"eventDuration\"));\n                    } catch (JFRPropertyNotAvailableException e) {}\n                }\n            }\n            \n            return false;\n        }\n        \n        \n        @Override\n        public int hashCode() {\n            return 37;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            return o instanceof Root;\n        }\n        \n        \n        private static String getName(LocksViewSupport.Aggregation aggregation, JFREvent event, boolean eventMode) {\n            try {\n                if (LocksViewSupport.Aggregation.CLASS.equals(aggregation)) return decodeClassName(event.getClass(\"monitorClass\").getName()); // NOI18N\n                if (LocksViewSupport.Aggregation.OBJECT.equals(aggregation)) return decodeClassName(event.getClass(\"monitorClass\").getName()) + \"(0x\" + Long.toHexString(event.getLong(\"address\")) + \")\"; // NOI18N\n                if (LocksViewSupport.Aggregation.THREAD_BLOCKED.equals(aggregation)) return event.getThread(\"eventThread\").getName();\n                if (LocksViewSupport.Aggregation.THREAD_BLOCKING.equals(aggregation)) return getThreadName(event, eventMode);\n            } catch (JFRPropertyNotAvailableException e) {}\n            return null;\n        }\n        \n        private static String getThreadName(JFREvent event, boolean eventMode) throws JFRPropertyNotAvailableException {\n            JFRThread thread = eventMode ? event.getThread(\"notifier\") : event.getThread(\"previousOwner\"); // NOI18N\n            return thread == null ? (eventMode ? \"<timed out>\" : \"<unknown thread>\") : thread.getName(); // NOI18N\n        }\n        \n        private static LocksNode createNode(String name, LocksViewSupport.Aggregation aggregation, LocksNode parent, boolean terminal) {\n            if (LocksViewSupport.Aggregation.CLASS.equals(aggregation)) return new LocksNode.LockClass(name, parent, terminal);\n            if (LocksViewSupport.Aggregation.OBJECT.equals(aggregation)) return new LocksNode.LockObject(name, parent, terminal);\n            if (LocksViewSupport.Aggregation.THREAD_BLOCKED.equals(aggregation)) return new LocksNode.Thread(name, false, parent, terminal);\n            if (LocksViewSupport.Aggregation.THREAD_BLOCKING.equals(aggregation)) return new LocksNode.Thread(name, true, parent, terminal);\n            return null;\n        }\n        \n        \n        private static String decodeClassName(String className) {\n            className = StringUtils.userFormClassName(className);\n            \n            if (className.startsWith(\"L\") && className.contains(\";\")) // NOI18N\n                className = className.substring(1).replace(\";\", \"\"); // NOI18N\n            \n            return className;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/locks/LocksRenderers.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.locks;\n\nimport java.awt.Font;\nimport java.time.Duration;\nimport javax.swing.JLabel;\nimport org.graalvm.visualvm.jfr.utils.ValuesConverter;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.McsTimeRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.MultiRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class LocksRenderers {\n    \n    private static int getMinimumWidth(String valueName) {\n        return new JLabel(valueName).getPreferredSize().width + 30;\n    }\n    \n    \n    static class LocksNameRenderer extends MultiRenderer {\n        \n        private static Font regular;\n        private static Font bold;\n        \n        private final LabelRenderer simpleRenderer;\n        private final JavaNameRenderer javaRenderer;\n        private final LabelRenderer threadRenderer;\n        \n        private final ProfilerRenderer[] renderers;\n        \n        \n        LocksNameRenderer() {\n            simpleRenderer = new LabelRenderer() {\n                @Override\n                public void setValue(Object value, int row) {\n                    LocksNode node = value instanceof LocksNode ? (LocksNode)value : null;\n                    LocksNode parent = node == null ? null : node.getParent();\n                    setVisible(node instanceof LocksNode.Label || parent != null && parent.getParent() != null && node.icon != null);\n                    if (isVisible()) {\n                        if (node instanceof LocksNode.Thread) {\n                            if (parent instanceof LocksNode.Thread) {\n                                if (\"<timed out>\".equals(parent.name)) setText(\"in\");\n                                else setText(((LocksNode.Thread)parent).blocking ? \"blocked\" : \"blocked by\");\n                            } else {\n                                setText(((LocksNode.Thread)node).blocking ? \"held by\" : \"blocked\");\n                            }\n                        } else if (parent instanceof LocksNode.Thread) {\n                            if (\"<timed out>\".equals(parent.name)) setText(\"on\");\n                            else setText(((LocksNode.Thread)parent).blocking ? \"held\" : \"blocked on\");\n                        } else if (node instanceof LocksNode.Label) {\n                            setText(node.name);\n                        }\n                    }\n                }\n            };\n            \n            javaRenderer = new JavaNameRenderer() {\n                @Override\n                public void setValue(Object value, int row) {\n                    setVisible(value instanceof LocksNode.LockClass || value instanceof LocksNode.LockObject);\n                    if (isVisible()) {\n                        LocksNode node = (LocksNode)value;\n                        super.setValue(node.name, row);\n                        setIcon(node.icon);\n                    }\n                }\n            };\n            \n            threadRenderer = new LabelRenderer() {\n                @Override\n                public void setValue(Object value, int row) {\n                    setVisible(value instanceof LocksNode.Thread);\n                    if (isVisible()) {\n                        LocksNode node = (LocksNode)value;\n                        LocksNode parent = node.getParent();\n                        boolean toplevel = parent == null || parent.getParent() == null;\n                        setFont(toplevel ? bold() : regular());\n                        super.setValue(node.name, row);\n                        setIcon(\"<timed out>\".equals(node.name) ? (toplevel ? Icons.getIcon(GeneralIcons.EMPTY) : null) : node.icon);\n                    }\n                }\n            };\n            \n            renderers = new ProfilerRenderer[] { simpleRenderer, javaRenderer, threadRenderer };\n        }\n\n        \n        @Override\n        protected ProfilerRenderer[] valueRenderers() {\n            return renderers;\n        }\n        \n        \n        public void setValue(Object value, int row) {\n            for (ProfilerRenderer renderer : valueRenderers())\n                renderer.setValue(value, row);\n        }\n        \n        \n        static String getDisplayName() {\n            return \"Name\";\n        }\n        \n        \n        private static Font regular() {\n            if (regular == null) regular = new LabelRenderer().getFont();\n            return regular;\n        }\n        \n        private static Font bold() {\n            if (bold == null) bold = new LabelRenderer().getFont().deriveFont(Font.BOLD);\n            return bold;\n        }\n        \n    }\n    \n    \n    static class TotalTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Total Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class MaxTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Max Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class TotalCountRenderer extends NumberRenderer {\n        \n        static String getDisplayName() {\n            return \"Total Count\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    \n    private static class TimeRenderer extends McsTimeRenderer {\n        \n        @Override\n        public void setValue(Object value, int row) {\n            if (value instanceof Duration) {\n                long micros = ValuesConverter.durationToMicros((Duration)value);\n                if (micros == 0) setText(\"< 0.001 ms\"); // NOI18N\n                else super.setValue(micros, row);\n            } else {\n                setText(\"-\"); // NOI18N\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/locks/LocksViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.locks;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.time.Duration;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.JButton;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JSeparator;\nimport javax.swing.JTree;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.tree.TreeNode;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.views.components.MessageComponent;\nimport org.graalvm.visualvm.lib.ui.components.HTMLLabel;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class LocksViewSupport {\n    \n    static enum Aggregation {\n        NONE { @Override public String toString() { return \"None\"; } },\n        CLASS { @Override public String toString() { return \"Monitor Class\"; } },\n        OBJECT { @Override public String toString() { return \"Monitor Object\"; } },\n        THREAD_BLOCKED { @Override public String toString() { return \"Blocked Thread\"; } },\n        THREAD_BLOCKING { @Override public String toString() { return \"Blocking Thread\"; } }\n    }\n\n    static abstract class MasterViewSupport extends JPanel {\n        \n        private int lastMode;\n        private Aggregation lastPrimary, lastSecondary;\n        \n        \n        MasterViewSupport(JFRModel model) {\n            initComponents(model);\n        }\n        \n        \n        DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(\"Locks\", null, this);\n        }\n        \n        \n        abstract void firstShown();\n        \n        abstract void changeAggregation(int mode, Aggregation primary, Aggregation secondary);\n        \n        \n        void showProgress() {\n            updateButton.setEnabled(false);\n            updateButton.setVisible(false);\n            statusValueLabel.setVisible(true);\n        }\n        \n        void hideProgress() {\n            statusValueLabel.setVisible(false);\n            updateButton.setVisible(true);\n        }\n        \n        \n        private void handleAggregationChanged(boolean updateSecondary) {\n            if (updateSecondary) {\n                int sel = secondCombo.getSelectedIndex();\n                \n                DefaultComboBoxModel<Aggregation> model = (DefaultComboBoxModel<Aggregation>)secondCombo.getModel();\n                while (model.getSize() > 1) model.removeElementAt(1);\n                \n                if (!Aggregation.CLASS.equals(firstCombo.getSelectedItem()) &&\n                    !Aggregation.OBJECT.equals(firstCombo.getSelectedItem()))\n                        model.addElement(Aggregation.CLASS);\n                \n                if (!Aggregation.CLASS.equals(firstCombo.getSelectedItem()) &&\n                    !Aggregation.OBJECT.equals(firstCombo.getSelectedItem()))\n                        model.addElement(Aggregation.OBJECT);\n                \n                if (!Aggregation.THREAD_BLOCKED.equals(firstCombo.getSelectedItem()))\n                    model.addElement(Aggregation.THREAD_BLOCKED);\n                \n                if (!Aggregation.THREAD_BLOCKING.equals(firstCombo.getSelectedItem()))\n                    model.addElement(Aggregation.THREAD_BLOCKING);\n                \n                secondCombo.setSelectedIndex(sel < secondCombo.getItemCount() ? sel : 0);\n            }\n            \n            updateButton.setEnabled(lastMode != modeCombo.getSelectedIndex() ||\n                                    lastPrimary != firstCombo.getSelectedItem() ||\n                                    lastSecondary != secondCombo.getSelectedItem());\n            \n        }\n        \n        \n        private int prefHeight = -1;\n        public Dimension getPreferredSize() {\n            if (modeCombo == null) return super.getPreferredSize();\n            Dimension pref = super.getPreferredSize();\n            if (prefHeight == -1) prefHeight = pref.height;\n            else pref.height = prefHeight;\n            return pref;\n        }\n        \n        \n        private void initComponents(JFRModel model) {\n            setOpaque(false);\n            \n            if (model == null) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.notAvailable(), BorderLayout.CENTER);\n            } else if (!model.containsEvent(JFRSnapshotLocksViewProvider.EventChecker.class)) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.noData(\"Locks\", JFRSnapshotLocksViewProvider.EventChecker.checkedTypes()), BorderLayout.CENTER);\n            } else {\n                setLayout(new GridBagLayout());\n                setBorder(BorderFactory.createEmptyBorder(11, 5, 20, 5));\n\n                GridBagConstraints constraints;\n\n                // modeLabel\n                JLabel modeLabel = new JLabel();\n                modeLabel.setText(\"Display:\");\n                modeLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 0;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(modeLabel, constraints);\n\n                // modeCombo\n                modeCombo = new JComboBox<>(new String[] { \"Locks & Object.wait()\", \"Locks\", \"Object.wait()\" });\n                modeCombo.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleAggregationChanged(false); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 1;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(modeCombo, constraints);\n\n                // modeSeparator\n                JSeparator modeSeparator = new JSeparator(JSeparator.VERTICAL);\n                modeSeparator.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 2;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 16, 0, 0);\n                add(modeSeparator, constraints);\n\n                // firstLabel\n                firstLabel = new JLabel();\n                firstLabel.setText(\"Aggregation:\");\n                firstLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 3;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(firstLabel, constraints);\n\n                // firstCombo\n                firstCombo = new JComboBox<>(new Aggregation[] { Aggregation.CLASS, Aggregation.OBJECT, Aggregation.THREAD_BLOCKED, Aggregation.THREAD_BLOCKING });\n                firstCombo.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleAggregationChanged(true); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 4;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(firstCombo, constraints);\n\n                // modeLabel\n                secondLabel = new JLabel();\n                secondLabel.setText(\"secondary:\");\n                secondLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 5;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 12, 0, 0);\n                add(secondLabel, constraints);\n\n                // memoryButton\n                secondCombo = new JComboBox<>(new Aggregation[] { Aggregation.NONE, Aggregation.THREAD_BLOCKED, Aggregation.THREAD_BLOCKING });\n                secondCombo.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleAggregationChanged(false); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 6;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(secondCombo, constraints);\n                \n                lastMode = modeCombo.getSelectedIndex();\n                lastPrimary = (Aggregation)firstCombo.getSelectedItem();\n                lastSecondary = (Aggregation)secondCombo.getSelectedItem();\n\n                // updateSeparator\n                JSeparator updateSeparator = new JSeparator(JSeparator.VERTICAL);\n                updateSeparator.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 7;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 16, 0, 0);\n                add(updateSeparator, constraints);\n\n                // updateButton\n                updateButton = new JButton(\"Update Data\");\n                updateButton.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        updateButton.setEnabled(false);\n                        lastMode = modeCombo.getSelectedIndex();\n                        lastPrimary = (Aggregation)firstCombo.getSelectedItem();\n                        lastSecondary = (Aggregation)secondCombo.getSelectedItem();\n                        changeAggregation(lastMode, lastPrimary, lastSecondary);\n                    }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 8;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 12, 0, 0);\n                add(updateButton, constraints);\n\n                // statusValueLabel\n                statusValueLabel = new HTMLLabel(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n                constraints = new GridBagConstraints();\n                constraints.gridx = 9;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 20, 0, 0);\n                add(statusValueLabel, constraints);\n                statusValueLabel.setVisible(false);\n\n                // filler1\n                constraints = new GridBagConstraints();\n                constraints.gridx = 10;\n                constraints.gridy = 2;\n                constraints.weightx = 1;\n                constraints.weighty = 1;\n                constraints.gridwidth = GridBagConstraints.REMAINDER;\n                constraints.fill = GridBagConstraints.BOTH;\n                constraints.anchor = GridBagConstraints.NORTHWEST;\n                constraints.insets = new Insets(0, 0, 0, 0);\n                add(Spacer.create(), constraints);\n\n                Dimension cpuD     = firstCombo.getPreferredSize();\n                Dimension memoryD  = secondCombo.getPreferredSize();\n                Dimension stopD    = modeCombo.getPreferredSize();\n\n                Dimension maxD = new Dimension(Math.max(cpuD.width, memoryD.width), Math.max(cpuD.height, memoryD.height));\n                maxD = new Dimension(Math.max(maxD.width, 0), Math.max(maxD.height, stopD.height));\n\n                firstCombo.setPreferredSize(maxD);\n                firstCombo.setMinimumSize(maxD);\n                secondCombo.setPreferredSize(maxD);\n                secondCombo.setMinimumSize(maxD);\n\n                stopD.height = maxD.height;\n                modeCombo.setPreferredSize(stopD);\n                modeCombo.setMinimumSize(stopD);\n\n                Dimension sepD = modeSeparator.getPreferredSize();\n                sepD.height = maxD.height - 2;\n                sepD.width = 5;\n                modeSeparator.setPreferredSize(sepD);\n                modeSeparator.setMinimumSize(sepD);\n\n                Dimension sepD2 = updateSeparator.getPreferredSize();\n                sepD2.height = maxD.height - 2;\n                sepD2.width = 5;\n                updateSeparator.setPreferredSize(sepD2);\n                updateSeparator.setMinimumSize(sepD2);\n\n                addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                            if (isShowing()) {\n                                removeHierarchyListener(this);\n                                SwingUtilities.invokeLater(MasterViewSupport.this::firstShown);\n                            }\n                        }\n                    }\n                });\n            }\n        }\n\n        private JLabel firstLabel;\n        private JLabel secondLabel;\n        private JComboBox<String> modeCombo;\n        private JComboBox<Aggregation> firstCombo;\n        private JComboBox<Aggregation> secondCombo;\n        private JButton updateButton;\n        private HTMLLabel statusValueLabel;\n        \n    }\n    \n    \n    static final class DataViewSupport extends JPanel {\n        \n        private DataModel tableModel;\n        private ProfilerTreeTable table;\n        \n        \n        DataViewSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Data\", null, 10, this, null); // NOI18N\n        }\n        \n        \n        void setData(LocksNode root, boolean twoAggregations) {\n            tableModel.setRoot(root);\n            table.setShowsRootHandles(twoAggregations);\n        }\n        \n        \n        private void initComponents() {\n            tableModel = new DataModel();\n            table = new ProfilerTreeTable(tableModel, true, true, new int[] { 0 });\n            \n            table.setRootVisible(false);\n            table.setShowsRootHandles(true);\n\n            table.setMainColumn(0);\n            table.setFitWidthColumn(0);\n\n            table.setSortColumn(1);\n            table.setDefaultSortOrder(SortOrder.DESCENDING);\n            table.setDefaultSortOrder(0, SortOrder.ASCENDING);\n            \n            LocksRenderers.LocksNameRenderer nameRenderer = new LocksRenderers.LocksNameRenderer();\n            table.setTreeCellRenderer(nameRenderer);\n            \n            LocksRenderers.TotalTimeRenderer totalTimeRenderer = new LocksRenderers.TotalTimeRenderer();\n            table.setColumnRenderer(1, totalTimeRenderer);\n            table.setDefaultColumnWidth(1, totalTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(1, LocksRenderers.TotalTimeRenderer.isInitiallyVisible());\n            \n            LocksRenderers.MaxTimeRenderer maxReadTimeRenderer = new LocksRenderers.MaxTimeRenderer();\n            table.setColumnRenderer(2, maxReadTimeRenderer);\n            table.setDefaultColumnWidth(2, maxReadTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(2, LocksRenderers.MaxTimeRenderer.isInitiallyVisible());\n            \n            LocksRenderers.TotalCountRenderer totalCountRenderer = new LocksRenderers.TotalCountRenderer();\n            table.setColumnRenderer(3, totalCountRenderer);\n            table.setDefaultColumnWidth(3, totalCountRenderer.getPreferredWidth());\n            table.setColumnVisibility(3, LocksRenderers.TotalCountRenderer.isInitiallyVisible());\n            \n            setLayout(new BorderLayout());\n            add(new ProfilerTableContainer(table, false, null), BorderLayout.CENTER);\n        }\n        \n        \n        private static class DataModel extends ProfilerTreeTableModel.Abstract {\n            \n            DataModel() {\n                super(new LocksNode.Root());\n            }\n            \n            \n            @Override\n            public int getColumnCount() {\n                return 4;\n            }\n\n            @Override\n            public Class<?> getColumnClass(int column) {\n                switch (column) {\n                    case 0: return JTree.class;\n                    case 1: return Duration.class;\n                    case 2: return Duration.class;\n                    case 3: return Long.class;\n                    default: return null;\n                }\n            }\n\n            @Override\n            public String getColumnName(int column) {\n                switch (column) {\n                    case 0: return LocksRenderers.LocksNameRenderer.getDisplayName();\n                    case 1: return LocksRenderers.TotalTimeRenderer.getDisplayName();\n                    case 2: return LocksRenderers.MaxTimeRenderer.getDisplayName();\n                    case 3: return LocksRenderers.TotalCountRenderer.getDisplayName();\n                    default: return null;\n                }\n            }\n\n            @Override\n            public Object getValueAt(TreeNode node, int column) {\n                if (node == null) return null;\n                LocksNode fnode = (LocksNode)node;\n                \n                switch (column) {\n                    case 0: return fnode;\n                    case 1: return fnode.duration;\n                    case 2: return fnode.durationMax;\n                    case 3: return toLong(fnode.count);\n                    default: return null;\n                }\n            }\n            \n            @Override\n            public void setValueAt(Object o, TreeNode node, int column) {}\n\n            @Override\n            public boolean isCellEditable(TreeNode node, int column) { return false; }\n            \n            \n            private Long toLong(long value) {\n                return value == 0 ? null : Long.valueOf(value);\n            }\n            \n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/monitor/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n# HTML-formatted: <unknown> (&lt; and &gt; must remain!)\nLBL_Unknown=&lt;unknown&gt;\n\nLBL_Monitor=Monitor\n\nLBL_Cpu=CPU\n\nLBL_Cpu_Usage=CPU usage\n\nLBL_Gc_Usage=GC activity\n\nLBL_Memory=Memory\n\nLBL_Heap=Heap\n\nLBL_PermGen=PermGen\n\nLBL_Classes=Classes\n\nLBL_Threads=Threads\n\nLBL_Perform_GC=Perform GC\n\nTXT_Perform_GC_failed=Perform GC action failed.\\n{0}\n\nLBL_Heap_Dump=Heap Dump\n\n# HTML-formatted: Uptime: 11:20 AM\nLBL_Uptime=<nobr><b>Uptime:</b> {0}</nobr>\n\nLBL_Heap_size=Size\n\nLBL_Used_heap=Used\n\nLBL_Heap_size_leg={0} size\n\nLBL_Used_heap_leg=Used {0}\n\nLBL_Max_Heap=Max\n\nLBL_PermGen_size=Size\n\nLBL_Used_PermGen=Used\n\nLBL_PermGen_size_leg={0} size\n\nLBL_Used_PermGen_leg=Used {0}\n\nLBL_Max_PermGen_size=Max\n\nLBL_Total_loaded_classes=Total loaded\n\nLBL_Shared_loaded_classes=Shared loaded\n\nLBL_Total_unloaded_classes=Total unloaded\n\nLBL_Shared_unloaded_classes=Shared unloaded\n\nLBL_Total_loaded_classes_leg=Total loaded classes\n\nLBL_Shared_loaded_classes_leg=Shared loaded classes\n\nLBL_Live_threads=Live\n\nLBL_Daemon_threads=Daemon\n\nLBL_Live_threads_peak=Live peak\n\nLBL_Started_threads_total=Total started\n\nLBL_Live_threads_leg=Live threads\n\nLBL_Daemon_threads_leg=Daemon threads\n\nFORMAT_hms={0} hrs {1} min {2} sec\nFORMAT_ms={0} min {1} sec\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/monitor/JFRSnapshotMonitorView.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.monitor;\n\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JFRSnapshotMonitorView extends JFRViewTab {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/monitor.png\";  // NOI18N\n    \n    JFRSnapshotMonitorView(JFRSnapshot snapshot) {\n        super(snapshot, NbBundle.getMessage(JFRSnapshotMonitorView.class, \"LBL_Monitor\"), new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 10);\n    }\n        \n        \n    @Override\n    protected DataViewComponent createComponent() {\n        JFRModel model = getModel();\n\n        boolean hasEvents = model != null && model.containsEvent(JFRSnapshotMonitorViewProvider.EventChecker.class);\n        boolean hasPermGen = hasEvents && model.containsEvent(JFRSnapshotMonitorViewProvider.PermGenChecker.class);\n        boolean hasMetaSpace = hasEvents && model.containsEvent(JFRSnapshotMonitorViewProvider.MetaspaceChecker.class);\n        \n        final MonitorViewSupport.CPUViewSupport cpuView = hasEvents ? new MonitorViewSupport.CPUViewSupport(model) : null;\n        final MonitorViewSupport.HeapViewSupport heapView = hasEvents ? new MonitorViewSupport.HeapViewSupport(model) : null;\n        final MonitorViewSupport.PermGenViewSupport permgenView = hasPermGen ? new MonitorViewSupport.PermGenViewSupport(model) : null;\n        final MonitorViewSupport.MetaspaceViewSupport metaspaceView = hasMetaSpace ? new MonitorViewSupport.MetaspaceViewSupport(model) : null;\n        final MonitorViewSupport.ClassesViewSupport classesView = hasEvents ? new MonitorViewSupport.ClassesViewSupport(model) : null;\n        final MonitorViewSupport.ThreadsViewSupport threadsView = hasEvents ? new MonitorViewSupport.ThreadsViewSupport(model) : null;\n        \n        MonitorViewSupport.MasterViewSupport masterView = new MonitorViewSupport.MasterViewSupport(model) {\n            @Override\n            void firstShown() { initialize(this, cpuView, heapView, permgenView, metaspaceView, classesView, threadsView); }\n        };\n        \n        \n        \n        DataViewComponent dvc = new DataViewComponent(\n                masterView.getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(!hasEvents));\n        \n        if (hasEvents) {\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.\n                    getMessage(JFRSnapshotMonitorView.class, \"LBL_Cpu\"), true), DataViewComponent.TOP_LEFT);  // NOI18N\n            dvc.addDetailsView(cpuView.getDetailsView(), DataViewComponent.TOP_LEFT);\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.\n                    getMessage(JFRSnapshotMonitorView.class, \"LBL_Memory\"), true), DataViewComponent.TOP_RIGHT);  // NOI18N\n            dvc.addDetailsView(heapView.getDetailsView(), DataViewComponent.TOP_RIGHT);\n            if (metaspaceView != null) dvc.addDetailsView(metaspaceView.getDetailsView(), DataViewComponent.TOP_RIGHT);\n            else if (permgenView != null) dvc.addDetailsView(permgenView.getDetailsView(), DataViewComponent.TOP_RIGHT);\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.\n                    getMessage(JFRSnapshotMonitorView.class, \"LBL_Classes\"), true), DataViewComponent.BOTTOM_LEFT);    // NOI18N\n            dvc.addDetailsView(classesView.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.\n                    getMessage(JFRSnapshotMonitorView.class, \"LBL_Threads\"), true), DataViewComponent.BOTTOM_RIGHT);   // NOI18N\n            dvc.addDetailsView(threadsView.getDetailsView(), DataViewComponent.BOTTOM_RIGHT);\n        }\n        \n        return dvc;\n    }\n    \n    \n    private void initialize(final MonitorViewSupport.MasterViewSupport masterView,\n                            final MonitorViewSupport.CPUViewSupport cpuView,\n                            final MonitorViewSupport.HeapViewSupport heapView,\n                            final MonitorViewSupport.PermGenViewSupport permgenView,\n                            final MonitorViewSupport.MetaspaceViewSupport metaspaceView,\n                            final MonitorViewSupport.ClassesViewSupport classesView,\n                            final MonitorViewSupport.ThreadsViewSupport threadsView) {\n        final JFREventVisitor doneHandler = new JFREventVisitor() {\n            @Override\n            public boolean visit(String typeName, JFREvent event) { return true; }\n            @Override\n            public void done() { masterView.dataComputed(); }\n        };\n        new RequestProcessor(\"JFR Monitor Initializer\").post(new Runnable() { // NOI18N\n            public void run() {\n                if (permgenView == null && metaspaceView == null) {\n                    getModel().visitEvents(cpuView, heapView, classesView, threadsView, doneHandler);\n                } else {\n                    getModel().visitEvents(cpuView, heapView, metaspaceView != null ? metaspaceView : permgenView, classesView, threadsView, doneHandler);\n                }\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/monitor/JFRSnapshotMonitorViewProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.monitor;\n\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREventChecker;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.jfr.view.JFRViewTabProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=JFRViewTabProvider.class)\npublic class JFRSnapshotMonitorViewProvider extends JFRViewTabProvider {\n    \n    static final String EVENT_CPU_LOAD = \"jdk.CPULoad\"; // NOI18N\n    static final String EVENT_HEAP_SUMMARY = \"jdk.GCHeapSummary\"; // NOI18N\n    static final String EVENT_PERMGEN_SUMMARY = \"http://www.oracle.com/hotspot/jvm/vm/gc/heap/perm_gen_summary\"; // NOI18N\n    static final String EVENT_METASPACE_SUMMARY = \"jdk.MetaspaceSummary\"; // NOI18N\n    static final String EVENT_CLASS_LOADING = \"jdk.ClassLoadingStatistics\"; // NOI18N\n    static final String EVENT_JAVA_THREAD = \"jdk.JavaThreadStatistics\"; // NOI18N\n    \n    \n    @Override\n    protected JFRViewTab createView(JFRSnapshot jfrSnapshot) {\n        return new JFRSnapshotMonitorView(jfrSnapshot);\n    }\n    \n    \n    @ServiceProvider(service=JFREventChecker.class)\n    public static final class PermGenChecker extends JFREventChecker {\n        \n        public PermGenChecker() {\n            super(checkedTypes());\n        }\n        \n        static String[] checkedTypes() {\n            return new String[] {\n                EVENT_PERMGEN_SUMMARY\n            };\n        }\n        \n    }\n    \n    @ServiceProvider(service=JFREventChecker.class)\n    public static final class MetaspaceChecker extends JFREventChecker {\n        \n        public MetaspaceChecker() {\n            super(checkedTypes());\n        }\n        \n        static String[] checkedTypes() {\n            return new String[] {\n                EVENT_METASPACE_SUMMARY\n            };\n        }\n        \n    }\n    \n    @ServiceProvider(service=JFREventChecker.class)\n    public static final class EventChecker extends JFREventChecker {\n        \n        public EventChecker() {\n            super(checkedTypes());\n        }\n        \n        static String[] checkedTypes() {\n            return new String[] {\n                EVENT_CPU_LOAD, EVENT_HEAP_SUMMARY, EVENT_PERMGEN_SUMMARY, EVENT_METASPACE_SUMMARY, EVENT_CLASS_LOADING, EVENT_JAVA_THREAD\n            };\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/monitor/MonitorViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.monitor;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.text.DecimalFormat;\nimport java.time.Duration;\nimport java.time.Instant;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.charts.ChartFactory;\nimport org.graalvm.visualvm.charts.SimpleXYChartDescriptor;\nimport org.graalvm.visualvm.charts.SimpleXYChartSupport;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.NotSupportedDisplayer;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.jfr.utils.TimeRecord;\nimport org.graalvm.visualvm.jfr.utils.ValuesConverter;\nimport org.graalvm.visualvm.jfr.views.components.MessageComponent;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass MonitorViewSupport {\n    \n    private static final String UNKNOWN = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Unknown\"); // NOI18N\n    \n    \n    static abstract class MasterViewSupport extends JPanel {\n        \n        private final JFRModel model;\n        \n        private HTMLTextArea area;\n        \n        \n        MasterViewSupport(JFRModel model) {\n            this.model = model;\n            initComponents();\n        }\n        \n        \n        abstract void firstShown();\n        \n        \n        DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Monitor\"), null, this);\n        }\n        \n        void dataComputed() {\n            final String telemetry = getBasicTelemetry(model);\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { area.setText(telemetry); }\n            });\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            if (model == null) {\n                add(MessageComponent.notAvailable(), BorderLayout.CENTER);\n            } else if (!model.containsEvent(JFRSnapshotMonitorViewProvider.EventChecker.class)) {\n                // Remove the Java 7 only event from the list of required events (http://www.oracle.com/hotspot/jvm/vm/gc/heap/perm_gen_summary)\n                List<String> eventTypes = new ArrayList<>();\n                eventTypes.addAll(Arrays.asList(JFRSnapshotMonitorViewProvider.EventChecker.checkedTypes()));\n                eventTypes.remove(JFRSnapshotMonitorViewProvider.EVENT_PERMGEN_SUMMARY);\n                \n                add(MessageComponent.noData(NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Monitor\"), eventTypes.toArray(new String[0])), BorderLayout.CENTER);\n            } else {\n                area = new HTMLTextArea(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n                area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n                add(area, BorderLayout.CENTER);\n\n                addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                            if (isShowing()) {\n                                removeHierarchyListener(this);\n                                SwingUtilities.invokeLater(MasterViewSupport.this::firstShown);\n                            }\n                        }\n                    }\n                });\n            }\n        }\n        \n        private String getBasicTelemetry(JFRModel model) {\n            Instant startTime = model.getJvmStartTime();\n            Instant endTime = model.getJvmShutdownTime();\n            boolean terminated = endTime != null;\n            if (!terminated) endTime = model.getLastEventTime();\n            \n            String ret = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Uptime\", (startTime == null ? \"&lt;unknown&gt;\" : getTime(startTime, endTime))); // NOI18N\n            if (terminated) {\n                String reason = model.getJvmShutdownReason();\n                ret += \"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Terminated:</b> \" + (reason != null ? reason : \"&lt;unknown reason&gt;\");\n            }\n            return ret;\n        }\n        \n        private static String getTime(Instant startTime, Instant endTime) {\n            long millis = ValuesConverter.durationToMillis(Duration.between(startTime, endTime));\n            \n            // Hours\n            long hours = millis / 3600000;\n            String sHours = hours == 0 ? null : new DecimalFormat(\"#0\").format(hours); // NOI18N\n            millis %= 3600000;\n            \n            // Minutes\n            long minutes = millis / 60000;\n            String sMinutes = new DecimalFormat(hours > 0 ? \"00\" : \"#0\").format(minutes); // NOI18N\n            millis %= 60000;\n            \n            // Seconds\n            String sSeconds = new DecimalFormat(\"#0.000\").format(millis / 1000d); // NOI18N\n            \n            if (sHours == null) {\n                 return NbBundle.getMessage(MonitorViewSupport.class, \"FORMAT_ms\", // NOI18N\n                                            new Object[] { sMinutes, sSeconds });\n            } else {\n                return NbBundle.getMessage(MonitorViewSupport.class, \"FORMAT_hms\", // NOI18N\n                                            new Object[] { sHours, sMinutes, sSeconds });\n            }\n        }\n        \n    }\n    \n    \n    static class CPUViewSupport extends JPanel implements JFREventVisitor {\n        \n        private static final String CPU = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Cpu\"); // NOI18N\n        private static final String CPU_USAGE = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Cpu_Usage\"); // NOI18N\n//        private static final String GC_USAGE = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Gc_Usage\"); // NOI18N\n        \n        private final JFRModel jfrModel;\n\n        private final boolean liveModel = false;\n//        private int processorsCount;\n        private boolean cpuMonitoringSupported;\n        private boolean gcMonitoringSupported;\n\n        private SimpleXYChartSupport chartSupport;\n        \n        \n        CPUViewSupport(JFRModel jfrModel) {\n            this.jfrModel = jfrModel;\n            \n            initModels();\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(CPU, null, 10, this, null);\n        }\n        \n        \n        // --- Visitor ---\n        \n        private static final class CPU extends TimeRecord {\n            final long value;\n            CPU(JFREvent event, JFRModel jfrModel) throws JFRPropertyNotAvailableException {\n                super(event, jfrModel);\n                value = Math.round(event.getFloat(\"jvmUser\") * 1000) + Math.round(event.getFloat(\"jvmSystem\") * 1000); // TODO: ??? // NOI18N\n            }\n        }\n        \n        private List<CPU> records;\n        \n        @Override\n        public void init() {\n            records = new ArrayList<>();\n        }\n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {            \n            if (JFRSnapshotMonitorViewProvider.EVENT_CPU_LOAD.equals(typeName)) {\n                try {\n                    records.add(new CPU(event, jfrModel));\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            records.sort(TimeRecord.COMPARATOR);\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    long lastTime = Long.MIN_VALUE + 1;\n                    for (final CPU record : records) {\n                        long time = jfrModel.nsToAbsoluteMillis(record.time);\n                        if (time <= lastTime) time = lastTime + 1;\n                        chartSupport.addValues(time, new long[] { record.value/*, 0*/ });\n                        lastTime = time;\n                    }\n\n                    if (!records.isEmpty()) {\n                        CPU last = records.get(records.size() - 1);\n                        records.clear();\n                        \n                        String cpuDetail = chartSupport.formatPercent(last.value);\n                        chartSupport.updateDetails(new String[] { cpuDetail/*, UNKNOWN*/ });\n                    }\n                    \n                    records = null;\n                }\n            });\n        }\n        \n        // ---\n\n        private void initModels() {\n            cpuMonitoringSupported = true;\n            gcMonitoringSupported = false;\n\n            if (cpuMonitoringSupported || gcMonitoringSupported) {\n                SimpleXYChartDescriptor chartDescriptor =\n                        SimpleXYChartDescriptor.percent(false, 0.1d, Integer.MAX_VALUE);\n\n                chartDescriptor.addLineItems(CPU_USAGE/*, GC_USAGE*/);\n                chartDescriptor.setDetailsItems(new String[] { CPU_USAGE/*, GC_USAGE*/ });\n\n                chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n\n                chartSupport.setZoomingEnabled(!liveModel);\n            }\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (cpuMonitoringSupported || gcMonitoringSupported) {\n                add(chartSupport.getChart(), BorderLayout.CENTER);\n                chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN });\n            } else {\n                add(new NotSupportedDisplayer(\"JFR snapshot\"), BorderLayout.CENTER);\n            }\n        }\n        \n    }\n    \n    \n    static class HeapViewSupport extends JPanel implements JFREventVisitor {\n        \n        private final JFRModel jfrModel;\n        \n        private final boolean liveModel = false;\n        private boolean memoryMonitoringSupported;\n        private final String heapName = \"Heap\";\n\n        private SimpleXYChartSupport chartSupport;\n\n        HeapViewSupport(JFRModel jfrModel) {\n            this.jfrModel = jfrModel;\n            initModels();\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(heapName, null, 10, this, null);\n        }\n        \n        \n        // --- Visitor ---\n        \n        private static final class Heap extends TimeRecord {\n            final long used;\n            final long commited;\n            Heap(JFREvent event, JFRModel jfrModel) throws JFRPropertyNotAvailableException {\n                super(event, jfrModel);\n                used = event.getLong(\"heapUsed\"); // NOI18N\n                commited = event.getLong(\"heapSpace.committedSize\"); // NOI18N\n            }\n        }\n        \n        private List<Heap> records;\n        private JFREvent lastEvent;\n        private long lastEventTime = Long.MIN_VALUE;\n        \n        @Override\n        public void init() {\n            records = new ArrayList<>();\n        }\n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {            \n            if (JFRSnapshotMonitorViewProvider.EVENT_HEAP_SUMMARY.equals(typeName))\n                try {\n                    Heap record = new Heap(event, jfrModel);\n                    records.add(record);\n                    \n                    if (lastEventTime < record.time) {\n                        lastEvent = event;\n                        lastEventTime = record.time;\n                    }\n                } catch (JFRPropertyNotAvailableException e) {}\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            records.sort(TimeRecord.COMPARATOR);\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    long lastTime = Long.MIN_VALUE + 1;\n                    for (final Heap record : records) {\n                        long time = jfrModel.nsToAbsoluteMillis(record.time);\n                        if (time <= lastTime) time = lastTime + 1;\n                        chartSupport.addValues(time, new long[] { record.commited, record.used });\n                        lastTime = time;\n                    }\n\n                    if (!records.isEmpty()) {\n                        records.clear();\n                        \n                        try {\n                            long heapUsed = lastEvent.getLong(\"heapUsed\"); // NOI18N\n                            long heapSpace_committedSize = lastEvent.getLong(\"heapSpace.committedSize\"); // NOI18N\n                            long heapSpace_reservedSize = lastEvent.getLong(\"heapSpace.reservedSize\"); // NOI18N\n                            chartSupport.updateDetails(new String[] { chartSupport.formatBytes(heapUsed),\n                                                                      chartSupport.formatBytes(heapSpace_committedSize),\n                                                                      chartSupport.formatBytes(heapSpace_reservedSize) });\n                        } catch (JFRPropertyNotAvailableException e) {}\n                    }\n                    \n                    records = null;\n                    lastEvent = null;\n                }\n            });\n        }\n\n        private void initModels() {\n//            liveModel = model.isLive();\n            memoryMonitoringSupported = true;\n//            heapName = memoryMonitoringSupported ? model.getHeapName() : NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Memory\"); // NOI18N\n\n            if (memoryMonitoringSupported) {\n                String HEAP_SIZE = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Heap_size\"); // NOI18N\n                String HEAP_SIZE_LEG = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Heap_size_leg\",heapName); // NOI18N\n                String USED_HEAP = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Used_heap\"); // NOI18N\n                String USED_HEAP_LEG = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Used_heap_leg\",heapName.toLowerCase()); // NOI18N\n                String MAX_HEAP = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Max_Heap\");   // NOI18N\n\n                SimpleXYChartDescriptor chartDescriptor =\n                        SimpleXYChartDescriptor.bytes(10 * 1024 * 1024, false, Integer.MAX_VALUE);\n\n                chartDescriptor.addLineFillItems(HEAP_SIZE_LEG, USED_HEAP_LEG);\n                chartDescriptor.setDetailsItems(new String[] { HEAP_SIZE, USED_HEAP, MAX_HEAP });\n\n                chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n//                model.registerHeapChartSupport(chartSupport);\n\n                chartSupport.setZoomingEnabled(!liveModel);\n            }\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (memoryMonitoringSupported) {\n                add(chartSupport.getChart(), BorderLayout.CENTER);\n                chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN, UNKNOWN });\n            } else {\n                add(new NotSupportedDisplayer(\"JFR snapshot\"), BorderLayout.CENTER);\n            }\n        }\n\n    }\n    \n    \n    static class PermGenViewSupport extends JPanel implements JFREventVisitor {\n        \n        private final JFRModel jfrModel;\n        \n        private final boolean liveModel = false;\n        private boolean memoryMonitoringSupported;\n        private final String heapName = \"PermGen\";\n\n        private SimpleXYChartSupport chartSupport;\n\n        PermGenViewSupport(JFRModel jfrModel) {\n            this.jfrModel = jfrModel;\n            initModels();\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(heapName, null, 20, this, null);\n        }\n        \n        \n        // --- Visitor ---\n        \n        private static final class PermGen extends TimeRecord {\n            final long used;\n            final long commited;\n            PermGen(JFREvent event, JFRModel jfrModel) throws JFRPropertyNotAvailableException {\n                super(event, jfrModel);\n                used = event.getLong(\"objectSpace.used\"); // NOI18N\n                commited = event.getLong(\"permSpace.committedSize\"); // NOI18N\n            }\n        }\n        \n        private List<PermGen> records;\n        private JFREvent lastEvent;\n        private long lastEventTime = Long.MIN_VALUE;\n        \n        @Override\n        public void init() {\n            records = new ArrayList<>();\n        }\n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {            \n            if (JFRSnapshotMonitorViewProvider.EVENT_PERMGEN_SUMMARY.equals(typeName)) {\n                try {\n                    PermGen record = new PermGen(event, jfrModel);\n                    records.add(record);\n                    \n                    if (lastEventTime < record.time) {\n                        lastEvent = event;\n                        lastEventTime = record.time;\n                    }\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            records.sort(TimeRecord.COMPARATOR);\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    long lastTime = Long.MIN_VALUE + 1;\n                    for (final PermGen record : records) {\n                        long time = jfrModel.nsToAbsoluteMillis(record.time);\n                        if (time <= lastTime) time = lastTime + 1;\n                        chartSupport.addValues(time, new long[] { record.commited, record.used });\n                        lastTime = time;\n                    }\n\n                    if (!records.isEmpty()) {\n                        records.clear();\n                        \n                        try {\n                            long permspace_used = lastEvent.getLong(\"objectSpace.used\"); // NOI18N\n                            long permspace_committed = lastEvent.getLong(\"permSpace.committedSize\"); // NOI18N\n                            long permspace_reserved = lastEvent.getLong(\"permSpace.reservedSize\"); // NOI18N\n                            chartSupport.updateDetails(new String[] { chartSupport.formatBytes(permspace_used),\n                                                                      chartSupport.formatBytes(permspace_committed),\n                                                                      chartSupport.formatBytes(permspace_reserved) });\n                        } catch (JFRPropertyNotAvailableException e) {}\n                    }\n                    \n                    records = null;\n                    lastEvent = null;\n                }\n            });\n        }\n\n        private void initModels() {\n//            liveModel = model.isLive();\n            memoryMonitoringSupported = true;\n//            heapName = memoryMonitoringSupported ? model.getHeapName() : NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Memory\"); // NOI18N\n\n            if (memoryMonitoringSupported) {\n                String HEAP_SIZE = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Heap_size\"); // NOI18N\n                String HEAP_SIZE_LEG = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Heap_size_leg\",heapName); // NOI18N\n                String USED_HEAP = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Used_heap\"); // NOI18N\n                String USED_HEAP_LEG = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Used_heap_leg\",heapName.toLowerCase()); // NOI18N\n                String MAX_HEAP = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Max_Heap\");   // NOI18N\n\n                SimpleXYChartDescriptor chartDescriptor =\n                        SimpleXYChartDescriptor.bytes(10 * 1024 * 1024, false, Integer.MAX_VALUE);\n\n                chartDescriptor.addLineFillItems(HEAP_SIZE_LEG, USED_HEAP_LEG);\n                chartDescriptor.setDetailsItems(new String[] { HEAP_SIZE, USED_HEAP, MAX_HEAP });\n\n                chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n//                model.registerHeapChartSupport(chartSupport);\n\n                chartSupport.setZoomingEnabled(!liveModel);\n            }\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (memoryMonitoringSupported) {\n                add(chartSupport.getChart(), BorderLayout.CENTER);\n                chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN, UNKNOWN });\n            } else {\n                add(new NotSupportedDisplayer(\"JFR snapshot\"), BorderLayout.CENTER);\n            }\n        }\n\n    }\n    \n    \n    static class MetaspaceViewSupport extends JPanel implements JFREventVisitor {\n        \n        private final JFRModel jfrModel;\n        \n        private final boolean liveModel = false;\n        private boolean memoryMonitoringSupported;\n        private final String heapName = \"Metaspace\";\n\n        private SimpleXYChartSupport chartSupport;\n\n        MetaspaceViewSupport(JFRModel jfrModel) {\n            this.jfrModel = jfrModel;\n            initModels();\n            initComponents();\n        }\n\n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(heapName, null, 20, this, null);\n        }\n        \n        \n        // --- Visitor ---\n        \n        private static final class Metaspace extends TimeRecord {\n            final long used;\n            final long commited;\n            Metaspace(JFREvent event, JFRModel jfrModel) throws JFRPropertyNotAvailableException {\n                super(event, jfrModel);\n                used = event.getLong(\"metaspace.used\"); // NOI18N\n                commited = event.getLong(\"metaspace.committed\"); // NOI18N\n            }\n        }\n        \n        private List<Metaspace> records;\n        private JFREvent lastEvent;\n        private long lastEventTime = Long.MIN_VALUE;\n        \n        @Override\n        public void init() {\n            records = new ArrayList<>();\n        }\n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {            \n            if (JFRSnapshotMonitorViewProvider.EVENT_METASPACE_SUMMARY.equals(typeName)) {\n                try {\n                    Metaspace record = new Metaspace(event, jfrModel);\n                    records.add(record);\n                    \n                    if (lastEventTime < record.time) {\n                        lastEvent = event;\n                        lastEventTime = record.time;\n                    }\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            records.sort(TimeRecord.COMPARATOR);\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    long lastTime = Long.MIN_VALUE + 1;\n                    for (final Metaspace record : records) {\n                        long time = jfrModel.nsToAbsoluteMillis(record.time);\n                        if (time <= lastTime) time = lastTime + 1;\n                        chartSupport.addValues(time, new long[] { record.commited, record.used });\n                        lastTime = time;\n                    }\n\n                    if (!records.isEmpty()) {\n                        records.clear();\n                        \n                        try {\n                            long metaspace_used = lastEvent.getLong(\"metaspace.used\"); // NOI18N\n                            long metaspace_committed = lastEvent.getLong(\"metaspace.committed\"); // NOI18N\n                            long metaspace_reserved = lastEvent.getLong(\"metaspace.reserved\"); // NOI18N\n                            chartSupport.updateDetails(new String[] { chartSupport.formatBytes(metaspace_used),\n                                                                      chartSupport.formatBytes(metaspace_committed),\n                                                                      chartSupport.formatBytes(metaspace_reserved) });\n                        } catch (JFRPropertyNotAvailableException e) {}\n                    }\n                    \n                    records = null;\n                    lastEvent = null;\n                }\n            });\n        }\n\n        private void initModels() {\n//            liveModel = model.isLive();\n            memoryMonitoringSupported = true;\n//            heapName = memoryMonitoringSupported ? model.getHeapName() : NbBundle.getMessage(ApplicationMonitorView.class, \"LBL_Memory\"); // NOI18N\n\n            if (memoryMonitoringSupported) {\n                String HEAP_SIZE = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Heap_size\"); // NOI18N\n                String HEAP_SIZE_LEG = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Heap_size_leg\",heapName); // NOI18N\n                String USED_HEAP = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Used_heap\"); // NOI18N\n                String USED_HEAP_LEG = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Used_heap_leg\",heapName.toLowerCase()); // NOI18N\n                String MAX_HEAP = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Max_Heap\");   // NOI18N\n\n                SimpleXYChartDescriptor chartDescriptor =\n                        SimpleXYChartDescriptor.bytes(10 * 1024 * 1024, false, Integer.MAX_VALUE);\n\n                chartDescriptor.addLineFillItems(HEAP_SIZE_LEG, USED_HEAP_LEG);\n                chartDescriptor.setDetailsItems(new String[] { HEAP_SIZE, USED_HEAP, MAX_HEAP });\n\n                chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n//                model.registerHeapChartSupport(chartSupport);\n\n                chartSupport.setZoomingEnabled(!liveModel);\n            }\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (memoryMonitoringSupported) {\n                add(chartSupport.getChart(), BorderLayout.CENTER);\n                chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN, UNKNOWN });\n            } else {\n                add(new NotSupportedDisplayer(\"JFR snapshot\"), BorderLayout.CENTER);\n            }\n        }\n\n    }\n    \n    \n    static class ClassesViewSupport extends JPanel implements JFREventVisitor {\n\n        private static final String TOTAL_LOADED = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Total_loaded_classes\");   // NOI18N\n        private static final String TOTAL_LOADED_LEG = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Total_loaded_classes_leg\");   // NOI18N\n//        private static final String SHARED_LOADED = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Shared_loaded_classes\"); // NOI18N\n//        private static final String SHARED_LOADED_LEG = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Shared_loaded_classes_leg\"); // NOI18N\n        private static final String TOTAL_UNLOADED = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Total_unloaded_classes\");   // NOI18N\n//        private static final String SHARED_UNLOADED = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Shared_unloaded_classes\"); // NOI18N\n\n        private final JFRModel jfrModel;\n        \n        private final boolean liveModel = false;\n        private boolean classMonitoringSupported;\n\n        private SimpleXYChartSupport chartSupport;\n\n        ClassesViewSupport(JFRModel jfrModel) {\n            this.jfrModel = jfrModel;\n            initModels();\n            initComponents();\n        }\n\n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Classes\"), null, 10, this, null);   // NOI18N\n        }\n        \n        \n        // --- Visitor ---\n        \n        private static final class Classes extends TimeRecord {\n            final long loaded;\n            Classes(JFREvent event, JFRModel jfrModel) throws JFRPropertyNotAvailableException {\n                super(event, jfrModel);\n                loaded = event.getLong(\"loadedClassCount\"); // NOI18N\n            }\n        }\n        \n        private List<Classes> records;\n        private JFREvent lastEvent;\n        private long lastEventTime = Long.MIN_VALUE;\n        \n        @Override\n        public void init() {\n            records = new ArrayList<>();\n        }\n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {            \n            if (JFRSnapshotMonitorViewProvider.EVENT_CLASS_LOADING.equals(typeName)) {\n                try {\n                    Classes record = new Classes(event, jfrModel);\n                    records.add(record);\n                    \n                    if (lastEventTime < record.time) {\n                        lastEvent = event;\n                        lastEventTime = record.time;\n                    }\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            records.sort(TimeRecord.COMPARATOR);\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    long lastTime = Long.MIN_VALUE + 1;\n                    for (final Classes record : records) {\n                        long time = jfrModel.nsToAbsoluteMillis(record.time);\n                        if (time <= lastTime) time = lastTime + 1;\n                        chartSupport.addValues(time, new long[] { record.loaded/*, 0*/ });\n                        lastTime = time;\n                    }\n\n                    if (!records.isEmpty()) {\n                        records.clear();\n                        \n                        try {\n                            long loadedClassCount = lastEvent.getLong(\"loadedClassCount\"); // NOI18N\n                            long unloadedClassCount = lastEvent.getLong(\"unloadedClassCount\"); // NOI18N\n                            chartSupport.updateDetails(new String[] { chartSupport.formatDecimal(loadedClassCount),\n                                                                      chartSupport.formatDecimal(unloadedClassCount)/*,\n                                                                      chartSupport.formatDecimal(totalUnloaded),\n                                                                      chartSupport.formatDecimal(sharedUnloaded)*/ });\n                        } catch (JFRPropertyNotAvailableException e) {}\n                    }\n                    \n                    records = null;\n                    lastEvent = null;\n                }\n            });\n        }\n\n        private void initModels() {\n//            liveModel = model.isLive();\n            classMonitoringSupported = true;\n\n            if (classMonitoringSupported) {\n                SimpleXYChartDescriptor chartDescriptor =\n                        SimpleXYChartDescriptor.decimal(100, false, Integer.MAX_VALUE);\n\n                chartDescriptor.addLineItems(TOTAL_LOADED_LEG/*, SHARED_LOADED_LEG*/);\n                chartDescriptor.setDetailsItems(new String[] { TOTAL_LOADED, /*SHARED_LOADED,*/\n                                                               TOTAL_UNLOADED/*, SHARED_UNLOADED*/ });\n\n                chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n//                model.registerClassesChartSupport(chartSupport);\n\n                chartSupport.setZoomingEnabled(!liveModel);\n            }\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (classMonitoringSupported) {\n                add(chartSupport.getChart(), BorderLayout.CENTER);\n                chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN/*, UNKNOWN, UNKNOWN*/ });\n            } else {\n                add(new NotSupportedDisplayer(\"JFR snapshot\"),\n                    BorderLayout.CENTER);\n            }\n        }\n\n    }\n    \n    \n    static class ThreadsViewSupport extends JPanel implements JFREventVisitor {\n\n        private static final String LIVE = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Live_threads\");   // NOI18N\n        private static final String LIVE_LEG = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Live_threads_leg\");   // NOI18N\n        private static final String DAEMON = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Daemon_threads\");// NOI18N\n        private static final String DAEMON_LEG = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Daemon_threads_leg\");// NOI18N\n        private static final String PEAK = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Live_threads_peak\");  // NOI18N\n        private static final String STARTED = NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Started_threads_total\");   // NOI18N\n\n        private final JFRModel jfrModel;\n        \n        private final boolean liveModel = false;\n        private boolean threadsMonitoringSupported;\n\n        private SimpleXYChartSupport chartSupport;\n\n        ThreadsViewSupport(JFRModel jfrModel) {\n            this.jfrModel = jfrModel;\n            initModels();\n            initComponents();\n        }\n\n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(MonitorViewSupport.class, \"LBL_Threads\"), null, 10, this, null);   // NOI18N\n        }\n        \n        \n        // --- Visitor ---\n        \n        private static final class Threads extends TimeRecord {\n            final long active;\n            final long daemon;\n            Threads(JFREvent event, JFRModel jfrModel) throws JFRPropertyNotAvailableException {\n                super(event, jfrModel);\n                active = event.getLong(\"activeCount\"); // NOI18N\n                daemon = event.getLong(\"daemonCount\"); // NOI18N\n            }\n        }\n        \n        private List<Threads> records;\n        private JFREvent lastEvent;\n        private long lastEventTime = Long.MIN_VALUE;\n        \n        @Override\n        public void init() {\n            records = new ArrayList<>();\n        }\n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {            \n            if (JFRSnapshotMonitorViewProvider.EVENT_JAVA_THREAD.equals(typeName)) {\n                try {\n                    Threads record = new Threads(event, jfrModel);\n                    records.add(record);\n                    \n                    if (lastEventTime < record.time) {\n                        lastEvent = event;\n                        lastEventTime = record.time;\n                    }\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n            return false;\n        }\n        \n        @Override\n        public void done() {\n            records.sort(TimeRecord.COMPARATOR);\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    long lastTime = Long.MIN_VALUE + 1;\n                    for (final Threads record : records) {\n                        long time = jfrModel.nsToAbsoluteMillis(record.time);\n                        if (time <= lastTime) time = lastTime + 1;\n                        chartSupport.addValues(time, new long[] { record.active, record.daemon });\n                        lastTime = time;\n                    }\n\n                    if (!records.isEmpty()) {\n                        records.clear();\n                        \n                        try {\n                            // TODO: lastEvent may not have the last timestamp!\n                            long activeCount = lastEvent.getLong(\"activeCount\"); // NOI18N\n                            long daemonCount = lastEvent.getLong(\"daemonCount\"); // NOI18N\n                            long peakCount = lastEvent.getLong(\"peakCount\"); // NOI18N\n                            long accumulatedCount = lastEvent.getLong(\"accumulatedCount\"); // NOI18N\n                            chartSupport.updateDetails(new String[] { chartSupport.formatDecimal(activeCount),\n                                                                      chartSupport.formatDecimal(daemonCount),\n                                                                      chartSupport.formatDecimal(peakCount),\n                                                                      chartSupport.formatDecimal(accumulatedCount) });\n                        } catch (JFRPropertyNotAvailableException e) {}\n                    }\n                    \n                    records = null;\n                    lastEvent = null;\n                }\n            });\n        }\n\n        private void initModels() {\n//            liveModel = model.isLive();\n            threadsMonitoringSupported = true;\n\n            if (threadsMonitoringSupported) {\n                SimpleXYChartDescriptor chartDescriptor =\n                        SimpleXYChartDescriptor.decimal(3, false, Integer.MAX_VALUE);\n\n                chartDescriptor.addLineItems(LIVE_LEG, DAEMON_LEG);\n                chartDescriptor.setDetailsItems(new String[] { LIVE, DAEMON,\n                                                               PEAK, STARTED });\n\n                chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor);\n//                model.registerThreadsChartSupport(chartSupport);\n\n                chartSupport.setZoomingEnabled(!liveModel);\n            }\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (threadsMonitoringSupported) {\n                add(chartSupport.getChart(), BorderLayout.CENTER);\n                chartSupport.updateDetails(new String[] { UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN });\n            } else {\n                add(new NotSupportedDisplayer(\"JFR snapshot\"), BorderLayout.CENTER);\n            }\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/overview/Bundle.properties",
    "content": "#\n# Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nLBL_Overview=Overview\n\nLBL_Saved_data=Saved data\n\nLBL_Details=Details\n\nLBL_Main_class=Main class\n\nLBL_Arguments=Arguments\n\nLBL_none=&lt;none&gt;\n\nLBL_Unknown=&lt;unknown&gt;\n\nLBL_JVM=JVM\n\nLBL_Java_Home=Java Home\n\nLBL_Java=Java\n\nLBL_Java_Version=version\n\nLBL_Java_Vendor=vendor\n\nLBL_JVM_Flags=JVM Flags\n\nLBL_JVM_arguments=JVM arguments\n\nLBL_System_properties=System properties\n\nMSG_JFR_Failed_General=<p><b>Failed to read the JFR snapshot.</b></p><br><p>Check the VisualVM logfile ({0}).</p>\n\nMSG_JFR_Failed_No_Loader=<p><b>Failed to read the JFR snapshot.</b></p><br><p>Please install at least one of the following JFR loaders using Tools | Plugins | Available Plugins and try again:</p><ul><li><b>VisualVM-JFR-Generic:</b> Generic JFR loader reading all JFR snapshots (slightly worse performance and higher memory consumption than the other loaders).</li><br><li><b>VisualVM-JFR-JDK9:</b> Support for the JFR loader bundled with JDK 9 and JDK 10 (requires running VisualVM on JDK 9/10) reading JFR snapshots created from JDK 9 and JDK 10.</li><br><li><b>VisualVM-JFR-JDK11:</b> Support for the JFR loader bundled with JDK 11 and newer (requires running VisualVM on JDK 11+) reading JFR snapshots created from JDK 9 and newer. Requires VisualVM-JFR-JDK9 to be installed as well.</li></ul>\n\nMSG_JFR_Failed_Install_Generic=<p><b>Failed to read the JFR snapshot.</b></p><br><p>Please install the <b>VisualVM-JFR-Generic</b> snapshot loader using Tools | Plugins | Available Plugins and try again.</p>\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/overview/JFRSnapshotOverviewView.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr.views.overview;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.util.Properties;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.model.JFRModelFactory;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JFRSnapshotOverviewView extends JFRViewTab {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/overview.png\";  // NOI18N\n    \n    \n    JFRSnapshotOverviewView(JFRSnapshot snapshot) {\n        super(snapshot, NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_Overview\"), new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 0);    // NOI18N\n    }\n    \n    \n    @Override\n    protected DataViewComponent createComponent() {\n        JFRModel model = getModel();\n        \n        if (model == null) {\n            MasterViewSupport masterView = new MasterViewSupport(model) {\n                @Override void firstShown() {}\n            };\n            return new DataViewComponent(masterView.getMasterView(), new DataViewComponent.MasterViewConfiguration(true));\n        } else {\n            final OverviewViewSupport.SnapshotsViewSupport snapshotView = new OverviewViewSupport.SnapshotsViewSupport((JFRSnapshot)getDataSource());\n\n            MasterViewSupport masterView = new MasterViewSupport(model) {\n                @Override\n                void firstShown() {\n                    initialize(snapshotView);\n                }\n            };\n            DataViewComponent dvc = new DataViewComponent(\n                    masterView.getMasterView(),\n                    new DataViewComponent.MasterViewConfiguration(false));\n\n            Properties jvmProperties = model.getSystemProperties();\n            String jvmargs = model.getJvmArgs();\n\n            dvc.configureDetailsView(new DataViewComponent.DetailsViewConfiguration(0.25, 0, -1, -1, -1, -1));\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_Saved_data\"), true), DataViewComponent.TOP_LEFT);  // NOI18N\n            dvc.addDetailsView(snapshotView.getDetailsView(), DataViewComponent.TOP_LEFT);\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_Details\"), true), DataViewComponent.TOP_RIGHT);    // NOI18N \n            dvc.addDetailsView(new OverviewViewSupport.JVMArgumentsViewSupport(jvmargs).getDetailsView(), DataViewComponent.TOP_RIGHT);\n            dvc.addDetailsView(new OverviewViewSupport.SystemPropertiesViewSupport(jvmProperties).getDetailsView(), DataViewComponent.TOP_RIGHT);\n\n            return dvc;\n        }\n    }\n    \n    private void initialize(final OverviewViewSupport.SnapshotsViewSupport snapshotView) {\n        new RequestProcessor(\"JFR Overview Initializer\").post(new Runnable() { // NOI18N\n            public void run() { getModel().visitEvents(snapshotView); }\n        });\n    }\n    \n    \n    // --- General data --------------------------------------------------------\n    \n    private static abstract class MasterViewSupport extends JPanel  {\n        \n        MasterViewSupport(JFRModel model) {\n            initComponents(model);\n        }\n        \n        \n        abstract void firstShown();\n        \n        \n        public DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_Overview\"), null, this);   // NOI18N\n        }\n        \n        \n        private void initComponents(JFRModel model) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            HTMLTextArea area = new HTMLTextArea(\"<nobr>\" + getGeneralProperties(model) + \"</nobr>\");    // NOI18N\n            area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n            \n//            add(area, BorderLayout.CENTER);\n            add(model == null ? new ScrollableContainer(area) : area, BorderLayout.CENTER);\n            \n            if (model != null) addHierarchyListener(new HierarchyListener() {\n                public void hierarchyChanged(HierarchyEvent e) {\n                    if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                        if (isShowing()) {\n                            removeHierarchyListener(this);\n                            SwingUtilities.invokeLater(MasterViewSupport.this::firstShown);\n                        }\n                    }\n                }\n            });\n        }\n        \n        private String getGeneralProperties(JFRModel model) {\n            if (model != null) {\n                StringBuilder data = new StringBuilder();\n                \n                // JFR Snapshot information\n                String commandLine = model.getJavaCommand();\n\n                if (commandLine != null) {\n                    // Application information\n                    int firstSpace = commandLine.indexOf(' ');\n                    String mainClass;\n                    String mainArgs = null;\n                    if (firstSpace == -1) {\n                        mainClass = commandLine;\n                    } else {\n                        mainClass = commandLine.substring(0,firstSpace);\n                        mainArgs = commandLine.substring(firstSpace+1);\n                    }\n                    String mainClassLbl = NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_Main_class\");    // NOI18N\n                    String argsLbl = NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_Arguments\");  // NOI18N\n                    data.append(\"<b>\"+mainClassLbl+\":</b> \" + mainClass + \"<br>\");  // NOI18N\n                    data.append(\"<b>\"+argsLbl+\":</b> \" + (mainArgs == null ? NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_none\") : mainArgs) + \"<br>\"); // NOI18N\n                    \n                    data.append(\"<br>\");    // NOI18N\n                }\n\n                // JVM information\n                String jvmFlags = model.getJvmFlags();\n                String jvmLbl = NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_JVM\"); // NOI18N\n                String jLbl = NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_Java\"); // NOI18N\n                String verLbl = NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_Java_Version\"); // NOI18N\n                String vendorLbl = NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_Java_Vendor\"); // NOI18N\n                String jhLbl = NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_Java_Home\");    // NOI18N\n                String flagsLbl = NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_JVM_Flags\"); // NOI18N\n                \n                String vmnS = model.getVmName();\n                String vmvS = model.getVmVersion();\n                String vmiS = model.getVmInfo();\n                if (vmvS != null || vmiS != null) {\n                    vmnS += \" (\";\n                    if (vmvS != null) vmnS += vmvS;\n                    if (vmvS != null && vmiS != null) vmnS += \", \";\n                    if (vmiS != null) vmnS += vmiS;\n                    vmnS += \")\";\n                }\n                data.append(\"<b>\"+jvmLbl+\":</b> \" + vmnS + \"<br>\");    // NOI18N\n                \n                Properties props = model.getSystemProperties();\n                if (props != null) {\n                    String javaVersion = props.getProperty(\"java.version\"); // NOI18N\n                    String javaVendor = props.getProperty(\"java.vendor\"); // NOI18N\n                    boolean spec = javaVersion == null && javaVendor == null;\n                    if (spec) {\n                        javaVersion = props.getProperty(\"java.vm.specification.version\"); // NOI18N\n                        javaVendor = props.getProperty(\"java.vm.vendor\"); // NOI18N\n                    }\n                    if (javaVersion != null || javaVendor != null) {\n                        data.append(\"<b>\"+jLbl+\":</b>\");\n                        if (javaVersion != null) {\n                            if (!spec) data.append(\" \"+verLbl+\" \" + javaVersion);   // NOI18N\n                            else data.append(\" \"+\"spec. version\"+\" \" + javaVersion);   // NOI18N\n                        }\n                        if (javaVendor != null) {\n                            if (javaVersion != null) data.append(\",\");\n                            if (!spec) data.append(\" \"+vendorLbl+\" \" + javaVendor);   // NOI18N\n                            else data.append(\" \"+\"VM vendor\"+\" \" + javaVendor);   // NOI18N\n                        }\n                        data.append(\"<br>\");\n                    }\n                }\n                String javaHome = model.getJavaHome();\n                data.append(\"<b>\"+jhLbl+\":</b> \" + (javaHome == null || javaHome.isEmpty() ? NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_none\") : javaHome) + \"<br>\"); // NOI18N\n                data.append(\"<b>\"+flagsLbl+\":</b> \" + (jvmFlags == null || jvmFlags.isEmpty() ? NbBundle.getMessage(JFRSnapshotOverviewView.class, \"LBL_none\") : jvmFlags) + \"<br><br>\");  // NOI18N\n                \n                return data.toString();\n            } else {\n                JFRModelFactory f = JFRModelFactory.getDefault();\n                if (!f.hasProviders()) return NbBundle.getMessage(JFRSnapshotOverviewView.class, \"MSG_JFR_Failed_Install_Generic\"); // NOI18N\n//                if (!f.hasProviders()) return NbBundle.getMessage(JFRSnapshotOverviewView.class, \"MSG_JFR_Failed_No_Loader\"); // NOI18N\n//                else if (!f.hasGenericProvider()) return NbBundle.getMessage(JFRSnapshotOverviewView.class, \"MSG_JFR_Failed_Install_Generic\"); // NOI18N\n                else return NbBundle.getMessage(JFRSnapshotOverviewView.class, \"MSG_JFR_Failed_General\", VisualVM.getInstance().getLogfileHandle()); // NOI18N\n            }\n            \n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/overview/JFRSnapshotOverviewViewProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr.views.overview;\n\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.jfr.view.JFRViewTabProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=JFRViewTabProvider.class)\npublic class JFRSnapshotOverviewViewProvider extends JFRViewTabProvider {\n    \n    @Override\n    protected JFRViewTab createView(JFRSnapshot jfrSnapshot) {\n        return new JFRSnapshotOverviewView(jfrSnapshot);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/overview/OverviewViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr.views.overview;\n\nimport java.awt.BorderLayout;\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.PrintWriter;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.StringTokenizer;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsSupport;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModelFactory;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.jfr.utils.ValuesConverter;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextAreaSearchUtils;\nimport org.graalvm.visualvm.threaddump.ThreadDump;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n * \n * @author Jiri Sedlacek\n */\nfinal class OverviewViewSupport {\n\n // --- Snapshots -----------------------------------------------------------\n    \n    static class SnapshotsViewSupport extends JPanel implements JFREventVisitor {\n        \n        private static final Logger LOGGER = Logger.getLogger(SnapshotsViewSupport.class.getName());\n        \n        private static final String LINK_TOGGLE_CATEGORY = \"file:/toggle_category/\"; // NOI18N\n        private static final String LINK_OPEN_SNAPSHOT = \"file:/open_snapshot/\"; // NOI18N\n        \n        private static final String CATEGORY_THREAD_DUMPS = \"thread_dumps\"; // NOI18N\n        \n        \n        private final JFRSnapshot snapshot;\n        \n        private final Map<String, Boolean> expansionMap = new HashMap<>();\n        \n        private List<Long> tdumpsTimestamps;\n        \n        private HTMLTextArea area;\n        \n        \n        SnapshotsViewSupport(JFRSnapshot snapshot) {\n            this.snapshot = snapshot;\n            \n            initComponents();\n        }        \n        \n        \n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(OverviewViewSupport.class, \"LBL_Saved_data\"), null, 10, this, null);   // NOI18N\n        }\n        \n        \n        @Override\n        public void init() {\n            tdumpsTimestamps = new ArrayList<>();\n        }\n\n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (\"jdk.ThreadDump\".equals(typeName)) { // NOI18N\n                try {\n                    tdumpsTimestamps.add(ValuesConverter.instantToNanos(event.getInstant(\"eventTime\"))); // NOI18N\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n            return false;\n        }\n\n        @Override\n        public void done() {\n            Collections.sort(tdumpsTimestamps);\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { area.setText(getSavedData()); }\n            });\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            area = new HTMLTextArea(getSavedData()) {\n                protected void showURL(URL url) {\n                    String link = url.toString();\n                    if (link.startsWith(LINK_TOGGLE_CATEGORY)) {\n                        link = link.substring(LINK_TOGGLE_CATEGORY.length());\n                        toggleExpanded(link); \n                        setText(getSavedData());\n                    } else if (link.startsWith(LINK_OPEN_SNAPSHOT)) {\n                        link = link.substring(LINK_OPEN_SNAPSHOT.length());\n                        openThreadDump(Long.parseLong(link));\n                    }\n                }\n            };\n            area.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n            \n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n        }\n        \n        private String getSavedData() {\n            StringBuilder data = new StringBuilder();\n            \n            int tdumpsCount = tdumpsTimestamps == null ? -1 : tdumpsTimestamps.size();\n            if (tdumpsCount < 0) {\n                data.append(\"<b>Progress:</b> reading data...\");\n            } else {\n                data.append(\"<b>Thread Dumps:</b> \");\n                \n                if (tdumpsCount == 0) {\n                    data.append(tdumpsCount);\n                } else {\n                    data.append(\"<a href='\" + (LINK_TOGGLE_CATEGORY + CATEGORY_THREAD_DUMPS) + \"'>\" + tdumpsCount + \"</a><br>\");\n                    \n                    if (isExpanded(CATEGORY_THREAD_DUMPS)) {\n                        for (long timestamp : tdumpsTimestamps) {\n                            data.append(\"&nbsp;&nbsp;&nbsp;<a href='\" + LINK_OPEN_SNAPSHOT + timestamp + \"'>\" + \"[threaddump] \" + SnapshotsSupport.getInstance().getTimeStamp(ValuesConverter.nanosToMillis(timestamp)) + \"</a><br>\"); // NOI18N\n                        }\n                        data.append(\"<br>\"); // NOI18N\n                    }\n                }\n            }\n            \n            return \"<nobr>\" + data.toString() + \"</nobr>\";   // NOI18N\n        }\n        \n        private boolean isExpanded(String categoryName) {\n            Boolean expanded = expansionMap.get(categoryName);\n            return expanded != null && expanded.booleanValue();\n        }\n        \n        private void toggleExpanded(String categoryName) {\n            expansionMap.put(categoryName, !isExpanded(categoryName));\n        }\n        \n        \n        private void openThreadDump(long timestamp) {\n            final String name = \"threaddump-\" + Long.toString(ValuesConverter.nanosToMillis(timestamp)); // NOI18N\n            DataSource.EVENT_QUEUE.post(new Runnable() {\n                public void run() {\n                    for (ThreadDump tdump : snapshot.getRepository().getDataSources(ThreadDump.class)) {\n                        File tdumpF = tdump.getFile();\n                        if (tdumpF != null && tdumpF.getName().startsWith(name)) {\n                            DataSourceWindowManager.sharedInstance().openDataSource(tdump, true);\n                            return;\n                        }\n                    }\n                    openThreadDumpImpl(timestamp);\n                }\n            });\n        }\n        \n        private void openThreadDumpImpl(long timestamp) {\n            new RequestProcessor(\"JFR Thread Dump Loader\").post(new Runnable() { // NOI18N\n                public void run() {\n                    JFRModelFactory.getJFRModelFor(snapshot).visitEvents(new JFREventVisitor() {\n                        @Override\n                        public boolean visit(String typeName, JFREvent event) {\n                            try {\n                                if (\"jdk.ThreadDump\".equals(typeName) && // NOI18N\n                                    ValuesConverter.instantToNanos(event.getInstant(\"eventTime\")) == timestamp) { // NOI18N\n                                    ThreadDump tdump = createThreadDump(ValuesConverter.nanosToMillis(timestamp), event.getString(\"result\")); // NOI18N\n                                    if (tdump != null) DataSourceWindowManager.sharedInstance().openDataSource(tdump, true);\n                                    return true;\n                                }\n                            } catch (JFRPropertyNotAvailableException e) {}\n                            return false;\n                        }\n                    });\n                }\n            });\n        }\n        \n        private ThreadDump createThreadDump(long timestamp, String result) {\n            if (result == null) return null;\n            \n            String name = \"threaddump-\" + timestamp + \".tdump\"; // NOI18N\n            File file = new File(snapshot.getStorage().getDirectory(), name);\n            \n            // TODO: created directly in <userdir>\\repository\\jfrsnapshots!\n            //       should be saved in a directory private to the snapshot\n            \n            try (PrintWriter out = new PrintWriter(file)) { out.println(result); file.deleteOnExit(); }\n            catch (FileNotFoundException ex) { LOGGER.log(Level.SEVERE, \"Error saving thread dump\", ex); } // NOI18N\n            \n            ThreadDump tdump = new ThreadDump(file, snapshot) {\n                { getStorage().setCustomProperty(PROPERTY_VIEW_CLOSABLE, Boolean.TRUE.toString()); }\n            };\n            snapshot.getRepository().addDataSource(tdump);\n            \n            return tdump;\n        }\n        \n    }\n    \n    \n    // --- JVM arguments -------------------------------------------------------\n    \n    static class JVMArgumentsViewSupport extends JPanel  {\n        \n        JVMArgumentsViewSupport(String jvmargs) {\n            initComponents(jvmargs);\n        }        \n        \n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(OverviewViewSupport.class, \"LBL_JVM_arguments\"), null, 10, this, null);    // NOI18N\n        }\n        \n        private void initComponents(String jvmargs) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            HTMLTextArea area = new HTMLTextArea(\"<nobr>\" + formatJVMArgs(jvmargs) + \"</nobr>\");   // NOI18N\n            area.setCaretPosition(0);\n            area.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n            \n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n            add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n        private String formatJVMArgs(String jvmargs) {\n            if (jvmargs == null || jvmargs.isEmpty()) return NbBundle.getMessage(OverviewViewSupport.class, \"LBL_none\"); // NOI18N\n            \n            String mangledString = \" \".concat(jvmargs).replace(\" -\",\"\\n\");  // NOI18N\n            StringTokenizer tok = new StringTokenizer(mangledString,\"\\n\");  // NOI18N\n            StringBuilder text = new StringBuilder(100);\n\n            while(tok.hasMoreTokens()) {\n                String arg = tok.nextToken().replace(\" \",\"&nbsp;\"); // NOI18N\n                int equalsSign = arg.indexOf('=');\n\n                text.append(\"<b>\"); // NOI18N\n                text.append(\"-\");   // NOI18N\n                if (equalsSign != -1) {\n                text.append(arg.substring(0,equalsSign));\n                text.append(\"</b>\");    // NOI18N\n                text.append(arg.substring(equalsSign));\n                } else {\n                text.append(arg);\n                text.append(\"</b>\");    // NOI18N\n                }\n                text.append(\"<br>\");    // NOI18N\n            }\n            return text.toString();\n        }\n        \n    }\n    \n    \n    // --- System properties ---------------------------------------------------\n    \n    static class SystemPropertiesViewSupport extends JPanel  {\n        \n        SystemPropertiesViewSupport(Properties properties) {\n            initComponents(properties);\n        }        \n        \n        public DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(OverviewViewSupport.class, \"LBL_System_properties\"), null, 20, this, null);    // NOI18N\n        }\n        \n        private void initComponents(Properties properties) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            HTMLTextArea area = area = new HTMLTextArea(\"<nobr>\" + formatSystemProperties(properties) + \"</nobr>\");    // NOI18N\n            area.setCaretPosition(0);\n            area.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n            \n            add(new ScrollableContainer(area), BorderLayout.CENTER);\n            add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n        }\n        \n        private String formatSystemProperties(Properties properties) {\n            if (properties == null || properties.isEmpty()) return NbBundle.getMessage(OverviewViewSupport.class, \"LBL_Unknown\"); // NOI18N\n            \n            StringBuilder text = new StringBuilder(200);\n            List<Object> keys = new ArrayList<>();\n            Enumeration<?> en = properties.propertyNames();\n            Iterator<?> keyIt;\n\n            while (en.hasMoreElements()) {\n                keys.add(en.nextElement());\n            }\n\n            keys.sort(null);\n            keyIt = keys.iterator();\n            while (keyIt.hasNext()) {\n                String key = (String) keyIt.next();\n                String val = properties.getProperty(key);\n\n                if (\"line.separator\".equals(key) && val != null) {  // NOI18N\n                    val = val.replace(\"\\n\", \"\\\\n\"); // NOI18N\n                    val = val.replace(\"\\r\", \"\\\\r\"); // NOI18N\n                }\n\n                text.append(\"<b>\"); // NOI18N\n                text.append(key);\n                text.append(\"</b>=\");   // NOI18N\n                text.append(val);\n                text.append(\"<br>\");    // NOI18N\n            }\n            return text.toString();\n        }\n        \n    }\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/recording/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nFORMAT_hms={0} hrs {1} min {2} sec\nFORMAT_ms={0} min {1} sec\nFORMAT_s={0} sec\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/recording/JFRSnapshotRecordingView.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.recording;\n\nimport java.time.Instant;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport javax.swing.ImageIcon;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.utils.ValuesConverter;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JFRSnapshotRecordingView extends JFRViewTab {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/jfrSnapshot.png\";  // NOI18N\n    \n    \n    JFRSnapshotRecordingView(JFRSnapshot dataSource) {\n        super(dataSource, \"Recording\", new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), Positionable.POSITION_LAST);   // NOI18N\n    }\n\n    \n    @Override\n    protected DataViewComponent createComponent() {\n        JFRModel model = getModel();\n        \n        if (model == null) {\n            RecordingViewSupport.MasterViewSupport masterView = new RecordingViewSupport.MasterViewSupport((JFRSnapshot)getDataSource(), model) {\n                @Override\n                void firstShown() {}\n            };\n            return new DataViewComponent(masterView.getMasterView(), new DataViewComponent.MasterViewConfiguration(true));\n        } else {\n            final RecordingViewSupport.SettingsSupport settingsView = new RecordingViewSupport.SettingsSupport(model);\n            final RecordingViewSupport.RecordingsSupport recordingsView = new RecordingViewSupport.RecordingsSupport(model);\n\n            RecordingViewSupport.MasterViewSupport masterView = new RecordingViewSupport.MasterViewSupport((JFRSnapshot)getDataSource(), model) {\n                @Override\n                void firstShown() { initialize(settingsView, this, recordingsView); }\n            };\n            DataViewComponent dvc = new DataViewComponent(masterView.getMasterView(), new DataViewComponent.MasterViewConfiguration(false));\n            dvc.configureDetailsView(new DataViewComponent.DetailsViewConfiguration(-1, -1, -1, -1, 0.75, 0.75));\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Settings\", true), DataViewComponent.TOP_LEFT);\n            dvc.addDetailsView(settingsView.getDetailsView(), DataViewComponent.TOP_LEFT);\n\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Concurrent recordings\", true), DataViewComponent.BOTTOM_LEFT);\n            dvc.addDetailsView(recordingsView.getDetailsView(), DataViewComponent.BOTTOM_LEFT);\n\n            return dvc;\n        }\n    }\n    \n    \n    private void initialize(final RecordingViewSupport.SettingsSupport settingsView, final JFREventVisitor... visitors) {\n        new RequestProcessor(\"JFR Recording Initializer\").post(new Runnable() { // NOI18N\n            public void run() {\n                final JFRModel model = getModel();\n                \n                final RecordingNode.Root settingsRoot = new RecordingNode.Root() {\n                    @Override void visitEventTypes() { model.visitEventTypes(this); }\n                    @Override long toRelativeNanos(Instant time) { return ValuesConverter.instantToRelativeNanos(time, model); }\n                };\n                \n                List<JFREventVisitor> allVisitors = new ArrayList<>(Arrays.asList(visitors));\n                allVisitors.add(settingsRoot);\n                model.visitEvents(allVisitors.toArray(new JFREventVisitor[0]));\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        settingsView.setData(settingsRoot.getChildCount() > 0 ? settingsRoot : new RecordingNode.Root(\"<no settings>\") {});\n                    }\n                });\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/recording/JFRSnapshotRecordingViewProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.recording;\n\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.jfr.view.JFRViewTabProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=JFRViewTabProvider.class)\npublic class JFRSnapshotRecordingViewProvider extends JFRViewTabProvider {\n\n    @Override\n    protected JFRViewTab createView(JFRSnapshot jfrSnapshot) {\n        return new JFRSnapshotRecordingView(jfrSnapshot);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/recording/RecordingNode.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.recording;\n\nimport java.time.Instant;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventType;\nimport org.graalvm.visualvm.jfr.model.JFREventTypeVisitor;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class RecordingNode extends CCTNode {\n    \n    private static final RecordingNode[] NO_NODES = new RecordingNode[0];\n    \n    private final RecordingNode parent;\n    private final List<RecordingNode> children;\n    \n    final String name;\n    final Icon icon;\n    \n    long time = Long.MIN_VALUE;\n    String setting;\n    String value;\n    String thread;\n    \n    \n    RecordingNode(String name, Icon icon, RecordingNode parent, List<RecordingNode> children) {\n        this.parent = parent;\n        this.children = children;\n        \n        this.name = name;\n        this.icon = icon;\n    }\n    \n    \n    RecordingNode getChild(String name) {\n        if (children != null)\n            for (RecordingNode child : children)\n                if (Objects.equals(name, child.name))\n                    return child;\n        return null;\n    }\n    \n    \n    @Override\n    public RecordingNode getChild(int index) {\n        return children == null ? null : children.get(index);\n    }\n\n    @Override\n    public RecordingNode[] getChildren() {\n        return children == null ? NO_NODES : children.toArray(NO_NODES);\n    }\n\n    @Override\n    public int getIndexOfChild(Object child) {\n        return children == null ? -1 : children.indexOf(child);\n    }\n\n    @Override\n    public int getNChildren() {\n        return children == null ? 0 : children.size();\n    }\n    \n    @Override\n    public boolean isLeaf() {\n        return children == null || children.isEmpty();\n    }\n\n    @Override\n    public RecordingNode getParent() {\n        return parent;\n    }\n\n    \n    protected void addChild(RecordingNode child) {\n        if (children != null) children.add(child);\n    }\n    \n    protected void removeAllChildren() {\n        if (children != null) children.clear();\n    }\n    \n    @Override\n    public String toString() {\n        return name;\n    }\n    \n    \n    static final class Event extends RecordingNode {\n        \n        Event(String name, RecordingNode parent) {\n            super(name, null, parent, new ArrayList<>());\n        }\n        \n        \n        @Override\n        public int hashCode() {\n            return name.hashCode();\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (!(o instanceof Event)) return false;\n            return Objects.equals(name, ((Event)o).name);\n        }\n\n        @Override\n        public String toString() {\n            return name;\n        }\n        \n    }\n    \n    \n    static final class Setting extends RecordingNode {\n        \n        private final long id;\n        \n        \n        Setting(long id, String name, String value, String thread, long time, RecordingNode parent) {\n            super(name, null, parent, null);\n            \n            this.id = id;\n            \n            this.value = value;\n            this.thread = thread;\n            this.time = time;\n        }\n        \n        \n        @Override\n        public int hashCode() {\n            return Long.hashCode(id);\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (!(o instanceof Setting)) return false;\n            return id == ((Setting)o).id;\n        }\n        \n    }\n    \n    \n    static class Root extends RecordingNode implements JFREventVisitor, JFREventTypeVisitor {\n        \n        private Map<Long, String> types;\n        \n        private long settingID = 0;\n        \n        \n        Root(String name) {\n            this();\n            Event e = new Event(name, this);\n            addChild(e);\n        }\n        \n        Root() {\n            super(null, null, null, new ArrayList<>());\n        }\n        \n        \n        void visitEventTypes() {}\n\n        long toRelativeNanos(Instant time) { return Long.MIN_VALUE; }\n        \n        \n        @Override\n        public void initTypes() {\n            types = new HashMap<>();\n        }\n        \n        @Override\n        public boolean visitType(String typeName, JFREventType type) {\n            types.put(type.getId(), type.getDisplayName());\n            return false;\n        }\n        \n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (\"jdk.ActiveSetting\".equals(typeName)) { // NOI18N\n                try {\n                    String eventName = getTypeName(event);\n\n                    RecordingNode eventNode = getChild(eventName);\n                    if (eventNode == null) {\n                        eventNode = new Event(eventName, this);\n                        addChild(eventNode);\n                    }\n\n                    String settingName = event.getString(\"name\"); // NOI18N\n                    String settingValue = event.getString(\"value\"); // NOI18N\n                    \n                    String threadName = getThreadName(event);\n                    \n                    RecordingNode settingNode = new Setting(settingID++, settingName, settingValue, threadName, toRelativeNanos(event.getInstant(\"eventTime\")), eventNode); // NOI18N\n                    eventNode.addChild(settingNode);\n                } catch (JFRPropertyNotAvailableException e) {\n                    System.err.println(\">>> XX \" + e + \" -- \" + event);\n                }\n            }\n            \n            return false;\n        }\n        \n        @Override\n        public void done() {\n            if (types != null) {\n                types.clear();\n                types = null;\n            }\n        }\n        \n        \n        private Boolean typeMode;\n        \n        private String getTypeName(JFREvent event) throws JFRPropertyNotAvailableException {\n            if (Boolean.TRUE.equals(typeMode)) {                // JFR loaders\n                return getTypeName(event.getLong(\"id\"));                        // NOI18N\n            } else if (Boolean.FALSE.equals(typeMode)) {        // Generic loader\n                return event.getValue(\"settingFor\").toString();                 // NOI18N\n            } else {                                            // not initialized yet\n                try {\n                    String eventName = getTypeName(event.getLong(\"id\"));        // NOI18N\n                    typeMode = Boolean.TRUE;\n                    return eventName;\n                } catch (JFRPropertyNotAvailableException e) {\n                    String eventName = event.getValue(\"settingFor\").toString(); // NOI18N\n                    typeMode = Boolean.FALSE;\n                    return eventName;\n                }\n            }\n        }\n        \n        private String getTypeName(long typeID) {\n            if (types == null) visitEventTypes();\n            return types.get(typeID);\n        }\n        \n        \n        private Boolean threadMode;\n        \n        private String getThreadName(JFREvent event) throws JFRPropertyNotAvailableException {\n            if (Boolean.TRUE.equals(threadMode)) {                  // v1+\n                return event.getThread(\"eventThread\").getName();                // NOI18N\n            } else if (Boolean.FALSE.equals(threadMode)) {          // v0\n                return \"-\";                                                     // NOI18N\n            } else {                                                // not initialized yet\n                try {\n                    String eventName = event.getThread(\"eventThread\").getName();// NOI18N\n                    threadMode = Boolean.TRUE;\n                    return eventName;\n                } catch (JFRPropertyNotAvailableException e) {\n                    threadMode = Boolean.FALSE;\n                    return \"-\";                                                 // NOI18N\n                }\n            }\n        }\n        \n        \n        @Override\n        public int hashCode() {\n            return 37;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            return o instanceof Root;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/recording/RecordingRenderers.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.recording;\n\nimport java.awt.Font;\nimport java.text.NumberFormat;\nimport java.time.Duration;\nimport javax.swing.JLabel;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.utils.DurationFormatter;\nimport org.graalvm.visualvm.jfr.utils.InstantFormatter;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.FormattedLabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class RecordingRenderers {\n    \n    private static int getMinimumWidth(String valueName) {\n        return new JLabel(valueName).getPreferredSize().width + 30;\n    }\n    \n    \n    static class NameRenderer extends LabelRenderer {\n        \n        private static Font regular;\n        private static Font bold;\n            \n        public void setValue(Object value, int row) {\n            if (value instanceof RecordingNode) {\n                RecordingNode node = (RecordingNode)value;\n                RecordingNode parent = node.getParent();\n                setFont(node.getChildCount() > 0 && parent != null && parent.getParent() == null ? bold() : regular());\n                setText(node.name);\n            } else {\n                setFont(value == null || \"<no recordings>\".equals(value.toString()) ? regular() : bold());\n                super.setValue(value, row);\n            }\n        }\n\n        static String getDisplayName() {\n            return \"Name\";\n        }\n        \n        private static Font regular() {\n            if (regular == null) regular = new LabelRenderer().getFont();\n            return regular;\n        }\n        \n        private static Font bold() {\n            if (bold == null) bold = new LabelRenderer().getFont().deriveFont(Font.BOLD);\n            return bold;\n        }\n\n    }\n    \n    \n    static class ValueRenderer extends LabelRenderer {\n        \n        ValueRenderer() {\n            setHorizontalAlignment(TRAILING);\n        }\n\n        static String getDisplayName() {\n            return \"Value\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(\"referenceValueString\", -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n\n    }\n    \n    static class ThreadRenderer extends LabelRenderer {\n        \n        ThreadRenderer() {\n            setHorizontalAlignment(TRAILING);\n        }\n\n        static String getDisplayName() {\n            return \"Thread\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(\"aLongThreadNameServingAsATemplate\", -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n\n    }\n    \n    \n    static class TimeRenderer extends LabelRenderer {\n        \n        private final JFRModel model;\n        \n        TimeRenderer(JFRModel model) {\n            this.model = model;\n            setHorizontalAlignment(TRAILING);\n        }\n        \n        public void setValue(Object value, int row) {\n            long nanos = value instanceof Long ? (Long)value : Long.MIN_VALUE;\n            setText(nanos > Long.MIN_VALUE ? InstantFormatter.format(model.nsToAbsoluteTime(nanos)) : \"\"); // NOI18N\n        }\n        \n        static String getDisplayName() {\n            return \"Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(System.currentTimeMillis(), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName())) + 30;\n        }\n        \n    }\n    \n    static class StartRenderer extends TimeRenderer {\n        \n        StartRenderer(JFRModel model) {\n            super(model);\n        }\n        \n        static String getDisplayName() {\n            return \"Start\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n    }\n    \n    static class DurationRenderer extends LabelRenderer {\n        \n        DurationRenderer() {\n            setHorizontalAlignment(TRAILING);\n        }\n        \n        @Override\n        public void setValue(Object value, int row) {\n            if (value == null) {\n                setText(\"\");\n            } else if (value instanceof Duration) {\n                Duration duration = (Duration)value;\n                setText(DurationFormatter.format(duration));\n            } else if (value instanceof Long) {\n                long duration = (Long)value;\n                if (duration == -1) setText(\"\");\n                else setText(DurationFormatter.format(Duration.ofNanos(duration)));\n            } else {\n                super.setValue(value, row);\n            }\n        }\n        \n        static String getDisplayName() {\n            return \"Duration\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Long.valueOf(999999999), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class IdRenderer extends FormattedLabelRenderer {\n        \n        IdRenderer() {\n            super(NumberFormat.getNumberInstance());\n            setHorizontalAlignment(TRAILING);\n        }\n        \n        public void setValue(Object value, int row) {\n            if (value instanceof Long && ((Long)value) == -1) setText(\"\");\n            else super.setValue(value, row);\n        }\n        \n        static String getDisplayName() {\n            return \"Id\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Long.valueOf(123456), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName())) + 30;\n        }\n        \n    }\n    \n    static class SizeRenderer extends FormattedLabelRenderer {\n        \n        SizeRenderer() {\n            super(Formatters.bytesFormat());\n            setHorizontalAlignment(SwingConstants.TRAILING);\n        }\n        \n        @Override\n        public void setValue(Object value, int row) {\n            if (!(value instanceof Long) || ((Long)value) >= 0) super.setValue(value, row);\n            else setText(\"\");\n//            if (!(value instanceof Long) || ((Long)value) > 0) super.setValue(value, row);\n//            else if (((Long)value) == 0) setText(\"-\");\n//            else setText(\"\");\n        }\n        \n        static String getDisplayName() {\n            return \"Max Size\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(99999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n                \n    }\n    \n    static class AgeRenderer extends DurationRenderer {\n        \n        static String getDisplayName() {\n            return \"Max Age\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Long.valueOf(999999999), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class DestinationRenderer extends LabelRenderer {\n        \n        DestinationRenderer() {\n            setHorizontalAlignment(TRAILING);\n        }\n        \n        static String getDisplayName() {\n            return \"Destination\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(\"aLongDestinationPathServingAsATemplate\", -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/recording/RecordingViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.recording;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.text.DecimalFormat;\nimport java.text.NumberFormat;\nimport java.time.Duration;\nimport java.time.Instant;\nimport java.util.HashSet;\nimport java.util.Objects;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.JTree;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.AbstractTableModel;\nimport javax.swing.tree.TreeNode;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.jfr.utils.InstantFormatter;\nimport org.graalvm.visualvm.jfr.utils.ValuesConverter;\nimport org.graalvm.visualvm.jfr.views.components.MessageComponent;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass RecordingViewSupport {\n    \n    static abstract class MasterViewSupport extends JPanel implements JFREventVisitor {\n        \n        private HTMLTextArea area;\n        \n        \n        MasterViewSupport(JFRSnapshot snapshot, JFRModel model) {\n            initComponents(model);\n        }\n        \n        \n        abstract void firstShown();\n\n        \n        DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(\"Recording\", null, this);  // NOI18N\n        }\n        \n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (\"jdk.DumpReason\".equals(typeName)) { // NOI18N\n                try {\n                    final String reason = event.getString(\"reason\"); // NOI18N\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            String summary = area.getText();\n                            summary += \"<br><b>Dump reason:</b>&nbsp;\";\n                            summary += reason;\n                            area.setText(summary);\n                        }\n                    });\n                } catch (JFRPropertyNotAvailableException e) {}\n                \n                return true;\n            }\n            return false;\n        }\n        \n\n        private void initComponents(JFRModel model) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (model == null) {\n                add(MessageComponent.notAvailable(), BorderLayout.CENTER);\n            } else {\n                area = new HTMLTextArea(createSummary(model));\n                area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n                add(area, BorderLayout.CENTER);\n\n                addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                            if (isShowing()) {\n                                removeHierarchyListener(this);\n                                SwingUtilities.invokeLater(MasterViewSupport.this::firstShown);\n                            }\n                        }\n                    }\n                });\n            }\n        }\n        \n        \n        private static String createSummary(JFRModel model) {\n            final StringBuilder s = new StringBuilder(\"<table border='0' cellpadding='0' cellspacing='0'>\"); // NOI18N\n            \n            Instant firstTime = model.getFirstEventTime();\n            Instant lastTime = model.getLastEventTime();\n            String firstEventTime = InstantFormatter.format(firstTime);\n            String lastEventTime = InstantFormatter.format(lastTime);\n            String totalTime = getTime(firstTime, lastTime);\n            String eventsCount = NumberFormat.getIntegerInstance().format(model.getEventsCount());\n            if (model.getExperimentalEventsCount() > 0) eventsCount += \" (incl. \" + NumberFormat.getIntegerInstance().format(model.getExperimentalEventsCount()) + \" experimental)\";\n            \n            s.append(\"<tr>\");\n            s.append(\"<td><b>First event time:</b>&nbsp;</td><td>\").append(firstEventTime).append(\"</td>\");\n            s.append(\"<td style='padding-left: 50px;'><b>Events count:</b>&nbsp;</td><td>\").append(eventsCount).append(\"</td>\");\n            s.append(\"</tr>\");\n            \n            s.append(\"<tr>\");\n            s.append(\"<td><b>Last event time:</b>&nbsp;</td><td>\").append(lastEventTime).append(\"</td>\");\n            s.append(\"<td style='padding-left: 50px;'><b>Events time:</b>&nbsp;</td><td>\").append(totalTime).append(\"</td>\");\n            s.append(\"</tr>\");\n            \n            s.append(\"</table>\"); // NOI18N\n            \n            return s.toString();\n        }\n        \n        private static String getTime(Instant firstTime, Instant lastTime) {\n            long millis = ValuesConverter.durationToMillis(Duration.between(firstTime, lastTime));\n            \n            // Hours\n            long hours = millis / 3600000;\n            String sHours = hours == 0 ? null : new DecimalFormat(\"#0\").format(hours); // NOI18N\n            millis %= 3600000;\n            \n            // Minutes\n            long minutes = millis / 60000;\n            String sMinutes = hours == 0 && minutes == 0 ? null : new DecimalFormat(hours > 0 ? \"00\" : \"#0\").format(minutes); // NOI18N\n            millis %= 60000;\n            \n            // Seconds\n            String sSeconds = new DecimalFormat(\"#0.000\").format(millis / 1000d); // NOI18N\n            \n            if (sMinutes == null) {\n                 return NbBundle.getMessage(RecordingViewSupport.class, \"FORMAT_s\", // NOI18N\n                                            new Object[] { sSeconds });\n            } else if (sHours == null) {\n                 return NbBundle.getMessage(RecordingViewSupport.class, \"FORMAT_ms\", // NOI18N\n                                            new Object[] { sMinutes, sSeconds });\n            } else {\n                return NbBundle.getMessage(RecordingViewSupport.class, \"FORMAT_hms\", // NOI18N\n                                            new Object[] { sHours, sMinutes, sSeconds });\n            }\n        }\n\n    }\n    \n    \n    static class SettingsSupport extends JPanel {\n        \n        private final JFRModel jfrModel;\n        \n        private DataModel tableModel;\n        private ProfilerTreeTable table;\n        \n        \n        SettingsSupport(JFRModel jfrModel) {\n            this.jfrModel = jfrModel;\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Settings\", null, 10, this, null);\n        }\n        \n        \n        void setData(RecordingNode root) {\n            tableModel.setRoot(root);\n        }\n        \n        \n        private void initComponents() {\n            tableModel = new DataModel();\n            table = new ProfilerTreeTable(tableModel, true, true, new int[] { 0 });\n            \n            table.setRootVisible(false);\n            table.setShowsRootHandles(true);\n\n            table.setMainColumn(0);\n            table.setFitWidthColumn(0);\n\n            table.setDefaultSortOrder(SortOrder.ASCENDING);\n            table.setSortColumn(0);\n            \n            RecordingRenderers.NameRenderer nameRenderer = new RecordingRenderers.NameRenderer();\n            table.setTreeCellRenderer(nameRenderer);\n            \n            RecordingRenderers.ValueRenderer valueRenderer = new RecordingRenderers.ValueRenderer();\n            RecordingRenderers.TimeRenderer timeRenderer = new RecordingRenderers.TimeRenderer(jfrModel);\n            int commonWidth = Math.max(valueRenderer.getPreferredWidth(), timeRenderer.getPreferredWidth());\n            \n            table.setColumnRenderer(1, valueRenderer);\n            table.setDefaultColumnWidth(1, commonWidth);\n            table.setColumnVisibility(1, RecordingRenderers.ValueRenderer.isInitiallyVisible());\n            \n            table.setColumnRenderer(2, timeRenderer);\n            table.setDefaultColumnWidth(2, commonWidth);\n            table.setColumnVisibility(2, RecordingRenderers.TimeRenderer.isInitiallyVisible());\n            \n            RecordingRenderers.ThreadRenderer threadRenderer = new RecordingRenderers.ThreadRenderer();\n            table.setColumnRenderer(3, threadRenderer);\n            table.setDefaultColumnWidth(3, threadRenderer.getPreferredWidth());\n            table.setColumnVisibility(3, RecordingRenderers.ThreadRenderer.isInitiallyVisible());\n            \n            setLayout(new BorderLayout());\n            add(new ProfilerTableContainer(table, false, null), BorderLayout.CENTER);\n        }\n        \n        \n        private static class DataModel extends ProfilerTreeTableModel.Abstract {\n            \n            DataModel() {\n                super(new RecordingNode.Root(\"reading data...\") {});\n            }\n            \n            \n            @Override\n            public int getColumnCount() {\n                return 4;\n            }\n\n            @Override\n            public Class<?> getColumnClass(int column) {\n                switch (column) {\n                    case 0: return JTree.class;\n                    case 1: return String.class;\n                    case 2: return Long.class;\n                    case 3: return String.class;\n                    default: return null;\n                }\n            }\n\n            @Override\n            public String getColumnName(int column) {\n                switch (column) {\n                    case 0: return RecordingRenderers.NameRenderer.getDisplayName();\n                    case 1: return RecordingRenderers.ValueRenderer.getDisplayName();\n                    case 2: return RecordingRenderers.TimeRenderer.getDisplayName();\n                    case 3: return RecordingRenderers.ThreadRenderer.getDisplayName();\n                    default: return null;\n                }\n            }\n\n            @Override\n            public Object getValueAt(TreeNode node, int column) {\n                if (node == null) return null;\n                RecordingNode rnode = (RecordingNode)node;\n                \n                switch (column) {\n                    case 0: return rnode;\n                    case 1: return rnode.value;\n                    case 2: return rnode.time;\n                    case 3: return rnode.thread;\n                    default: return null;\n                }\n            }\n            \n            @Override\n            public void setValueAt(Object o, TreeNode node, int column) {}\n\n            @Override\n            public boolean isCellEditable(TreeNode node, int column) { return false; }\n            \n        }\n        \n    }\n    \n    \n    static class RecordingsSupport extends JPanel implements JFREventVisitor {\n        \n        private final JFRModel jfrModel;\n        \n        private Record[] records;\n        private Set<Record> cache;\n        \n        private DataModel model;\n        private ProfilerTable table;\n        \n        \n        RecordingsSupport(JFRModel jfrModel) {\n            this.jfrModel = jfrModel;\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Concurrent recordings\", null, 10, this, null);\n        }\n        \n        \n        @Override\n        public void init() {\n            Record progress = new Record();\n            progress.name = \"reading data...\";\n            records = new Record[] { progress };\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { model.fireTableDataChanged(); }\n            });\n            \n            cache = new HashSet<>();\n        }\n\n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (\"jdk.ActiveRecording\".equals(typeName)) { // NOI18N\n                try {\n                    Record record = new Record();\n                    record.name = event.getString(\"name\"); // NOI18N\n                    record.id = event.getLong(\"id\"); // NOI18N\n                    record.start = ValuesConverter.instantToRelativeNanos(event.getInstant(\"recordingStart\"), jfrModel); // NOI18N\n                    record.duration = event.getDuration(\"recordingDuration\"); // NOI18N\n                    record.maxAge = event.getDuration(\"maxAge\"); // NOI18N\n                    record.maxSize = event.getLong(\"maxSize\"); // NOI18N\n                    record.destination = event.getString(\"destination\"); // NOI18N\n                    if (record.destination == null) record.destination = \"-\";\n    //                record.thread = event.getThread().getJavaName();\n\n                    cache.add(record);\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n            return false;\n        }\n\n        @Override\n        public void done() {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    if (cache.isEmpty())  {\n                        Record noData = new Record();\n                        noData.name = \"<no recordings>\";\n                        cache.add(noData);\n                    }\n                    \n                    records = cache.toArray(new Record[0]);\n                    \n                    model.fireTableDataChanged();\n                    \n                    cache.clear();\n                    cache = null;\n                }\n            });\n        }\n        \n        \n        private void initComponents() {\n            model = new DataModel();\n            \n            table = new ProfilerTable(model, true, true, null);\n            \n            table.setMainColumn(0);\n            table.setFitWidthColumn(0);\n\n            table.setDefaultSortOrder(SortOrder.ASCENDING);\n            table.setSortColumn(1);\n            \n            RecordingRenderers.NameRenderer nameRenderer = new RecordingRenderers.NameRenderer();\n            table.setColumnRenderer(0, nameRenderer);\n            \n            RecordingRenderers.IdRenderer idRenderer = new RecordingRenderers.IdRenderer();\n            table.setColumnRenderer(1, idRenderer);\n            table.setDefaultColumnWidth(1, idRenderer.getPreferredWidth());\n            table.setColumnVisibility(1, RecordingRenderers.IdRenderer.isInitiallyVisible());\n            \n            RecordingRenderers.StartRenderer startRenderer = new RecordingRenderers.StartRenderer(jfrModel);\n            table.setColumnRenderer(2, startRenderer);\n            table.setDefaultColumnWidth(2, startRenderer.getPreferredWidth());\n            table.setColumnVisibility(2, RecordingRenderers.TimeRenderer.isInitiallyVisible());\n            \n            RecordingRenderers.DurationRenderer durationRenderer = new RecordingRenderers.DurationRenderer();\n            RecordingRenderers.SizeRenderer sizeRenderer = new RecordingRenderers.SizeRenderer();\n            RecordingRenderers.AgeRenderer ageRenderer = new RecordingRenderers.AgeRenderer();\n            int commonWidth = Math.max(durationRenderer.getPreferredWidth(), sizeRenderer.getPreferredWidth());\n            commonWidth = Math.max(commonWidth, ageRenderer.getPreferredWidth());\n            table.setColumnRenderer(3, durationRenderer);\n            table.setDefaultColumnWidth(3, commonWidth);\n            table.setColumnVisibility(3, RecordingRenderers.DurationRenderer.isInitiallyVisible());\n            \n            table.setColumnRenderer(4, sizeRenderer);\n            table.setDefaultColumnWidth(4, commonWidth);\n            table.setColumnVisibility(4, RecordingRenderers.SizeRenderer.isInitiallyVisible());\n            \n            table.setColumnRenderer(5, ageRenderer);\n            table.setDefaultColumnWidth(5, commonWidth);\n            table.setColumnVisibility(5, RecordingRenderers.AgeRenderer.isInitiallyVisible());\n            \n            RecordingRenderers.DestinationRenderer destinationRenderer = new RecordingRenderers.DestinationRenderer();\n            table.setColumnRenderer(6, destinationRenderer);\n            table.setDefaultColumnWidth(6, destinationRenderer.getPreferredWidth());\n            table.setColumnVisibility(6, RecordingRenderers.DestinationRenderer.isInitiallyVisible());\n            \n//            RecordingRenderers.ThreadRenderer threadRenderer = new RecordingRenderers.ThreadRenderer();\n//            table.setColumnRenderer(7, threadRenderer);\n//            table.setDefaultColumnWidth(7, threadRenderer.getPreferredWidth());\n//            table.setColumnVisibility(7, RecordingRenderers.ThreadRenderer.isInitiallyVisible());\n            \n            setLayout(new BorderLayout());\n            add(new ProfilerTableContainer(table, false, null), BorderLayout.CENTER);\n        }\n        \n        \n        private static class Record {\n            \n            String name;\n            long id = -1;\n            long start = Long.MIN_VALUE;\n            Duration duration;\n            long maxSize = -1;\n            Duration maxAge;\n            String destination;\n//            String thread;\n            \n            \n            @Override\n            public int hashCode() {\n                return Objects.hash(name, id, start, duration, maxSize, maxAge, destination /*, thread*/);\n            }\n\n            @Override\n            public boolean equals(Object o) {\n                if (this == o) return true;\n                if (o == null) return false;\n                if (!(o instanceof Record)) return false;\n                \n                final Record r = (Record) o;\n                if (id != r.id) return false;\n                if (start != r.start) return false;\n                if (!Objects.equals(duration, r.duration)) return false;\n                if (maxSize != r.maxSize) return false;\n                if (!Objects.equals(maxAge, r.maxAge)) return false;\n                if (!Objects.equals(name, r.name)) return false;\n                if (!Objects.equals(destination, r.destination)) return false;\n//                if (!Objects.equals(thread, r.thread)) return false;\n                \n                return true;\n            }\n            \n        }\n        \n        \n        private class DataModel extends AbstractTableModel {\n            \n            @Override\n            public int getColumnCount() {\n                return 7;\n            }\n            \n            @Override\n            public String getColumnName(int columnIndex) {\n                switch (columnIndex) {\n                    case 0: return RecordingRenderers.NameRenderer.getDisplayName();\n                    case 1: return RecordingRenderers.IdRenderer.getDisplayName();\n                    case 2: return RecordingRenderers.StartRenderer.getDisplayName();\n                    case 3: return RecordingRenderers.DurationRenderer.getDisplayName();\n                    case 4: return RecordingRenderers.SizeRenderer.getDisplayName();\n                    case 5: return RecordingRenderers.AgeRenderer.getDisplayName();\n                    case 6: return RecordingRenderers.DestinationRenderer.getDisplayName();\n//                    case 7: return RecordingRenderers.ThreadRenderer.getDisplayName();\n                    default: return null;\n                }\n            }\n            \n            @Override\n            public Class<?> getColumnClass(int columnIndex) {\n                switch (columnIndex) {\n                    case 0: return String.class;\n                    case 1: return Long.class;\n                    case 2: return Long.class;\n                    case 3: return Duration.class;\n                    case 4: return Long.class;\n                    case 5: return Duration.class;\n                    case 6: return String.class;\n//                    case 7: return String.class;\n                    default: return null;\n                }\n            }\n\n            @Override\n            public int getRowCount() {\n                return records == null ? 0 : records.length;\n            }\n\n            @Override\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                switch (columnIndex) {\n                    case 0: return records[rowIndex].name;\n                    case 1: return records[rowIndex].id;\n                    case 2: return records[rowIndex].start;\n                    case 3: return records[rowIndex].duration;\n                    case 4: return records[rowIndex].maxSize;\n                    case 5: return records[rowIndex].maxAge;\n                    case 6: return records[rowIndex].destination;\n//                    case 7: return records[rowIndex].thread;\n                    default: return null;\n                }\n            }\n            \n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/sampler/Bundle.properties",
    "content": "#\n# Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_Sampler=Sampler\n\nLBL_Sample=Display\\:\nLBL_Profile=Profile\\:\n\nLBL_Cpu=CPU\n\nLBL_Memory=Memory\n\nLBL_Stop=Stop\n\nLBL_Status=Status:\n\nMSG_Sample=&Sample\n\nDESCR_Sample=Analysis by sampling profiler\n\nLBL_Settings=Settings\n\nLBL_Cpu_settings=CPU settings\n\nLBL_Memory_settings=Memory settings\n\nMSG_Checking_Availability=Checking availability...\n\nLBL_Information=Information\n\nLBL_Summary=Summary\n\nLBL_Undefined=<undefined>\n\nMSG_Application_terminated=application terminated\n\nMSG_Sampling_inactive=sampling inactive\n\nMSG_Cpu_progress=CPU sampling in progress\n\nMSG_Memory_progress=memory sampling in progress\n\nLBL_Refreshing=refreshing...\n\nLBL_Cpu_samples=CPU samples\n\nLBL_Cpu_sampling=<b>CPU sampling:</b><br>\n\nLBL_Memory_samples=Memory samples\n\nLBL_Memory_sampling=<br><br><b>Memory sampling:</b><br>\n\nMSG_No_save_data_cpu=<html><b>No data to save</b><br><br>Make sure the application performs some code<br>and the selected filter is not filtering out the calls.</html>\n\nMSG_No_save_data_memory=<html><b>No data to save</b><br><br>Make sure the application performs some code.</html>\n\nMSG_Thread_dump_unsupported=thread dump not supported\n\nMSG_ThreadCPU_unsupported=thread CPU time not supported\n\nMSG_Available=Available.\n\nMSG_Available_details=Available ({0}).\n\nMSG_Available_details2=Available ({0}, {1}).\n\nMSG_Available_details3=Available ({0}, {1}, {2}).\n\nMSG_Press_cpu=Press the 'CPU' button to start collecting performance data.\n\nMSG_Press_mem=Press the 'Memory' button to start collecting memory data.\n\nMSG_Unavailable=Not available.\n\nMSG_Unavailable_remote=Not available. Remote sampling is only supported for Java 8+ applications.\n\nMSG_Unavailable_connect_jdk=Not available. Cannot connect to target application. Make sure the application is running on a supported Java 6+.\n\nMSG_Unavailable_connect_log=Not available. Cannot connect to target application. Check the VisualVM logfile ({0}).\n\nMSG_Unavailable_read_log=Not available. Failed to read objects in target application. Check the VisualVM logfile ({0}).\n\nMSG_Gc_unsupported=perform GC not supported\n\nMSG_HeapDump_unsupported=heap dump not supported\n\nMSG_ThreadMemory_unsupported=thread memory allocation not supported\n\nMSG_Incorrect_CPU_settings=Provided CPU settings are invalid.\n\nMSG_Incorrect_Memory_settings=Provided Memory settings are invalid.\n\n\nLBL_Cpu_settings=CPU settings\n\nLBL_Cpu_samples=CPU samples\n\nTOOLTIP_Pause_results=Pause live results\n\nTOOLTIP_Update_results=Update live results now\n\nLBL_Deltas=Deltas\n\nTOOLTIP_Deltas=Show delta values\n\nLBL_Snapshot=Snapshot\n\nTOOLTIP_Snapshot=Take snapshot of collected results\n\nLBL_Thread_dump=Thread Dump\n\nTOOLTIP_Thread_dump=Take thread dump\n\nLBL_No_data=<No Data>\n\nMSG_unavailable=Not available.\n\nMSG_unavailable_init_jmx=Not available. Cannot initialize JMX connection to target application. Use 'Add JMX Connection' action to attach to the application.\n\nMSG_unavailable_create_jmx=Not available. Failed to create JMX connection to target application. Use 'Add JMX Connection' action to attach to the application.\n\nMSG_unavailable_threads=Not available. Cannot access threads in target application. Check the VisualVM logfile ({0}).\n\nLBL_ThreadAlloc=Thread CPU load\n\nCOL_Thread_name=Name\n\nCOL_ABytes=Thread Time (CPU)\n\nCOL_ABytes_Sec=Thread Time (CPU) / sec\n\nLBL_Threads=<b>Threads: </b>{0}\n\nLBL_Thread_filter=Thread Name Filter\n\nLBL_CPUTime=<b>Total CPU Time [ms]: </b>{0}\n\nThreadsCPUView_TOOLTIP_Col_name=Thread name\nThreadsCPUView_TOOLTIP_Col_time=Total thread CPU time\nThreadsCPUView_TOOLTIP_Col_timesec=Thread CPU time in last 1 second\nThreadsCPUView_LBL_Statistics=Statistics\\:\nThreadsCPUView_LBL_TCount=Threads Count\\:\nThreadsCPUView_LBL_Total_time=Total Time (CPU)\\:\n\n\n\nLBL_Memory_settings=Memory settings\n\nLBL_Heap_histogram=Heap histogram\n\nLBL_PermGen_histogram=PermGen histogram\n\nLBL_ThreadAlloc_M=Per thread allocations\n\nCOL_Class_name=Name\n\nCOL_Bytes_rel=Bytes [%]\n\nCOL_Bytes=Live Bytes\n\nCOL_ABytes_rel=Allocated Bytes [%]\n\nCOL_ABytes=Allocated Bytes\n\nCOL_ABytes_Sec=Allocated Bytes / sec\n\nCOL_Instances=Live Objects\n\nCOL_Thread_name=Name\n\nTOOLTIP_Pause_results=Pause live results\n\nTOOLTIP_Update_results=Update live results now\n\nLBL_Deltas=Deltas\n\nTOOLTIP_Deltas=Show delta values\n\nLBL_Snapshot=Snapshot\n\nTOOLTIP_Snapshot=Take snapshot of collected results\n\nLBL_Gc=Perform GC\n\nTOOLTIP_Gc=Perform garbage collection in target application\n\nLBL_HeapDump=Heap Dump\n\nTOOLTIP_HeapDump=Take heap dump\n\nLBL_Class_filter=Class Name Filter\n\nLBL_Thread_filter=Thread Name Filter\n\nLBL_Classes=<b>Classes: </b>{0}\n\nLBL_Instances=<b>Instances: </b>{0}\n\nLBL_Bytes=<b>Bytes: </b>{0}\n\nLBL_ABytes=<b>Total Allocated Bytes: </b>{0}\n\nLBL_Threads=<b>Threads: </b>{0}\n\nMemoryView_TOOLTIP_Col_name=Class name\nMemoryView_TOOLTIP_Col_size=Size of live instances\nMemoryView_TOOLTIP_Col_count=Number of live instances\nMemoryView_LBL_Results=Results\\:\nMemoryView_LBL_Data=Collected data\\:\nMemoryView_LBL_Snapshot=Snapshot\nMemoryView_Context_GoToSource=Go to Source\n\nThreadsMemoryView_TOOLTIP_Col_name=Thread name\nThreadsMemoryView_TOOLTIP_Col_bytes=Total bytes allocated by thread\nThreadsMemoryView_TOOLTIP_Col_bytessec=Bytes allocated by thread in last 1 second\nThreadsMemoryView_LBL_Results=Results\\:\nThreadsMemoryView_LBL_Statistics=Statistics\\:\nThreadsMemoryView_LBL_TCount=Threads Count\\:\nThreadsMemoryView_LBL_Total_bytes=Total Allocated Bytes\\:\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/sampler/CPUSamplerViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.sampler;\n\nimport java.awt.BorderLayout;\nimport java.awt.Font;\nimport java.text.Format;\nimport java.time.Instant;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.swing.JPanel;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.jfr.model.JFRStackTrace;\nimport org.graalvm.visualvm.jfr.model.JFRThread;\nimport org.graalvm.visualvm.jfr.utils.ValuesConverter;\nimport org.graalvm.visualvm.jfr.views.components.MessageComponent;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.StackTraceSnapshotBuilder;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.cpu.SnapshotCPUView;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.PercentRenderer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class CPUSamplerViewSupport {\n    \n    static final class CPUViewSupport extends JPanel implements JFREventVisitor {\n        \n        private final JFRModel model;\n        \n        private final boolean hasData;\n        \n        private List<JFREventWithStack> data;\n        private Set<String> ignoredEvents;\n        private JFRThreadInfoSupport tiSupport;\n        \n        \n        CPUViewSupport(JFRModel model) {\n            this.model = model;\n            \n            hasData = true; // all events used, let's assume some of them contain stack traces\n//            hasData = model.containsEvent(JFRSnapshotSamplerViewProvider.CPUSampleChecker.class);\n            \n            initComponents();\n        }\n        \n        \n        @Override\n        public void init() {\n            if (hasData) {\n                data = new ArrayList<>();\n                ignoredEvents = new HashSet<>();\n                tiSupport = new JFRThreadInfoSupport();\n            }\n        }\n\n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (!hasData) return true;\n            \n            try {\n                if (!ignoredEvents.contains(typeName))\n                    data.add(new JFREventWithStack(typeName, event, model, tiSupport));\n            } catch (JFRPropertyNotAvailableException e) {\n                ignoredEvents.add(typeName);\n            }\n            \n            return false;\n        }\n\n        @Override\n        public void done() {\n            if (hasData) {\n                StackTraceSnapshotBuilder builder = new StackTraceSnapshotBuilder();\n                Map<Long, Map<String, Object>> threads = new HashMap<>();\n\n                Collections.sort(data);\n                \n                long baseTime = System.nanoTime();\n                for (JFREventWithStack ev : data) {\n                    if (ev.isThreadEnd()) {\n                        threads.remove(ev.getThreadId());\n                    } else {\n                        threads.put(ev.getThreadId(), ev.getThreadInfo());\n                        builder.addStacktrace(getAllThreads(threads), baseTime + ev.getRelativeTime());\n                    }\n                }\n\n                data = null;\n                ignoredEvents = null;\n                tiSupport = null;\n                threads = null;\n\n                try {\n                    final CPUResultsSnapshot snapshot = builder.createSnapshot(ValuesConverter.instantToMillis(model.getFirstEventTime()));\n                    builder = null;\n                    \n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            removeAll();\n                            add(createView(snapshot), BorderLayout.CENTER);\n                        }\n                    });\n                } catch (CPUResultsSnapshot.NoDataAvailableException ex) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            removeAll();\n                            String msg = \"<html><b>No CPU samples data recorded.</b><br><br><br>\" +\n                                         \"To analyze the CPU samples make sure the JFR snapshot contains events with stack trace information.<br><br></html>\";\n                            add(MessageComponent.scrollable(msg), BorderLayout.CENTER);\n                        }\n                    });\n                }\n            }\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(\n                CPUSamplerViewSupport.class, \"LBL_Cpu_samples\"), null, 10, this, null); // NOI18N\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n//            if (!hasData) {\n//                setLayout(new BorderLayout());\n//                add(MessageComponent.noData(\"CPU samples\", JFRSnapshotSamplerViewProvider.CPUSampleChecker.checkedTypes()), BorderLayout.CENTER);\n//            }\n        }\n        \n        private SnapshotCPUView createView(CPUResultsSnapshot snapshot) {\n            return new SnapshotCPUView(snapshot, true, null, null, null, null) {\n                @Override protected boolean profileMethodEnabled() { return false; }\n                @Override protected boolean profileMethodSupported() { return false; }\n                @Override protected boolean profileClassSupported() { return false; }\n                @Override protected boolean showSourceSupported() { return GoToSource.isAvailable(); }\n                @Override protected void showSource(ClientUtils.SourceCodeSelection value) { GoToSource.openSource(null, value.getClassName(), value.getMethodName(), value.getMethodSignature()); }\n                @Override protected void selectForProfiling(ClientUtils.SourceCodeSelection value) {}\n            };\n        }\n\n        private Map<String, Object>[] getAllThreads(Map<Long, Map<String, Object>> threads) {\n            Collection<Map<String, Object>> allThreds = threads.values();\n\n            return  allThreds.toArray(new Map[0]);\n        }\n        \n    }\n    \n    \n    private static class JFREventWithStack implements Comparable<JFREventWithStack> {\n        \n        private final long eventTime;\n        private final Map<String, Object> threadInfo;\n        \n        \n        JFREventWithStack(String type, JFREvent event, JFRModel model, JFRThreadInfoSupport tiSupport) throws JFRPropertyNotAvailableException {\n            JFRStackTrace stack;\n            if (\"jdk.ThreadEnd\".equals(type)) { // NOI18N\n                stack = null;\n            } else {\n                stack = event.getStackTrace(\"eventStackTrace\"); // NOI18N\n                if (stack == null) throw new JFRPropertyNotAvailableException(\"Must define stackTrace to include into sampled snapshot\"); // NOI18N\n            }\n            \n            boolean profilingEvent = JFRSnapshotSamplerViewProvider.EVENT_EXECUTION_SAMPLE.equals(type) ||\n                                     JFRSnapshotSamplerViewProvider.EVENT_NATIVE_SAMPLE.equals(type);\n            \n            JFRThread thread = profilingEvent ? event.getThread(\"sampledThread\") : event.getThread(\"eventThread\"); // NOI18N\n            if (thread == null) throw new JFRPropertyNotAvailableException(\"Must define eventThread to include into sampled snapshot\"); // NOI18N\n            \n            Instant eventTimeI = event.getInstant(\"eventTime\"); // NOI18N\n            if (eventTimeI == null) throw new JFRPropertyNotAvailableException(\"Must define eventTime to include into sampled snapshot\"); // NOI18N\n            eventTime = ValuesConverter.instantToRelativeNanos(eventTimeI, model);\n            \n            if (profilingEvent) threadInfo = tiSupport.getThreadInfo(thread, stack, event.getString(\"state\")); // NOI18N\n            else threadInfo = tiSupport.getThreadInfo(thread, stack, getState(type));\n        }\n        \n        \n        long getRelativeTime() {\n            return eventTime;\n        }\n        \n        long getThreadId() {\n            return (Long)threadInfo.get(JFRThreadInfoSupport.THREAD_ID);\n        }\n        \n        Map<String, Object> getThreadInfo() {\n            return threadInfo;\n        }\n        \n        boolean isThreadEnd() {\n            return threadInfo.get(JFRThreadInfoSupport.THREAD_STACK) == null;\n        }\n        \n        \n        private static Thread.State getState(String type) {\n            switch (type) {\n                case (\"jdk.JavaMonitorWait\"):   return Thread.State.WAITING;        // NOI18N\n                case (\"jdk.JavaMonitorEnter\"):  return Thread.State.BLOCKED;        // NOI18N\n                case (\"jdk.ThreadPark\"):        return Thread.State.WAITING;        // NOI18N\n                case (\"jdk.ThreadSleep\"):       return Thread.State.TIMED_WAITING;  // NOI18N\n                default:                        return Thread.State.RUNNABLE;\n            }\n        }\n        \n\n        @Override\n        public int compareTo(JFREventWithStack o) {\n            return Long.compare(eventTime, o.eventTime);\n        }\n        \n    }\n    \n    private static class ThreadCPUData {\n        String name;\n        double utilization;\n\n        private ThreadCPUData(String threadName, double utiliz) {\n            name = threadName;\n            utilization = utiliz;\n        }\n    }\n\n    static final class ThreadsCPUViewSupport extends JPanel implements JFREventVisitor {\n        \n        private final boolean hasData;\n        \n        private Map<Long, ThreadCPUData> eventData;\n        \n        private String[] names;\n        private double[] values;\n        \n        private TreadsCPUTableModel tableModel;\n        private ProfilerTable table;\n        \n        \n        ThreadsCPUViewSupport(JFRModel model) {\n            hasData = model.containsEvent(JFRSnapshotSamplerViewProvider.ThreadCPUChecker.class);\n            \n            initComponents();\n        }\n        \n        \n        @Override\n        public void init() {\n            if (hasData) eventData = new HashMap<>();\n        }\n\n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (!hasData) return true;\n            \n            if (JFRSnapshotSamplerViewProvider.EVENT_THREAD_CPU.equals(typeName)) { // NOI18N\n                try {\n                    JFRThread thread = event.getThread(\"eventThread\");\n                    long tid = thread.getId();\n                    String threadName = thread.getName();\n                    double utilization = 100d * (event.getFloat(\"user\") + event.getFloat(\"system\")); // NOI18N\n                    ThreadCPUData cpuData = eventData.get(tid);\n                    if (cpuData == null || cpuData.utilization < utilization)\n                        eventData.put(tid, new ThreadCPUData(threadName, utilization));\n                } catch (JFRPropertyNotAvailableException e) { System.err.println(\">>> \" + e); }\n            }\n            return false;\n        }\n\n        @Override\n        public void done() {\n            if (hasData) SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    names = new String[eventData.size()];\n                    values = new double[eventData.size()];\n\n                    int i = 0;\n                    for (ThreadCPUData cpuData : eventData.values()) {\n                        names[i] = cpuData.name;\n                        values[i++] = cpuData.utilization;\n                    }\n                    \n                    tableModel.fireTableDataChanged();\n\n                    eventData.clear();\n                    eventData = null;\n                }\n            });\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(\n                CPUSamplerViewSupport.class, \"LBL_ThreadAlloc\"), null, 20, this, null); // NOI18N\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            if (!hasData) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.noData(\"Thread CPU load\", JFRSnapshotSamplerViewProvider.ThreadCPUChecker.checkedTypes()), BorderLayout.CENTER);\n            } else {\n                tableModel = new TreadsCPUTableModel();\n                table = new ProfilerTable(tableModel, true, true, null);\n\n                table.setMainColumn(0);\n                table.setFitWidthColumn(0);\n\n                table.setSortColumn(1);\n                table.setDefaultSortOrder(SortOrder.DESCENDING);\n                table.setDefaultSortOrder(0, SortOrder.ASCENDING);\n\n                HideableBarRenderer percentRenderer = new HideableBarRenderer(new PercentRenderer() {\n                    @Override\n                    protected String getValueString(Object value, int row, Format format) {\n                        String s = super.getValueString(value, row, format);\n                        if (s.startsWith(\"(\")) s = s.substring(1, s.length() - 1); // NOI18N\n                        return s;\n                    }\n                });\n\n                LabelRenderer threadRenderer = new LabelRenderer();\n                threadRenderer.setIcon(Icons.getIcon(ProfilerIcons.THREAD));\n                threadRenderer.setFont(threadRenderer.getFont().deriveFont(Font.BOLD));\n\n                table.setColumnRenderer(0, threadRenderer);\n                table.setColumnRenderer(1, percentRenderer);\n\n                percentRenderer.setMaxValue(9999999);\n                table.setDefaultColumnWidth(1, percentRenderer.getOptimalWidth());\n                percentRenderer.setMaxValue(100);\n\n                add(new ProfilerTableContainer(table, false, null), BorderLayout.CENTER);\n            }\n        }\n        \n        \n        private class TreadsCPUTableModel extends AbstractTableModel {\n        \n            public String getColumnName(int columnIndex) {\n                if (columnIndex == 0) {\n                    return \"Thread\";\n                } else if (columnIndex == 1) {\n                    return \"Top Utilization\";\n                }\n\n                return null;\n            }\n\n            public Class<?> getColumnClass(int columnIndex) {\n                if (columnIndex == 0) {\n                    return String.class;\n                } else {\n                    return Double.class;\n                }\n            }\n\n            public int getRowCount() {\n                return names == null ? 0 : names.length;\n            }\n\n            public int getColumnCount() {\n                return 2;\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                if (columnIndex == 0) {\n                    return names[rowIndex];\n                } else if (columnIndex == 1) {\n                    return values[rowIndex];\n                }\n\n                return null;\n            }\n\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/sampler/JFRSnapshotSamplerView.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr.views.sampler;\n\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRSnapshotSamplerView extends JFRViewTab {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/sampler.png\"; // NOI18N\n    \n    \n    JFRSnapshotSamplerView(JFRSnapshot jfrSnapshot) {\n        super(jfrSnapshot, NbBundle.getMessage(JFRSnapshotSamplerView.class, \"LBL_Sampler\"), // NOI18N\n              new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 70);\n\n    }\n    \n    \n    private DataViewComponent dvc;\n    private SamplerViewSupport.MasterViewSupport masterView;\n    private DataViewComponent.DetailsView[] currentDetails;\n    \n    protected DataViewComponent createComponent() {\n        final JFRModel model = getModel();\n        \n        masterView = new SamplerViewSupport.MasterViewSupport(model) {\n            @Override void showCPU() { JFRSnapshotSamplerView.this.showCPU(model); }\n            @Override void showMemory() { JFRSnapshotSamplerView.this.showMemory(model); }\n        };\n        \n        dvc = new DataViewComponent(\n                masterView.getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(model == null));\n        \n        if (model != null) {\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\n                        NbBundle.getMessage(JFRSnapshotSamplerView.class, \"LBL_Summary\"), // NOI18N\n                        false), DataViewComponent.TOP_LEFT);\n            DataViewComponent.DetailsView summaryView = new SamplerViewSupport.SummaryViewSupport(model).getDetailsView();\n            dvc.addDetailsView(summaryView, DataViewComponent.TOP_LEFT);\n            currentDetails = new DataViewComponent.DetailsView[] { summaryView };\n        }\n\n        return dvc;\n    }\n    \n    \n    private void showCPU(JFRModel model) {\n        for (DataViewComponent.DetailsView detail : currentDetails)\n            dvc.removeDetailsView(detail);\n        \n        CPUSamplerViewSupport.CPUViewSupport cpuView = new CPUSamplerViewSupport.CPUViewSupport(model);\n        DataViewComponent.DetailsView cpuViewW = cpuView.getDetailsView();\n        dvc.addDetailsView(cpuViewW, DataViewComponent.TOP_LEFT);\n        \n        CPUSamplerViewSupport.ThreadsCPUViewSupport threadCpuView = new CPUSamplerViewSupport.ThreadsCPUViewSupport(model);\n        DataViewComponent.DetailsView threadsCpuViewW = threadCpuView.getDetailsView();\n        dvc.addDetailsView(threadsCpuViewW, DataViewComponent.TOP_LEFT);\n        \n        currentDetails = new DataViewComponent.DetailsView[] { cpuViewW, threadsCpuViewW };\n        \n        initialize(cpuView, threadCpuView);\n    }\n    \n    private void showMemory(JFRModel model) {\n        for (DataViewComponent.DetailsView detail : currentDetails)\n            dvc.removeDetailsView(detail);\n        \n        MemorySamplerViewSupport.HeapViewSupport heapView = new MemorySamplerViewSupport.HeapViewSupport(model);\n        DataViewComponent.DetailsView heapViewW = heapView.getDetailsView();\n        dvc.addDetailsView(heapViewW, DataViewComponent.TOP_LEFT);\n        \n        MemorySamplerViewSupport.ThreadsMemoryViewSupport threadsMemoryView = new MemorySamplerViewSupport.ThreadsMemoryViewSupport(model);\n        DataViewComponent.DetailsView threadsMemoryViewW = threadsMemoryView.getDetailsView();\n        dvc.addDetailsView(threadsMemoryViewW, DataViewComponent.TOP_LEFT);\n        \n        currentDetails = new DataViewComponent.DetailsView[] { heapViewW, threadsMemoryViewW };\n        \n        initialize(heapView, threadsMemoryView);\n    }\n    \n    \n    private void initialize(JFREventVisitor... visitors) {\n        new RequestProcessor(\"JFR Sampler Initializer\").post(new Runnable() { // NOI18N\n            public void run() {\n                masterView.showProgress();\n                getModel().visitEvents(visitors);\n                masterView.hideProgress();\n            }\n        });\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/sampler/JFRSnapshotSamplerViewProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr.views.sampler;\n\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREventChecker;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.jfr.view.JFRViewTabProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=JFRViewTabProvider.class)\npublic final class JFRSnapshotSamplerViewProvider extends JFRViewTabProvider {\n    \n    static final String EVENT_EXECUTION_SAMPLE = \"jdk.ExecutionSample\"; // NOI18N\n    static final String EVENT_NATIVE_SAMPLE = \"jdk.NativeMethodSample\"; // NOI18N\n    static final String EVENT_THREAD_CPU = \"jdk.ThreadCPULoad\"; // NOI18N\n    static final String EVENT_OBJECT_COUNT = \"jdk.ObjectCount\"; // NOI18N\n    static final String EVENT_THREAD_ALLOCATIONS = \"jdk.ThreadAllocationStatistics\"; // NOI18N\n    \n    \n    protected JFRViewTab createView(JFRSnapshot jfrSnapshot) {\n        return new JFRSnapshotSamplerView(jfrSnapshot);\n    }\n    \n    \n//    @ServiceProvider(service=JFREventChecker.class)\n//    public static final class CPUSampleChecker extends JFREventChecker {\n//        \n//        public CPUSampleChecker() {\n//            super(checkedTypes());\n//        }\n//        \n//        static String[] checkedTypes() {\n//            return new String[] { EVENT_EXECUTION_SAMPLE, EVENT_NATIVE_SAMPLE };\n//        }\n//        \n//    }\n    \n    @ServiceProvider(service=JFREventChecker.class)\n    public static final class ThreadCPUChecker extends JFREventChecker {\n        \n        public ThreadCPUChecker() {\n            super(checkedTypes());\n        }\n        \n        static String[] checkedTypes() {\n            return new String[] { EVENT_THREAD_CPU };\n        }\n        \n    }    \n    \n    @ServiceProvider(service=JFREventChecker.class)\n    public static final class ObjectCountChecker extends JFREventChecker {\n        \n        public ObjectCountChecker() {\n            super(checkedTypes());\n        }\n        \n        static String[] checkedTypes() {\n            return new String[] { EVENT_OBJECT_COUNT };\n        }\n        \n    }\n    \n    @ServiceProvider(service=JFREventChecker.class)\n    public static final class ThreadAllocationsChecker extends JFREventChecker {\n        \n        public ThreadAllocationsChecker() {\n            super(checkedTypes());\n        }\n        \n        static String[] checkedTypes() {\n            return new String[] { EVENT_THREAD_ALLOCATIONS };\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/sampler/JFRThreadInfoSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.sampler;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.jfr.model.JFRMethod;\nimport org.graalvm.visualvm.jfr.model.JFRStackFrame;\nimport org.graalvm.visualvm.jfr.model.JFRStackTrace;\nimport org.graalvm.visualvm.jfr.model.JFRThread;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRThreadInfoSupport {\n    \n    static final String THREAD_ID = \"tid\"; // NOI18N\n    static final String THREAD_STACK = \"stack\"; // NOI18N\n    \n    private final Map<StackTraceElement,StackTraceElement> cache;\n\n    JFRThreadInfoSupport() {\n        cache = new HashMap<>();\n    }\n\n    Map<String,Object> getThreadInfo(JFRThread thread, JFRStackTrace stack, String state) {\n        return getThreadInfo(thread, stack, state(state));\n    }\n    \n    Map<String,Object> getThreadInfo(JFRThread thread, JFRStackTrace stack, Thread.State state) {\n        Map<String,Object> threadInfo = new HashMap<>();\n        \n        Long id = Long.valueOf(thread.getId());\n        threadInfo.put(THREAD_ID, id);\n        \n        if (stack != null) {\n            threadInfo.put(THREAD_STACK, stackTrace(stack));\n            threadInfo.put(\"name\", thread.getName()); // NOI18N\n            threadInfo.put(\"state\", state); // NOI18N\n        }\n\n        return threadInfo;\n    }\n    \n    \n    private StackTraceElement[] stackTrace(JFRStackTrace stack) {\n        List<JFRStackFrame> frames = stack.getFrames();\n        StackTraceElement[] elements = new StackTraceElement[frames.size()];\n        \n        for (int i = 0; i < frames.size(); i++)\n            elements[i] = stackTraceElement(frames.get(i));\n        \n        return elements;\n    }\n    \n    private StackTraceElement stackTraceElement(JFRStackFrame frame) {\n        JFRMethod method = frame.getMethod();\n        \n        String className = method == null ? null : method.getType().getName(); // NOI18N\n        String methodName = method == null ? null : method.getName(); // TODO: add signature! // NOI18N\n        \n        if (className == null) className = \"<unknown class>\";\n        if (methodName == null) methodName = \"<unknown method>\";\n        \n        int lineNumber = \"Native\".equals(frame.getType()) ? -2 : frame.getLine(); // NOI18N\n        \n        StackTraceElement el = new StackTraceElement(className, methodName, null, lineNumber);\n        return cache.computeIfAbsent(el, v -> el);\n    }\n    \n    private static Thread.State state(String state) {\n        if (\"STATE_RUNNABLE\".equals(state)) return Thread.State.RUNNABLE; // NOI18N\n        return Thread.State.WAITING; // safe fallback, no other states seem to be used for jdk.ExecutionSample and jdk.NativeMethodSample\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/sampler/MemorySamplerViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.sampler;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.LayoutManager;\nimport java.awt.event.ActionEvent;\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.InputMap;\nimport javax.swing.JComponent;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.jfr.model.JFRThread;\nimport org.graalvm.visualvm.jfr.views.components.MessageComponent;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class MemorySamplerViewSupport {\n    \n    static final class HeapViewSupport extends JPanel implements JFREventVisitor {\n        \n        private final boolean hasData;\n        \n        private Map<String, Long[]> eventData;\n        \n        private String[] names;\n        private long[] sizes;\n        private long[] counts;\n        \n        private HeapTableModel tableModel;\n        private ProfilerTable table;\n        private HideableBarRenderer[] renderers;\n        \n        private JComponent bottomPanel;\n        private JComponent filterPanel;\n        private JComponent searchPanel;\n        \n        \n        HeapViewSupport(JFRModel model) {\n            hasData = model.containsEvent(JFRSnapshotSamplerViewProvider.ObjectCountChecker.class);\n            \n            initComponents();\n        }\n        \n        \n        @Override\n        public void init() {\n            if (hasData) eventData = new HashMap<>();\n        }\n\n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (!hasData) return true;\n            \n            if (JFRSnapshotSamplerViewProvider.EVENT_OBJECT_COUNT.equals(typeName)) {\n                try {\n                    eventData.put(event.getClass(\"objectClass\").getName(), new Long[] { event.getLong(\"totalSize\"), event.getLong(\"count\") }); // NOI18N\n                } catch (JFRPropertyNotAvailableException e) {\n                    System.err.println(\">>> \" + e);\n                }\n            }\n            return false;\n        }\n\n        @Override\n        public void done() {\n            if (hasData) SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    long total1 = 0, total2 = 0;\n                    long max1 = 0, max2 = 0;\n                    \n                    names = new String[eventData.size()];\n                    sizes = new long[eventData.size()];\n                    counts = new long[eventData.size()];\n\n                    int i = 0;\n                    for (Map.Entry<String, Long[]> entry : eventData.entrySet()) {\n                        names[i] = decodeClassName(entry.getKey());\n                        sizes[i] = entry.getValue()[0];\n                        counts[i] = entry.getValue()[1];\n                        max1 = Math.max(sizes[i], max1);\n                        total1 += sizes[i];\n                        max2 = Math.max(counts[i], max2);\n                        total2 += counts[i];\n                        i++;\n                    }\n                    \n                    renderers[0].setMaxValue(max1);\n                    table.setDefaultColumnWidth(1, renderers[0].getOptimalWidth());\n                    renderers[0].setMaxValue(total1);\n                    \n                    renderers[1].setMaxValue(max2);\n                    table.setDefaultColumnWidth(2, renderers[1].getOptimalWidth());\n                    renderers[1].setMaxValue(total2);\n                    \n                    tableModel.fireTableDataChanged();\n\n                    eventData.clear();\n                    eventData = null;\n                }\n            });\n        }\n        \n        private static String decodeClassName(String className) {\n            className = StringUtils.userFormClassName(className);\n            \n            if (className.startsWith(\"L\") && className.contains(\";\")) // NOI18N\n                className = className.substring(1).replace(\";\", \"\"); // NOI18N\n            \n            return className;\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(\n                CPUSamplerViewSupport.class, \"LBL_Heap_histogram\"), null, 10, this, null); // NOI18N\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            if (!hasData) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.noData(\"Heap histogram\", JFRSnapshotSamplerViewProvider.ObjectCountChecker.checkedTypes()), BorderLayout.CENTER);\n            } else {\n                tableModel = new HeapTableModel();\n                table = new ProfilerTable(tableModel, true, true, null) {\n                    protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                        final String selectedClass = value == null ? null : value.toString();\n\n                        if (GoToSource.isAvailable()) {\n                            popup.add(new JMenuItem(NbBundle.getMessage(MemorySamplerViewSupport.class, \"MemoryView_Context_GoToSource\")) { // NOI18N\n                                { setEnabled(selectedClass != null); setFont(getFont().deriveFont(Font.BOLD)); }\n                                protected void fireActionPerformed(ActionEvent e) { GoToSource.openSource(null, selectedClass, null, null); }\n                            });\n                            popup.addSeparator();\n                        }\n\n                        popup.add(createCopyMenuItem());\n                        popup.addSeparator();\n\n                        popup.add(new JMenuItem(FilterUtils.ACTION_FILTER) {\n                            protected void fireActionPerformed(ActionEvent e) { HeapViewSupport.this.activateFilter(); }\n                        });\n                        popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {\n                            protected void fireActionPerformed(ActionEvent e) { HeapViewSupport.this.activateSearch(); }\n                        });\n                    }\n                };\n                \n                table.providePopupMenu(true);\n\n                table.setMainColumn(0);\n                table.setFitWidthColumn(0);\n\n                table.setSortColumn(1);\n                table.setDefaultSortOrder(SortOrder.DESCENDING);\n                table.setDefaultSortOrder(0, SortOrder.ASCENDING);\n\n                renderers = new HideableBarRenderer[2];\n                renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(Formatters.bytesFormat()));\n                renderers[1] = new HideableBarRenderer(new NumberPercentRenderer());\n\n                JavaNameRenderer classRenderer = new JavaNameRenderer(Icons.getIcon(LanguageIcons.CLASS));\n\n                table.setColumnRenderer(0, classRenderer);\n                table.setColumnRenderer(1, renderers[0]);\n                table.setColumnRenderer(2, renderers[1]);\n\n                add(new ProfilerTableContainer(table, false, null), BorderLayout.CENTER);\n                \n                InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n                ActionMap actionMap = getActionMap();\n\n                final String filterKey = FilterUtils.FILTER_ACTION_KEY;\n                Action filterAction = new AbstractAction() {\n                    public void actionPerformed(ActionEvent e) {\n                        HeapViewSupport.this.activateFilter();\n                    }\n                };\n                ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);\n\n                final String findKey = SearchUtils.FIND_ACTION_KEY;\n                Action findAction = new AbstractAction() {\n                    public void actionPerformed(ActionEvent e) {\n                        HeapViewSupport.this.activateSearch();\n                    }\n                };\n                ActionsSupport.registerAction(findKey, findAction, actionMap, inputMap);\n\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { SearchUtils.enableSearchActions(table); }\n                });\n            }\n        }\n        \n        private JComponent getBottomPanel() {\n            if (bottomPanel == null) {\n                bottomPanel = new JPanel(new FilterFindLayout());\n                bottomPanel.setOpaque(true);\n                bottomPanel.setBackground(UIManager.getColor(\"controlShadow\")); // NOI18N\n                add(bottomPanel, BorderLayout.SOUTH);\n            }\n            return bottomPanel;\n        }\n        \n        private void activateFilter() {\n            JComponent panel = getBottomPanel();\n\n            if (filterPanel == null) {\n                filterPanel = FilterUtils.createFilterPanel(table, null);\n                panel.add(filterPanel);\n                Container parent = panel.getParent();\n                parent.invalidate();\n                parent.revalidate();\n                parent.repaint();\n            }\n\n            panel.setVisible(true);\n\n            filterPanel.setVisible(true);\n            filterPanel.requestFocusInWindow();\n        }\n\n        private void activateSearch() {\n            JComponent panel = getBottomPanel();\n\n            if (searchPanel == null) {\n                searchPanel = SearchUtils.createSearchPanel(table);\n                panel.add(searchPanel);\n                Container parent = panel.getParent();\n                parent.invalidate();\n                parent.revalidate();\n                parent.repaint();\n            }\n\n            panel.setVisible(true);\n\n            searchPanel.setVisible(true);\n            searchPanel.requestFocusInWindow();\n        }\n        \n        \n        private final class FilterFindLayout implements LayoutManager {\n\n            public void addLayoutComponent(String name, Component comp) {}\n            public void removeLayoutComponent(Component comp) {}\n\n            public Dimension preferredLayoutSize(Container parent) {\n                JComponent filter = filterPanel;\n                if (filter != null && !filter.isVisible()) filter = null;\n\n                JComponent search = searchPanel;\n                if (search != null && !search.isVisible()) search = null;\n\n                Dimension dim = new Dimension();\n\n                if (filter != null && search != null) {\n                    Dimension dim1 = filter.getPreferredSize();\n                    Dimension dim2 = search.getPreferredSize();\n                    dim.width = dim1.width + dim2.width + 1;\n                    dim.height = Math.max(dim1.height, dim2.height);\n                } else if (filter != null) {\n                    dim = filter.getPreferredSize();\n                } else if (search != null) {\n                    dim = search.getPreferredSize();\n                }\n\n                if ((filter != null || search != null) /*&& hasBottomFilterFindMargin()*/)\n                    dim.height += 1;\n\n                return dim;\n            }\n\n            public Dimension minimumLayoutSize(Container parent) {\n                JComponent filter = filterPanel;\n                if (filter != null && !filter.isVisible()) filter = null;\n\n                JComponent search = searchPanel;\n                if (search != null && !search.isVisible()) search = null;\n\n                Dimension dim = new Dimension();\n\n                if (filter != null && search != null) {\n                    Dimension dim1 = filter.getMinimumSize();\n                    Dimension dim2 = search.getMinimumSize();\n                    dim.width = dim1.width + dim2.width + 1;\n                    dim.height = Math.max(dim1.height, dim2.height);\n                } else if (filter != null) {\n                    dim = filter.getMinimumSize();\n                } else if (search != null) {\n                    dim = search.getMinimumSize();\n                }\n\n                if ((filter != null || search != null) /*&& hasBottomFilterFindMargin()*/)\n                    dim.height += 1;\n\n                return dim;\n            }\n\n            public void layoutContainer(Container parent) {\n                JComponent filter = filterPanel;\n                if (filter != null && !filter.isVisible()) filter = null;\n\n                JComponent search = searchPanel;\n                if (search != null && !search.isVisible()) search = null;\n\n                int bottomOffset = /* hasBottomFilterFindMargin() ? 1 :*/ 0;\n\n                if (filter != null && search != null) {\n                    Dimension size = parent.getSize();\n                    int w = (size.width - 1) / 2;\n                    filter.setBounds(0, 0, w, size.height - bottomOffset);\n                    search.setBounds(w + 1, 0, size.width - w - 1, size.height - bottomOffset);\n                } else if (filter != null) {\n                    Dimension size = parent.getSize();\n                    filter.setBounds(0, 0, size.width, size.height - bottomOffset);\n                } else if (search != null) {\n                    Dimension size = parent.getSize();\n                    search.setBounds(0, 0, size.width, size.height - bottomOffset);\n                }\n            }\n\n        }\n        \n        \n        private class HeapTableModel extends AbstractTableModel {\n        \n            public String getColumnName(int columnIndex) {\n                if (columnIndex == 0) {\n                    return \"Name\";\n                } else if (columnIndex == 1) {\n                    return \"Bytes\";\n                } else if (columnIndex == 2) {\n                    return \"Objects\";\n                }\n\n                return null;\n            }\n\n            public Class<?> getColumnClass(int columnIndex) {\n                if (columnIndex == 0) {\n                    return String.class;\n                } else {\n                    return Long.class;\n                }\n            }\n\n            public int getRowCount() {\n                return names == null ? 0 : names.length;\n            }\n\n            public int getColumnCount() {\n                return 3;\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                if (columnIndex == 0) {\n                    return names[rowIndex];\n                } else if (columnIndex == 1) {\n                    return sizes[rowIndex];\n                } else if (columnIndex == 2) {\n                    return counts[rowIndex];\n                }\n\n                return null;\n            }\n\n        }\n        \n    }\n    \n    private static class ThreadAllocData {\n        String name;\n        long allocatedBytes;\n\n        private ThreadAllocData(String threadName, long allocBytes) {\n            name = threadName;\n            allocatedBytes = allocBytes;\n        }\n    }\n    \n    static final class ThreadsMemoryViewSupport extends JPanel implements JFREventVisitor {\n        \n        private final boolean hasData;\n        \n        private Map<Long, ThreadAllocData> eventData;\n        \n        private String[] names;\n        private long[] values;\n        \n        private TreadsAllocTableModel tableModel;\n        private ProfilerTable table;\n        private HideableBarRenderer[] renderers;\n        \n        \n        ThreadsMemoryViewSupport(JFRModel model) {\n            hasData = model.containsEvent(JFRSnapshotSamplerViewProvider.ThreadAllocationsChecker.class);\n            \n            initComponents();\n        }\n        \n        \n        @Override\n        public void init() {\n            if (hasData) eventData = new HashMap<>();\n        }\n\n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            if (!hasData) return true;\n            \n            if (JFRSnapshotSamplerViewProvider.EVENT_THREAD_ALLOCATIONS.equals(typeName)) { // NOI18N\n                try {\n                    JFRThread thread = event.getThread(\"thread\"); // NOI18N\n                    if (thread != null) {\n                        long tid = thread.getId();\n                        String threadName = thread.getName();\n                        long allocated = event.getLong(\"allocated\"); // NOI18N\n                        ThreadAllocData allocData = eventData.get(tid);\n                        if (allocData == null || allocData.allocatedBytes < allocated)\n                            eventData.put(tid, new ThreadAllocData(threadName, allocated));\n                    }\n                } catch (JFRPropertyNotAvailableException e) {}\n            }\n            return false;\n        }\n\n        @Override\n        public void done() {\n            if (hasData) SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    long total = 0;\n                    long max = 0;\n                    \n                    names = new String[eventData.size()];\n                    values = new long[eventData.size()];\n\n                    int i = 0;\n                    for (ThreadAllocData allocData : eventData.values()) {\n                        names[i] = allocData.name;\n                        values[i] = allocData.allocatedBytes;\n                        max = Math.max(values[i], max);\n                        total += values[i++];\n                    }\n                    \n                    renderers[0].setMaxValue(max);\n                    table.setDefaultColumnWidth(1, renderers[0].getOptimalWidth());\n                    renderers[0].setMaxValue(total);\n                    \n                    tableModel.fireTableDataChanged();\n\n                    eventData.clear();\n                    eventData = null;\n                }\n            });\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(\n                MemorySamplerViewSupport.class, \"LBL_ThreadAlloc_M\"), null, 20, this, null); // NOI18N\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n            \n            if (!hasData) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.noData(\"Per thread allocations\", JFRSnapshotSamplerViewProvider.ThreadAllocationsChecker.checkedTypes()), BorderLayout.CENTER);\n            } else {\n                tableModel = new TreadsAllocTableModel();\n                table = new ProfilerTable(tableModel, true, true, null);\n\n                table.setMainColumn(0);\n                table.setFitWidthColumn(0);\n\n                table.setSortColumn(1);\n                table.setDefaultSortOrder(SortOrder.DESCENDING);\n                table.setDefaultSortOrder(0, SortOrder.ASCENDING);\n\n                renderers = new HideableBarRenderer[1];\n                renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(Formatters.bytesFormat()));\n\n                LabelRenderer threadRenderer = new LabelRenderer();\n                threadRenderer.setIcon(Icons.getIcon(ProfilerIcons.THREAD));\n                threadRenderer.setFont(threadRenderer.getFont().deriveFont(Font.BOLD));\n\n                table.setColumnRenderer(0, threadRenderer);\n                table.setColumnRenderer(1, renderers[0]);\n\n                add(new ProfilerTableContainer(table, false, null), BorderLayout.CENTER);\n            }\n        }\n        \n        \n        private class TreadsAllocTableModel extends AbstractTableModel {\n        \n            public String getColumnName(int columnIndex) {\n                if (columnIndex == 0) {\n                    return \"Thread\";\n                } else if (columnIndex == 1) {\n                    return \"Allocated\";\n                }\n\n                return null;\n            }\n\n            public Class<?> getColumnClass(int columnIndex) {\n                if (columnIndex == 0) {\n                    return String.class;\n                } else {\n                    return Long.class;\n                }\n            }\n\n            public int getRowCount() {\n                return names == null ? 0 : names.length;\n            }\n\n            public int getColumnCount() {\n                return 2;\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                if (columnIndex == 0) {\n                    return names[rowIndex];\n                } else if (columnIndex == 1) {\n                    return values[rowIndex];\n                }\n\n                return null;\n            }\n\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/sampler/SamplerViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.sampler;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.ImageIcon;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.views.components.MessageComponent;\nimport org.graalvm.visualvm.lib.ui.components.HTMLLabel;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class SamplerViewSupport {\n    \n    static abstract class MasterViewSupport extends JPanel {\n        \n        MasterViewSupport(JFRModel model) {\n            initComponents(model);\n        }\n        \n        \n        DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(SamplerViewSupport.class, \"LBL_Sampler\"), null, this); // NOI18N\n        }\n        \n        \n        abstract void showCPU();\n        \n        abstract void showMemory();\n        \n        \n        void showProgress() {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    statusValueLabel.setVisible(true);\n                    cpuButton.setEnabled(false);\n                    memoryButton.setEnabled(false);\n                }\n            });\n        }\n        \n        void hideProgress() {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    statusValueLabel.setVisible(false);\n                    cpuButton.setEnabled(true);\n                    memoryButton.setEnabled(true);\n                }\n            });\n        }\n        \n        \n        private void handleCPUData() {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n//                    System.err.println(\">>> handleCPUData\");\n                    memoryButton.setSelected(false);\n                    showCPU();\n//                    memoryButton.invalidate();\n//                    memoryButton.setEnabled(false);\n//                    memoryButton.setEnabled(true);\n                }\n            });\n        }\n        \n        private void handleMemoryData() {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n//                    System.err.println(\">>> handleMemoryData\");\n                    cpuButton.setSelected(false);\n                    showMemory();\n//                    cpuButton.invalidate();\n//                    cpuButton.setEnabled(false);\n//                    cpuButton.setEnabled(true);\n                }\n            });\n        }\n        \n        \n        private void initComponents(JFRModel model) {\n            setOpaque(false);\n            \n            if (model == null) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.notAvailable(), BorderLayout.CENTER);\n            } else {\n                setLayout(new GridBagLayout());\n                setBorder(BorderFactory.createEmptyBorder(11, 5, 20, 5));\n\n                GridBagConstraints constraints;\n\n                // modeLabel\n                modeLabel = new JLabel(NbBundle.getMessage(SamplerViewSupport.class, \"LBL_Profile\")); // NOI18N\n                modeLabel.setFont(modeLabel.getFont().deriveFont(Font.BOLD));\n                Dimension d = modeLabel.getPreferredSize();\n                modeLabel.setText(NbBundle.getMessage(SamplerViewSupport.class, \"LBL_Sample\")); // NOI18N\n                d.width = Math.max(d.width, modeLabel.getPreferredSize().width);\n                modeLabel.setPreferredSize(d);\n                modeLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 0;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(modeLabel, constraints);\n\n                // cpuButton\n                cpuButton = new OneWayToggleButton(NbBundle.getMessage(SamplerViewSupport.class, \"LBL_Cpu\")); // NOI18N\n                cpuButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/sampler/resources/cpu.png\", true))); // NOI18N\n                cpuButton.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleCPUData(); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 2;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(cpuButton, constraints);\n\n                // memoryButton\n                memoryButton = new OneWayToggleButton(NbBundle.getMessage(SamplerViewSupport.class, \"LBL_Memory\")); // NOI18N\n                memoryButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/sampler/resources/memory.png\", true))); // NOI18N\n                memoryButton.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleMemoryData(); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 3;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(memoryButton, constraints);\n\n                // statusValueLabel\n                statusValueLabel = new HTMLLabel(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n    //            stopButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/sampler/resources/stop.png\", true))); // NOI18N\n    //            stopButton.addActionListener(new ActionListener() {\n    //                public void actionPerformed(ActionEvent e) { handleStopProfiling(); }\n    //            });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 4;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 20, 0, 0);\n                add(statusValueLabel, constraints);\n                statusValueLabel.setVisible(false);\n\n                // filler1\n                constraints = new GridBagConstraints();\n                constraints.gridx = 5;\n                constraints.gridy = 2;\n                constraints.weightx = 1;\n                constraints.weighty = 1;\n                constraints.gridwidth = GridBagConstraints.REMAINDER;\n                constraints.fill = GridBagConstraints.BOTH;\n                constraints.anchor = GridBagConstraints.NORTHWEST;\n                constraints.insets = new Insets(0, 0, 0, 0);\n                add(Spacer.create(), constraints);\n\n    //            // statusLabel\n    //            statusLabel = new JLabel(NbBundle.getMessage(SamplerViewSupport.class, \"LBL_Status\")); // NOI18N\n    //            statusLabel.setFont(statusLabel.getFont().deriveFont(Font.BOLD));\n    //            statusLabel.setOpaque(false);\n    //            constraints = new GridBagConstraints();\n    //            constraints.gridx = 0;\n    //            constraints.gridy = 3;\n    //            constraints.gridwidth = 1;\n    //            constraints.fill = GridBagConstraints.NONE;\n    //            constraints.anchor = GridBagConstraints.WEST;\n    //            constraints.insets = new Insets(6, 8, 4, 0);\n    //            add(statusLabel, constraints);\n\n    //            // statusValueLabel\n    //            statusValueLabel = new HTMLLabel() {\n    //                public void setText(String text) {super.setText(\"<nobr>\" + text + \"</nobr>\"); } // NOI18N\n    //                protected void showURL(URL url) {}\n    //\n    //                // NOTE: overriding dimensions prevents UI \"jumping\" when changing the link\n    //                public Dimension getPreferredSize() {\n    //                    Dimension dim = super.getPreferredSize();\n    //                    dim.height = getRefLabelHeight();\n    //                    return dim;\n    //                }\n    //                public Dimension getMinimumSize() { return getPreferredSize(); }\n    //                public Dimension getMaximumSize() { return getPreferredSize(); }\n    //            };\n    //            statusValueLabel.setOpaque(false);\n    //            statusValueLabel.setFocusable(false);\n    //            constraints = new GridBagConstraints();\n    //            constraints.gridx = 1;\n    //            constraints.gridy = 3;\n    //            constraints.gridwidth = GridBagConstraints.REMAINDER;\n    //            constraints.fill = GridBagConstraints.NONE;\n    //            constraints.anchor = GridBagConstraints.WEST;\n    //            constraints.insets = new Insets(6, 8, 4, 8);\n    //            add(statusValueLabel, constraints);\n\n    //            // filler2\n    //            constraints = new GridBagConstraints();\n    //            constraints.gridx = 2;\n    //            constraints.gridy = 3;\n    //            constraints.weightx = 1;\n    //            constraints.weighty = 1;\n    //            constraints.gridwidth = GridBagConstraints.REMAINDER;\n    //            constraints.fill = GridBagConstraints.BOTH;\n    //            constraints.anchor = GridBagConstraints.NORTHWEST;\n    //            constraints.insets = new Insets(0, 0, 0, 0);\n    //            add(Spacer.create(), constraints);\n\n                Dimension cpuD     = cpuButton.getPreferredSize();\n                Dimension memoryD  = memoryButton.getPreferredSize();\n    //            Dimension stopD    = stopButton.getPreferredSize();\n\n                Dimension maxD = new Dimension(Math.max(cpuD.width, memoryD.width), Math.max(cpuD.height, memoryD.height));\n    //            maxD = new Dimension(Math.max(maxD.width, stopD.width), Math.max(maxD.height, stopD.height));\n\n                cpuButton.setPreferredSize(maxD);\n                cpuButton.setMinimumSize(maxD);\n                memoryButton.setPreferredSize(maxD);\n                memoryButton.setMinimumSize(maxD);\n    //            stopButton.setPreferredSize(maxD);\n    //            stopButton.setMinimumSize(maxD);\n            }\n        }\n\n        private JLabel modeLabel;\n        private JToggleButton cpuButton;\n        private JToggleButton memoryButton;\n//        private JButton stopButton;\n//        private JLabel statusLabel;\n        private HTMLLabel statusValueLabel;\n\n//        private static int refLabelHeight = -1;\n//        private static int getRefLabelHeight() {\n//            if (refLabelHeight == -1)\n//                refLabelHeight = new HTMLLabel(\"X\").getPreferredSize().height; // NOI18N\n//            return refLabelHeight;\n//        }\n\n\n        private static final class OneWayToggleButton extends JToggleButton {\n\n            OneWayToggleButton(String text) {\n                super(text);\n            }\n\n            protected void processMouseEvent(MouseEvent e) {\n                if (!isSelected() || MouseEvent.MOUSE_EXITED == e.getID()) super.processMouseEvent(e);\n            }\n\n            protected void processKeyEvent(KeyEvent e) {\n                if (!isSelected()) super.processKeyEvent(e);\n            }\n\n        }\n        \n    }\n    \n    \n    static final class SummaryViewSupport extends JPanel {\n        \n        SummaryViewSupport(JFRModel model) {\n            super(new BorderLayout());\n            \n            HTMLTextArea summaryArea = new HTMLTextArea(getSummary(model));\n            summaryArea.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n            add(summaryArea, BorderLayout.CENTER);\n        }\n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(\n                        SamplerViewSupport.class, \"LBL_Summary\"), null, 10, // NOI18N\n                        new ScrollableContainer(this), null);\n        }\n        \n        private String getSummary(JFRModel model) {\n            StringBuilder builder = new StringBuilder();\n\n            addCpuHeader(builder);\n            builder.append(\"CPU samples \");\n            builder.append(\"available.\"); // all events used, let's assume some of them contain stack traces\n//            builder.append(model.containsEvent(JFRSnapshotSamplerViewProvider.CPUSampleChecker.class) ? \"available.\" : \"not recorded.\");\n            builder.append(\" \");\n            builder.append(\"Thread CPU load \");\n            builder.append(model.containsEvent(JFRSnapshotSamplerViewProvider.ThreadCPUChecker.class) ? \"available.\" : \"not recorded.\");\n\n            addMemoryHeader(builder);\n            builder.append(\"Heap histogram \");\n            builder.append(model.containsEvent(JFRSnapshotSamplerViewProvider.ObjectCountChecker.class) ? \"available.\" : \"not recorded.\");\n            builder.append(\" \");\n            builder.append(\"Per thread allocations \");\n            builder.append(model.containsEvent(JFRSnapshotSamplerViewProvider.ThreadAllocationsChecker.class) ? \"available.\" : \"not recorded.\");\n            \n            return builder.toString();\n        }\n\n        private static void addCpuHeader(StringBuilder builder) {\n            builder.append(NbBundle.getMessage(SamplerViewSupport.class, \"LBL_Cpu_sampling\")); // NOI18N\n        }\n\n        private static void addMemoryHeader(StringBuilder builder) {\n            builder.append(NbBundle.getMessage(SamplerViewSupport.class, \"LBL_Memory_sampling\")); // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/socketio/JFRSnapshotSocketIOView.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.socketio;\n\nimport javax.swing.ImageIcon;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRSnapshotSocketIOView extends JFRViewTab {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/socketio.png\"; // NOI18N\n    \n    \n    JFRSnapshotSocketIOView(JFRSnapshot jfrSnapshot) {\n        super(jfrSnapshot, \"Socket IO\", new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 40);\n\n    }\n    \n    \n    private DataViewComponent dvc;\n    private SocketIOViewSupport.MasterViewSupport masterView;\n    private SocketIOViewSupport.DataViewSupport dataView;\n    \n    \n    protected DataViewComponent createComponent() {\n        JFRModel model = getModel();\n        \n        masterView = new SocketIOViewSupport.MasterViewSupport(model) {\n            @Override\n            void firstShown() {\n                changeAggregation(SocketIOViewSupport.Aggregation.ADDRESS_PORT, SocketIOViewSupport.Aggregation.NONE);\n            }\n            @Override\n            void changeAggregation(SocketIOViewSupport.Aggregation primary, SocketIOViewSupport.Aggregation secondary) {\n                JFRSnapshotSocketIOView.this.setAggregation(primary, secondary);\n            }\n        };\n        \n        boolean hasEvents = model != null && model.containsEvent(JFRSnapshotSocketIOViewProvider.EventChecker.class);\n        \n        dvc = new DataViewComponent(\n                masterView.getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(!hasEvents));\n        \n        if (hasEvents) {\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\"Data\", false), DataViewComponent.TOP_LEFT);\n\n            dataView = new SocketIOViewSupport.DataViewSupport();\n            dvc.addDetailsView(dataView.getDetailsView(), DataViewComponent.TOP_LEFT);\n        }\n\n        return dvc;\n    }\n    \n    \n    private void setAggregation(final SocketIOViewSupport.Aggregation primary, final SocketIOViewSupport.Aggregation secondary) {\n        masterView.showProgress();\n        dataView.setData(new SocketIONode.Root(), false);\n        \n        new RequestProcessor(\"JFR SocketIO Initializer\").post(new Runnable() { // NOI18N\n            public void run() {\n                final SocketIONode.Root root = new SocketIONode.Root(primary, secondary);\n                getModel().visitEvents(root);\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        dataView.setData(root, !SocketIOViewSupport.Aggregation.NONE.equals(secondary));\n                        masterView.hideProgress();\n                    }\n                });\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/socketio/JFRSnapshotSocketIOViewProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.socketio;\n\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFREventChecker;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.jfr.view.JFRViewTabProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=JFRViewTabProvider.class)\npublic final class JFRSnapshotSocketIOViewProvider extends JFRViewTabProvider {\n    \n    static final String EVENT_SOCKET_READ = \"jdk.SocketRead\"; // NOI18N\n    static final String EVENT_SOCKET_WRITE = \"jdk.SocketWrite\"; // NOI18N\n    \n    \n    protected JFRViewTab createView(JFRSnapshot jfrSnapshot) {\n        return new JFRSnapshotSocketIOView(jfrSnapshot);\n    }\n    \n    \n    @ServiceProvider(service=JFREventChecker.class)\n    public static final class EventChecker extends JFREventChecker {\n        \n        public EventChecker() {\n            super(checkedTypes());\n        }\n        \n        static String[] checkedTypes() {\n            return new String[] {\n                EVENT_SOCKET_READ, EVENT_SOCKET_WRITE\n            };\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/socketio/SocketIONode.java",
    "content": "/*\n * Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.socketio;\n\nimport java.time.Duration;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class SocketIONode extends CCTNode {\n    \n    private static final String UNKNOWN = \"<unknown>\";\n    private static final SocketIONode[] NO_NODES = new SocketIONode[0];\n    \n    private final SocketIONode parent;\n    private final List<SocketIONode> children;\n    \n    final String key;\n    String name;\n    final Icon icon;\n    \n    long countR, countW = 0;\n    long bytesR, bytesW = 0;\n    Duration durationR, durationRMax, durationW, durationWMax;\n    \n    \n    SocketIONode(String key, String name, Icon icon, SocketIONode parent, List<SocketIONode> children) {\n        this.key = key;\n        this.parent = parent;\n        this.children = children;\n        \n        this.name = name;\n        this.icon = icon;\n    }\n    \n    \n    final void processRead(Duration duration, long bytes) {\n        if (parent != null) {\n            countR++;\n            bytesR += bytes;\n            if (durationR == null) durationR = duration; else durationR = durationR.plus(duration);\n            if (durationRMax == null || durationRMax.compareTo(duration) < 0) durationRMax = duration;\n            \n            parent.processRead(duration, bytes);\n        }\n    }\n    \n    final void processWrite(Duration duration, long bytes) {\n        if (parent != null) {\n            countW++;\n            bytesW += bytes;\n            if (durationW == null) durationW = duration; else durationW = durationW.plus(duration);\n            if (durationWMax == null || durationWMax.compareTo(duration) < 0) durationWMax = duration;\n            \n            parent.processWrite(duration, bytes);\n        }\n    }\n    \n    \n    SocketIONode getChild(String key) {\n        if (children != null)\n            for (SocketIONode child : children)\n                if (Objects.equals(key, child.key))\n                    return child;\n        return null;\n    }\n    \n    \n    @Override\n    public SocketIONode getChild(int index) {\n        return children == null ? null : children.get(index);\n    }\n\n    @Override\n    public SocketIONode[] getChildren() {\n        return children == null ? NO_NODES : children.toArray(NO_NODES);\n    }\n\n    @Override\n    public int getIndexOfChild(Object child) {\n        return children == null ? -1 : children.indexOf(child);\n    }\n\n    @Override\n    public int getNChildren() {\n        return children == null ? 0 : children.size();\n    }\n    \n    @Override\n    public boolean isLeaf() {\n        return children == null || children.isEmpty();\n    }\n\n    @Override\n    public SocketIONode getParent() {\n        return parent;\n    }\n\n    \n    protected void addChild(SocketIONode child) {\n        if (children != null) children.add(child);\n    }\n    \n    protected void removeAllChildren() {\n        if (children != null) children.clear();\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return key.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        if (!(o instanceof SocketIONode)) return false;\n        return Objects.equals(key, ((SocketIONode)o).key);\n    }\n    \n    @Override\n    public String toString() {\n        return name;\n    }\n\n    private void setName(String newName) {\n        if (name == null || newName.length() > name.length()) {\n            name = newName;\n        }\n    }\n    \n    \n    static final class Address extends SocketIONode {\n        \n        private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/host.png\";  // NOI18N\n        private static final Icon ICON = new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true));\n        \n        Address(String key, String name, SocketIONode parent, boolean terminal) {\n            super(key, name, ICON, parent, terminal ? null : new ArrayList<>());\n        }\n        \n    }\n    \n    static final class Port extends SocketIONode {\n        \n        private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/port.png\";  // NOI18N\n        private static final Icon ICON = new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true));\n        \n        Port(String name, SocketIONode parent, boolean terminal) {\n            super(name, name, ICON, parent, terminal ? null : new ArrayList<>());\n        }\n        \n    }\n    \n    \n    static final class Thread extends SocketIONode {\n        \n        Thread(String name, SocketIONode parent, boolean terminal) {\n            super(name, name, Icons.getIcon(ProfilerIcons.THREAD), parent, terminal ? null : new ArrayList<>());\n        }\n        \n    }\n    \n    \n    static final class Root extends SocketIONode implements JFREventVisitor {\n        \n        private final SocketIOViewSupport.Aggregation primary;\n        private final SocketIOViewSupport.Aggregation secondary;\n    \n        \n        Root() {\n            this(null, null);\n        }\n        \n        Root(SocketIOViewSupport.Aggregation primary, SocketIOViewSupport.Aggregation secondary) {\n            super(null, null, null, null, primary == null && secondary == null ? null : new ArrayList<>());\n            \n            this.primary = primary;\n            this.secondary = SocketIOViewSupport.Aggregation.NONE.equals(secondary) ? null : secondary;\n        }\n        \n\n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            Boolean rw;\n            if (JFRSnapshotSocketIOViewProvider.EVENT_SOCKET_READ.equals(typeName)) rw = Boolean.FALSE; // NOI18N\n            else if (JFRSnapshotSocketIOViewProvider.EVENT_SOCKET_WRITE.equals(typeName)) rw = Boolean.TRUE; // NOI18N\n            else rw = null;\n            \n            if (rw != null) {\n                String primaryKey = getKey(primary, event);\n                String primaryName = getName(primary, event);\n                if (primaryKey == null) primaryKey = UNKNOWN;\n                if (primaryName == null) primaryName = UNKNOWN;\n                \n                SocketIONode primaryNode = getChild(primaryKey);\n                if (primaryNode == null) {\n                    primaryNode = createNode(primaryKey, primaryName, primary, this, secondary == null);\n                    addChild(primaryNode);\n                }\n                \n                if (secondary != null) {\n                    String secondaryKey = getKey(secondary, event);\n                    String secondaryName = getName(secondary, event);\n                    if (secondaryKey == null) secondaryKey = UNKNOWN;\n                    if (secondaryName == null) secondaryName = UNKNOWN;\n                    \n                    SocketIONode secondaryNode = primaryNode.getChild(secondaryKey);\n                    if (secondaryNode == null) {\n                        secondaryNode = createNode(secondaryKey, secondaryName, secondary, primaryNode, true);\n                        primaryNode.addChild(secondaryNode);\n                    }\n                    \n                    processEvent(secondaryNode, secondaryName, event, rw);\n                } else {\n                    processEvent(primaryNode, primaryName, event, rw);\n                }\n            }\n            \n            return false;\n        }\n        \n        private static void processEvent(SocketIONode node, String name, JFREvent event, Boolean rw) {\n            try {\n                node.setName(name);\n                if (Boolean.FALSE.equals(rw)) node.processRead(getDuration(event), event.getLong(\"bytesRead\")); // NOI18N\n                else node.processWrite(getDuration(event), event.getLong(\"bytesWritten\")); // NOI18N\n            } catch (JFRPropertyNotAvailableException e) {\n                System.err.println(\">>> \" + e);\n            }\n        }\n        \n        \n        @Override\n        public int hashCode() {\n            return 37;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            return o instanceof Root;\n        }\n        \n        \n        private static String getKey(SocketIOViewSupport.Aggregation aggregation, JFREvent event) {\n            try {\n                if (SocketIOViewSupport.Aggregation.ADDRESS.equals(aggregation)) {\n                    return getAddress(event); // NOI18N\n                }\n                if (SocketIOViewSupport.Aggregation.PORT.equals(aggregation)) return getPort(event);\n                if (SocketIOViewSupport.Aggregation.ADDRESS_PORT.equals(aggregation)) {\n                    String address = getAddress(event); // NOI18N\n                    return address + \" : \" + getPort(event); // NOI18N\n                }\n                if (SocketIOViewSupport.Aggregation.THREAD.equals(aggregation)) return event.getThread(\"eventThread\").getName();\n            } catch (JFRPropertyNotAvailableException e) {}\n            return null;\n        }\n\n        private static Duration getDuration(JFREvent event) throws JFRPropertyNotAvailableException {\n            return event.getDuration(\"eventDuration\");\n        }\n        \n        private static String getAddress(JFREvent event) throws JFRPropertyNotAvailableException {\n            return event.getString(\"address\");\n        }\n\n        private static String getName(SocketIOViewSupport.Aggregation aggregation, JFREvent event) {\n            try {\n                if (SocketIOViewSupport.Aggregation.ADDRESS.equals(aggregation)) return getFullAddress(event);\n                if (SocketIOViewSupport.Aggregation.PORT.equals(aggregation)) return getPort(event);\n                if (SocketIOViewSupport.Aggregation.ADDRESS_PORT.equals(aggregation)) {\n                    return getFullAddress(event) + \" : \" + getPort(event); // NOI18N\n                }\n                if (SocketIOViewSupport.Aggregation.THREAD.equals(aggregation)) return event.getThread(\"eventThread\").getName();\n            } catch (JFRPropertyNotAvailableException e) {}\n            return null;\n        }\n\n        private static String getPort(JFREvent event) throws JFRPropertyNotAvailableException {\n            return String.valueOf(event.getInt(\"port\")); // NOI18N\n        }\n\n        private static String getFullAddress(JFREvent event) throws JFRPropertyNotAvailableException {\n            String address = getAddress(event); // NOI18N\n            String host = event.getString(\"host\"); // NOI18N\n            if (host != null && !host.trim().isEmpty() && !host.equals(address)) address = address + \" (\" + host + \")\"; // NOI18N\n            return address;\n        }\n        \n        private SocketIONode createNode(String key, String name, SocketIOViewSupport.Aggregation aggregation, SocketIONode parent, boolean terminal) {\n            if (SocketIOViewSupport.Aggregation.ADDRESS.equals(aggregation)) return new SocketIONode.Address(key, name, parent, terminal);\n            if (SocketIOViewSupport.Aggregation.PORT.equals(aggregation)) return new SocketIONode.Port(name, parent, terminal);\n            if (SocketIOViewSupport.Aggregation.ADDRESS_PORT.equals(aggregation)) return new SocketIONode.Address(key, name, parent, terminal);\n            if (SocketIOViewSupport.Aggregation.THREAD.equals(aggregation)) return new SocketIONode.Thread(name, parent, terminal);\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/socketio/SocketIORenderers.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.socketio;\n\nimport java.awt.Font;\nimport java.time.Duration;\nimport javax.swing.JLabel;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.jfr.utils.ValuesConverter;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.FormattedLabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.McsTimeRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class SocketIORenderers {\n    \n    private static int getMinimumWidth(String valueName) {\n        return new JLabel(valueName).getPreferredSize().width + 30;\n    }\n    \n    \n    static class NameRenderer extends LabelRenderer {\n        \n        private static Font regular;\n        private static Font bold;\n            \n        public void setValue(Object value, int row) {\n            if (value instanceof SocketIONode) {\n                SocketIONode node = (SocketIONode)value;\n                SocketIONode parent = node.getParent();\n                setFont(parent == null || parent.getParent() == null ? bold() : regular());\n                setText(node.name);\n                setIcon(node.icon);\n            } else {\n                super.setValue(value, row);\n            }\n        }\n\n        static String getDisplayName() {\n            return \"Name\";\n        }\n        \n        private static Font regular() {\n            if (regular == null) regular = new LabelRenderer().getFont();\n            return regular;\n        }\n        \n        private static Font bold() {\n            if (bold == null) bold = new LabelRenderer().getFont().deriveFont(Font.BOLD);\n            return bold;\n        }\n\n    }\n    \n    \n    static class TotalTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Total Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class ReadTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Read Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class MaxReadTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Max Read Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class WriteTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Write Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class MaxWriteTimeRenderer extends TimeRenderer {\n        \n        static String getDisplayName() {\n            return \"Max Write Time\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(Duration.ofMillis(999999999999l), -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class TotalCountRenderer extends NumberRenderer {\n        \n        static String getDisplayName() {\n            return \"Total Count\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class ReadCountRenderer extends NumberRenderer {\n        \n        static String getDisplayName() {\n            return \"Read Count\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class WriteCountRenderer extends NumberRenderer {\n        \n        static String getDisplayName() {\n            return \"Write Count\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return false;\n        }\n        \n        int getPreferredWidth() {\n            setValue(999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class ReadBytesRenderer extends BytesRenderer {\n        \n        static String getDisplayName() {\n            return \"Read Bytes\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(99999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    static class WriteBytesRenderer extends BytesRenderer {\n        \n        static String getDisplayName() {\n            return \"Write Bytes\";\n        }\n        \n        static boolean isInitiallyVisible() {\n            return true;\n        }\n        \n        int getPreferredWidth() {\n            setValue(99999999999999l, -1);\n            return Math.max(getPreferredSize().width, getMinimumWidth(getDisplayName()));\n        }\n        \n    }\n    \n    \n    private static class TimeRenderer extends McsTimeRenderer {\n        \n        @Override\n        public void setValue(Object value, int row) {\n            if (value instanceof Duration) {\n                long micros = ValuesConverter.durationToMicros((Duration)value);\n                if (micros == 0) setText(\"< 0.001 ms\"); // NOI18N\n                else super.setValue(micros, row);\n            } else {\n                setText(\"-\"); // NOI18N\n            }\n        }\n        \n    }\n    \n    private static class BytesRenderer extends FormattedLabelRenderer {\n        \n        BytesRenderer() {\n            super(Formatters.bytesFormat());\n            setHorizontalAlignment(SwingConstants.TRAILING);\n        }\n        \n        @Override\n        public void setValue(Object value, int row) {\n            if (value == null) setText(\"-\");\n            else super.setValue(value, row);\n        }\n                \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/socketio/SocketIOViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.socketio;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.time.Duration;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.JButton;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JSeparator;\nimport javax.swing.JTree;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.tree.TreeNode;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.views.components.MessageComponent;\nimport org.graalvm.visualvm.lib.ui.components.HTMLLabel;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class SocketIOViewSupport {\n    \n    static enum Aggregation {\n        NONE { @Override public String toString() { return \"None\"; } },\n        ADDRESS { @Override public String toString() { return \"Address\"; } },\n        PORT { @Override public String toString() { return \"Port\"; } },\n        ADDRESS_PORT { @Override public String toString() { return \"Address : Port\"; } },\n        THREAD { @Override public String toString() { return \"Thread\"; } }\n    }\n\n    static abstract class MasterViewSupport extends JPanel {\n        \n        private Aggregation lastPrimary, lastSecondary;\n        \n        \n        MasterViewSupport(JFRModel model) {\n            initComponents(model);\n        }\n        \n        \n        DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(\"Socket IO\", null, this);\n        }\n        \n        \n        abstract void firstShown();\n        \n        abstract void changeAggregation(Aggregation primary, Aggregation secondary);\n        \n        \n        void showProgress() {\n            updateButton.setEnabled(false);\n            updateButton.setVisible(false);\n            statusValueLabel.setVisible(true);\n        }\n        \n        void hideProgress() {\n            statusValueLabel.setVisible(false);\n            updateButton.setVisible(true);\n        }\n        \n        \n        private void handleAggregationChanged(boolean updateSecondary) {\n            if (updateSecondary) {\n                DefaultComboBoxModel<Aggregation> model = (DefaultComboBoxModel<Aggregation>) secondCombo.getModel();\n                while (model.getSize() > 1) model.removeElementAt(1);\n                \n                if (!Aggregation.ADDRESS.equals(firstCombo.getSelectedItem()) &&\n                    !Aggregation.PORT.equals(firstCombo.getSelectedItem()) &&\n                    !Aggregation.ADDRESS_PORT.equals(firstCombo.getSelectedItem()))\n                        model.addElement(Aggregation.ADDRESS_PORT);\n                \n                if (!Aggregation.ADDRESS.equals(firstCombo.getSelectedItem()) &&\n                    !Aggregation.ADDRESS_PORT.equals(firstCombo.getSelectedItem()))\n                        model.addElement(Aggregation.ADDRESS);\n                \n                if (!Aggregation.PORT.equals(firstCombo.getSelectedItem()) &&\n                    !Aggregation.ADDRESS_PORT.equals(firstCombo.getSelectedItem()))\n                        model.addElement(Aggregation.PORT);\n                \n                if (!Aggregation.THREAD.equals(firstCombo.getSelectedItem()))\n                    model.addElement(Aggregation.THREAD);\n            }\n            \n            updateButton.setEnabled(lastPrimary != firstCombo.getSelectedItem() ||\n                                    lastSecondary != secondCombo.getSelectedItem());\n            \n        }\n        \n        \n        private int prefHeight = -1;\n        public Dimension getPreferredSize() {\n            Dimension pref = super.getPreferredSize();\n            if (prefHeight == -1) prefHeight = pref.height;\n            else pref.height = prefHeight;\n            return pref;\n        }\n        \n        \n        private void initComponents(JFRModel model) {\n            setOpaque(false);\n            \n            if (model == null) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.notAvailable(), BorderLayout.CENTER);\n            } else if (!model.containsEvent(JFRSnapshotSocketIOViewProvider.EventChecker.class)) {\n                setLayout(new BorderLayout());\n                add(MessageComponent.noData(\"Socket IO\", JFRSnapshotSocketIOViewProvider.EventChecker.checkedTypes()), BorderLayout.CENTER);\n            } else {\n                setLayout(new GridBagLayout());\n                setBorder(BorderFactory.createEmptyBorder(11, 5, 20, 5));\n\n                GridBagConstraints constraints;\n\n                // modeLabel\n                firstLabel = new JLabel();\n                firstLabel.setText(\"Aggregation:\");\n                firstLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 0;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(firstLabel, constraints);\n\n                // cpuButton\n                firstCombo = new JComboBox<>(new Aggregation[] { Aggregation.ADDRESS_PORT, Aggregation.ADDRESS, Aggregation.PORT, Aggregation.THREAD });\n                firstCombo.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleAggregationChanged(true); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 1;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(firstCombo, constraints);\n\n                // modeLabel\n                secondLabel = new JLabel();\n                secondLabel.setText(\"secondary:\");\n                secondLabel.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 2;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 12, 0, 0);\n                add(secondLabel, constraints);\n\n                // memoryButton\n                secondCombo = new JComboBox<>(new Aggregation[] { Aggregation.NONE, Aggregation.THREAD });\n                secondCombo.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) { handleAggregationChanged(false); }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 3;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 8, 0, 0);\n                add(secondCombo, constraints);\n                \n                lastPrimary = (Aggregation)firstCombo.getSelectedItem();\n                lastSecondary = (Aggregation)secondCombo.getSelectedItem();\n                \n                // updateSeparator\n                JSeparator updateSeparator = new JSeparator(JSeparator.VERTICAL);\n                updateSeparator.setOpaque(false);\n                constraints = new GridBagConstraints();\n                constraints.gridx = 4;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 16, 0, 0);\n                add(updateSeparator, constraints);\n\n                // updateButton\n                updateButton = new JButton(\"Update Data\");\n                updateButton.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        updateButton.setEnabled(false);\n                        lastPrimary = (Aggregation)firstCombo.getSelectedItem();\n                        lastSecondary = (Aggregation)secondCombo.getSelectedItem();\n                        changeAggregation((Aggregation)firstCombo.getSelectedItem(), (Aggregation)secondCombo.getSelectedItem());\n                    }\n                });\n                constraints = new GridBagConstraints();\n                constraints.gridx = 5;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 12, 0, 0);\n                add(updateButton, constraints);\n\n                // statusValueLabel\n                statusValueLabel = new HTMLLabel(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n                constraints = new GridBagConstraints();\n                constraints.gridx = 6;\n                constraints.gridy = 2;\n                constraints.gridwidth = 1;\n                constraints.fill = GridBagConstraints.NONE;\n                constraints.anchor = GridBagConstraints.WEST;\n                constraints.insets = new Insets(4, 20, 0, 0);\n                add(statusValueLabel, constraints);\n                statusValueLabel.setVisible(false);\n\n                // filler1\n                constraints = new GridBagConstraints();\n                constraints.gridx = 7;\n                constraints.gridy = 2;\n                constraints.weightx = 1;\n                constraints.weighty = 1;\n                constraints.gridwidth = GridBagConstraints.REMAINDER;\n                constraints.fill = GridBagConstraints.BOTH;\n                constraints.anchor = GridBagConstraints.NORTHWEST;\n                constraints.insets = new Insets(0, 0, 0, 0);\n                add(Spacer.create(), constraints);\n\n                Dimension cpuD     = firstCombo.getPreferredSize();\n                Dimension memoryD  = secondCombo.getPreferredSize();\n    //            Dimension stopD    = stopButton.getPreferredSize();\n\n                Dimension maxD = new Dimension(Math.max(cpuD.width, memoryD.width), Math.max(cpuD.height, memoryD.height));\n    //            maxD = new Dimension(Math.max(maxD.width, stopD.width), Math.max(maxD.height, stopD.height));\n\n                firstCombo.setPreferredSize(maxD);\n                firstCombo.setMinimumSize(maxD);\n                secondCombo.setPreferredSize(maxD);\n                secondCombo.setMinimumSize(maxD);\n    //            stopButton.setPreferredSize(maxD);\n    //            stopButton.setMinimumSize(maxD);\n    \n                Dimension sepD = updateSeparator.getPreferredSize();\n                sepD.height = maxD.height - 2;\n                sepD.width = 5;\n                updateSeparator.setPreferredSize(sepD);\n                updateSeparator.setMinimumSize(sepD);\n\n                addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                            if (isShowing()) {\n                                removeHierarchyListener(this);\n                                SwingUtilities.invokeLater(MasterViewSupport.this::firstShown);\n                            }\n                        }\n                    }\n                });\n            }\n        }\n\n        private JLabel firstLabel;\n        private JLabel secondLabel;\n        private JComboBox<Aggregation> firstCombo;\n        private JComboBox<Aggregation> secondCombo;\n        private JButton updateButton;\n        private HTMLLabel statusValueLabel;\n        \n    }\n    \n    \n    static final class DataViewSupport extends JPanel {\n        \n        private DataModel tableModel;\n        private ProfilerTreeTable table;\n        \n        \n        DataViewSupport() {\n            initComponents();\n        }\n        \n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(\"Data\", null, 10, this, null); // NOI18N\n        }\n        \n        \n        void setData(SocketIONode root, boolean twoAggregations) {\n            tableModel.setRoot(root);\n            table.setShowsRootHandles(twoAggregations);\n        }\n        \n        \n        private void initComponents() {\n            tableModel = new DataModel();\n            table = new ProfilerTreeTable(tableModel, true, true, new int[] { 0 });\n            \n            table.setRootVisible(false);\n            table.setShowsRootHandles(true);\n\n            table.setMainColumn(0);\n            table.setFitWidthColumn(0);\n\n            table.setSortColumn(1);\n            table.setDefaultSortOrder(SortOrder.DESCENDING);\n            table.setDefaultSortOrder(0, SortOrder.ASCENDING);\n            \n            SocketIORenderers.NameRenderer nameRenderer = new SocketIORenderers.NameRenderer();\n            table.setTreeCellRenderer(nameRenderer);\n            \n            SocketIORenderers.TotalTimeRenderer totalTimeRenderer = new SocketIORenderers.TotalTimeRenderer();\n            table.setColumnRenderer(1, totalTimeRenderer);\n            table.setDefaultColumnWidth(1, totalTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(1, SocketIORenderers.TotalTimeRenderer.isInitiallyVisible());\n            \n            SocketIORenderers.ReadTimeRenderer readTimeRenderer = new SocketIORenderers.ReadTimeRenderer();\n            table.setColumnRenderer(2, readTimeRenderer);\n            table.setDefaultColumnWidth(2, readTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(2, SocketIORenderers.ReadTimeRenderer.isInitiallyVisible());\n            \n            SocketIORenderers.MaxReadTimeRenderer maxReadTimeRenderer = new SocketIORenderers.MaxReadTimeRenderer();\n            table.setColumnRenderer(3, maxReadTimeRenderer);\n            table.setDefaultColumnWidth(3, maxReadTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(3, SocketIORenderers.MaxReadTimeRenderer.isInitiallyVisible());\n            \n            SocketIORenderers.WriteTimeRenderer writeTimeRenderer = new SocketIORenderers.WriteTimeRenderer();\n            table.setColumnRenderer(4, writeTimeRenderer);\n            table.setDefaultColumnWidth(4, writeTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(4, SocketIORenderers.WriteTimeRenderer.isInitiallyVisible());\n            \n            SocketIORenderers.MaxWriteTimeRenderer maxWriteTimeRenderer = new SocketIORenderers.MaxWriteTimeRenderer();\n            table.setColumnRenderer(5, maxWriteTimeRenderer);\n            table.setDefaultColumnWidth(5, maxWriteTimeRenderer.getPreferredWidth());\n            table.setColumnVisibility(5, SocketIORenderers.MaxWriteTimeRenderer.isInitiallyVisible());\n            \n            SocketIORenderers.TotalCountRenderer totalCountRenderer = new SocketIORenderers.TotalCountRenderer();\n            table.setColumnRenderer(6, totalCountRenderer);\n            table.setDefaultColumnWidth(6, totalCountRenderer.getPreferredWidth());\n            table.setColumnVisibility(6, SocketIORenderers.TotalCountRenderer.isInitiallyVisible());\n            \n            SocketIORenderers.ReadCountRenderer readCountRenderer = new SocketIORenderers.ReadCountRenderer();\n            table.setColumnRenderer(7, readCountRenderer);\n            table.setDefaultColumnWidth(7, readCountRenderer.getPreferredWidth());\n            table.setColumnVisibility(7, SocketIORenderers.ReadCountRenderer.isInitiallyVisible());\n            \n            SocketIORenderers.WriteCountRenderer writeCountRenderer = new SocketIORenderers.WriteCountRenderer();\n            table.setColumnRenderer(8, writeCountRenderer);\n            table.setDefaultColumnWidth(8, writeCountRenderer.getPreferredWidth());\n            table.setColumnVisibility(8, SocketIORenderers.WriteCountRenderer.isInitiallyVisible());\n            \n            SocketIORenderers.ReadBytesRenderer readBytesRenderer = new SocketIORenderers.ReadBytesRenderer();\n            table.setColumnRenderer(9, readBytesRenderer);\n            table.setDefaultColumnWidth(9, readBytesRenderer.getPreferredWidth());\n            table.setColumnVisibility(9, SocketIORenderers.ReadBytesRenderer.isInitiallyVisible());\n            \n            SocketIORenderers.WriteBytesRenderer writeBytesRenderer = new SocketIORenderers.WriteBytesRenderer();\n            table.setColumnRenderer(10, writeBytesRenderer);\n            table.setDefaultColumnWidth(10, writeBytesRenderer.getPreferredWidth());\n            table.setColumnVisibility(10, SocketIORenderers.WriteBytesRenderer.isInitiallyVisible());\n            \n            setLayout(new BorderLayout());\n            add(new ProfilerTableContainer(table, false, null), BorderLayout.CENTER);\n        }\n        \n        \n        private static class DataModel extends ProfilerTreeTableModel.Abstract {\n            \n            DataModel() {\n                super(new SocketIONode.Root());\n            }\n            \n            \n            @Override\n            public int getColumnCount() {\n                return 11;\n            }\n\n            @Override\n            public Class<?> getColumnClass(int column) {\n                switch (column) {\n                    case 0: return JTree.class;\n                    case 1: return Duration.class;\n                    case 2: return Duration.class;\n                    case 3: return Duration.class;\n                    case 4: return Duration.class;\n                    case 5: return Duration.class;\n                    case 6: return Long.class;\n                    case 7: return Long.class;\n                    case 8: return Long.class;\n                    case 9: return Long.class;\n                    case 10: return Long.class;\n                    default: return null;\n                }\n            }\n\n            @Override\n            public String getColumnName(int column) {\n                switch (column) {\n                    case 0: return SocketIORenderers.NameRenderer.getDisplayName();\n                    case 1: return SocketIORenderers.TotalTimeRenderer.getDisplayName();\n                    case 2: return SocketIORenderers.ReadTimeRenderer.getDisplayName();\n                    case 3: return SocketIORenderers.MaxReadTimeRenderer.getDisplayName();\n                    case 4: return SocketIORenderers.WriteTimeRenderer.getDisplayName();\n                    case 5: return SocketIORenderers.MaxWriteTimeRenderer.getDisplayName();\n                    case 6: return SocketIORenderers.TotalCountRenderer.getDisplayName();\n                    case 7: return SocketIORenderers.ReadCountRenderer.getDisplayName();\n                    case 8: return SocketIORenderers.WriteCountRenderer.getDisplayName();\n                    case 9: return SocketIORenderers.ReadBytesRenderer.getDisplayName();\n                    case 10: return SocketIORenderers.WriteBytesRenderer.getDisplayName();\n                    default: return null;\n                }\n            }\n\n            @Override\n            public Object getValueAt(TreeNode node, int column) {\n                if (node == null) return null;\n                SocketIONode fnode = (SocketIONode)node;\n                \n                switch (column) {\n                    case 0: return fnode;\n                    case 1: return toDuration(fnode.durationR, fnode.durationW);\n                    case 2: return fnode.durationR;\n                    case 3: return fnode.durationRMax;\n                    case 4: return fnode.durationW;\n                    case 5: return fnode.durationWMax;\n                    case 6: return toLong(fnode.countR + fnode.countW);\n                    case 7: return toLong(fnode.countR);\n                    case 8: return toLong(fnode.countW);\n                    case 9: return toLong(fnode.bytesR);\n                    case 10: return toLong(fnode.bytesW);\n                    default: return null;\n                }\n            }\n            \n            @Override\n            public void setValueAt(Object o, TreeNode node, int column) {}\n\n            @Override\n            public boolean isCellEditable(TreeNode node, int column) { return false; }\n            \n            \n            private Long toLong(long value) {\n                return value == 0 ? null : Long.valueOf(value);\n            }\n            \n            private Duration toDuration(Duration duration1, Duration duration2) {\n                if (duration1 == null && duration2 == null) return null;\n                if (duration2 == null) return duration1;\n                if (duration1 == null) return duration2;\n                return duration1.plus(duration2);\n            }\n            \n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/threads/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_Threads=Threads\n\nLBL_Threads_visualization=Threads visualization\n\nLBL_Thread_Dump=Thread Dump\n\nLBL_Timeline=Timeline\n\nLBL_Table=Table\n\nLBL_Details=Details\n\nLBL_Live_threads=Live threads\n\nLBL_Daemon_threads=Daemon threads\n\nDeadlock_Alert_Text=<b>Deadlock detected!</b><br>Take a thread dump to get more info.\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/threads/JFRSnapshotThreadsView.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.threads;\n\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JFRSnapshotThreadsView extends JFRViewTab {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/jfr/resources/threads.png\";  // NOI18N\n    \n    \n    JFRSnapshotThreadsView(JFRSnapshot dataSource) {\n        super(dataSource, NbBundle.getMessage(JFRSnapshotThreadsView.class, \"LBL_Threads\"), new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 20);   // NOI18N\n    }\n\n    \n    @Override\n    protected DataViewComponent createComponent() {\n        JFRModel model = getModel();\n        \n        ThreadsViewSupport.TimelineViewSupport timelineView = new ThreadsViewSupport.TimelineViewSupport(model);\n        \n        ThreadsViewSupport.MasterViewSupport masterView = new ThreadsViewSupport.MasterViewSupport(model) {\n            @Override\n            void firstShown() { initialize(this, timelineView); }\n        };\n        DataViewComponent dvc = new DataViewComponent(masterView.getMasterView(), new DataViewComponent.MasterViewConfiguration(model == null));\n\n        if (model != null) {\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(JFRSnapshotThreadsView.class, \"LBL_Threads_visualization\"), true), DataViewComponent.TOP_LEFT); // NOI18N\n            dvc.addDetailsView(timelineView.getDetailsView(), DataViewComponent.TOP_LEFT);\n        }\n\n        return dvc;\n    }\n    \n    \n    private void initialize(ThreadsViewSupport.MasterViewSupport masterView, ThreadsViewSupport.TimelineViewSupport timelineView) {\n        new RequestProcessor(\"JFR Threads Initializer\").post(new Runnable() { // NOI18N\n            public void run() {\n                getModel().visitEvents(timelineView);\n                masterView.initialized(timelineView.getActiveTypes(),\n                timelineView.getThreadsCount());\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/threads/JFRSnapshotThreadsViewProvider.java",
    "content": "/*\n * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.threads;\n\nimport org.graalvm.visualvm.jfr.JFRSnapshot;\nimport org.graalvm.visualvm.jfr.view.JFRViewTab;\nimport org.graalvm.visualvm.jfr.view.JFRViewTabProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=JFRViewTabProvider.class)\npublic class JFRSnapshotThreadsViewProvider extends JFRViewTabProvider {\n\n    @Override\n    protected JFRViewTab createView(JFRSnapshot jfrSnapshot) {\n        return new JFRSnapshotThreadsView(jfrSnapshot);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/threads/JFRThreadsDataManager.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.threads;\n\nimport java.util.Collection;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadData;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadsDataManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JFRThreadsDataManager extends ThreadsDataManager {\n    \n    private long startTime;\n    private long endTime;\n    \n    private ThreadData[] threadData = new ThreadData[0];\n    \n    \n    void setData(long startTime, long endTime, Collection<ThreadData> threadData) {\n        this.startTime = startTime;\n        this.endTime = endTime;\n        this.threadData = threadData.toArray(this.threadData);\n        fireDataChanged();\n    }\n    \n    \n    public long getStartTime() { return startTime; }\n    public long getEndTime() { return endTime; }\n\n    public int getThreadsCount() { return threadData.length; }\n    public String getThreadName(int index) { return threadData[index].getName(); }\n    public String getThreadClassName(int index) { return threadData[index].getClassName(); }\n\n    public ThreadData getThreadData(int index) { return threadData[index]; }\n\n}\n"
  },
  {
    "path": "visualvm/jfr/src/org/graalvm/visualvm/jfr/views/threads/ThreadsViewSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.views.threads;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.TreeMap;\nimport javax.swing.AbstractAction;\nimport javax.swing.AbstractButton;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.jfr.model.JFRThread;\nimport org.graalvm.visualvm.jfr.utils.ValuesConverter;\nimport org.graalvm.visualvm.jfr.views.components.MessageComponent;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadData;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.ActionPopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.threads.ThreadsPanel;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ThreadsViewSupport {\n    \n    static abstract class MasterViewSupport extends JPanel {\n\n//        private static RequestProcessor worker = null;\n\n//        private Application application;\n        private HTMLTextArea area;\n        private HTMLTextArea alertArea;\n//        private JButton threadDumpButton;\n//        private static final String LIVE_THREADS = NbBundle.getMessage(ThreadsViewSupport.class, \"LBL_Live_threads\");    // NOI18N\n//        private static final String DAEMON_THREADS = NbBundle.getMessage(ThreadsViewSupport.class, \"LBL_Daemon_threads\");   // NOI18N\n\n        MasterViewSupport(JFRModel model/*, VisualVMThreadsDataManager threadsManager*/) {\n//            if (dataSource instanceof Application) application = (Application)dataSource;\n            initComponents(model);\n//            updateThreadsCounts(threadsManager);\n        }\n        \n        abstract void firstShown();\n\n        DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(ThreadsViewSupport.class, \"LBL_Threads\"), null, this);  // NOI18N\n        }\n        \n        void initialized(Collection<String> activeTypes, int threadsCount) {\n            if (activeTypes.isEmpty()) {\n                area.setText(threadsCount == 0 ? \"No threads information recorded\" : \"No thread states recorded.\");\n            } else {\n                StringBuilder sb = new StringBuilder();\n                boolean first = true;\n                for (String s : activeTypes) {\n                    if (first) first = false;\n                    else sb.append(\", \");\n                    sb.append(s);\n                }\n                area.setText(\"Thread states based on:&nbsp;&nbsp;<code>\" + sb.toString() + \"</code>\");\n            }\n        }\n\n        private void initComponents(JFRModel model) {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            if (model == null) {\n                add(MessageComponent.notAvailable(), BorderLayout.CENTER);\n            } else {\n                area = new HTMLTextArea(\"<nobr><b>Progress:</b> reading data...</nobr>\");\n                area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n\n                add(area, BorderLayout.WEST);\n\n                alertArea = new HTMLTextArea();\n                alertArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n                alertArea.setForeground(Color.RED);\n\n                add(alertArea, BorderLayout.CENTER);\n\n//                threadDumpButton = new JButton(new AbstractAction(NbBundle.getMessage(ThreadsViewSupport.class, \"LBL_Thread_Dump\")) {   // NOI18N\n//                    public void actionPerformed(ActionEvent e) {\n//    //                    ThreadDumpSupport.getInstance().takeThreadDump(application, (e.getModifiers() &\n//    //                            Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n//                    }\n//                });\n//                threadDumpButton.setEnabled(false);\n//\n//                JPanel buttonsArea = new JPanel(new BorderLayout());\n//                buttonsArea.setOpaque(false);\n//                JPanel buttonsContainer = new JPanel(new BorderLayout(3, 0));\n//                buttonsContainer.setBackground(area.getBackground());\n//                buttonsContainer.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n//                buttonsContainer.add(threadDumpButton, BorderLayout.EAST);\n//                buttonsArea.add(buttonsContainer, BorderLayout.NORTH);\n//\n//                add(buttonsArea, BorderLayout.AFTER_LINE_ENDS);\n\n                addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                            if (isShowing()) {\n                                removeHierarchyListener(this);\n                                SwingUtilities.invokeLater(MasterViewSupport.this::firstShown);\n                            }\n                        }\n                    }\n                });\n            }\n        }\n\n//        private void updateThreadsCounts(final VisualVMThreadsDataManager threadsManager) {\n//\n//            final int[] threads = new int[2];\n//\n//            getWorker().post(new Runnable() {\n//                public void run() {\n//                    try {\n//                        threads[0] = threadsManager.getThreadCount();\n//                        threads[1] = threadsManager.getDaemonThreadCount();\n//                    } catch (Exception ex) {\n//                        threads[0] = 0;\n//                        threads[1] = 0;\n//                    }\n//                    SwingUtilities.invokeLater(new Runnable() {\n//                        public void run() {\n//                            updateThreadsCounts(threads[0], threads[1]);\n//                        }\n//                    });\n//                }\n//            });\n//        }\n//\n//        private void setAlertText(String alert) {\n//            int selStart = alertArea.getSelectionStart();\n//            int selEnd = alertArea.getSelectionEnd();\n//            alertArea.setText(\"<center>\"+alert+\"</center>\");   // NOI18N\n//            alertArea.select(selStart, selEnd);\n//        }\n//        \n//        private void updateThreadsCounts(int liveThreads, int daemonThreads) {\n//            StringBuilder data = new StringBuilder();\n//\n//            data.append(\"<b>\" + LIVE_THREADS + \":</b> \" + liveThreads + \"<br>\");  // NOI18N\n//            data.append(\"<b>\" + DAEMON_THREADS + \":</b> \" + daemonThreads + \"<br>\");   // NOI18N\n//\n//            int selStart = area.getSelectionStart();\n//            int selEnd = area.getSelectionEnd();\n//            area.setText(data.toString());\n//            area.select(selStart, selEnd);\n//        }\n//\n//        private static synchronized RequestProcessor getWorker() {\n//            if (worker == null) worker = new RequestProcessor(\"ThreadsWorker\", 1); // NOI18N\n//            return worker;\n//        }\n\n    }\n    \n    \n//    @NbBundle.Messages({\n//        \"ThreadsFeatureUI_show=Show:\",\n//        \"ThreadsFeatureUI_filterAll=All Threads\",\n//        \"ThreadsFeatureUI_filterLive=Live Threads\",\n//        \"ThreadsFeatureUI_filterFinished=Finished Threads\",\n//        \"ThreadsFeatureUI_filterSelected=Selected Threads\",\n//        \"ThreadsFeatureUI_timeline=Timeline:\",\n//        \"ThreadsFeatureUI_threadsFilter=Threads filter\",\n//        \"# HTML formatted:\",\n//        \"ThreadsFeatureUI_noThreadsMsg=<html><b>No threads are currently selected.</b><br><br>Use the Selected column or invoke Select thread action to select threads.</html>\"\n//    })\n    static class TimelineViewSupport extends JPanel implements JFREventVisitor {\n        \n        private final JFRModel jfrModel;\n        \n        private JFRThreadsDataManager threadsManager;\n        \n        private ProfilerToolbar toolbar;\n        private ThreadsPanel threadsPanel;\n        \n        private JLabel shLabel;\n        private ActionPopupButton shFilter;\n\n        private JLabel tlLabel;\n        private JComponent tlZoomInButton;\n        private JComponent tlZoomOutButton;\n        private JComponent tlFitWidthButton;\n        \n\n        TimelineViewSupport(JFRModel jfrModel) {\n            this.jfrModel = jfrModel;\n            \n            initModels();\n            initComponents();\n        }\n\n        \n        DataViewComponent.DetailsView getDetailsView() {\n            return new DataViewComponent.DetailsView(NbBundle.getMessage(ThreadsViewSupport.class, \"LBL_Timeline\"), null, 10, this, null);  // NOI18N\n        }\n        \n        \n        private static final class Definition {\n            final String tname; long firstTime; byte firstState;\n            Definition(String tname, long firstTime, byte firstState) { this.tname = tname; this.firstTime = firstTime; this.firstState = firstState; }\n        }\n        \n        private static final class State {\n            final long time; final byte tstate;\n            State(long time, byte tstate) { this.time = time; this.tstate = tstate; }\n            @Override public int hashCode() { return Long.hashCode(time); }\n            @Override public boolean equals(Object o) { return o instanceof State && ((State) o).time == time; }\n\n            static final Comparator<State> COMPARATOR = new Comparator<State>() {\n                @Override public int compare(State r1, State r2) { return Long.compare(r1.time, r2.time); }\n            };\n        }\n        \n        \n        private long firstTimestamp = Long.MAX_VALUE;\n        private long lastTimestamp = Long.MIN_VALUE;\n        private Map<Long, List<State>> states;\n        private Map<Long, Definition> definitions;\n        private Set<String> ignoredEvents;\n        \n        private boolean[] activeTypes = new boolean[6];\n        \n        @Override\n        public void init() {\n            states = new HashMap<>();\n            definitions = new TreeMap<>();\n            ignoredEvents = new HashSet<>();\n        }\n        \n        @Override\n        public boolean visit(String typeName, JFREvent event) {\n            switch (typeName) {\n                case \"jdk.ThreadStart\": // NOI18N\n                    if (processEvent(event, \"thread\", CommonConstants.THREAD_STATUS_RUNNING, Byte.MIN_VALUE)) // NOI18N\n                        activeTypes[0] = true;\n                    break;\n                \n                case \"jdk.ThreadEnd\": // NOI18N\n                    if (processEvent(event, \"thread\", CommonConstants.THREAD_STATUS_ZOMBIE, Byte.MIN_VALUE)) // NOI18N\n                        activeTypes[1] = true;\n                    break;\n                \n                case \"jdk.JavaMonitorWait\": // NOI18N\n                    if (processEvent(event, \"eventThread\", CommonConstants.THREAD_STATUS_WAIT, CommonConstants.THREAD_STATUS_RUNNING)) // NOI18N\n                        activeTypes[2] = true;\n                    break;\n                \n                case \"jdk.JavaMonitorEnter\": // NOI18N\n                    if (processEvent(event, \"eventThread\", CommonConstants.THREAD_STATUS_MONITOR, CommonConstants.THREAD_STATUS_RUNNING)) // NOI18N\n                        activeTypes[3] = true;\n                    break;\n                \n                case \"jdk.ThreadPark\": // NOI18N\n                    if (processEvent(event, \"eventThread\", CommonConstants.THREAD_STATUS_PARK, CommonConstants.THREAD_STATUS_RUNNING)) // NOI18N\n                        activeTypes[4] = true;\n                    break;\n                \n                case \"jdk.ThreadSleep\": // NOI18N\n                    if (processEvent(event, \"eventThread\", CommonConstants.THREAD_STATUS_SLEEPING, CommonConstants.THREAD_STATUS_RUNNING)) // NOI18N\n                        activeTypes[5] = true;\n                    break;\n                \n                case \"jdk.Compilation\": // NOI18N\n                    processEvent(event, \"eventThread\", CommonConstants.THREAD_STATUS_RUNNING, CommonConstants.THREAD_STATUS_PARK); // ?? // NOI18N\n                    break;\n                \n                case \"jdk.ThreadAllocationStatistics\": // NOI18N\n                    try {\n                        JFRThread thread = event.getThread(\"eventThread\"); // NOI18N\n                        if (thread != null) {\n                            long allocated = event.getLong(\"allocated\"); // NOI18N\n                            byte tstate = allocated > 0 ? CommonConstants.THREAD_STATUS_RUNNING : CommonConstants.THREAD_STATUS_WAIT; // ??\n                            processDefinition(thread.getId(), thread.getName(), ValuesConverter.instantToRelativeNanos(event.getInstant(\"eventTime\"), jfrModel), tstate); // NOI18N\n                        }\n                    } catch (JFRPropertyNotAvailableException e) { System.err.println(\">>> --- \" + e); }\n                    break;\n                \n                default:\n                    try {\n                        if (!ignoredEvents.contains(typeName)) {\n                            JFRThread thread = event.getThread(\"eventThread\"); // NOI18N\n                            if (thread != null) processDefinition(thread.getId(), thread.getName(), ValuesConverter.instantToRelativeNanos(event.getInstant(\"eventTime\"), jfrModel), CommonConstants.THREAD_STATUS_RUNNING); // NOI18N\n                        }\n                    } catch (JFRPropertyNotAvailableException e) {\n                        ignoredEvents.add(typeName);\n                    }\n            }\n            \n            return false;\n        }\n        \n        @Override\n        public void done() {\n            final Collection<ThreadData> tdataC = new ArrayList<>();\n            \n            for (Map.Entry<Long, Definition> definitionE : definitions.entrySet()) {\n                long tid = definitionE.getKey();\n                Definition definition = definitionE.getValue();\n                \n                List<State> statesL = states.get(tid);\n                if (statesL == null) statesL = new ArrayList<>();\n                statesL.sort(State.COMPARATOR);\n                \n                if (statesL.isEmpty() && definition.firstState != Byte.MIN_VALUE) {\n                    statesL.add(new State(definition.firstTime, definition.firstState));\n                } else {\n                    long firstStateTime = statesL.get(0).time;\n                    if (firstStateTime > definition.firstTime && definition.firstState != Byte.MIN_VALUE)\n                        statesL.add(0, new State(definition.firstTime, definition.firstState));\n                }\n                \n                firstTimestamp = Math.min(firstTimestamp, statesL.get(0).time);\n                lastTimestamp = Math.max(lastTimestamp, statesL.get(statesL.size() - 1).time);\n                \n                ThreadData tdata = new ThreadData(definition.tname, \"java.lang.Thread\");\n                byte lastState = Byte.MIN_VALUE;\n                \n                for (State state : statesL) {\n                    long ttime = state.time;\n                    byte tstate = state.tstate;\n                    \n                    if (lastState != tstate) {\n                        tdata.add(jfrModel.nsToAbsoluteMillis(ttime), tstate);\n                        lastState = tstate;\n                    }\n                }\n                \n                tdataC.add(tdata);\n            }\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    threadsManager.setData(jfrModel.nsToAbsoluteMillis(firstTimestamp), jfrModel.nsToAbsoluteMillis(lastTimestamp), tdataC);\n                }\n            });\n            \n            states = null;\n            definitions = null;\n            ignoredEvents = null;\n        }\n        \n        \n        Collection<String> getActiveTypes() {\n            List<String> names = new ArrayList<>();\n            \n            if (activeTypes[0]) names.add(\"jdk.ThreadStart\"); // NOI18N\n            if (activeTypes[1]) names.add(\"jdk.ThreadEnd\"); // NOI18N\n            if (activeTypes[2]) names.add(\"jdk.JavaMonitorWait\"); // NOI18N\n            if (activeTypes[3]) names.add(\"jdk.JavaMonitorEnter\"); // NOI18N\n            if (activeTypes[4]) names.add(\"jdk.ThreadPark\"); // NOI18N\n            if (activeTypes[5]) names.add(\"jdk.ThreadSleep\"); // NOI18N\n            \n            activeTypes = null;\n            \n            return names;\n        }\n        \n        int getThreadsCount() {\n            return threadsManager.getThreadsCount();\n        }\n        \n        \n        private boolean processEvent(JFREvent event, String tkey, byte tstate1, byte tstate2) {\n            try {\n                JFRThread thread = event.getThread(tkey);\n                if (thread == null) return false;\n                \n                long tid = thread.getId();\n                List<State> tdata = states.computeIfAbsent(tid, k -> new ArrayList<>());\n\n                long ttime = ValuesConverter.instantToRelativeNanos(event.getInstant(\"eventTime\"), jfrModel); // NOI18N\n                tdata.add(new State(ttime, tstate1));\n                \n                processDefinition(tid, thread.getName(), ttime, tstate1);\n                \n                if (tstate2 != Byte.MIN_VALUE) {\n                    ttime += ValuesConverter.durationToNanos(event.getDuration(\"eventDuration\")); // NOI18N\n                    tdata.add(new State(ttime, tstate2));\n                }\n                \n                return true;\n            } catch (JFRPropertyNotAvailableException e) {\n                System.err.println(\">>> \" + e + \" --- \" + event);\n                return false;\n            }\n        }\n        \n        private void processDefinition(long tid, String tname, long ttime, byte tstate) {\n            Definition definition = definitions.get(tid);\n            \n            if (definition == null) {\n                definitions.put(tid, new Definition(tname, ttime, tstate));\n            } else if (definition.firstTime > ttime) {\n                definition.firstTime = ttime;\n                definition.firstState = tstate;\n            }\n            \n//            firstTimestamp = Math.min(firstTimestamp, ttime);\n        }\n        \n        \n        private void initModels() {\n            threadsManager = new JFRThreadsDataManager();\n        }\n\n        private void initComponents() {\n            setLayout(new BorderLayout());\n            setOpaque(false);\n\n            threadsPanel = new ThreadsPanel(threadsManager, null) {\n                protected void filterSelected(ThreadsPanel.Filter filter) {\n                    super.filterSelected(filter);\n                    shFilter.selectAction(filter.ordinal());\n                }\n            };\n            threadsPanel.threadsMonitoringEnabled();\n            \n//            InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n//            ActionMap actionMap = getActionMap();\n//\n//            final String filterKey = org.graalvm.visualvm.lib.ui.swing.FilterUtils.FILTER_ACTION_KEY;\n//            Action filterAction = new AbstractAction() {\n//                public void actionPerformed(ActionEvent e) {\n//                    Action action = threadsPanel.getActionMap().get(filterKey);\n//                    if (action != null && action.isEnabled()) action.actionPerformed(e);\n//                }\n//            };\n//            ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);\n//\n//            final String findKey = SearchUtils.FIND_ACTION_KEY;\n//            Action findAction = new AbstractAction() {\n//                public void actionPerformed(ActionEvent e) {\n//                    Action action = threadsPanel.getActionMap().get(findKey);\n//                    if (action != null && action.isEnabled()) action.actionPerformed(e);\n//                }\n//            };\n//            ActionsSupport.registerAction(findKey, findAction, actionMap, inputMap);\n            \n            // -----------------------------------------------------------------\n            // --- copy-pasted timeline toolbar from org.graalvm.visualvm.lib.profiler.v2.features.ThreadsFeatureUI\n            \n            shLabel = new GrayLabel(\"Show:\");\n\n            Action aAll = new AbstractAction() {\n                { putValue(NAME, \"All Threads\"); }\n                public void actionPerformed(ActionEvent e) { setFilter(ThreadsPanel.Filter.ALL); }\n\n            };\n            Action aLive = new AbstractAction() {\n                { putValue(NAME, \"Live Threads\"); }\n                public void actionPerformed(ActionEvent e) { setFilter(ThreadsPanel.Filter.LIVE); }\n\n            };\n            Action aFinished = new AbstractAction() {\n                { putValue(NAME, \"Finished Threads\"); }\n                public void actionPerformed(ActionEvent e) { setFilter(ThreadsPanel.Filter.FINISHED); }\n\n            };\n            Action aSelected = new AbstractAction() {\n                { putValue(NAME, \"Selected Threads\"); }\n                public void actionPerformed(ActionEvent e) { setSelectedFilter(); }\n\n            };\n            shFilter = new ActionPopupButton(aAll, aLive, aFinished, aSelected);\n            shFilter.setToolTipText(\"Threads filter\");\n\n            tlLabel = new GrayLabel(\"Timeline:\");\n\n\n            tlZoomInButton = (JComponent)threadsPanel.getZoomIn();\n            tlZoomInButton.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            tlZoomInButton.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n            tlZoomOutButton = (JComponent)threadsPanel.getZoomOut();\n            tlZoomOutButton.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            tlZoomOutButton.putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n            tlFitWidthButton = (JComponent)threadsPanel.getFitWidth();\n            tlFitWidthButton.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            tlFitWidthButton.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n            \n            // Workaround to initialize the timeline in fit-width mode\n            if (tlFitWidthButton instanceof AbstractButton) ((AbstractButton)tlFitWidthButton).doClick();\n\n            toolbar = ProfilerToolbar.create(true);\n\n//            toolbar.addSpace(2);\n//            toolbar.addSeparator();\n            toolbar.addSpace(5);\n\n            toolbar.add(shLabel);\n            toolbar.addSpace(2);\n            toolbar.add(shFilter);\n\n            toolbar.addSpace(2);\n            toolbar.addSeparator();\n            toolbar.addSpace(5);\n\n            toolbar.add(tlLabel);\n            toolbar.addSpace(2);\n            toolbar.add(tlZoomInButton);\n            toolbar.add(tlZoomOutButton);\n            toolbar.add(tlFitWidthButton);\n            \n            add(toolbar.getComponent(), BorderLayout.NORTH);\n\n//            setFilter(ThreadsPanel.Filter.LIVE);\n            setFilter(ThreadsPanel.Filter.ALL);\n            \n            // -----------------------------------------------------------------\n\n            add(threadsPanel, BorderLayout.CENTER);\n        }\n        \n        private void setSelectedFilter() {\n            if (threadsPanel.hasSelectedThreads()) {\n                setFilter(ThreadsPanel.Filter.SELECTED);\n            } else {\n                threadsPanel.showSelectedColumn();\n                shFilter.selectAction(threadsPanel.getFilter().ordinal());\n//                ProfilerDialogs.displayWarning(Bundle.ThreadsFeatureUI_noThreadsMsg());\n            }\n        }\n\n        private void setFilter(ThreadsPanel.Filter filter) {\n            threadsPanel.setFilter(filter);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.generic/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.jfr.generic\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.jfr.generic.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n    <target name=\"download-all-extbins\" unless=\"ext.binaries.downloaded\" depends=\"init\">\n      <echo>Downloading external binaries (external/ directory)...</echo>\n      <property name=\"binaries.cache\" location=\"${user.home}/.hgexternalcache\"/>\n      <property name=\"binaries.server\" value=\"https://netbeans.osuosl.org/binaries/\"/>\n      <downloadbinaries cache=\"${binaries.cache}\" server=\"${binaries.server}\" >\n          <manifest dir=\".\">\n              <include name=\"external/binaries-list\"/>\n          </manifest>\n      </downloadbinaries>\n      <property name=\"ext.binaries.downloaded\" value=\"true\"/>\n    </target>\n\n    <target name=\"-pre-compile\" depends=\"download-all-extbins\">\n    </target>\n\n    <target name=\"-pre-release\" depends=\"compile\">\n        <taskdef name=\"releasefilescopy\" classname=\"org.netbeans.nbbuild.extlibs.ReleaseFilesCopy\" classpath=\"${harness.dir}/tasks.jar\"/>\n        <releasefilescopy cluster=\"${cluster}\"/>\n    </target>\n\n    <target name=\"-release.files\" depends=\"projectized-common.-release.files\">\n        <taskdef name=\"releasefilesextra\" classname=\"org.netbeans.nbbuild.extlibs.ReleaseFilesExtra\" classpath=\"${harness.dir}/tasks.jar\"/>\n        <releasefilesextra property=\"release.files.extra\"/>\n    </target>\n\n    <target name=\"-pre-nbm\" depends=\"compile\">\n      <property name=\"license.file.override\" location=\"${build.dir}/license\"/>\n      <property name=\"extra.license.files\" value=\"\"/>\n      <taskdef name=\"releasefileslicense\" classname=\"org.netbeans.nbbuild.extlibs.ReleaseFilesLicense\" classpath=\"${harness.dir}/tasks.jar\"/>\n      <releasefileslicense license=\"${license.file.override}\" standardlicense=\"${license.file}\" extralicensefiles=\"${extra.license.files}\"/>\n    </target>\n\n</project>\n"
  },
  {
    "path": "visualvm/jfr.generic/external/binaries-list",
    "content": "0F89E45C26154C5EA910633F79A4503E6DA495AC org.openjdk.jmc:flightrecorder:8.3.1\n7DE2918886C01F3273DB610093F36257425D5DF2 org.openjdk.jmc:common:8.3.1\n56C7A637A793E7DC5A369D24EBADF0D1B85196C4 at.yawk.lz4:lz4-java:1.10.3\n35AE93BE1524B161525DA2C9A110019616F67548 org.owasp.encoder:encoder:1.2.3\n"
  },
  {
    "path": "visualvm/jfr.generic/external/encoder-1.2.3-license.txt",
    "content": "Name: Encoder\nDescription: The OWASP Encoders package is a collection of high-performance low-overhead contextual encoders, that when utilized correctly, is an effective tool in preventing Web Application security vulnerabilities such as Cross-Site Scripting.\nVersion: 1.2.3\nOrigin: https://github.com/OWASP/owasp-java-encoder\nLicense: BSD 3-Clause\n\nCopyright (c) 2015 Jeff Ichnowski\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n    * Redistributions of source code must retain the above\n      copyright notice, this list of conditions and the following\n      disclaimer.\n\n    * Redistributions in binary form must reproduce the above\n      copyright notice, this list of conditions and the following\n      disclaimer in the documentation and/or other materials\n      provided with the distribution.\n\n    * Neither the name of the OWASP nor the names of its\n      contributors may be used to endorse or promote products\n      derived from this software without specific prior written\n      permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\nFOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\nINDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\nHOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\nSTRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\nOF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "visualvm/jfr.generic/external/flightrecorder-8.3.1-license.txt",
    "content": "Name: JMC\nDescription: OpenJDK Mission Control, a production time profiling and diagnostics tools suite.\nLicense: UPL\nOrigin: https://github.com/openjdk/jmc\nVersion: 8.3.1\nFiles: common-8.3.1.jar, flightrecorder-8.3.1.jar\n\nCopyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.\n\nThe Universal Permissive License (UPL), Version 1.0\n\nSubject to the condition set forth below, permission is hereby granted to any \nperson obtaining a copy of this software, associated documentation and/or data \n(collectively the \"Software\"), free of charge and under any and all copyright \nrights in the Software, and any and all patent rights owned or freely \nlicensable by each licensor hereunder covering either (i) the unmodified \nSoftware as contributed to or provided by such licensor, or (ii) the Larger \nWorks (as defined below), to deal in both\n\n(a) the Software, and\n\n(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if \n    one is included with the Software (each a Larger Work to which the \n    Software is contributed by such licensors), without restriction, including \n    without limitation the rights to copy, create derivative works of, \n    display, perform, and distribute the Software and make, use, sell, offer \n    for sale, import, export, have made, and have sold the Software and the \n    Larger Work(s), and to sublicense the foregoing rights on either these or \n    other terms.\n\nThis license is subject to the following condition:\n\nThe above copyright notice and either this complete permission notice or at a \nminimum a reference to the UPL must be included in all copies or substantial \nportions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR \nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, \nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE \nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER \nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE \nSOFTWARE.\n\n\nCopyright (c) 2018 Oracle America, Inc. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without \nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, \n   this list of conditions and the following disclaimer.\n   \n2. Redistributions in binary form must reproduce the above copyright notice, \n   this list of conditions and the following disclaimer in the documentation \n   and/or other materials provided with the distribution.\n   \n3. Neither the name of the copyright holder nor the names of its contributors \n   may be used to endorse or promote products derived from this software \n   without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" \nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE \nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL \nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR \nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER \nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "visualvm/jfr.generic/external/lz4-java-1.10.3-license.txt",
    "content": "Name: lz4-java\nDescription: Java ports and bindings of the LZ4 compression algorithm and the xxHash hashing algorithm\nVersion: 1.10.3\nOrigin: https://github.com/yawkat/lz4-java\nLicense: Apache-2.0\n\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "visualvm/jfr.generic/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.jfr.generic/2\nOpenIDE-Module-Install: org/graalvm/visualvm/jfr/generic/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/jfr/generic/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.5\nOpenIDE-Module-Provides: jfr.implementation\n"
  },
  {
    "path": "visualvm/jfr.generic/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.jfr.generic-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/jfr.generic/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=56e1456d\nbuild.xml.script.CRC32=8bce95d6\nbuild.xml.stylesheet.CRC32=15ca8a54@2.76.1\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=56e1456d\nnbproject/build-impl.xml.script.CRC32=53506612\nnbproject/build-impl.xml.stylesheet.CRC32=1016842c@2.76.1\n"
  },
  {
    "path": "visualvm/jfr.generic/nbproject/project.properties",
    "content": "is.autoload=true\njavac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jiri Sedlacek\nnbm.needs.restart=true\nmodule.javadoc.packages=org.graalvm.visualvm.jfr.generic.*\nfile.reference.flightrecorder-8.3.1.jar=external/flightrecorder-8.3.1.jar\nfile.reference.common-8.3.1.jar=external/common-8.3.1.jar\nfile.reference.lz4-java-1.10.3.jar=external/lz4-java-1.10.3.jar\nfile.reference.encoder-1.2.3.jar=external/encoder-1.2.3.jar\nrelease.external/flightrecorder-8.3.1.jar=modules/ext/flightrecorder-8.3.1.jar\nrelease.external/common-8.3.1.jar=modules/ext/common-8.3.1.jar\nrelease.external/lz4-java-1.10.3.jar=modules/ext/lz4-java-1.10.3.jar\nrelease.external/encoder-1.2.3.jar=modules/ext/encoder-1.2.3.jar\n"
  },
  {
    "path": "visualvm/jfr.generic/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.jfr.generic</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.jfr</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.49</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n            <class-path-extension>\n                <runtime-relative-path>ext/common-8.3.1.jar</runtime-relative-path>\n                <binary-origin>external/common-8.3.1.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/flightrecorder-8.3.1.jar</runtime-relative-path>\n                <binary-origin>external/flightrecorder-8.3.1.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/lz4-java-1.10.3.jar</runtime-relative-path>\n                <binary-origin>external/lz4-java-1.10.3.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/encoder-1.2.3.jar</runtime-relative-path>\n                <binary-origin>external/encoder-1.2.3.jar</binary-origin>\n            </class-path-extension>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/jfr.generic/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/jfr.generic/src/org/graalvm/visualvm/jfr/generic/Bundle.properties",
    "content": "#\n# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=JFR Loaders\nOpenIDE-Module-Long-Description=Generic JFR loader reading all JFR snapshots.\n#<BR><BR>For better performance and lower memory consumption when running VisualVM on JDK 9 and newer, please install also one of the following JFR loaders:<BR><BR><B>VisualVM-JFR-JDK9:</B> Support for the JFR loader bundled with JDK 9 and JDK 10 (requires running VisualVM on JDK 9/10) reading JFR snapshots created from JDK 9 and JDK 10\\n<BR><BR><B>VisualVM-JFR-JDK11:</B> Support for the JFR loader bundled with JDK 11 and newer (requires running VisualVM on JDK 11+) reading JFR snapshots created from JDK 9 and newer\nOpenIDE-Module-Name=VisualVM-JFR-Generic\nOpenIDE-Module-Short-Description=Generic JFR loader reading all JFR snapshots\n"
  },
  {
    "path": "visualvm/jfr.generic/src/org/graalvm/visualvm/jfr/generic/Installer.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr.generic;\n\nimport org.graalvm.visualvm.jfr.generic.model.impl.JFRGenericModelProvider;\nimport org.openide.modules.ModuleInstall;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class Installer extends ModuleInstall {\n    \n    public void restored() {\n        JFRGenericModelProvider.register();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.generic/src/org/graalvm/visualvm/jfr/generic/model/impl/DisplayableSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.generic.model.impl;\n\nimport java.text.FieldPosition;\nimport java.text.Format;\nimport java.text.ParsePosition;\nimport java.util.Iterator;\nimport org.graalvm.visualvm.jfr.model.JFRDataDescriptor;\nimport org.openjdk.jmc.common.item.IAccessorKey;\nimport org.openjdk.jmc.common.item.IType;\nimport org.openjdk.jmc.common.unit.ContentType;\nimport org.openjdk.jmc.common.unit.IFormatter;\nimport org.openjdk.jmc.common.unit.LinearKindOfQuantity;\nimport org.openjdk.jmc.common.util.TypeHandling;\nimport org.openjdk.jmc.flightrecorder.JfrAttributes;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class DisplayableSupport {\n    \n    static Iterator<IAccessorKey> displayableAccessorKeys(final IType type, final boolean includeExperimental) {\n        return new Iterator<IAccessorKey>() {\n            private final String ID_STACKTRACE;\n            \n            private final Iterator<IAccessorKey> master;\n            private IAccessorKey next;\n            \n            {\n                ID_STACKTRACE = JfrAttributes.EVENT_STACKTRACE.getIdentifier();\n                \n                master = type.getAccessorKeys().keySet().iterator();\n                next = computeNext();\n            }\n            \n            @Override\n            public boolean hasNext() {\n                return next != null;\n            }\n\n            @Override\n            public IAccessorKey next() {\n                IAccessorKey ret = next;\n                next = computeNext();\n                return ret;\n            }\n            \n            private IAccessorKey computeNext() {\n                while (master.hasNext()) {\n                    IAccessorKey _next = master.next();\n                    if (isDisplayable(_next)) return _next;\n                }\n                return null;\n            }\n            \n            private boolean isDisplayable(IAccessorKey key) {\n                if (ID_STACKTRACE.equals(key.getIdentifier())) return false;\n                return includeExperimental || !isExperimental(key);\n            }\n        };\n    }\n    \n    \n    static JFRDataDescriptor getDataDescriptor(IAccessorKey key) {\n        String dataName = TypeHandling.getValueString(key);\n        String dataDescription = TypeHandling.getVerboseString(key);\n        ContentType contentType = key.getContentType();\n        Format dataFormat = new DataFormat(contentType.getDefaultFormatter());\n        boolean isNumericData = contentType instanceof LinearKindOfQuantity;\n        return new JFRDataDescriptor(dataName, dataDescription, dataFormat, null, isNumericData);\n    }\n    \n    \n    private static boolean isExperimental(IAccessorKey key) {\n        // TODO: should be turned into regexp and test matching, not startsWith!\n        String accessorName = TypeHandling.getValueString(key);\n        return accessorName.startsWith(JFRGenericEventType.EXPERIMENTAL_PREFIX);\n    }\n    \n    \n    private DisplayableSupport() {}\n    \n    \n    private static class DataFormat extends Format {\n        \n        private final IFormatter formatter;\n        \n        \n        DataFormat(IFormatter formatter) {\n            this.formatter = formatter;\n        }\n\n        \n        @Override\n        public StringBuffer format(Object o, StringBuffer b, FieldPosition p) {\n            if (o == null) return b.append(\"\"); // NOI18N\n            if (o instanceof String) return b.append(o.toString());\n            return b.append(formatter.format(o));\n        }\n\n        @Override\n        public Object parseObject(String source, ParsePosition pos) {\n            throw new UnsupportedOperationException(\"Not supported.\"); // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.generic/src/org/graalvm/visualvm/jfr/generic/model/impl/JFRGenericClass.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.generic.model.impl;\n\nimport org.graalvm.visualvm.jfr.model.JFRClass;\nimport org.openjdk.jmc.common.IMCType;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRGenericClass extends JFRClass {\n    \n    private final IMCType type;\n    \n    \n    JFRGenericClass(IMCType type) {\n        this.type = type;\n    }\n\n    \n    @Override\n    public String getName() {\n        return type.getFullName();\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return type.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRGenericClass && type.equals(((JFRGenericClass) o).type);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.generic/src/org/graalvm/visualvm/jfr/generic/model/impl/JFRGenericEvent.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.generic.model.impl;\n\nimport java.time.Duration;\nimport java.time.Instant;\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\nimport org.graalvm.visualvm.jfr.model.JFRClass;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.jfr.model.JFRStackTrace;\nimport org.graalvm.visualvm.jfr.model.JFRThread;\nimport org.openjdk.jmc.common.IMCStackTrace;\nimport org.openjdk.jmc.common.IMCThread;\nimport org.openjdk.jmc.common.IMCType;\nimport org.openjdk.jmc.common.item.IAccessorKey;\nimport org.openjdk.jmc.common.item.IAttribute;\nimport org.openjdk.jmc.common.item.IItem;\nimport org.openjdk.jmc.common.item.IMemberAccessor;\nimport org.openjdk.jmc.common.item.IType;\nimport org.openjdk.jmc.common.unit.IQuantity;\nimport org.openjdk.jmc.common.unit.QuantityConversionException;\nimport org.openjdk.jmc.common.unit.UnitLookup;\nimport org.openjdk.jmc.flightrecorder.JfrAttributes;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class JFRGenericEvent extends JFREvent {\n    \n    final IItem item;\n    \n    \n    protected JFRGenericEvent(IItem event, long id) {\n        super(id);\n        this.item = event;\n    }\n    \n    \n    protected abstract IQuantity getEventStartTime() throws JFRPropertyNotAvailableException;\n    \n    protected abstract IQuantity getEventEndTime() throws JFRPropertyNotAvailableException;\n    \n    protected abstract IQuantity getEventDuration() throws JFRPropertyNotAvailableException;\n    \n    protected abstract Object getThreadThread() throws JFRPropertyNotAvailableException;\n    \n    \n    @Override\n    public Instant getInstant(String key) throws JFRPropertyNotAvailableException {\n        switch (key) {\n            case \"eventTime\": // NOI18N\n            case \"startTime\": // NOI18N\n                IQuantity startTime = getEventStartTime();\n                return startTime == null ? null : instantFromQuantity(startTime);\n                \n            case \"endTime\": // NOI18N\n                IQuantity endTime = getEventStartTime();\n                return endTime == null ? null : instantFromQuantity(endTime);\n        }\n        \n        Object time = getValue(key);\n        if (time instanceof IQuantity) return instantFromQuantity((IQuantity)time);\n        else if (time == null) return null;\n        else throw new JFRPropertyNotAvailableException(\"No instant value available: \" + key);\n    }\n    \n    private static Instant instantFromQuantity(IQuantity quantity) {\n//        TimestampUnit ms = null;\n//        for (Object u : quantity.getType().getCommonUnits()) {\n//            if (u instanceof TimestampUnit) {\n//                TimestampUnit lu = (TimestampUnit)u;\n//                if (\"epochms\".equals(lu.getIdentifier())) {\n//                    ms = lu;\n//                    break;\n//                }\n//            }\n//        }\n//        \n//        try {\n//            return Instant.ofEpochMilli(quantity.longValueIn(ms));\n//        } catch (QuantityConversionException ex) {\n////            System.err.println(\">>> \" + ex);\n//            return null;\n//        }\n        \n        \n        // quantity expected to be always in epochns or epochms\n        try {\n            long nanos = quantity.longValueIn(UnitLookup.EPOCH_NS);\n            return Instant.EPOCH.plusNanos(nanos);\n        } catch (QuantityConversionException ex1) {\n            try {\n                long millis = quantity.longValueIn(UnitLookup.EPOCH_MS);\n                return Instant.ofEpochMilli(millis);\n            } catch (QuantityConversionException ex3) {\n                long seconds = quantity.clampedLongValueIn(UnitLookup.EPOCH_S);\n                return Instant.ofEpochSecond(seconds);\n            }\n        }\n        \n//        IQuantity seconds = quantity.in(UnitLookup.EPOCH_S);\n//        IQuantity nanos = quantity.subtract(seconds).in(UnitLookup.NANOSECOND);\n//\n//        return Instant.ofEpochSecond(seconds.longValue(), nanos.longValue());\n    }\n    \n    \n    @Override\n    public Duration getDuration(String key) throws JFRPropertyNotAvailableException {\n        if (\"eventDuration\".equals(key)) { // NOI18N\n            IQuantity duration = getEventDuration();\n            return duration == null ? null : durationFromQuantity(duration);\n        }\n        \n        Object duration = getValue(key);\n        if (duration instanceof IQuantity) return durationFromQuantity((IQuantity)duration);\n        else if (duration == null) return null;\n        else throw new JFRPropertyNotAvailableException(\"No duration value available: \" + key); // NOI18N\n    }\n    \n    private static Duration durationFromQuantity(IQuantity quantity) {\n        // quantity can be in ticks or time units - ms, us, ns etc.\n        try {\n            long nanos = quantity.longValueIn(UnitLookup.NANOSECOND);\n            return Duration.ofNanos(nanos);\n        } catch (QuantityConversionException ex1) {\n//            try {\n//                long micros = quantity.longValueIn(UnitLookup.MICROSECOND);\n//                return Duration.ofNanos(micros * 1000);\n//            } catch (QuantityConversionException ex2) {\n                try {\n                    long millis = quantity.longValueIn(UnitLookup.MILLISECOND);\n                    return Duration.ofMillis(millis);\n                } catch (QuantityConversionException ex3) {\n                    long seconds = quantity.clampedLongValueIn(UnitLookup.SECOND);\n                    return Duration.ofSeconds(seconds);\n                }\n//            }\n        }\n    }\n    \n    \n    @Override\n    public JFRClass getClass(String key) throws JFRPropertyNotAvailableException {\n        Object value = getValue(key);\n        if (value instanceof IMCType) return new JFRGenericClass((IMCType)value);\n        else if (value == null) return null;\n        else throw new JFRPropertyNotAvailableException(\"No class value available: \" + key);\n    }\n\n    @Override\n    public JFRThread getThread(String key) throws JFRPropertyNotAvailableException {\n        Object thread;\n        \n        switch (key) {\n            case \"eventThread\": // NOI18N\n                IMCThread eventThread = getValue(JfrAttributes.EVENT_THREAD);\n                return eventThread == null ? null : new JFRGenericThread(eventThread);\n                \n            case \"sampledThread\": // NOI18N\n                switch (item.getType().getIdentifier()) {\n                    case \"jdk.ExecutionSample\": // NOI18N\n                    case \"jdk.NativeMethodSample\": // NOI18N\n                        IMCThread sampledThread = getValue(JfrAttributes.EVENT_THREAD);\n                        return sampledThread == null ? null : new JFRGenericThread(sampledThread);\n                    default:\n                        thread = getValue(key);\n                        break;\n                }\n                break;\n                \n            case \"thread\": // NOI18N\n                switch (item.getType().getIdentifier()) {\n                    case \"jdk.ThreadStart\": // NOI18N\n                    case \"jdk.ThreadEnd\": // NOI18N\n                        thread = getThreadThread();\n                        break;\n                    case \"jdk.ThreadAllocationStatistics\": // NOI18N\n                        IMCThread sampledThread = getValue(JfrAttributes.EVENT_THREAD);\n                        return sampledThread == null ? null : new JFRGenericThread(sampledThread);\n                    default:\n                        thread = getValue(key);\n                        break;\n                }\n                break;\n                \n            default:\n                thread = getValue(key);\n        }\n        \n        if (thread instanceof IMCThread) return new JFRGenericThread((IMCThread)thread);\n        else if (thread == null) return null;\n        else throw new JFRPropertyNotAvailableException(\"No thread value available: \" + key);\n    }\n    \n    @Override\n    public JFRStackTrace getStackTrace(String key) throws JFRPropertyNotAvailableException {\n        if (\"eventStackTrace\".equals(key)) { // NOI18N\n            IMCStackTrace stackTrace = getValue(JfrAttributes.EVENT_STACKTRACE);\n            return stackTrace == null ? null : new JFRGenericStackTrace(stackTrace);\n        }\n        \n        Object stackTrace = getValue(key);\n        if (stackTrace instanceof IMCStackTrace) return new JFRGenericStackTrace((IMCStackTrace)stackTrace);\n        else if (stackTrace == null) return null;\n        else throw new JFRPropertyNotAvailableException(\"No stacktrace value available: \" + key);\n    }\n    \n    \n    @Override\n    public Object getValue(String key) throws JFRPropertyNotAvailableException {\n        key = key.replace('.', ':'); // NOI18N\n        \n        IType<?> type = item.getType();\n        for (IAccessorKey accessor : type.getAccessorKeys().keySet()) {\n            if (key.equals(accessor.getIdentifier())) \n                return type.getAccessor(accessor).getMember(item);\n        }\n        \n        throw new JFRPropertyNotAvailableException(\"No value available: \" + key);\n    }\n    \n    \n    protected <T> T getValue(IAttribute<T> attribute) throws JFRPropertyNotAvailableException {\n        IType type = item.getType();\n        IMemberAccessor<T, IItem> accessor = type.getAccessor(attribute.getKey());\n        if (accessor == null) throw new JFRPropertyNotAvailableException(\"No value available: \" + attribute.getIdentifier());\n        return accessor.getMember(item);\n    }\n    \n    \n    @Override\n    public List<Comparable<?>> getDisplayableValues(boolean includeExperimental) {\n        IType type = item.getType();        \n        List<Comparable<?>> values = new ArrayList<>();\n        Iterator<IAccessorKey> keys = DisplayableSupport.displayableAccessorKeys(type, includeExperimental);\n        while (keys.hasNext()) {\n            IAccessorKey key = keys.next();\n            Object value = type.getAccessor(key).getMember(item);\n            if (value instanceof Comparable) values.add((Comparable)value);\n            else values.add(key.getContentType().getDefaultFormatter().format(value));\n        }\n        return values;\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return item.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRGenericEvent && item.equals(((JFRGenericEvent) o).item);\n    }\n    \n    \n    @Override\n    public String toString() {\n        return item.toString() + \" [\" + item.getType().getAccessorKeys().keySet() + \"]\"; // NOI18N\n    }\n    \n    \n    // JFREvent for .jfr v0 (JDK 7 & 8)\n    static final class V0 extends JFRGenericEvent {\n        \n        V0(IItem event, long id) {\n            super(event, id);\n        }\n\n        @Override\n        protected IQuantity getEventStartTime() throws JFRPropertyNotAvailableException {\n            IType type = item.getType();\n            IMemberAccessor<IQuantity, IItem> startAccessor = type.getAccessor(JfrAttributes.START_TIME.getKey());\n            return startAccessor != null ? startAccessor.getMember(item) : getEventEndTime();\n        }\n        \n        @Override\n        protected IQuantity getEventEndTime() throws JFRPropertyNotAvailableException {\n            return getValue(JfrAttributes.END_TIME);\n        }\n        \n        @Override\n        protected IQuantity getEventDuration() throws JFRPropertyNotAvailableException {\n            IQuantity startTime = getValue(JfrAttributes.START_TIME);\n            if (startTime == null) throw new JFRPropertyNotAvailableException(\"No start time to compute event duration\");\n            \n            IQuantity endTime = getValue(JfrAttributes.END_TIME);\n            if (endTime == null) throw new JFRPropertyNotAvailableException(\"No end time to compute event duration\");\n            \n            return endTime.subtract(startTime);\n        }\n        \n        @Override\n        protected Object getThreadThread() throws JFRPropertyNotAvailableException {\n            return getValue(\"javalangthread\"); // NOI18N\n        }\n        \n    }\n    \n    \n    // JFREvent for .jfr v1 and v2 (JDK 9+)\n    static final class V1 extends JFRGenericEvent {\n        \n        V1(IItem event, long id) {\n            super(event, id);\n        }\n\n        @Override\n        protected IQuantity getEventStartTime() throws JFRPropertyNotAvailableException {\n            return getValue(JfrAttributes.START_TIME);\n        }\n        \n        @Override\n        protected IQuantity getEventEndTime() throws JFRPropertyNotAvailableException {\n            return getEventStartTime().add(getEventDuration());\n        }\n        \n        @Override\n        protected IQuantity getEventDuration() throws JFRPropertyNotAvailableException {\n            return getValue(JfrAttributes.DURATION);\n        }\n        \n        @Override\n        protected Object getThreadThread() throws JFRPropertyNotAvailableException {\n            return getValue(\"thread\"); // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.generic/src/org/graalvm/visualvm/jfr/generic/model/impl/JFRGenericEventFactory.java",
    "content": "/*\n * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.generic.model.impl;\n\nimport org.openjdk.jmc.common.item.IItem;\nimport org.openjdk.jmc.common.item.IType;\nimport org.openjdk.jmc.flightrecorder.JfrAttributes;\nimport org.openjdk.jmc.flightrecorder.internal.EventArray;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class JFRGenericEventFactory {\n    \n    abstract JFRGenericEvent createEvent(IItem item, long id);\n    \n    \n    static JFRGenericEventFactory resolve(EventArray[] types) {\n        for (EventArray typeA : types) {\n            IType type = typeA.getType();\n            if (type.getAccessor(JfrAttributes.END_TIME.getKey()) != null) return new V0();\n            if (type.getAccessor(JfrAttributes.DURATION.getKey()) != null) return new V1();\n        }\n        \n        throw new RuntimeException(\"No JFRGenericEventFactory resolved!\");\n    }\n    \n    \n    static class V0 extends JFRGenericEventFactory {\n\n        @Override JFRGenericEvent createEvent(IItem item, long id) { return new JFRGenericEvent.V0(item, id); }\n        \n    }\n    \n    static class V1 extends JFRGenericEventFactory {\n\n        @Override JFRGenericEvent createEvent(IItem item, long id) { return new JFRGenericEvent.V1(item, id); }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.generic/src/org/graalvm/visualvm/jfr/generic/model/impl/JFRGenericEventType.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.generic.model.impl;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.List;\nimport org.graalvm.visualvm.jfr.model.JFRDataDescriptor;\nimport org.graalvm.visualvm.jfr.model.JFREventType;\nimport org.openjdk.jmc.common.item.IAccessorKey;\nimport org.openjdk.jmc.common.item.IItem;\nimport org.openjdk.jmc.common.item.IType;\nimport org.openjdk.jmc.flightrecorder.messages.internal.Messages;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRGenericEventType extends JFREventType {\n    \n    static final String EXPERIMENTAL_PREFIX = Messages.getString(Messages.TypeManager_EXPERIMENTAL_TYPE).replace(\"{0}\", \"\").trim(); // NOI18N\n    \n    \n    private final long typeId;\n    private final IType type;\n    private final String[] category;\n    \n    \n    JFRGenericEventType(long typeId, IType<IItem> type, String[] category) {\n        this.typeId = typeId;\n        this.type = type;\n        this.category = category;\n    }\n    \n\n    @Override\n    public long getId() {\n        return typeId;\n    }\n\n    @Override\n    public String getName() {\n        return type.getIdentifier();\n    }\n\n    @Override\n    public String getDisplayName() {\n        return type.getName();\n    }\n\n    @Override\n    public String getDescription() {\n        return type.getDescription();\n    }\n    \n    @Override\n    public List<String> getCategory() {\n        return Arrays.asList(category);\n    }\n    \n    \n    @Override\n    public List<JFRDataDescriptor> getDisplayableDataDescriptors(boolean includeExperimental) {\n        List<JFRDataDescriptor> descriptors = new ArrayList<>();\n        Iterator<IAccessorKey> keys = DisplayableSupport.displayableAccessorKeys(type, includeExperimental);\n        while (keys.hasNext()) descriptors.add(DisplayableSupport.getDataDescriptor(keys.next()));\n        return descriptors;\n    }\n    \n    \n    @Override\n    public boolean isExperimental() {\n        // TODO: should be turned into regexp and test matching, not startsWith!\n        return type.getName().startsWith(EXPERIMENTAL_PREFIX);\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return type.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRGenericEventType && type.equals(((JFRGenericEventType) o).type);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.generic/src/org/graalvm/visualvm/jfr/generic/model/impl/JFRGenericMethod.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.generic.model.impl;\n\nimport org.graalvm.visualvm.jfr.model.JFRClass;\nimport org.graalvm.visualvm.jfr.model.JFRMethod;\nimport org.openjdk.jmc.common.IMCMethod;\nimport org.openjdk.jmc.common.IMCType;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRGenericMethod extends JFRMethod {\n    \n    private final IMCMethod method;\n    \n    \n    JFRGenericMethod(IMCMethod method) {\n        this.method = method;\n    }\n\n    \n    @Override\n    public String getName() {\n        return method.getMethodName();\n    }\n    \n    @Override\n    public String getDescriptor() {\n        return method.getFormalDescriptor();\n    }\n\n    @Override\n    public JFRClass getType() {\n        IMCType type = method.getType();\n        return type == null ? null : new JFRGenericClass(type);\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return method.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRGenericMethod && method.equals(((JFRGenericMethod) o).method);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.generic/src/org/graalvm/visualvm/jfr/generic/model/impl/JFRGenericModel.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.generic.model.impl;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventType;\nimport org.graalvm.visualvm.jfr.model.JFREventTypeVisitor;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.openjdk.jmc.common.io.IOToolkit;\nimport org.openjdk.jmc.common.item.IItem;\nimport org.openjdk.jmc.common.item.IType;\nimport org.openjdk.jmc.flightrecorder.CouldNotLoadRecordingException;\nimport org.openjdk.jmc.flightrecorder.internal.EventArray;\nimport org.openjdk.jmc.flightrecorder.internal.FlightRecordingLoader;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRGenericModel extends JFRModel {\n    \n    private static final Logger LOGGER = Logger.getLogger(JFRModel.class.getName());\n    \n    \n    private final EventArray[] types;\n    \n    private final JFRGenericEventFactory factory;\n    \n    \n    JFRGenericModel(String id, File snapshotFile) throws IOException, CouldNotLoadRecordingException {\n        super(id);\n        \n        types = loadFile(snapshotFile);\n        \n        factory = JFRGenericEventFactory.resolve(types);\n       \n        initialize();\n    }\n    \n    \n    @Override\n    public void visitEvents(JFREventVisitor... visitors) {\n        // Notify all visitors 'init'\n        for (JFREventVisitor visitor : visitors) visitor.init();\n        \n        // Notify visitors that are not done 'visit'\n        try {\n            List<JFREventVisitor> _visitors = new ArrayList<>(Arrays.asList(visitors));\n            Iterator<EventArray> iterables = Arrays.asList(types).iterator();\n            long id = 0;\n            while (!_visitors.isEmpty() && iterables.hasNext()) {\n                EventArray type = iterables.next();\n                String typeId = type.getType().getIdentifier();\n                Iterator<IItem> items = Arrays.asList(type.getEvents()).iterator();\n                while (!_visitors.isEmpty() && items.hasNext()) {\n                    JFREvent event = factory.createEvent(items.next(), id++);\n                    Iterator<JFREventVisitor> _visitorsI = _visitors.iterator();\n                    while (_visitorsI.hasNext())\n                        if (_visitorsI.next().visit(typeId, event))\n                            _visitorsI.remove();\n                }\n            }\n        } catch (Exception e) {\n            LOGGER.log(Level.INFO, \"Error visiting JFR events (generic loader)\", e);   // NOI18N\n        } finally {\n            // Notify all visitors 'done'\n            for (JFREventVisitor visitor : visitors) visitor.done();\n        }\n    }\n    \n    @Override\n    public void visitEventTypes(JFREventTypeVisitor... visitors) {\n        // Notify all visitors 'init'\n        for (JFREventTypeVisitor visitor : visitors) visitor.initTypes();\n        \n        // Notify visitors that are not done 'visitType'\n        try {\n            List<JFREventTypeVisitor> _visitors = new ArrayList<>(Arrays.asList(visitors));\n            int typeIdx = 0;\n            while (!_visitors.isEmpty() && typeIdx < types.length) {\n                EventArray type = types[typeIdx];\n                IType<IItem> itype = type.getType();\n                String typeId = itype.getIdentifier();\n                String[] typeCategory = type.getTypeCategory();\n                if (typeCategory == null) typeCategory = new String[] { \"Uncategorized\" };\n                JFREventType event = new JFRGenericEventType(typeIdx++, itype, typeCategory);\n                Iterator<JFREventTypeVisitor> _visitorsI = _visitors.iterator();\n                while (_visitorsI.hasNext())\n                    if (_visitorsI.next().visitType(typeId, event))\n                        _visitorsI.remove();\n            }\n        } catch (Exception e) {\n            LOGGER.log(Level.INFO, \"Error visiting JFR event types (generic loader)\", e);   // NOI18N\n        } finally {\n            // Notify all visitors 'done'\n            for (JFREventTypeVisitor visitor : visitors) visitor.doneTypes();\n        }\n    }\n    \n    \n    private static EventArray[] loadFile(File file) throws IOException, CouldNotLoadRecordingException {\n        InputStream stream = IOToolkit.openUncompressedStream(file);\n        try {\n            return FlightRecordingLoader.loadStream(stream, false, true).getArrays();\n        } finally {\n            IOToolkit.closeSilently(stream);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.generic/src/org/graalvm/visualvm/jfr/generic/model/impl/JFRGenericModelProvider.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.generic.model.impl;\n\nimport java.io.File;\nimport java.io.IOException;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.model.JFRModelFactory;\nimport org.graalvm.visualvm.jfr.model.JFRModelProvider;\nimport org.openjdk.jmc.flightrecorder.CouldNotLoadRecordingException;\nimport org.openjdk.jmc.flightrecorder.internal.NotEnoughMemoryException;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class JFRGenericModelProvider extends JFRModelProvider {\n    \n    private JFRGenericModelProvider() {\n        super(\"generic loader\", 10); // NOI18N\n    }\n    \n    \n    public static void register() {\n        JFRModelFactory.getDefault().registerProvider(new JFRGenericModelProvider());\n    }\n    \n    \n    @Override\n    protected JFRModel createModel(String id, File file) throws IOException, CouldNotLoadRecordingException {\n        try {\n            return new JFRGenericModel(id, file);\n        } catch (NotEnoughMemoryException e) {\n            throw new OutOfMemoryError(e.getMessage());\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.generic/src/org/graalvm/visualvm/jfr/generic/model/impl/JFRGenericStackFrame.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.generic.model.impl;\n\nimport org.graalvm.visualvm.jfr.model.JFRMethod;\nimport org.graalvm.visualvm.jfr.model.JFRStackFrame;\nimport org.openjdk.jmc.common.IMCFrame;\nimport org.openjdk.jmc.common.IMCMethod;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRGenericStackFrame extends JFRStackFrame {\n    \n    private final IMCFrame stackFrame;\n    \n    \n    JFRGenericStackFrame(IMCFrame stackFrame) {\n        this.stackFrame = stackFrame;\n    }\n    \n\n    @Override\n    public JFRMethod getMethod() {\n        IMCMethod method = stackFrame.getMethod();\n        return method == null ? null : new JFRGenericMethod(method);\n    }\n\n    @Override\n    public int getLine() {\n        return stackFrame.getFrameLineNumber();\n    }\n    \n    @Override\n    public int getBCI() {\n        return stackFrame.getBCI();\n    }\n\n    @Override\n    public String getType() {\n        IMCFrame.Type type = stackFrame.getType();\n        if (type.isUnknown()) {\n            return \"Native\";        // NOI18N  // ??\n        }\n        return type.getName();\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return stackFrame.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRGenericStackFrame && stackFrame.equals(((JFRGenericStackFrame) o).stackFrame);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.generic/src/org/graalvm/visualvm/jfr/generic/model/impl/JFRGenericStackTrace.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.generic.model.impl;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.graalvm.visualvm.jfr.model.JFRStackFrame;\nimport org.graalvm.visualvm.jfr.model.JFRStackTrace;\nimport org.openjdk.jmc.common.IMCFrame;\nimport org.openjdk.jmc.common.IMCStackTrace;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRGenericStackTrace extends JFRStackTrace {\n    \n    private final IMCStackTrace stackTrace;\n    \n    \n    JFRGenericStackTrace(IMCStackTrace stackTrace) {\n        this.stackTrace = stackTrace;\n    }\n\n    \n    @Override\n    public List<JFRStackFrame> getFrames() {\n        List<? extends IMCFrame> imcFrames = stackTrace.getFrames();\n        List<JFRStackFrame> frames = new ArrayList<>(imcFrames.size());\n        \n        for (IMCFrame imcFrame : imcFrames)\n            frames.add(new JFRGenericStackFrame(imcFrame));\n        \n        return frames;\n    }\n    \n    @Override\n    public boolean isTruncated() {\n        return stackTrace.getTruncationState().isTruncated();\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return stackTrace.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRGenericStackTrace && stackTrace.equals(((JFRGenericStackTrace) o).stackTrace);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.generic/src/org/graalvm/visualvm/jfr/generic/model/impl/JFRGenericThread.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.generic.model.impl;\n\nimport org.graalvm.visualvm.jfr.model.JFRThread;\nimport org.openjdk.jmc.common.IMCThread;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRGenericThread extends JFRThread {\n    \n    private final IMCThread thread;\n    \n    \n    JFRGenericThread(IMCThread thread) {\n        this.thread = thread;\n    }\n\n    \n    @Override\n    public long getId() {\n        // VM Thread throws NPE here\n        try { return thread.getThreadId(); }\n        catch (NullPointerException e) { return 0; }\n    }\n\n    @Override\n    public String getName() {\n        return thread.getThreadName();\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return thread.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRGenericThread && thread.equals(((JFRGenericThread) o).thread);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.jdk11/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.jfr.jdk11\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.jfr.jdk11.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/jfr.jdk11/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nOpenIDE-Module: org.graalvm.visualvm.jfr.jdk11/2\nOpenIDE-Module-Install: org/graalvm/visualvm/jfr/jdk11/Installer.class\nOpenIDE-Module-Java-Dependencies: Java > 11\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/jfr/jdk11/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.2\nOpenIDE-Module-Provides: jfr.implementation\n"
  },
  {
    "path": "visualvm/jfr.jdk11/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.jfr.jdk11-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/jfr.jdk11/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=1ba7908e\nbuild.xml.script.CRC32=c2718227\nbuild.xml.stylesheet.CRC32=15ca8a54@2.75.1\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=1ba7908e\nnbproject/build-impl.xml.script.CRC32=dc0dd611\nnbproject/build-impl.xml.stylesheet.CRC32=1016842c@2.75.1\n"
  },
  {
    "path": "visualvm/jfr.jdk11/nbproject/project.properties",
    "content": "is.autoload=true\njavac.compilerargs=-Xlint -Xlint:-serial\njavac.source=11\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jiri Sedlacek\nnbm.needs.restart=true\n"
  },
  {
    "path": "visualvm/jfr.jdk11/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.jfr.jdk11</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.jfr</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.49</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/jfr.jdk11/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/jfr.jdk11/src/org/graalvm/visualvm/jfr/jdk11/Bundle.properties",
    "content": "#\n# Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=JFR Loaders\nOpenIDE-Module-Long-Description=\\\n    Support for the JFR loader bundled with JDK 11 and newer (requires running VisualVM on JDK 11+) reading JFR snapshots created from JDK 9 and newer. \\\n    Requires VisualVM-JFR-JDK9 to be installed as well.\nOpenIDE-Module-Name=VisualVM-JFR-JDK11\nOpenIDE-Module-Short-Description=Support for the JFR loader bundled with JDK 11 and newer reading JFR snapshots created from JDK 11 and newer\n"
  },
  {
    "path": "visualvm/jfr.jdk11/src/org/graalvm/visualvm/jfr/jdk11/Installer.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jfr.jdk11;\n\nimport org.graalvm.visualvm.jfr.jdk11.model.impl.JFRJDK11ModelProvider;\nimport org.openide.modules.ModuleInstall;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class Installer extends ModuleInstall {\n    \n    public void restored() {\n        JFRJDK11ModelProvider.register();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.jdk11/src/org/graalvm/visualvm/jfr/jdk11/model/impl/DisplayableSupport.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.jdk11.model.impl;\n\nimport java.lang.annotation.Annotation;\nimport java.text.FieldPosition;\nimport java.text.Format;\nimport java.text.NumberFormat;\nimport java.text.ParsePosition;\nimport java.time.Duration;\nimport java.time.Instant;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Set;\nimport jdk.jfr.DataAmount;\nimport jdk.jfr.EventType;\nimport jdk.jfr.Experimental;\nimport jdk.jfr.Frequency;\nimport jdk.jfr.MemoryAddress;\nimport jdk.jfr.Percentage;\nimport jdk.jfr.Timespan;\nimport jdk.jfr.Timestamp;\nimport jdk.jfr.ValueDescriptor;\nimport jdk.jfr.consumer.RecordedClass;\nimport jdk.jfr.consumer.RecordedClassLoader;\nimport jdk.jfr.consumer.RecordedThread;\nimport org.graalvm.visualvm.jfr.model.JFRDataDescriptor;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.jfr.utils.DurationFormatter;\nimport org.graalvm.visualvm.jfr.utils.InstantFormatter;\nimport org.graalvm.visualvm.jfr.utils.ValuesChecker;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class DisplayableSupport {\n    \n    private static final String VALUE_NA = \"n/a\";\n    \n    private static final DefaultProcessor DEFAULT_PROCESSOR = new DefaultProcessor();\n    private static final DefaultFormat DEFAULT_FORMAT = new DefaultFormat();\n    \n    private static final FormatProcessor<? extends Annotation>[] FORMAT_PROCESSORS = new FormatProcessor<?>[] {\n        new TimestampFormatProcessor(),\n        new TimespanFormatProcessor(),\n        new MemoryAddressFormatProcessor(),\n        new FrequencyFormatProcessor(), // must be before DataAmountFormatProcessor!\n        new PercentFormatProcessor(),\n        new DataAmountFormatProcessor(), // must be the last item!\n    };\n    \n    private static final TypeProcessor[] TYPE_PROCESSORS = new TypeProcessor[] {\n        new RecordedThreadProcessor(),\n        new RecordedClassProcessor(),\n        new RecordedClassLoaderProcessor()\n    };\n    \n    private static final Set<String> PRIMITIVE_NUMERIC = new HashSet<>(Arrays.asList(\"byte\", \"short\", \"int\", \"long\", \"char\", \"float\", \"double\" // char?\n    ));\n    \n    \n    static Iterator<ValueDescriptor> displayableValueDescriptors(final EventType type, final boolean includeExperimental) {\n        return new Iterator<ValueDescriptor>() {\n            private final String ID_STACKTRACE;\n            \n            private final Iterator<ValueDescriptor> master;\n            private ValueDescriptor next;\n            \n            {\n                ID_STACKTRACE = \"stackTrace\"; // NOI18N\n                \n                master = type.getFields().iterator();\n                next = computeNext();\n            }\n            \n            @Override\n            public boolean hasNext() {\n                return next != null;\n            }\n\n            @Override\n            public ValueDescriptor next() {\n                ValueDescriptor ret = next;\n                next = computeNext();\n                return ret;\n            }\n            \n            private ValueDescriptor computeNext() {\n                while (master.hasNext()) {\n                    ValueDescriptor _next = master.next();\n                    if (isDisplayable(_next)) return _next;\n                }\n                return null;\n            }\n            \n            private boolean isDisplayable(ValueDescriptor descriptor) {\n                if (ID_STACKTRACE.equals(descriptor.getName())) return false;\n                return includeExperimental || !isExperimental(descriptor);\n            }\n        };\n    }\n    \n    \n    static JFRDataDescriptor getDataDescriptor(ValueDescriptor descriptor) {\n        Format dataFormat = null;\n        boolean isNumeric = false;\n        \n        for (FormatProcessor processor : FORMAT_PROCESSORS) {\n            Annotation annotation = descriptor.getAnnotation(processor.getType());\n            if (annotation != null) {\n                dataFormat = processor.createFormat(descriptor, annotation);\n                if (dataFormat != null) {\n                    isNumeric = processor.isNumeric();\n                    break;\n                }\n            }\n        }\n        \n        if (dataFormat == null) for (TypeProcessor processor : TYPE_PROCESSORS) {\n            String typeName = descriptor.getTypeName();\n            if (processor.handlesType(typeName)) {\n                dataFormat = processor.createFormat();\n                if (dataFormat != null) {\n                    isNumeric = processor.isNumeric();\n                    break;\n                }\n            }\n        }\n        \n        if (dataFormat == null) {\n            dataFormat = DEFAULT_FORMAT;\n            isNumeric = DEFAULT_PROCESSOR.isNumeric(descriptor);\n        }\n        \n        String dataName = descriptor.getLabel();\n        if (isExperimental(descriptor)) dataName = \"[Experimental] \" + dataName;\n        \n        return new JFRDataDescriptor(dataName, descriptor.getDescription(), dataFormat, null, isNumeric);\n    }\n    \n    \n    static Comparable<?> getDisplayValue(JFRJDK11Event event, ValueDescriptor descriptor) {\n//        List<AnnotationElement> annotations = descriptor.getAnnotationElements();\n//        for (AnnotationElement annotation : annotations) System.err.println(\">>> ANNOTATION \" + annotation.getTypeName() + \" - \" + annotation.getValues());\n//        System.err.println(\">>> ContentType \" + descriptor.getContentType());\n//        System.err.println(\">>> TypeName \" + descriptor.getTypeName());\n//        try { System.err.println(\">>> VALUE \" + event.getValue(descriptor.getName()).getClass().getName()); } catch (Throwable t) {}\n//        System.err.println(\">>> --------------------------\");\n        \n        for (FormatProcessor processor : FORMAT_PROCESSORS) {\n            Annotation annotation = descriptor.getAnnotation(processor.getType());\n            if (annotation != null) try { return processor.createValue(event, descriptor, annotation); }\n                                    catch (JFRPropertyNotAvailableException ex) { return null; }\n        }\n        \n        for (TypeProcessor processor : TYPE_PROCESSORS) {\n            String typeName = descriptor.getTypeName();\n            if (processor.handlesType(typeName)) try { return processor.createValue(event, descriptor); }\n                                                 catch (JFRPropertyNotAvailableException ex) { return null; }\n        }\n        \n        try { return DEFAULT_PROCESSOR.createValue(event, descriptor); }\n        catch (JFRPropertyNotAvailableException ex) { return null; }\n    }\n    \n    \n    private static boolean isExperimental(ValueDescriptor descriptor) {\n        return descriptor.getAnnotation(Experimental.class) != null;\n    }\n    \n    \n    private DisplayableSupport() {}\n    \n    \n    private static final NumberFormat DURATION_MS_FORMAT;\n    private static final NumberFormat NUMBER_FORMAT;\n    private static final NumberFormat PERCENT_FORMAT;\n    \n    static {\n        DURATION_MS_FORMAT = NumberFormat.getNumberInstance();\n        DURATION_MS_FORMAT.setMaximumFractionDigits(3);\n        DURATION_MS_FORMAT.setMinimumFractionDigits(3);\n        \n        NUMBER_FORMAT = NumberFormat.getNumberInstance();\n        \n        PERCENT_FORMAT = NumberFormat.getPercentInstance();\n        PERCENT_FORMAT.setMaximumFractionDigits(2);\n        PERCENT_FORMAT.setMinimumFractionDigits(2);\n    }\n    \n    \n    private static abstract class DataFormat extends Format {\n        \n        @Override\n        public Object parseObject(String source, ParsePosition pos) {\n            throw new UnsupportedOperationException(\"Not supported\");\n        }\n        \n    }\n    \n    \n    private static abstract class FormatProcessor<A extends Annotation> {\n        \n        abstract Class<A> getType();\n        \n        Format createFormat(ValueDescriptor descriptor, A annotation) {\n            return null;\n        }\n        \n        Comparable<?> createValue(JFRJDK11Event event, ValueDescriptor descriptor, A annotation) throws JFRPropertyNotAvailableException {\n            Object value = event.getValue(descriptor.getName());\n            return value instanceof Comparable ? (Comparable)value :\n                   value != null ? value.toString() : null;\n        }\n        \n        boolean isNumeric() {\n            return false;\n        }\n        \n    }\n    \n    \n    private static class TimestampFormatProcessor extends FormatProcessor<Timestamp> {\n        \n        @Override\n        Class<Timestamp> getType() {\n            return Timestamp.class;\n        }\n\n        @Override\n        Format createFormat(ValueDescriptor descriptor, Timestamp annotation) {\n            return new TimestampFormat();\n        }\n        \n        @Override\n        Comparable<?> createValue(JFRJDK11Event event, ValueDescriptor descriptor, Timestamp annotation) throws JFRPropertyNotAvailableException {\n            return event.getInstant(descriptor.getName());\n        }\n        \n    }\n    \n    private static final class TimestampFormat extends DataFormat {\n\n        @Override\n        public StringBuffer format(Object o, StringBuffer b, FieldPosition p) {\n            if (ValuesChecker.isNAValue(o)) return b.append(VALUE_NA);\n            \n            return o instanceof Instant ? InstantFormatter.format((Instant)o, b) :\n                   o == null ? b : b.append(\"<unknown>\");\n        }\n        \n    }\n    \n    \n    private static class TimespanFormatProcessor extends FormatProcessor<Timespan> {\n        \n        @Override\n        Class<Timespan> getType() {\n            return Timespan.class;\n        }\n\n        @Override\n        Format createFormat(ValueDescriptor descriptor, Timespan annotation) {\n            return new TimespanFormat();\n        }\n        \n        @Override\n        Comparable<?> createValue(JFRJDK11Event event, ValueDescriptor descriptor, Timespan annotation) throws JFRPropertyNotAvailableException {\n            return event.getDuration(descriptor.getName());\n        }\n        \n        @Override\n        boolean isNumeric() {\n            return true;\n        }\n        \n    }\n    \n    private static final class TimespanFormat extends DataFormat {\n\n        @Override\n        public StringBuffer format(Object o, StringBuffer b, FieldPosition p) {\n            if (ValuesChecker.isNAValue(o)) return b.append(VALUE_NA);\n            \n            return o instanceof Duration ? DurationFormatter.format((Duration)o, b) :\n                   o == null ? b : b.append(\"<unknown>\");\n        }\n        \n    }\n    \n    \n    private static class MemoryAddressFormatProcessor extends FormatProcessor<MemoryAddress> {\n        \n        @Override\n        Class<MemoryAddress> getType() {\n            return MemoryAddress.class;\n        }\n\n        @Override\n        Format createFormat(ValueDescriptor descriptor, MemoryAddress annotation) {\n            return new MemoryAddressFormat();\n        }\n        \n        @Override\n        boolean isNumeric() {\n            return true;\n        }\n        \n    }\n    \n    private static final class MemoryAddressFormat extends DataFormat {\n\n        @Override\n        public StringBuffer format(Object o, StringBuffer b, FieldPosition p) {\n            if (ValuesChecker.isNAValue(o)) return b.append(VALUE_NA);\n            \n            return o instanceof Number ? b.append(\"0x\").append(Long.toHexString(((Number)o).longValue())) :\n                   o == null ? b : b.append(\"<unknown>\");\n        }\n        \n    }\n    \n    \n    private static class FrequencyFormatProcessor extends FormatProcessor<Frequency> {\n        \n        @Override\n        Class<Frequency> getType() {\n            return Frequency.class;\n        }\n\n        @Override\n        Format createFormat(ValueDescriptor descriptor, Frequency annotation) {\n            FormatProcessor dataAmountProcessor = FORMAT_PROCESSORS[FORMAT_PROCESSORS.length - 1];\n            Annotation dataAmountAnnotation = descriptor.getAnnotation(dataAmountProcessor.getType());\n            return new FrequencyFormat(dataAmountAnnotation == null ? null : dataAmountProcessor.createFormat(descriptor, dataAmountAnnotation));\n        }\n        \n        @Override\n        boolean isNumeric() {\n            return true;\n        }\n        \n    }\n    \n    private static final class FrequencyFormat extends DataFormat {\n        \n        private final Format originalFormat;\n        \n        FrequencyFormat(Format originalFormat) {\n            this.originalFormat = originalFormat;\n        }\n\n        @Override\n        public StringBuffer format(Object o, StringBuffer b, FieldPosition p) {\n            if (ValuesChecker.isNAValue(o)) return b.append(VALUE_NA);\n            \n            return o instanceof Number ? formatFrequency((Number)o, b, p, originalFormat) :\n                   o == null ? b : b.append(\"<unknown>\");\n        }\n        \n        private static StringBuffer formatFrequency(Number n, StringBuffer b, FieldPosition p, Format f) {\n            if (f == null) return b.append(NUMBER_FORMAT.format(n.longValue())).append(\" Hz\");\n            else return f.format(n, b, p).append(\"/s\");\n        }\n        \n    }\n    \n    private static class DataAmountFormatProcessor extends FormatProcessor<DataAmount> {\n        \n        @Override\n        Class<DataAmount> getType() {\n            return DataAmount.class;\n        }\n\n        @Override\n        Format createFormat(ValueDescriptor descriptor, DataAmount annotation) {\n            return new DataAmountFormat(annotation.value());\n        }\n        \n        @Override\n        boolean isNumeric() {\n            return true;\n        }\n        \n    }\n    \n    private static final class DataAmountFormat extends DataFormat {\n        \n        private final String dataSuffix;\n        \n        DataAmountFormat(String dataFormat) {\n            this.dataSuffix = DataAmount.BYTES.equals(dataFormat) ? \" B\" :\n                              DataAmount.BITS.equals(dataFormat) ? \" b\" :\n                              \"\";\n        }\n\n        @Override\n        public StringBuffer format(Object o, StringBuffer b, FieldPosition p) {\n            if (ValuesChecker.isNAValue(o)) return b.append(VALUE_NA);\n            \n            return o instanceof Number ? b.append(NUMBER_FORMAT.format(((Number)o).longValue())).append(dataSuffix) :\n                   o == null ? b : b.append(\"<unknown>\");\n        }\n        \n    }\n    \n    \n    private static class PercentFormatProcessor extends FormatProcessor<Percentage> {\n        \n        @Override\n        Class<Percentage> getType() {\n            return Percentage.class;\n        }\n\n        @Override\n        Format createFormat(ValueDescriptor descriptor, Percentage annotation) {\n            return new PercentFormat();\n        }\n        \n        @Override\n        boolean isNumeric() {\n            return true;\n        }\n        \n    }\n    \n    private static final class PercentFormat extends DataFormat {\n\n        @Override\n        public StringBuffer format(Object o, StringBuffer b, FieldPosition p) {\n            if (ValuesChecker.isNAValue(o)) return b.append(VALUE_NA);\n            \n            return o instanceof Number ? b.append(PERCENT_FORMAT.format(((Number)o).doubleValue())) :\n                   o == null ? b : b.append(\"<unknown>\");\n        }\n        \n    }\n    \n    \n    private static abstract class TypeProcessor {\n        \n        abstract boolean handlesType(String typeName);\n        \n        Format createFormat() {\n            return null;\n        }\n        \n        Comparable<?> createValue(JFRJDK11Event event, ValueDescriptor descriptor) throws JFRPropertyNotAvailableException {\n            Object value = event.getValue(descriptor.getName());\n            return value instanceof Comparable ? (Comparable)value :\n                   value == null ? \"\" : value.toString();\n        }\n        \n        boolean isNumeric() {\n            return false;\n        }\n        \n    }\n    \n    \n    private static class RecordedThreadProcessor extends TypeProcessor {\n        \n        @Override\n        boolean handlesType(String typeName) {\n            return Thread.class.getName().equals(typeName);\n        }\n        \n        @Override\n        String createValue(JFRJDK11Event event, ValueDescriptor descriptor) throws JFRPropertyNotAvailableException {\n            Object value = event.getValue(descriptor.getName());\n            RecordedThread thread = value instanceof RecordedThread ? (RecordedThread)value : null;\n            if (thread == null) return \"\";\n            String name = thread.getJavaName();\n            return name != null ? name : thread.getOSName();\n        }\n        \n    }\n    \n    private static class RecordedClassProcessor extends TypeProcessor {\n        \n        @Override\n        boolean handlesType(String typeName) {\n            return Class.class.getName().equals(typeName);\n        }\n        \n        @Override\n        String createValue(JFRJDK11Event event, ValueDescriptor descriptor) throws JFRPropertyNotAvailableException {\n            Object value = event.getValue(descriptor.getName());\n            return value instanceof RecordedClass ? ((RecordedClass)value).getName(): \"\";\n        }\n        \n    }\n    \n    private static class RecordedClassLoaderProcessor extends TypeProcessor {\n        \n        @Override\n        boolean handlesType(String typeName) {\n            return \"jdk.types.ClassLoader\".equals(typeName) ||\n                   \"com.oracle.jfr.types.ClassLoader\".equals(typeName);\n        }\n        \n        @Override\n        String createValue(JFRJDK11Event event, ValueDescriptor descriptor) throws JFRPropertyNotAvailableException {\n            Object value = event.getValue(descriptor.getName());\n            return value instanceof RecordedClassLoader ? ((RecordedClassLoader)value).getType().getName(): \"\"; // NOTE: should actually be \"bootstrap\"\n        }\n        \n    }\n    \n    \n    private static class DefaultProcessor {\n        \n        Comparable<?> createValue(JFRJDK11Event event, ValueDescriptor descriptor) throws JFRPropertyNotAvailableException {\n            Object value = event.getValue(descriptor.getName());\n            \n            if (value == null) return null;\n            \n            if (value instanceof Comparable) return (Comparable<?>)value;\n            \n            return value.toString(); // Also includes RecordedObject which needs to be handled separately!\n        }\n        \n        boolean isNumeric(ValueDescriptor descriptor) {\n            return PRIMITIVE_NUMERIC.contains(descriptor.getTypeName());\n        }\n        \n    }\n    \n    private static final class DefaultFormat extends DataFormat {\n\n        @Override\n        public StringBuffer format(Object o, StringBuffer b, FieldPosition p) {\n            if (ValuesChecker.isNAValue(o)) return b.append(VALUE_NA);\n            \n            return o instanceof Number ? b.append(NUMBER_FORMAT.format(o)) :\n                   o == null ? b : b.append(o.toString());\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.jdk11/src/org/graalvm/visualvm/jfr/jdk11/model/impl/JFRJDK11Class.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.jdk11.model.impl;\n\nimport jdk.jfr.consumer.RecordedClass;\nimport org.graalvm.visualvm.jfr.model.JFRClass;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRJDK11Class extends JFRClass {\n    \n    private final RecordedClass rclass;\n    \n    \n    JFRJDK11Class(RecordedClass rclass) {\n        this.rclass = rclass;\n    }\n\n    \n    @Override\n    public String getName() {\n        return rclass.getName();\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return rclass.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRJDK11Class && rclass.equals(((JFRJDK11Class) o).rclass);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.jdk11/src/org/graalvm/visualvm/jfr/jdk11/model/impl/JFRJDK11Event.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.jdk11.model.impl;\n\nimport java.time.Duration;\nimport java.time.Instant;\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\nimport jdk.jfr.ValueDescriptor;\nimport jdk.jfr.consumer.RecordedClass;\nimport jdk.jfr.consumer.RecordedEvent;\nimport jdk.jfr.consumer.RecordedStackTrace;\nimport jdk.jfr.consumer.RecordedThread;\nimport org.graalvm.visualvm.jfr.model.JFRClass;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFRPropertyNotAvailableException;\nimport org.graalvm.visualvm.jfr.model.JFRStackTrace;\nimport org.graalvm.visualvm.jfr.model.JFRThread;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRJDK11Event extends JFREvent {\n    \n    protected final RecordedEvent event;\n\n    public JFRJDK11Event(RecordedEvent event, long id) {\n        super(id);\n        this.event = event;\n    }\n\n    @Override\n    public JFRClass getClass(String key) throws JFRPropertyNotAvailableException {\n        Object rclass = getValue(key);\n\n        if (rclass == null) return null;\n        else if (rclass instanceof RecordedClass) return new JFRJDK11Class((RecordedClass)rclass);\n        else throw new JFRPropertyNotAvailableException(\"No class value available: \" + key);\n    }\n\n    @Override\n    public JFRThread getThread(String key) throws JFRPropertyNotAvailableException {\n        if (\"eventThread\".equals(key)) { // NOI18N\n            RecordedThread thread = event.getThread();\n            return thread == null ? null : new JFRJDK11Thread(thread);\n        }\n\n        Object thread = getValue(key);\n        if (thread instanceof RecordedThread) return new JFRJDK11Thread((RecordedThread)thread);\n        else if (thread == null) return null;\n        else throw new JFRPropertyNotAvailableException(\"No thread value available: \" + key);\n    }\n\n    @Override\n    public JFRStackTrace getStackTrace(String key) throws JFRPropertyNotAvailableException {\n        if (\"eventStackTrace\".equals(key)) { // NOI18N\n            RecordedStackTrace stackTrace = event.getStackTrace();\n            return stackTrace == null ? null : new JFRJDK11StackTrace(stackTrace);\n        }\n\n        Object stackTrace = getValue(key);\n        if (stackTrace instanceof RecordedStackTrace) return new JFRJDK11StackTrace((RecordedStackTrace)stackTrace);\n        else if (stackTrace == null) return null;\n        else throw new JFRPropertyNotAvailableException(\"No stacktrace value available: \" + key);\n    }\n\n    @Override\n    public Object getValue(String key) throws JFRPropertyNotAvailableException {\n        try {\n            return event.getValue(key);\n        } catch (IllegalArgumentException e) {\n            throw new JFRPropertyNotAvailableException(e);\n        }\n    }\n\n\n    @Override\n    public List<Comparable<?>> getDisplayableValues(boolean includeExperimental) {\n        List<Comparable<?>> values = new ArrayList<>();\n        Iterator<ValueDescriptor> descriptors = DisplayableSupport.displayableValueDescriptors(event.getEventType(), includeExperimental);\n        while (descriptors.hasNext()) values.add(DisplayableSupport.getDisplayValue(this, descriptors.next()));\n        return values;\n    }\n\n    \n    @Override\n    public boolean getBoolean(String key) throws JFRPropertyNotAvailableException {\n        try {\n            return event.getBoolean(key);\n        } catch (IllegalArgumentException e) {\n            throw new JFRPropertyNotAvailableException(e);\n        }\n    }\n\n    @Override\n    public byte getByte(String key) throws JFRPropertyNotAvailableException {\n        try {\n            return event.getByte(key);\n        } catch (IllegalArgumentException e) {\n            throw new JFRPropertyNotAvailableException(e);\n        }\n    }\n\n    @Override\n    public char getChar(String key) throws JFRPropertyNotAvailableException {\n        try {\n            return event.getChar(key);\n        } catch (IllegalArgumentException e) {\n            throw new JFRPropertyNotAvailableException(e);\n        }\n    }\n\n    @Override\n    public double getDouble(String key) throws JFRPropertyNotAvailableException {\n        try {\n            return event.getDouble(key);\n        } catch (IllegalArgumentException e) {\n            throw new JFRPropertyNotAvailableException(e);\n        }\n    }\n\n    @Override\n    public float getFloat(String key) throws JFRPropertyNotAvailableException {\n        try {\n            return event.getFloat(key);\n        } catch (IllegalArgumentException e) {\n            throw new JFRPropertyNotAvailableException(e);\n        }\n    }\n\n    @Override\n    public int getInt(String key) throws JFRPropertyNotAvailableException {\n        try {\n            return event.getInt(key);\n        } catch (IllegalArgumentException e) {\n            throw new JFRPropertyNotAvailableException(e);\n        }\n    }\n\n    @Override\n    public long getLong(String key) throws JFRPropertyNotAvailableException {\n        try {\n            return event.getLong(key);\n        } catch (IllegalArgumentException e) {\n            throw new JFRPropertyNotAvailableException(e);\n        }\n    }\n\n    @Override\n    public short getShort(String key) throws JFRPropertyNotAvailableException {\n        try {\n            return event.getShort(key);\n        } catch (IllegalArgumentException e) {\n            throw new JFRPropertyNotAvailableException(e);\n        }\n    }\n    \n    @Override\n    public String getString(String key) throws JFRPropertyNotAvailableException {\n        try {\n            return event.getString(key);\n        } catch (IllegalArgumentException e) {\n            throw new JFRPropertyNotAvailableException(e);\n        }\n    }\n    \n    \n    @Override\n    public Instant getInstant(String key) throws JFRPropertyNotAvailableException {\n        switch (key) {\n            case \"eventTime\": // NOI18N\n            case \"startTime\": // NOI18N\n                return event.getStartTime();\n                \n            case \"endTime\": // NOI18N\n                return event.getEndTime();\n        }\n        \n        try {\n            return event.getInstant(key);\n        } catch (IllegalArgumentException e) {\n            throw new JFRPropertyNotAvailableException(e);\n        }\n    }\n    \n    @Override\n    public Duration getDuration(String key) throws JFRPropertyNotAvailableException {\n        if (\"eventDuration\".equals(key)) { // NOI18N\n            return event.getDuration();\n        } else try {\n            return event.getDuration(key);\n        } catch (IllegalArgumentException e) {\n            throw new JFRPropertyNotAvailableException(e);\n        }\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return event.hashCode();\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRJDK11Event && event.equals(((JFRJDK11Event) o).event);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.jdk11/src/org/graalvm/visualvm/jfr/jdk11/model/impl/JFRJDK11EventType.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.jdk11.model.impl;\n\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\nimport jdk.jfr.EventType;\nimport jdk.jfr.Experimental;\nimport jdk.jfr.ValueDescriptor;\nimport org.graalvm.visualvm.jfr.model.JFRDataDescriptor;\nimport org.graalvm.visualvm.jfr.model.JFREventType;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRJDK11EventType extends JFREventType {\n    \n    private final EventType type;\n    \n    \n    JFRJDK11EventType(EventType type) {\n        this.type = type;\n    }\n    \n    \n    @Override\n    public long getId() {\n        return type.getId();\n    }\n\n    @Override\n    public String getName() {\n        return type.getName();\n    }\n\n    @Override\n    public String getDisplayName() {\n        return isExperimental() ? \"[Experimental] \" + type.getLabel() : type.getLabel();\n    }\n\n    @Override\n    public String getDescription() {\n        return type.getDescription();\n    }\n    \n    @Override\n    public List<String> getCategory() {\n        return type.getCategoryNames();\n    }\n    \n    \n    @Override\n    public boolean isExperimental() {\n        return type.getAnnotation(Experimental.class) != null;\n    }\n    \n    \n    @Override\n    public List<JFRDataDescriptor> getDisplayableDataDescriptors(boolean includeExperimental) {\n        List<JFRDataDescriptor> ddescriptors = new ArrayList<>();\n        Iterator<ValueDescriptor> vdescriptors = DisplayableSupport.displayableValueDescriptors(type, includeExperimental);\n        while (vdescriptors.hasNext()) ddescriptors.add(DisplayableSupport.getDataDescriptor(vdescriptors.next()));\n        return ddescriptors;\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return type.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRJDK11EventType && type.equals(((JFRJDK11EventType) o).type);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.jdk11/src/org/graalvm/visualvm/jfr/jdk11/model/impl/JFRJDK11Method.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.jdk11.model.impl;\n\nimport jdk.jfr.consumer.RecordedClass;\nimport jdk.jfr.consumer.RecordedMethod;\nimport org.graalvm.visualvm.jfr.model.JFRClass;\nimport org.graalvm.visualvm.jfr.model.JFRMethod;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRJDK11Method extends JFRMethod {\n    \n    private final RecordedMethod method;\n    \n    \n    JFRJDK11Method(RecordedMethod method) {\n        this.method = method;\n    }\n\n    \n    @Override\n    public String getName() {\n        return method.getName();\n    }\n    \n    @Override\n    public String getDescriptor() {\n        return method.getDescriptor();\n    }\n\n    @Override\n    public JFRClass getType() {\n        RecordedClass rclass = method.getType();\n        return rclass == null ? null : new JFRJDK11Class(rclass);\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return method.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRJDK11Method && method.equals(((JFRJDK11Method) o).method);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.jdk11/src/org/graalvm/visualvm/jfr/jdk11/model/impl/JFRJDK11Model.java",
    "content": "/*\n * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.jdk11.model.impl;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport jdk.jfr.EventType;\nimport jdk.jfr.consumer.RecordedEvent;\nimport jdk.jfr.consumer.RecordingFile;\nimport org.graalvm.visualvm.jfr.model.JFREvent;\nimport org.graalvm.visualvm.jfr.model.JFREventType;\nimport org.graalvm.visualvm.jfr.model.JFREventTypeVisitor;\nimport org.graalvm.visualvm.jfr.model.JFREventVisitor;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JFRJDK11Model extends JFRModel {\n    private static final Logger LOGGER = Logger.getLogger(JFRModel.class.getName());\n    \n    protected static final String SNAPSHOT_V1_PREFIX = \"com.oracle.\"; // NOI18N\n    protected static final int SNAPSHOT_V1_PREFIX_LENGTH = SNAPSHOT_V1_PREFIX.length();\n\n    private int snapshotVersion;\n    private final File snapshotFile;\n    \n    \n    protected JFRJDK11Model(String id, File file) throws IOException {\n        super(id);\n\n        this.snapshotFile = file;\n\n        // Will throw IOException for an unsupported JFR format (0.9 or 2+)\n        try (RecordingFile events = new RecordingFile(snapshotFile.toPath())) {}\n\n        initialize();\n        LOGGER.log(Level.FINE, \"JFRJDK11Model created for \"+file);\n    }\n\n\n    @Override\n    public void visitEvents(JFREventVisitor... visitors) {\n        // Notify all visitors 'init'\n        for (JFREventVisitor visitor : visitors) visitor.init();\n\n        // Notify visitors that are not done 'visit'\n        try (RecordingFile events = new RecordingFile(snapshotFile.toPath())) {\n            List<JFREventVisitor> _visitors = new ArrayList<>(Arrays.asList(visitors));\n            long id = 0;\n            while (!_visitors.isEmpty() && events.hasMoreEvents()) {\n                RecordedEvent revent = events.readEvent();\n                String typeId = getTypeId(revent.getEventType());\n                JFREvent event = createEvent(revent, id++);\n                Iterator<JFREventVisitor> _visitorsI = _visitors.iterator();\n                while (_visitorsI.hasNext())\n                    if (_visitorsI.next().visit(typeId, event))\n                        _visitorsI.remove();\n            }\n        } catch (Exception e) {\n            LOGGER.log(Level.INFO, \"Error visiting JFR events (\" + getID()+ \")\", e);   // NOI18N\n        } finally {\n            // Notify all visitors 'done'\n            for (JFREventVisitor visitor : visitors) visitor.done();\n        }\n    }\n    \n    \n    @Override\n    public void visitEventTypes(JFREventTypeVisitor... visitors) {\n        // Notify all visitors 'init'\n        for (JFREventTypeVisitor visitor : visitors) visitor.initTypes();\n\n        // Notify visitors that are not done 'visit'\n        try (RecordingFile events = new RecordingFile(snapshotFile.toPath())) {\n            Iterator<EventType> types = events.readEventTypes().iterator();\n            List<JFREventTypeVisitor> _visitors = new ArrayList<>(Arrays.asList(visitors));\n            while (!_visitors.isEmpty() && types.hasNext()) {\n                EventType etype = types.next();\n                String typeId = getTypeId(etype);\n                JFREventType type = new JFRJDK11EventType(etype);\n                Iterator<JFREventTypeVisitor> _visitorsI = _visitors.iterator();\n                while (_visitorsI.hasNext())\n                    if (_visitorsI.next().visitType(typeId, type))\n                        _visitorsI.remove();\n            }\n        } catch (Exception e) {\n            LOGGER.log(Level.INFO, \"Error visiting JFR event types (\" + getID()+ \")\", e);   // NOI18N\n        } finally {\n            // Notify all visitors 'done'\n            for (JFREventTypeVisitor visitor : visitors) visitor.doneTypes();\n        }\n    }\n\n\n    protected String getTypeId(EventType eventType) {\n        String typeId = eventType.getName();\n        if (snapshotVersion == 0) {\n            if (isV1Id(typeId)) snapshotVersion = 1;\n            else snapshotVersion = 2;\n        }\n        return snapshotVersion == 1 ? normalizeV1Id(typeId) : typeId;\n    }\n    \n    protected static boolean isV1Id(String typeId) {\n        return typeId.startsWith(SNAPSHOT_V1_PREFIX);\n    }\n\n    protected static String normalizeV1Id(String typeId) {\n        return typeId.substring(SNAPSHOT_V1_PREFIX_LENGTH);\n    }\n\n    protected JFREvent createEvent(RecordedEvent revent, long id) {\n        return new JFRJDK11Event(revent, id);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.jdk11/src/org/graalvm/visualvm/jfr/jdk11/model/impl/JFRJDK11ModelProvider.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.jdk11.model.impl;\n\nimport java.io.File;\nimport java.io.IOException;\nimport org.graalvm.visualvm.jfr.model.JFRModel;\nimport org.graalvm.visualvm.jfr.model.JFRModelFactory;\nimport org.graalvm.visualvm.jfr.model.JFRModelProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class JFRJDK11ModelProvider extends JFRModelProvider {\n    \n    private JFRJDK11ModelProvider() {\n        super(\"JDK11 loader\", 1000); // NOI18N\n    }\n    \n    \n    public static void register() {\n        JFRModelFactory.getDefault().registerProvider(new JFRJDK11ModelProvider());\n    }\n    \n\n    @Override\n    protected JFRModel createModel(String id, File file) throws IOException {\n        return new JFRJDK11Model(id, file);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.jdk11/src/org/graalvm/visualvm/jfr/jdk11/model/impl/JFRJDK11StackFrame.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.jdk11.model.impl;\n\nimport jdk.jfr.consumer.RecordedFrame;\nimport jdk.jfr.consumer.RecordedMethod;\nimport org.graalvm.visualvm.jfr.model.JFRMethod;\nimport org.graalvm.visualvm.jfr.model.JFRStackFrame;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRJDK11StackFrame extends JFRStackFrame {\n    \n    private final RecordedFrame stackFrame;\n    \n    \n    JFRJDK11StackFrame(RecordedFrame stackFrame) {\n        this.stackFrame = stackFrame;\n    }\n    \n\n    @Override\n    public JFRMethod getMethod() {\n        RecordedMethod method = stackFrame.getMethod();\n        return method == null ? null : new JFRJDK11Method(method);\n    }\n\n    @Override\n    public int getLine() {\n        return stackFrame.getLineNumber();\n    }\n    \n    @Override\n    public int getBCI() {\n        return stackFrame.getBytecodeIndex();\n    }\n\n    @Override\n    public String getType() {\n        return stackFrame.getType();\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return stackFrame.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRJDK11StackFrame && stackFrame.equals(((JFRJDK11StackFrame) o).stackFrame);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.jdk11/src/org/graalvm/visualvm/jfr/jdk11/model/impl/JFRJDK11StackTrace.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.jdk11.model.impl;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport jdk.jfr.consumer.RecordedFrame;\nimport jdk.jfr.consumer.RecordedStackTrace;\nimport org.graalvm.visualvm.jfr.model.JFRStackFrame;\nimport org.graalvm.visualvm.jfr.model.JFRStackTrace;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRJDK11StackTrace extends JFRStackTrace {\n    \n    private final RecordedStackTrace stackTrace;\n    \n    \n    JFRJDK11StackTrace(RecordedStackTrace stackTrace) {\n        this.stackTrace = stackTrace;\n    }\n\n    \n    @Override\n    public List<JFRStackFrame> getFrames() {\n        List<RecordedFrame> recordedFrames = stackTrace.getFrames();\n        List<JFRStackFrame> frames = new ArrayList<>(recordedFrames.size());\n        \n        for (RecordedFrame recordedFrame : recordedFrames)\n            frames.add(new JFRJDK11StackFrame(recordedFrame));\n        \n        return frames;\n    }\n    \n    @Override\n    public boolean isTruncated() {\n        return stackTrace.isTruncated();\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return stackTrace.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRJDK11StackTrace && stackTrace.equals(((JFRJDK11StackTrace) o).stackTrace);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jfr.jdk11/src/org/graalvm/visualvm/jfr/jdk11/model/impl/JFRJDK11Thread.java",
    "content": "/*\n * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jfr.jdk11.model.impl;\n\nimport jdk.jfr.consumer.RecordedThread;\nimport org.graalvm.visualvm.jfr.model.JFRThread;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JFRJDK11Thread extends JFRThread {\n    \n    private final RecordedThread thread;\n    \n    \n    public JFRJDK11Thread(RecordedThread thread) {\n        this.thread = thread;\n    }\n\n    \n    @Override\n    public long getId() {\n        return thread.getJavaThreadId();\n    }\n\n    @Override\n    public String getName() {\n        // VM thread has a 'null' name\n        String name = thread.getJavaName();\n        return name == null ? \"VM Thread\" : name; // NOI18N\n    }\n    \n    \n    @Override\n    public int hashCode() {\n        return thread.hashCode();\n    }\n    \n    @Override\n    public boolean equals(Object o) {\n        return o instanceof JFRJDK11Thread && thread.equals(((JFRJDK11Thread) o).thread);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jmx/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.jmx\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.jmx.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/jmx/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.jmx/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/jmx/resources/layer.xml\nOpenIDE-Module-Install: org/graalvm/visualvm/jmx/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/jmx/Bundle.properties\nOpenIDE-Module-Provides: org.graalvm.visualvm.jmx\nOpenIDE-Module-Specification-Version: 2.2\n\n"
  },
  {
    "path": "visualvm/jmx/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.jmx-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/jmx/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=d8ba4e7e\nbuild.xml.script.CRC32=126c6436\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=d8ba4e7e\nnbproject/build-impl.xml.script.CRC32=dc3078ec\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/jmx/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\ncp.extra=${tools.jar}\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/jmx/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.jmx</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.keyring</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.40</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.sendopts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.11.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.50</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.18.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.jmx</package>\n                <package>org.graalvm.visualvm.jmx.env</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/jmx/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-JMX\n\nLBL_Adding=Adding {0}...\n\nLBL_Username=&Username\\:\n\nLBL_Password=&Password\\:\n\nLBL_Connection=&Connection\\:\n\nLBL_Usage=<html><nobr><b>Usage</b>: &lt;hostname&gt;:&lt;port&gt; OR service:jmx:&lt;protocol&gt;:&lt;sap&gt;</nobr></html>\n\nLBL_Display_name=&Display name\\:\n\nLBL_Caption_Security=Security\n\nLBL_Use_security_credentials=Us&e security credentials\n\nLBL_Save_security_credentials=&Save security credentials\n\nLBL_Insecure_connection=Do &not require SSL connection\n\nLBL_Caption_Connection=Connection\n\nLBL_Connect_Immediately=Connect &immediately\n\nTTP_Connect_Immediately=Attempt to connect immediately after submitting new JMX connection\n\nLBL_Auto_Connect=Connect &automatically\n\nTTP_Auto_Connect=Connect automatically whenever the target application is available\n\nLBL_Default_jmx_connection_name=Default Connection\n\nLBL_Default_jmx_connection_descr=Customizable JMX url and credentials\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/CredentialsProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.management.remote.JMXConnector;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.jmx.impl.JmxApplication;\nimport org.netbeans.api.keyring.Keyring;\n\n/**\n * EnvironmentProvider adding the {@code JMXConnector.CREDENTIALS} property to the JMX\n * environment map.\n *\n * There are two subclasses of EnvironmentProvider available, typically you want\n * to use the EnvironmentProvider.Custom class to provide a custom credentials\n * for a JMX connection. The EnvironmentProvider.Persistent class is used for\n * handling credentials for persisted connections.\n *\n * Note that if the credentials provided by this provider are incorrect a dialog\n * requesting new credentials will be displayed by the framework. If the\n * user-provided credentials are correct they will override the credentials\n * defined by this provider. The user-provided credentials are never persisted.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class CredentialsProvider extends EnvironmentProvider {\n\n    private static final String PROPERTY_USER = \"prop_credentials_user\"; // NOI18N\n    private static final String PROPERTY_PWORD = \"prop_credentials_pword\"; // NOI18N\n\n    private static Persistent PERSISTENT_PROVIDER;\n\n\n    static synchronized Persistent persistent() {\n        if (PERSISTENT_PROVIDER == null) PERSISTENT_PROVIDER = new Persistent();\n        return PERSISTENT_PROVIDER;\n    }\n\n\n    /**\n     * Returns a unique String identifying the CredentialsProvider. Must be\n     * overridden to return a different identificator when subclassing the\n     * CredentialsProvider.\n     *\n     * @return unique String identifying the CredentialsProvider\n     */\n    public String getId() {\n        return CredentialsProvider.class.getName();\n    }\n    \n    \n    abstract String getUsername(Storage storage);\n    \n    abstract boolean hasPassword(Storage storage);\n\n    public abstract boolean isPersistent(Storage storage);\n\n\n    /**\n     * CredentialsProvider to provide custom settings.\n     *\n     * @author Jiri Sedlacek\n     */\n    public static class Custom extends CredentialsProvider {\n\n        private final String user;\n        private final char[] pword;\n        private final boolean persistent;\n\n\n        /**\n         * Creates new instance of CredentialsProvider.Custom.\n         *\n         * @param username username\n         * @param password password\n         * @param persistent true if the credentials should be persisted for another VisualVM sessions, false otherwise\n         */\n        public Custom(String username, char[] password, boolean persistent) {\n            this.user = username;\n            this.pword = encodePassword(password);\n            this.persistent = persistent;\n        }\n\n\n        public Map<String, ?> getEnvironment(Application application, Storage storage) {\n            return createMap(user, getPassword(storage));\n        }\n\n        public String getEnvironmentId(Storage storage) {\n            if (user != null) return user;\n            return super.getEnvironmentId(storage);\n        }\n\n        public void saveEnvironment(Storage storage) {\n            if (!persistent) return;\n            storage.setCustomProperty(PROPERTY_USER, user);\n            String keyringId = JmxApplication.createId(null, this, storage);\n            char[] pw = getPassword(storage);\n            if (pw != null) {\n                Keyring.save(keyringId, pw, \"VisualVM - JMX password for \"+user);    // NOI18N\n            } else {\n                Keyring.delete(keyringId);\n            }\n        }\n        \n        \n        String getUsername(Storage storage) { return user; }\n\n        private char[] getPassword(Storage storage) {\n            if (hasPassword(storage)) {\n                return decodePassword(Arrays.copyOf(pword, pword.length));\n            }\n            return null;\n        }\n    \n        boolean hasPassword(Storage storage) { return pword != null &&\n                                               pword.length > 0; }\n\n        public boolean isPersistent(Storage storage) { return persistent; }\n\n    }\n\n\n    /**\n     * CredentialsProvider to provide custom settings.\n     *\n     * @author Jiri Sedlacek\n     */\n    public static class Persistent extends CredentialsProvider {\n\n        public Map<String, ?> getEnvironment(Application application, Storage storage) {\n            String user = storage.getCustomProperty(PROPERTY_USER);\n            return createMap(user, getPassword(storage));\n        }\n\n        public String getEnvironmentId(Storage storage) {\n            if (storage != null) {\n                String user = storage.getCustomProperty(PROPERTY_USER);\n                if (user != null) return user;\n            }\n            return super.getEnvironmentId(storage);\n        }\n\n\n        String getUsername(Storage storage) { return storage.getCustomProperty(\n                                                     PROPERTY_USER); }\n\n        private char[] getPassword(Storage storage) {\n            String keyringId = JmxApplication.createId(null, this, storage);\n            char[] pw = Keyring.read(keyringId);\n            if (pw != null) {\n                return pw;\n            }\n            // read old settings\n            String pword = storage.getCustomProperty(PROPERTY_PWORD);\n            if (pword != null && !pword.isEmpty()) {\n                // migrate old settings to Keyring\n                // Keyring.save(keyringId, decodePassword(pword.toCharArray()), \"VisualVM - JMX password for \"+getUsername(storage));       // NOI18N\n                // storage.clearCustomProperty(PROPERTY_PWORD);\n                //return getPassword(storage);\n                return decodePassword(pword.toCharArray());\n            }\n            return null;\n        }\n\n        boolean hasPassword(Storage storage) {\n            char[] pword = getPassword(storage);\n            return pword != null && pword.length>0;\n        }\n\n        public boolean isPersistent(Storage storage) {\n            return getUsername(storage) != null || hasPassword(storage);\n        }\n\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    // NOTE: clears the pword parameter!\n    private static Map<String, ?> createMap(String username, char[] pword) {\n        Map<String, Object>  map = new HashMap<>();\n\n        if (username != null && !username.isEmpty()) {\n            map.put(JMXConnector.CREDENTIALS, new String[] { username, pword == null ? null : new String(pword) });\n        }\n        if (pword != null) Arrays.fill(pword, (char)0);\n\n        return map;\n    }\n\n    // NOTE: clears the pword parameter!\n    private static char[] encodePassword(char[] pword) {\n        return pword == null ? null : Utils.encodePassword(pword);\n    }\n\n    // NOTE: clears the pword parameter!\n    private static char[] decodePassword(char[] pword) {\n        return pword == null ? null : Utils.decodePassword(pword);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/DefaultCustomizer.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx;\n\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ItemEvent;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.JCheckBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPasswordField;\nimport javax.swing.JTextField;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.border.Border;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.explorer.ExplorerSupport;\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.graalvm.visualvm.core.properties.PropertiesPanel;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.jmx.impl.JmxApplication;\nimport org.graalvm.visualvm.jmx.impl.JmxApplicationProvider;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\n\n/**\n * JmxConnectionCustomizer providing the default JMX Connection dialog to enter\n * JMX connection url and optional credentials.\n *\n * @author Jiri Sedlacek\n */\npublic class DefaultCustomizer extends JmxConnectionCustomizer {\n    \n    private static final String PROP_CONNECT_IMMEDIATELY = \"DefaultJMXCustomizer_prop_connect_immediately\"; // NOI18N\n    private static final String PROP_CONNECT_AUTOMATICALLY = \"DefaultJMXCustomizer_prop_connect_automatically\"; // NOI18N\n    \n    private static final boolean DEFAULT_CONNECT_IMMEDIATELY = true;\n    private static final boolean DEFAULT_CONNECT_AUTOMATICALLY = true;\n    \n\n    DefaultCustomizer() {\n        super(NbBundle.getMessage(DefaultCustomizer.class, \"LBL_Default_jmx_connection_name\"), // NOI18N\n              NbBundle.getMessage(DefaultCustomizer.class, \"LBL_Default_jmx_connection_descr\"), // NOI18N\n              1, false);\n    }\n\n\n    public boolean providesProperties(Application application) {\n        if (!(application instanceof JmxApplication)) return false;\n        EnvironmentProvider provider = ((JmxApplication)application).\n                getEnvironmentProvider();\n        return provider instanceof CredentialsProvider;\n    }\n\n    public PropertiesPanel createPanel(Application application) {\n        if (application == null) return new CustomizerUI();\n        else return new PropertiesUI(application);\n    }\n\n    public Setup getConnectionSetup(PropertiesPanel customizerPanel) {\n        if (!(customizerPanel instanceof CustomizerUI))\n            throw new IllegalArgumentException(\"Panel must be DefaultCustomizer.CustomizerUI\"); // NOI18N\n        CustomizerUI panel = (CustomizerUI)customizerPanel;\n\n        String connectionString = panel.getConnectionString();\n        String displayName = panel.getDisplayName();\n        EnvironmentProvider provider = new CredentialsProvider.Custom(\n                panel.getUsername(), panel.getPassword(), panel.getSaveCredentials());\n        boolean persistent = true;\n        boolean allowInsecure = panel.allowsInsecureConnection();\n        \n        boolean connectImmediately = panel.isConnectImmediately();\n        NbPreferences.forModule(DefaultCustomizer.class).putBoolean(PROP_CONNECT_IMMEDIATELY, connectImmediately);\n        boolean autoConnect = panel.isConnectAutomatically();\n        NbPreferences.forModule(DefaultCustomizer.class).putBoolean(PROP_CONNECT_AUTOMATICALLY, autoConnect);\n\n        return new JmxConnectionCustomizer.Setup(connectionString, displayName, provider, persistent,\n                                                 allowInsecure, connectImmediately, autoConnect);\n    }\n\n\n    /**\n     * Returns true if the provided string represents a valid JMX url, false otherwise.\n     *\n     * @param jmxurl JMX url to be checked\n     * @return true if the provided string represents a valid JMX url, false otherwise\n     */\n    protected static boolean isValidConnectionString(String jmxurl) {\n        boolean valid = false;\n        if (jmxurl != null) {\n            jmxurl = jmxurl.trim();\n            if (jmxurl.startsWith(\"service:jmx:\")) { // NOI18N\n                if (jmxurl.length() > \"service:jmx:\".length()) { // NOI18N\n                    valid = true;\n                }\n            } else {\n                //---------------------------------------\n                // Supported host and port combinations:\n                //     hostname:port\n                //     IPv4Address:port\n                //     [IPv6Address]:port\n                //---------------------------------------\n\n                try {\n                    new URL(\"http://\"+jmxurl);      // NOI18N\n                } catch (MalformedURLException ex) {\n                    return false;\n                }\n                // Is literal IPv6 address?\n                //\n                if (jmxurl.startsWith(\"[\")) { // NOI18N\n                    int index = jmxurl.indexOf(\"]:\"); // NOI18N\n                    if (index != -1) {\n                        // Extract port\n                        //\n                        try {\n                            String portStr = jmxurl.substring(index + 2);\n                            int port = Integer.parseInt(portStr);\n                            if (port >= 0 && port <= 0xFFFF) {\n                                valid = true;\n                            }\n                        } catch (NumberFormatException ex) {\n                            valid = false;\n                        }\n                    }\n                } else {\n                    String[] s = jmxurl.split(\":\"); // NOI18N\n                    if (s.length == 2) {\n                        try {\n                            int port = Integer.parseInt(s[1]);\n                            if (port >= 0 && port <= 0xFFFF) {\n                                valid = true;\n                            }\n                        } catch (NumberFormatException ex) {\n                            valid = false;\n                        }\n                    }\n                }\n            }\n        }\n        return valid;\n    }\n\n\n    /**\n     * Implementation of PropertiesPanel for entering the JMX url, optional\n     * credentials and selecting whether the credentials should be persistent or\n     * transient.\n     *\n     * @author Jiri Sedlacek\n     */\n    public static class CustomizerUI extends PropertiesPanel {\n\n        /**\n         * Creates new instance of CustomizerUI.\n         */\n        public CustomizerUI() {\n            initComponents();\n            initDefaults();\n            update();\n        }\n\n        /**\n         * Returns the JMX url defined by the panel.\n         *\n         * @return JMX url defined by the panel\n         */\n        public final String getConnectionString() {\n            return connectionField.getText().trim();\n        }\n\n        /**\n         * Returns connection name defined by the panel.\n         *\n         * @return connection name defined by the panel\n         */\n        public final String getDisplayName() {\n            return !displaynameCheckbox.isSelected() ? null :\n                displaynameField.getText().trim();\n        }\n\n        /**\n         * Returns username defined by the panel.\n         *\n         * @return username defined by the panel\n         */\n        public final String getUsername() {\n            return !securityCheckbox.isSelected() ? null :\n                usernameField.getText().trim();\n        }\n\n        /**\n         * Returns password defined by the panel.\n         *\n         * @return password defined by the panel\n         */\n        public final char[] getPassword() {\n            return !securityCheckbox.isSelected() ? null :\n                passwordField.getPassword();\n        }\n\n        /**\n         * Returns true if the panel requests to persist username and password,\n         * false otherwise.\n         *\n         * @return true if the panel requests to persist username and password, false otherwise\n         */\n        public final boolean getSaveCredentials() {\n            return !securityCheckbox.isSelected() ? false :\n                saveCheckbox.isSelected();\n        }\n        \n        /**\n         * Returns true if SSL is not required for the connection.\n         *\n         * @return true if SSL is not required for the connection, false otherwise\n         */\n        public final boolean allowsInsecureConnection() {\n            return noSSLCheckbox.isSelected();\n        }\n        \n        public final boolean isConnectImmediately() {\n            return connectImmediatelyChoice.isSelected();\n        }\n        \n        public final boolean isConnectAutomatically() {\n            return autoConnectChoice.isSelected();\n        }\n\n\n        private void initDefaults() {\n            Set<DataSource> selectedDataSources =\n                ExplorerSupport.sharedInstance().getSelectedDataSources();\n            if (selectedDataSources.size() != 1) return;\n            DataSource selectedDataSource = selectedDataSources.iterator().next();\n            if (!(selectedDataSource instanceof Host)) return;\n            Host host = (Host)selectedDataSource;\n            connectionField.setText(host.getHostName() + \":\"); // NOI18N\n        }\n\n        private void update() {\n            if (internalChange) return;\n\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    String username = getUsername();\n                    String url = getConnectionString();\n\n                    if (!displaynameCheckbox.isSelected()) {\n                        internalChange = true;\n                        displaynameField.setText((username == null || username.isEmpty() ?\n                            \"\" : username + \"@\") + url); // NOI18N\n                        internalChange = false;\n                    }\n\n                    String displayname = getDisplayName();\n                    displaynameField.setEnabled(displaynameCheckbox.isSelected());\n\n                    usernameField.setEnabled(securityCheckbox.isSelected());\n                    passwordField.setEnabled(securityCheckbox.isSelected());\n                    saveCheckbox.setEnabled(securityCheckbox.isSelected());\n\n                    setSettingsValid(isValidConnectionString(url) &&\n                            (!displaynameCheckbox.isSelected() || !displayname.isEmpty()));\n                }\n            });\n        }\n\n        private void initComponents() {\n            setLayout(new GridBagLayout());\n            GridBagConstraints constraints;\n\n            // connectionLabel\n            connectionLabel = new JLabel();\n            Mnemonics.setLocalizedText(connectionLabel, NbBundle.getMessage(\n                    DefaultCustomizer.class, \"LBL_Connection\")); // NOI18N\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 0;\n            constraints.gridwidth = 1;\n            constraints.fill = GridBagConstraints.NONE;\n            constraints.anchor = GridBagConstraints.EAST;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            add(connectionLabel, constraints);\n\n            // connectionField\n            connectionField = new JTextField();\n            connectionLabel.setLabelFor(connectionField);\n            connectionField.setPreferredSize(\n                    new Dimension(250, connectionField.getPreferredSize().height));\n            connectionField.getDocument().addDocumentListener(new DocumentListener() {\n                public void insertUpdate(DocumentEvent e) {\n                    update();\n                }\n                public void removeUpdate(DocumentEvent e) {\n                    update();\n                }\n                public void changedUpdate(DocumentEvent e) {\n                    update();\n                }\n            });\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = 0;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(0, 5, 0, 0);\n            add(connectionField, constraints);\n\n            // usageLabel\n            Font normalLabelFont = connectionLabel.getFont();\n            Font smallLabelFont =\n                    normalLabelFont.deriveFont(normalLabelFont.getSize2D() - 1);\n            usageLabel = new JLabel(NbBundle.getMessage(DefaultCustomizer.class, \"LBL_Usage\"));    // NOI18N\n            usageLabel.setFont(smallLabelFont);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = 1;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.NONE;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(0, 5, 0, 0);\n            add(usageLabel, constraints);\n\n            // displaynameCheckbox\n            displaynameCheckbox = new JCheckBox();\n            Mnemonics.setLocalizedText(displaynameCheckbox, NbBundle.getMessage(\n                    DefaultCustomizer.class, \"LBL_Display_name\")); // NOI18N\n            displaynameCheckbox.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    update();\n                }\n            });\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 2;\n            constraints.gridwidth = 1;\n            constraints.fill = GridBagConstraints.NONE;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(8, 0, 0, 0);\n            add(displaynameCheckbox, constraints);\n\n            // displaynameField\n            displaynameField = new JTextField();\n            displaynameField.setPreferredSize(\n                    new Dimension(250, displaynameField.getPreferredSize().height));\n            displaynameField.getDocument().addDocumentListener(new DocumentListener() {\n                public void insertUpdate(DocumentEvent e) {\n                    update();\n                }\n                public void removeUpdate(DocumentEvent e) {\n                    update();\n                }\n                public void changedUpdate(DocumentEvent e) {\n                    update();\n                }\n            });\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = 2;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(8, 5, 0, 0);\n            add(displaynameField, constraints);\n            \n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 3;\n            constraints.weightx = 1;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.insets = new Insets(20, 0, 0, 0);\n            add(UISupport.createSectionSeparator(NbBundle.getMessage(DefaultCustomizer.class, \"LBL_Caption_Security\")), constraints); // NOI18N\n\n            // securityCheckbox\n            securityCheckbox = new JCheckBox();\n            Mnemonics.setLocalizedText(securityCheckbox, NbBundle.getMessage(\n                    DefaultCustomizer.class, \"LBL_Use_security_credentials\")); // NOI18N\n            securityCheckbox.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    update();\n                }\n            });\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 4;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.NONE;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(8, 0, 0, 0);\n            add(securityCheckbox, constraints);\n\n            // usernameLabel\n            usernameLabel = new JLabel();\n            Mnemonics.setLocalizedText(usernameLabel, NbBundle.getMessage(\n                    DefaultCustomizer.class, \"LBL_Username\")); // NOI18N\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 5;\n            constraints.gridwidth = 1;\n            constraints.fill = GridBagConstraints.NONE;\n            constraints.anchor = GridBagConstraints.EAST;\n            constraints.insets = new Insets(5, 0, 0, 0);\n            add(usernameLabel, constraints);\n\n            // usernameField\n            usernameField = new JTextField();\n            usernameLabel.setLabelFor(usernameField);\n            usernameField.setPreferredSize(\n                    new Dimension(320, usernameField.getPreferredSize().height));\n            usernameField.getDocument().addDocumentListener(new DocumentListener() {\n                public void insertUpdate(DocumentEvent e) {\n                    update();\n                }\n                public void removeUpdate(DocumentEvent e) {\n                    update();\n                }\n                public void changedUpdate(DocumentEvent e) {\n                    update();\n                }\n            });\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = 5;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(5, 5, 0, 0);\n            add(usernameField, constraints);\n\n            // passwordLabel\n            passwordLabel = new JLabel();\n            Mnemonics.setLocalizedText(passwordLabel, NbBundle.getMessage(\n                    DefaultCustomizer.class, \"LBL_Password\")); // NOI18N\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 6;\n            constraints.gridwidth = 1;\n            constraints.fill = GridBagConstraints.NONE;\n            constraints.anchor = GridBagConstraints.EAST;\n            constraints.insets = new Insets(8, 0, 0, 0);\n            add(passwordLabel, constraints);\n\n            // passwordField\n            passwordField = new JPasswordField();\n            passwordLabel.setLabelFor(passwordField);\n            passwordField.setPreferredSize(\n                    new Dimension(200, passwordField.getPreferredSize().height));\n            passwordField.getDocument().addDocumentListener(new DocumentListener() {\n                public void insertUpdate(DocumentEvent e) {\n                    update();\n                }\n                public void removeUpdate(DocumentEvent e) {\n                    update();\n                }\n                public void changedUpdate(DocumentEvent e) {\n                    update();\n                }\n            });\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = 6;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(8, 5, 0, 0);\n            add(passwordField, constraints);\n\n            // saveCheckbox\n            saveCheckbox = new JCheckBox();   // NOI18N\n            Mnemonics.setLocalizedText(saveCheckbox, NbBundle.getMessage(\n                    DefaultCustomizer.class, \"LBL_Save_security_credentials\")); // NOI18N\n            saveCheckbox.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    update();\n                }\n            });\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 7;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.EAST;\n            constraints.insets = new Insets(8, 30, 0, 0);\n            add(saveCheckbox, constraints);\n            \n            // noSSLCheckbox\n            noSSLCheckbox = new JCheckBox();   // NOI18N\n            Mnemonics.setLocalizedText(noSSLCheckbox, NbBundle.getMessage(\n                    DefaultCustomizer.class, \"LBL_Insecure_connection\")); // NOI18N\n            noSSLCheckbox.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    update();\n                }\n            });\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 8;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(15, 0, 0, 0);\n            add(noSSLCheckbox, constraints);\n            \n            // --- connection options ------------------------------------------\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 9;\n            constraints.weightx = 1;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.insets = new Insets(20, 0, 0, 0);\n            add(UISupport.createSectionSeparator(NbBundle.getMessage(DefaultCustomizer.class, \"LBL_Caption_Connection\")), constraints); // NOI18N\n            \n            JPanel connectOptions = new JPanel(null);\n            connectOptions.setLayout(new BoxLayout(connectOptions, BoxLayout.LINE_AXIS));\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 10;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(8, 0, 0, 0);\n            add(connectOptions, constraints);\n            \n            connectImmediatelyChoice = new JCheckBox() {\n                protected void fireItemStateChanged(ItemEvent e) {\n                    super.fireItemStateChanged(e);\n                    if (autoConnectChoice != null) {\n                        autoConnectChoice.setEnabled(isSelected());\n                    }\n                }\n            };\n            Mnemonics.setLocalizedText(connectImmediatelyChoice, NbBundle.getMessage(DefaultCustomizer.class, \"LBL_Connect_Immediately\")); // NOI18N\n            connectImmediatelyChoice.setToolTipText(NbBundle.getMessage(DefaultCustomizer.class, \"TTP_Connect_Immediately\")); // NOI18N\n            connectOptions.add(connectImmediatelyChoice);\n            \n            connectOptions.add(Box.createHorizontalStrut(8));\n            \n            autoConnectChoice = new JCheckBox() {\n                public void setEnabled(boolean enabled) {\n                    super.setEnabled(enabled);\n                    if (!enabled) setSelected(false);\n                }\n            };\n            Mnemonics.setLocalizedText(autoConnectChoice, NbBundle.getMessage(DefaultCustomizer.class, \"LBL_Auto_Connect\")); // NOI18N\n            autoConnectChoice.setToolTipText(NbBundle.getMessage(DefaultCustomizer.class, \"TTP_Auto_Connect\")); // NOI18N\n            connectOptions.add(autoConnectChoice);\n            \n            connectImmediatelyChoice.setSelected(NbPreferences.forModule(DefaultCustomizer.class).getBoolean(PROP_CONNECT_IMMEDIATELY, DEFAULT_CONNECT_IMMEDIATELY));\n            if (connectImmediatelyChoice.isSelected()) autoConnectChoice.setSelected(NbPreferences.forModule(DefaultCustomizer.class).getBoolean(PROP_CONNECT_AUTOMATICALLY, DEFAULT_CONNECT_AUTOMATICALLY));\n            else autoConnectChoice.setEnabled(false);\n            // -----------------------------------------------------------------\n\n            // spacer\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 11;\n            constraints.weightx = 1;\n            constraints.weighty = 1;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.BOTH;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.insets = new Insets(10, 0, 0, 0);\n            add(Spacer.create(), constraints);\n\n            // UI tweaks\n            Border b = connectionLabel.getBorder();\n            int r = b == null ? 0 : b.getBorderInsets(connectionLabel).right;\n            \n            Border c = displaynameCheckbox.getBorder();\n            if (c != null) {\n                Insets i = c.getBorderInsets(displaynameCheckbox);\n                if (i == null) i = new Insets(0, 0, 0, 0);\n                Border bb = BorderFactory.createEmptyBorder(i.top, i.left, i.bottom, r);\n                displaynameCheckbox.setBorder(bb);\n                securityCheckbox.setBorder(bb);\n                noSSLCheckbox.setBorder(bb);\n            }\n        }\n\n\n        private boolean internalChange = false;\n\n        private JLabel connectionLabel;\n        private JTextField connectionField;\n        private JLabel usageLabel;\n        private JCheckBox displaynameCheckbox;\n        private JTextField displaynameField;\n        private JCheckBox securityCheckbox;\n        private JLabel usernameLabel;\n        private JTextField usernameField;\n        private JLabel passwordLabel;\n        private JPasswordField passwordField;\n        private JCheckBox saveCheckbox;\n        private JCheckBox noSSLCheckbox;\n        private JCheckBox connectImmediatelyChoice;\n        private JCheckBox autoConnectChoice;\n    }\n\n\n    /**\n     * Implementation of PropertiesPanel for viewing the JMX connection properties\n     * defined when creating the connection.\n     *\n     * @author Jiri Sedlacek\n     */\n    public static class PropertiesUI extends PropertiesPanel {\n\n        /**\n         * Creates new instance of PropertiesUI to display properties of the\n         * provided Application.\n         *\n         * @param application Application for which to display the properties\n         */\n        public PropertiesUI(Application application) {\n            initComponents();\n            setValues(application);\n        }\n\n\n        private void setValues(Application application) {\n            JmxApplication app = (JmxApplication)application;\n            String connectionString = JmxApplicationProvider.getConnectionString(app);\n\n            Storage storage = application.getStorage();\n            CredentialsProvider provider = (CredentialsProvider)app.getEnvironmentProvider();\n            String username = provider.getUsername(storage);\n            boolean isusername = username != null && !username.isEmpty();\n            boolean ispassword = provider.hasPassword(storage);\n            boolean ispersistent = provider.isPersistent(storage);\n            String noSSL = storage.getCustomProperty(JmxApplicationProvider.PROPERTY_RETRY_WITHOUT_SSL);\n\n            connectionField.setText(connectionString);\n            connectionField.setCaretPosition(0);\n            securityCheckbox.setSelected(isusername || ispassword);\n            usernameField.setText(username);\n            usernameField.setCaretPosition(0);\n            passwordField.setText(ispassword ? \"----------\" : \"\"); // NOI18N\n            passwordField.setCaretPosition(0);\n            saveCheckbox.setSelected(ispersistent);\n            noSSLCheckbox.setSelected(noSSL != null && Boolean.parseBoolean(noSSL));\n        }\n\n        private void initComponents() {\n            setLayout(new GridBagLayout());\n            GridBagConstraints constraints;\n\n            Color checkboxForeground = UIManager.getColor(\"CheckBox.foreground\"); // NOI18N\n            Color checkboxText = new Color(checkboxForeground.getRGB());\n\n            // connectionLabel\n            connectionLabel = new JLabel();\n            Mnemonics.setLocalizedText(connectionLabel, NbBundle.getMessage(\n                    DefaultCustomizer.class, \"LBL_Connection\")); // NOI18N\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 0;\n            constraints.gridwidth = 1;\n            constraints.fill = GridBagConstraints.NONE;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(3, 0, 3, 0);\n            add(connectionLabel, constraints);\n\n            // connectionField\n            connectionField = new JTextField();\n            connectionLabel.setLabelFor(connectionField);\n            connectionField.setEditable(false);\n            Dimension size = connectionField.getPreferredSize();\n            size.width = 1;\n            connectionField.setPreferredSize(size);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = 0;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(3, 5, 3, 0);\n            add(connectionField, constraints);\n\n            // securityCheckbox\n            securityCheckbox = new JCheckBox();\n            Mnemonics.setLocalizedText(securityCheckbox, NbBundle.getMessage(\n                    DefaultCustomizer.class, \"LBL_Use_security_credentials\")); // NOI18N\n            securityCheckbox.setEnabled(false);\n            securityCheckbox.setOpaque(false);\n            securityCheckbox.setForeground(checkboxText);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 3;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.NONE;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(15, 0, 0, 0);\n            add(securityCheckbox, constraints);\n\n            // usernameLabel\n            usernameLabel = new JLabel();\n            Mnemonics.setLocalizedText(usernameLabel, NbBundle.getMessage(\n                    DefaultCustomizer.class, \"LBL_Username\")); // NOI18N\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 4;\n            constraints.gridwidth = 1;\n            constraints.fill = GridBagConstraints.NONE;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(5, 20, 0, 0);\n            add(usernameLabel, constraints);\n\n            // usernameField\n            usernameField = new JTextField();\n            usernameLabel.setLabelFor(usernameField);\n            usernameField.setEditable(false);\n            size = usernameField.getPreferredSize();\n            size.width = 1;\n            usernameField.setPreferredSize(size);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = 4;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(5, 5, 0, 0);\n            add(usernameField, constraints);\n\n            // passwordLabel\n            passwordLabel = new JLabel();\n            Mnemonics.setLocalizedText(passwordLabel, NbBundle.getMessage(\n                    DefaultCustomizer.class, \"LBL_Password\")); // NOI18N\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 5;\n            constraints.gridwidth = 1;\n            constraints.fill = GridBagConstraints.NONE;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(8, 20, 0, 0);\n            add(passwordLabel, constraints);\n\n            // passwordField\n            passwordField = new JPasswordField();\n            passwordLabel.setLabelFor(passwordField);\n            passwordField.setEditable(false);\n            passwordField.setFocusable(false);\n            size = passwordField.getPreferredSize();\n            size.width = 1;\n            passwordField.setPreferredSize(size);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = 5;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(8, 5, 0, 0);\n            add(passwordField, constraints);\n\n            // saveCheckbox\n            saveCheckbox = new JCheckBox();   // NOI18N\n            Mnemonics.setLocalizedText(saveCheckbox, NbBundle.getMessage(\n                    DefaultCustomizer.class, \"LBL_Save_security_credentials\")); // NOI18N\n            saveCheckbox.setEnabled(false);\n            saveCheckbox.setOpaque(false);\n            saveCheckbox.setForeground(checkboxText);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 6;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(8, 16, 0, 0);\n            add(saveCheckbox, constraints);\n            \n            // noSSLCheckbox\n            noSSLCheckbox = new JCheckBox();   // NOI18N\n            Mnemonics.setLocalizedText(noSSLCheckbox, NbBundle.getMessage(\n                    DefaultCustomizer.class, \"LBL_Insecure_connection\")); // NOI18N\n            noSSLCheckbox.setEnabled(false);\n            noSSLCheckbox.setOpaque(false);\n            noSSLCheckbox.setForeground(checkboxText);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 7;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.anchor = GridBagConstraints.WEST;\n            constraints.insets = new Insets(15, 0, 3, 0);\n            add(noSSLCheckbox, constraints);\n\n            // spacer\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 8;\n            constraints.weightx = 1;\n            constraints.weighty = 1;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.fill = GridBagConstraints.BOTH;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            add(Spacer.create(), constraints);\n            \n            // UI tweaks\n            Border b = connectionLabel.getBorder();\n            int r = b == null ? 0 : b.getBorderInsets(connectionLabel).right;\n            \n            Border c = securityCheckbox.getBorder();\n            if (c != null) {\n                Insets i = c.getBorderInsets(securityCheckbox);\n                if (i == null) i = new Insets(0, 0, 0, 0);\n                Border bb = BorderFactory.createEmptyBorder(i.top, i.left, i.bottom, r);\n                securityCheckbox.setBorder(bb);\n                noSSLCheckbox.setBorder(bb);\n            }\n        }\n\n        private JLabel connectionLabel;\n        private JTextField connectionField;\n        private JCheckBox securityCheckbox;\n        private JLabel usernameLabel;\n        private JTextField usernameField;\n        private JLabel passwordLabel;\n        private JPasswordField passwordField;\n        private JCheckBox saveCheckbox;\n        private JCheckBox noSSLCheckbox;\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/EnvironmentProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx;\n\nimport java.util.Map;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.Storage;\n\n/**\n * Provider of the JMX environment for each JMX connection.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class EnvironmentProvider {\n\n    /**\n     * Returns a unique String identifying the EnvironmentProvider. The return\n     * value is used for persistency purposes and must be constant for providers\n     * supporting persistent JMX connections. Default implementation returns\n     * this.getClass().getName().\n     *\n     * @return unique String identifying the EnvironmentProvider\n     */\n    public String getId() { return getClass().getName(); }\n\n    /**\n     * Returns the JMX environment for the provided Application. The Storage\n     * contains the data which may have been previously saved using the\n     * saveEnvironment(Storage) method. Typically application.getStorage == storage.\n     *\n     * @param application Application for which to create the JMX environment\n     * @param storage the Storage where the settings may have been previously saved using the saveEnvironment(Storage) method, typically it is application.getStorage()\n     * @return JMX environment for the provided Application\n     */\n    public abstract Map<String, ?> getEnvironment(Application application, Storage storage);\n\n\n    /**\n     * Returns a unique identificator of the provided environment which helps\n     * to differentiate JMX connections defined by the same connection string\n     * but having different JMX environments. For example, the CredentialsProvider\n     * returns the username if defined.\n     *\n     * Note: the provided Storage may be null which means that the provider\n     * provides the environment for not persistent JMX connection.\n     *\n     * @param storage Storage or null if the JMX connection is not persistent\n     * @return unique identificator of the provided environment\n     */\n    public String getEnvironmentId(Storage storage) { return \"\"; } // NOI18N\n    \n    /**\n     * Gives the EnvironmentProvider a possibility to save it's settings into\n     * a Storage. This method is called by the framework as soon as the Storage\n     * is available. The provider may save the data to the provided Storage or\n     * it can use it's own approach to persist the data.\n     *\n     * @param storage Storage to store the provider's settings\n     */\n    public void saveEnvironment(Storage storage) {}\n\n    /**\n     * Gives the EnvironmentProvider a possibility to load saved settings from\n     * a Storage. This method is called by the framework as soon as the Storage\n     * of a restored persistent JMX connection is available. The provider may\n     * load the data from the provided Storage or it can use it's own approach\n     * to retrieve the persisted data.\n     *\n     * Note: typically this method is not needed as the provider can access the\n     * Storage directly in the getEnvironment(Application) method using\n     * application.getStorage().\n     *\n     * @param storage Storage containing the provider's settings\n     */\n    public void loadEnvironment(Storage storage) {}\n\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jmx;\n\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.properties.PropertiesSupport;\nimport org.graalvm.visualvm.jmx.impl.GeneralPropertiesProvider;\nimport org.graalvm.visualvm.jmx.impl.JmxApplication;\nimport org.graalvm.visualvm.jmx.impl.JmxApplicationDescriptorProvider;\nimport org.graalvm.visualvm.jmx.impl.JmxConnectionSupportImpl;\nimport org.graalvm.visualvm.jmx.impl.JmxModelProvider;\nimport org.graalvm.visualvm.jmx.impl.JmxPropertiesProvider;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.openide.modules.ModuleInstall;\n\nfinal class Installer extends ModuleInstall {\n\n    public void restored() {\n        JmxModelFactory.getDefault().registerProvider(new JmxModelProvider());\n        DataSourceDescriptorFactory.getDefault().registerProvider(new JmxApplicationDescriptorProvider());\n        JmxConnectionSupport.getInstance().registerProvider(CredentialsProvider.persistent());\n        DefaultCustomizer dcc = new DefaultCustomizer();\n        JmxConnectionSupport.getInstance().registerCustomizer(dcc);\n        JmxConnectionSupportImpl.setDefaultCustomizer(dcc);\n        PropertiesSupport.sharedInstance().registerPropertiesProvider(\n                new JmxPropertiesProvider(), JmxApplication.class);\n        PropertiesSupport.sharedInstance().registerPropertiesProvider(\n                new GeneralPropertiesProvider(), JmxApplication.class);\n        JmxApplicationsSupport.getInstance();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/JmxApplicationException.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx;\n\n/**\n * Exception being thrown when creating new JMX Application fails.\n *\n * @author Jiri Sedlacek\n */\npublic final class JmxApplicationException extends Exception {\n\n    /**\n     * Creates new instance of JmxApplicationException.\n     *\n     * @param message failure description.\n     */\n    public JmxApplicationException(String message) {\n        super(message);\n    }\n\n   /**\n     * Constructs a new JmxApplicationException with the specified detail message and\n     * cause.  <p>Note that the detail message associated with\n     * <code>cause</code> is <i>not</i> automatically incorporated in\n     * this exception's detail message.\n     *\n     * @param  message the detail message (which is saved for later retrieval\n     *         by the {@link #getMessage()} method).\n     * @param  cause the cause (which is saved for later retrieval by the\n     *         {@link #getCause()} method).  (A <tt>null</tt> value is\n     *         permitted, and indicates that the cause is nonexistent or\n     *         unknown.)\n     */\n    public JmxApplicationException(String message,Throwable cause) {\n        super(message,cause);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/JmxApplicationsSupport.java",
    "content": "/*\n *  Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.jmx;\n\nimport java.io.File;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.jmx.impl.JmxApplicationProvider;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\n\n/**\n * Support for creating JMX applications in VisualVM.\n *\n * @author Jiri Sedlacek\n */\npublic final class JmxApplicationsSupport {\n    \n    private static final String STORAGE_DIRNAME = \"jmxapplications\";    // NOI18N\n    \n    private static final Object storageDirectoryLock = new Object();\n    // @GuardedBy storageDirectoryLock\n    private static File storageDirectory;\n    private static final Object storageDirectoryStringLock = new Object();\n    // @GuardedBy storageDirectoryStringLock\n    private static String storageDirectoryString;\n\n    private static JmxApplicationsSupport instance;\n\n    private JmxApplicationProvider applicationProvider = new JmxApplicationProvider();\n\n\n    /**\n     * Returns singleton instance of JmxApplicationsSupport.\n     *\n     * @return singleton instance of JmxApplicationsSupport.\n     */\n    public static synchronized JmxApplicationsSupport getInstance() {\n        if (instance == null) instance = new JmxApplicationsSupport();\n        return instance;\n    }\n\n\n    /**\n     * Creates new Application defined by JMX connection and adds it to the\n     * Applications tree. The application won't be restored on another VisualVM\n     * sessions. Throws a JmxApplicationException if the application cannot be created.\n     *\n     * Note that even though the created application won't be restored for another\n     * VisualVM sessions, the host created for this application will be restored.\n     *\n     * @param connectionString definition of the connection, for example hostname:port\n     * @param displayName display name for the application, may be null\n     * @param username username for the connection, may be null\n     * @param password password for the connection, may be null\n     * @return created JMX application\n     * @throws JmxApplicationException if creating the application failed\n     */\n    public Application createJmxApplication(String connectionString, String displayName,\n                                            String username, String password) throws JmxApplicationException {\n\n        return createJmxApplication(connectionString, displayName, username,\n                                    password, false, false);\n    }\n\n    /**\n     * Creates new Application defined by JMX connection and adds it to the\n     * Applications tree. Throws a JmxApplicationException if the application\n     * cannot be created.\n     *\n     * Note that even if the created application isn't persistent for another\n     * VisualVM sessions, the host created for this application will be restored.\n     *\n     * @param connectionString definition of the connection, for example hostname:port\n     * @param displayName display name for the application, may be null\n     * @param username username for the connection, may be null\n     * @param password password for the connection, may be null\n     * @param saveCredentials if persistent, controls whether the username and password should be persisted for another VisualVM sessions\n     * @param persistent controls whether the application definition will be persisted for another VisualVM sessions\n     * @return created JMX application\n     * @throws JmxApplicationException if creating the application failed\n     */\n    public Application createJmxApplication(String connectionString,\n                                            String displayName, String username,\n                                            String password, boolean saveCredentials,\n                                            boolean persistent) throws JmxApplicationException {\n\n        if (username == null) username = \"\"; // NOI18N\n        if (password == null) password = \"\"; // NOI18N\n        \n        String suggestedName = JmxApplicationProvider.getSuggestedName(displayName,\n                connectionString, username);\n\n        EnvironmentProvider epr = new CredentialsProvider.Custom(username,\n                password.toCharArray(), saveCredentials);\n        return createJmxApplicationImpl(connectionString, displayName, suggestedName,\n                                        epr, persistent, false, true, true);\n    }\n\n    /**\n     * Creates new Application defined by JMX connection and adds it to the\n     * Applications tree. Throws a JmxApplicationException if the application\n     * cannot be created.\n     *\n     * @param connectionString definition of the connection, for example hostname:port\n     * @param displayName display name for the application, may be null\n     * @param provider JMX EnvironmentProvider for the Application\n     * @param persistent controls whether the application definition will be persisted for another VisualVM sessions\n     * @return created JMX application\n     * @throws JmxApplicationException if creating the application failed\n     */\n    public Application createJmxApplication(String connectionString,\n                                            String displayName,\n                                            EnvironmentProvider provider,\n                                            boolean persistent) throws JmxApplicationException {\n\n        String username = getUsername(provider);\n        String suggestedName = JmxApplicationProvider.getSuggestedName(displayName,\n                connectionString, username);\n        return createJmxApplicationImpl(connectionString, displayName, suggestedName,\n                                        provider, persistent, false, true, true);\n    }\n\n    /**\n     * Creates new Application defined by JMX connection and adds it to the\n     * Applications tree. The application won't be restored on another VisualVM\n     * sessions. Displays progress during application creation and opens an error\n     * dialog if creating the application failed. Throws a JmxApplicationException\n     * if the application cannot be created.\n     *\n     * Note that even though the created application won't be restored for another\n     * VisualVM sessions, the host created for this application will be restored.\n     *\n     * @param connectionString definition of the connection, for example hostname:port\n     * @param displayName display name for the application, may be null\n     * @param username username for the connection, may be null\n     * @param password password for the connection, may be null\n     * @return created JMX application or null if creating the application failed\n     */\n    public Application createJmxApplicationInteractive(String connectionString, String displayName,\n                                            String username, String password) {\n\n        return createJmxApplicationInteractive(connectionString, displayName, username,\n                                    password, false, false);\n    }\n\n    /**\n     * Creates new Application defined by JMX connection and adds it to the\n     * Applications tree. Displays progress during application creation and\n     * opens an error dialog if creating the application failed.\n     *\n     * Note that even if the created application isn't persistent for another\n     * VisualVM sessions, the host created for this application will be restored.\n     *\n     * @param connectionString definition of the connection, for example hostname:port\n     * @param displayName display name for the application, may be null\n     * @param username username for the connection, may be null\n     * @param password password for the connection, may be null\n     * @param saveCredentials if persistent, controls whether the username and password should be persisted for another VisualVM sessions\n     * @param persistent controls whether the application definition will be persisted for another VisualVM sessions\n     * @return created JMX application or null if creating the application failed\n     */\n    public Application createJmxApplicationInteractive(String connectionString,\n                                            String displayName, String username,\n                                            String password, boolean saveCredentials,\n                                            boolean persistent) {\n\n        return createJmxApplicationInteractive(connectionString, displayName, username, password,\n                                               saveCredentials, persistent, true, true);\n    }\n    \n    /**\n     * Creates new Application defined by JMX connection and adds it to the\n     * Applications tree. Displays progress during application creation and\n     * opens an error dialog if creating the application failed.\n     *\n     * Note that even if the created application isn't persistent for another\n     * VisualVM sessions, the host created for this application will be restored.\n     *\n     * @param connectionString definition of the connection, for example hostname:port\n     * @param displayName display name for the application, may be null\n     * @param username username for the connection, may be null\n     * @param password password for the connection, may be null\n     * @param saveCredentials if persistent, controls whether the username and password should be persisted for another VisualVM sessions\n     * @param persistent controls whether the application definition will be persisted for another VisualVM sessions\n     * @param connectImmediately true if the JMX connection should be attempted immediately after submitting, false otherwise\n     * @param connectAutomatically true if the JMX connection should be made automatically whenever the target application is available, false otherwise\n     * @return created JMX application or null if creating the application failed\n     */\n    public Application createJmxApplicationInteractive(String connectionString,\n                                            String displayName, String username,\n                                            String password, boolean saveCredentials,\n                                            boolean persistent, boolean connectImmediately,\n                                            boolean connectAutomatically) {\n\n        if (username == null) username = \"\"; // NOI18N\n        if (password == null) password = \"\"; // NOI18N\n        \n        final ProgressHandle[] pHandle = new ProgressHandle[1];\n        try {\n            final String suggestedName = JmxApplicationProvider.getSuggestedName(\n                    displayName, connectionString, username);\n            SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        pHandle[0] = ProgressHandle.createHandle(\n                                NbBundle.getMessage(JmxApplicationsSupport.class,\n                                                    \"LBL_Adding\", suggestedName)); // NOI18N\n                        pHandle[0].setInitialDelay(0);\n                        pHandle[0].start();\n                    }\n                });\n            EnvironmentProvider epr = new CredentialsProvider.Custom(username,\n                password.toCharArray(), saveCredentials);\n            return createJmxApplicationImpl(connectionString, displayName,\n                                            suggestedName, epr, persistent, false,\n                                            connectImmediately, connectAutomatically);\n        } catch (JmxApplicationException e) {\n            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(e.\n                    getMessage(), NotifyDescriptor.ERROR_MESSAGE));\n        } finally {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    if (pHandle[0] != null) {\n                        pHandle[0].finish();\n                    }\n                }\n            });\n        }\n        return null;\n    }\n    \n    /**\n     * Creates new Application defined by JMX connection and adds it to the\n     * Applications tree. Displays progress during application creation and\n     * opens an error dialog if creating the application failed.\n     *\n     * Note that even if the created application isn't persistent for another\n     * VisualVM sessions, the host created for this application will be restored.\n     *\n     * @param connectionString definition of the connection, for example hostname:port\n     * @param displayName display name for the application, may be null\n     * @param provider JMX EnvironmentProvider for the Application\n     * @param persistent controls whether the application definition will be persisted for another VisualVM sessions\n     * @return created JMX application or null if creating the application failed\n     */\n    public Application createJmxApplicationInteractive(String connectionString,\n                                            String displayName,\n                                            EnvironmentProvider provider,\n                                            boolean persistent) {\n\n        return createJmxApplicationInteractive(connectionString, displayName,\n                                            provider, persistent, false);\n    }\n\n    /**\n     * Creates new Application defined by JMX connection and adds it to the\n     * Applications tree. Displays progress during application creation and\n     * opens an error dialog if creating the application failed.\n     *\n     * Note that even if the created application isn't persistent for another\n     * VisualVM sessions, the host created for this application will be restored.\n     *\n     * @param connectionString definition of the connection, for example hostname:port\n     * @param displayName display name for the application, may be null\n     * @param provider JMX EnvironmentProvider for the Application\n     * @param persistent controls whether the application definition will be persisted for another VisualVM sessions\n     * @param allowsInsecure true if SSL is not required for the connection, false otherwise\n     * @return created JMX application or null if creating the application failed\n     */\n    public Application createJmxApplicationInteractive(String connectionString,\n                                            String displayName,\n                                            EnvironmentProvider provider,\n                                            boolean persistent, boolean allowsInsecure) {\n\n        return createJmxApplicationInteractive(connectionString, displayName, provider, persistent,\n                                               allowsInsecure, true, true);\n    }\n    \n    /**\n     * Creates new Application defined by JMX connection and adds it to the\n     * Applications tree. Displays progress during application creation and\n     * opens an error dialog if creating the application failed.\n     *\n     * Note that even if the created application isn't persistent for another\n     * VisualVM sessions, the host created for this application will be restored.\n     *\n     * @param connectionString definition of the connection, for example hostname:port\n     * @param displayName display name for the application, may be null\n     * @param provider JMX EnvironmentProvider for the Application\n     * @param persistent controls whether the application definition will be persisted for another VisualVM sessions\n     * @param allowsInsecure true if SSL is not required for the connection, false otherwise\n     * @param connectImmediately true if the JMX connection should be attempted immediately after submitting, false otherwise\n     * @param connectAutomatically true if the JMX connection should be made automatically whenever the target application is available, false otherwise\n     * @return created JMX application or null if creating the application failed\n     */\n    public Application createJmxApplicationInteractive(String connectionString,\n                                            String displayName,\n                                            EnvironmentProvider provider,\n                                            boolean persistent, boolean allowsInsecure,\n                                            boolean connectImmediately, boolean connectAutomatically) {\n\n        final ProgressHandle[] pHandle = new ProgressHandle[1];\n        try {\n            String username = getUsername(provider);\n            final String suggestedName = JmxApplicationProvider.getSuggestedName(\n                    displayName, connectionString, username);\n            SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        pHandle[0] = ProgressHandle.createHandle(\n                                NbBundle.getMessage(JmxApplicationsSupport.class,\n                                                    \"LBL_Adding\", suggestedName)); // NOI18N\n                        pHandle[0].setInitialDelay(0);\n                        pHandle[0].start();\n                    }\n                });\n            return createJmxApplicationImpl(connectionString, displayName, suggestedName,\n                                            provider, persistent, allowsInsecure,\n                                            connectImmediately, connectAutomatically);\n        } catch (JmxApplicationException e) {\n            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(e.\n                    getMessage(), NotifyDescriptor.ERROR_MESSAGE));\n        } finally {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    if (pHandle[0] != null) {\n                        pHandle[0].finish();\n                    }\n                }\n            });\n        }\n        return null;\n    }\n\n    private Application createJmxApplicationImpl(String connectionString,\n                                            String displayName, String suggestedName,\n                                            EnvironmentProvider provider,\n                                            boolean persistent, boolean allowsInsecure,\n                                            boolean connectImmediately, boolean connectAutomatically)\n                                            throws JmxApplicationException {\n\n        return applicationProvider.createJmxApplication(connectionString, displayName, suggestedName,\n                provider, persistent, allowsInsecure, connectImmediately, connectAutomatically);\n    }\n    \n    private static String getUsername(EnvironmentProvider provider) {\n        return provider instanceof CredentialsProvider.Custom ?\n                ((CredentialsProvider.Custom)provider).getUsername(null) : null;\n    }\n    \n    static String getStorageDirectoryString() {\n        synchronized(storageDirectoryStringLock) {\n            if (storageDirectoryString == null)\n                storageDirectoryString = Storage.getPersistentStorageDirectoryString() + File.separator + STORAGE_DIRNAME;\n            return storageDirectoryString;\n        }\n    }\n\n    /**\n     * Returns storage directory for defined JMX applications.\n     *\n     * @return storage directory for defined JMX applications.\n     */\n    public static File getStorageDirectory() {\n        synchronized(storageDirectoryLock) {\n            if (storageDirectory == null) {\n                String storageString = getStorageDirectoryString();\n                storageDirectory = new File(storageString);\n                if (storageDirectory.exists() && storageDirectory.isFile())\n                    throw new IllegalStateException(\"Cannot create hosts storage directory \" + storageString + \", file in the way\");    // NOI18N\n                if (storageDirectory.exists() && (!storageDirectory.canRead() || !storageDirectory.canWrite())) \n                    throw new IllegalStateException(\"Cannot access hosts storage directory \" + storageString + \", read&write permission required\"); // NOI18N\n                if (!Utils.prepareDirectory(storageDirectory))\n                    throw new IllegalStateException(\"Cannot create hosts storage directory \" + storageString);  // NOI18N\n            }\n            return storageDirectory;\n        }\n    }\n\n    /**\n     * Returns true if the storage directory for defined JMX applications already exists, false otherwise.\n     *\n     * @return true if the storage directory for defined JMX applications already exists, false otherwise.\n     */\n    public static boolean storageDirectoryExists() {\n        return new File(getStorageDirectoryString()).isDirectory();\n    }\n\n\n    private JmxApplicationsSupport() {\n        applicationProvider.initialize();\n    }\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/JmxConnectionCustomizer.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.properties.PropertiesPanel;\nimport org.graalvm.visualvm.core.properties.PropertiesProvider;\nimport org.graalvm.visualvm.jmx.impl.JmxPropertiesProvider;\n\n/**\n * Provider of a special JMX connection type. By registering the customizer\n * using JmxApplicationsSupport.registerConnectionCustomizer() a new connection\n * type is added to the Add JMX Connection dialog.\n * \n * If the hidesDefault flag is set for the customizer the default JMX connection\n * type provided by VisualVM is not displayed. This is useful when the custom\n * connection type extends the default one by adding new settings and it's not\n * desired to present both types to the user.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JmxConnectionCustomizer extends PropertiesProvider<Application> {\n\n    private final boolean hidesDefault;\n\n\n    /**\n     * Creates new instance of the JmxConnectionCustomizer. Typically only one\n     * instance of the customizer is needed, use\n     * JmxConnectionSupport.registerCustomizer to register the instance.\n     *\n     * @param customizerName name of the customizer to be displayed in the UI\n     * @param customizerDescription optional description of the customizer, may be null\n     * @param customizerPosition preferred position of this customizer in UI\n     * @param hidesDefault true if the default connection type should be hidden by this customizer, false otherwise\n     */\n    public JmxConnectionCustomizer(String customizerName, String customizerDescription,\n                                   int customizerPosition, boolean hidesDefault) {\n        super(customizerName, customizerDescription,\n              JmxPropertiesProvider.CATEGORY_JMX_CONNECTION, customizerPosition);\n        if (customizerName == null)\n            throw new IllegalArgumentException(\"customizerName cannot be null\"); // NOI18N\n        this.hidesDefault = hidesDefault;\n    }\n\n    /**\n     * Returns a unique String identifying the JmxConnectionCustomizer. The return\n     * value is used for persistency purposes and must be constant for customizers\n     * customizing persistent JMX connections. Default implementation returns\n     * this.getClass().getName().\n     *\n     * @return unique String identifying the JmxConnectionCustomizer\n     */\n    public String getId() { return getClass().getName(); }\n\n    /**\n     * Returns the Setup defining the JMX connection to be created.\n     * \n     * @param customizerPanel PropertiesPanel with the user-defined settings\n     * @return Setup defining the JMX connection to be created\n     */\n    public abstract Setup getConnectionSetup(PropertiesPanel customizerPanel);\n\n    /**\n     * Returns true if the JmxConnectionCustomizer works as a PropertiesProvider\n     * for the provided Application, false otherwise.\n     *\n     * @param application Application for which to provide the properties (never null)\n     * @return true if the JmxConnectionCustomizer works as a PropertiesProvider for the provided Application, false otherwise\n     */\n    public boolean providesProperties(Application application) { return true; }\n\n\n    /**\n     * Returns true if the default connection type should be hidden by this customizer, false otherwise.\n     *\n     * @return true if the default connection type should be hidden by this customizer, false otherwise\n     */\n    public final boolean hidesDefault() { return hidesDefault; }\n\n\n    /**\n     * Default implementation of the PropertiesProvider.supportsDataSource method,\n     * cannot be further overridden. JmxConnectionCustomizer always supports providing\n     * initial properties for a JMX application being created. Use the providesProperties\n     * method to control whether to provide a properties category for an existing\n     * application or not.\n     * \n     * @param application Application for which to provide the properties\n     * @return true for null Application, providesProperties(application) result otherwise\n     */\n    public final boolean supportsDataSource(Application application) {\n        return application == null ? true : providesProperties(application);\n    }\n\n    public void propertiesDefined(PropertiesPanel panel, Application application) {}\n\n    public void propertiesChanged(PropertiesPanel panel, Application application) {}\n\n    public void propertiesCancelled(PropertiesPanel panel, Application application) {}\n\n\n    public final String toString() { return getPropertiesName(); }\n\n\n    /**\n     * Setup based on the user-provided settings in the Panel defining the JMX\n     * connection to be created.\n     *\n     * @author Jiri Sedlacek\n     */\n    public static final class Setup {\n\n        private final String connectionString;\n        private final String displayName;\n        private final EnvironmentProvider environmentProvider;\n        private final boolean persistentConnection;\n        private final boolean allowsInsecureConnection;\n        private final boolean connectImmediately;\n        private final boolean connectAutomatically;\n\n\n        /**\n         * Creates new instance of Setup.\n         *\n         * @param connectionString connection string for the JMX connection\n         * @param displayName display name of the JMX connection or null\n         * @param environmentProvider EnvironmentProvider for the JMX connection\n         * @param persistentConnection true if the connection should be persisted for another VisualVM sessions, false otherwise\n         */\n        public Setup(String connectionString, String displayName,\n                     EnvironmentProvider environmentProvider,\n                     boolean persistentConnection) {\n            this(connectionString, displayName, environmentProvider,\n                 persistentConnection, false);\n        }\n        \n        /**\n         * Creates new instance of Setup.\n         *\n         * @param connectionString connection string for the JMX connection\n         * @param displayName display name of the JMX connection or null\n         * @param environmentProvider EnvironmentProvider for the JMX connection\n         * @param persistentConnection true if the connection should be persisted for another VisualVM sessions, false otherwise\n         * @param allowsInsecureConnection true if SSL is not required for the connection, false otherwise\n         */\n        public Setup(String connectionString, String displayName,\n                     EnvironmentProvider environmentProvider,\n                     boolean persistentConnection, boolean allowsInsecureConnection) {\n            this(connectionString, displayName, environmentProvider, persistentConnection, allowsInsecureConnection, true, true);\n        }\n        \n        /**\n         * Creates new instance of Setup.\n         *\n         * @param connectionString connection string for the JMX connection\n         * @param displayName display name of the JMX connection or null\n         * @param environmentProvider EnvironmentProvider for the JMX connection\n         * @param persistentConnection true if the connection should be persisted for another VisualVM sessions, false otherwise\n         * @param allowsInsecureConnection true if SSL is not required for the connection, false otherwise\n         * @param connectImmediately true if the JMX connection should be attempted immediately after submitting, false otherwise\n         * @param connectAutomatically true if the JMX connection should be made automatically whenever the target application is available, false otherwise\n         */\n        public Setup(String connectionString, String displayName,\n                     EnvironmentProvider environmentProvider,\n                     boolean persistentConnection, boolean allowsInsecureConnection,\n                     boolean connectImmediately, boolean connectAutomatically) {\n            if (connectionString == null)\n                throw new IllegalArgumentException(\"connectionString cannot be null\"); // NOI18N\n            if (environmentProvider == null)\n                throw new IllegalArgumentException(\"environmentProvider cannot be null\"); // NOI18N\n\n            this.connectionString = connectionString;\n            this.displayName = displayName;\n            this.environmentProvider = environmentProvider;\n            this.persistentConnection = persistentConnection;\n            this.allowsInsecureConnection = allowsInsecureConnection;\n            this.connectImmediately = connectImmediately;\n            this.connectAutomatically = connectAutomatically;\n        }\n\n\n        /**\n         * Returns the JMX connection string defining the connection to be created.\n         *\n         * @return JMX connection string defining the connection to be created\n         */\n        public String getConnectionString() { return connectionString; }\n\n        /**\n         * Returns the display name of the JMX connection to be created.\n         *\n         * @return display name of the JMX connection to be created\n         */\n        public String getDisplayName() { return displayName; }\n\n        /**\n         * Returns the EnvironmentProvider for the JMX connection to be created or null.\n         *\n         * @return EnvironmentProvider for the JMX connection to be created or null\n         */\n        public EnvironmentProvider getEnvironmentProvider() { return environmentProvider; }\n\n        /**\n         * Returns true if the JMX connection to be created should be restored for another VisualVM sessions, false otherwise\n         *\n         * @return true if the JMX connection to be created should be restored for another VisualVM sessions, false otherwise\n         */\n        public boolean isConnectionPersistent() { return persistentConnection; }\n        \n        /**\n         * Returns true if SSL is not required for the connection.\n         *\n         * @return true if SSL is not required for the connection, false otherwise\n         */\n        public boolean allowsInsecureConnection() { return allowsInsecureConnection; }\n        \n        /**\n         * Returns true if the JMX connection should be attempted immediately after submitting.\n         *\n         * @return true if the JMX connection should be attempted immediately after submitting, false otherwise\n         */\n        public boolean isConnectImmediately() { return connectImmediately; }\n        \n        /**\n         * Returns true if the JMX connection should be made automatically whenever the target application is available.\n         *\n         * @return true if the JMX connection should be made automatically whenever the target application is available, false otherwise\n         */\n        public boolean isConnectAutomatically() { return connectAutomatically; }\n        \n    }\n\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/JmxConnectionSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx;\n\nimport org.graalvm.visualvm.jmx.impl.JmxConnectionSupportImpl;\n\n/**\n * Support for customizing JMX connections in VisualVM. An entrypoint for\n * registering custom {@link EnvironmentProvider} and {@link JmxConnectionCustomizer}.\n *\n * @author Jiri Sedlacek\n */\npublic final class JmxConnectionSupport {\n\n    private static JmxConnectionSupport INSTANCE;\n\n    \n    /**\n     * Returns singleton instance of JmxConnectionSupport.\n     * \n     * @return singleton instance of JmxConnectionSupport\n     */\n    public synchronized static JmxConnectionSupport getInstance() {\n        if (INSTANCE == null) INSTANCE = new JmxConnectionSupport();\n        return INSTANCE;\n    }\n    \n\n    /**\n     * Registers new EnvironmentProvider.\n     * \n     * @param provider EnvironmentProvider to be registered\n     */\n    public void registerProvider(EnvironmentProvider provider) {\n        JmxConnectionSupportImpl.registerProviderImpl(provider);\n    }\n\n    /**\n     * Unregisters the EnvironmentProvider.\n     * \n     * @param provider EnvironmentProvider to unregister\n     */\n    public void unregisterProvider(EnvironmentProvider provider) {\n        JmxConnectionSupportImpl.unregisterProviderImpl(provider);\n    }\n\n\n    /**\n     * Registers new JmxConnectionCustomizer.\n     *\n     * @param customizer JmxConnectionCustomizer to be registered\n     */\n    public void registerCustomizer(JmxConnectionCustomizer customizer) {\n        JmxConnectionSupportImpl.registerCustomizer(customizer);\n    }\n\n    /**\n     * Unregisters the JmxConnectionCustomizer.\n     *\n     * @param customizer JmxConnectionCustomizer to unregister\n     */\n    public void unregisterCustomizer(JmxConnectionCustomizer customizer) {\n        JmxConnectionSupportImpl.unregisterCustomizer(customizer);\n    }\n    \n    \n    private JmxConnectionSupport() {}\n\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/AddJMXConnectionAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.awt.Image;\nimport java.awt.event.ActionEvent;\nimport java.util.Set;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.jmx.JmxApplicationsSupport;\nimport org.graalvm.visualvm.jmx.JmxConnectionCustomizer;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n    \n/**\n *\n * @author Jiri Sedlacek\n */\nclass AddJMXConnectionAction extends SingleDataSourceAction<Host> {\n    \n    private static final String ICON_PATH = \"org/graalvm/visualvm/jmx/resources/addJmxApplication.png\";   // NOI18N\n    private static final Image ICON =  ImageUtilities.loadImage(ICON_PATH);\n    \n    private boolean tracksSelection = false;\n    \n    private static AddJMXConnectionAction alwaysEnabled;\n    private static AddJMXConnectionAction selectionAware;\n    \n    \n    public static synchronized AddJMXConnectionAction alwaysEnabled() {\n        if (alwaysEnabled == null) {\n            alwaysEnabled = new AddJMXConnectionAction();\n            alwaysEnabled.putValue(SMALL_ICON, new ImageIcon(ICON));\n            alwaysEnabled.putValue(\"iconBase\", ICON_PATH);  // NOI18N\n        }\n        return alwaysEnabled;\n    }\n    \n    public static synchronized AddJMXConnectionAction selectionAware() {\n        if (selectionAware == null) {\n            selectionAware = new AddJMXConnectionAction();\n            selectionAware.tracksSelection = true;\n        }\n        return selectionAware;\n    }\n    \n    \n    protected void actionPerformed(Host host, ActionEvent actionEvent) {\n        final JmxConnectionConfigurator.Result result = JmxConnectionConfigurator.getResult();\n        final JmxConnectionCustomizer.Setup setup = result.getSetup();\n        if (setup != null) {\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    JmxApplication application = (JmxApplication)JmxApplicationsSupport.\n                            getInstance().createJmxApplicationInteractive(\n                            setup.getConnectionString(), setup.getDisplayName(),\n                            setup.getEnvironmentProvider(), setup.isConnectionPersistent(),\n                            setup.allowsInsecureConnection(), setup.isConnectImmediately(),\n                            setup.isConnectAutomatically());\n                    if (application == null) result.cancelled();\n                    else result.accepted(application);\n                }\n            });\n        } else {\n            result.cancelled();\n        }\n    }\n    \n    protected boolean isEnabled(Host host) {\n        return host != Host.UNKNOWN_HOST;\n    }\n    \n    protected void updateState(Set<Host> selectedHosts) {\n        if (tracksSelection) super.updateState(selectedHosts);\n    }\n    \n    \n    private AddJMXConnectionAction() {\n        super(Host.class);\n        putValue(NAME, NbBundle.getMessage(AddJMXConnectionAction.class, \"MSG_Add_JMX_Connection\"));    // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(AddJMXConnectionAction.class, \"ToolTip_Add_JMX_Connection\"));   // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/AutoConnectAction.java",
    "content": "/*\n *  Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JMenuItem;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.actions.Presenter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class AutoConnectAction extends SingleDataSourceAction<JmxApplication> implements Presenter.Popup {\n    \n    private static AutoConnectAction INSTANCE;\n    \n    private boolean currentAutoConnect;\n    \n    \n    public static synchronized AutoConnectAction instance() {\n        if (INSTANCE == null) INSTANCE = new AutoConnectAction();\n        return INSTANCE;\n    }\n    \n    \n    @Override\n    protected void actionPerformed(final JmxApplication app, ActionEvent actionEvent) {\n        final boolean autoConnect = currentAutoConnect;\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                if (autoConnect) app.disableHeartbeat();\n                else app.enableHeartbeat();\n            }\n        });\n    }\n\n    @Override\n    protected boolean isEnabled(JmxApplication app) {\n        return true;\n    }\n    \n    \n    @Override\n    public JMenuItem getPopupPresenter() {\n        JmxApplication app = ActionUtils.getSelectedDataSource(getScope());\n        currentAutoConnect = !app.isHeartbeatDisabled();\n        \n        JMenuItem presenter = new JCheckBoxMenuItem(this);\n        Mnemonics.setLocalizedText(presenter, NbBundle.getMessage(AutoConnectAction.class, \"LBL_AutoConnect\")); // NOI18N\n        presenter.setSelected(currentAutoConnect);\n        \n        return presenter;\n    }\n    \n    \n    private AutoConnectAction() {\n        super(JmxApplication.class);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\n\nMSG_Add_JMX_Connection=Add &JMX Connection...\n\nToolTip_Add_JMX_Connection=Add JMX Connection\n\nTitle_Add_JMX_Connection=Add JMX Connection\n\nLBL_Supply_Security_Credentials=Supply Security Credentials\n\nLBL_CredentialsMsg1=Security credentials for this connection are invalid or missing\\:\nLBL_CredentialsMsg2=Please provide the username and password:\n\nLBL_Username=&Username\\:\n\nLBL_Password=&Password\\:\n\nLBL_OK=OK\n\nTitle_Unresolved_JMX=Could Not Resolve JMX Connections\n\nMSG_Unresolved_JMX=<html><b>These JMX connections could not be resolved:</b><br>Do you want to resolve them on next VisualVM session?<br><br></html>\n\nMSG_Invalid_JMX_connection=Invalid JMX connection\\: {0}\n\nMSG_Cannot_resolve_host=Cannot resolve host\\: {0}\n\nMSG_connection_already_exists=JMX connection {0} already exists as {1}\n\nMSG_Cannot_connect_using=Cannot connect to {0} using {1}\n\nLBL_Connection_type=Connection &type\\:\n\nMSG_OPENJMX=open application specified by JMX connection (host:port)\n\nCAP_JmxConnection=JMX Connection\nDESCR_JmxConnection=JMX connection setup\n\nLBL_ConnectionProperties=Connection\nDESCR_ConnectionProperties=Connection used to discover and manage the application\nMSG_ConnectionProperties=The application is managed by a JMX connection. See the JMX Connection tab for details.\n\nTitle_Insecure_SSL=Secure Connection Failed\nMSG_Insecure_SSL=<html><b>The connection to {0}<br>could not be made using SSL. Retry without SSL?</b><br><br>\\\n                 Note that username and password will be sent in plain text.<html>\n\nRetry_Insecure_SSL=&Do not require SSL for this connection\n\nLBL_RememberAction=&Remember selected action\nTTP_RememberAction=Select to perform the action automatically on subsequent sessions. Can be reset using {0} | General | Reset Do Not Show Again confirmations.\n\nLBL_Connect=&Connect\nLBL_Disconnect=&Disconnect\nLBL_AutoConnect=Connect A&utomatically\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/ConnectDisconnectAction.java",
    "content": "/*\n *  Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.JMenuItem;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.actions.Presenter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ConnectDisconnectAction extends SingleDataSourceAction<JmxApplication> implements Presenter.Popup {\n    \n    private static ConnectDisconnectAction INSTANCE;\n    \n    private int currentState = Stateful.STATE_UNKNOWN;\n    private boolean currentAutoConnect;\n    \n    \n    public static synchronized ConnectDisconnectAction instance() {\n        if (INSTANCE == null) INSTANCE = new ConnectDisconnectAction();\n        return INSTANCE;\n    }\n    \n    \n    @Override\n    protected void actionPerformed(final JmxApplication app, ActionEvent actionEvent) {\n        final int state = currentState;\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                if (state == Stateful.STATE_AVAILABLE) app.disconnect();\n                else JmxHeartbeat.scheduleImmediately(app);\n            }\n        });\n    }\n\n    @Override\n    protected boolean isEnabled(JmxApplication app) {\n        return true;\n    }\n    \n    @Override\n    public JMenuItem getPopupPresenter() {\n        JmxApplication app = ActionUtils.getSelectedDataSource(getScope());\n        currentState = app.getState();\n        currentAutoConnect = !app.isHeartbeatDisabled();\n        \n        JMenuItem presenter = new JMenuItem(this);\n        if (currentState == Stateful.STATE_AVAILABLE) Mnemonics.setLocalizedText(presenter, NbBundle.getMessage(ConnectDisconnectAction.class, \"LBL_Disconnect\")); // NOI18N\n        else Mnemonics.setLocalizedText(presenter, NbBundle.getMessage(ConnectDisconnectAction.class, \"LBL_Connect\")); // NOI18N\n        presenter.setEnabled(currentState == Stateful.STATE_AVAILABLE || !currentAutoConnect);\n        \n        return presenter;\n    }\n    \n    \n    private ConnectDisconnectAction() {\n        super(JmxApplication.class);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/CredentialsConfigurator.java",
    "content": "/*\n * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.awt.Dialog;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPasswordField;\nimport javax.swing.JTextField;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Luis-Miguel Alventosa\n * @author Jiri Sedlacek\n */\npublic final class CredentialsConfigurator extends JPanel {\n\n    public static CredentialsConfigurator supplyCredentials(String url) {\n        CredentialsConfigurator asc = new CredentialsConfigurator(url);\n        asc.setupDefineCredentials();\n\n        final String title = NbBundle.getMessage(CredentialsConfigurator.class, \"LBL_Supply_Security_Credentials\");   // NOI18N\n        final DialogDescriptor dd = new DialogDescriptor(\n                asc, title, true,\n                new Object[]{asc.okButton, DialogDescriptor.CANCEL_OPTION},\n                asc.okButton, 0, null, null);\n        final Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n        d.pack();\n        d.setVisible(true);\n\n        if (dd.getValue() == asc.okButton) {\n            return asc;\n        } else {\n            return null;\n        }\n    }\n\n    public String getUsername() {\n        return usernameField.getText().trim();\n    }\n\n    public char[] getPassword() {\n        return passwordField.getPassword();\n    }\n\n    private CredentialsConfigurator(String url) {\n        initComponents(url);\n        update();\n    }\n\n    private void setupDefineCredentials() {\n        usernameField.setEnabled(true);\n        usernameField.setText(\"\");\n        passwordField.setEnabled(true);\n        passwordField.setText(\"\");\n    }\n\n    private void update() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                String username = getUsername();\n                char[] password = getPassword();\n                okButton.setEnabled(username.length() > 0 && password.length > 0);\n            }\n        });\n    }\n\n    private void initComponents(String url) {\n        setLayout(new GridBagLayout());\n        GridBagConstraints constraints;\n        \n        // hintLabel1\n        hintLabel1 = new JLabel();\n        hintLabel1.setFont(hintLabel1.getFont().deriveFont(Font.BOLD));\n        Mnemonics.setLocalizedText(hintLabel1, NbBundle.getMessage(CredentialsConfigurator.class, \"LBL_CredentialsMsg1\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 0;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(15, 10, 0, 30);\n        add(hintLabel1, constraints);\n        \n        // urlLabel\n        urlLabel = new JLabel(url);\n//        urlLabel.setFont(new Font(Font.MONOSPACED, Font.PLAIN, urlLabel.getFont().getSize()));\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(5, 20, 0, 10);\n        add(urlLabel, constraints);\n        \n        // hintLabel2\n        hintLabel2 = new JLabel();\n        Mnemonics.setLocalizedText(hintLabel2, NbBundle.getMessage(CredentialsConfigurator.class, \"LBL_CredentialsMsg2\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 2;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(20, 10, 0, 10);\n        add(hintLabel2, constraints);\n\n        // usernameLabel\n        usernameLabel = new JLabel();\n        Mnemonics.setLocalizedText(usernameLabel, NbBundle.getMessage(CredentialsConfigurator.class, \"LBL_Username\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 3;\n        constraints.gridwidth = 1;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(10, 20, 0, 0);\n        add(usernameLabel, constraints);\n\n        // usernameField\n        usernameField = new JTextField();\n        usernameLabel.setLabelFor(usernameField);\n        usernameField.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) {\n                update();\n            }\n            public void removeUpdate(DocumentEvent e) {\n                update();\n            }\n            public void changedUpdate(DocumentEvent e) {\n                update();\n            }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 1;\n        constraints.gridy = 3;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.HORIZONTAL;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(10, 5, 0, 10);\n        add(usernameField, constraints);\n\n        // passwordLabel\n        passwordLabel = new JLabel();\n        Mnemonics.setLocalizedText(passwordLabel, NbBundle.getMessage(CredentialsConfigurator.class, \"LBL_Password\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 4;\n        constraints.gridwidth = 1;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(8, 20, 0, 0);\n        add(passwordLabel, constraints);\n\n        // passwordField\n        passwordField = new JPasswordField();\n        passwordLabel.setLabelFor(passwordField);\n        passwordField.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) {\n                update();\n            }\n            public void removeUpdate(DocumentEvent e) {\n                update();\n            }\n            public void changedUpdate(DocumentEvent e) {\n                update();\n            }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 1;\n        constraints.gridy = 4;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.HORIZONTAL;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(8, 5, 0, 10);\n        add(passwordField, constraints);\n\n        // spacer\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 5;\n        constraints.weightx = 1;\n        constraints.weighty = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.insets = new Insets(0, 0, 15, 0);\n        add(Spacer.create(), constraints);\n\n        // okButton\n        okButton = new JButton(NbBundle.getMessage(CredentialsConfigurator.class, \"LBL_OK\"));   // NOI18N\n    }\n\n    private JLabel hintLabel1;\n    private JLabel urlLabel;\n    private JLabel hintLabel2;\n    private JLabel usernameLabel;\n    private JTextField usernameField;\n    private JLabel passwordLabel;\n    private JPasswordField passwordField;\n    private JButton okButton;\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/DisconnectedJmxModel.java",
    "content": "/*\n * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.util.Map;\nimport java.util.Properties;\nimport javax.management.MBeanServerConnection;\nimport javax.management.remote.JMXServiceURL;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass DisconnectedJmxModel extends JmxModel {\n\n    private final JMXServiceURL url;\n\n    DisconnectedJmxModel(JmxApplication app) {\n        url = app.getJMXServiceURL();\n    }\n\n    @Override\n    public ConnectionState getConnectionState() {\n        return ConnectionState.DISCONNECTED;\n    }\n\n    @Override\n    public MBeanServerConnection getMBeanServerConnection() {\n        return null;\n    }\n\n    @Override\n    public JvmMXBeans getJvmMXBeans() {\n        return null;\n    }\n\n    @Override\n    public JMXServiceURL getJMXServiceURL() {\n        return url;\n    }\n\n    @Override\n    public Properties getSystemProperties() {\n        return null;\n    }\n\n    @Override\n    public boolean isTakeHeapDumpSupported() {\n        return false;\n    }\n\n    @Override\n    public boolean takeHeapDump(String fileName) {\n        return false;\n    }\n\n    @Override\n    public boolean isTakeThreadDumpSupported() {\n        return false;\n    }\n\n    @Override\n    public String takeThreadDump() {\n        return null;\n    }\n\n    @Override\n    public String takeThreadDump(long[] threadIds) {\n        return null;\n    }\n\n    @Override\n    public HeapHistogram takeHeapHistogram() {\n        return null;\n    }\n\n    @Override\n    public String getFlagValue(String name) {\n        return null;\n    }\n\n    @Override\n    public void setFlagValue(String name, String value) {\n    }\n\n    @Override\n    public String getCommandLine() {\n        return null;\n    }\n\n    @Override\n    public String executeJCmd(String command, Map<String, Object> pars) {\n        return \"\";\n    }\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/GeneralPropertiesProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport javax.swing.BorderFactory;\nimport javax.swing.JTextArea;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.core.properties.PropertiesPanel;\nimport org.graalvm.visualvm.core.properties.PropertiesProvider;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class GeneralPropertiesProvider extends PropertiesProvider<JmxApplication> {\n\n    public GeneralPropertiesProvider() {\n        super(NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_ConnectionProperties\"), // NOI18N\n              NbBundle.getMessage(GeneralPropertiesProvider.class, \"DESCR_ConnectionProperties\"), // NOI18N\n              CATEGORY_GENERAL, 50);\n    }\n\n\n    public PropertiesPanel createPanel(JmxApplication dataSource) {\n        PropertiesPanel panel = new PropertiesPanel();\n        panel.setLayout(new BorderLayout());\n        JTextArea textArea = new JTextArea() {\n            public Dimension getMinimumSize() {\n                Dimension prefSize = getPreferredSize();\n                Dimension minSize = super.getMinimumSize();\n                prefSize.width = 0;\n                if (minSize.height < prefSize.height) return prefSize;\n                else return minSize;\n            }\n        };\n        textArea.setBorder(BorderFactory.createEmptyBorder());\n        textArea.setOpaque(false);\n        // Nimbus LaF doesn't respect setOpaque(false), this is a workaround.\n        // May cause delays for remote X sessions due to color transparency.\n        if (UIManager.getLookAndFeel().getID().equals(\"Nimbus\")) // NOI18N\n            textArea.setBackground(new Color(0, 0, 0, 0));\n        textArea.setEditable(false);\n        textArea.setLineWrap(true);\n        textArea.setWrapStyleWord(true);\n        textArea.setText(NbBundle.getMessage(GeneralPropertiesProvider.class, \"MSG_ConnectionProperties\")); // NOI18N\n        textArea.setCaretPosition(0);\n        textArea.setMinimumSize(new Dimension(1, 1));\n        panel.add(textArea, BorderLayout.CENTER);\n        return panel;\n    }\n\n\n    public boolean supportsDataSource(JmxApplication dataSource) { return dataSource != null; }\n\n    public void propertiesDefined(PropertiesPanel panel, JmxApplication dataSource) {}\n\n    public void propertiesChanged(PropertiesPanel panel, JmxApplication dataSource) {}\n\n    public void propertiesCancelled(PropertiesPanel panel, JmxApplication dataSource) {}\n\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/HeapHistogramImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Scanner;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HeapHistogramImpl extends HeapHistogram {\n    private static final String BOOLEAN_TEXT = \"boolean\"; // NOI18N\n    private static final String CHAR_TEXT = \"char\"; // NOI18N\n    private static final String BYTE_TEXT = \"byte\"; // NOI18N\n    private static final String SHORT_TEXT = \"short\"; // NOI18N\n    private static final String INT_TEXT = \"int\"; // NOI18N\n    private static final String LONG_TEXT = \"long\"; // NOI18N\n    private static final String FLOAT_TEXT = \"float\"; // NOI18N\n    private static final String DOUBLE_TEXT = \"double\"; // NOI18N\n    private static final String VOID_TEXT = \"void\"; // NOI18N\n    private static final char BOOLEAN_CODE = 'Z'; // NOI18N\n    private static final char CHAR_CODE = 'C'; // NOI18N\n    private static final char BYTE_CODE = 'B'; // NOI18N\n    private static final char SHORT_CODE = 'S'; // NOI18N\n    private static final char INT_CODE = 'I'; // NOI18N\n    private static final char LONG_CODE = 'J'; // NOI18N\n    private static final char FLOAT_CODE = 'F'; // NOI18N\n    private static final char DOUBLE_CODE = 'D'; // NOI18N\n    private static final char OBJECT_CODE = 'L'; // NOI18N\n    Set<ClassInfo> classes;\n    Date time;\n    long totalBytes;\n    long totalInstances;\n    long totalHeapBytes;\n    long totalHeapInstances;\n\n    HeapHistogramImpl(String histogramText) {\n        Map<String,ClassInfoImpl> classesMap = new HashMap<>(1024);\n        time = new Date();\n        Scanner sc = new Scanner(histogramText);\n        sc.useRadix(10);\n        while(!sc.hasNext(\"-+\")) {\n            sc.nextLine();\n        }\n        sc.skip(\"-+\");\n        sc.nextLine();\n\n\n        while(sc.hasNext(\"[0-9]+:\")) {  // NOI18N\n            ClassInfoImpl newClInfo = new ClassInfoImpl(sc);\n            storeClassInfo(newClInfo, classesMap);\n            totalHeapBytes += newClInfo.getBytes();\n            totalHeapInstances += newClInfo.getInstancesCount();\n        }\n        sc.next(\"Total\");   // NOI18N\n        totalInstances = sc.nextLong();\n        totalBytes = sc.nextLong();\n        classes = new HashSet<>(classesMap.values());\n    }\n\n    void storeClassInfo(final ClassInfoImpl newClInfo, final Map<String, ClassInfoImpl> map) {\n        ClassInfoImpl oldClInfo = map.get(newClInfo.getName());\n        if (oldClInfo == null) {\n            map.put(newClInfo.getName(),newClInfo);\n        } else {\n            oldClInfo.bytes += newClInfo.getBytes();\n            oldClInfo.instances += newClInfo.getInstancesCount();\n        }\n    }\n\n    public Date getTime() {\n        return (Date) time.clone();\n    }\n\n    public Set<ClassInfo> getHeapHistogram() {\n        return classes;\n    }\n\n    public long getTotalInstances() {\n        return totalInstances;\n    }\n\n    public long getTotalBytes() {\n        return totalBytes;\n    }\n\n    public long getTotalHeapInstances() {\n        return totalHeapInstances;\n    }\n\n    public long getTotalHeapBytes() {\n        return totalHeapBytes;\n    }\n\n    public Set<ClassInfo> getPermGenHistogram() {\n        return Collections.emptySet();\n    }\n\n    public long getTotalPerGenInstances() {\n        return -1;\n    }\n\n    public long getTotalPermGenHeapBytes() {\n        return -1;\n    }\n\n    static class ClassInfoImpl extends ClassInfo {\n        long instances;\n        long bytes;\n        String name;\n\n        ClassInfoImpl(Scanner sc) {\n            String jvmName;\n\n            sc.next();\n            instances = sc.nextLong();\n            bytes = sc.nextLong();\n            jvmName = sc.next();\n            sc.nextLine();  // skip module name on JDK 9\n            name = convertJVMName(jvmName);\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public long getInstancesCount() {\n            return instances;\n        }\n\n        public long getBytes() {\n            return bytes;\n        }\n\n        public int hashCode() {\n            return getName().hashCode();\n        }\n\n        public boolean equals(Object obj) {\n            if (obj instanceof ClassInfoImpl) {\n                return getName().equals(((ClassInfoImpl)obj).getName());\n            }\n            return false;\n        }\n\n        private String convertJVMName(String jvmName) {\n            String className = null;\n            int index = jvmName.lastIndexOf('[');     // NOI18N\n\n            if (index != -1) {\n                switch(jvmName.charAt(index+1)) {\n                    case BOOLEAN_CODE:\n                        className=BOOLEAN_TEXT;\n                        break;\n                    case CHAR_CODE:\n                        className=CHAR_TEXT;\n                        break;\n                    case BYTE_CODE:\n                        className=BYTE_TEXT;\n                        break;\n                    case SHORT_CODE:\n                        className=SHORT_TEXT;\n                        break;\n                    case INT_CODE:\n                        className=INT_TEXT;\n                        break;\n                    case LONG_CODE:\n                        className=LONG_TEXT;\n                        break;\n                    case FLOAT_CODE:\n                        className=FLOAT_TEXT;\n                        break;\n                    case DOUBLE_CODE:\n                        className=DOUBLE_TEXT;\n                        break;\n                    case OBJECT_CODE:\n                        className=jvmName.substring(index+2,jvmName.length()-1);\n                        break;\n                    default:\n                        System.err.println(\"Uknown name \"+jvmName);     // NOI18N\n                        className = jvmName;\n                }\n                for (int i=0;i<=index;i++) {\n                    className+=\"[]\";\n                }\n            }\n            if (className == null) {\n                className = jvmName;\n            }\n            return className.intern();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxApplication.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.io.IOException;\nimport java.lang.management.ManagementFactory;\nimport java.lang.management.RuntimeMXBean;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.remote.JMXServiceURL;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.jmx.EnvironmentProvider;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\n\n/**\n * This type of application represents an application\n * that is built from a {@link JMXServiceURL}.\n * \n * @author Luis-Miguel Alventosa\n * @author Jiri Sedlacek\n */\npublic final class JmxApplication extends Application {\n    \n    private static final Logger LOGGER = Logger.getLogger(JmxApplication.class.getName());\n    \n    static final String PROPERTY_DISABLE_HEARTBEAT = \"prop_disable_heartbeat\"; // NOI18N\n    \n    private int pid = UNKNOWN_PID;\n    private final JMXServiceURL url;\n    private final EnvironmentProvider envProvider;\n    private final Storage storage;\n    // since getting JVM for the first time can take a long time\n    // hard reference jvm from application so we are sure that it is not garbage collected\n    private Jvm jvm;\n    private JmxModel jmxModel;\n    private ProxyClient client;\n    \n    private PropertyChangeListener modelListener;\n    \n    private final Object connectionLock = new Object();\n\n    // Note: storage may be null, in this case the JmxApplication isn't persistent\n    // and creates a temporary storage just like any other regular Application\n    public JmxApplication(Host host, JMXServiceURL url, EnvironmentProvider envProvider, Storage storage) {\n        super(host, createId(url.toString(), envProvider, storage), STATE_UNAVAILABLE);\n        this.url = url;\n        this.envProvider = envProvider;\n        this.storage = storage;\n    }\n\n\n    public JMXServiceURL getJMXServiceURL() {\n        return url;\n    }\n\n    public EnvironmentProvider getEnvironmentProvider() {\n        return envProvider;\n    }\n\n    public int getPid() {\n        if (pid == UNKNOWN_PID && getState() == Stateful.STATE_AVAILABLE) {\n            if (jmxModel != null && jmxModel.getConnectionState() == ConnectionState.CONNECTED) {\n                JvmMXBeans mxbeans = jmxModel.getJvmMXBeans();\n                if (mxbeans != null) {\n                    RuntimeMXBean rt = mxbeans.getRuntimeMXBean();\n                    if (rt != null) {\n                        String name = rt.getName();\n                        if (name != null && name.contains(\"@\")) { // NOI18N\n                            name = name.substring(0, name.indexOf('@')); // NOI18N\n                            pid = Integer.parseInt(name);\n                        }\n                    }\n                }\n            }\n        }\n        return pid;\n    }\n\n    private static final String[] HOST_PROPS = {\n        \"os.arch\",\n        \"os.name\",\n        \"os.version\",\n        \"user.home\",\n        \"user.name\"\n    };\n    public boolean isLocalApplication() {\n        if (super.isLocalApplication()) {\n            // try to detect tunneled application\n            if (getState() == Stateful.STATE_AVAILABLE) {\n                if (jmxModel != null && jmxModel.getConnectionState() == ConnectionState.CONNECTED) {\n                    JvmMXBeans mxbeans = jmxModel.getJvmMXBeans();\n                    if (mxbeans != null) {\n                        RuntimeMXBean rt = mxbeans.getRuntimeMXBean();\n                        if (rt != null) {\n                            Map<String, String> appProperties = rt.getSystemProperties();\n                            if (!matchProps(HOST_PROPS, appProperties)) {\n                                return false;\n                            }\n                            if (!checkHostName(ManagementFactory.getRuntimeMXBean(), rt)) {\n                                return false;\n                            }\n                        }\n                    }\n                }\n            }\n            return true;\n        }\n        return false;\n    }\n\n    public boolean supportsUserRemove() {\n        return true;\n    }\n    \n    protected boolean supportsFinishedRemove() {\n        return storage == null;\n    }\n    \n    protected Storage createStorage() {\n        return storage != null ? storage : super.createStorage();\n    }\n    \n    protected void remove() {\n        if (getStorage().directoryExists())\n            Utils.delete(getStorage().getDirectory(), true);\n    }\n\n    public String toString() {\n        return \"JmxApplication [id: \" + getId() + \"]\";   // NOI18N\n    }\n\n    public static String createId(String urlId, EnvironmentProvider envProvider,\n                                   Storage storage) {\n        if (urlId == null) {\n            urlId = storage.getCustomProperty(JmxApplicationProvider.PROPERTY_CONNECTION_STRING);\n        }\n        // No envProvider -> return just url.toString()\n        if (envProvider == null) return urlId;\n\n        // No environmentID -> return just url.toString()\n        String envId = envProvider.getEnvironmentId(storage);\n        if (envId == null || envId.isEmpty()) return urlId; // NOI18N\n\n        // Defined environmentID -> use 'environmentID-url.toString()'\n        // Typically 'username-service:jmx:rmi:///jndi/rmi://hostName:portNum/jmxrmi'\n        return envId + \"-\" + urlId; // NOI18N\n    }\n\n    final ProxyClient getProxyClient() {\n        synchronized (connectionLock) {\n            return client;\n        }\n    }\n    \n    \n    // Only to be called from JmxHeartbeat\n    // Use JmxHeartbeat.scheduleImmediately(JmxApplication) from any other code!\n    final boolean tryConnect() {\n        synchronized (connectionLock) {\n            if (isConnected()) return true;\n            \n            try {\n                ProxyClient newClient = new ProxyClient(this);\n                newClient.connect();\n                if (newClient.getConnectionState() == ConnectionState.CONNECTED) {\n                    client = newClient;\n\n                    setStateImpl(Stateful.STATE_AVAILABLE);\n\n                    jmxModel = JmxModelFactory.getJmxModelFor(this);\n                    jvm = JvmFactory.getJVMFor(this);\n\n                    modelListener = new PropertyChangeListener() {\n                        public void propertyChange(PropertyChangeEvent evt) {\n                            if (evt.getNewValue() != ConnectionState.CONNECTED) {\n                                synchronized (connectionLock) {\n                                    setStateImpl(Stateful.STATE_UNAVAILABLE);\n                                }\n                            }\n                        }\n                    };\n                    jmxModel.addPropertyChangeListener(modelListener);\n\n                    return true;\n                }\n            } catch (IOException ex) {\n                LOGGER.log(Level.FINE, \"ProxyClient.connect\", ex); // NOI18N\n            }\n\n            return false;\n        }\n    }\n    \n    final void disconnect() {\n        disableHeartbeat();\n        \n        ProxyClient _client;\n        synchronized (connectionLock) {\n            if (!isConnected()) return;\n            _client = client;\n        }\n        \n        _client.disconnect(); // will invoke modelListener.propertyChange() -> ConnectionState.DISCONNECTED\n    }\n    \n    private boolean isConnected() { // must be called under connectionLock\n        return client != null && client.getConnectionState() == ConnectionState.CONNECTED;\n    }\n    \n    \n    private void setStateImpl(int newState) { // must be called under connectionLock\n        if (newState != Stateful.STATE_AVAILABLE) {\n            pid = UNKNOWN_PID;\n            jvm = null;\n            if (jmxModel != null && modelListener != null) jmxModel.removePropertyChangeListener(modelListener);\n            jmxModel = null;\n            client = null;\n            if (supportsHeartbeat(this)) JmxHeartbeat.scheduleLazily(this);\n        }\n        \n        setState(newState);\n    }\n    \n    \n    final void enableHeartbeat() {\n        getStorage().clearCustomProperty(PROPERTY_DISABLE_HEARTBEAT);\n        if (supportsHeartbeat(this)) {\n            synchronized (connectionLock) {\n                if (isConnected()) return;\n            }\n            JmxHeartbeat.scheduleImmediately(this);\n        }\n    }\n    \n    final void disableHeartbeat() {\n        getStorage().setCustomProperty(PROPERTY_DISABLE_HEARTBEAT, Boolean.TRUE.toString());\n    }\n    \n    final boolean isHeartbeatDisabled() {\n        return Boolean.TRUE.toString().equals(getStorage().getCustomProperty(PROPERTY_DISABLE_HEARTBEAT));\n    }\n    \n    \n    static boolean supportsHeartbeat(JmxApplication app) {\n        return !app.isRemoved() && !app.isHeartbeatDisabled();\n    }\n\n    private boolean matchProps(String[] propNames, Map<String, String> appProperties) {\n        for (String prop : propNames) {\n            String localProp = System.getProperty(prop);\n            String appProp = appProperties.get(prop);\n            if (!Objects.equals(localProp, appProp)) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    private boolean checkHostName(RuntimeMXBean localRuntime, RuntimeMXBean remoteRuntime) {\n        String localHost = getHostName(localRuntime.getName());\n        String remoteHost = getHostName(remoteRuntime.getName());\n\n        return Objects.equals(localHost, remoteHost);\n    }\n    \n    private String getHostName(String runtimeName) {\n        if (runtimeName == null) return null;\n        int index = runtimeName.indexOf('@');       // NOI18N\n\n        if (index >= 0) {\n            return runtimeName.substring(index+1);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxApplicationDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.awt.Image;\nimport java.beans.PropertyChangeEvent;\nimport java.util.Objects;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.ApplicationDescriptor;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.application.type.DefaultApplicationType;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.WeakListeners;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JmxApplicationDescriptor extends ApplicationDescriptor {\n     \n    private static final Image NODE_BADGE = ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/jmx/resources/jmxBadge.png\", true); // NOI18N\n     \n\n    protected JmxApplicationDescriptor(JmxApplication application) {\n        super(application, resolveApplicationType(application), resolvePosition(application, POSITION_AT_THE_END, true));\n        \n        application.addPropertyChangeListener(Stateful.PROPERTY_STATE, WeakListeners.propertyChange(this, Stateful.PROPERTY_STATE, application));\n//        application.addPropertyChangeListener(Stateful.PROPERTY_STATE, this);\n    }\n\n    public boolean supportsRename() {\n        return true;\n    }\n    \n    protected void setIcon(Image newIcon) {\n        super.setIcon(newIcon);\n        \n        String iconString = Utils.imageToString(newIcon, \"png\");   // NOI18N\n        getDataSource().getStorage().setCustomProperties(new String[] { PROPERTY_ICON }, new String[] { iconString });\n    }\n    \n    public Image getIcon() {\n        Image originalIcon = super.getIcon();\n        return originalIcon == null ? null : ImageUtilities.mergeImages(\n                                             originalIcon, NODE_BADGE, 0, 0);\n    }\n    \n    \n    private static ApplicationType resolveApplicationType(JmxApplication application) {\n        return application.getState() == Stateful.STATE_AVAILABLE ?\n               ApplicationTypeFactory.getApplicationTypeFor(application) :\n               new DisconnectedJmxApplicationType(application);\n    }\n    \n    \n    @Override\n    public void propertyChange(PropertyChangeEvent evt) {\n        super.propertyChange(evt);\n        \n        if (Stateful.PROPERTY_STATE.equals(evt.getPropertyName()) && Objects.equals(evt.getNewValue(), Stateful.STATE_AVAILABLE)) {\n            final Application application = getDataSource();\n            DataSource.EVENT_QUEUE.post(new Runnable() {\n                public void run() {\n                    ApplicationType type = ApplicationTypeFactory.getApplicationTypeFor(application);\n                    setApplicationType(type);\n                    \n                    String customName = application.getStorage().getCustomProperty(PROPERTY_NAME);\n                    if (customName != null) {\n                        setName(customName); // will reformat PID if needed\n                    } else {\n                        customName = resolveCustomName(application);\n                        if (customName != null) setImplicitName(customName, null);\n                        else setImplicitName(createGenericName(application, type.getName()), ApplicationType.PROPERTY_SUGGESTED_NAME);\n                    }\n                    \n                    setDescription(type.getDescription());\n                    setIcon(type.getIcon());\n                }\n            }, 500); // give the models some time to initialize to resolve the ApplicationType correctly\n        }\n    }\n    \n    \n    private static final class DisconnectedJmxApplicationType extends DefaultApplicationType {\n        \n        DisconnectedJmxApplicationType(JmxApplication application) {\n            super(application);\n        }\n     \n        \n        public String getDescription() {\n            return \"Unavailable application defined by a JMX connection.\";\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxApplicationDescriptorProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\n/**\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n * @author Luis-Miguel Alventosa\n */\npublic class JmxApplicationDescriptorProvider extends\n        AbstractModelProvider<DataSourceDescriptor, DataSource> {\n\n    public DataSourceDescriptor createModelFor(DataSource ds) {\n        if (ds instanceof JmxApplication) {\n            return new JmxApplicationDescriptor((JmxApplication) ds);\n        }\n        return null;\n    }\n    \n    public int priority() {\n        return 10;\n    }\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxApplicationProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.awt.BorderLayout;\nimport java.io.File;\nimport java.io.FilenameFilter;\nimport java.io.IOException;\nimport java.net.InetAddress;\nimport java.net.MalformedURLException;\nimport java.net.NetworkInterface;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport javax.management.remote.JMXServiceURL;\nimport javax.swing.BorderFactory;\nimport javax.swing.JCheckBox;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.host.HostsSupport;\nimport org.graalvm.visualvm.jmx.CredentialsProvider;\nimport org.graalvm.visualvm.jmx.EnvironmentProvider;\nimport org.graalvm.visualvm.jmx.JmxApplicationException;\nimport org.graalvm.visualvm.jmx.JmxApplicationsSupport;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.windows.WindowManager;\n\n/**\n * A provider for Applications added as JMX connections.\n *\n * @author Jiri Sedlacek\n * @author Luis-Miguel Alventosa\n */\npublic class JmxApplicationProvider {\n//    private static final Logger LOGGER = Logger.getLogger(JmxApplicationProvider.class.getName());\n    \n    // --- Snapshot format history ---------------------------------------------\n    //\n    // 1.0:     initial snapshot version\n    // 1.1:     added PROPERTY_ENV_PROVIDER_ID\n    // 1.2:     added PROPERTY_RETRY_WITHOUT_SSL\n    //\n    // -------------------------------------------------------------------------\n\n    private static final String SNAPSHOT_VERSION = \"snapshot_version\";  // NOI18N\n    private static final String SNAPSHOT_VERSION_DIVIDER = \".\";         // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = \"1\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION_MINOR = \"2\";   // NOI18N\n    private static final String CURRENT_SNAPSHOT_VERSION =\n                                                CURRENT_SNAPSHOT_VERSION_MAJOR +\n                                                SNAPSHOT_VERSION_DIVIDER +\n                                                CURRENT_SNAPSHOT_VERSION_MINOR;\n    \n    public static final String PROPERTY_RETRY_WITHOUT_SSL = \"prop_retry_without_ssl\"; // NOI18N\n    static final String PROPERTY_CONNECTION_STRING = \"prop_conn_string\";    // NOI18N\n    private static final String PROPERTY_HOSTNAME = \"prop_conn_hostname\";   // NOI18N\n    private static final String PROPERTY_ENV_PROVIDER_ID = \"prop_env_provider_id\"; // NOI18N\n    \n    \n    private static final String PROPERTIES_FILE = \"jmxapplication\" + Storage.DEFAULT_PROPERTIES_EXT;  // NOI18N\n    static final String JMX_SUFFIX = \".jmx\";  // NOI18N\n    \n    private static final String DNSA_KEY = \"JMXApplicationProvider_NotifyUnresolved\"; // NOI18N\n    \n    \n    private volatile boolean trackingNewHosts;\n    private Map<String, Set<Storage>> persistedApplications = new HashMap<>();\n    \n\n    private static boolean isLocalHost(String hostname) throws IOException {\n        InetAddress remoteAddr = InetAddress.getByName(hostname);\n        // Retrieve all the network interfaces on this host.\n        Enumeration<NetworkInterface> nis =\n                NetworkInterface.getNetworkInterfaces();\n        // Walk through the network interfaces to see\n        // if any of them matches the client's address.\n        // If true, then the client's address is local.\n        while (nis.hasMoreElements()) {\n            NetworkInterface ni = nis.nextElement();\n            Enumeration<InetAddress> addrs = ni.getInetAddresses();\n            while (addrs.hasMoreElements()) {\n                InetAddress localAddr = addrs.nextElement();\n                if (localAddr.equals(remoteAddr)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    // Resolves existing host based on hostname, JMXServiceURL\n    // or by using the JMXServiceURL to connect to the agent\n    // and retrieve the hostname information.\n    private Host getHost(String hostname, JMXServiceURL url)\n            throws IOException {\n        // Try to compute the Host instance from hostname\n        if (hostname != null) {\n            if (hostname.isEmpty() || isLocalHost(hostname)) {\n                return Host.LOCALHOST;\n            } else {\n                return HostsSupport.getInstance().getOrCreateHost(hostname, false);\n            }\n        }\n\n        // TODO: Connect to the agent and try to get the hostname.\n        //       app = JmxApplication(Host.UNKNOWN_HOST, url, storage);\n        //       JmxModelFactory.getJmxModelFor(app);\n\n        // WARNING: If a hostname could not be found the JMX application\n        //          is added under the <Unknown Host> tree node.\n        return Host.UNKNOWN_HOST;\n    }\n\n    public static String getConnectionString(JmxApplication application) {\n        return application.getStorage().getCustomProperty(PROPERTY_CONNECTION_STRING);\n    }\n    \n    public static String getSuggestedName(String displayName, String connectionString,\n                                          String username) {\n        // User-provided displayName always first\n        if (displayName != null) return displayName;\n        \n        // Generated name 'connectionString' or 'user@connectionString'\n        if (username == null) username = \"\"; // NOI18N\n        return (username.isEmpty() ? \"\" : username + \"@\") + connectionString; // NOI18N\n    }\n\n    public JmxApplication createJmxApplication(String connectionString, String displayName,\n                                               String suggestedName, EnvironmentProvider provider,\n                                               boolean persistent, boolean allowsInsecure,\n                                               boolean connectImmediately, boolean connectAutomatically)\n                                               throws JmxApplicationException {\n        // Initial check if the provided connectionName can be used for resolving the host/application\n        final String normalizedConnectionName = normalizeConnectionName(connectionString);\n        final JMXServiceURL serviceURL;\n        try {\n            serviceURL = getServiceURL(normalizedConnectionName);\n        } catch (MalformedURLException ex) {\n            throw new JmxApplicationException(NbBundle.getMessage(JmxApplicationProvider.class,\n                                \"MSG_Invalid_JMX_connection\", normalizedConnectionName),ex); // NOI18N\n        }\n\n        String hostName = getHostName(serviceURL);\n        hostName = hostName == null ? \"\" : hostName; // NOI18N\n\n        Storage storage = null;\n\n        if (persistent) {\n            File storageDirectory = Utils.getUniqueFile(JmxApplicationsSupport.getStorageDirectory(),\n                    \"\" + System.currentTimeMillis(), JMX_SUFFIX);    // NOI18N\n            Utils.prepareDirectory(storageDirectory);\n            storage = new Storage(storageDirectory, PROPERTIES_FILE);\n            storage.setCustomProperty(SNAPSHOT_VERSION, CURRENT_SNAPSHOT_VERSION);\n        }\n\n        try {\n            return addJmxApplication(true, serviceURL, normalizedConnectionName,\n                                 displayName, suggestedName, hostName, provider,\n                                 storage, Boolean.toString(allowsInsecure), true,\n                                 connectImmediately, connectAutomatically);\n        } catch (JMXException e) {\n            if (storage != null) {\n                File appStorage = storage.getDirectory();\n                if (appStorage.isDirectory()) Utils.delete(appStorage, true);\n            }\n            throw new JmxApplicationException(e.getMessage(), e.getCause());\n        }\n    }\n    \n    private JmxApplication addJmxApplication(boolean newApp, JMXServiceURL serviceURL,\n            String connectionName, String displayName, String suggestedName, String hostName,\n            EnvironmentProvider provider, Storage storage, String allowsInsecure, boolean lazy,\n            boolean connectImmediately, boolean connectAutomatically) throws JMXException {\n        \n        if (lazy) return addLazyJmxApplication(newApp, serviceURL, connectionName, displayName, suggestedName,\n                                               hostName, provider, storage, allowsInsecure, connectImmediately, connectAutomatically);\n        else throw new RuntimeException(\"Only lazy JMX connections currently implemented!\"); // NOI18N\n    }\n\n    private JmxApplication addLazyJmxApplication(boolean newApp, JMXServiceURL serviceURL, String connectionName,\n            String displayName, String suggestedName, String hostName, EnvironmentProvider provider,\n            Storage storage, String allowsInsecure, boolean connectImmediately, boolean connectAutomatically) throws JMXException {\n\n        // Resolve JMXServiceURL, finish if not resolved\n        if (serviceURL == null) {\n            try {\n                serviceURL = getServiceURL(connectionName);\n            } catch (MalformedURLException ex) {\n                throw new JMXException(true, NbBundle.getMessage(JmxApplicationProvider.class,\n                                    \"MSG_Invalid_JMX_connection\", connectionName), ex); // NOI18N\n            }\n        }\n\n        // Resolve existing Host or create new Host, finish if Host cannot be resolved\n        Set<Host> hosts = DataSourceRepository.sharedInstance().getDataSources(Host.class);\n        Host host = null;\n        try {\n            host = getHost(hostName, serviceURL);\n        } catch (Exception e) {\n            cleanupCreatedHost(hosts, host);\n            throw new JMXException(false, NbBundle.getMessage(JmxApplicationProvider.class,\n                                    \"MSG_Cannot_resolve_host\", hostName), e); // NOI18N\n        }\n\n        // Update persistent storage and EnvironmentProvider\n        if (storage != null) {\n            if (newApp) {\n                storage.setCustomProperty(PROPERTY_HOSTNAME, host.getHostName());\n                if (provider != null) {\n                    storage.setCustomProperty(PROPERTY_ENV_PROVIDER_ID, provider.getId());\n                    provider.saveEnvironment(storage);\n                }\n            } else {\n                if (provider != null) provider.loadEnvironment(storage);\n            }\n        }\n        \n        // Create the JmxApplication\n        final JmxApplication application = new JmxApplication(host, serviceURL, provider, storage);\n        \n        // Update display name and new EnvironmentProvider for non-persistent storage\n        if (newApp) {\n            Storage s = application.getStorage();\n            String[] keys = new String[] {\n                PROPERTY_CONNECTION_STRING,\n                displayName != null ?\n                    DataSourceDescriptor.PROPERTY_NAME :\n                    ApplicationType.PROPERTY_SUGGESTED_NAME\n            };\n\n            String[] values = new String[] {\n                connectionName,\n                displayName != null ?\n                    displayName :\n                    suggestedName\n            };\n\n            s.setCustomProperties(keys, values);\n            if (provider != null) provider.saveEnvironment(s);\n        }\n        \n        // Check if the given JmxApplication has been already added to the application tree\n        final Set<JmxApplication> jmxapps = host.getRepository().getDataSources(JmxApplication.class);\n        if (jmxapps.contains(application)) {\n            JmxApplication tempapp = null;\n            for (JmxApplication jmxapp : jmxapps) {\n                if (jmxapp.equals(application)) {\n                    tempapp = jmxapp;\n                    break;\n                }\n            }\n            cleanupCreatedHost(hosts, host);\n            throw new JMXException(true, NbBundle.getMessage(JmxApplicationProvider.class,\n                                    \"MSG_connection_already_exists\", new Object[] { // NOI18N\n                                    application.getId(), DataSourceDescriptorFactory.\n                                    getDescriptor(tempapp).getName() }));\n        }\n        \n        // Setup whether the SSL connection is required or not\n        application.getStorage().setCustomProperty(PROPERTY_RETRY_WITHOUT_SSL, allowsInsecure);\n        \n        host.getRepository().addDataSource(application);\n        \n        if (!connectAutomatically) application.disableHeartbeat();\n        if (connectImmediately) JmxHeartbeat.scheduleImmediately(application);\n\n        return application;\n    }\n    \n    \n    private void cleanupCreatedHost(Set<Host> hosts, Host host) {\n        // NOTE: this is not absolutely failsafe, if resolving the JMX application\n        // took a long time and its host has been added by the user/plugin, it may\n        // be removed by this call. Hopefully just a hypothetical case...\n        if (host != null && !Host.LOCALHOST.equals(host) && !hosts.contains(host))\n            host.getOwner().getRepository().removeDataSource(host);\n    }\n    \n    private String normalizeConnectionName(String connectionName) {\n        if (connectionName.startsWith(\"service:jmx:\")) return connectionName;   // NOI18N\n        return \"service:jmx:rmi:///jndi/rmi://\" + connectionName + \"/jmxrmi\";   // NOI18N  hostname:port\n    }\n    \n    private String getHostName(JMXServiceURL serviceURL) {\n        // Try to compute the hostname instance\n        // from the host in the JMXServiceURL.\n        String hostname = serviceURL.getHost();\n        if (hostname == null || hostname.isEmpty()) {\n            hostname = null;\n            // Try to compute the Host instance from the JNDI/RMI\n            // Registry Service urlPath in the JMXServiceURL.\n            if (\"rmi\".equals(serviceURL.getProtocol()) &&   // NOI18N\n                    serviceURL.getURLPath().startsWith(\"/jndi/rmi://\")) {   // NOI18N\n                String urlPath =\n                        serviceURL.getURLPath().substring(\"/jndi/rmi://\".length()); // NOI18N\n                if ('/' == urlPath.charAt(0)) { // NOI18N\n                    hostname = \"localhost\"; // NOI18N\n                } else if ('[' == urlPath.charAt(0)) { // IPv6 address  // NOI18N\n                    int closingSquareBracketIndex = urlPath.indexOf(']'); // NOI18N\n                    if (closingSquareBracketIndex == -1) {\n                        hostname = null;\n                    } else {\n                        hostname = urlPath.substring(0, closingSquareBracketIndex + 1);\n                    }\n                } else {\n                    int colonIndex = urlPath.indexOf(':'); // NOI18N\n                    int slashIndex = urlPath.indexOf('/'); // NOI18N\n                    int min = Math.min(colonIndex, slashIndex); // NOTE: can be -1!!!\n                    if (min == -1) {\n                        min = 0;\n                    }\n                    hostname = urlPath.substring(0, min);\n                    if (hostname.isEmpty()) {\n                        hostname = \"localhost\"; // NOI18N\n                    }\n                }\n            }\n        }\n        return hostname;\n    }\n\n    private JMXServiceURL getServiceURL(String connectionString) throws MalformedURLException {\n        return new JMXServiceURL(connectionString);\n    }\n\n    private void initPersistedApplications() {\n        if (!JmxApplicationsSupport.storageDirectoryExists()) return;\n        \n        File[] files = JmxApplicationsSupport.getStorageDirectory().listFiles(\n                new FilenameFilter() {\n                    public boolean accept(File dir, String name) {\n                        return name.endsWith(JMX_SUFFIX);\n                    }\n                });\n        \n        final int[] persistedAppsCount = new int[1];\n        for (File file : files) {\n            if (file.isDirectory()) {\n                persistedAppsCount[0]++;\n                Storage storage = new Storage(file, PROPERTIES_FILE);\n                Set<Storage> storageSet = persistedApplications.get(storage.getCustomProperty(PROPERTY_HOSTNAME));\n                if (storageSet == null) {\n                    storageSet = new HashSet<>();\n                    persistedApplications.put(storage.getCustomProperty(PROPERTY_HOSTNAME), storageSet);\n                }\n                storageSet.add(storage);\n            }\n        }\n        \n        DataChangeListener<Host> dataChangeListener = new DataChangeListener<Host>() {\n\n            public synchronized void dataChanged(DataChangeEvent<Host> event) {\n                final Set<String> failedAppsN = Collections.synchronizedSet(new HashSet<>());\n                final Set<Storage> failedAppsS = Collections.synchronizedSet(new HashSet<>());\n                Set<Host> hosts = event.getAdded();\n                for (Host host : hosts) {\n                    String hostName = host.getHostName();\n                    Set<Storage> storageSet = persistedApplications.get(hostName);\n                    int storageSetSize = storageSet == null ? 0 : storageSet.size();\n                    if (storageSetSize > 0) {\n                        persistedApplications.remove(hostName);\n                        \n                        String[] keys = new String[] {\n                            PROPERTY_CONNECTION_STRING,\n                            PROPERTY_HOSTNAME,\n                            DataSourceDescriptor.PROPERTY_NAME,\n                            ApplicationType.PROPERTY_SUGGESTED_NAME,\n                            PROPERTY_ENV_PROVIDER_ID,\n                            PROPERTY_RETRY_WITHOUT_SSL,\n                            JmxApplication.PROPERTY_DISABLE_HEARTBEAT\n                        };\n                        \n                        final AtomicInteger counter = new AtomicInteger(storageSetSize);\n                        final Collection<JmxApplication> persistentApps = Collections.synchronizedList(new ArrayList<>());\n                        RequestProcessor processor = new RequestProcessor(\"JMX Persistence Processor\", Math.min(storageSetSize, 10)); // NOI18N\n                        \n                        for (final Storage storage : storageSet) {\n                            final String[] values = storage.getCustomProperties(keys);\n                            processor.post(new Runnable() {\n                                public void run() {\n                                    try {\n                                        String epid = values[4];\n                                        if (epid == null) {\n                                            // Check for ver 1.0 which didn't support PROPERTY_ENVIRONMENT_PROVIDER\n                                            String sv = storage.getCustomProperty(SNAPSHOT_VERSION);\n                                            if (\"1.0\".equals(sv)) epid = CredentialsProvider.class.getName(); // NOI18N\n                                        }\n                                        EnvironmentProvider ep = epid == null ? null :\n                                                                 JmxConnectionSupportImpl.\n                                                                 getProvider(epid);\n                                        boolean autoConnect = !Boolean.parseBoolean(values[6]);\n                                        JmxApplication app = addLazyJmxApplication(false, null, values[0], values[2], values[3],\n                                                                                   values[1], ep, storage, values[5], autoConnect, autoConnect);\n                                        if (!app.isHeartbeatDisabled()) persistentApps.add(app);\n                                    } catch (final JMXException e) {\n                                        if (e.isConfig()) {\n                                            DialogDisplayer.getDefault().notifyLater(\n                                                new NotifyDescriptor.Message(e.\n                                                getMessage(), NotifyDescriptor.\n                                                ERROR_MESSAGE));\n                                        } else {\n                                            String name = values[2];\n                                            if (name == null || name.trim().isEmpty()) name = values[3];\n                                            failedAppsN.add(name);\n                                            failedAppsS.add(storage);\n                                        }\n                                    } finally {\n                                        if (counter.decrementAndGet() == 0)\n                                            JmxHeartbeat.scheduleImmediately(persistentApps.toArray(new JmxApplication[0]));\n                                    }\n                                    synchronized (persistedAppsCount) {\n                                        persistedAppsCount[0]--;\n                                        if (persistedAppsCount[0] == 0 && !failedAppsN.isEmpty())\n                                            notifyUnresolvedApplications(failedAppsN, failedAppsS);\n                                    }\n                                }\n                            });\n                        }\n                    }\n                }\n                \n                if (trackingNewHosts && persistedApplications.isEmpty()) {\n                    trackingNewHosts = false;\n                    DataSourceRepository.sharedInstance().removeDataChangeListener(this);\n                }\n            }\n            \n        };\n        \n        if (!persistedApplications.isEmpty()) {\n            trackingNewHosts = true;\n            DataSourceRepository.sharedInstance().addDataChangeListener(dataChangeListener, Host.class);\n        }\n    }\n    \n    private static void notifyUnresolvedApplications(final Set<String> failedHostsN, final Set<Storage> failedHostsS) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                String s = GlobalPreferences.sharedInstance().getDoNotShowAgain(DNSA_KEY);\n                Boolean b = s == null ? null : Boolean.parseBoolean(s);\n                \n                if (b == null) {\n                    JPanel messagePanel = new JPanel(new BorderLayout(5, 5));\n                    messagePanel.add(new JLabel(NbBundle.getMessage(JmxApplicationProvider.class, \"MSG_Unresolved_JMX\")), BorderLayout.NORTH); // NOI18N\n                    JList<Object> list = new JList<>(failedHostsN.toArray());\n                    list.setVisibleRowCount(4);\n                    messagePanel.add(new JScrollPane(list), BorderLayout.CENTER);\n                    JCheckBox dnsa = new JCheckBox();\n                    Mnemonics.setLocalizedText(dnsa, NbBundle.getMessage(JmxApplicationProvider.class, \"LBL_RememberAction\")); // NOI18N\n                    dnsa.setToolTipText(NbBundle.getMessage(JmxApplicationProvider.class, \"TTP_RememberAction\", VisualVM.getInstance().getOptionsHandle())); // NOI18N\n                    JPanel p = new JPanel(new BorderLayout());\n                    p.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 20));\n                    p.add(dnsa, BorderLayout.WEST);\n                    messagePanel.add(p, BorderLayout.SOUTH);\n                    NotifyDescriptor dd = new NotifyDescriptor(\n                            messagePanel, NbBundle.getMessage(JmxApplicationProvider.class, \"Title_Unresolved_JMX\"), // NOI18N\n                            NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.ERROR_MESSAGE,\n                            null, NotifyDescriptor.YES_OPTION);\n                    Object ret = DialogDisplayer.getDefault().notify(dd);\n                    \n                    if (ret == NotifyDescriptor.NO_OPTION) b = Boolean.FALSE;\n                    else if (ret == NotifyDescriptor.YES_OPTION) b = Boolean.TRUE;\n                    \n                    if (dnsa.isSelected() && b != null) GlobalPreferences.sharedInstance().setDoNotShowAgain(DNSA_KEY, b.toString());\n                }\n                \n                if (Boolean.FALSE.equals(b))\n                    for (Storage storage : failedHostsS) {\n                        File appStorage = storage.getDirectory();\n                        if (appStorage.isDirectory()) Utils.delete(appStorage, true);\n                    }\n\n                failedHostsS.clear();\n            }\n        }, 1000);\n    }\n\n    public void initialize() {\n        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {\n            public void run() {\n                VisualVM.getInstance().runTask(new Runnable() {\n                    public void run() {\n                        initPersistedApplications();\n                    }\n                });\n            }\n        });\n    }\n    \n    \n    private static class JMXException extends Exception {\n        private final boolean isConfig;\n        JMXException(boolean config, String message) { super(message); isConfig = config; }\n        JMXException(boolean config, String message, Throwable cause) { super(message,cause); isConfig = config; }\n        public boolean isConfig() { return isConfig; }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxConnectionConfigurator.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.Frame;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.Window;\nimport java.awt.event.MouseEvent;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultListModel;\nimport javax.swing.DefaultListSelectionModel;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.ListCellRenderer;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.border.Border;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport org.graalvm.visualvm.core.properties.PropertiesPanel;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.jmx.JmxConnectionCustomizer;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JmxConnectionConfigurator extends JPanel {\n\n    static Result getResult() {\n        JmxConnectionConfigurator configurator = instance();\n        configurator.warmup();\n\n        final DialogDescriptor dd = new DialogDescriptor(configurator,\n                NbBundle.getMessage(JmxConnectionConfigurator.class, \"Title_Add_JMX_Connection\"),   // NOI18N\n                true, new Object[] { configurator.okButton, DialogDescriptor.CANCEL_OPTION},\n                configurator.okButton, 0, null, null);\n        dd.setAdditionalOptions(new Object[] { configurator.hintLabel });\n        final Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n        configurator.updateWindowTitle(d);\n        d.pack();\n        d.setVisible(true);\n\n        Result result = configurator.get(dd.getValue() == configurator.okButton);\n        configurator.cleanup();\n\n        return result;\n    }\n\n\n\n    public static synchronized JmxConnectionConfigurator instance() {\n        if (INSTANCE == null) INSTANCE = new JmxConnectionConfigurator();\n        return INSTANCE;\n    }\n\n\n    public void warmup() {\n        // Resolve customizers\n        customizers.addAll(JmxConnectionSupportImpl.getCustomizers());\n        singleCustomizer = customizers.size() == 1;\n\n        // Populate list, initialize panels\n        JmxConnectionCustomizer itemToSelect = null;\n        for (JmxConnectionCustomizer customizer : customizers) {\n            connectionTypeListModel.addElement(customizer);\n            customizerPanels.add(customizer.createPanel(null));\n            if (customizer.toString().equals(lastSelectedItem))\n                itemToSelect = customizer;\n        }\n\n        // Update selector visibility\n        boolean selectorVisible = customizers.size() > 1;\n        connectionTypeLabel.setVisible(selectorVisible);\n        connectionTypeScroll.setVisible(selectorVisible);\n        customizerPanelScroll.setBorder(selectorVisible ?\n            BorderFactory.createEmptyBorder(5, 8, 0, 5) :\n            BorderFactory.createEmptyBorder(15, 5, 0, 5));\n\n        // Register selection listener\n        connectionTypeList.addListSelectionListener(selectionListener);\n\n        // Restore previously selected item\n        if (itemToSelect == null) connectionTypeList.setSelectedIndex(0);\n        else connectionTypeList.setSelectedValue(itemToSelect, true);\n\n        // Update OK button state\n        updateOkButton();\n\n        // Restore previous dialog size\n        if (lastSize != null) customizerPanelScroll.setPreferredSize(lastSize);\n        else initializePreferredSize();\n    }\n\n    public Result get(boolean accepted) {\n        JmxConnectionCustomizer.Setup setup = null;\n        if (accepted && selectedCustomizer != null && displayedPanel != null)\n            setup = selectedCustomizer.getConnectionSetup(displayedPanel);\n        return new Result(setup, selectedCustomizer, customizers, customizerPanels);\n    }\n\n    public void cleanup() {\n        // Save last selected item\n        Object selectedItem = connectionTypeList.getSelectedValue();\n        lastSelectedItem = selectedItem == null ? null : selectedItem.toString();\n\n        // Unregister selection listener\n        connectionTypeList.clearSelection();\n        connectionTypeList.removeListSelectionListener(selectionListener);\n\n        // Save dialog size\n        lastSize = customizerPanelScroll.getSize();\n\n        // Clear state\n        customizers.clear();\n        customizerPanels.clear();\n        customizerPanel.removeAll();\n        connectionTypeListModel.clear();\n        selectedCustomizer = null;\n    }\n\n    public void updateWindowTitle(Window w) {\n        if (singleCustomizer) return;\n        String title = NbBundle.getMessage(JmxConnectionConfigurator.class,\n                \"Title_Add_JMX_Connection\") + \" - \" + // NOI18N\n                selectedCustomizer.getPropertiesName();\n        if (w instanceof Dialog) ((Dialog)w).setTitle(title);\n        else if (w instanceof Frame) ((Frame)w).setTitle(title);\n    }\n\n\n    private void updateSelectedCustomizer() {\n        selectedCustomizer = connectionTypeList.getSelectedValue();\n        if (displayedPanel != null) {\n            displayedPanel.removeChangeListener(validityListener);\n            customizerPanel.removeAll();\n        }\n        if (selectedCustomizer != null) {\n            displayedPanel = customizerPanels.get(connectionTypeListModel.\n                                                  indexOf(selectedCustomizer));\n            updateWindowTitle(SwingUtilities.getWindowAncestor(this));\n        }\n        if (displayedPanel != null) {\n            displayedPanel.addChangeListener(validityListener);\n            customizerPanel.add(displayedPanel, BorderLayout.CENTER);\n            customizerPanel.revalidate();\n            customizerPanel.repaint();\n            updateOkButton();\n        }\n    }\n\n    private void updateOkButton() {\n        okButton.setEnabled(displayedPanel != null && displayedPanel.settingsValid());\n    }\n\n    private void updateHint() {\n        String hintText = selectedCustomizer == null ? null :\n                          selectedCustomizer.getPropertiesDescription();\n        if (hintText != null && !singleCustomizer) {\n            hintLabel.setIcon(INFO_ICON);\n            hintLabel.setText(hintText);\n        } else {\n            hintLabel.setIcon(null);\n            hintLabel.setText(\"\"); // NOI18N\n        }\n    }\n\n    private void initializePreferredSize() {\n        Dimension preferredSize = new Dimension();\n        for (PropertiesPanel panel : customizerPanels) {\n            Dimension panelPref = panel.getPreferredSize();\n            preferredSize.width = Math.max(preferredSize.width, panelPref.width);\n            preferredSize.height = Math.max(preferredSize.height, panelPref.height);\n        }\n        Insets insets = customizerPanelScroll.getInsets();\n        preferredSize.width += insets.left + insets.right;\n        preferredSize.height += insets.top + insets.bottom;\n        if (!singleCustomizer) preferredSize.height += 40; // Extra bottom space\n        customizerPanelScroll.setPreferredSize(preferredSize);\n    }\n\n    private JmxConnectionCustomizer getCustomizer(Point location) {\n        int index = connectionTypeList.locationToIndex(location);\n        if (index == -1) return null;\n        if (!connectionTypeList.getCellBounds(index, index).contains(location))\n            return null;\n        return connectionTypeListModel.getElementAt(index);\n    }\n\n\n    private class SelectionListener implements ListSelectionListener {\n        public void valueChanged(ListSelectionEvent e) {\n            if (!e.getValueIsAdjusting()) {\n                updateSelectedCustomizer();\n                updateHint();\n            }\n        }\n    }\n\n    private class ValidityListener implements ChangeListener {\n        public void stateChanged(ChangeEvent e) {\n            updateOkButton();\n        }\n    }\n\n\n    private void initComponents() {\n        okButton = new JButton(NbBundle.getMessage(JmxConnectionConfigurator.class, \"LBL_OK\"));    // NOI18N\n\n        hintLabel = new JLabel(\"\") { // NOI18N\n            public Dimension getPreferredSize() {\n                Dimension d = super.getPreferredSize();\n                d.height = Math.max(d.height, okButton.getPreferredSize().height);\n                return d;\n            }\n        };\n        hintLabel.setForeground(UIManager.getColor(\"Label.disabledForeground\")); // NOI18N\n\n        setLayout(new BorderLayout());\n\n        connectionTypeLabel = new JLabel();\n        Mnemonics.setLocalizedText(connectionTypeLabel,\n                NbBundle.getMessage(JmxConnectionConfigurator.class, \"LBL_Connection_type\")); // NOI18N\n        createBorder(connectionTypeLabel, BorderFactory.createEmptyBorder(15, 10, 0, 10));\n        add(connectionTypeLabel, BorderLayout.NORTH);\n\n        connectionTypeListModel = new DefaultListModel<>();\n        connectionTypeList = new JList<JmxConnectionCustomizer>(connectionTypeListModel) {\n            public String getToolTipText(MouseEvent evt) {\n                JmxConnectionCustomizer cust = getCustomizer(evt.getPoint());\n                return cust == null ? null : cust.getPropertiesDescription();\n            }\n\n        };\n        connectionTypeLabel.setLabelFor(connectionTypeList);\n        connectionTypeList.setSelectionModel(new DefaultListSelectionModel() {\n            public void removeSelectionInterval(int i1, int i2) {}\n        });\n        connectionTypeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        final ListCellRenderer defaultRenderer = connectionTypeList.getCellRenderer();\n        Component c = defaultRenderer.getListCellRendererComponent(connectionTypeList, \"X\", 0, false, false); // NOI18N\n        connectionTypeList.setFixedCellHeight(c.getPreferredSize().height + 2);\n        connectionTypeList.setCellRenderer(new ListCellRenderer() {\n            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {\n                return defaultRenderer.getListCellRendererComponent(list, \" \" + value + \" \", index, isSelected, cellHasFocus); // NOI18N\n            }\n        });\n        connectionTypeScroll = new JScrollPane(connectionTypeList,\n                                    JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                                    JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) {\n            public Dimension getPreferredSize() {\n                Dimension preferredSize = super.getPreferredSize();\n                preferredSize.width = Math.min(preferredSize.width, 300);\n                preferredSize.width = Math.max(preferredSize.width, 120);\n                return preferredSize;\n            }\n        };\n        createBorder(connectionTypeScroll, BorderFactory.createEmptyBorder(5, 10, 0, 0));\n        add(connectionTypeScroll, BorderLayout.WEST);\n\n        customizerPanel = new JPanel(new BorderLayout());\n        customizerPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));\n        customizerPanelScroll = new ScrollableContainer(customizerPanel,\n                ScrollableContainer.VERTICAL_SCROLLBAR_AS_NEEDED,\n                ScrollableContainer.HORIZONTAL_SCROLLBAR_NEVER);\n        customizerPanelScroll.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 5));\n        add(customizerPanelScroll, BorderLayout.CENTER);\n    }\n\n    private static void createBorder(JComponent component, Border border) {\n        Border cBorder = component.getBorder();\n        if (cBorder == null) component.setBorder(border);\n        else component.setBorder(BorderFactory.createCompoundBorder(border, cBorder));\n    }\n    \n\n    private JmxConnectionConfigurator() {\n        initComponents();\n    }\n\n\n    private static final Icon INFO_ICON =\n            ImageUtilities.loadImageIcon(\"org/graalvm/visualvm/jmx/resources/infoIcon.png\", // NOI18N\n            false);\n\n\n    private boolean singleCustomizer;\n\n    private JmxConnectionCustomizer selectedCustomizer;\n    private PropertiesPanel displayedPanel;\n    private List<JmxConnectionCustomizer> customizers = new ArrayList<>();\n    private List<PropertiesPanel> customizerPanels = new ArrayList<>();\n\n    private SelectionListener selectionListener = new SelectionListener();\n    private ValidityListener validityListener = new ValidityListener();\n\n    private String lastSelectedItem;\n    private Dimension lastSize;\n\n    private DefaultListModel<JmxConnectionCustomizer> connectionTypeListModel;\n\n    private JButton okButton;\n    private JLabel hintLabel;\n\n    private JLabel connectionTypeLabel;\n    private JList<JmxConnectionCustomizer> connectionTypeList;\n    private JScrollPane connectionTypeScroll;\n    private JPanel customizerPanel;\n    private ScrollableContainer customizerPanelScroll;\n\n    private static JmxConnectionConfigurator INSTANCE;\n\n\n    public static final class Result {\n\n        private final JmxConnectionCustomizer.Setup setup;\n        private final JmxConnectionCustomizer selectedCustomizer;\n        private final List<JmxConnectionCustomizer> customizers = new ArrayList<>();\n        private final List<PropertiesPanel> customizerPanels = new ArrayList<>();\n\n\n        public Result(JmxConnectionCustomizer.Setup setup,\n                      JmxConnectionCustomizer selectedCustomizer,\n                      List<JmxConnectionCustomizer> customizers,\n                      List<PropertiesPanel> customizerPanels) {\n            this.setup = setup;\n            this.selectedCustomizer = selectedCustomizer;\n            this.customizers.addAll(customizers);\n            this.customizerPanels.addAll(customizerPanels);\n        }\n\n\n        public JmxConnectionCustomizer.Setup getSetup() { return setup; }\n\n        public void accepted(JmxApplication application) {\n            for (int i = 0; i < customizers.size(); i++) {\n                JmxConnectionCustomizer c = customizers.get(i);\n                if (c == selectedCustomizer) {\n                    JmxPropertiesProvider.setCustomizer(application, selectedCustomizer);\n                    c.propertiesDefined(customizerPanels.get(i), application);\n                } else {\n                    customizers.get(i).propertiesCancelled(customizerPanels.get(i), null);\n                }\n            }\n        }\n\n        public void cancelled() {\n            for (int i = 0; i < customizers.size(); i++)\n                customizers.get(i).propertiesCancelled(customizerPanels.get(i), null);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxConnectionSupportImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.jmx.EnvironmentProvider;\nimport org.graalvm.visualvm.jmx.JmxConnectionCustomizer;\n\npublic final class JmxConnectionSupportImpl {\n\n    private static final Map<String, EnvironmentProvider> providers =\n            Collections.synchronizedMap(new HashMap<>());\n\n    private static final Map<String, JmxConnectionCustomizer> customizers =\n            Collections.synchronizedMap(new HashMap<>());\n\n    private static JmxConnectionCustomizer defaultCustomizer;\n    private static boolean defaultHidden = false;\n\n\n    // --- EnvironmentProvider stuff -------------------------------------------\n\n    public static void registerProviderImpl(EnvironmentProvider provider) {\n        String providerId = provider.getId();\n        if (providers.containsKey(providerId))\n            throw new UnsupportedOperationException(\"Provider with id '\" + providerId + // NOI18N\n                                                    \"' already registered\"); // NOI18N\n        providers.put(providerId, provider);\n    }\n\n    public static void unregisterProviderImpl(EnvironmentProvider provider) {\n        providers.remove(provider.getId());\n    }\n\n    public static EnvironmentProvider getProvider(String providerId) {\n        return providers.get(providerId);\n    }\n\n\n    // --- JmxConnectionCustomizer stuff ---------------------------------------\n\n    public static void registerCustomizer(JmxConnectionCustomizer customizer) {\n        String customizerId = customizer.getId();\n        if (customizers.containsKey(customizerId))\n            throw new UnsupportedOperationException(\"Customizer with id '\" + customizerId + // NOI18N\n                                                    \"' already registered\"); // NOI18N\n        customizers.put(customizerId, customizer);\n        defaultHidden = defaultHidden || customizer.hidesDefault();\n    }\n\n    public static void unregisterCustomizer(JmxConnectionCustomizer customizer) {\n        customizers.remove(customizer.getId());\n        if (customizer.hidesDefault()) updateDefaultHidden();\n    }\n\n    public static JmxConnectionCustomizer getCustomizer(String customizerId) {\n        return customizers.get(customizerId);\n    }\n\n    public static List<JmxConnectionCustomizer> getCustomizers() {\n        List<JmxConnectionCustomizer> list = customizers();\n        if (defaultHidden && defaultCustomizer != null)\n            list.remove(defaultCustomizer);\n        list.sort(Positionable.COMPARATOR);\n        return list;\n    }\n\n    public static void setDefaultCustomizer(JmxConnectionCustomizer customizer) {\n        if (defaultCustomizer != null)\n            throw new UnsupportedOperationException(\"Default customizer already set\"); // NOI18N\n        defaultCustomizer = customizer;\n    }\n    \n    static JmxConnectionCustomizer getDefaultCustomizer() {\n        return defaultCustomizer;\n    }\n\n\n    private static List<JmxConnectionCustomizer> customizers() {\n        List<JmxConnectionCustomizer> list = new ArrayList<>();\n        synchronized(customizers) { list.addAll(customizers.values()); }\n        return list;\n    }\n\n    private static void updateDefaultHidden() {\n        boolean newDefaultHidden = false;\n        List<JmxConnectionCustomizer> list = customizers();\n        for (JmxConnectionCustomizer customizer : list)\n            if (customizer.hidesDefault()) {\n                newDefaultHidden = true;\n                break;\n            }\n        defaultHidden = newDefaultHidden;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxHeartbeat.java",
    "content": "/*\n * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class JmxHeartbeat {\n    \n    private static final int MAX_HEARTBEAT_THREADS = Integer.getInteger(\"org.graalvm.visualvm.jmx.JmxHeartbeatThreads\", 10); // NOI18N\n    \n    private static final int LAZY_HEARTBEAT_DELAY = Integer.getInteger(\"org.graalvm.visualvm.jmx.HeartbeatDelay\", 5000); // NOI18N\n    private static final int IMMEDIATE_HEARTBEAT_DELAY = Integer.getInteger(\"org.graalvm.visualvm.jmx.ImmediateHeartbeatDelay\", 100); // NOI18N\n    \n    \n    private static final JmxHeartbeat LAZY = new Lazy();\n    private static final JmxHeartbeat IMMEDIATE = new Immediate(LAZY);\n        \n        \n    private final String id;\n    private final int delay;\n\n\n    private JmxHeartbeat(String id, int delay) {\n        this.id = id;\n        this.delay = delay;\n    }\n    \n    \n    static void scheduleImmediately(JmxApplication... apps) {\n        IMMEDIATE.schedule(apps);\n    }\n    \n    static void scheduleLazily(JmxApplication... apps) {\n        LAZY.schedule(apps);\n    }\n\n\n    protected abstract void schedule(JmxApplication... apps);\n    \n    protected abstract void pingFinished(JmxApplication... unresolved);\n\n\n    protected final void pingApps(Collection<JmxApplication> applications) {\n        int count = applications.size();\n        \n//        System.err.println(\">>> \" + id + \" Heartbeat for \" + count + \" targets at \" + java.time.LocalTime.now() + \": \" + applications);\n        \n        final AtomicInteger counter = new AtomicInteger(count);\n        final Collection<JmxApplication> unresolved = Collections.synchronizedList(new ArrayList<>());\n        RequestProcessor processor = new RequestProcessor(\"JMX \" + id + \" Heartbeat Processor\", Math.min(count, MAX_HEARTBEAT_THREADS)); // NOI18N\n        \n        for (final JmxApplication app : applications) {\n            processor.post(new Runnable() {\n                @Override\n                public void run() {\n                    try {\n                        if (!app.tryConnect()) unresolved.add(app);\n                    } finally {\n                        if (counter.decrementAndGet() == 0) pingFinished(unresolved.toArray(new JmxApplication[0]));\n                    }\n                }\n            }, delay);\n        }\n    }\n\n\n    protected static void cleanupUnavailableApps(Collection<JmxApplication> apps, boolean checkHeartbeat) {\n        Iterator<JmxApplication> appsI = apps.iterator();\n        while (appsI.hasNext()) {\n            JmxApplication app = appsI.next();\n            if (app.isRemoved() || app.getState() == Stateful.STATE_AVAILABLE) appsI.remove();\n            else if (checkHeartbeat && app.isHeartbeatDisabled()) appsI.remove();\n        }\n    }\n    \n    \n    private static final class Lazy extends JmxHeartbeat {\n        \n        private final Collection<JmxApplication> unavailable = new HashSet<>();\n    \n        private boolean heartbeatRunning;\n        \n        \n        private Lazy() {\n            super(\"Lazy\", LAZY_HEARTBEAT_DELAY); // NOI18N\n        }\n\n        \n        @Override\n        protected void schedule(JmxApplication... apps) {\n            Collection<JmxApplication> toPing;\n            \n            synchronized (unavailable) {\n                cleanupUnavailableApps(unavailable, true);\n                if (apps != null && apps.length > 0) unavailable.addAll(Arrays.asList(apps));\n                \n                if (heartbeatRunning || unavailable.isEmpty()) return;\n                \n                heartbeatRunning = true;\n                \n                toPing = new ArrayList<>(unavailable);\n                unavailable.clear();\n            }\n            \n            pingApps(toPing);\n        }\n        \n        @Override\n        protected void pingFinished(JmxApplication... apps) {\n            boolean pendingUnavailable;\n\n            synchronized (unavailable) {\n                if (apps.length > 0) unavailable.addAll(Arrays.asList(apps));\n                cleanupUnavailableApps(unavailable, true);\n                pendingUnavailable = !unavailable.isEmpty();\n                heartbeatRunning = false;\n            }\n\n            if (pendingUnavailable) schedule();\n        }\n        \n    }\n    \n    \n    private static final class Immediate extends JmxHeartbeat {\n        \n        private final JmxHeartbeat fallback;\n        \n        \n        private Immediate(JmxHeartbeat fallback) {\n            super(\"Immediate\", IMMEDIATE_HEARTBEAT_DELAY); // NOI18N\n            \n            this.fallback = fallback;\n        }\n        \n\n        @Override\n        protected void schedule(JmxApplication... apps) {\n            if (apps == null || apps.length == 0) return;\n            \n            Collection<JmxApplication> unavailableApps = new ArrayList<>(Arrays.asList(apps));\n            cleanupUnavailableApps(unavailableApps, false);\n            if (unavailableApps.isEmpty()) return;\n            \n            pingApps(unavailableApps);\n        }\n        \n        @Override\n        protected void pingFinished(JmxApplication... apps) {\n            if (apps.length > 0) fallback.schedule(apps);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxModelImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport com.sun.tools.attach.AgentInitializationException;\nimport com.sun.tools.attach.AgentLoadException;\nimport com.sun.tools.attach.AttachNotSupportedException;\nimport com.sun.tools.attach.VirtualMachine;\nimport java.awt.EventQueue;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Proxy;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.StringTokenizer;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.TimeoutException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.MBeanServerConnection;\nimport javax.management.remote.JMXServiceURL;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.tools.attach.AttachModelFactory;\nimport org.graalvm.visualvm.tools.jmx.CachedMBeanServerConnection;\nimport org.graalvm.visualvm.tools.jmx.CachedMBeanServerConnectionFactory;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeansFactory;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.openide.util.Utilities;\n\n/**\n * This class encapsulates the JMX functionality of the target Java application.\n *\n * Call {@link JmxModelFactory#getJmxModelFor(Application)} to get an instance of the\n * {@link JmxModel} class.\n *\n * Usually this class will be used as follows:\n *\n * <pre>\n * JmxModel jmx = JmxModelFactory.getJmxModelFor(application);\n * MBeanServerConnection mbsc = jmx.getMBeanServerConnection();\n * if (mbsc != null) {\n *    // Invoke JMX operations...\n * }\n * </pre>\n *\n * Several factory methods are available in {@link CachedMBeanServerConnectionFactory}\n * that can be used to work with a {@link CachedMBeanServerConnection} instead of a\n * plain {@link MBeanServerConnection}.\n *\n * In case the JMX connection is not established yet, you could register\n * a listener on the {@code JmxModel} for ConnectionState property changes.\n * The JmxModel notifies any PropertyChangeListeners about the ConnectionState\n * property change to CONNECTED and DISCONNECTED. The JmxModel instance will\n * be the source for any generated events.\n *\n * Polling for the ConnectionState is also possible by calling\n * {@link JmxModel#getConnectionState()}.\n *\n * @author Luis-Miguel Alventosa\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nclass JmxModelImpl extends JmxModel {\n//    private static final String PROPERTY_USERNAME = \"prop_username\";    // NOI18N\n//    private static final String PROPERTY_PASSWORD = \"prop_password\";    // NOI18N\n    private final static Logger LOGGER = Logger.getLogger(JmxModelImpl.class.getName());\n    private ProxyClient client;\n    private ApplicationRemovedListener removedListener;\n    private ApplicationAvailabilityListener availabilityListener;\n    private JmxSupport jmxSupport;\n    private final Object jmxSupportLock = new Object();\n    private JvmMXBeans mxbeans;\n    private final Object mxbeansLock = new Object();\n    \n    /**\n     * Creates an instance of {@code JmxModel} for a {@link JvmstatApplication}.\n     *\n     * @param application the {@link JvmstatApplication}.\n     */\n    JmxModelImpl(Application application, JvmstatModel jvmstat) {\n        try {\n            JvmJvmstatModel jvmstatModel = JvmJvmstatModelFactory.getJvmstatModelFor(application);\n            // Create ProxyClient (i.e. create the JMX connection to the JMX agent)\n            ProxyClient proxyClient = null;\n            if (Application.CURRENT_APPLICATION.equals(application)) {\n                // Monitor self\n                proxyClient = new ProxyClient(application);\n            } else if (application.isLocalApplication()) {\n                // Create a ProxyClient from local pid\n                String connectorAddress = jvmstat.findByName(\"sun.management.JMXConnectorServer.address\"); // NOI18N\n                String javaHome = jvmstat.findByName(\"java.property.java.home\");    // NOI18N\n                LocalVirtualMachine lvm = new LocalVirtualMachine(application.getPid(), AttachModelFactory.getAttachFor(application) != null, connectorAddress, javaHome);\n                if (!lvm.isManageable()) {\n                    if (lvm.isAttachable()) {\n                        proxyClient = new ProxyClient(application, lvm);\n                    } else {\n                        if (LOGGER.isLoggable(Level.WARNING)) {\n                            LOGGER.warning(\"The JMX management agent \" +    // NOI18N\n                                    \"cannot be enabled in this application (pid \" + // NOI18N\n                                    application.getPid() + \")\");  // NOI18N\n                        }\n                    }\n                } else {\n                    proxyClient = new ProxyClient(application, lvm);\n                }\n            }\n            if (proxyClient == null) {\n                // Create a ProxyClient for the remote out-of-the-box\n                // JMX management agent using the port and security\n                // related information retrieved through jvmstat.\n                List<String> urls = jvmstat.findByPattern(\"sun.management.JMXConnectorServer.[0-9]+.remoteAddress\"); // NOI18N\n                if (!urls.isEmpty()) {\n                    List<String> auths = jvmstat.findByPattern(\"sun.management.JMXConnectorServer.[0-9]+.authenticate\"); // NOI18N\n                    proxyClient = new ProxyClient(application, urls.get(0));\n                    if (\"true\".equals(auths.get(0))) {  // NOI18N\n                        proxyClient.supplyCredentials();\n                    }\n                } else {\n                    // Create a ProxyClient for the remote out-of-the-box\n                    // JMX management agent using the port specified in\n                    // the -Dcom.sun.management.jmxremote.port=<port>\n                    // system property\n                    String jvmArgs = jvmstatModel.getJvmArgs();\n                    StringTokenizer st = new StringTokenizer(jvmArgs);\n                    int port = -1;\n                    boolean authenticate = false;\n                    while (st.hasMoreTokens()) {\n                        String token = st.nextToken();\n                        if (token.startsWith(\"-Dcom.sun.management.jmxremote.port=\")) { // NOI18N\n                            port = Integer.parseInt(token.substring(token.indexOf('=') + 1)); // NOI18N\n                        } else if (token.equals(\"-Dcom.sun.management.jmxremote.authenticate=true\")) { // NOI18N\n                            authenticate = true;\n                        }\n                    }\n                    if (port != -1) {\n                        proxyClient = new ProxyClient(application, port);\n                        if (authenticate) {\n                            proxyClient.supplyCredentials();\n                        }\n                    }\n                }\n            }\n            if (proxyClient != null) {\n                client = proxyClient;\n                removedListener = new ApplicationRemovedListener();\n                availabilityListener = new ApplicationAvailabilityListener();\n                proxyClient.connect();\n                proxyClient.addConnectionStateListener(new PropertyChangeListener() {\n                    @Override\n                    public void propertyChange(PropertyChangeEvent evt) {\n                       propertyChangeSupport.firePropertyChange(CONNECTION_STATE_PROPERTY,\n                               evt.getOldValue(), evt.getNewValue());\n                    }\n                });\n                application.notifyWhenRemoved(removedListener);\n                if (getConnectionState() == JmxModel.ConnectionState.CONNECTED) {\n                    application.addPropertyChangeListener(Stateful.PROPERTY_STATE, availabilityListener);\n                }\n\n            }\n        } catch (Exception e) {\n//            LOGGER.throwing(JmxModelImpl.class.getName(), \"<init>\", e); // NOI18N\n            LOGGER.log(Level.INFO, \"Failed to create JmxModelImpl\", e); // NOI18N\n            client = null;\n        }\n    }\n\n    /**\n     * Creates an instance of {@code JmxModel} for a {@link JmxApplication}.\n     *\n     * @param application the {@link JmxApplication}.\n     */\n    JmxModelImpl(JmxApplication application) {\n        try {\n            client = application.getProxyClient();\n            removedListener = new ApplicationRemovedListener();\n            availabilityListener = new ApplicationAvailabilityListener();\n            if (client == null) {\n                client = new ProxyClient(application);\n                client.connect();\n            }\n            client.addConnectionStateListener(new PropertyChangeListener() {\n                @Override\n                public void propertyChange(PropertyChangeEvent evt) {\n                   propertyChangeSupport.firePropertyChange(CONNECTION_STATE_PROPERTY,\n                           evt.getOldValue(), evt.getNewValue());\n                }\n            });\n            application.notifyWhenRemoved(removedListener);\n            if (getConnectionState() == JmxModel.ConnectionState.CONNECTED) {\n                application.addPropertyChangeListener(Stateful.PROPERTY_STATE, availabilityListener);\n            }\n        } catch (Exception e) {\n//            LOGGER.throwing(JmxModelImpl.class.getName(), \"<init>\", e); // NOI18N\n            LOGGER.log(Level.INFO, \"Failed to create JmxModelImpl\", e); // NOI18N\n            client = null;\n        }\n    }\n\n    /**\n     * Returns the current connection state.\n     *\n     * @return the current connection state.\n     */\n    public ConnectionState getConnectionState() {\n        if (client != null) {\n            return client.getConnectionState();\n        }\n        return ConnectionState.DISCONNECTED;\n    }\n\n    /**\n     * Returns the {@link MBeanServerConnection} for the connection to\n     * an application. The returned {@code MBeanServerConnection} object\n     * becomes invalid when the connection state is changed to the\n     * {@link ConnectionState#DISCONNECTED DISCONNECTED} state.\n     *\n     * @return the {@code MBeanServerConnection} for the\n     * connection to an application. It returns {@code null}\n     * if the JMX connection couldn't be established.\n     */\n    public MBeanServerConnection getMBeanServerConnection() {\n        if (client != null) {\n            return client.getMBeanServerConnection();\n        }\n        return null;\n    }\n\n    /**\n     * <p>Method for obtaining the {@link JvmMXBeans} for\n     * the given {@link JmxModel}.</p>\n     *\n     * @return a {@link JvmMXBeans} instance containing the MXBean\n     * proxies for the Java platform MXBeans backed by the supplied\n     * {@link JmxModel}. No MBean caching is applied on the supplied\n     * {@link JmxModel}.\n     */\n    public JvmMXBeans getJvmMXBeans() {\n        synchronized (mxbeansLock) {\n            if (mxbeans == null) {\n                mxbeans = JvmMXBeansFactory.getJvmMXBeans(this);\n            }\n            return mxbeans;\n        }\n    }\n\n    /**\n     * Returns the {@link JMXServiceURL} associated to this {@code JmxModel}.\n     *\n     * @return the {@link JMXServiceURL} associated to this {@code JmxModel}.\n     */\n    public JMXServiceURL getJMXServiceURL() {\n        if (client != null) {\n            return client.getUrl();\n        }\n        return null;        \n    }\n\n    public Properties getSystemProperties() {\n        return getJmxSupport().getSystemProperties();\n    }\n\n    public boolean takeHeapDump(String fileName) {\n        return getJmxSupport().takeHeapDump(fileName);\n    }\n\n    public String takeThreadDump() {\n        return getJmxSupport().takeThreadDump();\n    }\n\n    public String takeThreadDump(long[] threadIds) {\n        return getJmxSupport().takeThreadDump(threadIds);\n    }    \n\n    public HeapHistogram takeHeapHistogram() {\n        return getJmxSupport().takeHeapHistogram();\n    }\n\n    public String getFlagValue(String name) {\n        return getJmxSupport().getFlagValue(name);\n    }\n\n    public void setFlagValue(String name, String value) {\n        getJmxSupport().setFlagValue(name,value);\n    }\n\n    public boolean isTakeHeapDumpSupported() {\n        JmxSupport support = getJmxSupport();\n        return support.getHotSpotDiagnostic() != null && !support.isReadOnlyConnection();\n    }\n    \n    public boolean isTakeThreadDumpSupported() {\n        JmxSupport support = getJmxSupport();\n        return support.getThreadBean() != null && !support.isReadOnlyConnection();\n    }\n\n    public String executeJCmd(String command, Map<String,Object> pars) {\n        JmxSupport support = getJmxSupport();\n        if (support.isReadOnlyConnection()) {\n            return null;\n        }\n        return support.executeJCmd(command, pars);\n    }\n\n    public String getCommandLine() {\n        JmxSupport support = getJmxSupport();\n        if (support.isReadOnlyConnection()) {\n            return null;\n        }\n        return support.getCommandLine();\n    }\n\n    private JmxSupport getJmxSupport() {\n        synchronized (jmxSupportLock) {\n            if (jmxSupport == null) {\n                jmxSupport = new JmxSupport(this);\n            }\n            return jmxSupport;\n        }\n    }\n\n    /**\n     * Disconnect from JMX agent when the application is removed.\n     */\n    private class ApplicationRemovedListener implements DataRemovedListener<Application> {\n\n        public void dataRemoved(Application application) {\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    client.markAsDead();\n                    removedListener = null;\n                }\n            });\n        }\n    }\n    \n    private class ApplicationAvailabilityListener implements PropertyChangeListener {\n\n        public void propertyChange(PropertyChangeEvent evt) {\n            if (!evt.getNewValue().equals(Stateful.STATE_AVAILABLE)) {\n                ((Application)evt.getSource()).removePropertyChangeListener(\n                        Stateful.PROPERTY_STATE, this);\n                client.disconnectImpl(false);\n                availabilityListener = null;\n            }\n        }\n    }\n\n    static class Checker {\n\n        private Checker() {\n        }\n\n        static MBeanServerConnection newChecker(\n                ProxyClient client, MBeanServerConnection mbsc) {\n            final InvocationHandler ih = new CheckerInvocationHandler(mbsc);\n            return (MBeanServerConnection) Proxy.newProxyInstance(\n                    Checker.class.getClassLoader(),\n                    new Class<?>[]{MBeanServerConnection.class},\n                    ih);\n        }\n    }\n\n    private static class CheckerInvocationHandler implements InvocationHandler {\n\n        private final MBeanServerConnection conn;\n\n        CheckerInvocationHandler(MBeanServerConnection conn) {\n            this.conn = conn;\n        }\n\n        public Object invoke(Object proxy, Method method, Object[] args)\n                throws Throwable {\n            if (LOGGER.isLoggable(Level.FINE)) {\n                // Check if MBeanServerConnection call is performed on EDT\n                if (EventQueue.isDispatchThread()) {\n                    Throwable thrwbl = new Throwable();\n\n                    LOGGER.log(Level.FINE, createTracedMessage(\"MBeanServerConnection call \" +  // NOI18N\n                            \"performed on Event Dispatch Thread!\", thrwbl));    // NOI18N\n                }\n            }\n            // Invoke MBeanServerConnection call\n            try {\n                return method.invoke(conn, args);\n            } catch (InvocationTargetException e) {\n                throw e.getCause();\n            }\n        }\n\n        private String createTracedMessage(String message, Throwable thrwbl) {\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            PrintWriter pw = new PrintWriter(baos);\n            pw.println(message);\n            thrwbl.printStackTrace(pw);\n            pw.flush();\n            return baos.toString();\n        }\n    }\n\n    static class LocalVirtualMachine {\n        private static ExecutorService winExec = Executors.newCachedThreadPool();\n\n        private int vmid;\n        private boolean isAttachSupported;\n        private String javaHome;\n        \n        // @GuardedBy this\n        volatile private String address;\n\n        LocalVirtualMachine(int vmid, boolean canAttach, String connectorAddress, String home) {\n            this.vmid = vmid;\n            this.address = connectorAddress;\n            this.isAttachSupported = canAttach;\n            this.javaHome = home;\n        }\n\n        int vmid() {\n            return vmid;\n        }\n\n        synchronized boolean isManageable() {\n            return (address != null);\n        }\n\n        boolean isAttachable() {\n            return isAttachSupported;\n        }\n\n        synchronized void startManagementAgent() throws IOException {\n            if (address != null) {\n                // already started\n                return;\n            }\n\n            if (!isAttachable()) {\n                throw new IOException(\"This virtual machine \\\"\" + vmid +    // NOI18N\n                        \"\\\" does not support dynamic attach.\"); // NOI18N\n            }\n            executeAndWait(() -> {\n                try {\n                    loadManagementAgent();\n                } catch (IOException ex) {\n                    LOGGER.log(Level.INFO, \"loadManagementAgent for PID \"+vmid+\" failed\", ex); // NOI18N\n                }\n                // rerurn void\n                return null;\n            });\n            // fails to load or start the management agent\n            if (address == null) {\n                // should never reach here\n                throw new IOException(\"Fails to find connector address\");   // NOI18N\n            }\n        }\n\n        synchronized String connectorAddress() {\n            // return null if not available or no JMX agent\n            return address;\n        }\n\n        private static final String LOCAL_CONNECTOR_ADDRESS_PROP =\n                \"com.sun.management.jmxremote.localConnectorAddress\";   // NOI18N\n\n        private void loadManagementAgent() throws IOException {\n            VirtualMachine vm = null;\n            String name = String.valueOf(vmid);\n            try {\n                vm = VirtualMachine.attach(name);\n            } catch (AttachNotSupportedException x) {\n                throw new IOException(x);\n            }\n            // try to enable local JMX via jcmd command\n            address = loadManagementAgentViaJcmd(vm);\n            if (address == null) {\n                // load the management agent into the target VM\n                loadManagementAgentViaJar(vm);\n                // get the connector address\n                Properties agentProps = vm.getAgentProperties();\n                address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);\n            }\n\n            vm.detach();\n        }\n\n        private void loadManagementAgentViaJar(VirtualMachine vm) throws IOException {\n            // Normally in ${java.home}/jre/lib/management-agent.jar but might\n            // be in ${java.home}/lib in build environments.\n\n            String agent = javaHome + File.separator + \"jre\" + File.separator + // NOI18N\n                    \"lib\" + File.separator + \"management-agent.jar\";    // NOI18N\n            File f = new File(agent);\n            if (!f.exists()) {\n                agent = javaHome + File.separator + \"lib\" + File.separator +    // NOI18N\n                        \"management-agent.jar\"; // NOI18N\n                f = new File(agent);\n                if (!f.exists()) {\n                    throw new IOException(\"Management agent not found\");    // NOI18N\n                }\n            }\n\n            agent = f.getCanonicalPath();\n            try {\n                vm.loadAgent(agent, \"com.sun.management.jmxremote\");    // NOI18N\n            } catch (AgentLoadException x) {\n                throw new IOException(x);\n            } catch (AgentInitializationException x) {\n                throw new IOException(x);\n            }\n        }\n\n        private String loadManagementAgentViaJcmd(VirtualMachine vm) {\n            try {\n                return vm.startLocalManagementAgent();\n            } catch (IOException ex) {\n                LOGGER.log(Level.INFO, \"startLocalManagementAgent for PID \"+vmid+\" failed\", ex); // NOI18N\n            }\n            return null;\n        }\n\n        // see AttachModelImpl.executeAndWait\n        private static <V> V executeAndWait(Callable<V> call) {\n            if (Utilities.isWindows()) {\n                Future<V> result = winExec.submit(call);\n                try {\n                    return result.get(SwingUtilities.isEventDispatchThread() ? 5 : 25, TimeUnit.SECONDS);\n                } catch (InterruptedException | ExecutionException | TimeoutException ex) {\n                    LOGGER.log(Level.INFO, \"executeAndWait get\", ex);    // NOI18N\n                }\n                return null;\n            }\n            try {\n                return call.call();\n            } catch (Exception ex) {\n                throw new RuntimeException(ex);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxModelProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.core.model.ModelProvider;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory;\n\n/**\n * The {@code JmxModelFactory} class is a factory class for getting\n * the {@link JmxModel} representation for the {@link Application}.\n *\n * @author Luis-Miguel Alventosa\n */\npublic class JmxModelProvider extends AbstractModelProvider<JmxModel, Application> {\n    \n    \n    /**\n     * Default {@link ModelProvider} implementation for {@link JmxModel}.\n     *\n     * In order to extend the {@code JmxModelFactory} to register your\n     * own {@link JmxModel}s for the different types of {@link Application}\n     * call {@link JmxModelFactory#registerProvider(ModelProvider)} supplying\n     * the new instance of {@link ModelProvider}.\n     *\n     * @param app application.\n     *\n     * @return an instance of {@link JmxModel}.\n     */\n    public JmxModel createModelFor(Application app) {\n        JvmstatModel jvmstat;\n        \n        if (app instanceof JmxApplication) {\n            if (app.getState() == Stateful.STATE_AVAILABLE)\n                return new JmxModelImpl((JmxApplication) app);\n            return new DisconnectedJmxModel((JmxApplication) app);\n        }\n        jvmstat = JvmstatModelFactory.getJvmstatFor(app);\n        if (jvmstat != null) {\n            return new JmxModelImpl(app,jvmstat);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxPropertiesProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.properties.PropertiesPanel;\nimport org.graalvm.visualvm.core.properties.PropertiesProvider;\nimport org.graalvm.visualvm.jmx.JmxConnectionCustomizer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class JmxPropertiesProvider extends PropertiesProvider<JmxApplication> {\n    \n    /**\n     * Key for the \"JMX Connection\" properties category.\n     */\n    public static final int CATEGORY_JMX_CONNECTION = 200;\n\n    private static final String PROP_CONN_CUSTOMIZER_ID = \"prop_conn_customizer_id\"; // NOI18N\n\n\n    public JmxPropertiesProvider() {\n        super(NbBundle.getMessage(JmxPropertiesProvider.class, \"CAP_JmxConnection\"), // NOI18N\n              NbBundle.getMessage(JmxPropertiesProvider.class, \"DESCR_JmxConnection\"), // NOI18N\n              CATEGORY_JMX_CONNECTION, 0);\n    }\n\n\n    public PropertiesPanel createPanel(JmxApplication application) {\n        JmxConnectionCustomizer customizer = getCustomizer(application);\n        return customizer == null ? null : customizer.createPanel(application);\n    }\n\n    public boolean supportsDataSource(JmxApplication application) {\n        if (application == null) return false;\n        JmxConnectionCustomizer customizer = getCustomizer(application);\n        return customizer == null ? false : customizer.supportsDataSource(application);\n    }\n\n    public void propertiesDefined(PropertiesPanel panel, JmxApplication application) {\n        JmxConnectionCustomizer customizer = getCustomizer(application);\n        if (customizer != null) customizer.propertiesDefined(panel, application);\n    }\n\n    public void propertiesChanged(PropertiesPanel panel, JmxApplication application) {\n        JmxConnectionCustomizer customizer = getCustomizer(application);\n        if (customizer != null) customizer.propertiesChanged(panel, application);\n    }\n\n    public void propertiesCancelled(PropertiesPanel panel, JmxApplication application) {\n        JmxConnectionCustomizer customizer = getCustomizer(application);\n        if (customizer != null) customizer.propertiesCancelled(panel, application);\n    }\n\n\n    static void setCustomizer(JmxApplication application, JmxConnectionCustomizer customizer) {\n        setCustomizer(application.getStorage(), customizer);\n    }\n\n    private static void setCustomizer(Storage storage, JmxConnectionCustomizer customizer) {\n        storage.setCustomProperty(PROP_CONN_CUSTOMIZER_ID, customizer.getId());\n    }\n\n    private static JmxConnectionCustomizer getCustomizer(JmxApplication application) {\n        String customizerId = application.getStorage().getCustomProperty(PROP_CONN_CUSTOMIZER_ID);\n        return customizerId != null ? JmxConnectionSupportImpl.getCustomizer(customizerId) : null;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxSupport.java",
    "content": "/*\n * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport com.sun.management.HotSpotDiagnosticMXBean;\nimport com.sun.management.VMOption;\nimport java.io.IOException;\nimport java.lang.management.LockInfo;\nimport java.lang.management.ManagementFactory;\nimport java.lang.management.MonitorInfo;\nimport java.lang.management.RuntimeMXBean;\nimport java.lang.management.ThreadInfo;\nimport java.lang.management.ThreadMXBean;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.text.SimpleDateFormat;\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.MBeanException;\nimport javax.management.MBeanInfo;\nimport javax.management.MBeanOperationInfo;\nimport javax.management.MBeanServerConnection;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\nimport javax.management.ReflectionException;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.openide.ErrorManager;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class JmxSupport {\n    private final static Logger LOGGER = Logger.getLogger(JmxSupport.class.getName());\n    private static final String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =\n            \"com.sun.management:type=HotSpotDiagnostic\";    // NOI18N\n    private static final String DIAGNOSTIC_COMMAND_MXBEAN_NAME =\n            \"com.sun.management:type=DiagnosticCommand\";    // NOI18N\n    private static final String ALL_OBJECTS_OPTION = \"-all\";    // NOI18N\n    private static final String HISTOGRAM_COMMAND = \"gcClassHistogram\";       // NOI18N\n    private static final String CMDLINE_COMMAND = \"vmCommandLine\";       // NOI18N\n    private static final String CMDLINE_PREFIX = \"java_command: \";       // NOI18N\n    private static final String CMDLINE_EMPTY = \"<unknown>\";            // NOI18N\n\n    private JmxModel jmxModel;\n    // HotspotDiagnostic\n    private boolean hotspotDiagnosticInitialized;\n    private final Object hotspotDiagnosticLock = new Object();\n    private HotSpotDiagnosticMXBean hotspotDiagnosticMXBean;\n    private final Object readOnlyConnectionLock = new Object();\n    private Boolean readOnlyConnection;\n    \n    private Boolean hasDumpAllThreads;\n    private final Object hasDumpAllThreadsLock = new Object();\n    \n    private Boolean hasDiagnosticCommand;\n    private final Object hasDiagnosticCommandLock = new Object();\n\n    private String commandLine;\n    private final Object commandLineLock = new Object();\n\n    JmxSupport(JmxModel jmx) {\n        jmxModel = jmx;\n    }\n    \n    private RuntimeMXBean getRuntime() {\n        JvmMXBeans jmx = jmxModel.getJvmMXBeans();\n        if (jmx != null) {\n            return jmx.getRuntimeMXBean();\n        }\n        return null;\n    }\n    \n    Properties getSystemProperties() {\n        try {\n            RuntimeMXBean runtime = getRuntime();\n            if (runtime != null) {\n                Properties prop = new Properties();\n                prop.putAll(runtime.getSystemProperties());\n                return prop;\n            }\n            return null;\n        } catch (Exception e) {\n            LOGGER.log(Level.INFO, \"getSystemProperties\", e); // NOI18N\n            return null;\n        }\n    }\n\n    boolean isReadOnlyConnection() {\n        synchronized (readOnlyConnectionLock) {\n            if (readOnlyConnection == null) {\n                readOnlyConnection = Boolean.FALSE;\n                ThreadMXBean threads = getThreadBean();\n                if (threads != null) {\n                    try {\n                        threads.getThreadInfo(1);\n                    } catch (SecurityException ex) {\n                        readOnlyConnection = Boolean.TRUE;\n                    }\n                }\n            }\n            return readOnlyConnection.booleanValue();\n        }\n    }\n    \n    ThreadMXBean getThreadBean() {\n        JvmMXBeans jmx = jmxModel.getJvmMXBeans();\n        if (jmx != null) {\n            return jmx.getThreadMXBean();\n        }\n        return null;\n    }\n    \n    HotSpotDiagnosticMXBean getHotSpotDiagnostic() {\n        synchronized (hotspotDiagnosticLock) {\n            if (hotspotDiagnosticInitialized) {\n                return hotspotDiagnosticMXBean;\n            }\n            JvmMXBeans jmx = jmxModel.getJvmMXBeans();\n            if (jmx != null) {\n                try {\n                    hotspotDiagnosticMXBean = jmx.getMXBean(\n                            ObjectName.getInstance(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME),\n                            HotSpotDiagnosticMXBean.class);\n                } catch (MalformedObjectNameException e) {\n                    ErrorManager.getDefault().log(ErrorManager.WARNING,\n                            \"Couldn't find HotSpotDiagnosticMXBean: \" + // NOI18N\n                            e.getLocalizedMessage());\n                } catch (IllegalArgumentException ex) {\n                    ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);\n                }\n            }\n            hotspotDiagnosticInitialized = true;\n            return hotspotDiagnosticMXBean;\n        }\n    }\n    \n    String takeThreadDump(long[] threadIds) {\n        try {\n            ThreadMXBean threadMXBean = getThreadBean();\n            if (threadMXBean == null) {\n                return null;\n            }\n            ThreadInfo[] threads;\n            StringBuilder sb = new StringBuilder(4096);\n            SimpleDateFormat df = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");  // NOI18N\n\n            if (hasDumpAllThreads()) {\n                threads = threadMXBean.getThreadInfo(threadIds, true, true);\n            } else {\n                threads = threadMXBean.getThreadInfo(threadIds, Integer.MAX_VALUE);\n            }\n            sb.append(df.format(new Date()) + \"\\n\");  // NOI18N\n            printThreads(sb, threadMXBean, threads);\n            return sb.toString();\n        } catch (Exception e) {\n            LOGGER.log(Level.INFO, \"takeThreadDump[]\", e); // NOI18N\n            return null;\n        }\n    }\n    \n    String takeThreadDump() {\n        try {\n            ThreadMXBean threadMXBean = getThreadBean();\n            if (threadMXBean == null) {\n                return null;\n            }\n            ThreadInfo[] threads;\n            Properties prop = getSystemProperties();\n            StringBuilder sb = new StringBuilder(4096);\n            SimpleDateFormat df = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");  // NOI18N\n            sb.append(df.format(new Date()) + \"\\n\");\n            sb.append(\"Full thread dump \" + prop.getProperty(\"java.vm.name\") + // NOI18N\n                    \" (\" + prop.getProperty(\"java.vm.version\") + \" \" + // NOI18N\n                    prop.getProperty(\"java.vm.info\") + \"):\\n\");  // NOI18N\n            if (hasDumpAllThreads()) {\n                threads = threadMXBean.dumpAllThreads(true, true);\n            } else {\n                long[] threadIds = threadMXBean.getAllThreadIds();\n                threads = threadMXBean.getThreadInfo(threadIds, Integer.MAX_VALUE);\n            }\n            printThreads(sb, threadMXBean, threads);\n            return sb.toString();\n        } catch (Exception e) {\n            LOGGER.log(Level.INFO,\"takeThreadDump\", e); // NOI18N\n            return null;\n        }\n    }\n    \n    private void printThreads(final StringBuilder sb, final ThreadMXBean threadMXBean, ThreadInfo[] threads) {\n        boolean jdk16 = hasDumpAllThreads();\n        \n        for (ThreadInfo thread : threads) {\n            if (thread != null) {\n                if (jdk16) {\n                    print16Thread(sb, threadMXBean, thread);\n                } else {\n                    print15Thread(sb, thread);\n                }\n            }\n        }\n    }\n    \n    private void print16Thread(final StringBuilder sb, final ThreadMXBean threadMXBean, final ThreadInfo thread) {\n        MonitorInfo[] monitors = null;\n        if (threadMXBean.isObjectMonitorUsageSupported()) {\n            monitors = thread.getLockedMonitors();\n        }\n        sb.append(\"\\n\\\"\" + thread.getThreadName() + // NOI18N\n                \"\\\" - Thread t@\" + thread.getThreadId() + \"\\n\");    // NOI18N\n        sb.append(\"   java.lang.Thread.State: \" + thread.getThreadState()); // NOI18N\n        sb.append(\"\\n\");   // NOI18N\n        int index = 0;\n        for (StackTraceElement st : thread.getStackTrace()) {\n            LockInfo lock = thread.getLockInfo();\n            String lockOwner = thread.getLockOwnerName();\n            \n            sb.append(\"\\tat \" + st.toString() + \"\\n\");    // NOI18N\n            if (index == 0) {\n                if (\"java.lang.Object\".equals(st.getClassName()) &&     // NOI18N\n                        \"wait\".equals(st.getMethodName())) {                // NOI18N\n                    if (lock != null) {\n                        sb.append(\"\\t- waiting on \");    // NOI18N\n                        printLock(sb,lock);\n                        sb.append(\"\\n\");    // NOI18N\n                    }\n                } else if (lock != null) {\n                    if (lockOwner == null) {\n                        sb.append(\"\\t- parking to wait for \");      // NOI18N\n                        printLock(sb,lock);\n                        sb.append(\"\\n\");            // NOI18N\n                    } else {\n                        sb.append(\"\\t- waiting to lock \");      // NOI18N\n                        printLock(sb,lock);\n                        sb.append(\" owned by \\\"\"+lockOwner+\"\\\" t@\"+thread.getLockOwnerId()+\"\\n\");   // NOI18N\n                    }\n                }\n            }\n            printMonitors(sb, monitors, index);\n            index++;\n        }\n        StringBuilder jnisb = new StringBuilder();\n        printMonitors(jnisb, monitors, -1);\n        if (jnisb.length() > 0) {\n            sb.append(\"   JNI locked monitors:\\n\");\n            sb.append(jnisb);\n        }\n        if (threadMXBean.isSynchronizerUsageSupported()) {\n            sb.append(\"\\n   Locked ownable synchronizers:\");    // NOI18N\n            LockInfo[] synchronizers = thread.getLockedSynchronizers();\n            if (synchronizers == null || synchronizers.length == 0) {\n                sb.append(\"\\n\\t- None\\n\");  // NOI18N\n            } else {\n                for (LockInfo li : synchronizers) {\n                    sb.append(\"\\n\\t- locked \");         // NOI18N\n                    printLock(sb,li);\n                    sb.append(\"\\n\");  // NOI18N\n                }\n            }\n        }\n    }\n\n    private void printMonitors(final StringBuilder sb, final MonitorInfo[] monitors, final int index) {\n        if (monitors != null) {\n            for (MonitorInfo mi : monitors) {\n                if (mi.getLockedStackDepth() == index) {\n                    sb.append(\"\\t- locked \");   // NOI18N\n                    printLock(sb,mi);\n                    sb.append(\"\\n\");    // NOI18N\n                }\n            }\n        }\n    }\n    \n    private void print15Thread(final StringBuilder sb, final ThreadInfo thread) {\n        sb.append(\"\\n\\\"\" + thread.getThreadName() + // NOI18N\n                \"\\\" - Thread t@\" + thread.getThreadId() + \"\\n\");    // NOI18N\n        sb.append(\"   java.lang.Thread.State: \" + thread.getThreadState()); // NOI18N\n        if (thread.getLockName() != null) {\n            sb.append(\" on \" + thread.getLockName());   // NOI18N\n            if (thread.getLockOwnerName() != null) {\n                sb.append(\" owned by: \" + thread.getLockOwnerName());   // NOI18N\n            }\n        }\n        sb.append(\"\\n\");    // NOI18N\n        for (StackTraceElement st : thread.getStackTrace()) {\n            sb.append(\"        at \" + st.toString() + \"\\n\");    // NOI18N\n        }\n    }\n    \n    private void printLock(StringBuilder sb,LockInfo lock) {\n        String id = Integer.toHexString(lock.getIdentityHashCode());\n        String className = lock.getClassName();\n        \n        sb.append(\"<\"+id+\"> (a \"+className+\")\");       // NOI18N\n    }\n    \n    boolean takeHeapDump(String fileName) {\n        HotSpotDiagnosticMXBean hsDiagnostic = getHotSpotDiagnostic();\n        if (hsDiagnostic != null) {\n            try {\n                hsDiagnostic.dumpHeap(fileName,true);\n            } catch (IOException ex) {\n                LOGGER.log(Level.INFO,\"takeHeapDump\", ex); // NOI18N\n                try {\n                    Path f = Paths.get(fileName);\n                    Files.deleteIfExists(f);\n                } catch (IOException ex1) {\n                    LOGGER.log(Level.INFO,\"takeHeapDump\", ex1); // NOI18N\n                }\n                return false;\n            }\n            return true;\n        }\n        return false;\n    }\n    \n    String getFlagValue(String name) {\n        try {\n            HotSpotDiagnosticMXBean hsDiagnostic = getHotSpotDiagnostic();\n            if (hsDiagnostic != null) {\n                VMOption option = hsDiagnostic.getVMOption(name);\n                if (option != null) {\n                    return option.getValue();\n                }\n            }\n            return null;\n        } catch (IllegalArgumentException ex) {\n            // non-existing VM option\n            LOGGER.log(Level.FINE, \"getFlagValue\", ex); // NOI18N\n            return null;\n        } catch (Exception ex) {\n            LOGGER.log(Level.INFO, \"getFlagValue\", ex); // NOI18N\n            return null;\n        }\n    }\n\n    HeapHistogram takeHeapHistogram() {\n        if (isReadOnlyConnection()) return null;\n        String histo = executeJCmd(HISTOGRAM_COMMAND, Collections.singletonMap(ALL_OBJECTS_OPTION, null));\n        if (histo != null) {\n            return new HeapHistogramImpl(histo);\n        }\n        return null;\n    }\n    \n    void setFlagValue(String name, String value) {\n        try {\n        HotSpotDiagnosticMXBean hsDiagnostic = getHotSpotDiagnostic();\n            if (hsDiagnostic != null) {\n                hsDiagnostic.setVMOption(name,value);\n            }\n        } catch (Exception ex) {\n            LOGGER.log(Level.INFO,\"setFlagValue\", ex); // NOI18N\n        }\n    }\n    \n    private boolean hasDiagnosticCommand() {\n        synchronized (hasDiagnosticCommandLock) {\n            if (hasDiagnosticCommand == null) {\n                hasDiagnosticCommand = Boolean.FALSE;\n                MBeanServerConnection conn = jmxModel.getMBeanServerConnection();\n                try {\n                    ObjectName diagCommName = new ObjectName(DIAGNOSTIC_COMMAND_MXBEAN_NAME);\n                    if (conn.isRegistered(diagCommName)) {\n                        hasDiagnosticCommand = Boolean.TRUE;\n                    }\n                } catch (MalformedObjectNameException ex) {\n                    Exceptions.printStackTrace(ex);\n                } catch (IOException ex) {\n                    LOGGER.log(Level.INFO, \"hasDiagnosticCommand\", ex); // NOI18N\n                }\n            }\n\n            return hasDiagnosticCommand.booleanValue();\n        }\n    }\n\n    private boolean hasDumpAllThreads() {\n        synchronized (hasDumpAllThreadsLock) {\n            if (hasDumpAllThreads == null) {\n                hasDumpAllThreads = Boolean.FALSE;\n                try {\n                    ObjectName threadObjName = new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME);\n                    MBeanInfo threadInfo = jmxModel.getMBeanServerConnection().getMBeanInfo(threadObjName);\n                    if (threadInfo != null) {\n                        for (MBeanOperationInfo op : threadInfo.getOperations()) {\n                            if (\"dumpAllThreads\".equals(op.getName())) {\n                                hasDumpAllThreads = Boolean.TRUE;\n                                break;\n                            }\n                        }\n                    }\n                } catch (Exception ex) {\n                    LOGGER.log(Level.INFO,\"hasDumpAllThreads\", ex); // NOI18N\n                }\n            }\n            return hasDumpAllThreads.booleanValue();\n        }\n    }\n\n    String getCommandLine() {\n        synchronized (commandLineLock) {\n            if (commandLine == null) {\n                String vmCommandLine = executeJCmd(CMDLINE_COMMAND);\n                if (vmCommandLine != null) {\n                    commandLine = parseVMCommandLine(vmCommandLine);\n                }\n            }\n            return commandLine;\n        }\n    }\n\n    private String executeJCmd(String command) {\n        return executeJCmd(command, Collections.emptyMap());\n    }\n\n    String executeJCmd(String command, Map<String,Object> pars) {\n        if (jmxModel.getConnectionState() == ConnectionState.CONNECTED && hasDiagnosticCommand()) {\n            try {\n                MBeanServerConnection conn = jmxModel.getMBeanServerConnection();\n                ObjectName diagCommName = new ObjectName(DIAGNOSTIC_COMMAND_MXBEAN_NAME);\n                Object[] params = null;\n                String[] signature = null;\n                Object ret;\n\n                if (!pars.isEmpty()) {\n                    params = new Object[]{getJCmdParams(pars)};\n                    signature = new String[]{String[].class.getName()};\n                }\n                ret = conn.invoke(diagCommName, command, params, signature);\n                if (ret instanceof String) {\n                    return (String) ret;\n                }\n            } catch (MalformedObjectNameException ex) {\n                throw new IllegalArgumentException(ex);\n            } catch (IOException ex) {\n                LOGGER.log(Level.INFO, \"executeJCmd\", ex); // NOI18N\n            } catch (InstanceNotFoundException ex) {\n                Exceptions.printStackTrace(ex);\n            } catch (MBeanException ex) {\n                Exceptions.printStackTrace(ex);\n            } catch (ReflectionException ex) {\n                Exceptions.printStackTrace(ex);\n            }\n        }\n        return null;\n    }\n\n    private String parseVMCommandLine(String vmCommandLine) {\n      String[] lines = vmCommandLine.split(\"\\\\r?\\\\n\");\n      for (String line : lines) {\n          if (line.startsWith(CMDLINE_PREFIX)) {\n              String cmdline = line.substring(CMDLINE_PREFIX.length());\n              if (CMDLINE_EMPTY.equals(cmdline)) return \"\";\n              return cmdline;\n          }\n      }\n      return null;\n    }\n\n    private static String[] getJCmdParams(Map<String, Object> pars) {\n        String[] jcmdParams = new String[pars.size()];\n        int i = 0;\n        for (Map.Entry<String,Object> e : pars.entrySet()) {\n            String par;\n            String key = e.getKey();\n            Object val = e.getValue();\n\n            if (val == null) {\n                par = key;\n            } else {\n                par = String.format(\"%s=%s\", key, quoteString(val.toString())); // NOI18N\n            }\n            jcmdParams[i++] = par;\n        }\n        return jcmdParams;\n    }\n\n    private static String quoteString(String val) {\n        if (val.indexOf(' ')>=0) {\n            return \"\\\"\"+val+\"\\\"\";   //NOI18N\n        }\n        return val;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/OpenJmxApplication.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.util.Collections;\nimport java.util.Map;\nimport java.util.Set;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.jmx.JmxApplicationsSupport;\nimport org.netbeans.api.sendopts.CommandException;\nimport org.netbeans.spi.sendopts.Env;\nimport org.netbeans.spi.sendopts.Option;\nimport org.netbeans.spi.sendopts.OptionProcessor;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n * Handling of --openjmx commandline option\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=OptionProcessor.class)\npublic final class OpenJmxApplication extends OptionProcessor {\n    \n    private Option openjmx = Option.requiredArgument(Option.NO_SHORT_NAME, \"openjmx\"); // NOI18N\n\n    public OpenJmxApplication() {\n        openjmx = Option.shortDescription(openjmx, \"org.graalvm.visualvm.jmx.impl.Bundle\",\"MSG_OPENJMX\");\n    }\n    \n    protected Set<Option> getOptions() {\n        return Collections.singleton(openjmx);\n    }\n\n    protected void process(Env env, Map<Option, String[]> optionValues) throws CommandException {\n        String[] connectionStrings = optionValues.get(openjmx);\n        if (connectionStrings != null && connectionStrings.length > 0)\n            openJmxApplication(connectionStrings[0]);\n    }\n\n    private void openJmxApplication(final String connectionString) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                JmxApplication application = (JmxApplication)JmxApplicationsSupport.getInstance().\n                        createJmxApplicationInteractive(connectionString, null, null, null);\n                if (application != null) {\n                    JmxPropertiesProvider.setCustomizer(application,\n                            JmxConnectionSupportImpl.getDefaultCustomizer());\n                    DataSourceWindowManager.sharedInstance().openDataSource(application);\n                }\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/ProxyClient.java",
    "content": "/*\n * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jmx.impl;\n\nimport java.awt.BorderLayout;\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport java.io.IOException;\nimport java.lang.management.ManagementFactory;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.ListenerNotFoundException;\nimport javax.management.MBeanServerConnection;\nimport javax.management.Notification;\nimport javax.management.NotificationListener;\nimport javax.management.remote.JMXConnectionNotification;\nimport javax.management.remote.JMXConnector;\nimport javax.management.remote.JMXConnectorFactory;\nimport javax.management.remote.JMXServiceURL;\nimport javax.rmi.ssl.SslRMIClientSocketFactory;\nimport javax.security.sasl.SaslException;\nimport javax.swing.JCheckBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.jmx.CredentialsProvider;\nimport org.graalvm.visualvm.jmx.EnvironmentProvider;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Luis-Miguel Alventosa\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nclass ProxyClient implements NotificationListener {\n\n    private final static Logger LOGGER = Logger.getLogger(ProxyClient.class.getName());\n\n    private static final int MODE_SELF = 0;\n    private static final int MODE_LOCAL = 1;\n    private static final int MODE_GENERIC = 2;\n    private final int mode;\n    private JmxModel.ConnectionState connectionState = JmxModel.ConnectionState.DISCONNECTED;\n    private volatile boolean isDead = true;\n    private String user = null;\n    private char[] pword = null;\n    private JmxModelImpl.LocalVirtualMachine lvm;\n    private JMXServiceURL jmxUrl = null;\n    private Application app;\n    private EnvironmentProvider envProvider = null;\n    private MBeanServerConnection conn = null;\n    private JMXConnector jmxc = null;\n    private static final SslRMIClientSocketFactory sslRMIClientSocketFactory = new SslRMIClientSocketFactory();\n    private boolean insecure; // do not check for SSL-protected RMI registry\n    private boolean checkSSLStub;\n    private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);\n\n    // Self attach\n    ProxyClient(Application app) throws IOException {\n        this.app = app;\n        this.mode = MODE_SELF;\n    }\n\n    // Local attach\n    ProxyClient(Application app, JmxModelImpl.LocalVirtualMachine lvm) throws IOException {\n        this.app = app;\n        this.mode = MODE_LOCAL;\n        this.lvm = lvm;\n    }\n\n    // Generic attach - host/port\n    ProxyClient(Application app, int port) throws IOException {\n        this(app, new JMXServiceURL(\"rmi\", \"\", 0, createUrl(app.getHost().getHostName(), // NOI18N\n        port)), null);\n    }\n\n    // Generic attach - connection string\n    ProxyClient(Application app, String url) throws IOException {\n        this(app, new JMXServiceURL(url), null);\n    }\n\n    // Generic attach - JmxApplication\n    ProxyClient(JmxApplication jmxApp) throws IOException {\n        this(jmxApp, jmxApp.getJMXServiceURL(), jmxApp.getEnvironmentProvider());\n    }\n\n    // Generic attach - JMXServiceURL\n    private ProxyClient(Application app, JMXServiceURL url, EnvironmentProvider envProvider) throws IOException {\n        this.mode = MODE_GENERIC;\n        this.jmxUrl = url;\n        this.app = app;\n        this.envProvider = envProvider;\n    }\n\n    void setCredentials(String user, char[] pword) {\n        if (envProvider instanceof CredentialsProvider && ((CredentialsProvider)envProvider).isPersistent(app.getStorage())) {\n            EnvironmentProvider epr = new CredentialsProvider.Custom(user, pword, true);\n            epr.saveEnvironment(app.getStorage());\n        } else {\n            this.user = user;\n            this.pword = pword;\n        }\n    }\n\n    boolean hasSSLStubCheck() {\n        return checkSSLStub;\n    }\n\n    void setInsecure() {\n        insecure = true;\n    }\n\n    boolean isInsecure() {\n        return insecure;\n    }\n\n    void addConnectionStateListener(PropertyChangeListener listener) {\n        propertyChangeSupport.addPropertyChangeListener(listener);\n    }\n\n    void removeConnectionStateListener(PropertyChangeListener listener) {\n        propertyChangeSupport.removePropertyChangeListener(listener);\n    }\n\n    private static String createUrl(String hostName, int port) {\n        return \"/jndi/rmi://\" + hostName + \":\" + port + \"/jmxrmi\"; // NOI18N\n    }\n\n    private void setConnectionState(JmxModel.ConnectionState state) {\n        JmxModel.ConnectionState oldState = connectionState;\n        connectionState = state;\n        propertyChangeSupport.firePropertyChange(JmxModelImpl.CONNECTION_STATE_PROPERTY, oldState, state);\n    }\n\n    JmxModel.ConnectionState getConnectionState() {\n        return connectionState;\n    }\n\n    void connect() {\n        while (true) {\n            try {\n                connectImpl();\n                break;\n            } catch (SecurityException e) {\n                LOGGER.log(Level.INFO, \"connect\", e);   // NOI18N\n                if (hasSSLStubCheck()) {\n                    Storage storage = app.getStorage();\n                    String noSSLProp = JmxApplicationProvider.PROPERTY_RETRY_WITHOUT_SSL;\n                    String noSSL = storage.getCustomProperty(noSSLProp);\n                    if (noSSL != null && Boolean.parseBoolean(noSSL)) { // NOI18N\n                        setInsecure();\n                        continue;\n                    } else {\n                        String conn = storage.getCustomProperty(DataSourceDescriptor.PROPERTY_NAME);\n                        if (conn == null) conn = storage.getCustomProperty(ApplicationType.PROPERTY_SUGGESTED_NAME);\n                        if (conn == null) conn = getUrl().toString();\n                        String msg = NbBundle.getMessage(ProxyClient.class, \"MSG_Insecure_SSL\", conn);  // NOI18N\n                        String title = NbBundle.getMessage(ProxyClient.class, \"Title_Insecure_SSL\");   // NOI18N\n                        String retry = NbBundle.getMessage(ProxyClient.class, \"Retry_Insecure_SSL\");   // NOI18N\n                        JLabel l = new JLabel(msg);\n                        JCheckBox c = new JCheckBox();\n                        Mnemonics.setLocalizedText(c, retry);\n                        c.setSelected(noSSL == null);\n                        JPanel p = new JPanel(new BorderLayout(0, 20));\n                        p.add(l, BorderLayout.CENTER);\n                        p.add(c, BorderLayout.SOUTH);\n                        NotifyDescriptor dd = new NotifyDescriptor.Confirmation(p, title, NotifyDescriptor.YES_NO_OPTION);\n                        if (DialogDisplayer.getDefault().notify(dd) == NotifyDescriptor.YES_OPTION) {\n                            storage.setCustomProperty(noSSLProp, Boolean.toString(c.isSelected()));\n                            setInsecure();\n                            continue;\n                        } else {\n                            break;\n                        }\n                    }\n                }\n                if (supplyCredentials() == null) {\n                    break;\n                }\n            }\n        }\n    }\n\n    /**\n     *  Ask for security credentials.\n     */\n    CredentialsConfigurator supplyCredentials() {\n        String displayName = app.getStorage().getCustomProperty(DataSourceDescriptor.PROPERTY_NAME);\n        if (displayName == null) displayName = getUrl().toString();\n        CredentialsConfigurator jsc = CredentialsConfigurator.supplyCredentials(displayName);\n        if (jsc != null) setCredentials(jsc.getUsername(), jsc.getPassword());\n        else if (app instanceof JmxApplication) ((JmxApplication)app).disableHeartbeat();\n        return jsc;\n    }\n\n\n    private void connectImpl() {\n        setConnectionState(JmxModel.ConnectionState.CONNECTING);\n        try {\n            tryConnect();\n            setConnectionState(JmxModel.ConnectionState.CONNECTED);\n        } catch (SecurityException e) {\n            setConnectionState(JmxModel.ConnectionState.DISCONNECTED);\n            throw e;\n        } catch (SaslException e) {\n            // Workaround for JBoss/WildFly authentication failed exception\n            throw new SecurityException(e);\n        } catch (Exception e) {\n            setConnectionState(JmxModel.ConnectionState.DISCONNECTED);\n            // Workaround for GlassFish's LoginException class not found\n            if (e.toString().contains(\"com.sun.enterprise.security.LoginException\")) { // NOI18N\n                throw new SecurityException(\"Authentication failed! Invalid username or password\"); // NOI18N\n            }\n            if (LOGGER.isLoggable(Level.FINE)) {\n                // Try to provide info on the target\n                //    Use PID when attach was used to connect,\n                //    Use JMXServiceURL otherwise...\n                final String param = (lvm != null) ? String.valueOf(lvm.vmid()) : ((jmxUrl != null) ? jmxUrl.toString() : \"\"); // NOI18N\n                LOGGER.log(Level.FINE, \"connect(\" + param + \")\", e); // NOI18N\n            }\n        }\n    }\n\n    private void tryConnect() throws IOException {\n        if (mode == MODE_SELF) {\n            jmxc = null;\n            conn = ManagementFactory.getPlatformMBeanServer();\n        } else {\n            if (mode == MODE_LOCAL) {\n                if (!lvm.isManageable()) {\n                    lvm.startManagementAgent();\n                    if (!lvm.isManageable()) {\n                        // FIXME: what to throw\n                        throw new IOException(lvm + \" not manageable\"); // NOI18N\n                    }\n                }\n                if (jmxUrl == null) {\n                    jmxUrl = new JMXServiceURL(lvm.connectorAddress());\n                }\n            }\n            Map<String, Object> env = new HashMap<>();\n            if (envProvider != null) {\n                env.putAll(envProvider.getEnvironment(app, app.getStorage()));\n            }\n            if (user != null || pword != null) {\n                env.put(JMXConnector.CREDENTIALS, new String[]{user, new String(pword)});\n            }\n            if (!insecure && mode != MODE_LOCAL && env.get(JMXConnector.CREDENTIALS) != null) {\n                env.put(\"jmx.remote.x.check.stub\", \"true\"); // NOI18N\n                checkSSLStub = true;\n            } else {\n                checkSSLStub = false;\n            }\n            jmxc = JMXConnectorFactory.newJMXConnector(jmxUrl, env);\n            jmxc.addConnectionNotificationListener(this, null, null);\n            try {\n                jmxc.connect(env);\n            } catch (java.io.IOException e) {\n                LOGGER.log(Level.INFO, \"tryConnect\", e);   // NOI18N\n                // Likely a SSL-protected RMI registry\n                if (\"rmi\".equals(jmxUrl.getProtocol())) { // NOI18N\n                    env.put(\"com.sun.jndi.rmi.factory.socket\", sslRMIClientSocketFactory); // NOI18N\n                    jmxc.connect(env);\n                } else {\n                    throw e;\n                }\n            }\n            MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();\n            conn = JmxModelImpl.Checker.newChecker(this, mbsc);\n        }\n        isDead = false;\n    }\n\n    MBeanServerConnection getMBeanServerConnection() {\n        return conn;\n    }\n\n    JMXServiceURL getUrl() {\n        return jmxUrl;\n    }\n\n    void disconnect() {\n        disconnectImpl(true);\n    }\n\n    synchronized void disconnectImpl(boolean sendClose) {\n        // Close MBeanServer connection\n        if (jmxc != null) {\n            try {\n                jmxc.removeConnectionNotificationListener(this);\n                if (sendClose) {\n                    jmxc.close();\n                }\n            } catch (IOException e) {\n                // Ignore...\n            } catch (ListenerNotFoundException e) {\n                LOGGER.log(Level.INFO, \"disconnectImpl\", e); // NOI18N\n            }\n            jmxc = null;\n        }\n        // Set connection state to DISCONNECTED\n        if (!isDead) {\n            isDead = true;\n            setConnectionState(JmxModel.ConnectionState.DISCONNECTED);\n        }\n    }\n\n    synchronized void markAsDead() {\n        disconnect();\n    }\n\n    boolean isDead() {\n        return isDead;\n    }\n\n    boolean isConnected() {\n        return !isDead();\n    }\n\n    public void handleNotification(Notification n, Object hb) {\n        if (n instanceof JMXConnectionNotification) {\n            if (JMXConnectionNotification.FAILED.equals(n.getType()) || JMXConnectionNotification.CLOSED.equals(n.getType())) {\n                markAsDead();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * JMX connections support in VisualVM.\n */\npackage org.graalvm.visualvm.jmx;\n"
  },
  {
    "path": "visualvm/jmx/src/org/graalvm/visualvm/jmx/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    \n    <folder name=\"Actions\">\n        <folder name=\"Other\">\n            <file name=\"org-graalvm-visualvm-jmx-impl-AddJMXConnectionAction-alwaysEnabled.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.jmx.impl.AddJMXConnectionAction.alwaysEnabled\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"Menu\">\n         <folder name=\"File\">\n            <file name=\"org-graalvm-visualvm-jmx-impl-AddJMXConnectionAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-jmx-impl-AddJMXConnectionAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"600\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"Toolbars\">\n        <folder name=\"DataSource\">\n            <file name=\"org-graalvm-visualvm-jmx-impl-AddJMXConnectionAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-jmx-impl-AddJMXConnectionAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"200\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"VisualVM\">\n        <folder name=\"ExplorerPopupSelection\">\n            \n            <file name=\"ExplorerPopupSelection-Separator-70.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"70\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-jmx-impl-ConnectDisconnectAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.jmx.impl.ConnectDisconnectAction.instance\"/>\n                <attr name=\"position\" intvalue=\"71\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-jmx-impl-AutoConnectAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.jmx.impl.AutoConnectAction.instance\"/>\n                <attr name=\"position\" intvalue=\"72\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-jmx-impl-AddJMXConnectionAction-selectionAware.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.jmx.impl.AddJMXConnectionAction.selectionAware\"/>\n                <attr name=\"position\" intvalue=\"100\"/>\n            </file>\n            \n        </folder>\n        \n        <folder name=\"ExplorerPopupNoSelection\">\n            \n            <file name=\"org-graalvm-visualvm-jmx-impl-AddJMXConnectionAction-alwaysEnabled.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-jmx-impl-AddJMXConnectionAction-alwaysEnabled.instance\"/>\n                <attr name=\"position\" intvalue=\"200\"/>\n            </file>\n            \n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "visualvm/jvm/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.jvm\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.jvm.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/jvm/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.jvm/2\nOpenIDE-Module-Install: org/graalvm/visualvm/jvm/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/jvm/Bundle.properties\nOpenIDE-Module-Provides: org.graalvm.visualvm.jvm\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "visualvm/jvm/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.jvm-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/jvm/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=11705818\nbuild.xml.script.CRC32=25884fdd\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=11705818\nnbproject/build-impl.xml.script.CRC32=63c7509b\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/jvm/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\ncp.extra=${tools.jar}\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nmodule.javadoc.packages=org.graalvm.visualvm.jvm.*\n\n"
  },
  {
    "path": "visualvm/jvm/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.jvm</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.49</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/jvm/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/jvm/src/org/graalvm/visualvm/jvm/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-JVM\n\nMSG_ThreadDumpfailed=Take Thread Dump failed\nLBL_Heap=Heap\nLBL_NA=N/A\nLBL_PermGen=PermGen\nLBL_Meta=Metaspace\n"
  },
  {
    "path": "visualvm/jvm/src/org/graalvm/visualvm/jvm/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvm;\n\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\npublic class Installer extends ModuleInstall {\n    \n    public void restored() {\n        JvmFactory.getDefault().registerProvider(new JvmProvider());\n        JvmFactory.getDefault().registerProvider(new JRockitJvmProvider());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jvm/src/org/graalvm/visualvm/jvm/JRockitJVMImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvm;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JRockitJVMImpl extends JVMImpl {\n \n    JRockitJVMImpl(Application app,JvmstatModel jvms) {\n        super(app,jvms);\n    }\n    \n    JRockitJVMImpl(Application app) {\n        super(app);\n    }\n        \n    @Override\n    public boolean is14() {\n        String ver = getVmVersion();\n        if (ver != null && ver.contains(\"1.4.2\")) { // NOI18N\n            return true;\n        }\n        return false;\n    }\n    \n    @Override\n    public boolean is15() {\n        String ver = getVmVersion();\n        if (ver != null && ver.contains(\"1.5.0\")) { // NOI18N\n            return true;\n        }\n        return false;\n    }\n    \n    @Override\n    public boolean is16() {\n        String ver = getVmVersion();\n        if (ver != null && ver.contains(\"1.6.0\")) { // NOI18N\n            return true;\n        }\n        return false;\n    }\n    \n    @Override\n    public boolean is17() {\n        return false;\n    }\n    \n    @Override\n    public boolean isDumpOnOOMEnabled() {\n        return false;\n    }\n        \n    @Override\n    public boolean isGetSystemPropertiesSupported() {\n        return (is16() && getAttach() != null) || jmxSupport.getRuntime() != null;\n    }\n        \n    @Override\n    public boolean isDumpOnOOMEnabledSupported() {\n        return false;\n    }\n        \n    @Override\n    public boolean isTakeHeapDumpSupported() {\n        return false;\n    }\n        \n    @Override\n    public boolean isTakeThreadDumpSupported() {\n        if (getAttach() != null) {\n            return true;\n        }\n        JmxModel jmx = getJmxModel();\n        if (jmx == null) {\n            return false;\n        }\n        return jmx.isTakeThreadDumpSupported();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jvm/src/org/graalvm/visualvm/jvm/JRockitJvmProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvm;\n\nimport java.lang.management.RuntimeMXBean;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JRockitJvmProvider extends JvmProvider {\n    private static final String JROCKIT_VM_NAME = \"BEA JRockit(R)\"; // NOI18N\n    private static final String VM_NAME = \"java.property.java.vm.name\"; // NOI18N\n    \n    @Override\n    public Jvm createModelFor(Application app) {\n        Jvm jvm = null;\n        JvmstatModel jvmstat = JvmstatModelFactory.getJvmstatFor(app);\n\n        if (jvmstat != null) {\n            String vmName = jvmstat.findByName(VM_NAME);\n            if (JROCKIT_VM_NAME.equals(vmName)) {\n                jvm = new JRockitJVMImpl(app, jvmstat);\n            }\n        } else {\n            JmxModel jmxModel = JmxModelFactory.getJmxModelFor(app);\n            if (jmxModel != null && jmxModel.getConnectionState() == JmxModel.ConnectionState.CONNECTED) {\n                JvmMXBeans mxbeans = jmxModel.getJvmMXBeans();\n                if (mxbeans != null) {\n                    RuntimeMXBean runtime = mxbeans.getRuntimeMXBean();\n                    if (runtime != null && JROCKIT_VM_NAME.equals(runtime.getVmName())) {\n                        jvm = new JRockitJVMImpl(app);\n                    }\n                }\n            }\n        }\n        return jvm;\n    }\n}\n"
  },
  {
    "path": "visualvm/jvm/src/org/graalvm/visualvm/jvm/JVMImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvm;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Properties;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.application.jvm.MonitoredDataListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.tools.attach.AttachModel;\nimport org.graalvm.visualvm.tools.attach.AttachModelFactory;\nimport org.graalvm.visualvm.tools.jfr.JfrModel;\nimport org.graalvm.visualvm.tools.jfr.JfrModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatListener;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.sa.SaModel;\nimport org.graalvm.visualvm.tools.sa.SaModelFactory;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JVMImpl extends Jvm implements JvmstatListener {\n    private static final String HEAP_DUMP_ON_OOME = \"HeapDumpOnOutOfMemoryError\";   // NOI18N\n    private static final String HEAP_DUMP_PATH = \"HeapDumpPath\";   // NOI18N\n    Application application;\n    Boolean isDumpOnOOMEnabled;\n    JvmstatModel monitoredVm;\n    JvmJvmstatModel jvmstatModel;\n    final Set<MonitoredDataListener> listeners;\n    final JmxSupport jmxSupport;\n    \n    // static JVM data \n    private boolean staticDataInitialized; \n    final private Object staticDataLock = new Object();\n    private String commandLine;\n    private String jvmArgs;\n    private String jvmFlags;\n    private String mainArgs;\n    private String mainClass;\n    private String vmVersion;\n    private String javaVersion;\n    private String javaHome;\n    private String vmInfo;\n    private String vmName;\n    private String vmVendor;\n\n \n    JVMImpl(Application app,JvmstatModel jvms) {\n        application = app;\n        monitoredVm = jvms;\n        jvmstatModel = JvmJvmstatModelFactory.getJvmstatModelFor(app);\n        jmxSupport = new JmxSupport(app,this);\n        listeners = new HashSet<>();\n    }\n    \n    JVMImpl(Application app) {\n        application = app;\n        jmxSupport = new JmxSupport(app,this);\n        listeners = new HashSet<>();\n    }\n    \n    public boolean isAttachable() {\n        if (jvmstatModel != null) {\n            if (!jvmstatModel.isAttachable()) {\n                return false;\n            }\n            return getAttach() != null;\n        }\n        return false;\n    }\n    \n    public boolean isBasicInfoSupported() {\n        return true;\n    }\n    \n    public String getCommandLine() {\n        initStaticData();\n        return commandLine;\n    }\n    \n    public String getJvmArgs() {\n        initStaticData();\n        return jvmArgs;\n    }\n    \n    public String getJvmFlags() {\n        initStaticData();\n        return jvmFlags;\n    }\n    \n    public String getMainArgs() {\n        initStaticData();\n        return mainArgs;\n    }\n    \n    public String getMainClass() {\n        initStaticData();\n        return mainClass;\n    }\n    \n    public String getVmVersion() {\n        initStaticData();\n        return vmVersion;\n    }\n\n    public String getJavaVersion() {\n        initStaticData();\n        if (javaVersion != null) {\n            return javaVersion;\n        }\n        return vmVersion;\n    }\n    \n    public String getJavaHome() {\n        initStaticData();\n        return javaHome;\n    }\n    \n    public String getVmInfo() {\n        initStaticData();\n        return vmInfo;\n    }\n    \n    public String getVmName() {\n        initStaticData();\n        return vmName;\n    }\n    \n    public String getVmVendor() {\n        initStaticData();\n        return vmVendor;\n    }\n    \n    public boolean is14() {\n        String ver = getVmVersion();\n        if (ver != null && ver.startsWith(\"1.4.\")) {    // NOI18N\n            return true;\n        }\n        return false;\n    }\n    \n    public boolean is15() {\n        String ver = getJavaVersion();\n        if (ver != null && ver.startsWith(\"1.5.\")) {    // NOI18N\n            return true;\n        }\n        return false;\n    }\n    \n    public boolean is16() {\n        String ver = getJavaVersion();\n        if (ver != null) {\n            if (ver.startsWith(\"1.6.\")) {    // NOI18N\n                return true;\n            }\n            // HotSpot Express, only vmVersion available\n            if (javaVersion == null && (ver.startsWith(\"10.\") || ver.startsWith(\"11.\"))) {  // NOI18N\n                return true;\n            }\n        }\n        return false;\n    }\n    \n    public boolean is17() {\n        String ver = getJavaVersion();\n        if (ver != null) {\n            if (ver.startsWith(\"1.7.\")) {    // NOI18N\n                return true;\n            }\n            // HotSpot Express, only vmVersion available\n            if (javaVersion == null && (ver.startsWith(\"12.\") || ver.startsWith(\"13.\") || ver.startsWith(\"14.\"))) { // NOI18N\n                return true;\n            }\n        }\n        return false;\n    }\n    \n    public boolean is18() {\n        String ver = getJavaVersion();\n        if (ver != null && ver.startsWith(\"1.8.\")) {\n            return true;\n        }\n        return false;\n    }\n    \n    public boolean is19() {\n        String ver = getJavaVersion();\n        if (ver != null && javaVersion != null && (ver.startsWith(\"1.9.\") || (ver.equals(\"9\")) || (ver.startsWith(\"9.\")))) {    // NOI18N\n            return true;\n        }\n        return false;\n    }\n    \n    public boolean is100() {\n        String ver = getJavaVersion();\n        if (ver != null && javaVersion != null && (ver.equals(\"10\") || ver.startsWith(\"10.\"))) {    // NOI18N\n            return true;\n        }\n        return false;\n    }\n\n    public boolean is110() {\n        String ver = getJavaVersion();\n        if (ver != null && javaVersion != null && (ver.equals(\"11\") || ver.equals(\"11-ea\") || ver.startsWith(\"11.\"))) {    // NOI18N\n            return true;\n        }\n        return false;\n    }\n\n    public boolean isDumpOnOOMEnabled() {\n        if (isDumpOnOOMEnabled == null) {\n            AttachModel attach = getAttach();\n            String args = null;\n            if (attach != null) {\n                args = attach.printFlag(HEAP_DUMP_ON_OOME);\n            }\n            if (args == null) {\n                JmxModel jmx = getJmxModel();\n                if (jmx != null && jmx.isTakeHeapDumpSupported()) {\n                    String value = jmx.getFlagValue(HEAP_DUMP_ON_OOME);\n                    isDumpOnOOMEnabled = Boolean.valueOf(value);\n                    return isDumpOnOOMEnabled.booleanValue();\n                }\n            }\n            if (args == null && monitoredVm != null) {\n                args = getJvmFlags().concat(getJvmArgs());\n            }\n            if (args != null && args.contains(\"-XX:+\"+HEAP_DUMP_ON_OOME)) { // NOI18N\n                isDumpOnOOMEnabled = Boolean.TRUE;\n            } else {\n                isDumpOnOOMEnabled = Boolean.FALSE;\n            }\n        }\n        return isDumpOnOOMEnabled.booleanValue();\n    }\n    \n    public void addMonitoredDataListener(MonitoredDataListener l) {\n        synchronized (listeners) {\n            if (listeners.add(l)) {\n                if (monitoredVm != null) {\n                    jmxSupport.disableTimer();\n                    monitoredVm.addJvmstatListener(this);\n                } else {\n                    jmxSupport.initTimer();\n                }\n            }\n        }\n    }\n    \n    public void removeMonitoredDataListener(MonitoredDataListener l) {\n        synchronized (listeners) {\n            if (listeners.remove(l)) {\n                if (listeners.isEmpty()) {\n                    if (monitoredVm != null) {\n                        monitoredVm.removeJvmstatListener(this);\n                    } else {\n                        jmxSupport.disableTimer();\n                    }\n                }\n            }\n        }\n    }\n    \n    public String[] getGenName() {\n        if (jvmstatModel != null) {\n            return jvmstatModel.getGenName();\n        }\n        return jmxSupport.getGenName();\n    }\n\n    public boolean isMonitoringSupported() {\n        return isClassMonitoringSupported() || isThreadMonitoringSupported() || isMemoryMonitoringSupported();\n    }\n    \n    public boolean isClassMonitoringSupported() {\n        return monitoredVm != null || jmxSupport.getRuntime() != null;\n    }\n    \n    public boolean isThreadMonitoringSupported() {\n        return (!is14() && monitoredVm != null) || jmxSupport.getRuntime() != null;\n    }\n    \n    public boolean isMemoryMonitoringSupported() {\n        return monitoredVm != null || jmxSupport.getRuntime() != null;\n    }\n    \n    public boolean isGetSystemPropertiesSupported() {\n        return getAttach() != null || jmxSupport.getRuntime() != null || getSAAgent() != null;\n    }\n    \n    public Properties getSystemProperties() {\n        AttachModel attach = getAttach();\n        Properties prop = null;\n        \n        if (attach != null) {\n            prop = attach.getSystemProperties();\n        }\n        if (prop != null)\n            return prop;\n        JmxModel jmx = getJmxModel();\n        if (jmx != null) {\n            prop = jmx.getSystemProperties();\n        }\n        if (prop != null) {\n            return prop;\n        }\n        SaModel saAgent = getSAAgent();\n        if (saAgent != null) {\n            return saAgent.getSystemProperties();\n        }\n        if (!isGetSystemPropertiesSupported()) {\n            throw new UnsupportedOperationException();\n        }\n        return null;\n    }\n    \n    public boolean isDumpOnOOMEnabledSupported() {\n        if (!application.isLocalApplication()) {\n            return false;\n        }\n        if (getAttach() != null) {\n            return true;\n        }\n        JmxModel jmx = getJmxModel();\n        if (jmx != null && jmx.isTakeHeapDumpSupported()) {\n            return true;\n        }\n        return false;\n    }\n    \n    public synchronized void setDumpOnOOMEnabled(boolean enabled) {\n        if (!isDumpOnOOMEnabledSupported()) {\n            throw new UnsupportedOperationException();\n        }\n        AttachModel attach = getAttach();\n        if (attach!=null) {\n            attach.setFlag(HEAP_DUMP_ON_OOME,enabled?\"1\":\"0\");  // NOI18N\n            if (enabled) {\n                attach.setFlag(HEAP_DUMP_PATH,application.getStorage().getDirectory().getAbsolutePath());\n            }\n        } else {\n            JmxModel jmx = getJmxModel();\n            jmx.setFlagValue(HEAP_DUMP_ON_OOME,Boolean.toString(enabled));\n            if (enabled) {\n                jmx.setFlagValue(HEAP_DUMP_PATH,application.getStorage().getDirectory().getAbsolutePath());\n            }\n        }\n        Boolean oldVlue = isDumpOnOOMEnabled;\n        isDumpOnOOMEnabled = Boolean.valueOf(enabled);\n        firePropertyChange(PROPERTY_DUMP_OOME_ENABLED,oldVlue,isDumpOnOOMEnabled);\n    }\n    \n    public boolean isTakeHeapDumpSupported() {\n        if (getAttach() != null) {\n            return true;\n        }\n        JmxModel jmx = getJmxModel();\n        if (application.isLocalApplication() && jmx != null && jmx.isTakeHeapDumpSupported()) {\n            return true;\n        }\n        return false;\n    }\n    \n    public boolean takeHeapDump(File dumpFile) {\n        if (!isTakeHeapDumpSupported()) {\n            throw new UnsupportedOperationException();\n        }\n        AttachModel attach = getAttach();\n        if (attach != null) {\n            if (attach.takeHeapDump(dumpFile.getAbsolutePath())) {\n                return true;\n            }\n        }\n        if (getJmxModel().takeHeapDump(dumpFile.getAbsolutePath())) {\n            return true;\n        }\n        return false;\n    }\n    \n    public boolean isTakeThreadDumpSupported() {\n        if (getAttach() != null) {\n            return true;\n        }\n        JmxModel jmx = getJmxModel();\n        if (jmx != null && jmx.isTakeThreadDumpSupported()) {\n            return true;\n        }\n        return getSAAgent() != null;\n    }\n    \n    public String takeThreadDump() {\n        AttachModel attach = getAttach();\n        String threadDump = null;\n        \n        if (attach != null) {\n            threadDump = attach.takeThreadDump();\n        }\n        if (threadDump == null) {\n            JmxModel jmx = getJmxModel();\n            if (jmx != null) {\n                threadDump = jmx.takeThreadDump();\n            }\n        }\n        if (threadDump == null) {\n            SaModel sa = getSAAgent();\n            if (sa != null) {\n                threadDump = sa.takeThreadDump();\n            }\n        }\n        if (threadDump == null) {\n            if (!isTakeThreadDumpSupported()) {\n                throw new UnsupportedOperationException();\n            }\n            threadDump = NbBundle.getMessage(JVMImpl.class, \"MSG_ThreadDumpfailed\");   // NOI18N\n        }\n        return threadDump;\n    }\n\n    public HeapHistogram takeHeapHistogram() {\n        AttachModel attach = getAttach();\n        HeapHistogram histogram = null;\n        \n        if (attach != null) {\n            histogram = attach.takeHeapHistogram();\n        }\n        if (histogram == null) {\n            JmxModel jmx = getJmxModel();\n            if (jmx != null) {\n                histogram = jmx.takeHeapHistogram();\n            }\n        }\n        return histogram;\n    }\n    \n    public boolean isCpuMonitoringSupported() {\n        return jmxSupport.hasProcessCPUTimeAttribute();\n    }\n    \n    public boolean isCollectionTimeSupported() {\n        Collection<?> gcList = jmxSupport.getGarbageCollectorMXBeans();\n        return gcList != null && !gcList.isEmpty();\n    }\n    \n    @Override\n    public int getAvailableProcessors() {\n        int processors = jmxSupport.getAvailableProcessors();\n\n        if (processors != -1) {\n            return processors;\n        }\n        return super.getAvailableProcessors();\n    }\n\n    public boolean isJfrAvailable() {\n        return JfrModelFactory.getJFRFor(application) != null;\n    }\n\n    public List<Long> jfrCheck() {\n        JfrModel jfrModel = JfrModelFactory.getJFRFor(application);\n        if (jfrModel != null) {\n            return jfrModel.jfrCheck();\n        }\n        return Collections.emptyList();\n    }\n\n    public String takeJfrDump(long recording, String fileName) {\n        JfrModel jfrModel = JfrModelFactory.getJFRFor(application);\n        if (jfrModel != null) {\n            return jfrModel.takeJfrDump(recording, fileName);\n        }\n        return null;\n    }\n\n    public boolean startJfrRecording(String name, String[] settings, String delay,\n            String duration, Boolean disk, String path, String maxAge, String maxSize,\n            Boolean dumpOnExit) {\n        JfrModel jfrModel = JfrModelFactory.getJFRFor(application);\n        if (jfrModel != null) {\n            return jfrModel.startJfrRecording(name, settings, delay, duration, disk,\n                    path, maxAge, maxSize, dumpOnExit);\n        }\n        return false;\n    }\n\n    public boolean stopJfrRecording() {\n        JfrModel jfrModel = JfrModelFactory.getJFRFor(application);\n        if (jfrModel != null) {\n            return jfrModel.stopJfrRecording();\n        }\n        return false;\n    }\n\n    public MonitoredData getMonitoredData() {     \n        if (application.getState() == Stateful.STATE_AVAILABLE) {\n            if (monitoredVm != null) {\n                return new MonitoredDataImpl(this, jvmstatModel,jmxSupport);\n            } else {\n                JvmMXBeans jmx = jmxSupport.getJvmMXBeans();\n                if (jmx != null) {\n                    return new MonitoredDataImpl(this, jmxSupport,jmx);\n                }\n            }\n        }\n        return null;\n    }\n    \n    protected AttachModel getAttach() {\n        return AttachModelFactory.getAttachFor(application);\n    }\n    \n    protected SaModel getSAAgent() {\n        return SaModelFactory.getSAAgentFor(application);\n    }\n    \n    protected JmxModel getJmxModel() {\n        return JmxModelFactory.getJmxModelFor(application);\n    }\n    \n    protected void initStaticData() {\n        synchronized (staticDataLock) {\n            if (staticDataInitialized) {\n                return;\n            }\n            if (jvmstatModel != null) {\n                commandLine = jvmstatModel.getCommandLine();\n                jvmArgs = getJvmArgsJvmstat();\n                jvmFlags = jvmstatModel.getJvmFlags();\n                mainArgs = jvmstatModel.getMainArgs();\n                mainClass = jvmstatModel.getMainClass();\n                vmVersion = jvmstatModel.getVmVersion();\n                javaVersion = jvmstatModel.getJavaVersion();\n                javaHome = jvmstatModel.getJavaHome();\n                vmInfo = jvmstatModel.getVmInfo();\n                vmName = jvmstatModel.getVmName();\n                vmVendor = jvmstatModel.getVmVendor();\n            } else {\n                JmxModel jmxModel = getJmxModel();\n                jvmArgs = jmxSupport.getJvmArgs();\n                Properties prop = jmxModel.getSystemProperties();\n                if (prop != null) {\n                    vmVersion = prop.getProperty(\"java.vm.version\");    // NOI18N\n                    javaVersion = prop.getProperty(\"java.version\");    // NOI18N\n                    javaHome = prop.getProperty(\"java.home\");   // NOI18N\n                    vmInfo = prop.getProperty(\"java.vm.info\");  // NOI18N\n                    vmName = prop.getProperty(\"java.vm.name\");  // NOI18N\n                    vmVendor = prop.getProperty(\"java.vm.vendor\");  // NOI18N\n                }\n                commandLine = jmxModel.getCommandLine();\n                mainArgs = jmxModel.getMainArgs();\n                mainClass = jmxModel.getMainClass();\n           }\n            staticDataInitialized = true;\n        }\n    }\n    \n    private String getJvmArgsJvmstat() {\n        String args = jvmstatModel.getJvmArgs();\n        if (args != null && args.length() == 1024) {\n            String longArgs = null;\n            AttachModel attach = getAttach();\n            if (attach != null) {\n                longArgs = attach.getJvmArgs();\n            }\n            if (longArgs == null) {\n                longArgs = jmxSupport.getJvmArgs();\n            }\n            if (longArgs == null) {\n                SaModel sa = getSAAgent();\n                if (sa != null) {\n                    longArgs = sa.getJvmArgs();\n                }\n            }\n            if (longArgs != null && longArgs.length() > 1024) {\n                args = longArgs;\n            }\n        }\n        return args;\n    }\n    \n    public void dataChanged(JvmstatModel stat) {\n        assert stat == monitoredVm;\n        MonitoredData data = new MonitoredDataImpl(this, jvmstatModel,jmxSupport);\n        notifyListeners(data);        \n    }\n\n    void notifyListeners(final MonitoredData data) {\n        List<MonitoredDataListener> listenersCopy;\n        synchronized (listeners) {\n            listenersCopy = new ArrayList<>(listeners);\n        }\n        for (MonitoredDataListener listener : listenersCopy) {\n            listener.monitoredDataEvent(data);\n        }        \n    }\n\n}\n"
  },
  {
    "path": "visualvm/jvm/src/org/graalvm/visualvm/jvm/JmxSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvm;\n\nimport java.lang.management.GarbageCollectorMXBean;\nimport java.lang.management.ManagementFactory;\nimport java.lang.management.MemoryPoolMXBean;\nimport java.lang.management.MemoryType;\nimport java.lang.management.OperatingSystemMXBean;\nimport java.lang.management.RuntimeMXBean;\nimport java.lang.reflect.UndeclaredThrowableException;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Timer;\nimport java.util.TimerTask;\nimport java.util.logging.Logger;\nimport javax.management.MBeanAttributeInfo;\nimport javax.management.MBeanInfo;\nimport javax.management.MBeanServerConnection;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModel.ConnectionState;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JmxSupport implements DataRemovedListener<Application> {\n    private final static Logger LOGGER = Logger.getLogger(JmxSupport.class.getName());\n    private static final String PROCESS_CPU_TIME_ATTR = \"ProcessCpuTime\"; // NOI18N\n\n    /** IBM/OpenJ9 only. */\n    private static final String PROCESS_CPU_TIME_NS_ATTR = \"ProcessCpuTimeByNS\"; // NOI18N\n\n    /**\n     * IBM/OpenJ9 only.\n     * Returns the collective processing capacity available to the VM\n     * in units of 1% of a physical processor. In environments without\n     * some kind of virtual partitioning, this will simply be the number\n     * of CPUs * 100.\n     */\n    private static final String PROCESSING_CAPACITY_ATTR = \"ProcessingCapacity\"; // NOI18N\n    private static final String PERM_GEN = \"Perm Gen\";  // NOI18N\n    private static final String PS_PERM_GEN = \"PS Perm Gen\";    // NOI18N\n    private static final String CMS_PERM_GEN = \"CMS Perm Gen\";    // NOI18N\n    private static final String G1_PERM_GEN = \"G1 Perm Gen\";    // NOI18N\n    private static final String METASPACE = \"Metaspace\";       // NOI18N\n    private static final String IBM_PERM_GEN = \"class storage\";    // NOI18N\n    private static final ObjectName osName = getOSName();\n    private static long INITIAL_DELAY = 100;\n\n    private Application application;\n    private JVMImpl jvm;\n    private final Object processCPUTimeAttributeLock = new Object();\n    private Boolean processCPUTimeAttribute;\n    private double processingCapacity;\n    private Timer timer;\n    private MemoryPoolMXBean permGenPool;\n    private Collection<GarbageCollectorMXBean> gcList;\n    private String[] genName;\n    private String processCpuTimeAttr;\n\n    JmxSupport(Application app, JVMImpl vm) {\n        jvm = vm;\n        application = app;\n        app.notifyWhenRemoved(this);\n    }\n\n    RuntimeMXBean getRuntime() {\n        JvmMXBeans jmx = getJvmMXBeans();\n        if (jmx != null) {\n            return jmx.getRuntimeMXBean();\n        }\n        return null;\n    }\n\n    boolean hasProcessCPUTimeAttribute() {\n        synchronized (processCPUTimeAttributeLock) {\n            if (processCPUTimeAttribute != null) {\n                return processCPUTimeAttribute.booleanValue();\n            }\n            processCPUTimeAttribute = Boolean.FALSE;\n            JmxModel jmx = JmxModelFactory.getJmxModelFor(application);\n           \n            if (jmx != null && jmx.getConnectionState().equals(ConnectionState.CONNECTED)) {\n                MBeanServerConnection conn = jmx.getMBeanServerConnection();\n                \n                if (conn != null) {\n                    try {\n                       MBeanInfo info = conn.getMBeanInfo(osName);\n                       MBeanAttributeInfo[] attrs = info.getAttributes();\n                       \n                       processingCapacity = 1;\n                       for (MBeanAttributeInfo attr : attrs) {\n                           String name = attr.getName();\n                           if (PROCESS_CPU_TIME_ATTR.equals(name) && !processCPUTimeAttribute) {\n                               processCPUTimeAttribute = Boolean.TRUE;\n                               processCpuTimeAttr = name;\n                           }\n                           if (PROCESS_CPU_TIME_NS_ATTR.equals(name)) {\n                               processCPUTimeAttribute = Boolean.TRUE;\n                               processCpuTimeAttr = name;\n                           }\n                           if (PROCESSING_CAPACITY_ATTR.equals(name)) {\n                               Number mul = (Number) conn.getAttribute(osName,PROCESSING_CAPACITY_ATTR);\n                               processingCapacity = mul.longValue()/100.0/getAvailableProcessors();\n                           }\n                        }\n                    } catch (Exception ex) {\n                       LOGGER.throwing(JmxSupport.class.getName(), \"hasProcessCPUTimeAttribute\", ex); // NOI18N\n                    }\n                }\n            }\n            return processCPUTimeAttribute.booleanValue();\n        }\n    }\n     \n    long getProcessCPUTime() {\n        if (!hasProcessCPUTimeAttribute()) {\n            throw new UnsupportedOperationException();\n        }\n        JmxModel jmx = JmxModelFactory.getJmxModelFor(application);\n        \n        if (jmx != null && jmx.getConnectionState().equals(ConnectionState.CONNECTED)) {\n           MBeanServerConnection conn = jmx.getMBeanServerConnection();\n            \n           if (conn != null) {\n                try {\n                    Long cputime = (Long)conn.getAttribute(osName,processCpuTimeAttr);\n                    \n                    return (long)(cputime.longValue()/processingCapacity);\n                } catch (Exception ex) {\n                    LOGGER.throwing(JmxSupport.class.getName(), \"hasProcessCPUTimeAttribute\", ex); // NOI18N\n                }\n            }\n        }\n        return -1;\n    }\n    \n    int getAvailableProcessors() {\n        JvmMXBeans jmx = getJvmMXBeans();\n        if (jmx != null) {\n            OperatingSystemMXBean osMXBean = jmx.getOperatingSystemMXBean();\n\n            if (osMXBean != null) {\n                return osMXBean.getAvailableProcessors();\n            }\n        }\n        return -1;\n    }\n\n    JvmMXBeans getJvmMXBeans() {\n        JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);\n        if (jmxModel != null && jmxModel.getConnectionState() == ConnectionState.CONNECTED) {\n            return jmxModel.getJvmMXBeans();\n        }\n        return null;\n    }\n    \n    synchronized Collection<GarbageCollectorMXBean> getGarbageCollectorMXBeans() {\n        if (gcList == null) {\n            JvmMXBeans jmx = getJvmMXBeans();\n            if (jmx != null) {\n                gcList = jmx.getGarbageCollectorMXBeans();\n            }           \n        }\n        return gcList;\n    }\n\n    String getJvmArgs() {\n        try {\n            RuntimeMXBean runtime = getRuntime();\n            if (runtime != null) {\n                StringBuilder buf = new StringBuilder();\n                List<String> args = runtime.getInputArguments();\n                for (String arg : args) {\n                    buf.append(arg).append(' ');\n                }\n                return buf.toString().trim();\n            }\n            return null;\n        } catch (Exception e) {\n            LOGGER.throwing(JmxSupport.class.getName(), \"getJvmArgs\", e); // NOI18N\n            return null;\n        }\n    }\n\n    MemoryPoolMXBean getPermGenPool() {\n        try {\n            if (permGenPool == null) {\n                JvmMXBeans jmx = getJvmMXBeans();\n                if (jmx != null) {\n                    Collection<MemoryPoolMXBean> pools = jmx.getMemoryPoolMXBeans();\n                    for (MemoryPoolMXBean pool : pools) {\n                        MemoryType type = pool.getType();\n                        String name = pool.getName();\n                        if (MemoryType.NON_HEAP.equals(type) &&\n                                (PERM_GEN.equals(name) ||\n                                PS_PERM_GEN.equals(name) ||\n                                CMS_PERM_GEN.equals(name) ||\n                                G1_PERM_GEN.equals(name) ||\n                                METASPACE.equals(name) ||\n                                IBM_PERM_GEN.equals(name))) {\n                            permGenPool = pool;\n                            break;\n                        }\n                    }\n                }\n            }\n            return permGenPool;\n        } catch (Exception e) {\n            LOGGER.throwing(JmxSupport.class.getName(), \"getPermGenPool\", e); // NOI18N\n            return null;\n        }\n    }\n\n    String[] getGenName() {\n        if (genName == null) {\n            MemoryPoolMXBean permPool = getPermGenPool();\n            initGenName();\n            if (permPool != null) {\n                String label;\n                String name = permPool.getName();\n                if (METASPACE.equals(name)) {\n                    label = NbBundle.getMessage(JmxSupport.class, \"LBL_Meta\"); // NOI18N                    \n                } else {\n                    label = NbBundle.getMessage(JmxSupport.class, \"LBL_PermGen\"); // NOI18N\n                }\n                genName[1] = label;\n            }\n        }\n        return genName;\n    }\n\n    void initGenName() {\n        genName = new String[2];\n        genName[0] = NbBundle.getMessage(JmxSupport.class, \"LBL_Heap\");   // NOI18N\n        genName[1] = NbBundle.getMessage(JmxSupport.class, \"LBL_NA\");   // NOI18N        \n    }\n    \n    void initTimer() {\n        int interval = GlobalPreferences.sharedInstance().getMonitoredDataPoll() * 1000;\n        final JvmMXBeans jmx = getJvmMXBeans();\n        if (jmx != null) {\n            TimerTask task = new TimerTask() {\n                public void run() {\n                    if (application.getState() == Stateful.STATE_AVAILABLE) try {\n                        MonitoredData data = new MonitoredDataImpl(jvm, JmxSupport.this, jmx);\n                        jvm.notifyListeners(data);\n                    } catch (UndeclaredThrowableException e) {\n                        LOGGER.throwing(JmxSupport.class.getName(), \"MonitoredDataImpl<init>\", e); // NOI18N\n                    }\n                }\n            };\n            disableTimer();\n            timer = new Timer(\"JMX MonitoredData timer for \"+application.getId());       // NOI18N\n            timer.schedule(task,INITIAL_DELAY,interval);\n        }\n    }\n\n    void disableTimer() {\n        if (timer != null) {\n            timer.cancel();\n        }\n    }\n\n    private static ObjectName getOSName() {\n        try {\n            return new ObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME);\n        } catch (MalformedObjectNameException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n    \n    public void dataRemoved(Application dataSource) {\n        disableTimer();\n    }\n}\n"
  },
  {
    "path": "visualvm/jvm/src/org/graalvm/visualvm/jvm/JvmProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvm;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JvmProvider extends AbstractModelProvider<Jvm, Application> {\n\n    public Jvm createModelFor(Application app) {\n        JvmstatModel jvmstat = JvmstatModelFactory.getJvmstatFor(app);\n        JVMImpl jvm = null;\n        if (jvmstat != null) {\n            jvm = new JVMImpl(app, jvmstat);\n        } else {\n            JmxModel jmxModel = JmxModelFactory.getJmxModelFor(app);\n            if (jmxModel != null && jmxModel.getConnectionState() == JmxModel.ConnectionState.CONNECTED) {\n                JvmMXBeans jmx = jmxModel.getJvmMXBeans();\n                if (jmx != null && jmx.getRuntimeMXBean() != null) {\n                    jvm = new JVMImpl(app);\n                }\n            }\n        }\n        return jvm;\n    }\n}\n"
  },
  {
    "path": "visualvm/jvm/src/org/graalvm/visualvm/jvm/MonitoredDataImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvm;\n\n\nimport java.lang.management.ClassLoadingMXBean;\nimport java.lang.management.GarbageCollectorMXBean;\nimport java.lang.management.MemoryPoolMXBean;\nimport java.lang.management.MemoryUsage;\nimport java.lang.management.RuntimeMXBean;\nimport java.lang.management.ThreadMXBean;\nimport java.util.Collection;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.MonitoredData;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass MonitoredDataImpl extends MonitoredData {\n  private final static Logger LOGGER = Logger.getLogger(MonitoredDataImpl.class.getName());\n\n  private MonitoredDataImpl(Jvm jvm, JmxSupport jmxSupport) {\n    monitoredVm = jvm;\n    try {\n        Collection<GarbageCollectorMXBean> gcList = jmxSupport.getGarbageCollectorMXBeans();\n\n        if (jmxSupport.hasProcessCPUTimeAttribute()) {\n            processCpuTime = jmxSupport.getProcessCPUTime();\n        }\n        if (gcList != null && !gcList.isEmpty()) {\n            for (GarbageCollectorMXBean gcBean : gcList) {\n                collectionTime+=gcBean.getCollectionTime();\n            }\n        }\n    } catch (Exception ex) {\n        LOGGER.throwing(MonitoredDataImpl.class.getName(), \"MonitoredDataImpl.<init>\", ex); // NOI18N\n    }\n  }\n  \n  MonitoredDataImpl(Jvm jvm, JvmJvmstatModel jvmstatModel,JmxSupport jmxSupport) {\n    this(jvm, jmxSupport);\n    loadedClasses = jvmstatModel.getLoadedClasses();\n    sharedLoadedClasses = jvmstatModel.getSharedLoadedClasses();\n    sharedUnloadedClasses = jvmstatModel.getSharedUnloadedClasses();\n    unloadedClasses = jvmstatModel.getUnloadedClasses();\n    threadsDaemon = jvmstatModel.getThreadsDaemon();\n    threadsLive = jvmstatModel.getThreadsLive();\n    threadsLivePeak = jvmstatModel.getThreadsLivePeak();\n    threadsStarted = jvmstatModel.getThreadsStarted();\n    applicationTime = jvmstatModel.getApplicationTime()/(jvmstatModel.getOsFrequency()/1000);\n    upTime = jvmstatModel.getUpTime()/(jvmstatModel.getOsFrequency()/1000);\n    genCapacity = jvmstatModel.getGenCapacity();\n    genUsed = jvmstatModel.getGenUsed();\n    genMaxCapacity = jvmstatModel.getGenMaxCapacity();\n  }\n\n  MonitoredDataImpl(Jvm jvm, JmxSupport jmxSupport,JvmMXBeans jmxModel) {\n    this(jvm, jmxSupport);\n    RuntimeMXBean runtimeBean = jmxModel.getRuntimeMXBean();\n    upTime = runtimeBean.getUptime();\n    ClassLoadingMXBean classBean = jmxModel.getClassLoadingMXBean();\n    ThreadMXBean threadBean = jmxModel.getThreadMXBean();\n    MemoryUsage mem = jmxModel.getMemoryMXBean().getHeapMemoryUsage();\n    MemoryPoolMXBean permBean = jmxSupport.getPermGenPool();\n    unloadedClasses = classBean.getUnloadedClassCount();\n    loadedClasses = classBean.getLoadedClassCount() + unloadedClasses;\n    sharedLoadedClasses = 0;\n    sharedUnloadedClasses = 0;\n    threadsDaemon = threadBean.getDaemonThreadCount();\n    threadsLive = threadBean.getThreadCount();\n    threadsLivePeak = threadBean.getPeakThreadCount();\n    threadsStarted = threadBean.getTotalStartedThreadCount();\n    applicationTime = 0;\n    genCapacity = new long[2];\n    genUsed = new long[2];\n    genMaxCapacity = new long[2];\n    genCapacity[0] = mem.getCommitted();\n    genUsed[0] = mem.getUsed();\n    genMaxCapacity[0] = mem.getMax();\n    if (permBean != null) {\n        MemoryUsage perm = permBean.getUsage();\n        genCapacity[1] = perm.getCommitted();\n        genUsed[1] = perm.getUsed();\n        genMaxCapacity[1] = perm.getMax();\n    }\n  }\n}\n"
  },
  {
    "path": "visualvm/jvmstat/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.jvmstat\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.jvmstat.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/jvmstat/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.jvmstat/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/jvmstat/resources/layer.xml\nOpenIDE-Module-Install: org/graalvm/visualvm/jvmstat/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/jvmstat/Bundle.properties\nOpenIDE-Module-Provides: org.graalvm.visualvm.jvmstat\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "visualvm/jvmstat/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.jvmstat-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/jvmstat/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=96920afa\nbuild.xml.script.CRC32=f21b0e21\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=96920afa\nnbproject/build-impl.xml.script.CRC32=c0e9022d\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/jvmstat/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\ncp.extra=${tools.jar}\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nmodule.javadoc.packages=org.graalvm.visualvm.jvmstat\n\n"
  },
  {
    "path": "visualvm/jvmstat/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.jvmstat</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.8.1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.5.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/jvmstat/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Jvmstat\n\nLBL_Meta=Metaspace\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport org.graalvm.visualvm.jvmstat.application.JvmstatApplicationProvider;\nimport org.graalvm.visualvm.jvmstat.application.PropertiesImpl;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory;\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\npublic class Installer extends ModuleInstall {\n    \n    public void restored() {\n        JvmJvmstatModelFactory factory = JvmJvmstatModelFactory.getDefault();\n        \n        JvmstatModelFactory.getDefault().registerProvider(new JvmstatModelProvider());\n        factory.registerProvider(new JvmJvmstatModelProvider());\n        factory.registerProvider(new JRockitJvmJvmstatModelProvider());\n        factory.registerProvider(new OracleJRockitJvmJvmstatModelProvider());\n        JvmstatApplicationProvider.register();\n        PropertiesImpl.initialize();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/JRockitJvmJvmstatModel.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.MonitoredValue;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JRockitJvmJvmstatModel extends JvmJvmstatModel {\n    private static final String PERM_GEN_PREFIX = \"bea.cls.memory.\";    // NOI18N\n    \n    JRockitJvmJvmstatModel(Application app,JvmstatModel stat) {\n        super(app,stat);\n        initMonitoredVales();\n    }\n    \n    private void initMonitoredVales() {\n        loadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.loadedClasses\"); // NOI18N\n        sharedLoadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.sharedLoadedClasses\"); // NOI18N\n        sharedUnloadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.sharedUnloadedClasses\"); // NOI18N\n        unloadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.unloadedClasses\"); // NOI18N\n        threadsDaemon = jvmstat.findMonitoredValueByName(\"java.threads.daemon\");    // NOI18N\n        threadsLive = jvmstat.findMonitoredValueByName(\"java.threads.live\");    // NOI18N\n        threadsLivePeak = jvmstat.findMonitoredValueByName(\"java.threads.livePeak\");    // NOI18N\n        threadsStarted = jvmstat.findMonitoredValueByName(\"java.threads.started\");  // NOI18N\n        applicationTime = jvmstat.findMonitoredValueByName(\"sun.rt.applicationTime\");   // NOI18N\n        upTime = jvmstat.findMonitoredValueByName(\"bea.rt.ticks\");  // NOI18N\n        MonitoredValue osFrequencyMon = jvmstat.findMonitoredValueByName(\"bea.rt.counterFrequency\");    // NOI18N\n        osFrequency = getLongValue(osFrequencyMon);\n        genCapacity = jvmstat.findMonitoredValueByPattern(\"bea.((gc.heap)|(cls.memory)).committed\");    // NOI18N\n        genUsed = jvmstat.findMonitoredValueByPattern(\"bea.((gc.heap)|(gc.nursery)|(cls.memory)).used\");    // NOI18N\n        genMaxCapacity=getGenerationSum(jvmstat.findMonitoredValueByPattern(\"bea.((gc.heap)|(cls.memory)).max\"));   // NOI18N\n    }\n    \n    protected String getPermGenPrefix() {\n        return PERM_GEN_PREFIX;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/JRockitJvmJvmstatModelProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class JRockitJvmJvmstatModelProvider extends JvmJvmstatModelProvider {\n    \n    public JvmJvmstatModel createModelFor(Application app) {\n        JvmstatModel jvmstat = JvmstatModelFactory.getJvmstatFor(app);\n        if (jvmstat != null) {\n            String vmName = jvmstat.findByName(\"java.property.java.vm.name\");   // NOI18N\n            \n            if (\"BEA JRockit(R)\".equals(vmName)) {  // NOI18N\n                JRockitJvmJvmstatModel jvm = null;\n                String vmVersion = jvmstat.findByName(\"java.property.java.vm.version\"); // NOI18N\n                \n                if (vmVersion != null) {\n                    if (vmVersion.contains(\"1.6.0\")) {  // NOI18N\n                        jvm = new JRockitJvmJvmstatModel(app,jvmstat);\n                    } else {\n                        jvm = new JRockitJvmJvmstatModel(app,jvmstat);\n                    }\n                }\n                return jvm;\n            }\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/JvmJvmstatModelProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class JvmJvmstatModelProvider extends AbstractModelProvider<JvmJvmstatModel, Application> {\n    private final static Logger LOGGER = Logger.getLogger(JvmJvmstatModelProvider.class.getName());\n    \n    public JvmJvmstatModel createModelFor(Application app) {\n        JvmstatModel jvmstat = JvmstatModelFactory.getJvmstatFor(app);\n        if (jvmstat != null) {\n\n            JvmJvmstatModel model = null;\n            // Check for Sun/Oracle VM (and maybe other?)\n            // try java.property.java.version from HotSpot Express 14.0\n            String javaVersion = jvmstat.findByName(\"java.property.java.version\"); // NOI18N\n\n            if (javaVersion != null) {\n                // JVM 1.6\n                if (javaVersion.startsWith(\"1.6.\")) model = new JvmJvmstatModel_5(app,jvmstat); // NOI18N\n                // JVM 1.7\n                else if (javaVersion.startsWith(\"1.7.\")) model = new JvmJvmstatModel_5(app,jvmstat); // NOI18N\n                // JVM 1.8\n                else if (javaVersion.startsWith(\"1.8.\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 1.9\n                else if (javaVersion.startsWith(\"1.9.\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 9\n                else if (isJavaVersion(javaVersion, \"9\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 10\n                else if (isJavaVersion(javaVersion,\"10\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 11\n                else if (isJavaVersion(javaVersion,\"11\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 12\n                else if (isJavaVersion(javaVersion,\"12\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 13\n                else if (isJavaVersion(javaVersion,\"13\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 14\n                else if (isJavaVersion(javaVersion,\"14\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 15\n                else if (isJavaVersion(javaVersion,\"15\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 16\n                else if (isJavaVersion(javaVersion,\"16\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 17\n                else if (isJavaVersion(javaVersion,\"17\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 18\n                else if (isJavaVersion(javaVersion,\"18\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 19\n                else if (isJavaVersion(javaVersion,\"19\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 20\n                else if (isJavaVersion(javaVersion,\"20\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 21\n                else if (isJavaVersion(javaVersion,\"21\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 22\n                else if (isJavaVersion(javaVersion,\"22\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 23\n                else if (isJavaVersion(javaVersion,\"23\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 24\n                else if (isJavaVersion(javaVersion,\"24\")) model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                // JVM 25\n                else if (isJavaVersion(javaVersion,\"25\")) model = new JvmJvmstatModel_25(app,jvmstat); // NOI18N\n            }\n            \n            if (model == null) {\n                String vmVersion = jvmstat.findByName(\"java.property.java.vm.version\"); // NOI18N\n\n                // JVM 1.4\n                if (vmVersion.startsWith(\"1.4.\")) model = new JvmJvmstatModel_4(app,jvmstat); // NOI18N\n\n                // JVM 1.5\n                else if (vmVersion.startsWith(\"1.5.\")) model = new JvmJvmstatModel_5(app,jvmstat); // NOI18N\n\n                // JVM 1.6\n                else if (vmVersion.startsWith(\"1.6.\")) model = new JvmJvmstatModel_5(app,jvmstat); // NOI18N\n\n                // JVM 1.7\n                else if (vmVersion.startsWith(\"1.7.\")) model = new JvmJvmstatModel_5(app,jvmstat); // NOI18N\n\n                // Hotspot Express\n                else if (vmVersion.startsWith(\"10.\")) model = new JvmJvmstatModel_5(app,jvmstat); // NOI18N\n                else if (vmVersion.startsWith(\"11.\")) model = new JvmJvmstatModel_5(app,jvmstat); // NOI18N\n                else if (vmVersion.startsWith(\"12.\")) model = new JvmJvmstatModel_5(app,jvmstat); // NOI18N\n                else if (vmVersion.startsWith(\"13.\")) model = new JvmJvmstatModel_5(app,jvmstat); // NOI18N\n                else if (vmVersion.startsWith(\"14.\")) model = new JvmJvmstatModel_5(app,jvmstat); // NOI18N\n\n                if (model == null) { // still not recognized, fallback to JvmJvmstatModel_8\n                    LOGGER.log(Level.WARNING, \"Unrecognized java.vm.version \" + vmVersion); // NOI18N\n                    model = new JvmJvmstatModel_8(app,jvmstat); // NOI18N\n                }\n            }\n            return model;\n        }\n        return null;\n    }\n    \n    private static boolean isJavaVersion(String javaVersionProperty, String releaseVersion) {\n        if (javaVersionProperty.equals(releaseVersion)) return true;\n        if (javaVersionProperty.equals(releaseVersion+\"-ea\")) return true;\n        if (javaVersionProperty.startsWith(releaseVersion+\".\")) return true;\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/JvmJvmstatModel_25.java",
    "content": "/*\n * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.MonitoredValue;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JvmJvmstatModel_25 extends JvmJvmstatModel {\n    private static final String PERM_GEN_PREFIX_META = \"sun.gc.metaspace.\";   // NOI18N\n    private static final String GC_TYPE_COUNTER_NAME = \"sun.gc.policy.name\";  // NOI18N\n    private static final String G1_NAME = \"GarbageFirst\";           // NOI18N\n    private static final String GC_COLLECTOR_COUNTER_NAME = \"sun.gc.collector.0.name\";  // NOI18N\n    private static final String GENERATIONAL_ZGC_NAME = \"ZGC minor collection pauses\"; // NOI18N\n\n    private long startup;\n\n    JvmJvmstatModel_25(Application app,JvmstatModel stat) {\n        super(app,stat);\n        initMonitoredVales();\n    }\n\n    private void initMonitoredVales() {\n      loadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.loadedClasses\");   // NOI18N\n      sharedLoadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.sharedLoadedClasses\");   // NOI18N\n      sharedUnloadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.sharedUnloadedClasses\");   // NOI18N\n      unloadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.unloadedClasses\");   // NOI18N\n      threadsDaemon = jvmstat.findMonitoredValueByName(\"java.threads.daemon\");  // NOI18N\n      threadsLive = jvmstat.findMonitoredValueByName(\"java.threads.live\");  // NOI18N\n      threadsLivePeak = jvmstat.findMonitoredValueByName(\"java.threads.livePeak\");  // NOI18N\n      threadsStarted = jvmstat.findMonitoredValueByName(\"java.threads.started\");    // NOI18N\n      applicationTime = jvmstat.findMonitoredValueByName(\"sun.rt.applicationTime\"); // NOI18N\n      MonitoredValue startTimeMon = jvmstat.findMonitoredValueByName(\"sun.rt.createVmBeginTime\");    // NOI18N\n      startup = getLongValue(startTimeMon);\n      MonitoredValue osFrequencyMon = jvmstat.findMonitoredValueByName(\"sun.os.hrt.frequency\"); // NOI18N\n      osFrequency = getLongValue(osFrequencyMon);\n      genCapacity = jvmstat.findMonitoredValueByPattern(\"sun.gc.((generation.[0-9]+)|(metaspace)).capacity\");   // NOI18N\n      genName[1] = NbBundle.getMessage(JvmJvmstatModel_25.class, \"LBL_Meta\"); // NOI18N\n      genUsed = jvmstat.findMonitoredValueByPattern(\"sun.gc.((generation.[0-9]+.space.[0-9]+)|(metaspace)).used\");  // NOI18N\n      genMaxCapacity=computeMaxCapacity();\n    }\n\n    private long[] computeMaxCapacity() {\n        String gcType = jvmstat.findByName(GC_TYPE_COUNTER_NAME);\n        String gcColName = jvmstat.findByName(GC_COLLECTOR_COUNTER_NAME);\n\n        if (G1_NAME.equals(gcType) || GENERATIONAL_ZGC_NAME.equals(gcColName)) {\n            // Generational ZGC Max Capacity GH-518\n            // Generational ZGC sets the max capacity of all spaces to heap_capacity\n            //\n            // G1 Max Capacity GH-127\n            // G1 sets the max capacity of all spaces to heap_capacity,\n            // given that G1 don't always have a reasonable upper bound on how big\n            // each space can grow.\n            long[] maxCapacity = new long[2];\n            MonitoredValue maxVal = jvmstat.findMonitoredValueByName(\"sun.gc.generation.0.maxCapacity\");    // NOI18N\n            MonitoredValue metaVal = jvmstat.findMonitoredValueByName(\"sun.gc.metaspace.maxCapacity\");    // NOI18N\n\n            maxCapacity[0] = getLongValue(maxVal);\n            maxCapacity[1] = getLongValue(metaVal);\n            return maxCapacity;\n        }\n        return getGenerationSum(jvmstat.findMonitoredValueByPattern(\"sun.gc.((generation.[0-9]+)|(metaspace)).maxCapacity\")); // NOI18N\n    }\n\n    protected String getPermGenPrefix() {\n        return PERM_GEN_PREFIX_META;\n    }\n\n    public long getUpTime() {\n        // ugly workaround for missing \"sun.os.hrt.ticks\" counter\n        // does not work well for remote application unless time is synchronized\n        return (System.currentTimeMillis() - startup)*(osFrequency/1000);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/JvmJvmstatModel_4.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.MonitoredValue;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JvmJvmstatModel_4 extends JvmJvmstatModel {\n    private static final String PERM_GEN_PREFIX = \"hotspot.gc.generation.2.\";   // NOI18N\n\n    JvmJvmstatModel_4(Application app,JvmstatModel stat) {\n        super(app,stat);\n        initMonitoredVales();\n    }\n\n    private void initMonitoredVales() {\n      loadedClasses = jvmstat.findMonitoredValueByName(\"hotspot.rt.cl.classes.loaded\"); // NOI18N\n      unloadedClasses = jvmstat.findMonitoredValueByName(\"hotspot.rt.cl.classes.unloaded\"); // NOI18N\n      applicationTime = jvmstat.findMonitoredValueByName(\"sun.rt.applicationTime\"); // NOI18N\n      upTime = jvmstat.findMonitoredValueByName(\"hotspot.rt.hrt.ticks\");    // NOI18N\n      MonitoredValue osFrequencyMon = jvmstat.findMonitoredValueByName(\"hotspot.rt.hrt.frequency\"); // NOI18N\n      osFrequency = getLongValue(osFrequencyMon);\n      genCapacity = jvmstat.findMonitoredValueByPattern(\"hotspot.gc.generation.[0-9]+.capacity.current\");   // NOI18N\n      genUsed = jvmstat.findMonitoredValueByPattern(\"hotspot.gc.generation.[0-9]+.space.[0-9]+.used\");  // NOI18N\n      genMaxCapacity = getGenerationSum(jvmstat.findMonitoredValueByPattern(\"hotspot.gc.generation.[0-9]+.capacity.max\"));  // NOI18N\n    }\n\n    protected String getPermGenPrefix() {\n        return PERM_GEN_PREFIX;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/JvmJvmstatModel_5.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.MonitoredValue;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JvmJvmstatModel_5 extends JvmJvmstatModel {\n    private static final String PERM_GEN_PREFIX = \"sun.gc.generation.2.\";   // NOI18N\n\n    JvmJvmstatModel_5(Application app,JvmstatModel stat) {\n        super(app,stat);\n        initMonitoredVales();\n    }\n\n    private void initMonitoredVales() {\n      loadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.loadedClasses\");   // NOI18N\n      sharedLoadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.sharedLoadedClasses\");   // NOI18N\n      sharedUnloadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.sharedUnloadedClasses\");   // NOI18N\n      unloadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.unloadedClasses\");   // NOI18N\n      threadsDaemon = jvmstat.findMonitoredValueByName(\"java.threads.daemon\");  // NOI18N\n      threadsLive = jvmstat.findMonitoredValueByName(\"java.threads.live\");  // NOI18N\n      threadsLivePeak = jvmstat.findMonitoredValueByName(\"java.threads.livePeak\");  // NOI18N\n      threadsStarted = jvmstat.findMonitoredValueByName(\"java.threads.started\");    // NOI18N\n      applicationTime = jvmstat.findMonitoredValueByName(\"sun.rt.applicationTime\"); // NOI18N\n      upTime = jvmstat.findMonitoredValueByName(\"sun.os.hrt.ticks\");    // NOI18N\n      MonitoredValue osFrequencyMon = jvmstat.findMonitoredValueByName(\"sun.os.hrt.frequency\"); // NOI18N\n      osFrequency = getLongValue(osFrequencyMon);\n      genCapacity = jvmstat.findMonitoredValueByPattern(\"sun.gc.generation.[0-9]+.capacity\");   // NOI18N\n      genUsed = jvmstat.findMonitoredValueByPattern(\"sun.gc.generation.[0-9]+.space.[0-9]+.used\");  // NOI18N\n      genMaxCapacity=getGenerationSum(jvmstat.findMonitoredValueByPattern(\"sun.gc.generation.[0-9]+.maxCapacity\")); // NOI18N\n    }\n\n    protected String getPermGenPrefix() {\n        return PERM_GEN_PREFIX;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/JvmJvmstatModel_8.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport java.util.List;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.MonitoredValue;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JvmJvmstatModel_8 extends JvmJvmstatModel {\n    private static final String PERM_GEN_PREFIX_META = \"sun.gc.metaspace.\";   // NOI18N\n    private static final String PERM_GEN_PREFIX_PERM = \"sun.gc.generation.2.\";   // NOI18N\n    private static final String GC_TYPE_COUNTER_NAME = \"sun.gc.policy.name\";  // NOI18N\n    private static final String G1_NAME = \"GarbageFirst\";           // NOI18N\n    private static final String GC_COLLECTOR_COUNTER_NAME = \"sun.gc.collector.0.name\";  // NOI18N\n    private static final String GENERATIONAL_ZGC_NAME = \"ZGC minor collection pauses\"; // NOI18N\n    \n    private String permGenPrefix = PERM_GEN_PREFIX_PERM;\n\n    JvmJvmstatModel_8(Application app,JvmstatModel stat) {\n        super(app,stat);\n        initMonitoredVales();\n    }\n\n    private void initMonitoredVales() {\n      loadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.loadedClasses\");   // NOI18N\n      sharedLoadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.sharedLoadedClasses\");   // NOI18N\n      sharedUnloadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.sharedUnloadedClasses\");   // NOI18N\n      unloadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.unloadedClasses\");   // NOI18N\n      threadsDaemon = jvmstat.findMonitoredValueByName(\"java.threads.daemon\");  // NOI18N\n      threadsLive = jvmstat.findMonitoredValueByName(\"java.threads.live\");  // NOI18N\n      threadsLivePeak = jvmstat.findMonitoredValueByName(\"java.threads.livePeak\");  // NOI18N\n      threadsStarted = jvmstat.findMonitoredValueByName(\"java.threads.started\");    // NOI18N\n      applicationTime = jvmstat.findMonitoredValueByName(\"sun.rt.applicationTime\"); // NOI18N\n      upTime = jvmstat.findMonitoredValueByName(\"sun.os.hrt.ticks\");    // NOI18N\n      MonitoredValue osFrequencyMon = jvmstat.findMonitoredValueByName(\"sun.os.hrt.frequency\"); // NOI18N\n      osFrequency = getLongValue(osFrequencyMon);\n      genCapacity = jvmstat.findMonitoredValueByPattern(\"sun.gc.((generation.[0-9]+)|(metaspace)).capacity\");   // NOI18N\n      initPermGenPrefix(genCapacity);\n      genUsed = jvmstat.findMonitoredValueByPattern(\"sun.gc.((generation.[0-9]+.space.[0-9]+)|(metaspace)).used\");  // NOI18N\n      genMaxCapacity=computeMaxCapacity();\n    }\n\n    private void initPermGenPrefix(List<MonitoredValue> monitors) {\n        for (MonitoredValue m : monitors) {\n            if (m.getName().startsWith(PERM_GEN_PREFIX_META)) {\n                permGenPrefix = PERM_GEN_PREFIX_META;\n                genName[1] = NbBundle.getMessage(JvmJvmstatModel_8.class, \"LBL_Meta\"); // NOI18N\n                break;\n            }\n        }\n    }\n    \n    private long[] computeMaxCapacity() {\n        String gcType = jvmstat.findByName(GC_TYPE_COUNTER_NAME);\n        String gcColName = jvmstat.findByName(GC_COLLECTOR_COUNTER_NAME);\n\n        if (G1_NAME.equals(gcType) || GENERATIONAL_ZGC_NAME.equals(gcColName)) {\n            // Generational ZGC Max Capacity GH-518\n            // Generational ZGC sets the max capacity of all spaces to heap_capacity\n            //\n            // G1 Max Capacity GH-127\n            // G1 sets the max capacity of all spaces to heap_capacity,\n            // given that G1 don't always have a reasonable upper bound on how big\n            // each space can grow.\n            long[] maxCapacity = new long[2];\n            MonitoredValue maxVal = jvmstat.findMonitoredValueByName(\"sun.gc.generation.0.maxCapacity\");    // NOI18N\n            MonitoredValue metaVal = jvmstat.findMonitoredValueByName(\"sun.gc.metaspace.maxCapacity\");    // NOI18N\n\n            maxCapacity[0] = getLongValue(maxVal);\n            maxCapacity[1] = getLongValue(metaVal);\n            return maxCapacity;\n        }\n        return getGenerationSum(jvmstat.findMonitoredValueByPattern(\"sun.gc.((generation.[0-9]+)|(metaspace)).maxCapacity\")); // NOI18N\n    }\n\n    protected String getPermGenPrefix() {\n        return permGenPrefix;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/JvmstatModelImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatListener;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.MonitoredValue;\nimport org.openide.ErrorManager;\nimport sun.jvmstat.monitor.Monitor;\nimport sun.jvmstat.monitor.MonitorException;\nimport sun.jvmstat.monitor.MonitoredHost;\nimport sun.jvmstat.monitor.MonitoredVm;\nimport sun.jvmstat.monitor.event.MonitorStatusChangeEvent;\nimport sun.jvmstat.monitor.event.VmEvent;\nimport sun.jvmstat.monitor.event.VmListener;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class JvmstatModelImpl extends JvmstatModel implements VmListener, DataRemovedListener<Application> {\n    private static final String Variability_CONSTANT = \"Constant\";  // NOI18N\n    Application application;\n    MonitoredVm monitoredVm;\n    final Set<JvmstatListener> listeners;\n    private Map<String,String> valueCache;\n    private Integer pid;\n    private MonitoredHost monitoredHost;\n\n    JvmstatModelImpl(Application app,MonitoredVm vm) {\n        application = app;\n        pid = Integer.valueOf(vm.getVmIdentifier().getLocalVmId());\n        monitoredVm = vm;\n        valueCache = new HashMap<>();\n        listeners = new HashSet<>();\n    }\n               \n    public void addJvmstatListener(JvmstatListener l) {\n        synchronized (listeners) {\n            if (listeners.isEmpty()) {\n                initListeners();\n            }\n            listeners.add(l);\n        }\n    }\n    \n    public void removeJvmstatListener(JvmstatListener l) {\n        synchronized (listeners) {\n            if (!listeners.isEmpty()) {\n                listeners.remove(l);\n                if (listeners.isEmpty()) {\n                    disableListeners();\n                }\n            }\n        }\n    }\n    \n    public String findByName(String name) {\n        String value = valueCache.get(name);\n        if (value != null) return value;\n        \n        try {\n            Monitor mon = monitoredVm.findByName(name);\n            if (mon != null) {\n                value = mon.getValue().toString();\n                if (Utils.getVariability(mon).toString().equals(Variability_CONSTANT)) {\n                    valueCache.put(name,value);\n                }\n            }\n            return value;\n        } catch (MonitorException ex) {\n            ErrorManager.getDefault().notify(ErrorManager.WARNING,ex);\n        }\n        return null;\n    }\n    \n    public MonitoredValue findMonitoredValueByName(String name) {\n        try {\n            Monitor mon = monitoredVm.findByName(name);\n            if (mon != null) {\n                return new MonitoredValueImpl(mon);\n            }\n        } catch (MonitorException ex) {\n            ErrorManager.getDefault().notify(ErrorManager.WARNING,ex);\n        }\n        return null;\n    }\n\n    \n    public List<String> findByPattern(String pattern) {\n        try {\n            List<Monitor> monitorList = monitoredVm.findByPattern(pattern);\n            List<String> monitorStrList = new ArrayList<>(monitorList.size());\n            for (Monitor monitor : monitorList) {\n                monitorStrList.add(monitor.getValue().toString());\n            }\n            return monitorStrList;\n        } catch (MonitorException ex) {\n            ErrorManager.getDefault().notify(ErrorManager.WARNING,ex);\n        }\n        return null;\n    }\n    \n    public List<MonitoredValue> findMonitoredValueByPattern(String pattern) {\n        try {\n            List<Monitor> monitorList = monitoredVm.findByPattern(pattern);\n            List<MonitoredValue> monitoredValueList = new ArrayList<>(monitorList.size());\n            for (Monitor monitor : monitorList) {\n                monitoredValueList.add(new MonitoredValueImpl(monitor));\n            }\n            return monitoredValueList;\n        } catch (MonitorException ex) {\n            ErrorManager.getDefault().notify(ErrorManager.WARNING,ex);\n        }\n        return null;  \n    }\n    \n    void initListeners() {\n        try {\n            monitoredHost = MonitoredHost.getMonitoredHost(monitoredVm.getVmIdentifier());\n            monitoredVm.addVmListener(this);\n        } catch (MonitorException ex) {\n            ErrorManager.getDefault().notify(ErrorManager.WARNING,ex);\n        }\n    }\n    \n    void disableListeners() {\n        try {\n            monitoredVm.removeVmListener(this);\n        } catch (MonitorException ex) {\n             ErrorManager.getDefault().notify(ErrorManager.WARNING,ex);\n        }\n        monitoredHost = null;\n    }\n        \n    /**\n     * Invoked when instrumentation objects are inserted into or removed\n     * from the MonitoredVm.\n     *\n     * @param event the object describing the event.\n     */\n    public void monitorStatusChanged(MonitorStatusChangeEvent event) {\n        \n    }\n    \n    /**\n     * Invoked when instrumentation objects are updated. This event is\n     * generated at a fixed interval as determined by the polling rate\n     * of the MonitoredVm that the VmListener is registered with.\n     *\n     * @param event the object describing the event.\n     */\n    public void monitorsUpdated(VmEvent event) {\n        assert event.getMonitoredVm().equals(monitoredVm);\n        try {\n            // check that the application is still alive\n            if (monitoredHost.activeVms().contains(pid)) {\n                List<JvmstatListener> listenersCopy;\n                synchronized  (listeners) {\n                    listenersCopy = new ArrayList<>(listeners);\n                }\n                for (JvmstatListener listener : listenersCopy) {\n                    listener.dataChanged(this);\n                }\n            } else { // application is not alive\n                disableListeners();\n                monitoredVm.detach();\n            }\n        } catch (MonitorException ex) {\n             ErrorManager.getDefault().notify(ErrorManager.WARNING,ex);\n             disableListeners();\n             monitoredVm.detach();\n        }\n    }\n    \n    /**\n     * Invoked when the connection to the MonitoredVm has disconnected\n     * due to communication errors.\n     *\n     * @param event the object describing the event.\n     */\n    public void disconnected(VmEvent event) {\n        ErrorManager.getDefault().log(\"Disconnect \"+event.getMonitoredVm().getVmIdentifier());  // NOI18N\n        disableListeners();\n        monitoredVm.detach();\n    }\n    \n    public void dataRemoved(Application dataSource) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                disableListeners();\n                monitoredVm.detach();\n            }\n        });\n    }\n\n    public String getConnectionId() {\n        return monitoredVm.getVmIdentifier().getURI().toString();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/JvmstatModelProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport java.net.URISyntaxException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.jvmstat.application.JvmstatApplicationProvider;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport sun.jvmstat.monitor.Monitor;\nimport sun.jvmstat.monitor.MonitorException;\nimport sun.jvmstat.monitor.MonitoredHost;\nimport sun.jvmstat.monitor.MonitoredVm;\nimport sun.jvmstat.monitor.VmIdentifier;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class JvmstatModelProvider extends AbstractModelProvider<JvmstatModel, Application> {\n    private final static Logger LOGGER = Logger.getLogger(JvmstatModelProvider.class.getName());\n    \n    static MonitoredVm getMonitoredVm(Application app) throws MonitorException {\n        if (app.isRemoved() || app.getPid() == Application.UNKNOWN_PID) return null;\n        \n        String vmId = \"//\" + app.getPid();  // NOI18N\n        try {\n            MonitoredHost monitoredHost = JvmstatApplicationProvider.findMonitoredHost(app);\n            if (monitoredHost != null) {\n                int refreshInterval = GlobalPreferences.sharedInstance().getMonitoredDataPoll() * 1000;\n                return monitoredHost.getMonitoredVm(new VmIdentifier(vmId),refreshInterval);\n            }\n        } catch (URISyntaxException ex) {\n            LOGGER.log(Level.WARNING,ex.getLocalizedMessage(),ex);\n        } catch (Exception ex) { \n            // MonitoredHostProvider.getMonitoredVm can throw java.lang.Exception on Windows, \n            // when opening shared memory file (java.lang.Exception: Could not open PerfMemory)\n            LOGGER.log(Level.INFO,\"getMonitoredVm failed\",ex);  // NOI18N\n        }\n        return null;\n    }\n    \n    public JvmstatModel createModelFor(Application app) {\n        MonitoredVm vm = null;\n        try {\n            vm = getMonitoredVm(app);\n            if (vm != null) {\n                Monitor vmEndTimeMon;\n                long vmEndTime = 0;\n                long oldVmEndTime = 0;\n                do {\n                    // check that the target VM is accessible\n                    if (vm.findByName(\"java.property.java.vm.version\") != null) {   // NOI18N\n                        JvmstatModelImpl jvmstat = new JvmstatModelImpl(app,vm);\n                        app.notifyWhenRemoved(jvmstat);\n                        return jvmstat;\n                    } else {\n                        // maybe it is too early and VM is not fully initialized\n                        LOGGER.log(Level.INFO, app.getId()+\" java.property.java.vm.version is null\"); // NOI18N\n                        vmEndTimeMon = vm.findByName(\"sun.rt.createVmEndTime\");     // NOI18N\n                        if (vmEndTimeMon != null) {\n                            LOGGER.log(Level.INFO, app.getId()+\" \"+vmEndTimeMon.getName()+\" = \"+vmEndTimeMon.getValue());   // NOI18N\n                            oldVmEndTime = vmEndTime;\n                            vmEndTime = ((Long)vmEndTimeMon.getValue()).longValue();\n                        }\n                        try {\n                            Thread.sleep(100);\n                        } catch (InterruptedException ex) {\n                            // ignore\n                        }\n                    }\n                } while (vmEndTimeMon != null && oldVmEndTime == 0);\n                LOGGER.log(Level.INFO, \"sun.rt.createVmEndTime is null \"+oldVmEndTime+\" \"+vmEndTime); // NOI18N\n            }\n        } catch (MonitorException ex) {\n            LOGGER.log(Level.INFO, \"Could not get MonitoredVM\", ex); // NOI18N\n        }\n        if (vm != null) {\n            vm.detach();\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/MonitoredValueImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport org.graalvm.visualvm.tools.jvmstat.MonitoredValue;\nimport sun.jvmstat.monitor.Monitor;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class MonitoredValueImpl extends MonitoredValue {\n    \n    private Monitor monitor;\n    \n    MonitoredValueImpl(Monitor mon) {\n        monitor = mon;\n    }\n    \n    public String getName() {\n        return monitor.getName();\n    }\n    \n    public Object getValue() {\n        return monitor.getValue();\n    }\n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/OracleJRockitJvmJvmstatModel.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.MonitoredValue;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass OracleJRockitJvmJvmstatModel extends JvmJvmstatModel {\n    private static final String PERM_GEN_PREFIX = \"oracle.cls.memory.\";    // NOI18N\n    \n    OracleJRockitJvmJvmstatModel(Application app,JvmstatModel stat) {\n        super(app,stat);\n        initMonitoredVales();\n    }\n    \n    private void initMonitoredVales() {\n        loadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.loadedClasses\"); // NOI18N\n        sharedLoadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.sharedLoadedClasses\"); // NOI18N\n        sharedUnloadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.sharedUnloadedClasses\"); // NOI18N\n        unloadedClasses = jvmstat.findMonitoredValueByName(\"java.cls.unloadedClasses\"); // NOI18N\n        threadsDaemon = jvmstat.findMonitoredValueByName(\"java.threads.daemon\");    // NOI18N\n        threadsLive = jvmstat.findMonitoredValueByName(\"java.threads.live\");    // NOI18N\n        threadsLivePeak = jvmstat.findMonitoredValueByName(\"java.threads.livePeak\");    // NOI18N\n        threadsStarted = jvmstat.findMonitoredValueByName(\"java.threads.started\");  // NOI18N\n        applicationTime = jvmstat.findMonitoredValueByName(\"sun.rt.applicationTime\");   // NOI18N\n        upTime = jvmstat.findMonitoredValueByName(\"oracle.rt.ticks\");  // NOI18N\n        MonitoredValue osFrequencyMon = jvmstat.findMonitoredValueByName(\"oracle.rt.counterFrequency\");    // NOI18N\n        osFrequency = getLongValue(osFrequencyMon);\n        genCapacity = jvmstat.findMonitoredValueByPattern(\"((jrockit.gc.pool.heap)|(oracle.cls.memory)).committed\");    // NOI18N\n        genUsed = jvmstat.findMonitoredValueByPattern(\"((jrockit.gc.pool.heap)|(jrockit.gc.pool.nursery)|(oracle.cls.memory)).used\");    // NOI18N\n        genMaxCapacity=getGenerationSum(jvmstat.findMonitoredValueByPattern(\"((jrockit.gc.pool.heap)|(oracle.cls.memory)).max\"));   // NOI18N\n    }\n    \n    protected String getPermGenPrefix() {\n        return PERM_GEN_PREFIX;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/OracleJRockitJvmJvmstatModelProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class OracleJRockitJvmJvmstatModelProvider extends JvmJvmstatModelProvider {\n    \n    public JvmJvmstatModel createModelFor(Application app) {\n        JvmstatModel jvmstat = JvmstatModelFactory.getJvmstatFor(app);\n        if (jvmstat != null) {\n            String vmName = jvmstat.findByName(\"java.property.java.vm.name\");   // NOI18N\n            \n            if (\"Oracle JRockit(R)\".equals(vmName)) {  // NOI18N\n                JvmJvmstatModel jvm = null;\n                String vmVersion = jvmstat.findByName(\"java.property.java.vm.version\"); // NOI18N\n                \n                if (vmVersion != null) {\n                    if (vmVersion.contains(\"1.6.0\")) {  // NOI18N\n                        jvm = new OracleJRockitJvmJvmstatModel(app,jvmstat);\n                    } else {\n                        jvm = new OracleJRockitJvmJvmstatModel(app,jvmstat);\n                    }\n                }\n                return jvm;\n            }\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/Utils.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport sun.jvmstat.monitor.Monitor;\n\n\n/**\n * @author Tomas Hurka\n */\nclass Utils {\n    private static Method getVariabilityMethod = getMonitorMethod(\"getVariability\");\n    private static Method getUnitsMethod = getMonitorMethod(\"getUnits\");\n    \n    static Object getVariability(Monitor monitor) {\n        return invokeGetter(monitor, getVariabilityMethod);\n    }\n    \n    static Object getUnits(Monitor monitor) {\n        return invokeGetter(monitor, getUnitsMethod);\n    }\n    \n    private static Object invokeGetter(Monitor monitor, Method method) {\n        try {\n            return method.invoke(monitor);\n        } catch (IllegalArgumentException ex) {\n            throw new RuntimeException(ex);\n        } catch (InvocationTargetException ex) {\n            throw new RuntimeException(ex);\n        } catch (IllegalAccessException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n    \n    private static Method getMonitorMethod(String methodName) {\n        try {\n            return Monitor.class.getDeclaredMethod(methodName);\n        } catch (SecurityException ex) {\n            throw new RuntimeException(ex);\n        } catch (NoSuchMethodException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/application/AddJstatdConnectionAction.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat.application;\n\nimport java.awt.event.ActionEvent;\nimport org.graalvm.visualvm.core.properties.PropertiesSupport;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport org.graalvm.visualvm.host.Host;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass AddJstatdConnectionAction extends SingleDataSourceAction<Host> {\n\n    private static AddJstatdConnectionAction instance;\n\n    public static synchronized AddJstatdConnectionAction instance() {\n        if (instance == null) instance = new AddJstatdConnectionAction();\n        return instance;\n    }\n\n\n    protected void actionPerformed(Host host, ActionEvent actionEvent) {\n        PropertiesSupport.sharedInstance().openProperties(host,\n                HostPropertiesProvider.CATEGORY_JSTATD_CONNECTION);\n    }\n\n    protected boolean isEnabled(Host host) {\n        return true;\n    }\n\n\n    private AddJstatdConnectionAction() {\n        super(Host.class);\n        putValue(NAME, NbBundle.getMessage(AddJstatdConnectionAction.class,\n                \"ACT_AddJstatdConnection\"));   // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(AddJstatdConnectionAction.class,\n                \"DESCR_AddJstatdConnection\"));   // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/application/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nMSG_Broken_Jps=<html><b>Local Java applications cannot be detected.</b><br><br>Please see the VisualVM Troubleshooting Guide for more<br>information and steps to fix the problem.<br><br>{0}</html>\nMSG_Broken_Jps_Link=<a href=\"https://visualvm.github.io/troubleshooting.html#jpswin\">https://visualvm.github.io/troubleshooting.html#jpswin</a>\nMSG_Broken_Jps_NoLink=<nobr>https://visualvm.github.io/troubleshooting.html#jpswin</nobr>\n\nMSG_Broken_Jps2=<html><b>Local Java applications cannot be monitored.</b><br><br>Please see the VisualVM Troubleshooting Guide for more<br>information and steps to fix the problem.<br><br>{0}</html>\nMSG_Broken_Jps2_Link=<a href=\"https://visualvm.github.io/troubleshooting.html#jpswin2\">https://visualvm.github.io/troubleshooting.html#jpswin2</a>\nMSG_Broken_Jps2_NoLink=<nobr>https://visualvm.github.io/troubleshooting.html#jpswin2</nobr>\n\nMSG_Broken_Jvmstat=<html><b>Failed to create jvmstat connection to {0}.</b><br><br>Check the VisualVM logfile for details.</html>\n\nBTN_AddDefault=Add &Default\nBTN_AddCustom=Add &Custom\nBTN_Remove=&Remove\nLBL_Port1=Port\\:\nLBL_Port2=&Port\\:\nLBL_Refresh1=Refresh interval\\:\nLBL_Refresh2=Re&fresh interval\\:\nLBL_RefreshUnits=sec.\nLBL_NoConnection=<No jstatd connection defined>\n\nCAP_JstatdProperties=jstatd Connections\nDESCR_JstatdProperties=Connections to jstatd running on the host\n\nLBL_JstatdAppProperties=jstatd Connection\nDESCR_JstatdAppProperties=jstatd connection setup\nLBL_Connection=&Connection\\:\n\nLBL_ConnectionProperties=Connection\nDESCR_ConnectionProperties=Connection used to discover and manage the application\nMSG_ConnectionPropertiesDefault=The application is managed by a local jvmstat connection.\nMSG_ConnectionPropertiesCustom=The application is managed by a jvmstat connection. See the jstatd Connection tab for details.\n\nACT_AddJstatdConnection=Add js&tatd Connection...\nDESCR_AddJstatdConnection=Adds new jstatd connection.\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/application/ConnectionDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat.application;\n\nimport java.net.URISyntaxException;\nimport java.rmi.registry.Registry;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.host.Host;\nimport org.openide.util.Exceptions;\nimport sun.jvmstat.monitor.HostIdentifier;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ConnectionDescriptor {\n\n    static final ConnectionDescriptor DEFAULT_LOCAL_DESCRIPTOR =\n            new ConnectionDescriptor(-1, GlobalPreferences.sharedInstance().getMonitoredHostPoll());\n\n    private int port;\n    private double refreshRate;\n\n\n    ConnectionDescriptor(int port, double refreshRate) {\n        setPort(port);\n        setRefreshRate(refreshRate);\n    }\n\n\n    static ConnectionDescriptor createDefault() {\n        return new ConnectionDescriptor(Registry.REGISTRY_PORT, GlobalPreferences.sharedInstance().getMonitoredHostPoll());\n    }\n\n\n    final void setPort(int port) { this.port = port; }\n\n    final int getPort() { return port; }\n\n    final void setRefreshRate(double refreshRate) { this.refreshRate = refreshRate; }\n\n    /**\n     * monitored host refresh rate\n     * @return refresh rate in seconds\n     */ \n    final double getRefreshRate() { return refreshRate; }\n\n\n    final HostIdentifier createHostIdentifier(Host host) {\n        String hostId = null;\n        if (this != DEFAULT_LOCAL_DESCRIPTOR) {\n            hostId = \"rmi://\" + host.getHostName(); // NOI18N\n            if (port != Registry.REGISTRY_PORT) hostId += \":\" + port; // NOI18N\n        }\n        try {\n            return new HostIdentifier(hostId);\n        } catch (URISyntaxException e) {\n            Exceptions.printStackTrace(e);\n            return null;\n        }\n    }\n\n\n    public boolean equals(Object o) {\n        if (!(o instanceof ConnectionDescriptor)) return false;\n        return port == ((ConnectionDescriptor)o).port;\n    }\n\n    public int hashCode() {\n        return port;\n    }\n\n    public String toString() {\n        return \"Port: \" + port + \", Refresh Rate: \" + refreshRate; // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/application/ConnectionsCustomizer.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat.application;\n\nimport java.awt.CardLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.event.ActionEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.text.NumberFormat;\nimport java.util.EventObject;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JFormattedTextField;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JSpinner;\nimport javax.swing.JTable;\nimport javax.swing.JTextField;\nimport javax.swing.SpinnerNumberModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.border.Border;\nimport javax.swing.event.CellEditorListener;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.TableCellEditor;\nimport javax.swing.table.TableCellRenderer;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.core.properties.PropertiesPanel;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.uisupport.JExtendedSpinner;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ConnectionsCustomizer extends PropertiesPanel {\n\n    private static final Border SELECTED_BORDER = selectedBorder();\n    private static final Border EMPTY_BORDER = emptyBorder(SELECTED_BORDER);\n    private static final ConnectionDescriptor DEFAULT_CONNECTION =\n            ConnectionDescriptor.createDefault();\n\n    private static final String DATA_VIEW = \"DATA_VIEW\"; // NOI18N\n    private static final String NO_DATA_VIEW = \"NO_DATA_VIEW\"; // NOI18N\n\n    private static int TABLE_WIDTH = -1;\n    private static int ROW_HEIGHT  = -1;\n\n    private final DefaultTableModel model;\n\n\n    ConnectionsCustomizer(Set<ConnectionDescriptor> descriptors) {\n        this.model = getModel(descriptors);\n        initComponents();\n        update();\n\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (model.getRowCount() > 0)\n                    table.getSelectionModel().setSelectionInterval(0, 0);\n            }\n        });\n    }\n\n\n    public Set<ConnectionDescriptor> getDescriptors() {\n        return getDescriptors(model);\n    }\n\n\n    private static DefaultTableModel getModel(Set<ConnectionDescriptor> descriptors) {\n        DefaultTableModel model = new DefaultTableModel(new Object[] { \"Connections\" }, 0); // NOI18N\n        for (ConnectionDescriptor descriptor : descriptors)\n                model.addRow(new Object[] { descriptor });\n        return model;\n    }\n\n    private static Set<ConnectionDescriptor> getDescriptors(DefaultTableModel model) {\n        Set<ConnectionDescriptor> descriptors = new HashSet<>();\n        for (int i = 0; i < model.getRowCount(); i++)\n            descriptors.add((ConnectionDescriptor)model.getValueAt(i, 0));\n        return descriptors;\n    }\n\n\n    private static Border selectedBorder() {\n        Border b = UIManager.getBorder(\"Table.focusSelectedCellHighlightBorder\"); // NOI18N\n        if (b == null) b = UIManager.getBorder(\"Table.focusCellHighlightBorder\"); // NOI18N\n        if (b != null) b = new SafeBorder(b); // #372, workarounds null from Border.getBorderInsets\n        return b;\n    }\n\n    private static Border emptyBorder(Border border) {\n        Insets i = border == null ? null : border.getBorderInsets(new JTextField());\n        return i == null ? BorderFactory.createEmptyBorder() :\n               BorderFactory.createEmptyBorder(i.top, i.left, i.bottom, i.right);\n    }\n\n\n    private void addDefault() {\n        model.addRow(new Object[] { ConnectionDescriptor.createDefault() });\n        int row = table.getRowCount() - 1;\n        table.getSelectionModel().setSelectionInterval(row, row);\n    }\n\n    private void addCustom() {\n        ConnectionDescriptor d = new ConnectionDescriptor(getUnusedPort(), GlobalPreferences.sharedInstance().getMonitoredHostPoll());\n        model.addRow(new Object[] { d });\n        int row = table.getRowCount() - 1;\n        table.getSelectionModel().setSelectionInterval(row, row);\n    }\n\n    private void removeSelected() {\n        int selectedRow = table.getSelectedRow();\n        if (selectedRow == -1) return;\n        table.clearSelection();\n        model.removeRow(selectedRow);\n        if (selectedRow < table.getRowCount()) table.getSelectionModel().setSelectionInterval(selectedRow, selectedRow);\n        else if (selectedRow > 0) table.getSelectionModel().setSelectionInterval(selectedRow - 1, selectedRow - 1);\n    }\n\n    private void update() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                CardLayout cl = (CardLayout)viewPanel.getLayout();\n                cl.show(viewPanel, model.getRowCount() > 0 ? DATA_VIEW : NO_DATA_VIEW);\n                addDefault.setEnabled(!containsConnection(DEFAULT_CONNECTION));\n                remove.setEnabled(table.getSelectedRow() != -1);\n            }\n        });\n    }\n\n\n    private boolean containsConnection(ConnectionDescriptor d) {\n        for (int i = 0; i < table.getRowCount(); i++)\n            if (table.getValueAt(i, 0).equals(d)) return true;\n        return false;\n    }\n\n    private int getUnusedPort() {\n        Set<Integer> ports = new HashSet<>();\n        for (int i = 0; i < table.getRowCount(); i++)\n            ports.add(((ConnectionDescriptor)table.getValueAt(i, 0)).getPort());\n        for (int i = ConnectionDescriptor.createDefault().getPort() + 1; i < 65536; i++)\n            if (!ports.contains(i)) return i;\n        return -1;\n    }\n\n\n    private void initComponents() {\n        setLayout(new GridBagLayout());\n\n        GridBagConstraints c;\n\n        CellRenderer renderer = new CellRenderer();\n        CellEditor editor = new CellEditor(new Runnable() {\n            public void run() { update(); }\n        });\n\n        table = new ConnectionsTable(model, renderer, editor) {\n            public int getRowHeight() {\n                return ROW_HEIGHT;\n            }\n            public Dimension getPreferredSize() {\n                Dimension ps = super.getPreferredSize();\n                ps.width = TABLE_WIDTH;\n                return ps;\n            }\n            public Dimension getMinimumSize() {\n                Dimension ms = super.getMinimumSize();\n                ms.width = TABLE_WIDTH;\n                return ms;\n            }\n        };\n        table.setShowGrid(false);\n        table.setIntercellSpacing(new Dimension());\n        table.setOpaque(false);\n        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n            public void valueChanged(ListSelectionEvent e) {\n                update();\n            }\n        });\n\n        if (TABLE_WIDTH == -1) {\n            TABLE_WIDTH = editor.getTableCellEditorComponent(table, new\n                          ConnectionDescriptor(1, 1), false, 1, 1).\n                          getPreferredSize().width;\n            editor.stopCellEditing();\n        }\n        if (ROW_HEIGHT == -1) {\n            ROW_HEIGHT  = renderer.getTableCellRendererComponent(table,\n                          new ConnectionDescriptor(1, 1), false, false,\n                          1, 1).getPreferredSize().height;\n        }\n\n        JScrollPane impl = new JScrollPane();\n        JScrollPane scroll = new ScrollableContainer(table);\n        scroll.setBorder(impl.getBorder());\n        if (!UISupport.isNimbusLookAndFeel())\n            scroll.setViewportBorder(impl.getViewportBorder());\n        scroll.getViewport().setOpaque(true);\n        scroll.getViewport().setBackground(UISupport.getDefaultBackground());\n        scroll.setPreferredSize(new Dimension(TABLE_WIDTH + 20, 1));\n\n        JLabel noConnection = new JLabel(NbBundle.getMessage(\n                ConnectionsCustomizer.class, \"LBL_NoConnection\"), JLabel.CENTER); // NOI18N\n        noConnection.setEnabled(false);\n        noConnection.setOpaque(false);\n        noConnection.setMinimumSize(new Dimension());\n        JScrollPane emptyScroll = new JScrollPane(noConnection,\n                JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n        emptyScroll.getViewport().setOpaque(true);\n        emptyScroll.getViewport().setBackground(UISupport.getDefaultBackground());\n        emptyScroll.setOpaque(false);\n        if (UISupport.isNimbusLookAndFeel())\n            emptyScroll.setViewportBorder(BorderFactory.createEmptyBorder());\n        viewPanel = new JPanel(new CardLayout());\n        viewPanel.setOpaque(false);\n        viewPanel.add(emptyScroll, NO_DATA_VIEW);\n        viewPanel.add(scroll, DATA_VIEW);\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.gridheight = GridBagConstraints.REMAINDER;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(0, 0, 0, 10);\n        add(viewPanel, c);\n\n        addDefault = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                addDefault();\n            }\n        };\n        Mnemonics.setLocalizedText(addDefault, NbBundle.getMessage(\n                ConnectionsCustomizer.class, \"BTN_AddDefault\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 3, 0);\n        add(addDefault, c);\n\n        JButton addCustom = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                addCustom();\n            }\n        };\n        Mnemonics.setLocalizedText(addCustom, NbBundle.getMessage(\n                ConnectionsCustomizer.class, \"BTN_AddCustom\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 0, 3, 0);\n        add(addCustom, c);\n\n        remove = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                removeSelected();\n            }\n        };\n        Mnemonics.setLocalizedText(remove, NbBundle.getMessage(\n                ConnectionsCustomizer.class, \"BTN_Remove\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 2;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 0, 0, 0);\n        add(remove, c);\n\n    }\n\n    private JPanel viewPanel;\n    private ConnectionsTable table;\n    private JButton addDefault;\n    private JButton remove;\n\n\n    private static class SafeBorder implements Border {\n\n        private final Border impl;\n\n        SafeBorder(Border impl) { this.impl = impl; }\n\n        public void paintBorder(Component cmpnt, Graphics grphcs, int i, int i1, int i2, int i3) {\n            impl.paintBorder(cmpnt, grphcs, i, i1, i2, i3);\n        }\n\n        public Insets getBorderInsets(Component cmpnt) {\n            Insets insets = impl.getBorderInsets(cmpnt);\n            if (insets == null) insets = new Insets(0, 0, 0, 0);\n            return insets;\n        }\n\n        public boolean isBorderOpaque() {\n            return impl.isBorderOpaque();\n        }\n\n    }\n\n\n    private static class CellRenderer extends JPanel implements TableCellRenderer {\n\n        private static final int BORDER_HEIGHT = 4;\n\n        private static final Color BACKGROUND;\n        private static final Color DARKER_BACKGROUND;\n\n        static {\n            BACKGROUND = UISupport.getDefaultBackground();\n\n            int darkerR = BACKGROUND.getRed() - 11;\n            if (darkerR < 0) darkerR += 26;\n            int darkerG = BACKGROUND.getGreen() - 11;\n            if (darkerG < 0) darkerG += 26;\n            int darkerB = BACKGROUND.getBlue() - 11;\n            if (darkerB < 0) darkerB += 26;\n            DARKER_BACKGROUND = new Color(darkerR, darkerG, darkerB);\n        }\n\n        private JLabel portLabel;\n        private JLabel portValueLabel;\n        private JLabel refreshLabel;\n        private JLabel refreshValueLabel;\n        private JLabel refreshUnitsLabel;\n\n        private final NumberFormat format = NumberFormat.getInstance();\n\n        CellRenderer() {\n            initComponents();\n        }\n\n\n        private void initComponents() {\n            portLabel = new JLabel(NbBundle.getMessage(\n                ConnectionsCustomizer.class, \"LBL_Port1\")); // NOI18N\n            portLabel.setFont(portLabel.getFont().deriveFont(Font.BOLD));\n            final int w = new JExtendedSpinner(new SpinnerNumberModel(0, 0, 65535, 0)).\n                    getPreferredSize().width;\n            portValueLabel = new JLabel() {\n                public Dimension getPreferredSize() {\n                    Dimension ps = super.getPreferredSize();\n                    ps.width = w;\n                    return ps;\n                }\n            };\n\n            refreshLabel = new JLabel(NbBundle.getMessage(\n                ConnectionsCustomizer.class, \"LBL_Refresh1\")); // NOI18N\n            refreshLabel.setFont(refreshLabel.getFont().deriveFont(Font.BOLD));\n            refreshValueLabel = new JLabel();\n            refreshUnitsLabel = new JLabel(NbBundle.getMessage(\n                ConnectionsCustomizer.class, \"LBL_RefreshUnits\")); // NOI18N\n\n            setLayout(new GridBagLayout());\n            GridBagConstraints c;\n\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 0;\n            c.fill = GridBagConstraints.NONE;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(BORDER_HEIGHT, 5, BORDER_HEIGHT, 0);\n            add(portLabel, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = 0;\n            c.fill = GridBagConstraints.NONE;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(BORDER_HEIGHT, 5, BORDER_HEIGHT, 0);\n            add(portValueLabel, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 2;\n            c.gridy = 0;\n            c.fill = GridBagConstraints.NONE;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(BORDER_HEIGHT, 15, BORDER_HEIGHT, 0);\n            add(refreshLabel, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 3;\n            c.gridy = 0;\n            c.fill = GridBagConstraints.NONE;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(BORDER_HEIGHT, 5, BORDER_HEIGHT, 0);\n            add(refreshValueLabel, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 4;\n            c.gridy = 0;\n            c.fill = GridBagConstraints.NONE;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(BORDER_HEIGHT, 5, BORDER_HEIGHT, 0);\n            add(refreshUnitsLabel, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 5;\n            c.gridy = 0;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.gridheight = GridBagConstraints.REMAINDER;\n            c.weightx = 1;\n            c.weighty = 1;\n            c.fill = GridBagConstraints.BOTH;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.insets = new Insets(0, 5, 0, 0);\n            add(Spacer.create(), c);\n\n            setOpaque(true);\n            setBorder(EMPTY_BORDER);\n        }\n\n        public Component getTableCellRendererComponent(JTable table, Object value,\n                                                       boolean isSelected, boolean hasFocus,\n                                                       int row, int column) {\n            ConnectionDescriptor cd = (ConnectionDescriptor)value;\n            portValueLabel.setText(format.format(cd.getPort()));\n            refreshValueLabel.setText(format.format(cd.getRefreshRate()));\n\n            if (!isSelected) {\n                boolean oddRow = row % 2 == 0;\n                setBackground(oddRow ? DARKER_BACKGROUND : BACKGROUND);\n            }\n\n            return this;\n        }\n\n        private static Color darker(Color c) {\n            if (c == null) return null;\n            int r = Math.abs(c.getRed() - 11);\n            int g = Math.abs(c.getGreen() - 11);\n            int b = Math.abs(c.getBlue() - 11);\n            int a = c.getAlpha();\n            return new Color(r, g, b, a);\n        }\n\n    }\n\n    private static class CellEditor extends JPanel implements TableCellEditor {\n\n        private static final int BORDER_HEIGHT = 6;\n        private static final Color BACKGROUND_COLOR =\n                UIManager.getColor(\"Tree.selectionBackground\"); // NOI18N\n        private static final Color FOREGROUND_COLOR =\n                UIManager.getColor(\"Tree.selectionForeground\"); // NOI18N\n\n        private Runnable updater;\n\n        private JTable table;\n        private ConnectionDescriptor cd;\n\n        private JLabel portLabel;\n        private JSpinner portSpinner;\n        private JLabel refreshLabel;\n        private JSpinner refreshSpinner;\n        private JLabel refreshUnitsLabel;\n\n\n        CellEditor(Runnable updater) {\n            this.updater = updater;\n            initComponents();\n        }\n\n        private PropertyChangeListener listener = new PropertyChangeListener() {\n            public void propertyChange(PropertyChangeEvent evt) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        updateBorder();\n                    }\n                });\n            }\n        };\n\n        private void updateBorder() {\n            if (displayFocus()) setBorder(SELECTED_BORDER);\n            else setBorder(EMPTY_BORDER);\n        }\n\n        private boolean displayFocus() {\n            if (table == null) return false;\n            Component focusOwner = KeyboardFocusManager.\n                    getCurrentKeyboardFocusManager().getFocusOwner();\n            return focusOwner != null ? focusOwner == table || SwingUtilities.\n                    isDescendingFrom(focusOwner, this) : false;\n        }\n\n        private void initComponents() {\n            portLabel = new JLabel();\n            Mnemonics.setLocalizedText(portLabel, NbBundle.getMessage(\n                ConnectionsCustomizer.class, \"LBL_Port2\")); // NOI18N\n            portLabel.setFont(portLabel.getFont().deriveFont(Font.BOLD));\n            portSpinner = new JExtendedSpinner(new SpinnerNumberModel(0, 0, 65535, 1));\n            portLabel.setLabelFor(portSpinner);\n\n            refreshLabel = new JLabel();\n            Mnemonics.setLocalizedText(refreshLabel, NbBundle.getMessage(\n                ConnectionsCustomizer.class, \"LBL_Refresh2\")); // NOI18N\n            refreshLabel.setFont(refreshLabel.getFont().deriveFont(Font.BOLD));\n            refreshSpinner = new JExtendedSpinner(new SpinnerNumberModel(3.0, 1.0, 9999.0, 1.0));\n            refreshLabel.setLabelFor(refreshSpinner);\n            refreshUnitsLabel = new JLabel(NbBundle.getMessage(\n                ConnectionsCustomizer.class, \"LBL_RefreshUnits\")); // NOI18N\n\n            setLayout(new GridBagLayout());\n            GridBagConstraints c;\n\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 0;\n            c.fill = GridBagConstraints.NONE;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(BORDER_HEIGHT, 5, BORDER_HEIGHT, 0);\n            add(portLabel, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = 0;\n            c.fill = GridBagConstraints.NONE;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(BORDER_HEIGHT, 5, BORDER_HEIGHT, 0);\n            add(portSpinner, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 2;\n            c.gridy = 0;\n            c.fill = GridBagConstraints.NONE;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(BORDER_HEIGHT, 15, BORDER_HEIGHT, 0);\n            add(refreshLabel, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 3;\n            c.gridy = 0;\n            c.fill = GridBagConstraints.NONE;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(BORDER_HEIGHT, 5, BORDER_HEIGHT, 0);\n            add(refreshSpinner, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 4;\n            c.gridy = 0;\n            c.fill = GridBagConstraints.NONE;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(BORDER_HEIGHT, 5, BORDER_HEIGHT, 5);\n            add(refreshUnitsLabel, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 5;\n            c.gridy = 0;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.gridheight = GridBagConstraints.REMAINDER;\n            c.weightx = 1;\n            c.weighty = 1;\n            c.fill = GridBagConstraints.BOTH;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.insets = new Insets(0, 5, 0, 0);\n            add(Spacer.create(), c);\n\n            setOpaque(true);\n            setBackground(BACKGROUND_COLOR);\n            portLabel.setForeground(FOREGROUND_COLOR);\n            refreshLabel.setForeground(FOREGROUND_COLOR);\n            refreshUnitsLabel.setForeground(FOREGROUND_COLOR);\n\n            JComponent portEditor = portSpinner.getEditor();\n            if (portEditor instanceof JSpinner.DefaultEditor) {\n                final JFormattedTextField tf = ((JSpinner.DefaultEditor)portEditor).getTextField();\n                tf.getDocument().addDocumentListener(new DocumentListener() {\n                    public void insertUpdate(DocumentEvent e) { commitEdit(); }\n                    public void removeUpdate(DocumentEvent e) { commitEdit(); }\n                    public void changedUpdate(DocumentEvent e) { commitEdit(); }\n\n                    private void commitEdit() {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                try {\n                                    int val = (Integer)tf.getFormatter().\n                                            stringToValue(tf.getText().trim());\n                                    if (cd != null) {\n                                        cd.setPort(val);\n                                        updater.run();\n                                    }\n                                } catch (Exception ex) {}\n                            }\n                        });\n                    }\n                });\n            } else {\n                portSpinner.addChangeListener(new ChangeListener() {\n                    public void stateChanged(ChangeEvent e) {\n                        if (cd != null) cd.setPort((Integer)portSpinner.getValue());\n                    }\n                });\n            }\n\n            JComponent refreshEditor = refreshSpinner.getEditor();\n            if (refreshEditor instanceof JSpinner.DefaultEditor) {\n                final JFormattedTextField tf = ((JSpinner.DefaultEditor)refreshEditor).getTextField();\n                tf.getDocument().addDocumentListener(new DocumentListener() {\n                    public void insertUpdate(DocumentEvent e) { commitEdit(); }\n                    public void removeUpdate(DocumentEvent e) { commitEdit(); }\n                    public void changedUpdate(DocumentEvent e) { commitEdit(); }\n\n                    private void commitEdit() {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                try {\n                                    int val = (Integer)tf.getFormatter().\n                                            stringToValue(tf.getText().trim());\n                                    if (cd != null) cd.setRefreshRate(val);\n                                } catch (Exception ex) {}\n                            }\n                        });\n                    }\n                });\n            } else {\n                refreshSpinner.addChangeListener(new ChangeListener() {\n                    public void stateChanged(ChangeEvent e) {\n                        if (cd != null) cd.setRefreshRate((Integer)refreshSpinner.getValue());\n                    }\n                });\n            }\n        }\n\n        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {\n            this.table = table;\n            cd = (ConnectionDescriptor)value;\n\n            portSpinner.setValue(cd.getPort());\n            refreshSpinner.setValue(cd.getRefreshRate());\n\n            updateBorder();\n            KeyboardFocusManager.getCurrentKeyboardFocusManager().\n                    addPropertyChangeListener(\"focusOwner\", listener); // NOI18N\n\n            return this;\n        }\n\n        public Object getCellEditorValue() { return cd; }\n\n        public boolean stopCellEditing() { cleanup(); return true; }\n\n        public boolean isCellEditable(EventObject anEvent) { return true; }\n\n        public boolean shouldSelectCell(EventObject anEvent) { return true; }\n\n        public void cancelCellEditing() { cleanup(); }\n\n        public void addCellEditorListener(CellEditorListener l) {}\n\n        public void removeCellEditorListener(CellEditorListener l) {}\n\n\n        private void cleanup() {\n            KeyboardFocusManager.getCurrentKeyboardFocusManager().\n                    removePropertyChangeListener(\"focusOwner\", listener); // NOI18N\n            table = null;\n            cd = null;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/application/ConnectionsTable.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat.application;\n\nimport java.awt.Component;\nimport java.util.EventObject;\nimport javax.swing.JPanel;\nimport javax.swing.JTable;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.event.CellEditorListener;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.TableCellEditor;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ConnectionsTable extends JTable {\n\n    ConnectionsTable(TableModel model, TableCellRenderer cellRenderer,\n                     TableCellEditor cellEditor) {\n\n        super(model);\n\n        setDefaultRenderer(Object.class, cellRenderer);\n        setDefaultEditor(Object.class, new CellEditor(cellEditor));\n\n        setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        getSelectionModel().addListSelectionListener(new SelectionListener(this));\n\n        setTableHeader(null);\n        \n    }\n\n\n    public void columnMarginChanged(ChangeEvent e) {\n\tresizeAndRepaint();\n    }\n\n    public void editingStopped(ChangeEvent e) {}\n    private void doEditingStopped(ChangeEvent e) {\n        super.editingStopped(e);\n        super.removeEditor();\n    }\n\n    public void editingCanceled(ChangeEvent e) {}\n//    private void doEditingCanceled(ChangeEvent e) {\n//        super.editingCanceled(e);\n//    }\n\n    public void removeEditor() {}\n//    void doRemoveEditor() {\n//        super.removeEditor();\n//    }\n\n\n    private static class SelectionListener implements ListSelectionListener {\n\n        private final ConnectionsTable table;\n        private int lastRow = -1;\n\n\n        SelectionListener(ConnectionsTable table) {\n            this.table = table;\n        }\n\n        public void valueChanged(ListSelectionEvent e) {\n            int row = table.getSelectedRow();\n            if (lastRow == row) return;\n\n            if (lastRow != -1) table.setRowHeight(lastRow, table.getRowHeight());\n            if (row != -1) {\n                table.editCellAt(row, 0, null);\n                if (table.isShowing()) table.requestFocusInWindow();\n            } else {\n                table.doEditingStopped(null);\n            }\n            \n            lastRow = row;\n        }\n        \n    }\n\n\n    private static class CellEditor extends JPanel implements TableCellEditor {\n\n        private final TableCellEditor impl;\n\n\n        CellEditor(TableCellEditor impl) {\n            this.impl = impl;\n        }\n\n        public Component getTableCellEditorComponent(JTable table, Object value,\n                                                     boolean isSelected, int row,\n                                                     int column) {\n            Component editor = impl.getTableCellEditorComponent(table, value,\n                                                     isSelected, row, column);\n            table.setRowHeight(row, editor.getPreferredSize().height);\n            return editor;\n        }\n\n\n        public Object getCellEditorValue() {\n            return impl.getCellEditorValue();\n        }\n\n        public boolean stopCellEditing() {\n            return impl.stopCellEditing();\n        }\n\n        public boolean isCellEditable(EventObject anEvent) {\n            return impl.isCellEditable(anEvent);\n        }\n\n        public boolean shouldSelectCell(EventObject anEvent) {\n            return impl.shouldSelectCell(anEvent);\n        }\n\n        public void cancelCellEditing() {\n            impl.cancelCellEditing();\n        }\n\n        public void addCellEditorListener(CellEditorListener l) {\n            impl.addCellEditorListener(l);\n        }\n\n        public void removeCellEditorListener(CellEditorListener l) {\n            impl.removeCellEditorListener(l);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/application/GeneralPropertiesProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat.application;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport javax.swing.BorderFactory;\nimport javax.swing.JTextArea;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.core.properties.PropertiesPanel;\nimport org.graalvm.visualvm.core.properties.PropertiesProvider;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass GeneralPropertiesProvider extends PropertiesProvider<JvmstatApplication> {\n\n    GeneralPropertiesProvider() {\n        super(NbBundle.getMessage(GeneralPropertiesProvider.class, \"LBL_ConnectionProperties\"), // NOI18N\n              NbBundle.getMessage(GeneralPropertiesProvider.class, \"DESCR_ConnectionProperties\"), // NOI18N\n              CATEGORY_GENERAL, 50);\n    }\n\n\n    public PropertiesPanel createPanel(JvmstatApplication dataSource) {\n        PropertiesPanel panel = new PropertiesPanel();\n        panel.setLayout(new BorderLayout());\n        JTextArea textArea = new JTextArea() {\n            public Dimension getMinimumSize() {\n                Dimension prefSize = getPreferredSize();\n                Dimension minSize = super.getMinimumSize();\n                prefSize.width = 0;\n                if (minSize.height < prefSize.height) return prefSize;\n                else return minSize;\n            }\n        };\n        textArea.setBorder(BorderFactory.createEmptyBorder());\n        textArea.setOpaque(false);\n        // Nimbus LaF doesn't respect setOpaque(false), this is a workaround.\n        // May cause delays for remote X sessions due to color transparency.\n        if (UIManager.getLookAndFeel().getID().equals(\"Nimbus\")) // NOI18N\n            textArea.setBackground(new Color(0, 0, 0, 0));\n        textArea.setEditable(false);\n        textArea.setLineWrap(true);\n        textArea.setWrapStyleWord(true);\n        textArea.setText(NbBundle.getMessage(GeneralPropertiesProvider.class,\n                PropertiesImpl.isLocalConnection(dataSource) ?\n                \"MSG_ConnectionPropertiesDefault\" : \"MSG_ConnectionPropertiesCustom\")); // NOI18N\n        textArea.setMinimumSize(new Dimension(1, 1));\n        textArea.setCaretPosition(0);\n        panel.add(textArea, BorderLayout.CENTER);\n        return panel;\n    }\n\n\n    public boolean supportsDataSource(JvmstatApplication dataSource) { return dataSource != null; }\n\n    public void propertiesDefined(PropertiesPanel panel, JvmstatApplication dataSource) {}\n\n    public void propertiesChanged(PropertiesPanel panel, JvmstatApplication dataSource) {}\n\n    public void propertiesCancelled(PropertiesPanel panel, JvmstatApplication dataSource) {}\n\n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/application/HostPropertiesProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat.application;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.properties.PropertiesPanel;\nimport org.graalvm.visualvm.core.properties.PropertiesProvider;\nimport org.graalvm.visualvm.host.Host;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass HostPropertiesProvider extends PropertiesProvider<Host> {\n\n    /**\n     * Key for the \"jstatd\" properties category.\n     */\n    static final int CATEGORY_JSTATD_CONNECTION = 100;\n\n    private static final String PROP_JSTATD_PORT = \"prop_jstatd_port\"; // NOI18N\n    private static final String PROP_JSTATD_REFRESH = \"prop_jstatd_refresh\"; // NOI18N\n\n\n    HostPropertiesProvider() {\n        super(NbBundle.getMessage(HostPropertiesProvider.class, \"CAP_JstatdProperties\"), // NOI18N\n              NbBundle.getMessage(HostPropertiesProvider.class, \"DESCR_JstatdProperties\"), // NOI18N\n              CATEGORY_JSTATD_CONNECTION, 0); // NOI18N\n    }\n\n\n    public boolean supportsDataSource(Host host) {\n        return true;\n    }\n\n    public PropertiesPanel createPanel(Host host) {\n        return new ConnectionsCustomizer(getDescriptorsEx(host));\n    }\n\n    public void propertiesDefined(PropertiesPanel panel, Host host) {\n        ConnectionsCustomizer customizer = (ConnectionsCustomizer)panel;\n        setDescriptors(host, customizer.getDescriptors());\n    }\n\n    public void propertiesChanged(PropertiesPanel panel, Host host) {\n        ConnectionsCustomizer customizer = (ConnectionsCustomizer)panel;\n        setDescriptorsEx(host, customizer.getDescriptors());\n    }\n\n    public void propertiesCancelled(PropertiesPanel panel, Host host) {\n        // Nothing to do\n    }\n\n\n    static Set<ConnectionDescriptor> descriptorsForHost(Host host) {\n        Set<ConnectionDescriptor> descriptors = getDescriptors(host);\n        if (Host.LOCALHOST.equals(host))\n            descriptors.add(ConnectionDescriptor.DEFAULT_LOCAL_DESCRIPTOR);\n        return cleanup(host, descriptors);\n    }\n\n    private static Set<ConnectionDescriptor> cleanup(Host h, Set<ConnectionDescriptor> d) {\n        Set<ConnectionDescriptor> descriptors = new HashSet<>(d);\n        Iterator<ConnectionDescriptor> iterator = descriptors.iterator();\n        while (iterator.hasNext())\n            if (iterator.next().createHostIdentifier(h) == null)\n                iterator.remove();\n        return descriptors;\n    }\n\n    private static Set<ConnectionDescriptor> getDescriptors(Host host) {\n        Storage storage = host == null ? null : host.getStorage();\n        return getDescriptors(storage);\n    }\n\n    private static Set<ConnectionDescriptor> getDescriptors(Storage storage) {\n        Set<ConnectionDescriptor> set = new HashSet<>();\n\n        if (storage != null) {\n            int index = 0;\n            String port = storage.getCustomProperty(PROP_JSTATD_PORT + \".\" + index); // NOI18N\n            while (port != null) {\n                String refresh = storage.getCustomProperty(PROP_JSTATD_REFRESH + \".\" + index); // NOI18N\n                try {\n                    set.add(new ConnectionDescriptor(Integer.parseInt(port), Double.parseDouble(refresh)));\n                } catch (NumberFormatException e) {\n                    // TODO: log it\n                }\n                port = storage.getCustomProperty(PROP_JSTATD_PORT + \".\" + ++index); // NOI18N\n            }\n        }\n\n        return set;\n    }\n\n    private static Set<ConnectionDescriptor> getDescriptorsEx(Host host) {\n        Set<ConnectionDescriptor> set = getDescriptors(host);\n        if (host == null) set.add(ConnectionDescriptor.createDefault());\n        return set;\n    }\n\n    private static void setDescriptors(Host host, Set<ConnectionDescriptor> descriptors) {\n        setDescriptors(host.getStorage(), descriptors);\n    }\n\n    private static void setDescriptors(Storage storage, Set<ConnectionDescriptor> descriptors) {\n        clearDescriptors(storage);\n        int index = 0;\n        for (ConnectionDescriptor descriptor : descriptors) {\n            storage.setCustomProperty(PROP_JSTATD_PORT + \".\" + index, // NOI18N\n                    Integer.toString(descriptor.getPort()));\n            storage.setCustomProperty(PROP_JSTATD_REFRESH + \".\" + index, // NOI18N\n                    Double.toString(descriptor.getRefreshRate()));\n            index++;\n        }\n    }\n\n    private static void setDescriptorsEx(Host host, Set<ConnectionDescriptor> newDescriptors) {\n        // Cache old descriptors\n        List<ConnectionDescriptor> oldDescriptors = new ArrayList<>(getDescriptorsEx(host));\n\n        // Set new descriptors\n        setDescriptors(host, newDescriptors);\n\n        // Resolve added descriptors\n        Set<ConnectionDescriptor> added = new HashSet<>(newDescriptors);\n        added.removeAll(oldDescriptors);\n        added = cleanup(host, added);\n\n        // Resolve removed descriptors\n        Set<ConnectionDescriptor> removed = new HashSet<>(oldDescriptors);\n        removed.removeAll(newDescriptors);\n        removed = cleanup(host, removed);\n\n        // Resolve changed descriptors\n        Set<ConnectionDescriptor> changed = new HashSet<>(newDescriptors);\n        changed.retainAll(oldDescriptors);\n        Iterator<ConnectionDescriptor> iterator = changed.iterator();\n        while (iterator.hasNext()) {\n            ConnectionDescriptor descriptor1 = iterator.next();\n            ConnectionDescriptor descriptor2 = oldDescriptors.get(\n                    oldDescriptors.indexOf(descriptor1));\n            if (Math.abs(descriptor1.getRefreshRate() -\n                         descriptor2.getRefreshRate()) < 0.001)\n                iterator.remove();\n        }\n        changed = cleanup(host, changed);\n\n        if (!added.isEmpty() || !removed.isEmpty() || !changed.isEmpty())\n            JvmstatApplicationProvider.sharedInstance().connectionsChanged(\n                    host, added, removed, changed);\n    }\n\n    private static void clearDescriptors(Storage storage) {\n        int index = 0;\n        String port = storage.getCustomProperty(PROP_JSTATD_PORT + \".\" + index); // NOI18N\n        while (port != null) {\n            storage.clearCustomProperties(new String[] {\n                PROP_JSTATD_PORT + \".\" + index, PROP_JSTATD_REFRESH + \".\" + index // NOI18N\n            });\n            port = storage.getCustomProperty(PROP_JSTATD_PORT + \".\" + ++index); // NOI18N\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/application/JstatdPropertiesProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat.application;\n\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport javax.swing.JLabel;\nimport javax.swing.JTextField;\nimport org.graalvm.visualvm.core.properties.PropertiesPanel;\nimport org.graalvm.visualvm.core.properties.PropertiesProvider;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.tools.jvmstat.JvmstatModelFactory;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JstatdPropertiesProvider extends PropertiesProvider<JvmstatApplication> {\n\n    /**\n     * Key for the \"jstatd Connection\" properties category.\n     */\n    public static final int CATEGORY_JSTATD_CONNECTION = 200;\n\n\n    JstatdPropertiesProvider() {\n        super(NbBundle.getMessage(JstatdPropertiesProvider.class, \"LBL_JstatdAppProperties\"), // NOI18N\n              NbBundle.getMessage(JstatdPropertiesProvider.class, \"DESCR_JstatdAppProperties\"), // NOI18N\n              CATEGORY_JSTATD_CONNECTION, 0);\n    }\n\n\n    public PropertiesPanel createPanel(JvmstatApplication dataSource) {\n        PropertiesPanel panel = new PropertiesPanel();\n        panel.setLayout(new GridBagLayout());\n\n        GridBagConstraints constraints;\n\n        // connectionLabel\n        JLabel connectionLabel = new JLabel();\n        Mnemonics.setLocalizedText(connectionLabel, NbBundle.getMessage(\n                JstatdPropertiesProvider.class, \"LBL_Connection\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 0;\n        constraints.gridwidth = 1;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(3, 0, 3, 5);\n        panel.add(connectionLabel, constraints);\n\n        // connectionField\n        JTextField connectionField = new JTextField(JvmstatModelFactory.getJvmstatFor(dataSource).getConnectionId());\n        connectionLabel.setLabelFor(connectionField);\n        connectionField.setCaretPosition(0);\n        connectionField.setEditable(false);\n        Dimension size = connectionField.getPreferredSize();\n        size.width = 1;\n        connectionField.setPreferredSize(size);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 1;\n        constraints.gridy = 0;\n        constraints.weightx = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.HORIZONTAL;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(3, 0, 3, 0);\n        panel.add(connectionField, constraints);\n\n        // Filler\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 1;\n        constraints.weighty = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.insets = new Insets(0, 0, 0, 0);\n        panel.add(Spacer.create(), constraints);\n\n        return panel;\n    }\n\n\n    public boolean supportsDataSource(JvmstatApplication dataSource) {\n        return dataSource != null && !PropertiesImpl.isLocalConnection(dataSource);\n    }\n\n    public void propertiesDefined(PropertiesPanel panel, JvmstatApplication dataSource) {}\n\n    public void propertiesChanged(PropertiesPanel panel, JvmstatApplication dataSource) {}\n\n    public void propertiesCancelled(PropertiesPanel panel, JvmstatApplication dataSource) {}\n\n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/application/JvmstatApplication.java",
    "content": "/*\n * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat.application;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.host.Host;\nimport sun.jvmstat.monitor.HostIdentifier;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class JvmstatApplication extends Application {   \n    \n    final private int pid;\n    final HostIdentifier hostId;\n    // since getting JVM for the first time can take a long time\n    // hard reference jvm from application so we are sure that it is not garbage collected\n    Jvm jvm;\n\n    JvmstatApplication(Host host, HostIdentifier hostId, String id, int pid) {\n        super(host, id);\n        this.pid = pid;\n        this.hostId = hostId;\n    }\n    \n    \n    public int getPid() {\n        return pid;\n    }\n    \n    \n    public boolean supportsUserRemove() {\n        return getState() == Stateful.STATE_UNAVAILABLE;\n    }\n    \n    protected boolean handleControlledRemove() {\n        return super.handleControlledRemove();\n    }\n    \n\n    protected void remove() {\n        super.remove();\n        JvmstatApplicationProvider.sharedInstance().removeFromMap(this);\n    }\n    \n    \n    void setStateImpl(int newState) {\n        setState(newState);\n    }\n\n    HostIdentifier getHostIdentifier() {\n       return hostId; \n    }\n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/application/JvmstatApplicationProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat.application;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.File;\nimport java.net.URL;\nimport java.rmi.ConnectException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.core.ui.DesktopUtils;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.uisupport.HTMLLabel;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.Utilities;\nimport sun.jvmstat.monitor.HostIdentifier;\nimport sun.jvmstat.monitor.MonitorException;\nimport sun.jvmstat.monitor.MonitoredHost;\nimport sun.jvmstat.monitor.event.HostEvent;\nimport sun.jvmstat.monitor.event.HostListener;\nimport sun.jvmstat.monitor.event.VmStatusChangeEvent;\n\n/**\n * A provider for Applications discovered by jvmstat.\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic class JvmstatApplicationProvider implements DataChangeListener<Host> {\n    private static final Logger LOGGER = Logger.getLogger(JvmstatApplicationProvider.class.getName());\n\n    private static final RequestProcessor PROCESSOR =\n            new RequestProcessor(\"JvmstatApplicationProvider Processor\", 10); // NOI18N\n    \n    private static JvmstatApplicationProvider instance;\n    \n    private final Map<String, JvmstatApplication> applications = new HashMap<>();\n    private final Map<Host,Map<HostIdentifier,JvmstatConnection>> hostsListeners = new HashMap<>();\n    \n    static synchronized JvmstatApplicationProvider sharedInstance() {\n        if (instance == null) {\n            instance = new JvmstatApplicationProvider();\n        }\n        return instance;\n    }\n    \n    public void dataChanged(DataChangeEvent<Host> event) {\n        Set<Host> newHosts = event.getAdded();\n        for (final Host host : newHosts) {\n            // run new host in request processor, since it will take\n            // a long time that there is no jstatd running on new host\n            // we do not want to block DataSource.EVENT_QUEUE for long time\n            PROCESSOR.post(new Runnable() {\n                public void run() {\n                    processNewHost(host);\n                }\n            });\n        }\n        Set<Host> removedHosts = event.getRemoved();\n        for (final Host host : removedHosts) {\n            // run removed host in request processor, since it can take\n            // a long time and we do not want to block DataSource.EVENT_QUEUE\n            // for long time\n            PROCESSOR.post(new Runnable() {\n                public void run() {\n                    processFinishedHost(host);\n                }\n            });\n        }\n    }\n    \n    private void processNewHost(final Host host) {\n        if (host == Host.UNKNOWN_HOST) return;\n        \n        Set<ConnectionDescriptor> descrs = HostPropertiesProvider.descriptorsForHost(host);\n        registerJvmstatConnections(host, descrs);\n    }\n    \n    private void registerJvmstatConnections(final Host host, final Set<ConnectionDescriptor> descrs) {\n        for (ConnectionDescriptor desc : descrs) {\n            int interval = (int)(desc.getRefreshRate()*1000);\n            HostIdentifier hostId = desc.createHostIdentifier(host);\n            registerJvmstatConnection(host,hostId,interval);\n        }\n    }\n    \n    private void processChangedJvmstatConnection(Host host, ConnectionDescriptor changedConnection) {\n        HostIdentifier hostId = changedConnection.createHostIdentifier(host);\n        MonitoredHost monitoredHost = getMonitoredHost(hostId);\n        if (monitoredHost != null) {\n            int interval = (int)(changedConnection.getRefreshRate()*1000);\n            monitoredHost.setInterval(interval);\n        }\n    }\n    \n    private void processFinishedHost(final Host host) {\n        if (host == Host.UNKNOWN_HOST) return;\n        \n        synchronized (hostsListeners) {\n            Map<HostIdentifier,JvmstatConnection> hostListeners = hostsListeners.get(host);\n            \n            if (hostListeners != null) {\n                for (JvmstatConnection listener : new ArrayList<>(hostListeners.values())) {\n                    processDisconnectedJvmstat(host, listener);\n                }\n            }\n        }\n    }\n    \n    private void processRemovedJvmstatConnection(final Host host, HostIdentifier hostId) {\n        if (host == Host.UNKNOWN_HOST) return;\n        \n        synchronized (hostsListeners) {\n            Map<HostIdentifier,JvmstatConnection> hostListeners = hostsListeners.get(host);\n            \n            if (hostListeners != null) {\n                JvmstatConnection listener = hostListeners.get(hostId);\n                if (listener != null) {\n                    processDisconnectedJvmstat(host, listener);\n                }\n            }\n        }\n    }\n    \n    private void processDisconnectedJvmstat(Host host, JvmstatConnection listener) {\n        HostIdentifier hostId = listener.monitoredHost.getHostIdentifier();\n        try { listener.monitoredHost.removeHostListener(listener); } catch (MonitorException ex) {}\n        unregisterHostListener(host,hostId);\n        Set<JvmstatApplication> jvmstatApplications = host.getRepository().getDataSources(JvmstatApplication.class);\n        Iterator<JvmstatApplication> appIt = jvmstatApplications.iterator();\n        while (appIt.hasNext()) {\n            JvmstatApplication application = appIt.next();\n            \n            if (application.getHostIdentifier().equals(hostId)) {\n                application.setStateImpl(Stateful.STATE_UNAVAILABLE);\n                if (application.handleControlledRemove()) appIt.remove();\n            } else {\n                appIt.remove();\n            }\n        }\n        host.getRepository().removeDataSources(jvmstatApplications);\n    }\n    \n    private void processNewApplicationsByPids(Host host, HostIdentifier hostId, Set<Integer> applicationPids) {\n        Set<JvmstatApplication> newApplications = new HashSet<>();\n        \n        for (int applicationPid : applicationPids) {\n            // Do not provide instance for Application.CURRENT_APPLICATION\n            if (Application.CURRENT_APPLICATION.getPid() == applicationPid && Host.LOCALHOST.equals(host)) {\n                continue;\n            }\n            \n            String appId = createId(host, applicationPid);\n            JvmstatApplication application = new JvmstatApplication(host, hostId, appId, applicationPid);\n            if (!applications.containsKey(appId)) {\n                // precompute JVM\n                application.jvm = JvmFactory.getJVMFor(application);\n                applications.put(appId, application);\n                newApplications.add(application);\n            } else {\n                JvmstatApplication zombieApp = applications.get(appId);\n                if (zombieApp != null && zombieApp.getState() == Stateful.STATE_UNAVAILABLE) {\n                    zombieApp.setStateImpl(Stateful.STATE_AVAILABLE);\n                    zombieApp.jvm = JvmFactory.getJVMFor(zombieApp);\n                }\n            }\n        }\n        \n        host.getRepository().addDataSources(newApplications);\n    }\n    \n    private void processTerminatedApplicationsByPids(Host host, Set<Integer> applicationPids) {\n        Set<JvmstatApplication> finishedApplications = new HashSet<>();\n        \n        for (int applicationPid : applicationPids) {\n            String appId = createId(host, applicationPid);\n            if (applications.containsKey(appId)) {\n                JvmstatApplication application = applications.get(appId);\n                if (application != null) {\n                    application.setStateImpl(Stateful.STATE_UNAVAILABLE);\n                    if (!application.handleControlledRemove()) finishedApplications.add(application);\n                }\n                applications.remove(appId);\n            }\n        }\n        \n        host.getRepository().removeDataSources(finishedApplications);\n    }\n    \n    private void registerHostListener(Host host,HostIdentifier hostId,JvmstatConnection hostListener) {\n        synchronized (hostsListeners) {\n            Map<HostIdentifier,JvmstatConnection> hostListeners = hostsListeners.get(host);\n            \n            if (hostListeners == null) {\n                hostListeners = new HashMap<>();\n                hostsListeners.put(host,hostListeners);\n            }\n            hostListeners.put(hostId,hostListener);\n        }\n    }\n    \n    private void unregisterHostListener(Host host,HostIdentifier hostId) {\n        synchronized (hostsListeners) {\n            Map<HostIdentifier,JvmstatConnection> hostListeners = hostsListeners.get(host);\n            \n            assert hostListeners != null;\n            hostListeners.remove(hostId);\n        }\n    }\n    \n    private void registerJvmstatConnection(Host host, HostIdentifier hostId, int interval) {\n        // Monitor the Host for new/finished Applications\n        // NOTE: the code relies on the fact that the provider is the first listener registered in MonitoredHost of the Host\n        // in which case the first obtained event contains all applications already running on the Host\n        JvmstatConnection hostListener = null;\n        \n        // Get the MonitoredHost for Host\n        final MonitoredHost monitoredHost = getMonitoredHost(hostId);\n        \n        if (monitoredHost == null) { // monitored host not available reschedule\n            rescheduleProcessNewHost(host,hostId);\n            return;\n        }\n        hostId = monitoredHost.getHostIdentifier();\n        monitoredHost.setInterval(interval);\n        if (host == Host.LOCALHOST) checkForBrokenLocalJps(monitoredHost);\n        try {\n            // Fetch already running applications on the host\n            processNewApplicationsByPids(host, hostId, monitoredHost.activeVms());\n            hostListener = new JvmstatConnection(host, monitoredHost);\n            monitoredHost.addHostListener(hostListener);\n            registerHostListener(host, hostId, hostListener);\n        } catch (MonitorException e) {\n            Throwable t = e.getCause();\n            monitoredHost.setLastException(e);\n            if (!(t instanceof ConnectException)) {\n                DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(\n                        NbBundle.getMessage(JvmstatApplicationProvider.class, \"MSG_Broken_Jvmstat\", // NOI18N\n                        DataSourceDescriptorFactory.getDescriptor(host).getName()),\n                        NotifyDescriptor.ERROR_MESSAGE));\n                LOGGER.log(Level.INFO, \"Jvmstat connection to \" + host + \" failed.\", t); // NOI18N\n            } else {\n                rescheduleProcessNewHost(host,hostId);\n            }\n        }\n    }\n    \n    private String createId(Host host, int pid) {\n        return host.getHostName() + \"-\" + pid;\n    }\n    \n    void removeFromMap(JvmstatApplication jvmstatApplication) {\n        applications.remove(jvmstatApplication.getId());\n    }\n    \n    // TODO: reimplement to listen for Host.getState() == STATE_UNAVAILABLE\n    //    private void processAllTerminatedApplications(Host host) {\n    //        Set<JvmstatApplication> applicationsSet = host.getRepository().getDataSources(JvmstatApplication.class);\n    //        Set<JvmstatApplication> finishedApplications = new HashSet();\n    //\n    //        for (JvmstatApplication application : applicationsSet)\n    //            if (applications.containsKey(application.getPid())) {\n    //                applications.remove(application.getPid());\n    //                finishedApplications.add(application);\n    //            }\n    //\n    //        host.getRepository().removeDataSources(finishedApplications);\n    //    }\n    \n    // Checks broken jps according to https://netbeans.org/bugzilla/show_bug.cgi?id=115490\n    // Checks broken jps according to https://java.net/jira/browse/VISUALVM-311\n    private void checkForBrokenLocalJps(MonitoredHost monitoredHost) {\n        try {\n            if (!monitoredHost.activeVms().isEmpty()) {\n\n                if (Utilities.isWindows()) {\n                    String perf = \"hsperfdata_\" + System.getProperty(\"user.name\"); // NOI18N\n                    File perfCorrect = new File(System.getProperty(\"java.io.tmpdir\"), perf); // NOI18N\n                    File perfCurrent = perfCorrect.getCanonicalFile(); // Resolves real capitalization\n                    if (!perfCorrect.getName().equals(perfCurrent.getName())) {\n                        String link = DesktopUtils.isBrowseAvailable() ? NbBundle.getMessage(JvmstatApplicationProvider.class, \"MSG_Broken_Jps2_Link\")   // NOI18N\n                                : NbBundle.getMessage(JvmstatApplicationProvider.class, \"MSG_Broken_Jps2_NoLink\");   // NOI18N\n                        String message = NbBundle.getMessage(JvmstatApplicationProvider.class, \"MSG_Broken_Jps2\", link); // NOI18N\n                        notifyBrokenJps(message);\n                    }\n                }\n\n                return;\n            }\n        } catch (Exception e) {\n            return;\n        }\n\n        String link = DesktopUtils.isBrowseAvailable() ? NbBundle.getMessage(JvmstatApplicationProvider.class, \"MSG_Broken_Jps_Link\")   // NOI18N\n                : NbBundle.getMessage(JvmstatApplicationProvider.class, \"MSG_Broken_Jps_NoLink\");   // NOI18N\n        String message = NbBundle.getMessage(JvmstatApplicationProvider.class, \"MSG_Broken_Jps\", link); // NOI18N\n        notifyBrokenJps(message);\n    }\n\n    private static void notifyBrokenJps(String message) {\n        final HTMLLabel label = new HTMLLabel(message) {\n            protected void showURL(URL url) {\n                try {\n                    DesktopUtils.browse(url.toURI());\n                } catch (Exception e) {}\n            }\n        };\n\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                NotifyDescriptor nd = new NotifyDescriptor.Message(label, NotifyDescriptor.ERROR_MESSAGE);\n                DialogDisplayer.getDefault().notify(nd);\n            }\n        });\n    }\n    \n    private MonitoredHost getLocalMonitoredHost() {\n        try {\n            return MonitoredHost.getMonitoredHost(\"localhost\"); // NOI18N\n        } catch (Exception ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n    \n    private MonitoredHost getMonitoredHost(HostIdentifier hostId) {\n        try {\n            return MonitoredHost.getMonitoredHost(hostId);\n        } catch (MonitorException ex) {\n            // NOTE: valid state, jstatd not running, Host will be scheduled for later MonitoredHost resolving\n            //            ErrorManager.getDefault().log(ErrorManager.WARNING,ex.getLocalizedMessage());\n        }\n        return null;\n    }\n    \n    public MonitoredHost getMonitoredHost(Application app) {\n        JvmstatApplication japp;\n        \n        if (Application.CURRENT_APPLICATION.equals(app)) {\n            return getLocalMonitoredHost();\n        }\n        if (!(app instanceof JvmstatApplication)) {\n            Host host = app.getHost();\n            String appId = createId(host, app.getPid());\n\n            japp = applications.get(appId);\n            if (japp!=null && !host.equals(japp.getHost())) {\n                // app is application running on different host via e.g. ssh tunnel\n                japp = null;\n            }\n        } else {\n            japp = (JvmstatApplication) app;\n        }\n        if (japp != null) {\n            return getMonitoredHost(japp.getHostIdentifier());\n        }\n        return null;\n    }\n    \n    private void rescheduleProcessNewHost(final Host host,final HostIdentifier hostId) {\n        int timerInterval = GlobalPreferences.sharedInstance().getMonitoredHostPoll();\n        Timer timer = new Timer(timerInterval*1000, new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                // do not block EQ - use request processor, processNewHost() can take a long time\n                PROCESSOR.post(new Runnable() {\n                    public void run() {\n                        if (!host.isRemoved()) {\n                            Set<ConnectionDescriptor> descriptors = HostPropertiesProvider.descriptorsForHost(host);\n                            \n                            for (ConnectionDescriptor desc : descriptors) {\n                                if (hostId.equals(desc.createHostIdentifier(host))) {\n                                    int interval = (int)(desc.getRefreshRate()*1000);\n                                    registerJvmstatConnection(host,hostId,interval);\n                                }\n                            }\n                        }\n                    }\n                });\n            }\n        });\n        timer.setRepeats(false);\n        timer.start();\n    }\n    \n    public static void register() {\n        DataSourceRepository.sharedInstance().addDataChangeListener(sharedInstance(), Host.class);\n    }\n    \n    public static MonitoredHost findMonitoredHost(Application app) {\n        return sharedInstance().getMonitoredHost(app);\n    }\n    \n    // Invoked from AWT thread\n    void connectionsChanged(final Host host, final Set<ConnectionDescriptor> added, final Set<ConnectionDescriptor> removed, final Set<ConnectionDescriptor> changed) {\n        PROCESSOR.post(new Runnable() {\n            public void run() {\n                registerJvmstatConnections(host,added);\n                for (ConnectionDescriptor removedConnection : removed) {\n                    processRemovedJvmstatConnection(host, removedConnection.createHostIdentifier(host));\n                }\n                for (ConnectionDescriptor changedConnection : changed) {\n                    processChangedJvmstatConnection(host, changedConnection);\n                }\n            }\n        });\n    }\n    \n    private class JvmstatConnection implements HostListener {\n        \n        // Flag for determining first MonitoredHost event\n        private boolean firstEvent = true;\n        private Host host;\n        private MonitoredHost monitoredHost;\n        \n        private JvmstatConnection(Host host, MonitoredHost mHost) {\n            this.host = host;\n            monitoredHost = mHost;\n        }\n        \n        public void vmStatusChanged(final VmStatusChangeEvent e) {\n            if (firstEvent) {\n                if (LOGGER.isLoggable(Level.FINER)) {\n                    LOGGER.finer(\"Monitored Host (\" + host.getHostName() + \") status changed - adding all active applications\");\n                }\n                firstEvent = false;\n                processNewApplicationsByPids(host, monitoredHost.getHostIdentifier(), e.getActive());\n            } else {\n                processNewApplicationsByPids(host, monitoredHost.getHostIdentifier(), e.getStarted());\n                processTerminatedApplicationsByPids(host, e.getTerminated());\n            }\n        }\n        \n        public void disconnected(HostEvent e) {\n            processDisconnectedJvmstat(host, this);\n            rescheduleProcessNewHost(host,monitoredHost.getHostIdentifier());\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/application/PropertiesImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.jvmstat.application;\n\nimport org.graalvm.visualvm.core.properties.PropertiesSupport;\nimport org.graalvm.visualvm.host.Host;\nimport sun.jvmstat.monitor.HostIdentifier;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class PropertiesImpl {\n    \n    private static final String LOCAL_JVMSTAT_URI = \"local://localhost\"; // NOI18N\n    \n\n    static boolean isLocalConnection(JvmstatApplication dataSource) {\n        HostIdentifier hi = dataSource.getHostIdentifier();\n        return LOCAL_JVMSTAT_URI.equals(hi.getURI().toString());\n    }\n\n\n    public static void initialize() {\n        PropertiesSupport.sharedInstance().registerPropertiesProvider(\n                new HostPropertiesProvider(), Host.class);\n        PropertiesSupport.sharedInstance().registerPropertiesProvider(\n                new GeneralPropertiesProvider(), JvmstatApplication.class);\n        PropertiesSupport.sharedInstance().registerPropertiesProvider(\n                new JstatdPropertiesProvider(), JvmstatApplication.class);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/jvmstat/src/org/graalvm/visualvm/jvmstat/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n\n    <folder name=\"VisualVM\">\n        <folder name=\"Actions\">\n            <file name=\"org-graalvm-visualvm-jvmstat-application-AddJstatdConnectionAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.jvmstat.application.AddJstatdConnectionAction.instance\"/>\n            </file>\n        </folder>\n\n        <folder name=\"ExplorerPopupSelection\">\n\n            <file name=\"org-graalvm-visualvm-jvmstat-application-AddJstatdConnectionAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-jvmstat-application-AddJstatdConnectionAction.instance\"/>\n                <attr name=\"position\" intvalue=\"150\"/>\n            </file>\n            \n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "visualvm/killapp/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.killapp\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.killapp.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/killapp/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.modules.killapp/1\nOpenIDE-Module-Layer: org/graalvm/visualvm/modules/killapp/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/killapp/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.2\n\n"
  },
  {
    "path": "visualvm/killapp/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.killapp-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/killapp/nbproject/project.properties",
    "content": "javac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Tomas Hurka\nrun.args.extra=--branding visualvm\nmodule.javadoc.packages=org.graalvm.visualvm.modules.killapp.*\n\n"
  },
  {
    "path": "visualvm/killapp/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.modules.killapp</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.12</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.13</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/killapp/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/killapp/src/org/graalvm/visualvm/modules/killapp/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Tools\nOpenIDE-Module-Long-Description=\\\n    This simple module adds ability to quicky kill locally running Java application.\nOpenIDE-Module-Name=VisualVM-Kill Application\nOpenIDE-Module-Short-Description=Kill Application\n"
  },
  {
    "path": "visualvm/killapp/src/org/graalvm/visualvm/modules/killapp/KillAction.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.killapp;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.core.ui.actions.MultiDataSourceAction;\nimport org.graalvm.visualvm.host.Host;\nimport java.awt.event.ActionEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.SwingUtilities;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.Utilities;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic final class KillAction extends MultiDataSourceAction<Application> {\n    \n    private final Set<Application> lastSelectedApplications;\n    private final RequestProcessor killRP;\n    private final PropertyChangeListener stateListener;\n\n    @NbBundle.Messages({\"CTL_KillAction=Kill Application\"})\n    public KillAction() {\n        super(Application.class);\n        putValue(NAME, Bundle.CTL_KillAction());\n        putValue(\"noIconInMenu\", Boolean.TRUE); // NOI18N\n        lastSelectedApplications = new HashSet<>();\n        killRP = new RequestProcessor(\"KillAction processor\", 5);   // NOI18N\n        stateListener = new PropertyChangeListener() {\n            public void propertyChange(PropertyChangeEvent evt) {\n                updateState(ActionUtils.getSelectedDataSources(Application.class));\n            }\n        };\n    }\n\n    @Override\n    protected void actionPerformed(Set<Application> dataSources, ActionEvent ae) {\n        for (Application dataSource : dataSources) {\n            killApplication(dataSource);\n        }\n    }\n\n    @Override\n    protected boolean isEnabled(Set<Application> dataSources) {\n        for (Application application : dataSources) {\n            lastSelectedApplications.add(application);\n            application.addPropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n            if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n            if (!isEnabled(application)) return false;\n        }\n        return true;\n    }\n\n    @Override\n    protected void updateState(Set<Application> dataSources) {\n        if (!lastSelectedApplications.isEmpty())\n            for (Application application : lastSelectedApplications)\n                application.removePropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n        lastSelectedApplications.clear();\n        super.updateState(dataSources);\n    }\n\n    private void killApplication(final Application app) {\n        final String pidString = String.valueOf(app.getPid());\n        final String[] command = getCommand(pidString, false);\n\n        if (command == null) {\n            return;\n        }\n\n        final Progress handle = new Progress(pidString);\n        app.notifyWhenRemoved(handle);\n        killRP.post(new Runnable() {\n            public void run() {\n                try {\n                    Runtime.getRuntime().exec(command);\n                    Thread.sleep(5000);\n                    if (app.getState() == Stateful.STATE_AVAILABLE) {\n                        // application is still alive, try to kill it hard way\n                        Runtime.getRuntime().exec(getCommand(pidString, true));\n                        refreshJvms();\n                    }\n                } catch (IOException ex) {\n                    Exceptions.printStackTrace(ex);\n                } catch (InterruptedException ex) {\n                    Exceptions.printStackTrace(ex);\n                } finally {\n                    handle.finish();\n                }\n            }\n        });\n    }\n\n    private void refreshJvms() throws IOException {\n        String javaSub = Utilities.isWindows() ? \"bin\\\\java.exe\" : \"bin/java\"; // NOI18N\n        File java = new File(System.getProperty(\"java.home\"), javaSub); // NOI18N\n\n        if (java.isFile()) {\n            String command[] = {java.getAbsolutePath(), \"-version\"};\n            Runtime.getRuntime().exec(command);\n        }\n    }\n\n    private boolean isEnabled(Application application) {\n        if (Application.CURRENT_APPLICATION.equals(application)) {\n            // don't commit suicide\n            return false;\n        }\n        if (!Host.LOCALHOST.equals(application.getHost())) {\n            // we cannot kill remote applications\n            return false;\n        }\n        return true;\n    }\n\n    private String[] getCommand(String pidString, boolean force) {\n        if (Utilities.isWindows()) {\n            if (force) {\n                return new String[]{\"taskkill\", \"/F\", \"/PID\", pidString};    // NOI18N                \n            } else {\n                return new String[]{\"taskkill\", \"/PID\", pidString};    // NOI18N\n            }\n        } else if (Utilities.isUnix()) {\n            if (force) {\n                return new String[]{\"kill\", \"-9\", pidString};   // NOI18N                \n            } else {\n                return new String[]{\"kill\", pidString};   // NOI18N\n            }\n        } else {\n            assert false : \"strange os\";  // NOI18N\n            return null;\n        }\n    }\n\n    @NbBundle.Messages({\"MSG_Kill=Killing application with PID {0}\"})\n    private static class Progress implements DataRemovedListener<Application>{\n\n        ProgressHandle handle;\n        boolean running;\n        \n        private Progress(String pid) {\n            handle = ProgressHandle.createHandle(Bundle.MSG_Kill(pid));\n            handle.setInitialDelay(500);\n            handle.start();\n            running = true;\n        }\n\n        private synchronized void finish() {\n            if (running) {\n                running = false;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        handle.finish();\n                        handle = null;\n                    }\n                });\n            }\n        }\n\n        public void dataRemoved(Application x) {\n            finish();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/killapp/src/org/graalvm/visualvm/modules/killapp/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    <folder name=\"Actions\">\n        <folder name=\"Other\">\n            <file name=\"org-graalvm-visualvm-modules-killapp-KillAction.instance\"/>\n        </folder>\n    </folder>\n    <folder name=\"Menu\">\n        <folder name=\"Applications\">\n            <file name=\"Kill-Separator-2950.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"2910\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-modules-killapp-KillAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-modules-killapp-KillAction.instance\"/>\n                <attr name=\"position\" intvalue=\"2911\"/>\n            </file>\n        </folder>\n    </folder>\n    <folder name=\"VisualVM\">\n        <folder name=\"ExplorerPopupSelection\">\n            <file name=\"Kill-Separator-1950.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"1910\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-modules-killapp-KillAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"Actions/Other/org-graalvm-visualvm-modules-killapp-KillAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1911\"/>\n            </file>\n        </folder>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "visualvm/launcher/visualvm",
    "content": "#!/bin/sh\n#\n# Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n#\n# resolve symlinks\n#\n\nPRG=$0\n\nwhile [ -h \"$PRG\" ]; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '^.*-> \\(.*\\)$' 2>/dev/null`\n    if expr \"$link\" : '^/' 2> /dev/null >/dev/null; then\n\tPRG=\"$link\"\n    else\n\tPRG=\"`dirname \"$PRG\"`/$link\"\n    fi\ndone\n\nif [ -f \"`dirname \"$PRG\"`/../Resources/visualvm/etc/visualvm.conf\" ] ; then\n    PRG=\"`dirname \"$PRG\"`/../Resources/visualvm/bin/visualvm\"\nfi\n\nprogdir=`dirname \"$PRG\"`\nold=`pwd`\ncd \"$progdir\"/..\nbasedir=`pwd`\ncd \"$old\"\n\ncase \"`uname`\" in\n    Darwin*)\n        # set default userdir and cachedir on macOS\n        DEFAULT_USERDIR_ROOT=\"${HOME}/Library/Application Support/VisualVM\"\n        DEFAULT_CACHEDIR_ROOT=${HOME}/Library/Caches/VisualVM\n        ;;\n    *) \n        # set default userdir and cachedir on unix systems\n        DEFAULT_USERDIR_ROOT=${HOME}/.visualvm\n        DEFAULT_CACHEDIR_ROOT=${HOME}/.cache/visualvm\n        ;;\nesac\n\n\nif [ -f \"$progdir\"/../lib/visualvm/etc/visualvm.conf ] ; then\n    visualvm_jdkhome=\"$basedir\"\n    old=`pwd`\n    cd \"$progdir/../lib/visualvm/\"\n    basedir=`pwd`\n    cd \"$old\"\n    . \"$progdir\"/../lib/visualvm/etc/visualvm.conf\nelif [ -f \"$progdir\"/../etc/visualvm.conf ] ; then\n    . \"$progdir\"/../etc/visualvm.conf\nfi\n\n\nexport DEFAULT_USERDIR_ROOT\n\n# #68373: look for userdir, but do not modify \"$@\"\nuserdir=\"${visualvm_default_userdir}\"\ncachedir=\"${visualvm_default_cachedir}\"\n\nfounduserdir=\"\"\nfor opt in \"$@\"; do\n    if [ \"${founduserdir}\" = \"yes\" ]; then\n        userdir=\"$opt\"\n        break\n    elif [ \"$opt\" = \"--userdir\" ]; then\n        founduserdir=\"yes\"\n    fi\ndone\nfoundcachedir=\"\"\nfor opt in \"$@\"; do\n    if [ \"${foundcachedir}\" = \"yes\" ]; then\n        cachedir=\"$opt\"\n        break\n    elif [ \"$opt\" = \"--cachedir\" ]; then\n        foundcachedir=\"yes\"\n    fi\ndone\n\nif [ -f \"${userdir}\"/etc/visualvm.conf ] ; then\n    . \"${userdir}\"/etc/visualvm.conf\nfi\n\n\nif [ ! -f \"$basedir\"/etc/visualvm.clusters ]; then\n    echo Cannot read cluster file: \"$basedir\"/etc/visualvm.clusters 1>&2\n    exit 1\nfi\n\nreadClusters() {\n    grep -v \"^#\" \"$basedir\"/etc/visualvm.clusters | grep -v \"^$\" | grep -v platform | while read X; do\n        if expr \"$X\" : \"/.*\" >/dev/null; then\n            echo \"$X\"\n        else\n            echo \"$basedir/$X\"\n        fi\n    done\n}\n\nabsolutize_paths() {\n    while read path; do\n        if [ -d \"$path\" ]; then\n            (cd \"$path\" 2>/dev/null && pwd)\n        else\n            echo \"$path\"\n        fi\n    done\n}\n\nvisualvm_clusters=`readClusters | absolutize_paths | tr '\\012' ':'`\n\nif [ ! -z \"$visualvm_extraclusters\" ] ; then\n    visualvm_clusters=\"$visualvm_clusters:$visualvm_extraclusters\"\nfi\n\nheap_size () {\n    mem=640\n    case \"`uname`\" in\n        Linux*)\n        mem=`cat /proc/meminfo | grep MemTotal | tr -d [:space:][:alpha:]:`\n        mem=`expr $mem / 1024`\n        ;;\n    SunOS*)\n        mem=`/usr/sbin/prtconf | grep Memory | /usr/bin/tr -dc '[0-9]'`\n        ;;\n    Darwin*)\n        mem=`/usr/sbin/sysctl hw.memsize | tr -d [:alpha:][:space:].:`\n        mem=`expr $mem / 1048576`\n        ;;\n        *) \n        ;;\n    esac\n    if [ -z \"$mem\" ] ; then\n        mem=640\n    fi\n    mem=`expr $mem / 5`\n    if [ $mem -gt 1024 ] ; then\n        mem=1024\n    elif [ $mem -lt 96 ] ; then\n        mem=96\n    fi\n    max_heap_size=$mem\n    return 0\n}\n\n\nif grep -v -- \"-J-Xmx\" >/dev/null <<EOF ; then\n${visualvm_default_options}\nEOF\n        heap_size\n\tvisualvm_default_options=\"-J-Xmx${max_heap_size}m ${visualvm_default_options}\"\nfi\n\nlaunchNbexec() {\n    nbexec=`grep -v \"^#\" \"$basedir\"/etc/visualvm.clusters | grep -v \"^$\" | grep platform | while read X; do\n        if expr \"$X\" : \"/.*\" >/dev/null; then\n           echo $X/lib/nbexec\n        elif [ -f \"$basedir\"/$X/lib/nbexec ]; then\n            echo \"$basedir\"/$X/lib/nbexec\n        fi\n    done | head -n 1`\n    if [ \\! -n \"$nbexec\" ] ; then\n      nbexec=\"$basedir\"/platform/lib/nbexec\n    fi\n    sh=sh\n    # #73162: Ubuntu uses the ancient Bourne shell, which does not implement trap well.\n    if [ -x /bin/bash ]\n    then\n        sh=/bin/bash\n    fi\n    if [ \"${founduserdir}\" = \"yes\" ]; then\n        exec $sh \"$nbexec\" \"$@\"\n    else\n        if [ \"${foundcachedir}\" = \"yes\" ]; then\n            exec $sh \"$nbexec\" --userdir \"${userdir}\" \"$@\"\n        else\n            exec $sh \"$nbexec\" --userdir \"${userdir}\" --cachedir \"${cachedir}\" \"$@\"\n        fi\n    fi\n}\n\n# in case of macOS, the apple.laf.useScreenMenuBar property should be ideally in the Info.plist file\n# but it doesn't get propagated into the executed java VM. \ncase \"`uname`\" in\n    Darwin*)\n        eval launchNbexec \\\n            --jdkhome '\"$visualvm_jdkhome\"' \\\n            -J-Xdock:name=VisualVM \\\n            '\"-J-Xdock:icon=$basedir/etc/visualvm.icns\"' \\\n            --branding visualvm \\\n            --clusters '\"$visualvm_clusters\"' \\\n            ${visualvm_default_options} \\\n            '\"$@\"'\n        ;;\n    *)\n        eval launchNbexec \\\n            --jdkhome '\"$visualvm_jdkhome\"' \\\n            --branding visualvm \\\n            --clusters '\"$visualvm_clusters\"' \\\n            ${visualvm_default_options} \\\n            '\"$@\"'\n        ;;\nesac\n"
  },
  {
    "path": "visualvm/launcher/visualvm.conf",
    "content": "#\n# Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n# Default locations of userdir and cachedir:\n#\n# On Windows ${DEFAULT_USERDIR_ROOT} will be replaced by the launcher\n# with \"<AppData>\\VisualVM\" where <AppData> is user's\n# value of \"AppData\" key in Windows Registry under\n# \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\"\n# and ${DEFAULT_CACHEDIR_ROOT} will be replaced by the launcher\n# with \"<Local AppData>\\VisualVM\\Cache\" where <Local AppData> is user's\n# value of \"Local AppData\" key in Windows Registry under\n# \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\"\n#\n# On Mac ${DEFAULT_USERDIR_ROOT} will be replaced by the launcher\n# with \"~/Library/Application Support/VisualVM\" and\n# ${DEFAULT_CACHEDIR_ROOT} with \"~/Library/Caches/VisualVM\"\n#\n# On other systems ${DEFAULT_USERDIR_ROOT} will be replaced by the launcher\n# with \"~/.visualvm\" and ${DEFAULT_CACHEDIR_ROOT} with \"~/.cache/visualvm\"\n#\n# You can also use ${HOME} variable which will be replaced with\n# user.home JVM system property value. This variable is valid only in\n# visualvm_default_userdir and visualvm_default_cachedir properties.\n#\n# NOTE: If you specify a non-default userdir path on command line\n# (--userdir option) and don't specify a cachedir path (--cachedir option),\n# cachedir will be in \"<userdir>/var/cache\".\n#\n# Cachedir must be different from userdir. The same cachedir and userdir\n# would cause problems.\n#\nvisualvm_default_userdir=\"${DEFAULT_USERDIR_ROOT}/dev\"\nvisualvm_default_cachedir=\"${DEFAULT_CACHEDIR_ROOT}/dev\"\n\n# Options used by VisualVM launcher by default:\n# (can be overridden by explicit command line switches)\n#\n\nvisualvm_default_options=\"-J-Xms24m -J-Xmx768m -J-Dnetbeans.accept_license_class=org.graalvm.visualvm.modules.startup.AcceptLicense -J-Dnetbeans.importclass=org.graalvm.visualvm.modules.startup.ImportSettings -J-Dsun.jvmstat.perdata.syncWaitMs=10000 -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.d3d=false -J-DTopSecurityManager.disable=true -J-Dorg.netbeans.core.TimeableEventQueue.quantum=360000 -J-Dpolyglot.js.nashorn-compat=true -J-Dsun.misc.URLClassPath.disableJarChecking=true -J-Djdk.attach.allowAttachSelf=true -J-Dorg.openide.util.ImageUtilities.level=950 -J--add-exports=java.desktop/com.sun.java.swing.plaf.gtk=ALL-UNNAMED -J--add-exports=java.desktop/sun.awt=ALL-UNNAMED -J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor.event=ALL-UNNAMED -J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED -J--add-exports=java.desktop/sun.swing=ALL-UNNAMED -J--add-exports=jdk.attach/sun.tools.attach=ALL-UNNAMED -J--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.plaf.synth=ALL-UNNAMED -J--add-opens=java.base/java.net=ALL-UNNAMED -J--add-opens=java.base/java.lang.ref=ALL-UNNAMED -J--add-opens=java.base/java.lang=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED -J-XX:+IgnoreUnrecognizedVMOptions -J-Dnetbeans.logger.console=true -J-Dnetbeans.exception.report.min.level=900 -J-ea\"\n# for development purposes you may wish to append: -J-Dnetbeans.logger.console=true -J-Dnetbeans.exception.report.min.level=900 -J-ea\n\n# Default location of JDK:\n#\n# It can be overridden on command line by using --jdkhome <dir>\n# Be careful when changing jdkhome.\n# There are two VisualVM launchers for Windows (32-bit and 64-bit) and\n# installer points to one of those in the VisualVM application shortcut \n# based on the Java version selected at installation time.\n#\n#visualvm_jdkhome=\"/path/to/jdk\"\n\n# Additional module clusters:\n# using ${path.separator} (';' on Windows or ':' on Unix):\n#\n#visualvm_extraclusters=\"/absolute/path/to/cluster1:/absolute/path/to/cluster2\"\n"
  },
  {
    "path": "visualvm/launcher/visualvm.import",
    "content": "#\n# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n# persistent storage\ninclude repository/.*\n# preferences\ninclude config/Preferences/.*\n# toolbars\ninclude config/Toolbars/.*\n# window system\ninclude config/Windows2Local/.*\n# custom visualvm conf\ninclude etc/visualvm.conf\n"
  },
  {
    "path": "visualvm/launcher/windows-src/Makefile",
    "content": "#  Main targets can be executed directly, and they are:\n#  \n#     build                    build a specific configuration\n#     clean                    remove built files from a configuration\n#     clobber                  remove all built files\n#     all                      build all configurations\n#     help                     print help mesage\n#  \n#  Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and\n#  .help-impl are implemented in nbproject/makefile-impl.mk.\n#\n# NOCDDL\n\n\n\n# Environment \nMKDIR=mkdir\nCP=cp\nCCADMIN=CCadmin\nRANLIB=ranlib\n\n\n\n# build\nbuild: .build-post-$(CONF)\n\n.build-pre: .build-pre-$(CONF)\n# Add your pre 'build' code here...\n\n.build-pre-visualvm.exe: visualvm.rc\n\twindres -ovisualvm.res -Ocoff visualvm.rc\n\n.build-pre-visualvm64.exe: visualvm.rc\n\tx86_64-w64-mingw32-windres.exe -ovisualvm64.res -Ocoff visualvm.rc\n\n.build-post-visualvm.exe: .build-impl\n\tcp visualvm.exe ../visualvm.exe\n\tstrip ../visualvm.exe\n\t\n.build-post-visualvm64.exe: .build-impl\n\tcp visualvm64.exe ../visualvm64.exe\n\tstrip ../visualvm.exe\n\n\t\t\t\t\t\t\t\t\t\t\t\n\n# clean\nclean: .clean-post\n\n.clean-pre:\n# Add your pre 'clean' code here...\n\n.clean-post: .clean-impl\n# Add your post 'clean' code here...\n\n\n\n# clobber\nclobber: .clobber-post\n\n.clobber-pre:\n# Add your pre 'clobber' code here...\n\n.clobber-post: .clobber-impl\n# Add your post 'clobber' code here...\n\n\n\n# all\nall: .all-post\n\n.all-pre:\n# Add your pre 'all' code here...\n\n.all-post: .all-impl\n# Add your post 'all' code here...\n\n\n\n# help\nhelp: .help-post\n\n.help-pre:\n# Add your pre 'help' code here...\n\n.help-post: .help-impl\n# Add your post 'help' code here...\n\n\n\n# include project implementation makefile\ninclude nbproject/Makefile-impl.mk\n"
  },
  {
    "path": "visualvm/launcher/windows-src/cmdargs.h",
    "content": "/*\n * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#ifndef _CMDARGS_H\n#define\t_CMDARGS_H\n\nclass CmdArgs {\npublic:\n\n    CmdArgs(int _count) {\n        used = 0;\n        size = _count;\n        args = new char*[size];\n        memset(args, 0, size * sizeof (char*));\n    }\n\n    ~CmdArgs() {\n        if (args) {\n            for (int i = 0; i < size; i++) {\n                delete[] args[i];\n            }\n            delete[] args;\n        }\n    }\n\n    void add(const char *arg) {\n        if (used + 1 > size) {\n            int newSize = size + size / 2 + 1;\n            char **newArgs = new char*[newSize];\n            memcpy(newArgs, args, size * sizeof (char*));\n            memset(newArgs + size, 0, (newSize - size) * sizeof (char*));\n            delete[] args;\n            args = newArgs;\n            size = newSize;\n        }\n        args[used] = new char[strlen(arg) + 1];\n        strcpy(args[used++], arg);\n    }\n\n    void addCmdLine(const char *cmdLine) {\n        char arg[1024] = \"\";\n        bool inQuotes = false;\n        bool inText = false;\n        int i = 0;\n        int j = 0;\n        char c;\n        while (c = cmdLine[i]) {\n            if (inQuotes) {\n                if (c == '\\\"') {\n                    inQuotes = false;\n                } else {\n                    arg[j++] = c;\n                }\n            } else {\n                switch (c) {\n                    case '\\\"':\n                        inQuotes = true;\n                        inText = true;\n                        break;\n                    case ' ':\n                    case '\\t':\n                    case '\\n':\n                    case '\\r':\n                        if (inText) {\n                            arg[j] = '\\0';\n                            add(arg);\n                            j = 0;\n                        }\n                        inText = false;\n                        break;\n                    default:\n                        inText = true;\n                        arg[j++] = c;\n                        break;\n                }\n            }\n            i++;\n        }\n        if (j > 0) {\n            arg[j] = '\\0';\n            add(arg);\n        }\n    }\n\n    int getCount() {\n        return used;\n    }\n\n    char **getArgs() {\n        return args;\n    }\n\nprivate:\n    int used;\n    int size;\n    char **args;\n};\n\n#endif\t/* _CMDARGS_H */\n\n"
  },
  {
    "path": "visualvm/launcher/windows-src/jvmfinder.cpp",
    "content": "/*\n * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#include \"jvmfinder.h\"\n#include <cassert>\n#include <fstream>\n\nusing namespace std;\n\nconst char *JvmFinder::OLD_JDK_KEY = \"Software\\\\JavaSoft\\\\Java Development Kit\";\nconst char *JvmFinder::OLD_JRE_KEY = \"Software\\\\JavaSoft\\\\Java Runtime Environment\";\nconst char *JvmFinder::JDK_KEY = \"Software\\\\JavaSoft\\\\JDK\";\nconst char *JvmFinder::JRE_KEY = \"Software\\\\JavaSoft\\\\JRE\";\nconst char *JvmFinder::CUR_VERSION_NAME = \"CurrentVersion\";\nconst char *JvmFinder::JAVA_HOME_NAME = \"JavaHome\";\nconst char *JvmFinder::JAVA_BIN_DIR = \"\\\\bin\";\nconst char *JvmFinder::JAVA_EXE_FILE = \"\\\\bin\\\\java.exe\";\nconst char *JvmFinder::JAVAW_EXE_FILE = \"\\\\bin\\\\javaw.exe\";\nconst char *JvmFinder::JAVA_CLIENT_DLL_FILE = \"\\\\bin\\\\client\\\\jvm.dll\";\nconst char *JvmFinder::JAVA_SERVER_DLL_FILE = \"\\\\bin\\\\server\\\\jvm.dll\";\nconst char *JvmFinder::JAVA_JRE_PREFIX = \"\\\\jre\";\nconst char *JvmFinder::ENV_JDK_HOME = \"JDK_HOME\";\nconst char *JvmFinder::ENV_JAVA_HOME = \"JAVA_HOME\";\n\nJvmFinder::JvmFinder() {\n}\n\nJvmFinder::JvmFinder(const JvmFinder& orig) {\n}\n\nJvmFinder::~JvmFinder() {\n}\n\nbool JvmFinder::getJavaPath(string &path) {\n    logMsg(\"JvmFinder::getJavaPath()\");\n    path = javaPath;\n    return !javaPath.empty();\n}\n\nbool JvmFinder::findJava(const char *minJavaVersion) {\n    if (find64bitJava(OLD_JDK_KEY, JAVA_JRE_PREFIX, minJavaVersion)) {\n        return true;\n    }\n    if (find64bitJava(JDK_KEY, \"\", minJavaVersion)) {\n        return true;\n    }\n    if (find32bitJava(OLD_JDK_KEY, JAVA_JRE_PREFIX, minJavaVersion)) {\n        return true;\n    }\n    if (findEnvJava(ENV_JDK_HOME)) {\n        return true;\n    }\n    if (findEnvJava(ENV_JAVA_HOME)) {\n        return true;\n    }\n    if (find64bitJava(OLD_JRE_KEY, \"\", minJavaVersion)) {\n        return true;\n    }\n    if (find64bitJava(JRE_KEY, \"\", minJavaVersion)) {\n        return true;\n    }\n    if (find32bitJava(OLD_JRE_KEY, \"\", minJavaVersion)) {\n        return true;\n    }\n    javaPath = \"\";\n    return false;\n}\n\nbool JvmFinder::find32bitJava(const char *javaKey, const char *prefix, const char *minJavaVersion) {\n    logMsg(\"JvmFinder::find32bitJava()\\n\\tjavaKey: %s\\n\\tprefix: %s\\n\\tminJavaVersion: %s\", javaKey, prefix, minJavaVersion);\n    string value;\n    bool result = false;\n    if (getStringFromRegistry(HKEY_LOCAL_MACHINE, javaKey, CUR_VERSION_NAME, value)) {\n        if (value >= minJavaVersion) {\n            string path;\n            if (getStringFromRegistry(HKEY_LOCAL_MACHINE, (string(javaKey) + \"\\\\\" + value).c_str(), JAVA_HOME_NAME, path)) {\n                result = checkJava(path.c_str(), prefix);\n            }\n        }\n    }\n    return result;\n}\n\nbool JvmFinder::find64bitJava(const char *javaKey, const char *prefix, const char *minJavaVersion) {\n    logMsg(\"JvmFinder::find64bitJava()\\n\\tjavaKey: %s\\n\\tprefix: %s\\n\\tminJavaVersion: %s\", javaKey, prefix, minJavaVersion);\n    string value;\n    bool result = false;\n    if(isWow64()) {\n        if (getStringFromRegistry64bit(HKEY_LOCAL_MACHINE, javaKey, CUR_VERSION_NAME, value)) {\n            if (value >= minJavaVersion) {\n                string path;\n                if (getStringFromRegistry64bit(HKEY_LOCAL_MACHINE, (string(javaKey) + \"\\\\\" + value).c_str(), JAVA_HOME_NAME, path)) {\n                    result = checkJava(path.c_str(), prefix);\n                }\n            }\n        }\n    }\n    return result;\n}\n\nbool JvmFinder::findEnvJava(const char *envVar) {\n    logMsg(\"JvmFinder::findEnvJava()\\n\\tenvVar: %s\", envVar);\n    bool result = false;\n    char *envJavaPath = getenv(envVar);\n    if (envJavaPath) {\n        if (checkJava(envJavaPath, \"\")) {\n            return true;\n        }\n        result = checkJava(envJavaPath, JAVA_JRE_PREFIX);\n    }\n    return result;\n}\n\nbool JvmFinder::checkJava(const char *path, const char *prefix) {\n    assert(path);\n    assert(prefix);\n    logMsg(\"checkJava(%s)\", path);\n    javaPath = path;\n    if (*javaPath.rbegin() == '\\\\') {\n        javaPath.erase(javaPath.length() - 1, 1);\n    }\n    string javaExePath = javaPath + prefix + JAVA_EXE_FILE;\n    string javawExePath = javaPath + prefix + JAVAW_EXE_FILE;\n    string javaClientDllPath = javaPath + prefix + JAVA_CLIENT_DLL_FILE;\n    string javaServerDllPath = javaPath + prefix + JAVA_SERVER_DLL_FILE;\n    if (!fileExists(javaClientDllPath.c_str())) {\n        javaClientDllPath = \"\";\n    }\n    if (!fileExists(javaServerDllPath.c_str())) {\n        javaServerDllPath = \"\";\n    }\n    string javaBinPath = javaPath + prefix + JAVA_BIN_DIR;\n    if (fileExists(javaExePath.c_str()) || !javaClientDllPath.empty() || !javaServerDllPath.empty()) {\n        if (!fileExists(javawExePath.c_str())) {\n            logMsg(\"javaw.exe does not exists, forcing java.exe\");\n            javawExePath = javaExePath;\n        }\n        return true;\n    }\n\n    javaPath.clear();\n    return false;\n}\n\n"
  },
  {
    "path": "visualvm/launcher/windows-src/jvmfinder.h",
    "content": "/*\n * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#ifndef JVMFINDER_H\n#define JVMFINDER_H\n\n#include <windows.h>\n#include <string>\n#include <list>\n#include \"o.n.bootstrap/utilsfuncs.h\"\n\nclass JvmFinder {\n    static const int MAX_ARGS_LEN = 32*1024;\n\n    static const char *JDK_KEY;\n    static const char *JRE_KEY;\n    static const char *OLD_JDK_KEY;\n    static const char *OLD_JRE_KEY;\n    static const char *CUR_VERSION_NAME;\n    static const char *JAVA_HOME_NAME;\n    static const char *JAVA_BIN_DIR;\n    static const char *JAVA_EXE_FILE;\n    static const char *JAVAW_EXE_FILE;\n    static const char *JAVA_CLIENT_DLL_FILE;\n    static const char *JAVA_SERVER_DLL_FILE;\n    static const char *JAVA_JRE_PREFIX;\n    static const char *ENV_JDK_HOME;\n    static const char *ENV_JAVA_HOME;\n\npublic:\n    JvmFinder();\n    virtual ~JvmFinder();\n\n    bool findJava(const char *minJavaVersion);\n    bool getJavaPath(std::string &path);\n\nprivate:\n    JvmFinder(const JvmFinder& orig);\n\n    bool checkJava(const char *javaPath, const char *prefix);\n    bool find32bitJava(const char *javaKey, const char *prefix, const char *minJavaVersion);\n    bool find64bitJava(const char *javaKey, const char *prefix, const char *minJavaVersion);\n    bool JvmFinder::findEnvJava(const char *envVar);\n\nprivate:\n    std::string javaPath;\n};\n\n#endif /* JVMFINDER_H */\n\n"
  },
  {
    "path": "visualvm/launcher/windows-src/nbproject/Makefile-impl.mk",
    "content": "# \n# Generated Makefile - do not edit! \n# \n# Edit the Makefile in the project folder instead (../Makefile). Each target\n# has a pre- and a post- target defined where you can add customization code.\n#\n# This makefile implements macros and targets common to all configurations.\n#\n# NOCDDL\n\n\n# Building and Cleaning subprojects are done by default, but can be controlled with the SUB\n# macro. If SUB=no, subprojects will not be built or cleaned. The following macro\n# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf\n# and .clean-reqprojects-conf unless SUB has the value 'no'\nSUB_no=NO\nSUBPROJECTS=${SUB_${SUB}}\nBUILD_SUBPROJECTS_=.build-subprojects\nBUILD_SUBPROJECTS_NO=\nBUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}\nCLEAN_SUBPROJECTS_=.clean-subprojects\nCLEAN_SUBPROJECTS_NO=\nCLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}\n\n\n# Project Name\nPROJECTNAME=windows-src\n\n# Active Configuration\nDEFAULTCONF=visualvm.exe\nCONF=${DEFAULTCONF}\n\n# All Configurations\nALLCONFS=visualvm.exe visualvm64.exe \n\n\n# build\n.build-impl: .build-pre .validate-impl .depcheck-impl\n\t@#echo \"=> Running $@... Configuration=$(CONF)\"\n\t\"${MAKE}\" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf\n\n\n# clean\n.clean-impl: .clean-pre .validate-impl .depcheck-impl\n\t@#echo \"=> Running $@... Configuration=$(CONF)\"\n\t\"${MAKE}\" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf\n\n\n# clobber \n.clobber-impl: .clobber-pre .depcheck-impl\n\t@#echo \"=> Running $@...\"\n\tfor CONF in ${ALLCONFS}; \\\n\tdo \\\n\t    \"${MAKE}\" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \\\n\tdone\n\n# all \n.all-impl: .all-pre .depcheck-impl\n\t@#echo \"=> Running $@...\"\n\tfor CONF in ${ALLCONFS}; \\\n\tdo \\\n\t    \"${MAKE}\" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \\\n\tdone\n\n# build tests\n.build-tests-impl: .build-impl .build-tests-pre\n\t@#echo \"=> Running $@... Configuration=$(CONF)\"\n\t\"${MAKE}\" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf\n\n# run tests\n.test-impl: .build-tests-impl .test-pre\n\t@#echo \"=> Running $@... Configuration=$(CONF)\"\n\t\"${MAKE}\" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf\n\n# dependency checking support\n.depcheck-impl:\n\t@echo \"# This code depends on make tool being used\" >.dep.inc\n\t@if [ -n \"${MAKE_VERSION}\" ]; then \\\n\t    echo \"DEPFILES=\\$$(wildcard \\$$(addsuffix .d, \\$${OBJECTFILES} \\$${TESTOBJECTFILES}))\" >>.dep.inc; \\\n\t    echo \"ifneq (\\$${DEPFILES},)\" >>.dep.inc; \\\n\t    echo \"include \\$${DEPFILES}\" >>.dep.inc; \\\n\t    echo \"endif\" >>.dep.inc; \\\n\telse \\\n\t    echo \".KEEP_STATE:\" >>.dep.inc; \\\n\t    echo \".KEEP_STATE_FILE:.make.state.\\$${CONF}\" >>.dep.inc; \\\n\tfi\n\n# configuration validation\n.validate-impl:\n\t@if [ ! -f nbproject/Makefile-${CONF}.mk ]; \\\n\tthen \\\n\t    echo \"\"; \\\n\t    echo \"Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}\"; \\\n\t    echo \"See 'make help' for details.\"; \\\n\t    echo \"Current directory: \" `pwd`; \\\n\t    echo \"\"; \\\n\tfi\n\t@if [ ! -f nbproject/Makefile-${CONF}.mk ]; \\\n\tthen \\\n\t    exit 1; \\\n\tfi\n\n\n# help\n.help-impl: .help-pre\n\t@echo \"This makefile supports the following configurations:\"\n\t@echo \"    ${ALLCONFS}\"\n\t@echo \"\"\n\t@echo \"and the following targets:\"\n\t@echo \"    build  (default target)\"\n\t@echo \"    clean\"\n\t@echo \"    clobber\"\n\t@echo \"    all\"\n\t@echo \"    help\"\n\t@echo \"\"\n\t@echo \"Makefile Usage:\"\n\t@echo \"    make [CONF=<CONFIGURATION>] [SUB=no] build\"\n\t@echo \"    make [CONF=<CONFIGURATION>] [SUB=no] clean\"\n\t@echo \"    make [SUB=no] clobber\"\n\t@echo \"    make [SUB=no] all\"\n\t@echo \"    make help\"\n\t@echo \"\"\n\t@echo \"Target 'build' will build a specific configuration and, unless 'SUB=no',\"\n\t@echo \"    also build subprojects.\"\n\t@echo \"Target 'clean' will clean a specific configuration and, unless 'SUB=no',\"\n\t@echo \"    also clean subprojects.\"\n\t@echo \"Target 'clobber' will remove all built files from all configurations and,\"\n\t@echo \"    unless 'SUB=no', also from subprojects.\"\n\t@echo \"Target 'all' will will build all configurations and, unless 'SUB=no',\"\n\t@echo \"    also build subprojects.\"\n\t@echo \"Target 'help' prints this message.\"\n\t@echo \"\"\n\n"
  },
  {
    "path": "visualvm/launcher/windows-src/nbproject/Makefile-variables.mk",
    "content": "#\n# Generated - do not edit!\n#\n# NOCDDL\n#\nCND_BASEDIR=`pwd`\nCND_BUILDDIR=build\nCND_DISTDIR=dist\n# visualvm.exe configuration\nCND_PLATFORM_visualvm.exe=Cygwin-Windows\nCND_ARTIFACT_DIR_visualvm.exe=\nCND_ARTIFACT_NAME_visualvm.exe=visualvm.exe\nCND_ARTIFACT_PATH_visualvm.exe=visualvm.exe\nCND_PACKAGE_DIR_visualvm.exe=dist/visualvm.exe/Cygwin-Windows/package\nCND_PACKAGE_NAME_visualvm.exe=windows-src.tar\nCND_PACKAGE_PATH_visualvm.exe=dist/visualvm.exe/Cygwin-Windows/package/windows-src.tar\n#\n# include compiler specific variables\n#\n# dmake command\nROOT:sh = test -f nbproject/private/Makefile-variables.mk || \\\n\t(mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)\n#\n# gmake command\n.PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk))\n#\ninclude nbproject/private/Makefile-variables.mk\n"
  },
  {
    "path": "visualvm/launcher/windows-src/nbproject/Makefile-visualvm.exe.mk",
    "content": "#\n# Generated Makefile - do not edit!\n#\n# Edit the Makefile in the project folder instead (../Makefile). Each target\n# has a -pre and a -post target defined where you can add customized code.\n#\n# This makefile implements configuration specific macros and targets.\n\n\n# Environment\nMKDIR=mkdir\nCP=cp\nGREP=grep\nNM=nm\nCCADMIN=CCadmin\nRANLIB=ranlib\nCC=gcc\nCCC=g++\nCXX=g++\nFC=gfortran\nAS=as\n\n# Macros\nCND_PLATFORM=Cygwin-Windows\nCND_DLIB_EXT=dll\nCND_CONF=visualvm.exe\nCND_DISTDIR=dist\nCND_BUILDDIR=build\n\n# Include project Makefile\ninclude Makefile\n\n# Object Directory\nOBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}\n\n# Object Files\nOBJECTFILES= \\\n\t${OBJECTDIR}/jvmfinder.o \\\n\t${OBJECTDIR}/o.n.bootstrap/utilsfuncs.o \\\n\t${OBJECTDIR}/visualvm.o \\\n\t${OBJECTDIR}/visualvmlauncher.o\n\n\n# C Compiler Flags\nCFLAGS=\n\n# CC Compiler Flags\nCCFLAGS=-m32 -mno-cygwin\nCXXFLAGS=-m32 -mno-cygwin\n\n# Fortran Compiler Flags\nFFLAGS=\n\n# Assembler Flags\nASFLAGS=\n\n# Link Libraries and Options\nLDLIBSOPTIONS=visualvm.res\n\n# Build Targets\n.build-conf: ${BUILD_SUBPROJECTS}\n\t\"${MAKE}\"  -f nbproject/Makefile-${CND_CONF}.mk visualvm.exe\n\nvisualvm.exe: ${OBJECTFILES}\n\t${LINK.cc} -o visualvm.exe ${OBJECTFILES} ${LDLIBSOPTIONS} -mwindows -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh\n\n${OBJECTDIR}/jvmfinder.o: jvmfinder.cpp\n\t${MKDIR} -p ${OBJECTDIR}\n\t${RM} \"$@.d\"\n\t$(COMPILE.cc) -O2 -s -DARCHITECTURE=32 -DNBEXEC_DLL=\\\"/lib/nbexec.dll\\\" -MMD -MP -MF \"$@.d\" -o ${OBJECTDIR}/jvmfinder.o jvmfinder.cpp\n\n${OBJECTDIR}/o.n.bootstrap/utilsfuncs.o: o.n.bootstrap/utilsfuncs.cpp\n\t${MKDIR} -p ${OBJECTDIR}/o.n.bootstrap\n\t${RM} \"$@.d\"\n\t$(COMPILE.cc) -O2 -s -DARCHITECTURE=32 -DNBEXEC_DLL=\\\"/lib/nbexec.dll\\\" -MMD -MP -MF \"$@.d\" -o ${OBJECTDIR}/o.n.bootstrap/utilsfuncs.o o.n.bootstrap/utilsfuncs.cpp\n\n${OBJECTDIR}/visualvm.o: visualvm.cpp\n\t${MKDIR} -p ${OBJECTDIR}\n\t${RM} \"$@.d\"\n\t$(COMPILE.cc) -O2 -s -DARCHITECTURE=32 -DNBEXEC_DLL=\\\"/lib/nbexec.dll\\\" -MMD -MP -MF \"$@.d\" -o ${OBJECTDIR}/visualvm.o visualvm.cpp\n\n${OBJECTDIR}/visualvmlauncher.o: visualvmlauncher.cpp\n\t${MKDIR} -p ${OBJECTDIR}\n\t${RM} \"$@.d\"\n\t$(COMPILE.cc) -O2 -s -DARCHITECTURE=32 -DNBEXEC_DLL=\\\"/lib/nbexec.dll\\\" -MMD -MP -MF \"$@.d\" -o ${OBJECTDIR}/visualvmlauncher.o visualvmlauncher.cpp\n\n# Subprojects\n.build-subprojects:\n\n# Clean Targets\n.clean-conf: ${CLEAN_SUBPROJECTS}\n\t${RM} -r ${CND_BUILDDIR}/${CND_CONF}\n\n# Subprojects\n.clean-subprojects:\n\n# Enable dependency checking\n.dep.inc: .depcheck-impl\n\ninclude .dep.inc\n"
  },
  {
    "path": "visualvm/launcher/windows-src/nbproject/Package-visualvm.exe.bash",
    "content": "#!/bin/bash -x\n\n#\n# Generated - do not edit!\n#\n\n# Macros\nTOP=`pwd`\nCND_PLATFORM=Cygwin-Windows\nCND_CONF=visualvm.exe\nCND_DISTDIR=dist\nCND_BUILDDIR=build\nCND_DLIB_EXT=dll\nNBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging\nTMPDIRNAME=tmp-packaging\nOUTPUT_PATH=visualvm.exe\nOUTPUT_BASENAME=visualvm.exe\nPACKAGE_TOP_DIR=windows-src/\n\n# Functions\nfunction checkReturnCode\n{\n    rc=$?\n    if [ $rc != 0 ]\n    then\n        exit $rc\n    fi\n}\nfunction makeDirectory\n# $1 directory path\n# $2 permission (optional)\n{\n    mkdir -p \"$1\"\n    checkReturnCode\n    if [ \"$2\" != \"\" ]\n    then\n      chmod $2 \"$1\"\n      checkReturnCode\n    fi\n}\nfunction copyFileToTmpDir\n# $1 from-file path\n# $2 to-file path\n# $3 permission\n{\n    cp \"$1\" \"$2\"\n    checkReturnCode\n    if [ \"$3\" != \"\" ]\n    then\n        chmod $3 \"$2\"\n        checkReturnCode\n    fi\n}\n\n# Setup\ncd \"${TOP}\"\nmkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package\nrm -rf ${NBTMPDIR}\nmkdir -p ${NBTMPDIR}\n\n# Copy files and create directories and links\ncd \"${TOP}\"\nmakeDirectory \"${NBTMPDIR}/windows-src/bin\"\ncopyFileToTmpDir \"${OUTPUT_PATH}.exe\" \"${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}.exe\" 0755\n\n\n# Generate tar file\ncd \"${TOP}\"\nrm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/windows-src.tar\ncd ${NBTMPDIR}\ntar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/windows-src.tar *\ncheckReturnCode\n\n# Cleanup\ncd \"${TOP}\"\nrm -rf ${NBTMPDIR}\n"
  },
  {
    "path": "visualvm/launcher/windows-src/nbproject/configurations.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configurationDescriptor version=\"100\">\n  <logicalFolder name=\"root\" displayName=\"root\" projectFiles=\"true\" kind=\"ROOT\">\n    <logicalFolder name=\"HeaderFiles\"\n                   displayName=\"Header Files\"\n                   projectFiles=\"true\">\n      <itemPath>cmdargs.h</itemPath>\n      <itemPath>jvmfinder.h</itemPath>\n      <itemPath>o.n.bootstrap/utilsfuncs.h</itemPath>\n      <itemPath>version.h</itemPath>\n      <itemPath>visualvmlauncher.h</itemPath>\n    </logicalFolder>\n    <logicalFolder name=\"ResourceFiles\"\n                   displayName=\"Resource Files\"\n                   projectFiles=\"true\">\n      <itemPath>version.rc</itemPath>\n      <itemPath>visualvm.exe.manifest</itemPath>\n      <itemPath>visualvm.rc</itemPath>\n    </logicalFolder>\n    <logicalFolder name=\"SourceFiles\"\n                   displayName=\"Source Files\"\n                   projectFiles=\"true\">\n      <itemPath>jvmfinder.cpp</itemPath>\n      <itemPath>o.n.bootstrap/utilsfuncs.cpp</itemPath>\n      <itemPath>visualvm.cpp</itemPath>\n      <itemPath>visualvmlauncher.cpp</itemPath>\n    </logicalFolder>\n    <logicalFolder name=\"ExternalFiles\"\n                   displayName=\"Important Files\"\n                   projectFiles=\"false\">\n      <itemPath>Makefile</itemPath>\n    </logicalFolder>\n  </logicalFolder>\n  <projectmakefile>Makefile</projectmakefile>\n  <confs>\n    <conf name=\"visualvm.exe\" type=\"1\">\n      <toolsSet>\n        <compilerSet>Cygwin|Cygwin</compilerSet>\n        <dependencyChecking>true</dependencyChecking>\n        <rebuildPropChanged>false</rebuildPropChanged>\n      </toolsSet>\n      <compileType>\n        <ccTool>\n          <developmentMode>5</developmentMode>\n          <stripSymbols>true</stripSymbols>\n          <architecture>1</architecture>\n          <commandLine>-mno-cygwin</commandLine>\n          <preprocessorList>\n            <Elem>ARCHITECTURE=32</Elem>\n            <Elem>NBEXEC_DLL=\"/lib/nbexec.dll\"</Elem>\n          </preprocessorList>\n        </ccTool>\n        <linkerTool>\n          <output>visualvm.exe</output>\n          <linkerLibItems>\n            <linkerOptionItem>visualvm.res</linkerOptionItem>\n          </linkerLibItems>\n          <commandLine>-mwindows -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh</commandLine>\n        </linkerTool>\n      </compileType>\n      <item path=\"cmdargs.h\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"jvmfinder.cpp\" ex=\"false\" tool=\"1\" flavor2=\"0\">\n      </item>\n      <item path=\"jvmfinder.h\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"o.n.bootstrap/utilsfuncs.cpp\" ex=\"false\" tool=\"1\" flavor2=\"0\">\n      </item>\n      <item path=\"o.n.bootstrap/utilsfuncs.h\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"version.h\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"version.rc\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"visualvm.cpp\" ex=\"false\" tool=\"1\" flavor2=\"0\">\n      </item>\n      <item path=\"visualvm.exe.manifest\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"visualvm.rc\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"visualvmlauncher.cpp\" ex=\"false\" tool=\"1\" flavor2=\"0\">\n      </item>\n      <item path=\"visualvmlauncher.h\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n    </conf>\n    <conf name=\"visualvm64.exe\" type=\"1\">\n      <toolsSet>\n        <compilerSet>Cygwin64|Cygwin</compilerSet>\n        <dependencyChecking>true</dependencyChecking>\n        <rebuildPropChanged>false</rebuildPropChanged>\n      </toolsSet>\n      <compileType>\n        <ccTool>\n          <developmentMode>5</developmentMode>\n          <stripSymbols>true</stripSymbols>\n          <architecture>2</architecture>\n          <commandLine>-mno-cygwin -static-libgcc -static-libstdc++</commandLine>\n          <preprocessorList>\n            <Elem>ARCHITECTURE=64</Elem>\n            <Elem>NBEXEC_DLL=\"/lib/nbexec64.dll\"</Elem>\n          </preprocessorList>\n        </ccTool>\n        <linkerTool>\n          <output>visualvm64.exe</output>\n          <linkerLibItems>\n            <linkerOptionItem>visualvm64.res</linkerOptionItem>\n          </linkerLibItems>\n          <commandLine>-mwindows -Wl,--nxcompat -Wl,--dynamicbase</commandLine>\n        </linkerTool>\n      </compileType>\n      <item path=\"cmdargs.h\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"jvmfinder.cpp\" ex=\"false\" tool=\"1\" flavor2=\"0\">\n      </item>\n      <item path=\"jvmfinder.h\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"o.n.bootstrap/utilsfuncs.cpp\" ex=\"false\" tool=\"1\" flavor2=\"0\">\n      </item>\n      <item path=\"o.n.bootstrap/utilsfuncs.h\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"version.h\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"version.rc\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"visualvm.cpp\" ex=\"false\" tool=\"1\" flavor2=\"0\">\n      </item>\n      <item path=\"visualvm.exe.manifest\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"visualvm.rc\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n      <item path=\"visualvmlauncher.cpp\" ex=\"false\" tool=\"1\" flavor2=\"0\">\n      </item>\n      <item path=\"visualvmlauncher.h\" ex=\"false\" tool=\"3\" flavor2=\"0\">\n      </item>\n    </conf>\n  </confs>\n</configurationDescriptor>\n"
  },
  {
    "path": "visualvm/launcher/windows-src/nbproject/project.properties",
    "content": ""
  },
  {
    "path": "visualvm/launcher/windows-src/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.cnd.makeproject</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/make-project/1\">\n            <name>VisualVM Launcher Win</name>\n            <make-project-type>0</make-project-type>\n            <c-extensions/>\n            <cpp-extensions>cpp</cpp-extensions>\n            <header-extensions>h</header-extensions>\n            <sourceEncoding>UTF-8</sourceEncoding>\n            <make-dep-projects/>\n            <sourceRootList/>\n            <confList>\n                <confElem>\n                    <name>visualvm.exe</name>\n                    <type>1</type>\n                </confElem>\n                <confElem>\n                    <name>visualvm64.exe</name>\n                    <type>1</type>\n                </confElem>\n            </confList>\n            <formatting>\n                <project-formatting-style>false</project-formatting-style>\n            </formatting>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/launcher/windows-src/o.n.bootstrap/argnames.h",
    "content": "/*\n * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#ifndef _ARGNAMES_H\n#define\t_ARGNAMES_H\n\n#define ARG_NAME_SEPAR_PROC \"--fork-java\"\n#define ARG_NAME_CONSOLE    \"--console\"\n#define ARG_NAME_LAUNCHER_LOG \"--trace\"\n#define ARG_NAME_LA_START_APP \"--la_start_app\"\n#define ARG_NAME_LA_START_AU \"--la_start_au\"\n#define ARG_NAME_LA_PPID \"--la_ppid\"\n#define ARG_NAME_USER_DIR \"--userdir\"\n#define ARG_DEFAULT_USER_DIR_ROOT \"--default_userdir_root\"\n#define ARG_NAME_CACHE_DIR \"--cachedir\"\n#define ARG_NAME_CLUSTERS \"--clusters\"\n#define ARG_NAME_BOOTCLASS \"--bootclass\"\n#define ARG_NAME_JDKHOME \"--jdkhome\"\n#define ARG_NAME_CP_PREPEND \"--cp:p\"\n#define ARG_NAME_CP_APPEND \"--cp:a\"\n#define ARG_NAME_NOSPLASH \"--nosplash\"\n\n\n#endif\t/* _ARGNAMES_H */\n\n"
  },
  {
    "path": "visualvm/launcher/windows-src/o.n.bootstrap/nbexecloader.h",
    "content": "/*\n * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#ifndef _NBEXECLOADER_H\n#define\t_NBEXECLOADER_H\n\n#include \"utilsfuncs.h\"\n\n#define HELP_MSG \\\n\"\\\n  --console suppress    supppress console output\\n\\\n  --console new         open new console for output\\n\\\n\\n\"\n\nclass NBExecLoader {\n    typedef int (*StartPlatform)(int argc, char *argv[], const char *help);\n\npublic:\n    NBExecLoader()\n        : hLib(0) {\n    }\n    ~NBExecLoader() {\n        if (hLib) {\n            FreeLibrary(hLib);\n        }\n    }\n    int start(const char *path, int argc, char *argv[]) {\n        if (!hLib) {\n            hLib = LoadLibrary(path);\n            if (!hLib) {\n                logErr(true, true, \"Cannot load \\\"%s\\\".\", path);\n                return -1;\n            }\n        }\n\n        StartPlatform startPlatform = (StartPlatform) GetProcAddress(hLib, \"startPlatform\");\n        if (!startPlatform) {\n            logErr(true, true, \"Cannot start platform, failed to find startPlatform() in %s\", path);\n            return -1;\n        }\n        logMsg(\"Starting platform...\\n\");\n        return startPlatform(argc, argv, HELP_MSG);\n    }\n\nprivate:\n    HMODULE hLib;\n};\n\n#endif\t/* _NBEXECLOADER_H */\n\n"
  },
  {
    "path": "visualvm/launcher/windows-src/o.n.bootstrap/utilsfuncs.cpp",
    "content": "/*\n * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#ifndef KEY_WOW64_64KEY\n#define KEY_WOW64_64KEY 0x0100\n#endif\n\n#include \"utilsfuncs.h\"\n#include \"argnames.h\"\n#include <tlhelp32.h>\n#include <windows.h>\n\nusing namespace std;\n\nbool disableFolderVirtualization(HANDLE hProcess) {\n    OSVERSIONINFO osvi = {0};\n    osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);\n    if (GetVersionEx(&osvi) && osvi.dwMajorVersion == 6) // check it is Win VISTA\n    {\n        HANDLE hToken;\n        if (OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken)) {\n            DWORD tokenInfoVal = 0;\n            if (!SetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS) 24, &tokenInfoVal, sizeof (DWORD))) {\n                // invalid token information class (24) is OK, it means there is no folder virtualization on current system\n                if (GetLastError() != ERROR_INVALID_PARAMETER) {\n                    logErr(true, true, \"Failed to set token information.\");\n                    return false;\n                }\n            }\n            CloseHandle(hToken);\n        } else {\n            logErr(true, true, \"Failed to open process token.\");\n            return false;\n        }\n    }\n    return true;\n}\n\nbool getStringFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, string &value) {\n    return getStringFromRegistryEx(rootKey, keyName, valueName, value, false);\n}\n\nbool getStringFromRegistry64bit(HKEY rootKey, const char *keyName, const char *valueName, string &value) {\n    return getStringFromRegistryEx(rootKey, keyName, valueName, value, true);\n}\n\n\n\nbool getStringFromRegistryEx(HKEY rootKey, const char *keyName, const char *valueName, string &value, bool read64bit) {\n    logMsg(\"getStringFromRegistry()\\n\\tkeyName: %s\\n\\tvalueName: %s\", keyName, valueName);\n    HKEY hKey = 0;\n    if (RegOpenKeyEx(rootKey, keyName, 0, KEY_READ | (read64bit ? KEY_WOW64_64KEY : 0), &hKey) == ERROR_SUCCESS) {\n        DWORD valSize = 4096;\n        DWORD type = 0;\n        char val[4096] = \"\";\n        if (RegQueryValueEx(hKey, valueName, 0, &type, (BYTE *) val, &valSize) == ERROR_SUCCESS\n                && type == REG_SZ) {\n            logMsg(\"%s: %s\", valueName, val);\n            RegCloseKey(hKey);\n            value = val;\n            return true;\n        } else {\n            logErr(true, false, \"RegQueryValueEx() failed.\");\n        }\n        RegCloseKey(hKey);\n    } else {\n        logErr(true, false, \"RegOpenKeyEx() failed.\");\n    }\n    return false;\n}\n\nbool getDwordFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, DWORD &value) {\n    logMsg(\"getDwordFromRegistry()\\n\\tkeyName: %s\\n\\tvalueName: %s\", keyName, valueName);\n    HKEY hKey = 0;\n    if (RegOpenKeyEx(rootKey, keyName, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\n        DWORD valSize = sizeof(DWORD);\n        DWORD type = 0;\n        if (RegQueryValueEx(hKey, valueName, 0, &type, (BYTE *) &value, &valSize) == ERROR_SUCCESS\n                && type == REG_DWORD) {\n            logMsg(\"%s: %u\", valueName, value);\n            RegCloseKey(hKey);\n            return true;\n        } else {\n            logErr(true, false, \"RegQueryValueEx() failed.\");\n        }\n        RegCloseKey(hKey);\n    } else {\n        logErr(true, false, \"RegOpenKeyEx() failed.\");\n    }\n    return false;\n}\n\nbool dirExists(const char *path) {\n    WIN32_FIND_DATA fd = {0};\n    HANDLE hFind = 0;\n    hFind = FindFirstFile(path, &fd);\n    if (hFind == INVALID_HANDLE_VALUE) {\n        logMsg(\"Dir \\\"%s\\\" does not exist\", path);\n        return false;\n    }\n    logMsg(\"Dir \\\"%s\\\" exists\", path);\n    FindClose(hFind);\n    return (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;\n}\n\nbool fileExists(const char *path) {\n    WIN32_FIND_DATA fd = {0};\n    HANDLE hFind = 0;\n    hFind = FindFirstFile(path, &fd);\n    if (hFind == INVALID_HANDLE_VALUE) {\n        logMsg(\"File \\\"%s\\\" does not exist\", path);\n        return false;\n    }\n\n    logMsg(\"File \\\"%s\\\" exists\", path);\n    FindClose(hFind);\n    return true;\n}\n\nbool normalizePath(char *path, int len) {\n    char tmp[MAX_PATH] = \"\";\n    int i = 0;\n    while (path[i] && i < MAX_PATH - 1) {\n        tmp[i] = path[i] == '/' ? '\\\\' : path[i];\n        i++;\n    }\n    tmp[i] = '\\0';\n    return _fullpath(path, tmp, len) != NULL;\n}\n\nbool createPath(const char *path) {\n    logMsg(\"Creating directory \\\"%s\\\"\", path);\n    char dir[MAX_PATH] = \"\";\n    const char *sep = strchr(path, '\\\\');\n    while (sep) {\n        strncpy(dir, path, sep - path);\n        if (!CreateDirectory(dir, 0) && GetLastError() != ERROR_ALREADY_EXISTS) {\n            logErr(true, false, \"Failed to create directory %s\", dir);\n            return false;\n        }\n        sep = strchr(sep + 1, '\\\\');\n    }\n    return true;\n}\n\n\nchar * getCurrentModulePath(char *path, int pathLen) {\n    MEMORY_BASIC_INFORMATION mbi;\n    static int dummy;\n    VirtualQuery(&dummy, &mbi, sizeof (mbi));\n    HMODULE hModule = (HMODULE) mbi.AllocationBase;\n    GetModuleFileName(hModule, path, pathLen);\n    return path;\n}\n\nchar * skipWhitespaces(char *str) {\n    while (*str != '\\0' && (*str == ' ' || *str == '\\t' || *str == '\\n' || *str == '\\r')) {\n        str++;\n    }\n    return str;\n}\n\nchar * trimWhitespaces(char *str) {\n    char *end = str + strlen(str) - 1;\n    while (end >= str && (*end == ' ' || *end == '\\t' || *end == '\\n' || *end == '\\r')) {\n        *end = '\\0';\n        end--;\n    }\n    return end;\n}\n\nchar* getSysError(char *str, int strSize) {\n    int err = GetLastError();\n    LPTSTR lpMsgBuf;\n    FormatMessage(\n            FORMAT_MESSAGE_ALLOCATE_BUFFER |\n            FORMAT_MESSAGE_FROM_SYSTEM |\n            FORMAT_MESSAGE_IGNORE_INSERTS,\n            NULL,\n            err,\n            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\n            (LPTSTR) & lpMsgBuf,\n            0,\n            NULL\n            );\n    LPTSTR tmp = strchr(lpMsgBuf, '\\r');\n    if (tmp != NULL) {\n        *tmp = '\\0';\n    }\n\n    _snprintf(str, strSize, \" %s (%u)\", lpMsgBuf, err);\n    LocalFree(lpMsgBuf);\n    return str;\n}\n\nstring gLogFileName;\n\nvoid logV(bool appendSysError, bool showMsgBox, const char *format, va_list args) {\n    char msg[4096] = \"\";\n    vsnprintf(msg, 4096, format, args);\n\n    if (appendSysError) {\n        char sysErr[512] = \"\";\n        getSysError(sysErr, 512);\n        strncat(msg, sysErr, 4096 - strlen(msg));\n    }\n\n    if (!gLogFileName.empty()) {\n        FILE *file = fopen(gLogFileName.c_str(), \"a\");\n        if (file) {\n            fprintf(file, \"%s\\n\", msg);\n            fclose(file);\n        }\n    }\n\n    if (showMsgBox) {\n        ::MessageBox(NULL, msg, \"Error\", MB_OK | MB_ICONSTOP);\n    }\n}\n\nvoid logErr(bool appendSysError, bool showMsgBox, const char *format, ...) {\n    va_list args;\n    va_start(args, format);\n    logV(appendSysError, showMsgBox, format, args);\n}\n\nvoid logMsg(const char *format, ...) {\n    va_list args;\n    va_start(args, format);\n    logV(false, false, format, args);\n}\n\nbool restarting(int argc, char *argv[]) {\n    for (int i = 0; i < argc; i++) {\n        if (strcmp(ARG_NAME_LA_START_APP, argv[i]) == 0 || strcmp(ARG_NAME_LA_START_AU, argv[i]) == 0) {\n            return true;\n        }\n    }\n    return false;\n}\n\nbool checkLoggingArg(int argc, char *argv[], bool delFile) {\n    for (int i = 0; i < argc; i++) {\n        if (strcmp(ARG_NAME_LAUNCHER_LOG, argv[i]) == 0) {\n            if (i + 1 == argc) {\n                logErr(false, true, \"Argument is missing for \\\"%s\\\" option.\", argv[i]);\n                return false;\n            }\n            gLogFileName = argv[++i];\n            // if we are restarting, keep log file\n            if (delFile && !restarting(argc, argv)) {\n                DeleteFile(gLogFileName.c_str());\n            }\n            break;\n        }\n    }\n    return true;\n}\n\nbool setupProcess(int &argc, char *argv[], DWORD &parentProcID, const char *attachMsg) {\n#define CHECK_ARG \\\n    if (i+1 == argc) {\\\n        logErr(false, true, \"Argument is missing for \\\"%s\\\" option.\", argv[i]);\\\n        return false;\\\n    }\n\n    parentProcID = 0;\n    DWORD cmdLineArgPPID = 0;\n    for (int i = 0; i < argc; i++) {\n        if (strcmp(ARG_NAME_CONSOLE, argv[i]) == 0) {\n            CHECK_ARG;\n            if (strcmp(\"new\", argv[i + 1]) == 0){\n                AllocConsole();\n            } else if (strcmp(\"suppress\", argv[i + 1]) == 0) {\n                // nothing, no console should be attached\n            } else {\n                logErr(false, true, \"Invalid argument for \\\"%s\\\" option.\", argv[i]);\n                return false;\n            }\n            // remove options\n            for (int k = i + 2; k < argc; k++) {\n                argv[k-2] = argv[k];\n            }\n            argc -= 2;\n            return true;\n        } else if (strcmp(ARG_NAME_LA_PPID, argv[i]) == 0) {\n            CHECK_ARG;\n            char *end = 0;\n            cmdLineArgPPID = strtoul(argv[++i], &end, 10);\n            if (cmdLineArgPPID == 0 && *end != '\\0') {\n                logErr(false, true, \"Invalid parameter for option %s\", ARG_NAME_LA_PPID);\n                return false;\n            }\n            logMsg(\"Command line arg PPID: %u\", cmdLineArgPPID);\n            break;\n        }\n    }\n#undef CHECK_ARG\n\n    // default, attach to parent process console if exists\n    // AttachConsole exists since WinXP, so be nice and do it dynamically\n    typedef BOOL (WINAPI *LPFAC)(DWORD  dwProcessId);\n    HINSTANCE hKernel32 = GetModuleHandle(\"kernel32\");\n    if (hKernel32) {\n        LPFAC attachConsole = (LPFAC) GetProcAddress(hKernel32, \"AttachConsole\");\n        if (attachConsole) {\n            if (cmdLineArgPPID) {\n                if (!attachConsole(cmdLineArgPPID)) {\n                    logErr(true, false, \"AttachConsole of PPID: %u failed.\", cmdLineArgPPID);\n                }\n            } else {\n                if (!attachConsole((DWORD) -1)) {\n                    logErr(true, false, \"AttachConsole of PP failed.\");\n                } else {\n                    getParentProcessID(parentProcID);\n                    if (attachMsg) {\n                        printToConsole(attachMsg);\n                    }\n                }\n            }\n        } else {\n            logErr(true, false, \"GetProcAddress() for AttachConsole failed.\");\n        }\n    }\n    return true;\n}\n\nbool isConsoleAttached() {\n    typedef HWND (WINAPI *GetConsoleWindowT)();\n    HINSTANCE hKernel32 = GetModuleHandle(\"kernel32\");\n    if (hKernel32) {\n        GetConsoleWindowT getConsoleWindow = (GetConsoleWindowT) GetProcAddress(hKernel32, \"GetConsoleWindow\");\n        if (getConsoleWindow) {\n            if (getConsoleWindow() != NULL) {\n                logMsg(\"Console is attached.\");\n                return true;\n            }\n        } else {\n            logErr(true, false, \"GetProcAddress() for GetConsoleWindow failed.\");\n        }\n    }\n    return false;\n}\n\nbool printToConsole(const char *msg) {\n    FILE *console = fopen(\"CON\", \"a\");\n    if (!console) {\n        return false;\n    }\n    fprintf(console, \"%s\", msg);\n    fclose(console);\n    return false;\n}\n\nbool getParentProcessID(DWORD &id) {\n    typedef HANDLE (WINAPI * CreateToolhelp32SnapshotT)(DWORD, DWORD);\n    typedef BOOL (WINAPI * Process32FirstT)(HANDLE, LPPROCESSENTRY32);\n    typedef BOOL (WINAPI * Process32NextT)(HANDLE, LPPROCESSENTRY32);\n\n    HINSTANCE hKernel32 = GetModuleHandle(\"kernel32\");\n    if (!hKernel32) {\n        return false;\n    }\n\n    CreateToolhelp32SnapshotT createToolhelp32Snapshot = (CreateToolhelp32SnapshotT) GetProcAddress(hKernel32, \"CreateToolhelp32Snapshot\");\n    Process32FirstT process32First = (Process32FirstT) GetProcAddress(hKernel32, \"Process32First\");\n    Process32NextT process32Next = (Process32NextT) GetProcAddress(hKernel32, \"Process32Next\");\n\n    if (createToolhelp32Snapshot == NULL || process32First == NULL || process32Next == NULL) {\n        logErr(true, false, \"Failed to obtain Toolhelp32 functions.\");\n        return false;\n    }\n\n    HANDLE hSnapshot = createToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\n    if (hSnapshot == INVALID_HANDLE_VALUE) {\n        logErr(true, false, \"Failed to obtain process snapshot.\");\n        return false;\n    }\n\n    PROCESSENTRY32 entry = {0};\n    entry.dwSize = sizeof (PROCESSENTRY32);\n    if (!process32First(hSnapshot, &entry)) {\n        CloseHandle(hSnapshot);\n        return false;\n    }\n\n    DWORD curID = GetCurrentProcessId();\n    logMsg(\"Current process ID: %u\", curID);\n\n    do {\n        if (entry.th32ProcessID == curID) {\n            id = entry.th32ParentProcessID;\n            logMsg(\"Parent process ID: %u\", id);\n            CloseHandle(hSnapshot);\n            return true;\n        }\n    } while (process32Next(hSnapshot, &entry));\n\n    CloseHandle(hSnapshot);\n    return false;\n}\n\nbool isWow64()\n{\n    BOOL IsWow64 = FALSE;\n    typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);\n    LPFN_ISWOW64PROCESS fnIsWow64Process;\n\n    fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(GetModuleHandle(TEXT(\"kernel32\")),\"IsWow64Process\");\n  \n    if (NULL != fnIsWow64Process)\n    {\n        if (!fnIsWow64Process(GetCurrentProcess(),&IsWow64))\n        {\n            // handle error\n        }\n    }\n    return IsWow64;\n}\n\nint convertAnsiToUtf8(const char *ansi, char *utf8, int utf8Len) {\n    const int len = 32*1024;\n    WCHAR tmp[len] = L\"\";\n    if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ansi, -1, tmp, len) == 0)\n        return -1;\n    if (WideCharToMultiByte(CP_UTF8, 0, tmp, -1, utf8, utf8Len, NULL, NULL) == 0)\n        return -1;\n    return 0;\n}\n\n"
  },
  {
    "path": "visualvm/launcher/windows-src/o.n.bootstrap/utilsfuncs.h",
    "content": "/*\n * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#ifndef _UTILSFUNCS_H\n#define\t_UTILSFUNCS_H\n\n#include <windows.h>\n#include <string>\n\nbool isWow64();\nbool disableFolderVirtualization(HANDLE hProcess);\nbool getStringFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, std::string &value);\nbool getStringFromRegistryEx(HKEY rootKey, const char *keyName, const char *valueName, std::string &value,bool read64bit);\nbool getStringFromRegistry64bit(HKEY rootKey, const char *keyName, const char *valueName, std::string &value);\nbool getDwordFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, DWORD &value);\nbool dirExists(const char *path);\nbool fileExists(const char *path);\nbool normalizePath(char *path, int len);\nbool createPath(const char *path);\nchar * getCurrentModulePath(char *path, int pathLen);\nchar * skipWhitespaces(char *str);\nchar * trimWhitespaces(char *str);\nvoid logMsg(const char *format, ...);\nvoid logErr(bool appendSysError, bool showMsgBox, const char *format, ...);\nbool checkLoggingArg(int argc, char *argv[], bool delFile);\nbool setupProcess(int &argc, char *argv[], DWORD &parentProcID, const char *attachMsg = 0);\nbool printToConsole(const char *msg);\nbool getParentProcessID(DWORD &id);\nbool isConsoleAttached();\nint convertAnsiToUtf8(const char *ansi, char *utf8, int utf8Len);\n\n#endif\t/* _UTILSFUNCS_H */\n\n"
  },
  {
    "path": "visualvm/launcher/windows-src/version.h",
    "content": "/*\n * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#define COMPANY \"Oracle Corporation\"\n#define COMPONENT \"VisualVM\"\n#define VER \"0.0.0.0\"\n#define FVER 0,0,0,0\n#define BUILD_ID \"0\"\n#define INTERNAL_NAME \"visualvm\"\n#define COPYRIGHT \"\\xA9 2007, 2024, Oracle and/or its affiliates. All rights reserved.\"\n#define FNAME \"visualvm.exe\"\n#define NAME \"VisualVM Dev. build\"\n\n"
  },
  {
    "path": "visualvm/launcher/windows-src/version.rc",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#include <winuser.h>\n#include <winver.h>\n#include \"version.h\"\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// Version\n//\n\nVS_VERSION_INFO VERSIONINFO\n FILEVERSION    FVER\n PRODUCTVERSION FVER\n FILEFLAGSMASK 0x3fL\n#ifdef _DEBUG\n FILEFLAGS 0x1L\n#else\n FILEFLAGS 0x0L\n#endif\n // FILEOS 0x4 is Win32, 0x40004 is Win32 NT only\n FILEOS 0x4L\n // FILETYPE should be 0x1 for .exe and 0x2 for .dll\n FILETYPE 0x1L \n FILESUBTYPE 0x0L\nBEGIN\n    BLOCK \"StringFileInfo\"\n    BEGIN\n        BLOCK \"000004b0\"\n        BEGIN\n            VALUE \"CompanyName\",      COMPANY       \"\\0\"\n            VALUE \"FileDescription\",  COMPONENT     \"\\0\"\n            VALUE \"FileVersion\",      VER           \"\\0\"\n            VALUE \"Full Version\",     BUILD_ID      \"\\0\"\n            VALUE \"InternalName\",     INTERNAL_NAME \"\\0\"\n            VALUE \"LegalCopyright\",   COPYRIGHT     \"\\0\"\n            VALUE \"OriginalFilename\", FNAME         \"\\0\"\n            VALUE \"ProductName\",      NAME          \"\\0\"\n            VALUE \"ProductVersion\",   VER           \"\\0\"\n        END\n    END\n    BLOCK \"VarFileInfo\"\n    BEGIN\n        VALUE \"Translation\", 0x0, 1200\n    END\nEND\n"
  },
  {
    "path": "visualvm/launcher/windows-src/visualvm.cpp",
    "content": "/*\n * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n\n#include \"visualvmlauncher.h\"\n\nint main(int argc, char *argv[]) {\n    VisualVMLauncher launcher;\n    return launcher.start(argc - 1, argv + 1);\n}\n"
  },
  {
    "path": "visualvm/launcher/windows-src/visualvm.exe.manifest",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n<assemblyIdentity version=\"0.0.0.0\"\n   processorArchitecture=\"X86\"\n   name=\"visualvm.exe\"\n   type=\"win32\"/>\n\n<description>VisualVM Process.</description>\n<dependency>\n  <dependentAssembly>\n    <assemblyIdentity\n      type=\"win32\"\n      name=\"Microsoft.Windows.Common-Controls\"\n      version=\"6.0.0.0\"\n      processorArchitecture=\"*\"\n      publicKeyToken=\"6595b64144ccf1df\"\n      language=\"*\"\n    />\n  </dependentAssembly>\n</dependency>\n<!-- Identify the application security requirements. -->\n<trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n  <security>\n    <requestedPrivileges>\n      <requestedExecutionLevel\n        level=\"asInvoker\"\n        uiAccess=\"false\"/>\n      </requestedPrivileges>\n     </security>\n</trustInfo>\n</assembly>\n"
  },
  {
    "path": "visualvm/launcher/windows-src/visualvm.rc",
    "content": "/*\n * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#include <winuser.h>\n\n#include \"version.rc\"\n\n// Icon with lowest ID value placed first to ensure application icon\n// remains consistent on all systems.\n\n100 ICON DISCARDABLE \"visualvm.ico\"\n\nCREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST \"visualvm.exe.manifest\"\n\n"
  },
  {
    "path": "visualvm/launcher/windows-src/visualvmlauncher.cpp",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#ifndef _WIN32_WINNT        \n#define _WIN32_WINNT 0x05010100\n#endif\n\n#include <io.h>\n#include <shlobj.h>\n#include \"visualvmlauncher.h\"\n#include \"o.n.bootstrap/utilsfuncs.h\"\n#include \"o.n.bootstrap/argnames.h\"\n#include \"o.n.bootstrap/nbexecloader.h\"\n\nusing namespace std;\n\nconst char *VisualVMLauncher::REQ_JAVA_VERSION = \"1.8\";\nconst char *VisualVMLauncher::NBEXEC_FILE_PATH = NBEXEC_DLL;\nconst char *VisualVMLauncher::OPT_VISUALVM_DEFAULT_USER_DIR = \"visualvm_default_userdir=\";\nconst char *VisualVMLauncher::OPT_VISUALVM_DEFAULT_CACHE_DIR = \"visualvm_default_cachedir=\";\nconst char *VisualVMLauncher::OPT_VISUALVM_DEFAULT_OPTIONS = \"visualvm_default_options=\";\nconst char *VisualVMLauncher::OPT_VISUALVM_EXTRA_CLUSTERS = \"visualvm_extraclusters=\";\nconst char *VisualVMLauncher::OPT_VISUALVM_JDK_HOME = \"visualvm_jdkhome=\";\nconst char *VisualVMLauncher::ENV_USER_PROFILE = \"USERPROFILE\";\nconst char *VisualVMLauncher::HOME_TOKEN = \"${HOME}\";\nconst char *VisualVMLauncher::DEFAULT_USERDIR_ROOT_TOKEN = \"${DEFAULT_USERDIR_ROOT}\";\nconst char *VisualVMLauncher::DEFAULT_CACHEDIR_ROOT_TOKEN = \"${DEFAULT_CACHEDIR_ROOT}\";\nconst char *VisualVMLauncher::VISUALVM_DIRECTORY = \"\\\\VisualVM\\\\\";\nconst char *VisualVMLauncher::VISUALVM_CACHES_DIRECTORY = \"\\\\VisualVM\\\\Cache\\\\\";\n\nconst char *VisualVMLauncher::CON_ATTACH_MSG = \n\"\\n\\nThe launcher has determined that the parent process has a console and will reuse it for its own console output.\\n\"\n\"Closing the console will result in termination of the running program.\\n\"\n\"Use '--console suppress' to suppress console output.\\n\"\n\"Use '--console new' to create a separate console window.\\n\";\n\nconst char *VisualVMLauncher::staticOptions[] = {\n    \"--branding\",\n    \"visualvm\"\n};\n\nVisualVMLauncher::VisualVMLauncher() {\n}\n\nVisualVMLauncher::VisualVMLauncher(const VisualVMLauncher& orig) {\n}\n\nVisualVMLauncher::~VisualVMLauncher() {\n}\n\nint VisualVMLauncher::start(char *cmdLine) {\n    CmdArgs args(50);\n    args.addCmdLine(cmdLine);\n    return start(args.getCount(), args.getArgs());\n}\n\nint VisualVMLauncher::start(int argc, char *argv[]) {\n    SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);\n    \n    DWORD parentProcID = 0;\n    if (!checkLoggingArg(argc, argv, true) || !setupProcess(argc, argv, parentProcID, CON_ATTACH_MSG) || !initBaseNames() || !readClusterFile()) {\n        return -1;\n    }\n\n    parseConfigFile((baseDir + \"\\\\etc\\\\\" + getAppName() + \".conf\").c_str());\n\n    if (!parseArgs(argc, argv)) {\n        return -1;\n    }\n    string oldUserDir = userDir;\n    parseConfigFile((userDir + \"\\\\etc\\\\\" + getAppName() + \".conf\").c_str());\n    userDir = oldUserDir;\n\n    adjustHeapSize();\n    addExtraClusters();\n    string nbexecPath;\n    SetDllDirectory(baseDir.c_str());\n    if (dirExists(platformDir.c_str())) {\n        nbexecPath = platformDir;\n    } else {\n        nbexecPath = baseDir + '\\\\' + platformDir;\n    }\n    if (!dirExists(nbexecPath.c_str())) {\n        logErr(false, true, \"Could not find platform cluster:\\n%s\", nbexecPath.c_str());\n        return false;\n    }\n\n    CmdArgs newArgs(argc + 20);\n    addSpecificOptions(newArgs);\n    \n    if (!clusters.empty()) {\n        newArgs.add(ARG_NAME_CLUSTERS);\n        newArgs.add(clusters.c_str());\n    }\n    if (!userDir.empty()) {\n        newArgs.add(ARG_NAME_USER_DIR);\n        newArgs.add(userDir.c_str());\n    }\n    if (!defUserDirRoot.empty()) {\n        newArgs.add(ARG_DEFAULT_USER_DIR_ROOT);\n        newArgs.add(defUserDirRoot.c_str());\n    }\n    if (!cacheDir.empty() && !customUserDirFound) {\n        newArgs.add(ARG_NAME_CACHE_DIR);\n        newArgs.add(cacheDir.c_str());\n    }\n    if (!nbOptions.empty()) {\n        newArgs.addCmdLine(nbOptions.c_str());\n    }\n    for (int i = 0; i < argc; i++) {\n        newArgs.add(argv[i]);\n    }\n    if (!jdkOptionFound && jdkHome.empty()) {\n        if (jvmFinder.findJava(REQ_JAVA_VERSION)) {\n            jvmFinder.getJavaPath(jdkHome);\n        }\n    }\n    if (!jdkHome.empty()) {\n        newArgs.add(ARG_NAME_JDKHOME);\n        newArgs.add(jdkHome.c_str());\n    }\n    if (parentProcID) {\n        newArgs.add(ARG_NAME_LA_PPID);\n        char tmp[16] = \"\";\n        newArgs.add(itoa(parentProcID, tmp, 10));\n    }\n    nbexecPath += NBEXEC_FILE_PATH;\n\n    const char *curDir = getCurrentDir();\n    if (curDir) {\n        char olddir[MAX_PATH];\n        DWORD rc = GetCurrentDirectory(MAX_PATH, olddir);\n        if (rc == 0) {\n            logErr(true, false, \"Failed to get current directory\");\n        } else {\n            string od = string(olddir);\n            od.insert(0, \"-J-Dnetbeans.user.dir=\");\n            newArgs.add(od.c_str());\n        }\n        logMsg(\"Changing current directory to: \\\"%s\\\"\", curDir);\n        SetCurrentDirectory(curDir);\n    }\n\n    NBExecLoader loader;\n    return loader.start(nbexecPath.c_str(), newArgs.getCount(), newArgs.getArgs());\n}\n\nbool VisualVMLauncher::initBaseNames() {\n    char path[MAX_PATH] = \"\";\n    getCurrentModulePath(path, MAX_PATH);\n    logMsg(\"Executable: %s\", path);\n    char *bslash = strrchr(path, '\\\\');\n    if (!bslash) {\n        return false;\n    }\n    appName = bslash + 1;\n    appName.erase(appName.rfind('.'));\n    \n    if (ARCHITECTURE == 64) {\n        appName = appName.erase(appName.length() - 2);\n    }\n    \n    logMsg(\"Application name: %s\", appName.c_str());\n\n    *bslash = '\\0';\n    bslash = strrchr(path, '\\\\');\n    if (!bslash) {\n        return false;\n    }\n    *bslash = '\\0';        \n\n    baseDir = path;\n    string config = baseDir + \"\\\\etc\\\\\" + getAppName() + \".conf\";\n    // check that the config file exists\n    if( (_access( config.c_str(), 4 )) == -1 ) {\n        config = baseDir + \"\\\\lib\\\\visualvm\\\\etc\\\\\" + getAppName() + \".conf\";\n        if( (_access( config.c_str(), 4 )) != -1 ) { // JDK installation\n            jdkHome = baseDir;\n            baseDir += \"\\\\lib\\\\visualvm\";\n        }         \n    }\n    \n    logMsg(\"Base dir: %s\", baseDir.c_str());\n    return true;\n}\n\nvoid VisualVMLauncher::addCluster(const char *cluster) {\n\n    class SetCurDir {\n    public:\n        SetCurDir(const char *dir) {\n            oldCurDir[0] = '\\0';\n            DWORD rc = GetCurrentDirectory(MAX_PATH, oldCurDir);\n            if (rc == 0) {\n                logErr(true, false, \"Failed to get current directory\");\n                return;\n            }\n            if (rc > MAX_PATH) {\n                logMsg(\"Failed to get current directory, buffer is too small.\");\n                return;\n            }\n            if (!SetCurrentDirectory(dir)) {\n                logErr(true, true, \"Failed to set current directory to \\\"%s\\\"\", dir);\n                oldCurDir[0] = '\\0';\n            }\n        }\n\n        ~SetCurDir() {\n            if (oldCurDir[0]) {\n                if (!SetCurrentDirectory(oldCurDir)) {\n                    logErr(true, true, \"Failed to set current directory to \\\"%s\\\"\", oldCurDir);\n                }\n            }\n        }\n    private:\n        char oldCurDir[MAX_PATH];\n    };\n\n    logMsg(\"addCluster: %s\", cluster);\n    SetCurDir setCurDir(baseDir.c_str());\n    char clusterPath[MAX_PATH + 1] = {0};\n    strncpy(clusterPath, cluster, MAX_PATH);\n    if (!normalizePath(clusterPath, MAX_PATH)) {\n        logMsg(\"Invalid cluster path: %s\", cluster);\n        return;\n    }\n    if (!clusters.empty()) {\n        clusters += ';';\n    }\n    logMsg(\"Adding cluster %s\", clusterPath);\n    clusters += clusterPath;\n}\n\nvoid VisualVMLauncher::addExtraClusters() {\n    logMsg(__PRETTY_FUNCTION__);\n    const char delim = ';';\n    string::size_type start = extraClusters.find_first_not_of(delim, 0);\n    string::size_type end = extraClusters.find_first_of(delim, start);\n    while (string::npos != end || string::npos != start) {\n        string cluster = extraClusters.substr(start, end - start);\n        addCluster(cluster.c_str());\n        start = extraClusters.find_first_not_of(delim, end);\n        end = extraClusters.find_first_of(delim, start);\n    }\n}\n\nbool VisualVMLauncher::readClusterFile() {\n    clusters = \"\";\n    string clusterFile = baseDir + \"\\\\etc\\\\\" + getAppName() + \".clusters\";\n    logMsg(\"readClusterFile() file: %s\", clusterFile.c_str());\n\n    FILE* file = fopen(clusterFile.c_str(), \"r\");\n    if (!file) {\n        logErr(true, true, \"Cannot open file \\\"%s\\\" for reading.\", clusterFile.c_str());\n        return false;\n    }\n\n    char line[4096] = \"\";\n    while (fgets(line, sizeof(line), file)) {\n        char *str = skipWhitespaces(line);\n        if (*str == '#' || *str == '\\0') {\n            continue;\n        }\n        char *pc = str;\n        while (*pc != '\\0' && *pc != '\\t' && *pc != '\\n' && *pc != '\\r') {\n            pc++;\n        }\n        *pc = '\\0';\n\n        if (platformDir.empty()) {\n            char *slash = strrchr(str, '\\\\');\n            if (!slash) {\n                slash = strrchr(str, '/');\n            }\n            char *dir = slash ? slash + 1 : str;\n            if (strncmp(dir, \"platform\", strlen(\"platform\")) == 0) {\n                platformDir = str;\n            } else {\n                addCluster(str);\n            }\n        } else {\n            addCluster(str);\n        }\n    }\n    bool ok = ferror(file) == 0;\n    if (!ok) {\n        logErr(true, true, \"Error while reading file \\\"%s\\\".\", clusterFile.c_str());\n    }\n    fclose(file);\n    if (platformDir.empty()) {\n        platformDir = \"platform\";\n    }\n    return ok;\n}\n\nbool VisualVMLauncher::parseArgs(int argc, char *argv[]) {\n#define CHECK_ARG \\\n    if (i+1 == argc) {\\\n        logErr(false, true, \"Argument is missing for \\\"%s\\\" option.\", argv[i]);\\\n        return false;\\\n    }\n\n    logMsg(\"parseArgs():\");\n    for (int i = 0; i < argc; i++) {\n        logMsg(\"\\t%s\", argv[i]);\n    }\n    customUserDirFound = 0;\n    jdkOptionFound = false;\n    for (int i = 0; i < argc; i++) {\n        if (strcmp(ARG_NAME_USER_DIR, argv[i]) == 0) {\n            CHECK_ARG;\n            char tmp[MAX_PATH + 1] = {0};\n            strncpy(tmp, argv[++i], MAX_PATH);\n            if (!normalizePath(tmp, MAX_PATH)) {\n                logErr(false, true, \"User directory path \\\"%s\\\" is not valid.\", argv[i]);\n                return false;\n            }\n            customUserDirFound = 1;\n            userDir = tmp;\n            logMsg(\"User dir: %s\", userDir.c_str());\n        }\n        if (strcmp(ARG_NAME_CACHE_DIR, argv[i]) == 0) {\n            CHECK_ARG;\n            char tmp[MAX_PATH + 1] = {0};\n            strncpy(tmp, argv[++i], MAX_PATH);\n            if (!normalizePath(tmp, MAX_PATH)) {\n                logErr(false, true, \"Cache directory path \\\"%s\\\" is not valid.\", argv[i]);\n                return false;\n            }\n            cacheDir = tmp;\n            logMsg(\"Cache dir: %s\", cacheDir.c_str());\n        }\n        if (strcmp(ARG_NAME_JDKHOME, argv[i]) == 0) {\n            jdkOptionFound = true;\n        }\n    }\n    logMsg(\"parseArgs() finished\");\n    return true;\n}\n\nbool VisualVMLauncher::findUserDir(const char *str) {\n    logMsg(__PRETTY_FUNCTION__);\n    if (strncmp(str, HOME_TOKEN, strlen(HOME_TOKEN)) == 0) {\n        if (userHome.empty()) {\n            char *userProfile = getenv(ENV_USER_PROFILE);\n            if (userProfile) {\n                userHome = userProfile;\n            } else {\n                TCHAR userHomeChar[MAX_PATH]; \n                if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, userHomeChar))) {    \n                    return false;\n                }\n                userHome = userHomeChar;\n                userHome.erase(userHome.rfind('\\\\'));\n            }\n            logMsg(\"User home: %s\", userHome.c_str());\n        }\n        userDir = userHome + (str + strlen(HOME_TOKEN));\n    } else if (strncmp(str, DEFAULT_USERDIR_ROOT_TOKEN, strlen(DEFAULT_USERDIR_ROOT_TOKEN)) == 0) {       \n        userDir = getDefaultUserDirRoot() + (str + strlen(DEFAULT_USERDIR_ROOT_TOKEN));\n    } else {\n        getDefaultUserDirRoot();\n        userDir = str;\n    }\n    return true;\n}\n\nbool VisualVMLauncher::findCacheDir(const char *str) {\n    logMsg(__PRETTY_FUNCTION__);\n    if (strncmp(str, HOME_TOKEN, strlen(HOME_TOKEN)) == 0) {\n        if (userHome.empty()) {\n            char *userProfile = getenv(ENV_USER_PROFILE);\n            if (userProfile) {\n                userHome = userProfile;\n            } else {\n                TCHAR userHomeChar[MAX_PATH]; \n                if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, userHomeChar))) {    \n                    return false;\n                }\n                userHome = userHomeChar;\n                userHome.erase(userHome.rfind('\\\\'));\n            }\n            logMsg(\"User home: %s\", userHome.c_str());\n        }\n        cacheDir = userHome + (str + strlen(HOME_TOKEN));\n    } else if (strncmp(str, DEFAULT_CACHEDIR_ROOT_TOKEN, strlen(DEFAULT_CACHEDIR_ROOT_TOKEN)) == 0) {        \n        cacheDir = getDefaultCacheDirRoot() + (str + strlen(DEFAULT_CACHEDIR_ROOT_TOKEN));\n    } else {\n        getDefaultCacheDirRoot();\n        cacheDir = str;\n    }\n    return true;\n}\n\nstring VisualVMLauncher::getDefaultUserDirRoot() {\n    TCHAR defUserDirRootChar[MAX_PATH];\n    if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, defUserDirRootChar))) {\n        return false;\n    }\n    defUserDirRoot = ((string) defUserDirRootChar) + VISUALVM_DIRECTORY;\n    defUserDirRoot.erase(defUserDirRoot.rfind('\\\\'));\n    logMsg(\"Default Userdir Root: %s\", defUserDirRoot.c_str());\n    return defUserDirRoot;\n}\n\nstring VisualVMLauncher::getDefaultCacheDirRoot() {\n    TCHAR defCacheDirRootChar[MAX_PATH];\n    if (FAILED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, defCacheDirRootChar))) {\n        return false;\n    }\n    defCacheDirRoot = ((string) defCacheDirRootChar) + VISUALVM_CACHES_DIRECTORY;\n    defCacheDirRoot.erase(defCacheDirRoot.rfind('\\\\'));\n    logMsg(\"Default Cachedir Root: %s\", defCacheDirRoot.c_str());\n    return defCacheDirRoot;\n}\n\nbool VisualVMLauncher::getOption(char *&str, const char *opt) {\n    if (strncmp(str, opt, strlen(opt)) == 0) {\n        str += strlen(opt);\n        char *end = trimWhitespaces(str);\n        if (*str == '\"') {\n            str++;\n        }\n        if (end >= str && *end == '\"') {\n            *end = '\\0';\n        }\n        logMsg(\"Option found: %s%s\", opt, str);\n        return true;\n    }\n    return false;\n}\n\nbool VisualVMLauncher::parseConfigFile(const char* path) {\n    logMsg(\"parseConfigFile(%s)\", path);\n    FILE *file = fopen(path, \"r\");\n    if (!file) {\n        logErr(true, false, \"Cannot open file \\\"%s\\\" for reading.\", path);\n        return false;\n    }\n    \n    char line[4096] = \"\";\n    while (fgets(line, sizeof(line), file)) {\n        char *str = skipWhitespaces(line);\n        if (*str == '#') {\n            continue;\n        }\n        if (getOption(str, getDefUserDirOptName())) {\n             findUserDir(str);\n             logMsg(\"User dir: %s\", userDir.c_str());\n        } else if (getOption(str, getDefCacheDirOptName())) {\n             findCacheDir(str);\n             logMsg(\"Cache dir: %s\", cacheDir.c_str());\n        } else if (getOption(str, getDefOptionsOptName())) {\n            // replace \\\" by \"\n            int len = strlen(str);\n            int k = 0;\n            for (int i = 0; i < len; i++) {\n                if (str[i] == '\\\\' && str[i+1] == '\\\"') {\n                    continue;\n                }\n                str[k++] = str[i];\n            }\n            str[k] = '\\0';\n            nbOptions = str;\n            logMsg(\"After replacement: %s\", nbOptions.c_str());\n\n        } else if (getOption(str, getExtraClustersOptName())) {\n            extraClusters = str;\n        } else if (getOption(str, getJdkHomeOptName())) {\n            jdkHome = str;\n        }\n    }\n    bool ok = ferror(file) == 0;\n    if (!ok) {\n        logErr(true, false, \"Error while reading file \\\"%s\\\".\", path);\n    }\n    fclose(file);\n    return true;\n}\n\ntypedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);\n\nbool VisualVMLauncher::areWeOn32bits() {\n    // find out if we are on 32-bit Windows\n    SYSTEM_INFO siSysInfo;\n    PGNSI pGNSI;\n    pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT(\"kernel32.dll\")),\n            \"GetNativeSystemInfo\");\n    if (NULL != pGNSI)\n        pGNSI(&siSysInfo);\n    else\n        GetSystemInfo(&siSysInfo);\n    logMsg(\"VisualVMLauncher::areWeOn32bits returns (0=false, 1=true)? %i\", ((siSysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) ||\n            (strstr(NBEXEC_FILE_PATH, \"64\") == NULL)));\n    return ((siSysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) ||\n            (strstr(NBEXEC_FILE_PATH, \"64\") == NULL));\n}\n\n// Search if -Xmx is specified in existing arguments\n// If it isn't compute default values based on 32/64-bits and available RAM\nvoid VisualVMLauncher::adjustHeapSize() {\n    if (nbOptions.find(\"-J-Xmx\") == string::npos) {\n        int maxheap;\n        if (areWeOn32bits())\n            maxheap = 512;\n        else\n            maxheap = 1024;\n        // find how much memory we have and add -Xmx as 1/5 of the memory\n        MEMORYSTATUSEX ms = {0};\n        ms.dwLength = sizeof (ms);\n        GlobalMemoryStatusEx(&ms);\n        int memory = (int)((ms.ullTotalPhys / 1024 / 1024) / 5);\n        if (memory < 96) {\n            memory = 96;\n        }\n        else if (memory > maxheap) {\n            memory = maxheap;\n        }\n        char tmp[32];\n        snprintf(tmp, 32, \" -J-Xmx%dm\", memory);\n        logMsg(\"Memory settings: -J-Xmx%dm\", memory);\n        nbOptions += tmp;\n    }\n}\n\nconst char * VisualVMLauncher::getAppName() {\n    return \"visualvm\";\n}\n\nvoid VisualVMLauncher::addSpecificOptions(CmdArgs &args) {\n    for (unsigned i = 0; i < sizeof (staticOptions) / sizeof (char*); i++) {\n        args.add(staticOptions[i]);\n    }\n}\n\nconst char * VisualVMLauncher::getDefUserDirOptName() {\n    return OPT_VISUALVM_DEFAULT_USER_DIR;\n}\n\nconst char * VisualVMLauncher::getDefCacheDirOptName() {\n    return OPT_VISUALVM_DEFAULT_CACHE_DIR;\n}\n\n\nconst char * VisualVMLauncher::getDefOptionsOptName() {\n    return OPT_VISUALVM_DEFAULT_OPTIONS;\n}\n\nconst char * VisualVMLauncher::getExtraClustersOptName() {\n    return OPT_VISUALVM_EXTRA_CLUSTERS;\n}\n\nconst char * VisualVMLauncher::getJdkHomeOptName() {\n    return OPT_VISUALVM_JDK_HOME;\n}\n\nconst char * VisualVMLauncher::getCurrentDir() {\n    return 0;\n}\n"
  },
  {
    "path": "visualvm/launcher/windows-src/visualvmlauncher.h",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#ifndef _NBLAUNCHER_H\n#define\t_NBLAUNCHER_H\n\n#include <string>\n#include <windows.h>\n#include <cstddef>\n#include \"cmdargs.h\"\n#include \"jvmfinder.h\"\n\nclass VisualVMLauncher {\nprotected:\n    static const char *REQ_JAVA_VERSION;\n    static const char *NBEXEC_FILE_PATH;\n    static const char *OPT_VISUALVM_DEFAULT_USER_DIR;\n    static const char *OPT_VISUALVM_DEFAULT_CACHE_DIR;\n    static const char *OPT_VISUALVM_DEFAULT_OPTIONS;\n    static const char *OPT_VISUALVM_EXTRA_CLUSTERS;\n    static const char *OPT_VISUALVM_JDK_HOME;\n    static const char *REG_SHELL_FOLDERS_KEY;\n    static const char *HOME_TOKEN;\n    static const char *DEFAULT_USERDIR_ROOT_TOKEN;\n    static const char *DEFAULT_CACHEDIR_ROOT_TOKEN;\n    static const char *CON_ATTACH_MSG;\n    static const char *VISUALVM_DIRECTORY;\n    static const char *VISUALVM_CACHES_DIRECTORY;\n\nprivate:\n    static const char *ENV_USER_PROFILE;\n    static const char *REG_DESKTOP_NAME;\n    static const char *REG_DEFAULT_USERDIR_ROOT;\n    static const char *REG_DEFAULT_CACHEDIR_ROOT;\n    static const char* staticOptions[];\n\n    typedef int (*StartPlatform)(int argc, char *argv[]);\n\npublic:\n    VisualVMLauncher();\n    virtual ~VisualVMLauncher();\n\n    int start(int argc, char *argv[]);\n    int start(char *cmdLine);\n\nprotected:\n    virtual bool initBaseNames();\n    virtual void addSpecificOptions(CmdArgs &args);\n    virtual bool areWeOn32bits();\n    virtual void adjustHeapSize();\n    virtual bool findUserDir(const char *str);\n    virtual bool findCacheDir(const char *str);\n    virtual const char * getAppName();\n    virtual const char * getDefUserDirOptName();\n    virtual const char * getDefCacheDirOptName();\n    virtual const char * getDefOptionsOptName();\n    virtual const char * getExtraClustersOptName();\n    virtual const char * getJdkHomeOptName();\n    virtual const char * getCurrentDir();\n\nprivate:\n    VisualVMLauncher(const VisualVMLauncher& orig);\n    bool readClusterFile();\n    bool parseArgs(int argc, char *argv[]);\n    bool parseConfigFile(const char* path);    \n    bool getOption(char *&str, const char *opt);\n    void addCluster(const char *cl);\n    void addExtraClusters();\n    std::string getDefaultUserDirRoot();\n    std::string getDefaultCacheDirRoot();\n\nprotected:\n    std::string baseDir;\n    std::string appName;\n    std::string platformDir;\n    std::string userHome;\n    std::string userDir;\n    std::string cacheDir;\n    std::string defUserDirRoot;\n    std::string defCacheDirRoot;\n    std::string clusters;\n    std::string extraClusters;\n    std::string nbOptions;\n    std::string jdkHome;\n    bool jdkOptionFound;\n    \nprivate:\n    bool customUserDirFound;\n    JvmFinder jvmFinder;\n};\n\n#endif\t/* _NBLAUNCHER_H */\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project basedir=\".\" default=\"netbeans\" name=\"lib.profiler\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.lib.jfluid</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n\n  <!-- Compile the JFluid engine system library, that depends on JDK version - so there are two libraries -->\n  <!-- Compile the engine system library -->\n    <target name=\"compile-system\" depends=\"init\">\n        <mkdir dir=\"${build15.classes.dir}\"/>\n        <javac srcdir=\"${src15.dir}\" destdir=\"${build15.classes.dir}\" debug=\"${build.compiler.debug}\" debuglevel=\"${build.compiler.debuglevel}\" encoding=\"UTF-8\"\n                deprecation=\"${build.compiler.deprecation}\" optimize=\"${build.compiler.optimize}\" source=\"1.5\" target=\"1.5\" includeantruntime=\"false\">\n            <include name=\"org/graalvm/visualvm/lib/jfluid/server/system/**\"/>\n            <compilerarg line=\"${javac.compilerargs}\"/>\n        </javac>\n        <mkdir dir=\"${build.classes.dir}\"/>\n        <javac srcdir=\"${src.dir}\" destdir=\"${build.classes.dir}\" debug=\"${build.compiler.debug}\" debuglevel=\"${build.compiler.debuglevel}\" encoding=\"UTF-8\"\n                classpath=\"${build15.classes.dir}\" deprecation=\"${build.compiler.deprecation}\" optimize=\"${build.compiler.optimize}\" source=\"1.4\" target=\"1.4\" includeantruntime=\"false\">\n            <include name=\"org/graalvm/visualvm/lib/jfluid/server/**\"/>\n            <include name=\"org/graalvm/visualvm/lib/jfluid/global/**\"/>\n            <include name=\"org/graalvm/visualvm/lib/jfluid/wireprotocol/**\"/>\n            <compilerarg line=\"${javac.compilerargs}\"/>\n        </javac>\n    </target>\n\n    <target name=\"post-compile\" depends=\"projectized-common.compile\">\n        <javac srcdir=\"${src15.dir}\" destdir=\"${build15.classes.dir}\" debug=\"${build.compiler.debug}\" debuglevel=\"${build.compiler.debuglevel}\" encoding=\"UTF-8\"\n                classpath=\"${build.classes.dir}\" deprecation=\"${build.compiler.deprecation}\" optimize=\"${build.compiler.optimize}\" source=\"1.5\" target=\"1.5\" includeantruntime=\"false\">\n            <compilerarg line=\"${javac.compilerargs}\"/>\n        </javac>\n    </target>\n\n    <target name=\"compile\" depends=\"init,compile-system, projectized-common.compile,post-compile\"/>\n\n    <target name=\"jar\" depends=\"init,compile,jar-prep\">\n        <!-- Client side -->\n        <jarwithmoduleattributes jarfile=\"${cluster}/${module.jar}\" compress=\"${build.package.compress}\" index=\"${build.package.index}\" manifest=\"${manifest.mf}\" stamp=\"${cluster}/.lastModified\">\n            <fileset dir=\"${build.classes.dir}\">\n              <exclude name=\"org/graalvm/visualvm/lib/jfluid/server/**\"/>\n            </fileset>\n        </jarwithmoduleattributes>\n        \n       <!-- Server side -->\n       <mkdir dir=\"${cluster}/lib\"/>\n       <jar destfile=\"${cluster}/${jfluid.server.jar}\"\n         basedir=\"${build.classes.dir}\"\n         includes=\"org/graalvm/visualvm/lib/jfluid/server/** org/graalvm/visualvm/lib/jfluid/global/** org/graalvm/visualvm/lib/jfluid/wireprotocol/**\"\n         compress=\"false\">\n       </jar>\n       <jar destfile=\"${cluster}/${jfluid.server.15.jar}\"\n         manifest=\"${src15.dir}/manifest.mf\"\n         basedir=\"${build15.classes.dir}\"\n         compress=\"false\">\n       </jar>\n    </target>\n\n    <target name=\"release\" depends=\"projectized-common.release\">\n        <fixcrlf eol=\"crlf\" srcdir=\"${cluster}/lib/deployed\" includes=\"**/*.map\"/>\n    </target>\n\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.lib.jfluid/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/lib/jfluid/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.20\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-linux-cvm.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nBuildForCVM()\n{\n        CVM_HOME=$1\n        JDK_ID=$2\n        echo $CVM_HOME $JDK_ID\n\tgcc -I$CVM_HOME/src/share/javavm/export -I$CVM_HOME/src/share -I$CVM_HOME/src/linux -I$CVM_HOME/src -I$CVM_HOME/src/linux-x86 -DLINUX -DCVM -pthread -fPIC -shared -O3 -Wall \\\n        -o ../../release/lib/deployed/$JDK_ID/linux/libprofilerinterface.so \\\n        ../src-jdk15/class_file_cache.c \\\n        ../src-jdk15/attach.c \\\n        ../src-jdk15/Classes.c \\\n        ../src-jdk15/Timers.c \\\n        ../src-jdk15/GC.c \\\n        ../src-jdk15/Threads.c \\\n        ../src-jdk15/Stacks.c \\\n        ../src-jdk15/common_functions.c\n\n        rm -f *.o\n\n\tgcc -I$CVM_HOME/src/share/javavm/export -I$CVM_HOME/src/share -I$CVM_HOME/src/linux -I$CVM_HOME/src -I$CVM_HOME/src/linux-x86 -DLINUX -DCVM -pthread -fPIC -shared -Wall  -g \\\n        -o ../../release/lib/deployed/$JDK_ID/linux/libprofilerinterface_g.so \\\n        ../src-jdk15/class_file_cache.c \\\n        ../src-jdk15/attach.c \\\n        ../src-jdk15/Classes.c \\\n        ../src-jdk15/Timers.c \\\n        ../src-jdk15/GC.c \\\n        ../src-jdk15/Threads.c \\\n        ../src-jdk15/Stacks.c \\\n        ../src-jdk15/common_functions.c\n\n        rm -f *.o\n}\n\nmkdir -p ../../release/lib/deployed/cvm/linux\n\nBuildForCVM \"$CVM_HOME\" \"cvm\"\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-linux.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nBuildForJDK()\n{\n        JAVA_HOME=$1\n        JDK_ID=$2\n\techo $JAVA_HOME $JDK_ID\n\tgcc -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -DLINUX -pthread -fPIC -shared -O3 -Wall \\\n\t-o ../../release/lib/deployed/$JDK_ID/linux/libprofilerinterface.so \\\n\t../src-jdk15/class_file_cache.c \\\n\t../src-jdk15/attach.c \\\n\t../src-jdk15/Classes.c \\\n\t../src-jdk15/HeapDump.c \\\n\t../src-jdk15/Timers.c \\\n\t../src-jdk15/GC.c \\\n\t../src-jdk15/Threads.c \\\n\t../src-jdk15/Stacks.c \\\n\t../src-jdk15/common_functions.c\n\n\trm -f *.o\n}\n\nBuildForJDK \"$JAVA_HOME_15\" \"jdk15\"\nBuildForJDK \"$JAVA_HOME_16\" \"jdk16\"\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-linux64.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nBuildForJDK()\n{\n        JAVA_HOME=$1\n        JDK_ID=$2\n        echo $JAVA_HOME $JDK_ID\n\tgcc32 -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -DLINUX -pthread -fPIC -shared -O3 -Wall -m64  \\\n\t-o ../../release/lib/deployed/$JDK_ID/linux-amd64/libprofilerinterface.so \\\n\t../src-jdk15/class_file_cache.c \\\n\t../src-jdk15/attach.c \\\n\t../src-jdk15/Classes.c \\\n\t../src-jdk15/HeapDump.c \\\n\t../src-jdk15/Timers.c \\\n\t../src-jdk15/GC.c \\\n\t../src-jdk15/Threads.c \\\n\t../src-jdk15/Stacks.c \\\n\t../src-jdk15/common_functions.c\n\n        rm -f *.o\n}\n\nBuildForJDK \"$JAVA_HOME_15\" \"jdk15\"\nBuildForJDK \"$JAVA_HOME_16\" \"jdk16\"\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-linuxaarch64.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nBuildForJDK()\n{\n        JAVA_HOME=$1\n        JDK_ID=$2\n        ARCH_DIR=$3\n        ARCH_FLAGS=$4\n\techo $JAVA_HOME $JDK_ID $ARCH_DIR $ARCH_FLAGS\n\t/usr/bin/gcc -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -DLINUX -pthread -fPIC -shared -O3 $ARCH_FLAGS -Wall \\\n\t-o ../../release/lib/deployed/$JDK_ID/$ARCH_DIR/libprofilerinterface.so \\\n\t../src-jdk15/class_file_cache.c \\\n\t../src-jdk15/attach.c \\\n\t../src-jdk15/Classes.c \\\n\t../src-jdk15/HeapDump.c \\\n\t../src-jdk15/Timers.c \\\n\t../src-jdk15/GC.c \\\n\t../src-jdk15/Threads.c \\\n\t../src-jdk15/Stacks.c \\\n\t../src-jdk15/common_functions.c\n\n\trm -f *.o\n}\n\nBuildForJDK \"$JAVA_HOME_16\" \"jdk16\" \"linux-aarch64\" \"\"\n\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-linuxarm.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nBuildForJDK()\n{\n        JAVA_HOME=$1\n        JDK_ID=$2\n        ARCH_DIR=$3\n        ARCH_TOOLS=$4\n        ARCH_FLAGS=$5\n\techo $JAVA_HOME $JDK_ID $ARCH_DIR $ARCH_TOOLS $ARCH_FLAGS\n\t$ARCH_TOOLS-gcc -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -DLINUX -pthread -fPIC -shared -O3 $ARCH_FLAGS -Wall \\\n\t-o ../../release/lib/deployed/$JDK_ID/$ARCH_DIR/libprofilerinterface.so \\\n\t../src-jdk15/class_file_cache.c \\\n\t../src-jdk15/attach.c \\\n\t../src-jdk15/Classes.c \\\n\t../src-jdk15/HeapDump.c \\\n\t../src-jdk15/Timers.c \\\n\t../src-jdk15/GC.c \\\n\t../src-jdk15/Threads.c \\\n\t../src-jdk15/Stacks.c \\\n\t../src-jdk15/common_functions.c\n\n\trm -f *.o\n}\n\nBuildForJDK \"$JAVA_HOME_16\" \"jdk16\" \"linux-arm\" \"$ARM_SFLT_TOOLS\" \"-msoft-float -march=armv5t\"\nBuildForJDK \"$JAVA_HOME_16\" \"jdk16\" \"linux-arm-vfp-hflt\" \"$ARM_VFP_HFLT_TOOLS\" \"-marm -mfloat-abi=hard -mfpu=vfp\"\n\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-mac-arm.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nBuildForJDK()\n{\n\tSYSROOT=$1\n\tJDK_ID=$2\n\tJDK_VER=$3\n\techo $SYSROOT $JDK_ID $JAVA_HOME\n\n\tCC_OPTS=\"-c -I$JAVA_HOME/include -I$JAVA_HOME/include/darwin \\\n        -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks \\\n\t-Os -Wunused-variable -fmessage-length=0 -mmacosx-version-min=11.0 -Wmost \\\n\t-Wno-four-char-constants -Wno-unknown-pragmas -isysroot $SYSROOT -DLINUX\"\n\n\tLD_OPTS=\"-Wl,-single_module -compatibility_version 1 -current_version 1 \\\n\t-dynamiclib -mmacosx-version-min=11.0 -isysroot $SYSROOT\"\n\n\tSOURCES=\"../src-jdk15/class_file_cache.c \\\n\t../src-jdk15/attach.c \\\n\t../src-jdk15/Classes.c \\\n\t../src-jdk15/HeapDump.c \\\n\t../src-jdk15/Timers.c \\\n\t../src-jdk15/GC.c \\\n\t../src-jdk15/Threads.c \\\n\t../src-jdk15/Stacks.c \\\n\t../src-jdk15/common_functions.c\"\n\n\tOBJ_FILES=\"class_file_cache.o \\\n\tattach.o \\\n\tClasses.o \\\n\tHeapDump.o \\\n\tTimers.o \\\n\tGC.o \\\n\tThreads.o \\\n\tStacks.o \\\n\tcommon_functions.o\"\n\n\tBuildForArch \"arm64\"\n\n        cp ../../release/lib/deployed/$JDK_ID/mac/libprofilerinterface.jnilib .\n        if lipo libprofilerinterface.jnilib -verify_arch arm64 ; then\n          lipo libprofilerinterface.jnilib -replace arm64 libprofilerinterface_arm64.jnilib \\\n          -output ../../release/lib/deployed/$JDK_ID/mac/libprofilerinterface.jnilib\n        else\n          lipo -create libprofilerinterface.jnilib libprofilerinterface_arm64.jnilib \\\n          -output ../../release/lib/deployed/$JDK_ID/mac/libprofilerinterface.jnilib\n        fi\n\n\trm *.jnilib\n\n}\n\nBuildForArch()\n{\n        ARCH=$1\n        echo \"ARCH \"$ARCH\n\n        clang $CC_OPTS -arch $ARCH $SOURCES\n        clang $LD_OPTS -arch $ARCH -o libprofilerinterface_$ARCH.jnilib $OBJ_FILES\n\n        rm *.o\n}\n\nBuildForJDK \"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk\" \"jdk16\" \"1.6\"\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-mac.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nBuildForJDK()\n{\n\tSYSROOT=$1\n\tJDK_ID=$2\n\tJDK_VER=$3\n\techo $SYSROOT $JDK_ID $SYSROOT/System/Library/Frameworks/JavaVM.framework/Versions/$JDK_VER/Headers\n\n\tCC_OPTS=\"-c -isystem $SYSROOT/System/Library/Frameworks/JavaVM.framework/Versions/$JDK_VER/Headers \\\n        -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks \\\n\t-Os -Wunused-variable -fmessage-length=0 -mmacosx-version-min=10.4 -Wmost \\\n\t-Wno-four-char-constants -Wno-unknown-pragmas -isysroot $SYSROOT -DLINUX\"\n\n\tLD_OPTS=\"-framework JavaVM  -Wl,-single_module -compatibility_version 1 -current_version 1 \\\n\t-dynamiclib -mmacosx-version-min=10.4 -isysroot $SYSROOT\"\n\n\tSOURCES=\"../src-jdk15/class_file_cache.c \\\n\t../src-jdk15/attach.c \\\n\t../src-jdk15/Classes.c \\\n\t../src-jdk15/HeapDump.c \\\n\t../src-jdk15/Timers.c \\\n\t../src-jdk15/GC.c \\\n\t../src-jdk15/Threads.c \\\n\t../src-jdk15/Stacks.c \\\n\t../src-jdk15/common_functions.c\"\n\n\tOBJ_FILES=\"class_file_cache.o \\\n\tattach.o \\\n\tClasses.o \\\n\tHeapDump.o \\\n\tTimers.o \\\n\tGC.o \\\n\tThreads.o \\\n\tStacks.o \\\n\tcommon_functions.o\"\n\n\tBuildForArch \"ppc\"\n        BuildForArch \"ppc64\"\n\tBuildForArch \"i386\"\n        BuildForArch \"x86_64\"\n\n\tlipo -create libprofilerinterface_ppc.jnilib libprofilerinterface_i386.jnilib \\\n\tlibprofilerinterface_ppc64.jnilib libprofilerinterface_x86_64.jnilib \\\n\t-output ../../release/lib/deployed/$JDK_ID/mac/libprofilerinterface.jnilib\n\n\trm *.jnilib\n}\n\nBuildForArch()\n{\n        ARCH=$1\n        echo \"ARCH \"$ARCH\n\n        gcc-4.0 $CC_OPTS -arch $ARCH $SOURCES\n        gcc-4.0 $LD_OPTS -arch $ARCH -o libprofilerinterface_$ARCH.jnilib $OBJ_FILES\n\n        rm *.o\n}\n\nBuildForJDK \"/Developer/SDKs/MacOSX10.4u.sdk\" \"jdk15\" \"1.5\"\nBuildForJDK \"/Developer/SDKs/MacOSX10.5.sdk\" \"jdk16\" \"1.6\"\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-solaris-cvm.sh",
    "content": "#!/usr/bin/bash\n\n# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nexport PROC=`uname -p`\necho PROC is $PROC\n\nif [ $PROC = \"i386\" ]; then\n  export PROC_FLAGS=\"-xregs=no%frameptr\"\nelif [ $PROC = \"sparc\" ]; then\n  export PROC_FLAGS=\"-xregs=no%appl -xmemalign=4s -xarch=v8\"\nelse\n  echo \"Invalid architecture \" $PROC\nfi\nmkdir -p ../../dist/deployed/cvm/solaris\n\nCC_FLAGS=\"-I$CVM_HOME/src/share/javavm/export -I$CVM_HOME/src/share \\\n-I$CVM_HOME/src/solaris -I$CVM_HOME/src -I$CVM_HOME/src/solaris-x86 \\\n-DSOLARIS -G -lrt -xO2 -v -mt -xc99=%none -xCC -Xa -xstrconst\"\n\ncc $CC_FLAGS $PROC_FLAGS \\\n-o ../../dist/deployed/cvm/solaris-$PROC/libprofilerinterface.so \\\n../src-jdk15/class_file_cache.c \\\n../src-jdk15/attach.c \\\n../src-jdk15/Classes.c \\\n../src-jdk15/Timers.c \\\n../src-jdk15/GC.c \\\n../src-jdk15/Threads.c \\\n../src-jdk15/Stacks.c \\\n../src-jdk15/common_functions.c\n\ncc $CC_FLAGS -g $PROC_FLAGS \\\n-o ../../dist/deployed/cvm/solaris-$PROC/libprofilerinterface_g.so \\\n../src-jdk15/class_file_cache.c \\\n../src-jdk15/attach.c \\\n../src-jdk15/Classes.c \\\n../src-jdk15/Timers.c \\\n../src-jdk15/GC.c \\\n../src-jdk15/Threads.c \\\n../src-jdk15/Stacks.c \\\n../src-jdk15/common_functions.c\n\n\ncc $CC_FLAGS $PROC_FLAGS \\\n-o ../../dist/deployed/cvm/solaris-$PROC/libclient.so \\\n../src/ProfilerClient.c\n\ncc $CC_FLAGS -g $PROC_FLAGS \\\n-o ../../dist/deployed/cvm/solaris-$PROC/libclient_g.so \\\n../src/ProfilerClient.c\n\nrm -f *.o\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-solaris.sh",
    "content": "#!/usr/bin/bash\n\n# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nBuildForJDK()\n{\n        JAVA_HOME=$1\n        JDK_ID=$2\n        echo $JAVA_HOME $JDK_ID\n        # Use Solaris Studio 12\n\tCC_FLAGS=\"-I$JAVA_HOME/include -I$JAVA_HOME/include/solaris -DSOLARIS -G -lrt \\\n\t-xO2 -v -mt -xc99=none -Kpic -xCC -Xa -xstrconst\"\n\n\tcc $CC_FLAGS $PROC_FLAGS \\\n\t-o ../../release/lib/deployed/$JDK_ID/solaris-$PROC/libprofilerinterface.so \\\n\t../src-jdk15/class_file_cache.c \\\n\t../src-jdk15/attach.c \\\n\t../src-jdk15/Classes.c \\\n\t../src-jdk15/HeapDump.c \\\n\t../src-jdk15/Timers.c \\\n\t../src-jdk15/GC.c \\\n\t../src-jdk15/Threads.c \\\n\t../src-jdk15/Stacks.c \\\n\t../src-jdk15/common_functions.c\n\n\trm -f *.o\n\n}\n\nexport PROC=`uname -p`\necho PROC is $PROC\n\nif [ $PROC = \"i386\" ]; then\n  export PROC_FLAGS=\"-xregs=no%frameptr\"\nelif [ $PROC = \"sparc\" ]; then\n  export PROC_FLAGS=\"-xregs=no%appl -xmemalign=4s -xarch=v8\"\nelse\n  echo \"Invalid architecture \" $PROC\nfi\n\nBuildForJDK \"$JAVA_HOME_15\" \"jdk15\"\nBuildForJDK \"$JAVA_HOME_16\" \"jdk16\"\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-solaris64.sh",
    "content": "#!/usr/bin/bash\n\n# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nBuildForJDK()\n{\n        JAVA_HOME=$1\n        JDK_ID=$2\n        echo $JAVA_HOME $JDK_ID\n        # Use Solaris Studio 12\n\tCC_FLAGS=\"-I$JAVA_HOME/include -I$JAVA_HOME/include/solaris -DSOLARIS -G -lrt \\\n\t-xO2 -v -mt -m64 -Kpic -xc99=none -xCC -Xa -xstrconst -errwarn=%all\"\n\n\tcc $CC_FLAGS $PROC_FLAGS \\\n\t-o ../../release/lib/deployed/$JDK_ID/solaris-$PROC/libprofilerinterface.so \\\n\t../src-jdk15/class_file_cache.c \\\n\t../src-jdk15/attach.c \\\n\t../src-jdk15/Classes.c \\\n\t../src-jdk15/HeapDump.c \\\n\t../src-jdk15/Timers.c \\\n\t../src-jdk15/GC.c \\\n\t../src-jdk15/Threads.c \\\n\t../src-jdk15/Stacks.c \\\n\t../src-jdk15/common_functions.c\n\n\trm -f *.o\n}\n\nexport PROC=`uname -p`\necho PROC is $PROC\n\nif [ $PROC = \"i386\" ]; then\n  export PROC_FLAGS=\"-xregs=no%frameptr\"\n  PROC=\"amd64\"\nelif [ $PROC = \"sparc\" ]; then\n  export PROC_FLAGS=\"-xregs=no%appl\"\n  PROC=\"sparcv9\"\nelse\n  echo \"Invalid architecture \" $PROC\nfi\n\nBuildForJDK \"$JAVA_HOME_15\" \"jdk15\"\nBuildForJDK \"$JAVA_HOME_16\" \"jdk16\"\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-windows-15.bat",
    "content": "rem Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nrem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\nrem\nrem This code is free software; you can redistribute it and/or modify it\nrem under the terms of the GNU General Public License version 2 only, as\nrem published by the Free Software Foundation.  Oracle designates this\nrem particular file as subject to the \"Classpath\" exception as provided\nrem by Oracle in the LICENSE file that accompanied this code.\nrem\nrem This code is distributed in the hope that it will be useful, but WITHOUT\nrem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nrem FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nrem version 2 for more details (a copy is included in the LICENSE file that\nrem accompanied this code).\nrem\nrem You should have received a copy of the GNU General Public License version\nrem 2 along with this work; if not, write to the Free Software Foundation,\nrem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\nrem\nrem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nrem or visit www.oracle.com if you need additional information or have any\nrem questions.\n\nSET BUILD_SRC_15=..\\src-jdk15\nSET BUILD_JDK=C:\\PROGRA~1\\java\\jdk1.5.0_15\nSET BUILD_OUTPUT=%TEMP%\\dist\nSET BUILD_DEPLOY=..\\..\\release\\lib\n\nmkdir %BUILD_OUTPUT%\\deployed\\jdk15\\windows\n\ncl /I%BUILD_JDK%\\include /I%BUILD_JDK%\\include\\win32 ^\n%BUILD_SRC_15%\\class_file_cache.c ^\n%BUILD_SRC_15%\\attach.c ^\n%BUILD_SRC_15%\\Classes.c ^\n%BUILD_SRC_15%\\HeapDump.c ^\n%BUILD_SRC_15%\\Timers.c ^\n%BUILD_SRC_15%\\GC.c ^\n%BUILD_SRC_15%\\Threads.c ^\n%BUILD_SRC_15%\\Stacks.c ^\n%BUILD_SRC_15%\\common_functions.c ^\n/D WIN32 /MD /Ox /c\n\nrc /fo version.res %BUILD_SRC_15%\\windows\\version.rc\n\nlink /DLL /MAP:%BUILD_OUTPUT%\\deployed\\jdk15\\windows\\profilerinterface.map /OUT:%BUILD_OUTPUT%\\deployed\\jdk15\\windows\\profilerinterface.dll ^\nClasses.obj HeapDump.obj Timers.obj GC.obj Threads.obj Stacks.obj common_functions.obj class_file_cache.obj attach.obj version.res\n\ndel vc60.pdb\ndel *.obj *.res\ndel %BUILD_OUTPUT%\\deployed\\jdk15\\windows\\*.lib %BUILD_OUTPUT%\\deployed\\jdk15\\windows\\*.exp %BUILD_OUTPUT%\\deployed\\jdk15\\windows\\*.ilk %BUILD_OUTPUT%\\deployed\\jdk15\\windows\\*.pdb\n\ncopy %BUILD_OUTPUT%\\deployed\\jdk15\\windows\\*.dll %BUILD_DEPLOY%\\deployed\\jdk15\\windows\ncopy %BUILD_OUTPUT%\\deployed\\jdk15\\windows\\*.map %BUILD_DEPLOY%\\deployed\\jdk15\\windows\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-windows-16.bat",
    "content": "rem Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nrem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\nrem\nrem This code is free software; you can redistribute it and/or modify it\nrem under the terms of the GNU General Public License version 2 only, as\nrem published by the Free Software Foundation.  Oracle designates this\nrem particular file as subject to the \"Classpath\" exception as provided\nrem by Oracle in the LICENSE file that accompanied this code.\nrem\nrem This code is distributed in the hope that it will be useful, but WITHOUT\nrem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nrem FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nrem version 2 for more details (a copy is included in the LICENSE file that\nrem accompanied this code).\nrem\nrem You should have received a copy of the GNU General Public License version\nrem 2 along with this work; if not, write to the Free Software Foundation,\nrem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\nrem\nrem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nrem or visit www.oracle.com if you need additional information or have any\nrem questions.\n\nSET BUILD_SRC_15=..\\src-jdk15\nSET BUILD_JDK=C:\\PROGRA~1\\java\\jdk1.6.0_22\nSET BUILD_OUTPUT=%TEMP%\\dist\nSET BUILD_DEPLOY=..\\..\\release\\lib\n\nmkdir %BUILD_OUTPUT%\\deployed\\jdk16\\windows\n\ncl /I%BUILD_JDK%\\include /I%BUILD_JDK%\\include\\win32 ^\n%BUILD_SRC_15%\\class_file_cache.c ^\n%BUILD_SRC_15%\\attach.c ^\n%BUILD_SRC_15%\\Classes.c ^\n%BUILD_SRC_15%\\HeapDump.c ^\n%BUILD_SRC_15%\\Timers.c ^\n%BUILD_SRC_15%\\GC.c ^\n%BUILD_SRC_15%\\Threads.c ^\n%BUILD_SRC_15%\\Stacks.c ^\n%BUILD_SRC_15%\\common_functions.c ^\n/D WIN32 /MD /Ox /c\n\nrc /fo version.res %BUILD_SRC_15%\\windows\\version.rc\n\nlink /DLL /NXCOMPAT /DYNAMICBASE /SAFESEH /NODEFAULTLIB:MSVCR80 /LIBPATH:%CRT_LIB_PATH% /MAP:%BUILD_OUTPUT%\\deployed\\jdk16\\windows\\profilerinterface.map /OUT:%BUILD_OUTPUT%\\deployed\\jdk16\\windows\\profilerinterface.dll ^\nClasses.obj HeapDump.obj Timers.obj GC.obj Threads.obj Stacks.obj common_functions.obj class_file_cache.obj attach.obj version.res\n\ndel vc60.pdb\ndel *.obj *.res\ndel %BUILD_OUTPUT%\\deployed\\jdk16\\windows\\*.lib %BUILD_OUTPUT%\\deployed\\jdk16\\windows\\*.exp %BUILD_OUTPUT%\\deployed\\jdk16\\windows\\*.ilk %BUILD_OUTPUT%\\deployed\\jdk16\\windows\\*.pdb\n\ncopy %BUILD_OUTPUT%\\deployed\\jdk16\\windows\\*.dll %BUILD_DEPLOY%\\deployed\\jdk16\\windows\ncopy %BUILD_OUTPUT%\\deployed\\jdk16\\windows\\*.map %BUILD_DEPLOY%\\deployed\\jdk16\\windows\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-windows-cvm-arm.bat",
    "content": "rem Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nrem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\nrem\nrem This code is free software; you can redistribute it and/or modify it\nrem under the terms of the GNU General Public License version 2 only, as\nrem published by the Free Software Foundation.  Oracle designates this\nrem particular file as subject to the \"Classpath\" exception as provided\nrem by Oracle in the LICENSE file that accompanied this code.\nrem\nrem This code is distributed in the hope that it will be useful, but WITHOUT\nrem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nrem FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nrem version 2 for more details (a copy is included in the LICENSE file that\nrem accompanied this code).\nrem\nrem You should have received a copy of the GNU General Public License version\nrem 2 along with this work; if not, write to the Free Software Foundation,\nrem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\nrem\nrem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nrem or visit www.oracle.com if you need additional information or have any\nrem questions.\n\nSET BUILD_SRC_15=..\\src-jdk15\nSET BUILD_DEPLOY=..\\..\\release\\lib\nset VSROOT=c:\\Program Files\\Microsoft Visual Studio 8\nset LIB=c:\\PROGRA~1\\WIEB7A~1\\WCE500\\WINDOW~1.0PO\\LIB\\ARMV4I\nset INCLUDE=C:\\Program Files\\Windows CE Tools\\wce500\\Windows Mobile 5.0 Pocket PC SDK\\Include\\Armv4i\nset VS2005_CE_ARM_PATH=C:\\Program Files\\Microsoft Visual Studio 8\\vc\\ce\\bin\\x86_arm\nset VS2005_COMMON_PATH=C:\\Program Files\\Microsoft Visual Studio 8\\vc\\bin\nset PATH=%VS2005_CE_ARM_PATH%;%VSROOT%\\Common7\\IDE;%VSROOT%\\VC\\BIN;%VSROOT%\\Common7\\Tools;%VSROOT%\\Common7\\Tools\\bin;%VSROOT%\\VC\\PlatformSDK\\bin;%VSROOT%\\SDK\\v2.0\\bin;C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727;%VSROOT%\\VC\\VCPackages;C:\\Program Files\\java\\jdk1.5.0_08\\bin;c:\\bin;c:\\mksnt;c:\\winnt\\system32\n\nmkdir %BUILD_DEPLOY%\\deployed\\cvm\\windows-arm\n\ncl /I%CVM_HOME%/src/share/javavm/export /I%CVM_HOME%/src/share /I%CVM_HOME%/src ^\n/I%CVM_HOME%/src/win32-x86 /I%CVM_HOME%/src/win32 ^\n%BUILD_SRC_15%\\class_file_cache.c ^\n%BUILD_SRC_15%\\attach.c ^\n%BUILD_SRC_15%\\Classes.c ^\n%BUILD_SRC_15%\\Timers.c ^\n%BUILD_SRC_15%\\GC.c ^\n%BUILD_SRC_15%\\Threads.c ^\n%BUILD_SRC_15%\\Stacks.c ^\n%BUILD_SRC_15%\\common_functions.c ^\n/D_ARM_ /DWIN32 /DWINCE /DUNDER_CE=500 /D_WIN32_WCE=500 /DWIN32_LEAN_AND_MEAN /DCVM /MD /Ox /c\n\nlink /DLL /incremental:yes /base:0x00100000 /subsystem:windowsce,5.01 /nodefaultlib:oldnames.lib /nodefaultlib:libcmt.lib ^\n/nodefaultlib:libcmtd.lib /nodefaultlib:libc.lib /nodefaultlib:libcd.lib ^\n/nodefaultlib:msvcrt.lib /nodefaultlib:msvcrtd.lib coredll.lib corelibc.lib ^\n/entry:_DllMainCRTStartup ^\n/MAP:%BUILD_DEPLOY%\\deployed\\cvm\\windows-arm\\profilerinterface.map ^\n/OUT:%BUILD_DEPLOY%\\deployed\\cvm\\windows-arm\\profilerinterface.dll ^\nClasses.obj Timers.obj GC.obj Threads.obj Stacks.obj common_functions.obj class_file_cache.obj attach.obj\n\n\ncl /I%CVM_HOME%/src/share/javavm/export /I%CVM_HOME%/src/share /I%CVM_HOME%/src ^\n/I%CVM_HOME%/src/win32-x86 /I%CVM_HOME%/src/win32 ^\n%BUILD_SRC_15%\\class_file_cache.c ^\n%BUILD_SRC_15%\\attach.c ^\n%BUILD_SRC_15%\\Classes.c ^\n%BUILD_SRC_15%\\Timers.c ^\n%BUILD_SRC_15%\\GC.c ^\n%BUILD_SRC_15%\\Threads.c ^\n%BUILD_SRC_15%\\Stacks.c ^\n%BUILD_SRC_15%\\common_functions.c ^\n/D_ARM_ /DWIN32 /DWINCE /DUNDER_CE=500 /D_WIN32_WCE=500 /DWIN32_LEAN_AND_MEAN /DCVM /MDd /Od /Zi /c \n\nlink /DLL /DEBUG /incremental:yes /base:0x00100000 /subsystem:windowsce,5.01 /nodefaultlib:oldnames.lib /nodefaultlib:libcmt.lib ^\n/nodefaultlib:libcmtd.lib /nodefaultlib:libc.lib /nodefaultlib:libcd.lib ^\n/nodefaultlib:msvcrt.lib /nodefaultlib:msvcrtd.lib coredll.lib corelibc.lib ^\n/entry:_DllMainCRTStartup ^\n/MAP:%BUILD_DEPLOY%\\deployed\\cvm\\windows-arm\\profilerinterface_g.map ^\n/OUT:%BUILD_DEPLOY%\\deployed\\cvm\\windows-arm\\profilerinterface_g.dll ^\nClasses.obj Timers.obj GC.obj Threads.obj Stacks.obj common_functions.obj class_file_cache.obj attach.obj\n\ndel *.obj\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-windows-cvm.bat",
    "content": "rem Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nrem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\nrem\nrem This code is free software; you can redistribute it and/or modify it\nrem under the terms of the GNU General Public License version 2 only, as\nrem published by the Free Software Foundation.  Oracle designates this\nrem particular file as subject to the \"Classpath\" exception as provided\nrem by Oracle in the LICENSE file that accompanied this code.\nrem\nrem This code is distributed in the hope that it will be useful, but WITHOUT\nrem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nrem FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nrem version 2 for more details (a copy is included in the LICENSE file that\nrem accompanied this code).\nrem\nrem You should have received a copy of the GNU General Public License version\nrem 2 along with this work; if not, write to the Free Software Foundation,\nrem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\nrem\nrem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nrem or visit www.oracle.com if you need additional information or have any\nrem questions.\n\nSET BUILD_SRC_15=..\\src-jdk15\nSET BUILD_OUTPUT=dist\nSET BUILD_DEPLOY=..\\..\\release\\lib\n\nset VS2005_COMMON_PATH=C:\\Program Files\\Microsoft Visual Studio 8\\vc\\bin\n\ncall \"%VS2005_COMMON_PATH%\\vcvars32\"\n\nmkdir %BUILD_OUTPUT%\\deployed\\cvm\\windows\n\ncl /I%CVM_HOME%/src/share/javavm/export /I%CVM_HOME%/src/share /I%CVM_HOME%/src ^\n/I%CVM_HOME%/src/win32-x86 /I%CVM_HOME%/src/win32 ^\n%BUILD_SRC_15%\\class_file_cache.c ^\n%BUILD_SRC_15%\\attach.c ^\n%BUILD_SRC_15%\\Classes.c ^\n%BUILD_SRC_15%\\Timers.c ^\n%BUILD_SRC_15%\\GC.c ^\n%BUILD_SRC_15%\\Threads.c ^\n%BUILD_SRC_15%\\Stacks.c ^\n%BUILD_SRC_15%\\common_functions.c ^\n/D WIN32 /D CVM /MD /Ox /c\n\nlink /DLL /MAP:%BUILD_OUTPUT%\\deployed\\cvm\\windows\\profilerinterface.map /OUT:%BUILD_OUTPUT%\\deployed\\cvm\\windows\\profilerinterface.dll ^\nClasses.obj Timers.obj GC.obj Threads.obj Stacks.obj common_functions.obj class_file_cache.obj attach.obj\nmt.exe -nologo -manifest %BUILD_OUTPUT%\\deployed\\cvm\\windows\\profilerinterface.dll.manifest -outputresource:%BUILD_OUTPUT%\\deployed\\cvm\\windows\\profilerinterface.dll;#2\n\ncl /I%CVM_HOME%/src/share/javavm/export /I%CVM_HOME%/src/share /I%CVM_HOME%/src ^\n/I%CVM_HOME%/src/win32-x86 /I%CVM_HOME%/src/win32 ^\n%BUILD_SRC_15%\\class_file_cache.c ^\n%BUILD_SRC_15%\\attach.c ^\n%BUILD_SRC_15%\\Classes.c ^\n%BUILD_SRC_15%\\Timers.c ^\n%BUILD_SRC_15%\\GC.c ^\n%BUILD_SRC_15%\\Threads.c ^\n%BUILD_SRC_15%\\Stacks.c ^\n%BUILD_SRC_15%\\common_functions.c ^\n/D WIN32 /D CVM /MDd /Zi /c\n\nlink /DLL /DEBUG /MAP:%BUILD_OUTPUT%\\deployed\\cvm\\windows\\profilerinterface_g.map /OUT:%BUILD_OUTPUT%\\deployed\\cvm\\windows\\profilerinterface_g.dll ^\nClasses.obj Timers.obj GC.obj Threads.obj Stacks.obj common_functions.obj class_file_cache.obj attach.obj\nmt.exe -nologo -manifest %BUILD_OUTPUT%\\deployed\\cvm\\windows\\profilerinterface_g.dll.manifest -outputresource:%BUILD_OUTPUT%\\deployed\\cvm\\windows\\profilerinterface_g.dll;#2\n\ndel vc60.pdb\ndel *.obj\ndel %BUILD_OUTPUT%\\deployed\\cvm\\windows\\*.lib %BUILD_OUTPUT%\\deployed\\cvm\\windows\\*.exp %BUILD_OUTPUT%\\deployed\\cvm\\windows\\*.ilk %BUILD_OUTPUT%\\deployed\\cvm\\windows\\*.pdb\n\ncopy %BUILD_OUTPUT%\\deployed\\cvm\\windows\\*.dll %BUILD_DEPLOY%\\deployed\\cvm\\windows\ncopy %BUILD_OUTPUT%\\deployed\\cvm\\windows\\*.map %BUILD_DEPLOY%\\deployed\\cvm\\windows\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-windows64-15.bat",
    "content": "rem Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nrem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\nrem\nrem This code is free software; you can redistribute it and/or modify it\nrem under the terms of the GNU General Public License version 2 only, as\nrem published by the Free Software Foundation.  Oracle designates this\nrem particular file as subject to the \"Classpath\" exception as provided\nrem by Oracle in the LICENSE file that accompanied this code.\nrem\nrem This code is distributed in the hope that it will be useful, but WITHOUT\nrem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nrem FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nrem version 2 for more details (a copy is included in the LICENSE file that\nrem accompanied this code).\nrem\nrem You should have received a copy of the GNU General Public License version\nrem 2 along with this work; if not, write to the Free Software Foundation,\nrem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\nrem\nrem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nrem or visit www.oracle.com if you need additional information or have any\nrem questions.\n\nSET BUILD_SRC_15=..\\src-jdk15\nSET BUILD_SRC=..\\src\nSET BUILD_JDK=C:\\PROGRA~1\\java\\jdk1.5.0_15\nSET BUILD_OUTPUT=%TEMP%\\dist\nSET BUILD_DEPLOY=..\\..\\release\\lib\n\nmkdir %BUILD_OUTPUT%\\deployed\\jdk15\\windows-amd64\n\ncl /I%BUILD_JDK%\\include /I%BUILD_JDK%\\include\\win32 ^\n%BUILD_SRC_15%\\class_file_cache.c ^\n%BUILD_SRC_15%\\attach.c ^\n%BUILD_SRC_15%\\Classes.c ^\n%BUILD_SRC_15%\\HeapDump.c ^\n%BUILD_SRC_15%\\Timers.c ^\n%BUILD_SRC_15%\\GC.c ^\n%BUILD_SRC_15%\\Threads.c ^\n%BUILD_SRC_15%\\Stacks.c ^\n%BUILD_SRC_15%\\common_functions.c ^\n/D WIN32 /MD /Ox /c\n\nrc /fo version.res %BUILD_SRC_15%\\windows\\version.rc\n\nlink /DLL /MAP:%BUILD_OUTPUT%\\deployed\\jdk15\\windows-amd64\\profilerinterface.map /OUT:%BUILD_OUTPUT%\\deployed\\jdk15\\windows-amd64\\profilerinterface.dll ^\nClasses.obj HeapDump.obj Timers.obj GC.obj Threads.obj Stacks.obj common_functions.obj class_file_cache.obj attach.obj version.res\n\ndel vc60.pdb\ndel *.obj *.res\ndel %BUILD_OUTPUT%\\deployed\\jdk15\\windows-amd64\\*.lib %BUILD_OUTPUT%\\deployed\\jdk15\\windows-amd64\\*.exp %BUILD_OUTPUT%\\deployed\\jdk15\\windows-amd64\\*.ilk %BUILD_OUTPUT%\\deployed\\jdk15\\windows-amd64\\*.pdb\n\ncopy %BUILD_OUTPUT%\\deployed\\jdk15\\windows-amd64\\*.dll %BUILD_DEPLOY%\\deployed\\jdk15\\windows-amd64\ncopy %BUILD_OUTPUT%\\deployed\\jdk15\\windows-amd64\\*.map %BUILD_DEPLOY%\\deployed\\jdk15\\windows-amd64\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/buildnative-windows64-16.bat",
    "content": "rem Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nrem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\nrem\nrem This code is free software; you can redistribute it and/or modify it\nrem under the terms of the GNU General Public License version 2 only, as\nrem published by the Free Software Foundation.  Oracle designates this\nrem particular file as subject to the \"Classpath\" exception as provided\nrem by Oracle in the LICENSE file that accompanied this code.\nrem\nrem This code is distributed in the hope that it will be useful, but WITHOUT\nrem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nrem FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nrem version 2 for more details (a copy is included in the LICENSE file that\nrem accompanied this code).\nrem\nrem You should have received a copy of the GNU General Public License version\nrem 2 along with this work; if not, write to the Free Software Foundation,\nrem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\nrem\nrem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nrem or visit www.oracle.com if you need additional information or have any\nrem questions.\n\nSET BUILD_SRC_15=..\\src-jdk15\nSET BUILD_SRC=..\\src\nSET BUILD_JDK=C:\\PROGRA~1\\java\\jdk1.6.0_22\nSET BUILD_OUTPUT=%TEMP%\\dist\nSET BUILD_DEPLOY=..\\..\\release\\lib\n\nmkdir %BUILD_OUTPUT%\\deployed\\jdk16\\windows-amd64\n\ncl /I%BUILD_JDK%\\include /I%BUILD_JDK%\\include\\win32 ^\n%BUILD_SRC_15%\\class_file_cache.c ^\n%BUILD_SRC_15%\\attach.c ^\n%BUILD_SRC_15%\\Classes.c ^\n%BUILD_SRC_15%\\HeapDump.c ^\n%BUILD_SRC_15%\\Timers.c ^\n%BUILD_SRC_15%\\GC.c ^\n%BUILD_SRC_15%\\Threads.c ^\n%BUILD_SRC_15%\\Stacks.c ^\n%BUILD_SRC_15%\\common_functions.c ^\n/D WIN32 /MD /Ox /c\n\nrc /fo version.res %BUILD_SRC_15%\\windows\\version.rc\n\nlink /DLL /NXCOMPAT /DYNAMICBASE /NODEFAULTLIB:MSVCR80 /LIBPATH:%CRT64_LIB_PATH% /MAP:%BUILD_OUTPUT%\\deployed\\jdk16\\windows-amd64\\profilerinterface.map /OUT:%BUILD_OUTPUT%\\deployed\\jdk16\\windows-amd64\\profilerinterface.dll ^\nClasses.obj HeapDump.obj Timers.obj GC.obj Threads.obj Stacks.obj common_functions.obj class_file_cache.obj attach.obj version.res\n\ndel vc60.pdb\ndel *.obj *.res\ndel %BUILD_OUTPUT%\\deployed\\jdk16\\windows-amd64\\*.lib %BUILD_OUTPUT%\\deployed\\jdk16\\windows-amd64\\*.exp %BUILD_OUTPUT%\\deployed\\jdk16\\windows-amd64\\*.ilk %BUILD_OUTPUT%\\deployed\\jdk16\\windows-amd64\\*.pdb\n\ncopy %BUILD_OUTPUT%\\deployed\\jdk16\\windows-amd64\\*.dll %BUILD_DEPLOY%\\deployed\\jdk16\\windows-amd64\ncopy %BUILD_OUTPUT%\\deployed\\jdk16\\windows-amd64\\*.map %BUILD_DEPLOY%\\deployed\\jdk16\\windows-amd64\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/build/generate-headers-15.bat",
    "content": "rem Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nrem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\nrem\nrem This code is free software; you can redistribute it and/or modify it\nrem under the terms of the GNU General Public License version 2 only, as\nrem published by the Free Software Foundation.  Oracle designates this\nrem particular file as subject to the \"Classpath\" exception as provided\nrem by Oracle in the LICENSE file that accompanied this code.\nrem\nrem This code is distributed in the hope that it will be useful, but WITHOUT\nrem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nrem FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nrem version 2 for more details (a copy is included in the LICENSE file that\nrem accompanied this code).\nrem\nrem You should have received a copy of the GNU General Public License version\nrem 2 along with this work; if not, write to the Free Software Foundation,\nrem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\nrem\nrem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nrem or visit www.oracle.com if you need additional information or have any\nrem questions.\n\nrem A script to generate JNI *.h files for classes that contain native methods\n\nSET BUILD_SRC_15=..\\src-jdk15\nSET BUILD_JDK=C:\\PROGRA~1\\java\\jdk1.5.0_10\n\n%BUILD_JDK%\\bin\\javah -d %BUILD_SRC_15% -classpath ..\\..\\src;..\\..\\src-jdk15 org.graalvm.visualvm.lib.jfluid.server.system.Classes org.graalvm.visualvm.lib.jfluid.server.system.HeapDump org.graalvm.visualvm.lib.jfluid.server.system.GC org.graalvm.visualvm.lib.jfluid.server.system.Timers org.graalvm.visualvm.lib.jfluid.server.system.Stacks org.graalvm.visualvm.lib.jfluid.server.system.Threads\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/Classes.c",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/*\n * author Tomas Hurka\n *        Ian Formanek\n *        Misha Dmitriev\n */\n\n#ifdef WIN32\n#include <Windows.h>\n#else\n#include <sys/time.h>\n#include <fcntl.h>\n#include <time.h>\n#endif\n\n#ifdef SOLARIS\n#define _STRUCTURED_PROC 1\n#include <sys/procfs.h>\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <assert.h>\n#include <string.h>\n\n#include \"jni.h\"\n#include \"jvmti.h\"\n\n#include \"org_graalvm_visualvm_lib_jfluid_server_system_Classes.h\"\n\n#include \"common_functions.h\"\n\n#ifndef TRUE\n#define TRUE 1\n#endif\n\n#ifndef FALSE\n#define FALSE 0\n#endif\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    getAllLoadedClasses\n * Signature: ()[Ljava/lang/Class;\n */\nJNIEXPORT jobjectArray JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_getAllLoadedClasses\n    (JNIEnv *env, jclass clz)\n{\n    jvmtiError res;\n    jint classCount, classStatus;\n    jclass *classes;\n    jobjectArray ret;\n    jclass type;\n    int i, j, n_linked_classes;\n    char *class_status;\n\n    res = (*_jvmti)->GetLoadedClasses(_jvmti, &classCount, &classes);\n    assert(res == JVMTI_ERROR_NONE);\n\n    n_linked_classes = 0;\n    class_status = malloc(classCount);\n    for (i = 0; i < classCount; i++) {\n        (*_jvmti)->GetClassStatus(_jvmti, classes[i], &classStatus);\n        if ((classStatus & JVMTI_CLASS_STATUS_PREPARED) != 0 && (classStatus & JVMTI_CLASS_STATUS_ERROR) == 0) {\t\n            class_status[i] = 1;\n            n_linked_classes++;\n        } else {\n            class_status[i] = 0;\n        }\n    }\n\n    type = (*env)->FindClass(env, \"java/lang/Class\");\n    assert(type != NULL);\n    ret = (*env)->NewObjectArray(env, n_linked_classes, type, NULL);\n    if (ret != NULL) {\n        j = 0;\n        for (i = 0; i < classCount; i++) {\n            if (class_status[i]) {\n                (*env)->SetObjectArrayElement(env, ret, j++, classes[i]);\n            }\n        }\n    }\n    free(class_status);\n    res = (*_jvmti)->Deallocate(_jvmti, (unsigned char*) classes);\n    assert(res == JVMTI_ERROR_NONE);\n  \n    return ret;\n}\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    cacheLoadedClasses\n * Signature: ([Ljava/lang/Class;I)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_cacheLoadedClasses\n  (JNIEnv *env, jclass clz, jobjectArray non_system_classes, jint class_count)\n{\n    jclass *classDefs = calloc(class_count,sizeof(jclass));\n    int i;\n    \n    for (i = 0; i < class_count; i++) {\n        classDefs[i] = (*env)->GetObjectArrayElement(env, non_system_classes, i);\n    }\n    cache_loaded_classes(_jvmti,classDefs,class_count);\n    free(classDefs);\n}\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    getCachedClassFileBytes\n * Signature: (Ljava/lang/Class;)[B\n */\nJNIEXPORT jbyteArray JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_getCachedClassFileBytes\n    (JNIEnv *env, jclass clz, jclass clazz) \n{\n    char *class_sig, *class_gen_sig;\n    jobject loader;\n    unsigned char *class_data;\n    int class_data_len;\n    jbyteArray ret;\n    jvmtiError res;\n  \n    res = (*_jvmti)->GetClassSignature(_jvmti, clazz, &class_sig, &class_gen_sig);\n    assert(res == JVMTI_ERROR_NONE);\n    res = (*_jvmti)->GetClassLoader(_jvmti, clazz, &loader);\n    assert(res == JVMTI_ERROR_NONE);\n  \n    /* class_sig is gonna look something like Lfoo/Bar; Convert it back into normal */\n    class_sig[strlen(class_sig) - 1] = 0;\n    get_saved_class_file_bytes(env, class_sig+1, loader, (jint*)&class_data_len, &class_data);\n  \n    (*_jvmti)->Deallocate(_jvmti, (void*) class_sig);\n    (*_jvmti)->Deallocate(_jvmti, (void*) class_gen_sig);\n  \n    if (class_data == NULL) {\n        return NULL;\n    }\n    \n    ret = (*env)->NewByteArray(env, class_data_len);\n    (*env)->SetByteArrayRegion(env, ret, 0, class_data_len, (jbyte*) class_data);\n    free(class_data);\n    return ret;\n}\n\n\nstatic jclass profilerInterfaceClazz;\nstatic jmethodID classLoadHookMethod = NULL;\n\nvoid JNICALL register_class_prepare(jvmtiEnv *jvmti_env, JNIEnv* env, jthread thread, jclass clazz) {\n    (*env)->CallStaticVoidMethod(env, profilerInterfaceClazz, classLoadHookMethod, clazz);\n    if ((*env)->ExceptionCheck(env)) {\n        (*env)->ExceptionDescribe(env);\n    }\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    enableClassLoadHook\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_enableClassLoadHook\n    (JNIEnv *env, jclass clz) \n{\n    jvmtiError res;\n  \n    if (classLoadHookMethod == NULL) {\n        profilerInterfaceClazz = (*env)->FindClass(env, \"org/graalvm/visualvm/lib/jfluid/server/ProfilerInterface\");\n        profilerInterfaceClazz = (*env)->NewGlobalRef(env, profilerInterfaceClazz);\n        classLoadHookMethod = (*env)->GetStaticMethodID(env, profilerInterfaceClazz, \"classLoadHook\", \"(Ljava/lang/Class;)V\");\n        _jvmti_callbacks->ClassPrepare = register_class_prepare;\n        res = (*_jvmti)->SetEventCallbacks(_jvmti, _jvmti_callbacks, sizeof(*_jvmti_callbacks));\n        assert (res == JVMTI_ERROR_NONE);\n    }\n  \n    res = (*_jvmti)->SetEventNotificationMode(_jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL);\n    assert(res == JVMTI_ERROR_NONE);\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    disableClassLoadHook\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_disableClassLoadHook\n    (JNIEnv *env, jclass clz) \n{\n    jvmtiError res;\n  \n    res = (*_jvmti)->SetEventNotificationMode(_jvmti, JVMTI_DISABLE, JVMTI_EVENT_CLASS_PREPARE, NULL);\n    assert(res == JVMTI_ERROR_NONE);\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    getObjectSize\n * Signature: (Ljava/lang/Object;)J\n */\nJNIEXPORT jlong JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_getObjectSize\n    (JNIEnv *env, jclass clz, jobject jobject) \n{\n    jlong res;\n  \n    (*_jvmti)->GetObjectSize(_jvmti, jobject, &res);\n    return res;\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    doRedefineClasses\n * Signature: ([Ljava/lang/Class;[[B)I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_doRedefineClasses\n    (JNIEnv *env, jclass clz, jobjectArray jclasses, jobjectArray jnewClassFileBytes) \n{\n    static jboolean nativeMethodBindDisabled = FALSE;\n  \n    jvmtiError res = JVMTI_ERROR_NONE;\n    jint nClasses, i;\n    jvmtiClassDefinition* classDefs;\n  \n    if (!nativeMethodBindDisabled) {\n        // First, disable the NativeMethodBind event, assume that Thread.sleep and Object.wait have already been intercepted\n        res = (*_jvmti)->SetEventNotificationMode(_jvmti, JVMTI_DISABLE, JVMTI_EVENT_NATIVE_METHOD_BIND, NULL);\n        if (res != JVMTI_ERROR_NONE) {\n            fprintf (stderr, \"Profiler Agent Error: Error while turning NativeMethodBind off: %d\\n\",res);\n            assert(res == JVMTI_ERROR_NONE);\n        }\n        nativeMethodBindDisabled = TRUE;\n    }\n  \n    nClasses = (*env)->GetArrayLength(env, jclasses);\n    classDefs = malloc(sizeof(jvmtiClassDefinition) * nClasses);\n    for (i = 0; i < nClasses; i++) {\n        jbyteArray jnewClassBytes;\n        jbyte *tmpClassBytes;\n        jint classBytesLen;\n      \n        jvmtiClassDefinition *classDef = classDefs + i;\n        classDef->klass = (*env)->GetObjectArrayElement(env, jclasses, i);\n        jnewClassBytes = (*env)->GetObjectArrayElement(env, jnewClassFileBytes, i);\n        classBytesLen = classDef->class_byte_count = (*env)->GetArrayLength(env, jnewClassBytes);\n        assert(classBytesLen > 0);\n      \n        tmpClassBytes = (*env)->GetByteArrayElements(env, jnewClassBytes, NULL);\n        classDef->class_bytes = malloc(classBytesLen);\n        memcpy((jbyte*) classDef->class_bytes, tmpClassBytes, classBytesLen);\n      \n        (*env)->ReleaseByteArrayElements(env, jnewClassBytes, tmpClassBytes, JNI_ABORT);\n        (*env)->DeleteLocalRef(env, jnewClassBytes);\n    }\n  \n    if (nClasses <= 100) {\n        res = (*_jvmti)->RedefineClasses(_jvmti, nClasses, classDefs);\n    } else {\n        // perform batch redefine in units of 100 classes\n        int idx = 0;\n        while (idx < nClasses) {\n            int redefineCount = nClasses - idx;\n            if (redefineCount > 100) {\n                redefineCount = 100;\n            }\n            fprintf (stdout, \"Profiler Agent: Redefining %d classes at idx %d, out of total %d \\n\",redefineCount, idx, (int)nClasses);\n            res = (*_jvmti)->RedefineClasses(_jvmti, redefineCount, classDefs + idx);\n            idx += 100;\n        }\n    }\n  \n    for (i = 0; i < nClasses; i++) {\n        (*env)->DeleteLocalRef(env, classDefs[i].klass);\n        free((jbyte*) classDefs[i].class_bytes);\n    }\n    free(classDefs);\n  \n    return res;\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    notifyAboutClassLoaderUnloading\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_notifyAboutClassLoaderUnloading\n  (JNIEnv *env, jclass clz) \n{\n    try_removing_bytes_for_unloaded_classes(env);\n}\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/GC.c",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/*\n * author Tomas Hurka\n *        Ian Formanek\n *        Misha Dmitriev\n */\n\n#ifdef WIN32\n#include <Windows.h>\n#else\n#include <sys/time.h>\n#include <fcntl.h>\n#include <time.h>\n#endif\n\n#ifdef SOLARIS\n#define _STRUCTURED_PROC 1\n#include <sys/procfs.h>\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <assert.h>\n#include <string.h>\n\n#include \"jni.h\"\n#include \"jvmti.h\"\n\n#include \"org_graalvm_visualvm_lib_jfluid_server_system_GC.h\"\n\n#include \"common_functions.h\"\n\n#define OBSERVED_PERIODS   10  /* must match OBSERVED_PERIODS in GC.java */\n#define OBJECT_INT_SIZE 2\n#define OBJECT_SIZE (sizeof(void *)*OBJECT_INT_SIZE)\n\nstatic int gc_epoch_counter, start_index, end_index;\nstatic jlong gc_start_timestamp, gc_finish_timestamp;\nstatic jlong *run_times, *gc_times, *start_times,*finish_times;\n\n\nvoid JNICALL register_gc_start(jvmtiEnv *jvmti_env) {\n    jlong new_timestamp = get_nano_time();\n    memmove(run_times, run_times + 1, (OBSERVED_PERIODS - 1) * sizeof(jlong));\n    run_times[OBSERVED_PERIODS - 1] = (new_timestamp - gc_finish_timestamp);\n    start_times[start_index] = new_timestamp;\n    start_index = (start_index+1) % OBSERVED_PERIODS;\n    gc_start_timestamp = new_timestamp;\n}\n\n\nvoid JNICALL register_gc_finish(jvmtiEnv *jvmti_env) {\n    jlong new_timestamp = get_nano_time();\n    memmove(gc_times, gc_times + 1, (OBSERVED_PERIODS - 1) * sizeof(jlong));\n    gc_times[OBSERVED_PERIODS - 1] = (new_timestamp - gc_start_timestamp);\n    finish_times[end_index] = new_timestamp;\n    end_index = (end_index+1) % OBSERVED_PERIODS;\n    gc_finish_timestamp = new_timestamp;\n    gc_epoch_counter++;\n}\n\n\nvoid enable_gc_start_finish_hook(JNIEnv *env, jboolean enable) {\n    jvmtiError res;\n    jvmtiEventMode mode;\n\n    if (enable) {\n        _jvmti_callbacks->GarbageCollectionStart = register_gc_start;\n        _jvmti_callbacks->GarbageCollectionFinish = register_gc_finish;\n        res = (*_jvmti)->SetEventCallbacks(_jvmti, _jvmti_callbacks, sizeof(*_jvmti_callbacks));\n        assert(res == JVMTI_ERROR_NONE);\n        mode = JVMTI_ENABLE;\n    } else {\n        mode = JVMTI_DISABLE;\n    }\n  \n    res = (*_jvmti)->SetEventNotificationMode(_jvmti, mode, JVMTI_EVENT_GARBAGE_COLLECTION_START, NULL);\n    assert(res == JVMTI_ERROR_NONE);\n    res = (*_jvmti)->SetEventNotificationMode(_jvmti, mode, JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, NULL);\n    assert(res == JVMTI_ERROR_NONE);\n}\n\n\n/*\n * Class:     profiler_server_system_GC\n * Method:    activateGCEpochCounter\n * Signature: (Z)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_activateGCEpochCounter\n  (JNIEnv *env, jclass clz, jboolean activate) \n{  \n    enable_gc_start_finish_hook(env, activate);\n    gc_epoch_counter = 0;\n  \n    run_times = (jlong*) calloc(OBSERVED_PERIODS, sizeof(jlong));\n    gc_times = (jlong*) calloc(OBSERVED_PERIODS, sizeof(jlong));\n    start_times = (jlong*) calloc(OBSERVED_PERIODS, sizeof(jlong));\n    finish_times = (jlong*) calloc(OBSERVED_PERIODS, sizeof(jlong));\n  \n    gc_finish_timestamp = get_nano_time();  /* We know this doesn't happen during GC */\n}\n\n\n/*\n * Class:     profiler_server_system_GC\n * Method:    resetGCEpochCounter\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_resetGCEpochCounter\n    (JNIEnv *env, jclass clz) \n{\n    gc_epoch_counter = 0;\n}\n\n\n/*\n * Class:     profiler_server_system_GC\n * Method:    getCurrentGCEpoch\n * Signature: ()I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_getCurrentGCEpoch\n    (JNIEnv *env, jclass clz) \n{\n    return gc_epoch_counter;\n}\n\n\n/*\n * Class:     profiler_server_system_GC\n * Method:    objectsAdjacent\n * Signature: (Ljava/lang/Object;Ljava/lang/Object;)Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_objectsAdjacent\n    (JNIEnv *env, jclass clz, jobject jobj1, jobject jobj2) \n{\n    /* Warning: this assumes the HotSpot VM and its current object handle format */\n    char* obj1 = jobj1 == NULL ? (char*) NULL : *((char**)(jobj1));\n    char* obj2 = jobj2 == NULL ? (char*) NULL : *((char**)(jobj2));\n    int diff = obj2 - obj1;\n    return (diff == OBJECT_SIZE) || (diff == -OBJECT_SIZE);\n}\n\n\n/*\n * Class:     profiler_server_system_GC\n * Method:    getGCRelativeTimeMetrics\n * Signature: ([J)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_getGCRelativeTimeMetrics\n  (JNIEnv *env, jclass clz, jlongArray metrics) \n{\n    int i;\n    jlong total_gc_time = 0, total_run_time = 0;\n    jlong gc_pause_rel_time, last_gc_pause_in_micro;\n  \n    for (i = 0; i < OBSERVED_PERIODS; i++) {\n        total_gc_time += gc_times[i];\n    }\n    \n    for (i = 0; i < OBSERVED_PERIODS; i++) {\n        total_run_time += run_times[i];\n    }\n    \n    /* We know this doesn't happen during GC, so we can calculate real run time */\n    total_run_time += (get_nano_time() - gc_finish_timestamp);\n  \n    if (total_run_time == 0) {\n        gc_pause_rel_time = 0;\n    } else {\n        gc_pause_rel_time = (jlong) (((float) total_gc_time) / ((float) (total_gc_time + total_run_time)) * 1000);\n    }\n    last_gc_pause_in_micro = gc_times[OBSERVED_PERIODS - 1] * 1000000 / 1000000000;\n  \n    (*env)->SetLongArrayRegion(env, metrics, 0, 1, &gc_pause_rel_time);\n    (*env)->SetLongArrayRegion(env, metrics, 1, 1, &last_gc_pause_in_micro);\n}\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_GC\n * Method:    getGCStartFinishTimes\n * Signature: ([J[J)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_getGCStartFinishTimes\n  (JNIEnv *env, jclass clz, jlongArray start, jlongArray finish)\n{\n    (*env)->SetLongArrayRegion(env, start, 0, OBSERVED_PERIODS, start_times);\n    (*env)->SetLongArrayRegion(env, finish, 0, OBSERVED_PERIODS, finish_times);\n}\n\n/*\n * Class:     profiler_server_system_GC\n * Method:    runGC\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_runGC\n  (JNIEnv *env, jclass clz) \n{\n    (*_jvmti)->ForceGarbageCollection(_jvmti);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/HeapDump.c",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/*\n * author Tomas Hurka\n */\n\n#ifdef WIN32\n#include <Windows.h>\n#else\n#define _GNU_SOURCE\n#include <dlfcn.h>\n#endif\n#include <stdio.h>\n#include \"jni.h\"\n#include \"jvmti.h\"\n\n#include \"org_graalvm_visualvm_lib_jfluid_server_system_HeapDump.h\"\n\n\njint (JNICALL *JVM_DumpHeap15)(JNIEnv* env, jstring outputfile, jboolean live);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_HeapDump\n * Method:    initialize15\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_HeapDump_initialize15\n  (JNIEnv *env, jclass clz) {\n#ifdef WIN32\n  /* Get the address of JVM_DumpHeap function */\n   HMODULE hModule = GetModuleHandle(\"jvm.dll\");\n  if (hModule == NULL) {\n    fprintf(stderr, \"Profiler Agent Error: Unable to get handle to jvm.dll\\n\");\n    return ; /* Unable to get handle to jvm.dll */\n  }\n  JVM_DumpHeap15 = (jint (JNICALL *)(JNIEnv*,jstring,jboolean)) GetProcAddress(hModule, \"JVM_DumpHeap\");\n  if (JVM_DumpHeap15 == NULL) {\n    fprintf(stderr, \"Profiler Agent Error: Unable to get address of JVM_DumpHeap function\\n\");\n    return; /* Unable to get address of JVM_DumpHeap function */\n  }\n#else\n  JVM_DumpHeap15 = (jint (JNICALL *)(JNIEnv*,jstring,jboolean)) dlsym(RTLD_DEFAULT, \"JVM_DumpHeap\");\n  if (JVM_DumpHeap15 == NULL)  {\n    //fprintf (stderr, \"Profiler Agent: %s\\n\", dlerror());\n    return;\n  }\n#endif\n\n  //fprintf(stderr, \"Profiler Agent: JVM_DumpHeap %p\\n\",JVM_DumpHeap15);\n}\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_HeapDump\n * Method:    takeHeapDump15Native\n * Signature: (Ljava/lang/String;)I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_HeapDump_takeHeapDump15Native\n(JNIEnv *env, jclass clz, jstring outputfile) {\n  jint error = -1;\n\n  if (JVM_DumpHeap15 != NULL) {\n    fprintf(stdout,\"Profiler Agent: Heap dump..\");\n    error = (*JVM_DumpHeap15)(env,outputfile,JNI_TRUE);\n    fprintf(stdout,\" end, status %d\\n\",(int)error);\n  }\n  return error;\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/Stacks.c",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/*\n * author Tomas Hurka\n *        Ian Formanek\n *        Misha Dmitriev\n */\n\n#ifdef WIN32\n#include <Windows.h>\n#else\n#include <sys/time.h>\n#include <fcntl.h>\n#include <time.h>\n#endif\n\n#ifdef SOLARIS\n#define _STRUCTURED_PROC 1\n#include <sys/procfs.h>\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <assert.h>\n#include <string.h>\n\n#include \"jni.h\"\n#include \"jvmti.h\"\n\n#include \"org_graalvm_visualvm_lib_jfluid_server_system_Stacks.h\"\n\n#include \"common_functions.h\"\n#include \"Threads.h\"\n\n#define NEEDS_CONVERSION (sizeof(jmethodID)!=sizeof(jint))\n#define NO_OF_BASE_BITS 2\n#define NO_OF_MASK_BITS (32-NO_OF_BASE_BITS)\n#define NO_OF_BASE_ADDRESS (1<<NO_OF_BASE_BITS)\n#define OFFSET_MASK ((1LL<<NO_OF_MASK_BITS)-1)\n#define BASE_ADDRESS_MASK (~OFFSET_MASK)\n\n#define MAX_FRAMES 16384\n\n#define PACKEDARR_ITEMS 4\n\nstatic jvmtiFrameInfo *_stack_frames_buffer = NULL;\nstatic jint *_stack_id_buffer = NULL;\nstatic jclass threadType = NULL;\nstatic jclass intArrType = NULL;\nstatic long long base_addresses[NO_OF_BASE_ADDRESS]={-1LL,-1LL,-1LL,-1LL};\n\nstatic jint convert_jmethodID_to_jint(jmethodID jmethod) {\n    if (NEEDS_CONVERSION) {\n        long long base_address=(long long)jmethod&BASE_ADDRESS_MASK;\n        unsigned int i;\n\n        for (i=0;i<NO_OF_BASE_ADDRESS;i++) {\n            if (base_addresses[i] == -1LL) {\n                base_addresses[i] = base_address;\n                //fprintf(stderr,\"Profiler Agent: Registering new base %llx\\n\",base_address);\n            }\n            if (base_addresses[i]==base_address) {\n                jint offset = (long long)jmethod&OFFSET_MASK;\n                offset |= i<<NO_OF_MASK_BITS;\n                //fprintf(stderr,\"M %p -> %x\\n\",jmethod,offset);\n                return offset;\n            }\n        }\n        fprintf(stderr,\"Profiler Agent Warning: Cannot convert %p\\n\",jmethod);\n        return 0;\n    } else {\n        return (jint)jmethod;\n    }\n}\n\nstatic jmethodID convert_jint_to_jmethodID(jint method) {\n    if (NEEDS_CONVERSION) {\n        int offset = method&OFFSET_MASK;\n        int base_id = ((unsigned int)method)>>NO_OF_MASK_BITS;\n        jmethodID jmethod = (jmethodID)(base_addresses[base_id]|offset);\n\n        //fprintf(stderr,\"X %x -> %p\\n\",method,jmethod);\n        //fflush(stderr);\n        return jmethod;\n    } else {\n        return (jmethodID)method;\n    }\n}\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n * Method:    getCurrentJavaStackDepth\n * Signature: (Ljava/lang/Thread;)I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Stacks_getCurrentJavaStackDepth\n    (JNIEnv *env, jclass clz, jobject jni_thread)\n{\n    jint count;\n\n    (*_jvmti)->GetFrameCount(_jvmti, jni_thread, &count);\n    return count;\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n * Method:    createNativeStackFrameBuffer\n * Signature: (I)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Stacks_createNativeStackFrameBuffer\n    (JNIEnv *env, jclass clz, jint sizeInFrames)\n{\n    if (_stack_frames_buffer != NULL) {\n        Java_org_graalvm_visualvm_lib_jfluid_server_system_Stacks_clearNativeStackFrameBuffer(env, clz);\n    }\n    _stack_frames_buffer = calloc(sizeInFrames, sizeof(jvmtiFrameInfo));\n    _stack_id_buffer = calloc(sizeInFrames, sizeof(jint));\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n * Method:    clearNativeStackFrameBuffer\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Stacks_clearNativeStackFrameBuffer\n    (JNIEnv *env, jclass clz)\n{\n    if (_stack_frames_buffer != NULL) {\n        free(_stack_frames_buffer);\n    }\n    if (_stack_id_buffer != NULL) {\n        free(_stack_id_buffer);\n    }\n    _stack_frames_buffer = NULL;\n    _stack_id_buffer = NULL;\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n * Method:    getCurrentStackFrameIds\n * Signature: (Ljava/lang/Thread;I[I)I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Stacks_getCurrentStackFrameIds\n    (JNIEnv *env, jclass clz, jthread jni_thread, jint depth, jintArray ret)\n{\n    jint i, count;\n    if (_stack_frames_buffer == NULL) {\n        /* Can happen if profiling stopped concurrently */\n        return 0;\n    }\n\n    (*_jvmti)->GetStackTrace(_jvmti, jni_thread, 0, depth, _stack_frames_buffer, &count);\n\n    for (i = 0; i < count; i++) {\n        _stack_id_buffer[i] = convert_jmethodID_to_jint(_stack_frames_buffer[i].method);\n    }\n    (*env)->SetIntArrayRegion(env, ret, 0, count, _stack_id_buffer);\n\n    return count;\n}\n\n\nstatic jbyte *byteData;\nstatic jint *strOffsets;\nstatic int byteDataLen, dataOfs, ofsIdx;\n\nstatic void copy_into_data_array(char *s) {\n    int len = strlen(s);\n    if (dataOfs + len > byteDataLen) {\n        jbyte *oldByteData = byteData;\n        int newLen = byteDataLen * 2;\n\n        if (newLen < dataOfs + len) {\n          newLen = dataOfs+len;\n        }\n        byteData = malloc(newLen);\n        memcpy(byteData, oldByteData, dataOfs);\n        free(oldByteData);\n        byteDataLen = newLen;\n    }\n\n    strncpy((char*)(byteData + dataOfs), s, len);\n    strOffsets[ofsIdx++] = dataOfs;\n    dataOfs += len;\n}\n\nstatic void copy_dummy_names_into_data_array() {\n    copy_into_data_array(\"<unknown class>\");\n    copy_into_data_array(\"<unknown method>\");\n    copy_into_data_array(\"()V\");\n    copy_into_data_array(\"0\");\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n * Method:    getMethodNamesForJMethodIds\n * Signature: (I[I[I)[B\n */\nJNIEXPORT jbyteArray JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Stacks_getMethodNamesForJMethodIds\n  (JNIEnv *env, jclass clz, jint nMethods, jintArray jmethodIds, jintArray packedArrayOffsets)\n{\n    jvmtiError res;\n    int i, len;\n    jint *methodIds;\n    jbyteArray ret;\n\n    // fprintf (stderr, \"1\");\n    methodIds = (jint*) malloc(sizeof(jint) * nMethods);\n    (*env)->GetIntArrayRegion(env, jmethodIds, 0, nMethods, methodIds);\n    strOffsets = (jint*) malloc(sizeof(jint) * nMethods * PACKEDARR_ITEMS);\n    byteDataLen = nMethods * PACKEDARR_ITEMS * 10;  /* The initial size for the packed strings array */\n    byteData = (jbyte*) malloc(byteDataLen);\n\n    // fprintf (stderr, \"2\");\n    dataOfs = ofsIdx = 0;\n\n    for (i = 0; i < nMethods; i++) {\n        jclass declaringClass;\n        char *className, *genericSignature, *methodName, *methodSig, *genericMethodSig;\n        jboolean native = JNI_FALSE;\n        jmethodID methodID = convert_jint_to_jmethodID(methodIds[i]);\n\n        //fprintf (stderr, \"Going to call GetMethodDeclaringClass for methodId = %d\\n\", *(int*)methodID);\n\n        res = (*_jvmti)->GetMethodDeclaringClass(_jvmti, methodID, &declaringClass);\n        if (res != JVMTI_ERROR_NONE || declaringClass == NULL || *((int*)declaringClass) == 0) { /* Also a bug workaround */\n            fprintf(stderr, \"Profiler Agent Warning: Invalid declaringClass obtained from jmethodID\\n\");\n            fprintf(stderr, \"Profiler Agent Warning: mId = %p, *mId = %d\\n\", methodID, *(int*)methodID);\n            fprintf(stderr, \"Profiler Agent Warning: dCl = %p\", declaringClass);\n            if (declaringClass != NULL) {\n                fprintf(stderr, \", *dCl = %d\\n\", *((int*)declaringClass));\n            } else {\n                fprintf(stderr, \"\\n\");\n            }\n            // fprintf(stderr, \"*** res = %d\", res);\n            copy_dummy_names_into_data_array();\n            continue;\n        }\n\n        // fprintf (stderr, \"Going to call GetClassSignature for methodId = %d, last res = %d, declaring class: %d\\n\", *(int*)methodID, res, *((int*)declaringClass));\n\n        res = (*_jvmti)->GetClassSignature(_jvmti, declaringClass, &className, &genericSignature);\n        if (res != JVMTI_ERROR_NONE) {\n            fprintf(stderr, \"Profiler Agent Warning: Couldn't obtain name of declaringClass = %p\\n\", declaringClass);\n            copy_dummy_names_into_data_array();\n            continue;\n        }\n\n        // fprintf (stderr, \"Going to call GetMethodName for methodId = %d, last res = %d, signature: %s\\n\", *(int*)methodID, res, genericSignature);\n\n        res = (*_jvmti)->GetMethodName(_jvmti, methodID, &methodName, &methodSig, &genericMethodSig);\n\n        if (res != JVMTI_ERROR_NONE) {\n            fprintf(stderr, \"Profiler Agent Warning: Couldn't obtain name for methodID = %p\\n\", methodID);\n            copy_dummy_names_into_data_array();\n            continue;\n        }\n\n        // fprintf (stderr, \"Going to call IsMethodNative for methodId = %d, last res = %d, signature: %s\\n\", *(int*)methodID, res, genericSignature);\n        \n        res = (*_jvmti)->IsMethodNative(_jvmti, methodID, &native);\n        \n        if (res != JVMTI_ERROR_NONE) {\n            fprintf(stderr, \"Profiler Agent Warning: Couldn't obtain native flag for methodID = %p\\n\", methodID);\n        }\n\n        // fprintf (stderr, \"Going to copy results, last res = %d, method name: %s, sig: %s, genSig: %s, native %d\\n\", res, methodName, methodSig, genericMethodSig, native);\n\n        len = strlen(className);\n        if (className[0] == 'L' && className[len-1] == ';') {\n            className[len-1] = 0;\n            copy_into_data_array(className+1);\n        } else {\n            copy_into_data_array(className);\n        }\n\n        copy_into_data_array(methodName);\n        copy_into_data_array(methodSig);\n        copy_into_data_array(native?\"1\":\"0\");\n\n        (*_jvmti)->Deallocate(_jvmti, (void*)className);\n\n        if (genericSignature != NULL) {\n            (*_jvmti)->Deallocate(_jvmti, (void*)genericSignature);\n        }\n\n        (*_jvmti)->Deallocate(_jvmti, (void*)methodName);\n        (*_jvmti)->Deallocate(_jvmti, (void*)methodSig);\n        if (genericMethodSig != NULL) {\n            (*_jvmti)->Deallocate(_jvmti, (void*)genericMethodSig);\n        }\n    }\n\n    // fprintf (stderr, \"3\");\n    free(methodIds);\n\n    ret = (*env)->NewByteArray(env, dataOfs);\n    (*env)->SetByteArrayRegion(env, ret, 0, dataOfs, byteData);\n    (*env)->SetIntArrayRegion(env, packedArrayOffsets, 0, nMethods*PACKEDARR_ITEMS, strOffsets);\n\n    // fprintf (stderr, \"4\");\n    free(strOffsets);\n    free(byteData);\n\n    return ret;\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n * Method:    getAllStackTraces\n * Signature: ([[Ljava/lang/Thread;[[I[[[I)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Stacks_getAllStackTraces\n  (JNIEnv *env, jclass clz, jobjectArray threads, jobjectArray states, jobjectArray frames)\n{\n    jobjectArray jthreadArr;\n    jobjectArray statesArr;\n    jobjectArray methodIdArrArr;\n    jvmtiStackInfo *stack_info;\n    jint *state_buffer;\n    jint thread_count;\n    int ti;\n    jvmtiError err;\n\n    err = (*_jvmti)->GetAllStackTraces(_jvmti, MAX_FRAMES, &stack_info, &thread_count); \n    if (err != JVMTI_ERROR_NONE) {\n       return;\n    }\n    if (threadType == NULL) {\n        threadType = (*env)->FindClass(env, \"java/lang/Thread\");\n        threadType = (*env)->NewGlobalRef(env, threadType);\n    }\n    if (intArrType == NULL) {\n        intArrType = (*env)->FindClass(env, \"[I\");\n        intArrType = (*env)->NewGlobalRef(env, intArrType);\n    }\n    jthreadArr = (*env)->NewObjectArray(env, thread_count, threadType, NULL);\n    (*env)->SetObjectArrayElement(env, threads, 0, jthreadArr);\n    statesArr = (*env)->NewIntArray(env, thread_count);\n    (*env)->SetObjectArrayElement(env, states, 0, statesArr);\n    methodIdArrArr = (*env)->NewObjectArray(env, thread_count, intArrType, NULL);\n    (*env)->SetObjectArrayElement(env, frames, 0, methodIdArrArr);    \n    state_buffer = calloc(thread_count, sizeof(jint));\n    \n    for (ti = 0; ti < thread_count; ti++) {\n       jvmtiStackInfo *infop = &stack_info[ti];\n       jthread thread = infop->thread;\n       jint state = infop->state;\n       jvmtiFrameInfo *frames = infop->frame_buffer;\n       jobjectArray jmethodIdArr;\n       jint *id_buffer;\n       int fi;\n\n       (*env)->SetObjectArrayElement(env, jthreadArr, ti, thread);\n       state_buffer[ti] = convert_JVMTI_thread_status_to_jfluid_status(state);\n       \n       jmethodIdArr = (*env)->NewIntArray(env, infop->frame_count);\n       (*env)->SetObjectArrayElement(env, methodIdArrArr, ti, jmethodIdArr);    \n       id_buffer = calloc(infop->frame_count, sizeof(jint));\n       for (fi = 0; fi < infop->frame_count; fi++) {\n          id_buffer[fi] = convert_jmethodID_to_jint(frames[fi].method);\n       }\n       (*env)->SetIntArrayRegion(env, jmethodIdArr, 0, infop->frame_count, id_buffer);\n       free(id_buffer);\n    }\n    (*env)->SetIntArrayRegion(env, statesArr, 0, thread_count, state_buffer);\n    \n    /* this one Deallocate call frees all data allocated by GetAllStackTraces */\n    err = (*_jvmti)->Deallocate(_jvmti, (unsigned char*)stack_info);\n    assert(err == JVMTI_ERROR_NONE);\n    free(state_buffer);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/Threads.c",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/*\n * author Ian Formanek\n *        Misha Dmitriev\n *        Tomas Hurka\n */\n\n#ifdef WIN32\n#include <Windows.h>\n#else\n#include <sys/time.h>\n#include <fcntl.h>\n#include <time.h>\n#endif\n\n#ifdef SOLARIS\n#define _STRUCTURED_PROC 1\n#include <sys/procfs.h>\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <assert.h>\n\n#include \"jni.h\"\n#include \"jvmti.h\"\n\n#include \"org_graalvm_visualvm_lib_jfluid_server_system_Threads.h\"\n\n#include \"common_functions.h\"\n\n/* The following is copied from org.graalvm.visualvm.lib.jfluid.global.CommonConstants */\n#define THREAD_STATUS_UNKNOWN  -1\n#define THREAD_STATUS_ZOMBIE    0\n#define THREAD_STATUS_RUNNING   1\n#define THREAD_STATUS_SLEEPING  2\n#define THREAD_STATUS_MONITOR   3\n#define THREAD_STATUS_WAIT      4\n#define THREAD_STATUS_PARK      5\n\n/* These masks essentially map JVMTI thread states into the above states */\nstatic jint JF_THREAD_STATE_MASK       = JVMTI_THREAD_STATE_TERMINATED |\n                                         JVMTI_THREAD_STATE_ALIVE |\n                                         JVMTI_THREAD_STATE_RUNNABLE |\n                                         JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER |\n                                         JVMTI_THREAD_STATE_WAITING |\n                                         JVMTI_THREAD_STATE_WAITING_INDEFINITELY |\n                                         JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT |\n                                         JVMTI_THREAD_STATE_SLEEPING |\n                                         JVMTI_THREAD_STATE_PARKED;\nstatic jint JF_THREAD_STATE_NEW        = 0;\nstatic jint JF_THREAD_STATE_TERMINATED = JVMTI_THREAD_STATE_TERMINATED;\nstatic jint JF_THREAD_STATE_RUNNABLE   = JVMTI_THREAD_STATE_ALIVE |\n                                         JVMTI_THREAD_STATE_RUNNABLE;\nstatic jint JF_THREAD_STATE_BLOCKED    = JVMTI_THREAD_STATE_ALIVE |\n                                         JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;\nstatic jint JF_THREAD_STATE_WAITING    = JVMTI_THREAD_STATE_ALIVE |\n                                         JVMTI_THREAD_STATE_WAITING |\n                                         JVMTI_THREAD_STATE_WAITING_INDEFINITELY;\nstatic jint JF_THREAD_STATE_TIMED_WAITING = JVMTI_THREAD_STATE_ALIVE |\n                                         JVMTI_THREAD_STATE_WAITING |\n                                         JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;\nstatic jint JF_THREAD_STATE_SLEEPING   = JVMTI_THREAD_STATE_ALIVE |\n                                         JVMTI_THREAD_STATE_WAITING |\n                                         JVMTI_THREAD_STATE_SLEEPING |\n                                         JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;\nstatic jint JF_THREAD_STATE_TIMED_PARKED = JVMTI_THREAD_STATE_ALIVE |\n                                         JVMTI_THREAD_STATE_WAITING |\n                                         JVMTI_THREAD_STATE_PARKED |\n                                         JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;\nstatic jint JF_THREAD_STATE_PARKED = JVMTI_THREAD_STATE_ALIVE |\n                                         JVMTI_THREAD_STATE_WAITING |\n                                         JVMTI_THREAD_STATE_PARKED |\n                                         JVMTI_THREAD_STATE_WAITING_INDEFINITELY;\n\n\nstatic int nProfThreads;\nstatic jthread *profThreads = NULL;\nstatic jthread mainThread = NULL, singleProfThread = NULL, additionalProfThread = NULL;\nstatic jclass threadType = NULL;\n\n\njint convert_JVMTI_thread_status_to_jfluid_status(jint jvmtiThreadStatus) {\n    jint status = jvmtiThreadStatus & JF_THREAD_STATE_MASK;\n  \n    if      (status == JF_THREAD_STATE_RUNNABLE)      return THREAD_STATUS_RUNNING;\n    else if (status == JF_THREAD_STATE_BLOCKED)       return THREAD_STATUS_MONITOR;\n    else if (status == JF_THREAD_STATE_WAITING)       return THREAD_STATUS_WAIT;\n    else if (status == JF_THREAD_STATE_TIMED_WAITING) return THREAD_STATUS_WAIT;\n    else if (status == JF_THREAD_STATE_PARKED)        return THREAD_STATUS_PARK;\n    else if (status == JF_THREAD_STATE_TIMED_PARKED)  return THREAD_STATUS_PARK;\n    else if (status == JF_THREAD_STATE_SLEEPING)      return THREAD_STATUS_SLEEPING;\n    else if (status == JF_THREAD_STATE_NEW)           return THREAD_STATUS_ZOMBIE;\n    else if (status == JF_THREAD_STATE_TERMINATED)    return THREAD_STATUS_ZOMBIE;\n    else                                              return THREAD_STATUS_UNKNOWN;\n}\n\n\nstatic int isProfilerThread(JNIEnv *env, jthread thread) {\n    int i;\n    if (additionalProfThread != NULL) {\n        if ((*env)->IsSameObject(env, thread, additionalProfThread)) {\n            return 1;\n         }\n    }\n    if (profThreads != NULL) {\n        for (i = 0; i < nProfThreads; i++) {\n            if ((*env)->IsSameObject(env, thread, profThreads[i])) return 1;\n        }\n        return 0;\n    } else {\n        return ((*env)->IsSameObject(env, thread, singleProfThread));\n    }\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    recordProfilerOwnThreads\n * Signature: (ZLjava/lang/Thread;)I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_recordProfilerOwnThreads\n    (JNIEnv *env, jclass clz, jboolean excludeSpecialThread, jobject specialThread) \n{\n    jvmtiError res;\n    int i, j;\n  \n    if (profThreads != NULL) {\n        for (i = 0; i < nProfThreads; i++) {\n            (*env)->DeleteGlobalRef(env, profThreads[i]);\n         }\n        (*_jvmti)->Deallocate(_jvmti, (unsigned char*) profThreads);\n    }\n    \n    profThreads = NULL;\n    if (singleProfThread != NULL) {\n        (*env)->DeleteGlobalRef(env, singleProfThread);\n    }\n    singleProfThread = NULL;\n    if (mainThread != NULL) {\n        (*env)->DeleteGlobalRef(env, mainThread);\n    }\n    mainThread = NULL;\n  \n    if (excludeSpecialThread) {\n        res = (*_jvmti)->GetAllThreads(_jvmti, (jint*)&nProfThreads, &profThreads);\n        assert(res == JVMTI_ERROR_NONE);\n        if (specialThread != NULL) {\n            for (i = 0; i < nProfThreads; i++) {\n                if ((*env)->IsSameObject(env, specialThread, profThreads[i])) {\n                    for (j = i+1; j < nProfThreads; j++) {\n                        profThreads[j-1] = profThreads[j];\n                    }\n                    nProfThreads--;\n                    break;\n                }\n            }\n            mainThread = (*env)->NewGlobalRef(env, specialThread);\n        }\n        /* Results were returned as local references; make them global to survive across native calls */\n        for (i = 0; i < nProfThreads; i++) {\n            profThreads[i] = (*env)->NewGlobalRef(env, profThreads[i]);\n        }\n        return nProfThreads;\n    } else {\n        singleProfThread = (*env)->NewGlobalRef(env, specialThread);\n        return 1;\n    }\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    recordAdditionalProfilerOwnThread\n * Signature: (Ljava/lang/Thread;)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_recordAdditionalProfilerOwnThread\n    (JNIEnv *env, jclass clz, jobject specialThread) \n{\n    if (additionalProfThread != NULL) {\n        (*env)->DeleteGlobalRef(env, additionalProfThread);\n    }\n    additionalProfThread = (*env)->NewGlobalRef(env, specialThread);\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    getTotalNumberOfThreads\n * Signature: ()I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_getTotalNumberOfThreads\n    (JNIEnv *env, jclass clz) \n{\n    jvmtiError res;\n    int nThreads;\n    jthread *threads = NULL;\n  \n    res = (*_jvmti)->GetAllThreads(_jvmti, (jint*)&nThreads, &threads);\n    assert(res == JVMTI_ERROR_NONE);\n    if (threads != NULL) {\n        (*_jvmti)->Deallocate(_jvmti, (unsigned char*) threads);\n    }\n    return nThreads;\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    suspendTargetAppThreads\n * Signature: (Ljava/lang/Thread;)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_suspendTargetAppThreads\n    (JNIEnv *env, jclass clz, jobject excludedThread) \n{\n    jvmtiError res;\n    int i;\n    int nThreads;\n    jthread *threads = NULL;\n  \n    res = (*_jvmti)->GetAllThreads(_jvmti, (jint*)&nThreads, &threads);\n    assert(res == JVMTI_ERROR_NONE);\n  \n    for (i = 0; i < nThreads; i++) {\n        if (! (isProfilerThread(env, threads[i]) || (*env)->IsSameObject(env, excludedThread, threads[i]))) {\n            (*_jvmti)->SuspendThread(_jvmti, threads[i]);\n        }\n    }\n  \n    (*_jvmti)->Deallocate(_jvmti, (unsigned char*) threads);\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    resumeTargetAppThreads\n * Signature: (Ljava/lang/Thread;)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_resumeTargetAppThreads\n    (JNIEnv *env, jclass clz, jobject excludedThread) \n{\n    jvmtiError res;\n    int i;\n    int nThreads;\n    jthread *threads = NULL;\n  \n    res = (*_jvmti)->GetAllThreads(_jvmti, (jint*)&nThreads, &threads);\n    assert(res == JVMTI_ERROR_NONE);\n  \n    for (i = 0; i < nThreads; i++) {\n        if (! (isProfilerThread(env, threads[i]) || (*env)->IsSameObject(env, excludedThread, threads[i]))) {\n            (*_jvmti)->ResumeThread(_jvmti, threads[i]);\n        }\n    }\n  \n    (*_jvmti)->Deallocate(_jvmti, (unsigned char*) threads);\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    terminateTargetAppThreads\n * Signature: (Ljava/lang/Object;)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_terminateTargetAppThreads\n    (JNIEnv *env, jclass clz, jobject excObject) \n{\n    jvmtiError res;\n    int i;\n    int nThreads;\n    jthread *threads;\n  \n    res = (*_jvmti)->GetAllThreads(_jvmti, (jint*)&nThreads, &threads);\n    assert(res == JVMTI_ERROR_NONE);\n  \n    for (i = 0; i < nThreads; i++) {\n        if (! isProfilerThread(env, threads[i])) {\n            (*_jvmti)->StopThread(_jvmti, threads[i], excObject);\n        }\n    }\n  \n    (*_jvmti)->Deallocate(_jvmti, (unsigned char*) threads);\n    if (mainThread != NULL) {\n        (*env)->DeleteGlobalRef(env, mainThread);\n    }\n    mainThread = NULL;\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    targetAppThreadsExist\n * Signature: ()Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_targetAppThreadsExist\n    (JNIEnv *env, jclass clz) \n{\n    jvmtiError res;\n    int i;\n    jboolean exist;\n    int nThreads;\n    jthread *threads;\n  \n    res = (*_jvmti)->GetAllThreads(_jvmti, (jint*)&nThreads, &threads);\n    assert(res == JVMTI_ERROR_NONE);\n  \n    exist = 0;\n    for (i = 0; i < nThreads; i++) {\n        if (! isProfilerThread(env, threads[i]) && ! (*env)->IsSameObject(env, threads[i], mainThread)) {\n            exist = 1;\n            break;\n        }\n    }\n  \n    (*_jvmti)->Deallocate(_jvmti, (unsigned char*) threads);\n    return exist;\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    getAllThreads\n * Signature: ([Ljava/lang/Thread;)[Ljava/lang/Thread;\n */\nJNIEXPORT jobjectArray JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_getAllThreads\n    (JNIEnv *env , jclass clz, jobjectArray jthreads) \n{\n    int nThreads, arrayLen, i;\n    jthread *threads = NULL;\n    jvmtiError res;\n\n    res = (*_jvmti)->GetAllThreads(_jvmti, (jint*)&nThreads, &threads);\n    assert(res == JVMTI_ERROR_NONE);\n\t  \n    arrayLen = (jthreads != NULL) ? (*env)->GetArrayLength(env, jthreads) : 0;\n    if (nThreads > arrayLen) {\n        if (threadType == NULL) {\n            threadType = (*env)->FindClass(env, \"java/lang/Thread\");\n            threadType = (*env)->NewGlobalRef(env, threadType);\n        }\n        jthreads = (*env)->NewObjectArray(env, nThreads, threadType, NULL);\n    }\n  \n    for (i = 0; i < nThreads; i++) {\n        (*env)->SetObjectArrayElement(env, jthreads, i, threads[i]);\n    }\n    for (i = nThreads; i < arrayLen; i++) {\n        (*env)->SetObjectArrayElement(env, jthreads, i, NULL);\n    }\n  \n    (*_jvmti)->Deallocate(_jvmti, (unsigned char*) threads);\n    return jthreads;\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    getThreadsStatus\n * Signature: ([Ljava/lang/Thread;[I)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_getThreadsStatus\n    (JNIEnv *env, jclass clz, jobjectArray jthreads, jintArray jstatus) \n{\n    int nThreads, i;\n    jint threadStatus;\n    jint *status;\n  \n    nThreads = (*env)->GetArrayLength(env, jthreads);\n    status = malloc(nThreads * sizeof(jint));\n  \n    for (i = 0; i < nThreads; i++) {\n        jthread thread = (*env)->GetObjectArrayElement(env, jthreads, i);\n        if (thread == NULL) {\n            continue;\n         }\n        (*_jvmti)->GetThreadState(_jvmti, thread, &threadStatus);\n        status[i] = convert_JVMTI_thread_status_to_jfluid_status(threadStatus);\n    }\n  \n    (*env)->SetIntArrayRegion(env, jstatus, 0, nThreads, status);\n    free(status);\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    getJVMArguments\n * Signature: ()Ljava/lang/String;\n */\nJNIEXPORT jstring JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_getJVMArguments\n    (JNIEnv *env, jclass clz) \n{\n    jstring ret = (*env)->NewStringUTF(env, \"*NOT PROVIDED IN THIS JVM VERSION*\");\n    return ret;\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    getJavaCommand\n * Signature: ()Ljava/lang/String;\n */\nJNIEXPORT jstring JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_getJavaCommand\n    (JNIEnv *env, jclass clz) \n{\n    jstring ret = (*env)->NewStringUTF(env, \"*NOT PROVIDED IN THIS JVM VERSION*\");\n    return ret;\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/Threads.h",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * author Tomas Hurka\n */\n\njint convert_JVMTI_thread_status_to_jfluid_status(jint jvmtiThrStatus);\n\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/Timers.c",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/*\n * author Tomas Hurka\n *        Ian Formanek\n *        Misha Dmitriev\n */\n\n#ifdef WIN32\n#include <Windows.h>\n#else\n#include <sys/time.h>\n#include <fcntl.h>\n#include <time.h>\n#endif\n\n#ifdef SOLARIS\n#define _STRUCTURED_PROC 1\n#include <sys/procfs.h>\n#include <unistd.h>\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <assert.h>\n\n#include \"jni.h\"\n#include \"jvmti.h\"\n\n#include \"org_graalvm_visualvm_lib_jfluid_server_system_Timers.h\"\n\n#include \"common_functions.h\"\n\n#ifdef CVM\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Timers\n * Method:    getCurrentTimeInCounts\n * Signature: ()J\n */\nJNIEXPORT jlong JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Timers_getCurrentTimeInCounts\n  (JNIEnv *env, jclass clz)\n{\n        jlong time;\n        jvmtiError res;\n\n        res = (*_jvmti)->GetTime(_jvmti,&time);\n        if (res != JVMTI_ERROR_NONE) fprintf(stderr, \"Profiler Agent Error: GetTime failed with %d\\n\",res);\n        assert(res == JVMTI_ERROR_NONE);\n        return time;\n}\n\n#endif\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Timers\n * Method:    getThreadCPUTimeInNanos\n * Signature: ()J\n */\nJNIEXPORT jlong JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Timers_getThreadCPUTimeInNanos\n  (JNIEnv *env, jclass clz)\n{\n\tjlong threadTime;\n\tjvmtiError res;\n\t\n\tres = (*_jvmti)->GetCurrentThreadCpuTime(_jvmti,&threadTime);\n\tif (res == /* JVMTI_ERROR_UNSUPPORTED_OPERATION */ 73) return -1;\n\tif (res != JVMTI_ERROR_NONE) fprintf(stderr, \"Profiler Agent Error: GetCurrentThreadCpuTime failed with %d\\n\",res);\n\tassert(res == JVMTI_ERROR_NONE);\n\treturn threadTime;\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Timers\n * Method:    osSleep\n * Signature: (I)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Timers_osSleep\n  (JNIEnv *env, jclass clz, jint ns)\n{\n#ifndef WIN32\n    struct timespec rqtp;\n    rqtp.tv_sec = 0;\n    rqtp.tv_nsec = ns;\n    nanosleep(&rqtp, NULL);\n#endif\n}\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Timers\n * Method:    enableMicrostateAccounting\n * Signature: (Z)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Timers_enableMicrostateAccounting\n  (JNIEnv *env, jclass clz, jboolean enable)\n{\n#ifdef SOLARIS\n    int ctlfd;\n    long ctl[2];\n    char procname[1024];\n\n    sprintf(procname, \"/proc/%d/ctl\", getpid());\n    ctlfd = open(procname, O_WRONLY);\n    if (ctlfd < 0) {\n        /*fprintf(stderr, \"open %s failed, errno = %d\\n\", procname, errno);*/\n        return;\n    }\n\n    if (enable) {\n        ctl[0] = PCSET;\n    } else {\n        ctl[0] = PCUNSET;\n    }\n    ctl[1] = PR_MSACCT;\n    if (write(ctlfd, ctl, 2*sizeof(long)) < 0) {\n    /*\n        fprintf(stderr, \"write failed, errno = %d\\n\", errno);\n    */\n    }\n    close(ctlfd);\n#endif\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/attach.c",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/*\n * author Ian Formanek\n *        Misha Dmitriev\n */\n\n#include <string.h>\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n\n#include \"jvmti.h\"\n\n#include \"common_functions.h\"\n\n#define JF_SERVER_JAR_1  \"/jfluid-server.jar\"\n#ifdef CVM\n#define JF_SERVER_JAR_2  \"/jfluid-server-cvm.jar\"\n#else\n#define JF_SERVER_JAR_2  \"/jfluid-server-15.jar\"\n#endif\n\n// these constatns must match those defined in ProfilerServer\n#define ATTACH_DYNAMIC 0\n#define ATTACH_DIRECT 1\n\nstatic char *_jfluid_dir;\nstatic int _port_no;\nstatic int _time_out = 0;\n\n\nvoid parse_options_and_extract_params(char *options) {\n    char *jfluid_added_boot_path, *port_str, *timeout_str;\n    char *jfluid_boot_class_subpaths[2];\n    int i, in_quoted_path = 0, quotes_present = 0, path_len = 0;\n    jvmtiError res;\n\n    while (in_quoted_path || (!in_quoted_path && options[path_len] != ',')) {\n        if (options[path_len] == '\\\"') {\n            quotes_present = 1;\n            in_quoted_path = !in_quoted_path;\n        }\n        path_len++;\n    }\n\n    port_str = options + path_len + 1;\n    _port_no = (int)strtol(port_str, &timeout_str, 10);\n    if (strlen(timeout_str) > 1) {\n        _time_out = atoi(timeout_str+1);\n    }\n\n    if (quotes_present) {\n        options += 1;\n        path_len -= 2;\n    }\n    _jfluid_dir = (char*) malloc(path_len + 1);\n    strncpy(_jfluid_dir, options, path_len);\n    _jfluid_dir[path_len] = 0;\n\n    jfluid_boot_class_subpaths[0] = JF_SERVER_JAR_1;\n    jfluid_boot_class_subpaths[1] = JF_SERVER_JAR_2;\n\n    for (i = 0; i < 2; i++) {\n        jfluid_added_boot_path = (char*) malloc(path_len + strlen(jfluid_boot_class_subpaths[i]) + 1);\n        strcpy(jfluid_added_boot_path, _jfluid_dir);\n        strcpy(jfluid_added_boot_path + path_len, jfluid_boot_class_subpaths[i]);\n\n        res = (*_jvmti)->AddToBootstrapClassLoaderSearch(_jvmti, jfluid_added_boot_path);\n        assert(res == JVMTI_ERROR_NONE);\n        free(jfluid_added_boot_path);\n    }\n}\n\n\n/*\n * This routine updates the bootstrap class path (if necessary) and then calls\n * ProfilerServer.activate() method.\n * The activateCode parameter signals the type of attachment to the ProfilerServer:\n *   0 - dynamic attachment (not used so far), 1 - attach on startup\n */\nstatic jint setupAndCallProfilerRuntimeActivate(JNIEnv *env, jint activateCode) {\n    jmethodID activateMethodID;\n    jclass profilerServerClass;\n    jstring jfluidDir;\n\n    /* For some reason (null classloader?) have to use slashed name - it barks if it is dotted */\n    profilerServerClass = (*env)->FindClass(env, \"org/graalvm/visualvm/lib/jfluid/server/ProfilerServer\");\n    if (profilerServerClass == NULL) {\n        char *new_sun_boot_class_path;\n        (*_jvmti)->GetSystemProperty(_jvmti, \"sun.boot.class.path\", &new_sun_boot_class_path);\n        fprintf(stderr, \"Profiler Agent Error: Can't start the profiler back end: main class not found\\n\");\n        fprintf(stderr, \"Profiler Agent Error: Boot class path was set to: %s\\n\", new_sun_boot_class_path);\n        (*_jvmti)->Deallocate(_jvmti, (void*)new_sun_boot_class_path);\n        fprintf(stderr, \"Profiler Agent Error: Please check if you have jfluid-server.jar on this path\\n\");\n        return -1;\n    }\n\n    activateMethodID = (*env)->GetStaticMethodID(env, profilerServerClass, \"activate\", \"(Ljava/lang/String;III)V\");\n    if (activateMethodID == NULL) {\n        fprintf(stderr, \"Profiler Agent Error: Can't start the profiler back end: activate(String, int) method not found in main class\\n\");\n        return -1;\n    }\n\n    jfluidDir = (*env)->NewStringUTF(env, _jfluid_dir);\n\n    (*env)->CallStaticVoidMethod(env, profilerServerClass, activateMethodID, jfluidDir, _port_no, activateCode, _time_out);\n\n    (*env)->DeleteLocalRef(env, jfluidDir);\n    (*env)->DeleteLocalRef(env, profilerServerClass);\n    if ((*env)->ExceptionCheck(env)) {\n        (*env)->ExceptionDescribe(env);\n        return -1;\n    }\n\n    return 0;\n}\n\n\n/** If the VM was launched on its own, we arrange that this is called right after the VM is initialized */\nvoid JNICALL vm_init_hook(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread) {\n    setupAndCallProfilerRuntimeActivate(jni_env, ATTACH_DIRECT);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/class_file_cache.c",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/*\n * author Ian Formanek\n *        Tomas Hurka\n *        Misha Dimitiev\n */\n#include <stdio.h>\n#include <stdlib.h>\n#include <assert.h>\n\n#include \"jni.h\"\n#include \"jvmti.h\"\n\n#include \"common_functions.h\"\n\n#ifdef WIN32\n#include <Windows.h>\n#else\n#include <sys/time.h>\n#include <string.h>\n#endif\n\n#ifndef TRUE\n#define TRUE 1\n#endif\n\n#ifndef FALSE\n#define FALSE 0\n#endif\n\n/** A hash table that maps class name/loader to class file bytes */\n#define _CTABLE_INIT_SIZE  19\nstatic char   **_ctable_classnames = NULL;\nstatic jobject *_ctable_loaders = NULL;\nstatic char   **_ctable_classdata = NULL;\nstatic int     *_ctable_classdata_lens = NULL;\nstatic int      _ctable_size = 0, _ctable_threshold = -1, _ctable_elements = 0, _total_cached_class_count = 0;\nstatic jobject  _ctable_lock = NULL;\n\nstatic jboolean  waitTrackingEnabled = FALSE;\nstatic jboolean  sleepTrackingEnabled = FALSE;\nstatic jboolean  parkTrackingEnabled = FALSE;\nstatic jboolean  lockContentionMonitoringEnabled = FALSE;\n\nstatic jboolean  trackingMethodsInitialized = FALSE;\n\nstatic waitCall  waitAddress = NULL;\nstatic sleepCall sleepAddress = NULL;\nstatic parkCall  parkAddress = NULL;\n\nstatic jclass    profilerRuntimeID = NULL;\nstatic jmethodID waitEntryID = NULL;\nstatic jmethodID waitExitID = NULL;\nstatic jmethodID monitorEntryID = NULL;\nstatic jmethodID monitorExitID = NULL;\nstatic jmethodID sleepEntryID = NULL;\nstatic jmethodID sleepExitID = NULL;\nstatic jmethodID parkEntryID = NULL;\nstatic jmethodID parkExitID = NULL;\nstatic jmethodID traceVMObjectAllocID = NULL;\nstatic jboolean retransformIsRunning = FALSE;\nstatic unsigned char BOGUS_CLASSFILE[] = \"HAHA\";\n#define END_CLASS_NAME \"org/graalvm/visualvm/lib/jfluid/server/ProfilerInterface$InitiateInstThread\"\n\n\nvoid cache_loaded_classes(jvmtiEnv *jvmti_env,jclass *classes,jint class_count) {\n#ifdef JNI_VERSION_1_6\n       //fprintf(stderr,\"cache_loade_classes, classes %d\\n\",(int)class_count);\n       jvmtiError res;\n\n       //fprintf(stderr,\"Retransform called\\n\");\n       retransformIsRunning = TRUE;\n       res=(*jvmti_env)->RetransformClasses(jvmti_env,class_count,classes);\n       retransformIsRunning = FALSE;\n       //fprintf(stderr,\"Retransform end\\n\");\n       if (res != JVMTI_ERROR_INVALID_CLASS_FORMAT && res != JVMTI_ERROR_NONE) { \n           fprintf(stderr,\"Profiler Agent Warning: Retransform failed with status %d\\n\",res);\n       }\n#endif\n}\n\nstatic jboolean isSameObject(JNIEnv *env, jobject obj1, jobject obj2) {\n    if (obj1 == NULL && obj2 == NULL) return JNI_TRUE;\n    if (obj1 == NULL || obj2 == NULL) return JNI_FALSE;\n    return (*env)->IsSameObject(env, obj1, obj2);\n}\n\n/*--------------------------------  Class hashtable management -------------------------------------*/\n\n/** Currently doesn't take into account loader, though ideally it should. */\nstatic int hash(const char *name, jobject loader) {\n    int i, code = 0;\n    int len = strlen(name);\n    for (i = 0; i < len; i++) {\n        code += name[i];\n    }\n  \n    if (code < 0) {\n        code = -code;\n    }\n    return code;\n}\n\n\nstatic void grow_ctable() {\n    int i;\n    int old_size = _ctable_size;\n    char **old_classnames = _ctable_classnames;\n    jobject *old_loaders = _ctable_loaders;\n    char **old_classdata = _ctable_classdata;\n    int *old_classdata_lens = _ctable_classdata_lens;\n  \n    if (_ctable_size == 0) {\n        _ctable_size = _CTABLE_INIT_SIZE;\n    } else {\n        _ctable_size = _ctable_size * 2 + 1;\n    }\n    _ctable_threshold = _ctable_size * 3 / 4;\n  \n    _ctable_classnames = calloc(_ctable_size, sizeof(char*));\n    _ctable_loaders = calloc(_ctable_size, sizeof(jobject));\n    _ctable_classdata = calloc(_ctable_size, sizeof(char*));\n    _ctable_classdata_lens = calloc(_ctable_size, sizeof(int));\n  \n    for (i = 0; i < old_size; i++) {\n        if (old_classnames[i] != NULL) {\n            int pos = hash(old_classnames[i], old_loaders[i]) % _ctable_size;\n            while (_ctable_classnames[pos] != NULL) {\n                pos = (pos + 1) % _ctable_size;\n            }\n            _ctable_classnames[pos] = old_classnames[i];\n            _ctable_loaders[pos] = old_loaders[i];\n            _ctable_classdata[pos] = old_classdata[i];\n            _ctable_classdata_lens[pos] = old_classdata_lens[i];\n        }\n    }\n  \n    if (old_classnames != NULL) {\n        free(old_classnames);\n        free(old_loaders);\n        free(old_classdata);\n        free(old_classdata_lens);\n    }\n}\n\n\n/** For the given class with non-NULL, non-system loader, save the supplied class file bytes permanently */\nstatic void save_class_file_bytes(JNIEnv *env, const char* name, jobject loader,\n                           jint class_data_len, const unsigned char* class_data) {\n    int pos;\n    /*printf(\"!!! Gonna save classfilebytes for class %s\\n\", name);*/\n  \n    (*env)->MonitorEnter(env, _ctable_lock);\n    if (_ctable_elements > _ctable_threshold) {\n        grow_ctable();\n    }\n  \n    pos = hash(name, loader) % _ctable_size;\n    while (_ctable_classnames[pos] != NULL) {\n        if (strcmp(name, _ctable_classnames[pos]) == 0 && isSameObject(env, loader, _ctable_loaders[pos])) { /* do not save class' bytecode if it is already saved */\n            (*env)->MonitorExit(env, _ctable_lock);\n            return;\n        } else {\n            pos = (pos + 1) % _ctable_size;\n        }\n    }\n  \n    _ctable_classnames[pos] = malloc(strlen(name) + 1);\n    strcpy(_ctable_classnames[pos], name);\n    if (loader != NULL) {\n        _ctable_loaders[pos] = (*env)->NewWeakGlobalRef(env, loader);\n    } else {\n        _ctable_loaders[pos] = NULL;\n    }\n    _ctable_classdata[pos] = malloc(class_data_len);\n    memcpy(_ctable_classdata[pos], class_data, class_data_len);\n    _ctable_classdata_lens[pos] = class_data_len;\n    _ctable_elements++;\n  \n    /* Check if we should try to do some pruning */\n    if (++_total_cached_class_count % 250 == 0) {\n        fprintf(stdout, \"Profiler Agent: 250 classes cached.\\n\");\n        try_removing_bytes_for_unloaded_classes(env);\n    }\n  \n    (*env)->MonitorExit(env, _ctable_lock);\n}\n\n\n/** Returns a copy of class bytes for the given class. These bytes should be deallocated\n  * using free() when not needed anymore.\n  *\n  * TODO: free memory for classes that will be unloaded\n  */\nvoid get_saved_class_file_bytes(JNIEnv *env, char *name, jobject loader, jint *class_data_len, unsigned char **class_data) {\n    int len, pos;\n  \n    (*env)->MonitorEnter(env, _ctable_lock);\n    pos = hash(name, loader) % _ctable_size;\n  \n    while (_ctable_classnames[pos] != NULL) {\n        if (strcmp(name, _ctable_classnames[pos]) == 0 && isSameObject(env, loader, _ctable_loaders[pos])) {\n            break;\n        } else {\n            pos = (pos + 1) % _ctable_size;\n        }\n    }\n  \n    if (_ctable_classnames[pos] == NULL) {\n        *class_data_len = 0;\n        *class_data = NULL;\n        (*env)->MonitorExit(env, _ctable_lock);\n        return;\n    }\n  \n    len = _ctable_classdata_lens[pos];\n    *class_data_len = len;\n    *class_data = malloc(len);\n    memcpy(*class_data, _ctable_classdata[pos], len);\n    (*env)->MonitorExit(env, _ctable_lock);\n}\n\n\n/** When the Java agent learns that some class loader is going to be unloaded, it notifies the C agent\n  * about that. Here we check for any weak references to classloader that got nullified, and get rid of\n  * class file bytes for such class loaders.\n  */\nvoid try_removing_bytes_for_unloaded_classes(JNIEnv *env) {\n}\n\nstatic jthread getOwner(jvmtiEnv *jvmti_env, jobject object) {\n    jvmtiMonitorUsage usage;\n    jvmtiError res;\n    \n    res = (*jvmti_env)->GetObjectMonitorUsage(jvmti_env, object, &usage);\n    assert(res == JVMTI_ERROR_NONE);\n    (*jvmti_env)->Deallocate(jvmti_env, (void*)usage.waiters);\n    (*jvmti_env)->Deallocate(jvmti_env, (void*)usage.notify_waiters);\n/*    if (usage.owner == NULL) {\n*        jint hash;\n*        res = (*jvmti_env)->GetObjectHashCode(jvmti_env, object, &hash);\n*        assert(res == JVMTI_ERROR_NONE);        \n*        fprintf(stderr, \"Profiler Agent Warning: NULL owner for lock %x.\\n\", (unsigned int)hash);\n*    }\n*/\n    return usage.owner;\n}\n\n/** Class file load hook that the JVM calls whenever a class file is loaded and about to be parsed */\nvoid JNICALL class_file_load_hook(\n      jvmtiEnv *jvmti_env,\n      JNIEnv* jni_env,\n      jclass class_being_redefined,\n      jobject loader,\n      const char* name,\n      jobject protection_domain,\n      jint class_data_len,\n      const unsigned char* class_data,\n      jint* new_class_data_len,\n      unsigned char** new_class_data) \n{\n    jvmtiError res;\n\n    if (name == NULL) {\n        /* NULL name */\n        fprintf(stderr, \"Profiler Agent Warning: JVMTI classLoadHook: class name is null.\\n\");\n        return;\n    }\n    if (class_being_redefined != NULL && !retransformIsRunning) {\n        /* Check if this class is being loaded for the first time (that is, not being redefined).\n           If it's being redefined, we return immediately. */\n        return;\n    }\n    if (loader == NULL) {\n        if (retransformIsRunning && strcmp(name,END_CLASS_NAME) == 0) {\n            /* Hack which will prevent unchanged classes to be redefined */ \n            res=(*jvmti_env)->Allocate(jvmti_env,sizeof(BOGUS_CLASSFILE), new_class_data);\n            assert(res == JVMTI_ERROR_NONE);\n            memcpy(*new_class_data,BOGUS_CLASSFILE,sizeof(BOGUS_CLASSFILE));\n            *new_class_data_len = sizeof(BOGUS_CLASSFILE);\n            return; \n        }\n    }\n    if (_ctable_lock == NULL) {\n        jvmtiPhase phase;\n\n        (*jvmti_env)->GetPhase(jvmti_env, &phase);\n        if (phase >= JVMTI_PHASE_LIVE) {\n            jclass object_class;\n\n            /* Create a lock object used to synchronize access to _ctable */\n            object_class = (*jni_env)->FindClass(jni_env, \"java/lang/Object\");\n            _ctable_lock = (*jni_env)->AllocObject(jni_env, object_class);\n            _ctable_lock = (*jni_env)->NewGlobalRef(jni_env, _ctable_lock);\n        } else {\n            return;\n        }\n    }\n    save_class_file_bytes(jni_env, name, loader, class_data_len, class_data);\n}\n\nstatic void initializeMethods (JNIEnv *env) {\n\n    jclass localProfilerRuntimeID;\n    jclass localProfilerRuntimeMemoryID;  \n    jboolean error = FALSE;\n  \n    localProfilerRuntimeID = (*env)->FindClass (env, \"org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntime\");\n    if (localProfilerRuntimeID == NULL) {\n  \n        (*env)->ExceptionDescribe (env);\n        fprintf(stderr, \"Profiler Agent Warning: Native bind failed to lookup org.graalvm.visualvm.lib.jfluid.server.ProfilerRuntime class!!!\\n\");\n        error = TRUE;\n  \n    } else {\n        profilerRuntimeID = (*env)->NewGlobalRef(env, localProfilerRuntimeID);\n    \n        waitEntryID = (*env)->GetStaticMethodID(env, profilerRuntimeID, \"waitEntry\", \"()V\");\n        if (waitEntryID == NULL) {\n            fprintf(stderr, \"Profiler Agent Warning: Native bind failed to lookup waitEntry method!!! \\n\");\n            (*env)->ExceptionDescribe (env);\n            error = TRUE;\n        }\n    \n        waitExitID = (*env)->GetStaticMethodID(env, profilerRuntimeID, \"waitExit\", \"()V\");\n        if (waitExitID == NULL) {\n            fprintf(stderr, \"Profiler Agent Warning: Native bind failed to lookup waitExit method!!! \\n\");\n            (*env)->ExceptionDescribe (env);\n            error = TRUE;\n        }\n    \n        sleepEntryID = (*env)->GetStaticMethodID(env, profilerRuntimeID, \"sleepEntry\", \"()V\");\n        if (sleepEntryID == NULL) {\n            fprintf(stderr, \"Profiler Agent Warning: Native bind failed to lookup sleepEntry method!!! \\n\");\n            (*env)->ExceptionDescribe (env);\n            error = TRUE;\n        }\n    \n        sleepExitID = (*env)->GetStaticMethodID(env, profilerRuntimeID, \"sleepExit\", \"()V\");\n        if (sleepExitID == NULL) {\n            fprintf(stderr, \"Profiler Agent Warning: Native bind failed to lookup sleepExit method!!! \\n\");\n            (*env)->ExceptionDescribe (env);\n            error = TRUE;\n        }\n    \n        monitorEntryID = (*env)->GetStaticMethodID(env, profilerRuntimeID, \"monitorEntry\", \"(Ljava/lang/Thread;Ljava/lang/Object;Ljava/lang/Thread;)V\");\n        if (monitorEntryID == NULL) {\n            fprintf(stderr, \"Profiler Agent Warning: Native bind failed to lookup monitorEntry method!!! \\n\");\n            (*env)->ExceptionDescribe (env);\n            error = TRUE;\n        }\n    \n        monitorExitID = (*env)->GetStaticMethodID(env, profilerRuntimeID, \"monitorExit\", \"(Ljava/lang/Thread;Ljava/lang/Object;)V\");\n        if (monitorExitID == NULL) {\n            fprintf(stderr, \"Profiler Agent Warning: Native bind failed to lookup monitorExit method!!! \\n\");\n            (*env)->ExceptionDescribe (env);\n            error = TRUE;\n        }\n\n        parkEntryID = (*env)->GetStaticMethodID(env, profilerRuntimeID, \"parkEntry\", \"()V\");\n        if (parkEntryID == NULL) {\n            fprintf(stderr, \"Profiler Agent Warning: Native bind failed to lookup parkEntry method!!! \\n\");\n            (*env)->ExceptionDescribe (env);\n            error = TRUE;\n        }\n    \n        parkExitID = (*env)->GetStaticMethodID(env, profilerRuntimeID, \"parkExit\", \"()V\");\n        if (parkExitID == NULL) {\n            fprintf(stderr, \"Profiler Agent Warning: Native bind failed to lookup parkExit method!!! \\n\");\n            (*env)->ExceptionDescribe (env);\n            error = TRUE;\n        }    \n    }\n    localProfilerRuntimeMemoryID = (*env)->FindClass (env, \"org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeMemory\");\n    if (localProfilerRuntimeMemoryID == NULL) {\n  \n        (*env)->ExceptionDescribe (env);\n        fprintf(stderr, \"Profiler Agent Warning: Native bind failed to lookup org.graalvm.visualvm.lib.jfluid.server.ProfilerRuntimeMemory class!!!\\n\");\n        error = TRUE;\n  \n    } else {\n        traceVMObjectAllocID = (*env)->GetStaticMethodID(env, localProfilerRuntimeMemoryID, \"traceVMObjectAlloc\", \"(Ljava/lang/Object;Ljava/lang/Class;)V\");\n        if (traceVMObjectAllocID == NULL) {\n            fprintf(stderr, \"Profiler Agent Warning: Native bind failed to lookup traceVMObjectAlloc method!!! \\n\");\n            (*env)->ExceptionDescribe (env);\n            error = TRUE;\n        }\n\n    }\n    if (error) {\n        // if there was an error initializing callbacks into agent, we disable wait,park and sleep tracking\n        waitTrackingEnabled = FALSE;\n        sleepTrackingEnabled = FALSE;\n        parkTrackingEnabled = FALSE;\n    }\n    trackingMethodsInitialized = TRUE;\n}\n\nvoid JNICALL native_method_bind_hook(\n            jvmtiEnv *jvmti_env,\n            JNIEnv* env,\n            jthread thread,\n            jmethodID method,\n            void* address,\n            void** new_address_ptr) {\n\n    jclass declaringClass;\n    char *className, *genericSignature, *methodName, *methodSig, *genericMethodSig;\n    int res;\n\n    if (env == NULL) {\n        return; // primordial phase\n    }\n\n    //fprintf (stderr, \"Going to call GetMethodDeclaringClass for methodId = %d\\n\", *(int*)method);\n\n    res = (*_jvmti)->GetMethodDeclaringClass(_jvmti, method, &declaringClass);\n    if (res != JVMTI_ERROR_NONE || declaringClass == NULL || *((int*)declaringClass) == 0) { /* Also a bug workaround */\n        fprintf(stderr, \"Profiler Agent Warning: Invalid declaringClass obtained from jmethodID\\n\");\n        fprintf(stderr, \"Profiler Agent Warning: mId = %p, *mId = %d\\n\", method, *(int*)method);\n        fprintf(stderr, \"Profiler Agent Warning: dCl = %p\", declaringClass);\n        if (declaringClass != NULL) {\n            fprintf(stderr, \", *dCl = %d\\n\", *((int*)declaringClass));\n        } else {\n            fprintf(stderr, \"\\n\");\n        }\n        //fprintf(stderr, \"*** res = %d\", res);\n        return;\n    }\n\n    //fprintf (stderr, \"Going to call GetClassSignature for methodId = %d, last res = %d, declaring class: %d\\n\", *(int*)method, res, *((int*)declaringClass));\n\n    res = (*_jvmti)->GetClassSignature(_jvmti, declaringClass, &className, &genericSignature);\n    if (res != JVMTI_ERROR_NONE) {\n        fprintf(stderr, \"Profiler Agent Warning: Couldn't obtain name of declaringClass = %p\\n\", declaringClass);\n        return;\n    }\n\n    //fprintf (stderr, \"Going to call GetMethodName for methodId = %d, last res = %d, signature: %s\\n\", *(int*)method, res, genericSignature);\n\n    res = (*_jvmti)->GetMethodName(_jvmti, method, &methodName, &methodSig, &genericMethodSig);\n\n    if (res != JVMTI_ERROR_NONE) {\n        fprintf(stderr, \"Profiler Agent Warning: Couldn't obtain name for methodID = %p\\n\", method);\n        return;\n    }\n\n    //fprintf (stderr, \"Method class: %s, method name: %s, sig: %s\\n\", className, methodName, methodSig);\n\n    // check for java.lang.Object.wait(long )\n    if (strcmp(\"Ljava/lang/Object;\",className)==0 && strcmp(\"wait\",methodName)==0 && strcmp(\"(J)V\",methodSig)==0) {\n        waitAddress = (waitCall)address;\n        *new_address_ptr = (void*) &waitInterceptor;\n        // fprintf(stderr, \"Profiler Agent: Object.wait intercepted.\\n\");\n    } else // check for java.lang.Thread.sleep(long )\n      if (strcmp(\"Ljava/lang/Thread;\",className)==0 && strcmp(\"sleep\",methodName)==0 && strcmp(\"(J)V\",methodSig)==0) {\n        sleepAddress = (sleepCall)address;\n        *new_address_ptr = (void*) &sleepInterceptor;\n        // fprintf(stderr, \"Profiler Agent: Thread.sleep intercepted.\\n\");\n    } else // check for sun.misc.Unsafe.park(boolean, long )\n      if (strcmp(\"Lsun/misc/Unsafe;\",className)==0 && strcmp(\"park\",methodName)==0 && strcmp(\"(ZJ)V\",methodSig)==0) {\n        parkAddress = (parkCall)address;\n        *new_address_ptr = (void*) &parkInterceptor;\n        // fprintf(stderr, \"Profiler Agent: Unsafe.park intercepted.\\n\");\n    }         \n\n    (*_jvmti)->Deallocate(_jvmti, (void*)className);\n\n    if (genericSignature != NULL) {\n        (*_jvmti)->Deallocate(_jvmti, (void*)genericSignature);\n    }\n\n    (*_jvmti)->Deallocate(_jvmti, (void*)methodName);\n    (*_jvmti)->Deallocate(_jvmti, (void*)methodSig);\n    if (genericMethodSig != NULL) {\n        (*_jvmti)->Deallocate(_jvmti, (void*)genericMethodSig);\n    }  \n}\n\n\nvoid JNICALL waitInterceptor (JNIEnv *env, jobject obj, jlong arg) {\n    jthrowable exception = NULL;\n    \n    if (waitTrackingEnabled) {\n        (*env)->CallStaticVoidMethod (env, profilerRuntimeID, waitEntryID, NULL);\n        (*env)->ExceptionDescribe (env);\n    }\n    \n    waitAddress(env, obj, arg);\n    \n    if (waitTrackingEnabled) {\n        // if an exception was thrown (InterruptedException), we need to catch and clear it for the exit handling\n        // and then rethrow\n        exception = (*env)->ExceptionOccurred (env);\n        if (exception != NULL) {\n            (*env)->ExceptionClear (env);\n        }\n        \n        (*env)->CallStaticVoidMethod (env, profilerRuntimeID, waitExitID, NULL);\n        (*env)->ExceptionDescribe (env);\n        \n        if (exception != NULL) {\n            (*env)->Throw (env, exception);\n        }\n    }\n}\n\nvoid JNICALL sleepInterceptor (JNIEnv *env, jclass clazz, jlong arg) {\n    jthrowable exception = NULL;\n    \n    if (sleepTrackingEnabled) {\n        (*env)->CallStaticVoidMethod (env, profilerRuntimeID, sleepEntryID, NULL);\n        (*env)->ExceptionDescribe (env);\n    }\n    \n    sleepAddress(env, clazz, arg);\n    \n    if (sleepTrackingEnabled) {\n        // if an exception was thrown (InterruptedException), we need to catch and clear it for the exit handling\n        // and then rethrow\n        exception = (*env)->ExceptionOccurred (env);\n        if (exception != NULL) {\n            (*env)->ExceptionClear (env);\n        }\n        \n        (*env)->CallStaticVoidMethod (env, profilerRuntimeID, sleepExitID, NULL);\n        (*env)->ExceptionDescribe (env);\n        \n        if (exception != NULL) {\n            (*env)->Throw (env, exception);\n        }\n    }\n}\n\nvoid JNICALL parkInterceptor (JNIEnv *env, jobject obj, jboolean arg0, jlong arg1) {\n    jthrowable exception = NULL;\n    \n    if (parkTrackingEnabled) {\n        (*env)->CallStaticVoidMethod (env, profilerRuntimeID, parkEntryID, NULL);\n        (*env)->ExceptionDescribe (env);\n    }\n    \n    parkAddress(env, obj, arg0, arg1);\n    \n    if (parkTrackingEnabled) {\n        // if an exception was thrown (InterruptedException), we need to catch and clear it for the exit handling\n        // and then rethrow\n        exception = (*env)->ExceptionOccurred (env);\n        if (exception != NULL) {\n            (*env)->ExceptionClear (env);\n        }\n        \n        (*env)->CallStaticVoidMethod (env, profilerRuntimeID, parkExitID, NULL);\n        (*env)->ExceptionDescribe (env);\n        \n        if (exception != NULL) {\n            (*env)->Throw (env, exception);\n        }\n    }\n}\n\nvoid JNICALL monitor_contended_enter_hook(\n            jvmtiEnv *jvmti_env,\n            JNIEnv* jni_env,\n            jthread thread,\n            jobject object) {\n\n    if (!trackingMethodsInitialized) {\n        initializeMethods (jni_env);\n    }\n  \n    if (waitTrackingEnabled || lockContentionMonitoringEnabled) {\n        jthread owner = NULL;\n        if (lockContentionMonitoringEnabled) {\n            owner = getOwner(jvmti_env, object);\n        }\n        (*jni_env)->CallStaticVoidMethod (jni_env, profilerRuntimeID, monitorEntryID, thread, object, owner);\n        (*jni_env)->ExceptionDescribe (jni_env);\n    }\n}\n\nvoid JNICALL monitor_contended_entered_hook(\n            jvmtiEnv *jvmti_env,\n            JNIEnv* jni_env,\n            jthread thread,\n            jobject object) {\n\n    if (!trackingMethodsInitialized) {\n        initializeMethods (jni_env);\n    }\n    \n    if (waitTrackingEnabled || lockContentionMonitoringEnabled) {\n        (*jni_env)->CallStaticVoidMethod (jni_env, profilerRuntimeID, monitorExitID, thread, object);\n        (*jni_env)->ExceptionDescribe (jni_env);\n    }\n}\n\nvoid JNICALL vm_object_alloc(jvmtiEnv *jvmti_env,\n            JNIEnv* jni_env,\n            jthread thread,\n            jobject object,\n            jclass object_klass,\n            jlong size) {\n    jthrowable exception = NULL;\n\n    if (jni_env == NULL) {\n        return; // primordial phase\n    }\n\n    if (!trackingMethodsInitialized) {\n        initializeMethods (jni_env);\n    }\n    // if an exception was thrown, we need to catch and clear it for the exit handling\n    // and then rethrow\n    exception = (*jni_env)->ExceptionOccurred (jni_env);\n    if (exception != NULL) {\n        (*jni_env)->ExceptionClear (jni_env);\n    }\n    (*jni_env)->CallStaticVoidMethod (jni_env, profilerRuntimeID, traceVMObjectAllocID, object, object_klass);\n    (*jni_env)->ExceptionDescribe (jni_env);\n\n    if (exception != NULL) {\n        (*jni_env)->Throw (jni_env, exception);\n    }\n}\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    setParkTrackingEnabled\n * Signature: (Z)Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_setParkTrackingEnabled\n  (JNIEnv *env, jclass clazz, jboolean value) {\n\n    if (!trackingMethodsInitialized) {\n        initializeMethods (env);\n    }  \n    if (parkAddress != NULL && parkEntryID != NULL && parkExitID != NULL) {\n        parkTrackingEnabled = value;\n        return TRUE;\n    }\n    return FALSE;\n}\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    setLockContentionMonitoringEnabled\n * Signature: (Z)Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_setLockContentionMonitoringEnabled\n  (JNIEnv *env, jclass clazz, jboolean value) {\n\n    lockContentionMonitoringEnabled = value;\n    return TRUE;\n}\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    setWaitTrackingEnabled\n * Signature: (Z)Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_setWaitTrackingEnabled\n  (JNIEnv *env, jclass clazz, jboolean value) {\n    if (!trackingMethodsInitialized) {\n        initializeMethods (env);\n    }  \n    if (waitAddress != NULL && waitEntryID != NULL && waitExitID != NULL && monitorEntryID != NULL && monitorExitID != NULL) {\n        waitTrackingEnabled = value;\n        return TRUE;\n    }\n    return FALSE;\n}\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    setSleepTrackingEnabled\n * Signature: (Z)Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_setSleepTrackingEnabled\n  (JNIEnv *env, jclass clazz, jboolean value) {\n    if (!trackingMethodsInitialized) {\n        initializeMethods (env);\n    }  \n    if (sleepAddress != NULL && sleepEntryID != NULL && sleepExitID != NULL) {\n        sleepTrackingEnabled = value;\n        return TRUE;\n    }\n    return FALSE;\n}\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    setVMObjectAllocEnabled\n * Signature: (Z)Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_setVMObjectAllocEnabled\n  (JNIEnv *env, jclass clazz, jboolean value) {\n    jvmtiError res;\n    jvmtiEventMode mode;\n\t\n    if (value) {\n        mode = JVMTI_ENABLE;\n    } else {\n        mode = JVMTI_DISABLE;\n    }\n    res = (*_jvmti)->SetEventNotificationMode(_jvmti, mode, JVMTI_EVENT_VM_OBJECT_ALLOC, NULL);\n    assert(res == JVMTI_ERROR_NONE);\n    return TRUE;\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/common_functions.c",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/*\n * author Ian Formanek\n *        Tomas Hurka\n *        Misha Dimitiev\n */\n\n#include <assert.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"jvmti.h\"\n\n#include \"common_functions.h\"\n\njvmtiEnv            *_jvmti;\njvmtiEventCallbacks *_jvmti_callbacks;\n\nstatic jlong _nano_time;\nstatic jvmtiEventCallbacks _jvmti_callbacks_static;\n\n/** A convenience function for the high-resolution timer */\njlong get_nano_time() {\n    (*_jvmti)->GetTime(_jvmti, &_nano_time);\n    return _nano_time;\n}\n\n\n/** Report the correct usage in case we think the user is trying to launch the VM on its own */\nvoid report_usage() {\n    fprintf(stderr, \"Profiler Agent: -agentpath:<PATH>/profilerinterface should be called with two parameters:\\n\");\n    fprintf(stderr, \"Profiler Agent: path to Profiler agent libraries and port number, separated by comma, for example:\\n\");\n    fprintf(stderr, \"Profiler Agent: java -agentpath:/mypath/profilerinterface=/home/me/nb-profiler-server/profiler-ea-libs,5140\\n\");\n}\n\nstatic void initializeJVMTI(JavaVM *jvm) {\n    jvmtiError err;\n    jvmtiCapabilities capas;\n    jint res;\n\n    /* Obtain the JVMTI environment to be used by this agent */\n#ifdef JNI_VERSION_1_6\n    (*jvm)->GetEnv(jvm, (void**)&_jvmti, JVMTI_VERSION_1_1);\n#else\n    (*jvm)->GetEnv(jvm, (void**)&_jvmti, JVMTI_VERSION_1_0);\n#endif\n\n    /* Enable runtime class redefinition capability */\n    err = (*_jvmti)->GetCapabilities(_jvmti, &capas);\n    assert(err == JVMTI_ERROR_NONE);\n    capas.can_redefine_classes = 1;\n#ifdef JNI_VERSION_1_6\n    capas.can_retransform_classes = 1;\n#endif\n    capas.can_generate_garbage_collection_events = 1;\n    capas.can_generate_native_method_bind_events = 1;\n    capas.can_generate_monitor_events = 1;\n    capas.can_get_current_thread_cpu_time = 1;\n    capas.can_generate_vm_object_alloc_events = 1;\n    capas.can_get_monitor_info = 1;\n    err = (*_jvmti)->AddCapabilities(_jvmti, &capas);\n    if (err != JVMTI_ERROR_NONE) {\n        fprintf(stderr, \"Profiler Agent Error: Failed to obtain JVMTI capabilities, error code: %d\\n\", err);\n    }\n\n    /* Zero out the callbacks data structure for future use*/\n    _jvmti_callbacks = &_jvmti_callbacks_static;\n    memset(_jvmti_callbacks, 0, sizeof(jvmtiEventCallbacks));\n\n    /* Enable class load hook event, that captures class file bytes for classes loaded by non-system loaders */\n    _jvmti_callbacks->ClassFileLoadHook = class_file_load_hook;\n    _jvmti_callbacks->NativeMethodBind = native_method_bind_hook;\n    _jvmti_callbacks->MonitorContendedEnter = monitor_contended_enter_hook;\n    _jvmti_callbacks->MonitorContendedEntered = monitor_contended_entered_hook;\n    _jvmti_callbacks->VMObjectAlloc = vm_object_alloc;\n    res = (*_jvmti)->SetEventCallbacks(_jvmti, _jvmti_callbacks, sizeof(*_jvmti_callbacks));\n    assert (res == JVMTI_ERROR_NONE);\n\n    res = (*_jvmti)->SetEventNotificationMode(_jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);\n    assert(res == JVMTI_ERROR_NONE);\n\n    res = (*_jvmti)->SetEventNotificationMode(_jvmti, JVMTI_ENABLE, JVMTI_EVENT_NATIVE_METHOD_BIND, NULL);\n    assert(res == JVMTI_ERROR_NONE);\n\n    res = (*_jvmti)->SetEventNotificationMode(_jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTER, NULL);\n    assert(res == JVMTI_ERROR_NONE);\n\n    res = (*_jvmti)->SetEventNotificationMode(_jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, NULL);\n    assert(res == JVMTI_ERROR_NONE);\n}\n\n/* The VM calls this function when the native library is loaded (for example, through System.loadLibrary). */\nJNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {\n    if (_jvmti == NULL) {\n        fprintf(stdout, \"Profiler Agent: JNI OnLoad Initializing...\\n\");\n\n        initializeJVMTI(jvm);\n    \n        fprintf(stdout, \"Profiler Agent: JNI OnLoad Initialized successfully\\n\");\n    }\n    return JNI_VERSION_1_2;\n}\n\n/** This function is called automatically upon agent startup */\nJNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {\n    fprintf(stdout, \"Profiler Agent: Initializing...\\n\");\n\n    initializeJVMTI(jvm);\n\n    if (options != NULL) {\n      fprintf (stdout, \"Profiler Agent: Options: >%s<\\n\", options);\n    } else {\n      fprintf (stdout, \"Profiler Agent: No options\\n\");\n    }    \n\n    /* If it looks like the VM was started not from the tool, but on its own, e.g. like\n    java -agentpath:/blahblah/profilerinterface=/foobar/profiler-ea-libs,5140\n    do some sanity checks for options and then eable the VM init event, so that we can start\n    our Java agent when the VM is initialized */\n    if (options != NULL && strlen(options) > 0) { /* The spec says no options means options == \"\", but in reality it's NULL */\n        if (strpbrk(options, \",\") == NULL) {\n            report_usage();\n            return -1;\n        } else {  /* We believe the options are correct */\n            parse_options_and_extract_params(options);\n            _jvmti_callbacks->VMInit = vm_init_hook;\n            (*_jvmti)->SetEventCallbacks(_jvmti, _jvmti_callbacks, sizeof(*_jvmti_callbacks));\n            (*_jvmti)->SetEventNotificationMode(_jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);\n        }\n    } // in case of calibration, the arguments are just empty, this is OK\n\n    fprintf(stdout, \"Profiler Agent: Initialized successfully\\n\");\n    return 0;\n}\n\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/common_functions.h",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nextern jvmtiEnv            *_jvmti;\nextern jvmtiEventCallbacks *_jvmti_callbacks;\n\njlong get_nano_time();\n\nvoid JNICALL class_file_load_hook(\n            jvmtiEnv *jvmti_env,\n            JNIEnv* jni_env,\n            jclass class_being_redefined,\n            jobject loader,\n            const char* name,\n            jobject protection_domain,\n            jint class_data_len,\n            const unsigned char* class_data,\n            jint* new_class_data_len,\n            unsigned char** new_class_data);\n\nvoid JNICALL native_method_bind_hook(\n            jvmtiEnv *jvmti_env,\n            JNIEnv* env,\n            jthread thread,\n            jmethodID method,\n            void* address,\n            void** new_address_ptr);\n\nvoid JNICALL monitor_contended_enter_hook(\n            jvmtiEnv *jvmti_env,\n            JNIEnv* jni_env,\n            jthread thread,\n            jobject object);\n\nvoid JNICALL monitor_contended_entered_hook(\n            jvmtiEnv *jvmti_env,\n            JNIEnv* jni_env,\n            jthread thread,\n            jobject object);\n\nvoid JNICALL vm_object_alloc(\n            jvmtiEnv *jvmti_env,\n            JNIEnv* jni_env,\n            jthread thread,\n            jobject object,\n            jclass object_klass,\n            jlong size);\n\ntypedef void (JNICALL *waitCall) (JNIEnv *env, jobject obj, jlong arg);\ntypedef void (JNICALL *sleepCall) (JNIEnv *env, jclass clazz, jlong arg);\ntypedef void (JNICALL *parkCall) (JNIEnv *env, jclass clazz, jboolean arg0, jlong arg1);\n\nvoid JNICALL waitInterceptor(JNIEnv *env, jobject obj, jlong arg);\nvoid JNICALL sleepInterceptor(JNIEnv *env, jclass clazz, jlong arg);\nvoid JNICALL parkInterceptor(JNIEnv *env, jclass clazz, jboolean arg0, jlong arg1);\n\nvoid get_saved_class_file_bytes(JNIEnv *env, char *name, jobject loader, jint *class_data_len, unsigned char **class_data);\n\nvoid try_removing_bytes_for_unloaded_classes(JNIEnv *env);\n\nvoid cache_loaded_classes(jvmtiEnv *jvmti_env,jclass *classes,jint class_count); \n\nvoid JNICALL vm_init_hook(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread);\n\nvoid parse_options_and_extract_params(char *options);\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/org_graalvm_visualvm_lib_jfluid_server_system_Classes.h",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/* DO NOT EDIT THIS FILE - it is machine generated */\n#include <jni.h>\n/* Header for class org_graalvm_visualvm_lib_jfluid_server_system_Classes */\n\n#ifndef _Included_org_graalvm_visualvm_lib_jfluid_server_system_Classes\n#define _Included_org_graalvm_visualvm_lib_jfluid_server_system_Classes\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    getAllLoadedClasses\n * Signature: ()[Ljava/lang/Class;\n */\nJNIEXPORT jobjectArray JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_getAllLoadedClasses\n  (JNIEnv *, jclass);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    cacheLoadedClasses\n * Signature: ([Ljava/lang/Class;I)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_cacheLoadedClasses\n  (JNIEnv *, jclass, jobjectArray, jint);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    getCachedClassFileBytes\n * Signature: (Ljava/lang/Class;)[B\n */\nJNIEXPORT jbyteArray JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_getCachedClassFileBytes\n  (JNIEnv *, jclass, jclass);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    enableClassLoadHook\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_enableClassLoadHook\n  (JNIEnv *, jclass);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    disableClassLoadHook\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_disableClassLoadHook\n  (JNIEnv *, jclass);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    getObjectSize\n * Signature: (Ljava/lang/Object;)J\n */\nJNIEXPORT jlong JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_getObjectSize\n  (JNIEnv *, jclass, jobject);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    setWaitTrackingEnabled\n * Signature: (Z)Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_setWaitTrackingEnabled\n  (JNIEnv *, jclass, jboolean);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    setParkTrackingEnabled\n * Signature: (Z)Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_setParkTrackingEnabled\n  (JNIEnv *, jclass, jboolean);\n\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    setSleepTrackingEnabled\n * Signature: (Z)Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_setSleepTrackingEnabled\n  (JNIEnv *, jclass, jboolean);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    setLockContentionMonitoringEnabled\n * Signature: (Z)Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_setLockContentionMonitoringEnabled\n  (JNIEnv *, jclass, jboolean);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    setVMObjectAllocEnabled\n * Signature: (Z)Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_setVMObjectAllocEnabled\n  (JNIEnv *, jclass, jboolean);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    notifyAboutClassLoaderUnloading\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_notifyAboutClassLoaderUnloading\n  (JNIEnv *, jclass);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Classes\n * Method:    doRedefineClasses\n * Signature: ([Ljava/lang/Class;[[B)I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Classes_doRedefineClasses\n  (JNIEnv *, jclass, jobjectArray, jobjectArray);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/org_graalvm_visualvm_lib_jfluid_server_system_Classes_RedefineException.h",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/* DO NOT EDIT THIS FILE - it is machine generated */\n#include <jni.h>\n/* Header for class org_graalvm_visualvm_lib_jfluid_server_system_Classes_RedefineException */\n\n#ifndef _Included_org_graalvm_visualvm_lib_jfluid_server_system_Classes_RedefineException\n#define _Included_org_graalvm_visualvm_lib_jfluid_server_system_Classes_RedefineException\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n#undef org_graalvm_visualvm_lib_jfluid_server_system_Classes_RedefineException_serialVersionUID\n#define org_graalvm_visualvm_lib_jfluid_server_system_Classes_RedefineException_serialVersionUID -3042686055658047285i64\n#undef org_graalvm_visualvm_lib_jfluid_server_system_Classes_RedefineException_serialVersionUID\n#define org_graalvm_visualvm_lib_jfluid_server_system_Classes_RedefineException_serialVersionUID -3387516993124229948i64\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/org_graalvm_visualvm_lib_jfluid_server_system_GC.h",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/* DO NOT EDIT THIS FILE - it is machine generated */\n#include <jni.h>\n/* Header for class org_graalvm_visualvm_lib_jfluid_server_system_GC */\n\n#ifndef _Included_org_graalvm_visualvm_lib_jfluid_server_system_GC\n#define _Included_org_graalvm_visualvm_lib_jfluid_server_system_GC\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_GC\n * Method:    activateGCEpochCounter\n * Signature: (Z)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_activateGCEpochCounter\n  (JNIEnv *, jclass, jboolean);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_GC\n * Method:    resetGCEpochCounter\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_resetGCEpochCounter\n  (JNIEnv *, jclass);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_GC\n * Method:    getCurrentGCEpoch\n * Signature: ()I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_getCurrentGCEpoch\n  (JNIEnv *, jclass);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_GC\n * Method:    objectsAdjacent\n * Signature: (Ljava/lang/Object;Ljava/lang/Object;)Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_objectsAdjacent\n  (JNIEnv *, jclass, jobject, jobject);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_GC\n * Method:    getGCRelativeTimeMetrics\n * Signature: ([J)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_getGCRelativeTimeMetrics\n  (JNIEnv *, jclass, jlongArray);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_GC\n * Method:    getGCStartFinishTimes\n * Signature: ([J[J)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_getGCStartFinishTimes\n  (JNIEnv *, jclass, jlongArray, jlongArray);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_GC\n * Method:    runGC\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_GC_runGC\n  (JNIEnv *, jclass);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/org_graalvm_visualvm_lib_jfluid_server_system_HeapDump.h",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/* DO NOT EDIT THIS FILE - it is machine generated */\n#include <jni.h>\n/* Header for class org_graalvm_visualvm_lib_jfluid_server_system_HeapDump */\n\n#ifndef _Included_org_graalvm_visualvm_lib_jfluid_server_system_HeapDump\n#define _Included_org_graalvm_visualvm_lib_jfluid_server_system_HeapDump\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_HeapDump\n * Method:    initialize15\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_HeapDump_initialize15\n  (JNIEnv *, jclass);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_HeapDump\n * Method:    takeHeapDump15Native\n * Signature: (Ljava/lang/String;)I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_HeapDump_takeHeapDump15Native\n  (JNIEnv *, jclass, jstring);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/org_graalvm_visualvm_lib_jfluid_server_system_Stacks.h",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/* DO NOT EDIT THIS FILE - it is machine generated */\n#include <jni.h>\n/* Header for class org_graalvm_visualvm_lib_jfluid_server_system_Stacks */\n\n#ifndef _Included_org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n#define _Included_org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n * Method:    getCurrentJavaStackDepth\n * Signature: (Ljava/lang/Thread;)I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Stacks_getCurrentJavaStackDepth\n  (JNIEnv *, jclass, jobject);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n * Method:    getCurrentStackFrameIds\n * Signature: (Ljava/lang/Thread;I[I)I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Stacks_getCurrentStackFrameIds\n  (JNIEnv *, jclass, jobject, jint, jintArray);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n * Method:    getMethodNamesForJMethodIds\n * Signature: (I[I[I)[B\n */\nJNIEXPORT jbyteArray JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Stacks_getMethodNamesForJMethodIds\n  (JNIEnv *, jclass, jint, jintArray, jintArray);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n * Method:    getAllStackTraces\n * Signature: ([[Ljava/lang/Thread;[[I[[[I)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Stacks_getAllStackTraces\n  (JNIEnv *, jclass, jobjectArray, jobjectArray, jobjectArray);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n * Method:    clearNativeStackFrameBuffer\n * Signature: ()V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Stacks_clearNativeStackFrameBuffer\n  (JNIEnv *, jclass);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Stacks\n * Method:    createNativeStackFrameBuffer\n * Signature: (I)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Stacks_createNativeStackFrameBuffer\n  (JNIEnv *, jclass, jint);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/org_graalvm_visualvm_lib_jfluid_server_system_Threads.h",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/* DO NOT EDIT THIS FILE - it is machine generated */\n#include <jni.h>\n/* Header for class org_graalvm_visualvm_lib_jfluid_server_system_Threads */\n\n#ifndef _Included_org_graalvm_visualvm_lib_jfluid_server_system_Threads\n#define _Included_org_graalvm_visualvm_lib_jfluid_server_system_Threads\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    recordProfilerOwnThreads\n * Signature: (ZLjava/lang/Thread;)I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_recordProfilerOwnThreads\n  (JNIEnv *, jclass, jboolean, jobject);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    recordAdditionalProfilerOwnThread\n * Signature: (Ljava/lang/Thread;)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_recordAdditionalProfilerOwnThread\n  (JNIEnv *, jclass, jobject);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    getTotalNumberOfThreads\n * Signature: ()I\n */\nJNIEXPORT jint JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_getTotalNumberOfThreads\n  (JNIEnv *, jclass);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    suspendTargetAppThreads\n * Signature: (Ljava/lang/Thread;)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_suspendTargetAppThreads\n  (JNIEnv *, jclass, jobject);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    resumeTargetAppThreads\n * Signature: (Ljava/lang/Thread;)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_resumeTargetAppThreads\n  (JNIEnv *, jclass, jobject);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    terminateTargetAppThreads\n * Signature: (Ljava/lang/Object;)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_terminateTargetAppThreads\n  (JNIEnv *, jclass, jobject);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    targetAppThreadsExist\n * Signature: ()Z\n */\nJNIEXPORT jboolean JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_targetAppThreadsExist\n  (JNIEnv *, jclass);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    getAllThreads\n * Signature: ([Ljava/lang/Thread;)[Ljava/lang/Thread;\n */\nJNIEXPORT jobjectArray JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_getAllThreads\n  (JNIEnv *, jclass, jobjectArray);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    getThreadsStatus\n * Signature: ([Ljava/lang/Thread;[I)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_getThreadsStatus\n  (JNIEnv *, jclass, jobjectArray, jintArray);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    getJVMArguments\n * Signature: ()Ljava/lang/String;\n */\nJNIEXPORT jstring JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_getJVMArguments\n  (JNIEnv *, jclass);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Threads\n * Method:    getJavaCommand\n * Signature: ()Ljava/lang/String;\n */\nJNIEXPORT jstring JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Threads_getJavaCommand\n  (JNIEnv *, jclass);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/org_graalvm_visualvm_lib_jfluid_server_system_Timers.h",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n/* DO NOT EDIT THIS FILE - it is machine generated */\n#include <jni.h>\n/* Header for class org_graalvm_visualvm_lib_jfluid_server_system_Timers */\n\n#ifndef _Included_org_graalvm_visualvm_lib_jfluid_server_system_Timers\n#define _Included_org_graalvm_visualvm_lib_jfluid_server_system_Timers\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n#ifdef CVM\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Timers\n * Method:    getCurrentTimeInCounts\n * Signature: ()J\n */\nJNIEXPORT jlong JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Timers_getCurrentTimeInCounts\n  (JNIEnv *, jclass);\n\n#endif\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Timers\n * Method:    getThreadCPUTimeInNanos\n * Signature: ()J\n */\nJNIEXPORT jlong JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Timers_getThreadCPUTimeInNanos\n  (JNIEnv *, jclass);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Timers\n * Method:    osSleep\n * Signature: (I)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Timers_osSleep\n  (JNIEnv *, jclass, jint);\n\n/*\n * Class:     org_graalvm_visualvm_lib_jfluid_server_system_Timers\n * Method:    enableMicrostateAccounting\n * Signature: (Z)V\n */\nJNIEXPORT void JNICALL Java_org_graalvm_visualvm_lib_jfluid_server_system_Timers_enableMicrostateAccounting\n  (JNIEnv *, jclass, jboolean);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/windows/version.h",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#define COMPANY \"Oracle Corporation\"\n#define COMPONENT \"NetBeans Profiler\"\n#define VER \"8.0.0.0\"\n#define FVER 8,0,0,0\n#define BUILD_ID \"22102013\"\n#define INTERNAL_NAME \"profilerinterface\"\n#define COPYRIGHT \"\\xA9 2007, 2013, Oracle and/or its affiliates. All rights reserved.\"\n#define FNAME \"profilerinterface.dll\"\n#define NAME \"NetBeans Profiler 8.0\"\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/native/src-jdk15/windows/version.rc",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#include <winuser.h>\n#include <winver.h>\n#include \"version.h\"\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// Version\n//\n\nVS_VERSION_INFO VERSIONINFO\n FILEVERSION    FVER\n PRODUCTVERSION FVER\n FILEFLAGSMASK 0x3fL\n#ifdef _DEBUG\n FILEFLAGS 0x1L\n#else\n FILEFLAGS 0x0L\n#endif\n // FILEOS 0x4 is Win32, 0x40004 is Win32 NT only\n FILEOS 0x4L\n // FILETYPE should be 0x1 for .exe and 0x2 for .dll\n FILETYPE 0x2L\n FILESUBTYPE 0x0L\nBEGIN\n    BLOCK \"StringFileInfo\"\n    BEGIN\n        BLOCK \"000004b0\"\n        BEGIN\n            VALUE \"CompanyName\",      COMPANY       \"\\0\"\n            VALUE \"FileDescription\",  COMPONENT     \"\\0\"\n            VALUE \"FileVersion\",      VER           \"\\0\"\n            VALUE \"Full Version\",     BUILD_ID      \"\\0\"\n            VALUE \"InternalName\",     INTERNAL_NAME \"\\0\"\n            VALUE \"LegalCopyright\",   COPYRIGHT     \"\\0\"\n            VALUE \"OriginalFilename\", FNAME         \"\\0\"\n            VALUE \"ProductName\",      NAME          \"\\0\"\n            VALUE \"ProductVersion\",   VER           \"\\0\"\n        END\n    END\n    BLOCK \"VarFileInfo\"\n    BEGIN\n        VALUE \"Translation\", 0x0, 1200\n    END\nEND\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.lib.jfluid-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/nbproject/genfiles.properties",
    "content": "# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=fb436b0f\nnbproject/build-impl.xml.script.CRC32=6e330c8c\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/nbproject/project.properties",
    "content": "# Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nis.autoload=true\nsrc15.dir=src-jdk15\nsrccvm.dir=src-cvm\n\n# timeout 100 minutes\ntest.timeout=6000000\ntest.excludes=**/profilingpoints/*Test.class\ntest.config.stable.includes=**/ProfilerStableTestSuite.class\ntest.config.stableBTD.includes=**/*Test.class\ntest.config.stableBTD.excludes=\\\n    org/graalvm/visualvm/lib/jfluid/tests/**/*,\\\n    **/HeapTest.class\ntest-qa-functional-sys-prop.java.awt.headless=true\n\nbuild15.classes.dir=${build.dir}/jdk15/classes/\nbuildcvm.classes.dir=${build.dir}/cvm/classes/\njfluid.server.jar=lib/jfluid-server.jar\njfluid.server.15.jar=lib/jfluid-server-15.jar\njfluid.server.cvm.jar=lib/jfluid-server-cvm.jar\ncp.extra=${build15.classes.dir}:${tools.jar}\n\nextra.module.files=\\\n    ${jfluid.server.jar},\\\n    ${jfluid.server.15.jar},\\\n    ${jfluid.server.cvm.jar}\nnbm.executable.files=\\\n    **/*.so,\\\n    remote-pack-defs/*.sh\n\njavac.source=1.8\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n            <suite-component/>\n            <module-dependencies/>\n            <test-dependencies>\n                <test-type>\n                    <name>unit</name>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.libs.junit4</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                </test-type>\n                <test-type>\n                    <name>qa-functional</name>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.libs.junit4</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.modules.nbjunit</code-name-base>\n                        <recursive/>\n                        <compile-dependency/>\n                    </test-dependency>\n                    <test-dependency>\n                        <code-name-base>org.openide.modules</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                </test-type>\n            </test-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.application.views</friend>\n                <friend>org.graalvm.visualvm.core</friend>\n                <friend>org.graalvm.visualvm.heapdump</friend>\n                <friend>org.graalvm.visualvm.heapviewer</friend>\n                <friend>org.graalvm.visualvm.heapviewer.truffle</friend>\n                <friend>org.graalvm.visualvm.jfr</friend>\n                <friend>org.graalvm.visualvm.jfr.streaming</friend>\n                <friend>org.graalvm.visualvm.lib.common</friend>\n                <friend>org.graalvm.visualvm.lib.profiler</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.api</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.attach</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.heapwalker</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.oql</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.snaptracer</friend>\n                <friend>org.graalvm.visualvm.lib.ui</friend>\n                <friend>org.graalvm.visualvm.modules.appui</friend>\n                <friend>org.graalvm.visualvm.profiler</friend>\n                <friend>org.graalvm.visualvm.profiling</friend>\n                <friend>org.graalvm.visualvm.sampler</friend>\n                <friend>org.graalvm.visualvm.sampler.truffle</friend>\n                <package>org.graalvm.visualvm.lib.jfluid</package>\n                <package>org.graalvm.visualvm.lib.jfluid.classfile</package>\n                <package>org.graalvm.visualvm.lib.jfluid.client</package>\n                <package>org.graalvm.visualvm.lib.jfluid.filters</package>\n                <package>org.graalvm.visualvm.lib.jfluid.global</package>\n                <package>org.graalvm.visualvm.lib.jfluid.instrumentation</package>\n                <package>org.graalvm.visualvm.lib.jfluid.jps</package>\n                <package>org.graalvm.visualvm.lib.jfluid.marker</package>\n                <package>org.graalvm.visualvm.lib.jfluid.results</package>\n                <package>org.graalvm.visualvm.lib.jfluid.results.coderegion</package>\n                <package>org.graalvm.visualvm.lib.jfluid.results.cpu</package>\n                <package>org.graalvm.visualvm.lib.jfluid.results.cpu.cct</package>\n                <package>org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes</package>\n                <package>org.graalvm.visualvm.lib.jfluid.results.cpu.marking</package>\n                <package>org.graalvm.visualvm.lib.jfluid.results.jdbc</package>\n                <package>org.graalvm.visualvm.lib.jfluid.results.locks</package>\n                <package>org.graalvm.visualvm.lib.jfluid.results.memory</package>\n                <package>org.graalvm.visualvm.lib.jfluid.results.monitor</package>\n                <package>org.graalvm.visualvm.lib.jfluid.results.threads</package>\n                <package>org.graalvm.visualvm.lib.jfluid.utils</package>\n                <package>org.graalvm.visualvm.lib.jfluid.utils.formatting</package>\n                <package>org.graalvm.visualvm.lib.jfluid.wireprotocol</package>\n            </friend-packages>\n            <extra-compilation-unit>\n                <package-root>${src15.dir}</package-root>\n                <classpath>${build.classes.dir}</classpath>\n                <built-to>${build15.classes.dir}</built-to>\n                <built-to>${cluster}/${jfluid.server.15.jar}</built-to>\n            </extra-compilation-unit>\n            <extra-compilation-unit>\n                <package-root>${srccvm.dir}</package-root>\n                <classpath/>\n                <built-to>${buildcvm.classes.dir}</built-to>\n                <built-to>${cluster}/${jfluid.server.cvm.jar}</built-to>\n            </extra-compilation-unit>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/../..\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/META-INF/services/org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCCTProvider",
    "content": "org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCallGraphBuilder"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/META-INF/services/org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCCTProvider$Listener",
    "content": "org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileBuilder"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/META-INF/services/org.graalvm.visualvm.lib.jfluid.results.cpu.CPUProfilingResultListener",
    "content": "org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCallGraphBuilder\norg.graalvm.visualvm.lib.jfluid.results.locks.LockGraphBuilder$CPULockGraphBuilder\norg.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcGraphBuilder"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/META-INF/services/org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileBuilder",
    "content": "org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileBuilder"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/META-INF/services/org.graalvm.visualvm.lib.jfluid.results.cpu.cct.CCTResultsFilter",
    "content": "org.graalvm.visualvm.lib.jfluid.results.cpu.cct.CCTResultsFilter"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/META-INF/services/org.graalvm.visualvm.lib.jfluid.results.cpu.cct.TimeCollector",
    "content": "org.graalvm.visualvm.lib.jfluid.results.cpu.cct.TimeCollector"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/META-INF/services/org.graalvm.visualvm.lib.jfluid.results.cpu.marking.MarkingEngine$StateObserver",
    "content": "org.graalvm.visualvm.lib.jfluid.results.cpu.cct.TimeCollector"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/META-INF/services/org.graalvm.visualvm.lib.jfluid.results.locks.LockProfilingResultListener",
    "content": "org.graalvm.visualvm.lib.jfluid.results.locks.LockGraphBuilder\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/META-INF/services/org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCCTProvider",
    "content": "org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCallGraphBuilder"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/META-INF/services/org.graalvm.visualvm.lib.jfluid.results.memory.MemoryProfilingResultsListener",
    "content": "org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCallGraphBuilder\norg.graalvm.visualvm.lib.jfluid.results.locks.LockGraphBuilder$MemoryLockGraphBuilder\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/Bundle.properties",
    "content": "# Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Name=Java Profiler (JFluid)\nProfilerClient_CannotOpenServerTempFileMsg=Cannot open temporary communication file created at the server side.\\nName\\: {0}\nProfilerClient_PerformingInstrumentationString=Performing instrumentation, please wait...\nProfilerClient_InvalidCodeRegionMsg=Invalid location was specified for code region instrumentation.\\nInstrumentation cannot be performed.\nProfilerClient_ClassNotFoundMsg=Could not find class {0} on the class path.\\nInstrumentation cannot be performed.\nProfilerClient_OutOfMemoryMsg=Too much data collected - the profiler ran out of memory.\\nCollected profiling data has been deleted and profiling resumed.\\nTo avoid this error please increase the -Xmx value\\nin the etc/visualvm.conf file in VisualVM directory\\nor lower the amount of details in profiling settings.\nProfilerClient_IncorrectAgentVersionMsg=Warning\\: The profiler agent you are connecting to is a different version than this profiler.\\nYou may encounter errors and unexpected behavior.\nProfilerClient_ErrorGettingCalibrationDataMsg=Error when retrieving saved calibration data for target JVM\\:\\n{0}\nProfilerClient_MustCalibrateFirstMsg=Since you did not run the Profiler on this machine or target JVM before,\\ndeleted the saved calibration data, or this data is corrupt, profiling will STOP now.\\n\\nYou have to run the calibration command for your target JVM\\nbefore running the Profiler with it again.\\nThe obtained calibration data will be saved and re-used\\non subsequent runs, so you will not see this message anymore.\\n\\nTo perform the calibration, use\\n\\\"Tools | Options | Profiling | Manage calibration data\\\".\\n\\n\n# HTML-formatted\nProfilerClient_MustCalibrateFirstShortMsg=<html><b>Calibration data missing.</b><br><br>Profiling cannot be started on this JDK. Please perform<br>profiler calibration first and start profiling again.</html>\n# HTML-formatted\nProfilerClient_InstrumentationLimitReachedMsg=<html><b>The limit of 64K instrumented methods has been reached.</b><br><br>The profiler cannot instrument more methods, some of your code<br>will not be profiled.<br><br>To avoid this problem, limit the number of profiled classes by<br>changing the profiling roots and/or instrumentation filter.</html>\nProfilerClient_CorruptedTargetCalibrationDataMsg=Problem with saved calibration data on target machine\\:\\n{0}\nProfilerClient_ConnectVmMsg=Connecting to the target VM...\nProfilerClient_TargetJvmErrorMsg=Target JVM terminated unexpectedly or does not respond.\\nWhen tried to send a message to it, got an IOException\\:\\n{0}\nProfilerClient_UnsupportedJvmMsg=Since the application you are trying to profile runs on {0} VM not supported by the Profiler, profiling will STOP now.\\n\\nPlease use 1.5.0 VM (Update 4 and higher) or 1.6.0 VM starting from build 26.\n\nTargetAppRunner_ClasspathSettingsIgnoredMsg=The value of '-classpath' specified through 'Profile/Edit Settings' menu will be ignored.\\nYou should specify the class path through 'File/Set class path' menu.\nTargetAppRunner_ErrorStartingJvmMsg=When starting target JVM, with command: {0}, caught an exception\\: {1}\nTargetAppRunner_CalibrationSummaryShortMsg=The calibration was successful.\\nClick Show Details to see calibration results.\\n\\nWarning\\: If your computer uses dynamic CPU frequency switching,\\nplease disable it and rerun calibration as changing the CPU frequency\\nduring profiling would produce inaccurate results.\nTargetAppRunner_CalibrationSummaryDetailsMsg=Some of the obtained calibration data is as follows\\:\\n\\n\nTargetAppRunner_FailedEstablishConnMsg=Failed to establish socket connection with the target JVM.\nTargetAppRunner_UnexpectedProblemStartingAppMsg=Unexpected problem when trying to start target application\\:\\n\nTargetAppRunner_JvmTerminatedNotRespondString=Target VM terminated or does not respond\nTargetAppRunner_InternalProblemString=Internal problem\nTargetAppRunner_FailedStartAppCauseMsg=Failed to start the target application. Cause\\:\\n{0}\nTargetAppRunner_CalibrationResultsMsg=Approximate time in one methodEntry()/methodExit() call pair\\:\\nWhen getting absolute timestamp only\\: {0} microseconds\\nWhen getting thread CPU timestamp only\\: {1} microseconds\\nWhen getting both timestamps\\: {2} microseconds\\n\\nApproximate time in one methodEntry()/methodExit() call pair\\nin sampled instrumentation mode\\: {3} microseconds\\n\nTargetAppRunner_CalibrationErrorMsg=Data transfer error during instrumentation calibration\nTargetAppRunner_InternalStatisticsOnlyMsg=This is internal statistics that should be used only to estimate the efficiency\\nof CPU profiling implementation. It is not for end-user results measurements.\\n\\n\nTargetAppRunner_InstrMethodsCountMsg=Instrumented/hotswapped total of {0} methods\nTargetAppRunner_ClassLoadFirstInvCountMsg=Issued {0} class load events, {1} first method invocation events\nTargetAppRunner_NonEmptyImgCountMsg=Issued {0} non-empty InstrumentMethodGroup responses\nTargetAppRunner_EmptyImgCountMsg=Issued {0} empty InstrumentMethodGroup responses\nTargetAppRunner_SingleImgCountMsg=Issued {0} single method InstrumentMethodGroup responses\nTargetAppRunner_AvgMethodTimeMsg=Average time per method group hotswapping/instrumentation operation\\: {0} ms.\nTargetAppRunner_MinMethodTimeMsg=Minimum time per method group hotswapping/instrumentation operation\\: {0} ms.\nTargetAppRunner_MaxMethodTimeMsg=Maximum time per method group hotswapping/instrumentation operation\\: {0} ms.\nTargetAppRunner_TotalRunTimeMsg=Total run time\\: {0} ms.\nTargetAppRunner_InjInstrTimeMsg=Time spent in injected instrumentation code for displayed thread\\: {0} ms ({1} %)\nTargetAppRunner_TotalInstrHotSwapTimeMsg=Total time spent in instrumentation/hotswapping in server\\: {0} ms ({1} %)\nTargetAppRunner_ByteCodeCommTimeMsg=Time spent in bytecode analysis/rewriting and wire communication in client\\: {0} ms ({1} %)\nTargetAppRunner_ClientByteCodeTimeMsg=Time spent in bytecode analysis/rewriting in client\\: {0} ms\nTargetAppRunner_ClientDiskProcessTimeMsg=Time spent in disk I/O and results processing in client\\: {0} ms ({1} %)\nTargetAppRunner_ClientResultsProcessTimeMsg=Time spent in results processing in client\\: {0} ms.\nTargetAppRunner_PerformingCalibrationMsg=Performing calibration, please wait...\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/ProfilerClient.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.net.ConnectException;\nimport java.net.Socket;\nimport java.text.MessageFormat;\nimport java.util.*;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\nimport org.graalvm.visualvm.lib.jfluid.client.AppStatusHandler;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.client.MonitoredData;\nimport org.graalvm.visualvm.lib.jfluid.client.ProfilingPointsProcessor;\nimport org.graalvm.visualvm.lib.jfluid.client.RuntimeProfilingPoint;\nimport org.graalvm.visualvm.lib.jfluid.global.CalibrationDataFileIO;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.BadLocationException;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.InstrumentationException;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.Instrumentor;\nimport org.graalvm.visualvm.lib.jfluid.marker.Marker;\nimport org.graalvm.visualvm.lib.jfluid.results.EventBufferProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.EventBufferResultsProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.ProfilingResultsDispatcher;\nimport org.graalvm.visualvm.lib.jfluid.results.coderegion.CodeRegionResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.*;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadDump;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.*;\n\n\n/**\n * The interface between the tool and the profiling back end.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Adrian Mos\n * @author Ian Formanek\n */\npublic class ProfilerClient implements CommonConstants {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Thread for execution of commands that, due to limitations of our wire protocol, need to be executed such that\n     * the ServerListener thread doesn't stay blocked while these commands are executed. See executeInSeparateThread()\n     * above.\n     */\n    private class SeparateCmdExecutionThread extends Thread {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void run() {\n            setName(PROFILER_SEPARATE_EXEC_THREAD_NAME);\n\n            synchronized (execInSeparateThreadLock) {\n                while (true) {\n                    try {\n                        execInSeparateThreadLock.wait();\n                    } catch (InterruptedException ex) {\n                        MiscUtils.internalError(\"ProfilerClient.SpecialExecutionThread.run()\"); // NOI18N\n                    }\n\n                    if (execInSeparateThreadCmd == null) {\n                        return; // It was a signal to this thread to terminate\n                    }\n\n                    Command cmd = execInSeparateThreadCmd;\n                    execInSeparateThreadCmd = null;\n\n                    switch (cmd.getType()) {\n                        case Command.ROOT_CLASS_LOADED:\n                            instrumentMethodGroupFromRoot((RootClassLoadedCommand) cmd);\n\n                            break;\n                        case Command.CLASS_LOADED:\n                        case Command.METHOD_INVOKED_FIRST_TIME:\n                        case Command.METHOD_LOADED:\n                            instrumentMethodGroupFollowUp(cmd);\n\n                            break;\n                        case Command.EVENT_BUFFER_DUMPED:\n                            EventBufferDumpedCommand bufferDumpedCmd = ((EventBufferDumpedCommand) cmd);\n                            byte[] buf = EventBufferProcessor.readDataAndPrepareForProcessing(bufferDumpedCmd);\n                            \n                            EventBufferResultsProvider.getDefault().dataReady(buf, getCurrentInstrType());\n                            sendSimpleRespToServer(true, null);\n\n                            break;\n                        case Command.CLASS_LOADER_UNLOADING:\n\n                            // We have to grab the forceObtainedResultsDumpLock to prevent forceObtainedResultsDump() coming in while\n                            // we are processing the data, sending the request for dump to the server that currently awaits the\n                            // request for jmethodIds, and thus creating a \"distributed deadlock\".\n                            synchronized (ProfilerClient.this) {\n                                synchronized (forceObtainedResultsDumpLock) {\n                                    if (memCctProvider != null) {\n                                        memCctProvider.updateInternals();\n                                    }\n\n                                    sendSimpleRespToServer(true, null);\n                                }\n                            }\n\n                            break;\n                    }\n                }\n            }\n        }\n    }\n\n    private class ServerListener extends Thread {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private final Object startedFlagLock = new Object();\n\n        // @GuardedBy startedFlagLock\n        private int startedFlag = 0; // 0 = initial state; 1 = started; -1 = cancelled\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public boolean isRunning() {\n            synchronized (startedFlagLock) {\n                return startedFlag == 1;\n            }\n        }\n\n        public void cancel() {\n            synchronized (startedFlagLock) {\n                startedFlag = -1;\n                startedFlagLock.notifyAll();\n            }\n        }\n\n        public void run() {\n            // Wait until we know that the connection is open\n            synchronized (startedFlagLock) {\n                while (startedFlag == 0) { // while the state hasn't been explicitly changed\n\n                    try {\n                        startedFlagLock.wait(500);\n                    } catch (InterruptedException e) {\n                        startedFlag = -1; // thread has been interrupet = effectively cancelled\n                    }\n                }\n\n                if (startedFlag == -1) { // cancelled\n\n                    return;\n                }\n            }\n            \n            startSeparateCmdExecThread();\n            try {\n                while (targetVMAlive) {\n                    try {\n                        Object o = wireIO.receiveCommandOrResponse();\n\n                        //System.out.println(\">>> Got response or command from server \" + o);\n                        if (o == null) {\n                            closeConnection();\n                        } else {\n                            if (o instanceof Command) {\n                                handleServerCommand((Command) o);\n                            } else {\n                                setLastResponse((Response) o);\n                            }\n                        }\n                    } catch (IOException ex) {\n                        if (targetVMAlive && !terminateOrDetachCommandIssued) { // It wasn't a normal connection shutdown\n                            MiscUtils.printErrorMessage(\"exception while trying to get response from the target JVM:\\n\" + ex); // NOI18N\n                            closeConnection();\n\n                            //            serverCommandHandler.handleServerCommand(null); // does not seem to do anything\n                        }\n                    }\n                }\n            } finally {\n                stopSeparateCmdExecThread();\n            }\n        }\n\n        public void shutdown() {\n            synchronized (startedFlagLock) {\n                startedFlag = 0;\n                startedFlagLock.notifyAll();\n            }\n        }\n\n        public void startRunning() {\n            synchronized (startedFlagLock) {\n                startedFlag = 1;\n                startedFlagLock.notifyAll();\n            }\n        }\n\n        private void handleServerCommand(final Command cmd) {\n            switch (cmd.getType()) {\n                case Command.SHUTDOWN_INITIATED:\n                    status.targetAppRunning = false;\n\n                    // Get and save the latest results and the internal statistics before the target VM goes away\n                    (new Thread() {\n                            public void run() {\n                                try {\n                                    if (currentInstrTypeIsRecursiveCPUProfiling() || currentInstrTypeIsMemoryProfiling()) {\n                                        forceObtainedResultsDump(false, 15);\n                                    }\n\n                                    // In case of memory profiling, fetch additional data from the VM - names for all jmethodIDs and\n                                    // object count\n                                    if (currentInstrTypeIsMemoryProfiling()) {\n                                        savedAllocatedObjectsCountResults = getAllocatedObjectsCountResults();\n                                        // #204978: methodIds must be loaded from instead of \n                                        // the MemoryCallGraphBuilder'shutdown' method where it is too late\n                                        if (memCctProvider instanceof MemoryCallGraphBuilder) {\n                                            ((MemoryCallGraphBuilder)memCctProvider).updateInternals();\n                                        }\n                                    }\n\n                                    status.savedInternalStats = getInternalStats();\n\n                                    appStatusHandler.handleShutdown();\n\n                                    sendSimpleCmdToServer(Command.SHUTDOWN_OK);\n                                } catch (ClientUtils.TargetAppOrVMTerminated ex) { /* Ignore silently */\n                                }\n                            }\n                        }).start();\n\n                    break;\n                case Command.SHUTDOWN_COMPLETED:\n                    targetVMAlive = false;\n                    status.targetAppRunning = false;\n                    EventBufferProcessor.removeEventBufferFile();\n\n                    break;\n                case Command.ROOT_CLASS_LOADED:\n                    executeInSeparateThread(cmd);\n\n                    break;\n                case Command.CLASS_LOADED:\n                case Command.METHOD_INVOKED_FIRST_TIME:\n                case Command.METHOD_LOADED:\n                    executeInSeparateThread(cmd);\n\n                    break;\n                case Command.EVENT_BUFFER_DUMPED:\n                    EventBufferDumpedCommand ebdCmd = (EventBufferDumpedCommand) cmd;\n                    String bufferName = ebdCmd.getEventBufferFileName();\n                    if (bufferName.length() > 0) {\n                        if (!EventBufferProcessor.bufFileExists()) {\n                            if (!EventBufferProcessor.setEventBufferFile(bufferName)) {\n                                appStatusHandler.displayError(MessageFormat.format(CANNOT_OPEN_SERVER_TEMPFILE_MSG,\n                                                                                   new Object[] { ebdCmd.getEventBufferFileName() }));\n                            }\n                        }\n                        resetJMethodIdTable();\n                    }\n                    readAndProcessProfilingResults(ebdCmd);\n\n                    break;\n                case Command.CLASS_LOADER_UNLOADING:\n                    executeInSeparateThread(cmd);\n\n                    break;\n                case Command.RESULTS_AVAILABLE:\n                    resultsStart = System.currentTimeMillis();\n\n                    break;\n                case Command.GET_CLASSID:\n\n                    GetClassIdCommand cidCmd = (GetClassIdCommand) cmd;\n                    int classId = instrumentor.getClassId(cidCmd.getClassName(), cidCmd.getClassLoaderId());\n                    sendComplexRespToServer(new GetClassIdResponse(classId != -1, classId));\n\n                    break;\n                case Command.STILL_ALIVE:\n                    break;\n            }\n\n            if (!targetVMAlive) {\n                closeConnection();\n            }\n\n            serverCommandHandler.handleServerCommand(cmd);\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String CANNOT_OPEN_SERVER_TEMPFILE_MSG;\n    private static final String PERFORMING_INSTRUMENTATION_STRING;\n    private static final String INVALID_CODE_REGION_MSG;\n    private static final String CLASS_NOT_FOUND_MSG;\n    private static final String OUT_OF_MEMORY_MSG;\n    private static final String INCORRECT_AGENT_VERSION_MSG;\n    private static final String ERROR_GETTING_CALIBRATION_DATA_MSG;\n    private static final String MUST_CALIBRATE_FIRST_MSG;\n    private static final String MUST_CALIBRATE_FIRST_SHORT_MSG;\n    private static final String INSTRUMENTATION_LIMIT_REACHED_MSG;\n    private static final String CORRUPTED_TARGET_CALIBRATION_DATA_MSG;\n    private static final String CONNECT_VM_MSG;\n    private static final String TARGET_JVM_ERROR_MSG;\n    private static final String UNSUPPORTED_JVM_MSG;\n\n    static {\n        ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.Bundle\"); // NOI18N\n        CANNOT_OPEN_SERVER_TEMPFILE_MSG = messages.getString(\"ProfilerClient_CannotOpenServerTempFileMsg\"); // NOI18N\n        PERFORMING_INSTRUMENTATION_STRING = messages.getString(\"ProfilerClient_PerformingInstrumentationString\"); // NOI18N\n        INVALID_CODE_REGION_MSG = messages.getString(\"ProfilerClient_InvalidCodeRegionMsg\"); // NOI18N\n        CLASS_NOT_FOUND_MSG = messages.getString(\"ProfilerClient_ClassNotFoundMsg\"); // NOI18N\n        OUT_OF_MEMORY_MSG = messages.getString(\"ProfilerClient_OutOfMemoryMsg\"); // NOI18N\n        INCORRECT_AGENT_VERSION_MSG = messages.getString(\"ProfilerClient_IncorrectAgentVersionMsg\"); // NOI18N\n        ERROR_GETTING_CALIBRATION_DATA_MSG = messages.getString(\"ProfilerClient_ErrorGettingCalibrationDataMsg\"); // NOI18N\n        MUST_CALIBRATE_FIRST_MSG = messages.getString(\"ProfilerClient_MustCalibrateFirstMsg\"); // NOI18N\n        MUST_CALIBRATE_FIRST_SHORT_MSG = messages.getString(\"ProfilerClient_MustCalibrateFirstShortMsg\"); // NOI18N\n        INSTRUMENTATION_LIMIT_REACHED_MSG = messages.getString(\"ProfilerClient_InstrumentationLimitReachedMsg\"); // NOI18N\n        CORRUPTED_TARGET_CALIBRATION_DATA_MSG = messages.getString(\"ProfilerClient_CorruptedTargetCalibrationDataMsg\"); // NOI18N\n        CONNECT_VM_MSG = messages.getString(\"ProfilerClient_ConnectVmMsg\"); // NOI18N\n        TARGET_JVM_ERROR_MSG = messages.getString(\"ProfilerClient_TargetJvmErrorMsg\"); // NOI18N\n        UNSUPPORTED_JVM_MSG = messages.getString(\"ProfilerClient_UnsupportedJvmMsg\"); // NOI18N\n    }\n    \n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private AppStatusHandler.ServerCommandHandler serverCommandHandler;\n    private AppStatusHandler appStatusHandler;\n    private CPUCCTProvider cpuCctProvider;\n    private Command execInSeparateThreadCmd;\n    private FlatProfileProvider flatProvider;\n    private InitiateProfilingCommand commandOnStartup = null;\n    private Instrumentor instrumentor;\n    private MemoryCCTProvider memCctProvider;\n    private JdbcCCTProvider jdbcCctProvider;\n    private final Object methodIdsTableLock = new Object();\n    private JMethodIdTable methodIdsTable;\n    private final Object execInSeparateThreadLock = new Object();\n    // To make dump processing and other commands mutually exclusive\n    final private Object forceObtainedResultsDumpLock = new Object();\n    // To make sure all instrumentation-related operations happen serially\n    private final Object instrumentationLock = new Object();\n    private final Object responseLock = new Object();\n    private ObjectInputStream socketIn;\n    private ObjectOutputStream socketOut;\n    private ProfilerEngineSettings settings;\n    private ProfilingSessionStatus status;\n    private ProfilingPointsProcessor profilingPointProcessor;\n    private volatile Response lastResponse;\n    private SeparateCmdExecutionThread separateCmdExecThread;\n    private ServerListener serverListener;\n    private HeapHistogramManager histogramManager;\n\n    //--------------------- Connection management --------------------\n    private Socket clientSocket;\n    private WireIO wireIO;\n\n    /**\n     * Needed to make memory profiling results available after app/VM shutdown\n     *\n     * Note that we don't have anything like getMemoryProfilingResult() here - essentially because we don't have memory\n     * results snapshots yet. Those, in turn, are not implemented because of performance concerns (reproducing our,\n     * potentially huge, hash table containing all tracked object, plus the call trees for these object allocations,\n     * every time that the user hits \"Get results\" seems scary). So instead of snapshots, we give the user various\n     * aspects of (constantly updated) memory profiling data on demand. Methods that return it are public ones in\n     * ObjAllocCallGraphBuilder, ObjLivenessCallGraphBuilder, and MemoryCallGraphBuilder.\n     * The getAllocatedObjectsCountResults() method below provides only one aspect of the memory profiling data.\n     */\n    private int[] savedAllocatedObjectsCountResults;\n    private volatile boolean forceObtainedResultsDumpCalled;\n    private volatile boolean handlingEventBufferDump;\n    private volatile boolean instrMethodsLimitReported;\n    private boolean serverClassesInitialized;\n    private volatile boolean targetVMAlive;\n    private volatile boolean terminateOrDetachCommandIssued;\n    private int currentAgentId = -1;\n    private long instrProcessingTime;\n    private long resultsStart;\n    private ClassRepository classRepo;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ProfilerClient(ProfilerEngineSettings settings, ProfilingSessionStatus status,\n            AppStatusHandler ash, ProfilingPointsProcessor ppp,\n                          AppStatusHandler.ServerCommandHandler sch) {\n        this.settings = settings;\n        this.status = status;\n        appStatusHandler = ash;\n        serverCommandHandler = sch;\n        classRepo = new ClassRepository();\n        instrumentor = new Instrumentor(classRepo, status, settings);\n        histogramManager = new HeapHistogramManager(settings);\n        EventBufferProcessor.initialize(this);\n        EventBufferResultsProvider.getDefault().addDispatcher(ProfilingResultsDispatcher.getDefault());\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns the array where element at index I is the total number of allocated objects for the class with I id.\n     * The relevant counters are kept at the server side and returned to the tool on demand, here.\n     */\n    public synchronized int[] getAllocatedObjectsCountResults()\n        throws ClientUtils.TargetAppOrVMTerminated {\n        if (!targetVMAlive) {\n            if (savedAllocatedObjectsCountResults != null) {\n                return savedAllocatedObjectsCountResults;\n            } else {\n                throw new ClientUtils.TargetAppOrVMTerminated(ClientUtils.TargetAppOrVMTerminated.VM);\n            }\n        }\n\n        savedAllocatedObjectsCountResults = null;\n        checkForTargetVMAlive();\n        sendSimpleCmdToServer(Command.GET_OBJECT_ALLOCATION_RESULTS);\n\n        ObjectAllocationResultsResponse resp = (ObjectAllocationResultsResponse) getAndCheckLastResponse(\"Unknown problem when trying to get allocated object count results.\"); // NOI18N\n\n        return resp.getResults();\n    }\n\n    /**\n     * Returns the snapshot of current multi-method CPU profiling results\n     *\n     * @return CPU Results snapshot\n     * @throws ClientUtils.TargetAppOrVMTerminated\n     *          In case the profiled application has already terminated\n     * @throws CPUResultsSnapshot.NoDataAvailableException\n     *          If no data are available yet\n     */\n    public synchronized CPUResultsSnapshot getCPUProfilingResultsSnapshot()\n        throws ClientUtils.TargetAppOrVMTerminated, CPUResultsSnapshot.NoDataAvailableException {\n        return getCPUProfilingResultsSnapshot(true);\n    }\n\n    /**\n     * Returns the snapshot of current multi-method CPU profiling results\n     *\n     * @param dump true to fetch latest events from server, false otherwise (use only available data)\n     * @return CPU Results snapshot\n     * @throws ClientUtils.TargetAppOrVMTerminated\n     *          In case the profiled application has already terminated\n     * @throws CPUResultsSnapshot.NoDataAvailableException\n     *          If no data are available yet\n     */\n    public CPUResultsSnapshot getCPUProfilingResultsSnapshot(boolean dump)\n        throws ClientUtils.TargetAppOrVMTerminated, CPUResultsSnapshot.NoDataAvailableException {\n        checkForTargetVMAlive();\n\n        if (dump) {\n            if (!forceObtainedResultsDump(false, 5)) {\n                return null;\n            }\n        }\n        synchronized (this) {\n            int len;\n            boolean twoTimeStamps;\n            String[] instrClassNames, instrMethodNames, instrMethodSigs;\n            try {\n                status.beginTrans(false);\n                twoTimeStamps = status.collectingTwoTimeStamps();\n                len = status.getNInstrMethods();\n                instrClassNames = new String[len];\n                System.arraycopy(status.getInstrMethodClasses(), 0, instrClassNames, 0, len);\n                instrMethodNames = new String[len];\n                System.arraycopy(status.getInstrMethodNames(), 0, instrMethodNames, 0, len);\n                instrMethodSigs = new String[len];\n                System.arraycopy(status.getInstrMethodSignatures(), 0, instrMethodSigs, 0, len);\n                return new CPUResultsSnapshot(resultsStart, System.currentTimeMillis(), cpuCctProvider, twoTimeStamps, instrClassNames, instrMethodNames, instrMethodSigs, len);\n            } finally {\n                status.endTrans();\n            }\n        }\n    }\n\n    /**\n     * Returns the snapshot of current code region profiling results\n     */\n    public synchronized CodeRegionResultsSnapshot getCodeRegionProfilingResultsSnapshot()\n        throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetVMAlive();\n        sendSimpleCmdToServer(Command.GET_CODE_REGION_CPU_RESULTS);\n\n        CodeRegionCPUResultsResponse resp = (CodeRegionCPUResultsResponse) getAndCheckLastResponse(\"Unknown problem when trying to get code region CPU results.\"); // NOI18N\n\n        return new CodeRegionResultsSnapshot(resultsStart, System.currentTimeMillis(), resp.getResults(),\n                                             status.timerCountsInSecond[0]);\n    }\n\n    public int getCurrentAgentId() {\n        return currentAgentId;\n    }\n\n    public void setCurrentInstrType(int type) {\n        status.currentInstrType = type;\n    }\n\n    public int getCurrentInstrType() {\n        return status.currentInstrType;\n    }\n\n    public ClassRepository getClassRepository() {\n        return classRepo;\n    }\n\n    public JMethodIdTable getJMethodIdTable() {\n        synchronized (methodIdsTableLock) {\n            if (methodIdsTable == null) {\n                methodIdsTable = new JMethodIdTable();\n            }\n            return methodIdsTable;\n        }\n    }\n\n    void resetJMethodIdTable() {\n        synchronized (methodIdsTableLock) {\n            methodIdsTable = null;\n        }\n    }\n\n    /**\n     * Determine which of the currently tracked threads are dead or alive. If the VM is not running, just returns null -\n     * it's clear that all threads are dead then.\n     */\n    public synchronized byte[] getCurrentThreadsLivenessStatus() {\n        try {\n            checkForTargetVMAlive();\n            sendSimpleCmdToServer(Command.GET_THREAD_LIVENESS_STATUS);\n\n            ThreadLivenessStatusResponse resp = (ThreadLivenessStatusResponse) getAndCheckLastResponse(\"Unknown problem when trying to get thread liveness information.\"); // NOI18N\n\n            return resp.getStatus();\n        } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n            if (serverListener.isRunning()) { // The possibly problematic situation is not known yet\n                ProfilerLogger.log(\"in getCurrentThreadLivenessStatus(), caught exception: \" + ex); // NOI18N\n            }\n\n            return null;\n        }\n    }\n\n    /**\n     * For the class with the given name and the initiating class loader (see Java Language/JVM Spec for definitions),\n     * find out and return the defining class loader. Both class loaders are internal class loader ids.\n     */\n    public synchronized int getDefiningClassLoaderId(String className, int initiatingLoaderId)\n                                              throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetVMAlive();\n\n        GetDefiningClassLoaderCommand cmd = new GetDefiningClassLoaderCommand(className, initiatingLoaderId);\n        sendComplexCmdToServer(cmd);\n\n        DefiningLoaderResponse resp = (DefiningLoaderResponse) getAndCheckLastResponse(\"Unknown problem when trying to get a defining loader for class\"); // NOI18N\n\n        return resp.getLoaderId();\n    }\n\n    public FlatProfileProvider getFlatProfileProvider() {\n        return flatProvider;\n    }\n\n    public long getInstrProcessingTime() {\n        return instrProcessingTime;\n    }\n\n    //---------------- Internal statistics and other target VM information obtaining ----------------\n    public synchronized InternalStatsResponse getInternalStats()\n        throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetVMAlive();\n        sendSimpleCmdToServer(Command.GET_INTERNAL_STATS);\n\n        InternalStatsResponse resp = (InternalStatsResponse) getLastResponse();\n\n        return resp;\n    }\n\n    public MemoryCCTProvider getMemoryCCTProvider() {\n        return memCctProvider;\n    }\n\n    /**\n     * Returns the snapshot of current Memory profiling results\n     *\n     * @return Memory Results snapshot\n     * @throws ClientUtils.TargetAppOrVMTerminated\n     *          In case the profiled application has already terminated\n     */\n    public MemoryResultsSnapshot getMemoryProfilingResultsSnapshot()\n        throws ClientUtils.TargetAppOrVMTerminated {\n        return getMemoryProfilingResultsSnapshot(true);\n    }\n\n    /**\n     * Returns the snapshot of current Memory profiling results\n     *\n     * @param dump true to fetch latest events from server, false otherwise (use only available data)\n     * @return Memory Results snapshot\n     * @throws ClientUtils.TargetAppOrVMTerminated\n     *          In case the profiled application has already terminated\n     */\n    public MemoryResultsSnapshot getMemoryProfilingResultsSnapshot(boolean dump)\n        throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetVMAlive();\n        int instrType = getCurrentInstrType();\n        \n        if (instrType == INSTR_NONE_MEMORY_SAMPLING) {\n            if (settings.getRunGCOnGetResultsInMemoryProfiling()) {\n                runGC();\n            }\n            return new SampledMemoryResultsSnapshot(resultsStart, System.currentTimeMillis(), this);\n        }\n        if (dump) {\n            if (!forceObtainedResultsDump(false, 5)) {\n                return null;\n            }\n        }\n\n        synchronized (this) {\n            memCctProvider.beginTrans(false);\n\n            try {\n                memCctProvider.updateInternals();\n\n                if (instrType == INSTR_OBJECT_ALLOCATIONS) {\n                    return new AllocMemoryResultsSnapshot(resultsStart, System.currentTimeMillis(), memCctProvider, this);\n                } else {\n                    return new LivenessMemoryResultsSnapshot(resultsStart, System.currentTimeMillis(), memCctProvider, this);\n                }\n            } finally {\n                memCctProvider.endTrans();\n            }\n        }\n    }\n\n   /**\n     * Returns the snapshot of current JDBC(Selects) profiling results\n     *\n     * @return JDBC Results snapshot\n     * @throws ClientUtils.TargetAppOrVMTerminated\n     *          In case the profiled application has already terminated\n     */\n    public JdbcResultsSnapshot getJdbcProfilingResultsSnapshot()\n        throws ClientUtils.TargetAppOrVMTerminated {\n        return getJdbcProfilingResultsSnapshot(true);\n    }\n\n    /**\n     * Returns the snapshot of current Memory profiling results\n     *\n     * @param dump true to fetch latest events from server, false otherwise (use only available data)\n     * @return Memory Results snapshot\n     * @throws ClientUtils.TargetAppOrVMTerminated\n     *          In case the profiled application has already terminated\n     */\n    public JdbcResultsSnapshot getJdbcProfilingResultsSnapshot(boolean dump)\n        throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetVMAlive();\n        if (dump) {\n            if (!forceObtainedResultsDump(false, 5)) {\n                return null;\n            }\n        }\n\n        synchronized (this) {\n            return new JdbcResultsSnapshot(resultsStart, System.currentTimeMillis(), jdbcCctProvider, this);\n        }\n    }\n    \n    public Marker getMethodMarker() {\n        return settings.getMethodMarker();\n    }\n\n    /**\n     * Called to obtain method names for jMethodIds, that we do not know method names of.\n     * This method is typically called when results are to be displayed, but also in case some classes are unloaded\n     * in the profiled application, as in this case we would lost method names for already accumulated results.\n     * <p>\n     * Assumption is that jMethodId is never reused inside the JVM.\n     *\n     * @param methodIds array of jMethodIds that we do not have names for\n     * @return the 4xn array, containing quadruplets of {class name, method name, method signature, native flag} strings for\n     *         given jmethodIds\n     */\n    public synchronized String[][] getMethodNamesForJMethodIds(int[] methodIds)\n        throws ClientUtils.TargetAppOrVMTerminated {\n        final int PACKEDARR_ITEMS = 4; // must match PACKEDARR_ITEMS in Stacks.c\n        checkForTargetVMAlive();\n\n        GetMethodNamesForJMethodIdsCommand cmd = new GetMethodNamesForJMethodIdsCommand(methodIds);\n        sendComplexCmdToServer(cmd);\n\n        MethodNamesResponse resp = (MethodNamesResponse) getAndCheckLastResponse(\"Unknown problem when trying to get method names for jmethodIds\"); // NOI18N\n\n        return StringUtils.convertPackedStringsIntoStringArrays(resp.getPackedData(), resp.getPackedArrayOffsets(), PACKEDARR_ITEMS);\n    }\n\n    public synchronized HeapHistogram getHeapHistogram() throws ClientUtils.TargetAppOrVMTerminated {\n        HeapHistogramResponse resp;\n        \n        checkForTargetVMAlive();\n        sendSimpleCmdToServer(Command.GET_HEAP_HISTOGRAM);\n        resp = (HeapHistogramResponse) getAndCheckLastResponse(\"Unknown problem when trying to get heap histogram\"); // NOI18N\n        return histogramManager.getHistogram(resp);\n    }\n    \n    public synchronized ThreadDump takeThreadDump() throws ClientUtils.TargetAppOrVMTerminated {\n        ThreadDumpResponse resp;\n        \n        checkForTargetVMAlive();\n        sendSimpleCmdToServer(Command.TAKE_THREAD_DUMP);\n        resp = (ThreadDumpResponse) getAndCheckLastResponse(\"Unknown problem when trying to take thread dump\"); // NOI18N\n        return new ThreadDump(resp.isJDK15(), resp.getTime(), resp.getThreads());\n    }\n\n    public synchronized byte[][] getCachedClassFileBytes(String[] classes, int[] classLoaderIds) throws ClientUtils.TargetAppOrVMTerminated {        \n        GetClassFileBytesResponse resp;\n        \n        checkForTargetVMAlive();\n        GetClassFileBytesCommand cmd = new GetClassFileBytesCommand(classes, classLoaderIds);\n        sendComplexCmdToServer(cmd);\n        resp = (GetClassFileBytesResponse) getAndCheckLastResponse(\"Unknown problem when trying to get cached class file bytes\"); // NOI18N\n        return resp.getClassBytes();\n    }\n\n    public synchronized MonitoredData getMonitoredData() {\n        try {\n            checkForTargetVMAlive();\n            sendSimpleCmdToServer(Command.GET_MONITORED_NUMBERS);\n\n            Response resp = getAndCheckLastResponse(\"Unknown problem when trying to get memory numbers.\"); // NOI18N\n\n            try {\n                MonitoredNumbersResponse mresp = (MonitoredNumbersResponse) resp;\n\n                return MonitoredData.getMonitoredData(getStatus(), mresp);\n            } catch (ClassCastException ex) {\n                // FIXME: this diagnostics stuff should be ultimately removed once the root cause of the problem is understood\n                MiscUtils.printErrorMessage(\"caught ClassCastException in getMonitoredNumbers. The real class of resp is \" // NOI18N\n                                            + resp.getClass().getName() + \", resp = \" + resp // NOI18N\n                                            );\n                throw ex;\n            }\n        } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n            if (serverListener.isRunning()) { // The possibly problematic situation is not known yet\n                ProfilerLogger.log(\"in getMonitoredData(), caught exception: \" + ex); // NOI18N\n            }\n\n            return null;\n        }\n    }\n\n    /**\n     * @return ProfilerEngineSettings current profiler engine settings\n     */\n    public ProfilerEngineSettings getSettings() {\n        return settings;\n    }\n\n    public ProfilingPointsProcessor getProfilingPointsProcessor() {\n        return profilingPointProcessor;\n    }\n\n    public ObjectInputStream getSocketInputStream() {\n        return socketIn;\n    }\n\n    public ProfilingSessionStatus getStatus() {\n        return status;\n    }\n\n    public synchronized boolean cpuResultsExist() throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetVMAlive();\n        sendSimpleCmdToServer(Command.CPU_RESULTS_EXIST);\n\n        Response resp = getAndCheckLastResponse(\"Unknown problem when trying to check for CPU profiling results.\"); // NOI18N\n\n        return resp.yes();\n    }\n\n    public boolean currentInstrTypeIsMemoryProfiling() {\n        return ((status.currentInstrType == INSTR_OBJECT_ALLOCATIONS) || (status.currentInstrType == INSTR_OBJECT_LIVENESS));\n    }\n\n    public boolean currentInstrTypeIsRecursiveCPUProfiling() {\n        return ((status.currentInstrType == INSTR_RECURSIVE_FULL) || (status.currentInstrType == INSTR_RECURSIVE_SAMPLED));\n    }\n\n    /**\n     * Removes instrumentation for classes with ids such that unprofiledClassStatusArray[id] == false.\n     * For these classes, no memory profiling data will be generated anymore.\n     */\n    public void deinstrumentMemoryProfiledClasses(boolean[] unprofiledClassStatusArray)\n                                           throws InstrumentationException, ClientUtils.TargetAppOrVMTerminated {\n        synchronized (instrumentationLock) {\n            if (getCurrentInstrType() == INSTR_NONE || getCurrentInstrType() == INSTR_NONE_SAMPLING) {\n                return;\n            }\n\n            Response resp;\n            checkForTargetAppRunning();\n\n            long curTime = System.currentTimeMillis();\n            InstrumentMethodGroupCommand cmd = instrumentor.getCommandToUnprofileClasses(unprofiledClassStatusArray);\n\n            if (!cmd.isEmpty()) {\n                synchronized (this) {\n                    // System.out.println(\"*** Profiler Engine: deinstrumentMemoryProfiledClasses() produced command:\"); cmd.dump();\n                    sendComplexCmdToServer(cmd);\n                    instrProcessingTime += (System.currentTimeMillis() - curTime);\n                    resp = getLastResponse();\n                }\n\n                if (!resp.isOK()) {\n                    throw new InstrumentationException(resp.getErrorMessage());\n                }\n            }\n        }\n    }\n\n    public void prepareDetachFromTargetJVM() throws ClientUtils.TargetAppOrVMTerminated {\n        while(true) {\n            // active waiting with released lock, this prevents deadlock if getDefiningClassLoaderId is\n            // called simultanously\n            synchronized(this) {\n                sendSimpleCmdToServer(Command.PREPARE_DETACH);\n                Response resp = getAndCheckLastResponse(\"prepareDetachFromTargetJVM\");\n                if(!resp.isOK()) {\n                    return;\n                }\n                if(resp.yes())\n                {\n                    break;\n                }\n            }\n            try {\n                Thread.sleep(2000);\n            } catch (InterruptedException ex) {\n                MiscUtils.printWarningMessage(\"Interrupted while waiting for prepare detach\");\n            }\n        }\n    }\n\n    public synchronized void detachFromTargetJVM() throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetVMAlive();\n        terminateOrDetachCommandIssued = true;\n        sendSimpleCmdToServer(Command.DETACH);\n\n        try {\n            getLastResponse();\n        } finally {\n            closeConnection();\n            EventBufferProcessor.removeEventBufferFile(); // Try again, just in case closeConnection returned without calling it\n        }\n    }\n\n    /**\n     * This is called in all modes, direct invoke or attachment, to establish connection with the target VM\n     * @param attachMode 0 = no attach, 1 = direct attach, 2 = dynamic attach\n     * @param calibrationOnlyRun connection in calibration mode only\n     * @param cancel shared cancel flag\n     */\n    public boolean establishConnectionWithServer(int attachMode, boolean calibrationOnlyRun, AtomicBoolean cancel) {\n        // Make sure we initialize this field early - it may be changed once we connect to the JVM and find out its\n        // real version.\n        status.targetJDKVersionString = settings.getTargetJDKVersionString();\n\n        return connectToServer(attachMode, calibrationOnlyRun, cancel);\n    }\n\n    /**\n     * Tells the server to send the contents of its data buffer to the tool immediately, no matter whether it's\n     * full or not.\n     */\n    public boolean forceObtainedResultsDump() throws ClientUtils.TargetAppOrVMTerminated {\n        return forceObtainedResultsDump(false, 0);\n    }\n\n    public boolean forceObtainedResultsDump(boolean liveResults, int retries)\n                                     throws ClientUtils.TargetAppOrVMTerminated {\n        boolean dumped = false;\n        int retryCounter = retries;\n\n        do {\n            dumped = forceObtainedResultsDump(liveResults);\n\n            if (!dumped) {\n                try {\n                    Thread.sleep(200);\n                } catch (InterruptedException e) {\n                    break;\n                }\n            }\n        } while (!dumped && (--retryCounter > 0));\n        // fix for Issue #135532\n        if (dumped) {\n             try {\n                Thread.sleep(200);\n            } catch (InterruptedException e) {\n            }\n        }\n        return dumped;\n    }\n\n    /**\n     * Tells the server to send the contents of its data buffer to the tool immediately, no matter whether it's\n     * full or not.\n     */\n    public boolean forceObtainedResultsDump(boolean liveResults)\n                                     throws ClientUtils.TargetAppOrVMTerminated {\n        // The locks below are in the special order, to prevent deadlocks\n        synchronized (this) {\n            synchronized (forceObtainedResultsDumpLock) {\n                if (handlingEventBufferDump) {\n                    return true; // If dump handling is already in progress, don't force the second dump\n                }\n\n                // no reason (and may be dangerous) to send another force dump command\n                checkForTargetVMAlive();\n                forceObtainedResultsDumpCalled = true;\n                sendSimpleCmdToServer(liveResults ? Command.DUMP_EXISTING_RESULTS_LIVE : Command.DUMP_EXISTING_RESULTS);\n\n                DumpResultsResponse resp = (DumpResultsResponse) getLastResponse();\n\n                if (resp.yes()) {\n                    status.dumpAbsTimeStamp = resp.getDumpAbsTimeStamp();\n                } else {\n                    if (ProfilerLogger.isDebug()) {\n                        ProfilerLogger.debug(\"Force Obtained Results - Received Dump Error \"); // NOI18N\n                    }\n                }\n\n                forceObtainedResultsDumpCalled = false;\n\n                return resp.yes();\n            }\n        }\n    }\n\n    /**\n     * This should be called to initiate code region instrumentation for specified code region.\n     * The data is remembered or sent to the server immediately if TA is already running. The actual instrumentation\n     * starts when server informs the tool that the class to be instrumented is loaded.\n     */\n    public void initiateCodeRegionInstrumentation(ClientUtils.SourceCodeSelection[] s)\n                                           throws ClassNotFoundException, BadLocationException, InstrumentationException,\n                                                  IOException, ClassFormatError, ClientUtils.TargetAppOrVMTerminated {\n        synchronized (instrumentationLock) {\n            removeAllInstrumentation();\n\n            if (status.targetAppRunning && status.remoteProfiling) {\n                if (!getCalibrationData(true)) {\n                    return;\n                }\n            }\n\n            instrumentor.setStatusInfoFromSourceCodeSelection(s);\n            instrumentor.setSavedSourceCodeSelection(s);\n\n            String className = instrumentor.getRootClassNames()[ProfilingSessionStatus.CODE_REGION_CLASS_IDX].replace('/', '.'); // NOI18N\n            InitiateProfilingCommand cmd = new InitiateProfilingCommand(INSTR_CODE_REGION, className, false,\n                                                                                    status.startProfilingPointsActive);\n            commandOnStartup = cmd;\n\n            setCurrentInstrType(INSTR_CODE_REGION);\n\n            if (status.targetAppRunning) {\n                sendSetInstrumentationParamsCmd(false);\n\n                String errorMessage = sendCommandAndGetResponse(commandOnStartup);\n\n                if (errorMessage != null) {\n                    appStatusHandler.displayWarning(errorMessage);\n                }\n            }\n        }\n    }\n\n    public void initiateMonitoring()  throws ClientUtils.TargetAppOrVMTerminated, InstrumentationException {\n         synchronized (instrumentationLock) {\n            removeAllInstrumentation();\n            InitiateProfilingCommand cmd = new InitiateProfilingCommand(INSTR_NONE);\n            commandOnStartup = cmd;\n            // just to be consistent, since removeAllInstrumentation()\n            // sets instrumentation type to INSTR_NONE\n            setCurrentInstrType(INSTR_NONE);\n\n            if (status.targetAppRunning) {\n                sendSetInstrumentationParamsCmd(false);\n\n                String errorMessage = sendCommandAndGetResponse(commandOnStartup);\n\n                if (errorMessage != null) {\n                    appStatusHandler.displayWarning(errorMessage);\n                }\n            }            \n         }\n    }\n\n    /**\n     * This should be called to initiate memory profiling instrumentation of specified type (object allocation or\n     * object liveness).\n     * The data is remembered or sent to the server immediately if TA is already running. The actual instrumentation\n     * starts when the TA is started and the first class of this app is loaded, or immediately if TA is already running.\n     */\n    public void initiateMemoryProfInstrumentation(int instrType)\n                                           throws ClientUtils.TargetAppOrVMTerminated, InstrumentationException {\n        synchronized (instrumentationLock) {\n            removeAllInstrumentation();\n\n            if (instrType == INSTR_NONE_MEMORY_SAMPLING) {\n                commandOnStartup = new InitiateProfilingCommand(INSTR_NONE_MEMORY_SAMPLING);\n            } else {\n                // Set this root class name irrespective of whether the target app has been started or not.\n                // If it's not yet started, then indeed instrumentation should be triggered by main class load event - otherwise\n                // the first loaded class that we register in the server is some reflection class loaded in process of main()\n                // invocation. It causes recursive invocations of classLoadHook() (because it also uses some reflection), thus\n                // screwing up the instrumentation procedure.\n                // If the target app is already running, then instrumentation starts immediately and isn't triggered by a class\n                // load event. However, if the same cmd that we build here is then re-used as commandOnStartup, it should again\n                // contain rootClassName.\n                String[] rootClassNames = new String[]{settings.getMainClassName()};\n                commandOnStartup = createInitiateInstrumnetation(instrType, rootClassNames, false, status.startProfilingPointsActive);\n\n            }\n            // See initiateRecursiveCPUProfInstrumentation for why it's important to setCurrentInstrType() early\n            setCurrentInstrType(instrType);\n\n            if (status.targetAppRunning) {\n                sendSetInstrumentationParamsCmd(false);\n\n                String errorMessage = sendCommandAndGetResponse(commandOnStartup);\n\n                if (errorMessage != null) {\n                    appStatusHandler.displayWarning(errorMessage);\n                }\n            }\n        }\n    }\n\n    /**\n     * This should be called to initiate CPU profiling instrumentation starting from specified root method(s).\n     * The data is remembered or sent to the server immediately if TA is already running. The actual instrumentation\n     * starts when server informs the tool that one of the classes to be instrumented is loaded.\n     */\n    public void initiateRecursiveCPUProfInstrumentation(ClientUtils.SourceCodeSelection[] s)\n                                                 throws ClassNotFoundException, BadLocationException, InstrumentationException,\n                                                        IOException, ClassFormatError, ClientUtils.TargetAppOrVMTerminated {\n        //    System.out.println(\"Initiating CPU instrumentation\");\n        //    for(int i=0;i<s.length;i++) {\n        //      System.out.println(s[i]);\n        //    }\n        synchronized (instrumentationLock) {\n            removeAllInstrumentation();\n\n            if (status.targetAppRunning && status.remoteProfiling) {\n                if (!getCalibrationData(true)) {\n                    return;\n                }\n            }\n\n            instrumentor.setStatusInfoFromSourceCodeSelection(s);\n\n            boolean instrSpawnedThreads = settings.getInstrumentSpawnedThreads();\n\n            String[] rootClassNames = instrumentor.getRootClassNames();\n            int instrType = (settings.getCPUProfilingType() == CPU_INSTR_FULL) ? INSTR_RECURSIVE_FULL : INSTR_RECURSIVE_SAMPLED;\n            InitiateProfilingCommand cmd = createInitiateInstrumnetation(instrType, rootClassNames,\n                                                                                    instrSpawnedThreads,\n                                                                                    status.startProfilingPointsActive);\n            commandOnStartup = cmd;\n            status.setTimerTypes(settings.getAbsoluteTimerOn(), settings.getThreadCPUTimerOn());\n\n            // It's important that we set current instr type *before* we make the following call. That's because,\n            // if targetAppRunning, at the server side all the operations in reaction to the commandOnStartup are performed\n            // in a separate thread. It appears that that thread may quickly send back the response with loaded classes etc..,\n            // and that may happen *before* we get response below and set currentInstrType. This fixes that\n            // (essentially, race condition) bug.\n            setCurrentInstrType(instrType);\n\n            if (status.targetAppRunning) {\n                sendSetInstrumentationParamsCmd(false);\n\n                String errorMessage = sendCommandAndGetResponse(commandOnStartup);\n\n                if (errorMessage != null) {\n                    appStatusHandler.displayWarning(errorMessage);\n                }\n            }\n        }\n    }\n\n    public void initiateCPUSampling() throws ClientUtils.TargetAppOrVMTerminated, InstrumentationException {\n         synchronized (instrumentationLock) {\n            removeAllInstrumentation();\n            InitiateProfilingCommand cmd = new InitiateProfilingCommand(INSTR_NONE_SAMPLING);\n            commandOnStartup = cmd;\n            status.setTimerTypes(settings.getAbsoluteTimerOn(), settings.getThreadCPUTimerOn());\n            setCurrentInstrType(INSTR_NONE_SAMPLING);\n\n            if (status.targetAppRunning) {\n                sendSetInstrumentationParamsCmd(false);\n\n                String errorMessage = sendCommandAndGetResponse(commandOnStartup);\n\n                if (errorMessage != null) {\n                    appStatusHandler.displayWarning(errorMessage);\n                }\n            }            \n         }\n    }\n\n    public synchronized boolean memoryResultsExist() {\n        return (getMemoryCCTProvider() != null) && (getMemoryCCTProvider().getStacksForClasses() != null);\n    }\n\n    /*\n     * A callback method to be executed at the beginning of profiling;\n     * will disappear once the snapshot generation routine is rewritten\n     */\n    public void registerCPUCCTProvider(CPUCCTProvider provider) {\n        cpuCctProvider = provider;\n    }\n\n    public void registerFlatProfileProvider(FlatProfileProvider provider) {\n        flatProvider = provider;\n    }\n\n    public void registerMemoryCCTProvider(MemoryCCTProvider provider) {\n        memCctProvider = provider;\n    }\n\n    public void registerJdbcCCTProvider(JdbcCCTProvider provider) {\n        jdbcCctProvider = provider;\n    }\n\n    public void removeAllInstrumentation(boolean cleanupClient)\n                                  throws InstrumentationException {\n        synchronized (instrumentationLock) {\n            commandOnStartup = null;\n\n            if (cleanupClient) {\n                status.resetInstrClassAndMethodInfo();\n            }\n\n            try {\n                clearPreviousInstrumentationInServer();\n            } catch (ClientUtils.TargetAppOrVMTerminated ex) { /* So be it */\n            }\n\n            setCurrentInstrType(INSTR_NONE);\n        }\n    }\n\n    public void removeAllInstrumentation() throws InstrumentationException {\n        removeAllInstrumentation(true);\n    }\n\n    /**\n     * If the target VM is terminated, cleans up all locally cached data so that they can be\n     * GCd from the memory. If the TA is running, this method does nothing.\n     */\n    public void resetClientData() {\n        if (targetJVMIsAlive()) {\n            return; // we should not do any of the following in this case\n        }\n\n        status.resetInstrClassAndMethodInfo();\n        instrumentor.resetPerVMInstanceData();\n    }\n\n    public synchronized void resetProfilerCollectors()\n                                              throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetVMAlive();\n        sendSimpleCmdToServer(Command.RESET_PROFILER_COLLECTORS);\n        getAndCheckLastResponse(\"Unknown problem when trying to reset profiler collectors.\"); // NOI18N\n    }\n\n    public synchronized void resumeTargetAppThreads() throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetAppRunning();\n        sendSimpleCmdToServer(Command.RESUME_TARGET_APP);\n        getAndCheckLastResponse(\"Unknown problem when trying to resume app threads.\"); // NOI18N\n    }\n\n    public synchronized void runGC() throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetVMAlive();\n        sendSimpleCmdToServer(Command.RUN_GC);\n        getAndCheckLastResponse(\"Unknown problem when trying to run GC\"); // NOI18N\n    }\n\n    public void sendSetInstrumentationParamsCmd(boolean changeableOnly)\n                                         throws ClientUtils.TargetAppOrVMTerminated {\n        SetChangeableInstrParamsCommand cmd = new SetChangeableInstrParamsCommand(settings.isLockContentionMonitoringEnabled(),\n                                                                                  settings.getNProfiledThreadsLimit(),\n                                                                                  settings.getMaxStringLength(),\n                                                                                  settings.getStackDepthLimit(),\n                                                                                  settings.getSamplingInterval(),\n                                                                                  settings.getAllocTrackEvery(),\n                                                                                  settings.getAllocStackTraceLimit(),\n                                                                                  settings.getRunGCOnGetResultsInMemoryProfiling(),\n                                                                                  settings.getExcludeWaitTime(),\n                                                                                  settings.getExcludeWaitTime(),\n                                                                                  settings.isThreadsSamplingEnabled(),\n                                                                                  settings.getSamplingFrequency());\n\n        String errorMessage = sendCommandAndGetResponse(cmd);\n\n        if (errorMessage != null) {\n            appStatusHandler.displayWarning(errorMessage);\n        }\n\n        if (!changeableOnly) {\n            SetUnchangeableInstrParamsCommand cmd1 = new SetUnchangeableInstrParamsCommand(status.remoteProfiling,\n                                                                                           settings.getAbsoluteTimerOn(),\n                                                                                           settings.getThreadCPUTimerOn(),\n                                                                                           settings.getInstrScheme(),\n                                                                                           settings.getCodeRegionCPUResBufSize());\n            errorMessage = sendCommandAndGetResponse(cmd1);\n\n            if (errorMessage != null) {\n                appStatusHandler.displayWarning(errorMessage);\n            }\n        }\n    }\n\n    /**\n     * This method is called both when the application is started by the tool, and when the tool attaches to a running\n     * application.\n     * It's called *after* the establishConnectionWithServer() above.\n     * sendExplicitStartCommand actually determines the mode - it's true if we really start the VM as opposed to\n     * attaching.\n     */\n    public boolean startTargetApp(boolean sendExplicitStartCommand)\n                           throws ClientUtils.TargetAppOrVMTerminated, ClientUtils.TargetAppFailedToStart {\n        status.resetInstrClassAndMethodInfo();\n        instrumentor.resetPerVMInstanceData();\n        status.setTimerTypes(settings.getAbsoluteTimerOn(), settings.getThreadCPUTimerOn());\n        serverCommandHandler.handleServerCommand(null); // To reset the displayed figures\n        checkForTargetVMAlive();\n        instrProcessingTime = 0;\n        instrMethodsLimitReported = false;\n\n        // Special treatment of the case when instrumentation type is changed between runs by simply\n        // switching a button in Settings\n        if (currentInstrTypeIsRecursiveCPUProfiling()) {\n            setCurrentInstrType((settings.getCPUProfilingType() == CPU_INSTR_FULL) ? INSTR_RECURSIVE_FULL : INSTR_RECURSIVE_SAMPLED);\n\n            if (commandOnStartup != null) {\n                commandOnStartup.setInstrType(getCurrentInstrType());\n            }\n        }\n\n        if (commandOnStartup != null) {\n            // Always set the current instrumentation parameters first\n            sendSetInstrumentationParamsCmd(false);\n\n            switch (getCurrentInstrType()) {\n                case INSTR_CODE_REGION:\n\n                    if (status.remoteProfiling && !getCalibrationData(true)) {\n                        try {\n                            terminateTargetJVM();\n                        } catch (ClientUtils.TargetAppOrVMTerminated e) {\n                        }\n\n                        return false;\n                    }\n\n                    break;\n                case INSTR_RECURSIVE_FULL:\n                case INSTR_RECURSIVE_SAMPLED:\n\n                    if (status.remoteProfiling && !getCalibrationData(true)) {\n                        try {\n                            terminateTargetJVM();\n                        } catch (ClientUtils.TargetAppOrVMTerminated e) {\n                        }\n\n                        return false;\n                    }\n\n                    if (settings.getInstrumentMethodInvoke()) {\n                        String error = sendSimpleCommandAndGetResponse(Command.INSTRUMENT_REFLECTION);\n\n                        if (error != null) {\n                            throw new ClientUtils.TargetAppFailedToStart(error);\n                        }\n                    }\n\n                    break;\n            }\n\n            String errorMessage = sendCommandAndGetResponse(commandOnStartup);\n\n            if (errorMessage != null) {\n                appStatusHandler.displayWarning(\"Profiler Agent Error: \" + errorMessage); // NOI18N\n            }\n\n            commandOnStartup = null;\n        } else {\n            // Needed to e.g. prevent initiateProfiling() called later from attempting to\n            // remove instrumentation from VM.\n            setCurrentInstrType(INSTR_NONE);\n        }\n\n        if (sendExplicitStartCommand) {\n            String error = sendSimpleCommandAndGetResponse(Command.START_TARGET_APP);\n\n            if (error != null) {\n                throw new ClientUtils.TargetAppFailedToStart(error);\n            }\n        }\n\n        status.targetAppRunning = true;\n        checkForInstrMethodsLimitReached();\n        EventBufferResultsProvider.getDefault().startup(this);\n\n        return true;\n    }\n\n    //---------------- Target Application Thread Management ----------------\n    public synchronized void suspendTargetAppThreads()\n                                              throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetAppRunning();\n        sendSimpleCmdToServer(Command.SUSPEND_TARGET_APP);\n        getAndCheckLastResponse(\"Unknown problem when trying to suspend app threads.\"); // NOI18N\n    }\n\n    public synchronized boolean takeHeapDump(String outputFile)\n                                      throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetVMAlive();\n        sendComplexCmdToServer(new TakeHeapDumpCommand(outputFile));\n\n        Response resp = getAndCheckLastResponse(\"takeHeapDump.\"); // NOI18N\n\n        return resp.isOK();\n    }\n\n    public boolean targetAppIsRunning() {\n        return status.targetAppRunning;\n    }\n\n    public boolean targetJVMIsAlive() {\n        return targetVMAlive;\n    }\n\n    //---------------- Target Application/JVM Status Management ----------------\n    public synchronized void terminateTargetJVM() throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetVMAlive();\n        terminateOrDetachCommandIssued = true;\n        sendSimpleCmdToServer(Command.TERMINATE_TARGET_JVM);\n\n        if (!getLastResponse().isOK()) {\n            throw new ClientUtils.TargetAppOrVMTerminated(ClientUtils.TargetAppOrVMTerminated.VM,\n                                                          \"Target JVM terminated or not responding\" // NOI18N\n            );\n        }\n\n        closeConnection();\n    }\n\n    private synchronized Response getAndCheckLastResponse(String errMessage)\n                                                   throws ClientUtils.TargetAppOrVMTerminated {\n        Response resp = getLastResponse();\n\n        if (!resp.isOK()) {\n            MiscUtils.printErrorMessage(\"error in getAndCheckLastResponse: for \" + resp + \" got error message: \" // NOI18N\n                                        + resp.getErrorMessage() + \" and context message \" + errMessage // NOI18N\n                                        );\n        }\n\n        return resp;\n    }\n\n    private synchronized boolean getCalibrationData(boolean getStoredData)\n                                             throws ClientUtils.TargetAppOrVMTerminated {\n        int cmdType = getStoredData ? Command.GET_STORED_CALIBRATION_DATA : Command.RUN_CALIBRATION_AND_GET_DATA;\n        sendSimpleCmdToServer(cmdType);\n\n        Response resp = getLastResponse();\n\n        if (!resp.isOK()) {\n            String msg = resp.getErrorMessage();\n\n            if (getStoredData) {\n                msg = MessageFormat.format(CORRUPTED_TARGET_CALIBRATION_DATA_MSG, new Object[] { msg });\n            }\n\n            appStatusHandler.displayError(msg);\n\n            return false;\n        }\n\n        CalibrationDataResponse cdr = (CalibrationDataResponse) resp;\n        status.methodEntryExitCallTime = cdr.getMethodEntryExitCallTime();\n        status.methodEntryExitInnerTime = cdr.getMethodEntryExitInnerTime();\n        status.methodEntryExitOuterTime = cdr.getMethodEntryExitOuterTime();\n        status.timerCountsInSecond = cdr.getTimerCountsInSecond();\n\n        return true;\n    }\n\n    private void setLastResponse(Response r) {\n        synchronized (responseLock) {\n            lastResponse = r;\n\n            try {\n                responseLock.notify();\n            } catch (IllegalMonitorStateException ex) {\n                MiscUtils.internalError(\"ProfilerClient.setLastResponse()\"); // NOI18N\n            }\n        }\n    }\n\n    private synchronized Response getLastResponse() throws ClientUtils.TargetAppOrVMTerminated {\n        Response res;\n        \n        checkForTargetVMAlive();\n        synchronized (responseLock) {\n            while (lastResponse == null) {\n                long start = System.currentTimeMillis();\n                \n                try {\n                    responseLock.wait(60000);\n                } catch (InterruptedException ex) {\n                    MiscUtils.internalError(\"InterruptedException in ProfilerClient.getLastResponse()\"); // NOI18N\n                }\n                \n                // If we have been waiting for above number of milliseconds and got no response, assume that we timed out\n                // and target JVM is dead\n                if (!targetVMAlive) {\n                    status.targetAppRunning = false;\n                    throw new ClientUtils.TargetAppOrVMTerminated(ClientUtils.TargetAppOrVMTerminated.VM);\n                } else if (lastResponse == null && wireIO.wasAlive()<start) { // timed out\n                    if (!appStatusHandler.confirmWaitForConnectionReply()) {\n                        status.targetAppRunning = false;\n                        targetVMAlive = false;\n                        throw new ClientUtils.TargetAppOrVMTerminated(ClientUtils.TargetAppOrVMTerminated.VM);\n                    }\n                }\n            }\n            res = lastResponse;\n            lastResponse = null;\n        }\n\n        return res;\n    }\n\n    /**\n     * Set at least some of the properties related to execution of the target JVM.\n     * If we attach to the target VM on-the-fly, we need to get everything from it.\n     * Otherwise, there are still some properties that we can guess in principle, but which we better ask the VM\n     * for, such as Java extension class path dirs and Java boot class path.\n     */\n    private boolean setVMProperties(VMPropertiesResponse resp, boolean terminateOnError) {\n        if (resp.getAgentVersion() != CommonConstants.CURRENT_AGENT_VERSION) {\n            appStatusHandler.displayWarning(INCORRECT_AGENT_VERSION_MSG);\n        }\n\n        // Check if the VM version is supported by the Profiler\n        String jdkVersionString = resp.getJDKVersionString();\n\n        if (!MiscUtils.isSupportedRunningJVMVersion(jdkVersionString)) {\n            String message = MessageFormat.format(UNSUPPORTED_JVM_MSG, new Object[] { jdkVersionString });\n            appStatusHandler.displayErrorAndWaitForConfirm(message);\n\n            try {\n                if (terminateOnError) {\n                    terminateTargetJVM();\n                } else {\n                    detachFromTargetJVM();\n                }\n            } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n            }\n\n            return false;\n        }\n\n        // Check the VM version, and if it doesn't match the one set in the tool, check if we have saved calibration data\n        // for this VM version\n        String jdkVersionName = Platform.getJDKVersionString(jdkVersionString);\n        settings.setTargetJDKVersionString(jdkVersionName);\n        status.targetJDKVersionString = jdkVersionName;\n        status.fullTargetJDKVersionString = jdkVersionString;\n        currentAgentId = resp.getAgentId();\n\n        if (!status.remoteProfiling) {\n            int res = CalibrationDataFileIO.readSavedCalibrationData(status);\n\n            if (res < 0) { // Fatal error with reading saved file data - report the details\n\n                String message = MessageFormat.format(ERROR_GETTING_CALIBRATION_DATA_MSG,\n                                                      new Object[] { CalibrationDataFileIO.getErrorMessage() });\n                appStatusHandler.displayErrorAndWaitForConfirm(message);\n\n                return false;\n            } else if (res > 0) { // Saved data file doesn't exist - notify the user and stop\n                appStatusHandler.displayErrorWithDetailsAndWaitForConfirm(MUST_CALIBRATE_FIRST_SHORT_MSG, MUST_CALIBRATE_FIRST_MSG);\n\n                try {\n                    if (terminateOnError) {\n                        terminateTargetJVM();\n                    } else {\n                        detachFromTargetJVM();\n                    }\n                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                }\n\n                return false;\n            }\n        }\n\n        status.jvmArguments = resp.getJVMArguments();\n        status.javaCommand = resp.getJavaCommand();\n        status.targetMachineOSName = resp.getTargetMachineOSName();\n        status.maxHeapSize = resp.getMaxHeapSize();\n        status.startupTimeMillis = resp.getStartupTimeMillis();\n        status.startupTimeInCounts = resp.getStartupTimeInCounts();\n        status.canInstrumentConstructor = resp.canInstrumentConstructor();\n\n        if (!status.remoteProfiling &&\n              (settings.getTargetJDKVersionString() == CommonConstants.JDK_CVM_STRING\n            || settings.getTargetJDKVersionString() == CommonConstants.JDK_15_STRING\n            || settings.getTargetJDKVersionString() == CommonConstants.JDK_16_STRING\n            || settings.getTargetJDKVersionString() == CommonConstants.JDK_17_STRING\n            || settings.getTargetJDKVersionString() == CommonConstants.JDK_18_STRING)\n                ) {\n            settings.setWorkingDir(resp.getWorkingDir());\n            settings.setVMClassPaths(resp.getJavaClassPath(), resp.getJavaExtDirs(), resp.getBootClassPath());\n        } else {\n            settings.setWorkingDir(\"\");\n            settings.setVMClassPaths(\"\", null, null);\n        }\n        classRepo.initClassPaths(settings.getWorkingDir(), settings.getVMClassPaths());\n\n        return true;\n    }\n\n    /**\n     * Check if we can't instrument more methods because the 64K limit is reached\n     */\n    private void checkForInstrMethodsLimitReached() {\n        if ((status.getStartingMethodId() >= 65535) && !instrMethodsLimitReported && status.targetAppRunning) {\n            appStatusHandler.displayWarningAndWaitForConfirm(INSTRUMENTATION_LIMIT_REACHED_MSG);\n            instrMethodsLimitReported = true;\n        }\n    }\n\n    private void checkForTargetAppRunning() throws ClientUtils.TargetAppOrVMTerminated {\n        if (!status.targetAppRunning) {\n            serverCommandHandler.handleServerCommand(null);\n            throw new ClientUtils.TargetAppOrVMTerminated(ClientUtils.TargetAppOrVMTerminated.APP);\n        }\n    }\n\n    private void checkForTargetVMAlive() throws ClientUtils.TargetAppOrVMTerminated {\n        if (!targetVMAlive) {\n            serverCommandHandler.handleServerCommand(null);\n            throw new ClientUtils.TargetAppOrVMTerminated(ClientUtils.TargetAppOrVMTerminated.VM);\n        }\n    }\n\n    //-------------------------------- Private implementation ------------------------------------------\n    private void clearPreviousInstrumentationInServer()\n                                               throws InstrumentationException, ClientUtils.TargetAppOrVMTerminated {\n        Response resp;\n        checkForTargetAppRunning();\n\n        // First send the command that will make the application stop emitting events\n        // But avoid doing that while we are processing the data at the client side, since it looks like when these two\n        // things happen at the same time, it's likely to cause problems.\n        // This is a quick fix. Probably a more solid solution is needed.\n        while (handlingEventBufferDump) {\n            try {\n                Thread.sleep(20);\n            } catch (Exception ex) {\n            }\n        }\n\n        String error = sendSimpleCommandAndGetResponse(Command.DEACTIVATE_INJECTED_CODE);\n\n        if (error != null) {\n            throw new InstrumentationException(error);\n        }\n\n        long curTime = System.currentTimeMillis();\n\n        // Now actually de-instrument the instrumented methods\n        InstrumentMethodGroupCommand cmd = instrumentor.createClearAllInstrumentationCommand();\n\n        synchronized (this) {\n            sendComplexCmdToServer(cmd);\n            instrProcessingTime += (System.currentTimeMillis() - curTime);\n            resp = getLastResponse();\n        }\n\n        if (!resp.isOK()) {\n            throw new InstrumentationException(resp.getErrorMessage());\n        }\n    }\n\n    private void closeConnection() {\n        if (!serverListener.isRunning()) {\n            return;\n        }\n\n        try {\n            status.targetAppRunning = false;\n            targetVMAlive = false;\n            serverListener.shutdown();\n            setLastResponse(null); // This is important, in case smb. is waiting for the response\n            socketOut.close();\n            socketIn.close();\n            clientSocket.close();\n\n            // This is kind of \"black magic\", that is needed when we hit \"Run\" without explicitly terminating\n            // the previous target JVM. If this pause is not made here, then for some reason we get:\n            // \"SocketException: Connection reset by peer: JVM_recv in socket input stream read\"  in connectToServer().\n            // I don't like this way of dealing with this problem - need to investigate why it really happens\n            try {\n                Thread.sleep(400);\n            } catch (InterruptedException e) {\n            }\n        } catch (IOException ex) {\n            // Don't do anything\n        } finally {\n            EventBufferResultsProvider.getDefault().shutdown();\n            EventBufferProcessor.removeEventBufferFile();\n        }\n    }\n\n    private boolean connectToServer(int attachMode, boolean calibrationOnlyRun, final AtomicBoolean cancel) {\n        status.targetAppRunning = false;\n        targetVMAlive = false;\n        terminateOrDetachCommandIssued = false;\n\n        String taHost = (attachMode == 1) ? settings.getRemoteHost() : \"\"; // NOI18N\n\n        if (taHost.isEmpty()) {\n            status.remoteProfiling = false;\n            taHost = \"127.0.0.1\"; // NOI18N\n        } else {\n            status.remoteProfiling = true;\n        }\n\n        final String host = taHost;\n        final int port = settings.getPortNo();\n        \n        int noOfCycles = 600; // Timeout is set to 150 sec\n        \n        Runnable cancelHandler = new Runnable() {\n            public void run() {\n                cancel.set(true);\n                serverListener.cancel(); \n            }\n        };\n        AppStatusHandler.AsyncDialog waitDialog =\n                appStatusHandler.getAsyncDialogInstance(CONNECT_VM_MSG, true, cancelHandler);\n        \n        try {\n            serverListener = new ServerListener();\n            waitDialog.display();\n            serverListener.start();\n\n            while (!cancel.get()) {\n                try {\n                    clientSocket = new Socket(host, port);\n                    clientSocket.setSoTimeout(0); // ATTENTION: timeout may be found useful eventually...\n                    clientSocket.setTcpNoDelay(true); // Necessary at least on Solaris to avoid delays in e.g. readInt() etc.\n                    socketOut = new ObjectOutputStream(clientSocket.getOutputStream());\n                    socketIn = new ObjectInputStream(clientSocket.getInputStream());\n                    wireIO = new WireIO(socketOut, socketIn);\n\n                    targetVMAlive = true; // This is in fact an assumption\n                    serverListener.startRunning();\n                    break;\n                } catch (ConnectException ex) {\n                    // ex.printStackTrace (System.err);\n                    try {\n                        Thread.sleep(250);\n                    } catch (InterruptedException iex) {\n                    }\n\n                    if (--noOfCycles == 0) {\n                        MiscUtils.printWarningMessage(\"timed out while trying to connect to the target JVM.\"); // NOI18N\n                        serverListener.cancel();\n                        break;\n                    }\n                }\n            }\n        } catch (Exception ex) { // SocketException, UnknownHostException, IOException\n            MiscUtils.printErrorMessage(\"exception while trying to connect to the target JVM:\\n\" + ex); // NOI18N\n        } finally {\n            waitDialog.close();\n        }\n\n        if (!serverListener.isRunning()) {\n            MiscUtils.printErrorMessage(\"connection with server not open\"); // NOI18N\n\n            return false;\n        }\n\n        // Now check the connection and do other preparation work\n        try {\n            String error = sendSimpleCommandAndGetResponse(Command.CHECK_CONNECTION);\n\n            if (error != null) {\n                targetVMAlive = false;\n                MiscUtils.printErrorMessage(\"got error message from agent:\" + error); // NOI18N\n\n                return false;\n            }\n\n            if (calibrationOnlyRun) {\n                //        System.err.println(\"G1\");\n                boolean res = getCalibrationData(false);\n\n                //        System.err.println(\"G2: \"+res);\n                try {\n                    terminateTargetJVM();\n                } catch (ClientUtils.TargetAppOrVMTerminated e) {\n                    ProfilerLogger.log(\"terminateTargetJVM failed with TargetAppOrVMTerminated exception:\"); // NOI18N\n                    ProfilerLogger.log(e.getMessage());\n\n                    // this is OK here\n                }\n\n                //        System.err.println(\"G3\");\n                return res;\n            }\n\n            boolean terminateOnError = attachMode != 2; // in case of direct attach we don't want to have a JVM process hanging around waiting for the client to connect\n                                                        // Get VM properties\n\n            synchronized (this) {\n                sendSimpleCmdToServer(Command.GET_VM_PROPERTIES);\n\n                Response aResponse = getLastResponse();\n\n                if (!(aResponse instanceof VMPropertiesResponse)) {\n                    System.err.println(\"SEVERE: Received \" + aResponse.getClass().getName() + \"(\" + aResponse.toString() // NOI18N\n                                       + \") instead of VMPropertiesResponse\"); // NOI18N\n                }\n\n                if (!setVMProperties((VMPropertiesResponse) aResponse, terminateOnError)) {\n                    return false;\n                }\n            }\n\n            // Send a command to initiate the fake RootClassLoadedCommand cycle, that forces initialization of some internal\n            // server classes\n            serverClassesInitialized = false;\n            // Note that here we can't use normal getCmd(), since this shared object could already have been initialized with\n            // real data.\n            error = sendCommandAndGetResponse(new InitiateProfilingCommand(INSTR_RECURSIVE_FULL,\n                                                                                 \"*FAKE_CLASS_FOR_INTERNAL_TEST*\") // NOI18N\n            );\n\n            if (error != null) {\n                MiscUtils.printErrorMessage(\"got error message from agent:\" + error); // NOI18N\n                targetVMAlive = false;\n\n                return false;\n            }\n\n            noOfCycles = 20;\n\n            while (!serverClassesInitialized && (--noOfCycles > 0)) {\n                try {\n                    Thread.sleep(100);\n                } catch (InterruptedException ex) {\n                }\n            }\n\n            if (!serverClassesInitialized) {\n                MiscUtils.printErrorMessage(\"timed out while trying to initialize internals in the target JVM.\"); // NOI18N\n                targetVMAlive = false;\n\n                return false;\n            }\n\n            try {\n                Thread.sleep(100); // To make sure everything has finished on the server side.\n            } catch (InterruptedException ex) {\n            }\n        } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n            targetVMAlive = false;\n            MiscUtils.printWarningMessage(\"target app terminated:\" + ex.getMessage()); // NOI18N\n\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Some commands, e.g. those related to instrumentation, are executed in a separate thread, since they may in turn\n     * send requests and await response from the server. Thus the listener thread, that calls this method, should be made\n     * available quickly so that it can listen for the server again.\n     */\n    private void executeInSeparateThread(Command cmd) {\n        synchronized (execInSeparateThreadLock) {\n            execInSeparateThreadCmd = cmd;\n\n            try {\n                execInSeparateThreadLock.notify();\n            } catch (IllegalMonitorStateException ex) {\n                MiscUtils.internalError(\"ProfilerClient.executeInSeparateThread()\"); // NOI18N\n            }\n        }\n    }\n\n    private void startSeparateCmdExecThread() {\n        assert separateCmdExecThread == null;\n        SeparateCmdExecutionThread t = new SeparateCmdExecutionThread();\n        t.setDaemon(true);\n        t.start();\n        separateCmdExecThread = t;\n    }\n    \n    private void stopSeparateCmdExecThread() {\n        assert separateCmdExecThread != null;\n        executeInSeparateThread(null); // stop thread\n        separateCmdExecThread = null;\n    }\n\n    private boolean handleFakeClassLoad(RootClassLoadedCommand cmd) {\n        if (cmd.getAllLoadedClassNames()[0].equals(\"*FAKE_CLASS_1*\")) { // NOI18N\n            sendComplexRespToServer(new InstrumentMethodGroupResponse(new String[] { \"*FAKE_CLASS_1*\", \"*FAKE_CLASS_2*\" },\n                                                                      new int[] { 0, 0 }, new byte[][] {\n                                                                          { 0 },\n                                                                          { 0 }\n                                                                      }, null, 0));\n            serverClassesInitialized = true;\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    private void handleIOExceptionOnSend(IOException ex)\n                                  throws ClientUtils.TargetAppOrVMTerminated {\n        checkForTargetVMAlive();\n        // For now, assume that the server went away. TODO [misha] - can it happen for any other reason?\n        appStatusHandler.displayError(MessageFormat.format(TARGET_JVM_ERROR_MSG, new Object[] { ex.getMessage() }));\n        closeConnection();\n        throw new ClientUtils.TargetAppOrVMTerminated(ClientUtils.TargetAppOrVMTerminated.VM);\n    }\n\n    private void instrumentMethodGroupFollowUp(Command cmd) {\n        synchronized (instrumentationLock) {\n            long curTime = System.currentTimeMillis();\n            InstrumentMethodGroupResponse imgr = instrumentor.createFollowUpInstrumentMethodGroupResponse(cmd);\n            instrProcessingTime += (System.currentTimeMillis() - curTime);\n            //if (imgr != null && ! imgr.isEmpty()) {\n            // System.err.println(\"*** Profiler Engine: instrumentMethodGroupFollowUp() produced response:\");\n            // imgr.dump();\n            // }\n            sendComplexRespToServer(imgr);\n        }\n\n        checkForInstrMethodsLimitReached();\n    }\n\n    private void instrumentMethodGroupFromRoot(final RootClassLoadedCommand cmd) {\n        synchronized (instrumentationLock) {\n            AppStatusHandler.AsyncDialog waitDialog = null;\n            try {\n                InstrumentMethodGroupResponse imgr;\n\n                if (!serverClassesInitialized) { // Check if it is a fake command from server, used to just pre-initialize\n                                                 // some internal server classes\n\n                    if (handleFakeClassLoad(cmd)) {\n                        return;\n                    }\n                }\n\n                appStatusHandler.pauseLiveUpdates();\n\n                if (status.targetAppRunning) {\n                    waitDialog = appStatusHandler.getAsyncDialogInstance(PERFORMING_INSTRUMENTATION_STRING, true, null);\n                    waitDialog.display();\n                }\n\n                // If the application is not running yet, it means that instrumentation is performed on startup. In that case,\n                // it typically takes very short time, so there is no real need to display this progress dialog. Additionally,\n                // the AWT Event Queue thread may be blocked in the call to startTargetApp, in which case this whole thing will\n                // hang (due to getAsyncDialogInstance NB implementation waiting on this thread's lock).\n                try {\n                    long curTime = System.currentTimeMillis();\n                    imgr = instrumentor.createInitialInstrumentMethodGroupResponse(cmd);\n                    instrProcessingTime += (System.currentTimeMillis() - curTime);\n                } catch (BadLocationException ex) {\n                    imgr = new InstrumentMethodGroupResponse(null);\n                    // Can currently happen only for INSTR_CODE_REGION\n                    appStatusHandler.displayError(INVALID_CODE_REGION_MSG);\n                } catch (ClassNotFoundException ex) {\n                    imgr = new InstrumentMethodGroupResponse(null);\n\n                    if (getCurrentInstrType() == INSTR_CODE_REGION) {\n                        appStatusHandler.displayError(MessageFormat.format(CLASS_NOT_FOUND_MSG, new Object[] { ex.getMessage() }));\n                    } else {\n                        MiscUtils.printErrorMessage(\"problem in instrumentMethodGroupFromRoot: \" + ex); // NOI18N\n                    }\n                }\n\n                //if (imgr != null ! imgr.isEmpty()) {\n                // System.err.println(\"*** Profiler Engine: instrumentMethodGroupFromRoot() produced response:\");\n                // imgr.dump(); }\n                // else System.err.println(\"*** Profiler Engine: instrumentMethodGroupFromRoot() produced empty response\");\n                sendComplexRespToServer(imgr);\n            } finally {\n                if (waitDialog != null) {\n                    waitDialog.close();\n                }\n\n                appStatusHandler.resumeLiveUpdates();\n            }\n        }\n    }\n\n    /**\n     * Upon receipt of the BUFFER_FULL command from the server, read and process the buffer contents\n     */\n    private void readAndProcessProfilingResults(EventBufferDumpedCommand cmd) {\n        int bufSize = cmd.getBufSize();\n\n        if (bufSize == 0) { // zero size may happen when dump is forced when there is actually no new information generated\n            sendSimpleRespToServer(true, null);\n\n            return;\n        }\n\n        handlingEventBufferDump = true;\n\n        // Results of memory/CPU profiling can be processed concurrently to take advantage of a possible multiprocessor machine.\n        // Similarly, during remote profiling any results can be processed concurrently, since processing on a different\n        // machine will not disturb execution timing on the TA machine. Note also that if this command is\n        // received as a result of the forced dump (as opposed to the normal one due to buffer overflow), the data should\n        // be processed synchronously to avoid e.g. a \"no results\" report when there are already some.\n\n        // update [ian] In case of remote profiling we actually can not process the results in concurrently,\n        // since there would suddenly be 2 pieces of code that simultaneously read from the socket stream\n        // leading to issue 59660: JFluid: error writing collected data to the socket\n        // see http://www.netbeans.org/issues/show_bug.cgi?id=59660 for details\n        if (!status.remoteProfiling && !forceObtainedResultsDumpCalled) {\n            // Note that the call below may block, waiting for separarateCmdExecThread to finish its current job.\n            // That means that nothing in readResultsFromBuffer() that this command eventually calls, is allowed to\n            // send a command to the server and await a response. If that happens, the communication thread will be\n            // unavailable for reading server's response (because it's waiting here), effectively causing a deadlock.\n            executeInSeparateThread(cmd);\n            handlingEventBufferDump = false;\n        } else {\n            // Process profiling results synchronously in case of:\n            //  - remote profiling\n            //  - explicite Get results (forceObtainedResultsDumpCalled)\n            byte[] buf = EventBufferProcessor.readDataAndPrepareForProcessing(cmd);\n            EventBufferResultsProvider.getDefault().dataReady(buf, getCurrentInstrType());\n            handlingEventBufferDump = false;\n            sendSimpleRespToServer(true, null);\n            forceObtainedResultsDumpCalled = false;\n        }\n    }\n\n    /**\n     * @param cmd Command to send\n     * @return null if command was confirmed OK from Agent, Error message otherwise\n     * @throws ClientUtils.TargetAppOrVMTerminated\n     *\n     */\n    private synchronized String sendCommandAndGetResponse(Command cmd)\n                                                   throws ClientUtils.TargetAppOrVMTerminated {\n        sendComplexCmdToServer(cmd);\n\n        Response resp = getLastResponse();\n\n        if (!resp.isOK()) {\n            MiscUtils.printErrorMessage(\"error in sendCommandAndGetResponse: for cmd = \" + cmd // NOI18N\n                                        + \" and resp = \" + resp + \" got error message: \" + resp.getErrorMessage() // NOI18N\n            );\n\n            return resp.getErrorMessage();\n        } else {\n            return null;\n        }\n    }\n\n    private void sendComplexCmdToServer(Command cmd) throws ClientUtils.TargetAppOrVMTerminated {\n        try {\n            wireIO.sendComplexCommand(cmd);\n        } catch (IOException ex) {\n            handleIOExceptionOnSend(ex);\n        }\n    }\n\n    private void sendComplexRespToServer(Response resp) {\n        try {\n            wireIO.sendComplexResponse(resp);\n        } catch (IOException ex) {\n            MiscUtils.printErrorMessage(\"exception when trying to send a response: \" + ex); // NOI18N\n\n            try {\n                handleIOExceptionOnSend(ex);\n            } catch (ClientUtils.TargetAppOrVMTerminated ex1) { /* All done already */\n            }\n        }\n    }\n\n    private void sendSimpleCmdToServer(int cmdType) throws ClientUtils.TargetAppOrVMTerminated {\n        try {\n            wireIO.sendSimpleCommand(cmdType);\n        } catch (IOException ex) {\n            handleIOExceptionOnSend(ex);\n        }\n    }\n\n    /**\n     * @param cmd Command to send\n     * @return null if command was confirmed OK from Agent, Error message otherwise\n     * @throws ClientUtils.TargetAppOrVMTerminated\n     *\n     */\n    private synchronized String sendSimpleCommandAndGetResponse(int cmdType)\n        throws ClientUtils.TargetAppOrVMTerminated {\n        sendSimpleCmdToServer(cmdType);\n\n        Response resp = getLastResponse();\n\n        if (!resp.isOK()) {\n            MiscUtils.printErrorMessage(\"error in sendCommandAndGetResponse: for cmdType = \" + cmdType // NOI18N\n                                        + \" and resp = \" + resp + \" got error message: \" + resp.getErrorMessage() // NOI18N\n            );\n\n            return resp.getErrorMessage();\n        } else {\n            return null;\n        }\n    }\n\n    private void sendSimpleRespToServer(boolean val, String errorMessage) {\n        try {\n            wireIO.sendSimpleResponse(val, errorMessage);\n        } catch (IOException ex) {\n            try {\n                handleIOExceptionOnSend(ex);\n            } catch (ClientUtils.TargetAppOrVMTerminated ex1) { /* All done already */\n            }\n        }\n    }\n    \n    private InitiateProfilingCommand createInitiateInstrumnetation(int instrType, String[] classNames,\n                                          boolean instrSpawnedThreads, boolean startProfilingPointsActive) {\n        RuntimeProfilingPoint points[] = settings.getRuntimeProfilingPoints();\n        String[] profilingPointHandlers = new String[points.length];\n        String[] profilingPointInfos = new String[points.length];\n        int[] profilingPointIDs = new int[points.length];\n        Arrays.sort(points); // ProfilerRuntime uses Arrays.binarySearch\n\n        for (int i = 0; i < points.length; i++) {\n            RuntimeProfilingPoint point = points[i];\n            profilingPointIDs[i] = point.getId();\n            profilingPointHandlers[i] = point.getServerHandlerClass();\n            profilingPointInfos[i] = point.getServerInfo();\n        }\n        return new InitiateProfilingCommand(instrType,classNames,\n                        profilingPointIDs,profilingPointHandlers,profilingPointInfos,\n                        instrSpawnedThreads,startProfilingPointsActive);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/ProfilerClientListener.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface ProfilerClientListener {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    void instrumentationChanged(int oldInstrType, int newInstrType);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/ProfilerEngineSettings.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.client.RuntimeProfilingPoint;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.marker.Marker;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport java.io.File;\nimport java.io.IOException;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\n\n\n/**\n * Global profiler session and engine settings, that are used in various parts of the system.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic final class ProfilerEngineSettings implements CommonConstants, Cloneable {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private InstrumentationFilter instrumentationFilter = new InstrumentationFilter();\n    private Marker methodMarker = Marker.DEFAULT;\n    private String jFluidRootDirName;\n    private String jvmArgs; // the arguments for JVM running the TA\n    private String mainArgs; // the TA arguments\n    private String mainClassName; // the TA main class name\n\n    // Target application setup-specific settings\n    private String mainClassPath = \"\"; // NOI18N           // the classpath for starting TA\n    private String remoteHost = \"\"; // NOI18N                  // Remote host name in case of remote profiling, \"\" for local profiling\n    private String targetJDKVersion = Platform.JDK_15_STRING; // the target JVM version string: see Platform.JDK_xx_STRING constants\n    private String targetJVMExeFile; // the JVM executable to run the TA\n    private String targetJVMStartupDirName; // the working directory for TA we are attaching to\n    private String workingDir = System.getProperty(\"user.dir\"); // NOI18N // the TA working directory\n    private ClientUtils.SourceCodeSelection[] instrumentationRootMethods = new ClientUtils.SourceCodeSelection[0];\n    private RuntimeProfilingPoint[] profilingPoints = new RuntimeProfilingPoint[0];\n\n    // THE FOLLOWING DATA IS REGENERATED ON EACH NEW JFLUID RUN AND/OR PROFILING SESSION WITHIN ONE RUN\n    private String[] vmClassPaths = new String[3]; // Target VM's java.class.path, java.ext.dirs and sun.boot.class.path\n    private boolean absoluteTimerOn = true;\n    private boolean dontShowZeroLiveObjAllocPaths = true;\n    private boolean excludeWaitTime = true;\n    private boolean instrumentEmptyMethods = false;\n\n    // JFluid and instrumentation-specific settings\n    private boolean instrumentGetterSetterMethods = false;\n    private boolean instrumentMethodInvoke = true;\n    private boolean instrumentSpawnedThreads = false;\n    private boolean runGCOnGetResultsInMemoryProfiling = false;\n    private boolean instrumentObjectInit = false;\n\n    // If false, the exec command is issued so that there is no visible console for the TA\n    private boolean separateConsole = true;\n    private boolean sortResultsByThreadCPUTime = false;\n    private boolean suspendTargetApp = false;\n    private boolean targetWindowRemains = false;\n    private boolean threadCPUTimerOn = false;\n    private boolean threadsMonitoringEnabled;\n    private boolean lockContentionMonitoringEnabled;\n    private boolean threadsSamplingEnabled;\n    private int allocStackTraceLimit = -5; // Negative number means full (unlimited) depth actually used, although the limit is preserved\n    private int maxStringLength = MAX_STRING_LENGTH_DEFAULT;\n    private int allocTrackEvery = 10;\n    private int architecture; // system architecture 32bit/64bit\n    private int codeRegionCPUResBufSize = 1000;\n    private int cpuProfilingType = CPU_INSTR_FULL;\n    private int instrScheme = INSTRSCHEME_LAZY; // See CommonConstants for definitions\n    private int nProfiledThreadsLimit = 32;\n    private int stackDepthLimit = Integer.MAX_VALUE;\n    private int portNo = 5140;\n    private int samplingInterval = 10;\n    private int samplingFrequency = 10;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setAbsoluteTimerOn(boolean v) {\n        absoluteTimerOn = v;\n    }\n\n    public boolean getAbsoluteTimerOn() {\n        return absoluteTimerOn;\n    }\n\n    public void setAllocStackTraceLimit(int depth) {\n        allocStackTraceLimit = depth;\n    }\n\n    public int getAllocStackTraceLimit() {\n        return allocStackTraceLimit;\n    }\n\n    public void setAllocTrackEvery(int interval) {\n        if (interval < 1) {\n            interval = 1;\n        }\n\n        allocTrackEvery = interval;\n    }\n\n    public int getAllocTrackEvery() {\n        return allocTrackEvery;\n    }\n\n    public void setCPUProfilingType(int v) {\n        cpuProfilingType = v;\n    }\n\n    public int getCPUProfilingType() {\n        return cpuProfilingType;\n    }\n\n    public void setCodeRegionCPUResBufSize(int size) {\n        codeRegionCPUResBufSize = size;\n    }\n\n    public int getCodeRegionCPUResBufSize() {\n        return codeRegionCPUResBufSize;\n    }\n\n    public void setDontShowZeroLiveObjAllocPaths(boolean v) {\n        dontShowZeroLiveObjAllocPaths = v;\n    } // TODO CHECK: unused method\n\n    public boolean getDontShowZeroLiveObjAllocPaths() {\n        return dontShowZeroLiveObjAllocPaths;\n    } // TODO CHECK: unused method\n\n    public void setExcludeWaitTime(boolean b) {\n        excludeWaitTime = b;\n    }\n\n    public boolean getExcludeWaitTime() {\n        return excludeWaitTime;\n    }\n\n    public void setInstrScheme(int scheme) {\n        instrScheme = scheme;\n    }\n\n    public int getInstrScheme() {\n        return instrScheme;\n    }\n\n    public void setInstrumentEmptyMethods(boolean b) {\n        instrumentEmptyMethods = b;\n    }\n\n    public boolean getInstrumentEmptyMethods() {\n        return instrumentEmptyMethods;\n    }\n\n    public void setInstrumentGetterSetterMethods(boolean b) {\n        instrumentGetterSetterMethods = b;\n    }\n\n    public boolean getInstrumentGetterSetterMethods() {\n        return instrumentGetterSetterMethods;\n    }\n\n    public void setInstrumentMethodInvoke(boolean b) {\n        instrumentMethodInvoke = b;\n    }\n\n    public boolean getInstrumentMethodInvoke() {\n        return instrumentMethodInvoke;\n    }\n\n    public void setInstrumentSpawnedThreads(boolean b) {\n        instrumentSpawnedThreads = b;\n    }\n\n    public boolean getInstrumentSpawnedThreads() {\n        return instrumentSpawnedThreads;\n    }\n\n    public void setInstrumentationFilter(GenericFilter f) {\n        instrumentationFilter = new InstrumentationFilter(f);\n    }\n\n    public InstrumentationFilter getInstrumentationFilter() {\n        return instrumentationFilter;\n    }\n\n    public void setInstrumentationRootMethods(ClientUtils.SourceCodeSelection[] methods) {\n        instrumentationRootMethods = methods;\n    }\n\n    public ClientUtils.SourceCodeSelection[] getInstrumentationRootMethods() {\n        return instrumentationRootMethods;\n    }\n\n    public String getJFluidRootDirName() {\n        return jFluidRootDirName;\n    } // TODO: move elsewhere\n\n    public void setJVMArgs(String args) {\n        jvmArgs = args;\n    }\n\n    public String[] getJVMArgs() {\n        return StringUtils.parseArgsString(jvmArgs);\n    }\n\n    public String getJVMArgsAsSingleString() {\n        return jvmArgs;\n    }\n\n    public void setMainArgs(String args) {\n        mainArgs = args;\n    }\n\n    public String[] getMainArgs() {\n        return StringUtils.parseArgsString(mainArgs);\n    }\n\n    public String getMainArgsAsSingleString() {\n        return mainArgs;\n    }\n\n    public void setMainClass(String name) {\n        mainClassName = name;\n    }\n\n    public String getMainClassName() {\n        return mainClassName;\n    }\n\n    public void setMainClassPath(String cp) {\n        mainClassPath = cp;\n    }\n\n    public String getMainClassPath() {\n        return mainClassPath;\n    }\n\n    public void setMethodMarker(Marker marker) {\n        methodMarker = marker;\n    }\n\n    public Marker getMethodMarker() {\n        return methodMarker;\n    }\n\n    public void setNProfiledThreadsLimit(int num) {\n        nProfiledThreadsLimit = num;\n    }\n\n    public int getNProfiledThreadsLimit() {\n        return nProfiledThreadsLimit;\n    }\n\n    public void setMaxStringLength(int maxLength) {\n        if (maxLength > MAX_STRING_LENGTH_TOP_LIMIT)\n            throw new IllegalArgumentException(maxLength+\" is over top limit \"+MAX_STRING_LENGTH_TOP_LIMIT);    // NOI18N\n        maxStringLength = maxLength;\n    }\n\n    public int getMaxStringLength() {\n        return maxStringLength;\n    }\n\n    public void setStackDepthLimit(int num) {\n        stackDepthLimit = num;\n    }\n\n    public int getStackDepthLimit() {\n        return stackDepthLimit;\n    }\n\n    public void setPortNo(int pNo) {\n        portNo = pNo;\n    }\n\n    public int getPortNo() {\n        return portNo;\n    }\n\n    public void setRemoteHost(String host) {\n        remoteHost = host;\n    }\n\n    public String getRemoteHost() {\n        return remoteHost;\n    }\n\n    public void setRunGCOnGetResultsInMemoryProfiling(boolean v) {\n        runGCOnGetResultsInMemoryProfiling = v;\n    }\n\n    public boolean getRunGCOnGetResultsInMemoryProfiling() {\n        return runGCOnGetResultsInMemoryProfiling;\n    }\n\n    public boolean isInstrumentArrayAllocation() {\n        return instrumentationFilter.hasArray();\n    }\n\n    public boolean isInstrumentObjectInit() {\n        return instrumentObjectInit;\n    }\n\n    public void setInstrumentObjectInit(boolean v) {\n        instrumentObjectInit = v;\n    }\n    \n    public void setRuntimeProfilingPoints(RuntimeProfilingPoint[] profilingPoints) {\n        this.profilingPoints = profilingPoints;\n    }\n\n    public RuntimeProfilingPoint[] getRuntimeProfilingPoints() {\n        return profilingPoints;\n    }\n\n    public void setSamplingInterval(int num) {\n        samplingInterval = num;\n    }\n\n    public int getSamplingInterval() {\n        return samplingInterval;\n    }\n\n    public void setSamplingFrequency(int num) {\n        samplingFrequency = num;\n    }\n\n    public int getSamplingFrequency() {\n        return samplingFrequency;\n    }\n\n    public void setSeparateConsole(boolean separateConsole) {\n        this.separateConsole = separateConsole;\n    }\n\n    public boolean getSeparateConsole() {\n        return separateConsole;\n    }\n\n    public void setSortResultsByThreadCPUTime(boolean v) {\n        sortResultsByThreadCPUTime = v;\n    }\n\n    public boolean getSortResultsByThreadCPUTime() {\n        return sortResultsByThreadCPUTime;\n    }\n\n    public void setSuspendTargetApp(boolean b) {\n        suspendTargetApp = b;\n    } // TODO CHECK: unused method\n\n    public boolean getSuspendTargetApp() {\n        return suspendTargetApp;\n    } // TODO CHECK: unused method\n\n    public void setSystemArchitecture(int arch) {\n        architecture = arch;\n    }\n\n    public int getSystemArchitecture() {\n        return architecture;\n    }\n\n    public void setTargetJDKVersionString(String ver) {\n        targetJDKVersion = ver;\n    }\n\n    public String getTargetJDKVersionString() {\n        return targetJDKVersion;\n    }\n\n    public void setTargetJVMExeFile(String name) {\n        targetJVMExeFile = name;\n    }\n\n    public String getTargetJVMExeFile() {\n        return targetJVMExeFile;\n    }\n\n    public void setTargetJVMStartupDirName(String dir) {\n        targetJVMStartupDirName = dir;\n    } // TODO CHECK: unused method\n\n    public String getTargetJVMStartupDirName() {\n        return targetJVMStartupDirName;\n    } // TODO CHECK: unused method\n\n    public void setTargetWindowRemains(boolean b) {\n        targetWindowRemains = b;\n    }\n\n    public boolean getTargetWindowRemains() {\n        return targetWindowRemains;\n    }\n\n    public void setThreadCPUTimerOn(boolean v) {\n        threadCPUTimerOn = v;\n    }\n\n    public boolean getThreadCPUTimerOn() {\n        return threadCPUTimerOn;\n    }\n\n    public void setThreadsMonitoringEnabled(boolean b) {\n        threadsMonitoringEnabled = b;\n    }\n\n    public boolean isThreadsMonitoringEnabled() {\n        return threadsMonitoringEnabled;\n    }\n    \n    public void setLockContentionMonitoringEnabled(boolean b) {\n        lockContentionMonitoringEnabled = b;\n    }\n\n    public boolean isLockContentionMonitoringEnabled() {\n        return lockContentionMonitoringEnabled;\n    }\n\n    public void setThreadsSamplingEnabled(boolean b) {\n        threadsSamplingEnabled = b;\n    }\n\n    public boolean isThreadsSamplingEnabled() {\n        return threadsSamplingEnabled;\n    }\n\n    public void setVMClassPaths(String javaClassPath, String javaExtDirs, String bootClassPath) {\n        vmClassPaths[0] = MiscUtils.getLiveClassPathSubset(javaClassPath, getWorkingDir());\n        vmClassPaths[1] = javaExtDirs;\n        vmClassPaths[2] = bootClassPath;\n\n        // Now set the JFluid class path to match that in the target JVM\n        try {\n            setMainClassPath(vmClassPaths[0]);\n        } catch (Exception ex) {\n            throw new InternalError(\"Should not happen\"); // NOI18N\n        }\n    }\n\n    public String[] getVMClassPaths() {\n        // Make sure that updates to the main class path work both ways\n        vmClassPaths[0] = getMainClassPath();\n\n        return vmClassPaths;\n    }\n\n    public void setWorkingDir(String name) {\n        workingDir = name;\n\n        if ((workingDir == null) || \"\".equals(workingDir)) { // NOI18N\n            workingDir = System.getProperty(\"user.dir\"); // NOI18N\n        }\n    }\n\n    public String getWorkingDir() {\n        return workingDir;\n    }\n\n    public Object clone() {\n        ProfilerEngineSettings clone = null;\n\n        try {\n            clone = (ProfilerEngineSettings) super.clone();\n\n            // clone array of instrumentatio root methods one by one\n            clone.instrumentationRootMethods = new ClientUtils.SourceCodeSelection[instrumentationRootMethods.length];\n\n            for (int i = 0; i < instrumentationRootMethods.length; i++) {\n                clone.instrumentationRootMethods[i] = (ClientUtils.SourceCodeSelection) instrumentationRootMethods[i].clone();\n            }\n\n            // clone instrumentation filter\n            clone.instrumentationFilter = new InstrumentationFilter(instrumentationFilter);\n\n            return clone;\n        } catch (CloneNotSupportedException e) {\n            throw new InternalError(\"Should never happen: ProfilerEngineSettings.clone\"); // NOI18N\n        }\n    }\n\n    public void initialize(String rootDirName) throws RuntimeException, IOException {\n        String jFluidNativeLibFullName = Platform.getAgentNativeLibFullName(rootDirName, false, null, -1);\n\n        String jFluidNativeLibDirName = jFluidNativeLibFullName.substring(0, jFluidNativeLibFullName.lastIndexOf('/')); // NOI18N\n\n        String checkedPath = \"\"; // NOI18N   // Needed only for error reporting\n\n        try {\n            File rootDir = MiscUtils.checkDirForName(checkedPath = rootDirName);\n            MiscUtils.checkDirForName(checkedPath = jFluidNativeLibDirName);\n            MiscUtils.checkFile(new File(checkedPath = jFluidNativeLibFullName), false);\n\n            jFluidRootDirName = rootDir.getCanonicalPath();\n        } catch (IOException e) {\n            throw new IOException(\"Problem with a required JFluid installation directory or file \" + checkedPath, e);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/ProfilerLogger.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid;\n\nimport java.io.PrintWriter;\nimport java.io.StringWriter;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n\n/**\n * This class serves as a wrapper for logging infrastructure\n * It should be used to log various profiler info messages\n * The logger used is identified as \"org.graalvm.visualvm.lib.jfluid.infolog\" and its level is automatically set to INFO\n * @author Jaroslav Bachorik\n */\npublic class ProfilerLogger {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Logger INSTANCE = Logger.getLogger(\"org.graalvm.visualvm.lib.jfluid.infolog\"); // NOI18N\n    private static final Level EXCEPTION_LEVEL = Level.SEVERE;\n    private static volatile Level DEFAULT_LEVEL = Level.INFO;\n    private static volatile boolean debugFlag = false;\n\n    static {\n        Level currentLevel = INSTANCE.getLevel();\n        Level newLevel = currentLevel;\n\n        if (DEFAULT_LEVEL.intValue() < EXCEPTION_LEVEL.intValue()) {\n            newLevel = DEFAULT_LEVEL;\n        } else {\n            newLevel = EXCEPTION_LEVEL;\n        }\n\n        if ((currentLevel == null) || (newLevel.intValue() < currentLevel.intValue())) {\n            INSTANCE.setLevel(newLevel);\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static boolean isDebug() {\n        return debugFlag;\n    }\n\n    public static void setLevel(Level level) {\n        INSTANCE.setLevel(level);\n\n        if (level.intValue() <= Level.FINEST.intValue()) {\n            debugFlag = true;\n        } else {\n            debugFlag = false;\n        }\n    }\n\n    public static Level getLevel() {\n        return INSTANCE.getLevel();\n    }\n\n    public static void debug(String message) {\n        INSTANCE.finest(message);\n    }\n\n    public static void info(String message) {\n        INSTANCE.info(message);\n    }\n\n    public static void log(String message) {\n        INSTANCE.log(DEFAULT_LEVEL, message);\n    }\n\n    public static void log(Exception ex) {\n        StringWriter sw = new StringWriter();\n        PrintWriter pw = new PrintWriter(sw);\n        ex.printStackTrace(pw);\n        INSTANCE.log(EXCEPTION_LEVEL, sw.toString());\n    }\n\n    public static void severe(String message) {\n        INSTANCE.severe(message);\n    }\n\n    public static void warning(String message) {\n        INSTANCE.warning(message);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/ProfilingEventListener.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid;\n\n\n/** An interface for listeners on profiling state\n *\n * @author Ian Formanek\n */\npublic interface ProfilingEventListener {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void attachedToTarget();\n\n    public void detachedFromTarget();\n\n    public void targetAppResumed();\n\n    public void targetAppStarted();\n\n    public void targetAppStopped();\n\n    public void targetAppSuspended();\n\n    public void targetVMTerminated();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/TargetAppRunner.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid;\n\nimport org.graalvm.visualvm.lib.jfluid.client.AppStatusHandler;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.client.ProfilingPointsProcessor;\nimport org.graalvm.visualvm.lib.jfluid.global.CalibrationDataFileIO;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.results.EventBufferProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCCTContainer;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.AsyncMessageCommand;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.Command;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.InternalStatsResponse;\nimport java.io.File;\nimport java.io.IOException;\nimport java.text.MessageFormat;\nimport java.text.NumberFormat;\nimport java.util.*;\nimport java.util.concurrent.CopyOnWriteArraySet;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\n\n/**\n * Functionality for high-level control of the Target Application (TA) execution, plus some utility methods\n * that seemed to fit best here.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class TargetAppRunner implements CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String CLASSPATH_SETTINGS_IGNORED_MSG;\n    private static final String ERROR_STARTING_JVM_MSG;\n    private static final String CALIBRATION_SUMMARY_SHORT_MSG;\n    private static final String CALIBRATION_SUMMARY_DETAILS_MSG;\n    private static final String FAILED_ESTABLISH_CONN_MSG;\n    private static final String UNEXPECTED_PROBLEM_STARTING_APP_MSG;\n    private static final String JVM_TERMINATED_NOTRESPOND_STRING;\n    private static final String INTERNAL_PROBLEM_STRING;\n    private static final String FAILED_START_APP_CAUSE_MSG;\n    private static final String CALIBRATION_RESULTS_MSG;\n    private static final String CALIBRATION_ERROR_MSG;\n    private static final String INTERNAL_STATISTICS_ONLY_MSG;\n    private static final String INSTR_METHODS_COUNT_MSG;\n    private static final String CLASSLOAD_FIRSTINV_COUNT_MSG;\n    private static final String NON_EMPTY_IMG_COUNT_MSG;\n    private static final String EMPTY_IMG_COUNT_MSG;\n    private static final String SINGLE_IMG_COUNT_MSG;\n    private static final String AVG_METHOD_TIME_MSG;\n    private static final String MIN_METHOD_TIME_MSG;\n    private static final String MAX_METHOD_TIME_MSG;\n    private static final String TOTAL_RUN_TIME_MSG;\n    private static final String INJ_INSTR_TIME_MSG;\n    private static final String TOTAL_INSTR_HOTSWAP_TIME_MSG;\n    private static final String BYTECODE_COMM_TIME_MSG;\n    private static final String CLIENT_BYTECODE_TIME_MSG;\n    private static final String CLIENT_DISK_PROCESS_MSG;\n    private static final String CLIENT_RESULTS_PROCESS_MSG;\n    private static final String PERFORMING_CALIBRATION_MSG;\n    \n    static {\n        ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.Bundle\"); // NOI18N\n        CLASSPATH_SETTINGS_IGNORED_MSG = messages.getString(\"TargetAppRunner_ClasspathSettingsIgnoredMsg\"); // NOI18N\n        ERROR_STARTING_JVM_MSG = messages.getString(\"TargetAppRunner_ErrorStartingJvmMsg\"); // NOI18N\n        CALIBRATION_SUMMARY_SHORT_MSG = messages.getString(\"TargetAppRunner_CalibrationSummaryShortMsg\"); // NOI18N\n        CALIBRATION_SUMMARY_DETAILS_MSG = messages.getString(\"TargetAppRunner_CalibrationSummaryDetailsMsg\"); // NOI18N\n        FAILED_ESTABLISH_CONN_MSG = messages.getString(\"TargetAppRunner_FailedEstablishConnMsg\"); // NOI18N\n        UNEXPECTED_PROBLEM_STARTING_APP_MSG = messages.getString(\"TargetAppRunner_UnexpectedProblemStartingAppMsg\"); // NOI18N\n        JVM_TERMINATED_NOTRESPOND_STRING = messages.getString(\"TargetAppRunner_JvmTerminatedNotRespondString\"); // NOI18N\n        INTERNAL_PROBLEM_STRING = messages.getString(\"TargetAppRunner_InternalProblemString\"); // NOI18N\n        FAILED_START_APP_CAUSE_MSG = messages.getString(\"TargetAppRunner_FailedStartAppCauseMsg\"); // NOI18N\n        CALIBRATION_RESULTS_MSG = messages.getString(\"TargetAppRunner_CalibrationResultsMsg\"); // NOI18N\n        CALIBRATION_ERROR_MSG = messages.getString(\"TargetAppRunner_CalibrationErrorMsg\"); // NOI18N\n        INTERNAL_STATISTICS_ONLY_MSG = messages.getString(\"TargetAppRunner_InternalStatisticsOnlyMsg\"); // NOI18N\n        INSTR_METHODS_COUNT_MSG = messages.getString(\"TargetAppRunner_InstrMethodsCountMsg\"); // NOI18N\n        CLASSLOAD_FIRSTINV_COUNT_MSG = messages.getString(\"TargetAppRunner_ClassLoadFirstInvCountMsg\"); // NOI18N\n        NON_EMPTY_IMG_COUNT_MSG = messages.getString(\"TargetAppRunner_NonEmptyImgCountMsg\"); // NOI18N\n        EMPTY_IMG_COUNT_MSG = messages.getString(\"TargetAppRunner_EmptyImgCountMsg\"); // NOI18N\n        SINGLE_IMG_COUNT_MSG = messages.getString(\"TargetAppRunner_SingleImgCountMsg\"); // NOI18N\n        AVG_METHOD_TIME_MSG = messages.getString(\"TargetAppRunner_AvgMethodTimeMsg\"); // NOI18N\n        MIN_METHOD_TIME_MSG = messages.getString(\"TargetAppRunner_MinMethodTimeMsg\"); // NOI18N\n        MAX_METHOD_TIME_MSG = messages.getString(\"TargetAppRunner_MaxMethodTimeMsg\"); // NOI18N\n        TOTAL_RUN_TIME_MSG = messages.getString(\"TargetAppRunner_TotalRunTimeMsg\"); // NOI18N\n        INJ_INSTR_TIME_MSG = messages.getString(\"TargetAppRunner_InjInstrTimeMsg\"); // NOI18N\n        TOTAL_INSTR_HOTSWAP_TIME_MSG = messages.getString(\"TargetAppRunner_TotalInstrHotSwapTimeMsg\"); // NOI18N\n        BYTECODE_COMM_TIME_MSG = messages.getString(\"TargetAppRunner_ByteCodeCommTimeMsg\"); // NOI18N\n        CLIENT_BYTECODE_TIME_MSG = messages.getString(\"TargetAppRunner_ClientByteCodeTimeMsg\"); // NOI18N\n        CLIENT_DISK_PROCESS_MSG = messages.getString(\"TargetAppRunner_ClientDiskProcessTimeMsg\"); // NOI18N\n        CLIENT_RESULTS_PROCESS_MSG = messages.getString(\"TargetAppRunner_ClientResultsProcessTimeMsg\"); // NOI18N\n        PERFORMING_CALIBRATION_MSG = messages.getString(\"TargetAppRunner_PerformingCalibrationMsg\"); // NOI18N\n    }\n                                                                                                                             // -----\n    private static final boolean DEBUG = System.getProperty(\"org.graalvm.visualvm.lib.jfluid.TargetAppRunner\") != null; // NOI18N\n    private static TargetAppRunner defaultTAR; // Ok only while we don't have multiple profiling sessions\n    private static final int EVENT_STARTED = 0;\n    private static final int EVENT_STOPPED = 1;\n    private static final int EVENT_SUSPENDED = 2;\n    private static final int EVENT_RESUMED = 3;\n    private static final int EVENT_ATTACHED = 4;\n    private static final int EVENT_TERMINATED = 5;\n    private static final int EVENT_DETACHED = 6;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    // Required for dialog shown during calibration\n    private AppStatusHandler appStatusHandler;\n    private Process runningAppProcess;\n    private ProfilerClient profilerClient;\n    private ProfilerEngineSettings settings;\n    private ProfilingSessionStatus status;\n    private Collection<ProfilingEventListener> listeners = new CopyOnWriteArraySet<>();\n    private boolean targetAppIsSuspended;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------    \n    \n    public TargetAppRunner(ProfilerEngineSettings settings, AppStatusHandler ash, ProfilingPointsProcessor ppp) {\n        this.settings = settings;\n        status = new ProfilingSessionStatus();\n        appStatusHandler = ash;\n\n        profilerClient = new ProfilerClient(settings, status, appStatusHandler, ppp,\n                                            new AppStatusHandler.ServerCommandHandler() {\n                public void handleServerCommand(Command cmd) {\n                    if (cmd != null) {\n                        if (cmd.getType() == Command.MESSAGE) {\n                            AsyncMessageCommand msg = (AsyncMessageCommand) cmd;\n\n                            if (msg.isPositive()) {\n//                                appStatusHandler.displayNotification(msg.getMessage());\n                            } else {\n                                appStatusHandler.displayError(msg.getMessage());\n\n                                //profilerClient.setCurrentInstrType(INSTR_NONE);\n                                // It looks like it often makes more sense to ignore the problem and get at least some info...\n                            }\n                        } else if (cmd.getType() == Command.RESULTS_AVAILABLE) {\n                            appStatusHandler.resultsAvailable();\n                        } else if (cmd.getType() == Command.TAKE_SNAPSHOT) {\n                            appStatusHandler.takeSnapshot();\n                        }\n                    }\n                }\n            });\n        defaultTAR = this;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static TargetAppRunner getDefault() {\n        return defaultTAR;\n    }\n\n    public AppStatusHandler getAppStatusHandler() {\n        return appStatusHandler;\n    }\n\n    public String getInternalStats() throws ClientUtils.TargetAppOrVMTerminated {\n        InternalStatsResponse stats = (status.savedInternalStats != null) ? status.savedInternalStats\n                                                                          : profilerClient.getInternalStats();\n\n        return getInternalStatsText(stats);\n    }\n\n    public ProfilerClient getProfilerClient() {\n        return profilerClient;\n    }\n\n    public ProfilerEngineSettings getProfilerEngineSettings() {\n        return settings;\n    }\n\n    public ProfilingSessionStatus getProfilingSessionStatus() {\n        return status;\n    }\n\n    public Process getRunningAppProcess() {\n        return runningAppProcess;\n    }\n\n    public void addProfilingEventListener(ProfilingEventListener profilingEventListener) {\n        listeners.add(profilingEventListener);\n    }\n\n    /**\n     * Attaches to a running application. It is expected that prepareForAttach method is called before this one\n     * to prepare the target app environment for attaching.\n     *\n     */\n    public boolean attachToTargetVM() {\n        if (connectToStartedVMAndStartTA(1, false)) {\n            status.runningInAttachedMode = true;\n            notifyListeners(EVENT_ATTACHED);\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * Attach to the started and waiting target JVM using the \"attach on startup\" method\n     */\n    public boolean attachToTargetVMOnStartup() {\n        if (connectToStartedVMAndStartTA(2, false)) {\n            status.runningInAttachedMode = true;\n            notifyListeners(EVENT_ATTACHED);\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * This call runs the target JVM instance just to calibrate (that is, measure the time it takes to execute)\n     * the instrumentation code that we then inject into target app code. The results are saved to be reused\n     * in subsequent runs.\n     */\n    public boolean calibrateInstrumentationCode() {\n        status.targetJDKVersionString = settings.getTargetJDKVersionString();\n\n        AppStatusHandler.AsyncDialog waitDialog =\n                appStatusHandler.getAsyncDialogInstance(PERFORMING_CALIBRATION_MSG, false, null);\n        waitDialog.display();\n\n        boolean res = false;\n\n        try {\n            if (!runJVMToCalibrateInstrumentation()) {\n                return false;\n            }\n\n            res = CalibrationDataFileIO.saveCalibrationData(status);\n\n            return true;\n        } finally {\n            waitDialog.close();\n\n            if (res) {\n                StringBuffer s = new StringBuffer();\n                s.append(CALIBRATION_SUMMARY_DETAILS_MSG);\n                appendCalibrationData(s);\n                appStatusHandler.displayNotificationWithDetailsAndWaitForConfirm(CALIBRATION_SUMMARY_SHORT_MSG, s.toString());\n            } else {\n                appStatusHandler.displayErrorAndWaitForConfirm(CalibrationDataFileIO.getErrorMessage());\n            }\n        }\n    }\n\n    /**\n     * Connects to the target JVM started using startTargetVM(), and starts the target application.\n     * Error reporting happens in the same way as in runTargetApp().\n     */\n    public boolean connectToStartedVMAndStartTA() {\n        return connectToStartedVMAndStartTA(false);\n    }\n\n    public void prepareDetachFromTargetJVM() {\n        try {\n            profilerClient.prepareDetachFromTargetJVM();\n        } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n            /* No need to say anything if it's already terminated */\n        }\n    }\n\n    public void detachFromTargetJVM() {\n        if (targetAppIsSuspended) {\n            try {\n                profilerClient.resumeTargetAppThreads();\n            } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n            }\n\n            targetAppIsSuspended = false;\n        }\n\n        try {\n            profilerClient.detachFromTargetJVM();\n            notifyListeners(EVENT_DETACHED);\n        } catch (ClientUtils.TargetAppOrVMTerminated ex) { /* No need to say anything if it's already terminated */\n        }\n\n        targetAppIsSuspended = false;\n    }\n\n    public boolean hasSupportedJDKForHeapDump() {\n        // not supported for JDK other than 10+ & 1.9 & 1.8 & 1.7 & 1.6 & 1.5.0_12 and up\n        String jdkVersion = getProfilerEngineSettings().getTargetJDKVersionString();\n\n        if (CommonConstants.JDK_15_STRING.equals(jdkVersion)) {\n            String fullJDKString = getProfilingSessionStatus().fullTargetJDKVersionString;\n            int minorVersion = Platform.getJDKMinorNumber(fullJDKString);\n\n            if (minorVersion >= 12) {\n                return true;\n            }\n            return false;\n        }\n        if (CommonConstants.JDK_CVM_STRING.equals(jdkVersion)\n           || CommonConstants.JDK_UNSUPPORTED_STRING.equals(jdkVersion)\n           ) {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     *  Initiates profiling session\n     * @param attachMode 0 = no attach; 1 = direct; 2 = dynamic\n     * @param calibrationOnlyRun\n     * @param cancel shared cancel flag\n     * @return Returns TRUE if the connection to the profiler agent has been successfully established\n     */\n    public boolean initiateSession(int attachMode, boolean calibrationOnlyRun, AtomicBoolean cancel) {\n        if (targetJVMIsAlive()) {\n            return true;\n        }\n\n        return profilerClient.establishConnectionWithServer(attachMode, calibrationOnlyRun, cancel);\n    }\n    \n    /**\n     *  Initiates profiling session\n     * @param attachMode 0 = no attach; 1 = direct; 2 = dynamic\n     * @param calibrationOnlyRun\n     * @return Returns TRUE if the connection to the profiler agent has been successfully established\n     */\n    public boolean initiateSession(int attachMode, boolean calibrationOnlyRun) {\n        return initiateSession(attachMode, calibrationOnlyRun, new AtomicBoolean(false));\n    }\n\n    /**\n     * @return true if the calibration data was read successfully, false otherwise\n     */\n    public boolean readSavedCalibrationData() {\n        status.targetJDKVersionString = settings.getTargetJDKVersionString();\n\n        int res = CalibrationDataFileIO.readSavedCalibrationData(status);\n\n        if (res < 0) { // Fatal error with reading saved file data - report the details\n            appStatusHandler.displayErrorAndWaitForConfirm(CalibrationDataFileIO.getErrorMessage());\n        }\n\n        return (res == 0);\n    }\n\n    public void removeProfilingEventListener(ProfilingEventListener profilingEventListener) {\n        listeners.remove(profilingEventListener);\n    }\n\n    public void resetTimers() throws ClientUtils.TargetAppOrVMTerminated {\n        profilerClient.resetProfilerCollectors();\n    }\n\n    public void resumeTargetAppIfSuspended() throws ClientUtils.TargetAppOrVMTerminated {\n        if (targetAppIsSuspended) {\n            profilerClient.resumeTargetAppThreads();\n            targetAppIsSuspended = false;\n            notifyListeners(EVENT_RESUMED);\n        }\n    }\n\n    public void runGC() throws ClientUtils.TargetAppOrVMTerminated {\n        profilerClient.runGC();\n    }\n\n    /**\n     * Starts the the target JVM, that then waits for the tool to establish the socket connection and start the\n     * TA itself). This function returns boolean indicating success or failure, however the actual problem is\n     * reported inside it using methods of the AppStatusHandler passed to this TargetAppRunner.\n     */\n    public boolean startTargetVM() {\n        return startTargetVM(settings.getJVMArgs(), settings.getMainClassName(), settings.getMainArgs(),\n                             settings.getWorkingDir(), settings.getSeparateConsole());\n    }\n\n    public void suspendTargetAppIfRunning() throws ClientUtils.TargetAppOrVMTerminated {\n        if (!targetAppIsSuspended) {\n            profilerClient.suspendTargetAppThreads();\n            targetAppIsSuspended = true;\n            notifyListeners(EVENT_SUSPENDED);\n        }\n    }\n\n    public boolean targetAppIsRunning() {\n        return status.targetAppRunning;\n    }\n\n    public boolean targetAppSuspended() {\n        return targetAppIsSuspended;\n    }\n\n    public boolean targetJVMIsAlive() {\n        return profilerClient.targetJVMIsAlive();\n    }\n\n    public void terminateTargetJVM() {\n        if (targetAppIsSuspended) {\n            try {\n                profilerClient.resumeTargetAppThreads();\n            } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n            }\n\n            targetAppIsSuspended = false;\n        }\n\n        try {\n            profilerClient.terminateTargetJVM();\n            notifyListeners(EVENT_TERMINATED);\n        } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n            /* Probably no need to say anything if it's already terminated */\n        }\n\n        targetAppIsSuspended = false;\n    }\n\n    //---------------------------- Statistics printing routines ----------------------------------\n\n    /**\n     * Note that this displayed statistics is really current, i.e. it may be newer than CPU results currently displayed\n     */\n    private String getInternalStatsText(InternalStatsResponse r) {\n        NumberFormat nf = NumberFormat.getInstance();\n        nf.setMaximumFractionDigits(2);\n\n        StringBuffer s = new StringBuffer(1000);\n\n        s.append(INTERNAL_STATISTICS_ONLY_MSG);\n\n        double wholeGraphGrossTimeAbs = CPUCCTContainer.getWholeGraphGrossTimeAbsForDisplayedThread();\n        double timeInInjectedCode = CPUCCTContainer.getTimeInInjectedCodeForDisplayedThread();\n        double totalRunTime = wholeGraphGrossTimeAbs + r.totalHotswappingTime + r.clientInstrTime + r.clientDataProcTime;\n\n        s.append(MessageFormat.format(INSTR_METHODS_COUNT_MSG, new Object[] { \"\" + r.nTotalInstrMethods })); // NOI18N\n        s.append(\"\\n\"); // NOI18N\n        s.append(MessageFormat.format(CLASSLOAD_FIRSTINV_COUNT_MSG,\n                                      new Object[] { \"\" + r.nClassLoads, \"\" + r.nFirstMethodInvocations })); // NOI18N\n        s.append(\"\\n\"); // NOI18N\n        s.append(MessageFormat.format(NON_EMPTY_IMG_COUNT_MSG, new Object[] { \"\" + r.nNonEmptyInstrMethodGroupResponses })); // NOI18N\n        s.append(\"\\n\"); // NOI18N\n        s.append(MessageFormat.format(EMPTY_IMG_COUNT_MSG, new Object[] { \"\" + r.nEmptyInstrMethodGroupResponses })); // NOI18N\n        s.append(\"\\n\"); // NOI18N\n        s.append(MessageFormat.format(SINGLE_IMG_COUNT_MSG, new Object[] { \"\" + r.nSingleMethodInstrMethodGroupResponses })); // NOI18N\n        s.append(\"\\n\"); // NOI18N\n\n        if (r.nNonEmptyInstrMethodGroupResponses > 0) {\n            s.append(MessageFormat.format(AVG_METHOD_TIME_MSG, new Object[] { nf.format(r.averageHotswappingTime) }));\n            s.append(\"\\n\"); // NOI18N\n            s.append(MessageFormat.format(MIN_METHOD_TIME_MSG, new Object[] { nf.format(r.minHotswappingTime) }));\n            s.append(\"\\n\"); // NOI18N\n            s.append(MessageFormat.format(MAX_METHOD_TIME_MSG, new Object[] { nf.format(r.maxHotswappingTime) }));\n            s.append(\"\\n\"); // NOI18N\n        }\n\n        s.append(\"\\n\"); // NOI18N\n\n        s.append(MessageFormat.format(TOTAL_RUN_TIME_MSG, new Object[] { nf.format(totalRunTime) }));\n        s.append(\"\\n\"); // NOI18N\n\n        if (totalRunTime == 0.0) {\n            totalRunTime = 1.0; // Just to avoid funny percentage figures in this case\n        }\n\n        s.append(MessageFormat.format(INJ_INSTR_TIME_MSG,\n                                      new Object[] {\n                                          nf.format(timeInInjectedCode), nf.format(timeInInjectedCode / totalRunTime * 100)\n                                      }));\n        s.append(\"\\n\"); // NOI18N\n        s.append(MessageFormat.format(TOTAL_INSTR_HOTSWAP_TIME_MSG,\n                                      new Object[] {\n                                          nf.format(r.totalHotswappingTime),\n                                          nf.format(r.totalHotswappingTime / totalRunTime * 100)\n                                      }));\n        s.append(\"\\n\"); // NOI18N\n        s.append(MessageFormat.format(BYTECODE_COMM_TIME_MSG,\n                                      new Object[] { nf.format(r.clientInstrTime), nf.format(r.clientInstrTime / totalRunTime * 100) }));\n        s.append(\"\\n\"); // NOI18N\n        s.append(MessageFormat.format(CLIENT_BYTECODE_TIME_MSG, new Object[] { \"\" + profilerClient.getInstrProcessingTime() })); // NOI18N\n        s.append(\"\\n\"); // NOI18N\n        s.append(MessageFormat.format(CLIENT_DISK_PROCESS_MSG,\n                                      new Object[] {\n                                          nf.format(r.clientDataProcTime), nf.format(r.clientDataProcTime / totalRunTime * 100)\n                                      }));\n        s.append(\"\\n\"); // NOI18N\n                        // no idea what is this supposed to do; put it back if someone has a clue\n                        //    EventBufferProcessor eb = profilerClient.getCPUCallGraphBuilder();\n                        //    if (eb == null) {\n                        //      eb = profilerClient.getMemoryCallGraphBuilder();\n                        //    }\n                        //    long dataProcessingTime = (eb != null) ? EventBufferProcessor.getDataProcessingTime() : 0;\n\n        long dataProcessingTime = EventBufferProcessor.getDataProcessingTime();\n        s.append(MessageFormat.format(CLIENT_RESULTS_PROCESS_MSG, new Object[] { \"\" + dataProcessingTime })); // NOI18N\n        s.append(\"\\n\"); // NOI18N\n        s.append(\"\\n\"); // NOI18N\n\n        appendCalibrationData(s);\n        s.append(\"\\n\"); // NOI18N\n\n        return s.toString();\n    }\n\n    private void appendCalibrationData(StringBuffer s) {\n        NumberFormat nf = NumberFormat.getInstance();\n        nf.setMaximumFractionDigits(4);\n\n        long cntsInSec = status.timerCountsInSecond[0];\n        double m0 = (((double) status.methodEntryExitCallTime[0]) * 1000000) / cntsInSec; // Expressed in microseconds\n        double m1 = (((double) status.methodEntryExitCallTime[1]) * 1000000) / cntsInSec; // Ditto\n        double m2 = (((double) status.methodEntryExitCallTime[2]) * 1000000) / cntsInSec; // Ditto\n        double m4 = (((double) status.methodEntryExitCallTime[4]) * 1000000) / cntsInSec; // Ditto\n\n        s.append(MessageFormat.format(CALIBRATION_RESULTS_MSG,\n                                      new Object[] { nf.format(m0), nf.format(m1), nf.format(m2), nf.format(m4) }));\n    }\n\n    private boolean connectToStartedVMAndStartTA(boolean calibrationOnlyRun) {\n        if (!connectToStartedVMAndStartTA(0, calibrationOnlyRun)) {\n            return false;\n        }\n\n        status.runningInAttachedMode = false;\n        notifyListeners(EVENT_STARTED);\n\n        return true;\n    }\n\n    //--------------------------------- Private implementation ------------------------------------\n\n    /**\n     * attachMode can have the following values:\n     * 0 - application started from under the tool; 1 - attach to the running application; 2 - attach on startup.\n     * calibrationOnlyRun == true means that we run the target JVM just to obtain instrumentation calibration data.\n     */\n    private boolean connectToStartedVMAndStartTA(int attachMode, boolean calibrationOnlyRun) {\n        //    if (!profilerClient.establishConnectionWithServer(attachMode != 0, calibrationOnlyRun)) {\n        //      appStatusHandler.displayError(FAILED_ESTABLISH_CONN_MSG);\n        //      return false;\n        //    }\n        if (calibrationOnlyRun) {\n            return true;\n        }\n\n        boolean sendExplicitStartCommand = (attachMode != 1);\n\n        try {\n            return profilerClient.startTargetApp(sendExplicitStartCommand);\n        } catch (ClientUtils.TargetAppOrVMTerminated e1) {\n            String message = UNEXPECTED_PROBLEM_STARTING_APP_MSG;\n\n            if (e1.isVMTerminated()) {\n                message += JVM_TERMINATED_NOTRESPOND_STRING;\n            } else {\n                message += INTERNAL_PROBLEM_STRING;\n            }\n\n            appStatusHandler.displayError(message);\n\n            return false;\n        } catch (ClientUtils.TargetAppFailedToStart e2) {\n            appStatusHandler.displayError(MessageFormat.format(FAILED_START_APP_CAUSE_MSG, new Object[] { e2.getOrigCause() }));\n\n            return false;\n        }\n    }\n\n    private void notifyListeners(int event) {\n        for (ProfilingEventListener target : listeners) {\n            switch (event) {\n                case EVENT_STARTED:\n                    target.targetAppStarted();\n\n                    break;\n                case EVENT_STOPPED:\n                    target.targetAppStopped();\n\n                    break;\n                case EVENT_SUSPENDED:\n                    target.targetAppSuspended();\n\n                    break;\n                case EVENT_RESUMED:\n                    target.targetAppResumed();\n\n                    break;\n                case EVENT_TERMINATED:\n                    target.targetVMTerminated();\n\n                    break;\n                case EVENT_ATTACHED:\n                    target.attachedToTarget();\n\n                    break;\n                case EVENT_DETACHED:\n                    target.detachedFromTarget();\n\n                    break;\n            }\n        }\n    }\n\n    //-------------------------- Calibration-related routines ----------------------------------\n    private boolean runJVMToCalibrateInstrumentation() {\n        boolean result = startTargetVM(new String[] {  }, CALIBRATION_PSEUDO_CLASS_NAME, new String[] {  }, \".\", settings.getSeparateConsole()); // NOI18N\n\n        if (!result) {\n            return false;\n        }\n\n        result = initiateSession(0, true);\n\n        //    result = connectToStartedVMAndStartTA(true);\n        //    if (!result) {\n        //      return false;\n        //    }\n        while (targetJVMIsAlive()) {\n            try {\n                Thread.sleep(100);\n            } catch (Exception ex) {\n                // ignore\n            }\n        }\n\n        if (status.timerCountsInSecond[0] == 0) { // Data not received?\n            appStatusHandler.displayErrorAndWaitForConfirm(CALIBRATION_ERROR_MSG);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    private boolean startTargetVM(String[] jvmArgs, String mainClassName, String[] mainArgs, String workingDir,\n                                  boolean separateConsole) {\n        boolean isWindows = Platform.isWindows();\n        status.savedInternalStats = null;\n\n        File dir = new File(workingDir);\n\n        String classPathArg = settings.getMainClassPath(); // Note that this returns user.dir if not set\n\n        // Create the classpath containing the JFluid server-side classes, that is passed to the target VM\n        String libPath = settings.getJFluidRootDirName();\n        String jdkVer = settings.getTargetJDKVersionString();\n\n        if (!jdkVer.equals(JDK_CVM_STRING) && !jdkVer.equals(JDK_UNSUPPORTED_STRING)) {\n            // for now the 1.6 and 1.7 and 1.8 and 9 and 10+ profiling uses the same jfluid-server as 1.5\n            jdkVer = JDK_15_STRING;\n        }\n\n        jdkVer = jdkVer.substring(3); // Convert e.g. \"jdk15\" into just \"15\"\n\n        String jFluidCP = libPath + File.separator + \"jfluid-server.jar\" // NOI18N\n                          + File.pathSeparator + libPath + File.separator + \"jfluid-server-\" // NOI18N\n                          + jdkVer + \".jar\"; // NOI18N\n\n        String[] newJVMArgs = new String[jvmArgs.length];\n        int idx = 0;\n\n        for (int i = 0; i < jvmArgs.length; i++) {\n            if ((jvmArgs[i].equals(\"-classpath\") || jvmArgs[i].equals(\"-cp\")) && ((i + 1) < jvmArgs.length)) { // NOI18N\n                                                                                                               // The user shouldn't set the classpath here, so let's ignore it.\n                appStatusHandler.displayWarning(CLASSPATH_SETTINGS_IGNORED_MSG);\n                i++;\n\n                //classPathArg += File.pathSeparator;\n                //classPathArg += jvmArgs[++i];\n            } else {\n                newJVMArgs[idx++] = jvmArgs[i];\n            }\n        }\n\n        ArrayList commands = new ArrayList(10);\n\n        if (separateConsole) {\n            if (isWindows) {\n                commands.add(\"cmd.exe\"); // NOI18N\n                commands.add(\"/K\"); // NOI18N\n                commands.add(\"start\"); // NOI18N\n                commands.add(\"\\\"Profiled Application Console\\\"\"); // NOI18N\n\n                if (settings.getTargetWindowRemains()) {\n                    commands.add(\"cmd\"); // This is used to prevent the window from closing if, say, // NOI18N\n                    commands.add(\"/K\"); // the target JVM crashes. // NOI18N\n                }\n            } else { // Solaris\n                commands.add(\"xterm\"); // NOI18N\n                commands.add(\"-sb\"); // NOI18N\n                commands.add(\"-sl\"); // NOI18N\n                commands.add(\"1000\"); // NOI18N\n                commands.add(\"-e\"); // NOI18N\n            }\n        }\n\n        commands.add(settings.getTargetJVMExeFile());\n\n        String jdk = settings.getTargetJDKVersionString();\n        if (!jdk.equals(Platform.JDK_CVM_STRING) &&\n            !jdk.equals(Platform.JDK_UNSUPPORTED_STRING)\n        ) {\n            int architecture = settings.getSystemArchitecture();\n            String jfNativeLibFullName = Platform.getAgentNativeLibFullName(settings.getJFluidRootDirName(), false,\n                                                                            settings.getTargetJDKVersionString(),\n                                                                            architecture);\n            commands.add(\"-agentpath:\" + jfNativeLibFullName); // NOI18N\n            if (Platform.isSolaris() && architecture == ARCH_64) {\n                if (jdkVer.equals(JDK_15_STRING)\n                    || jdkVer.equals(JDK_16_STRING)\n                    || jdkVer.equals(JDK_17_STRING)\n                    || jdkVer.equals(JDK_18_STRING)\n                    || jdkVer.equals(JDK_19_STRING)) {\n                    // -d64 is supported from JDK 1.5 to JDK 9\n                    commands.add(\"-d64\");\n                }\n            }\n        }\n\n        commands.add(\"-Xbootclasspath/a:\" + jFluidCP); // NOI18N\n\n        if ((classPathArg != null) && !classPathArg.isEmpty()) { // NOI18N\n            commands.add(\"-classpath\"); // NOI18N\n            commands.add(classPathArg);\n        }\n\n        if (!isWindows && settings.getTargetWindowRemains()) {\n            commands.add(\"-XX:+ShowMessageBoxOnError\"); // NOI18N\n        }\n\n        if (Platform.isLinux() && settings.getTargetJDKVersionString().equals(Platform.JDK_16_STRING)) {\n            commands.add(\"-XX:+UseLinuxPosixThreadCPUClocks\"); // NOI18N\n        }\n        for (String newJVMArg : newJVMArgs) {\n            commands.add(newJVMArg);\n        }\n\n        // debugging property for agent side - wire I/O\n        if (System.getProperty(\"org.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO.agent\") != null) { // NOI18N\n            commands.add(\"-Dorg.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO=true\"); // NOI18N\n        }\n\n        // debugging property for agent side - Class loader hook\n        if (System.getProperty(\"org.graalvm.visualvm.lib.jfluid.server.ProfilerInterface.classLoadHook\") != null) { // NOI18N\n            commands.add(\"-Dorg.graalvm.visualvm.lib.jfluid.server.ProfilerInterface.classLoadHook=true\"); // NOI18N\n        }\n\n        commands.add(\"org.graalvm.visualvm.lib.jfluid.server.ProfilerServer\"); // NOI18N\n\n        // Really needed by ProfilerServer only in JDK 1.4.2, to call System.load() with this param - TODO: check this\n        commands.add(Platform.getJFluidNativeLibDirName(settings.getJFluidRootDirName(), settings.getTargetJDKVersionString(),\n                                                        settings.getSystemArchitecture()));\n        commands.add(Integer.toString(settings.getPortNo()));\n\n        // 10 seconds is the default timeout, can be set via the profiler.agent.connect.timeout property\n        String timeOut = System.getProperty(\"profiler.agent.connect.timeout\", \"10\"); // NOI18N\n        commands.add(timeOut);\n\n        if (mainClassName != null) {\n            commands.add(mainClassName);\n        }\n\n        for (String mainArg : mainArgs) {\n            commands.add(mainArg);\n        }\n\n        String[] cmdArray = (String[])commands.toArray(new String[0]);\n\n        MiscUtils.printInfoMessage(\"Starting target application...\"); // NOI18N\n        MiscUtils.printVerboseInfoMessage(cmdArray);\n\n        if (DEBUG) {\n            System.err.println(\"TargetAppRunner.DEBUG: Starting VM with \" + cmdArray.length + \" commands.\"); // NOI18N\n\n            for (int i = 0; i < cmdArray.length; i++) {\n                System.err.println(\"TargetAppRunner.DEBUG: cmd[\" + i + \"] = >\" + cmdArray[i] + \"<\"); // NOI18N\n            }\n        }\n\n        try {\n            ProcessBuilder builder = new ProcessBuilder(cmdArray).directory(dir);\n            builder.redirectError(ProcessBuilder.Redirect.INHERIT);\n            builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);\n            runningAppProcess = builder.start();\n        } catch (IOException ex) {\n            StringBuilder sb = new StringBuilder();\n\n            for (String cmdArray1 : cmdArray) {\n                sb.append(cmdArray1).append('\\n'); // NOI18N\n            }\n\n            appStatusHandler.displayError(MessageFormat.format(ERROR_STARTING_JVM_MSG, new Object[] { sb, ex }));\n\n            return false;\n        }\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/classfile/BaseClassInfo.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.classfile;\n\n\n/**\n * Minimum representation of a class. Used as a base class for the full-fledged ClassInfo, but also\n * may used as is for e.g. array classes.\n *\n * @author Misha Dmitirev\n */\npublic class BaseClassInfo {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected String name;\n    protected String nameAndLoader; // A combinarion of class name and loader, uniquely identifying this ClassInfo\n\n    // Management of multiple versions for the same-named (but possibly not same-code) class, loaded by different classloaders\n    protected int classLoaderId; // IDs of all loaders with which versions of this class are loaded\n\n    // Data used by our object allocation instrumentation mechanism: integer class ID\n    private int instrClassId;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public BaseClassInfo(String className, int classLoaderId) {\n        this.name = className.intern();\n        this.classLoaderId = classLoaderId;\n        nameAndLoader = (name + \"#\" + classLoaderId).intern(); // NOI18N\n        instrClassId = -1;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setInstrClassId(int id) {\n        instrClassId = id;\n    }\n\n    public int getInstrClassId() {\n        return instrClassId;\n    }\n\n    public void setLoaderId(int loaderId) {\n        classLoaderId = loaderId;\n    }\n\n    public int getLoaderId() {\n        return classLoaderId;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public String getNameAndLoader() {\n        return nameAndLoader;\n    }\n\n    public String toString() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/classfile/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/classfile/ClassFileCache.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.classfile;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipException;\nimport java.util.zip.ZipFile;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.FileOrZipEntry;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\n\n\n/**\n * Fixed-size cache of binary classes (.class files). Used to avoid flooding memory with class files when performing intensive\n * method scanning, that may touch thousands of classes. Currently uses LRU eviction policy.\n * A separate, currently no-eviction cache, is maintained for classes supplied by the VM.\n *\n * @author Misha Dmitirev\n */\nclass ClassFileCache {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ClassPath classPath; // Used to quickly obtain an open JAR file for a given name\n    private Map vmSuppliedClassCache;\n    private byte[][] classFileBytes;\n    private String[] classNameAndLocation;\n    private long[] lastTimeUsed;\n    private int capacity;\n    private int size;\n    private int sizeLimit;\n    private long timeCounter;\n    private List preloadNames;\n    private List preloadLoaderIds;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    //------------ We don't expect the below API to be used outside of this package, hence it's package-private ------------\n    ClassFileCache(ClassPath cp) {\n        capacity = 877; // FIXME: may be worth setting size flexibly, or adjusting inside cache if too many evictions happen\n        size = 0;\n        sizeLimit = (capacity * 3) / 4;\n        classNameAndLocation = new String[capacity];\n        classFileBytes = new byte[capacity][];\n        lastTimeUsed = new long[capacity];\n\n        vmSuppliedClassCache = new HashMap();\n        preloadNames = new ArrayList();\n        preloadLoaderIds = new ArrayList();\n        classPath = cp;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    byte[] getClassFile(String name, String location) throws IOException {\n        String nameAndLocation = (name + \"#\" + location).intern(); // NOI18N\n        byte[] res;\n\n        if (location.startsWith(ClassRepository.LOCATION_VMSUPPLIED)) {\n            res = (byte[]) vmSuppliedClassCache.get(nameAndLocation);\n            if (res != null && res.length == 0) {\n                try {\n                    // known class without bytecode; get it from TA\n                    ProfilerClient client = TargetAppRunner.getDefault().getProfilerClient();\n                    if (!preloadNames.contains(name)) {\n                        preloadBytecode(name, location);\n                    }\n                    String names[] = (String[]) preloadNames.toArray(new String[0]);\n                    int loadersId[] = new int[preloadLoaderIds.size()];\n                    for (int i=0; i<loadersId.length; i++) {\n                        loadersId[i] = ((Integer)preloadLoaderIds.get(i)).intValue();\n                    }\n                    //System.out.println(\"Caching \"+names.length+\" classes\");\n                    byte[][] bytes = client.getCachedClassFileBytes(names, loadersId);\n                    for (int i=0; i<bytes.length; i++) {\n                        res = bytes[i];\n                        if (res == null) res = new byte[0];\n                        //System.out.println(\"Get class file for \" + names[i] + \" \" + res.length + \" bytes\");\n                        if (res.length != 0) {\n                            vmSuppliedClassCache.put(getNameAndLocation(names[i],loadersId[i]), res);\n                        }\n                    }\n                    preloadNames = new ArrayList();\n                    preloadLoaderIds = new ArrayList();\n                    res = (byte[]) vmSuppliedClassCache.get(nameAndLocation);\n                    if (res.length == 0) {\n                        throw new IOException(\"Get class file for \" + name + \" not found in TA\");\n                    }\n                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                    throw new IOException(ex);\n                }\n            }\n        } else {\n            res = get(nameAndLocation);\n\n            if (res == null) {\n                if (size > sizeLimit) {\n                    removeLRUEntry();\n                }\n\n                res = readAndPut(name, location, nameAndLocation);\n            }\n        }\n\n        return res;\n    }\n\n    void preloadBytecode(String name, String location) {\n        String nameAndLocation = (name + \"#\" + location).intern(); // NOI18N\n        if (location.startsWith(ClassRepository.LOCATION_VMSUPPLIED)) {\n            byte[] res = (byte[]) vmSuppliedClassCache.get(nameAndLocation);\n            if (res != null && res.length == 0) {\n                // known class without bytecode; get it from TA\n                preloadNames.add(name);\n                String loaderIdStr = location.substring(ClassRepository.LOCATION_VMSUPPLIED.length());\n                preloadLoaderIds.add(Integer.valueOf(loaderIdStr));\n            }\n        }\n    }\n\n    void addVMSuppliedClassFile(String name, int classLoaderId, byte[] buf) {\n        String nameAndLocation = getNameAndLocation(name, classLoaderId); \n        vmSuppliedClassCache.put(nameAndLocation, buf);\n    }\n\n    private String getNameAndLocation(String name, int classLoaderId) {\n        return (name + \"#\" + ClassRepository.getClassFileLoc(classLoaderId)).intern(); // NOI18N\n    }\n\n    /**\n     * Returns the actual class loader id for the given class/loader pair, or -1 if class is not loaded.\n     * The real loader may be the same as classLoaderId or its parent loader.\n     */\n    int hasVMSuppliedClassFile(String name, int classLoaderId) {\n        do {\n            // we are trying the whole classloader hierarchy up to the root system classloader with id=0\n            String nameAndLocation = getNameAndLocation(name, classLoaderId);  \n            boolean res = vmSuppliedClassCache.containsKey(nameAndLocation);\n\n            if (res) {\n                return classLoaderId;\n            } else if (classLoaderId != 0) {\n                classLoaderId = classPath.getClassLoaderTable().getParentLoader(classLoaderId);\n            }\n\n            if (classLoaderId == -1) {\n                MiscUtils.printWarningMessage(\"Failed to lookup classloader for: \" + name); // NOI18N\n\n                return -1;\n            }\n        } while (classLoaderId != 0);\n\n        return -1;\n    }\n\n    //---------------------------------------- Private implementation -------------------------------------------\n    private byte[] get(String nameAndLocation) {\n        int pos = (nameAndLocation.hashCode() & 0x7FFFFFFF) % capacity;\n\n        while ((classNameAndLocation[pos] != null) && (classNameAndLocation[pos] != nameAndLocation)) {\n            pos = (pos + 1) % capacity;\n        }\n\n        if (classNameAndLocation[pos] != null) {\n            lastTimeUsed[pos] = ++timeCounter;\n\n            return classFileBytes[pos];\n        } else {\n            return null;\n        }\n    }\n\n    private byte[] readAndPut(String name, String classFileLocation, String nameAndLocation)\n                       throws IOException {\n        byte[] classFile = readClassFile(name, classFileLocation);\n        int pos = (nameAndLocation.hashCode() & 0x7FFFFFFF) % capacity;\n\n        while (classNameAndLocation[pos] != null) {\n            pos = (pos + 1) % capacity;\n        }\n\n        classNameAndLocation[pos] = nameAndLocation;\n        classFileBytes[pos] = classFile;\n        lastTimeUsed[pos] = ++timeCounter;\n        size++;\n\n        return classFile;\n    }\n\n    private byte[] readClassFile(String name, String classFileLocation)\n                          throws IOException {\n        String classFileName = name + \".class\"; // NOI18N\n        File location = new File(classFileLocation);\n\n        if (location.isDirectory()) {\n            return MiscUtils.readFileIntoBuffer(new FileOrZipEntry(classFileLocation, classFileName));\n        } else { // Should be .jar file\n                 // The following code may be used at different stages of JFluid work, with different initialization states, so\n                 // it's coded defensively. If it can use an available open ZipFile, it will use it, otherwise it will open its own.\n\n            ZipFile zip = null;\n\n            if (classPath != null) {\n                try {\n                    zip = classPath.getZipFileForName(classFileLocation);\n                } catch (ZipException e2) {\n                    throw new IOException(\"Could not open archive \" + classFileLocation); // NOI18N\n                }\n            } else {\n                throw new IOException(\"Could not get classpath for \" + classFileName + \" in \" + classFileLocation); // NOI18N\n            }\n\n            ZipEntry entry = zip.getEntry(classFileName);\n\n            if (entry == null) {\n                throw new IOException(\"Could not find entry for \" + classFileName + \" in \" + classFileLocation); // NOI18N\n            }\n\n            int len = (int) entry.getSize();\n            byte[] buf = new byte[len];\n            try (InputStream in = zip.getInputStream(entry)) {\n                int readBytes;\n                int ofs = 0;\n                int remBytes = len;\n\n                do {\n                    readBytes = in.read(buf, ofs, remBytes);\n                    ofs += readBytes;\n                    remBytes -= readBytes;\n                } while (ofs < len);\n            }\n\n            return buf;\n        }\n    }\n\n    private void removeLRUEntry() {\n        long leastTime = 0x7FFFFFFFFFFFFFFFL;\n        int pos = 0;\n\n        for (int i = 0; i < capacity; i++) {\n            if ((lastTimeUsed[i] > 0) && (lastTimeUsed[i] < leastTime)) {\n                pos = i;\n            }\n        }\n\n        classNameAndLocation[pos] = null;\n        classFileBytes[pos] = null;\n        lastTimeUsed[pos] = 0;\n        size--;\n\n        return;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/classfile/ClassFileParser.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.classfile;\n\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassInfo.LocalVariableTables;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassInfo.LocalVariableTypeTables;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.JavaClassConstants;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\n\n\n/**\n * This class implements parsing a byte array representing a class file, generating a ClassInfo object.\n *\n * @author Misha Dmitirev\n * @author Tomas Hurka\n */\npublic class ClassFileParser implements JavaClassConstants {\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class ClassFileReadException extends Exception {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        ClassFileReadRuntimeException e;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        private ClassFileReadException(ClassFileReadRuntimeException e) {\n            this.e = e;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public Throwable getCause() {\n            return e;\n        }\n\n        public String getMessage() {\n            return e.getMessage();\n        }\n\n        public String toString() {\n            return e.toString();\n        }\n    }\n\n    private static class ClassFileReadRuntimeException extends RuntimeException {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ClassFileReadRuntimeException(String msg) {\n            super(msg);\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ClassInfo classInfo;\n    private byte[] classBuf;\n    private Object[] cpObjectCache;\n    private int[] cpOffsets;\n    private byte[] cpTags;\n    private int curBufPos;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void parseClassFile(byte[] classFile, ClassInfo classInfo)\n                        throws ClassFileReadException {\n        classBuf = classFile;\n        this.classInfo = classInfo;\n        curBufPos = 0;\n\n        try {\n            readPreamble();\n            readConstantPool();\n            readIntermediate();\n            skipFields();\n            readMethods();\n            readAttributes();\n        } catch (ClassFileReadRuntimeException e) {\n            throw new ClassFileReadException(e);\n        }\n    }\n\n    private char getChar(int bufPos) {\n        return (char) (((classBuf[bufPos++] & 255) << 8) + (classBuf[bufPos++] & 255));\n    }\n\n    private void badCPEntry(int entryNo) { // TODO CHECK: unused method\n        throw classFileReadException(\"Constant pool entry \" + entryNo + \" : invalid type\"); // NOI18N\n    }\n\n    private void badCPReference(int ofs, int i) {\n        throw classFileReadException(\"Bad constant pool reference: \" + ofs + \" from entry \" + i); // NOI18N\n    }\n\n    private ClassFileReadRuntimeException classFileReadException(String msg) {\n        msg = \"Error reading class \" + classInfo.name + \":\\n\" + msg; // NOI18N\n\n        return new ClassFileReadRuntimeException(msg);\n    }\n\n    /**\n     * Read class name at the given CONSTANT_Utf8 constant pool index, and return it\n     * trimmed of the possible 'L' prefix and ';' suffix.\n     */\n    private String classNameAtCPIndex(int idx) {\n        if (cpTags[idx] != CONSTANT_Utf8) {\n            throw classFileReadException(\"Constant pool entry \" + idx + \" should be UTF8 constant\"); // NOI18N\n        }\n\n        int arrayLevel = 0;\n\n        if (cpObjectCache[idx] == null) {\n            int utf8Len = getChar(cpOffsets[idx]);\n            int stPos = cpOffsets[idx] + 2;\n            int initStPos = stPos;\n\n            while (classBuf[stPos] == '[') { // NOI18N\n                stPos++;\n                arrayLevel++;\n            }\n\n            if (stPos != initStPos) {\n                if (classBuf[stPos] == 'L') { // NOI18N   // Non-primitive array type\n                    stPos++;\n                    utf8Len--; // To get rid of the terminating ';'\n                }\n            }\n\n            utf8Len = utf8Len - (stPos - initStPos);\n\n            String res = StringUtils.utf8ToString(classBuf, stPos, utf8Len);\n\n            for (int i = 0; i < arrayLevel; i++) {\n                res = \"[\" + res; // NOI18N\n            }\n\n            cpObjectCache[idx] = res;\n        }\n\n        return (String) cpObjectCache[idx];\n    }\n\n    private ClassFileReadRuntimeException dataFormatError() { // TODO CHECK: unused method\n\n        return classFileReadException(\"Data format error\"); // NOI18N\n    }\n\n    private char nextChar() {\n        return (char) (((classBuf[curBufPos++] & 255) << 8) + (classBuf[curBufPos++] & 255));\n    }\n\n    private int nextInt() {\n        return ((classBuf[curBufPos++] & 255) << 24) + ((classBuf[curBufPos++] & 255) << 16)\n               + ((classBuf[curBufPos++] & 255) << 8) + (classBuf[curBufPos++] & 255);\n    }\n\n    /**\n     * This method actually reads only the information related to the nested classes, and\n     * records only those of them which are first level nested classes of this class. The class\n     * may also reference other classes which are not package members through the same\n     * InnerClasses attribute - their names would be processed when their respective enclosing\n     * classes are read.\n     */\n    private void readAttributes() {\n        int i;\n        int j;\n\n        classInfo.attrsStartOfs = curBufPos;\n\n        char attrCount = nextChar();\n\n        for (i = 0; i < attrCount; i++) {\n            int attrNameIdx = nextChar();\n            int attrLen = nextInt();\n\n            if (utf8AtCPIndex(attrNameIdx).equals(\"InnerClasses\")) { // NOI18N\n\n                int nOfClasses = nextChar();\n                String[] nestedClasses = new String[nOfClasses];\n                int curIdx = 0;\n                int nonMemberClassCount = 0;\n\n                for (j = 0; j < nOfClasses; j++) {\n                    int innerClassInfoIdx = nextChar();\n                    int outerClassInfoIdx = nextChar();\n                    int innerClassNameIdx = nextChar();\n                    char innerClassAccessFlags = nextChar();\n\n                    String nestedClassFullName = classNameAtCPIndex(getChar(cpOffsets[innerClassInfoIdx]));\n\n                    // We are not interested in references to nested classes whose enclosing class is not this one.\n                    if (innerClassNameIdx != 0) {\n                        String nestedClassSimpleName = utf8AtCPIndex(innerClassNameIdx);\n\n                        if (!nestedClassFullName.equals(classInfo.name + \"$\" + nestedClassSimpleName)) { // NOI18N\n                                                                                                         // Let's check if it's a local class, with the name like \"EncClass$1$Local\"\n\n                            int count = nonMemberClassCount + 1;\n\n                            if (!nestedClassFullName.equals(classInfo.name + \"$\" + count + \"$\" + nestedClassSimpleName)) { // NOI18N\n                                continue;\n                            } else {\n                                nonMemberClassCount = count;\n                            }\n                        }\n                    } else {\n                        nonMemberClassCount++;\n\n                        if (!nestedClassFullName.equals(classInfo.name + \"$\" + nonMemberClassCount)) { // NOI18N\n                            continue;\n                        }\n                    }\n\n                    nestedClasses[curIdx++] = nestedClassFullName;\n                }\n\n                if (curIdx == nOfClasses) {\n                    classInfo.nestedClassNames = nestedClasses;\n                } else if (curIdx > 0) {\n                    // We found fewer nested classes for this class than we originally expected, but still more than 0.\n                    // Create a new array to fit their number exactly.\n                    classInfo.nestedClassNames = new String[curIdx];\n                    System.arraycopy(nestedClasses, 0, classInfo.nestedClassNames, 0, curIdx);\n                }\n\n                break;\n            } else {\n                curBufPos += attrLen;\n            }\n        }\n    }\n\n    private void readConstantPool() {\n        int methodRefsNo = 0;\n        int classRefsNo = 0;\n\n        classInfo.cpoolStartOfs = curBufPos;\n        classInfo.origCPoolCount = nextChar();\n        cpOffsets = new int[classInfo.origCPoolCount];\n        cpTags = new byte[classInfo.origCPoolCount];\n\n        int cpStart = curBufPos;\n        int len;\n        int i = 1;\n\n        while (i < cpOffsets.length) {\n            byte tag = classBuf[curBufPos++];\n            cpOffsets[i] = curBufPos;\n            cpTags[i] = tag;\n            i++;\n\n            switch (tag) {\n                case CONSTANT_Utf8:\n                    len = nextChar();\n                    curBufPos += len;\n\n                    break;\n                case CONSTANT_Class:\n                    classRefsNo++;\n                case CONSTANT_String:\n                case CONSTANT_MethodType:\n                case CONSTANT_Module:\n                case CONSTANT_Package:\n                    curBufPos += 2;\n\n                    break;\n                case CONSTANT_MethodHandle:\n                    curBufPos += 3;\n                    break;\n                case CONSTANT_Fieldref:\n                case CONSTANT_NameAndType:\n                case CONSTANT_Integer:\n                case CONSTANT_Float:\n                case CONSTANT_Dynamic:\n                case CONSTANT_InvokeDynamic:\n                    curBufPos += 4;\n\n                    break;\n                case CONSTANT_Methodref:\n                case CONSTANT_InterfaceMethodref:\n                    methodRefsNo++;\n                    curBufPos += 4;\n\n                    break;\n                case CONSTANT_Long:\n                case CONSTANT_Double:\n                    curBufPos += 8;\n                    i++;\n\n                    break;\n                default:\n                    throw classFileReadException(\"Bad constant pool tag: \" + tag + \" at \" + Integer.toString(curBufPos - 1)); // NOI18N\n            }\n        }\n\n        classInfo.cpoolRefsToMethodIdx = new char[methodRefsNo];\n        classInfo.cpoolRefsToMethodClassNameAndSig = new String[methodRefsNo][3];\n        classInfo.cpoolRefsToClassIdx = new char[classRefsNo];\n        classInfo.cpoolRefsToClassName = new String[classRefsNo];\n\n        int curMethodRef = 0;\n        int curClassRef = 0;\n        cpObjectCache = new Object[cpOffsets.length];\n\n        for (i = 0; i < cpOffsets.length; i++) {\n            int ofs = cpOffsets[i];\n\n            if ((cpTags[i] == CONSTANT_Methodref) || (cpTags[i] == CONSTANT_InterfaceMethodref)) {\n                classInfo.cpoolRefsToMethodIdx[curMethodRef] = (char) i;\n                classInfo.cpoolRefsToMethodClassNameAndSig[curMethodRef] = new String[3];\n\n                int classIdx = getChar(ofs);\n                int nameAndTypeIdx = getChar(ofs + 2);\n\n                if ((cpTags[classIdx] != CONSTANT_Class) || (cpTags[nameAndTypeIdx] != CONSTANT_NameAndType)) {\n                    badCPReference(ofs, i);\n                }\n\n                classInfo.cpoolRefsToMethodClassNameAndSig[curMethodRef][0] = classNameAtCPIndex(getChar(cpOffsets[classIdx]));\n                ofs = cpOffsets[nameAndTypeIdx];\n\n                int nameIdx = getChar(ofs);\n                int sigIdx = getChar(ofs + 2);\n\n                if ((cpTags[nameIdx] != CONSTANT_Utf8) || (cpTags[sigIdx] != CONSTANT_Utf8)) {\n                    badCPReference(ofs, i);\n                }\n\n                classInfo.cpoolRefsToMethodClassNameAndSig[curMethodRef][1] = utf8AtCPIndex(nameIdx);\n                classInfo.cpoolRefsToMethodClassNameAndSig[curMethodRef][2] = signatureAtCPIndex(sigIdx);\n                curMethodRef++;\n            } else if (cpTags[i] == CONSTANT_Class) {\n                classInfo.cpoolRefsToClassIdx[curClassRef] = (char) i;\n                classInfo.cpoolRefsToClassName[curClassRef] = classNameAtCPIndex(getChar(ofs));\n                curClassRef++;\n            }\n        }\n    }\n\n    private void readIntermediate() {\n        int i;\n        int classIdx;\n        int superClassIdx;\n\n        classInfo.intermediateDataStartOfs = curBufPos;\n        classInfo.accessFlags = nextChar();\n        classInfo.classIndex = classIdx = nextChar();\n\n        if (cpTags[classIdx] != CONSTANT_Class) {\n            throw classFileReadException(\"Bad reference to this class name\"); // NOI18N\n        }\n\n        classInfo.name = classNameAtCPIndex(getChar(cpOffsets[classIdx]));\n        superClassIdx = nextChar();\n\n        if (cpTags[superClassIdx] != CONSTANT_Class) {\n            if ((superClassIdx == 0) && classInfo.name.equals(CommonConstants.OBJECT_SLASHED_CLASS_NAME)) {\n                classInfo.superName = CommonConstants.OBJECT_SLASHED_CLASS_NAME;\n            } else {\n                throw classFileReadException(\"Bad reference to super class name\"); // NOI18N\n            }\n        } else {\n            classInfo.superName = classNameAtCPIndex(getChar(cpOffsets[superClassIdx]));\n        }\n\n        char intfCount = nextChar();\n\n        if (intfCount != 0) {\n            classInfo.interfaces = new String[intfCount];\n\n            for (i = 0; i < intfCount; i++) {\n                classIdx = nextChar();\n\n                if (cpTags[classIdx] != CONSTANT_Class) {\n                    throw classFileReadException(\"Bad reference to an implemented interface\"); // NOI18N\n                }\n\n                classInfo.interfaces[i] = classNameAtCPIndex(getChar(cpOffsets[classIdx]));\n            }\n        }\n    }\n\n    private void readMethods() {\n        classInfo.methodsStartOfs = curBufPos;\n\n        char methodCount = nextChar();\n\n        if (methodCount == 0) {\n            classInfo.methodNames = new String[0];\n\n            return;\n        }\n\n        String[] names = new String[methodCount];\n        String[] signatures = new String[methodCount];\n        char[] accessFlags = new char[methodCount];\n        int[] methodInfoOffsets = new int[methodCount];\n        int[] methodInfoLengths = new int[methodCount];\n        int[] bytecodeOffsets = new int[methodCount];\n        char[] bytecodeLengths = new char[methodCount];\n        int[] exceptionTableStartOffsets = new int[methodCount];\n        int[] lineNumberTableOffsets = new int[methodCount];\n        char[] lineNumberTableLengths = new char[methodCount];\n        int[] localVariableTableOffsets = new int[methodCount];\n        char[] localVariableTableLengths = new char[methodCount];\n        int localVaribaleTableCPindex = 0;\n        int[] localVariableTypeTableOffsets = new int[methodCount];\n        char[] localVariableTypeTableLengths = new char[methodCount];\n        int localVaribaleTypeTableCPindex = 0;\n        int[] stackMapTableOffsets = new int[methodCount];\n        char[] stackMapTableLengths = new char[methodCount];\n        int stackMapTableCPindex = 0;\n        \n        for (int i = 0; i < methodCount; i++) {\n            methodInfoOffsets[i] = curBufPos;\n            accessFlags[i] = nextChar();\n            names[i] = utf8AtCPIndex(nextChar());\n            signatures[i] = signatureAtCPIndex(nextChar());\n            bytecodeOffsets[i] = 0;\n            lineNumberTableOffsets[i] = 0;\n            localVariableTableOffsets[i] = 0;\n            localVariableTypeTableOffsets[i] = 0;\n            \n            int attrCount = nextChar();\n\n            for (int j = 0; j < attrCount; j++) {\n                int attrNameIdx = nextChar();\n                int attrLen = nextInt();\n\n                if (utf8AtCPIndex(attrNameIdx).equals(\"Code\")) { // NOI18N\n                    curBufPos += 4; // Skip max_stack and max_locals\n\n                    char codeLen = bytecodeLengths[i] = (char) nextInt();\n                    bytecodeOffsets[i] = curBufPos - methodInfoOffsets[i];\n                    curBufPos += codeLen;\n                    exceptionTableStartOffsets[i] = curBufPos - methodInfoOffsets[i];\n\n                    int count = nextChar(); // Exception table length\n                    curBufPos += (8 * count); // Skip exception table\n                    count = nextChar(); // Attribute (or rather sub-attribute) count\n\n                    for (int k = 0; k < count; k++) {\n                        attrNameIdx = nextChar();\n                        attrLen = nextInt();\n\n                        if (utf8AtCPIndex(attrNameIdx).equals(\"LineNumberTable\")) { // NOI18N\n                            char tableLen = lineNumberTableLengths[i] = nextChar();\n                            lineNumberTableOffsets[i] = curBufPos - methodInfoOffsets[i];\n                            curBufPos += (4 * tableLen);\n                        } else if (utf8AtCPIndex(attrNameIdx).equals(\"LocalVariableTable\")){    // NOI18N\n                            char tableLen = localVariableTableLengths[i] = nextChar();\n                            localVariableTableOffsets[i] = curBufPos - methodInfoOffsets[i];\n                            curBufPos += LocalVariableTables.ATTR_SIZE * tableLen;\n                            if (localVaribaleTableCPindex == 0) {\n                                localVaribaleTableCPindex = attrNameIdx;\n                            } else {\n                                assert localVaribaleTableCPindex == attrNameIdx;\n                            }\n                        } else if (utf8AtCPIndex(attrNameIdx).equals(\"LocalVariableTypeTable\")){    // NOI18N\n                            char tableLen = localVariableTypeTableLengths[i] = nextChar();\n                            localVariableTypeTableOffsets[i] = curBufPos - methodInfoOffsets[i];\n                            curBufPos += LocalVariableTypeTables.ATTR_SIZE * tableLen;\n                            if (localVaribaleTypeTableCPindex == 0) {\n                                localVaribaleTypeTableCPindex = attrNameIdx;\n                            } else {\n                                assert localVaribaleTypeTableCPindex == attrNameIdx;\n                            }\n                        } else if (utf8AtCPIndex(attrNameIdx).equals(\"StackMapTable\")){    // NOI18N\n                            char tableLen = stackMapTableLengths[i] = nextChar();\n                            stackMapTableOffsets[i] = curBufPos - methodInfoOffsets[i];\n                            curBufPos += attrLen - 2;\n                            if (stackMapTableCPindex == 0) {\n                                stackMapTableCPindex = attrNameIdx;\n                            } else {\n                                assert stackMapTableCPindex == attrNameIdx;\n                            }\n//                            LOG.info(\"StackMapTable size:\"+(tableLen+0)+\" for class:\"+classInfo.name+\" method:\"+ names[i]);\n                        } else {\n                            curBufPos += attrLen;\n                        }\n                    }\n                } else {\n                    curBufPos += attrLen;\n                }\n            }\n\n            methodInfoLengths[i] = curBufPos - methodInfoOffsets[i];\n        }\n\n        classInfo.methodNames = names;\n        classInfo.methodSignatures = signatures;\n        classInfo.methodAccessFlags = accessFlags;\n        classInfo.methodInfoOffsets = methodInfoOffsets;\n        classInfo.methodInfoLengths = methodInfoLengths;\n        classInfo.methodBytecodesOffsets = bytecodeOffsets;\n        classInfo.methodBytecodesLengths = bytecodeLengths;\n        classInfo.exceptionTableStartOffsets = exceptionTableStartOffsets;\n        classInfo.lineNumberTablesOffsets = lineNumberTableOffsets;\n        classInfo.lineNumberTablesLengths = lineNumberTableLengths;\n        classInfo.localVariableTablesOffsets = localVariableTableOffsets;\n        classInfo.localVariableTablesLengths = localVariableTableLengths;\n        classInfo.localVaribaleTableCPindex = localVaribaleTableCPindex;\n        classInfo.localVariableTypeTablesOffsets = localVariableTypeTableOffsets;\n        classInfo.localVariableTypeTablesLengths = localVariableTypeTableLengths;\n        classInfo.localVaribaleTypeTableCPindex = localVaribaleTypeTableCPindex;\n        classInfo.stackMapTablesOffsets = stackMapTableOffsets;\n        classInfo.stackMapTablesLengths = stackMapTableLengths;\n        classInfo.stackMapTableCPindex = stackMapTableCPindex;\n    }\n\n    private void readPreamble() {\n        int magic = nextInt();\n\n        if (magic != JAVA_MAGIC) {\n            throw classFileReadException(\"Illegal start of class file\"); // NOI18N\n        }\n\n        int minorVersion = nextChar();\n        int majorVersion = nextChar();\n\n        if ((majorVersion > JAVA_MAJOR_VERSION)\n                || (((majorVersion * 1000) + minorVersion) < ((JAVA_MIN_MAJOR_VERSION * 1000) + JAVA_MIN_MINOR_VERSION))) {\n            String versionCode = majorVersion + \".\" + minorVersion; // NOI18N\n            String message = \"Unsupported class file version: \" + versionCode; // NOI18N\n            throw classFileReadException(message);\n        }\n        classInfo.majorVersion = majorVersion;\n    }\n\n    private String signatureAtCPIndex(int idx) {\n        return utf8AtCPIndex(idx);\n    }\n\n    private void skipFields() {\n        classInfo.fieldsStartOfs = curBufPos;\n\n        char definedFieldCount = nextChar();\n\n        for (int i = 0; i < definedFieldCount; i++) {\n            curBufPos += 6; // skip 3 chars: flags, name index and signature index\n\n            int attrCount = nextChar();\n\n            for (int j = 0; j < attrCount; j++) {\n                curBufPos += 2; // Skip char: attr name index\n\n                int attrLen = nextInt();\n                curBufPos += attrLen;\n            }\n        }\n    }\n\n    private String utf8AtCPIndex(int idx) {\n        if (cpTags[idx] != CONSTANT_Utf8) {\n            throw classFileReadException(\"Constant pool entry \" + idx + \" should be UTF8 constant\"); // NOI18N\n        }\n\n        if (cpObjectCache[idx] == null) {\n            int utf8Len = getChar(cpOffsets[idx]);\n            cpObjectCache[idx] = StringUtils.utf8ToString(classBuf, cpOffsets[idx] + 2, utf8Len);\n        }\n\n        return (String) cpObjectCache[idx];\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/classfile/ClassInfo.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.classfile;\n\nimport java.io.IOException;\nimport java.lang.reflect.Modifier;\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassInfo.StackMapFrame.FrameType;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.JavaClassConstants;\n\n\n/**\n * A representation of a binary Java class, that is relatively compact - it does not contain method bodies,\n * and contains only a subset of information from the constant pool. Method bodies (or, more precisely, byte\n * arrays representing either full MethodInfos as defined in JVM Specification, or just method bodies), can\n * be obtained individually on demand.\n *\n * This class is abstract, since it contains a single abstract method that actually returns the class file bytes\n * for the whole class. Concrete subclasses of this class may choose to simply store this byte array, or retrieve\n * it e.g. from disk on demand.\n *\n * @author Misha Dmitirev\n * @author Tomas Hurka\n */\npublic abstract class ClassInfo extends BaseClassInfo implements JavaClassConstants, CommonConstants {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class LineNumberTables {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private char[][] lineNumbers;\n        private char[][] startPCs;\n        private boolean hasTable;\n\n        //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n        LineNumberTables(ClassInfo ci) {\n            byte[] classBuf;\n\n            try {\n                classBuf = ci.getClassFileBytes();\n            } catch (IOException ex1) { // Should not happen - class file already loaded once by this time\n                throw new RuntimeException(ex1);\n            } catch (ClassNotFoundException ex2) { // Dtto\n                 throw new RuntimeException(ex2);\n            }\n\n            int nMethods = ci.getMethodNames().length;\n            startPCs = new char[nMethods][];\n            lineNumbers = new char[nMethods][];\n\n            for (int i = 0; i < nMethods; i++) {\n                int ofs = ci.methodInfoOffsets[i] + ci.lineNumberTablesOffsets[i];\n\n                if (ofs == -1) {\n                    continue; // Abstract or native method, or no line number tables in this class\n                }\n\n                hasTable = true;\n\n                int tableLen = ci.lineNumberTablesLengths[i];\n                char[] startPC = startPCs[i] = new char[tableLen];\n                char[] lineNumber = lineNumbers[i] = new char[tableLen];\n\n                for (int j = 0; j < tableLen; j++) {\n                    startPC[j] = (char) (((classBuf[ofs++] & 255) << 8) + (classBuf[ofs++] & 255));\n                    lineNumber[j] = (char) (((classBuf[ofs++] & 255) << 8) + (classBuf[ofs++] & 255));\n                }\n            }\n        }\n        \n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public char[][] getStartPCs() {\n            return startPCs;\n        }\n\n        int[] getMinAndMaxLinesForMethod(int methodIdx) {\n            int[] lines = new int[2];\n\n            if (startPCs[methodIdx] == null) { // No line number table for this method - return special value\n                lines[0] = lines[1] = -1;\n\n                return lines;\n            }\n\n            lines[0] = 10000000;\n            lines[1] = -10000000;\n\n            char[] lns = lineNumbers[methodIdx];\n\n            for (int i = 0; i < lns.length; i++) {\n                if (lns[i] < lines[0]) {\n                    lines[0] = lns[i];\n                }\n\n                if (lns[i] > lines[1]) {\n                    lines[1] = lns[i];\n                }\n            }\n\n            return lines;\n        }\n\n        int bciForLineNo(int methodIdx, int lineNo) {\n            char[] spcs = startPCs[methodIdx];\n\n            if (spcs == null) {\n                return -1;\n            }\n\n            int tableLen = spcs.length;\n            char[] lns = lineNumbers[methodIdx];\n\n            int minLine = 100000000;\n            int bestLine = 100000000;\n            int maxLine = 0;\n\n            int curLine = -1;\n            int bestBCI = 100000000;\n\n            for (int i = 0; i < tableLen; i++) {\n                curLine = lns[i];\n\n                if (curLine > maxLine) {\n                    maxLine = curLine;\n                }\n\n                if (curLine < minLine) {\n                    minLine = curLine;\n                }\n\n                if (curLine == lineNo) { // Perfect match\n                    bestBCI = spcs[i];\n\n                    break;\n                } else if ((curLine > lineNo) && (curLine <= bestLine)) { // Update bci/line\n\n                    if (spcs[i] < bestBCI) { // ..but check first if it's the smallest bci for this line.\n                                             // The whole issue is due to 'while() { }' effectively compiled as 'do { } while()', where for the actual\n                                             // line of the 'while' statementwe get two different bci's in the line number table:\n                                             // 1. the one for the initial 'goto' that transfers us to the condition check block in the end of the loop body\n                                             // 2. the first bci of that condition check block.\n                                             // Whether we hit this line as the first or the last line of our code fragment, the smallest bci is a correct answer.\n                        bestBCI = spcs[i];\n                        bestLine = curLine;\n                    }\n                }\n            }\n\n            // Found a valid matching line if there is a perfect match or at least the specified\n            // line is within this method's line number table.\n            if ((curLine == lineNo) || ((lineNo >= minLine) && (lineNo <= maxLine))) {\n                return bestBCI;\n            } else {\n                return -1;\n            }\n        }\n\n        int lineNoForBci(int methodIdx, int bci) {\n            char[] spcs = startPCs[methodIdx];\n\n            if (spcs == null) {\n                return -1;\n            }\n\n            int tableLen = spcs.length;\n            char[] lns = lineNumbers[methodIdx];\n\n            int bestLine = -1;\n\n            for (int i = 0; i < tableLen; i++) {\n                if (spcs[i] > bci) {\n                    break; // reached in last cycle\n                }\n\n                bestLine = lns[i];\n            }\n\n            return bestLine;\n        }\n\n        private boolean hasTable() {\n            return hasTable;\n        }\n    }\n\n    public static class LocalVariableTables {\n\n        public static final int ATTR_SIZE = 10;\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private char[][] lengths;\n        private char[][] startPCs;\n        private boolean hasTable;\n\n        //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n        LocalVariableTables(ClassInfo ci) {\n            this(ci, ci.localVariableTablesOffsets, ci.localVariableTablesLengths);\n        }\n        \n        private LocalVariableTables(ClassInfo ci, int[] tablesOffsets, char[] tablesLengths) {\n            byte[] classBuf;\n\n            try {\n                classBuf = ci.getClassFileBytes();\n            } catch (IOException ex1) { // Should not happen - class file already loaded once by this time\n                throw new RuntimeException(ex1);\n            } catch (ClassNotFoundException ex2) {  // Ditto\n                throw new RuntimeException(ex2);\n            }\n\n            int nMethods = ci.getMethodNames().length;\n            startPCs = new char[nMethods][];\n            lengths = new char[nMethods][];\n\n            for (int i = 0; i < nMethods; i++) {\n                int tableLen = tablesLengths[i];\n\n                if (tableLen == 0) {\n                    continue;\n                }\n                int ofs = ci.methodInfoOffsets[i] + tablesOffsets[i];\n                char[] startPC = startPCs[i] = new char[tableLen];\n                char[] length = lengths[i] = new char[tableLen];\n\n                for (int j = 0; j < tableLen; j++, ofs+=ATTR_SIZE ) {\n                    int offset = ofs;\n                    startPC[j] = (char) (((classBuf[offset++] & 255) << 8) + (classBuf[offset++] & 255));\n                    length[j] = (char) (((classBuf[offset++] & 255) << 8) + (classBuf[offset++] & 255));\n                }\n                hasTable = true;\n            }\n        }\n        \n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        char[][] getStartPCs() {\n            return startPCs;\n        }\n\n        char[][] getLengts() {\n            return lengths;\n        }\n\n        public boolean hasTable() {\n            return hasTable;\n        }\n        \n        public void updateTable(int injectionPos, int injectedBytesCount, int methodIdx) {\n            if (hasTable()) {\n                char[] startPC = getStartPCs()[methodIdx];\n                char[] lengths = getLengts()[methodIdx];\n\n                if (startPC != null) {\n                    for (int i = 0; i < startPC.length; i++) {\n                        char currentBCI = startPC[i];\n                        if (currentBCI >= injectionPos) {\n                            startPC[i] = (char)(currentBCI + injectedBytesCount);\n                        } else {\n                            char currentLength = lengths[i];\n                            if (currentBCI + currentLength > injectionPos) {\n                                 lengths[i] = (char)(currentLength + injectedBytesCount);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    \n        public void writeTable(final byte[] buffer, int locVarTablePtr, int methodIdx) {\n            char[] startPC = getStartPCs()[methodIdx];\n            char[] lengths = getLengts()[methodIdx];\n\n            if (startPC != null) {\n                for (int i = 0; i < startPC.length; i++, locVarTablePtr+=ATTR_SIZE) {\n                    putU2(buffer, locVarTablePtr, startPC[i]);\n                    putU2(buffer, locVarTablePtr + 2, lengths[i]);\n                }\n            }\n        }  \n    }\n        \n    public static class LocalVariableTypeTables extends LocalVariableTables {\n\n        LocalVariableTypeTables(ClassInfo ci) {\n            super(ci, ci.localVariableTypeTablesOffsets, ci.localVariableTypeTablesLengths);\n        }\n    }\n//    public static Logger LOG = Logger.getLogger(ClassInfo.class.getName());   \n    public class StackMapTables {\n        private StackMapFrame[][] frames;\n        private byte[][] framesBytes;\n        private boolean hasTable;\n         \n        StackMapTables() {\n            byte[] classBuf;\n\n            try {\n                classBuf = ClassInfo.this.getClassFileBytes();\n            } catch (IOException ex1) { // Should not happen - class file already loaded once by this time\n                throw new RuntimeException(ex1);\n            } catch (ClassNotFoundException ex2) { // Ditto\n                throw new RuntimeException(ex2);\n            }\n\n            int nMethods = ClassInfo.this.getMethodNames().length;\n            frames = new StackMapFrame[nMethods][];\n            framesBytes = new byte[nMethods][];\n            for (int i = 0; i < nMethods; i++) {\n                int tableLen = ClassInfo.this.stackMapTablesLengths[i];\n\n                if (tableLen == 0) {\n                    continue;\n                }\n                int startOfs = ClassInfo.this.methodInfoOffsets[i] + ClassInfo.this.stackMapTablesOffsets[i];\n                int ofs = startOfs;\n                StackMapFrame[] frms = frames[i] = new StackMapFrame[tableLen];\n//                LOG.finer(\"Class \"+ClassInfo.this.name+\" method \"+ClassInfo.this.getMethodName(i));\n                for (int j = 0; j < tableLen; j++) {\n                    frms[j] = new StackMapFrame(classBuf,ofs);\n                    ofs+=frms[j].getSize();\n//                    LOG.finer(frms[j].toString());\n                }\n                int len = ofs - startOfs;\n                framesBytes[i] = new byte[len+tableLen+2*(StackMapFrame.FrameType.FULL_FRAME.size()+2*3)];\n                System.arraycopy(classBuf,startOfs,framesBytes[i],0,len);\n                hasTable = true;\n            }\n        }\n\n        public boolean hasTable() {\n            return hasTable;\n        }\n\n        public void updateTable(int injectionPos, int injectedBytesCount, int methodIdx, boolean changeTypeIsInjectNewInstr, boolean injectionBindsToFollowingInstruction) {\n            String method = getMethodName(methodIdx);\n            if (hasTable()) {\n                StackMapFrame[] frms = frames[methodIdx];\n                \n                if (frms != null) {\n                    int bciIter = -1;\n                    boolean  offsetAdjusted = false; // only need to adjust one offset\n                    \n                    for (StackMapFrame frame : frms) {\n                        int offsetDelta = frame.getOffsetDelta();\n                        bciIter += offsetDelta;\n\n                        if (!offsetAdjusted) {\n                            if (adjustOffset(bciIter, injectionPos, changeTypeIsInjectNewInstr, injectionBindsToFollowingInstruction)) {\n                                setOffsetDelta(methodIdx, frame, offsetDelta + injectedBytesCount);\n                                offsetAdjusted = true;\n                            }\n                        }\n                        frame.updateUnitilializedList(injectionPos, injectedBytesCount, changeTypeIsInjectNewInstr, injectionBindsToFollowingInstruction);\n                    }\n                }                \n            }\n        }\n        \n        public int getNumberOfFrames(int methodIdx) {\n            StackMapFrame[] frms = frames[methodIdx];\n            \n            if (frms != null) {\n                return frms.length;\n            }\n            return 0;\n        }\n\n        public byte[] getAttributeHeader(int methodIdx) {\n            byte[] header = new byte[8];\n            putU2(header,0,ClassInfo.this.stackMapTableCPindex);\n            return header;\n        }\n        \n        public byte[] writeTable(int methodIdx) {\n            StackMapFrame[] frms = frames[methodIdx];\n            byte frameBytes[] = framesBytes[methodIdx];\n            \n            if (frms != null) {\n                byte[] ret;\n                int offset = 0;\n                \n                for (StackMapFrame frame : frms) {\n                    frame.writeFrame(frameBytes, offset);\n                    offset+=frame.getSize();\n                }\n                ret = new byte[offset];\n                System.arraycopy(frameBytes,0,ret,0,offset);\n                return ret;\n            }\n            return null;\n        }\n\n        void addFullStackMapFrameEntry(int methodIdx, int endPC, int[] locals, int[] stacks) {\n            StackMapFrame[] frms = frames[methodIdx];\n            StackMapFrame[] newFrms;\n\n            if (frms != null) {\n                int bciIter = -1;\n\n                for (StackMapFrame frame : frms) {\n                    bciIter += frame.getOffsetDelta();\n                }\n                newFrms = frames[methodIdx] = new StackMapFrame[frms.length+1];\n                System.arraycopy(frms,0,newFrms,0,frms.length);\n                newFrms[frms.length] = new FullStackMapFrame(endPC - bciIter, locals, stacks);\n            } else {\n                newFrms = frames[methodIdx] = new StackMapFrame[1];\n                newFrms[0] = new FullStackMapFrame(endPC + 1, locals, stacks);\n                framesBytes[methodIdx] = new byte[newFrms[0].getSize()];\n                hasTable = true;\n            }\n        }\n\n        private void setOffsetDelta(int methodIdx, StackMapFrame frame, int newOffsetDelta) {\n            FrameType frameType = frame.frameType;\n            \n            if (frameType.equals(FrameType.SAME) && newOffsetDelta > 63) {\n                 extendFrame(methodIdx,frame,2);\n                frame.setFrameType(FrameType.SAME_FRAME_EXTENDED);\n            }\n            if (frameType.equals(FrameType.SAME_LOCALS_1_STACK_ITEM) && newOffsetDelta > 63) {\n                extendFrame(methodIdx,frame,2);\n                frame.setFrameType(FrameType.SAME_LOCALS_1_STACK_ITEM_EXTENDED);\n            }\n            frame.setOffsetDelta(newOffsetDelta);\n        }\n\n        private void extendFrame(int methodIdx, StackMapFrame frame, int addBytes) {\n             StackMapFrame[] frms = frames[methodIdx];\n             byte[] data = framesBytes[methodIdx];\n             int offset = 0;\n             \n             for (StackMapFrame f : frms) {\n                 if (f == frame) {\n                     break;\n                 }\n                 offset += f.getSize();\n             }\n             System.arraycopy(data,offset,data,offset+addBytes,data.length-offset-addBytes);\n        }\n    }\n    \n    static class StackMapFrame {\n        enum FrameType {\n            SAME(1),\n            SAME_LOCALS_1_STACK_ITEM(1),\n            SAME_LOCALS_1_STACK_ITEM_EXTENDED(3),\n            CHOP(3),\n            SAME_FRAME_EXTENDED(3),\n            APPEND(3),\n            FULL_FRAME(7);\n                    \n            private int frameSize;\n\n            int size() {return frameSize;}\n\n            FrameType(int size){\n               frameSize = size;\n            }\n        }\n        \n        FrameType frameType;\n        int storedOffsetDelta;\n        int size;\n        boolean modified;\n        boolean frameModified;\n        boolean uninitializedListModified;\n        List<Integer> uninitializedList;\n        \n        StackMapFrame(FrameType type, int offset, int s) {\n            frameType = type;\n            storedOffsetDelta = offset - 1;\n            size = type.size()+s;\n        }\n        \n        StackMapFrame(byte[] buffer, int offset) {\n            int type;\n            \n            type = buffer[offset++] & 0xff;\n            if (type <= 63) {\n                frameType = FrameType.SAME;\n                storedOffsetDelta = type;\n            } else if (type <= 127) {\n                frameType = FrameType.SAME_LOCALS_1_STACK_ITEM;\n                storedOffsetDelta = type - 64;\n                size = getVerificationTypeInfoSize(buffer[offset]);\n                storeUninitializedVariableInfo(buffer,offset,0);\n            } else if (type <= 246) {\n                throw new IllegalArgumentException(\"Type: \"+type);\n            } else if (type == 247) {\n                frameType = FrameType.SAME_LOCALS_1_STACK_ITEM_EXTENDED;\n                storedOffsetDelta = getU2(buffer,offset);\n                offset+=2;\n                size = getVerificationTypeInfoSize(buffer[offset]);\n                storeUninitializedVariableInfo(buffer,offset,0);\n            } else if (type <= 250) {\n                frameType = FrameType.CHOP;\n                storedOffsetDelta = getU2(buffer,offset);\n            } else if (type == 251) {\n                frameType = FrameType.SAME_FRAME_EXTENDED;\n                storedOffsetDelta = getU2(buffer,offset);\n            } else if (type <= 254) {\n                frameType = FrameType.APPEND;\n                storedOffsetDelta = getU2(buffer,offset);\n                offset+=2;\n                int locals = type - 251;\n                for (int i=0; i<locals; i++) {\n                    int typeInfoSize = getVerificationTypeInfoSize(buffer[offset]);\n                    size += typeInfoSize;\n                    storeUninitializedVariableInfo(buffer,offset,i);\n                    offset += typeInfoSize;\n                }\n            } else if (type == 255) {\n                frameType = FrameType.FULL_FRAME;\n                storedOffsetDelta = getU2(buffer,offset);\n                offset+=2;\n                int locals = getU2(buffer,offset);\n                offset+=2;\n//                LOG.finer(\"Locals: \"+locals);\n                for (int i = 0; i<locals; i++) {\n                    int typeInfoSize = getVerificationTypeInfoSize(buffer[offset]);\n                    size += typeInfoSize;\n                    storeUninitializedVariableInfo(buffer,offset,i);\n                    offset += typeInfoSize;\n                }\n                int stacks = getU2(buffer,offset);\n                offset+=2;\n//                LOG.finer(\"Stacks: \"+stacks);\n                for (int i=0; i<stacks; i++) {\n                    int typeInfoSize = getVerificationTypeInfoSize(buffer[offset]);\n                    size += typeInfoSize;\n                    storeUninitializedVariableInfo(buffer,offset,locals+i);\n                    offset += typeInfoSize;\n                }\n            } else {\n                throw new IllegalArgumentException(\"Type: \"+type);\n            }\n            size+=frameType.size();\n        }\n\n        int getSize() {\n            return size;\n        }\n        \n        void setFrameType(FrameType newFrameType) {\n            int frameSizeDiff = newFrameType.size() - frameType.size();\n            frameType = newFrameType;\n            size+=frameSizeDiff;\n            frameModified = true;\n        }\n        \n        private int getVerificationTypeInfoSize(byte type) {\n//            LOG.finer(\"VerificationTypeInfo: \"+(type+0));\n            switch (type) {\n                case 0: // ITEM_Top\n                case 1: // ITEM_Integrer\n                case 2: // ITEM_Float\n                case 3: // ITEM_Double\n                case 4: // ITEM_Long\n                case 5: // ITEM_Null\n                case 6: // ITEM_UnitializedThis\n                    return 1;\n                case 7: // ITEM_Object\n                case 8: // ITEM_Uninitialized\n                    return 3;\n                default:\n                    throw new IllegalArgumentException(\"Type \"+type);\n            }\n        }\n\n        public String toString() {\n            // for debugging\n            return \"StackMapFrame \"+frameType+\" offsetDelta \"+getOffsetDelta()+\" size \"+getSize();\n        }\n\n        private int getOffsetDelta() {\n            return storedOffsetDelta + 1;\n        }\n\n        private void setOffsetDelta(int newOffsetDelta) {\n            storedOffsetDelta = newOffsetDelta - 1;\n            modified = true;\n        }\n        \n        private void updateUnitilializedList(int injectionPos, int injectedBytesCount, boolean changeTypeIsInjectNewInstr, boolean injectionBindsToFollowingInstruction) {\n            if (uninitializedList != null) {\n                for (int i = 0; i<uninitializedList.size();i++) {\n                    Integer off = uninitializedList.get(i);\n                    if (off != null) {\n                        int uninitializedOffset = off.intValue();\n                        if (adjustOffset(uninitializedOffset, injectionPos, changeTypeIsInjectNewInstr, injectionBindsToFollowingInstruction)) {\n                            uninitializedList.set(i,Integer.valueOf(uninitializedOffset+injectedBytesCount));\n                            uninitializedListModified = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        private void storeUninitializedVariableInfo(byte[] buffer, int offset, int listIndex) {\n            byte type = buffer[offset++]; \n            if (type == 8) { // ITEM_Unitialized\n                if (uninitializedList == null) {\n                    uninitializedList = new ArrayList();\n                }\n                while (uninitializedList.size() < listIndex+1) {\n                    uninitializedList.add(null);\n                }\n                uninitializedList.set(listIndex,Integer.valueOf(getU2(buffer,offset)));\n//                LOG.finer(\"ITEM_Unitialized \"+Integer.valueOf(getU2(buffer,offset)));\n            }\n        }\n\n        void writeFrame(byte[] ret, int newFrameOffset) {\n            if (modified) {\n//                LOG.finer(\"Updating \"+frameType+\" new offset \"+getOffsetDelta()+\" old type \"+Integer.valueOf(ret[newFrameOffset]&0xff));\n                if (frameModified) {\n                    switch (frameType) {\n                        case SAME_LOCALS_1_STACK_ITEM_EXTENDED:\n                            ret[newFrameOffset] = (byte)247;\n                            break;\n                        case SAME_FRAME_EXTENDED:\n                            ret[newFrameOffset] = (byte)251;\n                            break;\n                    }\n                }\n                switch (frameType) {\n                    case SAME:\n                        ret[newFrameOffset] = (byte)(storedOffsetDelta & 0x3F);\n                        break;\n                    case SAME_LOCALS_1_STACK_ITEM:\n                        ret[newFrameOffset] = (byte)(64 + (storedOffsetDelta & 0x3F));\n                        break;\n                    case SAME_LOCALS_1_STACK_ITEM_EXTENDED:\n                    case CHOP:\n                    case SAME_FRAME_EXTENDED:\n                    case APPEND:\n                    case FULL_FRAME:\n                        putU2(ret, newFrameOffset+1, storedOffsetDelta);\n                        break;\n                }\n            }\n            if (uninitializedListModified) {\n                switch (frameType) {\n                    case SAME_LOCALS_1_STACK_ITEM:\n                        putU2(ret,newFrameOffset+2,uninitializedList.get(0).intValue());\n                        break;\n                    case SAME_LOCALS_1_STACK_ITEM_EXTENDED:\n                        putU2(ret,newFrameOffset+3,uninitializedList.get(0).intValue());\n                        break;\n                    case APPEND: {\n                        int offset = newFrameOffset+3;\n                        for (Integer off : uninitializedList) {\n                            byte type = ret[offset];\n                            int typeInfoSize = getVerificationTypeInfoSize(type);\n\n                            if (type == 8) { // ITEM_Unitialized\n                                putU2(ret,offset+1,off.intValue());\n                            }\n                            offset += typeInfoSize;\n                        }\n                        break;\n                    }\n                    case FULL_FRAME: {\n                        int offset = newFrameOffset+3;\n                        int locals = getU2(ret,offset);\n                        \n                        offset+=2;\n//                        LOG.finer(\"Locals: \"+locals);\n                        for (int i=0; i<locals; i++) {\n                            byte type = ret[offset];\n                            int typeInfoSize = getVerificationTypeInfoSize(type);\n                            \n                            if (type == 8) { // ITEM_Unitialized\n                                putU2(ret,offset+1,uninitializedList.get(i).intValue());\n                            }\n                            offset += typeInfoSize;\n                        }\n                        int stacks = getU2(ret,offset);\n                        offset+=2;\n//                        LOG.finer(\"Stacks: \"+stacks);\n                        for (int i=0; i<stacks; i++) {\n                            byte type = ret[offset];\n                            int typeInfoSize = getVerificationTypeInfoSize(type);\n                            \n                            if (type == 8) { // ITEM_Unitialized\n                                putU2(ret,offset+1,uninitializedList.get(locals+i).intValue());\n                            }\n                            offset += typeInfoSize;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n    }\n\n    static class FullStackMapFrame extends StackMapFrame {\n        int[] localsCPIdx;\n        int[] stacksCPIdx;\n        \n        FullStackMapFrame(int delta, int[] locals, int stacks[]) {\n            super(FrameType.FULL_FRAME, delta, stacks.length*3+((locals.length>0 && locals[0] == 0)?locals.length:3*locals.length));\n            localsCPIdx = locals;\n            stacksCPIdx = stacks;\n        }\n        \n        void writeFrame(byte[] ret, int offset) {\n            ret[offset++] = (byte)255; // FULL_FRAME\n            putU2(ret,offset,storedOffsetDelta); // offset_delta\n            offset+=2;\n            putU2(ret,offset,localsCPIdx.length); // locals\n            offset+=2;\n            for (int i=0; i<localsCPIdx.length;i++) {\n                int cpIndex = localsCPIdx[i];\n                \n                if (cpIndex == 0) {\n                   ret[offset++] = 0;  // ITEM_Top\n                } else {\n                    ret[offset++] = 7; // ITEM_Object\n                    putU2(ret,offset,cpIndex);\n                    offset+=2;\n                }\n            }\n            putU2(ret,offset,stacksCPIdx.length); // stacks\n            offset+=2;\n            for (int i=0; i<stacksCPIdx.length;i++) {\n                ret[offset++] = 7; // ITEM_Object\n                putU2(ret,offset,stacksCPIdx[i]);  // cpool_index\n                offset+=2;\n            }            \n        }\n    }\n    \n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    String packageName;\n    String superName;\n    char[] cpoolRefsToClassIdx; // Cpool indices of ClassEntry entires for referenced classes\n    String[] cpoolRefsToClassName; // Names of classes referenced from cpool, including array classes.\n    String[][] cpoolRefsToMethodClassNameAndSig;\n\n    // In all signatures we replace the 'L' and ';' symbols that enclose non-primitive type names with '@' and '#' respectively,\n    // so that class names inside signatures can be located fast and unambiguously.  \n    char[] cpoolRefsToMethodIdx; // Cpool indices of MethodEntry entries for referenced methods\n                                 // The following array consists of \"referenced method's class name, name, signature\" triplets.\n                                 // Defining classes names are trimmed of enclosing 'L' and ';' symbols\n    int[] exceptionTableStartOffsets; // Relative offsets within a MethodInfo\n    String[] interfaces;\n    char[] lineNumberTablesLengths;\n    int[] lineNumberTablesOffsets; // Relative offsets within a MethodInfo\n    int localVaribaleTableCPindex;\n    char[] localVariableTablesLengths;\n    int[] localVariableTablesOffsets; // Relative offsets within a MethodInfo\n    int localVaribaleTypeTableCPindex;\n    char[] localVariableTypeTablesLengths;\n    int[] localVariableTypeTablesOffsets; // Relative offsets within a MethodInfo\n    int stackMapTableCPindex;\n    char[] stackMapTablesLengths;\n    int[] stackMapTablesOffsets; // Relative offsets within a MethodInfo\n    char[] methodAccessFlags;\n    char[] methodBytecodesLengths;\n    int[] methodBytecodesOffsets; // Relative offsets within a MethodInfo\n    int[] methodInfoLengths;\n    int[] methodInfoOffsets;\n    String[] methodNames;\n    String[] methodSignatures;\n    String[] nestedClassNames;\n    int majorVersion;  // class file major version\n    int classIndex; // constant pool entry index representing this class\n    char accessFlags; // isInterface flag included\n    int attrsStartOfs; // Ditto for class attributes\n    int cpoolStartOfs; // Starting offset, in bytes, of the original cpool (cpool length char included)\n    int fieldsStartOfs; // Ditto for fields\n    int intermediateDataStartOfs; // Ditto for intermediate data (class flags, name, super, etc.)\n    int methodsStartOfs; // Ditto for methods\n    int origCPoolCount; // The number of entries in the original cpool of this class\n    private LineNumberTables lineNumberTables;\n    private LocalVariableTables localVariableTables;\n    private LocalVariableTypeTables localVariableTypeTables;\n    private StackMapTables stackMapTables;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    protected ClassInfo(String className, int loaderId) {\n        super(className, loaderId);\n        packageName = getPackageName(name);\n    }\n\n    /**\n     * This constructor is used for creation of temporary instances of ClassInfo, typically to just find out something about\n     * class contained in a given .class file.\n     */\n    ClassInfo(byte[] buf) throws ClassFormatError {\n        super(\"\", 0); // NOI18N\n\n        try {\n            new ClassFileParser().parseClassFile(buf, this);\n        } catch (ClassFileParser.ClassFileReadException ex) {\n            throw new ClassFormatError(ex.getMessage());\n        }\n\n        packageName = getPackageName(name);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getMajorVersion() {\n        return majorVersion;\n    }\n    \n    public boolean isAbstract() {\n        return Modifier.isAbstract(accessFlags);\n    }\n\n    public int getExceptionTableStartOffsetInMethodInfo(int i) {\n        return exceptionTableStartOffsets[i];\n    }\n\n    public int getExceptionTableCount(int i) {\n        int startOfs = getExceptionTableStartOffsetInMethodInfo(i);\n        byte[] methodInfo = getMethodInfo(i);\n        \n        return ((methodInfo[startOfs] & 0xFF) << 8) + (methodInfo[startOfs + 1] & 0xFF);\n    }\n    \n    public int getLocalVariableTableStartOffsetInMethodInfo(int i) {\n        return localVariableTablesOffsets[i];\n    }\n\n    public int getLocalVariableTypeTableStartOffsetInMethodInfo(int i) {\n        return localVariableTypeTablesOffsets[i];\n    }\n\n    public int getStackMapTableStartOffsetInMethodInfo(int i) {\n        return stackMapTablesOffsets[i];\n    }\n\n    public boolean isInterface() {\n        return Modifier.isInterface(accessFlags);\n    }\n\n    public String[] getInterfaceNames() {\n        return interfaces;\n    }\n\n    public LineNumberTables getLineNumberTables() {\n        initLineNumberTables();\n\n        return lineNumberTables;\n    }\n\n    public LocalVariableTables getLocalVariableTables() {\n        initLocalVariableTables();\n        return localVariableTables;\n    }\n\n    public LocalVariableTypeTables getLocalVariableTypeTables() {\n        initLocalVariableTypeTables();\n        return localVariableTypeTables;\n    }\n\n    public StackMapTables getStackMapTables() {\n        initStackMapTables();\n        return stackMapTables;\n    }\n    \n    public void resetTables() {\n        lineNumberTables = null;\n        localVariableTables = null;\n        localVariableTypeTables = null;\n        stackMapTables = null;\n    }\n    \n    public boolean isMethodAbstract(int i) {\n        return Modifier.isAbstract(methodAccessFlags[i]);\n    }\n\n    public byte[] getMethodBytecode(int i) {\n        try {\n            byte[] classFile = getClassFileBytes();\n            byte[] res = new byte[methodBytecodesLengths[i]];\n            System.arraycopy(classFile, methodInfoOffsets[i] + methodBytecodesOffsets[i], res, 0, methodBytecodesLengths[i]);\n\n            return res;\n        } catch (IOException ex1) {\n            return null; // Should not happen - class file already loaded once by this time\n        } catch (ClassNotFoundException ex2) {\n            return null;\n        } // Ditto\n    }\n\n    public int getMethodBytecodeOffsetInMethodInfo(int i) {\n        return methodBytecodesOffsets[i];\n    }\n\n    public int getMethodBytecodesLength(int i) {\n        return methodBytecodesLengths[i];\n    }\n\n    public boolean isMethodFinal(int i) {\n        return Modifier.isFinal(methodAccessFlags[i]);\n    }\n\n    public int getMethodIndex(String name, String sig) {\n        if (methodNames == null) {\n            return -1;\n        }\n        for (int i = 0; i < methodNames.length; i++) {\n            if ((methodNames[i] == name) && (methodSignatures[i] == sig)) {\n                return i;\n            }\n        }\n\n        return -1;\n    }\n\n    public byte[] getMethodInfo(int i) {\n        try {\n            byte[] classFile = getClassFileBytes();\n            byte[] res = new byte[methodInfoLengths[i]];\n            System.arraycopy(classFile, methodInfoOffsets[i], res, 0, methodInfoLengths[i]);\n\n            return res;\n        } catch (IOException ex1) {\n            return null; // Should not happen - class file already loaded once by this time\n        } catch (ClassNotFoundException ex2) {\n            return null;\n        } // Ditto\n    }\n\n    public int getMethodInfoLength(int i) {\n        return methodInfoLengths[i];\n    }\n\n    public String getMethodName(int i) {\n        return methodNames[i];\n    }\n\n    public String[] getMethodNames() {\n        if (methodNames == null) {\n            return new String[0];\n        }\n        return methodNames;\n    }\n\n    public boolean isMethodNative(int i) {\n        return Modifier.isNative(methodAccessFlags[i]);\n    }\n\n    public boolean isMethodPrivate(int i) {\n        return Modifier.isPrivate(methodAccessFlags[i]);\n    }\n\n    public boolean isMethodProtected(int i) {\n        return Modifier.isProtected(methodAccessFlags[i]);\n    }\n\n    public boolean isMethodPublic(int i) {\n        return Modifier.isPublic(methodAccessFlags[i]);\n    }\n\n    public String getMethodSignature(int i) {\n        return methodSignatures[i];\n    }\n\n    public String[] getMethodSignatures() {\n        return methodSignatures;\n    }\n\n    public boolean isMethodStatic(int i) {\n        return Modifier.isStatic(methodAccessFlags[i]);\n    }\n\n    public int[] getMinAndMaxLinesForMethod(int methodIdx) {\n        initLineNumberTables();\n\n        return lineNumberTables.getMinAndMaxLinesForMethod(methodIdx);\n    }\n\n    public String[] getNestedClassNames() {\n        return nestedClassNames;\n    }\n\n    public int getOrigAttrsStartOfs() {\n        return attrsStartOfs;\n    }\n\n    public int getOrigCPoolCount() {\n        return origCPoolCount;\n    }\n\n    public int getOrigCPoolStartOfs() {\n        return cpoolStartOfs;\n    }\n\n    public int getOrigFieldsStartOfs() {\n        return fieldsStartOfs;\n    }\n\n    public int getOrigIntermediateDataStartOfs() {\n        return intermediateDataStartOfs;\n    }\n\n    public int getOrigMethodsStartOfs() {\n        return methodsStartOfs;\n    }\n\n    public String getRefClassName(int refClassIdx) {\n        for (int i = 0; i < cpoolRefsToClassIdx.length; i++) {\n            if (cpoolRefsToClassIdx[i] == refClassIdx) {\n                return cpoolRefsToClassName[i];\n            }\n        }\n\n        return null;\n    }\n\n    public int getCPIndexOfClass(String className) {\n        int cpIndex = -1;\n        for (int i=0; i<cpoolRefsToClassName.length; i++) {\n            if (cpoolRefsToClassName[i].equals(className)) {\n                cpIndex = cpoolRefsToClassIdx[i];\n            }\n        }\n        return cpIndex;\n    }\n    \n    public String[] getRefMethodsClassNameAndSig(int refMethodIdx) {\n        for (int i = 0; i < cpoolRefsToMethodIdx.length; i++) {\n            if (cpoolRefsToMethodIdx[i] == refMethodIdx) {\n                return cpoolRefsToMethodClassNameAndSig[i];\n            }\n        }\n\n        return null;\n    }\n\n    public String getSuperclassName() {\n        return superName;\n    }\n\n    public int bciForMethodAndLineNo(int methodIdx, int lineNo) {\n        initLineNumberTables();\n\n        return lineNumberTables.bciForLineNo(methodIdx, lineNo);\n    }\n\n    /** Check if the given method's opcode at bci is goto. or goto_w. If so, find and return the bci of the previous opcode */\n    public int checkIfAtGoTo(int methodIdx, int bci) { // TODO CHECK: unused method\n\n        byte[] codeBytes = getMethodBytecode(methodIdx);\n        int codeAtBCI = codeBytes[bci] & 0xFF;\n\n        if ((codeAtBCI != opc_goto) && (codeAtBCI != opc_goto_w)) {\n            return bci;\n        }\n\n        return findPreviousBCI(codeBytes, bci);\n    }\n\n    public boolean containsMethod(String name, String sig) { // TODO CHECK: unused method\n\n        return (getMethodIndex(name, sig) != -1);\n    }\n\n    /** For given bytecode offset bci, return the offset of the bytecode before the one at bci */\n    public static int findPreviousBCI(byte[] codeBytes, int bci) {\n        int prev_offset = 0;\n\n        for (int offset = 0; offset < bci;) {\n            prev_offset = offset;\n\n            int opcode = codeBytes[offset] & 0xFF;\n\n            if (opcode == opc_wide) {\n                opcode = codeBytes[offset + 1] & 0xFF;\n\n                if (((opcode >= opc_iload) && (opcode <= opc_aload)) || ((opcode >= opc_istore) && (opcode <= opc_astore))\n                        || (opcode == opc_ret)) {\n                    offset += 4;\n                } else if (opcode == opc_iinc) {\n                    offset += 6;\n                } else {\n                    offset++;\n                }\n            } else {\n                switch (opcode) {\n                    case opc_tableswitch: {\n                        int tbl = (offset + 1 + 3) & (~3); // four byte boundry\n                        long default_skip = intAt(codeBytes, tbl, 0);\n                        long low = intAt(codeBytes, tbl, 1);\n                        long high = intAt(codeBytes, tbl, 2);\n                        tbl += (3 << 2); // three int header\n                        offset = tbl + (int) ((high - low + 1) << 2);\n\n                        break;\n                    }\n                    case opc_lookupswitch: {\n                        int tbl = (offset + 1 + 3) & (~3); // four byte boundry\n                        long default_skip = intAt(codeBytes, tbl, 0);\n                        int npairs = (int) intAt(codeBytes, tbl, 1);\n                        int nints = npairs * 2;\n                        tbl += (2 << 2); // two int header\n                        offset = tbl + (nints << 2);\n\n                        break;\n                    }\n                    default:\n                        offset += opc_length[opcode];\n\n                        break;\n                }\n            }\n        }\n\n        return prev_offset;\n    }\n\n    public int lineNoForMethodAndBci(int methodIdx, int bci) { // TODO CHECK: unused method\n        initLineNumberTables();\n\n        return lineNumberTables.lineNoForBci(methodIdx, bci);\n    }\n\n    /**\n     * Returns a {method idx, best BCI} pair for the given source line number in this class. If no suitable method is\n     * found, returns {-1, -1}. If this class doesn't have any line number tables (because it's abstract or because\n     * it was compiled without tables), returns {-2, -2}.\n     */\n    public int[] methodIdxAndBestBCIForLineNo(int lineNo) {\n        initLineNumberTables();\n\n        if (!lineNumberTables.hasTable()) {\n            return new int[] { -2, -2 };\n        }\n\n        int nMethods = methodNames.length;\n\n        // We need to take into account the fact that for a constructor/class initializer the line numbers may span\n        // a much larger range than the constructor body. That's due to instance/static initialization statements\n        // that can be scattered about the whole class. If we put the cursor into a method that is between two\n        // initializers, we may well get a constructor as the \"best match\" for the given line. Thus, we first\n        // search normal methods, and only if this fails - constructors and class initializer.\n        for (int i = 0; i < nMethods; i++) {\n            if ((methodNames[i] == \"<init>\") || (methodNames[i] == \"<clinit>\")) { // NOI18N\n                continue;\n            }\n\n            int bestBCI = lineNumberTables.bciForLineNo(i, lineNo);\n\n            if (bestBCI != -1) {\n                return new int[] { i, bestBCI };\n            }\n        }\n\n        // No success with ordinary methods - try constructors now\n        for (int i = 0; i < nMethods; i++) {\n            if ((methodNames[i] != \"<init>\") && (methodNames[i] != \"<clinit>\")) { // NOI18N\n                continue;\n            }\n\n            int bestBCI = lineNumberTables.bciForLineNo(i, lineNo);\n\n            if (bestBCI != -1) {\n                return new int[] { i, bestBCI };\n            }\n        }\n\n        return new int[] { -1, -1 };\n    }\n\n    // WARNING: this call doesn't check if the method in superClass is not private, final, static or constructor. This is done for\n    // speedup, since we call it only in the context when it is already known that the above is true.\n    public int overridesVirtualMethod(ClassInfo superClass, int superMethodIdx) { // TODO CHECK: unused method\n\n        int idx = getMethodIndex(superClass.methodNames[superMethodIdx], superClass.methodSignatures[superMethodIdx]);\n\n        if (idx == -1) {\n            return -1;\n        }\n\n        if (superClass.isMethodPublic(superMethodIdx) || superClass.isMethodProtected(superMethodIdx)) {\n            return idx;\n        } else if (superClass.packageName == this.packageName) {\n            return idx;\n        } else {\n            return -1;\n        }\n    }\n\n    //-------------------------------------- Protected methods -------------------------------------------\n\n    /** Returns the class file bytes for this class. */\n    protected abstract byte[] getClassFileBytes() throws IOException, ClassNotFoundException;\n\n    /**\n     * Returns package name for the given class. In case of no package, returns an\n     * empty, but non-null string. Returned string is interned.\n     */\n    protected static String getPackageName(String clazzName) {\n        int ldi = clazzName.lastIndexOf('/'); // For convenience, we use system-internal slashes, not dots\n\n        if (ldi == -1) {\n            return \"\"; // NOI18N\n        } else {\n            return clazzName.substring(0, ldi).intern();\n        }\n    }\n\n    /** Given the table at the specified index, return the specified entry */\n    static long intAt(byte[] codeBytes, int tbl, int entry) { // TODO CHECK: unused method\n\n        int base = tbl + (entry << 2);\n\n        return (codeBytes[base] << 24) | ((codeBytes[base + 1] & 0xFF) << 16) | ((codeBytes[base + 2] & 0xFF) << 8)\n               | (codeBytes[base + 3] & 0xFF);\n    }\n\n    static void putU2(byte[] buf, int pos, int value) {\n        buf[pos] = (byte) ((value >> 8) & 0xFF);\n        buf[pos + 1] = (byte) (value & 0xFF);\n    }\n\n    static int getU2(byte[] buf, int pos) {\n        return ((buf[pos] & 0xFF) << 8) + (buf[pos + 1] & 0xFF);\n    }\n\n    private static boolean adjustOffset(int bciIter, int injectionPos, boolean changeTypeIsInjectNewInstr, boolean injectionBindsToFollowingInstruction) {\n        boolean adjustOffset = false;\n        if (bciIter > injectionPos) {\n            adjustOffset = true;\n        } else if (changeTypeIsInjectNewInstr) {\n            if (injectionPos == 0 && bciIter == 0) {\n                adjustOffset = true;\n            } else if (!injectionBindsToFollowingInstruction && bciIter >= injectionPos) {\n                adjustOffset = true;\n            }\n        }\n        return adjustOffset;\n    }    \n    //----------------------------------------- Private implementation -----------------------------------\n\n    private synchronized void initLineNumberTables() {\n        if (lineNumberTables == null) {\n            lineNumberTables = new LineNumberTables(this);\n        }\n    }\n\n    private synchronized void initLocalVariableTables() {\n        if (localVariableTables == null) {\n            localVariableTables = new LocalVariableTables(this);\n        }\n    }\n\n    private synchronized void initLocalVariableTypeTables() {\n        if (localVariableTypeTables == null) {\n            localVariableTypeTables = new LocalVariableTypeTables(this);\n        }\n    }\n\n    private synchronized void initStackMapTables() {\n        if (stackMapTables == null) {\n            stackMapTables = new StackMapTables();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/classfile/ClassLoaderTable.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.classfile;\n\n\n/**\n * A table that maps a class loader to its parent class loader.\n *\n * @author Misha Dmitirev\n * @author Ian Formanek\n */\npublic class ClassLoaderTable {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // TODO [release]: change value to TRUE to remove the print code below entirely by compiler\n    private static final boolean DEBUG = System.getProperty(\"org.graalvm.visualvm.lib.jfluid.classfile.ClassLoaderTable\") != null; // NOI18N\n    private int[] parentLoaderIds;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Will provide Id of parent classloader for the specified classloader. The parent of system classloader (id=0)\n     * is the same system classloader (id=0).\n     *\n     * @param loader id of ClassLoader whose parent we are looking for\n     * @return The id of the parent classloader of the specified classloader\n     */\n    public int getParentLoader(int loader) {\n        if (DEBUG) {\n            System.err.println(\"ClassLoaderTable.DEBUG: getParent loader: \" + loader); // NOI18N\n        }\n\n        if (loader >= parentLoaderIds.length) {\n            // very strange situation: loader not known on tool side, seems like this can happen when using\n            // instrumentation for Method.invoke, where the MethodLoadedCommand comes for class sun.reflect.misc.Trampoline\n            // although the ClassLoadedCommand never is issued for this class\n            return -1;\n        }\n\n        return parentLoaderIds[loader];\n    }\n\n    /**\n     * @param thisAndParentLoaderData An array\n     */\n    public void addChildAndParent(int[] thisAndParentLoaderData) {\n        int ofs = thisAndParentLoaderData[2];\n\n        if (ofs == 0) {\n            addChildAndParent(thisAndParentLoaderData[0], thisAndParentLoaderData[1]);\n        } else {\n            int loaderId = thisAndParentLoaderData[0];\n\n            for (int i = 0; i < ofs; i++) {\n                addChildAndParent(loaderId, loaderId + 1);\n                loaderId++;\n            }\n\n            addChildAndParent(loaderId, thisAndParentLoaderData[1]);\n        }\n    }\n\n    /**\n     * Will perform initial initialization of the classloader table with data provided from the profiler VM.\n     *\n     * @param inParentLoaderIds table mapping id (idx) -&gt; parent id ([idx])\n     */\n    public void initTable(int[] inParentLoaderIds) {\n        if (DEBUG) {\n            System.err.println(\"ClassLoaderTable.DEBUG: init patent loader ids: \" + inParentLoaderIds.length); // NOI18N\n\n            for (int i = 0; i < inParentLoaderIds.length; i++) {\n                System.err.println(\"ClassLoaderTable.DEBUG: inParentLoaderIds[\" + i + \"]=\" + inParentLoaderIds[i]); // NOI18N\n            }\n        }\n\n        parentLoaderIds = inParentLoaderIds;\n\n        for (int i = 0; i < parentLoaderIds.length; i++) {\n            // We don't distinguish between bootstrap (-1) and system (0) class loaders, as well as some\n            // sun.reflect.DelegatingClassLoaders or whatever, that also have -1 as their parent.\n            if (parentLoaderIds[i] == -1) {\n                parentLoaderIds[i] = 0;\n            }\n        }\n    }\n\n    /**\n     * Will add a new pair of classloader, its parent to the table.\n     *\n     * @param childLoader  Id of classloader\n     * @param parentLoader Id of its parent classloader\n     */\n    private void addChildAndParent(int childLoader, int parentLoader) {\n        if (DEBUG) {\n            System.err.println(\"ClassLoaderTable.DEBUG: add child and parent: child: \" // NOI18N\n                               + childLoader + \", parent: \" // NOI18N\n                               + parentLoader);\n        }\n\n        int maxLoader = (childLoader > parentLoader) ? childLoader : parentLoader;\n\n        if (parentLoaderIds.length < (maxLoader + 1)) {\n            // new loader, need to enlarge the array\n            int[] oldTable = parentLoaderIds;\n            parentLoaderIds = new int[(childLoader * 2) + 1];\n            System.arraycopy(oldTable, 0, parentLoaderIds, 0, oldTable.length);\n        }\n\n        if (parentLoader == -1) {\n            parentLoader = 0;\n        }\n\n        parentLoaderIds[childLoader] = parentLoader;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/classfile/ClassPath.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.classfile;\n\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n\n/**\n * Class path, that can be set containing both directories and .jar files, and then used to read a .class (.java)\n * file with a specified fully qualified name.\n *\n * @author Misha Dmitirev\n * @author Tomas Hurka\n */\npublic class ClassPath {\n\n    private static final Random r = new Random(System.currentTimeMillis());\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private abstract static class PathEntry {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        protected HashSet entries;\n        protected int hits; // This is done to avoid indexing of the JAR files too early and all at once\n        protected int threshHits; // This is done to avoid indexing of the JAR files too early and all at once\n\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        abstract String getLocationForClassFile(String fileName);\n    }\n\n    private static class Dir extends PathEntry {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private File dir;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        Dir(File dirF) {\n            dir = dirF;\n            threshHits = 100 + r.nextInt(40);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        String getLocationForClassFile(String fileName) {\n            if (entries != null) {\n                if (entries.contains(fileName)) {\n                    return dir.getAbsolutePath();\n                } else {\n                    return null;\n                }\n            } else {\n                if (++hits >= threshHits) {\n                    entries = new HashSet();\n                    MiscUtils.getAllClassesInDir(dir.getAbsolutePath(), \"\", false, entries); // NOI18N\n\n                    return getLocationForClassFile(fileName);\n                } else {\n                    File file = new File(dir, fileName);\n\n                    //System.err.println(\"*** Trying file \" + file.getAbsolutePath() + \" in PathEntry = \" + dir.getAbsolutePath());\n                    if (file.exists()) {\n                        return dir.getAbsolutePath();\n                    } else {\n                        return null;\n                    }\n                }\n            }\n        }\n    }\n\n    private class Zip extends PathEntry {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private String zipFilePath;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        Zip(String path) {\n            zipFilePath = path;\n            threshHits = 50 + r.nextInt(20);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        String getLocationForClassFile(String fileName) {\n            if (entries != null) {\n                if (entries.contains(fileName)) {\n                    return zipFilePath;\n                } else {\n                    return null;\n                }\n            } else {\n                if (++hits >= threshHits) {\n                    entries = new HashSet();\n                    MiscUtils.getAllClassesInJar(zipFilePath, false, entries);\n                    return getLocationForClassFile(fileName);\n                } else {\n                    ZipFile zip;\n                    try {\n                        zip = getZipFileForName(zipFilePath);\n                    } catch (IOException ex) {\n                        System.err.println(\"Warning: CLASSPATH component \" + zipFilePath + \": \" + ex); // NOI18N\n                        return null;\n                    }\n                    ZipEntry entry = zip.getEntry(fileName);\n\n                    if (entry != null) {\n                        return zipFilePath;\n                    } else {\n                        return null;\n                    }\n                }\n            }\n        }\n    }\n    \n    private static class JarLRUCache extends LinkedHashMap {\n        private static final int MAX_CAPACITY = 100;\n        \n        private JarLRUCache() {  \n            super(10, 0.75f, true); \n        }\n        \n        protected boolean removeEldestEntry(Map.Entry eldest) {\n            if (size()>MAX_CAPACITY) {\n                try {\n                    ((ZipFile)eldest.getValue()).close();\n                } catch (IOException ex) {\n                    // ignore\n                }\n                return true;\n            }\n            return false;\n        }\n\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ClassFileCache classCache;\n    private ClassLoaderTable loaderTable;\n    private JarLRUCache zipFileNameToFile;\n    private PathEntry[] paths;\n    private boolean isCP; // True for a class path, false for a source path\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ClassPath(String classPath, boolean isCP) {\n        this.isCP = isCP;\n        List vec = new ArrayList();\n        zipFileNameToFile = new JarLRUCache();\n\n        for (StringTokenizer tok = new StringTokenizer(classPath, File.pathSeparator); tok.hasMoreTokens();) {\n            String path = tok.nextToken();\n\n            if (!path.isEmpty()) {\n                File file = new File(path);\n\n                if (file.exists()) {\n                    if (file.isDirectory()) {\n                        vec.add(new Dir(file));\n                    } else {\n                        vec.add(new Zip(file.getPath()));\n                    }\n                }\n            }\n        }\n\n        paths = (PathEntry[])vec.toArray(new PathEntry[0]);\n        classCache = new ClassFileCache(this);\n        loaderTable = new ClassLoaderTable();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Searches for the class on this class path, reads it if found, and returns the DynamicClassInfo for it.\n     * If class is not found, returns null. Exceptions are thrown if class file is found but something goes wrong when reading it.\n     */\n    public DynamicClassInfo getClassInfoForClass(String className, int classLoaderId)\n                                          throws IOException, ClassFormatError {\n        String slashedClassName = className.replace('.', '/'); // NOI18N\n                                                               //System.err.println(\"*** Requested \" + slashedClassName);\n\n        String dirOrJar = getLocationForClass(slashedClassName);\n\n        //if (dirOrJar == null) System.err.println(\"*** Unsuccessful for \" + slashedClassName);\n        if (dirOrJar == null) {\n            return null;\n        }\n\n        return new DynamicClassInfo(this, slashedClassName, classLoaderId, dirOrJar);\n    }\n\n    /** Requires \"slashed\" class name. Returns the directory or .jar name where this class is located, or null if not found. */\n    public String getLocationForClass(String slashedClassName) {\n        String fileName = slashedClassName + (isCP ? \".class\" : \".java\"); // NOI18N\n        for (PathEntry path : paths) {\n            String location = path.getLocationForClassFile(fileName);\n            if (location != null) {\n                return location;\n            }\n        }\n\n        return null;\n    }\n\n    /** This is used to avoid repetitive creation of ZipFiles in the code that reads files from JARs given just the name of the latter */\n    public ZipFile getZipFileForName(String zipFileName) throws IOException {\n        ZipFile zip = (ZipFile) zipFileNameToFile.get(zipFileName);\n        if (zip == null) {\n            zip = new ZipFile(zipFileName);\n            zipFileNameToFile.put(zipFileName,zip);\n        }\n        return zip;\n    }\n\n    void addVMSuppliedClassFile(String className, int classLoaderId, byte[] buf) {\n        classCache.addVMSuppliedClassFile(className, classLoaderId, buf);\n    }\n\n    int hasVMSuppliedClassFile(String className, int classLoaderId) {\n        return classCache.hasVMSuppliedClassFile(className, classLoaderId);\n    }\n\n    byte[] getClassFile(String name, String classFileLocation) throws IOException {\n        return classCache.getClassFile(name, classFileLocation);\n    }\n\n    void preloadBytecode(String name, String classFileLocation) {\n        classCache.preloadBytecode(name, classFileLocation);\n    }\n\n    public ClassLoaderTable getClassLoaderTable() {\n        return loaderTable;\n    }\n\n    public void close() {\n        // close all ZipFiles in ClassPath, the files on disk would otherwise be locked\n        // this is a bugfix for http://profiler.netbeans.org/issues/show_bug.cgi?id=61849\n        for (Iterator it = zipFileNameToFile.values().iterator(); it.hasNext();) {\n            try {\n                ((ZipFile) it.next()).close();\n            } catch (IOException e) {\n                // ignore\n            }\n        }\n    }\n\n    //------------------------------------------ Debugging -----------------------------------------\n    public String toString() {\n        StringBuilder buf = new StringBuilder();\n\n        for (PathEntry path : paths) {\n            buf.append((path instanceof Dir) ? ((Dir) path).dir.getAbsolutePath() : ((Zip) path).zipFilePath);\n            buf.append(File.pathSeparatorChar);\n        }\n\n        return buf.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/classfile/ClassRepository.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.classfile;\n\nimport java.io.File;\nimport java.io.FilenameFilter;\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.BadLocationException;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\n\n\n/**\n * A collection of several methods for general class file reading functionality. Allows to set\n * a class path, read a class from class path, generate a class that does not have a .class file (such\n * as an array class), etc. It also keeps track of classes ever loaded by it, and allows one to iterate\n * over these classes.\n *\n * @author Tomas Hurka\n * @author Misha Dmitirev\n */\npublic class ClassRepository implements CommonConstants {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    // ------------------------ Method-class-source related stuff --------------------------------\n    public static class CodeRegionBCI {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        public String className;\n        public String methodName;\n        public String methodSignature;\n        public int bci0;\n        public int bci1;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public CodeRegionBCI(String className, String methodName, String methodSignature, int bci0, int bci1) {\n            this.className = className;\n            this.methodName = methodName;\n            this.methodSignature = methodSignature;\n            this.bci0 = bci0;\n            this.bci1 = bci1;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public String toString() {\n            return \"CodeRegionBCI [\" // NOI18N\n                   + \"className: \" + className // NOI18N\n                   + \", methodName: \" + methodName // NOI18N\n                   + \", methodSignature: \" + methodSignature // NOI18N\n                   + \", bci0: \" + bci0 // NOI18N\n                   + \", bci1: \" + bci1 // NOI18N\n                   + \"]\"; // NOI18N\n        }\n    }\n\n    //~ fields/initializers -----------------------------------------------------------------------------------------------\n\n    // The below class file location signals to ClassFileCache that the class file should have been already supplied by the VM.\n    static final String LOCATION_VMSUPPLIED = \"<VM_SUPPLIED>\"; // NOI18N\n    private ClassPath classPath;\n    private Hashtable classes;\n    private Set notFoundClasses;\n    private Map definingClassLoaderMap;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ClassRepository() {\n        classes = new Hashtable();\n        notFoundClasses = new HashSet();\n        definingClassLoaderMap = new HashMap();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public List getAllClassVersions(String className) {\n        className = className.replace('.', '/').intern(); // NOI18N\n\n        Object entry = classes.get(className);\n\n        if (entry != null) { // A single class or placeholder, or a group of them for this name, exists\n\n            List ret = new ArrayList();\n\n            if (entry instanceof BaseClassInfo) {\n                ret.add(entry);\n            } else {\n                ret = ((SameNameClassGroup) entry).getAll();\n            }\n\n            return ret;\n        } else {\n            return null;\n        }\n    }\n\n    public Enumeration getClassEnumerationWithAllVersions() {\n        class ClassesEnumeration implements Enumeration {\n            private Enumeration baseEnum;\n            private Object nextElement;\n            private List classes;\n            private int idx;\n\n            ClassesEnumeration(Enumeration baseEnum) {\n                this.baseEnum = baseEnum;\n            }\n\n            public boolean hasMoreElements() {\n                if (nextElement == null) {\n                    return baseEnum.hasMoreElements();\n                } else {\n                    return true;\n                }\n            }\n\n            public Object nextElement() {\n                if (nextElement != null) {\n                    Object ret = nextElement;\n                    idx++;\n\n                    if (idx == classes.size()) {\n                        nextElement = null;\n                    } else {\n                        nextElement = classes.get(idx);\n                    }\n\n                    return ret;\n                } else {\n                    Object next = baseEnum.nextElement();\n\n                    if (next instanceof SameNameClassGroup) {\n                        SameNameClassGroup g = (SameNameClassGroup) next;\n                        classes = g.getAll();\n                        next = classes.get(0);\n\n                        if (classes.size() > 1) {\n                            idx = 1;\n                            nextElement = classes.get(1);\n                        } else {\n                            classes = null;\n                        }\n                    }\n\n                    return next;\n                }\n            }\n        }\n\n        return new ClassesEnumeration(classes.elements());\n    }\n\n    public ClassPath getClassPath() {\n        return classPath;\n    }\n\n    /**\n     * Returns names of all classes that can be located on the given classpath.\n     * Since this method performs directory scanning, it is recommended to call it once and cache the results.\n     */\n    public static List getClassesOnClasspath(List classPathElementList) { // TODO CHECK: unused method\n\n        List list = new ArrayList();\n        list.addAll(classPathElementList);\n\n        List res = new ArrayList();\n\n        for (Iterator e = list.iterator(); e.hasNext();) {\n            String dirOrJar = (String) e.next();\n\n            if (!(dirOrJar.endsWith(\".jar\") || dirOrJar.endsWith(\".zip\"))) // NOI18N\n             {\n                MiscUtils.getAllClassesInDir(dirOrJar, \"\", true, res); // NOI18N\n            } else {\n                MiscUtils.getAllClassesInJar(dirOrJar, true, res);\n            }\n        }\n\n        return res;\n    }\n\n    public CodeRegionBCI getMethodForSourceRegion(ClassInfo clazz, int startLine, int endLine)\n                                                  throws ClassNotFoundException, IOException, BadLocationException {\n        if (startLine > endLine) {\n            return null; // Just in case...\n        }\n\n        int[] idxAndBCI0 = clazz.methodIdxAndBestBCIForLineNo(startLine);\n        int methodIdx = idxAndBCI0[0];\n\n        if (methodIdx >= 0) {\n            String methodName = clazz.getMethodNames()[methodIdx];\n\n            if ((methodName == \"<init>\") || (methodName == \"<clinit>\")) { // NOI18N\n                                                                          // See the comment in ClassInfo.methodIdxAndBestBCIForLineNo() regarding initializers scattered about the class text.\n                                                                          // Check if a method in a nested class matches the same spot in the source code.\n\n                CodeRegionBCI res = getMethodForSourceRegionInNestedClasses(clazz, startLine, endLine);\n\n                if (res != null) {\n                    return res;\n                }\n            }\n\n            int[] minAndMaxLines = clazz.getMinAndMaxLinesForMethod(methodIdx);\n\n            int[] idxAndBCI1;\n            if (endLine == minAndMaxLines[1]) { // it's the last line of the same method\n                idxAndBCI1 = new int[2];\n                idxAndBCI1[0] = methodIdx;\n\n                // Need to find the bci of the last instruction in this method. It can only be a \"return\" or 'goto' ('goto_w').\n                // In either case, we should put the call before this instruction, since it would make no sense after it.\n                byte[] codeBytes = clazz.getMethodBytecode(methodIdx);\n                idxAndBCI1[1] = ClassInfo.findPreviousBCI(codeBytes, codeBytes.length);                \n            } else {\n                if (endLine < minAndMaxLines[1]) {\n                    endLine++; // That's because we will need to inject code after the *last bytecode corresponding to endLine*\n                }\n\n                idxAndBCI1 = clazz.methodIdxAndBestBCIForLineNo(endLine);\n\n                // Now let's check if start and end lines are within the same method.\n                // If the end line is definitely within some other method, it's an error and we return.\n                // However, it may just cover one or more of '}'s in the end of this method, and these lines\n                // are just not within this method's line number table. If so, assume that the end line is\n                // the last line of the this method.\n                if (methodIdx != idxAndBCI1[0]) {\n                    if (idxAndBCI1[0] != -1) { // Definitely this line belongs to some other method\n\n                        return null;\n                    } else { // Couldn't find the line - assume it's the last line of the same method\n                        idxAndBCI1[0] = methodIdx;\n\n                        // Need to find the bci of the last instruction in this method. It can only be a \"return\" or 'goto' ('goto_w').\n                        // In either case, we should put the call before this instruction, since it would make no sense after it.\n                        byte[] codeBytes = clazz.getMethodBytecode(methodIdx);\n                        idxAndBCI1[1] = ClassInfo.findPreviousBCI(codeBytes, codeBytes.length);\n                    }\n                }\n            }\n\n            // Now here is another issue. It appears that at least \"while() { }\" is effectively compiled as \"do..while\",\n            // i.e. the condition check is located after the block, not before. Which leads to the problem: if the\n            // user points at the line with \"while\" as a first region line, the \"exact\" bytecode offset for this particular\n            // line may be greater than the offset for the next line after \"while\"! This leads to incorrect measurements\n            // results at best and to the JVM crash during bytecode oop map generation at worst. To handle this, we\n            // currently use heuristics which just looks up the line with the smallest bci in between startLine and endLine.\n            int bestBCI0 = idxAndBCI0[1];\n\n            for (int lineNo = startLine + 1; lineNo < (endLine - 1); lineNo++) {\n                int otherBestBCI0 = clazz.bciForMethodAndLineNo(methodIdx, lineNo);\n\n                if (otherBestBCI0 < bestBCI0) {\n                    bestBCI0 = otherBestBCI0;\n                }\n            }\n\n            // Finally, check if the last bci is of the \"goto\" opcode. If so, we should actually return the bci of the\n            // previous opcode, since injecting code probe right after the \"goto\", as it will be done if no measures are\n            // taken, makes no sense. This code will not work as intended, and most likely will be just unreachable.\n            // THIS IS INCORRECT. We inject code *before*, not after, the given bytecode. So it can be goto as well.\n            //idxAndBCI1[1] = clazz.checkIfAtGoTo(methodIdx, idxAndBCI1[1]);\n            return new CodeRegionBCI(clazz.getName(), clazz.getMethodNames()[methodIdx], clazz.getMethodSignatures()[methodIdx],\n                                     bestBCI0, idxAndBCI1[1]);\n        } else if (methodIdx == -2) { // No line number tables in this class\n            throw new BadLocationException(\"Class does not have source line number tables.\\nRecompile it with appropriate options.\"); // NOI18N\n        }\n\n        // Suitable method not found. Look at nested classes, if there are any.\n        return getMethodForSourceRegionInNestedClasses(clazz, startLine, endLine);\n    }\n\n    /*  public static int[] getMinAndMaxLinesForMethod(String className, String methodName, String methodSignature)  // TODO CHECK: unused method\n       throws IOException, ClassFormatError {\n       ClassInfo clazz = lookupClassOnAllPaths(className);\n       String methodNames[] = clazz.getMethodNames();\n       String methodSignatures[] = clazz.getMethodSignatures();\n       methodName = methodName.intern();\n       methodSignature = methodSignature.intern();\n       int idx = clazz.getMethodIndex(methodName, methodSignature);\n       if (idx != -1)\n         return clazz.getMinAndMaxLinesForMethod(idx);\n       else\n         return null;\n       }\n     */\n    public static CodeRegionBCI getMethodMinAndMaxBCI(ClassInfo clazz, String methodName, String methodSignature) {\n        methodName = methodName.intern();\n        methodSignature = methodSignature.intern();\n\n        int idx = clazz.getMethodIndex(methodName, methodSignature);\n\n        if (idx == -1) {\n            return null;\n        }\n\n        // Note that className and clazz.getName() may be different, e.g. if className is specified as \"x.y.Outer.Inner\",\n        // when the correct format understood by the rest of JFluid is \"x.y.Outer$Inner\".\n        return new CodeRegionBCI(clazz.getName(), methodName, methodSignature, 0, clazz.getMethodBytecode(idx).length - 1);\n    }\n\n    public void addClassInfo(BaseClassInfo pci) {\n        BaseClassInfo singleExistingClazzOrPCI;\n        SameNameClassGroup classGroup;\n        String className = pci.getName();\n\n        Object entry = classes.get(className);\n\n        if (entry != null) { // A single class or placeholder, or a group of them for this name, exists\n\n            if (entry instanceof BaseClassInfo) {\n                singleExistingClazzOrPCI = (BaseClassInfo) entry;\n                classGroup = new SameNameClassGroup();\n                classGroup.add(singleExistingClazzOrPCI);\n                classGroup.add(pci);\n                classes.put(className, classGroup);\n            } else { // entry is a SameNameClassGroup\n                classGroup = (SameNameClassGroup) entry;\n                classGroup.add(pci);\n            }\n        } else { // An entry with this name doesn't exist\n            classes.put(className, pci);\n        }\n    }\n\n    /** Adds a VM-supplied class file to the class file cache, but not to this repository's hashtable yet. */\n    public void addVMSuppliedClassFile(String className, int classLoaderId, byte[] buf) {\n        assert buf != null && buf.length > 0;\n        addVMSuppliedClassFile(className, classLoaderId, buf, null, null);\n    }\n    \n    /** Adds a VM-supplied class file to the class file cache, but not to this repository's hashtable yet. */\n    public void addVMSuppliedClassFile(String className, int classLoaderId, byte[] buf, String superClassName, String[] interfaceNames) {\n        classPath.addVMSuppliedClassFile(className, classLoaderId, buf);\n        if (buf != null && buf.length == 0) {\n            // register lazy dynamic class\n            try {\n                String location = getClassFileLoc(classLoaderId);\n                DynamicClassInfo lazyClass = new LazyDynamicClassInfo(classPath, className, classLoaderId, location, superClassName, interfaceNames);\n                addClassInfo(lazyClass);\n            } catch (IOException ex) { // this should not happen\n                Logger.getLogger(ClassRepository.class.getName()).log(Level.SEVERE, null, ex);\n            }\n        }\n    }\n\n    /** Should be called after profiling finishes to cleanup any static data, close opened files, etc. */\n    public void cleanup() {\n        clearCache();\n\n        if (classPath != null) {\n            classPath.close();\n            classPath = null;\n        }\n    }\n\n    /** Will reset any cached data, will not reset data pertinent to session in progress */\n    public void clearCache() {\n        classes = new Hashtable();\n//        ClassFileCache.resetDefaultCache();\n        notFoundClasses = new HashSet();\n        definingClassLoaderMap = new HashMap();\n    }\n\n    /**\n     * This is the ClassRepository internal class path initialization method. The class path is initialized to the\n     * combination of the running VM's boot, extension and main class paths (if they are available; otherwise only\n     * the main path is obtained from the tool's settings), plus the secondary class path from the settings.\n     *\n     * @param workingDir            working directory, needed in case the given paths are in the local form\n     * @param classPaths            the 3 elements should be the user, extension, and boot class paths, respectively\n     */\n    public void initClassPaths(String workingDir, String[] classPaths) {\n        List userClassPathElementList = MiscUtils.getPathComponents(classPaths[0], true, workingDir);\n        List bootClassPathElementList = MiscUtils.getPathComponents(classPaths[2], true, workingDir);\n\n        String extPath = classPaths[1];\n        List extClassPathElementList = new ArrayList();\n\n        // Extension class path needs special handling, since it consists of directories, which contain .jars\n        // So we need to find all these .jars in all these dirs and add them to extClassPathElementList\n        List dirs = MiscUtils.getPathComponents(extPath, true, workingDir);\n\n        for (Iterator e = dirs.iterator(); e.hasNext();) {\n            File extDir = new File((String) e.next());\n            String[] extensions = extDir.list(new FilenameFilter() {\n                    public boolean accept(File dir, String name) {\n                        name = name.toLowerCase(Locale.ENGLISH);\n\n                        return name.endsWith(\".zip\") || name.endsWith(\".jar\"); // NOI18N\n                    }\n                });\n\n            if (extensions == null) {\n                continue;\n            }\n\n            for (String extension : extensions) {\n                String extJar = extDir.getAbsolutePath() + File.separatorChar + extension;\n                List allJarComponents = MiscUtils.getPathComponents(extJar,true,workingDir);\n                extClassPathElementList.addAll(allJarComponents);\n            }\n        }\n\n        List list = new ArrayList();\n        list.addAll(bootClassPathElementList);\n        list.addAll(extClassPathElementList);\n        list.addAll(userClassPathElementList);\n\n        StringBuilder buf = new StringBuilder();\n\n        for (Iterator e = list.iterator(); e.hasNext();) {\n            buf.append((String) e.next());\n\n            if (e.hasNext()) {\n                buf.append(File.pathSeparatorChar);\n            }\n        }\n\n        classPath = new ClassPath(buf.toString(), true);\n\n        notFoundClasses = new HashSet();\n    }\n\n    /**\n     * Lookup a class in the class repository. If it's not there, look it up on the classpath (for classes with 0 loader)\n     * or in the cache of VM-supplied classes. If the class is not found anywhere, reports this and returns null.\n     * Guaranteed to return a real class or null, but not a placeholder. Should not be called for special (array)\n     * classes - there is lookupSpecialClass() for that.\n     */\n    public DynamicClassInfo lookupClass(String className, int classLoaderId)\n                                        throws IOException, ClassFormatError {\n        return lookupClass(className, classLoaderId, true);\n    }\n\n    /**\n     * Lookup a class in the class repository. If it's not there, don't bother checking the classpath etc. - just\n     * return an instance of PlaceholderClassInfo. The rationale is that we may not ever need the real class for\n     * className; and when we need it, lookupClass() above will deliver it.\n     */\n    public BaseClassInfo lookupClassOrCreatePlaceholder(String className, int classLoaderId) {\n        BaseClassInfo singleExistingClazzOrPCI = null;\n        BaseClassInfo clazzOrPCI = null;\n        SameNameClassGroup classGroup = null;\n        className = className.replace('.', '/').intern(); // NOI18N\n\n        Object entry = classes.get(className);\n\n        if (entry != null) { // A single class or placeholder, or a group of them for this name, exists\n\n            if (entry instanceof BaseClassInfo) {\n                singleExistingClazzOrPCI = (BaseClassInfo) entry;\n                clazzOrPCI = SameNameClassGroup.checkForCompatibility(this, singleExistingClazzOrPCI, classLoaderId);\n            } else { // entry is a SameNameClassGroup\n                classGroup = (SameNameClassGroup) entry;\n                clazzOrPCI = classGroup.findCompatibleClass(this, classLoaderId);\n            }\n\n            if (clazzOrPCI != null) { // Found compatible class or placeholder\n\n                return clazzOrPCI;\n            } else { // Non-null entry for this class name, but no compatible class or placeholder\n                clazzOrPCI = new PlaceholderClassInfo(className, classLoaderId);\n\n                if (classGroup != null) {\n                    classGroup.add(clazzOrPCI);\n                } else { // There is already a single incompatible class or placeholder in classes - create a new class group\n                    classGroup = new SameNameClassGroup();\n                    classGroup.add(singleExistingClazzOrPCI);\n                    classGroup.add(clazzOrPCI);\n                    classes.put(className, classGroup);\n                }\n\n                return clazzOrPCI;\n            }\n        } else { // An entry with this name doesn't exist\n            clazzOrPCI = new PlaceholderClassInfo(className, classLoaderId);\n            classes.put(className, clazzOrPCI);\n\n            return clazzOrPCI;\n        }\n    }\n\n    /**\n     * Lookup a class in the class repository, only among those currently loaded by the VM.\n     * If there is no loaded class and allowExistingPlaceholder is true, also check for an existing placeholders.\n     * Returns either a loaded class, or if allowed an existing placeholder, or null, but not a new placeholder.\n     */\n    public BaseClassInfo lookupLoadedClass(String className, int classLoaderId, boolean allowExistingPlaceholder) {\n        BaseClassInfo singleExistingClazzOrPCI = null;\n        BaseClassInfo clazzOrPCI = null;\n        className = className.replace('.', '/').intern(); // NOI18N\n\n        Object entry = classes.get(className);\n\n        if (entry != null) { // A single class or placeholder, or a group of them for this name, exists\n\n            if (entry instanceof BaseClassInfo) {\n                singleExistingClazzOrPCI = (BaseClassInfo) entry;\n                clazzOrPCI = SameNameClassGroup.checkForCompatibility(this, singleExistingClazzOrPCI, classLoaderId);\n            } else { // entry is a SameNameClassGroup\n\n                SameNameClassGroup classGroup = (SameNameClassGroup) entry;\n                clazzOrPCI = classGroup.findCompatibleClass(this, classLoaderId);\n            }\n\n            if (clazzOrPCI != null) { // Found compatible class or placeholder\n\n                if (!(clazzOrPCI instanceof PlaceholderClassInfo)) {\n                    return clazzOrPCI;\n                } else if (allowExistingPlaceholder) {\n                    return clazzOrPCI;\n                }\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Used only for special classes, such as array classes, that don't have a .class file on the class path. If a class\n     * with the given name does not exist, a BaseClassInfo is created for it immediately.\n     */\n    public BaseClassInfo lookupSpecialClass(String className) {\n        if (className.indexOf('.') != -1) { // NOI18N\n            className = className.replace('.', '/').intern(); // NOI18N\n        }\n\n        BaseClassInfo clazz = (BaseClassInfo) classes.get(className);\n\n        if (clazz == null) {\n            clazz = new BaseClassInfo(className, 0); // For now, we don't distinguish between Object array classes for different loaders (if such a thing exists)\n            classes.put(className, clazz);\n        }\n\n        return clazz;\n    }\n\n    int getDefiningClassLoaderId(String className, int classLoaderId) {\n        String classId = className + \"#\" + classLoaderId; // NOI18N\n        Integer loaderInt = (Integer) definingClassLoaderMap.get(classId);\n\n        if (loaderInt != null) {\n            return loaderInt.intValue();\n        }\n\n        int loader = -1;\n\n        try {\n            loader = TargetAppRunner.getDefault().getProfilerClient().getDefiningClassLoaderId(className, classLoaderId);\n        } catch (Exception ex) {\n            // Don't bother about reporting an exception - somebody will do that later\n        }\n\n        definingClassLoaderMap.put(classId, Integer.valueOf(loader));\n\n        return loader;\n    }\n\n    private CodeRegionBCI getMethodForSourceRegionInNestedClasses(ClassInfo clazz, int startLine, int endLine)\n        throws ClassNotFoundException, IOException, ClassFormatError {\n        String className = clazz.getName();\n        String[] nestedClassNames = clazz.getNestedClassNames();\n        int classNameLen = className.length();\n\n        if (nestedClassNames != null) {\n            for (String nestedClassName : nestedClassNames) {\n                if (!(nestedClassName.startsWith(className) && (nestedClassName.length() > classNameLen))) {\n                    continue;\n                }\n\n                try {\n                    ClassInfo nestedClass = lookupClass(nestedClassName, clazz.getLoaderId());\n\n                    if (nestedClass != null) {\n                        CodeRegionBCI res = getMethodForSourceRegion(nestedClass, startLine, endLine);\n\n                        if (res != null) {\n                            return res;\n                        }\n                    }\n                } catch (BadLocationException ex) {\n                    // Clearly if we got into this method, there was a line number table in the upper level class. So the BadLocationException\n                    // that can only be thrown if no line number table is found in this particular nested class is a bogus and misleading.\n                    return null;\n                }\n            }\n        }\n\n        return null;\n    }\n\n    private DynamicClassInfo checkForVMSuppliedClass(String className, int classLoaderId)\n                                                     throws IOException, ClassFormatError {\n        int realLoaderId = classPath.hasVMSuppliedClassFile(className, classLoaderId);\n\n        if (realLoaderId != -1) {\n            String classFileLoc = getClassFileLoc(realLoaderId);\n            return new DynamicClassInfo(classPath, className, classLoaderId, classFileLoc);\n        } else {\n            return null;\n        }\n    }\n\n    static String getClassFileLoc(int realLoaderId) {\n        return (LOCATION_VMSUPPLIED + realLoaderId).intern();\n    }\n\n    private DynamicClassInfo lookupClass(String className, int classLoaderId, boolean reportIfNotFound)\n                                         throws IOException, ClassFormatError {\n        BaseClassInfo singleExistingClazzOrPCI = null;\n        BaseClassInfo clazzOrPCI;\n        SameNameClassGroup classGroup = null;\n        className = className.replace('.', '/').intern(); // NOI18N\n\n        Object entry = classes.get(className);\n\n        if (entry != null) { // A single class or placeholder, or a group of them for this name, exists\n\n            if (entry instanceof BaseClassInfo) {\n                singleExistingClazzOrPCI = (BaseClassInfo) entry;\n                clazzOrPCI = SameNameClassGroup.checkForCompatibility(this, singleExistingClazzOrPCI, classLoaderId);\n            } else { // entry is a SameNameClassGroup\n                classGroup = (SameNameClassGroup) entry;\n                clazzOrPCI = classGroup.findCompatibleClass(this, classLoaderId);\n            }\n\n            if (clazzOrPCI != null) { // Found compatible class or placeholder\n\n                if (!(clazzOrPCI instanceof PlaceholderClassInfo)) {\n                    return (DynamicClassInfo) clazzOrPCI;\n                } else { // Found a compatible placeholder\n\n                    PlaceholderClassInfo pci = (PlaceholderClassInfo) clazzOrPCI;\n                    DynamicClassInfo clazz = tryLoadRealClass(className, classLoaderId, reportIfNotFound);\n\n                    if (clazz != null) { // Found a real class for this placeholder\n                        pci.transferDataIntoRealClass(clazz);\n\n                        if (classGroup != null) {\n                            classGroup.replace(pci, clazz);\n                        } else {\n                            classes.put(className, clazz);\n                        }\n\n                        return clazz;\n                    } else {\n                        return null; // Didn't find a real class for this placeholder\n                    }\n                }\n            } else { // Non-null entry for this class name, but no compatible class or placeholder\n\n                DynamicClassInfo clazz = tryLoadRealClass(className, classLoaderId, reportIfNotFound);\n\n                if (clazz != null) { // Managed to load a right class\n\n                    if (classGroup != null) {\n                        classGroup.add(clazz);\n                    } else { // There is already a single incompatible class or placeholder in classes - create a new class group\n                        classGroup = new SameNameClassGroup();\n                        classGroup.add(singleExistingClazzOrPCI);\n                        classGroup.add(clazz);\n                        classes.put(className, classGroup);\n                    }\n\n                    return clazz;\n                } else {\n                    return null; // Could not load a right class\n                }\n            }\n        } else { // An entry with this name doesn't exist\n\n            DynamicClassInfo clazz = tryLoadRealClass(className, classLoaderId, reportIfNotFound);\n\n            if (clazz != null) {\n                classes.put(className, clazz);\n\n                return clazz;\n            } else {\n                return null;\n            }\n        }\n    }\n\n    private DynamicClassInfo tryLoadRealClass(String className, int classLoaderId, boolean reportIfNotFound)\n                                              throws IOException, ClassFormatError {\n        DynamicClassInfo clazz = null;\n        int loader = classLoaderId;\n\n        do {\n            // In case of remote profiling, even system classes, that we otherwise can look up on disk locally, are\n            // supplied by the VM. That's why we always call checkForVMSuppliedClass first.\n            clazz = checkForVMSuppliedClass(className, loader);\n\n            if (clazz == null) {\n                if (((loader == 0) || (loader == -1)) && (classPath != null)) { // sanity check; to prevent NPE in case the classPath hasn't been initialized (shouldn't happen anyway)\n                    clazz = classPath.getClassInfoForClass(className, loader);\n                }\n            }\n\n            if ((clazz != null) || (loader == 0)) {\n                break;\n            }\n\n            // Try parent loader - in some cases a class can be initially requested with the loader of its subclass\n            loader = classPath.getClassLoaderTable().getParentLoader(loader);\n        } while (loader >= 0);\n\n        if (clazz == null) {\n            // In some cases, the class loader graph for the app may be a non-tree structure, i.e. one class loader may delegate\n            // not just to its parent loader, but to some other loader(s) as well. In that case, our last resort is to ask the\n            // initiating loader itself for this class, and then get its defining loader.\n            loader = getDefiningClassLoaderId(className, classLoaderId);\n\n            if (loader != -1) {\n                clazz = checkForVMSuppliedClass(className, loader); // See above about remote profiling\n\n                if (clazz == null) {\n                    if (loader == 0) {\n                        clazz = classPath.getClassInfoForClass(className, loader);\n                    }\n                }\n            }\n        }\n\n        if ((clazz == null) && reportIfNotFound) {\n            if (!notFoundClasses.contains(className)) {\n                MiscUtils.printWarningMessage(\"class \" + className + \", ldr = \" + classLoaderId + \" not found anywhere\"); // NOI18N\n                notFoundClasses.add(className);\n            }\n        }\n\n        return clazz;\n    }\n\n    //----------------------------------- Debugging -----------------------------------\n\n    /*\n       private static void dumpLineTable(Method method) {\n         LineNumberTable lnt = method.getLineNumberTable();\n         if (lnt == null) return;\n         LineNumber[] lns = lnt.getLineNumberTable();\n         System.out.println(\"Line number table for \" + method.getName() + \".\" + method.getSignature());\n         for (int i = 0; i < lns.length; i++) {\n           System.out.println(lns[i].getLineNumber() + \" \" + lns[i].getStartPC());\n         }\n       }\n     */\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/classfile/DynamicClassInfo.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.classfile;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\n\n\n/**\n * A representation of a binary Java class that contains information for the class file itself, plus various status\n * bits used for proper instrumentation state accounting in JFluid.\n *\n * @author Tomas Hurka\n * @author Misha Dmitirev\n */\npublic class DynamicClassInfo extends ClassInfo {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ArrayList subclasses; // Subclasses as DynamicClassInfos\n    private DynamicClassInfo superClass; // Superclass as a DynamicClassInfo (just name not is inconvenient when multiple classloaders are used)\n    private String classFileLocation; // Directory or .jar file where the .class file is located.\n    private int[] baseCPoolCount;\n    private int java_lang_ThowableCPIndex; // constant pool index for java.lang.Throwable\n    private char[] instrMethodIds; // Ids assigned to instrumented methods, 0 for uninstrumented methods\n    private DynamicClassInfo[] interfacesDCI; // Ditto for superinterfaces\n\n    // Data used by our call graph revelation mechanism, to mark classes/methods according to their reachability,\n    // scannability, etc. properties\n    private char[] methodScanStatus;\n\n    // On JDK 1.5, we save methodinfos for all instrumented methods (until they are deinstrumented), so when methods from\n    // same class are instrumented one-by-one and redefineClasses is used for each of them, we don't have to regenerate the\n    // code for each previously instrumented method over and over again.\n    private byte[][] modifiedAndSavedMethodInfos;\n    private int[] modifiedMethodBytecodesLength;\n    private int[] modifiledLocalVariableTableOffsets;\n    private int[] modifiledLocalVariableTypeTableOffsets;\n    private int[] modifiledStackMapTableOffsets;\n    private boolean allMethodsMarkers = false;\n    private boolean allMethodsRoots = false;\n    private boolean hasUninstrumentedMarkerMethods;\n    private boolean hasUninstrumentedRootMethods;\n    private boolean hasMethodReachable;\n    private boolean isLoaded;\n\n    // true if class was scanned for for HttpServlet.do*() methods\n    private boolean servletDoMethodScanned;\n\n    /** Data for supporting both 1.4.2-style constant pool incremental extending and 1.5-style redefinition as a whole */\n    private int currentCPoolCount; // The current number of entries in the cpool of this class (increased due to instrumentation)\n                                   // When we add entries to cpool for a particular injection type, its size before entries are added (base count) is stored\n                                   // in this array's element corresponding to this injection type number (e.g. INJ_RECURSIVE_NORMAL_METHOD or INJ_CODE_REGION).\n    private int nInstrumentedMethods;\n    ClassPath classPath;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public DynamicClassInfo(ClassPath cp, String className, int loaderId, String classFileLocation)\n                     throws IOException, ClassFormatError {\n        this(cp, className, loaderId, classFileLocation, true);\n    }\n    \n    DynamicClassInfo(ClassPath cp, String className, int loaderId, String classFileLocation, boolean parseClass)\n                     throws IOException, ClassFormatError {\n        super(className, loaderId);\n        this.classFileLocation = classFileLocation;\n        classPath = cp;\n        \n        if (parseClass) {\n            parseClassFile(className);\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setAllMethodsMarkers() {\n        allMethodsMarkers = true;\n        hasUninstrumentedMarkerMethods = true;\n    }\n\n    public boolean getAllMethodsMarkers() {\n        return allMethodsMarkers;\n    }\n\n    public void setAllMethodsRoots() {\n        allMethodsRoots = true;\n        hasUninstrumentedRootMethods = true;\n    }\n\n    public boolean getAllMethodsRoots() {\n        return allMethodsRoots;\n    }\n\n    public void setBaseCPoolCount(int injType, int v) {\n        baseCPoolCount[injType] = v;\n    }\n\n    public int getBaseCPoolCount(int injType) {\n        return baseCPoolCount[injType];\n    }\n\n    public int getBaseCPoolCountLen() {\n        return baseCPoolCount.length;\n    }\n\n    public byte[] getClassFileBytes() throws IOException {\n        return classPath.getClassFile(name, classFileLocation);\n    }\n\n    public String getClassFileLocation() {\n        return classFileLocation;\n    } // TODO CHECK: unused method\n\n    public void setCurrentCPoolCount(int v) {\n        currentCPoolCount = v;\n    }\n\n    public int getCurrentCPoolCount() {\n        return currentCPoolCount;\n    }\n\n    public int getExceptionTableStartOffsetInMethodInfo(int idx) {\n        if ((modifiedAndSavedMethodInfos != null) && (modifiedAndSavedMethodInfos[idx] != null)) {\n            int bcLen = getBCLenForModifiedAndSavedMethodInfo(idx);\n\n            return methodBytecodesOffsets[idx] + bcLen;\n        } else {\n            return super.getExceptionTableStartOffsetInMethodInfo(idx);\n        }\n    }\n\n    public int getLocalVariableTableStartOffsetInMethodInfo(int idx) {\n        if ((modifiedAndSavedMethodInfos != null) && (modifiedAndSavedMethodInfos[idx] != null)) {\n            if (modifiledLocalVariableTableOffsets[idx] == 0) {\n                int newOffset = getExceptionTableStartOffsetInMethodInfo(idx)+getExceptionTableCount(idx)*8+2;\n                byte[] methodInfo = getMethodInfo(idx);\n                int attrCount = getU2(methodInfo, newOffset); newOffset+=2;// Attribute (or rather sub-attribute) count\n\n                for (int k = 0; k < attrCount; k++) {\n                    int attrNameIdx = getU2(methodInfo, newOffset); newOffset+=2;\n                    int attrLen = getU4(methodInfo, newOffset); newOffset+=4;\n\n                    if (attrNameIdx==localVaribaleTableCPindex){\n                        modifiledLocalVariableTableOffsets[idx] = newOffset+2;\n                        break;\n                    }\n                    newOffset += attrLen;\n                }\n            }\n            return modifiledLocalVariableTableOffsets[idx];\n        } else {\n            return super.getLocalVariableTableStartOffsetInMethodInfo(idx);\n        }\n    }\n    \n    public int getLocalVariableTypeTableStartOffsetInMethodInfo(int idx) {\n        if ((modifiedAndSavedMethodInfos != null) && (modifiedAndSavedMethodInfos[idx] != null)) {\n            if (modifiledLocalVariableTypeTableOffsets[idx] == 0) {\n                int newOffset = getExceptionTableStartOffsetInMethodInfo(idx)+getExceptionTableCount(idx)*8+2;\n                byte[] methodInfo = getMethodInfo(idx);\n                int attrCount = getU2(methodInfo, newOffset); newOffset+=2;// Attribute (or rather sub-attribute) count\n\n                for (int k = 0; k < attrCount; k++) {\n                    int attrNameIdx = getU2(methodInfo, newOffset); newOffset+=2;\n                    int attrLen = getU4(methodInfo, newOffset); newOffset+=4;\n\n                    if (attrNameIdx==localVaribaleTypeTableCPindex){\n                        modifiledLocalVariableTypeTableOffsets[idx] = newOffset+2;\n                        break;\n                    }\n                    newOffset += attrLen;\n                }\n            }\n            return modifiledLocalVariableTypeTableOffsets[idx];\n        } else {\n            return super.getLocalVariableTypeTableStartOffsetInMethodInfo(idx);\n        }\n    }\n    \n    public int getStackMapTableStartOffsetInMethodInfo(int idx) {\n        if ((modifiedAndSavedMethodInfos != null) && (modifiedAndSavedMethodInfos[idx] != null)) {\n            if (modifiledStackMapTableOffsets[idx] == 0) {\n                int newOffset = getExceptionTableStartOffsetInMethodInfo(idx)+getExceptionTableCount(idx)*8+2;\n                byte[] methodInfo = getMethodInfo(idx);\n                int attrCount = getU2(methodInfo, newOffset); newOffset+=2;// Attribute (or rather sub-attribute) count\n\n                for (int k = 0; k < attrCount; k++) {\n                    int attrNameIdx = getU2(methodInfo, newOffset); newOffset+=2;\n                    int attrLen = getU4(methodInfo, newOffset); newOffset+=4;\n\n                    if (attrNameIdx==stackMapTableCPindex){\n                        modifiledStackMapTableOffsets[idx] = newOffset+2;\n                        break;\n                    }\n                    newOffset += attrLen;\n                }\n            }\n            return modifiledStackMapTableOffsets[idx];\n        } else {\n            return super.getStackMapTableStartOffsetInMethodInfo(idx);\n        }\n    }\n    \n    public void setHasUninstrumentedMarkerMethods(boolean v) {\n        hasUninstrumentedMarkerMethods = v;\n    }\n\n    public void setHasUninstrumentedRootMethods(boolean v) {\n        hasUninstrumentedRootMethods = v;\n    }\n\n    public void setInstrMethodId(int i, int id) {\n        instrMethodIds[i] = (char) id;\n    }\n\n    public char getInstrMethodId(int i) {\n        return instrMethodIds[i];\n    } // TODO CHECK: unused method\n\n    public void setLoaded(boolean loaded) {\n        isLoaded = loaded;\n    }\n\n    public boolean isLoaded() {\n        return isLoaded;\n    }\n\n    public byte[] getMethodBytecode(int idx) {\n        if ((modifiedAndSavedMethodInfos != null) && (modifiedAndSavedMethodInfos[idx] != null)) {\n            byte[] methodInfo = modifiedAndSavedMethodInfos[idx];\n            int bcLen = getBCLenForModifiedAndSavedMethodInfo(idx);\n            byte[] ret = new byte[bcLen];\n            System.arraycopy(methodInfo, methodBytecodesOffsets[idx], ret, 0, bcLen);\n\n            return ret;\n        } else {\n            return super.getMethodBytecode(idx);\n        }\n    }\n\n    public int getMethodBytecodesLength(int idx) {\n        if ((modifiedAndSavedMethodInfos != null) && (modifiedAndSavedMethodInfos[idx] != null)) {\n            return getBCLenForModifiedAndSavedMethodInfo(idx);\n        } else {\n            return super.getMethodBytecodesLength(idx);\n        }\n    }\n\n    public byte[] getMethodInfo(int idx) {\n        if ((modifiedAndSavedMethodInfos != null) && (modifiedAndSavedMethodInfos[idx] != null)) {\n            return modifiedAndSavedMethodInfos[idx];\n        } else {\n            return super.getMethodInfo(idx);\n        }\n    }\n\n    public int getMethodInfoLength(int idx) {\n        if ((modifiedAndSavedMethodInfos != null) && (modifiedAndSavedMethodInfos[idx] != null)) {\n            return modifiedAndSavedMethodInfos[idx].length;\n        } else {\n            return super.getMethodInfoLength(idx);\n        }\n    }\n\n    public void setMethodInstrumented(int i) {\n        methodScanStatus[i] |= 8;\n        nInstrumentedMethods++;\n    }\n\n    public boolean isMethodInstrumented(int i) {\n        return (methodScanStatus[i] & 8) != 0;\n    }\n\n    public void setMethodLeaf(int i) {\n        methodScanStatus[i] |= 16;\n    }\n\n    public boolean isMethodLeaf(int i) {\n        return (methodScanStatus[i] & 16) != 0;\n    }\n\n    public void setMethodMarker(int i) {\n        methodScanStatus[i] |= 256;\n        hasUninstrumentedMarkerMethods = true;\n    }\n\n    public boolean isMethodMarker(int i) {\n        return allMethodsMarkers || ((methodScanStatus[i] & 256) != 0);\n    }\n\n    public boolean hasMethodReachable() {\n        return hasMethodReachable;\n    }\n\n    public void setMethodReachable(int i) {\n        hasMethodReachable = true;\n        methodScanStatus[i] |= 1;\n    }\n\n    public boolean isMethodReachable(int i) {\n        return (methodScanStatus[i] & 1) != 0;\n    }\n\n    public void setMethodRoot(int i) {\n        methodScanStatus[i] |= 64;\n        hasUninstrumentedRootMethods = true;\n    }\n\n    public boolean isMethodRoot(int i) {\n        return allMethodsRoots || ((methodScanStatus[i] & 64) != 0);\n    }\n\n    public void setMethodScanned(int i) {\n        methodScanStatus[i] |= 4; /* hasUninstrumentedScannedMethods = true; */\n    }\n\n    public boolean isMethodScanned(int i) {\n        return (methodScanStatus[i] & 4) != 0;\n    }\n\n    public void setMethodSpecial(int i) {\n        methodScanStatus[i] |= 128;\n    }\n\n    public boolean isMethodSpecial(int i) {\n        return (methodScanStatus[i] & 128) != 0;\n    }\n\n    public void setMethodUnscannable(int i) {\n        methodScanStatus[i] |= 2;\n    }\n\n    public boolean isMethodUnscannable(int i) {\n        return (methodScanStatus[i] & 2) != 0;\n    }\n\n    public void setMethodVirtual(int i) {\n        methodScanStatus[i] |= 32;\n    }\n\n    public boolean isMethodVirtual(int i) {\n        return (methodScanStatus[i] & 32) != 0;\n    }\n\n    public byte[] getOrigMethodInfo(int idx) {\n        return super.getMethodInfo(idx);\n    }\n\n    public int getOrigMethodInfoLength(int idx) {\n        return super.getMethodInfoLength(idx);\n    }\n\n    public void setServletDoMethodScanned() {\n        servletDoMethodScanned = true;\n    }\n\n    public boolean isServletDoMethodScanned() {\n        return servletDoMethodScanned;\n    }\n\n    public boolean isSubclassOf(String superClass) {\n        if (getName() == superClass) {\n            return true;\n        }\n\n        DynamicClassInfo sc = getSuperClass();\n\n        if ((sc == null) || (sc == this)) {\n            return false;\n        }\n\n        return sc.isSubclassOf(superClass);\n    }\n\n    public ArrayList getSubclasses() {\n        return subclasses;\n    }\n\n    public void setSuperClass(DynamicClassInfo sc) {\n        superClass = sc;\n    }\n\n    public DynamicClassInfo getSuperClass() {\n        return superClass;\n    }\n\n    public void setSuperInterface(DynamicClassInfo si, int idx) {\n        if (interfacesDCI == null) {\n            interfacesDCI = new DynamicClassInfo[interfaces.length];\n        }\n\n        interfacesDCI[idx] = si;\n    }\n\n    public DynamicClassInfo[] getSuperInterfaces() {\n        return interfacesDCI;\n    }\n\n    public void addSubclass(DynamicClassInfo subclass) {\n        if (subclasses == null) {\n            if (name == OBJECT_SLASHED_CLASS_NAME) {\n                subclasses = new ArrayList(500);\n            } else {\n                subclasses = new ArrayList();\n            }\n        }\n        if (isInterface() && subclasses.contains(subclass)) {\n            return; // prevent duplicate classes in subclasses list\n        }\n\n        subclasses.add(subclass);\n    }\n\n    public void preloadBytecode() {\n        // NO-OP bytecode is loaded from file/jar\n    }\n\n    public void setInterface() {\n        // NO-OP, information is read from class file\n    }\n    \n    public boolean hasInstrumentedMethods() {\n        return (nInstrumentedMethods > 0);\n    }\n\n    public boolean hasUninstrumentedMarkerMethods() {\n        return hasUninstrumentedMarkerMethods;\n    }\n\n    /*\n       public boolean hasUninstrumentedScannedMethods()          { return hasUninstrumentedScannedMethods; }  // TODO CHECK: unused method\n       public void setHasUninstrumentedScannedMethods(boolean v) { hasUninstrumentedScannedMethods = v; }  // TODO CHECK: unused method\n     */\n    public boolean hasUninstrumentedRootMethods() {\n        return hasUninstrumentedRootMethods;\n    }\n\n    /**\n     * Note that this method uses the name of the interface in question intentionally - its (few) callers\n     * benefit from providing the name rather than a DynamicClassInfo.\n     */\n    public boolean implementsInterface(String intfName) {\n        String[] intfs = getInterfaceNames();\n\n        if (intfs != null) {\n            for (String intf : intfs) {\n                if (intfName == intf) {\n                    return true;\n                }\n            }\n\n            DynamicClassInfo[] intfsDCI = getSuperInterfaces();\n\n            if (intfsDCI != null) {\n                for (DynamicClassInfo intfClazz : intfsDCI) {\n                    if ((intfClazz != null) && intfClazz.implementsInterface(intfName)) {\n                        return true;\n                    }\n                }\n            }\n        }\n\n        DynamicClassInfo superClass = getSuperClass();\n\n        if ((superClass == null) || (superClass.getName() == OBJECT_SLASHED_CLASS_NAME)) {\n            return false;\n        }\n\n        return superClass.implementsInterface(intfName);\n    }\n\n    public void saveMethodInfo(int idx, byte[] methodInfo) {\n        if (modifiedAndSavedMethodInfos == null) {\n            modifiedAndSavedMethodInfos = new byte[methodNames.length][];\n        }\n\n        modifiedAndSavedMethodInfos[idx] = methodInfo;\n        modifiedMethodBytecodesLength = new int[methodNames.length];\n        modifiledLocalVariableTableOffsets = new int[methodNames.length];\n        modifiledLocalVariableTypeTableOffsets = new int[methodNames.length];\n        modifiledStackMapTableOffsets = new int[methodNames.length];\n    }\n\n    public void unsetMethodInstrumented(int i) {\n        methodScanStatus[i] &= (~8);\n        nInstrumentedMethods--;\n    }\n\n    public void unsetMethodSpecial(int i) {\n        methodScanStatus[i] &= (~128);\n    }\n\n    @Override\n    public void resetTables() {\n        if (modifiedAndSavedMethodInfos == null) {\n            super.resetTables();\n        }\n    }\n\n    public void addGlobalCatchStackMapTableEntry(int methodIdx, int endPC) {\n        if (majorVersion >= 50) {\n            boolean isStatic = isMethodStatic(methodIdx);\n            boolean constructor = \"<init>\".equals(getMethodName(methodIdx));    // NOI18N\n            int[] localsCPIdx = new int[0];\n            int[] stacksCPIdx;\n            \n//            LOG.finer(\"Adding global catch for \" + getName() + \" method \" + getMethodName(methodIdx));   // NOI18N\n            if (stackMapTableCPindex == 0) {\n                stackMapTableCPindex = getBaseCPoolCount(INJ_STACKMAP);\n            }\n            if (java_lang_ThowableCPIndex == 0) {\n                java_lang_ThowableCPIndex = getCPIndexOfClass(\"java/lang/Throwable\");   // NOI18N\n                if (java_lang_ThowableCPIndex == -1) {\n//                    LOG.finer(\"java/lang/Thowable not found in \" + getName());   // NOI18N\n                    java_lang_ThowableCPIndex = getBaseCPoolCount(INJ_THROWABLE);\n                }\n            }\n            stacksCPIdx = new int[] {java_lang_ThowableCPIndex};\n            if (!isStatic) {\n                if (constructor) {\n                    localsCPIdx = new int[] {0};\n                } else {\n                    localsCPIdx = new int[] {};\n                }\n            }\n            getStackMapTables().addFullStackMapFrameEntry(methodIdx, endPC, localsCPIdx, stacksCPIdx);\n        }\n    }\n\n    final void parseClassFile(String className) throws ClassFormatError, IOException {\n        byte[] classFileBytes = getClassFileBytes();\n        try {\n            new ClassFileParser().parseClassFile(classFileBytes, this);\n            \n            if (!className.equals(name)) {\n                throw new ClassFormatError(\"Mismatch between name in .class file and location for \" + className // NOI18N\n                        + \"\\nYour class path setting may be incorrect.\"); // NOI18N\n            }\n        } catch (ClassFileParser.ClassFileReadException ex) {\n            throw new ClassFormatError(ex.getMessage());\n        }\n        methodScanStatus = new char[methodNames.length];\n        instrMethodIds = new char[methodNames.length];\n        currentCPoolCount = origCPoolCount;\n        baseCPoolCount = new int[INJ_MAXNUMBER];\n\n        for (int i = 0; i < INJ_MAXNUMBER; i++) {\n            baseCPoolCount[i] = -1;\n        }\n    }\n\n    private int getBCLenForModifiedAndSavedMethodInfo(int idx) {\n        if (modifiedMethodBytecodesLength[idx] == 0) {\n            byte[] methodInfo = modifiedAndSavedMethodInfos[idx];\n            int bcLenPos = methodBytecodesOffsets[idx] - 4;\n\n            modifiedMethodBytecodesLength[idx] =  getU4(methodInfo,bcLenPos);\n        }\n        return modifiedMethodBytecodesLength[idx];\n    }\n\n    static int getU2(byte[] bytecodes, int pos) {\n        return ((bytecodes[pos] & 0xFF) << 8) + (bytecodes[pos + 1] & 0xFF);\n    }\n\n    static int getU4(byte[] bytecodes, int pos) {\n        return ((bytecodes[pos] & 0xFF) << 24) + ((bytecodes[pos + 1] & 0xFF) << 16) + ((bytecodes[pos + 2] & 0xFF) << 8)\n               + (bytecodes[pos + 3] & 0xFF);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/classfile/LazyDynamicClassInfo.java",
    "content": "/*\n * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.classfile;\n\nimport java.io.IOException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n\n/**\n * A representation of a binary Java class, which bytecode is loaded lazily.\n * Superclass and interfaces need to be specified in constructor, since they are\n * needed very early. Without it bytecode will be read for all classes and there\n * will be no laziness.\n *\n * @author Tomas Hurka\n */\npublic class LazyDynamicClassInfo extends DynamicClassInfo {\n    private boolean isInitilaized;\n    private boolean isInterface;\n\n    public LazyDynamicClassInfo(ClassPath cp, String className, int loaderId, String classFileLocation,\n            String superClassName, String[] interfaceNames) throws IOException {\n        super(cp, className, loaderId, classFileLocation, false);\n        superName = superClassName;\n        interfaces = interfaceNames;\n    }\n\n    public int getMethodIndex(String name, String sig) {\n        if (initializeClassFile()) {\n            return super.getMethodIndex(name, sig);\n        }\n        return -1;\n    }\n\n    public String[] getMethodNames() {\n        if (initializeClassFile()) {\n            return super.getMethodNames();\n        }\n        return new String[0];\n    }\n\n    public void preloadBytecode() {\n        super.preloadBytecode();\n        if (!isInitilaized) {\n            classPath.preloadBytecode(getName(), getClassFileLocation());\n        }\n    }\n\n    public boolean isInterface() {\n        if (!isInitilaized) {\n            return isInterface;\n        }\n        return super.isInterface();\n    }\n\n    public void setInterface() {\n        isInterface = true;\n    }\n\n    private boolean initializeClassFile() {\n        if (!isInitilaized) {\n            isInitilaized = true;\n            try {\n                parseClassFile(getName());\n                return true;\n            } catch (ClassFormatError ex) {\n                Logger.getLogger(LazyDynamicClassInfo.class.getName()).log(Level.SEVERE, null, ex);\n            } catch (IOException ex) {\n                Logger.getLogger(LazyDynamicClassInfo.class.getName()).log(Level.INFO, null, ex);\n            }\n            return false;\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/classfile/PlaceholderClassInfo.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.classfile;\n\n\n/**\n * A placeholder for a real class that can be put into the table in ClassRepository. Used temporarily, in situations when some\n * info about class becomes known and/or has to be recorded before the class itself is loaded by the VM. Once a real class\n * is loaded, it replaces the placeholder, and the info from the latter is transferred into the real class using\n * transferDataIntoRealClass.\n *\n * @author Misha Dmitirev\n */\npublic class PlaceholderClassInfo extends BaseClassInfo {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public PlaceholderClassInfo(String className, int classLoaderId) {\n        super(className, classLoaderId);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void transferDataIntoRealClass(DynamicClassInfo clazz) {\n        clazz.setInstrClassId(this.getInstrClassId());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/classfile/SameNameClassGroup.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.classfile;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n\n/**\n * A container for a group of classes/placeholders with the same name and different classloaders,\n * plus the functionality to browse this group and check for compatible classes.\n *\n * @author Tomas Hurka\n * @author Misha Dmitirev\n */\npublic class SameNameClassGroup {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private List classes;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    SameNameClassGroup() {\n        classes = new ArrayList(4); // Hope we are not going to have too many class versions...\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public List getAll() {\n        return classes;\n    }\n\n    public void add(BaseClassInfo clazz) {\n        classes.add(clazz);\n    }\n\n    /**\n     * Check if class clazz with its existing loader is compatible with loader classLoaderId - that is,\n     * loader classLoaderId will return this class if asked for the class with this name.\n     */\n    public static BaseClassInfo checkForCompatibility(ClassRepository repo, BaseClassInfo clazz, int classLoaderId) {\n        ClassLoaderTable table = repo.getClassPath().getClassLoaderTable();\n        int entryLoader = clazz.getLoaderId();\n\n        if (entryLoader == classLoaderId) {\n            return clazz;\n        } else {\n            if (isParentLoaderTo(table, entryLoader, classLoaderId)) {\n                return clazz;\n            } else if (clazz instanceof PlaceholderClassInfo && isParentLoaderTo(table, classLoaderId, entryLoader)) { // This can happen at least with placeholders\n                clazz.setLoaderId(classLoaderId);\n\n                return clazz;\n            } else if (classLoaderId > 0) {\n                // In some cases, the class loader graph for the app may be a non-tree structure, i.e. one class loader may delegate\n                // not just to its parent loader, but to some other loader(s) as well. In that case, our last resort is to ask for\n                // its defining loader.          \n                int loader = repo.getDefiningClassLoaderId(clazz.getName(), classLoaderId);\n\n                if (loader == -1) {\n                    return null;\n                }\n\n                if (loader == entryLoader) {\n                    return clazz;\n                }\n            }\n\n            return null;\n        }\n    }\n\n    /** Find a class compatible with the given loader (see definition in checkFroCompatibility()) in this group. */\n    public BaseClassInfo findCompatibleClass(ClassRepository repo, int classLoaderId) {\n        int size = classes.size();\n        for (int i = 0; i < size; i++) {\n            BaseClassInfo clazz = (BaseClassInfo) classes.get(i);\n            if (clazz.getLoaderId() == classLoaderId) {\n                return clazz;\n            }\n        }\n        for (int i = 0; i < size; i++) {\n            BaseClassInfo clazz = (BaseClassInfo) classes.get(i);\n            clazz = checkForCompatibility(repo, clazz, classLoaderId);\n\n            if (clazz != null) {\n                return clazz;\n            }\n        }\n\n        return null;\n    }\n\n    public void replace(BaseClassInfo clazz1, BaseClassInfo clazz2) {\n        classes.remove(clazz1);\n        classes.add(clazz2);\n    }\n\n    private static boolean isParentLoaderTo(ClassLoaderTable table, int testParentLoader, int testChildLoader) {\n        int parent = table.getParentLoader(testChildLoader);\n\n        while (parent != testParentLoader) {\n            if (parent == 0) {\n                return false;\n            } else {\n                parent = table.getParentLoader(parent);\n            }\n        }\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/client/AppStatusHandler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.client;\n\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.Command;\n\n\n/**\n * A utility interface, used to handle (by displaying things in GUI) various app status changes.\n *\n * @author  Misha Dmitriev\n */\npublic interface AppStatusHandler {\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    /**\n     * An interface for a dialog that displays a message and a Cancel button.\n     * The intended usage is in situations when some action is done in background, and the user should be able to\n     * interrupt it at any moment.\n     * The dialog is displayed using display(). Then the status of the Cancel button should be polled periodically\n     * using cancelPressed() method, and finally the dialog can be closed using close(). Note that display() inevitably\n     * blocks the thread that called it, so it should be called in a thread separate from the one in which the background\n     * action is performed.\n     */\n    public static interface AsyncDialog {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void close();\n\n        /**\n         * This method is called to display the asynchronous wait dialog. It should block\n         * until the user explicitely cancels or method AsyncDialog.close is called\n         */\n        public void display();\n    }\n\n    /**\n     * A utility class, used to handle (by displaying things in GUI and by updating some parent class internal variables)\n     * commands coming from the server.\n     */\n    public static interface ServerCommandHandler {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void handleServerCommand(Command cmd);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public AsyncDialog getAsyncDialogInstance(String message, boolean showProgress, Runnable cancelHandler);\n\n    // The following methods should display messages asynchronously, i.e. they shouldn't block the current\n    // thread waiting for the user pressing OK.\n    public void displayError(String msg);\n\n    // These 3 methods SHOULD wait for the user to press ok, since they may be used in a sequence of displayed\n    // panels, and the next one shouldn't be displayed before the previous one is read and understood.\n    public void displayErrorAndWaitForConfirm(String msg);\n\n    public void displayErrorWithDetailsAndWaitForConfirm(String shortMsg, String detailsMsg);\n\n    public void displayNotification(String msg);\n\n    public void displayNotificationAndWaitForConfirm(String msg);\n\n    public void displayNotificationWithDetailsAndWaitForConfirm(String shortMsg, String detailsMsg);\n\n    public void displayWarning(String msg);\n\n    public void displayWarningAndWaitForConfirm(String msg);\n\n    /** Called each time profiling results will become available for the first time using current instrumentation */\n    public void resultsAvailable();\n\n    public void takeSnapshot();\n\n    /**\n     * Called from the profiler engine in case the waiting for reply timed out.\n     * The profiler can decide (e.g. by asking the user) whether to keep waiting or cancel the profiling.\n     *\n     * @return true to keep waiting for reply, false to cancel profiling\n     */\n    boolean confirmWaitForConnectionReply();\n\n    void handleShutdown();\n\n    /**\n     *  Called from the engine to signal that the profiler should not be getting results\n     *  because some internal change is in progress.\n     */\n    void pauseLiveUpdates();\n\n    /**\n     *  Called from the engine to signal that it is again safe to start getting results\n     */\n    void resumeLiveUpdates();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/client/ClientUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.client;\n\nimport java.util.Objects;\nimport java.util.regex.Pattern;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.DefaultMethodNameFormatter;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatter;\n\n\n/**\n * A collection of utility classes and methods used exclusively by the client.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Adrian Mos\n * @author Ian Formanek\n */\npublic class ClientUtils implements CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n    private static final MethodNameFormatter classNameFormatter = new DefaultMethodNameFormatter(DefaultMethodNameFormatter.VERBOSITY_CLASS);\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class SourceCodeSelection implements Cloneable {\n\n        private static final Pattern P1 = Pattern.compile(\"$**\", Pattern.LITERAL); // NOI18N\n        private static final Pattern P2 = Pattern.compile(\".**\", Pattern.LITERAL); // NOI18N\n        private static final Pattern P3 = Pattern.compile(\".*\", Pattern.LITERAL);  // NOI18N\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        String className;\n        String normalizedClassName;\n        String methodName;\n        String methodSignature;\n        boolean isMarkerMethod;\n        int endLine;\n        int startLine;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public SourceCodeSelection(String className, int startLine, int endLine) {\n            this.className = (className != null) ? className : \"\"; // NULL might cause problems in JFluid - see eg. #95961\n            this.startLine = startLine;\n            this.endLine = endLine;\n\n            // methodName and methodSignature are null in this case\n        }\n\n        public SourceCodeSelection(String className, String methodName, String methodSignature) {\n            this.className = (className != null) ? className : \"\"; // NULL might cause problems in JFluid - see eg. #95961\n            this.methodName = (methodName != null) ? methodName : \"\"; // NULL might cause problems in JFluid - see eg. #95961\n            this.methodSignature = (methodSignature != null) ? methodSignature : \"\"; // NULL might cause problems in JFluid - see eg. #95961\n            startLine = endLine = -1;\n        }\n\n        // Used for various special instrumentation kinds where no real method name/line are used\n        public SourceCodeSelection(int specialCode) {\n            if (specialCode == 1) {\n                // \"Instrument all spawned threads\" profiling mode. The \"run()\" method of all threads started after\n                // the \"instrument\" command is issued, is instrumented - but NOT the main() method. The intended usage\n                // of this mode is when JFluid is attached to an already running app. Otherwise, one should set the\n                // main method as a root, and call GlobalSettins.setInstrumentSpawnedThreads(true) explicitly.\n                className = NO_CLASS_NAME;\n                methodName = NO_METHOD_NAME;\n                methodSignature = NO_METHOD_SIGNATURE;\n                startLine = endLine = 0; // So that it's defined neither via source line nor via method name\n            }\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public String getClassName() {\n            return className;\n        }\n        \n        String getNormalizedClassName() {\n            if (normalizedClassName == null) {\n                normalizedClassName = P1.matcher(className).replaceAll(\"\"); // NOI18N\n                normalizedClassName = P2.matcher(normalizedClassName).replaceAll(\"\"); // NOI18N\n                normalizedClassName = P3.matcher(normalizedClassName).replaceAll(\"\"); // NOI18N\n            }\n            return normalizedClassName;\n        }\n\n        public int getEndLine() {\n            return endLine;\n        }\n\n        public void setMarkerMethod(boolean value) {\n            isMarkerMethod = value;\n        }\n\n        public boolean isMarkerMethod() {\n            return isMarkerMethod;\n        }\n\n        public String getMethodName() {\n            return methodName;\n        }\n\n        public String getMethodSignature() {\n            return methodSignature;\n        }\n\n        public int getStartLine() {\n            return startLine;\n        }\n\n        /** Return if the selection represents whole default package. */\n        public boolean isDefaultPackage() {\n            return className.isEmpty() && methodName.isEmpty() && methodSignature.isEmpty();\n        }\n        \n        /** Return if the selection represents subset of default package. */\n        public boolean isInDefaultPackage() {\n            return isDefaultPackage() || !className.contains(\".\");\n        }\n\n        public Object clone() throws CloneNotSupportedException {\n            SourceCodeSelection clone = (SourceCodeSelection) super.clone();\n            clone.className = className;\n            clone.normalizedClassName = normalizedClassName;\n            clone.methodName = methodName;\n            clone.methodSignature = methodSignature;\n            clone.endLine = endLine;\n            clone.startLine = startLine;\n\n            return clone;\n        }\n\n        public boolean contains(ClientUtils.SourceCodeSelection anotherSelection) {\n            if (definedViaSourceLines()) {\n                if (className.equals(anotherSelection.className)) {\n                    return (startLine >= anotherSelection.startLine) && (endLine <= anotherSelection.endLine);\n                }\n            } else {\n                if (isDefaultPackage()) {\n                    return isInDefaultPackage();\n                } else {\n                    String thisFlattened = toFlattened().replace('.', '\\\\').replace('$', '\\\\') + \"\\\\\"; //NOI18N\n                    String anotherFlattened = anotherSelection.toFlattened().replace('.', '\\\\').replace('$', '\\\\'); //NOI18N\n\n                    return anotherFlattened.startsWith(thisFlattened);\n                }\n            }\n\n            return false;\n        }\n\n        public boolean definedViaMethodName() {\n            return startLine == -1;\n        }\n\n        public boolean definedViaSourceLines() {\n            return startLine > 0;\n        }\n\n        public boolean equals(Object obj) {\n            if (obj == null) {\n                return false;\n            }\n\n            if (!(obj instanceof SourceCodeSelection)) {\n                return false;\n            }\n\n            SourceCodeSelection other = (SourceCodeSelection) obj;\n\n            //      if (this.isMarkerMethod != other.isMarkerMethod) return false;\n            // check start/end lines - they should be the same even in case they are not used\n            if ((this.startLine != other.startLine) || (this.endLine != other.endLine)) {\n                return false;\n            }\n\n//            // length of classNames needs to be the same\n//            // normalizing the class name; result of #203446\n//            String cn1 = this.className.replace(\"$**\", \"\").replace(\".**\", \"\").replace(\".*\", \"\"); // NOI18N\n//            // normalizing the class name; result of #203446\n//            String cn2 = other.className.replace(\"$**\", \"\").replace(\".**\", \"\").replace(\".*\", \"\"); // NOI18N\n//            if (!cn1.equals(cn2)) {\n//                return false;\n//            }\n            if (!getNormalizedClassName().equals(other.getNormalizedClassName())) return false;\n\n            if (!Objects.equals(methodName, other.methodName)) {\n                return false;\n            }\n            if (!Objects.equals(methodSignature, other.methodSignature)) {\n                return false;\n            }\n\n            return true;\n        }\n\n        public int hashCode() {\n            int hashcode = 0;\n            hashcode += (startLine + endLine);\n            hashcode += className.hashCode();\n//            hashcode += getNormalizedClassName().hashCode(); // ??? Should further improve the performance but actually degrades it\n            hashcode += ((methodName != null) ? methodName.hashCode() : 0);\n            hashcode += ((methodSignature != null) ? methodSignature.hashCode() : 0);\n\n            return hashcode;\n        }\n\n        public String toFlattened() {\n            if ((className == null) || (className.length() == 0)) {\n                return \"\"; // NOI18N\n            }\n\n            boolean wildcard = className.endsWith(\"*\"); // NOI18N\n            StringBuilder flattenedBuf = new StringBuilder(getNormalizedClassName());\n\n            if (!wildcard && methodName != null && methodName.length() > 0 && !methodName.endsWith(\"*\")) { //NOI18N\n                flattenedBuf.append('.').append(methodName);\n            }\n\n            if (!wildcard && methodSignature != null && methodSignature.length() > 0 && !methodSignature.endsWith(\"*\")) { //NOI18N\n                flattenedBuf.append(methodSignature);\n            }\n\n            return flattenedBuf.toString(); //NOI18N\n        }\n\n        public String toString() {\n            if (definedViaSourceLines()) {\n                return \"Source Code defined via lines: [class: \" // NOI18N\n                       + className + \", start line: \" // NOI18N\n                       + startLine + \", end line: \" // NOI18N\n                       + endLine + \"]\"; // NOI18N\n            } else {\n                StringBuilder sb = new StringBuilder();\n                sb.append(\"Source Code defined via method: \"); // NOI18N\n                sb.append(\"\\n\"); // NOI18N\n                sb.append(\"  class: \"); // NOI18N\n                sb.append(className);\n                sb.append(\"\\n  \"); // NOI18N\n\n                if (methodName != null) {\n                    sb.append(\"  method: \"); // NOI18N\n                    sb.append(methodName);\n                    sb.append(\"  \"); // NOI18N\n                    sb.append(methodSignature);\n                    sb.append(\"\\n  \"); // NOI18N\n                }\n\n                if (isMarkerMethod) {\n                    sb.append(\"[Marker Method]\\n\"); //NOI18N\n                }\n\n                return sb.toString();\n            }\n        }        \n    }\n\n    public static class TargetAppFailedToStart extends Exception {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private String origCause;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public TargetAppFailedToStart(String errorMessage) {\n            this.origCause = errorMessage;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public String getOrigCause() {\n            return origCause;\n        }\n    }\n\n    public static class TargetAppOrVMTerminated extends Exception {\n        //~ Static fields/initializers -------------------------------------------------------------------------------------------\n\n        public static final int VM = 1;\n        public static final int APP = 2;\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        int code;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public TargetAppOrVMTerminated(int code) {\n            this.code = code;\n        }\n\n        public TargetAppOrVMTerminated(int code, String message) {\n            super(message);\n            this.code = code;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public boolean isAppTerminated() {\n            return (code == APP);\n        }\n\n        public String getMessage() {\n            if (super.getMessage() == null) {\n                return (code == VM) ? \"Target JVM inactive\" : \"Target application inactive\"; // NOI18N\n            } else {\n                return super.getMessage();\n            }\n        }\n\n        public boolean isVMTerminated() {\n            return (code == VM);\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final String LINES_PREFIX = \"[lines]\"; //NOI18N\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static String selectionToString(ClientUtils.SourceCodeSelection selection) {\n        if (selection == null) {\n            return \"\"; //NOI18N\n        }\n\n        if (selection.definedViaSourceLines()) {\n            return LINES_PREFIX + selection.getClassName() + \",\" + selection.getStartLine() + \",\" + selection.getEndLine(); //NOI18N\n        } else {\n            if (selection.getMethodName() == null) {\n                return selection.getClassName();\n            } else if (selection.getMethodSignature() == null) {\n                return selection.getClassName() + \",\" + selection.getMethodName(); //NOI18N\n            } else {\n                return selection.getClassName() + \",\" + selection.getMethodName() + \",\" + selection.getMethodSignature(); //NOI18N\n            }\n        }\n    }\n\n    public static ClientUtils.SourceCodeSelection stringToSelection(String str) {\n        if ((str == null) || (str.length() == 0)) {\n\n            return null;\n        }\n\n        boolean viaLines = false;\n\n        if (str.startsWith(LINES_PREFIX)) {\n            viaLines = true;\n            str = str.substring(LINES_PREFIX.length());\n        }\n\n        String[] parts = str.split(\",\"); //NOI18N\n\n        if (viaLines) {\n            if (parts.length != 3) {\n                return null; // invalid\n            }\n\n            try {\n                return new ClientUtils.SourceCodeSelection(parts[0], Integer.parseInt(parts[1]), Integer.parseInt(parts[2]));\n            } catch (NumberFormatException e) {\n                return null; // error in encoding of lines\n            }\n        } else {\n            String className = \"\"; // NOI18N\n\n            if (parts.length > 0) {\n                className = parts[0];\n            }\n\n            String methodName = \"\"; // NOI18N\n\n            if (parts.length > 1) {\n                methodName = parts[1];\n            }\n\n            String methodSig = \"\"; // NOI18N\n\n            if (parts.length > 2) {\n                methodSig = parts[2];\n            }\n\n            return new ClientUtils.SourceCodeSelection(className, methodName, methodSig);\n        }\n    }\n\n    /** Format class name for use in root editor dialogs.\n     *  @param className class name obtained from {@link SourceCodeSelection#getClassName() }\n     *  @return class name formated to human readable form\n     */\n    public static String formatClassName(String className) {\n        return classNameFormatter.formatMethodName(className, \"\", \"\").toFormatted();\n    }\n\n    /** Parse user input text to the class name. Inversion of {@link #formatClassName(String)}.\n     *  @param text user input\n     *  @param allowWildcards enable wildcards in the class name\n     *  @return class name for use in {@link SourceCodeSelection} or <code>null</code> in case of malformed input.\n     */\n    public static String parseClassName(String text, boolean allowWildcards) {\n        if(text.isEmpty()) {\n            return null;\n        }\n        //irregularities for default package\n        if(text.equals(\".*\")) {\n            return allowWildcards ? \"\" : null;\n        }\n        if(text.equals(\".**\")) {\n            return null;\n        }\n\n        String[] components = text.split(\"\\\\.\", -1);//NOI18N\n        int len = components.length;\n        String last = components[len-1];\n        \n        if(len == 1) {\n            //class in default package\n            if(text.startsWith(\"*\")) {\n                //only $** suffix allowed\n                return null;\n            }\n            return checkWildcards(text, allowWildcards, false) ? text: null;\n        }\n        for(int i = 0; i < len; i++) {\n            if(components[i].isEmpty()) {\n                //missing component name\n                return null;\n            }\n            if(i < len-1 && components[i].contains(\"*\")) {//NOI18N\n                //wildcards are allowed only in the last component\n                return null;\n            }\n        }\n        if(checkWildcards(last, allowWildcards, true)) {\n            return text;\n        }\n        return null;\n    }\n\n    /** Check wildcards in the last component of the class name */\n    private static boolean checkWildcards(String last, boolean allowWildcards, boolean allowSubPackages) {\n        int wildcard = last.indexOf('*');//NOI18N\n        if(wildcard == -1) {\n            return true;\n        }\n        if(!allowWildcards) {\n            return false;\n        }\n        if(wildcard == last.length()-1) {\n            return true;\n        }\n        if(!allowSubPackages) {\n            return false;\n        }\n        if(wildcard != last.length()-2 || !last.endsWith(\"*\")) {//NOI18N\n            // ** must be at the end of class name\n            return false;\n        }        \n        return wildcard == 0 || last.charAt(wildcard-1) == '$';//NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/client/MonitoredData.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.client;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.MonitoredNumbersResponse;\n\n\n/**\n * A representation of the monitored data, returned by the server on demand, that is suitable for use by\n * presentation code.\n *\n * @author Tomas Hurka\n * @author  Misha Dmitriev\n */\npublic class MonitoredData {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private long[] gcFinishs;\n    private long[] gcStarts;\n\n    // The following array contains:\n    // - the amounts of free and total memory in elements 0 and 1\n    // - the number of user and system threads in elements 2 and 3\n    // - number of surviving generations in element 4\n    // - relative time spent in GC, in per mil (1/10th of per cent), and the duration of the last GC pause (in ms) in elements 5 and 6\n    // - timestamp at the moment when this packet was generated (obtained with System.currentTimeMillis()) in element 7\n    private long[] generalMNumbers;\n    private String[] newThreadClassNames;\n    private int[] newThreadIds;\n    private String[] newThreadNames;\n    private long[] stateTimestamps;\n    private int[] threadIds;\n    private byte[][] threadStates = new byte[20][20];\n\n    private int[] exThreadIds;\n    private long[] exStateTimestamps;\n    private byte[] exThreadStates;\n    private int mode = CommonConstants.MODE_THREADS_NONE;\n\n    // Data on new threads. Any thread that has been created between the previous and the current use of this object\n    // shows up on the list below, but just once. nNewThreads is the real number of threads, which may be shorter than\n    // the size of the following arrays.\n    private int nNewThreads;\n    private int nThreadStates;\n\n    // Data on thread states. nThreads is the real number of threads (dimension 0 of the following arrays), which\n    // may be shorter than the actual size of the following arrays. nStates is the number of thread states\n    // (dimension 1 of these arrays), and also may be shorter than the actual size.\n    // Thread state timestamps are expressed in milliseconds as obtained by System.currentTimeMillis() on server side.\n    // threadStates use constants defined in CommonConstants for thread states.\n    private int nThreads;\n\n    private int serverState;\n    private int serverProgress;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private MonitoredData(ProfilingSessionStatus status, MonitoredNumbersResponse mresp) {\n        long[] gn = mresp.getGeneralMonitoredNumbers();\n        generalMNumbers = new long[gn.length];\n        System.arraycopy(gn, 0, generalMNumbers, 0, gn.length);\n        mode = mresp.getThreadsDataMode();\n        \n        if (mode == CommonConstants.MODE_THREADS_SAMPLING) {\n            nThreads = mresp.getNThreads();\n            nThreadStates = mresp.getNThreadStates();\n            \n            int[] ids = mresp.getThreadIds();\n            threadIds = new int[nThreads];\n            System.arraycopy(ids, 0, threadIds, 0, nThreads);\n            \n            long[] ts = mresp.getStateTimestamps();\n            stateTimestamps = new long[nThreadStates];\n            System.arraycopy(ts, 0, stateTimestamps, 0, nThreadStates);\n            \n            setThreadStates(mresp.getThreadStates());\n        } else if (mode == CommonConstants.MODE_THREADS_EXACT) {\n            int expLen = mresp.getExactThreadIds().length;\n            exThreadIds = new int[expLen];\n            System.arraycopy(mresp.getExactThreadIds(), 0, exThreadIds, 0, expLen);\n            exThreadStates = new byte[expLen];\n            System.arraycopy(mresp.getExactThreadStates(), 0, exThreadStates, 0, expLen);\n            exStateTimestamps = new long[expLen];\n            System.arraycopy(mresp.getExactStateTimestamps(), 0, exStateTimestamps, 0, expLen);\n        }\n\n        nNewThreads = mresp.getNNewThreads();\n\n        if (nNewThreads > 0) {\n            int[] newIds = mresp.getNewThreadIds();\n            newThreadIds = new int[nNewThreads];\n            System.arraycopy(newIds, 0, newThreadIds, 0, nNewThreads);\n            newThreadNames = new String[nNewThreads];\n            System.arraycopy(mresp.getNewThreadNames(), 0, newThreadNames, 0, nNewThreads);\n            newThreadClassNames = new String[nNewThreads];\n            System.arraycopy(mresp.getNewThreadClassNames(), 0, newThreadClassNames, 0, nNewThreads);\n        }\n\n        gcStarts = mresp.getGCStarts();\n        convertToTimeInMillis(status, gcStarts);\n        gcFinishs = mresp.getGCFinishs();\n        convertToTimeInMillis(status, gcFinishs);\n\n        serverState = mresp.getServerState();\n        serverProgress = mresp.getServerProgress();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getServerState() {\n        return serverState;\n    }\n\n    public int getServerProgress() {\n        return serverProgress;\n    }\n\n    public long getFreeMemory() {\n        return generalMNumbers[MonitoredNumbersResponse.FREE_MEMORY_IDX];\n    }\n\n    public long[] getGCFinishs() {\n        return gcFinishs;\n    }\n\n    public long[] getGCStarts() {\n        return gcStarts;\n    }\n\n    public long getLastGCPauseInMS() {\n        return generalMNumbers[MonitoredNumbersResponse.GC_PAUSE_IDX];\n    }\n\n    public long getLoadedClassesCount() {\n        return generalMNumbers[MonitoredNumbersResponse.LOADED_CLASSES_IDX];\n    }\n\n    /**\n     * Returns the approximate accumulated process CPU elapsed time\n     * in nanoseconds. Note that the time is normalized to one processor.\n     * This method returns <tt>-1</tt> if the collection\n     * elapsed time is undefined for this collector.\n     *\n     * @return the approximate accumulated process CPU elapsed time\n     * in nanoseconds.\n     */\n    public long getProcessCpuTime() {\n        return generalMNumbers[MonitoredNumbersResponse.CPU_TIME_IDX];\n    }\n\n    /**\n     * With mresp, the same instance is reused all the time to save memory. However, with MonitoredData we\n     * generally can't afford that, so here we create a new object every time and copy data into it.\n     */\n    public static MonitoredData getMonitoredData(MonitoredNumbersResponse mresp) {\n        return new MonitoredData(null, mresp);\n    }\n\n    public static MonitoredData getMonitoredData(ProfilingSessionStatus status, MonitoredNumbersResponse mresp) {\n        return new MonitoredData(status, mresp);\n    }\n\n    public int getNNewThreads() {\n        return nNewThreads;\n    }\n\n    public long getNSurvivingGenerations() {\n        return generalMNumbers[MonitoredNumbersResponse.SURVIVING_GENERATIONS_IDX];\n    }\n\n    public long getNSystemThreads() {\n        return generalMNumbers[MonitoredNumbersResponse.SYSTEM_THREADS_IDX];\n    }\n\n    public int getNThreadStates() {\n        return nThreadStates;\n    }\n\n    public int getNThreads() {\n        return nThreads;\n    }\n\n    public long getNUserThreads() {\n        return generalMNumbers[MonitoredNumbersResponse.USER_THREADS_IDX];\n    }\n\n    public String[] getNewThreadClassNames() {\n        return newThreadClassNames;\n    }\n\n    public int[] getNewThreadIds() {\n        return newThreadIds;\n    }\n\n    public String[] getNewThreadNames() {\n        return newThreadNames;\n    }\n\n    public int getThreadsDataMode() {\n        return mode; \n    }\n\n    public int[] getExplicitThreadIds() {\n        return exThreadIds;\n    }\n    public long[] getExplicitStateTimestamps() {\n        return exStateTimestamps;\n    }\n    public byte[] getExplicitThreadStates() {\n        return exThreadStates;\n    }\n\n    public long getRelativeGCTimeInPerMil() {\n        return generalMNumbers[MonitoredNumbersResponse.GC_TIME_IDX];\n    }\n\n    public long[] getStateTimestamps() {\n        return stateTimestamps;\n    }\n\n    public int[] getThreadIds() {\n        return threadIds;\n    }\n\n    public byte[][] getThreadStates() {\n        return threadStates;\n    }\n\n    public long getTimestamp() {\n        return generalMNumbers[MonitoredNumbersResponse.TIMESTAMP_IDX];\n    }\n\n    public long getTotalMemory() {\n        return generalMNumbers[MonitoredNumbersResponse.TOTAL_MEMORY_IDX];\n    }\n\n    private static void convertToTimeInMillis(ProfilingSessionStatus session, final long[] hiResTimeStamp) {\n        if (hiResTimeStamp.length > 0) {\n            long statupInCounts = session.startupTimeInCounts;\n            long startupMillis = session.startupTimeMillis;\n\n            for (int i = 0; i < hiResTimeStamp.length; i++) {\n                hiResTimeStamp[i] = startupMillis + ((hiResTimeStamp[i] - statupInCounts) / (1000000000 / 1000L)); // 1 ms has 1000000000/1000 ns\n            }\n        }\n    }\n\n    private void setThreadStates(byte[] packedStates) {\n        threadStates = new byte[nThreads][nThreadStates];\n\n        int idx = 0;\n\n        for (int i = 0; i < nThreads; i++) {\n            System.arraycopy(packedStates, idx, threadStates[i], 0, nThreadStates);\n            idx += nThreadStates;\n        }\n    }\n\n    /** Debugging support */\n    private void print() {\n        for (int i = 0; i < nThreads; i++) {\n            System.err.print(\"id = \"); // NOI18N\n            System.err.print(threadIds[i]);\n            System.err.print(\", states = \"); // NOI18N\n\n            for (int j = 0; j < nThreadStates; j++) {\n                System.err.print(threadStates[i][j]);\n            }\n\n            System.err.println();\n        }\n\n        if (nNewThreads > 0) {\n            System.err.println(\"New threads added: \" + nNewThreads); // NOI18N\n\n            for (int i = 0; i < nNewThreads; i++) {\n                System.err.println(\"  id = \" + newThreadIds[i] + \", name = \" + newThreadNames[i] + \", classname = \" // NOI18N\n                                   + newThreadClassNames[i]);\n            }\n        }\n\n        System.err.println();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/client/ProfilingPointsProcessor.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.client;\n\n\n/**\n *\n * @author Tomas Hurka\n */\npublic abstract class ProfilingPointsProcessor {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public abstract void profilingPointHit(RuntimeProfilingPoint.HitEvent event);\n\n    public abstract void timeAdjust(final int threadId, final long timeDiff0, final long timeDiff1);\n\n    public abstract void init(Object project);\n\n    public abstract RuntimeProfilingPoint[] getSupportedProfilingPoints();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/client/RuntimeProfilingPoint.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.client;\n\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\n\n\n/**\n * Represents a Profiling point.\n * Its lifetime must not span across sessions.\n *\n * @author Tomas Hurka\n * @author Maros Sandor\n */\npublic class RuntimeProfilingPoint implements Comparable {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Encapsulates an event of hitting a profiling point.\n     */\n    public static class HitEvent {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private final int id;\n        private final int threadId;\n        private final long timestamp;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public HitEvent(int id, long timestamp, int threadId) {\n            this.id = id;\n            this.timestamp = timestamp;\n            this.threadId = threadId;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public int getId() {\n            return id;\n        }\n\n        public int getThreadId() {\n            return threadId;\n        }\n\n        public long getTimestamp() {\n            return timestamp;\n        }\n\n        public String toString() {\n            return \"HitEvent [id=\" + getId() + \", thread id=\" + getThreadId() + \", timestamp=\" + getTimestamp() + \"]\"; //NOI18N\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    /**\n     * Name of the class where the profiling point resides in the form: package.Class.Inner\n     */\n    private final String className;\n\n    /**\n     * Name of the method where this profiling point resides. This is mutually exclusive with the line field and means\n     * \"beginning of a method\".\n     */\n    private final String methodName;\n\n    /**\n     * Signature of the method where this profiling point resides. This is mutually exclusive with the line field and\n     * supplements the methodName field. May be null to indicate 'the first method with the given name'.\n     */\n    private final String methodSignature;\n\n    /**\n     * Handler for hit events.\n     */\n    private final String serverHandlerClass;\n\n    /**\n     * Additional arbitrary info send to server\n     */\n    private final String serverInfo;\n\n    /**\n     * ID identifies this profiling point in eventbuffer events.\n     */\n    private final int id;\n\n    /**\n     * Line number where this profiling point resides. This is mutually exclusive with the method field.\n     */\n    private final int line;\n\n    /**\n     * Line offset where this profiling point resides. This is mutually exclusive with the method field.\n     */\n    private final int offset;\n\n    /**\n     * Bytecode index; filled at runtime when the class loads and we inject profile point hit methods.\n     */\n    private int bci;\n\n    /**\n     * Method index; filled at runtime when the class loads and we inject profile point hit methods.\n     */\n    private int methodIdx = -1;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new profiling point.\n     *\n     *\n     *\n     * @param id unique ID of this profiling point\n     * @param className name of the class where this profiling point is placed\n     * @param line profiling point location in the class. If line is positive, it is be inserted just before the line executes.\n     *             If line is negative, it is inserted just after the line executes.\n     * @param offset line offset\n     * @param serverHandlerClass handles hits of this profiling point on server side (fully qualified class name)\n     */\n    public RuntimeProfilingPoint(int id, String className, int line, int offset, String serverHandlerClass, String serverInfo) {\n        this(id, className, line, offset, null, null, serverHandlerClass, serverInfo);\n    }\n\n    /**\n     * Creates a new profiling point.\n     *\n     *\n     *\n     * @param id unique ID of this profiling point\n     * @param className name of the class where this profiling point is placed\n     * @param methodName name of the method where this profiling point is placed\n     * @param methodSignature signature of the method where this profiling point is placed\n     * @param serverHandlerClass handles hits of this profiling point on server side (fully qualified class name)\n     */\n    public RuntimeProfilingPoint(int id, String className, String methodName, String methodSignature, String serverHandlerClass,\n                                 String serverInfo) {\n        this(id, className, -1, -1, methodName, methodSignature, serverHandlerClass, serverInfo);\n    }\n\n    private RuntimeProfilingPoint(int id, String className, int line, int offset, String methodName, String methodSignature,\n                                  String serverHandlerClass, String serverInfo) {\n        this.id = id;\n        this.className = className;\n        this.line = line;\n        this.offset = offset;\n        this.methodName = methodName;\n        this.methodSignature = methodSignature;\n        this.serverHandlerClass = serverHandlerClass;\n        this.serverInfo = serverInfo;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getBci() {\n        return bci;\n    }\n\n    public String getClassName() {\n        return className;\n    }\n\n    public int getId() {\n        return id;\n    }\n\n    public int getMethodIdx() {\n        return methodIdx;\n    }\n\n    public String getServerHandlerClass() {\n        return serverHandlerClass;\n    }\n\n    public String getServerInfo() {\n        return serverInfo;\n    }\n\n    public boolean resolve(ClassRepository repo, ClassInfo classInfo) {\n        if (methodIdx != -1) {\n            return true;\n        }\n\n        return (methodName != null) ? resolveMethodName(classInfo) : resolveLineNumber(repo, classInfo);\n    }\n\n    public String toString() {\n        return \"RuntimeProfilingPoint [id=\" + id + \", classname=\" + className + \", line=\" + line + \", offset=\" + offset\n               + \", server handler=\" + serverHandlerClass + \"]\"; //NOI18N\n    }\n\n    public int compareTo(Object o) {\n        if (!(o instanceof RuntimeProfilingPoint)) return -1;\n        return getId() - ((RuntimeProfilingPoint)o).getId();\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj == null) {\n            return false;\n        }\n        if (getClass() != obj.getClass()) {\n            return false;\n        }\n        final RuntimeProfilingPoint other = (RuntimeProfilingPoint) obj;\n        if (this.id != other.id) {\n            return false;\n        }\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int hash = 7;\n        hash = 23 * hash + this.id;\n        return hash;\n    }\n\n    private boolean resolveLineNumber(ClassRepository repo, ClassInfo classInfo) {\n        try {\n            //      int ln = Math.abs(line);\n            ClassRepository.CodeRegionBCI crbci = repo.getMethodForSourceRegion(classInfo, line, line);\n            methodIdx = classInfo.getMethodIndex(crbci.methodName, crbci.methodSignature);\n            bci = (offset == Integer.MAX_VALUE) ? crbci.bci1 : crbci.bci0;\n\n            return true;\n        } catch (Exception e) {\n            return false;\n        }\n    }\n\n    private boolean resolveMethodName(ClassInfo classInfo) {\n        if (methodSignature != null) {\n            methodIdx = classInfo.getMethodIndex(methodName, methodSignature);\n        } else {\n            String[] allNames = classInfo.getMethodNames();\n\n            for (int i = 0; i < allNames.length; i++) {\n                if (methodName.equals(allNames[i])) {\n                    methodIdx = i;\n\n                    break;\n                }\n            }\n        }\n\n        if (methodIdx == -1) {\n            return false;\n        }\n\n        bci = classInfo.getLineNumberTables().getStartPCs()[methodIdx][0];\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/filters/GenericFilter.java",
    "content": "/*\n * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.filters;\n\nimport java.util.Objects;\nimport java.util.Properties;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class GenericFilter {\n\n    public static final int TYPE_NONE = 0;\n    public static final int TYPE_INCLUSIVE = 10;\n    public static final int TYPE_EXCLUSIVE = 20;\n\n    protected static final int MODE_EQUALS = 1000;\n    protected static final int MODE_CONTAINS = 1010;\n    protected static final int MODE_STARTS_WITH = 1020;\n    protected static final int MODE_ENDS_WITH = 1030;\n\n    private static final String PROP_NAME = \"NAME\"; // NOI18N\n    private static final String PROP_VALUE = \"VALUE\"; // NOI18N\n    private static final String PROP_TYPE = \"TYPE\"; // NOI18N\n\n\n    private String name;\n    private String value;\n    private transient String[] values;\n\n    private int type;\n    private transient int[] modes;\n\n    private Boolean isEmpty;\n    private Boolean isAll;\n\n\n    public GenericFilter() {\n        this(null, \"\", TYPE_NONE); // NOI18N\n    }\n\n    public GenericFilter(GenericFilter other) {\n        this(other.name, other.value, other.values, other.type, other.modes);\n    }\n\n    public GenericFilter(String name, String value, int type) {\n        this(name, value, null, type, null);\n    }\n\n    public GenericFilter(Properties properties, String id) {\n        this(loadName(properties, id), loadValue(properties, id), loadType(properties, id));\n    }\n\n    private GenericFilter(String name, String value, String[] values, int type, int[] modes) {\n        this.name = name;\n        this.value = value;\n        this.values = values; // arrays are shared as long as the instances don't change, array of the changed instance is nulled\n        this.type = type;\n        this.modes = modes; // arrays are shared as long as the instances don't change, array of the changed instance is nulled\n    }\n\n\n    public void copyFrom(GenericFilter other) {\n        name = other.name;\n        value = other.value;\n        values = other.values; // arrays are shared as long as the instances don't change, array of the changed instance is nulled\n        type = other.type;\n        modes = other.modes; // arrays are shared as long as the instances don't change, array of the changed instance is nulled\n        isEmpty = other.isEmpty;\n        isAll = other.isAll;\n    }\n    \n    \n    public final void setName(String name) {\n        this.name = name;\n    }\n    \n    public final String getName() {\n        return name;\n    }\n    \n    public final void setValue(String value) {\n        this.value = value;\n        valueChanged();\n    }\n    \n    protected void valueChanged() {\n        values = null;\n        modes = null;\n        isEmpty = null;\n        isAll = null;\n    }\n    \n    public final String getValue() {\n        return value;\n    }\n\n    public final String[] getValues() {\n        if (values == null) values = computeValues(value);\n        return values;\n    }\n    \n    public final void setType(int type) {\n        this.type = type;\n    }\n    \n    public final int getType() {\n        return type;\n    }\n    \n    public final int[] getModes() {\n        if (modes == null) modes = computeModes(getValues());\n        return modes;\n    }\n    \n    \n    public final boolean isEmpty() {\n        if (isEmpty == null) isEmpty = value.isEmpty();\n        return isEmpty;\n    }\n    \n    public boolean isAll() {\n        if (isAll == null) isAll = isEmpty() || \"*\".equals(value) || \"**\".equals(value); // NOI18N\n        return isAll;\n    }\n\n    \n//    protected String computeValue(String[] values) { return value(values); }\n//    \n//    public static String value(String[] values) {\n//        int length = values.length;\n//\n//        if (length == 0) return \"\"; // NOI18N\n//        if (length == 1) return values[0];\n//\n//        StringBuilder b = new StringBuilder();\n//        for (int i = 0; i < length - 1; i++)\n//            b.append(values[i]).append(\", \"); // NOI18N\n//        b.append(values[values.length - 1]);\n//\n//        return b.toString().trim();\n//    }\n    \n    protected String[] computeValues(String _value) {\n        return values(_value);\n    }\n    \n    public static String[] values(String _value) {\n        return _value.replace(',', ' ').split(\" +\"); // NOI18N\n    }\n    \n    protected int[] computeModes(String[] _values) {\n        int length = _values.length;\n        int[] _modes = new int[length];\n        \n        for (int i = 0; i < length; i++) {\n            String _value = _values[i];\n            int vlength = _value == null ? 0 : _value.length();\n            \n            if (vlength == 0) {\n                _modes[i] = MODE_CONTAINS;\n                continue;\n            }\n            \n            boolean startsWith = _value.charAt(0) == '*'; // NOI18N\n            boolean endsWith = _value.charAt(vlength - 1) == '*'; // NOI18N\n            if (startsWith) _value = _value.substring(1);\n            if (endsWith) _value = _value.substring(0, vlength - (startsWith ? 2 : 1));\n            _values[i] = _value;\n            \n            if (_value.isEmpty()) {\n                _modes[i] = MODE_CONTAINS;\n                continue;\n            }\n            \n            if (startsWith) {\n                if (endsWith) _modes[i] = MODE_CONTAINS;\n                else _modes[i] = MODE_ENDS_WITH;\n            } else if (endsWith) {\n                _modes[i] = MODE_STARTS_WITH;\n            } else {\n                _modes[i] = MODE_EQUALS;\n            }\n        }\n        return _modes;\n    }\n    \n    \n    public boolean passes(String string) {\n        if (simplePasses(string)) return true;\n        \n        boolean inclusive = type == TYPE_INCLUSIVE;\n        \n        String[] _values = getValues();\n        int[] _modes = getModes();\n        for (int i = 0; i < _values.length; i++)\n            if (matches(string, _values[i], _modes[i]))\n                return inclusive;\n        \n        return !inclusive;\n    }\n    \n    protected boolean simplePasses(String string) {\n        if (type == TYPE_NONE) return true;\n        \n        boolean inclusive = type == TYPE_INCLUSIVE;\n        \n        if (isAll()) return inclusive;\n        if (getValues().length == 0) return inclusive;\n        \n        return false;\n    }\n        \n    protected boolean matches(String string, String filter, int mode) {\n        if (filter.isEmpty()) return true;\n        \n        switch (mode) {\n            case MODE_STARTS_WITH:\n                return string.startsWith(filter);\n            case MODE_EQUALS:\n                return string.equals(filter);\n            case MODE_ENDS_WITH:\n                return string.endsWith(filter);\n            case MODE_CONTAINS:\n                return string.contains(filter);\n        }\n        return false;\n    }\n    \n    \n    public boolean equals(Object obj) {\n        if (this == obj) return true;\n        if (obj == null) return false;\n\n        if (!obj.getClass().isAssignableFrom(getClass()) &&\n            !getClass().isAssignableFrom(obj.getClass())) return false;\n\n        return valuesEquals(obj);\n    }\n    \n    protected boolean valuesEquals(Object obj) {\n        GenericFilter other = (GenericFilter)obj;\n        \n        if (!Objects.equals(name, other.name)) return false;\n        if (!value.equals(other.value)) return false;\n        if (type != other.type) return false;\n        \n        return true;\n    }\n    \n    public int hashCode() {\n        return valuesHashCode(3);\n    }\n    \n    protected int valuesHashCode(int hashBase) {\n        if (name != null) hashBase = 67 * hashBase + name.hashCode();\n        hashBase = 67 * hashBase + value.hashCode();\n        hashBase = 67 * hashBase + type;\n        \n        return hashBase;\n    }\n    \n    \n    public String toString() {\n        StringBuilder b = new StringBuilder();\n        \n        b.append(getClass().getName());\n        b.append(\"[\"); // NOI18N\n        b.append(\"name: \").append(getName()); // NOI18N\n        b.append(\", value: \").append(getValue()); // NOI18N\n        b.append(\", type: \").append(typeString(getType())); // NOI18N\n        b.append(\"]\"); // NOI18N\n        \n        return b.toString();\n    }\n    \n    private static String typeString(int type) {\n        switch (type) {\n            case TYPE_NONE: return \"TYPE_NONE\"; // NOI18N\n            case TYPE_INCLUSIVE: return \"TYPE_INCLUSIVE\"; // NOI18N\n            case TYPE_EXCLUSIVE: return \"TYPE_EXCLUSIVE\"; // NOI18N\n            default: return \"unknown\"; // NOI18N\n        }\n    }\n    \n    \n    public void store(Properties properties, String id) {\n        if (name == null) properties.remove(id + PROP_NAME); else properties.put(id + PROP_NAME, name);\n        properties.put(id + PROP_VALUE, value);\n        properties.put(id + PROP_TYPE, Integer.toString(type));\n    }\n    \n    \n    private static String loadName(Properties properties, String id) {\n        return properties.getProperty(id + PROP_NAME);\n    }\n    \n    private static String loadValue(Properties properties, String id) {\n        String _value = properties.getProperty(id + PROP_VALUE);\n        if (_value == null) throw new InvalidFilterIdException(\"No filter value found\", id); // NOI18N\n        return _value;\n    }\n    \n    private static int loadType(Properties properties, String id) {\n        String _type = properties.getProperty(id + PROP_TYPE);\n        if (_type == null) throw new InvalidFilterIdException(\"No filter type found\", id); // NOI18N\n        try { return Integer.parseInt(_type); } catch (NumberFormatException e)\n            { throw new InvalidFilterIdException(\"Bad filter type specified\", id); } // NOI18N\n    }\n    \n    \n    public static final class InvalidFilterIdException extends IllegalArgumentException {\n        \n        public InvalidFilterIdException(String message, String filterId) {\n            super(message + \" for filter id \" + filterId); // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/filters/InstrumentationFilter.java",
    "content": "/*\n * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.filters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class InstrumentationFilter extends JavaTypeFilter {\n\n    private boolean fake;\n\n    public InstrumentationFilter() {\n        super();\n    }\n\n    public InstrumentationFilter(GenericFilter other) {\n        super(other);\n        if (!(other instanceof JavaTypeFilter)) {\n            fake = true;\n        }\n    }\n\n    @Override\n    public boolean passes(String string) {\n        if (fake) return true;\n        return super.passes(string);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/filters/JavaTypeFilter.java",
    "content": "/*\n * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.filters;\n\nimport java.util.Arrays;\nimport java.util.Properties;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JavaTypeFilter extends GenericFilter {\n\n    protected static final int MODE_STARTS_WITH_EX = 1025;\n\n    private transient Boolean isAll;\n    private transient Boolean isExact;\n    private transient Boolean hasArray;\n\n\n    public JavaTypeFilter() {\n        super();\n    }\n\n    public JavaTypeFilter(GenericFilter other) {\n        super(other);\n    }\n\n    public JavaTypeFilter(String value, int type) {\n        super(null, value, type);\n    }\n\n    public JavaTypeFilter(Properties properties, String id) {\n        super(properties, id);\n    }\n\n\n    public void copyFrom(JavaTypeFilter other) {\n        super.copyFrom(other);\n\n        isAll = other.isAll;\n        isExact = other.isExact;\n        hasArray = other.hasArray;\n    }\n\n\n    public final boolean isAll() {\n        if (super.isAll()) return true;\n        if (isAll == null) computeFlags();\n        return isAll;\n    }\n\n    public final boolean isExact() {\n        if (isExact == null) computeFlags();\n        return isExact;\n    }\n\n    private void computeFlags() {\n        for (String value : getValues())\n            if (\"*\".equals(value) || \"**\".equals(value)) // NOI18N\n                { isAll = true; isExact = false; break; }\n            else if (value.charAt(value.length() - 1) == '*') // NOI18N\n                { isExact = false; }\n\n        if (isAll == null) isAll = false;\n        if (isExact == null) isExact = true;\n    }\n\n    public final boolean hasArray() {\n        if (hasArray == null) hasArray = getValue().indexOf('[') > -1; // NOI18N\n        return hasArray;\n    }\n\n\n    protected void valueChanged() {\n        super.valueChanged();\n        isAll = null;\n        isExact = null;\n        hasArray = null;\n    }\n\n    protected String[] computeValues(String value) {\n        return super.computeValues(value.replace('.', '/')); // NOI18N\n    }\n    \n    \n    protected int[] computeModes(String[] values) {\n        int length = values.length;\n        int[] modes = new int[length];\n        \n        Arrays.fill(modes, MODE_EQUALS);\n        \n        for (int i = 0; i < length; i++) {\n            String value = values[i];\n            int vlength = value == null ? 0 : value.length();\n            \n            if (vlength > 0 && '*' == value.charAt(vlength - 1)) { // NOI18N\n                if (vlength > 1 && '*' == value.charAt(vlength - 2)) {\n                    value = value.substring(0, vlength - 2);\n                    modes[i] = MODE_STARTS_WITH;\n                } else {\n                    value = value.substring(0, vlength - 1);\n                    modes[i] = MODE_STARTS_WITH_EX;\n                }\n                values[i] = value;\n            }\n        }\n        \n        return modes;\n    }\n    \n    \n    protected boolean matches(String string, String filter, int mode) {\n        if (filter.isEmpty()) return true;\n        \n        if (mode == MODE_STARTS_WITH_EX) {\n            if (!string.startsWith(filter)) return false;\n            for (int i = filter.length(); i < string.length(); i++)\n                if ('/' == string.charAt(i)) return false; // NOI18N\n            return true;\n        }\n        \n        return super.matches(string, filter, mode);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/filters/TextFilter.java",
    "content": "/*\n * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.filters;\n\nimport java.util.Locale;\nimport java.util.Properties;\nimport java.util.regex.Pattern;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class TextFilter extends GenericFilter {\n\n    public static final int TYPE_REGEXP = 30;\n\n\n    private static final String[] NORMALIZED_NOT_READY = new String[0];\n\n    private String[] normalizedValues = NORMALIZED_NOT_READY;\n    private transient Pattern[] regexpPatterns;\n\n\n    public TextFilter() {\n        super(null, \"\", TYPE_INCLUSIVE); // NOI18N\n    }\n\n    public TextFilter(String value, int type, boolean caseSensitive) {\n        super(null, value, type);\n        setCaseSensitive(caseSensitive);\n    }\n\n    public TextFilter(Properties properties, String id) {\n        super(properties, id);\n    }\n\n\n    public void copyFrom(TextFilter other) {\n        super.copyFrom(other);\n\n        normalizedValues = other.normalizedValues;\n        regexpPatterns = other.regexpPatterns;\n    }\n\n\n    public boolean isAll() {\n//        return getType() == TYPE_REGEXP ? isEmpty() : super.isAll();\n        return isEmpty();\n    }\n\n\n    public final void setCaseSensitive(boolean caseSensitive) {\n//        if (caseSensitive != isCaseSensitive()) setValue(getValue()); // resets precomputed values\n        if (caseSensitive || getType() == TYPE_REGEXP) {\n            normalizedValues = null;\n        } else {\n            normalizedValues = NORMALIZED_NOT_READY;\n        }\n    }\n\n    public final boolean isCaseSensitive() {\n        return normalizedValues == null;\n    }\n\n\n    protected void valueChanged() {\n        super.valueChanged();\n\n        if (!isCaseSensitive()) normalizedValues = NORMALIZED_NOT_READY;\n        regexpPatterns = null;\n    }\n\n//    protected String[] computeValues(String value) {\n//        return getType() == TYPE_REGEXP ? super.computeValues(value) :\n//               super.computeValues(value.replace('*', ' ')); // NOI18N\n//    }\n    \n    \n    public boolean passes(String string) {\n        if (getType() == TYPE_REGEXP) {\n            String[] values = getValues();\n            \n            if (regexpPatterns == null) regexpPatterns = new Pattern[values.length];\n            \n            for (int i = 0; i < regexpPatterns.length; i++) {\n                if (regexpPatterns[i] == null) \n                    try {\n                        regexpPatterns[i] = Pattern.compile(values[i]);\n                    } catch (RuntimeException e) {\n                        handleInvalidFilter(values[i], e);\n                        regexpPatterns[i] = Pattern.compile(\".*\"); // NOI18N\n                    }\n                if (regexpPatterns[i].matcher(string).matches()) return true;\n            }\n            \n            return false;\n        } else {\n//            return super.passes(string);\n            if (simplePasses(string)) return true;\n            \n            String[] values = getValues();\n            \n            boolean caseSensitive = isCaseSensitive();\n            if (!caseSensitive) {\n                string = normalizeString(string);\n                if (normalizedValues == NORMALIZED_NOT_READY) normalizedValues = new String[values.length];\n            }\n            \n            for (int i = 0; i < values.length; i++) {\n                String value;\n                if (!caseSensitive) {\n                    if (normalizedValues[i] == null) normalizedValues[i] = normalizeString(values[i]);\n                    value = normalizedValues[i];\n                } else {\n                    value = values[i];\n                }\n                if (string.contains(value)) return getType() == TYPE_INCLUSIVE;\n            }\n\n            return getType() != TYPE_INCLUSIVE;\n        }\n    }\n    \n    \n    protected void handleInvalidFilter(String invalidValue, RuntimeException e) {}\n    \n    \n    private static String normalizeString(String string) {\n        // NOTE: comparing String.toLowerCase doesn't work correctly for all locales\n        // but is much faster than using String.equalsIgnoreCase or an exact algorithm\n        // for case-insensitive comparison\n        return string.toLowerCase(Locale.ENGLISH);\n    }\n    \n    \n    protected boolean valuesEquals(Object obj) {\n        if (!super.valuesEquals(obj)) return false;\n        \n        TextFilter other = (TextFilter)obj;\n        if (normalizedValues == null) {\n            if (other.normalizedValues != null) return false;\n        } else {\n            if (other.normalizedValues == null) return false;\n        }\n        \n        return true;\n    }\n    \n    protected int valuesHashCode(int hashBase) {\n        hashBase = super.valuesHashCode(hashBase);\n        \n        if (normalizedValues == null) hashBase = 67 * hashBase;\n        \n        return hashBase;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/global/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nCalibrationDataFileIO_CalibrationFileNotExistMsg=Profiler calibration data file does not exist\\:\\n{0}\nCalibrationDataFileIO_CalibrationFileNotReadableMsg=Saved calibration data file\\n{0}\\nexists, but is not readable.\\nPlease make it readable or delete it.\nCalibrationDataFileIO_CalibrationDataCorruptedPrefix=Saved calibration data file is corrupted\\:\nCalibrationDataFileIO_ShorterThanExpectedString=shorter than expected\nCalibrationDataFileIO_OriginalMessageString=Original message\\:\nCalibrationDataFileIO_ReRunCalibrationMsg=Will need to re-run instrumentation calibration.\nCalibrationDataFileIO_ErrorWritingCalibrationFilePrefix=Error writing saved calibration data file\\:\nCalibrationDataFileIO_ReExecuteCalibrationMsg=JFluid will re-execute instrumentation calibration on the next run.\n\nCommonConstants_ThreadStatusUnknownString=Unknown\nCommonConstants_ThreadStatusZombieString=Finished\nCommonConstants_ThreadStatusRunningString=Running\nCommonConstants_ThreadStatusSleepingString=Sleeping\nCommonConstants_ThreadStatusMonitorString=Monitor\nCommonConstants_ThreadStatusWaitString=Wait\nCommonConstants_ThreadStatusParkString=Park\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/global/CalibrationDataFileIO.java",
    "content": "/*\n * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.global;\n\nimport java.io.*;\nimport java.text.MessageFormat;\nimport java.util.ResourceBundle;\n\n\n/**\n * Reading and saving calibration data file.\n *\n * @author  Misha Dmitriev\n */\npublic class CalibrationDataFileIO {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String CALIBRATION_FILE_NOT_EXIST_MSG;\n    private static final String CALIBRATION_FILE_NOT_READABLE_MSG;\n    private static final String CALIBRATION_DATA_CORRUPTED_PREFIX;\n    private static final String SHORTER_THAN_EXPECTED_STRING;\n    private static final String ORIGINAL_MESSAGE_STRING;\n    private static final String RERUN_CALIBRATION_MSG;\n    private static final String ERROR_WRITING_CALIBRATION_FILE_PREFIX;\n    private static final String REEXECUTE_CALIBRATION_MSG;\n                                                                                                                                 // -----\n    private static String errorMessage;\n\n    static {\n        ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.global.Bundle\"); // NOI18N\n        CALIBRATION_FILE_NOT_EXIST_MSG = messages.getString(\"CalibrationDataFileIO_CalibrationFileNotExistMsg\"); // NOI18N\n        CALIBRATION_FILE_NOT_READABLE_MSG = messages.getString(\"CalibrationDataFileIO_CalibrationFileNotReadableMsg\"); // NOI18N\n        CALIBRATION_DATA_CORRUPTED_PREFIX = messages.getString(\"CalibrationDataFileIO_CalibrationDataCorruptedPrefix\"); // NOI18N\n        SHORTER_THAN_EXPECTED_STRING = messages.getString(\"CalibrationDataFileIO_ShorterThanExpectedString\"); // NOI18N\n        ORIGINAL_MESSAGE_STRING = messages.getString(\"CalibrationDataFileIO_OriginalMessageString\"); // NOI18N\n        RERUN_CALIBRATION_MSG = messages.getString(\"CalibrationDataFileIO_ReRunCalibrationMsg\"); // NOI18N\n        ERROR_WRITING_CALIBRATION_FILE_PREFIX = messages.getString(\"CalibrationDataFileIO_ErrorWritingCalibrationFilePrefix\"); // NOI18N\n        REEXECUTE_CALIBRATION_MSG = messages.getString(\"CalibrationDataFileIO_ReExecuteCalibrationMsg\"); // NOI18N\n    }\n    \n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static String getErrorMessage() {\n        String res = errorMessage;\n        errorMessage = null;\n\n        return res;\n    }\n\n    /**\n     * Reads the saved calibration data file.\n     * Returns -1 in case of a fatal error (cannot read the calibration file), -2 if file exists but data is corrupted,\n     * 1 if file does not exist, and 0 if file has been read successfully.\n     */\n    public static int readSavedCalibrationData(ProfilingSessionStatus status) {\n        String fn = null;\n\n        try {\n            fn = getCalibrationDataFileName(status.targetJDKVersionString);\n        } catch (IOException e) {\n            errorMessage = e.getMessage();\n\n            return -1;\n        }\n\n        File savedDataFile = new File(fn);\n\n        if (!savedDataFile.exists()) {\n            errorMessage = MessageFormat.format(CALIBRATION_FILE_NOT_EXIST_MSG, new Object[] { savedDataFile.toString() });\n\n            return 1;\n        }\n\n        if (!savedDataFile.canRead()) {\n            errorMessage = MessageFormat.format(CALIBRATION_FILE_NOT_READABLE_MSG, new Object[] { savedDataFile.toString() });\n\n            return -1;\n        }\n\n        FileInputStream fiStream = null;\n        try {\n            fiStream = new FileInputStream(savedDataFile);\n            ObjectInputStream oiStream = new ObjectInputStream(fiStream);\n\n            status.methodEntryExitCallTime = (double[]) oiStream.readObject();\n            status.methodEntryExitInnerTime = (double[]) oiStream.readObject();\n            status.methodEntryExitOuterTime = (double[]) oiStream.readObject();\n            status.timerCountsInSecond = (long[]) oiStream.readObject();\n\n            fiStream.close();\n        } catch (Exception e) {\n            errorMessage = e.getMessage();\n            String prefix = CALIBRATION_DATA_CORRUPTED_PREFIX;\n\n            if (errorMessage == null) {\n                if (e instanceof java.io.EOFException) {\n                    errorMessage = prefix + \" \" + SHORTER_THAN_EXPECTED_STRING; // NOI18N\n                }\n            } else {\n                errorMessage = prefix + \"\\n\" + ORIGINAL_MESSAGE_STRING + \" \" + errorMessage; // NOI18N\n            }\n\n            errorMessage += (\"\\n\" + RERUN_CALIBRATION_MSG + \"\\n\"); // NOI18N\n\n            return -2;\n        } finally {\n            if (fiStream != null) {\n                try {\n                    fiStream.close();\n                } catch (IOException e) {}\n            }\n        }\n\n        return 0;\n    }\n\n    public static boolean saveCalibrationData(ProfilingSessionStatus status) {\n        try {\n            FileOutputStream foStream = new FileOutputStream(getCalibrationDataFileName(status.targetJDKVersionString));\n            ObjectOutputStream ooStream = new ObjectOutputStream(foStream);\n\n            ooStream.writeObject(status.methodEntryExitCallTime);\n            ooStream.writeObject(status.methodEntryExitInnerTime);\n            ooStream.writeObject(status.methodEntryExitOuterTime);\n            ooStream.writeObject(status.timerCountsInSecond);\n\n            foStream.close();\n        } catch (IOException e) {\n            errorMessage = e.getMessage();\n            String prefix = ERROR_WRITING_CALIBRATION_FILE_PREFIX;\n            errorMessage = prefix + \"\\n\" + ORIGINAL_MESSAGE_STRING + \"\\n\" + errorMessage; // NOI18N\n                                                                                          // status.remoteProfiling below means that we actually perform off-line calibration on the remote target machine.\n                                                                                          // In that case, the message that follows, which is meaningful in case of local machine calibration, doesn't make sense.\n\n            if (!status.remoteProfiling) {\n                errorMessage += (\"\\n\" + REEXECUTE_CALIBRATION_MSG + \"\\n\"); // NOI18N\n            }\n\n            return false;\n        }\n\n        return true;\n    }\n\n    public static boolean validateCalibrationInput(String javaVersionString, String javaExecutable) {\n        if ((javaVersionString != null) && (javaExecutable != null)) {\n            if (!CommonConstants.JDK_UNSUPPORTED_STRING.equals(javaVersionString)\n                   && !CommonConstants.JDK_CVM_STRING.equals(javaVersionString)) {\n                if (new File(javaExecutable).exists()) {\n                    return true;\n                }\n            }\n        }\n\n        return false;\n    }\n\n    public static String getCalibrationDataFileName(String targetJDKVerString)\n                                              throws IOException {\n        String fileName = \"machinedata\" + \".\" + targetJDKVerString; // NOI18N\n\n        return Platform.getProfilerUserDir() + File.separator + fileName;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/global/CommonConstants.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.global;\n\nimport java.awt.Color;\nimport java.util.ResourceBundle;\n\n\n/**\n * Various Profiler engine-internal constants used in various parts of the system.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic interface CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    public static final String THREAD_STATUS_UNKNOWN_STRING = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.global.Bundle\").getString(\"CommonConstants_ThreadStatusUnknownString\"); // NOI18N  // TODO CHECK: unused method\n    public static final String THREAD_STATUS_ZOMBIE_STRING = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.global.Bundle\").getString(\"CommonConstants_ThreadStatusZombieString\"); // NOI18N\n    public static final String THREAD_STATUS_RUNNING_STRING = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.global.Bundle\").getString(\"CommonConstants_ThreadStatusRunningString\"); // NOI18N\n    public static final String THREAD_STATUS_SLEEPING_STRING = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.global.Bundle\").getString(\"CommonConstants_ThreadStatusSleepingString\"); // NOI18N;\n    public static final String THREAD_STATUS_MONITOR_STRING = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.global.Bundle\").getString(\"CommonConstants_ThreadStatusMonitorString\"); // NOI18N\n    public static final String THREAD_STATUS_WAIT_STRING = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.global.Bundle\").getString(\"CommonConstants_ThreadStatusWaitString\"); // NOI18N\n    public static final String THREAD_STATUS_PARK_STRING = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.global.Bundle\").getString(\"CommonConstants_ThreadStatusParkString\"); // NOI18N\n                                                                                        // -----\n\n    /** Names of our own classes, in various forms */\n    public static final String PROFILER_SERVER_SLASHED_CLASS_PREFIX = \"org/graalvm/visualvm/lib/jfluid/server/\"; // NOI18N\n    public static final String PROFILER_DOTTED_CLASS_PREFIX = \"org.graalvm.visualvm.lib.jfluid.\"; // NOI18N\n\n    // State of the profiler server\n    public static final int SERVER_RUNNING = 0;\n    public static final int SERVER_INITIALIZING = 1;\n    public static final int SERVER_PREPARING = 2;\n    public static final int SERVER_INSTRUMENTING = 3;\n\n    // Server progress constants\n    public static final int SERVER_PROGRESS_INDETERMINATE = -1;\n    public static final int SERVER_PROGRESS_WORKUNITS = 100;\n\n    // Agent state\n    public static final int AGENT_STATE_NOT_RUNNING = 0;\n    public static final int AGENT_STATE_READY_DYNAMIC = 1;\n    public static final int AGENT_STATE_READY_DIRECT = 2;\n    public static final int AGENT_STATE_CONNECTED = 3;\n    public static final int AGENT_STATE_DIFFERENT_ID = 4;\n    public static final int AGENT_STATE_OTHER_SESSION_IN_PROGRESS = 5;\n\n    // Agent Id\n    public static final int AGENT_ID_ANY = -1;\n\n    /** Numeric JDK versions that we currently distinguish between */\n    public static final int JDK_15 = 2;\n    public static final int JDK_16 = 3; // we treat JDK 1.5 the same as Tiger for now\n    public static final int JDK_17 = 4; // we treat JDK 17 the same as JDK 1.5 for now\n    public static final int JDK_18 = 6;\n    public static final int JDK_19 = 7;\n    public static final int JDK_100 = 8;\n    public static final int JDK_110 = 9;\n    public static final int JDK_120 = 10;\n    public static final int JDK_130 = 11;\n    public static final int JDK_140 = 12;\n    public static final int JDK_150 = 13;\n    public static final int JDK_160 = 14;\n    public static final int JDK_170 = 15;\n    public static final int JDK_180 = 16;\n    public static final int JDK_190 = 17;\n    public static final int JDK_200 = 18;\n    public static final int JDK_210 = 19;\n    public static final int JDK_220 = 20;\n    public static final int JDK_230 = 21;\n    public static final int JDK_240 = 22;\n    public static final int JDK_250 = 23;\n    public static final int JDK_CVM = 5;\n    public static final int JDK_UNSUPPORTED = -1;\n\n    /** Denoting strings for JDK versions that we currently distinguish between */\n    public static final String JDK_15_STRING = \"jdk15\"; // NOI18N\n    public static final String JDK_16_STRING = \"jdk16\"; // NOI18N\n    public static final String JDK_17_STRING = \"jdk17\"; // NOI18N\n    public static final String JDK_18_STRING = \"jdk18\"; // NOI18N\n    public static final String JDK_19_STRING = \"jdk19\"; // NOI18N\n    public static final String JDK_100_STRING = \"jdk100\"; // NOI18N\n    public static final String JDK_110_STRING = \"jdk110\"; // NOI18N\n    public static final String JDK_120_STRING = \"jdk120\"; // NOI18N\n    public static final String JDK_130_STRING = \"jdk130\"; // NOI18N\n    public static final String JDK_140_STRING = \"jdk140\"; // NOI18N\n    public static final String JDK_150_STRING = \"jdk150\"; // NOI18N\n    public static final String JDK_160_STRING = \"jdk160\"; // NOI18N\n    public static final String JDK_170_STRING = \"jdk170\"; // NOI18N\n    public static final String JDK_180_STRING = \"jdk180\"; // NOI18N\n    public static final String JDK_190_STRING = \"jdk190\"; // NOI18N\n    public static final String JDK_200_STRING = \"jdk200\"; // NOI18N\n    public static final String JDK_210_STRING = \"jdk210\"; // NOI18N\n    public static final String JDK_220_STRING = \"jdk220\"; // NOI18N\n    public static final String JDK_230_STRING = \"jdk230\"; // NOI18N\n    public static final String JDK_240_STRING = \"jdk240\"; // NOI18N\n    public static final String JDK_250_STRING = \"jdk250\"; // NOI18N\n    public static final String JDK_CVM_STRING = \"cvm\";  // NOI18N\n    public static final String JDK_UNSUPPORTED_STRING = \"UNSUPPORTED_JDK\"; // NOI18N\n\n    /** Constants for determining 32/64bit architecture */\n    public static final int ARCH_32 = 32;\n    public static final int ARCH_64 = 64;\n\n    /** Size of the event buffer, used to store/read rough profiling data */\n    public static final int EVENT_BUFFER_SIZE_IN_BYTES = 1200000;\n    /** Default for max string size (in chars) sent as value of parameter from TA */\n    public static final int MAX_STRING_LENGTH_DEFAULT = 1024;\n    /** Max limit for MAX_STRING_LENGTH_DEFAULT */\n    public static final int MAX_STRING_LENGTH_TOP_LIMIT = 4200;\n\n    // Codes of various profiling events, that are generated and stored in the buffer file by server and\n    // then retrieved by tool\n    public static final byte ROOT_ENTRY = 1;\n    public static final byte ROOT_EXIT = 2;\n    public static final byte MARKER_ENTRY = 3;\n    public static final byte MARKER_EXIT = 4;\n    public static final byte ADJUST_TIME = 5;\n    public static final byte METHOD_ENTRY = 6;\n    public static final byte METHOD_EXIT = 7;\n    public static final byte THREADS_SUSPENDED = 8;\n    public static final byte THREADS_RESUMED = 9;\n    public static final byte RESET_COLLECTORS = 10;\n    public static final byte NEW_THREAD = 11;\n    public static final byte OBJ_ALLOC_STACK_TRACE = 12;\n    public static final byte SET_FOLLOWING_EVENTS_THREAD = 13;\n    public static final byte OBJ_LIVENESS_STACK_TRACE = 14;\n    public static final byte OBJ_GC_HAPPENED = 15;\n\n    // These are used by hybrid (instrumentation-sampling) CPU profiling\n    public static final byte METHOD_ENTRY_UNSTAMPED = 16;\n    public static final byte METHOD_EXIT_UNSTAMPED = 17;\n    public static final byte MARKER_ENTRY_UNSTAMPED = 18;\n    public static final byte MARKER_EXIT_UNSTAMPED = 19;\n    \n    // locks/wait monitoring\n    public static final byte METHOD_ENTRY_WAIT = 20;\n    public static final byte METHOD_EXIT_WAIT = 21;\n    public static final byte METHOD_ENTRY_MONITOR = 22;\n    public static final byte METHOD_EXIT_MONITOR = 23;\n    public static final byte METHOD_ENTRY_SLEEP = 24;\n    public static final byte METHOD_EXIT_SLEEP = 25;\n    public static final byte METHOD_ENTRY_PARK = 26;\n    public static final byte METHOD_EXIT_PARK = 27;\n    public static final byte NEW_MONITOR = 28;\n    \n    public static final byte BUFFEREVENT_PROFILEPOINT_HIT = 29;\n    public static final byte SERVLET_DO_METHOD = 30;\n    public static final byte THREAD_DUMP_START = 31;\n    public static final byte THREAD_DUMP_END = 32;\n    public static final byte THREAD_INFO_IDENTICAL = 33;\n    public static final byte THREAD_INFO = 34;\n    public static final byte MARKER_ENTRY_PARAMETERS = 35;\n\n    // The following are used when storing unstamped method entry/exit events in the \"compact\" format, when both\n    // event code and method id are packed in a single char. See more comments in ProfilerRuntimeCPUSampledInstr.java\n    public static final char MAX_METHOD_ID_FOR_COMPACT_FORMAT = 0x3FFF;\n    public static final byte COMPACT_EVENT_FORMAT_BYTE_MASK = (byte) 0x80;\n    public static final char METHOD_ENTRY_COMPACT_MASK = 0x8000;\n    public static final byte METHOD_ENTRY_COMPACT_BYTE_MASK = (byte) 0x80;\n    public static final char METHOD_EXIT_COMPACT_MASK = 0xC000;\n    public static final byte METHOD_EXIT_COMPACT_BYTE_MASK = (byte) 0xC0;\n    public static final char COMPACT_EVENT_METHOD_ID_MASK = 0x3FFF;\n\n    // Target app instrumentation types\n    public static final int INSTR_NONE = 0; // no instrumentation performed => no profiling data\n    public static final int INSTR_CODE_REGION = 1; // instrument code region for CPU data\n    public static final int INSTR_NONE_SAMPLING = 2; // no instrumentation performed, CPU sampling will be used\n    public static final int INSTR_RECURSIVE_FULL = 3; // instrument for CPU data, full instrumentation (timestamps for each method entry/exit)\n    public static final int INSTR_RECURSIVE_SAMPLED = 4; // instrument for CPU data, sampled data obtained (timestamps at periodic intervals only)\n    public static final int INSTR_OBJECT_ALLOCATIONS = 5; // instrument for Memory data, allocations only\n    public static final int INSTR_OBJECT_LIVENESS = 6; // instrument for Memory data, complete\n    public static final int INSTR_NONE_MEMORY_SAMPLING = 7; // no instrumentation performed, Memory sampling will be used (live instances at periodic intervals only)\n                                                       // These are just helpful constants, not actual instrumentation types\n    public static final int INSTR_MEMORY_BASE = 5;\n    public static final int INSTR_MAXNUMBER = 7;\n\n    // Constants used to distinguish between \"full\" and \"sampled\" CPU instrumentation in the settings.\n    // Internally they are translated into INSTR_RECURSIVE and INSTR_RECURSIVE_SAMPLED, respectively\n    // CPU_SAMPLED is used for pure sampling without instrumentation, internally CPU_SAMPLED is \n    // translated to INSTR_NONE_SAMPLING\n    public static final int CPU_INSTR_FULL = 0;\n    public static final int CPU_INSTR_SAMPLED = 1;\n    public static final int CPU_SAMPLED = 2;\n\n    // Target app instrumentation schemes for CPU profiling\n    public static final int INSTRSCHEME_LAZY = 1; // Lazy scheme (B in the NB Profiler papers/report)\n    public static final int INSTRSCHEME_EAGER = 2; // Eager scheme (A in the above report)\n    public static final int INSTRSCHEME_TOTAL = 3; // Total instrumentation\n\n    // Names of special Java threads created by NB Profiler\n    public static final String PROFILER_SERVER_THREAD_NAME = \"*** Profiler Agent Communication Thread\"; // NOI18N\n    public static final String PROFILER_SPECIAL_EXEC_THREAD_NAME = \"*** Profiler Agent Special Execution Thread\"; // NOI18N\n    public static final String PROFILER_SEPARATE_EXEC_THREAD_NAME = \"*** JFluid Separate Command Execution Thread\"; // NOI18N\n\n    // Calibration-only run pseudo main class name\n    public static final String CALIBRATION_PSEUDO_CLASS_NAME = \"____Profiler+Calibration+Run____\"; // NOI18N\n\n    // These are used to signal to server that there is no defined root class/method to instrument. Instead, we instrument\n    // run() methods of all threads spawned after instrumentation command is received.\n    public static final String NO_CLASS_NAME = \"*NO_CLASS_NAME*\"; // NOI18N\n    public static final String NO_METHOD_NAME = \"*NO_METHOD_NAME*\"; // NOI18N\n    public static final String NO_METHOD_SIGNATURE = \"*NO_METHOD_SIGNATURE*\"; // NOI18N\n\n    // Stuff used by various instrumentation-related classes\n    static final String JAVA_LANG_REFLECT_METHOD_DOTTED_CLASS_NAME = \"java.lang.reflect.Method\"; // NOI18N\n    static final String JAVA_LANG_REFLECT_METHOD_SLASHED_CLASS_NAME = \"java/lang/reflect/Method\"; // NOI18N\n    static final String INVOKE_METHOD_NAME = \"invoke\"; // NOI18N\n    static final String INVOKE_METHOD_SIGNATURE = \"(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;\"; // NOI18N\n    static final String OBJECT_SLASHED_CLASS_NAME = \"java/lang/Object\";\n\n    // Kinds of injections that we make into TA methods\n    public static final int INJ_RECURSIVE_NORMAL_METHOD = 0;\n    public static final int INJ_RECURSIVE_ROOT_METHOD = 1;\n    public static final int INJ_RECURSIVE_MARKER_METHOD = 2;\n    public static final int INJ_RECURSIVE_SAMPLED_NORMAL_METHOD = 3;\n    public static final int INJ_RECURSIVE_SAMPLED_ROOT_METHOD = 4;\n    public static final int INJ_RECURSIVE_SAMPLED_MARKER_METHOD = 5;\n    public static final int INJ_REFLECT_METHOD_INVOKE = 6;\n    public static final int INJ_SERVLET_DO_METHOD = 7;\n    public static final int INJ_CODE_REGION = 8;\n    public static final int INJ_OBJECT_ALLOCATIONS = 9;\n    public static final int INJ_OBJECT_LIVENESS = 10;\n    public static final int INJ_STACKMAP = 11;\n    public static final int INJ_THROWABLE = 12;\n    public static final int INJ_MAXNUMBER = 13;\n\n    // Thread state constants. We currently use what is provided in JVMDI, and will probably have to change that once\n    // we switch to JVMTI in JDK 5.0\n    public static final byte THREAD_STATUS_UNKNOWN = -1; // Thread status is unknown.\n    public static final byte THREAD_STATUS_ZOMBIE = 0; // Thread is waiting to die. Also used for \"doesn't exist yet\" and \"dead\"\n    public static final byte THREAD_STATUS_RUNNING = 1; // Thread is runnable. Note that we unfortunately don't know whether it is\n                                                        // actually running or pre-empted by another thread...\n    public static final byte THREAD_STATUS_SLEEPING = 2; // Thread is sleeping - Thread.sleep() or JVM_Sleep() was called\n    public static final byte THREAD_STATUS_MONITOR = 3; // Thread is waiting on a java monitor\n    public static final byte THREAD_STATUS_WAIT = 4; // Thread is waiting - Object.wait() or JVM_MonitorWait() was called\n    public static final byte THREAD_STATUS_PARK = 5; // Thread is parked - sun/misc/Unsafe.park() was called\n\n    // Thread state color constants.\n\n    /** Thread status is unknown. */\n    public static final java.awt.Color THREAD_STATUS_UNKNOWN_COLOR = null;\n\n    /** Thread is waiting to die. Also used for \"doesn't exist yet\" and \"dead\" */\n    public static final java.awt.Color THREAD_STATUS_ZOMBIE_COLOR = null;\n\n    /** Thread is runnable. Note that we unfortunately don't know whether it's actually running or\n     * pre-empted by another thread...*/\n    public static final java.awt.Color THREAD_STATUS_RUNNING_COLOR = Color.getColor(\"org.graalvm.visualvm.ThreadColorRunning\", new java.awt.Color(58, 228, 103)); // NOI18N\n\n    /** Thread is sleeping - Thread.sleep() or JVM_Sleep() was called */\n    public static final java.awt.Color THREAD_STATUS_SLEEPING_COLOR = Color.getColor(\"org.graalvm.visualvm.ThreadColorSleeping\", new java.awt.Color(155, 134, 221)); // NOI18N\n\n    /** Thread is waiting on a java monitor */\n    public static final java.awt.Color THREAD_STATUS_MONITOR_COLOR = Color.getColor(\"org.graalvm.visualvm.ThreadColorMonitor\", new java.awt.Color(160, 240, 238)); // NOI18N\n\n    /** Thread is waiting - Object.wait() or JVM_MonitorWait() was called */\n    public static final java.awt.Color THREAD_STATUS_WAIT_COLOR = Color.getColor(\"org.graalvm.visualvm.ThreadColorWait\", new java.awt.Color(255, 228, 90)); // NOI18N\n\n    /** Thread is parked - sun/misc/Unsafe.park() was called */\n    public static final java.awt.Color THREAD_STATUS_PARK_COLOR = Color.getColor(\"org.graalvm.visualvm.ThreadColorPark\", new java.awt.Color(230, 128, 30)); // NOI18N\n\n    // Thread state description constants.\n    // see I18N String constants at the top of this file\n\n    // Modes for obtaining Thread states data\n    public static final int MODE_THREADS_NONE = 0;\n    public static final int MODE_THREADS_SAMPLING = 1;\n    public static final int MODE_THREADS_EXACT = 2;\n    \n    // Constants for results filter types\n    public static final int FILTER_NONE = 0;\n    public static final int FILTER_STARTS_WITH = 10;\n    public static final int FILTER_CONTAINS = 20;\n    public static final int FILTER_NOT_CONTAINS = 25;\n    public static final int FILTER_ENDS_WITH = 30;\n    public static final int FILTER_EQUALS = 40;\n    public static final int FILTER_REGEXP = 50;\n\n    // Default sorting column constant, means that target component decides itself which column will be used for sorting\n    public static final int SORTING_COLUMN_DEFAULT = -1;\n\n    // Miscellaneous\n    public static final String ENGINE_WARNING = \"*** Profiler engine warning: \"; // NOI18N\n    public static final String PLEASE_REPORT_PROBLEM = \"*** Please report this problem to feedback@profiler.netbeans.org\"; // NOI18N\n\n    // Agent versioning\n    public static final int AGENT_VERSION_10_M9 = 1;\n    public static final int AGENT_VERSION_10_M10 = 2;\n    public static final int AGENT_VERSION_60_M5 = 3;\n    public static final int AGENT_VERSION_60_M6 = 4;\n    public static final int AGENT_VERSION_60_M7 = 5;\n    public static final int AGENT_VERSION_60_M8 = 6;\n    public static final int AGENT_VERSION_60_M10 = 7;\n    public static final int AGENT_VERSION_60_BETA1 = 8;\n    public static final int AGENT_VERSION_67_BETA = 9;\n    public static final int AGENT_VERSION_69 = 10;\n    public static final int AGENT_VERSION_610_M2 = 11;\n    public static final int AGENT_VERSION_71 = 12;\n    public static final int AGENT_VERSION_73 = 13;\n    public static final int AGENT_VERSION_74 = 14;\n    public static final int AGENT_VERSION_80 = 15;\n    public static final int AGENT_VERSION_81 = 16;\n    public static final int AGENT_VERSION_82 = 17;\n    public static final int AGENT_VERSION_90 = 18;\n    public static final int AGENT_VERSION_VISUALVM_20 = 19;\n    public static final int AGENT_VERSION_VISUALVM_206 = 20;\n    public static final int AGENT_VERSION_VISUALVM_218 = 21;\n    public static final int CURRENT_AGENT_VERSION = AGENT_VERSION_VISUALVM_218;\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/global/Platform.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.global;\n\nimport java.io.File;\nimport java.io.IOException;\n\n\n/**\n * Determination of the current platform (OS, hardware) and related services.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class Platform implements CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    /**\n     * Operating system is Windows NT.\n     */\n    public static final int OS_WINNT = 1;\n\n    /**\n     * Operating system is Windows 95.\n     */\n    public static final int OS_WIN95 = 2;\n\n    /**\n     * Operating system is Windows 98.\n     */\n    public static final int OS_WIN98 = 4;\n\n    /**\n     * Operating system is Solaris.\n     */\n    public static final int OS_SOLARIS = 8;\n\n    /**\n     * Operating system is Linux.\n     */\n    public static final int OS_LINUX = 16;\n\n    /**\n     * Operating system is IBM AIX.\n     */\n    public static final int OS_AIX = 64;\n\n    /**\n     * Operating system is SGI IRIX.\n     */\n    public static final int OS_IRIX = 128;\n\n    /**\n     * Operating system is Sun OS.\n     */\n    public static final int OS_SUNOS = 256;\n\n    /**\n     * Operating system is Compaq TRU64 Unix\n     */\n    public static final int OS_TRU64 = 512;\n\n    /**\n     * Operating system is OS/2.\n     */\n    public static final int OS_OS2 = 1024;\n\n    /**\n     * Operating system is Mac.\n     */\n    public static final int OS_MAC = 2048;\n\n    /**\n     * Operating system is Windows 2000.\n     */\n    public static final int OS_WIN2000 = 4096;\n\n    /**\n     * Operating system is Compaq OpenVMS\n     */\n    public static final int OS_VMS = 8192;\n\n    /**\n     * Operating system is one of the Windows variants but we don't know which one it is\n     */\n    public static final int OS_WIN_OTHER = 16384;\n\n    /**\n     * Operating system is unknown.\n     */\n    public static final int OS_OTHER = 65536;\n\n    /**\n     * A mask for Windows platforms.\n     */\n    public static final int OS_WINDOWS_MASK = OS_WINNT | OS_WIN95 | OS_WIN98 | OS_WIN2000 | OS_WIN_OTHER;\n\n    /**\n     * A mask for Unix platforms.\n     */\n    public static final int OS_UNIX_MASK = OS_SOLARIS | OS_LINUX | OS_AIX | OS_IRIX | OS_SUNOS | OS_TRU64 | OS_MAC;\n\n    /**\n     * The operating system on which the tool runs\n     */\n    private static int operatingSystem = -1;\n    private static String jdkDenoteString;\n    private static int jdkVersion;\n    private static int sysArch; // 32/64bit architecture\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Given the name of the directory containing the JFluid native libraries (either just the root JFluid libs dir,\n     * or really the full path, depending on fullPathToLibSpecified parameter), return the full platform-dependent\n     * name for the \"profilerinterface\" library contained in that directory. If non-null jdkString is specified, it\n     * is used in the resulting path; otherwise the VM is queried for its version and the resulting string is used.\n     *\n     * @param fullAgentPath          The path to the library\n     * @param fullPathToLibSpecified whether or not a full path is specified (ending at the platform level)\n     * @param jdkString              CommonConstants.JDK_15_STRING\n     * @return A path to the native library to be used for this platform\n     */\n    public static String getAgentNativeLibFullName(String fullAgentPath, boolean fullPathToLibSpecified, String jdkString,\n                                                   int architecture) {\n        boolean is64bitArch;\n\n        if (jdkString == null) {\n            jdkString = getJDKVersionString();\n        }\n\n        if (architecture == -1) {\n            architecture = getSystemArchitecture();\n        }\n\n        is64bitArch = architecture == ARCH_64;\n\n        if (!jdkString.equals(JDK_15_STRING) && !jdkString.equals(JDK_CVM_STRING)\n            && !jdkString.equals(JDK_UNSUPPORTED_STRING)) {\n            // for now, we use the same libs for 1.6 and 1.7 and 1.8 and 1.9 and 10+\n            jdkString = JDK_16_STRING;\n        }\n\n        String libPrefix = \"\"; // NOI18N\n\n        if (!isWindows()) { // Mac and UNIXes\n            libPrefix = \"lib\"; // NOI18N\n        }\n\n        String libSuffix = \"\"; // NOI18N\n\n        if (isWindows()) {\n            libSuffix = \".dll\"; // Windows // NOI18N\n        } else if (isMac()) {\n            libSuffix = \".jnilib\"; // Mac // NOI18N\n        } else {\n            libSuffix = \".so\"; // UNIXes // NOI18N\n        }\n\n        String libSubPath = \"/\"; // NOI18N\n\n        if (!fullPathToLibSpecified) {\n            String libSubDir;\n            if (isWindows()) {\n               libSubDir = \"windows\"; // NOI18N\n            } else if (isMac()) {\n               libSubDir = \"mac\";\n            } else if (isLinux()) {\n               libSubDir = \"linux\"; // NOI18N\n            } else {\n               libSubDir = \"solaris\"; // NOI18N\n            }\n            String procArch = null;\n\n            if (is64bitArch) {\n                if (isLinuxIntel() || isWindows() || isSolarisIntel()) {\n                    procArch = \"amd64\"; // NOI18N\n                } else if (isSolarisSparc()) {\n                    procArch = \"sparcv9\"; // NOI18N\n                } else if (isLinuxAarch64()) {\n                    procArch = \"aarch64\"; // NOI18N\n                }\n            } else { // 32bit\n\n                if (isSolarisIntel()) {\n                    procArch = \"i386\"; // NOI18N\n                } else if (isSolarisSparc()) {\n                    procArch = \"sparc\"; // NOI18N\n                } else if (isLinuxArm()) {\n                    if (isLinuxArmVfpHflt()) {\n                        procArch = \"arm-vfp-hflt\"; // NOI18N\n                    } else {\n                        procArch = \"arm\"; // NOI18N\n                    }\n                }\n            }\n\n            if (procArch != null) {\n                libSubDir += (\"-\" + procArch);\n            }\n\n            libSubPath = \"/deployed/\" + jdkString + \"/\" + libSubDir + \"/\"; // NOI18N\n        }\n\n        String fullPath = fullAgentPath;\n\n        if (fullAgentPath.startsWith(\"\\\"\")) { // NOI18N\n            fullPath = fullAgentPath.substring(1, fullAgentPath.length() - 1);\n        }\n\n        fullPath = fullPath.replace('\\\\', '/'); // NOI18N\n\n        return fullPath + libSubPath + libPrefix + \"profilerinterface\" + libSuffix; // NOI18N\n    }\n\n    /**\n     * Returns JDK minor version\n     */\n    public static int getJDKMinorNumber(String jdkVersionString) {\n        if (jdkVersionString == null) {\n            return 0;\n        }\n\n        int minorIndex = jdkVersionString.lastIndexOf('_'); // NOI18N\n\n        if ((minorIndex > 0) && (minorIndex < (jdkVersionString.length() - 1))) {\n            String minorString = jdkVersionString.substring(minorIndex + 1);\n            int subverIndex = minorString.indexOf('-'); // NOI18N\n\n            if (subverIndex != -1) {\n                minorString = minorString.substring(0, subverIndex);\n            }\n\n            return Integer.parseInt(minorString);\n        }\n\n        return 0;\n    }\n    \n    /**\n     * Returns the JFluid-internal JDK version number\n     */\n    public static int getJDKVersionNumber(String javaVersion) {\n        int jdkVersion;\n\n        if (javaVersion.startsWith(\"1.5\")) { // NOI18N\n            jdkVersion = JDK_15;\n        } else if (javaVersion.startsWith(\"1.6\")) { // NOI18N\n            jdkVersion = JDK_16;\n        } else if (javaVersion.startsWith(\"1.7\")) { // NOI18N\n            jdkVersion = JDK_17;\n        } else if (javaVersion.startsWith(\"1.8\")) { // NOI18N\n            jdkVersion = JDK_18;\n        } else if (javaVersion.startsWith(\"1.9\")) { // NOI18N\n            jdkVersion = JDK_19;\n        } else if (isJavaVersion(javaVersion,\"9\")) { // NOI18N\n            jdkVersion = JDK_19;\n        } else if (isJavaVersion(javaVersion,\"10\")) { // NOI18N\n            jdkVersion = JDK_100;\n        } else if (isJavaVersion(javaVersion,\"11\")) { // NOI18N\n            jdkVersion = JDK_110;\n        } else if (isJavaVersion(javaVersion,\"12\")) { // NOI18N\n            jdkVersion = JDK_120;\n        } else if (isJavaVersion(javaVersion,\"13\")) { // NOI18N\n            jdkVersion = JDK_130;\n        } else if (isJavaVersion(javaVersion,\"14\")) { // NOI18N\n            jdkVersion = JDK_140;\n        } else if (isJavaVersion(javaVersion,\"15\")) { // NOI18N\n            jdkVersion = JDK_150;\n        } else if (isJavaVersion(javaVersion,\"16\")) { // NOI18N\n            jdkVersion = JDK_160;\n        } else if (isJavaVersion(javaVersion,\"17\")) { // NOI18N\n            jdkVersion = JDK_170;\n        } else if (isJavaVersion(javaVersion,\"18\")) { // NOI18N\n            jdkVersion = JDK_180;\n        } else if (isJavaVersion(javaVersion,\"19\")) { // NOI18N\n            jdkVersion = JDK_190;\n        } else if (isJavaVersion(javaVersion,\"20\")) { // NOI18N\n            jdkVersion = JDK_200;\n        } else if (isJavaVersion(javaVersion,\"21\")) { // NOI18N\n            jdkVersion = JDK_210;\n        } else if (isJavaVersion(javaVersion,\"22\")) { // NOI18N\n            jdkVersion = JDK_220;\n        } else if (isJavaVersion(javaVersion,\"23\")) { // NOI18N\n            jdkVersion = JDK_230;\n        } else if (isJavaVersion(javaVersion,\"24\")) { // NOI18N\n            jdkVersion = JDK_240;\n        } else if (isJavaVersion(javaVersion,\"25\")) { // NOI18N\n            jdkVersion = JDK_250;\n        } else if (javaVersion.equals(\"CVM\")) { // NOI18N\n            jdkVersion = JDK_CVM;\n        } else {\n            jdkVersion = JDK_UNSUPPORTED;\n        }\n        return jdkVersion;\n    }\n\n    private static final boolean isJavaVersion(String javaVersionProperty, String releaseVersion) {\n        if (javaVersionProperty.equals(releaseVersion)) return true;\n        if (javaVersionProperty.equals(releaseVersion+\"-ea\")) return true;\n        if (javaVersionProperty.startsWith(releaseVersion+\".\")) return true;\n        return false;\n    }\n    \n    /**\n     * Returns the JFluid-internal JDK version number\n     */\n    public static int getJDKVersionNumber() {\n        if (jdkVersion == 0) {\n            jdkVersion = getJDKVersionNumber(getJavaVersionString());\n        }\n        return jdkVersion;\n    }\n\n    /**\n     * Returns the string for, essentially, JFluid directory corresponding to a particular JDK version the TA runs on.\n     * Currently it's \"jdk15\" for JDK 1.5 version and \"jdk16\" for JDK 1.6 version, \"jdk17\" for JDK 1.7 version,\n     *  \"jdk18\" for JDK 1.8 version and \"jdk19\" for JDK 9 version and\n     *  \"jdk100\" for JDK 10 version and \"cvm\" for CVM\n     */\n    public static String getJDKVersionString(String javaVersionString) {\n        int jdkVersionNumber = getJDKVersionNumber(javaVersionString);\n        \n        switch (jdkVersionNumber) {\n            case JDK_15: return JDK_15_STRING;\n            case JDK_16: return JDK_16_STRING;\n            case JDK_17: return JDK_17_STRING;\n            case JDK_18: return JDK_18_STRING;\n            case JDK_19: return JDK_19_STRING;\n            case JDK_100: return JDK_100_STRING;\n            case JDK_110: return JDK_110_STRING;\n            case JDK_120: return JDK_120_STRING;\n            case JDK_130: return JDK_130_STRING;\n            case JDK_140: return JDK_140_STRING;\n            case JDK_150: return JDK_150_STRING;\n            case JDK_160: return JDK_160_STRING;\n            case JDK_170: return JDK_170_STRING;\n            case JDK_180: return JDK_180_STRING;\n            case JDK_190: return JDK_190_STRING;\n            case JDK_200: return JDK_200_STRING;\n            case JDK_210: return JDK_210_STRING;\n            case JDK_220: return JDK_220_STRING;\n            case JDK_230: return JDK_230_STRING;\n            case JDK_240: return JDK_240_STRING;\n            case JDK_250: return JDK_250_STRING;\n            case JDK_CVM: return JDK_CVM_STRING;\n            case JDK_UNSUPPORTED: return JDK_UNSUPPORTED_STRING;\n        }\n        System.err.println(\"Unsupported java \"+javaVersionString);\n        return JDK_UNSUPPORTED_STRING;\n    }\n\n    /**\n     * Returns the string for, essentially, JFluid directory corresponding to a particular JDK version the TA runs on.\n     * Currently it's \"jdk15\" for JDK 1.5 version, \"jdk16\" for JDK 1.6 version, \"jdk17\" for JDK 1.7 version,\n     * \"jdk18\" for JDK 1.8 version, \"jdk19\" for JDK 1.9 version and \"cvm\" for CVM\n     */\n    public static String getJDKVersionString() {\n        if (jdkDenoteString == null) {\n            jdkDenoteString = getJDKVersionString(getJavaVersionString());\n        }\n        return jdkDenoteString;\n    }\n\n    public static String getJavaVersionString() {\n        // This is ugly hack for CVM. CVM cannot be identified using java.version\n        // system property and we have to use java.vm.name which is hardcoded\n        // to \"CVM\"\n        String vmVersion = System.getProperty(\"java.vm.name\");   // NOI18N\n        if (\"CVM\".equals(vmVersion)) {\n            return vmVersion;\n        }\n        return System.getProperty(\"java.version\");  // NOI18N\n    }\n    \n    public static String getJFluidNativeLibDirName(String fullJFluidPath, String jdkString, int architecture) {\n        String jFluidNativeLibFullName = getAgentNativeLibFullName(fullJFluidPath, false, jdkString, architecture);\n\n        return jFluidNativeLibFullName.substring(0, jFluidNativeLibFullName.lastIndexOf('/')); // NOI18N\n    }\n\n    /**\n     * Test whether we are running on Linux\n     */\n    public static boolean isLinux() {\n        return (getOperatingSystem() == OS_LINUX);\n    }\n\n    /**\n     * Test whether the supplied OS name is Linux\n     */\n    public static boolean isLinux(String osName) {\n        return (getOperatingSystem(osName) == OS_LINUX);\n    }\n\n    public static boolean isMac() {\n        return (getOperatingSystem() == OS_MAC);\n    }\n    \n    /**\n     * Get the operating system on which we are is running.\n     * Returns one of the <code>OS_*</code> constants (such as {@link #OS_WINNT})\n     */\n    public static int getOperatingSystem() {\n        if (operatingSystem == -1) {\n            String osName = System.getProperty(\"os.name\"); // NOI18N\n            operatingSystem = getOperatingSystem(osName);\n        }\n\n        return operatingSystem;\n    }\n\n    public static int getOperatingSystem(String osName) {\n        if (\"Windows NT\".equals(osName)) { // NOI18N\n\n            return OS_WINNT;\n        } else if (\"Windows 95\".equals(osName)) { // NOI18N\n\n            return OS_WIN95;\n        } else if (\"Windows 98\".equals(osName)) { // NOI18N\n\n            return OS_WIN98;\n        } else if (\"Windows 2000\".equals(osName)) { // NOI18N\n\n            return OS_WIN2000;\n        } else if (osName.startsWith(\"Windows \")) { // NOI18N\n\n            return OS_WIN_OTHER;\n        } else if (\"Solaris\".equals(osName)) { // NOI18N\n\n            return OS_SOLARIS;\n        } else if (osName.startsWith(\"SunOS\")) { // NOI18N\n\n            return OS_SOLARIS;\n        } else if (osName.endsWith(\"Linux\")) { // NOI18N\n\n            return OS_LINUX;\n        } else if (\"AIX\".equals(osName)) { // NOI18N\n\n            return OS_AIX;\n        } else if (\"Irix\".equals(osName)) { // NOI18N\n\n            return OS_IRIX;\n        } else if (\"SunOS\".equals(osName)) { // NOI18N\n\n            return OS_SOLARIS;\n        } else if (\"Digital UNIX\".equals(osName)) { // NOI18N\n\n            return OS_TRU64;\n        } else if (\"OS/2\".equals(osName)) { // NOI18N\n\n            return OS_OS2;\n        } else if (\"OpenVMS\".equals(osName)) { // NOI18N\n\n            return OS_VMS;\n        } else if (osName.equalsIgnoreCase(\"mac os x\")) { // NOI18N\n\n            return OS_MAC;\n        } else if (osName.startsWith(\"Darwin\")) { // NOI18N\n\n            return OS_MAC;\n        } else {\n            return OS_OTHER;\n        }\n    }\n\n    public static String getProfilerUserDir() throws IOException {\n        String customDir = System.getProperty(\"nbprofiler.home\"); // NOI18N\n\n        if (customDir != null) {\n            File d = new File(customDir);\n\n            if (!d.exists()) {\n                if (!d.mkdir()) {\n                    throw new IOException(\"Could not create directory \" + customDir); // NOI18N\n                }\n            }\n\n            return customDir;\n        } else {\n            // use default location\n            String dir = System.getProperty(\"user.home\") + File.separator + \".nbprofiler\"; // NOI18N\n            File d = new File(dir);\n\n            if (!d.exists()) {\n                if (!d.mkdir()) {\n                    throw new IOException(\"Could not create directory \" + dir); // NOI18N\n                }\n            }\n\n            return dir;\n        }\n    }\n\n    /**\n     * Test whether we are running on Solaris\n     */\n    public static boolean isSolaris() {\n        return (getOperatingSystem() == OS_SOLARIS);\n    }\n\n    /**\n     * Test whether we are running on Solaris on Intel processor\n     */\n    public static boolean isSolarisIntel() {\n        String procArch = System.getProperty(\"os.arch\"); // NOI18N\n\n        return isSolaris() && (procArch.endsWith(\"86\") || procArch.equals(\"amd64\")); // NOI18N\n    }\n\n    /**\n     * Test whether we are running on Solaris on SPARC processor\n     */\n    public static boolean isSolarisSparc() {\n        String procArch = System.getProperty(\"os.arch\"); // NOI18N\n\n        return isSolaris() && procArch.startsWith(\"sparc\"); // NOI18N\n    }\n\n    /**\n     * Test whether we are running on Linux on ARM processor\n     */\n    public static boolean isLinuxArm() {\n        String procArch = System.getProperty(\"os.arch\"); // NOI18N\n        \n        return isLinux() && procArch.startsWith(\"arm\"); // NOI18N\n    }\n\n    /**\n     * Test whether we are running on Linux on ARM processor with Hard float ABI\n     */\n    public static boolean isLinuxArmVfpHflt() {\n        String procArch = System.getProperty(\"sun.arch.abi\"); // NOI18N\n        \n        return isLinux() && isLinuxArm() && \"gnueabihf\".equals(procArch); // NOI18N\n    }\n    \n    public static boolean isLinuxAarch64() {\n        String procArch = System.getProperty(\"os.arch\"); // NOI18N\n\n        return isLinux() && procArch.equals(\"aarch64\"); // NOI18N\n    }\n    /**\n     * Test whether we are running on Linux on ARM processor\n     */\n    public static boolean isLinuxIntel() {\n        String procArch = System.getProperty(\"os.arch\"); // NOI18N\n        \n        return isLinux() && (procArch.endsWith(\"86\") || procArch.equals(\"amd64\")); // NOI18N\n    }\n\n    /**\n     * Returns system architecture: 32/64bit\n     */\n    public static int getSystemArchitecture() {\n        if (sysArch == 0) {\n            String architecture = System.getProperty(\"sun.arch.data.model\"); // NOI18N\n            sysArch = getSystemArchitecture(architecture);\n        }\n        return sysArch;\n    }\n    \n    public static int getSystemArchitecture(String arch) {\n        return \"64\".equals(arch) ? ARCH_64 : ARCH_32;\n    }\n\n    /**\n     * Test whether we are running on some variant of Unix. Linux is included as well as the commercial vendors.\n     */\n    public static boolean isUnix() {\n        return (getOperatingSystem() & OS_UNIX_MASK) != 0;\n    }\n\n    /**\n     * Test whether we are is running on some variant of Windows\n     */\n    public static boolean isWindows() {\n        return (getOperatingSystem() & OS_WINDOWS_MASK) != 0;\n    }\n\n    /**\n     * Test whether the supplied OS name is some variant of Windows\n     */\n    public static boolean isWindows(String osName) {\n        return (getOperatingSystem(osName) & OS_WINDOWS_MASK) != 0;\n    }\n\n    /**\n     * Returns true if current system architecture is 32bit\n     */\n    public static boolean is32bitArchitecture() {\n        return getSystemArchitecture() == ARCH_32;\n    }\n\n    /**\n     * Returns true if current system architecture is 64bit\n     */\n    public static boolean is64bitArchitecture() {\n        return getSystemArchitecture() == ARCH_64;\n    }\n\n    /**\n     * Returns true if the given JVM version supports dynamic attach\n     */\n    public static boolean supportsDynamicAttach(String jdkVersionString) {\n        return jdkVersionString != null\n                && !CommonConstants.JDK_UNSUPPORTED_STRING.equals(jdkVersionString)\n                && !CommonConstants.JDK_CVM_STRING.equals(jdkVersionString)\n                && !CommonConstants.JDK_15_STRING.equals(jdkVersionString);\n    }\n\n    /**\n     * Returns true if the given JVM version passed as String correctly reports \"sleeping\" state\n     */\n    public static boolean supportsThreadSleepingStateMonitoring(String jdkVersionString) {\n        return jdkVersionString != null\n                && !CommonConstants.JDK_UNSUPPORTED_STRING.equals(jdkVersionString);\n    }\n\n    /**\n     * Returns true if the current JVM correctly reports \"sleeping\" state\n     */\n    public static boolean thisVMSupportsThreadSleepingStateMonitoring() {\n        return supportsThreadSleepingStateMonitoring(getJDKVersionNumber());\n    }\n\n    /**\n     * Returns true if the given JVM version number correctly reports \"sleeping\" state\n     */\n    private static boolean supportsThreadSleepingStateMonitoring(int jdkVersionNumber) {\n        return ((jdkVersionNumber == JDK_15) ||\n\t\t(jdkVersionNumber == JDK_16) ||\n\t\t(jdkVersionNumber == JDK_17) ||\n\t\t(jdkVersionNumber == JDK_18) ||\n\t\t(jdkVersionNumber >= JDK_19) ||\n\t\t(jdkVersionNumber == JDK_CVM));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/global/ProfilingSessionStatus.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.global;\n\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.InternalStatsResponse;\n\n\n/**\n * Various data pertinent to the profiling session. Note that this class is used by both client and back end,\n * although some data at the back end side is contained in the reduced form, to reduce memory usage.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Adrian Mos\n */\npublic class ProfilingSessionStatus {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int N_TIMER_CONSTANTS = 5;\n\n    //EJB Work: The index pointing to the class for code region instrumentation. It is the first class in the array of classes, as it should be the only class there.\n    public static final int CODE_REGION_CLASS_IDX = 0;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    // This internal statistics record is filled in at the client side only upon application termination. It exists just to\n    // allow the user to obtain statistics after the target app/VM has already completed execution.\n    public InternalStatsResponse savedInternalStats;\n\n    // Full (including minor version) target JDK version string - for example 1.5.0_12\n    public String fullTargetJDKVersionString;\n\n    // Data for both code region and method group instrumentation. In the latter case this data is for the root method.\n    public String instrClassLoaderName;\n\n    // Command line arguments of the JVM, and the full Java command, that includes main class (or .jar) plus its arguments\n    public String javaCommand;\n\n    // Command line arguments of the JVM, and the full Java command, that includes main class (or .jar) plus its arguments\n    public String jvmArguments;\n\n    // Target JDK version string, as returned by Platform.getJDKVersionString()\n    public String targetJDKVersionString;\n\n    // Target machine OS, as returned by System.getProperty(\"os.name\")\n    public String targetMachineOSName;\n\n    // true if target JDK class file verifier accepts our constructor instrumentation\n    public boolean canInstrumentConstructor;\n\n    // Important timer-related characteristics of instrumentation that we inject into the TA.\n    // Each array has 5 elements:\n    // o value when absolute timer is used;\n    // o value when thread-local CPU timer is used;\n    // o value of inner/outer absolute time when both timers are used;\n    // o value of inner/outer thread-local CPU time when both timers are used.\n    // o value when sampled instrumentation is used.\n    // ALL these values (including thread-local CPU ones, see comments in ProfilerCalibrator for explanation) are measured in\n    // absolute timer's counts (which is anything on Windows and nanoseconds on Solaris)\n    public double[] methodEntryExitCallTime = new double[N_TIMER_CONSTANTS]; // Elements #2 and #3 are actually the same\n    public double[] methodEntryExitInnerTime = new double[N_TIMER_CONSTANTS];\n    public double[] methodEntryExitOuterTime = new double[N_TIMER_CONSTANTS];\n    public long[] timerCountsInSecond = new long[2];\n    public boolean absoluteTimerOn;\n    public boolean remoteProfiling = false;\n    public boolean runningInAttachedMode; // true if attached to target JVM, false if started it from client\n    public boolean startProfilingPointsActive; // Indicates that inCallGraph should be set by profiling point handler code and NOT rootMethodEntry\n    public volatile boolean targetAppRunning;\n    public boolean threadCPUTimerOn;\n    public int currentInstrType;\n    public int instrEndLine;\n    public int instrScheme;\n    public int instrStartLine;\n\n    // Server's timestamp of the moment when CPU results dump is requested. Used to display absolute call graph time correctly even\n    // when no absolute timestamps for methods are collected. Note that we could probably do the same thing on a per-thread basis\n    // and thus have thread CPU call graph time always available - but that seems to be too much work for now.\n    public long dumpAbsTimeStamp;\n\n    // Target machnine maximum heap size returned by Runtime.maxMemory()\n    public long maxHeapSize;\n\n    // Target machnine statup time returned by Timers.getCurrentTimeInCounts()\n    public long startupTimeInCounts;\n\n    // Target machnine startup time returned by System.currentTimeMillis()\n    public long startupTimeMillis;\n    private TransactionalSupport transaction = new TransactionalSupport();\n    private int[] allocatedInstancesCount;\n    private int[] classLoaderIds;\n    private String[] classNames;\n    private String[] instrMethodClasses;\n    private boolean[] instrMethodInvoked;\n    private String[] instrMethodNames;\n    private String[] instrMethodSignatures;\n\n    // Data for the case of object allocations instrumentation\n    private int nInstrClasses;\n\n    // Data for the case of method group instrumentation\n    private int nInstrMethods;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int[] getAllocatedInstancesCount() {\n        beginTrans(false);\n\n        try {\n            return allocatedInstancesCount;\n        } finally {\n            endTrans();\n        }\n    }\n\n    public int[] getClassLoaderIds() {\n        beginTrans(false);\n\n        try {\n            return classLoaderIds;\n        } finally {\n            endTrans();\n        }\n    }\n\n    public String[] getClassNames() {\n        beginTrans(false);\n\n        try {\n            return classNames;\n        } finally {\n            endTrans();\n        }\n    }\n\n    public String[] getInstrMethodClasses() {\n        beginTrans(false);\n\n        try {\n            return instrMethodClasses;\n        } finally {\n            endTrans();\n        }\n    }\n\n    public boolean[] getInstrMethodInvoked() {\n        beginTrans(false);\n\n        try {\n            return instrMethodInvoked;\n        } finally {\n            endTrans();\n        }\n    }\n\n    public void setInstrMethodNames(String[] value) {\n        beginTrans(true);\n\n        try {\n            instrMethodNames = value;\n        } finally {\n            endTrans();\n        }\n    }\n\n    public String[] getInstrMethodNames() {\n        beginTrans(false);\n\n        try {\n            return instrMethodNames;\n        } finally {\n            endTrans();\n        }\n    }\n\n    public void setInstrMethodSignatures(String[] value) {\n        beginTrans(true);\n\n        try {\n            instrMethodSignatures = value;\n        } finally {\n            endTrans();\n        }\n    }\n\n    public String[] getInstrMethodSignatures() {\n        beginTrans(false);\n\n        try {\n            return instrMethodSignatures;\n        } finally {\n            endTrans();\n        }\n    }\n\n    public int getNInstrClasses() {\n        beginTrans(false);\n\n        try {\n            return nInstrClasses;\n        } finally {\n            endTrans();\n        }\n    }\n\n    public int getNInstrMethods() {\n        beginTrans(false);\n\n        try {\n            return nInstrMethods;\n        } finally {\n            endTrans();\n        }\n    }\n\n    public int getStartingMethodId() {\n        beginTrans(false);\n\n        try {\n            if (nInstrMethods > 0) {\n                return nInstrMethods;\n            } else {\n                return 1;\n            }\n        } finally {\n            endTrans();\n        }\n    }\n\n    public void setTimerTypes(boolean absolute, boolean threadCPU) {\n        absoluteTimerOn = absolute;\n        threadCPUTimerOn = threadCPU;\n    }\n\n    public void beginTrans(boolean mutable) {\n        transaction.beginTrans(mutable);\n    }\n\n    public boolean collectingTwoTimeStamps() {\n        return (absoluteTimerOn && threadCPUTimerOn);\n    }\n\n    public void endTrans() {\n        transaction.endTrans();\n    }\n\n    // ----------------------------------- Recursive method instrumentation management ------------------------------------------\n    public void resetInstrClassAndMethodInfo() {\n        beginTrans(true);\n\n        try {\n            nInstrMethods = 0;\n            instrMethodClasses = instrMethodNames = instrMethodSignatures = null;\n            instrMethodInvoked = null;\n            nInstrClasses = 0;\n            allocatedInstancesCount = null;\n            classNames = new String[0];\n        } finally {\n            endTrans();\n        }\n    }\n\n    // --------------------- Object allocations/liveness accounting management ------------------------------\n\n    /**\n     * Takes the delta in the number of profiled classes and their names, and updates internal data structures.\n     * Should be used only at client side.\n     */\n    public void updateAllocatedInstancesCountInfoInClient(String addedClassName) {\n        beginTrans(true);\n\n        try {\n            if ((nInstrClasses == 0) || (nInstrClasses == classNames.length)) {\n                boolean firstTime = (nInstrClasses == 0);\n                int newSize = firstTime ? 50 : ((nInstrClasses * 3) / 2);\n                int[] newAllocInstCount = new int[newSize];\n                String[] newClassNames = new String[newSize];\n\n                if (!firstTime) {\n                    System.arraycopy(allocatedInstancesCount, 0, newAllocInstCount, 0, nInstrClasses);\n                    System.arraycopy(classNames, 0, newClassNames, 0, nInstrClasses);\n                }\n\n                allocatedInstancesCount = newAllocInstCount;\n                classNames = newClassNames;\n            }\n\n            classNames[nInstrClasses++] = addedClassName;\n        } finally {\n            endTrans();\n        }\n    }\n\n    /** Same as above, but takes the total number of classes, and should be used only at server side. */\n    public void updateAllocatedInstancesCountInfoInServer(int nTotalClasses) {\n        beginTrans(true);\n\n        try {\n            boolean firstTime = (nInstrClasses == 0);\n            int oldSize = firstTime ? 0 : allocatedInstancesCount.length;\n            int newLen = nTotalClasses;\n\n            if (oldSize < newLen) {\n                int newSize = newLen * 2;\n                int[] newAllocInstCount = new int[newSize];\n\n                if (!firstTime) {\n                    System.arraycopy(allocatedInstancesCount, 0, newAllocInstCount, 0, nInstrClasses);\n                }\n\n                allocatedInstancesCount = newAllocInstCount;\n            }\n\n            nInstrClasses = nTotalClasses;\n        } finally {\n            endTrans();\n        }\n    }\n\n    /**\n     * This method updates information about instrumented methods (class, name, signature, class loader for class etc.)\n     * for a group of methods. Can be used at both client and server side.\n     */\n    public void updateInstrMethodsInfo(int nClasses, int nMethods, String[] classes, int[] loaderIds, int[] nMethodsInClass,\n                                       String[] methodNames, String[] methodSignatures, boolean[] isMethodLeaf) {\n        if (nClasses == 0) {\n            return;\n        }\n\n        beginTrans(true);\n\n        try {\n            boolean firstTime = (nInstrMethods == 0);\n            int oldSize = firstTime ? 0 : ((classes != null) ? instrMethodNames.length : instrMethodInvoked.length);\n            int emptyCell = (firstTime ? 1 : 0);\n            int nAddedMethods = nMethods + emptyCell;\n            int newLen = nInstrMethods + nMethods + emptyCell;\n\n            if (oldSize < newLen) { // Grow arrays\n\n                int newSize = newLen * 2;\n\n                if (classes != null) { // Client side execution\n\n                    String[] newClasses = new String[newSize];\n                    int[] newLoaderIds = new int[newSize];\n                    String[] newMethods = new String[newSize];\n                    String[] newSignatures = new String[newSize];\n\n                    if (!firstTime) {\n                        System.arraycopy(instrMethodClasses, 0, newClasses, 0, nInstrMethods);\n                        System.arraycopy(classLoaderIds, 0, newLoaderIds, 0, nInstrMethods);\n                        System.arraycopy(instrMethodNames, 0, newMethods, 0, nInstrMethods);\n                        System.arraycopy(instrMethodSignatures, 0, newSignatures, 0, nInstrMethods);\n                    }\n\n                    instrMethodClasses = newClasses;\n                    classLoaderIds = newLoaderIds;\n                    instrMethodNames = newMethods;\n                    instrMethodSignatures = newSignatures;\n                } else { // Server side execution\n\n                    boolean[] newMethodInvoked = new boolean[newSize];\n\n                    if (!firstTime) {\n                        System.arraycopy(instrMethodInvoked, 0, newMethodInvoked, 0, nInstrMethods);\n                    }\n\n                    instrMethodInvoked = newMethodInvoked;\n                }\n            }\n\n            if (classes != null) { // Client side execution\n\n                if (firstTime) {\n                    instrMethodClasses[0] = \"Thread\"; // NOI18N\n                    classLoaderIds[0] = 0;\n                    instrMethodNames[0] = \"\"; // NOI18N\n                    instrMethodSignatures[0] = \"\"; // NOI18N\n                }\n\n                int idx = nInstrMethods + emptyCell;\n\n                for (int i = 0; i < nClasses; i++) {\n                    for (int j = 0; j < nMethodsInClass[i]; j++) {\n                        instrMethodClasses[idx] = classes[i];\n                        classLoaderIds[idx] = loaderIds[i];\n                        idx++;\n                    }\n                }\n\n                System.arraycopy(methodNames, 0, instrMethodNames, nInstrMethods + emptyCell, nMethods);\n                System.arraycopy(methodSignatures, 0, instrMethodSignatures, nInstrMethods + emptyCell, nMethods);\n            } else { // Server side execution\n\n                if (isMethodLeaf != null) {\n                    System.arraycopy(isMethodLeaf, 0, instrMethodInvoked, nInstrMethods + emptyCell, nMethods);\n                }\n\n                if (instrScheme == CommonConstants.INSTRSCHEME_EAGER) {\n                    for (int i = nInstrMethods; i < (nInstrMethods + nAddedMethods); i++) {\n                        instrMethodInvoked[i] = true;\n                    }\n                }\n            }\n\n            nInstrMethods += nAddedMethods;\n        } finally {\n            endTrans();\n        }\n\n        //System.err.println(\"*** Profiler Engine: nMethods = \" + nMethods + \", nInstrMethods = \" + nInstrMethods + \", instrMethodInvoked.len = \" + instrMethodInvoked.length);\n    }\n\n    /**\n     * This method adds information about a single instrumented method. Intended to be used on client side only.\n     */\n    public void updateInstrMethodsInfo(String className, int loaderId, String methodName, String methodSignature) {\n        //System.err.println(\"*** Profiler Engine: updateInstr() called for \" + className + \".\" + methodName + \", nis = \" + nInstrMethods);\n        beginTrans(true);\n\n        try {\n            boolean firstTime = (nInstrMethods == 0);\n            int oldSize = firstTime ? 0 : instrMethodNames.length;\n            int newLen = nInstrMethods + 1;\n            int emptyCell = (firstTime ? 1 : 0);\n            int nAddedMethods = 1 + emptyCell;\n\n            if (oldSize < newLen) { // Grow arrays\n\n                int newSize = newLen * 2;\n\n                String[] newClasses = new String[newSize];\n                int[] newLoaderIds = new int[newSize];\n                String[] newMethods = new String[newSize];\n                String[] newSignatures = new String[newSize];\n\n                if (!firstTime) {\n                    System.arraycopy(instrMethodClasses, 0, newClasses, 0, nInstrMethods);\n                    System.arraycopy(classLoaderIds, 0, newLoaderIds, 0, nInstrMethods);\n                    System.arraycopy(instrMethodNames, 0, newMethods, 0, nInstrMethods);\n                    System.arraycopy(instrMethodSignatures, 0, newSignatures, 0, nInstrMethods);\n                }\n\n                instrMethodClasses = newClasses;\n                classLoaderIds = newLoaderIds;\n                instrMethodNames = newMethods;\n                instrMethodSignatures = newSignatures;\n            }\n\n            if (firstTime) {\n                instrMethodClasses[0] = \"Thread\"; // NOI18N\n                classLoaderIds[0] = 0;\n                instrMethodNames[0] = \"\"; // NOI18N\n                instrMethodSignatures[0] = \"\"; // NOI18N\n            }\n\n            int idx = nInstrMethods + emptyCell;\n            instrMethodClasses[idx] = className;\n            classLoaderIds[idx] = loaderId;\n            instrMethodNames[idx] = methodName;\n            instrMethodSignatures[idx] = methodSignature;\n\n            nInstrMethods += nAddedMethods;\n        } finally {\n            endTrans();\n        }\n\n        //System.err.println(\"*** Profiler Engine: nInstrMethods = \" + nInstrMethods + \", instrMethodNames.len = \" + instrMethodNames.length);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/global/TransactionalSupport.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.global;\n\n\n//import java.util.logging.Level;\n//import java.util.logging.Logger;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class TransactionalSupport {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static final boolean DEBUG = System.getProperty(TransactionalSupport.class.getName()) != null;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final Object transactionLock = new Object();\n    private final ThreadLocal interruptedFlag = new ThreadLocal();\n    private final ThreadLocal lockRead = new ThreadLocal();\n    private final ThreadLocal lockWrite = new ThreadLocal();\n\n    //  final static private Logger LOGGER = Logger.getLogger(TransactionalSupport.class.getName());\n    private boolean lockedExclusively = false;\n\n    //  final static private Logger LOGGER = Logger.getLogger(TransactionalSupport.class.getName());\n    private boolean lockedShared = false;\n    private int sharedLockCount = 0;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void beginTrans(boolean mutable) {\n        beginTrans(mutable, false);\n    }\n\n    public boolean beginTrans(boolean mutable, boolean failEarly) {\n        if (DEBUG) {\n            System.out.println(\"DEBUG: [\" + Thread.currentThread().getName() + \"] Starting transaction: mutable = \" + mutable\n                               + \", failEarly = \" + failEarly); // NOI18N\n        }\n\n        synchronized (transactionLock) {\n            boolean result = false;\n\n            do {\n                if (mutable) {\n                    result = lockExclusively();\n                } else {\n                    result = lockShared();\n                }\n\n                if (!result && !failEarly) {\n                    if (DEBUG) {\n                        System.out.println(\"DEBUG: [\" + Thread.currentThread().getName()\n                                           + \"] Couldn't start transaction. Going to wait for some time\"); // NOI18N\n                    }\n\n                    boolean interrupted = false;\n\n                    do {\n                        interrupted = false;\n\n                        try {\n                            transactionLock.wait();\n                        } catch (InterruptedException e) {\n                            interruptedFlag.set(new Object());\n                            interrupted = true;\n                            Thread.interrupted();\n                        }\n                    } while (interrupted);\n                }\n            } while (!result && !failEarly);\n\n            return result;\n        }\n    }\n\n    public void endTrans() {\n        synchronized (transactionLock) {\n            Integer roCounter = (Integer) lockRead.get();\n            Integer rwCounter = (Integer) lockWrite.get();\n\n            if (roCounter == null) {\n                unlockShared();\n            } else {\n                if (DEBUG) {\n                    System.out.println(\"DEBUG: [\" + Thread.currentThread().getName() + \"] Releasing ownership for a shared lock\"); // NOI18N\n                }\n\n                int counter = roCounter.intValue();\n\n                if (counter > 1) {\n                    lockRead.set(new Integer(counter - 1));\n                } else {\n                    lockRead.set(null);\n                    unlockShared();\n                }\n            }\n\n            if (rwCounter == null) {\n                if (DEBUG) {\n                    System.out.println(\"DEBUG: [\" + Thread.currentThread().getName() + \"] Unlocking an exclusive lock\"); // NOI18N\n                }\n\n                lockedExclusively = false;\n            } else {\n                if (DEBUG) {\n                    System.out.println(\"DEBUG: [\" + Thread.currentThread().getName()\n                                       + \"] Releasing ownership for an exclusive lock\"); // NOI18N\n                }\n\n                int counter = rwCounter.intValue();\n\n                if (counter > 1) {\n                    lockWrite.set(new Integer(counter - 1));\n                } else {\n                    lockWrite.set(null);\n\n                    if (DEBUG) {\n                        System.out.println(\"DEBUG: [\" + Thread.currentThread().getName() + \"] Unlocking an exclusive lock\"); // NOI18N\n                    }\n\n                    lockedExclusively = false;\n                }\n            }\n\n            transactionLock.notifyAll();\n        }\n\n        rethrowInterrupt();\n    }\n\n    private boolean lockExclusively() {\n        if (lockedShared) {\n            return promoteToExclusive();\n        }\n\n        if (lockedExclusively) {\n            return relockExclusively();\n        } else {\n            if (DEBUG) {\n                System.out.println(\"DEBUG: [\" + Thread.currentThread().getName() + \"] Grabbing an exclusive lock for transaction\"); // NOI18N\n            }\n\n            lockedExclusively = true;\n            lockWrite.set(new Integer(1));\n\n            return true;\n        }\n    }\n\n    private boolean lockShared() {\n        boolean result;\n\n        if (lockedExclusively) {\n            return relockExclusively();\n        } else {\n            if (DEBUG) {\n                System.out.println(\"DEBUG: [\" + Thread.currentThread().getName() + \"] Grabbing shared lock for transaction\"); // NOI18N\n            }\n\n            lockedShared = true;\n\n            Integer counter = (Integer) lockRead.get();\n\n            if (counter == null) {\n                lockRead.set(new Integer(1));\n                sharedLockCount++; // turn the lock counter only if the current thread doesn't own the sahred lock already\n            } else {\n                lockRead.set(new Integer(counter.intValue() + 1));\n            }\n\n            result = true;\n\n            return result;\n        }\n    }\n\n    private boolean promoteToExclusive() {\n        boolean result;\n\n        if (sharedLockCount > 1) {\n            System.err.println(\"WARNING: [\" + Thread.currentThread().getName() + \"] Cant promote a shared lock held by \"\n                               + sharedLockCount + \" threads!\"); // NOI18N\n\n            return false; // can't promote a shared lock held by more threads\n        }\n\n        Integer counter = (Integer) lockRead.get();\n\n        if (counter != null) {\n            if (DEBUG) {\n                System.out.println(\"DEBUG: [\" + Thread.currentThread().getName()\n                                   + \"] Promoting a previously owned shared lock to the exclusive one\"); // NOI18N\n            }\n\n            lockedShared = false;\n            sharedLockCount = 0;\n            lockedExclusively = true;\n            lockWrite.set(new Integer(counter.intValue() + 1));\n            lockRead.set(null);\n            result = true;\n        } else {\n            if (DEBUG) {\n                System.out.println(\"DEBUG: [\" + Thread.currentThread().getName()\n                                   + \"] Failed to promote a previously owned shared lock\"); // NOI18N\n            }\n\n            result = false;\n        }\n\n        return result;\n    }\n\n    private boolean relockExclusively() {\n        boolean result;\n        Integer counter = (Integer) lockWrite.get();\n\n        if (counter != null) {\n            if (DEBUG) {\n                System.out.println(\"DEBUG: [\" + Thread.currentThread().getName()\n                                   + \"] Relocking a previously owned exclusive lock\"); // NOI18N\n            }\n\n            lockWrite.set(new Integer(counter.intValue() + 1));\n            result = true;\n        } else {\n            if (DEBUG) {\n                System.out.println(\"DEBUG: [\" + Thread.currentThread().getName()\n                                   + \"] Failed to relock an exclusive lock. Not an owner.\"); // NOI18N\n            }\n\n            result = false;\n        }\n\n        return result;\n    }\n\n    private void rethrowInterrupt() {\n        if (interruptedFlag.get() != null) {\n            Thread.currentThread().interrupt();\n            interruptedFlag.set(null);\n        }\n    }\n\n    private void unlockShared() {\n        if (DEBUG) {\n            System.out.println(\"DEBUG: [\" + Thread.currentThread().getName() + \"] Unlocking a shared lock\"); // NOI18N\n        }\n\n        lockedShared = false;\n\n        if (sharedLockCount > 0) {\n            sharedLockCount--;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/BadLocationException.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport java.util.ResourceBundle;\n\n\n/**\n * An exception thrown when begin line or end line are incorrect during Code Fragment profiling\n *\n * @author Ian Formanek\n */\npublic class BadLocationException extends Exception {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String CANNOT_FIND_METHOD_CURSOR_MSG;\n    private static final String CANNOT_FIND_METHOD_SELECTION_MSG;\n\n    static {\n        ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.instrumentation.Bundle\"); // NOI18N\n        CANNOT_FIND_METHOD_CURSOR_MSG = messages.getString(\"BadLocationException_CannotFindMethodCursorMsg\"); // NOI18N\n        CANNOT_FIND_METHOD_SELECTION_MSG = messages.getString(\"BadLocationException_CannotFindMethodSelectionMsg\"); // NOI18N\n    }\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public BadLocationException() {\n    }\n\n    public BadLocationException(String message) {\n        super(message);\n    }\n\n    public BadLocationException(int code) {\n        super((code == 1) ? CANNOT_FIND_METHOD_CURSOR_MSG : ((code == 2) ? CANNOT_FIND_METHOD_SELECTION_MSG : null));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nBadLocationException_CannotFindMethodCursorMsg=Can't find a method for the given source line.\\nPerhaps you placed cursor on a line consisting only of '{', '}',\\nor a statement such as 'do {' or 'try {'?\nBadLocationException_CannotFindMethodSelectionMsg=Can't find a method for the given source lines.\\nPerhaps your selection's first or last line consists only of '{', '}',\\nor a statement such as 'do {' or 'try{'?\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/CPExtensionsRepository.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.ConstantPoolExtension.CPEntry;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.ConstantPoolExtension.PackedCPFragment;\n\n\n/**\n * A repository containing semi-prepared constant pool fragments for all kinds of instrumentation used in JFluid.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class CPExtensionsRepository implements JavaClassConstants, CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // These indices, adjusted properly for the base constant pool length for a given class, should be used as cpool indices\n    // of various methods injected into the target app methods.\n    public static int normalContents_MethodEntryMethodIdx;\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // These indices, adjusted properly for the base constant pool length for a given class, should be used as cpool indices\n    // of various methods injected into the target app methods.\n    public static int normalContents_MethodExitMethodIdx;\n    public static int normalContents_ProfilePointHitMethodIdx;\n    public static int rootContents_RootEntryMethodIdx;\n    public static int rootContents_MarkerEntryMethodIdx;\n    public static int miContents_AddParCharMethodIdx;\n    public static int miContents_AddParByteMethodIdx;\n    public static int miContents_AddParIntMethodIdx;\n    public static int miContents_AddParBooleanMethodIdx;\n    public static int miContents_AddParFloatMethodIdx;\n    public static int miContents_AddParDoubleMethodIdx;\n    public static int miContents_AddParShortMethodIdx;\n    public static int miContents_AddParLongMethodIdx;\n    public static int miContents_AddParObjectMethodIdx;\n    public static int rootContents_MarkerExitMethodIdx;\n    public static int rootContents_MarkerExitParMethodIdx;\n    public static int miContents_HandleReflectInvokeMethodIdx;\n    public static int miContents_HandleServletDoMethodIdx;\n    public static int codeRegionContents_CodeRegionEntryMethodIdx;\n    public static int codeRegionContents_CodeRegionExitMethodIdx;\n    public static int memoryProfContents_ProfilePointHitMethodIdx;\n    public static int memoryProfContents_TraceObjAllocMethodIdx; // Make sure it's the same for Obj Allocation and Obj Liveness, otherwise will have to change dependent code\n\n    //------------------------------------ Private implementation -----------------------------------------------\n\n    // Names and signatures of methods, calls to which we inject into TA code\n    private static final String PROFRUNTIME_CPU_CLASS_NAME = \"org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPU\"; // NOI18N\n    private static final String PROFRUNTIME_CPUFULL_CLASS_NAME = \"org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUFullInstr\"; // NOI18N\n    private static final String PROFRUNTIME_CPUSAMPLED_CLASS_NAME = \"org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUSampledInstr\"; // NOI18N\n    private static final String PROFRUNTIME_CPUCODEREGION_CLASS_NAME = \"org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUCodeRegion\"; // NOI18N\n    private static final String PROFRUNTIME_OBJALLOC_CLASS_NAME = \"org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeObjAlloc\"; // NOI18N\n    private static final String PROFRUNTIME_OBJLIVENESS_CLASS_NAME = \"org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeObjLiveness\"; // NOI18N\n    private static final String ROOT_ENTRY_METHOD_NAME = \"rootMethodEntry\"; // NOI18N\n    private static final String MARKER_ENTRY_METHOD_NAME = \"markerMethodEntry\"; // NOI18N\n    private static final String MARKER_EXIT_METHOD_NAME = \"markerMethodExit\"; // NOI18N\n    private static final String METHOD_ENTRY_METHOD_NAME = \"methodEntry\"; // NOI18N\n    private static final String METHOD_EXIT_METHOD_NAME = \"methodExit\"; // NOI18N\n    private static final String HANDLE_REFLECT_INVOKE_METHOD_NAME = \"handleJavaLangReflectMethodInvoke\"; // NOI18N\n    private static final String CODE_REGION_ENTRY_METHOD_NAME = \"codeRegionEntry\"; // NOI18N\n    private static final String CODE_REGION_EXIT_METHOD_NAME = \"codeRegionExit\"; // NOI18N\n    private static final String TRACE_OBJ_ALLOC_METHOD_NAME = \"traceObjAlloc\"; // NOI18N\n    private static final String PROFILE_POINT_HIT = \"profilePointHit\"; // NOI18N\n    private static final String HANDLE_SERVLET_DO_METHOD_NAME = \"handleServletDoMethod\"; // NOI18N\n    private static final String ADD_PARAMETER = \"addParameter\"; // NOI18N\n    private static final String VOID_VOID_SIGNATURE = \"()V\"; // NOI18N\n    private static final String CHAR_VOID_SIGNATURE = \"(C)V\"; // NOI18N\n    private static final String BYTE_VOID_SIGNATURE = \"(B)V\"; // NOI18N\n    private static final String INT_VOID_SIGNATURE = \"(I)V\"; // NOI18N\n    private static final String BOOLEAN_VOID_SIGNATURE = \"(Z)V\"; // NOI18N\n    private static final String FLOAT_VOID_SIGNATURE = \"(F)V\"; // NOI18N\n    private static final String DOUBLE_VOID_SIGNATURE = \"(D)V\"; // NOI18N\n    private static final String SHORT_VOID_SIGNATURE = \"(S)V\"; // NOI18N\n    private static final String LONG_VOID_SIGNATURE = \"(J)V\"; // NOI18N\n    private static final String OBJECT_VOID_SIGNATURE = \"(Ljava/lang/Object;)V\"; // NOI18N\n    private static final String OBJECT_CHAR_VOID_SIGNATURE = \"(Ljava/lang/Object;C)V\"; // NOI18N\n    private static final String REFLECT_METHOD_VOID_SIGNATURE = \"(Ljava/lang/reflect/Method;)V\"; // NOI18N\n    private static final String JAVA_LANG_THROWABLE_NAME = \"java/lang/Throwable\"; // NOI18N\n    private static final String STACK_MAP_TABLE_ATTRIBUTE = \"StackMapTable\"; // NOI18N\n\n    // Predefined constant pools for various kinds of instrumentation\n    private static PackedCPFragment[] standardCPFragments;\n\n    static {\n        initCommonAddedContents();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static PackedCPFragment getStandardCPFragment(int injectionType) {\n        return standardCPFragments[injectionType];\n    }\n\n    // Create standard added cpool contents for each injection kind defined by JFluid.\n    private static void initCommonAddedContents() {\n        standardCPFragments = new PackedCPFragment[INJ_MAXNUMBER];\n\n        // Initialize the \"normal\" recursive instrumentation added constant pool contents\n        CPEntry[] entries = new CPEntry[12];\n        int i = 0;\n        int methodEntryMethodRefIdx = i;\n        i = addMethod(PROFRUNTIME_CPUFULL_CLASS_NAME, METHOD_ENTRY_METHOD_NAME, CHAR_VOID_SIGNATURE, entries, i);\n        int methodExitMethodRefIdx = i;\n        i = addMethod(PROFRUNTIME_CPUFULL_CLASS_NAME, METHOD_EXIT_METHOD_NAME, CHAR_VOID_SIGNATURE, entries, i);\n        int profilePointHitMethodRefIdx = i;\n        addMethod(PROFRUNTIME_CPUFULL_CLASS_NAME, PROFILE_POINT_HIT, CHAR_VOID_SIGNATURE, entries, i);\n        int profilerRuntimeClassRefIdx = getClassCPEntryIndex(PROFRUNTIME_CPUFULL_CLASS_NAME, entries);\n        int charVoidSignatureIdx = getUtf8CPEntryIndex(CHAR_VOID_SIGNATURE, entries);\n        standardCPFragments[INJ_RECURSIVE_NORMAL_METHOD] = new PackedCPFragment(entries);\n        normalContents_ProfilePointHitMethodIdx = profilePointHitMethodRefIdx;\n        normalContents_MethodEntryMethodIdx = methodEntryMethodRefIdx;\n        normalContents_MethodExitMethodIdx = methodExitMethodRefIdx;\n\n        // Create cpool contents for \"sampled instrumentation\" code injection, by replacing just\n        // the instrumentation class name\n        entries[getUtf8CPEntryIndex(PROFRUNTIME_CPUFULL_CLASS_NAME, entries)] = new CPEntry(PROFRUNTIME_CPUSAMPLED_CLASS_NAME);\n        standardCPFragments[INJ_RECURSIVE_SAMPLED_NORMAL_METHOD] = new PackedCPFragment(entries);\n\n        // Additional constant pool contents for rootEntry(char methodId) injection\n        entries = new CPEntry[3];\n        addMethod(profilerRuntimeClassRefIdx + 0x10000, ROOT_ENTRY_METHOD_NAME, charVoidSignatureIdx + 0x10000, entries, 0);\n        standardCPFragments[INJ_RECURSIVE_ROOT_METHOD] = new PackedCPFragment(entries);\n        rootContents_RootEntryMethodIdx = 0;\n\n        // rootEntry() injection for sampled instrumentation is the same as for full instrumentation\n        standardCPFragments[INJ_RECURSIVE_SAMPLED_ROOT_METHOD] = new PackedCPFragment(entries);\n\n        // Additional constant pool contents for markerMethodEntry(char methodId) and markerMethodExit(char methodId) injection\n        entries = new CPEntry[39];\n        i = 0;\n        int markerEntryMethodRefIdx = i;\n        i = addMethod(profilerRuntimeClassRefIdx + 0x10000, MARKER_ENTRY_METHOD_NAME, charVoidSignatureIdx + 0x10000, entries, i);\n        int markerExitMethodRefIdx = i;\n        i = addMethod(profilerRuntimeClassRefIdx + 0x10000, MARKER_EXIT_METHOD_NAME, charVoidSignatureIdx + 0x10000, entries, i);\n        \n        rootContents_MarkerExitParMethodIdx = i;        \n        i = addMethod(profilerRuntimeClassRefIdx + 0x10000, MARKER_EXIT_METHOD_NAME, OBJECT_CHAR_VOID_SIGNATURE, entries, i);\n        miContents_AddParCharMethodIdx = i;\n        i = addMethod(PROFRUNTIME_CPU_CLASS_NAME, ADD_PARAMETER, CHAR_VOID_SIGNATURE, entries, i);\n        miContents_AddParByteMethodIdx = i;\n        i = addMethod(PROFRUNTIME_CPU_CLASS_NAME, ADD_PARAMETER, BYTE_VOID_SIGNATURE, entries, i);\n        miContents_AddParIntMethodIdx = i;\n        i = addMethod(PROFRUNTIME_CPU_CLASS_NAME, ADD_PARAMETER, INT_VOID_SIGNATURE, entries, i);\n        miContents_AddParBooleanMethodIdx = i;\n        i = addMethod(PROFRUNTIME_CPU_CLASS_NAME, ADD_PARAMETER, BOOLEAN_VOID_SIGNATURE, entries, i);\n        miContents_AddParFloatMethodIdx = i;\n        i = addMethod(PROFRUNTIME_CPU_CLASS_NAME, ADD_PARAMETER, FLOAT_VOID_SIGNATURE, entries, i);\n        miContents_AddParDoubleMethodIdx = i;\n        i = addMethod(PROFRUNTIME_CPU_CLASS_NAME, ADD_PARAMETER, DOUBLE_VOID_SIGNATURE, entries, i);\n        miContents_AddParShortMethodIdx = i;\n        i = addMethod(PROFRUNTIME_CPU_CLASS_NAME, ADD_PARAMETER, SHORT_VOID_SIGNATURE, entries, i);\n        miContents_AddParLongMethodIdx = i;\n        i = addMethod(PROFRUNTIME_CPU_CLASS_NAME, ADD_PARAMETER, LONG_VOID_SIGNATURE, entries, i);\n        miContents_AddParObjectMethodIdx = i;\n        addMethod(PROFRUNTIME_CPU_CLASS_NAME, ADD_PARAMETER, OBJECT_VOID_SIGNATURE, entries, i);\n        standardCPFragments[INJ_RECURSIVE_MARKER_METHOD] = new PackedCPFragment(entries);\n        rootContents_MarkerEntryMethodIdx = markerEntryMethodRefIdx;\n        rootContents_MarkerExitMethodIdx = markerExitMethodRefIdx;\n\n        // markerMethodEntry() injection for sampled instrumentation is the same as for full instrumentation\n        standardCPFragments[INJ_RECURSIVE_SAMPLED_MARKER_METHOD] = new PackedCPFragment(entries);\n\n        // Now initialize the constant pool contents added to class java.lang.reflect.Method, to support invoke() instrumentation    \n        entries = new CPEntry[6];\n        addMethod(PROFRUNTIME_CPU_CLASS_NAME, HANDLE_REFLECT_INVOKE_METHOD_NAME, REFLECT_METHOD_VOID_SIGNATURE, entries, 0);\n        standardCPFragments[INJ_REFLECT_METHOD_INVOKE] = new PackedCPFragment(entries);\n        miContents_HandleReflectInvokeMethodIdx = 0;\n\n        // Now initialize the constant pool contents added to class javax.servlet.http.HttpServlet , \n        // to support doGet(), doPost(), doPut(), doDelete() servlet tracking    \n        entries = new CPEntry[6];\n        addMethod(PROFRUNTIME_CPU_CLASS_NAME, HANDLE_SERVLET_DO_METHOD_NAME, OBJECT_VOID_SIGNATURE, entries, 0);\n        standardCPFragments[INJ_SERVLET_DO_METHOD] = new PackedCPFragment(entries);\n        miContents_HandleServletDoMethodIdx = 0;\n\n        // Initialize the constant pool contents used for code region profiling.\n        entries = new CPEntry[9];\n        i = 0;\n        int codeRegionEntryMethodRefIdx = i;\n        i = addMethod(PROFRUNTIME_CPUCODEREGION_CLASS_NAME, CODE_REGION_ENTRY_METHOD_NAME, VOID_VOID_SIGNATURE, entries, i);\n        int codeRegionExitMethodRefIdx = i;\n        addMethod(PROFRUNTIME_CPUCODEREGION_CLASS_NAME, CODE_REGION_EXIT_METHOD_NAME, VOID_VOID_SIGNATURE, entries, i);\n        standardCPFragments[INJ_CODE_REGION] = new PackedCPFragment(entries);\n        codeRegionContents_CodeRegionEntryMethodIdx = codeRegionEntryMethodRefIdx;\n        codeRegionContents_CodeRegionExitMethodIdx = codeRegionExitMethodRefIdx;\n\n        // Initialize the constant pool contents used for object allocation profiling\n        entries = new CPEntry[10];\n        i = 0;\n        int objAllocTraceMethodRefIdx = i;\n        i = addMethod(PROFRUNTIME_OBJALLOC_CLASS_NAME, TRACE_OBJ_ALLOC_METHOD_NAME, OBJECT_CHAR_VOID_SIGNATURE, entries, i);\n        int memPprofilePointHitMethodRefIdx = i;\n        addMethod(PROFRUNTIME_OBJALLOC_CLASS_NAME, PROFILE_POINT_HIT, CHAR_VOID_SIGNATURE, entries, i);\n        standardCPFragments[INJ_OBJECT_ALLOCATIONS] = new PackedCPFragment(entries);\n        memoryProfContents_TraceObjAllocMethodIdx = objAllocTraceMethodRefIdx;\n        memoryProfContents_ProfilePointHitMethodIdx = memPprofilePointHitMethodRefIdx;\n\n        // Create cpool contents for \"object liveness profiling\" code injection, by replacing just\n        // the instrumentation class name\n        entries[getUtf8CPEntryIndex(PROFRUNTIME_OBJALLOC_CLASS_NAME, entries)] = new CPEntry(PROFRUNTIME_OBJLIVENESS_CLASS_NAME);\n        standardCPFragments[INJ_OBJECT_LIVENESS] = new PackedCPFragment(entries);\n\n        /*memoryProfContents_TraceObjAllocMethodIdx = objAllocTraceMethodRefIdx;  // Same as above */\n        \n        entries = new CPEntry[1];\n        entries[0] = new CPEntry(STACK_MAP_TABLE_ATTRIBUTE);\n        standardCPFragments[INJ_STACKMAP] = new PackedCPFragment(entries);\n        \n        entries = new CPEntry[2];\n        addClass(JAVA_LANG_THROWABLE_NAME, entries, 0);\n        standardCPFragments[INJ_THROWABLE] = new PackedCPFragment(entries);\n\n    }\n    \n    static int addMethod(int classRefIdx, String methodName, int signatureIdx, CPEntry[] entries, int index) {\n        int methodRef = index;\n        entries[index++] = new CPEntry(CONSTANT_Methodref);\n        int nameAndTypeIdx = index;\n        index = addNameAndType(methodName, signatureIdx, entries, index);\n        entries[methodRef].setIndex1(classRefIdx);\n        entries[methodRef].setIndex2(nameAndTypeIdx);\n        return index;\n    }\n\n    static int addMethod(int classRefIdx, String methodName, String signature, CPEntry[] entries, int index) {\n        int methodRef = index;\n        entries[index++] = new CPEntry(CONSTANT_Methodref);\n        int nameAndTypeIdx = index;\n        index = addNameAndType(methodName, signature, entries, index);\n        entries[methodRef].setIndex1(classRefIdx);\n        entries[methodRef].setIndex2(nameAndTypeIdx);\n        return index;\n    }\n\n    static int addMethod(String className, String methodName, String signature, CPEntry[] entries, int index) {\n        int methodRef = index;\n        entries[index++] = new CPEntry(CONSTANT_Methodref);\n        int classIndex = getClassCPEntryIndex(className, entries);\n        if (classIndex == -1) {\n            classIndex = index;\n            index = addClass(className, entries, index);\n        }\n        int nameAndTypeIdx = index;\n        index = addNameAndType(methodName, signature, entries, index);\n        entries[methodRef].setIndex1(classIndex);\n        entries[methodRef].setIndex2(nameAndTypeIdx);\n        return index;\n    }\n    \n    static int addClass(String className, CPEntry[] entries, int index) {\n        entries[index] = new CPEntry(CONSTANT_Class);\n        entries[index].setIndex1(index+1);\n        entries[index+1] = new CPEntry(className);\n        return index+2;\n    }\n    \n    static int addNameAndType(String methodName, String signature, CPEntry[] entries, int index) {\n        int nameAndTypeIdx = index;\n        entries[index++] = new CPEntry(CONSTANT_NameAndType);\n        int nameIdx = getUtf8CPEntryIndex(methodName, entries);\n        if (nameIdx == -1) {\n            nameIdx = index;\n            entries[index++] = new CPEntry(methodName);\n        }\n        int sigIdx = getUtf8CPEntryIndex(signature, entries);\n        if (sigIdx == -1) {\n            sigIdx = index;\n            entries[index++] = new CPEntry(signature);\n        }\n        entries[nameAndTypeIdx].setIndex1(nameIdx);\n        entries[nameAndTypeIdx].setIndex2(sigIdx);\n        return index;\n    }\n\n    static int addNameAndType(String methodName, int signatureIdx, CPEntry[] entries, int index) {\n        entries[index] = new CPEntry(CONSTANT_NameAndType);\n        entries[index].setIndex1(index+1);\n        entries[index].setIndex2(signatureIdx);\n        entries[index+1] = new CPEntry(methodName);\n        return index+2;\n    }\n    \n    static boolean isUtf8CPEntry(CPEntry entry, String string) {\n        return  entry != null && entry.tag == CONSTANT_Utf8 && entry.utf8.equals(string);\n    }\n    \n    static int getUtf8CPEntryIndex(String string, CPEntry[] entries) {\n        for (int i = 0; i < entries.length; i++) {\n            if (isUtf8CPEntry(entries[i],string)) {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n    static int getClassCPEntryIndex(String string, CPEntry[] entries) {\n        for (int i = 0; i < entries.length; i++) {\n            CPEntry e = entries[i];\n            if (e != null && e.tag == CONSTANT_Class) {\n                if (isUtf8CPEntry(entries[e.index1],string)) {\n                    return i;                \n                }\n            }\n        }\n        return -1;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/ClassManager.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport java.io.IOException;\nimport java.util.*;\nimport org.graalvm.visualvm.lib.jfluid.classfile.*;\nimport org.graalvm.visualvm.lib.jfluid.client.RuntimeProfilingPoint;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.RootClassLoadedCommand;\n\n\n/**\n * Basic utility methods used by all scanner classes.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class ClassManager implements JavaClassConstants, CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final RuntimeProfilingPoint[] EMPTY_PROFILEPOINT_ARRAY = new RuntimeProfilingPoint[0];\n\n    /**\n     * Sorts profiling points by bytecode index so that injector can insert them sequentially.\n     */\n    private static Comparator ByBciComparator = new Comparator() {\n        public int compare(Object aa, Object bb) {\n            RuntimeProfilingPoint a = (RuntimeProfilingPoint) aa;\n            RuntimeProfilingPoint b = (RuntimeProfilingPoint) bb;\n\n            return a.getBci() - b.getBci();\n        }\n    };\n\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected ProfilingSessionStatus status;\n    protected ClassRepository classRepo;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    protected ClassManager(ClassRepository repo, ProfilingSessionStatus status) {\n        this.status = status;\n        classRepo = repo;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Filters profiling points for given class.\n     *\n     * @param points profiling points to scan\n     * @param classInfo searches for points in this class\n     * @return RuntimeProfilingPoint[] array of profiling points inside the specified method\n     */\n    protected RuntimeProfilingPoint[] getRuntimeProfilingPoints(RuntimeProfilingPoint[] points, ClassInfo classInfo) {\n        List newPoints = null;\n\n        String className = classInfo.getName().replace('/', '.'); // NOI18N\n        for (RuntimeProfilingPoint point : points) {\n            if (className.equals(point.getClassName()) && point.resolve(classRepo, classInfo)) {\n                if (newPoints == null) {\n                    newPoints = new ArrayList(2);\n                }\n\n                newPoints.add(point);\n            }\n        }\n\n        if (newPoints == null) {\n            return EMPTY_PROFILEPOINT_ARRAY;\n        }\n\n        return (RuntimeProfilingPoint[]) newPoints.toArray(new RuntimeProfilingPoint[0]);\n    }\n\n    /**\n     * Filters profiling points for given method.\n     *\n     * @param points profiling points to scan\n     * @param methodIdx method index in the given class\n     * @return RuntimeProfilingPoint[] array of profiling points inside the specified method\n     */\n    protected static RuntimeProfilingPoint[] getRuntimeProfilingPoints(RuntimeProfilingPoint[] points, int methodIdx) {\n        List newPoints = null;\n\n        for (RuntimeProfilingPoint point : points) {\n            if (point.getMethodIdx() == methodIdx) {\n                if (newPoints == null) {\n                    newPoints = new ArrayList(2);\n                }\n\n                newPoints.add(point);\n            }\n        }\n\n        if (newPoints == null) {\n            return EMPTY_PROFILEPOINT_ARRAY;\n        } else if (newPoints.size() > 1) {\n            Collections.sort(newPoints, ByBciComparator);\n        }\n\n        return (RuntimeProfilingPoint[]) newPoints.toArray(new RuntimeProfilingPoint[0]);\n    }\n\n    /**\n     * Filters profiling points for given class and method.\n     *\n     * @param points profiling points to scan\n     * @param classInfo searches for points in this class\n     * @param methodIdx method index in the given class\n     * @return RuntimeProfilingPoint[] array of profiling points inside the specified method\n     */\n    protected RuntimeProfilingPoint[] getRuntimeProfilingPoints(RuntimeProfilingPoint[] points, ClassInfo classInfo,\n                                                                       int methodIdx) {\n        List newPoints = null;\n        String className = classInfo.getName().replace('/', '.'); // NOI18N\n        for (RuntimeProfilingPoint point : points) {\n            if (className.equals(point.getClassName())) {\n                if (point.resolve(classRepo, classInfo)) {\n                    if (point.getMethodIdx() == methodIdx) {\n                        if (newPoints == null) {\n                            newPoints = new ArrayList(2);\n                        }\n\n                        newPoints.add(point);\n                    }\n                }\n            }\n        }\n\n        if (newPoints == null) {\n            return EMPTY_PROFILEPOINT_ARRAY;\n        } else if (newPoints.size() > 1) {\n            Collections.sort(newPoints, ByBciComparator);\n        }\n\n        return (RuntimeProfilingPoint[]) newPoints.toArray(new RuntimeProfilingPoint[0]);\n    }\n\n    /**\n     * Returns a ClassInfo for a given non-array class name. If actualCPLength &gt;= 0 is provided, the constant\n     * pool length in the returned ClassInfo is set to that value. Otherwise it is not touched, i.e. remains\n     * the same as for the .class file on the CLASSPATH.\n     */\n    protected DynamicClassInfo javaClassForName(String className, int classLoaderId) {\n        try {\n            return classRepo.lookupClass(className, classLoaderId);\n        } catch (IOException ex2) {\n            MiscUtils.printWarningMessage(\"Error reading class \" + className); // NOI18N\n            MiscUtils.printWarningMessage(ex2.getMessage());\n        } catch (ClassFormatError er) {\n            MiscUtils.printWarningMessage(er.getMessage());\n        }\n\n        return null;\n    }\n\n    protected BaseClassInfo javaClassForObjectArrayType(String elementTypeName) {\n        return classRepo.lookupSpecialClass(\"[\" + elementTypeName); // NOI18N\n    }\n\n    protected BaseClassInfo javaClassForPrimitiveArrayType(int arrayTypeId) {\n        return classRepo.lookupSpecialClass(PRIMITIVE_ARRAY_TYPE_NAMES[arrayTypeId]);\n    }\n\n    protected BaseClassInfo lookupSpecialClass(String className) {\n        return classRepo.lookupSpecialClass(className);\n    }\n\n    protected Enumeration getClassEnumerationWithAllVersions() {\n        return classRepo.getClassEnumerationWithAllVersions();\n    }\n\n    protected List getAllClassVersions(String className) {\n        return classRepo.getAllClassVersions(className);\n    }\n\n    /** This is currently used only in memory profiling */\n    protected BaseClassInfo javaClassOrPlaceholderForName(String className, int classLoaderId) {\n        return classRepo.lookupClassOrCreatePlaceholder(className, classLoaderId);\n    }\n\n    protected BaseClassInfo loadedJavaClassOrExistingPlaceholderForName(String className, int classLoaderId) {\n        return classRepo.lookupLoadedClass(className, classLoaderId, true);\n    }\n\n    protected void registerPlaceholder(PlaceholderClassInfo pci) {\n        classRepo.addClassInfo(pci);\n    }\n\n    protected void resetLoadedClassData() {\n        classRepo.clearCache();\n    }\n\n    /**\n     * Given a list of classes (normally all classes currently loaded by the JVM), determine those that are loaded using\n     * custom classloaders, get their cached bytecodes from the JVM, and put them into ClassRepository.\n     */\n    protected void storeClassFileBytesForCustomLoaderClasses(RootClassLoadedCommand rootLoaded) {\n        String[] loadedClasses = rootLoaded.getAllLoadedClassNames();\n        byte[][] cachedClassFileBytes = rootLoaded.getCachedClassFileBytes();\n        int[] loadedClassLoaderIds = rootLoaded.getAllLoadedClassLoaderIds();\n        int[] superClasses = rootLoaded.getAllLoaderSuperClassIds();\n        int[][] interfaceNames = rootLoaded.getAllLoadedInterfaceIds();\n        int nClasses = loadedClasses.length;\n        Set allInterfacesIndexes = new HashSet();\n\n        for (int i = 0; i < nClasses; i++) {\n            if (cachedClassFileBytes[i] != null) {\n                String name = loadedClasses[i];\n                int loaderId = loadedClassLoaderIds[i];\n                byte[] bytes = cachedClassFileBytes[i];\n                if (bytes != null && bytes.length == 0) {\n                    String superClass;\n                    int sidx = superClasses[i];\n                    if (sidx != -1 ) {\n                        superClass = loadedClasses[sidx];\n                    } else {\n                        superClass = OBJECT_SLASHED_CLASS_NAME;\n                    }\n                    int[] interfaceNamedIdxs = interfaceNames[i];\n                    List interfaces = new ArrayList();\n                    for (int j = 0; j < interfaceNamedIdxs.length; j++) {\n                        int iidx = interfaceNamedIdxs[j];\n                        if (iidx != -1) {\n                            interfaces.add(loadedClasses[iidx]);\n                            allInterfacesIndexes.add(Integer.valueOf(iidx));\n                        }\n                    }\n                    classRepo.addVMSuppliedClassFile(name, loaderId, bytes, superClass, (String[])interfaces.toArray(new String[0]));\n                } else {\n                    classRepo.addVMSuppliedClassFile(name, loaderId, bytes);\n                }\n            }\n        }\n        // set interfaces\n        for (Object intIndex : allInterfacesIndexes) {\n            int iidx = ((Integer)intIndex).intValue();\n            if (cachedClassFileBytes[iidx] != null) {\n                DynamicClassInfo iface = javaClassForName(loadedClasses[iidx], loadedClassLoaderIds[iidx]);\n                iface.setInterface();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/ClassRewriter.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport java.io.IOException;\nimport java.io.OutputStream;\n\n\n/**\n * This class contains functionality to rewrite a given complete class file, replacing given\n * methodinfos and appending the constant pool.\n *\n * @author  Misha Dmitriev\n */\npublic class ClassRewriter {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static byte[] rewriteClassFile(DynamicClassInfo clazz, byte[][] replacementMethodInfos, int nAddedCPEntries,\n                                          byte[] addedCPContents) {\n        // Now assemble a new class file. First get original class file bytes.\n        byte[] origBytes = null;\n\n        try {\n            origBytes = clazz.getClassFileBytes();\n        } catch (IOException ex) {\n            // Shouldn't happen, so a message just in case\n            MiscUtils.internalError(\"ClassRewriter: can't get original class file bytes for class \" + clazz.getName()\n                                    + \"\\nIOException message = \" + ex.getMessage()); // NOI18N\n        }\n\n        // Compute new class file length.\n        int newLen = origBytes.length;\n\n        // First add new constant pool size\n        newLen += addedCPContents.length;\n\n        // Now add differences between new and old method sizes\n        int nMethods = clazz.getMethodNames().length;\n\n        for (int i = 0; i < nMethods; i++) {\n            if (replacementMethodInfos[i] != null) {\n                newLen += (replacementMethodInfos[i].length - clazz.getOrigMethodInfoLength(i));\n            }\n        }\n\n        byte[] res = new byte[newLen];\n\n        // Copy over unchanged contents from old class file, copy/add changed contents, and adjust some counts\n        int destPos = 0;\n        // Copy preamble and original constant pool unchanged\n        System.arraycopy(origBytes, 0, res, destPos, clazz.getOrigIntermediateDataStartOfs());\n        destPos += clazz.getOrigIntermediateDataStartOfs();\n        // Copy our new constant pool extension\n        System.arraycopy(addedCPContents, 0, res, destPos, addedCPContents.length);\n        destPos += addedCPContents.length;\n\n        // Adjust the cpool count\n        int newCPCount = clazz.getOrigCPoolCount() + nAddedCPEntries;\n        int pos = clazz.getOrigCPoolStartOfs();\n        res[pos] = (byte) ((newCPCount >> 8) & 255);\n        res[pos + 1] = (byte) (newCPCount & 255);\n\n        // Copy intermediate data and fields unchanged\n        int count = clazz.getOrigMethodsStartOfs() - clazz.getOrigIntermediateDataStartOfs();\n        System.arraycopy(origBytes, clazz.getOrigIntermediateDataStartOfs(), res, destPos, count);\n        destPos += count;\n\n        // Now copy all new methodInfos. First write the method count\n        res[destPos] = (byte) ((nMethods >> 8) & 255);\n        res[destPos + 1] = (byte) (nMethods & 255);\n        destPos += 2;\n\n        // Write methodInfos\n        for (int i = 0; i < nMethods; i++) {\n            if (replacementMethodInfos[i] != null) {\n                System.arraycopy(replacementMethodInfos[i], 0, res, destPos, replacementMethodInfos[i].length);\n                destPos += replacementMethodInfos[i].length;\n            } else {\n                byte[] origMethodInfo = clazz.getOrigMethodInfo(i);\n                System.arraycopy(origMethodInfo, 0, res, destPos, origMethodInfo.length);\n                destPos += origMethodInfo.length;\n            }\n        }\n\n        // Copy what remains - class attributes\n        count = origBytes.length - clazz.getOrigAttrsStartOfs();\n        System.arraycopy(origBytes, clazz.getOrigAttrsStartOfs(), res, destPos, count);\n        clazz.resetTables();\n\n        // For debugging\n        //if (clazz.getName().equals(\"profilertestapp/Main\")) {\n        //  saveClassFileToDisk(clazz, res);\n        //}\n        return res;\n    }\n\n    public static void saveToDisk(String name, byte[] classBytes) {\n        if (Platform.getJDKVersionNumber() == Platform.JDK_CVM) {\n            // No room on device to do this\n            return;\n        }\n        name = name.replace('/', '_'); // NOI18N\n\n        System.err.print(\"*** Gonna save bytecode \" + name + \" to disk... \"); // NOI18N\n        try (OutputStream out = new FileOutputStream(new File(name + \".class\"))) { // NOI18N\n            out.write(classBytes);\n        } catch (IOException ex) {\n            System.err.println(\"*** In RecursiveMethodInstrumentor.saveClassFileToDisk caught ex = \" + ex); // NOI18N\n        }\n        System.err.println(\"done\"); // NOI18N\n    }\n\n    private static void saveClassFileToDisk(DynamicClassInfo clazz, byte[] replacementClassFile) {\n        saveToDisk(clazz.getName(), replacementClassFile);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/CodeRegionEntryExitCallsInjector.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n\n/**\n * Specialized subclass of Injector, that provides injection of our standard Code Region instrumentation -\n * codeRegionEntry() and codeRegionExit() calls - in appropriate places.\n *\n * @author Misha Dmitriev\n */\nclass CodeRegionEntryExitCallsInjector extends Injector implements CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // Stuff used for codeRegionEntry() and codeRegionExit() injection\n    protected static byte[] injectedCode;\n    protected static int injectedCodeLen;\n    protected static int injectedCodeMethodIdxPos;\n\n    static {\n        initializeInjectedCode();\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected int bci0; // Original code region bounds\n    protected int bci1; // Original code region bounds\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    CodeRegionEntryExitCallsInjector(DynamicClassInfo clazz, int baseCPoolCount, int methodIdx, int bci0, int bci1) {\n        super(clazz, methodIdx);\n        this.baseCPoolCount = baseCPoolCount;\n        this.bci0 = bci0;\n        this.bci1 = bci1;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public byte[] instrumentMethod() {\n        // Determine the index (among return instructions) of first return within the given code region, total number of returns between\n        // bci = 0 and bci1, and the original index of the last instruction within this region.\n        int firstRetIdx = -1;\n        int totalReturns = 0;\n        int lastInstrIdx = -1;\n        int bci = 0;\n\n        while (bci <= bci1) {\n            int bc = bytecodes[bci] & 0xFF;\n            lastInstrIdx++;\n\n            if ((bc >= opc_ireturn) && (bc <= opc_return)) {\n                if ((bci >= bci0) && (firstRetIdx == -1)) {\n                    firstRetIdx = totalReturns;\n                }\n\n                totalReturns++;\n            }\n\n            bci += opcodeLength(bci);\n        }\n\n        injectCodeRegionEntry();\n        lastInstrIdx += 2; // Since we added two opcodes in the above operation\n        injectCodeRegionExits(firstRetIdx, totalReturns, lastInstrIdx);\n\n        return createPackedMethodInfo();\n    }\n\n    private static void initializeInjectedCode() {\n        // Code packet for codeRegionEntry()/codeRegionExit()\n        injectedCodeLen = 4;\n        injectedCode = new byte[injectedCodeLen];\n        injectedCode[0] = (byte) opc_invokestatic;\n        // Positions 1, 2 are occupied by method index\n        injectedCodeMethodIdxPos = 1;\n        injectedCode[3] = (byte) opc_nop;\n    }\n\n    private void injectCodeRegionEntry() {\n        int targetMethodIdx = CPExtensionsRepository.codeRegionContents_CodeRegionEntryMethodIdx + baseCPoolCount;\n        putU2(injectedCode, injectedCodeMethodIdxPos, targetMethodIdx);\n\n        injectCodeAndRewrite(injectedCode, injectedCodeLen, bci0, true);\n    }\n\n    private void injectCodeRegionExits(int firstRetIdx, int totalReturns, int lastInstrIdx) {\n        // Prepare the codeRegionExit() code packet\n        int targetMethodIdx = CPExtensionsRepository.codeRegionContents_CodeRegionExitMethodIdx + baseCPoolCount;\n        putU2(injectedCode, injectedCodeMethodIdxPos, targetMethodIdx);\n\n        int curInstrIdx = -1;\n\n        if (firstRetIdx != -1) { // There is a corner case when a method has no returns at all - e.g. when it contains just a \"while (true)\" loop\n                                 // Inject codeRegionExit() before each return inside the selected fragment\n\n            for (int inFragmentRetIndex = firstRetIdx; inFragmentRetIndex < totalReturns; inFragmentRetIndex++) {\n                int curRetIdx = -1;\n                curInstrIdx = -1;\n\n                int bci = 0;\n\n                while (bci < bytecodesLength) {\n                    curInstrIdx++;\n\n                    int bc = bytecodes[bci] & 0xFF;\n\n                    if ((bc >= opc_ireturn) && (bc <= opc_return)) {\n                        curRetIdx++;\n\n                        if (curRetIdx == inFragmentRetIndex) {\n                            injectCodeAndRewrite(injectedCode, injectedCodeLen, bci, true);\n                            lastInstrIdx += 2;\n\n                            break;\n                        }\n                    }\n\n                    bci += opcodeLength(bci);\n                }\n            }\n        }\n\n        // Inject the call at the last bytecode, which may be anything\n        if (curInstrIdx == lastInstrIdx) {\n            return;\n        }\n\n        curInstrIdx = -1;\n\n        int bci = 0;\n\n        while (bci < bytecodesLength) {\n            curInstrIdx++;\n\n            if (curInstrIdx >= lastInstrIdx) {\n                injectCodeAndRewrite(injectedCode, injectedCodeLen, bci, true);\n\n                break;\n            }\n\n            bci += opcodeLength(bci);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/CodeRegionMethodInstrumentor.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository.CodeRegionBCI;\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils.SourceCodeSelection;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.RootClassLoadedCommand;\n\n\n/**\n * High-level access to functionality that instruments a (so far single) code region in a (single again) TA method.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class CodeRegionMethodInstrumentor extends ClassManager {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ClientUtils.SourceCodeSelection sourceCodeSelection;\n    private ArrayList instrClasses;\n    private String className;\n    private int nInstrClasses;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CodeRegionMethodInstrumentor(ClassRepository repo, ProfilingSessionStatus status, SourceCodeSelection codeSelection) {\n        super(repo, status);\n        sourceCodeSelection = codeSelection;\n        className = sourceCodeSelection.getClassName().replace('.', '/').intern(); // NOI18N\n        instrClasses = new ArrayList();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Object[] getFollowUpInstrumentCodeRegionResponse(int classLoaderId) {\n        DynamicClassInfo clazz = javaClassForName(className, classLoaderId);\n\n        instrClasses.clear();\n        instrClasses.add(clazz);\n        nInstrClasses = 1;\n\n        return createInstrumentedMethodPack();\n    }\n\n    protected Object[] createInstrumentedMethodPack() {\n        if (nInstrClasses == 0) {\n            return null;\n        }\n\n        return createInstrumentedMethodPack15();\n    }\n\n    Object[] getInitialInstrumentCodeRegionResponse(RootClassLoadedCommand rootLoaded) {\n        String[] loadedClasses = rootLoaded.getAllLoadedClassNames();\n        int[] loadedClassLoaderIds = rootLoaded.getAllLoadedClassLoaderIds();\n        DynamicClassInfo clazz = null;\n\n        storeClassFileBytesForCustomLoaderClasses(rootLoaded);\n         // We may have more than one version of the class with the given name, hence this search and instrClasses array\n        for (int i = 0; i < loadedClasses.length; i++) {\n            String loadedClassName = loadedClasses[i];\n\n            if (className == loadedClassName) {\n                clazz = javaClassForName(loadedClasses[i], loadedClassLoaderIds[i]);\n\n                if (clazz != null) {\n                    CodeRegionBCI instrLocation = computeCodeRegionFromSourceCodeSelection(clazz);\n\n                    if (instrLocation != null) {\n                        int mIdx = clazz.getMethodIndex(instrLocation.methodName, instrLocation.methodSignature);\n\n                        if (mIdx != -1) { // Not all class versions may have this method\n                            clazz.setLoaded(true);\n                            instrClasses.add(clazz);\n                        }\n                    }\n                }\n            }\n        }\n\n        nInstrClasses = instrClasses.size();\n\n        return createInstrumentedMethodPack();\n    }\n\n    private CodeRegionBCI computeCodeRegionFromSourceCodeSelection(ClassInfo clazz) {\n        try {\n            if (sourceCodeSelection.definedViaSourceLines()) {\n                int startLine = sourceCodeSelection.getStartLine();\n                int endLine = sourceCodeSelection.getEndLine();\n                CodeRegionBCI loc = classRepo.getMethodForSourceRegion(clazz, startLine, endLine);\n\n                status.beginTrans(true);\n\n                try {\n                    status.setInstrMethodNames(new String[] { loc.methodName });\n                    status.setInstrMethodSignatures(new String[] { loc.methodSignature });\n                } finally {\n                    status.endTrans();\n                }\n\n                return loc;\n            } else if (sourceCodeSelection.definedViaMethodName()) {\n                String methodName = sourceCodeSelection.getMethodName();\n                String methodSignature = sourceCodeSelection.getMethodSignature();\n\n                return ClassRepository.getMethodMinAndMaxBCI(clazz, methodName, methodSignature);\n            }\n        } catch (IOException ex) {\n            MiscUtils.printErrorMessage(ex.getMessage());\n        } catch (BadLocationException ex) {\n            MiscUtils.printErrorMessage(ex.getMessage());\n        } catch (ClassNotFoundException ex) {\n            MiscUtils.printErrorMessage(ex.getMessage());\n        }\n\n        return null;\n    }\n\n    /** Creates the 1.5-style array of instrumented class files. */\n    private Object[] createInstrumentedMethodPack15() {\n        String[] instrMethodClasses = new String[nInstrClasses];\n        int[] instrClassLoaderIds = new int[nInstrClasses];\n        byte[][] replacementClassFileBytes = new byte[nInstrClasses][];\n\n        for (int j = 0; j < nInstrClasses; j++) {\n            DynamicClassInfo clazz = (DynamicClassInfo) instrClasses.get(j);\n            instrMethodClasses[j] = clazz.getName().replace('/', '.'); // NOI18N\n            instrClassLoaderIds[j] = clazz.getLoaderId();\n\n            CodeRegionBCI instrLocation = computeCodeRegionFromSourceCodeSelection(clazz);\n            int mIdx = clazz.getMethodIndex(instrLocation.methodName, instrLocation.methodSignature); // TODO CHECK: local variable hides member variable\n            clazz.setMethodInstrumented(mIdx);\n\n            DynamicConstantPoolExtension ecp = DynamicConstantPoolExtension.getCPFragment(clazz, INJ_CODE_REGION);\n            byte[] newMethodInfo = InstrumentationFactory.instrumentCodeRegion(clazz, mIdx, instrLocation.bci0, instrLocation.bci1);\n\n            int nMethods = clazz.getMethodNames().length;\n            byte[][] replacementMethodInfos = new byte[nMethods][];\n\n            for (int i = 0; i < nMethods; i++) {\n                replacementMethodInfos[i] = clazz.getMethodInfo(i);\n            }\n\n            replacementMethodInfos[mIdx] = newMethodInfo;\n\n            int nAddedCPEntries = ecp.getNEntries();\n            byte[] addedCPContents = ecp.getContents();\n            replacementClassFileBytes[j] = ClassRewriter.rewriteClassFile(clazz, replacementMethodInfos, nAddedCPEntries,\n                                                                          addedCPContents);\n        }\n\n        return new Object[] { instrMethodClasses, instrClassLoaderIds, replacementClassFileBytes };\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/ConstantPoolExtension.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\n\n/**\n * Basic support for adding entries to a class's constant pool.\n * This class allows one to create a semi-prepared chunk of bytes (class PackedCPoolFragment) representing entries that\n * should be added to the constant pool of an arbitrary class. Then, by passing a PackedCPoolFragment to the constructor\n * of ConstantPoolExtension, one obtains a relocated (i.e. with indices adjusted for a concrete class' existing constant pool)\n * copy of added constant pool.\n *\n * @author Misha Dmitriev\n */\npublic class ConstantPoolExtension implements JavaClassConstants {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    //------------------------------------------ Helper classes -------------------------------------------------\n    public static class CPEntry {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        String utf8;\n        byte tag;\n        int index1;\n        int index2;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public CPEntry(int tag) {\n            this.tag = (byte) tag;\n        }\n\n        public CPEntry(String utf8) {\n            this.tag = CONSTANT_Utf8;\n            this.utf8 = utf8;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void setIndex1(int idx) {\n            index1 = idx;\n        }\n\n        public void setIndex2(int idx) {\n            index2 = idx;\n        }\n    }\n\n    /**\n     * Represents an array of bytes containing constant pool contents to append to the real constant pool, in the unrelocated\n     * form. Entries in this cpool fragment may point either to other entries within the same cpool fragment (internalIndicies\n     * array), or to entries in one other cpool fragment (externalIndices array). In either case indices are relative to the\n     * origin of the corresponding cpool fragment. By calling getRelocatedCPoolBytes(intBaseIndex, extBaseIndex), one gets the real\n     * constant pool added contents, with all indices relocated, i.e. pointing at correct absolute locations in the concrete class'\n     * constant pool.\n     */\n    public static class PackedCPFragment {\n        //~ Static fields/initializers -------------------------------------------------------------------------------------------\n\n        private static byte[] tmpBytes = new byte[96];\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        int nEntries;\n        private byte[] cpoolBytes; // Non-relocated cpool bytes\n        private char[] externalIndices; // Positions of all u2 indices in the above array, that need to be adjusted\n        private char[] internalIndices; // Positions of all u2 indices in the above array, that need to be adjusted\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public PackedCPFragment(CPEntry[] entries) {\n            nEntries = entries.length;\n\n            // First compute the packed size and the number of indices that would need adjustment\n            int packedSize = 0;\n            int nIntIdx = 0;\n            int nExtIdx = 0;\n\n            for (int i = 0; i < nEntries; i++) {\n                switch (entries[i].tag) {\n                    case CONSTANT_Class:\n                        packedSize += 3;\n\n                        if (entries[i].index1 <= 0xFFFF) {\n                            nIntIdx++;\n                        } else {\n                            nExtIdx++;\n                        }\n\n                        break;\n                    case CONSTANT_Fieldref:\n                    case CONSTANT_Methodref:\n                    case CONSTANT_InterfaceMethodref:\n                    case CONSTANT_NameAndType:\n                        packedSize += 5;\n\n                        if (entries[i].index1 <= 0xFFFF) {\n                            nIntIdx++;\n                        } else {\n                            nExtIdx++;\n                        }\n\n                        if (entries[i].index2 <= 0xFFFF) {\n                            nIntIdx++;\n                        } else {\n                            nExtIdx++;\n                        }\n\n                        break;\n                    case CONSTANT_Utf8:\n                        packedSize += (3 + entries[i].utf8.length());\n\n                        break;\n                    default:\n                        System.err.println(\"*** PackedAddedCPool : unsupported constant!\"); // NOI18N\n                }\n            }\n\n            cpoolBytes = new byte[packedSize];\n            internalIndices = new char[nIntIdx];\n            externalIndices = new char[nExtIdx];\n\n            int curPos = 0;\n            nIntIdx = 0;\n            nExtIdx = 0;\n\n            for (int i = 0; i < nEntries; i++) {\n                switch (entries[i].tag) {\n                    case CONSTANT_Class:\n                        cpoolBytes[curPos++] = entries[i].tag;\n\n                        if (entries[i].index1 <= 0xFFFF) {\n                            internalIndices[nIntIdx++] = (char) curPos;\n                        } else {\n                            externalIndices[nExtIdx++] = (char) curPos;\n                        }\n\n                        cpoolBytes[curPos++] = (byte) ((entries[i].index1 >> 8) & 0xFF);\n                        cpoolBytes[curPos++] = (byte) ((entries[i].index1) & 0xFF);\n\n                        break;\n                    case CONSTANT_Fieldref:\n                    case CONSTANT_Methodref:\n                    case CONSTANT_InterfaceMethodref:\n                    case CONSTANT_NameAndType:\n                        cpoolBytes[curPos++] = entries[i].tag;\n\n                        if (entries[i].index1 <= 0xFFFF) {\n                            internalIndices[nIntIdx++] = (char) curPos;\n                        } else {\n                            externalIndices[nExtIdx++] = (char) curPos;\n                        }\n\n                        cpoolBytes[curPos++] = (byte) ((entries[i].index1 >> 8) & 0xFF);\n                        cpoolBytes[curPos++] = (byte) ((entries[i].index1) & 0xFF);\n\n                        if (entries[i].index2 <= 0xFFFF) {\n                            internalIndices[nIntIdx++] = (char) curPos;\n                        } else {\n                            externalIndices[nExtIdx++] = (char) curPos;\n                        }\n\n                        cpoolBytes[curPos++] = (byte) ((entries[i].index2 >> 8) & 0xFF);\n                        cpoolBytes[curPos++] = (byte) ((entries[i].index2) & 0xFF);\n\n                        break;\n                    case CONSTANT_Utf8:\n                        cpoolBytes[curPos++] = entries[i].tag;\n\n                        String utf8 = entries[i].utf8;\n                        int len = utf8.length();\n                        cpoolBytes[curPos++] = (byte) ((len >> 8) & 0xFF);\n                        cpoolBytes[curPos++] = (byte) ((len) & 0xFF);\n\n                        for (int j = 0; j < len; j++) {\n                            tmpBytes[j] = (byte) utf8.charAt(j);\n                        }\n\n                        System.arraycopy(tmpBytes, 0, cpoolBytes, curPos, len);\n                        curPos += len;\n\n                        break;\n                    default:\n                        System.err.println(\"*** PackedAddedCPool : unsupported constant!\"); // NOI18N\n                }\n            }\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public byte[] getRelocatedCPBytes(int intBaseIndex, int extBaseIndex) {\n            byte[] ret = new byte[cpoolBytes.length];\n            System.arraycopy(cpoolBytes, 0, ret, 0, cpoolBytes.length);\n\n            for (int i = 0; i < internalIndices.length; i++) {\n                int pos = internalIndices[i];\n                int value = getU2(ret, pos);\n                value += intBaseIndex;\n                putU2(ret, pos, value);\n            }\n\n            for (int i = 0; i < externalIndices.length; i++) {\n                int pos = externalIndices[i];\n                int value = getU2(ret, pos);\n                value += extBaseIndex;\n                putU2(ret, pos, value);\n            }\n\n            return ret;\n        }\n    }\n\n    private static int getU2(byte[] buf, int pos) {\n        return ((buf[pos] & 0xFF) << 8) + (buf[pos + 1] & 0xFF);\n    }\n    \n    private static void putU2(byte[] buf, int pos, int value) {\n        buf[pos] = (byte) ((value >> 8) & 0xFF);\n        buf[pos + 1] = (byte) (value & 0xFF);\n    }\n    \n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected byte[] addedCPContents;\n    protected int nAddedEntries;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    //----------------------------------------- Protected methods ---------------------------------------------------\n\n    /** Creates a ConstantPoolExtension containing properly relocated contents from pcp. */\n    protected ConstantPoolExtension(PackedCPFragment pcp, int baseCPCount, int secondaryBaseCPCount) {\n        addedCPContents = pcp.getRelocatedCPBytes(baseCPCount, secondaryBaseCPCount);\n        nAddedEntries = pcp.nEntries;\n    }\n\n    protected ConstantPoolExtension() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public byte[] getConcatenatedContents(ConstantPoolExtension other) {\n        if (this.addedCPContents == null) {\n            return other.getContents();\n        } else if (other.addedCPContents == null) {\n            return this.getContents();\n        } else {\n            byte[] ret = new byte[this.addedCPContents.length + other.addedCPContents.length];\n            System.arraycopy(this.addedCPContents, 0, ret, 0, this.addedCPContents.length);\n            System.arraycopy(other.addedCPContents, 0, ret, this.addedCPContents.length, other.addedCPContents.length);\n\n            return ret;\n        }\n    }\n\n    public byte[] getContents() {\n        return addedCPContents;\n    }\n\n    //-------------------------------------- Public interface --------------------------------------------------------\n    public int getNEntries() {\n        return nAddedEntries;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/DynamicConstantPoolExtension.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n\n/**\n * Support for adding multiple different fragments to a class's constant pool, that also keeps track of whether\n * a particular fragment has already been added to this class or not.\n * The main API call for this class is getCPFragment, that returns a relocated (i.e. with indices adjusted for a concrete\n * given class) copy of added constant pool for particular injection type defined in JFluid. Once this operation is\n * performed, the information is registered in the corresponding ClassInfo (it is assumed that a real class in the JVM is\n * actually instrumented by adding this cpool fragment). Thus if subsequently for this class the constant pool fragment\n * for the same injection type is requested again, an empty result is returned.\n *\n * When performing actual method instrumentation (bytecode rewriting), use cpool indices of injected methods defined as\n * public static variables in CPExtensionsRepository. These variables need to be adjusted for the base cpool count value\n * for the given class/injection type.\n *\n * @author Misha Dmitriev\n */\npublic class DynamicConstantPoolExtension extends ConstantPoolExtension implements CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    //------------------------------------------ Private implementation -------------------------------------------------\n    private static DynamicConstantPoolExtension emptyECP = new DynamicConstantPoolExtension();\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected DynamicClassInfo clazz;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    protected DynamicConstantPoolExtension(DynamicClassInfo clazz, int injectionType, int baseCPCount, int secondaryCPCount) {\n        super(CPExtensionsRepository.getStandardCPFragment(injectionType), baseCPCount, secondaryCPCount);\n        this.clazz = clazz;\n    }\n\n    protected DynamicConstantPoolExtension() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Re-create the whole appended constant pool chunk out of (possibly several) fragments added for different\n     * kinds of instrumentation at possibly different times.\n     */\n    public static DynamicConstantPoolExtension getAllAddedCPFragments(DynamicClassInfo clazz) {\n        DynamicConstantPoolExtension res = new DynamicConstantPoolExtension(); // Equivalent of emptyECP\n        int lowerBaseCPCountBound = 0;\n        int baseCPCLen = clazz.getBaseCPoolCountLen();\n\n        for (int j = 0; j < baseCPCLen; j++) {\n            int minBaseCPCount = 0xFFFFFFF;\n            int cpFragmentIdx = -1;\n\n            // Find the CP fragment with the minimum base index, that hasn't been used yet\n            for (int i = 0; i < baseCPCLen; i++) {\n                int curCPCount = clazz.getBaseCPoolCount(i);\n\n                if (curCPCount != -1) {\n                    if ((curCPCount > lowerBaseCPCountBound) && (curCPCount < minBaseCPCount)) {\n                        minBaseCPCount = curCPCount;\n                        cpFragmentIdx = i;\n                    }\n                }\n            }\n\n            // If such a fragment exists, append it to the result. Otherwise return the final result.\n            if (cpFragmentIdx != -1) {\n                DynamicConstantPoolExtension res1 = newDynamicCPExtension(clazz, cpFragmentIdx,\n                                                                          clazz.getBaseCPoolCount(cpFragmentIdx));\n                res.addedCPContents = res.getConcatenatedContents(res1); // Don't change res contents, because initially it's emptyECP\n                res.nAddedEntries += res1.nAddedEntries;\n                lowerBaseCPCountBound = minBaseCPCount;\n            } else {\n                return res;\n            }\n        }\n\n        return res;\n    }\n\n    public static DynamicConstantPoolExtension getCPFragment(DynamicClassInfo clazz, int injType) {\n        if (clazz.getBaseCPoolCount(injType) != -1) {\n            return emptyECP; // clazz's cpool already extended for this instrumentation type\n        } else {\n            int currentCPCount = clazz.getCurrentCPoolCount();\n            DynamicConstantPoolExtension ecp = newDynamicCPExtension(clazz, injType, currentCPCount);\n            clazz.setBaseCPoolCount(injType, currentCPCount);\n            clazz.setCurrentCPoolCount(currentCPCount + ecp.nAddedEntries);\n\n            return ecp;\n        }\n    }\n\n    public static DynamicConstantPoolExtension getEmptyCPFragment() {\n        return emptyECP;\n    }\n\n    //-------------------------------------------- Protected methods ---------------------------------------------------\n    protected static DynamicConstantPoolExtension newDynamicCPExtension(DynamicClassInfo clazz, int injectionType, int baseCPCount) {\n        int secondaryCPCount = 0;\n\n        switch (injectionType) {\n            case INJ_RECURSIVE_ROOT_METHOD:\n            case INJ_RECURSIVE_MARKER_METHOD:\n                secondaryCPCount = clazz.getBaseCPoolCount(INJ_RECURSIVE_NORMAL_METHOD);\n\n                break;\n            case INJ_RECURSIVE_SAMPLED_ROOT_METHOD:\n            case INJ_RECURSIVE_SAMPLED_MARKER_METHOD:\n                secondaryCPCount = clazz.getBaseCPoolCount(INJ_RECURSIVE_SAMPLED_NORMAL_METHOD);\n\n                break;\n        }\n\n        return new DynamicConstantPoolExtension(clazz, injectionType, baseCPCount, secondaryCPCount);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/HandleReflectInvokeCallInjector.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\n\n\n/**\n * Specialized subclass of Injector, that provides injection of our standard handleJavaLangReflectMethodInvoke(Method method)\n * call into the java.lang.reflect.Method.invoke() method.\n *\n *  @author Misha Dmitriev\n */\nclass HandleReflectInvokeCallInjector extends SpecialCallInjector {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HandleReflectInvokeCallInjector(DynamicClassInfo clazz, int baseCPoolCount, int methodIdx) {\n        super(clazz, baseCPoolCount, methodIdx);\n        targetMethodIdx = CPExtensionsRepository.miContents_HandleReflectInvokeMethodIdx + baseCPoolCount;\n        initializeInjectedCode();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    private void initializeInjectedCode() {\n        injectedCodeLen = 4;\n        injectedCode = new byte[injectedCodeLen];\n        injectedCode[0] = (byte) opc_aload_0;\n        injectedCode[1] = (byte) opc_invokestatic;\n        // Positions 2, 3 are occupied by method index\n        injectedCodeMethodIdxPos = 2;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/HandleServletDoMethodCallInjector.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\n\n\n/**\n * Specialized subclass of Injector, that provides injection of our standard handleServletDoMethod(javax.servlet.http.HttpServletRequest request)\n * call into javax.servlet.http.HttpServlet methods\n * void doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)\n * void doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)\n * void doPut(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)\n * void doDelete(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)\n *\n *  @author Tomas Hurka\n */\nclass HandleServletDoMethodCallInjector extends SpecialCallInjector {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static String[] methodNames = { \"doGet\", \"doPost\", \"doPut\", \"doDelete\" }; // NOI18N\n    private static String SIGNATURE = \"(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V\"; // NOI18N\n    private static String[] methodSignatures = { SIGNATURE, SIGNATURE, SIGNATURE, SIGNATURE };\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HandleServletDoMethodCallInjector(DynamicClassInfo clazz, int baseCPoolCount, int methodIdx) {\n        super(clazz, baseCPoolCount, methodIdx);\n        targetMethodIdx = CPExtensionsRepository.miContents_HandleServletDoMethodIdx + baseCPoolCount;\n        initializeInjectedCode();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    static String getClassName() {\n        return \"javax/servlet/http/HttpServlet\"; // NOI18N\n    }\n\n    static String[] getMethodNames() {\n        return methodNames;\n    }\n\n    static String[] getMethodSignatures() {\n        return methodSignatures;\n    }\n\n    private void initializeInjectedCode() {\n        injectedCodeLen = 4;\n        injectedCode = new byte[injectedCodeLen];\n        injectedCode[0] = (byte) opc_aload_1;\n        injectedCode[1] = (byte) opc_invokestatic;\n        // Positions 2, 3 are occupied by method index\n        injectedCodeMethodIdxPos = 2;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/Injector.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.client.RuntimeProfilingPoint;\nimport java.util.Stack;\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n\n/**\n * Base class for a number of classes performing concrete method instrumentation injections. Contains core functionality\n * for injection of arbitrary bytecodes at a given location in a method and subsequent rewriting of bytecodes. Also\n * supports appending bytecodes to the existing bytecodes, and extending the method's exception table.\n *\n * @author Misha Dmitriev\n * @author Tomas Hurka\n */\npublic abstract class Injector extends SingleMethodScaner {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    //-------------------------------------- Helper classes ------------------------------------------\n    private abstract static class ChangeItem {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        int bci;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ChangeItem(int bci) {\n            this.bci = bci;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        abstract void handleCodeChange(Injector r);\n\n        void relocate(int breakBCI, int delta) {\n            if (bci > breakBCI) {\n                bci += delta;\n            }\n        }\n    }\n\n    private static class ChangeJumpWiden extends ChangeItem {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        int delta; // New length of instruction at bci\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ChangeJumpWiden(int bci, int delta) {\n            super(bci);\n            this.delta = delta;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        // Callback to do instruction\n        void handleCodeChange(Injector r) {\n            r.handleJumpWiden(bci, delta);\n        }\n    }\n\n    private static class ChangeSwitchPadding extends ChangeItem {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        boolean isLookupSwitch;\n        int padding;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ChangeSwitchPadding(int bci, int padding, boolean isLookupSwitch) {\n            super(bci);\n            this.padding = padding;\n            this.isLookupSwitch = isLookupSwitch;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        // Callback to do instruction\n        void handleCodeChange(Injector r) {\n            r.handleSwitchPadding(bci, padding, isLookupSwitch);\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final int MAX_SHORT = ((1 << 15) - 1);\n    private static final int MIN_SHORT = (-(1 << 15));\n\n    // Increment to possible stack depth -- two instrumentation arguments\n    private static final int STACK_INCREMENT = 2;\n    private static Stack changes = new Stack(); // Stack of additional changes to bytecodes that may be caused by our main injection change\n    private static byte[] _overwrite = new byte[3]; // Stores overwritten bytes for shrunken instructions\n\n    // The following array is re-used,to avoid excessive object allocations - which means that the class is not multi thread safe\n    private static byte[] reusableExcTable = new byte[100];\n\n    // ProfilerRuntime.profilePointHit instrumentation\n    private static final byte[] injProfilePointHitCode = new byte[] { opc_sipush, 0, 0, (byte) opc_invokestatic, 0, 0, 0, 0 };\n    private static final int injProfilePointHitIDCodeIdx = 1;\n    private static final int injProfilePointHitMethodIdx = 4;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected byte[] exceptionTable; // Current updateable copy of exception table (what is in MethodInfo Code attribute after exception_table_length)\n    protected int baseCPoolCount; // The \"base\" constant pool index, after which the set of entries containing the calls that\n                                  // we inject, plus supporting entries, are located.\n    protected int excTableEntryCount;\n    protected int maxLocals;\n    protected int maxStack;\n    protected int origBytecodesLength;\n    protected int origExcTableEntryCount;\n    private boolean changeTypeIsInjectNewInstr;\n    private boolean injectionBindsToFollowingInstruction;\n    private boolean classChecked;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    // ---------------------------------------- Protected methods -------------------------------------------------\n    protected Injector() {\n    }\n\n    /**\n     * Creates a new Injector for the specified method. Subsequently one can call injectCodeAndRewrite() and other\n     * methods below as many times as needed.\n     */\n    protected Injector(DynamicClassInfo clazz, int methodIdx) {\n        super(clazz, methodIdx);\n        origBytecodesLength = bytecodesLength;\n        maxStack = getU2(origMethodInfo, bytecodesStartIdx - 8);\n        maxLocals = getU2(origMethodInfo, bytecodesStartIdx - 6);\n        initExceptionTable();\n        origExcTableEntryCount = excTableEntryCount;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    // ------------------------------------ Public abstract interface ---------------------------------------------\n\n    /** In concrete subclasses, should do all the real work on method instrumentation and return the updated packed methodInfo */\n    public abstract byte[] instrumentMethod();\n\n    protected void addExceptionTableEntry(int startPC, int endPC, int handlerPC, int typeCPIndex) {\n        int pos = excTableEntryCount * 8;\n        putU2(exceptionTable, pos, startPC);\n        putU2(exceptionTable, pos + 2, endPC);\n        putU2(exceptionTable, pos + 4, handlerPC);\n        putU2(exceptionTable, pos + 6, typeCPIndex);\n        excTableEntryCount++;\n    }\n\n    protected void addGlobalCatchStackMapTableEntry(int endPC) {\n        DynamicClassInfo dynClass = (DynamicClassInfo)clazz;\n        if (!classChecked) {\n            classChecked = true;\n            if (!clazz.getStackMapTables().hasTable()) {\n                DynamicConstantPoolExtension.getCPFragment(dynClass, CommonConstants.INJ_STACKMAP);\n            }\n            if (clazz.getCPIndexOfClass(\"java/lang/Throwable\") == -1) { // NOI18N\n                DynamicConstantPoolExtension.getCPFragment(dynClass, CommonConstants.INJ_THROWABLE);\n            }\n        }\n        dynClass.addGlobalCatchStackMapTableEntry(methodIdx, endPC);\n    }\n\n    protected void appendCode(byte[] appendedBytes, int appendedBytesCount) {\n        System.arraycopy(appendedBytes, 0, bytecodes, bytecodesLength, appendedBytesCount);\n        bytecodesLength += appendedBytesCount;\n    }\n\n    protected byte[] createPackedMethodInfo() {\n        int diff = (bytecodesLength - origBytecodesLength) + ((excTableEntryCount - origExcTableEntryCount) * 8);\n        byte[] ret = new byte[origMethodInfo.length + diff];\n        System.arraycopy(origMethodInfo, 0, ret, 0, bytecodesStartIdx);\n        System.arraycopy(bytecodes, 0, ret, bytecodesStartIdx, bytecodesLength);\n\n        int attrLength = getU4(origMethodInfo, bytecodesStartIdx - 12);\n        attrLength += diff;\n        putU4(ret, bytecodesStartIdx - 12, attrLength); // Patch the attribute_length in Code attribute\n        putU4(ret, bytecodesStartIdx - 4, bytecodesLength); // Patch the code_length in Code attribute\n        System.arraycopy(origMethodInfo, bytecodesStartIdx + origBytecodesLength, ret, bytecodesStartIdx + bytecodesLength,\n                         origMethodInfo.length - bytecodesStartIdx - origBytecodesLength);\n\n        int excTableOldStart = clazz.getExceptionTableStartOffsetInMethodInfo(methodIdx);\n        int excTableNewStart = excTableOldStart + (bytecodesLength - origBytecodesLength);\n        int excTableOldLen = origExcTableEntryCount * 8;\n        int excTableNewLen = excTableEntryCount * 8;\n\n        if (excTableOldLen != excTableNewLen) {\n            System.arraycopy(ret, excTableNewStart + excTableOldLen, ret, excTableNewStart + excTableNewLen,\n                             origMethodInfo.length - excTableOldStart - excTableOldLen);\n            putU2(ret, excTableNewStart, excTableEntryCount);\n        }\n\n        System.arraycopy(exceptionTable, 0, ret, excTableNewStart + 2, excTableNewLen);\n\n        ClassInfo.LocalVariableTables localVarTable = clazz.getLocalVariableTables();\n        \n        if (localVarTable.hasTable()) {\n            int locVarTableOldStart = clazz.getLocalVariableTableStartOffsetInMethodInfo(methodIdx);\n            int locVarTablePtr = locVarTableOldStart + diff;\n            localVarTable.writeTable(ret, locVarTablePtr, methodIdx);\n        }\n\n        ClassInfo.LocalVariableTypeTables localVarTypeTable = clazz.getLocalVariableTypeTables();\n        \n        if (localVarTypeTable.hasTable()) {\n            int locVarTypeTableOldStart = clazz.getLocalVariableTypeTableStartOffsetInMethodInfo(methodIdx);\n            int locVarTypeTablePtr = locVarTypeTableOldStart + diff;\n            localVarTypeTable.writeTable(ret, locVarTypeTablePtr, methodIdx);\n        }\n\n        ClassInfo.StackMapTables stackMapTable = clazz.getStackMapTables();\n        \n        if (stackMapTable.hasTable()) {\n            int stackMapTableOldStart = clazz.getStackMapTableStartOffsetInMethodInfo(methodIdx);\n            byte[] stackMapData = stackMapTable.writeTable(methodIdx);\n            \n            if (stackMapData != null) {\n                int stackMapDiff = 0;\n                int stackMapTablePtr;\n                \n                if (stackMapTableOldStart != 0) {\n//                    ClassInfo.LOG.finer(\"Updating StackMapTable for \"+clazz.getName()+\" method \"+clazz.getMethodName(methodIdx));\n                    stackMapTablePtr = stackMapTableOldStart + diff;\n                    int originalSize = getU4(ret, stackMapTablePtr-6) - 2;\n//                    ClassInfo.LOG.finer(\"Original size \"+originalSize);\n                    \n                    if (stackMapData.length > originalSize) {  // add space and copy original data\n                        stackMapDiff = stackMapData.length-originalSize;\n                        ret = insertBytes(ret, stackMapTablePtr+originalSize, stackMapDiff);\n                    }\n                    System.arraycopy(stackMapData,0,ret,stackMapTablePtr,stackMapData.length);\n                } else {\n//                    ClassInfo.LOG.finer(\"Adding StackMapTable for \"+clazz.getName()+\" method \"+clazz.getMethodName(methodIdx));\n                    // add whole StackMapTable attribute\n                    byte[] header = stackMapTable.getAttributeHeader(methodIdx);\n                    int insertOffset = bytecodesStartIdx - 8 + attrLength; // end of Code attribute\n                    \n                    stackMapDiff = header.length + stackMapData.length;\n                    stackMapTablePtr = insertOffset + header.length;\n                    ret = insertBytes(ret, insertOffset, stackMapDiff);\n                    System.arraycopy(header, 0, ret, stackMapTablePtr-header.length , header.length);\n                    System.arraycopy(stackMapData, 0, ret, stackMapTablePtr, stackMapData.length);\n                    int arrtCountPrt = excTableNewStart+2+excTableNewLen;\n                    putU2(ret,arrtCountPrt,getU2(ret,arrtCountPrt)+1); // increment attributes_count item\n                }\n                if (stackMapDiff > 0) {\n                    putU4(ret, bytecodesStartIdx-12, attrLength + stackMapDiff);                  // update the attribute_length in Code attribute\n                    putU4(ret, stackMapTablePtr-6, stackMapData.length + 2);                          // update attribute size\n                    putU2(ret, stackMapTablePtr-2, stackMapTable.getNumberOfFrames(methodIdx));       // update no. of StackMap frames\n                }\n            }\n        }\n        \n        // FIXME: need to update linenumber table as well\n        putU2(ret, bytecodesStartIdx - 8, maxStack + STACK_INCREMENT);\n        putU2(ret, bytecodesStartIdx - 6, maxLocals);\n\n        return ret;\n    }\n\n    private byte[] insertBytes(final byte[] ret, final int insertionOffset, final int newBytes) {\n        byte[] newRet = new byte[ret.length+newBytes];\n        System.arraycopy(ret,0,newRet,0,insertionOffset);\n        if (insertionOffset < ret.length) {\n            System.arraycopy(ret, insertionOffset, \n                             newRet, insertionOffset+newBytes,\n                             ret.length-insertionOffset);\n        }\n        return newRet;\n    }\n\n    /**\n     * Injects the specified raw bytes array at the specified location.\n     * The last parameter indicates whether the injected code should be bound to the following (if true) or previous (if false) bytecode\n     * instruction. When binding to the following instruction, all jumps that target that instruction will target the injected code after\n     * rewriting. When binding to the previous instruction x, all jumps that target the instruction x+1 will still target that instruction\n     * after rewriting (i.e. not target our injected code, as in the first case).\n     */\n    protected void injectCodeAndRewrite(byte[] injectedBytes, int injectedBytesCount, int injectionPos,\n                                        boolean injectionBindsToFollowingInstruction) {\n        this.injectionBindsToFollowingInstruction = injectionBindsToFollowingInstruction;\n        relocateCode(injectionPos, 0, injectedBytesCount, true);\n        // Copy the bytecodes to inject into the method\n        System.arraycopy(injectedBytes, 0, bytecodes, injectionPos, injectedBytesCount);\n        // Now handle the additional changes that could be caused by the injection\n        handleCodeChanges();\n    }\n\n    /**\n     * Profiling points MUST BE already SORTED by BCI in ascending order and only relevant to this method.\n     *\n     * @param points sorted array of Profiling points\n     * @param ppHitCPMethodIdx\n     */\n    protected void insertProfilingPoints(RuntimeProfilingPoint[] points, int ppHitCPMethodIdx) {\n        for (int i = 0; i < points.length; i++) {\n            RuntimeProfilingPoint point = points[i];\n            assert (i == 0) || (point.getBci() >= points[i - 1].getBci());\n\n            int ppbci = point.getBci() + (i * injProfilePointHitCode.length);\n            injectProfilePointHit(point, ppbci, ppHitCPMethodIdx);\n            maxStack = Math.max(maxStack, 4);\n        }\n    }\n\n    /** Called by the ChangeJumpWiden class */\n    void handleJumpWiden(int bci, int delta) {\n        int ilen = rcInstrLen(bci);\n\n        if (ilen != 3) {\n            return; // Request already handled\n                    //Above: assert(code_at(bci) == Bytecodes::_goto_w || code_at(bci) == Bytecodes::_jsr_w, \"sanity check\");\n        }\n\n        //assert(ilen == 3, \"check length\");\n        relocateCode(bci, 3, 2, false);\n\n        int bc = bytecodes[bci] & 0xff;\n\n        switch (bc) {\n            case opc_goto:\n                bytecodes[bci] = (byte) opc_goto_w;\n\n                break;\n            case opc_jsr:\n                bytecodes[bci] = (byte) opc_jsr_w;\n\n                break;\n            default:\n                System.err.println(\"*** Profiler Engine: error - should not reach here in handleJumpWiden!\"); // NOI18N\n        }\n\n        // If it's a forward jump, add 2 for the widening.\n        if (delta > 0) {\n            delta += 2;\n        }\n\n        putInt(bci + 1, delta);\n    }\n\n    /** If a change item is recorded for bci, with the same is_lookup_switch flag value, returns the associated padding, else -1. */\n    private int getOrigSwitchPadding(int bci, boolean isLookupSwitch) {\n        for (int k = 0; k < changes.size(); k++) {\n            ChangeItem ci = (ChangeItem) changes.elementAt(k);\n\n            if (ci instanceof ChangeSwitchPadding) {\n                ChangeSwitchPadding csp = (ChangeSwitchPadding) ci;\n\n                if ((csp.isLookupSwitch == isLookupSwitch) && (csp.bci == bci)) {\n                    return csp.padding;\n                }\n            }\n        }\n\n        return -1;\n    }\n\n    /**\n     * The current instruction at bci is a jump; one of its offsets starts at \"offset\" and is a short if isShort is true,\n     * and an integer otherwise.  If the jump crosses breakBCI, change the span of the jump by delta.\n     */\n    private void changeJump(int bci, int offset, boolean isShort, int breakBCI, int delta) {\n        int bciDelta = (isShort) ? getShort(offset) : getInt(offset);\n        int targ = bci + bciDelta;\n\n        boolean doRewrite = false;\n\n        // Injection of a completely new instruction and widening of an existing instruction should be handled differently\n        if (changeTypeIsInjectNewInstr) {\n            if (breakBCI == 0) {\n                return; // No jump to the code injected at offset 0 can be made in the rewrited code\n                        // The most reliable way to verify the correctness of the statements below, is to draw a picture, something like\n                        // 1 a\n                        //     <--- breakBCI = 2\n                        // 2 b\n                        //     <--- breakBCI = 3\n                        // 3 goto\n                        //     <--- breakBCI = 4\n                        // 4 c\n                        // 5 d\n                        //\n                        // and then consider all the combinations of bci = 3 with breakBCI = 2, 3, 4 and targ = 1,2,4,5 - what should happen in each case.\n                        // For example:\n                        // bci = 3, breakBCI = 2, injectionBindsToFollowingInstruction = true\n                        // targ = 1 - should rewrite jump argument\n                        // targ = 2 - should rewrite jump argument (because we will need to jump to the injected code, rather than old instruction at b at 2)\n                        // targ = 4, 5 - don't need to rewrite jump argument\n                        // ... and so on\n            }\n\n            if (injectionBindsToFollowingInstruction) {\n                if (((bci < breakBCI) && (targ > breakBCI)) || ((bci >= breakBCI) && (targ <= breakBCI))) {\n                    doRewrite = true;\n                }\n            } else { // Injected code binds to previous instruction, e.g. the traceObjAlloc() call that follows a constructor call\n\n                if (((bci < breakBCI) && (targ >= breakBCI)) || ((bci >= breakBCI) && (targ < breakBCI))) {\n                    doRewrite = true;\n                }\n            }\n        } else {\n            if (((bci <= breakBCI) && (targ > breakBCI)) || ((bci >= breakBCI) && (targ < breakBCI))) {\n                doRewrite = true;\n            }\n        }\n\n        if (doRewrite) {\n            int newDelta = (bciDelta > 0) ? (bciDelta + delta) : (bciDelta - delta);\n\n            if (isShort && ((newDelta > MAX_SHORT) || (newDelta < MIN_SHORT))) {\n                changes.push(new ChangeJumpWiden(bci, newDelta));\n            } else if (isShort) {\n                putShort(offset, (short) newDelta);\n            } else {\n                putInt(offset, newDelta);\n            }\n        }\n    }\n\n    /** Changes all jumps crossing breakBCI by delta.  May enqueue things on the changes stack */\n    private void changeJumps(int breakBCI, int delta) {\n        int bci = 0;\n        int bc;\n\n        // Now, adjust any affected instructions.\n        while (bci < bytecodesLength) {\n            bc = (bytecodes[bci] & 0xFF);\n\n            if (((bc >= opc_ifeq) && (bc <= opc_if_acmpne)) || (bc == opc_ifnull) || (bc == opc_ifnonnull) || (bc == opc_goto)\n                    || (bc == opc_jsr)) {\n                changeJump(bci, bci + 1, true, breakBCI, delta);\n            } else {\n                switch (bc) {\n                    case opc_goto_w:\n                    case opc_jsr_w:\n                        changeJump(bci, bci + 1, false, breakBCI, delta);\n\n                        break;\n                    case opc_tableswitch:\n                    case opc_lookupswitch: {\n                        int recPad = getOrigSwitchPadding(bci, (bc != opc_tableswitch));\n                        int oldPad = (recPad != -1) ? recPad : (align(bci + 1) - (bci + 1));\n\n                        if (bci > breakBCI) {\n                            int new_bci = bci + delta;\n                            int newPad = align(new_bci + 1) - (new_bci + 1);\n\n                            // Do we need to check the padding?\n                            if (newPad != oldPad) {\n                                if (recPad == -1) {\n                                    changes.push(new ChangeSwitchPadding(bci, oldPad, (bc != opc_tableswitch)));\n                                }\n                            }\n                        }\n\n                        // Then the rest, which depends on the kind of switch.\n                        if (bc == opc_tableswitch) {\n                            changeJump(bci, bci + 1 + oldPad, false, breakBCI, delta);\n\n                            // We cannot use the Bytecode_tableswitch abstraction, since the padding might not be correct.\n                            int lo = getInt(bci + 1 + oldPad + (4 * 1));\n                            int hi = getInt(bci + 1 + oldPad + (4 * 2));\n                            int n = hi - lo + 1;\n\n                            for (int k = 0; k < n; k++) {\n                                changeJump(bci, bci + 1 + oldPad + (4 * (k + 3)), false, breakBCI, delta);\n                            }\n\n                            // Special next-bci calculation here...\n                            bci += (1 + oldPad + ((n + 3) * 4));\n\n                            continue;\n                        } else {\n                            changeJump(bci, bci + 1 + oldPad, false, breakBCI, delta);\n\n                            // We cannot use the Bytecode_lookupswitch abstraction, since the padding might not be correct.\n                            int npairs = getInt(bci + 1 + oldPad + (4 * 1));\n\n                            for (int k = 0; k < npairs; k++) {\n                                changeJump(bci, bci + 1 + oldPad + (4 * (2 + (2 * k) + 1)), false, breakBCI, delta);\n                            }\n\n                            // Special next-bci calculation here...\n                            bci += (1 + oldPad + ((2 + (npairs * 2)) * 4));\n\n                            continue;\n                        }\n                    }\n                    default:\n                        break;\n                }\n            }\n\n            bci += opcodeLength(bci);\n        }\n    }\n\n    //--------------------------------------- Private implementation -------------------------------------------\n    private void handleCodeChanges() {\n        while (!changes.empty()) {\n            // Inv: everything is aligned.\n            ChangeItem ci = (ChangeItem) changes.pop();\n            ci.handleCodeChange(this);\n        }\n    }\n\n    /** Handle lookup/table switch instructions.  Called be ChangeSwitchPad class */\n    private void handleSwitchPadding(int bci, int oldPad, boolean isLookupSwitch) {\n        int ilen = rcInstrLen(bci);\n        int newPad = align(bci + 1) - (bci + 1);\n        int padDelta = newPad - oldPad;\n\n        if (padDelta != 0) {\n            int len;\n\n            if (!isLookupSwitch) {\n                int low = getInt(bci + 1 + oldPad + 4);\n                int high = getInt(bci + 1 + oldPad + 8);\n                len = high - low + 1 + 3; // 3 for default, hi, lo.\n            } else {\n                int npairs = getInt(bci + 1 + oldPad + 4);\n                len = (npairs * 2) + 2; // 2 for default, npairs.\n            }\n\n            // Because \"relocateCode\" does a \"changeJumps\" loop, which parses instructions to determine their length,\n            // we need to call that before messing with the current instruction.  Since it may also overwrite the current\n            // instruction when moving down, remember the possibly overwritten part.\n            relocateCode(bci, ilen, padDelta, false); // Relocate the code following the instruction...\n\n            if (padDelta < 0) { // Move the shrunken instruction down.\n                System.arraycopy(bytecodes, bci + 1 + oldPad, bytecodes, bci + 1 + newPad, (len * 4) + padDelta);\n                System.arraycopy(_overwrite, 0, bytecodes, bci + 1 + newPad + (len * 4) + padDelta, -padDelta);\n            } else { // Move the expanded instruction up.\n                System.arraycopy(bytecodes, bci + 1 + oldPad, bytecodes, bci + 1 + newPad, len * 4);\n            }\n        }\n    }\n\n    private void initExceptionTable() {\n        int startOfs = clazz.getExceptionTableStartOffsetInMethodInfo(methodIdx);\n        excTableEntryCount = clazz.getExceptionTableCount(methodIdx);\n\n        int len = excTableEntryCount * 8;\n\n        if (reusableExcTable.length < (len + 40)) {\n            reusableExcTable = new byte[(len * 2) + 40]; // Can add at least 8*5 = 40 entries.\n        }\n\n        System.arraycopy(origMethodInfo, startOfs + 2, reusableExcTable, 0, len);\n        exceptionTable = reusableExcTable;\n    }\n\n    private void injectProfilePointHit(RuntimeProfilingPoint point, int bci, int ppHitCPMethodIdx) {\n        // Prepare the profilePointHit(char id, char flags) code packet that is to be injected\n        putU2(injProfilePointHitCode, injProfilePointHitMethodIdx, ppHitCPMethodIdx + baseCPoolCount);\n        putU2(injProfilePointHitCode, injProfilePointHitIDCodeIdx, point.getId());\n\n        injectCodeAndRewrite(injProfilePointHitCode, injProfilePointHitCode.length, bci, true);\n    }\n\n    /**\n     * We need a special instruction size method, since lookupswitches and tableswitches might not be\n     * properly aligned during relocation\n     */\n    private int rcInstrLen(int bci) {\n        int bc = bytecodes[bci] & 0xFF;\n\n        switch (bc) {\n            // In the case of switch instructions, see if we have the original padding recorded.\n            case opc_tableswitch:\n            case opc_lookupswitch: {\n                int pad = getOrigSwitchPadding(bci, (bc == opc_lookupswitch));\n\n                if (pad == -1) {\n                    return opcodeLength(bci);\n                }\n\n                // Otherwise, depends on the switch type.\n                switch (bc) {\n                    case opc_tableswitch: {\n                        int lo = getInt(bci + 1 + pad + (4 * 1));\n                        int hi = getInt(bci + 1 + pad + (4 * 2));\n                        int n = hi - lo + 1;\n\n                        return 1 + pad + (4 * (3 + n));\n                    }\n                    case opc_lookupswitch: {\n                        int npairs = getInt(bci + 1 + pad + (4 * 1));\n\n                        return 1 + pad + (4 * (2 + (2 * npairs)));\n                    }\n                }\n            }\n        }\n\n        return opcodeLength(bci);\n    }\n\n    /**\n     * The input is interpreted depending on the injectNewInstr flag value.\n     * If it's false, instruction at bci, whose size is iLen, is changing size by delta.\n     * If it's true, we inject some instructions bytes of length delta at bci.\n     * Reallocate, move code, recalculate jumps, and enqueue more change items as necessary.\n     * Note that currently it's assumed that delta is a multiple of 4 - in this way we avoid additional problems with changed\n     * paddings in 'switch' instructions.\n     */\n    private void relocateCode(int bci, int iLen, int delta, boolean injectNewInstr) {\n        changeTypeIsInjectNewInstr = injectNewInstr; // Other methods need to know whether we are injecting or widening an instruction\n\n        // Change jumps before doing the copying; this routine requires aligned switches. If we inject something in\n        // the very beginning of the method, changing jumps is not needed.\n        if (bci > 0) {\n            changeJumps(bci, delta);\n        }\n\n        // In case we have shrunken a tableswitch/lookupswitch statement, we store the last\n        // bytes that get overwritten. We have to copy the bytes after the changeJumps method\n        // has been called, since it is likely to update last offset in a tableswitch/lookupswitch\n        if (delta < 0) {\n            //assert(delta>=-3, \"we cannot overwrite more than 3 bytes\");\n            System.arraycopy(bytecodes, bci + iLen + delta, _overwrite, 0, -delta);\n        }\n\n        int nextBCI = bci + iLen; // Needed for instruction widening; ok for injection, since iLen == 0 in that case\n        System.arraycopy(bytecodes, nextBCI, bytecodes, nextBCI + delta, bytecodesLength - nextBCI);\n        bytecodesLength += delta;\n\n        updateExceptionTable(bci, delta);\n        updateLocalVariableTable(bci, delta);\n        updateLocalVariableTypeTable(bci, delta);\n        updateStackMapTable(bci, delta);\n\n        // We currently don't support the following updates - they are used only by debuggers.\n        // updateLineNumberTable(injectionPos, delta);\n\n        // Relocate the bcis of changes in the pending change stack\n        for (int j = 0; j < changes.size(); j++) {\n            ChangeItem ci = (ChangeItem) changes.elementAt(j);\n            ci.relocate(bci, delta);\n        }\n    }\n\n    private void updateExceptionTable(int injectionPos, int injectedBytesCount) {\n        int pos = 0;\n\n        for (int i = 0; i < excTableEntryCount; i++) {\n            int startPC = getU2(exceptionTable, pos);\n            int endPC = getU2(exceptionTable, pos + 2);\n            int handlerPC = getU2(exceptionTable, pos + 4);\n\n            if (startPC > injectionPos) {\n                startPC += injectedBytesCount;\n                endPC += injectedBytesCount;\n                putU2(exceptionTable, pos, startPC);\n                putU2(exceptionTable, pos + 2, endPC);\n            } else if (injectionPos < endPC) {\n                endPC += injectedBytesCount;\n                putU2(exceptionTable, pos + 2, endPC);\n            }\n\n            if (handlerPC > injectionPos) {\n                handlerPC += injectedBytesCount;\n                putU2(exceptionTable, pos + 4, handlerPC);\n            }\n\n            pos += 8;\n        }\n    }\n\n    private void updateLocalVariableTable(int injectionPos, int injectedBytesCount) {\n        ClassInfo.LocalVariableTables localVarTable = clazz.getLocalVariableTables();\n        \n        localVarTable.updateTable(injectionPos, injectedBytesCount, methodIdx);\n    }\n\n    private void updateLocalVariableTypeTable(int injectionPos, int injectedBytesCount) {\n        ClassInfo.LocalVariableTypeTables localVarTypeTable = clazz.getLocalVariableTypeTables();\n        \n        localVarTypeTable.updateTable(injectionPos, injectedBytesCount, methodIdx);\n    }\n\n    private void updateStackMapTable(int injectionPos, int injectedBytesCount) {\n        ClassInfo.StackMapTables stackMapTable = clazz.getStackMapTables();\n        \n        stackMapTable.updateTable(injectionPos, injectedBytesCount, methodIdx, changeTypeIsInjectNewInstr, injectionBindsToFollowingInstruction);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/InstrumentationException.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\n\n/**\n * Classes to report problems during instrumentation\n *\n * @author Misha Dmitriev\n */\npublic class InstrumentationException extends Exception {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public InstrumentationException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/InstrumentationFactory.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.client.RuntimeProfilingPoint;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n\n/**\n * This class provides essentially a convenience static-method API that allows one to obtain a version of a particular\n * method, instrumented in a particular predefined way.\n *\n * @author Tomas Hurka\n * @author  Misha Dmitriev\n */\npublic class InstrumentationFactory implements CommonConstants {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static byte[] instrumentAsProiflePointHitMethod(DynamicClassInfo clazz, int methodIdx, int injType,\n                                                           RuntimeProfilingPoint[] points) {\n        Injector mi = new ProfilePointHitCallInjector(clazz, clazz.getBaseCPoolCount(injType), methodIdx, points,\n                                                      CPExtensionsRepository.normalContents_ProfilePointHitMethodIdx);\n\n        return mi.instrumentMethod();\n    }\n\n    public static byte[] instrumentAsReflectInvokeMethod(DynamicClassInfo clazz, int methodIdx) {\n        Injector mi = new HandleReflectInvokeCallInjector(clazz, clazz.getBaseCPoolCount(INJ_REFLECT_METHOD_INVOKE), methodIdx);\n\n        return mi.instrumentMethod();\n    }\n\n    public static byte[] instrumentAsServletDoMethod(DynamicClassInfo clazz, int methodIdx) {\n        Injector mi = new HandleServletDoMethodCallInjector(clazz, clazz.getBaseCPoolCount(INJ_SERVLET_DO_METHOD), methodIdx);\n\n        return mi.instrumentMethod();\n    }\n\n    public static byte[] instrumentCodeRegion(DynamicClassInfo clazz, int methodIdx, int bci0, int bci1) {\n        Injector mi = new CodeRegionEntryExitCallsInjector(clazz, clazz.getBaseCPoolCount(INJ_CODE_REGION), methodIdx, bci0, bci1);\n\n        return mi.instrumentMethod();\n    }\n\n    /** injType is either INJ_OBJECT_ALLOCATIONS or INJ_OBJECT_LIVENESS */\n    public static byte[] instrumentForMemoryProfiling(ClassManager man, DynamicClassInfo clazz, int methodIdx,\n                                                      boolean[] allUnprofiledClassStatusArray, int injType,\n                                                      RuntimeProfilingPoint[] points, InstrumentationFilter instrFilter,\n                                                      boolean checkForOpcNew, boolean checkForOpcNewArray) {\n        Injector mi = new ObjLivenessInstrCallsInjector(man, clazz, clazz.getBaseCPoolCount(injType), methodIdx,\n                                                        allUnprofiledClassStatusArray, instrFilter,\n                                                        checkForOpcNew, checkForOpcNewArray);\n        mi.insertProfilingPoints(points, CPExtensionsRepository.memoryProfContents_ProfilePointHitMethodIdx);\n\n        return mi.instrumentMethod();\n    }\n\n    /**\n     * normalInjectionType is either INJ_RECURSIVE_NORMAL_METHOD or INJ_RECURSIVE_SAMPLED_NORMAL_METHOD\n     * rootInjectionType is either INJ_RECURSIVE_ROOT_METHOD or INJ_RECURSIVE_SAMPLED_ROOT_METHOD\n     */\n    public static byte[] instrumentMethod(DynamicClassInfo clazz, int methodIdx, int normalInjectionType, int rootInjectionType,\n                                          int markerInjectionType, int methodId, RuntimeProfilingPoint[] points) {\n        int baseCPCount0 = clazz.getBaseCPoolCount(normalInjectionType);\n        int baseCPCount1;\n        int injType;\n\n        if (clazz.isMethodRoot(methodIdx)) {\n            baseCPCount1 = clazz.getBaseCPoolCount(rootInjectionType);\n            injType = rootInjectionType;\n        } else if (clazz.isMethodMarker(methodIdx)) {\n            baseCPCount1 = clazz.getBaseCPoolCount(markerInjectionType);\n            injType = markerInjectionType;\n        } else {\n            baseCPCount1 = 0;\n            injType = normalInjectionType;\n        }\n\n        Injector mi = new MethodEntryExitCallsInjector(clazz, baseCPCount0, baseCPCount1, methodIdx, injType, methodId);\n        mi.insertProfilingPoints(points, CPExtensionsRepository.normalContents_ProfilePointHitMethodIdx);\n\n        byte[] res = mi.instrumentMethod();\n        clazz.setInstrMethodId(methodIdx, methodId);\n\n        return res;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/Instrumentor.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.classfile.BaseClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils.SourceCodeSelection;\nimport org.graalvm.visualvm.lib.jfluid.client.RuntimeProfilingPoint;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.ClassLoadedCommand;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.Command;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.InstrumentMethodGroupCommand;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.InstrumentMethodGroupResponse;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.MethodInvokedFirstTimeCommand;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.MethodLoadedCommand;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.RootClassLoadedCommand;\n\n\n/**\n * A high-level interface to all method instrumentation operations.\n * <p>\n * Instrumentor subclasses find methods/classes to be instrumented.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Adrian Mos\n * @author Ian Formanek\n */\npublic class Instrumentor implements CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // TODO [release]: change value to TRUE to remove the print code below entirely by compiler\n    private static final boolean DEBUG = System.getProperty(\"org.graalvm.visualvm.lib.jfluid.instrumentation.Instrumentor\") != null; // NOI18N\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private CodeRegionMethodInstrumentor crms;\n    private MemoryProfMethodInstrumentor oms;\n    private ProfilerEngineSettings settings;\n    private ProfilingSessionStatus status;\n    private RecursiveMethodInstrumentor ms;\n    private RootMethods rootMethods;\n    private ClassRepository classRepo;\n\n    // Data for the case of code region instrumentation\n    private SourceCodeSelection savedSourceCodeSelection;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of Instrumentor. A single instance is created by ProfileClient and reused on subsequent\n     * profiling sessions.\n     *\n     * @param status   ProfilingSessionStatus used for profiling\n     * @param settings Engine settings - same instance is reused for all profiling sessions, the settings are modified\n     *                 each time before the session is started.\n     * @param repo     ClassRepository to access profiled classes\n     */\n    public Instrumentor(ClassRepository repo, ProfilingSessionStatus status, ProfilerEngineSettings settings) {\n        this.status = status;\n        this.settings = settings;\n        classRepo = repo;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getClassId(String className, int classLoaderId) {\n        BaseClassInfo clazz;\n        InstrumentationFilter filter = settings.getInstrumentationFilter();\n\n        if (className.charAt(0) == '[') { // array , need special lookup\n                                          // strip L and ; from className, see ClassFileParser.classNameAtCPIndex\n\n            if (className.endsWith(\";\")) {\n                int elIndex = className.indexOf('L');\n                className = new StringBuffer(className).deleteCharAt(className.length() - 1).deleteCharAt(elIndex).toString();\n            }\n            String filterName = StringUtils.userFormClassName(className);\n            if (!filter.passes(filterName.replace('.', '/'))) { // NOI18N\n                return -1;\n            }\n\n            clazz = classRepo.lookupSpecialClass(className);\n            if (clazz.getInstrClassId() == -1) {\n                clazz.setInstrClassId(oms.getNextClassId(className));\n            }\n        } else {\n            if (!filter.passes(className.replace('.', '/'))) { // NOI18N\n                return -1;\n            }\n            clazz = classRepo.lookupClassOrCreatePlaceholder(className, classLoaderId);\n        }\n\n        if (clazz == null) {\n            System.err.println(\"Warning: could not find class \" + className + \" loaded by the VM on the class path\");\n\n            // warning already issued in ClassRepository.lookupClass method, no need to do it again\n            return -1;\n        }\n\n        if (clazz.getInstrClassId() == -1) {\n            System.err.println(\"Warning: \" + clazz.getNameAndLoader() + \" does not have instrClassId\");            \n        }\n        return clazz.getInstrClassId();\n    }\n\n    public synchronized InstrumentMethodGroupCommand getCommandToUnprofileClasses(boolean[] unprofiledClassStatusArray) {\n        ObjLivenessMethodInstrumentor olms = (ObjLivenessMethodInstrumentor) oms;\n        Object[] ret = olms.getMethodsToInstrumentUponClassUnprofiling(unprofiledClassStatusArray);\n\n        if (ret == null) {\n            return new InstrumentMethodGroupCommand(null);\n        } else {\n            return new InstrumentMethodGroupCommand(INSTR_OBJECT_LIVENESS, (String[]) ret[0], (int[]) ret[1], (byte[][]) ret[2],\n                                                    null, oms.getNInstantiatableClasses());\n        }\n    }\n\n    // --------------------------------------- Public interface ----------------------------------------------------------\n    public String[] getRootClassNames() {\n        List /*<String>*/ rootClassNames = rootMethods.getRootClassNames();\n        RuntimeProfilingPoint[] pps = settings.getRuntimeProfilingPoints();\n\n        if ((rootClassNames == null) && (pps.length > 0)) {\n            rootClassNames = new ArrayList();\n        }\n\n        for (RuntimeProfilingPoint pp : pps) {\n            String className = pp.getClassName();\n\n            if (!rootClassNames.contains(className)) {\n                rootClassNames.add(className);\n            }\n        }\n\n        if (rootClassNames == null) {\n            return null;\n        }\n\n        return (String[]) rootClassNames.toArray(new String[0]);\n    }\n\n    public void setSavedSourceCodeSelection(SourceCodeSelection[] s) {\n        savedSourceCodeSelection = s[0];\n    }\n\n    public void setStatusInfoFromSourceCodeSelection(SourceCodeSelection[] s)\n                                              throws ClassNotFoundException, BadLocationException, IOException, ClassFormatError {\n        if (s.length > 0) {\n            SourceCodeSelection sel = s[0];\n\n            if (sel.definedViaSourceLines()) {\n                status.instrStartLine = sel.getStartLine();\n                status.instrEndLine = sel.getEndLine();\n            }\n        }\n\n        rootMethods = new RootMethods(s);\n    }\n\n    public synchronized InstrumentMethodGroupCommand createClearAllInstrumentationCommand() {\n        Object[] ret = null;\n\n        switch (status.currentInstrType) {\n            case INSTR_RECURSIVE_FULL:\n            case INSTR_RECURSIVE_SAMPLED:\n            case INSTR_OBJECT_ALLOCATIONS:\n            case INSTR_OBJECT_LIVENESS:\n                ms = null; // Free some memory\n                ret = (new MiscInstrumentationOps(classRepo, status)).getOrigCodeForAllInstrumentedMethods();\n\n                break;\n            case INSTR_CODE_REGION:\n                ret = (new MiscInstrumentationOps(classRepo, status)).getOrigCodeForSingleInstrumentedMethod(rootMethods);\n\n                break;\n        }\n\n        ms = null;\n        oms = null;\n        crms = null; // Free some memory\n\n        if (ret == null) {\n            return new InstrumentMethodGroupCommand(null);\n        } else {\n            return new InstrumentMethodGroupCommand(INSTR_NONE, (String[]) ret[0], (int[]) ret[1], (byte[][]) ret[2], null, 0);\n        }\n    }\n\n    public synchronized InstrumentMethodGroupResponse createFollowUpInstrumentMethodGroupResponse(Command cmd) {\n        if (cmd instanceof ClassLoadedCommand) {\n            ClassLoadedCommand clcmd = (ClassLoadedCommand) cmd;\n            int[] thisAndParentLoaderData = clcmd.getThisAndParentLoaderData();\n\n            if (DEBUG) {\n                System.err.println(\"Instrumentor.DEBUG: Class loaded command: \" + cmd.toString()); // NOI18N\n            }\n\n            byte[] classFileBytes = clcmd.getClassFileBytes();\n\n            if (classFileBytes != null) {\n                classRepo.addVMSuppliedClassFile(clcmd.getClassName().replace('.','/'), thisAndParentLoaderData[0], classFileBytes);\n            }\n\n            classRepo.getClassPath().getClassLoaderTable().addChildAndParent(thisAndParentLoaderData);\n        } else if (cmd instanceof MethodLoadedCommand) {\n            MethodLoadedCommand mcmd = (MethodLoadedCommand) cmd;\n\n            if (DEBUG) {\n                System.err.println(\"Instrumentor.DEBUG: Method loaded command: \" + mcmd.toString()); // NOI18N\n            }\n        }\n\n        InstrumentMethodGroupResponse imgr = null;\n\n        switch (status.currentInstrType) {\n            case INSTR_RECURSIVE_FULL:\n            case INSTR_RECURSIVE_SAMPLED:\n                imgr = createFollowUpInstrumentMethodGroupResponseForCallGraph(cmd);\n\n                break;\n            case INSTR_CODE_REGION: // Follow-up can happen only if the same class is loaded with a different loader\n                                    // Just in case this is say MethodInvokedFirstTimeCommand generated from the previously\n                                    // active CPU instrumentation\n\n                if (!(cmd instanceof ClassLoadedCommand)) {\n                    return new InstrumentMethodGroupResponse(null);\n                }\n\n                imgr = createFollowUpInstrumentMethodGroupResponseForCodeRegion((ClassLoadedCommand) cmd);\n\n                break;\n            case INSTR_OBJECT_ALLOCATIONS:\n            case INSTR_OBJECT_LIVENESS:\n\n                // Just in case this is say MethodInvokedFirstTimeCommand generated from the previously\n                // active CPU instrumentation\n                if (!(cmd instanceof ClassLoadedCommand)) {\n                    return new InstrumentMethodGroupResponse(null);\n                }\n\n                imgr = createFollowUpInstrumentMethodGroupResponseForMemoryProfiling((ClassLoadedCommand) cmd);\n\n                break;\n            default:\n                imgr = new InstrumentMethodGroupResponse(null);\n        }\n\n        return imgr;\n    }\n\n    public synchronized InstrumentMethodGroupResponse createInitialInstrumentMethodGroupResponse(RootClassLoadedCommand cmd)\n        throws ClassNotFoundException, BadLocationException {\n        classRepo.getClassPath().getClassLoaderTable().initTable(cmd.getParentLoaderIds());\n\n        InstrumentMethodGroupResponse imgr = null;\n\n        switch (status.currentInstrType) {\n            case INSTR_RECURSIVE_FULL:\n            case INSTR_RECURSIVE_SAMPLED:\n                imgr = createInitialInstrumentMethodGroupResponseForCallGraph(cmd);\n\n                break;\n            case INSTR_CODE_REGION:\n                imgr = createInitialInstrumentMethodGroupResponseForCodeRegion(cmd);\n\n                break;\n            case INSTR_OBJECT_ALLOCATIONS:\n            case INSTR_OBJECT_LIVENESS:\n                imgr = createInitialInstrumentMethodGroupResponseForMemoryProfiling(status.currentInstrType, cmd);\n\n                break;\n            default:\n                System.err.println(ENGINE_WARNING\n                                   + \"Instrumentor.createInitialInstrumentMethodGroupResponse() called with INSTR_NONE?\" // NOI18N\n                                   );\n                System.err.println(PLEASE_REPORT_PROBLEM);\n                imgr = new InstrumentMethodGroupResponse(null);\n\n                break;\n        }\n\n        return imgr;\n    }\n\n    /**\n     * This is called every time just before the target application is started or right after we attach to it.\n     * It resets the internal data for loaded/instrumented classes etc.\n     */\n    public void resetPerVMInstanceData() {\n        classRepo.clearCache();\n    }\n\n    private InstrumentMethodGroupResponse createFollowUpInstrumentMethodGroupResponseForCallGraph(Command cmd) {\n        Object[] ret = null;\n\n        // It may happen that if profiling is modified during intensive class loading, some class load message from\n        // server may be already in the pipeline and eventually get here despite the change, and before the relevant\n        // Method Scaner is initialized. This check should prevent problems caused by this inconsistency.\n        if (ms == null) {\n            return new InstrumentMethodGroupResponse(null);\n        }\n\n        if (cmd instanceof MethodInvokedFirstTimeCommand) {\n            int id = ((MethodInvokedFirstTimeCommand) cmd).getMethodId();\n            //System.out.println(\"--------- Received method invoked event for id = \" + id + \", method = \"\n            // + status.instrMethodClasses[id] + \".\" + status.instrMethodNames[id] + status.instrMethodSignatures[id]);\n            status.beginTrans(false);\n\n            try {\n                if ((id >= status.getInstrMethodClasses().length) || (status.getInstrMethodClasses()[id] == null)) {\n                    // Defensive programming: this situation may happen if something went wrong with previous deinstrumentation,\n                    // so some old methodEntry() call isn't removed and gets called. Avoid a crash and issue a warning instead\n                    return new InstrumentMethodGroupResponse(null);\n                }\n\n                ret = ms.getMethodsToInstrumentUponMethodInvocation(status.getInstrMethodClasses()[id],\n                                                                    status.getClassLoaderIds()[id],\n                                                                    status.getInstrMethodNames()[id],\n                                                                    status.getInstrMethodSignatures()[id]);\n            } finally {\n                status.endTrans();\n            }\n        } else if (cmd instanceof ClassLoadedCommand) {\n            ClassLoadedCommand ccmd = (ClassLoadedCommand) cmd;\n            //System.out.println(\"--------- Received class load event for class \" + ccmd.getClassName());\n            ret = ms.getMethodsToInstrumentUponClassLoad(ccmd.getClassName(), ccmd.getThisAndParentLoaderData()[0],\n                                                         ccmd.getThreadInCallGraph());\n        } else if (cmd instanceof MethodLoadedCommand) {\n            MethodLoadedCommand mcmd = (MethodLoadedCommand) cmd;\n            //System.out.println(\"--------- Recieved method load event for \" + mcmd.getClassName() + \".\"\n            // + mcmd.getMethodName() + mcmd.getMethodSignature());\n            ret = ms.getMethodsToInstrumentUponReflectInvoke(mcmd.getClassName(), mcmd.getClassLoaderId(), mcmd.getMethodName(),\n                                                             mcmd.getMethodSignature());\n        }\n\n        if (ret == null) {\n            return new InstrumentMethodGroupResponse(null);\n        } else {\n            return new InstrumentMethodGroupResponse((String[]) ret[0], (int[]) ret[1], (byte[][]) ret[3], (boolean[]) ret[2], 0);\n        }\n    }\n\n    private InstrumentMethodGroupResponse createFollowUpInstrumentMethodGroupResponseForCodeRegion(ClassLoadedCommand cmd) {\n        //System.out.println(\"--------- Received class load event for class \" + cmd.getClassName());\n        // It may happen that if profiling is modified during intensive class loading, some class load message from\n        // server may be already in the pipeline and eventually get here despite the change, and before the relevant\n        // Method Scaner is initialized. This check should prevent problems caused by this inconsistency.\n        if (crms == null) {\n            return new InstrumentMethodGroupResponse(null);\n        }\n\n        Object[] ret = crms.getFollowUpInstrumentCodeRegionResponse(cmd.getThisAndParentLoaderData()[0]);\n\n        if (ret == null) {\n            return new InstrumentMethodGroupResponse(null);\n        } else {\n            return new InstrumentMethodGroupResponse((String[]) ret[0], (int[]) ret[1], (byte[][]) ret[2], null, 0);\n        }\n    }\n\n    private InstrumentMethodGroupResponse createFollowUpInstrumentMethodGroupResponseForMemoryProfiling(ClassLoadedCommand cmd) {\n        //System.out.println(\"--------- Received class load event for class \" + cmd.getClassName());\n        // It may happen that if profiling is modified during intensive class loading, some class load message from\n        // server may be already in the pipeline and eventually get here despite the change, and before the relevant\n        // Method Scaner is initialized. This check should prevent problems caused by this inconsistency.\n        if (oms == null) {\n            return new InstrumentMethodGroupResponse(null);\n        }\n\n        Object[] ret = oms.getMethodsToInstrumentUponClassLoad(cmd.getClassName(), cmd.getThisAndParentLoaderData()[0]);\n\n        if (ret == null) {\n            return new InstrumentMethodGroupResponse(null);\n        } else {\n            int maxInstrClassId = status.getNInstrClasses();\n\n            return new InstrumentMethodGroupResponse((String[]) ret[0], (int[]) ret[1], (byte[][]) ret[2], null, maxInstrClassId);\n        }\n    }\n\n    // ------------------------------------ Transitive method closure instrumentation ------------------------------------\n    private InstrumentMethodGroupResponse createInitialInstrumentMethodGroupResponseForCallGraph(RootClassLoadedCommand rootLoaded) {\n        //System.err.println(\"*** Received root class load event for class names: \");\n        //for (int i = 0; i < rootClassNames.length; i++) System.err.println(\"  \" + rootClassNames[i] + \".\" +\n        // rootMethodNames[i] + rootMethodSignatures[i]);\n        //System.err.println(\"*** Number of target VM loaded classes: \" + loadedClasses.length);\n        //System.err.println(\"*** Root classes are at positions:\");\n        //for (int i = 0; i < loadedClasses.length; i++) {\n        //System.err.println(loadedClasses[i]);\n        //for (int j = 0; j < rootClassNames.length; j++) {\n        //  if (loadedClasses[i].equals(rootClassNames[j])) System.err.println(\"  \" + i + \" - \" + rootClassNames[j]);\n        //}\n        //}\n        Object[] ret;\n\n        switch (settings.getInstrScheme()) {\n            case INSTRSCHEME_LAZY:\n                ms = new RecursiveMethodInstrumentor1(classRepo, status, settings);\n\n                break;\n            case INSTRSCHEME_EAGER:\n                ms = new RecursiveMethodInstrumentor2(classRepo, status, settings);\n\n                break;\n            case INSTRSCHEME_TOTAL:\n                ms = new RecursiveMethodInstrumentor3(classRepo, status, settings);\n\n                break;\n        }\n\n        ret = ms.getInitialMethodsToInstrument(rootLoaded, rootMethods);\n\n        if (ret == null) {\n            return new InstrumentMethodGroupResponse(null);\n        } else {\n            return new InstrumentMethodGroupResponse((String[]) ret[0], (int[]) ret[1], (byte[][]) ret[3], (boolean[]) ret[2], 0);\n        }\n    }\n\n    // ---------------------------------- Code region instrumentation ----------------------------------------------------\n    private InstrumentMethodGroupResponse createInitialInstrumentMethodGroupResponseForCodeRegion(RootClassLoadedCommand rootLoaded)\n        throws ClassNotFoundException, BadLocationException {\n        classRepo.clearCache();\n\n        crms = new CodeRegionMethodInstrumentor(classRepo, status, savedSourceCodeSelection);\n\n        Object[] ret = crms.getInitialInstrumentCodeRegionResponse(rootLoaded);\n\n        if (ret == null) {\n            return new InstrumentMethodGroupResponse(null);\n        }\n\n        return new InstrumentMethodGroupResponse((String[]) ret[0], (int[]) ret[1], (byte[][]) ret[2], null, 0);\n    }\n\n    // -------------------------------------- Memory profiling instrumentation -------------------------------------------\n    private InstrumentMethodGroupResponse createInitialInstrumentMethodGroupResponseForMemoryProfiling(int instrType,\n                                                                         RootClassLoadedCommand rootLoaded) {\n        //System.out.println(\"+++++++++ Received memory profiling instrumentation initialization event of type \"\n        // + instrType);\n        //System.out.println(\"+++++++++ Number of target VM loaded classes: \" + loadedClasses.length);\n        oms = new ObjLivenessMethodInstrumentor(classRepo, status, settings, (instrType == INSTR_OBJECT_LIVENESS));\n\n        Object[] ret = oms.getInitialMethodsToInstrument(rootLoaded);\n\n        if (ret == null) {\n            return new InstrumentMethodGroupResponse(null);\n        } else {\n            int maxInstrClassId = oms.getNInstantiatableClasses() + status.getNInstrClasses();\n\n            return new InstrumentMethodGroupResponse((String[]) ret[0], (int[]) ret[1], (byte[][]) ret[2], null, maxInstrClassId);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/JavaClassConstants.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\n\n/**\n * Various constants that may be used in a binary class file.\n *\n * @author Misha Dmitriev\n */\npublic interface JavaClassConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    /* Class file constants */\n    public static final int JAVA_MAGIC = 0xCAFEBABE;\n    public static final int JAVA_MAJOR_VERSION = 69;\n    public static final int JAVA_MINOR_VERSION = 0;\n    public static final int JAVA_MIN_MAJOR_VERSION = 45;\n    public static final int JAVA_MIN_MINOR_VERSION = 3;\n\n    /* Constant pool entries tag constants */\n    public static final int CONSTANT_Utf8 = 1;\n    public static final int CONSTANT_Unicode = 2;\n    public static final int CONSTANT_Integer = 3;\n    public static final int CONSTANT_Float = 4;\n    public static final int CONSTANT_Long = 5;\n    public static final int CONSTANT_Double = 6;\n    public static final int CONSTANT_Class = 7;\n    public static final int CONSTANT_String = 8;\n    public static final int CONSTANT_Fieldref = 9;\n    public static final int CONSTANT_Methodref = 10;\n    public static final int CONSTANT_InterfaceMethodref = 11;\n    public static final int CONSTANT_NameAndType = 12;\n    public static final int CONSTANT_unused13 = 13;\n    public static final int CONSTANT_unused14 = 14;\n    public static final int CONSTANT_MethodHandle = 15;\n    public static final int CONSTANT_MethodType = 16;\n    public static final int CONSTANT_Dynamic = 17;\n    public static final int CONSTANT_InvokeDynamic = 18;\n    public static final int CONSTANT_Module = 19;\n    public static final int CONSTANT_Package = 20;\n\n    /* Opcodes */\n    static final int opc_try = -3;\n    static final int opc_dead = -2;\n    static final int opc_label = -1;\n    static final int opc_nop = 0;\n    static final int opc_aconst_null = 1;\n    static final int opc_iconst_m1 = 2;\n    static final int opc_iconst_0 = 3;\n    static final int opc_iconst_1 = 4;\n    static final int opc_iconst_2 = 5;\n    static final int opc_iconst_3 = 6;\n    static final int opc_iconst_4 = 7;\n    static final int opc_iconst_5 = 8;\n    static final int opc_lconst_0 = 9;\n    static final int opc_lconst_1 = 10;\n    static final int opc_fconst_0 = 11;\n    static final int opc_fconst_1 = 12;\n    static final int opc_fconst_2 = 13;\n    static final int opc_dconst_0 = 14;\n    static final int opc_dconst_1 = 15;\n    static final int opc_bipush = 16;\n    static final int opc_sipush = 17;\n    static final int opc_ldc = 18;\n    static final int opc_ldc_w = 19;\n    static final int opc_ldc2_w = 20;\n    static final int opc_iload = 21;\n    static final int opc_lload = 22;\n    static final int opc_fload = 23;\n    static final int opc_dload = 24;\n    static final int opc_aload = 25;\n    static final int opc_iload_0 = 26;\n    static final int opc_iload_1 = 27;\n    static final int opc_iload_2 = 28;\n    static final int opc_iload_3 = 29;\n    static final int opc_lload_0 = 30;\n    static final int opc_lload_1 = 31;\n    static final int opc_lload_2 = 32;\n    static final int opc_lload_3 = 33;\n    static final int opc_fload_0 = 34;\n    static final int opc_fload_1 = 35;\n    static final int opc_fload_2 = 36;\n    static final int opc_fload_3 = 37;\n    static final int opc_dload_0 = 38;\n    static final int opc_dload_1 = 39;\n    static final int opc_dload_2 = 40;\n    static final int opc_dload_3 = 41;\n    static final int opc_aload_0 = 42;\n    static final int opc_aload_1 = 43;\n    static final int opc_aload_2 = 44;\n    static final int opc_aload_3 = 45;\n    static final int opc_iaload = 46;\n    static final int opc_laload = 47;\n    static final int opc_faload = 48;\n    static final int opc_daload = 49;\n    static final int opc_aaload = 50;\n    static final int opc_baload = 51;\n    static final int opc_caload = 52;\n    static final int opc_saload = 53;\n    static final int opc_istore = 54;\n    static final int opc_lstore = 55;\n    static final int opc_fstore = 56;\n    static final int opc_dstore = 57;\n    static final int opc_astore = 58;\n    static final int opc_istore_0 = 59;\n    static final int opc_istore_1 = 60;\n    static final int opc_istore_2 = 61;\n    static final int opc_istore_3 = 62;\n    static final int opc_lstore_0 = 63;\n    static final int opc_lstore_1 = 64;\n    static final int opc_lstore_2 = 65;\n    static final int opc_lstore_3 = 66;\n    static final int opc_fstore_0 = 67;\n    static final int opc_fstore_1 = 68;\n    static final int opc_fstore_2 = 69;\n    static final int opc_fstore_3 = 70;\n    static final int opc_dstore_0 = 71;\n    static final int opc_dstore_1 = 72;\n    static final int opc_dstore_2 = 73;\n    static final int opc_dstore_3 = 74;\n    static final int opc_astore_0 = 75;\n    static final int opc_astore_1 = 76;\n    static final int opc_astore_2 = 77;\n    static final int opc_astore_3 = 78;\n    static final int opc_iastore = 79;\n    static final int opc_lastore = 80;\n    static final int opc_fastore = 81;\n    static final int opc_dastore = 82;\n    static final int opc_aastore = 83;\n    static final int opc_bastore = 84;\n    static final int opc_castore = 85;\n    static final int opc_sastore = 86;\n    static final int opc_pop = 87;\n    static final int opc_pop2 = 88;\n    static final int opc_dup = 89;\n    static final int opc_dup_x1 = 90;\n    static final int opc_dup_x2 = 91;\n    static final int opc_dup2 = 92;\n    static final int opc_dup2_x1 = 93;\n    static final int opc_dup2_x2 = 94;\n    static final int opc_swap = 95;\n    static final int opc_iadd = 96;\n    static final int opc_ladd = 97;\n    static final int opc_fadd = 98;\n    static final int opc_dadd = 99;\n    static final int opc_isub = 100;\n    static final int opc_lsub = 101;\n    static final int opc_fsub = 102;\n    static final int opc_dsub = 103;\n    static final int opc_imul = 104;\n    static final int opc_lmul = 105;\n    static final int opc_fmul = 106;\n    static final int opc_dmul = 107;\n    static final int opc_idiv = 108;\n    static final int opc_ldiv = 109;\n    static final int opc_fdiv = 110;\n    static final int opc_ddiv = 111;\n    static final int opc_irem = 112;\n    static final int opc_lrem = 113;\n    static final int opc_frem = 114;\n    static final int opc_drem = 115;\n    static final int opc_ineg = 116;\n    static final int opc_lneg = 117;\n    static final int opc_fneg = 118;\n    static final int opc_dneg = 119;\n    static final int opc_ishl = 120;\n    static final int opc_lshl = 121;\n    static final int opc_ishr = 122;\n    static final int opc_lshr = 123;\n    static final int opc_iushr = 124;\n    static final int opc_lushr = 125;\n    static final int opc_iand = 126;\n    static final int opc_land = 127;\n    static final int opc_ior = 128;\n    static final int opc_lor = 129;\n    static final int opc_ixor = 130;\n    static final int opc_lxor = 131;\n    static final int opc_iinc = 132;\n    static final int opc_i2l = 133;\n    static final int opc_i2f = 134;\n    static final int opc_i2d = 135;\n    static final int opc_l2i = 136;\n    static final int opc_l2f = 137;\n    static final int opc_l2d = 138;\n    static final int opc_f2i = 139;\n    static final int opc_f2l = 140;\n    static final int opc_f2d = 141;\n    static final int opc_d2i = 142;\n    static final int opc_d2l = 143;\n    static final int opc_d2f = 144;\n    static final int opc_i2b = 145;\n    static final int opc_i2c = 146;\n    static final int opc_i2s = 147;\n    static final int opc_lcmp = 148;\n    static final int opc_fcmpl = 149;\n    static final int opc_fcmpg = 150;\n    static final int opc_dcmpl = 151;\n    static final int opc_dcmpg = 152;\n    static final int opc_ifeq = 153;\n    static final int opc_ifne = 154;\n    static final int opc_iflt = 155;\n    static final int opc_ifge = 156;\n    static final int opc_ifgt = 157;\n    static final int opc_ifle = 158;\n    static final int opc_if_icmpeq = 159;\n    static final int opc_if_icmpne = 160;\n    static final int opc_if_icmplt = 161;\n    static final int opc_if_icmpge = 162;\n    static final int opc_if_icmpgt = 163;\n    static final int opc_if_icmple = 164;\n    static final int opc_if_acmpeq = 165;\n    static final int opc_if_acmpne = 166;\n    static final int opc_goto = 167;\n    static final int opc_jsr = 168;\n    static final int opc_ret = 169;\n    static final int opc_tableswitch = 170;\n    static final int opc_lookupswitch = 171;\n    static final int opc_ireturn = 172;\n    static final int opc_lreturn = 173;\n    static final int opc_freturn = 174;\n    static final int opc_dreturn = 175;\n    static final int opc_areturn = 176;\n    static final int opc_return = 177;\n    static final int opc_getstatic = 178;\n    static final int opc_putstatic = 179;\n    static final int opc_getfield = 180;\n    static final int opc_putfield = 181;\n    static final int opc_invokevirtual = 182;\n    static final int opc_invokespecial = 183;\n    static final int opc_invokestatic = 184;\n    static final int opc_invokeinterface = 185;\n    static final int opc_invokedynamic = 186;\n    static final int opc_new = 187;\n    static final int opc_newarray = 188;\n    static final int opc_anewarray = 189;\n    static final int opc_arraylength = 190;\n    static final int opc_athrow = 191;\n    static final int opc_checkcast = 192;\n    static final int opc_instanceof = 193;\n    static final int opc_monitorenter = 194;\n    static final int opc_monitorexit = 195;\n    static final int opc_wide = 196;\n    static final int opc_multianewarray = 197;\n    static final int opc_ifnull = 198;\n    static final int opc_ifnonnull = 199;\n    static final int opc_goto_w = 200;\n    static final int opc_jsr_w = 201;\n    static final int opc_breakpoint = 202;\n    public static final int[] opc_length = {\n                                    1, // opc_nop\n                                    1, // opc_aconst_null              = 1;\n                                    1, // opc_iconst_m1                = 2;\n                                    1, // opc_iconst_0                 = 3;\n                                    1, // opc_iconst_1                 = 4;\n                                    1, // opc_iconst_2                 = 5;\n                                    1, // opc_iconst_3                 = 6;\n                                    1, // opc_iconst_4                 = 7;\n                                    1, // opc_iconst_5                 = 8;\n                                    1, // opc_lconst_0                 = 9;\n                                    1, // opc_lconst_1                 = 10;\n                                    1, // opc_fconst_0                 = 11;\n                                    1, // opc_fconst_1                 = 12;\n                                    1, // opc_fconst_2                 = 13;\n                                    1, // opc_dconst_0                 = 14;\n                                    1, // opc_dconst_1                 = 15;\n                                    2, // opc_bipush\n                                    3, // opc_sipush\n                                    2, // opc_ldc\n                                    3, // opc_ldc_w\n                                    3, // opc_ldc2_w\n                                    2, // opc_iload\n                                    2, // opc_lload\n                                    2, // opc_fload\n                                    2, // opc_dload\n                                    2, // opc_aload\n                                    1, // opc_iload_0                  = 26;\n                                    1, // opc_iload_1                  = 27;\n                                    1, // opc_iload_2                  = 28;\n                                    1, // opc_iload_3                  = 29;\n                                    1, // opc_lload_0                  = 30;\n                                    1, // opc_lload_1                  = 31;\n                                    1, // opc_lload_2                  = 32;\n                                    1, // opc_lload_3                  = 33;\n                                    1, // opc_fload_0                  = 34;\n                                    1, // opc_fload_1                  = 35;\n                                    1, // opc_fload_2                  = 36;\n                                    1, // opc_fload_3                  = 37;\n                                    1, // opc_dload_0                  = 38;\n                                    1, // opc_dload_1                  = 39;\n                                    1, // opc_dload_2                  = 40;\n                                    1, // opc_dload_3                  = 41;\n                                    1, // opc_aload_0                  = 42;\n                                    1, // opc_aload_1                  = 43;\n                                    1, // opc_aload_2                  = 44;\n                                    1, // opc_aload_3                  = 45;\n                                    1, // opc_iaload                   = 46;\n                                    1, // opc_laload                   = 47;\n                                    1, // opc_faload                   = 48;\n                                    1, // opc_daload                   = 49;\n                                    1, // opc_aaload                   = 50;\n                                    1, // opc_baload                   = 51;\n                                    1, // opc_caload                   = 52;\n                                    1, // opc_saload                   = 53;\n                                    2, // opc_istore\n                                    2, // opc_lstore\n                                    2, // opc_fstore\n                                    2, // opc_dstore\n                                    2, // opc_astore\n                                    1, // opc_istore_0                 = 59;\n                                    1, // opc_istore_1                 = 60;\n                                    1, // opc_istore_2                 = 61;\n                                    1, // opc_istore_3                 = 62;\n                                    1, // opc_lstore_0                 = 63;\n                                    1, // opc_lstore_1                 = 64;\n                                    1, // opc_lstore_2                 = 65;\n                                    1, // opc_lstore_3                 = 66;\n                                    1, // opc_fstore_0                 = 67;\n                                    1, // opc_fstore_1                 = 68;\n                                    1, // opc_fstore_2                 = 69;\n                                    1, // opc_fstore_3                 = 70;\n                                    1, // opc_dstore_0                 = 71;\n                                    1, // opc_dstore_1                 = 72;\n                                    1, // opc_dstore_2                 = 73;\n                                    1, // opc_dstore_3                 = 74;\n                                    1, // opc_astore_0                 = 75;\n                                    1, // opc_astore_1                 = 76;\n                                    1, // opc_astore_2                 = 77;\n                                    1, // opc_astore_3                 = 78;\n                                    1, // opc_iastore                  = 79;\n                                    1, // opc_lastore                  = 80;\n                                    1, // opc_fastore                  = 81;\n                                    1, // opc_dastore                  = 82;\n                                    1, // opc_aastore                  = 83;\n                                    1, // opc_bastore                  = 84;\n                                    1, // opc_castore                  = 85;\n                                    1, // opc_sastore                  = 86;\n                                    1, // opc_pop                      = 87;\n                                    1, // opc_pop2                     = 88;\n                                    1, // opc_dup                      = 89;\n                                    1, // opc_dup_x1                   = 90;\n                                    1, // opc_dup_x2                   = 91;\n                                    1, // opc_dup2                     = 92;\n                                    1, // opc_dup2_x1                  = 93;\n                                    1, // opc_dup2_x2                  = 94;\n                                    1, // opc_swap                     = 95;\n                                    1, // opc_iadd                     = 96;\n                                    1, // opc_ladd                     = 97;\n                                    1, // opc_fadd                     = 98;\n                                    1, // opc_dadd                     = 99;\n                                    1, // opc_isub                     = 100;\n                                    1, // opc_lsub                     = 101;\n                                    1, // opc_fsub                     = 102;\n                                    1, // opc_dsub                     = 103;\n                                    1, // opc_imul                     = 104;\n                                    1, // opc_lmul                     = 105;\n                                    1, // opc_fmul                     = 106;\n                                    1, // opc_dmul                     = 107;\n                                    1, // opc_idiv                     = 108;\n                                    1, // opc_ldiv                     = 109;\n                                    1, // opc_fdiv                     = 110;\n                                    1, // opc_ddiv                     = 111;\n                                    1, // opc_irem                     = 112;\n                                    1, // opc_lrem                     = 113;\n                                    1, // opc_frem                     = 114;\n                                    1, // opc_drem                     = 115;\n                                    1, // opc_ineg                     = 116;\n                                    1, // opc_lneg                     = 117;\n                                    1, // opc_fneg                     = 118;\n                                    1, // opc_dneg                     = 119;\n                                    1, // opc_ishl                     = 120;\n                                    1, // opc_lshl                     = 121;\n                                    1, // opc_ishr                     = 122;\n                                    1, // opc_lshr                     = 123;\n                                    1, // opc_iushr                    = 124;\n                                    1, // opc_lushr                    = 125;\n                                    1, // opc_iand                     = 126;\n                                    1, // opc_land                     = 127;\n                                    1, // opc_ior                      = 128;\n                                    1, // opc_lor                      = 129;\n                                    1, // opc_ixor                     = 130;\n                                    1, // opc_lxor                     = 131;\n                                    3, // opc_iinc\n                                    1, // opc_i2l                      = 133;\n                                    1, // opc_i2f                      = 134;\n                                    1, // opc_i2d                      = 135;\n                                    1, // opc_l2i                      = 136;\n                                    1, // opc_l2f                      = 137;\n                                    1, // opc_l2d                      = 138;\n                                    1, // opc_f2i                      = 139;\n                                    1, // opc_f2l                      = 140;\n                                    1, // opc_f2d                      = 141;\n                                    1, // opc_d2i                      = 142;\n                                    1, // opc_d2l                      = 143;\n                                    1, // opc_d2f                      = 144;\n                                    1, // opc_i2b                      = 145;\n                                    1, // opc_i2c                      = 146;\n                                    1, // opc_i2s                      = 147;\n                                    1, // opc_lcmp                     = 148;\n                                    1, // opc_fcmpl                    = 149;\n                                    1, // opc_fcmpg                    = 150;\n                                    1, // opc_dcmpl                    = 151;\n                                    1, // opc_dcmpg                    = 152;\n                                    3, // opc_ifeq\n                                    3, // opc_ifne\n                                    3, // opc_iflt\n                                    3, // opc_ifge\n                                    3, // opc_ifgt\n                                    3, // opc_ifle\n                                    3, // opc_if_icmpeq\n                                    3, // opc_if_icmpne\n                                    3, // opc_if_icmplt\n                                    3, // opc_if_icmpge\n                                    3, // opc_if_icmpgt\n                                    3, // opc_if_icmple\n                                    3, // opc_if_acmpeq\n                                    3, // opc_if_acmpne\n                                    3, // opc_goto\n                                    3, // opc_jsr\n                                    2, // opc_ret\n                                    0, // opc_tableswitch - variable length, handled specially\n                                    0, // opc_lookupswitch - variable length, handled specially\n                                    1, // opc_ireturn                  = 172;\n                                    1, // opc_lreturn                  = 173;\n                                    1, // opc_freturn                  = 174;\n                                    1, // opc_dreturn                  = 175;\n                                    1, // opc_areturn                  = 176;\n                                    1, // opc_return                   = 177;\n                                    3, // opc_getstatic\n                                    3, // opc_putstatic\n                                    3, // opc_getfield\n                                    3, // opc_putfield\n                                    3, // opc_invokevirtual\n                                    3, // opc_invokespecial\n                                    3, // opc_invokestatic\n                                    5, // opc_invokeinterface\n                                    5, // opc_invokedynamic\n                                    3, // opc_new\n                                    2, // opc_newarray\n                                    3, // opc_anewarray\n                                    1, // opc_arraylength              = 190;\n                                    1, // opc_athrow                   = 191;\n                                    3, // opc_checkcast\n                                    3, // opc_instanceof\n                                    1, // opc_monitorenter             = 194;\n                                    1, // opc_monitorexit              = 195;\n                                    0, // opc_wide - special handling\n                                    4, // opc_multianewarray\n                                    3, // opc_ifnull\n                                    3, // opc_ifnonnull\n                                    5, // opc_goto_w\n                                    5, // opc_jsr_w\n                                    0, // opc_breakpoint\n                                };\n\n    /* Primitive type array codes (used by opc_newarray opcode) */\n    public static final int T_BOOLEAN = 4; // Z\n    public static final int T_CHAR = 5; // C\n    public static final int T_FLOAT = 6; // F\n    public static final int T_DOUBLE = 7; // D\n    public static final int T_BYTE = 8; // B\n    public static final int T_SHORT = 9; // S\n    public static final int T_INT = 10; // I\n    public static final int T_LONG = 11; // J\n    public static final String[] PRIMITIVE_ARRAY_TYPE_NAMES = {\n                                    null,\n                                    null,\n                                    null,\n                                    null, \n                                    \"[Z\", // NOI18N\n                                    \"[C\", // NOI18N\n                                    \"[F\", // NOI18N\n                                    \"[D\", // NOI18N\n                                    \"[B\", // NOI18N\n                                    \"[S\", // NOI18N\n                                    \"[I\", // NOI18N\n                                    \"[J\" // NOI18N\n                                };\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/MemoryProfMethodInstrumentor.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.classfile.BaseClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.VMUtils;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.RootClassLoadedCommand;\n\n\n/**\n * Base class providing common functionality for instrumenting TA methods to generate object allocation/liveness data.\n * The fact that there are two classes at this time, MemoryProfMethodInstrumentor and ObjLivenessMethodInstrumentor, is\n * explained by purely historical reasons - in the past we had instrumentation implemented differently for object allocation\n * and liveness profiling. Now the same kind of instrumentation is used for both profiling types (the exact method names\n * for injected calls are different, but the way of injecting these calls and their signatures are exactly the same).\n *\n * In principle, MemoryProfMethodInstrumentor and ObjLivenessMethodInstrumentor can be merged, but there is no compelling\n * need for that. Furthermore, if in future say some different memory instrumentation kind is introduced, this division\n * may help.\n *\n * @author Misha Dmitriev\n */\npublic abstract class MemoryProfMethodInstrumentor extends ClassManager {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    class MethodScanerForNewOpcodes extends SingleMethodScaner {\n        private final InstrumentationFilter instrFilter;\n\n        MethodScanerForNewOpcodes(ClassInfo clazz, int methodIdx, InstrumentationFilter filter) {\n            super(clazz, methodIdx);\n            instrFilter = filter;\n        }\n        \n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        boolean hasNewOpcodes(MemoryProfMethodInstrumentor minstr, boolean checkForOpcNew, boolean checkForOpcNewArray) {\n            if (!checkForOpcNew && !checkForOpcNewArray) return false;\n            int loaderId = clazz.getLoaderId();\n            boolean found = false;\n            int bc;\n            int bci = 0;\n\n            while (bci < bytecodesLength) {\n                bc = (bytecodes[bci] & 0xFF);\n\n                if ((bc == opc_new) && checkForOpcNew) {\n\n                    int classCPIdx = getU2(bci + 1);\n                    String refClassName = clazz.getRefClassName(classCPIdx);\n                    if (instrFilter.passes(refClassName)) {\n                        found = true;\n                        BaseClassInfo refClazz = javaClassOrPlaceholderForName(refClassName, loaderId);\n\n                        if (refClazz.getInstrClassId() == -1) {\n                            refClazz.setInstrClassId(minstr.getNextClassId(refClazz.getName()));\n                        }\n                    }                    \n                } else if ((bc == opc_anewarray || bc == opc_multianewarray) && checkForOpcNewArray) {\n\n                    int classCPIdx = getU2(bci + 1);\n                    String refClassName = clazz.getRefClassName(classCPIdx);\n                    BaseClassInfo refClazz = null;\n                    if (bc == opc_anewarray) {\n                        if (instrFilter.passes(refClassName.concat(\"[]\"))) {    // NOI18N\n                            refClazz = javaClassForObjectArrayType(refClassName);\n                        }\n                    } else { // opc_multianewarray\n                        if (instrFilter.passes(getMultiArrayClassName(refClassName))) {\n                            refClazz = classRepo.lookupSpecialClass(refClassName);\n                        }\n                    }\n\n                    if (refClazz != null) { // Warning already issued\n                        found = true;\n\n                        if (refClazz.getInstrClassId() == -1) {\n                            refClazz.setInstrClassId(minstr.getNextClassId(refClazz.getName()));\n                        }\n                    }\n                } else if (bc == opc_newarray && checkForOpcNewArray) {\n                    int arrayClassId = getByte(bci + 1);\n                    BaseClassInfo refClazz = javaClassForPrimitiveArrayType(arrayClassId);\n                    String className = StringUtils.userFormClassName(refClazz.getName());\n\n                    if (instrFilter.passes(className)) {\n                        found = true;\n                        if (refClazz.getInstrClassId() == -1) {\n                            refClazz.setInstrClassId(minstr.getNextClassId(refClazz.getName()));\n                        }\n                    }\n                }\n\n                bci += opcodeLength(bci);\n            }\n\n            return found;\n        }\n\n        private String getMultiArrayClassName(String refClassName) {\n            int dimension = refClassName.lastIndexOf('[');\n            String baseClass = refClassName.substring(dimension + 1);\n\n            if (VMUtils.isVMPrimitiveType(baseClass)) {\n                return StringUtils.userFormClassName(refClassName);\n            } else {\n                StringBuilder arrayClass = new StringBuilder(refClassName.length() + dimension + 1);\n                arrayClass.append(refClassName.substring(dimension + 1));\n\n                for (int i = 0; i <= dimension; i++) {\n                    arrayClass.append(\"[]\");        // NOI18N\n                }\n                return arrayClass.toString();\n            }\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected ArrayList instrClasses = new ArrayList();\n    protected String[] instantiatableClasses;\n    protected int injType;\n    protected int instrClassId;\n    protected int nInstantiatableClasses;\n    protected int nInstrClasses;\n    protected int nInstrMethods;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public MemoryProfMethodInstrumentor(ClassRepository repo, ProfilingSessionStatus status, int injType) {\n        super(repo, status);\n        this.status = status;\n        instantiatableClasses = new String[100];\n        this.injType = injType;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Object[] getInitialMethodsToInstrument(RootClassLoadedCommand rootLoaded) {\n        List classes = new ArrayList();\n        resetLoadedClassData();\n        initInstrumentationPackData();\n        instrClassId = 0;\n\n        storeClassFileBytesForCustomLoaderClasses(rootLoaded);\n\n        String[] loadedClasses = rootLoaded.getAllLoadedClassNames();\n        int[] loadedClassLoaderIds = rootLoaded.getAllLoadedClassLoaderIds();\n        for (int i = 0; i < loadedClasses.length; i++) {\n            DynamicClassInfo clazz = javaClassForName(loadedClasses[i], loadedClassLoaderIds[i]);\n\n            if (classNeedsInstrumentation(clazz)) {\n                clazz.preloadBytecode();\n            }\n            classes.add(clazz);\n        }\n        for (Object clazz : classes) {\n            findAndMarkMethodsToInstrumentInClass((DynamicClassInfo) clazz);\n        }\n\n        return createInstrumentedMethodPack();\n    }\n\n    public String[] getInstantiatableClasses() {\n        return instantiatableClasses;\n    }\n\n    public Object[] getMethodsToInstrumentUponClassLoad(String className, int classLoaderId) {\n        initInstrumentationPackData();\n        findAndMarkMethodsToInstrumentInClass(className, classLoaderId);\n\n        return createInstrumentedMethodPack();\n    }\n\n    public int getNInstantiatableClasses() {\n        return nInstantiatableClasses;\n    }\n\n    /** Checks if there are any methods in this class that need to be instrumented. */\n    protected void findAndMarkMethodsToInstrumentInClass(String className, int classLoaderId) {\n        findAndMarkMethodsToInstrumentInClass(javaClassForName(className, classLoaderId));\n    }\n    \n    /** Checks if there are any methods in this class that need to be instrumented. */\n    protected void findAndMarkMethodsToInstrumentInClass(DynamicClassInfo clazz) {\n        if (clazz == null) {\n            return; // Warning has already been reported\n        }\n\n        if (!clazz.isLoaded()) {\n            clazz.setLoaded(true);\n\n            // We assign an ID to class no matter whether or not this class is going to be instantiated anywhere in the program\n            // As a result, we may have quite some classes that are in the appropriate table in 'status', but have zero objects\n            // associated with them forever.\n            // I am not sure why this is done here, but perhaps there was a good reason for this. Need to comment such things immediately...\n            if ((clazz.getInstrClassId() == -1) && !clazz.isInterface()) {\n                clazz.setInstrClassId(getNextClassId(clazz.getName()));\n            }\n\n            if (classNeedsInstrumentation(clazz)) {\n                String[] methodNames = clazz.getMethodNames();\n                boolean found = false;\n\n                for (int i = 0; i < methodNames.length; i++) {\n                    if (clazz.isMethodNative(i) || clazz.isMethodAbstract(i)) {\n                        clazz.setMethodUnscannable(i);\n\n                        continue;\n                    }\n\n                    if (methodNeedsInstrumentation(clazz, i)) {\n                        nInstrMethods++;\n                        clazz.setMethodInstrumented(i);\n                        found = true;\n                    }\n                }\n\n                if (found) {\n                    nInstrClasses++;\n                    instrClasses.add(clazz);\n                }\n            }\n        }\n    }\n\n    protected void initInstrumentationPackData() {\n        instrClasses.clear();\n        nInstrClasses = nInstrMethods = 0;\n        nInstantiatableClasses = 0;\n    }\n\n    protected abstract boolean classNeedsInstrumentation(ClassInfo clazz);\n    protected abstract boolean methodNeedsInstrumentation(ClassInfo clazz, int methodIdx);\n\n    /** Creates a multi-class packet of instrumented methods or classes */\n    protected Object[] createInstrumentedMethodPack() {\n        if (nInstrMethods == 0) {\n            return null;\n        }\n\n        return createInstrumentedMethodPack15();\n    }\n\n    protected boolean hasNewOpcodes(ClassInfo clazz, int methodIdx, boolean checkForOpcNew, boolean checkForOpcNewArray, InstrumentationFilter instrFilter) {\n        MethodScanerForNewOpcodes msfno = new MethodScanerForNewOpcodes(clazz, methodIdx, instrFilter);\n\n        return msfno.hasNewOpcodes(this, checkForOpcNew, checkForOpcNewArray);\n    }\n\n    protected abstract byte[] instrumentMethod(DynamicClassInfo clazz, int methodIdx);\n\n    protected boolean methodNeedsRewriting(DynamicClassInfo clazz, int methodIdx) {\n        return clazz.isMethodInstrumented(methodIdx);\n    }\n\n    int getNextClassId(String className) {\n        if (nInstantiatableClasses == instantiatableClasses.length) {\n            String[] oldInstantiatableClasses = instantiatableClasses;\n            instantiatableClasses = new String[oldInstantiatableClasses.length + 100];\n            System.arraycopy(oldInstantiatableClasses, 0, instantiatableClasses, 0, oldInstantiatableClasses.length);\n        }\n\n        instantiatableClasses[nInstantiatableClasses++] = className;\n        status.updateAllocatedInstancesCountInfoInClient(className);\n\n        return instrClassId++;\n    }\n\n    /** Creates the 1.5-style array of instrumented class files. */\n    private Object[] createInstrumentedMethodPack15() {\n        String[] instrMethodClasses = new String[nInstrClasses];\n        int[] instrClassLoaderIds = new int[nInstrClasses];\n        byte[][] replacementClassFileBytes = new byte[nInstrClasses][];\n\n        for (int j = 0; j < nInstrClasses; j++) {\n            DynamicClassInfo clazz = (DynamicClassInfo) instrClasses.get(j);\n            instrMethodClasses[j] = clazz.getName().replace('/', '.'); // NOI18N\n            instrClassLoaderIds[j] = clazz.getLoaderId();\n\n            String[] methodNames = clazz.getMethodNames();\n            int nMethods = methodNames.length;\n            byte[][] replacementMethodInfos = new byte[nMethods][];\n\n            DynamicConstantPoolExtension.getCPFragment(clazz, injType);\n\n            for (int i = 0; i < nMethods; i++) {\n                if (methodNeedsRewriting(clazz, i)) {\n                    replacementMethodInfos[i] = instrumentMethod(clazz, i);\n                } else {\n                    replacementMethodInfos[i] = clazz.getMethodInfo(i);\n                }\n            }\n\n            DynamicConstantPoolExtension wholeECP = DynamicConstantPoolExtension.getAllAddedCPFragments(clazz);\n            int nAddedCPEntries = wholeECP.getNEntries();\n            byte[] addedCPContents = wholeECP.getContents();\n            replacementClassFileBytes[j] = ClassRewriter.rewriteClassFile(clazz, replacementMethodInfos, nAddedCPEntries,\n                                                                          addedCPContents);\n        }\n\n        return new Object[] { instrMethodClasses, instrClassLoaderIds, replacementClassFileBytes };\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/MethodEntryExitCallsInjector.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport java.io.ByteArrayOutputStream;\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\nimport static org.graalvm.visualvm.lib.jfluid.utils.VMUtils.*;\n\n/**\n * Specialized subclass of Injector, that provides injection of our standard\n * \"recursive\" instrumentation - methodEntry(char methodId) (rootEntry(char\n * methodId)) and methodExit(char methodId) calls - in appropriate places in TA\n * methods.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\nclass MethodEntryExitCallsInjector extends Injector implements CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // Stuff used for rootEntry(char), methodEntry(char), and methodExit(char) injection interchangeably\n    protected static byte[] injCode1;\n    protected static int injCodeLen1;\n    protected static int injCodeMethodIdxPos1;\n    protected static int injCodeMethodIdPos1;\n\n    // Stuff used for the equivalent of try { .. } catch (Throwable ex) { methodExit(methodId); throw ex; } around the whole method\n    protected static byte[] injCode2;\n    protected static int injCodeLen2;\n    protected static int injCodeMethodIdxPos2;\n    protected static int injCodeMethodIdPos2;\n\n    // Stuff used for markerMethodExit(Object, char) injection\n    protected static byte[] injCode3;\n    protected static int injCodeLen3;\n    protected static int injCodeMethodIdxPos3;\n    protected static int injCodeMethodIdPos3;\n\n    static {\n        initializeInjectedCode();\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n    protected int baseRootCPoolCount; // cpool base for root method type injection cpool fragment\n    protected int injType; // INJ_RECURSIVE_NORMAL_METHOD, INJ_RECURSIVE_ROOT_METHOD, or same with _SAMPLED_ added\n    protected int methodId; // methodId (char parameter value) that methodEntry(methodId) etc. should be invoked with\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n    MethodEntryExitCallsInjector(DynamicClassInfo clazz, int normalInstrBaseCPoolCount, int rootInstrBaseCPoolCount, int methodIdx,\n            int injType, int methodId) {\n        super(clazz, methodIdx);\n        this.injType = injType;\n        this.methodId = methodId;\n        baseCPoolCount = normalInstrBaseCPoolCount;\n        baseRootCPoolCount = rootInstrBaseCPoolCount;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    public byte[] instrumentMethod() {\n        // Determine the number of returns in this method\n        int totalReturns = 0;\n        int bci = 0;\n\n        while (bci < bytecodesLength) {\n            int bc = bytecodes[bci] & 0xFF;\n\n            if ((bc >= opc_ireturn) && (bc <= opc_return)) {\n                totalReturns++;\n            }\n\n            bci += opcodeLength(bci);\n        }\n\n        injectMethodEntry();\n        injectMethodExits(totalReturns);\n        injectGlobalCatch();\n\n        // Done very conservatively.\n        maxStack += 1;\n\n        return createPackedMethodInfo();\n    }\n\n    private static void initializeInjectedCode() {\n        // Injection for methodEntry(char methodId) (rootMethodEntry(char methodId)) and methodExit(char methodId)\n        // the length of the injected code is extended to 8, to avoid worrying about switch statement 4-byte alignment\n        injCodeLen1 = 8;\n        injCode1 = new byte[injCodeLen1];\n        injCode1[0] = (byte) opc_sipush;\n        // Positions 1, 2 are occupied by methodId\n        injCodeMethodIdPos1 = 1;\n        injCode1[3] = (byte) opc_invokestatic;\n        // Positions 4, 5 are occupied by method index\n        injCodeMethodIdxPos1 = 4;\n        injCode1[6] = injCode1[7] = (byte) opc_nop;\n\n        // Injection for the whole-method all-exceptions try - catch\n        // We do not need to worry about 4-byte alignment since this always goes to the end of a method\n        injCodeLen2 = 9;\n        injCode2 = new byte[injCodeLen2];\n        injCode2[0] = (byte) opc_astore_1;\n        injCode2[1] = (byte) opc_sipush;\n        // Positions 2, 3 are occupied by methodId\n        injCodeMethodIdPos2 = 2;\n        injCode2[4] = (byte) opc_invokestatic;\n        // Positions 5, 6 are occpupied by method index for methodExit()\n        injCodeMethodIdxPos2 = 5;\n        injCode2[7] = (byte) opc_aload_1;\n        injCode2[8] = (byte) opc_athrow;\n\n        injCodeLen3 = 8;\n        injCode3 = new byte[injCodeLen3];\n        injCode3[0] = (byte) opc_dup;\n        injCode3[1] = (byte) opc_sipush;\n        // Positions 2, 3 are occupied by methodId\n        injCodeMethodIdPos3 = 2;\n        injCode3[4] = (byte) opc_invokestatic;\n        // Positions 5, 6 are occupied by method index\n        injCodeMethodIdxPos3 = 5;\n        injCode3[7] = (byte) opc_nop;\n    }\n\n    /**\n     * Injects code that is effectively try { } catch (Throwable ex) {\n     * methodExit (); rethrow ex; } To have methodExit called even in case\n     * Errors/Exceptions are thrown.\n     */\n    private void injectGlobalCatch() {\n        int targetMethodIdx;\n\n        if ((injType == INJ_RECURSIVE_MARKER_METHOD) || (injType == INJ_RECURSIVE_SAMPLED_MARKER_METHOD)) {\n            targetMethodIdx = CPExtensionsRepository.rootContents_MarkerExitMethodIdx + baseRootCPoolCount;\n        } else {\n            targetMethodIdx = CPExtensionsRepository.normalContents_MethodExitMethodIdx + baseCPoolCount;\n        }\n\n        putU2(injCode2, injCodeMethodIdPos2, methodId);\n        putU2(injCode2, injCodeMethodIdxPos2, targetMethodIdx);\n\n        int origLen = bytecodesLength;\n        int bci = 0;\n\n        //int lastInstrBCI = 0;\n        //while (bci < bytecodesLength) {\n        //  lastInstrBCI = bci;\n        //  bci += opcodeLength(bci);\n        //}\n        // Above is the \"theoretically correct\" variant of the code: we should determine the starting offset of the\n        // last bytecode of the method, and use it as the end index in the exception table entry that we add. However,\n        // for some reason, it appears that at least in case when in the given method the last bytecode is athrow,\n        // the above code results in the exception thrown by this athrow and not caught by our global handler. This\n        // looks like a bug in the JVM, but anyway, the workaround (?), when we set the last bytecode offset equal\n        // to the start of our handler itself, works. Not sure, though, that it will pass verification... but when\n        // we have per-method verification working, we will be in a much better position to discuss this possible VM bug :-)\n        int lastInstrBCI = bytecodesLength;\n\n        appendCode(injCode2, injCodeLen2);\n        addExceptionTableEntry(0, lastInstrBCI, origLen, 0);\n        addGlobalCatchStackMapTableEntry(lastInstrBCI);\n\n        if (maxLocals < 2) {\n            maxLocals = 2;\n        }\n    }\n\n    private void injectMethodEntry() {\n        int targetMethodIdx = 0;\n\n        // Prepare the methodEntry(char methodId) or rootEntry(char methodId) code packet that is to be injected\n        if ((injType == INJ_RECURSIVE_ROOT_METHOD) || (injType == INJ_RECURSIVE_SAMPLED_ROOT_METHOD)) {\n            targetMethodIdx = CPExtensionsRepository.rootContents_RootEntryMethodIdx + baseRootCPoolCount;\n        } else if ((injType == INJ_RECURSIVE_MARKER_METHOD) || (injType == INJ_RECURSIVE_SAMPLED_MARKER_METHOD)) {\n            targetMethodIdx = CPExtensionsRepository.rootContents_MarkerEntryMethodIdx + baseRootCPoolCount;\n        } else {\n            targetMethodIdx = CPExtensionsRepository.normalContents_MethodEntryMethodIdx + baseCPoolCount;\n        }\n\n        putU2(injCode1, injCodeMethodIdxPos1, targetMethodIdx);\n        putU2(injCode1, injCodeMethodIdPos1, methodId);\n\n        injectCodeAndRewrite(injCode1, injCodeLen1, 0, true);\n        if (injType == INJ_RECURSIVE_MARKER_METHOD || injType == INJ_RECURSIVE_SAMPLED_MARKER_METHOD) {\n            // for marker method inject code to get parameters\n            ByteArrayOutputStream code = new ByteArrayOutputStream();\n            String parTypes = getParTypes();\n            int parIndex;\n            \n            if (clazz.isMethodStatic(methodIdx)) {\n                parIndex = 0;\n            } else {\n                parIndex = 1;\n                if ( !\"<init>\".equals(clazz.getMethodName(methodIdx))) {\n                    // 'this' is parameter at index 0\n                    getParInvocationCode(REFERENCE, 0, code);\n                }\n            }\n            for (char vmParType : parTypes.toCharArray()) {\n                getParInvocationCode(vmParType, parIndex, code);\n                switch (vmParType) {\n                    case DOUBLE:\n                    case LONG:\n                        parIndex+=2;\n                        break;\n                    default:\n                        parIndex++;\n                }\n            }\n            int padding = (4 - code.size() % 4) % 4;\n            for (int i = 0; i < padding; i++) {\n                code.write(opc_nop);\n            }\n            injectCodeAndRewrite(code.toByteArray(), code.size(), 0, true);        \n        }\n    }\n\n    private void injectMethodExits(int totalReturns) {\n        // Prepare the methodExit(char methodId) code packet\n        int targetMethodIdx;\n        int targetParMethodIdx = -1;\n\n        if ((injType == INJ_RECURSIVE_MARKER_METHOD) || (injType == INJ_RECURSIVE_SAMPLED_MARKER_METHOD)) {\n            targetMethodIdx = CPExtensionsRepository.rootContents_MarkerExitMethodIdx + baseRootCPoolCount;\n            targetParMethodIdx = CPExtensionsRepository.rootContents_MarkerExitParMethodIdx + baseRootCPoolCount;\n        } else {\n            targetMethodIdx = CPExtensionsRepository.normalContents_MethodExitMethodIdx + baseCPoolCount;\n        }\n\n        putU2(injCode1, injCodeMethodIdxPos1, targetMethodIdx);\n        if (targetParMethodIdx != -1) {\n            putU2(injCode3, injCodeMethodIdPos3, methodId);\n            putU2(injCode3, injCodeMethodIdxPos3, targetParMethodIdx);            \n        }        \n\n        for (int i = 0; i < totalReturns; i++) {\n            int retIdx = -1;\n            int bci = 0;\n\n            while (bci < bytecodesLength) {\n                int bc = bytecodes[bci] & 0xFF;\n\n                if ((bc >= opc_ireturn) && (bc <= opc_return)) {\n                    retIdx++;\n\n                    if (retIdx == i) {\n                        if (bc == opc_areturn && targetParMethodIdx != -1) {\n                            injectCodeAndRewrite(injCode3, injCodeLen3, bci, true);                            \n                        } else {\n                            injectCodeAndRewrite(injCode1, injCodeLen1, bci, true);\n                        }\n                        break;\n                    }\n                }\n\n                bci += opcodeLength(bci);\n            }\n        }\n    }\n\n    private String getParTypes() {\n        String sig = clazz.getMethodSignature(methodIdx);\n        int idx1 = sig.indexOf('(') + 1; // NOI18N\n        int idx2 = sig.lastIndexOf(')'); // NOI18N\n        StringBuilder paramsBuf = new StringBuilder();\n        boolean arrayIndicator;\n\n        if (idx2 > 0) {\n            String paramsString = sig.substring(idx1, idx2);\n            arrayIndicator = false;\n            int curPos = 0;\n            char nextChar;\n\n            while (curPos < paramsString.length()) {\n                while (paramsString.charAt(curPos) == '[') { // NOI18N\n                    arrayIndicator = true;\n                    curPos++;\n                }\n\n                nextChar = paramsString.charAt(curPos++);\n\n                if (nextChar == REFERENCE) { // it's a class\n                    while (paramsString.charAt(curPos) != ';') { // NOI18N\n                        curPos++;\n                    }\n                    curPos++;\n                }\n\n                if (arrayIndicator) {\n                    paramsBuf.append(REFERENCE);\n                } else {\n                    paramsBuf.append(nextChar);\n                }\n            }\n        }\n        return paramsBuf.toString();\n    }\n\n    private void getParInvocationCode(char vmParType, int i, ByteArrayOutputStream code) {\n\n        switch (vmParType) {\n            case BOOLEAN: {\n                getIloadCode(i, code);\n                getInvokeStatic(CPExtensionsRepository.miContents_AddParBooleanMethodIdx + baseRootCPoolCount, code);\n                break;\n            }\n            case CHAR: {\n                getIloadCode(i, code);\n                getInvokeStatic(CPExtensionsRepository.miContents_AddParCharMethodIdx + baseRootCPoolCount, code);\n                break;\n            }\n            case BYTE: {\n                getIloadCode(i, code);\n                getInvokeStatic(CPExtensionsRepository.miContents_AddParByteMethodIdx + baseRootCPoolCount, code);\n                break;\n            }\n            case SHORT: {\n                getIloadCode(i, code);\n                getInvokeStatic(CPExtensionsRepository.miContents_AddParShortMethodIdx + baseRootCPoolCount, code);\n                break;\n            }\n            case INT: {\n                getIloadCode(i, code);\n                getInvokeStatic(CPExtensionsRepository.miContents_AddParIntMethodIdx + baseRootCPoolCount, code);\n                break;\n            }\n            case LONG: {\n                getLloadCode(i, code);\n                getInvokeStatic(CPExtensionsRepository.miContents_AddParLongMethodIdx + baseRootCPoolCount, code);\n                break;\n            }\n            case FLOAT: {\n                getFloadCode(i, code);\n                getInvokeStatic(CPExtensionsRepository.miContents_AddParFloatMethodIdx + baseRootCPoolCount, code);\n                break;\n            }\n            case DOUBLE: {\n                getDloadCode(i, code);\n                getInvokeStatic(CPExtensionsRepository.miContents_AddParDoubleMethodIdx + baseRootCPoolCount, code);\n                break;\n            }\n            case REFERENCE: {\n                getAloadCode(i, code);\n                getInvokeStatic(CPExtensionsRepository.miContents_AddParObjectMethodIdx + baseRootCPoolCount, code);\n                break;\n            }\n        }\n    }\n\n    private void getIloadCode(int index, ByteArrayOutputStream code) {\n        switch (index) {\n            case 0:\n                code.write(opc_iload_0);\n                break;\n            case 1:\n                code.write(opc_iload_1);\n                break;\n            case 2:\n                code.write(opc_iload_2);\n                break;\n            case 3:\n                code.write(opc_iload_3);\n                break;\n            default:\n                code.write(opc_iload);\n                code.write(index);\n        }\n    }\n\n    private void getLloadCode(int index, ByteArrayOutputStream code) {\n        switch (index) {\n            case 0:\n                code.write(opc_lload_0);\n                break;\n            case 1:\n                code.write(opc_lload_1);\n                break;\n            case 2:\n                code.write(opc_lload_2);\n                break;\n            case 3:\n                code.write(opc_lload_3);\n                break;\n            default:\n                code.write(opc_lload);\n                code.write(index);\n        }\n    }\n\n    private void getFloadCode(int index, ByteArrayOutputStream code) {\n        switch (index) {\n            case 0:\n                code.write(opc_fload_0);\n                break;\n            case 1:\n                code.write(opc_fload_1);\n                break;\n            case 2:\n                code.write(opc_fload_2);\n                break;\n            case 3:\n                code.write(opc_fload_3);\n                break;\n            default:\n                code.write(opc_fload);\n                code.write(index);\n        }\n    }\n\n    private void getDloadCode(int index, ByteArrayOutputStream code) {\n        switch (index) {\n            case 0:\n                code.write(opc_dload_0);\n                break;\n            case 1:\n                code.write(opc_dload_1);\n                break;\n            case 2:\n                code.write(opc_dload_2);\n                break;\n            case 3:\n                code.write(opc_dload_3);\n                break;\n            default:\n                code.write(opc_dload);\n                code.write(index);\n        }\n    }\n\n    private void getAloadCode(int index, ByteArrayOutputStream code) {\n        switch (index) {\n            case 0:\n                code.write(opc_aload_0);\n                break;\n            case 1:\n                code.write(opc_aload_1);\n                break;\n            case 2:\n                code.write(opc_aload_2);\n                break;\n            case 3:\n                code.write(opc_aload_3);\n                break;\n            default:\n                code.write(opc_aload);\n                code.write(index);\n        }\n    }\n    \n    private void getInvokeStatic(int cpIndex, ByteArrayOutputStream code) {\n        code.write(opc_invokestatic);\n        code.write((cpIndex >> 8) & 0xFF);\n        code.write(cpIndex & 0xFF);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/MiscInstrumentationOps.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.List;\n\n\n/**\n * A number of miscellaneous, relatively high-level, instrumentation operations.\n *\n * @author Misha Dmitriev\n */\npublic class MiscInstrumentationOps extends ClassManager {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private List instrClasses;\n    private int nInstrClasses;\n    private int nInstrMethods;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public MiscInstrumentationOps(ClassRepository repo, ProfilingSessionStatus status) {\n        super(repo, status);\n        instrClasses = new ArrayList();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Object[] getOrigCodeForAllInstrumentedMethods() {\n        nInstrClasses = nInstrMethods = 0;\n\n        for (Enumeration e = classRepo.getClassEnumerationWithAllVersions(); e.hasMoreElements();) {\n            Object ci = e.nextElement();\n\n            if (!(ci instanceof DynamicClassInfo)) {\n                continue; // It's a BaseClassInfo, created just for e.g. array classes, or a PlaceholderClassInfo\n            }\n\n            DynamicClassInfo clazz = (DynamicClassInfo) ci;\n\n            if (!clazz.isLoaded()) {\n                continue;\n            }\n\n            if (!clazz.hasInstrumentedMethods()) {\n                continue;\n            }\n\n            instrClasses.add(clazz);\n\n            int nMethods = clazz.getMethodNames().length;\n            int nLocalInstrMethods = 0;\n\n            for (int i = 0; i < nMethods; i++) {\n                if (clazz.isMethodInstrumented(i) && !clazz.isMethodUnscannable(i)) {\n                    nLocalInstrMethods++;\n                }\n            }\n\n            nInstrClasses++;\n            nInstrMethods += nLocalInstrMethods;\n        }\n\n        return createInstrumentedMethodPack();\n    }\n\n    Object[] getOrigCodeForSingleInstrumentedMethod(RootMethods rootMethods) {\n        String className = rootMethods.classNames[ProfilingSessionStatus.CODE_REGION_CLASS_IDX];\n        String methodName = rootMethods.methodNames[ProfilingSessionStatus.CODE_REGION_CLASS_IDX];\n        String methodSignature = rootMethods.methodSignatures[ProfilingSessionStatus.CODE_REGION_CLASS_IDX];\n\n        List classes = classRepo.getAllClassVersions(className);\n\n        if (classes == null) {\n            return null; // Can happen if actually nothing was instrumented, since class of intrest hasn't been loaded\n        }\n\n        methodName = methodName.intern();\n        methodSignature = methodSignature.intern();\n\n        nInstrClasses = nInstrMethods = 0;\n\n        for (int i = 0; i < classes.size(); i++) {\n            DynamicClassInfo clazz = (DynamicClassInfo) classes.get(i);\n            int methodIdx = clazz.getMethodIndex(methodName, methodSignature);\n\n            if (methodIdx != -1) { // Otherwise this method doesn't exist in this class version\n                instrClasses.add(clazz);\n                nInstrClasses++;\n                nInstrMethods++;\n            }\n        }\n\n        if (nInstrClasses == 0) {\n            MiscUtils.printErrorMessage(\"got zero classes when attempting to deinstrument a single instrumented method\"); // NOI18N\n\n            return null; // Should not happen, but just in case...\n        }\n\n        return createInstrumentedMethodPack();\n    }\n\n    protected Object[] createInstrumentedMethodPack() {\n        if (nInstrMethods == 0) {\n            return null;\n        }\n\n        return createInstrumentedMethodPack15();\n    }\n\n    /** Creates the 1.5-style array of instrumented class files. */\n    private Object[] createInstrumentedMethodPack15() {\n        String[] instrMethodClasses = new String[nInstrClasses];\n        int[] instrClassLoaderIds = new int[nInstrClasses];\n        byte[][] replacementClassFileBytes = new byte[nInstrClasses][];\n\n        for (int j = 0; j < nInstrClasses; j++) {\n            DynamicClassInfo clazz = (DynamicClassInfo) instrClasses.get(j);\n            instrMethodClasses[j] = clazz.getName().replace('/', '.'); // NOI18N\n            instrClassLoaderIds[j] = clazz.getLoaderId();\n\n            // As an optimization, we now send just nulls for class file bytes to the server, who loads original class file bytes in place\n            //try {\n            //  replacementClassFileBytes[j] = clazz.getClassFileBytes();\n            //} catch (IOException ex) {\n            //  // Shouldn't happen, so a message just in case\n            //  MiscUtils.internalError(\"MiscInstrumentationOps: can't get original class file bytes for class \" + clazz.getName() + \"\\nIOException message = \" + ex.getMessage());\n            //}\n        }\n\n        return new Object[] { instrMethodClasses, instrClassLoaderIds, replacementClassFileBytes };\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/ObjLivenessInstrCallsInjector.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport java.io.IOException;\nimport org.graalvm.visualvm.lib.jfluid.classfile.BaseClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.VMUtils;\n\n\n/**\n * Specialized subclass of Injector, that provides injection of our object allocation and liveness instrumentation -\n * ProfilerRuntimeObjAlloc/ProfilerRuntimeObjLiveness.traceObjAlloc(Object obj, char classId) call\n * after each \"new\", \"anewarray\" or \"newarray\" bytecode.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\nclass ObjLivenessInstrCallsInjector extends Injector implements CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // Stuff used for traceObjAlloc(Object, char)\n    protected static byte[] injectedCode;\n    protected static int injectedCodeLen;\n    protected static int injectedCodeMethodIdxPos;\n    protected static int injectedCodeClassIdPos;\n\n    static {\n        initializeInjectedCode();\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected boolean[] allUnprofiledClassStatusArray;\n    private final InstrumentationFilter instrFilter;\n    private final boolean checkForOpcNew;\n    private final boolean checkForOpcNewArray;\n    private final ClassManager classManager;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    ObjLivenessInstrCallsInjector(ClassManager manager, DynamicClassInfo clazz, \n                                  int baseCPoolCount, int methodIdx,\n                                  boolean[] allUnprofiledClassStatusArray,\n                                  InstrumentationFilter instrFilter, boolean checkForOpcNew,\n                                  boolean checkForOpcNewArray) {\n        super(clazz, methodIdx);\n        this.baseCPoolCount = baseCPoolCount;\n        this.allUnprofiledClassStatusArray = allUnprofiledClassStatusArray;\n        this.instrFilter = instrFilter;\n        this.checkForOpcNew = checkForOpcNew;\n        this.checkForOpcNewArray = checkForOpcNewArray;\n        classManager = manager;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public byte[] instrumentMethod() {\n        int bci = 0;\n        int nInjections = 0;\n\n        if (ObjLivenessMethodInstrumentor.isObjectConstructor(clazz, methodIdx)) {\n            injectTraceObjAllocObjCtor(bci);\n            nInjections++;\n        } else {\n            int loaderId = clazz.getLoaderId();\n            int bc;\n\n            // Instrument all opc_new, opc_anewarray and opc_newarray instructions, for which allUnprofiledClassStatusArray[classId] != true\n            int opcNewCount = 0;\n\n            // Instrument all opc_new, opc_anewarray and opc_newarray instructions, for which allUnprofiledClassStatusArray[classId] != true\n            int opcNewToInstr = 0;\n\n            do {\n                opcNewToInstr = opcNewCount + 1;\n                bci = 0;\n\n                while (bci < bytecodesLength && bytecodesLength + injectedCodeLen < 65535) {\n                    bc = (bytecodes[bci] & 0xFF);\n\n                    if ((bc == opc_new && checkForOpcNew) || (checkForOpcNewArray && (bc == opc_anewarray || bc == opc_newarray || bc == opc_multianewarray))) {\n                        opcNewToInstr--;\n\n                        if (opcNewToInstr == 0) {\n                            opcNewCount++;\n\n                            BaseClassInfo refClazz;\n\n                            if ((bc == opc_new) || (bc == opc_anewarray) || (bc == opc_multianewarray)) {\n                                int classCPIdx = getU2(bci + 1);\n                                String refClassName = clazz.getRefClassName(classCPIdx);\n\n                                if (bc == opc_new) {\n                                    if (!instrFilter.passes(refClassName)) {\n                                        break;\n                                    }\n                                    refClazz = classManager.javaClassOrPlaceholderForName(refClassName, loaderId);\n                                } else if (bc == opc_anewarray) {\n                                    if (!instrFilter.passes(refClassName.concat(\"[]\"))) {    // NOI18N\n                                        break;\n                                    }\n                                    refClazz = classManager.javaClassForObjectArrayType(refClassName);\n                                } else {\n                                    if (!instrFilter.passes(getMultiArrayClassName(refClassName))) {\n                                        break;\n                                    }\n                                    refClazz = classManager.lookupSpecialClass(refClassName);\n                                }\n\n                                if (refClazz == null) {\n                                    break; // Warning already issued\n                                }\n\n                                int classId = refClazz.getInstrClassId();\n\n                                if ((allUnprofiledClassStatusArray != null) && (allUnprofiledClassStatusArray.length > classId)\n                                        && allUnprofiledClassStatusArray[classId]) {\n                                    break;\n                                }\n\n                                if ((bc == opc_anewarray) || (bc == opc_multianewarray)) { // Simply inject the call after the bytecode instruction\n                                    injectTraceObjAlloc(classId, bci + opcodeLength(bci));\n                                    nInjections++;\n                                } else { // opc_new - we can only inject the call after the corresponding constructor call\n                                    bci += opcodeLength(bci);\n                                    bc = (bytecodes[bci] & 0xFF);\n\n                                    if ((bc != opc_dup) && (bc != opc_dup_x1) && (bc != opc_dup_x2)) {\n                                        // see issue http://www.netbeans.org/issues/show_bug.cgi?id=59085\n                                        // the JBoss JSP compiler generates bytecode that uses opc_dup_x1 in some cases,\n                                        // something javac would not generate\n                                        // in this case, injecting extra dup would corrupt the stack, so we cannot perform it\n                                        // same is expected for opc_dup_x2\n\n                                        // No standard 'dup' after 'new'. Can happen if there is a line like 'new Foo()', with no assignment of reference to the new object.\n                                        // This seems to be a rare case - javac apparently always adds 'dup' to 'new' (it would add 'pop' after it if the object is not used).\n                                        // We assume that if there is no 'dup' directly after 'new', there is also no 'dup' for this same object later.\n\n                                        //System.err.println(\"*** Gonna inject dup at bci = \" + bci + \" in method = \" + clazz.getName() + \".\" + clazz.getMethodName(methodIdx) + \" , idx = \" + methodIdx);\n                                        injectDup(bci);\n\n                                        //System.out.println(\"*** For \" + clazz.getName() + \".\" + clazz.getMethodName(methodIdx) + \" gonna locateConstructor from bci = \" + bci);\n                                        bci = locateConstructorCallForNewOp(bci, bytecodesLength, refClassName);\n\n                                        // [fixme]\n                                        //\n                                        // unfortunately deinjecting the dump here is not straightforward if bci = -1\n                                        // as an indication of failure to figure out the correct constructor call\n                                        // So far this is not happening, the issue that happens with Hibernate goes through the other branch\n                                        // without injecting dup\n                                        // see http://www.netbeans.org/issues/show_bug.cgi?id=67346\n                                        injectTraceObjAllocNoDup(classId, bci);\n                                        nInjections++;\n                                    } else {\n                                        bci = locateConstructorCallForNewOp(bci, bytecodesLength, refClassName);\n\n                                        if (bci != -1) {\n                                            injectTraceObjAlloc(classId, bci);\n                                            nInjections++;\n                                        }\n                                    }\n                                }\n                            } else { // opc_newarray - primitive array allocation\n\n                                int arrayClassId = getByte(bci + 1);\n                                refClazz = classManager.javaClassForPrimitiveArrayType(arrayClassId);\n\n                                int classId = refClazz.getInstrClassId();\n                                String className = StringUtils.userFormClassName(refClazz.getName());\n\n                                if (!instrFilter.passes(className)) {\n                                    break;\n                                }\n                                if ((allUnprofiledClassStatusArray == null) || !allUnprofiledClassStatusArray[classId]) {\n                                    injectTraceObjAlloc(classId, bci + 2);\n                                    nInjections++;\n                                }\n                            }\n\n                            break;\n                        }\n                    }\n\n                    bci += opcodeLength(bci);\n                }\n            } while (opcNewToInstr == 0);\n            if (bci < bytecodesLength) {\n                // method was not fully instrumented -> issue warnining\n                String methodFQN = clazz.getName()+\".\"+clazz.getMethodName(methodIdx)+clazz.getMethodSignature(methodIdx);  // NOI18N\n                MiscUtils.printWarningMessage(\"Method \"+methodFQN+\" is too big to be fully instrumented.\");  // NOI18N\n            }\n        }\n        if (nInjections == 0) {\n            ((DynamicClassInfo) clazz).unsetMethodInstrumented(methodIdx);\n        } else {\n            // Done very conservatively.\n            maxStack += 2;\n        }\n\n        return createPackedMethodInfo();\n    }\n\n    private static String getMultiArrayClassName(String refClassName) {\n        int dimension = refClassName.lastIndexOf('[');\n        String baseClass = refClassName.substring(dimension+1);\n\n        if (VMUtils.isVMPrimitiveType(baseClass)) {\n            return StringUtils.userFormClassName(refClassName);\n        } else {\n            StringBuilder arrayClass = new StringBuilder(refClassName.length()+dimension+1);\n            arrayClass.append(refClassName.substring(dimension+1));\n            \n            for (int i = 0; i <= dimension; i++) {\n                arrayClass.append(\"[]\");        // NOI18N\n            }\n            return arrayClass.toString();\n        }\n    }\n\n    private static void initializeInjectedCode() {\n        // Code packet for traceObjAlloc(Object obj, char classId)\n        injectedCodeLen = 8;\n        injectedCode = new byte[injectedCodeLen];\n        injectedCode[0] = (byte) opc_dup; // push newly created object to top of stack to pass as the first argument to traceObjAlloc method\n        injectedCode[1] = (byte) opc_sipush; // push char - the actual value will be next two bytes, a second parameter passed to traceObjAlloc method\n                                             // Positions 2, 3 are occupied by classId\n\n        injectedCodeClassIdPos = 2;\n        injectedCode[4] = (byte) opc_invokestatic;\n        // Positions 5, 6 are occupied by method index\n        injectedCodeMethodIdxPos = 5;\n        injectedCode[7] = (byte) opc_nop;\n    }\n\n    private void injectDup(int bci) {\n        byte[] injCode = new byte[] { (byte) opc_dup, (byte) opc_nop, (byte) opc_nop, (byte) opc_nop };\n        injectCodeAndRewrite(injCode, 4, bci, false);\n    }\n\n    private void injectTraceObjAlloc(int classId, int bci) {\n        // Prepare the traceObjAlloc(Object obj, char classId) code packet that is to be injected\n        int targetMethodIdx = CPExtensionsRepository.memoryProfContents_TraceObjAllocMethodIdx + baseCPoolCount;\n        putU2(injectedCode, injectedCodeMethodIdxPos, targetMethodIdx);\n        putU2(injectedCode, injectedCodeClassIdPos, classId);\n\n        injectCodeAndRewrite(injectedCode, injectedCodeLen, bci, false);\n    }\n\n    private void injectTraceObjAllocNoDup(int classId, int bci) {\n        injectedCode[0] = (byte) opc_nop; // Remove the dup\n                                          // Prepare the traceObjAlloc(Object obj, char classId) code packet that is to be injected\n\n        int targetMethodIdx = CPExtensionsRepository.memoryProfContents_TraceObjAllocMethodIdx + baseCPoolCount;\n        putU2(injectedCode, injectedCodeMethodIdxPos, targetMethodIdx);\n        putU2(injectedCode, injectedCodeClassIdPos, classId);\n\n        injectCodeAndRewrite(injectedCode, injectedCodeLen, bci, false);\n        injectedCode[0] = (byte) opc_dup; // Restore dup\n    }\n\n    private void injectTraceObjAllocObjCtor(int bci) {\n        injectedCode[0] = (byte) opc_aload_0; // Insert aload_0\n        // Prepare the traceObjAlloc(Object obj, 0) code packet that is to be injected\n\n        int targetMethodIdx = CPExtensionsRepository.memoryProfContents_TraceObjAllocMethodIdx + baseCPoolCount;\n        putU2(injectedCode, injectedCodeMethodIdxPos, targetMethodIdx);\n        putU2(injectedCode, injectedCodeClassIdPos, 0);\n\n        injectCodeAndRewrite(injectedCode, injectedCodeLen, bci, true);\n        injectedCode[0] = (byte) opc_dup; // Restore dup\n    }\n\n    private int locateConstructorCallForNewOp(int startBCI, int bytecodesLength, String newOpClassName) {\n        int bc;\n        int bci = startBCI;\n        int nestedNewOps = 0;\n        \n        while (bci < bytecodesLength) {\n            bc = bytecodes[bci] & 0xFF;\n            if (bc == opc_new) {\n                nestedNewOps++;\n            } else if (bc == opc_invokespecial) {\n                int index = getU2(bci + 1);\n                String[] cms = clazz.getRefMethodsClassNameAndSig(index);\n\n                if (cms == null) {\n                    System.err.println(\"Failed to locate constant pool ref in: \" + clazz.getName()); // NOI18N\n                    System.err.println(\"new Op class: \" + newOpClassName); // NOI18N\n                    System.err.println(\"bci: \" + bci + \", startBCI: \" + startBCI); // NOI18N\n                    System.err.println(\"constant pool ref index: \" + index); // NOI18N\n                    dumpClassFile();\n                    //debug = true;\n                    return -1;\n                }\n\n                String refClassName = cms[0];\n                String refMethodName = cms[1];\n\n                if (refMethodName == \"<init>\") { // NOI18N  // It's really a constructor call, not e.g. a call to a private method of 'this'\n                    if (nestedNewOps == 0) {\n                        bci += opcodeLength(bci);\n                        return bci;\n                    } else {\n                        nestedNewOps--;\n                    }\n                }\n            }\n            bci += opcodeLength(bci);\n        }\n\n        System.err.println(\"Profiler Warning: Failed to instrument creation of class \" + newOpClassName // NOI18N\n                           + \" in method \" + clazz.getName() + \".\" + clazz.getMethodName(methodIdx)); // NOI18N\n        dumpClassFile();\n        return -1; // not instrumentable, there is no call to constructor\n    }\n\n    private void dumpClassFile() {\n        try {\n            ClassRewriter.saveToDisk(clazz.getName(), ((DynamicClassInfo) clazz).getClassFileBytes());\n        } catch (IOException e) {\n            System.err.println(\"Caught exception while dumping class: \" + clazz.getName() + \", \" + e.getMessage()); // NOI18N\n            e.printStackTrace(System.err);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/ObjLivenessMethodInstrumentor.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport java.util.Enumeration;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.classfile.BaseClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\n\n\n/**\n * High-level access to functionality that instruments TA methods to generate object allocation and liveness data.\n * Also has support for removing instrumentation for a subset of classes that the user deemed\n * \"not interesting\".\n *\n * @author Misha Dmitriev\n */\npublic class ObjLivenessMethodInstrumentor extends MemoryProfMethodInstrumentor {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    class MethodScanerForBannedInstantiations extends SingleMethodScaner {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        protected boolean[] unprofiledClassStatusArray;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        void setUnprofiledClassStatusArray(boolean[] v) {\n            unprofiledClassStatusArray = v;\n        }\n\n        boolean hasNewOpcodes(boolean checkForOpcNew, boolean checkForOpcNewArray) {\n            if (!checkForOpcNew && !checkForOpcNewArray) return false;\n            int loaderId = clazz.getLoaderId();\n            int bc;\n            int bci = 0;\n\n            while (bci < bytecodesLength) {\n                bc = (bytecodes[bci] & 0xFF);\n\n                if ((bc == opc_new && checkForOpcNew) || \n                   ((bc == opc_anewarray || (bc == opc_multianewarray) && checkForOpcNewArray))) {\n                    int classCPIdx = getU2(bci + 1);\n                    String refClassName = clazz.getRefClassName(classCPIdx);\n                    BaseClassInfo refClazz;\n\n                    if (bc == opc_new) {\n                        refClazz = javaClassOrPlaceholderForName(refClassName, loaderId);\n                    } else if (bc == opc_anewarray) {\n                        refClazz = javaClassForObjectArrayType(refClassName);\n                    } else {\n                        refClazz = lookupSpecialClass(refClassName);\n                    }\n\n                    int classId = refClazz.getInstrClassId();\n\n                    if (classId != -1) {\n                        if ((unprofiledClassStatusArray.length > classId) && unprofiledClassStatusArray[classId]) {\n                            return true;\n                        }\n                    }\n                } else if (bc == opc_newarray && checkForOpcNewArray) {\n                    int arrayClassId = getByte(bci + 1);\n                    BaseClassInfo refClazz = javaClassForPrimitiveArrayType(arrayClassId);\n                    int classId = refClazz.getInstrClassId();\n\n                    if (classId != -1) {\n                        if (unprofiledClassStatusArray[classId]) {\n                            return true;\n                        }\n                    }\n                }\n\n                bci += opcodeLength(bci);\n            }\n\n            return false;\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // Values that operationCode can have\n    protected static final int STANDARD_INSTRUMENTATION = 1;\n    protected static final int SELECTIVE_INSTR_REMOVAL = 2;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected boolean[] allUnprofiledClassStatusArray;\n    protected int operationCode; // Depending on this value, use different methods to mark/determine if a method needs rewriting\n    private final ProfilerEngineSettings engineSettings;\n    private final InstrumentationFilter instrFilter;\n    private final boolean instrObjectInit;\n    private final boolean instrArr;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ObjLivenessMethodInstrumentor(ClassRepository repo, ProfilingSessionStatus status, ProfilerEngineSettings engineSettings, boolean isLiveness) {\n        super(repo, status, isLiveness ? INJ_OBJECT_LIVENESS : INJ_OBJECT_ALLOCATIONS);\n        this.engineSettings = engineSettings;\n        instrFilter = engineSettings.getInstrumentationFilter();\n        operationCode = STANDARD_INSTRUMENTATION;\n        instrObjectInit = engineSettings.isInstrumentObjectInit();\n        instrArr = engineSettings.isInstrumentArrayAllocation();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * This is called when object allocation profiling is already active, with the argument where each line\n     * corresponds to a class id, and value true at this line means that the class should not be profiled anymore\n     * (i.e. allocation info for its instances shouldn't be generated). Returns the methods from which the\n     * instrumentation for unprofiled classes is removed (but for others it's still in place).\n     */\n    public Object[] getMethodsToInstrumentUponClassUnprofiling(boolean[] unprofiledClassStatusArray) {\n        MethodScanerForBannedInstantiations msbi;\n        \n        operationCode = SELECTIVE_INSTR_REMOVAL;\n        initInstrumentationPackData();\n        msbi = new MethodScanerForBannedInstantiations();\n        msbi.setUnprofiledClassStatusArray(unprofiledClassStatusArray);\n        setAllUnprofiledClassStatusArray(unprofiledClassStatusArray);\n\n        for (Enumeration e = getClassEnumerationWithAllVersions(); e.hasMoreElements();) {\n            Object ci = e.nextElement();\n\n            if (!(ci instanceof DynamicClassInfo)) {\n                continue; // It's a BaseClassInfo, created just for e.g. array classes, or a PlaceholderClassInfo\n            }\n\n            DynamicClassInfo clazz = (DynamicClassInfo) ci;\n\n            if (!clazz.isLoaded()) {\n                continue;\n            }\n\n            if (!clazz.hasInstrumentedMethods()) {\n                continue;\n            }\n\n            String[] methodNames = clazz.getMethodNames();\n            boolean found = false;\n\n            for (int i = 0; i < methodNames.length; i++) {\n                if (!clazz.isMethodInstrumented(i)) {\n                    continue;\n                }\n\n                msbi.setClassAndMethod(clazz, i);\n\n                if (msbi.hasNewOpcodes(!instrObjectInit, instrArr)) {\n                    found = true;\n                    clazz.setMethodSpecial(i);\n                    nInstrMethods++;\n                }\n            }\n\n            if (found) {\n                nInstrClasses++;\n                instrClasses.add(clazz);\n            }\n        }\n\n        Object[] res = createInstrumentedMethodPack();\n        operationCode = STANDARD_INSTRUMENTATION;\n\n        return res;\n    }\n\n    /**\n     * Every time the user tells the tool to remove profiling for some class(es), the info about only\n     * those classes currently selected for unprofiling, rather than about all classes ever unprofiled,\n     * is recorded and then passed here via currentUnprofiledClassStatusArray[]. This is done to simplify\n     * scanning instrumented methods for 'new' instructions to unprofile, so that instructions that\n     * have already been unprofiled before don't cause false positives. However, when rewriting methods\n     * that may already contain some unprofiled instantiations (to unprofile more instantiations), or\n     * rewriting fresh uninstrumented methods, we need to use cumulative info about all unprofilings.\n     * That info is collected here, in allUnprofiledClassStatusArray.\n     */\n    protected void setAllUnprofiledClassStatusArray(boolean[] currentUnprofiledClassStatusArray) {\n        int len = currentUnprofiledClassStatusArray.length;\n\n        if ((allUnprofiledClassStatusArray == null) || (allUnprofiledClassStatusArray.length < len)) {\n            boolean[] old = allUnprofiledClassStatusArray;\n            allUnprofiledClassStatusArray = new boolean[len];\n\n            if (old != null) {\n                System.arraycopy(old, 0, allUnprofiledClassStatusArray, 0, old.length);\n            }\n        }\n\n        for (int i = 0; i < len; i++) {\n            if (currentUnprofiledClassStatusArray[i]) {\n                allUnprofiledClassStatusArray[i] = true;\n            }\n        }\n    }\n\n    protected byte[] instrumentMethod(DynamicClassInfo clazz, int methodIdx) {\n        return InstrumentationFactory.instrumentForMemoryProfiling(this, clazz, methodIdx, allUnprofiledClassStatusArray, injType,\n                                             getRuntimeProfilingPoints(engineSettings.getRuntimeProfilingPoints(),clazz, methodIdx),\n                                             instrFilter, !instrObjectInit, instrArr);\n    }\n\n    protected boolean classNeedsInstrumentation(ClassInfo clazz) {\n        if (clazz == null) {\n            return false;\n        }\n        if (!instrObjectInit || instrArr) {\n            return true;\n        }\n        if (instrObjectInit && OBJECT_SLASHED_CLASS_NAME.equals(clazz.getName()) && clazz.getLoaderId() <= 0) {\n            return true;\n        }\n        return false;\n    }\n\n    protected boolean methodNeedsInstrumentation(ClassInfo clazz, int methodIdx) {\n        // TODO: hasNewOpcodes must be called in any case, because it has side effects!\n        boolean ni = hasNewOpcodes(clazz, methodIdx, !instrObjectInit, instrArr, instrFilter);\n        boolean pp = getRuntimeProfilingPoints(engineSettings.getRuntimeProfilingPoints(), clazz, methodIdx).length > 0;\n        boolean oi = instrObjectInit && isObjectConstructor(clazz, methodIdx);\n        return ni || pp || oi;\n    }\n\n    @Override\n    protected boolean methodNeedsRewriting(DynamicClassInfo clazz, int methodIdx) {\n        if (operationCode == STANDARD_INSTRUMENTATION) {\n            return clazz.isMethodInstrumented(methodIdx);\n        } else { // SELECTIVE_INSTR_REMOVAL\n\n            boolean res = clazz.isMethodSpecial(methodIdx);\n            clazz.unsetMethodSpecial(methodIdx);\n\n            return res;\n        }\n    }\n    \n    static boolean isObjectConstructor(ClassInfo clazz, int methodIdx) {\n        if (OBJECT_SLASHED_CLASS_NAME.equals(clazz.getName())\n                && clazz.getLoaderId() <= 0\n                && \"<init>\".equals(clazz.getMethodName(methodIdx))) {   // NOI18N\n            return true;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/ProfilePointHitCallInjector.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.client.RuntimeProfilingPoint;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n\n/**\n * Specialized subclass of Injector, that provides injection of ProfilePoint hit method\n *\n *  @author Tomas Hurka\n */\nclass ProfilePointHitCallInjector extends Injector implements CommonConstants {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    RuntimeProfilingPoint[] profilePoints;\n    int ppHitCPMethodIdx;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    ProfilePointHitCallInjector(DynamicClassInfo clazz, int baseCPoolCount, int methodIdx, RuntimeProfilingPoint[] pps, int cPMethodIdx) {\n        super(clazz, methodIdx);\n        profilePoints = pps;\n        ppHitCPMethodIdx = cPMethodIdx;\n        this.baseCPoolCount = baseCPoolCount;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public byte[] instrumentMethod() {\n        insertProfilingPoints(profilePoints, ppHitCPMethodIdx);\n\n        // Done very conservatively.\n        maxStack += 1;\n\n        return createPackedMethodInfo();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/RecursiveMethodInstrumentor.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.classfile.BaseClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.PlaceholderClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.client.RuntimeProfilingPoint;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.RootClassLoadedCommand;\n\n/**\n * Base class for two \"recursive\" method scanners, implementing the \"eager\" and \"lazy\" transitive call subgraph revelation and\n * instrumentation schemes. This class contains functionality used by both scanners.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Adrian Mos\n */\npublic abstract class RecursiveMethodInstrumentor extends ClassManager {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    protected static class ReachableMethodPlaceholder extends PlaceholderClassInfo {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        protected ArrayList methodNamesAndSigs;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ReachableMethodPlaceholder(String className, int classLoaderId) {\n            super(className, classLoaderId);\n            methodNamesAndSigs = new ArrayList();\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void registerReachableMethod(String methodName, String methodSig) {\n            int nameIdx = methodNamesAndSigs.indexOf(methodName);\n\n            if (nameIdx != -1) {\n                if (methodNamesAndSigs.get(nameIdx + 1).equals(methodSig)) {\n                    return;\n                }\n            }\n\n            methodNamesAndSigs.add(methodName);\n            methodNamesAndSigs.add(methodSig);\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected Map instrClasses = new HashMap();\n    protected InstrumentationFilter instrFilter;\n    protected byte[] codeBytes;\n    protected boolean dontInstrumentEmptyMethods;\n    protected boolean dontScanGetterSetterMethods;\n    protected boolean instrumentSpawnedThreads;\n\n    // This flag shows whether we have already instrumented the java.lang.reflect.Method.invoke() method to intercept all invocations.\n    // The current policy is to instrument it eagerly, in the very first method instrumentation packet. However, the actual\n    // interception can be turned on and off at run time on demand.\n    protected boolean reflectInvokeInstrumented = false;\n    protected int markerInjectionType; // Bytecode injections that are set dependent on the above\n    protected int nInstrClasses;\n    protected int nInstrMethods;\n    protected int normalInjectionType; // Bytecode injections that are set dependent on the above\n    protected int offset;\n    protected int rootInjectionType; // Bytecode injections that are set dependent on the above\n    RootMethods rootMethods;\n\n    // remembered here because of profiling points\n    private ProfilerEngineSettings engineSettings;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    RecursiveMethodInstrumentor(ClassRepository repo, ProfilingSessionStatus status, ProfilerEngineSettings settings) {\n        super(repo, status);\n\n        switch (status.currentInstrType) {\n            case INSTR_RECURSIVE_FULL:\n                normalInjectionType = INJ_RECURSIVE_NORMAL_METHOD;\n                rootInjectionType = INJ_RECURSIVE_ROOT_METHOD;\n                markerInjectionType = INJ_RECURSIVE_MARKER_METHOD;\n\n                break;\n            case INSTR_RECURSIVE_SAMPLED:\n                normalInjectionType = INJ_RECURSIVE_SAMPLED_NORMAL_METHOD;\n                rootInjectionType = INJ_RECURSIVE_SAMPLED_ROOT_METHOD;\n                markerInjectionType = INJ_RECURSIVE_SAMPLED_MARKER_METHOD;\n\n                break;\n        }\n\n        reflectInvokeInstrumented = false;\n\n        dontScanGetterSetterMethods = !settings.getInstrumentGetterSetterMethods();\n        dontInstrumentEmptyMethods = !settings.getInstrumentEmptyMethods();\n        instrumentSpawnedThreads = settings.getInstrumentSpawnedThreads();\n        instrFilter = settings.getInstrumentationFilter();\n        engineSettings = settings;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * This method is called when some class containing an instrumentation root method is loaded by the VM (either has just\n     * been loaded, or the JFluid server, upon the user's command to initiate instrumentation, has detected that it has been\n     * loaded some time in the past). The JFluid server then sends a RootClassLoadedCommand to the tool. This command contains\n     * the information on all classes currently loaded by the VM - see the details in this method's header.\n     * This method should initialize instrumentation-related data structures, register given classes as loaded, and return\n     * the initial set of methods to instrument in the format given by createInstrumentedMethodPack().\n     */\n    abstract Object[] getInitialMethodsToInstrument(RootClassLoadedCommand rootLoaded, RootMethods rootMethods);\n\n    public abstract Object[] getMethodsToInstrumentUponClassLoad(String className, int classLoaderId, boolean threadInCallGraph);\n\n    /** Methods below return method bytecodes to instrument upon specific events reported by the JFluid server. */\n    public abstract Object[] getMethodsToInstrumentUponMethodInvocation(String className, int classLoaderId, String methodName,\n                                                                        String methodSignature);\n\n    public abstract Object[] getMethodsToInstrumentUponReflectInvoke(String className, int classLoaderId, String methodName,\n                                                                     String methodSignature);\n\n    /** Called every time before a new round of instrumentation, caused by class load, method invoke, etc. */\n    protected void initInstrMethodData() {\n        instrClasses.clear();\n        nInstrClasses = nInstrMethods = 0;\n    }\n\n    protected static boolean rootClassNameIsReal(String rootClassName) {\n        return !rootClassName.equals(NO_CLASS_NAME);\n    }\n\n    protected void addToSubclassList(DynamicClassInfo clazz, DynamicClassInfo addedClassInfo) {\n        DynamicClassInfo superClass = getSuperClass(clazz);\n        clazz.setSuperClass(superClass);\n\n        if ((superClass != null) && !clazz.isInterface()) {\n\n            if (addedClassInfo != null) {\n                superClass.addSubclass(addedClassInfo);\n                findAndMarkOverridingMethodsReachable(superClass, addedClassInfo);\n            }\n\n            if (superClass.getName() != OBJECT_SLASHED_CLASS_NAME) {\n                addToSubclassList(superClass, addedClassInfo);\n            }\n        }\n\n        DynamicClassInfo[] interfaces = getInterfaces(clazz);\n\n        if (interfaces != null) {\n            for (int i = 0; i < interfaces.length; i++) {\n                DynamicClassInfo superInterface = interfaces[i];\n                clazz.setSuperInterface(superInterface, i);\n\n                if (superInterface != null) {\n                    if (addedClassInfo != null) {\n                        superInterface.addSubclass(addedClassInfo);\n                        findAndMarkOverridingMethodsReachable(superInterface, addedClassInfo);\n                    }\n\n                    addToSubclassList(superInterface, addedClassInfo);\n                }\n            }\n        }\n    }\n\n    protected abstract void findAndMarkOverridingMethodsReachable(DynamicClassInfo superClass, DynamicClassInfo subClass);\n\n    protected abstract void processInvoke(DynamicClassInfo clazz, boolean virtualCall, int index);\n\n    protected final int at(int index) {\n        return codeBytes[offset + index] & 0xFF;\n    }\n\n    /**\n     * Given the table at the specified index, return the specified entry\n     */\n    protected final long intAt(int tbl, int entry) {\n        int base = tbl + (entry << 2);\n\n        return (codeBytes[base] << 24) | ((codeBytes[base + 1] & 0xFF) << 16) | ((codeBytes[base + 2] & 0xFF) << 8)\n               | (codeBytes[base + 3] & 0xFF);\n    }\n\n    protected void scanMethod(DynamicClassInfo clazz, int index) {\n        byte[] bytecode = clazz.getMethodBytecode(index);\n        scanBytecode(clazz, bytecode);\n    }\n\n    protected final int shortAt(int index) {\n        int base = offset + index;\n\n        return ((codeBytes[base] & 0xFF) << 8) | (codeBytes[base + 1] & 0xFF);\n    }\n\n    /**\n     * This method is used either to normally process the bytecodes of a method, in which case clazz != null and the return\n     * result is ignored. If clazz == null, then returns false upon encountering the first invoke bytecode, and true if there\n     * are no invokes, i.e. it's a leaf method.\n     */\n    protected boolean scanBytecode(DynamicClassInfo clazz, byte[] code) {\n        codeBytes = code;\n\n        for (offset = 0; offset < codeBytes.length;) {\n            int opcode = at(0);\n\n            if (opcode == opc_wide) {\n                opcode = at(1);\n\n                if (((opcode >= opc_iload) && (opcode <= opc_aload)) || ((opcode >= opc_istore) && (opcode <= opc_astore))\n                        || (opcode == opc_ret)) {\n                    offset += 4;\n                } else if (opcode == opc_iinc) {\n                    offset += 6;\n                } else {\n                    offset++;\n                }\n            } else {\n                switch (opcode) {\n                    case opc_tableswitch: {\n                        int tbl = (offset + 1 + 3) & (~3); // four byte boundry\n                        long default_skip = intAt(tbl, 0);\n                        long low = intAt(tbl, 1);\n                        long high = intAt(tbl, 2);\n                        tbl += (3 << 2); // three int header\n                        offset = tbl + (int) ((high - low + 1) << 2);\n\n                        break;\n                    }\n                    case opc_lookupswitch: {\n                        int tbl = (offset + 1 + 3) & (~3); // four byte boundry\n                        long default_skip = intAt(tbl, 0);\n                        int npairs = (int) intAt(tbl, 1);\n                        int nints = npairs * 2;\n                        tbl += (2 << 2); // two int header\n                        offset = tbl + (nints << 2);\n\n                        break;\n                    }\n                    case opc_invokevirtual:\n                    case opc_invokespecial:\n                    case opc_invokestatic: {\n                        if (clazz == null) {\n                            return false; // Using scanBytecode() as a leaf-method checker\n                        }\n\n                        int index = shortAt(1);\n                        processInvoke(clazz, (opcode == opc_invokevirtual), index);\n                        offset += 3;\n\n                        break;\n                    }\n                    case opc_invokeinterface: {\n                        if (clazz == null) {\n                            return false; // Using scanBytecode() as a leaf-method checker\n                        }\n\n                        int index = shortAt(1);\n                        processInvoke(clazz, true, index);\n                        offset += 5;\n\n                        break;\n                    }\n                    default:\n                        offset += opc_length[opcode];\n\n                        break;\n                }\n            }\n        }\n\n        return true;\n    }\n\n    protected abstract boolean tryInstrumentSpawnedThreads(DynamicClassInfo clazz);\n\n    protected static boolean isEmptyMethod(byte[] code) {\n        return (code.length == 1); // Can't be anything but \"return\"\n    }\n\n    protected static boolean isGetterSetterMethod(byte[] code) {\n        // Getter (accessor) method:\n        // 0 aload_0; 1 getfield x ; 4 (i..a)return.  Parameter size = 1\n        // Setter method:\n        // 0 aload_0; 1 (i..a)load_1; 2 putfield x; 5 return. Parameter size = 2\n        if (code.length == 5) {\n            if (((code[0] & 0xFF) == opc_aload_0) && ((code[1] & 0xFF) == opc_getfield)\n                    && (((code[4] & 0xFF) >= opc_ireturn) && ((code[4] & 0xFF) <= opc_areturn))) {\n                return true;\n            }\n        } else if (code.length == 6) {\n            if (((code[0] & 0xFF) == opc_aload_0) && (((code[1] & 0xFF) >= opc_iload_1) && ((code[1] & 0xFF) <= opc_aload_1))\n                    && ((code[2] & 0xFF) == opc_putfield) && ((code[5] & 0xFF) == opc_return)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    protected boolean isLeafMethod(byte[] code) {\n        return scanBytecode(null, code);\n    }\n\n    /** Create a multi-class packet of instrumented methods or classes */\n    protected Object[] createInstrumentedMethodPack() {\n        if (nInstrClasses == 0) {\n            return null;\n        }\n\n        return createInstrumentedMethodPack15();\n    }\n\n    protected void markAllMethodsMarker(DynamicClassInfo clazz) {\n        clazz.setAllMethodsMarkers();\n    }\n\n    protected void markAllMethodsRoot(DynamicClassInfo clazz) {\n        clazz.setAllMethodsRoots();\n    }\n\n    protected void markClassAndMethodForInstrumentation(DynamicClassInfo clazz, int methodIdx) {\n        if ((status.getStartingMethodId() + nInstrMethods) < 65535) {\n            addInsrClass(clazz);\n\n            nInstrMethods++;\n        } else { // Can't instrument more than 64K methods - mark this method as already instrumented\n            clazz.setMethodInstrumented(methodIdx);\n        }\n    }\n\n    protected void markProfilingPointForInstrumentation(String classNameDot, String className, int classLoaderId) {\n        RuntimeProfilingPoint[] pp = engineSettings.getRuntimeProfilingPoints();\n        for (RuntimeProfilingPoint point : pp) {\n            if (classNameDot.equals(point.getClassName())) {\n                DynamicClassInfo clazz = javaClassForName(className, classLoaderId);\n                \n                if (clazz != null) {\n                    markProfilingPonitForInstrumentation(clazz);\n                }\n                return;\n            }\n        }\n    }\n\n    protected void markProfilingPonitForInstrumentation(DynamicClassInfo clazz) {\n        RuntimeProfilingPoint[] pp = engineSettings.getRuntimeProfilingPoints();\n        RuntimeProfilingPoint[] ppclass = getRuntimeProfilingPoints(pp,clazz);\n        \n        if (ppclass.length > 0) {\n            addInsrClass(clazz);\n        }\n    }\n\n    protected boolean markMethod(DynamicClassInfo clazz, int rootMethod) {\n        String rootMethodName = rootMethods.methodNames[rootMethod];\n        String rootMethodSignature = rootMethods.methodSignatures[rootMethod];\n        boolean isMarkerMethod = rootMethods.markerMethods[rootMethod];\n        int rootMethodIdx = clazz.getMethodIndex(rootMethodName, rootMethodSignature);\n\n        if (rootMethodIdx == -1) {\n            return false;\n        }\n\n        if (isMarkerMethod) {\n            clazz.setMethodMarker(rootMethodIdx);\n        } else {\n            clazz.setMethodRoot(rootMethodIdx);\n        }\n\n        return true;\n    }\n\n    protected boolean markMethodMarker(DynamicClassInfo clazz, String rootMethodName, String rootMethodSignature) {\n        int rootMethodIdx = clazz.getMethodIndex(rootMethodName, rootMethodSignature);\n\n        if (rootMethodIdx == -1) {\n            return false;\n        }\n\n        clazz.setMethodMarker(rootMethodIdx);\n\n        return true;\n    }\n\n    protected boolean markMethodRoot(DynamicClassInfo clazz, String rootMethodName, String rootMethodSignature) {\n        int rootMethodIdx = clazz.getMethodIndex(rootMethodName, rootMethodSignature);\n\n        if (rootMethodIdx == -1) {\n            return false;\n        }\n\n        clazz.setMethodRoot(rootMethodIdx);\n\n        return true;\n    }\n    \n    //---------------------------- Private implementation of instrumentation data packing ---------------------------\n\n    /** Create a multi-class packet of instrumented 1.5-style data */\n    private Object[] createInstrumentedMethodPack15() {\n        DynamicClassInfo reflectMethodClass = null;\n        int reflectMethodClassIdx = -1;\n\n        if (!reflectInvokeInstrumented) {\n            // Check if java.lang.reflect.Method is already among classes to instrument\n            int idx = 0;\n\n            for (Iterator e = instrClasses.values().iterator(); e.hasNext(); idx++) {\n                DynamicClassInfo clazz = (DynamicClassInfo) e.next();\n\n                if (clazz.getName() == JAVA_LANG_REFLECT_METHOD_SLASHED_CLASS_NAME) {\n                    reflectMethodClassIdx = idx;\n                    reflectMethodClass = clazz;\n                    break;\n                }\n            }\n            if (reflectMethodClassIdx == -1) {\n                reflectMethodClass = javaClassForName(JAVA_LANG_REFLECT_METHOD_SLASHED_CLASS_NAME, 0);\n                if (reflectMethodClass != null) {\n                    nInstrClasses++;\n                }\n            }\n            if (reflectMethodClass == null) {\n                reflectInvokeInstrumented = true;\n            }\n        }\n\n        String[] instrMethodClasses = new String[nInstrClasses];\n        int[] instrClassLoaderIds = new int[nInstrClasses];\n        boolean[] instrMethodLeaf = new boolean[nInstrMethods];\n        byte[][] replacementClassFileBytes = new byte[nInstrClasses][];\n        int methodId = status.getStartingMethodId();\n        int classIdx = 0;\n        int methodIdx = 0;\n\n        for (Iterator e = instrClasses.values().iterator(); e.hasNext();) {\n            DynamicClassInfo clazz = (DynamicClassInfo) e.next();\n            int nMethods = clazz.getMethodNames().length;\n            instrMethodClasses[classIdx] = clazz.getName().replace('/', '.').intern(); // NOI18N\n            instrClassLoaderIds[classIdx] = clazz.getLoaderId();\n\n            boolean hasRootMethods = clazz.hasUninstrumentedRootMethods();\n            boolean hasMarkerMethods = clazz.hasUninstrumentedMarkerMethods();\n            DynamicConstantPoolExtension.getCPFragment(clazz, normalInjectionType);\n\n            if (hasRootMethods) {\n                DynamicConstantPoolExtension.getCPFragment(clazz, rootInjectionType);\n            }\n\n            if (hasMarkerMethods) {\n                DynamicConstantPoolExtension.getCPFragment(clazz, markerInjectionType);\n            }\n\n            int imInClass = 0;\n            byte[][] replacementMethodInfos = new byte[nMethods][];\n            RuntimeProfilingPoint[] pointsForClass = getRuntimeProfilingPoints(engineSettings.getRuntimeProfilingPoints(), clazz);\n\n            //System.err.println(\"CLazz: \"+clazz.getName());\n            for (int i = 0; i < nMethods; i++) {\n                // FIXME: issue 68840: An overridden method overriding with subclass of return type is instrumented twice\n                // http://profiler.netbeans.org/issues/show_bug.cgi?id=68840\n                // a method whose return type is not exact match as the method which it implements/overrides would be listed\n                // and processed twice, leading to double instrumentation\n\n                //System.err.println(\"Method: \"+clazz.getMethodName(i)+\" \" + clazz.getMethodSignature(i));\n                RuntimeProfilingPoint[] points = getRuntimeProfilingPoints(pointsForClass, i);\n\n                if (!clazz.isMethodInstrumented(i)) {\n                    if (clazz.isMethodReachable(i) && !clazz.isMethodUnscannable(i)) {\n                        clazz.setMethodInstrumented(i);\n                        instrMethodLeaf[methodIdx] = clazz.isMethodLeaf(i);\n                        //System.err.println(\">>>1 For method \" + clazz.getName() + \".\" + clazz.getMethodName(i) + clazz.getMethodSignature(i) + \" gonna use methodId = \" + methodId);\n                        replacementMethodInfos[i] = InstrumentationFactory.instrumentMethod(clazz, i, normalInjectionType,\n                                                                                            rootInjectionType,\n                                                                                            markerInjectionType, methodId++,\n                                                                                            points);\n                        clazz.saveMethodInfo(i, replacementMethodInfos[i]);\n\n                        status.updateInstrMethodsInfo(instrMethodClasses[classIdx], instrClassLoaderIds[classIdx],\n                                                      clazz.getMethodNames()[i], clazz.getMethodSignatures()[i]);\n                        imInClass++;\n                        methodIdx++;\n                    } else if (points.length > 0) {\n                        replacementMethodInfos[i] = InstrumentationFactory.instrumentAsProiflePointHitMethod(clazz, i,\n                                                                                                             normalInjectionType,\n                                                                                                             points);\n                        clazz.saveMethodInfo(i, replacementMethodInfos[i]);\n                        imInClass++;\n                    }\n                } else {\n                    replacementMethodInfos[i] = clazz.getMethodInfo(i); // Will return the previously instrumented methodInfo\n                    imInClass++;\n                }\n            }\n\n            instrumentServletDoMethods(clazz, replacementMethodInfos);\n\n            if (imInClass > 0) {\n                if (hasRootMethods) {\n                    clazz.setHasUninstrumentedRootMethods(false);\n                }\n\n                if (hasMarkerMethods) {\n                    clazz.setHasUninstrumentedMarkerMethods(false);\n                }\n\n                DynamicConstantPoolExtension wholeECP = DynamicConstantPoolExtension.getAllAddedCPFragments(clazz);\n                int nAddedCPEntries = wholeECP.getNEntries();\n                byte[] addedCPContents = wholeECP.getContents();\n                replacementClassFileBytes[classIdx] = ClassRewriter.rewriteClassFile(clazz, replacementMethodInfos,\n                                                                                     nAddedCPEntries, addedCPContents);\n            }\n            classIdx++;\n        }\n\n        if (!reflectInvokeInstrumented) { // Special instrumentation of java.lang.reflect.Method.invoke()\n            int nMethods = reflectMethodClass.getMethodNames().length;\n            byte[][] replacementMethodInfos = new byte[nMethods][];\n\n            if (reflectMethodClassIdx == -1) {\n                instrMethodClasses[classIdx] = JAVA_LANG_REFLECT_METHOD_DOTTED_CLASS_NAME;\n                instrClassLoaderIds[classIdx] = 0;\n            } else {\n                classIdx = reflectMethodClassIdx;\n\n                for (int i = 0; i < nMethods; i++) {\n                    replacementMethodInfos[i] = reflectMethodClass.getMethodInfo(i);\n                }\n            }\n\n            int idx = reflectMethodClass.getMethodIndex(INVOKE_METHOD_NAME, INVOKE_METHOD_SIGNATURE);\n            DynamicConstantPoolExtension.getCPFragment(reflectMethodClass, INJ_REFLECT_METHOD_INVOKE);\n\n            replacementMethodInfos[idx] = InstrumentationFactory.instrumentAsReflectInvokeMethod(reflectMethodClass, idx);\n\n            DynamicConstantPoolExtension wholeECP = DynamicConstantPoolExtension.getAllAddedCPFragments(reflectMethodClass);\n            int nAddedCPEntries = wholeECP.getNEntries();\n            byte[] addedCPContents = wholeECP.getContents();\n            replacementClassFileBytes[classIdx] = ClassRewriter.rewriteClassFile(reflectMethodClass, replacementMethodInfos, nAddedCPEntries,\n                                                                                 addedCPContents);\n\n            reflectMethodClass.saveMethodInfo(idx, replacementMethodInfos[idx]);\n            reflectInvokeInstrumented = true;\n        }\n\n        return new Object[] { instrMethodClasses, instrClassLoaderIds, instrMethodLeaf, replacementClassFileBytes };\n    }\n\n    private void instrumentServletDoMethods(DynamicClassInfo clazz, byte[][] replacementMethodInfos) {\n        if (!Boolean.getBoolean(\"org.graalvm.visualvm.lib.jfluid.servletTracking\")) { // NOI18N\n            return;\n        }\n\n        if (clazz.isServletDoMethodScanned()) {\n            return;\n        }\n\n        clazz.setServletDoMethodScanned();\n\n        if (!clazz.isSubclassOf(HandleServletDoMethodCallInjector.getClassName())) {\n            return;\n        }\n\n        DynamicConstantPoolExtension.getCPFragment(clazz, INJ_SERVLET_DO_METHOD);\n\n        String[] methods = HandleServletDoMethodCallInjector.getMethodNames();\n        String[] sigs = HandleServletDoMethodCallInjector.getMethodSignatures();\n\n        for (int i = 0; i < methods.length; i++) {\n            int midx = clazz.getMethodIndex(methods[i], sigs[i]);\n\n            if (midx != -1) {\n                replacementMethodInfos[midx] = InstrumentationFactory.instrumentAsServletDoMethod(clazz, midx);\n                clazz.saveMethodInfo(midx, replacementMethodInfos[midx]);\n            }\n        }\n    }\n\n    private void addInsrClass(final DynamicClassInfo clazz) {\n        String classNameAndLoader = clazz.getNameAndLoader();\n\n        if (!instrClasses.containsKey(classNameAndLoader)) {\n            instrClasses.put(classNameAndLoader, clazz);\n            nInstrClasses++;\n        }\n    }\n    \n    private DynamicClassInfo getSuperClass(DynamicClassInfo clazz) {\n        String superClassName = clazz.getSuperclassName();\n        \n        if (clazz.isLoaded()) {\n            List classes = getAllClassVersions(superClassName);\n            if (classes != null && classes.size() == 1) {\n                BaseClassInfo bci = (BaseClassInfo)classes.get(0);\n                if (bci instanceof DynamicClassInfo) return (DynamicClassInfo)bci;\n            }\n        }\n        return javaClassForName(superClassName, clazz.getLoaderId());\n    }\n    \n    private DynamicClassInfo[] getInterfaces(DynamicClassInfo clazz) {\n        String[] interfaceNames = clazz.getInterfaceNames();\n        \n        if (interfaceNames != null) {\n            DynamicClassInfo[] interfaces = new DynamicClassInfo[interfaceNames.length];\n            int loaderId = clazz.getLoaderId();\n            boolean isLoaded = clazz.isLoaded();\n            \n            for (int i = 0; i < interfaceNames.length; i++) {\n                if (isLoaded) {\n                    List classes = getAllClassVersions(interfaceNames[i]);\n                    if (classes != null && classes.size()==1) {\n                        BaseClassInfo bci = (BaseClassInfo)classes.get(0);\n                        if (bci instanceof DynamicClassInfo) {\n                            interfaces[i] = (DynamicClassInfo)classes.get(0);\n                            continue;\n                        }\n                    }\n                }\n                interfaces[i] = javaClassForName(interfaceNames[i], loaderId);\n            }\n            return interfaces;\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/RecursiveMethodInstrumentor1.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.classfile.BaseClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.PlaceholderClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.RootClassLoadedCommand;\n\n\n/**\n * Recursive method scanner that implements the lazy instrumentation scheme (\"Scheme B\" in the JFluid paper).\n *\n * @author Misha Dmitriev\n * @author Adrian Mos\n */\npublic class RecursiveMethodInstrumentor1 extends RecursiveMethodInstrumentor {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    /** A placeholder for a class that contains reachable method and in which transferData() is specialized for this instrumentation scheme */\n    protected class ReachableMethodPlaceholder1 extends ReachableMethodPlaceholder {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ReachableMethodPlaceholder1(String refClassName, int classLoaderId) {\n            super(refClassName, classLoaderId);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void processReachableMethods(DynamicClassInfo clazz) {\n            int len = methodNamesAndSigs.size();\n\n            for (int i = 0; i < len; i += 2) {\n                locateAndMarkMethodReachable(clazz, (String) methodNamesAndSigs.get(i), (String) methodNamesAndSigs.get(i + 1),\n                                             false, true, false, false);\n            }\n        }\n    }\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public RecursiveMethodInstrumentor1(ClassRepository repo, ProfilingSessionStatus status, ProfilerEngineSettings settings) {\n        super(repo, status, settings);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    Object[] getInitialMethodsToInstrument(RootClassLoadedCommand rootLoaded, RootMethods roots) {\n        DynamicClassInfo[] loadedClassInfos = preGetInitialMethodsToInstrument(rootLoaded);\n\n        rootMethods = roots;\n\n        // Check which root classes have already been loaded, and mark their root methods accordingly\n        for (DynamicClassInfo loadedClassInfo : loadedClassInfos) {\n            if (loadedClassInfo == null) {\n                continue; // Can this happen?\n            }\n\n            String className = loadedClassInfo.getName();\n\n            markProfilingPonitForInstrumentation(loadedClassInfo);\n            tryInstrumentSpawnedThreads(loadedClassInfo);\n\n            for (int rIdx = 0; rIdx < rootMethods.classNames.length; rIdx++) {\n                String rootClassName = rootMethods.classNames[rIdx];\n\n                boolean isMatch = false;\n\n                if (rootMethods.classesWildcard[rIdx]) {\n                    if (Wildcards.matchesWildcard(rootClassName, className)) {\n                        //            System.out.println(\"Matched package wildcard - \" + rootClassName);\n                        isMatch = true;\n                    }\n                } else {\n                    if (className == rootClassName) { // precise match\n                        isMatch = true;\n                    }\n                }\n\n                if (isMatch) { // This root class is loaded\n                    boolean isMarkerMethod = rootMethods.markerMethods[rIdx];\n                    boolean checkSubClasses = loadedClassInfo.isInterface() && isMarkerMethod;\n                    if (Wildcards.isPackageWildcard(rootClassName) || Wildcards.isMethodWildcard(rootMethods.methodNames[rIdx])) {\n                        if (isMarkerMethod) {\n                            markAllMethodsMarker(loadedClassInfo);\n                        } else {\n                            markAllMethodsRoot(loadedClassInfo);\n                        }\n\n                        String[] methodNames = loadedClassInfo.getMethodNames();\n                        String[] signatures = loadedClassInfo.getMethodSignatures();\n\n                        for (int methodIdx = 0; methodIdx < methodNames.length; methodIdx++) {\n                            locateAndMarkMethodReachable(loadedClassInfo, methodNames[methodIdx], signatures[methodIdx],\n                                                         false, false, checkSubClasses, isMarkerMethod);\n                        }\n                    } else {\n                        markMethod(loadedClassInfo, rIdx);\n                        locateAndMarkMethodReachable(loadedClassInfo, rootMethods.methodNames[rIdx],\n                                                     rootMethods.methodSignatures[rIdx], false, false, checkSubClasses, isMarkerMethod);\n                    }\n                }\n            }\n        }\n\n        locateAndMarkMethodReachable(javaClassForName(\"java/lang/ClassLoader\", 0), \"loadClass\",   // NOI18N\n                                     \"(Ljava/lang/String;)Ljava/lang/Class;\", true, false, true, false); // NOI18N\n\n        return createInstrumentedMethodPack();\n    }\n\n    public Object[] getMethodsToInstrumentUponClassLoad(String classNameDot, int classLoaderId, boolean threadInCallGraph) {\n        //System.out.println(\"*** MS1: instr. upon CL: \" + className);\n        String className = classNameDot.replace('.', '/').intern(); // NOI18N\n\n        initInstrMethodData();\n        markProfilingPointForInstrumentation(classNameDot,className,classLoaderId);\n        // If a class doesn't pass the current instrumentation filter, we can't immediately reject it, since there is a chance\n        // it contains some root methods. So we have to check that first.\n        boolean isRootClass = false;\n\n        for (int rIdx = 0; rIdx < rootMethods.classNames.length; rIdx++) {\n            final String rootClassName = rootMethods.classNames[rIdx];\n\n            if (rootMethods.classesWildcard[rIdx]) {\n                if (Wildcards.matchesWildcard(rootClassName, className)) {\n                    //          System.out.println(\"Matched package wildcard - \" + rootClassName);\n                    isRootClass = true;\n\n                    break;\n                }\n            } else {\n                if (className == rootClassName) {\n                    isRootClass = true;\n\n                    break;\n                }\n            }\n        }\n\n        boolean normallyFilteredOut = !instrFilter.passes(className);\n\n        if (!isRootClass) {\n            if (normallyFilteredOut) {\n                return createInstrumentedMethodPack(); // profile points !\n            }\n        }\n\n        BaseClassInfo placeholder = loadedJavaClassOrExistingPlaceholderForName(className, classLoaderId);\n        DynamicClassInfo clazz = javaClassForName(className, classLoaderId);\n\n        if (clazz == null) {\n            return null; // Warning already issued\n        }\n\n        boolean instrumentClinit = threadInCallGraph;\n\n        if (!clazz.isLoaded()) {\n            clazz.setLoaded(true);\n            addToSubclassList(clazz, normallyFilteredOut ? null : clazz); // null as a second parameter will result in NOT marking any methods reachable\n\n            // Check to see if this class has been marked as root by the user:\n            for (int rIdx = 0; rIdx < rootMethods.classNames.length; rIdx++) {\n                final String rootClassName = rootMethods.classNames[rIdx];\n\n                boolean isMatch = false;\n\n                if (rootMethods.classesWildcard[rIdx]) {\n                    if (Wildcards.matchesWildcard(rootClassName, className)) {\n                        //            System.out.println(\"Matched package wildcard - \" + rootClassName);\n                        isMatch = true;\n                    }\n                } else {\n                    if (className == rootClassName) { // precise match\n                        isMatch = true;\n                    }\n                }\n\n                if (isMatch) { // it is indeed a root class\n                    boolean checkSubClasses = clazz.isInterface() && rootMethods.markerMethods[rIdx];\n\n                    if (Wildcards.isPackageWildcard(rootClassName) || Wildcards.isMethodWildcard(rootMethods.methodNames[rIdx])) {\n                        if (rootMethods.markerMethods[rIdx]) {\n                            markAllMethodsMarker(clazz);\n                        } else {\n                            markAllMethodsRoot(clazz);\n                        }\n\n                        String[] methodNames = clazz.getMethodNames();\n                        String[] signatures = clazz.getMethodSignatures();\n\n                        for (int methodIdx = 0; methodIdx < methodNames.length; methodIdx++) {\n                            locateAndMarkMethodReachable(clazz, methodNames[methodIdx], signatures[methodIdx], false, false, checkSubClasses, false);\n                        }\n                    } else {\n                        markMethod(clazz, rIdx);\n                        locateAndMarkMethodReachable(clazz, rootMethods.methodNames[rIdx], rootMethods.methodSignatures[rIdx],\n                                                     false, false, checkSubClasses, true);\n                    }\n                }\n            }\n            if (instrumentClinit) {\n                instrumentClinit(clazz);\n            }\n            if (placeholder instanceof ReachableMethodPlaceholder1) {\n                ((ReachableMethodPlaceholder1)placeholder).processReachableMethods(clazz);\n            } else if (placeholder != null) {\n//                System.out.println(\"Class: \"+placeholder.getNameAndLoader());\n            }\n            tryInstrumentSpawnedThreads(clazz);\n\n            return createInstrumentedMethodPack();\n        } else {\n            return null;\n        }\n    }\n\n    public Object[] getMethodsToInstrumentUponMethodInvocation(String className, int classLoaderId, String methodName,\n                                                               String methodSignature) {\n        //System.out.println(\"*** MS1: instr. upon MI: \" + className + \".\" + methodName + methodSignature);\n        className = className.replace('.', '/').intern(); // NOI18N\n        methodName = methodName.intern();\n        methodSignature = methodSignature.intern();\n        initInstrMethodData();\n\n        checkAndScanMethod(className, classLoaderId, methodName, methodSignature);\n\n        return createInstrumentedMethodPack();\n    }\n\n    public Object[] getMethodsToInstrumentUponReflectInvoke(String className, int classLoaderId, String methodName,\n                                                            String methodSignature) {\n        //System.out.println(\"*** MS1: instr. upon reflect MI: \" + className + \".\" + methodName + methodSignature);\n        className = className.replace('.', '/').intern();\n\n        DynamicClassInfo clazz = javaClassForName(className, classLoaderId);\n\n        if (clazz == null) {\n            // System.err.println(\"Warning: could not find class \" + className + \" loaded by the VM on the class path\");\n            // warning already issued in ClassRepository.lookupClass method, no need to do it again\n            return null;\n        }\n\n        if (!clazz.isLoaded()) {\n            return null; // Probably impossible\n        }\n\n        initInstrMethodData();\n\n        methodName = methodName.intern();\n        methodSignature = methodSignature.intern();\n\n        locateAndMarkMethodReachable(clazz, methodName, methodSignature, false, false, false, false);\n\n        //countReachableScannableMethods(clazz);\n        return createInstrumentedMethodPack();\n    }\n\n    protected void findAndMarkOverridingMethodsReachable(DynamicClassInfo superClass, DynamicClassInfo subClass) {\n        if (!superClass.hasMethodReachable()) {\n            return;\n        }\n        \n        String[] methodNames = superClass.getMethodNames();\n        String[] methodSignatures = superClass.getMethodSignatures();\n        boolean lookupInSuper = superClass.isInterface();\n\n        for (int i = 0; i < methodNames.length; i++) {\n            if (!(superClass.isMethodVirtual(i) && superClass.isMethodReachable(i))) {\n                continue;\n            }\n            boolean isMarker = superClass.isMethodMarker(i);\n\n            // int idx = subClass.overridesVirtualMethod(superClass, i); - I once tried this, but with no visible effect. Strict check\n            // for whether a method with the same name and signature in subclass really overrrides a method in superclass, given all other\n            // conditions that we have already checked (e.g. that the method in superclass is not private), will only detect a pathological\n            // case when both method versions are package-private. This is rare, if ever happens at all.\n            locateAndMarkMethodReachable(subClass, methodNames[i], methodSignatures[i], true, lookupInSuper, false, isMarker);\n        }\n    }\n\n    protected void processInvoke(DynamicClassInfo clazz, boolean virtualCall, int index) {\n        byte[] savedCodeBytes = codeBytes;\n        int savedOffset = offset;\n\n        String[] cms = clazz.getRefMethodsClassNameAndSig(index);\n\n        if (cms == null) {\n            return; // That's how coming across our own stuff currently manifests itself, e.g. when scanning instrumented Method.invoke()\n        }\n\n        String refClassName = cms[0];\n\n        if (refClassName.startsWith(PROFILER_SERVER_SLASHED_CLASS_PREFIX)) {\n            return; // We may come across our own stuff e.g. when scanning instrumented Method.invoke()\n        }\n\n        int loaderId = clazz.getLoaderId();\n\n        // Now let's check if the callee class is actually loaded at this time. If not, we just record the fact that the\n        // callee method is reachable using a placeholder class, and return\n        BaseClassInfo refClazz = loadedJavaClassOrExistingPlaceholderForName(refClassName, loaderId);\n\n        if ((refClazz == null) || (refClazz instanceof PlaceholderClassInfo)) {\n            ReachableMethodPlaceholder pci = (refClazz == null) ? new ReachableMethodPlaceholder1(refClassName, loaderId)\n                                                                : (ReachableMethodPlaceholder) refClazz;\n            pci.registerReachableMethod(cms[1], cms[2]);\n\n            if (refClazz == null) {\n                registerPlaceholder(pci);\n            }\n        } else {\n            locateAndMarkMethodReachable((DynamicClassInfo) refClazz, cms[1], cms[2], virtualCall, true, true, false);\n        }\n\n        offset = savedOffset;\n        codeBytes = savedCodeBytes;\n    }\n\n    /**\n     * If instrumenteSpawnedThreads is true and the given class implements Runnable, find  and mark as root its run() method.\n     */\n    protected boolean tryInstrumentSpawnedThreads(DynamicClassInfo clazz) {\n        if (instrumentSpawnedThreads) {\n            if (clazz.implementsInterface(\"java/lang/Runnable\") && (clazz.getName() != \"java/lang/Thread\")) { // NOI18N\n\n                boolean res = markMethodRoot(clazz, \"run\", \"()V\"); // NOI18N\n                locateAndMarkMethodReachable(clazz, \"run\", \"()V\", false, false, false, false); // NOI18N\n\n                return res;\n            }\n        }\n\n        return false;\n    }\n\n    private void instrumentClinit(DynamicClassInfo clazz) {\n        locateAndMarkMethodReachable(clazz, \"<clinit>\", \"()V\", false, false, false, false); // NOI18N        \n    }\n\n    private void checkAndScanMethod(String className, int classLoaderId, String methodName, String methodSignature) {\n        DynamicClassInfo clazz = javaClassForName(className, classLoaderId);\n\n        if (clazz == null) {\n            return;\n        }\n\n        int idx = clazz.getMethodIndex(methodName, methodSignature);\n\n        if (idx == -1) {\n            MiscUtils.internalError(\"can't find method \" + methodName + methodSignature + \" in class \" + className); // NOI18N\n        }\n\n        if (clazz.isMethodUnscannable(idx)) {\n            MiscUtils.internalError(\"got to scan unscannable method \" + className + \".\" + methodName + methodSignature); // NOI18N\n        }\n\n        clazz.setMethodScanned(idx);\n        scanMethod(clazz, idx);\n    }\n\n    /**\n     * Mark the given method reachable. The boolean parameters affect this function in the following way:\n     * - virtualCall = true means that we reached this method via a \"call virtual\" instruction, or otherwise know that it's\n     * virtual, and want to treat it as virtual. So, for example, if checkSubclasses is true, a method with this name and\n     * signature should be looked up in subclasses of this class.\n     * - lookupInSuperIfNotFoundInThis = true means that if the given method is not found in this class, it should be looked\n     * up in its superclasses.\n     * - checkSubclasses = true means that if a method is virtual (either because virtualCall == true or because this method is\n     * really defined in this class and marked as virtual), methods that override it in subclasses of this class should also\n     * be marked reachable.\n     * - setAsMarkerMethod = true means tag reachable method as marker method\n     */\n    private boolean locateAndMarkMethodReachable(DynamicClassInfo clazz, String methodName, String methodSignature,\n                                                 boolean virtualCall, boolean lookupInSuperIfNotFoundInThis,\n                                                 boolean checkSubclasses, boolean setAsMarkerMethod) {\n        boolean constructorNotInstrumented = false;\n        if (clazz == null) {\n            return false; // Normally shouldn't happen, it's just development-time facilitation (introduced when working on 1.5 support)\n        }\n\n        String className = clazz.getName();\n        int idx = clazz.getMethodIndex(methodName, methodSignature);\n\n        if (idx != -1) {\n            if (clazz.isMethodReachable(idx)) {\n                return true;\n            }\n\n            clazz.setMethodReachable(idx);\n\n            if (!clazz.isMethodStatic(idx) && !clazz.isMethodPrivate(idx) && !clazz.isMethodFinal(idx)\n                    && (methodName != \"<init>\")) {  // NOI18N\n                clazz.setMethodVirtual(idx);\n            }\n\n            if (clazz.isMethodNative(idx) || clazz.isMethodAbstract(idx)\n                    || (!clazz.isMethodRoot(idx) && !clazz.isMethodMarker(idx) && !instrFilter.passes(className))\n                    || (className == OBJECT_SLASHED_CLASS_NAME)) {  // Actually, just the Object.<init> method?\n                clazz.setMethodUnscannable(idx);\n            } else if (methodName == \"<init>\" && !status.canInstrumentConstructor && clazz.getMajorVersion()>50) {\n                clazz.setMethodUnscannable(idx);\n                constructorNotInstrumented = true;\n            } else {\n                byte[] bytecode = clazz.getMethodBytecode(idx);\n\n                if ((dontInstrumentEmptyMethods && isEmptyMethod(bytecode))\n                        || (dontScanGetterSetterMethods && isGetterSetterMethod(bytecode))) {\n                    clazz.setMethodUnscannable(idx);\n                } else {\n                    if (isLeafMethod(bytecode)) {\n                        clazz.setMethodLeaf(idx);\n                    }\n                }\n            }\n\n            if (!clazz.isLoaded()) {\n                return true; // No need to check subclasses because there are no loaded subclasses if this class itself is not loaded\n            }\n            \n            // Class is loaded, method is reachable and not unscannable are sufficient conditions for instrumenting method\n            if (!clazz.isMethodUnscannable(idx)) {\n                markClassAndMethodForInstrumentation(clazz, idx);\n                if (setAsMarkerMethod) {\n                    clazz.setMethodMarker(idx);\n                }\n            } else if (constructorNotInstrumented) {\n                scanMethod(clazz, idx);\n            }\n        }\n\n        if (checkSubclasses && (((idx != -1) && clazz.isMethodVirtual(idx)) || ((idx == -1) && virtualCall)) && className != OBJECT_SLASHED_CLASS_NAME) {\n            ArrayList subclasses = clazz.getSubclasses();\n\n            if (subclasses != null) {\n                preloadBytecodeForAllSubclasses(subclasses);\n                for (int i = 0; i < subclasses.size(); i++) {\n                    DynamicClassInfo subClass = (DynamicClassInfo) subclasses.get(i);\n                    //System.out.println(\"Gonna scan subclass \" + subclassNames.get(i) + \" of class \" + className + \" for method \" + methodName);\n                    // DynamicClassInfo subClass = javaClassForName((String) subclassNames.get(i));\n                    // if ((idx != -1 && subClass.overridesVirtualMethod(clazz, idx) != -1) || idx == -1) - see the comment in findAndMarkOverridingMethods()\n                    // on why this seems to be of no use.\n                    if (!subClass.isInterface()) {\n                        boolean searchSuper = clazz.isInterface() && !subclasses.contains(subClass.getSuperClass());\n                        locateAndMarkMethodReachable(subClass, methodName, methodSignature, virtualCall,\n                                                      searchSuper, false, setAsMarkerMethod);\n                    }\n                }\n            }\n        }\n\n        if (idx != -1) {\n            return true;\n        }\n\n        if (!lookupInSuperIfNotFoundInThis) {\n            return false;\n        }\n\n        // Method not defined in this class - try superclass, and if not successful - all superinterfaces\n        if (!clazz.isInterface()) {\n            DynamicClassInfo superClazz = clazz.getSuperClass();\n\n            if ((superClazz != null) && (superClazz.getName() != clazz.getName())) {\n                if (locateAndMarkMethodReachable(superClazz, methodName, methodSignature, virtualCall, true, false, setAsMarkerMethod)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    //----------------------------------- Private implementation ------------------------------------------------\n    private DynamicClassInfo[] preGetInitialMethodsToInstrument(RootClassLoadedCommand rootLoaded) {\n        //System.out.println(\"*** MS1: instr. initial: \" + rootClassName);\n        resetLoadedClassData();\n        storeClassFileBytesForCustomLoaderClasses(rootLoaded);\n        initInstrMethodData();\n\n        String[] loadedClasses = rootLoaded.getAllLoadedClassNames();\n        int[] loadedClassLoaderIds = rootLoaded.getAllLoadedClassLoaderIds();\n        DynamicClassInfo[] loadedClassInfos = new DynamicClassInfo[loadedClasses.length];\n\n        // preload all classes\n        for (int i = 0; i < loadedClasses.length; i++) {\n            DynamicClassInfo clazz = javaClassForName(loadedClasses[i], loadedClassLoaderIds[i]);\n\n            if (clazz == null) {\n                continue;\n            }\n\n            clazz.setLoaded(true);\n            loadedClassInfos[i] = clazz;\n        }\n        for (int i = 0; i < loadedClasses.length; i++) {\n            DynamicClassInfo clazz = javaClassForName(loadedClasses[i], loadedClassLoaderIds[i]);\n\n            if (clazz != null) {\n                addToSubclassList(clazz, clazz);\n            }\n        }\n\n        return loadedClassInfos;\n    }\n    \n    void preloadBytecodeForAllSubclasses(Collection classes) {\n        for (Object clazz : classes) {\n            ((DynamicClassInfo)clazz).preloadBytecode();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/RecursiveMethodInstrumentor2.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport java.util.ArrayList;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.classfile.BaseClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.PlaceholderClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.RecursiveMethodInstrumentor.ReachableMethodPlaceholder;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.RootClassLoadedCommand;\n\n\n/**\n * Recursive method scanner that implements the eager instrumentation scheme (\"Scheme A\" in the JFluid paper).\n *\n * @author Misha Dmitriev\n * @author Adrian Mos\n */\npublic class RecursiveMethodInstrumentor2 extends RecursiveMethodInstrumentor {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    /** A placeholder for a class that contains reachable method and in which transferData() is specialized for this instrumentation scheme */\n    protected class ReachableMethodPlaceholder2 extends ReachableMethodPlaceholder {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ReachableMethodPlaceholder2(String refClassName, int classLoaderId) {\n            super(refClassName, classLoaderId);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void transferDataIntoRealClass(DynamicClassInfo clazz) {\n            super.transferDataIntoRealClass(clazz);\n\n            int len = methodNamesAndSigs.size();\n\n            for (int i = 0; i < len; i += 2) {\n                checkAndScanMethod(clazz, (String) methodNamesAndSigs.get(i), (String) methodNamesAndSigs.get(i + 1), false,\n                                   false, false);\n            }\n        }\n    }\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public RecursiveMethodInstrumentor2(ClassRepository repo, ProfilingSessionStatus status, ProfilerEngineSettings settings) {\n        super(repo, status, settings);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    Object[] getInitialMethodsToInstrument(RootClassLoadedCommand rootLoaded, RootMethods roots) {\n        DynamicClassInfo[] loadedClassInfos = preGetInitialMethodsToInstrument(rootLoaded);\n\n        rootMethods = roots;\n\n        // Check which root classes have already been loaded, and mark their root methods accordingly\n        for (DynamicClassInfo loadedClassInfo : loadedClassInfos) {\n            if (loadedClassInfo == null) {\n                continue; // Can this happen?\n            }\n\n            markProfilingPonitForInstrumentation(loadedClassInfo);\n            tryInstrumentSpawnedThreads(loadedClassInfo); // This only checks for Runnable.run()\n\n            for (int rIdx = 0; rIdx < rootMethods.classNames.length; rIdx++) {\n                String rootClassName = rootMethods.classNames[rIdx];\n                boolean isMatch = false;\n\n                if (rootMethods.classesWildcard[rIdx]) {\n                    if (Wildcards.matchesWildcard(rootClassName, loadedClassInfo.getName())) {\n                        //            System.out.println(\"(Instrumentor 2) Matched package wildcard - \" + rootClassName);\n                        isMatch = true;\n                    }\n                } else {\n                    if (loadedClassInfo.getName().equals(rootClassName)) { // precise match\n                        isMatch = true;\n                    }\n                }\n\n                if (isMatch) { // This root class is loaded\n\n                    if (Wildcards.isPackageWildcard(rootClassName) || Wildcards.isMethodWildcard(rootMethods.methodNames[rIdx])) {\n                        if (rootMethods.markerMethods[rIdx]) {\n                            markAllMethodsMarker(loadedClassInfo);\n                        } else {\n                            markAllMethodsRoot(loadedClassInfo);\n                        }\n\n                        String[] methodNames = loadedClassInfo.getMethodNames();\n                        String[] signatures = loadedClassInfo.getMethodSignatures();\n\n                        for (int methodIdx = 0; methodIdx < methodNames.length; methodIdx++) {\n                            checkAndScanMethod(loadedClassInfo, methodNames[methodIdx], signatures[methodIdx], false, false,\n                                               false);\n                        }\n                    } else {\n                        markMethod(loadedClassInfo, rIdx);\n                        checkAndScanMethod(loadedClassInfo, rootMethods.methodNames[rIdx],\n                                           rootMethods.methodSignatures[rIdx], false, false, false);\n                    }\n                }\n            }\n        }\n\n        // So that class loading is measured correctly from the beginning\n        checkAndScanMethod(javaClassForName(\"java/lang/ClassLoader\", 0), \"loadClass\", \"(Ljava/lang/String;)Ljava/lang/Class;\", // NOI18N\n                           true, false, true);\n\n        return createInstrumentedMethodPack();\n    }\n\n    public Object[] getMethodsToInstrumentUponClassLoad(String classNameDot, int classLoaderId, boolean threadInCallGraph) {\n        //System.out.println(\"*** MS2: instr. upon CL: \" + className);\n        String className = classNameDot.replace('.', '/').intern(); // NOI18N\n\n        initInstrMethodData();\n        markProfilingPointForInstrumentation(classNameDot,className,classLoaderId);\n        // If a class doesn't pass the current instrumentation filter, we can't immediately reject it, since there is a chance\n        // it contains some root methods. So we have to check that first.\n        boolean isRootClass = false;\n\n        for (int rIdx = 0; rIdx < rootMethods.classNames.length; rIdx++) {\n            String rootClassName = rootMethods.classNames[rIdx];\n\n            if (rootMethods.classesWildcard[rIdx]) {\n                if (Wildcards.matchesWildcard(rootClassName, className)) {\n                    //          System.out.println(\"(Instrumentor 2) Matched package wildcard - \" + rootClassName);\n                    isRootClass = true;\n\n                    break;\n                }\n            } else {\n                if (className.equals(rootClassName)) {\n                    isRootClass = true;\n\n                    break;\n                }\n            }\n        }\n\n        boolean normallyFilteredOut = !instrFilter.passes(className);\n\n        if (!isRootClass) {\n            if (normallyFilteredOut) {\n                return createInstrumentedMethodPack();  // profile points!\n            }\n        }\n\n        DynamicClassInfo clazz = javaClassForName(className, classLoaderId);\n\n        if (clazz == null) {\n            return null; // Warning already issued\n        }\n\n        boolean instrumentClinit = threadInCallGraph;\n\n        if (!clazz.isLoaded()) {\n            clazz.setLoaded(true);\n            addToSubclassList(clazz, normallyFilteredOut ? null : clazz); // This call may cause scanning of methods of this class, so all initialization should be done before\n\n            // Check to see if this class has been marked as root by the user:\n            for (int rIdx = 0; rIdx < rootMethods.classNames.length; rIdx++) {\n                String rootClassName = rootMethods.classNames[rIdx];\n                boolean isMatch = false;\n\n                if (rootMethods.classesWildcard[rIdx]) {\n                    if (Wildcards.matchesWildcard(rootClassName, className)) {\n                        //            System.out.println(\"(Instrumentor 2) Matched package wildcard - \" + rootClassName);\n                        isMatch = true;\n                    }\n                } else {\n                    if (className.equals(rootClassName)) { // precise match\n                        isMatch = true;\n                    }\n                }\n\n                if (isMatch) { //it is indeed a root class\n\n                    if (Wildcards.isPackageWildcard(rootClassName) || Wildcards.isMethodWildcard(rootMethods.methodNames[rIdx])) {\n                        if (rootMethods.markerMethods[rIdx]) {\n                            markAllMethodsMarker(clazz);\n                        } else {\n                            markAllMethodsRoot(clazz);\n                        }\n\n                        String[] methodNames = clazz.getMethodNames();\n                        String[] signatures = clazz.getMethodSignatures();\n\n                        for (int methodIdx = 0; methodIdx < methodNames.length; methodIdx++) {\n                            checkAndScanMethod(clazz, methodNames[methodIdx], signatures[methodIdx], false, false, false);\n                        }\n                    } else {\n                        markMethod(clazz, rIdx);\n                        checkAndScanMethod(clazz, rootMethods.methodNames[rIdx], rootMethods.methodSignatures[rIdx], false,\n                                           false, false);\n                    }\n                }\n            }\n\n            String[] methodNames = clazz.getMethodNames();\n            String[] methodSignatures = clazz.getMethodSignatures();\n\n            for (int i = 0; i < methodNames.length; i++) {\n                if (clazz.isMethodReachable(i)\n                        || (!normallyFilteredOut && instrumentClinit && (methodNames[i] == \"<clinit>\"))) { // NOI18N\n                    checkAndScanMethod(clazz, methodNames[i], methodSignatures[i], false, false, false);\n                }\n            }\n\n            tryInstrumentSpawnedThreads(clazz);\n\n            return createInstrumentedMethodPack();\n        } else {\n            return null;\n        }\n    }\n\n    public Object[] getMethodsToInstrumentUponMethodInvocation(String className, int classLoaderId, String methodName,\n                                                               String methodSignature) {\n        return null; // This method is just not used with this flavour of MethodScanner\n    }\n\n    public Object[] getMethodsToInstrumentUponReflectInvoke(String className, int classLoaderId, String methodName,\n                                                            String methodSignature) {\n        //System.out.println(\"*** MS2: instr. upon reflect MI: \" + className + \".\" + methodName + methodSignature);\n        className = className.replace('.', '/').intern(); // NOI18N\n\n        DynamicClassInfo clazz = javaClassForName(className, classLoaderId);\n\n        if (clazz == null) {\n            return null;\n        }\n\n        initInstrMethodData();\n\n        methodName = methodName.intern();\n        methodSignature = methodSignature.intern();\n\n        checkAndScanMethod(clazz, methodName, methodSignature, false, false, false);\n\n        return createInstrumentedMethodPack();\n    }\n\n    protected void findAndMarkOverridingMethodsReachable(DynamicClassInfo superClass, DynamicClassInfo subClass) {\n        String[] methodNames = superClass.getMethodNames();\n        String[] methodSignatures = superClass.getMethodSignatures();\n\n        for (int i = 0; i < methodNames.length; i++) {\n            if (!(superClass.isMethodVirtual(i) && superClass.isMethodReachable(i))) {\n                continue;\n            }\n\n            // int idx = subClass.overridesVirtualMethod(superClass, i); - I once tried this, but with no visible effect. Strict check\n            // for whether a method with the same name and signature in subclass really overrrides a method in superclass, given all other\n            // conditions that we have already checked (e.g. that the method in superclass is not private), will only detect a pathological\n            // case when both method versions are package-private. This is rare, if ever happens at all.\n            checkAndScanMethod(subClass, methodNames[i], methodSignatures[i], true, false, false);\n        }\n    }\n\n    protected void processInvoke(DynamicClassInfo clazz, boolean virtualCall, int index) {\n        byte[] savedCodeBytes = codeBytes;\n        int savedOffset = offset;\n\n        String[] cms = clazz.getRefMethodsClassNameAndSig(index);\n\n        if (cms == null) {\n            return; // That's how coming across our own stuff currently manifests itself, e.g. when scanning instrumented Method.invoke()\n        }\n\n        String refClassName = cms[0];\n\n        if (refClassName.startsWith(PROFILER_SERVER_SLASHED_CLASS_PREFIX)) {\n            return; // We may come across our own stuff e.g. when scanning instrumented Method.invoke()\n        }\n\n        int loaderId = clazz.getLoaderId();\n\n        // Now let's check if the callee class is actually loaded at this time. If not, we just record the fact that the\n        // callee method is reachable using a placeholder class, and return\n        BaseClassInfo refClazz = loadedJavaClassOrExistingPlaceholderForName(refClassName, loaderId);\n\n        if ((refClazz == null) || (refClazz instanceof PlaceholderClassInfo)) {\n            ReachableMethodPlaceholder pci = (refClazz == null) ? new ReachableMethodPlaceholder2(refClassName, loaderId)\n                                                                : (ReachableMethodPlaceholder) refClazz;\n            pci.registerReachableMethod(cms[1], cms[2]);\n\n            if (refClazz == null) {\n                registerPlaceholder(pci);\n            }\n        } else {\n            checkAndScanMethod((DynamicClassInfo) refClazz, cms[1], cms[2], virtualCall, true, true);\n        }\n\n        offset = savedOffset;\n        codeBytes = savedCodeBytes;\n    }\n\n    protected boolean tryInstrumentSpawnedThreads(DynamicClassInfo clazz) {\n        if (instrumentSpawnedThreads) {\n            if (clazz.implementsInterface(\"java/lang/Runnable\") && (clazz.getName() != \"java/lang/Thread\")) { // NOI18N\n\n                boolean res = markMethodRoot(clazz, \"run\", \"()V\"); // NOI18N\n                checkAndScanMethod(clazz, \"run\", \"()V\", false, false, false); // NOI18N\n\n                return res;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Mark the given method reachable. The boolean parameters affect this function in the following way:\n     * - virtualCall = true means that we reached this method via a \"call virtual\" instruction, or otherwise know that it's\n     * virtual, and want to treat it as virtual. So, for example, if checkSubclasses is true, a method with this name and\n     * signature should be looked up in subclasses of this class.\n     * - lookupInSuperIfNotFoundInThis = true means that if the given method is not found in this class, it should be looked\n     * up in its superclasses.\n     * - checkSubclasses = true means that if a method is virtual (either because virtualCall == true or because this method is\n     * really defined in this class and marked as virtual), methods that override it in subclasses of this class should also\n     * be marked reachable.\n     */\n    private boolean checkAndScanMethod(DynamicClassInfo clazz, String methodName, String methodSignature, boolean virtualCall,\n                                       boolean lookupInSuperIfNotFoundInThis, boolean checkSubclasses) {\n        boolean constructorNotInstrumented = false;\n        String className = clazz.getName();\n        int idx = clazz.getMethodIndex(methodName, methodSignature);\n\n        if (idx != -1) {\n            byte[] bytecode = null;\n\n            if (!clazz.isMethodReachable(idx)) {\n                clazz.setMethodReachable(idx);\n\n                if (!clazz.isMethodStatic(idx) && !clazz.isMethodPrivate(idx) && !clazz.isMethodFinal(idx)\n                        && (methodName != \"<init>\")) { //NOI18N\n                    clazz.setMethodVirtual(idx);\n                }\n\n                if (clazz.isMethodNative(idx) || clazz.isMethodAbstract(idx)\n                        || (!clazz.isMethodRoot(idx) && !clazz.isMethodMarker(idx) && !instrFilter.passes(className))\n                        || (className == OBJECT_SLASHED_CLASS_NAME)) {  // Actually, just the Object.<init> method?\n                    clazz.setMethodUnscannable(idx);\n                } else if (methodName == \"<init>\" && !status.canInstrumentConstructor && clazz.getMajorVersion()>50) {\n                    clazz.setMethodUnscannable(idx);\n                    constructorNotInstrumented = true;\n                } else {\n                    bytecode = clazz.getMethodBytecode(idx);\n\n                    if ((dontInstrumentEmptyMethods && isEmptyMethod(bytecode))\n                            || (dontScanGetterSetterMethods && isGetterSetterMethod(bytecode))) {\n                        clazz.setMethodUnscannable(idx);\n                    } else {\n                        if (isLeafMethod(bytecode)) {\n                            clazz.setMethodLeaf(idx);\n                        }\n                    }\n                }\n            } else { // Method is already marked reachable - could be done for a not yet loaded class\n\n                if (clazz.isMethodScanned(idx) || clazz.isMethodUnscannable(idx)) {\n                    return true;\n                } else {\n                    bytecode = clazz.getMethodBytecode(idx);\n                }\n            }\n\n            if (!clazz.isLoaded()) {\n                return true; // No need to check subclasses because there are no loaded subclasses if this class itself is not loaded\n                             // Class is loaded, method is reachable and not unscannable are sufficient conditions for instrumenting method\n            }\n\n            if (!clazz.isMethodUnscannable(idx)) {\n                markClassAndMethodForInstrumentation(clazz, idx);\n                clazz.setMethodScanned(idx);\n                //if (!lookupInSuperIfNotFoundInThis && !checkSubclasses) System.out.println(\"Gonna scan potentially reachable \" + className + \".\" + methodName + methodSignature);\n                scanBytecode(clazz, bytecode);\n            } else if (constructorNotInstrumented) {\n                scanMethod(clazz, idx);\n            }\n        }\n\n        if (checkSubclasses && (((idx != -1) && clazz.isMethodVirtual(idx)) || ((idx == -1) && virtualCall))) {\n            ArrayList subclasses = clazz.getSubclasses();\n\n            if (subclasses != null) {\n                for (int i = 0; i < subclasses.size(); i++) {\n                    DynamicClassInfo subClass = (DynamicClassInfo) subclasses.get(i);\n                    //System.out.println(\"Gonna scan subclass \" + subclassNames.get(i) + \" of class \" + className + \" for method \" + methodName);\n                    // DynamicClassInfo subClass = javaClassForName((String) subclassNames.get(i));\n                    // if ((idx != -1 && subClass.overridesVirtualMethod(clazz, idx) != -1) || idx == -1) - see the comment in findAndMarkOverridingMethods()\n                    // on why this seems to be of no use.\n                    if (!subClass.isInterface()) {\n                        boolean searchSuper = clazz.isInterface() && !subclasses.contains(subClass.getSuperClass());\n                        checkAndScanMethod(subClass, methodName, methodSignature, virtualCall, searchSuper,\n                                           false);\n                    }\n                }\n            }\n        }\n\n        if (idx != -1) {\n            return true;\n        }\n\n        if (!lookupInSuperIfNotFoundInThis) {\n            return false;\n        }\n\n        // Method not defined in this class - try superclass, and if not successful - all superinterfaces\n        if (!clazz.isInterface()) {\n            DynamicClassInfo superClazz = clazz.getSuperClass();\n\n            if ((superClazz != null) && (superClazz.getName() != clazz.getName())) {\n                if (checkAndScanMethod(superClazz, methodName, methodSignature, virtualCall, true, false)) {\n                    return true;\n                }\n            }\n        }\n\n        return false;\n    }\n\n    //----------------------------------- Private implementation ------------------------------------------------\n    private DynamicClassInfo[] preGetInitialMethodsToInstrument(RootClassLoadedCommand rootLoaded) {\n        //System.out.println(\"*** MS2: instr. initial\");\n        resetLoadedClassData();\n        storeClassFileBytesForCustomLoaderClasses(rootLoaded);\n        initInstrMethodData();\n\n        DynamicClassInfo[] loadedClassInfos;\n        String[] loadedClasses = rootLoaded.getAllLoadedClassNames();\n        int[] loadedClassLoaderIds = rootLoaded.getAllLoadedClassLoaderIds();\n        //if (instrumentSpawnedThreads) tmpClassInfos = new DynamicClassInfo[loadedClasses.length];\n        loadedClassInfos = new DynamicClassInfo[loadedClasses.length]; //EJB Work: removed the condition in the above line as we need to return the temp array anyway (used to check for multiple roots, see the overloaded getInitialMethodsToInstrument )\n\n        for (int i = 0; i < loadedClasses.length; i++) {\n            DynamicClassInfo clazz = javaClassForName(loadedClasses[i], loadedClassLoaderIds[i]);\n\n            if (clazz == null) {\n                continue;\n            }\n\n            clazz.setLoaded(true);\n            addToSubclassList(clazz, clazz);\n            loadedClassInfos[i] = clazz;\n        }\n\n        return loadedClassInfos;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/RecursiveMethodInstrumentor3.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.RootClassLoadedCommand;\n\n\n/**\n * Recursive method scanner that implements the total instrumentation scheme.\n * In fact, it's not even a scanner, since it just instruments absolutely everything -\n * but it uses the same interface.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class RecursiveMethodInstrumentor3 extends RecursiveMethodInstrumentor {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    // Attributes to hold saved values for root classes, methods and signatures\n    private boolean noExplicitRootsSpecified = false, mainMethodInstrumented = false;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public RecursiveMethodInstrumentor3(ClassRepository repo,ProfilingSessionStatus status, ProfilerEngineSettings settings) {\n        super(repo, status, settings);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Object[] getMethodsToInstrumentUponClassLoad(String className, int classLoaderId, boolean threadInCallGraph) {\n        boolean DEBUG = false;\n\n        /*    if (className.startsWith(\"java2d\")) {\n           DEBUG = true;\n           }\n         */\n        if (DEBUG) {\n            System.out.println(\"*** MS2: instr. upon CL: \" + className); // NOI18N\n        }\n\n        className = className.replace('.', '/').intern(); // NOI18N\n\n        DynamicClassInfo clazz = javaClassForName(className, classLoaderId);\n\n        if (clazz == null) {\n            return null;\n        }\n\n        if (DEBUG) {\n            System.out.println(\"*** MS2: instr. upon CL 2: \" + clazz.getNameAndLoader()); // NOI18N\n        }\n\n        clazz.setLoaded(true);\n        addToSubclassList(clazz, clazz); // Have to call this in advance to determine if a class implements Runnable (possibly indirectly)\n\n        if (clazz.isInterface()) {\n            return null;\n        }\n\n        initInstrMethodData();\n\n        // Mark as roots all methods that the total instrumentation method views as implicit roots\n        boolean isRootClass = false;\n        int rootIdxForAll = -1;\n\n        markProfilingPonitForInstrumentation(clazz);\n        isRootClass = tryInstrumentSpawnedThreads(clazz); // This only checks for Runnable.run()\n\n        if (noExplicitRootsSpecified && !mainMethodInstrumented) { // Check if this class has main method. The first loaded class with main method should be main class.\n\n            if (tryMainMethodInstrumentation(clazz)) {\n                isRootClass = true;\n                // allow to instrument two main classes if one of them is from sun.launcher package\n                if (!clazz.getName().startsWith(\"sun/launcher/Launcher\")) {     // NOI18N\n                    mainMethodInstrumented = true;\n                }\n            }\n        }\n\n        // Check to see if this class has been marked as root by the user:\n        if (!isRootClass) {\n            for (int rIdx = 0; rIdx < rootMethods.classNames.length; rIdx++) {\n                String rootClassName = rootMethods.classNames[rIdx];\n\n                if (rootMethods.classesWildcard[rIdx]) {\n                    if (Wildcards.matchesWildcard(rootClassName, className)) {\n                        //            System.out.println(\"Matched package wildcard - \" + rootClassName);\n                        isRootClass = true;\n\n                        break;\n                    }\n                } else {\n                    if (className.equals(rootClassName)) {\n                        isRootClass = true;\n\n                        break;\n                    }\n                }\n            }\n        }\n\n        boolean normallyFilteredOut = !instrFilter.passes(className);\n\n        if (!isRootClass) {\n            if (normallyFilteredOut) {\n                return createInstrumentedMethodPack(); // profile points !\n            }\n        }\n\n        // Check to see if this class has been marked as root by the user:\n        for (int rIdx = 0; rIdx < rootMethods.classNames.length; rIdx++) {\n            String rootClassName = rootMethods.classNames[rIdx];\n            boolean isMatch = false;\n\n            if (rootMethods.classesWildcard[rIdx]) {\n                if (Wildcards.matchesWildcard(rootClassName, className)) {\n                    //            System.out.println(\"Matched package wildcard - \" + rootClassName);\n                    isMatch = true;\n                }\n            } else {\n                if (className.equals(rootClassName)) { // precise match\n                    isMatch = true;\n                }\n            }\n\n            if (isMatch) { // it is indeed a root class\n\n                if (Wildcards.isPackageWildcard(rootClassName) || Wildcards.isMethodWildcard(rootMethods.methodNames[rIdx])) {\n                    if (rootMethods.markerMethods[rIdx]) {\n                        markAllMethodsMarker(clazz);\n                    } else {\n                        markAllMethodsRoot(clazz);\n                    }\n                } else {\n                    markMethod(clazz, rIdx);\n                    checkAndMarkMethodForInstrumentation(clazz, rootMethods.methodNames[rIdx], rootMethods.methodSignatures[rIdx]);\n                }\n            }\n        }\n\n        if (!normallyFilteredOut || clazz.getAllMethodsMarkers() || clazz.getAllMethodsRoots()) {\n            checkAndMarkAllMethodsForInstrumentation(clazz);\n        }\n\n        return createInstrumentedMethodPack();\n    }\n\n    public Object[] getMethodsToInstrumentUponMethodInvocation(String className, int classLoaderId, String methodName,\n                                                               String methodSignature) {\n        // This method is just not used with this flavour of MethodScanner\n        throw new IllegalStateException(\"Class \"+className+\" method \"+methodName);\n    }\n\n    public Object[] getMethodsToInstrumentUponReflectInvoke(String className, int classLoaderId, String methodName,\n                                                            String methodSignature) {\n        return null; // Doesn't have to do anything - everything is handled upon class load\n    }\n\n    protected void findAndMarkOverridingMethodsReachable(DynamicClassInfo superClass, DynamicClassInfo subClass) {\n        // Doesn't do anything (actually not used/called at all) in this scaner\n    }\n\n    protected void processInvoke(DynamicClassInfo clazz, boolean virtualCall, int index) {\n        // Doesn't do anything (not used) in this scaner\n    }\n\n    protected boolean tryInstrumentSpawnedThreads(DynamicClassInfo clazz) {\n//        System.err.println(\"TryInstrumentSpawnedThreads: \" + instrumentSpawnedThreads + \"/\" + noExplicitRootsSpecified);\n        if (instrumentSpawnedThreads || noExplicitRootsSpecified) {\n            if (clazz.implementsInterface(\"java/lang/Runnable\") && (clazz.getName() != \"java/lang/Thread\")) { // NOI18N\n\n                boolean res = markMethodRoot(clazz, \"run\", \"()V\"); // NOI18N\n                checkAndMarkMethodForInstrumentation(clazz, \"run\", \"()V\"); // NOI18N\n\n                return res;\n            }\n        }\n\n        return false;\n    }\n\n    protected boolean tryMainMethodInstrumentation(DynamicClassInfo clazz) {\n        int idx = clazz.getMethodIndex(\"main\", \"([Ljava/lang/String;)V\"); // NOI18N\n\n        if (idx == -1) {\n            return false;\n        }\n\n        if (!(clazz.isMethodStatic(idx) && clazz.isMethodPublic(idx))) {\n            return false;\n        }\n\n        markMethodRoot(clazz, \"main\", \"([Ljava/lang/String;)V\"); // NOI18N\n        checkAndMarkMethodForInstrumentation(clazz, idx);\n\n        return true;\n    }\n\n    Object[] getInitialMethodsToInstrument(RootClassLoadedCommand rootLoaded, RootMethods roots) {\n        DynamicClassInfo[] loadedClassInfos = preGetInitialMethodsToInstrument(rootLoaded);\n\n        rootMethods = roots;\n        checkForNoRootsSpecified(roots);\n\n        // Check which root classes have already been loaded, and mark their root methods accordingly\n        for (DynamicClassInfo loadedClassInfo : loadedClassInfos) {\n            if (loadedClassInfo == null) {\n                continue; // Can this happen?\n            }\n\n            markProfilingPonitForInstrumentation(loadedClassInfo);\n            tryInstrumentSpawnedThreads(loadedClassInfo); // This only checks for Runnable.run()\n\n            for (int rIdx = 0; rIdx < rootMethods.classNames.length; rIdx++) {\n                String rootClassName = rootMethods.classNames[rIdx];\n                boolean isMatch = false;\n\n                if (rootMethods.classesWildcard[rIdx]) {\n                    if (Wildcards.matchesWildcard(rootClassName, loadedClassInfo.getName())) {\n                        //            System.out.println(\"Matched package wildcard - \" + rootClassName);\n                        isMatch = true;\n                    }\n                } else {\n                    if (loadedClassInfo.getName().equals(rootClassName)) { // precise match\n                        isMatch = true;\n                    }\n                }\n\n                if (isMatch) {\n                    if (Wildcards.isPackageWildcard(rootClassName) || Wildcards.isMethodWildcard(rootMethods.methodNames[rIdx])) {\n                        if (rootMethods.markerMethods[rIdx]) {\n                            markAllMethodsMarker(loadedClassInfo);\n                        } else {\n                            markAllMethodsRoot(loadedClassInfo);\n                        }\n                    } else {\n                        markMethod(loadedClassInfo, rIdx);\n                        checkAndMarkMethodForInstrumentation(loadedClassInfo, rootMethods.methodNames[rIdx],\n                                                             rootMethods.methodSignatures[rIdx]);\n                    }\n                }\n            }\n\n            checkAndMarkAllMethodsForInstrumentation(loadedClassInfo);\n        }\n\n        // So that class loading is measured correctly from the beginning\n        checkAndMarkMethodForInstrumentation(javaClassForName(\"java/lang/ClassLoader\", 0), \"loadClass\",  // NOI18N\n                                             \"(Ljava/lang/String;)Ljava/lang/Class;\");  // NOI18N\n\n        return createInstrumentedMethodPack();\n    }\n\n    private void checkAndMarkAllMethodsForInstrumentation(DynamicClassInfo clazz) {\n        if (clazz.isInterface()) {\n            return;\n        }\n\n        String[] methods = clazz.getMethodNames();\n\n        for (int i = 0; i < methods.length; i++) {\n            checkAndMarkMethodForInstrumentation(clazz, i);\n        }\n    }\n\n    /** Mark the given method reachable, if there are no barriers for that (like native, empty, etc. method) */\n    private void checkAndMarkMethodForInstrumentation(DynamicClassInfo clazz, String methodName, String methodSignature) {\n        if (clazz == null) {\n            return;\n        }\n\n        int idx = clazz.getMethodIndex(methodName, methodSignature);\n\n        if (idx == -1) {\n            return;\n        }\n\n        checkAndMarkMethodForInstrumentation(clazz, idx);\n    }\n\n    private void checkAndMarkMethodForInstrumentation(DynamicClassInfo clazz, int idx) {\n        String className = clazz.getName();\n\n        if (!clazz.isMethodReachable(idx)) {\n            clazz.setMethodReachable(idx);\n\n            if (clazz.isMethodNative(idx) || clazz.isMethodAbstract(idx)\n                    || (!clazz.isMethodRoot(idx) && !clazz.isMethodMarker(idx) && !instrFilter.passes(className))\n                    || (className == OBJECT_SLASHED_CLASS_NAME) // Actually, just the Object.<init> method?\n            ) {\n                clazz.setMethodUnscannable(idx);\n            } else if (clazz.getMethodName(idx) == \"<init>\" && !status.canInstrumentConstructor && clazz.getMajorVersion()>50) {\n                clazz.setMethodUnscannable(idx);\n            } else {\n                byte[] bytecode = clazz.getMethodBytecode(idx);\n\n                if ((dontInstrumentEmptyMethods && isEmptyMethod(bytecode))\n                        || (dontScanGetterSetterMethods && isGetterSetterMethod(bytecode))) {\n                    clazz.setMethodUnscannable(idx);\n                } else {\n                    clazz.setMethodLeaf(idx);\n                }\n            }\n\n            // Class is loaded, method is reachable and not unscannable are sufficient conditions for instrumenting method\n            if (!clazz.isMethodUnscannable(idx)) {\n                markClassAndMethodForInstrumentation(clazz, idx);\n            }\n        }\n    }\n\n    private void checkForNoRootsSpecified(RootMethods roots) {\n//        System.err.println(\"Checking for no roots specified\");\n        // It may happen, for example when directly attaching to a remote application and choosing the Entire App CPU\n        // profiling, that there are no explicitly specified root methods (because the main method is not known in advance).\n        // To get sensible profiling results, we take special measures, by just guessing what the main class is.\n        noExplicitRootsSpecified = true;\n        \n        if ((roots != null) && (roots.classNames.length != 0)) {\n            int rootCount = roots.markerMethods.length;\n\n            if (rootCount > 0) {\n                for (int i = 0; i < rootCount; i++) {\n                    if (!roots.markerMethods[i]) {\n                        noExplicitRootsSpecified = false;\n\n                        break;\n                    }\n                }\n            }\n        }\n//        System.err.println(\"NoRootsSpecified = \" + noExplicitRootsSpecified);\n    }\n\n    //----------------------------------- Private implementation ------------------------------------------------\n    private DynamicClassInfo[] preGetInitialMethodsToInstrument(RootClassLoadedCommand rootLoaded) {\n        //System.out.println(\"*** MS2: instr. initial\");\n        reflectInvokeInstrumented = true; // We don't need to instrument reflection specially in this mode\n\n        resetLoadedClassData();\n        storeClassFileBytesForCustomLoaderClasses(rootLoaded);\n        initInstrMethodData();\n\n        DynamicClassInfo[] loadedClassInfos;\n        String[] loadedClasses = rootLoaded.getAllLoadedClassNames();\n        int[] loadedClassLoaderIds = rootLoaded.getAllLoadedClassLoaderIds();\n        loadedClassInfos = new DynamicClassInfo[loadedClasses.length]; //EJB Work: removed the condition in the above line as we need to return the temp array anyway (used to check for multiple roots, see the overloaded getInitialMethodsToInstrument )\n\n        for (int i = 0; i < loadedClasses.length; i++) {\n            DynamicClassInfo clazz = javaClassForName(loadedClasses[i], loadedClassLoaderIds[i]);\n\n            if (clazz == null) {\n                // warning already issued in ClassRepository.lookupClass method, no need to do it again\n                continue;\n            }\n\n            clazz.setLoaded(true);\n            addToSubclassList(clazz, clazz); // Needed basically only for methods like implementsInterface() to work correctly\n            loadedClassInfos[i] = clazz;\n        }\n\n        return loadedClassInfos;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/RootMethods.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport java.util.ArrayList;\nimport java.util.List;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass RootMethods {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    // In case of multiple roots, here we have 1 to 1 correspondence between classNames, methodNames and methodSignatures\n    // E.g. we may have X,foo,() and X,bar,() as the respective elements of these three arrays.\n    String[] classNames;\n    boolean[] classesWildcard;\n    boolean[] markerMethods;\n    String[] methodNames;\n    String[] methodSignatures;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    RootMethods(ClientUtils.SourceCodeSelection[] roots) {\n        classNames = new String[roots.length];\n        methodNames = new String[roots.length];\n        methodSignatures = new String[roots.length];\n        classesWildcard = new boolean[roots.length];\n        markerMethods = new boolean[roots.length];\n\n        for (int i = 0; i < roots.length; i++) {\n            ClientUtils.SourceCodeSelection s = roots[i];\n\n            if (s.definedViaSourceLines()) {\n                classNames = new String[] { s.getClassName() };\n            } else if (s.definedViaMethodName()) {\n                // Convert all the class names into slash form\n                String rootName = classNames[i] = s.getClassName().replace('.', '/').intern(); // NOI18N\n                                                                                               //System.err.println(\"root rootName: \"+rootName);\n\n                if (Wildcards.isPackageWildcard(rootName)) {\n                    classesWildcard[i] = true;\n                    classNames[i] = Wildcards.unwildPackage(rootName);\n                    //System.err.println(\"Uses wildcard: \"+rootClasses[i]);\n                    // root method name and signature is not used in this case\n                } else {\n                    methodNames[i] = s.getMethodName().intern();\n                    methodSignatures[i] = s.getMethodSignature().intern();\n                    classesWildcard[i] = false;\n                }\n            } else { // The third case, when no root methods or code region is defined (\"Instrument all spawned threads\")\n                classNames = methodNames = methodSignatures = new String[0];\n            }\n\n            markerMethods[i] = s.isMarkerMethod();\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    List /*<String>*/ getRootClassNames() {\n        if (classNames.length > 0) {\n            List rootClasses = new ArrayList();\n\n            for (String className : classNames) {\n                String name = className.replace('/', '.'); // NOI18N;\n                if (!rootClasses.contains(name)) {\n                    rootClasses.add(name);\n                }\n            }\n\n            return rootClasses;\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/SingleMethodScaner.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassInfo;\n\n\n/**\n * Base class, containing functionality to scan bytecodes in a single method.\n *\n * @author Misha Dmitriev\n */\npublic class SingleMethodScaner implements JavaClassConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // The following array is re-used,to avoid excessive object allocations - which means that THIS CLASS IS NOT MULTITHREAD-SAFE!\n    private static byte[] reusableBytecodes = new byte[100];\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected ClassInfo clazz;\n    protected byte[] bytecodes; // Current updateable copy of bytecodes (what is in MethodInfo Code attribute between the code_length and the exception_table_length fields)\n    protected byte[] origMethodInfo;\n    protected int bytecodesLength;\n    protected int bytecodesStartIdx;\n    protected int methodIdx;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SingleMethodScaner() {\n    }\n\n    public SingleMethodScaner(ClassInfo clazz, int methodIdx) {\n        setClassAndMethod(clazz, methodIdx);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setClassAndMethod(ClassInfo clazz, int methodIdx) {\n        this.clazz = clazz;\n        this.methodIdx = methodIdx;\n        origMethodInfo = clazz.getMethodInfo(methodIdx);\n        bytecodesStartIdx = clazz.getMethodBytecodeOffsetInMethodInfo(methodIdx);\n        bytecodesLength = clazz.getMethodBytecodesLength(methodIdx);\n        initBytecodesArray();\n    }\n\n    protected static int getU2(byte[] buf, int pos) {\n        return ((buf[pos] & 0xFF) << 8) + (buf[pos + 1] & 0xFF);\n    }\n\n    protected static int getU4(byte[] buf, int pos) {\n        return ((buf[pos] & 0xFF) << 24) + ((buf[pos + 1] & 0xFF) << 16) + ((buf[pos + 2] & 0xFF) << 8) + (buf[pos + 3] & 0xFF);\n    }\n\n    protected static int align(int n) {\n        return (n + 3) & ~3;\n    }\n\n    protected int opcodeLength(int bci) {\n        int ret;\n        int opcode = bytecodes[bci] & 0xFF;\n\n        try {\n            ret = opc_length[opcode];\n        } catch (ArrayIndexOutOfBoundsException ex) {\n            System.err.println(\"*** JFluid warning: unknown opcode: \" + opcode + \" detected at offset \" + bci // NOI18N\n                               + \"in class/method \" + clazz.getName() + \".\" + clazz.getMethodName(methodIdx) // NOI18N\n                               + clazz.getMethodSignature(methodIdx));\n\n            ClassRewriter.saveToDisk(clazz.getName(), bytecodes);\n\n            return 1;\n        }\n\n        if (ret != 0) {\n            return ret;\n        }\n\n        if (opcode == opc_wide) {\n            opcode = bytecodes[bci + 1] & 0xFF;\n\n            if (((opcode >= opc_iload) && (opcode <= opc_aload)) || ((opcode >= opc_istore) && (opcode <= opc_astore))\n                    || (opcode == opc_ret)) {\n                return 4;\n            } else if (opcode == opc_iinc) {\n                return 6;\n            } else {\n                return 2;\n            }\n        } else {\n            int pad = align(bci + 1) - (bci + 1);\n\n            switch (opcode) {\n                case opc_tableswitch: {\n                    int lo = getInt(bci + 1 + pad + (4 * 1));\n                    int hi = getInt(bci + 1 + pad + (4 * 2));\n                    int n = hi - lo + 1;\n\n                    return 1 + pad + (4 * (3 + n));\n                }\n                case opc_lookupswitch: {\n                    int npairs = getInt(bci + 1 + pad + (4 * 1));\n\n                    return 1 + pad + (4 * (2 + (2 * npairs)));\n                }\n            }\n        }\n\n        System.err.println(\"*** Profiler Engine: error - should not reach here in opcodeLength()\"); // NOI18N\n\n        return 0;\n    }\n\n    protected static void putByte(byte[] buf, int pos, int value) {\n        buf[pos] = (byte) (value & 0xFF);\n    }\n\n    protected static void putU2(byte[] buf, int pos, int value) {\n        buf[pos] = (byte) ((value >> 8) & 0xFF);\n        buf[pos + 1] = (byte) (value & 0xFF);\n    }\n\n    protected static void putU4(byte[] buf, int pos, int value) {\n        buf[pos] = (byte) ((value >> 24) & 0xFF);\n        buf[pos + 1] = (byte) ((value >> 16) & 0xFF);\n        buf[pos + 2] = (byte) ((value >> 8) & 0xFF);\n        buf[pos + 3] = (byte) (value & 0xFF);\n    }\n\n    protected int getByte(int pos) {\n        return (bytecodes[pos] & 0xFF);\n    }\n\n    protected int getInt(int pos) {\n        return getU4(pos);\n    }\n\n    protected short getShort(int pos) {\n        return (short) (((bytecodes[pos] & 0xFF) << 8) + (bytecodes[pos + 1] & 0xFF));\n    }\n\n    protected int getU2(int pos) {\n        return ((bytecodes[pos] & 0xFF) << 8) + (bytecodes[pos + 1] & 0xFF);\n    }\n\n    protected int getU4(int pos) {\n        return ((bytecodes[pos] & 0xFF) << 24) + ((bytecodes[pos + 1] & 0xFF) << 16) + ((bytecodes[pos + 2] & 0xFF) << 8)\n               + (bytecodes[pos + 3] & 0xFF);\n    }\n\n    protected void initBytecodesArray() {\n        if (reusableBytecodes.length < (bytecodesLength * 8)) {\n            reusableBytecodes = new byte[bytecodesLength * 8];\n        }\n\n        System.arraycopy(origMethodInfo, bytecodesStartIdx, reusableBytecodes, 0, bytecodesLength);\n        bytecodes = reusableBytecodes;\n    }\n\n    protected void putInt(int pos, int value) {\n        putU4(pos, value);\n    }\n\n    protected void putShort(int pos, short value) {\n        bytecodes[pos] = (byte) ((value >> 8) & 0xFF);\n        bytecodes[pos + 1] = (byte) (value & 0xFF);\n    }\n\n    protected void putU4(int pos, int value) {\n        bytecodes[pos] = (byte) ((value >> 24) & 0xFF);\n        bytecodes[pos + 1] = (byte) ((value >> 16) & 0xFF);\n        bytecodes[pos + 2] = (byte) ((value >> 8) & 0xFF);\n        bytecodes[pos + 3] = (byte) (value & 0xFF);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/instrumentation/SpecialCallInjector.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.instrumentation;\n\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n\n/**\n * Specialized subclass of Injector, that provides special injection of java.lang.Method.invoke() and HttpServer.do*()\n * methods.\n *\n *  @author Tomas Hurka\n */\nabstract class SpecialCallInjector extends Injector implements CommonConstants {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    byte[] injectedCode;\n    int injectedCodeLen;\n    int injectedCodeMethodIdxPos;\n    int targetMethodIdx;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    SpecialCallInjector(DynamicClassInfo clazz, int baseCPoolCount, int methodIdx) {\n        super(clazz, methodIdx);\n        this.baseCPoolCount = baseCPoolCount;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public byte[] instrumentMethod() {\n        putU2(injectedCode, injectedCodeMethodIdxPos, targetMethodIdx);\n\n        injectCodeAndRewrite(injectedCode, injectedCodeLen, 0, true);\n\n        // Done very conservatively\n        maxStack += 1;\n\n        return createPackedMethodInfo();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/jps/JpsProxy.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.jps;\n\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport sun.jvmstat.monitor.*;\nimport java.lang.management.ManagementFactory;\nimport java.net.URISyntaxException;\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\n\n\n/**\n * This class is based on \"jvmps\" class from jvmps 2.0 written by Brian Doherty.\n * It provides functionality to identify all the JVMs currently running on the local machine.\n * Comments starting with //// are original comments from Brian.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class JpsProxy {\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /** Returns the array of records for all running VMs capable of dynamic attach (JDK 1.6 and newer)*/\n    public static RunningVM[] getRunningVMs() {\n        String hostname = null;\n        List vret = new ArrayList();\n\n        try {\n            HostIdentifier hostId = new HostIdentifier(hostname);\n            MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(hostId);\n            String selfName = ManagementFactory.getRuntimeMXBean().getName();\n\n            //// get the list active VMs on the specified host.\n            Set jvms = monitoredHost.activeVms();\n\n            if (jvms.isEmpty()) {\n                return null;\n            }\n\n            for (Iterator j = jvms.iterator(); j.hasNext();) {\n                int lvmid = ((Integer) j.next()).intValue();\n\n                if (selfName.startsWith(lvmid + \"@\")) { // myself\n\n                    continue;\n                }\n\n                VmIdentifier id = null;\n                MonitoredVm vm = null;\n                String uriString = \"//\" + lvmid + \"?mode=r\"; // NOI18N\n\n                try {\n                    id = new VmIdentifier(uriString);\n                    vm = monitoredHost.getMonitoredVm(id, 0);\n                } catch (URISyntaxException e) {\n                    //// this error should not occur as we are creating our own VMIdentifiers above based on a validated HostIdentifier.\n                    //// This would be an unexpected condition.\n                    MiscUtils.printWarningMessage(\"in jvmps, detected malformed VM Identifier: \" + uriString + \"; ignored\"); // NOI18N\n\n                    continue;\n                } catch (MonitorException e) {\n                    System.out.println(\"Ex \" + e.getMessage());\n                    e.printStackTrace();\n\n                    //// it's possible that from the time we acquired the list of available jvms that a jvm has terminated. Therefore, it is\n                    //// best just to ignore this error.\n                    continue;\n                } catch (Exception e) {\n                    //// certain types of errors, such as access acceptions, can be encountered when attaching to a jvm.\n                    //// These are reported as exceptions, not as some subclass of security exception.\n\n                    //// FIXME - we should probably have some provision for logging these types of errors, or possibly just print out the\n                    //// the Java Virtual Machine lvmid in a finally clause: System.out.println(String.valueOf(lvmid));\n                    MiscUtils.printWarningMessage(\"in jvmps, for VM = \" + String.valueOf(lvmid) + \" got exception: \" + e); // NOI18N\n\n                    continue;\n                }\n\n                if (!isAttachable(vm)) {\n                    monitoredHost.detach(vm);\n\n                    continue;\n                }\n\n                String cmdString = MonitoredVmUtil.commandLine(vm);\n                String mainClass = MonitoredVmUtil.mainClass(vm, true);\n                String mainArgs = MonitoredVmUtil.mainArgs(vm);\n                String vmArgs = MonitoredVmUtil.jvmArgs(vm);\n                String vmFlags = MonitoredVmUtil.jvmFlags(vm);\n\n                monitoredHost.detach(vm);\n\n                RunningVM rvm = new RunningVM(lvmid, vmFlags, vmArgs, mainClass, mainArgs);\n                vret.add(rvm);\n            }\n        } catch (MonitorException e) {\n            String report = \"in jvmps, got MonitorException\"; // NOI18N\n\n            if (e.getMessage() != null) {\n                report += (\" with message + \" + e.getMessage()); // NOI18N\n            }\n\n            MiscUtils.printWarningMessage(report);\n\n            return null;\n        } catch (URISyntaxException e) {\n            MiscUtils.printWarningMessage(\"in jvmps, got malformed Host Identifier: \" + hostname); // NOI18N\n\n            return null;\n        }\n\n        return (RunningVM[]) vret.toArray(new RunningVM[0]);\n    }\n\n    private static boolean isAttachable(MonitoredVm vm) {\n        try {\n            return MonitoredVmUtil.isAttachable(vm);\n        } catch (MonitorException ex) {\n            ex.printStackTrace();\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/jps/RunningVM.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.jps;\n\n\n/**\n * A container for various information available for a running JVM.\n * Note that \"VM flags\" that we have for the VM in principle, is various -XX:+... options, which are supposed to\n * be used only by real expert users, or for debugging. We have them here just for completeness, but since they\n * are used very rarely, there is probably no reason to display them in the attach dialog or whatever.\n *\n * @author Misha Dmitriev\n */\npublic class RunningVM {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private String mainArgs;\n    private String mainClass;\n    private String vmArgs;\n    private String vmFlags;\n    private int pid;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of RunningVM */\n    public RunningVM(int pid, String vmFlags, String vmArgs, String mainClass, String mainArgs) {\n        this.pid = pid;\n        this.vmFlags = vmFlags;\n        this.vmArgs = vmArgs;\n        this.mainClass = mainClass;\n        this.mainArgs = mainArgs;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getMainArgs() {\n        return mainArgs;\n    }\n\n    public String getMainClass() {\n        return mainClass;\n    }\n\n    public int getPid() {\n        return pid;\n    }\n\n    public String getVMArgs() {\n        return vmArgs;\n    }\n\n    public String getVMFlags() {\n        return vmFlags;\n    }\n\n    public String toString() {\n        return getPid() + \"  \" + getVMFlags() + \"  \" + getVMArgs() + \"  \" + getMainClass() + \"  \" + getMainArgs(); // NOI18N\n    }\n\n    public int hashCode() {\n        return toString().hashCode();\n    }\n    \n    public boolean equals(Object o) {\n        if (!(o instanceof RunningVM)) return false;\n        return toString().equals(o.toString());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/marker/ClassMarker.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.marker;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.marking.MarkMapping;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ClassMarker implements Marker {\n    private static Logger LOGGER = Logger.getLogger(ClassMarker.class.getName());\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Map markMap;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of ClassMarker */\n    public ClassMarker() {\n        markMap = new HashMap();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public MarkMapping[] getMappings() {\n        List mappings = new ArrayList();\n\n        for (Iterator iter = markMap.keySet().iterator(); iter.hasNext();) {\n            String className = (String) iter.next();\n            ClientUtils.SourceCodeSelection markerMethod = new ClientUtils.SourceCodeSelection(className, Wildcards.ALLWILDCARD,\n                                                                                               \"\"); // NOI18N\n            markerMethod.setMarkerMethod(true);\n            mappings.add(new MarkMapping(markerMethod, (Mark) markMap.get(className)));\n        }\n\n        return (MarkMapping[]) mappings.toArray(new MarkMapping[0]);\n    }\n\n    public Mark[] getMarks() {\n        return (Mark[])new HashSet(markMap.values()).toArray(new Mark[0]);\n    }\n\n    public void addClassMark(String className, Mark mark) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Marking class \" + className + \" with \" + mark.getId());\n        }\n\n        markMap.put(className, mark);\n    }\n\n    public void removeClassMark(String className) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Unmarking class \" + className);\n        }\n        markMap.remove(className);\n    }\n\n    public void resetClassMarks() {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Unmarking all classes\");\n        }\n        markMap.clear();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/marker/CompositeMarker.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.marker;\n\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.marking.MarkMapping;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.LinkedHashSet;\nimport java.util.Set;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class CompositeMarker implements Marker {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Set delegates;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of CompositeMarker */\n    public CompositeMarker() {\n        delegates = new LinkedHashSet();\n    }\n\n    public CompositeMarker(Set markerList) {\n        this();\n        delegates.addAll(markerList);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public MarkMapping[] getMappings() {\n        Set markerMethods = new HashSet();\n\n        for (Iterator iter = delegates.iterator(); iter.hasNext();) {\n            Marker delegate = (Marker) iter.next();\n            MarkMapping[] mMethods = delegate.getMappings();\n            markerMethods.addAll(Arrays.asList(mMethods));\n        }\n\n        return (MarkMapping[]) markerMethods.toArray(new MarkMapping[0]);\n    }\n\n    public Mark[] getMarks() {\n        Set allMarks = new HashSet();\n\n        for (Iterator iter = delegates.iterator(); iter.hasNext();) {\n            Marker delegate = (Marker) iter.next();\n            Mark[] marks = delegate.getMarks();\n            allMarks.addAll(Arrays.asList(marks));\n        }\n        return (Mark[]) allMarks.toArray(new Mark[0]);\n    }\n\n    public void addMarker(Marker marker) {\n        if (marker == null) {\n            return;\n        }\n\n        delegates.add(marker);\n    }\n\n    public void addMarkers(Collection markers) {\n        if (markers == null) {\n            return;\n        }\n\n        delegates.addAll(markers);\n    }\n\n    public void removeMarker(Marker marker) {\n        if (marker == null) {\n            return;\n        }\n\n        delegates.remove(marker);\n    }\n\n    public void removeMarkers(Collection markers) {\n        if (markers == null) {\n            return;\n        }\n\n        delegates.removeAll(markers);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/marker/Mark.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.marker;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class Mark implements Cloneable {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final short DEFAULT_ID = 0;\n    public static final char ID_NONE = (char) 0;\n    private static short counter = 1;\n    public static final Mark DEFAULT = new Mark(DEFAULT_ID);\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n    public final short id;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of Mark */\n    public Mark(short value) {\n        this.id = value;\n    }\n\n    public Mark() {\n        this.id = counter++;\n    }\n\n    public boolean isDefault() {\n        return this.equals(DEFAULT);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public short getId() {\n        return id;\n    }\n\n    public Object clone() throws CloneNotSupportedException {\n        return super.clone();\n    }\n\n    public boolean equals(Object other) {\n        if (other == null) {\n            return false;\n        }\n\n        if (!(other instanceof Mark)) {\n            return false;\n        }\n\n        return id == ((Mark) other).id;\n    }\n\n    public int hashCode() {\n        int hash = 5;\n        hash = 43 * hash + this.id;\n        return hash;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/marker/Marker.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.marker;\n\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.marking.MarkMapping;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface Marker {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final Marker DEFAULT = new Marker() {\n        public MarkMapping[] getMappings() {\n            return new MarkMapping[0];\n        }\n\n        public Mark[] getMarks() {\n            return new Mark[] { Mark.DEFAULT};\n        }\n    };\n\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    MarkMapping[] getMappings();\n    Mark[] getMarks();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/marker/MethodMarker.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.marker;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.marking.MarkMapping;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class MethodMarker implements Marker {\n    private static Logger LOGGER = Logger.getLogger(MethodMarker.class.getName());\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Map markMap;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of MethodMarker\n     */\n    public MethodMarker() {\n        markMap = new HashMap();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public MarkMapping[] getMappings() {\n        List mappings = new ArrayList();\n\n        for (Iterator iter = markMap.keySet().iterator(); iter.hasNext();) {\n            ClientUtils.SourceCodeSelection markerMethod = (ClientUtils.SourceCodeSelection) iter.next();\n            markerMethod.setMarkerMethod(true);\n            mappings.add(new MarkMapping(markerMethod, (Mark) markMap.get(markerMethod)));\n        }\n\n        return (MarkMapping[]) mappings.toArray(new MarkMapping[0]);\n    }\n\n    public Mark[] getMarks() {\n        return (Mark[])new HashSet(markMap.values()).toArray(new Mark[0]);\n    }\n\n    public void addMethodMark(String className, String methodName, String signature, Mark mark) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Marking method \" + className + \"#\" + methodName + \":\" + signature + \" with \" + mark.getId());\n        }\n        markMap.put(new ClientUtils.SourceCodeSelection(className, methodName, signature), mark);\n    }\n\n    public void removeMethodMark(String className, String methodName, String signature) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Unmarking method \" + className + \"#\" + methodName + \":\" + signature);\n        }\n        markMap.remove(new ClientUtils.SourceCodeSelection(className, methodName, signature));\n    }\n\n    public void resetMethodMarks() {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Unmarking all methods\");\n        }\n        markMap.clear();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/marker/PackageMarker.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.marker;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.marking.MarkMapping;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class PackageMarker implements Marker {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n    private static Logger LOGGER = Logger.getLogger(PackageMarker.class.getName());\n    private Map markMap;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of PackageMarker */\n    public PackageMarker() {\n        markMap = new HashMap();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public MarkMapping[] getMappings() {\n        List mappings = new ArrayList();\n\n        for (Iterator iter = markMap.keySet().iterator(); iter.hasNext();) {\n            String packageName = (String) iter.next();\n            ClientUtils.SourceCodeSelection markerMethod = new ClientUtils.SourceCodeSelection(packageName, \"\", \"\"); // NOI18N\n            markerMethod.setMarkerMethod(true);\n            mappings.add(new MarkMapping(markerMethod, (Mark) markMap.get(packageName)));\n        }\n\n        return (MarkMapping[]) mappings.toArray(new MarkMapping[0]);\n    }\n\n    public Mark[] getMarks() {\n        return (Mark[])new HashSet(markMap.values()).toArray(new Mark[0]);\n    }\n\n    public void addPackageMark(String packageName, Mark mark, boolean recursive) {\n        if (packageName.length() == 0) {\n            packageName = \"default\"; // NOI18N\n        }\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Marking package \" + packageName + \" with \" + mark.getId());\n        }\n        markMap.put(packageName + (recursive ? \".**\" : \".*\"), mark);\n    }\n\n    public void removePackageMark(String packageName) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Unmarking package \" + packageName);\n        }\n        markMap.remove(packageName);\n    }\n\n    public void resetPackageMarks() {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Unmarking all packages\");\n        }\n        markMap.clear();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/AbstractDataFrameProcessor.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport java.nio.ByteBuffer;\nimport java.util.Iterator;\nimport java.util.Set;\nimport java.util.concurrent.CopyOnWriteArraySet;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n * @author Tomas Hurka\n */\npublic abstract class AbstractDataFrameProcessor implements DataFrameProcessor {\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    protected static interface ListenerFunctor {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        void execute(ProfilingResultListener listener);\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    protected static final Logger LOGGER = Logger.getLogger(DataFrameProcessor.class.getName());\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected volatile ProfilerClient client = null;\n    protected volatile boolean collectingTwoTimeStamps;\n    private final Set listeners = new CopyOnWriteArraySet();\n\n    // @GuardedBy this\n    private boolean processorLives = false;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public boolean hasListeners() {\n        return !listeners.isEmpty();\n    }\n\n    public void processDataFrame(byte[] buffer) {\n        synchronized(client) {\n            synchronized (this) {\n                if (!processorLives) return;\n                try {\n                    fireBatchStart();\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Frame start, size=\"+buffer.length); // NOI18N\n                    }\n                    collectingTwoTimeStamps = (client != null) ? client.getStatus().collectingTwoTimeStamps() : false;\n                    doProcessDataFrame(ByteBuffer.wrap(buffer));\n                } catch (Throwable e) {\n                    LOGGER.log(Level.SEVERE, \"Error while processing data frame\", e); // NOI18N\n                } finally {\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Frame stop\"); // NOI18N\n                    }\n                    fireBatchStop();\n                }\n            }\n        }\n    }\n\n    public void removeAllListeners() {\n        for (Iterator iter = listeners.iterator(); iter.hasNext();) {\n            ((ProfilingResultListener) iter.next()).shutdown();\n        }\n        listeners.clear();\n    }\n\n    public void reset() {\n        fireReset();\n    }\n\n    public void shutdown() {\n        // finalize the batch\n        synchronized(this) {\n            processorLives = false;\n            fireShutdown();\n        }\n    }\n\n    public void startup(ProfilerClient client) {\n        synchronized(this) {\n            processorLives = true;\n            this.client = client;\n        }\n    }\n\n    protected void addListener(final ProfilingResultListener listener) {\n        listeners.add(listener);\n    }\n\n    protected abstract void doProcessDataFrame(ByteBuffer buffer);\n\n    protected static long getTimeStamp(ByteBuffer buffer) {\n        long timestamp = (((long) buffer.get() & 0xFF) << 48) | (((long) buffer.get() & 0xFF) << 40)\n                         | (((long) buffer.get() & 0xFF) << 32) | (((long) buffer.get() & 0xFF) << 24)\n                         | (((long) buffer.get() & 0xFF) << 16) | (((long) buffer.get() & 0xFF) << 8)\n                         | ((long) buffer.get() & 0xFF);\n        return timestamp;\n    }\n\n    protected static String getString(final ByteBuffer buffer) {\n        int strLen = buffer.getChar();\n        byte[] str = new byte[strLen];\n        \n        buffer.get(str);\n        return new String(str);\n    }\n\n    protected void fireProfilingPoint(final int threadId, final int ppId, final long timeStamp) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    listener.profilingPoint(threadId, ppId, timeStamp);\n                }\n            });\n    }\n\n    protected void fireReset() {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    listener.reset();\n                }\n            });\n    }\n\n    protected void foreachListener(ListenerFunctor functor) {\n        for (Iterator iter = listeners.iterator(); iter.hasNext();) {\n            functor.execute((ProfilingResultListener) iter.next());\n        }\n    }\n\n    protected void removeListener(final ProfilingResultListener listener) {\n        if (listeners.remove(listener)) {\n            listener.shutdown();\n        }\n    }\n\n    private void fireBatchStart() {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    listener.onBatchStart();\n                }\n            });\n    }\n\n    private void fireBatchStop() {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    listener.onBatchStop();\n                }\n            });\n    }\n\n    private void fireShutdown() {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    listener.shutdown();\n                }\n            });\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/BaseCallGraphBuilder.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport java.lang.ref.WeakReference;\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.concurrent.CopyOnWriteArraySet;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic abstract class BaseCallGraphBuilder implements ProfilingResultListener, CCTProvider {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    protected static final Logger LOGGER = Logger.getLogger(BaseCallGraphBuilder.class.getName());\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected List /*<Runnable>*/ afterBatchCommands = new ArrayList /*<Runnable>*/();\n    protected ProfilingSessionStatus status;\n    protected final Set cctListeners = new CopyOnWriteArraySet();\n    protected WeakReference clientRef;\n    protected boolean batchNotEmpty = false;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of BaseCallGraphBuilder */\n    public BaseCallGraphBuilder() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void addListener(CCTProvider.Listener listener) {\n        cctListeners.add(listener);\n    }\n\n    public void onBatchStart() {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Starting batch\"); // NOI18N\n        }\n\n        afterBatchCommands.clear();\n        batchNotEmpty = false;\n        doBatchStart();\n    }\n\n    public void onBatchStop() {\n        doBatchStop();\n\n        if (batchNotEmpty) {\n            fireCCTEstablished(false);\n        } else {\n            fireCCTEstablished(true);\n        }\n\n        if (!afterBatchCommands.isEmpty()) {\n            for (Iterator iter = afterBatchCommands.iterator(); iter.hasNext();) {\n                ((Runnable) iter.next()).run();\n            }\n\n            afterBatchCommands.clear();\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Finishing batch\"); // NOI18N\n        }\n    }\n\n    public void removeAllListeners() {\n        cctListeners.clear();\n    }\n\n    public void removeListener(CCTProvider.Listener listener) {\n        cctListeners.remove(listener);\n    }\n\n    public void reset() {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Resetting CallGraphBuilder\"); // NOI18N\n        }\n\n        try {\n            doReset();\n            fireCCTReset();\n        } catch (Exception e) {\n            LOGGER.severe(e.getMessage());\n        }\n    }\n\n    public void shutdown() {\n        status = null;\n        afterBatchCommands.clear();\n        doShutdown();\n    }\n\n    public void startup(ProfilerClient profilerClient) {\n        status = profilerClient.getStatus();\n        clientRef = new WeakReference(profilerClient);\n        doStartup(profilerClient);\n    }\n\n    protected abstract RuntimeCCTNode getAppRootNode();\n\n    protected abstract void doBatchStart();\n\n    protected abstract void doBatchStop();\n\n    protected abstract void doReset();\n\n    protected abstract void doShutdown();\n\n    protected abstract void doStartup(ProfilerClient profilerClient);\n\n    protected ProfilerClient getClient() {\n        if (clientRef == null) {\n            return null;\n        }\n\n        return (ProfilerClient) clientRef.get();\n    }\n\n    private void fireCCTEstablished(boolean empty) {\n        RuntimeCCTNode appNode = getAppRootNode();\n\n        if (appNode == null) {\n            return;\n        }\n\n        for (Iterator iter = cctListeners.iterator(); iter.hasNext();) {\n            ((CCTProvider.Listener) iter.next()).cctEstablished(appNode, empty);\n        }\n    }\n\n    private void fireCCTReset() {\n        for (Iterator iter = cctListeners.iterator(); iter.hasNext();) {\n            ((CCTProvider.Listener) iter.next()).cctReset();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nFilteringSupport_FilteredOutLbl=Filtered out\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/CCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport javax.swing.tree.TreeNode;\n\n\n/**\n * This interface must be implemented by every CCT node.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class CCTNode implements TreeNode {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public abstract CCTNode getChild(int index);\n\n    public abstract CCTNode[] getChildren();\n\n    public abstract int getIndexOfChild(Object child);\n\n    public abstract int getNChildren();\n\n    public abstract CCTNode getParent();\n\n    //public boolean hasChildren();\n\n\n    // --- Filtering support ---\n\n    private boolean filtered;\n\n    public CCTNode createFilteredNode() { return null; }\n\n    protected void setFilteredNode() { filtered = true; }\n\n    public boolean isFiltered() { return filtered; }\n\n    public void merge(CCTNode node) {}\n\n    // ---\n\n\n    //--- TreeNode adapter ---\n    public Enumeration<CCTNode> children() {\n        final CCTNode[] _children = getChildren();\n        final int _childrenCount = _children == null ? 0 : _children.length;\n\n        if (_childrenCount == 0) return Collections.emptyEnumeration();\n\n        return new Enumeration<CCTNode>() {\n            private int index = 0;\n            public boolean hasMoreElements() { return index < _childrenCount; }\n            public CCTNode nextElement()     { return _children[index++]; }\n        };\n    }\n\n    public boolean isLeaf() {\n        return getChildCount() == 0;\n    }\n\n    public boolean getAllowsChildren() {\n        return true;\n    }\n\n    public int getIndex(TreeNode node) {\n        return getIndexOfChild(node);\n    }\n\n    public int getChildCount() {\n        return getNChildren();\n    }\n    \n    public TreeNode getChildAt(int index) {\n        return getChild(index);\n    }\n    //---\n    \n    \n    public static interface FixedPosition {}\n    \n    public static interface AlwaysFirst extends FixedPosition {}\n    \n    public static interface AlwaysLast extends FixedPosition {}\n    \n    public static interface DoNotSortChildren {}\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/CCTProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface CCTProvider {\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    public static interface Listener {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        /* void cctEstablished(RuntimeCCTNode appRootNode);\n         *\n         * in order to fix the issue #114638 i need to introduce the \"empty\" flag\n         * it should be removed once this code is cleaned up\n         */\n        void cctEstablished(RuntimeCCTNode appRootNode, boolean empty);\n\n        void cctReset();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    void addListener(Listener listener);\n\n    void removeAllListeners();\n\n    void removeListener(Listener listener);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/DataFrameProcessor.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface DataFrameProcessor {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    boolean hasListeners();\n\n    void processDataFrame(byte[] buffer);\n\n    void reset();\n\n    void shutdown();\n\n    void startup(ProfilerClient client);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/DataManager.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Set;\n\n/**\n * A common functionality for DataManagers\n *\n * @author Ian Formanek\n */\npublic abstract class DataManager {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final Set listeners = new HashSet();\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    // --- Listeners ---------------------------------------------------------------\n\n    /**\n     * Adds new threadData Listener.\n     *\n     * @param listener threadData listener to add\n     */\n    public void addDataListener(DataManagerListener listener) {\n        listeners.add(listener);\n    }\n\n    /**\n     * Removes threadData listener.\n     *\n     * @param listener threadData listener to remove\n     */\n    public void removeDataListener(DataManagerListener listener) {\n        listeners.remove(listener);\n    }\n\n    /**\n     * Notifies all listeners about the threadData change.\n     */\n    protected void fireDataChanged() {\n        if (listeners.isEmpty()) {\n            return;\n        }\n\n        Set toNotify;\n\n        synchronized (listeners) {\n            toNotify = new HashSet(listeners);\n        }\n\n        Iterator iterator = toNotify.iterator();\n\n        while (iterator.hasNext()) {\n            final DataManagerListener listener = ((DataManagerListener) iterator.next());\n            listener.dataChanged();\n        }\n    }\n\n    /**\n     * Notifies all listeners about the reset of threads data.\n     */\n    protected void fireDataReset() {\n        if (listeners.isEmpty()) {\n            return;\n        }\n\n        Set toNotify;\n\n        synchronized (listeners) {\n            toNotify = new HashSet(listeners);\n        }\n\n        Iterator iterator = toNotify.iterator();\n\n        while (iterator.hasNext()) {\n            final DataManagerListener listener = ((DataManagerListener) iterator.next());\n            listener.dataReset();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/DataManagerListener.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\n\n/**\n * A listener for data managers, that allows to be notified about data changes.\n *\n * @author Jiri Sedlacek\n * @author Ian Formanek\n */\npublic interface DataManagerListener {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Called when the data managed by the manager change\n     */\n    void dataChanged();\n\n    /**\n     * Called when the data managed by the manager reset (e.g. when a new session is started)\n     */\n    void dataReset();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/EventBufferProcessor.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport java.nio.MappedByteBuffer;\nimport java.nio.channels.FileChannel;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.EventBufferDumpedCommand;\n\n\n/**\n * Management of the shared-memory \"event buffer\" file, into which TA instrumentation writes rough profiling\n * data, and which is processed here at the client side.\n * So far it's deliberately allstatic. Can be made more object-style, but before doing that, check its current\n * usage in ProfilerClient and, as a superclass, in CPUCallGraphBuilder etc.\n *\n * @author Misha Dmitirev\n * @author Tomas Hurka\n */\npublic class EventBufferProcessor implements CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    protected static ProfilingSessionStatus status;\n    protected static ProfilerClient profilerClient;\n    protected static MappedByteBuffer mapByteBuf;\n    protected static File bufFile;\n    protected static RandomAccessFile raFile;\n    protected static FileChannel bufFileChannel;\n    protected static boolean bufFileExists;\n    protected static long startDataProcessingTime;\n    protected static long dataProcessingTime;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * For statistics only\n     */\n    public static long getDataProcessingTime() {\n        return dataProcessingTime;\n    }\n\n    public static boolean setEventBufferFile(String fileName) {\n        if ((status != null) && status.remoteProfiling) {\n            return true;\n        }\n\n        if (bufFile != null) {\n            removeEventBufferFile();\n        }\n\n        try {\n            bufFile = new File(fileName);\n            raFile = new RandomAccessFile(bufFile, \"rw\"); // NOI18N\n            bufFileChannel = raFile.getChannel();\n            mapByteBuf = bufFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, EVENT_BUFFER_SIZE_IN_BYTES);\n            mapByteBuf.rewind();\n            mapByteBuf.mark();\n            bufFileExists = true;\n        } catch (FileNotFoundException ex1) {\n            return false;\n        } catch (IOException ex2) {\n            ProfilerLogger.severe(\"internal error when opening memory-mapped temporary file\"); // NOI18N\n            ProfilerLogger.log(ex2);\n            ProfilerLogger.severe(PLEASE_REPORT_PROBLEM);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    public static boolean bufFileExists() {\n        return bufFileExists;\n    }\n\n    public static void initialize(ProfilerClient inProfilerClient) {\n        profilerClient = inProfilerClient;\n        status = profilerClient.getStatus();\n    }\n\n    public static synchronized byte[] readDataAndPrepareForProcessing(EventBufferDumpedCommand cmd) {\n        byte[] buf;\n        if (!status.remoteProfiling) {\n            int bufSizeInBytes = cmd.getBufSize();\n            buf = new byte[bufSizeInBytes];\n            mapByteBuf.reset();\n            mapByteBuf.get(buf, 0, bufSizeInBytes);\n        } else {\n            buf = cmd.getBuffer();\n            assert buf != null;\n            assert buf.length == cmd.getBufSize();\n        }\n        startDataProcessingTime = System.currentTimeMillis();\n        return buf;\n    }\n\n    public static void removeEventBufferFile() {\n        if ((status != null) && status.remoteProfiling) {\n            return; // This may be called \"uniformly\" even during monitoring, when status isn't initialized\n        }\n\n        try {\n            if (bufFile != null) {\n                mapByteBuf = null;\n\n                if (bufFileChannel != null) {\n                    bufFileChannel.close(); // bufFileChannel can accidentally be null, if previous connection didn't quite succeed\n                }\n\n                if (raFile != null) {\n                    raFile.close();\n                }\n\n                System.gc(); // Stupid - but that's the only way to GC mapBuf and thus to enable the buffer file deletion...\n                             // Now try to remove the buffer file. If this doesn't happen immediately, try again - it may be that the\n                             // target VM has not yet freed this file on its side. Repeat attempts for 2 seconds.\n\n                for (int i = 0; i < 20; i++) {\n                    if (bufFile.delete()) {\n                        bufFile = null;\n                        bufFileExists = false;\n\n                        return;\n                    } else {\n                        try {\n                            Thread.sleep(100);\n                        } catch (InterruptedException e) {\n                        }\n                    }\n                }\n            }\n        } catch (IOException ex) {\n            ProfilerLogger.severe(\"internal error when closing memory-mapped temporary file\"); // NOI18N\n            ProfilerLogger.severe(PLEASE_REPORT_PROBLEM);\n        } finally {\n            bufFileExists = false;\n        }\n    }\n\n    public static void reset() {\n        dataProcessingTime = 0;\n\n        // buf = null; // to cleanup memory allocated for the buffer - we cannot do this here, there may be events in the\n        // buffer that are still unprocessed and the EventBufferProcessor in the cycle of processing it\n        // see http://profiler.netbeans.org/issues/show_bug.cgi?id=69275\n    }\n\n    protected static synchronized void completeDataProcessing() {\n        dataProcessingTime += (System.currentTimeMillis() - startDataProcessingTime);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/EventBufferResultsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class EventBufferResultsProvider implements ProfilingResultsProvider {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Logger LOGGER = Logger.getLogger(EventBufferResultsProvider.class.getName());\n    private static final EventBufferResultsProvider instance = new EventBufferResultsProvider();\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final Set listeners = Collections.synchronizedSet(new HashSet());\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of RawProfilingResultsCollector */\n    private EventBufferResultsProvider() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static EventBufferResultsProvider getDefault() {\n        return instance;\n    }\n\n    public void addDispatcher(ProfilingResultsProvider.Dispatcher dispatcher) {\n        listeners.add(dispatcher);\n    }\n\n    public void dataReady(final byte[] buf, int instrumentationType) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Profiling data ready \"+buf.length); // NOI18N\n        }\n        fireProcessData(buf, instrumentationType);\n    }\n\n    public void removeDispatcher(ProfilingResultsProvider.Dispatcher dispatcher) {\n        listeners.remove(dispatcher);\n    }\n\n    public void shutdown() {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Shutting down profiler\"); // NOI18N\n        }\n\n        fireShutdown();\n    }\n\n    public void startup(ProfilerClient client) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Starting up profiler\"); // NOI18N\n        }\n\n        fireStartup(client);\n    }\n\n    private void fireProcessData(final byte[] data, final int instrumentationType) {\n        for (Iterator iter = listeners.iterator(); iter.hasNext();) {\n            ProfilingResultsProvider.Dispatcher dispatcher = (ProfilingResultsProvider.Dispatcher) iter.next();\n            dispatcher.dataFrameReceived(data, instrumentationType);\n        }\n    }\n\n    private void fireShutdown() {\n        for (Iterator iter = listeners.iterator(); iter.hasNext();) {\n            ProfilingResultsProvider.Dispatcher dispatcher = (ProfilingResultsProvider.Dispatcher) iter.next();\n            dispatcher.shutdown();\n        }\n    }\n\n    private void fireStartup(ProfilerClient client) {\n        for (Iterator iter = listeners.iterator(); iter.hasNext();) {\n            ProfilingResultsProvider.Dispatcher dispatcher = (ProfilingResultsProvider.Dispatcher) iter.next();\n            dispatcher.startup(client);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/ExportDataDumper.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport java.io.BufferedOutputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStreamWriter;\nimport java.io.UnsupportedEncodingException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n\n/**\n * An instance of this class is passed to code that generates text representation of profiling\n * results for export. It is intended that the text generating code periodically checks the size\n * of the StringBuffer it uses for storage, and if it's above some critical value, dumps it using\n * the code below. If there is an error during this process, it is not returned immediately to avoid\n * making text generator code too complex - instead the caller can eventually retrieve the error\n * using the getCaughtException() method.\n *\n * @author Misha Dmitriev\n * @author Petr Cyhelsky\n */\npublic class ExportDataDumper {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int BUFFER_SIZE = 32000; //roughly 32 kB buffer\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    OutputStreamWriter osw;\n    BufferedOutputStream bos;\n    IOException caughtEx;\n    int numExceptions=0;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ExportDataDumper(FileOutputStream fw) {\n        bos = new BufferedOutputStream(fw, BUFFER_SIZE);\n        try {\n            osw = new OutputStreamWriter(bos, \"UTF-8\");\n        } catch (UnsupportedEncodingException ex) {\n            numExceptions++;\n            Logger.getLogger(ExportDataDumper.class.getName()).log(Level.SEVERE, null, ex);\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public IOException getCaughtException() {\n        return caughtEx;\n    }\n\n    public int getNumExceptions() {\n        return numExceptions;\n    }\n    \n    public void dumpByte(byte b) {\n        if (caughtEx != null) {\n            return;\n        }\n\n        try {\n            bos.write(b);\n        } catch (IOException ex) {\n            caughtEx = ex;\n            System.out.println(b);\n            numExceptions++;\n            System.err.println(ex.getMessage());\n        }\n    }\n\n    public void dumpData(CharSequence s) {\n        if (caughtEx != null) {\n            return;\n        }\n\n        try {\n            if (s!=null) osw.append(s);\n        } catch (IOException ex) {\n            caughtEx = ex;\n            System.out.println(s);\n            numExceptions++;\n            System.err.println(ex.getMessage());\n        }\n    }\n\n    public void close() {\n        try {\n            osw.close();\n            bos.close();\n        } catch (IOException ex) {\n            caughtEx = ex;\n            System.err.println(ex.getMessage());\n        }\n    }\n\n    public void dumpDataAndClose(StringBuffer s) {\n        dumpData(s);\n        close();\n    }\n\n    public BufferedOutputStream getOutputStream() {\n        return bos;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/FilterSortSupport.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport java.util.ResourceBundle;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class FilterSortSupport implements CommonConstants {\n\n    public static final String FILTERED_OUT_LBL;\n\n    static {\n        ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.Bundle\"); // NOI18N\n        FILTERED_OUT_LBL = messages.getString(\"FilteringSupport_FilteredOutLbl\"); //NOI18N\n    }\n\n    public static boolean passesFilter(Configuration info, String nodeName) {\n        return passesFilter(info.getFilterString(), info.getFilterType(), nodeName);\n    }\n\n    public static boolean passesFilter(String filter, int filterType, String nodeName) {\n        switch (filterType) {\n            case FILTER_NONE:\n                return true;\n            case FILTER_CONTAINS:\n                return nodeName.toLowerCase().contains(filter);\n            case FILTER_NOT_CONTAINS:\n                return !nodeName.toLowerCase().contains(filter);\n            case FILTER_REGEXP:\n                try {\n                    return nodeName.matches(filter); // case sensitive!\n                } catch (java.util.regex.PatternSyntaxException e) {\n                    return false;\n                }\n        }\n        return false;\n    }\n\n\n    public static final class Configuration {\n\n        private int sortBy;\n        private boolean sortOrder;\n        private String filterString = \"\"; // NOI18N\n        private int filterType = CommonConstants.FILTER_CONTAINS;\n\n\n        public int getSortBy() {\n            return sortBy;\n        }\n\n        public boolean getSortOrder() {\n            return sortOrder;\n        }\n\n        public String getFilterString() {\n            return filterString;\n        }\n\n        public int getFilterType() {\n           return filterType;\n        }\n        \n        \n        public void setSortInfo(int sortBy, boolean sortOrder) {\n            this.sortBy = sortBy;\n            this.sortOrder = sortOrder;\n        }\n        \n        public void setFilterInfo(String filterString, int filterType) {\n            this.filterString = filterString;\n            this.filterType = filterType;\n        }\n        \n    }\n   \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/ProfilingResultListener.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface ProfilingResultListener {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    void onBatchStart();\n\n    void onBatchStop();\n\n    void profilingPoint(int threadId, int ppId, long timeStamp);\n\n    void reset();\n\n    void shutdown();\n\n    void startup(ProfilerClient profilerClient);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/ProfilingResultsDispatcher.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUDataFrameProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUProfilingResultListener;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUSamplingDataFrameProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.locks.LockDataFrameProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.locks.LockProfilingResultListener;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryDataFrameProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryProfilingResultsListener;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n * @author Tomas Hurka\n */\npublic final class ProfilingResultsDispatcher implements ProfilingResultsProvider.Dispatcher {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Logger LOGGER = Logger.getLogger(ProfilingResultsDispatcher.class.getName());\n    private static final int QLengthLowerBound = 13;\n    private static final int QLengthUpperBound = 15;\n    private static ProfilingResultsDispatcher instance;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final AbstractDataFrameProcessor cpuDataProcessor = new CPUDataFrameProcessor();\n    private final AbstractDataFrameProcessor cpuSamplingDataProcessor = new CPUSamplingDataFrameProcessor();\n    private final AbstractDataFrameProcessor memoryDataProcessor = new MemoryDataFrameProcessor();\n    private final AbstractDataFrameProcessor lockDataProcessor = new LockDataFrameProcessor();\n    private final Object cpuDataProcessorQLengthLock = new Object();\n    private final Object memDataProcessorQLengthLock = new Object();\n    private final Object lockDataProcessorQLengthLock = new Object();\n    private ExecutorService queueProcessor;\n    private volatile boolean pauseFlag = true;\n\n    // @GuardedBy cpuDataProcessorQLengthLock\n    private int cpuDataProcessorQLength = 0;\n\n    // @GuardedBy memDataProcessorQLengthLock\n    private int memDataProcessorQLength = 0;\n\n    // @GuardedBy lockDataProcessorQLengthLock\n    private int lockDataProcessorQLength = 0;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static synchronized ProfilingResultsDispatcher getDefault() {\n        if (instance == null) {\n            instance = new ProfilingResultsDispatcher();\n        }\n\n        return instance;\n    }\n\n    public void addListener(final CPUProfilingResultListener listener) {\n        cpuDataProcessor.addListener(listener);\n        cpuSamplingDataProcessor.addListener(listener);\n    }\n\n    public void addListener(final MemoryProfilingResultsListener listener) {\n        memoryDataProcessor.addListener(listener);\n    }\n\n    public void addListener(final LockProfilingResultListener listener) {\n        lockDataProcessor.addListener(listener);\n    }\n\n    public synchronized void dataFrameReceived(final byte[] buffer, final int instrumentationType) {\n        if (!cpuDataProcessor.hasListeners() && !memoryDataProcessor.hasListeners() &&\n            !cpuSamplingDataProcessor.hasListeners() && !lockDataProcessor.hasListeners()) {\n            return; // no consumers\n        }\n\n        switch (instrumentationType) {\n            case CommonConstants.INSTR_RECURSIVE_FULL:\n            case CommonConstants.INSTR_RECURSIVE_SAMPLED: {\n                synchronized (cpuDataProcessorQLengthLock) {\n                    cpuDataProcessorQLength++;\n\n                    if (cpuDataProcessorQLength > QLengthUpperBound) {\n                        try {\n                            cpuDataProcessorQLengthLock.wait();\n                        } catch (InterruptedException e) {\n                            Thread.currentThread().interrupt();\n                        }\n                    }\n\n                    getExecutor().submit(new Runnable() {\n                            public void run() {\n                                try {\n                                    cpuDataProcessor.processDataFrame(buffer);\n                                } finally {\n                                    synchronized (cpuDataProcessorQLengthLock) {\n                                        cpuDataProcessorQLength--;\n\n                                        if (cpuDataProcessorQLength < QLengthLowerBound) {\n                                            cpuDataProcessorQLengthLock.notifyAll();\n                                        }\n                                    }\n                                }\n                            }\n                        });\n                }\n\n                break;\n            }\n            case CommonConstants.INSTR_OBJECT_ALLOCATIONS:\n            case CommonConstants.INSTR_OBJECT_LIVENESS: {\n                synchronized (memDataProcessorQLengthLock) {\n                    memDataProcessorQLength++;\n\n                    if (memDataProcessorQLength > QLengthUpperBound) {\n                        try {\n                            memDataProcessorQLengthLock.wait();\n                        } catch (InterruptedException e) {\n                            Thread.currentThread().interrupt();\n                        }\n                    }\n\n                    getExecutor().submit(new Runnable() {\n                            public void run() {\n                                try {\n                                    memoryDataProcessor.processDataFrame(buffer);\n                                } finally {\n                                    synchronized (memDataProcessorQLengthLock) {\n                                        memDataProcessorQLength--;\n\n                                        if (memDataProcessorQLength < QLengthLowerBound) {\n                                            memDataProcessorQLengthLock.notifyAll();\n                                        }\n                                    }\n                                }\n                            }\n                        });\n                }\n\n                break;\n            }\n            case CommonConstants.INSTR_NONE_SAMPLING: {\n                synchronized (cpuDataProcessorQLengthLock) {\n                    cpuDataProcessorQLength++;\n\n                    if (cpuDataProcessorQLength > QLengthUpperBound) {\n                        try {\n                            cpuDataProcessorQLengthLock.wait();\n                        } catch (InterruptedException e) {\n                            Thread.currentThread().interrupt();\n                        }\n                    }\n\n                    getExecutor().submit(new Runnable() {\n                            public void run() {\n                                try {\n                                    cpuSamplingDataProcessor.processDataFrame(buffer);\n                                } finally {\n                                    synchronized (cpuDataProcessorQLengthLock) {\n                                        cpuDataProcessorQLength--;\n\n                                        if (cpuDataProcessorQLength < QLengthLowerBound) {\n                                            cpuDataProcessorQLengthLock.notifyAll();\n                                        }\n                                    }\n                                }\n                            }\n                        });\n                }\n\n                break;\n            }                \n            default: {\n                synchronized (lockDataProcessorQLengthLock) {\n                    lockDataProcessorQLength++;\n\n                    if (lockDataProcessorQLength > QLengthUpperBound) {\n                        try {\n                            lockDataProcessorQLengthLock.wait();\n                        } catch (InterruptedException e) {\n                            Thread.currentThread().interrupt();\n                        }\n                    }\n\n                    getExecutor().submit(new Runnable() {\n                            public void run() {\n                                try {\n                                    lockDataProcessor.processDataFrame(buffer);\n                                } finally {\n                                    synchronized (lockDataProcessorQLengthLock) {\n                                        lockDataProcessorQLength--;\n\n                                        if (lockDataProcessorQLength < QLengthLowerBound) {\n                                            lockDataProcessorQLengthLock.notifyAll();\n                                        }\n                                    }\n                                }\n                            }\n                        });\n                }\n            }\n        }\n    }\n\n    public void pause(boolean flush) {\n        pauseFlag = true;\n    }\n\n    public void removeAllListeners() {\n        cpuDataProcessor.removeAllListeners();\n        cpuSamplingDataProcessor.removeAllListeners();\n        memoryDataProcessor.removeAllListeners();\n        lockDataProcessor.removeAllListeners();\n    }\n\n    public void removeListener(final CPUProfilingResultListener listener) {\n        cpuDataProcessor.removeListener(listener);\n        cpuSamplingDataProcessor.removeListener(listener);\n    }\n\n    public void removeListener(final MemoryProfilingResultsListener listener) {\n        memoryDataProcessor.removeListener(listener);\n    }\n\n    public void removeListener(final LockProfilingResultListener listener) {\n        lockDataProcessor.removeListener(listener);\n    }\n\n    public void reset() {\n        fireReset();\n    }\n\n    public void resume() {\n        pauseFlag = false;\n    }\n\n    public synchronized void shutdown() {\n        //    queueProcessor.shutdownNow();\n        fireShutdown(); // signalize shutdown\n        removeAllListeners();\n    }\n\n    public synchronized void startup(ProfilerClient client) {\n        fireStartup(client);\n        resume();\n    }\n\n    private synchronized ExecutorService getExecutor() {\n        if (queueProcessor == null) {\n            queueProcessor = Executors.newSingleThreadExecutor();\n        }\n\n        return queueProcessor;\n    }\n\n    private synchronized void fireReset() {\n        cpuDataProcessor.reset();\n        cpuSamplingDataProcessor.reset();\n        memoryDataProcessor.reset();\n        lockDataProcessor.reset();\n    }\n\n    private synchronized void fireShutdown() {\n        cpuDataProcessor.shutdown();\n        cpuSamplingDataProcessor.shutdown();\n        memoryDataProcessor.shutdown();\n        lockDataProcessor.shutdown();\n    }\n\n    private synchronized void fireStartup(ProfilerClient client) {\n        cpuSamplingDataProcessor.startup(client);\n        cpuDataProcessor.startup(client);\n        memoryDataProcessor.startup(client);\n        lockDataProcessor.startup(client);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/ProfilingResultsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface ProfilingResultsProvider {\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    public interface Dispatcher {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        /**\n         * Called when a new pack of data is received from the server\n         * @param buffer The data received. MUST be treated as IMMUTABLE\n         */\n        void dataFrameReceived(final byte[] buffer, final int instrumentationType);\n\n        void pause(boolean flush);\n\n        void reset();\n\n        void resume();\n\n        void shutdown();\n\n        void startup(ProfilerClient client);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    void addDispatcher(ProfilingResultsProvider.Dispatcher dispatcher);\n\n    void dataReady(final byte[] buffer, int instrumentationType);\n\n    void removeDispatcher(ProfilingResultsProvider.Dispatcher dispatcher);\n\n    void shutdown();\n\n    void startup(ProfilerClient client);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/ResultsSnapshot.java",
    "content": "/*\n * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.util.Date;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n\n/**\n * Root superclass for various types of profiling results snapshots\n */\npublic class ResultsSnapshot {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    protected static final Logger LOGGER = Logger.getLogger(ResultsSnapshot.class.getName());\n    private static final int SNAPSHOT_VERSION = 1;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    //  protected static final boolean DEBUG = System.getProperty(\"org.graalvm.visualvm.lib.jfluid.results.ResultsSnapshot\") != null; // NOI18N // TODO [release] set to TRUE at release\n    protected long beginTime;\n    protected long timeTaken;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ResultsSnapshot() {\n    } // for externalization\n\n    protected ResultsSnapshot(long beginTime, long timeTaken) {\n        this.beginTime = beginTime;\n        this.timeTaken = timeTaken;\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            debugValues();\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public long getBeginTime() {\n        return beginTime;\n    }\n\n    public long getTimeTaken() {\n        return timeTaken;\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        int version = in.readInt();\n\n        if (version != SNAPSHOT_VERSION) {\n            throw new IOException(\"Stored version not supported: \" + version); // NOI18N\n        }\n\n        beginTime = in.readLong();\n        timeTaken = in.readLong();\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            debugValues();\n        }\n    }\n\n    public String toString() {\n        return StringUtils.formatUserDate(new Date(timeTaken));\n    }\n\n    public void writeToStream(DataOutputStream out) throws IOException {\n        out.writeInt(SNAPSHOT_VERSION);\n        out.writeLong(beginTime);\n        out.writeLong(timeTaken);\n    }\n\n    protected String debugLength(Object array) {\n        if (array == null) {\n            return \"null\"; // NOI18N\n        } else if (array instanceof int[]) {\n            return \"\" + ((int[]) array).length; // NOI18N\n        } else if (array instanceof long[]) {\n            return \"\" + ((long[]) array).length; // NOI18N\n        } else if (array instanceof float[]) {\n            return \"\" + ((float[]) array).length; // NOI18N\n        } else if (array instanceof Object[]) {\n            return \"\" + ((Object[]) array).length; // NOI18N\n        } else {\n            return \"Unknown\"; // NOI18N\n        }\n    }\n\n    private void debugValues() {\n        LOGGER.finest(\"beginTime: \" + beginTime); // NOI18N\n        LOGGER.finest(\"timeTaken: \" + timeTaken); // NOI18N\n    }\n\n    // used by LoadedSnapshot when loading from file\n    public void setProfilerSettings(ProfilerEngineSettings pes) {\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/RuntimeCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results;\n\n\n/**\n * Marking interface\n * @author Jaroslav Bachorik\n */\npublic interface RuntimeCCTNode {\n    RuntimeCCTNode[] getChildren();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/RuntimeCCTNodeProcessor.java",
    "content": "/*\n * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results;\n\nimport java.util.ArrayDeque;\nimport java.util.Deque;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MarkedCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MethodCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.ServletRequestCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.SimpleCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.ThreadCPUCCTNode;\n\n/**\n * Provides a pluggable implementation of {@linkplain RuntimeCCTNode} hierarchy traversal<br>\n * \n * @author Jaroslav Bachorik\n */\nfinal public class RuntimeCCTNodeProcessor {\n    final private static Logger LOGGER = Logger.getLogger(RuntimeCCTNodeProcessor.class.getName());\n\n    /**\n     * A processor plugin definition. <br>\n     * Plugin implementations should be based rather on {@linkplain PluginAdapter}\n     */\n    public static interface Plugin {\n        /**\n         * {@linkplain RuntimeCCTNode} hierarchy traversal starts\n         */\n        void onStart();\n        /**\n         * {@linkplain RuntimeCCTNode} hierarchy traversal stops\n         */\n        void onStop();\n        /**\n         * A node is being processed\n         * @param node The node being processed\n         */\n        void onNode(RuntimeCCTNode node);\n        /**\n         * A node and all its children have been processed\n         * @param node The node having been processed\n         */\n        void onBackout(RuntimeCCTNode node);\n    }\n\n    /**\n     * An adapter for {@linkplain Plugin}.<br>\n     * Provides default empty implementations and implements simple dispatching\n     * mechanism for typed <b>onNode</b> calls.\n     */\n    public static abstract class PluginAdapter implements Plugin {\n        @Override\n        final public void onBackout(RuntimeCCTNode node) {\n            if (node instanceof MethodCPUCCTNode) {\n                onBackout((MethodCPUCCTNode)node);\n            } else if (node instanceof MarkedCPUCCTNode) {\n                onBackout((MarkedCPUCCTNode)node);\n            } else if (node instanceof ThreadCPUCCTNode) {\n                onBackout((ThreadCPUCCTNode)node);\n            } else if (node instanceof SimpleCPUCCTNode) {\n                onBackout((SimpleCPUCCTNode)node);\n            } else if (node instanceof ServletRequestCPUCCTNode) {\n                onBackout((ServletRequestCPUCCTNode)node);\n            } else {\n                LOGGER.log(Level.WARNING, \"Can not process uncrecoginzed node class {0}\", node.getClass());\n            }\n        }\n\n        @Override\n        final public void onNode(RuntimeCCTNode node) {\n            if (node instanceof MethodCPUCCTNode) {\n                onNode((MethodCPUCCTNode)node);\n            } else if (node instanceof MarkedCPUCCTNode) {\n                onNode((MarkedCPUCCTNode)node);\n            } else if (node instanceof ThreadCPUCCTNode) {\n                onNode((ThreadCPUCCTNode)node);\n            } else if (node instanceof SimpleCPUCCTNode) {\n                onNode((SimpleCPUCCTNode)node);\n            } else if (node instanceof ServletRequestCPUCCTNode) {\n                onNode((ServletRequestCPUCCTNode)node);\n            } else {\n                LOGGER.log(Level.WARNING, \"Can not process uncrecoginzed node class {0}\", node.getClass());\n            }\n        }\n\n        @Override\n        public void onStart() {\n        }\n\n        @Override\n        public void onStop() {\n        }\n        /**\n         * @see Plugin#onNode(org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode) \n         */\n        protected void onNode(MethodCPUCCTNode node) {}\n        /**\n         * @see Plugin#onNode(org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode) \n         */\n        protected void onNode(MarkedCPUCCTNode node) {}\n        /**\n         * @see Plugin#onNode(org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode) \n         */\n        protected void onNode(ThreadCPUCCTNode node) {}\n        /**\n         * @see Plugin#onNode(org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode) \n         */\n        protected void onNode(SimpleCPUCCTNode node) {}\n        /**\n         * @see Plugin#onNode(org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode) \n         */\n        protected void onNode(ServletRequestCPUCCTNode node) {}\n        /**\n         * @see Plugin#onBackout(org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode) \n         */\n        protected void onBackout(MethodCPUCCTNode node) {}\n        /**\n         * @see Plugin#onBackout(org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode) \n         */\n        protected void onBackout(MarkedCPUCCTNode node) {}\n        /**\n         * @see Plugin#onBackout(org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode) \n         */\n        protected void onBackout(ThreadCPUCCTNode node) {}\n        /**\n         * @see Plugin#onBackout(org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode) \n         */\n        protected void onBackout(SimpleCPUCCTNode node) {}\n        /**\n         * @see Plugin#onBackout(org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode) \n         */\n        protected void onBackout(ServletRequestCPUCCTNode node) {}\n    }\n    \n    private static abstract class Item<T extends RuntimeCCTNode> {\n        final protected T instance;\n        final protected Plugin[] plugins;\n        \n        Item(T instance, Plugin ... plugins) {\n            this.instance = instance;\n            this.plugins = plugins;\n        }\n        \n        abstract void process(int maxMethodId);\n    }\n    \n    private static class SimpleItem extends Item<RuntimeCCTNode> {\n        final private Deque<Item<RuntimeCCTNode>> stack;\n        SimpleItem(Deque<Item<RuntimeCCTNode>> stack, RuntimeCCTNode instance, Plugin ... plugins) {\n            super(instance, plugins);\n            this.stack = stack;\n        }\n\n        @Override\n        void process(int maxMethodId) {\n            stack.add(new BackoutItem(instance, plugins));\n            for(RuntimeCCTNode n : instance.getChildren()) {\n                if (n instanceof MethodCPUCCTNode) {\n                    if (((MethodCPUCCTNode)n).getMethodId() >= maxMethodId) continue;\n                }\n                stack.add(new SimpleItem(stack, n, plugins));\n            }\n            for(Plugin p : plugins) {\n                if (p != null) {\n                    p.onNode(instance);\n                }\n            }\n        }\n    }\n    \n    private static class BackoutItem extends Item<RuntimeCCTNode> {\n        BackoutItem(RuntimeCCTNode instance, Plugin ... plugins) {\n            super(instance, plugins);\n        }\n\n        @Override\n        void process(int maxMethodId) {\n            for(Plugin p : plugins) {\n                if (p != null) {\n                    p.onBackout(instance);\n                }\n            }\n        }\n    }\n    \n    private RuntimeCCTNodeProcessor() {}\n    \n    public static void process(RuntimeCCTNode root, Plugin ... plugins) {\n        Deque<Item<RuntimeCCTNode>> nodeStack = new ArrayDeque<>();\n        \n        for(Plugin p : plugins) {\n            if (p != null) {\n                p.onStart();\n            }\n        }\n        nodeStack.push(new SimpleItem(nodeStack, root, plugins));\n        int maxMethodId = (root instanceof SimpleCPUCCTNode) ? ((SimpleCPUCCTNode)root).getMaxMethodId() : Integer.MAX_VALUE;\n        processStack(maxMethodId, nodeStack, plugins);\n        for(Plugin p : plugins) {\n            if (p != null) {\n                p.onStop();\n            }\n        }\n    }\n    \n    private static void processStack(int maxMethodId, Deque<Item<RuntimeCCTNode>> stack, Plugin ... plugins) {\n        while (!stack.isEmpty()) {\n            Item<RuntimeCCTNode> item = stack.pollLast();\n            if (item != null) {\n                item.process(maxMethodId);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/coderegion/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nCodeRegionResultsSnapshot_CodeFragmentMsg=Code Fragment\\: {0}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/coderegion/CodeRegionResultsSnapshot.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.coderegion;\n\nimport org.graalvm.visualvm.lib.jfluid.results.ResultsSnapshot;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.text.MessageFormat;\nimport java.util.ResourceBundle;\nimport java.util.logging.Level;\n\n\n/**\n * A class that holds single snapshot of Code Fragment profiling results.\n *\n * @author ian Formanek\n */\npublic final class CodeRegionResultsSnapshot extends ResultsSnapshot {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String CODE_FRAGMENT_MSG = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.coderegion.Bundle\").getString(\"CodeRegionResultsSnapshot_CodeFragmentMsg\"); // NOI18N\n                                                                                                                     // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private long[] rawData;\n    private long timerCountsInSecond;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CodeRegionResultsSnapshot(long beginTime, long timeTaken, long[] rawData, long timerCountsInSecond) {\n        super(beginTime, timeTaken);\n        this.rawData = rawData;\n        this.timerCountsInSecond = timerCountsInSecond;\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            debugValues();\n        }\n    }\n\n    public CodeRegionResultsSnapshot() {\n    } // for loading from file\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @return The number of invocations for which we remember their time.\n     * @see #getTimes() - getTimes()[0] contains the total number of invocations of the tracked method/code\n     */\n    public int getInvocations() {\n        if (rawData == null) {\n            return 0;\n        } else {\n            return rawData.length;\n        }\n    }\n\n    public long getTimerCountsInSecond() {\n        return timerCountsInSecond;\n    }\n\n    /**\n     * @return an array of long values. times[0] is total number of invocations, times[1]-times[times.length-1] contain\n     *         the invocation times for all invocations.\n     */\n    public long[] getTimes() {\n        return rawData;\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        super.readFromStream(in);\n        timerCountsInSecond = in.readLong();\n\n        int len = in.readInt();\n        rawData = new long[len];\n\n        for (int i = 0; i < len; i++) {\n            rawData[i] = in.readLong();\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            debugValues();\n        }\n    }\n\n    public String toString() {\n        return MessageFormat.format(CODE_FRAGMENT_MSG, new Object[] { super.toString() });\n    }\n\n    public void writeToStream(DataOutputStream out) throws IOException {\n        super.writeToStream(out);\n        out.writeLong(timerCountsInSecond);\n        out.writeInt(rawData.length);\n\n        for (int i = 0; i < rawData.length; i++) {\n            out.writeLong(rawData[i]);\n        }\n    }\n\n    private void debugValues() {\n        LOGGER.finest(\"rawData.length: \" + debugLength(rawData)); // NOI18N\n        LOGGER.finest(\"timerCountsInSecond: \" + timerCountsInSecond); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/AllThreadsMergedCPUCCTContainer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport java.util.HashSet;\nimport java.util.ResourceBundle;\n\n\n/**\n * A container for all threads merged CPU data. Currently supports/provides only flat profile data.\n *\n * @author Misha Dmitriev\n */\npublic class AllThreadsMergedCPUCCTContainer extends CPUCCTContainer {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String ALL_THREADS_STRING = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.cpu.Bundle\").getString(\"AllThreadsMergedCPUCCTContainer_AllThreadsString\"); // NOI18N\n                                                                                                                             // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected int view;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public AllThreadsMergedCPUCCTContainer(CPUResultsSnapshot cpuResSnapshot, PrestimeCPUCCTNode[] rootNodeSubNodes, int view) {\n        super(cpuResSnapshot);\n        this.threadId = -1;\n        this.threadName = ALL_THREADS_STRING;\n        this.view = view;\n        collectingTwoTimeStamps = cpuResSnapshot.isCollectingTwoTimeStamps();\n\n        compactData = new byte[OFS_SUBNODE02];\n        setNCallsForNodeOfs(0, 1); // 1 call for \"All threads\" node looks more logical than 0 calls\n        rootNode = new PrestimeCPUCCTNodeBacked(this, rootNodeSubNodes);\n\n        // Calculate the total execution time for all threads by just summing individual thread total times\n        long time = 0;\n\n        for (PrestimeCPUCCTNode rootNodeSubNode : rootNodeSubNodes) {\n            time += rootNodeSubNode.getTotalTime0();\n        }\n\n        wholeGraphNetTime0 = time;\n        setTotalTime0ForNodeOfs(0, time);\n\n        if (collectingTwoTimeStamps) {\n            time = 0;\n\n            for (PrestimeCPUCCTNode rootNodeSubNode : rootNodeSubNodes) {\n                time += rootNodeSubNode.getTotalTime1();\n            }\n\n            wholeGraphNetTime1 = time;\n            setTotalTime1ForNodeOfs(0, time);\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String[] getMethodClassNameAndSig(int methodId) {\n        return cpuResSnapshot.getMethodClassNameAndSig(methodId, view);\n    }\n\n    protected FlatProfileContainer generateFlatProfile() {\n        preGenerateFlatProfile();\n\n        PrestimeCPUCCTNode[] children = (PrestimeCPUCCTNode[]) rootNode.getChildren();\n\n        if (children != null) for (PrestimeCPUCCTNode children1 : children) {\n            CPUCCTContainer childContainer = children1.getContainer();\n            childContainer.timePerMethodId0 = this.timePerMethodId0;\n            childContainer.timePerMethodId1 = this.timePerMethodId1;\n            childContainer.totalTimePerMethodId0 = this.totalTimePerMethodId0;\n            childContainer.totalTimePerMethodId1 = this.totalTimePerMethodId1;\n            childContainer.invPerMethodId = this.invPerMethodId;\n            childContainer.methodsOnStack = new HashSet();\n            \n            childContainer.addFlatProfTimeForNode(0);\n\n            childContainer.timePerMethodId0 = childContainer.timePerMethodId1 = null;\n            childContainer.totalTimePerMethodId0 = childContainer.totalTimePerMethodId1 = null;\n            childContainer.invPerMethodId = null;\n            childContainer.methodsOnStack = null;\n        }\n\n        return postGenerateFlatProfile();\n    }\n\n    protected PrestimeCPUCCTNodeFree generateReverseCCT(int methodId) {\n        PrestimeCPUCCTNode[] children = (PrestimeCPUCCTNode[]) rootNode.getChildren();\n\n        PrestimeCPUCCTNodeFree rev = null;\n\n        for (PrestimeCPUCCTNode children1 : children) {\n            CPUCCTContainer childContainer = children1.getContainer();\n\n            if (rev == null) {\n                rev = childContainer.generateReverseCCT(methodId);\n            } else {\n                childContainer.addToReverseCCT(rev, methodId);\n            }\n        }\n\n        return rev;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nAllThreadsMergedCPUCCTContainer_AllThreadsString=All threads\n\nCPUResultsSnapshot_CpuMsg=CPU\\: {0}\n\nMethodIdMap_AnonymousPackageString=<unnamed package>\n\nPrestimeCPUCCTNode_SelfTimeString=Self time\n\nMSG_INVALID_METHODID=\"Invalid methodId={0} (max. accomodated methodId is {1})\"\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/CPUCCTClassContainer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.utils.IntVector;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Set;\n\n\n/**\n * An extension of CPUCCTContainer that has functionality to build a class- or package-level CCT out of the method-level CCT.\n *\n * @author Misha Dmitriev\n */\npublic class CPUCCTClassContainer extends CPUCCTContainer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected int view;\n\n    //-- Temporary data used during construction\n    private CPUCCTContainer sourceContainer;\n    private MethodIdMap methodIdMap;\n    private long childTotalTime0;\n    private long childTotalTime1;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CPUCCTClassContainer(CPUCCTContainer sourceContainer, MethodIdMap methodIdMap, int view) {\n        super(sourceContainer.cpuResSnapshot);\n        this.view = view;\n        this.sourceContainer = sourceContainer;\n        this.threadId = sourceContainer.threadId;\n        this.threadName = sourceContainer.threadName;\n        this.wholeGraphNetTime0 = sourceContainer.wholeGraphNetTime0;\n        this.wholeGraphNetTime1 = sourceContainer.wholeGraphNetTime1;\n        this.childOfsSize = CHILD_OFS_SIZE_3;\n\n        collectingTwoTimeStamps = sourceContainer.collectingTwoTimeStamps;\n        nodeSize = sourceContainer.nodeSize;\n\n        compactData = new byte[sourceContainer.compactData.length]; // Initially create a same-sized array - should be more than enough\n\n        this.methodIdMap = methodIdMap;\n\n        IntVector rootMethodVec = new IntVector();\n        rootMethodVec.add(0);\n\n        int lastOfs = generateClassNodeFromMethodNodes(rootMethodVec, 0);\n\n        // Create an array of appropriate size\n        byte[] oldData = compactData;\n        compactData = new byte[lastOfs];\n        System.arraycopy(oldData, 0, compactData, 0, lastOfs);\n\n        rootNode = new PrestimeCPUCCTNodeBacked(this, null, 0);\n\n        if (rootNode.getMethodId() == 0) {\n            rootNode.setThreadNode();\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String[] getMethodClassNameAndSig(int methodId) {\n        return cpuResSnapshot.getMethodClassNameAndSig(methodId, view);\n    }\n\n    /**\n     * For a given vector of source (method-level) nodes, where all nodes have the same class, generate\n     * a single class-level node. Do the same with all the source node's children.\n     * Returns the offset right after the last generated node, which is this node if it has no children,\n     * or the last recursive child of this node.\n     */\n    protected int generateClassNodeFromMethodNodes(IntVector methodNodes, int dataOfs) {\n        int nMethodNodes = methodNodes.size();\n        int nCalls = 0;\n        long time0 = 0;\n        long time1 = 0;\n\n        for (int i = 0; i < nMethodNodes; i++) {\n            int methodNodeOfs = methodNodes.get(i);\n            nCalls += sourceContainer.getNCallsForNodeOfs(methodNodeOfs);\n            time0 += sourceContainer.getSelfTime0ForNodeOfs(methodNodeOfs);\n\n            if (collectingTwoTimeStamps) {\n                time1 += sourceContainer.getSelfTime1ForNodeOfs(methodNodeOfs);\n            }\n        }\n\n        int methodId = sourceContainer.getMethodIdForNodeOfs(methodNodes.get(0));\n\n        if (methodId != 0) {\n            methodId = methodIdMap.getClassOrPackageIdForMethodId(methodId);\n        }\n\n        setMethodIdForNodeOfs(dataOfs, methodId);\n        setNCallsForNodeOfs(dataOfs, nCalls);\n        setSelfTime0ForNodeOfs(dataOfs, time0);\n\n        if (collectingTwoTimeStamps) {\n            setSelfTime1ForNodeOfs(dataOfs, time1);\n        }\n\n        // Now add all the children of methodNodes that have the same class, to thisNode, and collect the rest of the\n        // children of methodNodes into sourceChildren vector.\n        IntVector sourceChildren = new IntVector();\n        Set uniqChildrenCache = new HashSet();\n\n        for (int i = 0; i < nMethodNodes; i++) {\n            int methodNodeOfs = methodNodes.get(i);\n            int nChildren = sourceContainer.getNChildrenForNodeOfs(methodNodeOfs);\n\n            if (nChildren > 0) {\n                processChildren(dataOfs, methodNodeOfs, nChildren, sourceChildren, uniqChildrenCache);\n            }\n        }\n\n        int thisNodeNChildren = uniqChildrenCache.size();\n        int nextNodeOfs = dataOfs + nodeSize + (thisNodeNChildren * childOfsSize);\n\n        if (thisNodeNChildren == 0) {\n            childTotalTime0 = getSelfTime0ForNodeOfs(dataOfs); // We are effectively returning these values\n\n            if (collectingTwoTimeStamps) {\n                childTotalTime1 = getSelfTime1ForNodeOfs(dataOfs);\n            }\n\n            setTotalTime0ForNodeOfs(dataOfs, childTotalTime0);\n\n            if (collectingTwoTimeStamps) {\n                setTotalTime1ForNodeOfs(dataOfs, childTotalTime1);\n            }\n\n            return nextNodeOfs;\n        } else {\n            time0 = getSelfTime0ForNodeOfs(dataOfs);\n\n            if (collectingTwoTimeStamps) {\n                time1 = getSelfTime1ForNodeOfs(dataOfs);\n            }\n        }\n\n        setNChildrenForNodeOfs(dataOfs, thisNodeNChildren);\n\n        IntVector sameTypeChildren = new IntVector();\n        int nAllChildren = sourceChildren.size();\n        int[] sourceChildrenClassIds = new int[nAllChildren];\n\n        for (int i = 0; i < nAllChildren; i++) {\n            int mid = sourceContainer.getMethodIdForNodeOfs(sourceChildren.get(i));\n            sourceChildrenClassIds[i] = methodIdMap.getClassOrPackageIdForMethodId(mid);\n        }\n\n        Iterator e = uniqChildrenCache.iterator();\n\n        for (int i = 0; e.hasNext(); i++) {\n            sameTypeChildren.clear();\n\n            int sourceChildClassOrPackageId = ((Integer) e.next()).intValue();\n\n            for (int j = 0; j < nAllChildren; j++) {\n                if (sourceChildrenClassIds[j] == sourceChildClassOrPackageId) {\n                    sameTypeChildren.add(sourceChildren.get(j));\n                }\n            }\n\n            setChildOfsForNodeOfs(dataOfs, i, nextNodeOfs);\n\n            nextNodeOfs = generateClassNodeFromMethodNodes(sameTypeChildren, nextNodeOfs);\n            time0 += childTotalTime0;\n\n            if (collectingTwoTimeStamps) {\n                time1 += childTotalTime1;\n            }\n        }\n\n        setTotalTime0ForNodeOfs(dataOfs, time0);\n\n        if (collectingTwoTimeStamps) {\n            setTotalTime1ForNodeOfs(dataOfs, time1);\n        }\n\n        childTotalTime0 = time0;\n\n        if (collectingTwoTimeStamps) {\n            childTotalTime1 = time1;\n        }\n\n        return nextNodeOfs;\n    }\n\n    /**\n     * Given this target node, and the array of its source-level children, treat them as follows:\n     * 1. The info for a source child who has the same class as this node, is added to this node.\n     * Its own children are processed recursively by calling this same method.\n     * 2. The first source child whose class is different and was not observed before (not contained\n     * in uniqChildCache) is added to uniqChildCache, and to allSourceChildren.\n     * 3. All other source children are added to allSourceChildren, but not to uniqChildCache.\n     */\n    protected void processChildren(int dataOfs, int methodNodeOfs, int nChildren, IntVector allSourceChildren,\n                                   Set uniqChildCache) {\n        int thisNodeClassOrPackageId = getMethodIdForNodeOfs(dataOfs);\n\n        int nCalls = 0;\n        long time0 = 0;\n        long time1 = 0;\n\n        for (int i = 0; i < nChildren; i++) {\n            int sourceChildOfs = sourceContainer.getChildOfsForNodeOfs(methodNodeOfs, i);\n            int sourceChildClassOrPackageId = methodIdMap.getClassOrPackageIdForMethodId(sourceContainer.getMethodIdForNodeOfs(sourceChildOfs));\n\n            if (sourceChildClassOrPackageId == thisNodeClassOrPackageId) { // A child node has the same class as this node\n                nCalls += sourceContainer.getNCallsForNodeOfs(sourceChildOfs);\n                time0 += sourceContainer.getSelfTime0ForNodeOfs(sourceChildOfs);\n\n                if (collectingTwoTimeStamps) {\n                    time1 += sourceContainer.getSelfTime1ForNodeOfs(sourceChildOfs);\n                }\n\n                // sourceChild's children logically become this node's children now.\n                int nSourceChildChildren = sourceContainer.getNChildrenForNodeOfs(sourceChildOfs);\n\n                if (nSourceChildChildren > 0) {\n                    this.processChildren(dataOfs, sourceChildOfs, nSourceChildChildren, allSourceChildren, uniqChildCache);\n                }\n            } else { // A child node belongs to a different class\n\n                Integer key = Integer.valueOf(sourceChildClassOrPackageId);\n\n                uniqChildCache.add(key);\n                allSourceChildren.add(sourceChildOfs);\n            }\n        }\n\n        nCalls += getNCallsForNodeOfs(dataOfs);\n        time0 += getSelfTime0ForNodeOfs(dataOfs);\n\n        if (collectingTwoTimeStamps) {\n            time1 += getSelfTime1ForNodeOfs(dataOfs);\n        }\n\n        setNCallsForNodeOfs(dataOfs, nCalls);\n        setSelfTime0ForNodeOfs(dataOfs, time0);\n\n        if (collectingTwoTimeStamps) {\n            setSelfTime1ForNodeOfs(dataOfs, time1);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/CPUCCTContainer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MethodCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.RuntimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.TimedCPUCCTNode;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\n\n\n/**\n * An instance of this class contains a presentation-time CCT for the given thread in the compact, flattened form, that is also fast\n * to generate and save/retrieve.\n * Can represent data only on the method level \"view\" AKA \"aggregation level\". The CPUCCTClassContainer subclass provides functionality\n * to create and represent data at class and package aggregation level. The AllThreadsMergedCPUCCTContainer also supports views. A single\n * instance of CPUCCTContainer or its subclass can represent data only on a single aggregation level.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class CPUCCTContainer {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Logger LOGGER = Logger.getLogger(CPUCCTContainer.class.getName());\n\n    // -- Data used for the compact representation of the CCT\n    /* In the compactData array, data is packed in the following way:\n     *  |---------------------------------------------------------------------------------------------------------\n     *  | methodID | nCalls  |time0  | self  |time1        | self  |nbr. of subnodes | subnode0 |     | subnodeN |\n     *  |          |         |       | time0 |(if 2 timers | time1 |                 | offset   | ... | offset   |\n     *  |          |         |       |       | used)       |       |                 |          |     |          |\n     *  |---------------------------------------------------------------------------------------------------------\n     *    2 bytes   4 bytes   5 bytes 5 bytes  5 bytes      5 bytes  2 bytes           3 or 4 bytes depending on the size of compactData array\n     */\n    protected static final int OFS_METHODID = 0;\n    protected static final int OFS_NCALLS = OFS_METHODID + 2;\n    protected static final int OFS_TIME0 = OFS_NCALLS + 4;\n    protected static final int OFS_SELFTIME0 = OFS_TIME0 + 5;\n    protected static final int OFS_TIME1 = OFS_SELFTIME0 + 5;\n    protected static final int OFS_SELFTIME1 = OFS_TIME1 + 5;\n    protected static final int OFS_NSUBNODES1 = OFS_SELFTIME0 + 5;\n    protected static final int OFS_NSUBNODES2 = OFS_SELFTIME1 + 5;\n    protected static final int OFS_SUBNODE01 = OFS_NSUBNODES1 + 2;\n    protected static final int OFS_SUBNODE02 = OFS_NSUBNODES2 + 2;\n    protected static final int CHILD_OFS_SIZE_3 = 3;\n    protected static final int CHILD_OFS_SIZE_4 = 4;\n\n    // These are just the same-named xxxAbsCounts values converted into microseconds. So far used ONLY for informational purposes\n    // (in \"get internal statistics\"), thus static is more or less tolerable (so far...)\n    private static double timeInInjectedCodeInMS;\n    private static double wholeGraphGrossTimeAbsInMS;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected CPUResultsSnapshot cpuResSnapshot;\n    protected FlatProfileContainer cachedFlatProfile;\n    public PrestimeCPUCCTNode rootNode;\n    protected String threadName;\n    protected byte[] compactData;\n    protected int[] invPerMethodId;\n\n    // -- Temporary data used during flat profile generation\n    protected long[] timePerMethodId0;\n    protected long[] timePerMethodId1;\n    protected long[] totalTimePerMethodId0;\n    protected long[] totalTimePerMethodId1;\n    protected Set methodsOnStack;\n    protected boolean collectingTwoTimeStamps; // True if we collect two timestamps, absolute and thread CPU, for each method invocation\n    protected boolean displayWholeThreadCPUTime; // True if we can calculate, and thus display, valid whole thread CPU time\n\n    // Time spent in instrumentation, measured in counts\n    protected double timeInInjectedCodeInAbsCounts;\n    protected double timeInInjectedCodeInThreadCPUCounts;\n    protected int childOfsSize = -1;\n    protected int nodeSize; // Size of a single node above, not taking possible subnodeOffset fields into account\n    protected int threadId;\n\n    // -- Data that is supposed to be used for user information in various parts of the CPU results display\n    // Gross time spent in the whole graph, measured in counts. It's measured by \"starting the clock\" when the root\n    // method is entered, and \"stopping the clock\" when it exits. Time for hotswapping and on-line data processing\n    // is factored out, so what is actually contained in wholeGraphGrossTime is (pure time + instrumentation time).\n    // Note that independent of method timestamps collected, root method entry and exit events always have both\n    // absolute and thread CPU time stamps.\n    protected long wholeGraphGrossTimeAbs;\n    protected long wholeGraphGrossTimeThreadCPU;\n\n    // This is calculated as a sum of net times spent in all methods\n    protected long wholeGraphNetTime0;\n    protected long wholeGraphNetTime1;\n\n    // This is calculated as the above gross time minus total time spent in instrumentation\n    protected long wholeGraphPureTimeAbs;\n    protected long wholeGraphPureTimeThreadCPU;\n    private InstrumentationFilter filter;\n    private PrestimeCPUCCTNodeFree reverseCCTRootNode;\n//    private ProfilingSessionStatus status;\n    private int[] nodeStack;\n    private int childTotalNCalls;\n    private int currentNodeStackSize;\n    private int nodeStackPtr;\n\n    // -- Temporary data used during reverse CCT generation\n    private int selectedMethodId;\n\n    // -- Temporary data used during above array generation\n    private long childTotalTime0InTimerUnits;\n    private long childTotalTime1InTimerUnits;\n    long totalInvNo;\n\n    private TimingAdjusterOld timingAdjuster;\n\n    private MethodInfoMapper methodInfoMapper = MethodInfoMapper.DEFAULT;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CPUCCTContainer(TimedCPUCCTNode rtRootNode, CPUResultsSnapshot cpuResSnapshot, MethodInfoMapper methodInfoMapper, TimingAdjusterOld timingAdjuster,\n                           InstrumentationFilter usedFilter, int nNodes,\n                           double[] threadActiveTimesInCounts, int threadId, String threadName) {\n        this(cpuResSnapshot);\n\n        this.threadId = threadId;\n        this.threadName = threadName;\n\n        this.methodInfoMapper = methodInfoMapper;\n        this.timingAdjuster = timingAdjuster;\n        this.filter = usedFilter;\n\n        collectingTwoTimeStamps = cpuResSnapshot.isCollectingTwoTimeStamps();\n\n        generateCompactData(rtRootNode, nNodes);\n\n        calculateThreadActiveTimesInMS(threadActiveTimesInCounts);\n\n        rootNode = new PrestimeCPUCCTNodeBacked(this, null, 0);\n\n        if (rtRootNode.isRoot()) {\n            rootNode.setThreadNode();\n        }\n    }\n\n    protected CPUCCTContainer(CPUResultsSnapshot cpuResSnapshot) {\n        this.cpuResSnapshot = cpuResSnapshot;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public CPUResultsSnapshot getCPUResSnapshot() {\n        return cpuResSnapshot;\n    }\n\n    public int getChildOfsForNodeOfs(int nodeOfs, int childIdx) {\n        if (childOfsSize == CHILD_OFS_SIZE_4) {\n            return get4Bytes(nodeOfs + (collectingTwoTimeStamps ? OFS_SUBNODE02 : OFS_SUBNODE01) + (childOfsSize * childIdx));\n        } else {\n            return get3Bytes(nodeOfs + (collectingTwoTimeStamps ? OFS_SUBNODE02 : OFS_SUBNODE01) + (childOfsSize * childIdx));\n        }\n    }\n\n    public boolean isCollectingTwoTimeStamps() {\n        return collectingTwoTimeStamps;\n    }\n\n    public FlatProfileContainer getFlatProfile() {\n        //    if (cachedFlatProfile == null) {\n        //      generateFlatProfile();\n        //    }\n        //    return cachedFlatProfile;\n        return generateFlatProfile();\n    }\n\n    public String[] getMethodClassNameAndSig(int methodId) {\n        return cpuResSnapshot.getMethodClassNameAndSig(methodId, CPUResultsSnapshot.METHOD_LEVEL_VIEW);\n    }\n\n    // -- Methods for retrieving data for individual nodes\n    public int getMethodIdForNodeOfs(int nodeOfs) {\n        return get2Bytes(nodeOfs + OFS_METHODID);\n    }\n\n    public int getNCallsForNodeOfs(int nodeOfs) {\n        return get4Bytes(nodeOfs + OFS_NCALLS);\n    }\n\n    public int getNChildrenForNodeOfs(int nodeOfs) {\n        return get2Bytes(nodeOfs + (collectingTwoTimeStamps ? OFS_NSUBNODES2 : OFS_NSUBNODES1));\n    }\n\n    public PrestimeCPUCCTNode getReverseCCT(int methodId) {\n        return generateReverseCCT(methodId);\n    }\n\n    public PrestimeCPUCCTNode getRootNode() {\n        return rootNode;\n    }\n\n    public long getSelfTime0ForNodeOfs(int nodeOfs) {\n        return get5Bytes(nodeOfs + OFS_SELFTIME0);\n    }\n\n    public long getSelfTime1ForNodeOfs(int nodeOfs) {\n        return get5Bytes(nodeOfs + OFS_SELFTIME1);\n    }\n\n    public long getSleepTime0ForNodeOfs(int nodeOfs) {\n        return 0;\n    } // TODO [wait]\n\n    public int getThreadId() {\n        return threadId;\n    }\n\n    public String getThreadName() {\n        return threadName;\n    }\n\n    // Provided for information purposes (that is, the \"get internal statistics\" action) only. Since this stuff\n    // is not used in any real calculations, it's more or less tolerable so far to have it static.\n    public static double getTimeInInjectedCodeForDisplayedThread() {\n        return timeInInjectedCodeInMS;\n    }\n\n    public long getTotalTime0ForNodeOfs(int nodeOfs) {\n        return get5Bytes(nodeOfs + OFS_TIME0);\n    }\n\n    public long getTotalTime1ForNodeOfs(int nodeOfs) {\n        return get5Bytes(nodeOfs + OFS_TIME1);\n    }\n\n    public long getWaitTime0ForNodeOfs(int nodeOfs) {\n        return 0;\n    } // TODO [wait]\n\n    public static double getWholeGraphGrossTimeAbsForDisplayedThread() {\n        return wholeGraphGrossTimeAbsInMS;\n    }\n\n    public long getWholeGraphNetTime0() {\n        return wholeGraphNetTime0;\n    }\n\n    public long getWholeGraphNetTime1() {\n        return wholeGraphNetTime1;\n    }\n\n    public long getWholeGraphPureTimeAbs() {\n        return wholeGraphPureTimeAbs;\n    }\n\n    public long getWholeGraphPureTimeThreadCPU() {\n        return wholeGraphPureTimeThreadCPU;\n    }\n\n    public boolean canDisplayWholeGraphCPUTime() {\n        return displayWholeThreadCPUTime;\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        threadId = in.readInt();\n        threadName = in.readUTF();\n\n        collectingTwoTimeStamps = in.readBoolean();\n\n        int len = in.readInt();\n        compactData = new byte[len];\n\n        if (compactData.length > 0xFFFFFF) {\n            childOfsSize = CHILD_OFS_SIZE_4;\n        } else {\n            childOfsSize = CHILD_OFS_SIZE_3;\n        }\n\n        in.readFully(compactData);\n\n        nodeSize = in.readInt();\n\n        wholeGraphGrossTimeAbs = in.readLong();\n        wholeGraphGrossTimeThreadCPU = in.readLong();\n        timeInInjectedCodeInAbsCounts = in.readDouble();\n        timeInInjectedCodeInThreadCPUCounts = in.readDouble();\n        wholeGraphPureTimeAbs = in.readLong();\n        wholeGraphPureTimeThreadCPU = in.readLong();\n        wholeGraphNetTime0 = in.readLong();\n        wholeGraphNetTime1 = in.readLong();\n        totalInvNo = in.readLong();\n        displayWholeThreadCPUTime = in.readBoolean();\n\n        rootNode = new PrestimeCPUCCTNodeBacked(this, null, 0);\n\n        if (this.getMethodIdForNodeOfs(0) == 0) {\n            rootNode.setThreadNode();\n        }\n    }\n\n    // -- Serialization support\n    public void writeToStream(DataOutputStream out) throws IOException {\n        out.writeInt(threadId);\n        out.writeUTF(threadName);\n\n        out.writeBoolean(collectingTwoTimeStamps);\n\n        out.writeInt(compactData.length);\n        out.write(compactData);\n        out.writeInt(nodeSize);\n\n        out.writeLong(wholeGraphGrossTimeAbs);\n        out.writeLong(wholeGraphGrossTimeThreadCPU);\n        out.writeDouble(timeInInjectedCodeInAbsCounts);\n        out.writeDouble(timeInInjectedCodeInThreadCPUCounts);\n        out.writeLong(wholeGraphPureTimeAbs);\n        out.writeLong(wholeGraphPureTimeThreadCPU);\n        out.writeLong(wholeGraphNetTime0);\n        out.writeLong(wholeGraphNetTime1);\n        out.writeLong(totalInvNo);\n        out.writeBoolean(displayWholeThreadCPUTime);\n    }\n\n    protected void setChildOfsForNodeOfs(int nodeOfs, int childIdx, int val) {\n        if (childOfsSize == CHILD_OFS_SIZE_4) {\n            store4Bytes(nodeOfs + (collectingTwoTimeStamps ? OFS_SUBNODE02 : OFS_SUBNODE01) + (childOfsSize * childIdx), val);\n        } else {\n            store3Bytes(nodeOfs + (collectingTwoTimeStamps ? OFS_SUBNODE02 : OFS_SUBNODE01) + (childOfsSize * childIdx), val);\n        }\n    }\n\n    // -- Methods for setting data for individual nodes\n    protected void setMethodIdForNodeOfs(int nodeOfs, int val) {\n        store2Bytes(nodeOfs + OFS_METHODID, val);\n    }\n\n    protected void setNCallsForNodeOfs(int nodeOfs, int val) {\n        store4Bytes(nodeOfs + OFS_NCALLS, val);\n    }\n\n    protected void setNChildrenForNodeOfs(int nodeOfs, int val) {\n        store2Bytes(nodeOfs + (collectingTwoTimeStamps ? OFS_NSUBNODES2 : OFS_NSUBNODES1), val);\n    }\n\n    protected void setSelfTime0ForNodeOfs(int nodeOfs, long val) {\n        store5Bytes(nodeOfs + OFS_SELFTIME0, val);\n    }\n\n    protected void setSelfTime1ForNodeOfs(int nodeOfs, long val) {\n        store5Bytes(nodeOfs + OFS_SELFTIME1, val);\n    }\n\n    protected void setSleepTime0ForNodeOfs(int dataOfs, long waitTime0) {\n    } // TODO [sleep should be stored separately in future versions]\n\n    protected void setTotalTime0ForNodeOfs(int nodeOfs, long val) {\n        store5Bytes(nodeOfs + OFS_TIME0, val);\n    }\n\n    protected void setTotalTime1ForNodeOfs(int nodeOfs, long val) {\n        store5Bytes(nodeOfs + OFS_TIME1, val);\n    }\n\n    protected void setWaitTime0ForNodeOfs(int dataOfs, long waitTime0) {\n    } // TODO [wait should be stored separately in future versions]\n\n    protected void addFlatProfTimeForNode(int dataOfs) {\n        int methodId = getMethodIdForNodeOfs(dataOfs);\n        Integer methodIdInt = Integer.valueOf(methodId);\n        boolean isRecursiveCall = methodsOnStack.contains(methodIdInt);\n        \n        if (methodId >= invPerMethodId.length) {\n            LOGGER.log(Level.WARNING, \"Method ID ({0}) out of bounds ({1})\", new Object[]{methodId, invPerMethodId.length});\n            return;\n        }\n        int nChildren = getNChildrenForNodeOfs(dataOfs);\n\n        if (nChildren > 0) {\n            if (!isRecursiveCall) {\n                methodsOnStack.add(methodIdInt);\n            }\n            for (int i = 0; i < nChildren; i++) {\n                int childOfs = getChildOfsForNodeOfs(dataOfs, i);\n                addFlatProfTimeForNode(childOfs);\n            }\n            if (!isRecursiveCall) {\n                methodsOnStack.remove(methodIdInt);                \n            }\n        }\n\n        timePerMethodId0[methodId] += getSelfTime0ForNodeOfs(dataOfs);\n        if (!isRecursiveCall) {\n            totalTimePerMethodId0[methodId] += getTotalTime0ForNodeOfs(dataOfs);\n        }\n        if (collectingTwoTimeStamps) {\n            timePerMethodId1[methodId] += getSelfTime1ForNodeOfs(dataOfs);\n            if (!isRecursiveCall) {\n                totalTimePerMethodId1[methodId] += getTotalTime1ForNodeOfs(dataOfs);\n            }\n        }\n\n        invPerMethodId[methodId] += getNCallsForNodeOfs(dataOfs);\n    }\n\n    protected void addToReverseCCT(PrestimeCPUCCTNodeFree reverseNode, int methodId) {\n        selectedMethodId = methodId;\n        reverseCCTRootNode = reverseNode;\n\n        currentNodeStackSize = 320;\n        nodeStack = new int[currentNodeStackSize];\n        nodeStackPtr = 0;\n        checkStraightGraphNode(0);\n\n        nodeStack = null; // Free memory\n        reverseCCTRootNode = null; // Ditto\n    }\n\n    /**\n     * Walk all the elements of the main graph, looking for nodes with selectedMethodId signature.\n     * Whenever one is found, add its path, in reversed form, to the rootNode.\n     * When path is added, same-named nodes are merged until the first pair of different nodes is found.\n     */\n    protected void checkStraightGraphNode(int dataOfs) {\n        if (nodeStackPtr >= currentNodeStackSize) {\n            int[] newNodeStack = new int[currentNodeStackSize * 2];\n            System.arraycopy(nodeStack, 0, newNodeStack, 0, currentNodeStackSize);\n            nodeStack = newNodeStack;\n            currentNodeStackSize = currentNodeStackSize * 2;\n        }\n\n        nodeStack[nodeStackPtr++] = dataOfs;\n\n        if (getMethodIdForNodeOfs(dataOfs) == selectedMethodId) {\n            addReversePath();\n        }\n\n        int nChildren = getNChildrenForNodeOfs(dataOfs);\n\n        for (int i = 0; i < nChildren; i++) {\n            checkStraightGraphNode(getChildOfsForNodeOfs(dataOfs, i));\n        }\n\n        nodeStackPtr--;\n    }\n\n    protected FlatProfileContainer generateFlatProfile() {\n        preGenerateFlatProfile();\n\n        addFlatProfTimeForNode(0);\n\n        return postGenerateFlatProfile();\n    }\n\n    protected PrestimeCPUCCTNodeFree generateReverseCCT(int methodId) {\n        selectedMethodId = methodId;\n\n        currentNodeStackSize = 320;\n        nodeStack = new int[currentNodeStackSize];\n        nodeStackPtr = 0;\n        checkStraightGraphNode(0);\n\n        PrestimeCPUCCTNodeFree ret = reverseCCTRootNode;\n\n        nodeStack = null; // Free memory\n        reverseCCTRootNode = null; // Ditto\n\n        return ret;\n    }\n\n    protected int get2Bytes(int ofs) {\n        return (((int) compactData[ofs] & 0xFF) << 8) | ((int) compactData[ofs + 1] & 0xFF);\n    }\n\n    protected int get3Bytes(int ofs) {\n        return (((int) compactData[ofs++] & 0xFF) << 16) | (((int) compactData[ofs++] & 0xFF) << 8)\n               | ((int) compactData[ofs++] & 0xFF);\n    }\n\n    protected int get4Bytes(int ofs) {\n        return (((int) compactData[ofs++] & 0xFF) << 24) | (((int) compactData[ofs++] & 0xFF) << 16)\n               | (((int) compactData[ofs++] & 0xFF) << 8) | ((int) compactData[ofs++] & 0xFF);\n    }\n\n    protected long get5Bytes(int ofs) {\n        return (((long) compactData[ofs++] & 0xFF) << 32) | (((long) compactData[ofs++] & 0xFF) << 24)\n               | (((long) compactData[ofs++] & 0xFF) << 16) | (((long) compactData[ofs++] & 0xFF) << 8)\n               | ((long) compactData[ofs++] & 0xFF);\n    }\n\n    protected FlatProfileContainer postGenerateFlatProfile() {\n        FlatProfileContainer fpc = new FlatProfileContainerBacked(this, timePerMethodId0, timePerMethodId1, \n                totalTimePerMethodId0, totalTimePerMethodId1, invPerMethodId, timePerMethodId0.length);\n\n        timePerMethodId0 = timePerMethodId1 = null;\n        totalTimePerMethodId0 = totalTimePerMethodId1 = null;\n        invPerMethodId = null;\n        methodsOnStack = null;\n\n        fpc.filterOriginalData(cpuResSnapshot.filter);\n        return fpc;\n    }\n\n    protected void preGenerateFlatProfile() {\n        int totalMethods = cpuResSnapshot.getNInstrMethods();\n        timePerMethodId0 = new long[totalMethods];\n        totalTimePerMethodId0 = new long[totalMethods];\n\n        if (collectingTwoTimeStamps) {\n            timePerMethodId1 = new long[totalMethods];\n            totalTimePerMethodId1 = new long[totalMethods];\n        }\n\n        invPerMethodId = new int[totalMethods];\n        timePerMethodId0[0] = -1; // 0th element is a hidden \"Thread\" quazi-method. This prevents exposing it in a pathological case when all times are zero.\n        totalTimePerMethodId0[0] = -1; // 0th element is a hidden \"Thread\" quazi-method. This prevents exposing it in a pathological case when all times are zero.\n        methodsOnStack = new HashSet();\n    }\n\n    // -- Utility methods, not interesting enough to place earlier in the code\n    protected void store2Bytes(int ofs, int data) {\n        compactData[ofs] = (byte) ((data >> 8) & 0xFF);\n        compactData[ofs + 1] = (byte) ((data) & 0xFF);\n    }\n\n    protected void store3Bytes(int ofs, int data) {\n        int curPos = ofs;\n        compactData[curPos++] = (byte) ((data >> 16) & 0xFF);\n        compactData[curPos++] = (byte) ((data >> 8) & 0xFF);\n        compactData[curPos++] = (byte) ((data) & 0xFF);\n    }\n\n    protected void store4Bytes(int ofs, int data) {\n        int curPos = ofs;\n        compactData[curPos++] = (byte) ((data >> 24) & 0xFF);\n        compactData[curPos++] = (byte) ((data >> 16) & 0xFF);\n        compactData[curPos++] = (byte) ((data >> 8) & 0xFF);\n        compactData[curPos++] = (byte) ((data) & 0xFF);\n    }\n\n    protected void store5Bytes(int ofs, long data) {\n        int curPos = ofs;\n        compactData[curPos++] = (byte) ((data >> 32) & 0xFF);\n        compactData[curPos++] = (byte) ((data >> 24) & 0xFF);\n        compactData[curPos++] = (byte) ((data >> 16) & 0xFF);\n        compactData[curPos++] = (byte) ((data >> 8) & 0xFF);\n        compactData[curPos++] = (byte) ((data) & 0xFF);\n    }\n\n    private void addChild(AddChildLocalVars locals) {\n        if ((locals.node == null) || (locals.parent == null)) {\n            return;\n        }\n\n        locals.filterStatus = locals.node.getFilteredStatus();\n\n        if (!(locals.node instanceof MethodCPUCCTNode)) {\n            locals.filterStatus = TimedCPUCCTNode.FILTERED_YES;\n        }\n\n        switch (locals.filterStatus) {\n            case TimedCPUCCTNode.FILTERED_YES: {\n                locals.compParent = locals.parent;\n\n                break;\n            }\n            case TimedCPUCCTNode.FILTERED_MAYBE: {\n                if (locals.node instanceof MethodCPUCCTNode) {\n                    methodInfoMapper.lock(false);\n                    try {\n                        locals.className = methodInfoMapper.getInstrMethodClass(((MethodCPUCCTNode) locals.node).getMethodId()).replace('.', '/'); // NOI18N\n                        if (!filter.passes(locals.className)) {\n                            locals.compParent = locals.parent;\n                        } else {\n                            locals.newChild = (TimedCPUCCTNode) locals.node.clone();\n                            locals.compParent = locals.newChild;\n                        }\n                    } finally {\n                        methodInfoMapper.unlock();\n                    }\n                } else {\n                    locals.compParent = locals.parent;\n                }\n\n                break;\n            }\n            case TimedCPUCCTNode.FILTERED_NO: {\n                locals.existingChild = MethodCPUCCTNode.Locator.locate(((MethodCPUCCTNode) locals.node).getMethodId(),\n                                                                                 locals.parent.getChildren());\n\n                if (locals.existingChild == null) {\n                    locals.newChild = (TimedCPUCCTNode) locals.node.clone();\n                    locals.compParent = locals.newChild;\n                } else {\n                    locals.newChild = null;\n                    locals.existingChild.addNCalls(locals.node.getNCalls());\n                    locals.existingChild.addNCallsDiff(locals.node.getNCallsDiff());\n                    locals.existingChild.addNetTime0(locals.node.getNetTime0());\n                    locals.existingChild.addNetTime1(locals.node.getNetTime1());\n                    locals.existingChild.addSleepTime0(locals.node.getSleepTime0());\n                    locals.existingChild.addWaitTime0(locals.node.getWaitTime0());\n                    locals.compParent = locals.existingChild;\n                }\n\n                break;\n            }\n            default:ProfilerLogger.warning(\"Unknown filtered status (\" + locals.filterStatus + \") for \" + locals.node); // NOI18N\n        }\n\n        locals.nChildren = (locals.node.getChildren() != null) ? locals.node.getChildren().length : 0;\n\n        for (int i = 0; i < locals.nChildren; i++) {\n            addChild(new AddChildLocalVars((TimedCPUCCTNode) locals.node.getChildren()[i], locals.compParent));\n        }\n\n        if (locals.newChild != null) {\n            locals.parent.attachNodeAsChild(locals.newChild);\n        } else if (locals.compParent == locals.parent) { // filtered-out node\n            if (!locals.parent.isRoot()) { // no propagation of filtered-out data to the Thread level node\n                locals.parent.addNetTime0(locals.node.getNetTime0());\n                locals.parent.addSleepTime0(locals.node.getSleepTime0());\n                locals.parent.addWaitTime0(locals.node.getWaitTime0());\n                locals.parent.addNCallsDiff(locals.node.getNCalls());\n\n                if (collectingTwoTimeStamps) {\n                    locals.parent.addNetTime1(locals.node.getNetTime1());\n                }\n            } else {\n                //        threadTimeCompensation0 += node.getNetTime0();\n                //        if (collectingTwoTimeStamps) {\n                //          threadTimeCompensation1 += node.getNetTime1();\n                //        }\n            }\n        }\n    }\n    \n    private static final class AddChildLocalVars {\n        private final TimedCPUCCTNode node;\n        private final TimedCPUCCTNode parent;\n        private TimedCPUCCTNode compParent;\n        private TimedCPUCCTNode newChild;\n        private int filterStatus;\n        private int nChildren;\n        private MethodCPUCCTNode existingChild;\n        private String className;\n        \n        AddChildLocalVars(TimedCPUCCTNode n, TimedCPUCCTNode p) {\n            node = n;\n            parent = p;\n        }\n    }\n\n    /**\n     * Add the whole reverse path contained in the nodeStack to the reverse call tree, merging nodes where appropriate.\n     * Most of the complexity of the code is due to handling of the intermediate \"from\" nodes.\n     */\n    private void addReversePath() {\n        PrestimeCPUCCTNodeFree curNode = null; // This is effectively a node above the root node - which is non-existent\n        int stackTopIdx = nodeStackPtr - 1;\n\n        for (int i = stackTopIdx; i >= 0; i--) {\n            int sourceNodeOfs = nodeStack[i];\n            int sourceNodeId = getMethodIdForNodeOfs(sourceNodeOfs);\n\n            if (sourceNodeId == 0) {\n                return; // It doesn't make sense to add \"Thread\" nodes to the reverse tree\n            }\n\n            boolean matchingChildFound = false;\n\n            if (i < stackTopIdx) { // sourceNodeOfs is some intermediate node\n\n                PrestimeCPUCCTNodeFree[] curNodeChildren = (PrestimeCPUCCTNodeFree[]) curNode.getChildren();\n\n                if (curNodeChildren != null) {\n                    for (PrestimeCPUCCTNodeFree curNodeChildren1 : curNodeChildren) {\n                        if (curNodeChildren1.getMethodId() == sourceNodeId) {\n                            curNode = curNodeChildren1;\n                            if (curNode.isContextCallsNode()) { // Skip the \"context calls\" node if it exists\n\n                                int prevSourceNodeOfs = nodeStack[i + 1];\n                                mergeBySelfTime(curNode, prevSourceNodeOfs);\n                                curNode = (PrestimeCPUCCTNodeFree) curNode.getChildren()[0];\n                            }\n\n                            mergeBySelfTime(curNode, sourceNodeOfs);\n                            matchingChildFound = true;\n\n                            break;\n                        }\n                    }\n                }\n            } else { // sourceNode is the topmost stack node\n                curNode = reverseCCTRootNode;\n\n                if (curNode == null) {\n                    curNode = createChildlessCopyBySelfTime(sourceNodeOfs);\n                    reverseCCTRootNode = curNode;\n                } else {\n                    mergeBySelfTime(curNode, sourceNodeOfs);\n                }\n\n                matchingChildFound = true;\n            }\n\n            if (!matchingChildFound) { // sourceNode may only be an intermediate node\n\n                PrestimeCPUCCTNodeFree newNode = createChildlessCopyBySelfTime(sourceNodeOfs);\n                PrestimeCPUCCTNodeFree[] curNodeChildren = (PrestimeCPUCCTNodeFree[]) curNode.getChildren();\n\n                if (curNodeChildren != null) {\n                    // For the given node, add an intermediate \"context calls\" node. If previously there was just one child,\n                    // insert another \"context calls\" node for it.\n                    int prevSourceNodeOfs = nodeStack[i + 1];\n\n                    if (curNodeChildren.length == 1) { // Insert a context node for the already existing single child\n\n                        PrestimeCPUCCTNodeFree origFirstChild = curNodeChildren[0];\n                        PrestimeCPUCCTNodeFree ccNode = curNode.createChildlessCopy();\n                        subtractNodeDataBySelfTime(ccNode, prevSourceNodeOfs); // Undo the results of merging with the parent of sourceNode\n                        ccNode.setMethodId(origFirstChild.getMethodId());\n                        ccNode.setContextCallsNode();\n                        curNodeChildren[0] = ccNode;\n                        ccNode.parent = curNode;\n                        ccNode.addChild(origFirstChild);\n                        origFirstChild.parent = ccNode;\n                    }\n\n                    PrestimeCPUCCTNodeFree ccNode = createChildlessCopyBySelfTime(prevSourceNodeOfs);\n                    ccNode.setMethodId(getMethodIdForNodeOfs(sourceNodeOfs));\n                    ccNode.setContextCallsNode();\n                    curNode.addChild(ccNode);\n                    ccNode.parent = curNode;\n                    curNode = ccNode;\n                }\n\n                curNode.addChild(newNode);\n                newNode.parent = curNode;\n                curNode = newNode;\n            }\n        }\n    }\n\n    /**\n     * After presentation-time CCT is generated, calculate various special time values stored in this instance\n     */\n    private void calculateThreadActiveTimesInMS(double[] threadActiveTimesInCounts) {\n        //!!! Delete this comment after deciding what to do with the whole issue.\n        // In the code below, '+=' is caused by the fact that this method may be called multiple times when in getRootNode() we\n        // generate CCTs for all threads. In the default single-thread case the real value is just added to the initial zero value.\n        wholeGraphGrossTimeAbs = (long) threadActiveTimesInCounts[0];\n        wholeGraphGrossTimeThreadCPU = (long) threadActiveTimesInCounts[1];\n        timeInInjectedCodeInAbsCounts = threadActiveTimesInCounts[2];\n        timeInInjectedCodeInThreadCPUCounts = threadActiveTimesInCounts[3];\n\n        wholeGraphGrossTimeAbsInMS += ((wholeGraphGrossTimeAbs * 1000.0) / timingAdjuster.getInstrTimingData().timerCountsInSecond0);\n        timeInInjectedCodeInMS += ((timeInInjectedCodeInAbsCounts * 1000.0) / timingAdjuster.getInstrTimingData().timerCountsInSecond0);\n\n        // Note that here we have to use status.timerCountsInSecond[x] explicitly instead of timerCountsInSecond0/1 (which may correspond to wrong time type)\n        wholeGraphPureTimeAbs += (int) ((((double) wholeGraphGrossTimeAbs - timeInInjectedCodeInAbsCounts) * 1000000) / timingAdjuster.getInstrTimingData().timerCountsInSecond1);\n\n        //System.err.println(\"*** wholeGraphTimeAbs gross (cnts) = \" + wholeGraphGrossTimeAbs + \", pure (mcs) = \" + wholeGraphPureTimeAbs);\n        if (wholeGraphGrossTimeThreadCPU > 0) { // Otherwise it means we couldn't calculate it and it shouldn't be displayed\n            displayWholeThreadCPUTime = true;\n            wholeGraphPureTimeThreadCPU += (int) ((((double) wholeGraphGrossTimeThreadCPU - timeInInjectedCodeInThreadCPUCounts) * 1000000) / timingAdjuster.getInstrTimingData().timerCountsInSecond1);\n\n            //System.err.println(\"*** wholeGraphTimeThreadCPU gross (cnts) = \" + wholeGraphGrossTimeThreadCPU + \", pure (mcs) = \" + wholeGraphPureTimeThreadCPU);\n            //System.err.println(\"*** timeInInjectedCode (mcs) = \" + (timeInInjectedCodeInAbsCounts * 1000000 / status.timerCountsInSecond[0]));\n        } else {\n            displayWholeThreadCPUTime = false;\n        }\n\n        // Take measures in case timer's low resolution has caused funny results\n        if (wholeGraphPureTimeAbs < 0) {\n            wholeGraphPureTimeAbs = 0;\n        }\n\n        if (wholeGraphPureTimeThreadCPU < 0) {\n            wholeGraphPureTimeThreadCPU = 0;\n        }\n\n        wholeGraphNetTime0 += get5Bytes(0 + OFS_TIME0);\n\n        if (collectingTwoTimeStamps) {\n            wholeGraphNetTime1 += get5Bytes(0 + OFS_TIME1);\n        }\n    }\n\n    private PrestimeCPUCCTNodeFree createChildlessCopyBySelfTime(int sourceNodeDataOfs) {\n        PrestimeCPUCCTNodeFree node = new PrestimeCPUCCTNodeFree(this, null, getMethodIdForNodeOfs(sourceNodeDataOfs));\n        mergeBySelfTime(node, sourceNodeDataOfs);\n\n        return node;\n    }\n\n    //  private long threadTimeCompensation0, threadTimeCompensation1;\n    private TimedCPUCCTNode filterCCT(final TimedCPUCCTNode rootNode) {\n        TimedCPUCCTNode newRoot = (TimedCPUCCTNode) rootNode.clone();\n\n        //    threadTimeCompensation0 = threadTimeCompensation1 = 0;\n        int nChildren = (rootNode.getChildren() != null) ? rootNode.getChildren().length : 0;\n\n        for (int i = 0; i < nChildren; i++) {\n            addChild(new AddChildLocalVars((TimedCPUCCTNode) rootNode.getChildren()[i], newRoot));\n        }\n\n        //    long time0, time1;\n        //    time0 = newRoot.getNetTime0() - threadTimeCompensation0;\n        newRoot.setNetTime0(0);\n\n        if (collectingTwoTimeStamps) {\n            //      time1 = newRoot.getNetTime1() - threadTimeCompensation1;\n            newRoot.setNetTime1(0);\n        }\n\n        return newRoot;\n    }\n\n    private void generateCompactData(TimedCPUCCTNode rootNode, int nNodes) {\n        nodeSize = collectingTwoTimeStamps ? OFS_SUBNODE02 : OFS_SUBNODE01;\n        childOfsSize = CHILD_OFS_SIZE_3;\n\n        int arraySize = (nodeSize * nNodes) + (childOfsSize * (nNodes - 1)); // For each node, except the root one, there is a parent node that references it with childOfsSize bytes long offset\n\n        if (arraySize > 0xFFFFFF) { // compactData is to big to use 3 bytes subnode offsets\n            childOfsSize = CHILD_OFS_SIZE_4;\n            arraySize = (nodeSize * nNodes) + (childOfsSize * (nNodes - 1));\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"generateCompact data: nNodes {0}\", nNodes); // NOI18N\n            LOGGER.log(Level.FINEST, \"generateCompact data: node size {0}\", nodeSize); // NOI18N\n            LOGGER.log(Level.FINEST, \"generateCompact data: array size {0}\", arraySize); // NOI18N\n            LOGGER.log(Level.FINEST, \"generateCompact data: child offset {0}\", childOfsSize); // NOI18N\n        }\n\n        compactData = new byte[arraySize];\n\n        rootNode = filterCCT(rootNode);\n        generateMirrorNode(new GenerateMirrorNodeLocalVars(rootNode, 0));\n    }\n\n    /**\n     * Generates an equivalent of rtNode in the compact data. Returns the offset right after the last generated node, which\n     * is this node if it has no children, or the last recursive child of this node.\n     */\n    private int generateMirrorNode(GenerateMirrorNodeLocalVars locals) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"Generate mirror node for ofs: {0}, node: {1}\", new Object[]{locals.dataOfs, locals.rtNode}); // NOI18N\n        }\n\n        generateNodeBase(locals.rtNode, locals.dataOfs);\n\n        totalInvNo += locals.rtNode.getNCalls();\n\n        locals.nodeChildren = locals.rtNode.getChildren();\n\n        locals.nChildren = (locals.nodeChildren != null) ? locals.nodeChildren.length : 0;\n        locals.nextNodeOfs = locals.dataOfs + nodeSize + (locals.nChildren * childOfsSize);\n\n        locals.nCallsFromThisNode += locals.rtNode.getNCallsDiff();\n\n        if (locals.nChildren > 0) {\n            locals.childCounter = 0;\n\n            for (locals.i = 0; locals.i < locals.nChildren; locals.i++) {\n                locals.aNode = (RuntimeCPUCCTNode)locals.nodeChildren[locals.i];\n\n                if (locals.aNode instanceof MethodCPUCCTNode) { // TODO replace \"instanceof\" by a visitor implementation\n                    setChildOfsForNodeOfs(locals.dataOfs, locals.childCounter, locals.nextNodeOfs);\n                    locals.nextNodeOfs = generateMirrorNode(new GenerateMirrorNodeLocalVars((MethodCPUCCTNode) locals.aNode, locals.nextNodeOfs));\n\n                    locals.thisNodeTotalTime0InTimerUnits += childTotalTime0InTimerUnits; // Completely uncleansed time\n\n                    if (collectingTwoTimeStamps) {\n                        locals.thisNodeTotalTime1InTimerUnits += childTotalTime1InTimerUnits; // Ditto\n                    }\n\n                    locals.nCallsFromThisNode += ((MethodCPUCCTNode) locals.aNode).getNCalls();\n                    locals.totalNCallsFromThisNode += childTotalNCalls;\n                    locals.childCounter++;\n                }\n            }\n        }\n\n        // Calculate cleansed self time\n        /* PROTOTYPE [wait]\n           long time = (long) (((double) rtNode.netTime0 - rtNode.waitTime0 - rtNode.nCalls * timingData.methodEntryExitInnerTime0 - nCallsFromThisNode * timingData.methodEntryExitOuterTime0) * 1000000 / timingData.timerCountsInSecond0);\n         */\n        locals.time = (long) timingAdjuster.adjustTime(locals.rtNode.getNetTime0(), locals.rtNode.getNCalls()+locals.rtNode.getNCallsDiff(), locals.nCallsFromThisNode, false);\n\n        //    (long) (((double) rtNode.getNetTime0() - rtNode.getNCalls() * timingData.methodEntryExitInnerTime0\n        //      - nCallsFromThisNode * timingData.methodEntryExitOuterTime0) * 1000000 / timingData\n        //      .timerCountsInSecond0);\n        if (locals.time < 0) {\n            // It may happen that for some very short methods the resulting time, after subtracting the instrumentation time, gets negative.\n            // When I calculated some concrete results using the (now-commented) code below, it appeared that for such methods the net\n            // time per call, in timer counts, is in the order of -0.1.. -0.2. In other words, it's a very small error caused by the\n            // hi-res timer (on Windows at least) being still too coarse-grain if just a few machine instructions are to be measured; and\n            // possibly insufficient precision of our advanced determination of instrumentation time.\n            // Setting the result to zero seems reasonable in this situation.\n            //if (nCallsFromThisNode == 0) {\n            // Net time per call, in counts\n            //double ntpc = ((double)cgNode.netTime - thisNode.nCalls * methodEntryExitInnerTime - nCallsFromThisNode * methodEntryExitOuterTime) / thisNode.nCalls;\n            //System.out.println(\"*** N: id= \" + thisNode.methodId + \", cls= \" + thisNode.nCalls + \", netTime= \" + cgNode.netTime + \", nCFrom= \" + nCallsFromThisNode + \", res = \" + thisNode.netTime + \", ntpc = \" + ntpc);\n            //}\n            locals.time = 0;\n        }\n\n        setSelfTime0ForNodeOfs(locals.dataOfs, locals.time);\n        setWaitTime0ForNodeOfs(locals.dataOfs, locals.rtNode.getWaitTime0());\n        setSleepTime0ForNodeOfs(locals.dataOfs, locals.rtNode.getSleepTime0());\n\n        locals.thisNodeTotalTime0InTimerUnits += locals.rtNode.getNetTime0(); // Uncleansed time for this node and all its children\n        childTotalTime0InTimerUnits = locals.thisNodeTotalTime0InTimerUnits; // It will be effectively returned by this method\n                                                                      // Calculate cleansed total time\n\n        locals.time = (long) timingAdjuster.adjustTime(locals.thisNodeTotalTime0InTimerUnits, locals.rtNode.getNCalls()+locals.totalNCallsFromThisNode, locals.totalNCallsFromThisNode,\n                                                   false);\n\n        //    time = (long) (((double) thisNodeTotalTime0InTimerUnits - rtNode.getNCalls()* timingData.methodEntryExitInnerTime0\n        //      - totalNCallsFromThisNode * timingData.methodEntryExitCallTime0) * 1000000 / timingData\n        //      .timerCountsInSecond0);\n        if (locals.time < 0) {\n            //System.out.println(\"*** Negative: \" + thisNode.totalTime0 + \", thisNCalls = \" + thisNode.nCalls + \", fromNCalls = \" + totalNCallsFromThisNode);\n            locals.time = 0;\n        }\n\n        setTotalTime0ForNodeOfs(locals.dataOfs, locals.time);\n\n        if (collectingTwoTimeStamps) {\n            // Calculate cleansed self time\n            locals.time = (long) timingAdjuster.adjustTime(locals.rtNode.getNetTime1(), locals.rtNode.getNCalls()+locals.rtNode.getNCallsDiff(), locals.nCallsFromThisNode, true);\n\n            //      time = (long) (((double) rtNode.getNetTime1()\n            //        - rtNode.getNCalls() * timingData.methodEntryExitInnerTime1\n            //        - nCallsFromThisNode * timingData.methodEntryExitOuterTime1) * 1000000 / timingData\n            //        .timerCountsInSecond1);\n            if (locals.time < 0) {\n                locals.time = 0;\n            }\n\n            setSelfTime1ForNodeOfs(locals.dataOfs, locals.time);\n            locals.thisNodeTotalTime1InTimerUnits += locals.rtNode.getNetTime1();\n            childTotalTime1InTimerUnits = locals.thisNodeTotalTime1InTimerUnits; // It will be effectively returned by this method\n                                                                          // Calculate cleansed total time\n\n            locals.time = (long) timingAdjuster.adjustTime(locals.thisNodeTotalTime1InTimerUnits, locals.rtNode.getNCalls()+locals.totalNCallsFromThisNode,\n                                                       locals.totalNCallsFromThisNode, true);\n\n            //      time = (long) (((double) thisNodeTotalTime1InTimerUnits - rtNode.getNCalls() * timingData.methodEntryExitInnerTime0\n            //        - totalNCallsFromThisNode * timingData.methodEntryExitCallTime1) * 1000000 / timingData\n            //        .timerCountsInSecond1);\n            if (locals.time < 0) {\n                locals.time = 0;\n            }\n\n            setTotalTime1ForNodeOfs(locals.dataOfs, locals.time);\n        }\n\n        childTotalNCalls = locals.totalNCallsFromThisNode + locals.rtNode.getNCalls(); // It will be effectively returned by this method\n\n        return locals.nextNodeOfs;\n    }\n\n    private static class GenerateMirrorNodeLocalVars {\n        private final TimedCPUCCTNode rtNode;\n        private final int dataOfs;\n        private long thisNodeTotalTime0InTimerUnits;\n        private long thisNodeTotalTime1InTimerUnits;\n        private int nCallsFromThisNode;\n        private int totalNCallsFromThisNode;\n        private RuntimeCCTNode[] nodeChildren;\n        private int nChildren;\n        private int nextNodeOfs;\n        private int childCounter;\n        private int i;\n        private RuntimeCPUCCTNode aNode;\n        private long time;\n        \n        private GenerateMirrorNodeLocalVars(TimedCPUCCTNode node, int off) {\n            rtNode = node;\n            dataOfs = off;\n        } \n    }\n    \n    private void generateNodeBase(TimedCPUCCTNode rtNode, int nodeDataOfs) {\n        int methodId = (rtNode instanceof MethodCPUCCTNode) ? ((MethodCPUCCTNode) rtNode).getMethodId() : 0;\n        int nCalls = rtNode.getNCalls();\n        int nChildren = (rtNode.getChildren() != null) ? rtNode.getChildren().length : 0;\n\n        setMethodIdForNodeOfs(nodeDataOfs, methodId);\n        setNCallsForNodeOfs(nodeDataOfs, nCalls);\n        setNChildrenForNodeOfs(nodeDataOfs, nChildren);\n    }\n\n    private void mergeBySelfTime(PrestimeCPUCCTNodeFree curNode, int sourceNodeDataOfs) {\n        curNode.addNCalls(getNCallsForNodeOfs(sourceNodeDataOfs));\n        curNode.addTotalTime0(getSelfTime0ForNodeOfs(sourceNodeDataOfs));\n\n        if (collectingTwoTimeStamps) {\n            curNode.addTotalTime1(getSelfTime1ForNodeOfs(sourceNodeDataOfs));\n        }\n\n        curNode.addWaitTime0(getWaitTime0ForNodeOfs(sourceNodeDataOfs));\n        curNode.addSleepTime0(getSleepTime0ForNodeOfs(sourceNodeDataOfs));\n    }\n\n    private void subtractNodeDataBySelfTime(PrestimeCPUCCTNodeFree curNode, int sourceNodeDataOfs) {\n        curNode.addNCalls(-getNCallsForNodeOfs(sourceNodeDataOfs));\n        curNode.addTotalTime0(-getSelfTime0ForNodeOfs(sourceNodeDataOfs));\n\n        if (collectingTwoTimeStamps) {\n            curNode.addTotalTime1(-getSelfTime1ForNodeOfs(sourceNodeDataOfs));\n        }\n\n        curNode.addWaitTime0(-getWaitTime0ForNodeOfs(sourceNodeDataOfs)); // TODO: [wait] what is this?\n        curNode.addSleepTime0(-getSleepTime0ForNodeOfs(sourceNodeDataOfs)); // TODO: [wait] what is this?\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/CPUCCTProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.results.CCTProvider;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface CPUCCTProvider extends CCTProvider {\n    public static interface Listener extends CCTProvider.Listener {\n    }\n\n    /**\n     * Generate the presentation CCTs for all threads that are currently profiled. Returns an array of all generated CPUCCTContainers\n     * (which accidentally may contain just 0 elements, if none of the created threads actually have any data at this time).\n     */\n    CPUCCTContainer[] createPresentationCCTs(CPUResultsSnapshot cpuSnapshot);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/CPUCallGraphBuilder.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.ResourceBundle;\nimport java.util.logging.Level;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ProfilingPointsProcessor;\nimport org.graalvm.visualvm.lib.jfluid.client.RuntimeProfilingPoint;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.marker.Mark;\nimport org.graalvm.visualvm.lib.jfluid.results.BaseCallGraphBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNodeProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MarkedCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MethodCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.RuntimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.ServletRequestCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.SimpleCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.ThreadCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.TimedCPUCCTNode;\n\n\n/**\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Jaroslav Bachorik\n */\npublic class CPUCallGraphBuilder extends BaseCallGraphBuilder implements CPUProfilingResultListener, CPUCCTProvider {\n\n    private class DebugInfoCollector extends RuntimeCCTNodeProcessor.PluginAdapter {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private StringBuffer buffer = new StringBuffer();\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        DebugInfoCollector() {\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public StringBuffer getBuffer() {\n            return buffer;\n        }\n\n        public synchronized String getInfo(RuntimeCPUCCTNode node) {\n            buffer = new StringBuffer();\n            RuntimeCCTNodeProcessor.process(node, this);\n\n            return buffer.toString();\n        }\n\n        @Override\n        public void onNode(MethodCPUCCTNode node) {\n            buffer.append(debugMethod(node.getMethodId()));\n        }\n        @Override\n        public void onNode(ServletRequestCPUCCTNode node) {\n            buffer.append(\"Boundary\"); // NOI18N\n        }\n        \n        @Override\n        public void onNode(ThreadCPUCCTNode node) {\n            buffer.append(\"threadId = \").append(node.getThreadId()); // NOI18N\n        }\n        \n        @Override\n        public void onNode(MarkedCPUCCTNode node) {\n            buffer.append(\"Category \").append(node.getMark()); // NOI18N\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private DebugInfoCollector debugCollector = null;\n    private InstrumentationFilter instrFilter;\n    private boolean stackIntegrityViolationReported;\n    private long delta;\n\n    private MethodInfoMapper methodInfoMapper = MethodInfoMapper.DEFAULT;\n    private TimingAdjusterOld timingAdjuster = TimingAdjusterOld.getDefault();\n    final private ThreadInfos threadInfos = new ThreadInfos();\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public CPUCCTContainer[] createPresentationCCTs(CPUResultsSnapshot cpuSnapshot) {\n        threadInfos.beginTrans(false);\n\n        try {\n            // process the ThreadInfo data structure to create a CCT presentation\n            String[] threadNames = threadInfos.getThreadNames();\n\n            // There is a chance that the data has not been initialized yet\n            if (threadNames == null) {\n                return null;\n            }\n\n            int len = threadNames.length;\n\n            if (len == 0) {\n                return null;\n            }\n\n            List ccts = new ArrayList(len);\n\n            for (int i = 0; i < len; i++) {\n                ThreadInfo ti = threadInfos.threadInfos[i];\n\n                if ((ti == null) || (ti.stack[0] == null)) {\n                    continue; // Can happen if thread just created, but nothing has been executed on its behalf yet\n                }\n\n                // Fix the problem with inconsistent thread times that otherwise will occur for e.g. threads sitting in wait()\n                // for long enough time when \"get results\" is pressed\n                applyDiffAtGetResultsMoment(ti);\n                double[] activeTimes = calculateThreadActiveTimes(ti);\n\n                TimedCPUCCTNode rootNode = ti.stack[0];\n\n                CPUCCTContainer cct = new CPUCCTContainer(rootNode, cpuSnapshot, methodInfoMapper, timingAdjuster, \n                                                          instrFilter, ti.totalNNodes, activeTimes, ti.threadId, threadNames[i]);\n\n                if ((cct.rootNode != null) && (cct.rootNode.getNChildren() > 0)) {\n                    ccts.add(cct);\n                }\n                undoDiffAtGetResultsMoment(ti);\n            }\n\n            return (CPUCCTContainer[]) ccts.toArray(new CPUCCTContainer[0]);\n        } finally {\n            threadInfos.endTrans();\n        }\n    }\n\n    public void setMethodInfoMapper(MethodInfoMapper mapper) {\n        this.methodInfoMapper = mapper != null ? mapper : MethodInfoMapper.DEFAULT;\n    }\n\n    protected boolean isCollectingTwoTimeStamps() {\n        return status.collectingTwoTimeStamps();\n    }\n\n    /** See the comment to ThreadInfo.diffAtGetResultsMoment field. */\n    protected void applyDiffAtGetResultsMoment(ThreadInfo ti) {\n    }\n\n    /**\n     * See the comment to ThreadInfo.diffAtGetResultsMoment field. When we resume data processing for the given thread,\n     * we need to undo the effect of applyDiffAtGetResultsMoment.\n     */\n    protected void undoDiffAtGetResultsMoment(ThreadInfo ti) {\n    }\n\n    protected long getDumpAbsTimeStamp() {\n        return status.dumpAbsTimeStamp;\n    }\n\n    public void methodEntry(final int methodId, final int threadId, final int methodType, final long timeStamp0,\n                            final long timeStamp1, final List parameters, int[] methodIds) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo ti = threadInfos.threadInfos[threadId];\n\n        if (ti == null) {\n            return;\n        }\n\n        switch (methodType) {\n            case METHODTYPE_NORMAL: {\n                plainMethodEntry(methodId, ti, timeStamp0, timeStamp1);\n\n                break;\n            }\n            case METHODTYPE_ROOT: {\n                rootMethodEntry(methodId, ti, timeStamp0, timeStamp1);\n\n                break;\n            }\n            case METHODTYPE_MARKER: {\n                markerMethodEntry(methodId, ti, timeStamp0, timeStamp1, parameters, methodIds);\n\n                break;\n            }\n        }\n\n        batchNotEmpty = true;\n    }\n\n    public void methodEntryUnstamped(final int methodId, final int threadId, final int methodType, final List parameters, final int[] methodIds) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo ti = threadInfos.threadInfos[threadId];\n\n        if (ti == null) {\n            return;\n        }\n\n        switch (methodType) {\n            case METHODTYPE_NORMAL: {\n                plainMethodEntry(methodId, ti);\n\n                break;\n            }\n            case METHODTYPE_MARKER: {\n                markerMethodEntry(methodId, ti, parameters, methodIds);\n\n                break;\n            }\n        }\n\n        batchNotEmpty = true;\n    }\n\n    public void methodExit(final int methodId, final int threadId, final int methodType, final long timeStamp0,\n                           final long timeStamp1, final Object retVal) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo ti = threadInfos.threadInfos[threadId];\n\n        if (ti == null) {\n            return;\n        }\n\n        TimedCPUCCTNode oldNode = null;\n\n        switch (methodType) {\n            case METHODTYPE_MARKER:\n            case METHODTYPE_NORMAL: {\n                oldNode = plainMethodExit(methodId, ti, timeStamp0, timeStamp1);\n\n                break;\n            }\n            case METHODTYPE_ROOT: {\n                oldNode = rootMethodExit(methodId, ti, timeStamp0, timeStamp1);\n\n                break;\n            }\n        }\n\n        if (oldNode != null) {\n            TimedCPUCCTNode oneMoreNode = ti.peek();\n\n            // category must go with a method node; so close them together\n            if (oneMoreNode instanceof MarkedCPUCCTNode) {\n                //        oneMoreNode.addNCalls(oldNode.getNCalls());\n                //        oneMoreNode.addNetTime0(oldNode.getNetTime0());\n                //        oneMoreNode.addNetTime1(oldNode.getNetTime1());\n                //        oneMoreNode.addSleepTime0(oldNode.getSleepTime0());\n                //        oneMoreNode.addWaitTime0(oldNode.getWaitTime0());\n                ti.pop();\n                oneMoreNode = ti.peek();\n            }\n            // Servelt node must go with a method node; so close them together\n            if (oneMoreNode instanceof ServletRequestCPUCCTNode) {\n                //        oneMoreNode.addNCalls(oldNode.getNCalls());\n                //        oneMoreNode.addNetTime0(oldNode.getNetTime0());\n                //        oneMoreNode.addNetTime1(oldNode.getNetTime1());\n                //        oneMoreNode.addSleepTime0(oldNode.getSleepTime0());\n                //        oneMoreNode.addWaitTime0(oldNode.getWaitTime0());\n                ti.pop();\n            }        \n        }\n\n        batchNotEmpty = true;\n    }\n\n    public void methodExitUnstamped(final int methodId, final int threadId, final int methodType) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo ti = threadInfos.threadInfos[threadId];\n\n        if (ti == null) {\n            return;\n        }\n\n        TimedCPUCCTNode oldNode = null;\n\n        switch (methodType) {\n            case METHODTYPE_MARKER:\n            case METHODTYPE_NORMAL: {\n                oldNode = plainMethodExit(methodId, ti);\n\n                break;\n            }\n        }\n\n        if (oldNode != null) {\n            TimedCPUCCTNode oneMoreNode = ti.peek();\n\n            // category must go with a method node; so close them together\n            if (oneMoreNode instanceof MarkedCPUCCTNode) {\n                //        oneMoreNode.addNCalls(oldNode.getNCalls());\n                //        oneMoreNode.addNetTime0(oldNode.getNetTime0());\n                //        oneMoreNode.addNetTime1(oldNode.getNetTime1());\n                //        oneMoreNode.addSleepTime0(oldNode.getSleepTime0());\n                //        oneMoreNode.addWaitTime0(oldNode.getWaitTime0());\n                ti.pop();\n                oneMoreNode = ti.peek();\n            }\n            // Servelt node must go with a method node; so close them together\n            if (oneMoreNode instanceof ServletRequestCPUCCTNode) {\n                //        oneMoreNode.addNCalls(oldNode.getNCalls());\n                //        oneMoreNode.addNetTime0(oldNode.getNetTime0());\n                //        oneMoreNode.addNetTime1(oldNode.getNetTime1());\n                //        oneMoreNode.addSleepTime0(oldNode.getSleepTime0());\n                //        oneMoreNode.addWaitTime0(oldNode.getWaitTime0());\n                ti.pop();\n            }\n        }\n\n        batchNotEmpty = true;\n    }\n\n    public void monitorEntry(final int threadId, final long timeStamp0, final long timeStamp1, final int monitorId, int ownerThreadId) {\n        waitEntry(threadId, timeStamp0, timeStamp1);\n        batchNotEmpty = true;\n    }\n\n    public void monitorExit(final int threadId, final long timeStamp0, final long timeStamp1, final int monitorId) {\n        waitExit(threadId, timeStamp0, timeStamp1);\n        batchNotEmpty = true;\n    }\n\n    public void newThread(final int threadId, final String threadName, final String threadClassName) {\n        if (!isReady()) {\n            return;\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"New thread creation for thread id = {0}, name = {1}\", new Object[]{threadId, threadName});\n        }\n\n        threadInfos.newThreadInfo(threadId, threadName, threadClassName);\n        batchNotEmpty = true;\n    }\n\n    public void newMonitor(int hash, String className) {\n        if (!isReady()) {\n            return;\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"New monitor creation, mId = {0}, className = {1}\", new Object[]{Integer.toHexString(hash), className});\n        }\n    }\n\n    public void servletRequest(final int threadId, final int requestType, final String servletPath, final int sessionId) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n        \n        ThreadInfo ti = threadInfos.threadInfos[threadId];\n\n        if (ti == null) {\n            return;\n        }\n\n        TimedCPUCCTNode curNode = ti.peek();\n\n        if (curNode == null) {\n            curNode = new ThreadCPUCCTNode(threadId);\n            ti.totalNNodes++;\n            ti.push(curNode);\n            ti.totalNInv--;\n        }\n\n        ServletRequestCPUCCTNode servletNode = ServletRequestCPUCCTNode.Locator.locate(requestType, servletPath,\n                                                                                       curNode.getChildren());\n\n        if (servletNode == null) {\n            servletNode = new ServletRequestCPUCCTNode(requestType, servletPath);\n            curNode.attachNodeAsChild(servletNode);\n        }\n\n        ti.push(servletNode);\n    }\n\n    public void sleepEntry(final int threadId, long timeStamp0, long timeStamp1) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo ti = threadInfos.threadInfos[threadId];\n        TimedCPUCCTNode curNode = ti.peek();\n        if (curNode == null) {\n            return;\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"ENTRY SLEEP: \" // + debugNode(curNode) // NOI18N\n                          + \", time: \" + timeStamp0 // NOI18N\n                          + \", delta: \" + (timeStamp0 - delta) // NOI18N\n                          + \", tid: \" + ti.threadId // NOI18N\n                          );\n            delta = timeStamp0;\n        }\n\n        long diff = timeStamp0 - ti.topMethodEntryTime0;\n\n        if (diff > 0) {\n            curNode.addNetTime0(diff);\n        } else {\n            timeStamp0 = ti.topMethodEntryTime0;\n        }\n\n        ti.topMethodEntryTime0 = timeStamp0;\n\n        curNode.setLastWaitOrSleepStamp(timeStamp0);\n        batchNotEmpty = true;\n    }\n\n    public void sleepExit(final int threadId, final long timeStamp0, final long timeStamp1) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo ti = threadInfos.threadInfos[threadId];\n        TimedCPUCCTNode curNode = ti.peek();\n        if (curNode == null) {\n            return;\n        }\n\n        long lastSleep = timeStamp0 - curNode.getLastWaitOrSleepStamp();\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"EXIT SLEEP: \" //+ debugNode(curNode) // NOI18N\n                          + \", time: \" + timeStamp0 // NOI18N\n                          + \", delta: \" + (timeStamp0 - delta) // NOI18N\n                          + \", slept: \" + lastSleep // NOI18N\n                          + \", tid: \" + ti.threadId // NOI18N\n                          );\n            delta = timeStamp0;\n            lastSleep = 0;\n        }\n\n        curNode.setLastWaitOrSleepStamp(0);\n        curNode.addSleepTime0(lastSleep);\n\n        // move start timer for current method, so that the time spent sleeping is ignored\n        if ((timeStamp0 - ti.topMethodEntryTime0) > 0) {\n            ti.topMethodEntryTime0 = timeStamp0;\n        }\n\n        batchNotEmpty = true;\n    }\n\n    public void threadsResume(final long timeStamp0, final long timeStamp1) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo[] tis = threadInfos.threadInfos;\n\n        for (ThreadInfo ti : tis) {\n            if ((ti == null) || (ti.stackTopIdx < 0)) {\n                continue;\n            }\n\n            ti.topMethodEntryTime0 = timeStamp0;\n\n            if (isCollectingTwoTimeStamps()) {\n                ti.topMethodEntryTime1 = timeStamp1;\n            }\n\n            if (isCollectingTwoTimeStamps()) {\n                ti.rootMethodEntryTimeAbs = timeStamp0;\n                ti.rootMethodEntryTimeThreadCPU = timeStamp1;\n            } else {\n                ti.rootMethodEntryTimeAbs = timeStamp0;\n\n                // rootMethodEntryTimeThreadCPU can remain the same - thread was suspended and time wasn't increasing\n            }\n        }\n\n        batchNotEmpty = true;\n    }\n\n    public void threadsSuspend(final long timeStamp0, final long timeStamp1) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo[] tis = threadInfos.threadInfos;\n\n        for (ThreadInfo ti : tis) {\n            if ((ti == null) || (ti.stackTopIdx < 0)) {\n                continue;\n            }\n\n            TimedCPUCCTNode curNode = ti.stack[ti.stackTopIdx];\n\n            long diff = timeStamp0 - ti.topMethodEntryTime0;\n\n            if (diff > 0) {\n                curNode.addNetTime0(diff);\n            }\n\n            if (isCollectingTwoTimeStamps()) {\n                ti.rootGrossTimeAbs += (timeStamp0 - ti.rootMethodEntryTimeAbs);\n                diff = timeStamp1 - ti.topMethodEntryTime1;\n\n                if (diff > 0) {\n                    curNode.addNetTime1(diff);\n                }\n\n                ti.rootGrossTimeThreadCPU += (timeStamp1 - ti.rootMethodEntryTimeThreadCPU);\n            } else { // Collecting only absolute timestamps\n                ti.rootGrossTimeAbs += (timeStamp0 - ti.rootMethodEntryTimeAbs);\n\n                // Shouldn't do anything with rootGrossTimeThreadCPU, since while thread is suspended,\n                // thread CPU time is stopped\n            }\n        }\n\n        batchNotEmpty = true;\n    }\n    \n    public void profilingPoint(final int threadId, final int ppId, final long timeStamp) {\n        ProfilerClient client = getClient();\n\n        if (client == null) {\n            return;\n        }\n\n        final ProfilingPointsProcessor ppp = client.getProfilingPointsProcessor();\n\n        afterBatchCommands.add(new Runnable() {\n            public void run() {\n                ppp.profilingPointHit(new RuntimeProfilingPoint.HitEvent(ppId, timeStamp, threadId));\n            }\n        });\n    }\n\n    /**\n     * Called when the TA is suspended waiting for the tool to process the buffer\n     */\n    public void timeAdjust(final int threadId, final long timeDiff0, final long timeDiff1) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo ti = threadInfos.threadInfos[threadId];\n\n        // In this case, time stamps are actually time adjustments.\n        // timeStamp0 is always abosolute and timeStamp1 is always thread CPU.\n        ti.rootMethodEntryTimeAbs += timeDiff0;\n        ti.rootMethodEntryTimeThreadCPU += timeDiff1;\n        ti.topMethodEntryTime0 += timeDiff0;\n\n        if (isCollectingTwoTimeStamps()) {\n            ti.topMethodEntryTime1 += timeDiff1;\n        }\n\n        ProfilerClient client = getClient();\n        if (client != null) {\n            final ProfilingPointsProcessor ppp = client.getProfilingPointsProcessor();\n            if (ppp != null) {\n                afterBatchCommands.add(new Runnable() {\n                    public void run() {\n                        ppp.timeAdjust(threadId, timeDiff0, timeDiff1);\n                    }\n                });\n            }\n        }\n        batchNotEmpty = true;\n    }\n\n    public void waitEntry(final int threadId, long timeStamp0, long timeStamp1) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo ti = threadInfos.threadInfos[threadId];\n        TimedCPUCCTNode curNode = ti.peek();\n        if (curNode == null) {\n            return;\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"ENTRY WAIT: \" //+ debugNode(curNode) // NOI18N\n                          + \", time: \" + timeStamp0 // NOI18N\n                          + \", delta: \" + (timeStamp0 - delta) // NOI18N\n                          + \", tid: \" + ti.threadId // NOI18N\n                          );\n            delta = timeStamp0;\n            //LOGGER.finest(dumpStack(ti));\n        }\n\n        long diff = timeStamp0 - ti.topMethodEntryTime0;\n\n        if (diff > 0) {\n            curNode.addNetTime0(diff);\n        } else {\n            timeStamp0 = ti.topMethodEntryTime0;\n        }\n\n        ti.topMethodEntryTime0 = timeStamp0;\n\n        curNode.setLastWaitOrSleepStamp(timeStamp0);\n        batchNotEmpty = true;\n    }\n\n    public void waitExit(final int threadId, final long timeStamp0, final long timeStamp1) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo ti = threadInfos.threadInfos[threadId];\n        TimedCPUCCTNode curNode = ti.peek();\n        if (curNode == null) {\n            return;\n        }\n\n        long lastWait = timeStamp0 - curNode.getLastWaitOrSleepStamp();\n        curNode.setLastWaitOrSleepStamp(0);\n        curNode.addWaitTime0(lastWait);\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"EXIT WAIT: \" //+ debugNode(curNode) // NOI18N\n                          + \", time: \" + timeStamp0 // NOI18N\n                          + \", delta: \" + (timeStamp0 - delta) // NOI18N\n                          + \", waited: \" + lastWait // NOI18N\n                          + \", tid: \" + ti.threadId // NOI18N\n                          );\n            delta = timeStamp0;\n            //LOGGER.finest(dumpStack(ti));\n        }\n\n        // move start timer for current method, so that the time spent waiting is ignored\n        if ((timeStamp0 - ti.topMethodEntryTime0) > 0) {\n            ti.topMethodEntryTime0 = timeStamp0;\n        }\n\n        batchNotEmpty = true;\n    }\n\n    public void parkEntry(final int threadId, long timeStamp0, long timeStamp1) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo ti = threadInfos.threadInfos[threadId];\n        TimedCPUCCTNode curNode = ti.peek();\n        if (curNode == null) {\n            return;\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"ENTRY PARK: \" //+ debugNode(curNode) // NOI18N\n                          + \", time: \" + timeStamp0 // NOI18N\n                          + \", delta: \" + (timeStamp0 - delta) // NOI18N\n                          + \", tid: \" + ti.threadId // NOI18N\n                          );\n            delta = timeStamp0;\n            //LOGGER.finest(dumpStack(ti));\n        }\n\n        long diff = timeStamp0 - ti.topMethodEntryTime0;\n\n        if (diff > 0) {\n            curNode.addNetTime0(diff);\n        } else {\n            timeStamp0 = ti.topMethodEntryTime0;\n        }\n\n        ti.topMethodEntryTime0 = timeStamp0;\n\n        curNode.setLastWaitOrSleepStamp(timeStamp0);\n        batchNotEmpty = true;\n    }\n\n    public void parkExit(final int threadId, final long timeStamp0, final long timeStamp1) {\n        if (!isReady() || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo ti = threadInfos.threadInfos[threadId];\n        TimedCPUCCTNode curNode = ti.peek();\n        if (curNode == null) {\n            return;\n        }\n\n        long lastWait = timeStamp0 - curNode.getLastWaitOrSleepStamp();\n        curNode.setLastWaitOrSleepStamp(0);\n        curNode.addWaitTime0(lastWait);\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"EXIT PARK: \" //+ debugNode(curNode) // NOI18N\n                          + \", time: \" + timeStamp0 // NOI18N\n                          + \", delta: \" + (timeStamp0 - delta) // NOI18N\n                          + \", waited: \" + lastWait // NOI18N\n                          + \", tid: \" + ti.threadId // NOI18N\n                          );\n            delta = timeStamp0;\n            //LOGGER.finest(dumpStack(ti));\n        }\n\n        // move start timer for current method, so that the time spent park is ignored\n        if ((timeStamp0 - ti.topMethodEntryTime0) > 0) {\n            ti.topMethodEntryTime0 = timeStamp0;\n        }\n\n        batchNotEmpty = true;\n    }\n\n    /**\n     * For each monitored thread, returns the current absolute and thread-local CPU time. Returned thread-local time\n     * may be just -1, indicating that it can't be reliably calculated for the given thread (at this moment or at all).\n     */\n    protected long[][] getAllThreadsActiveTimes() {\n        int len = threadInfos.getThreadNames().length;\n        long[][] res = new long[2][len];\n\n        for (int i = 0; i < len; i++) {\n            ThreadInfo ti = threadInfos.threadInfos[i];\n            double[] times = calculateThreadActiveTimes(ti);\n\n            res[0][i] = (long) (((times[0] - times[2]) * 1000) / timingAdjuster.getInstrTimingData().timerCountsInSecond0);\n            res[1][i] = (times[1] != -1) ? (long) (((times[1] - times[3]) * 1000) / timingAdjuster.getInstrTimingData().timerCountsInSecond1) : (-1);\n        }\n\n        return res;\n    }\n\n    protected RuntimeCCTNode getAppRootNode() {\n        if (threadInfos.isEmpty()) {\n            return null;\n        }\n\n        RuntimeCPUCCTNode appNode = null;\n\n        threadInfos.beginTrans(false);\n\n        try {\n            ProfilerClient client = getClient();\n            if (client != null) {\n                appNode = new SimpleCPUCCTNode(client.getStatus().getNInstrMethods());                \n            } else {\n                appNode = new SimpleCPUCCTNode(true);\n            }\n\n            int len = (threadInfos.getThreadNames() != null) ? threadInfos.getThreadNames().length : 0;\n\n            for (int i = 0; i < len; i++) {\n                ThreadInfo ti = threadInfos.threadInfos[i];\n\n                if ((ti == null) || (ti.stack[0] == null)) {\n                    continue;\n                }\n\n                appNode.attachNodeAsChild(ti.stack[0]);\n            }\n        } finally {\n            threadInfos.endTrans();\n        }\n\n        return appNode;\n    }\n\n    //----------------------------- Calculation of supporting numeric data ---------------------------\n\n    /**\n     * For the given thread, calculate the following values (not all may be available, depending on the active timers and\n     * the current thread state (inside or outside the profiled call graph):\n     * absolute gross time, thread CPU gross time, time spent in instrumentation code in absolute counts, same time in\n     * thread-local time counts.\n     * The values are assigned to the relevant fields of cgm parameter (if it's not null), and returned as an array of\n     * doubles.\n     * NOTE THAT setMethodEntryExitTimesGivenCollectedTimeStampsKinds() SHOULD BE CALLED ONCE BEFORE CALLING THIS METHOD!\n     */\n    double[] calculateThreadActiveTimes(ThreadInfo ti) {\n        TimedCPUCCTNode rootNode = ti.stack[0];\n\n        if (rootNode == null) {\n            // May happen if thread just created, but nothing ran its behalf yet\n            return new double[] { 0, 0, 0, 0 };\n        }\n\n        // Now calculate and return gross times for the whole call subgraph.\n        // Note that absolute time is provided irrespective of the timers (absolute only, thread CPU only, or both) used\n        // for methods.\n        // Correct thread CPU time can be provided only if either thread CPU timer is used, or if execution is currently\n        // not within the call graph.\n        // If we can't provide a correct thread CPU time, we set cgm.wholeGraphGrossTimeThreadCPU to a negative value,\n        // indicating that this time should not be displayed at all.\n        long rootGrossTimeAbs = ti.rootGrossTimeAbs;\n\n        // System.err.println(\"\\n*** CPUCallGraphBuilder: rootGrossTimeAbs = \"\n        // + rootGrossTimeAbs + \", totalNInv = \" + ti.totalNInv);  // NOI18N\n        if (ti.stackTopIdx != -1) {\n            long time0 = getDumpAbsTimeStamp();\n\n            if (ti.topMethodEntryTime0 > time0) {\n                time0 = ti.topMethodEntryTime0;\n            }\n\n            rootGrossTimeAbs += (time0 - ti.rootMethodEntryTimeAbs);\n\n            //System.err.println(\"*** dumpAbsTimeStamp = \" + status.dumpAbsTimeStamp + \", ti.topMethodEntryTime0 = \"\n            // + ti.topMethodEntryTime0 + \", ti.rootMethodEntryTimeAbs = \" + ti.rootMethodEntryTimeAbs); // NOI18N\n            //System.err.println(\"*** Adjusted rootGrossTimeAbs = \" + rootGrossTimeAbs); // NOI18N\n        }\n\n        //System.err.println(\"*** rootGrossTimeAbs in ms = \" + ((double) rootGrossTimeAbs) * 1000 / status.timerCountsInSecond[0]); // NOI18N\n        long rootGrossTimeCPU = ti.rootGrossTimeThreadCPU;\n\n        //System.err.println(\"*** ti.rootGrossTimeThreadCPU = \" + ti.rootGrossTimeThreadCPU + \", totalNInv = \" + ti.totalNInv); // NOI18N\n        if (ti.stackTopIdx != -1) {\n            if (isCollectingTwoTimeStamps()) {\n                rootGrossTimeCPU += (ti.topMethodEntryTime1 - ti.rootMethodEntryTimeThreadCPU);\n\n                //System.err.println(\"*** ti.topMethodEntryTime1 = \" + ti.topMethodEntryTime1 + \", ti.rootMethodEntryTimeThreadCPU = \" + ti.rootMethodEntryTimeThreadCPU);\n                //System.err.println(\"*** adjustment for CPU time = \" + (ti.topMethodEntryTime1 - ti.rootMethodEntryTimeThreadCPU)); // NOI18N\n            } else {\n                rootGrossTimeCPU = -1;\n            }\n        }\n\n        //System.err.println(\"*** Adjusted rootGrossTimeCPU = \" + rootGrossTimeCPU + \", in ms = \" + ((double) rootGrossTimeCPU) * 1000 / status.timerCountsInSecond[1]); // NOI18N\n        int nRootInv = rootNode.getNCalls();\n        double timeInInjectedCodeInAbsCounts;\n        double timeInInjectedCodeInThreadCPUCounts = 0;\n        // Calculate timeInInjectedCodeInAbsCounts.\n        timeInInjectedCodeInAbsCounts = timingAdjuster.delta(nRootInv, (int) (ti.totalNInv - nRootInv), false);\n\n        //System.err.println(\"*** timeInInjectedCodeInAbsCounts = \" + timeInInjectedCodeInAbsCounts + \", in ms = \" + ((double) timeInInjectedCodeInAbsCounts) * 1000 / status.timerCountsInSecond[0]); // NOI18N\n\n        // Now calculate timeInInjectedCodeInThreadCPUCounts\n        if (isCollectingTwoTimeStamps()) {\n            timeInInjectedCodeInThreadCPUCounts = timingAdjuster.delta(nRootInv, (int) (ti.totalNInv - nRootInv), true);\n        } else { // Same calculation whether we have absoluteTimerOn == true or not\n                 // Just convert the known time into thread CPU time units\n            timeInInjectedCodeInThreadCPUCounts = (timeInInjectedCodeInAbsCounts * timingAdjuster.getInstrTimingData().timerCountsInSecond1) / timingAdjuster.getInstrTimingData().timerCountsInSecond0;\n        }\n\n        //System.err.println(\"*** timeInInjectedCodeInThreadCPUCounts = \" + timeInInjectedCodeInThreadCPUCounts); // NOI18N\n        return new double[] {\n                   (double) rootGrossTimeAbs, (double) rootGrossTimeCPU, timeInInjectedCodeInAbsCounts,\n                   timeInInjectedCodeInThreadCPUCounts\n               };\n    }\n\n    protected void doBatchStart() {\n        /****************************************************************************/\n        /* Timing adjuster must be initialized here as in doStartup() it may happen */\n        /* that the instrumentation type has not been set yet                       */\n        /****************************************************************************/\n        ProfilerClient client = getClient();\n        if (client != null) {\n            timingAdjuster = TimingAdjusterOld.getInstance(client.getStatus());\n        }\n        threadInfos.beginTrans(true);\n    }\n\n    protected void doBatchStop() {\n        threadInfos.endTrans();\n    }\n\n    protected void doReset() {\n        boolean threadLocked = threadInfos.beginTrans(true, true);\n\n        if (threadLocked) { // ignore request for reset received durin an ongoing active transaction\n\n            try {\n                threadInfos.reset();\n            } finally {\n                threadInfos.endTrans();\n            }\n        }\n    }\n\n    protected void doShutdown() {\n        threadInfos.reset();\n        instrFilter = null;\n    }\n\n    protected void doStartup(final ProfilerClient profilerClient) {\n        instrFilter = profilerClient.getSettings().getInstrumentationFilter();\n        \n        setMethodInfoMapper(new MethodInfoMapper() {\n            final private String INVALID_MID=ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.cpu.Bundle\").getString(\"MSG_INVALID_METHODID\"); // NOI18N\n            @Override\n            public String getInstrMethodClass(int methodId) {\n                String[] cNames = profilerClient.getStatus().getInstrMethodClasses();\n                if (methodId < cNames.length) {\n                    return cNames[methodId];\n                } else {\n                    LOGGER.log(Level.WARNING, INVALID_MID, new Object[]{methodId, cNames.length - 1});\n                    return null;\n                }\n            }\n\n            @Override\n            public String getInstrMethodName(int methodId) {\n                String[] mNames = profilerClient.getStatus().getInstrMethodNames();\n                if (methodId < mNames.length) {\n                    return mNames[methodId];\n                } else {\n                    LOGGER.log(Level.WARNING, INVALID_MID, new Object[]{methodId, mNames.length - 1});\n                    return null;\n                }\n            }\n\n            @Override\n            public String getInstrMethodSignature(int methodId) {\n                String[] sNames = profilerClient.getStatus().getInstrMethodSignatures();\n                if (methodId < sNames.length) {\n                    return sNames[methodId];\n                } else {\n                    LOGGER.log(Level.WARNING, INVALID_MID, new Object[]{methodId, sNames.length - 1});\n                    return null;\n                }\n            }\n\n            @Override\n            public int getMinMethodId() {\n                return 1;\n            }\n\n            @Override\n            public int getMaxMethodId() {\n                return profilerClient.getStatus().getNInstrMethods();\n            }\n\n            @Override\n            public void lock(boolean mutable) {\n                profilerClient.getStatus().beginTrans(mutable);\n            }\n\n            @Override\n            public void unlock() {\n                profilerClient.getStatus().endTrans();\n            }\n\n\n        });\n\n        profilerClient.registerCPUCCTProvider(this);\n    }\n\n    protected void setFilter(InstrumentationFilter filter) {\n        this.instrFilter = filter;\n    }\n\n    private synchronized DebugInfoCollector getDebugCollector() {\n        if (debugCollector == null) {\n            debugCollector = new DebugInfoCollector();\n        }\n\n        return debugCollector;\n    }\n\n    protected boolean isReady() {\n        return (status != null) && (instrFilter != null);\n    }\n\n    private String debugMethod(int methodId) {\n        StringBuilder buffer = new StringBuilder();\n        try {\n            methodInfoMapper.lock(false);\n\n            buffer.append(methodInfoMapper.getInstrMethodClass(methodId)).append('.').append(methodInfoMapper.getInstrMethodName(methodId)); // NOI18N\n            buffer.append(methodInfoMapper.getInstrMethodSignature(methodId)).append(\" (methodId = \").append(methodId).append(')'); // NOI18N\n        } finally {\n            methodInfoMapper.unlock();\n        }\n\n        return buffer.toString();\n    }\n\n    private String debugNode(RuntimeCPUCCTNode node) {\n        return getDebugCollector().getInfo(node);\n    }\n\n    private String dumpStack(ThreadInfo ti) {\n        StringBuilder buffer = new StringBuilder();\n        buffer.append(\"*** Thread stack dump:\\n\"); // NOI18N\n\n        for (int i = ti.stackTopIdx; i >= 0; i--) {\n            DebugInfoCollector collector = new DebugInfoCollector();\n            TimedCPUCCTNode frame = ti.stack[i];\n            RuntimeCCTNodeProcessor.process(frame, collector);\n            buffer.append(collector.getInfo(frame)).append('\\n'); // NOI18N\n        }\n\n        return buffer.toString();\n    }\n\n    private TimedCPUCCTNode markerMethodEntry(final int methodId, final ThreadInfo ti, long timeStamp0, long timeStamp1,\n                                              boolean stamped, List parameters, int[] methodIds) {\n//        Mark mark = MarkingEngine.getDefault().markMethod(methodId, status);\n        Mark mark = Mark.DEFAULT;\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"MarkerMEntry{0} for tId = {1}, time: {2}, method:  {3}, inRoot: {4}, rootEntryTimeThread: {5}\", new Object[]{(!stamped) ? \"(unstamped)\" : \"\", (int) ti.threadId, timeStamp0, debugMethod(methodId), ti.rootMethodEntryTimeAbs, ti.rootMethodEntryTimeThreadCPU});\n        }\n\n        TimedCPUCCTNode curNode = ti.peek();\n\n        if (curNode == null) {\n            TimedCPUCCTNode rootNode = new ThreadCPUCCTNode(ti.threadId);\n            ti.totalNNodes++;\n            ti.push(rootNode);\n            ti.totalNInv--;\n\n            if (!mark.isDefault()) {\n                curNode = new MarkedCPUCCTNode(mark);\n                rootNode.attachNodeAsChild(curNode);\n                ti.totalNNodes++;\n                ti.push(curNode);\n                rootNode = curNode;\n            }\n\n            curNode = new MethodCPUCCTNode(methodId);\n            rootNode.attachNodeAsChild(curNode);\n            ti.totalNNodes++;\n            ti.push(curNode);\n\n            ti.topMethodEntryTime0 = timeStamp0;\n\n            if (isCollectingTwoTimeStamps()) {\n                ti.topMethodEntryTime1 = timeStamp1;\n            }\n        } else {\n            if (stamped) {\n                long diff = timeStamp0 - ti.topMethodEntryTime0;\n\n                if (diff > 0) {\n                    curNode.addNetTime0(diff);\n                } else {\n                    timeStamp0 = ti.topMethodEntryTime0;\n                }\n\n                ti.topMethodEntryTime0 = timeStamp0;\n\n                if (isCollectingTwoTimeStamps()) {\n                    diff = timeStamp1 - ti.topMethodEntryTime1;\n\n                    if (diff > 0) {\n                        curNode.addNetTime1(diff);\n                    } else {\n                        timeStamp1 = ti.topMethodEntryTime1;\n                    }\n\n                    ti.topMethodEntryTime1 = timeStamp1;\n                }\n            }\n\n            TimedCPUCCTNode calleeNode;\n\n            if (!mark.isDefault()) {\n                // try to locate the category node; or create a new node for the category\n                calleeNode = MarkedCPUCCTNode.Locator.locate(mark, curNode.getChildren());\n\n                if (calleeNode == null) {\n                    calleeNode = new MarkedCPUCCTNode(mark);\n                    curNode.attachNodeAsChild(calleeNode);\n                    ti.totalNNodes++;\n                }\n\n                ti.push(calleeNode);\n                curNode = calleeNode;\n            }\n\n            // Now find the appropriate callee in this node or create one\n            calleeNode = MethodCPUCCTNode.Locator.locate(methodId, curNode.getChildren());\n\n            if (calleeNode == null) {\n                calleeNode = new MethodCPUCCTNode(methodId);\n                curNode.attachNodeAsChild(calleeNode);\n                ti.totalNNodes++;\n            }\n\n            ti.push(calleeNode);\n            curNode = calleeNode; // make the callee node be the current one\n        }\n\n        //    curNode.setMarkID(categoryId);\n        if (!ti.isInRoot()) { // not within root method CCT\n            curNode.setFilteredStatus(TimedCPUCCTNode.FILTERED_YES);\n\n            if (stamped) { // stamped marker method called before any root method; must set rootMethodEntryTimes\n                           // Be careful - with MARKER_ENTRY and MARKER_EXIT events, unlike with others, timeStamp0 is *always* absolute time,\n                           // and timeStamp1 is *always* thread CPU time\n                ti.rootMethodEntryTimeAbs = timeStamp0;\n                ti.rootMethodEntryTimeThreadCPU = timeStamp1;\n                ti.topMethodEntryTime0 = timeStamp0;\n\n                if (isCollectingTwoTimeStamps()) {\n                    ti.topMethodEntryTime1 = timeStamp1;\n                }\n            }\n        } else {\n            try {\n                methodInfoMapper.lock(false);\n                String jvmClassName = methodInfoMapper.getInstrMethodClass(((MethodCPUCCTNode) curNode).getMethodId()).replace('.', '/'); // NOI18N\n                ProfilerClient client = getClient();\n\n                if (client != null) {\n                    if (!client.getSettings().getInstrumentationFilter().passes(jvmClassName)) {\n                        curNode.setFilteredStatus(TimedCPUCCTNode.FILTERED_YES);\n                    }\n                } else {\n                    curNode.setFilteredStatus(TimedCPUCCTNode.FILTERED_YES);\n                }\n            } finally {\n                methodInfoMapper.unlock();\n            }\n        }\n\n        return curNode;\n    }\n\n    private TimedCPUCCTNode markerMethodEntry(final int methodId, final ThreadInfo ti, long timeStamp0, long timeStamp1, List parameters, int[] methodIds) {\n        return markerMethodEntry(methodId, ti, timeStamp0, timeStamp1, true, parameters, methodIds);\n    }\n\n    private TimedCPUCCTNode markerMethodEntry(final int methodId, final ThreadInfo ti, List parameters, int[] methodIds) {\n        return markerMethodEntry(methodId, ti, 0, 0, false, parameters, methodIds);\n    }\n\n    private TimedCPUCCTNode plainMethodEntry(final int methodId, final ThreadInfo ti, long timeStamp0, long timeStamp1,\n                                             boolean stamped) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"MethodEntry {0}: for tId = {1}, time: {2}, delta: {3}, method:  {4}\", new Object[]{(!stamped) ? \"(unstamped)\" : \"\", (int) ti.threadId, timeStamp0, timeStamp0 - delta, debugMethod(methodId)});\n        }\n\n        TimedCPUCCTNode curNode = ti.peek();\n\n        if (stamped) {\n            long diff = timeStamp0 - ti.topMethodEntryTime0;\n\n            if (diff > 0) {\n                curNode.addNetTime0(diff);\n            } else {\n                timeStamp0 = ti.topMethodEntryTime0;\n            }\n\n            ti.topMethodEntryTime0 = timeStamp0;\n\n            if (isCollectingTwoTimeStamps()) {\n                diff = timeStamp1 - ti.topMethodEntryTime1;\n\n                if (diff > 0) {\n                    curNode.addNetTime1(diff);\n                } else {\n                    timeStamp1 = ti.topMethodEntryTime1;\n                }\n\n                ti.topMethodEntryTime1 = timeStamp1;\n            }\n        }\n\n        // Now find the appropriate callee in this node or create one\n        MethodCPUCCTNode methodNode = MethodCPUCCTNode.Locator.locate(methodId, curNode.getChildren());\n\n        if (methodNode != null) {\n            ti.push(methodNode);\n\n            return methodNode;\n        }\n\n        // Appropriate sub-node not found, or there are no sub-nodes yet - create one\n        methodNode = new MethodCPUCCTNode(methodId);\n        curNode.attachNodeAsChild(methodNode);\n\n        curNode = methodNode;\n\n        ti.totalNNodes++;\n        ti.push(curNode);\n\n        if (!ti.isInRoot()) {\n            try {\n                methodInfoMapper.lock(false);\n                String jvmClassName = methodInfoMapper.getInstrMethodClass(((MethodCPUCCTNode) curNode).getMethodId()).replace('.', '/'); // NOI18N\n                ProfilerClient client = getClient();\n\n                if (client != null) {\n                    if (!client.getSettings().getInstrumentationFilter().passes(jvmClassName)) {\n                        curNode.setFilteredStatus(TimedCPUCCTNode.FILTERED_YES);\n                    }\n                } else {\n                    curNode.setFilteredStatus(TimedCPUCCTNode.FILTERED_YES);\n                }\n            } finally {\n                methodInfoMapper.unlock();\n            }\n        }\n\n        return curNode;\n    }\n\n    private TimedCPUCCTNode plainMethodEntry(final int methodId, final ThreadInfo ti, long timeStamp0, long timeStamp1) {\n        return plainMethodEntry(methodId, ti, timeStamp0, timeStamp1, true);\n    }\n\n    private TimedCPUCCTNode plainMethodEntry(final int methodId, final ThreadInfo ti) {\n        return plainMethodEntry(methodId, ti, 0, 0, false);\n    }\n\n    private TimedCPUCCTNode plainMethodExit(final int methodId, final ThreadInfo ti, long timeStamp0, long timeStamp1,\n                                            boolean stamped) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"MethodExit  {0}: for tId = {1}, time: {2}, delta: {3}, method:  {4}\", new Object[]{(!stamped) ? \"(unstamped)\" : \"\", ti.threadId, timeStamp0, timeStamp0 - delta, debugMethod(methodId)});\n            delta = timeStamp0;\n        }\n\n        TimedCPUCCTNode curNode = ti.peek();\n\n        if (curNode == null) {\n            LOGGER.severe(CommonConstants.ENGINE_WARNING + \"critical: stack integrity violation on method exit.\\n\" // NOI18N\n                          + \"*** methodId on simulated stack top is unidentifiable\\n\"); // NOI18N\n\n            return null;\n        }\n\n        if (!(curNode instanceof MethodCPUCCTNode)) {\n            LOGGER.severe(CommonConstants.ENGINE_WARNING + \"critical: stack integrity violation on method exit.\\n\" // NOI18N\n                          + \"*** methodId on simulated stack top is unidentifiable\\n\"); // NOI18N\n\n            return null;\n        }\n\n        MethodCPUCCTNode methodNode = (MethodCPUCCTNode) curNode;\n\n        if (methodId != methodNode.getMethodId()) {\n            StringBuilder message = new StringBuilder();\n            message.append(CommonConstants.ENGINE_WARNING).append(\"critical: stack integrity violation on method exit.\\n\"); // NOI18N\n            message.append(\"*** methodId on simulated stack top: \").append((int) methodNode.getMethodId()); // NOI18N\n            message.append(\", received methodId (should match) = \").append((int) methodId).append('\\n'); // NOI18N\n            message.append(\"received method debug: \").append(debugMethod(methodId)).append('\\n'); // NOI18N\n            message.append(CommonConstants.PLEASE_REPORT_PROBLEM);\n\n            if (!stackIntegrityViolationReported) {\n                message.append(dumpStack(ti));\n                stackIntegrityViolationReported = true;\n            }\n\n            message.append('\\n'); // NOI18N\n            LOGGER.severe(message.toString());\n\n            return null;\n        }\n\n        // Timer's coarse granularities etc. may occasionally cause this issue. FIXME: maybe need a warning, though not\n        // every time this happens, but probably rather in the end of run, so that the problem could then be investigated.\n        if (stamped) {\n            long diff = timeStamp0 - ti.topMethodEntryTime0;\n\n            if (diff > 0) {\n                curNode.addNetTime0(diff);\n            } else {\n                timeStamp0 = ti.topMethodEntryTime0;\n            }\n\n            if (isCollectingTwoTimeStamps()) {\n                diff = timeStamp1 - ti.topMethodEntryTime1;\n\n                if (diff > 0) {\n                    curNode.addNetTime1(diff);\n                } else {\n                    timeStamp1 = ti.topMethodEntryTime1;\n                }\n            }\n        }\n\n        TimedCPUCCTNode oldNode = ti.pop();\n\n        //    if ((ti.stackTopIdx < 0 || ti.stack[ti.stackTopIdx].getMethodId() == 0) && checkStack) {\n        //      System.err.println(ENGINE_WARNING + \"critical: stack state on methodExit is like at rootMethodExit\"); // NOI18N\n        //      System.err.println(PLEASE_REPORT_PROBLEM);\n        //    }\n        // Resume the net time for the caller\n        if (stamped) {\n            ti.topMethodEntryTime0 = timeStamp0;\n\n            if (isCollectingTwoTimeStamps()) {\n                ti.topMethodEntryTime1 = timeStamp1;\n            }\n        }\n\n        return oldNode;\n    }\n\n    private TimedCPUCCTNode plainMethodExit(final int methodId, final ThreadInfo ti, long timeStamp0, long timeStamp1) {\n        return plainMethodExit(methodId, ti, timeStamp0, timeStamp1, true);\n    }\n\n    private TimedCPUCCTNode plainMethodExit(final int methodId, final ThreadInfo ti) {\n        return plainMethodExit(methodId, ti, 0, 0, false);\n    }\n\n    private TimedCPUCCTNode rootMethodEntry(final int methodId, final ThreadInfo ti, final long timeStamp0, final long timeStamp1) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"RootMEntry for tId = {0}, time: {1}, method:  {2}\", new Object[]{(int) ti.threadId, timeStamp0, debugMethod(methodId)});\n        }\n\n//        Mark mark = MarkingEngine.getDefault().markMethod(methodId, status);\n        Mark mark = Mark.DEFAULT;\n\n        TimedCPUCCTNode curNode = ti.peek();\n\n        if (ti.isInRoot()) {\n            StringBuilder buffer = new StringBuilder();\n            buffer.append(CommonConstants.ENGINE_WARNING)\n                  .append(\"critical: at root method entry thread stack is not at 0 - should not happen!\\n\"); // NOI18N\n            buffer.append(\"*** thread = \").append(threadInfos.threadNames[ti.threadId]); // NOI18N\n            buffer.append(\", ti.stackTopIdx = \").append(ti.stackTopIdx); // NOI18N\n\n            if (curNode != null) {\n                buffer.append(\", curNode = \").append(curNode).append('\\n'); // NOI18N\n            }\n\n            buffer.append(CommonConstants.PLEASE_REPORT_PROBLEM);\n            LOGGER.severe(buffer.toString());\n        }\n\n        if (curNode == null) { // no node on stack\n\n            TimedCPUCCTNode rootNode = new ThreadCPUCCTNode(ti.threadId); // create a new thread node\n            ti.totalNNodes++;\n            ti.push(rootNode); // and place it on the stack\n            ti.totalNInv--;\n\n            if (!mark.isDefault()) {\n                curNode = new MarkedCPUCCTNode(mark);\n                rootNode.attachNodeAsChild(curNode);\n                ti.totalNNodes++;\n                ti.push(curNode);\n                rootNode = curNode;\n            }\n\n            curNode = new MethodCPUCCTNode(methodId); // now create the root method node\n            rootNode.attachNodeAsChild(curNode); // and attach it to the previously created thread node\n            ti.totalNNodes++;\n        } else {\n            TimedCPUCCTNode calleeNode;\n\n            if (!mark.isDefault()) {\n                // try to locate the category node; or create a new node for the category\n                calleeNode = MarkedCPUCCTNode.Locator.locate(mark, curNode.getChildren());\n\n                if (calleeNode == null) {\n                    calleeNode = new MarkedCPUCCTNode(mark);\n                    curNode.attachNodeAsChild(calleeNode);\n                    ti.totalNNodes++;\n                }\n\n                ti.push(calleeNode);\n                curNode = calleeNode;\n            }\n\n            calleeNode = MethodCPUCCTNode.Locator.locate(methodId, curNode.getChildren());\n\n            if (calleeNode == null) {\n                calleeNode = new MethodCPUCCTNode(methodId);\n                curNode.attachNodeAsChild(calleeNode);\n                ti.totalNNodes++;\n            }\n\n            curNode = calleeNode;\n        }\n\n        ti.push(curNode); // make the new node the current one\n                          //    curNode.setMarkID(categoryId);\n\n        // Be careful - with ROOT_ENTRY and ROOT_EXIT events, unlike with others, timeStamp0 is *always* absolute time,\n        // and timeStamp1 is *always* thread CPU time\n        ti.rootMethodEntryTimeAbs = timeStamp0;\n        ti.rootMethodEntryTimeThreadCPU = timeStamp1;\n        ti.topMethodEntryTime0 = timeStamp0;\n\n        if (isCollectingTwoTimeStamps()) {\n            ti.topMethodEntryTime1 = timeStamp1;\n        }\n\n        ti.inRoot++;\n\n        return curNode;\n    }\n\n    private TimedCPUCCTNode rootMethodExit(final int methodId, final ThreadInfo ti, long timeStamp0, long timeStamp1) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"RootMExit for tId = {0}, time: {1}, delta: {2}, method: {3}\", new Object[]{(int) ti.threadId, timeStamp0, timeStamp0 - delta, debugMethod(methodId)});\n            delta = timeStamp0;\n        }\n\n        TimedCPUCCTNode curNode = ti.peek();\n\n        if (curNode == null) {\n            LOGGER.severe(CommonConstants.ENGINE_WARNING + \"critical: stack integrity violation on root method exit.\\n\" // NOI18N\n                          + \"*** methodId on simulated stack top is unidentifiable\\n\"); // NOI18N\n\n            return null;\n        }\n\n        if (!(curNode instanceof MethodCPUCCTNode)) {\n            LOGGER.severe(CommonConstants.ENGINE_WARNING + \"critical: stack integrity violation on root method exit.\\n\" // NOI18N\n                          + \"*** methodId on simulated stack top is unidentifiable\\n\"); // NOI18N\n\n            return null;\n        }\n\n        MethodCPUCCTNode methodNode = (MethodCPUCCTNode) curNode;\n\n        if (methodId != methodNode.getMethodId()) {\n            StringBuilder message = new StringBuilder();\n            message.append(CommonConstants.ENGINE_WARNING).append(\"critical: stack integrity violation on root thod exit.\\n\"); // NOI18N\n            message.append(\"*** methodId on simulated stack top: \").append((int) methodNode.getMethodId()).append('\\n'); // NOI18N\n            message.append(\", received methodId (should match) = \").append((int) methodId).append('\\n'); // NOI18N\n            message.append(\"received method debug: \").append(debugMethod(methodId)).append('\\n'); // NOI18N\n            message.append(CommonConstants.PLEASE_REPORT_PROBLEM);\n\n            if ((status != null) && (status.getInstrMethodClasses() != null) && !stackIntegrityViolationReported) {\n                message.append(dumpStack(ti));\n                stackIntegrityViolationReported = true;\n            }\n\n            message.append('\\n'); // NOI18N\n            LOGGER.severe(message.toString());\n\n            return null;\n        }\n\n        // Be careful - with ROOT_ENTRY and ROOT_EXIT events, unlike with others, timeStamp0 is *always* absolute time,\n        // and timeStamp1 is *always* thread CPU time\n        long diff = timeStamp0 - ti.topMethodEntryTime0;\n\n        if (diff > 0) {\n            curNode.addNetTime0(diff);\n        } else {\n            timeStamp0 = ti.topMethodEntryTime0;\n        }\n\n        if (isCollectingTwoTimeStamps()) {\n            diff = timeStamp1 - ti.topMethodEntryTime1;\n\n            if (diff > 0) {\n                curNode.addNetTime1(diff);\n            } else {\n                timeStamp1 = ti.topMethodEntryTime1;\n            }\n        }\n\n        ti.inRoot--;\n\n        TimedCPUCCTNode oldNode = ti.pop();\n\n        if (ti.isInRoot()) { // We are actually exiting a non-root invocation of the root method\n            ti.topMethodEntryTime0 = timeStamp0;\n\n            if (isCollectingTwoTimeStamps()) {\n                ti.topMethodEntryTime1 = timeStamp1;\n            }\n        } else {\n            ti.rootGrossTimeAbs += (timeStamp0 - ti.rootMethodEntryTimeAbs);\n            ti.rootGrossTimeThreadCPU += (timeStamp1 - ti.rootMethodEntryTimeThreadCPU);\n            ti.rootMethodEntryTimeAbs = 0;\n            ti.rootMethodEntryTimeThreadCPU = 0;\n        }\n\n        return oldNode;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/CPUDataFrameProcessor.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.ProfilingResultListener;\nimport org.graalvm.visualvm.lib.jfluid.results.locks.AbstractLockDataFrameProcessor;\n\nimport static org.graalvm.visualvm.lib.jfluid.utils.VMUtils.*;\n\n/**\n * This class main purpose is to parse a chunk of CPU related data received from\n * the JFluid server agent and dispatch the resulting events to all interested parties\n * @author Jaroslav Bachorik\n * @author Tomas Hurka\n */\npublic class CPUDataFrameProcessor extends AbstractLockDataFrameProcessor {\n\n    private boolean hasMonitorInfo;\n    private Map methodParameters = new HashMap();\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void doProcessDataFrame(ByteBuffer buffer) {\n        hasMonitorInfo = (client != null) ? client.getSettings().isLockContentionMonitoringEnabled() : false;\n\n        try {\n            while (buffer.hasRemaining()) {\n                byte eventType = buffer.get();\n\n                if ((eventType & CommonConstants.COMPACT_EVENT_FORMAT_BYTE_MASK) != 0) {\n                    char charEvent = (char) ((((int) eventType & 0xFF) << 8) | ((int) buffer.get() & 0xFF));\n\n                    if ((byte) (eventType & CommonConstants.METHOD_EXIT_COMPACT_BYTE_MASK) == CommonConstants.METHOD_EXIT_COMPACT_BYTE_MASK) {\n                        fireMethodExitUnstamped(charEvent & CommonConstants.COMPACT_EVENT_METHOD_ID_MASK, currentThreadId,\n                                                CPUProfilingResultListener.METHODTYPE_NORMAL);\n                    } else {\n                        fireMethodEntryUnstamped(charEvent & CommonConstants.COMPACT_EVENT_METHOD_ID_MASK, currentThreadId,\n                                                 CPUProfilingResultListener.METHODTYPE_NORMAL, null, null);\n                    }\n\n                    continue;\n                }\n\n                if (!((eventType == CommonConstants.BUFFEREVENT_PROFILEPOINT_HIT) || (eventType == CommonConstants.SERVLET_DO_METHOD)\n                        || (eventType == CommonConstants.SET_FOLLOWING_EVENTS_THREAD) || (eventType == CommonConstants.NEW_THREAD)\n                        || (eventType == CommonConstants.RESET_COLLECTORS) || (eventType == CommonConstants.NEW_MONITOR)\n                        || (eventType == CommonConstants.MARKER_ENTRY_PARAMETERS))) {\n                    int methodId = -1;\n                    long timeStamp0 = 0;\n                    long timeStamp1 = 0;\n                    int hash = -1;\n                    int ownerThreadId = -1;\n                    \n                    if ((eventType != CommonConstants.ADJUST_TIME // those events do not carry methodId\n                        ) && (eventType != CommonConstants.METHOD_ENTRY_WAIT) \n                            && (eventType != CommonConstants.METHOD_EXIT_WAIT)\n                            && (eventType != CommonConstants.METHOD_ENTRY_PARK) \n                            && (eventType != CommonConstants.METHOD_EXIT_PARK)\n                            && (eventType != CommonConstants.METHOD_ENTRY_MONITOR)\n                            && (eventType != CommonConstants.METHOD_EXIT_MONITOR)\n                            && (eventType != CommonConstants.METHOD_ENTRY_SLEEP) \n                            && (eventType != CommonConstants.METHOD_EXIT_SLEEP)) {\n                        methodId = buffer.getChar();\n                    }\n\n                    if ((eventType != CommonConstants.METHOD_ENTRY_UNSTAMPED) && (eventType != CommonConstants.METHOD_EXIT_UNSTAMPED)\n                            && (eventType != CommonConstants.MARKER_ENTRY_UNSTAMPED)\n                            && (eventType != CommonConstants.MARKER_EXIT_UNSTAMPED)) {\n                        timeStamp0 = getTimeStamp(buffer);\n\n                        if ((eventType != CommonConstants.METHOD_ENTRY_WAIT)\n                                && (eventType != CommonConstants.METHOD_EXIT_WAIT)\n                                && (eventType != CommonConstants.METHOD_ENTRY_PARK)\n                                && (eventType != CommonConstants.METHOD_EXIT_PARK)\n                                && (eventType != CommonConstants.METHOD_ENTRY_MONITOR)\n                                && (eventType != CommonConstants.METHOD_EXIT_MONITOR)\n                                && (eventType != CommonConstants.METHOD_ENTRY_SLEEP)\n                                && (eventType != CommonConstants.METHOD_EXIT_SLEEP)) {\n                            if (collectingTwoTimeStamps) {\n                                timeStamp1 = getTimeStamp(buffer);\n                            }\n                        }\n                        if (hasMonitorInfo && (eventType == CommonConstants.METHOD_ENTRY_MONITOR || eventType == CommonConstants.METHOD_EXIT_MONITOR)) {\n                            hash = buffer.getInt();\n                            if (eventType == CommonConstants.METHOD_ENTRY_MONITOR) {\n                                ownerThreadId = buffer.getInt();\n                            }\n                        }\n                    }\n\n                    switch (eventType) {\n                        case CommonConstants.MARKER_ENTRY_UNSTAMPED: {\n                            List parameters = (List) methodParameters.get(Integer.valueOf(currentThreadId));\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Marker entry unstamped, tId={0}, mId={1}, pars={2}\", new Object[]{currentThreadId, methodId, parameters.toString()}); // NOI18N\n                            }\n\n                            fireMethodEntryUnstamped(methodId, currentThreadId, CPUProfilingResultListener.METHODTYPE_MARKER, parameters, null);\n                            methodParameters.remove(Integer.valueOf(currentThreadId));\n                            break;\n                        }\n                        case CommonConstants.METHOD_ENTRY_UNSTAMPED: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Method entry unstamped, tId={0}, mId={1}\", new Object[]{currentThreadId, methodId}); // NOI18N\n                            }\n\n                            fireMethodEntryUnstamped(methodId, currentThreadId, CPUProfilingResultListener.METHODTYPE_NORMAL, null, null);\n\n                            break;\n                        }\n                        case CommonConstants.MARKER_EXIT_UNSTAMPED: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Marker exit unstamped, tId={0}, mId={1}\", new Object[]{currentThreadId, methodId}); // NOI18N\n                            }\n\n                            fireMethodExitUnstamped(methodId, currentThreadId, CPUProfilingResultListener.METHODTYPE_MARKER);\n\n                            break;\n                        }\n                        case CommonConstants.METHOD_EXIT_UNSTAMPED: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Method exit unstamped, tId={0}, mId={1}\", new Object[]{currentThreadId, methodId}); // NOI18N\n                            }\n\n                            fireMethodExitUnstamped(methodId, currentThreadId, CPUProfilingResultListener.METHODTYPE_NORMAL);\n\n                            break;\n                        }\n                        case CommonConstants.MARKER_ENTRY: {\n                            List parameters = (List) methodParameters.get(Integer.valueOf(currentThreadId));\n                            int depth = getDepth(buffer);\n                            int[] methodIds = new int[depth];\n\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Marker entry , tId={0}, mId={1}, pars={2} depth={3}\", new Object[]{currentThreadId, methodId, parameters.toString(), depth}); // NOI18N\n                            }\n\n                            for (int i = 0; i < depth; i++) {\n                                methodIds[i] = buffer.getInt();\n                            }\n\n                            fireMethodEntry(methodId, currentThreadId, CPUProfilingResultListener.METHODTYPE_MARKER, timeStamp0,\n                                            timeStamp1, parameters, methodIds);\n                            methodParameters.remove(Integer.valueOf(currentThreadId));                            \n                            break;\n                        }\n                        case CommonConstants.ROOT_ENTRY: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Root entry , tId={0}, mId={1}\", new Object[]{currentThreadId, methodId}); // NOI18N\n                            }\n\n                            fireMethodEntry(methodId, currentThreadId, CPUProfilingResultListener.METHODTYPE_ROOT, timeStamp0,\n                                            timeStamp1);\n\n                            break;\n                        }\n                        case CommonConstants.METHOD_ENTRY: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Method entry , tId={0}, mId={1}\", new Object[]{currentThreadId, methodId}); // NOI18N\n                            }\n\n                            fireMethodEntry(methodId, currentThreadId, CPUProfilingResultListener.METHODTYPE_NORMAL, timeStamp0,\n                                            timeStamp1);\n\n                            break;\n                        }\n                        case CommonConstants.MARKER_EXIT: {\n                            List parameters = (List) methodParameters.get(Integer.valueOf(currentThreadId));\n                            Object retVal = parameters == null ? null : parameters.get(0);\n                            \n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                if (retVal != null) {\n                                    LOGGER.log(Level.FINEST, \"Marker exit , tId={0}, mId={1}, retVal={2}\", new Object[]{currentThreadId, methodId, retVal}); // NOI18N                                    \n                                } else {\n                                    LOGGER.log(Level.FINEST, \"Marker exit , tId={0}, mId={1}\", new Object[]{currentThreadId, methodId}); // NOI18N\n                                }\n                            }\n\n                            fireMethodExit(methodId, currentThreadId, CPUProfilingResultListener.METHODTYPE_MARKER, timeStamp0,\n                                           timeStamp1, retVal);\n                            methodParameters.remove(Integer.valueOf(currentThreadId));\n                            break;\n                        }\n                        case CommonConstants.ROOT_EXIT: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Root exit , tId={0}, mId={1}\", new Object[]{currentThreadId, methodId}); // NOI18N\n                            }\n\n                            fireMethodExit(methodId, currentThreadId, CPUProfilingResultListener.METHODTYPE_ROOT, timeStamp0,\n                                           timeStamp1, null);\n\n                            break;\n                        }\n                        case CommonConstants.METHOD_EXIT: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Method exit , tId={0}, mId={1}\", new Object[]{currentThreadId, methodId}); // NOI18N\n                            }\n\n                            fireMethodExit(methodId, currentThreadId, CPUProfilingResultListener.METHODTYPE_NORMAL, timeStamp0,\n                                           timeStamp1, null);\n\n                            break;\n                        }\n                        case CommonConstants.ADJUST_TIME: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Adjust time , tId={0}\", currentThreadId); // NOI18N\n                            }\n\n                            fireAdjustTime(currentThreadId, timeStamp0, timeStamp1);\n\n                            break;\n                        }\n                        case CommonConstants.METHOD_ENTRY_MONITOR: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Monitor entry , tId={0} , monitorId={1}, ownerId={2}\", new Object[]{currentThreadId,Integer.toHexString(hash),ownerThreadId}); // NOI18N\n                            }\n\n                            fireMonitorEntry(currentThreadId, timeStamp0, timeStamp1, hash, ownerThreadId);\n\n                            break;\n                        }\n                        case CommonConstants.METHOD_EXIT_MONITOR: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Monitor exit , tId={0} , monitorId={1}\", new Object[]{currentThreadId,Integer.toHexString(hash)}); // NOI18N\n                            }\n\n                            fireMonitorExit(currentThreadId, timeStamp0, timeStamp1, hash);\n\n                            break;\n                        }\n                        case CommonConstants.METHOD_ENTRY_SLEEP: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Sleep entry , tId={0}\", currentThreadId); // NOI18N\n                            }\n\n                            fireSleepEntry(currentThreadId, timeStamp0, timeStamp1);\n\n                            break;\n                        }\n                        case CommonConstants.METHOD_EXIT_SLEEP: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Sleep exit , tId={0}\", currentThreadId); // NOI18N\n                            }\n\n                            fireSleepExit(currentThreadId, timeStamp0, timeStamp1);\n\n                            break;\n                        }\n                        case CommonConstants.METHOD_ENTRY_WAIT: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Wait entry , tId={0}\", currentThreadId); // NOI18N\n                            }\n\n                            fireWaitEntry(currentThreadId, timeStamp0, timeStamp1);\n\n                            break;\n                        }\n                        case CommonConstants.METHOD_EXIT_WAIT: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Wait exit , tId={0}\", currentThreadId); // NOI18N\n                            }\n\n                            fireWaitExit(currentThreadId, timeStamp0, timeStamp1);\n\n                            break;\n                        }\n                        case CommonConstants.METHOD_ENTRY_PARK: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Park entry , tId={0}\", currentThreadId); // NOI18N\n                            }\n\n                            fireParkEntry(currentThreadId, timeStamp0, timeStamp1);\n\n                            break;\n                        }\n                        case CommonConstants.METHOD_EXIT_PARK: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Park exit , tId={0}\", currentThreadId); // NOI18N\n                            }\n\n                            fireParkExit(currentThreadId, timeStamp0, timeStamp1);\n\n                            break;\n                        }\n                        case CommonConstants.THREADS_SUSPENDED: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.finest(\"Threads suspend\"); // NOI18N\n                            }\n\n                            fireThreadsSuspend(timeStamp0, timeStamp1);\n\n                            break;\n                        }\n                        case CommonConstants.THREADS_RESUMED: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.finest(\"Threads resume\"); // NOI18N\n                            }\n\n                            fireThreadsResumed(timeStamp0, timeStamp1);\n\n                            break;\n                        }\n                        default: {\n                            LOGGER.log(Level.SEVERE, \"*** Profiler Engine: internal error: got unknown event type in CPUDataFrameProcessor: {0} at {1}\", // NOI18N\n                                                    new Object[]{(int) eventType, buffer.position()});\n                            StringBuilder sb = new StringBuilder();\n                            sb.append(\"dataframe [\");   // NOI18N\n                            buffer.rewind();\n                            while (buffer.hasRemaining()) {\n                                sb.append(buffer.get()).append(\",\");    // NOI18N\n                            }\n                            sb.append(\"]\\n\");   // NOI18N\n                            LOGGER.severe(sb.toString());\n\n                            break;\n                        }\n                    }\n                } else {\n                    switch (eventType) {\n                        case CommonConstants.BUFFEREVENT_PROFILEPOINT_HIT: {\n                            int id = buffer.getChar();\n                            long timeStamp = getTimeStamp(buffer);\n                            int threadId = buffer.getChar();\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.finest(\"Profile Point Hit \" + id + \", threadId=\" + id + \", timeStamp=\" + timeStamp); // NOI18N\n                            }\n                            fireProfilingPoint(threadId, id, timeStamp);\n\n                            break;\n                        }\n                        case CommonConstants.SET_FOLLOWING_EVENTS_THREAD: {\n                            currentThreadId = buffer.getChar();\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Change current thread , tId={0}\", currentThreadId); // NOI18N\n                            }\n\n                            break;\n                        }\n                        case CommonConstants.NEW_THREAD: {\n                            int threadId = buffer.getChar();\n                            String threadName = getString(buffer);\n                            String threadClassName = getString(buffer);\n\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Creating new thread , tId={0}\", threadId); // NOI18N\n                            }\n\n                            fireNewThread(threadId, threadName, threadClassName);\n                            currentThreadId = threadId;\n\n                            break;\n                        }\n                        case CommonConstants.NEW_MONITOR: {\n                            int hash = buffer.getInt();\n                            String className = getString(buffer);\n\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Creating new monitor , monitorId={0} , className={1}\", new Object[] {Integer.toHexString(hash), className}); // NOI18N\n                            }\n                            fireNewMonitor(hash, className);\n                            break;\n                        }\n                        case CommonConstants.SERVLET_DO_METHOD: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Servlet track start , tId={0}\", currentThreadId); // NOI18N\n                            }\n\n                            byte requestType = buffer.get();\n                            String servletPath = getString(buffer);\n                            int sessionId = buffer.getInt();\n                            \n                            fireServletRequest(currentThreadId, requestType, servletPath, sessionId);\n\n                            break;\n                        }\n                        case CommonConstants.MARKER_ENTRY_PARAMETERS: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.log(Level.FINEST, \"Marker method parameters , tId={0}\", currentThreadId); // NOI18N\n                            }\n                            \n                            List parameters = new ArrayList();\n                            int pars = buffer.get();\n                            \n                            for (int i = 0; i < pars; i++) {\n                                parameters.add(readParameter(buffer));\n                            }\n                            methodParameters.put(Integer.valueOf(currentThreadId), parameters);\n                            break;\n                        }\n                        case CommonConstants.RESET_COLLECTORS: {\n                            if (LOGGER.isLoggable(Level.FINEST)) {\n                                LOGGER.finest(\"Profiling data reset\"); // NOI18N\n                            }\n\n                            fireReset();\n\n                            break;\n                        }\n                        default: {\n                            LOGGER.log(Level.SEVERE, \"*** Profiler Engine: internal error: got unknown event type in CPUDataFrameProcessor: {0} at {1}\", // NOI18N\n                                                      new Object[]{(int) eventType, buffer.position()});\n                            StringBuilder sb = new StringBuilder();\n                            sb.append(\"dataframe [\");   // NOI18N\n                            buffer.rewind();\n                            while (buffer.hasRemaining()) {\n                                sb.append(buffer.get()).append(\",\");    // NOI18N\n                            }\n                            sb.append(\"]\\n\");   // NOI18N\n                            LOGGER.severe(sb.toString());\n\n                            break;\n                        }\n                    }\n                }\n            }\n        } catch (ArrayIndexOutOfBoundsException aioobe) {\n            StringBuilder sb = new StringBuilder();\n            sb.append(\"AIOOBE in dataframe [\");\n            buffer.rewind();\n            while (buffer.hasRemaining()) {\n                sb.append(buffer.get()).append(\",\");\n            }\n            sb.append(\"]\\n\");\n            LOGGER.severe(sb.toString());\n            throw aioobe;\n        }\n    }\n    \n    private Object readParameter(ByteBuffer buffer) {\n        char type = (char) buffer.get();\n        switch (type) {\n            case BOOLEAN: {\n                byte val = buffer.get();\n                if (val == 0) {\n                    return Boolean.FALSE;\n                }\n                if (val == 1) {\n                    return Boolean.TRUE;\n                }\n                throw new IllegalArgumentException(Byte.toString(val));\n            }\n            case CHAR:\n                return Character.valueOf(buffer.getChar());\n            case BYTE:\n                return Byte.valueOf(buffer.get());\n            case SHORT:\n                return Short.valueOf(buffer.getShort());\n            case INT:\n                return Integer.valueOf(buffer.getInt());\n            case LONG:\n                return Long.valueOf(buffer.getLong());\n            case FLOAT:\n                return Float.valueOf(Float.intBitsToFloat(buffer.getInt()));\n            case DOUBLE:\n                return Double.valueOf(Double.longBitsToDouble(buffer.getLong()));\n            case REFERENCE:\n                int lengthChars = buffer.getShort()/2;\n                StringBuilder string = new StringBuilder(lengthChars);\n                for (int i = 0; i < lengthChars; i++) {\n                    string.append(buffer.getChar());\n                }\n                return string.toString();\n        }\n        throw new IllegalArgumentException(Integer.toString(type));\n    }\n\n    private void fireMethodEntry(final int methodId, final int threadId, final int methodType, final long timeStamp0,\n                                 final long timeStamp1) {\n        fireMethodEntry(methodId, threadId, methodType, timeStamp0, timeStamp1, null, null);\n    }\n\n    private void fireMethodEntry(final int methodId, final int threadId, final int methodType, final long timeStamp0,\n                                 final long timeStamp1, final List parameters, final int[] methodIds) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((CPUProfilingResultListener) listener).methodEntry(methodId, threadId, methodType, timeStamp0, timeStamp1, parameters, methodIds);\n                }\n            });\n    }\n\n    private void fireMethodEntryUnstamped(final int methodId, final int threadId, final int methodType, final List parameters, final int[] methodIds) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((CPUProfilingResultListener) listener).methodEntryUnstamped(methodId, threadId, methodType, parameters, methodIds);\n                }\n            });\n    }\n\n    private void fireMethodExit(final int methodId, final int threadId, final int methodType, final long timeStamp0,\n                                final long timeStamp1, final Object retVal) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((CPUProfilingResultListener) listener).methodExit(methodId, threadId, methodType, timeStamp0, timeStamp1, retVal);\n                }\n            });\n    }\n\n    private void fireMethodExitUnstamped(final int methodId, final int threadId, final int methodType) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((CPUProfilingResultListener) listener).methodExitUnstamped(methodId, threadId, methodType);\n                }\n            });\n    }\n\n    private void fireServletRequest(final int threadId, final int requestType, final String servletPath, final int sessionId) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((CPUProfilingResultListener) listener).servletRequest(threadId, requestType, servletPath, sessionId);\n                }\n            });\n    }\n\n    private void fireSleepEntry(final int threadId, final long timeStamp0, final long timeStamp1) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((CPUProfilingResultListener) listener).sleepEntry(threadId, timeStamp0, timeStamp1);\n                }\n            });\n    }\n\n    private void fireSleepExit(final int threadId, final long timeStamp0, final long timeStamp1) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((CPUProfilingResultListener) listener).sleepExit(threadId, timeStamp0, timeStamp1);\n                }\n            });\n    }\n\n    private void fireThreadsResumed(final long timeStamp0, final long timeStamp1) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((CPUProfilingResultListener) listener).threadsSuspend(timeStamp0, timeStamp1);\n                }\n            });\n    }\n\n    private void fireThreadsSuspend(final long timeStamp0, final long timeStamp1) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((CPUProfilingResultListener) listener).threadsSuspend(timeStamp0, timeStamp1);\n                }\n            });\n    }\n\n    private void fireWaitEntry(final int threadId, final long timeStamp0, final long timeStamp1) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((CPUProfilingResultListener) listener).waitEntry(threadId, timeStamp0, timeStamp1);\n                }\n            });\n    }\n\n    private void fireWaitExit(final int threadId, final long timeStamp0, final long timeStamp1) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((CPUProfilingResultListener) listener).waitExit(threadId, timeStamp0, timeStamp1);\n                }\n            });\n    }\n\n    private void fireParkEntry(final int threadId, final long timeStamp0, final long timeStamp1) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((CPUProfilingResultListener) listener).parkEntry(threadId, timeStamp0, timeStamp1);\n                }\n            });\n    }\n\n    private void fireParkExit(final int threadId, final long timeStamp0, final long timeStamp1) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((CPUProfilingResultListener) listener).parkExit(threadId, timeStamp0, timeStamp1);\n                }\n            });\n    }\n\n    private static int getDepth(ByteBuffer buffer) {\n        int depth = ((((int) buffer.get()) & 0xFF) << 16) | ((((int) buffer.get()) & 0xFF) << 8)\n                    | (((int) buffer.get()) & 0xFF);\n        return depth;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/CPUProfilingResultListener.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.results.locks.LockProfilingResultListener;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface CPUProfilingResultListener extends LockProfilingResultListener {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static final int METHODTYPE_NORMAL = 1;\n    static final int METHODTYPE_ROOT = 2;\n    static final int METHODTYPE_MARKER = 3;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    void methodEntry(final int methodId, final int threadId, final int methodType, final long timeStamp0, final long timeStamp1,\n            final List parameters, final int[] methodIds);\n\n    void methodEntryUnstamped(final int methodId, final int threadId, final int methodType, final List parameters, final int[] methodIds);\n\n    void methodExit(final int methodId, final int threadId, final int methodType, final long timeStamp0, final long timeStamp1, final Object retVal);\n\n    void methodExitUnstamped(final int methodId, final int threadId, final int methodType);\n\n    void servletRequest(final int threadId, final int requestType, final String servletPath, final int sessionId);\n\n    void sleepEntry(final int threadId, final long timeStamp0, final long timeStamp1);\n\n    void sleepExit(final int threadId, final long timeStamp0, final long timeStamp1);\n\n    void threadsResume(final long timeStamp0, final long timeStamp1);\n\n    void threadsSuspend(final long timeStamp0, final long timeStamp1);\n\n    void waitEntry(final int threadId, final long timeStamp0, final long timeStamp1);\n\n    void waitExit(final int threadId, final long timeStamp0, final long timeStamp1);\n\n    void parkEntry(final int threadId, final long timeStamp0, final long timeStamp1);\n\n    void parkExit(final int threadId, final long timeStamp0, final long timeStamp1);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/CPUResultsDiff.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class CPUResultsDiff extends CPUResultsSnapshot {\n\n    private final CPUResultsSnapshot snapshot1;\n    private final CPUResultsSnapshot snapshot2;\n\n\n    public CPUResultsDiff(CPUResultsSnapshot snapshot1, CPUResultsSnapshot snapshot2) {\n//        this.snapshot1 = new CPUResultsSnapshot();\n//        this.snapshot1.readFromSnapshot(snapshot1);\n//        this.snapshot2 = new CPUResultsSnapshot();\n//        this.snapshot2.readFromSnapshot(snapshot2);\n        this.snapshot1 = snapshot1;\n        this.snapshot2 = snapshot2;\n\n        threadCCTContainers = snapshot1.threadCCTContainers;\n    }\n\n    public boolean isCollectingTwoTimeStamps() {\n        return snapshot1.collectingTwoTimeStamps &&\n               snapshot2.collectingTwoTimeStamps;\n    }\n\n    // Not used for diff\n    public CPUCCTContainer getContainerForThread(int threadId, int view) {\n        return snapshot1.getContainerForThread(threadId, view);\n    }\n\n    public DiffFlatProfileContainer getFlatProfile(int threadId, int view) {\n        // NOTE: only works correctly for threadId == -1 (All Threads)\n        // TODO: resolve correct threadId for snapshot2 !!!\n        FlatProfileContainer fpc1 = snapshot1.getFlatProfile(threadId, view);\n        FlatProfileContainer fpc2 = snapshot2.getFlatProfile(threadId, view);\n        return DiffFlatProfileContainer.create(fpc1, fpc2);\n    }\n\n    public FlatProfileContainer getFlatProfile(Collection<Integer> threads, int view) {\n        FlatProfileContainer fpc1 = snapshot1.getFlatProfile(threads, view);\n        FlatProfileContainer fpc2 = snapshot2.getFlatProfile(threads2(threads), view);\n        return DiffFlatProfileContainer.create(fpc1, fpc2);\n    }\n    \n    // Not used for diff\n    public String[] getInstrMethodClasses(int view) {\n        return snapshot1.getInstrMethodClasses(view);\n    }\n\n    // Used by CPUTestCase.logInstrumented\n    // Otherwise not used for diff\n    public String[] getInstrMethodNames() {\n        return snapshot1.getInstrMethodNames();\n    }\n\n    // Not used for diff\n    public String[] getInstrMethodSignatures() {\n        return snapshot1.getInstrMethodSignatures();\n    }\n\n    public String[] getMethodClassNameAndSig(int methodId, int view) {\n        return methodId < 0 ? snapshot2.getMethodClassNameAndSig(-methodId, view) :\n                              snapshot1.getMethodClassNameAndSig(methodId, view);\n    }\n    \n    public Map<Integer, ClientUtils.SourceCodeSelection> getMethodIDMap(int view) {\n        Map<Integer, ClientUtils.SourceCodeSelection> map = new HashMap();\n        for (int i = 0; i < snapshot1.instrMethodClassesViews[view].length; i++)\n            map.put(i, snapshot1.getSourceCodeSelection(i, view));\n        for (int i = 0; i < snapshot2.instrMethodClassesViews[view].length; i++)\n            map.put(-i, snapshot2.getSourceCodeSelection(i, view));\n        return map;\n    }\n\n    // Not used for diff\n    public int getNInstrMethods() {\n        return snapshot1.getNInstrMethods();\n    }\n\n    // Not used\n    public int getNThreads() {\n        return snapshot1.getNThreads();\n    }\n\n    public PrestimeCPUCCTNode getReverseCCT(int threadId, int methodId, int view) {\n        // TODO: resolve correct threadId for snapshot2\n        PrestimeCPUCCTNode root1 = snapshot1.getReverseCCT(threadId, methodId, view);\n        PrestimeCPUCCTNode root2 = snapshot2.getReverseCCT(threadId, methodId, view);\n        return new DiffCPUCCTNode(root1, root2);\n    }\n\n    public PrestimeCPUCCTNode getRootNode(int view) {\n        PrestimeCPUCCTNode root1 = snapshot1.getRootNode(view);\n        PrestimeCPUCCTNode root2 = snapshot2.getRootNode(view);\n        return new DiffCPUCCTNode(root1, root2);\n    }\n    \n    public PrestimeCPUCCTNode getRootNode(int view, Collection<Integer> threads, boolean merge) {\n        PrestimeCPUCCTNode root1 = snapshot1.getRootNode(view, threads, merge);\n        PrestimeCPUCCTNode root2 = snapshot2.getRootNode(view, threads2(threads), merge);\n        return new DiffCPUCCTNode(root1, root2);\n    }\n    \n    public PrestimeCPUCCTNode getReverseRootNode(int view, Collection<Integer> threads, boolean merge) {\n        PrestimeCPUCCTNode root1 = snapshot1.getReverseRootNode(view, threads, merge);\n        PrestimeCPUCCTNode root2 = snapshot2.getReverseRootNode(view, threads2(threads), merge);\n        return new DiffCPUCCTNode(root1, root2);\n    }\n    \n    private Collection<Integer> threads2(Collection<Integer> threads1) {\n        if (threads1 == null || threads1.isEmpty()) return threads1;\n        \n        Set<String> threads1Names = new HashSet();\n        for (int thread1Id : threads1) threads1Names.add(getThreadNameForId(thread1Id));\n        Set<Integer> threads2 = new HashSet();\n        for (int thread2Id : snapshot2.getThreadIds())\n            if (threads1Names.contains(snapshot2.getThreadNameForId(thread2Id)))\n                threads2.add(thread2Id);\n        \n        return threads2;\n    }\n    \n    public long getBound(int view) {\n        long bound = Long.MIN_VALUE;\n        \n        PrestimeCPUCCTNode root = getRootNode(view);\n        CCTNode[] children = root.getChildren();\n        for (CCTNode child : children)\n            bound = Math.max(bound, Math.abs(((PrestimeCPUCCTNode)child).getTotalTime0()));\n        \n        return bound;\n    }\n    \n    public void filterForward(final String filter, final int filterType, final PrestimeCPUCCTNodeBacked root) {\n//        PrestimeCPUCCTNodeBacked node1 = ((DiffCPUCCTNode)root).node1;\n//        if (node1 != null) snapshot1.filterForward(filter, filterType, node1);\n//        \n//        PrestimeCPUCCTNodeBacked node2 = ((DiffCPUCCTNode)root).node2;\n//        if (node2 != null) snapshot2.filterForward(filter, filterType, node2);\n//        \n//        super.filterForward(filter, filterType, root);\n    }\n    \n    public void saveSortParams(int sortBy, boolean sortOrder, CCTNode node) {\n//        PrestimeCPUCCTNodeBacked node1 = ((DiffCPUCCTNode)node).node1;\n//        if (node1 != null) snapshot1.saveSortParams(sortBy, sortOrder, node1);\n//        \n//        PrestimeCPUCCTNodeBacked node2 = ((DiffCPUCCTNode)node).node2;\n//        if (node2 != null) snapshot2.saveSortParams(sortBy, sortOrder, node2);\n//        \n//        super.saveSortParams(sortBy, sortOrder, node);\n    }\n    \n    // TODO: used by CPUDiffPanel, fix!\n    public int[] getThreadIds() {\n        return snapshot1.getThreadIds();\n    }\n\n    // Not used for diff\n    public String getThreadNameForId(int threadId) {\n        return snapshot1.getThreadNameForId(threadId);\n    }\n\n    // TODO: used by CPUDiffPanel, fix!\n    public String[] getThreadNames() {\n        return snapshot1.getThreadNames();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/CPUResultsSnapshot.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.results.ResultsSnapshot;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.text.MessageFormat;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.ResourceBundle;\nimport java.util.WeakHashMap;\nimport java.util.logging.Level;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.FilterSortSupport;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\n\n\n/**\n * Management of the CPU profiling results snapshot.\n * A CPU snapshot is created from the runtime CCTs for all profiled threads, that are provided by CPUCallGraphBuilder.\n * Initially it contains only these same (logically) CCTs (in instances of CPUCCTContainer), but in compact \"flattened\"\n * format that takes less space in memory, and represented in microseconds, cleansed time.\n * When the user starts to open CCT nodes for the given thread, the relevant objects (PrestimeCPUCCTNodes) are generated lazily\n * for touched nodes out of the initial compact representation. This is done via a PrestimeCPUCCTNode object keeping a pointer\n * into the compact tree representation where its data is located, from which the data for its children can be located, etc.\n * When the user requests data in different \"view\" (switching say from method-level to class- (or package-) level aggregation),\n * the relevant compact representation for all threads is generated out of the initial compact representation.\n * <p>\n * Has an API for\n * - returning the root of the all-threads CCT. The node objects themselves take care of lazy construction of sub-nodes\n * out of the compact representation, when needed\n * - generation of the accumulated time per method (flat profile) out of the CCT.\n *\n * @author Misha Dmitriev\n */\npublic class CPUResultsSnapshot extends ResultsSnapshot {\n    /**************************************************************************\n    +------------------------------------------------------------------------------+\n    | Profiler CPU snapshot format description                                     |\n    +------------------------------------------------------------------------------+\n    int         version\n    long        timestamp\n    long        duration\n    boolean     measure thread time?\n    int         #instrumented methods\n    ===> (for #instrumented methods)\n    string      class name\n    string      method name\n    string      signature\n    <===\n    int         #threads\n    ===> (for #threads)\n    int         thread id\n    string      thread name\n    boolean     measure thread time?\n    int         compact data length\n    byte[]      compact data with the given length\n    int         node size\n    long        wholeGraphGrossTimeAbs\n    long        wholeGraphGrossTimeThreadCPU\n    double      timeInInjectedCodeInAbsCounts\n    double      timeInInjectedCodeInThreadCPUCounts\n    long        wholeGraphPureTimeAbs\n    long        wholeGraphPureTimeThreadCPU\n    long        wholeGraphNetTime0\n    long        wholeGraphNetTime1\n    long        totalInvNo\n    boolean     displayWholeThreadCPUTime\n    <===\n\n\n    +------------------------------------------------------------------------------+\n    | CPU compact data format description                                          |\n    +------------------------------------------------------------------------------+\n    0-1     2 bytes         methodID\n    2-5     4 bytes         nCalls\n    6-10    5 bytes         time0\n    11-15   5 bytes         self time0\n    16-20   5 bytes         time1(if measuring thread time)\n    21-25   5 bytes         self time1(if measuring thread time)\n    26-27   2 bytes         # of subnodes\n    28-30   3 bytes         if compact data size <= 16777215\n    28-31   4 bytes         if compact data size > 16777215\n    ***************************************************************************/\n\n    /**\n     * This exception just indicates that snapshot can't be created because no data is available\n     */\n    public static class NoDataAvailableException extends Exception {\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String CPU_MSG = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.cpu.Bundle\").getString(\"CPUResultsSnapshot_CpuMsg\"); // NOI18N\n                                                                                           // -----\n\n    // Views-related stuff\n    public static final int METHOD_LEVEL_VIEW = 0;\n    public static final int CLASS_LEVEL_VIEW = 1;\n    public static final int PACKAGE_LEVEL_VIEW = 2;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected Map threadIdMap;\n    protected CPUCCTContainer[] allThreadsMergedCCTContainers; // [method|class|package aggregation level] -> CPUCCTContainer Per-view representation of all threads merged CCT containers\n\n    // <class name>,<method name>,<method signature> triplets corresponding to methodIds in the profiling results\n    // The 0th entry is reserved for a special \"Threads\" node\n    // instrMethodClasses consists of 3 arrays, each per different \"view\"\n    protected String[][] instrMethodClassesViews;\n    protected String[] instrMethodNames;\n    protected String[] instrMethodSignatures;\n    protected PrestimeCPUCCTNode[] rootNode; // Per-view root nodes\n    protected CPUCCTContainer[][] threadCCTContainers; // [method|class|package aggregation level][0-nThreads] -> CPUCCTContainer\n    protected boolean collectingTwoTimeStamps;\n    protected InstrumentationFilter filter;\n\n    // Number of instrumented methods - may be smaller than the size of the above arrays\n    protected int nInstrMethods;\n    \n    private final Map<CCTNode, FilterSortSupport.Configuration> sortInfos = new WeakHashMap();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CPUResultsSnapshot() { // No-arg constructor needed for above serialization methods to work\n        super();\n        threadIdMap = new HashMap();\n    }\n\n    public CPUResultsSnapshot(long beginTime, long timeTaken, CPUCCTProvider cctProvider, boolean collectingTwoTimestamps,\n                              String[] instrClassNames, String[] instrMethodNames, String[] instrMethodSigs, int nInstrMethods)\n                       throws NoDataAvailableException {\n        this(beginTime, timeTaken, cctProvider,\n             collectingTwoTimestamps, null,\n             instrClassNames, instrMethodNames, instrMethodSigs, nInstrMethods);\n    }\n\n    public CPUResultsSnapshot(long beginTime, long timeTaken,\n                              CPUCCTProvider cctProvider, boolean collectingTwoTimestamps, InstrumentationFilter filter,\n                              String[] instrClassNames, String[] instrMethodNames, String[] instrMethodSigs, int nInstrMethods)\n                       throws NoDataAvailableException {\n        super(beginTime, timeTaken);\n\n        this.collectingTwoTimeStamps = collectingTwoTimestamps;\n        this.filter = filter;\n\n        this.instrMethodClassesViews = new String[3][];\n        this.instrMethodClassesViews[METHOD_LEVEL_VIEW] = instrClassNames;\n        this.instrMethodNames = instrMethodNames;\n        this.instrMethodSignatures = instrMethodSigs;\n        this.nInstrMethods = nInstrMethods;\n\n        // Generate individual CCT containers for all threads in CPUCallGraphBuilder.\n        CPUCCTContainer[] methodLevelCCTs = cctProvider.createPresentationCCTs(this);\n\n        if (methodLevelCCTs == null || methodLevelCCTs.length == 0) {\n            throw new NoDataAvailableException();\n        }\n\n        threadIdMap = new HashMap(methodLevelCCTs.length);\n\n        for (int i = 0; i < methodLevelCCTs.length; i++) {\n            threadIdMap.put(Integer.valueOf(methodLevelCCTs[i].threadId), Integer.valueOf(i));\n        }\n\n        threadCCTContainers = new CPUCCTContainer[3][];\n        threadCCTContainers[METHOD_LEVEL_VIEW] = methodLevelCCTs;\n\n        allThreadsMergedCCTContainers = new CPUCCTContainer[3];\n        rootNode = new PrestimeCPUCCTNode[3];\n        rootNode[METHOD_LEVEL_VIEW] = createRootNodeForAllThreads(METHOD_LEVEL_VIEW);\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            debugValues();\n        }\n    }\n    \n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    public void setProfilerSettings(ProfilerEngineSettings pes) {\n        if (pes.getCPUProfilingType() == CommonConstants.CPU_SAMPLED) {\n            filter = pes.getInstrumentationFilter();\n        }\n    }\n\n    public boolean isCollectingTwoTimeStamps() {\n        return collectingTwoTimeStamps;\n    }\n\n    public CPUCCTContainer getContainerForThread(int threadId, int view) {\n        generateDataForView(view);\n        \n        return threadCCTContainers[view][getContainerIdForThreadId(threadId)];\n    }\n\n    public FlatProfileContainer getFlatProfile(int threadId, int view) {\n        generateDataForView(view);\n        \n        if (threadId != -1) {\n            return threadCCTContainers[view][getContainerIdForThreadId(threadId)].getFlatProfile();\n        } else {\n            return allThreadsMergedCCTContainers[view].getFlatProfile();\n        }\n    }\n    \n    public FlatProfileContainer getFlatProfile(Collection<Integer> threads, int view) {\n        if (threads == null) return getFlatProfile(-1, view);\n        else if (threads.size() == 1) return getFlatProfile(threads.iterator().next(), view);\n        else return createContainerForThreads(threads, view).getFlatProfile();\n    }\n\n    // -- Views-related code\n    public String[] getInstrMethodClasses(int view) {\n        return instrMethodClassesViews[view];\n    }\n\n    public String[] getInstrMethodNames() {\n        return instrMethodNames;\n    }\n\n    public String[] getInstrMethodSignatures() {\n        return instrMethodSignatures;\n    }\n\n    public String[] getMethodClassNameAndSig(int methodId, int view) {\n        if (view == METHOD_LEVEL_VIEW) {\n            return new String[] {\n                       instrMethodClassesViews[METHOD_LEVEL_VIEW][methodId], instrMethodNames[methodId],\n                       instrMethodSignatures[methodId]\n                   };\n        } else {\n            return new String[] { instrMethodClassesViews[view][methodId], null, null };\n        }\n    }\n    \n    public ClientUtils.SourceCodeSelection getSourceCodeSelection(int methodId, int view) {\n        String[] sel = getMethodClassNameAndSig(methodId, view);\n        return sel[1] != null ? new ClientUtils.SourceCodeSelection(sel[0], sel[1], sel[2]):\n                         new ClientUtils.SourceCodeSelection(sel[0], Wildcards.ALLWILDCARD, null);\n    }\n    \n    public Map<Integer, ClientUtils.SourceCodeSelection> getMethodIDMap(int view) {\n        Map<Integer, ClientUtils.SourceCodeSelection> map = new HashMap();\n        for (int i = 0; i < instrMethodClassesViews[view].length; i++)\n            map.put(i, getSourceCodeSelection(i, view));\n        return map;\n    }\n\n    public int getNInstrMethods() {\n        return nInstrMethods;\n    }\n\n    public int getNThreads() {\n        return threadCCTContainers[METHOD_LEVEL_VIEW].length;\n    }\n\n    public PrestimeCPUCCTNode getReverseCCT(int threadId, int methodId, int view) {\n        generateDataForView(view);\n\n        if (threadId >= 0) {\n            return threadCCTContainers[view][getContainerIdForThreadId(threadId)].getReverseCCT(methodId);\n        } else if (threadId == -1) {\n            return allThreadsMergedCCTContainers[view].getReverseCCT(methodId);\n        } else {\n            throw new IllegalArgumentException(\"!!! Cannot generate reverse CCT for threadId = \" + threadId); // NOI18N\n        }\n    }\n\n    public PrestimeCPUCCTNode getRootNode(int view) {\n        generateDataForView(view);\n\n        return rootNode[view];\n    }\n    \n    public PrestimeCPUCCTNode getRootNode(int view, Collection<Integer> threads, boolean merge) {\n        if (threads == null) {\n            if (merge == false) {\n                return fixNCalls(getRootNode(view));\n            } else {\n                int[] _threads = getThreadIds();\n                threads = new ArrayList(_threads.length);\n                for (int t : _threads) threads.add(t);\n            }\n        }\n        \n        PrestimeCPUCCTNode[] nodes = new PrestimeCPUCCTNode[threads.size()];\n        Iterator<Integer> threadIds = threads.iterator();\n        for (int i = 0; i < nodes.length; i++)\n            nodes[i] = getContainerForThread(threadIds.next(), view).getRootNode();\n        \n        generateDataForView(view);\n        \n        return merge ? new PrestimeCPUCCTNodeBacked(threadCCTContainers[view][0], mergedChildren(nodes)) :\n                       fixNCalls(new PrestimeCPUCCTNodeBacked(threadCCTContainers[view][0], nodes));\n    }\n    \n    // Workaround to display sum of invocations of all children for thread nodes\n    private PrestimeCPUCCTNode fixNCalls(PrestimeCPUCCTNode root) {\n        CCTNode[] children = root == null ? null : root.getChildren();\n        if (children != null) for (CCTNode node : children) {\n            PrestimeCPUCCTNode _root = (PrestimeCPUCCTNode)node;\n            _root.nCalls = 0;\n            CCTNode[] _children = _root.getChildren();\n            if (_children != null) for (CCTNode child : _children)\n                _root.addNCalls(((PrestimeCPUCCTNode)child).getNCalls());\n        }\n        return root;\n    }\n    \n    private PrestimeCPUCCTNode[] mergedChildren(PrestimeCPUCCTNode[] nodes) {\n        List<PrestimeCPUCCTNode> merged = new ArrayList();\n        \n        for (PrestimeCPUCCTNode node : nodes) {\n            CCTNode[] children = node.getChildren();\n            if (children != null) for (CCTNode n : children) {\n                int idx = merged.indexOf(n);\n                if (idx == -1) merged.add(((PrestimeCPUCCTNode)n).createCopy());\n                else merged.get(idx).merge(n);\n            }\n        }\n        \n        return merged.toArray(new PrestimeCPUCCTNode[0]);\n    }\n    \n    public PrestimeCPUCCTNode getReverseRootNode(final int view, Collection<Integer> threads, boolean merge) {\n        int[] threadIds = getThreadIds();\n        List<PrestimeCPUCCTNode> nodes = new ArrayList();\n        for (int i = 0; i < threadIds.length; i++) {\n            final int threadIdF = threadIds[i];\n            if (threads == null || threads.contains(threadIdF)) {\n                final CPUCCTContainer containerF = getContainerForThread(threadIdF, view);\n                final FlatProfileContainer flatF = containerF.getFlatProfile();\n                \n                class ThreadNodeBacked extends PrestimeCPUCCTNodeBacked {\n                    ThreadNodeBacked() {\n                        super(containerF, null);\n                        nCalls = (int)flatF.getNTotalInvocations();\n                        totalTime0 = containerF.getWholeGraphNetTime0();\n                        totalTime1 = containerF.isCollectingTwoTimeStamps() ? containerF.getWholeGraphNetTime1() : 0;\n                        nChildren = flatF.getNRows();\n                    }\n                    PrestimeCPUCCTNode createCopy() {\n                        ThreadNodeBacked copy = new ThreadNodeBacked();\n                        setupCopy(copy);\n                        return copy;\n                    }\n                    public PrestimeCPUCCTNode[] getChildren() {\n                        if (nChildren == 0) return null;\n                        \n                        if (children == null) {\n                            children = new PrestimeCPUCCTNode[flatF.getNRows()];\n                            for (int m = 0; m < children.length; m++) {\n                                final int mF = m;\n                                final int methodIdF = flatF.getMethodIdAtRow(m);\n                                \n                                class ReverseNodeBacked extends PrestimeCPUCCTNodeBacked {\n                                    ReverseNodeBacked() {\n                                        nChildren = 1;\n                                        container = ThreadNodeBacked.this.container;\n                                        methodId = methodIdF;\n                                        nCalls = flatF.getNInvocationsAtRow(mF);\n                                        totalTime0 = flatF.getTotalTimeInMcs0AtRow(mF);\n                                        totalTime1 = flatF.isCollectingTwoTimeStamps() ? flatF.getTotalTimeInMcs1AtRow(mF) : 0;\n                                        parent = ThreadNodeBacked.this;\n                                    }\n                                    PrestimeCPUCCTNode createCopy() {\n                                        ReverseNodeBacked copy = new ReverseNodeBacked();\n                                        setupCopy(copy);\n                                        return copy;\n                                    }\n                                    public PrestimeCPUCCTNode[] getChildren() {\n                                        if (nChildren == 0) return null;\n                                        \n                                        if (children == null) {\n                                            PrestimeCPUCCTNode r = getReverseCCT(threadIdF, methodIdF, view);\n                                            children = r.children;\n                                            nChildren = children == null ? 0 : children.length;\n                                            if (nChildren > 0) for (PrestimeCPUCCTNode ch : children) ch.parent = this;\n                                        }\n\n                                        return children;\n                                    }\n                                }\n                                \n                                children[m] = new ReverseNodeBacked();\n                            }\n                        }\n\n                        return children;\n                    }\n                }\n                \n                nodes.add(new ThreadNodeBacked());\n            }\n        }\n        \n        generateDataForView(view);\n        \n        PrestimeCPUCCTNode[] _nodes = nodes.toArray(new PrestimeCPUCCTNode[0]);\n        PrestimeCPUCCTNode root = new PrestimeCPUCCTNodeBacked(threadCCTContainers[view][0], merge ? mergedChildren(_nodes) : _nodes);\n        return fixNCalls(root);\n    }\n    \n    public FilterSortSupport.Configuration getFilterSortInfo(CCTNode node) {\n        return sortInfo(node);\n    }\n    \n    private FilterSortSupport.Configuration sortInfo(CCTNode node) {\n        while (node.getParent() != null)\n            node = node.getParent();\n        FilterSortSupport.Configuration config = sortInfos.get(node);\n        if (config == null) {\n            config = new FilterSortSupport.Configuration();\n            sortInfos.put(node, config);\n        }\n        return config;\n    }\n    \n    public void filterForward(final String filter, final int filterType, final PrestimeCPUCCTNodeBacked root) {\n//        FilterSortSupport.Configuration config = sortInfo(root);\n//        config.setFilterInfo(filter, filterType);\n//        \n//        if (!FilterSortSupport.passesFilter(config, root.getNodeName())) {\n////            root.setFilteredNode();\n//        } else {\n////            root.resetFilteredNode();\n//        }\n//        root.resetChildren();\n    }\n    \n    public void filterReverse(String filter, int filterType, PrestimeCPUCCTNodeFree root, int view) {\n//        PrestimeCPUCCTNodeFree rev = (PrestimeCPUCCTNodeFree)getReverseCCT(\n//                root.getContainer().getThreadId(), root.getMethodId(), view);\n//        FilterSortSupport.Configuration config = sortInfo(root);\n//        config.setFilterInfo(filter, filterType);\n//        filter(config, rev);\n//        root.children = rev.children;\n//        if (root.children != null) {\n//            for (PrestimeCPUCCTNode ch : root.children)\n//                ch.parent = root;\n//            \n//            root.sortChildren(config.getSortBy(), config.getSortOrder());\n//        }\n//        if (!FilterSortSupport.passesFilter(config, root.getNodeName())) {\n////            root.setFilteredNode();\n//        } else {\n////            root.resetFilteredNode();\n//        }\n    }\n    \n//    private void filter(FilterSortSupport.Configuration config, PrestimeCPUCCTNodeFree node) {\n//        if (node.children != null) {\n//            PrestimeCPUCCTNodeFree filtered = null;\n//            List<PrestimeCPUCCTNodeFree> ch = new ArrayList();\n//            for (PrestimeCPUCCTNode n : node.children) {\n//                PrestimeCPUCCTNodeFree nn = (PrestimeCPUCCTNodeFree)n;\n//                if (FilterSortSupport.passesFilter(config, nn.getNodeName())) {\n//                    int i = ch.indexOf(nn);\n//                    if (i == -1) ch.add(nn);\n//                    else ch.get(i).merge(nn);\n//                } else {\n//                    if (filtered == null) {\n////                        nn.setFilteredNode();\n//                        filtered = nn;\n//                        ch.add(nn);\n//                    } else {\n//                        filtered.merge(nn);\n//                    }\n//                }\n//            }\n//            \n//            if (ch.isEmpty()) {\n//                node.children = null;\n//            } else {\n//                if (node.isFiltered() && filtered != null && ch.size() == 1) {\n//                    // \"naive\" approach, collapse simple chain of filtered out nodes\n//                    PrestimeCPUCCTNodeFree n = ch.get(0);\n//                    filter(config, n);\n//                    node.children = n.children;\n//                } else {\n//                    node.children = ch.toArray(new PrestimeCPUCCTNodeFree[0]);\n//                }\n//            }\n//            \n//            if (node.children != null)\n//                for (PrestimeCPUCCTNode n : node.children)\n//                    filter(config, (PrestimeCPUCCTNodeFree)n);\n//        }\n//    }\n\n    public int[] getThreadIds() {\n        int[] ret = new int[threadCCTContainers[METHOD_LEVEL_VIEW].length];\n\n        for (int i = 0; i < threadCCTContainers[METHOD_LEVEL_VIEW].length; i++) {\n            ret[i] = threadCCTContainers[METHOD_LEVEL_VIEW][i].threadId;\n        }\n\n        return ret;\n    }\n\n    public String getThreadNameForId(int threadId) {\n        return getThreadNames()[getContainerIdForThreadId(threadId)];\n    }\n\n    public String[] getThreadNames() {\n        String[] ret = new String[threadCCTContainers[METHOD_LEVEL_VIEW].length];\n\n        for (int i = 0; i < threadCCTContainers[METHOD_LEVEL_VIEW].length; i++) {\n            ret[i] = threadCCTContainers[METHOD_LEVEL_VIEW][i].threadName;\n        }\n\n        return ret;\n    }\n    \n    public CPUResultsSnapshot createDiff(CPUResultsSnapshot snapshot) {\n        if (!(snapshot instanceof CPUResultsSnapshot)) return null;\n        return new CPUResultsDiff(this, (CPUResultsSnapshot)snapshot);\n    }\n    \n    void readFromSnapshot(CPUResultsSnapshot s) {\n        beginTime = s.beginTime;\n        timeTaken = s.timeTaken;\n        collectingTwoTimeStamps = s.collectingTwoTimeStamps;\n        \n        nInstrMethods = s.nInstrMethods;\n        instrMethodClassesViews = s.instrMethodClassesViews;\n        \n        instrMethodNames = s.instrMethodNames;\n        instrMethodSignatures = s.instrMethodSignatures;\n        \n        threadCCTContainers = new CPUCCTContainer[3][];\n        CPUCCTContainer[] scontainers = s.threadCCTContainers[METHOD_LEVEL_VIEW];\n        int nThreads = scontainers.length;\n        CPUCCTContainer[] containers = new CPUCCTContainer[nThreads];\n        threadCCTContainers[METHOD_LEVEL_VIEW] = containers;\n        \n        threadIdMap = s.threadIdMap;\n        for (int i = 0; i < nThreads; i++) {\n            containers[i] = new CPUCCTContainer(this);\n            \n            containers[i].threadId = scontainers[i].threadId;\n            containers[i].threadName = scontainers[i].threadName;\n\n            containers[i].collectingTwoTimeStamps = scontainers[i].collectingTwoTimeStamps;\n\n            containers[i].compactData = scontainers[i].compactData;\n\n            containers[i].childOfsSize = scontainers[i].childOfsSize;\n\n            containers[i].nodeSize = scontainers[i].nodeSize;\n\n            containers[i].wholeGraphGrossTimeAbs = scontainers[i].wholeGraphGrossTimeAbs;\n            containers[i].wholeGraphGrossTimeThreadCPU = scontainers[i].wholeGraphGrossTimeThreadCPU;\n            containers[i].timeInInjectedCodeInAbsCounts = scontainers[i].timeInInjectedCodeInAbsCounts;\n            containers[i].timeInInjectedCodeInThreadCPUCounts = scontainers[i].timeInInjectedCodeInThreadCPUCounts;\n            containers[i].wholeGraphPureTimeAbs = scontainers[i].wholeGraphPureTimeAbs;\n            containers[i].wholeGraphPureTimeThreadCPU = scontainers[i].wholeGraphPureTimeThreadCPU;\n            containers[i].wholeGraphNetTime0 = scontainers[i].wholeGraphNetTime0;\n            containers[i].wholeGraphNetTime1 = scontainers[i].wholeGraphNetTime1;\n            containers[i].totalInvNo = scontainers[i].totalInvNo;\n            containers[i].displayWholeThreadCPUTime = scontainers[i].displayWholeThreadCPUTime;\n\n            containers[i].rootNode = new PrestimeCPUCCTNodeBacked(containers[i], null, 0);\n\n            if (containers[i].getMethodIdForNodeOfs(0) == 0) {\n                containers[i].rootNode.setThreadNode();\n            }\n        }\n        \n        allThreadsMergedCCTContainers = new CPUCCTContainer[3];\n        rootNode = new PrestimeCPUCCTNode[3];\n        rootNode[METHOD_LEVEL_VIEW] = createRootNodeForAllThreads(METHOD_LEVEL_VIEW);\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        super.readFromStream(in);\n        collectingTwoTimeStamps = in.readBoolean();\n\n        nInstrMethods = in.readInt();\n        instrMethodClassesViews = new String[3][];\n\n        String[] classNames = new String[nInstrMethods];\n        instrMethodClassesViews[METHOD_LEVEL_VIEW] = classNames;\n        instrMethodNames = new String[nInstrMethods];\n        instrMethodSignatures = new String[nInstrMethods];\n\n        for (int i = 0; i < nInstrMethods; i++) {\n            classNames[i] = in.readUTF();\n            instrMethodNames[i] = in.readUTF();\n            instrMethodSignatures[i] = in.readUTF();\n        }\n\n        int nThreads = in.readInt();\n        threadCCTContainers = new CPUCCTContainer[3][];\n\n        CPUCCTContainer[] containers = new CPUCCTContainer[nThreads];\n        threadCCTContainers[METHOD_LEVEL_VIEW] = containers;\n\n        for (int i = 0; i < nThreads; i++) {\n            containers[i] = new CPUCCTContainer(this);\n            containers[i].readFromStream(in);\n            threadIdMap.put(Integer.valueOf(containers[i].threadId), Integer.valueOf(i));\n        }\n\n        allThreadsMergedCCTContainers = new CPUCCTContainer[3];\n        rootNode = new PrestimeCPUCCTNode[3];\n        rootNode[METHOD_LEVEL_VIEW] = createRootNodeForAllThreads(METHOD_LEVEL_VIEW);\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            debugValues();\n        }\n    }\n\n    // -- Methods for saving/retrieving sorting parameters\n    public void saveSortParams(int sortBy, boolean sortOrder, CCTNode node) {\n        FilterSortSupport.Configuration config = sortInfo(node);\n        config.setSortInfo(sortBy, sortOrder);\n    }\n\n    public String toString() {\n        return MessageFormat.format(CPU_MSG, new Object[] { super.toString() });\n    }\n\n    //---- Serialization support\n    public void writeToStream(DataOutputStream out) throws IOException {\n        super.writeToStream(out);\n        out.writeBoolean(collectingTwoTimeStamps);\n\n        out.writeInt(nInstrMethods);\n\n        String[] classNames = instrMethodClassesViews[METHOD_LEVEL_VIEW];\n\n        for (int i = 0; i < nInstrMethods; i++) {\n            out.writeUTF(classNames[i]);\n            out.writeUTF(instrMethodNames[i]);\n            out.writeUTF(instrMethodSignatures[i]);\n        }\n\n        CPUCCTContainer[] containers = threadCCTContainers[METHOD_LEVEL_VIEW];\n        int nThreads = containers.length;\n        out.writeInt(nThreads);\n\n        for (int i = 0; i < nThreads; i++) {\n            containers[i].writeToStream(out);\n        }\n    }\n\n    private int getContainerIdForThreadId(int threadId) {\n        Integer tid = Integer.valueOf(threadId);\n        Integer cId = null;\n\n        if (threadIdMap.containsKey(tid)) {\n            cId = (Integer) threadIdMap.get(tid);\n        }\n\n        return (cId != null) ? cId.intValue() : 0;\n    }\n\n    protected PrestimeCPUCCTNode createRootNodeForAllThreads(int view) {\n        generateDataForView(view);\n        \n        CPUCCTContainer[] ccts = threadCCTContainers[view];\n        int len = ccts.length;\n        PrestimeCPUCCTNode[] threadNodes = new PrestimeCPUCCTNode[len];\n\n        for (int i = 0; i < len; i++) {\n            PrestimeCPUCCTNode tRootNode = ccts[i].getRootNode();\n\n            if (!tRootNode.isThreadNode()) {\n                threadNodes[i] = new PrestimeCPUCCTNodeBacked(ccts[i], new PrestimeCPUCCTNode[] { tRootNode });\n            } else {\n                threadNodes[i] = tRootNode;\n            }\n        }\n\n        allThreadsMergedCCTContainers[view] = new AllThreadsMergedCPUCCTContainer(this, threadNodes, view);\n\n        return allThreadsMergedCCTContainers[view].getRootNode();\n    }\n    \n    protected CPUCCTContainer createContainerForThreads(Collection<Integer> threads, int view) {\n        generateDataForView(view);\n        \n        CPUCCTContainer[] ccts = threadCCTContainers[view];\n        PrestimeCPUCCTNode[] threadNodes = new PrestimeCPUCCTNode[threads.size()];\n        int threadIdx = 0;\n\n        for (CPUCCTContainer cct : ccts) {\n            if (threads.contains(cct.getThreadId())) {\n                PrestimeCPUCCTNode tRootNode = cct.getRootNode();\n                if (tRootNode.isThreadNode()) threadNodes[threadIdx++] = tRootNode;\n                else threadNodes[threadIdx++] = new PrestimeCPUCCTNodeBacked(cct,\n                                                new PrestimeCPUCCTNode[] { tRootNode });\n            }\n        }\n\n        return new AllThreadsMergedCPUCCTContainer(this, threadNodes, view);\n    }\n    \n    private void debugValues() {\n        LOGGER.log(Level.FINEST, \"collectingTwoTimeStamps: {0}\", collectingTwoTimeStamps); // NOI18N\n        LOGGER.log(Level.FINEST, \"threadCCTContainers.length: {0}\", debugLength(threadCCTContainers)); // NOI18N\n        LOGGER.log(Level.FINEST, \"allThreadsMergedCCTContainers.length: {0}\", debugLength(allThreadsMergedCCTContainers));\n        LOGGER.log(Level.FINEST, \"rootNode.length: {0}\", debugLength(rootNode)); // NOI18N\n        LOGGER.log(Level.FINEST, \"instrMethodClassesViews.length: {0}\", debugLength(instrMethodClassesViews));\n        LOGGER.log(Level.FINEST, \"instrMethodNames.length: {0}\", debugLength(instrMethodNames)); // NOI18N\n        LOGGER.log(Level.FINEST, \"instrMethodSignatures.length: {0}\", debugLength(instrMethodSignatures));\n        LOGGER.log(Level.FINEST, \"nInstrMethods: {0}\", nInstrMethods); // NOI18N\n//        LOGGER.log(Level.FINEST, \"sortNodesBy: {0}\", sortNodesBy); // NOI18N\n//        LOGGER.log(Level.FINEST, \"sortNodesOrder: {0}\", sortNodesOrder); // NOI18N\n    }\n\n    /**\n     * callChainType code can be:\n     * 1 - call chains with invocations and timings;\n     * 2 - call chains with invocation numbers only;\n     * 3 - call chains with no timings and/or invocation numbers.\n     * /\n     * public StringBuffer getResultsInCSVFormat(int callChainTypeCode, ExportDataDumper dataDumper) {\n     * //!!! Need to copy here a whole lot of stuff from CPUCCTManager\n     *      \n     * return null;\n     * }\n     */\n\n    //------------------------------------ Private implementation ----------------------------------------------------\n\n    /**\n     * If data for the provided view have not yet been initialized, it creates threadCCTContainers[view],\n     * rootNode[view] and allThreadsMergedCCTContainers[view].\n     *\n     * @param view either of METHOD_LEVEL_VIEW, CLASS_LEVEL_VIEW or PACKAGE_LEVEL_VIEW\n     */\n    private void generateDataForView(int view) {\n        if (threadCCTContainers[view] == null) {\n            MethodIdMap methodIdMap = new MethodIdMap(instrMethodClassesViews[METHOD_LEVEL_VIEW], nInstrMethods, view);\n            int len = threadCCTContainers[METHOD_LEVEL_VIEW].length;\n            threadCCTContainers[view] = new CPUCCTContainer[len];\n\n            for (int i = 0; i < len; i++) {\n                threadCCTContainers[view][i] = new CPUCCTClassContainer(threadCCTContainers[METHOD_LEVEL_VIEW][i], methodIdMap,\n                                                                        view);\n            }\n\n            rootNode[view] = createRootNodeForAllThreads(view);\n            instrMethodClassesViews[view] = methodIdMap.getInstrClassesOrPackages();\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/CPUSamplingDataFrameProcessor.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils.TargetAppOrVMTerminated;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.ProfilingResultListener;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.StackTraceSnapshotBuilder.SampledThreadInfo;\nimport org.graalvm.visualvm.lib.jfluid.results.locks.AbstractLockDataFrameProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.JMethodIdTable;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.JMethodIdTable.JMethodIdTableEntry;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.DefaultMethodNameFormatter;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatter;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatterFactory;\n\n/**\n * This class main purpose is to parse a chunk of CPU sampled data received from\n * the JFluid server agent and dispatch the resulting events to all interested parties\n * @author Tomas Hurka\n */\npublic class CPUSamplingDataFrameProcessor extends AbstractLockDataFrameProcessor {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n    private String currentThreadName, currentThreadClassName;\n    private long currentTimestamp;\n    private Map<Integer,ThreadInfo> currentThreadsDump;\n    private Map<Integer,ThreadInfo> lastThreadsDump;\n    private List<ThreadDump> threadDumps = new ArrayList();\n    private MethodNameFormatter formatter = MethodNameFormatterFactory.getDefault(new DefaultMethodNameFormatter(DefaultMethodNameFormatter.VERBOSITY_FULLMETHOD)).getFormatter();\n    private StackTraceSnapshotBuilder builder;\n    \n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    public void doProcessDataFrame(ByteBuffer buffer) {\n        JMethodIdTable methodIdsTable = client.getJMethodIdTable();\n        \n        threadDumps = new ArrayList();\n        while (buffer.hasRemaining()) {\n            byte eventType = buffer.get();\n            \n            switch (eventType) {    \n                case CommonConstants.THREAD_DUMP_START:\n                    currentThreadsDump = new HashMap();\n                    currentTimestamp = getTimeStamp(buffer);\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Thread dump start: Timestamps:\"+currentTimestamp); // NOI18N\n                    }\n                    break;\n                case CommonConstants.NEW_THREAD: {\n                    int threadId = buffer.getChar();\n                    String threadName = getString(buffer);\n                    String threadClassName = getString(buffer);\n                    \n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Creating new thread: tId=\"+threadId+\" name=\"+threadName); // NOI18N\n                    }\n                    \n                    currentThreadId = threadId;\n                    currentThreadName = threadName;\n                    currentThreadClassName = threadClassName;\n                    fireNewThread(threadId, threadName, threadClassName);\n                    break;\n                }\n                case CommonConstants.SET_FOLLOWING_EVENTS_THREAD: {\n                    currentThreadId = buffer.getChar();\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.log(Level.FINEST, \"Change current thread , tId={0}\", currentThreadId); // NOI18N\n                    }\n\n                    break;\n                }\n                case CommonConstants.THREAD_INFO_IDENTICAL: {\n                    int threadId = buffer.getChar();\n                    Integer threadIdObj = Integer.valueOf(threadId);\n                    ThreadInfo lastInfo = lastThreadsDump.get(threadIdObj);\n                    assert lastInfo != null;\n                    currentThreadsDump.put(threadIdObj,lastInfo);\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Thread info identical: tId:\"+threadId); // NOI18N\n                    }\n                    break;\n                }\n                case CommonConstants.THREAD_INFO: {\n                    int threadId = buffer.getChar();\n                    byte state = buffer.get();\n                    int stackLen = buffer.getChar();\n                    int methodIds[] = new int[stackLen];\n                    ThreadInfo info;\n                    \n                    for (int i=0; i<stackLen; i++) {\n                        methodIds[i] = buffer.getInt();\n                        methodIdsTable.checkMethodId(methodIds[i]);\n                    }\n                    if (currentThreadId == threadId) {\n                        info = new ThreadInfo(currentThreadName,threadId,state,methodIds);\n                    } else {\n                        info = new ThreadInfo(null,threadId,state,methodIds);                        \n                    }\n                    currentThreadsDump.put(Integer.valueOf(threadId),info);\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Thread info: tId:\"+threadId+\" state:\"+state+\" mIds:\"+Arrays.toString(methodIds)); // NOI18N\n                    }\n                    break;  \n                }\n                case CommonConstants.THREAD_DUMP_END: {\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Thread dump end\"); // NOI18N\n                    }\n                    lastThreadsDump = currentThreadsDump;\n                    threadDumps.add(new ThreadDump(currentTimestamp,currentThreadsDump));\n                    break;\n                }\n                case CommonConstants.RESET_COLLECTORS: {\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Profiling data reset\"); // NOI18N\n                    }\n                    fireReset();\n                    builder.reset();\n                    break;\n                }\n                case CommonConstants.NEW_MONITOR: {\n                    int hash = buffer.getInt();\n                    String className = getString(buffer);\n\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.log(Level.FINEST, \"Creating new monitor , monitorId={0} , className={1}\", new Object[] {Integer.toHexString(hash), className}); // NOI18N\n                    }\n\n                    fireNewMonitor(hash, className);\n                    break;\n                }\n                case CommonConstants.METHOD_ENTRY_MONITOR:\n                case CommonConstants.METHOD_EXIT_MONITOR: {\n                    long timeStamp0 = getTimeStamp(buffer);\n                    long timeStamp1 = -1;\n                    int hash = buffer.getInt();\n                    \n                    if (eventType == CommonConstants.METHOD_ENTRY_MONITOR) {\n                        int ownerThreadId = buffer.getInt();\n                        if (LOGGER.isLoggable(Level.FINEST)) {\n                            LOGGER.log(Level.FINEST, \"Monitor entry , tId={0} , monitorId={1} , ownerId={2}\", new Object[]{currentThreadId,Integer.toHexString(hash),ownerThreadId}); // NOI18N\n                        }\n\n                        fireMonitorEntry(currentThreadId, timeStamp0, timeStamp1, hash, ownerThreadId);\n                    }\n                    if (eventType == CommonConstants.METHOD_EXIT_MONITOR) {\n                        if (LOGGER.isLoggable(Level.FINEST)) {\n                            LOGGER.log(Level.FINEST, \"Monitor exit , tId={0} , monitorId={1}\", new Object[]{currentThreadId,Integer.toHexString(hash)}); // NOI18N\n                        }\n\n                        fireMonitorExit(currentThreadId, timeStamp0, timeStamp1, hash);\n                    }\n                    break;\n                }\n                case CommonConstants.ADJUST_TIME: {\n                    long timeStamp0 = getTimeStamp(buffer);\n                    long timeStamp1 = collectingTwoTimeStamps ? getTimeStamp(buffer) : 0;\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.log(Level.FINEST, \"Adjust time , tId={0}\", currentThreadId); // NOI18N\n                    }\n\n                    fireAdjustTime(currentThreadId, timeStamp0, timeStamp1);\n\n                    break;\n                }\n                default: {\n                    LOGGER.log(Level.SEVERE, \"*** Profiler Engine: internal error: got unknown event type in CPUSamplingDataFrameProcessor: {0} at {1}\", // NOI18N\n                            new Object[]{(int) eventType, buffer.position()});\n                    \n                    break;\n                }\n            }\n        }\n        try {\n            methodIdsTable.getNamesForMethodIds(client);\n        } catch (TargetAppOrVMTerminated ex) {\n            ProfilerLogger.log(ex.getMessage());\n            return;\n        }\n        processCollectedDumps(methodIdsTable,threadDumps);\n        threadDumps.clear();\n    }\n\n    public void startup(ProfilerClient client) {\n        final CPUCallGraphBuilder[] ccgb = new CPUCallGraphBuilder[1];\n        \n        super.startup(client);\n        \n        foreachListener(new ListenerFunctor() {\n            public void execute(ProfilingResultListener listener) {\n                if (listener instanceof CPUCallGraphBuilder) {\n                    ccgb[0] = (CPUCallGraphBuilder) listener;\n                }\n            }\n        });\n        builder = new StackTraceSnapshotBuilder(ccgb[0],client.getSettings().getInstrumentationFilter(),client.getStatus());\n    }\n    \n    public void shutdown() {\n        super.shutdown();\n        builder = null;\n    }\n  \n    private static Thread.State getThreadState(int threadState) {\n        switch (threadState) {\n            case CommonConstants.THREAD_STATUS_UNKNOWN:\n                return Thread.State.TERMINATED;\n            case CommonConstants.THREAD_STATUS_ZOMBIE:\n                return Thread.State.TERMINATED;\n            case CommonConstants.THREAD_STATUS_RUNNING:\n                return Thread.State.RUNNABLE;\n            case CommonConstants.THREAD_STATUS_SLEEPING:\n                return Thread.State.TIMED_WAITING;\n            case CommonConstants.THREAD_STATUS_MONITOR:\n                return Thread.State.BLOCKED;\n            case CommonConstants.THREAD_STATUS_WAIT:\n            case CommonConstants.THREAD_STATUS_PARK:\n                return Thread.State.WAITING;\n            default:\n                return Thread.State.TERMINATED;\n        }\n    }\n\n    private void processCollectedDumps(JMethodIdTable methodIdTable, List<ThreadDump> threadDumps) {\n        Map<Integer,StackTraceElement> stackTraceElements = new HashMap();\n        InstrumentationFilter filter = builder.getFilter();\n        \n        for (ThreadDump td : threadDumps) {\n            SampledThreadInfo[] sampledThreadInfos = new SampledThreadInfo[td.threadDumps.length];\n            int tindex = 0;\n            \n            for (ThreadInfo ti : td.threadDumps) {\n                int[] methodIds = ti.methodsIds;\n                StackTraceElement[] stackTrace = new StackTraceElement[methodIds.length];\n\n                for (int i=0; i<methodIds.length; i++) {\n                    int methodId = methodIds[i];\n                    StackTraceElement el = stackTraceElements.get(Integer.valueOf(methodId));\n                    \n                    if (el == null) {\n                        JMethodIdTableEntry entry = methodIdTable.getEntry(methodId);\n                        String method = formatter.formatMethodName(entry.className, entry.methodName, entry.methodSig).toFormatted();\n                        String className = entry.className.replace('/','.'); // NOI18N\n                        String methodName = method+StackTraceSnapshotBuilder.NAME_SIG_SPLITTER+entry.methodSig;\n                        el = new StackTraceElement(className, methodName, null, entry.isNative?-2:-1);\n                        stackTraceElements.put(Integer.valueOf(methodId),el);\n                    }\n                    stackTrace[i] = el;\n                }\n                sampledThreadInfos[tindex++] = new SampledThreadInfo(ti.threadName,ti.threadId,ti.state,stackTrace,filter);\n            }\n            builder.addStacktrace(sampledThreadInfos,td.timestamp);\n        }\n    }\n    \n    private static final class ThreadInfo {\n        private int[] methodsIds;\n        private Thread.State state;\n        private String threadName;\n        private long threadId;\n \n        ThreadInfo(String tn, long tid, byte ts, int[] st) {\n            threadName = tn;\n            threadId = tid;\n            state = getThreadState(ts);\n            methodsIds = st;\n        }\n    }\n     \n    private static final class ThreadDump {\n        private long timestamp;\n        private ThreadInfo[] threadDumps;\n        \n        ThreadDump(long ts, Map<Integer,ThreadInfo> threadsMap) {\n            timestamp = ts;\n            threadDumps = threadsMap.values().toArray(new ThreadInfo[0]);\n        }\n    }    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/DiffCPUCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport java.util.*;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.FilterSortSupport;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass DiffCPUCCTNode extends PrestimeCPUCCTNodeBacked {\n\n    final PrestimeCPUCCTNode node1;\n    final PrestimeCPUCCTNode node2;\n\n\n    DiffCPUCCTNode(PrestimeCPUCCTNode n1, PrestimeCPUCCTNode n2) {\n        node1 = n1;\n        node2 = n2;\n        container = node1 == null ? node2.container : node1.container;\n    }\n\n\n    DiffCPUCCTNode createCopy() {\n        DiffCPUCCTNode copy = new DiffCPUCCTNode(node1, node2);\n        setupCopy(copy);\n        return copy;\n    }\n\n\n    public DiffCPUCCTNode createFilteredNode() {\n        DiffCPUCCTNode filtered = new DiffCPUCCTNode(node1, node2);\n        setupFilteredNode(filtered);\n        return filtered;\n    }\n\n    public DiffCPUCCTNode createRootCopy() {\n//        PrestimeCPUCCTNodeBacked copy1 = node1.createRootCopy();\n//        PrestimeCPUCCTNodeBacked copy2 = node2.createRootCopy();\n//        return new DiffCPUCCTNode(copy1, copy2);\n        return null; // Subtrees currently not supported\n    }\n\n\n    @Override\n    public CCTNode getChild(int index) {\n        getChildren();\n\n        if (index < children.length) {\n            return children[index];\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public CCTNode[] getChildren() {\n        if (children != null) return children;\n\n        PrestimeCPUCCTNode[] children1 = node1 == null ? null : (PrestimeCPUCCTNode[])node1.getChildren();\n        PrestimeCPUCCTNode[] children2 = node2 == null ? null : (PrestimeCPUCCTNode[])node2.getChildren();\n\n        if (children1 == null) children1 = new PrestimeCPUCCTNode[0];\n        if (children2 == null) children2 = new PrestimeCPUCCTNode[0];\n        children = computeChildren(children1, children2, this);\n        \n        if (children == null) children = new PrestimeCPUCCTNode[0];\n        nChildren = children.length;\n        \n        return children;\n    }\n    \n    private static PrestimeCPUCCTNode[] computeChildren(PrestimeCPUCCTNode[] children1, PrestimeCPUCCTNode[] children2, PrestimeCPUCCTNode parent) {        \n        Map<String, PrestimeCPUCCTNode> nodes1 = new HashMap();\n        for (PrestimeCPUCCTNode node : children1) {\n            String name = node.getNodeName();\n            PrestimeCPUCCTNode sameNode = nodes1.get(name);\n            if (sameNode == null) nodes1.put(name, node.createCopy());\n            else sameNode.merge(node); // Merge same-named items\n        }\n        \n        Map<String, PrestimeCPUCCTNode> nodes2 = new HashMap();\n        for (PrestimeCPUCCTNode node : children2) {\n            String name = node.getNodeName();\n            PrestimeCPUCCTNode sameNode = nodes2.get(name);\n            if (sameNode == null) nodes2.put(name, node.createCopy());\n            else sameNode.merge(node); // Merge same-named items\n        }\n        \n        List<PrestimeCPUCCTNode> children = new ArrayList();\n        for (PrestimeCPUCCTNode node1 : nodes1.values()) {\n            PrestimeCPUCCTNode node2 = nodes2.get(node1.getNodeName());\n            if (node2 != null) children.add(new DiffCPUCCTNode(node1, node2));\n            else children.add(new DiffCPUCCTNode(node1, null));\n        }\n        for (PrestimeCPUCCTNode node2 : nodes2.values()) {\n            if (!nodes1.containsKey(node2.getNodeName())) children.add(new DiffCPUCCTNode(null, node2));\n        }\n        \n        for (PrestimeCPUCCTNode child : children) child.parent = parent;\n        \n        return children.toArray(new PrestimeCPUCCTNode[0]);\n    }\n    \n    protected void resetChildren() {\n        if (node1 != null) node1.resetChildren();\n        if (node2 != null) node2.resetChildren();\n        children = null;\n    }\n\n    @Override\n    public int getMethodId() {\n        return node1 == null ? (-node2.getMethodId()) : node1.getMethodId();\n    }\n\n    @Override\n    public int getNCalls() {\n        int nCalls1 = node1 == null ? 0 : node1.getNCalls();\n        int nCalls2 = node2 == null ? 0 : node2.getNCalls();\n        return nCalls2 - nCalls1 + nCalls;\n    }\n\n    @Override\n    public int getNChildren() {\n        return getChildren().length;\n    }\n    \n    public boolean isLeaf() {\n        boolean leaf1 = node1 == null || node1.isLeaf();\n        boolean leaf2 = node2 == null || node2.isLeaf();\n        return leaf1 && leaf2;\n    }\n\n    @Override\n    public long getSleepTime0() {\n        long sleepTime0_1 = node1 == null ? 0 : node1.getSleepTime0();\n        long sleepTime0_2 = node2 == null ? 0 : node2.getSleepTime0();\n        return sleepTime0_2 - sleepTime0_1 + sleepTime0;\n    }\n\n    @Override\n    public int getThreadId() {\n        return node1 == null ? node2.getThreadId() : node1.getThreadId();\n    }\n\n    @Override\n    public long getTotalTime0() {\n        long totalTime0_1 = node1 == null ? 0 : node1.getTotalTime0();\n        long totalTime0_2 = node2 == null ? 0 : node2.getTotalTime0();\n        return totalTime0_2 - totalTime0_1 + totalTime0;\n    }\n\n    @Override\n    public float getTotalTime0InPerCent() {\n        float totalTime0ipc_1 = node1 == null ? 0 : node1.getTotalTime0InPerCent();\n        float totalTime0ipc_2 = node2 == null ? 0 : node2.getTotalTime0InPerCent();\n        return totalTime0ipc_2 - totalTime0ipc_1;\n    }\n\n    @Override\n    public long getTotalTime1() {\n        long totalTime1_1 = node1 == null ? 0 : node1.getTotalTime1();\n        long totalTime1_2 = node2 == null ? 0 : node2.getTotalTime1();\n        return totalTime1_2 - totalTime1_1 + totalTime1;\n    }\n\n    @Override\n    public float getTotalTime1InPerCent() {\n        float totalTime1ipc_1 = node1 == null ? 0 : node1.getTotalTime1InPerCent();\n        float totalTime1ipc_2 = node2 == null ? 0 : node2.getTotalTime1InPerCent();\n        return totalTime1ipc_2 - totalTime1ipc_1;\n    }\n\n    @Override\n    public long getWaitTime0() {\n        long waitTime0_1 = node1 == null ? 0 : node1.getWaitTime0();\n        long waitTime0_2 = node2 == null ? 0 : node2.getWaitTime0();\n        return waitTime0_2 - waitTime0_1 + waitTime0;\n    }\n\n    @Override\n    public void sortChildren(int sortBy, boolean sortOrder) {\n//        if (node1 != null) node1.sortChildren(sortBy, sortOrder);\n//        if (node2 != null) node2.sortChildren(sortBy, sortOrder);\n//        super.sortChildren(sortBy, sortOrder);\n    }    \n    \n    \n    @Override\n    public String getNodeName() {\n        if (isFiltered()) return FilterSortSupport.FILTERED_OUT_LBL;\n        return node1 == null ? node2.getNodeName() : node1.getNodeName();\n    }\n    \n//    public void setSelfTimeNode() {\n//        if (node1 != null) node1.setSelfTimeNode();\n//        if (node2 != null) node2.setSelfTimeNode();\n//    }\n    \n    @Override\n    public boolean isSelfTimeNode() {\n        return node1 == null ? node2.isSelfTimeNode() : node1.isSelfTimeNode();\n    }\n    \n//    public void setThreadNode() {\n//        if (node1 != null) node1.setThreadNode();\n//        if (node2 != null) node2.setThreadNode();\n//    }\n\n    @Override\n    public boolean isThreadNode() {\n        return node1 == null ? node2.isThreadNode() : node1.isThreadNode();\n    }\n    \n    @Override\n    public boolean isContextCallsNode() {\n        return node1 == null ? node2.isContextCallsNode() : node1.isContextCallsNode();\n    }\n    \n//    public void setFilteredNode() {\n//        if (node1 != null) node1.setFilteredNode();\n//        if (node2 != null) node2.setFilteredNode();\n//    }\n    \n//    public void resetFilteredNode() {\n//        if (node1 != null) node1.resetFilteredNode();\n//        if (node2 != null) node2.resetFilteredNode();\n//    }\n\n//    @Override\n//    public boolean isFilteredNode() {\n//        return node1 == null ? node2.isFilteredNode() : node1.isFilteredNode();\n//    }\n    \n    public boolean equals(Object o) {\n        if (!(o instanceof PrestimeCPUCCTNode)) return false;\n        return getNodeName().equals(((PrestimeCPUCCTNode)o).getNodeName());\n    }\n    \n    public int hashCode() {\n        return getNodeName().hashCode();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/DiffFlatProfileContainer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport java.util.*;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatterFactory;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DiffFlatProfileContainer extends FlatProfileContainer {\n\n    private final ClientUtils.SourceCodeSelection[] sels;\n    private final double wholeGraphNetTime0;\n    private final double wholeGraphNetTime1;\n    private final long minTime;\n    private final long maxTime;\n\n\n    static DiffFlatProfileContainer create(FlatProfileContainer c1, FlatProfileContainer c2) {\n        boolean collectingTwoTimeStamps = c1.collectingTwoTimeStamps && c2.collectingTwoTimeStamps;\n\n        Set<ClientUtils.SourceCodeSelection> sels1 = new HashSet();\n        int rows1 = c1.timeInMcs0.length;\n        for (int i = 0; i < rows1; i++) sels1.add(c1.getSourceCodeSelectionAtRow(i));\n\n        Map<ClientUtils.SourceCodeSelection, Integer> sels2 = new HashMap();\n        int rows2 = c2.timeInMcs0.length;\n        for (int i = 0; i < rows2; i++) sels2.put(c2.getSourceCodeSelectionAtRow(i), i);\n\n        int pointer = 0;\n        long[] timesInMcs0 = new long[rows1 + rows2];\n        long[] timesInMcs1 = collectingTwoTimeStamps ? new long[rows1 + rows2] : null;\n        long[] totalTimesInMcs0 = new long[rows1 + rows2];\n        long[] totalTimesInMcs1 = collectingTwoTimeStamps ? new long[rows1 + rows2] : null;\n        int[] nInvocations = new int[rows1 + rows2];\n        ClientUtils.SourceCodeSelection[] sels = new ClientUtils.SourceCodeSelection[rows1 + rows2];\n        int[] methodIDs = new int[rows1 + rows2];\n\n        for (int i = 0; i < rows1; i++) {\n            ClientUtils.SourceCodeSelection sel = c1.getSourceCodeSelectionAtRow(i);\n            timesInMcs0[pointer] = -c1.timeInMcs0[i];\n            totalTimesInMcs0[pointer] = -c1.totalTimeInMcs0[i];\n            if (collectingTwoTimeStamps) {\n                timesInMcs1[pointer] = -c1.timeInMcs1[i];\n                totalTimesInMcs1[pointer] = -c1.totalTimeInMcs1[i];\n            }\n            nInvocations[pointer] = -c1.nInvocations[i];\n            sels[pointer] = sel;\n            methodIDs[pointer] = c1.methodIds[i];\n            \n            Integer i2 = sels2.get(sel);\n            if (i2 != null) {\n                timesInMcs0[pointer] += c2.timeInMcs0[i2];\n                totalTimesInMcs0[pointer] += c2.totalTimeInMcs0[i2];\n                if (collectingTwoTimeStamps) {\n                    timesInMcs1[pointer] += c2.timeInMcs1[i2];\n                    totalTimesInMcs1[pointer] += c2.totalTimeInMcs1[i2];\n                }\n                nInvocations[pointer] += c2.nInvocations[i2];\n            }\n            pointer++;\n        }\n        \n        for (int i = 0; i < rows2; i++) {\n            ClientUtils.SourceCodeSelection sel = c2.getSourceCodeSelectionAtRow(i);\n            if (!sels1.contains(sel)) {\n                timesInMcs0[pointer] = c2.timeInMcs0[i];\n                totalTimesInMcs0[pointer] = c2.totalTimeInMcs0[i];\n                if (collectingTwoTimeStamps) {\n                    timesInMcs1[pointer] = c2.timeInMcs1[i];\n                    totalTimesInMcs1[pointer] = c2.totalTimeInMcs1[i];\n                }\n                nInvocations[pointer] = c2.nInvocations[i];\n                sels[pointer] = sel;\n                methodIDs[pointer] = -c2.methodIds[i];\n                pointer++;\n            }\n        }\n        \n        double wholeGraphNetTime0 = c2.getWholeGraphNetTime0() - c1.getWholeGraphNetTime0();\n        double wholeGraphNetTime1 = c2.getWholeGraphNetTime1() - c1.getWholeGraphNetTime1();\n        \n        return new DiffFlatProfileContainer(collectingTwoTimeStamps, \n                Arrays.copyOf(timesInMcs0, pointer), collectingTwoTimeStamps ? Arrays.copyOf(timesInMcs1, pointer) : null,\n                Arrays.copyOf(totalTimesInMcs0, pointer), collectingTwoTimeStamps ? Arrays.copyOf(totalTimesInMcs1, pointer) : null,\n                Arrays.copyOf(nInvocations, pointer), Arrays.copyOf(sels, pointer),\n                Arrays.copyOf(methodIDs, pointer), pointer, wholeGraphNetTime0, wholeGraphNetTime1);\n    }\n    \n    private DiffFlatProfileContainer(boolean collectingTwoTimeStamps, long[] timeInMcs0, long[] timeInMcs1, \n             long[] totalTimeInMcs0, long[] totalTimeInMcs1, int[] nInvocations, ClientUtils.SourceCodeSelection[] sels, \n             int[] methodIDs, int nMethods, double wholeGraphNetTime0, double wholeGraphNetTime1) {\n        super(timeInMcs0, timeInMcs1, totalTimeInMcs0, totalTimeInMcs1, nInvocations, null, nMethods);\n        this.collectingTwoTimeStamps = collectingTwoTimeStamps;\n        this.sels = sels;\n        this.wholeGraphNetTime0 = wholeGraphNetTime0;\n        this.wholeGraphNetTime1 = wholeGraphNetTime1;\n        \n        long minTimeX = Long.MAX_VALUE;\n        long maxTimeX = Long.MIN_VALUE;\n        nRows = nMethods;\n        this.methodIds = methodIDs;\n        for (int i = 0; i < nRows; i++) {\n            minTimeX = Math.min(minTimeX, timeInMcs0[i]);\n            maxTimeX = Math.max(maxTimeX, timeInMcs0[i]);\n            nTotalInvocations += nInvocations[i];\n        }\n        \n        if (minTimeX > 0 && maxTimeX > 0) minTimeX = 0;\n        else if (minTimeX < 0 && maxTimeX < 0) maxTimeX = 0;\n        minTime = minTimeX;\n        maxTime = maxTimeX;\n    }\n    \n\n    @Override\n    public String getMethodNameAtRow(int row) {\n        ClientUtils.SourceCodeSelection sel = getSourceCodeSelectionAtRow(row);\n        return MethodNameFormatterFactory.getDefault().getFormatter()\n                                         .formatMethodName(sel.getClassName(), sel.getMethodName(),\n                                                           sel.getMethodSignature()).toFormatted();\n    }\n    \n    @Override\n    public ClientUtils.SourceCodeSelection getSourceCodeSelectionAtRow(int row) {\n        return sels[row];\n    }\n\n    @Override\n    public double getWholeGraphNetTime0() {\n        return wholeGraphNetTime0;\n    }\n\n    @Override\n    public double getWholeGraphNetTime1() {\n        return wholeGraphNetTime1;\n    }\n    \n    public long getMinTime() {\n        return minTime;\n    }\n    \n    public long getMaxTime() {\n        return maxTime;\n    }\n    \n    protected void swap(int a, int b) {\n        ClientUtils.SourceCodeSelection sel = sels[a];\n        sels[a] = sels[b];\n        sels[b] = sel;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/FlatProfileBuilder.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.CCTFlattener;\n\n//import org.graalvm.visualvm.lib.jfluid.results.cpu.cct.NodeMarker;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNodeProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.CCTResultsFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.TimeCollector;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.SimpleCPUCCTNode;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class FlatProfileBuilder implements FlatProfileProvider, CPUCCTProvider.Listener {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Logger LOGGER = Logger.getLogger(FlatProfileBuilder.class.getName());\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private CCTFlattener flattener;\n    private FlatProfileContainer lastFlatProfile = null;\n    private ProfilerClient client;\n    private SimpleCPUCCTNode appNode;\n\n    private TimeCollector collector = null;\n    private CCTResultsFilter filter = null;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setContext(ProfilerClient client, TimeCollector collector, CCTResultsFilter filter) {\n        if (this.client != null) {\n            this.collector = null;\n            this.filter = null;\n            this.client.registerFlatProfileProvider(null);\n        }\n\n        if (client != null) {\n            this.collector = collector;\n            this.filter = filter;\n            flattener = new CCTFlattener(client, filter);\n            client.registerFlatProfileProvider(this);\n        } else {\n            flattener = null;\n        }\n\n        this.client = client;\n        appNode = null;\n    }\n\n    public synchronized void cctEstablished(RuntimeCCTNode appRootNode, boolean empty) {\n        if (empty) return;\n        \n        if (appRootNode instanceof SimpleCPUCCTNode) {\n            appNode = (SimpleCPUCCTNode) appRootNode;\n        } else {\n            appNode = null;\n        }\n    }\n\n    public synchronized void cctReset() {\n        appNode = null;\n    }\n\n    public synchronized FlatProfileContainer createFlatProfile() {\n        if (appNode == null) {\n            return null;\n        }\n\n        client.getStatus().beginTrans(false);\n\n        try {\n            RuntimeCCTNodeProcessor.process(\n                appNode, \n                filter,\n                flattener,\n                collector\n            );\n            \n            lastFlatProfile = flattener.getFlatProfile();\n\n        } finally {\n            client.getStatus().endTrans();\n        }\n\n        return lastFlatProfile;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/FlatProfileContainer.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\n\n\n/**\n * Container for CPU profiling results in the flat profile form. Supports sorting this\n * data by each column and filtering it as many times as needed (only the external representation\n * is changed in that case; internally data remains the same). This class is an abstract superclass\n * of concrete subclasses in which the data is either backed by CPUCCTContainer or not.\n *\n * @author Misha Dmitriev\n * @author Jiri Sedlacek\n */\npublic abstract class FlatProfileContainer {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int SORT_BY_NAME = 1;\n    public static final int SORT_BY_TIME = 2;\n    public static final int SORT_BY_SECONDARY_TIME = 3;\n    public static final int SORT_BY_INV_NUMBER = 4;\n    public static final int SORT_BY_TOTAL_TIME = 5;\n    public static final int SORT_BY_SECONDARY_TOTAL_TIME = 6;\n\n    // This variable is used to remember the timestamp (absolute or thread-CPU) used to calculate percentage\n    // numbers, between invocations of \"Get results\", i.e. creations of new objects of this class.\n    protected static boolean staticUsePrimaryTime;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected int[] methodIds;\n    protected final char[] methodMarks;\n    protected int[] nInvocations;\n    protected float[] percent;\n    protected long[] timeInMcs0;\n    protected long[] timeInMcs1;\n    protected long[] totalTimeInMcs0;\n    protected long[] totalTimeInMcs1;\n    protected boolean collectingTwoTimeStamps;\n    protected long nTotalInvocations;\n    protected int nRows; // Number of methods currently displayed\n                       // nRows may be < totalMethods due to user setting up a filter for flat profile data\n    private int totalMethods; // Number of methods with non-zero number of invocations\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public FlatProfileContainer(long[] timeInMcs0, long[] timeInMcs1, long[] totalTimeInMcs0, long[] totalTimeInMcs1,\n            int[] nInvocations, char[] marks, int nMethods) {\n        this.timeInMcs0 = timeInMcs0;\n        this.timeInMcs1 = timeInMcs1;\n        this.totalTimeInMcs0 = totalTimeInMcs0;\n        this.totalTimeInMcs1 = totalTimeInMcs1;\n        this.nInvocations = nInvocations;\n        this.methodMarks = marks;\n        totalMethods = nMethods;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public boolean isCollectingTwoTimeStamps() {\n        return collectingTwoTimeStamps;\n    }\n\n    public int getMethodIdAtRow(int row) {\n        return methodIds[row];\n    }\n\n    public abstract String getMethodNameAtRow(int row);\n    \n    public abstract ClientUtils.SourceCodeSelection getSourceCodeSelectionAtRow(int row);\n\n    public int getNInvocationsAtRow(int row) {\n        return nInvocations[row];\n    }\n\n    public int getNRows() {\n        return nRows;\n    }\n\n    public long getNTotalInvocations() {\n        return nTotalInvocations;\n    }\n\n    public float getPercentAtRow(int row) {\n        return percent[row];\n    }\n\n    public long getTimeInMcs0AtRow(int row) {\n        return timeInMcs0[row];\n    }\n\n    public long getTimeInMcs1AtRow(int row) {\n        return timeInMcs1[row];\n    }\n\n    public long getTotalTimeInMcs0AtRow(int row) {\n        return totalTimeInMcs0[row];\n    }\n\n    public long getTotalTimeInMcs1AtRow(int row) {\n        return totalTimeInMcs1[row];\n    }\n\n    public abstract double getWholeGraphNetTime0();\n\n    public abstract double getWholeGraphNetTime1();\n\n    public void filterOriginalData(String[] filters, int type, double valueFilter) {\n//        //    percent = null;\n//        if (((type == CommonConstants.FILTER_NONE) || (filters == null) || filters[0].isEmpty()) && (valueFilter == 0.0d)) { // NOI18N\n//            nRows = totalMethods; // Effectively removes all filtering\n//\n//            return;\n//        }\n//\n//        // Now go through all methods and move those that don't pass filter to the end of the array\n//        nRows = totalMethods;\n//\n//        for (int i = 0; i < nRows; i++) {\n//            if (!passedFilters(getMethodNameAtRow(i), filters, type)/*|| ! passedValueFilter (getPercentAtRow(i), valueFilter) */ ) {\n//                int endIdx = --nRows;\n//\n//                if (i >= endIdx) {\n//                    continue;\n//                }\n//\n//                // Swap the current element and the one at (nRows - 1) index\n//                swap(i, endIdx);\n//                \n//                swap(methodIds,i,endIdx);\n//                swap(timeInMcs0,i,endIdx);\n//                swap(totalTimeInMcs0,i,endIdx);\n//\n//                if (collectingTwoTimeStamps) {\n//                    swap(timeInMcs1,i,endIdx);\n//                    swap(totalTimeInMcs1,i,endIdx);\n//                }\n//\n//                swap(nInvocations,i,endIdx);\n//                i--; // Because we've just put an unchecked element at the current position\n//            }\n//        }\n    }\n\n    public void filterOriginalData(InstrumentationFilter filter) {\n        if (filter == null || filter.isEmpty()) {\n            nRows = totalMethods; // Effectively removes all filtering\n\n            return;\n        }\n        // Now go through all methods and move those that don't pass filter to the end of the array\n        nRows = totalMethods;\n\n        for (int i = 0; i < nRows; i++) {\n            ClientUtils.SourceCodeSelection sc = getSourceCodeSelectionAtRow(i);\n            if (!filter.passes(sc.getClassName().replace('.', '/'))) {\n                int endIdx = --nRows;\n\n                if (i >= endIdx) {\n                    continue;\n                }\n\n                // Swap the current element and the one at (nRows - 1) index\n                swap(i, endIdx);\n\n                swap(methodIds,i,endIdx);\n                swap(timeInMcs0,i,endIdx);\n                swap(totalTimeInMcs0,i,endIdx);\n\n                if (collectingTwoTimeStamps) {\n                    swap(timeInMcs1,i,endIdx);\n                    swap(totalTimeInMcs1,i,endIdx);\n                }\n\n                swap(nInvocations,i,endIdx);\n                i--; // Because we've just put an unchecked element at the current position\n            }\n        }\n    }\n\n    public void sortBy(int sortCrit, boolean order) {\n//        switch (sortCrit) {\n//            case SORT_BY_NAME:\n//                sortDataByMethodName(order);\n//\n//                break;\n//            case SORT_BY_TIME:\n//                sortDataByTime(true, order);\n//\n//                break;\n//            case SORT_BY_SECONDARY_TIME:\n//                sortDataByTime(false, order);\n//\n//                break;\n//            case SORT_BY_TOTAL_TIME:\n//                sortDataByTotalTime(true, order);\n//\n//                break;\n//            case SORT_BY_SECONDARY_TOTAL_TIME:\n//                sortDataByTotalTime(false, order);\n//\n//                break;\n//            case SORT_BY_INV_NUMBER:\n//                sortDataByInvNumber(order);\n//\n//                break;\n//        }\n    }\n\n    protected void removeZeroInvocationEntries() {\n        nRows = 0;\n\n        // Note that at index 0 we always have a \"Thread\" quazi-method, that we shouldn't take into account\n        for (int i = 1; i < totalMethods; i++) {\n            if (nInvocations[i] > 0) {\n                nRows++;\n            }\n        }\n\n        long[] oldTime0 = timeInMcs0;\n        long[] oldTime1 = timeInMcs1;\n        long[] oldTotalTime0 = totalTimeInMcs0;\n        long[] oldTotalTime1 = totalTimeInMcs1;\n        int[] oldNInvocations = nInvocations;\n\n        timeInMcs0 = new long[nRows];\n        totalTimeInMcs0 = new long[nRows];\n\n        if (collectingTwoTimeStamps) {\n            timeInMcs1 = new long[nRows];\n            totalTimeInMcs1 = new long[nRows];\n        }\n\n        nInvocations = new int[nRows];\n        methodIds = new int[nRows];\n\n        int k = 0;\n\n        for (int i = 1; i < totalMethods; i++) {\n            if (oldNInvocations[i] > 0) {\n                long time = oldTime0[i];\n                if (time < 0) {\n                    time = 0; // Replace possible negative time entries with 0\n                }\n                timeInMcs0[k] = time;\n\n                time = oldTotalTime0[i];\n                if (time < 0) {\n                    time = 0;\n                }\n                totalTimeInMcs0[k] = time;\n\n                if (collectingTwoTimeStamps) {\n                    time = oldTime1[i];\n                    if (time < 0) {\n                        time = 0;\n                    }\n                    timeInMcs1[k] = time;\n\n                    time = oldTotalTime1[i];\n                    if (time < 0) {\n                        time = 0;\n                    }\n                    totalTimeInMcs1[k] = time;\n                }\n\n                nInvocations[k] = oldNInvocations[i];\n                nTotalInvocations += oldNInvocations[i];\n                methodIds[k] = i;\n                k++;\n            }\n        }\n\n        totalMethods = nRows;\n    }\n\n    private void calculatePercent(boolean usePrimaryTime) {\n        percent = new float[nRows];\n\n        double wholeNetTime = getWholeGraphNetTime0();\n        long[] tpm = timeInMcs0;\n\n        if (collectingTwoTimeStamps && (!usePrimaryTime)) {\n            wholeNetTime = getWholeGraphNetTime1();\n            tpm = timeInMcs1;\n        }\n\n        for (int i = 0; i < nRows; i++) {\n            percent[i] = (float) ((wholeNetTime > 0) ? ((double) tpm[i] / wholeNetTime * 100) : 0);\n        }\n\n        staticUsePrimaryTime = usePrimaryTime;\n    }\n\n    private boolean passedFilter(String value, String filter, int type) {\n//        // Case sensitive comparison:\n//        /*switch (type) {\n//           case CommonConstants.FILTER_STARTS_WITH:\n//             return value.startsWith(filter);\n//           case CommonConstants.FILTER_CONTAINS:\n//             return value.indexOf(filter) != -1;\n//           case CommonConstants.FILTER_ENDS_WITH:\n//             return value.endsWith(filter);\n//           case CommonConstants.FILTER_EQUALS:\n//             return value.equals(filter);\n//           case CommonConstants.FILTER_REGEXP:\n//             return value.matches(filter);\n//           }*/\n//\n//        // Case insensitive comparison (except regexp):\n//        switch (type) {\n////            case CommonConstants.FILTER_STARTS_WITH:\n////                return value.regionMatches(true, 0, filter, 0, filter.length()); // case insensitive startsWith, optimized\n//            case CommonConstants.FILTER_CONTAINS:\n//                return value.toLowerCase().contains(filter); // case insensitive indexOf, NOT OPTIMIZED\n//            case CommonConstants.FILTER_NOT_CONTAINS:\n//                return !value.toLowerCase().contains(filter);\n////            case CommonConstants.FILTER_ENDS_WITH:\n////                // case insensitive endsWith, optimized\n////                return value.regionMatches(true, value.length() - filter.length(), filter, 0, filter.length());\n////            case CommonConstants.FILTER_EQUALS:\n////                return value.equalsIgnoreCase(filter); // case insensitive equals\n//            case CommonConstants.FILTER_REGEXP:\n//                try {\n//                    return value.matches(filter); //  case sensitive!\n//                } catch (java.util.regex.PatternSyntaxException e) {\n//                    return false;\n//                }\n//        }\n\n        return false;\n    }\n\n//    private boolean passedFilters(String value, String[] filters, int type) {\n//        for (int i = 0; i < filters.length; i++) {\n//            if (passedFilter(value, filters[i], type)) {\n//                return true;\n//            }\n//        }\n//\n//        return false;\n//    }\n//\n//    private void sortDataByInvNumber(boolean sortOrder) {\n//        if ((percent == null) || (percent.length != nRows)) {\n//            calculatePercent(staticUsePrimaryTime);\n//        }\n//\n//        (new IntSorter(nInvocations, 0, nRows) {\n//                protected void swap(int a, int b) {\n//                    super.swap(a, b);\n//                    FlatProfileContainer.this.swap(a, b);\n//\n//                    FlatProfileContainer.swap(timeInMcs0,a,b);\n//                    FlatProfileContainer.swap(totalTimeInMcs0,a,b);\n//\n//                    if (collectingTwoTimeStamps) {\n//                        FlatProfileContainer.swap(timeInMcs1,a,b);\n//                        FlatProfileContainer.swap(totalTimeInMcs1,a,b);\n//                    }\n//\n//                    FlatProfileContainer.swap(methodIds,a,b);\n//\n//                    if (percent != null) {\n//                        FlatProfileContainer.swap(percent,a,b);\n//                    }\n//                }\n//            }).sort(sortOrder);\n//    }\n//\n//    private void sortDataByMethodName(boolean sortOrder) {\n//        String[] fullMethodNames = new String[nRows];\n//\n//        if ((percent == null) || (percent.length != nRows)) {\n//            calculatePercent(staticUsePrimaryTime);\n//        }\n//\n//        for (int i = 0; i < nRows; i++) {\n//            fullMethodNames[i] = getMethodNameAtRow(i);\n//        }\n//\n//        (new StringSorter(fullMethodNames, 0, nRows) {\n//                protected void swap(int a, int b) {\n//                    super.swap(a, b);\n//                    FlatProfileContainer.this.swap(a, b);\n//\n//                    FlatProfileContainer.swap(timeInMcs0,a,b);\n//                    FlatProfileContainer.swap(totalTimeInMcs0,a,b);\n//\n//                    if (collectingTwoTimeStamps) {\n//                        FlatProfileContainer.swap(timeInMcs1,a,b);\n//                        FlatProfileContainer.swap(totalTimeInMcs1,a,b);\n//                    }\n//\n//                    FlatProfileContainer.swap(methodIds,a,b);\n//                    FlatProfileContainer.swap(nInvocations,a,b);\n//\n//                    if (percent != null) {\n//                        FlatProfileContainer.swap(percent,a,b);\n//                    }\n//                }\n//            }).sort(sortOrder);\n//    }\n//\n//    private void sortDataByTime(boolean usePrimaryTime, boolean sortOrder) {\n//        long[] tpmA = null;\n//        long[] tpmB = null;\n//\n//        // Percentage is recalculated every time, since it depends on whether primary/secondary time is used\n//        if ((percent == null) || (usePrimaryTime != staticUsePrimaryTime) || (percent.length != nRows)) {\n//            calculatePercent(usePrimaryTime);\n//        }\n//\n//        if (collectingTwoTimeStamps) {\n//            if (usePrimaryTime) {\n//                tpmA = timeInMcs0;\n//                tpmB = timeInMcs1;\n//            } else {\n//                tpmA = timeInMcs1;\n//                tpmB = timeInMcs0;\n//            }\n//        } else {\n//            tpmA = timeInMcs0;\n//        }\n//\n//        final long[] tpmBF = tpmB;\n//\n//        (new LongSorter(tpmA, 0, nRows) {\n//                protected void swap(int a, int b) {\n//                    super.swap(a, b);\n//                    FlatProfileContainer.this.swap(a, b);\n//\n//                    FlatProfileContainer.swap(totalTimeInMcs0,a,b);\n//                    \n//                    if (collectingTwoTimeStamps) {\n//                        FlatProfileContainer.swap(tpmBF,a,b);\n//                        FlatProfileContainer.swap(totalTimeInMcs1,a,b);\n//                    }\n//\n//                    FlatProfileContainer.swap(methodIds,a,b);\n//                    FlatProfileContainer.swap(nInvocations,a,b);\n//\n//                    if (percent != null) {\n//                        FlatProfileContainer.swap(percent,a,b);\n//                    }\n//                }\n//            }).sort(sortOrder);\n//\n//        // Next, sort the methods with zero time by the number of invocations\n//        int len = nRows - 1;\n//\n//        while ((len >= 0) && (tpmA[len] == 0)) {\n//            len--;\n//        }\n//\n//        if (len < (nRows - 1)) {\n//            (new IntSorter(nInvocations, len + 1, nRows - len - 1) {\n//                    protected void swap(int a, int b) {\n//                        super.swap(a, b);\n//                        FlatProfileContainer.this.swap(a, b);\n//\n//                        FlatProfileContainer.swap(totalTimeInMcs0,a,b);\n//                        \n//                        if (collectingTwoTimeStamps) {\n//                            FlatProfileContainer.swap(tpmBF,a,b);\n//                            FlatProfileContainer.swap(totalTimeInMcs1,a,b);\n//                        }\n//\n//                        FlatProfileContainer.swap(methodIds,a,b);\n//                    }\n//                }).sort(sortOrder);\n//        }\n//    }\n//\n//    private void sortDataByTotalTime(boolean usePrimaryTime, boolean sortOrder) {\n//        long[] tpmA = null;\n//        long[] tpmB = null;\n//\n//        // Percentage is recalculated every time, since it depends on whether primary/secondary time is used\n//        if ((percent == null) || (usePrimaryTime != staticUsePrimaryTime) || (percent.length != nRows)) {\n//            calculatePercent(usePrimaryTime);\n//        }\n//\n//        if (collectingTwoTimeStamps) {\n//            if (usePrimaryTime) {\n//                tpmA = totalTimeInMcs0;\n//                tpmB = totalTimeInMcs1;\n//            } else {\n//                tpmA = totalTimeInMcs1;\n//                tpmB = totalTimeInMcs0;\n//            }\n//        } else {\n//            tpmA = totalTimeInMcs0;\n//        }\n//\n//        final long[] tpmBF = tpmB;\n//\n//        (new LongSorter(tpmA, 0, nRows) {\n//                protected void swap(int a, int b) {\n//                    super.swap(a, b);\n//                    FlatProfileContainer.this.swap(a, b);\n//\n//                    FlatProfileContainer.swap(timeInMcs0,a,b);\n//                    \n//                    if (collectingTwoTimeStamps) {\n//                        FlatProfileContainer.swap(tpmBF,a,b);\n//                        FlatProfileContainer.swap(timeInMcs1,a,b);\n//                    }\n//\n//                    FlatProfileContainer.swap(methodIds,a,b);\n//                    FlatProfileContainer.swap(nInvocations,a,b);\n//\n//                    if (percent != null) {\n//                        FlatProfileContainer.swap(percent,a,b);\n//                    }\n//                }\n//            }).sort(sortOrder);\n//\n//        // Next, sort the methods with zero time by the number of invocations\n//        int len = nRows - 1;\n//\n//        while ((len >= 0) && (tpmA[len] == 0)) {\n//            len--;\n//        }\n//\n//        if (len < (nRows - 1)) {\n//            (new IntSorter(nInvocations, len + 1, nRows - len - 1) {\n//                    protected void swap(int a, int b) {\n//                        super.swap(a, b);\n//                        FlatProfileContainer.this.swap(a, b);\n//\n//                        FlatProfileContainer.swap(timeInMcs0,a,b);\n//\n//                        if (collectingTwoTimeStamps) {\n//                            FlatProfileContainer.swap(tpmBF,a,b);\n//                            FlatProfileContainer.swap(timeInMcs1,a,b);\n//                        }\n//\n//                        FlatProfileContainer.swap(methodIds,a,b);\n//                    }\n//                }).sort(sortOrder);\n//        }\n//    }\n//    \n//    private static void swap(float[] arr, int i1, int i2) {\n//        float itmp = arr[i1];\n//        arr[i1] = arr[i2];\n//        arr[i2] = itmp;\n//    }\n//\n    private static void swap(long[] arr, int i1, int i2) {\n        long itmp = arr[i1];\n        arr[i1] = arr[i2];\n        arr[i2] = itmp;\n    }\n\n    private static void swap(int[] arr, int i1, int i2) {\n        int itmp = arr[i1];\n        arr[i1] = arr[i2];\n        arr[i2] = itmp;\n    }\n    \n    protected void swap(int a, int b) {}\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/FlatProfileContainerBacked.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatterFactory;\n\n\n/**\n * Container for CPU profiling results in the flat profile form. A concrete subclass of FlatProfileContainer,\n * where the data is backed by CPUCCTContainer.\n *\n * @author Misha Dmitriev\n */\npublic class FlatProfileContainerBacked extends FlatProfileContainer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected CPUCCTContainer cctContainer;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * The data passed to this constructor may contain some zero-invocation rows. That's because the size of passed arrays\n     * is equal to the number of currently instrumented methods, but in general not all of the methods may be invoked even\n     * once at an arbitrary moment.\n     *\n     * @param cctContainer The CPU results\n     * @param timeInMcs0   Array of Absolute timer values (self-time) for each method - always used\n     * @param timeInMcs1   Array of CPU timer values (self-time) for each method - optional, may be null\n     * @param totalTimeInMcs0   Array of Absolute timer (total time) values for each method - always used\n     * @param totalTimeInMcs1   Array of CPU timer (total time) values for each method - optional, may be null\n     * @param nInvocations Array of number of invocations for each method\n     * @param nMethods     Total number of profiled methods - length of the provided arrays\n     */\n    public FlatProfileContainerBacked(CPUCCTContainer cctContainer, long[] timeInMcs0, long[] timeInMcs1,\n            long[] totalTimeInMcs0, long[] totalTimeInMcs1, int[] nInvocations, int nMethods) {\n        super(timeInMcs0, timeInMcs1, totalTimeInMcs0, totalTimeInMcs1, nInvocations, null, nMethods);\n        this.cctContainer = cctContainer;\n\n        collectingTwoTimeStamps = cctContainer.isCollectingTwoTimeStamps();\n\n        // Now get rid of zero-invocation entries once and forever. Also set nTotalInvocations and set negative times\n        // (that may be possible due to time cleansing inaccuracies) to zero.\n        removeZeroInvocationEntries();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public CPUCCTContainer getCCTContainer() {\n        return cctContainer;\n    }\n\n    public String getMethodNameAtRow(int row) {\n        ClientUtils.SourceCodeSelection sel = getSourceCodeSelectionAtRow(row);\n        return MethodNameFormatterFactory.getDefault().getFormatter().formatMethodName(sel).toFormatted();\n        \n//        int methodId = methodIds[row];\n//        String[] methodClassNameAndSig = cctContainer.getMethodClassNameAndSig(methodId);\n//\n//        return MethodNameFormatterFactory.getDefault().getFormatter()\n//                                         .formatMethodName(methodClassNameAndSig[0], methodClassNameAndSig[1],\n//                                                           methodClassNameAndSig[2]).toFormatted();\n//\n//        //    return format.getFormattedClassAndMethod();\n    }\n    \n    public ClientUtils.SourceCodeSelection getSourceCodeSelectionAtRow(int row) {\n        int methodId = methodIds[row];\n        String[] sel = cctContainer.getMethodClassNameAndSig(methodId);\n        return new ClientUtils.SourceCodeSelection(sel[0], sel[1], sel[2]);\n    }\n\n    public double getWholeGraphNetTime0() {\n        return cctContainer.getWholeGraphNetTime0();\n    }\n\n    public double getWholeGraphNetTime1() {\n        return cctContainer.getWholeGraphNetTime1();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/FlatProfileContainerFree.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatterFactory;\n\n\n/**\n * Container for CPU profiling results in the flat profile form. A concrete subclass of FlatProfileContainer,\n * where the data is partially backed by ProfilingSessionStatus and partially is self-contained.\n *\n * @author Misha Dmitriev\n */\npublic class FlatProfileContainerFree extends FlatProfileContainer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected ProfilingSessionStatus status;\n    protected double wholeGraphNetTime0;\n    protected double wholeGraphNetTime1;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * The data passed to this constructor may contain some zero-invocation rows. That's because the size of passed arrays\n     * is equal to the number of currently instrumented methods, but in general not all of the methods may be invoked even\n     * once at an arbitrary moment.\n     *\n     * @param sessionStatus      Reference to ProfilingSessionStatus\n     * @param timeInMcs0         Array of Absolute timer values (self-time) for each method - always used\n     * @param timeInMcs1         Array of CPU timer values (self-time) for each method - optional, may be null\n     * @param totalTimeInMcs0    Array of Absolute timer (total time) values for each method - always used\n     * @param totalTimeInMcs1    Array of CPU timer (total time) values for each method - optional, may be null\n     * @param nInvocations       Array of number of invocations for each method\n     * @param wholeGraphNetTime0 Total absolute time\n     * @param wholeGraphNetTime1 Total CPU time - not used if CPU timer is not used\n     * @param nMethods           Total number of profiled methods - length of the provided arrays\n     */\n    public FlatProfileContainerFree(ProfilingSessionStatus sessionStatus, long[] timeInMcs0, long[] timeInMcs1, \n            long[] totalTimeInMcs0, long[] totalTimeInMcs1, int[] nInvocations, char[] marks, \n            double wholeGraphNetTime0, double wholeGraphNetTime1, int nMethods) {\n        super(timeInMcs0, timeInMcs1, totalTimeInMcs0, totalTimeInMcs1, nInvocations, marks, nMethods);\n        this.status = sessionStatus;\n        this.wholeGraphNetTime0 = wholeGraphNetTime0;\n        this.wholeGraphNetTime1 = wholeGraphNetTime1;\n\n        collectingTwoTimeStamps = sessionStatus.collectingTwoTimeStamps();\n\n        // Now get rid of zero-invocation entries once and forever. Also set nTotalInvocations and set negative times\n        // (that may be possible due to time cleansing inaccuracies) to zero.\n        removeZeroInvocationEntries();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getMethodNameAtRow(int row) {\n        ClientUtils.SourceCodeSelection sel = getSourceCodeSelectionAtRow(row);\n        return MethodNameFormatterFactory.getDefault().getFormatter()\n                                         .formatMethodName(sel.getClassName(), sel.getMethodName(),\n                                                           sel.getMethodSignature()).toFormatted();\n        \n//        int methodId = methodIds[row];\n//        MethodNameFormatter formatter = MethodNameFormatterFactory.getDefault().getFormatter(null);\n//\n//        status.beginTrans(false);\n//\n//        try {\n//            String[] classes = status.getInstrMethodClasses();\n//            String[] methods = status.getInstrMethodNames();\n//            String[] signatures = status.getInstrMethodSignatures();\n//\n//            return formatter.formatMethodName((classes != null && classes.length > methodId) ? classes[methodId] : null,\n//                                              (methods != null && methods.length > methodId) ? methods[methodId] : null,\n//                                              (signatures != null && signatures.length > methodId) ? signatures[methodId] : null).toFormatted();\n//        } finally {\n//            status.endTrans();\n//        }\n    }\n    \n    public ClientUtils.SourceCodeSelection getSourceCodeSelectionAtRow(int row) {\n        int methodId = methodIds[row];\n\n        status.beginTrans(false);\n\n        try {\n            String[] classes = status.getInstrMethodClasses();\n            String[] methods = status.getInstrMethodNames();\n            String[] signatures = status.getInstrMethodSignatures();\n            \n            String _class = classes != null && classes.length > methodId ? classes[methodId] : null;\n            String _method = methods != null && methods.length > methodId ? methods[methodId] : null;\n            String _signature = signatures != null && signatures.length > methodId ? signatures[methodId] : null;\n\n            return new ClientUtils.SourceCodeSelection(_class, _method, _signature);\n        } finally {\n            status.endTrans();\n        }\n    }\n\n    public ProfilingSessionStatus getStatus() {\n        return status;\n    }\n\n    public double getWholeGraphNetTime0() {\n        return wholeGraphNetTime0;\n    }\n\n    public double getWholeGraphNetTime1() {\n        return wholeGraphNetTime1;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/FlatProfileProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface FlatProfileProvider {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public FlatProfileContainer createFlatProfile();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/InstrTimingData.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n\n/**\n * This class is simply a container for instrumentation timing data that needs to be passed around between\n * a number of different objects when processing CPU profiling results.\n *\n * @author Misha Dmitriev\n */\npublic class InstrTimingData implements Cloneable {\n    final public static InstrTimingData DEFAULT = new InstrTimingData();\n\n    // Of these variables, the xxx0 ones are used when either only absolute or only thread CPU timer is used.\n    // xxx0 and xxx1 together are used only when both timers are used.\n    double methodEntryExitCallTime0 = 0;\n    double methodEntryExitCallTime1 = 0;\n    double methodEntryExitInnerTime0 = 0;\n    double methodEntryExitInnerTime1 = 0;\n    double methodEntryExitOuterTime0 = 0;\n    double methodEntryExitOuterTime1 = 0;\n    long timerCountsInSecond0 = 1000; // default is a millisecond timer granularity; will get replaced from the calibration data\n    long timerCountsInSecond1 = 1000; // default is a millisecond timer granularity; will get replaced from the calibration data\n\n    @Override\n    public Object clone() {\n        try {\n            return super.clone();\n        } catch (CloneNotSupportedException e) {\n            Logger.getLogger(InstrTimingData.class.getName()).log(Level.SEVERE, \"Unable to clone \" + InstrTimingData.class.getName(), e);\n            return null;\n        }\n    }\n\n    public InstrTimingData() {}\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n\n\n    public String toString() {\n        String s1 = \"callTime0 = \" + methodEntryExitCallTime0 + \", innerTime0 = \" + methodEntryExitInnerTime0\n                    + \", outerTime0 = \" // NOI18N\n                    + methodEntryExitOuterTime0 + \"\\n\" // NOI18N\n                    + \"callTime1 = \" + methodEntryExitCallTime1 + \", innerTime1 = \" + methodEntryExitInnerTime1\n                    + \", outerTime1 = \" // NOI18N\n                    + methodEntryExitOuterTime1 + \"\\n\" // NOI18N\n                    + \"countsInSec0 = \" + timerCountsInSecond0 + \", countsInSec1 = \" + timerCountsInSecond1 + \"\\n\"; // NOI18N\n\n        return s1;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/MethodIdMap.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.util.ResourceBundle;\nimport java.util.concurrent.ConcurrentHashMap;\n\n\n/**\n * This class provides a map between method ids and class (package) ids, which is needed when\n * constructing an aggregated class- (package-) level view of CPU profiling results out of the\n * initial method-level view\n *\n * @author Misha Dmitriev\n */\npublic class MethodIdMap {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String ANONYMOUS_PACKAGE_STRING = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.cpu.Bundle\").getString(\"MethodIdMap_AnonymousPackageString\"); // NOI18N\n                                                                                                                     // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ArrayList classOrPackageNames;\n    private Map classIdCache; // Maps a class (package) name to its integer id\n    private int[] classIds;\n    private int curClassId;\n    private int newView;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @param methodLevelInstrClassNames names of classes for instrumented methods. The total number of entries is\n     *                                   equal to the number of instrumented methods, but some entries may be the same of\n     *                                   course.\n     * @param nInstrMethods              number of entries in this array that are actually used\n     * @param newView                    the new view for which we are creating ids - class-level or package-level\n     */\n    public MethodIdMap(String[] methodLevelInstrClassNames, int nInstrMethods, int newView) {\n        this.newView = newView;\n        classIds = new int[nInstrMethods];\n        classIdCache = new ConcurrentHashMap();\n        classOrPackageNames = new ArrayList();\n        curClassId = 0;\n        classOrPackageNames.add(methodLevelInstrClassNames[0]);\n\n        classIds[0] = 0; // The hidden \"Thread\" quazi-method transforms into \"Thread\" quazi-class\n\n        for (int i = 1; i < nInstrMethods; i++) {\n            classIds[i] = getClassId(methodLevelInstrClassNames[i]);\n        }\n\n        classIdCache = null; // Not needed anymore - free memory\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getClassOrPackageIdForMethodId(int methodId) {\n        return classIds[methodId];\n    }\n\n    public String[] getInstrClassesOrPackages() {\n        String[] ret = (String[]) classOrPackageNames.toArray(new String[0]);\n        classOrPackageNames = null;\n\n        return ret;\n    }\n\n    public int getNInstrClassesOrPackages() {\n        return curClassId + 1;\n    }\n\n    private int getClassId(String className) {\n        String name = (newView == CPUResultsSnapshot.CLASS_LEVEL_VIEW) ? className : getPackageName(className);\n        Integer classId = (Integer) classIdCache.get(name);\n\n        if (classId == null) {\n            curClassId++;\n            classOrPackageNames.add(name);\n            classIdCache.put(name, Integer.valueOf(curClassId));\n\n            return curClassId;\n        } else {\n            return classId.intValue();\n        }\n    }\n\n    private String getPackageName(String className) {\n        int lastDivPos = className.lastIndexOf('.'); // NOI18N\n\n        if (lastDivPos == -1) {\n            return ANONYMOUS_PACKAGE_STRING;\n        } else {\n            return className.substring(0, lastDivPos).intern();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/MethodInfoMapper.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport java.util.logging.Logger;\n\npublic abstract class MethodInfoMapper {\n    final static protected Logger LOGGER = Logger.getLogger(MethodInfoMapper.class.getName());\n\n    public static final MethodInfoMapper DEFAULT = new MethodInfoMapper() {\n\n        @Override\n        public String getInstrMethodClass(int methodId) {\n            LOGGER.warning(\"Usage of the default MethodInfoMapper implementation is discouraged\");\n            return \"<UNKNOWN>\";\n        }\n\n        @Override\n        public String getInstrMethodName(int methodId) {\n            LOGGER.warning(\"Usage of the default MethodInfoMapper implementation is discouraged\");\n            return \"<UNKNOWN>\";\n        }\n\n        @Override\n        public String getInstrMethodSignature(int methodId) {\n            LOGGER.warning(\"Usage of the default MethodInfoMapper implementation is discouraged\");\n            return \"<UNKNOWN>\";\n        }\n\n        @Override\n        public int getMaxMethodId() {\n            LOGGER.warning(\"Usage of the default MethodInfoMapper implementation is discouraged\");\n            return 0;\n        }\n\n        @Override\n        public int getMinMethodId() {\n            LOGGER.warning(\"Usage of the default MethodInfoMapper implementation is discouraged\");\n            return 0;\n        }\n    };\n\n    public abstract String getInstrMethodClass(int methodId);\n\n    public abstract String getInstrMethodName(int methodId);\n\n    public abstract String getInstrMethodSignature(int methodId);\n\n    public abstract int getMinMethodId();\n\n    public abstract int getMaxMethodId();\n\n    public void lock(boolean mutable) {\n        // default no-op\n    }\n\n    public void unlock() {\n        // default no-op\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/PrestimeCPUCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatterFactory;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.ResourceBundle;\nimport javax.swing.tree.TreeNode;\nimport org.graalvm.visualvm.lib.jfluid.results.FilterSortSupport;\n\n\n/**\n * Base Presentation-Time CPU Profiling Calling Context Tree (CCT) Node class.\n * Subclasses provide an implementation that is backed by the flattened tree data array in CPUCCTContainer\n * (PrestimeCPUCCTNodeBacked) and the one that contains all the data in the node itself (PrestimeCPUCCTNodeFree).\n *\n * @author Misha Dmitriev\n */\npublic abstract class PrestimeCPUCCTNode extends CCTNode implements Cloneable {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String SELF_TIME_STRING;\n\n    static {\n        ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.cpu.Bundle\"); // NOI18N\n        SELF_TIME_STRING = messages.getString(\"PrestimeCPUCCTNode_SelfTimeString\"); // NOI18N\n    }\n\n    protected static final char MASK_SELF_TIME_NODE = 0x1;\n    protected static final char MASK_CONTEXT_CALLS_NODE = 0x2;\n    protected static final char MASK_THREAD_NODE = 0x4;\n//    protected static final char MASK_FILTERED_NODE = 0x8;\n    public static final int SORT_BY_NAME = 1;\n    public static final int SORT_BY_TIME_0 = 2;\n    public static final int SORT_BY_TIME_1 = 3;\n    public static final int SORT_BY_INVOCATIONS = 4;\n\n\n    public static final PrestimeCPUCCTNode EMPTY = new PrestimeCPUCCTNode() {\n        PrestimeCPUCCTNode createCopy() { return null; }\n        \n        public PrestimeCPUCCTNode getChild(int index) { return null; }\n        public PrestimeCPUCCTNode[] getChildren() { return new PrestimeCPUCCTNode[0]; }\n        public int getIndexOfChild(Object child) { return -1; }\n        public int getNChildren() { return 0; }\n        public String getNodeName() { return \"\"; } // NOI18N\n        public long getTime() { return 0; }\n        public double getTimeInPerCent() { return 0; }\n        public long getWaits() { return 0; }\n\n        public int getMethodId() { return -1; }\n        public int getNCalls() { return -1; }\n        public long getSleepTime0() { return -1; }\n        public int getThreadId() { return -1; }\n        public long getTotalTime0() { return -1; }\n        public float getTotalTime0InPerCent() { return -1; }\n        public long getTotalTime1() { return -1; }\n        public float getTotalTime1InPerCent() { return -1; }\n        public long getWaitTime0() { return -1; }\n        public void sortChildren(int sortBy, boolean sortOrder) {}\n        public TreeNode getChildAt(int childIndex) { return null; }\n        public int getChildCount() { return 0; }\n        public CCTNode getParent() { return null; }\n        public int getIndex(TreeNode node) { return -1; }\n        public boolean getAllowsChildren() { return false; }\n        public boolean isLeaf() { return true; }\n        public Enumeration children() { return null; }\n    };\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected CPUCCTContainer container;\n    protected PrestimeCPUCCTNode parent;\n    protected PrestimeCPUCCTNode[] children;\n    protected char flags; // Non-zero for several special kinds of nodes, per MASK_* bit constants above\n    \n    private String nodeName;\n    \n    protected int methodId;\n    protected int nCalls;\n    protected long sleepTime0;\n\n    /** The same class used for both standard and \"extended\" nodes (collecting one or two timestamps) */\n    protected long totalTime0;\n    protected long totalTime1;\n\n    /** The same class used for both standard and \"extended\" nodes (collecting one or two timestamps) */\n    protected long waitTime0;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    protected PrestimeCPUCCTNode() {\n    }\n\n    /**\n     * Constructor for creating normal nodes representing methods\n     */\n    protected PrestimeCPUCCTNode(CPUCCTContainer container, PrestimeCPUCCTNode parent, int methodId) {\n        this.container = container;\n        this.parent = parent;\n        this.methodId = methodId;\n    }\n    \n    // --- Cloning support ---\n    \n    PrestimeCPUCCTNode createCopy() {\n        throw new UnsupportedOperationException(\"Cannot be called directly on \" + getClass().getName()); // NOI18N\n    };\n    \n    void setupCopy(PrestimeCPUCCTNode node) {\n        node.container = container;\n        node.parent = parent;\n        node.children = children;\n        \n        node.flags = flags;\n\n        node.nodeName = nodeName;\n        node.methodId = methodId;\n        \n        node.nCalls = nCalls;\n        \n        node.sleepTime0 = sleepTime0;\n        node.totalTime0 = totalTime0;\n        node.totalTime1 = totalTime1;\n        node.waitTime0 = waitTime0;\n    }\n    \n    // --- Filtering support ---\n    \n    protected void setupFilteredNode(PrestimeCPUCCTNode filtered) {\n        setupCopy(filtered);\n        \n        filtered.setFilteredNode();\n        \n        filtered.nodeName = null;\n        filtered.methodId = -1;\n\n        Collection<PrestimeCPUCCTNode> _childrenL = resolveChildren(this);\n        filtered.children = _childrenL.toArray(new PrestimeCPUCCTNode[0]);\n    }\n    \n    public void merge(CCTNode node) {\n        if (node instanceof PrestimeCPUCCTNode) {\n            PrestimeCPUCCTNode _node = (PrestimeCPUCCTNode)node;\n            \n            addNCalls(_node.getNCalls());\n            addSleepTime0(_node.getSleepTime0());\n            addTotalTime0(_node.getTotalTime0());\n            addTotalTime1(_node.getTotalTime1());\n            addWaitTime0(_node.getWaitTime0());\n\n            List<PrestimeCPUCCTNode> ch = new ArrayList();\n            \n            // Include current children\n            PrestimeCPUCCTNode[] _children = (PrestimeCPUCCTNode[])getChildren();\n            if (_children != null) for (PrestimeCPUCCTNode child : _children)\n                    ch.add(child.createCopy());\n            \n            // Add or merge new children\n            PrestimeCPUCCTNode[] __children = (PrestimeCPUCCTNode[])node.getChildren();\n            if (__children != null) for (PrestimeCPUCCTNode child : __children) {\n                if (child != null) {\n                    int idx = ch.indexOf(child);\n                    if (idx == -1) ch.add(child.createCopy());\n                    else ch.get(idx).merge(child);\n                }\n            }\n            \n            children = ch.toArray(new PrestimeCPUCCTNode[0]);\n        }\n    }\n\n    protected static Collection<PrestimeCPUCCTNode> resolveChildren(PrestimeCPUCCTNode node) {\n        List<PrestimeCPUCCTNode> chldrn = new ArrayList();\n        PrestimeCPUCCTNode[] chld = (PrestimeCPUCCTNode[])node.getChildren();\n        if (chld != null) for (PrestimeCPUCCTNode chl : chld)\n            if (!chl.isSelfTimeNode()) chldrn.add(chl);\n        return chldrn;\n    }\n    \n    // ---\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public CCTNode getChild(int index) {\n        return children[index];\n    }\n\n    public CCTNode[] getChildren() {\n        return children;\n    }\n    \n    public int getNChildren() {\n        return (children != null) ? children.length : 0;\n    }\n\n    public CPUCCTContainer getContainer() {\n        return container;\n    }\n    \n    \n    public int getMethodId() {\n        return methodId;\n    }\n    \n    public int getNCalls() {\n        return nCalls;\n    }\n    \n    public long getSleepTime0() {\n        return sleepTime0;\n\n        // TODO: [wait] self time node?\n    }\n    \n    public int getThreadId() {\n        return container.getThreadId();\n    }\n    \n    public long getTotalTime0() {\n        return totalTime0;\n    }\n    \n    public long getTotalTime1() {\n        return totalTime1;\n    }\n    \n    public long getWaitTime0() {\n        return waitTime0; // TODO [wait]\n    }\n    \n    \n    public void addNCalls(int addCalls) {\n        nCalls += addCalls;\n    }\n\n    public void addSleepTime0(long addTime) {\n        sleepTime0 += addTime;\n    }\n\n    public void addTotalTime0(long addTime) {\n        totalTime0 += addTime;\n    }\n\n    public void addTotalTime1(long addTime) {\n        totalTime1 += addTime;\n    }\n\n    public void addWaitTime0(long addTime) {\n        waitTime0 += addTime;\n    }\n    \n\n    public void setContextCallsNode() {\n        flags = MASK_CONTEXT_CALLS_NODE;\n    }\n\n    public boolean isContextCallsNode() {\n        return (flags & MASK_CONTEXT_CALLS_NODE) != 0;\n    }\n\n    public String[] getMethodClassNameAndSig() {\n        if (!isThreadNode()) {\n            return container.getMethodClassNameAndSig(getMethodId());\n        } else {\n            return new String[] { container.getThreadName(), \"\", \"\" }; // NOI18N\n        }\n    }\n    \n    protected void resetChildren() {\n        if (children != null)\n            for (PrestimeCPUCCTNode n : children)\n                n.resetChildren();\n    }\n\n//    public abstract int getMethodId();\n//\n//    public abstract int getNCalls();\n//\n//    public abstract int getNChildren();\n    \n    public String getNodeName() {\n        if (nodeName == null) nodeName = computeNodeName();\n        return nodeName;\n    }\n\n    protected String computeNodeName() {\n        if (isFiltered()) {\n            return FilterSortSupport.FILTERED_OUT_LBL;\n        } else if (isSelfTimeNode()) {\n            return SELF_TIME_STRING;\n        } else if (isThreadNode()) {\n            return container.getThreadName();\n        }\n\n        int methodId = getMethodId();\n        String[] methodClassNameAndSig = container.getMethodClassNameAndSig(methodId);\n\n        //    PlainFormattableMethodName format = new PlainFormattableMethodName(\n        //        methodClassNameAndSig[0], methodClassNameAndSig[1], methodClassNameAndSig[2]\n        //    );\n        //    String res = format.getFormattedClassAndMethod();\n        return MethodNameFormatterFactory.getDefault().getFormatter().formatMethodName(\n                                          methodClassNameAndSig[0], methodClassNameAndSig[1],\n                                          methodClassNameAndSig[2]).toFormatted();\n\n//        if (isContextCallsNode()) {\n//            return MessageFormat.format(FROM_MSG, new Object[] { res });\n//        } else {\n//            return res;\n//        }\n    }\n    \n    public boolean equals(Object o) {\n        if (!(o instanceof PrestimeCPUCCTNode)) return false;\n        PrestimeCPUCCTNode oo = (PrestimeCPUCCTNode)o;\n        \n        // Handle root\n        if (parent == null) return oo.parent == null;\n        \n        // Handle toplevel thread nodes\n        if (isThreadNode()) return container.getThreadId() == oo.container.getThreadId();\n        \n        // Handle self time nodes\n        if (isSelfTimeNode()) return oo.isSelfTimeNode();\n        \n        // Handle filtered-out containers\n        if (isFiltered()) return oo.isFiltered();\n        \n        // Handle \"when called from\" containers\n        if (isContextCallsNode()) return getMethodId() == oo.getMethodId();\n        \n        // Handle regular method nodes\n        return getMethodId() == oo.getMethodId();\n        \n//        // Expected fallback for packages/classes view (no methodIDs)\n//        return getNodeName().equals(((PrestimeCPUCCTNode)o).getNodeName());\n    }\n    \n    public int hashCode() {        \n        // Handle root\n        if (parent == null) return 1;\n        \n        // Handle toplevel thread nodes\n        if (isThreadNode()) return container.getThreadId();\n        \n        // Handle self time nodes\n        if (isSelfTimeNode()) return -1;\n        \n        // Handle filtered-out containers\n        if (isFiltered()) return -10;\n        \n        // Handle \"when called from\" containers\n        if (isContextCallsNode()) return Integer.MIN_VALUE + getMethodId();\n        \n        // Handle regular method nodes\n        return getMethodId();\n        \n//        // Expected fallback for packages/classes view (no methodIDs)\n//        return getNodeName().hashCode();\n    }\n\n    public CCTNode getParent() {\n        return parent;\n    }\n\n//    public abstract long getSleepTime0();\n//\n//    public abstract int getThreadId();\n\n    public void setSelfTimeNode() {\n        flags |= MASK_SELF_TIME_NODE;\n    }\n\n    public boolean isSelfTimeNode() {\n        return (flags & MASK_SELF_TIME_NODE) != 0;\n    }\n\n    public void setThreadNode() {\n        flags |= MASK_THREAD_NODE;\n    }\n\n    public boolean isThreadNode() {\n        return (flags & MASK_THREAD_NODE) != 0;\n    }\n    \n//    public void setFilteredNode() {\n//        flags |= MASK_FILTERED_NODE;\n//    }\n//    \n//    public void resetFilteredNode() {\n//        flags &= ~MASK_FILTERED_NODE;\n//    }\n//\n//    public boolean isFilteredNode() {\n//        return (flags & MASK_FILTERED_NODE) != 0;\n//    }\n\n//    public abstract long getTotalTime0();\n\n    public abstract float getTotalTime0InPerCent();\n\n//    public abstract long getTotalTime1();\n\n    public abstract float getTotalTime1InPerCent();\n\n//    public abstract long getWaitTime0();\n\n    public int getIndexOfChild(Object child) {\n//        if (children == null) JOptionPane.showMessageDialog(null, \"Node: \" + this + \"\\nindex of child: \" + child);\\\n        if (getNChildren() == 0) return -1;\n        for (int i = 0; i < children.length; i++) {\n            if ((PrestimeCPUCCTNode) child == children[i]) {\n                return i;\n            }\n        }\n\n        return -1;\n    }\n\n    /**\n     * This is not equal to doSortChildren below, because the real implementation of sortChildren may need to do some\n     * more things, such as generating the children, or deciding to return immediately.\n     */\n    public void sortChildren(int sortBy, boolean sortOrder) {};\n    \n    public String toString() {\n        return getNodeName();\n    }\n\n//    protected void doSortChildren(int sortBy, boolean sortOrder) {\n//        int len = children.length;\n//\n//        for (int i = 0; i < len; i++) {\n//            children[i].sortChildren(sortBy, sortOrder);\n//        }\n//\n//        if (len > 1) {\n//            switch (sortBy) {\n//                case SORT_BY_NAME:\n//                    sortChildrenByName(sortOrder);\n//\n//                    break;\n//                case SORT_BY_TIME_0:\n//                    sortChildrenByTime0(sortOrder);\n//\n//                    break;\n//                case SORT_BY_TIME_1:\n//                    sortChildrenByTime1(sortOrder);\n//\n//                    break;\n//                case SORT_BY_INVOCATIONS:\n//                    sortChildrenByInvocations(sortOrder);\n//\n//                    break;\n//            }\n//        }\n//    }\n//\n//    protected void sortChildrenByInvocations(boolean sortOrder) {\n//        int len = children.length;\n//        int[] values = new int[len];\n//\n//        for (int i = 0; i < len; i++) {\n//            values[i] = children[i].getNCalls();\n//        }\n//\n//        sortInts(values, sortOrder);\n//    }\n//\n//    protected void sortChildrenByName(boolean sortOrder) {\n//        int len = children.length;\n//        String[] values = new String[len];\n//\n//        for (int i = 0; i < len; i++) {\n//            values[i] = children[i].getNodeName();\n//        }\n//\n//        sortStrings(values, sortOrder);\n//    }\n//\n//    protected void sortChildrenByTime0(boolean sortOrder) {\n//        int len = children.length;\n//        long[] values = new long[len];\n//\n//        for (int i = 0; i < len; i++) {\n//            values[i] = children[i].getTotalTime0();\n//        }\n//\n//        sortLongs(values, sortOrder);\n//    }\n//\n//    protected void sortChildrenByTime1(boolean sortOrder) {\n//        int len = children.length;\n//        long[] values = new long[len];\n//\n//        for (int i = 0; i < len; i++) {\n//            values[i] = children[i].getTotalTime1();\n//        }\n//\n//        sortLongs(values, sortOrder);\n//    }\n//\n//    protected void sortInts(int[] values, boolean sortOrder) {\n//        int len = values.length;\n//\n//        // Just the insertion sort - we will never get really large arrays here\n//        for (int i = 0; i < len; i++) {\n//            for (int j = i; (j > 0) && ((sortOrder == false) ? (values[j - 1] < values[j]) : (values[j - 1] > values[j])); j--) {\n//                int tmp = values[j];\n//                values[j] = values[j - 1];\n//                values[j - 1] = tmp;\n//\n//                PrestimeCPUCCTNode tmpCh = children[j];\n//                children[j] = children[j - 1];\n//                children[j - 1] = tmpCh;\n//            }\n//        }\n//    }\n//\n//    protected void sortLongs(long[] values, boolean sortOrder) {\n//        int len = values.length;\n//\n//        // Just the insertion sort - we will never get really large arrays here\n//        for (int i = 0; i < len; i++) {\n//            for (int j = i; (j > 0) && ((sortOrder == false) ? (values[j - 1] < values[j]) : (values[j - 1] > values[j])); j--) {\n//                long tmp = values[j];\n//                values[j] = values[j - 1];\n//                values[j - 1] = tmp;\n//\n//                PrestimeCPUCCTNode tmpCh = children[j];\n//                children[j] = children[j - 1];\n//                children[j - 1] = tmpCh;\n//            }\n//        }\n//    }\n//\n//    protected void sortStrings(String[] values, boolean sortOrder) {\n//        int len = values.length;\n//\n//        // Just the insertion sort - we will never get really large arrays here\n//        for (int i = 0; i < len; i++) {\n//            for (int j = i;\n//                     (j > 0)\n//                     && ((sortOrder == false) ? (values[j - 1].compareTo(values[j]) < 0) : (values[j - 1].compareTo(values[j]) > 0));\n//                     j--) {\n//                String tmp = values[j];\n//                values[j] = values[j - 1];\n//                values[j - 1] = tmp;\n//\n//                PrestimeCPUCCTNode tmpCh = children[j];\n//                children[j] = children[j - 1];\n//                children[j - 1] = tmpCh;\n//            }\n//        }\n//    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/PrestimeCPUCCTNodeBacked.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport java.text.NumberFormat;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n\n/**\n * Presentation-Time CPU Profiling Calling Context Tree (CCT) Node backed by the flattened tree data array in\n * CPUCCTContainer. These nodes are constructed on demand, i.e. only when the user opens some node in the CCT on screen.\n * They contain minimum amount of data in the node instance itself. As a result, a tree constructed of such nodes has\n * a very small overhead on top of the flattened data that already exists (and has relatively low space consumption and\n * construction time). The drawback is that it's difficult to add elements to a tree represented in the flattened form.\n *\n * @author Misha Dmitriev\n */\npublic class PrestimeCPUCCTNodeBacked extends PrestimeCPUCCTNode {\n\n    private static NumberFormat percentFormat=null;\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected int selfCompactDataOfs;\n    protected Set<Integer> compactDataOfs;\n    protected int nChildren;\n\n//    protected int methodID;\n//\n//    protected int nCalls;\n//    protected long sleepTime0;\n//    protected long totalTime0;\n//    protected long totalTime1;\n//    protected long waitTime0;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Constructor for creating normal nodes representing methods\n     */\n    public PrestimeCPUCCTNodeBacked(CPUCCTContainer container, PrestimeCPUCCTNode parent, int compactDataOfs) {\n        super(container, parent, container.getMethodIdForNodeOfs(compactDataOfs));\n        selfCompactDataOfs = compactDataOfs;\n        this.compactDataOfs = new HashSet();\n        this.compactDataOfs.add(selfCompactDataOfs);\n        this.container = container;\n        \n        nChildren = container.getNChildrenForNodeOfs(compactDataOfs);\n        \n//        methodId = container.getMethodIdForNodeOfs(compactDataOfs);\n        nCalls = container.getNCallsForNodeOfs(compactDataOfs);\n        sleepTime0 = container.getSleepTime0ForNodeOfs(compactDataOfs);\n        totalTime0 = container.getTotalTime0ForNodeOfs(compactDataOfs);\n        if (container.collectingTwoTimeStamps)\n            totalTime1 = container.getTotalTime1ForNodeOfs(compactDataOfs);\n        waitTime0 = container.getWaitTime0ForNodeOfs(compactDataOfs);\n    }\n\n    /**\n     * Constructor for creating a node that represent a whole thread\n     */\n    protected PrestimeCPUCCTNodeBacked(CPUCCTContainer container, PrestimeCPUCCTNode[] children) {\n        super(container, null, -1);\n        setThreadNode();\n        this.children = children;\n        nChildren = children == null ? 0 : children.length;\n        for (int i = 0; i < nChildren; i++)\n            if (children[i] != null) children[i].parent = this;\n    }\n    \n    PrestimeCPUCCTNodeBacked() {}\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    PrestimeCPUCCTNode createCopy() {\n        PrestimeCPUCCTNodeBacked copy = new PrestimeCPUCCTNodeBacked();\n        setupCopy(copy);\n        return copy;\n    }\n    \n    void setupCopy(PrestimeCPUCCTNodeBacked node) {\n        super.setupCopy(node);\n        node.selfCompactDataOfs = selfCompactDataOfs;\n        node.compactDataOfs = compactDataOfs;\n//        node.compactDataOfs = new HashSet();\n//        node.compactDataOfs.add(node.selfCompactDataOfs);\n        node.nChildren = nChildren;\n    }\n    \n    \n    public CCTNode createFilteredNode() {\n        PrestimeCPUCCTNodeBacked filtered = new PrestimeCPUCCTNodeBacked();\n        setupFilteredNode(filtered);\n        return filtered;\n    }\n    \n    protected void setupFilteredNode(PrestimeCPUCCTNodeBacked filtered) {\n        super.setupFilteredNode(filtered);\n        filtered.nChildren = filtered.children.length;\n    }\n    \n    public void merge(CCTNode node) {\n        super.merge(node);\n        nChildren = children.length;\n    }\n    \n    public PrestimeCPUCCTNodeBacked createRootCopy() {\n        PrestimeCPUCCTNodeBacked copy = new PrestimeCPUCCTNodeBacked(container, parent, selfCompactDataOfs);\n        \n        copy.parent = null;\n        \n        copy.compactDataOfs.clear();\n        copy.compactDataOfs.addAll(compactDataOfs);\n        \n        copy.children = null;\n        copy.nChildren = nChildren;\n        \n        copy.methodId = methodId;\n        copy.nCalls = nCalls;\n        copy.sleepTime0 = sleepTime0;\n        copy.totalTime0 = totalTime0;\n        copy.totalTime1 = totalTime1;\n        copy.waitTime0 = waitTime0;\n        \n        return copy;\n    }\n\n    public CCTNode getChild(int index) {\n        getChildren();\n\n        if (index < children.length) {\n            return children[index];\n        } else {\n            return null;\n        }\n    }\n    \n    public CCTNode[] getChildren() {\n        if (nChildren == 0) {\n            return null;\n        } else if (children != null) {\n            return children;\n        }\n        \n        List<PrestimeCPUCCTNodeBacked> childrenL = new ArrayList();\n//        PrestimeCPUCCTNodeBacked filtered = null;\n        \n//        FilterSortSupport.Configuration config = container.getCPUResSnapshot().getFilterSortInfo(this);\n        \n        for (int ofs : compactDataOfs) {\n            int chcount = container.getNChildrenForNodeOfs(ofs);\n            for (int i = 0; i < chcount; i++) {\n                PrestimeCPUCCTNodeBacked ch = new PrestimeCPUCCTNodeBacked(container,\n                        this, container.getChildOfsForNodeOfs(ofs, i));\n//                if (FilterSortSupport.passesFilter(config, ch.getNodeName())) {\n                    int chindex = childrenL.indexOf(ch);\n                    if (chindex != -1) childrenL.get(chindex).merge(ch);\n                    else childrenL.add(ch);\n//                } else {\n//                    if (filtered == null) {\n//                        filtered = ch;\n//                        ch.setFilteredNode();\n//                        childrenL.add(filtered);\n//                    } else {\n//                        filtered.merge(ch);\n//                    }\n//                }\n            }\n        }\n\n        if (hasSelfTimeChild()) {\n            PrestimeCPUCCTNodeBacked selfTimeChild =\n                    new PrestimeCPUCCTNodeBacked(container, parent, selfCompactDataOfs);\n            selfTimeChild.setSelfTimeNode();\n            childrenL.add(selfTimeChild);\n        }\n        \n//        if (isFilteredNode() && filtered != null && childrenL.size() == 1) {\n//            // \"naive\" approach, collapse simple chain of filtered out nodes\n//            children = (PrestimeCPUCCTNode[])filtered.getChildren();\n//            nChildren = children == null ? 0 : children.length;\n//            compactDataOfs = filtered.compactDataOfs;\n//        } else {\n            nChildren = childrenL.size();\n            children = childrenL.toArray(new PrestimeCPUCCTNode[0]);\n//        }\n        \n//        // Now that children are created, sort them in the order previously used\n//        sortChildren(config.getSortBy(), config.getSortOrder());\n        \n        return children;\n    }\n    \n    public boolean isLeaf() {\n        if (nChildren == 0) return true;\n        else if (children == null) return false;\n        else return children.length == 0;\n    }\n    \n    private boolean hasSelfTimeChild() {\n        return !isThreadNode() && !isFiltered() && compactDataOfs.size() == 1;\n    }\n    \n    protected void merge(PrestimeCPUCCTNodeBacked node) {\n//        children = null;\n//        nChildren += node.nChildren;\n//        \n//        nCalls += node.nCalls;\n//        sleepTime0 += node.sleepTime0;\n//        totalTime0 += node.totalTime0;\n//        totalTime1 += node.totalTime1;\n//        waitTime0 += node.waitTime0;\n    }\n    \n    protected void resetChildren() {\n//        if (compactDataOfs != null) {\n//            compactDataOfs.clear();\n//            compactDataOfs.add(selfCompactDataOfs);\n//            nChildren = container.getNChildrenForNodeOfs(selfCompactDataOfs);\n//        }\n//        \n//        if (children == null) return;\n//        \n//        if (!isThreadNode() || parent != null) { // thread nodes\n//            children = null;\n//        } else {\n//            super.resetChildren();\n//        }\n    }\n    \n    public void setSelfTimeNode() {\n        super.setSelfTimeNode();\n        nChildren = 0;\n        children = null;\n        int ofs = selfCompactDataOfs;\n        totalTime0 = container.getSelfTime0ForNodeOfs(ofs);\n        if (container.collectingTwoTimeStamps)\n            totalTime1 = container.getSelfTime1ForNodeOfs(ofs);\n    }\n\n//    public int getMethodId() {\n//        return methodID;\n//    }\n\n//    public int getNCalls() {\n//        return nCalls;\n//    }\n\n    public int getNChildren() {\n        if (getChildren() == null) return 0;\n        return nChildren;\n    }\n\n//    public long getSleepTime0() {\n//        return sleepTime0;\n//\n//        // TODO: [wait] self time node?\n//    }\n\n//    public int getThreadId() {\n//        return container.getThreadId();\n//    }\n\n//    public long getTotalTime0() {\n//        return totalTime0;\n//    }\n\n    public float getTotalTime0InPerCent() {\n        float result = (float) ((container.getWholeGraphNetTime0() > 0)\n                                ? ((double) totalTime0 / (double) container.getWholeGraphNetTime0() * 100.0) : 0);\n\n        return (result < 100) ? result : 100;\n    }\n\n//    public long getTotalTime1() {\n//        return totalTime1;\n//    }\n\n    public float getTotalTime1InPerCent() {\n        return (float) ((container.getWholeGraphNetTime1() > 0)\n                        ? ((double) totalTime1 / (double) container.getWholeGraphNetTime1() * 100.0) : 0);\n    }\n\n//    public long getWaitTime0() {\n//        return waitTime0;\n//\n//        // TODO: [wait] self time node?\n//    }\n    \n    public void exportXMLData(ExportDataDumper eDD,String indent) {\n        String newline = System.getProperty(\"line.separator\"); // NOI18N\n        StringBuffer result = new StringBuffer(indent+\"<node>\"+newline); //NOI18N\n        result.append(indent).append(\" <Name>\").append(replaceHTMLCharacters(getNodeName())).append(\"</Name>\").append(newline); //NOI18N\n        CCTNode p = getParent();\n        result.append(indent).append(\" <Parent>\").append(replaceHTMLCharacters((p==null)?(\"none\"):(((PrestimeCPUCCTNodeBacked)getParent()).getNodeName()))).append(\"</Parent>\").append(newline); //NOI18N\n        result.append(indent).append(\" <Time_Relative>\").append(percentFormat.format(p!=null?(((double) getTotalTime0InPerCent())/100):100)).append(\"</Time_Relative>\").append(newline); //NOI18N\n        result.append(indent).append(\" <Time>\").append( p!=null ? getTotalTime0() : \"N/A\" ).append(\"</Time>\").append(newline); //NOI18N\n        if (container.collectingTwoTimeStamps) {\n            result.append(indent).append(\" <Time-CPU>\").append(getTotalTime1()).append(\"</Time-CPU>\").append(newline); //NOI18N\n        }\n        result.append(indent).append(\" <Invocations>\").append( p!=null ? getNCalls() : 1).append(\"</Invocations>\").append(newline); //NOI18N\n        eDD.dumpData(result); //dumps the current row\n        // children nodes\n        if (children!=null) {\n            for (int i = 0; i < nChildren; i++) {\n                ((PrestimeCPUCCTNodeBacked)children[i]).exportXMLData(eDD, indent+\"  \"); //NOI18N\n            }\n        } else {\n            if (nChildren>0) {\n                int tempNChildren=nChildren;\n                PrestimeCPUCCTNode[] tempChildren=(PrestimeCPUCCTNode[]) getChildren();\n                children=null;\n                for (int i = 0; i < nChildren; i++) {\n                    ((PrestimeCPUCCTNodeBacked)tempChildren[i]).exportXMLData(eDD, indent+\"  \"); //NOI18N\n                }\n                nChildren=tempNChildren;\n            }\n        }\n        result=new StringBuffer(indent+\"</node>\"); //NOI18N\n        eDD.dumpData(result);\n    }\n\n    public void exportHTMLData(ExportDataDumper eDD, int depth) {\n        StringBuffer result = new StringBuffer(\"<tr><td class=\\\"method\\\"><pre class=\\\"method\\\">.\"); //NOI18N\n        for (int i=0; i<depth; i++) {\n            result.append(\".\"); //NOI18N\n        }\n        result.append(replaceHTMLCharacters(getNodeName())).append(\"</pre></td><td class=\\\"right\\\">\").append(percentFormat.format(((double) getTotalTime0InPerCent())/100)).append(\"</td><td class=\\\"right\\\">\").append(getTotalTime0()); //NOI18N\n        if (container.collectingTwoTimeStamps) {\n            result.append(\"</td><td class=\\\"right\\\">\").append(getTotalTime1()); //NOI18N\n        }\n        result.append(\"</td><td class=\\\"right\\\">\").append(getNCalls()).append(\"</td></tr>\"); //NOI18N\n        eDD.dumpData(result); //dumps the current row\n        // children nodes\n        if (children!=null) {\n            for (int i = 0; i < nChildren; i++) {\n                ((PrestimeCPUCCTNodeBacked)children[i]).exportHTMLData(eDD, depth+1);\n            }\n        } else {\n            if (nChildren>0) {\n                int tempNChildren=nChildren;\n                PrestimeCPUCCTNode[] tempChildren=(PrestimeCPUCCTNode[]) getChildren();\n                children=null;\n                for (int i = 0; i < nChildren; i++) {\n                    ((PrestimeCPUCCTNodeBacked)tempChildren[i]).exportHTMLData(eDD, depth+1);\n                }\n                nChildren=tempNChildren;\n            }\n        }\n    }\n\n    private String replaceHTMLCharacters(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break; // NOI18N\n              case '>': sb.append(\"&gt;\"); break; // NOI18N\n              case '&': sb.append(\"&amp;\"); break; // NOI18N\n              case '\"': sb.append(\"&quot;\"); break; // NOI18N\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n\n    public void exportCSVData(String separator, int depth, ExportDataDumper eDD) {\n        StringBuffer result = new StringBuffer();\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n        String indent = \" \"; // NOI18N\n\n        // this node\n        result.append(quote);\n        for (int i=0; i<depth; i++) {\n            result.append(indent); // to simulate the tree structure in CSV\n        }\n        result.append(getNodeName()).append(quote).append(separator);\n        result.append(quote).append(getTotalTime0InPerCent()).append(quote).append(separator);\n        result.append(quote).append(getTotalTime0()).append(quote).append(separator);\n        if (container.collectingTwoTimeStamps) {\n            result.append(quote).append(getTotalTime1()).append(quote).append(separator);\n        }\n        result.append(quote).append(getNCalls()).append(quote).append(newLine);\n        eDD.dumpData(result); //dumps the current row\n        // children nodes\n        if (children!=null) {\n            for (int i = 0; i < nChildren; i++) {\n                ((PrestimeCPUCCTNodeBacked)children[i]).exportCSVData(separator, depth+1, eDD);\n            }\n        } else {\n            if (nChildren>0) {\n                int tempNChildren=nChildren;\n                PrestimeCPUCCTNode[] tempChildren=(PrestimeCPUCCTNode[]) getChildren();\n                children=null;\n                for (int i = 0; i < nChildren; i++) {\n                    ((PrestimeCPUCCTNodeBacked)tempChildren[i]).exportCSVData(separator, depth+1, eDD);\n                }\n                nChildren=tempNChildren;\n            }\n        }\n    }\n\n    public static void setPercentFormat(NumberFormat percentFormat) {\n        PrestimeCPUCCTNodeBacked.percentFormat = percentFormat;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/PrestimeCPUCCTNodeFree.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport java.text.NumberFormat;\n\n\n/**\n * Presentation-Time CPU Profiling Calling Context Tree (CCT) Node that contains all necessary data in its data fields.\n * These objects are used for reverse CCTs and other trees that have to be constructed incrementally, so that backing by\n * flattened data cannot be easily implemented.\n *\n * @author Misha Dmitriev\n */\npublic class PrestimeCPUCCTNodeFree extends PrestimeCPUCCTNode {\n\n    private static NumberFormat percentFormat=null;\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n//    protected int methodId;\n//    protected int nCalls;\n//    protected long sleepTime0;\n//\n//    /** The same class used for both standard and \"extended\" nodes (collecting one or two timestamps) */\n//    protected long totalTime0;\n//    protected long totalTime1;\n//\n//    /** The same class used for both standard and \"extended\" nodes (collecting one or two timestamps) */\n//    protected long waitTime0;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Constructor for creating normal nodes representing methods\n     */\n    protected PrestimeCPUCCTNodeFree(CPUCCTContainer container, PrestimeCPUCCTNode parent, int methodId) {\n        super(container, parent, methodId);\n//        this.methodId = methodId;\n    }\n\n    PrestimeCPUCCTNodeFree() {}\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n//    public CCTNode getChild(int index) {\n//        return children[index];\n//    }\n//\n//    public CCTNode[] getChildren() {\n//        return children;\n//    }\n    \n    PrestimeCPUCCTNode createCopy() {\n        PrestimeCPUCCTNodeFree copy = new PrestimeCPUCCTNodeFree();\n        setupCopy(copy);\n        return copy;\n    }\n    \n    public CCTNode createFilteredNode() {\n        PrestimeCPUCCTNodeFree filtered = new PrestimeCPUCCTNodeFree();\n        setupFilteredNode(filtered);\n        return filtered;\n    }\n\n    public void setMethodId(int methodId) {\n        this.methodId = methodId;\n    }\n\n//    public int getMethodId() {\n//        return methodId;\n//    }\n\n//    public int getNCalls() {\n//        return nCalls;\n//    }\n\n//    public int getNChildren() {\n//        return (children != null) ? children.length : 0;\n//    }\n\n//    public long getSleepTime0() {\n//        return 0; // TODO [wait]\n//    }\n\n//    public int getThreadId() {\n//        return container.getThreadId();\n//    }\n\n//    public long getTotalTime0() {\n//        return totalTime0;\n//    }\n\n    public float getTotalTime0InPerCent() {\n        float result = (float) ((double) totalTime0 / container.getWholeGraphNetTime0() * 100);\n\n        return (result < 100) ? result : 100f;\n    }\n\n//    public long getTotalTime1() {\n//        return totalTime1;\n//    }\n\n    public float getTotalTime1InPerCent() {\n        return (float) ((double) totalTime1 / container.getWholeGraphNetTime1() * 100);\n    }\n\n//    public long getWaitTime0() {\n//        return 0; // TODO [wait]\n//    }\n    \n//    void merge(PrestimeCPUCCTNodeFree node) {\n//        addNCalls(node.getNCalls());\n//        addSleepTime0(node.getSleepTime0());\n//        addTotalTime0(node.getTotalTime0());\n//        addTotalTime1(node.getTotalTime1());\n//        addWaitTime0(node.getWaitTime0());\n//        \n//        if (node.children != null) {\n//            for (PrestimeCPUCCTNode ch : node.children)\n//                ch.parent = this;\n//            \n//            int chl = children == null ? 0 : children.length;\n//            int newchl = node.children.length;\n//            PrestimeCPUCCTNodeFree[] newch = new PrestimeCPUCCTNodeFree[chl + newchl];\n//            if (children != null) System.arraycopy(children, 0, newch, 0, chl);\n//            System.arraycopy(node.children, 0, newch, chl, newchl);\n//            children = newch;\n//        }\n//    }\n\n    public void addChild(PrestimeCPUCCTNodeFree node) {\n        if (children == null) {\n            children = new PrestimeCPUCCTNodeFree[1];\n        } else {\n            PrestimeCPUCCTNodeFree[] newch = new PrestimeCPUCCTNodeFree[children.length + 1];\n            System.arraycopy(children, 0, newch, 0, children.length);\n            children = newch;\n        }\n\n        children[children.length - 1] = node;\n    }\n\n//    /**\n//     * Methods used during node merging\n//     */\n//    public void addNCalls(int addCalls) {\n//        nCalls += addCalls;\n//    }\n//\n//    public void addSleepTime0(long addTime) {\n//        sleepTime0 += addTime;\n//    }\n//\n//    public void addTotalTime0(long addTime) {\n//        totalTime0 += addTime;\n//    }\n//\n//    public void addTotalTime1(long addTime) {\n//        totalTime1 += addTime;\n//    }\n//\n//    public void addWaitTime0(long addTime) {\n//        waitTime0 += addTime;\n//    }\n\n    /**\n     * Create a copy of this node, but with zero children\n     */\n    public PrestimeCPUCCTNodeFree createChildlessCopy() {\n        try {\n            PrestimeCPUCCTNodeFree res = (PrestimeCPUCCTNodeFree) this.clone();\n            res.children = null;\n\n            return res;\n        } catch (CloneNotSupportedException ex) {\n            return null; /* Shouldn't happen */\n        }\n    }\n    \n    public void exportXMLData(ExportDataDumper eDD,String indent) {\n        String newline = System.getProperty(\"line.separator\"); // NOI18N\n        StringBuffer result = new StringBuffer(indent+\"<node>\"+newline); //NOI18N\n        result.append(indent).append(\" <Name>\").append(replaceHTMLCharacters(getNodeName())).append(\"</Name>\").append(newline); //NOI18N\n        CCTNode p = getParent();\n        result.append(indent).append(\" <Parent>\").append(replaceHTMLCharacters((p==null)?(\"none\"):(((PrestimeCPUCCTNodeFree)getParent()).getNodeName()))).append(\"</Parent>\").append(newline); //NOI18N\n        result.append(indent).append(\" <Time_Relative>\").append(percentFormat.format( p==null ? ((double)getTotalTime0InPerCent())/100 : 100 )).append(\"</Time_Relative>\").append(newline); //NOI18N\n        result.append(indent).append(\" <Time>\").append(p==null ? getTotalTime0() : \"N/A\").append(\"</Time>\").append(newline); //NOI18N\n        if (container.collectingTwoTimeStamps) {\n            result.append(indent).append(\" <Time-CPU>\").append(getTotalTime1()).append(\"</Time-CPU>\").append(newline); //NOI18N\n        }\n        result.append(indent).append(\" <Invocations>\").append(p==null ? getNCalls() : 1 ).append(\"</Invocations>\").append(newline); //NOI18N\n        eDD.dumpData(result); //dumps the current row\n        // children nodes\n        if (children!=null) {\n            for (int i = 0; i < getNChildren(); i++) {\n                ((PrestimeCPUCCTNodeFree)children[i]).exportXMLData(eDD, indent+\"  \"); //NOI18N\n            }\n        }\n        result=new StringBuffer(indent+\"</node>\"); //NOI18N\n        eDD.dumpData(result);\n    }\n\n    public void exportHTMLData(ExportDataDumper eDD, int depth) {\n        StringBuffer result = new StringBuffer(\"<tr><td class=\\\"method\\\"><pre class=\\\"method\\\">\"); //NOI18N\n        for (int i=0; i<depth; i++) {\n            result.append(\".\"); //NOI18N\n        }\n        result.append(replaceHTMLCharacters(getNodeName())).append(\"</pre></td><td class=\\\"right\\\">\").append(percentFormat.format(((double)getTotalTime0InPerCent())/100)).append(\"</td><td class=\\\"right\\\">\").append(getTotalTime0());\n        if (container.collectingTwoTimeStamps) {\n            result.append(\"</td><td class=\\\"right\\\">\").append(getTotalTime1());\n        }\n        result.append(\"</td><td class=\\\"right\\\">\").append(getNCalls()).append(\"</td></tr>\"); //NOI18N\n        eDD.dumpData(result); //dumps the current row\n        // children nodes\n        if (children!=null) {\n            for (int i = 0; i < getNChildren(); i++) {\n                ((PrestimeCPUCCTNodeFree)children[i]).exportHTMLData(eDD, depth+1);\n            }\n        }\n    }\n\n    private String replaceHTMLCharacters(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break; // NOI18N\n              case '>': sb.append(\"&gt;\"); break; // NOI18N\n              case '&': sb.append(\"&amp;\"); break; // NOI18N\n              case '\"': sb.append(\"&quot;\"); break; // NOI18N\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n\n    public void exportCSVData(String separator, int depth, ExportDataDumper eDD) {\n        StringBuffer result = new StringBuffer();\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n        String indent = \" \"; // NOI18N\n\n        // this node\n        result.append(quote);\n        for (int i=0; i<depth; i++) {\n            result.append(indent); // to simulate the tree structure in CSV\n        }\n        result.append(getNodeName()).append(quote).append(separator);\n        result.append(quote).append(getTotalTime0InPerCent()).append(quote).append(separator);\n        result.append(quote).append(getTotalTime0()).append(quote).append(separator);\n        if (container.collectingTwoTimeStamps) {\n            result.append(quote).append(getTotalTime1()).append(quote).append(separator);\n        }\n        result.append(quote).append(getNCalls()).append(quote).append(newLine);\n        eDD.dumpData(result); //dumps the current row\n        // children nodes\n        if (children!=null) {\n            for (int i = 0; i < getNChildren(); i++) {\n                ((PrestimeCPUCCTNodeFree)children[i]).exportCSVData(separator, depth+1, eDD);\n            }\n        }\n    }\n\n    public static void setPercentFormat(NumberFormat percentFormat) {\n        PrestimeCPUCCTNodeFree.percentFormat = percentFormat;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/StackTraceSnapshotBuilder.java",
    "content": "/*\n * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport java.lang.Thread.State;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.ListIterator;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\nimport java.util.concurrent.atomic.AtomicReference;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MethodCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.TimedCPUCCTNode;\n\n/**\n *\n * @author Jaroslav Bachorik, Tomas Hurka\n */\npublic class StackTraceSnapshotBuilder {\n\n    static final char NAME_SIG_SPLITTER = '|';\n    private static final StackTraceElement[] NO_STACK_TRACE = new StackTraceElement[0];\n    private static final boolean COLLECT_TWO_TIMESTAMPS = true;\n    private static final Set<MethodInfo> knownBLockingMethods = new HashSet(Arrays.asList(new MethodInfo[] {\n        new MethodInfo(\"java.net.PlainSocketImpl\", \"socketAccept[native]\"), // NOI18N\n        new MethodInfo(\"java.net.PlainSocketImpl\", \"socketAccept[native](java.net.SocketImpl) : void\"), // NOI18N\n        new MethodInfo(\"sun.awt.windows.WToolkit\", \"eventLoop[native]\"), // NOI18N\n        new MethodInfo(\"sun.awt.windows.WToolkit\", \"eventLoop[native]() : void\"), // NOI18N\n        new MethodInfo(\"java.lang.UNIXProcess\", \"waitForProcessExit[native]\"), // NOI18N\n        new MethodInfo(\"java.lang.UNIXProcess\", \"waitForProcessExit[native](int) : int\"), // NOI18N\n        new MethodInfo(\"sun.awt.X11.XToolkit\", \"waitForEvents[native]\"), // NOI18N\n        new MethodInfo(\"sun.awt.X11.XToolkit\", \"waitForEvents[native](long) : void\"), // NOI18N\n        new MethodInfo(\"apple.awt.CToolkit\", \"doAWTRunLoop[native]\"), // NOI18N\n        new MethodInfo(\"apple.awt.CToolkit\", \"doAWTRunLoop[native](long, boolean, boolean) : void\"), // NOI18N\n        new MethodInfo(\"java.lang.Object\", \"wait[native]\"), // NOI18N\n        new MethodInfo(\"java.lang.Object\", \"wait[native](long) : void\"), // NOI18N\n        new MethodInfo(\"java.lang.Object\", \"wait0[native]\"), // NOI18N\n        new MethodInfo(\"java.lang.Object\", \"wait0[native](long) : void\"), // NOI18N\n        new MethodInfo(\"java.lang.Thread\", \"sleep[native]\"), // NOI18N\n        new MethodInfo(\"java.lang.Thread\", \"sleep[native](long) : void\"), // NOI18N\n        new MethodInfo(\"java.lang.Thread\", \"sleep0[native]\"), // NOI18N\n        new MethodInfo(\"java.lang.Thread\", \"sleep0[native](long) : void\"), // NOI18N\n        new MethodInfo(\"java.lang.Thread\", \"sleepNanos0[native]\"), // NOI18N\n        new MethodInfo(\"java.lang.Thread\", \"sleepNanos0[native](long) : void\"), // NOI18N\n        new MethodInfo(\"sun.net.dns.ResolverConfigurationImpl\",\"notifyAddrChange0[native]\"), // NOI18N\n        new MethodInfo(\"sun.net.dns.ResolverConfigurationImpl\",\"notifyAddrChange0[native]() : int\"), // NOI18N\n        new MethodInfo(\"java.lang.ProcessImpl\",\"waitFor[native]\"), // NOI18N\n        new MethodInfo(\"java.lang.ProcessImpl\",\"waitFor[native]() : int\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.EPollArrayWrapper\",\"epollWait[native]\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.EPollArrayWrapper\",\"epollWait[native](long, int, long, int) : int\"), // NOI18N\n        new MethodInfo(\"java.net.DualStackPlainSocketImpl\",\"accept0[native]\"), // NOI18N\n        new MethodInfo(\"java.net.DualStackPlainSocketImpl\",\"accept0[native](int, java.net.InetSocketAddress[]) : int\"), // NOI18N\n        new MethodInfo(\"java.lang.ProcessImpl\",\"waitForInterruptibly[native]\"), // NOI18N\n        new MethodInfo(\"java.lang.ProcessImpl\",\"waitForInterruptibly[native](long) : void\"), // NOI18N\n        new MethodInfo(\"sun.print.Win32PrintServiceLookup\",\"notifyPrinterChange[native]\"), // NOI18N\n        new MethodInfo(\"sun.print.Win32PrintServiceLookup\",\"notifyPrinterChange[native](long) : int\"), // NOI18N\n        new MethodInfo(\"java.net.DualStackPlainSocketImpl\",\"waitForConnect[native]\"), // NOI18N\n        new MethodInfo(\"java.net.DualStackPlainSocketImpl\",\"waitForConnect[native](int, int) : void\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.KQueueArrayWrapper\",\"kevent0[native]\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.KQueueArrayWrapper\",\"kevent0[native](int, long, int, long) : int\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.WindowsSelectorImpl$SubSelector\",\"poll0[native]\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.WindowsSelectorImpl$SubSelector\",\"poll0[native](long, int, int[], int[], int[], long) : int\"), // NOI18N\n        new MethodInfo(\"java.net.PlainSocketImpl\", \"socketConnect[native]\"), // NOI18N\n        new MethodInfo(\"java.net.PlainSocketImpl\", \"socketConnect[native](java.net.InetAddress, int, int) : void\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.ServerSocketChannelImpl\", \"accept0[native]\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.ServerSocketChannelImpl\", \"accept0[native](java.io.FileDescriptor, java.io.FileDescriptor, java.net.InetSocketAddress[]) : int\"), // NOI18N\n        new MethodInfo(\"java.lang.ref.Reference\", \"waitForReferencePendingList[native]\"), // NOI18N\n        new MethodInfo(\"java.lang.ref.Reference\", \"waitForReferencePendingList[native]() : void\"), // NOI18N\n        new MethodInfo(\"sun.nio.fs.LinuxWatchService\", \"poll[native]\"), // NOI18N\n        new MethodInfo(\"sun.nio.fs.LinuxWatchService\", \"poll[native](int, int) : int\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.Net\", \"accept[native]\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.Net\", \"accept[native](java.io.FileDescriptor, java.io.FileDescriptor, java.net.InetSocketAddress[]) : int\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.Net\", \"poll[native]\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.Net\", \"poll[native](java.io.FileDescriptor, int, long) : int\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.Net\", \"connect0[native]\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.Net\", \"connect0[native](boolean, java.io.FileDescriptor, java.net.InetAddress, int) : int\"), // NOI18N\n        new MethodInfo(\"java.lang.ProcessHandleImpl\", \"waitForProcessExit0[native]\"), // NOI18N\n        new MethodInfo(\"java.lang.ProcessHandleImpl\", \"waitForProcessExit0[native](long, boolean) : int\"), // NOI18N\n        new MethodInfo(\"java.net.PlainSocketImpl\", \"accept0[native]\"), // NOI18N\n        new MethodInfo(\"java.net.PlainSocketImpl\", \"accept0[native](int, java.net.InetSocketAddress[]) : int\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.KQueue\", \"keventPoll[native]\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.KQueue\", \"keventPoll[native](int, long, int) : int\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.KQueue\", \"poll[native]\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.KQueue\", \"poll[native](int, long, int, long) : int\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.UnixDomainSockets\", \"accept0[native]\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.UnixDomainSockets\", \"accept0[native](java.io.FileDescriptor, java.io.FileDescriptor, java.lang.Object[]) : int\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.EPoll\", \"wait[native]\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.EPoll\", \"wait[native](int, long, int, int) : int\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.WEPoll\", \"wait[native]\"), // NOI18N\n        new MethodInfo(\"sun.nio.ch.WEPoll\", \"wait[native](long, long, int, int) : int\"), // NOI18N\n    }));\n\n    private InstrumentationFilter filter;\n    \n    static class MethodInfo {\n        \n        final String className;\n        final String methodName;\n        final String signature;\n        final boolean isNative;\n        \n        MethodInfo(String className, String methodName) {\n            this.className = className;\n            this.methodName = methodName;\n            signature = \"\";\n            isNative = false;\n        }\n        \n        MethodInfo(StackTraceElement element) {\n            isNative = element.isNativeMethod();\n            final String nativeSuffix = \"[native]\"; // NOI18N\n            String methodAndSigName = element.getMethodName();\n            String method;\n            int index = methodAndSigName.indexOf(NAME_SIG_SPLITTER);\n            if (index > 0) {\n                method = methodAndSigName.substring(0, index);\n                signature = methodAndSigName.substring(index+1);\n            } else {\n                method = methodAndSigName;\n                signature = \"\";\n            }\n            if (isNative) {\n                index = method.indexOf('(');    // NOI18N\n                if (index > 0) {\n                    methodName = new StringBuilder(method).insert(index, nativeSuffix).toString();\n                } else {\n                    methodName = method + nativeSuffix;\n                }\n            } else {\n                methodName = method;\n            }\n            className = element.getClassName();\n        }\n        \n        @Override\n        public boolean equals(Object obj) {\n            if (this == obj) {\n                return true;\n            }\n            if (obj == null) {\n                return false;\n            }\n            if (getClass() != obj.getClass()) {\n                return false;\n            }\n            final MethodInfo other = (MethodInfo) obj;\n            if (!Objects.equals(className, other.className)) {\n                return false;\n            }\n            if (!Objects.equals(methodName, other.methodName)) {\n                return false;\n            }\n            if (!Objects.equals(signature, other.signature)) {\n                return false;\n            }\n            return true;\n        }\n        \n        @Override\n        public int hashCode() {\n            int hash = 5;\n            hash = 29 * hash + (this.className != null ? this.className.hashCode() : 0);\n            hash = 29 * hash + (this.methodName != null ? this.methodName.hashCode() : 0);\n            hash = 29 * hash + (this.signature != null ? this.signature.hashCode() : 0);\n            return hash;\n        }\n        \n        @Override\n        public String toString() {\n            return className + \".\" + methodName + \"()\";\n        }\n    }\n    \n    static class SampledThreadInfo {\n        private StackTraceElement[] stackTrace;\n        private Thread.State state;\n        private String threadName;\n        private long threadId;\n        private long threadCpuTime;\n \n        SampledThreadInfo(String tn, long tid, Thread.State ts, StackTraceElement[] st, InstrumentationFilter filter) {\n            this (tn, tid,ts, st, -1, filter);\n        }\n\n        SampledThreadInfo(String tn, long tid, Thread.State ts, StackTraceElement[] st, long tct, InstrumentationFilter filter) {\n            threadName = tn;\n            threadId = tid;\n            state = ts;\n            stackTrace = st;\n            threadCpuTime = tct;\n            if (state == Thread.State.RUNNABLE && containsKnownBlockingMethod(st)) { // known blocking method -> change state to waiting\n                state = Thread.State.WAITING;\n            }\n            if (filter != null) {\n                int i;\n                \n                for (i=0; i<st.length; i++) {\n                    StackTraceElement frame = st[i];\n                    if (filter.passes(frame.getClassName().replace('.','/'))) { // NOI18N\n                        if (i>1) {\n                            stackTrace = new StackTraceElement[st.length-i+1];\n                            System.arraycopy(st,i-1,stackTrace,0,stackTrace.length);\n                        }\n                        break;\n                    }\n                }\n                if (i==st.length) {\n                    stackTrace = NO_STACK_TRACE;\n                }\n            }\n        }\n        \n        SampledThreadInfo(java.lang.management.ThreadInfo info, InstrumentationFilter filter) {\n            this(info.getThreadName(), info.getThreadId(), info.getThreadState(), info.getStackTrace(), filter);\n        }\n        \n        private static boolean containsKnownBlockingMethod(StackTraceElement[] stackTrace) {\n            if (stackTrace.length > 0) {\n                MethodInfo firstFrame = new MethodInfo(stackTrace[0]);\n                return knownBLockingMethods.contains(firstFrame);\n            }\n            return false;\n        }\n\n        private StackTraceElement[] getStackTrace() {\n            return stackTrace;\n        }\n\n        State getThreadState() {\n            return state;\n        }\n\n        private String getThreadName() {\n            return threadName;\n        }\n\n        private long getThreadId() {\n            return threadId;\n        }\n        \n    }\n    \n    final Set<Long> threadIds = new HashSet<>();\n    final List<String> threadNames = new ArrayList<>();\n    final List<byte[]> threadCompactData = new ArrayList<>();\n    final List<MethodInfo> methodInfos = new ArrayList<>();\n    final Map<MethodInfo,Integer> methodInfoMap = new HashMap<>();\n    final MethodInfoMapper mapper = new MethodInfoMapper() {\n        \n        @Override\n        public String getInstrMethodClass(int methodId) {\n            return methodInfos.get(methodId).className;\n        }\n        \n        @Override\n        public String getInstrMethodName(int methodId) {\n            return methodInfos.get(methodId).methodName;\n        }\n        \n        @Override\n        public String getInstrMethodSignature(int methodId) {\n            return methodInfos.get(methodId).signature;\n        }\n        \n        @Override\n        public int getMaxMethodId() {\n            return methodInfos.size();\n        }\n        \n        @Override\n        public int getMinMethodId() {\n            return 0;\n        }\n    };\n    final CPUCallGraphBuilder ccgb;\n    final ProfilingSessionStatus status;\n    final Object lock = new Object();\n    final Object stampLock = new Object();\n    // @GuardedBy stampLock\n    long currentDumpTimeStamp = -1L;\n    final AtomicReference<Map<Long, SampledThreadInfo>> lastStackTrace = new AtomicReference<>(Collections.EMPTY_MAP);\n    int stackTraceCount = 0;\n    //    int builderBatchSize;\n    final Set<String> ignoredThreadNames = new HashSet<>();\n    final Map<Long,Long> threadtimes = new HashMap();\n    \n    {\n        registerNewMethodInfo(new MethodInfo(\"Thread\",\"\")); // NOI18N\n    }\n    \n    public StackTraceSnapshotBuilder() {\n        this(1, null);\n    }\n    \n    StackTraceSnapshotBuilder(CPUCallGraphBuilder b, InstrumentationFilter f, ProfilingSessionStatus s) {\n        //        builderBatchSize = batchSize;\n        filter = f;\n        setDefaultTiming();\n        ccgb = b;\n        status = s;\n    }\n    \n    public StackTraceSnapshotBuilder(int batchSize, InstrumentationFilter f) {\n        //        builderBatchSize = batchSize;\n        filter = f;\n        setDefaultTiming();\n        ccgb = new StackTraceCallGraphBuilder(mapper, f);\n        status = null;\n    }\n    \n    final public void setIgnoredThreads(Set<String> ignoredThreadNames) {\n        synchronized (lock) {\n            this.ignoredThreadNames.clear();\n            this.ignoredThreadNames.addAll(ignoredThreadNames);\n        }\n    }\n    \n    final void addStacktrace(SampledThreadInfo[] threads, long dumpTimeStamp) throws IllegalStateException {\n        long timediff = processDumpTimeStamp(dumpTimeStamp);\n        \n        if (timediff < 0) return;\n        synchronized (lock) {\n            Map<Long,SampledThreadInfo> tinfoMap = new HashMap(threads.length);\n            \n            for (SampledThreadInfo tinfo : threads) {\n                tinfoMap.put(tinfo.getThreadId(),tinfo);\n            }\n            processThreadDump(timediff, dumpTimeStamp, tinfoMap);\n            //            if (stackTraceCount%builderBatchSize == 0) {\n            //                ccgb.doBatchStop();\n            //            }\n        }\n    }\n\n    final public void addStacktrace(Map<String, Object>[] infoMap, long dumpTimeStamp) throws IllegalStateException {\n        List<SampledThreadInfo> threads = new ArrayList<>(infoMap.length);\n\n        for (Map<String,Object> threadInfo : infoMap) {\n            String name = (String) threadInfo.get(\"name\");\n            StackTraceElement[] stack = (StackTraceElement[]) threadInfo.get(\"stack\");\n            long tid = (Long) threadInfo.get(\"tid\");\n            Long threadCpuTime = (Long) threadInfo.get(\"threadCpuTime\");\n            State state = (State) threadInfo.get(\"state\");\n\n            if (threadCpuTime == null) {\n                threadCpuTime = Long.valueOf(-1);   // no thread cpu time\n            }\n            if (state == null) {\n                state = State.RUNNABLE;\n            }\n            SampledThreadInfo i = new SampledThreadInfo(name, tid, state, stack, threadCpuTime.longValue(), filter);\n\n            threads.add(i);\n        }\n        addStacktrace(threads.toArray(new SampledThreadInfo[0]), dumpTimeStamp);\n    }\n    \n    final public void addStacktrace(java.lang.management.ThreadInfo[] threads, long dumpTimeStamp) throws IllegalStateException {\n        long timediff = processDumpTimeStamp(dumpTimeStamp);\n        \n        if (timediff < 0) return;\n        synchronized (lock) {\n            Map<Long,SampledThreadInfo> tinfoMap = new HashMap(threads.length);\n            \n            //            if (stackTraceCount%builderBatchSize == 0) {\n            //                ccgb.doBatchStart();\n            //            }\n            for (java.lang.management.ThreadInfo tinfo : threads) {\n                if (tinfo != null) {\n                    tinfoMap.put(tinfo.getThreadId(),new SampledThreadInfo(tinfo,filter));\n                }\n            }\n            processThreadDump(timediff, dumpTimeStamp, tinfoMap);\n            //            if (stackTraceCount%builderBatchSize == 0) {\n            //                ccgb.doBatchStop();\n            //            }\n        }\n    }\n\n    private void processThreadDump(final long timediff, final long dumpTimeStamp, final Map<Long, SampledThreadInfo> tinfoMap) throws IllegalStateException {\n        Iterator<Map.Entry<Long,SampledThreadInfo>> tinfoIt = tinfoMap.entrySet().iterator();\n        \n        while (tinfoIt.hasNext()) {\n            Map.Entry<Long,SampledThreadInfo> tinfoEntry = tinfoIt.next();\n            SampledThreadInfo tinfo = tinfoEntry.getValue();\n            String tname = tinfo.getThreadName();\n            \n            if (ignoredThreadNames.contains(tname)) {\n                tinfoIt.remove();\n                continue;\n            }\n            Thread.State newState = tinfo.getThreadState();\n            // ignore threads, which has not yet started.\n            if (Thread.State.NEW.equals(newState)) {\n                tinfoIt.remove();\n                continue;\n            }\n            \n            long threadId = tinfo.getThreadId();\n            if (!threadIds.contains(threadId)) {\n                long threadCpuTime = tinfo.threadCpuTime;\n                threadIds.add(threadId);\n                threadNames.add(tname);\n                ccgb.newThread((int) threadId, tname, \"<none>\");\n                if (threadCpuTime != -1) {\n                    threadtimes.put(threadId,threadCpuTime);\n                } else {\n                    threadtimes.put(threadId,dumpTimeStamp);\n                }\n            }\n            StackTraceElement[] newElements = tinfo.getStackTrace();\n            SampledThreadInfo oldTinfo = lastStackTrace.get().get(threadId);\n            StackTraceElement[] oldElements = NO_STACK_TRACE;\n            Thread.State oldState = Thread.State.NEW;\n            \n            if (oldTinfo != null) {\n                oldElements = oldTinfo.getStackTrace();\n                oldState = oldTinfo.getThreadState();\n            }\n            processDiffs((int) threadId, oldElements, newElements, dumpTimeStamp, tinfo.threadCpuTime, timediff, oldState, newState);\n        }\n        \n        for (SampledThreadInfo oldTinfo : lastStackTrace.get().values()) {            \n            if (!tinfoMap.containsKey(oldTinfo.getThreadId())) {\n                Thread.State oldState = oldTinfo.getThreadState();\n                Thread.State newState = Thread.State.TERMINATED;\n                processDiffs((int) oldTinfo.getThreadId(), oldTinfo.getStackTrace(), NO_STACK_TRACE, dumpTimeStamp, oldTinfo.threadCpuTime, timediff, oldState, newState);\n            }\n        }\n        \n        lastStackTrace.set(tinfoMap);\n        \n        stackTraceCount++;\n    }\n\n    private long processDumpTimeStamp(long dumpTimeStamp) {\n        long timediff;\n        synchronized(stampLock) {\n            if (dumpTimeStamp <= currentDumpTimeStamp) {\n                // issue #171756 - ignore misplaced samples\n                // montonicity of System.nanoTime is not presently guaranteed (CR 6458294)\n                // throw new IllegalStateException(\"Adding stacktrace with timestamp \" + dumpTimeStamp + \" is not allowed after a stacktrace with timestamp \" + currentDumpTimeStamp + \" has been added\");\n                return -1;\n            }\n            timediff = dumpTimeStamp - currentDumpTimeStamp;\n            currentDumpTimeStamp = dumpTimeStamp;\n        }\n        return timediff;\n    }\n    \n    private void processDiffs(int threadId, StackTraceElement[] oldElements, StackTraceElement[] newElements, long timestamp, long threadCpuTime, long timediff, Thread.State oldState, Thread.State newState) throws IllegalStateException {\n        assert newState != Thread.State.NEW : \"Invalid thread state \" + newState.name() + \" for taking a stack trace\"; // just to be sure\n        if (oldState == Thread.State.TERMINATED && newState != Thread.State.TERMINATED) {\n            throw new IllegalStateException(\"Thread has already been set to \" + Thread.State.TERMINATED.name() + \" - stack trace can not be taken\");\n        }\n        //        switch (oldState) {\n        //            case NEW: {\n        //                switch (newState) {\n        //                    case RUNNABLE: {\n        //                        processDiffs(threadId, oldElements, newElements, timestamp);\n        //                        break;\n        //                    }\n        //                }\n        //                break;\n        //            }\n        //            case RUNNABLE: {\n        //                break;\n        //            }\n        //            case WAITING:\n        //            case TIMED_WAITING: {\n        //                ccgb.waitExit(threadId, timestamp, threadtime);\n        //                break;\n        //            }\n        //            case BLOCKED: {\n        //                ccgb.monitorExit(threadId, timestamp, threadtime);\n        //                break;\n        //            }\n        //        }\n        long threadtime;\n        if (threadCpuTime == -1) {\n            threadtime = threadtimes.get(Long.valueOf(threadId));\n            if (oldState == Thread.State.RUNNABLE) {\n                threadtime += timediff;\n                threadtimes.put(Long.valueOf(threadId),threadtime);\n            }\n        } else {\n            threadtime = threadCpuTime;\n        }\n        //        if (newState == Thread.State.RUNNABLE && newElements.length > 0) {\n        //            StackTraceElement top = newElements[0];\n        //            if (top.getClassName().equals(\"java.lang.Object\") && top.isNativeMethod() && top.getMethodName().equals(\"wait\")) {\n        //                System.out.println(\"!!!!!!!!!!!!!!!!!!!!!!!\");\n        //                System.out.println(\"!!!!!!!!!!!!!!!!!!!!!!!\");\n        //            }\n        //        }\n        processDiffs(threadId, oldElements, newElements, timestamp, threadtime);\n        //        switch (newState) {\n        //            case RUNNABLE: {\n        //                break;\n        //            }\n        //            case WAITING:\n        //            case TIMED_WAITING: {\n        //                ccgb.waitEntry(threadId, timestamp, threadtime);\n        //                break;\n        //            }\n        //            case BLOCKED: {\n        //                ccgb.monitorEntry(threadId, timestamp, threadtime);\n        //                break;\n        //            }\n        //        }\n    }\n    \n    private void processDiffs(int threadId, StackTraceElement[] oldElements, StackTraceElement[] newElements, long timestamp, long threadtimestamp) throws IllegalStateException {\n        if (oldElements.length == 0 && newElements.length == 0) {\n            return;\n        }\n        \n        int newMax = newElements.length - 1;\n        int oldMax = oldElements.length - 1;\n        int globalMax = Math.max(oldMax, newMax);\n        \n        List<StackTraceElement> newElementsList = Collections.EMPTY_LIST;\n        List<StackTraceElement> oldElementsList = Collections.EMPTY_LIST;\n        \n        for (int iteratorIndex = 0; iteratorIndex <= globalMax; iteratorIndex++) {\n            StackTraceElement oldElement = oldMax >= iteratorIndex ? oldElements[oldMax - iteratorIndex] : null;\n            StackTraceElement newElement = newMax >= iteratorIndex ? newElements[newMax - iteratorIndex] : null;\n            \n            if (oldElement != null && newElement != null) {\n                if (!oldElement.equals(newElement)) {\n                    if (hasSameMethodInfo(oldElement,newElement)) {\n                        iteratorIndex++;\n                    }\n                    newElementsList = Arrays.asList(newElements).subList(0, newMax - iteratorIndex + 1);\n                    oldElementsList = Arrays.asList(oldElements).subList(0, oldMax - iteratorIndex + 1);\n                    break;\n                }\n            } else if (oldElement == null && newElement != null) {\n                newElementsList = Arrays.asList(newElements).subList(0, newMax - iteratorIndex + 1);\n                break;\n                \n            } else if (oldElement != null && newElement == null) {\n                oldElementsList = Arrays.asList(oldElements).subList(0, oldMax - iteratorIndex + 1);\n                break;\n                \n            }\n        }\n        \n        // !!! The order is important - first we need to exit from the\n        // already entered methods and only then we can enter the new ones !!!\n        addMethodExits(threadId, oldElementsList, timestamp, threadtimestamp, newElements.length == 0);\n        addMethodEntries(threadId, newElementsList, timestamp, threadtimestamp, oldElements.length == 0);\n    }\n    \n    private void addMethodEntries(int threadId, List<StackTraceElement> elements, long timestamp, long threadtimestamp, boolean asRoot) throws IllegalStateException {\n        boolean inRoot = false;\n        ListIterator<StackTraceElement> reverseIt = elements.listIterator(elements.size());\n        \n        while(reverseIt.hasPrevious()) {\n            StackTraceElement element = reverseIt.previous();\n            MethodInfo mi = new MethodInfo(element);\n            Integer mId = methodInfoMap.get(mi);\n            if (mId == null) {\n                mId = registerNewMethodInfo(mi);\n                if (status != null) {\n                    String method = mi.methodName;\n                    int index = method.indexOf('(');\n                    if (index > 0) {\n                        method = method.substring(0,index);\n                    }\n                    status.updateInstrMethodsInfo(mi.className,0,method,mi.signature);\n                }\n            }\n            \n            if (asRoot && !inRoot) {\n                inRoot = true;\n                ccgb.methodEntry(mId.intValue(), threadId, CPUCallGraphBuilder.METHODTYPE_ROOT, timestamp, threadtimestamp, null, null);\n            } else {\n                ccgb.methodEntry(mId.intValue(), threadId, CPUCallGraphBuilder.METHODTYPE_NORMAL, timestamp, threadtimestamp, null, null);\n            }\n            \n        }\n    }\n\n    private Integer registerNewMethodInfo(final MethodInfo mi) {\n        Integer index = Integer.valueOf(methodInfos.size());\n        \n        methodInfos.add(mi);\n        methodInfoMap.put(mi,index);\n        return index;\n    }\n    \n    private void addMethodExits(int threadId, List<StackTraceElement> elements, long timestamp, long threadtimestamp, boolean asRoot) throws IllegalStateException {\n        int rootIndex = elements.size();\n        for (StackTraceElement element : elements) {\n            MethodInfo mi = new MethodInfo(element);\n            Integer index = methodInfoMap.get(mi);\n            if (index == null) {\n                System.err.println(\"*** Not found: \" + mi);\n                throw new IllegalStateException();\n            }\n            \n            if (asRoot && --rootIndex == 0) {\n                ccgb.methodExit(index.intValue(), threadId, CPUCallGraphBuilder.METHODTYPE_ROOT, timestamp, threadtimestamp, null);\n            } else {\n                ccgb.methodExit(index.intValue(), threadId, CPUCallGraphBuilder.METHODTYPE_NORMAL, timestamp, threadtimestamp, null);\n            }\n        }\n    }\n    \n    private boolean hasSameMethodInfo(StackTraceElement oldElement, StackTraceElement newElement) {\n        MethodInfo oldMethodInfo = new MethodInfo(oldElement);\n        MethodInfo newMethodInfo = new MethodInfo(newElement);\n        \n        return oldMethodInfo.equals(newMethodInfo);\n    }\n    \n    private void setDefaultTiming() {\n        // Ugly code to set default CPU calibration data\n        ProfilingSessionStatus pss = new ProfilingSessionStatus();\n        pss.timerCountsInSecond[0] = InstrTimingData.DEFAULT.timerCountsInSecond0;\n        pss.timerCountsInSecond[1] = InstrTimingData.DEFAULT.timerCountsInSecond1;\n        pss.currentInstrType = CommonConstants.INSTR_RECURSIVE_FULL;\n        pss.absoluteTimerOn = true;\n        pss.threadCPUTimerOn = true;\n        TimingAdjusterOld.getInstance(pss);        \n    }\n\n    /**\n     * Creates CPUResultsSnapsot\n     * @param since time in milliseconds\n     * @return snapshot\n     * @throws org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot.NoDataAvailableException \n     */\n    public final CPUResultsSnapshot createSnapshot(\n            long since) throws CPUResultsSnapshot.NoDataAvailableException {\n        if (stackTraceCount < 1) {\n            throw new CPUResultsSnapshot.NoDataAvailableException();\n        }\n        \n        String[] instrMethodClasses;\n        String[] instrMethodNames;\n        String[] instrMethodSigs;\n        int miCount;\n        synchronized (lock) {\n            miCount = methodInfos.size();\n            instrMethodClasses = new String[methodInfos.size()];\n            instrMethodNames = new String[methodInfos.size()];\n            instrMethodSigs = new String[methodInfos.size()];\n            \n            int counter = 0;\n            for (MethodInfo mi : methodInfos) {\n                instrMethodClasses[counter] = mi.className;\n                instrMethodNames[counter] = mi.methodName;\n                instrMethodSigs[counter] = mi.signature;\n                counter++;\n            }\n            return new CPUResultsSnapshot(since, System.currentTimeMillis(),\n                    ccgb, ccgb.isCollectingTwoTimeStamps(), filter,\n                    instrMethodClasses, instrMethodNames, instrMethodSigs, miCount);\n        }\n    }\n    \n    public final void reset() {\n        synchronized (lock) {\n            ccgb.reset();\n            if (status != null) {\n                status.resetInstrClassAndMethodInfo();\n            }\n            methodInfos.clear();\n            methodInfoMap.clear();\n            threadIds.clear();\n            threadNames.clear();\n            stackTraceCount = 0;\n            lastStackTrace.set(Collections.EMPTY_MAP);\n            registerNewMethodInfo(new MethodInfo(\"Thread\",\"\")); // NOI18N\n            synchronized(stampLock) {\n                currentDumpTimeStamp = -1L;\n            }\n        }\n    }\n    \n    public MethodInfoMapper getMapper() {\n        return mapper;\n    }\n    \n    public RuntimeCCTNode getAppRootNode() {\n        return ccgb.getAppRootNode();\n    }\n    \n    public boolean collectionTwoTimeStamps() {\n        return COLLECT_TWO_TIMESTAMPS;\n    }\n    \n    public InstrumentationFilter getFilter() {\n        return filter;\n    }\n    \n    private class StackTraceCallGraphBuilder extends CPUCallGraphBuilder {\n\n        StackTraceCallGraphBuilder (MethodInfoMapper mapper, InstrumentationFilter filter) {\n            setFilter(filter);\n            setMethodInfoMapper(mapper);\n        }\n\n        @Override\n        protected boolean isCollectingTwoTimeStamps() {\n            return COLLECT_TWO_TIMESTAMPS;\n        }\n\n        @Override\n        protected boolean isReady() {\n            return true;\n        }\n\n        @Override\n        protected long getDumpAbsTimeStamp() {\n            synchronized (stampLock) {\n                return currentDumpTimeStamp;\n            }\n        }\n\n        @Override\n        protected void applyDiffAtGetResultsMoment(ThreadInfo ti) {\n            long time0 = getDumpAbsTimeStamp();\n            long diff0 = time0 - ti.topMethodEntryTime0;\n            long diff1 = getThreadTime(ti, time0) - ti.topMethodEntryTime1;\n\n            if (diff0<0) diff0=0;\n            if (diff1<0) diff1=0;\n            if (diff0>0 || diff1>0) {\n                applyDiffToTopNode(ti, diff0, diff1);\n                ti.diffAtGetResultsMoment0 = diff0;\n                ti.diffAtGetResultsMoment1 = diff1;\n            }\n        }\n\n        @Override\n        protected void undoDiffAtGetResultsMoment(ThreadInfo ti) {\n            if (ti.diffAtGetResultsMoment0>0) {\n                applyDiffToTopNode(ti, -ti.diffAtGetResultsMoment0, -ti.diffAtGetResultsMoment1);\n                ti.diffAtGetResultsMoment0 = 0;\n            }\n        }\n\n        private long getThreadTime(ThreadInfo ti, long time0) {\n            if (isCollectingTwoTimeStamps()) {\n                SampledThreadInfo sti = lastStackTrace.get().get(Long.valueOf(ti.threadId));\n\n                if (sti!=null) {\n                    if (sti.threadCpuTime != -1) {\n                        return sti.threadCpuTime;\n                    }\n                    if (sti.getThreadState() == Thread.State.RUNNABLE) {\n                        return threadtimes.get(Long.valueOf(ti.threadId));\n                    }\n                }\n            }\n            return 0;\n        }\n\n        private void applyDiffToTopNode(ThreadInfo ti, long diff0, long diff1) {\n            TimedCPUCCTNode top = ti.peek();\n\n            if (top instanceof MethodCPUCCTNode) {\n                top.addNetTime0(diff0);\n                if (isCollectingTwoTimeStamps()) {\n                    top.addNetTime1(diff1);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/ThreadInfo.java",
    "content": "/*\n * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.TimedCPUCCTNode;\n\npublic class ThreadInfo {\n\n    //~ Static fields/initializers -------------------------------------------------------------------------------------------\n    // The following variable is used to record the \"compensation\" value, a difference between the timestamp at the\n    // moment user hits \"get results\" and the timestamp for the method entry into the top stack method. To present\n    // results consistenly, we add this value to the TimedCPUCCTNode for the top-stack method. However, when\n    // processing of data is resumed, we need to subtract this value back from that node.\n    // This is effectively the self time for the last invocation of the top method on stack - if we would not keep\n    // it separately, it would not be reported\n    long diffAtGetResultsMoment0; // diff between last methodEntry and current moment timestamp - we will have to compensate for the processing time\n    long diffAtGetResultsMoment1; // as above, but for thread CPU time\n\n    //~ Instance fields ------------------------------------------------------------------------------------------------------\n    final private Object stackLock = new Object();\n    public TimedCPUCCTNode[] stack;\n    // Simulated stack for this thread - stack starting at root method\n    // (or a pseudo node if multiple root methods are called within the thread)\n    int inRoot;\n    // flag indicating this thread is in a root method initiated code\n    int stackTopIdx;\n    // Index of the stack top element\n    public final int threadId;\n    public int totalNNodes;\n    // total number of call tree nodes for this thread\n    long rootGrossTimeAbs;\n    long rootGrossTimeThreadCPU;\n    // Accumulated absolute and thread CPU gross time for the root method\n    // - blackout data subtracted, calibration data not\n    public long rootMethodEntryTimeAbs;\n    public long rootMethodEntryTimeThreadCPU;\n    // Absoute and thread CPU entry timestamps for the root method.\n    // The xxx0 part is used when only absolute or thread CPU time data is collected.\n    // Both xxx0 and xx1 parts are used when both timestamps are collected.\n    public long topMethodEntryTime0;\n    public long topMethodEntryTime1;\n    // Entry (or \"re-entry\" upon return from the callee) time for the topmost method\n    public long totalNInv;\n\n    ThreadInfo(int threadId) {\n        super();\n        stack = new TimedCPUCCTNode[40];\n        stackTopIdx = -1;\n        inRoot = 0;\n        this.threadId = threadId;\n    }\n\n    public boolean isInRoot() {\n        return inRoot > 0;\n    }\n\n    public TimedCPUCCTNode peek() {\n        synchronized (stackLock) {\n            return (stackTopIdx > -1) ? stack[stackTopIdx] : null;\n        }\n    }\n\n    public TimedCPUCCTNode pop() {\n        TimedCPUCCTNode node = null;\n        synchronized (stackLock) {\n            if (stackTopIdx >= 0) {\n                node = stack[stackTopIdx];\n                stack[stackTopIdx] = null;\n                stackTopIdx--;\n            }\n            return node;\n        }\n    }\n\n    public void push(TimedCPUCCTNode node) {\n        synchronized (stackLock) {\n            stackTopIdx++;\n            if (stackTopIdx >= stack.length) {\n                increaseStack();\n            }\n            stack[stackTopIdx] = node;\n            node.addNCalls(1);\n            totalNInv++;\n        }\n    }\n\n    private void increaseStack() {\n        synchronized(stackLock) {\n            TimedCPUCCTNode[] newStack = new TimedCPUCCTNode[stack.length * 2];\n            System.arraycopy(stack, 0, newStack, 0, stack.length);\n            stack = newStack;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/ThreadInfos.java",
    "content": "/*\n * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.global.TransactionalSupport;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ThreadInfos {\n\n    public ThreadInfo[] threadInfos;\n    String[] threadNames;\n    String[] threadClassNames;\n    int threadInfosLastIdx;\n    private TransactionalSupport transaction = new TransactionalSupport();\n\n    public ThreadInfos() {\n        reset();\n    }\n\n    public void beginTrans(boolean mutable) {\n        transaction.beginTrans(mutable);\n    }\n\n    boolean beginTrans(boolean mutable, boolean failEarly) {\n        return transaction.beginTrans(mutable, failEarly);\n    }\n\n    public void endTrans() {\n        transaction.endTrans();\n    }\n\n    public boolean isEmpty() {\n        beginTrans(false);\n        try {\n            if ((threadInfos == null) || (threadInfos.length == 0)) {\n                return true;\n            }\n            for (ThreadInfo threadInfo : threadInfos) {\n                if ((threadInfo != null) && (threadInfo.stack != null) && (threadInfo.stack[0] != null) && (threadInfo.stack[0].getChildren() != null) && (threadInfo.stack[0].getChildren().length > 0)) {\n                    return false;\n                }\n            }\n            return true;\n        } finally {\n            endTrans();\n        }\n    }\n\n    public String[] getThreadNames() {\n        beginTrans(false);\n        try {\n            return threadNames;\n        } finally {\n            endTrans();\n        }\n    }\n\n    public void newThreadInfo(int threadId, String threadName, String threadClassName) {\n        beginTrans(true);\n        try {\n            if ((threadId > threadInfosLastIdx) || (threadInfos == null)) {\n                int newLen = threadId + 1;\n                ThreadInfo[] newInfos = new ThreadInfo[newLen];\n                String[] newNames = new String[newLen];\n                String[] newClassNames = new String[newLen];\n                if (threadInfos != null) {\n                    System.arraycopy(threadInfos, 0, newInfos, 0, threadInfos.length);\n                    System.arraycopy(threadNames, 0, newNames, 0, threadNames.length);\n                    System.arraycopy(threadClassNames, 0, newClassNames, 0, threadNames.length);\n                }\n                threadInfos = newInfos;\n                threadNames = newNames;\n                threadClassNames = newClassNames;\n                threadInfosLastIdx = threadId;\n            }\n            if (threadInfos[threadId] == null) {\n                threadInfos[threadId] = new ThreadInfo(threadId);\n                threadNames[threadId] = threadName;\n                threadClassNames[threadId] = threadClassName;\n            }\n        } finally {\n            endTrans();\n        }\n    }\n\n    public void reset() {\n        beginTrans(true);\n        try {\n            threadInfos = null;\n            threadNames = null;\n            threadClassNames = null;\n            threadInfosLastIdx = -1;\n        } finally {\n            endTrans();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/TimingAdjuster.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\n\n//import org.graalvm.visualvm.lib.jfluid.global.Platform;\n//import org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\n//import org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class TimingAdjuster {\n    //  // @GuardedBy this\n    //  private InstrTimingData timingData;\n    //\n    //  public TimingAdjuster(final ProfilingSessionStatus status, final boolean collectingTwoTimeStamps) {\n    //    calculateTimingData(status, collectingTwoTimeStamps);\n    //  }\n    //\n    //  final public synchronized TimeStamp adjustTime(TimeStamp time, int incommingInv, int outgoingInv) {\n    //    TimeStamp result = null;\n    //\n    //    long timeExCleansed = timingData.timerCountsInSecond1 == 0 ? 0 : (long)((double) time.getExtendedTime() - incommingInv * timingData.methodEntryExitInnerTime1 - outgoingInv * timingData.methodEntryExitOuterTime1) * 1000000 / timingData.timerCountsInSecond1;\n    //    long timeCleansed = timingData.timerCountsInSecond0 == 0 ? 0 : (long)((double) time.getTime() - incommingInv * timingData.methodEntryExitInnerTime0 - outgoingInv * timingData.methodEntryExitOuterTime0) * 1000000 / timingData.timerCountsInSecond0;\n    //\n    //    timeCleansed = timeCleansed < 0 ? 0 : timeCleansed;\n    //    timeExCleansed = timeExCleansed < 0 ? 0 : timeExCleansed;\n    //\n    //    result = TimeStamp.createTimeStamp(timeCleansed, timeExCleansed);\n    //\n    //    return result;\n    //  }\n    //\n    //  final public synchronized double delta(int incommingInv, int outgoingInv, boolean secondTimestamp) {\n    //    double adjusted = 0;\n    //    if (secondTimestamp) {\n    //      adjusted = ((double) incommingInv * timingData.methodEntryExitInnerTime1 - outgoingInv * timingData.methodEntryExitOuterTime1) * 1000000 / timingData.timerCountsInSecond1;\n    //    } else {\n    //      adjusted = ((double) incommingInv * timingData.methodEntryExitInnerTime0 - outgoingInv * timingData.methodEntryExitOuterTime0) * 1000000 / timingData.timerCountsInSecond0;\n    //    }\n    //    \n    //    if (adjusted < 0) adjusted = 0;\n    //    return adjusted;\n    //  }\n    //  \n    //  final public synchronized boolean isAdjustible(long time, int incommingInv, int outgoingInv, boolean secondTimestamp) {\n    //    if (secondTimestamp) {\n    //      return time > (incommingInv * timingData.methodEntryExitInnerTime1 + outgoingInv * timingData.methodEntryExitOuterTime1);\n    //    } else {\n    //      return time > (incommingInv * timingData.methodEntryExitInnerTime0 + outgoingInv * timingData.methodEntryExitOuterTime0);\n    //    }\n    //  }\n    //  \n    //  public synchronized void calculateTimingData(final ProfilingSessionStatus status, final boolean collectingTwoTimeStamps) {\n    //    timingData = new InstrTimingData();\n    //    // We use the following \"safety margins\" to artificially decrease the time spent in instrumentation.\n    //    // That's because it looks like due to various CPU level speed optimizations the execution time for some code with\n    //    // added instrumentation may be pretty much equal to the execution time of the instrumentation itself. The profiled\n    //    // code, esp. if it's just one or two lines, is effectively executed in parallel with instrumentation.\n    //    // Furthermore, highly optimizing CPU plus possibly smth. like rounding errors may occasionally result in the\n    //    // measured time that is even *smaller* than the execution time of the instrumentation. This will result in\n    //    // *negative* cleansed times presented to the user.\n    //    // This safety margin is rough, but probably most reliable way to deal with these issues. The value has been\n    //    // chosen experimentally, and seems to result in reasonable compromise between data accuracy and no occurrences\n    //    // of zero time results.\n    //    double safetyMargin0 = 0.88;\n    //    double safetyMargin1 = 0.88;\n    //    double safetyMargin2 = 0.88;\n    //    if (collectingTwoTimeStamps) {\n    //      // Note that all methodEntryExitXXX times are measured in status in absolute timer counts.\n    //      // For usage in factor-out operations, we need to convert those that are used with thread CPU time values\n    //      // into thread CPU time units.\n    //      timingData.methodEntryExitCallTime0 = status.methodEntryExitCallTime[2] * safetyMargin2;\n    //      timingData.methodEntryExitCallTime1 =\n    //        status.methodEntryExitCallTime[3] * status.timerCountsInSecond[1] / status.timerCountsInSecond[0]\n    //        * safetyMargin2;\n    //      timingData.methodEntryExitInnerTime0 = status.methodEntryExitInnerTime[2] * safetyMargin2;\n    //      timingData.methodEntryExitOuterTime0 = status.methodEntryExitOuterTime[2] * safetyMargin2;\n    //      timingData.methodEntryExitInnerTime1 =\n    //        status.methodEntryExitInnerTime[3] * status.timerCountsInSecond[1] / status.timerCountsInSecond[0]\n    //        * safetyMargin2;\n    //      timingData.methodEntryExitOuterTime1 =\n    //        status.methodEntryExitOuterTime[3] * status.timerCountsInSecond[1] / status.timerCountsInSecond[0]\n    //        * safetyMargin2;\n    //      timingData.timerCountsInSecond0 = status.timerCountsInSecond[0];\n    //      timingData.timerCountsInSecond1 = status.timerCountsInSecond[1];\n    //    } else {\n    //      if (status.absoluteTimerOn) {\n    //        timingData.methodEntryExitCallTime0 = status.methodEntryExitCallTime[0] * safetyMargin0;\n    //        timingData.methodEntryExitInnerTime0 = status.methodEntryExitInnerTime[0] * safetyMargin0;\n    //        timingData.methodEntryExitOuterTime0 = status.methodEntryExitOuterTime[0] * safetyMargin0;\n    //        timingData.timerCountsInSecond0 = status.timerCountsInSecond[0];\n    //      } else {\n    //        // Thread CPU only timer used. On Windows and Linux, with extremely low (10 ms or even worse) resolution of\n    //        // this timer, it doesn't make sense to use cleansing - it introduces negative figures for short-running\n    //        // methods, for which I didn't find any graceful way to deal with.\n    //        // Also, cleansing is needed to make results sensible for short-running methods - but here for such methods\n    //        // they are already non-sensible, with 0 as a most typical result.\n    //        String targetMachineOSName = status.targetMachineOSName;\n    //        if (targetMachineOSName == null) return; // dont calculate timings for an undefined OS\n    //        if (Platform.isWindows(targetMachineOSName) || Platform.isLinux(targetMachineOSName)) {\n    //          safetyMargin1 = 0;\n    //        }\n    //        timingData.methodEntryExitCallTime0 =\n    //          status.methodEntryExitCallTime[1] * status.timerCountsInSecond[1] / status.timerCountsInSecond[0]\n    //          * safetyMargin1;\n    //        timingData.methodEntryExitInnerTime0 =\n    //          status.methodEntryExitInnerTime[1] * status.timerCountsInSecond[1] / status.timerCountsInSecond[0]\n    //          * safetyMargin1;\n    //        timingData.methodEntryExitOuterTime0 =\n    //          status.methodEntryExitOuterTime[1] * status.timerCountsInSecond[1] / status.timerCountsInSecond[0]\n    //          * safetyMargin1;\n    //        timingData.timerCountsInSecond0 = status.timerCountsInSecond[1];\n    //      }\n    //    }\n    //    System.out.println(timingData);\n    //  }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/TimingAdjusterOld.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport java.lang.ref.WeakReference;\n\n\n/**\n * A utility class to perform time measurements adjustments\n * @author Jaroslav Bachorik\n */\npublic class TimingAdjusterOld {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static TimingAdjusterOld instance;\n    private static WeakReference lastStatusRef;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private InstrTimingData timingData;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private TimingAdjusterOld(InstrTimingData timing) {\n        timingData = timing;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static synchronized TimingAdjusterOld getDefault() {\n        if (instance == null) {\n            instance = new TimingAdjusterOld(InstrTimingData.DEFAULT);\n        }\n\n        return instance;\n    }\n\n    public static synchronized TimingAdjusterOld getInstance(final ProfilingSessionStatus status) {\n        if (instance != null) {\n            ProfilingSessionStatus lastStatus = (lastStatusRef != null) ? (ProfilingSessionStatus) lastStatusRef.get() : null;\n\n            if (((lastStatus != null) && !lastStatus.equals(status)) || (lastStatus == null)) {\n                lastStatusRef = new WeakReference(status);\n\n                switch (status.currentInstrType) {\n                    case CommonConstants.INSTR_RECURSIVE_FULL: {\n                        instance = new TimingAdjusterOld(getFullInstrTimingData(status));\n\n                        break;\n                    }\n                    case CommonConstants.INSTR_RECURSIVE_SAMPLED: {\n                        instance = new TimingAdjusterOld(getSampledInstrTimingData(status));\n\n                        break;\n                    }\n                }\n            }\n        } else {\n            lastStatusRef = new WeakReference(status);\n\n            switch (status.currentInstrType) {\n                case CommonConstants.INSTR_RECURSIVE_FULL: {\n                    instance = new TimingAdjusterOld(getFullInstrTimingData(status));\n\n                    break;\n                }\n                case CommonConstants.INSTR_RECURSIVE_SAMPLED: {\n                    instance = new TimingAdjusterOld(getSampledInstrTimingData(status));\n\n                    break;\n                }\n            }\n        }\n\n        return instance;\n    }\n\n    public final double adjustTime(long time, int incommingInv, int outgoingInv, boolean secondTimestamp) {\n        if (timingData == null) {\n            return (double) time;\n        }\n\n        if (timingData.methodEntryExitCallTime0 == 0) {\n            if (secondTimestamp) {\n                return (double) time / timingData.timerCountsInSecond1;\n            } else {\n                return (double) time / timingData.timerCountsInSecond0;\n            }\n        }\n\n        if (secondTimestamp) {\n            return (((double) time - (incommingInv * timingData.methodEntryExitInnerTime1)\n                    - (outgoingInv * timingData.methodEntryExitOuterTime1)) * 1000000) / timingData.timerCountsInSecond1;\n        } else {\n            return (((double) time - (incommingInv * timingData.methodEntryExitInnerTime0)\n                    - (outgoingInv * timingData.methodEntryExitOuterTime0)) * 1000000) / timingData.timerCountsInSecond0;\n        }\n    }\n\n    public final double delta(int incommingInv, int outgoingInv, boolean secondTimestamp) {\n        if (timingData == null  || timingData.methodEntryExitCallTime0 == 0) {\n            return 0d;\n        }\n\n        double adjusted = 0;\n\n        if (secondTimestamp) {\n            adjusted = ((((double) incommingInv * timingData.methodEntryExitInnerTime1)\n                        + (outgoingInv * timingData.methodEntryExitOuterTime1)) * 1000000) / timingData.timerCountsInSecond1;\n        } else {\n            adjusted = ((((double) incommingInv * timingData.methodEntryExitInnerTime0)\n                        + (outgoingInv * timingData.methodEntryExitOuterTime0)) * 1000000) / timingData.timerCountsInSecond0;\n        }\n\n        if (adjusted < 0) {\n            adjusted = 0;\n        }\n\n        return adjusted;\n    }\n\n    public InstrTimingData getInstrTimingData() {\n        InstrTimingData data = getFullInstrTimingData(lastStatusRef != null ? (ProfilingSessionStatus)lastStatusRef.get() : null);\n        return data != null ? (InstrTimingData)data.clone() : (InstrTimingData)InstrTimingData.DEFAULT.clone();\n    }\n\n    private static InstrTimingData getFullInstrTimingData(ProfilingSessionStatus status) {\n        if (status == null) {\n            return null;\n        }\n        InstrTimingData timingData = new InstrTimingData();\n\n        // We use the following \"safety margins\" to artificially decrease the time spent in instrumentation.\n        // That's because it looks like due to various CPU level speed optimizations the execution time for some code with\n        // added instrumentation may be pretty much equal to the execution time of the instrumentation itself. The profiled\n        // code, esp. if it's just one or two lines, is effectively executed in parallel with instrumentation.\n        // Furthermore, highly optimizing CPU plus possibly smth. like rounding errors may occasionally result in the\n        // measured time that is even *smaller* than the execution time of the instrumentation. This will result in\n        // *negative* cleansed times presented to the user.\n        // This safety margin is rough, but probably most reliable way to deal with these issues. The value has been\n        // chosen experimentally, and seems to result in reasonable compromise between data accuracy and no occurrences\n        // of zero time results.\n        double safetyMargin0 = 0.88;\n        double safetyMargin1 = 0.88;\n        double safetyMargin2 = 0.88;\n\n        if (status.collectingTwoTimeStamps()) {\n            // Note that all methodEntryExitXXX times are measured in status in absolute timer counts.\n            // For usage in factor-out operations, we need to convert those that are used with thread CPU time values\n            // into thread CPU time units.\n            timingData.methodEntryExitCallTime0 = status.methodEntryExitCallTime[2] * safetyMargin2;\n            timingData.methodEntryExitCallTime1 = (status.methodEntryExitCallTime[3] * status.timerCountsInSecond[1]) / status.timerCountsInSecond[0] * safetyMargin2;\n            timingData.methodEntryExitInnerTime0 = status.methodEntryExitInnerTime[2] * safetyMargin2;\n            timingData.methodEntryExitOuterTime0 = status.methodEntryExitOuterTime[2] * safetyMargin2;\n            timingData.methodEntryExitInnerTime1 = (status.methodEntryExitInnerTime[3] * status.timerCountsInSecond[1]) / status.timerCountsInSecond[0] * safetyMargin2;\n            timingData.methodEntryExitOuterTime1 = (status.methodEntryExitOuterTime[3] * status.timerCountsInSecond[1]) / status.timerCountsInSecond[0] * safetyMargin2;\n            timingData.timerCountsInSecond0 = status.timerCountsInSecond[0];\n            timingData.timerCountsInSecond1 = status.timerCountsInSecond[1];\n        } else {\n            if (status.absoluteTimerOn) {\n                timingData.methodEntryExitCallTime0 = status.methodEntryExitCallTime[0] * safetyMargin0;\n                timingData.methodEntryExitInnerTime0 = status.methodEntryExitInnerTime[0] * safetyMargin0;\n                timingData.methodEntryExitOuterTime0 = status.methodEntryExitOuterTime[0] * safetyMargin0;\n                timingData.timerCountsInSecond0 = status.timerCountsInSecond[0];\n            } else {\n                // Thread CPU only timer used. On Windows (and till NB 7.0 also Linux), with extremely low\n                // (10 ms or even worse) resolution of\n                // this timer, it doesn't make sense to use cleansing - it introduces negative figures for short-running\n                // methods, for which I didn't find any graceful way to deal with.\n                // Also, cleansing is needed to make results sensible for short-running methods - but here for such methods\n                // they are already non-sensible, with 0 as a most typical result.\n                String targetMachineOSName = status.targetMachineOSName;\n\n                if (Platform.isWindows(targetMachineOSName) && status.targetJDKVersionString.equals(Platform.JDK_16_STRING)) {\n                    safetyMargin1 = 0;\n                }\n\n                timingData.methodEntryExitCallTime0 = (status.methodEntryExitCallTime[1] * status.timerCountsInSecond[1]) / status.timerCountsInSecond[0] * safetyMargin1;\n                timingData.methodEntryExitInnerTime0 = (status.methodEntryExitInnerTime[1] * status.timerCountsInSecond[1]) / status.timerCountsInSecond[0] * safetyMargin1;\n                timingData.methodEntryExitOuterTime0 = (status.methodEntryExitOuterTime[1] * status.timerCountsInSecond[1]) / status.timerCountsInSecond[0] * safetyMargin1;\n                timingData.timerCountsInSecond0 = status.timerCountsInSecond[1];\n            }\n        }\n\n        return timingData;\n    }\n\n    private static InstrTimingData getSampledInstrTimingData(ProfilingSessionStatus status) {\n        if (status == null) {\n            return null;\n        }\n        \n        InstrTimingData timingData = new InstrTimingData();\n\n        double entryExitTimeInAbsCounts = status.methodEntryExitCallTime[4];\n        double entryExitTimeInThreadCPUCounts = entryExitTimeInAbsCounts / status.timerCountsInSecond[0] * status.timerCountsInSecond[1];\n\n        if (status.collectingTwoTimeStamps()) {\n            timingData.methodEntryExitCallTime0 = entryExitTimeInAbsCounts;\n            timingData.methodEntryExitCallTime1 = entryExitTimeInThreadCPUCounts;\n            timingData.methodEntryExitInnerTime0 = entryExitTimeInAbsCounts;\n            timingData.methodEntryExitOuterTime0 = 0;\n            timingData.methodEntryExitInnerTime1 = entryExitTimeInThreadCPUCounts;\n            timingData.methodEntryExitOuterTime1 = 0;\n            timingData.timerCountsInSecond0 = status.timerCountsInSecond[0];\n            timingData.timerCountsInSecond1 = status.timerCountsInSecond[1];\n        } else {\n            if (status.absoluteTimerOn) {\n                timingData.methodEntryExitCallTime0 = entryExitTimeInAbsCounts;\n                timingData.methodEntryExitInnerTime0 = entryExitTimeInAbsCounts;\n                timingData.methodEntryExitOuterTime0 = 0;\n                timingData.timerCountsInSecond0 = status.timerCountsInSecond[0];\n            } else {\n                timingData.methodEntryExitCallTime0 = entryExitTimeInThreadCPUCounts;\n                timingData.methodEntryExitInnerTime0 = entryExitTimeInThreadCPUCounts;\n                timingData.methodEntryExitOuterTime0 = 0;\n                timingData.timerCountsInSecond0 = status.timerCountsInSecond[1];\n            }\n        }\n\n        return timingData;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/cct/CCTFlattener.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.cct;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.Stack;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNodeProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainerFree;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.TimingAdjusterOld;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MethodCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.TimedCPUCCTNode;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n * @author Tomas Hurka\n */\npublic class CCTFlattener extends RuntimeCCTNodeProcessor.PluginAdapter {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Logger LOGGER = Logger.getLogger(CCTFlattener.class.getName());\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final Object containerGuard = new Object();\n\n    // @GuardedBy containerGuard\n    private FlatProfileContainer container;\n    private ProfilerClient client;\n    private Stack<TotalTime> parentStack;\n    private Set methodsOnStack;\n    private int[] invDiff;\n    private int[] invPM;\n    private int[] nCalleeInvocations;\n    private long[] timePM0;\n    private long[] timePM1;\n    private long[] totalTimePM0;\n    private long[] totalTimePM1;\n    private int nMethods;\n\n    private CCTResultsFilter currentFilter;\n    private InstrumentationFilter instrFilter;\n    private int cpuProfilingType;\n    private boolean twoTimestamps;\n    private TimingAdjusterOld timingAdjuster;\n  \n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CCTFlattener(ProfilerClient client, CCTResultsFilter filter) {\n        this.client = client;\n        parentStack = new Stack();\n        methodsOnStack = new HashSet();\n        this.currentFilter = filter;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public FlatProfileContainer getFlatProfile() {\n        synchronized (containerGuard) {\n            return container;\n        }\n    }\n\n    @Override\n    public void onStart() {\n        ProfilingSessionStatus status = client.getStatus();\n        ProfilerEngineSettings pes = client.getSettings();\n        \n        nMethods = getMaxMethodId();\n        timePM0 = new long[nMethods];\n        timePM1 = new long[status.collectingTwoTimeStamps() ? nMethods : 0];\n        totalTimePM0 = new long[nMethods];\n        totalTimePM1 = new long[status.collectingTwoTimeStamps() ? nMethods : 0];\n        invPM = new int[nMethods];\n        invDiff = new int[nMethods];\n        nCalleeInvocations = new int[nMethods];\n        parentStack.clear();\n        methodsOnStack.clear();\n        instrFilter = pes.getInstrumentationFilter();\n        cpuProfilingType = pes.getCPUProfilingType();\n        twoTimestamps = status.collectingTwoTimeStamps();\n        timingAdjuster = TimingAdjusterOld.getInstance(status);\n        \n        synchronized (containerGuard) {\n            container = null;\n        }\n        \n        // uncomment the following piece of code when trying to reproduce #205482\n//        try {\n//            Thread.sleep(120);\n//        } catch (InterruptedException interruptedException) {\n//        }\n    }\n\n    @Override\n    public void onStop() {\n        // Now convert the data into microseconds\n        long wholeGraphTime0 = 0;\n\n        // Now convert the data into microseconds\n        long wholeGraphTime1 = 0;\n        long totalNInv = 0;\n\n        for (int i = 0; i < nMethods; i++) {\n            double time = timingAdjuster.adjustTime(timePM0[i], (invPM[i] + invDiff[i]), (nCalleeInvocations[i] + invDiff[i]),\n                                                       false);\n\n            if (time < 0) {\n                // in some cases the combination of cleansing the time by calibration and subtracting wait/sleep\n                // times can lead to <0 time\n                // see http://profiler.netbeans.org/issues/show_bug.cgi?id=64416\n                time = 0;\n            }\n\n            timePM0[i] = (long) time;\n\n            // don't include the Thread time into wholegraphtime\n            if (i > 0) {\n                wholeGraphTime0 += time;\n            }\n\n            if (twoTimestamps) {\n                time = timingAdjuster.adjustTime(timePM1[i], (invPM[i] + invDiff[i]), (nCalleeInvocations[i] + invDiff[i]),\n                                                    true);\n                \n                if (time < 0) {\n                    time = 0;\n                }\n                    \n                timePM1[i] = (long) time;\n\n                // don't include the Thread time into wholegraphtime\n                if (i > 0) {\n                    wholeGraphTime1 += time;\n                }\n            }\n\n            totalNInv += invPM[i];\n        }\n\n        synchronized (containerGuard) {\n            container = createContainer(timePM0, timePM1, totalTimePM0, totalTimePM1, invPM, wholeGraphTime0, wholeGraphTime1);\n        }\n\n        timePM0 = timePM1 = null;\n        totalTimePM0 = totalTimePM1 = null;\n        invPM = invDiff = nCalleeInvocations = null;\n        parentStack.clear();\n        methodsOnStack.clear();\n        instrFilter = null;\n    }\n    \n    @Override\n    public void onNode(MethodCPUCCTNode node) {\n        final int nodeMethodId = node.getMethodId();\n        final int nodeFilerStatus = node.getFilteredStatus();\n        final MethodCPUCCTNode currentParent = parentStack.isEmpty() ? null : (MethodCPUCCTNode) parentStack.peek().parent;\n        boolean filteredOut = (nodeFilerStatus == TimedCPUCCTNode.FILTERED_YES); // filtered out by rootmethod/markermethod rules\n\n        if (!filteredOut && (cpuProfilingType == CommonConstants.CPU_SAMPLED || nodeFilerStatus == TimedCPUCCTNode.FILTERED_MAYBE)) { // filter out all methods not complying to instrumentation filter & secure to remove\n\n            String jvmClassName = getInstrMethodClass(nodeMethodId).replace('.', '/'); // NOI18N\n\n            if (!instrFilter.passes(jvmClassName)) {\n                filteredOut = true;\n            }\n        }\n\n        if (!filteredOut && (currentFilter != null)) {\n            filteredOut = !currentFilter.passesFilter(); // finally use the mark filter\n        }\n        final int parentMethodId = currentParent != null ? currentParent.getMethodId() : -1;\n        \n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"Processing runtime node: {0}.{1}; filtered={2}, time={3}, CPU time={4}\", // NOI18N\n                       new Object[]{getInstrMethodClass(nodeMethodId), getInstrMethodName(nodeMethodId), \n                       filteredOut, node.getNetTime0(), node.getNetTime1()});\n\n            String parentInfo = (currentParent != null)\n                                ? (getInstrMethodClass(parentMethodId) + \".\"\n                                + getInstrMethodName(parentMethodId)) : \"none\"; // NOI18N\n            LOGGER.log(Level.FINEST, \"Currently used parent: {0}\", parentInfo); // NOI18N\n        }\n\n        if (filteredOut) {\n            if ((currentParent != null) && !currentParent.isRoot()) {\n                invDiff[parentMethodId] += node.getNCalls();\n\n                timePM0[parentMethodId] += node.getNetTime0();\n\n                if (twoTimestamps) {\n                    timePM1[parentMethodId] += node.getNetTime1();\n                }\n            }\n        } else {\n            timePM0[nodeMethodId] += node.getNetTime0();\n\n            if (twoTimestamps) {\n                timePM1[nodeMethodId] += node.getNetTime1();\n            }\n\n            invPM[nodeMethodId] += node.getNCalls();\n\n            if ((currentParent != null) && !currentParent.isRoot()) {\n                nCalleeInvocations[parentMethodId] += node.getNCalls();\n            }\n        }\n        final MethodCPUCCTNode nextParent = filteredOut ? currentParent : node;\n        final TotalTime timeNode = new TotalTime(nextParent,methodsOnStack.contains(nodeMethodId));\n        timeNode.totalTimePM0+=node.getNetTime0();\n        if (twoTimestamps) timeNode.totalTimePM1+=node.getNetTime1();  \n        if (!timeNode.recursive) {\n            methodsOnStack.add(nodeMethodId);\n        }\n        parentStack.push(timeNode);\n    }\n\n    @Override\n    public void onBackout(MethodCPUCCTNode node) {\n        TotalTime current = parentStack.pop();\n        if (!current.recursive) {\n            int nodeMethodId = node.getMethodId();\n            methodsOnStack.remove(nodeMethodId);\n            if (nodeMethodId != -1) {\n                long time = (long) timingAdjuster.adjustTime(current.totalTimePM0, node.getNCalls()+current.outCalls, current.outCalls,\n                                                           false);\n                if (time>0) {\n                    totalTimePM0[nodeMethodId]+=time;\n                }\n                if (twoTimestamps) {\n                    time = (long) timingAdjuster.adjustTime(current.totalTimePM1, node.getNCalls()+current.outCalls, current.outCalls,\n                                                           true);\n                    if (time>0) {\n                        totalTimePM1[nodeMethodId]+=time;\n                    }\n                }\n            }\n        }\n        // add self data to parent\n        if (!parentStack.isEmpty()) {\n            TotalTime parent = parentStack.peek();\n            parent.add(current);\n            parent.outCalls+=node.getNCalls();\n        }\n    }\n\n    protected int getMaxMethodId() {\n        return client.getStatus().getNInstrMethods();\n    }\n\n    protected String getInstrMethodClass(int nodeMethodId) {\n        return client.getStatus().getInstrMethodClasses()[nodeMethodId];\n    }\n\n    protected String getInstrMethodName(int nodeMethodId) {\n        return client.getStatus().getInstrMethodNames()[nodeMethodId];\n    }\n\n    protected FlatProfileContainer createContainer(long[] timeInMcs0, long[] timeInMcs1, \n            long[] totalTimeInMcs0, long[] totalTimeInMcs1, int[] nInvocations, \n            double wholeGraphNetTime0, double wholeGraphNetTime1) {\n        return new FlatProfileContainerFree(client.getStatus(), timeInMcs0, timeInMcs1, totalTimeInMcs0, totalTimeInMcs1,\n                    nInvocations, new char[0], wholeGraphNetTime0, wholeGraphNetTime1, nInvocations.length);\n    }\n\n    private static class TotalTime {\n        private final MethodCPUCCTNode parent;\n        private final boolean recursive;\n        private int outCalls;\n        private long totalTimePM0;\n        private long totalTimePM1;\n        \n        TotalTime(MethodCPUCCTNode n, boolean r) {\n            parent = n;\n            recursive = r;\n        }\n\n        private void add(TotalTime current) {\n            outCalls += current.outCalls;\n            totalTimePM0 += current.totalTimePM0;\n            totalTimePM1 += current.totalTimePM1;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/cct/CCTResultsFilter.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.cct;\n\nimport java.util.Collection;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MarkedCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.ThreadCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.marker.Mark;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Set;\nimport java.util.Stack;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNodeProcessor;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic final class CCTResultsFilter extends RuntimeCCTNodeProcessor.PluginAdapter {\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    public static interface Evaluator {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        boolean evaluate(Mark mark);\n    }\n\n    public static interface EvaluatorProvider {\n        Set/*<Evaluator>*/ getEvaluators();\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Logger LOGGER = Logger.getLogger(CCTResultsFilter.class.getName());\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Set /*<Evaluator>*/ evaluators = null;\n    private Set evaluatorProviders = new HashSet();\n\n    private Stack passFlagStack;\n    private boolean passingFilter;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of CategoryFilter */\n    public CCTResultsFilter() {\n        evaluators = new HashSet /*<Evaluator>*/();\n        passFlagStack = new Stack();\n        doReset();\n    }\n\n    public void setEvaluators(Collection evaluatorProviders) {\n        this.evaluatorProviders.clear();\n        this.evaluatorProviders.addAll(evaluatorProviders);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    public synchronized boolean passesFilter() {\n        return passingFilter;\n    }\n\n    @Override\n    public void onStart() {\n        evaluators.clear();\n        \n        for(Iterator iter = evaluatorProviders.iterator();iter.hasNext();) {\n            evaluators.addAll(((EvaluatorProvider)iter.next()).getEvaluators());\n        }\n    }\n\n    @Override\n    public void onStop() {\n        evaluators.clear();\n    }\n\n    public void reset() {\n        doReset();\n    }\n\n    @Override\n    public void onNode(ThreadCPUCCTNode node) {\n        LOGGER.finest(\"visiting thread node\");\n        passFlagStack.push(Boolean.valueOf(passingFilter));\n        passingFilter = true;\n\n        for (Iterator iter = evaluators.iterator(); iter.hasNext();) {\n            Evaluator evaluator = (Evaluator) iter.next();\n            passingFilter = passingFilter && evaluator.evaluate(Mark.DEFAULT);\n        }\n\n        LOGGER.log(Level.FINEST, \"Evaluator result: {0}\", passingFilter);\n    }\n    \n    @Override\n    public void onNode(MarkedCPUCCTNode node) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"Entering a node marked {0}\", node.getMark().getId()); // NOI18N\n        }\n\n        passFlagStack.push(Boolean.valueOf(passingFilter));\n        passingFilter = true;\n\n        for (Iterator iter = evaluators.iterator(); iter.hasNext();) {\n            Evaluator evaluator = (Evaluator) iter.next();\n            passingFilter = passingFilter && evaluator.evaluate(node.getMark());\n        }\n    }\n    \n    @Override\n    public void onBackout(ThreadCPUCCTNode node) {\n        if (!passFlagStack.isEmpty()) {\n            passingFilter = ((Boolean) passFlagStack.pop()).booleanValue();\n        }\n    }\n    \n    public void onBackout(MarkedCPUCCTNode node) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"Leaving a node marked {0}\", node.getMark().getId()); // NOI18N\n        }\n\n        if (!passFlagStack.isEmpty()) {\n            passingFilter = ((Boolean) passFlagStack.pop()).booleanValue();\n        }\n    }    \n\n    private void doReset() {\n        passingFilter = false;\n        passFlagStack.clear();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/cct/TimeCollector.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.cct;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.marker.Mark;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.TimingAdjusterOld;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MethodCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.marking.MarkAwareNodeProcessorPlugin;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class TimeCollector extends MarkAwareNodeProcessorPlugin {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private static class TimingData {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        int inCalls;\n        int outCalls;\n        long netTime0;\n        long netTime1;\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Map timing;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of MarkTimer\n     */\n    public TimeCollector() {\n        this.timing = new HashMap();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public synchronized long getNetTime0(Mark mark) {\n        if (isReset()) {\n            return 0;\n        }\n\n        TimingData currentTiming = (TimingData) timing.get(mark);\n        long time = (currentTiming != null)\n                    ? (long) TimingAdjusterOld.getDefault()\n                                              .adjustTime(currentTiming.netTime0, currentTiming.inCalls, currentTiming.outCalls,\n                                                          false) : 0;\n\n        return (time > 0) ? time : 0;\n    }\n\n    public synchronized long getNetTime1(Mark mark) {\n        if (isReset()) {\n            return 0;\n        }\n\n        TimingData currentTiming = (TimingData) timing.get(mark);\n        long time = (currentTiming != null)\n                    ? (long) TimingAdjusterOld.getDefault()\n                                              .adjustTime(currentTiming.netTime1, currentTiming.inCalls, currentTiming.outCalls,\n                                                          true) : 0;\n\n        return (time > 0) ? time : 0;\n    }\n\n    @Override\n    public void onStart() {\n        super.onStart();\n        timing.clear();\n    }\n\n    @Override\n    public void onStop() {\n        if (isReset()) {\n            this.timing = new HashMap();\n        }\n        super.onStop();\n    }\n\n    @Override\n    public void onNode(MethodCPUCCTNode node) {\n        if (isReset()) {\n            return;\n        }\n\n        Mark mark = getCurrentMark();\n        Mark parentMark = getParentMark();\n\n        if (mark != null) {\n            TimingData data = (TimingData) timing.get(mark);\n\n            if (data == null) {\n                data = new TimingData();\n                timing.put(mark, data);\n            }\n\n            data.inCalls += node.getNCalls();\n            data.netTime0 += node.getNetTime0();\n            data.netTime1 += node.getNetTime1();\n        }\n\n        if (parentMark != null) {\n            TimingData parentData = (TimingData) timing.get(parentMark);\n\n            if (parentData == null) {\n                parentData = new TimingData();\n                timing.put(parentMark, parentData);\n            }\n\n            parentData.outCalls += node.getNCalls();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/cct/nodes/BaseCPUCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes;\n\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic abstract class BaseCPUCCTNode implements RuntimeCPUCCTNode {\n\n    private static final RuntimeCCTNode[] EMPTY_CHILDREN = new RuntimeCCTNode[0];\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    /** Children nodes in the RuntimeCPUCCTNode tree. This field can have three different values depending on the\n     * number of children:\n     *   null if there are no children\n     *   instance of RuntimeCPUCCTNode if there is exactly one child\n     *   instance of RuntimeCPUCCTNode[] if there are multiple children\n     * This is purely a memory consumption optimization, which typically saves about 50% of memory, since a lot of\n     * RuntimeCPUCCTNode trees are a sequence of single-child nodes, and in such case we remove the need to\n     * create a one-item array.\n     */\n    private Object children;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of BaseCPUCCTNode */\n    public BaseCPUCCTNode() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public RuntimeCCTNode[] getChildren() {\n        if (children == null) {\n            return EMPTY_CHILDREN;\n        } else if (children instanceof RuntimeCPUCCTNode) {\n            return new RuntimeCPUCCTNode[]{(RuntimeCPUCCTNode)children};\n        }\n        return (RuntimeCPUCCTNode[])children;\n    }\n\n    public void attachNodeAsChild(RuntimeCPUCCTNode node) {\n        if (children == null) {\n            children = node;\n        } else if (children instanceof RuntimeCPUCCTNode) {\n            children = new RuntimeCPUCCTNode[]{(RuntimeCPUCCTNode)children,node};\n        } else {\n            RuntimeCPUCCTNode[] ch = (RuntimeCPUCCTNode[]) children;\n            RuntimeCPUCCTNode[] newChildren = new RuntimeCPUCCTNode[ch.length+1];\n            System.arraycopy(ch, 0, newChildren, 0, ch.length);\n            newChildren[newChildren.length-1] = node;\n            children = newChildren;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/cct/nodes/MarkedCPUCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes;\n\nimport org.graalvm.visualvm.lib.jfluid.marker.Mark;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class MarkedCPUCCTNode extends TimedCPUCCTNode {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class Locator {\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        private Locator() {\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public static MarkedCPUCCTNode locate(Mark mark, RuntimeCCTNode[] nodes) {\n            for(RuntimeCCTNode n : nodes) {\n                if (n instanceof MarkedCPUCCTNode && ((MarkedCPUCCTNode)n).getMark().equals(mark)) {\n                    return (MarkedCPUCCTNode)n;\n                }\n            }\n            return null;\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Mark mark;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of MarkedCPUCCTNode */\n    public MarkedCPUCCTNode(Mark mark) {\n        super();\n        this.mark = mark;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Mark getMark() {\n        return mark;\n    }\n\n    public boolean isRoot() {\n        return false;\n    }\n\n    public boolean equals(Object otherNode) {\n        if (otherNode == null) {\n            return false;\n        }\n\n        if (!(otherNode instanceof MarkedCPUCCTNode)) {\n            return false;\n        }\n\n        return mark.equals(((MarkedCPUCCTNode) otherNode).getMark());\n    }\n\n    public int hashCode() {\n        return (mark == null) ? 0 : mark.hashCode();\n    }\n\n    protected TimedCPUCCTNode createSelfInstance() {\n        return new MarkedCPUCCTNode(mark);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/cct/nodes/MethodCPUCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes;\n\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class MethodCPUCCTNode extends TimedCPUCCTNode {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class Locator {\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        private Locator() {\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public static MethodCPUCCTNode locate(int methodId, RuntimeCCTNode[] nodes) {\n            for(RuntimeCCTNode n : nodes) {\n                if (n instanceof MethodCPUCCTNode && ((MethodCPUCCTNode)n).getMethodId() == methodId)  {\n                    return (MethodCPUCCTNode)n;\n                }\n            }\n            return null;\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final int methodId;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of MethodCPUCCTNode */\n    public MethodCPUCCTNode(int methodId) {\n        super();\n        this.methodId = methodId;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getMethodId() {\n        return methodId;\n    }\n\n    public boolean isRoot() {\n        return false;\n    }\n\n    protected TimedCPUCCTNode createSelfInstance() {\n        return new MethodCPUCCTNode(getMethodId());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/cct/nodes/RuntimeCPUCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes;\n\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface RuntimeCPUCCTNode extends RuntimeCCTNode {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    boolean isRoot();\n\n    void attachNodeAsChild(RuntimeCPUCCTNode node);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/cct/nodes/ServletRequestCPUCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes;\n\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ServletRequestCPUCCTNode extends TimedCPUCCTNode {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class Locator {\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        private Locator() {\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public static ServletRequestCPUCCTNode locate(int requestType, String servletPath, RuntimeCCTNode[] nodes) {\n            for(RuntimeCCTNode n : nodes) {\n                if (n instanceof ServletRequestCPUCCTNode) {\n                    ServletRequestCPUCCTNode sn = (ServletRequestCPUCCTNode)n;\n                    if (sn.getServletPath().equals(servletPath) && sn.getRequestType() == requestType) {\n                        return sn;\n                    }\n                }\n            }\n            return null;\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    int hashCode = 0;\n    private final String servletPath;\n    private final int requestType;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of ServletRequestCPUCCTNode\n     */\n    public ServletRequestCPUCCTNode(int requestType, String path) {\n        super();\n        this.servletPath = path;\n        this.requestType = requestType;\n        setFilteredStatus(FILTERED_YES); // boundary node is going to be filtered by default\n        setNCalls(0);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getRequestType() {\n        return requestType;\n    }\n\n    public boolean isRoot() {\n        return false;\n    }\n\n    public String getServletPath() {\n        return servletPath;\n    }\n\n    public boolean equals(Object otherNode) {\n        if (otherNode == null) {\n            return false;\n        }\n\n        if (!(otherNode instanceof ServletRequestCPUCCTNode)) {\n            return false;\n        }\n\n        return servletPath.equals(((ServletRequestCPUCCTNode) otherNode).servletPath)\n               && (requestType == ((ServletRequestCPUCCTNode) otherNode).requestType);\n    }\n\n    public int hashCode() {\n        if (hashCode == 0) {\n            hashCode = servletPath.hashCode() + (requestType * 18321);\n        }\n\n        return hashCode;\n    }\n\n    protected TimedCPUCCTNode createSelfInstance() {\n        return new ServletRequestCPUCCTNode(requestType, servletPath);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/cct/nodes/SimpleCPUCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class SimpleCPUCCTNode extends BaseCPUCCTNode {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final boolean root;\n    private final int maxMethodId;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of SimpleCPUCCTNode */\n    public SimpleCPUCCTNode(boolean root) {\n        super();\n        this.root = root;\n        this.maxMethodId = Integer.MAX_VALUE;\n    }\n\n    public SimpleCPUCCTNode(int maxMethodId) {\n        super();\n        this.root = false;\n        this.maxMethodId = maxMethodId;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public boolean isRoot() {\n        return root;\n    }\n\n    public int getMaxMethodId() {\n        return maxMethodId;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/cct/nodes/ThreadCPUCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ThreadCPUCCTNode extends TimedCPUCCTNode {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final int threadId;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of ThreadCPUCCTNode */\n    public ThreadCPUCCTNode(int threadId) {\n        super();\n        this.threadId = threadId;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public boolean isRoot() {\n        return true;\n    }\n\n    public int getThreadId() {\n        return threadId;\n    }\n\n    protected TimedCPUCCTNode createSelfInstance() {\n        return new ThreadCPUCCTNode(threadId);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/cct/nodes/TimedCPUCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic abstract class TimedCPUCCTNode extends BaseCPUCCTNode implements Cloneable, RuntimeCPUCCTNode {\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int FILTERED_NO = 0;\n    public static final int FILTERED_YES = 2;\n    public static final int FILTERED_MAYBE = 1;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    // timing data\n    private long netTime0;\n    private long netTime1;\n    private long sleepTime0;\n    private long waitTime0;\n\n    private char filteredStatus;\n    private int nCalls;\n    private int nCallsDiff;\n    private long lastWaitOrSleepStamp;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public TimedCPUCCTNode() {\n        super();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Sets the \"filtered out\" status of the node\n     * @param status Use one of the following:\n     *               TimedCPUCCTNode.FILTERED_NO - if the node is not filtered out at all\n     *               TimedCPUCCTNode.FILTERED_YES - if the node is unconditionally filtered out\n     *               TimedCPUCCTNode.FILTERED_MAYBE - if the node might be filtered out, depending on other profiling settings\n     */\n    public synchronized void setFilteredStatus(int status) {\n        filteredStatus = (char) (status & 0xff);\n    }\n\n    //  public synchronized char getMarkID() {\n    //    return markId;\n    //  }\n    //\n    //  public synchronized void setMarkID(final char markId) {\n    //    this.markId = markId;\n    //  }\n\n    /**\n     * Returns the \"filtered out\" status of the node\n     * @return Returns one of the following values:\n     *         TimedCPUCCTNode.FILTERED_NO - if the node is not filtered out at all\n     *         TimedCPUCCTNode.FILTERED_YES - if the node is unconditionally filtered out\n     *         TimedCPUCCTNode.FILTERED_MAYBE - if the node might be filtered out, depending on other profiling settings\n     */\n    public synchronized int getFilteredStatus() {\n        return filteredStatus;\n    }\n\n    public synchronized void setLastWaitOrSleepStamp(final long time) {\n        lastWaitOrSleepStamp = time;\n    }\n\n    public synchronized long getLastWaitOrSleepStamp() {\n        return lastWaitOrSleepStamp;\n    }\n\n    public synchronized void setNCalls(final int calls) {\n        nCalls = calls;\n    }\n\n    public synchronized int getNCalls() {\n        return nCalls;\n    }\n\n    public synchronized void setNCallsDiff(final int calls) {\n        nCallsDiff = calls;\n    }\n\n    public synchronized int getNCallsDiff() {\n        return nCallsDiff;\n    }\n\n    public void setNetTime0(final long time) {\n        netTime0 = time;\n    }\n\n    public long getNetTime0() {\n        return netTime0;\n    }\n\n    public void setNetTime1(final long time) {\n        netTime1 = time;\n    }\n\n    public long getNetTime1() {\n        return netTime1;\n    }\n\n    public void setSleepTime0(final long time) {\n        sleepTime0 = time;\n    }\n\n    public long getSleepTime0() {\n        return sleepTime0;\n    }\n\n    public void setWaitTime0(final long time) {\n        waitTime0 = time;\n    }\n\n    public synchronized long getWaitTime0() {\n        return waitTime0;\n    }\n\n    public synchronized int addNCalls(final int calls) {\n        nCalls += calls;\n\n        return nCalls;\n    }\n\n    public synchronized int addNCallsDiff(final int calls) {\n        nCallsDiff += calls;\n\n        return nCallsDiff;\n    }\n\n    public long addNetTime0(final long time) {\n        netTime0 += time;\n        return netTime0;\n    }\n\n    public long addNetTime1(final long time) {\n        netTime1 += time;\n        return netTime1;\n    }\n\n    public long addSleepTime0(final long time) {\n        sleepTime0 += time;\n        return sleepTime0;\n    }\n\n    public long addWaitTime0(final long time) {\n        waitTime0 += time;\n        return waitTime0;\n    }\n\n    // @Override\n    public synchronized Object clone() {\n        TimedCPUCCTNode node = createSelfInstance();\n        node.setNCalls(getNCalls());\n        node.setNetTime0(getNetTime0());\n        node.setNetTime1(getNetTime1());\n        node.setSleepTime0(getSleepTime0());\n        node.setWaitTime0(getWaitTime0());\n        //    node.setMarkID(getMarkID());\n        node.setFilteredStatus(getFilteredStatus());\n        node.setNCallsDiff(0);\n\n        return node;\n    }\n\n    protected abstract TimedCPUCCTNode createSelfInstance();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/marking/MarkAwareNodeProcessorPlugin.java",
    "content": "/*\n * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.marking;\n\nimport java.util.ArrayDeque;\nimport java.util.Deque;\nimport org.graalvm.visualvm.lib.jfluid.global.TransactionalSupport;\nimport org.graalvm.visualvm.lib.jfluid.marker.Mark;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNodeProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MarkedCPUCCTNode;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class MarkAwareNodeProcessorPlugin extends RuntimeCCTNodeProcessor.PluginAdapter implements MarkingEngine.StateObserver {\n    volatile boolean resetFlag = false;\n    private Mark parentMark = null;\n    private Deque<Mark> markStack = new ArrayDeque<>();\n    private final TransactionalSupport transaction = new TransactionalSupport();\n\n    @Override\n    public void onBackout(MarkedCPUCCTNode node) {\n        markStack.pop();\n        parentMark = (Mark) (markStack.isEmpty() ? null : markStack.peek());\n    }\n\n    @Override\n    public void onNode(MarkedCPUCCTNode node) {\n        parentMark = (Mark) (markStack.isEmpty() ? null : markStack.peek());\n        markStack.push(node.getMark());\n    }\n\n    @Override\n    public void onStart() {\n        transaction.beginTrans(true);\n        parentMark = null;\n        resetFlag = false;\n    }\n\n    @Override\n    public void onStop() {\n        markStack.clear();\n        parentMark = null;\n        transaction.endTrans();\n    }\n\n    public void beginTrans(final boolean mutable) {\n        transaction.beginTrans(mutable);\n    }\n\n    public void endTrans() {\n        if (resetFlag) {\n            markStack.clear();\n            resetFlag = false;\n        }\n\n        transaction.endTrans();\n    }\n\n    public synchronized void onReset() {\n        resetFlag = true;\n        transaction.endTrans();\n    }\n\n    @Override\n    public void stateChanged(MarkingEngine instance) {\n        reset();\n    }\n\n    protected final Mark getCurrentMark() {\n        return (Mark) (markStack.isEmpty() ? Mark.DEFAULT : markStack.peek());\n    }\n\n    protected final Mark getParentMark() {\n        return (parentMark != null) ? parentMark : Mark.DEFAULT;\n    }\n\n    protected synchronized boolean isReset() {\n        return resetFlag;\n    }\n\n    private void reset() {\n        resetFlag = true;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/marking/MarkMapper.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.marking;\n\nimport org.graalvm.visualvm.lib.jfluid.marker.Mark;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport java.util.HashMap;\nimport java.util.Map;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\nclass MarkMapper implements MarkingEngine.StateObserver {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    // @GuardedBy marksGuard\n    private final Map markMap = new HashMap();\n    private final Object marksGuard = new Object();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Mark getMark(int methodId, ProfilingSessionStatus status) {\n        if (status == null) {\n            return Mark.DEFAULT;\n        }\n\n        synchronized (marksGuard) {\n            Mark mark = (Mark) markMap.get(Integer.valueOf(methodId));\n\n            if (mark == null) {\n                mark = MarkingEngine.getDefault().mark(methodId, status); // do mark the method\n                markMap.put(Integer.valueOf(methodId), mark);\n            }\n\n            return mark;\n        }\n    }\n\n    public void stateChanged(MarkingEngine instance) {\n        reset();\n    }\n\n    private void reset() {\n        synchronized (marksGuard) {\n            markMap.clear();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/marking/MarkMapping.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.marking;\n\nimport org.graalvm.visualvm.lib.jfluid.marker.Mark;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class MarkMapping {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    public final ClientUtils.SourceCodeSelection markMask;\n    public final Mark mark;\n    public final String markSig;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public MarkMapping(final ClientUtils.SourceCodeSelection markMask, final Mark mark) {\n        this.markMask = markMask;\n        this.mark = mark;\n        this.markSig = markMask.toFlattened();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/marking/MarkingEngine.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.cpu.marking;\n\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport org.graalvm.visualvm.lib.jfluid.marker.Mark;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport java.util.Iterator;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.marker.Marker;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class MarkingEngine {\n    private static String INVALID_MID = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.cpu.Bundle\").getString(\"MSG_INVALID_METHODID\"); // NOI18N\n\n    private static Logger LOGGER = Logger.getLogger(MarkingEngine.class.getName());\n\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    public static interface StateObserver {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        void stateChanged(MarkingEngine instance);\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static MarkingEngine instance;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final Object markGuard = new Object();\n\n    final private MarkMapper mapper;\n\n    // @GuardedBy markGuard\n    private MarkMapping[] marks;\n\n    private Set observers = new HashSet();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of MarkingEngine\n     */\n    private MarkingEngine() {\n        mapper = new MarkMapper();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static synchronized MarkingEngine getDefault() {\n        if (instance == null) {\n            instance = new MarkingEngine();\n        }\n\n        return instance;\n    }\n\n    // configure the engine for a given set of {@linkplain MarkMapping}\n    public synchronized void configure(MarkMapping[] mappings, Collection observers) {\n        setMarks(mappings != null ? mappings : Marker.DEFAULT.getMappings());\n        this.observers.clear();\n        this.observers.add( mapper );\n        this.observers.addAll(observers);\n    }\n\n    public synchronized void deconfigure() {\n        setMarks(Marker.DEFAULT.getMappings());\n    }\n\n    public ClientUtils.SourceCodeSelection[] getMarkerMethods() {\n        synchronized (markGuard) {\n            if (marks == null) {\n                return new ClientUtils.SourceCodeSelection[0];\n            }\n\n            ClientUtils.SourceCodeSelection[] methods = new ClientUtils.SourceCodeSelection[marks.length];\n\n            for (int i = 0; i < marks.length; i++) {\n                methods[i] = marks[i].markMask;\n            }\n\n            return methods;\n        }\n    }\n\n    public int getNMarks() {\n        synchronized (markGuard) {\n            return (marks != null) ? marks.length : 0;\n        }\n    }\n\n    public Mark markMethod(int methodId, ProfilingSessionStatus status) {\n        synchronized(mapper) {\n            return mapper.getMark(methodId, status);\n        }\n    }\n\n    Mark mark(int methodId, ProfilingSessionStatus status) {\n        ClientUtils.SourceCodeSelection method = null;\n\n        synchronized (markGuard) {\n            if (marks == null || marks.length == 0 || status == null) {\n                return Mark.DEFAULT;\n            }\n\n            status.beginTrans(false);\n\n            try {\n                String[] cNames = status.getInstrMethodClasses();\n                String[] mNames = status.getInstrMethodNames();\n                String[] sigs = status.getInstrMethodSignatures();\n                \n                if (mNames.length <= methodId || cNames.length <= methodId || sigs.length <= methodId) {\n                    int maxMid = Math.min(Math.min(mNames.length, cNames.length), sigs.length);\n                    LOGGER.log(Level.WARNING, INVALID_MID, new Object[]{methodId, maxMid});\n                } else {\n                    method = new ClientUtils.SourceCodeSelection(cNames[methodId],\n                                                                 mNames[methodId],\n                                                                 sigs[methodId]);\n                }\n            } finally {\n                status.endTrans();\n            }\n\n            if (method != null) {\n                String methodSig = method.toFlattened();\n\n                for (MarkMapping mark : marks) {\n                    if (methodSig.startsWith(mark.markSig)) {\n                        return mark.mark;\n                    }\n                }\n            }\n\n            return Mark.DEFAULT;\n        }\n    }\n\n    private void setMarks(MarkMapping[] marks) {\n        boolean stateChange = false;\n\n        synchronized (markGuard) {\n            stateChange = !Arrays.equals(this.marks,marks);\n            this.marks = marks;\n        }\n        if (stateChange) {\n            fireStateChanged();\n        }\n    }\n\n    private void fireStateChanged() {\n        for (Iterator iter = observers.iterator(); iter.hasNext();) {\n            ((StateObserver) iter.next()).stateChanged(this);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/jdbc/JdbcCCTProvider.java",
    "content": "/*\n * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.jdbc;\n\nimport org.graalvm.visualvm.lib.jfluid.results.CCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.RuntimeMemoryCCTNode;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic interface JdbcCCTProvider extends CCTProvider, FlatProfileProvider {\n    public static final int SQL_STATEMENT_UNKNOWN = -1;\n    public static final int SQL_STATEMENT = 0;\n    public static final int SQL_PREPARED_STATEMENT = 1;\n    public static final int SQL_CALLABLE_STATEMENT = 2;\n\n    public static final int SQL_COMMAND_BATCH = -2;\n    public static final int SQL_COMMAND_OTHER = -1;\n    public static final int SQL_COMMAND_ALTER = 0;\n    public static final int SQL_COMMAND_CREATE = 1;\n    public static final int SQL_COMMAND_DELETE = 2;\n    public static final int SQL_COMMAND_DESCRIBE = 3;\n    public static final int SQL_COMMAND_INSERT = 4;\n    public static final int SQL_COMMAND_SELECT = 5;\n    public static final int SQL_COMMAND_SET = 6;\n    public static final int SQL_COMMAND_UPDATE = 7;\n\n    public static final String STATEMENT_INTERFACE = java.sql.Statement.class.getName();\n    public static final String PREPARED_STATEMENT_INTERFACE = java.sql.PreparedStatement.class.getName();\n    public static final String CALLABLE_STATEMENT_INTERFACE = java.sql.CallableStatement.class.getName();\n    public static final String CONNECTION_INTERFACE = java.sql.Connection.class.getName();\n    public static final String DRIVER_INTERFACE = java.sql.Driver.class.getName();\n\n    public static interface Listener extends CCTProvider.Listener {\n    }\n\n    RuntimeMemoryCCTNode[] getStacksForSelects();\n    int getCommandType(int selectId);\n    int getSQLCommand(int selectId);\n    String[] getTables(int selectId);\n    void updateInternals();\n    void beginTrans(boolean mutable);\n    void endTrans();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/jdbc/JdbcGraphBuilder.java",
    "content": "/*\n * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.jdbc;\n\nimport java.io.IOException;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\nimport org.graalvm.visualvm.lib.jfluid.classfile.DynamicClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.filters.TextFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.BaseCallGraphBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNodeProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUProfilingResultListener;\nimport static org.graalvm.visualvm.lib.jfluid.results.cpu.CPUProfilingResultListener.METHODTYPE_MARKER;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainerFree;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.ThreadInfo;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.ThreadInfos;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.CCTFlattener;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MethodCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.RuntimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.SimpleCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.ThreadCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.TimedCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.JMethodIdTable;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.JMethodIdTable.JMethodIdTableEntry;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.RuntimeMemoryCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.RuntimeObjAllocTermCCTNode;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class JdbcGraphBuilder extends BaseCallGraphBuilder implements CPUProfilingResultListener, JdbcCCTProvider {\n\n    static final Logger JDBC_LOGGER = Logger.getLogger(JdbcGraphBuilder.class.getName());\n\n    private Map statements;\n    private Map connections;\n    private Map<Select,Integer> selectsToId;\n    private Map<Integer, Select> idsToSelect;\n    private Map<ThreadInfo, SQLStatement> currentObject;\n    private Map<ThreadInfo, Integer> currentSqlLevel;\n    private int lastSelectId;\n    private RuntimeMemoryCCTNode[] stacksForSelects; // [1- maxSelectId] selectId -> root of its allocation traces tree\n    final private ThreadInfos threadInfos = new ThreadInfos();\n    private final SQLParser sqlParser = new SQLParser();\n    private TextFilter filter;\n\n    @Override\n    protected RuntimeCCTNode getAppRootNode() {\n        if (threadInfos.isEmpty()) {\n            return null;\n        }\n\n        RuntimeCPUCCTNode appNode = null;\n\n        beginTrans(false);\n\n        try {\n            ProfilerClient client = getClient();\n            if (client != null) {\n                appNode = new SimpleCPUCCTNode(lastSelectId + 1);\n            } else {\n                appNode = new SimpleCPUCCTNode(true);\n            }\n\n            int len = (threadInfos.getThreadNames() != null) ? threadInfos.getThreadNames().length : 0;\n\n            for (int i = 0; i < len; i++) {\n                ThreadInfo ti = threadInfos.threadInfos[i];\n\n                if ((ti == null) || (ti.stack[0] == null)) {\n                    continue;\n                }\n\n                appNode.attachNodeAsChild(ti.stack[0]);\n            }\n        } finally {\n            endTrans();\n        }\n\n        return appNode;\n    }\n\n    public RuntimeMemoryCCTNode[] getStacksForSelects() {\n        beginTrans(false);\n\n        try {\n            return stacksForSelects;\n        } finally {\n            endTrans();\n        }\n    }\n\n    @Override\n    public FlatProfileContainer createFlatProfile() {\n        beginTrans(false);\n\n        try {\n            RuntimeCCTNode appNode = getAppRootNode();\n\n            if (appNode != null) {\n                CCTFlattener flattener = new JdbcCCTFlattener(getClient());\n\n                RuntimeCCTNodeProcessor.process(appNode, flattener);\n                return flattener.getFlatProfile();\n            }\n            return null;\n        } finally {\n            endTrans();\n        }\n    }\n\n    @Override\n    protected void doBatchStart() {\n        beginTrans(true);\n    }\n\n    @Override\n    protected void doBatchStop() {\n        endTrans();\n    }\n\n    @Override\n    protected void doReset() {\n        beginTrans(true);\n        try {\n            threadInfos.reset();\n            selectsToId.clear();\n            idsToSelect.clear();\n            currentObject.clear();\n            currentSqlLevel.clear();\n            lastSelectId = 0;\n            if (stacksForSelects != null) {\n                Arrays.fill(stacksForSelects, null);\n            }\n        } finally {\n            endTrans();\n        }\n    }\n\n    @Override\n    protected void doShutdown() {\n        statements = null;\n        connections = null;\n        selectsToId = null;\n        idsToSelect = null;\n        currentObject = null;\n        currentSqlLevel = null;\n        stacksForSelects = null;\n    }\n\n    @Override\n    protected void doStartup(ProfilerClient profilerClient) {\n        statements = new HashMap();\n        connections = new HashMap();\n        selectsToId = new HashMap();\n        idsToSelect = new HashMap();\n        currentObject = new HashMap();\n        currentSqlLevel = new HashMap();\n        threadInfos.reset();\n        stacksForSelects = null;\n        lastSelectId = 0;\n        profilerClient.registerJdbcCCTProvider(this);\n        InstrumentationFilter f = profilerClient.getSettings().getInstrumentationFilter();\n        filter = new TextFilter(f.getValue(), f.getType(), false);\n    }\n\n    @Override\n    public void profilingPoint(int threadId, int ppId, long timeStamp) {\n    }\n\n    @Override\n    public void methodEntry(int methodId, int threadId, int methodType, long timeStamp0, long timeStamp1, List parameters, int[] methoIds) {\n        if (methodType == METHODTYPE_MARKER) {\n            if (threadInfos.threadInfos == null) {\n                return;\n            }\n            ThreadInfo ti = threadInfos.threadInfos[threadId];\n            if (ti == null) {\n                return;\n            }\n            int sqlCallLevel = incrementSqlLevel(ti); \n            if (JDBC_LOGGER.isLoggable(Level.FINEST)) {\n                String className = status.getInstrMethodClasses()[methodId];\n                String methodName = status.getInstrMethodNames()[methodId];\n                JDBC_LOGGER.log(Level.FINEST, \"markerMethodEntry, mId = {0}, {1}.{2}{3}\", new Object[]{methodId, className, methodName, parameters.toString()});\n            }\n            if (sqlCallLevel > 1) {\n                if (ti.peek() instanceof MethodCPUCCTNode) {\n                    markerMethodEntry(-1, ti, timeStamp0, timeStamp1, true);\n                    batchNotEmpty = true;\n                }\n                return;\n            }\n            if (JDBC_LOGGER.isLoggable(Level.FINEST) && methoIds != null) {\n                debugStackTrace(methoIds);\n            }\n            if (hasThis(methodId)) {\n                String thisString = (String) parameters.get(0);\n                int index = thisString.indexOf('@');\n                String thisClass = thisString.substring(0, index);\n                String thisHash = thisString.substring(index + 1);\n\n                if (implementsInterface(thisClass, STATEMENT_INTERFACE)) {\n                    SQLStatement statement = (SQLStatement) statements.get(thisHash);\n                    String select;\n\n                    if (statement == null) {\n                        statement = new SQLStatement(SQL_STATEMENT_UNKNOWN);\n                        statements.put(thisHash, statement);\n                    }\n                    select = statement.invoke(status.getInstrMethodNames()[methodId], status.getInstrMethodSignatures()[methodId], parameters);\n                    if (select != null && filter.passes(select)) {\n                        int selectId = getSelectId(statement.getType(), select);\n                        markerMethodEntry(selectId, ti, timeStamp0, timeStamp1, true);\n                        RuntimeObjAllocTermCCTNode term = (RuntimeObjAllocTermCCTNode) processStackTrace(selectId, methoIds);\n                        if (term != null) {\n                            term.updateForNewObject(0);\n                        }\n                        batchNotEmpty = true;\n                    }\n                }\n                if (implementsInterface(thisClass, CONNECTION_INTERFACE)) {\n                    SQLConnection connection = (SQLConnection) connections.get(thisHash);\n                    if (connection == null) {\n                        connection = new SQLConnection();\n                        connections.put(thisHash, connection);\n                    }\n                    connection.invoke(status.getInstrMethodNames()[methodId], status.getInstrMethodSignatures()[methodId], parameters);\n                    assert currentObject.get(ti) == null;\n                    currentObject.put(ti, connection.useCurrentStatement());\n                }\n            }\n        }\n    }\n\n    @Override\n    public void methodEntryUnstamped(int methodId, int threadId, int methodType, List parameters, int[] methoIds) {\n    }\n\n    @Override\n    public void methodExit(int methodId, int threadId, int methodType, long timeStamp0, long timeStamp1, Object retVal) {\n        if (methodType == METHODTYPE_MARKER) {\n            if (status == null || (threadInfos.threadInfos == null)) {\n                return;\n            }\n\n            ThreadInfo ti = threadInfos.threadInfos[threadId];\n\n            if (ti == null) {\n                return;\n            }\n            int sqlCallLevel = decrementSqlLevel(ti);\n\n            plainMethodExit(methodId, ti, timeStamp0, timeStamp1, true);\n            if (sqlCallLevel == 0) {\n                SQLStatement st = currentObject.get(ti);\n                \n                if (st != null && retVal instanceof String) {\n                    String thisString = (String) retVal;\n                    int index = thisString.indexOf('@');\n                    String thisClass = thisString.substring(0, index);\n                    String thisHash = thisString.substring(index + 1);\n                    if (implementsInterface(thisClass, STATEMENT_INTERFACE)) {\n                        assert st != null;\n                        statements.put(thisHash, st);\n                    }\n                }\n                currentObject.remove(ti);\n            }\n            batchNotEmpty = true;\n        }\n    }\n\n    @Override\n    public void methodExitUnstamped(int methodId, int threadId, int methodType) {\n    }\n\n    @Override\n    public void servletRequest(int threadId, int requestType, String servletPath, int sessionId) {\n    }\n\n    @Override\n    public void sleepEntry(int threadId, long timeStamp0, long timeStamp1) {\n    }\n\n    @Override\n    public void sleepExit(int threadId, long timeStamp0, long timeStamp1) {\n    }\n\n    @Override\n    public void threadsResume(long timeStamp0, long timeStamp1) {\n    }\n\n    @Override\n    public void threadsSuspend(long timeStamp0, long timeStamp1) {\n    }\n\n    @Override\n    public void waitEntry(int threadId, long timeStamp0, long timeStamp1) {\n    }\n\n    @Override\n    public void waitExit(int threadId, long timeStamp0, long timeStamp1) {\n    }\n\n    @Override\n    public void parkEntry(int threadId, long timeStamp0, long timeStamp1) {\n    }\n\n    @Override\n    public void parkExit(int threadId, long timeStamp0, long timeStamp1) {\n    }\n\n    @Override\n    public void monitorEntry(int threadId, long timeStamp0, long timeStamp1, int monitorId, int ownerThreadId) {\n    }\n\n    @Override\n    public void monitorExit(int threadId, long timeStamp0, long timeStamp1, int monitorId) {\n    }\n\n    @Override\n    public void newThread(int threadId, String threadName, String threadClassName) {\n        if (status == null) {\n            return;\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"New thread creation for thread id = {0}, name = {1}\", new Object[]{threadId, threadName});\n        }\n\n        threadInfos.newThreadInfo(threadId, threadName, threadClassName);\n    }\n\n    @Override\n    public void newMonitor(int hash, String className) {\n    }\n\n    @Override\n    /**\n     * Called when the TA is suspended waiting for the tool to process the\n     * buffer\n     */\n    public void timeAdjust(final int threadId, final long timeDiff0, final long timeDiff1) {\n        if (status == null || (threadInfos.threadInfos == null)) {\n            return;\n        }\n\n        ThreadInfo ti = threadInfos.threadInfos[threadId];\n\n        // In this case, time stamps are actually time adjustments.\n        // timeStamp0 is always abosolute and timeStamp1 is always thread CPU.\n        ti.rootMethodEntryTimeAbs += timeDiff0;\n        ti.rootMethodEntryTimeThreadCPU += timeDiff1;\n        ti.topMethodEntryTime0 += timeDiff0;\n\n        if (isCollectingTwoTimeStamps()) {\n            ti.topMethodEntryTime1 += timeDiff1;\n        }\n    }\n\n    private boolean hasThis(int methodId) {\n        String methodName = status.getInstrMethodNames()[methodId];\n        if (methodName.equals(\"<init>\")) {\n            return false;\n        }\n        String className = status.getInstrMethodClasses()[methodId];\n        String signature = status.getInstrMethodSignatures()[methodId];\n        int classLoaderId = status.getClassLoaderIds()[methodId];\n\n        try {\n            ClassRepository classRepo = getClient().getClassRepository();\n            ClassInfo clazz = classRepo.lookupClass(className, classLoaderId);\n            int methodIdx = clazz.getMethodIndex(methodName, signature);\n            return !clazz.isMethodStatic(methodIdx);\n        } catch (IOException ex) {\n            Logger.getLogger(JdbcGraphBuilder.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (ClassFormatError ex) {\n            Logger.getLogger(JdbcGraphBuilder.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        return false;\n    }\n\n    private boolean implementsInterface(String thisClass, String STATEMENT_INTERFACE) {\n        try {\n            String slashedClass = thisClass.replace('.', '/');  // NOI18N\n            ClassRepository classRepo = getClient().getClassRepository();\n            DynamicClassInfo clazz = classRepo.lookupClass(STATEMENT_INTERFACE, 0);\n            if (clazz != null) {\n                List subclasses = clazz.getSubclasses();\n\n                if (subclasses != null) {\n                    for (int i = 0; i < subclasses.size(); i++) {\n                        DynamicClassInfo subclass = (DynamicClassInfo) subclasses.get(i);\n\n                        if (subclass.getName().equals(slashedClass)) {\n                            return true;\n                        }\n                    }\n                }\n            }\n            return false;\n        } catch (IOException ex) {\n            Logger.getLogger(JdbcGraphBuilder.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (ClassFormatError ex) {\n            Logger.getLogger(JdbcGraphBuilder.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        return false;\n    }\n\n    private int getSelectId(int type, String select) {\n        Select sel = new Select(type, select);\n        \n        Integer selectId = selectsToId.get(sel);\n        if (selectId == null) {\n            selectId = Integer.valueOf(++lastSelectId);\n            sel.setCommandType(extractSQLCommandType(select));\n            sel.setTables(extractTables(select));\n            selectsToId.put(sel, selectId);\n            idsToSelect.put(selectId, sel);\n            updateNumberOfSelects();\n        }\n        return selectId.intValue();\n    }\n\n    private boolean isCollectingTwoTimeStamps() {\n        return status.collectingTwoTimeStamps();\n    }\n\n    private TimedCPUCCTNode markerMethodEntry(final int selectId, final ThreadInfo ti, long timeStamp0, long timeStamp1,\n            boolean stamped) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"MarkerMEntry{0} for tId = {1}, time: {2}, method:  {3}, inRoot: {4}, rootEntryTimeThread: {5}\", new Object[]{(!stamped) ? \"(unstamped)\" : \"\", (int) ti.threadId, timeStamp0, debugSelect(selectId), ti.rootMethodEntryTimeAbs, ti.rootMethodEntryTimeThreadCPU});\n        }\n\n        TimedCPUCCTNode curNode = ti.peek();\n\n        if (curNode == null) {\n            TimedCPUCCTNode rootNode = new ThreadCPUCCTNode(ti.threadId);\n            ti.totalNNodes++;\n            ti.push(rootNode);\n            ti.totalNInv--;\n\n            curNode = new MethodCPUCCTNode(selectId);\n            rootNode.attachNodeAsChild(curNode);\n            ti.totalNNodes++;\n            ti.push(curNode);\n\n            ti.topMethodEntryTime0 = timeStamp0;\n\n            if (isCollectingTwoTimeStamps()) {\n                ti.topMethodEntryTime1 = timeStamp1;\n            }\n        } else {\n            if (stamped) {\n                long diff = timeStamp0 - ti.topMethodEntryTime0;\n\n                if (diff > 0) {\n                    curNode.addNetTime0(diff);\n                } else {\n                    timeStamp0 = ti.topMethodEntryTime0;\n                }\n\n                ti.topMethodEntryTime0 = timeStamp0;\n\n                if (isCollectingTwoTimeStamps()) {\n                    diff = timeStamp1 - ti.topMethodEntryTime1;\n\n                    if (diff > 0) {\n                        curNode.addNetTime1(diff);\n                    } else {\n                        timeStamp1 = ti.topMethodEntryTime1;\n                    }\n\n                    ti.topMethodEntryTime1 = timeStamp1;\n                }\n            }\n\n            TimedCPUCCTNode calleeNode;\n\n            // Now find the appropriate callee in this node or create one\n            calleeNode = MethodCPUCCTNode.Locator.locate(selectId, curNode.getChildren());\n\n            if (calleeNode == null) {\n                calleeNode = new MethodCPUCCTNode(selectId);\n                curNode.attachNodeAsChild(calleeNode);\n                ti.totalNNodes++;\n            }\n\n            ti.push(calleeNode);\n            curNode = calleeNode; // make the callee node be the current one\n        }\n\n        if (selectId == -1) {\n            curNode.setFilteredStatus(TimedCPUCCTNode.FILTERED_YES);\n        }\n\n        if (stamped) { // stamped marker method called before any root method; must set rootMethodEntryTimes\n            // Be careful - with MARKER_ENTRY and MARKER_EXIT events, unlike with others, timeStamp0 is *always* absolute time,\n            // and timeStamp1 is *always* thread CPU time\n            ti.rootMethodEntryTimeAbs = timeStamp0;\n            ti.rootMethodEntryTimeThreadCPU = timeStamp1;\n            ti.topMethodEntryTime0 = timeStamp0;\n\n            if (isCollectingTwoTimeStamps()) {\n                ti.topMethodEntryTime1 = timeStamp1;\n            }\n        }\n        return curNode;\n    }\n\n    private TimedCPUCCTNode plainMethodExit(final int methodId, final ThreadInfo ti, long timeStamp0, long timeStamp1,\n            boolean stamped) {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"MethodExit  {0}: for tId = {1}, time: {2}, method:  {3}\", new Object[]{(!stamped) ? \"(unstamped)\" : \"\", ti.threadId, timeStamp0, methodId});\n        }\n\n        TimedCPUCCTNode curNode = ti.peek();\n\n        if (!(curNode instanceof MethodCPUCCTNode)) {\n            return null;\n        }\n\n        // Timer's coarse granularities etc. may occasionally cause this issue. FIXME: maybe need a warning, though not\n        // every time this happens, but probably rather in the end of run, so that the problem could then be investigated.\n        if (stamped) {\n            long diff = timeStamp0 - ti.topMethodEntryTime0;\n\n            if (diff > 0) {\n                curNode.addNetTime0(diff);\n            } else {\n                timeStamp0 = ti.topMethodEntryTime0;\n            }\n\n            if (isCollectingTwoTimeStamps()) {\n                diff = timeStamp1 - ti.topMethodEntryTime1;\n\n                if (diff > 0) {\n                    curNode.addNetTime1(diff);\n                } else {\n                    timeStamp1 = ti.topMethodEntryTime1;\n                }\n            }\n        }\n\n        TimedCPUCCTNode oldNode = ti.pop();\n\n        //    if ((ti.stackTopIdx < 0 || ti.stack[ti.stackTopIdx].getMethodId() == 0) && checkStack) {\n        //      System.err.println(ENGINE_WARNING + \"critical: stack state on methodExit is like at rootMethodExit\"); // NOI18N\n        //      System.err.println(PLEASE_REPORT_PROBLEM);\n        //    }\n        // Resume the net time for the caller\n        if (stamped) {\n            ti.topMethodEntryTime0 = timeStamp0;\n\n            if (isCollectingTwoTimeStamps()) {\n                ti.topMethodEntryTime1 = timeStamp1;\n            }\n        }\n\n        return oldNode;\n    }\n\n    /**\n     * Given the selectId and the array of methodIds of the stack trace for the\n     * newly invoked select, update the reverse Calling Context Tree for this\n     * select. Adds new nodes and/or increases allocated object counters/size in\n     * nodes. Returns the terminating node in the resulting CCT branch.\n     */\n    private RuntimeMemoryCCTNode processStackTrace(int selectId, int[] methodIds) {\n        if (selectId >= stacksForSelects.length) {\n            LOGGER.severe(\"Received stack for non existent select Id: \" + (int) selectId + \", current length: \" + stacksForSelects.length); // NOI18N\n            return null;\n        }\n\n        RuntimeMemoryCCTNode curNode = stacksForSelects[selectId];\n        RuntimeMemoryCCTNode parentNode = null;\n\n        if (curNode == null) {\n            curNode = new RuntimeMemoryCCTNode(0);\n            stacksForSelects[selectId] = curNode;\n        }\n\n        int depth = methodIds.length;\n        int depthMinusOne = depth - 1;\n\n        for (int i = 0; i < depth; i++) {\n            int methodId = methodIds[i];\n            parentNode = curNode;\n\n            Object children = curNode.children;\n\n            boolean found = false;\n\n            if (children != null) {\n                if (children instanceof RuntimeMemoryCCTNode) {\n                    if (((RuntimeMemoryCCTNode) children).methodId == methodId) {\n                        curNode = (RuntimeMemoryCCTNode) children;\n                        found = true;\n                    }\n                } else {\n                    RuntimeMemoryCCTNode[] ar = (RuntimeMemoryCCTNode[]) children;\n\n                    for (RuntimeMemoryCCTNode ar1 : ar) {\n                        if (ar1.methodId == methodId) {\n                            curNode = ar1;\n                            found = true;\n\n                            break;\n                        }\n                    }\n                }\n            }\n\n            if (!found) {\n                // Appropriate subnode not found or there are no subnodes yet - create one.\n                if (i < depthMinusOne) {\n                    curNode = curNode.addNewChild(methodId); // Non-terminal node\n                } else { // Terminal node - need to create a specialized one depending on the profiling type (obj alloc or obj liveness)\n\n                    RuntimeMemoryCCTNode newNode = new RuntimeObjAllocTermCCTNode(methodId);\n                    curNode.attachNodeAsChild(newNode);\n                    curNode = newNode;\n                }\n            }\n        }\n\n        // Now check if the curNode that we are going to return is actually not an instance of one of classes representing\n        // \"terminal nodes\", like RuntimeObjAllocTermCCTNode or RuntimeObjLivenessTermCCTNode. Such nodes contain information\n        // that is normally the same for the whole call chain - such as total number/size of objects of the given type allocated\n        // by this call chain. However, it looks like in some cases (different threads?) it may happen that one complete call\n        // chain may become a fragment of another, longer call chain. In that case we will neeed to have a \"terminal\" node in the middle\n        // of the chain. Here we are checking for the case when first a longer chain is created, and then a shorter one that\n        // matches a part of the longer one is found, and taking measures.\n        if (curNode.getClass() == RuntimeMemoryCCTNode.class) {\n            RuntimeMemoryCCTNode newNode = new RuntimeObjAllocTermCCTNode(curNode.methodId);\n            newNode.children = curNode.children;\n\n            if (parentNode != null) {\n                Object parChildren = parentNode.children;\n                assert (parChildren != null); // parent will always have chilren\n\n                if (parChildren instanceof RuntimeMemoryCCTNode) {\n                    if (parChildren == curNode) {\n                        parentNode.children = newNode;\n                    }\n                } else {\n                    RuntimeMemoryCCTNode[] ar = (RuntimeMemoryCCTNode[]) parChildren;\n\n                    for (int i = 0; i < ar.length; i++) {\n                        if (ar[i] == curNode) {\n                            ar[i] = newNode;\n\n                            break;\n                        }\n                    }\n                }\n            } else {\n                stacksForSelects[selectId] = newNode;\n            }\n\n            curNode = newNode;\n        }\n\n        return curNode;\n    }\n\n    private void updateNumberOfSelects() {\n        int nProfiledSelects = lastSelectId + 1;\n\n        if ((stacksForSelects == null) || (stacksForSelects.length <= nProfiledSelects)) {\n            int newSize = (nProfiledSelects * 3) / 2;\n            RuntimeMemoryCCTNode[] newStacks = new RuntimeMemoryCCTNode[newSize];\n\n            if (stacksForSelects != null) {\n                System.arraycopy(stacksForSelects, 0, newStacks, 0, stacksForSelects.length);\n            }\n            stacksForSelects = newStacks;\n        }\n    }\n\n    private String debugSelect(int selectId) {\n        if (selectId == -1) {\n            return \"-1\";\n        }\n        Select sel = idsToSelect.get(Integer.valueOf(selectId));\n        if (sel == null) {\n            return \"Null select for SelectId \" + selectId;\n        }\n        return sel.getSelect();\n    }\n\n    private void debugStackTrace(int[] methoIds) {\n        JMethodIdTable table = getClient().getJMethodIdTable();\n        for (int i = 0; i < methoIds.length; i++) {\n            table.checkMethodId(methoIds[i]);\n        }\n        try {\n            table.getNamesForMethodIds(getClient());\n            for (int i = 0; i < methoIds.length; i++) {\n                JMethodIdTableEntry en = table.getEntry(methoIds[i]);\n                JDBC_LOGGER.log(Level.FINEST, \"{0}.{1}\", new Object[]{en.className, en.methodName});\n            }\n        } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n            Logger.getLogger(JdbcGraphBuilder.class.getName()).log(Level.SEVERE, null, ex);\n        }\n    }\n\n    int extractSQLCommandType(String sql) {\n        return sqlParser.extractSQLCommandType(sql);\n    }\n    \n    String[] extractTables(String sql) {\n        return sqlParser.extractTables(sql);\n    }\n    \n    @Override\n    public void beginTrans(boolean mutable) {\n        threadInfos.beginTrans(mutable);\n    }\n\n    @Override\n    public void endTrans() {\n        threadInfos.endTrans();\n    }\n\n    @Override\n    public void updateInternals() {\n        final ProfilerClient client = getClient();\n        if (client != null) {\n            synchronized (client) {\n                beginTrans(false);\n\n                try {\n                    PresoObjAllocCCTNode.getNamesForMethodIdsFromVM(client, stacksForSelects);\n                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                    ProfilerLogger.log(ex.getMessage());\n                    /* No longer ignore silently */\n                } finally {\n                    endTrans();\n                }\n            }\n        }\n    }\n\n    @Override\n    public int getCommandType(int selectId) {\n        Select sel = idsToSelect.get(Integer.valueOf(selectId));\n        if (sel != null) {\n            return sel.getType();\n        }\n        return JdbcCCTProvider.SQL_STATEMENT_UNKNOWN;\n    }\n\n    @Override\n    public int getSQLCommand(int selectId) {\n        Select sel = idsToSelect.get(Integer.valueOf(selectId));\n        if (sel != null) {\n            return sel.getCommandType();\n        }\n        return JdbcCCTProvider.SQL_COMMAND_OTHER;\n    }\n\n    @Override\n    public String[] getTables(int selectId) {\n        Select sel = idsToSelect.get(Integer.valueOf(selectId));\n        if (sel != null) {\n            return sel.getTables();\n        }\n        return new String[0];\n    }\n\n    private int incrementSqlLevel(ThreadInfo ti) {\n        Integer sqlLevel = currentSqlLevel.get(ti);\n        if (sqlLevel == null) {\n            sqlLevel = Integer.valueOf(1);\n        } else {\n            sqlLevel = Integer.valueOf(sqlLevel.intValue()+1);\n        }\n        currentSqlLevel.put(ti, sqlLevel);\n        return sqlLevel.intValue();\n    }\n\n    private int decrementSqlLevel(ThreadInfo ti) {\n        Integer sqlLevel = currentSqlLevel.get(ti);\n\n        assert sqlLevel != null;\n        sqlLevel = Integer.valueOf(sqlLevel.intValue()-1);\n        currentSqlLevel.put(ti, sqlLevel);\n        return sqlLevel.intValue();\n    }\n\n\n    private class JdbcCCTFlattener extends CCTFlattener {\n\n        JdbcCCTFlattener(ProfilerClient client) {\n            super(client, null);\n        }\n\n        @Override\n        protected int getMaxMethodId() {\n            return lastSelectId + 1;\n        }\n\n        @Override\n        protected String getInstrMethodClass(int selectId) {\n            Select sel = idsToSelect.get(Integer.valueOf(selectId));\n            if (sel == null) {\n                return \"Unknown select for selectId \" + selectId;\n            }\n            return sel.getSelect();\n        }\n\n        @Override\n        protected String getInstrMethodName(int nodeMethodId) {\n            return \"\";\n        }\n\n        @Override\n        protected FlatProfileContainer createContainer(long[] timeInMcs0, long[] timeInMcs1, long[] totalTimeInMcs0, long[] totalTimeInMcs1, int[] nInvocations, double wholeGraphNetTime0, double wholeGraphNetTime1) {\n            return new JdbcFlatProfileContainer(timeInMcs0, timeInMcs1, totalTimeInMcs0, totalTimeInMcs1, nInvocations, wholeGraphNetTime0, wholeGraphNetTime1);\n        }\n    }\n    \n    private class JdbcFlatProfileContainer extends FlatProfileContainerFree {\n        \n        private JdbcFlatProfileContainer(long[] timeInMcs0, long[] timeInMcs1, long[] totalTimeInMcs0, long[] totalTimeInMcs1, int[] nInvocations, double wholeGraphNetTime0, double wholeGraphNetTime1) {\n            super(getClient().getStatus(), timeInMcs0, timeInMcs1, totalTimeInMcs0, totalTimeInMcs1, nInvocations, new char[0], wholeGraphNetTime0, wholeGraphNetTime1, nInvocations.length);\n        }\n\n        @Override\n        public String getMethodNameAtRow(int row) {\n            int selectId = getMethodIdAtRow(row);\n            return idsToSelect.get(Integer.valueOf(selectId)).getSelect();\n        }\n        \n    }\n    \n    private static class Select {\n        private final int type;\n        private  int commandType;\n        private final String select;\n        private String[] tables;\n        \n        Select(int t, String s) {\n            type = t;\n            select = s;\n        }\n\n        private int getType() {\n            return type;\n        }\n\n        private void setCommandType(int ct) {\n            commandType = ct;\n        }\n\n        private void setTables(String[] t) {\n            tables = t;\n        }\n\n        private int getCommandType() {\n            return commandType;\n        }\n\n        public String[] getTables() {\n            return tables;\n        }\n\n        private String getSelect() {\n            return select;\n        }\n\n        @Override\n        public int hashCode() {\n            return type ^ select.hashCode();\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (this == obj) {\n                return true;\n            }\n            if (obj == null) {\n                return false;\n            }\n            if (getClass() != obj.getClass()) {\n                return false;\n            }\n            final Select other = (Select) obj;\n            if (this.type != other.type) {\n                return false;\n            }\n            if (!Objects.equals(this.select, other.select)) {\n                return false;\n            }\n            return true;\n        }\n        \n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/jdbc/JdbcResultsDiff.java",
    "content": "/*\n * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.jdbc;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.DiffObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.JMethodIdTable;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.RuntimeMemoryCCTNode;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class JdbcResultsDiff extends JdbcResultsSnapshot {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final JdbcResultsSnapshot snapshot1;\n    private final JdbcResultsSnapshot snapshot2;\n\n    private Map selectIdToSnapshot1;\n    private Map selectIdToSnapshot2;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public JdbcResultsDiff(JdbcResultsSnapshot snapshot1, JdbcResultsSnapshot snapshot2) {\n        this.snapshot1 = snapshot1;\n        this.snapshot2 = snapshot2;\n\n        computeDiff(snapshot1, snapshot2);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    public long getBeginTime() {\n        return -1;\n    }\n\n    @Override\n    public JMethodIdTable getJMethodIdTable() {\n        return null;\n    }\n\n    @Override\n    public long getTimeTaken() {\n        return -1;\n    }\n\n    @Override\n    public boolean containsStacks() {\n        return snapshot1.containsStacks() && snapshot2.containsStacks();\n    }\n\n    @Override\n    public PresoObjAllocCCTNode createPresentationCCT(int selectId, boolean dontShowZeroLiveObjAllocPaths) {\n        int selectId1 = selectId1(selectId);\n        int selectId2 = selectId2(selectId);\n        PresoObjAllocCCTNode node1 = null;\n        PresoObjAllocCCTNode node2 = null;\n        \n        if (selectId1 != -1) {\n            node1 = snapshot1.createPresentationCCT(selectId1, dontShowZeroLiveObjAllocPaths);\n        }\n        if (selectId2 != -1) {\n            node2 = snapshot2.createPresentationCCT(selectId2, dontShowZeroLiveObjAllocPaths);\n        }\n        return new DiffObjAllocCCTNode(node1, node2);\n    }\n\n    @Override\n    public void readFromStream(DataInputStream in) throws IOException {\n        throw new UnsupportedOperationException(\"Persistence not supported for snapshot comparison\"); // NOI18N\n    }\n\n    //---- Serialization support\n    @Override\n    public void writeToStream(DataOutputStream out) throws IOException {\n        throw new UnsupportedOperationException(\"Persistence not supported for snapshot comparison\"); // NOI18N\n    }\n\n    @Override\n    protected PresoObjAllocCCTNode createPresentationCCT(RuntimeMemoryCCTNode rootNode, int classId,\n                                                         boolean dontShowZeroLiveObjAllocPaths) {\n        int selectId1 = selectId1(classId);\n        int selectId2 = selectId2(classId);\n        PresoObjAllocCCTNode node1 = null;\n        PresoObjAllocCCTNode node2 = null;\n\n        if (selectId1 != -1) {\n            node1 = snapshot1.createPresentationCCT(rootNode, selectId1, dontShowZeroLiveObjAllocPaths);\n        }\n        if (selectId2 != -1) {\n            node2 = snapshot2.createPresentationCCT(rootNode, selectId2, dontShowZeroLiveObjAllocPaths);\n        }\n        return new DiffObjAllocCCTNode(node1, node2);\n    }\n    \n    private int selectId1(int selectId) {\n        Integer id = (Integer) selectIdToSnapshot1.get(selectId);\n        if (id != null) {\n            return id.intValue();\n        }\n        return -1;\n    }\n    \n    private int selectId2(int selectId) {\n        Integer id = (Integer) selectIdToSnapshot2.get(selectId);\n        if (id != null) {\n            return id.intValue();\n        }\n        return -1;\n    }\n\n    private void computeDiff(JdbcResultsSnapshot snapshot1, JdbcResultsSnapshot snapshot2) {\n        int s1nSelects = snapshot1.getNProfiledSelects();\n        int s2nSelects = snapshot2.getNProfiledSelects();\n\n        // temporary cache for creating diff\n        HashMap<String, Integer> selectsNamesIdxMap = new HashMap(s1nSelects);\n        ArrayList<String> selectsArr = new ArrayList(s1nSelects);\n        ArrayList<Long> invocationsArr = new ArrayList(s1nSelects);\n        ArrayList<Long> timesArr = new ArrayList(s1nSelects);\n        ArrayList<Integer> commandsArr = new ArrayList(s1nSelects);\n        ArrayList<String[]> tablesArr = new ArrayList(s1nSelects);\n        ArrayList<Integer> typesArr = new ArrayList(s1nSelects);\n\n        // fill the cache with negative values from snapshot1\n        String[] s1SelectNames = snapshot1.getSelectNames();\n        long[] s1Invocations = snapshot1.getInvocationsPerSelectId();\n        long[] s1Times = snapshot1.getTimePerSelectId();\n        int[] s1Types = snapshot1.getTypeForSelectId();\n        int[] s1Commands = snapshot1.getCommandTypeForSelectId();\n        String[][] s1Tables = snapshot1.getTablesForSelectId();\n\n        selectIdToSnapshot1 = new HashMap(s1nSelects);\n        for (int i = 0; i < s1nSelects; i++) {\n            String selectId = s1SelectNames[i]+Integer.toString(s1Types[i]);\n\n            selectsNamesIdxMap.put(selectId, i);\n            selectIdToSnapshot1.put(i, i);\n            selectsArr.add(s1SelectNames[i]);\n            invocationsArr.add( - s1Invocations[i]);\n            timesArr.add(- s1Times[i]);\n            commandsArr.add(s1Commands[i]);\n            tablesArr.add(s1Tables[i]);\n            typesArr.add(s1Types[i]);\n        }\n\n        // create diff using values from snapshot2\n        String[] s2SelectNames = snapshot2.getSelectNames();\n        long[] s2Invocations = snapshot2.getInvocationsPerSelectId();\n        long[] s2Times = snapshot2.getTimePerSelectId();\n        int[] s2Types = snapshot2.getTypeForSelectId();\n        int[] s2Commands = snapshot2.getCommandTypeForSelectId();\n        String[][] s2Tables = snapshot2.getTablesForSelectId();\n\n        selectIdToSnapshot2 = new HashMap(s2nSelects);\n        for (int i = 1; i < s2nSelects; i++) {\n            String selectId = s2SelectNames[i]+Integer.toString(s2Types[i]);\n            Integer selectIdx = selectsNamesIdxMap.get(selectId);\n\n            if (selectIdx != null) {\n                // select already present in snapshot1\n                invocationsArr.set(selectIdx, - s1Invocations[selectIdx] + s2Invocations[i]);\n                timesArr.set(selectIdx, - s1Times[selectIdx] + s2Times[i]);\n                selectIdToSnapshot2.put(selectIdx, i);\n            } else {\n                // select not present in snapshot1\n                selectsNamesIdxMap.put(selectId, selectsArr.size());\n                selectIdToSnapshot2.put(selectsArr.size(), i);\n                selectsArr.add(s2SelectNames[i]);\n                invocationsArr.add(s2Invocations[i]);\n                timesArr.add(s2Times[i]);\n                commandsArr.add(s2Commands[i]);\n                tablesArr.add(s2Tables[i]);\n                typesArr.add(s2Types[i]);\n            }\n        }\n\n        // move the diff to instance variables\n        nProfiledSelects = selectsNamesIdxMap.size();\n        selectNames = new String[nProfiledSelects];\n        invocationsPerSelectId = new long[nProfiledSelects];\n        timePerSelectId = new long[nProfiledSelects];\n        commandTypeForSelectId = new int[nProfiledSelects];\n        tablesForSelectId = new String[nProfiledSelects][];\n        typeForSelectId = new int[nProfiledSelects];\n\n        for (int index = 1; index < selectsArr.size(); index++) {\n            selectNames[index] = selectsArr.get(index);\n            invocationsPerSelectId[index] = invocationsArr.get(index);\n            timePerSelectId[index] = timesArr.get(index);\n            commandTypeForSelectId[index] = commandsArr.get(index);\n            tablesForSelectId[index] = tablesArr.get(index);\n            typeForSelectId[index] = typesArr.get(index);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/jdbc/JdbcResultsSnapshot.java",
    "content": "/*\n * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.jdbc;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Stack;\nimport java.util.logging.Level;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.FilterSortSupport;\nimport org.graalvm.visualvm.lib.jfluid.results.ResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.JMethodIdTable;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.RuntimeMemoryCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.RuntimeObjAllocTermCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.RuntimeObjLivenessTermCCTNode;\n\n/**\n * Results snapshot for Jdbc (selects) Profiling.\n *\n * @author Tomas Hurka\n */\npublic class JdbcResultsSnapshot extends ResultsSnapshot {\n   /***************************************************************************\n    +------------------------------------------------------------------------------+\n    | Profiler memory snapshot format description                                  |\n    +------------------------------------------------------------------------------+\n    int         version\n    long        timestamp\n    long        duration\n    int         # profiled selects\n    ===> for(# profiled selects)\n    string      select\n    long        #number of invocations\n    <===\n    boolean     contains stacktraces\n    int         # stacktraces\n    ===> for(# stacktraces)\n    :::> load node\n    int         type (RuntimeMemoryCCTNode.TYPE_RuntimeMemoryCCTNode,\n                      RuntimeMemoryCCTNode.TYPE_RuntimeObjAllocTermCCTNode,\n                      RuntimeMemoryCCTNode.RuntimeObjLivenessTermCCTNode)\n    int         methodId\n    int         # children\n    ======> for(# children)\n    >load node<\n    <=====\n    <::: load node\n    <===\n    ***************************************************************************/\n    \n    private JMethodIdTable table;\n    /** [0-nProfiledSelects] select names */\n    String[] selectNames;\n\n    /** [1-nProfiledSelects] total number of invocations for select */\n    long[] invocationsPerSelectId;\n\n    /** [1-nProfiledSelects] total time for select */\n    long[] timePerSelectId;\n\n    /** [1-nProfiledSelects] select type see JdbcCCTProvider.SQL* constants */\n    int[] typeForSelectId;\n\n    /** [1-nProfiledSelects] command type see JdbcCCTProvider.SQL_COMMAND* constants */\n    int[] commandTypeForSelectId;\n\n    /** [1-nProfiledSelects] array of  SQL tables affected by selectId */\n    String[][] tablesForSelectId;\n\n    /** [1-nProfiledSelects] select Id -> root of its allocation traces tree */\n    private RuntimeMemoryCCTNode[] stacksForSelects;\n\n    /** total number of profiled selects */\n    int nProfiledSelects;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public JdbcResultsSnapshot() { // No-arg constructor needed for above serialization methods to work\n    } \n\n    public JdbcResultsSnapshot(long beginTime, long timeTaken, JdbcCCTProvider provider, ProfilerClient client)\n                          throws ClientUtils.TargetAppOrVMTerminated {\n        super(beginTime, timeTaken);\n\n        provider.beginTrans(false);\n\n        try {\n            performInit(client, provider);           \n        } finally {\n            provider.endTrans();\n\n            if (LOGGER.isLoggable(Level.FINEST)) {\n                debugValues();\n            }\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getSelectName(int selectId) {\n        return selectNames[selectId];\n    }\n\n    public String[] getSelectNames() {\n        return selectNames;\n    }\n\n    public JMethodIdTable getJMethodIdTable() {\n        return table;\n    }\n\n    public int getNProfiledSelects() {\n        return nProfiledSelects;\n    }\n\n    public long[] getInvocationsPerSelectId() {\n        return invocationsPerSelectId;\n    }\n\n    public long[] getTimePerSelectId() {\n        return timePerSelectId;\n    }\n\n    public int[] getTypeForSelectId() {\n        return typeForSelectId;\n    }\n\n    public int[] getCommandTypeForSelectId() {\n        return commandTypeForSelectId;\n    }\n\n    public String[][] getTablesForSelectId() {\n        return tablesForSelectId;\n    }\n\n    public boolean containsStacks() {\n        return stacksForSelects != null;\n    }\n        \n    public void filterReverse(String filter, int filterType, int sortBy, boolean sortOrder, PresoObjAllocCCTNode root, int selectId, boolean dontShowZeroLiveObjAllocPaths) {\n        PresoObjAllocCCTNode rev =\n                (PresoObjAllocCCTNode)createPresentationCCT(selectId, dontShowZeroLiveObjAllocPaths);\n        filter(filter, filterType, rev);\n        root.children = rev.children;\n        if (root.children != null) {\n            for (PresoObjAllocCCTNode ch : root.children)\n                ch.parent = root;\n            root.sortChildren(sortBy, sortOrder);\n        }\n        if (!FilterSortSupport.passesFilter(filter, filterType, root.getNodeName())) {\n//            root.setFilteredNode();\n//            root.methodId = -1;\n        } else {\n//            root.resetFilteredNode();\n        }\n    }\n    \n    private void filter(String filter, int filterType, PresoObjAllocCCTNode node) {\n        if (node.children != null) {\n            PresoObjAllocCCTNode filtered = null;\n            List<PresoObjAllocCCTNode> ch = new ArrayList();\n            for (PresoObjAllocCCTNode n : node.children) {\n                PresoObjAllocCCTNode nn = (PresoObjAllocCCTNode)n;\n                if (FilterSortSupport.passesFilter(filter, filterType, nn.getNodeName())) {\n                    int i = ch.indexOf(nn);\n                    if (i == -1) ch.add(nn);\n                    else ch.get(i).merge(nn);\n                } else {\n                    if (filtered == null) {\n//                        nn.setFilteredNode();\n//                        nn.methodId = -1;\n                        filtered = nn;\n                        ch.add(nn);\n                    } else {\n                        filtered.merge(nn);\n                    }\n                }\n            }\n            \n            if (ch.isEmpty()) {\n                node.children = null;\n            } else {\n                if (node.isFiltered() && filtered != null && ch.size() == 1) {\n                    // \"naive\" approach, collapse simple chain of filtered out nodes\n                    PresoObjAllocCCTNode n = ch.get(0);\n                    filter(filter, filterType, n);\n                    node.children = n.children;\n                } else {\n                    node.children = ch.toArray(new PresoObjAllocCCTNode[0]);\n                }\n            }\n            \n            if (node.children != null)\n                for (PresoObjAllocCCTNode n : node.children)\n                    filter(filter, filterType, (PresoObjAllocCCTNode)n);\n        }\n    }\n    \n\n    /**\n     * Creates a presentation-time allocation stack traces CCT for given selectId.\n     *\n     * @param selectId                       Select ID of the select whose allocation stack traces we request\n     * @param dontShowZeroLiveObjAllocPaths If true, allocation paths with zero live objects will not be included in CCT\n     * @return presentation-time CCT with allocation stack traces or null if none are available\n     */\n    public PresoObjAllocCCTNode createPresentationCCT(int selectId, boolean dontShowZeroLiveObjAllocPaths) {\n        if (stacksForSelects == null) {\n            return null;\n        }\n\n        RuntimeMemoryCCTNode rootNode = stacksForSelects[selectId];\n\n        if (rootNode == null) {\n            return null;\n        }\n\n        return createPresentationCCT(rootNode, selectId, dontShowZeroLiveObjAllocPaths);\n    }\n\n    public JdbcResultsSnapshot createDiff(JdbcResultsSnapshot snapshot) {\n        if (!(snapshot instanceof JdbcResultsSnapshot)) return null;\n        return new JdbcResultsDiff(this, (JdbcResultsSnapshot)snapshot);\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        super.readFromStream(in);\n        \n        StringCache strings = new StringCache();\n        nProfiledSelects = in.readInt();\n        selectNames = new String[nProfiledSelects];\n        invocationsPerSelectId = new long[nProfiledSelects];\n        timePerSelectId = new long[nProfiledSelects];\n        typeForSelectId = new int[nProfiledSelects];\n        commandTypeForSelectId = new int[nProfiledSelects];\n        tablesForSelectId = new String[nProfiledSelects][];\n\n        for (int i = 1; i < nProfiledSelects; i++) {\n            selectNames[i] = in.readUTF();\n            invocationsPerSelectId[i] = in.readLong();\n            timePerSelectId[i] = in.readLong();\n            typeForSelectId[i] = in.readInt();\n            commandTypeForSelectId[i] = in.readInt();\n            tablesForSelectId[i] = new String[in.readInt()];\n            for (int j = 0; j < tablesForSelectId[i].length; j++) {\n                tablesForSelectId[i][j] = strings.intern(in.readUTF());\n            }\n        }\n\n        if (in.readBoolean()) {\n            int len = in.readInt();\n            //System.err.println(\"Read len: \" +len);\n            stacksForSelects = new RuntimeMemoryCCTNode[len];\n\n            for (int i = 0; i < len; i++) {\n                int type = in.readInt();\n\n                //System.err.println(\"  [\" + i + \"] = \" + type);\n                if (type != 0) {\n                    stacksForSelects[i] = RuntimeMemoryCCTNode.create(type);\n                    stacksForSelects[i].readFromStream(in);\n                }\n            }\n\n            if (in.readBoolean()) {\n                table = new JMethodIdTable();\n                table.readFromStream(in);\n            }\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            debugValues();\n        }\n    }\n\n    //---- Serialization support\n    public void writeToStream(DataOutputStream out) throws IOException {\n        super.writeToStream(out);\n\n        out.writeInt(nProfiledSelects);\n\n        for (int i = 1; i < nProfiledSelects; i++) {\n            out.writeUTF(selectNames[i]);\n            out.writeLong(invocationsPerSelectId[i]);\n            out.writeLong(timePerSelectId[i]);\n            out.writeInt(typeForSelectId[i]);\n            out.writeInt(commandTypeForSelectId[i]);\n            out.writeInt(tablesForSelectId[i].length);\n            for (String item : tablesForSelectId[i]) {\n                out.writeUTF(item);\n            }\n        }\n\n        out.writeBoolean(stacksForSelects != null);\n\n        if (stacksForSelects != null) {\n            out.writeInt(stacksForSelects.length);\n\n            //.err.println(\"Stored len: \" +stacksForSelects.length);\n            for (RuntimeMemoryCCTNode stacksForSelect : stacksForSelects) {\n                if (stacksForSelect == null) {\n                    //System.err.println(\"  [\" + i + \"] = 0\");\n                    out.writeInt(0);\n                } else {\n                    out.writeInt(stacksForSelect.getType());\n                    //System.err.println(\"  [\" + i + \"] = \" + stacksForSelects[i].getType());\n                    stacksForSelect.writeToStream(out);\n                }\n            }\n\n            out.writeBoolean(table != null);\n\n            if (table != null) {\n                table.writeToStream(out);\n            }\n        }\n    }\n\n    /**\n     * Will create presentation CCT for call stacks for given root node.\n     *\n     * @param rootNode                      The root node that contains allocation stack traces data\n     * @param selectId                       Id of select whose allocations we are requesting\n     * @param dontShowZeroLiveObjAllocPaths if true, allocation paths with zero live objects will not be included\n     * @return a non-null instance of the root of presentation-time allocations CCT\n     */\n    protected PresoObjAllocCCTNode createPresentationCCT(RuntimeMemoryCCTNode rootNode, int selectId,\n                                                                  boolean dontShowZeroLiveObjAllocPaths) {\n                return PresoObjAllocCCTNode.createPresentationCCTFromSnapshot(getJMethodIdTable(), rootNode, getSelectName(selectId));\n    }\n\n    protected void performInit(ProfilerClient client, JdbcCCTProvider provider)\n                                 throws ClientUtils.TargetAppOrVMTerminated {\n        FlatProfileContainer fpc = provider.createFlatProfile();\n        if (fpc != null) {\n            nProfiledSelects = fpc.getNRows() + 1;\n\n            invocationsPerSelectId = new long[nProfiledSelects];\n            timePerSelectId = new long[nProfiledSelects];\n            typeForSelectId = new int[nProfiledSelects];\n            commandTypeForSelectId = new int[nProfiledSelects];\n            tablesForSelectId = new String[nProfiledSelects][];\n            selectNames = new String[nProfiledSelects];\n            for (int i=0; i<fpc.getNRows() ; i++) {\n                int selectId = fpc.getMethodIdAtRow(i);\n                selectNames[selectId] = fpc.getMethodNameAtRow(i);\n                invocationsPerSelectId[selectId] = fpc.getNInvocationsAtRow(i);\n                timePerSelectId[selectId] = fpc.getTotalTimeInMcs0AtRow(i);\n                typeForSelectId[selectId] = provider.getCommandType(selectId);\n                commandTypeForSelectId[selectId] = provider.getSQLCommand(selectId);\n                tablesForSelectId[selectId] = provider.getTables(selectId);\n            }\n\n            RuntimeMemoryCCTNode[] stacks = provider.getStacksForSelects();\n            if ((stacks != null) && checkContainsStacks(stacks)) {\n                stacksForSelects = new RuntimeMemoryCCTNode[stacks.length];\n                PresoObjAllocCCTNode.getNamesForMethodIdsFromVM(client, stacks);\n\n                for (int i = 0; i < nProfiledSelects; i++) {\n                    if (stacks[i] != null) {\n                        stacksForSelects[i] = (RuntimeMemoryCCTNode) stacks[i].clone();\n                        updateTime(stacksForSelects[i], timePerSelectId[i]/invocationsPerSelectId[i]);\n                    }\n                }\n                table = new JMethodIdTable(client.getJMethodIdTable());\n            }\n        } else {\n            selectNames = new String[0];\n        }\n    }\n\n    private boolean checkContainsStacks(RuntimeMemoryCCTNode[] stacksForSelects) {\n        for (RuntimeMemoryCCTNode stacksForSelect : stacksForSelects) {\n            if (stacksForSelect == null) {\n                continue;\n            }\n\n            if (stacksForSelect instanceof RuntimeObjAllocTermCCTNode) {\n                continue;\n            }\n\n            if (stacksForSelect instanceof RuntimeObjLivenessTermCCTNode) {\n                continue;\n            }\n\n            return true;\n        }\n\n        return false; // no data but term nodes or nulls\n    }\n\n    void debugValues() {\n        LOGGER.finest(\"nProfiledSelects: \" + nProfiledSelects); // NOI18N\n        LOGGER.finest(\"stacksForSelects.length: \" + debugLength(stacksForSelects)); // NOI18N\n        LOGGER.finest(\"invocationsPerSelectId.length: \" + debugLength(invocationsPerSelectId));\n        LOGGER.finest(\"timePerSelectId.length: \" + debugLength(timePerSelectId));\n        LOGGER.finest(\"typeForSelectId.length: \" + debugLength(typeForSelectId));\n        LOGGER.finest(\"commandTypeForSelectId.length: \" + debugLength(commandTypeForSelectId));\n        LOGGER.finest(\"tablesForSelectId.length: \" + debugLength(tablesForSelectId));\n        LOGGER.finest(\"selectNames.length: \" + debugLength(selectNames)); // NOI18N\n        LOGGER.finest(\"table: \" + ((table == null) ? \"null\" : table.debug())); // NOI18N\n    }\n\n    private void updateTime(RuntimeMemoryCCTNode stacksForSelect, long l) {\n        Stack nodes = new Stack();\n        \n        nodes.add(stacksForSelect);\n        while (!nodes.empty()) {\n            RuntimeMemoryCCTNode n = (RuntimeMemoryCCTNode) nodes.pop();\n            if (n instanceof RuntimeObjAllocTermCCTNode) {\n                RuntimeObjAllocTermCCTNode node = (RuntimeObjAllocTermCCTNode)n;\n                node.totalObjSize = l*node.nCalls;\n            }\n            if (n.children != null) {\n                if (n.children instanceof RuntimeMemoryCCTNode) {\n                    nodes.push(n.children);\n                } else {\n                    RuntimeMemoryCCTNode[] ar = (RuntimeMemoryCCTNode[]) n.children;\n\n                    for (RuntimeMemoryCCTNode ar1 : ar) {\n                        nodes.push(ar1);\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/jdbc/SQLConnection.java",
    "content": "/*\n * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.jdbc;\n\nimport java.util.List;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass SQLConnection {\n\n    SQLStatement currentStatement;\n\n    void invoke(String methodName, String methodSignature, List parameters) {\n        switch (methodName) {\n            case \"createStatement\":\n                createStatement();\n                break;\n            case \"prepareStatement\":\n                prepareStatement((String) parameters.get(1));\n                break;\n            case \"prepareCall\":\n                prepareCall((String) parameters.get(1));\n                break;\n        }\n    }\n\n    void createStatement() {\n        assert currentStatement == null;\n        currentStatement = new SQLStatement(JdbcCCTProvider.SQL_STATEMENT);\n    }\n\n    void prepareStatement(String sql) {\n         assert currentStatement == null;\n       currentStatement = new SQLStatement(JdbcCCTProvider.SQL_PREPARED_STATEMENT, sql);\n    }\n\n    void prepareCall(String sql) {\n        assert currentStatement == null;\n        currentStatement = new SQLStatement(JdbcCCTProvider.SQL_CALLABLE_STATEMENT, sql);\n    }\n\n    SQLStatement useCurrentStatement() {\n        SQLStatement st = currentStatement;\n        currentStatement = null;\n        return st;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/jdbc/SQLParser.java",
    "content": "/*\n * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.jdbc;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport static org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcCCTProvider.*;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass SQLParser {\n\n    Object[] commands = {\n        \"ALTER\", SQL_COMMAND_ALTER,     // NOI18N\n        \"CREATE\", SQL_COMMAND_CREATE,   // NOI18N\n        \"DELETE\", SQL_COMMAND_DELETE,   // NOI18N\n        \"DESCRIBE\", SQL_COMMAND_DESCRIBE,   // NOI18N\n        \"INSERT\", SQL_COMMAND_INSERT,   // NOI18N\n        \"SELECT\", SQL_COMMAND_SELECT,   // NOI18N\n        \"SET\", SQL_COMMAND_SET,         // NOI18N\n        \"UPDATE\", SQL_COMMAND_UPDATE    // NOI18N\n    };\n    private static final String fromRegexp = \"(^\\\\bSELECT\\\\b)|\" +\n            \"(\\\\bFROM\\\\b)|\" +\n            \"(\\\\bWHERE\\\\b)|\" +\n            \"(\\\\bGROUP\\\\sBY\\\\b)|\" +\n            \"(\\\\bORDER\\\\sBY\\\\b)|\" +\n            \"(^\\\\bUPDATE\\\\b)|\" +\n            \"(^\\\\bINSERT INTO\\\\b)|\" +\n            \"('[^']*')\";\n    private static final String wordRegexp = \"\\\\b\\\\w+\\\\.?\\\\w*\\\\b\";\n\n    private final Pattern commandsPattern;\n    private final Pattern fromPattern;\n    private final Pattern wordPattern;\n    private final StringCache strings;\n\n    SQLParser() {\n        StringBuilder pattern = new StringBuilder();\n\n        for (int i =0; i < commands.length; i+=2) {\n            pattern.append(\"(^\\\\b\");    // NOI18N\n            pattern.append(commands[i]);\n            pattern.append(\"\\\\b)|\");    // NOI18N\n        }\n        commandsPattern = Pattern.compile(pattern.substring(0, pattern.length()-1), Pattern.CASE_INSENSITIVE);\n        fromPattern = Pattern.compile(fromRegexp, Pattern.CASE_INSENSITIVE);\n        wordPattern = Pattern.compile(wordRegexp, Pattern.CASE_INSENSITIVE);\n        strings = new StringCache();\n    }\n\n    int extractSQLCommandType(String sql) {\n        if (sql != null && sql.startsWith(\"[\")) {\n            return SQL_COMMAND_BATCH;\n        }\n        Matcher m = commandsPattern.matcher(sql);\n        \n        if (m.find()) {\n            for (int i=0; i < commands.length; i+=2) {\n                if (m.start(i/2+1) != -1) {\n                    return ((Integer)commands[i+1]).intValue();\n                }\n            }\n            throw new IllegalArgumentException(m.toString());\n        }\n        return SQL_COMMAND_OTHER;\n    }\n    \n    String[] extractTables(String sql) {\n        String fromClause = extractFromClause(sql);\n        \n        if (fromClause != null) {\n            String[] tablesRefs = fromClause.trim().split(\",\");\n            Set<String> tables = new HashSet(tablesRefs.length);\n            \n            for (String tablesRef : tablesRefs) {\n                Matcher m = wordPattern.matcher(tablesRef);\n                if (m.find()) {\n                    tables.add(strings.intern(m.group()));\n                }\n            }\n            return tables.toArray(new String[0]);\n        }\n        return new String[0];\n    }\n    \n    \n    String extractFromClause(String sql) {\n        Matcher m = fromPattern.matcher(sql);\n        if (m.find()) {\n            if (m.start(1) != -1) { // SELECT \n                int fromStart = -1;\n                int fromEnd = -1;\n                while (m.find()) {\n                    if (m.end(2) != -1) { // FROM\n                        fromStart = m.end(2);\n                    } else if (m.start(3) != -1) {    // WHERE\n                        fromEnd = m.start(3);\n                        break;\n                    } else if (m.start(4) != -1) {    // GROUP BY\n                        fromEnd = m.start(4);\n                        break;\n                    } else if (m.start(5) != -1) {    // ORDER BY\n                        fromEnd = m.start(5);\n                        break;\n                    }\n                }\n                if (fromStart < fromEnd) {\n                    return sql.substring(fromStart+1, fromEnd);\n                } else if (fromStart != -1 && fromEnd == -1) { // just FROM without WHERE\n                    return sql.substring(fromStart+1);\n                }\n            } else if (m.start(6) != -1) {        // UPDATE\n                Matcher mw = wordPattern.matcher(sql.substring(m.end(6)+1));\n                if (mw.find()) {\n                    return mw.group();\n                }\n            } else if (m.start(7) != -1) {        // INSERT INTO\n                Matcher mw = wordPattern.matcher(sql.substring(m.end(7)+1));\n                if (mw.find()) {\n                    return mw.group();\n                }\n            }\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/jdbc/SQLStatement.java",
    "content": "/*\n * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.jdbc;\n\nimport java.io.InputStream;\nimport java.io.Reader;\nimport java.math.BigDecimal;\nimport java.net.URL;\nimport java.sql.Array;\nimport java.sql.Blob;\nimport java.sql.Clob;\nimport java.sql.Date;\nimport java.sql.NClob;\nimport java.sql.Ref;\nimport java.sql.RowId;\nimport java.sql.SQLException;\nimport java.sql.SQLXML;\nimport java.sql.Time;\nimport java.sql.Timestamp;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Calendar;\nimport java.util.List;\nimport java.util.logging.Level;\nimport static org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcGraphBuilder.JDBC_LOGGER;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass SQLStatement {\n\n    static final Object NEW_STATEMENT = new Object();\n    static final Object NEW_PREPARED_STATEMENT = new Object();\n    static final Object NEW_CALLABLE_STATEMENT = new Object();\n\n    private List batch = new ArrayList();\n    private ArrayList parameters = new ArrayList();\n    private String sqlTemplate;\n    private final int type;\n\n    SQLStatement(int t) {\n        type = t;\n    }\n\n    SQLStatement(int t, String sql) {\n        sqlTemplate = sql;\n        type = t;\n    }\n\n    String invoke(String methodName, String methodSignature, List parameters) {\n        String select = null;\n\n        switch(methodName) {\n            case \"executeQuery\":\n                if (parameters.size() == 1) {\n                    select = executeQuery();\n                } else {\n                    select = executeQuery((String) parameters.get(1));\n                }\n                break;\n            case \"executeUpdate\":\n                if (parameters.size() == 1) {\n                    select = executeUpdate();\n                } else {\n                    select = executeUpdate((String) parameters.get(1));\n                }\n                break;\n            case \"execute\":\n                if (parameters.size() == 1) {\n                    select = execute();\n                } else {\n                    select = execute((String) parameters.get(1));\n                }\n                break;\n            case \"addBatch\":\n                if (parameters.size() == 1) {\n                    addBatch();\n                } else {\n                    addBatch((String) parameters.get(1));\n                }\n                break;\n            case \"clearBatch\":\n                clearBatch();\n                break;\n            case \"executeBatch\":\n                select = executeBatch();\n                break;\n            case \"setDate\":\n                setDate((Integer)parameters.get(1), (String)parameters.get(2));\n                break;\n            case \"setTimestamp\":\n                setTimestamp((Integer)parameters.get(1), (String)parameters.get(2));\n                break;\n            case \"setNull\":\n                setNull((Integer)parameters.get(1), (Integer)parameters.get(2));\n                break;\n            default:\n                if (methodName.startsWith(\"set\") && parameters.size()>=3 && parameters.get(1) instanceof Integer) {\n                    setParameter(methodName, (Integer)parameters.get(1), parameters.get(2));\n                }\n        }\n        return select;\n    }\n\n    String executeQuery(String sql) {\n        if (JDBC_LOGGER.isLoggable(Level.FINE)) {\n            JDBC_LOGGER.log(Level.FINE, \"executeQuery {0}\", new Object[]{sql});\n        }\n        return sql;\n    }\n\n    String executeUpdate(String sql) {\n        if (JDBC_LOGGER.isLoggable(Level.FINE)) {\n            JDBC_LOGGER.log(Level.FINE, \"executeUpdate {0}\", new Object[]{sql});\n        }\n        return sql;\n    }\n\n    String execute(String sql) {\n        if (JDBC_LOGGER.isLoggable(Level.FINE)) {\n            JDBC_LOGGER.log(Level.FINE, \"execute {0}\", new Object[]{sql});\n        }\n        return sql;\n    }\n\n    void addBatch() {\n        batch.add(getFullSql());\n    }\n\n    void addBatch(String sql) {\n        batch.add(sql);\n    }\n\n    void clearBatch() {\n        batch.clear();\n    }\n\n    String executeBatch() {\n        if (JDBC_LOGGER.isLoggable(Level.FINE)) {\n            JDBC_LOGGER.log(Level.FINE, \"executeBatch {0}\", new Object[]{Arrays.toString(batch.toArray())});\n        }\n        return Arrays.toString(batch.toArray());\n    }\n\n    void setNull(int parameterIndex, int sqlType) {\n        if (JDBC_LOGGER.isLoggable(Level.FINER)) {\n            JDBC_LOGGER.log(Level.FINER, \"setNull index:{0} type:{1}\", new Object[]{parameterIndex,sqlType});\n        }\n        ensureCapacity(parameterIndex);\n        parameters.set(parameterIndex, \"NULL\");\n    }\n\n    void setBoolean(int parameterIndex, Boolean x) {\n        parameters.ensureCapacity(parameterIndex+1);\n        parameters.add(x);\n    }\n\n    void setByte(int parameterIndex, byte x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setShort(int parameterIndex, short x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setInt(int parameterIndex, int x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setLong(int parameterIndex, long x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setFloat(int parameterIndex, float x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setDouble(int parameterIndex, double x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setBigDecimal(int parameterIndex, BigDecimal x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setString(int parameterIndex, String x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setBytes(int parameterIndex, byte[] x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setDate(int parameterIndex, String x) {\n        ensureCapacity(parameterIndex);\n        long time = Long.parseLong(x);\n        if (JDBC_LOGGER.isLoggable(Level.FINER)) {\n            JDBC_LOGGER.log(Level.FINER, \"setDate index:{0} value:{1}\", new Object[]{parameterIndex,new Date(time)});\n        }\n        parameters.set(parameterIndex, new Date(time));\n    }\n\n    void setTime(int parameterIndex, Time x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setTimestamp(int parameterIndex, String x) {\n        ensureCapacity(parameterIndex);\n        long time = Long.parseLong(x);\n        if (JDBC_LOGGER.isLoggable(Level.FINER)) {\n            JDBC_LOGGER.log(Level.FINER, \"setTime index:{0} value:{1}\", new Object[]{parameterIndex,new Timestamp(time)});\n        }\n        parameters.set(parameterIndex, new Timestamp(time));\n    }\n\n    void setAsciiStream(int parameterIndex, InputStream x, int length) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setUnicodeStream(int parameterIndex, InputStream x, int length) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setBinaryStream(int parameterIndex, InputStream x, int length) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void clearParameters() throws SQLException {\n        parameters.clear();\n    }\n\n    void setObject(int parameterIndex, Object x, int targetSqlType) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setObject(int parameterIndex, Object x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setCharacterStream(int parameterIndex, Reader reader, int length) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setRef(int parameterIndex, Ref x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setBlob(int parameterIndex, Blob x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setClob(int parameterIndex, Clob x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setArray(int parameterIndex, Array x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setDate(int parameterIndex, Date x, Calendar cal) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setTime(int parameterIndex, Time x, Calendar cal) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setNull(int parameterIndex, int sqlType, String typeName) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setURL(int parameterIndex, URL x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setRowId(int parameterIndex, RowId x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setNString(int parameterIndex, String value) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setNCharacterStream(int parameterIndex, Reader value, long length) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setNClob(int parameterIndex, NClob value) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setClob(int parameterIndex, Reader reader, long length) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setBlob(int parameterIndex, InputStream inputStream, long length) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setNClob(int parameterIndex, Reader reader, long length) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setSQLXML(int parameterIndex, SQLXML xmlObject) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setAsciiStream(int parameterIndex, InputStream x, long length) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setBinaryStream(int parameterIndex, InputStream x, long length) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setCharacterStream(int parameterIndex, Reader reader, long length) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setAsciiStream(int parameterIndex, InputStream x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setBinaryStream(int parameterIndex, InputStream x) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setCharacterStream(int parameterIndex, Reader reader) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setNCharacterStream(int parameterIndex, Reader value) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setClob(int parameterIndex, Reader reader) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setBlob(int parameterIndex, InputStream inputStream) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    void setNClob(int parameterIndex, Reader reader) {\n        parameters.ensureCapacity(parameterIndex+1);\n    }\n\n    private void setParameter(String method, Integer parameterIndex, Object p) {\n        if (JDBC_LOGGER.isLoggable(Level.FINER)) {\n            JDBC_LOGGER.log(Level.FINER, \"{0} index:{1} value:{2}\", new Object[]{method,parameterIndex,p});\n        }\n        ensureCapacity(parameterIndex);\n        parameters.set(parameterIndex, p);\n    }\n\n    String executeQuery() {\n        if (JDBC_LOGGER.isLoggable(Level.FINE)) {\n            JDBC_LOGGER.log(Level.FINE, \"executeQuery {0}\", new Object[]{getFullSql()});\n        }\n        return getFullSql();\n    }\n\n    String executeUpdate() {\n        if (JDBC_LOGGER.isLoggable(Level.FINE)) {\n            JDBC_LOGGER.log(Level.FINE, \"executeUpdate {0}\", new Object[]{getFullSql()});\n        }\n        return getFullSql();\n    }\n\n    String execute() {\n        if (JDBC_LOGGER.isLoggable(Level.FINE)) {\n            JDBC_LOGGER.log(Level.FINE, \"execute {0}\", new Object[]{getFullSql()});\n        }\n        return getFullSql();\n    }\n\n    private void ensureCapacity(Integer parameterIndex) {\n        while(parameters.size() <= parameterIndex) {\n            parameters.add(null);\n        }\n    }\n\n    private String getFullSql() {\n        if (sqlTemplate == null) return null;\n        StringBuilder fullSql = new StringBuilder(sqlTemplate.length());\n        int qindex = 0;\n        int parindex = 1;\n        String par;\n\n        do {\n            int lindex = qindex;\n            qindex = sqlTemplate.indexOf('?', qindex);\n            if (qindex == -1) {\n                qindex = sqlTemplate.length();\n                par = \"\";\n            } else {\n                if (parindex >= parameters.size()) {\n                    par = \"!!!!!UNSET\";     // NOI18N\n                } else {\n                    par = formatParamter(parameters.get(parindex++));\n                }\n            }\n            fullSql.append(sqlTemplate.substring(lindex, qindex));\n            fullSql.append(par);\n            qindex++;\n        } while (qindex < sqlTemplate.length());\n        return fullSql.toString();\n    }\n\n    private String formatParamter(Object par) {\n        if (par instanceof String) {\n            return \"'\"+par+\"'\";\n        }\n        if (par == null) {\n            return \"*NULL*\";    // NOI18N\n        }\n        return par.toString();\n    }\n\n    @Override\n    public String toString() {\n        return super.toString() + \":\" + sqlTemplate;    /// NOI18N\n    }\n\n    int getType() {\n        return type;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/jdbc/StringCache.java",
    "content": "/*\n * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.jdbc;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Caches Strings so that there is only one instance of particular string.\n * Functionality is similar to String.intern().\n *\n * @author Tomas Hurka\n */\nclass StringCache {\n\n    Map <String,String> cache;\n\n    StringCache() {\n        cache = new HashMap(2048);\n    }\n\n    String intern(String s) {\n        String unique = cache.get(s);\n        if (unique == null) {\n            cache.put(s, s);\n            return s;\n        }\n        return unique;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/AbstractLockDataFrameProcessor.java",
    "content": "/*\n * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.locks;\n\nimport org.graalvm.visualvm.lib.jfluid.results.AbstractDataFrameProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.ProfilingResultListener;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic abstract class AbstractLockDataFrameProcessor extends AbstractDataFrameProcessor {\n\n    protected volatile int currentThreadId = -1;\n\n    protected void fireMonitorEntry(final int threadId, final long timeStamp0, final long timeStamp1, final int monitorId, final int ownerThreadId) {\n        foreachListener(new ListenerFunctor() {\n            public void execute(ProfilingResultListener listener) {\n                ((LockProfilingResultListener) listener).monitorEntry(threadId, timeStamp0, timeStamp1, monitorId, ownerThreadId);\n            }\n        });\n    }\n\n    protected void fireMonitorExit(final int threadId, final long timeStamp0, final long timeStamp1, final int monitorId) {\n        foreachListener(new ListenerFunctor() {\n            public void execute(ProfilingResultListener listener) {\n                ((LockProfilingResultListener) listener).monitorExit(threadId, timeStamp0, timeStamp1, monitorId);\n            }\n        });\n    }\n\n    protected void fireNewMonitor(final int hash, final String className) {\n        foreachListener(new ListenerFunctor() {\n            public void execute(ProfilingResultListener listener) {\n                ((LockProfilingResultListener) listener).newMonitor(hash, className);\n            }\n        });\n    }\n\n    protected void fireNewThread(final int threadId, final String threadName, final String threadClassName) {\n        foreachListener(new ListenerFunctor() {\n            public void execute(ProfilingResultListener listener) {\n                ((LockProfilingResultListener) listener).newThread(threadId, threadName, threadClassName);\n            }\n        });\n    }\n\n    protected void fireAdjustTime(final int threadId, final long timeStamp0, final long timeStamp1) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((LockProfilingResultListener) listener).timeAdjust(threadId, timeStamp0, timeStamp1);\n                }\n            });\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/Bundle.properties",
    "content": "# Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nThreadLockCCTNode_WaitMonitors=was blocked by\nThreadLockCCTNode_WaitMonitorsOwner=held by {0}\nThreadLockCCTNode_OwnerMonitors=held\nThreadLockCCTNode_OwnerMonitorsWait=blocked {0}\nMonitorCCTNode_WaitThreads=blocked\nMonitorCCTNode_WaitThreadsOwner=held by {0}\nMonitorCCTNode_OwnerThreads=owned by\nMonitorCCTNode_OwnerThreadsWait=blocked {0}\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/LockCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.locks;\n\nimport java.text.NumberFormat;\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\n\n/**\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic abstract class LockCCTNode extends CCTNode {\n\n//    public static final int SORT_BY_NAME = 1;\n//    public static final int SORT_BY_TIME = 2;\n//    public static final int SORT_BY_WAITS = 3;\n\n    public static final LockCCTNode EMPTY = new LockCCTNode(null) {\n        public LockCCTNode getChild(int index) { return null; }\n        public LockCCTNode[] getChildren() { return new LockCCTNode[0]; }\n        public int getIndexOfChild(Object child) { return -1; }\n        public int getNChildren() { return 0; }\n        public String getNodeName() { return \"\"; } // NOI18N\n        public long getTime() { return 0; }\n        public double getTimeInPerCent() { return 0; }\n        public long getWaits() { return 0; }\n    };\n\n    private List<LockCCTNode> children;\n    private final LockCCTNode parent;\n\n//    private int sortBy;\n//    private boolean sortOrder;\n\n    LockCCTNode(LockCCTNode p) {\n        parent = p;\n    }\n\n\n    @Override\n    public LockCCTNode getChild(int index) {\n        if (children == null) {\n            computeChildrenImpl();\n        }\n        return children.get(index);\n    }\n\n    @Override\n    public LockCCTNode[] getChildren() {\n        if (children == null) {\n            computeChildrenImpl();\n        }\n        return children.toArray(new LockCCTNode[0]);\n    }\n\n    @Override\n    public int getIndexOfChild(Object child) {\n        if (children == null) {\n            computeChildrenImpl();\n        }\n        return children.indexOf(child);\n    }\n\n    @Override\n    public int getNChildren() {\n        if (children == null) {\n            computeChildrenImpl();\n        }\n        return children.size();\n    }\n\n    @Override\n    public LockCCTNode getParent() {\n        return parent;\n    }\n\n    void addChild(LockCCTNode child) {\n        if (children == null) {\n            children = new ArrayList();\n        }\n        children.add(child);\n    }\n\n    void computeChildren() {\n        children = new ArrayList();\n    }\n    \n    private void computeChildrenImpl() {\n        computeChildren();\n//        sortChildren(sortBy, sortOrder);\n    }\n\n    public double getTimeInPerCent() {\n        LockCCTNode p = getParent();\n        long allTime = p.getTime();\n        double ppercent = p.getTimeInPerCent();\n        long time = getTime();\n        return ppercent * time / allTime;\n    }\n\n    public abstract String getNodeName();\n\n    public abstract long getTime();\n\n    public abstract long getWaits();\n    \n    public boolean isThreadLockNode() { return false; }\n    public boolean isMonitorNode() { return false; }\n    \n    public String toString() { return getNodeName(); }\n    \n//    public void sortChildren(int sortBy, boolean sortOrder) {\n//        this.sortBy = sortBy;\n//        this.sortOrder = sortOrder;\n//        \n//        if (children == null || getNChildren() < 2) return;\n//        \n//        doSortChildren(sortBy, sortOrder);\n//    }\n//    \n//    protected void doSortChildren(int sortBy, boolean sortOrder) {\n//        switch (sortBy) {\n//            case SORT_BY_NAME:\n//                sortChildrenByName(sortOrder);\n//                break;\n//            case SORT_BY_TIME:\n//                sortChildrenByTime(sortOrder);\n//                break;\n//            case SORT_BY_WAITS:\n//                sortChildrenByWaits(sortOrder);\n//                break;\n//        }\n//        \n//        for (LockCCTNode child : children) child.sortChildren(sortBy, sortOrder);\n//    }\n//\n//    protected void sortChildrenByName(final boolean sortOrder) {\n//        Collections.sort(children, new Comparator<LockCCTNode>() {\n//            public int compare(LockCCTNode n1, LockCCTNode n2) {\n//                return sortOrder ?\n//                       n1.getNodeName().toLowerCase().compareTo(n2.getNodeName().toLowerCase()) :\n//                       n2.getNodeName().toLowerCase().compareTo(n1.getNodeName().toLowerCase());\n//            }\n//        });\n//    }\n//\n//    protected void sortChildrenByTime(final boolean sortOrder) {\n//        Collections.sort(children, new Comparator<LockCCTNode>() {\n//            public int compare(LockCCTNode n1, LockCCTNode n2) {\n//                long result = sortOrder ? n1.getTime() - n2.getTime() :\n//                                          n2.getTime() - n1.getTime();\n//                return result == 0 ? 0 : (result > 0 ? 1 : -1);\n//            }\n//        });\n//    }\n//    \n//    protected void sortChildrenByWaits(final boolean sortOrder) {\n//        Collections.sort(children, new Comparator<LockCCTNode>() {\n//            public int compare(LockCCTNode n1, LockCCTNode n2) {\n//                long result = sortOrder ? n1.getWaits() - n2.getWaits() :\n//                                          n2.getWaits() - n1.getWaits();\n//                return result == 0 ? 0 : (result > 0 ? 1 : -1);\n//            }\n//        });\n//    }\n    \n\n    public void debug() {\n        if (parent != null) {\n            String offset = \"\";\n            for (CCTNode p = parent; p != null; p = p.getParent()) {\n                offset += \"  \";\n            }\n            System.out.println(offset + getNodeName() + \n                    \" Waits: \" + getWaits() + \n                    \" Time: \" + getTime() + \n                    \" \" + NumberFormat.getPercentInstance().format(getTimeInPerCent()/100));\n        }\n        for (CCTNode ch : getChildren()) {\n            if (ch instanceof LockCCTNode) {\n                ((LockCCTNode) ch).debug();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/LockCCTProvider.java",
    "content": "/*\n * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.locks;\n\nimport org.graalvm.visualvm.lib.jfluid.results.CCTProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic interface LockCCTProvider extends CCTProvider {\n    public static interface Listener extends CCTProvider.Listener {\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/LockDataFrameProcessor.java",
    "content": "/*\n * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.locks;\n\nimport java.nio.ByteBuffer;\nimport java.util.logging.Level;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class LockDataFrameProcessor extends AbstractLockDataFrameProcessor {\n\n    @Override\n    public void doProcessDataFrame(ByteBuffer buffer) {\n\n        while (buffer.hasRemaining()) {\n            if (LOGGER.isLoggable(Level.FINEST)) {\n                LOGGER.finest(\"Command start offset \"+buffer.position()); // NOI18N\n            }\n            byte eventType = buffer.get();\n\n            switch (eventType) {\n                case CommonConstants.RESET_COLLECTORS: {\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Profiling data reset\"); // NOI18N\n                    }\n\n                    fireReset();\n\n                    break;\n                }\n                case CommonConstants.BUFFEREVENT_PROFILEPOINT_HIT: {\n                    int id = buffer.getChar();\n                    long timeStamp = getTimeStamp(buffer);\n                    int threadId = buffer.getChar();\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Profile Point Hit \" + id + \", threadId=\" + id + \", timeStamp=\" + timeStamp); // NOI18N\n                    }\n\n                    fireProfilingPoint(threadId, id, timeStamp);\n\n                    break;\n                }\n                case CommonConstants.SET_FOLLOWING_EVENTS_THREAD: {\n                    currentThreadId = buffer.getChar();\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.log(Level.FINEST, \"Change current thread , tId={0}\", currentThreadId); // NOI18N\n                    }\n\n                    break;\n                }\n                case CommonConstants.NEW_THREAD: {\n                    int threadId = buffer.getChar();\n                    String threadName = getString(buffer);\n                    String threadClassName = getString(buffer);\n\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.log(Level.FINEST, \"Creating new thread , tId={0}\", threadId); // NOI18N\n                    }\n\n                    fireNewThread(threadId, threadName, threadClassName);\n                    currentThreadId = threadId;\n\n                    break;\n                }\n                case CommonConstants.NEW_MONITOR: {\n                    int hash = buffer.getInt();\n                    String className = getString(buffer);\n\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.log(Level.FINEST, \"Creating new monitor , monitorId={0} , className={1}\", new Object[] {Integer.toHexString(hash), className}); // NOI18N\n                    }\n\n                    fireNewMonitor(hash, className);\n                    break;\n                }\n                case CommonConstants.METHOD_ENTRY_MONITOR:\n                case CommonConstants.METHOD_EXIT_MONITOR: {\n                    long timeStamp0 = getTimeStamp(buffer);\n                    long timeStamp1 = -1;\n                    int hash = buffer.getInt();\n                    \n                    if (eventType == CommonConstants.METHOD_ENTRY_MONITOR) {\n                        int ownerThreadId = buffer.getInt();\n                        if (LOGGER.isLoggable(Level.FINEST)) {\n                            LOGGER.log(Level.FINEST, \"Monitor entry , tId={0} , monitorId={1} , ownerId={2}\", new Object[]{currentThreadId,Integer.toHexString(hash),ownerThreadId}); // NOI18N\n                        }\n\n                        fireMonitorEntry(currentThreadId, timeStamp0, timeStamp1, hash, ownerThreadId);\n                    }\n                    if (eventType == CommonConstants.METHOD_EXIT_MONITOR) {\n                        if (LOGGER.isLoggable(Level.FINEST)) {\n                            LOGGER.log(Level.FINEST, \"Monitor exit , tId={0} , monitorId={1}\", new Object[]{currentThreadId,Integer.toHexString(hash)}); // NOI18N\n                        }\n\n                        fireMonitorExit(currentThreadId, timeStamp0, timeStamp1, hash);\n                    }\n                    break;\n                }\n                case CommonConstants.ADJUST_TIME: {\n                    long timeStamp0 = getTimeStamp(buffer);\n                    long timeStamp1 = collectingTwoTimeStamps ? getTimeStamp(buffer) : 0;\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.log(Level.FINEST, \"Adjust time , tId={0}\", currentThreadId); // NOI18N\n                    }\n\n                    fireAdjustTime(currentThreadId, timeStamp0, timeStamp1);\n\n                    break;\n                }\n                default: {\n                    LOGGER.severe(\"*** Profiler Engine: internal error: got unknown event type in LockDataFrameProcessor: \" // NOI18N\n                                  + (int) eventType\n                                  + \" at \" + buffer.position() // NOI18N\n                                  );\n\n                    break;\n                }\n            }\n            if (LOGGER.isLoggable(Level.FINEST)) {\n                    LOGGER.finest(\"Command end offset \"+buffer.position()); // NOI18N\n            }\n        }\n        if (LOGGER.isLoggable(Level.FINEST)) {\n                LOGGER.finest(\"Buffer end offset \"+buffer.position()); // NOI18N\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/LockGraphBuilder.java",
    "content": "/*\n * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.locks;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.global.TransactionalSupport;\nimport org.graalvm.visualvm.lib.jfluid.results.BaseCallGraphBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUProfilingResultListener;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryProfilingResultsListener;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class LockGraphBuilder extends BaseCallGraphBuilder implements LockProfilingResultListener, LockCCTProvider {\n\n    static final Logger LOG = Logger.getLogger(LockGraphBuilder.class.getName());\n    final private ThreadInfos threadInfos = new ThreadInfos();\n    private Map<Integer, MonitorInfo> monitorInfos = new HashMap();\n    private final TransactionalSupport transaction = new TransactionalSupport();\n\n    @Override\n    protected RuntimeCCTNode getAppRootNode() {\n        Map<ThreadInfo, List<List<ThreadInfo.MonitorDetail>>> threadsCopy = new HashMap(threadInfos.threadInfos.length);\n        Map<MonitorInfo, List<List<MonitorInfo.ThreadDetail>>> monitorsCopy = new HashMap(monitorInfos.size());\n\n        for (ThreadInfo ti : threadInfos.threadInfos) {\n            if (ti != null) {\n                List<List<ThreadInfo.MonitorDetail>> monitors = new ArrayList(2);\n\n                if (!ti.isEmpty()) {\n                    monitors.add(ti.cloneWaitMonitorDetails());\n                    monitors.add(ti.cloneOwnerMonitorDetails());\n                    threadsCopy.put(ti, monitors);\n                }\n            }\n        }\n        for (MonitorInfo mi : monitorInfos.values()) {\n            List<List<MonitorInfo.ThreadDetail>> threads = new ArrayList(2);\n            \n            threads.add(mi.cloneWaitThreadDetails());\n            threads.add(mi.cloneOwnerThreadDetails());\n            monitorsCopy.put(mi, threads);\n        }\n        return new LockRuntimeCCTNode(threadsCopy, monitorsCopy);\n    }\n\n    @Override\n    protected void doBatchStart() {\n        transaction.beginTrans(true);\n    }\n\n    @Override\n    protected void doBatchStop() {\n        transaction.endTrans();\n    }\n\n    @Override\n    protected void doReset() {\n        if (LOG.isLoggable(Level.FINEST)) {\n            LOG.log(Level.FINEST, \"Do Reset called\");\n        }\n        boolean threadLocked = transaction.beginTrans(true, true);\n\n        if (threadLocked) { // ignore request for reset received durin an ongoing active transaction\n\n            try {\n                threadInfos.reset();\n                monitorInfos = new HashMap();\n            } finally {\n                transaction.endTrans();\n            }\n        }\n    }\n\n    @Override\n    protected void doShutdown() {\n        threadInfos.reset();\n        monitorInfos = new HashMap();\n    }\n\n    @Override\n    protected void doStartup(ProfilerClient profilerClient) {\n        // do nothing\n    }\n\n    @Override\n    public void monitorEntry(int threadId, long timeStamp0, long timeStamp1, int monitorId, int ownerThreadId) {\n        ThreadInfo ti = getThreadInfo(threadId);\n\n        if (ti == null) {\n            return;\n        }\n        if (LOG.isLoggable(Level.FINEST)) {\n            LOG.log(Level.FINEST, \"Monitor entry thread id = {0}, mId = {1}, owner id = {2}\", new Object[]{threadId, Integer.toHexString(monitorId), ownerThreadId});\n        }\n        MonitorInfo m = getMonitorInfo(monitorId);\n        ThreadInfo ownerTi = getThreadInfo(ownerThreadId);\n        assert ownerTi != null;\n        ti.openMonitor(ownerTi, m, timeStamp0);\n        m.openThread(ti, ownerTi, timeStamp0);\n    }\n\n    @Override\n    public void monitorExit(int threadId, long timeStamp0, long timeStamp1, int monitorId) {\n        ThreadInfo ti = getThreadInfo(threadId);\n\n        if (ti == null) {\n            return;\n        }\n        if (LOG.isLoggable(Level.FINEST)) {\n            LOG.log(Level.FINEST, \"Monitor exit thread id = {0}, mId = {1}\", new Object[]{threadId, Integer.toHexString(monitorId)});\n        }\n        MonitorInfo m = getMonitorInfo(monitorId);\n        ti.closeMonitor(m, timeStamp0);\n        m.closeThread(ti, timeStamp0);\n        batchNotEmpty = true;\n    }\n\n    @Override\n    public void newThread(int threadId, String threadName, String threadClassName) {\n        if (!isReady()) {\n            return;\n        }\n        if (LOG.isLoggable(Level.FINEST)) {\n            LOG.log(Level.FINEST, \"New thread creation for thread id = {0}, name = {1}\", new Object[]{threadId, threadName});\n        }\n        threadInfos.newThreadInfo(threadId, threadName, threadClassName);\n    }\n\n    @Override\n    public void newMonitor(int hash, String className) {\n        if (!isReady()) {\n            return;\n        }\n        if (LOG.isLoggable(Level.FINEST)) {\n            LOG.log(Level.FINEST, \"New monitor creation, mId = {0}, className = {1}\", new Object[]{Integer.toHexString(hash), className});\n        }\n        registerNewMonitor(hash,className);\n    }\n\n/*\n    @Override\n    public void sleepEntry(int threadId, long timeStamp0, long timeStamp1) {\n        ThreadInfo ti = getThreadInfo(threadId);\n\n        if (ti == null) {\n            return;\n        }\n        if (LOG.isLoggable(Level.FINEST)) {\n            LOG.log(Level.FINEST, \"Sleep entry thread id = {0}\", threadId);\n        }\n    }\n\n    @Override\n    public void sleepExit(int threadId, long timeStamp0, long timeStamp1) {\n        ThreadInfo ti = getThreadInfo(threadId);\n\n        if (ti == null) {\n            return;\n        }\n        if (LOG.isLoggable(Level.FINEST)) {\n            LOG.log(Level.FINEST, \"Sleep exit thread id = {0}\", threadId);\n        }\n    }\n*/\n\n    public void profilingPoint(final int threadId, final int ppId, final long timeStamp) {\n        // do nothing\n    }\n\n    @Override\n    public void timeAdjust(int threadId, long timeDiff0, long timeDiff1) {\n        ThreadInfo ti = getThreadInfo(threadId);\n\n        if (ti == null) {\n            return;\n        }\n        if (LOG.isLoggable(Level.FINEST)) {\n            LOG.log(Level.FINEST, \"Time adjust thread id = {0}, time = {1}, CPU time = {2}\", new Object[]{threadId, timeDiff0, timeDiff1});\n        }\n        ti.timeAdjust(timeDiff0);\n    }\n/*\n    @Override\n    public void waitEntry(int threadId, long timeStamp0, long timeStamp1) {\n        ThreadInfo ti = getThreadInfo(threadId);\n\n        if (ti == null) {\n            return;\n        }\n        if (LOG.isLoggable(Level.FINEST)) {\n            LOG.log(Level.FINEST, \"Wait entry thread id = {0}\", threadId);\n        }\n    }\n\n    @Override\n    public void waitExit(int threadId, long timeStamp0, long timeStamp1) {\n        ThreadInfo ti = getThreadInfo(threadId);\n\n        if (ti == null) {\n            return;\n        }\n        if (LOG.isLoggable(Level.FINEST)) {\n            LOG.log(Level.FINEST, \"Wait exit thread id = {0}\", threadId);\n        }\n    }\n\n    @Override\n    public void parkEntry(int threadId, long timeStamp0, long timeStamp1) {\n        ThreadInfo ti = getThreadInfo(threadId);\n\n        if (ti == null) {\n            return;\n        }\n        if (LOG.isLoggable(Level.FINEST)) {\n            LOG.log(Level.FINEST, \"Park entry thread id = {0}\", threadId);\n        }\n    }\n\n    @Override\n    public void parkExit(int threadId, long timeStamp0, long timeStamp1) {\n        ThreadInfo ti = getThreadInfo(threadId);\n\n        if (ti == null) {\n            return;\n        }\n        if (LOG.isLoggable(Level.FINEST)) {\n            LOG.log(Level.FINEST, \"Park entry thread id = {0}\", threadId);\n        }\n    }\n*/\n    private boolean isReady() {\n        return (status != null);\n    }\n\n    private ThreadInfo getThreadInfo(int threadId) {\n        if (!isReady()) {\n            return null;\n        }\n\n        return threadInfos.getThreadInfo(threadId);\n    }\n\n    private MonitorInfo getMonitorInfo(int monitorId) {\n        Integer mid = new Integer(monitorId);\n        MonitorInfo mi = monitorInfos.get(mid);\n        if (mi == null) {\n            mi = new MonitorInfo(monitorId);\n            monitorInfos.put(mid, mi);\n        }\n        return mi;\n    }\n\n    private void registerNewMonitor(int monitorId, String className) {\n        Integer mid = new Integer(monitorId);\n        MonitorInfo mi = monitorInfos.get(mid);\n        if (mi == null) {\n            mi = new MonitorInfo(monitorId,className);\n            monitorInfos.put(mid, mi);        \n        } else {\n            mi.setClassName(className);\n        }\n    }\n    \n    public static final class CPULockGraphBuilder extends LockGraphBuilder implements CPUProfilingResultListener {\n\n        @Override\n        public void methodEntry(int methodId, int threadId, int methodType, long timeStamp0, long timeStamp1, List parameters, int[] methoIds) {\n        }\n\n        @Override\n        public void methodEntryUnstamped(int methodId, int threadId, int methodType, List parameters, int[] methoIds) {\n        }\n\n        @Override\n        public void methodExit(int methodId, int threadId, int methodType, long timeStamp0, long timeStamp1, Object retVal) {\n        }\n\n        @Override\n        public void methodExitUnstamped(int methodId, int threadId, int methodType) {\n        }\n\n        @Override\n        public void servletRequest(int threadId, int requestType, String servletPath, int sessionId) {\n        }\n\n        @Override\n        public void sleepEntry(int threadId, long timeStamp0, long timeStamp1) {\n        }\n\n        @Override\n        public void sleepExit(int threadId, long timeStamp0, long timeStamp1) {\n        }\n\n        @Override\n        public void threadsResume(long timeStamp0, long timeStamp1) {\n        }\n\n        @Override\n        public void threadsSuspend(long timeStamp0, long timeStamp1) {\n        }\n\n        @Override\n        public void waitEntry(int threadId, long timeStamp0, long timeStamp1) {\n        }\n\n        @Override\n        public void waitExit(int threadId, long timeStamp0, long timeStamp1) {\n        }\n\n        @Override\n        public void parkEntry(int threadId, long timeStamp0, long timeStamp1) {\n        }\n\n        @Override\n        public void parkExit(int threadId, long timeStamp0, long timeStamp1) {\n        }\n        \n    }\n    public static final class MemoryLockGraphBuilder extends LockGraphBuilder implements MemoryProfilingResultsListener {\n\n        @Override\n        public void onAllocStackTrace(char classId, long objSize, int[] methodIds) {\n        }\n\n        @Override\n        public void onGcPerformed(char classId, long objectId, int objEpoch) {\n        }\n\n        @Override\n        public void onLivenessStackTrace(char classId, long objectId, int objEpoch, long objSize, int[] methodIds) {\n        }\n        \n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/LockProfilingResultListener.java",
    "content": "/*\n * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.locks;\n\nimport org.graalvm.visualvm.lib.jfluid.results.ProfilingResultListener;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic interface LockProfilingResultListener extends ProfilingResultListener {\n\n    void monitorEntry(final int threadId, final long timeStamp0, final long timeStamp1, final int monitorId, int ownerThreadId);\n\n    void monitorExit(final int threadId, final long timeStamp0, final long timeStamp1, final int monitorId);\n\n    void newThread(final int threadId, final String threadName, final String threadClassName);\n\n    void newMonitor(final int hash, final String className);\n\n    void timeAdjust(int threadId, long timeDiff0, long timeDiff1);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/LockRuntimeCCTNode.java",
    "content": "/*\n * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.locks;\n\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class LockRuntimeCCTNode implements RuntimeCCTNode {\n\n    private final Map<ThreadInfo, List<List<ThreadInfo.MonitorDetail>>> threads;\n    private final Map<MonitorInfo, List<List<MonitorInfo.ThreadDetail>>> monitors;\n\n    LockRuntimeCCTNode(Map<ThreadInfo, List<List<ThreadInfo.MonitorDetail>>> threadsCopy, Map<MonitorInfo, List<List<MonitorInfo.ThreadDetail>>> monitorCopy) {\n        threads = threadsCopy;\n        monitors = monitorCopy;\n    }\n\n    public LockCCTNode getThreads() {\n        LockCCTNode top = new TopLockCCTNode();\n        for (Map.Entry<ThreadInfo, List<List<ThreadInfo.MonitorDetail>>> entry : threads.entrySet()) {\n            top.addChild(new ThreadLockCCTNode(top, entry.getKey(), entry.getValue()));\n        }\n        return top;\n    }\n\n    public LockCCTNode getMonitors() {\n        LockCCTNode top = new TopLockCCTNode();\n        for (Map.Entry<MonitorInfo, List<List<MonitorInfo.ThreadDetail>>> entry : monitors.entrySet()) {\n            top.addChild(new MonitorCCTNode(top, entry.getKey(), entry.getValue()));\n        }\n        return top;\n    }\n\n    @Override\n    public RuntimeCCTNode[] getChildren() {\n        throw new UnsupportedOperationException(\"Not supported.\");  // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/MonitorCCTNode.java",
    "content": "/*\n * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.locks;\n\nimport java.text.MessageFormat;\nimport java.util.List;\nimport java.util.ResourceBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass MonitorCCTNode extends LockCCTNode {\n\n    // I18N String constants\n    private static final String WAIT_THREADS_LBL;\n    private static final String WAIT_THREADS_OWNER_LBL;\n    private static final String OWNER_THREADS_LBL;\n    private static final String OWNER_THREADS_WAIT_LBL;\n\n    static {\n        ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.locks.Bundle\"); // NOI18N\n        WAIT_THREADS_LBL = messages.getString(\"MonitorCCTNode_WaitThreads\"); // NOI18N\n        WAIT_THREADS_OWNER_LBL = messages.getString(\"MonitorCCTNode_WaitThreadsOwner\"); // NOI18N\n        OWNER_THREADS_LBL = messages.getString(\"MonitorCCTNode_OwnerThreads\"); // NOI18N\n        OWNER_THREADS_WAIT_LBL = messages.getString(\"MonitorCCTNode_OwnerThreadsWait\"); // NOI18N\n    }\n\n    private final MonitorInfo monitor;\n    private final List<MonitorInfo.ThreadDetail> waitThreads;\n    private final List<MonitorInfo.ThreadDetail> ownerThreads;\n    private ThreadsCCTNode waitNode;\n    private long allTime;\n    private long allCount;\n\n    MonitorCCTNode(LockCCTNode top, MonitorInfo key, List<List<MonitorInfo.ThreadDetail>> value) {\n        super(top);\n        assert value.size() == 2;\n        monitor = key;\n        waitThreads = value.get(0);\n        ownerThreads = value.get(1);\n    }\n\n    @Override\n    public String getNodeName() {\n        return monitor.getName();\n    }\n\n    @Override\n    public long getTime() {\n        if (allTime == 0) {\n            summarize();\n        }\n        return allTime;\n    }\n\n    @Override\n    public long getWaits() {\n        if (allCount == 0) {\n            summarize();\n        }\n        return allCount;\n    }\n\n    @Override\n    public boolean isMonitorNode() {\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        return monitor.hashCode();\n    }\n\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj instanceof MonitorCCTNode) {\n            return monitor.equals(((MonitorCCTNode)obj).monitor);\n        }\n        return false;\n    }\n\n    private void summarize() {\n        getChildren();\n        if (waitNode != null) {\n            allTime = waitNode.getTime();\n            allCount = waitNode.getWaits();\n        }\n    }\n\n    @Override\n    void computeChildren() {\n        super.computeChildren();\n        if (!waitThreads.isEmpty()) {\n            waitNode = new ThreadsCCTNode(this, WAIT_THREADS_LBL, WAIT_THREADS_OWNER_LBL, waitThreads);\n            addChild(waitNode);\n        }\n        if (!ownerThreads.isEmpty()) {\n            addChild(new ThreadsCCTNode(this, OWNER_THREADS_LBL, OWNER_THREADS_WAIT_LBL, ownerThreads));\n        }\n    }\n    \n    static class ThreadsCCTNode extends LockCCTNode {\n\n        private final List<MonitorInfo.ThreadDetail> threads;\n        private final String name;\n        private final String threadNameFormat;\n        private long allTime;\n        private long allCount;\n        \n        ThreadsCCTNode(MonitorCCTNode p, String n, String tnf, List<MonitorInfo.ThreadDetail> ths) {\n            super(p);\n            name = n;\n            threadNameFormat = tnf;\n            threads = ths;\n        }\n        \n        @Override\n        public String getNodeName() {\n            return name;\n        }\n\n        @Override\n        public long getTime() {\n            if (allTime == 0) {\n                summarize();\n            }\n            return allTime;\n       }\n\n        @Override\n        public long getWaits() {\n            if (allCount == 0) {\n                summarize();\n            }\n            return allCount;\n       }\n\n        @Override\n        void computeChildren() {\n            super.computeChildren();\n            for (MonitorInfo.ThreadDetail td : threads) {\n                addChild(new ThreadDetailLockCCTNode(this, threadNameFormat, false, td));\n            }\n        }\n\n        @Override\n        public int hashCode() {\n            return name.hashCode();\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof ThreadsCCTNode) {\n                ThreadsCCTNode tn = (ThreadsCCTNode) obj;\n                return name.equals(tn.name) && getParent().equals(tn.getParent());\n            }\n            return false;\n        }\n\n        private void summarize() {\n            for (MonitorInfo.ThreadDetail td : threads) {\n                allTime += td.waitTime;\n                allCount += td.count;\n            }\n        }\n    }\n    \n    static class ThreadDetailLockCCTNode extends LockCCTNode {\n\n        private final MonitorInfo.ThreadDetail threadDetail;\n        private final String threadNameFormat;\n        private final boolean useFormat;\n        \n        ThreadDetailLockCCTNode(LockCCTNode p, String nf, boolean uf, MonitorInfo.ThreadDetail td) {\n            super(p);\n            threadDetail = td;\n            threadNameFormat = nf;\n            useFormat = uf;\n        }\n\n        ThreadDetailLockCCTNode(LockCCTNode p, String nf, MonitorInfo.ThreadDetail td) {\n            this(p, nf, true, td);\n        }\n\n        @Override\n        public boolean isThreadLockNode() {\n            return true;\n        }\n\n        @Override\n        public String getNodeName() {\n            String name = threadDetail.threadInfo.getName();\n\n            if (threadNameFormat != null && useFormat) {\n                name = MessageFormat.format(threadNameFormat, name);\n            }\n            return name;\n        }\n\n        @Override\n        public long getTime() {\n            return threadDetail.waitTime;\n        }\n\n        @Override\n        public long getWaits() {\n            return threadDetail.count;\n        }\n\n        @Override\n        public int hashCode() {\n            return threadDetail.hashCode();\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof ThreadDetailLockCCTNode) {\n                ThreadDetailLockCCTNode tn = (ThreadDetailLockCCTNode) obj;\n                return threadDetail.threadInfo.equals(tn.threadDetail.threadInfo) && getParent().equals(tn.getParent());\n            }\n            return false;\n        }\n\n        @Override\n        void computeChildren() {\n            super.computeChildren();\n            for (MonitorInfo.ThreadDetail td : threadDetail.cloneThreadDetails()) {\n                addChild(new ThreadDetailLockCCTNode(this, threadNameFormat, td));\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/MonitorInfo.java",
    "content": "/*\n * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.locks;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass MonitorInfo {\n\n    final private int monitorId;\n    private String className;\n    private Map<ThreadInfo, OpenThread> openThreads;\n    private Map<ThreadInfo, ThreadDetail> waitThreads;\n    private Map<ThreadInfo, ThreadDetail> ownerThreads;\n\n    MonitorInfo(int id) {\n        monitorId = id;\n        waitThreads = new HashMap();\n        ownerThreads = new HashMap();\n        openThreads = new HashMap();\n        className = \"*unknown*\"; // NOI18N\n    }\n\n    MonitorInfo(int id, String cname) {\n        this(id);\n        className = StringUtils.userFormClassName(cname);\n    }\n\n    void setClassName(String cname) {\n        className = StringUtils.userFormClassName(cname);\n    }\n\n   @Override\n    public boolean equals(Object obj) {\n        if (obj == this) {\n            return true;\n        }\n        if (obj instanceof MonitorInfo) {\n            MonitorInfo mi = (MonitorInfo) obj;\n            return mi.monitorId == monitorId;\n        }\n        return false;\n    }\n\n    @Override\n    public int hashCode() {\n        return monitorId;\n    }\n\n    void openThread(ThreadInfo ti, ThreadInfo owner, long timeStamp0) {\n        assert openThreads.get(ti) == null;\n        openThreads.put(ti, new OpenThread(ti, owner, timeStamp0));\n    }\n\n    void closeThread(ThreadInfo ti, long timeStamp0) {\n        OpenThread openThread = openThreads.remove(ti);\n        assert openThread != null;\n        long wait = timeStamp0 - openThread.timeStamp;\n        addThread(waitThreads, ti, openThread.owner, wait);\n        addThread(ownerThreads, openThread.owner, ti, wait);\n    }\n\n    private static void addThread(Map<ThreadInfo,ThreadDetail> threads, ThreadInfo master, ThreadInfo detail, long wait) {\n        ThreadDetail td = threads.get(master);\n        if (td == null) {\n            td = new ThreadDetail(master);\n            threads.put(master, td);\n        }\n        td.addWait(detail, wait);\n    }\n\n    void timeAdjust(ThreadInfo ti, long timeDiff) {\n        OpenThread openThread = openThreads.get(ti);\n        assert openThread != null;\n        openThread.timeAdjust(timeDiff);\n    }\n\n    List<ThreadDetail> cloneWaitThreadDetails() {\n        return cloneThreadDetails(waitThreads);\n    }\n\n    List<ThreadDetail> cloneOwnerThreadDetails() {\n        return cloneThreadDetails(ownerThreads);\n    }\n\n    static List<ThreadDetail> cloneThreadDetails(Map<ThreadInfo,ThreadDetail> threads) {\n        List details = new ArrayList(threads.size());\n        for (ThreadDetail d : threads.values()) {\n            details.add(new ThreadDetail(d));\n        }\n        return details;\n\n    }\n\n    String getName() {\n        return new StringBuffer(className).append('(').append(Integer.toHexString(monitorId)).append(')').toString(); // NOI18N\n    }\n\n    private static class OpenThread {\n\n        private final ThreadInfo threadInfo;\n        private final ThreadInfo owner;\n        private long timeStamp;\n\n        OpenThread(ThreadInfo ti, ThreadInfo ownerTi, long ts) {\n            threadInfo = ti;\n            owner = ownerTi;\n            timeStamp = ts;\n        }\n\n        private void timeAdjust(long timeDiff) {\n            timeStamp += timeDiff;\n        }\n    }\n\n    static class ThreadDetail {\n\n        final ThreadInfo threadInfo;\n        private Map<ThreadInfo, ThreadDetail> threads;\n        long count;\n        long waitTime;\n\n        ThreadDetail(ThreadInfo ti) {\n            threadInfo = ti;\n            threads = new HashMap();\n        }\n\n        ThreadDetail(ThreadDetail d) {\n            threadInfo = d.threadInfo;\n            count = d.count;\n            waitTime = d.waitTime;\n            threads = new HashMap();\n            for (ThreadDetail td : d.threads.values()) {\n                threads.put(td.threadInfo, new ThreadDetail(td));\n            }\n        }\n\n        List<ThreadDetail> cloneThreadDetails() {\n            return MonitorInfo.cloneThreadDetails(threads);\n        }\n\n        void addWait(ThreadInfo ti, long wait) {\n            waitTime += wait;\n            count++;\n            if (ti != null) {\n                addThread(ti, wait);\n            }\n        }\n        \n        private void addThread(ThreadInfo ti, long wait) {\n            ThreadDetail td = threads.get(ti);\n            \n            if (td == null) {\n                td = new ThreadDetail(ti);\n                threads.put(ti, td);\n            }\n            td.addWait(null, wait);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/ThreadInfo.java",
    "content": "/*\n * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.locks;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.logging.Level;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ThreadInfo {\n\n    private final int threadId;\n    private final Map<MonitorInfo, MonitorDetail> waitMonitors;\n    private final Map<MonitorInfo, MonitorDetail> ownerMonitors;\n    private OpenMonitor openMonitor;\n    private final String threadName;\n    private final String threadClassName;\n\n    ThreadInfo(int id, String name, String className) {\n        threadId = id;\n        threadName = name;\n        threadClassName = className;\n        waitMonitors = new HashMap();\n        ownerMonitors = new HashMap();\n    }\n\n    void openMonitor(ThreadInfo owner, MonitorInfo mi, long timeStamp) {\n        assert openMonitor == null;\n        openMonitor = new OpenMonitor(mi, owner, timeStamp);\n    }\n\n    void closeMonitor(MonitorInfo mi, long timeStamp) {\n        assert openMonitor != null;\n        assert mi.equals(openMonitor.monitor);\n        long wait = timeStamp - openMonitor.timeStamp;\n        if (LockGraphBuilder.LOG.isLoggable(Level.FINEST)) {\n            LockGraphBuilder.LOG.log(Level.FINEST, \"Monitor exit mId = {0}, time diff = {1}\", new Object[]{Integer.toHexString(mi.hashCode()), wait});\n        }\n        addMonitor(waitMonitors, mi, openMonitor.owner, wait);\n        addMonitor(openMonitor.owner.ownerMonitors, mi, this, wait);\n        openMonitor = null;\n    }\n\n    private static void addMonitor(Map<MonitorInfo,MonitorDetail> monitors, MonitorInfo mi, ThreadInfo ti, long wait) {\n        MonitorDetail m = monitors.get(mi);\n        if (m == null) {\n            m = new MonitorDetail(mi);\n            monitors.put(mi, m);\n        }\n        m.addWait(ti, wait);\n    }\n\n    void timeAdjust(long timeDiff) {\n        if (openMonitor != null) {\n            openMonitor.timeAdjust(timeDiff);\n            openMonitor.monitor.timeAdjust(this, timeDiff);\n        }\n    }\n    \n    boolean isEmpty() {\n        return waitMonitors.isEmpty() && ownerMonitors.isEmpty();\n    }\n\n    List<MonitorDetail> cloneWaitMonitorDetails() {\n        return cloneMonitorDetails(waitMonitors);\n    }\n\n    List<MonitorDetail> cloneOwnerMonitorDetails() {\n        return cloneMonitorDetails(ownerMonitors);\n    }\n\n    private static List<MonitorDetail> cloneMonitorDetails(Map<MonitorInfo,MonitorDetail> monitors) {\n        List details = new ArrayList(monitors.size());\n        for (MonitorDetail m : monitors.values()) {\n            details.add(new MonitorDetail(m));\n        }\n        return details;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj == this) {\n            return true;\n        }\n        if (obj instanceof ThreadInfo) {\n            ThreadInfo mi = (ThreadInfo) obj;\n            return mi.threadId == threadId;\n        }\n        return false;\n    }\n\n    @Override\n    public int hashCode() {\n        return threadId;\n    }\n\n    String getName() {\n        return threadName;\n    }\n\n    private static class OpenMonitor {\n\n        final MonitorInfo monitor;\n        final ThreadInfo owner;\n        long timeStamp;\n\n        OpenMonitor(MonitorInfo mi, ThreadInfo ti, long ts0) {\n            assert mi != null;\n            assert ti != null;\n            monitor = mi;\n            owner = ti;\n            timeStamp = ts0;\n        }\n\n        private void timeAdjust(long timeDiff) {\n            timeStamp += timeDiff;\n        }\n    }\n\n    static class MonitorDetail {\n\n        final MonitorInfo monitor;\n        final Map<ThreadInfo, MonitorInfo.ThreadDetail> threads;\n        long count;\n        long waitTime;\n\n        private MonitorDetail(MonitorInfo mi) {\n            monitor = mi;\n            threads = new HashMap();\n        }\n\n        MonitorDetail(MonitorDetail m) {\n            monitor = m.monitor;\n            count = m.count;\n            waitTime = m.waitTime;\n            threads = new HashMap();\n            for (MonitorInfo.ThreadDetail td : m.threads.values()) {\n                threads.put(td.threadInfo, td);\n            }\n        }\n\n        List<MonitorInfo.ThreadDetail> cloneThreadDetails() {\n            return MonitorInfo.cloneThreadDetails(threads);\n        }\n\n        private void addWait(ThreadInfo ti, long wait) {\n            waitTime += wait;\n            count++;\n            if (ti != null) {\n                addThread(ti, wait);\n            }\n        }\n        \n        private void addThread(ThreadInfo ti, long wait) {\n            MonitorInfo.ThreadDetail td = threads.get(ti);\n            \n            if (td == null) {\n                td = new MonitorInfo.ThreadDetail(ti);\n                threads.put(ti, td);\n            }\n            td.addWait(null, wait);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/ThreadInfos.java",
    "content": "/*\n * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.locks;\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class ThreadInfos {\n\n    ThreadInfo[] threadInfos;\n    int threadInfosLastIdx;\n    ThreadInfo unknowThread = new ThreadInfo(-1, \"Unknown\", \"N/A\");     // NOI18N\n\n    ThreadInfos() {\n        reset();\n    }\n\n    boolean isEmpty() {\n        if ((threadInfos == null) || (threadInfos.length == 0)) {\n            return true;\n        }\n        for (ThreadInfo threadInfo : threadInfos) {\n            if (threadInfo != null) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    void newThreadInfo(int threadId, String threadName, String threadClassName) {\n        if ((threadId > threadInfosLastIdx) || (threadInfos == null)) {\n            int newLen = threadId + 1;\n            ThreadInfo[] newInfos = new ThreadInfo[newLen];\n            if (threadInfos != null) {\n                System.arraycopy(threadInfos, 0, newInfos, 0, threadInfos.length);\n            }\n            threadInfos = newInfos;\n            threadInfosLastIdx = threadId;\n        }\n        threadInfos[threadId] = new ThreadInfo(threadId, threadName, threadClassName);\n    }\n\n    void reset() {\n        threadInfos = null;\n        threadInfosLastIdx = -1;\n    }\n\n    ThreadInfo getThreadInfo(int threadId) {\n        if (threadId == -1) return unknowThread;\n        if (!isEmpty()) {\n            return threadInfos[threadId];\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/ThreadLockCCTNode.java",
    "content": "/*\n * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.locks;\n\nimport java.util.List;\nimport java.util.ResourceBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ThreadLockCCTNode extends LockCCTNode {\n\n    // I18N String constants\n    private static final String WAIT_MONITORS_LBL;\n    private static final String WAIT_MONITORS_OWNER_LBL;\n    private static final String OWNER_MONITORS_LBL;\n    private static final String OWNER_MONITORS__WAIT_LBL;\n\n    static {\n        ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.locks.Bundle\"); // NOI18N\n        WAIT_MONITORS_LBL = messages.getString(\"ThreadLockCCTNode_WaitMonitors\"); // NOI18N\n        WAIT_MONITORS_OWNER_LBL = messages.getString(\"ThreadLockCCTNode_WaitMonitorsOwner\"); // NOI18N\n        OWNER_MONITORS_LBL = messages.getString(\"ThreadLockCCTNode_OwnerMonitors\"); // NOI18N\n        OWNER_MONITORS__WAIT_LBL = messages.getString(\"ThreadLockCCTNode_OwnerMonitorsWait\"); // NOI18N\n    }\n\n    private final ThreadInfo ti;\n    private final List<ThreadInfo.MonitorDetail> waitMonitors;\n    private final List<ThreadInfo.MonitorDetail> ownerMonitors;\n    private MonitorsCCTNode waitNode;\n    private long allTime;\n    private long allCount;\n\n    ThreadLockCCTNode(LockCCTNode parent, ThreadInfo key, List<List<ThreadInfo.MonitorDetail>> value) {\n        super(parent);\n        assert value.size() == 2;\n        ti = key;\n        waitMonitors = value.get(0);\n        ownerMonitors = value.get(1);\n    }\n\n    @Override\n    public String getNodeName() {\n        return ti.getName();\n    }\n\n    @Override\n    public long getTime() {\n        if (allTime == 0) {\n            summarize();\n        }\n        return allTime;\n    }\n\n    @Override\n    public long getWaits() {\n        if (allCount == 0) {\n            summarize();\n        }\n        return allCount;\n    }\n\n    @Override\n    public boolean isThreadLockNode() {\n        return true;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj instanceof ThreadLockCCTNode) {\n            return ti.equals(((ThreadLockCCTNode)obj).ti);\n        }\n        return false;\n    }\n\n    @Override\n    public int hashCode() {\n        return ti.hashCode();\n    }\n\n    private void summarize() {\n        getChildren();\n        if (waitNode != null) {\n            allTime = waitNode.getTime();\n            allCount = waitNode.getWaits();\n        }\n    }\n\n    @Override\n    void computeChildren() {\n        super.computeChildren();\n        if (!waitMonitors.isEmpty()) {\n            waitNode = new MonitorsCCTNode(this, WAIT_MONITORS_LBL, WAIT_MONITORS_OWNER_LBL, waitMonitors);\n            addChild(waitNode);\n        }\n        if (!ownerMonitors.isEmpty()) {\n            addChild(new MonitorsCCTNode(this, OWNER_MONITORS_LBL, OWNER_MONITORS__WAIT_LBL, ownerMonitors));\n        }\n    }\n    \n    static class MonitorsCCTNode extends LockCCTNode {\n\n        private final List<ThreadInfo.MonitorDetail> monitors;\n        private final String name;\n        private final String threadNameFormat;\n        private long allTime;\n        private long allCount;\n        \n        MonitorsCCTNode(ThreadLockCCTNode p, String n, String tnf, List<ThreadInfo.MonitorDetail> ms) {\n            super(p);\n            name = n;\n            threadNameFormat = tnf;\n            monitors = ms;\n        }\n        \n        @Override\n        public String getNodeName() {\n            return name;\n        }\n\n        @Override\n        public long getTime() {\n            if (allTime == 0) {\n                summarize();\n            }\n            return allTime;\n       }\n\n        @Override\n        public long getWaits() {\n            if (allCount == 0) {\n                summarize();\n            }\n            return allCount;\n       }\n\n        @Override\n        public int hashCode() {\n            return name.hashCode();\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof MonitorsCCTNode) {\n                MonitorsCCTNode mn = (MonitorsCCTNode) obj;\n                return name.equals(mn.name) && getParent().equals(mn.getParent());\n            }\n            return false;\n        }\n\n        @Override\n        void computeChildren() {\n            super.computeChildren();\n            for (ThreadInfo.MonitorDetail md : monitors) {\n                addChild(new MonitorDetailsCCTNode(this, threadNameFormat, md));\n            }\n        }\n\n        private void summarize() {\n            for (ThreadInfo.MonitorDetail md : monitors) {\n                allTime += md.waitTime;\n                allCount += md.count;\n            }\n        }        \n    }\n    \n    static class MonitorDetailsCCTNode extends LockCCTNode {\n        \n        private final ThreadInfo.MonitorDetail monitorDetail;\n        private final String threadNameFormat;\n        \n        private MonitorDetailsCCTNode(LockCCTNode p, String tnf, ThreadInfo.MonitorDetail md) {\n            super(p);\n            threadNameFormat = tnf;\n            monitorDetail = md;\n        }\n\n        @Override\n        public boolean isMonitorNode() {\n            return true;\n        }\n\n        @Override\n        public String getNodeName() {\n            return monitorDetail.monitor.getName();\n        }\n\n        @Override\n        public long getTime() {\n            return monitorDetail.waitTime;\n        }\n\n        @Override\n        public long getWaits() {\n            return monitorDetail.count;\n        }\n\n        @Override\n        public int hashCode() {\n            return monitorDetail.monitor.hashCode();\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof MonitorDetailsCCTNode) {\n                MonitorDetailsCCTNode mn = (MonitorDetailsCCTNode) obj;\n                return monitorDetail.monitor.equals(mn.monitorDetail.monitor) && getParent().equals(mn.getParent());\n            }\n            return false;\n        }\n\n        @Override\n        void computeChildren() {\n            super.computeChildren();\n             for (MonitorInfo.ThreadDetail td : monitorDetail.cloneThreadDetails()) {\n                addChild(new MonitorCCTNode.ThreadDetailLockCCTNode(this, threadNameFormat, td));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/locks/TopLockCCTNode.java",
    "content": "/*\n * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.locks;\n\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass TopLockCCTNode extends LockCCTNode {\n\n    private long totalTime;\n    private int totalWaits;\n\n    TopLockCCTNode() {\n        super(null);\n    }\n\n    @Override\n    public String getNodeName() {\n        return \"Invisible root node\";  //NOI18N\n    }\n\n    @Override\n    public long getTime() {\n        if (totalTime == 0) {\n            for (CCTNode ch : getChildren()) {\n                if (ch instanceof LockCCTNode) {\n                    totalTime += ((LockCCTNode) ch).getTime();\n                }\n            }\n        }\n        return totalTime;\n    }\n\n    @Override\n    public int hashCode() {\n        return TopLockCCTNode.class.hashCode();\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        return obj instanceof TopLockCCTNode;\n    }\n\n    @Override\n    public double getTimeInPerCent() {\n        return 100;\n    }\n\n    @Override\n    public long getWaits() {\n        if (totalWaits == 0) {\n            for (CCTNode ch : getChildren()) {\n                if (ch instanceof LockCCTNode) {\n                    totalWaits += ((LockCCTNode) ch).getWaits();\n                }\n            }\n        }\n        return totalWaits;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/AllocMemoryResultsDiff.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.Map;\n\n\n/**\n * Class representing a difference between two snapshots,\n * diffing only values available in AllocMemoryResultsSnapshot\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic class AllocMemoryResultsDiff extends AllocMemoryResultsSnapshot {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final AllocMemoryResultsSnapshot snapshot1;\n    private final AllocMemoryResultsSnapshot snapshot2;\n\n    private String[] classNames;\n    private int[] objectsCounts;\n    private long[] objectsSizePerClass;\n    private int nClasses;\n    private long maxObjectsSizePerClassDiff;\n    private long minObjectsSizePerClassDiff;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public AllocMemoryResultsDiff(AllocMemoryResultsSnapshot snapshot1, AllocMemoryResultsSnapshot snapshot2) {\n        this.snapshot1 = snapshot1;\n        this.snapshot2 = snapshot2;\n\n        computeDiff(snapshot1, snapshot2);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public long getBeginTime() {\n        return -1;\n    }\n\n    public String getClassName(int classId) {\n        return classNames[classId];\n    }\n\n    public String[] getClassNames() {\n        return classNames;\n    }\n\n    public JMethodIdTable getJMethodIdTable() {\n        return null;\n    }\n\n    public long getMaxObjectsSizePerClassDiff() {\n        return maxObjectsSizePerClassDiff;\n    }\n\n    public long getMinObjectsSizePerClassDiff() {\n        return minObjectsSizePerClassDiff;\n    }\n\n    public int getNProfiledClasses() {\n        return nClasses;\n    }\n\n    public int[] getObjectsCounts() {\n        return objectsCounts;\n    }\n\n    public long[] getObjectsSizePerClass() {\n        return objectsSizePerClass;\n    }\n\n    public long getTimeTaken() {\n        return -1;\n    }\n\n    public boolean containsStacks() {\n        return snapshot1.containsStacks() && snapshot2.containsStacks();\n    }\n\n    public PresoObjAllocCCTNode createPresentationCCT(int classId, boolean dontShowZeroLiveObjAllocPaths) {\n        int selectId1 = classId1(classId);\n        int selectId2 = classId2(classId);\n        PresoObjAllocCCTNode node1 = null;\n        PresoObjAllocCCTNode node2 = null;\n\n        if (selectId1 != -1) {\n            node1 = snapshot1.createPresentationCCT(selectId1, dontShowZeroLiveObjAllocPaths);\n        }\n        if (selectId2 != -1) {\n            node2 = snapshot2.createPresentationCCT(selectId2, dontShowZeroLiveObjAllocPaths);\n        }\n        return new DiffObjAllocCCTNode(node1, node2);\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        throw new UnsupportedOperationException(\"Persistence not supported for snapshot comparison\"); // NOI18N\n    }\n\n    //---- Serialization support\n    public void writeToStream(DataOutputStream out) throws IOException {\n        throw new UnsupportedOperationException(\"Persistence not supported for snapshot comparison\"); // NOI18N\n    }\n\n    protected PresoObjAllocCCTNode createPresentationCCT(RuntimeMemoryCCTNode rootNode, int classId,\n                                                         boolean dontShowZeroLiveObjAllocPaths) {\n        int selectId1 = classId1(classId);\n        int selectId2 = classId2(classId);\n        PresoObjAllocCCTNode node1 = null;\n        PresoObjAllocCCTNode node2 = null;\n\n        if (selectId1 != -1) {\n            node1 = snapshot1.createPresentationCCT(rootNode, selectId1, dontShowZeroLiveObjAllocPaths);\n        }\n        if (selectId2 != -1) {\n            node2 = snapshot2.createPresentationCCT(rootNode, selectId2, dontShowZeroLiveObjAllocPaths);\n        }\n        return new DiffObjAllocCCTNode(node1, node2);\n    }\n    \n    private int classId1(int classId) {\n        return classId(classId, snapshot1);\n    }\n    \n    private int classId2(int classId) {\n        return classId(classId, snapshot2);\n    }\n    \n    private int classId(int classId, AllocMemoryResultsSnapshot snapshot) {\n        if (snapshot == null) return -1;\n        \n        String className = getClassName(classId);\n        String[] classNames = snapshot.getClassNames();\n        if (classNames == null) return -1;\n        \n        for (int i = 0; i < classNames.length; i++)\n            if (classNames[i].equals(className)) return i;\n        \n        return -1;\n    }\n\n    private void computeDiff(AllocMemoryResultsSnapshot snapshot1, AllocMemoryResultsSnapshot snapshot2) {\n        // must detect the minimum, same approach as in SnapshotAllocResultsPanel.fetchResultsFromSnapshot()\n        int s1nClasses = Math.min(snapshot1.getNProfiledClasses(), snapshot1.getObjectsCounts().length);\n        s1nClasses = Math.min(s1nClasses, snapshot1.getObjectsSizePerClass().length);\n\n        int s2nClasses = Math.min(snapshot2.getNProfiledClasses(), snapshot2.getObjectsCounts().length);\n        s2nClasses = Math.min(s2nClasses, snapshot2.getObjectsSizePerClass().length);\n\n        // temporary cache for creating diff\n        HashMap<String, Integer> classNamesIdxMap = new HashMap(s1nClasses);\n        ArrayList<Integer> objCountsArr = new ArrayList(s1nClasses);\n        ArrayList<Long> objSizesArr = new ArrayList(s1nClasses);\n\n        // fill the cache with negative values from snapshot1\n        String[] s1ClassNames = snapshot1.getClassNames();\n        int[] s1ObjectsCount = snapshot1.getObjectsCounts();\n        long[] s1ObjectsSizes = snapshot1.getObjectsSizePerClass();\n\n        for (int i = 0; i < s1nClasses; i++) {\n            Integer classIdx = classNamesIdxMap.get(s1ClassNames[i]);\n\n            if (classIdx != null) { // duplicate classname - add objCountsArr and objSizesArr to original classname\n                objCountsArr.set(classIdx, objCountsArr.get(classIdx) - s1ObjectsCount[i]);\n                objSizesArr.set(classIdx, objSizesArr.get(classIdx) - s1ObjectsSizes[i]);\n            } else {\n                classNamesIdxMap.put(s1ClassNames[i], objCountsArr.size());\n                objCountsArr.add(-s1ObjectsCount[i]);\n                objSizesArr.add(-s1ObjectsSizes[i]);\n            }\n        }\n\n        // create diff using values from snapshot2\n        String[] s2ClassNames = snapshot2.getClassNames();\n        int[] s2ObjectsCount = snapshot2.getObjectsCounts();\n        long[] s2ObjectsSizes = snapshot2.getObjectsSizePerClass();\n\n        for (int i = 0; i < s2nClasses; i++) {\n            Integer classIdx = classNamesIdxMap.get(s2ClassNames[i]);\n\n            if (classIdx != null) {\n                // class already present in snapshot1\n//                if (objectsCount != 0 || objCountsArr.get(classIndex) != 0) { // Do not add classes not displayed in compared snapshots (zero instances number)\n                objCountsArr.set(classIdx, objCountsArr.get(classIdx) + s2ObjectsCount[i]);\n                objSizesArr.set(classIdx, objSizesArr.get(classIdx) + s2ObjectsSizes[i]);\n//                } else {\n//                    classNamesIdxMap.remove(s2ClassNames[i]); // Remove classname that should not be displayed\n//                }\n            } else {\n                // class not present in snapshot1\n//                if (objectsCount != 0) { // Do not add classes not displayed in compared snapshots (zero instances number)\n                    classNamesIdxMap.put(s2ClassNames[i], objCountsArr.size());\n                    objCountsArr.add(s2ObjectsCount[i]);\n                    objSizesArr.add(s2ObjectsSizes[i]);\n//                }\n            }\n        }\n\n        // move the diff to instance variables\n        nClasses = classNamesIdxMap.size();\n        classNames = new String[nClasses];\n        objectsCounts = new int[nClasses];\n        objectsSizePerClass = new long[nClasses];\n        minObjectsSizePerClassDiff = Long.MAX_VALUE;\n        maxObjectsSizePerClassDiff = Long.MIN_VALUE;\n\n        Iterator<Map.Entry<String, Integer>> classNamesIter = classNamesIdxMap.entrySet().iterator();\n        int index = 0;\n\n        while (classNamesIter.hasNext()) {\n            Map.Entry<String, Integer> entry = classNamesIter.next();\n            int classIndex = entry.getValue();\n\n            classNames[index] = entry.getKey();\n            objectsCounts[index] = objCountsArr.get(classIndex);\n            objectsSizePerClass[index] = objSizesArr.get(classIndex);\n\n            minObjectsSizePerClassDiff = Math.min(minObjectsSizePerClassDiff, objectsSizePerClass[index]);\n            maxObjectsSizePerClassDiff = Math.max(maxObjectsSizePerClassDiff, objectsSizePerClass[index]);\n\n            index++;\n        }\n\n        if ((minObjectsSizePerClassDiff > 0) && (maxObjectsSizePerClassDiff > 0)) {\n            minObjectsSizePerClassDiff = 0;\n        } else if ((minObjectsSizePerClassDiff < 0) && (maxObjectsSizePerClassDiff < 0)) {\n            maxObjectsSizePerClassDiff = 0;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/AllocMemoryResultsSnapshot.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.text.MessageFormat;\nimport java.util.ResourceBundle;\nimport java.util.logging.Level;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\n\n\n/**\n * Results snapshot for Allocations Memory Profiling.\n *\n * @author Ian Formanek\n */\npublic class AllocMemoryResultsSnapshot extends MemoryResultsSnapshot {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String MEMORY_ALLOC_MSG = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.memory.Bundle\").getString(\"AllocMemoryResultsSnapshot_MemoryAllocMsg\"); // NOI18N\n                                                                                                                    // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int[] objectsCounts;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public AllocMemoryResultsSnapshot() {\n    } // No-arg constructor needed for above serialization methods to work\n\n    public AllocMemoryResultsSnapshot(long beginTime, long timeTaken, MemoryCCTProvider provider, ProfilerClient client)\n                               throws ClientUtils.TargetAppOrVMTerminated {\n        super(beginTime, timeTaken, provider, client);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int[] getObjectsCounts() {\n        return objectsCounts;\n    }\n\n    public void performInit(ProfilerClient client, MemoryCCTProvider provider)\n                     throws ClientUtils.TargetAppOrVMTerminated {\n        super.performInit(client, provider);\n        \n        int[] cnts = client.getAllocatedObjectsCountResults();\n        objectsCounts = new int[cnts.length];\n        System.arraycopy(cnts, 0, objectsCounts, 0, cnts.length);\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            debugValues();\n        }\n    }\n    \n    public AllocMemoryResultsSnapshot createDiff(MemoryResultsSnapshot snapshot) {\n        if (!(snapshot instanceof AllocMemoryResultsSnapshot)) return null;\n        return new AllocMemoryResultsDiff(this, (AllocMemoryResultsSnapshot)snapshot);\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        super.readFromStream(in);\n\n        int len = in.readInt();\n        objectsCounts = new int[len];\n\n        for (int i = 0; i < len; i++) {\n            objectsCounts[i] = in.readInt();\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            debugValues();\n        }\n    }\n\n    public String toString() {\n        return MessageFormat.format(MEMORY_ALLOC_MSG, new Object[] { super.toString() });\n    }\n\n    //---- Serialization support\n    public void writeToStream(DataOutputStream out) throws IOException {\n        super.writeToStream(out);\n\n        out.writeInt(objectsCounts.length);\n\n        for (int i = 0; i < objectsCounts.length; i++) {\n            out.writeInt(objectsCounts[i]);\n        }\n    }\n\n    protected PresoObjAllocCCTNode createPresentationCCT(RuntimeMemoryCCTNode rootNode, int classId,\n                                                         boolean dontShowZeroLiveObjAllocPaths) {\n        return PresoObjAllocCCTNode.createPresentationCCTFromSnapshot(getJMethodIdTable(), rootNode, getClassName(classId));\n    }\n\n    void debugValues() {\n        super.debugValues();\n        LOGGER.finest(\"objectsCounts.length: \" + debugLength(objectsCounts)); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nSampledMemoryResultsSnapshot_MemorySamledMsg=Memory (Sampling)\\: {0}\n\nAllocMemoryResultsSnapshot_MemoryAllocMsg=Memory (Allocations)\\: {0}\n\nLivenessMemoryResultsSnapshot_MemoryLivenessMsg=Memory (Liveness)\\: {0}\n\nPresoObjAllocCCTNode_VMAllocMsg=Objects allocated by reflection\n\nPresoObjAllocCCTNode_UnknownMsg=<Unknown>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/ClassHistoryDataManager.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport org.graalvm.visualvm.lib.jfluid.results.DataManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ClassHistoryDataManager extends DataManager {\n\n    private int trackedClassID;\n    private String trackedClassName;\n\n    public long[] timeStamps; // Timeline\n    public int[] nTotalAllocObjects; // Objects Allocated\n    public long[] totalAllocObjectsSize; // Bytes Allocated\n    public int[] nTrackedLiveObjects; // Live Objects\n    public long[] trackedLiveObjectsSize; // Live Bytes\n\n\n    private int arrayBufferSize;\n    private int currentArraysSize;\n    private int itemCount;\n\n\n    public ClassHistoryDataManager() {\n        this(50);\n    }\n\n    public ClassHistoryDataManager(int arrayBufferSize) {\n        this.arrayBufferSize = arrayBufferSize;\n        reset();\n    }\n\n\n    public synchronized void setArrayBufferSize(int arrayBufferSize) {\n        this.arrayBufferSize = arrayBufferSize;\n    }\n\n    public synchronized int getArrayBufferSize() {\n        return arrayBufferSize;\n    }\n\n    public synchronized int getItemCount() {\n        return itemCount;\n    }\n\n    public synchronized int getTrackedClassID() {\n        return trackedClassID;\n    }\n\n    public synchronized String getTrackedClassName() {\n        return trackedClassName;\n    }\n\n    public synchronized boolean isTrackingClass() {\n        return trackedClassName != null;\n    }\n\n\n    public synchronized void setupClass(int trackedClassID, String trackedClassName) {\n        reset();\n\n        this.trackedClassID = trackedClassID;\n        this.trackedClassName = trackedClassName;\n    }\n\n    public synchronized void resetClass() {\n        reset();\n    }\n\n    public synchronized void processData(int[] nTotalAllocObjects,\n                                         long[] totalAllocObjectsSize) {\n\n        checkArraysSize();\n\n        timeStamps[itemCount] = System.currentTimeMillis();\n        this.nTotalAllocObjects[itemCount] = nTotalAllocObjects[trackedClassID];\n        this.totalAllocObjectsSize[itemCount] = totalAllocObjectsSize[trackedClassID];\n\n        itemCount++;\n\n        fireDataChanged();\n\n    }\n\n    public synchronized void processData(int[] nTotalAllocObjects,\n                                         int[] nTrackedLiveObjects,\n                                         long[] trackedLiveObjectsSize) {\n\n        checkArraysSize();\n\n        timeStamps[itemCount] = System.currentTimeMillis();\n        this.nTotalAllocObjects[itemCount] = nTotalAllocObjects[trackedClassID];\n        this.nTrackedLiveObjects[itemCount] = nTrackedLiveObjects[trackedClassID];\n        this.trackedLiveObjectsSize[itemCount] = trackedLiveObjectsSize[trackedClassID];\n\n        itemCount++;\n\n        fireDataChanged();\n\n    }\n\n\n    private void reset() {\n        itemCount = 0;\n\n        trackedClassID = -1;\n        trackedClassName = null;\n\n        timeStamps = new long[arrayBufferSize];\n        nTotalAllocObjects = new int[arrayBufferSize];\n        totalAllocObjectsSize = new long[arrayBufferSize];\n        nTrackedLiveObjects = new int[arrayBufferSize];\n        trackedLiveObjectsSize = new long[arrayBufferSize];\n\n        currentArraysSize = arrayBufferSize;\n\n        fireDataReset();\n    }\n    \n    private void checkArraysSize() {\n        // array extension is needed\n        if (currentArraysSize == itemCount) {\n            timeStamps = extendArray(timeStamps, arrayBufferSize);\n            nTotalAllocObjects = extendArray(nTotalAllocObjects, arrayBufferSize);\n            totalAllocObjectsSize = extendArray(totalAllocObjectsSize, arrayBufferSize);\n            nTrackedLiveObjects = extendArray(nTrackedLiveObjects, arrayBufferSize);\n            trackedLiveObjectsSize = extendArray(trackedLiveObjectsSize, arrayBufferSize);\n\n            // update current array size\n            currentArraysSize += arrayBufferSize;\n        }\n    }\n\n    // extends 1-dimensional long array\n    private static long[] extendArray(long[] array, int extraLength) {\n        int originalLength = array.length;\n        long[] newArray = new long[originalLength + extraLength];\n        System.arraycopy(array, 0, newArray, 0, originalLength);\n\n        return newArray;\n    }\n\n    // extends 1-dimensional int array\n    private static int[] extendArray(int[] array, int extraLength) {\n        int originalLength = array.length;\n        int[] newArray = new int[originalLength + extraLength];\n        System.arraycopy(array, 0, newArray, 0, originalLength);\n\n        return newArray;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/DiffObjAllocCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.results.FilterSortSupport;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DiffObjAllocCCTNode extends PresoObjAllocCCTNode {\n\n    private final PresoObjAllocCCTNode node1;\n    private final PresoObjAllocCCTNode node2;\n\n\n    public DiffObjAllocCCTNode(PresoObjAllocCCTNode node1, PresoObjAllocCCTNode node2) {\n        this.node1 = node1;\n        this.node2 = node2;\n\n        long nCalls1 = node1 == null ? 0 : node1.nCalls;\n        long nCalls2 = node2 == null ? 0 : node2.nCalls;\n        nCalls = nCalls2 - nCalls1;\n\n        long totalObjSize1 = node1 == null ? 0 : node1.totalObjSize;\n        long totalObjSize2 = node2 == null ? 0 : node2.totalObjSize;\n        totalObjSize = totalObjSize2 - totalObjSize1;\n\n        PresoObjAllocCCTNode[] children1 = node1 == null ? null : (PresoObjAllocCCTNode[])node1.getChildren();\n        if (children1 == null) children1 = new PresoObjAllocCCTNode[0];\n        PresoObjAllocCCTNode[] children2 = node2 == null ? null : (PresoObjAllocCCTNode[])node2.getChildren();\n        if (children2 == null) children2 = new PresoObjAllocCCTNode[0];\n        setChildren(computeChildren(children1, children2, this));\n    }\n\n\n    public DiffObjAllocCCTNode createFilteredNode() {\n        DiffObjAllocCCTNode filtered = new DiffObjAllocCCTNode(node1, node2);\n        setupFilteredNode(filtered);\n        return filtered;\n    }\n\n\n    public String getNodeName() {\n        if (nodeName == null) {\n            if (isFiltered()) nodeName = FilterSortSupport.FILTERED_OUT_LBL;\n            else nodeName = getNode().getNodeName();\n        }\n        return nodeName;\n    }\n    \n    public String[] getMethodClassNameAndSig() {\n        return getNode().getMethodClassNameAndSig();\n    }\n    \n    \n    public boolean equals(Object o) {\n        if (o == this) return true;\n        if (!(o instanceof DiffObjAllocCCTNode)) return false;\n        DiffObjAllocCCTNode other = (DiffObjAllocCCTNode)o;\n        if (isFiltered()) {\n            return other.isFiltered();\n        }\n        if (other.isFiltered()) {\n            return false;\n        }\n        return getNode().equals(other.getNode());\n    }\n\n    public int hashCode() {\n        return getNode().hashCode();\n    }\n    \n    \n    public boolean isLeaf() {\n        boolean leaf1 = node1 == null || node1.isLeaf();\n        boolean leaf2 = node2 == null || node2.isLeaf();\n        return leaf1 && leaf2;\n    }\n    \n    private PresoObjAllocCCTNode getNode() {\n        if (node1 == null) {\n            return node2;\n        }\n        return node1;\n    }\n    \n    private static PresoObjAllocCCTNode[] computeChildren(PresoObjAllocCCTNode[] children1, PresoObjAllocCCTNode[] children2, PresoObjAllocCCTNode parent) {        \n        Map<Handle, PresoObjAllocCCTNode> nodes1 = new HashMap();\n        for (PresoObjAllocCCTNode node : children1) {\n            Handle name = new Handle(node);\n            PresoObjAllocCCTNode sameNode = nodes1.get(name);\n            if (sameNode == null) nodes1.put(name, node);\n            else sameNode.merge(node);\n        }\n        \n        Map<Handle, PresoObjAllocCCTNode> nodes2 = new HashMap();\n        for (PresoObjAllocCCTNode node : children2) {\n            Handle name = new Handle(node);\n            PresoObjAllocCCTNode sameNode = nodes2.get(name);\n            if (sameNode == null) nodes2.put(name, node);\n            else sameNode.merge(node); // Merge same-named items\n        }\n        \n        List<PresoObjAllocCCTNode> children = new ArrayList();\n        for (PresoObjAllocCCTNode node1 : nodes1.values()) {\n            PresoObjAllocCCTNode node2 = nodes2.get(new Handle(node1));\n            if (node2 != null) children.add(new DiffObjAllocCCTNode(node1, node2));\n            else children.add(new DiffObjAllocCCTNode(node1, null));\n        }\n        for (PresoObjAllocCCTNode node2 : nodes2.values()) {\n            if (!nodes1.containsKey(new Handle(node2))) children.add(new DiffObjAllocCCTNode(null, node2));\n        }\n        \n        return children.toArray(new PresoObjAllocCCTNode[0]);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/DiffObjLivenessCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.results.FilterSortSupport;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass DiffObjLivenessCCTNode extends PresoObjLivenessCCTNode {\n\n    private final PresoObjLivenessCCTNode node1;\n    private final PresoObjLivenessCCTNode node2;\n\n\n    DiffObjLivenessCCTNode(PresoObjLivenessCCTNode node1, PresoObjLivenessCCTNode node2) {\n        this.node1 = node1;\n        this.node2 = node2;\n\n        long nCalls1 = node1 == null ? 0 : node1.nCalls;\n        long nCalls2 = node2 == null ? 0 : node2.nCalls;\n        nCalls = nCalls2 - nCalls1;\n\n        long totalObjSize1 = node1 == null ? 0 : node1.totalObjSize;\n        long totalObjSize2 = node2 == null ? 0 : node2.totalObjSize;\n        totalObjSize = totalObjSize2 - totalObjSize1;\n\n        float avgObjectAge1 = node1 == null ? 0 : node1.avgObjectAge;\n        float avgObjectAge2 = node2 == null ? 0 : node2.avgObjectAge;\n        avgObjectAge = avgObjectAge2 - avgObjectAge1;\n\n        int nLiveObjects1 = node1 == null ? 0 : node1.nLiveObjects;\n        int nLiveObjects2 = node2 == null ? 0 : node2.nLiveObjects;\n        nLiveObjects = nLiveObjects2 - nLiveObjects1;\n\n        int survGen1 = node1 == null ? 0 : node1.survGen;\n        int survGen2 = node2 == null ? 0 : node2.survGen;\n        survGen = survGen2 - survGen1;\n\n        PresoObjAllocCCTNode[] children1 = node1 == null ? null : (PresoObjAllocCCTNode[])node1.getChildren();\n        if (children1 == null) children1 = new PresoObjAllocCCTNode[0];\n        PresoObjAllocCCTNode[] children2 = node2 == null ? null : (PresoObjAllocCCTNode[])node2.getChildren();\n        if (children2 == null) children2 = new PresoObjAllocCCTNode[0];\n        setChildren(computeChildren(children1, children2, this));\n    }\n    \n    \n    public DiffObjLivenessCCTNode createFilteredNode() {\n        DiffObjLivenessCCTNode filtered = new DiffObjLivenessCCTNode(node1, node2);\n        setupFilteredNode(filtered);\n        return filtered;\n    }\n    \n    \n    public String getNodeName() {\n        if (nodeName == null) {\n            if (isFiltered()) nodeName = FilterSortSupport.FILTERED_OUT_LBL;\n            else nodeName = getNode().getNodeName();\n        }\n        return nodeName;\n    }\n    \n    public String[] getMethodClassNameAndSig() {\n        return getNode().getMethodClassNameAndSig();\n    }\n    \n    \n    public boolean equals(Object o) {\n        if (o == this) return true;\n        if (!(o instanceof DiffObjLivenessCCTNode)) return false;\n        DiffObjLivenessCCTNode other = (DiffObjLivenessCCTNode)o;\n        if (isFiltered()) {\n            return other.isFiltered();\n        }\n        if (other.isFiltered()) {\n            return false;\n        }\n        return getNode().equals(other.getNode());\n    }\n\n    public int hashCode() {\n        return getNode().hashCode();\n    }\n    \n    \n    public boolean isLeaf() {\n        boolean leaf1 = node1 == null || node1.isLeaf();\n        boolean leaf2 = node2 == null || node2.isLeaf();\n        return leaf1 && leaf2;\n    }\n    \n    private PresoObjLivenessCCTNode getNode() {\n        if (node1 == null) {\n            return node2;\n        }\n        return node1;\n    }\n    \n    private static PresoObjAllocCCTNode[] computeChildren(PresoObjAllocCCTNode[] children1, PresoObjAllocCCTNode[] children2, PresoObjLivenessCCTNode parent) {        \n        Map<Handle, PresoObjAllocCCTNode> nodes1 = new HashMap();\n        for (PresoObjAllocCCTNode node : children1) {\n            Handle name = new Handle(node);\n            PresoObjAllocCCTNode sameNode = nodes1.get(name);\n            if (sameNode == null) nodes1.put(name, node);\n            else sameNode.merge(node);\n        }\n        \n        Map<Handle, PresoObjAllocCCTNode> nodes2 = new HashMap();\n        for (PresoObjAllocCCTNode node : children2) {\n            Handle name = new Handle(node);\n            PresoObjAllocCCTNode sameNode = nodes2.get(name);\n            if (sameNode == null) nodes2.put(name, node);\n            else sameNode.merge(node); // Merge same-named items\n        }\n        \n        List<PresoObjAllocCCTNode> children = new ArrayList();\n        for (PresoObjAllocCCTNode node1 : nodes1.values()) {\n            PresoObjAllocCCTNode node2 = nodes2.get(new Handle(node1));\n            if (node2 != null) children.add(new DiffObjLivenessCCTNode((PresoObjLivenessCCTNode)node1, (PresoObjLivenessCCTNode)node2));\n            else children.add(new DiffObjLivenessCCTNode((PresoObjLivenessCCTNode)node1, null));\n        }\n        for (PresoObjAllocCCTNode node2 : nodes2.values()) {\n            if (!nodes1.containsKey(new Handle(node2))) children.add(new DiffObjLivenessCCTNode(null, (PresoObjLivenessCCTNode)node2));\n        }\n        \n        return children.toArray(new PresoObjAllocCCTNode[0]);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/HeapHistogram.java",
    "content": "/*\n * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.util.Date;\nimport java.util.Set;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic abstract class HeapHistogram {\n\n    public abstract Date getTime();\n\n    public abstract long getTotalInstances();\n\n    public abstract long getTotalBytes();\n\n    public abstract Set<ClassInfo> getHeapHistogram();\n\n    public abstract long getTotalHeapInstances();\n\n    public abstract long getTotalHeapBytes();\n\n    public abstract Set<ClassInfo> getPermGenHistogram();\n\n    public abstract long getTotalPerGenInstances();\n\n    public abstract long getTotalPermGenHeapBytes();\n\n    public static abstract class ClassInfo {\n\n        public abstract String getName();\n\n        public abstract long getInstancesCount();\n\n        public abstract long getBytes();\n\n        public int hashCode() {\n            return getName().hashCode();\n        }\n\n        public boolean equals(Object obj) {\n            if (obj instanceof ClassInfo) {\n                return getName().equals(((ClassInfo) obj).getName());\n            }\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/HeapHistogramManager.java",
    "content": "/*\n * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.HeapHistogramResponse;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class HeapHistogramManager {\n\n    private Map<Integer, String> classesIdMap = new HashMap(8000);\n    private final ProfilerEngineSettings settings;\n\n    public HeapHistogramManager(ProfilerEngineSettings settings) {\n        this.settings = settings;\n    }\n\n    public HeapHistogram getHistogram(HeapHistogramResponse resp) {\n        String[] newNames = resp.getNewNames();\n        int[] newIds = resp.getNewids();\n\n        for (int i = 0; i < newNames.length; i++) {\n            classesIdMap.put(newIds[i], newNames[i]);\n        }\n        int ids[] = resp.getIds();\n        long instances[] = resp.getInstances();\n        long bytes[] = resp.getBytes();\n        HeapHistogramImpl histogram = new HeapHistogramImpl(resp.getTime());\n        GenericFilter classFilter = settings.getInstrumentationFilter();\n        for (int i = 0; i < ids.length; i++) {\n            String className = classesIdMap.get(ids[i]);\n\n            if (classFilter.passes(className.replace('.', '/'))) { // NOI18N\n                ClassInfoImpl ci = new ClassInfoImpl(className, instances[i], bytes[i]);\n                histogram.addClassInfo(ci, false);\n            }\n        }\n        return histogram;\n    }\n\n    static class HeapHistogramImpl extends HeapHistogram {\n\n        private Date time;\n        private long totalHeapInstances;\n        private long totalHeapBytes;\n        private Set<ClassInfo> heap;\n        private long totalPermInstances;\n        private long totalPermBytes;\n        private Set<ClassInfo> perm;\n\n        HeapHistogramImpl(Date t) {\n            time = t;\n            heap = new HashSet(4096);\n            perm = new HashSet();\n        }\n\n        void addClassInfo(ClassInfo ci, boolean permInfo) {\n            if (permInfo) {\n                perm.add(ci);\n                totalPermInstances += ci.getInstancesCount();\n                totalPermBytes += ci.getBytes();\n            } else {\n                heap.add(ci);\n                totalHeapInstances += ci.getInstancesCount();\n                totalHeapBytes += ci.getBytes();\n            }\n        }\n\n        @Override\n        public Date getTime() {\n            return time;\n        }\n\n        @Override\n        public long getTotalInstances() {\n            return totalHeapInstances + totalPermInstances;\n        }\n\n        @Override\n        public long getTotalBytes() {\n            return totalHeapBytes + totalPermBytes;\n        }\n\n        @Override\n        public Set<ClassInfo> getHeapHistogram() {\n            return heap;\n        }\n\n        @Override\n        public long getTotalHeapInstances() {\n            return totalHeapInstances;\n        }\n\n        @Override\n        public long getTotalHeapBytes() {\n            return totalHeapBytes;\n        }\n\n        @Override\n        public Set<ClassInfo> getPermGenHistogram() {\n            return perm;\n        }\n\n        @Override\n        public long getTotalPerGenInstances() {\n            return totalPermInstances;\n        }\n\n        @Override\n        public long getTotalPermGenHeapBytes() {\n            return totalPermBytes;\n        }\n    }\n\n    static class ClassInfoImpl extends HeapHistogram.ClassInfo {\n\n        private String name;\n        private long instances;\n        private long bytes;\n\n        ClassInfoImpl(String n, long i, long b) {\n            name = n;\n            instances = i;\n            bytes = b;\n        }\n\n        @Override\n        public String getName() {\n            return name;\n        }\n\n        @Override\n        public long getInstancesCount() {\n            return instances;\n        }\n\n        @Override\n        public long getBytes() {\n            return bytes;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/JMethodIdTable.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\n\n\n/**\n * This class maps jmethodIds to (clazz, methodIdx) pairs\n *\n * @author Misha Dmitriev\n */\npublic class JMethodIdTable {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class JMethodIdTableEntry {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        public String className;\n        public String methodName;\n        public String methodSig;\n        public transient boolean isNative;\n        int methodId;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        JMethodIdTableEntry(int methodId) {\n            this.methodId = methodId;\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static String NATIVE_SUFFIX = \"[native]\";   // NOI18N\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JMethodIdTableEntry[] entries;\n    private boolean staticTable = false;\n    private int incompleteEntries;\n    private int nElements;\n    private int size;\n    private int threshold;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public JMethodIdTable() {\n        size = 97;\n        threshold = (size * 3) / 4;\n        nElements = 0;\n        entries = new JMethodIdTableEntry[size];\n    }\n\n    public JMethodIdTable(JMethodIdTable otherTable) {\n        staticTable = true;\n        threshold = otherTable.nElements + 1;\n        size = (threshold * 4) / 3 ;\n        nElements = 0;\n        entries = new JMethodIdTableEntry[size];\n        \n        for (JMethodIdTableEntry entry : otherTable.entries) {\n            if (entry != null) {\n                addEntry(entry.methodId, entry.className, entry.methodName, entry.methodSig, entry.isNative);\n            }\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    synchronized public String debug() {\n        if (entries == null) {\n            return \"Entries = null, size = \" + size + \", nElements = \" + nElements + \", threshold = \" // NOI18N\n                   + threshold + \", incompleteEntries = \" + incompleteEntries; // NOI18N\n        } else {\n            return \"Entries.length = \" + entries.length + \", size = \" + size + \", nElements = \" + nElements // NOI18N\n                   + \", threshold = \" + threshold + \", incompleteEntries = \" + incompleteEntries; // NOI18N\n        }\n    }\n\n    synchronized public void readFromStream(DataInputStream in) throws IOException {\n        size = in.readInt();\n        nElements = in.readInt();\n        threshold = in.readInt();\n\n        entries = new JMethodIdTableEntry[size];\n\n        int count = in.readInt();\n\n        for (int i = 0; i < count; i++) {\n            int methodId = in.readInt();\n            String className = in.readUTF();\n            String methodName = in.readUTF();\n            String methodSig = in.readUTF();\n            boolean isNative = false;\n            \n            if (methodName.endsWith(NATIVE_SUFFIX)) {\n                methodName = methodName.substring(0, methodName.length() - NATIVE_SUFFIX.length());\n                isNative = true;\n            }\n            addEntry(methodId, className, methodName, methodSig, isNative);\n        }\n    }\n\n    synchronized public void writeToStream(DataOutputStream out) throws IOException {\n        out.writeInt(size);\n        out.writeInt(nElements);\n        out.writeInt(threshold);\n\n        int count = 0;\n\n        for (JMethodIdTableEntry entrie : entries) {\n            if (entrie != null) {\n                count++;\n            }\n        }\n\n        out.writeInt(count);\n\n        for (JMethodIdTableEntry entry : entries) {\n            if (entry != null) {\n                out.writeInt(entry.methodId);\n                out.writeUTF(entry.className);\n                out.writeUTF(entry.isNative ? entry.methodName.concat(NATIVE_SUFFIX) : entry.methodName);\n                out.writeUTF(entry.methodSig);\n            }\n        }\n    }\n\n    synchronized public JMethodIdTableEntry getEntry(int methodId) {\n        int pos = hash(methodId) % size;\n\n        while ((entries[pos] != null) && (entries[pos].methodId != methodId)) {\n            pos = (pos + 1) % size;\n        }\n\n        return entries[pos];\n    }\n\n    synchronized public void getNamesForMethodIds(ProfilerClient profilerClient)\n                                    throws ClientUtils.TargetAppOrVMTerminated {\n        if (staticTable) {\n            throw new IllegalStateException(\"Attempt to update snapshot JMethodIdTable\"); // NOI18N\n        }\n\n        if (incompleteEntries == 0) {\n            return;\n        }\n\n        int[] missingNameMethodIds = new int[incompleteEntries];\n        int idx = 0;\n\n        for (JMethodIdTableEntry entrie : entries) {\n            if (entrie == null) {\n                continue;\n            }\n            if (entrie.className == null) {\n                missingNameMethodIds[idx++] = entrie.methodId;\n            }\n        }\n\n        String[][] methodClassNameAndSig = profilerClient.getMethodNamesForJMethodIds(missingNameMethodIds);\n\n        for (int i = 0; i < missingNameMethodIds.length; i++) {\n            completeEntry(missingNameMethodIds[i], methodClassNameAndSig[0][i], methodClassNameAndSig[1][i],\n                          methodClassNameAndSig[2][i], getBoolean(methodClassNameAndSig[3][i]));\n        }\n\n        incompleteEntries = 0;\n    }\n\n    void addEntry(int methodId, String className, String methodName, String methodSig, boolean isNative) {\n        checkMethodId(methodId);\n        completeEntry(methodId, className, methodName, methodSig, isNative);\n    }\n\n    synchronized public void checkMethodId(int methodId) {\n        int pos = hash(methodId) % size;\n\n        while (entries[pos] != null) {\n            if (entries[pos].methodId == methodId) {\n                return;\n            }\n\n            pos = (pos + 1) % size;\n        }\n\n        if (nElements < threshold) {\n            entries[pos] = new JMethodIdTableEntry(methodId);\n            nElements++;\n            incompleteEntries++;\n\n            return;\n        } else {\n            growTable();\n            checkMethodId(methodId);\n        }\n    }\n\n    synchronized private void completeEntry(int methodId, String className, String methodName, String methodSig, boolean isNative) {\n        int pos = hash(methodId) % size;\n\n        while (entries[pos].methodId != methodId) {\n            pos = (pos + 1) % size;\n        }\n\n        entries[pos].className = className;\n        entries[pos].methodName = methodName;\n        entries[pos].methodSig = methodSig;\n        entries[pos].isNative = isNative;\n    }\n\n    private void growTable() {\n        JMethodIdTableEntry[] oldEntries = entries;\n        size = (size * 2) + 1;\n        threshold = (size * 3) / 4;\n        entries = new JMethodIdTableEntry[size];\n\n        for (JMethodIdTableEntry oldEntry : oldEntries) {\n            if (oldEntry != null) {\n                int pos = hash(oldEntry.methodId) % size;\n\n                while (entries[pos] != null) {\n                    pos = (pos + 1) % size;\n                }\n\n                entries[pos] = oldEntry;\n            }\n        }\n    }\n\n    private int hash(int x) {\n        return ((x >> 2) * 123457) & 0xFFFFFFF;\n    }\n    \n    private boolean getBoolean(String boolStr) {\n        return \"1\".equals(boolStr);       // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/LivenessMemoryResultsDiff.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.Map;\n\n\n/**\n * Class representing a difference between two snapshots,\n * diffing only values available in LivenessMemoryResultsSnapshot\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic class LivenessMemoryResultsDiff extends LivenessMemoryResultsSnapshot {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final LivenessMemoryResultsSnapshot snapshot1;\n    private final LivenessMemoryResultsSnapshot snapshot2;\n\n    private float[] avgObjectAge;\n    private String[] classNames;\n    private int[] maxSurvGen;\n    private int[] nTotalAllocObjects;\n\n    //  private int[] objectsCounts;\n    private long[] objectsSizePerClass;\n    private long[] nTrackedAllocObjects;\n    private int[] nTrackedLiveObjects;\n    private long[] trackedLiveObjectsSize;\n    private int nClasses;\n    private long maxTrackedLiveObjectsSizeDiff;\n    private long minTrackedLiveObjectsSizeDiff;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public LivenessMemoryResultsDiff(LivenessMemoryResultsSnapshot snapshot1, LivenessMemoryResultsSnapshot snapshot2) {\n        this.snapshot1 = snapshot1;\n        this.snapshot2 = snapshot2;\n\n        computeDiff(snapshot1, snapshot2);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public float[] getAvgObjectAge() {\n        return avgObjectAge;\n    }\n\n    public long getBeginTime() {\n        return -1;\n    }\n\n    public String getClassName(int classId) {\n        return classNames[classId];\n    }\n\n    public String[] getClassNames() {\n        return classNames;\n    }\n\n    public JMethodIdTable getJMethodIdTable() {\n        return null;\n    }\n\n    public int[] getMaxSurvGen() {\n        return maxSurvGen;\n    }\n\n    public long getMaxTrackedLiveObjectsSizeDiff() {\n        return maxTrackedLiveObjectsSizeDiff;\n    }\n\n    public long getMaxValue() {\n        return -1;\n    }\n\n    public long getMinTrackedLiveObjectsSizeDiff() {\n        return minTrackedLiveObjectsSizeDiff;\n    }\n\n    // seems to be unused in LivenessMemoryResultsSnapshot\n    public int getNAlloc() {\n        return getNProfiledClasses();\n    }\n\n    public int getNInstrClasses() {\n        return getNProfiledClasses();\n    }\n\n    public int getNProfiledClasses() {\n        return nClasses;\n    }\n\n    public long getNTotalTracked() {\n        return -1;\n    }\n\n    public long getNTotalTrackedBytes() {\n        return -1;\n    }\n\n    //---\n    public long[] getNTrackedAllocObjects() {\n        return nTrackedAllocObjects;\n    }\n\n    public int getNTrackedItems() {\n        return getNProfiledClasses();\n    }\n\n    public int[] getNTrackedLiveObjects() {\n        return nTrackedLiveObjects;\n    }\n\n    public long[] getObjectsSizePerClass() {\n        return objectsSizePerClass;\n    }\n\n    public long getTimeTaken() {\n        return -1;\n    }\n\n    public long[] getTrackedLiveObjectsSize() {\n        return trackedLiveObjectsSize;\n    }\n\n    public boolean containsStacks() {\n        return false;\n    }\n\n    public PresoObjLivenessCCTNode createPresentationCCT(int classId, boolean dontShowZeroLiveObjAllocPaths) {\n        int selectId1 = classId1(classId);\n        int selectId2 = classId2(classId);\n        PresoObjLivenessCCTNode node1 = null;\n        PresoObjLivenessCCTNode node2 = null;\n\n        if (selectId1 != -1) {\n            node1 = snapshot1.createPresentationCCT(selectId1, dontShowZeroLiveObjAllocPaths);\n        }\n        if (selectId2 != -1) {\n            node2 = snapshot2.createPresentationCCT(selectId2, dontShowZeroLiveObjAllocPaths);\n        }\n        return new DiffObjLivenessCCTNode(node1, node2);\n    }\n\n    public int[] getnTotalAllocObjects() {\n        return nTotalAllocObjects;\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        throw new UnsupportedOperationException(\"Persistence not supported for snapshot comparison\"); // NOI18N\n    }\n\n    //---- Serialization support\n    public void writeToStream(DataOutputStream out) throws IOException {\n        throw new UnsupportedOperationException(\"Persistence not supported for snapshot comparison\"); // NOI18N\n    }\n\n    protected PresoObjLivenessCCTNode createPresentationCCT(RuntimeMemoryCCTNode rootNode, int classId,\n                                                         boolean dontShowZeroLiveObjAllocPaths) {\n        int selectId1 = classId1(classId);\n        int selectId2 = classId2(classId);\n        PresoObjLivenessCCTNode node1 = null;\n        PresoObjLivenessCCTNode node2 = null;\n\n        if (selectId1 != -1) {\n            node1 = snapshot1.createPresentationCCT(rootNode, selectId1, dontShowZeroLiveObjAllocPaths);\n        }\n        if (selectId2 != -1) {\n            node2 = snapshot2.createPresentationCCT(rootNode, selectId2, dontShowZeroLiveObjAllocPaths);\n        }\n        return new DiffObjLivenessCCTNode(node1, node2);\n    }\n    \n    private int classId1(int classId) {\n        return classId(classId, snapshot1);\n    }\n    \n    private int classId2(int classId) {\n        return classId(classId, snapshot2);\n    }\n    \n    private int classId(int classId, LivenessMemoryResultsSnapshot snapshot) {\n        if (snapshot == null) return -1;\n        \n        String className = getClassName(classId);\n        String[] classNames = snapshot.getClassNames();\n        if (classNames == null) return -1;\n        \n        for (int i = 0; i < classNames.length; i++)\n            if (classNames[i].equals(className)) return i;\n        \n        return -1;\n    }\n\n    private void computeDiff(LivenessMemoryResultsSnapshot snapshot1, LivenessMemoryResultsSnapshot snapshot2) {\n        // number of classes in snapshots\n        int s1nClasses = snapshot1.getNTrackedItems();\n        int s2nClasses = snapshot2.getNTrackedItems();\n\n        // temporary cache for creating diff\n        HashMap<String, Integer> classNamesIdxMap = new HashMap(s1nClasses);\n        ArrayList<Long> nTrackedAllocObjectsArr = new ArrayList(s1nClasses);\n        ArrayList<Long> objectsSizePerClassArr = new ArrayList(s1nClasses);\n        ArrayList<Integer> nTrackedLiveObjectsArr = new ArrayList(s1nClasses);\n        ArrayList<Integer> maxSurvGenArr = new ArrayList(s1nClasses);\n        ArrayList<Float> avgObjectAgeArr = new ArrayList(s1nClasses);\n        ArrayList<Long> trackedLiveObjectsSizeArr = new ArrayList(s1nClasses);\n        ArrayList<Integer> nTotalAllocObjectsArr = new ArrayList(s1nClasses);\n\n        // fill the cache with negative values from snapshot1\n        String[] s1ClassNames = snapshot1.getClassNames();\n        long[] s1NTrackedAllocObjects = snapshot1.getNTrackedAllocObjects();\n        long[] s1ObjectsSizePerClass = snapshot1.getObjectsSizePerClass();\n        int[] s1NTrackedLiveObjects = snapshot1.getNTrackedLiveObjects();\n        int[] s1MaxSurvGen = snapshot1.getMaxSurvGen();\n        float[] s1AvgObjectAge = snapshot1.getAvgObjectAge();\n        long[] s1TrackedLiveObjectsSize = snapshot1.getTrackedLiveObjectsSize();\n        int[] s1NTotalAllocObjects = snapshot1.getnTotalAllocObjects();\n\n        int idx = 0;\n\n        for (int i = 0; i < s1nClasses; i++) {\n//            if (s1NTotalAllocObjects[i] > 0) {\n                Integer classIdx = classNamesIdxMap.get(s1ClassNames[i]);\n\n                if (classIdx != null) { // duplicate classname\n                    nTrackedAllocObjectsArr.set(classIdx, nTrackedAllocObjectsArr.get(classIdx) - s1NTrackedAllocObjects[i]);\n                    objectsSizePerClassArr.set(classIdx, objectsSizePerClassArr.get(classIdx) - s1ObjectsSizePerClass[i]);\n                    nTrackedLiveObjectsArr.set(classIdx, nTrackedLiveObjectsArr.get(classIdx) - s1NTrackedLiveObjects[i]);\n                    maxSurvGenArr.set(classIdx, maxSurvGenArr.get(classIdx) - s1MaxSurvGen[i]);\n                    avgObjectAgeArr.set(classIdx, avgObjectAgeArr.get(classIdx) - s1AvgObjectAge[i]);\n                    trackedLiveObjectsSizeArr.set(classIdx, trackedLiveObjectsSizeArr.get(classIdx) - s1TrackedLiveObjectsSize[i]);\n                    nTotalAllocObjectsArr.set(classIdx, nTotalAllocObjectsArr.get(classIdx) - s1NTotalAllocObjects[i]);\n                } else {\n                    classNamesIdxMap.put(s1ClassNames[i], idx++);\n                    nTrackedAllocObjectsArr.add(-s1NTrackedAllocObjects[i]);\n                    objectsSizePerClassArr.add(-s1ObjectsSizePerClass[i]);\n                    nTrackedLiveObjectsArr.add(-s1NTrackedLiveObjects[i]);\n                    maxSurvGenArr.add(-s1MaxSurvGen[i]);\n                    avgObjectAgeArr.add(-s1AvgObjectAge[i]);\n                    trackedLiveObjectsSizeArr.add(-s1TrackedLiveObjectsSize[i]);\n                    nTotalAllocObjectsArr.add(-s1NTotalAllocObjects[i]);\n                }\n//            }\n        }\n\n        // create diff using values from snapshot2\n        String[] s2ClassNames = snapshot2.getClassNames();\n        long[] s2NTrackedAllocObjects = snapshot2.getNTrackedAllocObjects();\n        long[] s2ObjectsSizePerClass = snapshot2.getObjectsSizePerClass();\n        int[] s2NTrackedLiveObjects = snapshot2.getNTrackedLiveObjects();\n        int[] s2MaxSurvGen = snapshot2.getMaxSurvGen();\n        float[] s2AvgObjectAge = snapshot2.getAvgObjectAge();\n        long[] s2TrackedLiveObjectsSize = snapshot2.getTrackedLiveObjectsSize();\n        int[] s2NTotalAllocObjects = snapshot2.getnTotalAllocObjects();\n\n        for (int i = 0; i < s2nClasses; i++) {\n//            if (s2NTotalAllocObjects[i] > 0) {\n                Integer classIdx = classNamesIdxMap.get(s2ClassNames[i]);\n\n                if (classIdx != null) {\n                    // class already present in snapshot1\n                    nTrackedAllocObjectsArr.set(classIdx, nTrackedAllocObjectsArr.get(classIdx) + s2NTrackedAllocObjects[i]);\n                    objectsSizePerClassArr.set(classIdx, objectsSizePerClassArr.get(classIdx) + s2ObjectsSizePerClass[i]);\n                    nTrackedLiveObjectsArr.set(classIdx, nTrackedLiveObjectsArr.get(classIdx) + s2NTrackedLiveObjects[i]);\n                    maxSurvGenArr.set(classIdx, maxSurvGenArr.get(classIdx) + s2MaxSurvGen[i]);\n                    avgObjectAgeArr.set(classIdx, avgObjectAgeArr.get(classIdx) + s2AvgObjectAge[i]);\n                    trackedLiveObjectsSizeArr.set(classIdx, trackedLiveObjectsSizeArr.get(classIdx) + s2TrackedLiveObjectsSize[i]);\n                    nTotalAllocObjectsArr.set(classIdx, nTotalAllocObjectsArr.get(classIdx) + s2NTotalAllocObjects[i]);\n                } else {\n                    // class not present in snapshot1\n                    classNamesIdxMap.put(s2ClassNames[i], nTrackedAllocObjectsArr.size());\n                    nTrackedAllocObjectsArr.add(s2NTrackedAllocObjects[i]);\n                    objectsSizePerClassArr.add(s2ObjectsSizePerClass[i]);\n                    nTrackedLiveObjectsArr.add(s2NTrackedLiveObjects[i]);\n                    maxSurvGenArr.add(s2MaxSurvGen[i]);\n                    avgObjectAgeArr.add(s2AvgObjectAge[i]);\n                    trackedLiveObjectsSizeArr.add(s2TrackedLiveObjectsSize[i]);\n                    nTotalAllocObjectsArr.add(s2NTotalAllocObjects[i]);\n                }\n//            }\n        }\n\n        // move the diff to instance variables\n        nClasses = classNamesIdxMap.size();\n        classNames = new String[nClasses];\n        nTrackedAllocObjects = new long[nClasses];\n        objectsSizePerClass = new long[nClasses];\n        nTrackedLiveObjects = new int[nClasses];\n        maxSurvGen = new int[nClasses];\n        avgObjectAge = new float[nClasses];\n        trackedLiveObjectsSize = new long[nClasses];\n        nTotalAllocObjects = new int[nClasses];\n        minTrackedLiveObjectsSizeDiff = Integer.MAX_VALUE;\n        maxTrackedLiveObjectsSizeDiff = Integer.MIN_VALUE;\n\n        Iterator<Map.Entry<String, Integer>> classNamesIter = classNamesIdxMap.entrySet().iterator();\n        int index = 0;\n\n        while (classNamesIter.hasNext()) {\n            Map.Entry<String, Integer> entry = classNamesIter.next();\n            int classIndex = entry.getValue();\n\n            classNames[index] = entry.getKey();\n            nTrackedAllocObjects[index] = nTrackedAllocObjectsArr.get(classIndex);\n            objectsSizePerClass[index] = objectsSizePerClassArr.get(classIndex);\n            nTrackedLiveObjects[index] = nTrackedLiveObjectsArr.get(classIndex);\n            maxSurvGen[index] = maxSurvGenArr.get(classIndex);\n            avgObjectAge[index] = avgObjectAgeArr.get(classIndex);\n            trackedLiveObjectsSize[index] = trackedLiveObjectsSizeArr.get(classIndex);\n            nTotalAllocObjects[index] = nTotalAllocObjectsArr.get(classIndex);\n\n            minTrackedLiveObjectsSizeDiff = Math.min(minTrackedLiveObjectsSizeDiff, trackedLiveObjectsSize[index]);\n            maxTrackedLiveObjectsSizeDiff = Math.max(maxTrackedLiveObjectsSizeDiff, trackedLiveObjectsSize[index]);\n\n            index++;\n        }\n\n        if ((minTrackedLiveObjectsSizeDiff > 0) && (maxTrackedLiveObjectsSizeDiff > 0)) {\n            minTrackedLiveObjectsSizeDiff = 0;\n        } else if ((minTrackedLiveObjectsSizeDiff < 0) && (maxTrackedLiveObjectsSizeDiff < 0)) {\n            maxTrackedLiveObjectsSizeDiff = 0;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/LivenessMemoryResultsSnapshot.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.util.logging.Level;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils.TargetAppOrVMTerminated;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.text.MessageFormat;\nimport java.util.ResourceBundle;\n\n\n/**\n * Results snapshot for Allocations Memory Profiling.\n *\n * @author Ian Formanek\n */\npublic class LivenessMemoryResultsSnapshot extends MemoryResultsSnapshot {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String MEMORY_LIVENESS_MSG = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.memory.Bundle\").getString(\"LivenessMemoryResultsSnapshot_MemoryLivenessMsg\"); // NOI18N\n                                                                                                                             // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    /** [0 - nProfiledClasses] index: classId, average object age for class */\n    private float[] avgObjectAge;\n\n    /** [0 - nProfiledClasses] index: classId, contains tracked live instrances # for this class -\n     * assumption: smaller than allocated, thus only int */\n    private int[] maxSurvGen;\n    private int[] nTotalAllocObjects;\n\n    /** [0 - nProfiledClasses] index: classId, contains tracked allocated instrances # for this class */\n    private long[] nTrackedAllocObjects;\n    private int[] nTrackedLiveObjects;\n    private long[] trackedLiveObjectsSize;\n    private int currentEpoch;\n\n    /** used to keep track of total allocations number, which is in turn needed to monitor\n     * JFluid tool's used heap space */\n    private int nInstrClasses;\n    private int nTotalTracked;\n    private int nTrackedItems;\n    private long maxValue;\n    private long nTotalTrackedBytes;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public LivenessMemoryResultsSnapshot() {\n    } // No-arg constructor needed for above serialization methods to work\n\n    public LivenessMemoryResultsSnapshot(long beginTime, long timeTaken, MemoryCCTProvider provider, ProfilerClient client)\n                                  throws TargetAppOrVMTerminated {\n        super(beginTime, timeTaken, provider, client);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @return An average object age for each class\n     */\n    public float[] getAvgObjectAge() {\n        return avgObjectAge;\n    }\n\n    /**\n     * @return An array of maximum number of surviving generations for each class\n     */\n    public int[] getMaxSurvGen() {\n        return maxSurvGen;\n    }\n\n    public long getMaxValue() {\n        return maxValue;\n    }\n\n    /**\n     * @return Number of classes\n     */\n    public int getNAlloc() {\n        return nInstrClasses;\n    }\n\n    public int getNInstrClasses() {\n        return nInstrClasses;\n    }\n\n    public long getNTotalTracked() {\n        return nTotalTracked;\n    }\n\n    public long getNTotalTrackedBytes() {\n        return nTotalTrackedBytes;\n    }\n\n    /**\n     * @return An array of number of tracked allocations for each class\n     */\n    public long[] getNTrackedAllocObjects() {\n        return nTrackedAllocObjects;\n    }\n\n    public int getNTrackedItems() {\n        return nTrackedItems;\n    }\n\n    /**\n     * @return An array of number of tracked live objects for each class\n     */\n    public int[] getNTrackedLiveObjects() {\n        return nTrackedLiveObjects;\n    }\n\n    public long[] getTrackedLiveObjectsSize() {\n        return trackedLiveObjectsSize;\n    }\n\n    public int[] getnTotalAllocObjects() {\n        return nTotalAllocObjects;\n    }\n\n    public void performInit(ProfilerClient client, MemoryCCTProvider provider)\n                     throws TargetAppOrVMTerminated {\n        super.performInit(client, provider);\n        \n        MemoryCCTProvider.ObjectNumbersContainer onc = provider.getLivenessObjectNumbers();\n\n        int len;\n        len = onc.nTrackedAllocObjects.length;\n        nTrackedAllocObjects = new long[len];\n        System.arraycopy(onc.nTrackedAllocObjects, 0, nTrackedAllocObjects, 0, len);\n        len = onc.nTrackedLiveObjects.length;\n        nTrackedLiveObjects = new int[len];\n        System.arraycopy(onc.nTrackedLiveObjects, 0, nTrackedLiveObjects, 0, len);\n        len = onc.trackedLiveObjectsSize.length;\n        trackedLiveObjectsSize = new long[len];\n        System.arraycopy(onc.trackedLiveObjectsSize, 0, trackedLiveObjectsSize, 0, len);\n        len = onc.avgObjectAge.length;\n        avgObjectAge = new float[len];\n        System.arraycopy(onc.avgObjectAge, 0, avgObjectAge, 0, len);\n        len = onc.maxSurvGen.length;\n        maxSurvGen = new int[len];\n        System.arraycopy(onc.maxSurvGen, 0, maxSurvGen, 0, len);\n\n        nInstrClasses = onc.nInstrClasses;\n\n        int[] tmp = client.getAllocatedObjectsCountResults();\n        len = tmp.length;\n        nTotalAllocObjects = new int[len];\n        System.arraycopy(tmp, 0, nTotalAllocObjects, 0, len);\n\n        // Below is a bit of \"defensive programming\". Normally the sizes of arrays here should be same\n        // except for nTotalAllocObjects, that is returned from the server, and may be shorter if some\n        // instrumented classes have not propagated to the server yet.\n        nTrackedItems = Math.min(nTrackedAllocObjects.length, nTrackedLiveObjects.length);\n        nTrackedItems = Math.min(nTrackedItems, trackedLiveObjectsSize.length);\n        nTrackedItems = Math.min(nTrackedItems, avgObjectAge.length);\n        nTrackedItems = Math.min(nTrackedItems, maxSurvGen.length);\n        nTrackedItems = Math.min(nTrackedItems, nInstrClasses);\n        nTrackedItems = Math.min(nTrackedItems, nTotalAllocObjects.length);\n\n        // Now if some classes are unprofiled, reflect that in nTotalAllocObjects\n        //for (int i = 0; i < nTrackedAllocObjects.length; i++) {\n        for (int i = 0; i < nTrackedItems; i++) {\n            if (nTrackedAllocObjects[i] == -1) {\n                nTotalAllocObjects[i] = 0;\n            }\n        }\n\n        // Operations necessary for correct bar representation of results\n        maxValue = 0;\n        nTotalTrackedBytes = 0;\n        nTotalTracked = 0;\n\n        //for (int i = 0; i < trackedLiveObjectsSize.length; i++) {\n        for (int i = 0; i < nTrackedItems; i++) {\n            if (maxValue < trackedLiveObjectsSize[i]) {\n                maxValue = trackedLiveObjectsSize[i];\n            }\n\n            nTotalTrackedBytes += trackedLiveObjectsSize[i];\n            nTotalTracked += nTrackedLiveObjects[i];\n        }\n\n        currentEpoch = provider.getCurrentEpoch();\n    }\n    \n    public LivenessMemoryResultsSnapshot createDiff(MemoryResultsSnapshot snapshot) {\n        if (!(snapshot instanceof LivenessMemoryResultsSnapshot)) return null;\n        return new LivenessMemoryResultsDiff(this, (LivenessMemoryResultsSnapshot)snapshot);\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        super.readFromStream(in);\n\n        int len = in.readInt();\n        nTrackedAllocObjects = new long[len];\n\n        for (int i = 0; i < len; i++) {\n            nTrackedAllocObjects[i] = in.readLong();\n        }\n\n        len = in.readInt();\n        nTrackedLiveObjects = new int[len];\n\n        for (int i = 0; i < len; i++) {\n            nTrackedLiveObjects[i] = in.readInt();\n        }\n\n        len = in.readInt();\n        maxSurvGen = new int[len];\n\n        for (int i = 0; i < len; i++) {\n            maxSurvGen[i] = in.readInt();\n        }\n\n        len = in.readInt();\n        trackedLiveObjectsSize = new long[len];\n\n        for (int i = 0; i < len; i++) {\n            trackedLiveObjectsSize[i] = in.readLong();\n        }\n\n        len = in.readInt();\n        avgObjectAge = new float[len];\n\n        for (int i = 0; i < len; i++) {\n            avgObjectAge[i] = in.readFloat();\n        }\n\n        nInstrClasses = in.readInt();\n\n        len = in.readInt();\n        nTotalAllocObjects = new int[len];\n\n        for (int i = 0; i < len; i++) {\n            nTotalAllocObjects[i] = in.readInt();\n        }\n\n        nTrackedItems = in.readInt();\n        maxValue = in.readLong();\n        nTotalTrackedBytes = in.readLong();\n        nTotalTracked = in.readInt();\n        currentEpoch = in.readInt();\n    }\n\n    public String toString() {\n        return MessageFormat.format(MEMORY_LIVENESS_MSG, new Object[] { super.toString() });\n    }\n\n    //---- Serialization support\n    public void writeToStream(DataOutputStream out) throws IOException {\n        super.writeToStream(out);\n\n        out.writeInt(nTrackedAllocObjects.length);\n\n        for (int i = 0; i < nTrackedAllocObjects.length; i++) {\n            out.writeLong(nTrackedAllocObjects[i]);\n        }\n\n        out.writeInt(nTrackedLiveObjects.length);\n\n        for (int i = 0; i < nTrackedLiveObjects.length; i++) {\n            out.writeInt(nTrackedLiveObjects[i]);\n        }\n\n        out.writeInt(maxSurvGen.length);\n\n        for (int i = 0; i < maxSurvGen.length; i++) {\n            out.writeInt(maxSurvGen[i]);\n        }\n\n        out.writeInt(trackedLiveObjectsSize.length);\n\n        for (int i = 0; i < trackedLiveObjectsSize.length; i++) {\n            out.writeLong(trackedLiveObjectsSize[i]);\n        }\n\n        out.writeInt(avgObjectAge.length);\n\n        for (int i = 0; i < avgObjectAge.length; i++) {\n            out.writeFloat(avgObjectAge[i]);\n        }\n\n        out.writeInt(nInstrClasses);\n\n        out.writeInt(nTotalAllocObjects.length);\n\n        for (int i = 0; i < nTotalAllocObjects.length; i++) {\n            out.writeInt(nTotalAllocObjects[i]);\n        }\n\n        out.writeInt(nTrackedItems);\n        out.writeLong(maxValue);\n        out.writeLong(nTotalTrackedBytes);\n        out.writeInt(nTotalTracked);\n        out.writeInt(currentEpoch);\n    }\n    \n    public PresoObjLivenessCCTNode createPresentationCCT(int classId, boolean dontShowZeroLiveObjAllocPaths) {\n        return (PresoObjLivenessCCTNode)super.createPresentationCCT(classId, dontShowZeroLiveObjAllocPaths);\n    }\n\n    protected PresoObjLivenessCCTNode createPresentationCCT(RuntimeMemoryCCTNode rootNode, int classId,\n                                                         boolean dontShowZeroLiveObjAllocPaths) {\n        return PresoObjLivenessCCTNode.createPresentationCCTFromSnapshot(this, rootNode, getClassName(classId), currentEpoch,\n                                                                         dontShowZeroLiveObjAllocPaths);\n    }\n\n    void debugValues() {\n        super.debugValues();\n        LOGGER.log(Level.FINEST, \"nTrackedAllocObjects.length: {0}\", debugLength(nTrackedAllocObjects));\n        LOGGER.log(Level.FINEST, \"nTrackedLiveObjects.length: {0}\", debugLength(nTrackedLiveObjects));\n        LOGGER.log(Level.FINEST, \"maxSurvGen.length: {0}\", debugLength(maxSurvGen)); // NOI18N\n        LOGGER.log(Level.FINEST, \"trackedLiveObjectsSize.length: {0}\", debugLength(trackedLiveObjectsSize));\n        LOGGER.log(Level.FINEST, \"avgObjectAge.length: {0}\", debugLength(avgObjectAge)); // NOI18N\n        LOGGER.log(Level.FINEST, \"nInstrClasses: {0}\", nInstrClasses); // NOI18N\n        LOGGER.log(Level.FINEST, \"nTotalAllocObjects.length: {0}\", debugLength(nTotalAllocObjects)); // NOI18N\n        LOGGER.log(Level.FINEST, \"nTrackedItems: {0}\", nTrackedItems); // NOI18N\n        LOGGER.log(Level.FINEST, \"maxValue: {0}\", maxValue); // NOI18N\n        LOGGER.log(Level.FINEST, \"nTotalTrackedBytes: {0}\", nTotalTrackedBytes); // NOI18N\n        LOGGER.log(Level.FINEST, \"nTotalTracked: {0}\", nTotalTracked); // NOI18N\n        LOGGER.log(Level.FINEST, \"currentEpoch: {0}\", currentEpoch); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/MemoryCCTManager.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\n\n/**\n * Management of the reverse call graph representation for object allocations call paths.\n *\n * @author Misha Dmitriev\n */\npublic class MemoryCCTManager {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private PresoObjAllocCCTNode rootNode;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    //  public MemoryCCTManager(MemoryCCTProvider provider, int classId, boolean dontShowZeroLiveObjAllocPaths)\n    //      throws ClientUtils.TargetAppOrVMTerminated {\n    //    rootNode = provider.createPresentationCCT(classId, dontShowZeroLiveObjAllocPaths);\n    //  }\n    public MemoryCCTManager(MemoryResultsSnapshot snapshot, int classId, boolean dontShowZeroLiveObjAllocPaths) {\n        rootNode = snapshot.createPresentationCCT(classId, dontShowZeroLiveObjAllocPaths);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @return true if the allocation stack traces are empty (and the getRootNode returns null), false otherwise\n     * @see #getRootNode()\n     */\n    public boolean isEmpty() {\n        return rootNode == null;\n    }\n\n    /**\n     * @return The root noe of allocation stack traces or null if empty.\n     * @see #isEmpty()\n     */\n    public PresoObjAllocCCTNode getRootNode() {\n        return rootNode;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/MemoryCCTProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTProvider;\n\n\n/**\n * @author Jaroslav Bachorik\n */\npublic interface MemoryCCTProvider extends CCTProvider {\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    public static interface Listener extends CCTProvider.Listener {\n    }\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    // *****************************************************\n\n    /**\n     * A container class, needed just for correct data transfer to its consumers.\n     * @author Misha Dmitirev\n     */\n    public static class ObjectNumbersContainer {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        public float[] avgObjectAge;\n        public int[] maxSurvGen;\n        public long[] nTrackedAllocObjects;\n        public int[] nTrackedLiveObjects;\n        public long[] trackedLiveObjectsSize;\n        public int nInstrClasses;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ObjectNumbersContainer(long[] nTrackedAllocObjects, int[] nTrackedLiveObjects, long[] trackedLiveObjectsSize,\n                               float[] avgObjectAge, int[] maxSurvGen, boolean[] unprofiledClass, int nProfiledClasses) {\n            nInstrClasses = nProfiledClasses;\n\n            int len = nProfiledClasses;\n            this.nTrackedAllocObjects = new long[len];\n            this.nTrackedLiveObjects = new int[len];\n            this.trackedLiveObjectsSize = new long[len];\n            this.avgObjectAge = avgObjectAge;\n            this.maxSurvGen = maxSurvGen;\n\n            if (nTrackedAllocObjects != null) {\n                System.arraycopy(nTrackedAllocObjects, 0, this.nTrackedAllocObjects, 0, len);\n            }\n\n            if (nTrackedLiveObjects != null) {\n                System.arraycopy(nTrackedLiveObjects, 0, this.nTrackedLiveObjects, 0, len);\n            }\n\n            if (trackedLiveObjectsSize != null) {\n                System.arraycopy(trackedLiveObjectsSize, 0, this.trackedLiveObjectsSize, 0, len);\n            }\n\n            for (int i = 0; i < unprofiledClass.length; i++) {\n                if (unprofiledClass[i]) {\n                    this.nTrackedAllocObjects[i] = -1; // Special value\n                    this.nTrackedLiveObjects[i] = 0;\n                    this.trackedLiveObjectsSize[i] = 0;\n                    this.avgObjectAge[i] = 0.0f;\n                    this.maxSurvGen[i] = 0;\n                }\n            }\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    long[] getAllocObjectNumbers();\n\n    int getCurrentEpoch();\n\n    ObjectNumbersContainer getLivenessObjectNumbers();\n\n    // following methods should be used only temporarily\n    int getNProfiledClasses();\n\n    long[] getObjectsSizePerClass();\n\n    RuntimeMemoryCCTNode[] getStacksForClasses();\n\n    void beginTrans(boolean mutable);\n\n    boolean classMarkedUnprofiled(int classId);\n\n    PresoObjAllocCCTNode createPresentationCCT(int classId, boolean dontShowZeroLiveObjAllocPaths)\n                                        throws ClientUtils.TargetAppOrVMTerminated;\n\n    void endTrans();\n\n    /**\n     * Marks the class with the given id as \"unprofiled\". Instrumentation for the class is not removed at this point.\n     */\n    void markClassUnprofiled(int classId);\n\n    void updateInternals();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/MemoryCallGraphBuilder.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.client.ProfilingPointsProcessor;\nimport org.graalvm.visualvm.lib.jfluid.client.RuntimeProfilingPoint;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.TransactionalSupport;\nimport org.graalvm.visualvm.lib.jfluid.results.BaseCallGraphBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\n\n\n/**\n * @author Misha Dmitirev\n * @author Jaroslav Bachorik\n */\npublic class MemoryCallGraphBuilder extends BaseCallGraphBuilder implements MemoryProfilingResultsListener, MemoryCCTProvider {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    /**\n     * A hashtable specialized for mapping object ids to references to the respective CCT terminating nodes.\n     * <p/>\n     * Only used for updating of existing structures with new data.\n     */\n    private static class ObjIdToCCTNodeMap {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        /** [0-capacity] individual tracked instances Ids, also replicated at the server side -\n         * bit combination opf epoch, classId & sequential counter */\n        private long[] keys;\n\n        /** [0-capacity] size in Bytes of tracked instance */\n        private long[] objSize;\n\n        /** [0-capacity] pointer to the \"Term\" node containing data - see RuntimeObjLivenessTermCCTNode */\n        private RuntimeObjLivenessTermCCTNode[] values;\n        private int capacity;\n        private int k;\n        private int nObjects;\n        private int threshold; // nObjects - number of tracked objects\n        private long a = 5700357409661599241L;\n        private long lastRemovedObjSize;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ObjIdToCCTNodeMap() {\n            init();\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public long getLastRemovedObjSize() {\n            return lastRemovedObjSize;\n        }\n\n        public RuntimeObjLivenessTermCCTNode getNode(long key) {\n            int pos = hash(key);\n            long keyAtPos = keys[pos];\n            int iter = capacity >> 2;\n\n            while ((keyAtPos != key) && (iter > 0)) { // -1 after a large num of iterations can happen only if \"reset collectors\" was performed\n                pos = (pos + 1) % capacity;\n                keyAtPos = keys[pos];\n                iter--;\n            }\n\n            if (iter == 0) {\n                return null;\n            }\n\n            keys[pos] = -1;\n\n            RuntimeObjLivenessTermCCTNode ret = values[pos];\n            values[pos] = null;\n            lastRemovedObjSize = objSize[pos];\n            nObjects--;\n\n            return ret;\n        }\n\n        public void clear() {\n            keys = null;\n            values = null;\n            init();\n        }\n\n        public void put(long key, RuntimeObjLivenessTermCCTNode value, long size) {\n            if (nObjects > threshold) {\n                rehash();\n            }\n\n            int pos = hash(key);\n\n            while (keys[pos] != -1) {\n                pos = (pos + 1) % capacity;\n            }\n\n            keys[pos] = key;\n            values[pos] = value;\n            objSize[pos] = size;\n            nObjects++;\n        }\n\n        public int sizeInBytes() {\n            return (keys.length * 8) + (values.length * 4) + (objSize.length * 8);\n        }\n\n        private void setThreshold() {\n            threshold = (capacity * 3) / 4;\n        }\n\n        private int hash(long key) {\n            return (int) ((key * a) >>> (64 - k));\n        }\n\n        private void init() {\n            capacity = 1024;\n            k = 10; // 2^k == capacity\n            nObjects = 0;\n            setThreshold();\n            keys = new long[capacity];\n\n            for (int i = 0; i < capacity; i++) {\n                keys[i] = -1;\n            }\n\n            values = new RuntimeObjLivenessTermCCTNode[capacity];\n            objSize = new long[capacity];\n        }\n\n        private void rehash() {\n            long[] oldKeys = keys;\n            RuntimeObjLivenessTermCCTNode[] oldValues = values;\n            long[] oldObjSize = objSize;\n            int oldCapacity = capacity;\n            capacity = capacity * 2;\n            k++;\n            keys = new long[capacity];\n\n            for (int i = 0; i < capacity; i++) {\n                keys[i] = -1;\n            }\n\n            values = new RuntimeObjLivenessTermCCTNode[capacity];\n            objSize = new long[capacity];\n\n            for (int i = 0; i < oldCapacity; i++) {\n                if (oldKeys[i] != -1) {\n                    int pos = hash(oldKeys[i]);\n\n                    while (keys[pos] != -1) {\n                        pos = (pos + 1) % capacity;\n                    }\n\n                    keys[pos] = oldKeys[i];\n                    values[pos] = oldValues[i];\n                    objSize[pos] = oldObjSize[i];\n                }\n            }\n\n            setThreshold();\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    /** used to allow us to update the structures dynamically at runtime (maps internal objId to its corresponding\n     * RuntimeObjLivenessTermNode - table of surviving generations (same class & same allocation path))\n     */\n    private ObjIdToCCTNodeMap objMap;\n    private final TransactionalSupport transaction = new TransactionalSupport();\n\n    /**\n     * [0 - nProfiledClasses] index: classId, average object age for class\n     */\n    private float[] avgObjectAge;\n\n    /**\n     * [0 - nProfiledClasses] index: classId\n     */\n    private int[] maxSurvGen;\n\n    /** [0 - nProfiledClasses] index: classId, contains tracked allocated instances # for this class */\n    private long[] nTrackedAllocObjects;\n\n    /** [0 - nProfiledClasses] index: classId,\n     * contains tracked live instances # for this class - assumption: smaller than allocated, thus only int\n     */\n    private int[] nTrackedLiveObjects;\n    private long[] objectsSizePerClass; // [0-nProfiledClasses] total size in bytes for tracked instances of this class\n    private RuntimeMemoryCCTNode[] stacksForClasses; // [0-nProfiledClasses] class Id -> root of its allocation traces tree\n\n    /**\n     * [0 - nProfiledClasses] index: classId, if true, the class has been selected for not being profiled\n     */\n    private boolean[] unprofiledClass;\n\n    /**\n     * the latest GC, numbered from 0 (the first one)\n     */\n    private int currentEpoch;\n    private int nProfiledClasses; // total number of profiled classes\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public long[] getAllocObjectNumbers() {\n        transaction.beginTrans(false);\n\n        try {\n            long[] res = new long[nProfiledClasses];\n            System.arraycopy(objectsSizePerClass, 0, res, 0, res.length);\n\n            return res;\n        } finally {\n            transaction.endTrans();\n        }\n    }\n\n    // temporary methods for exposing builder's internals\n    public int getCurrentEpoch() {\n        transaction.beginTrans(false);\n\n        try {\n            return currentEpoch;\n        } finally {\n            transaction.endTrans();\n        }\n    }\n\n    public MemoryCCTProvider.ObjectNumbersContainer getLivenessObjectNumbers() {\n        transaction.beginTrans(false);\n\n        try {\n            if (getClient().getCurrentInstrType() != CommonConstants.INSTR_OBJECT_LIVENESS) {\n                throw new IllegalStateException(\"MemoryCallGraphBuilder must be running in TRACKING_LIVENESS mode in order to provide liveness statistics\"); // NOI18N\n            }\n\n            // Note that for average ages and epoch tails to be realistic we have to have all dead object removed from our data.\n            // That's currently more or less the case, since we call System.gc() before invoking \"get results\" when doing\n            // Object Liveness Profiling.\n            // However, it would be better if we had a native call to perform full GC, since System.gc() may be disabled easily.\n            updateNumberOfClasses();\n            calculateAverageObjectAges();\n            calculateTotalNumberOfSurvGens();\n\n            ObjectNumbersContainer res = new ObjectNumbersContainer(nTrackedAllocObjects, nTrackedLiveObjects,\n                                                                    objectsSizePerClass, avgObjectAge, maxSurvGen,\n                                                                    unprofiledClass, nProfiledClasses);\n\n            return res;\n        } finally {\n            transaction.endTrans();\n        }\n    }\n\n    public int getNProfiledClasses() {\n        transaction.beginTrans(false);\n\n        try {\n            updateNumberOfClasses(); // performance hit is ~ 1ms\n            return nProfiledClasses;\n        } finally {\n            transaction.endTrans();\n        }\n    }\n\n    public long[] getObjectsSizePerClass() {\n        transaction.beginTrans(false);\n\n        try {\n            return objectsSizePerClass;\n        } finally {\n            transaction.endTrans();\n        }\n    }\n\n    public RuntimeMemoryCCTNode[] getStacksForClasses() {\n        transaction.beginTrans(false);\n\n        try {\n            return stacksForClasses;\n        } finally {\n            transaction.endTrans();\n        }\n    }\n\n    public void beginTrans(boolean mutable) {\n        transaction.beginTrans(mutable);\n    }\n\n    public boolean classMarkedUnprofiled(int classId) {\n        transaction.beginTrans(false);\n\n        try {\n            return unprofiledClass[classId];\n        } finally {\n            transaction.endTrans();\n        }\n    }\n\n    public PresoObjAllocCCTNode createPresentationCCT(int classId, boolean dontShowZeroLiveObjAllocPaths)\n                                               throws ClientUtils.TargetAppOrVMTerminated {\n        transaction.beginTrans(false);\n\n        try {\n            PresoObjAllocCCTNode presNode = null;\n            RuntimeMemoryCCTNode classNode = getClassNode(classId);\n            String className = getClassName(classId);\n\n            if ((classNode == null) || (className == null)) {\n                return null;\n            }\n\n            switch (getClient().getCurrentInstrType()) {\n                case CommonConstants.INSTR_OBJECT_LIVENESS: {\n                    presNode = PresoObjLivenessCCTNode.createPresentationCCTFromVM(getClient(), classNode, className,\n                                                                                   currentEpoch, dontShowZeroLiveObjAllocPaths);\n\n                    break;\n                }\n                case CommonConstants.INSTR_OBJECT_ALLOCATIONS: {\n                    presNode = PresoObjAllocCCTNode.createPresentationCCTFromVM(getClient(), classNode, className);\n\n                    break;\n                }\n                default:throw new IllegalStateException(\"MemoryCallGraphBuilder runs in an illegal mode\"); // NOI18N\n            }\n\n            return presNode;\n        } finally {\n            transaction.endTrans();\n        }\n    }\n\n    public void endTrans() {\n        transaction.endTrans();\n    }\n\n    public void markClassUnprofiled(int classId) {\n        transaction.beginTrans(true);\n\n        try {\n            unprofiledClass[classId] = true;\n        } finally {\n            transaction.endTrans();\n        }\n    }\n\n    public void onAllocStackTrace(char classId, long objSize, int[] methodIds) {\n        RuntimeObjAllocTermCCTNode termNode = (RuntimeObjAllocTermCCTNode) processStackTrace(classId, methodIds, false);\n\n        if (termNode != null) {\n            termNode.updateForNewObject(objSize);\n            objectsSizePerClass[classId] += objSize;\n        }\n\n        batchNotEmpty = true;\n    }\n\n    public void onGcPerformed(char classId, long objectId, int objEpoch) {\n        if (currentEpoch < objEpoch) {\n            currentEpoch = objEpoch;\n        }\n\n        RuntimeObjLivenessTermCCTNode termNode = objMap.getNode(objectId);\n        long objSize = objMap.getLastRemovedObjSize();\n\n        if (termNode == null) {\n            return; // Can happen if \"reset collectors\" previously performed\n        }\n\n        termNode.updateForRemovedObject(objSize);\n        termNode.removeLiveObjectForEpoch(objEpoch);\n        nTrackedLiveObjects[classId]--;\n        objectsSizePerClass[classId] -= objSize;\n\n        batchNotEmpty = true;\n    }\n\n    public void onLivenessStackTrace(char classId, long objectId, int objEpoch, long objSize, int[] methodIds) {\n        if (getClient().getCurrentInstrType() != CommonConstants.INSTR_OBJECT_LIVENESS) {\n            return; // ignore liveness events when not in appropriate mode\n        }\n\n        if (currentEpoch < objEpoch) {\n            currentEpoch = objEpoch;\n        }\n\n        try {\n            RuntimeObjLivenessTermCCTNode termNode = (RuntimeObjLivenessTermCCTNode) processStackTrace(classId, methodIds, true);\n\n            if (termNode != null) {\n                termNode.updateForNewObject(objSize);\n                termNode.addLiveObjectForEpoch(objEpoch);\n                objMap.put(objectId, termNode, objSize);\n\n                nTrackedAllocObjects[classId]++;\n                nTrackedLiveObjects[classId]++;\n                objectsSizePerClass[classId] += objSize;\n            }\n        } catch (OutOfMemoryError e) {\n            ProfilerLogger.warning(\"OOME, resetting collectors!!!\"); // NOI18N // TODO\n            reset();\n        }\n\n        batchNotEmpty = true;\n    }\n    \n    public void profilingPoint(final int threadId, final int ppId, final long timeStamp) {\n        ProfilerClient client = getClient();\n\n        if (client == null) {\n            return;\n        }\n\n        final ProfilingPointsProcessor ppp = client.getProfilingPointsProcessor();\n\n        afterBatchCommands.add(new Runnable() {\n                public void run() {\n                    ppp.profilingPointHit(new RuntimeProfilingPoint.HitEvent(ppId, timeStamp, threadId));\n                }\n            });\n    }\n\n    @Override\n    public void monitorEntry(int threadId, long timeStamp0, long timeStamp1, int monitorId, int ownerThreadId) {\n        // ignore\n    }\n\n    @Override\n    public void monitorExit(int threadId, long timeStamp0, long timeStamp1, int monitorId) {\n        // ignore\n    }\n\n    @Override\n    public void newThread(int threadId, String threadName, String threadClassName) {\n        // ignore\n    }\n\n    @Override\n    public void newMonitor(int hash, String className) {\n        // ignore\n    }\n\n    @Override\n    public void timeAdjust(int threadId, long timeDiff0, long timeDiff1) {\n        // ignore\n    }\n    \n    public void updateInternals() {\n        loadNamesForJMethodIds();\n    }\n\n    protected RuntimeCCTNode getAppRootNode() {\n        return new RuntimeMemoryCCTNode();\n    }\n\n    protected void doBatchStart() {\n        transaction.beginTrans(true);\n        updateNumberOfClasses();\n    }\n\n    protected void doBatchStop() {\n        transaction.endTrans();\n    }\n\n    protected void doReset() {\n        transaction.beginTrans(true);\n\n        try {\n            if (stacksForClasses != null) {\n                for (int i = 0; i < stacksForClasses.length; i++) {\n                    stacksForClasses[i] = null;\n                    objectsSizePerClass[i] = 0;\n                }\n            }\n\n            if (objMap != null) {\n                objMap.clear();\n            }\n\n            if (nTrackedAllocObjects != null) {\n                for (int i = 0; i < nTrackedAllocObjects.length; i++) {\n                    nTrackedAllocObjects[i] = 0;\n                    objectsSizePerClass[i] = 0;\n                }\n            }\n\n            if (nTrackedLiveObjects != null) {\n                for (int i = 0; i < nTrackedLiveObjects.length; i++) {\n                    nTrackedLiveObjects[i] = 0;\n                }\n            }\n\n            if (objectsSizePerClass != null) {\n                for (int i = 0; i < objectsSizePerClass.length; i++) {\n                    objectsSizePerClass[i] = 0;\n                }\n            }\n        } finally {\n            transaction.endTrans();\n        }\n    }\n\n    protected void doShutdown() {\n        // #204978: 'loadNamesForJMethodIds()' must be called on SHUTDOWN_INITIATED command\n        // release memory\n        resetInternalState();\n    }\n\n    protected void doStartup(ProfilerClient profilerClient) {\n        resetInternalState();\n        profilerClient.registerMemoryCCTProvider(this);\n    }\n\n    private void resetInternalState() {\n        objMap = new ObjIdToCCTNodeMap();\n        currentEpoch = 0;\n\n        nProfiledClasses = 0;\n        stacksForClasses = null;\n        objectsSizePerClass = null;\n        nTrackedAllocObjects = null;\n        nTrackedLiveObjects = null;\n        maxSurvGen = null;\n        avgObjectAge = null;\n        unprofiledClass = null;\n        currentEpoch = -1;\n\n    }\n    \n    private String getClassName(int classId) {\n        status.beginTrans(false);\n\n        try {\n            return status.getClassNames()[classId];\n        } finally {\n            status.endTrans();\n        }\n    }\n\n    private RuntimeMemoryCCTNode getClassNode(int classId) {\n        return stacksForClasses[classId];\n    }\n\n    private boolean isInitialized() {\n        return (unprofiledClass != null) && (stacksForClasses != null);\n    }\n\n    private RuntimeMemoryCCTNode getNewTerminalNode(int methodId, boolean live) {\n        return live ? new RuntimeObjLivenessTermCCTNode(methodId) : new RuntimeObjAllocTermCCTNode(methodId);\n    }\n\n    private void calculateAverageObjectAges() {\n        if (!isInitialized()) {\n            return; // in the middle of initialization; don't recalculate\n        }\n\n        int nClasses = nProfiledClasses;\n\n        avgObjectAge = new float[nClasses];\n\n        for (int i = 0; i < nClasses; i++) {\n            if (unprofiledClass[i]) {\n                continue;\n            }\n\n            RuntimeMemoryCCTNode rootNode = stacksForClasses[i];\n\n            if (rootNode == null) {\n                continue;\n            }\n\n            float age = RuntimeObjLivenessTermCCTNode.calculateAvgObjectAgeForAllPaths(rootNode, currentEpoch);\n\n            if (age < 0.0f) {\n                age = 0.0f; // May happen after \"Reset collectors\"\n            }\n\n            avgObjectAge[i] = age;\n        }\n    }\n\n    private void calculateTotalNumberOfSurvGens() {\n        if (!isInitialized()) {\n            return;\n        }\n\n        maxSurvGen = new int[nProfiledClasses];\n\n        for (int i = 0; i < maxSurvGen.length; i++) {\n            if (unprofiledClass[i]) {\n                continue;\n            }\n\n            RuntimeMemoryCCTNode rootNode = stacksForClasses[i];\n\n            if (rootNode == null) {\n                continue;\n            }\n\n            maxSurvGen[i] = RuntimeObjLivenessTermCCTNode.calculateTotalNumberOfSurvGensForAllPaths(rootNode);\n        }\n    }\n\n    //************************************************************\n\n    /**********************************************************************************************\n     * Private implementation\n     **********************************************************************************************/\n    private void loadNamesForJMethodIds() {\n        // problem: unloaded classes in the meantime\n        // unloaded classes need to be handled specifically - see ClassLoaderManager, JMethodIdTable\n        final ProfilerClient client = getClient();\n        if (client != null) {\n            synchronized (client) {\n                transaction.beginTrans(false);\n\n                try {\n                    PresoObjAllocCCTNode.getNamesForMethodIdsFromVM(client, stacksForClasses);\n                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                    ProfilerLogger.log(ex.getMessage()); /* No longer ignore silently */\n                } finally {\n                    transaction.endTrans();\n                }\n            }\n        }\n    }\n\n    /**\n     * Given the classId and the array of methodIds of the stack trace for\n     * the newly allocated object, update the reverse Calling Context Tree for this\n     * class. Adds new nodes and/or increases allocated object counters/size in nodes. Returns the terminating\n     * node in the resulting CCT branch.\n     */\n    private RuntimeMemoryCCTNode processStackTrace(char classId, int[] methodIds, boolean live) {\n        if (classId >= stacksForClasses.length) {\n            ProfilerLogger.severe(\"Received stack for non existent class Id: \" + (int) classId + \", current length: \" + stacksForClasses.length); // NOI18N\n            updateNumberOfClasses();\n            ProfilerLogger.severe(\"Received stack for non existent class Id: \" + (int) classId\n                                  + \", current length after updateNumberOfClasses: \" // NOI18N\n                                  + stacksForClasses.length);\n\n            if (classId >= stacksForClasses.length) {\n                return null;\n            }\n        }\n\n        RuntimeMemoryCCTNode curNode = stacksForClasses[classId];\n        RuntimeMemoryCCTNode parentNode = null;\n\n        if (curNode == null) {\n            curNode = new RuntimeMemoryCCTNode(0);\n            stacksForClasses[classId] = curNode;\n        }\n\n        int depth = methodIds.length;\n        int depthMinusOne = depth - 1;\n\n        for (int i = 0; i < depth; i++) {\n            int methodId = methodIds[i];\n            parentNode = curNode;\n\n            Object children = curNode.children;\n\n            boolean found = false;\n\n            if (children != null) {\n                if (children instanceof RuntimeMemoryCCTNode) {\n                    if (((RuntimeMemoryCCTNode) children).methodId == methodId) {\n                        curNode = (RuntimeMemoryCCTNode) children;\n                        found = true;\n                    }\n                } else {\n                    RuntimeMemoryCCTNode[] ar = (RuntimeMemoryCCTNode[]) children;\n\n                    for (RuntimeMemoryCCTNode ar1 : ar) {\n                        if (ar1.methodId == methodId) {\n                            curNode = ar1;\n                            found = true;\n\n                            break;\n                        }\n                    }\n                }\n            }\n\n            if (!found) {\n                // Appropriate subnode not found or there are no subnodes yet - create one.\n                if (i < depthMinusOne) {\n                    curNode = curNode.addNewChild(methodId); // Non-terminal node\n                } else { // Terminal node - need to create a specialized one depending on the profiling type (obj alloc or obj liveness)\n\n                    RuntimeMemoryCCTNode newNode = getNewTerminalNode(methodId, live);\n                    curNode.attachNodeAsChild(newNode);\n                    curNode = newNode;\n                }\n            }\n        }\n\n        // Now check if the curNode that we are going to return is actually not an instance of one of classes representing\n        // \"terminal nodes\", like RuntimeObjAllocTermCCTNode or RuntimeObjLivenessTermCCTNode. Such nodes contain information\n        // that is normally the same for the whole call chain - such as total number/size of objects of the given type allocated\n        // by this call chain. However, it looks like in some cases (different threads?) it may happen that one complete call\n        // chain may become a fragment of another, longer call chain. In that case we will neeed to have a \"terminal\" node in the middle\n        // of the chain. Here we are checking for the case when first a longer chain is created, and then a shorter one that\n        // matches a part of the longer one is found, and taking measures.\n        if (curNode.getClass() == RuntimeMemoryCCTNode.class) {\n            RuntimeMemoryCCTNode newNode = getNewTerminalNode(curNode.methodId, live);\n            newNode.children = curNode.children;\n\n            if (parentNode != null) {\n                Object parChildren = parentNode.children;\n                assert (parChildren != null); // parent will always have chilren\n\n                if (parChildren instanceof RuntimeMemoryCCTNode) {\n                    if (parChildren == curNode) {\n                        parentNode.children = newNode;\n                    }\n                } else {\n                    RuntimeMemoryCCTNode[] ar = (RuntimeMemoryCCTNode[]) parChildren;\n\n                    for (int i = 0; i < ar.length; i++) {\n                        if (ar[i] == curNode) {\n                            ar[i] = newNode;\n\n                            break;\n                        }\n                    }\n                }\n            } else {\n                stacksForClasses[classId] = newNode;\n            }\n\n            curNode = newNode;\n        }\n\n        return curNode;\n    }\n\n    private void updateNumberOfClasses() {\n        status.beginTrans(false);\n\n        try {\n            nProfiledClasses = status.getNInstrClasses();\n        } finally {\n            status.endTrans();\n        }\n\n        if ((stacksForClasses == null) || (stacksForClasses.length < nProfiledClasses)) {\n            int newSize = (nProfiledClasses * 3) / 2;\n            RuntimeMemoryCCTNode[] newStacks = new RuntimeMemoryCCTNode[newSize];\n\n            if (stacksForClasses != null) {\n                System.arraycopy(stacksForClasses, 0, newStacks, 0, stacksForClasses.length);\n            }\n\n            stacksForClasses = newStacks;\n\n            long[] newObjSize = new long[newSize];\n\n            if (objectsSizePerClass != null) {\n                System.arraycopy(objectsSizePerClass, 0, newObjSize, 0, objectsSizePerClass.length);\n            }\n\n            objectsSizePerClass = newObjSize;\n        }\n\n        if (getClient().getCurrentInstrType() == CommonConstants.INSTR_OBJECT_LIVENESS) {\n            if ((nTrackedLiveObjects == null) || (nTrackedLiveObjects.length < nProfiledClasses)) {\n                int newSize = (nProfiledClasses * 3) / 2;\n                int[] tmpIOldData = nTrackedLiveObjects;\n                int[] tmpINewData = null;\n                long[] tmpLOldData = nTrackedAllocObjects;\n                long[] tmpLNewData = null;\n                boolean[] tmpBOldData = unprofiledClass;\n                boolean[] tmpBNewData = null;\n                tmpINewData = new int[newSize];\n\n                if (tmpIOldData != null) {\n                    System.arraycopy(tmpIOldData, 0, tmpINewData, 0, tmpIOldData.length);\n                }\n\n                tmpLNewData = new long[newSize];\n\n                if (tmpLOldData != null) {\n                    System.arraycopy(tmpLOldData, 0, tmpLNewData, 0, tmpLOldData.length);\n                }\n\n                tmpBNewData = new boolean[newSize];\n\n                if (tmpBOldData != null) {\n                    System.arraycopy(tmpBOldData, 0, tmpBNewData, 0, tmpBOldData.length);\n                }\n\n                nTrackedLiveObjects = tmpINewData;\n                nTrackedAllocObjects = tmpLNewData;\n                unprofiledClass = tmpBNewData;\n\n                /* Currently unused - avgObjectAge is created on demand only\n                   float[][] tmpFOldData = new float[][]{avgObjectAge};\n                   float[][] tmpFNewData = new float[1][];\n                   for (int i = 0; i < 1; i++) {\n                     tmpFNewData[i] = new float[newSize];\n                     if (tmpFOldData[i] != null) System.arraycopy(tmpFOldData[i], 0, tmpFNewData[i], 0, tmpFOldData[i].length);\n                   }\n                   avgObjectAge = tmpFNewData[0]; */\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/MemoryDataFrameProcessor.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.nio.ByteBuffer;\nimport java.util.logging.Level;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.ProfilingResultListener;\nimport org.graalvm.visualvm.lib.jfluid.results.locks.AbstractLockDataFrameProcessor;\n\n/**\n *\n * @author Jaroslav Bachorik\n * @author Tomas Hurka\n */\npublic class MemoryDataFrameProcessor extends AbstractLockDataFrameProcessor {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void doProcessDataFrame(ByteBuffer buffer) {\n        int currentEpoch = -1;\n\n        while (buffer.hasRemaining()) {\n            byte eventType = buffer.get();\n\n            switch (eventType) {\n                case CommonConstants.OBJ_ALLOC_STACK_TRACE: {\n                    char classId = buffer.getChar();\n                    long objSize = getObjSize(buffer);\n                    int depth = getDepth(buffer);\n\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Allocation stack trace: classId=\" + (int) classId + \", objSize=\" + objSize + \", depth=\" + depth); // NOI18N\n                    }\n\n                    int[] methodIds = new int[depth];\n\n                    for (int i = 0; i < depth; i++) {\n                        methodIds[i] = buffer.getInt();\n                    }\n\n                    fireAllocStackTrace(classId, objSize, methodIds);\n\n                    break;\n                }\n                case CommonConstants.OBJ_LIVENESS_STACK_TRACE: {\n                    char classId = buffer.getChar();\n                    int objEpoch = buffer.getChar();\n\n                    if (objEpoch > currentEpoch) {\n                        currentEpoch = objEpoch; // objEpoch may be < currentEpoch if e.g. the GC event is being processed\n                    }\n\n                    long objectId = ((((long) classId) & 0xFFFF) << 48) | ((((long) objEpoch) & 0xFFFF) << 32)\n                                    | (((long) buffer.getInt()) & 0xFFFFFFFF);\n                    long objSize = getObjSize(buffer);\n\n                    int depth = getDepth(buffer);\n\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Liveness stack trace: classId=\" + (int) classId + \", objectId=\" + objectId + \", objEpoch=\" //NOI18N\n                                      + objEpoch + \", objSize=\" + objSize + \", depth=\" + depth); // NOI18N\n                    }\n\n                    int[] methodIds = new int[depth];\n\n                    for (int i = 0; i < depth; i++) {\n                        methodIds[i] = buffer.getInt();\n                    }\n\n                    fireLivenessStackTrace(classId, objectId, objEpoch, objSize, methodIds);\n\n                    break;\n                }\n                case CommonConstants.OBJ_GC_HAPPENED: {\n                    char classId = buffer.getChar();\n                    int objEpoch = buffer.getChar();\n\n                    if (objEpoch > currentEpoch) {\n                        currentEpoch = objEpoch; // objEpoch may be < currentEpoch if e.g. the GC event is being processed\n                    }\n\n                    long objectId = ((((long) classId) & 0xFFFF) << 48) | ((((long) objEpoch) & 0xFFFF) << 32)\n                                    | (((long) buffer.getInt()) & 0xFFFFFFFF);\n\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"GC Performed: classId=\" + (int) classId + \", objectId=\" + objectId + \", objEpoch=\" + objEpoch); // NOI18N\n                    }\n\n                    fireGCPerformed(classId, objectId, objEpoch);\n\n                    break;\n                }\n                case CommonConstants.RESET_COLLECTORS: {\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Profiling data reset\"); // NOI18N\n                    }\n\n                    fireReset();\n\n                    break;\n                }\n                case CommonConstants.BUFFEREVENT_PROFILEPOINT_HIT: {\n                    int id = buffer.getChar();\n                    long timeStamp = getTimeStamp(buffer);\n                    int threadId = buffer.getChar();\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"Profile Point Hit \" + id + \", threadId=\" + id + \", timeStamp=\" + timeStamp); // NOI18N\n                    }\n\n                    fireProfilingPoint(threadId, id, timeStamp);\n\n                    break;\n                }\n                case CommonConstants.SET_FOLLOWING_EVENTS_THREAD: {\n                    currentThreadId = buffer.getChar();\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.log(Level.FINEST, \"Change current thread , tId={0}\", currentThreadId); // NOI18N\n                    }\n\n                    break;\n                }\n                case CommonConstants.NEW_THREAD: {\n                    int threadId = buffer.getChar();\n                    String threadName = getString(buffer);\n                    String threadClassName = getString(buffer);\n\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.log(Level.FINEST, \"Creating new thread , tId={0}\", threadId); // NOI18N\n                    }\n\n                    fireNewThread(threadId, threadName, threadClassName);\n                    currentThreadId = threadId;\n\n                    break;\n                }\n                case CommonConstants.NEW_MONITOR: {\n                    int hash = buffer.getInt();\n                    String className = getString(buffer);\n\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.log(Level.FINEST, \"Creating new monitor , monitorId={0} , className={1}\", new Object[] {Integer.toHexString(hash), className}); // NOI18N\n                    }\n\n                    fireNewMonitor(hash, className);\n                    break;\n                }\n                case CommonConstants.METHOD_ENTRY_MONITOR:\n                case CommonConstants.METHOD_EXIT_MONITOR: {\n                    long timeStamp0 = getTimeStamp(buffer);\n                    long timeStamp1 = -1;\n                    int hash = buffer.getInt();\n                    \n                    if (eventType == CommonConstants.METHOD_ENTRY_MONITOR) {\n                        int ownerThreadId = buffer.getInt();\n                        if (LOGGER.isLoggable(Level.FINEST)) {\n                            LOGGER.log(Level.FINEST, \"Monitor entry , tId={0} , monitorId={1} , ownerId={2}\", new Object[]{currentThreadId,Integer.toHexString(hash),ownerThreadId}); // NOI18N\n                        }\n\n                        fireMonitorEntry(currentThreadId, timeStamp0, timeStamp1, hash, ownerThreadId);\n                    }\n                    if (eventType == CommonConstants.METHOD_EXIT_MONITOR) {\n                        if (LOGGER.isLoggable(Level.FINEST)) {\n                            LOGGER.log(Level.FINEST, \"Monitor exit , tId={0} , monitorId={1}\", new Object[]{currentThreadId,Integer.toHexString(hash)}); // NOI18N\n                        }\n\n                        fireMonitorExit(currentThreadId, timeStamp0, timeStamp1, hash);\n                    }\n                    break;\n                }\n                case CommonConstants.ADJUST_TIME: {\n                    long timeStamp0 = getTimeStamp(buffer);\n                    long timeStamp1 = collectingTwoTimeStamps ? getTimeStamp(buffer) : 0;\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.log(Level.FINEST, \"Adjust time , tId={0}\", currentThreadId); // NOI18N\n                    }\n\n                    fireAdjustTime(currentThreadId, timeStamp0, timeStamp1);\n\n                    break;\n                }\n                default: {\n                    LOGGER.severe(\"*** Profiler Engine: internal error: got unknown event type in MemoryDataFrameProcessor: \" // NOI18N\n                                  + (int) eventType\n                                  + \" at \" + buffer.position() // NOI18N\n                                  );\n\n                    break;\n                }\n            }\n        }\n    }\n\n    private void fireAllocStackTrace(final char classId, final long objSize, final int[] methodIds) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    try {\n                        ((MemoryProfilingResultsListener) listener).onAllocStackTrace(classId, objSize, methodIds);\n                    } catch (Exception e) {\n                        e.printStackTrace();\n                    }\n                }\n            });\n    }\n\n    private void fireGCPerformed(final char classId, final long objectId, final int objEpoch) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((MemoryProfilingResultsListener) listener).onGcPerformed(classId, objectId, objEpoch);\n                }\n            });\n    }\n\n    private void fireLivenessStackTrace(final char classId, final long objectId, final int objEpoch, final long objSize,\n                                        final int[] methodIds) {\n        foreachListener(new ListenerFunctor() {\n                public void execute(ProfilingResultListener listener) {\n                    ((MemoryProfilingResultsListener) listener).onLivenessStackTrace(classId, objectId, objEpoch, objSize,\n                                                                                     methodIds);\n                }\n            });\n    }\n    \n    private static long getObjSize(ByteBuffer buffer) {\n        long objSize = (((long) buffer.get() & 0xFF) << 32) | (((long) buffer.get() & 0xFF) << 24)\n                       | (((long) buffer.get() & 0xFF) << 16) | (((long) buffer.get() & 0xFF) << 8)\n                       | ((long) buffer.get() & 0xFF);\n        return objSize;\n    }\n    \n    private static int getDepth(ByteBuffer buffer) {\n        int depth = ((((int) buffer.get()) & 0xFF) << 16) | ((((int) buffer.get()) & 0xFF) << 8)\n                    | (((int) buffer.get()) & 0xFF);\n        return depth;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/MemoryProfilingResultsListener.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport org.graalvm.visualvm.lib.jfluid.results.locks.LockProfilingResultListener;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface MemoryProfilingResultsListener extends LockProfilingResultListener {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    void onAllocStackTrace(char classId, long objSize, int[] methodIds);\n\n    void onGcPerformed(char classId, long objectId, int objEpoch);\n\n    void onLivenessStackTrace(char classId, long objectId, int objEpoch, long objSize, int[] methodIds);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/MemoryResultsSnapshot.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.results.ResultsSnapshot;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.logging.Level;\nimport org.graalvm.visualvm.lib.jfluid.results.FilterSortSupport;\n\n\n/**\n * Results snapshot for Memory Profiling.\n *\n * @author Ian Formanek\n */\npublic abstract class MemoryResultsSnapshot extends ResultsSnapshot {\n    /***************************************************************************\n    +------------------------------------------------------------------------------+\n    | Profiler memory snapshot format description                                  |\n    +------------------------------------------------------------------------------+\n    int         version\n    long        timestamp\n    long        duration\n    int         # profiled classes\n    ===> for(# profiled classes)\n    string      class name\n    long        object size per class\n    <===\n    boolean     contains stacktraces\n    int         # stacktraces\n    ===> for(# stacktraces)\n    :::> load node\n    int         type (RuntimeMemoryCCTNode.TYPE_RuntimeMemoryCCTNode,\n                      RuntimeMemoryCCTNode.TYPE_RuntimeObjAllocTermCCTNode,\n                      RuntimeMemoryCCTNode.RuntimeObjLivenessTermCCTNode)\n    int         methodId\n    int         # children\n    ======> for(# children)\n    >load node<\n    <=====\n    <::: load node\n    <===\n    ***************************************************************************/\n\n    private JMethodIdTable table;\n    /** [0-nProfiledClasses] class names */\n    String[] classNames;\n\n    /** [0-nProfiledClasses] total size in bytes for tracked instances of this class */\n    long[] objectsSizePerClass;\n\n    /** [0-nProfiledClasses] class Id -> root of its allocation traces tree */\n    private RuntimeMemoryCCTNode[] stacksForClasses;\n\n    /** total number of profiled classes */\n    int nProfiledClasses;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public MemoryResultsSnapshot() {\n    } // No-arg constructor needed for above serialization methods to work\n\n    public MemoryResultsSnapshot(long beginTime, long timeTaken, MemoryCCTProvider provider, ProfilerClient client)\n                          throws ClientUtils.TargetAppOrVMTerminated {\n        super(beginTime, timeTaken);\n\n        // TODO [performance]: profile for performance - specifically which of the actions below is most time consuming\n        ProfilingSessionStatus status = client.getStatus();\n        status.beginTrans(false);\n\n        try {\n            performInit(client, provider);           \n        } finally {\n            status.endTrans();\n\n            if (LOGGER.isLoggable(Level.FINEST)) {\n                debugValues();\n            }\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getClassName(int classId) {\n        return classNames[classId];\n    }\n\n    public String[] getClassNames() {\n        return classNames;\n    }\n\n    public JMethodIdTable getJMethodIdTable() {\n        return table;\n    }\n\n    public int getNProfiledClasses() {\n        return nProfiledClasses;\n    }\n\n    public long[] getObjectsSizePerClass() {\n        return objectsSizePerClass;\n    }\n\n    public boolean containsStacks() {\n        return stacksForClasses != null;\n    }\n    \n    \n    public abstract MemoryResultsSnapshot createDiff(MemoryResultsSnapshot snapshot);\n    \n    public void filterReverse(String filter, int filterType, int sortBy, boolean sortOrder, PresoObjAllocCCTNode root, int classId, boolean dontShowZeroLiveObjAllocPaths) {\n        PresoObjAllocCCTNode rev =\n                (PresoObjAllocCCTNode)createPresentationCCT(classId, dontShowZeroLiveObjAllocPaths);\n        filter(filter, filterType, rev);\n        root.children = rev.children;\n        if (root.children != null) {\n            for (PresoObjAllocCCTNode ch : root.children)\n                ch.parent = root;\n            root.sortChildren(sortBy, sortOrder);\n        }\n        if (!FilterSortSupport.passesFilter(filter, filterType, root.getNodeName())) {\n//            root.setFilteredNode();\n//            root.methodId = -1;\n        } else {\n//            root.resetFilteredNode();\n        }\n    }\n    \n    private void filter(String filter, int filterType, PresoObjAllocCCTNode node) {\n        if (node.children != null) {\n            PresoObjAllocCCTNode filtered = null;\n            List<PresoObjAllocCCTNode> ch = new ArrayList();\n            for (PresoObjAllocCCTNode n : node.children) {\n                PresoObjAllocCCTNode nn = (PresoObjAllocCCTNode)n;\n                if (FilterSortSupport.passesFilter(filter, filterType, nn.getNodeName())) {\n                    int i = ch.indexOf(nn);\n                    if (i == -1) ch.add(nn);\n                    else ch.get(i).merge(nn);\n                } else {\n                    if (filtered == null) {\n//                        nn.setFilteredNode();\n//                        nn.methodId = -1;\n                        filtered = nn;\n                        ch.add(nn);\n                    } else {\n                        filtered.merge(nn);\n                    }\n                }\n            }\n            \n            if (ch.isEmpty()) {\n                node.children = null;\n            } else {\n                if (node.isFiltered() && filtered != null && ch.size() == 1) {\n                    // \"naive\" approach, collapse simple chain of filtered out nodes\n                    PresoObjAllocCCTNode n = ch.get(0);\n                    filter(filter, filterType, n);\n                    node.children = n.children;\n                } else {\n                    node.children = ch.toArray(new PresoObjAllocCCTNode[0]);\n                }\n            }\n            \n            if (node.children != null)\n                for (PresoObjAllocCCTNode n : node.children)\n                    filter(filter, filterType, (PresoObjAllocCCTNode)n);\n        }\n    }\n    \n\n    /**\n     * Creates a presentation-time allocation stack traces CCT for given classId.\n     *\n     * @param classId                       Class ID of the class whose allocation stack traces we request\n     * @param dontShowZeroLiveObjAllocPaths If true, allocation paths with zero live objects will not be included in CCT\n     * @return presentation-time CCT with allocation stack traces or null if none are available\n     */\n    public PresoObjAllocCCTNode createPresentationCCT(int classId, boolean dontShowZeroLiveObjAllocPaths) {\n        if (stacksForClasses == null) {\n            return null;\n        }\n\n        RuntimeMemoryCCTNode rootNode = stacksForClasses[classId];\n\n        if (rootNode == null) {\n            return null;\n        }\n\n        return createPresentationCCT(rootNode, classId, dontShowZeroLiveObjAllocPaths);\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        super.readFromStream(in);\n\n        nProfiledClasses = in.readInt();\n        classNames = new String[nProfiledClasses];\n        objectsSizePerClass = new long[nProfiledClasses];\n\n        for (int i = 0; i < nProfiledClasses; i++) {\n            classNames[i] = in.readUTF();\n            objectsSizePerClass[i] = in.readLong();\n        }\n\n        if (in.readBoolean()) {\n            int len = in.readInt();\n            //System.err.println(\"Read len: \" +len);\n            stacksForClasses = new RuntimeMemoryCCTNode[len];\n\n            for (int i = 0; i < len; i++) {\n                int type = in.readInt();\n\n                //System.err.println(\"  [\" + i + \"] = \" + type);\n                if (type != 0) {\n                    stacksForClasses[i] = RuntimeMemoryCCTNode.create(type);\n                    stacksForClasses[i].readFromStream(in);\n                }\n            }\n\n            if (in.readBoolean()) {\n                table = new JMethodIdTable();\n                table.readFromStream(in);\n            }\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            debugValues();\n        }\n    }\n\n    //---- Serialization support\n    public void writeToStream(DataOutputStream out) throws IOException {\n        super.writeToStream(out);\n\n        out.writeInt(nProfiledClasses);\n\n        for (int i = 0; i < nProfiledClasses; i++) {\n            out.writeUTF(classNames[i]);\n            out.writeLong(objectsSizePerClass[i]);\n        }\n\n        out.writeBoolean(stacksForClasses != null);\n\n        if (stacksForClasses != null) {\n            out.writeInt(stacksForClasses.length);\n\n            //.err.println(\"Stored len: \" +stacksForClasses.length);\n            for (RuntimeMemoryCCTNode stacksForClasse : stacksForClasses) {\n                if (stacksForClasse == null) {\n                    //System.err.println(\"  [\" + i + \"] = 0\");\n                    out.writeInt(0);\n                } else {\n                    out.writeInt(stacksForClasse.getType());\n                    //System.err.println(\"  [\" + i + \"] = \" + stacksForClasses[i].getType());\n                    stacksForClasse.writeToStream(out);\n                }\n            }\n\n            out.writeBoolean(table != null);\n\n            if (table != null) {\n                table.writeToStream(out);\n            }\n        }\n    }\n\n    /**\n     * Will create presentation CCT for call stacks for given root node.\n     *\n     * @param rootNode                      The root node that contains allocation stack traces data\n     * @param classId                       Id of class whose allocations we are requesting\n     * @param dontShowZeroLiveObjAllocPaths if true, allocation paths with zero live objects will not be included\n     * @return a non-null instance of the root of presentation-time allocations CCT\n     */\n    protected abstract PresoObjAllocCCTNode createPresentationCCT(RuntimeMemoryCCTNode rootNode, int classId,\n                                                                  boolean dontShowZeroLiveObjAllocPaths);\n\n    protected void performInit(ProfilerClient client, MemoryCCTProvider provider)\n                                 throws ClientUtils.TargetAppOrVMTerminated {\n        nProfiledClasses = provider.getNProfiledClasses();\n\n        int len = 0;\n\n        if (provider.getObjectsSizePerClass() != null) {\n            //System.err.println(\"mcgb.objectsSizePerClass len is: \"+mcgb.objectsSizePerClass.length);\n            len = provider.getObjectsSizePerClass().length;\n            objectsSizePerClass = new long[len];\n            System.arraycopy(provider.getObjectsSizePerClass(), 0, objectsSizePerClass, 0, len);\n        } /*else {\n           System.err.println(\"mcgb.objectsSizePerClass is NULL\");\n           }   */\n        String[] s_classNames = client.getStatus().getClassNames();\n        //      len = s_classNames.length;\n        len = nProfiledClasses;\n        //System.err.println(\"status.classNames.length is: \"+len );\n        classNames = new String[len];\n        System.arraycopy(s_classNames, 0, classNames, 0, len);\n\n        //      System.out.println(\"Created snapshot [\" + timeTaken + \"] with \" + classNames.length + \" classes; nProfiledClasses = \" + nProfiledClasses);\n        RuntimeMemoryCCTNode[] stacks = provider.getStacksForClasses();\n        if ((stacks != null) && checkContainsStacks(stacks)) {\n            stacksForClasses = new RuntimeMemoryCCTNode[stacks.length];\n\n            for (int i = 0; i < stacksForClasses.length; i++) {\n                if (stacks[i] != null) {\n                    stacksForClasses[i] = (RuntimeMemoryCCTNode) stacks[i].clone();\n                }\n            }\n\n            table = new JMethodIdTable(client.getJMethodIdTable());\n        }        \n    }\n\n    private boolean checkContainsStacks(RuntimeMemoryCCTNode[] stacksForClasses) {\n        for (RuntimeMemoryCCTNode stacksForClass : stacksForClasses) {\n            if (stacksForClass == null) {\n                continue;\n            }\n\n            if (stacksForClass instanceof RuntimeObjAllocTermCCTNode) {\n                continue;\n            }\n\n            if (stacksForClass instanceof RuntimeObjLivenessTermCCTNode) {\n                continue;\n            }\n\n            return true;\n        }\n\n        return false; // no data but term nodes or nulls\n    }\n\n    void debugValues() {\n        LOGGER.finest(\"nProfiledClasses: \" + nProfiledClasses); // NOI18N\n        LOGGER.finest(\"stacksForClasses.length: \" + debugLength(stacksForClasses)); // NOI18N\n        LOGGER.finest(\"objectsSizePerClass.length: \" + debugLength(objectsSizePerClass));\n        LOGGER.finest(\"classNames.length: \" + debugLength(classNames)); // NOI18N\n        LOGGER.finest(\"table: \" + ((table == null) ? \"null\" : table.debug())); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/PresoObjAllocCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatterFactory;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport java.util.ResourceBundle;\nimport org.graalvm.visualvm.lib.jfluid.results.FilterSortSupport;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\n\n\n/**\n * Presentation-Time Memory Profiling Calling Context Tree (CCT) Node. Used \"as is\" for Object Allocation\n * profiling, and used as a base class for PresoObjLivenessCCTNode. Contains additional functionality\n * to map jmethodIDs (integer identifiers automatically assigned to methods by the JVM, that are returned\n * by stack trace routines) to method names. This includes sending a request to the server to get method\n * names/signatures for given jmethodIDs.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class PresoObjAllocCCTNode extends CCTNode {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final String VM_ALLOC_CLASS = \"org.graalvm.visualvm.lib.jfluid.server.ProfilerRuntimeMemory\"; // NOI18N\n    public static final String VM_ALLOC_METHOD = \"traceVMObjectAlloc\"; // NOI18N\n    private static final String VM_ALLOC_TEXT = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.memory.Bundle\") // NOI18N\n    .getString(\"PresoObjAllocCCTNode_VMAllocMsg\"); // NOI18N\n    private static final String UKNOWN_NODENAME = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.memory.Bundle\") // NOI18N\n    .getString(\"PresoObjAllocCCTNode_UnknownMsg\"); // NOI18N\n    public static final int SORT_BY_NAME = 1;\n    public static final int SORT_BY_ALLOC_OBJ_SIZE = 2;\n    public static final int SORT_BY_ALLOC_OBJ_NUMBER = 3;\n    \n//    protected static final char MASK_FILTERED_NODE = 0x8;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    public long nCalls;\n    public long totalObjSize;\n    public PresoObjAllocCCTNode parent;\n    String className;\n    String methodName;\n//    String methodSig;\n    String nodeName;\n    public PresoObjAllocCCTNode[] children;\n    int methodId;\n    JMethodIdTable.JMethodIdTableEntry entry;\n    \n    protected char flags;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n    \n    public static PresoObjAllocCCTNode rootNode(PresoObjAllocCCTNode[] children) {\n        PresoObjAllocCCTNode root = new PresoObjAllocCCTNode();\n        root.setChildren(children);\n        return root;\n    }\n    \n    public PresoObjAllocCCTNode(String className, long nCalls, long totalObjSize) {\n        this.className = className;\n        this.nCalls = nCalls;\n        this.totalObjSize = totalObjSize;\n        \n        methodName = Wildcards.ALLWILDCARD;\n    }\n    \n    PresoObjAllocCCTNode() {}\n    \n    protected PresoObjAllocCCTNode(RuntimeMemoryCCTNode rtNode) {\n        methodId = rtNode.methodId;\n\n        if (rtNode instanceof RuntimeObjAllocTermCCTNode) {\n            RuntimeObjAllocTermCCTNode rtTermNode = (RuntimeObjAllocTermCCTNode) rtNode;\n            nCalls += rtTermNode.nCalls;\n            totalObjSize += rtTermNode.totalObjSize;\n        }\n    }\n    \n    \n    protected final void setChildren(PresoObjAllocCCTNode[] children) {\n        this.children = children;\n        for (PresoObjAllocCCTNode child : children) child.parent = this;\n    }\n    \n    \n    // --- Filtering support\n    \n    public CCTNode createFilteredNode() {\n        PresoObjAllocCCTNode filtered = new PresoObjAllocCCTNode();\n        setupFilteredNode(filtered);        \n        return filtered;\n    }\n    \n    protected void setupFilteredNode(PresoObjAllocCCTNode filtered) {\n        filtered.setFilteredNode();\n         \n        filtered.parent = parent;\n\n        filtered.nCalls = nCalls;\n        filtered.totalObjSize = totalObjSize;\n\n        Collection<PresoObjAllocCCTNode> _childrenL = resolveChildren(this);\n        filtered.children = _childrenL.toArray(new PresoObjAllocCCTNode[0]);\n    }\n    \n    public void merge(CCTNode node) {\n        if (node instanceof PresoObjAllocCCTNode) {\n            PresoObjAllocCCTNode _node = (PresoObjAllocCCTNode)node;\n            \n            nCalls += _node.nCalls;\n            totalObjSize += _node.totalObjSize;\n\n            List<PresoObjAllocCCTNode> ch = new ArrayList();\n            \n            // Include current children\n            if (children != null) ch.addAll(Arrays.asList(children));\n            \n            // Add or merge new children\n            for (PresoObjAllocCCTNode child : resolveChildren(_node)) {\n                int idx = ch.indexOf(child);\n                if (idx == -1) ch.add(child);\n                else ch.get(idx).merge(child);\n            }\n            \n            children = ch.toArray(new PresoObjAllocCCTNode[0]);\n        }\n    }\n\n    protected static Collection<PresoObjAllocCCTNode> resolveChildren(PresoObjAllocCCTNode node) {\n        PresoObjAllocCCTNode[] chldrn = (PresoObjAllocCCTNode[])node.getChildren();\n        return chldrn == null ? Collections.EMPTY_LIST : Arrays.asList(chldrn);\n    }\n    \n    // ---\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void getNamesForMethodIdsFromVM(ProfilerClient profilerClient, RuntimeMemoryCCTNode[] allStackRoots)\n                                           throws ClientUtils.TargetAppOrVMTerminated {\n        if (allStackRoots == null) {\n            return; // Can happen if this is called too early\n        }\n\n        JMethodIdTable table = profilerClient.getJMethodIdTable();\n        for (RuntimeMemoryCCTNode allStackRoot : allStackRoots) {\n            if (allStackRoot != null) {\n                checkMethodIdForNodeFromVM(table, allStackRoot);\n            }\n        }\n        table.getNamesForMethodIds(profilerClient);\n    }\n\n    public static PresoObjAllocCCTNode createPresentationCCTFromSnapshot(JMethodIdTable methodIdTable,\n                                                                         RuntimeMemoryCCTNode rootRuntimeNode,\n                                                                         String classTypeName) {\n        PresoObjAllocCCTNode rootNode = generateMirrorNode(rootRuntimeNode);\n        assignNamesToNodesFromSnapshot(methodIdTable, rootNode, classTypeName);\n\n        return rootNode;\n    }\n\n    public static PresoObjAllocCCTNode createPresentationCCTFromVM(ProfilerClient profilerClient,\n                                                                   RuntimeMemoryCCTNode rootRuntimeNode, String classTypeName)\n        throws ClientUtils.TargetAppOrVMTerminated {\n        PresoObjAllocCCTNode rootNode = generateMirrorNode(rootRuntimeNode);\n        assignNamesToNodesFromVM(profilerClient, rootNode, classTypeName);\n\n        return rootNode;\n    }\n\n    public CCTNode getChild(int index) {\n        if (index < children.length) {\n            return children[index];\n        } else {\n            return null;\n        }\n    }\n\n    public CCTNode[] getChildren() {\n        return children;\n    }\n\n    public int getIndexOfChild(Object child) {\n        for (int i = 0; i < children.length; i++) {\n            if ((PresoObjAllocCCTNode) child == children[i]) {\n                return i;\n            }\n        }\n\n        return -1;\n    }\n\n    public String[] getMethodClassNameAndSig() {\n        return new String[] { getClassName(), getMethodName(), getMethodSig()};\n    }\n\n    public int getNChildren() {\n        if (children != null) {\n            return children.length;\n        } else {\n            return 0;\n        }\n    }\n\n    public String getNodeName() {\n        if (nodeName == null) {\n            if (isFiltered()) {\n                nodeName = FilterSortSupport.FILTERED_OUT_LBL;\n            } else if (methodId != 0) {\n                if (VM_ALLOC_CLASS.equals(getClassName()) && VM_ALLOC_METHOD.equals(getMethodName())) { // special handling of ProfilerRuntimeMemory.traceVMObjectAlloc\n                    nodeName = VM_ALLOC_TEXT;\n                } else {\n                    nodeName = MethodNameFormatterFactory.getDefault().getFormatter().formatMethodName(\n                                        getClassName(), getMethodName(), getMethodSig()).toFormatted();\n                }\n            } else if (getClassName() != null) {\n                nodeName = getClassName();\n            } else {\n                nodeName = UKNOWN_NODENAME;\n            }\n        }\n        \n        return nodeName;\n    }\n\n    public CCTNode getParent() {\n        return parent;\n    }\n\n    public void sortChildren(int sortBy, boolean sortOrder) {\n//        int nChildren = getNChildren();\n//\n//        if (nChildren == 0) {\n//            return;\n//        }\n//\n//        for (int i = 0; i < nChildren; i++) {\n//            children[i].sortChildren(sortBy, sortOrder);\n//        }\n//\n//        if (nChildren > 1) {\n//            switch (sortBy) {\n//                case SORT_BY_NAME:\n//                    sortChildrenByName(sortOrder);\n//\n//                    break;\n//                case SORT_BY_ALLOC_OBJ_SIZE:\n//                    sortChildrenByAllocObjSize(sortOrder);\n//\n//                    break;\n//                case SORT_BY_ALLOC_OBJ_NUMBER:\n//                    sortChildrenByAllocObjNumber(sortOrder);\n//\n//                    break;\n//            }\n//        }\n    }\n\n    public String toString() {\n        return getNodeName();\n    }\n    \n//    public void setFilteredNode() {\n//        flags |= MASK_FILTERED_NODE;\n//    }\n//    \n//    public void resetFilteredNode() {\n//        flags &= ~MASK_FILTERED_NODE;\n//    }\n//\n//    public boolean isFilteredNode() {\n//        return (flags & MASK_FILTERED_NODE) != 0;\n//    }\n    \n//    void merge(PresoObjAllocCCTNode node) {\n//        nCalls += node.nCalls;\n//        totalObjSize += totalObjSize;\n//        \n//        if (node.children != null) {\n//            for (PresoObjAllocCCTNode ch : node.children)\n//                ch.parent = this;\n//            \n//            int chl = children == null ? 0 : children.length;\n//            int newchl = node.children.length;\n//            PresoObjAllocCCTNode[] newch = new PresoObjAllocCCTNode[chl + newchl];\n//            if (children != null) System.arraycopy(children, 0, newch, 0, chl);\n//            System.arraycopy(node.children, 0, newch, chl, newchl);\n//            children = newch;\n//        }\n//    }\n    \n    public boolean equals(Object o) {\n        if (o == this) return true;\n        if (!(o instanceof PresoObjAllocCCTNode)) return false;\n        PresoObjAllocCCTNode other = (PresoObjAllocCCTNode)o;\n        if (isFiltered()) {\n            return other.isFiltered();\n        }\n        if (other.isFiltered()) {\n            return false;\n        }\n        if (methodId == 0) {\n            return getNodeName().equals(other.getNodeName());\n        }\n        if (other.methodId == 0) {\n            return false;\n        }\n        return entry.className.equals(other.entry.className) &&\n               entry.methodName.equals(other.entry.methodName) &&\n               entry.methodSig.equals(other.entry.methodSig);\n    }\n    \n    public int hashCode() {\n        if (methodId == 0 || isFiltered()) {\n            return getNodeName().hashCode();\n        }\n        return entry.className.hashCode() ^ entry.methodName.hashCode() ^ entry.methodSig.hashCode();\n    }\n\n    protected static void assignNamesToNodesFromSnapshot(JMethodIdTable methodIdTable, PresoObjAllocCCTNode rootNode,\n                                                         String classTypeName) {\n        rootNode.className = StringUtils.userFormClassName(classTypeName);\n        rootNode.setFullClassAndMethodInfo(methodIdTable);\n    }\n\n    protected static void assignNamesToNodesFromVM(ProfilerClient profilerClient, PresoObjAllocCCTNode rootNode,\n                                                   String classTypeName)\n                                            throws ClientUtils.TargetAppOrVMTerminated {\n        JMethodIdTable table = profilerClient.getJMethodIdTable();\n        table.getNamesForMethodIds(profilerClient);\n        rootNode.className = StringUtils.userFormClassName(classTypeName);\n        rootNode.setFullClassAndMethodInfo(table);\n    }\n\n    protected static PresoObjAllocCCTNode generateMirrorNode(RuntimeMemoryCCTNode rtNode) {\n        PresoObjAllocCCTNode thisNode = new PresoObjAllocCCTNode(rtNode);\n        Object nodeChildren = rtNode.children;\n\n        if (nodeChildren != null) {\n            if (nodeChildren instanceof RuntimeMemoryCCTNode) {\n                thisNode.children = new PresoObjAllocCCTNode[1];\n\n                PresoObjAllocCCTNode child = generateMirrorNode((RuntimeMemoryCCTNode) nodeChildren);\n                thisNode.children[0] = child;\n                child.parent = thisNode;\n                thisNode.nCalls += child.nCalls;\n                thisNode.totalObjSize += child.totalObjSize;\n            } else {\n                RuntimeMemoryCCTNode[] ar = (RuntimeMemoryCCTNode[]) nodeChildren;\n                int nChildren = ar.length;\n\n                if (nChildren > 0) {\n                    thisNode.children = new PresoObjAllocCCTNode[nChildren];\n\n                    for (int i = 0; i < nChildren; i++) {\n                        PresoObjAllocCCTNode child = generateMirrorNode(ar[i]);\n                        thisNode.children[i] = child;\n                        child.parent = thisNode;\n                        thisNode.nCalls += child.nCalls;\n                        thisNode.totalObjSize += child.totalObjSize;\n                    }\n                }\n            }\n        }\n\n        return thisNode;\n    }\n\n    protected boolean setFullClassAndMethodInfo(JMethodIdTable methodIdTable) {\n        if (methodId != 0) {\n            entry = methodIdTable.getEntry(methodId);\n        }\n\n        // If any object allocations that happen in our own code are caught (which shouldn't happen),\n        // make sure to conceal this data here.\n        boolean thisNodeOk = entry!=null && !\"org/graalvm/visualvm/lib/jfluid/server/ProfilerServer\".equals(entry.className); // NOI18N\n        boolean childrenOk = true;\n\n        if (children != null) {\n            for (int i = 0; i < children.length; i++) {\n                if (!children[i].setFullClassAndMethodInfo(methodIdTable)) {\n                    childrenOk = false;\n                    children[i] = null;\n                }\n            }\n        }\n\n        if (!childrenOk) {\n            // Determine the number of non-null children and create a new children array\n            int newLen = 0;\n\n            for (PresoObjAllocCCTNode children1 : children) {\n                newLen += ((children1 != null) ? 1 : 0);\n            }\n\n            boolean hasNonNullChildren = (newLen > 0);\n\n            if (!hasNonNullChildren) {\n                children = null;\n            } else {\n                PresoObjAllocCCTNode[] newChildren = new PresoObjAllocCCTNode[newLen];\n                int idx = 0;\n\n                for (PresoObjAllocCCTNode children1 : children) {\n                    if (children1 != null) {\n                        newChildren[idx++] = children1;\n                    }\n                }\n\n                children = newChildren;\n            }\n\n            if ((getMethodName() == null) || (getMethodName().equals(\"main\") && getMethodSig() // NOI18N\n                .equals(\"([Ljava/lang/String;)V\"))) { // NOI18N\n\n                return true;\n            } else {\n                return thisNodeOk;\n            }\n        } else {\n            return thisNodeOk;\n        }\n    }\n\n    protected static void checkMethodIdForNodeFromVM(JMethodIdTable table, RuntimeMemoryCCTNode rtNode) {\n        if (rtNode.methodId != 0) {\n            table.checkMethodId(rtNode.methodId);\n        }\n\n        Object nodeChildren = rtNode.children;\n\n        if (nodeChildren != null) {\n            if (nodeChildren instanceof RuntimeMemoryCCTNode) {\n                checkMethodIdForNodeFromVM(table, (RuntimeMemoryCCTNode) nodeChildren);\n            } else {\n                RuntimeMemoryCCTNode[] ar = (RuntimeMemoryCCTNode[]) nodeChildren;\n\n                for (RuntimeMemoryCCTNode ar1 : ar) {\n                    checkMethodIdForNodeFromVM(table, ar1);\n                }\n            }\n        }\n    }\n\n//    protected void sortChildrenByAllocObjNumber(boolean sortOrder) {\n//        int len = children.length;\n//        long[] values = new long[len];\n//\n//        for (int i = 0; i < len; i++) {\n//            values[i] = children[i].nCalls;\n//        }\n//\n//        sortLongs(values, sortOrder);\n//    }\n//\n//    protected void sortChildrenByAllocObjSize(boolean sortOrder) {\n//        int len = children.length;\n//        long[] values = new long[len];\n//\n//        for (int i = 0; i < len; i++) {\n//            values[i] = children[i].totalObjSize;\n//        }\n//\n//        sortLongs(values, sortOrder);\n//    }\n//\n//    protected void sortChildrenByName(boolean sortOrder) {\n//        int len = children.length;\n//        String[] values = new String[len];\n//\n//        for (int i = 0; i < len; i++) {\n//            values[i] = children[i].getNodeName();\n//        }\n//\n//        sortStrings(values, sortOrder);\n//    }\n//\n//    protected void sortFloats(float[] values, boolean sortOrder) {\n//        int len = values.length;\n//\n//        // Just the insertion sort - we will never get really large arrays here\n//        for (int i = 0; i < len; i++) {\n//            for (int j = i; (j > 0) && ((sortOrder == false) ? (values[j - 1] < values[j]) : (values[j - 1] > values[j])); j--) {\n//                float tmp = values[j];\n//                values[j] = values[j - 1];\n//                values[j - 1] = tmp;\n//\n//                PresoObjAllocCCTNode tmpCh = children[j];\n//                children[j] = children[j - 1];\n//                children[j - 1] = tmpCh;\n//            }\n//        }\n//    }\n//\n//    protected void sortInts(int[] values, boolean sortOrder) {\n//        int len = values.length;\n//\n//        // Just the insertion sort - we will never get really large arrays here\n//        for (int i = 0; i < len; i++) {\n//            for (int j = i; (j > 0) && ((sortOrder == false) ? (values[j - 1] < values[j]) : (values[j - 1] > values[j])); j--) {\n//                int tmp = values[j];\n//                values[j] = values[j - 1];\n//                values[j - 1] = tmp;\n//\n//                PresoObjAllocCCTNode tmpCh = children[j];\n//                children[j] = children[j - 1];\n//                children[j - 1] = tmpCh;\n//            }\n//        }\n//    }\n//\n//    protected void sortLongs(long[] values, boolean sortOrder) {\n//        int len = values.length;\n//\n//        // Just the insertion sort - we will never get really large arrays here\n//        for (int i = 0; i < len; i++) {\n//            for (int j = i; (j > 0) && ((sortOrder == false) ? (values[j - 1] < values[j]) : (values[j - 1] > values[j])); j--) {\n//                long tmp = values[j];\n//                values[j] = values[j - 1];\n//                values[j - 1] = tmp;\n//\n//                PresoObjAllocCCTNode tmpCh = children[j];\n//                children[j] = children[j - 1];\n//                children[j - 1] = tmpCh;\n//            }\n//        }\n//    }\n//\n//    protected void sortStrings(String[] values, boolean sortOrder) {\n//        int len = values.length;\n//\n//        // Just the insertion sort - we will never get really large arrays here\n//        for (int i = 0; i < len; i++) {\n//            for (int j = i;\n//                     (j > 0)\n//                     && ((sortOrder == false) ? (values[j - 1].compareTo(values[j]) < 0) : (values[j - 1].compareTo(values[j]) > 0));\n//                     j--) {\n//                String tmp = values[j];\n//                values[j] = values[j - 1];\n//                values[j - 1] = tmp;\n//\n//                PresoObjAllocCCTNode tmpCh = children[j];\n//                children[j] = children[j - 1];\n//                children[j - 1] = tmpCh;\n//            }\n//        }\n//    }\n\n    public void exportXMLData(ExportDataDumper eDD,String indent) {\n        String newline = System.getProperty(\"line.separator\"); // NOI18N\n        StringBuffer result = new StringBuffer(indent+\"<Node>\"+newline); //NOI18N\n        result.append(indent).append(\" <Name>\").append(replaceHTMLCharacters(getNodeName())).append(\"<Name>\").append(newline); //NOI18N\n        result.append(indent).append(\" <Parent>\").append(replaceHTMLCharacters((getParent()==null)?(\"none\"):(((PresoObjAllocCCTNode)getParent()).getNodeName()))).append(\"<Parent>\").append(newline); //NOI18N\n        result.append(indent).append(\" <Bytes_Allocated>\").append(totalObjSize).append(\"</Bytes_Allocated>\").append(newline); //NOI18N\n        result.append(indent).append(\" <Objects_Allocated>\").append(nCalls).append(\"</Objects_Allocated>\").append(newline); //NOI18N\n        eDD.dumpData(result); //dumps the current row\n        // children nodes\n        if (children!=null) {\n            for (int i = 0; i < getNChildren(); i++) {\n                children[i].exportXMLData(eDD, indent+\" \"); //NOI18N\n            }\n        }\n        result=new StringBuffer(indent+\"</Node>\"); //NOI18N\n        eDD.dumpData(result);\n    }\n\n    public void exportHTMLData(ExportDataDumper eDD, int depth) {\n        StringBuffer result = new StringBuffer(\"<tr><td class=\\\"method\\\"><pre class=\\\"method\\\">\"); //NOI18N\n        for (int i=0; i<depth; i++) {\n            result.append(\".\"); //NOI18N\n        }\n        result.append(replaceHTMLCharacters(getNodeName())).append(\"</pre></td><td class=\\\"right\\\">\").append(totalObjSize).append(\"</td><td class=\\\"right\\\">\").append(nCalls).append(\"</td><td class=\\\"parent\\\"><pre class=\\\"parent\\\">\").append(replaceHTMLCharacters((getParent()==null)?(\"none\"):(((PresoObjAllocCCTNode)getParent()).getNodeName()))).append(\"</pre></td></tr>\"); //NOI18N\n        eDD.dumpData(result); //dumps the current row\n        // children nodes\n        if (children!=null) {\n            for (PresoObjAllocCCTNode children1 : children) {\n                children1.exportHTMLData(eDD, depth+1);\n            }\n        }\n    }\n\n    private String replaceHTMLCharacters(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break; // NOI18N\n              case '>': sb.append(\"&gt;\"); break; // NOI18N\n              case '&': sb.append(\"&amp;\"); break; // NOI18N\n              case '\"': sb.append(\"&quot;\"); break; // NOI18N\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n\n    public void exportCSVData(String separator, int depth, ExportDataDumper eDD) {\n        StringBuffer result = new StringBuffer();\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n        String indent = \" \"; // NOI18N\n\n        // this node\n        result.append(quote);\n        for (int i=0; i<depth; i++) {\n            result.append(indent); // to simulate the tree structure in CSV\n        }\n        result.append(getNodeName()).append(quote).append(separator);\n        result.append(quote).append(totalObjSize).append(quote).append(separator);\n        result.append(quote).append(nCalls).append(quote).append(separator);\n        result.append(quote).append((getParent()==null)?(\"none\"):(((PresoObjAllocCCTNode)getParent()).getNodeName())).append(newLine); // NOI18N\n        eDD.dumpData(result); //dumps the current row\n        // children nodes\n        if (children!=null) {\n            for (PresoObjAllocCCTNode children1 : children) {\n                children1.exportCSVData(separator, depth+1, eDD);\n            }\n        }\n    }\n\n    String getClassName() {\n        if (className == null && entry != null) {\n            className = entry.className.replace('/', '.'); // NOI18N\n        }\n        return className;\n    }\n\n    String getMethodName() {\n        if (methodName == null && entry != null) {\n            methodName = entry.methodName;\n            if (entry.isNative) {\n                methodName = methodName.concat(JMethodIdTable.NATIVE_SUFFIX);\n            }   \n        }\n        return methodName;\n    }\n\n    String getMethodSig() {\n        if (entry != null) {\n            return entry.methodSig;\n        }\n        return null;\n    }\n    \n    static class Handle {\n\n        final PresoObjAllocCCTNode node;\n        \n        Handle(PresoObjAllocCCTNode n) {\n            node = n;\n        }\n\n        public int hashCode() {\n            return node.hashCode();\n        }\n\n        public boolean equals(Object obj) {\n            if (obj == this) return true;\n            \n            return node.equals(((Handle)obj).node);\n        }\n        \n        \n        \n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/PresoObjLivenessCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\n\n\n/**\n * Presentation-Time Object Liveness Profiling Calling Context Tree (CCT) Node.\n *\n * @author Misha Dmitriev\n */\npublic class PresoObjLivenessCCTNode extends PresoObjAllocCCTNode {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static int currentEpoch;\n    public static final int SORT_BY_LIVE_OBJ_SIZE = 1;\n    public static final int SORT_BY_LIVE_OBJ_NUMBER = 2;\n    public static final int SORT_BY_ALLOC_OBJ = 3;\n    public static final int SORT_BY_AVG_AGE = 4;\n    public static final int SORT_BY_SURV_GEN = 5;\n    public static final int SORT_BY_NAME = 6;\n    public static final int SORT_BY_TOTAL_ALLOC_OBJ = 7;\n    private static boolean dontShowZeroLiveObjNodes;\n//    public final NumberFormat decimalFormat = NumberFormat.getInstance(Locale.ENGLISH);\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    public float avgObjectAge;\n    public int nLiveObjects;\n    public int survGen;\n    public int nTotalAllocObjects = -1; // Only populated for root nodes\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public static PresoObjLivenessCCTNode rootNode(PresoObjLivenessCCTNode[] children) {\n        PresoObjLivenessCCTNode root = new PresoObjLivenessCCTNode();\n        root.setChildren(children);\n        return root;\n    }\n\n    public PresoObjLivenessCCTNode(String className, long nCalls, long totalObjSize, int nLiveObjects, int nTotalAllocObjects, float avgObjectAge, int survGen) {\n        super(className, nCalls, totalObjSize);\n        this.nLiveObjects = nLiveObjects;\n        this.nTotalAllocObjects = nTotalAllocObjects;\n        this.avgObjectAge = avgObjectAge;\n        this.survGen = survGen;\n    }\n    \n    PresoObjLivenessCCTNode() {}\n    \n    protected PresoObjLivenessCCTNode(RuntimeMemoryCCTNode rtNode) {\n        super(rtNode);\n    }\n    \n    \n    // --- Filtering support\n    \n    public PresoObjLivenessCCTNode createFilteredNode() {\n        PresoObjLivenessCCTNode filtered = new PresoObjLivenessCCTNode();\n        setupFilteredNode(filtered);        \n        return filtered;\n    }\n    \n     protected void setupFilteredNode(PresoObjLivenessCCTNode filtered) {\n        super.setupFilteredNode(filtered);\n        \n        filtered.nLiveObjects = nLiveObjects;\n        filtered.avgObjectAge = avgObjectAge;\n        filtered.survGen = survGen;\n    }\n    \n    public void merge(CCTNode node) {\n        if (node instanceof PresoObjLivenessCCTNode) {\n            PresoObjLivenessCCTNode _node = (PresoObjLivenessCCTNode)node;\n            \n            nLiveObjects += _node.nLiveObjects;\n            // TODO: use a more precise aggregation algorithm!!!\n            avgObjectAge = Math.max(avgObjectAge, _node.avgObjectAge);\n            survGen = Math.max(survGen, _node.survGen);\n            \n            super.merge(node);\n        }\n    }\n    \n    // ---\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static PresoObjLivenessCCTNode createPresentationCCTFromSnapshot(LivenessMemoryResultsSnapshot snapshot,\n                                                                         RuntimeMemoryCCTNode rootRuntimeNode,\n                                                                         String classTypeName, int curEpoch,\n                                                                         boolean dontShowZeroLiveObjAllocPaths) {\n        currentEpoch = curEpoch;\n        dontShowZeroLiveObjNodes = dontShowZeroLiveObjAllocPaths;\n\n        SurvGenSet survGens = new SurvGenSet();\n\n        PresoObjLivenessCCTNode rootNode = generateMirrorNode(rootRuntimeNode, survGens);\n\n        if (rootNode != null) { // null means there are no live objects for any allocation path\n            assignNamesToNodesFromSnapshot(snapshot.getJMethodIdTable(), rootNode, classTypeName);\n        }\n\n        return rootNode;\n    }\n\n    public static PresoObjAllocCCTNode createPresentationCCTFromVM(ProfilerClient profilerClient,\n                                                                   RuntimeMemoryCCTNode rootRuntimeNode, String classTypeName,\n                                                                   int curEpoch, boolean dontShowZeroLiveObjAllocPaths)\n        throws ClientUtils.TargetAppOrVMTerminated {\n        currentEpoch = curEpoch;\n        dontShowZeroLiveObjNodes = dontShowZeroLiveObjAllocPaths;\n\n        SurvGenSet survGens = new SurvGenSet();\n\n        PresoObjAllocCCTNode rootNode = generateMirrorNode(rootRuntimeNode, survGens);\n\n        if (rootNode != null) { // null means there are no live objects for any allocation path\n            assignNamesToNodesFromVM(profilerClient, rootNode, classTypeName);\n        }\n\n        return rootNode;\n    }\n    \n    \n    \n//    void merge(PresoObjAllocCCTNode node) {\n//        PresoObjLivenessCCTNode nodel = (PresoObjLivenessCCTNode)node;\n//        nLiveObjects += nodel.nLiveObjects;\n//        // TODO: use a more precise aggregation algorithm!!!\n//        avgObjectAge = Math.max(avgObjectAge, nodel.avgObjectAge);\n//        survGen = Math.max(survGen, nodel.survGen);\n//        \n//        super.merge(node);\n//    }\n\n    public void sortChildren(int sortBy, boolean sortOrder) {\n//        int nChildren = getNChildren();\n//\n//        if (nChildren == 0) {\n//            return;\n//        }\n//\n//        for (int i = 0; i < nChildren; i++) {\n//            children[i].sortChildren(sortBy, sortOrder);\n//        }\n//\n//        if (nChildren > 1) {\n//            switch (sortBy) {\n//                case SORT_BY_LIVE_OBJ_SIZE:\n//                    sortChildrenByLiveObjSize(sortOrder);\n//\n//                    break;\n//                case SORT_BY_LIVE_OBJ_NUMBER:\n//                    sortChildrenByLiveObjNumber(sortOrder);\n//\n//                    break;\n//                case SORT_BY_ALLOC_OBJ:\n//                    sortChildrenByAllocObjNumber(sortOrder);\n//\n//                    break;\n//                case SORT_BY_AVG_AGE:\n//                    sortChildrenByAvgAge(sortOrder);\n//\n//                    break;\n//                case SORT_BY_SURV_GEN:\n//                    sortChildrenBySurvGen(sortOrder);\n//\n//                    break;\n//                case SORT_BY_NAME:\n//                    sortChildrenByName(sortOrder);\n//\n//                    break;\n//            }\n//        }\n    }\n\n    protected static PresoObjLivenessCCTNode generateMirrorNode(RuntimeMemoryCCTNode rtNode, SurvGenSet survGens) {\n        PresoObjLivenessCCTNode thisNode = null;\n\n        if (rtNode instanceof RuntimeObjLivenessTermCCTNode) { // A \"terminal\" node may occur even in the middle of the call chain\n\n            RuntimeObjLivenessTermCCTNode rtTermNode = (RuntimeObjLivenessTermCCTNode) rtNode;\n            int nLiveObjects = rtTermNode.calculateTotalNLiveObjects();\n\n            if (dontShowZeroLiveObjNodes && (nLiveObjects == 0) && (rtNode.children == null)) {\n                return null;\n            }\n\n            thisNode = new PresoObjLivenessCCTNode(rtNode);\n            thisNode.nLiveObjects = nLiveObjects;\n            //thisNode.survGen = RuntimeObjLivenessTermCCTNode.calculateTotalNumberOfSurvGensForAllPaths(rtTermNode);\n            RuntimeObjLivenessTermCCTNode.calculateTotalNumberOfSurvGens(rtTermNode, survGens);\n            thisNode.survGen = survGens.getTotalNoOfAges();\n            thisNode.avgObjectAge = RuntimeObjLivenessTermCCTNode.calculateAvgObjectAgeForAllPaths(rtTermNode, currentEpoch);\n\n            if (rtNode.children != null) {\n                int len = (rtNode.children instanceof RuntimeMemoryCCTNode) ? 1 : ((RuntimeMemoryCCTNode[]) rtNode.children).length;\n                thisNode.children = new PresoObjAllocCCTNode[len];\n            }\n        }\n\n        Object nodeChildren = rtNode.children;\n\n        if (nodeChildren != null) {\n            RuntimeMemoryCCTNode[] ar;\n\n            if (nodeChildren instanceof RuntimeMemoryCCTNode) {\n                ar = new RuntimeMemoryCCTNode[1];\n                ar[0] = (RuntimeMemoryCCTNode) nodeChildren;\n            } else {\n                ar = (RuntimeMemoryCCTNode[]) nodeChildren;\n            }\n\n            int nChildren = ar.length;\n\n            if (nChildren > 0) {\n                double avgAge = 0;\n                int childIdx = 0;\n\n                for (int i = 0; i < nChildren; i++) {\n                    SurvGenSet subNodeSurvGens = (nChildren == 1) ? survGens : new SurvGenSet();\n                    PresoObjLivenessCCTNode child = (PresoObjLivenessCCTNode) generateMirrorNode(ar[i], subNodeSurvGens);\n\n                    if (child != null) {\n                        if (thisNode == null) {\n                            thisNode = new PresoObjLivenessCCTNode(rtNode);\n                            thisNode.children = new PresoObjAllocCCTNode[nChildren];\n                        }\n                    } else {\n                        continue;\n                    }\n\n                    thisNode.children[childIdx++] = child;\n                    child.parent = thisNode;\n                    thisNode.nCalls += child.nCalls;\n                    thisNode.totalObjSize += child.totalObjSize;\n                    thisNode.nLiveObjects += child.nLiveObjects;\n                    avgAge += (child.avgObjectAge * child.nLiveObjects);\n\n                    if (nChildren > 1) {\n                        survGens.mergeWith(subNodeSurvGens);\n                    }\n                }\n\n                if (dontShowZeroLiveObjNodes && ((thisNode == null) || (thisNode.nLiveObjects == 0))) {\n                    return null;\n                }\n\n                if (childIdx < nChildren) {\n                    PresoObjAllocCCTNode[] newChildren = new PresoObjAllocCCTNode[childIdx];\n                    System.arraycopy(thisNode.children, 0, newChildren, 0, childIdx);\n                    thisNode.children = newChildren;\n                }\n\n                thisNode.avgObjectAge = (thisNode.nLiveObjects > 0) ? (float) (avgAge / thisNode.nLiveObjects) : 0;\n                thisNode.survGen = survGens.getTotalNoOfAges();\n            }\n        }\n\n        return thisNode;\n    }\n\n//    protected void sortChildrenByAvgAge(boolean sortOrder) {\n//        int len = children.length;\n//        float[] values = new float[len];\n//\n//        for (int i = 0; i < len; i++) {\n//            values[i] = ((PresoObjLivenessCCTNode) children[i]).avgObjectAge;\n//        }\n//\n//        sortFloats(values, sortOrder);\n//    }\n//\n//    protected void sortChildrenByLiveObjNumber(boolean sortOrder) {\n//        int len = children.length;\n//        int[] values = new int[len];\n//\n//        for (int i = 0; i < len; i++) {\n//            values[i] = ((PresoObjLivenessCCTNode) children[i]).nLiveObjects;\n//        }\n//\n//        sortInts(values, sortOrder);\n//    }\n//\n//    protected void sortChildrenByLiveObjSize(boolean sortOrder) {\n//        sortChildrenByAllocObjSize(sortOrder);\n//    }\n//\n//    protected void sortChildrenBySurvGen(boolean sortOrder) {\n//        int len = children.length;\n//        int[] values = new int[len];\n//\n//        for (int i = 0; i < len; i++) {\n//            values[i] = ((PresoObjLivenessCCTNode) children[i]).survGen;\n//        }\n//\n//        sortInts(values, sortOrder);\n//    }\n\n    @Override\n    public void exportXMLData(ExportDataDumper eDD,String indent) {\n        String newline = System.getProperty(\"line.separator\"); // NOI18N\n        StringBuffer result = new StringBuffer(indent+\"<Node>\"+newline); //NOI18N\n        result.append(indent).append(\" <Name>\").append(replaceHTMLCharacters(getNodeName())).append(\"</Name>\").append(newline); //NOI18N\n        result.append(indent).append(\" <Parent>\").append(replaceHTMLCharacters((getParent()==null)?(\"none\"):(((PresoObjAllocCCTNode)getParent()).getNodeName()))).append(\"</Parent>\").append(newline); //NOI18N\n        result.append(indent).append(\" <Live_Bytes>\").append(totalObjSize).append(\"</Live_Bytes>\").append(newline); //NOI18N\n        result.append(indent).append(\" <Live_Objects>\").append(nLiveObjects).append(\"</Live_Objects>\").append(newline); //NOI18N\n        result.append(indent).append(\" <Allocated_Objects>\").append(nCalls).append(\"</Allocated_Objects>\").append(newline); //NOI18N\n        result.append(indent).append(\" <Avg_Age>\").append(avgObjectAge).append(\"</Avg_Age>\").append(newline); //NOI18N\n        result.append(indent).append(\" <Generations>\").append(survGen).append(\"</Generations>\").append(newline); //NOI18N\n        eDD.dumpData(result); //dumps the current row\n        // children nodes\n        if (children!=null) {\n            for (int i = 0; i < getNChildren(); i++) {\n                children[i].exportXMLData(eDD, indent+\" \"); //NOI18N\n            }\n        }\n        result=new StringBuffer(indent+\"</Node>\"); //NOI18N\n        eDD.dumpData(result);\n    }\n\n    @Override\n    public void exportHTMLData(ExportDataDumper eDD, int depth) {\n        StringBuffer result = new StringBuffer(\"<tr><td class=\\\"method\\\"><pre class=\\\"method\\\">\"); //NOI18N\n        for (int i=0; i<depth; i++) {\n            result.append(\".\"); //NOI18N\n        }\n        result.append(replaceHTMLCharacters(getNodeName())).append(\"</pre></td><td class=\\\"right\\\">\").append(totalObjSize).append(\"</td><td class=\\\"right\\\">\").append(nLiveObjects).append(\"</td><td class=\\\"right\\\">\").append(nCalls).append(\"</td><td class=\\\"right\\\">\").append(avgObjectAge).append(\"</td><td class=\\\"right\\\">\").append(survGen).append(\"</td><td class=\\\"parent\\\"><pre class=\\\"parent\\\">\").append(replaceHTMLCharacters((getParent()==null)?(\"none\"):(((PresoObjAllocCCTNode)getParent()).getNodeName()))).append(\"</pre></td></tr>\"); //NOI18N\n        eDD.dumpData(result); //dumps the current row\n        // children nodes\n        if (children!=null) {\n            for (PresoObjAllocCCTNode children1 : children) {\n                children1.exportHTMLData(eDD, depth+1);\n            }\n        }\n    }\n\n    private String replaceHTMLCharacters(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break; // NOI18N\n              case '>': sb.append(\"&gt;\"); break; // NOI18N\n              case '&': sb.append(\"&amp;\"); break; // NOI18N\n              case '\"': sb.append(\"&quot;\"); break; // NOI18N\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n\n    @Override\n    public void exportCSVData(String separator, int depth, ExportDataDumper eDD) {\n        StringBuffer result = new StringBuffer();\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n        String indent = \" \"; // NOI18N\n\n        // this node\n        result.append(quote);\n        for (int i=0; i<depth; i++) {\n            result.append(indent); // to simulate the tree structure in CSV\n        }\n        result.append(getNodeName()).append(quote).append(separator);\n        result.append(quote).append(totalObjSize).append(quote).append(separator);\n        result.append(quote).append(nLiveObjects).append(quote).append(separator);\n        result.append(quote).append(nCalls).append(quote).append(separator);\n//        result.append(quote).append(decimalFormat.format(avgObjectAge)).append(quote).append(separator);\n        result.append(quote).append(survGen).append(quote).append(separator);\n        result.append(quote).append((getParent()==null)?(\"none\"):(((PresoObjAllocCCTNode)getParent()).getNodeName())).append(newLine); // NOI18N\n        eDD.dumpData(result); //dumps the current row\n        // children nodes\n        if (children!=null) {\n            for (PresoObjAllocCCTNode children1 : children) {\n                ((PresoObjLivenessCCTNode) children1).exportCSVData(separator, depth+1, eDD);\n            }\n        }\n    }\n\n    public void setDecimalFormat() {\n//        decimalFormat.setMinimumFractionDigits(3);\n//        decimalFormat.setMaximumFractionDigits(3);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/RuntimeMemoryCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\n\n/**\n * A node of the run time Memory Profiling Calling Context Tree (CCT). Unlike the presentation-time CCT, this one\n * contains information in the form that is quickly updateable at run time, but needs further processing for\n * proper presentation. Instances of class RuntimeMemoryCCTNode are used only as non-terminal nodes, and contain\n * minimum information to save space. The information such as the total number of calls, size of allocated objects,\n * etc., which can be calculated  for intermediate nodes if known for terminal nodes, is contained, in runtime CCT,\n * only in specialized terminal nodes (instances of classes RuntimeObjAllocTermCCTNode and\n * RuntimeObjLivenessTermCCTNode).\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class RuntimeMemoryCCTNode implements Cloneable, RuntimeCCTNode {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final RuntimeCCTNode[] EMPTY_CHILDREN = new RuntimeMemoryCCTNode[0];\n\n    protected static final int TYPE_RuntimeMemoryCCTNode = 1;\n    protected static final int TYPE_RuntimeObjAllocTermCCTNode = 2;\n    protected static final int TYPE_RuntimeObjLivenessTermCCTNode = 3;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    /** Children nodes in the forward stack trace tree. This field can have three different values depending on the\n     * number of children:\n     *   null if there are no children\n     *   instance of RuntimeMemoryCCTNode if there is exactly one child\n     *   instance of RuntimeMemoryCCTNode[] if there are multiple children\n     * This is purely a memory consumption optimization, which typically saves about 80% of memory, since most allocation\n     * stack traces are a sequence of single-child nodes, and in such case we remove the need to create a one-item array\n     */\n    public Object children;\n\n    /** unique Id of method - jMethodId from JVM (see MemoryCallGraphBuilder.getNamesForJMethodIds) */\n    public int methodId;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** For I/O only */\n    protected RuntimeMemoryCCTNode() {\n    }\n\n    public RuntimeMemoryCCTNode(int methodId) {\n        this.methodId = methodId;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getType() {\n        return TYPE_RuntimeMemoryCCTNode;\n    }\n\n    public static RuntimeMemoryCCTNode create(int type) {\n        switch (type) {\n            case TYPE_RuntimeMemoryCCTNode:\n                return new RuntimeMemoryCCTNode();\n            case TYPE_RuntimeObjAllocTermCCTNode:\n                return new RuntimeObjAllocTermCCTNode();\n            case TYPE_RuntimeObjLivenessTermCCTNode:\n                return new RuntimeObjLivenessTermCCTNode();\n        }\n\n        throw new IllegalArgumentException(\"Illegal type: \" + type); // NOI18N\n    }\n\n    public RuntimeMemoryCCTNode addNewChild(int methodId) {\n        if (children == null) {\n            children = new RuntimeMemoryCCTNode(methodId);\n\n            return (RuntimeMemoryCCTNode) children;\n        } else {\n            RuntimeMemoryCCTNode[] ar = addChildEntry();\n\n            return (ar[ar.length - 1] = new RuntimeMemoryCCTNode(methodId));\n        }\n    }\n\n    public void attachNodeAsChild(RuntimeMemoryCCTNode node) {\n        if (children == null) {\n            children = node;\n        } else {\n            RuntimeMemoryCCTNode[] ar = addChildEntry();\n            ar[ar.length - 1] = node;\n        }\n    }\n\n    @Override\n    public RuntimeCCTNode[] getChildren() {\n        if (children == null) {\n            return EMPTY_CHILDREN;\n        } else if (children instanceof RuntimeCCTNode) {\n            return new RuntimeCCTNode[]{(RuntimeCCTNode)children};\n        } else if (children instanceof RuntimeCCTNode[]) {\n            return (RuntimeCCTNode[])children;\n        }\n        return EMPTY_CHILDREN;\n    }\n\n    public Object clone() {\n        try {\n            RuntimeMemoryCCTNode ret = (RuntimeMemoryCCTNode) super.clone();\n\n            if (children != null) {\n                if (children instanceof RuntimeMemoryCCTNode) {\n                    ret.children = ((RuntimeMemoryCCTNode) children).clone();\n                } else {\n                    RuntimeMemoryCCTNode[] ar = (RuntimeMemoryCCTNode[]) children;\n                    ret.children = new RuntimeMemoryCCTNode[ar.length];\n\n                    for (int i = 0; i < ar.length; i++) {\n                        ((RuntimeMemoryCCTNode[]) ret.children)[i] = (RuntimeMemoryCCTNode) ar[i].clone();\n                    }\n                }\n            }\n\n            return ret;\n        } catch (CloneNotSupportedException e) {\n            throw new InternalError(\"Clone should never fail\"); // NOI18N\n        }\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        methodId = in.readInt();\n\n        int len = in.readInt();\n\n        if (len == 0) {\n            children = null;\n        } else if (len == 1) {\n            int type = in.readInt();\n            children = RuntimeMemoryCCTNode.create(type);\n            ((RuntimeMemoryCCTNode) children).readFromStream(in);\n        } else {\n            RuntimeMemoryCCTNode[] ar = new RuntimeMemoryCCTNode[len];\n\n            for (int i = 0; i < len; i++) {\n                int type = in.readInt();\n                ar[i] = RuntimeMemoryCCTNode.create(type);\n                ar[i].readFromStream(in);\n            }\n\n            children = ar;\n        }\n    }\n\n    public void writeToStream(DataOutputStream out) throws IOException {\n        out.writeInt(methodId);\n\n        if (children == null) {\n            out.writeInt(0);\n        } else if (children instanceof RuntimeMemoryCCTNode) {\n            out.writeInt(1);\n            out.writeInt(((RuntimeMemoryCCTNode) children).getType());\n            ((RuntimeMemoryCCTNode) children).writeToStream(out);\n        } else {\n            RuntimeMemoryCCTNode[] ar = (RuntimeMemoryCCTNode[]) children;\n            out.writeInt(ar.length);\n\n            for (RuntimeMemoryCCTNode ar1 : ar) {\n                out.writeInt(ar1.getType());\n                ar1.writeToStream(out);\n            }\n        }\n    }\n\n    private RuntimeMemoryCCTNode[] addChildEntry() {\n        assert (children != null);\n\n        if (children instanceof RuntimeMemoryCCTNode) {\n            // currently just single child\n            RuntimeMemoryCCTNode[] ret = new RuntimeMemoryCCTNode[2];\n            ret[0] = (RuntimeMemoryCCTNode) children;\n            children = ret;\n\n            return ret;\n        } else {\n            RuntimeMemoryCCTNode[] ar = (RuntimeMemoryCCTNode[]) children;\n            RuntimeMemoryCCTNode[] newchildren = new RuntimeMemoryCCTNode[ar.length + 1];\n            System.arraycopy(ar, 0, newchildren, 0, ar.length);\n            children = newchildren;\n\n            return newchildren;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/RuntimeObjAllocTermCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\n\n\n/**\n * A terminal node used in Object Allocation Profiling Calling Context Tree (CCT).\n * Contains the information gathered during object allocation profiling, which can be calculated  for intermediate nodes\n * if known for terminal nodes.\n * <p>\n * Normally used as a leaf, except in case there are multiple same paths in the tree with different length\n * <p>\n * The information in TermCCTNode represents all objects of the same type allocated using same call path.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class RuntimeObjAllocTermCCTNode extends RuntimeMemoryCCTNode {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    public long nCalls; // # of invocations\n    public long totalObjSize; // object size in Bytes\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public RuntimeObjAllocTermCCTNode(int methodId) {\n        super(methodId);\n    }\n\n    protected RuntimeObjAllocTermCCTNode() {\n    } // only for I/O\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getType() {\n        return TYPE_RuntimeObjAllocTermCCTNode;\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        super.readFromStream(in);\n        nCalls = in.readLong();\n        totalObjSize = in.readLong();\n    }\n\n    public void updateForNewObject(long objSize) {\n        nCalls++;\n        totalObjSize += objSize;\n    }\n\n    public void updateForRemovedObject(long objSize) {\n        totalObjSize -= objSize;\n    }\n\n    public void writeToStream(DataOutputStream out) throws IOException {\n        super.writeToStream(out);\n        out.writeLong(nCalls);\n        out.writeLong(totalObjSize);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/RuntimeObjLivenessTermCCTNode.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\n\n\n/**\n * A terminal node used in Object Liveness Profiling Calling Context Tree (CCT).\n * Contains the information gathered during object liveness profiling, which can be calculated  for intermediate nodes\n * if known for terminal nodes.\n * <p>\n * Normally used as a leaf, except in case there are multiple same paths in the tree with differfent length.\n * <p>\n * The information in TermCCTNode represents all objects of the same type allocated using same call path.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class RuntimeObjLivenessTermCCTNode extends RuntimeObjAllocTermCCTNode {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    // info on surviving generation\n    // [0] - epoch number\n    // [1] - # allocated in given epoch\n    // e.g.\n    // +---------+\n    // | 1  | 4  |\n    // | 5  | 3  |\n    // | 6  | 34 |\n    // | 14 | 56 |\n    // +---------+\n    private int[][] epochAndNLiveObjects; // null in static snapshots\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public RuntimeObjLivenessTermCCTNode(int methodId) {\n        super(methodId);\n    }\n\n    protected RuntimeObjLivenessTermCCTNode() {\n    } // only for I/O\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getType() {\n        return TYPE_RuntimeObjLivenessTermCCTNode;\n    }\n\n    /**\n     * Only called (from ObjLivenessCallGraphBuilder) when processing results during profiled app runtime\n     */\n    public void addLiveObjectForEpoch(int epoch) {\n        if (epochAndNLiveObjects == null) {\n            epochAndNLiveObjects = new int[2][2];\n            epochAndNLiveObjects[0][0] = epochAndNLiveObjects[0][1] = -1;\n        }\n\n        int len = epochAndNLiveObjects[0].length;\n        int lenMinusOne = len - 1;\n        int row = lenMinusOne;\n\n        while ((epochAndNLiveObjects[0][row] == -1) && (row > 0)) {\n            row--;\n        }\n\n        if (epochAndNLiveObjects[0][row] > -1) { // Some epochs already exist\n\n            if (epochAndNLiveObjects[0][row] < epoch) { // This epoch is newer than the newest recorded one; need to open a new epoch\n\n                if (row == lenMinusOne) {\n                    int[][] newEpochAndNLiveObjects = new int[2][len + 2];\n                    System.arraycopy(epochAndNLiveObjects[0], 0, newEpochAndNLiveObjects[0], 0, len);\n                    System.arraycopy(epochAndNLiveObjects[1], 0, newEpochAndNLiveObjects[1], 0, len);\n                    epochAndNLiveObjects = newEpochAndNLiveObjects;\n                    epochAndNLiveObjects[0][len] = epochAndNLiveObjects[0][len + 1] = -1;\n                }\n\n                row++;\n            } else {\n                // Search if this epoch exists at all. Such a thing (an object allocation record for an old epoch arriving when\n                // a newer epoch(s) have already been opened) may happen in heavily multithreaded programs, where rescheduling\n                // happens when a thread is inside our ProfilerRuntimeObjLiveness.traceObjAlloc() method.\n                while ((row > 0) && (epochAndNLiveObjects[0][row] != epoch)) {\n                    row--;\n                }\n\n                if (epochAndNLiveObjects[0][row] != epoch) { // Pathological case. We don't track them - they shouldn't be frequent anyway.\n\n                    return;\n                }\n            }\n        }\n\n        epochAndNLiveObjects[0][row] = epoch;\n        epochAndNLiveObjects[1][row]++;\n    }\n\n    public static float calculateAvgObjectAgeForAllPaths(RuntimeMemoryCCTNode rootNode, int currentEpoch) {\n        int[] nObjAndAge = new int[2];\n        calculateNObjAndAge(rootNode, currentEpoch, nObjAndAge);\n\n        if (nObjAndAge[0] == 0) {\n            return 0.0f; // Zero live objects - zero age\n        }\n\n        return (float) ((double) nObjAndAge[1] / (double) nObjAndAge[0]);\n    }\n\n    /**\n     * Works with epoch\n     */\n    public int calculateTotalNLiveObjects() {\n        if (epochAndNLiveObjects == null) {\n            return 0;\n        }\n\n        int res = 0;\n        int row = 0;\n        int len = epochAndNLiveObjects[0].length;\n\n        while ((row < len) && (epochAndNLiveObjects[0][row] != -1)) {\n            res += epochAndNLiveObjects[1][row];\n            row++;\n        }\n\n        return res;\n    }\n\n    public static int calculateTotalNumberOfSurvGensForAllPaths(RuntimeMemoryCCTNode rootNode) {\n        SurvGenSet sgSet = new SurvGenSet();\n        calculateTotalNumberOfSurvGens(rootNode, sgSet);\n\n        return sgSet.getTotalNoOfAges();\n    }\n\n    public Object clone() {\n        RuntimeObjLivenessTermCCTNode ret = (RuntimeObjLivenessTermCCTNode) super.clone();\n\n        if (epochAndNLiveObjects == null) {\n            ret.epochAndNLiveObjects = null;\n        } else {\n            int len = epochAndNLiveObjects[0].length;\n            ret.epochAndNLiveObjects = new int[2][len];\n            System.arraycopy(epochAndNLiveObjects[0], 0, ret.epochAndNLiveObjects[0], 0, len);\n            System.arraycopy(epochAndNLiveObjects[1], 0, ret.epochAndNLiveObjects[1], 0, len);\n        }\n\n        return ret;\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        super.readFromStream(in);\n\n        int len = in.readInt();\n\n        epochAndNLiveObjects = new int[2][len];\n\n        for (int i = 0; i < len; i++) {\n            epochAndNLiveObjects[0][i] = in.readInt();\n            epochAndNLiveObjects[1][i] = in.readInt();\n        }\n    }\n\n    /**\n     * Only called (from ObjLivenessCallGraphBuilder) when processing results during profiled app runtime\n     */\n    public void removeLiveObjectForEpoch(int epoch) {\n        assert (epochAndNLiveObjects != null);\n\n        int len = epochAndNLiveObjects[0].length;\n        int lenMinusOne = len - 1;\n        int row = lenMinusOne;\n\n        while ((epochAndNLiveObjects[0][row] != epoch) && (row > 0)) {\n            row--;\n        }\n\n        if (epochAndNLiveObjects[0][row] != epoch) { // Pathological case. We don't track them - they shouldn't be frequent anyway.\n\n            return;\n        }\n\n        epochAndNLiveObjects[1][row]--;\n\n        if (epochAndNLiveObjects[1][row] == 0) { // Perform array compaction\n\n            if (row < lenMinusOne) {\n                if (!((row < lenMinusOne) && (epochAndNLiveObjects[0][row + 1] == -1))) { // There are non-empty rows behind this one\n                    System.arraycopy(epochAndNLiveObjects[0], row + 1, epochAndNLiveObjects[0], row, lenMinusOne - row);\n                    System.arraycopy(epochAndNLiveObjects[1], row + 1, epochAndNLiveObjects[1], row, lenMinusOne - row);\n                } else {\n                    epochAndNLiveObjects[0][row] = -1;\n                }\n            }\n\n            epochAndNLiveObjects[0][lenMinusOne] = -1;\n            epochAndNLiveObjects[1][lenMinusOne] = 0;\n        }\n    }\n\n    public void writeToStream(DataOutputStream out) throws IOException {\n        super.writeToStream(out);\n\n        int len = (epochAndNLiveObjects == null) ? 0 : epochAndNLiveObjects[0].length;\n        out.writeInt(len);\n\n        for (int i = 0; i < len; i++) {\n            out.writeInt(epochAndNLiveObjects[0][i]);\n            out.writeInt(epochAndNLiveObjects[1][i]);\n        }\n    }\n\n    /**\n     * Works with epoch\n     */\n    protected static void calculateNObjAndAge(RuntimeMemoryCCTNode node, int currentEpoch, int[] nObjAndAge) {\n        if (node instanceof RuntimeObjLivenessTermCCTNode) {\n            RuntimeObjLivenessTermCCTNode thisNode = (RuntimeObjLivenessTermCCTNode) node;\n            int[][] epochAndNLiveObjects = thisNode.epochAndNLiveObjects;\n\n            if (epochAndNLiveObjects != null) {\n                int row = 0;\n                int len = epochAndNLiveObjects[0].length;\n\n                while ((row < len) && (epochAndNLiveObjects[0][row] != -1)) {\n                    nObjAndAge[0] += epochAndNLiveObjects[1][row]; // Add the number of objects for this epoch\n                    nObjAndAge[1] += (epochAndNLiveObjects[1][row] * (currentEpoch - epochAndNLiveObjects[0][row])); // Add their total age\n                    row++;\n                }\n            }\n        }\n\n        if (node.children != null) {\n            if (node.children instanceof RuntimeMemoryCCTNode) {\n                calculateNObjAndAge((RuntimeMemoryCCTNode) node.children, currentEpoch, nObjAndAge);\n            } else {\n                RuntimeMemoryCCTNode[] ar = (RuntimeMemoryCCTNode[]) node.children;\n\n                for (RuntimeMemoryCCTNode ar1 : ar) {\n                    calculateNObjAndAge(ar1, currentEpoch, nObjAndAge);\n                }\n            }\n        }\n    }\n\n    /**\n     * Works with epoch\n     */\n    protected static void calculateTotalNumberOfSurvGens(RuntimeMemoryCCTNode node, SurvGenSet sgSet) {\n        if (node instanceof RuntimeObjLivenessTermCCTNode) {\n            RuntimeObjLivenessTermCCTNode thisNode = (RuntimeObjLivenessTermCCTNode) node;\n            int[][] epochAndNLiveObjects = thisNode.epochAndNLiveObjects;\n\n            if (epochAndNLiveObjects != null) {\n                int[] epochs = epochAndNLiveObjects[0];\n                int len = epochs.length;\n\n                for (int i = 0; i < len; i++) {\n                    if (epochs[i] != -1) {\n                        sgSet.addAge(epochs[i]);\n                    } else {\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (node.children != null) {\n            if (node.children instanceof RuntimeMemoryCCTNode) {\n                calculateTotalNumberOfSurvGens((RuntimeMemoryCCTNode) node.children, sgSet);\n            } else {\n                RuntimeMemoryCCTNode[] ar = (RuntimeMemoryCCTNode[]) node.children;\n\n                for (RuntimeMemoryCCTNode ar1 : ar) {\n                    calculateTotalNumberOfSurvGens(ar1, sgSet);\n                }\n            }\n        }\n    }\n\n    /**\n     * Works with epoch\n     */\n    protected void dumpEpochs() {\n        if (epochAndNLiveObjects != null) {\n            int len = epochAndNLiveObjects[0].length;\n\n            for (int i = 0; i < len; i++) {\n                System.err.println(\"epoch = \" + epochAndNLiveObjects[0][i] + \", objno = \" + epochAndNLiveObjects[1][i]); // NOI18N\n            }\n        } else {\n            System.err.println(\"epoch = null\"); // NOI18N\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/SampledMemoryResultsDiff.java",
    "content": "/*\n * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.Map;\n\n/**\n * Class representing a difference between two snapshots, diffing only values\n * available in SampledMemoryResultsSnapshot\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic class SampledMemoryResultsDiff extends SampledMemoryResultsSnapshot {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int[] objectsCounts;\n    private int nClasses;\n    private long maxObjectsSizePerClassDiff;\n    private long minObjectsSizePerClassDiff;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n    public SampledMemoryResultsDiff(SampledMemoryResultsSnapshot snapshot1, SampledMemoryResultsSnapshot snapshot2) {\n        computeDiff(snapshot1, snapshot2);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    public long getBeginTime() {\n        return -1;\n    }\n\n    public String getClassName(int classId) {\n        return null;\n    }\n\n    public String[] getClassNames() {\n        return classNames;\n    }\n\n    public JMethodIdTable getJMethodIdTable() {\n        return null;\n    }\n\n    public long getMaxObjectsSizePerClassDiff() {\n        return maxObjectsSizePerClassDiff;\n    }\n\n    public long getMinObjectsSizePerClassDiff() {\n        return minObjectsSizePerClassDiff;\n    }\n\n    public int getNProfiledClasses() {\n        return nClasses;\n    }\n\n    public int[] getObjectsCounts() {\n        return objectsCounts;\n    }\n\n    public long[] getObjectsSizePerClass() {\n        return objectsSizePerClass;\n    }\n\n    public long getTimeTaken() {\n        return -1;\n    }\n\n    public boolean containsStacks() {\n        return false;\n    }\n\n    public PresoObjAllocCCTNode createPresentationCCT(int classId, boolean dontShowZeroLiveObjAllocPaths) {\n        return null;\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        throw new UnsupportedOperationException(\"Persistence not supported for snapshot comparison\"); // NOI18N\n    }\n\n    //---- Serialization support\n    public void writeToStream(DataOutputStream out) throws IOException {\n        throw new UnsupportedOperationException(\"Persistence not supported for snapshot comparison\"); // NOI18N\n    }\n\n    protected PresoObjAllocCCTNode createPresentationCCT(RuntimeMemoryCCTNode rootNode, int classId,\n            boolean dontShowZeroLiveObjAllocPaths) {\n        return null;\n    }\n\n    private void computeDiff(SampledMemoryResultsSnapshot snapshot1, SampledMemoryResultsSnapshot snapshot2) {\n        // must detect the minimum, same approach as in SnapshotAllocResultsPanel.fetchResultsFromSnapshot()\n        int s1nClasses = Math.min(snapshot1.getNProfiledClasses(), snapshot1.getObjectsCounts().length);\n        s1nClasses = Math.min(s1nClasses, snapshot1.getObjectsSizePerClass().length);\n\n        int s2nClasses = Math.min(snapshot2.getNProfiledClasses(), snapshot2.getObjectsCounts().length);\n        s2nClasses = Math.min(s2nClasses, snapshot2.getObjectsSizePerClass().length);\n\n        // temporary cache for creating diff\n        HashMap<String, Integer> classNamesIdxMap = new HashMap(s1nClasses);\n        ArrayList<Integer> objCountsArr = new ArrayList(s1nClasses);\n        ArrayList<Long> objSizesArr = new ArrayList(s1nClasses);\n\n        // fill the cache with negative values from snapshot1\n        String[] s1ClassNames = snapshot1.getClassNames();\n        int[] s1ObjectsCount = snapshot1.getObjectsCounts();\n        long[] s1ObjectsSizes = snapshot1.getObjectsSizePerClass();\n\n        for (int i = 0; i < s1nClasses; i++) {\n            Integer classIdx = classNamesIdxMap.get(s1ClassNames[i]);\n\n            if (classIdx != null) { // duplicate classname - add objCountsArr and objSizesArr to original classname\n                objCountsArr.set(classIdx, objCountsArr.get(classIdx) - s1ObjectsCount[i]);\n                objSizesArr.set(classIdx, objSizesArr.get(classIdx) - s1ObjectsSizes[i]);\n            } else {\n                classNamesIdxMap.put(s1ClassNames[i], objCountsArr.size());\n                objCountsArr.add(-s1ObjectsCount[i]);\n                objSizesArr.add(-s1ObjectsSizes[i]);\n            }\n        }\n\n        // create diff using values from snapshot2\n        String[] s2ClassNames = snapshot2.getClassNames();\n        int[] s2ObjectsCount = snapshot2.getObjectsCounts();\n        long[] s2ObjectsSizes = snapshot2.getObjectsSizePerClass();\n\n        for (int i = 0; i < s2nClasses; i++) {\n            int objectsCount = s2ObjectsCount[i];\n            Integer classIdx = classNamesIdxMap.get(s2ClassNames[i]);\n\n            if (classIdx != null) {\n                // class already present in snapshot1\n                if (objectsCount != 0 || objCountsArr.get(classIdx) != 0) { // Do not add classes not displayed in compared snapshots (zero instances number)\n                    objCountsArr.set(classIdx, objCountsArr.get(classIdx) + objectsCount);\n                    objSizesArr.set(classIdx, objSizesArr.get(classIdx) + s2ObjectsSizes[i]);\n                } else {\n                    classNamesIdxMap.remove(s2ClassNames[i]); // Remove classname that should not be displayed\n                }\n            } else {\n                // class not present in snapshot1\n                if (objectsCount != 0) { // Do not add classes not displayed in compared snapshots (zero instances number)\n                    classNamesIdxMap.put(s2ClassNames[i], objCountsArr.size());\n                    objCountsArr.add(objectsCount);\n                    objSizesArr.add(s2ObjectsSizes[i]);\n                }\n            }\n        }\n\n        // move the diff to instance variables\n        nClasses = classNamesIdxMap.size();\n        classNames = new String[nClasses];\n        objectsCounts = new int[nClasses];\n        objectsSizePerClass = new long[nClasses];\n        minObjectsSizePerClassDiff = Long.MAX_VALUE;\n        maxObjectsSizePerClassDiff = Long.MIN_VALUE;\n\n        Iterator<Map.Entry<String, Integer>> classNamesIter = classNamesIdxMap.entrySet().iterator();\n        int index = 0;\n\n        while (classNamesIter.hasNext()) {\n            Map.Entry<String, Integer> entry = classNamesIter.next();\n            int classIndex =  entry.getValue();\n\n            classNames[index] = entry.getKey();\n            objectsCounts[index] = objCountsArr.get(classIndex);\n            objectsSizePerClass[index] = objSizesArr.get(classIndex);\n\n            minObjectsSizePerClassDiff = Math.min(minObjectsSizePerClassDiff, objectsSizePerClass[index]);\n            maxObjectsSizePerClassDiff = Math.max(maxObjectsSizePerClassDiff, objectsSizePerClass[index]);\n\n            index++;\n        }\n\n        if ((minObjectsSizePerClassDiff > 0) && (maxObjectsSizePerClassDiff > 0)) {\n            minObjectsSizePerClassDiff = 0;\n        } else if ((minObjectsSizePerClassDiff < 0) && (maxObjectsSizePerClassDiff < 0)) {\n            maxObjectsSizePerClassDiff = 0;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/SampledMemoryResultsSnapshot.java",
    "content": "/*\n * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.text.MessageFormat;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\n\n\n/**\n * Results snapshot for Sampled Memory Profiling.\n *\n * @author Ian Formanek\n * @author Tomas Hurka\n */\npublic class SampledMemoryResultsSnapshot extends MemoryResultsSnapshot {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String MEMORY_SAMPLED_MSG = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.results.memory.Bundle\").getString(\"SampledMemoryResultsSnapshot_MemorySamledMsg\"); // NOI18N\n                                                                                                                    // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int[] liveObjectsCounts;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SampledMemoryResultsSnapshot() {\n    } // No-arg constructor needed for above serialization methods to work\n\n    public SampledMemoryResultsSnapshot(long beginTime, long timeTaken, ProfilerClient client)\n                               throws ClientUtils.TargetAppOrVMTerminated {\n        super(beginTime, timeTaken, null, client);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int[] getObjectsCounts() {\n        return liveObjectsCounts;\n    }\n\n    public void performInit(ProfilerClient client, MemoryCCTProvider provider)\n                     throws ClientUtils.TargetAppOrVMTerminated {\n        HeapHistogram histo = client.getHeapHistogram();\n        Set<HeapHistogram.ClassInfo> info = histo.getHeapHistogram();\n        \n        nProfiledClasses = info.size();\n        classNames = new String[nProfiledClasses];\n        objectsSizePerClass = new long[nProfiledClasses];\n        liveObjectsCounts = new int[nProfiledClasses];\n        int i = 0;\n        for (HeapHistogram.ClassInfo ci : info) {\n            classNames[i] = ci.getName();\n            objectsSizePerClass[i] = ci.getBytes();\n            liveObjectsCounts[i] = (int)ci.getInstancesCount();\n            i++;\n        }\n    }\n    \n    public SampledMemoryResultsSnapshot createDiff(MemoryResultsSnapshot snapshot) {\n        if (!(snapshot instanceof SampledMemoryResultsSnapshot)) return null;\n        return new SampledMemoryResultsDiff(this, (SampledMemoryResultsSnapshot)snapshot);\n    }\n\n    public void readFromStream(DataInputStream in) throws IOException {\n        super.readFromStream(in);\n\n        int len = in.readInt();\n        liveObjectsCounts = new int[len];\n\n        for (int i = 0; i < len; i++) {\n            liveObjectsCounts[i] = in.readInt();\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            debugValues();\n        }\n    }\n\n    public String toString() {\n        return MessageFormat.format(MEMORY_SAMPLED_MSG, new Object[] { super.toString() });\n    }\n\n    //---- Serialization support\n    public void writeToStream(DataOutputStream out) throws IOException {\n        super.writeToStream(out);\n\n        out.writeInt(liveObjectsCounts.length);\n\n        for (int i = 0; i < liveObjectsCounts.length; i++) {\n            out.writeInt(liveObjectsCounts[i]);\n        }\n    }\n\n    protected PresoObjAllocCCTNode createPresentationCCT(RuntimeMemoryCCTNode rootNode, int classId,\n                                                         boolean dontShowZeroLiveObjAllocPaths) {\n        return PresoObjAllocCCTNode.createPresentationCCTFromSnapshot(getJMethodIdTable(), rootNode, getClassName(classId));\n    }\n\n    void debugValues() {\n        super.debugValues();\n        LOGGER.finest(\"objectsCounts.length: \" + debugLength(liveObjectsCounts)); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/memory/SurvGenSet.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.memory;\n\n\n/**\n * This class is used to calculate the cardinality of the set of all object ages for the given class,\n * which is actually the definition of the number of surviving generations.\n *\n * @author Misha Dmitriev\n */\npublic class SurvGenSet {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int[] age;\n    private int limit;\n    private int nEls;\n    private int nSlots;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SurvGenSet() {\n        nSlots = 11;\n        age = new int[nSlots];\n\n        for (int i = 0; i < nSlots; i++) {\n            age[i] = -1;\n        }\n\n        nEls = 0;\n        limit = (nSlots * 3) / 4;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /* Get the total number of different ages */\n    public int getTotalNoOfAges() {\n        return nEls;\n    }\n\n    /**\n     * Add the given age to the existing set of ages\n     */\n    public void addAge(int objAge) {\n        int pos = objAge % nSlots;\n\n        while ((age[pos] != objAge) && (age[pos] != -1)) {\n            pos = (pos + 1) % nSlots;\n        }\n\n        if (age[pos] == -1) {\n            age[pos] = objAge;\n            nEls++;\n\n            if (nEls >= limit) {\n                rehash();\n            }\n        }\n    }\n\n    public void mergeWith(SurvGenSet other) {\n        int[] otherAge = other.age;\n        int otherLen = otherAge.length;\n\n        for (int i = 0; i < otherLen; i++) {\n            if (otherAge[i] != -1) {\n                addAge(otherAge[i]);\n            }\n        }\n    }\n\n    private void rehash() {\n        int[] oldAge = age;\n        int oldNSlots = nSlots;\n        nSlots = (oldNSlots * 2) + 1;\n        age = new int[nSlots];\n\n        for (int i = 0; i < nSlots; i++) {\n            age[i] = -1;\n        }\n\n        nEls = 0;\n        limit = (nSlots * 3) / 4;\n\n        for (int i = 0; i < oldNSlots; i++) {\n            if (oldAge[i] != -1) {\n                addAge(oldAge[i]);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/monitor/VMTelemetryDataManager.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.monitor;\n\nimport org.graalvm.visualvm.lib.jfluid.client.MonitoredData;\nimport org.graalvm.visualvm.lib.jfluid.results.DataManager;\n\n\n/**\n * A class that holds telemetry data about the target VM for a single profiling\n * session. It consumes/processes data obtained from the server via the\n * MonitoredData class. A listener is provided for those who want to be notified\n * about newly arrived data.\n *\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic class VMTelemetryDataManager extends DataManager {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    public long[] freeMemory;\n    public long[] lastGCPauseInMS;\n    public long[] loadedClassesCount;\n    public long[] processCPUTimeInPromile;\n    public long[] nSurvivingGenerations;\n    public long[] nSystemThreads;\n    public long[] nTotalThreads;\n    public long[] nUserThreads;\n    public long[] relativeGCTimeInPerMil;\n    public long[] timeStamps;\n    public long[] totalMemory;\n    public long[] usedMemory;\n\n    public long[][] gcFinishs;\n    public long[][] gcStarts;\n\n    public long maxHeapSize = Long.MAX_VALUE; // value of Xmx, constant within one profiling session\n\n    // --- Data storage ----------------------------------------------------------\n    private MonitoredData lastData = null; // last data processed\n\n    private boolean firstStart;\n    private int lastUnpairedStart;\n\n    // --- Arrays extending policy -----------------------------------------------\n    private int arrayBufferSize;\n    private int currentArraysSize;\n    private int itemCount;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    // --- Constructors ----------------------------------------------------------\n\n    /**\n     * Creates a new instance of VMTelemetryDataManager\n     */\n    public VMTelemetryDataManager() {\n        this(50);\n    }\n\n    /**\n     * Creates a new instance of VMTelemetryDataManager\n     */\n    public VMTelemetryDataManager(int arrayBufferSize) {\n        this.arrayBufferSize = arrayBufferSize;\n        reset();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public synchronized void setArrayBufferSize(int arrayBufferSize) {\n        this.arrayBufferSize = arrayBufferSize;\n    }\n\n    public synchronized int getArrayBufferSize() {\n        return arrayBufferSize;\n    }\n\n    // --- Getters / setters -----------------------------------------------------\n    public synchronized int getItemCount() {\n        return itemCount;\n    }\n\n    public synchronized MonitoredData getLastData() {\n        return lastData;\n    }\n\n    // --- Public runtime API ----------------------------------------------------\n    public synchronized void processData(MonitoredData data) {\n        long cpuTimeInPromile;\n        long processCPUTime = data.getProcessCpuTime();\n        \n        if (processCPUTime != -1) {\n            if (lastData != null) {\n                long cpuDiffInMicroSec = (processCPUTime - lastData.getProcessCpuTime())/1000L;\n                long timeDiffMicroSec = (data.getTimestamp() - lastData.getTimestamp())*1000L;\n                if (timeDiffMicroSec < 1000) timeDiffMicroSec = 1000;\n                cpuTimeInPromile = (1000*cpuDiffInMicroSec)/timeDiffMicroSec;\n            } else {\n               cpuTimeInPromile = 0; \n            }\n        } else {\n            cpuTimeInPromile = -1;\n        }\n        addValuesInternal(data.getTimestamp(), data.getFreeMemory(), data.getTotalMemory(), data.getNUserThreads(),\n                          data.getNSystemThreads(), data.getNSurvivingGenerations(), data.getRelativeGCTimeInPerMil(),\n                          data.getLastGCPauseInMS(), data.getLoadedClassesCount(), cpuTimeInPromile, data.getGCStarts(), data.getGCFinishs());\n        lastData = data;\n    }\n\n    public synchronized void reset() {\n        lastData = null;\n\n        itemCount = 0;\n\n        timeStamps = new long[arrayBufferSize];\n\n        freeMemory = new long[arrayBufferSize];\n\n        totalMemory = new long[arrayBufferSize];\n\n        usedMemory = new long[arrayBufferSize];\n\n        nUserThreads = new long[arrayBufferSize];\n\n        nSystemThreads = new long[arrayBufferSize];\n\n        nTotalThreads = new long[arrayBufferSize];\n\n        nSurvivingGenerations = new long[arrayBufferSize];\n\n        relativeGCTimeInPerMil = new long[arrayBufferSize];\n\n        lastGCPauseInMS = new long[arrayBufferSize];\n\n        loadedClassesCount = new long[arrayBufferSize];\n\n        processCPUTimeInPromile = new long[arrayBufferSize];\n        \n        currentArraysSize = arrayBufferSize;\n        \n        gcStarts = new long[arrayBufferSize][];\n        gcFinishs = new long[arrayBufferSize][];\n\n        firstStart = true;\n        lastUnpairedStart = -1;\n\n        fireDataReset();\n    }\n\n    // --- Data storage management -----------------------------------------------\n    private void addValuesInternal(long timeStamp, long freeMemory, long totalMemory, long nUserThreads, long nSystemThreads,\n                                   long nSurvivingGenerations, long relativeGCTimeInPerMil, long lastGCPauseInMS,\n                                   long loadedClassesCount, long cpuTimeInPromile, long[] gcStarts, \n                                   long[] gcFinishs) {\n        checkArraysSize();\n\n        this.timeStamps[itemCount] = timeStamp;\n        this.freeMemory[itemCount] = freeMemory;\n        this.totalMemory[itemCount] = totalMemory;\n        this.usedMemory[itemCount] = totalMemory - freeMemory;\n        this.nUserThreads[itemCount] = nUserThreads;\n        this.nSystemThreads[itemCount] = nSystemThreads;\n        this.nTotalThreads[itemCount] = nSystemThreads + nUserThreads;\n        this.nSurvivingGenerations[itemCount] = nSurvivingGenerations;\n\n        // TODO: should be one tenth (relativeGCTimeInPerMil / 10)\n        this.relativeGCTimeInPerMil[itemCount] = relativeGCTimeInPerMil;\n        this.lastGCPauseInMS[itemCount] = lastGCPauseInMS;\n        this.loadedClassesCount[itemCount] = loadedClassesCount;\n        this.processCPUTimeInPromile[itemCount] = cpuTimeInPromile;\n\n        if (gcStarts.length > 0 || gcFinishs.length > 0) {\n\n//            // Ensure the first event is gc start (filter-out leading gc end)\n//            if (firstStart && gcStarts.length > 0) {\n//                if (gcFinishs.length > 0 && gcStarts[0] > gcFinishs[0]) {\n//                    long[] gcFinishs2 = new long[gcFinishs.length - 1];\n//                    if (gcFinishs2.length > 0) System.arraycopy(gcFinishs, 1,\n//                                                                gcFinishs2, 0,\n//                                                                gcFinishs2.length);\n//                    gcFinishs = gcFinishs2;\n//                }\n//                firstStart = false;\n//            }\n\n            // Ensure the first event is gc start (fake leading gc start)\n            int starts = gcStarts.length;\n            if (firstStart && (starts > 0 || gcFinishs.length > 0)) {\n                if (starts == 0 || gcStarts[0] > gcFinishs[0]) {\n                    long[] gcStarts2 = new long[starts + 1];\n                    if (starts > 0) System.arraycopy(gcStarts, 0, gcStarts2, 1, starts);\n                    gcStarts2[0] = timeStamps[0];\n                    gcStarts = gcStarts2;\n                }\n                firstStart = false;\n            }\n\n            // Check if this item is paired\n            boolean sameStartsFinishsCount = gcStarts.length == gcFinishs.length;\n            boolean thisItemsPaired = (sameStartsFinishsCount && lastUnpairedStart == -1) ||\n                                      (!sameStartsFinishsCount && lastUnpairedStart != -1);\n\n            // Prepare extra buffer for unpaired items\n            int extraItemsBuffer = thisItemsPaired ? 0 : 1;\n\n            // Compute length of new data\n            int newItemsLength = Math.max(gcStarts.length, gcFinishs.length) +\n                                 extraItemsBuffer;\n\n            // Add new gc starts\n            if (gcStarts.length == newItemsLength) {\n                this.gcStarts[itemCount] = gcStarts;\n            } else {\n                this.gcStarts[itemCount] = new long[newItemsLength];\n                System.arraycopy(gcStarts, 0,\n                                 this.gcStarts[itemCount], extraItemsBuffer,\n                                 gcStarts.length);\n            }\n\n            // Add new gc finishs\n            if (gcFinishs.length == newItemsLength) {\n                this.gcFinishs[itemCount] = gcFinishs;\n            } else {\n                this.gcFinishs[itemCount] = new long[newItemsLength];\n                System.arraycopy(gcFinishs, 0,\n                                 this.gcFinishs[itemCount], 0,\n                                 gcFinishs.length);\n            }\n\n            // Mark the unpaired finish\n            if (!thisItemsPaired) {\n                this.gcFinishs[itemCount][newItemsLength - 1] = -1;\n            }\n\n            // Fix the unpaired start\n            if (lastUnpairedStart != -1) {\n                long[] unpairedStarts = this.gcStarts[lastUnpairedStart];\n                long[] unpairedFinishs = this.gcFinishs[lastUnpairedStart];\n                unpairedFinishs[unpairedFinishs.length - 1] = this.gcFinishs[itemCount][0];\n                this.gcStarts[itemCount][0] = unpairedStarts[unpairedStarts.length - 1];\n            }\n\n            // Update last unpaired start\n            if (!thisItemsPaired) {\n                lastUnpairedStart = itemCount;\n            } else {\n                lastUnpairedStart = -1;\n            }\n\n        } else {\n            this.gcStarts[itemCount] = gcStarts;\n            this.gcFinishs[itemCount] = gcFinishs;\n        }\n\n        itemCount++;\n\n        fireDataChanged();\n    }\n\n    private void checkArraysSize() {\n        // array extension is needed\n        if (currentArraysSize == itemCount) {\n            timeStamps = extendArray(timeStamps, arrayBufferSize);\n            freeMemory = extendArray(freeMemory, arrayBufferSize);\n            totalMemory = extendArray(totalMemory, arrayBufferSize);\n            usedMemory = extendArray(usedMemory, arrayBufferSize);\n            nUserThreads = extendArray(nUserThreads, arrayBufferSize);\n            nSystemThreads = extendArray(nSystemThreads, arrayBufferSize);\n            nTotalThreads = extendArray(nTotalThreads, arrayBufferSize);\n            nSurvivingGenerations = extendArray(nSurvivingGenerations, arrayBufferSize);\n            relativeGCTimeInPerMil = extendArray(relativeGCTimeInPerMil, arrayBufferSize);\n            lastGCPauseInMS = extendArray(lastGCPauseInMS, arrayBufferSize);\n            loadedClassesCount = extendArray(loadedClassesCount, arrayBufferSize);\n            processCPUTimeInPromile = extendArray(processCPUTimeInPromile, arrayBufferSize);\n\n            gcStarts = extendArray(gcStarts, arrayBufferSize);\n            gcFinishs = extendArray(gcFinishs, arrayBufferSize);\n\n            // update current array size\n            currentArraysSize += arrayBufferSize;\n        }\n    }\n\n    // extends 1-dimensional long array\n    private static long[] extendArray(long[] array, int extraLength) {\n        int originalLength = array.length;\n        long[] newArray = new long[originalLength + extraLength];\n        System.arraycopy(array, 0, newArray, 0, originalLength);\n\n        return newArray;\n    }\n\n    // extends 2-dimensional long array\n    private static long[][] extendArray(long[][] array, int extraLength) {\n        int originalLength = array.length;\n        long[][] newArray = new long[originalLength + extraLength][];\n        System.arraycopy(array, 0, newArray, 0, originalLength);\n\n        return newArray;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/threads/ThreadData.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.threads;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport java.awt.*;\n\n\n/**\n * A representation of the thread timeline data for a single thread\n *\n * @author Misha Dmitriev\n */\npublic class ThreadData {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static final byte NO_STATE = 127;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final Object dataLock = new Object();\n    private final String name;\n    private final String className;\n    private long[] times = new long[6];\n    private byte[] threadStates; // Array of states corresponding to above timestamps\n                                 // @GuardedBy dataLock\n\n    // @GuardedBy dataLock\n    private long[] timeStamps; // Array of points in time at which thread's state changes\n                               // @GuardedBy dataLock\n\n    // @GuardedBy dataLock\n    private int capacity;\n    private int curSize;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ThreadData(String name, String className) {\n        synchronized (dataLock) {\n            capacity = 50;\n            timeStamps = new long[capacity];\n            threadStates = new byte[capacity];\n            curSize = 0;\n        }\n\n        this.name = name;\n        this.className = className;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getClassName() {\n        return className;\n    }\n\n    public byte getFirstState() {\n        synchronized (dataLock) {\n            if (curSize == 0) {\n                return NO_STATE;\n            } else {\n                return threadStates[0];\n            }\n        }\n    }\n\n    public long getFirstTimeStamp() {\n        synchronized (dataLock) {\n            if (curSize == 0) {\n                return 0;\n            } else {\n                return timeStamps[0];\n            }\n        }\n    }\n\n    public byte getLastState() {\n        synchronized (dataLock) {\n            if (curSize == 0) {\n                return NO_STATE;\n            } else {\n                return threadStates[curSize - 1];\n            }\n        }\n    }\n\n    public long getLastTimeStamp() {\n        synchronized (dataLock) {\n            if (curSize == 0) {\n                return 0;\n            } else {\n                return timeStamps[curSize - 1];\n            }\n        }\n    }\n\n    public String getName() {\n        synchronized (dataLock) {\n            return name;\n        }\n    }\n    \n    public long getRunningTime(long lastTimestamp) {\n        synchronized (dataLock) {\n            long time = times[CommonConstants.THREAD_STATUS_RUNNING];\n            if (getLastState() == CommonConstants.THREAD_STATUS_RUNNING)\n                time += (lastTimestamp - getLastTimeStamp());\n            return time;\n        }\n    }\n    \n    public long getSleepingTime(long lastTimestamp) {\n        synchronized (dataLock) {\n            long time = times[CommonConstants.THREAD_STATUS_SLEEPING];\n            if (getLastState() == CommonConstants.THREAD_STATUS_SLEEPING)\n                time += (lastTimestamp - getLastTimeStamp());\n            return time;\n        }\n    }\n    \n    public long getWaitTime(long lastTimestamp) {\n        synchronized (dataLock) {\n            long time = times[CommonConstants.THREAD_STATUS_WAIT];\n            if (getLastState() == CommonConstants.THREAD_STATUS_WAIT)\n                time += (lastTimestamp - getLastTimeStamp());\n            return time;\n        }\n    }\n    \n    public long getParkTime(long lastTimestamp) {\n        synchronized (dataLock) {\n            long time = times[CommonConstants.THREAD_STATUS_PARK];\n            if (getLastState() == CommonConstants.THREAD_STATUS_PARK)\n                time += (lastTimestamp - getLastTimeStamp());\n            return time;\n        }\n    }\n    \n    public long getMonitorTime(long lastTimestamp) {\n        synchronized (dataLock) {\n            long time = times[CommonConstants.THREAD_STATUS_MONITOR];\n            if (getLastState() == CommonConstants.THREAD_STATUS_MONITOR)\n                time += (lastTimestamp - getLastTimeStamp());\n            return time;\n        }\n    }\n    \n    public long getTotalTime(long lastTimestamp) {\n        return isAliveState(getLastState()) ? lastTimestamp - getFirstTimeStamp() :\n                                              getLastTimeStamp() - getFirstTimeStamp();\n    }\n\n    public byte getStateAt(int idx) {\n        synchronized (dataLock) {\n            return threadStates[idx];\n        }\n    }\n\n    public static Color getThreadStateColor(int threadState) {\n        switch (threadState) {\n            case CommonConstants.THREAD_STATUS_UNKNOWN:\n                return CommonConstants.THREAD_STATUS_UNKNOWN_COLOR;\n            case CommonConstants.THREAD_STATUS_ZOMBIE:\n                return CommonConstants.THREAD_STATUS_ZOMBIE_COLOR;\n            case CommonConstants.THREAD_STATUS_RUNNING:\n                return CommonConstants.THREAD_STATUS_RUNNING_COLOR;\n            case CommonConstants.THREAD_STATUS_SLEEPING:\n                return CommonConstants.THREAD_STATUS_SLEEPING_COLOR;\n            case CommonConstants.THREAD_STATUS_MONITOR:\n                return CommonConstants.THREAD_STATUS_MONITOR_COLOR;\n            case CommonConstants.THREAD_STATUS_WAIT:\n                return CommonConstants.THREAD_STATUS_WAIT_COLOR;\n            case CommonConstants.THREAD_STATUS_PARK:\n                return CommonConstants.THREAD_STATUS_PARK_COLOR;\n            default:\n                return CommonConstants.THREAD_STATUS_UNKNOWN_COLOR;\n        }\n    }\n    \n    public static boolean isAliveState(int threadState) {\n        if (threadState == CommonConstants.THREAD_STATUS_RUNNING) return true;\n        if (threadState == CommonConstants.THREAD_STATUS_SLEEPING) return true;\n        if (threadState == CommonConstants.THREAD_STATUS_MONITOR) return true;\n        if (threadState == CommonConstants.THREAD_STATUS_WAIT) return true;\n        if (threadState == CommonConstants.THREAD_STATUS_PARK) return true;\n        return false;\n    }\n\n    public Color getThreadStateColorAt(int idx) {\n        synchronized (dataLock) {\n            return getThreadStateColor(threadStates[idx]);\n        }\n    }\n\n    public long getTimeStampAt(int idx) {\n        synchronized (dataLock) {\n            return timeStamps[idx];\n        }\n    }\n\n    public void add(long timeStamp, byte threadState) {\n        synchronized (dataLock) {\n            if (curSize == capacity) {\n                long[] oldStamps = timeStamps;\n                byte[] oldStates = threadStates;\n                int oldCapacity = capacity;\n                capacity = capacity * 2;\n                timeStamps = new long[capacity];\n                threadStates = new byte[capacity];\n                System.arraycopy(oldStamps, 0, timeStamps, 0, oldCapacity);\n                System.arraycopy(oldStates, 0, threadStates, 0, oldCapacity);\n            }\n\n            timeStamps[curSize] = timeStamp;\n            threadStates[curSize] = threadState;\n            \n            if (curSize > 0) {\n                long duration = timeStamp - timeStamps[curSize - 1];\n                times[threadStates[curSize - 1]] += duration;\n                times[0] += duration;\n            }\n            \n            curSize++;\n        }\n    }\n\n    public void clearStates() {\n        synchronized (dataLock) {\n            capacity = 50;\n            timeStamps = new long[capacity];\n            threadStates = new byte[capacity];\n            curSize = 0;\n            times = new long[6];\n        }\n    }\n\n    public int size() {\n        synchronized (dataLock) {\n            return curSize;\n        }\n    }\n    \n    public String toString() {\n        return getName();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/threads/ThreadDump.java",
    "content": "/*\n * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.threads;\n\nimport java.lang.management.ThreadInfo;\nimport java.util.Date;\nimport javax.management.openmbean.CompositeData;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class ThreadDump {\n\n    private final boolean jdk15;\n    private final Date time;\n    private Object[] cdThreads;\n    private ThreadInfo[] tinfos;\n    private final Object tinfoLock = new Object();\n\n    public ThreadDump(boolean j15, Date t, Object[] th) {\n        jdk15 = j15;\n        time = t;\n        cdThreads = th;\n    }\n\n    public boolean isJDK15() {\n        return jdk15;\n    }\n\n    public Date getTime() {\n        return time;\n    }\n\n    public ThreadInfo[] getThreads() {\n        synchronized (tinfoLock) {\n            if (tinfos == null) {\n                int i = 0;\n                tinfos = new ThreadInfo[cdThreads.length];\n                for (Object cd : cdThreads) {\n                    tinfos[i++] = ThreadInfo.from((CompositeData) cd);\n                }\n                cdThreads = null;\n            }\n            return tinfos;\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"Thread dump taken at:\" + getTime() + \" threads: \" + getThreads().length;  // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/threads/ThreadsDataManager.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.results.threads;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.client.MonitoredData;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.DataManager;\n\n\n/**\n * A class that holds data about threads history (state changes) during a\n * profiling session. It consumes/processes data obtained from the server via the\n * MonitoredData class, but translates them into data structures more efficient for\n * presentation. A listener is provided for those who want to be notified about\n * newly arrived data.\n *\n * @author Jiri Sedlacek\n * @author Ian Formanek\n * @author Misha Dmitriev\n */\npublic class ThreadsDataManager extends DataManager {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Map<Integer,Integer> idToIndex = new HashMap(30);\n    private ThreadData[] threadData; // Per-thread array of points at which thread's state changes\n    private boolean supportsSleepingState = true;\n    private boolean threadsMonitoringEnabled = true;\n    private long endTime; // Timestamp of threadData end\n    private long startTime; // Timestamp of threadData start\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of ThreadsDataManager\n     */\n    public ThreadsDataManager() {\n        reset();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns the timestamp representing end time of collecting threadData (timestamp of last valid threadData record).\n     */\n    public synchronized long getEndTime() {\n        return endTime;\n    }\n\n    // --- Public interface ---------------------------------------------------------------\n\n    /**\n     * Returns the timestamp representing start time of collecting threadData (timestamp of first threadData record).\n     */\n    public synchronized long getStartTime() {\n        return startTime;\n    }\n\n    public synchronized void setSupportsSleepingStateMonitoring(boolean supportsSleepingState) {\n        this.supportsSleepingState = supportsSleepingState;\n    }\n\n    public synchronized String getThreadClassName(int index) {\n        return threadData[index].getClassName();\n    }\n\n    public synchronized ThreadData getThreadData(int index) {\n        return threadData[index];\n    }\n\n    public synchronized String getThreadName(int index) {\n        return threadData[index].getName();\n    }\n\n    /**\n     * Returns the number of currently monitored threads\n     */\n    public synchronized int getThreadsCount() {\n        return threadData.length;\n    }\n\n    public synchronized void setThreadsMonitoringEnabled(boolean enabled) {\n        if (threadsMonitoringEnabled == enabled) {\n            return;\n        }\n\n        threadsMonitoringEnabled = enabled;\n\n        if (!threadsMonitoringEnabled) { // clear accumulated data, except thread ids and names\n            for (ThreadData threadData1 : threadData) {\n                threadData1.clearStates();\n            }\n        }\n    }\n\n    /**\n     * Returns <CODE>true</CODE> if there are some monitored threads\n     */\n    public synchronized boolean hasData() {\n        return getThreadsCount() != 0;\n    }\n\n    /**\n     * Convert the data received from the server on this iteration into the internal compressed format,\n     * and notify listeners\n     */\n    public synchronized void processData(MonitoredData monitoredData) {\n        //debugData ();\n        int max = threadData.length;\n        int newThreadsNum = monitoredData.getNNewThreads();\n\n        // 1. process newly created threads\n        if (newThreadsNum > 0) {\n            addNewThreads(monitoredData.getNewThreadNames(), monitoredData.getNewThreadClassNames());\n\n            int[] newIds = monitoredData.getNewThreadIds();\n\n            for (int i = 0; i < newThreadsNum; i++) {\n                idToIndex.put(Integer.valueOf(newIds[i]), Integer.valueOf(i + max)); // add new threads to the end of the array\n            }\n        }\n\n        // 2. process all threads data\n        if (threadsMonitoringEnabled) {\n            if (monitoredData.getThreadsDataMode() == CommonConstants.MODE_THREADS_EXACT) {\n                int[] exThreadIds = monitoredData.getExplicitThreadIds();\n                long[] exTimestamps = monitoredData.getExplicitStateTimestamps();\n                byte[] exStates = monitoredData.getExplicitThreadStates();\n                \n                if (exTimestamps.length == 0) {\n                    return;\n                }\n                if (startTime == 0) {\n                    startTime = exTimestamps[0];\n                }\n                // precise states timers\n                for (int i = 0; i < exThreadIds.length; i++) {\n                    Integer intIndex = idToIndex.get(Integer.valueOf(exThreadIds[i]));\n                    int index = intIndex.intValue();\n                    ThreadData tData = threadData[index];\n                    tData.add(exTimestamps[i], exStates[i]);\n                }\n                \n                endTime = exTimestamps[exTimestamps.length - 1];\n                fireDataChanged(); // all listeners are notified about threadData change */\n            } else if (monitoredData.getThreadsDataMode() == CommonConstants.MODE_THREADS_SAMPLING) {\n                int[] threadIds = monitoredData.getThreadIds();\n                long[] timestamps = monitoredData.getStateTimestamps();\n                byte[][] states = monitoredData.getThreadStates();\n                int nThreads = monitoredData.getNThreads();\n                int nStates = monitoredData.getNThreadStates();\n                \n                if (nStates == 0 || nThreads == 0) {\n                    return;\n                }                \n                // Set the timestamp of first data\n                if (startTime == 0) {\n                    startTime = timestamps[0];\n                }\n                for (int threadIdx = 0; threadIdx < nThreads; threadIdx++) {\n                    Integer intIndex = idToIndex.get(Integer.valueOf(threadIds[threadIdx]));\n                    int index = intIndex.intValue();\n                    byte[] threadStates = states[threadIdx];\n                    ThreadData tData = threadData[index];\n                    \n                    for (int stampIdx = 0; stampIdx < nStates; stampIdx++) {\n                        long timeStamp = timestamps[stampIdx];\n                        byte state = threadStates[stampIdx];\n                        byte lastState = tData.getLastState();\n                        \n                        if ((lastState == ThreadData.NO_STATE) || (lastState != state)) {\n                            tData.add(timeStamp, state);\n                        }\n                    }\n                }\n                \n                endTime = timestamps[nStates - 1]; // end timestamp is updated\n                fireDataChanged(); // all listeners are notified about threadData change */\n            }\n        } else {\n            // in this mode we are only tracking thread ids and names, not thread states\n        }\n    }\n\n    /**\n     * Resets the threadData - clears timestamps and threadData store.\n     */\n    public synchronized void reset() {\n        startTime = 0;\n        endTime = 0;\n        threadData = new ThreadData[0];\n        idToIndex.clear();\n        fireDataReset(); // all listeners are notified about threadData change\n    }\n    \n    /**\n     * Resets the collected data during a running profiling session.\n     */\n    public synchronized void resetStates() {\n        if (threadData != null) {\n            startTime = 0;\n            endTime = 0;\n            for (ThreadData data : threadData) data.clearStates();\n            fireDataReset(); // all listeners are notified about threadData change\n        }\n    }\n\n    public synchronized boolean supportsSleepingStateMonitoring() {\n        return supportsSleepingState;\n    }\n\n    // --- Private implementation ---------------------------------------------------------------\n\n    /**\n     * Enlarges internal array of threads' threadData stores according to newly created threads\n     */\n    private void addNewThreads(String[] newNames, String[] newClassNames) {\n        int newSize = newNames.length + threadData.length;\n        ThreadData[] tmpData = new ThreadData[newSize];\n\n        if (threadData.length > 0) {\n            System.arraycopy(threadData, 0, tmpData, 0, threadData.length);\n        }\n\n        for (int i = threadData.length, idx = 0; i < newSize; i++, idx++) {\n            tmpData[i] = new ThreadData(newNames[idx], newClassNames[idx]);\n        }\n\n        threadData = tmpData;\n    }\n\n    //  private void debugData() {\n    //    System.err.print(\"start time: \" + startTime); // NOI18N\n    //    System.err.print(\", end time: \" + endTime); // NOI18N\n    //    System.err.println(\", delta time: \" + (endTime - startTime)); // NOI18N\n    //\n    //    System.err.println(\"number of threads: \" + threadData.length); // NOI18N\n    //    //new Exception(\"Stack trace\").printStackTrace(System.err);\n    //    for (int i = 0; i < threadData.length; i++) {\n    //      System.err.println(\n    //          \"thread [\" + i + \"] = \" + threadData[i].getName() + \" class \" + threadData[i].getClassName() // NOI18N\n    //      );\n    //    }\n    //  }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nProfilerCalibrator_CannotSaveCalibrationDataMsg=Performed calibration successfully, but could not save calibration data\\:\\n{0}\nProfilerCalibrator_CalibrationSuccessMsg=Calibration performed successfully\nProfilerCalibrator_CalibrationResultsPrefix=For your reference, obtained results are as follows\\:\nProfilerCalibrator_CalibrationResultsMsg=Approximate time in one methodEntry()/methodExit() call pair\\:\\nWhen getting absolute timestamp only\\: {0} microseconds\\nWhen getting thread CPU timestamp only\\: {1} microseconds\\nWhen getting both timestamps\\: {2} microseconds\\n\\nApproximate time in one methodEntry()/methodExit() call pair\\nin sampled instrumentation mode\\: {3} microseconds\\n\nProfilerCalibrator_StartingCalibrationMsg=Starting calibration...\nProfilerCalibrator_TimerCountsMsg=*** timerCountsInSecond = {0}\nProfilerCalibrator_TimerValueMsg=*** sample value returned by timer = {0}\nProfilerCalibrator_InjectionCalibrationMsg=----------- Injected profiler code calibration -----------\nProfilerCalibrator_TimeGetCurrentTimeInCountsMsg=Time per each getCurrentTimeInCounts() call\nProfilerCalibrator_TimeGetThreadCPUTimeInNanosMsg=Time per each getThreadCPUTimeInNanos() call\nProfilerCalibrator_TimeCountsMcsMsg={0} counts, {1} mcs\nProfilerCalibrator_TimeSuccessPairsMsg=Time per each successful methodEntry()/methodExit() pair of calls ({0}, {1})\nProfilerCalibrator_MinimumTimeMsg=Minimum time\\: {0} counts, or {1} mcs.\nProfilerCalibrator_InnerOuterTimeMsg=Inner/outer time for a successful methodEntry()/methodExit() pair of calls\nProfilerCalibrator_InnerTimeMcsMsg=Inner time\\: {0} mcs.\nProfilerCalibrator_OuterTimeMcsMsg=Outer time: {0} mcs.\nProfilerCalibrator_SampledTimeMsg=Time per each sampled instrumentation methodEntry()/methodExit() pair of calls\nProfilerCalibrator_RegionTimeMsg=Time per each codeRegionEntry()/codeRegionExit() pair of calls\n\nProfilerInterface_InternalErrorMsg=Internal error\\:\\nExpected InstrumentMethodGroupResponse, got response of class {0},\\nvalue = {1}\\nAll instrumentation will be removed\nProfilerInterface_UnexpectedExceptionMsg=Unexpected exception caught when trying to instrument classes.\\nOriginal exception\\:\\n{0}\\nStack trace\\:\\n\\n{1}\nProfilerInterface_InstrumentationSuccessfulMsg=Deferred instrumentation performed successfully\nProfilerInterface_HistogramNotAvailableMsg=Histogram is not available.\n\nProfilerServer_EnterToShutdownMsg=Press ENTER to shut down the target JVM...\nProfilerServer_MainClassNotPublicMsg=Main class {0} is not public.\\nProfiler can not start it\nProfilerServer_IncorrectMainModifiersMsg=Method {0}.main(String args[]) has incorrect modifiers\nProfilerServer_UnexpectedExceptionMsg=Target application threw an unexpected exception\\: {0}\nProfilerServer_ElapsedTimeMsg=Main application thread elapsed time\\: {0} ms.\nProfilerServer_ConnectionMsg=Profiler Agent\\: Established connection with the tool\nProfilerServer_WaitingOnPortMsg=Profiler Agent\\: Waiting for connection on port {0} (Protocol version: {1})\nProfilerServer_WaitingOnPortTimeoutMsg=Profiler Agent\\: Waiting for connection on port {0}, timeout {1} seconds (Protocol version: {2})\nProfilerServer_ConnectionExceptionMsg=Profiler Agent Error\\: Exception when trying to establish connection with client\\:\\n{0}\nProfilerServer_ConnectionExceptionBindMsg=Profiler Agent Error\\: Make sure the previously profiled process has been fully terminated\nProfilerServer_ConnectionTimeoutMsg=Profiler Agent Error\\: Timed out trying to establish connection with client\nProfilerServer_AgentErrorMsg=Profiler Agent Error\\: {0}\nProfilerServer_ConnectionInterruptedMsg=Profiler Agent Error\\: Connection with client interrupted\nProfilerServer_CommandExceptionMsg=Profiler Agent Error\\: Exception when handling command from client\\:\\n{0}\nProfilerServer_ResponseExceptionMsg=Profiler Agent Error\\: Exception when trying to send response or command to client\\:\\n{0}\nProfilerServer_ConnectionClosedMsg=Profiler Agent\\: Connection with agent closed\nProfilerServer_ConnectionClosedExMsg=Profiler Agent\\: Connection with agent closed (ProfilingSessionStatus was null)\nProfilerServer_IncorrectAgentIdMsg=Profiler Agent Warning\\: Wrong agentId specified\\: {0}\nProfilerServer_ThreadExceptionMsg=Profiler Agent Error\\: Exception in executeInSeparateThread()\nProfilerServer_ThreadWaitExceptionMsg=Profiler Agent Error\\: Exception in wait in SeparateCmdExecutionThread\nProfilerServer_LocalSessionMsg=Profiler Agent: Local accelerated session\nProfilerServer_RemoteSessionMsg=Profiler Agent: Standard session\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ClassBytesLoader.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.RandomAccessFile;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.net.URL;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n\n/**\n * Loading bytes for classes that are known to be loaded by system and bootstrap class loaders.\n *\n * @author Tomas Hurka\n * @author  Misha Dmitriev\n */\npublic class ClassBytesLoader {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static Map jarCache = new HashMap();\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    public static URL getClassFileURL(String className) {\n        String resourceName = className.replace('.', '/') + \".class\"; // NOI18N\n        URL classUrl =  ClassLoader.getSystemResource(resourceName);\n        // in case the classname is a synthetic class there is no resource defining its bytecode\n        if (classUrl == null) {\n            //System.err.println(\"***Profer debug: could not get .class file URL for a synthetic class \" + className  // NOI18N\n            //                   + \" in ClassBytesLoader.getClassFileURL\"); // NOI18N\n        }\n        return classUrl;\n    }\n\n    public static byte[] getClassFileBytes(String className) {\n        return getClassFileBytes(getClassFileURL(className));\n    }\n\n    public static byte[] getClassFileBytes(URL classUrl) {\n        if (classUrl == null) return null;\n        String proto = classUrl.getProtocol();\n\n        if (proto == null) { // Should not happen, this is a critical error message\n            System.err.println(\"***Profiler agent critical error: could not get .class file for class \" + classUrl.toExternalForm()\n                               + \" in ClassBytesLoader.getClassFileBytes\"); // NOI18N\n\n            return null;\n        }\n\n        //System.err.println(\"Reading \"+classUrl);\n        try {\n            if (proto.equals(\"jar\")) { // NOI18N\n\n                return readJar(classUrl);\n            } else if (proto.equals(\"file\")) { // NOI18N\n\n                return readFile(classUrl);\n            } else {\n\n                return readUrl(classUrl);\n            }\n        } catch (IOException ex) {\n            System.err.println(\"*** Profiler agent critical error: caught IOException in ClassBytesLoadergetClassFileBytes: \" + ex); // NOI18N\n            ex.printStackTrace();\n            System.err.println(\"*** End Profiler agent critical error message ---------------------------\"); // NOI18N\n\n            return null;\n        } catch (URISyntaxException ex) {\n            System.err.println(\"*** Profiler agent critical error: caught URISyntaxException in ClassBytesLoadergetClassFileBytes: \" + ex); // NOI18N\n            ex.printStackTrace();\n            System.err.println(\"*** End Profiler agent critical error message ---------------------------\"); // NOI18N\n\n            return null;\n        }\n    }\n\n    /** This method just initializes an experimentally determined set of classes that may be called indirectly by\n     *  getClassFileBytes() above (through ClassLoader.getSystemResourceAsStream().\n     */\n    public static void preloadClasses(boolean remote) {\n        getClassFileBytes(\"java.lang.Object\"); // NOI18N\n        new java.io.FilePermission(\"*\", \"read\"); // NOI18N\n\n        new java.util.HashMap().keySet().iterator();\n \n        // compressed remote profiling\n        if (remote) new java.util.zip.Deflater();\n        \n        try {\n            // for JDK 9\n            Class.forName(\"java.io.RandomAccessFile$1\");    // NOI18N\n        } catch (ClassNotFoundException ex) {\n            // just ignore - RandomAccessFile$1 is not available on JDK 7 and earlier\n        }\n    }\n\n    private static byte[] readFile(final URL classUrl)\n                            throws IOException, URISyntaxException {\n        URI uri = new URI(classUrl.toString());\n        File file = new File(uri);\n        RandomAccessFile f = new RandomAccessFile(file, \"r\");   // NOI18N\n        byte[] buf = new byte[(int) f.length()];\n\n        f.readFully(buf);\n        //System.err.println(\"Size \"+buf.length);\n        f.close();\n\n        return buf;\n    }\n\n    private static byte[] readJar(final URL classUrl) throws IOException {\n        String filePart = classUrl.getFile();\n        int sep = filePart.lastIndexOf('!');\n        String file = filePart.substring(0, sep);\n        String entry = filePart.substring(sep + 2);\n        ZipFile jarFile = (ZipFile) jarCache.get(file);\n        InputStream is;\n        ZipEntry zipEntry;\n        byte[] buf;\n        int pos = 0;\n\n        if (jarFile == null) {\n            jarFile = new ZipFile(new File(URI.create(file)));\n            jarCache.put(file, jarFile);\n        }\n\n        zipEntry = jarFile.getEntry(entry);\n        is = jarFile.getInputStream(zipEntry);\n        buf = new byte[(int) zipEntry.getSize()];\n\n        while (pos < buf.length) {\n            pos += is.read(buf, pos, buf.length - pos);\n        }\n\n        is.close();\n\n        //System.err.println(\"Size \"+buf.length);\n        return buf;\n    }\n\n    private static byte[] readUrl(URL classUrl) throws IOException {\n        InputStream is = classUrl.openStream();\n        ByteArrayOutputStream bos = new ByteArrayOutputStream(16384);\n        byte[] buffer = new byte[4096];\n        int len;\n        \n        while ((len = is.read(buffer)) != -1) {\n            bos.write(buffer, 0, len);\n        }\n        is.close();\n        //System.err.println(\"Size \"+bos.size());\n        return bos.toByteArray();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ClassLoaderManager.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Classes;\nimport java.lang.ref.PhantomReference;\nimport java.lang.ref.ReferenceQueue;\nimport java.lang.ref.WeakReference;\nimport java.lang.reflect.Method;\nimport java.util.Vector;\nimport java.util.WeakHashMap;\n\n\n/**\n * Functionality that ultimately allows us to obtain a class given its name and class loader.\n * One reason for this class to exist, is to enable access to non-public methods of class java.lang.ClassLoader,\n * that allow one to obtain a class loaded by the given loader, or make sure that this class hasn't been loaded by\n * the given loader. Also this class provides accounting for parent loader for each registered loader, which is\n * needed at the client side to correctly perform class instrumentation. Finally, we keep track of class (actually\n * class loader) unloading events, which is necessary e.g. during memory profiling, to prevent\n * getMethodNamesForJMethodIds from crashing or returning \"unknown method\" results.\n *\n * Manages:\n *  - class unloading\n *  - knowing what is loader for each class in CPU profiling\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\nclass ClassLoaderManager implements CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // TODO [release]: change value to TRUE to remove the print code below entirely by compiler\n    private static final boolean DEBUG = System.getProperty(\"org.graalvm.visualvm.lib.jfluid.server.ClassLoaderManager\") != null; // NOI18N\n    private static ProfilerServer profilerServer;\n    private static WeakHashMap /*<ClassLoader, ClassLoaderManager>*/ manMap;\n    private static Vector /*<ClassLoaderManager>*/ manVec;\n    private static ReferenceQueue rq;\n    private static boolean notifyToolAboutUnloadedClasses;\n    private static Method findLoadedClassMethod;\n    private static Method findBootstrapClassMethod;\n\n    /*\n       public static void reset() {\n         manMap = null;\n         manVec = null;\n         rq = null;\n       }\n     */\n    private static boolean notifyThreadIsRunning;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private PhantomReference targetLdrPhantomRef; // This is used to keep track of the moment when the loader is about\n                                                  // to be GCed\n    private WeakReference targetLdrWeakRef; // We use WeakReferences to prevent memory leaks due to direct\n                                            // references to unused loaders\n    private int indexIntoManVec; // Index into the vector of ClassLoaderManagers \"manVec\" below.\n    private int parentLoaderId; // Index of the targetLoader's parent loader into \"managers\" below\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    // --- Instance methods ------------------------------------------------------------------------------------------------\n    private ClassLoaderManager(ClassLoader targetLoader, int indexIntoManVec) {\n        this.targetLdrWeakRef = new WeakReference(targetLoader);\n        this.targetLdrPhantomRef = new PhantomReference(targetLoader, rq);\n        this.indexIntoManVec = indexIntoManVec;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /** Debugging support */\n    public String toString() {\n        return (\"CLManager: indexIntoManVec = \" + indexIntoManVec + \", parentLoaderId = \" + parentLoaderId); // NOI18N\n    }\n\n    static int getDefiningLoaderForClass(String className, int initiatingLoaderId) {\n        if (initiatingLoaderId >= manVec.size()) {\n            return -1;\n        }\n\n        ClassLoaderManager man = (ClassLoaderManager) manVec.get(initiatingLoaderId);\n\n        if ((man == null) || (man.targetLdrWeakRef.get() == null)) {\n            return -1;\n        }\n\n        Class clazz = man.getLoadedClassInThisLoaderOnly(className);\n\n        if (clazz != null) {\n            return registerLoader(clazz);\n        } else {\n            return -1;\n        }\n    }\n\n    static Class getLoadedClass(String name, int loaderIdx) {\n        if (loaderIdx == -1) {\n            loaderIdx = 0;\n        }\n\n        Class res = ((ClassLoaderManager) manVec.get(loaderIdx)).getLoadedClass(name);\n\n        if (res != null) {\n            return res;\n        } else {\n            System.err.println(ENGINE_WARNING + \"class \" + name + \" that should be instrumented is not loaded by target VM\"); // NOI18N\n\n            ClassLoader errLoader = (ClassLoader) (((ClassLoaderManager) manVec.get(loaderIdx)).targetLdrWeakRef.get());\n            System.err.print(\"*** Requested classloader: \" + errLoader); // NOI18N\n\n            if (errLoader != null) {\n                System.err.println(\", its class = \" + errLoader.getClass() + \", index = \" // NOI18N\n                                   + loaderIdx + \", hashcode = \" + errLoader.hashCode()); // NOI18N\n            } else {\n                System.err.println(\", its index = \" + loaderIdx); // NOI18N\n            }\n\n            return null;\n        }\n    }\n\n    static void setNotifyToolAboutUnloadedClasses(boolean v) {\n        notifyToolAboutUnloadedClasses = v;\n    }\n\n    /**\n     * Creates a table that maps loader id to its parent class loader.\n     *\n     * @return An array that maps class loader id (idx) to its parent class loader it ([idx])\n     */\n    static int[] getParentLoaderIdTable() {\n        int size = manVec.size();\n        int[] ret = new int[size];\n\n        for (int i = 0; i < size; i++) {\n            ret[i] = ((ClassLoaderManager) manVec.get(i)).parentLoaderId;\n        }\n\n        return ret;\n    }\n\n    /* Not used\n       public static int getParentLoaderId(int thisLoaderId) {\n         if (thisLoaderId == -1 || thisLoaderId == 0) return 0;\n         else return ((ClassLoaderManager) manVec.get(thisLoaderId)).parentLoaderId;\n       }\n     */\n\n    /**\n     * This whole method exists, in addition to simple getParentLoaderId() above, to make possible passing to the tool\n     * information about \"chains of loaders\" that may occasionally be discovered when a class is loaded. I.e. it may\n     * happen that a new loader A is created, then A creates a child loader B, and finally a class is loaded by B. At\n     * this time we happen to register *both* loaders B and A in registerLoader() above, and also parent loader A gets\n     * a loaderId with a *greater* value than that for B.\n     *\n     * So for the tool to adequately reflect the class loader structure of the application, we need to pass info about\n     * more than 2 loaders with a single class. Fortunately, when there are x>2 loaders involved, the first x-1 get\n     * sequentially growing IDs. So what is returned here in the int[3] array, is the ID for the first and the last\n     * loader in such a chain, plus the chain length (which is 0 in the case of a simple child-parent pair).\n     *\n     * @param thisLoaderId Class loader Id whose parent we are looking for\n     * @return a 3 item array [0]=first loader in chain, [1]=last loader in chain, [2]=chain length, can be 0 in\n     *         simple case\n     */\n    static int[] getThisAndParentLoaderData(int thisLoaderId) {\n        if ((thisLoaderId == -1) || (thisLoaderId == 0)) {\n            return new int[] { 0, 0, 0 };\n        } else {\n            int parentLoaderId = ((ClassLoaderManager) manVec.get(thisLoaderId)).parentLoaderId;\n\n            if (parentLoaderId == -1) {\n                parentLoaderId = 0;\n            }\n\n            if (parentLoaderId <= thisLoaderId) {\n                return new int[] { thisLoaderId, parentLoaderId, 0 };\n            } else {\n                int ofs = 0;\n                int curLoaderId = thisLoaderId;\n\n                while (parentLoaderId > curLoaderId) {\n                    ofs++;\n                    curLoaderId = parentLoaderId;\n                    parentLoaderId = ((ClassLoaderManager) manVec.get(curLoaderId)).parentLoaderId;\n                }\n\n                if (parentLoaderId < 0) {\n                    parentLoaderId = 0;\n                }\n\n                return new int[] { thisLoaderId, parentLoaderId, ofs };\n            }\n        }\n    }\n\n    static void addLoader(ClassLoader loader) {\n        if (DEBUG) {\n            System.out.println(\"Add loader for: \" + loader); // NOI18N\n        }\n\n        ClassLoaderManager ldrMan = (ClassLoaderManager) manMap.get(loader);\n\n        if (ldrMan != null) {\n            // a manager for this class loader already exists\n            return;\n        }\n\n        // create new ClassLoaderManager, with the id being next available int\n        int newId = manVec.size();\n        ldrMan = new ClassLoaderManager(loader, newId);\n\n        if (DEBUG) {\n            System.out.println(\"ClassLoaderManager.DEBUG: Add loader for: \" + loader + \", new Id: \" + newId); // NOI18N\n        }\n\n        manMap.put(loader, ldrMan);\n        manVec.add(ldrMan); // will be placed at the correct index: newId\n    }\n\n    static void addSystemClassLoader() {\n        ClassLoader systemCl = ClassLoader.getSystemClassLoader();\n        ClassLoader extensionCl = systemCl.getParent();\n\n        if (extensionCl != null) {\n            addLoader(extensionCl);\n            registerLoader(systemCl);\n        } else {\n            addLoader(systemCl);\n        }\n    }\n\n    /**\n     * This method SHOULD be called frequently enough to allow unloaded classes go away.\n     * On the other hand, since currently it's called from monitoring code, which itself has to execute at regular\n     * enough intervals, it has to return quickly - that's why we are using a separate thread in it, that does the\n     * potentially long-executing work.\n     * In addition to just clearing a PhantomReference, the code could have removed the relevant ClassLoaderManager\n     * from Vector/Hashtable that contain these managers. We can implement that later.\n     */\n    static void checkForUnloadedClasses() {\n        if (rq == null) {\n            return;\n        }\n\n        PhantomReference clRef = null;\n\n        if ((clRef = (PhantomReference) rq.poll()) != null) {\n            if (notifyToolAboutUnloadedClasses) {\n                class NotifyThread extends Thread {\n                    private PhantomReference clRef;\n\n                    NotifyThread(PhantomReference clRef) {\n                        this.clRef = clRef;\n                        ThreadInfo.addProfilerServerThread(this);\n                    }\n\n                    public void run() {\n                        notifyThreadIsRunning = true;\n\n                        do {\n                            // Note that there is a small chance that this call will not really dump all information, if some\n                            // thread isfor some reason preempted while it's in traceObjAlloc() and not let finish it. This may\n                            // result in some jmethodIDs not sent to client in time and thus not resolved in the call below. But\n                            // the probability of such an event seems very low, and we also have exception handlers in native\n                            // code now, to protect us from such mishaps.\n\n                            // [ian]: this seems like a reason for EXCEPTION_ACCESS_VIOLATION when doing getMethodNamesForJMethodIds\n                            ProfilerInterface.dumpExistingResults(false);\n\n//                            synchronized (ProfilerServer.execInSeparateThreadLock) {\n                                ProfilerInterface.serialClientOperationsLock.beginTrans(true);\n\n                                try {\n                                    // This will send the command to the client and will wait for a response from it, which will\n                                    // come only after the client in turn asks the server for method names for all jmethodIDs it\n                                    // currently has\n                                    profilerServer.sendClassLoaderUnloadingCommand();\n                                } finally {\n                                    ProfilerInterface.serialClientOperationsLock.endTrans();\n                                }\n//                            }\n\n                            clRef.clear();\n                        } while ((clRef = (PhantomReference) rq.poll()) != null);\n\n                        // Notify the native code that may cache class file bytes in a separate data structure,\n                        // that some classes have gone\n                        Classes.notifyAboutClassLoaderUnloading();\n                        ThreadInfo.removeProfilerServerThread(this);\n                        notifyThreadIsRunning = false;\n                    }\n                }\n\n                if (!notifyThreadIsRunning) {\n                    new NotifyThread(clRef).start(); // Otherwise will do the same thing next time we get here\n                }\n            } else {\n                do {\n                    clRef.clear();\n                } while ((clRef = (PhantomReference) rq.poll()) != null);\n\n                Classes.notifyAboutClassLoaderUnloading();\n            }\n        }\n    }\n\n    static void initialize(ProfilerServer inProfilerServer) {\n        try {\n            Class classLoaderClass = ClassLoader.class;\n            Class[] stringArg = new Class[] { String.class };\n            findLoadedClassMethod = classLoaderClass.getDeclaredMethod(\"findLoadedClass\", stringArg); // NOI18N\n            findLoadedClassMethod.setAccessible(true); // REQUIRED to suppress\n            findBootstrapClassMethod = classLoaderClass.getDeclaredMethod(\"findBootstrapClass\", stringArg); // NOI18N\n            findBootstrapClassMethod.setAccessible(true); // access checks\n        } catch (Exception ex) {\n            System.err.println(ENGINE_WARNING+\"Cannot use ClassLoader.findLoadedClass() and/or ClassLoader.findBootstrapClass() in ClassLoaderManager\"); // NOI18N\n            if (DEBUG) ex.printStackTrace(System.err);\n            findLoadedClassMethod = null;\n            findBootstrapClassMethod = null;          \n        }\n\n        // This is done to just initialize some reflection classes, which may otherwise be initialized only when\n        // this class is used for the first time, and thus may cause endless class load recursion\n        ClassLoaderManager clm = new ClassLoaderManager(ClassLoader.getSystemClassLoader(), 0);\n        clm.getLoadedClass(\"java.lang.String\"); // NOI18N\n\n        profilerServer = inProfilerServer;\n\n        manMap = new WeakHashMap();\n        manVec = new Vector();\n        rq = new ReferenceQueue();\n    }\n\n    static int registerLoader(Class clazz) {\n        ClassLoader loader = clazz.getClassLoader();\n\n        if (loader == null) {\n            return -1;\n        }\n\n        int ret = registerLoader(loader);\n\n        if (DEBUG) {\n            System.out.println(\"ClassLoaderManager.DEBUG: Register loader for: \" + clazz.getName() + \", ldr: \" + loader\n                               + \", id: \" + ret); // NOI18N\n        }\n\n        return ret;\n    }\n\n    private static synchronized int registerLoader(ClassLoader loader) {\n        ClassLoaderManager ldrMan = (ClassLoaderManager) manMap.get(loader);\n\n        if (ldrMan != null) {\n            if (ldrMan.targetLdrWeakRef.get() == loader) {\n                return ldrMan.indexIntoManVec;\n            } else {\n                // This probably was a really bad (impossible?) clash - check if this loader is actually\n                // registered somewhere\n                int size = manVec.size();\n\n                for (int i = 0; i < size; i++) {\n                    ldrMan = (ClassLoaderManager) manVec.get(i);\n\n                    if (ldrMan.targetLdrWeakRef.get() == loader) {\n                        return ldrMan.indexIntoManVec;\n                    }\n                }\n            }\n        }\n\n        int ldrIdx = manVec.size();\n        ldrMan = new ClassLoaderManager(loader, ldrIdx);\n        manMap.put(loader, ldrMan);\n        manVec.add(ldrMan);\n\n        ClassLoader parentLoader = loader.getParent();\n        ldrMan.parentLoaderId = (parentLoader != null) ? registerLoader(parentLoader) : (-1);\n\n        return ldrIdx;\n    }\n\n    /** Get a class with the given name, if it is loaded by the given class loader or one of its parent loaders */\n    private Class getLoadedClass(String className) {\n        try {\n            Object[] args = new Object[] { className };\n            ClassLoader loader = (ClassLoader) targetLdrWeakRef.get();\n\n            while (loader != null) {\n                Class res = getLoadedClassInThisLoaderOnly(className);\n\n                // Class res = targetLoader.findLoadedClass(className);\n                if (res != null) {\n                    return res;\n                } else {\n                    loader = loader.getParent();\n                }\n            }\n\n            if (findBootstrapClassMethod != null) {\n                try {\n                    return (Class) findBootstrapClassMethod.invoke(ClassLoader.getSystemClassLoader(), args);\n\n                    // targetLoader.findBootstrapClass(className);\n                } catch (Exception ex) { // ClassNotFoundException may be thrown\n                    System.err.println(\"Profiler Agent Error: internal error in ClassLoaderManager 1\"); // NOI18N\n                    ex.printStackTrace(System.err);\n\n                    return null;\n                }\n            } else {\n                // we don't have findBootstrapClassMethod - try inefficient way\n                return ClassLoader.getSystemClassLoader().loadClass(className);\n            }\n        } catch (ClassNotFoundException ex) {\n            System.err.println(ENGINE_WARNING+\"CNFE for \"+className+\" in ClassLoaderManager \"); // NOI18N\n            if (DEBUG) ex.printStackTrace(System.err);\n        } catch (Exception ex) {\n            System.err.println(\"Profiler Agent Error: internal error in ClassLoaderManager 1\"); // NOI18N\n            ex.printStackTrace(System.err);\n        }\n\n        return null;\n    }\n\n    private Class getLoadedClassInThisLoaderOnly(String className) {\n        Class clazz = null;\n        ClassLoader loader = (ClassLoader) targetLdrWeakRef.get();\n        \n        if (loader == null) {\n            return null;\n        }\n        if (findLoadedClassMethod != null) {\n            try {\n                Object[] args = new Object[] { className };\n                clazz = (Class) findLoadedClassMethod.invoke(loader, args);\n            } catch (Exception ex) {\n                System.err.println(\"Profiler Agent Error: internal error in ClassLoaderManager 2\"); // NOI18N\n                ex.printStackTrace(System.err);\n            }\n        }\n        // if we don't have findLoadedClassMethod - try inefficient way\n        if (findLoadedClassMethod == null || (clazz == null && indexIntoManVec > 0)) {\n            try {\n                clazz = loader.loadClass(className);\n            } catch (ClassNotFoundException ex) {\n                System.err.println(ENGINE_WARNING+\"CNFE in getLoadedClassInThisLoaderOnly \"+ex.getLocalizedMessage()+\" for \"+className+\" classloaderId \"+indexIntoManVec+\" classLoader: \"+loader);\n            }\n            //System.out.println(\"Loaded class \"+className+\" initial loader \"+indexIntoManVec);\n        }\n\n        return clazz;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/EventBufferManager.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport java.nio.MappedByteBuffer;\nimport java.nio.channels.FileChannel;\n\n\n/**\n * Target VM-side management of the shared-memory event buffer file, through which rough profiling data\n * is transmitted to the client.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class EventBufferManager implements CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final boolean DEBUG = System.getProperty(\"org.graalvm.visualvm.lib.jfluid.server.EventBufferManager\") != null; // NOI18N\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private File bufFile;\n    private FileChannel bufFileChannel;\n    private MappedByteBuffer mapByteBuf;\n    private ProfilerServer profilerServer;\n    private RandomAccessFile raFile;\n    private String bufFileName = \"\";\n    private boolean bufFileOk;\n    private boolean bufFileSent;\n    private boolean remoteProfiling;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public EventBufferManager(ProfilerServer server) {\n        profilerServer = server;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getBufferFileName() {\n        if (remoteProfiling) {\n            return \"\"; // NOI18N\n        } else {\n            return bufFileName;\n        }\n    }\n\n    public void eventBufferDumpHook(byte[] eventBuffer, int startPos, int curPtrPos) {\n        int length = curPtrPos - startPos;\n\n        if (!remoteProfiling) {\n            if (!bufFileOk) {\n                return;\n            }\n\n            if (DEBUG) {\n                System.err.println(\"EventBufferManager.DEBUG: Dumping to file: startPos:\" + startPos + \", length:\" + length); // NOI18N\n            }\n\n            mapByteBuf.reset();\n            mapByteBuf.put(eventBuffer, startPos, length);\n            bufFileOk = profilerServer.sendEventBufferDumpedCommand(length, bufFileSent ? \"\": getBufferFileName());\n            bufFileSent = true;\n        } else {\n            if (DEBUG) {\n                System.err.println(\"EventBufferManager.DEBUG: Dumping to compressed wire: startPos:\" + startPos + \", length:\" + length); // NOI18N\n            }\n            profilerServer.sendEventBufferDumpedCommand(length, eventBuffer, startPos);\n        }\n    }\n\n    public void freeBufferFile() {\n        if (remoteProfiling) {\n            return;\n        }\n\n        try {\n            if (bufFileChannel != null) {\n                mapByteBuf = null;\n                bufFileChannel.close();\n                raFile.close();\n                System.gc(); // GCing mapBuf is the only way to free the buffer file.\n                bufFileOk = false;\n            }\n        } catch (IOException ex) {\n            System.err.println(\"Profiler Agent Error: internal error when closing temporary memory-mapped communication file\"); // NOI18N\n        }\n    }\n\n    public void openBufferFile(int sizeInBytes) throws IOException {\n        remoteProfiling = ProfilerServer.getProfilingSessionStatus().remoteProfiling;\n        if (remoteProfiling) {\n            return;\n        }\n\n        if (bufFileOk) {\n            return;\n        }\n\n        try {\n            bufFileSent = false;\n            bufFile = File.createTempFile(\"jfluidbuf\", null); // NOI18N\n            bufFileName = bufFile.getCanonicalPath();\n\n            // Bugfix: http://profiler.netbeans.org/issues/show_bug.cgi?id=59166\n            // Summary: Temporary communication file should be accessible for all users\n            // Bugfix details: As it does not seem to be possible to set the file permissions using Java code\n            //                 we explicitely invoke chmod on the newly created buffer file if we are on UNIX\n            if (Platform.isUnix()) {\n                try {\n                    Runtime.getRuntime().exec(new String[] { \"chmod\", \"666\", bufFileName }); // NOI18N\n                } catch (Exception e) {\n                    System.err.println(\"*** JFluid Warning: Failed to set access permissions on temporary buffer file, you may not be able to attach as a different user: \" + e.getMessage()); // NOI18N\n                }\n            }\n\n            raFile = new RandomAccessFile(bufFile, \"rw\"); // NOI18N\n            bufFileChannel = raFile.getChannel();\n            mapByteBuf = bufFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, sizeInBytes);\n            mapByteBuf.rewind();\n            mapByteBuf.mark();\n            bufFileOk = true;\n        } catch (FileNotFoundException ex1) {\n            System.err.println(\"Profiler Agent Error: FileNotFoundException in EventBufferManager.openBufferFile - should not happen!\"); // NOI18N\n\n            return;\n        } catch (IOException ex2) {\n            System.err.println(\"Profiler Agent Error: Could not create temporary buffer file in the default temporary directory: \"\n                               + ex2.getMessage() + \": \" + System.getProperty(\"java.io.tmpdir\")); // NOI18N\n            throw new IOException(\"Could not create temporary buffer file in the default temporary directory: \"\n                                  + ex2.getMessage() + \": \" + System.getProperty(\"java.io.tmpdir\")); // NOI18N\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/HeapHistogramManager.java",
    "content": "/*\n * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport java.io.BufferedReader;\nimport java.io.FilterInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.Reader;\nimport java.io.UnsupportedEncodingException;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.HeapHistogramResponse;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HeapHistogramManager {\n\n    private static final String BOOLEAN_TEXT = \"boolean\"; // NOI18N\n    private static final String CHAR_TEXT = \"char\"; // NOI18N\n    private static final String BYTE_TEXT = \"byte\"; // NOI18N\n    private static final String SHORT_TEXT = \"short\"; // NOI18N\n    private static final String INT_TEXT = \"int\"; // NOI18N\n    private static final String LONG_TEXT = \"long\"; // NOI18N\n    private static final String FLOAT_TEXT = \"float\"; // NOI18N\n    private static final String DOUBLE_TEXT = \"double\"; // NOI18N\n    private static final String VOID_TEXT = \"void\"; // NOI18N\n    private static final Map permGenNames = new HashMap();\n\n    static {\n        permGenNames.put(\"<methodKlass>\", \"Read-Write Method Metadata\");       // NOI18N\n        permGenNames.put(\"<constMethodKlass>\", \"Read-Only Method Metadata\");   // NOI18N\n        permGenNames.put(\"<methodDataKlass>\", \"Method Profiling Information\"); // NOI18N\n        permGenNames.put(\"<constantPoolKlass>\", \"Constant Pool Metadata\");     // NOI18N\n        permGenNames.put(\"<constantPoolCacheKlass>\", \"Class Resolution Optimization Metadata\");  // NOI18N\n        permGenNames.put(\"<symbolKlass>\", \"VM Symbol Metadata\");               // NOI18N\n        permGenNames.put(\"<compiledICHolderKlass>\", \"Inline Cache Metadata\");  // NOI18N\n        permGenNames.put(\"<instanceKlassKlass>\", \"Instance Class Metadata\");   // NOI18N\n        permGenNames.put(\"<objArrayKlassKlass>\", \"Object Array Class Metadata\");  // NOI18N\n        permGenNames.put(\"<typeArrayKlassKlass>\", \"Scalar Array Class Metadata\"); // NOI18N\n        permGenNames.put(\"<klassKlass>\", \"Base Class Metadata\");                  // NOI18N\n        permGenNames.put(\"<arrayKlassKlass>\", \"Base Array Class Metadata\");       // NOI18N\n    }\n    Map classesIdMap = new HashMap(8000);\n    boolean isJrockitVM;\n\n    HeapHistogramManager() {\n        String vmName = System.getProperty(\"java.vm.name\"); // NOI18N\n\n        if (vmName != null) {\n            if (\"BEA JRockit(R)\".equals(vmName)) {  // NOI18N\n                isJrockitVM = true;\n            } else if (\"Oracle JRockit(R)\".equals(vmName)) {  // NOI18N\n                isJrockitVM = true;\n            }\n        }\n    }\n\n    HeapHistogramResponse computeHistogram(InputStream in) {\n        HeapHistogramResponse histogram;\n\n        if (in == null) {\n            return null;\n        }\n        try {\n            if (isJrockitVM) {\n                histogram = computeHistogramJRockit(in);\n            } else {    // HotSpot\n                histogram = computeHistogramImpl(in);\n            }\n            in.close();\n        } catch (IOException ex) {\n            ex.printStackTrace();\n            return null;\n        }\n        return histogram;\n    }\n\n    private HeapHistogramResponse computeHistogramJRockit(InputStream in) throws IOException {\n        long totalHeapBytes = 0;\n        long totalHeapInstances = 0;\n        long totalInstances = 0;\n        long totalBytes = 0;\n        Map classesMap = new HashMap(1024);\n        Date time = new Date();\n        Scanner sc = new Scanner(in);\n        sc.nextLine();\n        sc.skip('-');\n        sc.nextLine();\n\n        while (sc.hasDigit()) {\n            JRockitClassInfoImpl newClInfo = new JRockitClassInfoImpl(sc);\n\n            if (ProfilerInterface.serverInternalClassName(newClInfo.getName())) {\n                continue;\n            }\n            storeClassInfo(newClInfo, classesMap);\n            totalHeapBytes += newClInfo.getBytes();\n            totalHeapInstances += newClInfo.getInstancesCount();\n        }\n        totalInstances = totalHeapInstances;\n        totalBytes = totalHeapBytes;\n        return getResponse(classesMap, time);\n    }\n\n    private HeapHistogramResponse computeHistogramImpl(InputStream in) throws IOException {\n        long totalBytes = 0;\n        long totalInstances = 0;\n        long totalHeapBytes = 0;\n        long totalHeapInstances = 0;\n        long totalPermGenBytes = 0;\n        long totalPermgenInstances = 0;\n        Map permGenMap = new HashMap(1024);\n        Map classesMap = new HashMap(1024);\n        Date time = new Date();\n        Scanner sc = new Scanner(in);\n\n        while(!sc.hasNext(\"------------------\")) {      // NOI18N\n            sc.nextLine();\n        }\n        sc.skip('-');       // NOI18N\n        sc.nextLine();\n\n        while (sc.hasDigit()) {\n            ClassInfoImpl newClInfo = new ClassInfoImpl(sc);\n\n            if (ProfilerInterface.serverInternalClassName(newClInfo.getName())) {\n                continue;\n            }\n            if (newClInfo.isPermGen()) {\n                storeClassInfo(newClInfo, permGenMap);\n                totalPermGenBytes += newClInfo.getBytes();\n                totalPermgenInstances += newClInfo.getInstancesCount();\n            } else {\n                storeClassInfo(newClInfo, classesMap);\n                totalHeapBytes += newClInfo.getBytes();\n                totalHeapInstances += newClInfo.getInstancesCount();\n            }\n        }\n        if (\"Total\".equals(sc.next())) {   // NOI18N\n            totalInstances = sc.nextLong();\n            totalBytes = sc.nextLong();\n        }\n        return getResponse(classesMap, time);\n    }\n\n    static void storeClassInfo(final ClassInfoImpl newClInfo, final Map map) {\n        ClassInfoImpl oldClInfo = (ClassInfoImpl) map.get(newClInfo.getName());\n        if (oldClInfo == null) {\n            map.put(newClInfo.getName(), newClInfo);\n        } else {\n            oldClInfo.bytes += newClInfo.getBytes();\n            oldClInfo.instances += newClInfo.getInstancesCount();\n        }\n    }\n\n    private HeapHistogramResponse getResponse(Map classesMap, Date time) {\n        Map newClassNames;\n        int[] ids;\n        long[] instances;\n        long[] bytes;\n        int[] newids;\n        String[] newNames;\n        newClassNames = new HashMap(100);\n        ids = new int[classesMap.size()];\n        instances = new long[classesMap.size()];\n        bytes = new long[classesMap.size()];\n        int outIndex = 0;\n        Iterator it = classesMap.values().iterator();\n        while (it.hasNext()) {\n            ClassInfoImpl ci = (ClassInfoImpl) it.next();\n            String name = ci.getName();\n            Integer cindex = (Integer) classesIdMap.get(name);\n            if (cindex == null) {\n                cindex = new Integer(classesIdMap.size());\n                classesIdMap.put(name, cindex);\n                newClassNames.put(name, cindex);\n            }\n            ids[outIndex] = cindex.intValue();\n            instances[outIndex] = ci.instances;\n            bytes[outIndex] = ci.bytes;\n            outIndex++;\n        }\n        newids = new int[newClassNames.size()];\n        newNames = new String[newClassNames.size()];\n        outIndex = 0;\n        it = newClassNames.entrySet().iterator();\n        while (it.hasNext()) {\n            Map.Entry newClassEntry = (Map.Entry) it.next();\n            newids[outIndex] = ((Integer) newClassEntry.getValue()).intValue();\n            newNames[outIndex] = (String) newClassEntry.getKey();\n            outIndex++;\n        }\n        return new HeapHistogramResponse(time, newNames, newids, ids, instances, bytes);\n    }\n\n    static class ClassInfoImpl {\n\n        long instances;\n        long bytes;\n        String name;\n        boolean permGen;\n\n        ClassInfoImpl() {\n        }\n\n        ClassInfoImpl(Scanner sc) throws IOException {\n            String jvmName;\n\n            sc.skipWord();\n            instances = sc.nextLong();\n            bytes = sc.nextLong();\n            jvmName = sc.next();\n            sc.nextLine();  // skip module name on JDK 9\n            permGen = jvmName.charAt(0) == '<';     // NOI18N\n            name = convertJVMName(jvmName);\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public long getInstancesCount() {\n            return instances;\n        }\n\n        public long getBytes() {\n            return bytes;\n        }\n\n        public int hashCode() {\n            return getName().hashCode();\n        }\n\n        public boolean equals(Object obj) {\n            if (obj instanceof ClassInfoImpl) {\n                return getName().equals(((ClassInfoImpl) obj).getName());\n            }\n            return false;\n        }\n\n        private boolean isPermGen() {\n            return permGen;\n        }\n\n        String convertJVMName(String jvmName) {\n            String name = null;\n            int index = jvmName.lastIndexOf('[');\n\n            if (index != -1) {\n                switch (jvmName.charAt(index + 1)) {\n                    case ProfilerInterface.BOOLEAN:\n                        name = BOOLEAN_TEXT;\n                        break;\n                    case ProfilerInterface.CHAR:\n                        name = CHAR_TEXT;\n                        break;\n                    case ProfilerInterface.BYTE:\n                        name = BYTE_TEXT;\n                        break;\n                    case ProfilerInterface.SHORT:\n                        name = SHORT_TEXT;\n                        break;\n                    case ProfilerInterface.INT:\n                        name = INT_TEXT;\n                        break;\n                    case ProfilerInterface.LONG:\n                        name = LONG_TEXT;\n                        break;\n                    case ProfilerInterface.FLOAT:\n                        name = FLOAT_TEXT;\n                        break;\n                    case ProfilerInterface.DOUBLE:\n                        name = DOUBLE_TEXT;\n                        break;\n                    case ProfilerInterface.REFERENCE:\n                        name = jvmName.substring(index + 2, jvmName.length() - 1);\n                        break;\n                    default:\n                        System.err.println(\"Uknown name \" + jvmName);   // NOI18N\n                        name = jvmName;\n                }\n                for (int i = 0; i <= index; i++) {\n                    name = name.concat(\"[]\");           // NOI18N\n                }\n            } else if (isPermGen()) {\n                name = (String) permGenNames.get(jvmName);\n            }\n            if (name == null) {\n                name = jvmName;\n            }\n            return name;\n        }\n    }\n\n    static class JRockitClassInfoImpl extends ClassInfoImpl {\n\n        JRockitClassInfoImpl(Scanner sc) throws IOException {\n            String jvmName;\n\n            sc.skipWord();// skip unused 99.9%\n            bytes = computeBytes(sc);\n            instances = sc.nextLong();\n            sc.skipWord(); // diff unused\n            jvmName = sc.next();\n            name = convertJVMName(jvmName.replace('/', '.'));\n        }\n\n        private long computeBytes(Scanner sc) throws IOException {\n            long bytes = sc.nextLong();\n            char multi = Character.toUpperCase(sc.nextChar());\n            if ('K' == multi) {  // NOI18N\n                bytes *= 1024;\n            } else if ('M'== multi) {   // NOI18N\n                bytes *= 1024 * 1024;\n            } else if ('G' == multi) {   // NOI18N\n                bytes *= 1024 * 1024 * 1024L;\n            }\n            return bytes;\n        }\n    }\n\n    private static class Scanner {\n\n        Reader reader;\n        StringBuffer token;\n\n        Scanner(InputStream is) throws UnsupportedEncodingException {\n            reader = new BufferedReader(new InputStreamReader(new FullInputStream(is), \"UTF-8\"));   // NOI18N\n            token = new StringBuffer(128);\n        }\n\n        void nextLine() throws IOException {\n            int ch;\n            int ch2;\n            \n            do {\n                ch = reader.read();\n            } while (!isNewLine(ch));\n            reader.mark(1);\n            ch2 = reader.read();\n            if (isNewLine(ch2)) {\n                if (ch2 != ch) {\n                    return;\n                }\n            }\n            reader.reset();\n            return;\n        }\n\n        void skip(char s) throws IOException {\n            int ch;\n\n            do {\n                reader.mark(1);\n                ch = reader.read();\n            } while (ch == s);\n            reader.reset();\n            return;\n        }\n\n        long nextLong() throws IOException {\n            int ch;\n            long number = 0;\n\n            skipWhitespace();\n            while (true) {\n                reader.mark(1);\n                ch = reader.read();\n                if (!Character.isDigit(ch)) {\n                    reader.reset();\n                    return number;\n                }\n                number *= 10;\n                number += ch - '0';     // NOI18N\n            }\n        }\n\n        String next() throws IOException {\n            int ch;\n\n            skipWhitespace();\n            token.setLength(0);\n            while (true) {\n                reader.mark(1);\n                ch = reader.read();\n                if (Character.isWhitespace(ch)) {\n                    reader.reset();\n                    return token.toString();\n                }\n                token.append((char) ch);\n            }\n        }\n\n        char nextChar() throws IOException {\n            return (char) reader.read();\n        }\n\n        void skipWhitespace() throws IOException {\n            int ch;\n            \n            do {\n                reader.mark(1);\n                ch = reader.read();\n            } while (Character.isWhitespace(ch));\n            reader.reset();\n        }\n\n        boolean hasDigit() throws IOException {\n            boolean digit;\n            int ch;\n            \n            skipWhitespace();\n            reader.mark(1);\n            ch = reader.read();\n            digit = Character.isDigit(ch);\n            reader.reset();\n            return digit;\n        }\n\n        void skipWord() throws IOException {\n            int ch;\n            \n            skipWhitespace();\n            do {\n                reader.mark(1);\n                ch = reader.read();\n            } while (!Character.isWhitespace(ch));\n            reader.reset();\n        }\n\n        void close() throws IOException {\n            reader.close();\n        }\n\n        private boolean isNewLine(int ch) {\n            if (ch == '\\r') {    // NOI18N\n                return true;\n            }\n            if (ch == '\\n') {    // NOI18N\n                return true;\n            }\n            return false;\n        }\n\n        private boolean hasNext(String string) throws IOException {\n            reader.mark(string.length());\n            for (int i = 0; i < string.length(); i++) {\n                int ch = reader.read();\n                if (ch != string.charAt(i)) {\n                    reader.reset();\n                    return false;\n                }\n            }\n            reader.reset();\n            return true;\n        }\n    }\n\n    private static class FullInputStream extends FilterInputStream {\n\n        byte[] data;\n\n        FullInputStream(InputStream is) {\n            super(is);\n            data = new byte[256];\n        }\n\n        public int read(byte[] b, int off, int len) throws IOException {\n            int n = 0;\n\n            while (n < len) {\n                int count;\n                int remaining = len - n;\n                \n                if (remaining > data.length) {\n                    remaining = data.length;\n                }\n                count = super.read(data, 0, remaining);\n                if (count < 0) {\n                    if (n == 0) {   // nothing was read -> EOF\n                        return -1;\n                    }\n                    return n;\n                }\n                System.arraycopy(data, 0, b, off + n, count);\n                n += count;\n            }\n            return n;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/InstrumentConstructorTest.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass InstrumentConstructorTest {\n\n    private static final boolean DEBUG = Boolean.getBoolean(\"org.graalvm.visualvm.lib.jfluid.server.InstrumentConstructorTest\");\n\n    static boolean test() {\n        // JDK 6 works fine in all cases\n        if (Platform.getJDKVersionNumber() <= CommonConstants.JDK_16) {\n            if (DEBUG) {\n                System.err.println(\"ConstructorTest OK, JDK:\"+Platform.getJDKVersionString());\n            }\n            return true;\n        }\n        try {\n            return new TestClassLoader().test();\n        } catch (InstantiationException ex) {\n            ex.printStackTrace();\n        } catch (IllegalAccessException ex) {\n            ex.printStackTrace();\n        }\n        return false;\n    }\n\n    private static class TestClassLoader extends ClassLoader {\n    /*\n        Classfile org/graalvm/visualvm/lib/jfluid/ConstructorTest.class\n          Last modified May 8, 2018; size 609 bytes\n          MD5 checksum 6796b1dd2e3cb95970ea0a811e633bef\n          Compiled from \"ConstructorTest.java\"\n        public class org.graalvm.visualvm.lib.jfluid.ConstructorTest\n          minor version: 0\n          major version: 51\n          flags: (0x0021) ACC_PUBLIC, ACC_SUPER\n          this_class: #2                          // org/graalvm/visualvm/lib/jfluid/ConstructorTest\n          super_class: #3                         // java/lang/Object\n          interfaces: 0, fields: 0, methods: 1, attributes: 1\n        Constant pool:\n           #1 = Methodref          #3.#13         // java/lang/Object.\"<init>\":()V\n           #2 = Class              #14            // org/graalvm/visualvm/lib/jfluid/ConstructorTest\n           #3 = Class              #15            // java/lang/Object\n           #4 = Utf8               <init>\n           #5 = Utf8               ()V\n           #6 = Utf8               Code\n           #7 = Utf8               LineNumberTable\n           #8 = Utf8               LocalVariableTable\n           #9 = Utf8               this\n          #10 = Utf8               Lorg/graalvm/visualvm/lib/jfluid/ConstructorTest;\n          #11 = Utf8               SourceFile\n          #12 = Utf8               ConstructorTest.java\n          #13 = NameAndType        #4:#5          // \"<init>\":()V\n          #14 = Utf8               org/graalvm/visualvm/lib/jfluid/ConstructorTest\n          #15 = Utf8               java/lang/Object\n          #16 = Methodref          #17.#19        // org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUFullInstr.methodEntry:(C)V\n          #17 = Class              #18            // org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUFullInstr\n          #18 = Utf8               org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUFullInstr\n          #19 = NameAndType        #20:#21        // methodEntry:(C)V\n          #20 = Utf8               methodEntry\n          #21 = Utf8               (C)V\n          #22 = Methodref          #17.#23        // org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUFullInstr.methodExit:(C)V\n          #23 = NameAndType        #24:#21        // methodExit:(C)V\n          #24 = Utf8               methodExit\n          #25 = Methodref          #17.#26        // org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUFullInstr.profilePointHit:(C)V\n          #26 = NameAndType        #27:#21        // profilePointHit:(C)V\n          #27 = Utf8               profilePointHit\n          #28 = Methodref          #17.#29        // org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUFullInstr.rootMethodEntry:(C)V\n          #29 = NameAndType        #30:#21        // rootMethodEntry:(C)V\n          #30 = Utf8               rootMethodEntry\n          #31 = Utf8               StackMapTable\n          #32 = Class              #33            // java/lang/Throwable\n          #33 = Utf8               java/lang/Throwable\n        {\n          public org.graalvm.visualvm.lib.jfluid.ConstructorTest();\n            descriptor: ()V\n            flags: (0x0001) ACC_PUBLIC\n            Code:\n              stack=4, locals=2, args_size=1\n                 0: sipush        1\n                 3: invokestatic  #28                 // Method org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUFullInstr.rootMethodEntry:(C)V\n                 6: nop\n                 7: nop\n                 8: aload_0\n                 9: invokespecial #1                  // Method java/lang/Object.\"<init>\":()V\n                12: sipush        1\n                15: invokestatic  #22                 // Method org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUFullInstr.methodExit:(C)V\n                18: nop\n                19: nop\n                20: return\n                21: astore_1\n                22: sipush        1\n                25: invokestatic  #22                 // Method org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUFullInstr.methodExit:(C)V\n                28: aload_1\n                29: athrow\n              Exception table:\n                 from    to  target type\n                     0    21    21   any\n              LineNumberTable:\n                line 4: 0\n              LocalVariableTable:\n                Start  Length  Slot  Name   Signature\n                    8      13     0  this   Lorg/graalvm/visualvm/lib/jfluid/ConstructorTest;\n              StackMapTable: number_of_entries = 1\n                frame_type = 255 // full_frame\n                  offset_delta = 21\n                  locals = [ top ]\n                  stack = [ class java/lang/Throwable ]\n        }\n        SourceFile: \"ConstructorTest.java\"\n\n        */\n        // od -t u1 ConstructorTest.class | awk '{for (i=2; i<=NF; i++) { val=$i; if (val>127) val-=256 ; printf (\"%d, \", val); } printf \"\\n\"}'\n\n        private byte[] classBytes = new byte[]{-54, -2, -70, -66, 0, 0, 0, 51, 0, 34, 10, 0, 3, 0, 13, 7, \n            0, 14, 7, 0, 15, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, \n            3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15, 76, 105, \n            110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 18, \n            76, 111, 99, 97, 108, 86, 97, 114, 105, 97, 98, 108, 101, 84, 97, 98, \n            108, 101, 1, 0, 4, 116, 104, 105, 115, 1, 0, 49, 76, 111, 114, 103, \n            47, 103, 114, 97, 97, 108, 118, 109, 47, 118, 105, 115, 117, 97, 108, 118, \n            109, 47, 108, 105, 98, 47, 106, 102, 108, 117, 105, 100, 47, 67, 111, 110, \n            115, 116, 114, 117, 99, 116, 111, 114, 84, 101, 115, 116, 59, 1, 0, 10, \n            83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 20, 67, 111, 110, \n            115, 116, 114, 117, 99, 116, 111, 114, 84, 101, 115, 116, 46, 106, 97, 118, \n            97, 12, 0, 4, 0, 5, 1, 0, 47, 111, 114, 103, 47, 103, 114, 97, \n            97, 108, 118, 109, 47, 118, 105, 115, 117, 97, 108, 118, 109, 47, 108, 105, \n            98, 47, 106, 102, 108, 117, 105, 100, 47, 67, 111, 110, 115, 116, 114, 117, \n            99, 116, 111, 114, 84, 101, 115, 116, 1, 0, 16, 106, 97, 118, 97, 47, \n            108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 10, 0, 17, 0, 19, \n            7, 0, 18, 1, 0, 66, 111, 114, 103, 47, 103, 114, 97, 97, 108, 118, \n            109, 47, 118, 105, 115, 117, 97, 108, 118, 109, 47, 108, 105, 98, 47, 106, \n            102, 108, 117, 105, 100, 47, 115, 101, 114, 118, 101, 114, 47, 80, 114, 111, \n            102, 105, 108, 101, 114, 82, 117, 110, 116, 105, 109, 101, 67, 80, 85, 70, \n            117, 108, 108, 73, 110, 115, 116, 114, 12, 0, 20, 0, 21, 1, 0, 11, \n            109, 101, 116, 104, 111, 100, 69, 110, 116, 114, 121, 1, 0, 4, 40, 67, \n            41, 86, 10, 0, 17, 0, 23, 12, 0, 24, 0, 21, 1, 0, 10, 109, \n            101, 116, 104, 111, 100, 69, 120, 105, 116, 10, 0, 17, 0, 26, 12, 0, \n            27, 0, 21, 1, 0, 15, 112, 114, 111, 102, 105, 108, 101, 80, 111, 105, \n            110, 116, 72, 105, 116, 10, 0, 17, 0, 29, 12, 0, 30, 0, 21, 1, \n            0, 15, 114, 111, 111, 116, 77, 101, 116, 104, 111, 100, 69, 110, 116, 114, \n            121, 1, 0, 13, 83, 116, 97, 99, 107, 77, 97, 112, 84, 97, 98, 108, \n            101, 7, 0, 33, 1, 0, 19, 106, 97, 118, 97, 47, 108, 97, 110, 103, \n            47, 84, 104, 114, 111, 119, 97, 98, 108, 101, 0, 33, 0, 2, 0, 3, \n            0, 0, 0, 0, 0, 1, 0, 1, 0, 4, 0, 5, 0, 1, 0, 6, \n            0, 0, 0, 99, 0, 4, 0, 2, 0, 0, 0, 30, 17, 0, 1, -72, \n            0, 28, 0, 0, 42, -73, 0, 1, 17, 0, 1, -72, 0, 22, 0, 0, \n            -79, 76, 17, 0, 1, -72, 0, 22, 43, -65, 0, 1, 0, 0, 0, 21, \n            0, 21, 0, 0, 0, 3, 0, 7, 0, 0, 0, 6, 0, 1, 0, 0, \n            0, 4, 0, 8, 0, 0, 0, 12, 0, 1, 0, 8, 0, 13, 0, 9, \n            0, 10, 0, 0, 0, 31, 0, 0, 0, 13, 0, 1, -1, 0, 21, 0, \n            1, 0, 0, 1, 7, 0, 32, 0, 1, 0, 11, 0, 0, 0, 2, 0, \n            12,};\n\n        private boolean test() throws InstantiationException, IllegalAccessException {\n            if (DEBUG) {\n                System.err.println(\"ConstructorTest Class size:\"+classBytes.length);\n            }\n            Class cls = defineClass(\"org.graalvm.visualvm.lib.jfluid.ConstructorTest\", classBytes, 0, classBytes.length);\n            if (DEBUG) {\n                System.err.println(\"ConstructorTest Class load:\"+cls);\n            }\n            try {\n                cls.getConstructors();\n            } catch (VerifyError ve) {\n                if (DEBUG) {\n                    ve.printStackTrace();\n                }\n                return false;\n            }\n            return true;\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/Monitors.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Classes;\nimport org.graalvm.visualvm.lib.jfluid.server.system.GC;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Threads;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Timers;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.MonitoredNumbersResponse;\nimport java.util.Vector;\n\n\n/**\n * Implementation of the monitoring functionality, active throughout the TA execution.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class Monitors implements CommonConstants {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    static class LongList {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        long[] data;\n        int size;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        LongList(int size) {\n            data = new long[size];\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        long[] getArray() {\n            long[] arr = new long[size];\n            System.arraycopy(data, 0, arr, 0, size);\n\n            return arr;\n        }\n\n        void add(long l) {\n            ensureSize();\n            data[size++] = l;\n        }\n\n        void clear() {\n            size = 0;\n        }\n\n        void ensureSize() {\n            if (size >= data.length) {\n                int newCapacity = ((size * 3) / 2) + 1;\n                long[] elementData = new long[newCapacity];\n                System.arraycopy(data, 0, elementData, 0, size);\n                data = elementData;\n            }\n        }\n    }\n\n    static class SurvGenAndThreadsMonitor extends Thread {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        public volatile boolean started;\n        public volatile boolean terminated;\n        private LongList gcFinishs;\n        private LongList gcStarts;\n        private ThreadDataTable threadTable;\n        private Vector markerObjects;\n        private int[] allThreadStatusRough;\n\n        // ---------------------------------- Thread status data management -------------------------------------\n        private Thread[] allThreadsRough;\n\n        // -------------------------------- Surviving generations data management ---------------------------------\n        private int savedGCEpoch;\n        private long lastGCFinish;\n        private long lastGCStart;\n        private long time; // Used just for estimating the overhead\n        private long time0; // Used just for estimating the overhead\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        SurvGenAndThreadsMonitor() {\n            super(\"*** JFluid Monitor thread ***\"); // NOI18N\n            savedGCEpoch = GC.getCurrentGCEpoch();\n            markerObjects = new Vector();\n            allThreadsRough = new Thread[20];\n            allThreadStatusRough = new int[20];\n            threadTable = new ThreadDataTable();\n            gcStarts = new LongList(16);\n            gcFinishs = new LongList(16);\n            setPriority(Thread.MAX_PRIORITY);\n            setDaemon(true);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public int getNSurvGen() {\n            return markerObjects.size();\n        }\n\n        public synchronized void getThreadsData(MonitoredNumbersResponse mresp) {\n            //threadTable.printCurrentStatus();\n            threadTable.getThreadsData(mresp);\n            threadTable.resetStates();\n        }\n\n        public long getTime() {\n            long ret = time;\n            time = 0;\n\n            return ret;\n        }\n\n        public synchronized void addThreadStateChange(Thread thread, byte state, long timeStamp, Object monitor) {\n            if (started && !terminated) threadTable.addExactState (thread, -1, state, timeStamp);\n        }\n\n        public void run() {\n            started = true;\n\n            int checkForUnloadedClassesCounter = 3;\n\n            while (!terminated) {\n                //time0 = ProfilerRuntime.getCurrentTimeInCounts();\n                updateSurvGenData();\n                updateThreadsData();\n                updateGCStartFinishData();\n\n                // The next call has nothing to do with monitoring - it's \"housekeeping\". See details in ClassLoaderManager.\n                if (--checkForUnloadedClassesCounter == 0) {\n                    ClassLoaderManager.checkForUnloadedClasses();\n                    checkForUnloadedClassesCounter = 3;\n                }\n\n                ThreadInfo.releaseDeadThreads();\n\n                //time += (ProfilerRuntime.getCurrentTimeInCounts() - time0);\n                try {\n                    Thread.sleep(100);\n                } catch (Exception ex) {\n                }\n            }\n            ThreadInfo.removeProfilerServerThread(this);\n        }\n\n        synchronized void updateGCStartFinishData() {\n            int i;\n            long maxStart = lastGCStart;\n            long maxFinish = lastGCFinish;\n            GC.getGCStartFinishTimes(gcStartTimes, gcFinishTimes);\n\n            for (i = 0; i < GC.OBSERVED_PERIODS; i++) {\n                long start = gcStartTimes[i];\n                long finish = gcFinishTimes[i];\n\n                if (start > lastGCStart) {\n                    gcStarts.add(start & 0xFFFFFFFFFFFFFFL); // we use only 7 bytes for hi res timer\n                    maxStart = start;\n                }\n\n                if (finish > lastGCFinish) {\n                    gcFinishs.add(finish & 0xFFFFFFFFFFFFFFL); // we use only 7 bytes for hi res timer\n                    maxFinish = finish;\n                }\n            }\n\n            lastGCStart = maxStart;\n            lastGCFinish = maxFinish;\n        }\n\n        private synchronized void getGCStartFinishData(MonitoredNumbersResponse resp) {\n            long[] start = gcStarts.getArray();\n            long[] finish = gcFinishs.getArray();\n\n            gcStarts.clear();\n            gcFinishs.clear();\n\n            resp.setGCstartFinishData(start, finish);\n        }\n\n        private void updateSurvGenData() {\n            // Compare the previously saved GC epoch value with the current one, and allocate new marker if it changed\n            int currentGCEpoch = GC.getCurrentGCEpoch();\n\n            if (currentGCEpoch != savedGCEpoch) {\n                //System.out.println(\"***              GC epoch changed from \" + savedGCEpoch + \" to \" + currentGCEpoch);\n                markerObjects.add(new Object());\n                savedGCEpoch = currentGCEpoch;\n\n                // Walk through the markers, determine which ones are adjacent, etc.\n                int lenMinusOne = markerObjects.size() - 1;\n                int initSize = lenMinusOne + 1;\n\n                for (int i = 0; i < lenMinusOne; i++) {\n                    if (GC.objectsAdjacent(markerObjects.get(i), markerObjects.get(i + 1))) {\n                        //System.out.println(\"********* Objects adjacent at i = \" + i + \": \" + markerObjects.get(i) + \" and \" + markerObjects.get(i+1));\n                        markerObjects.remove(i);\n                        i--;\n                        lenMinusOne--;\n                    }\n                }\n            }\n        }\n\n        private void updateThreadsData() {\n            Thread tMain = ProfilerServer.isTargetAppMainThreadComplete() ? ProfilerServer.getMainThread() : null;\n\n            allThreadsRough = Threads.getAllThreads(allThreadsRough);\n\n            if (allThreadStatusRough.length < allThreadsRough.length) {\n                allThreadStatusRough = new int[allThreadsRough.length];\n            }\n\n            Threads.getThreadsStatus(allThreadsRough, allThreadStatusRough);\n\n            if (DEBUG) {\n                for (int i = 0; i < allThreadsRough.length; i++) {\n                    if (allThreadsRough[i] == null) {\n                        break;\n                    }\n\n                    System.err.println(\"org.graalvm.visualvm.lib.jfluid.server.Monitors.DEBUG: \" // NOI18N\n                                       + allThreadsRough[i].getName() + \", status: \" + allThreadStatusRough[i]); // NOI18N\n                }\n            }\n\n            synchronized (this) {\n                threadTable.prePut();\n\n                for (int i = 0; i < allThreadsRough.length; i++) {\n                    Thread thread = allThreadsRough[i];\n\n                    if (thread == null) {\n                        break; // No more live threads in this array\n                    }\n\n                    // We check if the thread is our own using ThreadInfo.isProfilerServerThread(), not its name\n                    // (which looks easier), because it turns out that Thread.getName() creates a new String out of internal\n                    // char[] array every time. ThreadInfo check should be just faster.\n                    if ((thread == this) || (thread == tMain) || ThreadInfo.isProfilerServerThread(thread)) {\n                        //System.err.println(\"Skipping thread \"+i+\", tMain:\"+tMain +\", thread: \"+thread);\n                        continue;\n                    }\n\n                    threadTable.put(thread, allThreadStatusRough[i]);\n                }\n                threadTable.findDeathThreads();\n                threadTable.incStatusIdx();\n            }\n\n            if (DEBUG) {\n                System.err.println(\"Final thread table: \"); // NOI18N\n                threadTable.printCurrentStatus();\n            }\n        }\n    }\n\n    static class ThreadDataTable {\n        //~ Static fields/initializers -------------------------------------------------------------------------------------------\n\n        private static final int INITIAL_SIZE = 23;\n        private static final int INITIAL_NSTATES = 20;\n        private static Object dummyObj = new Object();\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private String[] newThreadClassNames = new String[INITIAL_SIZE];\n        private int[] newThreadIds = new int[INITIAL_SIZE];\n        private String[] newThreadNames = new String[INITIAL_SIZE];\n        private long[] packedStateTimestamps = new long[INITIAL_NSTATES];\n        private int[] packedThreadIds = new int[INITIAL_SIZE];\n        private byte[] packedThreadStates = new byte[INITIAL_SIZE * INITIAL_NSTATES];\n        private long[] stateSampleTimestamps;\n        private int[] threadIds;\n        private boolean[] threadNew;\n        private byte[][] threadStates;\n        private Object[] threads;\n        private boolean jvmSupportsThreadSleepingState;\n        private int curStateIdx;\n        private int curThreadId;\n        private int nFilledSlots;\n        private int nNewThreads;\n        private int nStates;\n        private int nThreads;\n        private int size;\n        private int threshold;\n        private int explPos;\n        private byte[] explicitStates;\n        private int[] explicitThreads;\n        private long[] explicitTimeStamps;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ThreadDataTable() {\n            size = INITIAL_SIZE;\n            threshold = (size * 3) / 4;\n            curThreadId = 1;\n            nStates = INITIAL_NSTATES;\n            threads = new Object[size];\n            threadIds = new int[size];\n            threadStates = new byte[size][nStates];\n            stateSampleTimestamps = new long[nStates];\n            threadNew = new boolean[size];\n            nThreads = 0;\n            nFilledSlots = 0;\n            curStateIdx = 0;\n            jvmSupportsThreadSleepingState = Platform.thisVMSupportsThreadSleepingStateMonitoring();\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void getThreadsData(MonitoredNumbersResponse mresp) {\n            if (explPos > 0) {\n                // pass the collected explicit thread state changes\n                int[] msgExplicitThreads = new int[explPos];\n                System.arraycopy(explicitThreads, 0, msgExplicitThreads, 0, explPos);\n                byte[] msgExplicitStates = new byte[explPos];\n                System.arraycopy(explicitStates, 0, msgExplicitStates, 0, explPos);\n                long[] msgExplicitTimeStamps = new long[explPos];\n                System.arraycopy(explicitTimeStamps, 0, msgExplicitTimeStamps, 0, explPos);\n                \n                mresp.setExplicitDataOnThreads(msgExplicitThreads, msgExplicitStates, msgExplicitTimeStamps);\n                \n                // and reset the arrays/pos\n                explicitStates = new byte[explPos];\n                explicitThreads = new int[explPos];\n                explicitTimeStamps = new long[explPos];\n                explPos = 0;\n            } else {\n                // explicit Threads states not supported\n                if (nThreads > packedThreadIds.length) {\n                    packedThreadIds = new int[nThreads];\n                }\n                \n                if (curStateIdx > packedStateTimestamps.length) {\n                    packedStateTimestamps = new long[curStateIdx];\n                }\n                \n                int totalStates = nThreads * curStateIdx;\n                \n                if (totalStates > packedThreadStates.length) {\n                    packedThreadStates = new byte[totalStates];\n                }\n                \n                int idx0 = 0;\n                int idx1 = 0;\n                \n                for (int i = 0; i < size; i++) {\n                    if ((threads[i] != null) && (threads[i] != dummyObj)) {\n                        packedThreadIds[idx0++] = threadIds[i];\n                        System.arraycopy(threadStates[i], 0, packedThreadStates, idx1, curStateIdx);\n                        idx1 += curStateIdx;\n                    }\n                }\n                \n                System.arraycopy(stateSampleTimestamps, 0, packedStateTimestamps, 0, curStateIdx);\n                \n                mresp.setDataOnThreads(nThreads, curStateIdx, packedThreadIds, packedStateTimestamps, packedThreadStates);\n            }\n\n            if (nNewThreads > 0) {\n                if (nNewThreads > newThreadIds.length) {\n                    newThreadIds = new int[nNewThreads];\n                    newThreadNames = new String[nNewThreads];\n                    newThreadClassNames = new String[nNewThreads];\n                }\n\n                int idx = 0;\n\n                for (int i = 0; i < size; i++) {\n                    if (threadNew[i]) {\n                        newThreadIds[idx] = threadIds[i];\n                        Thread t = (Thread) threads[i];\n                        newThreadClassNames[idx] = t.getClass().getName();\n                        try {\n                            newThreadNames[idx] = t.getName();\n                        } catch (NullPointerException e) {\n                            newThreadNames[idx] = \"*Unknown thread (\"+threadIds[i]+\")*\";  // NOI18N\n                        }\n                        idx++;\n                    }\n                }\n\n                mresp.setDataOnNewThreads(nNewThreads, newThreadIds, newThreadNames, newThreadClassNames);\n            }\n        }\n\n        public void incStatusIdx() {\n            curStateIdx++;\n\n            if (curStateIdx == nStates) {\n                growStatesArrays();\n            }\n        }\n\n        /**\n         * Sets current status for all threads to dead. Subsequent calls to put will change the status of live threads appropriately.\n         * The rest of the threads for which status will remain dead, are really dead.\n         */\n        public void prePut() {\n            for (int i = 0; i < size; i++) {\n                threadStates[i][curStateIdx] = 0;\n            }\n\n            stateSampleTimestamps[curStateIdx] = System.currentTimeMillis();\n        }\n\n        /** Debugging support */\n        public void printCurrentStatus() {\n            for (int i = 0; i < size; i++) {\n                if ((threads[i] == null) || (threads[i] == dummyObj)) {\n                    continue;\n                }\n\n                System.err.print(((Thread) threads[i]).getName() + \"  \"); // NOI18N\n\n                byte[] states = threadStates[i];\n\n                for (int j = 0; j < curStateIdx; j++) {\n                    System.err.print(states[j]);\n                }\n\n                System.err.println();\n            }\n\n            System.err.println();\n        }\n\n        void put(Thread thread, int status) {\n            int pos = getPosIndex(thread);\n\n            if (threads[pos] == null) {\n                threadNew[pos] = true;\n                threads[pos] = thread;\n                threadIds[pos] = curThreadId++;\n                nThreads++;\n                nNewThreads++;\n                nFilledSlots++;\n            }\n\n            if (explPos > 0) {\n                // we are actually using exact thread states tracking, so make use of zombie state that we otherwise do\n                // not get\n                if (status == CommonConstants.THREAD_STATUS_ZOMBIE || threadNew[pos]) {\n                    addExactState(null, threadIds[pos], (byte)status, stateSampleTimestamps[curStateIdx]);\n                }\n                \n                // just an optimization, if we use exact timings, the sampling data will only contain state running\n                status = CommonConstants.THREAD_STATUS_RUNNING;\n            }\n            \n            threadStates[pos][curStateIdx] = (byte) status;\n\n            if (nFilledSlots > threshold) {\n                growTable();\n            }\n        }\n\n        private int getPosIndex(final Thread thread) {\n            int pos = (thread.hashCode() & 0x7FFFFFFF) % size;\n\n            while ((threads[pos] != thread) && (threads[pos] != null)) {\n                pos = (pos + 1) % size;\n            }\n            return pos;\n        }\n\n        private void findDeathThreads() {\n            if (explPos == 0) return;\n            // we are actually using exact thread states tracking, so make use zombie state that we otherwise do\n            for (int i = 0; i < size; i++) {\n                if ((threads[i] == null) || (threads[i] == dummyObj)) {\n                    continue;\n                }\n\n                if (threadStates[i][curStateIdx] == 0) { // Thread is dead\n                    addExactState(null,threadIds[i],CommonConstants.THREAD_STATUS_ZOMBIE,stateSampleTimestamps[curStateIdx]);\n                }\n            }\n        }\n        \n        public void resetStates() {\n            nNewThreads = 0;\n\n            if (curStateIdx == 0) {\n                return;\n            }\n\n            int idx = curStateIdx - 1;\n\n            for (int i = 0; i < size; i++) {\n                if ((threads[i] == null) || (threads[i] == dummyObj)) {\n                    continue;\n                }\n\n                threadNew[i] = false;\n\n                if (threadStates[i][idx] == 0) { // Thread is dead\n                    threads[i] = dummyObj;\n                    nThreads--;\n                }\n            }\n\n            curStateIdx = 0;\n        }\n\n        private void growStatesArrays() {\n            int oldNStates = nStates;\n            nStates = nStates * 2;\n\n            for (int i = 0; i < size; i++) {\n                byte[] oldStates = threadStates[i];\n                threadStates[i] = new byte[nStates];\n                System.arraycopy(oldStates, 0, threadStates[i], 0, oldNStates);\n            }\n\n            long[] oldTimestamps = stateSampleTimestamps;\n            stateSampleTimestamps = new long[nStates];\n            System.arraycopy(oldTimestamps, 0, stateSampleTimestamps, 0, oldNStates);\n        }\n\n        private void growTable() {\n            int oldSize = size;\n            size = (((nThreads * 4) / 3) * 2) + 1;\n\n            if (size < oldSize) {\n                size = oldSize; // Too many threads are dead; get rid of them without growing the table\n                                // Otherwise, if the application generates lots of short-lived threads, we may probably end up growing the table\n                                // endlessly without reason\n            }\n\n            threshold = (size * 3) / 4;\n\n            Object[] oldThreads = threads;\n            int[] oldThreadIds = threadIds;\n            byte[][] oldThreadStates = threadStates;\n            boolean[] oldThreadNew = threadNew;\n            threads = new Object[size];\n            threadIds = new int[size];\n            threadStates = new byte[size][];\n            threadNew = new boolean[size];\n\n            for (int i = 0; i < oldSize; i++) {\n                if ((oldThreads[i] == null) || (oldThreads[i] == dummyObj)) {\n                    continue;\n                }\n\n                Object thread = oldThreads[i];\n                int pos = (thread.hashCode() & 0x7FFFFFFF) % size;\n\n                while (threads[pos] != null) {\n                    pos = (pos + 1) % size;\n                }\n\n                threadNew[pos] = oldThreadNew[i];\n                threads[pos] = thread;\n                threadIds[pos] = oldThreadIds[i];\n                threadStates[pos] = oldThreadStates[i];\n            }\n\n            for (int i = 0; i < size; i++) {\n                if (threadStates[i] == null) {\n                    threadStates[i] = new byte[nStates];\n                }\n            }\n\n            nFilledSlots = nThreads;\n        }\n\n        void addExactState(Thread thread, int threadId, byte state, long timeStamp) {\n            int id = threadId;\n            if (id == -1) {\n                id = findThreadId(thread);\n            }\n            if (id == -1) {\n                // thread not found, forget about it\n                return;\n            }\n            \n            if (explicitThreads == null) {\n                explicitStates = new byte[20];\n                explicitThreads = new int [20];\n                explicitTimeStamps = new long[20];\n            }\n            \n            if (explicitStates.length == explPos) {\n                byte[] newExplicitStates = new byte[explPos * 2];\n                System.arraycopy(explicitStates, 0, newExplicitStates, 0, explicitStates.length);\n                explicitStates = newExplicitStates;\n                \n                int[] newExplicitThreads = new int[explPos * 2];\n                System.arraycopy(explicitThreads, 0, newExplicitThreads, 0, explicitThreads.length);\n                explicitThreads = newExplicitThreads;\n                \n                long[] newExplicitTimeStamps = new long[explPos * 2];\n                System.arraycopy(explicitTimeStamps, 0, newExplicitTimeStamps, 0, explicitTimeStamps.length);\n                explicitTimeStamps = newExplicitTimeStamps;\n            }\n            \n            explicitStates[explPos] = state;\n            explicitThreads[explPos] = id;\n            explicitTimeStamps[explPos] = timeStamp;\n            explPos++;\n        }\n\n        private int findThreadId(Thread thread) {\n            int pos = getPosIndex(thread);\n            \n            if (threads[pos] == thread) {\n                return threadIds[pos];\n            }\n            return -1; // not found\n        }\n\n    }\n\n    interface DeterminateProgress {\n        public void next();        \n    }\n\n    private static class ActiveServerState implements DeterminateProgress{\n        //~ Instance fields ----------------------------------------------------------------------------------------------------------\n        private final ActiveServerState parent;\n        private final int serverState;\n        private final int stepCount;\n        private final double stepSize;\n        private final boolean indeterminate;\n        private int step;\n\n        private final int id;\n        private static int counter = 0;\n\n        //~ Constructors -------------------------------------------------------------------------------------------------------------\n        ActiveServerState(int serverState) {\n            this(null, serverState, 0);\n        }\n\n        ActiveServerState(ActiveServerState parent, int serverState, int stepCount) {\n            this.parent = parent;\n            this.serverState = serverState;\n            this.stepCount = stepCount;\n            if (stepCount == 0) {\n                this.stepSize = parent == null ? 1.0 : parent.stepSize;\n                this.indeterminate = parent == null ? true : parent.indeterminate;\n            } else {\n                this.stepSize = parent == null ? 1.0/stepCount : parent.stepSize/stepCount;\n                this.indeterminate = false;\n            }\n            this.step = 0;\n            this.id = counter ++;\n            //System.out.println(\"ActiveServerState #\"+String.valueOf(id)+\": init(serverState=\"+String.valueOf(serverState)+\", stepCount=\"+String.valueOf(stepCount)+\", stepSize=\"+String.valueOf(stepSize)+\")\");\n        }\n        \n        //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n        private int getServerState() {\n            return serverState;\n        }\n\n        private int getProgress() {\n            if(indeterminate) {\n               return CommonConstants.SERVER_PROGRESS_INDETERMINATE; \n            }\n            return (int)(getRealProgress()*CommonConstants.SERVER_PROGRESS_WORKUNITS);\n        }\n\n        private synchronized double getRealProgress() {\n            double result;\n            if(indeterminate) {\n                result = 0.0;\n            } else if(parent == null) {\n                assert stepCount == 0: \"called for indeterminate state\";\n                result = 1.0*step/stepCount;\n            } else {\n                result = parent.getRealProgress() + parent.stepSize*step/stepCount;\n            }\n            return result;\n        }\n          \n        public synchronized void next() {\n            assert stepCount > 0: \"called for indeterminate progress state\";\n            step ++;\n            if(step >= stepCount) {\n                step = stepCount - 1;\n            }\n        }        \n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final boolean DEBUG = Boolean.getBoolean(\"org.graalvm.visualvm.lib.jfluid.server.Monitors\");\n    protected static Runtime runtime;\n    protected static long[] generalMNums;\n    protected static long[] gcRelTime;\n    protected static long[] gcStartTimes;\n    protected static long[] gcFinishTimes;\n    private static SurvGenAndThreadsMonitor stMonitor;\n    private static long startTimeMilis;\n    private static long startTimeCounts;\n    private static boolean threadsSamplingEnabled;\n\n    protected static long time; // Used just for estimating the overhead\n\n    private static ActiveServerState activeServerState;\n    private static final Object activeServerStateLock = new Object();\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static MonitoredNumbersResponse getMonitoredNumbers() {\n        //time = ProfilerRuntime.getCurrentTimeInCounts();\n        int nTotalThreads = Threads.getTotalNumberOfThreads();\n        int nUserThreads = nTotalThreads - ThreadInfo.getLiveServerThreads(); // This number includes our Server communication thread, memory monitor thread, and separate command execution thread\n\n        int nSystemThreads = ProfilerInterface.getNPrerecordedSystemThreads();\n\n        if (nSystemThreads != -1) { // \"Start from tool\" mode, so we have recorded system threads\n            nUserThreads -= nSystemThreads;\n\n            if (ProfilerServer.isTargetAppMainThreadComplete()) { // It's not really complete, but executes JFluid code, so logically it's done.\n                nUserThreads--;\n            }\n        } else { // Attach mode, no exact knowledge of the number of system threads\n            nSystemThreads = 0;\n        }\n\n        // Get the relative GC time metrics\n        GC.getGCRelativeTimeMetrics(gcRelTime);\n\n        generalMNums[MonitoredNumbersResponse.FREE_MEMORY_IDX] = runtime.freeMemory();\n        generalMNums[MonitoredNumbersResponse.TOTAL_MEMORY_IDX] = runtime.totalMemory();\n        generalMNums[MonitoredNumbersResponse.USER_THREADS_IDX] = nUserThreads;\n        generalMNums[MonitoredNumbersResponse.SYSTEM_THREADS_IDX] = nSystemThreads;\n        generalMNums[MonitoredNumbersResponse.SURVIVING_GENERATIONS_IDX] = stMonitor.getNSurvGen();\n        generalMNums[MonitoredNumbersResponse.GC_TIME_IDX] = gcRelTime[0];\n        generalMNums[MonitoredNumbersResponse.GC_PAUSE_IDX] = gcRelTime[1];\n        generalMNums[MonitoredNumbersResponse.LOADED_CLASSES_IDX] = Classes.getLoadedClassCount();\n        generalMNums[MonitoredNumbersResponse.CPU_TIME_IDX] = Timers.getProcessCpuTime();\n        generalMNums[MonitoredNumbersResponse.TIMESTAMP_IDX] = System.currentTimeMillis();\n\n        int serverState;\n        int serverProgress;\n        synchronized(activeServerStateLock) {\n            serverState = activeServerState.getServerState();\n            serverProgress = activeServerState.getProgress();\n        }\n        MonitoredNumbersResponse resp = new MonitoredNumbersResponse(generalMNums, serverState, serverProgress);\n        stMonitor.getThreadsData(resp);\n        stMonitor.getGCStartFinishData(resp);\n\n        //showTime();\n        return resp;\n    }\n\n    public static void initialize() {\n        runtime = Runtime.getRuntime();\n        gcRelTime = new long[2];\n        gcStartTimes = new long[GC.OBSERVED_PERIODS];\n        gcFinishTimes = new long[GC.OBSERVED_PERIODS];\n        generalMNums = new long[MonitoredNumbersResponse.GENERAL_NUMBERS_SIZE];\n        GC.activateGCEpochCounter(true);\n        stMonitor = new SurvGenAndThreadsMonitor();\n        ThreadInfo.addProfilerServerThread(stMonitor);\n        startTimeMilis = System.currentTimeMillis();\n        startTimeCounts = Timers.getCurrentTimeInCounts();\n        activeServerState = new ActiveServerState(CommonConstants.SERVER_RUNNING);\n        stMonitor.start();\n    }\n\n    static void setThreadsSamplingEnabled(boolean b) {\n        threadsSamplingEnabled = b;\n    }\n\n    static DeterminateProgress enterServerState(int serverState, int stepCount) {\n        synchronized(activeServerStateLock) {\n            activeServerState = new ActiveServerState(activeServerState, serverState, stepCount);\n            return activeServerState;\n        }\n    }\n\n    static void enterServerState(int serverState) {\n        synchronized(activeServerStateLock) {\n            activeServerState = new ActiveServerState(activeServerState, serverState, 0);\n        }\n    }\n\n    static void exitServerState() {\n        synchronized(activeServerStateLock) {\n            activeServerState = activeServerState.parent;\n        }\n    }\n\n    static void recordThreadStateChange(Thread thread, byte state, long timeStamp, Object monitor) {\n        if (threadsSamplingEnabled) return;\n        if (timeStamp == -1) {\n            timeStamp = Timers.getCurrentTimeInCounts();\n        }\n        // convert to \n        long diff = timeStamp - startTimeCounts;\n        diff /= Timers.getNoOfCountsInSecond() / 1000;\n        timeStamp = startTimeMilis + diff;\n        if (DEBUG) {\n              switch (state) {\n                case CommonConstants.THREAD_STATUS_MONITOR:\n                    System.err.println(\"Thread state change: \"+thread.getName()+\", Monitor: \"+timeStamp+\", monitor: \"+System.identityHashCode(monitor));\n                    break;\n                case CommonConstants.THREAD_STATUS_WAIT:\n                    System.err.println(\"Thread state change: \"+thread.getName()+\", Wait: \"+timeStamp);\n                    break;\n                case CommonConstants.THREAD_STATUS_PARK:\n                    System.err.println(\"Thread state change: \"+thread.getName()+\", Park: \"+timeStamp);\n                    break;\n                case CommonConstants.THREAD_STATUS_SLEEPING:\n                    System.err.println(\"Thread state change: \"+thread.getName()+\", Sleep: \"+timeStamp);\n                    break;\n                case CommonConstants.THREAD_STATUS_RUNNING:\n                    System.err.println(\"Thread state change: \"+thread.getName()+\", Run: \"+timeStamp);\n                    break;\n            }\n        }\n\n        if (stMonitor != null) {\n            stMonitor.addThreadStateChange(thread, state, timeStamp, monitor);\n        }\n    }\n\n    /** Check if all monitor threads have been started */\n    public static boolean monitorThreadsStarted() {\n        return stMonitor.started;\n    }\n\n    public static void shutdown() {\n        stMonitor.terminated = true;\n    }\n\n    /** Measures and prints the overhead of the monitoring code */\n    private static void showTime() {\n        long cnts = Timers.getNoOfCountsInSecond();\n        time = ((Timers.getCurrentTimeInCounts() - time) * 1000000) / cnts;\n\n        long time1 = (stMonitor.getTime() * 1000000) / cnts;\n        System.out.println(\"!!! time = \" + time + \", time1 = \" + time1 + \", sum = \" + (time + time1)); // NOI18N\n        // Originally (with no thread state information) time returned above would be 60..80 + 600..700 microsec\n        // If getMonitoredNumbers() is called roughly once a second, this translates into 750/1000000*100 = 0.075 per cent overhead\n        // With thread state information, overhead grows to about 60..80 + 1000 microsec. Still just 0.1 per cent overhead.\n        // Transport, and, more importantly, client-side processing, likely take much more time.\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilerAPI.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\n\n/**\n * An API that allows the profiled application to control certain profiling functions.\n *\n * @author Ian Formanek\n */\npublic class ProfilerAPI {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void resetCollectedResults() {\n        ProfilerServer.requestClientResetResults();\n    }\n\n    public static void takeSnapshot() {\n        ProfilerServer.requestClientTakeSnapshot();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilerCalibrator.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CalibrationDataFileIO;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Timers;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.InternalStatsResponse;\nimport java.text.MessageFormat;\nimport java.text.NumberFormat;\nimport java.util.ResourceBundle;\n\n\n/**\n * Functionality that allows one to measure in advance the time that standard instrumentation takes.\n * These values can then be subtracted from the rough profiling results, giving measurements that are\n * much more close to reality.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\nclass ProfilerCalibrator extends ProfilerRuntime {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    // !!! Warning - do not use ResourceBundle.getBundle here, won't work in context of direct/dynamic attach !!!\n    // Default EN messages initialized here, will be replaced by localized messages in static initializer\n    private static String CANNOT_SAVE_CALIBRATION_DATA_MSG = \"Performed calibration successfully, but could not save calibration data:\\n{0}\"; // NOI18N\n    private static String CALIBRATION_SUCCESS_MSG = \"Calibration performed successfully\"; // NOI18N\n    private static String CALIBRATION_RESULTS_PREFIX = \"For your reference, obtained results are as follows:\"; // NOI18N\n    private static String CALIBRATION_RESULTS_MSG = \"Approximate time in one methodEntry()/methodExit() call pair:\\nWhen getting absolute timestamp only: {0} microseconds\\nWhen getting thread CPU timestamp only: {1} microseconds\\nWhen getting both timestamps: {2} microseconds\\n\\nApproximate time in one methodEntry()/methodExit() call pair\\nin sampled instrumentation mode: {3} microseconds\\n\"; // NOI18N\n    private static String STARTING_CALIBRATION_MSG = \"Starting calibration...\"; // NOI18N\n    private static String TIMER_COUNTS_MSG = \"*** timerCountsInSecond = {0}\"; // NOI18N\n    private static String TIMER_VALUE_MSG = \"*** sample value returned by timer = {0}\"; // NOI18N\n    private static String INJECTION_CALIBRATION_MSG = \"----------- Injected profiler code calibration -----------\"; // NOI18N\n    private static String TIME_getCurrentTimeInCounts_MSG = \"Time per each getCurrentTimeInCounts() call\"; // NOI18N\n    private static String TIME_getThreadCPUTimeInNanos_MSG = \"Time per each getThreadCPUTimeInNanos() call\"; // NOI18N\n    private static String TIME_COUNTS_MCS_MSG = \"{0} counts, {1} mcs\"; // NOI18N\n    private static String TIME_SUCCESS_PAIRS_MSG = \"Time per each successful methodEntry()/methodExit() pair of calls ({0}, {1})\"; // NOI18N\n    private static String MINIMUM_TIME_MSG = \"Minimum time: {0} counts, or {1} mcs.\"; // NOI18N\n    private static String INNER_OUTER_TIME_MSG = \"Inner/outer time for a successful methodEntry()/methodExit() pair of calls\"; // NOI18N\n    private static String INNER_TIME_MCS_MSG = \"Inner time: {0} mcs.\"; // NOI18N\n    private static String OUTER_TIME_MCS_MSG = \"Outer time: {0} mcs.\"; // NOI18N\n    private static String SAMPLED_TIME_MSG = \"Time per each sampled instrumentation methodEntry()/methodExit() pair of calls\"; // NOI18N\n    private static String REGION_TIME_MSG = \"Time per each codeRegionEntry()/codeRegionExit() pair of calls\"; // NOI18N\n                                                                                                              // -----\n\n    static {\n        ResourceBundle messages = ProfilerServer.getProfilerServerResourceBundle();\n\n        if (messages != null) {\n            CANNOT_SAVE_CALIBRATION_DATA_MSG = messages.getString(\"ProfilerCalibrator_CannotSaveCalibrationDataMsg\"); // NOI18N\n            CALIBRATION_SUCCESS_MSG = messages.getString(\"ProfilerCalibrator_CalibrationSuccessMsg\"); // NOI18N\n            CALIBRATION_RESULTS_PREFIX = messages.getString(\"ProfilerCalibrator_CalibrationResultsPrefix\"); // NOI18N\n            CALIBRATION_RESULTS_MSG = messages.getString(\"ProfilerCalibrator_CalibrationResultsMsg\"); // NOI18N\n            STARTING_CALIBRATION_MSG = messages.getString(\"ProfilerCalibrator_StartingCalibrationMsg\"); // NOI18N\n            TIMER_COUNTS_MSG = messages.getString(\"ProfilerCalibrator_TimerCountsMsg\"); // NOI18N\n            TIMER_VALUE_MSG = messages.getString(\"ProfilerCalibrator_TimerValueMsg\"); // NOI18N\n            INJECTION_CALIBRATION_MSG = messages.getString(\"ProfilerCalibrator_InjectionCalibrationMsg\"); // NOI18N\n            TIME_getCurrentTimeInCounts_MSG = messages.getString(\"ProfilerCalibrator_TimeGetCurrentTimeInCountsMsg\"); // NOI18N\n            TIME_getThreadCPUTimeInNanos_MSG = messages.getString(\"ProfilerCalibrator_TimeGetThreadCPUTimeInNanosMsg\"); // NOI18N\n            TIME_COUNTS_MCS_MSG = messages.getString(\"ProfilerCalibrator_TimeCountsMcsMsg\"); // NOI18N\n            TIME_SUCCESS_PAIRS_MSG = messages.getString(\"ProfilerCalibrator_TimeSuccessPairsMsg\"); // NOI18N\n            MINIMUM_TIME_MSG = messages.getString(\"ProfilerCalibrator_MinimumTimeMsg\"); // NOI18N\n            INNER_OUTER_TIME_MSG = messages.getString(\"ProfilerCalibrator_InnerOuterTimeMsg\"); // NOI18N\n            INNER_TIME_MCS_MSG = messages.getString(\"ProfilerCalibrator_InnerTimeMcsMsg\"); // NOI18N\n            OUTER_TIME_MCS_MSG = messages.getString(\"ProfilerCalibrator_OuterTimeMcsMsg\"); // NOI18N\n            SAMPLED_TIME_MSG = messages.getString(\"ProfilerCalibrator_SampledTimeMsg\"); // NOI18N\n            REGION_TIME_MSG = messages.getString(\"ProfilerCalibrator_RegionTimeMsg\"); // NOI18N\n        }\n    }\n\n    private static ProfilingSessionStatus status;\n    private static boolean printResults;\n    private static byte[] buf;\n    private static double minTimePerMethodEntryExitCallInCounts;\n    private static double minTimePerMethodEntryExitCallInMCS;\n    private static double innerTimeInCounts;\n    private static double outerTimeInCounts;\n    private static long cntInSecond;\n    private static int nCall;\n    private static int cycleWhenMinResultDetected;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    //private static double deviation; private static int nDevSamples;\n    public static void init(ProfilingSessionStatus status) {\n        ProfilerCalibrator.status = status;\n    }\n\n    /**\n     * Main method is called in two cases:\n     * - when the user wants to perform calibration and save results on the machine where the tool is not installed,\n     *   so that later remote profiling can be performed on this machine. No command line args are needed.\n     * - a backdoor usage when JF developers want to see calibration data, tune the internals etc. In that case,\n     *   a special command line argument -develmode should be provided.\n     */\n    public static void main(String[] args) {\n        boolean inDevelMode;\n\n        if ((args.length > 0) && args[0].equals(\"-develmode\")) { // NOI18N  // Development mode, see above\n            inDevelMode = true;\n            System.out.println(\"Loader for this class is \" + ProfilerCalibrator.class.getClassLoader()); // NOI18N\n        } else {\n            inDevelMode = false;\n\n            ProfilingSessionStatus localStatus = new ProfilingSessionStatus();\n            localStatus.targetJDKVersionString = Platform.getJDKVersionString();\n            localStatus.remoteProfiling = true;\n            init(localStatus);\n        }\n\n        if (Platform.getJDKVersionNumber() == Platform.JDK_CVM) {\n            System.loadLibrary(\"profilerinterface\"); // NOI18N\n        }\n        Timers.initialize();\n\n        measureBCIOverhead(inDevelMode);\n\n        if (!inDevelMode) {\n            if (!CalibrationDataFileIO.saveCalibrationData(status)) {\n                System.err.println(MessageFormat.format(CANNOT_SAVE_CALIBRATION_DATA_MSG,\n                                                        new Object[] { CalibrationDataFileIO.getErrorMessage() }));\n                System.exit(-1);\n            }\n\n            System.out.println(CALIBRATION_SUCCESS_MSG);\n            System.out.println(CALIBRATION_RESULTS_PREFIX);\n\n            NumberFormat nf = NumberFormat.getInstance();\n            nf.setMaximumFractionDigits(4);\n\n            long cntsInSec = status.timerCountsInSecond[0];\n            double m0 = (((double) status.methodEntryExitCallTime[0]) * 1000000) / cntsInSec; // Expressed in microseconds\n            double m1 = (((double) status.methodEntryExitCallTime[1]) * 1000000) / cntsInSec; // Ditto\n            double m2 = (((double) status.methodEntryExitCallTime[2]) * 1000000) / cntsInSec; // Ditto\n            double m4 = (((double) status.methodEntryExitCallTime[4]) * 1000000) / cntsInSec; // Ditto\n\n            StringBuilder s = new StringBuilder();\n            s.append(MessageFormat.format(CALIBRATION_RESULTS_MSG,\n                                          new Object[] { nf.format(m0), nf.format(m1), nf.format(m2), nf.format(m4) }));\n\n            System.out.println(s.toString());\n        }\n    }\n\n    /**\n     * In addition to calculating and optionally printing some measurements of the overhead imposed by BCI, this\n     * call, I hope,  makes the impact of BCI on the target application more uniform/predictable, since it causes\n     * the VM to precompile various profiling calls.\n     */\n    public static void measureBCIOverhead(boolean printRes) {\n        printResults = printRes;\n\n        System.out.println(STARTING_CALIBRATION_MSG);\n\n        // Just wait for some time, to e.g. make caller threads finish their work, etc.\n        try {\n            Thread.sleep(1000);\n        } catch (Exception ex) {\n        }\n\n        cntInSecond = Timers.getNoOfCountsInSecond();\n        printResults(MessageFormat.format(TIMER_COUNTS_MSG, new Object[] { \"\" + cntInSecond })); // NOI18N\n        printResults(MessageFormat.format(TIMER_VALUE_MSG, new Object[] { \"\" + Timers.getCurrentTimeInCounts() })); // NOI18N\n\n        if (status != null) {\n            status.timerCountsInSecond = new long[2];\n            status.timerCountsInSecond[0] = cntInSecond;\n            status.timerCountsInSecond[1] = 1000000000;\n        }\n\n        ProfilerRuntime.resetProfilerCollectors(INSTR_RECURSIVE_FULL);\n        ProfilerRuntimeCPU.setNProfiledThreadsLimit(1);\n        ProfilerRuntimeCPU.setInstrMethodsInvoked(new boolean[] { true, true, true, true });\n        ProfilerRuntimeCPU.createThreadInfoForCurrentThread();\n\n        printResults(INJECTION_CALIBRATION_MSG + \"\\n\"); // NOI18N\n\n        if (printResults) { // Measure and print the performance of getCurrentTimeInCounts() - for information only\n            measureTimerCall(true);\n            measureTimerCall(false);\n        }\n\n        //deviation = 0; nDevSamples = 0;\n        nCall = -1;\n        measureMethodEntryExitCalls(); // A warmup run to make the compiler make all necessary inlines etc.\n\n        for (nCall = 0; nCall < 4; nCall++) {\n            measureMethodEntryExitCalls(); // This knows what to count depending on nCall\n\n            if (status != null) {\n                status.methodEntryExitCallTime[nCall] = minTimePerMethodEntryExitCallInCounts;\n                status.methodEntryExitInnerTime[nCall] = innerTimeInCounts;\n                status.methodEntryExitOuterTime[nCall] = outerTimeInCounts;\n            }\n        }\n\n        //deviation /= nDevSamples; System.out.println(\"**! deviation = \" + deviation);\n\n        //if (printResults) {                             // For information purposes only\n        //  measureUnsuccessfulMethodEntryExitCalls();  \n        //  measureSuccessfulMethodEntryExitCallsCalledFromInterpreted();\n        //}\n        nCall = -1;\n        measureSampledMethodEntryExitCalls(); // Again a warmup run\n        nCall = 0;\n        measureSampledMethodEntryExitCalls();\n\n        if (status != null) {\n            status.methodEntryExitCallTime[4] = minTimePerMethodEntryExitCallInCounts;\n            status.methodEntryExitInnerTime[4] = innerTimeInCounts;\n            status.methodEntryExitOuterTime[4] = outerTimeInCounts;\n        }\n\n        measureCodeRegionCalls();\n\n        printResults(\"----------------------------------------------------------\\n\"); // NOI18N\n\n        buf = null;\n        ProfilerRuntimeCPUCodeRegion.setCPUResBufSize(0);\n        ThreadInfo.setDefaultEvBufParams();\n        ProfilerRuntime.resetProfilerCollectors(INSTR_RECURSIVE_FULL);\n        ProfilerRuntime.resetProfilerCollectors(INSTR_RECURSIVE_SAMPLED);\n    }\n\n    static InternalStatsResponse getInternalStats() {\n        InternalStatsResponse r = new InternalStatsResponse();\n        r.nTotalInstrMethods = ProfilerInterface.nTotalInstrMethods;\n        r.nClassLoads = ProfilerInterface.nClassLoads;\n        r.nFirstMethodInvocations = ProfilerInterface.nFirstMethodInvocations;\n        r.nNonEmptyInstrMethodGroupResponses = ProfilerInterface.nNonEmptyInstrMethodGroupResponses;\n        r.nEmptyInstrMethodGroupResponses = ProfilerInterface.nEmptyInstrMethodGroupResponses;\n        r.nSingleMethodInstrMethodGroupResponses = ProfilerInterface.nSingleMethodInstrMethodGroupResponses;\n\n        long cntsInSec = Timers.getNoOfCountsInSecond();\n        r.clientInstrTime = (((double) ProfilerInterface.clientInstrTime) * 1000) / cntsInSec;\n        r.clientDataProcTime = (((double) ProfilerInterface.clientDataProcTime) * 1000) / cntsInSec;\n\n        if (r.nNonEmptyInstrMethodGroupResponses > 0) {\n            r.totalHotswappingTime = (((double) ProfilerInterface.totalHotswappingTime) * 1000) / cntsInSec;\n            r.averageHotswappingTime = ((((double) ProfilerInterface.totalHotswappingTime) * 1000) / cntsInSec / ProfilerInterface.nNonEmptyInstrMethodGroupResponses);\n            r.minHotswappingTime = (((double) ProfilerInterface.minHotswappingTime) * 1000) / cntsInSec;\n            r.maxHotswappingTime = (((double) ProfilerInterface.maxHotswappingTime) * 1000) / cntsInSec;\n        }\n\n        r.methodEntryExitCallTime0 = (((double) status.methodEntryExitCallTime[0]) * 1000000) / cntsInSec; // Expressed in microseconds\n        r.methodEntryExitCallTime1 = (((double) status.methodEntryExitCallTime[1]) * 1000000) / cntsInSec; // Ditto\n        r.methodEntryExitCallTime2 = (((double) status.methodEntryExitCallTime[2]) * 1000000) / cntsInSec; // Expressed in microseconds\n\n        return r;\n    }\n\n    static void resetInternalStatsCollectors() {\n        ProfilerInterface.totalHotswappingTime = 0;\n        ProfilerInterface.clientInstrTime = 0;\n        ProfilerInterface.clientDataProcTime = 0;\n    }\n\n    private static void measureCodeRegionCalls() {\n        printResults(\"\\n\" + REGION_TIME_MSG); // NOI18N\n        ProfilerRuntimeCPUCodeRegion.setCPUResBufSize(100);\n        ProfilerRuntimeCPUCodeRegion.resetProfilerCollectors();\n\n        int noOfInnerIterations = 50;\n\n        for (int i = 0; i < 50; i++) {\n            long time = Timers.getCurrentTimeInCounts();\n\n            for (int j = 0; j < noOfInnerIterations; j++) {\n                ProfilerRuntimeCPUCodeRegion.codeRegionEntry();\n                ProfilerRuntimeCPUCodeRegion.codeRegionExit();\n                ProfilerRuntimeCPUCodeRegion.codeRegionEntry();\n                ProfilerRuntimeCPUCodeRegion.codeRegionExit();\n            }\n\n            time = Timers.getCurrentTimeInCounts() - time;\n\n            if (printResults && ((i % 5) == 0)) {\n                double timeInCounts = (double) time / (noOfInnerIterations * 2);\n                double timePerMethodInMCS = (((double) time * 1000000) / cntInSecond / (noOfInnerIterations * 2));\n                printResults(MessageFormat.format(TIME_COUNTS_MCS_MSG, new Object[] { \"\" + timeInCounts, \"\" + timePerMethodInMCS })); // NOI18N\n            }\n        }\n    }\n\n    private static void measureMethodEntryExitCalls() {\n        boolean absolute = false;\n        boolean threadCPU = false;\n\n        switch (nCall) {\n            case -1:\n            case 0:\n                absolute = true;\n                threadCPU = false;\n\n                break;\n            case 1:\n                absolute = false;\n                threadCPU = true;\n\n                break;\n            case 2:\n            case 3:\n                absolute = true;\n                threadCPU = true;\n\n                break;\n        }\n\n        printResults(\"\\n\" + MessageFormat.format(TIME_SUCCESS_PAIRS_MSG, new Object[] { \"\" + absolute, \"\" + threadCPU })); // NOI18N\n\n        ProfilerRuntimeCPU.setTimerTypes(absolute, threadCPU);\n\n        // NOTE: this is, unfortunately, simply an experimentally determined number of iterations, that makes HotSpot fully inline\n        // the call when the server compiler is used. It would certainly be better to make this algorithm more adaptive, since\n        // this way it is likely to be quite sensitive to VM changes... I have also observed that for some reason on the server\n        // compiler on Windows, even after the warmup run, i.e. on nCall == 0, the measured call time does not achieve its lowest\n        // value until noOfOuterIterations is close to 200. On nCall == 1 etc. there does not seem to be such an issue. I can't\n        // explain this phenomenon yet.\n        int noOfOuterIterations = 300;\n        int noOfInnerIterations = 200;\n        int innerIterationBufferSize = (ThreadInfo.MAX_EVENT_SIZE * ((noOfInnerIterations * 4) + 2) * 5) / 4;\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        // Buffer size is calculated as \"required\" * 5/4, which is a \"safety margin\"\n        if (nCall == -1) {\n            buf = new byte[2 * innerIterationBufferSize];\n        }\n\n        ti.setEvBuf(buf);\n        ProfilerRuntime.eventBuffer = buf;\n        ProfilerRuntime.globalEvBufPosThreshold = buf.length; // To prevent event buffer dump triggering\n\n        if (nCall != 3) { // On the last call to this method, we just calculate the new value from the same array contents\n            minTimePerMethodEntryExitCallInMCS = 100000.0;\n            minTimePerMethodEntryExitCallInCounts = 1000000;\n            cycleWhenMinResultDetected = 1;\n\n            for (int i = 0; i < noOfOuterIterations; i++) {\n                ti.evBufPos = ((cycleWhenMinResultDetected + 1) % 2) * innerIterationBufferSize;\n                ProfilerRuntimeCPUFullInstr.rootMethodEntry((char) 1);\n\n                long time = Timers.getCurrentTimeInCounts();\n\n                for (int j = 0; j < noOfInnerIterations; j++) {\n                    ProfilerRuntimeCPUFullInstr.methodEntry((char) 2);\n                    ProfilerRuntimeCPUFullInstr.methodExit((char) 2);\n                    ProfilerRuntimeCPUFullInstr.methodEntry((char) 3);\n                    ProfilerRuntimeCPUFullInstr.methodExit((char) 3);\n                }\n\n                time = Timers.getCurrentTimeInCounts() - time;\n                ProfilerRuntimeCPUFullInstr.methodExit((char) 1);\n\n                double timeInCounts = (double) time / (noOfInnerIterations * 2);\n                double timeInMCS = (((double) time * 1000000) / cntInSecond / (noOfInnerIterations * 2));\n\n                // Calculate the deviation\n                //if (i > 10 && !(nCall == 0 && i < (noOfOuterIterations - 100))) {\n                //  deviation += (double) Math.abs(timeInCounts - minTimePerMethodEntryExitCallInCounts) / minTimePerMethodEntryExitCallInCounts;\n                //  nDevSamples++;\n                //}\n                if (timeInCounts < minTimePerMethodEntryExitCallInCounts) {\n                    minTimePerMethodEntryExitCallInCounts = timeInCounts;\n                    minTimePerMethodEntryExitCallInMCS = timeInMCS;\n                    cycleWhenMinResultDetected = ((cycleWhenMinResultDetected + 1) % 2);\n                }\n\n                if (printResults && ((i % 5) == 0)) {\n                    printResults(MessageFormat.format(TIME_COUNTS_MCS_MSG, new Object[] { \"\" + timeInCounts, \"\" + timeInMCS })); // NOI18N\n                }\n            }\n\n            printResults(MessageFormat.format(MINIMUM_TIME_MSG,\n                                              new Object[] {\n                                                  \"\" + minTimePerMethodEntryExitCallInCounts, // NOI18N\n                                                  \"\" + minTimePerMethodEntryExitCallInMCS // NOI18N\n                                              }));\n        }\n\n        // Now calculate the ratio of time spent in the inner part of methodEntry-methodExit pair to the time\n        // spent in the outer part of this pair.\n        printResults(\"\\n\" + INNER_OUTER_TIME_MSG); // NOI18N\n\n        if ((nCall != 1) && (nCall != 3)) {\n            // High-precision calculation of inner and outer time when really hi-res timer is used.\n            int recordSize = 1 + 2 + 7 + ((nCall >= 2) ? 7 : 0); // Event type, method id, and 1 or 2 7-byte timestamps\n            int curPos = (cycleWhenMinResultDetected * innerIterationBufferSize) + (1 * recordSize);\n\n            int totalCalls = noOfInnerIterations * 4;\n            long innerTime = 0;\n            long outerTime = 0;\n            long prevTimeStamp = 0;\n            boolean inner = false;\n            int prefixEls = 1 + 2 + ((nCall == 3) ? 7 : 0); // Event type, method id, possible second time stamp\n            int suffixEls = ((nCall == 2) ? 7 : 0); // Possible second time stamp\n\n            for (int i = 0; i < totalCalls; i++) {\n                byte eventType = buf[curPos];\n\n                // Now that the implementation is stable, there is not much need in the following checks\n                if (inner && (eventType != METHOD_EXIT)) {\n                    System.out.println(\"Problem with inner! \" + (int) eventType + \", curPos = \" + curPos); // NOI18N\n                } else if (!inner && (eventType != METHOD_ENTRY)) {\n                    System.out.println(\"Problem with outer! \" + (int) eventType + \", curPos = \" + curPos); // NOI18N\n                }\n\n                curPos += prefixEls; // Omit event type, method id, and, possibly, non-relevant timestamp\n\n                long timeStamp = (((long) buf[curPos++] & 0xFF) << 48) | (((long) buf[curPos++] & 0xFF) << 40)\n                                 | (((long) buf[curPos++] & 0xFF) << 32) | (((long) buf[curPos++] & 0xFF) << 24)\n                                 | (((long) buf[curPos++] & 0xFF) << 16) | (((long) buf[curPos++] & 0xFF) << 8)\n                                 | ((long) buf[curPos++] & 0xFF);\n                long time = (i > 0) ? (timeStamp - prevTimeStamp) : 0;\n\n                if (inner) {\n                    innerTime += time;\n                } else {\n                    outerTime += time;\n                }\n\n                inner = !inner;\n                prevTimeStamp = timeStamp;\n                curPos += suffixEls;\n            }\n\n            innerTimeInCounts = ((double) innerTime) / ((double)totalCalls / 2);\n            outerTimeInCounts = ((double) outerTime) / (((double)totalCalls / 2) - 1);\n        } else {\n            // Both on Windows and Solaris, thread-local time is extremely low-resolution (10 ms and 1 ms),\n            // thus our standard high-precision method won't work. Rough calculation is used instead.\n            // Can we (and does it make sense to) do better?\n            innerTimeInCounts = outerTimeInCounts = minTimePerMethodEntryExitCallInCounts / 2;\n        }\n\n        double innerTimeInMCS = ((innerTimeInCounts * 1000000) / cntInSecond);\n        double outerTimeInMCS = ((outerTimeInCounts * 1000000) / cntInSecond);\n        printResults(MessageFormat.format(INNER_TIME_MCS_MSG, new Object[] { \"\" + innerTimeInMCS })); // NOI18N\n        printResults(MessageFormat.format(OUTER_TIME_MCS_MSG, new Object[] { \"\" + outerTimeInMCS })); // NOI18N\n    }\n\n    private static void measureSampledMethodEntryExitCalls() {\n        printResults(\"\\n\" + SAMPLED_TIME_MSG); // NOI18N\n                                               //ProfilerRuntime.resetProfilerCollectors(INSTR_RECURSIVE_SAMPLED);  THIS IS NOT NEEDED - will delete our current ThreadInfo\n\n        int noOfOuterIterations = (nCall == -1) ? 200 : 80; // Large number to make the server compiler inline everything\n        int noOfInnerIterations = 200;\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n        ti.setEvBuf(buf);\n\n        minTimePerMethodEntryExitCallInMCS = 100000.0;\n        minTimePerMethodEntryExitCallInCounts = 1000000;\n\n        for (int i = 0; i < noOfOuterIterations; i++) {\n            ti.evBufPos = 0;\n            ProfilerRuntimeCPUSampledInstr.rootMethodEntry((char) 1);\n\n            long time = Timers.getCurrentTimeInCounts();\n\n            for (int j = 0; j < noOfInnerIterations; j++) {\n                ProfilerRuntimeCPUSampledInstr.methodEntry((char) 2);\n                ProfilerRuntimeCPUSampledInstr.methodExit((char) 2);\n                ProfilerRuntimeCPUSampledInstr.methodEntry((char) 3);\n                ProfilerRuntimeCPUSampledInstr.methodExit((char) 3);\n                ProfilerRuntimeCPUSampledInstr.methodEntry((char) 2);\n                ProfilerRuntimeCPUSampledInstr.methodExit((char) 2);\n                ProfilerRuntimeCPUSampledInstr.methodEntry((char) 3);\n                ProfilerRuntimeCPUSampledInstr.methodExit((char) 3);\n            }\n\n            time = Timers.getCurrentTimeInCounts() - time;\n            ProfilerRuntimeCPUSampledInstr.methodExit((char) 1);\n\n            double timeInCounts = (double) time / (noOfInnerIterations * 4);\n            double timeInMCS = (((double) time * 1000000) / cntInSecond / (noOfInnerIterations * 4));\n\n            if (timeInCounts < minTimePerMethodEntryExitCallInCounts) {\n                minTimePerMethodEntryExitCallInCounts = timeInCounts;\n                minTimePerMethodEntryExitCallInMCS = timeInMCS;\n            }\n\n            if (printResults && ((i % 5) == 0)) {\n                System.out.println(MessageFormat.format(TIME_COUNTS_MCS_MSG, new Object[] { \"\" + timeInCounts, \"\" + timeInMCS })); // NOI18N\n            }\n        }\n\n        innerTimeInCounts = outerTimeInCounts = minTimePerMethodEntryExitCallInCounts / 2;\n    }\n\n    private static void measureTimerCall(boolean absolute) {\n        if (absolute) {\n            printResults(TIME_getCurrentTimeInCounts_MSG);\n        } else {\n            printResults(TIME_getThreadCPUTimeInNanos_MSG);\n        }\n\n        int noOfInnerIterations = 1000;\n        long res;\n\n        for (int i = 0; i < 50; i++) {\n            long time = Timers.getCurrentTimeInCounts();\n\n            for (int j = 0; j < noOfInnerIterations; j++) {\n                if (absolute) {\n                    res = Timers.getCurrentTimeInCounts();\n                } else {\n                    res = Timers.getThreadCPUTimeInNanos();\n                }\n            }\n\n            time = Timers.getCurrentTimeInCounts() - time;\n\n            if (printResults && ((i % 5) == 0)) {\n                double timeInCounts = (double) time / (noOfInnerIterations + 2);\n                double timePerMethodInMCS = (((double) time * 1000000) / cntInSecond / (noOfInnerIterations + 2));\n                printResults(MessageFormat.format(TIME_COUNTS_MCS_MSG, new Object[] { \"\" + timeInCounts, \"\" + timePerMethodInMCS })); // NOI18N\n            }\n        }\n    }\n\n    private static void printResults(String str) {\n        if (printResults) {\n            System.out.println(str);\n        }\n    }\n\n    /** The following two methods can be used for info purposes if needed */\n    /*private static void measureUnsuccessfulMethodEntryExitCalls() {\n       printResults(\"\\nTime per each unsuccessful methodEntry()/methodExit() pair of calls\");\n       ProfilerRuntime.resetProfilerCollectors(INSTR_RECURSIVE);\n       int noOfInnerIterations = 50;\n       for (int i = 0; i < 15; i++) {\n         long time = Timers.getCurrentTimeInCounts();\n         for (int j = 0; j < noOfInnerIterations; j++) {\n           ProfilerRuntimeCPUFullInstr.methodEntry((char) 2);\n           ProfilerRuntimeCPUFullInstr.methodExit((char) 2);\n           ProfilerRuntimeCPUFullInstr.methodEntry((char) 3);\n           ProfilerRuntimeCPUFullInstr.methodExit((char) 3);\n         }\n         time = Timers.getCurrentTimeInCounts() - time;\n         if (printResults && i % 5 == 0) {\n           double timeInCounts = (double) time / (noOfInnerIterations * 2);\n           double timePerMethodInMCS = ((double) time * 1000000 / cntInSecond / (noOfInnerIterations * 2));\n           System.out.println(timeInCounts + \" counts,  \" + timePerMethodInMCS + \" mcs\");\n         }\n       }\n       }\n       private static void measureSuccessfulMethodEntryExitCallsCalledFromInterpreted(boolean printResults) {\n         printResults(\"\\nTime per successful methodEntry()/methodExit() pair when called from interpreted code\");\n         ProfilerRuntime.resetProfilerCollectors(INSTR_RECURSIVE);\n         ProfilerRuntimeCPU.createThreadInfoForThread(Thread.currentThread());\n         int noOfInnerIterations = 50;\n         for (int i = 0; i < 15; i++) {\n           ProfilerRuntimeCPUFullInstr.rootMethodEntry((char) 1);\n           long time = Timers.getCurrentTimeInCounts();\n           for (int j = 0; j < noOfInnerIterations; j++) {\n             ProfilerRuntimeCPUFullInstr.methodEntry((char) 2);\n             ProfilerRuntimeCPUFullInstr.methodExit((char) 2);\n             ProfilerRuntimeCPUFullInstr.methodEntry((char) 3);\n             ProfilerRuntimeCPUFullInstr.methodExit((char) 3);\n           }\n           time = Timers.getCurrentTimeInCounts() - time;\n           ProfilerRuntimeCPUFullInstr.methodExit((char) 1);\n           if (printResults && i % 5 == 0) {\n             double timeInCounts = (double) time / (noOfInnerIterations * 2);\n             double timePerMethodInMCS = ((double) time * 1000000 / cntInSecond / (noOfInnerIterations * 2));\n             System.out.println(timeInCounts + \" counts,  \" + timePerMethodInMCS + \" mcs\");\n           }\n         }\n       }  ***/\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilerInterface.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.lang.ref.WeakReference;\nimport java.lang.reflect.Method;\nimport java.net.URL;\nimport java.text.MessageFormat;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\nimport java.util.ResourceBundle;\nimport java.util.WeakHashMap;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.global.TransactionalSupport;\nimport org.graalvm.visualvm.lib.jfluid.server.system.*;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.*;\n\n\n/**\n * Main interface to the target VM side introspection functionality.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Adrian Mos\n * @author Ian Formanek\n */\npublic class ProfilerInterface implements CommonConstants {\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private static class HFIRIThread extends Thread {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        HFIRIThread() {\n            ThreadInfo.addProfilerServerThread(this);\n            this.setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + \" 1\"); // NOI18N\n            setDaemon(true);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void run() {\n            RootClassLoadedCommand cmd = new RootClassLoadedCommand(new String[] { \"*FAKE_CLASS_1*\", \"*FAKE_CLASS_2*\" }, // NOI18N\n                                                                    new int[] { 0, 0 }, null, new int[] { 0, 0 }, new int[2][], 2, new int[] { -1 });\n            profilerServer.sendComplexCmdToClient(cmd);\n\n            InstrumentMethodGroupResponse imgr = (InstrumentMethodGroupResponse) ProfilerServer.getLastResponse();\n            ThreadInfo.removeProfilerServerThread(this);\n        }\n    }\n\n    private static class InitiateProfilingThread extends Thread {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private InitiateProfilingCommand cmd;\n        private boolean targetAppRunning;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        InitiateProfilingThread(InitiateProfilingCommand cmd, boolean targetAppRunning) {\n            ThreadInfo.addProfilerServerThread(this);\n            this.setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + \" 2\"); // NOI18N\n            this.cmd = cmd;\n            this.targetAppRunning = targetAppRunning;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void run() {\n            Monitors.enterServerState(CommonConstants.SERVER_INITIALIZING);\n            // We take a serialClientOperationsLock, then turn class load hook on, to prevent possible class loads, that\n            // will neither get into loadedClassesArray nor be intercepted properly and reported to client by classLoadHook.\n            // In other words, classes that are loaded before this point get into loadedClassesArray; classes loaded\n            // afterwards should be individually intercepted and reported to client.\n            serialClientOperationsLock.beginTrans(true);\n\n            try {\n                initInstrumentationThread = Thread.currentThread();\n\n                int instrType = cmd.getInstrType();\n                setCurrentInstrType(instrType);\n                switch (instrType) {\n                    case INSTR_NONE:\n                        // do nothing\n                        break;\n                    case INSTR_NONE_SAMPLING:\n                        ProfilerRuntimeSampler.initialize();\n                        break;\n                    case INSTR_CODE_REGION:\n                    case INSTR_RECURSIVE_FULL:\n                    case INSTR_RECURSIVE_SAMPLED:\n                    case INSTR_OBJECT_ALLOCATIONS:\n                    case INSTR_OBJECT_LIVENESS:\n                        initiateInstrumentation(instrType);\n                        break;\n                    case INSTR_NONE_MEMORY_SAMPLING:\n                        if (Histogram.initialize(Platform.getJDKVersionNumber() >= Platform.JDK_19)) {\n                            ProfilerServer.notifyClientOnResultsAvailability();\n                        }\n                        break;\n                    default:\n                        throw new IllegalArgumentException(\"Instr. type: \"+instrType);\n                }\n                initInstrumentationThread = null;\n            } finally {\n                serialClientOperationsLock.endTrans();\n                Monitors.exitServerState();\n            }\n\n            ThreadInfo.removeProfilerServerThread(this);\n        }\n\n        private void initiateInstrumentation(final int instrType) {\n            Monitors.DeterminateProgress progress = Monitors.enterServerState(CommonConstants.SERVER_INITIALIZING, 2);\n            int[] profilingPointIDs = cmd.getProfilingPointIDs();\n            String[] handlers = cmd.getProfilingPointHandlers();\n            String[] infos = cmd.getProfilingPointInfos();\n            \n            rootClassNames = cmd.getRootClassNames();\n            status.startProfilingPointsActive = cmd.isStartProfilingPointsActive();\n            ProfilingPointServerHandler.initInstances(profilingPointIDs, handlers, infos);\n            computeRootWildcard();\n            rootClassLoaded = false;\n\n            // the following code is needed to avoid issue 59660: Remote profiling can cause the agent to hang if CPU\n            // or Code Fragment profiling is used\n            // see http://profiler.netbeans.org/issues/show_bug.cgi?id=59660\n            // and http://profiler.netbeans.org/issues/show_bug.cgi?id=61968\n            new LinkedHashMap().keySet().iterator();\n            try {\n                // for take heap dump\n                Class.forName(\"java.lang.reflect.InvocationTargetException\"); // NOI18N\n                Class.forName(\"java.lang.InterruptedException\");    // NOI18N\n                Class.forName(\"java.lang.ClassFormatError\"); // NOI18N class caching\n            } catch (ClassNotFoundException e) {\n                e.printStackTrace(System.err);\n            }\n\n            if (Platform.getJDKVersionNumber() >= CommonConstants.JDK_19) {\n                try {\n                    // preload classes for classLoadHook()\n                    Class.forName(\"java.lang.WeakPairMap$Pair\"); // NOI18N\n                    Class.forName(\"java.lang.WeakPairMap$WeakRefPeer\");    // NOI18N\n                    Class.forName(\"java.lang.WeakPairMap$Pair$Weak\"); // NOI18N\n                    Class.forName(\"java.lang.WeakPairMap$Pair$Weak$1\"); // NOI18N\n                } catch (ClassNotFoundException e) {\n                    e.printStackTrace(System.err);\n                }\n            }\n            \n            // The following code is needed to enforce native method bind for Thread.sleep before instrumentation, so\n            // that the NativeMethodBind it can be disabled as first thing in instrumentation\n            // this is needed as a workaround for JDK bug:\n            // CR 6318850 Updated P3 hotspot/jvmti RedefineClasses() and NativeMethodBind event crash\n            try {\n                Thread.sleep(1);\n            } catch (InterruptedException e) {\n            } // ignore\n\n            synchronized (this) {\n                try {\n                    wait(1);\n                } catch (InterruptedException e) {\n                } // ignore\n            }\n\n            // reset loadedClassesArray so that next time it contains current loaded classes\n            loadedClassesArray = null;\n            loadedClassesLoaders = null;\n            Classes.enableClassLoadHook();\n\n            instrSpawnedThreads = cmd.getInstrSpawnedThreads();\n\n            if (targetAppRunning || hasAnyCoreClassNames(cmd.getRootClassNames()) || instrSpawnedThreads\n                    || (instrType == INSTR_OBJECT_ALLOCATIONS) || (instrType == INSTR_OBJECT_LIVENESS)) {\n                getLoadedClasses(); // Init loadedClassesArray\n\n                boolean loadedRootClassesExist = false;\n\n                if (!detachStarted) {\n                    switch (instrType) {\n                        case INSTR_RECURSIVE_FULL:\n                        case INSTR_RECURSIVE_SAMPLED:\n                            // This will look into loadedClassesArray to check if there are any root classes already loaded\n                            loadedRootClassesExist = instrSpawnedThreads ? true : checkForLoadedRootClasses();\n\n                            break;\n                        case INSTR_CODE_REGION:\n                            loadedRootClassesExist = checkForLoadedRootClasses();\n\n                            break;\n                        case INSTR_OBJECT_ALLOCATIONS:\n                        case INSTR_OBJECT_LIVENESS:\n                            loadedRootClassesExist = true;\n\n                            break;\n                    }\n                }\n\n                progress.next();\n\n                if (loadedRootClassesExist) { // Root class(es) has been loaded or none is needed - start\n                                              // instrumentation-related operations right away\n                    sendRootClassLoadedCommand(false);\n\n                    if (!getAndInstrumentClasses(true)) {\n                        disableProfilerHooks();\n                    }\n\n                    rootClassLoaded = true; // See the comment in classLoadHook why it's worth setting rootClassLoaded\n                                            // to true after the first instrumentation, not before\n                } else {\n                    // if root class is not loaded, reset loadedClassesArray so that next time it contains current loaded classes\n                    loadedClassesArray = null;\n                    loadedClassesLoaders = null;\n                }\n            }\n            Monitors.exitServerState();\n        }\n\n        private static void computeRootWildcard() {\n            rootClassNameWildcard = new boolean[rootClassNames.length];\n            rootClassNamePackageWildcard = new boolean[rootClassNames.length];\n\n            for (int i = 0; i < rootClassNames.length; i++) {\n                int nameLen = rootClassNames[i].length();\n                rootClassNameWildcard[i] = (nameLen == 0) // default package wildcard\n                                           || (rootClassNames[i].charAt(nameLen - 1) == '.'); // ends with \".\" // NOI18N\n                if (!rootClassNameWildcard[i]) {\n                    if (rootClassNames[i].charAt(nameLen - 1) == '*') { // package wild card - instrument all classes including subpackages\n                        rootClassNames[i] = rootClassNames[i].substring(0,nameLen - 1); // remove *\n                        rootClassNameWildcard[i] = true;\n                        rootClassNamePackageWildcard[i] = true;\n                    }\n//                    System.out.println(\"Root \"+rootClassNames[i]+\" wild \"+rootClassNameWildcard[i]+\" package \"+rootClassNamePackageWildcard[i]);\n                }\n            }\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final int REDEFINE_CHUNK_SIZE = 500;\n    \n    static final char BOOLEAN = 'Z'; // NOI18N\n    static final char CHAR = 'C'; // NOI18N\n    static final char BYTE = 'B'; // NOI18N\n    static final char SHORT = 'S'; // NOI18N\n    static final char INT = 'I'; // NOI18N\n    static final char LONG = 'J'; // NOI18N\n    static final char FLOAT = 'F'; // NOI18N\n    static final char DOUBLE = 'D'; // NOI18N\n    static final char VOID = 'V'; // NOI18N\n    static final char REFERENCE = 'L'; // NOI18N\n\n    // -----\n    // I18N String constants\n    // !!! Warning - do not use ResourceBundle.getBundle here, won't work in context of direct/dynamic attach !!!\n    // Default EN messages initialized here, will be replaced by localized messages in static initializer\n    private static String INTERNAL_ERROR_MSG = \"Internal error:\\nExpected InstrumentMethodGroupResponse, got response of class {0},\\nvalue = {1}\\nAll instrumentation will be removed\"; // NOI18N\n    private static String UNEXPECTED_EXCEPTION_MSG = \"Unexpected exception caught when trying to instrument classes.\\nOriginal exception:\\n{0}\\nStack trace:\\n\\n{1}\"; // NOI18N\n    private static String INSTRUMENTATION_SUCCESSFUL_MSG = \"Deferred instrumentation performed successfully\"; // NOI18N\n    private static String HISTOGRAM_NOT_AVAILABLE_MSG = \"Histogram is not available.\"; // NOI18N\n    // -----\n\n    static {\n        ResourceBundle messages = ProfilerServer.getProfilerServerResourceBundle();\n\n        if (messages != null) {\n            INTERNAL_ERROR_MSG = messages.getString(\"ProfilerInterface_InternalErrorMsg\"); // NOI18N\n            UNEXPECTED_EXCEPTION_MSG = messages.getString(\"ProfilerInterface_UnexpectedExceptionMsg\"); // NOI18N\n            INSTRUMENTATION_SUCCESSFUL_MSG = messages.getString(\"ProfilerInterface_InstrumentationSuccessfulMsg\"); // NOI18N\n            HISTOGRAM_NOT_AVAILABLE_MSG = messages.getString(\"ProfilerInterface_HistogramNotAvailableMsg\");     // NOI18N\n        }\n    }\n\n    // TODO [release]: change value to FALSE to remove the print code below entirely by compiler\n    private static final boolean DEBUG = Boolean.getBoolean(\"org.graalvm.visualvm.lib.jfluid.server.ProfilerInterface.classLoadHook\"); // NOI18N\n    private static final boolean INSTRUMENT_JFLUID_CLASSES = Boolean.getBoolean(\"org.graalvm.visualvm.lib.jfluid.server.instrumentJFluidClasses\"); // NOI18N\n\n    private static final byte[] EMPTY = new byte[0];\n    \n    // The lock used to serialize requests from server to client. May be used outside this class.\n    public static final TransactionalSupport serialClientOperationsLock = new TransactionalSupport();\n    private static ProfilerServer profilerServer;\n    private static ProfilingSessionStatus status;\n    private static EventBufferManager evBufManager;\n    private static WeakReference[] loadedClassesArray; // Temporary array, used to send all loaded class names to client\n                                               // on instrumentation initiation.\n    private static int[] loadedClassesLoaders; // Ditto, for loaders\n    private static WeakHashMap reflectMethods; // Cache of methods called using reflection\n    private static boolean targetAppSuspended = false;\n    private static boolean instrumentReflection = false;\n    private static boolean instrSpawnedThreads;\n    private static int[] packedArrayOffsets;\n    private static int nSystemThreads;\n    private static Thread initInstrumentationThread;\n    private static String[] rootClassNames;\n    private static boolean[] rootClassNameWildcard;\n    private static boolean[] rootClassNamePackageWildcard;\n\n    // For statistics\n    static int nClassLoads;\n\n    // For statistics\n    static int nFirstMethodInvocations;\n\n    // For statistics\n    static int nEmptyInstrMethodGroupResponses;\n    static int nNonEmptyInstrMethodGroupResponses;\n    static int nSingleMethodInstrMethodGroupResponses;\n    static int nTotalInstrMethods;\n    static long totalHotswappingTime;\n    static long minHotswappingTime = 10000000000L;\n    static long maxHotswappingTime;\n    static long clientInstrStartTime;\n    static long clientInstrTime;\n    static long clientDataProcStartTime;\n    static long clientDataProcTime;\n\n    //----------------------------------------- Private implementation --------------------------------------------------\n    private static boolean rootClassLoaded; // has root class been loaded?\n\n    // The following variable addresses the issue of classLoadHook called for a class, that is already registered as\n    // loaded, (through getAllLoadedClasses) but is actually initialized only when extendConstantPool() is called on it.\n    // Initialization would cause classLoadHook invocation on this class, and subsequent \"second class load event\"\n    // messages in client (which is just confusing). But this may also cause more subtle deadlock bug due to\n    // classLoadHook() trying to record adjustTime event, while serialClientOperationsLock is held by an outer invocation\n    // of classLoadHook() or methodInvokedFirstTime(). To avoid all these problems we use this simple way to avoid\n    // unnecessary classLoadHook() invocations.\n    private static volatile Thread instrumentMethodGroupCallThread;\n\n    private static volatile boolean detachStarted;\n    \n    private static HeapHistogramManager heapHistgramManager;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static CodeRegionCPUResultsResponse getCodeRegionCPUResults() {\n        CodeRegionCPUResultsResponse resp = new CodeRegionCPUResultsResponse(ProfilerRuntimeCPUCodeRegion.getProfilingResults());\n\n        return resp;\n    }\n\n    public static void setCurrentInstrType(int type) {\n        boolean isMemoryProfiling = (type == INSTR_OBJECT_ALLOCATIONS) || (type == INSTR_OBJECT_LIVENESS);\n\n        status.currentInstrType = type;\n        Classes.setVMObjectAllocEnabled(isMemoryProfiling);\n    }\n\n    public static int getCurrentInstrType() {\n        return status.currentInstrType;\n    }\n\n    public static ThreadLivenessStatusResponse getCurrentThreadLivenessStatus() {\n        ThreadLivenessStatusResponse resp = new ThreadLivenessStatusResponse(ThreadInfo.getCurrentLivenessStatus());\n\n        return resp;\n    }\n\n    public static void setInstrumentReflection(boolean v) {\n        if (status.targetAppRunning) {\n            ProfilerRuntimeCPU.setJavaLangReflectMethodInvokeInterceptEnabled(v);\n        } else {\n            instrumentReflection = v;\n        }\n    }\n\n    public static MethodNamesResponse getMethodNamesForJMethodIds(int[] methodIds) {\n        final int PACKEDARR_ITEMS = 4; // must match PACKEDARR_ITEMS in Stacks.c\n        int nMethods = methodIds.length;\n        int len = nMethods * PACKEDARR_ITEMS;\n        packedArrayOffsets = new int[len];\n\n        byte[] packedData = Stacks.getMethodNamesForJMethodIds(nMethods, methodIds, packedArrayOffsets);\n        MethodNamesResponse resp = new MethodNamesResponse(packedData, packedArrayOffsets);\n\n        return resp;\n    }\n\n    public static int getNPrerecordedSystemThreads() {\n        return nSystemThreads;\n    }\n\n    public static ObjectAllocationResultsResponse getObjectAllocationResults() {\n        status.beginTrans(false);\n\n        try {\n            ObjectAllocationResultsResponse resp = new ObjectAllocationResultsResponse(status.getAllocatedInstancesCount(),\n                                                                                       status.getNInstrClasses());\n\n            return resp;\n        } finally {\n            status.endTrans();\n        }\n    }\n\n    public static void setProfilerServer(ProfilerServer server) {\n        profilerServer = server;\n    }\n\n    /**\n     * This method cleans up the data structures managed by this class, but not by various ProfilerRuntimeXXX classes.\n     * The latter are cleaned up separately, by the following deactivateInjectedCode() method.\n     */\n    public static void clearProfilerDataStructures() {\n        //loadedClassesArray = null;\n        //loadedClassesCPLengths = null;\n        //loadedClassesLoaders = null;\n        //ClassLoaderManager.reset();\n        //packedArrayOffsets = null;\n        reflectMethods = null;\n\n        //evBufManager.freeBufferFile();\n    }\n\n    public static boolean cpuResultsExist() {\n        return ProfilerRuntime.profiledTargetAppThreadsExist();\n    }\n\n    static void disableProfiling() {\n        int instrType = getCurrentInstrType();\n\n        switch (instrType) {\n            case INSTR_NONE:\n            case INSTR_NONE_MEMORY_SAMPLING:\n                ProfilerRuntime.clearDataStructures();\n                break;\n                \n            case INSTR_NONE_SAMPLING:\n                ProfilerRuntimeSampler.shutdown();\n                break;\n                \n            case INSTR_CODE_REGION:\n                ProfilerRuntimeCPUCodeRegion.enableProfiling(false);\n\n                if (rootClassNames != null) {\n                    rootClassNames = null;\n                }\n\n                break;\n            case INSTR_RECURSIVE_FULL:\n                ProfilerRuntimeCPUFullInstr.enableProfiling(false);\n                ProfilerRuntimeCPU.setTimerTypes(false, false); // Mainly to clean up microstate accounting on Solaris\n\n                break;\n            case INSTR_RECURSIVE_SAMPLED:\n                ProfilerRuntimeCPUSampledInstr.enableProfiling(false);\n                ProfilerRuntimeCPU.setTimerTypes(false, false);\n\n                break;\n            case INSTR_OBJECT_ALLOCATIONS:\n                ProfilerRuntimeObjAlloc.enableProfiling(false);\n\n                break;\n            case INSTR_OBJECT_LIVENESS:\n                ProfilerRuntimeObjLiveness.enableProfiling(false);\n\n                break;\n        }        \n    }\n\n    /**\n     * Deactivate the injected code for the current instrumentation type, and clean up all the supporting data structures\n     * maintained by the corresponding ProfilerRuntimeXXX class.\n     */\n    public static void deactivateInjectedCode() {\n        disableProfilerHooks();\n        disableProfiling();\n        status.resetInstrClassAndMethodInfo();\n        setCurrentInstrType(INSTR_NONE);\n    }\n\n    public static void disableProfilerHooks() {\n        Classes.setWaitTrackingEnabled(false);\n        Classes.setParkTrackingEnabled(false);\n        Classes.setSleepTrackingEnabled(false);\n        Classes.setVMObjectAllocEnabled(false);\n        Classes.disableClassLoadHook();\n        ProfilerRuntimeCPU.setJavaLangReflectMethodInvokeInterceptEnabled(false);\n        ClassLoaderManager.setNotifyToolAboutUnloadedClasses(false);\n    }\n\n    public static void dumpExistingResults(boolean live) {\n        if (!live && (getCurrentInstrType() == INSTR_OBJECT_LIVENESS) && ProfilerRuntimeObjLiveness.getRunGCOnGetResults()) {\n            GC.runGC();\n\n            try {\n                // Give WeakReference collector thread a chance to register some (hopefully most of) object GCs\n                Thread.sleep(500);\n\n            } catch (Exception ex) {\n            }\n        }\n\n        ProfilerRuntime.dumpEventBuffer();\n    }\n\n    /**\n     * This method initializes the internal data structures, and also records the profiler's own thread(s), so that\n     * they are not affected by our suspend/resume operations. If we run in the normal mode, i.e. the target JVM was\n     * started by the client, specialThread is the current thread, which will then become the target app main thread.\n     * It should be excluded from the list of the profiler's own threads. If we run in the attached mode, specialThread\n     * is the only thread that we can reliably characterize as the profiler's own.\n     */\n    public static void initProfilerInterface(ProfilingSessionStatus status, Thread specialThread) {\n        boolean jdk15 = Platform.getJDKVersionNumber() == Platform.JDK_15;\n        Timers.initialize();\n        Classes.initialize();\n        GC.initialize();\n        Stacks.initialize();\n        Threads.initialize();\n        HeapDump.initialize(jdk15);\n        ThreadDump.initialize(jdk15);\n        ClassLoaderManager.initialize(profilerServer);\n        ClassLoaderManager.addSystemClassLoader();\n        reflectMethods = new WeakHashMap();\n\n        evBufManager = new EventBufferManager(profilerServer);\n        heapHistgramManager = new HeapHistogramManager();\n        ProfilerInterface.status = status;\n        detachStarted = false;\n\n        // Check that all profiler's own threads are running, and then record them internally, so that target app threads\n        // are accounted for properly.\n        while (!Monitors.monitorThreadsStarted()) {\n            try {\n                Thread.sleep(50);\n            } catch (Exception ex) {\n            }\n        }\n\n        if (status.runningInAttachedMode) {\n            Threads.recordProfilerOwnThreads(false, specialThread);\n            nSystemThreads = -1; // Indicates that we really don't know how many of these threads\n                                 // are VM-own, or system, threads\n        } else {\n            nSystemThreads = Threads.recordProfilerOwnThreads(true, specialThread);\n        }\n\n        ProfilerRuntime.init(new ProfilerRuntime.ExternalActionsHandler() {\n                public void handleFirstTimeMethodInvoke(char methodId) {\n                    firstTimeMethodInvokeHook(methodId);\n                }\n\n                public void handleReflectiveInvoke(Method method) {\n                    reflectiveMethodInvokeHook(method);\n                }\n\n                public int handleFirstTimeVMObjectAlloc(String className, int definingClassLoaderId) {\n                    return firstTimeVMObjectAlloc(className, definingClassLoaderId);\n                }\n\n                public void handleEventBufferDump(byte[] eventBuffer, int startPos, int curPtrPos) {\n                    serialClientOperationsLock.beginTrans(true); // So that this event does not interfere with class\n                                                                 // loads / method invocations\n                    try {\n                        clientDataProcStartTime = Timers.getCurrentTimeInCounts();\n                        evBufManager.eventBufferDumpHook(eventBuffer, startPos, curPtrPos);\n                        clientDataProcTime += (Timers.getCurrentTimeInCounts() - clientDataProcStartTime);\n                    } finally {\n                        serialClientOperationsLock.endTrans();\n                    }\n                }\n            });\n    }\n\n    public static void initiateProfiling(final InitiateProfilingCommand cmd, final boolean targetAppRunning)\n                                        throws Exception {\n        int instrType = cmd.getInstrType();\n        String instrClassName = cmd.getRootClassName();\n\n        if (instrClassName.equals(\"*FAKE_CLASS_FOR_INTERNAL_TEST*\")) { // NOI18N\n            handleFakeInitRecursiveInstrumentationCommand(); // To initialize certain internal classes, see comments\n                                                             // in handleFake... method\n\n            return;\n        }\n\n        switch (instrType) {\n            case INSTR_NONE:\n            case INSTR_NONE_MEMORY_SAMPLING:\n                createEventBuffer();\n                \n                break;\n            case INSTR_RECURSIVE_FULL:\n            case INSTR_RECURSIVE_SAMPLED:\n            case INSTR_OBJECT_ALLOCATIONS:\n            case INSTR_OBJECT_LIVENESS:\n                createEventBuffer();\n                status.resetInstrClassAndMethodInfo();\n\n                if ((instrType == INSTR_OBJECT_ALLOCATIONS) || (instrType == INSTR_OBJECT_LIVENESS)) {\n                    ClassLoaderManager.setNotifyToolAboutUnloadedClasses(true);\n                } else {\n                    ClassLoaderManager.setNotifyToolAboutUnloadedClasses(false);\n                }\n\n                break;\n            case INSTR_CODE_REGION:\n                ProfilerRuntimeCPUCodeRegion.resetProfilerCollectors();\n\n                break;\n            case INSTR_NONE_SAMPLING:\n                createEventBuffer();\n                break;\n            default:\n                throw new IllegalArgumentException(\"Instr. type: \"+instrType);\n        }\n\n        // We have to perform the following operations in a separate thread, since they may involve further dialog with\n        // the tool (client), whereas this thread has to return quickly to send the \"OK\" response to the tool.\n        new InitiateProfilingThread(cmd, targetAppRunning).start();\n    }\n\n    public static void instrumentMethods(InstrumentMethodGroupCommand cmd)\n                                  throws Exception {\n        if (!cmd.isEmpty()) {\n            try {\n                instrumentMethodGroupNow(cmd.getBase());\n            } catch (Exception ex) {\n                deactivateInjectedCode();\n                setCurrentInstrType(INSTR_NONE);\n                throw ex;\n            }\n        }\n\n        setCurrentInstrType(cmd.getInstrType());\n    }\n\n    public static void resetProfilerCollectors() {\n        ProfilerRuntime.resetProfilerCollectors(getCurrentInstrType());\n        reflectMethods = new WeakHashMap(); // So that methods that are possibly holding unreachable classes are\n                                            // removed and classes allowed to be GCed\n    }\n\n    public static void resumeTargetApp() {\n        if (getCurrentInstrType() == INSTR_RECURSIVE_FULL) {\n            ProfilerRuntimeCPUFullInstr.resumeActiveTimers();\n        }\n\n        Threads.resumeTargetAppThreads(null);\n        targetAppSuspended = false;\n    }\n\n    public static void suspendTargetApp() {\n        Threads.suspendTargetAppThreads(null);\n\n        if (getCurrentInstrType() == INSTR_RECURSIVE_FULL) {\n            ProfilerRuntimeCPUFullInstr.suspendActiveTimers();\n        }\n\n        targetAppSuspended = true;\n    }\n\n    static void createEventBuffer() throws IOException {\n        evBufManager.openBufferFile(EVENT_BUFFER_SIZE_IN_BYTES);\n        ProfilerRuntime.createEventBuffer(EVENT_BUFFER_SIZE_IN_BYTES);\n    }\n\n    static String getBufferFileName() {\n        if (evBufManager != null) {\n            return evBufManager.getBufferFileName();\n        }\n        return \"\";\n    }\n\n    static void setDetachStarted(boolean detachStarted) {\n        ProfilerInterface.detachStarted = detachStarted;\n    }\n\n    static boolean isDetachStarted() {\n        return detachStarted;\n    }\n        \n    static Response computeHistogram() {\n        Response resp = null;\n        \n        if (Histogram.isAvailable()) {\n            resp = heapHistgramManager.computeHistogram(Histogram.getRawHistogram());\n        }\n        if (resp == null) {\n            resp = new Response(HISTOGRAM_NOT_AVAILABLE_MSG);\n            \n        }\n        return resp;\n    }\n\n    static byte[][] getClassFileBytes(String[] classNames, int[] classLoaderIds) {\n        int MAX_CLASSES = 1000;\n        Class[] nonSystemClasses = new Class[MAX_CLASSES+1]; // classes loaded by classloaders other that bootstrap and system\n        int nonSystemIndex = 0;\n        byte[][] bytes = new byte[classNames.length][];\n        Class[] classes = new Class[classNames.length];\n\n        for (int i = 0; i < loadedClassesArray.length; i++) {\n            Class loadedClass = getOrdinaryClass(loadedClassesArray[i]);\n            if (loadedClass == null) {\n                // class was unloaded or has special name\n                continue;\n            }\n            int classLoaderId = loadedClassesLoaders[i];\n            String name = loadedClass.getName();\n            \n            // At the client side we treat classes loaded by the bootstrap and by the system classloaders in the same way\n            if (classLoaderId == -1) classLoaderId = 0;\n            for (int j = 0; j < classNames.length; j++) {\n                if (classLoaderIds[j] == classLoaderId && classNames[j].equals(name)) {\n                    classes[j] = loadedClass;\n                    nonSystemClasses[nonSystemIndex++] = loadedClass;\n                    break;\n                }\n            }\n            if (nonSystemIndex == MAX_CLASSES) {\n                cacheLoadedClasses(nonSystemClasses,nonSystemIndex);\n                nonSystemIndex = 0;\n                profilerServer.sendSimpleCmdToClient(Command.STILL_ALIVE);\n            }\n        }\n        if (nonSystemIndex > 0) {\n            cacheLoadedClasses(nonSystemClasses,nonSystemIndex);\n        }\n        for (int i = 0; i < classes.length; i++) {\n            if (classes[i] != null) {\n                bytes[i] = getClassFileBytes(classes[i], classLoaderIds[i]);\n            }\n        }\n        return bytes;\n    }\n    \n    private static boolean getAndInstrumentClasses(boolean rootClassInstrumentation) {\n        Response r = ProfilerServer.getLastResponse();\n\n        if (!(r instanceof InstrumentMethodGroupResponse)) { // This is an internal error which, hopefully, has been fixed.\n\n            String msg = MessageFormat.format(INTERNAL_ERROR_MSG, new Object[] { r.getClass(), r });\n            deactivateInjectedCode();\n            profilerServer.sendComplexCmdToClient(new AsyncMessageCommand(false, msg));\n\n            return false;\n        }\n\n        InstrumentMethodGroupResponse imgr = (InstrumentMethodGroupResponse) r;\n        clientInstrTime += (Timers.getCurrentTimeInCounts() - clientInstrStartTime);\n\n        if (!imgr.isOK()) {\n            return false;\n        }\n\n        if (imgr.isEmpty()) {\n            nEmptyInstrMethodGroupResponses++;\n\n            // Don't return immediately, because may have rootClassInstrumentation == true (see above)\n        } else {\n            // Do the following update before instrumentation, since if we do this after it, chances are some instrumented\n            // method in another thread enters e.g. methodEntry() and hits the not-yet-updated invocation array before\n            // updating has been completed.\n            updateInstrClassAndMethodNames(imgr.getBase(), true);\n\n            if (rootClassInstrumentation && (getCurrentInstrType() == INSTR_OBJECT_LIVENESS)) {\n                // Create a ThreadInfo for the current thread immediately to avoid recursion with trace object allocation calls\n                ThreadInfo.getThreadInfo();\n            }\n\n            try {\n                instrumentMethodGroupNow(imgr.getBase());\n            } catch (Exception ex) {\n                //deactivateInjectedCode();   // It looks like it often makes more sense to proceed and get at least some info\n                profilerServer.sendComplexCmdToClient(new AsyncMessageCommand(false, ex.getMessage()));\n\n                return true; // Used to be \"return false\" (but see comment above).\n            }\n        }\n\n        if (rootClassInstrumentation) {\n            switch (getCurrentInstrType()) {\n                case INSTR_RECURSIVE_FULL:\n\n                    if (instrumentReflection) {\n                        ProfilerRuntimeCPU.setJavaLangReflectMethodInvokeInterceptEnabled(true);\n                    }\n\n                    ProfilerRuntimeCPUFullInstr.enableProfiling(true);\n\n                    break;\n                case INSTR_RECURSIVE_SAMPLED:\n\n                    if (instrumentReflection) {\n                        ProfilerRuntimeCPU.setJavaLangReflectMethodInvokeInterceptEnabled(true);\n                    }\n\n                    ProfilerRuntimeCPUSampledInstr.enableProfiling(true);\n\n                    break;\n                case INSTR_CODE_REGION:\n                    ProfilerRuntimeCPUCodeRegion.enableProfiling(true);\n\n                    break;\n                case INSTR_OBJECT_ALLOCATIONS:\n                    ProfilerRuntimeObjAlloc.enableProfiling(true);\n\n                    break;\n                case INSTR_OBJECT_LIVENESS:\n                    ProfilerRuntimeObjLiveness.enableProfiling(true);\n\n                    break;\n            }\n        }\n\n        return true;\n    }\n\n    private static boolean isCoreClassName(String name) {\n        name = name.replace('.', '/'); // NOI18N\n\n        return (name.startsWith(\"java/\") || name.startsWith(\"sun/\") || name.startsWith(\"javax/\")); // NOI18N\n    }\n\n    private static void getLoadedClasses() {\n        if (loadedClassesArray == null) {\n            int nonSystemIndex = 0;\n            int MAX_CLASSES = 1000;\n            Class[] nonSystemClasses = new Class[MAX_CLASSES+1]; // classes loaded by classloaders other that bootstrap and system\n            boolean dynamic = profilerServer.isDynamic();\n            Class[] allClasses = Classes.getAllLoadedClasses();\n            loadedClassesArray = new WeakReference[allClasses.length];\n            loadedClassesLoaders = new int[allClasses.length];\n            \n            Monitors.DeterminateProgress progress = Monitors.enterServerState(CommonConstants.SERVER_PREPARING, loadedClassesArray.length);\n            try {\n                for (int i = 0; i < loadedClassesArray.length; i++) {\n                    progress.next();\n                    if(detachStarted) {\n                        return;\n                    }\n                    Class clazz = allClasses[i];\n                    loadedClassesArray[i] = new WeakReference(clazz);\n                    loadedClassesLoaders[i] = ClassLoaderManager.registerLoader(clazz);\n                }\n            } finally {\n                Monitors.exitServerState();\n            }\n        }\n    }\n\n    private static boolean isRootClass(String className) {\n        for (int i = 0; i < rootClassNames.length; i++) {\n            String rootName = rootClassNames[i];\n\n            if (rootClassNameWildcard[i]) {\n                if (className.startsWith(rootName)) {\n                    if (rootClassNamePackageWildcard[i]) {  // instrument also subpackages\n                        return true;\n                    }\n                    if (className.indexOf('.', rootName.length()) == -1) { // not a subpackage\n                        return true;\n                    }\n                } else if (rootClassNamePackageWildcard[i]){\n                    if (className.equals(rootName.substring(0,rootName.length()-1)))\n                    {\n                        return true;\n                    }\n                }\n            } else if (rootName.equals(className)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    private static void appendTypeName(StringBuffer sb, Class type) {\n        if (type.isArray()) {\n            do {\n                sb.append('['); // NOI18N\n                type = type.getComponentType();\n            } while (type.isArray());\n        }\n\n        if (type == Integer.TYPE) {\n            sb.append(INT);\n        } else if (type == Boolean.TYPE) {\n            sb.append(BOOLEAN);\n        } else if (type == Byte.TYPE) {\n            sb.append(BYTE);\n        } else if (type == Character.TYPE) {\n            sb.append(CHAR);\n        } else if (type == Long.TYPE) {\n            sb.append(LONG);\n        } else if (type == Float.TYPE) {\n            sb.append(FLOAT);\n        } else if (type == Double.TYPE) {\n            sb.append(DOUBLE);\n        } else if (type == Void.TYPE) {\n            sb.append(VOID);\n        } else {\n            sb.append(REFERENCE);\n            sb.append(type.getName().replace('.', '/')); // NOI18N\n            sb.append(';'); // NOI18N\n        }\n    }\n\n    private static boolean checkForLoadedRootClasses() {\n        for (int i = 0; i < loadedClassesArray.length; i++) {\n            Class loadedClass = (Class) loadedClassesArray[i].get();\n            if (loadedClass != null && isRootClass(loadedClass.getName())) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /** Called on CLASS_PREPARE JVMTI event */\n    private static void classLoadHook(Class clazz) {\n        ThreadInfo threadInfo = ThreadInfo.getThreadInfo();\n\n        threadInfo.inProfilingRuntimeMethod++;\n\n        try {\n            String className = clazz.getName();\n\n            if (instrumentMethodGroupCallThread == Thread.currentThread() || internalClassName(className)) { // See comment at inInstrumentMethodGroupCall\n                ClassLoaderManager.registerLoader(clazz); // Still register the loader, for reasons related with\n                                                          // management of jmethodIds\n\n                return;\n            }\n\n            Thread currentThread = Thread.currentThread();\n\n            if (PROFILER_SERVER_THREAD_NAME.equals(currentThread.getName())) {\n                System.err.println(ENGINE_WARNING + \"class \" + className + \" loaded by \" + PROFILER_SERVER_THREAD_NAME); // NOI18N\n\n                return;\n            }\n\n            if ((initInstrumentationThread != null) && (currentThread == initInstrumentationThread)) {\n                // Looks like on rare occasions we can get this problem - class load hook called when it shouldn't.\n                // If we are already here, we can't (easily at least) fix this problem, but at least we can warn the user.\n                System.err.println(ENGINE_WARNING + \"class load hook invoked at inappropriate time for \" // NOI18N\n                                   + className + \", loader = \" + clazz.getClassLoader()); // NOI18N\n                System.err.println(\"*** This class will not be instrumented unless you re-run the instrumentation command\"); // NOI18N\n                System.err.println(PLEASE_REPORT_PROBLEM);\n                System.err.println(\"=============================== Stack trace =====================\"); // NOI18N\n                Thread.dumpStack();\n                System.err.println(\"=============================== End stack trace =================\"); // NOI18N\n\n                return;\n            }\n\n            //System.out.println(\"+++ Class load hook invoked for \" + className + \", loader = \" + clazz.getClassLoader());\n            int classLoaderId = ClassLoaderManager.registerLoader(clazz);\n            boolean resumeTimer = false;\n\n            if (DEBUG) {\n                System.err.println(\"ProfilerInterface.classLoadHook.DEBUG: \" + className + \", classLoaderId: \" + classLoaderId); // NOI18N\n            }\n\n            serialClientOperationsLock.beginTrans(true);\n\n            try {\n                boolean rootInstrumented = false;\n                String excMessage = null;\n                int instrType = getCurrentInstrType();\n\n                if (instrType == INSTR_NONE) {\n                    return; // Instrumentation was turned off in the mean time\n                }\n\n                // bugfix for issue http://profiler.netbeans.org/issues/show_bug.cgi?id=65968\n                boolean resumeProfiling = false;\n\n                if (ThreadInfo.profilingSuspended()) {\n                    ThreadInfo.suspendProfiling();\n                    resumeProfiling = true;\n                }\n\n                try {\n                    if (rootClassLoaded) { // if yes, it means instrumentation has been started\n                                           // [ian] why the following if???\n\n                        if ((instrType != INSTR_RECURSIVE_FULL) && (instrType != INSTR_RECURSIVE_SAMPLED)\n                                && (instrType != INSTR_OBJECT_ALLOCATIONS) && (instrType != INSTR_OBJECT_LIVENESS)) {\n                            if (!((instrType == INSTR_CODE_REGION)\n                                    && className.equals(rootClassNames[ProfilingSessionStatus.CODE_REGION_CLASS_IDX]))) {\n                                return; // Nothing to do\n                            }\n                        }\n\n                        ThreadInfo ti = null;\n\n                        if ((instrType == INSTR_RECURSIVE_FULL) || (instrType == INSTR_RECURSIVE_SAMPLED)) {\n                            nClassLoads++;\n                            ti = ProfilerRuntimeCPU.suspendCurrentThreadTimer(); // start blackout period\n                            clientInstrStartTime = Timers.getCurrentTimeInCounts();\n                            // We'll be unable to call resumeCurrentThreadTimer() right here, since here we are holding serialClientOperationsLock.\n                            // The same lock is acquired when we dump the event buffer. So if here we call resumeTimer(), which calls writeEvent(),\n                            // we can get into a deadlock if some other thread at this time is dumping the event buffer and tries to acquire that lock.\n                            resumeTimer = true; // resume blackout period at the end\n                        }\n\n                        byte[] classFileBytes = getClassFileBytes(clazz, classLoaderId);\n                        // send request to tool to instrument the bytecode\n                        ClassLoadedCommand cmd = new ClassLoadedCommand(className,\n                                                                        ClassLoaderManager.getThisAndParentLoaderData(classLoaderId),\n                                                                        classFileBytes, (ti != null) ? ti.isInCallGraph() : false);\n                        profilerServer.sendComplexCmdToClient(cmd);\n\n                        // read response from tool that should contain the instrumented bytecode, and redefine the methods/classes\n                        if (!getAndInstrumentClasses(false)) {\n                            disableProfilerHooks();\n\n                            return;\n                        }\n                    } else {\n                        // in total inst scheme for CPU profiling we instrument everything\n                        boolean rootWasLoaded = ((instrType == INSTR_RECURSIVE_FULL) || (instrType == INSTR_RECURSIVE_SAMPLED))\n                                                && (status.instrScheme == INSTRSCHEME_TOTAL);\n\n                        // No root classes have been loaded - check if it's one of them\n                        if (!rootWasLoaded && !isRootClass(className)) {\n                            return;\n                        }\n\n                        // This is a root class - proceed with requesting client for instrumented code.\n                        nClassLoads++;\n                        clientInstrStartTime = Timers.getCurrentTimeInCounts();\n                        sendRootClassLoadedCommand(true);\n\n                        if (!getAndInstrumentClasses(true)) {\n                            disableProfilerHooks();\n\n                            return;\n                        }\n\n                        // Note: it is important to have 'rootClassLoaded = true' here, i.e. *after* (not before) the call to getAndInstrumentClasses().\n                        // It looks like some classes returned by getAllLoadedClasses() may be not completely initialized, and thus when we finally\n                        // load them properly in instrumentMethodGroup() before intrumenting, they get initialized and classLoadHook is called for each\n                        // of them. If rootClassLoaded is true, then for each such class a request is sent to the client, which wonders why it got a\n                        // second class load event for the same class. Having rootClassLoaded not set until all such classes are loaded eliminates this\n                        // issue. WARNING: may it happen that some really new class is loaded as a side effect of initializing of the classes described\n                        // above? If so, it will be effectively lost. Need to try to come up with a test to confirm or prove this worry wrong.\n                        rootInstrumented = true;\n                        rootClassLoaded = true;\n\n                        // This is done to avoid counting the time spent in instrumentation etc. upon root class load, but before our app (or actually\n                        // data recording) started. That's because we use this internal statistics to calculate/verify the gross run time of the app.\n                        ProfilerCalibrator.resetInternalStatsCollectors();\n                    }\n\n                    if (rootInstrumented || (excMessage != null)) {\n                        AsyncMessageCommand cmd = null;\n\n                        if (excMessage == null) {\n                            cmd = new AsyncMessageCommand(true, INSTRUMENTATION_SUCCESSFUL_MSG);\n                        } else {\n                            cmd = new AsyncMessageCommand(false, excMessage);\n                        }\n\n                        profilerServer.sendComplexCmdToClient(cmd);\n                    }\n                } finally {\n                    if (resumeProfiling) {\n                        ThreadInfo.resumeProfiling();\n                    }\n                }\n            } finally { // end of synchronized(serialClientOperationsLock)\n                serialClientOperationsLock.endTrans();\n            }\n\n            if (resumeTimer) {\n                int instrType = getCurrentInstrType();\n\n                if ((instrType == INSTR_RECURSIVE_FULL) || (instrType == INSTR_RECURSIVE_SAMPLED)) {\n                    ProfilerRuntimeCPU.resumeCurrentThreadTimer();\n                }\n            }\n        } finally {\n            threadInfo.inProfilingRuntimeMethod--;\n        }\n    }\n\n    private static void firstTimeMethodInvokeHook(char methodId) {\n        serialClientOperationsLock.beginTrans(true);\n\n        try {\n            int instrType = getCurrentInstrType();\n\n            if ((instrType != INSTR_RECURSIVE_FULL) && (instrType != INSTR_RECURSIVE_SAMPLED)) {\n                return; // Chances are that instrumentation is already stopped\n            }\n\n            clientInstrStartTime = Timers.getCurrentTimeInCounts();\n\n            MethodInvokedFirstTimeCommand cmd = new MethodInvokedFirstTimeCommand(methodId);\n            profilerServer.sendComplexCmdToClient(cmd);\n\n            if (!getAndInstrumentClasses(false)) {\n                disableProfilerHooks();\n\n                return;\n            }\n\n            // The following reset is done to avoid counting the time spent in instrumentation before data recording started.\n            if (nFirstMethodInvocations == 0) {\n                ProfilerCalibrator.resetInternalStatsCollectors();\n            }\n\n            nFirstMethodInvocations++;\n        } finally {\n            serialClientOperationsLock.endTrans();\n        }\n    }\n\n    private static int firstTimeVMObjectAlloc(String className, int definingClassLoaderId) {\n        GetClassIdResponse resp;\n\n        if (internalClassName(className)) {\n            return -1;\n        }\n        \n        serialClientOperationsLock.beginTrans(true);\n\n        try {\n            GetClassIdCommand cmd = new GetClassIdCommand(className, definingClassLoaderId);\n            profilerServer.sendComplexCmdToClient(cmd);\n            resp = (GetClassIdResponse) ProfilerServer.getLastResponse();\n        }  finally {\n            serialClientOperationsLock.endTrans();\n        }\n        if (resp.isOK()) {\n            int classId = resp.getClassId();\n            int instrClasses = classId+1;\n            if (instrClasses > status.getNInstrClasses()) {\n                status.updateAllocatedInstancesCountInfoInServer(instrClasses);\n                ProfilerRuntimeMemory.setAllocatedInstancesCountArray(status.getAllocatedInstancesCount());\n            }\n            return classId;\n        }\n        return -1;\n    }\n\n    private static void handleFakeInitRecursiveInstrumentationCommand() {\n        // Send a fake RootClassLoadedCommand to the client and get a reply from it. This is done to force initialization\n        // of all classes related to this operation. If this happens later, it can cause deadlock due to classLoadHook called upon\n        // loading of some of these classes, when classLoadHook is already locked to \"serialize\" class load events.\n        new HFIRIThread().start();\n    }\n\n    /**\n     *  support for multiple roots needed by EJB work\n     *  will check each class to see if it is a candidate to be a core class\n     */\n    private static boolean hasAnyCoreClassNames(String[] classes) {\n        if (!(classes.length > 0)) {\n            return false;\n        }\n\n        for (int i = 0; i < classes.length; i++) {\n            if (isCoreClassName(classes[i])) {\n                return true;\n            }\n        }\n\n        return false; //none found...\n    }\n\n    private static void instrumentMethodGroupNow(InstrumentMethodGroupData imgb)\n                                          throws Exception {\n        //divided into 2 parts: cass loading and class instrumenting\n        Monitors.DeterminateProgress wholeProgress = Monitors.enterServerState(CommonConstants.SERVER_INITIALIZING, 2);\n        try {\n            instrumentMethodGroupCallThread = Thread.currentThread();\n\n            int res = 0;\n            long time = Timers.getCurrentTimeInCounts();\n            nNonEmptyInstrMethodGroupResponses++;\n\n            int nClasses = imgb.getNClasses();\n            String[] instrClassNames = imgb.getMethodClasses();\n            int[] instrClassLoaders = imgb.getClassLoaderIds();\n            int nMethods = imgb.getNMethods();\n\n            Class[] clazzes = new Class[nClasses];\n            byte[][] b = imgb.getReplacementClassFileBytes();\n            int k = 0;\n\n            Monitors.DeterminateProgress progress = Monitors.enterServerState(CommonConstants.SERVER_PREPARING, nClasses);\n            try {\n                for (int i = 0; i < nClasses; i++) {\n                    progress.next();\n                    clazzes[k] = ClassLoaderManager.getLoadedClass(instrClassNames[i], instrClassLoaders[i]);\n\n                    if (clazzes[k] != null) {\n                        if (b[k] == null) {\n                            // An optimization to avoid overhead of creating and sending original class file bytes from client\n                            // to server\n                            if (instrClassLoaders[i] == 0) {\n                                b[k] = ClassBytesLoader.getClassFileBytes(instrClassNames[i]);\n                            }\n                            if (b[k] == null) {\n                                b[k] = getCachedClassFileBytes(clazzes[k]);\n                            }\n                        }\n\n                        k++;\n                    } else {\n                        reportUnloadedClass(instrClassNames[i]);\n\n                        int classesToMove = nClasses - k - 1;\n                        System.arraycopy(clazzes, k + 1, clazzes, k, classesToMove);\n                        System.arraycopy(b, k + 1, b, k, classesToMove);\n                    }\n                }\n\n                if (k < nClasses) {\n                    Class[] oldClazzes = clazzes;\n                    clazzes = new Class[k];\n                    System.arraycopy(oldClazzes, 0, clazzes, 0, k);\n                }\n            } finally {\n                progress = null;\n                Monitors.exitServerState();                \n            }\n            \n            wholeProgress.next();\n\n            redefineClasses(clazzes, imgb.getReplacementClassFileBytes());\n\n            time = Timers.getCurrentTimeInCounts() - time;\n            totalHotswappingTime += time;\n\n            if (time < minHotswappingTime) {\n                minHotswappingTime = time;\n            } else if (time > maxHotswappingTime) {\n                maxHotswappingTime = time;\n            }\n\n            instrumentMethodGroupCallThread = null;\n        } catch (Throwable t) {\n            if (t instanceof Classes.RedefineException) {\n                int nClasses = imgb.getNClasses();\n                String[] instrClassNames = imgb.getMethodClasses();\n                System.err.println(\"Profiler Agent Error: Redefinition failed for classes:\"); // NOI18N\n\n                for (int i = 0; i < nClasses; i++) {\n                    System.err.println(instrClassNames[i]);\n                }\n\n                System.err.println(\"Profiler Agent Error: with message: \" + ((Classes.RedefineException) t).getMessage()); // NOI18N\n\n                byte[][] newBytes = imgb.getReplacementClassFileBytes();\n\n                for (int i = 0; i < nClasses; i++) {\n                    String name = instrClassNames[i];\n                    File outFile = new File(name + \".class\"); // NOI18N\n                    System.err.println(\"Debug: writing class file: \" + name + \", into file: \" + outFile.getPath()); // NOI18N\n\n                    try {\n                        FileOutputStream fos = new FileOutputStream(outFile);\n                        fos.write(newBytes[i]);\n                        fos.close();\n                    } catch (IOException exc) {\n                        System.err.println(\"error: \" + exc + \" writing class file: \" + outFile.getPath()); // NOI18N\n                    }\n                }\n\n                throw ((Classes.RedefineException) t);\n            } else {\n                java.io.StringWriter sw = new java.io.StringWriter();\n                java.io.PrintWriter pw = new java.io.PrintWriter(sw);\n                t.printStackTrace(pw);\n                throw new Exception(MessageFormat.format(UNEXPECTED_EXCEPTION_MSG, new Object[] { t, sw.toString() }));\n            }\n        } finally {\n            instrumentMethodGroupCallThread = null;            \n            Monitors.exitServerState();\n        }\n    }\n\n    private static void redefineClasses(Class[] classes, byte[][] bytecode) throws Classes.RedefineException {\n        Monitors.DeterminateProgress progress = Monitors.enterServerState(CommonConstants.SERVER_INSTRUMENTING, \n                                                        (classes.length+REDEFINE_CHUNK_SIZE-1)/REDEFINE_CHUNK_SIZE);\n        try {\n            int index = 0;\n            Class[] chunkClasses = null;\n            byte[][] chunkBytecode = null;\n            while(index < classes.length) {\n                int size = Math.min(classes.length - index, REDEFINE_CHUNK_SIZE);\n                if(chunkClasses == null || chunkClasses.length != size ) {\n                    chunkClasses = new Class[size];\n                    chunkBytecode = new byte[size][];\n                }\n                System.arraycopy(classes, index, chunkClasses, 0, size);\n                System.arraycopy(bytecode, index, chunkBytecode, 0, size);\n                Classes.redefineClasses(chunkClasses, chunkBytecode);\n                progress.next();\n                index += size;\n            }            \n        } finally {\n            Monitors.exitServerState();\n        }\n    }\n\n    private static boolean internalClassName(String name) {\n        return (serverInternalClassName(name)\n               || // WARNING: sun.reflect.* are not really internal classes, but they may create too many problems by being loaded unexpectedly\n        // by our internal code and causing classLoadHook to be invoked recursively. At least we need sun.reflect.Generated* to be\n        // dismissed. Others could probably be less of a problem if ClassLoaderManager didn't use reflection.\n        (name.startsWith(\"sun.reflect.\") && !name.startsWith(\"sun.reflect.GeneratedSerializationConstructorAccessor\")\n                  && !name.startsWith(\"sun.reflect.GeneratedConstructorAccessor\")) // NOI18N\n               || name.startsWith(\"sun.instrument.\") // NOI18N\n                                                     // FIXME: below is a (hopefully temporary) fix to the strange problem showing up as ClassCircularityError when\n                                                     // we try to profile PetStore with eager instrumentation scheme on Sun ONE AS 7. This makes the problem go away,\n                                                     // but its root cause is still unclear to me.\n               || name.equals(\"com.sun.enterprise.J2EESecurityManager\") // NOI18N\n               // do not instrument classes created by Unsafe.defineAnonymousClass() \n               || name.contains(\"/\") // NOI18N   \n        );\n    }\n\n    static boolean serverInternalClassName(String name) {\n        if (INSTRUMENT_JFLUID_CLASSES) {\n            return name.startsWith(\"org.graalvm.visualvm.lib.jfluid.server\") || // NOI18N\n                   name.startsWith(\"org.graalvm.visualvm.lib.jfluid.global\") || // NOI18N\n                   name.startsWith(\"org.graalvm.visualvm.lib.jfluid.wireprotocol\"); // NOI18N\n        } else {\n            return name.startsWith(PROFILER_DOTTED_CLASS_PREFIX);\n        }\n    }\n\n    private static void reflectiveMethodInvokeHook(Method method) {\n        serialClientOperationsLock.beginTrans(true);\n\n        try {\n            if (reflectMethods.containsKey(method)) {\n                return;\n            }\n\n            ProfilerRuntimeCPU.suspendCurrentThreadTimer();\n\n            reflectMethods.put(method, null);\n\n            Class clazz = method.getDeclaringClass();\n            String className = clazz.getName();\n            String methodName = method.getName();\n            Class[] paramTypes = method.getParameterTypes();\n            StringBuffer sb = new StringBuffer();\n            sb.append('(');\n\n            for (int i = 0; i < paramTypes.length; i++) {\n                appendTypeName(sb, paramTypes[i]);\n            }\n\n            sb.append(')');\n            appendTypeName(sb, method.getReturnType());\n\n            String methodSignature = sb.toString();\n\n            clientInstrStartTime = Timers.getCurrentTimeInCounts();\n\n            MethodLoadedCommand cmd = new MethodLoadedCommand(className, ClassLoaderManager.registerLoader(clazz), methodName,\n                                                              methodSignature);\n            profilerServer.sendComplexCmdToClient(cmd);\n\n            if (!getAndInstrumentClasses(false)) {\n                disableProfilerHooks();\n\n                return;\n            }\n\n            ProfilerRuntimeCPU.resumeCurrentThreadTimer();\n        } finally {\n            serialClientOperationsLock.endTrans();\n        }\n    }\n\n    private static void reportUnloadedClass(String className) {\n        System.err.println(ENGINE_WARNING + \"target VM cannot load class to instrument \" + className); // NOI18N\n        System.err.println(\"*** probably it has been unloaded recently\"); // NOI18N\n    }\n\n    private static void reportCacheMiss(final byte[] bytes, final Class clazz) {\n        if (bytes == null) {\n            System.err.println(ENGINE_WARNING + \"Failed to lookup cached class \" + clazz.getName()); // NOI18N\n        }\n    }\n    \n    private static byte[] getCachedClassFileBytes(Class clazz) {\n        byte[] bytes = Classes.getCachedClassFileBytes(clazz);\n        reportCacheMiss(bytes, clazz);\n        return bytes;\n    }\n\n    private static void cacheLoadedClass(Class clazz) {\n        Class[] classes = new Class[2];\n        classes[0] = clazz;\n        cacheLoadedClasses(classes,1);\n    }\n    \n    private static void cacheLoadedClasses(Class[] nonSystemClasses, int nonSystemIndex) {\n        if (DEBUG) System.out.println(\"Caching \"+nonSystemIndex+\" classes\");\n        nonSystemClasses[nonSystemIndex++] = ProfilerInterface.InitiateProfilingThread.class;\n        Classes.cacheLoadedClasses(nonSystemClasses,nonSystemIndex);\n    }\n\n    /* Get class file bytes if they are available, i.e. if the class is loaded by a custom classloader\n    * If remote profiling is used, get these class file bytes from system classpath\n    * classLoaderId = 0 means that it is a system or bootstrap classloader\n    */\n    private static byte[] getClassFileBytes(Class clazz, int classLoaderId) {\n        return getClassFileBytes(clazz, classLoaderId, true);\n    }\n\n    private static byte[] getClassFileBytes(Class clazz, int classLoaderId, boolean force) {\n        byte[] classFileBytes = null;\n        URL classURL = null;\n        \n        if (classLoaderId > 0 || (classURL = ClassBytesLoader.getClassFileURL(clazz.getName())) == null) {\n            classFileBytes = Classes.getCachedClassFileBytes(clazz);\n            if (classFileBytes == null) {\n                if (DEBUG) {\n                    System.err.println(\"Cannot get classbytes for \"+clazz.getName()+\" loader \"+classLoaderId);\n                }\n                if (!force) return EMPTY;\n                cacheLoadedClass(clazz);\n                classFileBytes = getCachedClassFileBytes(clazz);\n                if (classFileBytes == null) {\n                    if (Platform.getJDKVersionNumber() != Platform.JDK_CVM) {\n                        System.err.println(\"***Profiler agent warning: could not get .class file for a synthetic class \" + clazz.getName()\n                                           + \" in ProfilerInterface.getClassFileBytes\"); // NOI18N\n                    }\n                }\n            }\n        } else if (status.remoteProfiling || Platform.getJDKVersionNumber() >= Platform.JDK_19) {\n            classFileBytes = ClassBytesLoader.getClassFileBytes(classURL);\n        }\n        return classFileBytes;\n    }\n    \n    private static void sendRootClassLoadedCommand(boolean doGetLoadedClasses) {\n        if (doGetLoadedClasses) {\n            getLoadedClasses(); // Otherwise we know loadedClassesArray has already been initialized\n        }\n\n        int len = loadedClassesArray.length;\n        String[] loadedClassNames = new String[len];\n        int[] loaders = new int[len];\n        byte[][] cachedClassFileBytes = new byte[len][];\n        int[] loadedClassesSuper = new int[len];\n        int[][] loadedClassesInterfaces = new int[len][];\n        int instrType = getCurrentInstrType();\n        boolean isLazyInstrType = profilerServer.isDynamic()\n                && (instrType == INSTR_RECURSIVE_FULL || instrType == INSTR_RECURSIVE_SAMPLED)\n                && status.instrScheme == INSTRSCHEME_LAZY \n                && !instrSpawnedThreads;\n        boolean isMemoryProfiling = profilerServer.isDynamic()\n                && (instrType == INSTR_OBJECT_ALLOCATIONS || instrType == INSTR_OBJECT_LIVENESS);\n        Map classIndex = new HashMap(loadedClassesArray.length*4/3);\n        Class[] classesArray = new Class[len];\n\n        for (int i = 0; i < len; i++) {\n            Class clazz = getOrdinaryClass(loadedClassesArray[i]);\n            if (clazz == null) {\n                // class was unloaded or has special name\n                continue;\n            }\n            int index = classIndex.size();\n            classesArray[index] = clazz;\n            loaders[index] = loadedClassesLoaders[i];\n            classIndex.put(clazz, new Integer(index));\n        }\n        for (int i = 0; i < classIndex.size(); i++) {\n            Class clazz = classesArray[i];\n            String name = clazz.getName();\n            boolean forceClassFile = (!isLazyInstrType && !isMemoryProfiling) || isRootClass(name);\n            loadedClassNames[i] = name;\n            cachedClassFileBytes[i] = getClassFileBytes(clazz, loaders[i], forceClassFile);\n\n            if (!forceClassFile) {\n                Class superClass = clazz.getSuperclass();\n                Class[] interfaces = clazz.getInterfaces();\n                \n                if (superClass != null) {\n                    Integer clsId = (Integer) classIndex.get(superClass);\n                    if (clsId != null) {\n                        loadedClassesSuper[i] = clsId.intValue();\n                    } else {\n                        //System.out.println(\"Super class of class \"+name+\" not found: \"+superClass.getName());\n                        loadedClassesSuper[i] = -1;\n                    }\n                } else {\n                    loadedClassesSuper[i] = -1;\n                }\n                loadedClassesInterfaces[i] = new int[interfaces.length];\n                for (int j = 0; j < interfaces.length; j++) {\n                    Integer clsId = (Integer)classIndex.get(interfaces[j]);\n                    if (clsId != null) {\n                        loadedClassesInterfaces[i][j] = clsId.intValue();\n                    } else {\n                        //System.out.println(\"Interface of class \"+name+\" not found: \"+interfaces[j].getName());\n                        loadedClassesSuper[i] = -1;\n                    }\n                }\n            }\n        }\n        RootClassLoadedCommand cmd = new RootClassLoadedCommand(loadedClassNames, loaders, cachedClassFileBytes, \n                                                loadedClassesSuper, loadedClassesInterfaces, classIndex.size(),\n                                                ClassLoaderManager.getParentLoaderIdTable());\n        profilerServer.sendComplexCmdToClient(cmd);\n    }\n\n    private static Class getOrdinaryClass(WeakReference classRef) {\n        Class clazz = (Class) classRef.get();\n        if (clazz != null) {\n            String name = clazz.getName();\n\n            if (!name.startsWith(\"[\") && !internalClassName(name)) {\n                return clazz;\n            }             \n        }\n        return null;\n    }\n    \n    private static void updateInstrClassAndMethodNames(InstrumentMethodGroupData imgb, boolean firstTime) {\n        status.beginTrans(false);\n\n        try {\n            switch (getCurrentInstrType()) {\n                case INSTR_RECURSIVE_FULL:\n                case INSTR_RECURSIVE_SAMPLED:\n                    status.updateInstrMethodsInfo(imgb.getNClasses(), imgb.getNMethods(), null, null, null, null, null,\n                                                  imgb.getInstrMethodLeaf());\n                    ProfilerRuntimeCPU.setInstrMethodsInvoked(status.getInstrMethodInvoked());\n\n                    break;\n                case INSTR_OBJECT_ALLOCATIONS:\n                case INSTR_OBJECT_LIVENESS:\n                    status.updateAllocatedInstancesCountInfoInServer(imgb.getAddInfo());\n                    ProfilerRuntimeMemory.setAllocatedInstancesCountArray(status.getAllocatedInstancesCount());\n\n                    break;\n            }\n        } finally {\n            status.endTrans();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntime.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport java.lang.reflect.Method;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Classes;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Histogram;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Timers;\n\n/**\n * This is a base class, containing common functionality for classes that contain instrumentation methods.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class ProfilerRuntime implements CommonConstants {\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    // ------------- Handling operations that should be performed outside ProfilerRuntime --------------\n    public static interface ExternalActionsHandler {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void handleEventBufferDump(byte[] eventBuffer, int startPos, int curPtrPos);\n\n        public void handleFirstTimeMethodInvoke(char methodId);\n\n        public int handleFirstTimeVMObjectAlloc(String className, int definingClassLoaderId);\n\n        public void handleReflectiveInvoke(Method method);\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final boolean DEBUG = false;\n    protected static ExternalActionsHandler externalActionsHandler;\n    protected static boolean lockContentionMonitoringEnabled;\n\n    // ---------------------------------- Writing profiler events --------------------------------------\n    protected static byte[] eventBuffer;\n    protected static int globalEvBufPos;\n    protected static int globalEvBufPosThreshold;\n    protected static volatile boolean sendingBuffer;\n    private static boolean printEvents; // For debugging\n    private volatile static Set knownMonitors;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void createEventBuffer(int bufSize) {\n        eventBuffer = new byte[bufSize];\n        globalEvBufPosThreshold = bufSize - (3 * ThreadInfo.MAX_EVENT_SIZE) - 1;\n        globalEvBufPos = 0;\n    }\n\n    // Asynchronous event buffer dump\n    public static void dumpEventBuffer() {\n        if (eventBuffer == null) {\n            return; // Just in case somebody calls it with null eventBuffer\n        }\n\n        if (sendingBuffer) {\n            return; // No need (and may cause a deadlock in tool) if forced dump is requested while\n                    // a routine dump is already in progress\n        }\n\n        synchronized (eventBuffer) {\n            sendingBuffer = true;\n\n            // Dump the info from all thread-local buffers (if they are not null) into the global buffer\n            ThreadInfo[] tis = ThreadInfo.getThreadInfos();\n\n            for (int i = 0; i < tis.length; i++) {\n                ThreadInfo ti = tis[i];\n\n                if ((ti == null) || (ti.evBuf == null) || !ti.isInitialized()) {\n                    continue;\n                }\n\n                int curPos = ti.evBufPos; // Guaranteed to be at event boundary\n\n                if (((globalEvBufPos + curPos) - ti.evBufDumpLastPos) > globalEvBufPosThreshold) {\n                    break; // We don't try to perform more than one global buffer dumps yet\n                }\n\n                int evBufSize = curPos - ti.evBufDumpLastPos;\n\n                if (evBufSize > 0) {\n                    eventBuffer[globalEvBufPos++] = SET_FOLLOWING_EVENTS_THREAD;\n                    eventBuffer[globalEvBufPos++] = (byte) ((ti.threadId >> 8) & 0xFF);\n                    eventBuffer[globalEvBufPos++] = (byte) (ti.threadId & 0xFF);\n                    System.arraycopy(ti.evBuf, ti.evBufDumpLastPos, eventBuffer, globalEvBufPos, evBufSize);\n                    globalEvBufPos += evBufSize;\n                    ti.evBufDumpLastPos = curPos;\n                }\n            }\n\n            externalActionsHandler.handleEventBufferDump(eventBuffer, 0, globalEvBufPos);\n            globalEvBufPos = 0;\n            sendingBuffer = false;\n        }\n    }\n\n    protected static void copyLocalBuffer(ThreadInfo ti) {\n        long absTimeStamp = 0;\n        long threadTimeStamp = 0;\n\n        // Copy the local buffer into the main buffer - however avoid doing that if we have already reset profiler collectors\n        if (eventBuffer == null) {\n            return;\n        }\n\n        boolean needToAdjustTime = false;\n\n        if (sendingBuffer) { // Some other thread is already sending the buffer contents\n            absTimeStamp = Timers.getCurrentTimeInCounts();\n            if (ProfilerRuntimeCPU.threadCPUTimerOn) threadTimeStamp = Timers.getThreadCPUTimeInNanos();\n\n            synchronized (eventBuffer) { // Wait on the lock. When it's free, buffer has been sent and reset\n\n                if (sendingBuffer) {\n                    System.err.println(\"*** Sanity check failed - sendingBuffer where should have been already sent\"); // NOI18N\n                }\n\n                needToAdjustTime = true;\n            }\n        }\n\n        synchronized (eventBuffer) {\n            if (!ti.isInitialized()) {\n                return; // Reset collectors performed when we were already executing instrumentation code\n            }\n\n            int curPos = ti.evBufPos;\n\n            // First check if the global buffer itself needs to be dumped\n            int evBufDumpLastPos = ti.evBufDumpLastPos;\n\n            if (((globalEvBufPos + curPos) - evBufDumpLastPos) > globalEvBufPosThreshold) {\n                sendingBuffer = true;\n\n                if (!needToAdjustTime) {\n                    absTimeStamp = Timers.getCurrentTimeInCounts();\n                    if (ProfilerRuntimeCPU.threadCPUTimerOn) threadTimeStamp = Timers.getThreadCPUTimeInNanos();\n                    needToAdjustTime = true;\n                }\n\n                externalActionsHandler.handleEventBufferDump(eventBuffer, 0, globalEvBufPos);\n                globalEvBufPos = 0;\n                sendingBuffer = false;\n            }\n            \n            // check that we still have valid eventBuffer\n            if (eventBuffer != null) {\n                // Finally copy the local buffer into the global one\n                eventBuffer[globalEvBufPos++] = SET_FOLLOWING_EVENTS_THREAD;\n                eventBuffer[globalEvBufPos++] = (byte) ((ti.threadId >> 8) & 0xFF);\n                eventBuffer[globalEvBufPos++] = (byte) ((ti.threadId) & 0xFF);\n                System.arraycopy(ti.evBuf, evBufDumpLastPos, eventBuffer, globalEvBufPos, curPos - evBufDumpLastPos);\n                globalEvBufPos += (curPos - evBufDumpLastPos);\n                ti.evBufPos = 0;\n                ti.evBufDumpLastPos = 0;\n\n                // Now, if we previously spent time waiting for another thread to dump the global buffer, or doing that\n                // ourselves, write the ADJUST_TIME event into the local buffer\n                if (needToAdjustTime) {\n                    writeAdjustTimeEvent(ti, absTimeStamp, threadTimeStamp);\n                }\n            }\n        }\n    }\n\n    public static void init(ExternalActionsHandler h) {\n        externalActionsHandler = h;\n    }\n\n    public static void setLockContentionMonitoringEnabled(boolean b) {\n        lockContentionMonitoringEnabled = b;\n        knownMonitors = b ? new HashSet() : null;\n        Classes.setLockContentionMonitoringEnabled(b);\n        if (DEBUG) {\n            System.out.println(\"ProfilerRuntime.DEBUG: setLockContentionMonitoringEnabled \"+b);\n        }\n    }\n\n    // ------------- Handling wait/sleep/monitors entry/exit -------------------------------------------\n    public static void monitorEntry(Thread t, Object monitor, Thread owner) {\n        if (ThreadInfo.profilingSuspended() || ThreadInfo.isProfilerServerThread(t)\n            || ThreadInfo.isProfilerServerMonitor(monitor)) {\n            // nothing done for profiler own threads or if in instrumentation\n            return;\n        }\n        long timeStamp = -1;\n        ThreadInfo ti = ThreadInfo.getThreadInfo(t);\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n        ti.inProfilingRuntimeMethod++;\n\n        ProfilingSessionStatus status = ProfilerServer.getProfilingSessionStatus();\n        ThreadInfo ownerTi = owner != null ? ThreadInfo.getThreadInfo(owner) : null;\n\n        if (status != null) {\n            switch (status.currentInstrType) {\n                case INSTR_RECURSIVE_FULL:\n                case INSTR_RECURSIVE_SAMPLED:\n                    timeStamp = ProfilerRuntimeCPU.monitorEntryCPU(ti, monitor, ownerTi);\n\n                    break;\n                case INSTR_CODE_REGION:\n                    timeStamp = ProfilerRuntimeCPUCodeRegion.monitorEntryRegion(t, monitor, ownerTi);\n\n                    break;\n            }\n        }\n        if (lockContentionMonitoringEnabled && timeStamp == -1) {\n            writeWaitTimeEvent(METHOD_ENTRY_MONITOR, ti, monitor, ownerTi);\n        }\n\n        Monitors.recordThreadStateChange(ti.thread, THREAD_STATUS_MONITOR, timeStamp, monitor);\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    public static void monitorExit(Thread t, Object monitor) {\n        if (ThreadInfo.profilingSuspended() || ThreadInfo.isProfilerServerThread(t)\n            || ThreadInfo.isProfilerServerMonitor(monitor)) {\n            // nothing done for profiler own threads or if in instrumentation\n            return;\n        }\n        long timeStamp = -1;\n        ThreadInfo ti = ThreadInfo.getThreadInfo(t);\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n        ti.inProfilingRuntimeMethod++;\n\n        ProfilingSessionStatus status = ProfilerServer.getProfilingSessionStatus();\n\n        if (status != null) {\n            switch (status.currentInstrType) {\n                case INSTR_RECURSIVE_FULL:\n                case INSTR_RECURSIVE_SAMPLED:\n                    timeStamp = ProfilerRuntimeCPU.monitorExitCPU(ti, monitor);\n\n                    break;\n                case INSTR_CODE_REGION:\n                    timeStamp = ProfilerRuntimeCPUCodeRegion.monitorExitRegion(t, monitor);\n\n                    break;\n            }\n        }\n        if (lockContentionMonitoringEnabled && timeStamp == -1) {\n            writeWaitTimeEvent(METHOD_EXIT_MONITOR, ti, monitor);\n        }\n\n        Monitors.recordThreadStateChange(ti.thread, THREAD_STATUS_RUNNING, timeStamp, null);\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    public static void sleepEntry() {\n        if (ThreadInfo.profilingSuspended() || ThreadInfo.isCurrentThreadProfilerServerThread()) {\n            // nothing done for profiler own threads or if in instrumentation\n            return;\n        }\n        long timeStamp = -1;\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n        ti.inProfilingRuntimeMethod++;\n\n        ProfilingSessionStatus status = ProfilerServer.getProfilingSessionStatus();\n\n        if (status != null) {\n            switch (status.currentInstrType) {\n                case INSTR_RECURSIVE_FULL:\n                case INSTR_RECURSIVE_SAMPLED:\n                    timeStamp = ProfilerRuntimeCPU.sleepEntryCPU(ti);\n\n                    break;\n                case INSTR_CODE_REGION:\n                    ProfilerRuntimeCPUCodeRegion.sleepEntryRegion();\n\n                    break;\n            }\n        }\n\n        Monitors.recordThreadStateChange(ti.thread, THREAD_STATUS_SLEEPING, timeStamp, null);\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    public static void sleepExit() {\n        if (ThreadInfo.profilingSuspended() || ThreadInfo.isCurrentThreadProfilerServerThread()) {\n            // nothing done for profiler own threads or if in instrumentation\n            return;\n        }\n        long timeStamp = -1;\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n        ti.inProfilingRuntimeMethod++;\n\n        ProfilingSessionStatus status = ProfilerServer.getProfilingSessionStatus();\n\n        if (status != null) {\n            switch (status.currentInstrType) {\n                case INSTR_RECURSIVE_FULL:\n                case INSTR_RECURSIVE_SAMPLED:\n                    timeStamp = ProfilerRuntimeCPU.sleepExitCPU(ti);\n\n                    break;\n                case INSTR_CODE_REGION:\n                    ProfilerRuntimeCPUCodeRegion.sleepExitRegion();\n\n                    break;\n            }\n        }\n\n        Monitors.recordThreadStateChange(ti.thread, THREAD_STATUS_RUNNING, timeStamp, null);\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    public static void waitEntry() {\n        if (ThreadInfo.profilingSuspended() || ThreadInfo.isCurrentThreadProfilerServerThread()) {\n            // nothing done for profiler own threads or if in instrumentation\n            return;\n        }\n        long timeStamp = -1;\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n        ti.inProfilingRuntimeMethod++;\n\n        ProfilingSessionStatus status = ProfilerServer.getProfilingSessionStatus();\n\n        if (status != null) {\n            switch (status.currentInstrType) {\n                case INSTR_RECURSIVE_FULL:\n                case INSTR_RECURSIVE_SAMPLED:\n                    timeStamp = ProfilerRuntimeCPU.waitEntryCPU(ti);\n\n                    break;\n                case INSTR_CODE_REGION:\n                    ProfilerRuntimeCPUCodeRegion.waitEntryRegion();\n\n                    break;\n            }\n        }\n\n        Monitors.recordThreadStateChange(ti.thread, THREAD_STATUS_WAIT, timeStamp, null);\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    public static void waitExit() {\n        if (ThreadInfo.profilingSuspended() || ThreadInfo.isCurrentThreadProfilerServerThread()) {\n            // nothing done for profiler own threads or if in instrumentation\n            return;\n        }\n        long timeStamp = -1;\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n        ti.inProfilingRuntimeMethod++;\n\n        ProfilingSessionStatus status = ProfilerServer.getProfilingSessionStatus();\n\n        if (status != null) {\n            switch (status.currentInstrType) {\n                case INSTR_RECURSIVE_FULL:\n                case INSTR_RECURSIVE_SAMPLED:\n                    timeStamp = ProfilerRuntimeCPU.waitExitCPU(ti);\n\n                    break;\n                case INSTR_CODE_REGION:\n                    ProfilerRuntimeCPUCodeRegion.waitExitRegion();\n\n                    break;\n            }\n        }\n\n        Monitors.recordThreadStateChange(ti.thread, THREAD_STATUS_RUNNING, timeStamp, null);\n        ti.inProfilingRuntimeMethod--;\n    }\n    \n    public static void parkEntry() {\n        if (ThreadInfo.profilingSuspended() || ThreadInfo.isCurrentThreadProfilerServerThread()) {\n            // nothing done for profiler own threads or if in instrumentation\n            return;\n        }\n        long timeStamp = -1;\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n        ti.inProfilingRuntimeMethod++;\n\n        ProfilingSessionStatus status = ProfilerServer.getProfilingSessionStatus();\n\n        if (status != null) {\n            switch (status.currentInstrType) {\n                case INSTR_RECURSIVE_FULL:\n                case INSTR_RECURSIVE_SAMPLED:\n                    timeStamp = ProfilerRuntimeCPU.parkEntryCPU(ti);\n\n                    break;\n                case INSTR_CODE_REGION:\n                    ProfilerRuntimeCPUCodeRegion.parkEntryRegion();\n\n                    break;\n            }\n        }\n\n        Monitors.recordThreadStateChange(ti.thread, THREAD_STATUS_PARK, timeStamp, null);\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    public static void parkExit() {\n        if (ThreadInfo.profilingSuspended() || ThreadInfo.isCurrentThreadProfilerServerThread()) {\n            // nothing done for profiler own threads or if in instrumentation\n            return;\n        }\n        long timeStamp = -1;\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n        ti.inProfilingRuntimeMethod++;\n\n        ProfilingSessionStatus status = ProfilerServer.getProfilingSessionStatus();\n\n        if (status != null) {\n            switch (status.currentInstrType) {\n                case INSTR_RECURSIVE_FULL:\n                case INSTR_RECURSIVE_SAMPLED:\n                    timeStamp = ProfilerRuntimeCPU.parkExitCPU(ti);\n\n                    break;\n                case INSTR_CODE_REGION:\n                    ProfilerRuntimeCPUCodeRegion.parkExitRegion();\n\n                    break;\n            }\n        }\n\n        Monitors.recordThreadStateChange(ti.thread, THREAD_STATUS_RUNNING, timeStamp, null);\n        ti.inProfilingRuntimeMethod--;\n    }\n    \n    // ------------------------------ Common setup functionality ---------------------------------------\n    public static void resetProfilerCollectors(int instrType) {\n        if ((instrType != INSTR_CODE_REGION) && (eventBuffer != null)) {\n            synchronized (eventBuffer) {\n                doResetProfilerCollectors(instrType);\n            }\n        } else {\n            doResetProfilerCollectors(instrType);\n        }\n    }\n\n    public static void writeProfilingPointHitEvent(int id, long absTimeStamp) {\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n        int tid = ti.threadId;\n\n        if (ti.evBuf == null || !ti.isInitialized()) { // memory profiling or ThreadInfo is not initialized -> use global event buffer\n\n            synchronized (eventBuffer) {\n                int curPos = globalEvBufPos;\n\n                if (curPos > globalEvBufPosThreshold) { // Dump the buffer\n                    dumpEventBuffer();\n                    curPos = 0;\n                }\n\n                curPos = writePPointHitToBuffer(eventBuffer, absTimeStamp, curPos, id, tid);\n                globalEvBufPos = curPos;\n            }\n        } else { // CPU profiling write to thread event buffer\n\n            int curPos = ti.evBufPos; // It's important to use a local copy for evBufPos, so that evBufPos is at event boundary at any moment\n\n            if (curPos > ThreadInfo.evBufPosThreshold) {\n                ProfilerRuntimeCPU.copyLocalBuffer(ti); // ugly I know :-( \n                curPos = ti.evBufPos;\n            }\n\n            byte[] evBuf = ti.evBuf;\n            ti.evBufPos = writePPointHitToBuffer(evBuf, absTimeStamp, curPos, id, tid);\n        }\n    }\n\n    public static void profilePointHit(char id) {\n        if (ThreadInfo.profilingSuspended() || ThreadInfo.isCurrentThreadProfilerServerThread()) {\n            return;\n        }\n\n        if (eventBuffer == null) {\n            return; // Instrumentation removal happened when we were in instrumentation\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        ti.inProfilingRuntimeMethod++;\n\n        ProfilingPointServerHandler method = ProfilingPointServerHandler.getHandler(id);\n        if (method != null) {\n            try {\n                method.profilingPointHit(id);\n            } catch (Exception e) {\n                e.printStackTrace(System.err);\n            }\n        }\n\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    static void writeThreadCreationEvent(ThreadInfo ti) {\n        writeThreadCreationEvent(ti.thread, ti.getThreadId());\n    }\n\n    protected static void writeThreadCreationEvent(Thread thread, int threadId) {\n        String threadName;\n        String threadClassName = thread.getClass().getName();\n        int fullInfoLen;\n        \n        try {\n            threadName = thread.getName();\n            if (threadName.length() == 0) {\n                threadName = thread.toString();\n            }\n        } catch (NullPointerException e) {\n            threadName = \"*Unknown thread (\"+threadId+\")*\";  // NOI18N\n        }\n        fullInfoLen = ((threadName.length() + threadClassName.length()) * 2) + 7;\n        synchronized (eventBuffer) {\n            if ((globalEvBufPos + fullInfoLen) > globalEvBufPosThreshold) {\n                sendingBuffer = true;\n                externalActionsHandler.handleEventBufferDump(eventBuffer, 0, globalEvBufPos);\n                globalEvBufPos = 0;\n                sendingBuffer = false;\n            }\n\n            eventBuffer[globalEvBufPos++] = NEW_THREAD;\n\n            eventBuffer[globalEvBufPos++] = (byte) ((threadId >> 8) & 0xFF);\n            eventBuffer[globalEvBufPos++] = (byte) ((threadId) & 0xFF);\n\n            byte[] name = threadName.getBytes();\n            int len = name.length;\n            eventBuffer[globalEvBufPos++] = (byte) ((len >> 8) & 0xFF);\n            eventBuffer[globalEvBufPos++] = (byte) ((len) & 0xFF);\n            System.arraycopy(name, 0, eventBuffer, globalEvBufPos, len);\n            globalEvBufPos += len;\n            name = threadClassName.getBytes();\n            len = name.length;\n            eventBuffer[globalEvBufPos++] = (byte) ((len >> 8) & 0xFF);\n            eventBuffer[globalEvBufPos++] = (byte) ((len) & 0xFF);\n            System.arraycopy(name, 0, eventBuffer, globalEvBufPos, len);\n            globalEvBufPos += len;\n        }\n    }\n    \n    static void writeAdjustTimeEvent(ThreadInfo ti, long absTimeStamp, long threadTimeStamp) {\n        //if (printEvents) System.out.println(\"*** Writing ADJUST_TIME event, metodId = \" + (int)methodId + \", ts = \" + timeStamp);\n        byte[] evBuf = ti.evBuf;\n        int curPos = ti.evBufPos; // It's important to use a local copy for evBufPos, so that evBufPos is at event boundary at any moment\n\n        // Check if the local buffer is about to overflow. We initially didn't have this code here, assuming that writeAdjustTimeEvent()\n        // cannot be called more than 1-2 times in a row. However, later we recognized that actually a large number of this calls can be\n        // made sequentially by classLoadHook() if many classes are loaded in a row. So we need to perform all checks for overflow;\n        // however we take some advantage of the fact that we don't need to take intermediate time stamps etc.\n        if (curPos > ThreadInfo.evBufPosThreshold) {\n            // Copy the local buffer into the main buffer - however avoid doing that if we have already reset profiler collectors\n            if (eventBuffer == null) {\n                return;\n            }\n\n            synchronized (eventBuffer) {\n                curPos = ti.evBufPos;\n\n                boolean globalBufNeedsDump = false;\n\n                // First check if the global buffer itself needs to be dumped\n                int evBufDumpLastPos = ti.evBufDumpLastPos;\n\n                if (((globalEvBufPos + curPos) - evBufDumpLastPos) > globalEvBufPosThreshold) {\n                    globalBufNeedsDump = true;\n                    sendingBuffer = true;\n                    externalActionsHandler.handleEventBufferDump(eventBuffer, 0, globalEvBufPos);\n                    globalEvBufPos = 0;\n                    sendingBuffer = false;\n                }\n\n                // Finally copy the local buffer into the global one\n                eventBuffer[globalEvBufPos++] = SET_FOLLOWING_EVENTS_THREAD;\n                eventBuffer[globalEvBufPos++] = (byte) ((ti.threadId >> 8) & 0xFF);\n                eventBuffer[globalEvBufPos++] = (byte) ((ti.threadId) & 0xFF);\n                System.arraycopy(evBuf, evBufDumpLastPos, eventBuffer, globalEvBufPos, curPos - evBufDumpLastPos);\n                globalEvBufPos += (curPos - evBufDumpLastPos);\n                ti.evBufPos = 0;\n                ti.evBufDumpLastPos = 0;\n            }\n        }\n\n        curPos = ti.evBufPos;\n        evBuf[curPos++] = ADJUST_TIME;\n\n        long absInterval = Timers.getCurrentTimeInCounts() - absTimeStamp;\n        evBuf[curPos++] = (byte) ((absInterval >> 48) & 0xFF);\n        evBuf[curPos++] = (byte) ((absInterval >> 40) & 0xFF);\n        evBuf[curPos++] = (byte) ((absInterval >> 32) & 0xFF);\n        evBuf[curPos++] = (byte) ((absInterval >> 24) & 0xFF);\n        evBuf[curPos++] = (byte) ((absInterval >> 16) & 0xFF);\n        evBuf[curPos++] = (byte) ((absInterval >> 8) & 0xFF);\n        evBuf[curPos++] = (byte) ((absInterval) & 0xFF);\n\n        if (ProfilerRuntimeCPU.threadCPUTimerOn) {\n            long threadInterval = Timers.getThreadCPUTimeInNanos() - threadTimeStamp;\n            evBuf[curPos++] = (byte) ((threadInterval >> 48) & 0xFF);\n            evBuf[curPos++] = (byte) ((threadInterval >> 40) & 0xFF);\n            evBuf[curPos++] = (byte) ((threadInterval >> 32) & 0xFF);\n            evBuf[curPos++] = (byte) ((threadInterval >> 24) & 0xFF);\n            evBuf[curPos++] = (byte) ((threadInterval >> 16) & 0xFF);\n            evBuf[curPos++] = (byte) ((threadInterval >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((threadInterval) & 0xFF);\n        }\n        ti.evBufPos = curPos;\n    }\n\n    static long writeWaitTimeEvent(byte eventType, ThreadInfo ti, Object id) {\n        return writeWaitTimeEvent(eventType, ti, id, null);\n    }\n    \n    static long writeWaitTimeEvent(byte eventType, ThreadInfo ti, Object id, ThreadInfo ownerTi) {\n        if (eventBuffer == null) return -1;\n        int hash = writeNewMonitorEvent(ti,id);\n        \n        if (ownerTi != null) {\n            initThreadInfo(ownerTi);\n        }\n        // if (printEvents) System.out.println(\"*** Writing event \" + eventType + \", metodId = \" + (int)methodId);\n        int curPos = ti.evBufPos; // It's important to use a local copy for evBufPos, so that evBufPos is at event boundary at any moment\n\n        if (curPos > ThreadInfo.evBufPosThreshold) {\n            copyLocalBuffer(ti);\n            curPos = ti.evBufPos;\n        }\n\n        byte[] evBuf = ti.evBuf;\n\n        evBuf[curPos++] = eventType;\n\n        // Note that in the code below, we write only the 7 low bytes of the 64-bit value. The justification is that this saves\n        // us some performance and memory, and 2^55 == 36028797018963968 ns == 36028797 sec == 10008 hr == 416 days is a sufficent\n        // representation range for the foreseeable usages of our tool. (***)\n        long absTimeStamp = Timers.getCurrentTimeInCounts();\n\n        if (DEBUG) {\n            System.out.println(\"ProfilerRuntime.DEBUG: Writing waitTime event type = \" + eventType + // NOI18N\n                    \", timestamp: \" + absTimeStamp + // NOI18N\n                    (id==null ? \"\" : \", id: \"+Integer.toHexString(hash)) + // NOI18N\n                    (ownerTi == null ? \"\" : \", ownerId: \"+ownerTi.threadId)); // NOI18N\n        }\n\n        evBuf[curPos++] = (byte) ((absTimeStamp >> 48) & 0xFF);\n        evBuf[curPos++] = (byte) ((absTimeStamp >> 40) & 0xFF);\n        evBuf[curPos++] = (byte) ((absTimeStamp >> 32) & 0xFF);\n        evBuf[curPos++] = (byte) ((absTimeStamp >> 24) & 0xFF);\n        evBuf[curPos++] = (byte) ((absTimeStamp >> 16) & 0xFF);\n        evBuf[curPos++] = (byte) ((absTimeStamp >> 8) & 0xFF);\n        evBuf[curPos++] = (byte) ((absTimeStamp) & 0xFF);\n        if (hash != -1) {\n            evBuf[curPos++] = (byte) ((hash >> 24) & 0xFF);\n            evBuf[curPos++] = (byte) ((hash >> 16) & 0xFF);\n            evBuf[curPos++] = (byte) ((hash >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((hash) & 0xFF);\n            if (eventType == METHOD_ENTRY_MONITOR) {\n                int ownerId = -1;\n                \n                if (ownerTi != null) {\n                    ownerId = ownerTi.getThreadId();\n                }\n                evBuf[curPos++] = (byte) ((ownerId >> 24) & 0xFF);\n                evBuf[curPos++] = (byte) ((ownerId >> 16) & 0xFF);\n                evBuf[curPos++] = (byte) ((ownerId >> 8) & 0xFF);\n                evBuf[curPos++] = (byte) ((ownerId) & 0xFF);\n            }\n        }\n\n        ti.evBufPos = curPos;\n        return absTimeStamp;\n    }\n\n    private static int writeNewMonitorEvent(ThreadInfo ti, Object id) {\n        if (id == null || !lockContentionMonitoringEnabled) return -1;\n        initThreadInfo(ti);\n        int hash = System.identityHashCode(id);\n        Integer hashInt = new Integer(hash);\n        if (knownMonitors.add(hashInt)) {\n            int curPos = ti.evBufPos; // It's important to use a local copy for evBufPos, so that evBufPos is at event boundary at any moment\n\n            if (DEBUG) {\n                System.out.println(\"ProfilerRuntime.DEBUG: New Monitor \"+Integer.toHexString(hash));\n            }\n            if (curPos > ThreadInfo.evBufPosThreshold) {\n                copyLocalBuffer(ti);\n                curPos = ti.evBufPos;\n            }\n\n            byte[] evBuf = ti.evBuf;\n            evBuf[curPos++] = NEW_MONITOR;\n            evBuf[curPos++] = (byte) ((hash >> 24) & 0xFF);\n            evBuf[curPos++] = (byte) ((hash >> 16) & 0xFF);\n            evBuf[curPos++] = (byte) ((hash >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((hash) & 0xFF);            \n\n            byte[] name = id.getClass().getName().getBytes();\n            int len = name.length;\n            evBuf[curPos++] = (byte) ((len >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((len) & 0xFF);\n            System.arraycopy(name, 0, evBuf, curPos, len);\n            curPos += len;\n            ti.evBufPos = curPos;\n        }\n        return hash;\n    }\n\n    private static void initThreadInfo(ThreadInfo ti) {\n        if (!ti.isInitialized()) {\n            ti.initialize();\n            ti.useEventBuffer();\n            writeThreadCreationEvent(ti);\n        } else if (ti.evBuf == null) {\n            ti.useEventBuffer();\n        }\n    }\n\n    // -------------------------------- Thread-related stuff ------------------------------------------\n    public static boolean profiledTargetAppThreadsExist() {\n        return (ThreadInfo.getNProfiledAppThreads() > 0);\n    }\n\n    protected static void changeAllThreadsInProfRuntimeMethodStatus(int val) {\n        ThreadInfo.changeAllThreadsInProfRuntimeMethodStatus(val);\n    }\n\n    protected static void clearDataStructures() {\n        eventBuffer = null;\n        globalEvBufPos = 0;\n        ThreadInfo.resetThreadInfoTable();\n        knownMonitors = new HashSet();\n    }\n\n    protected static void createNewDataStructures() {\n        ThreadInfo.resetThreadInfoTable(); // Despite the name, it effectively creates some data\n    }\n\n    private static void doResetProfilerCollectors(int instrType) {\n        ThreadInfo.resetThreadInfoTable();\n        globalEvBufPos = 0;\n        knownMonitors = new HashSet();\n\n        if (eventBuffer != null) {\n            eventBuffer[globalEvBufPos++] = RESET_COLLECTORS;\n        }\n\n        switch (instrType) {\n            case INSTR_RECURSIVE_FULL:\n            case INSTR_RECURSIVE_SAMPLED:\n                ProfilerRuntimeCPU.resetProfilerCollectors();\n\n                break;\n            case INSTR_NONE_SAMPLING:\n                ProfilerRuntimeSampler.resetProfilerCollectors();\n                \n                break;\n            case INSTR_CODE_REGION:\n                ProfilerRuntimeCPUCodeRegion.resetProfilerCollectors();\n\n                break;\n            case INSTR_OBJECT_ALLOCATIONS:\n            case INSTR_OBJECT_LIVENESS:\n                ProfilerRuntimeMemory.resetProfilerCollectors(instrType);\n\n                break;\n            case INSTR_NONE_MEMORY_SAMPLING:\n                if (Histogram.isAvailable()) {\n                    ProfilerServer.notifyClientOnResultsAvailability();\n                }\n                break;\n        }\n    }\n\n    private static int writePPointHitToBuffer(byte[] buf, final long absTimeStamp, int curPos, final int id, final int tid) {\n        buf[curPos++] = BUFFEREVENT_PROFILEPOINT_HIT;\n        buf[curPos++] = (byte) ((id >> 8) & 0xFF);\n        buf[curPos++] = (byte) (id & 0xFF);\n        buf[curPos++] = (byte) ((absTimeStamp >> 48) & 0xFF);\n        buf[curPos++] = (byte) ((absTimeStamp >> 40) & 0xFF);\n        buf[curPos++] = (byte) ((absTimeStamp >> 32) & 0xFF);\n        buf[curPos++] = (byte) ((absTimeStamp >> 24) & 0xFF);\n        buf[curPos++] = (byte) ((absTimeStamp >> 16) & 0xFF);\n        buf[curPos++] = (byte) ((absTimeStamp >> 8) & 0xFF);\n        buf[curPos++] = (byte) ((absTimeStamp) & 0xFF);\n        buf[curPos++] = (byte) ((tid >> 8) & 0xFF);\n        buf[curPos++] = (byte) ((tid) & 0xFF);\n\n        return curPos;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPU.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport java.lang.reflect.Method;\nimport java.util.Date;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Stacks;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Timers;\n\n/**\n * This class contains the functionality that is common for all CPU profiling methods available in JFluid.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class ProfilerRuntimeCPU extends ProfilerRuntime {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final boolean DEBUG = false;\n    private static int maxStringLength = MAX_STRING_LENGTH_DEFAULT;  // in chars\n    static final Object NO_RET_VALUE = new Object();\n    private static int nProfiledThreadsLimit;\n    protected static int nProfiledThreadsAllowed;\n    protected static int stackDepthLimit = Integer.MAX_VALUE;\n    protected static boolean enableFirstTimeMethodInvoke;\n\n    // The following flag is used to prevent deadlock inside getThreadInfo() by forcing immediate return from methodEntry() etc.\n    // in case methodEntry() (typically when it's injected in some core class method) is executed on behalf of some profiler server thread,\n    // when all target app threads are suspended. In that case, some thread may be suspended within getThreadInfo(), holding the lock.\n    // It is also used to disable instrumentation to be on the safe side when we e.g. detach from a running multithreaded application -\n    // it looks as if in this case de-instrumentation may not immediately propagate everywhere.\n    protected static volatile boolean recursiveInstrumentationDisabled = false;\n\n    // ------------------------------------------ Timers -----------------------------------------------\n    protected static boolean absoluteTimerOn;\n\n    // ------------------------------------------ Timers -----------------------------------------------\n    protected static boolean threadCPUTimerOn;\n\n    protected static boolean waitTrackingEnabled;\n    protected static boolean sleepTrackingEnabled;\n    \n    // ---------------------------------- Profile Data Acquisition --------------------------------------\n    protected static boolean[] instrMethodInvoked;\n    private static boolean javaLangReflectMethodInvokeInterceptEnabled = false;\n    private static Method getRequestedSessionIdMethod;\n    private static Method getMethodMethod;\n    private static Method getServletPathMethod;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    // See the comment in writeTimeStampedEvent() below, marked with (***)\n    // On all OSes except Linux, the upper byte of value returned by Timers.getCurrentTimeInCounts() will be zero - timer\n    // calculates time from program start or from machine start. But on Linux it seems to be timeofday or something. We have\n    // to take measures here to return time in the same format as used for collected data.\n    public static long getAbsTimeStampInCollectedFormat() {\n        return Timers.getCurrentTimeInCounts() & 72057594037927935L; //0xFFFFFFFFFFFFFF, i.e. 7 bytes\n    }\n\n    public static void setInstrMethodsInvoked(boolean[] methodInvoked) {\n        instrMethodInvoked = methodInvoked;\n    }\n\n    public static void setJavaLangReflectMethodInvokeInterceptEnabled(boolean v) {\n        javaLangReflectMethodInvokeInterceptEnabled = v;\n    }\n\n    public static void setNProfiledThreadsLimit(int num) {\n        nProfiledThreadsLimit = nProfiledThreadsAllowed = num;\n    }\n\n    public static void setMaxStringLength(int maxLength) {\n        maxStringLength = maxLength;\n    }\n\n    public static void setStackDepthLimit(int num) {\n        stackDepthLimit = num;\n    }\n\n    public static void setWaitAndSleepTracking(boolean waitTracking, boolean sleepTracking) {\n        waitTrackingEnabled = waitTracking;\n        sleepTrackingEnabled = sleepTracking;\n    }\n    \n    public static void setTimerTypes(boolean absolute, boolean threadCPU) {\n        if (threadCPU != threadCPUTimerOn && Platform.isSolaris()) {\n            Timers.enableMicrostateAccounting(threadCPU);\n        }\n\n        absoluteTimerOn = absolute;\n        threadCPUTimerOn = threadCPU;\n    }\n    \n    public static void enableFirstTimeMethodInvoke(boolean enabled) {\n        enableFirstTimeMethodInvoke = enabled;\n    }\n\n    // This is currently used only when calibrating the profiler, to pre-create a ThreadInfo before calling methodEntry/Exit.\n    // It is done to prevent the system attempting to send a \"new thread created\" message to the client.\n    public static void createThreadInfoForCurrentThread() {\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n        ti.initialize();\n        ti.useEventBuffer();\n        ti.inCallGraph = false; // Important: this is a correct initial value when ti is used in calibration\n    }\n\n    public static void handleJavaLangReflectMethodInvoke(Method method) {\n        if (!javaLangReflectMethodInvokeInterceptEnabled) {\n            return;\n        }\n\n        if (recursiveInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized() || !ti.inCallGraph) {\n            return; // ti == null may happen if instrumentation has been removed or data collectors reset\n        }\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        ti.inProfilingRuntimeMethod++;\n\n        externalActionsHandler.handleReflectiveInvoke(method);\n\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    public static void handleServletDoMethod(Object request) {\n        if (recursiveInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized()) {\n            System.out.println(\"No thread for servlet request\"); // NOI18N\n\n            return;\n        }\n\n        ti.inProfilingRuntimeMethod++;\n        servletDoMethodHook(ti, request);\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    public static void resetProfilerCollectors() {\n        nProfiledThreadsAllowed = nProfiledThreadsLimit;\n    }\n\n    public static void resumeCurrentThreadTimer() {\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized() || !ti.inCallGraph) {\n            return;\n        }\n\n        writeAdjustTimeEvent(ti, ti.absEntryTime, ti.threadEntryTime);\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    // This is currently called in class load hook, to stop counting the time and emitting method entry/exit events while the\n    // hook and other Java code that it may call are active.\n    public static ThreadInfo suspendCurrentThreadTimer() {\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized() || !ti.inCallGraph) {\n            return ti;\n        }\n\n        ti.inProfilingRuntimeMethod++;\n\n        // those timestamps are taken here, as opposed to earlier in this method, because we need to make sure we do not\n        // profile the Timer.get... calls, by increasing the ti.inProfilingRuntimeMethod\n        // see issue 65614 for a possible impact of this\n        // http://profiler.netbeans.org/issues/show_bug.cgi?id=65614\n        ti.absEntryTime = Timers.getCurrentTimeInCounts();\n        if (threadCPUTimerOn) {\n            ti.threadEntryTime = Timers.getThreadCPUTimeInNanos();\n        }\n        return ti;\n    }\n\n    protected static void clearDataStructures() {\n        ProfilerRuntime.clearDataStructures();\n        nProfiledThreadsAllowed = nProfiledThreadsLimit;\n    }\n    \n    protected static void createNewDataStructures() {\n        ProfilerRuntime.createNewDataStructures();\n        // top level Marker method has stacktrace \n        Stacks.createNativeStackFrameBuffer(ProfilerRuntimeMemory.MAX_STACK_FRAMES);\n    }\n\n    protected static long currentTimeInCounts() {\n        return Timers.getCurrentTimeInCounts();\n    }\n\n    protected static void enableProfiling(boolean v) {\n        recursiveInstrumentationDisabled = !v;\n\n        // Doesn't call clearDataStructures() since this is an \"abstract\" class\n    }\n\n    // ---------------------------------- Handling wait/sleep/monitor times ----------------------------\n    protected static long monitorEntryCPU(ThreadInfo ti, Object monitor, ThreadInfo ownerTi) {\n        if (recursiveInstrumentationDisabled || !waitTrackingEnabled) {\n            return -1; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        if (ti.isInitialized() && ti.inCallGraph) {\n            //System.out.println(\"++++++monitorEntry, depth = \" + ti.stackDepth);\n            return writeWaitTimeEvent(METHOD_ENTRY_MONITOR, ti, monitor, ownerTi);\n        }\n        return -1;\n    }\n\n    protected static long monitorExitCPU(ThreadInfo ti, Object monitor) {\n        if (recursiveInstrumentationDisabled || !waitTrackingEnabled) {\n            return -1; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        if (ti.isInitialized() && ti.inCallGraph) {\n            //System.out.println(\"++++++monitorExit, depth = \" + ti.stackDepth);\n            return writeWaitTimeEvent(METHOD_EXIT_MONITOR, ti, monitor);\n        }\n        return -1;\n    }\n\n    protected static long sleepEntryCPU(ThreadInfo ti) {\n        if (recursiveInstrumentationDisabled || !sleepTrackingEnabled) {\n            return -1; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n        if (ti.isInitialized() && ti.inCallGraph) {\n            //System.out.println(\"++++++sleepEntry, depth = \" + ti.stackDepth);\n            return writeWaitTimeEvent(METHOD_ENTRY_SLEEP, ti);\n        }\n        return -1;\n    }\n\n    protected static long sleepExitCPU(ThreadInfo ti) {\n        if (recursiveInstrumentationDisabled || !sleepTrackingEnabled) {\n            return -1; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        if (ti.isInitialized() && ti.inCallGraph) {\n            //System.out.println(\"++++++sleepExit, depth = \" + ti.stackDepth);\n            return writeWaitTimeEvent(METHOD_EXIT_SLEEP, ti);\n        }\n        return -1;\n    }\n\n    protected static long waitEntryCPU(ThreadInfo ti) {\n        if (recursiveInstrumentationDisabled || !waitTrackingEnabled) {\n            return -1; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        if (ti.isInitialized() && ti.inCallGraph) {\n            //System.out.println(\"++++++waitEntry, depth = \" + ti.stackDepth);\n            return writeWaitTimeEvent(METHOD_ENTRY_WAIT, ti);\n        }\n        return -1;\n    }\n\n    protected static long waitExitCPU(ThreadInfo ti) {\n        if (recursiveInstrumentationDisabled || !waitTrackingEnabled) {\n            return -1; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        if (ti.isInitialized() && ti.inCallGraph) {\n            //System.out.println(\"++++++waitExit, depth = \" + ti.stackDepth);\n            return writeWaitTimeEvent(METHOD_EXIT_WAIT, ti);\n        }\n        return -1;\n    }\n\n    protected static long parkEntryCPU(ThreadInfo ti) {\n        if (recursiveInstrumentationDisabled || !waitTrackingEnabled) {\n            return -1; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        if (ti.isInitialized() && ti.inCallGraph) {\n            //System.out.println(\"++++++parkEntry, depth = \" + ti.stackDepth);\n            return writeWaitTimeEvent(METHOD_ENTRY_PARK, ti);\n        }\n        return -1;\n    }\n\n    protected static long parkExitCPU(ThreadInfo ti) {\n        if (recursiveInstrumentationDisabled || !waitTrackingEnabled) {\n            return -1; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        if (ti.isInitialized() && ti.inCallGraph) {\n            //System.out.println(\"++++++parkExit, depth = \" + ti.stackDepth);\n            return writeWaitTimeEvent(METHOD_EXIT_PARK, ti);\n        }\n        return -1;\n    }\n\n    protected static void firstTimeMethodInvoke(final ThreadInfo ti, final char methodId) {\n        if (enableFirstTimeMethodInvoke) {\n            long absTimeStamp = Timers.getCurrentTimeInCounts();\n            long threadTimeStamp = threadCPUTimerOn ? Timers.getThreadCPUTimeInNanos() : 0;\n            externalActionsHandler.handleFirstTimeMethodInvoke(methodId);\n            writeAdjustTimeEvent(ti, absTimeStamp, threadTimeStamp);\n        }\n    }\n\n    static void writeServletDoMethod(ThreadInfo ti, String method, String servletPath, String sessionId) {\n        int fullInfoLen = 1 + 1 + (servletPath.length() * 2) + 4;\n        int curPos = ti.evBufPos; // It's important to use a local copy for evBufPos, so that evBufPos is at event boundary at any moment\n\n        if ((curPos + fullInfoLen) > ThreadInfo.evBufPosThreshold) {\n            copyLocalBuffer(ti);\n            curPos = ti.evBufPos;\n        }\n\n        byte[] evBuf = ti.evBuf;\n        byte methodId = -1;\n        int sessionHash = -1;\n\n        if (\"GET\".equals(method)) { // NOI18N\n            methodId = 1;\n        } else if (\"POST\".equals(method)) { // NOI18N\n            methodId = 2;\n        } else if (\"PUT\".equals(method)) { // NOI18N\n            methodId = 3;\n        } else if (\"DELETE\".equals(method)) { // NOI18N\n            methodId = 4;\n        }\n\n        if (sessionId != null) {\n            sessionHash = sessionId.hashCode();\n        }\n\n        evBuf[curPos++] = SERVLET_DO_METHOD;\n        evBuf[curPos++] = methodId;\n\n        byte[] name = servletPath.getBytes();\n        int len = name.length;\n        evBuf[curPos++] = (byte) ((len >> 8) & 0xFF);\n        evBuf[curPos++] = (byte) ((len) & 0xFF);\n        System.arraycopy(name, 0, evBuf, curPos, len);\n        curPos += len;\n        evBuf[curPos++] = (byte) ((sessionHash >> 24) & 0xFF);\n        evBuf[curPos++] = (byte) ((sessionHash >> 16) & 0xFF);\n        evBuf[curPos++] = (byte) ((sessionHash >> 8) & 0xFF);\n        evBuf[curPos++] = (byte) ((sessionHash) & 0xFF);\n        ti.evBufPos = curPos;\n    }\n\n    // ---------------------------------- Writing profiler events --------------------------------------\n    static void writeTimeStampedEvent(byte eventType, ThreadInfo ti, char methodId) {\n        int[] stackFrameIds = null;\n        int currentStackDepth = 0;\n        if (eventType == MARKER_ENTRY) {\n            // top-level marker method has stack trace\n            if (ti.stackDepth == 0) {\n                stackFrameIds = new int[ProfilerRuntimeMemory.MAX_STACK_FRAMES];\n                currentStackDepth = Stacks.getCurrentStackFrameIds(ti.getThread(), stackFrameIds.length, stackFrameIds);\n                currentStackDepth -= ProfilerRuntimeMemory.NO_OF_PROFILER_FRAMES;\n            } else {\n                stackFrameIds = new int[0];\n            }\n        }\n        int curPos = ti.evBufPos; // It's important to use a local copy for evBufPos, so that evBufPos is at event boundary at any moment\n\n        if (curPos + currentStackDepth*4 > ThreadInfo.evBufPosThreshold) {\n            copyLocalBuffer(ti);\n            curPos = ti.evBufPos;\n        }\n\n        byte[] evBuf = ti.evBuf;\n        if (!ti.isInitialized()) return;    // Reset collectors performed when we were already executing instrumentation code \n        evBuf[curPos++] = eventType;\n        evBuf[curPos++] = (byte) ((methodId >> 8) & 0xFF);\n        evBuf[curPos++] = (byte) ((methodId) & 0xFF);\n\n        // Note that in the code below, we write only the 7 low bytes of the 64-bit timestamp. The justification is that this saves\n        // us some performance and memory, and 2^55 == 36028797018963968 ns == 36028797 sec == 10008 hr == 416 days is a sufficent\n        // representation range for the foreseeable usages of our tool. (***)\n        if (absoluteTimerOn) {\n            long absTimeStamp = Timers.getCurrentTimeInCounts();\n            evBuf[curPos++] = (byte) ((absTimeStamp >> 48) & 0xFF);\n            evBuf[curPos++] = (byte) ((absTimeStamp >> 40) & 0xFF);\n            evBuf[curPos++] = (byte) ((absTimeStamp >> 32) & 0xFF);\n            evBuf[curPos++] = (byte) ((absTimeStamp >> 24) & 0xFF);\n            evBuf[curPos++] = (byte) ((absTimeStamp >> 16) & 0xFF);\n            evBuf[curPos++] = (byte) ((absTimeStamp >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((absTimeStamp) & 0xFF);\n\n            if (DEBUG) {\n                System.out.println(\"ProfilerRuntimeCPU.DEBUG: Writing event (Abs) type = \" + eventType + \", metodId = \"\n                                   + (int) methodId + \", timestamp: \" + absTimeStamp); // NOI18N\n            }\n        }\n\n        if (threadCPUTimerOn) {\n            long threadTimeStamp = Timers.getThreadCPUTimeInNanos();\n            evBuf[curPos++] = (byte) ((threadTimeStamp >> 48) & 0xFF);\n            evBuf[curPos++] = (byte) ((threadTimeStamp >> 40) & 0xFF);\n            evBuf[curPos++] = (byte) ((threadTimeStamp >> 32) & 0xFF);\n            evBuf[curPos++] = (byte) ((threadTimeStamp >> 24) & 0xFF);\n            evBuf[curPos++] = (byte) ((threadTimeStamp >> 16) & 0xFF);\n            evBuf[curPos++] = (byte) ((threadTimeStamp >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((threadTimeStamp) & 0xFF);\n\n            if (DEBUG) {\n                System.out.println(\"ProfilerRuntimeCPU.DEBUG: Writing event (CPU) type = \" + eventType + \", metodId = \"\n                                   + (int) methodId + \", timestamp: \" + threadTimeStamp); // NOI18N\n            }\n        }\n        if (stackFrameIds != null) {\n            evBuf[curPos++] = (byte) ((currentStackDepth >> 16) & 0xFF);\n            evBuf[curPos++] = (byte) ((currentStackDepth >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((currentStackDepth) & 0xFF);\n            int frameIdx = ProfilerRuntimeMemory.NO_OF_PROFILER_FRAMES;\n\n            for (int i = 0; i < currentStackDepth; i++) {\n                evBuf[curPos++] = (byte) ((stackFrameIds[frameIdx] >> 24) & 0xFF);\n                evBuf[curPos++] = (byte) ((stackFrameIds[frameIdx] >> 16) & 0xFF);\n                evBuf[curPos++] = (byte) ((stackFrameIds[frameIdx] >> 8) & 0xFF);\n                evBuf[curPos++] = (byte) ((stackFrameIds[frameIdx]) & 0xFF);\n                frameIdx++;\n            }\n        }\n\n        ti.evBufPos = curPos;\n    }\n    \n    static long writeWaitTimeEvent(byte eventType, ThreadInfo ti) {\n        return writeWaitTimeEvent(eventType, ti, null);\n    }\n    \n    static void writeParametersEvent(ThreadInfo ti) {\n        List pars = ti.getParameters();\n        int parsLength = 0;\n        if (pars != null) {\n            for (int i = 0; i < pars.size(); i++) {\n                parsLength += 1 + getParSize(pars.get(i));\n            }\n        }\n        int fullInfoLen = 1 + 1 + parsLength;\n        int curPos = ti.evBufPos; // It's important to use a local copy for evBufPos, so that evBufPos is at event boundary at any moment\n\n        if ((curPos + fullInfoLen) > ThreadInfo.evBufPosThreshold) {\n            copyLocalBuffer(ti);\n            curPos = ti.evBufPos;\n        }\n\n        byte[] evBuf = ti.evBuf;\n\n        evBuf[curPos++] = MARKER_ENTRY_PARAMETERS;\n        if (pars != null) {\n            evBuf[curPos++] = (byte) pars.size();\n\n            for (int i = 0; i < pars.size(); i++) {\n                curPos = writeParameter(evBuf, curPos, pars.get(i));\n            }\n            ti.clearParameters();\n        } else {\n            evBuf[curPos++] = 0;            \n        }\n        ti.evBufPos = curPos;\n    }\n\n    static void writeRetValue(Object ret, ThreadInfo ti) {\n        if (ret != NO_RET_VALUE) {\n            ti.addParameter(ret != null ? convertToString(ret) : \"\");\n            writeParametersEvent(ti);\n        }\n    }\n    \n    private static void servletDoMethodHook(ThreadInfo ti, Object request) {\n        String servletPath = null;\n        String method = null;\n        String requestedSessionId = null;\n\n        if (getRequestedSessionIdMethod == null) {\n            try {\n                Class requestClass = request.getClass();\n                getRequestedSessionIdMethod = requestClass.getMethod(\"getRequestedSessionId\", null); // NOI18N\n                getMethodMethod = requestClass.getMethod(\"getMethod\", null); // NOI18N\n                getServletPathMethod = requestClass.getMethod(\"getServletPath\", null); // NOI18N\n            } catch (Exception ex) {\n                ex.printStackTrace();\n\n                return;\n            }\n        }\n\n        try {\n            requestedSessionId = (String) getRequestedSessionIdMethod.invoke(request, null);\n            method = (String) getMethodMethod.invoke(request, null);\n            servletPath = (String) getServletPathMethod.invoke(request, null);\n        } catch (Exception ex) {\n            ex.printStackTrace();\n\n            return;\n        }\n\n        writeServletDoMethod(ti, method, servletPath, requestedSessionId);\n    }\n    \n    public static void addParameter(boolean b) {\n        if (recursiveInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n        ti.inProfilingRuntimeMethod++;\n        ti.addParameter(Boolean.valueOf(b));\n        ti.inProfilingRuntimeMethod--; \n    }\n\n    public static void addParameter(char b) {\n        if (recursiveInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        ti.inProfilingRuntimeMethod++;\n        ti.addParameter(new Character(b));\n        ti.inProfilingRuntimeMethod--; \n    }\n\n    public static void addParameter(byte b) {\n        if (recursiveInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        ti.inProfilingRuntimeMethod++;\n        ti.addParameter(new Byte(b));\n        ti.inProfilingRuntimeMethod--; \n    }\n\n    public static void addParameter(short b) {\n        if (recursiveInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        ti.inProfilingRuntimeMethod++;\n        ti.addParameter(new Short(b));\n        ti.inProfilingRuntimeMethod--; \n    }\n\n    public static void addParameter(int b) {\n        if (recursiveInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        ti.inProfilingRuntimeMethod++;\n        ti.addParameter(new Integer(b));\n        ti.inProfilingRuntimeMethod--; \n    }\n\n    public static void addParameter(long b) {\n        if (recursiveInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        ti.inProfilingRuntimeMethod++;\n        ti.addParameter(new Long(b));\n        ti.inProfilingRuntimeMethod--; \n    }\n\n    public static void addParameter(float b) {\n        if (recursiveInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        ti.inProfilingRuntimeMethod++;\n        ti.addParameter(new Float(b));\n        ti.inProfilingRuntimeMethod--; \n    }\n\n    public static void addParameter(double b) {\n        if (recursiveInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        ti.inProfilingRuntimeMethod++;\n        ti.addParameter(new Double(b));\n        ti.inProfilingRuntimeMethod--; \n    }\n\n    public static void addParameter(Object b) {\n        if (recursiveInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        ti.inProfilingRuntimeMethod++;\n        ti.addParameter(b != null ? convertToString(b) : \"\");\n        ti.inProfilingRuntimeMethod--; \n    }\n    \n    private static int getParSize(Object p) {\n        Class type = p.getClass();\n        if (type == Integer.class) {\n            return 4;\n        } else if (type == Boolean.class) {\n            return 1;\n        } else if (type == Byte.class) {\n            return 1;\n        } else if (type == Short.class) {\n            return 2;\n        } else if (type == Character.class) {\n            return 2;\n        } else if (type == Long.class) {\n            return 8;\n        } else if (type == Float.class) {\n            return 4;\n        } else if (type == Double.class) {\n            return 8;\n        } else {\n            return 2 + truncatedByteLength((String) p);\n        }\n    }\n    \n    private static int writeParameter(byte[] evBuf, int curPos, Object p) {\n        Class type = p.getClass();\n        if (type == Integer.class) {\n            int vp = ((Integer)p).intValue();\n            evBuf[curPos++] = ProfilerInterface.INT;\n            evBuf[curPos++] = (byte) ((vp >> 24) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 16) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp) & 0xFF);\n        } else if (type == Boolean.class) {\n            boolean vp = ((Boolean)p).booleanValue();\n            evBuf[curPos++] = ProfilerInterface.BOOLEAN;\n            evBuf[curPos++] = (byte) (vp ? 1 : 0);\n        } else if (type == Byte.class) {\n            byte vp = ((Byte)p).byteValue();\n            evBuf[curPos++] = ProfilerInterface.BYTE;\n            evBuf[curPos++] = vp;\n        } else if (type == Short.class) {\n            short vp = ((Short)p).shortValue();\n            evBuf[curPos++] = ProfilerInterface.SHORT;\n            evBuf[curPos++] = (byte) ((vp >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp) & 0xFF);\n        } else if (type == Character.class) {\n            char vp = ((Character)p).charValue();\n            evBuf[curPos++] = ProfilerInterface.CHAR;\n            evBuf[curPos++] = (byte) ((vp >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp) & 0xFF);\n        } else if (type == Long.class) {\n            long vp = ((Long)p).longValue();\n            evBuf[curPos++] = ProfilerInterface.LONG;\n            evBuf[curPos++] = (byte) ((vp >> 56) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 48) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 40) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 32) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 24) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 16) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp) & 0xFF); \n        } else if (type == Float.class) {\n            int vp = Float.floatToIntBits(((Float)p).floatValue());\n            evBuf[curPos++] = ProfilerInterface.FLOAT;\n            evBuf[curPos++] = (byte) ((vp >> 24) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 16) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp) & 0xFF);\n        } else if (type == Double.class) {\n            long vp = Double.doubleToLongBits(((Double)p).doubleValue());\n            evBuf[curPos++] = ProfilerInterface.DOUBLE;\n            evBuf[curPos++] = (byte) ((vp >> 56) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 48) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 40) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 32) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 24) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 16) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((vp) & 0xFF);\n        } else {    \n            String sp = (String) p;\n            int lengthBytes = truncatedByteLength(sp);\n            evBuf[curPos++] = ProfilerInterface.REFERENCE;\n            evBuf[curPos++] = (byte) ((lengthBytes >> 8) & 0xFF);\n            evBuf[curPos++] = (byte) ((lengthBytes) & 0xFF);\n            for (int i = 0; i < lengthBytes/2; i++) {\n                char ch = sp.charAt(i);\n                evBuf[curPos++] = (byte) ((ch >> 8) & 0xFF);\n                evBuf[curPos++] = (byte) ((ch) & 0xFF);\n            }\n        }\n        return curPos;\n    }\n    \n    static String convertToString(Object o) {\n        String clazz = o.getClass().getName();\n        \n        if (clazz.startsWith(\"java.lang.\")) {\n            return o.toString();\n        }\n        if (clazz.equals(\"java.sql.Date\")) {\n            return String.valueOf(((Date)o).getTime());\n        }\n        if (clazz.equals(\"java.sql.Timestamp\")) {\n            return String.valueOf(((Date)o).getTime());\n        }\n        if (clazz.equals(\"java.math.BigDecimal\")) {\n            return o.toString();\n        }\n        return getObjectId(o, clazz);\n    }\n    \n    private static int truncatedByteLength(String s) {\n        int length = s.length();\n        \n        if (length < maxStringLength) {\n            return length*2;\n        }\n        return maxStringLength*2;\n    }\n    \n    private static String getObjectId(Object o, String clazz) {\n        return clazz + \"@\" + Integer.toHexString(System.identityHashCode(o));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUCodeRegion.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport org.graalvm.visualvm.lib.jfluid.server.system.Timers;\n\n\n/**\n * Functionality for single code region profiling.\n *\n * @author Misha Dmitriev\n */\npublic class ProfilerRuntimeCPUCodeRegion extends ProfilerRuntime {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    protected static long[] codeRegionResults = new long[0];\n    protected static int newBufSize;\n    protected static int bufSize;\n    protected static int curIdx;\n    protected static long invCount;\n    protected static boolean codeRegionInstrumentationDisabled;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void setCPUResBufSize(int size) {\n        newBufSize = size; // We don't set bufSize immediately to prevent the collector from crash if it's already active\n    }\n\n    public static long[] getProfilingResults() {\n        synchronized (codeRegionResults) {\n            int size = (invCount < bufSize) ? (int) invCount : bufSize;\n            size++; // The very first element of the returned array is the total number of invocations\n\n            long[] res = new long[size];\n            res[0] = (int) invCount;\n\n            if (invCount < bufSize) {\n                System.arraycopy(codeRegionResults, 0, res, 1, (int) invCount);\n            } else {\n                System.arraycopy(codeRegionResults, curIdx, res, 1, bufSize - curIdx);\n                System.arraycopy(codeRegionResults, 0, res, bufSize - curIdx + 1, curIdx);\n            }\n\n            return res;\n        }\n    }\n\n    public static void codeRegionEntry() {\n        //System.out.println(\"+++++++++ codeRegionEntry \" + Thread.currentThread());\n        if (codeRegionInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized()) {\n            ti.initialize();\n        }\n\n        ti.inCallGraph = true;\n        ti.absEntryTime = Timers.getCurrentTimeInCounts();\n    }\n\n    public static void codeRegionExit() {\n        if (codeRegionInstrumentationDisabled) {\n            return;\n        }\n\n        long time = Timers.getCurrentTimeInCounts();\n\n        //System.out.println(\"--------- codeRegionExit \" + Thread.currentThread());\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized() || !ti.inCallGraph) {\n            return;\n        }\n\n        time = time - ti.absEntryTime;\n\n        synchronized (codeRegionResults) {\n            codeRegionResults[curIdx++] = time;\n            invCount++;\n\n            if (curIdx == bufSize) {\n                curIdx = 0;\n            }\n        }\n\n        ti.inCallGraph = false;\n    }\n\n    public static void enableProfiling(boolean v) {\n        if (v) {\n            createNewDataStructures();\n            codeRegionInstrumentationDisabled = false;\n        } else {\n            codeRegionInstrumentationDisabled = true;\n            clearDataStructures();\n        }\n    }\n\n    public static void resetProfilerCollectors() {\n        synchronized (codeRegionResults) {\n            bufSize = newBufSize;\n            codeRegionResults = new long[bufSize];\n            invCount = 0;\n            curIdx = 0;\n        }\n    }\n\n    protected static void clearDataStructures() {\n        ProfilerRuntime.clearDataStructures();\n\n        synchronized (codeRegionResults) {\n            codeRegionResults = new long[0];\n            invCount = 0;\n            curIdx = 0;\n        }\n    }\n\n    // ---------------------------------- Handling wait/sleep/monitor times ----------------------------\n    protected static long monitorEntryRegion(Thread t, Object monitor, ThreadInfo ownerTi) {\n        if (codeRegionInstrumentationDisabled) {\n            return -1;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized() || !ti.inCallGraph) {\n            return -1;\n        }\n\n        // take note of the time we started waiting\n        return ti.lastWaitStartTime = Timers.getCurrentTimeInCounts();\n    }\n\n    protected static long monitorExitRegion(Thread t, Object monitor) {\n        if (codeRegionInstrumentationDisabled) {\n            return -1;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if ((ti == null) || !ti.inCallGraph) {\n            return -1;\n        }\n        long timeStamp = Timers.getCurrentTimeInCounts();\n        // adjust the entry time so that the time spent waiting is not accounted for\n        ti.absEntryTime += (timeStamp - ti.lastWaitStartTime);\n        return timeStamp;\n    }\n\n    protected static void sleepEntryRegion() {\n        if (codeRegionInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized() || !ti.inCallGraph) {\n            return;\n        }\n\n        // take note of the time we started waiting\n        ti.lastWaitStartTime = Timers.getCurrentTimeInCounts();\n    }\n\n    protected static void sleepExitRegion() {\n        if (codeRegionInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized() || !ti.inCallGraph) {\n            return;\n        }\n\n        // adjust the entry time so that the time spent waiting is not accounted for\n        ti.absEntryTime += (Timers.getCurrentTimeInCounts() - ti.lastWaitStartTime);\n    }\n\n    protected static void waitEntryRegion() {\n        if (codeRegionInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized() || !ti.inCallGraph) {\n            return;\n        }\n\n        // take note of the time we started waiting\n        ti.lastWaitStartTime = Timers.getCurrentTimeInCounts();\n    }\n\n    protected static void waitExitRegion() {\n        if (codeRegionInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized() || !ti.inCallGraph) {\n            return;\n        }\n\n        // adjust the entry time so that the time spent waiting is not accounted for\n        ti.absEntryTime += (Timers.getCurrentTimeInCounts() - ti.lastWaitStartTime);\n    }\n\n    protected static void parkEntryRegion() {\n        if (codeRegionInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized() || !ti.inCallGraph) {\n            return;\n        }\n\n        // take note of the time we started waiting\n        ti.lastWaitStartTime = Timers.getCurrentTimeInCounts();\n    }\n\n    protected static void parkExitRegion() {\n        if (codeRegionInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized() || !ti.inCallGraph) {\n            return;\n        }\n\n        // adjust the entry time so that the time spent waiting is not accounted for\n        ti.absEntryTime += (Timers.getCurrentTimeInCounts() - ti.lastWaitStartTime);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUFullInstr.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\n/**\n * This class contains the actual methods for full instrumentation recursive CPU profiling, calls to which are injected\n * into the target application (TA) bytecodes when they are instrumented.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class ProfilerRuntimeCPUFullInstr extends ProfilerRuntimeCPU {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void enableProfiling(boolean v) {\n        if (v) {\n            createNewDataStructures();\n            ProfilerRuntimeCPU.enableProfiling(v);\n        } else {\n            ProfilerRuntimeCPU.enableProfiling(v);\n            clearDataStructures();\n        }\n    }\n\n    // ---------------------------------- Profile Data Acquisition --------------------------------------\n    /** Called upon entry into a special root method used for */\n    public static void markerMethodEntry(char methodId) {\n        if (recursiveInstrumentationDisabled) {\n            return; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        //if (instrMethodClasses != null && methodId < instrMethodClasses.length) System.out.println(\"++++++Marker methodEntry for \" + instrMethodClasses[methodId] + \".\" + instrMethodNames[methodId] + \", thread = \" + Thread.currentThread());\n        //else System.out.println(\"++++++Marker methodEntry for methodId = \" + (int)methodId + \", thread = \" + Thread.currentThread());\n        if (!ti.isInitialized()) {\n            if ((nProfiledThreadsAllowed > 0) && !ThreadInfo.isCurrentThreadProfilerServerThread()) {\n                ti.initialize();\n                ti.useEventBuffer();\n\n                synchronized (eventBuffer) { // Make this happen atomically wrt. other operations on eventBuffer, such as reset collectors\n                    nProfiledThreadsAllowed--;\n\n                    ti.inProfilingRuntimeMethod++;\n                    ti.inCallGraph = true;\n                    writeThreadCreationEvent(ti);\n                }\n            } else {\n                return;\n            }\n        } else {\n            ti.inProfilingRuntimeMethod++;\n            ti.inCallGraph = true;\n        }\n\n        if (ti.stackDepth <= stackDepthLimit) {\n            // when methodId > 64K/2 is passed here using our instrumentation's sipush command at the call site, \n            // it's treated here as a signed integer. Thus without\n            // the below fix we can get e.g. an ArrayIndexOutOfBoundsException(-32768) when methodId == 32768 (***)\n            int methodIdInt = methodId&0xff;\n            methodIdInt |= methodId&0xff00;\n\n            if (!instrMethodInvoked[methodIdInt]) {\n                instrMethodInvoked[methodIdInt] = true; // Mark this method as invoked\n                if (ti.rootMethodStackDepth > 0) { // marker method under root method - perform instrumentation of nearest callees\n                    firstTimeMethodInvoke(ti, methodId);\n                }\n            }\n\n            ProfilerServer.notifyClientOnResultsAvailability();\n            writeParametersEvent(ti);\n            writeTimeStampedEvent(MARKER_ENTRY, ti, methodId);\n        }\n        ti.stackDepth++; //= 1;  // This is the logical stack depth\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    /** Called upon exit from the marker method. */\n    public static void markerMethodExit(char methodId) {\n        markerMethodExit(NO_RET_VALUE, methodId);\n    }\n    \n    /** Called upon exit from the marker method. */\n    public static void markerMethodExit(Object ret, char methodId) {\n        if (recursiveInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.isInitialized() && ti.inCallGraph) { // ti == null may happen if instrumentation has been removed or data collectors reset\n\n            if (ti.inProfilingRuntimeMethod > 0) {\n                return;\n            }\n\n            ti.inProfilingRuntimeMethod++;\n\n            //System.out.println(\"------markerMethodExit for \" + instrMethodClasses[methodId] + \".\" + instrMethodNames[methodId] + \", depth = \" + ti.stackDepth + \", id = \" + (int) methodId);\n            ti.stackDepth--;\n\n            if (ti.stackDepth < 1) {\n                ti.inCallGraph = false; // We are exiting the marker method of our call subgraph\n            }\n            if (ti.stackDepth <= stackDepthLimit) {\n                writeRetValue(ret, ti);\n                writeTimeStampedEvent(MARKER_EXIT, ti, methodId);\n            }\n            ti.inProfilingRuntimeMethod--;\n        }\n    }\n\n    /** Called upon entry into a non-root target application method */\n    public static void methodEntry(char methodId) {\n        if (recursiveInstrumentationDisabled) {\n            return; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.isInitialized() && ti.inCallGraph && (ti.rootMethodStackDepth > 0)) {\n            if (ti.inProfilingRuntimeMethod > 0) {\n                return;\n            }\n\n            ti.inProfilingRuntimeMethod++;\n            //System.out.println(\"++++++methodEntry, depth = \" + ti.stackDepth + \", id = \" + (int) methodId);\n\n            if (ti.stackDepth <= stackDepthLimit) {\n                // See comment marked with (***)\n                int methodIdInt = methodId&0xff;\n                methodIdInt |= methodId&0xff00;\n\n                // Now check if it's the first invocation of this method, and if so, perform instrumentation of nearest callees\n                if (!instrMethodInvoked[methodIdInt]) {\n                    instrMethodInvoked[methodIdInt] = true; // Mark this method as invoked\n                    firstTimeMethodInvoke(ti, methodId);\n                }\n\n                writeTimeStampedEvent(METHOD_ENTRY, ti, methodId);\n            }\n            ti.stackDepth++;\n            ti.inProfilingRuntimeMethod--;\n        }\n    }\n\n    /** Called upon exit from the method. */\n    public static void methodExit(char methodId) {\n        if (recursiveInstrumentationDisabled) {\n            return; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.isInitialized() && ti.inCallGraph && (ti.rootMethodStackDepth > 0)) { // ti == null may happen if instrumentation has been removed or data collectors reset\n\n            if (ti.inProfilingRuntimeMethod > 0) {\n                return;\n            }\n\n            ti.inProfilingRuntimeMethod++;\n\n            //System.out.println(\"------methodExit, depth = \" + ti.stackDepth + \", id = \" + (int) methodId);\n            if (ti.rootMethodStackDepth == ti.stackDepth) {\n                ti.rootMethodStackDepth = 0;\n            }\n\n            ti.stackDepth--;\n\n            if (ti.stackDepth < 1) {\n                ti.inCallGraph = false; // We are exiting the root method of our call subgraph\n                writeTimeStampedEvent(ROOT_EXIT, ti, methodId);\n            } else if (ti.rootMethodStackDepth == 0) { // We are exiting the root method, which was under marker method\n                writeTimeStampedEvent(ROOT_EXIT, ti, methodId);\n            } else if (ti.stackDepth <= stackDepthLimit) {\n                writeTimeStampedEvent(METHOD_EXIT, ti, methodId);\n            }\n\n            ti.inProfilingRuntimeMethod--;\n        }\n    }\n\n    public static void resumeActiveTimers() {\n        writeTimeStampedEvent(THREADS_RESUMED, null, (char) 0); // FIXME: see above\n        changeAllThreadsInProfRuntimeMethodStatus(-1); // See the comment in suspendActiveTimers()\n        recursiveInstrumentationDisabled = false;\n    }\n\n    /** Called upon entry into a root target application method */\n    public static void rootMethodEntry(char methodId) {\n        if (recursiveInstrumentationDisabled) {\n            return; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        ProfilerServer.notifyClientOnResultsAvailability();\n\n        if (ti.isInitialized() && !ti.inCallGraph && (ti.stackDepth > 0)) {\n            ti.inCallGraph = true;\n            methodEntry(methodId);\n            ti.inCallGraph = false;\n\n            return;\n        }\n\n        if (ti.isInitialized() && ti.inCallGraph && (ti.rootMethodStackDepth > 0)) {\n            methodEntry(methodId);\n        } else { // Entered the root method from outside this call subgraph\n                 //if (instrMethodClasses != null && methodId < instrMethodClasses.length) System.out.println(\"++++++Root methodEntry for \" + instrMethodClasses[methodId] + \".\" + instrMethodNames[methodId] + \", thread = \" + Thread.currentThread());\n                 //else System.out.println(\"++++++Root methodEntry for methodId = \" + (int)methodId + \", thread = \" + Thread.currentThread());\n\n            if (!ti.isInitialized()) {\n                if ((nProfiledThreadsAllowed > 0) && !ThreadInfo.isCurrentThreadProfilerServerThread()) {\n                    ti.initialize();\n                    ti.useEventBuffer();\n\n                    synchronized (eventBuffer) { // Make this happen atomically wrt. other operations on eventBuffer, such as reset collectors\n                        nProfiledThreadsAllowed--;\n                        ti.inProfilingRuntimeMethod++;\n\n                        if (!ProfilerServer.startProfilingPointsActive()) {\n                            ti.inCallGraph = true;\n                        }\n\n                        writeThreadCreationEvent(ti);\n                    }\n                } else {\n                    return;\n                }\n            } else {\n                ti.inProfilingRuntimeMethod++;\n\n                if (ti.stackDepth == 0 && !ProfilerServer.startProfilingPointsActive()) {\n                    ti.inCallGraph = true;\n                }\n            }\n\n            // See comment marked with (***)\n            int methodIdInt = methodId&0xff;\n            methodIdInt |= methodId&0xff00;\n            \n            // Check if it's the first invocation of this method, and if so, perform instrumentation of its immediate callees\n            if (!instrMethodInvoked[methodIdInt]) {\n                instrMethodInvoked[methodIdInt] = true;\n                if (enableFirstTimeMethodInvoke) externalActionsHandler.handleFirstTimeMethodInvoke(methodId);\n            }\n\n            ti.stackDepth++; //= 1;  // This is the logical stack depth\n            writeTimeStampedEvent(ROOT_ENTRY, ti, methodId);\n\n            ti.rootMethodStackDepth = ti.stackDepth;\n            ti.inProfilingRuntimeMethod--;\n        }\n    }\n\n    public static void suspendActiveTimers() {\n        changeAllThreadsInProfRuntimeMethodStatus(+1); // In case any instrumented method is called while we perform profiler work on behalf of this thread.\n        recursiveInstrumentationDisabled = true;\n        writeTimeStampedEvent(THREADS_SUSPENDED, null, (char) 0); // FIXME: need a special event writing method or something\n    }\n\n    protected static void clearDataStructures() {\n        ProfilerRuntimeCPU.clearDataStructures();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeCPUSampledInstr.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\n/**\n * This class contains the actual methods for sampled instrumentation recursive CPU profiling, calls to which are injected\n * into the target application (TA) bytecodes when they are instrumented.\n *\n * methodEntry: if taking timestamp (in new sampling slot), time is charged to method being left\n * methodExit: if taking timestamp (in new sampling slot), time is charged to method being exited\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class ProfilerRuntimeCPUSampledInstr extends ProfilerRuntimeCPU {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    //------------------------------------------- Support classes --------------------------------------------------\n\n    /** A thread that periodically sets the sample flag for worker threads */\n    static class TimeSampler extends SamplingThread {\n\n        TimeSampler(int sampilingInterval) {\n            super(sampilingInterval);\n            setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + \" 9\"); // NOI18N\n       }\n\n        void sample() {\n            ThreadInfo.setSampleDueForAllThreads();\n        }\n\n    }\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    protected static int samplingInterval = 10;\n    private static SamplingThread st;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void setSamplingInterval(int v) {\n        samplingInterval = v;\n    }\n\n    public static void enableProfiling(boolean v) {\n        if (v) {\n            createNewDataStructures();\n            ProfilerRuntimeCPU.enableProfiling(v);\n        } else {\n            ProfilerRuntimeCPU.enableProfiling(v);\n            clearDataStructures();\n        }\n    }\n\n    // ---------------------------------- Profile Data Acquisition --------------------------------------\n    /** Called upon entry into a special root method used for */\n    public static void markerMethodEntry(char methodId) {\n        if (recursiveInstrumentationDisabled) {\n            return; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        //if (instrMethodClasses != null && methodId < instrMethodClasses.length) System.out.println(\"++++++Marker methodEntry for \" + instrMethodClasses[methodId] + \".\" + instrMethodNames[methodId] + \", thread = \" + Thread.currentThread());\n        //else System.out.println(\"++++++Marker methodEntry for methodId = \" + (int)methodId + \", thread = \" + Thread.currentThread());\n        if (!ti.isInitialized()) {\n            if ((nProfiledThreadsAllowed > 0) && !ThreadInfo.isCurrentThreadProfilerServerThread()) {\n                ti.initialize();\n                ti.useEventBuffer();\n\n                synchronized (eventBuffer) { // Make this happen atomically wrt. other operations on eventBuffer, such as reset collectors\n                    nProfiledThreadsAllowed--;\n                    ti.inProfilingRuntimeMethod++;\n                    ti.inCallGraph = true;\n                    writeThreadCreationEvent(ti);\n                }\n            } else {\n                return;\n            }\n        } else {\n            ti.inProfilingRuntimeMethod++;\n            ti.inCallGraph = true;\n        }\n\n        if (ti.stackDepth <= stackDepthLimit) {\n            // when methodId > 64K/2 is passed here using our instrumentation's sipush command at the call site, \n            // it's treated here as a signed integer. Thus without\n            // the below fix we can get e.g. an ArrayIndexOutOfBoundsException(-32768) when methodId == 32768 (***)\n            int methodIdInt = methodId&0xff;\n            methodIdInt |= methodId&0xff00;\n\n            if (!instrMethodInvoked[methodIdInt]) {\n                instrMethodInvoked[methodIdInt] = true; // Mark this method as invoked\n                if (ti.rootMethodStackDepth > 0) { // marker method under root method - perform instrumentation of nearest callees\n                    firstTimeMethodInvoke(ti, methodId);\n                }\n            }\n\n            ProfilerServer.notifyClientOnResultsAvailability();\n            writeParametersEvent(ti);\n            if (ti.stackDepth > 0) {\n                if (!ti.sampleDue) {\n                    writeUnstampedEvent(MARKER_ENTRY_UNSTAMPED, ti, methodId);\n                } else {\n                    writeTimeStampedEvent(MARKER_ENTRY, ti, methodId);\n                    ti.sampleDue = false;\n                }\n            } else {\n                writeTimeStampedEvent(MARKER_ENTRY, ti, methodId);\n            }\n        }\n        ti.stackDepth++; //= 1;  // This is the logical stack depth\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    /** Called upon exit from the marker method. */\n    public static void markerMethodExit(char methodId) {\n      markerMethodExit(NO_RET_VALUE, methodId);\n    }\n    \n    /** Called upon exit from the marker method. */\n    public static void markerMethodExit(Object ret, char methodId) {\n        if (recursiveInstrumentationDisabled) {\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.isInitialized() && ti.inCallGraph) { // ti == null may happen if instrumentation has been removed or data collectors reset\n\n            if (ti.inProfilingRuntimeMethod > 0) {\n                return;\n            }\n\n            ti.inProfilingRuntimeMethod++;\n\n            //System.out.println(\"------markerMethodExit for \" + instrMethodClasses[methodId] + \".\" + instrMethodNames[methodId] + \", depth = \" + ti.stackDepth + \", id = \" + (int) methodId);\n            ti.stackDepth--;\n\n            if (ti.stackDepth < 1) {\n                ti.inCallGraph = false; // We are exiting the marker method of our call subgraph\n                writeRetValue(ret, ti);\n                writeTimeStampedEvent(MARKER_EXIT, ti, methodId);\n            } else if (ti.stackDepth <= stackDepthLimit) {\n                if (!ti.sampleDue) {\n                    writeRetValue(ret, ti);\n                    writeUnstampedEvent(MARKER_EXIT_UNSTAMPED, ti, methodId);\n                } else {\n                    writeRetValue(ret, ti);\n                    writeTimeStampedEvent(MARKER_EXIT, ti, methodId);\n                    ti.sampleDue = false;\n                }\n            }\n\n            ti.inProfilingRuntimeMethod--;\n        }\n    }\n\n    /** Called upon entry into a non-root target application method */\n    public static void methodEntry(char methodId) {\n        if (recursiveInstrumentationDisabled) {\n            return; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.isInitialized() && ti.inCallGraph && (ti.rootMethodStackDepth > 0)) {\n            if (ti.inProfilingRuntimeMethod > 0) {\n                return;\n            }\n\n            ti.inProfilingRuntimeMethod++;\n            //System.out.println(\"++++++methodEntry, depth = \" + ti.stackDepth + \", id = \" + (int) methodId);\n\n            if (ti.stackDepth <= stackDepthLimit) {\n                // See comment marked with (***)\n                int methodIdInt = methodId&0xff;\n                methodIdInt |= methodId&0xff00;\n\n                // Now check if it's the first invocation of this method, and if so, perform instrumentation of nearest callees\n                if (!instrMethodInvoked[methodIdInt]) {\n                    instrMethodInvoked[methodIdInt] = true;\n                    firstTimeMethodInvoke(ti, methodId);\n                }\n\n                if (!ti.sampleDue) {\n                    if (methodId <= MAX_METHOD_ID_FOR_COMPACT_FORMAT) {\n                        writeCompactEvent(ti, (char) (METHOD_ENTRY_COMPACT_MASK | methodId));\n                    } else {\n                        writeUnstampedEvent(METHOD_ENTRY_UNSTAMPED, ti, methodId);\n                    }\n                } else {\n                    writeTimeStampedEvent(METHOD_ENTRY, ti, methodId);\n                    ti.sampleDue = false;\n                }\n            }\n            ti.stackDepth++;\n            ti.inProfilingRuntimeMethod--;\n        }\n    }\n\n    /** Called upon exit from the method. */\n    public static void methodExit(char methodId) {\n        if (recursiveInstrumentationDisabled) {\n            return; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.isInitialized() && ti.inCallGraph && (ti.rootMethodStackDepth > 0)) { // ti == null may happen if instrumentation has been removed or data collectors reset\n\n            if (ti.inProfilingRuntimeMethod > 0) {\n                return;\n            }\n\n            ti.inProfilingRuntimeMethod++;\n\n            //System.out.println(\"------methodExit, depth = \" + ti.stackDepth + \", id = \" + (int) methodId);\n            if (ti.rootMethodStackDepth == ti.stackDepth) {\n                ti.rootMethodStackDepth = 0;\n            }\n\n            ti.stackDepth--;\n\n            if (ti.stackDepth < 1) {\n                ti.inCallGraph = false; // We are exiting the root method of our call subgraph\n                writeTimeStampedEvent(ROOT_EXIT, ti, methodId);\n            } else if (ti.rootMethodStackDepth == 0) { // We are exiting the root method, which was under marker method\n                writeTimeStampedEvent(ROOT_EXIT, ti, methodId);\n            } else if (ti.stackDepth <= stackDepthLimit) {\n                if (!ti.sampleDue) {\n                    // short path: not taking time stamp\n\n                    // See comment marked with (***)\n                    methodId = (char) ((int) methodId);\n\n                    if (methodId <= MAX_METHOD_ID_FOR_COMPACT_FORMAT) {\n                        writeCompactEvent(ti, (char) (METHOD_EXIT_COMPACT_MASK | methodId));\n                    } else {\n                        writeUnstampedEvent(METHOD_EXIT_UNSTAMPED, ti, methodId);\n                    }\n                } else {\n                    writeTimeStampedEvent(METHOD_EXIT, ti, methodId);\n                    ti.sampleDue = false;\n                }\n            }\n\n            ti.inProfilingRuntimeMethod--;\n        }\n    }\n\n    /** Called upon entry into a root target application method */\n    public static void rootMethodEntry(char methodId) {\n        if (recursiveInstrumentationDisabled) {\n            return; // See the comment at the recursiveInstrumentationDisabled variable declaration\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        ProfilerServer.notifyClientOnResultsAvailability();\n\n        if (ti.isInitialized() && !ti.inCallGraph && (ti.stackDepth > 0)) {\n            ti.inCallGraph = true;\n            methodEntry(methodId);\n            ti.inCallGraph = false;\n\n            return;\n        }\n\n        if (ti.isInitialized() && ti.inCallGraph && (ti.rootMethodStackDepth > 0)) {\n            methodEntry(methodId);\n        } else { // Entered the root method from outside this call subgraph\n                 //if (instrMethodClasses != null && methodId < instrMethodClasses.length) System.out.println(\"++++++Root methodEntry for \" + instrMethodClasses[methodId] + \".\" + instrMethodNames[methodId] + \", thread = \" + Thread.currentThread());\n                 //else System.out.println(\"++++++Root methodEntry for methodId = \" + (int)methodId + \", thread = \" + Thread.currentThread());\n\n            if (!ti.isInitialized()) {\n                if ((nProfiledThreadsAllowed > 0) && !ThreadInfo.isCurrentThreadProfilerServerThread()) {\n                    ti.initialize();\n                    ti.useEventBuffer();\n\n                    synchronized (eventBuffer) { // Make this happen atomically wrt. other operations on eventBuffer, such as reset collectors\n                        nProfiledThreadsAllowed--;\n                        ti.inProfilingRuntimeMethod++;\n\n                        if (!ProfilerServer.startProfilingPointsActive()) {\n                            ti.inCallGraph = true;\n                        }\n\n                        writeThreadCreationEvent(ti);\n                    }\n                } else {\n                    return;\n                }\n            } else {\n                ti.inProfilingRuntimeMethod++;\n\n                if (ti.stackDepth == 0 && !ProfilerServer.startProfilingPointsActive()) {\n                    ti.inCallGraph = true;\n                }\n            }\n\n            // See comment marked with (***)\n            int methodIdInt = methodId&0xff;\n            methodIdInt |= methodId&0xff00;\n            \n            // Check if it's the first invocation of this method, and if so, perform instrumentation of its immediate callees\n            if (!instrMethodInvoked[methodIdInt]) {\n                instrMethodInvoked[methodIdInt] = true;\n                if (enableFirstTimeMethodInvoke) externalActionsHandler.handleFirstTimeMethodInvoke(methodId);\n            }\n\n            ti.stackDepth++; //= 1;  // This is the logical stack depth\n            writeTimeStampedEvent(ROOT_ENTRY, ti, methodId);\n            ti.rootMethodStackDepth = ti.stackDepth;\n            ti.inProfilingRuntimeMethod--;\n        }\n    }\n\n    protected static void clearDataStructures() {\n        ProfilerRuntimeCPU.clearDataStructures();\n\n        if (st != null) {\n            st.terminate();\n        }\n    }\n\n    protected static void createNewDataStructures() {\n        ProfilerRuntimeCPU.createNewDataStructures();\n        st = new TimeSampler(samplingInterval);\n        st.start();\n    }\n\n    // ---------------------------------- Writing profiler events --------------------------------------  \n\n    // In order to optimize usage of the event buffer, we exploit the facts that:\n    // (1) We have just a handful of different events, and thus their normal codes are small numbers, that need a few bits.\n    // (2) We rarely instrument more than a few thousand methods, so out of 16 bits of char methodId the upper two are usually unused\n    // (3) Just two events, method entry and method exit, happen ~3 orders of magnitude more often than others.\n    // (4) When performing sampled instrumentation profiling, most of method entry/exit events don't have a timestamp.\n    // Given all these observations, we can encode unstamped method entry/exit events with method id <= MAX_METHOD_ID_FOR_COMPACT_FORMAT\n    // (equal to 0x3FFF, i.e. not using the upper two bits) as just a single char. The uppermost bit determines if the char\n    // corresponds to a full event stored in the compact format, or to just an event code. The second bit from the top determines\n    // the actual event - method entry or method exit. Subsequent bits are the method id.\n\n    /** Write a two-byte event, such as unstamped method entry/exit in compact format. */\n    static void writeCompactEvent(ThreadInfo ti, char event) {\n        // if (printEvents) System.out.println(\"*** Writing compact event \" + (int) event);\n        ti.evBuf[ti.evBufPos++] = (byte) ((event >> 8) & 0xFF);\n        ti.evBuf[ti.evBufPos++] = (byte) ((event) & 0xFF);\n\n        if (ti.evBufPos > ThreadInfo.evBufPosThreshold) {\n            copyLocalBuffer(ti);\n        }\n    }\n\n    /** Write an unstamped event, such as method entry/exit for a method whose id is > MAX_METHOD_ID_FOR_COMPACT_FORMAT */\n    static void writeUnstampedEvent(byte eventType, ThreadInfo ti, char methodId) {\n        // if (printEvents) System.out.println(\"*** Writing unstamped event \" + (int) eventType + \", metodId = \" + (int)methodId);\n        byte[] evBuf = ti.evBuf;\n        int curPos = ti.evBufPos; // It's important to use a local copy for evBufPos, so that evBufPos is at event boundary at any moment\n        evBuf[curPos++] = eventType;\n        evBuf[curPos++] = (byte) ((methodId >> 8) & 0xFF);\n        evBuf[curPos++] = (byte) ((methodId) & 0xFF);\n        ti.evBufPos = curPos;\n\n        if (curPos > ThreadInfo.evBufPosThreshold) {\n            copyLocalBuffer(ti);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeMemory.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport org.graalvm.visualvm.lib.jfluid.server.system.Classes;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Stacks;\nimport java.util.HashMap;\nimport java.util.Map;\n\n\n/**\n * This class contains methods and data structures that are common for both modes of memory profiling - object\n * allocation and object liveness.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class ProfilerRuntimeMemory extends ProfilerRuntime {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    protected static final int MAX_STACK_FRAMES = 100; // Maximum number of stack frames that we can sample\n    protected static final int NO_OF_PROFILER_FRAMES = 3; // Number of our own frames on stack when we take a stack sample\n    protected static int[] allocatedInstancesCount;\n    protected static int allocatedInstArrayLength;\n    protected static short[] allocatedInstThreshold;\n    protected static char[] objectSize;\n    protected static short samplingInterval;\n    protected static int stackSamplingDepth;\n    static final Object classIdMapLock = new Object();\n    private static int currentStackDepth;\n    private static int[] stackFrameIds;\n    private static Map classIdMap;\n    private static volatile boolean resultsAvailable;\n    private static final boolean DEBUG = false;\n\n    // -------------------------------------- Miscellaneous support routines ------------------------------------------\n    private static long randSeed;\n    private static int bits;\n    private static short samplingIntervalBase;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void setAllocatedInstancesCountArray(int[] aic) {\n        allocatedInstancesCount = aic;\n\n        if (aic == null) {\n            allocatedInstThreshold = null;\n            objectSize = null;\n            stackFrameIds = null;\n            Stacks.clearNativeStackFrameBuffer();\n\n            return;\n        } else if (allocatedInstArrayLength < aic.length) {\n            short[] oldThresh = (allocatedInstThreshold != null) ? allocatedInstThreshold : null;\n            allocatedInstThreshold = new short[aic.length];\n\n            if (oldThresh != null) {\n                System.arraycopy(oldThresh, 0, allocatedInstThreshold, 0, allocatedInstArrayLength);\n            }\n\n            char[] oldObjectSize = (objectSize != null) ? objectSize : null;\n            objectSize = new char[aic.length];\n\n            if (oldObjectSize != null) {\n                System.arraycopy(oldObjectSize, 0, objectSize, 0, allocatedInstArrayLength);\n            }\n\n            allocatedInstArrayLength = aic.length;\n        }\n    }\n\n    /** Negative parameter means the depth is not limited. val == 0 means we should not take stack samples */\n    public static void setStackSamplingDepth(int val) {\n        if (val < 0) {\n            val = MAX_STACK_FRAMES;\n        } else if (val > 0) {\n            val += NO_OF_PROFILER_FRAMES; // Top frames are always our own methods\n\n            if (val > MAX_STACK_FRAMES) {\n                val = MAX_STACK_FRAMES;\n            }\n        } else {\n            currentStackDepth = 0;\n        }\n\n        stackSamplingDepth = val;\n    }\n\n    public static void setSamplingInterval(short val) {\n        samplingInterval = val;\n        initRandomGenerator();\n    }\n\n    /** Memory profiling-specific reset collectors functionality. */\n    public static void resetProfilerCollectors(int instrType) {\n        if (allocatedInstancesCount != null) {\n            for (int i = 0; i < allocatedInstancesCount.length; i++) {\n                allocatedInstancesCount[i] = 0;\n                allocatedInstThreshold[i] = 0;\n            }\n        }\n\n        if (instrType == INSTR_OBJECT_LIVENESS) {\n            ProfilerRuntimeObjLiveness.resetProfilerCollectors();\n        }\n\n        classIdMap = new HashMap();\n        resultsAvailable = false;\n    }\n\n    public static void traceVMObjectAlloc(Object instance, Class clazz) {\n        if ((classIdMap == null) || ThreadInfo.profilingSuspended() || ThreadInfo.isProfilerServerThread(Thread.currentThread())) {\n            // Avoid counting objects allocated by our own agent threads, or by this method's callees\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n        int classId;\n        boolean isObjectLiveness;\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        if (!ti.isInitialized()) {\n            ti.initialize();\n            if (lockContentionMonitoringEnabled) writeThreadCreationEvent(ti);\n        }\n\n        ti.inProfilingRuntimeMethod++;\n        classId = getClassId(clazz);\n        if (classId == -1) {\n            // System.err.println(\"*** JFluid warning: Invalid classId for class:\"+classNameId);\n            ti.inProfilingRuntimeMethod--;\n\n            return;\n        }\n\n        isObjectLiveness = ProfilerInterface.getCurrentInstrType() == INSTR_OBJECT_LIVENESS;\n        ti.inProfilingRuntimeMethod--;\n\n        if (isObjectLiveness) {\n            ProfilerRuntimeObjLiveness.traceObjAlloc(instance, (char)classId);\n        } else {\n            ProfilerRuntimeObjAlloc.traceObjAlloc(instance, (char)classId);\n        }\n    }\n\n    static int getClassId(Class clazz) {\n        String className = clazz.getName();\n        int definingClassLoaderId = ClassLoaderManager.registerLoader(clazz);\n        String classNameId = new StringBuffer(className).append('#').append(definingClassLoaderId).toString();\n        Integer classIdInt;\n        \n        synchronized (classIdMapLock) {\n            classIdInt = (Integer) classIdMap.get(classNameId);\n        }\n\n        if (classIdInt == null) {\n            int newClassId = externalActionsHandler.handleFirstTimeVMObjectAlloc(className, definingClassLoaderId);\n\n            classIdInt = new Integer(newClassId);\n            synchronized (classIdMapLock) {\n                classIdMap.put(classNameId, classIdInt);\n            }\n            if (newClassId == -1) {\n                if (DEBUG) System.out.println(\"ProfilerRuntimeMemory.DEBUG: Invalid classId for class:\"+classNameId);\n//                if (classNameId.startsWith(\"org.graalvm.visualvm.lib.jfluid\")) Thread.dumpStack();\n//                if (classNameId.startsWith(\"[\")) Thread.dumpStack();\n            }\n        }\n        return classIdInt.intValue();\n    }\n    \n    static boolean isInternalClass(Class clazz) {\n        return clazz == ThreadInfo.class || clazz == ThreadInfo[].class;\n    }\n    \n    // ------------------------------------------ Stack trace obtaining -----------------------------------------------\n\n    /** This is used in Object Allocation profiling mode */\n    protected static synchronized void getAndSendCurrentStackTrace(int classId, long objSize) {\n        if (eventBuffer == null) {\n            return; // Chances are that instrumentation has been removed while we were executing instrumentation code\n        }\n\n        synchronized (eventBuffer) { // Note that we have to use synchronization here due to the static stackFrameIds[] array\n\n            if (stackSamplingDepth != 0) {\n                currentStackDepth = Stacks.getCurrentStackFrameIds(Thread.currentThread(), stackSamplingDepth, stackFrameIds);\n            }\n\n            writeObjAllocStackTraceEvent(classId, objSize);\n        }\n    }\n\n    /** This is used in Object Liveness profiling mode */\n    protected static synchronized void getAndSendCurrentStackTrace(int classId, char epoch, int objCount, long objSize) {\n        if (eventBuffer == null) {\n            return; // Chances are that instrumentation has been removed while we were executing instrumentation code\n        }\n\n        synchronized (eventBuffer) { // Note that we have to use synchronization here due to the static stackFrameIds[] array\n\n            if (stackSamplingDepth != 0) {\n                currentStackDepth = Stacks.getCurrentStackFrameIds(Thread.currentThread(), stackSamplingDepth, stackFrameIds);\n            }\n\n            writeObjLivenessStackTraceEvent(classId, epoch, objCount, objSize);\n        }\n    }\n\n    protected static long getCachedObjectSize(int classInt, Object object) {\n        long objSize = objectSize[classInt];\n\n        if (objSize <= 1) { // An array (variable size, value 1) or cached size unset (value 0)\n\n            if (object == null) { // Should not happen, this is a debugging/critical error statement\n                System.err.println(\"*** JFluid critical error: received null object for classId = \" + classInt\n                                   + \" in getCachedObjectSize\"); // NOI18N\n                Thread.dumpStack();\n                System.err.println(\"*** End JFluid critical error message ---------------------------\"); // NOI18N\n            }\n\n            if (objSize == 0) { // Size not determined yet\n                objSize = Classes.getObjectSize(object);\n\n                if (object.getClass().isArray() || (objSize > 0xFFFF)) {\n                    objectSize[classInt] = 1; // Size will be determined separately every time\n                } else {\n                    objectSize[classInt] = (char) objSize; // Size will be used for all objects of this class\n                }\n            } else {\n                objSize = Classes.getObjectSize(object);\n            }\n        }\n\n        return objSize;\n    }\n\n    protected static void clearDataStructures() {\n        ProfilerRuntime.clearDataStructures();\n        allocatedInstancesCount = null;\n        stackFrameIds = null;\n        Stacks.clearNativeStackFrameBuffer();\n    }\n\n    protected static void createNewDataStructures() {\n        ProfilerRuntime.createNewDataStructures();\n        stackFrameIds = new int[MAX_STACK_FRAMES];\n        Stacks.createNativeStackFrameBuffer(MAX_STACK_FRAMES);\n        classIdMap = new HashMap();\n        resultsAvailable = false;\n    }\n\n    protected static void enableProfiling(boolean v) {\n        // Doesn't call createNewDataStructures() or clearDataStructures() since this is an \"abstract\" class\n    }\n\n    protected static void initRandomGenerator() {\n        randSeed = System.currentTimeMillis();\n\n        if (samplingInterval == 1) {\n            return;\n        } else if ((samplingInterval == 2) || (samplingInterval == 3)) {\n            bits = 1;\n            samplingIntervalBase = (short) (samplingInterval - 1);\n\n            return;\n        } else {\n            bits = 1;\n\n            int val = 1; // That should be the nearest power of two smaller than samplingInterval\n\n            while (true) {\n                int newVal = val << 1;\n\n                if (newVal < samplingInterval) {\n                    bits++;\n                    val = newVal;\n                } else {\n                    break;\n                }\n            }\n\n            // Set samplingIntervalBase to (samplingInterval - val/2), and make bits correspond to val/2\n            samplingIntervalBase = (short) (samplingInterval - (val >> 1));\n            bits -= 1;\n        }\n    }\n\n    protected static short nextRandomizedInterval() {\n        if (samplingInterval == 1) {\n            return 1;\n        }\n\n        // This is copied from 'int java.util.Random.next(int bits)'\n        randSeed = ((randSeed * 0x5DEECE66DL) + 0xBL) & ((1L << 48) - 1);\n\n        return (short) (samplingIntervalBase + ((int) (randSeed >>> (48 - bits))));\n    }\n\n    // ---------------------------------------- Writing profiler events -----------------------------------------\n\n    /** Note that there is no synchronized(eventBuffer) in this method, since synchronization is already required by its callers */\n    protected static void writeObjAllocStackTraceEvent(int classId, long objSize) {\n        if (eventBuffer == null) {\n            return; // Instrumentation removal happened when we were in instrumentation \n        }\n\n        if (currentStackDepth != 0) {\n            currentStackDepth -= NO_OF_PROFILER_FRAMES; // Top frames are our own methods\n        }\n\n        if (!resultsAvailable) {\n            resultsAvailable = true;\n            ProfilerServer.notifyClientOnResultsAvailability();\n        }\n\n        int curPos = globalEvBufPos;\n\n        if ((curPos + 16 + (currentStackDepth * 4)) > globalEvBufPosThreshold) { // Dump the buffer\n            externalActionsHandler.handleEventBufferDump(eventBuffer, 0, curPos);\n            curPos = 0;\n        }\n\n        eventBuffer[curPos++] = OBJ_ALLOC_STACK_TRACE;\n        eventBuffer[curPos++] = (byte) ((classId >> 8) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((classId) & 0xFF);\n\n        eventBuffer[curPos++] = (byte) ((objSize >> 32) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((objSize >> 24) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((objSize >> 16) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((objSize >> 8) & 0xFF);\n        eventBuffer[curPos++] = (byte) (objSize & 0xFF);\n\n        curPos = writeStack(curPos);\n        globalEvBufPos = curPos;\n    }\n\n    protected static void writeObjGCEvent(long objectId) {\n        if (eventBuffer == null) {\n            return; // Instrumentation removal happened when we were in instrumentation \n        }\n\n        synchronized (eventBuffer) {\n            int curPos = globalEvBufPos;\n\n            if (curPos > globalEvBufPosThreshold) { // Dump the buffer\n                externalActionsHandler.handleEventBufferDump(eventBuffer, 0, curPos);\n                curPos = 0;\n            }\n\n            eventBuffer[curPos++] = OBJ_GC_HAPPENED;\n            eventBuffer[curPos++] = (byte) ((objectId >> 56) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((objectId >> 48) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((objectId >> 40) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((objectId >> 32) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((objectId >> 24) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((objectId >> 16) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((objectId >> 8) & 0xFF);\n            eventBuffer[curPos++] = (byte) (objectId & 0xFF);\n            globalEvBufPos = curPos;\n        }\n    }\n\n    /** Note that there is no synchronized(eventBuffer) in this method, since synchronization is already required by its callers */\n    protected static void writeObjLivenessStackTraceEvent(int classId, char epoch, int objCount, long objSize) {\n        if (eventBuffer == null) {\n            return; // Instrumentation removal happened when we were in instrumentation \n        }\n\n        if (currentStackDepth != 0) {\n            currentStackDepth -= NO_OF_PROFILER_FRAMES; // Top 4 frames are our own methods\n        }\n\n        if (!resultsAvailable) {\n            resultsAvailable = true;\n            ProfilerServer.notifyClientOnResultsAvailability();\n        }\n\n        int curPos = globalEvBufPos;\n\n        if ((curPos + 24 + (currentStackDepth * 4)) > globalEvBufPosThreshold) { // Dump the buffer\n            externalActionsHandler.handleEventBufferDump(eventBuffer, 0, curPos);\n            curPos = 0;\n        }\n\n        eventBuffer[curPos++] = OBJ_LIVENESS_STACK_TRACE;\n        eventBuffer[curPos++] = (byte) ((classId >> 8) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((classId) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((epoch >> 8) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((epoch) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((objCount >> 24) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((objCount >> 16) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((objCount >> 8) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((objCount) & 0xFF);\n\n        eventBuffer[curPos++] = (byte) ((objSize >> 32) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((objSize >> 24) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((objSize >> 16) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((objSize >> 8) & 0xFF);\n        eventBuffer[curPos++] = (byte) (objSize & 0xFF);\n\n        curPos = writeStack(curPos);\n        globalEvBufPos = curPos;\n    }\n\n    private static int writeStack(int curPos) {\n        eventBuffer[curPos++] = (byte) ((currentStackDepth >> 16) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((currentStackDepth >> 8) & 0xFF);\n        eventBuffer[curPos++] = (byte) ((currentStackDepth) & 0xFF);\n\n        /// A variant when we send non-reversed call graph\n        //int base = depth + NO_OF_PROFILER_FRAMES - 1;\n        //for (int i = 0; i < depth; i++) {\n        //  eventBuffer[curPos++] = (char) ((stackFrameIds[base-i] >> 16) & 0xFFFF);\n        //  eventBuffer[curPos++] = (char) ((stackFrameIds[base-i]) & 0xFFFF);\n        //}\n        int frameIdx = NO_OF_PROFILER_FRAMES;\n\n        for (int i = 0; i < currentStackDepth; i++) {\n            eventBuffer[curPos++] = (byte) ((stackFrameIds[frameIdx] >> 24) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((stackFrameIds[frameIdx] >> 16) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((stackFrameIds[frameIdx] >> 8) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((stackFrameIds[frameIdx]) & 0xFF);\n            frameIdx++;\n        }\n\n        return curPos;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeObjAlloc.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\n\n/**\n * This class contains instrumentation methods for object allocation profiling.\n *\n * @author Misha Dmitriev\n */\npublic class ProfilerRuntimeObjAlloc extends ProfilerRuntimeMemory {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    protected static boolean objAllocProfilingDisabled = true;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void enableProfiling(boolean v) {\n        if (!v) {\n            objAllocProfilingDisabled = true;\n        }\n\n        if (v) {\n            createNewDataStructures();\n            ProfilerRuntimeMemory.enableProfiling(v);\n        } else {\n            ProfilerRuntimeMemory.enableProfiling(v);\n\n            // Give the threads that are currently executing instrumentation enough time to finish\n            // before we nullify the data structures that are used in instrumentation code.\n            try {\n                Thread.sleep(100);\n            } catch (Exception ex) {\n            }\n\n            clearDataStructures();\n        }\n\n        if (v) {\n            objAllocProfilingDisabled = false;\n        }\n    }\n\n    public static void traceObjAlloc(Object object, char classId) {\n        if (objAllocProfilingDisabled) {\n            return;\n        }\n\n        if (ThreadInfo.profilingSuspended()\n            || ThreadInfo.isCurrentThreadProfilerServerThread()\n            || (classId == 0 && isInternalClass(object.getClass()))) {\n            // Avoid counting objects allocated by our own agent threads, or by this method's callees\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        if (!ti.isInitialized()) {\n            ti.initialize();\n            if (lockContentionMonitoringEnabled) writeThreadCreationEvent(ti);\n        }\n\n        ti.inProfilingRuntimeMethod++;\n\n        int classInt;\n\n        if (classId == 0) {\n            //System.out.println(\"traceObjAlloc(Object object, 0) \"+ object.getClass());\n            classInt = getClassId(object.getClass());\n            if (classInt == -1) {\n                ti.inProfilingRuntimeMethod--;\n                return;\n            }\n        } else {\n            // See comment marked with (***) in ProfilerRuntimeCPUFullInstr\n            classInt = classId&0xff;\n            classInt |= classId&0xff00;\n        }\n        synchronized (allocatedInstancesCount) {\n            allocatedInstancesCount[classInt]++;\n        }\n\n        if (allocatedInstThreshold[classInt] <= 0) {\n            long objSize = getCachedObjectSize(classInt, object);\n            getAndSendCurrentStackTrace(classInt, objSize);\n            allocatedInstThreshold[classInt] = nextRandomizedInterval();\n        }\n\n        allocatedInstThreshold[classInt]--;\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    protected static void clearDataStructures() {\n        ProfilerRuntimeMemory.clearDataStructures();\n    }\n\n    protected static void createNewDataStructures() {\n        ProfilerRuntimeMemory.createNewDataStructures();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeObjLiveness.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport org.graalvm.visualvm.lib.jfluid.server.system.GC;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Threads;\nimport java.lang.ref.ReferenceQueue;\nimport java.lang.ref.WeakReference;\n\n\n/**\n * This class contains instrumentation methods for object liveness profiling.\n *\n * @author Misha Dmitriev\n */\npublic class ProfilerRuntimeObjLiveness extends ProfilerRuntimeMemory {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    // ------------------------------------- Support classes --------------------------------------------------\n    static class ProfilerRuntimeObjLivenessWeakRef extends WeakReference {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        long objId;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ProfilerRuntimeObjLivenessWeakRef(Object obj, ReferenceQueue rq, long objId) {\n            super(obj, rq);\n            this.objId = objId;\n        }\n    }\n\n    /** A thread that waits on a ReferenceQueue managing our marked objects */\n    static class ReferenceManagerThread extends Thread {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private volatile boolean terminated;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ReferenceManagerThread() {\n            ThreadInfo.addProfilerServerThread(this);\n            setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + \" 3\"); // NOI18N\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void run() {\n            while (!terminated) {\n                try {\n                    ProfilerRuntimeObjLivenessWeakRef wr = (ProfilerRuntimeObjLivenessWeakRef) rq.remove(200);\n\n                    if (wr != null && !terminated) {\n                        signalObjGC(wr);\n                    }\n                } catch (InterruptedException ex) { /* Should not happen */\n                }\n            }\n\n            ThreadInfo.removeProfilerServerThread(this);\n        }\n\n        public void terminate() {\n            terminated = true;\n        }\n    }\n\n    /** A hashtable keeping a set of all tracked objects */\n    static class WeakRefSet {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private WeakReference[] keys;\n        private int capacity;\n        private int nObjects;\n        private int threshold;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        WeakRefSet() {\n            capacity = 1003;\n            setThreshold();\n            keys = new WeakReference[capacity];\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public synchronized void put(WeakReference key) {\n            if (nObjects > threshold) {\n                rehash();\n            }\n\n            int pos = (key.hashCode() & 0x7FFFFFFF) % capacity;\n\n            while (keys[pos] != null) {\n                pos = (pos + 1) % capacity;\n            }\n\n            keys[pos] = key;\n            nObjects++;\n        }\n\n        public synchronized void remove(WeakReference key) {\n            int pos = (key.hashCode() & 0x7FFFFFFF) % capacity;\n\n            while (keys[pos] != key) {\n                pos = (pos + 1) % capacity;\n            }\n\n            keys[pos] = null;\n            nObjects--;\n        }\n\n        private void setThreshold() {\n            threshold = (capacity * 3) / 4;\n        }\n\n        private void rehash() {\n            WeakReference[] oldKeys = keys;\n            int oldCapacity = capacity;\n            capacity = (capacity * 2) + 1;\n            keys = new WeakReference[capacity];\n\n            for (int i = 0; i < oldCapacity; i++) {\n                if (oldKeys[i] != null) {\n                    int pos = (oldKeys[i].hashCode() & 0x7FFFFFFF) % capacity;\n\n                    while (keys[pos] != null) {\n                        pos = (pos + 1) % capacity;\n                    }\n\n                    keys[pos] = oldKeys[i];\n                }\n            }\n\n            setThreshold();\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    protected static ReferenceQueue rq;\n    private static WeakRefSet objSet;\n    private static ReferenceManagerThread rmt;\n    protected static boolean runGCOnGetResults;\n    protected static boolean objLivenessProfilingDisabled = true;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void enableProfiling(boolean v) {\n        if (v) {\n            createNewDataStructures();\n            // activateGCEpochCounter(true);  We don't do this anymore, it's activated forever in profiler.server.Monitors\n            GC.resetGCEpochCounter();\n            ProfilerRuntimeMemory.enableProfiling(true);\n            objLivenessProfilingDisabled = false;\n        } else {\n            objLivenessProfilingDisabled = true;\n            ProfilerRuntimeMemory.enableProfiling(false);\n\n            // Give the threads that are currently executing instrumentation enough time to finish\n            // before we nullify the data structures that are used in instrumentation code.\n            try {\n                Thread.sleep(100);\n            } catch (Exception ex) {\n            }\n\n            clearDataStructures();\n        }\n    }\n\n    public static void resetProfilerCollectors() {\n        if (rmt != null) {\n            GC.runGC();\n            rmt.terminate();\n        }\n\n        createNewDataStructures();\n\n        // We don't reset the epoch counter anymore, since there is still a chance that some objects with a higher\n        // epoch counter are reported after this event, which may confuse the tool. So we keep the ever-growing epoch counter.\n        //GC.resetGCEpochCounter();\n\n        // TODO [ian] - check this furhter - it was reported by Jon Christianssen that objects with high surviving gen\n        // numbers were reported after resetting the results, which he (rightfully so) considered wrong\n    }\n\n    static void signalObjGC(ProfilerRuntimeObjLivenessWeakRef wr) {\n        long objectId = wr.objId;\n        objSet.remove(wr);\n        writeObjGCEvent(objectId);\n    }\n\n    public static void traceObjAlloc(Object object, char classId) {\n        if (objLivenessProfilingDisabled) {\n            return;\n        }\n\n        if (ThreadInfo.profilingSuspended()\n            || ThreadInfo.isCurrentThreadProfilerServerThread()\n            || (classId == 0 && isInternalClass(object.getClass()))) {\n            // Avoid counting objects allocated by our own agent threads, or by this method's callees\n            return;\n        }\n\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n\n        if (!ti.isInitialized()) {\n            ti.initialize();\n            if (lockContentionMonitoringEnabled) writeThreadCreationEvent(ti);\n        }\n\n        if (ti.inProfilingRuntimeMethod > 0) {\n            return;\n        }\n\n        ti.inProfilingRuntimeMethod++;\n\n        int classInt;\n        \n        if (classId == 0) {\n            //System.out.println(\"traceObjAlloc(Object object, 0) \"+ object.getClass());\n            classInt = getClassId(object.getClass());\n            if (classInt == -1) {\n                ti.inProfilingRuntimeMethod--;\n                return;\n            }\n        } else {\n            // See comment marked with (***) in ProfilerRuntimeCPUFullInstr\n            classInt = classId&0xff;\n            classInt |= classId&0xff00;\n        }\n\n        int objCount = 0;\n\n        synchronized (allocatedInstancesCount) {\n            objCount = ++allocatedInstancesCount[classInt];\n        }\n\n        if (allocatedInstThreshold[classInt] <= 0) {\n            //System.out.print(\"+++ Alloc object \"); //System.out.print((int) classId); System.out.print(\" \"); System.out.println(object);\n            char epoch = (char) GC.getCurrentGCEpoch();\n\n            // Generate a 64-bit object id. Make sure the function is the same at the tool side!\n            long objectId = (((long) classInt) << 48) | (((long) epoch) << 32) | ((long) objCount);\n            ProfilerRuntimeObjLivenessWeakRef wr = new ProfilerRuntimeObjLivenessWeakRef(object, rq, objectId);\n            objSet.put(wr);\n\n            long objSize = getCachedObjectSize(classInt, object);\n\n            getAndSendCurrentStackTrace(classInt, epoch, objCount, objSize);\n\n            allocatedInstThreshold[classInt] = nextRandomizedInterval();\n        }\n\n        allocatedInstThreshold[classInt]--;\n        ti.inProfilingRuntimeMethod--;\n    }\n\n    protected static void setRunGCOnGetResults(boolean v) {\n        runGCOnGetResults = v;\n    }\n\n    protected static boolean getRunGCOnGetResults() {\n        return runGCOnGetResults;\n    }\n\n    protected static void clearDataStructures() {\n        ProfilerRuntimeMemory.clearDataStructures();\n\n        if (rmt != null) {\n            GC.runGC();\n            rmt.terminate();\n        }\n\n        rq = null;\n        objSet = null;\n        rmt = null;\n\n        // activateGCEpochCounter(false);  See the comment in enableProfiling() above\n    }\n\n    protected static void createNewDataStructures() {\n        ProfilerRuntimeMemory.createNewDataStructures();\n        rq = new ReferenceQueue();\n        objSet = new WeakRefSet();\n        rmt = new ReferenceManagerThread();\n        Threads.recordAdditionalProfilerOwnThread(rmt);\n        rmt.start();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilerRuntimeSampler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Stacks;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Timers;\n\n/**\n * @author Tomas Hurka\n */\nclass ProfilerRuntimeSampler extends ProfilerRuntime {\n\n    private static Sampling sampling;\n    private static int samplingFrequency = 10;\n\n    static void setSamplngFrequency(int v) {\n        samplingFrequency = v;\n    }\n\n    static class Sampling extends SamplingThread {\n        private int[] states = new int[0];\n        private int[][] methodIds = new int[0][];\n        private Map arrayOffsetMap = new HashMap();\n        private Map threadIdMap = new HashMap();\n        private volatile boolean resetData = false;\n        private boolean sendDataAvailable = true;\n\n        Sampling(int samplingInterval) {\n            super(samplingInterval);\n            setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + \" 10\"); // NOI18N\n        }\n\n        void sample() {\n            Thread[][] newThreads = new Thread[1][];\n            int[][] newStates = new int[1][];\n            int[][][] newMethodIds = new int[1][][];\n            Map newArrayOffsetMap = new HashMap();\n            Map newThreadIdMap = new HashMap();\n            long timestamp;\n\n            if (resetData) {\n                resetProfilerCollectors();\n                resetData = false;\n                sendDataAvailable = true;\n            }\n            Stacks.getAllStackTraces(newThreads, newStates, newMethodIds);\n            timestamp = Timers.getCurrentTimeInCounts();\n\n            if (newThreads[0] != null && eventBuffer != null) { // ignore samples without data\n                synchronized (eventBuffer) {\n                    if (resetData) return;  // skip this sample if the collectors was not reset yet\n                    writeThreadDumpStart(timestamp);\n                    for (int i = 0; i < newThreads[0].length; i++) {\n                        Thread t = newThreads[0][i];\n                        int[] mids = newMethodIds[0][i];\n\n                        if (!ThreadInfo.isProfilerServerThread(t)) {\n                            int status = newStates[0][i];\n                            Long ltid = Long.valueOf(t.getId());\n                            Integer index = (Integer) arrayOffsetMap.get(ltid);\n                            Integer tid = (Integer) threadIdMap.get(ltid);\n\n                            if (index != null) {\n                                if (status == states[index.intValue()] && Arrays.equals(mids,methodIds[index.intValue()])) {\n                                    writeThreadInfoNoChange(tid);\n                                } else {\n                                    writeThreadInfo(tid,status,mids);\n                                }\n                            } else if (status != CommonConstants.THREAD_STATUS_ZOMBIE && mids.length>0) { \n                                // new thread with a stacktrace\n                                ThreadInfo ti = ThreadInfo.getThreadInfo(t);\n                                tid = new Integer(ti.getThreadId());\n                                if (!ti.isInitialized()) {\n                                    ti.initialize();\n                                    ProfilerRuntime.writeThreadCreationEvent(t,tid.intValue());\n                                }\n                                writeThreadInfo(tid,status,mids);\n                            } else { // new thread which is not started yet or it did not ever have stacktrace \n                                continue; \n                            }\n                            newArrayOffsetMap.put(ltid, new Integer(i));\n                            newThreadIdMap.put(ltid,tid);\n                        }\n                    }\n                    writeThreadDumpEnd();\n                }\n                arrayOffsetMap = newArrayOffsetMap;\n                threadIdMap = newThreadIdMap;\n                states = newStates[0];\n                methodIds = newMethodIds[0];\n            }\n        }\n\n        private void resetProfilerCollectors() {\n            arrayOffsetMap = new HashMap();\n            threadIdMap = new HashMap();\n            states = new int[0];\n            methodIds = new int[0][];        \n        }\n         \n        private void writeThreadDumpStart(long absTimeStamp) {\n            if (eventBuffer == null) {\n                return; \n            }\n\n            if (sendDataAvailable) {\n                ProfilerServer.notifyClientOnResultsAvailability();\n                sendDataAvailable = false;\n            }\n\n            int curPos = globalEvBufPos;\n\n            if (curPos + 8 > globalEvBufPosThreshold) { // Dump the buffer\n                externalActionsHandler.handleEventBufferDump(eventBuffer, 0, curPos);\n                curPos = 0;\n            }\n\n            eventBuffer[curPos++] = THREAD_DUMP_START;\n            eventBuffer[curPos++] = (byte) ((absTimeStamp >> 48) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((absTimeStamp >> 40) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((absTimeStamp >> 32) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((absTimeStamp >> 24) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((absTimeStamp >> 16) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((absTimeStamp >> 8) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((absTimeStamp) & 0xFF);\n\n            globalEvBufPos = curPos;\n        }\n              \n        private void writeThreadDumpEnd() {\n            if (eventBuffer == null) {\n                return; \n            }\n\n            int curPos = globalEvBufPos;\n\n            if (curPos + 1 > globalEvBufPosThreshold) { // Dump the buffer\n                externalActionsHandler.handleEventBufferDump(eventBuffer, 0, curPos);\n                curPos = 0;\n            }\n\n            eventBuffer[curPos++] = THREAD_DUMP_END;\n            globalEvBufPos = curPos;\n        }\n\n        private void writeThreadInfoNoChange(Integer tid) {\n            if (eventBuffer == null) {\n                return; \n            }\n\n            int curPos = globalEvBufPos;\n\n            if (curPos + 3 > globalEvBufPosThreshold) { // Dump the buffer\n                externalActionsHandler.handleEventBufferDump(eventBuffer, 0, curPos);\n                curPos = 0;\n            }\n\n            int threadId = tid.intValue();\n            \n            eventBuffer[curPos++] = THREAD_INFO_IDENTICAL;\n            eventBuffer[curPos++] = (byte) ((threadId >> 8) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((threadId) & 0xFF);\n            globalEvBufPos = curPos;\n        }\n\n        private void writeThreadInfo(Integer tid, int status, int[] mids) {\n            if (eventBuffer == null) {\n                return; \n            }\n\n            int curPos = globalEvBufPos;\n\n            if (curPos + 6 + mids.length*4 > globalEvBufPosThreshold) { // Dump the buffer\n                externalActionsHandler.handleEventBufferDump(eventBuffer, 0, curPos);\n                curPos = 0;\n            }\n\n            int threadId = tid.intValue();\n            int stackLen = mids.length;\n            \n            eventBuffer[curPos++] = THREAD_INFO;\n            eventBuffer[curPos++] = (byte) ((threadId >> 8) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((threadId) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((status) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((stackLen >> 8) & 0xFF);\n            eventBuffer[curPos++] = (byte) ((stackLen) & 0xFF);\n            for (int i = 0; i < mids.length; i++) {\n                eventBuffer[curPos++] = (byte) ((mids[i] >> 24) & 255);\n                eventBuffer[curPos++] = (byte) ((mids[i] >> 16) & 255);\n                eventBuffer[curPos++] = (byte) ((mids[i] >> 8) & 255);\n                eventBuffer[curPos++] = (byte) ((mids[i]) & 255);                \n            }\n            globalEvBufPos = curPos;\n        }\n    }\n\n    static void initialize() {\n        sampling = new Sampling(samplingFrequency);\n        sampling.start();\n    }\n\n    public static void shutdown() {\n        sampling.terminate();\n        sampling = null;\n        ProfilerRuntime.clearDataStructures();\n    }\n    \n    static void resetProfilerCollectors() {\n        if (sampling != null) sampling.resetData = true;   \n    }\n}\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilerServer.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CalibrationDataFileIO;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Classes;\nimport org.graalvm.visualvm.lib.jfluid.server.system.GC;\nimport org.graalvm.visualvm.lib.jfluid.server.system.HeapDump;\nimport org.graalvm.visualvm.lib.jfluid.server.system.ThreadDump;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Threads;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Timers;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.*;\nimport java.io.*;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.net.*;\nimport java.text.MessageFormat;\nimport java.util.*;\n\n\n/**\n * This class contains functionality for starting (attaching to) the Target Application (TA), and for\n * communication between the profiling back end and the tool (server and client).\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class ProfilerServer extends Thread implements CommonConstants {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private static class AttachDynamicThread extends Thread {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private int activateCode;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        AttachDynamicThread(int activateCode) {\n            this.setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + \" 5\"); // NOI18N\n            this.activateCode = activateCode;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void run() {\n            try {\n                doActivate(activateCode);\n            } catch (Throwable ex) {\n                System.err.println(\"Profiler dynamic attach initialization failed due to:\"); //NOI18N\n                ex.printStackTrace();\n            }\n        }\n    }\n\n    // Copied from org.openide.util.NbBundle\n    // Does not support branding!\n    private static class LocaleIterator extends Object implements Iterator {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        /**\n         * current locale, and initial locale\n         */\n        private Locale initLocale;\n\n        /**\n         * current locale, and initial locale\n         */\n        private Locale locale;\n\n        /**\n         * the branding string in use\n         */\n        private String branding;\n\n        /**\n         * current suffix which will be returned in next calling nextElement\n         */\n        private String current;\n\n        /**\n         * this flag means, if default locale is in progress\n         */\n        private boolean defaultInProgress = false;\n\n        /**\n         * this flag means, if empty suffix was exported yet\n         */\n        private boolean empty = false;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        /**\n         * Creates new LocaleIterator for given locale.\n         *\n         * @param locale given Locale\n         */\n        LocaleIterator(Locale locale) {\n            this.locale = this.initLocale = locale;\n\n            if (locale.equals(Locale.getDefault())) {\n                defaultInProgress = true;\n            }\n\n            current = '_' + locale.toString(); // NOI18N\n\n            //            if (brandingToken == null) {\n            branding = null;\n\n            //            } else {\n            //                branding = \"_\" + brandingToken; // NOI18N\n            //            }\n\n            //System.err.println(\"Constructed: \" + this);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        /**\n         * Tests if there is any suffix.\n         */\n        public boolean hasNext() {\n            return (current != null);\n        }\n\n        /**\n         * @return next suffix.\n         * @throws NoSuchElementException if there is no more locale suffix.\n         */\n        public Object next() throws NoSuchElementException {\n            if (current == null) {\n                throw new NoSuchElementException();\n            }\n\n            final String ret;\n\n            if (branding == null) {\n                ret = current;\n            } else {\n                ret = branding + current;\n            }\n\n            int lastUnderbar = current.lastIndexOf('_'); // NOI18N\n\n            if (lastUnderbar == 0) {\n                if (empty) {\n                    reset();\n                } else {\n                    current = \"\"; // NOI18N\n                    empty = true;\n                }\n            } else {\n                if (lastUnderbar == -1) {\n                    if (defaultInProgress) {\n                        reset();\n                    } else {\n                        // [PENDING] stuff with trying the default locale\n                        // after the real one does not actually seem to work...\n                        locale = Locale.getDefault();\n                        current = '_' + locale.toString(); // NOI18N\n                        defaultInProgress = true;\n                    }\n                } else {\n                    current = current.substring(0, lastUnderbar);\n                }\n            }\n\n            //System.err.println(\"Returning: `\" + ret + \"' from: \" + this);\n            return ret;\n        }\n\n        public void remove() throws UnsupportedOperationException {\n            throw new UnsupportedOperationException();\n        }\n\n        /**\n         * Finish a series.\n         * If there was a branding prefix, restart without that prefix\n         * (or with a shorter prefix); else finish.\n         */\n        private void reset() {\n            if (branding != null) {\n                current = '_' + initLocale.toString(); // NOI18N\n\n                int idx = branding.lastIndexOf('_'); // NOI18N\n\n                if (idx == 0) {\n                    branding = null;\n                } else {\n                    branding = branding.substring(0, idx);\n                }\n\n                empty = false;\n            } else {\n                current = null;\n            }\n        }\n    }\n\n    /**\n     * A shutdown wait thread\n     */\n    private static class ShutdownWaitThread extends Thread {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ShutdownWaitThread() {\n            setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + \" 7\"); // NOI18N\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void run() {\n            if (preemptExit && connectionOpen) {\n                profilerServer.sendSimpleCmdToClient(Command.SHUTDOWN_INITIATED);\n                waitForShutdownOK();\n                cleanupOnShutdown();\n\n                // ... and proceed with shutdown\n            }\n        }\n    }\n\n    /**\n     * A thread to execute certain commands in (see comments to executeInSeparateThread above)\n     */\n    private class SeparateCmdExecutionThread extends Thread {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private volatile boolean stopped = false;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        SeparateCmdExecutionThread() {\n            ThreadInfo.addProfilerServerThread(this);\n            setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + \" 6\"); // NOI18N\n            setDaemon(true);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void run() {\n            synchronized (execInSeparateThreadLock) {\n                while (true) {\n                    try {\n                        execInSeparateThreadLock.wait();\n                    } catch (InterruptedException ex) {\n                        System.err.println(THREAD_WAIT_EXCEPTION_MSG);\n                    }\n\n                    if (stopped) {\n                        ThreadInfo.removeProfilerServerThread(this);\n                        return;\n                    }\n\n                    int opCode = execInSeparateThreadOpCode;\n\n                    switch (opCode) {\n                        case Command.DUMP_EXISTING_RESULTS:\n                        case Command.DUMP_EXISTING_RESULTS_LIVE:\n\n                            long absTimeStamp = ProfilerRuntimeCPU.getAbsTimeStampInCollectedFormat();\n                            boolean res = false;\n\n                            if ((ProfilerRuntime.eventBuffer != null) && !ProfilerRuntime.sendingBuffer) {\n                                synchronized (ProfilerRuntime.eventBuffer) {\n                                    res = ProfilerInterface.serialClientOperationsLock.beginTrans(true, true);\n\n                                    if (res) {\n                                        try {\n                                            ProfilerInterface.dumpExistingResults(opCode == Command.DUMP_EXISTING_RESULTS_LIVE);\n                                        } finally {\n                                            ProfilerInterface.serialClientOperationsLock.endTrans();\n                                        }\n                                    }\n                                }\n                            }\n\n                            DumpResultsResponse resp = new DumpResultsResponse(res, absTimeStamp);\n                            sendComplexResponseToClient(resp);\n\n                            break;\n                        case Command.RESET_PROFILER_COLLECTORS:\n                            requestClientResetResults();\n                            sendSimpleResponseToClient(true, null);\n\n                            break;\n                    }\n                }\n            }\n        }\n\n        public void terminate() {\n            stopped = true;\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    // !!! Warning - do not use ResourceBundle.getBundle here, won't work in context of direct/dynamic attach !!!\n    // Default EN messages initialized here, will be replaced by localized messages in initLocalizedResources()\n    private static ResourceBundle messages;\n    private static String ENTER_TO_SHUTDOWN_MSG = \"Press ENTER to shut down the target JVM...\"; // NOI18N\n    private static String MAIN_CLASS_NOT_PUBLIC_MSG = \"Main class {0} is not public.\\nProfiler can not start it\"; // NOI18N\n    private static String INCORRECT_MAIN_MODIFIERS_MSG = \"Method {0}.main(String args[]) has incorrect modifiers\"; // NOI18N\n    private static String UNEXPECTED_EXCEPTION_MSG = \"Target application threw an unexpected exception: {0}\"; // NOI18N\n    private static String ELAPSED_TIME_MSG = \"Main application thread elapsed time: {0} ms.\"; // NOI18N\n    private static String CONNECTION_MSG = \"Profiler Agent: Established connection with the tool\"; // NOI18N\n    private static String WAITING_ON_PORT_MSG = \"Profiler Agent: Waiting for connection on port {0} (Protocol version: {1})\"; // NOI18N\n    private static String WAITING_ON_PORT_TIMEOUT_MSG = \"Profiler Agent: Waiting for connection on port {0}, timeout {1} seconds (Protocol version: {2})\"; // NOI18N\n    private static String CONNECTION_EXCEPTION_MSG = \"Profiler Agent Error: Exception when trying to establish connection with client:\\n{0}\"; // NOI18N\n    private static String CONNECTION_EXCEPTION_BIND_MSG = \"Profiler Agent Error: Make sure the previously profiled process has been fully terminated\"; // NOI18N\n    private static String CONNECTION_TIMEOUT_MSG = \"Profiler Agent Error: Timed out trying to establish connection with client\"; // NOI18N\n    private static String AGENT_ERROR_MSG = \"Profiler Agent Error: {0}\"; // NOI18N\n    private static String CONNECTION_INTERRUPTED_MSG = \"Profiler Agent Error: Connection with client interrupted\"; // NOI18N\n    private static String COMMAND_EXCEPTION_MSG = \"Profiler Agent Error: Exception when handling command from client:\\n{0}\"; // NOI18N\n    private static String RESPONSE_EXCEPTION_MSG = \"Profiler Agent Error: Exception when trying to send response or command to client:\\n{0}\"; // NOI18N\n    private static String CONNECTION_CLOSED_MSG = \"Profiler Agent: Connection with agent closed\"; // NOI18N\n    private static String CONNECTION_CLOSED_EX_MSG = \"Profiler Agent: Connection with agent closed (ProfilingSessionStatus was null)\"; // NOI18N\n    private static String INCORRECT_AGENT_ID_MSG = \"Profiler Agent Warning: Wrong agentId specified: {0}\"; // NOI18N\n    private static String THREAD_EXCEPTION_MSG = \"Profiler Agent Error: Exception in executeInSeparateThread()\"; // NOI18N\n    private static String THREAD_WAIT_EXCEPTION_MSG = \"Profiler Agent Error: Exception in wait in SeparateCmdExecutionThread\"; // NOI18N\n    private static String LOCAL_SESSION_MSG = \"Profiler Agent: Local accelerated session\"; // NOI18N\n    private static String REMOTE_SESSION_MSG = \"Profiler Agent: Standard session\"; // NOI18N\n    \n    public static final int ATTACH_DYNAMIC = 0;\n    public static final int ATTACH_DIRECT = 1;\n    private static volatile boolean profilerInterfaceInitialized;\n    private static volatile boolean connectionOpen;\n    private static volatile boolean connectionFailed;\n    private static volatile boolean detachCommandReceived;\n    private static ProfilerServer profilerServer;\n    private static ProfilingSessionStatus status;\n    private static volatile boolean startTargetApp;\n    private static volatile boolean targetAppMainThreadComplete;\n    private static volatile Exception startupException;\n    private static final Object targetAppRunningLock = new Object();\n    private static Thread mainThread;\n\n    // Management of execution of some commands in a separate thread\n    private static SeparateCmdExecutionThread separateCmdExecutionThread;\n    private static ShutdownWaitThread shutdownWaitThread;\n    static final Object execInSeparateThreadLock = new Object();\n    static int execInSeparateThreadOpCode;\n    private static volatile boolean preemptExit = true;\n    private static boolean shutdownOK = false;\n    private static final Object shutdownLock = new Object();\n    private static final Object resultsNotifiedLock = new Object();\n\n    // @GuardedBy resultsNotifiedLock\n    private static boolean resultsNotified = false;\n    private static boolean resourcesInitialized = false;\n\n    // This data is needed to avoid passing parameters to doActivate() which may cause problems in attach by pid mode on Windows.\n    private static String _fullJFluidPath;\n    private static int _portNo;\n    private static int _activateCode;\n    private static int _timeOut = 0;\n    private static Response lastResponse;\n    private static final Object responseLock = new Object();\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ObjectInputStream socketIn;\n    private ObjectOutputStream socketOut;\n    private ServerSocket serverSocket;\n    private Socket clientSocket;\n    private WireIO wireIO;\n    private boolean dynamic;\n    private int agentId = -1;\n    final private Random r = new Random(System.currentTimeMillis()) ;\n\n    //---------------------------------------------------------------------------------------\n    // Communication management\n    //---------------------------------------------------------------------------------------\n    private int serverPort;\n    private int serverTimeout = 0; // no timeout by default\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private ProfilerServer(int port, boolean dynamic, int timeout) {\n        super(PROFILER_SERVER_THREAD_NAME);\n        setPriority(Thread.MAX_PRIORITY);\n        serverPort = port;\n        ThreadInfo.addProfilerServerThread(this);\n        this.dynamic = dynamic;\n\n        if (!dynamic) {\n            // for dynamic attach, the server should never timeout\n            serverTimeout = timeout;\n        }\n\n        setDaemon(true);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static synchronized Response getLastResponse() {\n        Response res;\n\n        synchronized (responseLock) {\n            if (lastResponse == null) {\n                // I had to introduce the check below, since for some applications, seemingly the GUI ones that open a FileChooser dialog,\n                // we can somehow get an InterruptedException below. This is likely a bug in JDK - maybe AWT just browses and calls\n                // Thread.interrupt() that causes this exception, on waiting threads, and can mistake our thread for its own or something.\n                boolean gotInterrupted = false;\n\n                do {\n                    try {\n                        responseLock.wait();\n                        gotInterrupted = false;\n                    } catch (InterruptedException ex) {\n                        //System.err.println(\"*** JFluid warning: InterruptedException in ProfilerServer.getLastResponse()\");\n                        gotInterrupted = true;\n                    }\n                } while (gotInterrupted);\n\n                if (lastResponse == null) {\n                    System.out.println(\"Profiler Agent Error: lastResponse == null - internal error?\"); // NOI18N\n                }\n            }\n\n            res = lastResponse;\n            lastResponse = null;\n        }\n\n        return res;\n    }\n\n    public static Thread getMainThread() {\n        return mainThread;\n    }\n\n    public static ProfilingSessionStatus getProfilingSessionStatus() {\n        return status;\n    }\n\n    public static boolean isTargetAppMainThreadComplete() {\n        return targetAppMainThreadComplete;\n    }\n\n    public static void activate(String fullJFluidPath, int portNo, final int activateCode) {\n        activate(fullJFluidPath, portNo, activateCode, 0);\n    }\n\n    /**\n     * Entrypoint in the usage scenario when the client attaches to the running target app using an OS signal,\n     * or the \"attach on startup\" method. On JDK 1.5,\n     * called from ProfilerActivate15.premain().\n     * activateCode == 0 : \"attach on the fly\", activateCode == 1 : \"attach on startup\"\n     *\n     * @param fullJFluidPath Full path to the agent libs\n     * @param portNo         Port number to use\n     * @param activateCode   one of ATTACH_DIRECT or ATTACH_DYNAMIC, determines whether the server is started in dynamic\n     *                       attach mode ( JDK 1.6) or Direct attach\n     * @param timeOut        Time out in seconds for server socket, or 0 for no timeout\n     * @see #ATTACH_DIRECT\n     * @see #ATTACH_DYNAMIC\n     */\n    public static void activate(String fullJFluidPath, int portNo, final int activateCode, int timeOut) {\n        if (connectionOpen) {\n            throw new IllegalStateException(\"Connection already opened on port \"+portNo);   // NOI18N\n        }\n        try {\n            _fullJFluidPath = fullJFluidPath;\n            _portNo = portNo;\n            _timeOut = timeOut;\n            _activateCode = activateCode;\n\n            initLocalizedResources();\n\n            if (activateCode == ATTACH_DYNAMIC) {\n                // Creation of the new thread is (hopefully) a temporary workaround to avoid the problem with stack\n                // overflow or something else when we attach on Windows \"by pid\", i.e. using the CreateRemoteThread() call.\n                new AttachDynamicThread(activateCode).start();\n            } else {\n                doActivate(activateCode);\n            }\n        } catch (Throwable ex) {\n            System.err.println(\"Profiler initialization failed due to:\"); //NOI18N\n            ex.printStackTrace();\n        }\n    }\n\n    /**\n     * Entrypoint in the usage scenario where the client starts and stops the target application.\n     * Start the communication thread and then the target application.\n     * args[0] is the full path to the directory where JFluid native libraries are contained.\n     * args[1] is the communication port number.\n     * args[2] (optional) if it is a number, it is a timeout for the profiler server (in seconds) to wait until the\n     * client connects\n     * args[2 or 3] is the target app main class name; args[3 or 4..n] are its arguments.\n     */\n    public static void main(String[] args) {\n        mainThread = Thread.currentThread();\n\n        // Fix for Issue 69454 - cannot find path to Profiler libraries (http://www.netbeans.org/issues/show_bug.cgi?id=69454)\n        // _fullJFluidPath is needed for lazy initializing localized messages, but it was originally set only by the activate() method\n        // Now it has to be set also here for the I18N to work\n        try {\n            _fullJFluidPath = new File(args[0]).getParentFile().getParentFile().getParentFile().getAbsolutePath();\n        } catch (Exception ex) {\n            throw new RuntimeException(\"ProfilerServer: Unable to initialize ResourceBundle for ProfilerServer, cannot resolve library directory\\n\" // NOI18N\n                                       + ex.getMessage());\n        }\n\n        initLocalizedResources();\n        initInternals();\n\n        // Get the port number\n        int portNo = 0;\n\n        try {\n            portNo = Integer.parseInt(args[1]);\n        } catch (NumberFormatException e) {\n            internalError(\"illegal port number specified: \" + args[1]); // NOI18N\n        }\n\n        int idx = 2;\n\n        // Get the optional timeout number\n        int timeout = 0;\n\n        try {\n            timeout = Integer.parseInt(args[2]);\n            idx = 3;\n        } catch (NumberFormatException e) {\n            // timeout not specified (it is optional)\n        }\n\n        // Move the target app arguments into special array\n        int len = args.length - (idx + 1);\n        String[] targetAppArgs = new String[len];\n        System.arraycopy(args, idx + 1, targetAppArgs, 0, len);\n\n        // Start the communication thread and wait for it to establish connection with client\n        profilerServer = new ProfilerServer(portNo, true, timeout);\n        profilerServer.start();\n\n        while (!(connectionOpen || connectionFailed)) {\n            delay(50);\n        }\n\n        if (connectionFailed) {\n            // prevent the console from dying without the user being able to see the error\n            // pressEnterToShutDown();\n            // no cleanup in this case, as there is no connection established\n            preemptExit = false;\n            System.exit(-1);\n        }\n\n        ProfilerInterface.setProfilerServer(profilerServer);\n\n        initSupportingFunctionality(false);\n\n        // Accept, or wait for, the client command to start the target app, and then start it.\n        while (!startTargetApp) {\n            delay(100);\n        }\n\n        runTargetApp(args[idx], targetAppArgs);\n        targetAppMainThreadComplete = true;\n\n        // If we haven't actually managed to start the app, notify the waiting communication thread.\n        if (startupException != null) {\n            synchronized (targetAppRunningLock) {\n                targetAppRunningLock.notify();\n            }\n        }\n\n        // Wait for some time in case the target app started some threads and then exited the main thread, while the\n        // offspring threads have not yet fully initialized\n        delay(300);\n\n        // Now wait until all target app threads (excluding this, main one) terminate.\n        while (Threads.targetAppThreadsExist()) {\n            delay(300);\n        }\n\n        status.targetAppRunning = false;\n        ProfilerInterface.disableProfilerHooks(); // So that e.g. System.exit() doesn't cause class loads and command sends\n                                                  // DEBUGGING: if it's needed to check how good is the sampling interval when sampled instrumentation is used,\n                                                  // decomment the one below to make the sampling thread stop here and report the debug data.\n                                                  // ProfilerRuntimeCPUSampledInstr.clearDataStructures();\n\n        profilerServer.sendSimpleCmdToClient(Command.SHUTDOWN_INITIATED);\n        waitForShutdownOK();\n        forcedShutdown();\n    }\n\n    public void setRemoteProfiling(boolean remote) {\n        status.remoteProfiling = remote;\n        if (remote) {\n            System.out.println(REMOTE_SESSION_MSG);\n            ClassBytesLoader.preloadClasses(remote);\n        } else {\n            System.out.println(LOCAL_SESSION_MSG);\n            if (Platform.getJDKVersionNumber() >= JDK_19) {\n                // This is to preload some classes that can otherwise be loaded at inappropriate time and cause class load hook firing.\n                ClassBytesLoader.preloadClasses(remote);\n            }\n        }\n    }\n\n    public static void notifyClientOnResultsAvailability() {\n        if (!connectionOpen) {\n            return;\n        }\n\n        if (profilerServer == null) {\n            return; // in calibration mode\n        }\n\n        synchronized (resultsNotifiedLock) {\n            if (resultsNotified) {\n                return; // no need to notify again\n            }\n\n            resultsNotified = true;\n            profilerServer.sendSimpleCmdToClient(Command.RESULTS_AVAILABLE);\n        }\n    }\n\n    /**\n     * reset data, including the data in event buffer\n     */\n    public static void requestClientResetResults() {\n        // make sure resultsNotified flag is set to false\n        profilerServer.resetResultsNotifiedFlag();\n        ProfilerInterface.resetProfilerCollectors();\n        ProfilerCalibrator.resetInternalStatsCollectors();\n    }\n\n    public static void requestClientTakeSnapshot() {\n        if (profilerServer == null) {\n            return; // in calibration mode\n        }\n\n        profilerServer.sendSimpleCmdToClient(Command.TAKE_SNAPSHOT);\n    }\n\n    public boolean getAndCheckLastResponse() {\n        Response resp = getLastResponse();\n\n        return resp.isOK();\n    }\n\n    public void run() {\n        if (connectToClient()) {\n            while (!profilerInterfaceInitialized) {\n                delay(50);\n            }\n\n            listenToClient();\n        } else {\n            preemptExit = false;\n        }\n        ThreadInfo.removeProfilerServerThread(this);\n    }\n\n    public void sendClassLoaderUnloadingCommand() {\n        sendSimpleCmdToClient(Command.CLASS_LOADER_UNLOADING);\n        getLastResponse();\n    }\n\n    public synchronized void sendComplexCmdToClient(Command cmd) {\n        try {\n            wireIO.sendComplexCommand(cmd);\n        } catch (IOException ex) {\n            if (!detachCommandReceived) {\n                handleIOExceptionOnSend(ex);\n            }\n        }\n    }\n\n    public synchronized void sendComplexResponseToClient(Response resp) {\n        try {\n            wireIO.sendComplexResponse(resp);\n        } catch (IOException ex) {\n            if (!detachCommandReceived) {\n                handleIOExceptionOnSend(ex);\n            }\n        }\n    }\n\n    // Several methods to send commands specific for modules that use wireprotocol just occasionally\n    public boolean sendEventBufferDumpedCommand(int length, String bufferName) {\n        EventBufferDumpedCommand cmd = new EventBufferDumpedCommand(length,bufferName);\n        sendComplexCmdToClient(cmd);\n        return getAndCheckLastResponse();\n    }\n\n    public boolean sendEventBufferDumpedCommand(int length, byte[] buffer, int startPos) {\n        EventBufferDumpedCommand cmd = new EventBufferDumpedCommand(length,buffer,startPos);\n        sendComplexCmdToClient(cmd);\n\n        return getAndCheckLastResponse();\n    }\n\n    public synchronized void sendSimpleCmdToClient(int cmdType) {\n        try {\n            wireIO.sendSimpleCommand(cmdType);\n        } catch (IOException ex) {\n            if (!detachCommandReceived) {\n                handleIOExceptionOnSend(ex);\n            }\n        }\n    }\n\n    public synchronized void sendSimpleResponseToClient(boolean val, String errorMessage) {\n        try {\n            wireIO.sendSimpleResponse(val, errorMessage);\n        } catch (IOException ex) {\n            if (!detachCommandReceived) {\n                handleIOExceptionOnSend(ex);\n            }\n        }\n    }\n\n    // --- I18N Support ----------------------------------------------------------\n\n    // This method is used for obtaining ResourceBundle from classes that can be\n    // used by ProfilerServer in context of direct/dynamic attach.\n    //\n    // If path to profiler server libraries (.jar) is known, ResourceBundle is obtained\n    // using custom classloader (solves problem with bootstrap classloader&dynamic attach)\n    //\n    // Does not support branding!\n    static ResourceBundle getProfilerServerResourceBundle() {\n        if (messages != null) {\n            return messages;\n        }\n\n        // 1. try to get the ResourceBundle using custom classloader\n        if (_fullJFluidPath != null) {\n            try {\n                messages = getProfilerServerResourceBundle(_fullJFluidPath);\n            } catch (Exception e) {\n                System.err.println(\"Profiler Server: Problem with customized initializing localized messages...\\n\" + e.getMessage()); // NOI18N\n            }\n        }\n\n        // cannot find jfluid-server.jar or Bundle.properties not found\n\n        if (messages != null) {\n            return messages; // ResourceBundle successfuly loaded using custom classloader\n        }\n\n        // 2. try to get the ResourceBundle in standard way\n        try {\n            messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.server.Bundle\"); // NOI18N\n        } catch (Exception e) {\n            System.err.println(\"Profiler Server: Problem with default initializing localized messages...\\n\" + e.getMessage()); // NOI18N\n        }\n\n        return messages;\n    }\n\n    static void initLocalizedResources() {\n        if (resourcesInitialized) {\n            return;\n        }\n\n        messages = getProfilerServerResourceBundle();\n\n        if (messages != null) {\n            ENTER_TO_SHUTDOWN_MSG = messages.getString(\"ProfilerServer_EnterToShutdownMsg\"); // NOI18N\n            MAIN_CLASS_NOT_PUBLIC_MSG = messages.getString(\"ProfilerServer_MainClassNotPublicMsg\"); // NOI18N\n            INCORRECT_MAIN_MODIFIERS_MSG = messages.getString(\"ProfilerServer_IncorrectMainModifiersMsg\"); // NOI18N\n            UNEXPECTED_EXCEPTION_MSG = messages.getString(\"ProfilerServer_UnexpectedExceptionMsg\"); // NOI18N\n            ELAPSED_TIME_MSG = messages.getString(\"ProfilerServer_ElapsedTimeMsg\"); // NOI18N\n            CONNECTION_MSG = messages.getString(\"ProfilerServer_ConnectionMsg\"); // NOI18N\n            WAITING_ON_PORT_MSG = messages.getString(\"ProfilerServer_WaitingOnPortMsg\"); // NOI18N\n            WAITING_ON_PORT_TIMEOUT_MSG = messages.getString(\"ProfilerServer_WaitingOnPortTimeoutMsg\"); // NOI18N\n            CONNECTION_EXCEPTION_MSG = messages.getString(\"ProfilerServer_ConnectionExceptionMsg\"); // NOI18N\n            CONNECTION_EXCEPTION_BIND_MSG = messages.getString(\"ProfilerServer_ConnectionExceptionBindMsg\"); // NOI18N\n            CONNECTION_TIMEOUT_MSG = messages.getString(\"ProfilerServer_ConnectionTimeoutMsg\"); // NOI18N\n            AGENT_ERROR_MSG = messages.getString(\"ProfilerServer_AgentErrorMsg\"); // NOI18N\n            CONNECTION_INTERRUPTED_MSG = messages.getString(\"ProfilerServer_ConnectionInterruptedMsg\"); // NOI18N\n            COMMAND_EXCEPTION_MSG = messages.getString(\"ProfilerServer_CommandExceptionMsg\"); // NOI18N\n            RESPONSE_EXCEPTION_MSG = messages.getString(\"ProfilerServer_ResponseExceptionMsg\"); // NOI18N\n            CONNECTION_CLOSED_MSG = messages.getString(\"ProfilerServer_ConnectionClosedMsg\"); // NOI18N\n            CONNECTION_CLOSED_EX_MSG = messages.getString(\"ProfilerServer_ConnectionClosedExMsg\"); // NOI18N\n            INCORRECT_AGENT_ID_MSG = messages.getString(\"ProfilerServer_IncorrectAgentIdMsg\"); // NOI18N\n            THREAD_EXCEPTION_MSG = messages.getString(\"ProfilerServer_ThreadExceptionMsg\"); // NOI18N\n            THREAD_WAIT_EXCEPTION_MSG = messages.getString(\"ProfilerServer_ThreadWaitExceptionMsg\"); // NOI18N\n            LOCAL_SESSION_MSG = messages.getString(\"ProfilerServer_LocalSessionMsg\"); // NOI18N\n            REMOTE_SESSION_MSG = messages.getString(\"ProfilerServer_RemoteSessionMsg\"); // NOI18N\n            resourcesInitialized = true;\n        }\n    }\n\n    public static void loadNativeLibrary(String fullJFluidPath, boolean fullPathToLibSpecified) {\n        String libFullName = Platform.getAgentNativeLibFullName(fullJFluidPath, fullPathToLibSpecified, null, -1);\n        System.load(libFullName);\n    }\n\n    static boolean startProfilingPointsActive() {\n        if (status != null) {\n            return status.startProfilingPointsActive;\n        }\n\n        return false;\n    }\n\n    private static File getInfoFile(int port) throws IOException {\n        String dirName = Platform.getProfilerUserDir();\n\n        return new File(dirName + File.separator + port);\n    }\n\n    private static void setShutdownOK() {\n        synchronized (shutdownLock) {\n            shutdownOK = true;\n            shutdownLock.notifyAll();\n        }\n    }\n\n    private static void cleanupOnShutdown() {\n        Monitors.shutdown();\n        ProfilerInterface.disableProfilerHooks();\n        ProfilerInterface.disableProfiling();\n\n        // Bugfix for 65947: Profiler blocks a finishing profiled application\n        // The following connectionOpen = false is done just to prevent error message from listenToClient(). When the connection\n        // is closed either by the client or here by closeConnection(), whoever is faster, listenToClient() waiting for input in socket\n        // will get IOException.\n        // Be careful with this! sendResponseToClient() currently doesn't check connectionOpen value, but if it does, this should be changed.\n        connectionOpen = false;\n        profilerServer.sendSimpleCmdToClient(Command.SHUTDOWN_COMPLETED);\n        profilerServer.closeConnection();\n        profilerServer.stopSeparateCmdExecutionThread();\n    }\n\n    private static void delay(int ms) {\n        try {\n            Thread.sleep(ms);\n        } catch (InterruptedException e) {\n        }\n    }\n\n    /**\n     * Note that putting the code of this into the custom thread above and thus executing in \"attach and startup\"\n     * in a separate thread as well, causes the VM to crash. Probably a new thread can't be created in a call from\n     * pre-main function.\n     *\n     * @param activateCode ATTACH_DYNAMIC or ATTACH_DIRECT\n     * @see #ATTACH_DYNAMIC\n     * @see #ATTACH_DIRECT\n     */\n    private static void doActivate(int activateCode) {\n        ProfilerInterface.disableProfilerHooks(); // Just in case\n        initInternals();\n\n        // Start the communication thread and wait for it to establish connection with client\n        profilerServer = new ProfilerServer(_portNo, activateCode == ATTACH_DYNAMIC, _timeOut);\n        profilerServer.start();\n\n        while (!(connectionOpen || connectionFailed)) {\n            delay(100);\n        }\n\n        if (connectionFailed) {\n            if (activateCode == ATTACH_DIRECT) {\n                System.exit(-1);\n            } else {\n                return; // in dynamic attach we just continue with execution\n            }\n        }\n\n        ProfilerInterface.setProfilerServer(profilerServer);\n\n        initSupportingFunctionality(true);\n\n        if (_activateCode == ATTACH_DIRECT) {\n            // \"Attach on startup\", where we normally wait until the initiate instrumentation request arrives and instrumentation starts.\n            // However, the user can also choose to resume the target app without any instrumentation\n            while ((ProfilerInterface.getCurrentInstrType() == INSTR_NONE) && !status.targetAppRunning) {\n                delay(200);\n            }\n\n            delay(100); // Wait a bit more to make sure the classLoadHook is really set\n        }\n\n        status.targetAppRunning = true;\n    }\n\n    private static void forcedShutdown() {\n        cleanupOnShutdown();\n        preemptExit = false;\n        System.exit(-1);\n    }\n\n    private static void initInternals() {\n        shutdownWaitThread = new ShutdownWaitThread();\n        Runtime.getRuntime().addShutdownHook(shutdownWaitThread);\n        profilerInterfaceInitialized = false;\n        connectionOpen = false;\n        connectionFailed = false;\n        detachCommandReceived = false;\n        profilerServer = null;\n        status = null;\n        startTargetApp = false;\n        startupException = null;\n\n        // Preload this class, to avoid possible strange problems that may happen in case of wire protocol errors, that in\n        // turn may cause loading of this class, that in turn may invoke classLoadHook, etc.\n        try {\n            Class.forName(\"java.net.SocketException\"); // NOI18N\n        } catch (ClassNotFoundException ex) { /* Shouldn't happen */\n        }\n\n        // Preload this class, to avoid possible strange problems that happen during Entire App CPU profiling of tomcat,\n        // where classLoadHook is invoked during processing GET_DEFINING_CLASSLOADER request\n        try {\n            Class.forName(\"java.util.AbstractList$Itr\"); // NOI18N\n        } catch (ClassNotFoundException ex) { /* Shouldn't happen */\n        }\n\n        ThreadInfo.clearProfilerServerThreads();\n    }\n\n    /**\n     * Called after the connection with the tool is established, i.e. we know that we are connected, in which mode\n     * (attached or called directly) and whether it's local or remote connection.\n     */\n    private static void initSupportingFunctionality(boolean inAttachedMode) {\n        status = new ProfilingSessionStatus();\n        status.runningInAttachedMode = inAttachedMode;\n        status.targetJDKVersionString = Platform.getJDKVersionString();\n\n        Monitors.initialize(); // Initialize before initProfilerInterface to get monitor thread(s) recorded as system thread(s)\n                               // Also initialize before initProfilerInterface, same purpose\n\n        profilerServer.initSeparateCmdExecutionThread();\n        ThreadInfo.addProfilerServerThread(shutdownWaitThread);\n        // Profiler interface initialization includes recording profiler's own threads (all currently running threads minus the\n        // current thread, since it will become the target app's main thread).\n        ProfilerInterface.initProfilerInterface(status, inAttachedMode ? profilerServer : Thread.currentThread());\n\n        profilerInterfaceInitialized = true;\n    }\n\n    private static void pressEnterToShutDown() {\n        // Make sure any excessive previous input doesn't cause us to shut down immediately\n        try {\n            while (System.in.available() > 0) {\n                System.in.read();\n            }\n        } catch (IOException ex) {\n            // ignore\n        }\n\n        System.out.println(ENTER_TO_SHUTDOWN_MSG);\n\n        try {\n            System.in.read();\n        } catch (IOException ex) {\n            // ignore\n        }\n    }\n\n    private static void runTargetApp(String mainClassName, String[] mainArgs) {\n        Class targetMainClass = null;\n\n        try {\n            targetMainClass = ClassLoader.getSystemClassLoader().loadClass(mainClassName);\n        } catch (ClassNotFoundException ex) {\n            startupException = ex;\n            System.err.println(ex);\n\n            return;\n        }\n\n        // For the reasons I don't quite understand, if the main class is not public, then somewhere (when we attempt to invoke the\n        // main method using reflection?) we get the following: \"java.lang.IllegalAccessException: Class org.graalvm.visualvm.lib.jfluid.server.ProfilerServer\n        // can not access a member of class Test with modifiers \"public static\"\". Thus we have to run the below preemptive check. Hope this is not\n        // a problem for the majority of our users...\n        if (!Modifier.isPublic(targetMainClass.getModifiers())) {\n            startupException = new IllegalAccessException(MessageFormat.format(MAIN_CLASS_NOT_PUBLIC_MSG, new Object[] { targetMainClass }));\n            System.err.println(startupException);\n\n            return;\n        }\n\n        Method targetMainMethod = null;\n        Class[] params = new Class[] { String[].class };\n\n        try {\n            targetMainMethod = targetMainClass.getDeclaredMethod(\"main\", params); // NOI18N\n        } catch (NoSuchMethodException ex) {\n            startupException = ex;\n            System.err.println(ex);\n\n            return;\n        }\n\n        // Check for correct method modifiers, to (hopefully) avoid IllegalAccessException and IllegalArgumentException\n        int mod = targetMainMethod.getModifiers();\n\n        if (!(Modifier.isPublic(mod) && Modifier.isStatic(mod)) || Modifier.isAbstract(mod) || Modifier.isInterface(mod)) {\n            startupException = new IllegalAccessException(MessageFormat.format(INCORRECT_MAIN_MODIFIERS_MSG, new Object[] { targetMainClass }));\n            System.err.println(startupException);\n\n            return;\n        }\n\n        // We hope after our checks the only exceptions that can be thrown by the target app are those that it generates for\n        // natural reasons, and which we should not report as \"failed to start the application\"\n        status.targetAppRunning = true;\n\n        synchronized (targetAppRunningLock) {\n            targetAppRunningLock.notify();\n        }\n\n        long startTime = Timers.getCurrentTimeInCounts();\n\n        try {\n            targetMainMethod.invoke(targetMainClass, new Object[] { mainArgs });\n        } catch (IllegalAccessException e1) {\n            startupException = e1;\n            System.err.println(e1);\n        } catch (IllegalArgumentException e2) {\n            startupException = e2;\n            System.err.println(e2);\n        } catch (InvocationTargetException e3) {\n            Throwable cause = e3.getCause();\n\n            if (cause != null) {\n                cause.printStackTrace(System.err);\n            } else { // Can this ever happen?\n                internalError(\"Target application threw a null exception?\"); // NOI18N\n            }\n        } catch (Throwable ex) {\n            ProfilerInterface.disableProfilerHooks();\n            internalError(MessageFormat.format(UNEXPECTED_EXCEPTION_MSG, new Object[] { ex }), false);\n            ex.printStackTrace(System.err);\n        } finally {\n            int elapsedTime = (int) (((Timers.getCurrentTimeInCounts() - startTime) * 1000) / Timers.getNoOfCountsInSecond());\n            System.out.println(MessageFormat.format(ELAPSED_TIME_MSG, new Object[] { \"\" + elapsedTime })); // NOI18N\n        }\n    }\n\n    private static void waitForShutdownOK() {\n        synchronized (shutdownLock) {\n            while (!shutdownOK && !Thread.interrupted()) {\n                try {\n                    shutdownLock.wait(500);\n                } catch (InterruptedException e) {\n                }\n\n                Thread.yield();\n            }\n\n            if (shutdownOK) {\n                return;\n            }\n        }\n\n        System.err.println(\"ProfilerServer hasn't shut down cleanly. Terminated.\"); // NOI18N\n\n        //    while (true) {\n        //      if (shutdownOK) {\n        //        return;\n        //      }\n        //      delay(100);\n        //    }\n    }\n\n    private int getAgentId() {\n        if (agentId == -1) {\n            String id = System.getProperty(\"nbprofiler.agentid\"); // NOI18N\n\n            if (id != null) {\n                try {\n                    agentId = Integer.parseInt(id);\n                } catch (NumberFormatException e) {\n                    System.err.println(MessageFormat.format(INCORRECT_AGENT_ID_MSG, new Object[] { id }));\n                                                                                                           // ignore, the agentId will be generated randomly\n                }\n            }\n\n            if (agentId == -1) {\n                agentId = r.nextInt(Integer.MAX_VALUE);\n            }\n        }\n\n        return agentId;\n    }\n\n    private static void setLastResponse(Response r) {\n        synchronized (responseLock) {\n            lastResponse = r;\n\n            try {\n                responseLock.notify();\n            } catch (IllegalMonitorStateException ex) {\n                internalError(\"IllegalMonitorState in ProfilerServer.setLastResponse()\"); // NOI18N\n            }\n        }\n    }\n\n    private static String getLocalizedJFluidServerJar(String jfluidServerDir) {\n        String localizedJFluidServerJar = null;\n\n        // normalize provided directory to use forward slashes with slash at the end of path\n        String baseDir = jfluidServerDir.replace('\\\\', '/'); // NOI18N\n\n        if (!baseDir.endsWith(\"/\")) { // NOI18N\n            baseDir = baseDir + \"/\"; // NOI18N\n        }\n\n        // check if directory exists\n        File baseDirF = new File(baseDir);\n\n        if (!baseDirF.exists() || !baseDirF.isDirectory()) {\n            return null;\n        }\n\n        // check if locale directory exists\n        String localeDir = baseDir + \"locale/\"; // NOI18N\n        File localeDirF = new File(localeDir);\n\n        if (localeDirF.exists() && localeDirF.isDirectory()) {\n            // locale directory found, try to find jar inside\n            localizedJFluidServerJar = getLocalizedJFluidServerJarInDir(localeDir);\n\n            if (localizedJFluidServerJar != null) {\n                return localizedJFluidServerJar;\n            }\n        }\n\n        // locale directory doesn't exist or jar not found in it, try to find jar directly in jfluid dir\n        localizedJFluidServerJar = getLocalizedJFluidServerJarInDir(baseDir);\n\n        return localizedJFluidServerJar;\n    }\n\n    private static String getLocalizedJFluidServerJarInDir(String jfluidServerLocaleDir) {\n        LocaleIterator localeIterator = new LocaleIterator(Locale.getDefault());\n        String jarFile;\n        File jarFileF;\n\n        while (localeIterator.hasNext()) {\n            jarFile = jfluidServerLocaleDir + \"jfluid-server\" + localeIterator.next() + \".jar\"; // NOI18N\n            jarFileF = new File(jarFile);\n\n            if (jarFileF.exists() && jarFileF.isFile()) {\n                return jarFile;\n            }\n        }\n\n        return null;\n    }\n\n    // Does not support branding!\n    private static ResourceBundle getProfilerServerResourceBundle(String jfluidPath) {\n        ResourceBundle bundle = null;\n\n        if (jfluidPath == null) {\n            throw new RuntimeException(\"ProfilerServer: Unable to initialize ResourceBundle for ProfilerServer, \" // NOI18N\n                                       + \"cannot find path to Profiler libraries\" // NOI18N\n                                       );\n        }\n\n        String jfluidServerJar = getLocalizedJFluidServerJar(jfluidPath);\n\n        if (jfluidServerJar == null) {\n            throw new RuntimeException(\"ProfilerServer: Unable to initialize ResourceBundle for ProfilerServer, \" // NOI18N\n                                       + \"cannot find localized jfluid-server.jar\" // NOI18N\n                                       );\n        }\n\n        try {\n            if (!jfluidServerJar.startsWith(\"/\")) { // NOI18N\n                jfluidServerJar = \"/\" + jfluidServerJar; // NOI18N\n            }\n\n            String bundleJarURLPath = \"jar:file:\" + jfluidServerJar + \"!/\"; // NOI18N\n            URLClassLoader loader = new URLClassLoader(new URL[] { new URL(bundleJarURLPath) });\n            bundle = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.server.Bundle\", Locale.getDefault(), loader); // NOI18N\n        } catch (Exception e2) {\n            throw new RuntimeException(\"ProfilerServer: Unable to initialize ResourceBundle for ProfilerServer\\n\" + e2.getMessage()); // NOI18N\n        }\n\n        if (bundle == null) {\n            throw new RuntimeException(\"ProfilerServer: Unable to initialize ResourceBundle for ProfilerServer\" // NOI18N\n            );\n        }\n\n        return bundle;\n    }\n\n    private synchronized void closeConnection() {\n        connectionOpen = false;\n        if (status != null) {\n            status.targetAppRunning = false;\n        }\n        removeInfoFile();\n\n        try {\n            socketOut.close();\n            socketIn.close();\n            clientSocket.close();\n            serverSocket.close();\n        } catch (IOException ex) {\n        }\n\n        if (status == null) {\n            System.out.println(CONNECTION_CLOSED_EX_MSG);\n        } else if (status.runningInAttachedMode) {\n            System.out.println(CONNECTION_CLOSED_MSG);\n        }\n\n        preemptExit = false;\n    }\n\n    private boolean connectToClient() {\n        try {\n            if (serverTimeout == 0) {\n                System.out.println(MessageFormat.format(WAITING_ON_PORT_MSG,\n                                                        new Object[] { \"\" + serverPort, // NOI18N\n                                                                       \"\" + CURRENT_AGENT_VERSION // NOI18N\n                                                        }));\n            } else {\n                System.out.println(MessageFormat.format(WAITING_ON_PORT_TIMEOUT_MSG,\n                                                        new Object[] { \"\" + serverPort, // NOI18N\n                                                                       \"\" + serverTimeout, // NOI18N\n                                                                       \"\" + CURRENT_AGENT_VERSION // NOI18N\n                                                        }));\n            }\n\n            serverSocket = new ServerSocket(serverPort);\n            serverSocket.setSoTimeout(serverTimeout * 1000); // serverTimeout is in seconds\n            createInfoFile();\n            clientSocket = serverSocket.accept();\n            clientSocket.setTcpNoDelay(true); // Necessary at least on Solaris to avoid delays in e.g. readInt() etc.\n            socketIn = new ObjectInputStream(clientSocket.getInputStream());\n            socketOut = new ObjectOutputStream(clientSocket.getOutputStream());\n            wireIO = new WireIO(socketOut, socketIn);\n            connectionOpen = true;\n            System.out.println(CONNECTION_MSG);\n            return true;\n        } catch (SocketTimeoutException ex) {\n            System.err.println(CONNECTION_TIMEOUT_MSG);\n            connectionFailed = true;\n        } catch (IOException ex) {\n            System.err.println(MessageFormat.format(CONNECTION_EXCEPTION_MSG, new Object[] { ex }));\n            if (ex instanceof BindException) System.err.println(CONNECTION_EXCEPTION_BIND_MSG);\n            connectionFailed = true;\n        } finally {\n            //removeInfoFile ();\n        }\n\n        return false;\n    }\n\n    private void createInfoFile() {\n        BufferedOutputStream bos = null;\n\n        try {\n            File f = getInfoFile(serverPort);\n            f.createNewFile();\n            f.deleteOnExit();\n\n            Properties props = new Properties();\n            props.setProperty(\"dynamic\", Boolean.toString(dynamic)); // NOI18N\n            props.setProperty(\"working.dir\", System.getProperty(\"user.dir\")); // NOI18N\n            props.setProperty(\"agent.id\", Integer.toString(getAgentId())); // NOI18N\n            props.setProperty(\"java.version\", System.getProperty(\"java.version\")); // NOI18N\n\n            FileOutputStream fos = new FileOutputStream(f);\n            bos = new BufferedOutputStream(fos);\n\n            props.store(bos, \"\"); // NOI18N\n\n            bos.close();\n        } catch (IOException e) {\n            System.err.println(MessageFormat.format(AGENT_ERROR_MSG, new Object[] { e.getMessage() }));\n        } finally {\n            if (bos != null) {\n                try {\n                    bos.close();\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n            }\n        }\n    }\n\n    /**\n     * Some of the commands need to be executed in a separate thread, because they result in the server sending something\n     * to the client and awaiting its response. The response, in turn, can only be picked up by the single JFluid communication\n     * thread. So we execute these commands in a separate thread to allow the main communication thread to return immediately,\n     * and be ready to process client's response.\n     */\n    private void executeInSeparateThread(int opCode) {\n        synchronized (execInSeparateThreadLock) {\n            execInSeparateThreadOpCode = opCode;\n\n            try {\n                execInSeparateThreadLock.notify();\n            } catch (IllegalMonitorStateException ex) {\n                System.err.println(THREAD_EXCEPTION_MSG);\n            }\n        }\n    }\n\n    //---------------------------------------------------------------------------------------\n    // Command/response handling\n    //---------------------------------------------------------------------------------------\n    private void handleClientCommand(Command cmd) {\n        //System.out.println(\">>> Got command \" + cmd);\n        if (cmd.getType() == Command.START_TARGET_APP) {\n            if (status.runningInAttachedMode) {\n                // This is a special case - the user has chosen \"Attach on startup\" and then \"resume application without instrumentation\"\n                status.targetAppRunning = true;\n                sendSimpleResponseToClient(true, null);\n\n                return;\n            }\n\n            // Start target app is handled by a separate thread, since we want to return to the client a synchronous response telling\n            // whether or not the target app was started successfully. To get an answer to this question, we have to wait until the main\n            // class is loaded, its main method is found, etc. Only after that the targetAppRunningLock.notify() is called. Until then\n            // this thread remains blocked. However, if instrumentation root method == main method, class load hook is invoked immediately\n            // when the main class is loaded. Class load hook, in turn, sends a RootClassLoaded command to the server and waits for the\n            // response. But responses are read by the same thread that calls handleClientCommand(). So if we do the below operations in\n            // the same thread, we deadlock - so, a separate thread is needed to allow the main listener thread to handle incoming\n            // commands/responses immediately.\n            class MyThread extends Thread {\n                MyThread() {\n                    ThreadInfo.addProfilerServerThread(this);\n                    this.setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + \" 4\"); // NOI18N\n                }\n\n                public void run() {\n                    synchronized (targetAppRunningLock) {\n                        startTargetApp = true;\n\n                        try {\n                            targetAppRunningLock.wait();\n                        } catch (InterruptedException ex) {\n                            internalError(\"START_TARGET_APP\"); // NOI18N\n                        }\n                    }\n\n                    if (startupException != null) {\n                        sendSimpleResponseToClient(false, startupException.toString());\n                    } else {\n                        sendSimpleResponseToClient(true, null);\n                    }\n\n                    ThreadInfo.removeProfilerServerThread(this);\n                }\n            }\n            new MyThread().start();\n\n            return;\n        }\n\n        switch (cmd.getType()) {\n            case Command.GET_MONITORED_NUMBERS:\n                sendComplexResponseToClient(Monitors.getMonitoredNumbers());\n\n                break;\n            case Command.INITIATE_PROFILING:\n\n                // Bugfix 69645: Take snapshot is not enabled after modifying profiling from CPU to memory\n                // http://profiler.netbeans.org/issues/show_bug.cgi?id=69645\n                synchronized (resultsNotifiedLock) {\n                    resultsNotified = false;\n                }\n\n                try {\n                    ProfilerInterface.initiateProfiling((InitiateProfilingCommand) cmd, status.targetAppRunning);\n                    sendSimpleResponseToClient(true, null);\n                } catch (Exception ex) {\n                    sendSimpleResponseToClient(false, ex.getMessage());\n                }\n\n                break;\n            case Command.INSTRUMENT_METHOD_GROUP:\n                class InstrumentMethodGroupThread extends Thread {\n                    final InstrumentMethodGroupCommand methodGroupCmd;\n                    String exceptionString;\n\n                    InstrumentMethodGroupThread(InstrumentMethodGroupCommand cmd) {\n                        ThreadInfo.addProfilerServerThread(this);\n                        setName(PROFILER_SPECIAL_EXEC_THREAD_NAME + \" 8\"); // NOI18N\n                        methodGroupCmd = cmd;\n                    }\n\n                    public void run() {\n                        try {\n                            ProfilerInterface.instrumentMethods(methodGroupCmd);\n                        } catch (Exception ex) {\n                            exceptionString = ex.getLocalizedMessage();\n                        }\n\n                        ThreadInfo.removeProfilerServerThread(this);\n                    }\n                }\n\n                InstrumentMethodGroupThread instrumentMethodGroupThread = new InstrumentMethodGroupThread((InstrumentMethodGroupCommand) cmd);\n                instrumentMethodGroupThread.start();\n\n                while(instrumentMethodGroupThread.isAlive()) {\n                    delay(2000);\n                    sendSimpleCmdToClient(Command.STILL_ALIVE);\n                }\n\n                if (instrumentMethodGroupThread.exceptionString != null) {\n                    sendSimpleResponseToClient(false, instrumentMethodGroupThread.exceptionString);\n                } else {\n                    sendSimpleResponseToClient(true, null);\n                }\n\n                break;\n            case Command.CHECK_CONNECTION:\n                sendSimpleResponseToClient(true, null);\n\n                break;\n            case Command.SET_CHANGEABLE_INSTR_PARAMS:\n                boolean threadSampling;\n                boolean waitTracking;\n                boolean sleepTracking;\n                boolean lockContentionMonitoring;\n                SetChangeableInstrParamsCommand scipCmd = (SetChangeableInstrParamsCommand) cmd;\n                lockContentionMonitoring = scipCmd.isLockContentionMonitoringEnabled();\n                ProfilerRuntime.setLockContentionMonitoringEnabled(lockContentionMonitoring);\n                ProfilerRuntimeCPU.setNProfiledThreadsLimit(scipCmd.getNProfiledThreadsLimit());\n                ProfilerRuntimeCPU.setMaxStringLength(scipCmd.getMaxStringLength());\n                ProfilerRuntimeCPU.setStackDepthLimit(scipCmd.getStackDepthLimit());\n                ProfilerRuntimeCPUSampledInstr.setSamplingInterval(scipCmd.getSamplingInterval());\n                ProfilerRuntimeSampler.setSamplngFrequency(scipCmd.getThreadsSamplingFrequency());\n                ProfilerRuntimeMemory.setSamplingInterval((short) scipCmd.getObjAllocStackSamplingInterval());\n                ProfilerRuntimeMemory.setStackSamplingDepth(scipCmd.getObjAllocStackSamplingDepth());\n                ProfilerRuntimeObjLiveness.setRunGCOnGetResults(scipCmd.getRunGCOnGetResultsInMemoryProfiling());\n                threadSampling = scipCmd.isThreadsSamplingEnabled();\n                waitTracking = scipCmd.isWaitTrackingEnabled();\n                sleepTracking = scipCmd.isSleepTrackingEnabled();\n                Monitors.setThreadsSamplingEnabled(threadSampling);\n                ProfilerRuntimeCPU.setWaitAndSleepTracking(waitTracking,sleepTracking);\n                Classes.setWaitTrackingEnabled(threadSampling || waitTracking || lockContentionMonitoring);\n                Classes.setParkTrackingEnabled(threadSampling || waitTracking);\n                Classes.setSleepTrackingEnabled(threadSampling || sleepTracking);\n                sendSimpleResponseToClient(true, null);\n\n                break;\n            case Command.SET_UNCHANGEABLE_INSTR_PARAMS:\n\n                SetUnchangeableInstrParamsCommand sucipCmd = (SetUnchangeableInstrParamsCommand) cmd;\n                ProfilerRuntimeCPU.setTimerTypes(sucipCmd.getAbsoluteTimerOn(), sucipCmd.getThreadCPUTimerOn());\n                status.instrScheme = sucipCmd.getInstrScheme();\n                ProfilerRuntimeCPUCodeRegion.setCPUResBufSize(sucipCmd.getCodeRegionCPUResBufSize());\n                ProfilerRuntimeCPU.enableFirstTimeMethodInvoke(status.instrScheme != INSTRSCHEME_TOTAL);\n                setRemoteProfiling(sucipCmd.getRemoteProfiling());\n                sendSimpleResponseToClient(true, null);\n\n                break;\n            case Command.CPU_RESULTS_EXIST:\n                sendSimpleResponseToClient(ProfilerInterface.cpuResultsExist(), null);\n\n                break;\n            case Command.DUMP_EXISTING_RESULTS:\n            case Command.DUMP_EXISTING_RESULTS_LIVE:\n                // We have to execute the dump in a separate thread to make this call (handleClientCommand()) return immediately.\n                // Otherwise, it would not allow the server to receive a response from the client, that the client sends when it\n                // processes the dumped results. Generally, all commands that may call ProfilerRuntime.dumpEventBuffer() should be\n                // executed in a separate thread.\n                executeInSeparateThread(cmd.getType());\n\n                break;\n            case Command.GET_CODE_REGION_CPU_RESULTS:\n                sendComplexResponseToClient(ProfilerInterface.getCodeRegionCPUResults());\n\n                break;\n            case Command.GET_OBJECT_ALLOCATION_RESULTS:\n                sendComplexResponseToClient(ProfilerInterface.getObjectAllocationResults());\n\n                break;\n            case Command.GET_METHOD_NAMES_FOR_JMETHOD_IDS:\n\n                GetMethodNamesForJMethodIdsCommand gmnCmd = (GetMethodNamesForJMethodIdsCommand) cmd;\n                sendComplexResponseToClient(ProfilerInterface.getMethodNamesForJMethodIds(gmnCmd.getMethodIds()));\n\n                break;\n            case Command.RESET_PROFILER_COLLECTORS:\n                // Since the resetProfilerCollectors() eventually invokes the dump results method, which in turn sends a command to the client\n                // and awaits response, we have to execute it in a separate thread. See comments in DUMP_EXISTING_RESULTS above.\n                executeInSeparateThread(cmd.getType());\n\n                break;\n            case Command.DEACTIVATE_INJECTED_CODE:\n                ProfilerInterface.deactivateInjectedCode();\n                sendSimpleResponseToClient(true, null);\n\n                break;\n            case Command.GET_THREAD_LIVENESS_STATUS:\n                sendComplexResponseToClient(ProfilerInterface.getCurrentThreadLivenessStatus());\n\n                break;\n            case Command.SUSPEND_TARGET_APP:\n                ProfilerInterface.suspendTargetApp();\n                sendSimpleResponseToClient(true, null);\n\n                break;\n            case Command.RESUME_TARGET_APP:\n                ProfilerInterface.resumeTargetApp();\n                sendSimpleResponseToClient(true, null);\n\n                break;\n            case Command.TERMINATE_TARGET_JVM:\n\n                if (ProfilerInterface.getCurrentInstrType() != INSTR_NONE) {\n                    ProfilerInterface.deactivateInjectedCode();\n                }\n\n                sendSimpleResponseToClient(true, null);\n                closeConnection();\n                preemptExit = false;\n                doExit();\n\n                break;\n            case Command.SHUTDOWN_OK:\n                setShutdownOK();\n\n                break;\n            case Command.INSTRUMENT_REFLECTION:\n                ProfilerInterface.setInstrumentReflection(true);\n                sendSimpleResponseToClient(true, null);\n\n                break;\n            case Command.DEINSTRUMENT_REFLECTION:\n                ProfilerInterface.setInstrumentReflection(false);\n                sendSimpleResponseToClient(true, null);\n\n                break;\n            case Command.RUN_GC:\n                GC.runGC();\n                sendSimpleResponseToClient(true, null);\n\n                break;\n            case Command.GET_DEFINING_CLASS_LOADER: {\n                GetDefiningClassLoaderCommand gdclCmd = (GetDefiningClassLoaderCommand) cmd;\n                int loaderId = ClassLoaderManager.getDefiningLoaderForClass(gdclCmd.getClassName(), gdclCmd.getClassLoaderId());\n                DefiningLoaderResponse resp = new DefiningLoaderResponse(loaderId);\n                sendComplexResponseToClient(resp);\n\n                break;\n            }\n            case Command.GET_VM_PROPERTIES: {\n                status.jvmArguments = Threads.getJVMArguments();\n                status.javaCommand = Threads.getJavaCommand();\n\n                VMPropertiesResponse resp = new VMPropertiesResponse(Platform.getJavaVersionString(), \n                                                                     System.getProperty(\"java.class.path\"), // NOI18N\n                                                                     System.getProperty(\"java.ext.dirs\", \"\"), // NOI18N\n                                                                     System.getProperty(\"sun.boot.class.path\", \"\"), // NOI18N\n                                                                     System.getProperty(\"user.dir\"), // NOI18N\n                                                                     status.jvmArguments, status.javaCommand,\n                                                                     System.getProperty(\"os.name\"), // NOI18N\n                                                                     InstrumentConstructorTest.test(),\n                                                                     Runtime.getRuntime().maxMemory(),\n                                                                     System.currentTimeMillis(), Timers.getCurrentTimeInCounts(),\n                                                                     getAgentId()\n                );\n                sendComplexResponseToClient(resp);\n\n                break;\n            }\n            case Command.GET_STORED_CALIBRATION_DATA: { // called in the beginning of remote CPU profiling\n\n                int ret = CalibrationDataFileIO.readSavedCalibrationData(status);\n\n                if (ret == 0) {\n                    CalibrationDataResponse resp = new CalibrationDataResponse(status.methodEntryExitCallTime,\n                                                                               status.methodEntryExitInnerTime,\n                                                                               status.methodEntryExitOuterTime,\n                                                                               status.timerCountsInSecond);\n                    profilerServer.sendComplexResponseToClient(resp);\n                } else {\n                    sendSimpleResponseToClient(false, CalibrationDataFileIO.getErrorMessage());\n                }\n\n                break;\n            }\n            case Command.RUN_CALIBRATION_AND_GET_DATA: {\n                ProfilerCalibrator.init(status);\n                ProfilerCalibrator.measureBCIOverhead(false);\n\n                CalibrationDataResponse resp = new CalibrationDataResponse(status.methodEntryExitCallTime,\n                                                                           status.methodEntryExitInnerTime,\n                                                                           status.methodEntryExitOuterTime,\n                                                                           status.timerCountsInSecond);\n                profilerServer.sendComplexResponseToClient(resp);\n\n                break;\n            }\n            case Command.GET_INTERNAL_STATS:\n                ProfilerCalibrator.init(status);\n                sendComplexResponseToClient(ProfilerCalibrator.getInternalStats());\n\n                break;\n            case Command.PREPARE_DETACH:\n                ProfilerInterface.setDetachStarted(true); //inform other threads they should stop ongoing instrumentation\n                boolean success = ProfilerInterface.serialClientOperationsLock.beginTrans(true, true);\n                sendSimpleResponseToClient(success, null);                \n                break;\n            case Command.DETACH:\n                if(ProfilerInterface.isDetachStarted()) {\n                    ProfilerInterface.serialClientOperationsLock.endTrans();\n                }\n                ProfilerInterface.setDetachStarted(false);\n\n                // Just in case, normally should be deactivated and cleaned up by client\n                ProfilerInterface.deactivateInjectedCode();\n                ProfilerInterface.disableProfilerHooks();\n                ProfilerInterface.clearProfilerDataStructures();\n\n                stopSeparateCmdExecutionThread();\n                Monitors.shutdown();\n                ThreadInfo.clearProfilerServerThreads();\n                detachCommandReceived = true;\n                sendSimpleResponseToClient(true, null);\n\n                break;\n            case Command.TAKE_HEAP_DUMP:\n\n                TakeHeapDumpCommand dumpCmd = (TakeHeapDumpCommand) cmd;\n                String error = HeapDump.takeHeapDump(dumpCmd.getOutputFile());\n\n                sendSimpleResponseToClient(error == null, error);\n\n                break;\n            case Command.GET_HEAP_HISTOGRAM:\n                Response resp = ProfilerInterface.computeHistogram();\n                sendComplexResponseToClient(resp);\n                \n                break;\n            case Command.TAKE_THREAD_DUMP:\n                Response tdResp = new ThreadDumpResponse(ThreadDump.isJDK15(), new Date(), ThreadDump.takeThreadDump());\n                sendComplexResponseToClient(tdResp);\n                \n                break;\n            case Command.GET_CLASS_FILE_BYTES:\n                //System.out.println(cmd);\n                GetClassFileBytesCommand getCmd = (GetClassFileBytesCommand) cmd;\n                byte[][] bytes = ProfilerInterface.getClassFileBytes(getCmd.getClasses(), getCmd.getClassLoaderIds());\n                sendComplexResponseToClient(new GetClassFileBytesResponse(bytes));\n                \n                break;\n        }\n    }\n\n    private void doExit() {\n\n        // try Lookup.getDefault().lookup(ClassLoader.class)\n        try {\n            Class lookupClz = Thread.currentThread().getContextClassLoader().loadClass(\"org.openide.util.Lookup\"); // NOI18N\n            Method instMethod = lookupClz.getMethod(\"getDefault\", new Class[0]); // NOI18N\n            Method lookupMethod = lookupClz.getMethod(\"lookup\", new Class[]{Class.class}); // NOI18N\n\n            Object instance = instMethod.invoke(lookupClz, new Object[0]);\n            if (instance != null) {\n                ClassLoader clInstance = (ClassLoader)lookupMethod.invoke(instance, new Class[]{ClassLoader.class});\n                if (clInstance != null) {\n                    // try to call Ide.quit in JDeveloper\n                    try {\n                        Class oracleIde = clInstance.loadClass(\"oracle.ide.Ide\"); // NOI18N\n                        Method ideQuitMethod = oracleIde.getMethod(\"quit\", new Class[0]); // NOI18N\n                        ideQuitMethod.invoke(oracleIde, new Object[0]);\n                        return;\n                    } catch (Exception ex) {\n                        // ignore\n                    }\n                    // try to call LifecycleManager in NetBeans\n                    Class lcmInstanceClz = clInstance.loadClass(\"org.openide.LifecycleManager\"); // NOI18N\n                    Method lcmInstMethod = lcmInstanceClz.getMethod(\"getDefault\", new Class[0]); // NOI18N\n                    Method lcmExitMethod = lcmInstanceClz.getMethod(\"exit\", new Class[0]); // NOI18N\n                    Object lcmInstance = lcmInstMethod.invoke(lcmInstanceClz, new Object[0]);\n                    lcmExitMethod.invoke(lcmInstance, new Object[0]);\n                    return;\n                }\n            }\n        } catch (Exception ex) {\n            // ignore\n        }\n        \n        // fall through a general system exit\n        System.exit(-1);\n    }\n\n    private void handleIOExceptionOnSend(IOException ex) {\n        System.err.println(MessageFormat.format(RESPONSE_EXCEPTION_MSG, new Object[] { ex }));\n        ex.printStackTrace(System.err);\n        closeConnection();\n    }\n\n    private void initSeparateCmdExecutionThread() {\n        separateCmdExecutionThread = new SeparateCmdExecutionThread();\n        separateCmdExecutionThread.start();\n    }\n\n    private static void internalError(String message) {\n        internalError(message, true);\n    }\n\n    private static void internalError(String message, boolean exit) {\n        System.err.println(\"Profiler Engine Error: \" + message); // NOI18N\n\n        if (exit) {\n            preemptExit = false;\n            System.exit(-1);\n        }\n    }\n\n    private void listenToClient() {\n        while (connectionOpen && !detachCommandReceived) {\n            try {\n                Object o = wireIO.receiveCommandOrResponse();\n\n                if (o == null) {\n                    System.err.println(CONNECTION_INTERRUPTED_MSG);\n\n                    break; // end of connection\n                }\n\n                //System.out.println(\">>> Profiler Engine: received command or response \" + o);\n                if (o instanceof Command) {\n                    handleClientCommand((Command) o);\n                } else {\n                    setLastResponse((Response) o);\n                }\n            } catch (IOException ex) {\n                if (connectionOpen && !detachCommandReceived) { // It is not an asynchronous connection shutdown\n                    System.err.println(MessageFormat.format(COMMAND_EXCEPTION_MSG, new Object[] { ex }));\n                }\n\n                break;\n            }\n        }\n\n        closeConnection();\n    }\n\n    private void removeInfoFile() {\n        try {\n            getInfoFile(serverPort).delete();\n        } catch (IOException e) {\n            System.err.println(MessageFormat.format(AGENT_ERROR_MSG, new Object[] { e.getMessage() }));\n        }\n    }\n\n    private void stopSeparateCmdExecutionThread() {\n        separateCmdExecutionThread.terminate();\n\n        synchronized (execInSeparateThreadLock) {\n            try {\n                execInSeparateThreadLock.notify();\n            } catch (IllegalMonitorStateException ex) {\n            }\n        }\n    }\n    \n    private void resetResultsNotifiedFlag() {\n        synchronized (resultsNotifiedLock) {\n            resultsNotified = false;\n        }\n    }\n\n    boolean isDynamic() {\n        return dynamic;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ProfilingPointServerHandler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport org.graalvm.visualvm.lib.jfluid.server.system.Timers;\nimport java.lang.reflect.Method;\nimport java.util.Arrays;\n\n\n/**\n * Base class for custom profiling point server handlers. Default implementation just writes timestamped\n * event to the event buffer to be later processed by the client executor. Handlers are expected to be\n * singletons accessible via static getInstance() method.\n *\n * @author Tomas Hurka\n * @author Maros Sandor\n */\npublic class ProfilingPointServerHandler {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n    private static ProfilingPointServerHandler[] profilingPointHandlers;\n    private static int[] profilingPointIDs;\n    private static ProfilingPointServerHandler instance;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    public static synchronized ProfilingPointServerHandler getInstance(String clientInfo) {\n        if (instance == null) {\n            instance = new ProfilingPointServerHandler();\n        }\n\n        return instance;\n    }\n\n    public static synchronized void initInstances(int[] ppIDs, String[] handlerClassNames, String[] handlersInfo) {\n        profilingPointIDs = ppIDs;\n        profilingPointHandlers = getInstances(handlerClassNames, handlersInfo);\n    }\n\n    public static ProfilingPointServerHandler getHandler(char handlerId) {\n        int idx = Arrays.binarySearch(profilingPointIDs, handlerId);\n        if (idx >= 0) {\n            return profilingPointHandlers[idx];\n        }\n        return null;\n    }\n\n    private static ProfilingPointServerHandler[] getInstances(String[] handlerClassNames, String[] handlersInfo) {\n        ProfilingPointServerHandler[] handlers = new ProfilingPointServerHandler[handlerClassNames.length];\n\n        for (int i = 0; i < handlerClassNames.length; i++) {\n            try {\n                Method method = Class.forName(handlerClassNames[i]).getMethod(\"getInstance\", new Class[] { String.class }); //NOI18N\n                handlers[i] = (ProfilingPointServerHandler) method.invoke(null, new Object[] { handlersInfo[i] });\n            } catch (Exception e) {\n                e.printStackTrace(System.err);\n            }\n        }\n\n        return handlers;\n    }\n\n    /**\n     * Invoked by the JFluid server when the profiling point hits.\n     *\n     * @param id unique ID of the profiling point\n     */\n    public void profilingPointHit(int id) {\n        long absTimeStamp = Timers.getCurrentTimeInCounts();\n        profilingPointHit(id, absTimeStamp);\n    }\n\n    /**\n     * Invoked by the JFluid server when the profiling point hits.\n     *\n     * @param id unique ID of the profiling point\n     */\n    public void profilingPointHit(int id, long absTimeStamp) {\n        ProfilerRuntime.writeProfilingPointHitEvent(id, absTimeStamp);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ResetResultsProfilingPointHandler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\n/**\n * Performs special handling of Reset Results profiling points on server side.\n *\n * @author Maros Sandor\n */\npublic class ResetResultsProfilingPointHandler extends ProfilingPointServerHandler {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static ProfilingPointServerHandler instance;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static synchronized ProfilingPointServerHandler getInstance(String clientInfo) {\n        if (instance == null) {\n            instance = new ResetResultsProfilingPointHandler();\n        }\n\n        return instance;\n    }\n\n    public void profilingPointHit(int id) {\n        super.profilingPointHit(id);\n        ProfilerRuntime.dumpEventBuffer();\n        ProfilerServer.requestClientResetResults();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/SamplingThread.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Timers;\n\n\n/**\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\nabstract class SamplingThread extends Thread {\n    //~ Static fields/initializers -------------------------------------------------------------------------------------------\n\n    private static final boolean isSolaris = Platform.isSolaris();\n    private static final boolean isLinux = Platform.isLinux();\n    private static final boolean isUnix = isSolaris || isLinux;\n    private static final int VIOLATION_THRESHOLD = 10;\n    private static final boolean DEBUG = false;\n\n    //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n    private volatile boolean terminated;\n    private int count;\n    private int samplingInterval;\n\n    //~ Methods --------------------------------------------------------------------------------------------------------------\n\n    SamplingThread(int interval) {\n        ThreadInfo.addProfilerServerThread(this);\n        setPriority(Thread.MAX_PRIORITY);\n        setDaemon(true);\n        samplingInterval = interval;\n        if (isSolaris) {\n            samplingInterval *= 1000000; // Convert into nanos - the Solaris hires timer resolution\n        } else if (isLinux) {\n            samplingInterval *= 1000; // Convert into microseconds - the Linux hires timer resolution\n        }\n    }\n\n    public void run() {\n        int adjustedSamplingInterval = samplingInterval;\n        int upperBound = (samplingInterval * 5) / 4;\n        int lowerBound = samplingInterval / 10;\n        int violationCount = VIOLATION_THRESHOLD;\n\n        long startTime = Timers.getCurrentTimeInCounts();\n\n        while (!terminated) {\n            if (!isUnix) {\n                try {\n                    Thread.sleep(samplingInterval);\n                }  catch (InterruptedException ex) { /* Should not happen */\n                }\n            }  else { // Solaris and Linux\n\n                long time = Timers.getCurrentTimeInCounts();\n                // On Solaris, the resolution of Thread.sleep(), which boils down to the select(3C) system call, seems to be\n                // around 20 ms. So we have to use our own call, which eventually calls nanosleep() and takes an argument in nanos.\n                // On Linux (at least version 7.3 + patches, which I tried), nanosleep() seems to have a 20 ms resolution (or even\n                // give 20 ms no matter what?), which is a documented bug (see 'man nanosleep'). Well, maybe it improves in future...\n                Timers.osSleep(adjustedSamplingInterval);\n                time = Timers.getCurrentTimeInCounts()  - time;\n\n                if ((time > upperBound) && (adjustedSamplingInterval > lowerBound)) {\n                    if (violationCount > 0) {\n                        violationCount--;\n                    } else {\n                        adjustedSamplingInterval = (adjustedSamplingInterval * 95) / 100;\n                        violationCount = VIOLATION_THRESHOLD;\n                    }\n                }\n            }\n            \n            sample();\n\n            if (DEBUG) {\n                count++;\n            }\n        }\n\n        if (DEBUG && isUnix) {\n            long time = ((Timers.getCurrentTimeInCounts() - startTime) * 1000) / Timers.getNoOfCountsInSecond();\n            System.out.println(\"JFluid sampling thread: elapsed time: \" + time + \" ms, avg interval: \" + (((double) time) / count) + \"ms, adjusted interval: \" + adjustedSamplingInterval + \" OS units\"); // NOI18N\n        }\n        ThreadInfo.removeProfilerServerThread(this);\n    }\n\n    abstract void sample();\n\n    void terminate() {\n        terminated = true;\n\n        try {\n            Thread.sleep(100);\n        }  catch (InterruptedException ex) { /* Should not happen */\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/StartProfilingPointHandler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\n/**\n * Performs special handling of Start Profiling profiling points on server side.\n *\n * @author Maros Sandor\n */\npublic class StartProfilingPointHandler extends ProfilingPointServerHandler {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static ProfilingPointServerHandler instance;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static synchronized ProfilingPointServerHandler getInstance(String clientInfo) {\n        if (instance == null) {\n            instance = new StartProfilingPointHandler();\n        }\n\n        return instance;\n    }\n\n    public void profilingPointHit(int id) {\n        ThreadInfo ti = ThreadInfo.getThreadInfo();\n        ti.inCallGraph = true;\n        super.profilingPointHit(id);\n        ProfilerRuntime.dumpEventBuffer();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/StopProfilingPointHandler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\n/**\n * Performs special handling of Start Profiling profiling points on server side.\n *\n * @author Maros Sandor\n */\npublic class StopProfilingPointHandler {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class RevertInstrumentation extends ProfilingPointServerHandler {\n        //~ Static fields/initializers -------------------------------------------------------------------------------------------\n\n        private static ProfilingPointServerHandler instance;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public static synchronized ProfilingPointServerHandler getInstance(String clientInfo) {\n            if (instance == null) {\n                instance = new RevertInstrumentation();\n            }\n\n            return instance;\n        }\n\n        public void profilingPointHit(int id) {\n            super.profilingPointHit(id);\n            ProfilerRuntime.dumpEventBuffer();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/TakeHeapdumpProfilingPointHandler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.server.system.HeapDump;\nimport org.graalvm.visualvm.lib.jfluid.server.system.Timers;\nimport java.io.File;\nimport java.util.HashMap;\nimport java.util.Map;\n\n\n/**\n * Performs special handling of Take HeapDump profiling points on server side.\n *\n * @author Tomas Hurka\n */\npublic class TakeHeapdumpProfilingPointHandler extends ProfilingPointServerHandler {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static Map instances;\n    private static final String TAKEN_HEAPDUMP_PREFIX = \"heapdump-\"; // NOI18N\n    private static final String HEAPDUMP_EXTENSION = \"hprof\"; // NOI18N\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final String heapdumpFilePrefix;\n    private final boolean remoteProfiling;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private TakeHeapdumpProfilingPointHandler(String dir) {\n        heapdumpFilePrefix = dir + File.separatorChar + TAKEN_HEAPDUMP_PREFIX;\n        remoteProfiling = ProfilerServer.getProfilingSessionStatus().remoteProfiling;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static synchronized ProfilingPointServerHandler getInstance(String clientInfo) {\n        TakeHeapdumpProfilingPointHandler instance;\n\n        if (instances == null) {\n            instances = new HashMap();\n        }\n        instance = (TakeHeapdumpProfilingPointHandler) instances.get(clientInfo);\n        if (instance == null) {\n            instance = new TakeHeapdumpProfilingPointHandler(clientInfo);\n            instances.put(clientInfo, instance);\n        }\n\n        return instance;\n    }\n\n    public void profilingPointHit(int id) {\n        int instrType = ProfilerInterface.getCurrentInstrType();\n        boolean cpuProfiling = (instrType == CommonConstants.INSTR_RECURSIVE_FULL)\n                               || (instrType == CommonConstants.INSTR_RECURSIVE_SAMPLED);\n\n        if (cpuProfiling) { // CPU profiling\n            ProfilerRuntimeCPU.suspendCurrentThreadTimer();\n        }\n\n        long absTimeStamp = Timers.getCurrentTimeInCounts();\n\n        if (!remoteProfiling) { // take heap dump is supported only for local profiling\n\n            String heapdumpName = getHeapDumpName(absTimeStamp);\n            String error = HeapDump.takeHeapDump(heapdumpName);\n\n            if (error != null) {\n                System.err.println(\"Dump to \" + heapdumpName + \" failed with \" + error); // NOI18N\n            }\n        }\n\n        super.profilingPointHit(id, absTimeStamp);\n\n        if (cpuProfiling) {\n            ProfilerRuntimeCPU.resumeCurrentThreadTimer();\n        }\n    }\n\n    private String getHeapDumpName(long time) {\n        return heapdumpFilePrefix + (time & 0xFFFFFFFFFFFFFFL) + \".\" + HEAPDUMP_EXTENSION;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/TakeSnapshotProfilingPointHandler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.server.system.GC;\n\n\n/**\n * Performs special handling of Take Snapshot profiling points on server side.\n *\n * @author Tomas Hurka\n * @author Maros Sandor\n */\npublic class TakeSnapshotProfilingPointHandler extends ProfilingPointServerHandler {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static ProfilingPointServerHandler instance;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static synchronized ProfilingPointServerHandler getInstance(String clientInfo) {\n        if (instance == null) {\n            instance = new TakeSnapshotProfilingPointHandler();\n        }\n\n        return instance;\n    }\n\n    public void profilingPointHit(int id) {\n        int instrType = ProfilerInterface.getCurrentInstrType();\n        boolean cpuProfiling = (instrType == CommonConstants.INSTR_RECURSIVE_FULL)\n                               || (instrType == CommonConstants.INSTR_RECURSIVE_SAMPLED);\n\n        if (cpuProfiling) { // CPU profiling\n            ProfilerRuntimeCPU.suspendCurrentThreadTimer();\n        } else {\n            GC.runGC();\n\n            // TODO: REVISIT: to wait for ProfilerRuntimeObjLiveness.ReferenceManagerThread, should be removed once we utilize object tags\n            try {\n                Thread.sleep(300);\n            } catch (InterruptedException e) {\n            }\n        }\n\n        super.profilingPointHit(id);\n        ProfilerRuntime.dumpEventBuffer();\n\n        if (cpuProfiling) {\n            ProfilerRuntimeCPU.resumeCurrentThreadTimer();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/TakeSnapshotWithResetProfilingPointHandler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\n/**\n * Performs special handling of Take Snapshot With Reset profiling points on server side.\n *\n * @author Tomas Hurka\n * @author Maros Sandor\n */\npublic class TakeSnapshotWithResetProfilingPointHandler extends TakeSnapshotProfilingPointHandler {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static ProfilingPointServerHandler instance;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static synchronized ProfilingPointServerHandler getInstance(String clientInfo) {\n        if (instance == null) {\n            instance = new TakeSnapshotWithResetProfilingPointHandler();\n        }\n\n        return instance;\n    }\n\n    public void profilingPointHit(int id) {\n        super.profilingPointHit(id);\n        ProfilerServer.requestClientResetResults();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/ThreadInfo.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * An instance of this class is allocated for each profiled thread, to hold thread-local information, such as whether\n * the thread is currently in the profiled call subgraph, the simulated call stack, the thread-local rough generated\n * data buffer (for CPU profiling), etc. Static methods to create and lookup instances of ThreadInfo given a Thread\n * object are also provided in this class.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class ThreadInfo {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static final int MAX_EVENT_ENTRIES_IN_LOCAL_BUFFER = 500; // Thread-local buffer, in events\n    static final int MAX_EVENT_SIZE = 1 + 2 + 7 + 7; // In bytes; comprises event type, method id, and two long timestamps\n    static int evBufSize; // Size and threshold, same for each thread-local buffer\n    static int evBufPosThreshold; // Size and threshold, same for each thread-local buffer\n\n    static {\n        setDefaultEvBufParams();\n    }\n\n    static Thread[] profilerServerThreads;\n    static int nProfilerServerThreads;\n    static int nProfiledAppThreads;\n    static ThreadInfo dummyThreadInfo = new ThreadInfo(null); // Used just to avoid null checks in some situations\n    private static boolean profilingSuspended = false;\n\n    // ThreadInfo hash table\n    private static ThreadInfo[] threadInfos = new ThreadInfo[1]; // To avoid null checks - important!\n    private static final Object threadInfosLock = new Object();\n    private static int threadInfosSize;\n    private static int nThreads;\n    private static boolean hasDeadThreads;\n    private static ThreadInfo lastThreadInfo = dummyThreadInfo;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    Thread thread; // Thread object for this ThreadInfo\n    byte[] evBuf; // Thread-local event (rough profiling data) buffer. Currently used in CPU profiling only.\n    boolean inCallGraph; // Indicates whether the thread is currently in the profiled subgraph\n    boolean sampleDue; // In sampled instrumentation mode, indicates that next sampling should be done\n    int evBufDumpLastPos; // Used to avoid synchronization in writeEvent() and yet to allow for asynchronous event buffer dumps.\n    int evBufPos; // Current position in the local event buffer\n    int inProfilingRuntimeMethod; // Indicates whether currently some profiling runtime method is executed on behalf of this thread\n    int rootMethodStackDepth; // logical stack depth of the root method which is inside of marker method\n    int stackDepth; // Current logical (i.e. relative to the root method frame) stack depth\n    int threadId; // Integer ID\n    long absEntryTime; // Used to support thread suspension and code fragment profiling\n    long lastWaitStartTime; // Used in Code Region profiling for tracking wait times\n    long threadEntryTime; // Used to support thread suspension and code fragment profiling\n    private boolean initialized; // To signal that this thread is not initialized or was reset, so this threadInfo is unusable\n    List parameters;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private ThreadInfo(Thread thread) {\n        this.thread = thread;\n        inProfilingRuntimeMethod = 1; // To make possible trace method calls while ThreadInfo is initialized return immediately\n        threadId = nThreads & 0xFFFF;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public final boolean isInCallGraph() {\n        return inCallGraph;\n    }\n\n    public final Thread getThread() {\n        return thread;\n    }\n\n    public final int getThreadId() {\n        return threadId;\n    }\n\n    static boolean isProfilerServerMonitor(Object monitor) {\n        return monitor == threadInfosLock || monitor == ProfilerRuntimeMemory.classIdMapLock;\n    }\n    \n    public static boolean isCurrentThreadProfilerServerThread() {\n        return isProfilerServerThread(Thread.currentThread());\n    }\n\n    public static boolean isProfilerServerThread(Thread thread) {\n        if (profilerServerThreads == null) {\n            return false;\n        }\n\n        for (int i = 0; i < nProfilerServerThreads; i++) {\n            if (profilerServerThreads[i] == thread) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    public static synchronized void addProfilerServerThread(Thread thread) {\n        profilerServerThreads[nProfilerServerThreads++] = thread;\n    }\n\n    //-----------------------------------------------------------------------------------------------\n    // Accounting for profiler's own threads\n    //-----------------------------------------------------------------------------------------------\n\n    // We use a simple array of Threads, not a Vector (as once before) here, since Vector's \"contains()\" method's\n    // performance is really worse than that of simple compare in isProfilerThread() below. It's likely related to the\n    // fact that contains() calls one or two other methods and uses \"equals()\" for compares, rather than simple \"==\".\n    // Otherwise these methods don't have to be very sophisticated, since there are not going to be more than 3-6 such\n    // threads. Also, during CPU profiling each of them is called only once, when a ThreadInfo is created for the\n    // corresponding thread. A field is marked accordingly in ThreadInfo, and then checked in each methodEntry/Exit().\n    public static synchronized void clearProfilerServerThreads() {\n        if (profilerServerThreads == null) {\n            profilerServerThreads = new Thread[10];\n        } else {\n            for (int i = 0; i < nProfilerServerThreads; i++) {\n                profilerServerThreads[i] = null;\n            }\n\n            nProfilerServerThreads = 0;\n        }\n    }\n\n    public static boolean profilingSuspended() {\n        return profilingSuspended;\n    }\n\n    public static synchronized void removeProfilerServerThread(Thread thread) {\n        if (profilerServerThreads == null) {\n            return;\n        }\n\n        for (int i = 0; i < nProfilerServerThreads; i++) {\n            if (profilerServerThreads[i] == thread) {\n                if (i < (nProfilerServerThreads - 1)) {\n                    System.arraycopy(profilerServerThreads, i + 1, profilerServerThreads, i, nProfilerServerThreads - i - 1);\n                }\n                profilerServerThreads[nProfilerServerThreads - 1] = null;\n\n                nProfilerServerThreads--;\n\n                return;\n            }\n        }\n    }\n\n    static int getLiveServerThreads() {\n        int serverThreads = 0;\n        for (int i = 0; i < nProfilerServerThreads; i++) {\n            if (profilerServerThreads[i].isAlive()) {\n                serverThreads++;\n            }\n        }\n        return serverThreads;\n    }\n\n    public static void resumeProfiling() {\n        profilingSuspended = false;\n    }\n\n    public static void suspendProfiling() {\n        profilingSuspended = true;\n    }\n\n    static byte[] getCurrentLivenessStatus() {\n        ThreadInfo[] tis = threadInfos;\n        int resLen = nThreads;\n        byte[] res = new byte[resLen];\n\n        for (int i = 0; i < tis.length; i++) {\n            ThreadInfo ti = tis[i];\n\n            if ((ti != null) && (ti.threadId < resLen) && (ti.thread != null)) {\n                // We don't care if a new thread was created, but we don't list it - at the tool side the currently observed\n                // number of threads is also <= nThreads\n                res[ti.threadId] = ti.thread.isAlive() ? (byte) 1 : 0;\n            }\n        }\n\n        return res;\n    }\n\n    static void setDefaultEvBufParams() {\n        evBufSize = MAX_EVENT_ENTRIES_IN_LOCAL_BUFFER * MAX_EVENT_SIZE;\n        evBufPosThreshold = evBufSize - (4 * MAX_EVENT_SIZE) - 1;\n        threadInfos = new ThreadInfo[1]; // To avoid null checks\n        threadInfosSize = 0;\n    }\n\n    final boolean isInitialized() {\n        return initialized;\n    }\n\n    final void initialize() {\n        inProfilingRuntimeMethod++;\n\n        if (!isProfilerServerThread(thread)) {\n            nProfiledAppThreads++;\n        }\n\n        resetInternalState();\n        initialized = true;\n        inProfilingRuntimeMethod--;\n    }\n\n    final void useEventBuffer() {\n        evBuf = new byte[evBufSize];\n    }\n\n    void addParameter(Object par) {\n        if (parameters == null) {\n            parameters = new ArrayList();\n        }\n        parameters.add(par);\n    }\n    \n    List getParameters() {\n        return parameters;\n    }\n    \n    void clearParameters() {\n        parameters.clear();\n    }\n    \n    static int getNProfiledAppThreads() {\n        return nProfiledAppThreads;\n    }\n\n    static void setSampleDueForAllThreads() {\n        ThreadInfo[] tis = threadInfos;\n\n        for (int i = 0; i < tis.length; i++) {\n            ThreadInfo ti = tis[i];\n\n            if (ti != null) { // We don't care if a new thread was created, but we don't list it\n                ti.sampleDue = true;\n            }\n        }\n    }\n\n    static ThreadInfo getThreadInfo() {\n        Thread thread = Thread.currentThread();\n        ThreadInfo ti = lastThreadInfo;\n\n        if (ti.thread == thread) {\n            return ti;\n        }\n\n        return getThreadInfo(thread);\n    }\n\n    static ThreadInfo getThreadInfo(Thread thread) {\n        ThreadInfo ti = getThreadInfoOrNull(thread);\n\n        if (ti == null) {\n            ti = newThreadInfo(thread);\n        }\n\n        return ti;\n    }\n\n    static ThreadInfo[] getThreadInfos() {\n        return threadInfos;\n    }\n\n    static void changeAllThreadsInProfRuntimeMethodStatus(int val) {\n        synchronized (threadInfosLock) {\n            for (int i = 0; i < threadInfos.length; i++) {\n                ThreadInfo ti = threadInfos[i];\n\n                if (!ti.inCallGraph) {\n                    continue;\n                }\n\n                ti.inProfilingRuntimeMethod += val;\n            }\n        }\n    }\n\n    static void resetThreadInfoTable() {\n        ThreadInfo[] oldTIs = threadInfos;\n\n        synchronized (threadInfosLock) {\n            nProfiledAppThreads = 0;\n            lastThreadInfo = dummyThreadInfo; // To avoid null checks\n\n            for (int i = 0; i < oldTIs.length; i++) {\n                ThreadInfo ti = oldTIs[i];\n\n                if ((ti == null) || (ti.thread == null)) {\n                    oldTIs[i] = null;\n\n                    continue;\n                }\n\n                ti.initialized = false;\n            }\n        }\n    }\n\n    //-----------------------------------------------------------------------------------------------\n    // Special methods for non-standard usage of ThreadInfo\n    //-----------------------------------------------------------------------------------------------\n\n    // This method is used only by ProfilerCalibrator\n    void setEvBuf(byte[] buf) {\n        evBuf = buf;\n        evBufSize = buf.length;\n        evBufPosThreshold = buf.length - (2 * MAX_EVENT_SIZE) - 1;\n    }\n\n    static void releaseDeadThreads() {\n        ThreadInfo[] tis = threadInfos;\n\n        for (int i = 0; i < tis.length; i++) {\n            ThreadInfo ti = tis[i];\n\n            if (ti != null) {\n                Thread t = ti.thread;\n\n                if ((t != null) && !t.isAlive()) {\n                    if (ti.evBuf != null) {\n                        if (ti.evBufPos > 0) { // dump local event buffer\n                            ProfilerRuntimeCPU.copyLocalBuffer(ti);\n                        }\n                        ti.evBuf = null; // release results buffer\n                    }\n                    ti.thread = null; // release dead thread\n                    ti.parameters = null;\n                    hasDeadThreads = true;\n                }\n            }\n        }\n    }\n\n    private static int getThreadHashCode(Thread t) {\n        return System.identityHashCode(t) & 0x7fffffff;\n    }\n\n    private static ThreadInfo getThreadInfoOrNull(Thread thread) {\n        ThreadInfo[] tis = threadInfos;\n        int capacity = tis.length;\n        int pos = getThreadHashCode(thread) % capacity;\n        ThreadInfo ti;\n\n        while ((ti = tis[pos]) != null) {\n            if (ti.thread == thread) {\n                return ti;\n            } else {\n                pos = (pos + 1) % capacity;\n            }\n        }\n\n        return null;\n    }\n\n    private static void addThreadInfo(final ThreadInfo res, final Thread thread) {\n        if (threadInfosSize >= ((threadInfos.length * 3) / 4)) {\n            rehash();\n        }\n\n        int capacity = threadInfos.length;\n        int pos = getThreadHashCode(thread) % capacity;\n\n        while (threadInfos[pos] != null) {\n            pos = (pos + 1) % capacity;\n        }\n\n        threadInfos[pos] = res;\n        threadInfosSize++;\n    }\n\n    private static ThreadInfo newThreadInfo(Thread thread) {\n        synchronized (threadInfosLock) {\n            ThreadInfo ti = getThreadInfoOrNull(thread);\n\n            if (ti != null) {\n                return ti;\n            }\n\n            ThreadInfo res = new ThreadInfo(thread);\n\n            nThreads++;\n            addThreadInfo(res, thread);\n            res.inProfilingRuntimeMethod = 0;\n\n            return res;\n        }\n    }\n\n    private static void rehash() {\n        int capacity = hasDeadThreads ? threadInfos.length : (threadInfos.length * 2) + 1;\n        ThreadInfo[] newTIs = new ThreadInfo[capacity];\n        int size = 0;\n\n        for (int i = 0; i < threadInfos.length; i++) {\n            ThreadInfo ti = threadInfos[i];\n\n            if ((ti == null) || (ti.thread == null)) {\n                continue;\n            }\n\n            int pos = getThreadHashCode(ti.thread) % capacity;\n\n            while (newTIs[pos] != null) {\n                pos = (pos + 1) % capacity;\n            }\n\n            newTIs[pos] = ti;\n            size++;\n        }\n\n        threadInfos = newTIs;\n        threadInfosSize = size;\n        hasDeadThreads = false;\n    }\n\n    private void resetInternalState() {\n        evBufPos = evBufDumpLastPos = 0;\n        absEntryTime = lastWaitStartTime = threadEntryTime = 0;\n        rootMethodStackDepth = stackDepth = 0;\n        inCallGraph = sampleDue = false;\n        evBuf = null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/system/GC.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\n\n/**\n * Provides methods for monitoring GC activities.\n *\n * @author  Misha Dmitriev\n */\npublic class GC {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int OBSERVED_PERIODS = 10; // must match OBSERVED_PERIODS in GC.c\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static native int getCurrentGCEpoch();\n\n    /**\n     * Returns the following two numbers:\n     * metrics[0] - (Sum GC pause time for the last 10 periods) / (Total execution time for the last 10 periods) * 1000\n     * metrics[1] - last GC pause in microseconds\n     */\n    public static native void getGCRelativeTimeMetrics(long[] metrics);\n\n    public static native void getGCStartFinishTimes(long[] start, long[] finish);\n\n    public static native void activateGCEpochCounter(boolean activate);\n\n    /** Should be called at earliest possible time */\n    public static void initialize() {\n        // Doesn't do anything in this version\n    }\n\n    /**\n     * Returns true if two instances of class Object are adjacent in memory.\n     * Used by our memory leak monitoring mechanism.\n     * Doesn't work (always returns true) in vanilla JDK 1.5\n     */\n    public static native boolean objectsAdjacent(Object o1, Object o2);\n\n    public static native void resetGCEpochCounter();\n\n    public static native void runGC();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/system/Stacks.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\n\n/**\n * Provides methods for accessing thread stacks contents.\n *\n * @author  Misha Dmitriev\n */\npublic class Stacks {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /** Returns the number of Java frames on the stack of the current thread */\n    public static native int getCurrentJavaStackDepth(Thread thread);\n\n    /**\n     * stackDepth parameter is the maximum number of stack frames that can be sampled. Returns the actual number of\n     * stack frames sampled.\n     */\n    public static native int getCurrentStackFrameIds(Thread thread, int stackDepth, int[] stackFrameIds);\n\n    /**\n     * For the given array of jmethodIds, returns the names of the respective methods as\n     * (class name, method name and method signature) triplets.\n     * All this symbolic information is returned as a single packed array of bytes (with each string in UTF8 format).\n     * packedArrayOffsets is filled out with offsets of all of these strings.\n     *\n     * @param nMethods The number of methods, length of the methodIds array\n     * @param methodIds An array of jMethodIds for which we need their names\n     * @param packedArrayOffsets An array that, upon return from this method, will contain the indexes into the returned\n     *        array\n     * @return A packed array of bytes of triplets [class name, method name, method signature], packedArrayOffsets\n     *         contains indexes into this array for individual items\n     */\n    public static native byte[] getMethodNamesForJMethodIds(int nMethods, int[] methodIds, int[] packedArrayOffsets);\n\n    /**\n     * Get information about the stacks of all live threads\n     * @param threads used to return all threads\n     * @param states used to return thread's states\n     * @param frames used to return jMethodIds of frames of all threads\n     */\n    public static native void getAllStackTraces(Thread[][] threads, int[][] states, int[][][] frames);\n    \n    /** Clear the above stack frame buffer permanently. */\n    public static native void clearNativeStackFrameBuffer();\n\n    /**\n     * Creates the internal, C-level stack frame buffer, used for intermediate storage of data obtained using\n     * getCurrentStackFrameIds. Since just a single buffer is used, getCurrentStackFrameIds is obviously not\n     * multithread-safe. The code that uses this stuff has to use a single lock - so far not a problem for memory\n     * profiling where we use it, since normally it collects data for just every 10th object, thus the probability\n     * of contention is not very high.\n     */\n    public static native void createNativeStackFrameBuffer(int sizeInFrames);\n\n    /** Should be called at earliest possible time */\n    public static void initialize() {\n        // Doesn't do anything in this version\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/server/system/Threads.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\n\n/**\n * Provides methods for accessing various information related to threads.\n *\n * @author  Misha Dmitriev\n */\npublic class Threads {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns all live Java threads in this JVM. If the number of threads fits into the threads array, it is reused\n     * (unused elements are filled with nulls). Otherwise, or if threads is null, a new array is created.\n     */\n    public static native Thread[] getAllThreads(Thread[] threads);\n\n    //----------------- Miscellaneous\n    public static native String getJVMArguments();\n\n    public static native String getJavaCommand();\n\n    /** For each passed thread, stores its status as defined in CommonConstants, in the status array. threads may contain nulls. */\n    public static native void getThreadsStatus(Thread[] threads, int[] status);\n\n    /** Returns the total number of live Java threads. */\n    public static native int getTotalNumberOfThreads();\n\n    /** Should be called at earliest possible time */\n    public static void initialize() {\n        // Doesn't do anything in this version\n    }\n\n    /**\n     * Records a given thread as a profiler's own thread, so that targetAppTreadsExist() does not treat it as a\n     * target app thread. Note that the current implementation allows only one additional profiler thread; if this\n     * is called more than once, only the latest thread is remembered.\n     */\n    public static native void recordAdditionalProfilerOwnThread(Thread specialThread);\n\n    /**\n     * Record profiler's own threads. If excludeSpecialThread is true, record all the Java threads currently existing\n     * in this JVM, minus specialThread. Otherwise, record only the specialThread. Returns the number of recorded threads.\n     */\n    public static native int recordProfilerOwnThreads(boolean excludeSpecialThread, Thread specialThread);\n\n    public static synchronized native void resumeTargetAppThreads(Thread excludedThread);\n\n    public static synchronized native void suspendTargetAppThreads(Thread excludedThread);\n\n    /**\n     * Checks if any live target application threads still exist. A target application thread is any thread not recorded\n     * previously by recordProfilerOwnThreads() or recordAdditionalProfilerOwnThread().\n     */\n    public static native boolean targetAppThreadsExist();\n\n    public static void terminateTargetAppThreads() {\n        terminateTargetAppThreads(new ThreadDeath());\n    }\n\n    public static native void terminateTargetAppThreads(Object exception);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nMiscUtils_NotDirectoryMsg=File {0} found, but it is not a directory.\nMiscUtils_NotFileMsg=File {0} found, but it is not a normal file.\nMiscUtils_FileNotReadableMsg=File {0} found, but it is not readable.\nMiscUtils_FileNotExistMsg=File does not exist.\nMiscUtils_VmVersionMsg=Version string printed by the specified VM\\:\nMiscUtils_VmUnknownMsg=Unrecognized Java Virtual Machine - probably not a Sun HotSpot VM.\nMiscUtils_VmIncompatibleMsg=This is an incompatible Java VM - need standard HotSpot VM 1.5.x and newer\n\n# ------------------------------------------------------------------------------\n# Following are formats for time/date in a form that is tuned for user wrt to space needed and clarity/usefulness.\n# Used in saved snapshots list under combo in Profiler control panel (left)\n# ------------------------------------------------------------------------------\n# Formatting patterns are described in Java API - java.text.SimpleDateFormat\n# ------------------------------------------------------------------------------\n\n# [Name of Day], h:mm:ss AM/PM (for default [en])\nStringUtils_ThisWeekFormat=EEEE, h\\:mm\\:ss a\n# Last [Name of Day], h:mm:ss AM/PM (for default [en])\nStringUtils_LastWeekFormat='Last' EEEE, h\\:mm\\:ss a\n# Yesterday, h:mm:ss AM/PM (for default [en])\nStringUtils_YesterdayFormat='Yesterday,' h\\:mm\\:ss a\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/FileOrZipEntry.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.Locale;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n\n/**\n * A container that can represent either a plain file, or an entry in the zip/jar archive.\n * Used for unification of read operations on both types of files. So far likely not the most clean implementation.\n *\n * @author  Misha Dmitriev\n */\npublic class FileOrZipEntry {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private File file;\n    private String dirOrJar;\n    private String fileName;\n    private boolean isZipEntry;\n    private long len;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public FileOrZipEntry(String dirOrJar, String fileName) {\n        this.dirOrJar = dirOrJar;\n        this.fileName = fileName;\n\n        String lcd = dirOrJar.toLowerCase(Locale.ENGLISH);\n        isZipEntry = (lcd.endsWith(\".jar\") || lcd.endsWith(\".zip\")); // NOI18N\n        len = -1;\n    }\n\n    public FileOrZipEntry(File file) {\n        this.file = file;\n        isZipEntry = false;\n        len = -1;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public File getFile() {\n        if (isZipEntry) {\n            return null;\n        }\n\n        if (file == null) {\n            file = new File(dirOrJar, fileName);\n        }\n\n        return file;\n    }\n\n    public boolean isFile() {\n        return (!isZipEntry);\n    }\n\n    public String getFullName() {\n        if (!isZipEntry) {\n            if (file == null) {\n                file = new File(dirOrJar, fileName);\n            }\n\n            return file.getAbsolutePath();\n        } else {\n            return dirOrJar + \"/\" + fileName; // NOI18N\n        }\n    }\n\n    public InputStream getInputStream() throws IOException {\n        if (file != null) {\n            return new FileInputStream(file);\n        } else if (!isZipEntry) {\n            file = new File(dirOrJar, fileName);\n            len = file.length();\n\n            return new FileInputStream(file);\n        } else {\n            ZipFile zip = new ZipFile(dirOrJar);\n            ZipEntry entry = zip.getEntry(fileName);\n            len = entry.getSize();\n\n            return zip.getInputStream(entry);\n        }\n    }\n\n    public long getLength() throws IOException {\n        if (len != -1) {\n            return len;\n        } else if (file != null) {\n            return file.length();\n        } else if (!isZipEntry) {\n            return (new File(dirOrJar, fileName)).length();\n        } else {\n            try (ZipFile zip = new ZipFile(dirOrJar)) {\n                return zip.getEntry(fileName).getSize();\n            }\n        }\n    }\n\n    public String getName() {\n        if (isZipEntry) {\n            int lastSlashIdx = fileName.lastIndexOf('/'); // NOI18N\n\n            if (lastSlashIdx == -1) {\n                return fileName;\n            } else {\n                return fileName.substring(lastSlashIdx + 1);\n            }\n        } else {\n            if (fileName == null) {\n                fileName = file.getName();\n            }\n\n            return fileName;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/FloatSorter.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils;\n\n\n/**\n * An implementation of quick sort for float numbers.\n * The advantage of this class is that it provides a protected swap(idx1, idx2) method, that can be overridden by a\n * subclass. This allows one to easily create a subclass of FloatSorter, that would sort, for example, a data structure\n * consisting of several arrays, whose elements at the same index are viewed as a single logical record, and the order\n * of these records is determined by the order of elements in one float[] array. A subclass to sort such records should\n * override swap(). The new implementation of swap() should call super.swap() and then take care of swapping the rest\n * of the \"fields\" of the two given logical records.\n *\n * @author Misha Dmitriev\n */\npublic class FloatSorter {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private float[] x;\n    private int len;\n    private int off;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public FloatSorter(float[] x, int off, int len) {\n        this.x = x;\n        this.off = off;\n        this.len = len;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Performs sorting in ascending or descending order\n     * @param asc Defines the order of sorting: <CODE>true</CODE> means ascending order, <CODE>false</CODE> means descending order.\n     */\n    public void sort(boolean asc) {\n        if (asc) {\n            sort1Asc(off, len);\n        } else {\n            sort1Desc(off, len);\n        }\n    }\n\n    /** Swaps x[a] with x[b]. An subclass may override this method to e.g. swap other data associated with elements of the sorted array */\n    protected void swap(int a, int b) {\n        float t = x[a];\n        x[a] = x[b];\n        x[b] = t;\n    }\n\n    /** Returns the index of the median of the three indexed floats. */\n    private int med3(int a, int b, int c) {\n        return ((x[a] < x[b]) ? ((x[b] < x[c]) ? b : ((x[a] < x[c]) ? c : a)) : ((x[b] > x[c]) ? b : ((x[a] > x[c]) ? c : a)));\n    }\n\n    private void sort1Asc(int off, int len) {\n        // Insertion sort on smallest arrays\n        if (len < 7) {\n            for (int i = off; i < (len + off); i++) {\n                for (int j = i; (j > off) && (x[j - 1] > x[j]); j--) {\n                    swap(j, j - 1);\n                }\n            }\n\n            return;\n        }\n\n        // Choose a partition element, v\n        int m = off + (len >> 1); // Small arrays, middle element\n\n        if (len > 7) {\n            int l = off;\n            int n = (off + len) - 1;\n\n            if (len > 40) { // Big arrays, pseudomedian of 9\n\n                int s = len / 8;\n                l = med3(l, l + s, l + (2 * s));\n                m = med3(m - s, m, m + s);\n                n = med3(n - (2 * s), n - s, n);\n            }\n\n            m = med3(l, m, n); // Mid-size, med of 3\n        }\n\n        float v = x[m];\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int a = off;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int b = a;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int c = (off + len) - 1;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int d = c;\n\n        while (true) {\n            while ((b <= c) && (x[b] <= v)) {\n                if (x[b] == v) {\n                    swap(a++, b);\n                }\n\n                b++;\n            }\n\n            while ((c >= b) && (x[c] >= v)) {\n                if (x[c] == v) {\n                    swap(c, d--);\n                }\n\n                c--;\n            }\n\n            if (b > c) {\n                break;\n            }\n\n            swap(b++, c--);\n        }\n\n        // Swap partition elements back to middle\n        int s;\n\n        // Swap partition elements back to middle\n        int n = off + len;\n        s = Math.min(a - off, b - a);\n        vecswap(off, b - s, s);\n        s = Math.min(d - c, n - d - 1);\n        vecswap(b, n - s, s);\n\n        // Recursively sort non-partition-elements\n        if ((s = b - a) > 1) {\n            sort1Asc(off, s);\n        }\n\n        if ((s = d - c) > 1) {\n            sort1Asc(n - s, s);\n        }\n    }\n\n    private void sort1Desc(int off, int len) {\n        // Insertion sort on smallest arrays\n        if (len < 7) {\n            for (int i = off; i < (len + off); i++) {\n                for (int j = i; (j > off) && (x[j - 1] < x[j]); j--) {\n                    swap(j, j - 1);\n                }\n            }\n\n            return;\n        }\n\n        // Choose a partition element, v\n        int m = off + (len >> 1); // Small arrays, middle element\n\n        if (len > 7) {\n            int l = off;\n            int n = (off + len) - 1;\n\n            if (len > 40) { // Big arrays, pseudomedian of 9\n\n                int s = len / 8;\n                l = med3(l, l + s, l + (2 * s));\n                m = med3(m - s, m, m + s);\n                n = med3(n - (2 * s), n - s, n);\n            }\n\n            m = med3(l, m, n); // Mid-size, med of 3\n        }\n\n        float v = x[m];\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int a = off;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int b = a;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int c = (off + len) - 1;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int d = c;\n\n        while (true) {\n            while ((b <= c) && (x[b] >= v)) {\n                if (x[b] == v) {\n                    swap(a++, b);\n                }\n\n                b++;\n            }\n\n            while ((c >= b) && (x[c] <= v)) {\n                if (x[c] == v) {\n                    swap(c, d--);\n                }\n\n                c--;\n            }\n\n            if (b > c) {\n                break;\n            }\n\n            swap(b++, c--);\n        }\n\n        // Swap partition elements back to middle\n        int s;\n\n        // Swap partition elements back to middle\n        int n = off + len;\n        s = Math.min(a - off, b - a);\n        vecswap(off, b - s, s);\n        s = Math.min(d - c, n - d - 1);\n        vecswap(b, n - s, s);\n\n        // Recursively sort non-partition-elements\n        if ((s = b - a) > 1) {\n            sort1Desc(off, s);\n        }\n\n        if ((s = d - c) > 1) {\n            sort1Desc(n - s, s);\n        }\n    }\n\n    /** Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)]. */\n    private void vecswap(int a, int b, int n) {\n        for (int i = 0; i < n; i++, a++, b++) {\n            swap(a, b);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/IntSorter.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils;\n\n\n/**\n * An implementation of quick sort for integer numbers.\n * The advantage of this class is that it provides a protected swap(idx1, idx2) method, that can be overridden by a\n * subclass. This allows one to easily create a subclass of IntSorter, that would sort, for example, a data structure\n * consisting of several arrays, whose elements at the same index are viewed as a single logical record, and the order\n * of these records is determined by the order of elements in one int[] array. A subclass to sort such records should\n * override swap(). The new implementation of swap() should call super.swap() and then take care of swapping the rest\n * of the \"fields\" of the two given logical records.\n *\n * @author Misha Dmitriev\n */\npublic class IntSorter {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int[] x;\n    private int len;\n    private int off;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public IntSorter(int[] x, int off, int len) {\n        this.x = x;\n        this.off = off;\n        this.len = len;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Performs sorting in ascending or descending order\n     * @param asc Defines the order of sorting: <CODE>true</CODE> means ascending order, <CODE>false</CODE> means descending order.\n     */\n    public void sort(boolean asc) {\n        if (asc) {\n            sort1Asc(off, len);\n        } else {\n            sort1Desc(off, len);\n        }\n    }\n\n    /** Swaps x[a] with x[b]. An subclass may override this method to e.g. swap other data associated with elements of the sorted array */\n    protected void swap(int a, int b) {\n        int t = x[a];\n        x[a] = x[b];\n        x[b] = t;\n    }\n\n    /** Returns the index of the median of the three indexed integers. */\n    private int med3(int a, int b, int c) {\n        return ((x[a] < x[b]) ? ((x[b] < x[c]) ? b : ((x[a] < x[c]) ? c : a)) : ((x[b] > x[c]) ? b : ((x[a] > x[c]) ? c : a)));\n    }\n\n    private void sort1Asc(int off, int len) {\n        // Insertion sort on smallest arrays\n        if (len < 7) {\n            for (int i = off; i < (len + off); i++) {\n                for (int j = i; (j > off) && (x[j - 1] > x[j]); j--) {\n                    swap(j, j - 1);\n                }\n            }\n\n            return;\n        }\n\n        // Choose a partition element, v\n        int m = off + (len >> 1); // Small arrays, middle element\n\n        if (len > 7) {\n            int l = off;\n            int n = (off + len) - 1;\n\n            if (len > 40) { // Big arrays, pseudomedian of 9\n\n                int s = len / 8;\n                l = med3(l, l + s, l + (2 * s));\n                m = med3(m - s, m, m + s);\n                n = med3(n - (2 * s), n - s, n);\n            }\n\n            m = med3(l, m, n); // Mid-size, med of 3\n        }\n\n        int v = x[m];\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int a = off;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int b = a;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int c = (off + len) - 1;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int d = c;\n\n        while (true) {\n            while ((b <= c) && (x[b] <= v)) {\n                if (x[b] == v) {\n                    swap(a++, b);\n                }\n\n                b++;\n            }\n\n            while ((c >= b) && (x[c] >= v)) {\n                if (x[c] == v) {\n                    swap(c, d--);\n                }\n\n                c--;\n            }\n\n            if (b > c) {\n                break;\n            }\n\n            swap(b++, c--);\n        }\n\n        // Swap partition elements back to middle\n        int s;\n\n        // Swap partition elements back to middle\n        int n = off + len;\n        s = Math.min(a - off, b - a);\n        vecswap(off, b - s, s);\n        s = Math.min(d - c, n - d - 1);\n        vecswap(b, n - s, s);\n\n        // Recursively sort non-partition-elements\n        if ((s = b - a) > 1) {\n            sort1Asc(off, s);\n        }\n\n        if ((s = d - c) > 1) {\n            sort1Asc(n - s, s);\n        }\n    }\n\n    private void sort1Desc(int off, int len) {\n        // Insertion sort on smallest arrays\n        if (len < 7) {\n            for (int i = off; i < (len + off); i++) {\n                for (int j = i; (j > off) && (x[j - 1] < x[j]); j--) {\n                    swap(j, j - 1);\n                }\n            }\n\n            return;\n        }\n\n        // Choose a partition element, v\n        int m = off + (len >> 1); // Small arrays, middle element\n\n        if (len > 7) {\n            int l = off;\n            int n = (off + len) - 1;\n\n            if (len > 40) { // Big arrays, pseudomedian of 9\n\n                int s = len / 8;\n                l = med3(l, l + s, l + (2 * s));\n                m = med3(m - s, m, m + s);\n                n = med3(n - (2 * s), n - s, n);\n            }\n\n            m = med3(l, m, n); // Mid-size, med of 3\n        }\n\n        int v = x[m];\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int a = off;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int b = a;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int c = (off + len) - 1;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int d = c;\n\n        while (true) {\n            while ((b <= c) && (x[b] >= v)) {\n                if (x[b] == v) {\n                    swap(a++, b);\n                }\n\n                b++;\n            }\n\n            while ((c >= b) && (x[c] <= v)) {\n                if (x[c] == v) {\n                    swap(c, d--);\n                }\n\n                c--;\n            }\n\n            if (b > c) {\n                break;\n            }\n\n            swap(b++, c--);\n        }\n\n        // Swap partition elements back to middle\n        int s;\n\n        // Swap partition elements back to middle\n        int n = off + len;\n        s = Math.min(a - off, b - a);\n        vecswap(off, b - s, s);\n        s = Math.min(d - c, n - d - 1);\n        vecswap(b, n - s, s);\n\n        // Recursively sort non-partition-elements\n        if ((s = b - a) > 1) {\n            sort1Desc(off, s);\n        }\n\n        if ((s = d - c) > 1) {\n            sort1Desc(n - s, s);\n        }\n    }\n\n    /** Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)]. */\n    private void vecswap(int a, int b, int n) {\n        for (int i = 0; i < n; i++, a++, b++) {\n            swap(a, b);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/IntVector.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils;\n\n\n/**\n * A Vector of ints. Implements a subset of standard java.util.Vector class\n *\n * @author Misha Dmitriev\n */\npublic class IntVector {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int[] vec;\n    private int size;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public IntVector() {\n        this(10);\n    }\n\n    public IntVector(int capacity) {\n        vec = new int[capacity];\n        size = 0;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void add(int val) {\n        if (size == vec.length) {\n            int[] oldVec = vec;\n            vec = new int[oldVec.length * 2];\n            System.arraycopy(oldVec, 0, vec, 0, oldVec.length);\n        }\n\n        vec[size++] = val;\n    }\n\n    public void clear() {\n        size = 0;\n    }\n\n    public int get(int idx) {\n        return vec[idx];\n    }\n\n    public int size() {\n        return size;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/LongSorter.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils;\n\n\n/**\n * An implementation of quick sort for long numbers.\n * The advantage of this class is that it provides a protected swap(idx1, idx2) method, that can be overridden by a\n * subclass. This allows one to easily create a subclass of LongSorter, that would sort, for example, a data structure\n * consisting of several arrays, whose elements at the same index are viewed as a single logical record, and the order\n * of these records is determined by the order of elements in one long[] array. A subclass to sort such records should\n * override swap(). The new implementation of swap() should call super.swap() and then take care of swapping the rest\n * of the \"fields\" of the two given logical records.\n *\n * @author Misha Dmitriev\n */\npublic class LongSorter {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private long[] x;\n    private int len;\n    private int off;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public LongSorter(long[] x, int off, int len) {\n        this.x = x;\n        this.off = off;\n        this.len = len;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Performs sorting in ascending or descending order\n     * @param asc Defines the order of sorting: <CODE>true</CODE> means ascending order, <CODE>false</CODE> means descending order.\n     */\n    public void sort(boolean asc) {\n        if (asc) {\n            sort1Asc(off, len);\n        } else {\n            sort1Desc(off, len);\n        }\n    }\n\n    /** Swaps x[a] with x[b]. An subclass may override this method to e.g. swap other data associated with elements of the sorted array */\n    protected void swap(int a, int b) {\n        long t = x[a];\n        x[a] = x[b];\n        x[b] = t;\n    }\n\n    /** Returns the index of the median of the three indexed integers. */\n    private int med3(int a, int b, int c) {\n        return ((x[a] < x[b]) ? ((x[b] < x[c]) ? b : ((x[a] < x[c]) ? c : a)) : ((x[b] > x[c]) ? b : ((x[a] > x[c]) ? c : a)));\n    }\n\n    private void sort1Asc(int off, int len) {\n        // Insertion sort on smallest arrays\n        if (len < 7) {\n            for (int i = off; i < (len + off); i++) {\n                for (int j = i; (j > off) && (x[j - 1] > x[j]); j--) {\n                    swap(j, j - 1);\n                }\n            }\n\n            return;\n        }\n\n        // Choose a partition element, v\n        int m = off + (len >> 1); // Small arrays, middle element\n\n        if (len > 7) {\n            int l = off;\n            int n = (off + len) - 1;\n\n            if (len > 40) { // Big arrays, pseudomedian of 9\n\n                int s = len / 8;\n                l = med3(l, l + s, l + (2 * s));\n                m = med3(m - s, m, m + s);\n                n = med3(n - (2 * s), n - s, n);\n            }\n\n            m = med3(l, m, n); // Mid-size, med of 3\n        }\n\n        long v = x[m];\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int a = off;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int b = a;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int c = (off + len) - 1;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int d = c;\n\n        while (true) {\n            while ((b <= c) && (x[b] <= v)) {\n                if (x[b] == v) {\n                    swap(a++, b);\n                }\n\n                b++;\n            }\n\n            while ((c >= b) && (x[c] >= v)) {\n                if (x[c] == v) {\n                    swap(c, d--);\n                }\n\n                c--;\n            }\n\n            if (b > c) {\n                break;\n            }\n\n            swap(b++, c--);\n        }\n\n        // Swap partition elements back to middle\n        int s;\n\n        // Swap partition elements back to middle\n        int n = off + len;\n        s = Math.min(a - off, b - a);\n        vecswap(off, b - s, s);\n        s = Math.min(d - c, n - d - 1);\n        vecswap(b, n - s, s);\n\n        // Recursively sort non-partition-elements\n        if ((s = b - a) > 1) {\n            sort1Asc(off, s);\n        }\n\n        if ((s = d - c) > 1) {\n            sort1Asc(n - s, s);\n        }\n    }\n\n    private void sort1Desc(int off, int len) {\n        // Insertion sort on smallest arrays\n        if (len < 7) {\n            for (int i = off; i < (len + off); i++) {\n                for (int j = i; (j > off) && (x[j - 1] < x[j]); j--) {\n                    swap(j, j - 1);\n                }\n            }\n\n            return;\n        }\n\n        // Choose a partition element, v\n        int m = off + (len >> 1); // Small arrays, middle element\n\n        if (len > 7) {\n            int l = off;\n            int n = (off + len) - 1;\n\n            if (len > 40) { // Big arrays, pseudomedian of 9\n\n                int s = len / 8;\n                l = med3(l, l + s, l + (2 * s));\n                m = med3(m - s, m, m + s);\n                n = med3(n - (2 * s), n - s, n);\n            }\n\n            m = med3(l, m, n); // Mid-size, med of 3\n        }\n\n        long v = x[m];\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int a = off;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int b = a;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int c = (off + len) - 1;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int d = c;\n\n        while (true) {\n            while ((b <= c) && (x[b] >= v)) {\n                if (x[b] == v) {\n                    swap(a++, b);\n                }\n\n                b++;\n            }\n\n            while ((c >= b) && (x[c] <= v)) {\n                if (x[c] == v) {\n                    swap(c, d--);\n                }\n\n                c--;\n            }\n\n            if (b > c) {\n                break;\n            }\n\n            swap(b++, c--);\n        }\n\n        // Swap partition elements back to middle\n        int s;\n\n        // Swap partition elements back to middle\n        int n = off + len;\n        s = Math.min(a - off, b - a);\n        vecswap(off, b - s, s);\n        s = Math.min(d - c, n - d - 1);\n        vecswap(b, n - s, s);\n\n        // Recursively sort non-partition-elements\n        if ((s = b - a) > 1) {\n            sort1Desc(off, s);\n        }\n\n        if ((s = d - c) > 1) {\n            sort1Desc(n - s, s);\n        }\n    }\n\n    /** Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)]. */\n    private void vecswap(int a, int b, int n) {\n        for (int i = 0; i < n; i++, a++, b++) {\n            swap(a, b);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/MiscUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.file.DirectoryStream;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.text.MessageFormat;\nimport java.util.*;\nimport java.util.jar.Attributes;\nimport java.util.jar.JarFile;\nimport java.util.jar.Manifest;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\n\n\n/**\n * Miscellaneous utilities for class names/path management, file management, and printing/logging.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class MiscUtils {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String NOT_DIRECTORY_MSG;\n    private static final String NOT_FILE_MSG;\n    private static final String FILE_NOT_READABLE_MSG;\n    private static final String FILE_NOT_EXIST_MSG;\n    private static final String VM_VERSION_MSG;\n    private static final String VM_UNKNOWN_MSG;\n    private static final String VM_INCOMPATIBLE_MSG;\n\n    static {\n        ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.utils.Bundle\"); // NOI18N\n        NOT_DIRECTORY_MSG = messages.getString(\"MiscUtils_NotDirectoryMsg\"); // NOI18N\n        NOT_FILE_MSG = messages.getString(\"MiscUtils_NotFileMsg\"); // NOI18N\n        FILE_NOT_READABLE_MSG = messages.getString(\"MiscUtils_FileNotReadableMsg\"); // NOI18N\n        FILE_NOT_EXIST_MSG = messages.getString(\"MiscUtils_FileNotExistMsg\"); // NOI18N\n        VM_VERSION_MSG = messages.getString(\"MiscUtils_VmVersionMsg\"); // NOI18N\n        VM_UNKNOWN_MSG = messages.getString(\"MiscUtils_VmUnknownMsg\"); // NOI18N\n        VM_INCOMPATIBLE_MSG = messages.getString(\"MiscUtils_VmIncompatibleMsg\"); // NOI18N\n    }\n\n    // ------------------------------------------------------------------------------------------------\n    //    Printing/logging management\n    // ------------------------------------------------------------------------------------------------\n    private static boolean verbosePrint = false;\n    private static boolean printInfo = true;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static String getAbsoluteFilePath(String fileName, String baseDir) {\n        boolean local = false;\n\n        // If the name is in the local form, convert it into an absolute form\n        if (fileName.startsWith(\".\")) { // NOI18N\n            local = true;\n        } else {\n            if (Platform.isWindows()) {\n                if (!((fileName.charAt(0) == '\\\\') || (fileName.charAt(0) == '/') // NOI18N\n                        || ((fileName.length() > 1) && (fileName.charAt(1) == ':')))) { // NOI18N\n                    local = true;\n                }\n            } else {\n                if (!((fileName.charAt(0) == '/') || (fileName.charAt(0) == '~'))) { // NOI18N\n                    local = true;\n                }\n            }\n        }\n\n        if (local) {\n            fileName = baseDir + \"/\" + fileName; // NOI18N\n        }\n\n        return fileName;\n    }\n\n    public static void getAllClassesInDir(String dirName, String packageName, boolean removeClassExt, Collection res) {\n        File dir = new File(dirName);\n        String[] fileNames = dir.list();\n\n        if (fileNames == null) {\n            return;\n        }\n\n        for (String fileName : fileNames) {\n            if (fileName.endsWith(\".class\")) { // NOI18N\n\n                String className = packageName\n                                   + (removeClassExt ? fileName.substring(0, fileName.length() - 6) : fileName);\n                res.add(className.intern());\n            } else {\n                String subDirName = dirName + File.separator + fileName;\n                File subDir = new File(subDirName);\n\n                if (subDir.exists() && subDir.isDirectory()) {\n                    String subPackage = packageName + fileName + \"/\"; // NOI18N\n                    getAllClassesInDir(subDirName, subPackage, removeClassExt, res);\n                }\n            }\n        }\n    }\n\n    public static void getAllClassesInJar(String jarName, boolean removeClassExt, Collection res) {\n        ZipFile zip = null;\n\n        try {\n            zip = new ZipFile(jarName);\n            for (Enumeration entries = zip.entries(); entries.hasMoreElements();) {\n                ZipEntry entry = (ZipEntry) entries.nextElement();\n                String className = entry.getName();\n\n                if (className.endsWith(\".class\")) { // NOI18N\n\n                    if (removeClassExt) {\n                        className = className.substring(0, className.length() - 6);\n                    }\n\n                    res.add(className.intern());\n                }\n            }\n            zip.close();\n        } catch (Exception ex) {\n            System.err.println(\"Warning: could not open archive \" + jarName); // NOI18N\n\n            return;\n        }\n    }\n\n    // ------------------------------------------------------------------------------------------------\n    //    File management\n    // ------------------------------------------------------------------------------------------------\n    public static String getCanonicalPath(File file) {\n        try {\n            if (!file.exists()) {\n                return null;\n            }\n\n            return file.getCanonicalPath();\n        } catch (IOException e) {\n            return null;\n        }\n    }\n\n    // -----\n\n    // ------------------------------------------------------------------------------------------------\n    //   Class name and class path management\n    // ------------------------------------------------------------------------------------------------\n\n    /** Determine the outermost class name for the given source file, based on the available source path\n     * @param sourceFileName the name of the source file\n     * @param mainSourcePath the main source path to search within\n     * @param secondarySourcePath the secondary source path to search within\n     */\n    public static String getClassNameForSource(String sourceFileName, String mainSourcePath, String secondarySourcePath,\n                                               String workingDir) {\n        if ((sourceFileName.charAt(1) == ':') && !Character.isLowerCase(sourceFileName.charAt(0))) { // NOI18N\n            sourceFileName = sourceFileName.substring(0, 1).toLowerCase() + sourceFileName.substring(1);\n        }\n\n        for (int i = 0; i < 2; i++) {\n            String sourcePath = ((i == 0) ? mainSourcePath : secondarySourcePath);\n\n            if (sourcePath == null) {\n                continue;\n            }\n\n            List paths = getPathComponents(sourcePath, true, workingDir);\n\n            for (int j = 0; j < paths.size(); j++) {\n                String path = (String) paths.get(j);\n\n                if ((path.charAt(1) == ':') && !Character.isLowerCase(path.charAt(0))) { // NOI18N\n                    path = path.substring(0, 1).toLowerCase() + path.substring(1);\n                }\n\n                if (!path.endsWith(File.separator)) {\n                    path += File.separator;\n                }\n\n                if (sourceFileName.startsWith(path)) {\n                    String className = sourceFileName.substring(path.length(), sourceFileName.length() - 5);\n\n                    return className.replace(File.separatorChar, '.'); // NOI18N\n                }\n            }\n        }\n\n        return null;\n    }\n\n    public static String getFirstPathComponent(String path) {\n        int pos = path.indexOf(File.pathSeparatorChar);\n\n        if (pos == -1) {\n            return path;\n        } else {\n            return path.substring(0, pos);\n        }\n    }\n\n    // ------------------------------------------------------------------------------------------------\n    //    JDK version determination for a given executable file\n    // ------------------------------------------------------------------------------------------------\n    public static String getJDKVersionForJVMExeFile(File exeFile)\n                                             throws IOException {\n        String[] cmdLine = new String[] { exeFile.getAbsolutePath(), \"-version\" }; // NOI18N\n        Process javaProcess = Runtime.getRuntime().exec(cmdLine);\n\n        //javaProcess.waitFor(); // this should probably be here\n        InputStream bis = javaProcess.getErrorStream();\n\n        int maxLen = 500;\n        int availBytes;\n        int readBytes;\n        int ofs = 0;\n        byte[] bytes = new byte[maxLen];\n\n        do {\n            availBytes = bis.available();\n\n            if (availBytes == 0) {\n                availBytes = 1;\n            }\n\n            if ((ofs + availBytes) >= maxLen) {\n                availBytes = maxLen - ofs;\n            }\n\n            readBytes = bis.read(bytes, ofs, availBytes);\n\n            if (readBytes != -1) {\n                ofs += readBytes;\n            }\n        } while ((readBytes != -1) && (ofs < maxLen));\n\n        bis.close();\n\n        String outString = new String(bytes, 0, ofs);\n        String printOutString = \"\\n\" + VM_VERSION_MSG + \"\\n\" + outString; // NOI18N\n\n        // The string should start with something like 'java version \"1.5.0\"' (note the quotes). Let's remove the stuff before the quote\n        int pos = outString.indexOf('\\\"'); // NOI18N\n\n        if (pos == -1) {\n            throw new IOException(VM_UNKNOWN_MSG + printOutString);\n        }\n\n        outString = outString.substring(pos + 1);\n\n        return Platform.getJDKVersionString(outString);\n    }\n\n    /** For a string representing a class path, remove all entries that don't correspond to existing files, and return the remaining ones. */\n    public static String getLiveClassPathSubset(String path, String workingDir) {\n        List liveComponents = getPathComponents(path, true, workingDir);\n        StringBuilder buf = new StringBuilder(liveComponents.size() * 10);\n\n        if (!liveComponents.isEmpty()) {\n            buf.append((String) liveComponents.get(0));\n\n            for (int i = 1; i < liveComponents.size(); i++) {\n                buf.append(File.pathSeparator);\n                buf.append((String) liveComponents.get(i));\n            }\n        }\n\n        return buf.toString();\n    }\n\n    /**\n     * Returns the components of the compound path, such as CLASSPATH. If doCheck is true,\n     * checks if each of the components really exists, i.e. is an existing directory or file,\n     * and returns only existing components. workingDir is needed in case the passed path has\n     * a local form.\n     */\n    public static List getPathComponents(String path, boolean doCheck, String workingDir) {\n        ArrayList list = new ArrayList();\n\n        if (path != null) {\n            StringTokenizer tok = new StringTokenizer(path, File.pathSeparator);\n\n            while (tok.hasMoreTokens()) {\n                String name = tok.nextToken();\n                boolean addedToList = false;\n                \n                if ((name == null) || (name.length() == 0)) {\n                    continue; // Essentially sanity check, but who knows?\n                }\n\n                if (doCheck) {\n                    name = getAbsoluteFilePath(name, workingDir);\n                    name = getCanonicalPath(new File(name)); // clean up the name into a canonical path\n                    if (name != null && !list.contains(name)) {\n                        list.add(name);\n                        addedToList = true;\n                    }\n                } else {\n                    list.add(name);\n                    addedToList = true;\n                }\n                if (addedToList) {\n                    try {\n                        getClassPathFromManifest(name,list);\n                    } catch (URISyntaxException ex) {\n                        System.out.println(\"Error processing \"+name);   // NOI18N\n                        ex.printStackTrace();\n                    } catch (IOException ex) {\n                        System.out.println(\"Error processing \"+name);   // NOI18N\n                        ex.printStackTrace();\n                    }\n                }\n            }\n        }\n        return list;\n    }\n\n    private static void getClassPathFromManifest(String jarPath,List pathList) throws IOException, URISyntaxException {\n        if (jarPath.toLowerCase(Locale.ENGLISH).endsWith(\".jar\")) {   // NOI18N\n            File pathFile = new File(jarPath);\n            try (JarFile jarFile = new JarFile(pathFile)) {\n                Manifest manifest = jarFile.getManifest();\n\n                if (manifest != null) {\n                    Attributes attrs = manifest.getMainAttributes();\n\n                    if (attrs != null) {\n                        String jarCp = attrs.getValue(Attributes.Name.CLASS_PATH);\n\n                        if (jarCp != null) {\n                            File parent = pathFile.getParentFile();\n                            StringTokenizer tokens = new StringTokenizer(jarCp);\n\n                            while(tokens.hasMoreTokens()) {\n                                URI fileUri = new URI(tokens.nextToken());\n                                File cpFile;\n                                String cpName;\n\n                                if (!fileUri.isAbsolute()) {\n                                    cpFile = new File(parent,fileUri.getPath());\n                                } else {\n                                    cpFile = new File(fileUri);\n                                }\n                                cpName = getCanonicalPath(cpFile);\n                                if (cpName != null && !pathList.contains(cpName)) {\n                                    pathList.add(cpName);\n                                    getClassPathFromManifest(cpName,pathList);\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    \n    private static boolean addToList(File file,List path) {\n        String pathName = getCanonicalPath(file);\n        \n        if (pathName != null && !path.contains(pathName)) {\n            path.add(pathName);\n            return true;\n        }\n        return false;\n    }\n    \n    public static void setSilent(boolean silent) {\n        printInfo = !silent;\n    }\n\n    public static boolean isSlashedJavaCoreClassName(String name) {\n        return (name.startsWith(\"java/\") || name.startsWith(\"sun/\") || name.startsWith(\"javax/\")); // NOI18N\n    }\n\n    public static boolean isSupportedJVM(Map jdkProperties) {\n        String jdkVersionString = (String) jdkProperties.get(\"java.version\"); // NOI18N\n        String vmNameString = (String) jdkProperties.get(\"java.vm.name\"); // NOI18N\n\n        if (jdkVersionString == null || vmNameString == null) { // probably not a platform for JDK\n            return false;\n        }\n\n        if (isSupportedJDK(jdkVersionString)) {\n            return true;\n        }\n        // CVM is recognized via java.vm.name system property\n        return isSupportedJDK(vmNameString);\n    }\n\n    // This method is used for checking running JVM if supported.\n    // jvmVersionString should be enough to decide that\n    public static boolean isSupportedRunningJVMVersion(String jdkVersionString) {\n        return isSupportedJDK(jdkVersionString);\n    }\n\n    public static void setVerbosePrint() {\n        verbosePrint = true;\n    }\n\n    public static File checkDirForName(String name) throws IOException {\n        File file = new File(name);\n\n        return checkFile(file, true);\n    }\n\n    public static File checkFile(File file, boolean isDir)\n                          throws IOException {\n        if (file.exists()) {\n            if (isDir) {\n                if (!file.isDirectory()) {\n                    throw new IOException(MessageFormat.format(NOT_DIRECTORY_MSG, new Object[] { file }));\n                }\n            } else {\n                if (!file.isFile()) {\n                    throw new IOException(MessageFormat.format(NOT_FILE_MSG, new Object[] { file }));\n                }\n            }\n\n            if (!file.canRead()) {\n                throw new IOException(MessageFormat.format(FILE_NOT_READABLE_MSG, new Object[] { file }));\n            }\n\n            return file;\n        } else {\n            throw new IOException(FILE_NOT_EXIST_MSG);\n        }\n    }\n\n    public static File checkFileForName(String name) throws IOException {\n        File file = new File(name);\n\n        return checkFile(file, false);\n    }\n\n    /** Checks if given directory is already listed on path */\n    public static boolean containsDirectoryOnPath(String directory, String path) {\n        String normalizedDirectory = new File(directory).getAbsolutePath().toLowerCase(Locale.ENGLISH);\n        String normalizedPath = new File(path).getAbsolutePath().toLowerCase(Locale.ENGLISH);\n        List pathComponents = getPathComponents(normalizedPath, false, null);\n\n        for (int i = 0; i < pathComponents.size(); i++) {\n            if (normalizedDirectory.equals(pathComponents.get(i))) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    public static void deleteHeapTempFiles() {\n        if (Platform.isWindows()) { // this is workaroud for JDK bug #6359560\n\n            File tempDir = new File(System.getProperty(\"java.io.tmpdir\")); // NOI18N\n            try (DirectoryStream<Path> files = Files.newDirectoryStream(tempDir.toPath())) {\n                for (Path p : files) {\n                    String fname = p.toFile().getName();\n\n                    if (fname.startsWith(\"NBProfiler\") && (fname.endsWith(\".map\") || fname.endsWith(\".ref\") || fname.endsWith(\".gc\"))) { // NOI18N\n                        Files.delete(p);\n                    }\n                }\n            } catch (IOException ex) {\n                System.err.println(\"deleteHeapTempFiles failed\");   // NOI18N\n                ex.printStackTrace();\n            }\n        }\n    }\n\n    public static boolean fileForNameOk(String name) {\n        try {\n            checkFileForName(name);\n\n            return true;\n        } catch (IOException ex) {\n            return false;\n        }\n    }\n\n    public static boolean inSamePackage(String className1, String className2) {\n        int ldi1 = className1.lastIndexOf('.'); // NOI18N\n        int ldi2 = className2.lastIndexOf('.'); // NOI18N\n\n        if (ldi1 != ldi2) {\n            return false;\n        }\n\n        if (ldi1 == -1) {\n            return true;\n        }\n\n        return (className1.substring(0, ldi1).equals(className2.substring(0, ldi2)));\n    }\n\n    /**\n     * Method to handle internal error condition.\n     *\n     * @param message The message describing the error\n     */\n    public static void internalError(String message) {\n        throw new InternalError(message);\n    }\n\n    public static void printErrorMessage(String message) {\n        System.err.println(\"*** Profiler error (\" + getDate() + \"): \" + message); // NOI18N\n    }\n\n    public static void printInfoMessage(String message) {\n        if (printInfo) {\n            System.err.println(\"*** Profiler message (\" + getDate() + \"): \" + message); // NOI18N\n        }\n    }\n\n    public static void printVerboseInfoMessage(String message) {\n        if (verbosePrint) {\n            System.err.println(\"Profiler Engine: \" + message); // NOI18N\n        }\n    }\n\n    public static void printVerboseInfoMessage(String[] elements) {\n        if (!verbosePrint) {\n            return;\n        }\n\n        int i;\n\n        for (i = 0; i < (elements.length - 1); i++) {\n            System.err.print(elements[i]);\n            System.err.print(\" \"); // NOI18N\n        }\n\n        System.err.println(elements[i]);\n    }\n\n    public static void printWarningMessage(String message) {\n        System.err.println(\"*** Profiler warning (\" + getDate() + \"): \" + message); // NOI18N\n    }\n\n    public static byte[] readFileIntoBuffer(FileOrZipEntry fileOrZip)\n                                     throws IOException {\n        if (fileOrZip.isFile()) {\n            checkFile(fileOrZip.getFile(), false);\n        }\n\n        try (InputStream in = fileOrZip.getInputStream()) {\n            int len = (int) fileOrZip.getLength();\n            byte[] buf = new byte[len];\n            int readBytes;\n            int ofs = 0;\n            int remBytes = len;\n            do {\n                readBytes = in.read(buf, ofs, remBytes);\n                ofs += readBytes;\n                remBytes -= readBytes;\n            } while (ofs < len);\n            return buf;\n        }\n    }\n\n    private static String getDate() {\n        return (new Date()).toString();\n    }\n\n    private static boolean isSupportedJDK(String jdkVersionString) {\n        int jdkVersionNumber = Platform.getJDKVersionNumber(jdkVersionString);\n        if (jdkVersionNumber == Platform.JDK_15) {\n            if (jdkVersionString.equals(\"1.5.0\") || jdkVersionString.startsWith(\"1.5.0_01\") ||  // NOI18N\n                jdkVersionString.startsWith(\"1.5.0_02\") || jdkVersionString.startsWith(\"1.5.0_03\")) { // NOI18N\n                return false;\n            } else {\n                return true;\n            }\n        }\n        return jdkVersionNumber != Platform.JDK_UNSUPPORTED;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/StringSorter.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils;\n\n\n/**\n * An implementation of quick sort for Strings numbers.\n * The advantage of this class is that it provides a protected swap(idx1, idx2) method, that can be overridden by a\n * subclass. This allows one to easily create a subclass of IntSorter, that would sort, for example, a data structure\n * consisting of several arrays, whose elements at the same index are viewed as a single logical record, and the order\n * of these records is determined by the order of elements in one int[] array. A subclass to sort such records should\n * override swap(). The new implementation of swap() should call super.swap() and then take care of swapping the rest\n * of the \"fields\" of the two given logical records.\n *\n * @author Misha Dmitriev\n */\npublic class StringSorter {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private String[] x;\n    private int len;\n    private int off;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public StringSorter(String[] x, int off, int len) {\n        this.x = x;\n        this.off = off;\n        this.len = len;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Performs sorting in ascending or descending order\n     * @param asc Defines the order of sorting: <CODE>true</CODE> means ascending order, <CODE>false</CODE> means descending order.\n     */\n    public void sort(boolean asc) {\n        if (asc) {\n            sort1Asc(off, len);\n        } else {\n            sort1Desc(off, len);\n        }\n    }\n\n    /** Swaps x[a] with x[b]. An subclass may override this method to e.g. swap other data associated with elements of the sorted array */\n    protected void swap(int a, int b) {\n        String t = x[a];\n        x[a] = x[b];\n        x[b] = t;\n    }\n\n    /** Returns the index of the median of the three indexed integers. */\n    private int med3(int a, int b, int c) {\n        return ((x[a].compareTo(x[b]) > 0) ? ((x[b].compareTo(x[c]) > 0) ? b : ((x[a].compareTo(x[c]) > 0) ? c : a))\n                                           : ((x[b].compareTo(x[c]) < 0) ? b : ((x[a].compareTo(x[c]) < 0) ? c : a)));\n    }\n\n    private void sort1Asc(int off, int len) {\n        // Insertion sort on smallest arrays\n        if (len < 7) {\n            for (int i = off; i < (len + off); i++) {\n                for (int j = i; (j > off) && (x[j - 1].compareTo(x[j]) > 0); j--) {\n                    swap(j, j - 1);\n                }\n            }\n\n            return;\n        }\n\n        // Choose a partition element, v\n        int m = off + (len >> 1); // Small arrays, middle element\n\n        if (len > 7) {\n            int l = off;\n            int n = (off + len) - 1;\n\n            if (len > 40) { // Big arrays, pseudomedian of 9\n\n                int s = len / 8;\n                l = med3(l, l + s, l + (2 * s));\n                m = med3(m - s, m, m + s);\n                n = med3(n - (2 * s), n - s, n);\n            }\n\n            m = med3(l, m, n); // Mid-size, med of 3\n        }\n\n        String v = x[m];\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int a = off;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int b = a;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int c = (off + len) - 1;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int d = c;\n\n        while (true) {\n            while ((b <= c) && (x[b].compareTo(v) <= 0)) {\n                if (x[b].equals(v)) {\n                    swap(a++, b);\n                }\n\n                b++;\n            }\n\n            while ((c >= b) && (x[c].compareTo(v) >= 0)) {\n                if (x[c].equals(v)) {\n                    swap(c, d--);\n                }\n\n                c--;\n            }\n\n            if (b > c) {\n                break;\n            }\n\n            swap(b++, c--);\n        }\n\n        // Swap partition elements back to middle\n        int s;\n\n        // Swap partition elements back to middle\n        int n = off + len;\n        s = Math.min(a - off, b - a);\n        vecswap(off, b - s, s);\n        s = Math.min(d - c, n - d - 1);\n        vecswap(b, n - s, s);\n\n        // Recursively sort non-partition-elements\n        if ((s = b - a) > 1) {\n            sort1Asc(off, s);\n        }\n\n        if ((s = d - c) > 1) {\n            sort1Asc(n - s, s);\n        }\n    }\n\n    private void sort1Desc(int off, int len) {\n        // Insertion sort on smallest arrays\n        if (len < 7) {\n            for (int i = off; i < (len + off); i++) {\n                for (int j = i; (j > off) && (x[j - 1].compareTo(x[j]) < 0); j--) {\n                    swap(j, j - 1);\n                }\n            }\n\n            return;\n        }\n\n        // Choose a partition element, v\n        int m = off + (len >> 1); // Small arrays, middle element\n\n        if (len > 7) {\n            int l = off;\n            int n = (off + len) - 1;\n\n            if (len > 40) { // Big arrays, pseudomedian of 9\n\n                int s = len / 8;\n                l = med3(l, l + s, l + (2 * s));\n                m = med3(m - s, m, m + s);\n                n = med3(n - (2 * s), n - s, n);\n            }\n\n            m = med3(l, m, n); // Mid-size, med of 3\n        }\n\n        String v = x[m];\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int a = off;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int b = a;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int c = (off + len) - 1;\n\n        // Establish Invariant: v* (<v)* (>v)* v*\n        int d = c;\n\n        while (true) {\n            while ((b <= c) && (x[b].compareTo(v) >= 0)) {\n                if (x[b].equals(v)) {\n                    swap(a++, b);\n                }\n\n                b++;\n            }\n\n            while ((c >= b) && (x[c].compareTo(v) <= 0)) {\n                if (x[c].equals(v)) {\n                    swap(c, d--);\n                }\n\n                c--;\n            }\n\n            if (b > c) {\n                break;\n            }\n\n            swap(b++, c--);\n        }\n\n        // Swap partition elements back to middle\n        int s;\n\n        // Swap partition elements back to middle\n        int n = off + len;\n        s = Math.min(a - off, b - a);\n        vecswap(off, b - s, s);\n        s = Math.min(d - c, n - d - 1);\n        vecswap(b, n - s, s);\n\n        // Recursively sort non-partition-elements\n        if ((s = b - a) > 1) {\n            sort1Desc(off, s);\n        }\n\n        if ((s = d - c) > 1) {\n            sort1Desc(n - s, s);\n        }\n    }\n\n    /** Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)]. */\n    private void vecswap(int a, int b, int n) {\n        for (int i = 0; i < n; i++, a++, b++) {\n            swap(a, b);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/StringUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils;\n\nimport java.text.DateFormat;\nimport java.text.DecimalFormatSymbols;\nimport java.text.NumberFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Calendar;\nimport java.util.Date;\nimport java.util.ResourceBundle;\n\nimport static org.graalvm.visualvm.lib.jfluid.utils.VMUtils.*;\n\n/**\n * Utility methods for String-related operations.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class StringUtils {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final String THIS_WEEK_FORMAT;\n    private static final String LAST_WEEK_FORMAT;\n    private static final String YESTERDAY_FORMAT;\n    private static NumberFormat percentage;\n    private static NumberFormat intFormat = NumberFormat.getIntegerInstance();\n    private static char SEPARATOR = DecimalFormatSymbols.getInstance().getDecimalSeparator();\n\n    static {\n        ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.jfluid.utils.Bundle\"); // NOI18N\n        THIS_WEEK_FORMAT = messages.getString(\"StringUtils_ThisWeekFormat\"); // NOI18N\n        LAST_WEEK_FORMAT = messages.getString(\"StringUtils_LastWeekFormat\"); // NOI18N\n        YESTERDAY_FORMAT = messages.getString(\"StringUtils_YesterdayFormat\"); // NOI18N\n        percentage = NumberFormat.getNumberInstance();\n        percentage.setMaximumFractionDigits(1);\n        percentage.setMinimumFractionDigits(1);\n    }\n                                                                                            // -----\n    private static SimpleDateFormat thisWeekFormat = new SimpleDateFormat(THIS_WEEK_FORMAT);\n    private static SimpleDateFormat lastWeekFormat = new SimpleDateFormat(LAST_WEEK_FORMAT);\n    private static SimpleDateFormat yesterdayFormat = new SimpleDateFormat(YESTERDAY_FORMAT);\n    private static DateFormat todayFormat = DateFormat.getTimeInstance(DateFormat.MEDIUM);\n    private static DateFormat otherFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);\n    private static DateFormat fullFormat = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.MEDIUM);\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void appendSplittedLongString(StringBuffer sb, String s, int maxLineLen) {\n        int nLines = (s.length() / maxLineLen) + (((s.length() % maxLineLen) != 0) ? 1 : 0);\n        int idx = 0;\n\n        for (int i = 0; i < nLines; i++) {\n            if (i > 0) {\n                sb.append('\\n'); // NOI18N\n            }\n\n            int endIdx = idx + maxLineLen;\n\n            if (endIdx > s.length()) {\n                endIdx = s.length();\n            }\n\n            sb.append(s.substring(idx, endIdx));\n            idx = endIdx;\n        }\n    }\n\n    public static String[][] convertPackedStringsIntoStringArrays(byte[] packedData, int[] packedArrayOffsets, int dim) {\n        String[][] ret = new String[dim][];\n        int len = packedArrayOffsets.length / dim;\n\n        for (int i = 0; i < dim; i++) {\n            ret[i] = new String[len];\n        }\n\n        int idx = 0;\n        int lastIdx = packedArrayOffsets.length - 1;\n\n        for (int j = 0; j < len; j++) {\n            for (int i = 0; i < dim; i++) {\n                int utf8Len = (idx < lastIdx) ? (packedArrayOffsets[idx + 1] - packedArrayOffsets[idx])\n                                              : (packedData.length - packedArrayOffsets[idx]);\n                ret[i][j] = utf8ToString(packedData, packedArrayOffsets[idx], utf8Len);\n                idx++;\n            }\n        }\n\n        return ret;\n    }\n\n    /** Used to print per cent figures with one digit after decimal point */\n    public static String floatPerCentToString(float t) {\n        return percentage.format(t);\n    }\n\n    // ------------------------------------------------------------------------------------------------\n    //    Time/Date formatting\n    // ------------------------------------------------------------------------------------------------\n    public static String formatFullDate(Date date) {\n        return fullFormat.format(date);\n    }\n\n    /** Formats provided time/date in a form that is tuned for user wrt to space needed and clarity/usefulness.\n     * It compareses the time/date passed against current time, and decides from one of 5 formats:\n     * - if the time is today, format it just using the time hh:mm:ss AM/PM\n     * - if the time is yesterday, format is as Yesterday, hh:mm AM/PM\n     * - if the time is this week, format is as [Name of Day], hh:mm AM/PM\n     * - if the time is last week, format is as Last [Name of Day], hh:mm AM/PM\n     * - otherwise format it as dd MMM yyyy\n     *\n     * @param date The date to format\n     * @return String with formatted time/date\n     */\n    public static String formatUserDate(Date date) {\n        Calendar now = Calendar.getInstance();\n        Calendar before = Calendar.getInstance();\n        before.setTime(date);\n\n        if (before.getTimeInMillis() <= now.getTimeInMillis()) { // the time is indeed in the past\n\n            int daysDelta = getDaysDifference(before, now);\n\n            if (daysDelta == 0) {\n                // today\n                return todayFormat.format(date);\n            } else if (daysDelta == 1) {\n                // yesterday\n                return yesterdayFormat.format(date);\n            } else {\n                int weekDelta = getWeekDifference(before, now);\n\n                if (weekDelta == 0) {\n                    // this week\n                    return thisWeekFormat.format(date);\n                } else if (weekDelta == 1) {\n                    //last week\n                    return lastWeekFormat.format(date);\n                }\n            }\n        }\n\n        return otherFormat.format(date);\n    }\n\n    private static final String MCS_ZERO = \"0\" + SEPARATOR + \"0\"; // NOI18N\n    /** Represent time (given in microsecond) in milliseconds, with roughly the same number of meaningful digits */\n    public static String mcsTimeToString(long t) {\n        if (t == 0) return MCS_ZERO;\n        \n        StringBuilder tmpBuf = new StringBuilder();\n        \n        if (t < 0) tmpBuf.append(\"-\"); // NOI18N\n        t = Math.abs(t);\n\n        if (t >= 100000) {\n            tmpBuf.append(intFormat.format(t / 1000));\n            return tmpBuf.toString();\n        } else if (t >= 10000) {\n            long x = t / 1000;\n            tmpBuf.append(intFormat.format(x));\n            tmpBuf.append(SEPARATOR);\n            tmpBuf.append(Long.toString((t - (x * 1000)) / 100));\n\n            return tmpBuf.toString();\n\n            //return Long.toString(x) + \".\" + Long.toString((t - x*1000) / 100);\n        } else if (t >= 1000) {\n            long x = t / 1000;\n            tmpBuf.append(intFormat.format(x));\n            tmpBuf.append(SEPARATOR);\n            tmpBuf.append(Long.toString((t - (x * 1000)) / 10));\n\n            return tmpBuf.toString();\n\n            //return Long.toString(x) + \".\" + Long.toString((t - x*1000) / 10);\n        } else {\n            if (t >= 100) {\n                tmpBuf.append(\"0\"); // NOI18N\n                tmpBuf.append(SEPARATOR);\n            } else if (t >= 10) {\n                tmpBuf.append(\"0\"); // NOI18N\n                tmpBuf.append(SEPARATOR);\n                tmpBuf.append(\"0\"); // NOI18N\n            } else {\n                tmpBuf.append(\"0\"); // NOI18N\n                tmpBuf.append(SEPARATOR);\n                tmpBuf.append(\"00\"); // NOI18N\n            }\n\n            return (tmpBuf.append(Long.toString(t))).toString();\n        }\n    }\n\n    /** Represents the given number of bytes as is, or as \"xxx K\" (if &gt;= 100 KBytes), or as \"xxx M\" (if &gt;= 100 MBytes) */\n    public static String nBytesToString(long b) {\n        StringBuilder tmpBuf = new StringBuilder();\n\n        if (b < (100 * 1024)) {\n            return intFormat.format(b) + \" B\"; // NOI18N\n        } else if (b < (100 * 1024 * 1024)) {\n            long k = b >> 10;\n            tmpBuf.append(intFormat.format(k));\n\n            if (b < (100 * 1024 * 1024)) {\n                tmpBuf.append(SEPARATOR); // NOI18N\n                tmpBuf.append(Long.toString((b - (k << 10)) / 102)); // 102 stands for 1/10th of 1K\n            }\n\n            tmpBuf.append(\" KB\"); // NOI18N\n\n            return tmpBuf.toString();\n        } else {\n            long m = b >> 20;\n            tmpBuf.append(intFormat.format(m));\n\n            if (b < 10737418240L) {\n                tmpBuf.append(SEPARATOR);\n                tmpBuf.append(Long.toString((b - (m << 20)) / 104858)); // 104858 stands for 1/10th of 1M\n            }\n\n            tmpBuf.append(\" MB\"); // NOI18N\n\n            return tmpBuf.toString();\n        }\n    }\n\n    // ------------------------------------------------------------------------------------------------\n    //    Miscellaneous\n    // ------------------------------------------------------------------------------------------------  \n    public static String[] parseArgsString(String args) {\n        if (args == null) {\n            return new String[0];\n        }\n\n        ArrayList listRes = new ArrayList();\n\n        int pos0 = 0;\n        int len = args.length();\n\n        while (pos0 < len) {\n            int pos1 = pos0;\n\n            while ((pos1 < len) && (args.charAt(pos1) != ' ') && (args.charAt(pos1) != 8)) { // NOI18N\n                pos1++;\n            }\n\n            listRes.add(args.substring(pos0, pos1));\n            pos0 = pos1 + 1;\n\n            while ((pos0 < len) && ((args.charAt(pos0) == ' ') || (args.charAt(pos0) == 8))) { // NOI18N\n                pos0++;\n            }\n        }\n\n        return (String[]) listRes.toArray(new String[0]);\n    }\n\n    public static String userFormClassName(String className) {\n        if (className == null) {\n            return null;\n        }\n\n        className = className.replace('/', '.'); // NOI18N\n\n        if (className.startsWith(\"[\")) { // NOI18N\n\n            String elemType = null;\n            int lastBrackPos = className.lastIndexOf('['); // NOI18N\n\n            if (lastBrackPos == (className.length() - 2)) { // It's an array of ultimately primitive type, e.g. [[C\n\n                switch (className.charAt(lastBrackPos + 1)) {\n                    case CHAR:\n                        elemType = CHAR_STRING;\n                        break;\n                    case BYTE:\n                        elemType = BYTE_STRING;\n                        break;\n                    case INT:\n                        elemType = INT_STRING;\n                        break;\n                    case BOOLEAN:\n                        elemType = BOOLEAN_STRING;\n                        break;\n                    case FLOAT:\n                        elemType = FLOAT_STRING;\n                        break;\n                    case DOUBLE:\n                        elemType = DOUBLE_STRING;\n                        break;\n                    case SHORT:\n                        elemType = SHORT_STRING;\n                        break;\n                    case LONG:\n                        elemType = LONG_STRING;\n                        break;\n                }\n            } else {\n                elemType = className.substring(lastBrackPos + 1);\n            }\n\n            int nDims = lastBrackPos + 1;\n            StringBuilder tmpBuf = new StringBuilder();\n            tmpBuf.append(elemType);\n\n            for (int i = 0; i < nDims; i++) {\n                tmpBuf.append(\"[]\"); // NOI18N\n            }\n\n            return tmpBuf.toString();\n        } else {\n            return className;\n        }\n    }\n\n    public static String utf8ToString(byte[] src, int stPos, int utf8Len) {\n        char[] strBuf = new char[utf8Len];\n        int i = stPos;\n        int j = 0;\n        int limit = stPos + utf8Len;\n\n        while (i < limit) {\n            int b = src[i++] & 255;\n\n            if (b >= 224) {\n                b = (b & 15) << 12;\n                b = b | ((src[i++] & 63) << 6);\n                b = b | (src[i++] & 63);\n            } else if (b >= 192) {\n                b = (b & 31) << 6;\n                b = b | (src[i++] & 63);\n            }\n\n            strBuf[j++] = (char) b;\n        }\n\n        return (new String(strBuf, 0, j)).intern();\n    }\n\n    private static int getDaysDifference(Calendar before, Calendar after) {\n        int diff = after.get(Calendar.DAY_OF_YEAR) - before.get(Calendar.DAY_OF_YEAR);\n        diff = diff + (before.getMaximum(Calendar.DAY_OF_YEAR) * (after.get(Calendar.YEAR) - before.get(Calendar.YEAR)));\n\n        return diff;\n    }\n\n    private static int getWeekDifference(Calendar before, Calendar after) {\n        int diff = after.get(Calendar.WEEK_OF_YEAR) - before.get(Calendar.WEEK_OF_YEAR);\n        diff = diff + (before.getMaximum(Calendar.WEEK_OF_YEAR) * (after.get(Calendar.YEAR) - before.get(Calendar.YEAR)));\n\n        return diff;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/VMUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils;\n\n\n/**\n * Utilities for dealing with VM representation of stuff.\n *\n * @author Ian Formanek\n */\npublic class VMUtils {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final char BOOLEAN = 'Z'; // NOI18N\n    public static final char CHAR = 'C'; // NOI18N\n    public static final char BYTE = 'B'; // NOI18N\n    public static final char SHORT = 'S'; // NOI18N\n    public static final char INT = 'I'; // NOI18N\n    public static final char LONG = 'J'; // NOI18N\n    public static final char FLOAT = 'F'; // NOI18N\n    public static final char DOUBLE = 'D'; // NOI18N\n    public static final char VOID = 'V'; // NOI18N\n    public static final char REFERENCE = 'L'; // NOI18N\n\n    public static final String BOOLEAN_CODE = \"Z\"; // NOI18N\n    public static final String CHAR_CODE = \"C\"; // NOI18N\n    public static final String BYTE_CODE = \"B\"; // NOI18N\n    public static final String SHORT_CODE = \"S\"; // NOI18N\n    public static final String INT_CODE = \"I\"; // NOI18N\n    public static final String LONG_CODE = \"J\"; // NOI18N\n    public static final String FLOAT_CODE = \"F\"; // NOI18N\n    public static final String DOUBLE_CODE = \"D\"; // NOI18N\n    public static final String VOID_CODE = \"V\"; // NOI18N\n\n    public static final String BOOLEAN_STRING = \"boolean\"; // NOI18N\n    public static final String CHAR_STRING = \"char\"; // NOI18N\n    public static final String BYTE_STRING = \"byte\"; // NOI18N\n    public static final String SHORT_STRING = \"short\"; // NOI18N\n    public static final String INT_STRING = \"int\"; // NOI18N\n    public static final String LONG_STRING = \"long\"; // NOI18N\n    public static final String FLOAT_STRING = \"float\"; // NOI18N\n    public static final String DOUBLE_STRING = \"double\"; // NOI18N\n    public static final String VOID_STRING = \"void\"; // NOI18N\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static String typeToVMSignature(final String type) {\n        //    System.err.println(\"sig for: \"+type);\n        String ret = type.replace('.', '/'); // NOI18N\n\n        // 1. replace primitive types or surround class name\n        if (ret.startsWith(BOOLEAN_STRING)) {\n            ret = ret.replace(BOOLEAN_STRING, BOOLEAN_CODE);\n        } else if (ret.startsWith(CHAR_STRING)) {\n            ret = ret.replace(CHAR_STRING, CHAR_CODE);\n        } else if (ret.startsWith(BYTE_STRING)) {\n            ret = ret.replace(BYTE_STRING, BYTE_CODE);\n        } else if (ret.startsWith(SHORT_STRING)) {\n            ret = ret.replace(SHORT_STRING, SHORT_CODE);\n        } else if (ret.startsWith(INT_STRING)) {\n            ret = ret.replace(INT_STRING, INT_CODE);\n        } else if (ret.startsWith(LONG_STRING)) {\n            ret = ret.replace(LONG_STRING, LONG_CODE);\n        } else if (ret.startsWith(FLOAT_STRING)) {\n            ret = ret.replace(FLOAT_STRING, FLOAT_CODE);\n        } else if (ret.startsWith(DOUBLE_STRING)) {\n            ret = ret.replace(DOUBLE_STRING, DOUBLE_CODE);\n        } else if (ret.startsWith(VOID_STRING)) {\n            ret = ret.replace(VOID_STRING, VOID_CODE);\n        } else {\n            // if the remainder is a class, surround it with \"L...;\"\n            final int arIdx = ret.indexOf('['); // NOI18N\n\n            if (arIdx == -1) {\n                ret = \"L\" + ret + \";\"; // NOI18N\n            } else {\n                ret = \"L\" + ret.substring(0, arIdx) + \";\" + ret.substring(arIdx); // NOI18N\n            }\n        }\n\n        // 2. put all array marks to the beginning in the VM-signature style\n        while (ret.endsWith(\"[]\")) { // NOI18N\n            ret = \"[\" + ret.substring(0, ret.length() - 2); // NOI18N\n        }\n\n        //    System.err.println(\"is: \"+ret);\n        return ret;\n    }\n    \n    public static boolean isVMPrimitiveType(String className) {\n        if (className == null || className.length() != 1) return false;\n        if (VMUtils.BOOLEAN_CODE.equals(className) || VMUtils.CHAR_CODE.equals(className) || VMUtils.BYTE_CODE.equals(className) ||\n            VMUtils.SHORT_CODE.equals(className) || VMUtils.INT_CODE.equals(className) || VMUtils.LONG_CODE.equals(className) ||\n            VMUtils.FLOAT_CODE.equals(className) || VMUtils.DOUBLE_CODE.equals(className)) return true;\n        return false;\n    }\n    \n    public static boolean isPrimitiveType(String className) {\n        if (className == null || className.length() < 1) return false;\n        if (VMUtils.BOOLEAN_STRING.equals(className) || VMUtils.CHAR_STRING.equals(className) || VMUtils.BYTE_STRING.equals(className) ||\n            VMUtils.SHORT_STRING.equals(className) || VMUtils.INT_STRING.equals(className) || VMUtils.LONG_STRING.equals(className) ||\n            VMUtils.FLOAT_STRING.equals(className) || VMUtils.DOUBLE_STRING.equals(className)) return true;\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/Wildcards.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class Wildcards {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final String ALLWILDCARD = \"*\"; // NOI18N\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static boolean matchesWildcard(String wildcard, String loadedClassName) {\n        //    System.err.println(\"Matches wildcard: \"+loadedClassName+\", wild: \"+wildcard + \" : \" + (loadedClassName.startsWith(wildcard) && (loadedClassName.indexOf('/', wildcard.length()) == -1)));\n        boolean packageWildcard = false;\n        if (wildcard.endsWith(Wildcards.ALLWILDCARD)) { // package wild card - instrument all classes including subpackages\n            wildcard = Wildcards.unwildPackage(wildcard);\n            packageWildcard = true;\n        }\n        if (!loadedClassName.startsWith(wildcard)) {\n            if (packageWildcard && loadedClassName.equals(wildcard.substring(0,wildcard.length()-1))) {\n                return true;\n            }\n            return false;\n        }\n        return packageWildcard || (loadedClassName.indexOf('/', wildcard.length()) == -1); // NOI18N\n    }\n\n\n    public static boolean isMethodWildcard(String methodName) {\n        return (methodName != null) ? (methodName.equals(ALLWILDCARD) || methodName.equals(\"<all>\")) : false; // NOI18N\n    }\n\n    public static boolean isPackageWildcard(String className) {\n        if (className == null) {\n            return false;\n        }\n\n        return (className.length() == 0 // empty string is default package wildcard\n        ) || className.endsWith(\"/\") // ends with '/', means package wildcard // NOI18N\n               || className.endsWith(\".\") // ends with '.', means package wildcard // NOI18N\n               || className.endsWith(ALLWILDCARD); // ends with the default WILDCARD (*)\n    }\n\n    public static String unwildPackage(String packageMask) {\n        if (packageMask == null) {\n            return null;\n        }\n\n        //    System.out.print(\"Performing unwildPackage() : \" + packageMask);\n        if (packageMask.endsWith(ALLWILDCARD)) {\n            //      String newPk = packageMask.substring(0, packageMask.length() - 2);\n            //      System.out.println(\" -> \" + newPk);\n            return packageMask.substring(0, packageMask.length() - 1).intern();\n        }\n\n        return packageMask.intern();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/formatting/DefaultMethodNameFormatter.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils.formatting;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class DefaultMethodNameFormatter implements MethodNameFormatter {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int VERBOSITY_CLASS = 1;\n    public static final int VERBOSITY_METHOD = 2;\n    public static final int VERBOSITY_CLASSMETHOD = 3;\n    public static final int VERBOSITY_FULLMETHOD = 4;\n    public static final int VERBOSITY_FULLCLASSMETHOD = 5;\n    private static final int VERBOSITY_MIN = 1;\n    private static final int VERBOSITY_MAX = 5;\n    private static final int VERBOSITY_DEFAULT = VERBOSITY_CLASSMETHOD;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int verbosity;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of DefaultMethodNameFormatter\n     * @param verbosity verbosity level: 1 = getFormattedClass(), 2 = getFormattedMethod(), 3 = getFormattedClassAndMethod(),\n     *                                   4 = getFullFormattedMethod(), 5 = getFullFormatedClassAndMethod()\n     */\n    public DefaultMethodNameFormatter(int verbosity) {\n        this.verbosity = ((verbosity >= VERBOSITY_MIN) && (verbosity <= VERBOSITY_MAX)) ? verbosity : VERBOSITY_DEFAULT;\n    }\n\n    public DefaultMethodNameFormatter() {\n        this.verbosity = VERBOSITY_DEFAULT;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Formattable formatMethodName(String className, String methodName, String signature) {\n        return new PlainFormattableMethodName(className, methodName, signature, verbosity);\n    }\n\n    public Formattable formatMethodName(ClientUtils.SourceCodeSelection method) {\n        return new PlainFormattableMethodName(method.getClassName(), method.getMethodName(), method.getMethodSignature(),\n                                              verbosity);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/formatting/Formattable.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils.formatting;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface Formattable {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Return a formatted value of the encapsulated object\n     */\n    String toFormatted();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/formatting/MethodNameFormatter.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils.formatting;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface MethodNameFormatter {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    Formattable formatMethodName(ClientUtils.SourceCodeSelection method);\n\n    Formattable formatMethodName(String className, String methodName, String signature);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/formatting/MethodNameFormatterFactory.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils.formatting;\n\nimport org.graalvm.visualvm.lib.jfluid.marker.Mark;\nimport java.util.HashMap;\nimport java.util.Map;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class MethodNameFormatterFactory {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static MethodNameFormatterFactory instance;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    // maps the method marks to appropriate formatters\n    // @GuardedBy this\n    private final Map formatterMap;\n    private MethodNameFormatter defaultFormatter;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of MethodNameFormatterFactory\n     */\n    private MethodNameFormatterFactory() {\n        formatterMap = new HashMap();\n    }\n\n    private MethodNameFormatterFactory(MethodNameFormatterFactory template) {\n        formatterMap = template.formatterMap;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static synchronized MethodNameFormatterFactory getDefault() {\n        if (instance == null) {\n            instance = new MethodNameFormatterFactory();\n            instance.defaultFormatter = new DefaultMethodNameFormatter();\n        }\n\n        return instance;\n    }\n\n    public static synchronized MethodNameFormatterFactory getDefault(MethodNameFormatter defaultFormatter) {\n        MethodNameFormatterFactory factory = new MethodNameFormatterFactory(getDefault());\n        factory.defaultFormatter = defaultFormatter;\n\n        return factory;\n    }\n\n    public MethodNameFormatter getFormatter() {\n        return defaultFormatter;\n    }\n\n    public synchronized MethodNameFormatter getFormatter(Mark mark) {\n        if ((mark == null) || mark.isDefault()) {\n            return defaultFormatter;\n        }\n\n        MethodNameFormatter formatter = (MethodNameFormatter) formatterMap.get(mark);\n\n        if (formatter == null) {\n            return defaultFormatter;\n        }\n\n        return formatter;\n    }\n\n    public synchronized void registerFormatter(Mark mark, MethodNameFormatter formatter) {\n        formatterMap.put(mark, formatter);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/utils/formatting/PlainFormattableMethodName.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils.formatting;\n\nimport org.graalvm.visualvm.lib.jfluid.utils.*;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\nimport static org.graalvm.visualvm.lib.jfluid.utils.VMUtils.*;\n\n/**\n * A class that can be used to obtain Java class or method name formatted in various ways.\n *\n * @author Ian Formanek\n * @author Misha Dmitriev\n */\npublic class PlainFormattableMethodName implements Formattable {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Logger LOGGER = Logger.getLogger(PlainFormattableMethodName.class.getName());\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private String className;\n    private String methodName;\n    private String params;\n    private String returnType;\n    private int verbosity;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new methodNameFormatter for given class/method/signature.\n     * The method name and signature can be null, in which case the formatter works for class only.\n     *\n     * @param cname  A fully qualified name of the class, or null if only formatting methods\n     *                   - e.g. \"java/lang/String\"\n     * @param mname A name of method, empty string or \"<init>\" for constructors or null if method is not specified\n     *                   - e.g. \"concat\"\n     * @param sig  VM signature of method or null if method is not specified or <clinit> is the method\n     *                   - e.g. \"(Ljava/lang/String;)Ljava/lang/String;\"\n     * @param verbosity verbosity level: 1 = getFormattedClass(), 2 = getFormattedMethod(), 3 = getFormattedClassAndMethod(),\n     *                                   4 = getFullFormattedMethod(), 5 = getFullFormatedClassAndMethod()\n     */\n    PlainFormattableMethodName(String cname, String mname, String sig, int verbosity) {\n        int curPos;\n        int idx1;\n        int idx2;\n        char nextChar;\n\n        this.verbosity = verbosity;\n\n        StringBuilder arrayIndicator = new StringBuilder();\n\n        if (cname != null) {\n            this.className = cname.replace('/', '.'); // NOI18N\n        } else {\n            // can be null in case formatter is only interested in method formatting\n            this.className = \"<unknown class>\"; // NOI18N\n        }\n\n        if (this.className.length() == 0) { // deafult package wildcard\n            this.className = \".*\"; // NOI18N\n        }\n\n        if (this.className.endsWith(\".\")) { // slightly different wildcard notation; for the backward compatibility sake we keep it\n            this.className = this.className + \"*\";  // NOI18N\n        }\n\n        if (mname == null || mname.isEmpty() || mname.equals(\"*\")) { // NOI18N\n            // methodName can be null when class- or package-level view is used\n            params = \"\"; // NOI18N\n            returnType = \"\"; // NOI18N\n        } else {\n            if (\"\".equals(mname) && !this.className.contains(\"*\")) { // NOI18N\n                this.methodName = \"<init>\"; // NOI18N\n            } else {\n                this.methodName = mname;\n            }\n\n            if (\"<clinit>\".equals(methodName) || Wildcards.isMethodWildcard(methodName)) { // NOI18N\n                params = \"\"; // NOI18N\n                returnType = \"\"; // NOI18N\n            } else {\n                idx1 = sig.lastIndexOf(')') + 1; // NOI18N\n\n                if ((idx1 > 0) && !\"<init>\".equals(methodName)) { // NOI18N\n                    // For e.g. the \"Thread\" root node it may be zero; there was a bug with it when this method\n                    // was hit for \"Thread\" in results export\n                    returnType = sig.substring(idx1);\n                    curPos = 0;\n\n                    try {\n                        while (returnType.charAt(curPos) == '[') { // NOI18N\n                            arrayIndicator.append(\"[]\"); // NOI18N\n                            curPos++;\n                        }\n                        \n                        nextChar = returnType.charAt(curPos++);\n                        \n                        if (nextChar == BOOLEAN) {\n                            returnType = BOOLEAN_STRING + arrayIndicator.toString();\n                        } else if (nextChar == CHAR) {\n                            returnType = CHAR_STRING + arrayIndicator.toString();\n                        } else if (nextChar == BYTE) {\n                            returnType = BYTE_STRING + arrayIndicator.toString();\n                        } else if (nextChar == SHORT) {\n                            returnType = SHORT_STRING + arrayIndicator.toString();\n                        } else if (nextChar == INT) {\n                            returnType = INT_STRING + arrayIndicator.toString();\n                        } else if (nextChar == LONG) {\n                            returnType = LONG_STRING + arrayIndicator.toString();\n                        } else if (nextChar == FLOAT) {\n                            returnType = FLOAT_STRING + arrayIndicator.toString();\n                        } else if (nextChar == DOUBLE) {\n                            returnType = DOUBLE_STRING + arrayIndicator.toString();\n                        } else if (nextChar == VOID) {\n                            returnType = VOID_STRING + arrayIndicator.toString();\n                        } else {\n                            // return type is a class\n                            // Check if the class belongs to the java.lang.* package, and replace it with simple name if so.\n                            // However, avoid doing so if it's from say java.lang.ref.* package - otherwise we'll get confusing\n                            // names like ref.Reference\n                            returnType = returnType.substring(curPos, returnType.length() - 1); //strip \"L\" at the beginning\n                            // and \";\" at end\n\n                            if (returnType.startsWith(\"java/lang/\") && (returnType.indexOf('/', 10) == -1)) { // NOI18N\n                                returnType = returnType.substring(10);\n                            }\n                            \n                            returnType = returnType.replace('$', '.'); // NOI18N\n                            returnType = returnType.replace('/', '.') + arrayIndicator.toString(); // NOI18N\n                        }\n                    } catch (StringIndexOutOfBoundsException e) {\n                        LOGGER.log(Level.INFO, \"Can not format return type \\\"{0}\\\"\", sig.substring(idx1));\n                    }\n                } else {\n                    // constructor or no end parenthesis\n                    returnType = \"\"; // NOI18N\n                }\n\n                idx1 = sig.indexOf('(') + 1; // NOI18N\n                idx2 = sig.lastIndexOf(')'); // NOI18N\n\n                if (idx2 > 0) {\n                    String paramsString = sig.substring(idx1, idx2);\n                    StringBuilder paramsBuf = new StringBuilder();\n                    arrayIndicator.setLength(0);\n                    curPos = 0;\n\n                    try {\n                        while (curPos < paramsString.length()) {\n                            while (paramsString.charAt(curPos) == '[') { // NOI18N\n                                arrayIndicator.append(\"[]\"); // NOI18N\n                                curPos++;\n                            }\n                            \n                            nextChar = paramsString.charAt(curPos++);\n                            \n                            if (nextChar == BOOLEAN) {\n                                paramsBuf.append(BOOLEAN_STRING);\n                            } else if (nextChar == CHAR) {\n                                paramsBuf.append(CHAR_STRING);\n                            } else if (nextChar == BYTE) {\n                                paramsBuf.append(BYTE_STRING);\n                            } else if (nextChar == SHORT) {\n                                paramsBuf.append(SHORT_STRING);\n                            } else if (nextChar == INT) {\n                                paramsBuf.append(INT_STRING);\n                            } else if (nextChar == LONG) {\n                                paramsBuf.append(LONG_STRING);\n                            } else if (nextChar == FLOAT) {\n                                paramsBuf.append(FLOAT_STRING);\n                            } else if (nextChar == DOUBLE) {\n                                paramsBuf.append(DOUBLE_STRING);\n                            } else {\n                                // it's a class\n                                int startPos = curPos;\n                                \n                                while (paramsString.charAt(curPos) != ';') { // NOI18N\n                                    curPos++;\n                                }\n                                \n                                String typeName = paramsString.substring(startPos, curPos); //strip \"L\" at the beginning and \";\" at end\n\n                                if (typeName.startsWith(\"java/lang/\") && (typeName.indexOf('/', 10) == -1)) { // NOI18N\n                                    typeName = typeName.substring(10);\n                                }\n                                \n                                typeName = typeName.replace('$', '.'); // NOI18N\n                                typeName = typeName.replace('/', '.'); // NOI18N\n                                paramsBuf.append(typeName);\n                                curPos++;\n                            }\n                            \n                            if (arrayIndicator.length() > 0) {\n                                paramsBuf.append(arrayIndicator.toString());\n                            }\n                            \n                            arrayIndicator.setLength(0);\n                            \n                            if (curPos < paramsString.length()) {\n                                paramsBuf.append(\", \"); // NOI18N\n                            }\n                        }\n                    } catch (StringIndexOutOfBoundsException e) {\n                        LOGGER.log(Level.INFO, \"Can not format param list \\\"{0}\\\"\", paramsString);\n                    }\n\n                    params = paramsBuf.toString();\n                } else {\n                    params = \"\"; // NOI18N\n                }\n            }\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"Formattable method name for:\"); // NOI18N\n            LOGGER.log(Level.FINEST, \"Class: {0}\", this.className); // NOI18N\n            LOGGER.log(Level.FINEST, \"Method: {0}\", this.methodName); // NOI18N\n            LOGGER.log(Level.FINEST, \"Return type: {0}\", this.returnType); // NOI18N\n            LOGGER.log(Level.FINEST, \"Parameters: {0}\", this.params); // NOI18N\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @return formatted class name, using '.' to separate packages = e.g. \"java.lang.String\"\n     */\n    public String getFormattedClass() {\n        return className;\n    }\n\n    /**\n     * @return formatted class and method name (with parameter types, but without its return type).\n     *         Will return the same as getFormattedClass if method was not specified.\n     */\n    public String getFormattedClassAndMethod() {\n        if ((methodName == null) || (methodName.length() == 0)) {\n            return getFormattedClass();\n        } else {\n            return className + \".\" + getFormattedMethod(); // NOI18N\n        }\n    }\n\n    /**\n     * @return formatted method name, with parameter types, but without the return type. Will return empty string\n     *         if method was not specified.\n     */\n    public String getFormattedMethod() {\n        if (LOGGER.isLoggable(Level.FINER)) {\n            LOGGER.log(Level.FINER, \"Getting formatted method name for {0}\", methodName); // NOI18N\n        }\n\n        if ((methodName == null) || (methodName.length() == 0)) {\n            return \"\"; // NOI18N  // Understanding is that class-level view is used\n//        } else if (\"<clinit>\".equals(methodName)) { // NOI18N\n//            return methodName;\n        } else {\n            return methodName + \"(\" + getParamsString() + \")\"; // NOI18N\n        }\n    }\n\n    /**\n     * @return formatted class and method name (with parameter types and return type)\n     *         Will return the same as getFormattedClass if method was not specified.\n     */\n    public String getFullFormattedClassAndMethod() {\n        if ((methodName == null) || (methodName.length() == 0)) {\n            return getFormattedClass();\n        } else {\n            return className + \".\" + getFullFormattedMethod(); // NOI18N\n        }\n    }\n\n    /**\n     * @return formatted method name with parameter types and return type (return type not used if constructor).\n     *         Will return empty string if method was not specified.\n     */\n    public String getFullFormattedMethod() {\n        if (LOGGER.isLoggable(Level.FINER)) {\n            LOGGER.log(Level.FINER, \"Getting full formatted method name for {0}\", methodName); // NOI18N\n        }\n\n        if ((methodName == null) || (methodName.length() == 0)) {\n            return \"\"; // NOI18N  // Understanding is that class-level view is used\n        } else if (\"<clinit>\".equals(methodName)) { // NOI18N\n            return methodName + \"()\";\n        } else if (\"<init>\".equals(methodName)) { // NOI18N\n            return methodName + \"(\" + getParamsString() + \")\"; // NOI18N\n        } else if (\"*\".equals(methodName)) { // NOI18N\n            return methodName;\n        } else {\n            return methodName + \"(\" + getParamsString() + \") : \" + getReturnTypeX(); // NOI18N\n        }\n    }\n\n    /**\n     * @return parameters of the given method - formatted string -, empty string if the method has no parameters or\n     *         no method was specified\n     */\n    public String getParamsString() {\n        return params;\n    }\n\n    /**\n     * @return return type of the given method, empty String if void or method was not specified\n     */\n    public String getReturnTypeX() {\n        return returnType;\n    }\n\n    @Override\n    public String toFormatted() {\n        switch (verbosity) {\n            case DefaultMethodNameFormatter.VERBOSITY_CLASS:return getFormattedClass();\n            case DefaultMethodNameFormatter.VERBOSITY_METHOD:return getFormattedMethod();\n            case DefaultMethodNameFormatter.VERBOSITY_CLASSMETHOD:return getFormattedClassAndMethod();\n            case DefaultMethodNameFormatter.VERBOSITY_FULLMETHOD:return getFullFormattedMethod();\n            case DefaultMethodNameFormatter.VERBOSITY_FULLCLASSMETHOD:return getFullFormattedClassAndMethod();\n            default:return getFullFormattedClassAndMethod();\n        }\n    }\n\n    @Override\n    public String toString() {\n        return getFullFormattedClassAndMethod();\n    }\n\n    private boolean isAllWildCard(String methodName) {\n        return methodName.equals(\"<all>\") || methodName.equals(\"*\"); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/AsyncMessageCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Asynchronous message that the server may occasionally send to the client.\n *\n * @author Misha Dmitriev\n */\npublic class AsyncMessageCommand extends Command {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private String message;\n    private boolean positive;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public AsyncMessageCommand(boolean positive, String message) {\n        super(MESSAGE);\n        this.positive = positive;\n\n        if (message == null) {\n            message = \"\"; // NOI18N\n        }\n\n        this.message = message;\n    }\n\n    // Custom serialization support\n    AsyncMessageCommand() {\n        super(MESSAGE);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getMessage() {\n        return message;\n    }\n\n    public boolean isPositive() {\n        return positive;\n    }\n\n    public String toString() {\n        return \"Async message: \" + (isPositive() ? \"positive\" : \"negative\") + \", message = \" + message; // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        positive = in.readBoolean();\n        message = in.readUTF();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeBoolean(positive);\n        out.writeUTF(message);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/CalibrationDataResponse.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Contains the calibration information obtained for CPU instrumentation used for profiling.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class CalibrationDataResponse extends Response {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    // The following is the same stuff that we have in ProfilingSessionStatus\n    private double[] methodEntryExitCallTime;\n    private double[] methodEntryExitInnerTime;\n    private double[] methodEntryExitOuterTime;\n    private long[] timerCountsInSecond; // This is always of length 2\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CalibrationDataResponse(double[] callTime, double[] innerTime, double[] outerTime, long[] timerCountsInSecond) {\n        super(true, CALIBRATION_DATA);\n        this.methodEntryExitCallTime = callTime;\n        this.methodEntryExitInnerTime = innerTime;\n        this.methodEntryExitOuterTime = outerTime;\n        this.timerCountsInSecond = timerCountsInSecond;\n    }\n\n    // Custom serialization support\n    CalibrationDataResponse() {\n        super(true, CALIBRATION_DATA);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public double[] getMethodEntryExitCallTime() {\n        return methodEntryExitCallTime;\n    }\n\n    public double[] getMethodEntryExitInnerTime() {\n        return methodEntryExitInnerTime;\n    }\n\n    public double[] getMethodEntryExitOuterTime() {\n        return methodEntryExitOuterTime;\n    }\n\n    public long[] getTimerCountsInSecond() {\n        return timerCountsInSecond;\n    }\n\n    // For debugging\n    public String toString() {\n        return \"CalibrationDataResponse, \" + super.toString(); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        int len = in.readInt();\n        methodEntryExitCallTime = new double[len];\n        methodEntryExitInnerTime = new double[len];\n        methodEntryExitOuterTime = new double[len];\n\n        for (int i = 0; i < len; i++) {\n            methodEntryExitCallTime[i] = in.readDouble();\n        }\n\n        for (int i = 0; i < len; i++) {\n            methodEntryExitInnerTime[i] = in.readDouble();\n        }\n\n        for (int i = 0; i < len; i++) {\n            methodEntryExitOuterTime[i] = in.readDouble();\n        }\n\n        timerCountsInSecond = new long[2];\n        timerCountsInSecond[0] = in.readLong();\n        timerCountsInSecond[1] = in.readLong();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        int len = methodEntryExitCallTime.length;\n        out.writeInt(len);\n\n        for (int i = 0; i < len; i++) {\n            out.writeDouble(methodEntryExitCallTime[i]);\n        }\n\n        for (int i = 0; i < len; i++) {\n            out.writeDouble(methodEntryExitInnerTime[i]);\n        }\n\n        for (int i = 0; i < len; i++) {\n            out.writeDouble(methodEntryExitOuterTime[i]);\n        }\n\n        out.writeLong(timerCountsInSecond[0]);\n        out.writeLong(timerCountsInSecond[1]);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/ClassLoadedCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Notification about a class load event that the server sends to the client.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class ClassLoadedCommand extends Command {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private String className;\n    private byte[] classFileBytes;\n    private int[] thisAndParentLoaderData;\n    private boolean threadInCallGraph;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ClassLoadedCommand(String className, int[] thisAndParentLoaderData, byte[] classFileBytes, boolean threadInCallGraph) {\n        super(CLASS_LOADED);\n        this.className = className;\n        this.thisAndParentLoaderData = thisAndParentLoaderData;\n        this.classFileBytes = classFileBytes;\n        this.threadInCallGraph = threadInCallGraph;\n    }\n\n    // Custom serialization support\n    ClassLoadedCommand() {\n        super(CLASS_LOADED);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public byte[] getClassFileBytes() {\n        return classFileBytes;\n    }\n\n    public String getClassName() {\n        return className;\n    }\n\n    public int[] getThisAndParentLoaderData() {\n        return thisAndParentLoaderData;\n    }\n\n    public boolean getThreadInCallGraph() {\n        return threadInCallGraph;\n    }\n\n    // for debugging\n    public String toString() {\n        return super.toString() + \", className: \" + className // NOI18N\n               + \", threadInCallGraph: \" + threadInCallGraph // NOI18N\n               + \", thisAndParentLoaderData: \" // NOI18N\n               + thisAndParentLoaderData[0] + \", \" // NOI18N\n               + thisAndParentLoaderData[1] + \", \" // NOI18N\n               + thisAndParentLoaderData[2] + \", classFileBytes: \"\n               + ((classFileBytes == null) ? \"null\" : (\"\" + classFileBytes.length)); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        className = in.readUTF();\n        thisAndParentLoaderData = new int[3];\n\n        for (int i = 0; i < 3; i++) {\n            thisAndParentLoaderData[i] = in.readInt();\n        }\n\n        int len = in.readInt();\n\n        if (len == 0) {\n            classFileBytes = null;\n        } else {\n            classFileBytes = new byte[len];\n            in.readFully(classFileBytes);\n        }\n\n        threadInCallGraph = in.readBoolean();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeUTF(className);\n\n        for (int i = 0; i < 3; i++) {\n            out.writeInt(thisAndParentLoaderData[i]);\n        }\n\n        if (classFileBytes != null) {\n            out.writeInt(classFileBytes.length);\n            out.write(classFileBytes);\n            classFileBytes = null;\n        } else {\n            out.writeInt(0);\n        }\n\n        out.writeBoolean(threadInCallGraph);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/CodeRegionCPUResultsResponse.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Code region CPU profiling results, that are sent to the client upon request.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class CodeRegionCPUResultsResponse extends Response {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private long[] results;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CodeRegionCPUResultsResponse(long[] results) {\n        super(true, CODE_REGION_CPU_RESULTS);\n        // Note that he first element of the array is the total number of invocations and should not be changed.\n        this.results = results;\n    }\n\n    // Custom serialization support\n    CodeRegionCPUResultsResponse() {\n        super(true, CODE_REGION_CPU_RESULTS);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public long[] getResults() {\n        return results;\n    }\n\n    // For debugging\n    public String toString() {\n        return \"CodeRegionCPUResultsResponse, length: \" + results.length + \", \" + super.toString(); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        int len = in.readInt();\n        results = new long[len];\n\n        for (int i = 0; i < len; i++) {\n            results[i] = in.readLong();\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(results.length);\n\n        for (int i = 0; i < results.length; i++) {\n            out.writeLong(results[i]);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/Command.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Base class for all Commands, i.e. wire protocol messages that can be sent by both client and\n * server at any moment. Some Commands contain nothing but their type, and therefore instances of\n * this Command class can be used to transfer them. Others contain additional information, and\n * therefore specialized subclasses of Command are used for them.\n *\n * @author Misha Dmitriev\n */\npublic class Command {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int CHECK_CONNECTION = 1;\n    public static final int START_TARGET_APP = 2;\n    public static final int CLASS_LOADED = 3;\n    public static final int SET_CHANGEABLE_INSTR_PARAMS = 4;\n    public static final int SET_UNCHANGEABLE_INSTR_PARAMS = 5;\n    public static final int CPU_RESULTS_EXIST = 6;\n    public static final int INSTRUMENT_METHOD_GROUP = 7;\n    public static final int GET_CODE_REGION_CPU_RESULTS = 8;\n    public static final int DEACTIVATE_INJECTED_CODE = 9;\n    public static final int SUSPEND_TARGET_APP = 10;\n    public static final int RESUME_TARGET_APP = 11;\n    public static final int TERMINATE_TARGET_JVM = 12;\n    public static final int INITIATE_PROFILING = 13;\n    public static final int MESSAGE = 14;\n    public static final int SHUTDOWN_OK = 15; // profiled VM can proceed with shutdown\n    public static final int GET_THREAD_LIVENESS_STATUS = 16;\n    public static final int ROOT_CLASS_LOADED = 17;\n    public static final int SHUTDOWN_INITIATED = 18; // profiled VM shutdown initiated\n    public static final int SHUTDOWN_COMPLETED = 19; // profiled VM shutdown completed, clean up\n    public static final int INSTRUMENT_REFLECTION = 20;\n    public static final int DEINSTRUMENT_REFLECTION = 21;\n    public static final int METHOD_LOADED = 22;\n    public static final int METHOD_INVOKED_FIRST_TIME = 23;\n    public static final int GET_INTERNAL_STATS = 24;\n    public static final int DETACH = 25;\n    public static final int EVENT_BUFFER_DUMPED = 26;\n    public static final int DUMP_EXISTING_RESULTS = 27;\n    public static final int GET_VM_PROPERTIES = 28;\n    public static final int RESET_PROFILER_COLLECTORS = 29;\n    public static final int GET_OBJECT_ALLOCATION_RESULTS = 30;\n    public static final int GET_METHOD_NAMES_FOR_JMETHOD_IDS = 31;\n    public static final int GET_MONITORED_NUMBERS = 32;\n    public static final int RUN_GC = 33;\n    public static final int RUN_CALIBRATION_AND_GET_DATA = 34;\n    public static final int GET_DEFINING_CLASS_LOADER = 35;\n    public static final int CLASS_LOADER_UNLOADING = 36;\n    public static final int GET_STORED_CALIBRATION_DATA = 37;\n    public static final int RESULTS_AVAILABLE = 38;\n    public static final int TAKE_SNAPSHOT = 39;\n    public static final int DUMP_EXISTING_RESULTS_LIVE = 40;\n    public static final int TAKE_HEAP_DUMP = 41;\n    public static final int GET_CLASSID = 42;\n    public static final int STILL_ALIVE = 43;\n    public static final int PREPARE_DETACH = 44;\n    public static final int GET_HEAP_HISTOGRAM = 45;\n    public static final int TAKE_THREAD_DUMP = 46;\n    public static final int GET_CLASS_FILE_BYTES = 47;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int type; // One of the above constants determining the Command type.\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public Command(int type) {\n        this.type = type;\n    }\n\n    // Custom serialization support\n    Command() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getType() {\n        return type;\n    }\n\n    public static String cmdTypeToString(int type) {\n        switch (type) {\n            case CHECK_CONNECTION:\n                return \"CHECK_CONNECTION\"; // NOI18N\n            case START_TARGET_APP:\n                return \"START_TARGET_APP\"; // NOI18N\n            case CLASS_LOADED:\n                return \"CLASS_LOADED\"; // NOI18N\n            case SET_CHANGEABLE_INSTR_PARAMS:\n                return \"SET_CHANGEABLE_INSTR_PARAMS\"; // NOI18N\n            case SET_UNCHANGEABLE_INSTR_PARAMS:\n                return \"SET_UNCHANGEABLE_INSTR_PARAMS\"; // NOI18N\n            case CPU_RESULTS_EXIST:\n                return \"CPU_RESULTS_EXIST\"; // NOI18N\n            case INSTRUMENT_METHOD_GROUP:\n                return \"INSTRUMENT_METHOD_GROUP\"; // NOI18N\n            case GET_CODE_REGION_CPU_RESULTS:\n                return \"GET_CODE_REGION_CPU_RESULTS\"; // NOI18N\n            case DEACTIVATE_INJECTED_CODE:\n                return \"DEACTIVATE_INJECTED_CODE\"; // NOI18N\n            case SUSPEND_TARGET_APP:\n                return \"SUSPEND_TARGET_APP\"; // NOI18N\n            case RESUME_TARGET_APP:\n                return \"RESUME_TARGET_APP\"; // NOI18N\n            case TERMINATE_TARGET_JVM:\n                return \"TERMINATE_TARGET_JVM\"; // NOI18N\n            case INITIATE_PROFILING:\n                return \"INITIATE_PROFILING\"; // NOI18N\n            case MESSAGE:\n                return \"MESSAGE\"; // NOI18N\n            case SHUTDOWN_OK:\n                return \"SHUTDOWN_OK\"; // NOI18N\n            case GET_THREAD_LIVENESS_STATUS:\n                return \"GET_THREAD_LIVENESS_STATUS\"; // NOI18N\n            case ROOT_CLASS_LOADED:\n                return \"ROOT_CLASS_LOADED\"; // NOI18N\n            case SHUTDOWN_INITIATED:\n                return \"SHUTDOWN_INITIATED\"; // NOI18N\n            case SHUTDOWN_COMPLETED:\n                return \"SHUTDOWN_COMPLETED\"; // NOI18N\n            case INSTRUMENT_REFLECTION:\n                return \"INSTRUMENT_REFLECTION\"; // NOI18N\n            case DEINSTRUMENT_REFLECTION:\n                return \"DEINSTRUMENT_REFLECTION\"; // NOI18N\n            case METHOD_LOADED:\n                return \"METHOD_LOADED\"; // NOI18N\n            case METHOD_INVOKED_FIRST_TIME:\n                return \"METHOD_INVOKED_FIRST_TIME\"; // NOI18N\n            case GET_INTERNAL_STATS:\n                return \"GET_INTERNAL_STATS\"; // NOI18N\n            case DETACH:\n                return \"DETACH\"; // NOI18N\n            case EVENT_BUFFER_DUMPED:\n                return \"EVENT_BUFFER_DUMPED\"; // NOI18N\n            case DUMP_EXISTING_RESULTS:\n                return \"DUMP_EXISTING_RESULTS\"; // NOI18N\n            case GET_VM_PROPERTIES:\n                return \"GET_VM_PROPERTIES\"; // NOI18N\n            case RESET_PROFILER_COLLECTORS:\n                return \"RESET_PROFILER_COLLECTORS\"; // NOI18N\n            case GET_OBJECT_ALLOCATION_RESULTS:\n                return \"GET_OBJECT_ALLOCATION_RESULTS\"; // NOI18N\n            case GET_METHOD_NAMES_FOR_JMETHOD_IDS:\n                return \"GET_METHOD_NAMES_FOR_JMETHOD_IDS\"; // NOI18N\n            case GET_MONITORED_NUMBERS:\n                return \"MONITORED_NUMBERS\"; // NOI18N\n            case RUN_GC:\n                return \"RUN_GC\"; // NOI18N\n            case RUN_CALIBRATION_AND_GET_DATA:\n                return \"RUN_CALIBRATION_AND_GET_DATA\"; // NOI18N\n            case GET_DEFINING_CLASS_LOADER:\n                return \"GET_DEFINING_CLASSLOADER\"; // NOI18N\n            case CLASS_LOADER_UNLOADING:\n                return \"CLASS_LOADER_UNLOADING\"; // NOI18N\n            case GET_STORED_CALIBRATION_DATA:\n                return \"GET_STORED_CALIBRATION_DATA\"; // NOI18N\n            case RESULTS_AVAILABLE:\n                return \"RESULTS_AVAILABLE\"; // NOI18N\n            case TAKE_SNAPSHOT:\n                return \"TAKE_SNAPSHOT\"; // NOI18N\n            case DUMP_EXISTING_RESULTS_LIVE:\n                return \"DUMP_EXISTING_RESULTS_LIVE\"; // NOI18N\n            case TAKE_HEAP_DUMP:\n                return \"TAKE_HEAP_DUMP\"; // NOI18N\n            case GET_CLASSID:\n                return \"GET_CLASSID\"; // NOI18N\n            case STILL_ALIVE:\n                return \"STILL_ALIVE\"; // NOI18N\n            case PREPARE_DETACH:\n                return \"PREPARE_DETACH\"; // NOI18N\n            case GET_HEAP_HISTOGRAM:\n                return \"GET_HEAP_HISTOGRAM\"; // NOI18N\n            case TAKE_THREAD_DUMP:\n                return \"TAKE_THREAD_DUMP\"; // NOI18N\n            case GET_CLASS_FILE_BYTES:\n                return \"GET_CLASS_FILE_BYTES\";  // NOI18N\n        }\n\n        return \"Unknown command\"; // NOI18N\n    }\n\n    // For debugging\n    public String toString() {\n        return cmdTypeToString(type);\n    }\n\n    void setType(int type) {\n        this.type = type;\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/DefiningLoaderResponse.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Response containing the id of the defining class loader, sent to the client in response to the relevant request.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class DefiningLoaderResponse extends Response {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int loaderId;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public DefiningLoaderResponse(int loaderId) {\n        super(true, DEFINING_LOADER);\n\n        if (loaderId == -1) {\n            loaderId = 0; // At the client side we treat classes loaded by bootstrap and by system classloaders in the same way\n        }\n\n        this.loaderId = loaderId;\n    }\n\n    // Custom serialization support\n    DefiningLoaderResponse() {\n        super(true, DEFINING_LOADER);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getLoaderId() {\n        return loaderId;\n    }\n\n    // For debugging\n    public String toString() {\n        return \"DefiningLoaderResponse, loaderId: \" + loaderId + \", \" + super.toString(); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        loaderId = in.readInt();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(loaderId);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/DumpResultsResponse.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Response to the client's request to dump the current rough profiling data contents into the shared-memory file.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class DumpResultsResponse extends Response {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private long dumpAbsTimeStamp;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public DumpResultsResponse(boolean yes, long absTimeStamp) {\n        super(yes, DUMP_RESULTS);\n        this.dumpAbsTimeStamp = absTimeStamp;\n    }\n\n    // Custom serialization support\n    DumpResultsResponse() {\n        super(true, DUMP_RESULTS);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public long getDumpAbsTimeStamp() {\n        return dumpAbsTimeStamp;\n    }\n\n    // For debugging\n    public String toString() {\n        return \"DumpResultsResponse, timeStamp: \" + dumpAbsTimeStamp + \", \" + super.toString(); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        dumpAbsTimeStamp = in.readLong();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeLong(dumpAbsTimeStamp);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/EventBufferDumpedCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.util.zip.DataFormatException;\nimport java.util.zip.Deflater;\nimport java.util.zip.Inflater;\n\n\n/**\n * This command is issued by the profiling back-end when an event buffer is dumped into the shared-memory file\n * for natural reasons (capacity exceeded).\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Tomas Hurka\n */\npublic class EventBufferDumpedCommand extends Command {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int bufSize;\n    private String eventBufferFileName;\n    private byte[] buffer;\n    private int startPos;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public EventBufferDumpedCommand(int bufSize, byte[] buf, int start) {\n        super(EVENT_BUFFER_DUMPED);\n        this.bufSize = bufSize;\n        buffer = buf;\n        startPos = start;\n        eventBufferFileName = \"\";\n    }\n\n    public EventBufferDumpedCommand(int bufSize, String bufferName) {\n        super(EVENT_BUFFER_DUMPED);\n        this.bufSize = bufSize;\n        buffer = null;\n        startPos = -1;\n        eventBufferFileName = bufferName;\n    }\n\n    // Custom serialization support\n    EventBufferDumpedCommand() {\n        super(EVENT_BUFFER_DUMPED);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getBufSize() {\n        return bufSize;\n    }\n\n    public byte[] getBuffer() {\n        return buffer;\n    }\n\n    // For debugging\n    public String toString() {\n        return super.toString() + \", bufSize: \" + bufSize + (eventBufferFileName.length()>0 ? \", eventBufferFileName:\" + eventBufferFileName : \"\"); // NOI18N\n    }\n\n    public String getEventBufferFileName() {\n        return eventBufferFileName;\n    }\n    \n    void readObject(ObjectInputStream in) throws IOException {\n        boolean hasBuffer;\n        \n        bufSize = in.readInt();\n        hasBuffer = in.readBoolean();\n        if (hasBuffer) {\n            int compressedSize = in.readInt();\n            byte[] compressedBuf = new byte[compressedSize];\n            Inflater decompressor = new Inflater();\n            \n            buffer = new byte[bufSize];\n            in.readFully(compressedBuf);\n            decompressor.setInput(compressedBuf);\n            try {\n                int originalSize = decompressor.inflate(buffer);\n                assert originalSize==bufSize;\n            } catch (DataFormatException ex) {\n                throw new IOException(ex.getMessage());\n            } finally {\n                decompressor.end();\n            }\n            eventBufferFileName = \"\";\n        } else {\n            eventBufferFileName = in.readUTF();\n        }\n    }\n    \n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(bufSize);\n        out.writeBoolean(buffer != null);\n        if (buffer != null) {\n            Deflater compressor = new Deflater();\n            // for small buffers, the compressed size can be somewhat larger than the original  \n            byte[] compressedBytes = new byte[bufSize + 32]; \n            int compressedSize;\n            \n            compressor.setInput(buffer,startPos,bufSize);\n            compressor.finish();\n            compressedSize = compressor.deflate(compressedBytes);\n            out.writeInt(compressedSize);\n            out.write(compressedBytes,0,compressedSize);\n        } else {\n            out.writeUTF(eventBufferFileName);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/GetClassFileBytesCommand.java",
    "content": "/*\n * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.util.Arrays;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class GetClassFileBytesCommand extends Command {\n\n    private String[] classes;\n    private int[] classLoaderIds;\n\n    public GetClassFileBytesCommand(String[] classes, int[] classLoaderIds) {\n        this();\n        this.classes = classes;\n        this.classLoaderIds = classLoaderIds;\n    }\n\n    // Custom serializaion support\n    GetClassFileBytesCommand() {\n        super(GET_CLASS_FILE_BYTES);\n    }\n\n    public int[] getClassLoaderIds() {\n        return classLoaderIds;\n    }\n\n    public String[] getClasses() {\n        return classes;\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        int nClasses = in.readInt();\n\n        if (nClasses == 0) {\n            return;\n        }\n\n        classes = new String[nClasses];\n        classLoaderIds = new int[nClasses];\n\n        for (int i = 0; i < nClasses; i++) {\n            classes[i] = in.readUTF().replace('/', '.');    // NOI18N\n            classLoaderIds[i] = in.readInt();\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        if (classes == null) {\n            out.writeInt(0);\n\n            return;\n        }\n\n        int nClasses = classes.length;\n        out.writeInt(nClasses);\n\n        for (int i = 0; i < nClasses; i++) {\n            out.writeUTF(classes[i]);\n            out.writeInt(classLoaderIds[i]);\n        }\n\n        classes = null;\n        classLoaderIds = null;\n    }\n\n    public String toString() {\n        return super.toString() + \" \"+classes.length+\" classes(): \"+Arrays.toString(classes);   // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/GetClassFileBytesResponse.java",
    "content": "/*\n * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class GetClassFileBytesResponse extends Response {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private byte[][] classBytes;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n    public GetClassFileBytesResponse(byte[][] bytes) {\n        this();\n        classBytes = bytes;\n    }\n\n    // Custom serialization support\n    GetClassFileBytesResponse() {\n        super(true, GET_CLASS_FILE_BYTES_RESPONSE);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    public byte[][] getClassBytes() {\n        return classBytes;\n    }\n\n    // For debugging\n    public String toString() {\n        return \"GetClassFileBytesResponse, classes: \" + classBytes.length + \", \" + super.toString(); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        int nClasses = in.readInt();\n\n        if (nClasses == 0) {\n            return;\n        }\n\n        classBytes = new byte[nClasses][];\n\n        for (int i = 0; i < nClasses; i++) {\n            int len = in.readInt();\n\n            if (len > 0) {\n                classBytes[i] = new byte[len];\n                in.readFully(classBytes[i]);\n            }\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(classBytes.length);\n\n        for (int i = 0; i < classBytes.length; i++) {\n            if (classBytes[i] == null) {\n                out.writeInt(0);\n            } else {\n                out.writeInt(classBytes[i].length);\n                out.write(classBytes[i]);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/GetClassIdCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Command that is issued by back end when the instance is allocated via reflection\n * and a classId is needed for given class identified by class name and classloader id.\n *\n * It is only used for Memory profiling\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class GetClassIdCommand extends Command {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private String className;\n    private int classLoaderId;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates new MethodLoadedCommand.\n     *\n     * @param className name of the class loaded\n     * @param classLoaderId id of ClassLoader that loaded the class\n     */\n    public GetClassIdCommand(String className, int classLoaderId) {\n        this();\n        this.className = className;\n\n        // At the client side we treat classes loaded by bootstrap and by system classloaders in the same way\n        if (classLoaderId == -1) {\n            classLoaderId = 0;\n        }\n\n        this.classLoaderId = classLoaderId;\n    }\n\n    // Custom serialization support\n    GetClassIdCommand() {\n        super(GET_CLASSID);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @return id of ClassLoader that loaded the class\n     */\n    public int getClassLoaderId() {\n        return classLoaderId;\n    }\n\n    /**\n     * @return name of the class loaded\n     */\n    public String getClassName() {\n        return className;\n    }\n\n    /**\n     * @return Debug println of values\n     */\n    public String toString() {\n        return super.toString() + \", className: \" + className // NOI18N\n               + \", classLoaderId: \" + classLoaderId; // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        className = in.readUTF();\n        classLoaderId = in.readInt();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeUTF(className);\n        out.writeInt(classLoaderId);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/GetClassIdResponse.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Response to the client's request when classId is needed for given class identified\n * by class name and classloader id.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class GetClassIdResponse extends Response {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int classId;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public GetClassIdResponse(boolean yes, int classId) {\n        super(yes, CLASSID_RESPONSE);\n        this.classId = classId;\n    }\n\n    // Custom serialization support\n    GetClassIdResponse() {\n        super(true, CLASSID_RESPONSE);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getClassId() {\n        return classId;\n    }\n\n    // For debugging\n    public String toString() {\n        return \"GetClassIdResponse, classId: \" + classId + \", \" + super.toString(); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        classId = in.readInt();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(classId);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/GetDefiningClassLoaderCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * A request to obtain the defining class loader for a given class and its initiating loader,\n * that the client sends to the server.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class GetDefiningClassLoaderCommand extends Command {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private String className;\n    private int classLoaderId;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    // This is to avoid creating a new instance of this class every time a new class is loaded\n    public GetDefiningClassLoaderCommand(String className, int classLoaderId) {\n        super(GET_DEFINING_CLASS_LOADER);\n        this.className = className.replace('/', '.'); // NOI18N\n        this.classLoaderId = classLoaderId;\n    }\n\n    // Custom serialization support\n    GetDefiningClassLoaderCommand() {\n        super(GET_DEFINING_CLASS_LOADER);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getClassLoaderId() {\n        return classLoaderId;\n    }\n\n    public String getClassName() {\n        return className;\n    }\n\n    // For debugging\n    public String toString() {\n        return super.toString() + \", className: \" + className + \", classLoaderId: \" + classLoaderId; // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        className = in.readUTF();\n        classLoaderId = in.readInt();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeUTF(className);\n        out.writeInt(classLoaderId);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/GetMethodNamesForJMethodIdsCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Request from the client to the back end to return names of methods with specified jmethodIDs.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class GetMethodNamesForJMethodIdsCommand extends Command {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int[] methodIds;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public GetMethodNamesForJMethodIdsCommand(int[] methodIds) {\n        super(GET_METHOD_NAMES_FOR_JMETHOD_IDS);\n        this.methodIds = methodIds;\n    }\n\n    // Custom serialization support\n    GetMethodNamesForJMethodIdsCommand() {\n        super(GET_METHOD_NAMES_FOR_JMETHOD_IDS);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int[] getMethodIds() {\n        return methodIds;\n    }\n\n    // For debugging\n    public String toString() {\n        return super.toString() + \", length: \" + methodIds.length; // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        int len = in.readInt();\n        methodIds = new int[len];\n\n        for (int i = 0; i < len; i++) {\n            methodIds[i] = in.readInt();\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(methodIds.length);\n\n        for (int i = 0; i < methodIds.length; i++) {\n            out.writeInt(methodIds[i]);\n        }\n\n        methodIds = null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/HeapHistogramResponse.java",
    "content": "/*\n * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.util.Date;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class HeapHistogramResponse extends Response {\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Date time;\n    private String[] newNames;\n    private int[] newids;\n    private int[] ids;\n    private long[] instances,bytes;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public HeapHistogramResponse(Date t, String[] nn, int[] nid, int[] id, long[] i, long[] b) {\n        super(true, HEAP_HISTOGRAM);\n        time = t;\n        newNames = nn;\n        newids = nid;\n        ids = id;\n        instances = i;\n        bytes = b;\n    }\n\n    // Custom serialization support\n    HeapHistogramResponse() {\n        super(true, HEAP_HISTOGRAM);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Date getTime() {\n        return time;\n    }\n\n    public String[] getNewNames() {\n        return newNames;\n    }\n\n    public int[] getNewids() {\n        return newids;\n    }\n\n    public int[] getIds() {\n        return ids;\n    }\n\n    public long[] getInstances() {\n        return instances;\n    }\n\n    public long[] getBytes() {\n        return bytes;\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        long t = in.readLong();\n        time = new Date(t);\n        int len = in.readInt();\n        newNames = new String[len];\n        for (int i = 0; i < len; i++) {\n            newNames[i] = in.readUTF();\n        }\n        len = in.readInt();\n        newids = new int[len];\n        for (int i = 0; i < len; i++) {\n            newids[i] = in.readInt();\n        }\n        len = in.readInt();\n        ids = new int[len];\n        for (int i = 0; i < len; i++) {\n            ids[i] = in.readInt();\n        }\n        len = in.readInt();\n        instances = new long[len];\n        for (int i = 0; i < len; i++) {\n            instances[i] = in.readLong();\n        }\n        len = in.readInt();\n        bytes = new long[len];\n        for (int i = 0; i < len; i++) {\n            bytes[i] = in.readLong();\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeLong(time.getTime());\n        out.writeInt(newNames.length);\n        for (int i = 0; i < newNames.length; i++) {\n            out.writeUTF(newNames[i]);\n        }\n        out.writeInt(newids.length);\n        for (int i = 0; i < newids.length; i++) {\n            out.writeInt(newids[i]);\n        }\n        out.writeInt(ids.length);\n        for (int i = 0; i < ids.length; i++) {\n            out.writeInt(ids[i]);\n        }\n        out.writeInt(instances.length);\n        for (int i = 0; i < instances.length; i++) {\n            out.writeLong(instances[i]);\n        }\n        out.writeInt(bytes.length);\n        for (int i = 0; i < bytes.length; i++) {\n            out.writeLong(bytes[i]);\n        }\n        newNames = null;\n        newids = null;\n        ids = null;\n        instances = null;\n        bytes = null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/InitiateProfilingCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n/**\n * Request from the client to the back end to initiate TA instrumentation of the given type.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Adrian Mos\n * @author Ian Formanek\n */\npublic class InitiateProfilingCommand extends Command {\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private String[] classNames;\n    private String[] profilingPointHandlers;\n    private int[] profilingPointIDs;\n    private String[] profilingPointInfos;\n    private boolean instrSpawnedThreads;\n    private boolean startProfilingPointsActive;\n    private int instrType;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public InitiateProfilingCommand(int instrType, String[] classNames,\n                                          int[] ppIDs, String[] ppHandlers, String[] ppInfos,\n                                          boolean instrSpawnedThreads, boolean startProfilingPointsActive) {\n        super(INITIATE_PROFILING);\n        if ((classNames == null)) {\n            classNames = new String[] { \" \" }; // NOI18N\n        } else if (classNames[0] == null) {\n            classNames[0] = \" \"; // NOI18N\n        }\n\n        this.instrType = instrType;\n        this.classNames = classNames;\n        profilingPointIDs = ppIDs;\n        profilingPointHandlers = ppHandlers;\n        profilingPointInfos = ppInfos;\n        this.instrSpawnedThreads = instrSpawnedThreads;\n        this.startProfilingPointsActive = startProfilingPointsActive;\n    }\n\n    /** Legacy support for single root instrumentation */\n    public InitiateProfilingCommand(int instrType, String className, boolean instrSpawnedThreads,\n                                          boolean startProfilingPointsActive) {\n        this(instrType,\n             className==null ? new String[]{\" \"} : new String[]{className},\n             null,null,null,\n             instrSpawnedThreads,startProfilingPointsActive);\n    }\n\n\n    /** This is a special method only called to setup the connection in ProfilerClient.connectToServer() - see comments there */\n    public InitiateProfilingCommand(int instrType, String className) {\n        this(instrType,className,false,false);\n    }\n\n    public InitiateProfilingCommand(int instrType) {\n        this(instrType,null);\n    }\n\n    // Custom serialzation support\n    InitiateProfilingCommand() {\n        super(INITIATE_PROFILING);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public boolean getInstrSpawnedThreads() {\n        return instrSpawnedThreads;\n    }\n\n    public void setInstrType(int t) {\n        instrType = t;\n    }\n\n    public int getInstrType() {\n        return instrType;\n    }\n\n    public String[] getProfilingPointHandlers() {\n        return profilingPointHandlers;\n    }\n\n    public int[] getProfilingPointIDs() {\n        return profilingPointIDs;\n    }\n\n    public String[] getProfilingPointInfos() {\n        return profilingPointInfos;\n    }\n\n    public String getRootClassName() {\n        return classNames[0];\n    } // Legacy support for one root\n\n    public String[] getRootClassNames() {\n        return classNames;\n    }\n\n    public boolean isStartProfilingPointsActive() {\n        return startProfilingPointsActive;\n    }\n\n    // for debugging\n    public String toString() {\n        return super.toString() + \", instrType = \" + instrType; // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        instrType = in.readInt();\n\n        int len = in.readInt();\n        classNames = new String[len];\n\n        for (int i = 0; i < len; i++) {\n            classNames[i] = in.readUTF().intern(); // Interning is important, since checks are through '=='\n        }\n\n        instrSpawnedThreads = in.readBoolean();\n        startProfilingPointsActive = in.readBoolean();\n\n        try {\n            profilingPointIDs = (int[]) in.readObject();\n            profilingPointHandlers = (String[]) in.readObject();\n            profilingPointInfos = (String[]) in.readObject();\n        } catch (ClassNotFoundException e) {\n            throw new IOException(e);\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(instrType);\n        out.writeInt(classNames.length);\n\n        for (int i = 0; i < classNames.length; i++) {\n            out.writeUTF(classNames[i]);\n        }\n\n        out.writeBoolean(instrSpawnedThreads);\n        out.writeBoolean(startProfilingPointsActive);\n        out.writeObject(profilingPointIDs);\n        out.writeObject(profilingPointHandlers);\n        out.writeObject(profilingPointInfos);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/InstrumentMethodGroupCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Request from client to back end to instrument a group of TA methods.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class InstrumentMethodGroupCommand extends Command {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private InstrumentMethodGroupData b;\n    private int instrType;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** 1.5-style RedefineClasses() instrumentation constructor */\n    public InstrumentMethodGroupCommand(int instrType, String[] instrMethodClasses, int[] instrMethodClassLoaderIds,\n                                        byte[][] replacementClassFileBytes, boolean[] instrMethodLeaf, int addInfo) {\n        super(INSTRUMENT_METHOD_GROUP);\n        this.instrType = instrType;\n        b = new InstrumentMethodGroupData(instrMethodClasses, instrMethodClassLoaderIds, replacementClassFileBytes,\n                                          instrMethodLeaf, addInfo);\n    }\n\n    /** This is used just to send \"empty\" commands, meaning no methods are instrumented */\n    public InstrumentMethodGroupCommand(Object dummy) {\n        super(INSTRUMENT_METHOD_GROUP);\n        instrType = -1;\n    }\n\n    // Custom serializaion support\n    InstrumentMethodGroupCommand() {\n        super(INSTRUMENT_METHOD_GROUP);\n        b = new InstrumentMethodGroupData();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public InstrumentMethodGroupData getBase() {\n        return b;\n    }\n\n    public int[] getClassLoaderIds() {\n        return b.instrMethodClassLoaderIds;\n    }\n\n    public boolean isEmpty() {\n        return instrType == -1;\n    }\n\n    public boolean[] getInstrMethodLeaf() {\n        return b.instrMethodLeaf;\n    }\n\n    public int getInstrType() {\n        return instrType;\n    }\n\n    public String[] getMethodClasses() {\n        return b.instrMethodClasses;\n    }\n\n    public byte[][] getReplacementClassFileBytes() {\n        return b.replacementClassFileBytes;\n    }\n\n    public void dump() {\n        System.err.print(\"-- InstrumentMethodGroupCommand: \"); // NOI18N\n\n        if (b != null) {\n            b.dump();\n        }\n    }\n\n    // ------------------------ Debugging -------------------------\n    public String toString() {\n        return super.toString() + \" \" + ((b != null) ? b.toString() : \"null\"); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        instrType = in.readInt();\n\n        if (!isEmpty()) {\n            b.readObject(in);\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(instrType);\n\n        if (!isEmpty()) {\n            b.writeObject(out);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/InstrumentMethodGroupData.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Conceptually, the base class for both InstrumentMethodGroupResponse and InstrumentMethodGroupCommand. However, we have to use\n * an instance of this class in each of the above, plus some delegation, instead of normal inheritance, since the above classes\n * have to extend Response and Command, respectively.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n */\npublic class InstrumentMethodGroupData {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected int[] instrMethodClassLoaderIds;\n    protected String[] instrMethodClasses;\n    protected boolean[] instrMethodLeaf;\n    protected byte[][] replacementClassFileBytes;\n    protected int addInfo;\n    protected int nClasses;\n    protected int nMethods;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** 1.5-style RedefineClasses() instrumentation constructor */\n    public InstrumentMethodGroupData(String[] instrMethodClasses, int[] instrMethodClassLoaderIds,\n                                     byte[][] replacementClassFileBytes, boolean[] instrMethodLeaf, int addInfo) {\n        nClasses = instrMethodClasses.length;\n        nMethods = (instrMethodLeaf != null) ? instrMethodLeaf.length : 0;\n        this.instrMethodClasses = instrMethodClasses;\n        this.instrMethodClassLoaderIds = instrMethodClassLoaderIds;\n        this.replacementClassFileBytes = replacementClassFileBytes;\n        this.addInfo = addInfo;\n    }\n\n    // Custom serializaion support\n    InstrumentMethodGroupData() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getAddInfo() {\n        return addInfo;\n    }\n\n    public int[] getClassLoaderIds() {\n        return instrMethodClassLoaderIds;\n    }\n\n    public boolean[] getInstrMethodLeaf() {\n        return instrMethodLeaf;\n    }\n\n    public String[] getMethodClasses() {\n        return instrMethodClasses;\n    }\n\n    public int getNClasses() {\n        return nClasses;\n    }\n\n    public int getNMethods() {\n        return nMethods;\n    }\n\n    public byte[][] getReplacementClassFileBytes() {\n        return replacementClassFileBytes;\n    }\n\n    public void dump() {\n        if (instrMethodClasses == null) {\n            System.err.println(\"0 classes --\"); // NOI18N\n\n            return;\n        } else {\n            if (instrMethodClasses[0].startsWith(\"*FAKE\")) { // NOI18N\n                System.err.println(\"Fake InstrMethodGroupBase --\"); // NOI18N\n\n                return;\n            }\n\n            System.err.println(nClasses + \" classes, \" + nMethods + \" methods --\"); // NOI18N\n        }\n\n        int idx = 0;\n\n        for (int i = 0; i < nClasses; i++) {\n            System.err.print(\"--Class \" + instrMethodClasses[i] + \",\" + instrMethodClassLoaderIds[i]); // NOI18N\n            System.err.println();\n        }\n    }\n\n    // ------------------------ Debugging -------------------------\n    public String toString() {\n        return ((instrMethodClasses != null) ? (instrMethodClasses.length) : 0) + \" classes.\"; // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        nClasses = in.readInt();\n\n        if (nClasses == 0) {\n            return;\n        }\n\n        if ((instrMethodClasses == null) || (nClasses > instrMethodClasses.length)) {\n            instrMethodClasses = new String[nClasses];\n            instrMethodClassLoaderIds = new int[nClasses];\n        }\n\n        for (int i = 0; i < nClasses; i++) {\n            instrMethodClasses[i] = in.readUTF();\n            instrMethodClassLoaderIds[i] = in.readInt();\n        }\n\n        nMethods = in.readInt();\n\n        int code = in.read();\n\n        if (code != 0) {\n            if ((instrMethodLeaf == null) || (nMethods > instrMethodLeaf.length)) {\n                instrMethodLeaf = new boolean[nMethods];\n            }\n\n            for (int i = 0; i < nMethods; i++) {\n                instrMethodLeaf[i] = in.readBoolean();\n            }\n        } else {\n            instrMethodLeaf = null;\n        }\n\n        addInfo = in.readInt();\n\n        if ((replacementClassFileBytes == null) || (nClasses > replacementClassFileBytes.length)) {\n            replacementClassFileBytes = new byte[nClasses][];\n        }\n\n        for (int i = 0; i < nClasses; i++) {\n            int len = in.readInt();\n\n            if (len > 0) {\n                replacementClassFileBytes[i] = new byte[len];\n                in.readFully(replacementClassFileBytes[i]);\n            }\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        if (instrMethodClasses == null) {\n            out.writeInt(0);\n\n            return;\n        }\n\n        out.writeInt(nClasses);\n\n        for (int i = 0; i < nClasses; i++) {\n            out.writeUTF(instrMethodClasses[i]);\n            out.writeInt(instrMethodClassLoaderIds[i]);\n        }\n\n        out.writeInt(nMethods);\n\n        if (instrMethodLeaf != null) {\n            out.write(1);\n\n            for (int i = 0; i < nMethods; i++) {\n                out.writeBoolean(instrMethodLeaf[i]);\n            }\n        } else {\n            out.write(0);\n        }\n\n        out.writeInt(addInfo);\n\n        for (int i = 0; i < nClasses; i++) {\n            if (replacementClassFileBytes[i] == null) {\n                out.writeInt(0);\n            } else {\n                out.writeInt(replacementClassFileBytes[i].length);\n                out.write(replacementClassFileBytes[i]);\n            }\n        }\n\n        instrMethodClasses = null;\n        instrMethodClassLoaderIds = null;\n        instrMethodLeaf = null;\n        replacementClassFileBytes = null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/InstrumentMethodGroupResponse.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Response from client to back end, that contains a group of TA methods to instrument.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class InstrumentMethodGroupResponse extends Response {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private InstrumentMethodGroupData b;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** 1.5-style RedefineClasses() instrumentation constructor */\n    public InstrumentMethodGroupResponse(String[] instrMethodClasses, int[] instrMethodClassLoaderIds,\n                                         byte[][] replacementClassFileBytes, boolean[] instrMethodLeaf, int addInfo) {\n        super(true, INSTRUMENT_METHOD_GROUP);\n        b = new InstrumentMethodGroupData(instrMethodClasses, instrMethodClassLoaderIds, replacementClassFileBytes,\n                                          instrMethodLeaf, addInfo);\n    }\n\n    /** This is used just to send \"empty\" responses, meaning no methods are instrumented */\n    public InstrumentMethodGroupResponse(Object dummy) {\n        super(false, INSTRUMENT_METHOD_GROUP);\n    }\n\n    // Custom serializaion support\n    InstrumentMethodGroupResponse() {\n        super(INSTRUMENT_METHOD_GROUP);\n        b = new InstrumentMethodGroupData();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public InstrumentMethodGroupData getBase() {\n        return b;\n    }\n\n    public int[] getClassLoaderIds() {\n        return b.instrMethodClassLoaderIds;\n    }\n\n    public boolean isEmpty() {\n        return !yes;\n    }\n\n    public boolean[] getInstrMethodLeaf() {\n        return b.instrMethodLeaf;\n    }\n\n    public String[] getMethodClasses() {\n        return b.instrMethodClasses;\n    }\n\n    public byte[][] getReplacementClassFileBytes() {\n        return b.replacementClassFileBytes;\n    }\n\n    public void dump() {\n        System.err.print(\"-- InstrumentMethodGroupResponse: \"); // NOI18N\n        b.dump();\n    }\n\n    // ------------------------ Debugging -------------------------\n    public String toString() {\n        return \"InstrumentMethodGroupResponse \" + ((b != null) ? b.toString() : \"empty\"); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        if (!isEmpty()) {\n            b.readObject(in);\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        if (!isEmpty()) {\n            b.writeObject(out);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/InternalStatsResponse.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Response containing instrumentation- and profiling-related statistics - most of the data that is presented if one\n * invokes Profile | Get internal statistics command in the tool.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class InternalStatsResponse extends Response {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    public double averageHotswappingTime;\n    public double clientDataProcTime;\n    public double clientInstrTime;\n    public double maxHotswappingTime;\n    public double methodEntryExitCallTime0;\n    public double methodEntryExitCallTime1;\n    public double methodEntryExitCallTime2;\n    public double minHotswappingTime;\n    public double totalHotswappingTime;\n    public int nClassLoads;\n    public int nEmptyInstrMethodGroupResponses;\n    public int nFirstMethodInvocations;\n    public int nNonEmptyInstrMethodGroupResponses;\n    public int nSingleMethodInstrMethodGroupResponses;\n\n    // Fields made public as an exception, to avoid too many accessors\n    public int nTotalInstrMethods;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * We don't use a normal constructor with parameters here, since there are too many parameters to pass.\n     * Instead we use public data fields.\n     */\n    public InternalStatsResponse() {\n        super(true, INTERNAL_STATS);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    // For debugging\n    public String toString() {\n        return \"InternalStatsResponse, \" + super.toString(); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        nTotalInstrMethods = in.readInt();\n        nClassLoads = in.readInt();\n        nFirstMethodInvocations = in.readInt();\n        nNonEmptyInstrMethodGroupResponses = in.readInt();\n        nEmptyInstrMethodGroupResponses = in.readInt();\n        nSingleMethodInstrMethodGroupResponses = in.readInt();\n        clientInstrTime = in.readDouble();\n        clientDataProcTime = in.readDouble();\n        totalHotswappingTime = in.readDouble();\n        averageHotswappingTime = in.readDouble();\n        minHotswappingTime = in.readDouble();\n        maxHotswappingTime = in.readDouble();\n        methodEntryExitCallTime0 = in.readDouble();\n        methodEntryExitCallTime1 = in.readDouble();\n        methodEntryExitCallTime2 = in.readDouble();\n    }\n\n    // Custom serialization support\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(nTotalInstrMethods);\n        out.writeInt(nClassLoads);\n        out.writeInt(nFirstMethodInvocations);\n        out.writeInt(nNonEmptyInstrMethodGroupResponses);\n        out.writeInt(nEmptyInstrMethodGroupResponses);\n        out.writeInt(nSingleMethodInstrMethodGroupResponses);\n        out.writeDouble(clientInstrTime);\n        out.writeDouble(clientDataProcTime);\n        out.writeDouble(totalHotswappingTime);\n        out.writeDouble(averageHotswappingTime);\n        out.writeDouble(minHotswappingTime);\n        out.writeDouble(maxHotswappingTime);\n        out.writeDouble(methodEntryExitCallTime0);\n        out.writeDouble(methodEntryExitCallTime1);\n        out.writeDouble(methodEntryExitCallTime2);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/MethodInvokedFirstTimeCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Command issued by the back end when the lazy transitive CPU profiling instrumentation scheme is used,\n * and the given method is invoked for the first time.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class MethodInvokedFirstTimeCommand extends Command {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private char methodId;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public MethodInvokedFirstTimeCommand(char methodId) {\n        super(METHOD_INVOKED_FIRST_TIME);\n        this.methodId = methodId;\n    }\n\n    // Custom serialization support\n    MethodInvokedFirstTimeCommand() {\n        super(METHOD_INVOKED_FIRST_TIME);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getMethodId() {\n        return methodId;\n    }\n\n    // for debugging\n    public String toString() {\n        return super.toString() + \", methodId: \" + ((int) methodId); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        methodId = in.readChar();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeChar(methodId);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/MethodLoadedCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Command that is issued by back end when the option to instrument methods invoked via reflection is on,\n * and a given method is just about to be executed in this way.\n *\n * It is only used for CPU profiling, when Eager or Lazy schemes are used (RecursiveMethodInstrumentor1 or\n * RecursiveMethodInstrumentor2). In total scheme, everything is handle by ClassLoadedCommand.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class MethodLoadedCommand extends Command {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private String className;\n    private String methodName;\n    private String methodSignature;\n    private int classLoaderId;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates new MethodLoadedCommand.\n     *\n     * @param className name fo the class loaded\n     * @param classLoaderId id of ClassLoader that loaded the class\n     * @param methodName Name of method that is going to be invoked\n     * @param methodSignature Signature of method that is going to be invoked\n     */\n    public MethodLoadedCommand(String className, int classLoaderId, String methodName, String methodSignature) {\n        super(METHOD_LOADED);\n        this.className = className;\n\n        // At the client side we treat classes loaded by bootstrap and by system classloaders in the same way\n        if (classLoaderId == -1) {\n            classLoaderId = 0;\n        }\n\n        this.classLoaderId = classLoaderId;\n        this.methodName = methodName;\n        this.methodSignature = methodSignature;\n    }\n\n    // Custom serialization support\n    MethodLoadedCommand() {\n        super(METHOD_LOADED);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @return id of ClassLoader that loaded the class\n     */\n    public int getClassLoaderId() {\n        return classLoaderId;\n    }\n\n    /**\n     * @return name fo the class loaded\n     */\n    public String getClassName() {\n        return className;\n    }\n\n    /**\n     * @return Name of method that is going to be invoked\n     */\n    public String getMethodName() {\n        return methodName;\n    }\n\n    /**\n     * @return Signature of method that is going to be invoked\n     */\n    public String getMethodSignature() {\n        return methodSignature;\n    }\n\n    /**\n     * @return Debug println of values\n     */\n    public String toString() {\n        return super.toString() + \", className: \" + className // NOI18N\n               + \", classLoaderId: \" + classLoaderId // NOI18N\n               + \", methodName: \" + methodName // NOI18N\n               + \", methodSignature: \" + methodSignature; // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        className = in.readUTF();\n        classLoaderId = in.readInt();\n        methodName = in.readUTF();\n        methodSignature = in.readUTF();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeUTF(className);\n        out.writeInt(classLoaderId);\n        out.writeUTF(methodName);\n        out.writeUTF(methodSignature);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/MethodNamesResponse.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * This is issued by back end in response to GetMethodNamesForJMethodIdsCommand. It contains strings with methods'\n * classes, names and signatures, packed into a single byte[] array. At the client side this data is subsequently\n * unpacked (not in this class to avoid having unused code at the back end side).\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class MethodNamesResponse extends Response {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int[] packedArrayOffsets;\n    private byte[] packedData;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public MethodNamesResponse(byte[] packedData, int[] packedArrayOffsets) {\n        super(true, METHOD_NAMES);\n        this.packedData = packedData;\n        this.packedArrayOffsets = packedArrayOffsets;\n    }\n\n    // Custom serialization support\n    MethodNamesResponse() {\n        super(true, METHOD_NAMES);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int[] getPackedArrayOffsets() {\n        return packedArrayOffsets;\n    }\n\n    public byte[] getPackedData() {\n        return packedData;\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        int len = in.readInt();\n        packedData = new byte[len];\n        in.readFully(packedData);\n        len = in.readInt();\n        packedArrayOffsets = new int[len];\n\n        for (int i = 0; i < len; i++) {\n            packedArrayOffsets[i] = in.readInt();\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(packedData.length);\n        out.write(packedData);\n        out.writeInt(packedArrayOffsets.length);\n\n        for (int i = 0; i < packedArrayOffsets.length; i++) {\n            out.writeInt(packedArrayOffsets[i]);\n        }\n\n        packedData = null;\n        packedArrayOffsets = null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/MonitoredNumbersResponse.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.util.Arrays;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n\n/**\n * This Response, issued by the back end, contains the current information about free and total memory available\n * for the target application.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class MonitoredNumbersResponse extends Response {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int FREE_MEMORY_IDX = 0;\n    public static final int TOTAL_MEMORY_IDX = 1;\n    public static final int USER_THREADS_IDX = 2;\n    public static final int SYSTEM_THREADS_IDX = 3;\n    public static final int SURVIVING_GENERATIONS_IDX = 4;\n    public static final int GC_TIME_IDX = 5;\n    public static final int GC_PAUSE_IDX = 6;\n    public static final int LOADED_CLASSES_IDX = 7;\n    public static final int CPU_TIME_IDX = 8;\n    public static final int TIMESTAMP_IDX = 9;\n    public static final int GENERAL_NUMBERS_SIZE = 10;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private long[] gcFinishs;\n    private long[] gcStarts;\n    private long[] generalNumbers = new long[GENERAL_NUMBERS_SIZE];\n    private String[] newThreadClassNames;\n    private int[] newThreadIds;\n    private String[] newThreadNames;\n    private long[] stateTimestamps = new long[10];\n    private int[] threadIds = new int[10];\n    private byte[] threadStates = new byte[100];\n    private int nNewThreads;\n    private int nThreadStates;\n    private int nThreads;\n\n    private int[] exactThreadIds;\n    private byte[] exactThreadStates;\n    private long[] exactTimeStamps;\n    private int mode = CommonConstants.MODE_THREADS_NONE;\n    private int serverState = CommonConstants.SERVER_RUNNING;\n    private int serverProgress = CommonConstants.SERVER_PROGRESS_INDETERMINATE;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public MonitoredNumbersResponse(long[] generalNumbers, int serverState, int serverProgress) {\n        super(true, MONITORED_NUMBERS);\n        this.generalNumbers = generalNumbers;\n        this.nNewThreads = 0;\n        this.serverState = serverState;\n        this.serverProgress = serverProgress;\n    }\n\n    // Custom serialization support\n    MonitoredNumbersResponse() {\n        super(true, MONITORED_NUMBERS);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setDataOnNewThreads(int nNewThreads, int[] newThreadIds, String[] newThreadNames, String[] newThreadClassNames) {\n        this.nNewThreads = nNewThreads;\n        this.newThreadIds = newThreadIds;\n        this.newThreadNames = newThreadNames;\n        this.newThreadClassNames = newThreadClassNames;\n    }\n\n    public void setDataOnThreads(int nThreads, int nThreadStates, int[] threadIds, long[] stateTimestamps, byte[] threadStates) {\n        this.mode = CommonConstants.MODE_THREADS_SAMPLING;\n        this.nThreads = nThreads;\n        this.nThreadStates = nThreadStates;\n        this.threadIds = threadIds;\n        this.stateTimestamps = stateTimestamps;\n        this.threadStates = threadStates;\n    }\n\n    public void setExplicitDataOnThreads(int[] explicitThreads, byte[] explicitStates, long[] explicitTimeStamps) {\n        assert (explicitStates.length == explicitThreads.length && explicitThreads.length == explicitTimeStamps.length);\n        this.mode = CommonConstants.MODE_THREADS_EXACT;\n        this.exactThreadIds = explicitThreads;\n        this.exactThreadStates = explicitStates;\n        this.exactTimeStamps = explicitTimeStamps;\n    }\n\n    public long[] getGCFinishs() {\n        return gcFinishs;\n    }\n\n    public long[] getGCStarts() {\n        return gcStarts;\n    }\n\n    public void setGCstartFinishData(long[] start, long[] finish) {\n        gcStarts = start;\n        gcFinishs = finish;\n    }\n\n    public long[] getGeneralMonitoredNumbers() {\n        return generalNumbers;\n    }\n\n    public int getNNewThreads() {\n        return nNewThreads;\n    }\n\n    public int getNThreadStates() {\n        return nThreadStates;\n    }\n\n    public int getNThreads() {\n        return nThreads;\n    }\n\n    public String[] getNewThreadClassNames() {\n        return newThreadClassNames;\n    }\n\n    public int[] getNewThreadIds() {\n        return newThreadIds;\n    }\n\n    public String[] getNewThreadNames() {\n        return newThreadNames;\n    }\n\n    public long[] getStateTimestamps() {\n        return stateTimestamps;\n    }\n\n    public int[] getThreadIds() {\n        return threadIds;\n    }\n\n    public byte[] getThreadStates() {\n        return threadStates;\n    }\n  \n    public int getThreadsDataMode(){\n        return mode;\n    }\n\n    // sampling-based data, to be used in case mode=MODE_THREADS_EXACT\n    public int[] getExactThreadIds() {\n        return exactThreadIds;\n    }\n    public byte[] getExactThreadStates() {\n        return exactThreadStates;\n    }\n    public long[] getExactStateTimestamps() {\n        return exactTimeStamps;\n    }\n    \n    public int getServerState() {\n        return serverState;\n    }\n\n    public int getServerProgress() {\n        return serverProgress;\n    }\n\n    // For debugging\n    public String toString() {\n        return super.toString() + \", mode=\" + mode +     // NOI18N\n                \", serverState=\" + serverState           // NOI18N\n                 + \", serverProgress=\" + serverProgress; // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        int arrSize;\n\n        mode = in.readInt();\n        for (int i = 0; i < generalNumbers.length; i++) {\n            generalNumbers[i] = in.readLong();\n        }\n\n        if (mode == CommonConstants.MODE_THREADS_SAMPLING) {\n            nThreads = in.readInt();\n            nThreadStates = in.readInt();\n            if (threadIds.length < nThreads) {\n                threadIds = new int[nThreads];\n            }\n            if (stateTimestamps.length < nThreadStates) {\n                stateTimestamps = new long[nThreadStates];\n            }\n            \n            int len = nThreads * nThreadStates;\n            \n            if (threadStates.length < len) {\n                threadStates = new byte[len];\n            }\n            for (int i = 0; i < nThreads; i++) {\n                threadIds[i] = in.readInt();\n            }\n            for (int i = 0; i < nThreadStates; i++) {\n                stateTimestamps[i] = in.readLong();\n            }\n            in.readFully(threadStates, 0, len);\n        }  else if (mode == CommonConstants.MODE_THREADS_EXACT) {\n            int exactLen = in.readInt();\n            exactThreadIds = new int[exactLen];\n            exactThreadStates = new byte[exactLen];\n            exactTimeStamps = new long[exactLen];\n            \n            for (int i = 0; i < exactLen; i++) {\n                exactThreadIds[i] = in.readInt();\n                exactThreadStates[i] = in.readByte();\n                exactTimeStamps[i] = in.readLong();\n            }\n        }\n\n        nNewThreads = in.readInt();\n\n        if (nNewThreads > 0) {\n            if ((newThreadIds == null) || (newThreadIds.length < nNewThreads)) {\n                newThreadIds = new int[nNewThreads];\n                newThreadNames = new String[nNewThreads];\n                newThreadClassNames = new String[nNewThreads];\n            }\n\n            for (int i = 0; i < nNewThreads; i++) {\n                newThreadIds[i] = in.readInt();\n                newThreadNames[i] = in.readUTF();\n                newThreadClassNames[i] = in.readUTF();\n            }\n        }\n\n        arrSize = in.readInt();\n        gcStarts = new long[arrSize];\n\n        for (int i = 0; i < arrSize; i++) {\n            gcStarts[i] = in.readLong();\n        }\n\n        arrSize = in.readInt();\n        gcFinishs = new long[arrSize];\n\n        for (int i = 0; i < arrSize; i++) {\n            gcFinishs[i] = in.readLong();\n        }\n\n        Arrays.sort(gcStarts);\n        Arrays.sort(gcFinishs);\n\n        serverState = in.readInt();\n        serverProgress = in.readInt();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(mode);\n        for (int i = 0; i < generalNumbers.length; i++) {\n            out.writeLong(generalNumbers[i]);\n        }\n\n        if (mode == CommonConstants.MODE_THREADS_SAMPLING) {\n            out.writeInt(nThreads);\n            out.writeInt(nThreadStates);\n            for (int i = 0; i < nThreads; i++) {\n                out.writeInt(threadIds[i]);\n            }\n            for (int i = 0; i < nThreadStates; i++) {\n                out.writeLong(stateTimestamps[i]);\n            }\n            int len = nThreads * nThreadStates;\n            out.write(threadStates, 0, len);\n        } else if (mode == CommonConstants.MODE_THREADS_EXACT) {\n            out.writeInt(exactThreadStates.length);\n            for (int i = 0; i < exactThreadIds.length; i++) {\n                out.writeInt(exactThreadIds[i]);\n                out.writeByte(exactThreadStates[i]);\n                out.writeLong(exactTimeStamps[i]);\n            }\n        }\n\n        if (nNewThreads == 0) {\n            out.writeInt(0);\n        } else {\n            out.writeInt(nNewThreads);\n\n            for (int i = 0; i < nNewThreads; i++) {\n                out.writeInt(newThreadIds[i]);\n                out.writeUTF(newThreadNames[i]);\n                out.writeUTF(newThreadClassNames[i]);\n            }\n        }\n\n        out.writeInt(gcStarts.length);\n\n        for (int i = 0; i < gcStarts.length; i++) {\n            out.writeLong(gcStarts[i]);\n        }\n\n        out.writeInt(gcFinishs.length);\n\n        for (int i = 0; i < gcFinishs.length; i++) {\n            out.writeLong(gcFinishs[i]);\n        }\n\n        out.writeInt(serverState);\n        out.writeInt(serverProgress);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/ObjectAllocationResultsResponse.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * This Response, issued by the back end, contains the current information about the number of objects allocated\n * for each type.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class ObjectAllocationResultsResponse extends Response {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int[] results;\n    private int nEntries;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ObjectAllocationResultsResponse(int[] results, int nEntries) {\n        super(true, OBJECT_ALLOCATION_RESULTS);\n        this.results = results;\n        this.nEntries = nEntries;\n    }\n\n    // Custom serialization support\n    ObjectAllocationResultsResponse() {\n        super(true, OBJECT_ALLOCATION_RESULTS);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int[] getResults() {\n        return results;\n    }\n\n    // For debugging\n    public String toString() {\n        return \"ObjectAllocationResultsResponse, entries: \" + nEntries + \", \" + super.toString(); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        nEntries = in.readInt();\n        results = new int[nEntries];\n\n        for (int i = 0; i < nEntries; i++) {\n            results[i] = in.readInt();\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(nEntries);\n\n        for (int i = 0; i < nEntries; i++) {\n            out.writeInt(results[i]);\n        }\n\n        results = null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/Response.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Instances of this class are sent back by both client and back end (server) in response to some Commands.\n * An instance of the base Response class is used to signal just success or failure (with possible additional\n * error message). Instances of its subclasses are used to pass additional information.\n *\n * @author Misha Dmitriev\n */\npublic class Response {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // Each new response class should have its own identifier, listed here.\n    public static final int NO_TYPE = 0;\n    public static final int CODE_REGION_CPU_RESULTS = 1;\n    public static final int INSTRUMENT_METHOD_GROUP = 2;\n    public static final int INTERNAL_STATS = 3;\n    public static final int VM_PROPERTIES = 4;\n    public static final int DUMP_RESULTS = 5;\n    public static final int OBJECT_ALLOCATION_RESULTS = 6;\n    public static final int METHOD_NAMES = 7;\n    public static final int THREAD_LIVENESS_STATUS = 8;\n    public static final int MONITORED_NUMBERS = 9;\n    public static final int DEFINING_LOADER = 10;\n    public static final int CALIBRATION_DATA = 11;\n    public static final int CLASSID_RESPONSE = 12;\n    public static final int HEAP_HISTOGRAM = 13;\n    public static final int THREAD_DUMP = 14;\n    public static final int GET_CLASS_FILE_BYTES_RESPONSE = 15;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected String errorMessage;\n    protected boolean yes;\n    private int type;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public Response(boolean yes) {\n        type = NO_TYPE;\n        this.yes = yes;\n    }\n\n    public Response(String errorMessage) {\n        type = NO_TYPE;\n        this.errorMessage = errorMessage;\n    }\n\n    protected Response(boolean yes, int type) {\n        this.yes = yes;\n        this.type = type;\n    }\n\n    // Custom serialization support\n    Response() {\n        type = NO_TYPE;\n    }\n\n    Response(int type) {\n        this.type = type;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getErrorMessage() {\n        return errorMessage;\n    }\n\n    public boolean isOK() {\n        return errorMessage == null;\n    }\n\n    public int getType() {\n        return type;\n    }\n\n    // For debugging\n    public String toString() {\n        String s = respTypeToString(type);\n\n        return s + (isOK() ? (\" Ok, \" + (yes() ? \"yes\" : \"no\")) : (\" Error, \" + errorMessage)); // NOI18N\n    }\n\n    public boolean yes() {\n        return yes;\n    }\n\n    void setErrorMessage(String msg) {\n        this.errorMessage = msg;\n    }\n\n    void setType(int type) {\n        this.type = type;\n    }\n\n    void setYes(boolean yes) {\n        this.yes = yes;\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n    }\n\n    static String respTypeToString(int type) {\n        if (type != NO_TYPE) {\n            switch (type) {\n                case CODE_REGION_CPU_RESULTS:\n                    return \"CODE_REGION_CPU_RESULTS\"; // NOI18N\n                case INSTRUMENT_METHOD_GROUP:\n                    return \"INSTRUMENT_METHOD_GROUP\"; // NOI18N\n                case INTERNAL_STATS:\n                    return \"INTERNAL_STATS\"; // NOI18N\n                case VM_PROPERTIES:\n                    return \"VM_PROPERTIES\"; // NOI18N\n                case DUMP_RESULTS:\n                    return \"DUMP_RESULTS\"; // NOI18N\n                case OBJECT_ALLOCATION_RESULTS:\n                    return \"OBJECT_ALLOCATION_RESULTS\"; // NOI18N\n                case METHOD_NAMES:\n                    return \"METHOD_NAMES\"; // NOI18N\n                case THREAD_LIVENESS_STATUS:\n                    return \"THREAD_LIVENESS_STATUS\"; // NOI18N\n                case MONITORED_NUMBERS:\n                    return \"MONITORED_NUMBERS\"; // NOI18N\n                case DEFINING_LOADER:\n                    return \"DEFINING_LOADER\"; // NOI18N\n                case CALIBRATION_DATA:\n                    return \"CALIBRATION_DATA\"; // NOI18N\n                case CLASSID_RESPONSE:\n                    return \"CLASSID_RESPONSE\"; // NOI18N\n                case HEAP_HISTOGRAM:\n                    return \"HEAP_HISTOGRAM\"; // NOI18N\n                case THREAD_DUMP:\n                    return \"THREAD_DUMP\";   // NOI18N\n                case GET_CLASS_FILE_BYTES_RESPONSE:\n                    return \"GET_CLASS_FILE_BYTES_RESPONSE\";\n                default:\n                    return \"Unknown response\"; // NOI18N\n            }\n        } else {\n            return \"NO TYPE\"; // NOI18N\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/RootClassLoadedCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.util.zip.GZIPInputStream;\nimport java.util.zip.GZIPOutputStream;\n\n\n/**\n * This command is issued by the back end to signal that the root instrumentation class has been loaded.\n * It contains the information about all classes loaded by the target JVM by that time.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class RootClassLoadedCommand extends Command {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int[] allLoadedClassLoaderIds;\n    private String[] allLoadedClassNames;\n    private byte[][] cachedClassFileBytes;\n    private int[] allLoadedClassesSuper;\n    private int[][] allLoadedClassesInterfaces;\n    private int[] parentLoaderIds; // An index into this table is a loader id, and the value at this index is this loader's parent loader id.\n    private int classCount;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public RootClassLoadedCommand(String[] allLoadedClassNames, int[] loaderIds, byte[][] cachedClassFileBytes,\n                                int[] loadedClassesSuper, int[][] loadedClassesInterfaces,int classCount,\n                                int[] parentLoaderIds) {\n        super(ROOT_CLASS_LOADED);\n        this.allLoadedClassNames = allLoadedClassNames;\n        this.allLoadedClassLoaderIds = loaderIds;\n        this.cachedClassFileBytes = cachedClassFileBytes;\n        this.allLoadedClassesSuper = loadedClassesSuper;\n        this.allLoadedClassesInterfaces = loadedClassesInterfaces;\n        this.classCount = classCount;\n        this.parentLoaderIds = parentLoaderIds;\n    }\n\n    // Custom serialization support\n    RootClassLoadedCommand() {\n        super(ROOT_CLASS_LOADED);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int[] getAllLoadedClassLoaderIds() {\n        return allLoadedClassLoaderIds;\n    }\n\n    public String[] getAllLoadedClassNames() {\n        return allLoadedClassNames;\n    }\n\n    public byte[][] getCachedClassFileBytes() {\n        byte[][] res = cachedClassFileBytes;\n        cachedClassFileBytes = null; // Save memory\n\n        return res;\n    }\n\n    public int[] getAllLoaderSuperClassIds() {\n        return allLoadedClassesSuper;\n    }\n\n    public int[][] getAllLoadedInterfaceIds() {\n        return allLoadedClassesInterfaces;\n    }\n    \n    public int[] getParentLoaderIds() {\n        // Return a copy, just in case, since this instance of parentLoaderIds is reused when this command is received\n        int[] newParentLoaderIds = new int[parentLoaderIds.length];\n        System.arraycopy(parentLoaderIds, 0, newParentLoaderIds, 0, parentLoaderIds.length);\n\n        return newParentLoaderIds;\n    }\n\n    // for debugging\n    public String toString() {\n        return super.toString() + \", classes: \" + classCount;  // NOI18N\n    }\n\n    void readObject(ObjectInputStream gin) throws IOException {\n        GZIPInputStream eix = new GZIPInputStream(gin, 32768);\n        ObjectInputStream in = new ObjectInputStream(eix);\n        byte[] EMPTY = new byte[0];\n        classCount = in.readInt();\n        allLoadedClassNames = new String[classCount];\n\n        for (int i = 0; i < classCount; i++) {\n            allLoadedClassNames[i] = in.readUTF().replace('.', '/').intern();   // NOI18N\n        }\n\n        allLoadedClassLoaderIds = new int[classCount];\n\n        for (int i = 0; i < classCount; i++) {\n            allLoadedClassLoaderIds[i] = in.readInt();\n        }\n\n        int len = in.readInt();\n\n        if (len == 0) {\n            cachedClassFileBytes = null;\n        } else {\n            cachedClassFileBytes = new byte[len][];\n\n            for (int i = 0; i < len; i++) {\n                int bytesLen = in.readInt();\n\n                if (bytesLen == -1) {\n                    continue;\n                }\n                if (bytesLen == 0) {\n                   cachedClassFileBytes[i] = EMPTY;\n                   continue;\n                }\n                cachedClassFileBytes[i] = new byte[bytesLen];\n                in.readFully(cachedClassFileBytes[i]);\n            }\n        }\n\n        allLoadedClassesSuper = new int[classCount];\n        for (int i = 0; i < classCount; i++) {\n            allLoadedClassesSuper[i] = in.readInt();\n        }\n\n        allLoadedClassesInterfaces = new int[classCount][];\n        for (int i = 0; i < classCount; i++) {\n            int ilen = in.readInt();\n            allLoadedClassesInterfaces[i] = new int[ilen];\n            for (int j = 0; j < ilen; j++) {\n                allLoadedClassesInterfaces[i][j] = in.readInt();\n            }\n        }\n        \n        len = in.readInt();\n        parentLoaderIds = new int[len];\n\n        for (int i = 0; i < len; i++) {\n            parentLoaderIds[i] = in.readInt();\n        }\n        int eof = in.read();\n        if (eof != -1) throw new IOException(\"RootClassLoadedCommand EOF not found, read:\"+eof);\n        boolean failed = false;\n        for (int i = 21; i<127; i+=7) {\n            int inb = gin.read();\n            if (inb != i) {\n                failed = true;\n                if (WireIO.DEBUG) System.out.print(i+\"=\"+inb+\"; \");\n                if (inb%7 == 0) {\n                    i = inb;\n                }\n            }\n        }\n        if (WireIO.DEBUG && failed) System.out.println(\"RootClassLoadedCommand fixed.\");\n    }\n\n    void writeObject(ObjectOutputStream gout) throws IOException {\n        GZIPOutputStream eox = new GZIPOutputStream(gout, 32768);\n        ObjectOutputStream out = new ObjectOutputStream(eox);\n        out.writeInt(classCount);\n\n        for (int i = 0; i < classCount; i++) {\n            out.writeUTF(allLoadedClassNames[i]);\n        }\n\n        for (int i = 0; i < classCount; i++) {\n            int loaderId = allLoadedClassLoaderIds[i];\n\n            // At the client side we treat classes loaded by the bootstrap and by the system classloaders in the same way\n            if (loaderId == -1) {\n                loaderId = 0;\n            }\n\n            out.writeInt(loaderId);\n        }\n\n        if (cachedClassFileBytes == null) {\n            out.writeInt(0);\n        } else {\n            out.writeInt(classCount);\n\n            for (int i = 0; i < classCount; i++) {\n                if (cachedClassFileBytes[i] == null) {\n                    out.writeInt(-1);\n                } else {\n                    out.writeInt(cachedClassFileBytes[i].length);\n                    if (cachedClassFileBytes[i].length > 0) {\n                        out.write(cachedClassFileBytes[i]);\n                    }\n                }\n            }\n        }\n\n        for (int i = 0; i < classCount; i++) {\n            out.writeInt(allLoadedClassesSuper[i]);\n        }\n\n        for (int i = 0; i < classCount; i++) {\n            int[] ifacesIds = allLoadedClassesInterfaces[i];\n            if (ifacesIds != null) {\n                out.writeInt(ifacesIds.length);\n                for (int j = 0; j < ifacesIds.length; j++) {\n                    out.writeInt(ifacesIds[j]);\n                }\n            } else {\n                out.writeInt(0);\n            } \n        }\n        \n        out.writeInt(parentLoaderIds.length);\n\n        for (int i = 0; i < parentLoaderIds.length; i++) {\n            out.writeInt(parentLoaderIds[i]);\n        }\n        out.flush();\n        eox.finish();\n        gout.flush();\n        for (int i = 7; i<127; i+=7) gout.write(i);\n\n        // Free memory\n        allLoadedClassNames = null;\n        allLoadedClassLoaderIds = null;\n        cachedClassFileBytes = null;\n        allLoadedClassesSuper = null;\n        allLoadedClassesInterfaces = null;\n        parentLoaderIds = null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/SetChangeableInstrParamsCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * This command, sent by the client, contains the instrumentation parameters (settings) that\n * can be changed once instrumentation is active and profiling is going on.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Tomas Hurka\n */\npublic class SetChangeableInstrParamsCommand extends Command {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private boolean runGCOnGetResultsInMemoryProfiling;\n    private boolean sleepTrackingEnabled;\n    private boolean waitTrackingEnabled;\n    private boolean threadsSamplingEnabled;\n    private boolean lockContentionMonitoringEnabled;\n    private int nProfiledThreadsLimit;\n    private int maxStringLength;\n    private int stackDepthLimit;\n    private int objAllocStackSamplingDepth;\n    private int objAllocStackSamplingInterval;\n    private int samplingInterval;\n    private int threadsSamplingFrequency;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SetChangeableInstrParamsCommand(boolean lockContentionMonitoringEnabled, int nProfiledThreadsLimit,\n                                           int maxStringLength, int stackDepthLimit,\n                                           int samplingInterval, int objAllocStackSamplingInterval,\n                                           int objAllocStackSamplingDepth, boolean runGCOnGetResults,\n                                           boolean waitTrackingEnabled, boolean sleepTrackingEnabled,\n                                           boolean threadsSamplingEnabled, int threadsSamplingFrequency) {\n        super(SET_CHANGEABLE_INSTR_PARAMS);\n        this.lockContentionMonitoringEnabled = lockContentionMonitoringEnabled;\n        this.nProfiledThreadsLimit = nProfiledThreadsLimit;\n        this.maxStringLength = maxStringLength;\n        this.stackDepthLimit = stackDepthLimit;\n        this.samplingInterval = samplingInterval;\n        this.threadsSamplingFrequency = threadsSamplingFrequency;\n        this.objAllocStackSamplingInterval = objAllocStackSamplingInterval;\n        this.objAllocStackSamplingDepth = objAllocStackSamplingDepth;\n        this.runGCOnGetResultsInMemoryProfiling = runGCOnGetResults;\n        this.waitTrackingEnabled = waitTrackingEnabled;\n        this.sleepTrackingEnabled = sleepTrackingEnabled;\n        this.threadsSamplingEnabled = threadsSamplingEnabled;\n    }\n\n    // Custom serialization support\n    SetChangeableInstrParamsCommand() {\n        super(SET_CHANGEABLE_INSTR_PARAMS);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public boolean isLockContentionMonitoringEnabled() {\n        return lockContentionMonitoringEnabled;\n    }\n\n    public int getNProfiledThreadsLimit() {\n        return nProfiledThreadsLimit;\n    }\n\n    public int getMaxStringLength() {\n        return maxStringLength;\n    }\n\n    public int getStackDepthLimit() {\n        return stackDepthLimit;\n    }\n\n    public int getObjAllocStackSamplingDepth() {\n        return objAllocStackSamplingDepth;\n    }\n\n    public int getObjAllocStackSamplingInterval() {\n        return objAllocStackSamplingInterval;\n    }\n\n    public boolean getRunGCOnGetResultsInMemoryProfiling() {\n        return runGCOnGetResultsInMemoryProfiling;\n    }\n\n    public int getSamplingInterval() {\n        return samplingInterval;\n    }\n\n    public int getThreadsSamplingFrequency() {\n        return threadsSamplingFrequency;\n    }\n\n    public boolean isSleepTrackingEnabled() {\n        return sleepTrackingEnabled;\n    }\n\n    public boolean isWaitTrackingEnabled() {\n        return waitTrackingEnabled;\n    }\n\n    public boolean isThreadsSamplingEnabled() {\n        return threadsSamplingEnabled;\n    }\n\n    // For debugging\n    public String toString() {\n        return super.toString() + \", lockContentionMonitoringEnabled: \" + lockContentionMonitoringEnabled // NOI18N\n               + \", nProfiledThreadsLimit: \" + nProfiledThreadsLimit // NOI18N\n               + \", maxStringLength: \" + maxStringLength // NOI18N\n               + \", stackDepthLimit: \" + stackDepthLimit // NOI18N\n               + \", samplingInterval: \" + samplingInterval // NOI18N\n               + \", objAllocStackSamplingInterval: \" + objAllocStackSamplingInterval // NOI18N\n               + \", objAllocStackSamplingDepth: \" + objAllocStackSamplingDepth // NOI18N\n               + \", runGCOnGetResultsInMemoryProfiling: \" + runGCOnGetResultsInMemoryProfiling // NOI18N\n               + \", waitTrackingEnabled: \" + waitTrackingEnabled // NOI18N\n               + \", sleepTrackingEnabled: \" + sleepTrackingEnabled // NOI18N\n               + \", threadsSamplingEnabled: \" + threadsSamplingEnabled // NOI18N\n               + \", threadsSamplingFrequency: \" + threadsSamplingFrequency; // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        lockContentionMonitoringEnabled = in.readBoolean();\n        nProfiledThreadsLimit = in.readInt();\n        maxStringLength = in.readInt();\n        stackDepthLimit = in.readInt();\n        samplingInterval = in.readInt();\n        objAllocStackSamplingInterval = in.readInt();\n        objAllocStackSamplingDepth = in.readInt();\n        runGCOnGetResultsInMemoryProfiling = in.readBoolean();\n        waitTrackingEnabled = in.readBoolean();\n        sleepTrackingEnabled = in.readBoolean();\n        threadsSamplingEnabled = in.readBoolean();\n        threadsSamplingFrequency = in.readInt();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeBoolean(lockContentionMonitoringEnabled);\n        out.writeInt(nProfiledThreadsLimit);\n        out.writeInt(maxStringLength);\n        out.writeInt(stackDepthLimit);\n        out.writeInt(samplingInterval);\n        out.writeInt(objAllocStackSamplingInterval);\n        out.writeInt(objAllocStackSamplingDepth);\n        out.writeBoolean(runGCOnGetResultsInMemoryProfiling);\n        out.writeBoolean(waitTrackingEnabled);\n        out.writeBoolean(sleepTrackingEnabled);\n        out.writeBoolean(threadsSamplingEnabled);\n        out.writeInt(threadsSamplingFrequency);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/SetUnchangeableInstrParamsCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * This command, sent by the client, contains the instrumentation parameters (settings),\n * that cannot be modified once instrumentation is active and profiling is going on.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class SetUnchangeableInstrParamsCommand extends Command {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private boolean remoteProfiling;\n    private boolean absoluteTimerOn;\n    private boolean threadCPUTimerOn;\n    private int codeRegionCPUResBufSize;\n    private int instrScheme;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SetUnchangeableInstrParamsCommand(boolean remote, boolean absoluteTimerOn, boolean threadCPUTimerOn, int instrScheme,\n                                             int codeRegionCPUResBufSize) {\n        super(SET_UNCHANGEABLE_INSTR_PARAMS);\n        remoteProfiling = remote;\n        this.absoluteTimerOn = absoluteTimerOn;\n        this.threadCPUTimerOn = threadCPUTimerOn;\n        this.instrScheme = instrScheme;\n        this.codeRegionCPUResBufSize = codeRegionCPUResBufSize;\n    }\n\n    // Custom serialization support\n    SetUnchangeableInstrParamsCommand() {\n        super(SET_UNCHANGEABLE_INSTR_PARAMS);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public boolean getRemoteProfiling() {\n        return remoteProfiling;\n    }\n\n    public boolean getAbsoluteTimerOn() {\n        return absoluteTimerOn;\n    }\n\n    public int getCodeRegionCPUResBufSize() {\n        return codeRegionCPUResBufSize;\n    }\n\n    public int getInstrScheme() {\n        return instrScheme;\n    }\n\n    public boolean getThreadCPUTimerOn() {\n        return threadCPUTimerOn;\n    }\n\n    // For debugging\n    public String toString() {\n        return super.toString() + \", remoteProfiling: \" + remoteProfiling // NOI18N\n               + \", absoluteTimerOn: \" + absoluteTimerOn // NOI18N\n               + \", threadCPUTimerOn: \" + threadCPUTimerOn // NOI18N\n               + \", instrScheme: \" + instrScheme // NOI18N\n               + \", codeRegionCPUResBufSize: \" + codeRegionCPUResBufSize; // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        remoteProfiling = in.readBoolean();\n        absoluteTimerOn = in.readBoolean();\n        threadCPUTimerOn = in.readBoolean();\n        instrScheme = in.readInt();\n        codeRegionCPUResBufSize = in.readInt();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeBoolean(remoteProfiling);\n        out.writeBoolean(absoluteTimerOn);\n        out.writeBoolean(threadCPUTimerOn);\n        out.writeInt(instrScheme);\n        out.writeInt(codeRegionCPUResBufSize);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/TakeHeapDumpCommand.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * This command sent by client is the request to the TA to take a heap dump\n * @author Tomas Hurka\n */\npublic class TakeHeapDumpCommand extends Command {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private String outputFile; //Dumps the heap to the outputFile file\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public TakeHeapDumpCommand(String name) {\n        super(TAKE_HEAP_DUMP);\n        outputFile = name;\n    }\n\n    // Custom serialization support\n    TakeHeapDumpCommand() {\n        super(TAKE_HEAP_DUMP);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getOutputFile() {\n        return outputFile;\n    }\n\n    // For debugging\n    public String toString() {\n        return super.toString() + \", outputFile: \" + outputFile; // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        outputFile = in.readUTF();\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeUTF(outputFile);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/ThreadDumpResponse.java",
    "content": "/*\n * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.util.Date;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class ThreadDumpResponse extends Response {\n\n    private boolean jdk15;\n    private Date time;\n    Object[] cdThreads;\n\n    public ThreadDumpResponse(boolean j15, Date d, Object[] td) {\n        super(true, THREAD_DUMP);\n        jdk15 = j15;\n        time = d;\n        if (td == null) td = new Object[0];\n        cdThreads = td;\n    }\n\n    // Custom serialization support\n    ThreadDumpResponse() {\n        super(true, THREAD_DUMP);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public boolean isJDK15() {\n        return jdk15;\n    }\n\n    public Date getTime() {\n        return time;\n    }\n\n    public Object[] getThreads() {\n        return cdThreads;\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        jdk15 = in.readBoolean();\n        long t = in.readLong();\n        time = new Date(t);\n        int len = in.readInt();\n        cdThreads = new Object[len];\n        for (int i = 0; i < len; i++) {\n            try {\n                cdThreads[i] = in.readObject();\n            } catch (ClassNotFoundException ex) {\n                throw new IOException(ex);\n            }\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeBoolean(jdk15);\n        out.writeLong(time.getTime());\n        out.writeInt(cdThreads.length);\n        for (int i = 0; i < cdThreads.length; i++) {\n            out.writeObject(cdThreads[i]);\n        }\n        time = null;\n        cdThreads = null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/ThreadLivenessStatusResponse.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * This Response, issued by the back end, contains the current information about the live/dead status for tracked threads.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class ThreadLivenessStatusResponse extends Response {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private byte[] status;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ThreadLivenessStatusResponse(byte[] status) {\n        super(true, THREAD_LIVENESS_STATUS);\n        this.status = status;\n    }\n\n    // Custom serialization support\n    ThreadLivenessStatusResponse() {\n        super(true, THREAD_LIVENESS_STATUS);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public byte[] getStatus() {\n        return status;\n    }\n\n    // For debugging\n    public String toString() {\n        return \"ThreadLivenessStatusResponse, \" + super.toString(); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        int len = in.readInt();\n        status = new byte[len];\n        in.readFully(status);\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(status.length);\n        out.write(status);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/VMPropertiesResponse.java",
    "content": "/*\n * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * This response is generated by the back end and contains the  VM properties such as various class paths.\n *\n * @author Tomas Hurka\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class VMPropertiesResponse extends Response {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private String bootClassPath;\n    private String javaClassPath;\n    private String javaCommand;\n    private String javaExtDirs;\n    private String jdkVersionString;\n    private String jvmArguments;\n    private String targetMachineOSName;\n    private String workingDir;\n    private boolean canInstrumentConstructor;\n    private int agentId;\n    private int agentVersion;\n    private long maxHeapSize;\n    private long startupTimeInCounts;\n    private long startupTimeMillis;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public VMPropertiesResponse(String jdkVerString, String javaClassPath, String javaExtDirs, String bootClassPath,\n                                String workingDir, String jvmArguments, String javaCommand, String targetMachineOSName,\n                                boolean canInstrumentConstructor, long maxHeapSize, long startupTimeMillis,\n                                long startupTimeInCounts, int agentId) {\n        super(true, VM_PROPERTIES);\n        this.jdkVersionString = jdkVerString;\n        this.javaClassPath = javaClassPath;\n        this.javaExtDirs = javaExtDirs;\n        this.bootClassPath = bootClassPath;\n        this.workingDir = workingDir;\n        this.jvmArguments = (jvmArguments != null) ? jvmArguments : \"\"; // NOI18N\n        this.javaCommand = (javaCommand != null) ? javaCommand : \"\"; // NOI18N\n        this.targetMachineOSName = targetMachineOSName;\n        this.canInstrumentConstructor = canInstrumentConstructor;\n        this.maxHeapSize = maxHeapSize;\n        this.startupTimeMillis = startupTimeMillis;\n        this.startupTimeInCounts = startupTimeInCounts & 0xFFFFFFFFFFFFFFL; // we use only 7 bytes for hi res timer\n        this.agentId = agentId;\n        this.agentVersion = CommonConstants.CURRENT_AGENT_VERSION;\n    }\n\n    // Custom serialization support\n    VMPropertiesResponse() {\n        super(true, VM_PROPERTIES);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getAgentId() {\n        return agentId;\n    }\n\n    public int getAgentVersion() {\n        return agentVersion;\n    }\n\n    public String getBootClassPath() {\n        return bootClassPath;\n    }\n\n    public String getJDKVersionString() {\n        return jdkVersionString;\n    }\n\n    public String getJVMArguments() {\n        return jvmArguments;\n    }\n\n    public String getJavaClassPath() {\n        return javaClassPath;\n    }\n\n    public String getJavaCommand() {\n        return javaCommand;\n    }\n\n    public String getJavaExtDirs() {\n        return javaExtDirs;\n    }\n\n    public boolean canInstrumentConstructor() {\n        return canInstrumentConstructor;\n    }\n\n    public long getMaxHeapSize() {\n        return maxHeapSize;\n    }\n\n    public long getStartupTimeInCounts() {\n        return startupTimeInCounts;\n    }\n\n    public long getStartupTimeMillis() {\n        return startupTimeMillis;\n    }\n\n    public String getTargetMachineOSName() {\n        return targetMachineOSName;\n    }\n\n    public String getWorkingDir() {\n        return workingDir;\n    }\n\n    // For debugging\n    public String toString() {\n        return \"VMPropertiesResponse:\" // NOI18N\n               + \"\\n  jdkVersionString: \" + jdkVersionString // NOI18N\n               + \"\\n  javaClassPath: \" + javaClassPath // NOI18N\n               + \"\\n  javaExtDirs: \" + javaExtDirs // NOI18N\n               + \"\\n  bootClassPath: \" + bootClassPath // NOI18N\n               + \"\\n  workingDir: \" + workingDir // NOI18N\n               + \"\\n  jvmArguments: \" + jvmArguments // NOI18N\n               + \"\\n  javaCommand: \" + javaCommand // NOI18N\n               + \"\\n  targetMachineOSName: \" + targetMachineOSName // NOI18N\n               + \"\\n  canInstrumentConstructor: \" + canInstrumentConstructor // NOI18N\n               + \"\\n  maxHeapSize: \" + maxHeapSize // NOI18N\n               + \"\\n  startupTimeMillis: \" + startupTimeMillis // NOI18N\n               + \"\\n  startupTimeInCounts: \" + startupTimeInCounts // NOI18N\n               + \"\\n  agentId: \" + agentId // NOI18N\n               + \"\\n  agentVersion: \" + agentVersion // NOI18N\n               + \"\\n\" + super.toString(); // NOI18N\n    }\n\n    void readObject(ObjectInputStream in) throws IOException {\n        try {\n            agentVersion = in.readInt();\n            jdkVersionString = in.readUTF();\n            javaClassPath = (String) in.readObject();\n            javaExtDirs = in.readUTF();\n            bootClassPath = in.readUTF();\n            workingDir = in.readUTF();\n            jvmArguments = in.readUTF();\n            javaCommand = in.readUTF();\n            targetMachineOSName = in.readUTF();\n            canInstrumentConstructor = in.readBoolean();\n            maxHeapSize = in.readLong();\n            startupTimeMillis = in.readLong();\n            startupTimeInCounts = in.readLong();\n            agentId = in.readInt();\n        } catch (ClassNotFoundException ex) {\n            throw new IOException(ex);\n        }\n    }\n\n    void writeObject(ObjectOutputStream out) throws IOException {\n        out.writeInt(agentVersion);\n        out.writeUTF(jdkVersionString);\n        out.writeObject(javaClassPath);\n        out.writeUTF(javaExtDirs);\n        out.writeUTF(bootClassPath);\n        out.writeUTF(workingDir);\n        out.writeUTF(jvmArguments);\n        out.writeUTF(javaCommand);\n        out.writeUTF(targetMachineOSName);\n        out.writeBoolean(canInstrumentConstructor);\n        out.writeLong(maxHeapSize);\n        out.writeLong(startupTimeMillis);\n        out.writeLong(startupTimeInCounts);\n        out.writeInt(agentId);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/wireprotocol/WireIO.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.wireprotocol;\n\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\n\n\n/**\n * Implementation of our custom serialization. We use our own, specialized, simplified and optimized flavor of\n * object serialization, to improve performance and avoid various things that standard serialization performs\n * behind the scenes, such as loading of many classes, generating some classes on-the-fly, and so on. These\n * actions can cause various undesirable side effects when used for such a sensitive thing as profiling.\n * However, this kind of serialization is not completely automatic, and some manual changes in this class are\n * required every time a new Command or Response subclass is created. Read the comments in this file to see\n * where the changes should be made.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n */\npublic class WireIO {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static final boolean DEBUG = System.getProperty(\"org.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO\") != null; // NOI18N\n    private static final int IS_SIMPLE_COMMAND = 1;\n    private static final int IS_COMPLEX_COMMAND = 2;\n    private static final int IS_SIMPLE_RESPONSE = 3;\n    private static final int IS_COMPLEX_RESPONSE = 4;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ObjectInputStream in;\n    private ObjectOutputStream out;\n    private long wasAlive;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public WireIO(ObjectOutputStream pout, ObjectInputStream pin) {\n        out = pout;\n        in = pin;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Object receiveCommandOrResponse() throws IOException {\n        int code = in.read();\n\n        /*if (code == -1) {\n           if (DEBUG) System.out.println(\"WireIO.DEBUG: received end of stream code\");\n           return null; // end of stream, no more data\n           }*/\n        wasAlive = System.currentTimeMillis();\n        switch (code) {\n            case IS_SIMPLE_COMMAND:\n\n                Command c = new Command(in.read());\n\n                if (DEBUG) {\n                    System.out.println(\"WireIO.DEBUG: received simple command: \" + c); // NOI18N\n                }\n\n                return c;\n            case IS_COMPLEX_COMMAND: {\n                int cmdType = in.read();\n\n                if (DEBUG) {\n                    System.out.println(\"WireIO.DEBUG: received complex command type: \" // NOI18N\n                                       + Command.cmdTypeToString(cmdType));\n                }\n\n                Command cmd = null;\n\n                switch (cmdType) {\n                    case Command.METHOD_INVOKED_FIRST_TIME:\n                        cmd = new MethodInvokedFirstTimeCommand();\n\n                        break;\n                    case Command.CLASS_LOADED:\n                        cmd = new ClassLoadedCommand();\n\n                        break;\n                    case Command.MESSAGE:\n                        cmd = new AsyncMessageCommand();\n\n                        break;\n                    case Command.METHOD_LOADED:\n                        cmd = new MethodLoadedCommand();\n\n                        break;\n                    case Command.ROOT_CLASS_LOADED:\n                        cmd = new RootClassLoadedCommand();\n\n                        break;\n                    case Command.INITIATE_PROFILING:\n                        cmd = new InitiateProfilingCommand();\n\n                        break;\n                    case Command.SET_CHANGEABLE_INSTR_PARAMS:\n                        cmd = new SetChangeableInstrParamsCommand();\n\n                        break;\n                    case Command.SET_UNCHANGEABLE_INSTR_PARAMS:\n                        cmd = new SetUnchangeableInstrParamsCommand();\n\n                        break;\n                    case Command.EVENT_BUFFER_DUMPED:\n                        cmd = new EventBufferDumpedCommand();\n\n                        break;\n                    case Command.INSTRUMENT_METHOD_GROUP:\n                        cmd = new InstrumentMethodGroupCommand();\n\n                        break;\n                    case Command.GET_METHOD_NAMES_FOR_JMETHOD_IDS:\n                        cmd = new GetMethodNamesForJMethodIdsCommand();\n\n                        break;\n                    case Command.GET_DEFINING_CLASS_LOADER:\n                        cmd = new GetDefiningClassLoaderCommand();\n\n                        break;\n                    case Command.TAKE_HEAP_DUMP:\n                        cmd = new TakeHeapDumpCommand();\n\n                        break;\n                    case Command.GET_CLASSID:\n                        cmd = new GetClassIdCommand();\n\n                        break;\n                    case Command.GET_CLASS_FILE_BYTES:\n                        cmd = new GetClassFileBytesCommand();\n\n                        break;                        \n                    default:\n                        throw new IOException(\"JFluid wire protocol error: received unknown command type. Value: \" // NOI18N\n                                              + cmdType);\n                }\n\n                cmd.readObject(in);\n\n                if (DEBUG) {\n                    System.out.println(\"WireIO.DEBUG:         command is: \" + cmd); // NOI18N\n                }\n\n                return cmd;\n            }\n            case IS_SIMPLE_RESPONSE:\n\n                Response simpleResp = new Response(in.readBoolean());\n\n                if (in.read() != 0) {\n                    simpleResp.setErrorMessage(in.readUTF());\n                } else {\n                    simpleResp.setErrorMessage(null);\n                }\n\n                if (DEBUG) {\n                    System.out.println(\"WireIO.DEBUG: received simple response \" + simpleResp); // NOI18N\n                }\n\n                return simpleResp;\n            case IS_COMPLEX_RESPONSE:\n\n                int respType = in.read();\n\n                if (DEBUG) {\n                    System.out.println(\"WireIO.DEBUG: received complex response \" // NOI18N\n                                       + Response.respTypeToString(respType));\n                }\n\n                Response resp = null;\n\n                switch (respType) {\n                    case Response.CODE_REGION_CPU_RESULTS:\n                        resp = new CodeRegionCPUResultsResponse();\n\n                        break;\n                    case Response.INSTRUMENT_METHOD_GROUP:\n                        resp = new InstrumentMethodGroupResponse();\n\n                        break;\n                    case Response.INTERNAL_STATS:\n                        resp = new InternalStatsResponse();\n\n                        break;\n                    case Response.VM_PROPERTIES:\n                        resp = new VMPropertiesResponse();\n\n                        break;\n                    case Response.DUMP_RESULTS:\n                        resp = new DumpResultsResponse();\n\n                        break;\n                    case Response.OBJECT_ALLOCATION_RESULTS:\n                        resp = new ObjectAllocationResultsResponse();\n\n                        break;\n                    case Response.METHOD_NAMES:\n                        resp = new MethodNamesResponse();\n\n                        break;\n                    case Response.THREAD_LIVENESS_STATUS:\n                        resp = new ThreadLivenessStatusResponse();\n\n                        break;\n                    case Response.MONITORED_NUMBERS:\n                        resp = new MonitoredNumbersResponse();\n\n                        break;\n                    case Response.DEFINING_LOADER:\n                        resp = new DefiningLoaderResponse();\n\n                        break;\n                    case Response.CALIBRATION_DATA:\n                        resp = new CalibrationDataResponse();\n\n                        break;\n                    case Response.CLASSID_RESPONSE:\n                        resp = new GetClassIdResponse();\n\n                        break;\n                    case Response.HEAP_HISTOGRAM:\n                        resp = new HeapHistogramResponse();\n                        \n                        break;\n                    case Response.THREAD_DUMP:\n                        resp = new ThreadDumpResponse();\n                        \n                        break;\n                    case Response.GET_CLASS_FILE_BYTES_RESPONSE:\n                        resp = new GetClassFileBytesResponse();\n                        \n                        break;\n                    default:\n                        throw new IOException(\"JFluid wire protocol error: received unknown response type. Value: \" + respType); // NOI18N\n                }\n\n                resp.setYes(in.readBoolean());\n\n                if (in.read() != 0) {\n                    resp.setErrorMessage(in.readUTF());\n                } else {\n                    resp.setErrorMessage(null);\n                }\n\n                resp.readObject(in);\n\n                if (DEBUG) {\n                    System.out.println(\"WireIO.DEBUG:    response is: \" + resp); // NOI18N\n                }\n\n                return resp;\n            default:\n\n                if (DEBUG) {\n                    System.out.println(\"WireIO.DEBUG: received unknown code: \" + code); // NOI18N\n                }\n\n                throw new IOException(\"JFluid wire protocol error: code does not correspond to command or response. Value \" + code); // NOI18N\n        }\n    }\n\n    public synchronized void sendComplexCommand(Command cmd)\n                                         throws IOException {\n        if (DEBUG) {\n            System.out.println(\"WireIO.DEBUG: gonna send complex command: \" + cmd); // NOI18N\n        }\n\n        out.write(IS_COMPLEX_COMMAND);\n        out.write(cmd.getType());\n        cmd.writeObject(out);\n        out.flush();\n    }\n\n    public synchronized void sendComplexResponse(Response resp)\n                                          throws IOException {\n        if (DEBUG) {\n            System.out.println(\"WireIO.DEBUG: gonna send response: \" + resp); // NOI18N\n        }\n\n        out.write(IS_COMPLEX_RESPONSE);\n        out.write(resp.getType());\n        out.writeBoolean(resp.yes());\n\n        String errorMessage = resp.getErrorMessage();\n\n        if (errorMessage == null) {\n            out.write(0);\n        } else {\n            out.write(1);\n            out.writeUTF(errorMessage);\n        }\n\n        resp.writeObject(out);\n        out.flush();\n    }\n\n    public synchronized void sendSimpleCommand(int cmdType)\n                                        throws IOException {\n        if (DEBUG) {\n            System.out.println(\"WireIO.DEBUG: gonna send simple command:\" + Command.cmdTypeToString(cmdType)); // NOI18N\n        }\n\n        out.write(IS_SIMPLE_COMMAND);\n        out.write(cmdType);\n        out.flush();\n    }\n\n    public synchronized void sendSimpleResponse(boolean yes, String errorMessage)\n                                         throws IOException {\n        if (DEBUG) {\n            System.out.println(\"WireIO.DEBUG: gonna send simple response: yes: \" + yes // NOI18N\n                               + \", errorMessage: \" + errorMessage // NOI18N\n                               );\n        }\n\n        out.write(IS_SIMPLE_RESPONSE);\n        out.writeBoolean(yes);\n\n        if (errorMessage == null) {\n            out.write(0);\n        } else {\n            out.write(1);\n            out.writeUTF(errorMessage);\n        }\n\n        out.flush();\n    }\n\n    public long wasAlive() {\n        return wasAlive;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-cvm/manifest.mf",
    "content": "Boot-Class-Path: jfluid-server.jar jfluid-server-15.jar\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-cvm/org/graalvm/visualvm/lib/jfluid/server/system/Classes.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\n\n/**\n * Provides methods for dynamic bytecode redefinition and other class-related operations.\n * A version for CVM\n *\n * @author Tomas Hurka\n * @author  Misha Dmitriev\n */\npublic class Classes {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    /** We convert all error codes or exceptions thrown by redefine calls into a single error message in\n     * this exception\n     */\n    public static class RedefineException extends Exception {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public RedefineException(String msg) {\n            super(msg);\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns all currently loaded *and linked* classes.\n     * On CVM, it returns just a Class[] array of all loaded classes\n     */\n    public static native Class[] getAllLoadedClasses();\n\n    /**\n     * Returns the cached class file bytes for the given class. Currently\n     * agent caches these bytes only for classes loaded with custom classloaders (that is, not\n     * bootstrap (null) and not system classloader). If this method is called for a class loaded using bootstrap or\n     * system classloader, it just returns null.\n     */\n    public static native byte[] getCachedClassFileBytes(Class clazz);\n\n    public static int getLoadedClassCount() {\n        return getAllLoadedClasses().length;\n    }\n\n    /** Object size for a given object */\n    public static native long getObjectSize(Object obj);\n\n    public static native boolean setSleepTrackingEnabled(boolean value);\n\n    public static native boolean setVMObjectAllocEnabled(boolean value);\n\n    public static native boolean setWaitTrackingEnabled(boolean value);\n\n    public static native boolean setParkTrackingEnabled(boolean value);\n\n    public static native void cacheLoadedClasses(Class[] nonSystemClasses, int nonSystemIndex);\n\n    /** Disables the above class load hook */\n    public static native void disableClassLoadHook();\n\n    /**\n     * When the class load hook is enabled, it will call the ProfilerInterface.classLoadHook(Class) method every time\n     * a class is load and prepared.\n     */\n    public static native void enableClassLoadHook();\n\n    /** Should be called at earliest possible time */\n    public static void initialize() {\n    }\n\n    /**\n     * This notifies the underlying native code about the fact that some classloader (we don't know which one since\n     * we use PhantomReferences for them) is unloaded. Thus the native code that could have cached the class file\n     * bytes for classes loaded with this loader, may release these bytes now. Really needed only in 1.5.\n     */\n    public static native void notifyAboutClassLoaderUnloading();\n\n    /** RedefineClasses() as provided in CVM  */\n    public static void redefineClasses(Class[] classes, byte[][] newClassFileBytes)\n                                throws RedefineException {\n        if (classes.length > newClassFileBytes.length) {\n            throw new RedefineException(\"Inconsistent input data: classes.length = \" + classes.length // NOI18N\n                                        + \", newClassFileBytes.length = \" + newClassFileBytes.length); // NOI18N\n        }\n\n        for (int i = 0; i < classes.length; i++) {\n            if (classes[i] == null) {\n                throw new RedefineException(\"null input data: classes at \" + i); // NOI18N\n            }\n\n            if (newClassFileBytes[i] == null) {\n                throw new RedefineException(\"null input data: newClassFileBytes at \" + i + \" for class \"+classes[i].getName()); // NOI18N\n            }\n        }\n\n        int res = doRedefineClasses(classes, newClassFileBytes);\n\n        if (res != 0) {\n            throw new RedefineException(\"Redefinition failed with error \" + res + \"\\n\" // NOI18N\n                                        + \"Check JVMTI documentation for this error code.\"); // NOI18N\n        }\n    }\n\n    // ======================================== CVM specific code ===============================================\n    private static native int doRedefineClasses(Class[] classes, byte[][] newClassFileBytes);\n\n    private static RedefineException newRedefineException(String msg, Throwable origCause) {\n        msg = \"Class redefinition error: \" + msg + \"\\nOriginal exception:\\n\" + origCause; // NOI18N\n\n        return new RedefineException(msg);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-cvm/org/graalvm/visualvm/lib/jfluid/server/system/HeapDump.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class HeapDump {\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private HeapDump() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void initialize(boolean jdk15) {\n    }\n\n    public static String takeHeapDump(String outputFile) {\n        return takeHeapDumpCVM(outputFile);\n    }\n\n\n    private static String takeHeapDumpCVM(String outputFile) {\n        return \"Take heap dump is not available.\"; // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-cvm/org/graalvm/visualvm/lib/jfluid/server/system/Histogram.java",
    "content": "/*\n * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\nimport java.io.InputStream;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class Histogram {\n\n    public static boolean isAvailable() {\n        return false;\n    }\n\n    public static boolean initialize(boolean jdk9) {\n        return false;\n    }\n\n    public static InputStream getRawHistogram() {\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-cvm/org/graalvm/visualvm/lib/jfluid/server/system/ThreadDump.java",
    "content": "/*\n * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class ThreadDump {\n\n    public static void initialize(boolean jdk15) {\n    }\n\n    public static Object[] takeThreadDump() {\n        return null;\n    }\n\n    public static boolean isJDK15() {\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-cvm/org/graalvm/visualvm/lib/jfluid/server/system/Timers.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\n/**\n * Provides methods for obtaining various high-resolution system times. A\n * version for CVM\n *\n * @author Misha Dmitriev\n */\npublic class Timers {\n\n    /**\n     * Should be called at earliest possible time\n     */\n    public static void initialize() {\n        getThreadCPUTimeInNanos();\n    }\n\n\n    /**\n     * \"counts\" instead of nanoseconds in this method are for compatibility with\n     * the previous versions of JFluid, that call a native method for system\n     * timer, which, in turn, returns the result in sub-microsecond \"counts\" on\n     * Windows.\n     */\n    public static native long getCurrentTimeInCounts();\n\n    public static long getNoOfCountsInSecond() {\n        return 1000000000;\n    }\n\n\n    public static native long getThreadCPUTimeInNanos();\n\n    /**\n     * Returns the approximate accumulated process CPU elapsed time in\n     * nanoseconds. Note that the time is normalized to one processor.\n     * This method returns <tt>-1</tt> if the collection elapsed\n     * time is undefined for this collector.\n     *\n     * @return the approximate accumulated process CPU elapsed time in\n     * nanoseconds.\n     */\n    public static long getProcessCpuTime() {\n        return -1;\n    }\n\n    /**\n     * WORKS ONLY ON UNIX, calls nanosleep(). On Solaris, this is more precise\n     * than the built-in Thread.sleep() call implementation that, at least in\n     * JDK 1.4.2, goes to select(3C). On Linux, it should be more precise, but\n     * it turns out that nanosleep() in this OS, at least in version 7.3 that I\n     * tested, has a resolution of at least 20ms. This seems to be a known\n     * issue; hopefully they fix it in future.\n     */\n    public static native void osSleep(int ns);\n\n\n    /**\n     * This is relevant only on Solaris. By default, the resolution of the\n     * thread local CPU timer is 10 ms. If we enable micro state accounting, it\n     * enables significantly (but possibly at a price of some overhead). So I\n     * turn it on only when thread CPU timestamps are really collected.\n     */\n    public static native void enableMicrostateAccounting(boolean v);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-jdk15/manifest.mf",
    "content": "Premain-Class: org.graalvm.visualvm.lib.jfluid.server.ProfilerActivate15\nAgent-Class: org.graalvm.visualvm.lib.jfluid.server.ProfilerActivate15\nCan-Redefine-Classes: true\nBoot-Class-Path: jfluid-server.jar jfluid-server-15.jar\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-jdk15/org/graalvm/visualvm/lib/jfluid/server/ProfilerActivate15.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server;\n\nimport java.io.File;\nimport java.lang.instrument.Instrumentation;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.net.URL;\n\n\n/**\n * Class that contains the premain() method, needed by the java.lang.instrument Java agent\n * mechanism, that we use for \"attach on startup\" operation with JDK 1.5.\n *\n * @author Tomas Hurka\n * @author  Misha Dmitriev\n */\npublic class ProfilerActivate15 {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void agentmain(final String agentArgs, final Instrumentation inst) {\n        activate(agentArgs, inst, ProfilerServer.ATTACH_DYNAMIC);\n    }\n\n    /**\n     * This method is called after the VM has been initialized, but before the TA's main() method.\n     * A single arguments string passed to it is the \"options\" string specified to the -javaagent\n     * argument, as java -javaagent:jarpath=options. It should contain the communication port number\n     * and optional timeout separated by a comma.\n     */\n    public static void premain(String agentArgs, Instrumentation inst) {\n        activate(agentArgs, inst, ProfilerServer.ATTACH_DIRECT);\n    }\n\n    private static File getArchiveFile(URL url) {\n        String protocol = url.getProtocol();\n\n        if (\"jar\".equals(protocol)) { //NOI18N\n\n            String path = url.getPath();\n            int index = path.indexOf(\"!/\"); //NOI18N\n\n            if (index >= 0) {\n                try {\n                    return new File(new URI(path.substring(0, index)));\n                } catch (URISyntaxException ex) {\n                    throw new IllegalArgumentException(url.toString());\n                }\n            }\n        }\n\n        throw new IllegalArgumentException(url.toString());\n    }\n\n    private static void activate(String agentArgs, Instrumentation inst, int activateCode) {\n        URL classUrl = getSelfClassUrl();\n        File jar = getArchiveFile(classUrl);\n        String fullJFluidPath = jar.getParent();\n\n        if ((agentArgs == null) || (agentArgs.length() == 0)) { // no options, just load the native library. This is used for remote-pack calibration\n            ProfilerServer.loadNativeLibrary(fullJFluidPath, false);\n\n            return;\n        }\n\n        int timeOut = 0;\n        int commaPos = agentArgs.indexOf(',');\n\n        if (commaPos != -1) { // optional timeout is specified\n\n            String timeOutStr = agentArgs.substring(commaPos + 1, agentArgs.length());\n\n            try {\n                timeOut = Integer.parseInt(timeOutStr);\n            } catch (NumberFormatException ex) {\n                System.err.println(\"*** Profiler Engine: invalid timeout number specified to premain(): \" + timeOutStr); // NOI18N\n                System.exit(-1);\n            }\n\n            agentArgs = agentArgs.substring(0, commaPos);\n        }\n\n        String portStr = agentArgs;\n        int portNo = 0;\n\n        try {\n            portNo = Integer.parseInt(portStr);\n        } catch (NumberFormatException ex) {\n            System.err.println(\"*** Profiler Engine: invalid port number specified to premain(): \" + portStr); // NOI18N\n            System.exit(-1);\n        }\n        \n        ProfilerServer.loadNativeLibrary(fullJFluidPath, false);\n        ProfilerServer.activate(fullJFluidPath, portNo, activateCode, timeOut);\n    }\n\n    private static URL getSelfClassUrl() {\n        String SELF_CLASS_NAME = \"org/graalvm/visualvm/lib/jfluid/server/ProfilerActivate15.class\"; // NOI18N\n        \n        URL classUrl = ClassLoader.getSystemClassLoader().getResource(SELF_CLASS_NAME);\n        if (classUrl == null) {\n            classUrl = Thread.currentThread().getContextClassLoader().getResource(SELF_CLASS_NAME);\n        }\n        return classUrl;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-jdk15/org/graalvm/visualvm/lib/jfluid/server/system/Classes.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\nimport java.lang.management.ClassLoadingMXBean;\nimport java.lang.management.ManagementFactory;\n\n\n/**\n * Provides methods for dynamic bytecode redefinition and other class-related operations.\n * A version for JDK 1.5\n *\n * @author Tomas Hurka\n * @author  Misha Dmitriev\n */\npublic class Classes {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    /** We convert all error codes or exceptions thrown by redefine calls into a single error message in\n     * this exception\n     */\n    public static class RedefineException extends Exception {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public RedefineException(String msg) {\n            super(msg);\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static ClassLoadingMXBean classLoadingBean;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns all currently loaded *and linked* classes.\n     * On JDK 1.5, it returns just a Class[] array of all loaded classes\n     */\n    public static native Class[] getAllLoadedClasses();\n\n    /**\n     * Returns the cached class file bytes for the given class. Currently\n     * agent (on JDK 1.5) caches these bytes only for classes loaded with custom classloaders (that is, not\n     * bootstrap (null) and not system classloader). If this method is called for a class loaded using bootstrap or\n     * system classloader, it just returns null.\n     */\n    public static native byte[] getCachedClassFileBytes(Class clazz);\n\n    public static int getLoadedClassCount() {\n        return classLoadingBean.getLoadedClassCount();\n    }\n\n    /** Object size for a given object */\n    public static native long getObjectSize(Object obj);\n\n    public static native boolean setSleepTrackingEnabled(boolean value);\n\n    public static native boolean setVMObjectAllocEnabled(boolean value);\n\n    public static native boolean setWaitTrackingEnabled(boolean value);\n\n    public static native boolean setParkTrackingEnabled(boolean value);\n\n    public static native boolean setLockContentionMonitoringEnabled(boolean value);\n\n    public static native void cacheLoadedClasses(Class[] nonSystemClasses, int nonSystemIndex);\n\n    /** Disables the above class load hook */\n    public static native void disableClassLoadHook();\n\n    /**\n     * When the class load hook is enabled, it will call the ProfilerInterface.classLoadHook(Class) method every time\n     * a class is load and prepared.\n     */\n    public static native void enableClassLoadHook();\n\n    /** Should be called at earliest possible time */\n    public static void initialize() {\n        classLoadingBean = ManagementFactory.getClassLoadingMXBean();\n    }\n\n    /**\n     * This notifies the underlying native code about the fact that some classloader (we don't know which one since\n     * we use PhantomReferences for them) is unloaded. Thus the native code that could have cached the class file\n     * bytes for classes loaded with this loader, may release these bytes now. Really needed only in 1.5.\n     */\n    public static native void notifyAboutClassLoaderUnloading();\n\n    /** RedefineClasses() as provided starting from JDK 1.5 */\n    public static void redefineClasses(Class[] classes, byte[][] newClassFileBytes)\n                                throws RedefineException {\n        if (classes.length > newClassFileBytes.length) {\n            throw new RedefineException(\"Inconsistent input data: classes.length = \" + classes.length // NOI18N\n                                        + \", newClassFileBytes.length = \" + newClassFileBytes.length); // NOI18N\n        }\n\n        for (int i = 0; i < classes.length; i++) {\n            if (classes[i] == null) {\n                throw new RedefineException(\"null input data: classes at \" + i); // NOI18N\n            }\n\n            if (newClassFileBytes[i] == null) {\n                throw new RedefineException(\"null input data: newClassFileBytes at \" + i + \" for class \"+classes[i].getName()); // NOI18N\n            }\n        }\n\n        int res = doRedefineClasses(classes, newClassFileBytes);\n\n        if (res != 0) {\n            throw new RedefineException(\"Redefinition failed with error \" + res + \"\\n\" // NOI18N\n                                        + \"Check JVMTI documentation for this error code.\"); // NOI18N\n        }\n    }\n\n    // ======================================== JDK 1.5 specific code ===============================================\n    private static native int doRedefineClasses(Class[] classes, byte[][] newClassFileBytes);\n\n    private static RedefineException newRedefineException(String msg, Throwable origCause) {\n        msg = \"Class redefinition error: \" + msg + \"\\nOriginal exception:\\n\" + origCause; // NOI18N\n\n        return new RedefineException(msg);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-jdk15/org/graalvm/visualvm/lib/jfluid/server/system/HeapDump.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\nimport java.lang.management.ManagementFactory;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.JMRuntimeException;\nimport javax.management.MBeanException;\nimport javax.management.MBeanServer;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\nimport javax.management.ReflectionException;\n\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class HeapDump {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static MBeanServer mserver;\n    private static ObjectName hotspotDiag;\n    private static boolean initialized;\n    private static boolean runningOnJdk15;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private HeapDump() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void initialize(boolean jdk15) {\n        runningOnJdk15 = jdk15;\n        if (runningOnJdk15) {\n            initialize15();\n        } else {\n            initialize16();\n        }\n    }\n\n    public static String takeHeapDump(String outputFile) {\n        if (runningOnJdk15) {\n            return takeHeapDump15(outputFile);\n        }\n\n        return takeHeapDump16(outputFile);\n    }\n\n    private static native void initialize15();\n\n    private static void initialize16() {\n        if (initialized) {\n            return;\n        }\n\n        initialized = true;\n\n        try {\n            mserver = ManagementFactory.getPlatformMBeanServer();\n        } catch (JMRuntimeException ex) {\n            // Glassfish: if ManagementFactory.getPlatformMBeanServer() is called too early it will throw JMRuntimeException\n            // in such case initialization will be rerun later as part of takeHeapDump()\n            System.err.println(ex.getLocalizedMessage());\n            initialized = false;\n\n            return;\n        }\n\n        try {\n            hotspotDiag = new ObjectName(\"com.sun.management:type=HotSpotDiagnostic\");   // NOI18N\n            mserver.getObjectInstance(hotspotDiag);\n        } catch (MalformedObjectNameException ex) {\n            ex.printStackTrace();\n        } catch (InstanceNotFoundException ex) {\n            System.err.println(\"Heap Dump is not available\"); // NOI18N\n        } catch (SecurityException ex) {\n            ex.printStackTrace();\n        } catch (NullPointerException ex) {\n            ex.printStackTrace();\n        }\n    }\n\n    private static String takeHeapDump15(String outputFile) {\n        int error = -1;\n\n        try {\n            error = takeHeapDump15Native(outputFile);\n        } catch (Exception ex) {\n            return ex.getLocalizedMessage();\n        }\n\n        if (error == -1) {\n            return \"Take heap dump is not available.\"; // NOI18N\n        }\n\n        return null;\n    }\n\n    private static native int takeHeapDump15Native(String outputFile);\n\n    private static String takeHeapDump16(String outputFile) {\n        String error = null;\n        initialize16();\n\n        if ((mserver == null) || (hotspotDiag == null)) {\n            return \"Take heap dump is not available.\"; // NOI18N\n        }\n\n        try {\n            mserver.invoke(hotspotDiag, \"dumpHeap\", new Object[] {outputFile, true}, new String[] {String.class.getName(), boolean.class.getName()} );  // NOI18N\n        } catch (IllegalArgumentException ex) {\n            error = ex.getLocalizedMessage();\n        } catch (InstanceNotFoundException ex) {\n            error = ex.getLocalizedMessage();\n        } catch (MBeanException ex) {\n            error = ex.getLocalizedMessage();\n        } catch (ReflectionException ex) {\n            error = ex.getLocalizedMessage();\n        }\n\n        return error;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-jdk15/org/graalvm/visualvm/lib/jfluid/server/system/Histogram.java",
    "content": "/*\n * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\nimport java.io.InputStream;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class Histogram {\n    private static Boolean initialized;\n    private static boolean runningOnJdk9;\n\n    public static boolean isAvailable() {\n        if (initialized != null) {\n            return initialized.booleanValue();\n        }\n        return false;\n    }\n\n    public static boolean initialize(boolean jdk9) {\n        runningOnJdk9 = jdk9;\n        if (runningOnJdk9) {\n            initialized = Boolean.valueOf(Histogram19.initialize());\n        } else {\n            initialized = Boolean.valueOf(Histogram18.initialize());\n        }\n        return initialized.booleanValue();\n    }\n\n    public static InputStream getRawHistogram() {\n        if (runningOnJdk9) {\n            return Histogram19.getRawHistogram();\n        }\n        return Histogram18.getRawHistogram();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-jdk15/org/graalvm/visualvm/lib/jfluid/server/system/Histogram18.java",
    "content": "/*\n * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\nimport java.io.File;\nimport java.io.InputStream;\nimport java.lang.management.ManagementFactory;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.net.URLClassLoader;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass Histogram18 {\n    private static final String LIVE_OBJECTS_OPTION = \"-live\";  // NOI18N\n    private static final String ALL_OBJECTS_OPTION = \"-all\";    // NOI18N\n    private static final String VIRTUAL_MACHINE_CLASS = \"com.sun.tools.attach.VirtualMachine\"; // NOI18N\n    private static final String HS_VIRTUAL_MACHINE_CLASS = \"sun.tools.attach.HotSpotVirtualMachine\"; // NOI18N\n    private static final String VIRTUAL_MACHINE_ATTACH_METHOD = \"attach\";   // NOI18N\n    private static final String VIRTUAL_MACHINE_HEAPHISTO_METHOD = \"heapHisto\";   // NOI18N\n    private static String selfPid;\n    private static Method vmAttach;\n    private static Method vmHisto;\n    private static Object virtualMachine;\n\n    static InputStream getRawHistogram() {\n        try {\n            if (virtualMachine == null) {\n                virtualMachine = vmAttach.invoke(null, selfPid);\n            }\n            Object ret = vmHisto.invoke(virtualMachine, new Object[]{new Object[]{ALL_OBJECTS_OPTION}});\n            if (ret instanceof InputStream) {\n                return (InputStream)ret;\n            }\n        } catch (IllegalAccessException ex) {\n            return null;\n        } catch (IllegalArgumentException ex) {\n            return null;\n        } catch (InvocationTargetException ex) {\n            return null;\n        }\n        return null;\n    }\n\n    private static ClassLoader getToolsJar() {\n        File home = getJavaHome();\n        File toolsJar = new File(home,\"lib/tools.jar\"); // NOI18N\n        if (toolsJar.exists() && toolsJar.isFile()) {\n            try {\n                return new URLClassLoader(new URL[] {toolsJar.toURI().toURL()});\n            } catch (MalformedURLException ex) {\n                return null;\n            }\n        }\n        return null;\n    }\n    \n    private static File getJavaHome() {\n        File jdkHome = new File(System.getProperty(\"java.home\")); // NOI18N\n        if (\"jre\".equals(jdkHome.getName())) {  // NOI18N\n           jdkHome = jdkHome.getParentFile(); \n        }\n        return jdkHome;\n    }\n\n    static boolean initialize() {\n        try {\n            Class vmClass = loadClass(VIRTUAL_MACHINE_CLASS);\n            Class hsVmClass = Class.forName(HS_VIRTUAL_MACHINE_CLASS, true, vmClass.getClassLoader()); \n            vmAttach = vmClass.getMethod(VIRTUAL_MACHINE_ATTACH_METHOD, String.class);\n            vmHisto = hsVmClass.getMethod(VIRTUAL_MACHINE_HEAPHISTO_METHOD, Object[].class);\n        } catch (NoSuchMethodException ex) {\n            ex.printStackTrace();\n            return false;\n        } catch (SecurityException ex) {\n            ex.printStackTrace();\n            return false;\n        } catch (ClassNotFoundException ex) {\n            ex.printStackTrace();\n            return false;\n        }\n        String selfName = ManagementFactory.getRuntimeMXBean().getName();\n        selfPid = selfName.substring(0, selfName.indexOf('@')); // NOI18N\n        return true;\n    }\n    \n    /** load class from tools.jar\n     * \n     * @param className class name\n     * @return class\n     * @throws ClassNotFoundException \n     */\n    private static Class loadClass(String className) throws ClassNotFoundException {\n        // try boot classloader first\n        try {\n            return Class.forName(className);\n        } catch (ClassNotFoundException ex) {\n//            ex.printStackTrace();\n        }\n        // locate and try to use tools.jar\n        ClassLoader toolsJar = getToolsJar();\n        if (toolsJar == null) {\n            throw new ClassNotFoundException(className);\n        }\n        return Class.forName(className, true, toolsJar);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-jdk15/org/graalvm/visualvm/lib/jfluid/server/system/Histogram19.java",
    "content": "/*\n * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.InputStream;\nimport java.lang.management.ManagementFactory;\nimport java.nio.charset.StandardCharsets;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.MBeanException;\nimport javax.management.MBeanServer;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\nimport javax.management.ReflectionException;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass Histogram19 {\n    private static final String DIAGNOSTIC_COMMAND_MXBEAN_NAME =\n            \"com.sun.management:type=DiagnosticCommand\";    // NOI18N\n    private static final String ALL_OBJECTS_OPTION = \"-all\";    // NOI18N\n    private static final String HISTOGRAM_COMMAND = \"gcClassHistogram\";       // NOI18N\n    private static MBeanServer mserver;\n    private static ObjectName hotspotDiag;\n\n    static boolean initialize() {\n        boolean initok = false;\n        try {\n            mserver = ManagementFactory.getPlatformMBeanServer();\n            hotspotDiag = new ObjectName(DIAGNOSTIC_COMMAND_MXBEAN_NAME);\n            mserver.getObjectInstance(hotspotDiag);\n            initok = true;\n        } catch (MalformedObjectNameException ex) {\n            ex.printStackTrace();\n        } catch (InstanceNotFoundException ex) {\n            System.err.println(\"Heap Histogram is not available\"); // NOI18N\n        } catch (SecurityException ex) {\n            ex.printStackTrace();\n        } catch (NullPointerException ex) {\n            ex.printStackTrace();\n        }\n        return initok;\n    }\n\n    static InputStream getRawHistogram() {\n        try {\n            Object histo = mserver.invoke(hotspotDiag,\n                    HISTOGRAM_COMMAND,\n                    new Object[] {new String[] {ALL_OBJECTS_OPTION}},\n                    new String[] {String[].class.getName()}\n            );\n            if (histo instanceof String) {\n                return new ByteArrayInputStream(((String)histo).getBytes(StandardCharsets.UTF_8));\n            }\n        } catch (InstanceNotFoundException ex) {\n            ex.printStackTrace();\n        } catch (MBeanException ex) {\n            ex.printStackTrace();\n        } catch (ReflectionException ex) {\n            ex.printStackTrace();\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-jdk15/org/graalvm/visualvm/lib/jfluid/server/system/ThreadDump.java",
    "content": "/*\n * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\nimport java.lang.management.ManagementFactory;\nimport java.lang.management.ThreadInfo;\nimport java.lang.management.ThreadMXBean;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.management.openmbean.CompositeData;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class ThreadDump {\n\n    private static final String[][] methods = new String[][]{\n        {\"sun.management.ThreadInfoCompositeData\", \"toCompositeData\"}, // NOI18N Sun JVM\n        {\"com.ibm.lang.management.ManagementUtils\", \"toThreadInfoCompositeData\"} // NOI18N IBM J9\n    };\n\n    private static Method toCompositeDataMethod;\n    private static ThreadMXBean threadBean;\n    private static boolean runningOnJdk15;\n\n    public static void initialize(boolean jdk15) {\n        runningOnJdk15 = jdk15;\n        threadBean = ManagementFactory.getThreadMXBean();\n        for (String[] method : methods) {\n            String className = method[0];\n            String methodName = method[1];\n            try {\n                Class clazz = Class.forName(className);\n                toCompositeDataMethod = clazz.getMethod(methodName, ThreadInfo.class);\n                if (toCompositeDataMethod != null) {\n                    break;\n                }\n            } catch (ClassNotFoundException ex) {\n            } catch (NoSuchMethodException ex) {\n            } catch (SecurityException ex) {\n            }\n        }\n    }\n\n    public static Object[] takeThreadDump() {\n        ThreadInfo[] threads = (runningOnJdk15) ? takeThreadDump15() : takeThreadDump16();\n        List compositeData = new ArrayList(threads.length);\n\n        for (int i = 0; i < threads.length; i++) {\n            ThreadInfo ti = threads[i];\n            if (ti != null) {\n                compositeData.add(toCompositeData(ti));\n            }\n        }\n        return compositeData.toArray(new CompositeData[0]);\n    }\n\n    public static boolean isJDK15() {\n        return runningOnJdk15;\n    }\n    \n    private static CompositeData toCompositeData(ThreadInfo tinfo) {\n        try {\n            return (CompositeData) toCompositeDataMethod.invoke(null, tinfo);\n        } catch (IllegalAccessException ex) {\n            throw new RuntimeException(ex);\n        } catch (IllegalArgumentException ex) {\n            throw new RuntimeException(ex);\n        } catch (InvocationTargetException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n\n    private static ThreadInfo[] takeThreadDump15() {\n        long[] tids = threadBean.getAllThreadIds();\n        return threadBean.getThreadInfo(tids, Integer.MAX_VALUE);\n    }\n\n    private static ThreadInfo[] takeThreadDump16() {\n        return threadBean.dumpAllThreads(true, true);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/src-jdk15/org/graalvm/visualvm/lib/jfluid/server/system/Timers.java",
    "content": "/*\n * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.server.system;\n\nimport java.lang.management.ManagementFactory;\nimport javax.management.JMRuntimeException;\nimport javax.management.MBeanAttributeInfo;\nimport javax.management.MBeanServerConnection;\nimport javax.management.ObjectName;\n\n\n/**\n * Provides methods for obtaining various high-resolution system times.\n * A version for JDK 1.5\n *\n * @author  Misha Dmitriev\n */\npublic class Timers {\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static MBeanServerConnection conn;\n    private static final String PROCESS_CPU_TIME_ATTR = \"ProcessCpuTime\"; // NOI18N\n\n    /** IBM/OpenJ9 only. */\n    private static final String PROCESS_CPU_TIME_NS_ATTR = \"ProcessCpuTimeByNS\"; // NOI18N\n\n    /**\n     * IBM/OpenJ9 only.\n     * Returns the collective processing capacity available to the VM\n     * in units of 1% of a physical processor. In environments without\n     * some kind of virtual partitioning, this will simply be the number\n     * of CPUs * 100.\n     */\n    private static final String PROCESSING_CAPACITY_ATTR = \"ProcessingCapacity\"; // NOI18N\n    private static ObjectName osName;\n    private static double processingCapacity;\n    private static int processorsCount;\n    private static boolean processCPUTimeAttribute;\n    private static boolean initialized;\n    private static String processCpuTimeAttr;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * \"counts\" instead of nanoseconds in this method are for compatibility with the previous\n     * versions of JFluid, that call a native method for system timer, which, in turn, returns\n     * the result in sub-microsecond \"counts\" on Windows.\n     */\n    public static long getCurrentTimeInCounts() {\n        return System.nanoTime();\n    }\n\n    public static long getNoOfCountsInSecond() {\n        return 1000000000;\n    }\n\n    public static native long getThreadCPUTimeInNanos();\n\n    /**\n     * Returns the approximate accumulated process CPU elapsed time\n     * in nanoseconds. Note that the time is normalized to one processor.\n     * This method returns <tt>-1</tt> if the collection\n     * elapsed time is undefined for this collector.\n     *\n     * @return the approximate accumulated process CPU elapsed time\n     * in nanoseconds.\n     */\n    public static long getProcessCpuTime() {\n        initializeProcessCPUTime();\n        if (processCPUTimeAttribute) {\n             try {\n                 Long cputime = (Long)conn.getAttribute(osName,processCpuTimeAttr);\n\n                 return (long)(cputime.longValue()/processingCapacity/processorsCount);\n             } catch (Exception ex) {\n                 ex.printStackTrace();\n             }\n        }\n        return -1;\n    }\n\n    /**\n     * This is relevant only on Solaris. By default, the resolution of the thread local CPU timer is 10 ms. If we enable\n     * micro state accounting, it enables significantly (but possibly at a price of some overhead). So I turn it on only\n     * when thread CPU timestamps are really collected.\n     */\n    public static native void enableMicrostateAccounting(boolean v);\n\n    /** Should be called at earliest possible time */\n    public static void initialize() {\n        ManagementFactory.getThreadMXBean();\n        getThreadCPUTimeInNanos();\n        initializeProcessCPUTime();\n    }\n\n    private static void initializeProcessCPUTime() {\n        if (initialized) {\n            return;\n        }\n\n        initialized = true;\n        try {\n            MBeanAttributeInfo[] attrs;\n            \n            conn = ManagementFactory.getPlatformMBeanServer();\n            osName = new ObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME);\n            attrs = conn.getMBeanInfo(osName).getAttributes();\n            processorsCount = ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors();\n            for (int i = 0; i < attrs.length; i++) {\n                String name = attrs[i].getName();\n                \n                if (PROCESS_CPU_TIME_ATTR.equals(name) && !processCPUTimeAttribute) {\n                    processCPUTimeAttribute = Boolean.TRUE;\n                    processCpuTimeAttr = name;\n                }\n                if (PROCESS_CPU_TIME_NS_ATTR.equals(name)) {\n                    processCPUTimeAttribute = Boolean.TRUE;\n                    processCpuTimeAttr = name;\n                }\n                if (PROCESSING_CAPACITY_ATTR.equals(name)) {\n                    Number mul = (Number) conn.getAttribute(osName,PROCESSING_CAPACITY_ATTR);\n                    processingCapacity = mul.longValue()/100.0/processorsCount;\n                }\n            }\n        } catch (JMRuntimeException ex) {\n            // Glassfish: if ManagementFactory.getPlatformMBeanServer() is called too early it will throw JMRuntimeException\n            // in such case initialization will be rerun later as part of getProcessCpuTime()\n            System.err.println(ex.getLocalizedMessage());\n            initialized = false;       \n            return;   \n        } catch (Exception ex) {\n            ex.printStackTrace();\n        }\n    }\n\n    /**\n     * WORKS ONLY ON UNIX, calls nanosleep(). On Solaris, this is more precise than the built-in Thread.sleep() call\n     * implementation that, at least in JDK 1.4.2, goes to select(3C). On Linux, it should be more precise, but it\n     * turns out that nanosleep() in this OS, at least in version 7.3 that I tested, has a resolution of at least 20ms.\n     * This seems to be a known issue; hopefully they fix it in future.\n     */\n    public static native void osSleep(int ns);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/perf/InstrumentationTest.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * InstrumentationTest.java\n * JUnit based test\n *\n * Created on November 7, 2006, 2:14 PM\n */\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.perf;\n\nimport junit.framework.*;\nimport org.netbeans.junit.NbPerformanceTest;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.Instrumentor;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.CommonProfilerTestCase;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.InstrumentMethodGroupResponse;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.RootClassLoadedCommand;\nimport java.io.BufferedInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.PrintStream;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.HashSet;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\n\n\n/**\n *\n * @author ehucka\n */\npublic class InstrumentationTest extends CommonProfilerTestCase implements NbPerformanceTest {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    ArrayList<NbPerformanceTest.PerformanceData> data = new ArrayList();\n    ProfilerEngineSettings settings;\n    String[] classNames;\n    byte[][] classesBytes;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public InstrumentationTest(String testName) {\n        super(testName);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static Test suite() {\n        TestSuite suite = new TestSuite(org.graalvm.visualvm.lib.jfluid.tests.jfluid.perf.InstrumentationTest.class);\n\n        return suite;\n    }\n\n    public NbPerformanceTest.PerformanceData[] getPerformanceData() {\n        return data.toArray(new NbPerformanceTest.PerformanceData[0]);\n    }\n\n    public void reportPerformance(String name, long value, String unit) {\n        NbPerformanceTest.PerformanceData d = new NbPerformanceTest.PerformanceData();\n        d.name = name;\n        d.value = value;\n        d.unit = unit;\n        d.threshold = NbPerformanceTest.PerformanceData.NO_THRESHOLD;\n        data.add(d);\n    }\n\n    public void testJ2SE() {\n        try {\n            String jarPath = \"/perfdata/j2se-simple.jar\";\n            File f = new File(getDataDir(), jarPath);\n            assertTrue(\"Instrumented jar file doesn't exist.\", f.exists());\n            initTest(f.getAbsolutePath());\n            startInstrumentationTest(f.getAbsolutePath());\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            fail();\n        }\n    }\n\n    public void testJaxb() {\n        try {\n            String jarPath = \"/perfdata/jaxb-xjc.jar\";\n            File f = new File(getDataDir(), jarPath);\n            assertTrue(\"Instrumented jar file doesn't exist.\", f.exists());\n            initTest(f.getAbsolutePath());\n            startInstrumentationTest(f.getAbsolutePath());\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            fail();\n        }\n    }\n\n    public void testJaxbNoGettersEmpties() {\n        try {\n            String jarPath = \"/perfdata/jaxb-xjc.jar\";\n            File f = new File(getDataDir(), jarPath);\n            assertTrue(\"Instrumented jar file doesn't exist.\", f.exists());\n            initTest(f.getAbsolutePath());\n            settings.setInstrumentGetterSetterMethods(false);\n            settings.setInstrumentEmptyMethods(false);\n            startInstrumentationTest(f.getAbsolutePath());\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            fail();\n        }\n    }\n\n    public void testSimple() {\n        try {\n            String jarPath = \"/perfdata/oneclass.jar\";\n            File f = new File(getDataDir(), jarPath);\n            assertTrue(\"Instrumented jar file doesn't exist.\", f.exists());\n            initTest(f.getAbsolutePath());\n            startInstrumentationTest(f.getAbsolutePath());\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            fail();\n        }\n    }\n\n    public void testSimpleNoEmpties() {\n        try {\n            String jarPath = \"/perfdata/oneclass.jar\";\n            File f = new File(getDataDir(), jarPath);\n            assertTrue(\"Instrumented jar file doesn't exist.\", f.exists());\n            initTest(f.getAbsolutePath());\n            settings.setInstrumentEmptyMethods(false);\n            startInstrumentationTest(f.getAbsolutePath());\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            fail();\n        }\n    }\n\n    public void testSimpleNoGetters() {\n        try {\n            String jarPath = \"/perfdata/oneclass.jar\";\n            File f = new File(getDataDir(), jarPath);\n            assertTrue(\"Instrumented jar file doesn't exist.\", f.exists());\n            initTest(f.getAbsolutePath());\n            settings.setInstrumentGetterSetterMethods(false);\n            startInstrumentationTest(f.getAbsolutePath());\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            fail();\n        }\n    }\n\n    protected void setClasses(String jarPath) throws Exception {\n        ArrayList<String> names = new ArrayList(16);\n        ArrayList<byte[]> bytes = new ArrayList(16);\n        JarFile file = new JarFile(jarPath);\n        Enumeration<JarEntry> entries = file.entries();\n        ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);\n        int read = 0;\n        byte[] buffer = new byte[1024];\n\n        while (entries.hasMoreElements()) {\n            JarEntry entry = entries.nextElement();\n\n            if (entry.getName().endsWith(\".class\")) {\n                String nm = entry.getName();\n                nm = nm.substring(0, nm.lastIndexOf(\".\"));\n                names.add(nm);\n\n                BufferedInputStream bis = new BufferedInputStream(file.getInputStream(entry));\n\n                while ((read = bis.read(buffer)) > -1) {\n                    bos.write(buffer, 0, read);\n                }\n\n                bis.close();\n                bytes.add(bos.toByteArray());\n                bos.reset();\n            }\n        }\n\n        classNames = names.toArray(new String[0]);\n        classesBytes = bytes.toArray(new byte[0][]);\n    }\n\n    protected void setRootMethods(String jarFile) throws Exception {\n        JarFile file = new JarFile(jarFile);\n        HashSet<String> list = new HashSet(8);\n\n        for (Enumeration<JarEntry> entries = file.entries(); entries.hasMoreElements();) {\n            JarEntry entry = entries.nextElement();\n\n            if (entry.getName().endsWith(\".class\")) {\n                String name = entry.getName();\n                int idx = name.lastIndexOf('/');\n                String packageName = (idx == -1) ? name : name.substring(0, idx);\n                packageName = packageName.replace('/', '.');\n                list.add(packageName);\n            }\n        }\n\n        ClientUtils.SourceCodeSelection[] ret = new ClientUtils.SourceCodeSelection[list.size()];\n        String[] cls = list.toArray(new String[0]);\n\n        for (int i = 0; i < list.size(); i++) {\n            ret[i] = new ClientUtils.SourceCodeSelection(cls[i] + \".\", \"\", \"\"); //NOI18N\n        }\n\n        settings.setInstrumentationRootMethods(ret);\n    }\n\n    protected boolean checkBytes(String className, byte[] bytes) {\n        String clnm = className.replace(\".\", \"/\");\n        int clindex = -1;\n\n        for (int i = 0; i < classNames.length; i++) {\n            if (classNames[i].equals(clnm)) {\n                clindex = i;\n\n                break;\n            }\n        }\n\n        if (clindex == -1) {\n            throw new IllegalStateException(\"Class \" + className + \" has not original.\");\n        }\n\n        byte[] origbytes = classesBytes[clindex];\n\n        if (origbytes.length != bytes.length) {\n            return false;\n        }\n\n        for (int i = 0; i < bytes.length; i++) {\n            if (bytes[i] != origbytes[i]) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    protected ProfilerEngineSettings initTest(String pathToJar)\n                                       throws Exception {\n        settings = new ProfilerEngineSettings();\n        settings.setPortNo(5140);\n        settings.setSeparateConsole(false);\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_TOTAL);\n        settings.setInstrumentEmptyMethods(true);\n        settings.setInstrumentGetterSetterMethods(true);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentSpawnedThreads(true);\n        settings.setJVMArgs(\"\");\n\n        setRootMethods(pathToJar);\n\n        setTargetVM(settings);\n        //setClassPath(settings);\n        setProfilerHome(settings);\n\n        setStatus(STATUS_NONE);\n\n        return settings;\n    }\n\n    protected void startInstrumentationTest(String jarFile)\n                                     throws Exception {\n        ProfilingSessionStatus status = new ProfilingSessionStatus();\n        status.targetJDKVersionString = settings.getTargetJDKVersionString();\n\n        PrintStream oldOutStream = System.out;\n        PrintStream oldErrStream = System.err;\n        System.setOut(getLogStream());\n        System.setErr(getLogStream());\n\n        Instrumentor instr = new Instrumentor(status, settings);\n        instr.setStatusInfoFromSourceCodeSelection(settings.getInstrumentationRootMethods());\n        status.currentInstrType = CommonConstants.INSTR_RECURSIVE_FULL;\n\n        setClasses(jarFile);\n\n        int[] loadersIDs = new int[classNames.length];\n\n        for (int i = 0; i < classNames.length; i++) {\n            loadersIDs[i] = 20;\n        }\n\n        int[] parentloadersIDs = new int[classNames.length];\n\n        for (int i = 0; i < classNames.length; i++) {\n            parentloadersIDs[i] = 0;\n        }\n\n        RootClassLoadedCommand cmd = new RootClassLoadedCommand(classNames, loadersIDs, classesBytes, classNames.length,\n                                                                parentloadersIDs, null);\n        log(\"Start instrumenting ...\");\n\n        InstrumentMethodGroupResponse resp = null;\n        long time = System.currentTimeMillis();\n        resp = instr.createInitialInstrumentMethodGroupResponse(cmd);\n        time = System.currentTimeMillis() - time;\n        ref(\"Number of Classes: \" + classNames.length);\n\n        byte[][] clbytes = resp.getReplacementClassFileBytes();\n        ref(\"Instrumented Classes: \" + resp.getBase().getNClasses());\n        ref(\"Instrumented Methods: \" + resp.getBase().getNMethods());\n\n        if (resp.getErrorMessage() != null) {\n            log(\"Error Message: \" + resp.getErrorMessage());\n        }\n\n        String[] clnames = resp.getMethodClasses();\n        byte[][] bts = resp.getReplacementClassFileBytes();\n        boolean comp = false;\n\n        for (int i = 0; i < clnames.length; i++) {\n            if (checkBytes(clnames[i], bts[i])) {\n                log(\"Equals bytes: \" + clnames[i]);\n            }\n        }\n\n        System.setOut(oldOutStream);\n        System.setErr(oldErrStream);\n        reportPerformance(getName(), time, \"ms\");\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/coverage.txt",
    "content": "What functionality the functional tests cover.\n\nTest of calibration\nTests of CPU profiling\n Default settings\n Instrumentation: sampled, full\n CPU Instrumentation: lazy, eager, total\n Instrument: methods invoke, setter/getter, empty methods\n Instrumentation filters\n Not instr. spawned threads\n Set limit of spawned threads\n Set instrumentation root methods\n Measure methods with wait/sleep\n\nTests of CPU snapshot\n Check sums of subnodes in call tree - time, percents\n Simple test of serialization/deserialization of snapshots\n Test of reverse call stack\n\nTests of memory profiling\n Objects creations\n Objects liveness\n Check actual objects count and size\n \nTests of code region profiling\n Method code region\n Code lines region\n Method with wait/sleep\n\nTests of monitor threads\n List of running threads\n Roughly states of threads"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testMethodWithWaitEager.pass",
    "content": "simple.cpu.WaitingTest.method1000()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testMethodWithWaitEagerServer.pass",
    "content": "simple.cpu.WaitingTest.method1000()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testMethodWithWaitExcludeWEager.pass",
    "content": "simple.cpu.WaitingTest.method1000()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testMethodWithWaitExcludeWLazy.pass",
    "content": "simple.cpu.WaitingTest.method1000()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testMethodWithWaitExcludeWTotal.pass",
    "content": "simple.cpu.WaitingTest.method1000()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testMethodWithWaitLazy.pass",
    "content": "simple.cpu.WaitingTest.method1000()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testMethodWithWaitLazyServer.pass",
    "content": "simple.cpu.WaitingTest.method1000()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testMethodWithWaitTotal.pass",
    "content": "simple.cpu.WaitingTest.method1000()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testMethodWithWaitTotalServer.pass",
    "content": "simple.cpu.WaitingTest.method1000()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsDefault.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumenManyMethodsLazy.pass",
    "content": "simple.cpu.Methods2.method1()\nsimple.cpu.Methods2.method10()\nsimple.cpu.Methods2.method100()\nsimple.cpu.Methods2.method101()\nsimple.cpu.Methods2.method102()\nsimple.cpu.Methods2.method103()\nsimple.cpu.Methods2.method104()\nsimple.cpu.Methods2.method105()\nsimple.cpu.Methods2.method106()\nsimple.cpu.Methods2.method107()\nsimple.cpu.Methods2.method108()\nsimple.cpu.Methods2.method109()\nsimple.cpu.Methods2.method11()\nsimple.cpu.Methods2.method110()\nsimple.cpu.Methods2.method111()\nsimple.cpu.Methods2.method112()\nsimple.cpu.Methods2.method113()\nsimple.cpu.Methods2.method114()\nsimple.cpu.Methods2.method115()\nsimple.cpu.Methods2.method116()\nsimple.cpu.Methods2.method117()\nsimple.cpu.Methods2.method118()\nsimple.cpu.Methods2.method119()\nsimple.cpu.Methods2.method12()\nsimple.cpu.Methods2.method120()\nsimple.cpu.Methods2.method121()\nsimple.cpu.Methods2.method122()\nsimple.cpu.Methods2.method123()\nsimple.cpu.Methods2.method124()\nsimple.cpu.Methods2.method125()\nsimple.cpu.Methods2.method126()\nsimple.cpu.Methods2.method127()\nsimple.cpu.Methods2.method128()\nsimple.cpu.Methods2.method129()\nsimple.cpu.Methods2.method13()\nsimple.cpu.Methods2.method130()\nsimple.cpu.Methods2.method131()\nsimple.cpu.Methods2.method132()\nsimple.cpu.Methods2.method133()\nsimple.cpu.Methods2.method134()\nsimple.cpu.Methods2.method135()\nsimple.cpu.Methods2.method136()\nsimple.cpu.Methods2.method137()\nsimple.cpu.Methods2.method138()\nsimple.cpu.Methods2.method139()\nsimple.cpu.Methods2.method14()\nsimple.cpu.Methods2.method140()\nsimple.cpu.Methods2.method141()\nsimple.cpu.Methods2.method142()\nsimple.cpu.Methods2.method143()\nsimple.cpu.Methods2.method144()\nsimple.cpu.Methods2.method145()\nsimple.cpu.Methods2.method146()\nsimple.cpu.Methods2.method147()\nsimple.cpu.Methods2.method148()\nsimple.cpu.Methods2.method149()\nsimple.cpu.Methods2.method15()\nsimple.cpu.Methods2.method150()\nsimple.cpu.Methods2.method151()\nsimple.cpu.Methods2.method152()\nsimple.cpu.Methods2.method153()\nsimple.cpu.Methods2.method154()\nsimple.cpu.Methods2.method155()\nsimple.cpu.Methods2.method156()\nsimple.cpu.Methods2.method157()\nsimple.cpu.Methods2.method158()\nsimple.cpu.Methods2.method159()\nsimple.cpu.Methods2.method16()\nsimple.cpu.Methods2.method160()\nsimple.cpu.Methods2.method161()\nsimple.cpu.Methods2.method162()\nsimple.cpu.Methods2.method163()\nsimple.cpu.Methods2.method164()\nsimple.cpu.Methods2.method165()\nsimple.cpu.Methods2.method166()\nsimple.cpu.Methods2.method167()\nsimple.cpu.Methods2.method168()\nsimple.cpu.Methods2.method169()\nsimple.cpu.Methods2.method17()\nsimple.cpu.Methods2.method170()\nsimple.cpu.Methods2.method171()\nsimple.cpu.Methods2.method172()\nsimple.cpu.Methods2.method173()\nsimple.cpu.Methods2.method174()\nsimple.cpu.Methods2.method175()\nsimple.cpu.Methods2.method176()\nsimple.cpu.Methods2.method177()\nsimple.cpu.Methods2.method178()\nsimple.cpu.Methods2.method179()\nsimple.cpu.Methods2.method18()\nsimple.cpu.Methods2.method180()\nsimple.cpu.Methods2.method181()\nsimple.cpu.Methods2.method182()\nsimple.cpu.Methods2.method183()\nsimple.cpu.Methods2.method184()\nsimple.cpu.Methods2.method185()\nsimple.cpu.Methods2.method186()\nsimple.cpu.Methods2.method187()\nsimple.cpu.Methods2.method188()\nsimple.cpu.Methods2.method189()\nsimple.cpu.Methods2.method19()\nsimple.cpu.Methods2.method190()\nsimple.cpu.Methods2.method191()\nsimple.cpu.Methods2.method192()\nsimple.cpu.Methods2.method193()\nsimple.cpu.Methods2.method194()\nsimple.cpu.Methods2.method195()\nsimple.cpu.Methods2.method196()\nsimple.cpu.Methods2.method197()\nsimple.cpu.Methods2.method198()\nsimple.cpu.Methods2.method199()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentAllEager.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentAllEagerServer.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentAllLazy.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentAllLazyServer.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentAllTotal.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentAllTotalServer.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentExcludeJavas.pass",
    "content": "java.lang.ApplicationShutdownHooks$1.run()\nsimple.cpu.Bean.<init>()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentExcludeJavasServer.pass",
    "content": "java.lang.ApplicationShutdownHooks$1.run()\nsimple.cpu.Bean.<init>()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentManyMethodsEager.pass",
    "content": "simple.cpu.Methods2.method1()\nsimple.cpu.Methods2.method10()\nsimple.cpu.Methods2.method100()\nsimple.cpu.Methods2.method101()\nsimple.cpu.Methods2.method102()\nsimple.cpu.Methods2.method103()\nsimple.cpu.Methods2.method104()\nsimple.cpu.Methods2.method105()\nsimple.cpu.Methods2.method106()\nsimple.cpu.Methods2.method107()\nsimple.cpu.Methods2.method108()\nsimple.cpu.Methods2.method109()\nsimple.cpu.Methods2.method11()\nsimple.cpu.Methods2.method110()\nsimple.cpu.Methods2.method111()\nsimple.cpu.Methods2.method112()\nsimple.cpu.Methods2.method113()\nsimple.cpu.Methods2.method114()\nsimple.cpu.Methods2.method115()\nsimple.cpu.Methods2.method116()\nsimple.cpu.Methods2.method117()\nsimple.cpu.Methods2.method118()\nsimple.cpu.Methods2.method119()\nsimple.cpu.Methods2.method12()\nsimple.cpu.Methods2.method120()\nsimple.cpu.Methods2.method121()\nsimple.cpu.Methods2.method122()\nsimple.cpu.Methods2.method123()\nsimple.cpu.Methods2.method124()\nsimple.cpu.Methods2.method125()\nsimple.cpu.Methods2.method126()\nsimple.cpu.Methods2.method127()\nsimple.cpu.Methods2.method128()\nsimple.cpu.Methods2.method129()\nsimple.cpu.Methods2.method13()\nsimple.cpu.Methods2.method130()\nsimple.cpu.Methods2.method131()\nsimple.cpu.Methods2.method132()\nsimple.cpu.Methods2.method133()\nsimple.cpu.Methods2.method134()\nsimple.cpu.Methods2.method135()\nsimple.cpu.Methods2.method136()\nsimple.cpu.Methods2.method137()\nsimple.cpu.Methods2.method138()\nsimple.cpu.Methods2.method139()\nsimple.cpu.Methods2.method14()\nsimple.cpu.Methods2.method140()\nsimple.cpu.Methods2.method141()\nsimple.cpu.Methods2.method142()\nsimple.cpu.Methods2.method143()\nsimple.cpu.Methods2.method144()\nsimple.cpu.Methods2.method145()\nsimple.cpu.Methods2.method146()\nsimple.cpu.Methods2.method147()\nsimple.cpu.Methods2.method148()\nsimple.cpu.Methods2.method149()\nsimple.cpu.Methods2.method15()\nsimple.cpu.Methods2.method150()\nsimple.cpu.Methods2.method151()\nsimple.cpu.Methods2.method152()\nsimple.cpu.Methods2.method153()\nsimple.cpu.Methods2.method154()\nsimple.cpu.Methods2.method155()\nsimple.cpu.Methods2.method156()\nsimple.cpu.Methods2.method157()\nsimple.cpu.Methods2.method158()\nsimple.cpu.Methods2.method159()\nsimple.cpu.Methods2.method16()\nsimple.cpu.Methods2.method160()\nsimple.cpu.Methods2.method161()\nsimple.cpu.Methods2.method162()\nsimple.cpu.Methods2.method163()\nsimple.cpu.Methods2.method164()\nsimple.cpu.Methods2.method165()\nsimple.cpu.Methods2.method166()\nsimple.cpu.Methods2.method167()\nsimple.cpu.Methods2.method168()\nsimple.cpu.Methods2.method169()\nsimple.cpu.Methods2.method17()\nsimple.cpu.Methods2.method170()\nsimple.cpu.Methods2.method171()\nsimple.cpu.Methods2.method172()\nsimple.cpu.Methods2.method173()\nsimple.cpu.Methods2.method174()\nsimple.cpu.Methods2.method175()\nsimple.cpu.Methods2.method176()\nsimple.cpu.Methods2.method177()\nsimple.cpu.Methods2.method178()\nsimple.cpu.Methods2.method179()\nsimple.cpu.Methods2.method18()\nsimple.cpu.Methods2.method180()\nsimple.cpu.Methods2.method181()\nsimple.cpu.Methods2.method182()\nsimple.cpu.Methods2.method183()\nsimple.cpu.Methods2.method184()\nsimple.cpu.Methods2.method185()\nsimple.cpu.Methods2.method186()\nsimple.cpu.Methods2.method187()\nsimple.cpu.Methods2.method188()\nsimple.cpu.Methods2.method189()\nsimple.cpu.Methods2.method19()\nsimple.cpu.Methods2.method190()\nsimple.cpu.Methods2.method191()\nsimple.cpu.Methods2.method192()\nsimple.cpu.Methods2.method193()\nsimple.cpu.Methods2.method194()\nsimple.cpu.Methods2.method195()\nsimple.cpu.Methods2.method196()\nsimple.cpu.Methods2.method197()\nsimple.cpu.Methods2.method198()\nsimple.cpu.Methods2.method199()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentManyMethodsTotal.pass",
    "content": "simple.cpu.Methods2.method1()\nsimple.cpu.Methods2.method10()\nsimple.cpu.Methods2.method100()\nsimple.cpu.Methods2.method101()\nsimple.cpu.Methods2.method102()\nsimple.cpu.Methods2.method103()\nsimple.cpu.Methods2.method104()\nsimple.cpu.Methods2.method105()\nsimple.cpu.Methods2.method106()\nsimple.cpu.Methods2.method107()\nsimple.cpu.Methods2.method108()\nsimple.cpu.Methods2.method109()\nsimple.cpu.Methods2.method11()\nsimple.cpu.Methods2.method110()\nsimple.cpu.Methods2.method111()\nsimple.cpu.Methods2.method112()\nsimple.cpu.Methods2.method113()\nsimple.cpu.Methods2.method114()\nsimple.cpu.Methods2.method115()\nsimple.cpu.Methods2.method116()\nsimple.cpu.Methods2.method117()\nsimple.cpu.Methods2.method118()\nsimple.cpu.Methods2.method119()\nsimple.cpu.Methods2.method12()\nsimple.cpu.Methods2.method120()\nsimple.cpu.Methods2.method121()\nsimple.cpu.Methods2.method122()\nsimple.cpu.Methods2.method123()\nsimple.cpu.Methods2.method124()\nsimple.cpu.Methods2.method125()\nsimple.cpu.Methods2.method126()\nsimple.cpu.Methods2.method127()\nsimple.cpu.Methods2.method128()\nsimple.cpu.Methods2.method129()\nsimple.cpu.Methods2.method13()\nsimple.cpu.Methods2.method130()\nsimple.cpu.Methods2.method131()\nsimple.cpu.Methods2.method132()\nsimple.cpu.Methods2.method133()\nsimple.cpu.Methods2.method134()\nsimple.cpu.Methods2.method135()\nsimple.cpu.Methods2.method136()\nsimple.cpu.Methods2.method137()\nsimple.cpu.Methods2.method138()\nsimple.cpu.Methods2.method139()\nsimple.cpu.Methods2.method14()\nsimple.cpu.Methods2.method140()\nsimple.cpu.Methods2.method141()\nsimple.cpu.Methods2.method142()\nsimple.cpu.Methods2.method143()\nsimple.cpu.Methods2.method144()\nsimple.cpu.Methods2.method145()\nsimple.cpu.Methods2.method146()\nsimple.cpu.Methods2.method147()\nsimple.cpu.Methods2.method148()\nsimple.cpu.Methods2.method149()\nsimple.cpu.Methods2.method15()\nsimple.cpu.Methods2.method150()\nsimple.cpu.Methods2.method151()\nsimple.cpu.Methods2.method152()\nsimple.cpu.Methods2.method153()\nsimple.cpu.Methods2.method154()\nsimple.cpu.Methods2.method155()\nsimple.cpu.Methods2.method156()\nsimple.cpu.Methods2.method157()\nsimple.cpu.Methods2.method158()\nsimple.cpu.Methods2.method159()\nsimple.cpu.Methods2.method16()\nsimple.cpu.Methods2.method160()\nsimple.cpu.Methods2.method161()\nsimple.cpu.Methods2.method162()\nsimple.cpu.Methods2.method163()\nsimple.cpu.Methods2.method164()\nsimple.cpu.Methods2.method165()\nsimple.cpu.Methods2.method166()\nsimple.cpu.Methods2.method167()\nsimple.cpu.Methods2.method168()\nsimple.cpu.Methods2.method169()\nsimple.cpu.Methods2.method17()\nsimple.cpu.Methods2.method170()\nsimple.cpu.Methods2.method171()\nsimple.cpu.Methods2.method172()\nsimple.cpu.Methods2.method173()\nsimple.cpu.Methods2.method174()\nsimple.cpu.Methods2.method175()\nsimple.cpu.Methods2.method176()\nsimple.cpu.Methods2.method177()\nsimple.cpu.Methods2.method178()\nsimple.cpu.Methods2.method179()\nsimple.cpu.Methods2.method18()\nsimple.cpu.Methods2.method180()\nsimple.cpu.Methods2.method181()\nsimple.cpu.Methods2.method182()\nsimple.cpu.Methods2.method183()\nsimple.cpu.Methods2.method184()\nsimple.cpu.Methods2.method185()\nsimple.cpu.Methods2.method186()\nsimple.cpu.Methods2.method187()\nsimple.cpu.Methods2.method188()\nsimple.cpu.Methods2.method189()\nsimple.cpu.Methods2.method19()\nsimple.cpu.Methods2.method190()\nsimple.cpu.Methods2.method191()\nsimple.cpu.Methods2.method192()\nsimple.cpu.Methods2.method193()\nsimple.cpu.Methods2.method194()\nsimple.cpu.Methods2.method195()\nsimple.cpu.Methods2.method196()\nsimple.cpu.Methods2.method197()\nsimple.cpu.Methods2.method198()\nsimple.cpu.Methods2.method199()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentNotSpawnedThreads.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentNotSpawnedThreadsServer.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentRootMethod.pass",
    "content": "simple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsInstrumentRootMethodServer.pass",
    "content": "simple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsLimitedThreads.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsLimitedThreadsServer.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsSampledProfilingEager.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsSampledProfilingLazy.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsSampledProfilingServerEager.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsSampledProfilingServerLazy.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsSampledProfilingServerTotal.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest/testSettingsSampledProfilingTotal.pass",
    "content": "simple.cpu.Bean.<init>()\nsimple.cpu.Bean.emptyMethod()\nsimple.cpu.Bean.run100()\nsimple.cpu.Bean.run1000()\nsimple.cpu.Bean.run20()\nsimple.cpu.Bean.setName(String)\nsimple.cpu.CPU1.main(String[])\nsimple.cpu.CPUThread.<init>()\nsimple.cpu.CPUThread.run()\nsimple.cpu.CPUThread.run512()\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/CPUSnapshotTest/testMethods.pass",
    "content": "simple.cpu.Methods.method27()                                 2  \n simple.cpu.Methods.method26()                                2  \n  simple.cpu.Methods.method25()                               2  \n   simple.cpu.Methods.method24()                              2  \n    simple.cpu.Methods.method23()                             2  \n     simple.cpu.Methods.method22()                            2  \n      simple.cpu.Methods.method21()                           2  \n       simple.cpu.Methods.method20()                          2  \n        simple.cpu.Methods.method19()                         2  \n         simple.cpu.Methods.method18()                        2  \n          simple.cpu.Methods.method17()                       2  \n           simple.cpu.Methods.method16()                      2  \n            simple.cpu.Methods.method15()                     2  \n             simple.cpu.Methods.method14()                    2  \n              simple.cpu.Methods.method13()                   2  \n               simple.cpu.Methods.method12()                  2  \n                simple.cpu.Methods.method11()                 2  \n                 simple.cpu.Methods.method10()                2  \n                  simple.cpu.Methods.method9()                2  \n                   simple.cpu.Methods.method8()               2  \n                    simple.cpu.Methods.method7()              2  \n                     simple.cpu.Methods.method6()             2  \n                      simple.cpu.Methods.method5()            2  \n                       simple.cpu.Methods.method4()           2  \n                        simple.cpu.Methods.method3()          2  \n                         simple.cpu.Methods.method2()         2  \n                          simple.cpu.Methods.method1()        2  \n                           simple.cpu.Methods.method0()       2  \n                            simple.cpu.Methods.main(String[]) 1  \n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/CPUSnapshotTest/testMethodsServer.pass",
    "content": "simple.cpu.Methods.method27()                                 2  \n simple.cpu.Methods.method26()                                2  \n  simple.cpu.Methods.method25()                               2  \n   simple.cpu.Methods.method24()                              2  \n    simple.cpu.Methods.method23()                             2  \n     simple.cpu.Methods.method22()                            2  \n      simple.cpu.Methods.method21()                           2  \n       simple.cpu.Methods.method20()                          2  \n        simple.cpu.Methods.method19()                         2  \n         simple.cpu.Methods.method18()                        2  \n          simple.cpu.Methods.method17()                       2  \n           simple.cpu.Methods.method16()                      2  \n            simple.cpu.Methods.method15()                     2  \n             simple.cpu.Methods.method14()                    2  \n              simple.cpu.Methods.method13()                   2  \n               simple.cpu.Methods.method12()                  2  \n                simple.cpu.Methods.method11()                 2  \n                 simple.cpu.Methods.method10()                2  \n                  simple.cpu.Methods.method9()                2  \n                   simple.cpu.Methods.method8()               2  \n                    simple.cpu.Methods.method7()              2  \n                     simple.cpu.Methods.method6()             2  \n                      simple.cpu.Methods.method5()            2  \n                       simple.cpu.Methods.method4()           2  \n                        simple.cpu.Methods.method3()          2  \n                         simple.cpu.Methods.method2()         2  \n                          simple.cpu.Methods.method1()        2  \n                           simple.cpu.Methods.method0()       2  \n                            simple.cpu.Methods.main(String[]) 1  \n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/CPUSnapshotTest/testNoThreads.pass",
    "content": "simple.cpu.Region.run100()                                    23 \n when called from simple.cpu.Region.<init>()                  3  \n  simple.cpu.Region.<init>()                                  1  \n   simple.cpu.Region.main(String[])                           1  \n when called from simple.cpu.Region.run2000()                 20 \n  simple.cpu.Region.run2000()                                 1  \n   simple.cpu.Region.<init>()                                 1  \n    simple.cpu.Region.main(String[])                          1  \n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/CPUSnapshotTest/testSimple.pass",
    "content": "simple.CPU.test20()                                           5  \n simple.CPU.test500()                                         5  \n  simple.CPU.test1000()                                       5  \n   simple.CPU.main(String[])                                  1  \n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/CPUSnapshotTest/testSimpleServer.pass",
    "content": "simple.CPU.test20()                                           5  \n simple.CPU.test500()                                         5  \n  simple.CPU.test1000()                                       5  \n   simple.CPU.main(String[])                                  1  \n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/CPUSnapshotTest/testThreads.pass",
    "content": "simple.cpu.Region.run100()                                    76 \n when called from simple.cpu.Region.<init>()                  6  \n  simple.cpu.Region.<init>()                                  2  \n   when called from simple.cpu.Region.main(String[])          1  \n    simple.cpu.Region.main(String[])                          1  \n   when called from simple.cpu.AnotherThread.run()            1  \n    simple.cpu.AnotherThread.run()                            1  \n when called from simple.cpu.Region.run2000()                 60 \n  simple.cpu.Region.run2000()                                 3  \n   when called from simple.cpu.Region.<init>()                2  \n    simple.cpu.Region.<init>()                                2  \n     when called from simple.cpu.Region.main(String[])        1  \n      simple.cpu.Region.main(String[])                        1  \n     when called from simple.cpu.AnotherThread.run()          1  \n      simple.cpu.AnotherThread.run()                          1  \n   when called from simple.cpu.AnotherThread.run()            1  \n    simple.cpu.AnotherThread.run()                            1  \n when called from simple.cpu.AnotherThread.run()              10 \n  simple.cpu.AnotherThread.run()                              1  \n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/CPUSnapshotTest/testThreadsServer.pass",
    "content": "simple.cpu.Region.run100()                                    76 \n when called from simple.cpu.Region.<init>()                  6  \n  simple.cpu.Region.<init>()                                  2  \n   when called from simple.cpu.Region.main(String[])          1  \n    simple.cpu.Region.main(String[])                          1  \n   when called from simple.cpu.AnotherThread.run()            1  \n    simple.cpu.AnotherThread.run()                            1  \n when called from simple.cpu.Region.run2000()                 60 \n  simple.cpu.Region.run2000()                                 3  \n   when called from simple.cpu.Region.<init>()                2  \n    simple.cpu.Region.<init>()                                2  \n     when called from simple.cpu.Region.main(String[])        1  \n      simple.cpu.Region.main(String[])                        1  \n     when called from simple.cpu.AnotherThread.run()          1  \n      simple.cpu.AnotherThread.run()                          1  \n   when called from simple.cpu.AnotherThread.run()            1  \n    simple.cpu.AnotherThread.run()                            1  \n when called from simple.cpu.AnotherThread.run()              10 \n  simple.cpu.AnotherThread.run()                              1  \n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/CPUSnapshotTest/testWaits.pass",
    "content": "simple.cpu.WaitingTest.method1000()                           2  \n simple.cpu.WaitingTest.main(String[])                        1  \n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/CPUSnapshotTest/testWaitsServer.pass",
    "content": "simple.cpu.WaitingTest.method1000()                           2  \n simple.cpu.WaitingTest.main(String[])                        1  \n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/BasicTest/testSettingsAllocations.pass",
    "content": "Name                            DCount  \nsimple.memory.Bean              4094    \nsimple.memory.Memory1           1       \n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/BasicTest/testSettingsAllocationsServer.pass",
    "content": "Name                            DCount  \nsimple.memory.Bean              4094    \nsimple.memory.Memory1           1       \n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/BasicTest/testSettingsAllocationsStackTraces.pass",
    "content": "Name                            DCount  \nsimple.memory.Bean              4094    \nsimple.memory.Memory1           1       \n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/BasicTest/testSettingsAllocationsStackTracesServer.pass",
    "content": "Name                            DCount  \nsimple.memory.Bean              4094    \nsimple.memory.Memory1           1       \n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/BasicTest/testSettingsDefault.pass",
    "content": "Name                            DCount  \nsimple.Data                     2000    \nsimple.Memory                   1       \n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/BasicTest/testSettingsLiveness.pass",
    "content": "Name                            LiveObjs  Allocs  \nsimple.memory.Bean              2047      4094    \nsimple.memory.Memory1           0         1       \n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/BasicTest/testSettingsLivenessServer.pass",
    "content": "Name                            LiveObjs  Allocs  \nsimple.memory.Bean              2047      4094    \nsimple.memory.Memory1           0         1       \n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/BasicTest/testSettingsLivenessStackTraces.pass",
    "content": "Name                            LiveObjs  Allocs  \nsimple.memory.Bean              2047      4094    \nsimple.memory.Memory1           0         1       \n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/BasicTest/testSettingsLivenessStackTracesServer.pass",
    "content": "Name                            LiveObjs  Allocs  \nsimple.memory.Bean              2047      4094    \nsimple.memory.Memory1           0         1       \n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/MemorySnapshotTest/testSettingsAllocations.pass",
    "content": "Does not contain stacks.\nName                            Objects \nsimple.memory.Bean              4094    \nsimple.memory.Memory1           1       \n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/MemorySnapshotTest/testSettingsAllocationsServer.pass",
    "content": "Does not contain stacks.\nName                            Objects \nsimple.memory.Bean              4094    \nsimple.memory.Memory1           1       \n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/MemorySnapshotTest/testSettingsAllocationsStackTraces.pass",
    "content": "Contains stacks.\nName                            Objects \nsimple.memory.Bean              4094    \nsimple.memory.Memory1           1       \n\nsimple.memory.Bean\n simple.memory.Memory1.add()\n  simple.memory.Memory1.main(String[])\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/MemorySnapshotTest/testSettingsAllocationsStackTracesServer.pass",
    "content": "Contains stacks.\nName                            Objects \nsimple.memory.Bean              4094    \nsimple.memory.Memory1           1       \n\nsimple.memory.Bean\n simple.memory.Memory1.add()\n  simple.memory.Memory1.main(String[])\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/MemorySnapshotTest/testSettingsLiveness.pass",
    "content": "Does not contain stacks.\nName                            LiveObjs  Allocs  Total   \nsimple.memory.Bean              2047      4094    4094    \nsimple.memory.Memory1           0         1       1       \n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/MemorySnapshotTest/testSettingsLivenessServer.pass",
    "content": "Does not contain stacks.\nName                            LiveObjs  Allocs  Total   \nsimple.memory.Bean              2047      4094    4094    \nsimple.memory.Memory1           0         1       1       \n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/MemorySnapshotTest/testSettingsLivenessStackTraces.pass",
    "content": "Contains stacks.\nName                            LiveObjs  Allocs  Total   \nsimple.memory.Bean              2047      4094    4094    \nsimple.memory.Memory1           0         1       1       \n\nsimple.memory.Bean\n simple.memory.Memory1.add()\n  simple.memory.Memory1.main(String[])\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/MemorySnapshotTest/testSettingsLivenessStackTracesServer.pass",
    "content": "Contains stacks.\nName                            LiveObjs  Allocs  Total   \nsimple.memory.Bean              2047      4094    4094    \nsimple.memory.Memory1           0         1       1       \n\nsimple.memory.Bean\n simple.memory.Memory1.add()\n  simple.memory.Memory1.main(String[])\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/monitor/BasicTest/testBasic.pass",
    "content": "Consumer 1\nConsumer 2\nFinalizer\nProducer 1\nProducer 2\nReference Handler\nSignal Dispatcher\nmain\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/monitor/BasicTest/testBasicCPU.pass",
    "content": "Consumer 1\nConsumer 2\nFinalizer\nProducer 1\nProducer 2\nReference Handler\nSignal Dispatcher\nmain\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/monitor/BasicTest/testBasicMemory.pass",
    "content": "Consumer 1\nConsumer 2\nFinalizer\nProducer 1\nProducer 2\nReference Handler\nSignal Dispatcher\nmain\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/monitor/BasicTest/testCascadeThreads.pass",
    "content": "Cascade 1\nCascade 2\nCascade 3\nCascade 4\nCascade 5\nFinalizer\nReference Handler\nSignal Dispatcher\nmain\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/monitor/BasicTest/testCascadeThreadsCPU.pass",
    "content": "Cascade 1\nCascade 2\nCascade 3\nCascade 4\nCascade 5\nFinalizer\nReference Handler\nSignal Dispatcher\nmain\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/monitor/BasicTest/testCascadeThreadsMemory.pass",
    "content": "Cascade 1\nCascade 2\nCascade 3\nCascade 4\nCascade 5\nFinalizer\nReference Handler\nSignal Dispatcher\nmain\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/monitor/BasicTest/testGUICPU.pass",
    "content": "AWT-EventQueue-0\nAWT-Shutdown\nAWT-XAWT\nFinalizer\nImage Fetcher 3\nIntro\nJava2D Disposer\nReference Handler\nSignal Dispatcher\nTimerQueue\nmain\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/perf/InstrumentationTest/testJ2SE.pass",
    "content": "Number of Classes: 24\nInstrumented Classes: 24\nInstrumented Methods: 1196\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/perf/InstrumentationTest/testJaxb.pass",
    "content": "Number of Classes: 1125\nInstrumented Classes: 940\nInstrumented Methods: 7541\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/perf/InstrumentationTest/testJaxbNoGettersEmpties.pass",
    "content": "Number of Classes: 1125\nInstrumented Classes: 940\nInstrumented Methods: 6798\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/perf/InstrumentationTest/testSimple.pass",
    "content": "Number of Classes: 1\nInstrumented Classes: 1\nInstrumented Methods: 4\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/perf/InstrumentationTest/testSimpleJ2SE.pass",
    "content": "Number of Classes: 24\nInstrumented Classes: 24\nInstrumented Methods: 1196\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/perf/InstrumentationTest/testSimpleNoEmpties.pass",
    "content": "Number of Classes: 1\nInstrumented Classes: 1\nInstrumented Methods: 3\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/perf/InstrumentationTest/testSimpleNoGetters.pass",
    "content": "Number of Classes: 1\nInstrumented Classes: 1\nInstrumented Methods: 3\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/profilingpoints/BasicTest/testEmpytBlock.pass",
    "content": "Stopwatches:\nsimple.cpu.Region:33->34, 75 pass(es)\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/profilingpoints/BasicTest/testFirstEmptyLineEndMethod.pass",
    "content": "Stopwatches:\nsimple.cpu.Region:26->30, 3 pass(es)\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/profilingpoints/BasicTest/testLinesCodeEmptyBlockEmptyLine.pass",
    "content": "Stopwatches:\nsimple.cpu.Region:38->40, 5 pass(es)\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/profilingpoints/BasicTest/testLinesWithWait.pass",
    "content": "Stopwatches:\nsimple.cpu.WaitingTest:17->40, 2 pass(es)\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/profilingpoints/BasicTest/testSimpleBlock.pass",
    "content": "Stopwatches:\nsimple.cpu.Region:27->29, 3 pass(es)\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/profilingpoints/BasicTest/testSimpleBlockServer.pass",
    "content": "Stopwatches:\nsimple.cpu.Region:27->29, 3 pass(es)\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/profilingpoints/BasicTest/testStartMethodMultiCommands.pass",
    "content": "Stopwatches:\nsimple.cpu.Region:19->20, 2 pass(es)\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/profilingpoints/BasicTest/testWholeMethod.pass",
    "content": "Stopwatches:\nsimple.cpu.Region:32->35, 75 pass(es)\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/wireio/BasicTest/testComplexCommands.pass",
    "content": "Server start to listen on port 5140\n received command Async message: positive, message = async message text\n received command CLASS_LOADED, className: java.lang.String, threadInCallGraph: true, thisAndParentLoaderData: 0, 0, 0, classFileBytes: null\n received command ROOT_CLASS_LOADED, classes: 1\n received command SET_UNCHANGEABLE_INSTR_PARAMS, remoteProfiling: false, absoluteTimerOn: true, threadCPUTimerOn: false, instrScheme: 0, codeRegionCPUResBufSize: 1024\n received command METHOD_INVOKED_FIRST_TIME, methodId: 0\n received command GET_METHOD_NAMES_FOR_JMETHOD_IDS, length: 1\n received command METHOD_LOADED, className: java.lang.String, classLoaderId: 7, methodName: toString(), methodSignature: \n received command EVENT_BUFFER_DUMPED, bufSize: 1024\n received command SET_CHANGEABLE_INSTR_PARAMS, lockContentionMonitoringEnabled: false, nProfiledThreadsLimit: 32, maxStringLength: 1024, stackDepthLimit: 12, samplingInterval: 10, objAllocStackSamplingInterval: 5, objAllocStackSamplingDepth: 10, runGCOnGetResultsInMemoryProfiling: true, waitTrackingEnabled: true, sleepTrackingEnabled: true, threadsSamplingEnabled: true, threadsSamplingFrequency: 10\n received command INITIATE_PROFILING, instrType = 0\n received command INSTRUMENT_METHOD_GROUP 1 classes.\n received command GET_DEFINING_CLASSLOADER, className: java.lang.String, classLoaderId: 1\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/wireio/BasicTest/testComplexResponse.pass",
    "content": "Server start to listen on port 5140\n received object org.graalvm.visualvm.lib.jfluid.wireprotocol.CodeRegionCPUResultsResponse CodeRegionCPUResultsResponse, length: 3, CODE_REGION_CPU_RESULTS Ok, yes\n received object org.graalvm.visualvm.lib.jfluid.wireprotocol.ThreadLivenessStatusResponse ThreadLivenessStatusResponse, THREAD_LIVENESS_STATUS Ok, yes\n received object org.graalvm.visualvm.lib.jfluid.wireprotocol.DumpResultsResponse DumpResultsResponse, timeStamp: 200508181215, DUMP_RESULTS Ok, yes\n received object org.graalvm.visualvm.lib.jfluid.wireprotocol.InstrumentMethodGroupResponse InstrumentMethodGroupResponse 1 classes.\n received object org.graalvm.visualvm.lib.jfluid.wireprotocol.MethodNamesResponse METHOD_NAMES Ok, yes\n received object org.graalvm.visualvm.lib.jfluid.wireprotocol.DefiningLoaderResponse DefiningLoaderResponse, loaderId: 1, DEFINING_LOADER Ok, yes\n received object org.graalvm.visualvm.lib.jfluid.wireprotocol.CalibrationDataResponse CalibrationDataResponse, CALIBRATION_DATA Ok, yes\n received object org.graalvm.visualvm.lib.jfluid.wireprotocol.InternalStatsResponse InternalStatsResponse, INTERNAL_STATS Ok, yes\n received object org.graalvm.visualvm.lib.jfluid.wireprotocol.ObjectAllocationResultsResponse ObjectAllocationResultsResponse, entries: 1, OBJECT_ALLOCATION_RESULTS Ok, yes\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/wireio/BasicTest/testSimpleCommands.pass",
    "content": "Server start to listen on port 5140\n received command CHECK_CONNECTION\n received command START_TARGET_APP\n received command CLASS_LOADED\n received command SET_CHANGEABLE_INSTR_PARAMS\n received command SET_UNCHANGEABLE_INSTR_PARAMS\n received command CPU_RESULTS_EXIST\n received command INSTRUMENT_METHOD_GROUP\n received command GET_CODE_REGION_CPU_RESULTS\n received command DEACTIVATE_INJECTED_CODE\n received command SUSPEND_TARGET_APP\n received command RESUME_TARGET_APP\n received command TERMINATE_TARGET_JVM\n received command INITIATE_PROFILING\n received command MESSAGE\n received command SHUTDOWN_OK\n received command GET_THREAD_LIVENESS_STATUS\n received command ROOT_CLASS_LOADED\n received command SHUTDOWN_INITIATED\n received command SHUTDOWN_COMPLETED\n received command INSTRUMENT_REFLECTION\n received command DEINSTRUMENT_REFLECTION\n received command METHOD_LOADED\n received command METHOD_INVOKED_FIRST_TIME\n received command GET_INTERNAL_STATS\n received command DETACH\n received command EVENT_BUFFER_DUMPED\n received command DUMP_EXISTING_RESULTS\n received command GET_VM_PROPERTIES\n received command RESET_PROFILER_COLLECTORS\n received command GET_OBJECT_ALLOCATION_RESULTS\n received command GET_METHOD_NAMES_FOR_JMETHOD_IDS\n received command MONITORED_NUMBERS\n received command RUN_GC\n received command RUN_CALIBRATION_AND_GET_DATA\n received command GET_DEFINING_CLASSLOADER\n received command CLASS_LOADER_UNLOADING\n received command GET_STORED_CALIBRATION_DATA\n received command RESULTS_AVAILABLE\n received command TAKE_SNAPSHOT\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/wireio/BasicTest/testSimpleResponse.pass",
    "content": "Server start to listen on port 5140\n received object org.graalvm.visualvm.lib.jfluid.wireprotocol.Response NO TYPE Error, Error message.\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/goldenfiles/org/graalvm/visualvm/lib/jfluid/tests/jfluid/wireio/BasicTest/testUnknownSimpleCommand.pass",
    "content": "Server start to listen on port 5140\n received command Unknown command\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/build-before-profiler.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See commented blocks below for -->\n<!-- some examples of how to customize the build. -->\n<!-- (If you delete it and reopen the project it will be recreated.) -->\n<project name=\"j2se-simple\" default=\"default\" basedir=\".\">\n    <description>Builds, tests, and runs the project j2se-simple.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n\n    <import file=\"nbproject/profiler-build-impl.xml\"/>\n    <target name=\"-post-jar\">\n        <move file=\"${dist.jar}\" todir=\"distrib\"/>\n    </target>\n   <!--\n\n    There exist several targets which are by default empty and which can be \n    used for execution of your tasks. These targets are usually executed \n    before and after some main targets. They are: \n\n      -pre-init:                 called before initialization of project properties\n      -post-init:                called after initialization of project properties\n      -pre-compile:              called before javac compilation\n      -post-compile:             called after javac compilation\n      -pre-compile-single:       called before javac compilation of single file\n      -post-compile-single:      called after javac compilation of single file\n      -pre-compile-test:         called before javac compilation of JUnit tests\n      -post-compile-test:        called after javac compilation of JUnit tests\n      -pre-compile-test-single:  called before javac compilation of single JUnit test\n      -post-compile-test-single: called after javac compilation of single JUunit test\n      -pre-jar:                  called before JAR building\n      -post-jar:                 called after JAR building\n      -post-clean:               called after cleaning build products\n\n    (Targets beginning with '-' are not intended to be called on their own.)\n\n    Example of inserting an obfuscator after compilation could look like this:\n\n        <target name=\"-post-compile\">\n            <obfuscate>\n                <fileset dir=\"${build.classes.dir}\"/>\n            </obfuscate>\n        </target>\n\n    For list of available properties check the imported \n    nbproject/build-impl.xml file. \n\n\n    Another way to customize the build is by overriding existing main targets.\n    The targets of interest are: \n\n      -init-macrodef-javac:     defines macro for javac compilation\n      -init-macrodef-junit:     defines macro for junit execution\n      -init-macrodef-debug:     defines macro for class debugging\n      -init-macrodef-java:      defines macro for class execution\n      -do-jar-with-manifest:    JAR building (if you are using a manifest)\n      -do-jar-without-manifest: JAR building (if you are not using a manifest)\n      run:                      execution of project \n      -javadoc-build:           Javadoc generation\n      test-report:              JUnit report generation\n\n    An example of overriding the target for project execution could look like this:\n\n        <target name=\"run\" depends=\"j2se-simple-impl.jar\">\n            <exec dir=\"bin\" executable=\"launcher.exe\">\n                <arg file=\"${dist.jar}\"/>\n            </exec>\n        </target>\n\n    Notice that the overridden target depends on the jar target and not only on \n    the compile target as the regular run target does. Again, for a list of available \n    properties which you can use, check the target you are overriding in the\n    nbproject/build-impl.xml file. \n\n    -->\n</project>\n\n\n\n\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See commented blocks below for -->\n<!-- some examples of how to customize the build. -->\n<!-- (If you delete it and reopen the project it will be recreated.) -->\n<project name=\"j2se-simple\" default=\"default\" basedir=\".\">\n    <description>Builds, tests, and runs the project j2se-simple.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n\n    <import file=\"nbproject/profiler-build-impl.xml\"/>\n    <import file=\"nbproject/profiler-build-impl.xml\"/>\n    <target name=\"-post-jar\">\n        <move file=\"${dist.jar}\" todir=\"distrib\"/>\n    </target>\n   <!--\n\n    There exist several targets which are by default empty and which can be \n    used for execution of your tasks. These targets are usually executed \n    before and after some main targets. They are: \n\n      -pre-init:                 called before initialization of project properties\n      -post-init:                called after initialization of project properties\n      -pre-compile:              called before javac compilation\n      -post-compile:             called after javac compilation\n      -pre-compile-single:       called before javac compilation of single file\n      -post-compile-single:      called after javac compilation of single file\n      -pre-compile-test:         called before javac compilation of JUnit tests\n      -post-compile-test:        called after javac compilation of JUnit tests\n      -pre-compile-test-single:  called before javac compilation of single JUnit test\n      -post-compile-test-single: called after javac compilation of single JUunit test\n      -pre-jar:                  called before JAR building\n      -post-jar:                 called after JAR building\n      -post-clean:               called after cleaning build products\n\n    (Targets beginning with '-' are not intended to be called on their own.)\n\n    Example of inserting an obfuscator after compilation could look like this:\n\n        <target name=\"-post-compile\">\n            <obfuscate>\n                <fileset dir=\"${build.classes.dir}\"/>\n            </obfuscate>\n        </target>\n\n    For list of available properties check the imported \n    nbproject/build-impl.xml file. \n\n\n    Another way to customize the build is by overriding existing main targets.\n    The targets of interest are: \n\n      -init-macrodef-javac:     defines macro for javac compilation\n      -init-macrodef-junit:     defines macro for junit execution\n      -init-macrodef-debug:     defines macro for class debugging\n      -init-macrodef-java:      defines macro for class execution\n      -do-jar-with-manifest:    JAR building (if you are using a manifest)\n      -do-jar-without-manifest: JAR building (if you are not using a manifest)\n      run:                      execution of project \n      -javadoc-build:           Javadoc generation\n      test-report:              JUnit report generation\n\n    An example of overriding the target for project execution could look like this:\n\n        <target name=\"run\" depends=\"j2se-simple-impl.jar\">\n            <exec dir=\"bin\" executable=\"launcher.exe\">\n                <arg file=\"${dist.jar}\"/>\n            </exec>\n        </target>\n\n    Notice that the overridden target depends on the jar target and not only on \n    the compile target as the regular run target does. Again, for a list of available \n    properties which you can use, check the target you are overriding in the\n    nbproject/build-impl.xml file. \n\n    -->\n</project>\n\n\n\n\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n\nFor the purpose of easier reading the script\nis divided into following sections:\n\n  - initialization\n  - compilation\n  - jar\n  - execution\n  - debugging\n  - javadoc\n  - junit compilation\n  - junit execution\n  - junit debugging\n  - applet\n  - cleanup\n\n        -->\n<project xmlns:j2seproject1=\"http://www.netbeans.org/ns/j2se-project/1\" xmlns:j2seproject3=\"http://www.netbeans.org/ns/j2se-project/3\" xmlns:jaxrpc=\"http://www.netbeans.org/ns/j2se-project/jax-rpc\" basedir=\"..\" default=\"default\" name=\"j2se-simple-impl\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <target depends=\"test,jar,javadoc\" description=\"Build and test whole project.\" name=\"default\"/>\n    <!-- \n                ======================\n                INITIALIZATION SECTION \n                ======================\n            -->\n    <target name=\"-pre-init\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target depends=\"-pre-init\" name=\"-init-private\">\n        <property file=\"nbproject/private/config.properties\"/>\n        <property file=\"nbproject/private/configs/${config}.properties\"/>\n        <property file=\"nbproject/private/private.properties\"/>\n    </target>\n    <target depends=\"-pre-init,-init-private\" name=\"-init-user\">\n        <property file=\"${user.properties.file}\"/>\n        <!-- The two properties below are usually overridden -->\n        <!-- by the active platform. Just a fallback. -->\n        <property name=\"default.javac.source\" value=\"1.4\"/>\n        <property name=\"default.javac.target\" value=\"1.4\"/>\n    </target>\n    <target depends=\"-pre-init,-init-private,-init-user\" name=\"-init-project\">\n        <property file=\"nbproject/configs/${config}.properties\"/>\n        <property file=\"nbproject/project.properties\"/>\n    </target>\n    <target depends=\"-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property\" name=\"-do-init\">\n        <available file=\"${manifest.file}\" property=\"manifest.available\"/>\n        <condition property=\"main.class.available\">\n            <and>\n                <isset property=\"main.class\"/>\n                <not>\n                    <equals arg1=\"${main.class}\" arg2=\"\" trim=\"true\"/>\n                </not>\n            </and>\n        </condition>\n        <condition property=\"manifest.available+main.class\">\n            <and>\n                <isset property=\"manifest.available\"/>\n                <isset property=\"main.class.available\"/>\n            </and>\n        </condition>\n        <condition property=\"do.mkdist\">\n            <and>\n                <isset property=\"libs.CopyLibs.classpath\"/>\n                <not>\n                    <istrue value=\"${mkdist.disabled}\"/>\n                </not>\n            </and>\n        </condition>\n        <condition property=\"manifest.available+main.class+mkdist.available\">\n            <and>\n                <istrue value=\"${manifest.available+main.class}\"/>\n                <isset property=\"do.mkdist\"/>\n            </and>\n        </condition>\n        <condition property=\"manifest.available+mkdist.available\">\n            <and>\n                <istrue value=\"${manifest.available}\"/>\n                <isset property=\"do.mkdist\"/>\n            </and>\n        </condition>\n        <condition property=\"manifest.available-mkdist.available\">\n            <or>\n                <istrue value=\"${manifest.available}\"/>\n                <isset property=\"do.mkdist\"/>\n            </or>\n        </condition>\n        <condition property=\"manifest.available+main.class-mkdist.available\">\n            <or>\n                <istrue value=\"${manifest.available+main.class}\"/>\n                <isset property=\"do.mkdist\"/>\n            </or>\n        </condition>\n        <condition property=\"have.tests\">\n            <or>\n                <available file=\"${test.src.dir}\"/>\n            </or>\n        </condition>\n        <condition property=\"have.sources\">\n            <or>\n                <available file=\"${src.dir}\"/>\n            </or>\n        </condition>\n        <condition property=\"netbeans.home+have.tests\">\n            <and>\n                <isset property=\"netbeans.home\"/>\n                <isset property=\"have.tests\"/>\n            </and>\n        </condition>\n        <condition property=\"no.javadoc.preview\">\n            <and>\n                <isset property=\"javadoc.preview\"/>\n                <isfalse value=\"${javadoc.preview}\"/>\n            </and>\n        </condition>\n        <property name=\"run.jvmargs\" value=\"\"/>\n        <property name=\"javac.compilerargs\" value=\"\"/>\n        <property name=\"work.dir\" value=\"${basedir}\"/>\n        <condition property=\"no.deps\">\n            <and>\n                <istrue value=\"${no.dependencies}\"/>\n            </and>\n        </condition>\n        <property name=\"javac.debug\" value=\"true\"/>\n        <property name=\"javadoc.preview\" value=\"true\"/>\n        <property name=\"application.args\" value=\"\"/>\n        <property name=\"source.encoding\" value=\"${file.encoding}\"/>\n        <property name=\"runtime.encoding\" value=\"${source.encoding}\"/>\n        <condition property=\"javadoc.encoding.used\" value=\"${javadoc.encoding}\">\n            <and>\n                <isset property=\"javadoc.encoding\"/>\n                <not>\n                    <equals arg1=\"${javadoc.encoding}\" arg2=\"\"/>\n                </not>\n            </and>\n        </condition>\n        <property name=\"javadoc.encoding.used\" value=\"${source.encoding}\"/>\n        <property name=\"includes\" value=\"**\"/>\n        <property name=\"excludes\" value=\"\"/>\n        <property name=\"do.depend\" value=\"false\"/>\n        <condition property=\"do.depend.true\">\n            <istrue value=\"${do.depend}\"/>\n        </condition>\n        <path id=\"endorsed.classpath.path\" path=\"${endorsed.classpath}\"/>\n        <condition else=\"\" property=\"endorsed.classpath.cmd.line.arg\" value=\"-Xbootclasspath/p:'${toString:endorsed.classpath.path}'\">\n            <length length=\"0\" string=\"${endorsed.classpath}\" when=\"greater\"/>\n        </condition>\n        <property name=\"javac.fork\" value=\"false\"/>\n    </target>\n    <target name=\"-post-init\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target depends=\"-pre-init,-init-private,-init-user,-init-project,-do-init\" name=\"-init-check\">\n        <fail unless=\"src.dir\">Must set src.dir</fail>\n        <fail unless=\"test.src.dir\">Must set test.src.dir</fail>\n        <fail unless=\"build.dir\">Must set build.dir</fail>\n        <fail unless=\"dist.dir\">Must set dist.dir</fail>\n        <fail unless=\"build.classes.dir\">Must set build.classes.dir</fail>\n        <fail unless=\"dist.javadoc.dir\">Must set dist.javadoc.dir</fail>\n        <fail unless=\"build.test.classes.dir\">Must set build.test.classes.dir</fail>\n        <fail unless=\"build.test.results.dir\">Must set build.test.results.dir</fail>\n        <fail unless=\"build.classes.excludes\">Must set build.classes.excludes</fail>\n        <fail unless=\"dist.jar\">Must set dist.jar</fail>\n    </target>\n    <target name=\"-init-macrodef-property\">\n        <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/j2se-project/1\">\n            <attribute name=\"name\"/>\n            <attribute name=\"value\"/>\n            <sequential>\n                <property name=\"@{name}\" value=\"${@{value}}\"/>\n            </sequential>\n        </macrodef>\n    </target>\n    <target name=\"-init-macrodef-javac\">\n        <macrodef name=\"javac\" uri=\"http://www.netbeans.org/ns/j2se-project/3\">\n            <attribute default=\"${src.dir}\" name=\"srcdir\"/>\n            <attribute default=\"${build.classes.dir}\" name=\"destdir\"/>\n            <attribute default=\"${javac.classpath}\" name=\"classpath\"/>\n            <attribute default=\"${includes}\" name=\"includes\"/>\n            <attribute default=\"${excludes}\" name=\"excludes\"/>\n            <attribute default=\"${javac.debug}\" name=\"debug\"/>\n            <attribute default=\"${empty.dir}\" name=\"sourcepath\"/>\n            <attribute default=\"${empty.dir}\" name=\"gensrcdir\"/>\n            <element name=\"customize\" optional=\"true\"/>\n            <sequential>\n                <property location=\"${build.dir}/empty\" name=\"empty.dir\"/>\n                <mkdir dir=\"${empty.dir}\"/>\n                <javac debug=\"@{debug}\" deprecation=\"${javac.deprecation}\" destdir=\"@{destdir}\" encoding=\"${source.encoding}\" excludes=\"@{excludes}\" fork=\"${javac.fork}\" includeantruntime=\"false\" includes=\"@{includes}\" source=\"${javac.source}\" sourcepath=\"@{sourcepath}\" srcdir=\"@{srcdir}\" target=\"${javac.target}\" tempdir=\"${java.io.tmpdir}\">\n                    <src>\n                        <dirset dir=\"@{gensrcdir}\" erroronmissingdir=\"false\">\n                            <include name=\"*\"/>\n                        </dirset>\n                    </src>\n                    <classpath>\n                        <path path=\"@{classpath}\"/>\n                    </classpath>\n                    <compilerarg line=\"${endorsed.classpath.cmd.line.arg}\"/>\n                    <compilerarg line=\"${javac.compilerargs}\"/>\n                    <customize/>\n                </javac>\n            </sequential>\n        </macrodef>\n        <macrodef name=\"depend\" uri=\"http://www.netbeans.org/ns/j2se-project/3\">\n            <attribute default=\"${src.dir}\" name=\"srcdir\"/>\n            <attribute default=\"${build.classes.dir}\" name=\"destdir\"/>\n            <attribute default=\"${javac.classpath}\" name=\"classpath\"/>\n            <sequential>\n                <depend cache=\"${build.dir}/depcache\" destdir=\"@{destdir}\" excludes=\"${excludes}\" includes=\"${includes}\" srcdir=\"@{srcdir}\">\n                    <classpath>\n                        <path path=\"@{classpath}\"/>\n                    </classpath>\n                </depend>\n            </sequential>\n        </macrodef>\n        <macrodef name=\"force-recompile\" uri=\"http://www.netbeans.org/ns/j2se-project/3\">\n            <attribute default=\"${build.classes.dir}\" name=\"destdir\"/>\n            <sequential>\n                <fail unless=\"javac.includes\">Must set javac.includes</fail>\n                <pathconvert pathsep=\",\" property=\"javac.includes.binary\">\n                    <path>\n                        <filelist dir=\"@{destdir}\" files=\"${javac.includes}\"/>\n                    </path>\n                    <globmapper from=\"*.java\" to=\"*.class\"/>\n                </pathconvert>\n                <delete>\n                    <files includes=\"${javac.includes.binary}\"/>\n                </delete>\n            </sequential>\n        </macrodef>\n    </target>\n    <target name=\"-init-macrodef-junit\">\n        <macrodef name=\"junit\" uri=\"http://www.netbeans.org/ns/j2se-project/3\">\n            <attribute default=\"${includes}\" name=\"includes\"/>\n            <attribute default=\"${excludes}\" name=\"excludes\"/>\n            <attribute default=\"**\" name=\"testincludes\"/>\n            <sequential>\n                <junit dir=\"${work.dir}\" errorproperty=\"tests.failed\" failureproperty=\"tests.failed\" fork=\"true\" showoutput=\"true\" tempdir=\"${build.dir}\">\n                    <batchtest todir=\"${build.test.results.dir}\">\n                        <fileset dir=\"${test.src.dir}\" excludes=\"@{excludes},${excludes}\" includes=\"@{includes}\">\n                            <filename name=\"@{testincludes}\"/>\n                        </fileset>\n                    </batchtest>\n                    <classpath>\n                        <path path=\"${run.test.classpath}\"/>\n                    </classpath>\n                    <syspropertyset>\n                        <propertyref prefix=\"test-sys-prop.\"/>\n                        <mapper from=\"test-sys-prop.*\" to=\"*\" type=\"glob\"/>\n                    </syspropertyset>\n                    <formatter type=\"brief\" usefile=\"false\"/>\n                    <formatter type=\"xml\"/>\n                    <jvmarg line=\"${endorsed.classpath.cmd.line.arg}\"/>\n                    <jvmarg line=\"${run.jvmargs}\"/>\n                </junit>\n            </sequential>\n        </macrodef>\n    </target>\n    <target depends=\"-init-debug-args\" name=\"-init-macrodef-nbjpda\">\n        <macrodef name=\"nbjpdastart\" uri=\"http://www.netbeans.org/ns/j2se-project/1\">\n            <attribute default=\"${main.class}\" name=\"name\"/>\n            <attribute default=\"${debug.classpath}\" name=\"classpath\"/>\n            <attribute default=\"\" name=\"stopclassname\"/>\n            <sequential>\n                <nbjpdastart addressproperty=\"jpda.address\" name=\"@{name}\" stopclassname=\"@{stopclassname}\" transport=\"${debug-transport}\">\n                    <classpath>\n                        <path path=\"@{classpath}\"/>\n                    </classpath>\n                </nbjpdastart>\n            </sequential>\n        </macrodef>\n        <macrodef name=\"nbjpdareload\" uri=\"http://www.netbeans.org/ns/j2se-project/1\">\n            <attribute default=\"${build.classes.dir}\" name=\"dir\"/>\n            <sequential>\n                <nbjpdareload>\n                    <fileset dir=\"@{dir}\" includes=\"${fix.classes}\">\n                        <include name=\"${fix.includes}*.class\"/>\n                    </fileset>\n                </nbjpdareload>\n            </sequential>\n        </macrodef>\n    </target>\n    <target name=\"-init-debug-args\">\n        <property name=\"version-output\" value=\"java version &quot;${ant.java.version}\"/>\n        <condition property=\"have-jdk-older-than-1.4\">\n            <or>\n                <contains string=\"${version-output}\" substring=\"java version &quot;1.0\"/>\n                <contains string=\"${version-output}\" substring=\"java version &quot;1.1\"/>\n                <contains string=\"${version-output}\" substring=\"java version &quot;1.2\"/>\n                <contains string=\"${version-output}\" substring=\"java version &quot;1.3\"/>\n            </or>\n        </condition>\n        <condition else=\"-Xdebug\" property=\"debug-args-line\" value=\"-Xdebug -Xnoagent -Djava.compiler=none\">\n            <istrue value=\"${have-jdk-older-than-1.4}\"/>\n        </condition>\n        <condition else=\"dt_socket\" property=\"debug-transport-by-os\" value=\"dt_shmem\">\n            <os family=\"windows\"/>\n        </condition>\n        <condition else=\"${debug-transport-by-os}\" property=\"debug-transport\" value=\"${debug.transport}\">\n            <isset property=\"debug.transport\"/>\n        </condition>\n    </target>\n    <target depends=\"-init-debug-args\" name=\"-init-macrodef-debug\">\n        <macrodef name=\"debug\" uri=\"http://www.netbeans.org/ns/j2se-project/3\">\n            <attribute default=\"${main.class}\" name=\"classname\"/>\n            <attribute default=\"${debug.classpath}\" name=\"classpath\"/>\n            <element name=\"customize\" optional=\"true\"/>\n            <sequential>\n                <java classname=\"@{classname}\" dir=\"${work.dir}\" fork=\"true\">\n                    <jvmarg line=\"${endorsed.classpath.cmd.line.arg}\"/>\n                    <jvmarg line=\"${debug-args-line}\"/>\n                    <jvmarg value=\"-Xrunjdwp:transport=${debug-transport},address=${jpda.address}\"/>\n                    <jvmarg value=\"-Dfile.encoding=${runtime.encoding}\"/>\n                    <redirector errorencoding=\"${runtime.encoding}\" inputencoding=\"${runtime.encoding}\" outputencoding=\"${runtime.encoding}\"/>\n                    <jvmarg line=\"${run.jvmargs}\"/>\n                    <classpath>\n                        <path path=\"@{classpath}\"/>\n                    </classpath>\n                    <syspropertyset>\n                        <propertyref prefix=\"run-sys-prop.\"/>\n                        <mapper from=\"run-sys-prop.*\" to=\"*\" type=\"glob\"/>\n                    </syspropertyset>\n                    <customize/>\n                </java>\n            </sequential>\n        </macrodef>\n    </target>\n    <target name=\"-init-macrodef-java\">\n        <macrodef name=\"java\" uri=\"http://www.netbeans.org/ns/j2se-project/1\">\n            <attribute default=\"${main.class}\" name=\"classname\"/>\n            <attribute default=\"${run.classpath}\" name=\"classpath\"/>\n            <element name=\"customize\" optional=\"true\"/>\n            <sequential>\n                <java classname=\"@{classname}\" dir=\"${work.dir}\" fork=\"true\">\n                    <jvmarg line=\"${endorsed.classpath.cmd.line.arg}\"/>\n                    <jvmarg value=\"-Dfile.encoding=${runtime.encoding}\"/>\n                    <redirector errorencoding=\"${runtime.encoding}\" inputencoding=\"${runtime.encoding}\" outputencoding=\"${runtime.encoding}\"/>\n                    <jvmarg line=\"${run.jvmargs}\"/>\n                    <classpath>\n                        <path path=\"@{classpath}\"/>\n                    </classpath>\n                    <syspropertyset>\n                        <propertyref prefix=\"run-sys-prop.\"/>\n                        <mapper from=\"run-sys-prop.*\" to=\"*\" type=\"glob\"/>\n                    </syspropertyset>\n                    <customize/>\n                </java>\n            </sequential>\n        </macrodef>\n    </target>\n    <target name=\"-init-presetdef-jar\">\n        <presetdef name=\"jar\" uri=\"http://www.netbeans.org/ns/j2se-project/1\">\n            <jar compress=\"${jar.compress}\" jarfile=\"${dist.jar}\">\n                <j2seproject1:fileset dir=\"${build.classes.dir}\"/>\n            </jar>\n        </presetdef>\n    </target>\n    <target depends=\"-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar\" name=\"init\"/>\n    <!--\n                ===================\n                COMPILATION SECTION\n                ===================\n            -->\n    <target name=\"-deps-jar-init\" unless=\"built-jar.properties\">\n        <property location=\"${build.dir}/built-jar.properties\" name=\"built-jar.properties\"/>\n        <delete file=\"${built-jar.properties}\" quiet=\"true\"/>\n    </target>\n    <target if=\"already.built.jar.${basedir}\" name=\"-warn-already-built-jar\">\n        <echo level=\"warn\" message=\"Cycle detected: j2se-simple was already built\"/>\n    </target>\n    <target depends=\"init,-deps-jar-init\" name=\"deps-jar\" unless=\"no.deps\">\n        <mkdir dir=\"${build.dir}\"/>\n        <touch file=\"${built-jar.properties}\" verbose=\"false\"/>\n        <property file=\"${built-jar.properties}\" prefix=\"already.built.jar.\"/>\n        <antcall target=\"-warn-already-built-jar\"/>\n        <propertyfile file=\"${built-jar.properties}\">\n            <entry key=\"${basedir}\" value=\"\"/>\n        </propertyfile>\n    </target>\n    <target depends=\"init,-check-automatic-build,-clean-after-automatic-build\" name=\"-verify-automatic-build\"/>\n    <target depends=\"init\" name=\"-check-automatic-build\">\n        <available file=\"${build.classes.dir}/.netbeans_automatic_build\" property=\"netbeans.automatic.build\"/>\n    </target>\n    <target depends=\"init\" if=\"netbeans.automatic.build\" name=\"-clean-after-automatic-build\">\n        <antcall target=\"clean\"/>\n    </target>\n    <target depends=\"init,deps-jar\" name=\"-pre-pre-compile\">\n        <mkdir dir=\"${build.classes.dir}\"/>\n    </target>\n    <target name=\"-pre-compile\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target if=\"do.depend.true\" name=\"-compile-depend\">\n        <pathconvert property=\"build.generated.subdirs\">\n            <dirset dir=\"${build.generated.sources.dir}\" erroronmissingdir=\"false\">\n                <include name=\"*\"/>\n            </dirset>\n        </pathconvert>\n        <j2seproject3:depend srcdir=\"${src.dir}:${build.generated.subdirs}\"/>\n    </target>\n    <target depends=\"init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend\" if=\"have.sources\" name=\"-do-compile\">\n        <j2seproject3:javac gensrcdir=\"${build.generated.sources.dir}\"/>\n        <copy todir=\"${build.classes.dir}\">\n            <fileset dir=\"${src.dir}\" excludes=\"${build.classes.excludes},${excludes}\" includes=\"${includes}\"/>\n        </copy>\n    </target>\n    <target name=\"-post-compile\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target depends=\"init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile\" description=\"Compile project.\" name=\"compile\"/>\n    <target name=\"-pre-compile-single\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target depends=\"init,deps-jar,-pre-pre-compile\" name=\"-do-compile-single\">\n        <fail unless=\"javac.includes\">Must select some files in the IDE or set javac.includes</fail>\n        <j2seproject3:force-recompile/>\n        <j2seproject3:javac excludes=\"\" gensrcdir=\"${build.generated.sources.dir}\" includes=\"${javac.includes}\" sourcepath=\"${src.dir}\"/>\n    </target>\n    <target name=\"-post-compile-single\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target depends=\"init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single\" name=\"compile-single\"/>\n    <!--\n                ====================\n                JAR BUILDING SECTION\n                ====================\n            -->\n    <target depends=\"init\" name=\"-pre-pre-jar\">\n        <dirname file=\"${dist.jar}\" property=\"dist.jar.dir\"/>\n        <mkdir dir=\"${dist.jar.dir}\"/>\n    </target>\n    <target name=\"-pre-jar\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target depends=\"init,compile,-pre-pre-jar,-pre-jar\" name=\"-do-jar-without-manifest\" unless=\"manifest.available-mkdist.available\">\n        <j2seproject1:jar/>\n    </target>\n    <target depends=\"init,compile,-pre-pre-jar,-pre-jar\" if=\"manifest.available\" name=\"-do-jar-with-manifest\" unless=\"manifest.available+main.class-mkdist.available\">\n        <j2seproject1:jar manifest=\"${manifest.file}\"/>\n    </target>\n    <target depends=\"init,compile,-pre-pre-jar,-pre-jar\" if=\"manifest.available+main.class\" name=\"-do-jar-with-mainclass\" unless=\"manifest.available+main.class+mkdist.available\">\n        <j2seproject1:jar manifest=\"${manifest.file}\">\n            <j2seproject1:manifest>\n                <j2seproject1:attribute name=\"Main-Class\" value=\"${main.class}\"/>\n            </j2seproject1:manifest>\n        </j2seproject1:jar>\n        <echo>To run this application from the command line without Ant, try:</echo>\n        <property location=\"${build.classes.dir}\" name=\"build.classes.dir.resolved\"/>\n        <property location=\"${dist.jar}\" name=\"dist.jar.resolved\"/>\n        <pathconvert property=\"run.classpath.with.dist.jar\">\n            <path path=\"${run.classpath}\"/>\n            <map from=\"${build.classes.dir.resolved}\" to=\"${dist.jar.resolved}\"/>\n        </pathconvert>\n        <echo>java -cp \"${run.classpath.with.dist.jar}\" ${main.class}</echo>\n    </target>\n    <target depends=\"init,compile,-pre-pre-jar,-pre-jar\" if=\"manifest.available+main.class+mkdist.available\" name=\"-do-jar-with-libraries\">\n        <property location=\"${build.classes.dir}\" name=\"build.classes.dir.resolved\"/>\n        <pathconvert property=\"run.classpath.without.build.classes.dir\">\n            <path path=\"${run.classpath}\"/>\n            <map from=\"${build.classes.dir.resolved}\" to=\"\"/>\n        </pathconvert>\n        <pathconvert pathsep=\" \" property=\"jar.classpath\">\n            <path path=\"${run.classpath.without.build.classes.dir}\"/>\n            <chainedmapper>\n                <flattenmapper/>\n                <globmapper from=\"*\" to=\"lib/*\"/>\n            </chainedmapper>\n        </pathconvert>\n        <taskdef classname=\"org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs\" classpath=\"${libs.CopyLibs.classpath}\" name=\"copylibs\"/>\n        <copylibs compress=\"${jar.compress}\" jarfile=\"${dist.jar}\" manifest=\"${manifest.file}\" runtimeclasspath=\"${run.classpath.without.build.classes.dir}\">\n            <fileset dir=\"${build.classes.dir}\"/>\n            <manifest>\n                <attribute name=\"Main-Class\" value=\"${main.class}\"/>\n                <attribute name=\"Class-Path\" value=\"${jar.classpath}\"/>\n            </manifest>\n        </copylibs>\n        <echo>To run this application from the command line without Ant, try:</echo>\n        <property location=\"${dist.jar}\" name=\"dist.jar.resolved\"/>\n        <echo>java -jar \"${dist.jar.resolved}\"</echo>\n    </target>\n    <target depends=\"init,compile,-pre-pre-jar,-pre-jar\" if=\"manifest.available+mkdist.available\" name=\"-do-jar-with-libraries-without-mainclass\" unless=\"main.class.available\">\n        <property location=\"${build.classes.dir}\" name=\"build.classes.dir.resolved\"/>\n        <pathconvert property=\"run.classpath.without.build.classes.dir\">\n            <path path=\"${run.classpath}\"/>\n            <map from=\"${build.classes.dir.resolved}\" to=\"\"/>\n        </pathconvert>\n        <pathconvert pathsep=\" \" property=\"jar.classpath\">\n            <path path=\"${run.classpath.without.build.classes.dir}\"/>\n            <chainedmapper>\n                <flattenmapper/>\n                <globmapper from=\"*\" to=\"lib/*\"/>\n            </chainedmapper>\n        </pathconvert>\n        <taskdef classname=\"org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs\" classpath=\"${libs.CopyLibs.classpath}\" name=\"copylibs\"/>\n        <copylibs compress=\"${jar.compress}\" jarfile=\"${dist.jar}\" manifest=\"${manifest.file}\" runtimeclasspath=\"${run.classpath.without.build.classes.dir}\">\n            <fileset dir=\"${build.classes.dir}\"/>\n            <manifest>\n                <attribute name=\"Class-Path\" value=\"${jar.classpath}\"/>\n            </manifest>\n        </copylibs>\n    </target>\n    <target depends=\"init,compile,-pre-pre-jar,-pre-jar\" if=\"do.mkdist\" name=\"-do-jar-with-libraries-without-manifest\" unless=\"manifest.available\">\n        <property location=\"${build.classes.dir}\" name=\"build.classes.dir.resolved\"/>\n        <pathconvert property=\"run.classpath.without.build.classes.dir\">\n            <path path=\"${run.classpath}\"/>\n            <map from=\"${build.classes.dir.resolved}\" to=\"\"/>\n        </pathconvert>\n        <pathconvert pathsep=\" \" property=\"jar.classpath\">\n            <path path=\"${run.classpath.without.build.classes.dir}\"/>\n            <chainedmapper>\n                <flattenmapper/>\n                <globmapper from=\"*\" to=\"lib/*\"/>\n            </chainedmapper>\n        </pathconvert>\n        <taskdef classname=\"org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs\" classpath=\"${libs.CopyLibs.classpath}\" name=\"copylibs\"/>\n        <copylibs compress=\"${jar.compress}\" jarfile=\"${dist.jar}\" runtimeclasspath=\"${run.classpath.without.build.classes.dir}\">\n            <fileset dir=\"${build.classes.dir}\"/>\n            <manifest>\n                <attribute name=\"Class-Path\" value=\"${jar.classpath}\"/>\n            </manifest>\n        </copylibs>\n    </target>\n    <target name=\"-post-jar\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target depends=\"init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-do-jar-with-libraries-without-mainclass,-do-jar-with-libraries-without-manifest,-post-jar\" description=\"Build JAR.\" name=\"jar\"/>\n    <!--\n                =================\n                EXECUTION SECTION\n                =================\n            -->\n    <target depends=\"init,compile\" description=\"Run a main class.\" name=\"run\">\n        <j2seproject1:java>\n            <customize>\n                <arg line=\"${application.args}\"/>\n            </customize>\n        </j2seproject1:java>\n    </target>\n    <target name=\"-do-not-recompile\">\n        <property name=\"javac.includes.binary\" value=\"\"/>\n    </target>\n    <target depends=\"init,compile-single\" name=\"run-single\">\n        <fail unless=\"run.class\">Must select one file in the IDE or set run.class</fail>\n        <j2seproject1:java classname=\"${run.class}\"/>\n    </target>\n    <target depends=\"init,compile-test-single\" name=\"run-test-with-main\">\n        <fail unless=\"run.class\">Must select one file in the IDE or set run.class</fail>\n        <j2seproject1:java classname=\"${run.class}\" classpath=\"${run.test.classpath}\"/>\n    </target>\n    <!--\n                =================\n                DEBUGGING SECTION\n                =================\n            -->\n    <target depends=\"init\" if=\"netbeans.home\" name=\"-debug-start-debugger\">\n        <j2seproject1:nbjpdastart name=\"${debug.class}\"/>\n    </target>\n    <target depends=\"init\" if=\"netbeans.home\" name=\"-debug-start-debugger-main-test\">\n        <j2seproject1:nbjpdastart classpath=\"${debug.test.classpath}\" name=\"${debug.class}\"/>\n    </target>\n    <target depends=\"init,compile\" name=\"-debug-start-debuggee\">\n        <j2seproject3:debug>\n            <customize>\n                <arg line=\"${application.args}\"/>\n            </customize>\n        </j2seproject3:debug>\n    </target>\n    <target depends=\"init,compile,-debug-start-debugger,-debug-start-debuggee\" description=\"Debug project in IDE.\" if=\"netbeans.home\" name=\"debug\"/>\n    <target depends=\"init\" if=\"netbeans.home\" name=\"-debug-start-debugger-stepinto\">\n        <j2seproject1:nbjpdastart stopclassname=\"${main.class}\"/>\n    </target>\n    <target depends=\"init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee\" if=\"netbeans.home\" name=\"debug-stepinto\"/>\n    <target depends=\"init,compile-single\" if=\"netbeans.home\" name=\"-debug-start-debuggee-single\">\n        <fail unless=\"debug.class\">Must select one file in the IDE or set debug.class</fail>\n        <j2seproject3:debug classname=\"${debug.class}\"/>\n    </target>\n    <target depends=\"init,compile-single,-debug-start-debugger,-debug-start-debuggee-single\" if=\"netbeans.home\" name=\"debug-single\"/>\n    <target depends=\"init,compile-test-single\" if=\"netbeans.home\" name=\"-debug-start-debuggee-main-test\">\n        <fail unless=\"debug.class\">Must select one file in the IDE or set debug.class</fail>\n        <j2seproject3:debug classname=\"${debug.class}\" classpath=\"${debug.test.classpath}\"/>\n    </target>\n    <target depends=\"init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test\" if=\"netbeans.home\" name=\"debug-test-with-main\"/>\n    <target depends=\"init\" name=\"-pre-debug-fix\">\n        <fail unless=\"fix.includes\">Must set fix.includes</fail>\n        <property name=\"javac.includes\" value=\"${fix.includes}.java\"/>\n    </target>\n    <target depends=\"init,-pre-debug-fix,compile-single\" if=\"netbeans.home\" name=\"-do-debug-fix\">\n        <j2seproject1:nbjpdareload/>\n    </target>\n    <target depends=\"init,-pre-debug-fix,-do-debug-fix\" if=\"netbeans.home\" name=\"debug-fix\"/>\n    <!--\n                ===============\n                JAVADOC SECTION\n                ===============\n            -->\n    <target depends=\"init\" name=\"-javadoc-build\">\n        <mkdir dir=\"${dist.javadoc.dir}\"/>\n        <javadoc additionalparam=\"${javadoc.additionalparam}\" author=\"${javadoc.author}\" charset=\"UTF-8\" destdir=\"${dist.javadoc.dir}\" docencoding=\"UTF-8\" encoding=\"${javadoc.encoding.used}\" failonerror=\"true\" noindex=\"${javadoc.noindex}\" nonavbar=\"${javadoc.nonavbar}\" notree=\"${javadoc.notree}\" private=\"${javadoc.private}\" source=\"${javac.source}\" splitindex=\"${javadoc.splitindex}\" use=\"${javadoc.use}\" useexternalfile=\"true\" version=\"${javadoc.version}\" windowtitle=\"${javadoc.windowtitle}\">\n            <classpath>\n                <path path=\"${javac.classpath}\"/>\n            </classpath>\n            <fileset dir=\"${src.dir}\" excludes=\"${excludes}\" includes=\"${includes}\">\n                <filename name=\"**/*.java\"/>\n            </fileset>\n            <fileset dir=\"${build.generated.sources.dir}\" erroronmissingdir=\"false\">\n                <include name=\"**/*.java\"/>\n            </fileset>\n        </javadoc>\n    </target>\n    <target depends=\"init,-javadoc-build\" if=\"netbeans.home\" name=\"-javadoc-browse\" unless=\"no.javadoc.preview\">\n        <nbbrowse file=\"${dist.javadoc.dir}/index.html\"/>\n    </target>\n    <target depends=\"init,-javadoc-build,-javadoc-browse\" description=\"Build Javadoc.\" name=\"javadoc\"/>\n    <!--\n                =========================\n                JUNIT COMPILATION SECTION\n                =========================\n            -->\n    <target depends=\"init,compile\" if=\"have.tests\" name=\"-pre-pre-compile-test\">\n        <mkdir dir=\"${build.test.classes.dir}\"/>\n    </target>\n    <target name=\"-pre-compile-test\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target if=\"do.depend.true\" name=\"-compile-test-depend\">\n        <j2seproject3:depend classpath=\"${javac.test.classpath}\" destdir=\"${build.test.classes.dir}\" srcdir=\"${test.src.dir}\"/>\n    </target>\n    <target depends=\"init,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend\" if=\"have.tests\" name=\"-do-compile-test\">\n        <j2seproject3:javac classpath=\"${javac.test.classpath}\" debug=\"true\" destdir=\"${build.test.classes.dir}\" srcdir=\"${test.src.dir}\"/>\n        <copy todir=\"${build.test.classes.dir}\">\n            <fileset dir=\"${test.src.dir}\" excludes=\"${build.classes.excludes},${excludes}\" includes=\"${includes}\"/>\n        </copy>\n    </target>\n    <target name=\"-post-compile-test\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target depends=\"init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test\" name=\"compile-test\"/>\n    <target name=\"-pre-compile-test-single\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target depends=\"init,compile,-pre-pre-compile-test,-pre-compile-test-single\" if=\"have.tests\" name=\"-do-compile-test-single\">\n        <fail unless=\"javac.includes\">Must select some files in the IDE or set javac.includes</fail>\n        <j2seproject3:force-recompile destdir=\"${build.test.classes.dir}\"/>\n        <j2seproject3:javac classpath=\"${javac.test.classpath}\" debug=\"true\" destdir=\"${build.test.classes.dir}\" excludes=\"\" includes=\"${javac.includes}\" sourcepath=\"${test.src.dir}\" srcdir=\"${test.src.dir}\"/>\n        <copy todir=\"${build.test.classes.dir}\">\n            <fileset dir=\"${test.src.dir}\" excludes=\"${build.classes.excludes},${excludes}\" includes=\"${includes}\"/>\n        </copy>\n    </target>\n    <target name=\"-post-compile-test-single\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target depends=\"init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single\" name=\"compile-test-single\"/>\n    <!--\n                =======================\n                JUNIT EXECUTION SECTION\n                =======================\n            -->\n    <target depends=\"init\" if=\"have.tests\" name=\"-pre-test-run\">\n        <mkdir dir=\"${build.test.results.dir}\"/>\n    </target>\n    <target depends=\"init,compile-test,-pre-test-run\" if=\"have.tests\" name=\"-do-test-run\">\n        <j2seproject3:junit testincludes=\"**/*Test.java\"/>\n    </target>\n    <target depends=\"init,compile-test,-pre-test-run,-do-test-run\" if=\"have.tests\" name=\"-post-test-run\">\n        <fail if=\"tests.failed\" unless=\"ignore.failing.tests\">Some tests failed; see details above.</fail>\n    </target>\n    <target depends=\"init\" if=\"have.tests\" name=\"test-report\"/>\n    <target depends=\"init\" if=\"netbeans.home+have.tests\" name=\"-test-browse\"/>\n    <target depends=\"init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse\" description=\"Run unit tests.\" name=\"test\"/>\n    <target depends=\"init\" if=\"have.tests\" name=\"-pre-test-run-single\">\n        <mkdir dir=\"${build.test.results.dir}\"/>\n    </target>\n    <target depends=\"init,compile-test-single,-pre-test-run-single\" if=\"have.tests\" name=\"-do-test-run-single\">\n        <fail unless=\"test.includes\">Must select some files in the IDE or set test.includes</fail>\n        <j2seproject3:junit excludes=\"\" includes=\"${test.includes}\"/>\n    </target>\n    <target depends=\"init,compile-test-single,-pre-test-run-single,-do-test-run-single\" if=\"have.tests\" name=\"-post-test-run-single\">\n        <fail if=\"tests.failed\" unless=\"ignore.failing.tests\">Some tests failed; see details above.</fail>\n    </target>\n    <target depends=\"init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single\" description=\"Run single unit test.\" name=\"test-single\"/>\n    <!--\n                =======================\n                JUNIT DEBUGGING SECTION\n                =======================\n            -->\n    <target depends=\"init,compile-test\" if=\"have.tests\" name=\"-debug-start-debuggee-test\">\n        <fail unless=\"test.class\">Must select one file in the IDE or set test.class</fail>\n        <property location=\"${build.test.results.dir}/TEST-${test.class}.xml\" name=\"test.report.file\"/>\n        <delete file=\"${test.report.file}\"/>\n        <mkdir dir=\"${build.test.results.dir}\"/>\n        <j2seproject3:debug classname=\"org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner\" classpath=\"${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}\">\n            <customize>\n                <syspropertyset>\n                    <propertyref prefix=\"test-sys-prop.\"/>\n                    <mapper from=\"test-sys-prop.*\" to=\"*\" type=\"glob\"/>\n                </syspropertyset>\n                <arg value=\"${test.class}\"/>\n                <arg value=\"showoutput=true\"/>\n                <arg value=\"formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter\"/>\n                <arg value=\"formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}\"/>\n            </customize>\n        </j2seproject3:debug>\n    </target>\n    <target depends=\"init,compile-test\" if=\"netbeans.home+have.tests\" name=\"-debug-start-debugger-test\">\n        <j2seproject1:nbjpdastart classpath=\"${debug.test.classpath}\" name=\"${test.class}\"/>\n    </target>\n    <target depends=\"init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test\" name=\"debug-test\"/>\n    <target depends=\"init,-pre-debug-fix,compile-test-single\" if=\"netbeans.home\" name=\"-do-debug-fix-test\">\n        <j2seproject1:nbjpdareload dir=\"${build.test.classes.dir}\"/>\n    </target>\n    <target depends=\"init,-pre-debug-fix,-do-debug-fix-test\" if=\"netbeans.home\" name=\"debug-fix-test\"/>\n    <!--\n                =========================\n                APPLET EXECUTION SECTION\n                =========================\n            -->\n    <target depends=\"init,compile-single\" name=\"run-applet\">\n        <fail unless=\"applet.url\">Must select one file in the IDE or set applet.url</fail>\n        <j2seproject1:java classname=\"sun.applet.AppletViewer\">\n            <customize>\n                <arg value=\"${applet.url}\"/>\n            </customize>\n        </j2seproject1:java>\n    </target>\n    <!--\n                =========================\n                APPLET DEBUGGING  SECTION\n                =========================\n            -->\n    <target depends=\"init,compile-single\" if=\"netbeans.home\" name=\"-debug-start-debuggee-applet\">\n        <fail unless=\"applet.url\">Must select one file in the IDE or set applet.url</fail>\n        <j2seproject3:debug classname=\"sun.applet.AppletViewer\">\n            <customize>\n                <arg value=\"${applet.url}\"/>\n            </customize>\n        </j2seproject3:debug>\n    </target>\n    <target depends=\"init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet\" if=\"netbeans.home\" name=\"debug-applet\"/>\n    <!--\n                ===============\n                CLEANUP SECTION\n                ===============\n            -->\n    <target name=\"-deps-clean-init\" unless=\"built-clean.properties\">\n        <property location=\"${build.dir}/built-clean.properties\" name=\"built-clean.properties\"/>\n        <delete file=\"${built-clean.properties}\" quiet=\"true\"/>\n    </target>\n    <target if=\"already.built.clean.${basedir}\" name=\"-warn-already-built-clean\">\n        <echo level=\"warn\" message=\"Cycle detected: j2se-simple was already built\"/>\n    </target>\n    <target depends=\"init,-deps-clean-init\" name=\"deps-clean\" unless=\"no.deps\">\n        <mkdir dir=\"${build.dir}\"/>\n        <touch file=\"${built-clean.properties}\" verbose=\"false\"/>\n        <property file=\"${built-clean.properties}\" prefix=\"already.built.clean.\"/>\n        <antcall target=\"-warn-already-built-clean\"/>\n        <propertyfile file=\"${built-clean.properties}\">\n            <entry key=\"${basedir}\" value=\"\"/>\n        </propertyfile>\n    </target>\n    <target depends=\"init\" name=\"-do-clean\">\n        <delete dir=\"${build.dir}\"/>\n        <delete dir=\"${dist.dir}\" followsymlinks=\"false\" includeemptydirs=\"true\"/>\n    </target>\n    <target name=\"-post-clean\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target depends=\"init,deps-clean,-do-clean,-post-clean\" description=\"Clean build products.\" name=\"clean\"/>\n    <target name=\"-check-call-dep\">\n        <property file=\"${call.built.properties}\" prefix=\"already.built.\"/>\n        <condition property=\"should.call.dep\">\n            <not>\n                <isset property=\"already.built.${call.subproject}\"/>\n            </not>\n        </condition>\n    </target>\n    <target depends=\"-check-call-dep\" if=\"should.call.dep\" name=\"-maybe-call-dep\">\n        <ant antfile=\"${call.script}\" inheritall=\"false\" target=\"${call.target}\">\n            <propertyset>\n                <propertyref prefix=\"transfer.\"/>\n                <mapper from=\"transfer.*\" to=\"*\" type=\"glob\"/>\n            </propertyset>\n        </ant>\n    </target>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=7dd73fa8\nbuild.xml.script.CRC32=bd4bea1f\nbuild.xml.stylesheet.CRC32=e2435cb5\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=0919c763\nnbproject/build-impl.xml.script.CRC32=ef794fc9\nnbproject/build-impl.xml.stylesheet.CRC32=576378a2@1.34.0.45\nnbproject/profiler-build-impl.xml.data.CRC32=0919c763\nnbproject/profiler-build-impl.xml.script.CRC32=abda56ed\nnbproject/profiler-build-impl.xml.stylesheet.CRC32=a5b6598e\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/nbproject/profiler-build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n\nFor the purpose of easier reading the script\nis divided into following sections:\n\n  - initialization\n  - profiling\n  - applet profiling\n\n-->\n<project name=\"-profiler-impl\" default=\"profile\" basedir=\"..\">\n    <target name=\"default\" depends=\"profile\" description=\"Build and profile the project.\"/>\n    <!--\n    ======================\n    INITIALIZATION SECTION\n    ======================\n    -->\n    <target name=\"profile-init\" depends=\"-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check\"/>\n    <target name=\"-profile-pre-init\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target name=\"-profile-post-init\">\n        <!-- Empty placeholder for easier customization. -->\n        <!-- You can override this target in the ../build.xml file. -->\n    </target>\n    <target name=\"-profile-init-macrodef-profile\">\n        <macrodef name=\"resolve\">\n            <attribute name=\"name\"/>\n            <attribute name=\"value\"/>\n            <sequential>\n                <property name=\"@{name}\" value=\"${env.@{value}}\"/>\n            </sequential>\n        </macrodef>\n        <macrodef name=\"profile\">\n            <attribute name=\"classname\" default=\"${main.class}\"/>\n            <element name=\"customize\" optional=\"true\"/>\n            <sequential>\n                <property environment=\"env\"/>\n                <resolve name=\"profiler.current.path\" value=\"${profiler.info.pathvar}\"/>\n                <java fork=\"true\" classname=\"@{classname}\" dir=\"${profiler.info.dir}\" jvm=\"${profiler.info.jvm}\">\n                    <jvmarg value=\"${profiler.info.jvmargs.agent}\"/>\n                    <jvmarg line=\"${profiler.info.jvmargs}\"/>\n                    <env key=\"${profiler.info.pathvar}\" path=\"${profiler.info.agentpath}:${profiler.current.path}\"/>\n                    <arg line=\"${application.args}\"/>\n                    <classpath>\n                        <path path=\"${run.classpath}\"/>\n                    </classpath>\n                    <syspropertyset>\n                        <propertyref prefix=\"run-sys-prop.\"/>\n                        <mapper type=\"glob\" from=\"run-sys-prop.*\" to=\"*\"/>\n                    </syspropertyset>\n                    <customize/>\n                </java>\n            </sequential>\n        </macrodef>\n    </target>\n    <target name=\"-profile-init-check\" depends=\"-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile\">\n        <fail unless=\"profiler.info.jvm\">Must set JVM to use for profiling in profiler.info.jvm</fail>\n        <fail unless=\"profiler.info.jvmargs.agent\">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>\n    </target>\n    <!--\n    =================\n    PROFILING SECTION\n    =================\n    -->\n    <target name=\"profile\" if=\"netbeans.home\" depends=\"profile-init,compile\" description=\"Profile a project in the IDE.\">\n        <nbprofiledirect>\n            <classpath>\n                <path path=\"${run.classpath}\"/>\n            </classpath>\n        </nbprofiledirect>\n        <profile/>\n    </target>\n    <target name=\"profile-single\" if=\"netbeans.home\" depends=\"profile-init,compile-single\" description=\"Profile a selected class in the IDE.\">\n        <fail unless=\"profile.class\">Must select one file in the IDE or set profile.class</fail>\n        <nbprofiledirect>\n            <classpath>\n                <path path=\"${run.classpath}\"/>\n            </classpath>\n        </nbprofiledirect>\n        <profile classname=\"${profile.class}\"/>\n    </target>\n    <!--\n    =========================\n    APPLET PROFILING  SECTION\n    =========================\n    -->\n    <target name=\"profile-applet\" if=\"netbeans.home\" depends=\"profile-init,compile-single\">\n        <nbprofiledirect>\n            <classpath>\n                <path path=\"${run.classpath}\"/>\n            </classpath>\n        </nbprofiledirect>\n        <profile classname=\"sun.applet.AppletViewer\">\n            <customize>\n                <arg value=\"${applet.url}\"/>\n            </customize>\n        </profile>\n    </target>\n    <!--\n    =========================\n    TESTS PROFILING  SECTION\n    =========================\n    -->\n    <target name=\"profile-test-single\" if=\"netbeans.home\" depends=\"profile-init,compile-test-single\">\n        <nbprofiledirect>\n            <classpath>\n                <path path=\"${run.test.classpath}\"/>\n            </classpath>\n        </nbprofiledirect>\n        <junit showoutput=\"true\" fork=\"true\" dir=\"${profiler.info.dir}\" jvm=\"${profiler.info.jvm}\" failureproperty=\"tests.failed\" errorproperty=\"tests.failed\">\n            <env key=\"${profiler.info.pathvar}\" path=\"${profiler.info.agentpath}:${profiler.current.path}\"/>\n            <jvmarg value=\"${profiler.info.jvmargs.agent}\"/>\n            <jvmarg line=\"${profiler.info.jvmargs}\"/>\n            <test name=\"${profile.class}\"/>\n            <classpath>\n                <path path=\"${run.test.classpath}\"/>\n            </classpath>\n            <syspropertyset>\n                <propertyref prefix=\"test-sys-prop.\"/>\n                <mapper type=\"glob\" from=\"test-sys-prop.*\" to=\"*\"/>\n            </syspropertyset>\n            <formatter type=\"brief\" usefile=\"false\"/>\n            <formatter type=\"xml\"/>\n        </junit>\n    </target>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/nbproject/project.properties",
    "content": "application.args=\napplication.title=j2se-simple\napplication.vendor=jb198685\nbuild.classes.dir=${build.dir}/classes\nbuild.classes.excludes=**/*.java,**/*.form\n# This directory is removed when the project is cleaned:\nbuild.dir=build\nbuild.generated.sources.dir=${build.dir}/generated-sources\n# Only compile against the classpath explicitly listed here:\nbuild.sysclasspath=ignore\nbuild.test.classes.dir=${build.dir}/test/classes\nbuild.test.results.dir=${build.dir}/test/results\ndebug.classpath=\\\n    ${run.classpath}\ndebug.test.classpath=\\\n    ${run.test.classpath}\n# This directory is removed when the project is cleaned:\ndist.dir=dist\ndist.jar=${dist.dir}/j2se-simple.jar\ndist.javadoc.dir=${dist.dir}/javadoc\nexcludes=\nincludes=**\njar.compress=true\njavac.classpath=\\\n    ${libs.swing-layout.classpath}\n# Space-separated list of extra javac options\njavac.compilerargs=\njavac.deprecation=false\njavac.source=1.5\njavac.target=1.5\njavac.test.classpath=\\\n    ${javac.classpath}:\\\n    ${build.classes.dir}:\\\n    ${libs.junit.classpath}\njavadoc.additionalparam=\njavadoc.author=false\njavadoc.encoding=\njavadoc.noindex=false\njavadoc.nonavbar=false\njavadoc.notree=false\njavadoc.private=false\njavadoc.splitindex=true\njavadoc.use=true\njavadoc.version=false\njavadoc.windowtitle=\nmain.class=simple.cpu.CPU1\nmanifest.file=manifest.mf\nplatform.active=default_platform\nrun.classpath=\\\n    ${javac.classpath}:\\\n    ${build.classes.dir}\n# Space-separated list of JVM arguments used when running the project\n# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value\n# or test-sys-prop.name=value to set system properties for unit tests):\nrun.jvmargs=\nrun.test.classpath=\\\n    ${javac.test.classpath}:\\\n    ${build.test.classes.dir}\nsrc.dir=src\ntest.src.dir=test\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.java.j2seproject</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/j2se-project/3\">\n            <name>j2se-simple</name>\n            <minimum-ant-version>1.6</minimum-ant-version>\n            <source-roots>\n                <root id=\"src.dir\"/>\n            </source-roots>\n            <test-roots>\n                <root id=\"test.src.dir\"/>\n            </test-roots>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/CPU.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage simple;\n\n\n/**\n *\n * @author\n */\npublic class CPU {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of CPU\n     */\n    public CPU() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        try {\n            System.out.println(\"Application (20070815) started: \" + System.currentTimeMillis());\n\n            for (int i = 0; i < 5; i++) {\n                test1000();\n            }\n\n            double[] fibo = new double[100];\n            fibo[0] = 0;\n            fibo[1] = 1;\n\n            for (int i = 2; i < 100; i++) {\n                fibo[i] = fibo[i - 2] + fibo[i - 1];\n            }\n\n            System.out.println(\"Fibonacci:\");\n            System.out.print(\"[\");\n\n            for (int i = 0; i < 100; i++) {\n                System.out.print(fibo[i]);\n\n                if (i < 99) {\n                    System.out.print(\",\");\n                }\n            }\n\n            System.out.println(\"]\");\n            System.out.println(\"Application finished: \" + System.currentTimeMillis());\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    private static void test1000() {\n        long startTime = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - startTime) < 1000) {\n            ;\n        }\n\n        test500();\n    }\n\n    private static void test20() {\n        long startTime = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - startTime) < 20) {\n            ;\n        }\n    }\n\n    private static void test500() {\n        long startTime = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - startTime) < 500) {\n            ;\n        }\n\n        test20();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/Consumer.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * Consumer.java\n *\n * Created on June 14, 2005, 12:20 PM\n *\n * To change this template, choose Tools | Options and locate the template under\n * the Source Creation and Management node. Right-click the template and choose\n * Open. You can then make changes to the template in the Source Editor.\n */\npackage simple;\n\n\n/**\n *\n * @author ehucka\n */\npublic class Consumer extends Thread {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Data cubbyhole;\n    private int number;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public Consumer(Data c, int number) {\n        cubbyhole = c;\n        this.number = number;\n        setName(\"Consumer \" + number);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void run() {\n        int value = 0;\n\n        while (true) {\n            value = cubbyhole.get(number);\n\n            long time = System.currentTimeMillis();\n\n            while ((System.currentTimeMillis() - time) < value) {\n                ;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/Data.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * Data.java\n *\n * Created on June 14, 2005, 12:37 PM\n *\n * To change this template, choose Tools | Options and locate the template under\n * the Source Creation and Management node. Right-click the template and choose\n * Open. You can then make changes to the template in the Source Editor.\n */\npackage simple;\n\n\n/**\n *\n * @author ehucka\n */\npublic class Data {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private boolean available = false;\n    private int contents;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public synchronized int get(int who) {\n        while (available == false) {\n            try {\n                wait();\n            } catch (InterruptedException e) {\n            }\n        }\n\n        available = false;\n        notifyAll();\n\n        return contents;\n    }\n\n    public synchronized void put(int who, int value) {\n        while (available == true) {\n            try {\n                wait();\n            } catch (InterruptedException e) {\n            }\n        }\n\n        contents = value;\n        available = true;\n        notifyAll();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/Memory.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage simple;\n\nimport java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.util.ArrayList;\n\n\n/**\n *\n * @author ehucka\n */\npublic class Memory {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    ArrayList list = new ArrayList();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of Memory */\n    public Memory() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void getData() {\n        for (int i = 0; i < 100; i++) {\n            list.add(new Data());\n        }\n    }\n\n    public void get1000() {\n        long[] l = new long[100];\n        list.add(l);\n    }\n\n    public void get500() {\n        int[] d = new int[1000];\n        list.add(d);\n    }\n\n    public static void main(String[] args) {\n        System.out.println(\">>app: start: \" + System.currentTimeMillis());\n\n        //wait for profiler\n        /*try {\n           BufferedReader br=new BufferedReader(new InputStreamReader(System.in));\n           br.readLine();\n           } catch (Exception ex) {}\n           //wait for the first measuring\n           try {\n               Thread.sleep(3000);\n           } catch (Exception e) {}*/\n        Memory m = new Memory();\n        int cycle = 20;\n\n        while (cycle > 0) {\n            try {\n                Thread.sleep(100);\n            } catch (Exception ex) {\n            }\n\n            m.get1000();\n            m.get500();\n            m.getData();\n            cycle--;\n        }\n\n        System.out.println(\">>app: end: \" + System.currentTimeMillis());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/Monitor.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * Monitor.java\n *\n * Created on June 14, 2005, 12:20 PM\n *\n * To change this template, choose Tools | Options and locate the template under\n * the Source Creation and Management node. Right-click the template and choose\n * Open. You can then make changes to the template in the Source Editor.\n */\npackage simple;\n\n\n/**\n *\n * @author ehucka\n */\npublic class Monitor {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of Monitor\n     */\n    public Monitor() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        Data data = new Data();\n        Consumer c1 = new Consumer(data, 1);\n        Producer p1 = new Producer(data, 1);\n        p1.start();\n        c1.start();\n\n        try {\n            Thread.sleep(5000);\n\n            Consumer c2 = new Consumer(data, 2);\n            Producer p2 = new Producer(data, 2);\n            p2.start();\n            c2.start();\n            p1.join();\n            p2.join();\n        } catch (InterruptedException e) {\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/Producer.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * Producer.java\n *\n * Created on June 14, 2005, 12:20 PM\n *\n * To change this template, choose Tools | Options and locate the template under\n * the Source Creation and Management node. Right-click the template and choose\n * Open. You can then make changes to the template in the Source Editor.\n */\npackage simple;\n\n\n/**\n *\n * @author ehucka\n */\npublic class Producer extends Thread {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Data cubbyhole;\n    private int number;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public Producer(Data c, int number) {\n        cubbyhole = c;\n        this.number = number;\n        setName(\"Producer \" + number);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void run() {\n        while (true) {\n            int in = (int) (Math.random() * 500);\n            long time = System.currentTimeMillis();\n\n            while ((System.currentTimeMillis() - time) < in) {\n                ;\n            }\n\n            cubbyhole.put(number, in);\n\n            try {\n                sleep(in);\n            } catch (InterruptedException e) {\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/cpu/AnotherThread.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage simple.cpu;\n\nclass AnotherThread extends Thread {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void run() {\n        Region r = new Region();\n        r.run1000();\n        r.run2000();\n        r.run1000();\n\n        for (int i = 0; i < 10; i++) {\n            r.run100();\n        }\n\n        r.run1000();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/cpu/Bean.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * Bean.java\n *\n * Created on July 21, 2005, 1:14 PM\n *\n * To change this template, choose Tools | Options and locate the template under\n * the Source Creation and Management node. Right-click the template and choose\n * Open. You can then make changes to the template in the Source Editor.\n */\npackage simple.cpu;\n\n\n/**\n *\n * @author ehucka\n */\npublic class Bean {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    String name;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of Bean */\n    public Bean() {\n        run20();\n        run20();\n        run20();\n        run20();\n\n        run100();\n        run100();\n\n        run1000();\n        emptyMethod();\n        setName(\"Beanb\");\n        System.out.println(\"\");\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setName(String n) {\n        name = n;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void emptyMethod() {\n    }\n\n    public void run100() {\n        long startTime = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - startTime) < 100) {\n            ;\n        }\n    }\n\n    public void run1000() {\n        long startTime = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - startTime) < 1000) {\n            ;\n        }\n    }\n\n    public void run20() {\n        long startTime = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - startTime) < 20) {\n            ;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/cpu/CPU1.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * CPU1.java\n *\n * Created on July 21, 2005, 1:14 PM\n *\n * To change this template, choose Tools | Options and locate the template under\n * the Source Creation and Management node. Right-click the template and choose\n * Open. You can then make changes to the template in the Source Editor.\n */\npackage simple.cpu;\n\n\n/**\n *\n * @author ehucka\n */\npublic class CPU1 {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of CPU1 */\n    public CPU1() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        System.out.println(\"start app: \" + System.currentTimeMillis());\n\n        for (int i = 0; i < 1; i++) {\n            Bean b = new Bean();\n            b.setName(\"Bean\");\n            System.out.println(\"\");\n\n            CPUThread th = new CPUThread();\n            th.start();\n\n            try {\n                th.join();\n            } catch (Exception ex) {\n            }\n        }\n\n        System.out.println(\"end app: \" + System.currentTimeMillis());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/cpu/CPUThread.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * CPUThread.java\n *\n * Created on July 21, 2005, 1:19 PM\n *\n * To change this template, choose Tools | Options and locate the template under\n * the Source Creation and Management node. Right-click the template and choose\n * Open. You can then make changes to the template in the Source Editor.\n */\npackage simple.cpu;\n\n\n/**\n *\n * @author ehucka\n */\npublic class CPUThread extends Thread {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of CPUThread */\n    public CPUThread() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void run() {\n        run512();\n        run512();\n    }\n\n    public void run512() {\n        long startTime = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - startTime) < 512) {\n            ;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/cpu/Measure.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage simple.cpu;\n\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.PrintStream;\nimport java.util.HashMap;\n\n\n/**\n *\n * @author ehucka\n */\npublic class Measure {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static PrintStream ps;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of Measure\n     */\n    public Measure() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void empty() {\n    }\n\n    public static void main(String[] args) {\n        System.out.println(\"Application started: \" + System.currentTimeMillis());\n\n        try {\n            ps = new PrintStream(new FileOutputStream(args[0]));\n\n            Measure m = new Measure();\n            m.test();\n            ps.close();\n        } catch (Exception ex) {\n            ex.printStackTrace();\n        }\n\n        System.out.println(\"Application finished: \" + System.currentTimeMillis());\n    }\n\n    public void run10() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n    }\n\n    public void run100() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 100) {\n            ;\n        }\n    }\n\n    public void run1000() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 1000) {\n            ;\n        }\n    }\n\n    public void run1000Call1() {\n        empty();\n\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 1000) {\n            ;\n        }\n    }\n\n    public void run1000Call4() {\n        empty();\n        empty();\n\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 1000) {\n            ;\n        }\n\n        empty();\n        empty();\n    }\n\n    public void run100Call1() {\n        empty();\n\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 100) {\n            ;\n        }\n    }\n\n    public void run100Call4() {\n        empty();\n        empty();\n\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 100) {\n            ;\n        }\n\n        empty();\n        empty();\n    }\n\n    //a method call\n    public void run10Call1() {\n        empty();\n\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n    }\n\n    //4 calls\n    public void run10Call4() {\n        empty();\n        empty();\n\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        empty();\n        empty();\n    }\n\n    public void run20() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 20) {\n            ;\n        }\n    }\n\n    public void run200() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 200) {\n            ;\n        }\n    }\n\n    public void run2000() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 2000) {\n            ;\n        }\n    }\n\n    public void run2000Call1() {\n        empty();\n\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 2000) {\n            ;\n        }\n    }\n\n    public void run2000Call4() {\n        empty();\n        empty();\n\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 2000) {\n            ;\n        }\n\n        empty();\n        empty();\n    }\n\n    public void run200Call1() {\n        empty();\n\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 200) {\n            ;\n        }\n    }\n\n    public void run200Call4() {\n        empty();\n        empty();\n\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 200) {\n            ;\n        }\n\n        empty();\n        empty();\n    }\n\n    public void run20Call1() {\n        empty();\n\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 20) {\n            ;\n        }\n    }\n\n    public void run20Call4() {\n        empty();\n        empty();\n\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 20) {\n            ;\n        }\n\n        empty();\n        empty();\n    }\n\n    public void run4000by10() {\n        long time;\n\n        for (int i = 0; i < 400; i++) {\n            time = System.currentTimeMillis();\n\n            while ((System.currentTimeMillis() - time) < 10) {\n                ;\n            }\n        }\n    }\n\n    public void run4000by100() {\n        long time;\n\n        for (int i = 0; i < 40; i++) {\n            time = System.currentTimeMillis();\n\n            while ((System.currentTimeMillis() - time) < 100) {\n                ;\n            }\n        }\n    }\n\n    public void run4000by1000() {\n        long time;\n\n        for (int i = 0; i < 4; i++) {\n            time = System.currentTimeMillis();\n\n            while ((System.currentTimeMillis() - time) < 1000) {\n                ;\n            }\n        }\n    }\n\n    public void test() {\n        ps.println(\"Method;Ideal Time;Measured time\");\n\n        long time = System.currentTimeMillis();\n        int count = 20;\n\n        for (int i = 0; i < count; i++) {\n            run10();\n        }\n\n        time = System.currentTimeMillis() - time;\n\n        double val = time / (double) count;\n        ps.println(\"run10;10;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 20;\n\n        for (int i = 0; i < count; i++) {\n            run20();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run20;20;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 10;\n\n        for (int i = 0; i < count; i++) {\n            run100();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run100;100;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 10;\n\n        for (int i = 0; i < count; i++) {\n            run200();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run200;200;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 5;\n\n        for (int i = 0; i < count; i++) {\n            run1000();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run1000;1000;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 5;\n\n        for (int i = 0; i < count; i++) {\n            run2000();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run2000;2000;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 4;\n\n        for (int i = 0; i < count; i++) {\n            run4000by10();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run4000by10;4000;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 4;\n\n        for (int i = 0; i < count; i++) {\n            run4000by100();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run4000by100;4000;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 4;\n\n        for (int i = 0; i < count; i++) {\n            run4000by1000();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run4000by1000;4000;\" + String.valueOf(val));\n\n        //******************************************************************\n        time = System.currentTimeMillis();\n        count = 20;\n\n        for (int i = 0; i < count; i++) {\n            run10Call1();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run10Call1;10;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 20;\n\n        for (int i = 0; i < count; i++) {\n            run20Call1();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run20Call1;20;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 10;\n\n        for (int i = 0; i < count; i++) {\n            run100Call1();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run100Call1;100;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 10;\n\n        for (int i = 0; i < count; i++) {\n            run200Call1();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run200Call1;200;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 5;\n\n        for (int i = 0; i < count; i++) {\n            run1000Call1();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run1000Call1;1000;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 5;\n\n        for (int i = 0; i < count; i++) {\n            run2000Call1();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run2000Call1;2000;\" + String.valueOf(val));\n        //******************************************************************\n        time = System.currentTimeMillis();\n        count = 20;\n\n        for (int i = 0; i < count; i++) {\n            run10Call4();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run10Call4;10;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 20;\n\n        for (int i = 0; i < count; i++) {\n            run20Call4();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run20Call4;20;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 10;\n\n        for (int i = 0; i < count; i++) {\n            run100Call4();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run100Call4;100;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 10;\n\n        for (int i = 0; i < count; i++) {\n            run200Call4();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run200Call4;200;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 5;\n\n        for (int i = 0; i < count; i++) {\n            run1000Call4();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run1000Call4;1000;\" + String.valueOf(val));\n\n        time = System.currentTimeMillis();\n        count = 5;\n\n        for (int i = 0; i < count; i++) {\n            run2000Call4();\n        }\n\n        time = System.currentTimeMillis() - time;\n        val = time / (double) count;\n        ps.println(\"run2000Call4;2000;\" + String.valueOf(val));\n\n        //******************************************************************\n    }\n\n    protected static String complete(String s, int chars) {\n        StringBuffer sb = new StringBuffer(chars);\n        int tot = chars - s.length();\n        sb.append(s);\n\n        for (int i = 0; i < tot; i++) {\n            sb.append(\" \");\n        }\n\n        return sb.substring(0, chars);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/cpu/Methods.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage simple.cpu;\n\n\n/**\n *\n * @author ehucka\n */\npublic class Methods {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of WaitingTest */\n    public Methods() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        System.out.println(\"start app: \" + System.currentTimeMillis());\n\n        Methods test = new Methods();\n\n        for (int i = 0; i < 2; i++) {\n            test.method0();\n        }\n\n        System.out.println(\"end app: \" + System.currentTimeMillis());\n\n        /*\n           //generation\n           int count=100;\n           for (int i=0;i < count;i++) {\n               System.out.println(\"    public void method\"+i+\"() {\");\n               System.out.println(\"        long time=System.currentTimeMillis();\");\n               System.out.println(\"        while ((System.currentTimeMillis()-time) < 10);\");\n               if (i < (count-1))\n                   System.out.println(\"        method\"+(i+1)+\"();\");\n               System.out.println(\"    }\\n\");\n           }*/\n    }\n\n    public void method0() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method1();\n    }\n\n    public void method1() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method2();\n    }\n\n    public void method10() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method11();\n    }\n\n    public void method11() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method12();\n    }\n\n    public void method12() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method13();\n    }\n\n    public void method13() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method14();\n    }\n\n    public void method14() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method15();\n    }\n\n    public void method15() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method16();\n    }\n\n    public void method16() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method17();\n    }\n\n    public void method17() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method18();\n    }\n\n    public void method18() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method19();\n    }\n\n    public void method19() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method20();\n    }\n\n    public void method2() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method3();\n    }\n\n    public void method20() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method21();\n    }\n\n    public void method21() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method22();\n    }\n\n    public void method22() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method23();\n    }\n\n    public void method23() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method24();\n    }\n\n    public void method24() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method25();\n    }\n\n    public void method25() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method26();\n    }\n\n    public void method26() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method27();\n    }\n\n    public void method27() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method28();\n    }\n\n    public void method28() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method29();\n    }\n\n    public void method29() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method30();\n    }\n\n    public void method3() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method4();\n    }\n\n    public void method30() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method31();\n    }\n\n    public void method31() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method32();\n    }\n\n    public void method32() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method33();\n    }\n\n    public void method33() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method34();\n    }\n\n    public void method34() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method35();\n    }\n\n    public void method35() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method36();\n    }\n\n    public void method36() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method37();\n    }\n\n    public void method37() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method38();\n    }\n\n    public void method38() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method39();\n    }\n\n    public void method39() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method40();\n    }\n\n    public void method4() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method5();\n    }\n\n    public void method40() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method41();\n    }\n\n    public void method41() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method42();\n    }\n\n    public void method42() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method43();\n    }\n\n    public void method43() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method44();\n    }\n\n    public void method44() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method45();\n    }\n\n    public void method45() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method46();\n    }\n\n    public void method46() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method47();\n    }\n\n    public void method47() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method48();\n    }\n\n    public void method48() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method49();\n    }\n\n    public void method49() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method50();\n    }\n\n    public void method5() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method6();\n    }\n\n    public void method50() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method51();\n    }\n\n    public void method51() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method52();\n    }\n\n    public void method52() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method53();\n    }\n\n    public void method53() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method54();\n    }\n\n    public void method54() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method55();\n    }\n\n    public void method55() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method56();\n    }\n\n    public void method56() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method57();\n    }\n\n    public void method57() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method58();\n    }\n\n    public void method58() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method59();\n    }\n\n    public void method59() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method60();\n    }\n\n    public void method6() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method7();\n    }\n\n    public void method60() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method61();\n    }\n\n    public void method61() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method62();\n    }\n\n    public void method62() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method63();\n    }\n\n    public void method63() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method64();\n    }\n\n    public void method64() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method65();\n    }\n\n    public void method65() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method66();\n    }\n\n    public void method66() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method67();\n    }\n\n    public void method67() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method68();\n    }\n\n    public void method68() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method69();\n    }\n\n    public void method69() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method70();\n    }\n\n    public void method7() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method8();\n    }\n\n    public void method70() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method71();\n    }\n\n    public void method71() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method72();\n    }\n\n    public void method72() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method73();\n    }\n\n    public void method73() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method74();\n    }\n\n    public void method74() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method75();\n    }\n\n    public void method75() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method76();\n    }\n\n    public void method76() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method77();\n    }\n\n    public void method77() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method78();\n    }\n\n    public void method78() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method79();\n    }\n\n    public void method79() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method80();\n    }\n\n    public void method8() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method9();\n    }\n\n    public void method80() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method81();\n    }\n\n    public void method81() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method82();\n    }\n\n    public void method82() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method83();\n    }\n\n    public void method83() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method84();\n    }\n\n    public void method84() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method85();\n    }\n\n    public void method85() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method86();\n    }\n\n    public void method86() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method87();\n    }\n\n    public void method87() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method88();\n    }\n\n    public void method88() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method89();\n    }\n\n    public void method89() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method90();\n    }\n\n    public void method9() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method10();\n    }\n\n    public void method90() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method91();\n    }\n\n    public void method91() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method92();\n    }\n\n    public void method92() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method93();\n    }\n\n    public void method93() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method94();\n    }\n\n    public void method94() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method95();\n    }\n\n    public void method95() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method96();\n    }\n\n    public void method96() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method97();\n    }\n\n    public void method97() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method98();\n    }\n\n    public void method98() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n\n        method99();\n    }\n\n    public void method99() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 10) {\n            ;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/cpu/Methods2.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage simple.cpu;\n\n\n/**\n *\n * @author ehucka\n */\npublic class Methods2 {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of WaitingTest */\n    public Methods2() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        System.out.println(\"start app: \" + System.currentTimeMillis());\n\n        Methods2 test = new Methods2();\n\n        for (int i = 0; i < 4; i++) {\n            test.method0();\n            test.method9();\n            test.method99();\n            test.method999();\n        }\n\n        System.out.println(\"end app: \" + System.currentTimeMillis());\n\n        /*\n           //generation\n           int methods=1000;\n           System.out.println(\"public void method0() {\\nlong time=System.currentTimeMillis();\");\n           System.out.println(\"while ((System.currentTimeMillis()-time) < 10);\\n}\\n\");\n           for (int i = 1; i < methods; i++) {\n               System.out.println(\"public void method\"+i+\"() {\\nmethod\"+(i-1)+\"();\\n}\\n\");\n           }*/\n    }\n\n    public void method0() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 400) {\n            ;\n        }\n    }\n\n    public void method1() {\n        method0();\n    }\n\n    public void method10() {\n        method9();\n    }\n\n    public void method100() {\n        method99();\n    }\n\n    public void method101() {\n        method100();\n    }\n\n    public void method102() {\n        method101();\n    }\n\n    public void method103() {\n        method102();\n    }\n\n    public void method104() {\n        method103();\n    }\n\n    public void method105() {\n        method104();\n    }\n\n    public void method106() {\n        method105();\n    }\n\n    public void method107() {\n        method106();\n    }\n\n    public void method108() {\n        method107();\n    }\n\n    public void method109() {\n        method108();\n    }\n\n    public void method11() {\n        method10();\n    }\n\n    public void method110() {\n        method109();\n    }\n\n    public void method111() {\n        method110();\n    }\n\n    public void method112() {\n        method111();\n    }\n\n    public void method113() {\n        method112();\n    }\n\n    public void method114() {\n        method113();\n    }\n\n    public void method115() {\n        method114();\n    }\n\n    public void method116() {\n        method115();\n    }\n\n    public void method117() {\n        method116();\n    }\n\n    public void method118() {\n        method117();\n    }\n\n    public void method119() {\n        method118();\n    }\n\n    public void method12() {\n        method11();\n    }\n\n    public void method120() {\n        method119();\n    }\n\n    public void method121() {\n        method120();\n    }\n\n    public void method122() {\n        method121();\n    }\n\n    public void method123() {\n        method122();\n    }\n\n    public void method124() {\n        method123();\n    }\n\n    public void method125() {\n        method124();\n    }\n\n    public void method126() {\n        method125();\n    }\n\n    public void method127() {\n        method126();\n    }\n\n    public void method128() {\n        method127();\n    }\n\n    public void method129() {\n        method128();\n    }\n\n    public void method13() {\n        method12();\n    }\n\n    public void method130() {\n        method129();\n    }\n\n    public void method131() {\n        method130();\n    }\n\n    public void method132() {\n        method131();\n    }\n\n    public void method133() {\n        method132();\n    }\n\n    public void method134() {\n        method133();\n    }\n\n    public void method135() {\n        method134();\n    }\n\n    public void method136() {\n        method135();\n    }\n\n    public void method137() {\n        method136();\n    }\n\n    public void method138() {\n        method137();\n    }\n\n    public void method139() {\n        method138();\n    }\n\n    public void method14() {\n        method13();\n    }\n\n    public void method140() {\n        method139();\n    }\n\n    public void method141() {\n        method140();\n    }\n\n    public void method142() {\n        method141();\n    }\n\n    public void method143() {\n        method142();\n    }\n\n    public void method144() {\n        method143();\n    }\n\n    public void method145() {\n        method144();\n    }\n\n    public void method146() {\n        method145();\n    }\n\n    public void method147() {\n        method146();\n    }\n\n    public void method148() {\n        method147();\n    }\n\n    public void method149() {\n        method148();\n    }\n\n    public void method15() {\n        method14();\n    }\n\n    public void method150() {\n        method149();\n    }\n\n    public void method151() {\n        method150();\n    }\n\n    public void method152() {\n        method151();\n    }\n\n    public void method153() {\n        method152();\n    }\n\n    public void method154() {\n        method153();\n    }\n\n    public void method155() {\n        method154();\n    }\n\n    public void method156() {\n        method155();\n    }\n\n    public void method157() {\n        method156();\n    }\n\n    public void method158() {\n        method157();\n    }\n\n    public void method159() {\n        method158();\n    }\n\n    public void method16() {\n        method15();\n    }\n\n    public void method160() {\n        method159();\n    }\n\n    public void method161() {\n        method160();\n    }\n\n    public void method162() {\n        method161();\n    }\n\n    public void method163() {\n        method162();\n    }\n\n    public void method164() {\n        method163();\n    }\n\n    public void method165() {\n        method164();\n    }\n\n    public void method166() {\n        method165();\n    }\n\n    public void method167() {\n        method166();\n    }\n\n    public void method168() {\n        method167();\n    }\n\n    public void method169() {\n        method168();\n    }\n\n    public void method17() {\n        method16();\n    }\n\n    public void method170() {\n        method169();\n    }\n\n    public void method171() {\n        method170();\n    }\n\n    public void method172() {\n        method171();\n    }\n\n    public void method173() {\n        method172();\n    }\n\n    public void method174() {\n        method173();\n    }\n\n    public void method175() {\n        method174();\n    }\n\n    public void method176() {\n        method175();\n    }\n\n    public void method177() {\n        method176();\n    }\n\n    public void method178() {\n        method177();\n    }\n\n    public void method179() {\n        method178();\n    }\n\n    public void method18() {\n        method17();\n    }\n\n    public void method180() {\n        method179();\n    }\n\n    public void method181() {\n        method180();\n    }\n\n    public void method182() {\n        method181();\n    }\n\n    public void method183() {\n        method182();\n    }\n\n    public void method184() {\n        method183();\n    }\n\n    public void method185() {\n        method184();\n    }\n\n    public void method186() {\n        method185();\n    }\n\n    public void method187() {\n        method186();\n    }\n\n    public void method188() {\n        method187();\n    }\n\n    public void method189() {\n        method188();\n    }\n\n    public void method19() {\n        method18();\n    }\n\n    public void method190() {\n        method189();\n    }\n\n    public void method191() {\n        method190();\n    }\n\n    public void method192() {\n        method191();\n    }\n\n    public void method193() {\n        method192();\n    }\n\n    public void method194() {\n        method193();\n    }\n\n    public void method195() {\n        method194();\n    }\n\n    public void method196() {\n        method195();\n    }\n\n    public void method197() {\n        method196();\n    }\n\n    public void method198() {\n        method197();\n    }\n\n    public void method199() {\n        method198();\n    }\n\n    public void method2() {\n        method1();\n    }\n\n    public void method20() {\n        method19();\n    }\n\n    public void method200() {\n        method199();\n    }\n\n    public void method201() {\n        method200();\n    }\n\n    public void method202() {\n        method201();\n    }\n\n    public void method203() {\n        method202();\n    }\n\n    public void method204() {\n        method203();\n    }\n\n    public void method205() {\n        method204();\n    }\n\n    public void method206() {\n        method205();\n    }\n\n    public void method207() {\n        method206();\n    }\n\n    public void method208() {\n        method207();\n    }\n\n    public void method209() {\n        method208();\n    }\n\n    public void method21() {\n        method20();\n    }\n\n    public void method210() {\n        method209();\n    }\n\n    public void method211() {\n        method210();\n    }\n\n    public void method212() {\n        method211();\n    }\n\n    public void method213() {\n        method212();\n    }\n\n    public void method214() {\n        method213();\n    }\n\n    public void method215() {\n        method214();\n    }\n\n    public void method216() {\n        method215();\n    }\n\n    public void method217() {\n        method216();\n    }\n\n    public void method218() {\n        method217();\n    }\n\n    public void method219() {\n        method218();\n    }\n\n    public void method22() {\n        method21();\n    }\n\n    public void method220() {\n        method219();\n    }\n\n    public void method221() {\n        method220();\n    }\n\n    public void method222() {\n        method221();\n    }\n\n    public void method223() {\n        method222();\n    }\n\n    public void method224() {\n        method223();\n    }\n\n    public void method225() {\n        method224();\n    }\n\n    public void method226() {\n        method225();\n    }\n\n    public void method227() {\n        method226();\n    }\n\n    public void method228() {\n        method227();\n    }\n\n    public void method229() {\n        method228();\n    }\n\n    public void method23() {\n        method22();\n    }\n\n    public void method230() {\n        method229();\n    }\n\n    public void method231() {\n        method230();\n    }\n\n    public void method232() {\n        method231();\n    }\n\n    public void method233() {\n        method232();\n    }\n\n    public void method234() {\n        method233();\n    }\n\n    public void method235() {\n        method234();\n    }\n\n    public void method236() {\n        method235();\n    }\n\n    public void method237() {\n        method236();\n    }\n\n    public void method238() {\n        method237();\n    }\n\n    public void method239() {\n        method238();\n    }\n\n    public void method24() {\n        method23();\n    }\n\n    public void method240() {\n        method239();\n    }\n\n    public void method241() {\n        method240();\n    }\n\n    public void method242() {\n        method241();\n    }\n\n    public void method243() {\n        method242();\n    }\n\n    public void method244() {\n        method243();\n    }\n\n    public void method245() {\n        method244();\n    }\n\n    public void method246() {\n        method245();\n    }\n\n    public void method247() {\n        method246();\n    }\n\n    public void method248() {\n        method247();\n    }\n\n    public void method249() {\n        method248();\n    }\n\n    public void method25() {\n        method24();\n    }\n\n    public void method250() {\n        method249();\n    }\n\n    public void method251() {\n        method250();\n    }\n\n    public void method252() {\n        method251();\n    }\n\n    public void method253() {\n        method252();\n    }\n\n    public void method254() {\n        method253();\n    }\n\n    public void method255() {\n        method254();\n    }\n\n    public void method256() {\n        method255();\n    }\n\n    public void method257() {\n        method256();\n    }\n\n    public void method258() {\n        method257();\n    }\n\n    public void method259() {\n        method258();\n    }\n\n    public void method26() {\n        method25();\n    }\n\n    public void method260() {\n        method259();\n    }\n\n    public void method261() {\n        method260();\n    }\n\n    public void method262() {\n        method261();\n    }\n\n    public void method263() {\n        method262();\n    }\n\n    public void method264() {\n        method263();\n    }\n\n    public void method265() {\n        method264();\n    }\n\n    public void method266() {\n        method265();\n    }\n\n    public void method267() {\n        method266();\n    }\n\n    public void method268() {\n        method267();\n    }\n\n    public void method269() {\n        method268();\n    }\n\n    public void method27() {\n        method26();\n    }\n\n    public void method270() {\n        method269();\n    }\n\n    public void method271() {\n        method270();\n    }\n\n    public void method272() {\n        method271();\n    }\n\n    public void method273() {\n        method272();\n    }\n\n    public void method274() {\n        method273();\n    }\n\n    public void method275() {\n        method274();\n    }\n\n    public void method276() {\n        method275();\n    }\n\n    public void method277() {\n        method276();\n    }\n\n    public void method278() {\n        method277();\n    }\n\n    public void method279() {\n        method278();\n    }\n\n    public void method28() {\n        method27();\n    }\n\n    public void method280() {\n        method279();\n    }\n\n    public void method281() {\n        method280();\n    }\n\n    public void method282() {\n        method281();\n    }\n\n    public void method283() {\n        method282();\n    }\n\n    public void method284() {\n        method283();\n    }\n\n    public void method285() {\n        method284();\n    }\n\n    public void method286() {\n        method285();\n    }\n\n    public void method287() {\n        method286();\n    }\n\n    public void method288() {\n        method287();\n    }\n\n    public void method289() {\n        method288();\n    }\n\n    public void method29() {\n        method28();\n    }\n\n    public void method290() {\n        method289();\n    }\n\n    public void method291() {\n        method290();\n    }\n\n    public void method292() {\n        method291();\n    }\n\n    public void method293() {\n        method292();\n    }\n\n    public void method294() {\n        method293();\n    }\n\n    public void method295() {\n        method294();\n    }\n\n    public void method296() {\n        method295();\n    }\n\n    public void method297() {\n        method296();\n    }\n\n    public void method298() {\n        method297();\n    }\n\n    public void method299() {\n        method298();\n    }\n\n    public void method3() {\n        method2();\n    }\n\n    public void method30() {\n        method29();\n    }\n\n    public void method300() {\n        method299();\n    }\n\n    public void method301() {\n        method300();\n    }\n\n    public void method302() {\n        method301();\n    }\n\n    public void method303() {\n        method302();\n    }\n\n    public void method304() {\n        method303();\n    }\n\n    public void method305() {\n        method304();\n    }\n\n    public void method306() {\n        method305();\n    }\n\n    public void method307() {\n        method306();\n    }\n\n    public void method308() {\n        method307();\n    }\n\n    public void method309() {\n        method308();\n    }\n\n    public void method31() {\n        method30();\n    }\n\n    public void method310() {\n        method309();\n    }\n\n    public void method311() {\n        method310();\n    }\n\n    public void method312() {\n        method311();\n    }\n\n    public void method313() {\n        method312();\n    }\n\n    public void method314() {\n        method313();\n    }\n\n    public void method315() {\n        method314();\n    }\n\n    public void method316() {\n        method315();\n    }\n\n    public void method317() {\n        method316();\n    }\n\n    public void method318() {\n        method317();\n    }\n\n    public void method319() {\n        method318();\n    }\n\n    public void method32() {\n        method31();\n    }\n\n    public void method320() {\n        method319();\n    }\n\n    public void method321() {\n        method320();\n    }\n\n    public void method322() {\n        method321();\n    }\n\n    public void method323() {\n        method322();\n    }\n\n    public void method324() {\n        method323();\n    }\n\n    public void method325() {\n        method324();\n    }\n\n    public void method326() {\n        method325();\n    }\n\n    public void method327() {\n        method326();\n    }\n\n    public void method328() {\n        method327();\n    }\n\n    public void method329() {\n        method328();\n    }\n\n    public void method33() {\n        method32();\n    }\n\n    public void method330() {\n        method329();\n    }\n\n    public void method331() {\n        method330();\n    }\n\n    public void method332() {\n        method331();\n    }\n\n    public void method333() {\n        method332();\n    }\n\n    public void method334() {\n        method333();\n    }\n\n    public void method335() {\n        method334();\n    }\n\n    public void method336() {\n        method335();\n    }\n\n    public void method337() {\n        method336();\n    }\n\n    public void method338() {\n        method337();\n    }\n\n    public void method339() {\n        method338();\n    }\n\n    public void method34() {\n        method33();\n    }\n\n    public void method340() {\n        method339();\n    }\n\n    public void method341() {\n        method340();\n    }\n\n    public void method342() {\n        method341();\n    }\n\n    public void method343() {\n        method342();\n    }\n\n    public void method344() {\n        method343();\n    }\n\n    public void method345() {\n        method344();\n    }\n\n    public void method346() {\n        method345();\n    }\n\n    public void method347() {\n        method346();\n    }\n\n    public void method348() {\n        method347();\n    }\n\n    public void method349() {\n        method348();\n    }\n\n    public void method35() {\n        method34();\n    }\n\n    public void method350() {\n        method349();\n    }\n\n    public void method351() {\n        method350();\n    }\n\n    public void method352() {\n        method351();\n    }\n\n    public void method353() {\n        method352();\n    }\n\n    public void method354() {\n        method353();\n    }\n\n    public void method355() {\n        method354();\n    }\n\n    public void method356() {\n        method355();\n    }\n\n    public void method357() {\n        method356();\n    }\n\n    public void method358() {\n        method357();\n    }\n\n    public void method359() {\n        method358();\n    }\n\n    public void method36() {\n        method35();\n    }\n\n    public void method360() {\n        method359();\n    }\n\n    public void method361() {\n        method360();\n    }\n\n    public void method362() {\n        method361();\n    }\n\n    public void method363() {\n        method362();\n    }\n\n    public void method364() {\n        method363();\n    }\n\n    public void method365() {\n        method364();\n    }\n\n    public void method366() {\n        method365();\n    }\n\n    public void method367() {\n        method366();\n    }\n\n    public void method368() {\n        method367();\n    }\n\n    public void method369() {\n        method368();\n    }\n\n    public void method37() {\n        method36();\n    }\n\n    public void method370() {\n        method369();\n    }\n\n    public void method371() {\n        method370();\n    }\n\n    public void method372() {\n        method371();\n    }\n\n    public void method373() {\n        method372();\n    }\n\n    public void method374() {\n        method373();\n    }\n\n    public void method375() {\n        method374();\n    }\n\n    public void method376() {\n        method375();\n    }\n\n    public void method377() {\n        method376();\n    }\n\n    public void method378() {\n        method377();\n    }\n\n    public void method379() {\n        method378();\n    }\n\n    public void method38() {\n        method37();\n    }\n\n    public void method380() {\n        method379();\n    }\n\n    public void method381() {\n        method380();\n    }\n\n    public void method382() {\n        method381();\n    }\n\n    public void method383() {\n        method382();\n    }\n\n    public void method384() {\n        method383();\n    }\n\n    public void method385() {\n        method384();\n    }\n\n    public void method386() {\n        method385();\n    }\n\n    public void method387() {\n        method386();\n    }\n\n    public void method388() {\n        method387();\n    }\n\n    public void method389() {\n        method388();\n    }\n\n    public void method39() {\n        method38();\n    }\n\n    public void method390() {\n        method389();\n    }\n\n    public void method391() {\n        method390();\n    }\n\n    public void method392() {\n        method391();\n    }\n\n    public void method393() {\n        method392();\n    }\n\n    public void method394() {\n        method393();\n    }\n\n    public void method395() {\n        method394();\n    }\n\n    public void method396() {\n        method395();\n    }\n\n    public void method397() {\n        method396();\n    }\n\n    public void method398() {\n        method397();\n    }\n\n    public void method399() {\n        method398();\n    }\n\n    public void method4() {\n        method3();\n    }\n\n    public void method40() {\n        method39();\n    }\n\n    public void method400() {\n        method399();\n    }\n\n    public void method401() {\n        method400();\n    }\n\n    public void method402() {\n        method401();\n    }\n\n    public void method403() {\n        method402();\n    }\n\n    public void method404() {\n        method403();\n    }\n\n    public void method405() {\n        method404();\n    }\n\n    public void method406() {\n        method405();\n    }\n\n    public void method407() {\n        method406();\n    }\n\n    public void method408() {\n        method407();\n    }\n\n    public void method409() {\n        method408();\n    }\n\n    public void method41() {\n        method40();\n    }\n\n    public void method410() {\n        method409();\n    }\n\n    public void method411() {\n        method410();\n    }\n\n    public void method412() {\n        method411();\n    }\n\n    public void method413() {\n        method412();\n    }\n\n    public void method414() {\n        method413();\n    }\n\n    public void method415() {\n        method414();\n    }\n\n    public void method416() {\n        method415();\n    }\n\n    public void method417() {\n        method416();\n    }\n\n    public void method418() {\n        method417();\n    }\n\n    public void method419() {\n        method418();\n    }\n\n    public void method42() {\n        method41();\n    }\n\n    public void method420() {\n        method419();\n    }\n\n    public void method421() {\n        method420();\n    }\n\n    public void method422() {\n        method421();\n    }\n\n    public void method423() {\n        method422();\n    }\n\n    public void method424() {\n        method423();\n    }\n\n    public void method425() {\n        method424();\n    }\n\n    public void method426() {\n        method425();\n    }\n\n    public void method427() {\n        method426();\n    }\n\n    public void method428() {\n        method427();\n    }\n\n    public void method429() {\n        method428();\n    }\n\n    public void method43() {\n        method42();\n    }\n\n    public void method430() {\n        method429();\n    }\n\n    public void method431() {\n        method430();\n    }\n\n    public void method432() {\n        method431();\n    }\n\n    public void method433() {\n        method432();\n    }\n\n    public void method434() {\n        method433();\n    }\n\n    public void method435() {\n        method434();\n    }\n\n    public void method436() {\n        method435();\n    }\n\n    public void method437() {\n        method436();\n    }\n\n    public void method438() {\n        method437();\n    }\n\n    public void method439() {\n        method438();\n    }\n\n    public void method44() {\n        method43();\n    }\n\n    public void method440() {\n        method439();\n    }\n\n    public void method441() {\n        method440();\n    }\n\n    public void method442() {\n        method441();\n    }\n\n    public void method443() {\n        method442();\n    }\n\n    public void method444() {\n        method443();\n    }\n\n    public void method445() {\n        method444();\n    }\n\n    public void method446() {\n        method445();\n    }\n\n    public void method447() {\n        method446();\n    }\n\n    public void method448() {\n        method447();\n    }\n\n    public void method449() {\n        method448();\n    }\n\n    public void method45() {\n        method44();\n    }\n\n    public void method450() {\n        method449();\n    }\n\n    public void method451() {\n        method450();\n    }\n\n    public void method452() {\n        method451();\n    }\n\n    public void method453() {\n        method452();\n    }\n\n    public void method454() {\n        method453();\n    }\n\n    public void method455() {\n        method454();\n    }\n\n    public void method456() {\n        method455();\n    }\n\n    public void method457() {\n        method456();\n    }\n\n    public void method458() {\n        method457();\n    }\n\n    public void method459() {\n        method458();\n    }\n\n    public void method46() {\n        method45();\n    }\n\n    public void method460() {\n        method459();\n    }\n\n    public void method461() {\n        method460();\n    }\n\n    public void method462() {\n        method461();\n    }\n\n    public void method463() {\n        method462();\n    }\n\n    public void method464() {\n        method463();\n    }\n\n    public void method465() {\n        method464();\n    }\n\n    public void method466() {\n        method465();\n    }\n\n    public void method467() {\n        method466();\n    }\n\n    public void method468() {\n        method467();\n    }\n\n    public void method469() {\n        method468();\n    }\n\n    public void method47() {\n        method46();\n    }\n\n    public void method470() {\n        method469();\n    }\n\n    public void method471() {\n        method470();\n    }\n\n    public void method472() {\n        method471();\n    }\n\n    public void method473() {\n        method472();\n    }\n\n    public void method474() {\n        method473();\n    }\n\n    public void method475() {\n        method474();\n    }\n\n    public void method476() {\n        method475();\n    }\n\n    public void method477() {\n        method476();\n    }\n\n    public void method478() {\n        method477();\n    }\n\n    public void method479() {\n        method478();\n    }\n\n    public void method48() {\n        method47();\n    }\n\n    public void method480() {\n        method479();\n    }\n\n    public void method481() {\n        method480();\n    }\n\n    public void method482() {\n        method481();\n    }\n\n    public void method483() {\n        method482();\n    }\n\n    public void method484() {\n        method483();\n    }\n\n    public void method485() {\n        method484();\n    }\n\n    public void method486() {\n        method485();\n    }\n\n    public void method487() {\n        method486();\n    }\n\n    public void method488() {\n        method487();\n    }\n\n    public void method489() {\n        method488();\n    }\n\n    public void method49() {\n        method48();\n    }\n\n    public void method490() {\n        method489();\n    }\n\n    public void method491() {\n        method490();\n    }\n\n    public void method492() {\n        method491();\n    }\n\n    public void method493() {\n        method492();\n    }\n\n    public void method494() {\n        method493();\n    }\n\n    public void method495() {\n        method494();\n    }\n\n    public void method496() {\n        method495();\n    }\n\n    public void method497() {\n        method496();\n    }\n\n    public void method498() {\n        method497();\n    }\n\n    public void method499() {\n        method498();\n    }\n\n    public void method5() {\n        method4();\n    }\n\n    public void method50() {\n        method49();\n    }\n\n    public void method500() {\n        method499();\n    }\n\n    public void method501() {\n        method500();\n    }\n\n    public void method502() {\n        method501();\n    }\n\n    public void method503() {\n        method502();\n    }\n\n    public void method504() {\n        method503();\n    }\n\n    public void method505() {\n        method504();\n    }\n\n    public void method506() {\n        method505();\n    }\n\n    public void method507() {\n        method506();\n    }\n\n    public void method508() {\n        method507();\n    }\n\n    public void method509() {\n        method508();\n    }\n\n    public void method51() {\n        method50();\n    }\n\n    public void method510() {\n        method509();\n    }\n\n    public void method511() {\n        method510();\n    }\n\n    public void method512() {\n        method511();\n    }\n\n    public void method513() {\n        method512();\n    }\n\n    public void method514() {\n        method513();\n    }\n\n    public void method515() {\n        method514();\n    }\n\n    public void method516() {\n        method515();\n    }\n\n    public void method517() {\n        method516();\n    }\n\n    public void method518() {\n        method517();\n    }\n\n    public void method519() {\n        method518();\n    }\n\n    public void method52() {\n        method51();\n    }\n\n    public void method520() {\n        method519();\n    }\n\n    public void method521() {\n        method520();\n    }\n\n    public void method522() {\n        method521();\n    }\n\n    public void method523() {\n        method522();\n    }\n\n    public void method524() {\n        method523();\n    }\n\n    public void method525() {\n        method524();\n    }\n\n    public void method526() {\n        method525();\n    }\n\n    public void method527() {\n        method526();\n    }\n\n    public void method528() {\n        method527();\n    }\n\n    public void method529() {\n        method528();\n    }\n\n    public void method53() {\n        method52();\n    }\n\n    public void method530() {\n        method529();\n    }\n\n    public void method531() {\n        method530();\n    }\n\n    public void method532() {\n        method531();\n    }\n\n    public void method533() {\n        method532();\n    }\n\n    public void method534() {\n        method533();\n    }\n\n    public void method535() {\n        method534();\n    }\n\n    public void method536() {\n        method535();\n    }\n\n    public void method537() {\n        method536();\n    }\n\n    public void method538() {\n        method537();\n    }\n\n    public void method539() {\n        method538();\n    }\n\n    public void method54() {\n        method53();\n    }\n\n    public void method540() {\n        method539();\n    }\n\n    public void method541() {\n        method540();\n    }\n\n    public void method542() {\n        method541();\n    }\n\n    public void method543() {\n        method542();\n    }\n\n    public void method544() {\n        method543();\n    }\n\n    public void method545() {\n        method544();\n    }\n\n    public void method546() {\n        method545();\n    }\n\n    public void method547() {\n        method546();\n    }\n\n    public void method548() {\n        method547();\n    }\n\n    public void method549() {\n        method548();\n    }\n\n    public void method55() {\n        method54();\n    }\n\n    public void method550() {\n        method549();\n    }\n\n    public void method551() {\n        method550();\n    }\n\n    public void method552() {\n        method551();\n    }\n\n    public void method553() {\n        method552();\n    }\n\n    public void method554() {\n        method553();\n    }\n\n    public void method555() {\n        method554();\n    }\n\n    public void method556() {\n        method555();\n    }\n\n    public void method557() {\n        method556();\n    }\n\n    public void method558() {\n        method557();\n    }\n\n    public void method559() {\n        method558();\n    }\n\n    public void method56() {\n        method55();\n    }\n\n    public void method560() {\n        method559();\n    }\n\n    public void method561() {\n        method560();\n    }\n\n    public void method562() {\n        method561();\n    }\n\n    public void method563() {\n        method562();\n    }\n\n    public void method564() {\n        method563();\n    }\n\n    public void method565() {\n        method564();\n    }\n\n    public void method566() {\n        method565();\n    }\n\n    public void method567() {\n        method566();\n    }\n\n    public void method568() {\n        method567();\n    }\n\n    public void method569() {\n        method568();\n    }\n\n    public void method57() {\n        method56();\n    }\n\n    public void method570() {\n        method569();\n    }\n\n    public void method571() {\n        method570();\n    }\n\n    public void method572() {\n        method571();\n    }\n\n    public void method573() {\n        method572();\n    }\n\n    public void method574() {\n        method573();\n    }\n\n    public void method575() {\n        method574();\n    }\n\n    public void method576() {\n        method575();\n    }\n\n    public void method577() {\n        method576();\n    }\n\n    public void method578() {\n        method577();\n    }\n\n    public void method579() {\n        method578();\n    }\n\n    public void method58() {\n        method57();\n    }\n\n    public void method580() {\n        method579();\n    }\n\n    public void method581() {\n        method580();\n    }\n\n    public void method582() {\n        method581();\n    }\n\n    public void method583() {\n        method582();\n    }\n\n    public void method584() {\n        method583();\n    }\n\n    public void method585() {\n        method584();\n    }\n\n    public void method586() {\n        method585();\n    }\n\n    public void method587() {\n        method586();\n    }\n\n    public void method588() {\n        method587();\n    }\n\n    public void method589() {\n        method588();\n    }\n\n    public void method59() {\n        method58();\n    }\n\n    public void method590() {\n        method589();\n    }\n\n    public void method591() {\n        method590();\n    }\n\n    public void method592() {\n        method591();\n    }\n\n    public void method593() {\n        method592();\n    }\n\n    public void method594() {\n        method593();\n    }\n\n    public void method595() {\n        method594();\n    }\n\n    public void method596() {\n        method595();\n    }\n\n    public void method597() {\n        method596();\n    }\n\n    public void method598() {\n        method597();\n    }\n\n    public void method599() {\n        method598();\n    }\n\n    public void method6() {\n        method5();\n    }\n\n    public void method60() {\n        method59();\n    }\n\n    public void method600() {\n        method599();\n    }\n\n    public void method601() {\n        method600();\n    }\n\n    public void method602() {\n        method601();\n    }\n\n    public void method603() {\n        method602();\n    }\n\n    public void method604() {\n        method603();\n    }\n\n    public void method605() {\n        method604();\n    }\n\n    public void method606() {\n        method605();\n    }\n\n    public void method607() {\n        method606();\n    }\n\n    public void method608() {\n        method607();\n    }\n\n    public void method609() {\n        method608();\n    }\n\n    public void method61() {\n        method60();\n    }\n\n    public void method610() {\n        method609();\n    }\n\n    public void method611() {\n        method610();\n    }\n\n    public void method612() {\n        method611();\n    }\n\n    public void method613() {\n        method612();\n    }\n\n    public void method614() {\n        method613();\n    }\n\n    public void method615() {\n        method614();\n    }\n\n    public void method616() {\n        method615();\n    }\n\n    public void method617() {\n        method616();\n    }\n\n    public void method618() {\n        method617();\n    }\n\n    public void method619() {\n        method618();\n    }\n\n    public void method62() {\n        method61();\n    }\n\n    public void method620() {\n        method619();\n    }\n\n    public void method621() {\n        method620();\n    }\n\n    public void method622() {\n        method621();\n    }\n\n    public void method623() {\n        method622();\n    }\n\n    public void method624() {\n        method623();\n    }\n\n    public void method625() {\n        method624();\n    }\n\n    public void method626() {\n        method625();\n    }\n\n    public void method627() {\n        method626();\n    }\n\n    public void method628() {\n        method627();\n    }\n\n    public void method629() {\n        method628();\n    }\n\n    public void method63() {\n        method62();\n    }\n\n    public void method630() {\n        method629();\n    }\n\n    public void method631() {\n        method630();\n    }\n\n    public void method632() {\n        method631();\n    }\n\n    public void method633() {\n        method632();\n    }\n\n    public void method634() {\n        method633();\n    }\n\n    public void method635() {\n        method634();\n    }\n\n    public void method636() {\n        method635();\n    }\n\n    public void method637() {\n        method636();\n    }\n\n    public void method638() {\n        method637();\n    }\n\n    public void method639() {\n        method638();\n    }\n\n    public void method64() {\n        method63();\n    }\n\n    public void method640() {\n        method639();\n    }\n\n    public void method641() {\n        method640();\n    }\n\n    public void method642() {\n        method641();\n    }\n\n    public void method643() {\n        method642();\n    }\n\n    public void method644() {\n        method643();\n    }\n\n    public void method645() {\n        method644();\n    }\n\n    public void method646() {\n        method645();\n    }\n\n    public void method647() {\n        method646();\n    }\n\n    public void method648() {\n        method647();\n    }\n\n    public void method649() {\n        method648();\n    }\n\n    public void method65() {\n        method64();\n    }\n\n    public void method650() {\n        method649();\n    }\n\n    public void method651() {\n        method650();\n    }\n\n    public void method652() {\n        method651();\n    }\n\n    public void method653() {\n        method652();\n    }\n\n    public void method654() {\n        method653();\n    }\n\n    public void method655() {\n        method654();\n    }\n\n    public void method656() {\n        method655();\n    }\n\n    public void method657() {\n        method656();\n    }\n\n    public void method658() {\n        method657();\n    }\n\n    public void method659() {\n        method658();\n    }\n\n    public void method66() {\n        method65();\n    }\n\n    public void method660() {\n        method659();\n    }\n\n    public void method661() {\n        method660();\n    }\n\n    public void method662() {\n        method661();\n    }\n\n    public void method663() {\n        method662();\n    }\n\n    public void method664() {\n        method663();\n    }\n\n    public void method665() {\n        method664();\n    }\n\n    public void method666() {\n        method665();\n    }\n\n    public void method667() {\n        method666();\n    }\n\n    public void method668() {\n        method667();\n    }\n\n    public void method669() {\n        method668();\n    }\n\n    public void method67() {\n        method66();\n    }\n\n    public void method670() {\n        method669();\n    }\n\n    public void method671() {\n        method670();\n    }\n\n    public void method672() {\n        method671();\n    }\n\n    public void method673() {\n        method672();\n    }\n\n    public void method674() {\n        method673();\n    }\n\n    public void method675() {\n        method674();\n    }\n\n    public void method676() {\n        method675();\n    }\n\n    public void method677() {\n        method676();\n    }\n\n    public void method678() {\n        method677();\n    }\n\n    public void method679() {\n        method678();\n    }\n\n    public void method68() {\n        method67();\n    }\n\n    public void method680() {\n        method679();\n    }\n\n    public void method681() {\n        method680();\n    }\n\n    public void method682() {\n        method681();\n    }\n\n    public void method683() {\n        method682();\n    }\n\n    public void method684() {\n        method683();\n    }\n\n    public void method685() {\n        method684();\n    }\n\n    public void method686() {\n        method685();\n    }\n\n    public void method687() {\n        method686();\n    }\n\n    public void method688() {\n        method687();\n    }\n\n    public void method689() {\n        method688();\n    }\n\n    public void method69() {\n        method68();\n    }\n\n    public void method690() {\n        method689();\n    }\n\n    public void method691() {\n        method690();\n    }\n\n    public void method692() {\n        method691();\n    }\n\n    public void method693() {\n        method692();\n    }\n\n    public void method694() {\n        method693();\n    }\n\n    public void method695() {\n        method694();\n    }\n\n    public void method696() {\n        method695();\n    }\n\n    public void method697() {\n        method696();\n    }\n\n    public void method698() {\n        method697();\n    }\n\n    public void method699() {\n        method698();\n    }\n\n    public void method7() {\n        method6();\n    }\n\n    public void method70() {\n        method69();\n    }\n\n    public void method700() {\n        method699();\n    }\n\n    public void method701() {\n        method700();\n    }\n\n    public void method702() {\n        method701();\n    }\n\n    public void method703() {\n        method702();\n    }\n\n    public void method704() {\n        method703();\n    }\n\n    public void method705() {\n        method704();\n    }\n\n    public void method706() {\n        method705();\n    }\n\n    public void method707() {\n        method706();\n    }\n\n    public void method708() {\n        method707();\n    }\n\n    public void method709() {\n        method708();\n    }\n\n    public void method71() {\n        method70();\n    }\n\n    public void method710() {\n        method709();\n    }\n\n    public void method711() {\n        method710();\n    }\n\n    public void method712() {\n        method711();\n    }\n\n    public void method713() {\n        method712();\n    }\n\n    public void method714() {\n        method713();\n    }\n\n    public void method715() {\n        method714();\n    }\n\n    public void method716() {\n        method715();\n    }\n\n    public void method717() {\n        method716();\n    }\n\n    public void method718() {\n        method717();\n    }\n\n    public void method719() {\n        method718();\n    }\n\n    public void method72() {\n        method71();\n    }\n\n    public void method720() {\n        method719();\n    }\n\n    public void method721() {\n        method720();\n    }\n\n    public void method722() {\n        method721();\n    }\n\n    public void method723() {\n        method722();\n    }\n\n    public void method724() {\n        method723();\n    }\n\n    public void method725() {\n        method724();\n    }\n\n    public void method726() {\n        method725();\n    }\n\n    public void method727() {\n        method726();\n    }\n\n    public void method728() {\n        method727();\n    }\n\n    public void method729() {\n        method728();\n    }\n\n    public void method73() {\n        method72();\n    }\n\n    public void method730() {\n        method729();\n    }\n\n    public void method731() {\n        method730();\n    }\n\n    public void method732() {\n        method731();\n    }\n\n    public void method733() {\n        method732();\n    }\n\n    public void method734() {\n        method733();\n    }\n\n    public void method735() {\n        method734();\n    }\n\n    public void method736() {\n        method735();\n    }\n\n    public void method737() {\n        method736();\n    }\n\n    public void method738() {\n        method737();\n    }\n\n    public void method739() {\n        method738();\n    }\n\n    public void method74() {\n        method73();\n    }\n\n    public void method740() {\n        method739();\n    }\n\n    public void method741() {\n        method740();\n    }\n\n    public void method742() {\n        method741();\n    }\n\n    public void method743() {\n        method742();\n    }\n\n    public void method744() {\n        method743();\n    }\n\n    public void method745() {\n        method744();\n    }\n\n    public void method746() {\n        method745();\n    }\n\n    public void method747() {\n        method746();\n    }\n\n    public void method748() {\n        method747();\n    }\n\n    public void method749() {\n        method748();\n    }\n\n    public void method75() {\n        method74();\n    }\n\n    public void method750() {\n        method749();\n    }\n\n    public void method751() {\n        method750();\n    }\n\n    public void method752() {\n        method751();\n    }\n\n    public void method753() {\n        method752();\n    }\n\n    public void method754() {\n        method753();\n    }\n\n    public void method755() {\n        method754();\n    }\n\n    public void method756() {\n        method755();\n    }\n\n    public void method757() {\n        method756();\n    }\n\n    public void method758() {\n        method757();\n    }\n\n    public void method759() {\n        method758();\n    }\n\n    public void method76() {\n        method75();\n    }\n\n    public void method760() {\n        method759();\n    }\n\n    public void method761() {\n        method760();\n    }\n\n    public void method762() {\n        method761();\n    }\n\n    public void method763() {\n        method762();\n    }\n\n    public void method764() {\n        method763();\n    }\n\n    public void method765() {\n        method764();\n    }\n\n    public void method766() {\n        method765();\n    }\n\n    public void method767() {\n        method766();\n    }\n\n    public void method768() {\n        method767();\n    }\n\n    public void method769() {\n        method768();\n    }\n\n    public void method77() {\n        method76();\n    }\n\n    public void method770() {\n        method769();\n    }\n\n    public void method771() {\n        method770();\n    }\n\n    public void method772() {\n        method771();\n    }\n\n    public void method773() {\n        method772();\n    }\n\n    public void method774() {\n        method773();\n    }\n\n    public void method775() {\n        method774();\n    }\n\n    public void method776() {\n        method775();\n    }\n\n    public void method777() {\n        method776();\n    }\n\n    public void method778() {\n        method777();\n    }\n\n    public void method779() {\n        method778();\n    }\n\n    public void method78() {\n        method77();\n    }\n\n    public void method780() {\n        method779();\n    }\n\n    public void method781() {\n        method780();\n    }\n\n    public void method782() {\n        method781();\n    }\n\n    public void method783() {\n        method782();\n    }\n\n    public void method784() {\n        method783();\n    }\n\n    public void method785() {\n        method784();\n    }\n\n    public void method786() {\n        method785();\n    }\n\n    public void method787() {\n        method786();\n    }\n\n    public void method788() {\n        method787();\n    }\n\n    public void method789() {\n        method788();\n    }\n\n    public void method79() {\n        method78();\n    }\n\n    public void method790() {\n        method789();\n    }\n\n    public void method791() {\n        method790();\n    }\n\n    public void method792() {\n        method791();\n    }\n\n    public void method793() {\n        method792();\n    }\n\n    public void method794() {\n        method793();\n    }\n\n    public void method795() {\n        method794();\n    }\n\n    public void method796() {\n        method795();\n    }\n\n    public void method797() {\n        method796();\n    }\n\n    public void method798() {\n        method797();\n    }\n\n    public void method799() {\n        method798();\n    }\n\n    public void method8() {\n        method7();\n    }\n\n    public void method80() {\n        method79();\n    }\n\n    public void method800() {\n        method799();\n    }\n\n    public void method801() {\n        method800();\n    }\n\n    public void method802() {\n        method801();\n    }\n\n    public void method803() {\n        method802();\n    }\n\n    public void method804() {\n        method803();\n    }\n\n    public void method805() {\n        method804();\n    }\n\n    public void method806() {\n        method805();\n    }\n\n    public void method807() {\n        method806();\n    }\n\n    public void method808() {\n        method807();\n    }\n\n    public void method809() {\n        method808();\n    }\n\n    public void method81() {\n        method80();\n    }\n\n    public void method810() {\n        method809();\n    }\n\n    public void method811() {\n        method810();\n    }\n\n    public void method812() {\n        method811();\n    }\n\n    public void method813() {\n        method812();\n    }\n\n    public void method814() {\n        method813();\n    }\n\n    public void method815() {\n        method814();\n    }\n\n    public void method816() {\n        method815();\n    }\n\n    public void method817() {\n        method816();\n    }\n\n    public void method818() {\n        method817();\n    }\n\n    public void method819() {\n        method818();\n    }\n\n    public void method82() {\n        method81();\n    }\n\n    public void method820() {\n        method819();\n    }\n\n    public void method821() {\n        method820();\n    }\n\n    public void method822() {\n        method821();\n    }\n\n    public void method823() {\n        method822();\n    }\n\n    public void method824() {\n        method823();\n    }\n\n    public void method825() {\n        method824();\n    }\n\n    public void method826() {\n        method825();\n    }\n\n    public void method827() {\n        method826();\n    }\n\n    public void method828() {\n        method827();\n    }\n\n    public void method829() {\n        method828();\n    }\n\n    public void method83() {\n        method82();\n    }\n\n    public void method830() {\n        method829();\n    }\n\n    public void method831() {\n        method830();\n    }\n\n    public void method832() {\n        method831();\n    }\n\n    public void method833() {\n        method832();\n    }\n\n    public void method834() {\n        method833();\n    }\n\n    public void method835() {\n        method834();\n    }\n\n    public void method836() {\n        method835();\n    }\n\n    public void method837() {\n        method836();\n    }\n\n    public void method838() {\n        method837();\n    }\n\n    public void method839() {\n        method838();\n    }\n\n    public void method84() {\n        method83();\n    }\n\n    public void method840() {\n        method839();\n    }\n\n    public void method841() {\n        method840();\n    }\n\n    public void method842() {\n        method841();\n    }\n\n    public void method843() {\n        method842();\n    }\n\n    public void method844() {\n        method843();\n    }\n\n    public void method845() {\n        method844();\n    }\n\n    public void method846() {\n        method845();\n    }\n\n    public void method847() {\n        method846();\n    }\n\n    public void method848() {\n        method847();\n    }\n\n    public void method849() {\n        method848();\n    }\n\n    public void method85() {\n        method84();\n    }\n\n    public void method850() {\n        method849();\n    }\n\n    public void method851() {\n        method850();\n    }\n\n    public void method852() {\n        method851();\n    }\n\n    public void method853() {\n        method852();\n    }\n\n    public void method854() {\n        method853();\n    }\n\n    public void method855() {\n        method854();\n    }\n\n    public void method856() {\n        method855();\n    }\n\n    public void method857() {\n        method856();\n    }\n\n    public void method858() {\n        method857();\n    }\n\n    public void method859() {\n        method858();\n    }\n\n    public void method86() {\n        method85();\n    }\n\n    public void method860() {\n        method859();\n    }\n\n    public void method861() {\n        method860();\n    }\n\n    public void method862() {\n        method861();\n    }\n\n    public void method863() {\n        method862();\n    }\n\n    public void method864() {\n        method863();\n    }\n\n    public void method865() {\n        method864();\n    }\n\n    public void method866() {\n        method865();\n    }\n\n    public void method867() {\n        method866();\n    }\n\n    public void method868() {\n        method867();\n    }\n\n    public void method869() {\n        method868();\n    }\n\n    public void method87() {\n        method86();\n    }\n\n    public void method870() {\n        method869();\n    }\n\n    public void method871() {\n        method870();\n    }\n\n    public void method872() {\n        method871();\n    }\n\n    public void method873() {\n        method872();\n    }\n\n    public void method874() {\n        method873();\n    }\n\n    public void method875() {\n        method874();\n    }\n\n    public void method876() {\n        method875();\n    }\n\n    public void method877() {\n        method876();\n    }\n\n    public void method878() {\n        method877();\n    }\n\n    public void method879() {\n        method878();\n    }\n\n    public void method88() {\n        method87();\n    }\n\n    public void method880() {\n        method879();\n    }\n\n    public void method881() {\n        method880();\n    }\n\n    public void method882() {\n        method881();\n    }\n\n    public void method883() {\n        method882();\n    }\n\n    public void method884() {\n        method883();\n    }\n\n    public void method885() {\n        method884();\n    }\n\n    public void method886() {\n        method885();\n    }\n\n    public void method887() {\n        method886();\n    }\n\n    public void method888() {\n        method887();\n    }\n\n    public void method889() {\n        method888();\n    }\n\n    public void method89() {\n        method88();\n    }\n\n    public void method890() {\n        method889();\n    }\n\n    public void method891() {\n        method890();\n    }\n\n    public void method892() {\n        method891();\n    }\n\n    public void method893() {\n        method892();\n    }\n\n    public void method894() {\n        method893();\n    }\n\n    public void method895() {\n        method894();\n    }\n\n    public void method896() {\n        method895();\n    }\n\n    public void method897() {\n        method896();\n    }\n\n    public void method898() {\n        method897();\n    }\n\n    public void method899() {\n        method898();\n    }\n\n    public void method9() {\n        method8();\n    }\n\n    public void method90() {\n        method89();\n    }\n\n    public void method900() {\n        method899();\n    }\n\n    public void method901() {\n        method900();\n    }\n\n    public void method902() {\n        method901();\n    }\n\n    public void method903() {\n        method902();\n    }\n\n    public void method904() {\n        method903();\n    }\n\n    public void method905() {\n        method904();\n    }\n\n    public void method906() {\n        method905();\n    }\n\n    public void method907() {\n        method906();\n    }\n\n    public void method908() {\n        method907();\n    }\n\n    public void method909() {\n        method908();\n    }\n\n    public void method91() {\n        method90();\n    }\n\n    public void method910() {\n        method909();\n    }\n\n    public void method911() {\n        method910();\n    }\n\n    public void method912() {\n        method911();\n    }\n\n    public void method913() {\n        method912();\n    }\n\n    public void method914() {\n        method913();\n    }\n\n    public void method915() {\n        method914();\n    }\n\n    public void method916() {\n        method915();\n    }\n\n    public void method917() {\n        method916();\n    }\n\n    public void method918() {\n        method917();\n    }\n\n    public void method919() {\n        method918();\n    }\n\n    public void method92() {\n        method91();\n    }\n\n    public void method920() {\n        method919();\n    }\n\n    public void method921() {\n        method920();\n    }\n\n    public void method922() {\n        method921();\n    }\n\n    public void method923() {\n        method922();\n    }\n\n    public void method924() {\n        method923();\n    }\n\n    public void method925() {\n        method924();\n    }\n\n    public void method926() {\n        method925();\n    }\n\n    public void method927() {\n        method926();\n    }\n\n    public void method928() {\n        method927();\n    }\n\n    public void method929() {\n        method928();\n    }\n\n    public void method93() {\n        method92();\n    }\n\n    public void method930() {\n        method929();\n    }\n\n    public void method931() {\n        method930();\n    }\n\n    public void method932() {\n        method931();\n    }\n\n    public void method933() {\n        method932();\n    }\n\n    public void method934() {\n        method933();\n    }\n\n    public void method935() {\n        method934();\n    }\n\n    public void method936() {\n        method935();\n    }\n\n    public void method937() {\n        method936();\n    }\n\n    public void method938() {\n        method937();\n    }\n\n    public void method939() {\n        method938();\n    }\n\n    public void method94() {\n        method93();\n    }\n\n    public void method940() {\n        method939();\n    }\n\n    public void method941() {\n        method940();\n    }\n\n    public void method942() {\n        method941();\n    }\n\n    public void method943() {\n        method942();\n    }\n\n    public void method944() {\n        method943();\n    }\n\n    public void method945() {\n        method944();\n    }\n\n    public void method946() {\n        method945();\n    }\n\n    public void method947() {\n        method946();\n    }\n\n    public void method948() {\n        method947();\n    }\n\n    public void method949() {\n        method948();\n    }\n\n    public void method95() {\n        method94();\n    }\n\n    public void method950() {\n        method949();\n    }\n\n    public void method951() {\n        method950();\n    }\n\n    public void method952() {\n        method951();\n    }\n\n    public void method953() {\n        method952();\n    }\n\n    public void method954() {\n        method953();\n    }\n\n    public void method955() {\n        method954();\n    }\n\n    public void method956() {\n        method955();\n    }\n\n    public void method957() {\n        method956();\n    }\n\n    public void method958() {\n        method957();\n    }\n\n    public void method959() {\n        method958();\n    }\n\n    public void method96() {\n        method95();\n    }\n\n    public void method960() {\n        method959();\n    }\n\n    public void method961() {\n        method960();\n    }\n\n    public void method962() {\n        method961();\n    }\n\n    public void method963() {\n        method962();\n    }\n\n    public void method964() {\n        method963();\n    }\n\n    public void method965() {\n        method964();\n    }\n\n    public void method966() {\n        method965();\n    }\n\n    public void method967() {\n        method966();\n    }\n\n    public void method968() {\n        method967();\n    }\n\n    public void method969() {\n        method968();\n    }\n\n    public void method97() {\n        method96();\n    }\n\n    public void method970() {\n        method969();\n    }\n\n    public void method971() {\n        method970();\n    }\n\n    public void method972() {\n        method971();\n    }\n\n    public void method973() {\n        method972();\n    }\n\n    public void method974() {\n        method973();\n    }\n\n    public void method975() {\n        method974();\n    }\n\n    public void method976() {\n        method975();\n    }\n\n    public void method977() {\n        method976();\n    }\n\n    public void method978() {\n        method977();\n    }\n\n    public void method979() {\n        method978();\n    }\n\n    public void method98() {\n        method97();\n    }\n\n    public void method980() {\n        method979();\n    }\n\n    public void method981() {\n        method980();\n    }\n\n    public void method982() {\n        method981();\n    }\n\n    public void method983() {\n        method982();\n    }\n\n    public void method984() {\n        method983();\n    }\n\n    public void method985() {\n        method984();\n    }\n\n    public void method986() {\n        method985();\n    }\n\n    public void method987() {\n        method986();\n    }\n\n    public void method988() {\n        method987();\n    }\n\n    public void method989() {\n        method988();\n    }\n\n    public void method99() {\n        method98();\n    }\n\n    public void method990() {\n        method989();\n    }\n\n    public void method991() {\n        method990();\n    }\n\n    public void method992() {\n        method991();\n    }\n\n    public void method993() {\n        method992();\n    }\n\n    public void method994() {\n        method993();\n    }\n\n    public void method995() {\n        method994();\n    }\n\n    public void method996() {\n        method995();\n    }\n\n    public void method997() {\n        method996();\n    }\n\n    public void method998() {\n        method997();\n    }\n\n    public void method999() {\n        method998();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/cpu/Region.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * Region.java\n *\n * Created on November 1, 2005, 4:02 PM\n *\n * To change this template, choose Tools | Template Manager\n * and open the template in the editor.\n */\npackage simple.cpu;\n\n\n/**\n *\n * @author ehucka\n */\npublic class Region {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of Region */\n    public Region() {\n        run100();\n        run100();\n        run100();\n        run1000();\n        run2000();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        System.out.println(\"Start application: \" + System.currentTimeMillis());\n\n        AnotherThread tt = new AnotherThread();\n        tt.start();\n\n        Region r = new Region();\n\n        try {\n            tt.join();\n        } catch (InterruptedException ex) {\n            ex.printStackTrace();\n        }\n\n        System.out.println(\"Finish application: \" + System.currentTimeMillis());\n    }\n\n    public void run100() {\n        long startTime = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - startTime) < 100) {\n            ;\n        }\n    }\n\n    public void run1000() {\n        long startTime = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - startTime) < 1000) {\n            ;\n        }\n    }\n\n    public void run2000() {\n        for (int i = 0; i < 20; i++) {\n            run100();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/cpu/WaitingTest.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage simple.cpu;\n\npublic class WaitingTest {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final Object mutex = new Object();\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    long run = 0;\n    long sleep = 0;\n    long wait = 0;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public WaitingTest() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void main(String[] args) {\n        System.out.println(\"Start app: \" + System.currentTimeMillis());\n\n        WaitingTest test = new WaitingTest();\n\n        for (int i = 0; i < 2; i++) {\n            test.method1000();\n            System.out.println(\"sleep: \" + test.sleep);\n            System.out.println(\"wait: \" + test.wait);\n            System.out.println(\"run: \" + test.run);\n        }\n\n        System.out.println(\"Finish app: \" + System.currentTimeMillis());\n    }\n\n    public void method1000() {\n        sleep = 0;\n        run = 0;\n        wait = 0;\n\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 1000) {\n            ;\n        }\n\n        run += (System.currentTimeMillis() - time);\n        time = System.currentTimeMillis();\n\n        synchronized (mutex) {\n            try {\n                mutex.wait(1000);\n            } catch (InterruptedException ex) {\n                ex.printStackTrace();\n            }\n        }\n\n        wait += (System.currentTimeMillis() - time);\n        time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 1000) {\n            ;\n        }\n\n        run += (System.currentTimeMillis() - time);\n        time = System.currentTimeMillis();\n\n        try {\n            Thread.sleep(1000);\n        } catch (InterruptedException ex) {\n        }\n\n        sleep += (System.currentTimeMillis() - time);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/memory/Bean.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * Bean.java\n *\n * Created on July 25, 2005, 4:15 PM\n *\n * To change this template, choose Tools | Options and locate the template under\n * the Source Creation and Management node. Right-click the template and choose\n * Open. You can then make changes to the template in the Source Editor.\n */\npackage simple.memory;\n\n\n/**\n *\n * @author ehucka\n */\npublic class Bean {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    String data1;\n    String data2;\n    String data3;\n    String data4;\n    byte value4;\n    double value1;\n    int value2;\n    long value3;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of Bean */\n    public Bean() {\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/memory/Memory1.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * Memory1.java\n *\n * Created on July 25, 2005, 4:16 PM\n *\n * To change this template, choose Tools | Options and locate the template under\n * the Source Creation and Management node. Right-click the template and choose\n * Open. You can then make changes to the template in the Source Editor.\n */\npackage simple.memory;\n\nimport java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.util.ArrayList;\n\n\n/**\n *\n * @author ehucka\n */\npublic class Memory1 {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static ArrayList storage2 = new ArrayList();\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    ArrayList storage;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of Memory1 */\n    public Memory1() {\n        storage = new ArrayList();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void add() {\n        storage.add(new Bean());\n        storage2.add(new Bean());\n    }\n\n    public void clear() {\n        storage.clear();\n    }\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        System.out.println(\">>app: start: \" + System.currentTimeMillis());\n\n        //wait for profiler\n        /*try {\n           BufferedReader br=new BufferedReader(new InputStreamReader(System.in));\n           br.readLine();\n           } catch (Exception ex) {}\n           //wait for the first measuring\n           try {\n               Thread.sleep(4000);\n           } catch (Exception e) {}*/\n        int[] cnts = new int[] { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1 };\n        Memory1 memory = new Memory1();\n\n        for (int i = 0; i < cnts.length; i++) {\n            /*try {\n               Thread.sleep(200);\n               } catch (Exception e) {}*/\n            for (int b = 0; b < cnts[i]; b++) {\n                memory.add();\n            }\n\n            try {\n                Thread.sleep(200);\n            } catch (Exception e) {\n            }\n\n            //memory.clear();\n            System.gc();\n        }\n\n        System.out.println(\">>app: end: \" + System.currentTimeMillis());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/monitor/CascadeThread.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage simple.monitor;\n\n\n/**\n *\n * @author ehucka\n */\npublic class CascadeThread extends Thread {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static int MAX_THREADS = 5;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of CascadeThread */\n    public CascadeThread() {\n        super(\"Cascade \" + MAX_THREADS);\n        MAX_THREADS--;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void run() {\n        long time = System.currentTimeMillis();\n\n        while ((System.currentTimeMillis() - time) < 2000) {\n            ;\n        }\n\n        System.out.println(getName() + \" die\");\n\n        if (MAX_THREADS > 0) {\n            new CascadeThread().start();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/j2se-simple/src/simple/monitor/Monitor1.java",
    "content": "/*\n * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage simple.monitor;\n\n\n/**\n *\n * @author ehucka\n */\npublic class Monitor1 {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of Monitor1 */\n    public Monitor1() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        // TODO code application logic here\n        CascadeThread t = new CascadeThread();\n        t.start();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/jbb/config.properties",
    "content": "#########################################################################\n#                                                                       #\n#     Control parameters for SPECjbb benchmark                          #\n#                                                                       #\n#########################################################################\n#\n#  This file has 2 sections; changable parameters and fixed parameters.\n#  The fixed parameters exist so that you may run tests any way you want,\n#  however in order to have a valid, reportable run of SPECjbb, you must\n#  reset them to their original values.\n#\n#########################################################################\n#                                                                       #\n#     Changable input parameters                                        #\n#                                                                       #\n#########################################################################\n# Warehouse sequence may be controlled in either of two ways.  The more\n# usual method for specifying warehouse sequence is the triple\n# input.starting_number_warehouses, input.increment_number_warehouses,\n# and input.ending_number_warehouses, which causes the sequence of\n# warehouses to progress from input.starting_number_warehouses to\n# input.ending_number_warehouses, incrementing by\n# input.increment_number_warehouses.\n# The alternative method of specifying warehouse sequence is\n# input.sequence_of_number_of_warehouses, which allows specification of\n# an arbitrary list of positive integers in increasing order.\n# For a publishable result the warehouse sequence must begin at 1, \n# increment by 1 and go to at least 8 warehouses\n# The expected_peak_warehouses defaults to the result of the runtime call\n# Runtime.getRuntime.availableProcessors()\n# It can be overeridden here but then a submission should include an explanation\n# in the Notes field\ninput.jvm_instances=1\ninput.starting_number_warehouses=1\ninput.increment_number_warehouses=1\ninput.ending_number_warehouses=3\n#The default value for input.expected_peak_warehouse\n#is Runtime.getRuntime.availableProcessors\n#If you modify this property, the result must be submitted for review before publication\n#and an explanation should be included in the Notes section.  See the run rules for details.\n#input.expected_peak_warehouse =0\n#input.sequence_of_number_of_warehouses=1 2 3 4 5 6 7 8\n#\n# 'show_warehouse_detail' controls whether to print per-warehouse\n# statistics in the raw results file. These statistics are not used\n# in the final report but may be useful when analyzing a JVMs behavior.\n# When running a large number of warehouses (i.e. on a system with a\n# lot of CPUs), changing this to true will results in very large\n# raw files. For submissions to SPEC, it is recommended that this \n# attribute be set to false.\n#\ninput.show_warehouse_detail=false\n#\n# 'include_file' is the name for the descriptive properties file. On\n# systems where the file separator is \\, use \\\\ as the file separator\n# here.\n# \n# Examples:\n#        input.include_file=SPECjbb_config.props\n#        input.include_file=/path/to/SPECjbb_config.props\n#        input.include_file=c:\\\\path\\\\to\\\\SPECjbb_config.props\n\n\n#input.include_file=SPECjbb_config.props\n#\n# directory to store output files. On systems where the file separator \n# is \\, use \\\\ as the file separator here.\n# \n# Examples:\n#        input.include_file=results\n#        input.include_file=/path/to/results\n#        input.include_file=c:\\\\path\\\\to\\\\results\n#\ninput.output_directory=results\n#########################################################################\n#                                                                       #\n#     Fixed input parameters                                            #\n#                                                                       #\n#     YOUR RESULTS WILL BE INVALID IF YOU CHANGE THESE PARAMETERS       #\n#                                                                       #\n#########################################################################\n# DON'T CHANGE THIS PARAMETER, OR ELSE !!!!\ninput.suite=SPECjbb\n# Benchmark logging level\ninput.log_level=INFO\n# Deterministic Random Seed (required value is false)\ninput.deterministic_random_seed=false\n# rampup and rampdown specify rampup and rampdown for multi-jvm mode\n# only. (seconds)\ninput.per_jvm_warehouse_rampup=3\ninput.per_jvm_warehouse_rampdown=20\n#\n# If you need to collect stats or profiles, it may be useful to increase\n# the 'measurement_seconds'.  This will, however, invalidate your results\n#\n# Amount of time to run each point prior to the measurement window\n#input.ramp_up_seconds=30\ninput.ramp_up_seconds=30\n# Time of measurement window\n#input.measurement_seconds=240\ninput.measurement_seconds=60\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/jbb/xml/jbb-document.dtd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--\n    Document   : jbb-document.dtd\n    Created on : September 24, 2004, 10:52 AM\n    Author     : dagastin\n    Description: SPECjbb2005 DisplayScreen DTD\n        Purpose of the document follows.\n        \n    SPECjbb2005 JBB-Document DTD\n-->\n<!ELEMENT   JBB-Document    (DisplayName,Line*)>\n\n<!ELEMENT   DisplayName      (#PCDATA)>\n\n<!ELEMENT   Line  (LineData*)>\n<!ATTLIST Line row  CDATA #REQUIRED>\n<!ELEMENT   LineData    (#PCDATA)>\n\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/data/projects/jbb/xml/template-document.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--\n    Document   : display.xml\n    Created on : September 24, 2004, 10:54 AM\n    Author     : dagastin\n    Description:\n        Purpose of the document follows.\n-->\n\n<!DOCTYPE JBB-Document SYSTEM \"jbb-document.dtd\">\n<JBB-Document>\n<DisplayName>JBB-Document-Template</DisplayName>\n</JBB-Document>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/BasicTest.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid;\n\nimport junit.framework.Test;\nimport junit.textui.TestRunner;\nimport org.netbeans.junit.NbModuleSuite;\nimport org.graalvm.visualvm.lib.jfluid.*;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.*;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.TestProfilerAppHandler;\n\n\npublic class BasicTest extends CommonProfilerTestCase {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public BasicTest(String testName) {\n        super(testName);\n    }\n\n    public static void main(String[] args) {\n        TestRunner.run(suite());\n    }\n\n    public static Test suite() {\n        return NbModuleSuite.create(\n            NbModuleSuite.createConfiguration(BasicTest.class).addTest(\n            \"testCalibrate\").enableModules(\".*\").clusters(\".*\").honorAutoloadEager(true).gui(false));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void testCalibrate() {\n        ProfilerEngineSettings settings;\n        settings = new ProfilerEngineSettings();\n        setTargetVM(settings);\n        settings.setPortNo(5140);\n        settings.setSeparateConsole(false);\n        setStatus(STATUS_NONE);\n\n        setProfilerHome(settings);\n\n        TargetAppRunner runner = new TargetAppRunner(settings, new TestProfilerAppHandler(this),\n                                                     new TestProfilingPointsProcessor());\n        runner.addProfilingEventListener(Utils.createProfilingListener(this));\n\n        try {\n            assertTrue(\"Error in calibration\", runner.calibrateInstrumentationCode());\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            assertFalse(\"Error in calibration\", true);\n        } finally {\n            runner.terminateTargetJVM();\n\n            //            waitForStatus(STATUS_FINISHED, 60 * 1000);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/CommonProfilerTestCase.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.PrintStream;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.client.AppStatusHandler;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils.SourceCodeSelection;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.DumpStream;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport org.netbeans.junit.NbTestCase;\nimport org.netbeans.junit.diff.LineDiff;\nimport org.openide.modules.InstalledFileLocator;\n\n\npublic abstract class CommonProfilerTestCase extends NbTestCase {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int STATUS_ERROR = 255;\n    public static final int STATUS_NONE = 0;\n    public static final int STATUS_RUNNING = 1;\n    public static final int STATUS_RESULTS_AVAILABLE = 2;\n    public static final int STATUS_APP_FINISHED = 4;\n    public static final int STATUS_MEASURED = 8;\n    public static final int STATUS_FINISHED = 16;\n    public static final int STATUS_LIVERESULTS_AVAILABLE = 32;\n    private static final boolean CREATE_GOLDENS = false;\n    private static final String GOLDENS_CVS_PATH = CommonProfilerTestCase.class.getResource(\"CommonProfilerTestCase.class\").toString().replace(\"classes/org/graalvm/visualvm/lib/jfluid/tests/jfluid/CommonProfilerTestCase.class\", \"data/goldenfiles\").replace(\"file:/\", \"\");    \n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected DumpStream err;\n    protected DumpStream out;\n    protected File diff;\n    protected File ref;\n    protected Process profilingProcess = null;\n    PrintStream goldenStream;\n    PrintStream logStream;\n    PrintStream refStream;\n    private String mainClass;\n    private String projectName;\n    private String[][] rootMethods;\n    private volatile int status = 0;\n    private File workdir;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CommonProfilerTestCase(String name) {\n        super(name);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setMainClass(String mainClass) {\n        this.mainClass = mainClass;\n    }\n\n    public String getMainClass() {\n        return mainClass;\n    }\n\n    public void setProjectName(String projectName) {\n        this.projectName = projectName;\n    }\n\n    public String getProjectName() {\n        return projectName;\n    }\n\n    public void setRootMethods(String[][] rootMethods) {\n        this.rootMethods = rootMethods;\n    }\n\n    public String[][] getRootMethods() {\n        return rootMethods;\n    }\n\n    public synchronized void setStatus(int status) {\n        log(\"STATUS: set status \" + getStatus(status));\n        System.err.println(\"STATUS: set status \" + getStatus(status));\n\n        if (STATUS_ERROR == status) {\n            new Exception(\"STATUS_ERROR set\").printStackTrace();\n        }\n\n        this.status |= status;\n        notifyAll();\n    }\n\n    public synchronized int getStatus() {\n        return status;\n    }\n\n    public synchronized String getStatus(int status) {\n        StringBuilder sb = new StringBuilder();\n\n        if (status == STATUS_ERROR) {\n            sb.append(\"ERROR\");\n        } else {\n            if ((status & STATUS_APP_FINISHED) > 0) {\n                sb.append(\"APP_FINISHED \");\n            }\n\n            if ((status & STATUS_FINISHED) > 0) {\n                sb.append(\"FINISHED \");\n            }\n\n            if ((status & STATUS_MEASURED) > 0) {\n                sb.append(\"MEASURED \");\n            }\n\n            if (status == 0) {\n                sb.append(\"NONE \");\n            }\n\n            if ((status & STATUS_RESULTS_AVAILABLE) > 0) {\n                sb.append(\"RESULTS_AVAILABLE \");\n            }\n\n            if ((status & STATUS_RUNNING) > 0) {\n                sb.append(\"RUNNING \");\n            }\n\n            if ((status & STATUS_LIVERESULTS_AVAILABLE) > 0) {\n                sb.append(\"LIVERESULTS_AVAILABLE \");\n            }\n        }\n\n        return sb.toString();\n    }\n\n    public synchronized boolean isStatus(int status) {\n        if (status == STATUS_ERROR) {\n            return (getStatus() == status);\n        }\n\n        return ((getStatus() & status) > 0);\n    }\n\n    public void log(Throwable t) {\n        t.printStackTrace(getLogStream());\n    }\n\n    public void log(String s) {\n        getLogStream().println(s);\n    }\n\n    public void log(Object o) {\n        log(o.toString());\n    }\n\n    public void log(double[] ar) {\n        StringBuilder sb = new StringBuilder(ar.length * 10);\n        sb.append(\"[\");\n\n        for (int i = 0; i < ar.length; i++) {\n            sb.append(String.valueOf(ar[i]));\n\n            if (i < (ar.length - 1)) {\n                sb.append(\", \");\n            }\n        }\n\n        sb.append(\"]\");\n        log(sb.toString());\n    }\n\n    public void log(int[] ar) {\n        StringBuilder sb = new StringBuilder(ar.length * 10);\n        sb.append(\"[\");\n\n        for (int i = 0; i < ar.length; i++) {\n            sb.append(String.valueOf(ar[i]));\n\n            if (i < (ar.length - 1)) {\n                sb.append(\", \");\n            }\n        }\n\n        sb.append(\"]\");\n        log(sb.toString());\n    }\n\n    public void log(HashMap map) {\n        Object[] keys = map.keySet().toArray();\n        Arrays.sort(keys);\n\n        for (int i = 0; i < keys.length; i++) {\n            log((String) keys[i] + \" = \" + (String) (map.get(keys[i])));\n        }\n    }\n\n    public void log(ProfilerEngineSettings settings) {\n        HashMap map = new HashMap(32);\n        storeSettings(settings, map);\n        log(map);\n    }\n\n    public void ref(String s) {\n        //System.out.println(s);\n        getRefStream().println(s);\n\n        if (CREATE_GOLDENS) {\n            goldenStream.println(s);\n        }\n    }\n\n    public void ref(String[] s) {\n        StringBuffer sb = new StringBuffer();\n\n        for (int i = 0; i < s.length; i++) {\n            sb.append(s[i]);\n\n            if (i < (s.length - 1)) {\n                sb.append(\", \");\n            }\n        }\n\n        ref(sb);\n    }\n\n    public void ref(Object o) {\n        ref(o.toString());\n    }\n\n    public void runTest() throws Throwable {\n        try {\n            super.runTest();\n        } catch (Throwable td) {\n            td.printStackTrace();\n\n            if (!isStatus(STATUS_ERROR)) {\n                setStatus(STATUS_ERROR);\n            }\n\n            throw td;\n        }\n    }\n\n    public synchronized void unsetStatus(int status) {\n        if (status != STATUS_ERROR) {\n            log(\"STATUS: unset status \" + getStatus(status));\n            System.err.println(\"STATUS: unset status \" + getStatus(status));\n            this.status &= ~status;\n            notifyAll();\n        }\n    }\n\n    public void waitForStatus(int status) {\n        waitForStatus(status, 0L);\n    }\n\n    public synchronized void waitForStatus(int status, long timeout) {\n        log(\"STATUS: wait for status \" + getStatus(status));\n        System.err.println(\"STATUS: wait for status \" + getStatus(status));\n\n        while (!isStatus(status) && !isStatus(STATUS_ERROR)) {\n            try {\n                wait(timeout);\n            } catch (InterruptedException e) {\n            }\n        }\n\n        log(\"STATUS: reached status \" + getStatus(getStatus()));\n        System.err.println(\"STATUS: reached status \" + getStatus(getStatus()));\n\n        if (isStatus(STATUS_ERROR)) {\n            assertTrue(\"Error state of test\", false);\n        }\n    }\n\n    protected void setClassPath(ProfilerEngineSettings settings) {\n        String projPath = getProjectPath(getProjectName());\n        settings.setMainClassPath(projPath);\n        //coverage\n        //settings.setMainClassPath(\"/space/tmp/testrun/emma/lib/emma.jar:\" + xData + jarPath);\n        settings.setMainClass(getMainClass());\n        settings.setVMClassPaths(projPath, \"\", \"\");\n    }\n\n    protected PrintStream getLogStream() {\n        if (logStream == null) {\n            logStream = getLog();\n        }\n\n        return logStream;\n    }\n\n    protected void setProfilerHome(ProfilerEngineSettings settings) {\n        try {\n            String profilerHome = System.getProperty(\"profiler.home\");\n            String libsDir;\n            if ((profilerHome == null) || !new File(profilerHome).exists()) {\n                libsDir = getLibsDir();\n            } else {\n                libsDir = profilerHome + \"/lib\";\n            }\n\n            settings.initialize(libsDir);\n        } catch (IOException ex) {\n            ex.printStackTrace();\n            assertFalse(\"Error in initialization\", true);\n        }\n    }\n\n    private String getLibsDir() {\n        final File dir = InstalledFileLocator.getDefault().locate(\"lib/jfluid-server.jar\", //NOI18N\n                                                     \"org.graalvm.visualvm.lib.jfluid\", false); //NOI18N\n        if (dir == null) {\n            return null;\n        }\n        return dir.getParentFile().getPath();\n    }\n\n    protected String getProjectPath(String projectName) {\n        String jarPath = \"/projects/\" + projectName + \"/distrib/\" + projectName + \".jar\";\n\n        if (!new File(getDataDir(), jarPath).exists()) {\n            jarPath = \"/projects/\" + projectName + \"/dist/\" + projectName + \".jar\";\n        }\n\n        if (!new File(getDataDir(), jarPath).exists()) {\n            assertTrue(\"There is not profiled application\", false);\n\n            return \"\";\n        }\n\n        String xData = getDataDir().getAbsolutePath();\n\n        return xData + jarPath;\n    }\n\n    protected PrintStream getRefStream() {\n        if (refStream == null) {\n            refStream = getRef();\n\n            if (CREATE_GOLDENS) {\n                File file = new File(GOLDENS_CVS_PATH);\n                file = new File(file, getClass().getName().replace('.', '/') + \"/\" + getName() + \".pass\");\n\n                if (!file.getParentFile().exists()) {\n                    file.getParentFile().mkdirs();\n                }\n\n                try {\n                    goldenStream = new PrintStream(new FileOutputStream(file));\n                } catch (Exception ex) {\n                    ex.printStackTrace();\n                }\n            }\n        }\n\n        return refStream;\n    }\n\n    protected void setRootMethods(ProfilerEngineSettings settings, String[][] rootMethods) {\n        this.rootMethods = rootMethods;\n\n        if (rootMethods == null) {\n            this.rootMethods = new String[][] {\n                                   { mainClass, \"main\", \"([Ljava/lang/String;)V\" }\n                               };\n        }\n\n        ArrayList al = new ArrayList();\n\n        for (int i = 0; i < this.rootMethods.length; i++) {\n            al.add(new ClientUtils.SourceCodeSelection(this.rootMethods[i][0], this.rootMethods[i][1], this.rootMethods[i][2]));\n        }\n\n        settings.setInstrumentationRootMethods((ClientUtils.SourceCodeSelection[]) al.toArray(new ClientUtils.SourceCodeSelection[al\n                                                                                                                                  .size()]));\n    }\n\n    protected void setTargetVM(ProfilerEngineSettings settings) {\n        String vers = System.getProperty(\"java.version\");\n\n        if (vers.startsWith(\"1.5\")) {\n            if (vers.startsWith(\"1.5.0\")\n                    && ((vers.charAt(\"1.5.0\".length()) != '_')\n                           || (Integer.parseInt(vers.substring(\"1.5.0\".length() + 1, \"1.5.0\".length() + 3)) < 4))) {\n                System.err.println(\"Illegal version of JVM: \" + vers);\n\n                return;\n            }\n\n            settings.setTargetJDKVersionString(CommonConstants.JDK_15_STRING);\n        } else {\n            settings.setTargetJDKVersionString(Platform.getJDKVersionString(vers));\n        }\n\n        String home = System.getProperty(\"java.home\");\n\n        if (File.separatorChar == '/') {\n            settings.setTargetJVMExeFile(home + \"/bin/java\");\n        } else {\n            settings.setTargetJVMExeFile(home + \"\\\\bin\\\\java.exe\");\n        }\n\n        settings.setSystemArchitecture(Platform.getSystemArchitecture());\n    }\n\n    protected void setUp() throws Exception {\n        System.err.println(\"START TEST \" + getClass().getName() + \".\" + getName());\n\n        //System.setProperty(\"org.graalvm.visualvm.lib.jfluid.TargetAppRunner\", \"true\");\n        workdir = getWorkDir();\n        diff = new File(workdir, getName() + \".diff\");\n        ref = new File(workdir, getName() + \".ref\");\n        log(\"Test Source: http://hg.netbeans.org/main-golden/file/tip/lib.profiler/test/qa-functional/src/\"\n            + getClass().getName().replace('.', '/') + \".java\");\n\n        //check for running server\n        try {\n            java.net.Socket sock = new java.net.Socket(\"localhost\", 5140);\n            sock.getOutputStream().write(1);\n            sock.close();\n            assertTrue(\"Another server is running on port 5140\", false);\n        } catch (Exception ex) {\n        }\n    }\n\n    protected void addJVMArgs(ProfilerEngineSettings settings, String arg) {\n        String old = settings.getJVMArgsAsSingleString();\n\n        if ((old == null) || (old.length() == 0)) {\n            settings.setJVMArgs(arg);\n        } else {\n            settings.setJVMArgs(old + \" \" + arg);\n        }\n    }\n\n    protected void bindStreams(Process p) {\n        err = new DumpStream(p, p.getErrorStream(), getLogStream(), \"[App error] \");\n        err.start();\n        out = new DumpStream(p, p.getInputStream(), getLogStream(), \"[App output] \");\n        out.start();\n    }\n\n    protected String complete(String s, int chars) {\n        StringBuilder sb = new StringBuilder(chars);\n        int tot = chars - s.length();\n        sb.append(s);\n\n        for (int i = 0; i < tot; i++) {\n            sb.append(\" \");\n        }\n\n        return sb.substring(0, chars);\n    }\n\n    protected void finalizeTest(TargetAppRunner runner) {\n        //finish client\n        if (!isStatus(STATUS_MEASURED)) { // to release handleShutdown call\n            System.err.println(\"must be set measured\");\n            setStatus(STATUS_MEASURED);\n        }\n\n        if (!isStatus(STATUS_APP_FINISHED)) { //not handled shutdown\n            System.err.println(\"target vm must be terminated\");\n            runner.terminateTargetJVM();\n        }\n\n        //wait for agent death\n        int cycles = 50;\n\n        while ((cycles > 0) && runner.targetJVMIsAlive()) {\n            try {\n                Thread.sleep(500);\n                cycles--;\n            } catch (InterruptedException ex) {\n            }\n        }\n\n        assertFalse(\"Target JVM is running after finish\", runner.targetJVMIsAlive());\n\n        //test the profiled proces is finished\n        if (profilingProcess != null) {\n            try {\n                profilingProcess.waitFor();\n\n                if (out != null) {\n                    out.join();\n                    err.join();\n                }\n\n                profilingProcess.destroy();\n            } catch (InterruptedException ex) {\n                ex.printStackTrace();\n            }\n\n            profilingProcess = null;\n        }\n\n        //log settings\n        log(\"\\nProfiler settings\\n\");\n        log(runner.getProfilerEngineSettings());\n        log(\"\");\n        System.err.println(\"Test \" + getName() + \" finalized.\");\n        \n        try {\n            Thread.sleep(3000);\n        } catch (InterruptedException ex) {\n            ex.printStackTrace(System.err);\n        }\n    }\n\n    protected void initAppByStream(TargetAppRunner runner) {\n        Process p = runner.getRunningAppProcess();\n        assert p != null;\n\n        try {\n            PrintStream ps = new PrintStream(p.getOutputStream());\n            ps.print(\"start\");\n            ps.close();\n        } catch (Exception ex) {\n        }\n    }\n\n    protected ProfilerEngineSettings initTest(String projectName, String mainClass, String[][] rootMethods) {\n        ProfilerEngineSettings settings = new ProfilerEngineSettings();\n        settings.setPortNo(5140);\n        settings.setSeparateConsole(true);\n        settings.setInstrScheme(ProfilerEngineSettings.INSTRSCHEME_TOTAL);\n        settings.setJVMArgs(\"\");\n        settings.setWorkingDir(workdir.getAbsolutePath());\n        //coverage\n        //addJVMArgs(settings, \"-Demma.coverage.out.file=/space/tmp/testrun/coverage.emma\");\n        setProjectName(projectName);\n        setMainClass(mainClass);\n        setRootMethods(settings, rootMethods);\n\n        setTargetVM(settings);\n        setClassPath(settings);\n        setProfilerHome(settings);\n\n        setStatus(STATUS_NONE);\n\n        return settings;\n    }\n\n    protected Process startTargetVM(TargetAppRunner runner) {\n        ProfilerEngineSettings settings = runner.getProfilerEngineSettings();\n        AppStatusHandler handler = runner.getAppStatusHandler();\n        ArrayList commands = new ArrayList(10);\n\n        commands.add(settings.getTargetJVMExeFile());\n\n        //agentpath with options\n        String jfNativeLibFullName = Platform.getAgentNativeLibFullName(settings.getJFluidRootDirName(), false,\n                                                                        settings.getTargetJDKVersionString(), -1);\n        String libpath = jfNativeLibFullName.substring(0, jfNativeLibFullName.indexOf(\"deployed\") - 1);\n        String timeOut = System.getProperty(\"profiler.agent.connect.timeout\", \"10\");\n        commands.add(\"-agentpath:\" + jfNativeLibFullName + \"=\" + libpath + \",\" + Integer.toString(settings.getPortNo()) + \",\"\n                     + timeOut);\n\n        if (!Platform.isWindows() && settings.getTargetWindowRemains()) {\n            commands.add(\"-XX:+ShowMessageBoxOnError\"); // NOI18N\n        }\n\n        //classptah\n        commands.add(\"-classpath\");\n        commands.add(settings.getMainClassPath());\n\n        //jvm arguments\n        for (int i = 0; i < settings.getJVMArgs().length; i++) {\n            commands.add(settings.getJVMArgs()[i]);\n        }\n\n        // debugging property for agent side - wire I/O\n        if (System.getProperty(\"org.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO.agent\") != null) { // NOI18N\n            commands.add(\"-Dorg.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO=true\"); // NOI18N\n        }\n\n        // debugging property for agent side - Class loader hook\n        if (System.getProperty(\"org.graalvm.visualvm.lib.jfluid.server.ProfilerInterface.classLoadHook\") != null) { // NOI18N\n            commands.add(\"-Dorg.graalvm.visualvm.lib.jfluid.server.ProfilerInterface.classLoadHook=true\"); // NOI18N\n        }\n\n        //main class of application\n        commands.add(settings.getMainClassName());\n\n        //arguments of application\n        for (int i = 0; i < settings.getMainArgs().length; i++) {\n            commands.add(settings.getMainArgs()[i]);\n        }\n\n        String[] cmdArray = new String[commands.size()];\n        commands.toArray(cmdArray);\n\n        MiscUtils.printInfoMessage(\"Starting target application...\"); // NOI18N\n        MiscUtils.printVerboseInfoMessage(cmdArray);\n\n        System.err.println(\"Starting VM with \" + cmdArray.length + \" commands.\"); // NOI18N\n\n        StringBuilder sb = new StringBuilder();\n\n        for (int i = 0; i < cmdArray.length; i++) {\n            sb.append(cmdArray[i]);\n            sb.append(' ');\n        }\n\n        System.err.println(sb.toString());\n\n        try {\n            profilingProcess = Runtime.getRuntime().exec(cmdArray, null, new File(settings.getWorkingDir()));\n\n            if (profilingProcess != null) {\n                runner.initiateSession(1, false);\n            } else {\n                throw new NullPointerException();\n            }\n\n            return profilingProcess;\n        } catch (IOException ex) {\n            String s = \"\"; // NOI18N\n\n            for (int i = 0; i < cmdArray.length; i++) {\n                s = s + cmdArray[i] + \"\\n\"; // NOI18N\n            }\n\n            handler.displayError(\"When starting target JVM, with command: \" + s + \", caught an exception: \" + ex.getMessage());\n            ex.printStackTrace();\n        }\n\n        return null;\n    }\n\n    protected void storeSettings(ProfilerEngineSettings settings, HashMap map) {\n        map.put(\"profiler.settings.cpu.profiling.type\",\n                ((settings.getCPUProfilingType() == CommonConstants.CPU_INSTR_FULL) ? \"CPU_INSTR_FULL\" : \"CPU_INSTR_SAMPLED\"));\n\n        if (settings.getInstrScheme() == CommonConstants.INSTRSCHEME_LAZY) {\n            map.put(\"profiler.settings.instr.scheme\", \"INSTRSCHEME_LAZY\");\n        } else if (settings.getInstrScheme() == CommonConstants.INSTRSCHEME_EAGER) {\n            map.put(\"profiler.settings.instr.scheme\", \"INSTRSCHEME_EAGER\");\n        } else {\n            map.put(\"profiler.settings.instr.scheme\", \"INSTRSCHEME_TOTAL\");\n        }\n\n        map.put(\"profiler.settings.override.working.dir\", settings.getWorkingDir());\n        map.put(\"profiler.settings.override.jvm.args\", toString(settings.getJVMArgs()));\n        map.put(\"profiler.settings.override.port.no\", Integer.toString(settings.getPortNo()));\n        map.put(\"profiler.settings.thread.cpu.timer.on\", Boolean.toString(settings.getThreadCPUTimerOn()));\n        map.put(\"profiler.settings.istrument.getter.setter.methods\", Boolean.toString(settings.getInstrumentGetterSetterMethods()));\n        map.put(\"profiler.settings.instrument.empty.methods\", Boolean.toString(settings.getInstrumentEmptyMethods()));\n        map.put(\"profiler.settings.instrument.method.invoke\", Boolean.toString(settings.getInstrumentMethodInvoke()));\n        map.put(\"profiler.settings.instrument.spawned.threads\", Boolean.toString(settings.getInstrumentSpawnedThreads()));\n        map.put(\"profiler.settings.n.profiled.threads.limit\", Integer.toString(settings.getNProfiledThreadsLimit()));\n        map.put(\"profiler.settings.stack.depth.limit\", Integer.toString(settings.getStackDepthLimit())); \n        map.put(\"profiler.settings.sort.results.by.thread.cpu.time\", Boolean.toString(settings.getSortResultsByThreadCPUTime()));\n        map.put(\"profiler.settings.sampling.interval\", Integer.toString(settings.getSamplingInterval()));\n        map.put(\"profiler.settings.code.region.cpu.res.buf.size\", Integer.toString(settings.getCodeRegionCPUResBufSize()));\n        map.put(\"profiler.settings.run.gc.on.get.results.in.memory.profiling\",\n                Boolean.toString(settings.getRunGCOnGetResultsInMemoryProfiling()));\n        map.put(\"profiler.settings.obj.alloc.stack.sampling.interval\", Integer.toString(settings.getAllocTrackEvery()));\n        map.put(\"profiler.settings.obj.alloc.stack.sampling.depth\", Integer.toString(settings.getAllocStackTraceLimit()));\n        map.put(\"profiler.settings.exclude.wait.time\", Boolean.toString(settings.getExcludeWaitTime()));\n\n        InstrumentationFilter filter = settings.getInstrumentationFilter();\n\n        // TODO: fix for the new filters!\n        if (filter != null) {\n            map.put(\"profiler.settings.instrumentation.filter.string\", toString(filter.getValues()));\n            map.put(\"profiler.settings.instrumentation.filter.type\",\n                    ((filter.getType() == InstrumentationFilter.TYPE_EXCLUSIVE) ? \"EXCLUSIVE\" : \"INCLUSIVE\"));\n        } else {\n            map.put(\"profiler.settings.instrumentation.filter.selected\", \"NONE\");\n        }\n\n        SourceCodeSelection[] roots = settings.getInstrumentationRootMethods();\n\n        if ((roots != null) && (roots.length > 0)) {\n            map.put(\"profiler.settings.instrumentation.root.methods.size\", Integer.toString(roots.length));\n\n            StringBuilder sb = new StringBuilder();\n\n            for (int i = 0; i < roots.length; i++) {\n                if (roots[i].getStartLine() > -1) {\n                    sb.append(roots[i].getClassName());\n                    sb.append(\"[\");\n                    sb.append(roots[i].getStartLine());\n                    sb.append(\", \");\n                    sb.append(roots[i].getEndLine());\n                    sb.append(\"]\");\n                } else {\n                    sb.append(roots[i].getClassName());\n                    sb.append(\".\");\n                    sb.append(roots[i].getMethodName());\n                    sb.append(roots[i].getMethodSignature());\n                }\n\n                if (i < (roots.length - 1)) {\n                    sb.append(\", \");\n                }\n            }\n\n            map.put(\"profiler.settings.istrumentation.root.methods-\", sb.toString()); //prefix\n        } else {\n            map.put(\"profiler.settings.instrumentation.root.methods.size\", \"0\");\n            map.put(\"profiler.settings.istrumentation.root.methods-\", \"\");\n        }\n    }\n\n    protected void tearDown() throws Exception {\n        if (refStream != null) {\n            refStream.close();\n\n            if (CREATE_GOLDENS) {\n                goldenStream.close();\n            } else {\n                boolean bgolden = true;\n\n                try {\n                    getGoldenFile();\n                } catch (Throwable t) {\n                    bgolden = false;\n                }\n\n                if ((bgolden || (ref.length() > 0)) && !isStatus(STATUS_ERROR)) {\n                    LineDiff ld = new LineDiff();\n                    assertFalse(\"Golden files differ\", ld.diff(ref, getGoldenFile(), diff));\n                }\n            }\n        }\n\n        if (logStream != null) {\n            logStream.close();\n        }\n\n        System.err.println(\"Test \" + getName() + \" finished.\");\n    }\n\n    protected String toString(String[] array) {\n        StringBuilder sb = new StringBuilder();\n\n        for (int i = 0; i < array.length; i++) {\n            sb.append(array[i]);\n            sb.append(\" \");\n        }\n\n        return sb.toString();\n    }\n\n    protected String toString(int[] array) {\n        StringBuilder sb = new StringBuilder();\n\n        for (int i = 0; i < array.length; i++) {\n            sb.append(array[i]);\n            sb.append(\" \");\n        }\n\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/ProfilerStableTestSuite.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid;\n\nimport junit.framework.Test;\nimport org.netbeans.junit.NbModuleSuite;\n\n/**\n *\n * @author tester\n */\npublic class ProfilerStableTestSuite {\n    public static Test suite() {\n    return NbModuleSuite.create(\n      NbModuleSuite.emptyConfiguration()\n        .addTest(org.graalvm.visualvm.lib.jfluid.tests.jfluid.BasicTest.class)\n        .addTest(org.graalvm.visualvm.lib.jfluid.tests.jfluid.perf.InstrumentationTest.class)\n        .addTest(org.graalvm.visualvm.lib.jfluid.tests.jfluid.wireio.BasicTest.class)\n        .addTest(org.graalvm.visualvm.lib.jfluid.tests.jfluid.monitor.BasicTest.class)\n        .addTest(org.graalvm.visualvm.lib.jfluid.tests.jfluid.memory.BasicTest.class)\n\t.addTest(org.graalvm.visualvm.lib.jfluid.tests.jfluid.memory.MemorySnapshotTest.class)\n        .addTest(org.graalvm.visualvm.lib.jfluid.tests.jfluid.others.MeasureDiffsTest.class)\n        .addTest(org.graalvm.visualvm.lib.jfluid.tests.jfluid.cpu.CPUSnapshotTest.class)\n\t.addTest(org.graalvm.visualvm.lib.jfluid.tests.jfluid.cpu.BasicTest.class, org.graalvm.visualvm.lib.jfluid.tests.jfluid.cpu.BasicTest.tests)\n        .addTest(org.graalvm.visualvm.lib.jfluid.tests.jfluid.cpu.BasicTest.class, org.graalvm.visualvm.lib.jfluid.tests.jfluid.cpu.BasicTest.tests2)\n        .addTest(org.graalvm.visualvm.lib.jfluid.tests.jfluid.cpu.BasicTest.class, org.graalvm.visualvm.lib.jfluid.tests.jfluid.cpu.BasicTest.tests3)\n        .addTest(org.graalvm.visualvm.lib.jfluid.tests.jfluid.benchmarks.JbbTest.class)\n    );\n  }\n\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/benchmarks/JbbTest.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.benchmarks;\n\nimport junit.framework.Test;\nimport junit.textui.TestRunner;\nimport org.netbeans.junit.NbModuleSuite;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n\n/**\n *\n * @author ehucka\n */\npublic class JbbTest extends JbbTestType {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of JbbTest\n     */\n    public JbbTest(String name) {\n        super(name);\n    }\n\n    public static void main(String[] args) {\n        TestRunner.run(suite());\n    }\n\n    public static Test suite() {\n        return NbModuleSuite.create(\n            NbModuleSuite.createConfiguration(JbbTest.class).addTest(\n            \"testBasic\",\n            \"testDefaultEntire\",\n            \"testDefaultPart\",\n            \"testInstrumentEager\",\n            \"testInstrumentSampledLazy\",\n            \"testInstrumentSampledTotal\")\n            .honorAutoloadEager(true).enableModules(\".*\").clusters(\".*\").gui(false));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void testBasic() {\n        ProfilerEngineSettings settings = initCpuTest(\"jbb\", \"spec.jbb.JBBmain\");\n        startBenchmarkTest(settings, 20);\n    }\n\n    public void testDefaultEntire() {\n        ProfilerEngineSettings settings = initCpuTest(\"jbb\", \"spec.jbb.JBBmain\");\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_TOTAL);\n        settings.setInstrumentEmptyMethods(false);\n        settings.setInstrumentGetterSetterMethods(false);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentSpawnedThreads(true);\n        settings.setExcludeWaitTime(true);\n        startBenchmarkTest(settings, 170);\n    }\n\n    public void testDefaultPart() {\n        ProfilerEngineSettings settings = initCpuTest(\"jbb\", \"spec.jbb.JBBmain\");\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_LAZY);\n        settings.setInstrumentEmptyMethods(false);\n        settings.setInstrumentGetterSetterMethods(false);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentSpawnedThreads(false);\n        settings.setExcludeWaitTime(true);\n        startBenchmarkTest(settings, 10);\n    }\n\n    public void testInstrumentEager() {\n        ProfilerEngineSettings settings = initCpuTest(\"jbb\", \"spec.jbb.JBBmain\");\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_EAGER);\n        settings.setInstrumentEmptyMethods(false);\n        settings.setInstrumentGetterSetterMethods(false);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentSpawnedThreads(true);\n        settings.setExcludeWaitTime(true);\n        startBenchmarkTest(settings, 165);\n    }\n\n    public void testInstrumentSampledLazy() {\n        ProfilerEngineSettings settings = initCpuTest(\"jbb\", \"spec.jbb.JBBmain\");\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_SAMPLED);\n        settings.setSamplingInterval(10);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_LAZY);\n        settings.setInstrumentEmptyMethods(false);\n        settings.setInstrumentGetterSetterMethods(false);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentSpawnedThreads(true);\n        settings.setExcludeWaitTime(true);\n        startBenchmarkTest(settings, 30);\n    }\n\n    public void testInstrumentSampledTotal() {\n        ProfilerEngineSettings settings = initCpuTest(\"jbb\", \"spec.jbb.JBBmain\");\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_SAMPLED);\n        settings.setSamplingInterval(10);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_TOTAL);\n        settings.setInstrumentEmptyMethods(false);\n        settings.setInstrumentGetterSetterMethods(false);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentSpawnedThreads(true);\n        settings.setExcludeWaitTime(true);\n        startBenchmarkTest(settings, 35);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/benchmarks/JbbTestType.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * CPUType.java\n *\n * Created on July 19, 2005, 5:20 PM\n */\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.benchmarks;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.*;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.DumpStream;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.TestProfilerAppHandler;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.TestProfilingPointsProcessor;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.Utils;\nimport java.io.BufferedInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.util.*;\n\n\n/**\n *\n * @author ehucka\n */\npublic abstract class JbbTestType extends CommonProfilerTestCase {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of CPUType\n     */\n    public JbbTestType(String name) {\n        super(name);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    protected int[] checkResults(File workdir) {\n        try {\n            File rawres = new File(workdir, \"results/SPECjbbSingleJVM/SPECjbb.001.raw\");\n            log(rawres.getAbsolutePath() + \" exists \" + rawres.exists());\n\n            BufferedInputStream inp = new BufferedInputStream(new FileInputStream(rawres));\n            Properties props = new Properties();\n            props.load(inp);\n            inp.close();\n\n            int[] ret = new int[2];\n            ret[0] = (int) Double.parseDouble(props.getProperty(\"result.test1.company.score\"));\n            //ret[0][1]=(int)Double.parseDouble(props.getProperty(\"result.test1.company.heapused\"));\n            ret[1] = (int) Double.parseDouble(props.getProperty(\"result.test2.company.score\"));\n\n            //ret[1][1]=(int)Double.parseDouble(props.getProperty(\"result.test2.company.heapused\"));\n            return ret;\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n\n        return null;\n    }\n\n    protected void evalueateResults(int[] without, int[] with, int maxSlowdown) {\n        double[] diffs = new double[with.length];\n\n        for (int i = 0; i < diffs.length; i++) {\n            diffs[i] = (100.0 * (without[i] - with[i])) / with[i];\n        }\n\n        int maxmult = 0;\n        log(\"\\n\\nTests     Normal    Profiler  Diff%     Multiple\");\n\n        for (int i = 0; i < diffs.length; i++) {\n            log(complete(\"test \" + String.valueOf(i + 1), 10) + complete(String.valueOf(without[i]), 10)\n                + complete(String.valueOf(with[i]), 10) + complete(String.valueOf(diffs[i]), 6) + \" %  \"\n                + complete(String.valueOf(without[i] / with[i]), 8));\n\n            if (maxmult < (without[i] / with[i])) {\n                maxmult = without[i] / with[i];\n            }\n        }\n\n        log(\"\\nMax multiple: \" + String.valueOf(maxmult) + \" Max allowed: \"+maxSlowdown+\"\\n\");\n        assertTrue(\"Difference multiple is greater than \"+maxSlowdown+\" - \" + String.valueOf(maxmult), (maxmult <= maxSlowdown));\n    }\n\n    protected ProfilerEngineSettings initCpuTest(String projectName, String mainClass) {\n        ProfilerEngineSettings settings = initTest(projectName, mainClass, null);\n\n        //defaults\n        //addJVMArgs(settings, \"-Dorg.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO=true\");\n        String xData = new File(getDataDir(), \"/projects/\" + projectName + \"/config.properties\").getAbsolutePath();\n        addJVMArgs(settings, \"-Xms256m -Xmx256m\");\n        settings.setMainArgs(\"-propfile \" + xData);\n        settings.setThreadCPUTimerOn(false);\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);\n\n        Utils.copyFolder(new File(getDataDir(), \"/projects/\" + projectName + \"/xml\"), new File(settings.getWorkingDir(), \"xml\"));\n\n        return settings;\n    }\n\n    protected void startBenchmarkTest(ProfilerEngineSettings settings, int maxSlowdown) {\n        //without profiler\n        log(\"without profiler\");\n        log(\"*******************************************************************************\");\n\n        ArrayList command = new ArrayList(20);\n        command.add(settings.getTargetJVMExeFile());\n        command.add(\"-cp\");\n        command.add(settings.getMainClassPath());\n\n        String[] args = settings.getJVMArgs();\n\n        for (String arg : args) {\n            command.add(arg);\n        }\n\n        command.add(settings.getMainClassName());\n        args = settings.getMainArgs();\n\n        for (String arg : args) {\n            command.add(arg);\n        }\n\n        try {\n            Process p = Runtime.getRuntime()\n                               .exec((String[]) (command.toArray(new String[0])), null,\n                                     new File(settings.getWorkingDir()));\n            new DumpStream(p, p.getErrorStream(), getLogStream(), \"[App error] \").start();\n            new DumpStream(p, p.getInputStream(), getLogStream(), \"[App output] \").start();\n            p.waitFor();\n        } catch (Exception ex) {\n            ex.printStackTrace();\n        }\n\n        File workdir = new File(settings.getWorkingDir());\n        int[] res1 = checkResults(workdir);\n        TargetAppRunner runner = new TargetAppRunner(settings, new TestProfilerAppHandler(this),\n                                                     new TestProfilingPointsProcessor());\n\n        try {\n            Utils.removeFolder(new File(workdir, \"results\"));\n            log(\"with profiler\");\n            log(\"*******************************************************************************\");\n            runner.addProfilingEventListener(Utils.createProfilingListener(this));\n\n            runner.readSavedCalibrationData();\n            runner.getProfilerClient().initiateRecursiveCPUProfInstrumentation(settings.getInstrumentationRootMethods());\n\n            long time = System.currentTimeMillis();\n            Process p = startTargetVM(runner);\n            assertNotNull(\"Target JVM is not started\", p);\n            time = System.currentTimeMillis();\n            runner.attachToTargetVMOnStartup();\n            //Thread.sleep(delay);//wait for init\n            waitForStatus(STATUS_RUNNING);\n            assertTrue(\"runner is not running\", runner.targetAppIsRunning());\n\n            ArrayList metods = new ArrayList();\n            long checkDelay = 1500;\n            \n            while (!isStatus(STATUS_APP_FINISHED) && !isStatus(STATUS_ERROR)) {\n                time = System.currentTimeMillis();\n                Thread.sleep(checkDelay);\n\n                //do nothing\n            }\n\n            setStatus(STATUS_MEASURED);\n            log(\"finish ****************************** \" + getStatus());\n\n            int[] res2 = checkResults(workdir);\n            evalueateResults(res1, res2, maxSlowdown);\n        } catch (Exception ex) {\n            log(ex);\n            assertTrue(\"Exception thrown: \" + ex.getMessage(), false);\n        } finally {\n            finalizeTest(runner);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/BasicTest.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.cpu;\n\nimport junit.framework.Test;\nimport junit.textui.TestRunner;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.netbeans.junit.NbModuleSuite;\n\n/**\n *\n * @author ehucka\n */\npublic class BasicTest extends CPUTestCase {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final long MAX_DELAY = 25000L;\n\n    public static final String[] tests = new String[]{\n        /*\"testLiveResultsAll\",\n        \"testLiveResultsBasic\",\n        \"testLiveResultsWaitEager\",\n        \"testLiveResultsWaitLazy\",\n        \"testLiveResultsWaitSampled\", // not stable */\n        \"testLiveResultsWaitServer\",\n        \"testLiveResultsWaitTotal\",\n        \"testMethodWithWaitEager\",\n        \"testMethodWithWaitEagerServer\",\n        \"testMethodWithWaitExcludeWEager\",\n        \"testMethodWithWaitExcludeWLazy\",\n        \"testMethodWithWaitExcludeWTotal\",\n        \"testMethodWithWaitLazy\"\n    };\n    public static final String[] tests2 = new String[]{\n        \"testMethodWithWaitLazyServer\",\n        \"testMethodWithWaitTotal\",\n        \"testMethodWithWaitTotalServer\",\n        \"testSettingsDefault\", // not stable\n        \"testSettingsInstrumenManyMethodsLazy\",\n        \"testSettingsInstrumentAllEager\",\n        \"testSettingsInstrumentAllEagerServer\",\n        \"testSettingsInstrumentAllLazy\",\n        \"testSettingsInstrumentAllLazyServer\",\n        \"testSettingsInstrumentAllTotal\",\n        \"testSettingsInstrumentAllTotalServer\",\n        \"testSettingsInstrumentExcludeJavas\",\n        \"testSettingsInstrumentExcludeJavasServer\"\n    };\n    public static final String[] tests3 = new String[]{\n        \"testSettingsInstrumentManyMethodsTotal\",\n        \"testSettingsInstrumentNotSpawnedThreads\",\n        \"testSettingsInstrumentNotSpawnedThreadsServer\",\n        \"testSettingsInstrumentRootMethod\",\n        \"testSettingsInstrumentRootMethodServer\",\n        \"testSettingsLimitedThreads\",\n        \"testSettingsLimitedThreadsServer\",\n        \"testSettingsSampledProfilingEager\",\n        \"testSettingsSampledProfilingLazy\",\n        \"testSettingsSampledProfilingServerEager\",\n        \"testSettingsSampledProfilingServerLazy\",\n        \"testSettingsSampledProfilingServerTotal\",\n        \"testSettingsSampledProfilingTotal\"\n    };\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n            /** Creates a new instance of BasicTest */\n\n    public BasicTest(String name) {\n        super(name);\n    }\n\n    public static void main(String[] args) {\n        TestRunner.run(suite());\n    }\n\n    public static Test suite() {\n        return NbModuleSuite.create(\n                NbModuleSuite.createConfiguration(BasicTest.class).addTest(\n                \"testLiveResultsAll\",\n                \"testLiveResultsBasic\",\n                \"testLiveResultsWaitEager\",\n                \"testLiveResultsWaitLazy\",\n                \"testLiveResultsWaitSampled\",\n                \"testLiveResultsWaitServer\",\n                \"testLiveResultsWaitTotal\",\n                \"testMethodWithWaitEager\",\n                \"testMethodWithWaitEagerServer\",\n                \"testMethodWithWaitExcludeWEager\",\n                \"testMethodWithWaitExcludeWLazy\",\n                \"testMethodWithWaitExcludeWTotal\",\n                \"testMethodWithWaitLazy\",\n                 \"testMethodWithWaitLazyServer\",\n                \"testMethodWithWaitTotal\",\n                \"testMethodWithWaitTotalServer\",\n                \"testSettingsDefault\",\n//                \"testSettingsInstrumenManyMethodsLazy\", JVM crash \n                \"testSettingsInstrumentAllEager\",\n                \"testSettingsInstrumentAllEagerServer\",\n                \"testSettingsInstrumentAllLazy\",\n                \"testSettingsInstrumentAllLazyServer\",\n                \"testSettingsInstrumentAllTotal\",\n                \"testSettingsInstrumentAllTotalServer\",\n                \"testSettingsInstrumentExcludeJavas\",\n                \"testSettingsInstrumentExcludeJavasServer\",\n                \"testSettingsInstrumentManyMethodsTotal\",\n                \"testSettingsInstrumentNotSpawnedThreads\",\n                \"testSettingsInstrumentNotSpawnedThreadsServer\",\n                \"testSettingsInstrumentRootMethod\",\n                \"testSettingsInstrumentRootMethodServer\",\n                \"testSettingsLimitedThreads\",\n                \"testSettingsLimitedThreadsServer\",\n                \"testSettingsSampledProfilingEager\",\n                \"testSettingsSampledProfilingLazy\",\n                \"testSettingsSampledProfilingServerEager\",\n                \"testSettingsSampledProfilingServerLazy\",\n                \"testSettingsSampledProfilingServerTotal\",\n                \"testSettingsSampledProfilingTotal\"\n                ).enableModules(\".*\").clusters(\".*\").gui(false));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    public void temptestSettingsInstrumentRootMethod(boolean server) {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.CPU1\",\n                new String[][]{\n                    {\"simple.cpu.CPUThread\", \"run\", \"()V\"}\n                });\n        settings.setInstrumentSpawnedThreads(false);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentGetterSetterMethods(true);\n        settings.setInstrumentEmptyMethods(true);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_LAZY);\n\n        if (server) {\n            addJVMArgs(settings, \"-server\");\n        }\n\n        startCPUTest(settings, new String[]{\"simple.cpu.CPUThread.run512()\"}, new long[]{512L}, 40.0,\n                new String[]{\"simple\"}, ALL_INV_ERROR_METHOD);\n    }\n\n    public void testLiveResultsAll() {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.CPU1\");\n        startCPUTest(settings, new String[]{\"\"}, 1000, MAX_DELAY);\n    }\n\n    public void testLiveResultsBasic() {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.CPU\");\n        startCPUTest(settings, new String[]{\"simple\"}, 1500, MAX_DELAY);\n    }\n\n    public void testLiveResultsWaitEager() {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.WaitingTest\");\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_EAGER);\n        startCPUTest(settings, new String[]{\"simple\"}, 1000, MAX_DELAY);\n    }\n\n    public void testLiveResultsWaitLazy() {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.WaitingTest\");\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_LAZY);\n        startCPUTest(settings, new String[]{\"simple\"}, 1000, MAX_DELAY);\n    }\n\n    public void testLiveResultsWaitSampled() {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.WaitingTest\");\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_SAMPLED);\n        settings.setSamplingInterval(1);\n        startCPUTest(settings, new String[]{\"simple\"}, 1000, MAX_DELAY);\n    }\n\n    public void testLiveResultsWaitServer() {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.WaitingTest\");\n        addJVMArgs(settings, \"-server\");\n        startCPUTest(settings, new String[]{\"simple\"}, 1000, MAX_DELAY);\n    }\n\n    public void testLiveResultsWaitTotal() {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.WaitingTest\");\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_TOTAL);\n        startCPUTest(settings, new String[]{\"simple\"}, 1000, MAX_DELAY);\n    }\n\n    public void testMethodWithWaitEager() {\n        temptestMethodWithWait(CommonConstants.INSTRSCHEME_EAGER, false, false, 2000L);\n    }\n\n    public void testMethodWithWaitEagerServer() {\n        temptestMethodWithWait(CommonConstants.INSTRSCHEME_EAGER, false, true, 2000L);\n    }\n\n    public void testMethodWithWaitExcludeWEager() {\n        temptestMethodWithWait(CommonConstants.INSTRSCHEME_EAGER, true, false, 4000L);\n    }\n\n    public void testMethodWithWaitExcludeWLazy() {\n        temptestMethodWithWait(CommonConstants.INSTRSCHEME_LAZY, true, false, 4000L);\n    }\n\n    public void testMethodWithWaitExcludeWTotal() {\n        temptestMethodWithWait(CommonConstants.INSTRSCHEME_TOTAL, true, false, 4000L);\n    }\n\n    public void testMethodWithWaitLazy() {\n        temptestMethodWithWait(CommonConstants.INSTRSCHEME_LAZY, false, false, 2000L);\n    }\n\n    public void testMethodWithWaitLazyServer() {\n        temptestMethodWithWait(CommonConstants.INSTRSCHEME_LAZY, false, true, 2000L);\n    }\n\n    public void testMethodWithWaitTotal() {\n        temptestMethodWithWait(CommonConstants.INSTRSCHEME_TOTAL, false, false, 2000L);\n    }\n\n    public void testMethodWithWaitTotalServer() {\n        temptestMethodWithWait(CommonConstants.INSTRSCHEME_TOTAL, false, true, 2000L);\n    }\n\n    public void testSettingsDefault() {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.CPU1\");\n        startCPUTest(settings,\n                new String[]{\n                    \"simple.cpu.Bean.run20()\", \"simple.cpu.Bean.run100()\", \"simple.cpu.Bean.run1000()\",\n                    \"simple.cpu.CPUThread.run512()\"\n                }, new long[]{20L, 100L, 1000L, 512L}, 40.0, new String[]{\"simple\"}, ALL_INV_ERROR_METHOD);\n    }\n\n    public void testSettingsInstrumenManyMethodsLazy() {\n        temptestSettingsInstrumentManyMethods(CommonConstants.INSTRSCHEME_LAZY);\n    }\n\n    public void testSettingsInstrumentAllEager() {\n        temptestSettingsInstrumentAll(CommonConstants.INSTRSCHEME_EAGER, false);\n    }\n\n    public void testSettingsInstrumentAllEagerServer() {\n        temptestSettingsInstrumentAll(CommonConstants.INSTRSCHEME_EAGER, true);\n    }\n\n    public void testSettingsInstrumentAllLazy() {\n        temptestSettingsInstrumentAll(CommonConstants.INSTRSCHEME_LAZY, false);\n    }\n\n    public void testSettingsInstrumentAllLazyServer() {\n        temptestSettingsInstrumentAll(CommonConstants.INSTRSCHEME_LAZY, true);\n    }\n\n    public void testSettingsInstrumentAllTotal() {\n        temptestSettingsInstrumentAll(CommonConstants.INSTRSCHEME_TOTAL, false);\n    }\n\n    public void testSettingsInstrumentAllTotalServer() {\n        temptestSettingsInstrumentAll(CommonConstants.INSTRSCHEME_TOTAL, true);\n    }\n\n    public void testSettingsInstrumentExcludeJavas() {\n        temptestSettingsInstrumentExcludeJavas(false);\n    }\n\n    public void testSettingsInstrumentExcludeJavasServer() {\n        temptestSettingsInstrumentExcludeJavas(true);\n    }\n\n    public void testSettingsInstrumentManyMethodsTotal() {\n        temptestSettingsInstrumentManyMethods(CommonConstants.INSTRSCHEME_TOTAL);\n    }\n\n    public void testSettingsInstrumentNotSpawnedThreads() {\n        temptestSettingsInstrumentNotSpawnedThreads(false);\n    }\n\n    public void testSettingsInstrumentNotSpawnedThreadsServer() {\n        temptestSettingsInstrumentNotSpawnedThreads(true);\n    }\n\n    public void testSettingsInstrumentRootMethod() {\n        temptestSettingsInstrumentRootMethod(false);\n    }\n\n    public void testSettingsInstrumentRootMethodServer() {\n        temptestSettingsInstrumentRootMethod(true);\n    }\n\n    public void testSettingsLimitedThreads() {\n        temptestSettingsLimitedThreads(false);\n    }\n\n    public void testSettingsLimitedThreadsServer() {\n        temptestSettingsLimitedThreads(true);\n    }\n\n    public void testSettingsSampledProfilingEager() {\n        temptestSettingsSampledProfiling(false, CommonConstants.INSTRSCHEME_EAGER);\n    }\n\n    public void testSettingsSampledProfilingLazy() {\n        temptestSettingsSampledProfiling(false, CommonConstants.INSTRSCHEME_LAZY);\n    }\n\n    public void testSettingsSampledProfilingServerEager() {\n        temptestSettingsSampledProfiling(true, CommonConstants.INSTRSCHEME_EAGER);\n    }\n\n    public void testSettingsSampledProfilingServerLazy() {\n        temptestSettingsSampledProfiling(true, CommonConstants.INSTRSCHEME_LAZY);\n    }\n\n    public void testSettingsSampledProfilingServerTotal() {\n        temptestSettingsSampledProfiling(true, CommonConstants.INSTRSCHEME_TOTAL);\n    }\n\n    public void testSettingsSampledProfilingTotal() {\n        temptestSettingsSampledProfiling(false, CommonConstants.INSTRSCHEME_TOTAL);\n    }\n\n    protected void temptestMethodWithWait(int instrscheme, boolean withwaits, boolean server, long idealtime) {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.WaitingTest\",\n                new String[][]{\n                    {\"simple.cpu.WaitingTest\", \"method1000\", \"()V\"}\n                });\n        settings.setInstrScheme(instrscheme);\n        settings.setExcludeWaitTime(!withwaits);\n\n        if (server) {\n            addJVMArgs(settings, \"-server\");\n        }\n\n        startCPUTest(settings, new String[]{\"simple.cpu.WaitingTest.method1000()\"}, new long[]{idealtime}, 40.0,\n                new String[]{\"simple\"}, ALL_INV_ERROR_METHOD);\n    }\n\n    protected void temptestSettingsInstrumentAll(int instrScheme, boolean server) {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.CPU1\");\n        settings.setInstrumentSpawnedThreads(true);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentGetterSetterMethods(true);\n        settings.setInstrumentEmptyMethods(true);\n        settings.setInstrScheme(instrScheme);\n\n        if (server) {\n            addJVMArgs(settings, \"-server\");\n        }\n\n        startCPUTest(settings,\n                new String[]{\n                    \"simple.cpu.Bean.run20()\", \"simple.cpu.Bean.run100()\", \"simple.cpu.Bean.run1000()\",\n                    \"simple.cpu.CPUThread.run512()\"\n                }, new long[]{20L, 100L, 1000L, 512L}, 40.0, new String[]{\"simple\"}, ALL_INV_ERROR_METHOD);\n    }\n\n    protected void temptestSettingsInstrumentExcludeJavas(boolean server) {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.CPU1\");\n        settings.setInstrumentSpawnedThreads(true);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentGetterSetterMethods(false);\n        settings.setInstrumentEmptyMethods(false);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_LAZY);\n\n        if (server) {\n            addJVMArgs(settings, \"-server\");\n        }\n\n        // TODO: fix for the new filters!\n        InstrumentationFilter filter = new InstrumentationFilter();\n        filter.setType(InstrumentationFilter.TYPE_EXCLUSIVE);\n        filter.setValue(\"java\");\n        settings.setInstrumentationFilter(filter);\n        startCPUTest(settings,\n                new String[]{\n                    \"simple.cpu.Bean.run20()\", \"simple.cpu.Bean.run100()\", \"simple.cpu.Bean.run1000()\",\n                    \"simple.cpu.CPUThread.run512()\"\n                }, new long[]{20L, 100L, 1000L, 512L}, 40.0, new String[]{\"simple\", \"java\"}, ALL_INV_ERROR_METHOD);\n    }\n\n    protected void temptestSettingsInstrumentManyMethods(int instrscheme) {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.Methods2\");\n        settings.setInstrumentSpawnedThreads(true);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentGetterSetterMethods(true);\n        settings.setInstrumentEmptyMethods(true);\n        settings.setInstrScheme(instrscheme);\n        startCPUTest(settings, new String[]{\"simple.cpu.Methods2.method0()\"}, new long[]{400L}, 40.0,\n                new String[]{\"simple.cpu.Methods2.method1\"}, ALL_INV_ERROR_METHOD);\n    }\n\n    protected void temptestSettingsInstrumentNotSpawnedThreads(boolean server) {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.CPU1\");\n        settings.setInstrumentSpawnedThreads(false);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentGetterSetterMethods(true);\n        settings.setInstrumentEmptyMethods(true);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_LAZY);\n\n        if (server) {\n            addJVMArgs(settings, \"-server\");\n        }\n\n        startCPUTest(settings,\n                new String[]{\n                    \"simple.cpu.Bean.run20()\", \"simple.cpu.Bean.run100()\", \"simple.cpu.Bean.run1000()\",\n                    \"simple.cpu.CPUThread.run512()\"\n                }, new long[]{20L, 100L, 1000L, 512L}, 40.0, new String[]{\"simple\"}, ALL_INV_ERROR_METHOD);\n    }\n\n    protected void temptestSettingsLimitedThreads(boolean server) {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.CPU1\");\n        settings.setInstrumentSpawnedThreads(true);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentGetterSetterMethods(true);\n        settings.setInstrumentEmptyMethods(true);\n        settings.setNProfiledThreadsLimit(1);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_LAZY);\n\n        if (server) {\n            addJVMArgs(settings, \"-server\");\n        }\n\n        startCPUTest(settings,\n                new String[]{\n                    \"simple.cpu.Bean.run20()\", \"simple.cpu.Bean.run100()\", \"simple.cpu.Bean.run1000()\",\n                    \"simple.cpu.CPUThread.run512()\"\n                }, new long[]{20L, 100L, 1000L, 512L}, 40.0, new String[]{\"simple\"}, ALL_INV_ERROR_METHOD);\n    }\n\n    protected void temptestSettingsSampledProfiling(boolean server, int instrScheme) {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.CPU1\");\n        settings.setInstrumentSpawnedThreads(true);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentGetterSetterMethods(true);\n        settings.setInstrumentEmptyMethods(true);\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_SAMPLED);\n        settings.setSamplingInterval(5);\n        settings.setInstrScheme(instrScheme);\n\n        if (server) {\n            addJVMArgs(settings, \"-server\");\n        }\n\n        startCPUTest(settings,\n                new String[]{\n                    \"simple.cpu.Bean.run20()\", \"simple.cpu.Bean.run100()\", \"simple.cpu.Bean.run1000()\",\n                    \"simple.cpu.CPUThread.run512()\"\n                }, new long[]{20L, 100L, 1000L, 512L}, 40.0, new String[]{\"simple\"}, ALL_INV_ERROR_METHOD);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/CPUSnapshotTest.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.cpu;\n\nimport junit.framework.Test;\nimport junit.textui.TestRunner;\nimport org.netbeans.junit.NbModuleSuite;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\n\n\n/**\n *\n * @author ehucka\n */\npublic class CPUSnapshotTest extends CPUSnapshotTestCase {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of BasicTest */\n    public CPUSnapshotTest(String name) {\n        super(name);\n    }\n\n    public static void main(String[] args) {\n        TestRunner.run(suite());\n    }\n\n    public static Test suite() {\n        return NbModuleSuite.create(\n            NbModuleSuite.createConfiguration(CPUSnapshotTest.class).addTest(\n            \"testMethods\",\n            \"testMethodsServer\",\n            \"testNoThreads\",\n            \"testSimple\",\n            \"testSimpleServer\",\n            \"testThreads\",\n            \"testThreadsServer\",\n            \"testWaits\",\n            \"testWaitsServer\")\n            .honorAutoloadEager(true).enableModules(\".*\").clusters(\".*\").gui(false));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void testMethods() {\n        ProfilerEngineSettings settings = initSnapshotTest(\"j2se-simple\", \"simple.cpu.Methods\", null);\n        startSnapshotTest(settings, new String[] { \"simple.cpu.Methods\", \"method27\", \"()V\" }, 0, 1.0,\n                          new String[] { \"sun\", \"java\" });\n    }\n\n    public void testMethodsServer() {\n        ProfilerEngineSettings settings = initSnapshotTest(\"j2se-simple\", \"simple.cpu.Methods\", null);\n        addJVMArgs(settings, \"-server\");\n        startSnapshotTest(settings, new String[] { \"simple.cpu.Methods\", \"method27\", \"()V\" }, 0, 1.0,\n                          new String[] { \"sun\", \"java\" });\n    }\n\n    public void testNoThreads() {\n        ProfilerEngineSettings settings = initSnapshotTest(\"j2se-simple\", \"simple.cpu.Region\", null);\n        settings.setInstrumentSpawnedThreads(false);\n        startSnapshotTest(settings, new String[] { \"simple.cpu.Region\", \"run100\", \"()V\" }, 0, 1.0, new String[] { \"sun\", \"java\" });\n    }\n\n    public void testSimple() {\n        ProfilerEngineSettings settings = initSnapshotTest(\"j2se-simple\", \"simple.CPU\", null);\n        startSnapshotTest(settings, new String[] { \"simple.CPU\", \"test20\", \"()V\" }, 0, 1.0, new String[] { \"sun\", \"java\" });\n    }\n\n    public void testSimpleServer() {\n        ProfilerEngineSettings settings = initSnapshotTest(\"j2se-simple\", \"simple.CPU\", null);\n        addJVMArgs(settings, \"-server\");\n        startSnapshotTest(settings, new String[] { \"simple.CPU\", \"test20\", \"()V\" }, 0, 1.0, new String[] { \"sun\", \"java\" });\n    }\n\n    public void testThreads() {\n        ProfilerEngineSettings settings = initSnapshotTest(\"j2se-simple\", \"simple.cpu.Region\", null);\n        settings.setInstrumentSpawnedThreads(true);\n        startSnapshotTest(settings, new String[] { \"simple.cpu.Region\", \"run100\", \"()V\" }, 0, 1.0, new String[] { \"sun\", \"java\" });\n    }\n\n    public void testThreadsServer() {\n        ProfilerEngineSettings settings = initSnapshotTest(\"j2se-simple\", \"simple.cpu.Region\", null);\n        addJVMArgs(settings, \"-server\");\n        settings.setInstrumentSpawnedThreads(true);\n        startSnapshotTest(settings, new String[] { \"simple.cpu.Region\", \"run100\", \"()V\" }, 0, 1.0, new String[] { \"sun\", \"java\" });\n    }\n\n    public void testWaits() {\n        ProfilerEngineSettings settings = initSnapshotTest(\"j2se-simple\", \"simple.cpu.WaitingTest\", null);\n        startSnapshotTest(settings, new String[] { \"simple.cpu.WaitingTest\", \"method1000\", \"()V\" }, 0, 1.0,\n                          new String[] { \"sun\", \"java\" });\n    }\n\n    public void testWaitsServer() {\n        ProfilerEngineSettings settings = initSnapshotTest(\"j2se-simple\", \"simple.cpu.WaitingTest\", null);\n        addJVMArgs(settings, \"-server\");\n        startSnapshotTest(settings, new String[] { \"simple.cpu.WaitingTest\", \"method1000\", \"()V\" }, 0, 1.0,\n                          new String[] { \"sun\", \"java\" });\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/CPUSnapshotTestCase.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * CPUSnapshotTestCase.java\n *\n * Created on July 19, 2005, 5:20 PM\n */\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.EventBufferResultsProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.ProfilingResultsDispatcher;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCallGraphBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainerFree;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.*;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.*;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\n\n\n/**\n *\n * @author ehucka\n */\npublic abstract class CPUSnapshotTestCase extends CommonProfilerTestCase {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private class CPUResultListener implements CPUCCTProvider.Listener {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private final Object resultsLock = new Object();\n        private boolean hasResults = false;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void cctEstablished(RuntimeCCTNode appRootNode) {\n            log(\"CCT Results established\");\n\n            synchronized (resultsLock) {\n                hasResults = true;\n                resultsLock.notify();\n            }\n        }\n\n        public void cctReset() {\n            log(\"CCT Results reset\");\n\n            synchronized (resultsLock) {\n                hasResults = false;\n                resultsLock.notify();\n            }\n        }\n\n        public boolean wait4results(long timeout) {\n            synchronized (resultsLock) {\n                if (!hasResults) {\n                    try {\n                        resultsLock.wait(timeout);\n                    } catch (InterruptedException e) {\n                    }\n                }\n\n                return hasResults;\n            }\n        }\n\n        public void cctEstablished(RuntimeCCTNode appRootNode, boolean empty) {\n            throw new UnsupportedOperationException(\"Not supported yet.\");\n        }\n    }\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of CPUSnapshotTestCase\n     */\n    public CPUSnapshotTestCase(String name) {\n        super(name);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    protected boolean checkSerialization(CPUResultsSnapshot snapshot) {\n        try {\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            DataOutputStream dos = new DataOutputStream(baos);\n            snapshot.writeToStream(dos);\n            dos.close();\n\n            byte[] bytes = baos.toByteArray();\n            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);\n            DataInputStream dis = new DataInputStream(bais);\n            CPUResultsSnapshot snapshot2 = new CPUResultsSnapshot();\n            snapshot2.readFromStream(dis);\n            dis.close();\n\n            baos = new ByteArrayOutputStream();\n            dos = new DataOutputStream(baos);\n            snapshot2.writeToStream(dos);\n            dos.close();\n\n            byte[] bytes2 = baos.toByteArray();\n\n            //compare\n            if (bytes.length != bytes2.length) {\n                return false;\n            }\n\n            for (int i = 0; i < bytes.length; i++) {\n                if (bytes[i] != bytes2[i]) {\n                    return false;\n                }\n            }\n\n            return true;\n        } catch (Exception ex) {\n            ex.printStackTrace();\n        }\n\n        return false;\n    }\n\n    protected void checkSumsOfCCTNodes(PrestimeCPUCCTNode node, String pre, double tolerance, String[] filterout, int level) {\n        log(complete(pre + node.getNodeName(), 62) + complete(StringUtils.mcsTimeToString(node.getTotalTime0()), 9) + \" ms   (\"\n            + complete(StringUtils.floatPerCentToString(node.getTotalTime0InPerCent()), 7) + \" %)  \"\n            + complete(String.valueOf(node.getNCalls()), 3));\n\n        boolean exclude = false;\n\n        if (filterout != null) {\n            for (String filterout1 : filterout) {\n                if (node.getNodeName().startsWith(filterout1)) {\n                    exclude = true;\n\n                    break;\n                }\n            }\n        }\n\n        if (!exclude) {\n            long time = 0;\n            float percent = 0.0f;\n\n            for (int i = 0; i < node.getNChildren(); i++) {\n                PrestimeCPUCCTNode pnode = (PrestimeCPUCCTNode) (node.getChild(i));\n                checkSumsOfCCTNodes(pnode, pre + \" \", tolerance, filterout, level + 1);\n                time += pnode.getTotalTime0();\n                percent += pnode.getTotalTime0InPerCent();\n            }\n\n            if ((level > 1) && (node.getNChildren() > 0)) {\n                long absDiff = Math.abs(time - node.getTotalTime0());\n                if (absDiff > 5) {\n                    double timediff = (absDiff * 100.0) / node.getTotalTime0();\n                    double percentdiff = (Math.abs(percent - node.getTotalTime0InPerCent()) * 100.0) / node.getTotalTime0InPerCent();\n\n                    if ((timediff > tolerance) || (percentdiff > tolerance)) {\n                        log(\"Node : \" + node.getNodeName());\n                        log(\"Time diff: \" + timediff + \" %\");\n                        log(\"Percent diff: \" + percentdiff + \" %\");\n                        assertTrue(\"Node's and sum of subnodes values differ\", false);\n                    }\n                }\n            }\n        }\n    }\n\n    protected int[] findThreadAndMethod(PrestimeCPUCCTNode node, String[] method, String[] filterout) {\n        boolean exclude = false;\n\n        if (filterout != null) {\n            for (String filterout1 : filterout) {\n                if (node.getNodeName().startsWith(filterout1)) {\n                    exclude = true;\n\n                    break;\n                }\n            }\n        }\n\n        if (!exclude) {\n            String[] nmethod = node.getMethodClassNameAndSig();\n            boolean found = true;\n\n            for (int i = 0; i < nmethod.length; i++) {\n                if (!nmethod[i].equals(method[i])) {\n                    found = false;\n                }\n            }\n\n            if (found) {\n                return new int[] { node.getThreadId(), node.getMethodId() };\n            }\n\n            for (int i = 0; i < node.getNChildren(); i++) {\n                PrestimeCPUCCTNode pnode = (PrestimeCPUCCTNode) (node.getChild(i));\n                int[] ret = findThreadAndMethod(pnode, method, filterout);\n\n                if (ret != null) {\n                    return ret;\n                }\n            }\n        }\n\n        return null;\n    }\n\n    protected ProfilerEngineSettings initSnapshotTest(String projectName, String mainClass, String[][] rootMethods) {\n        ProfilerEngineSettings settings = initTest(projectName, mainClass, rootMethods);\n        //defaults\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_TOTAL);\n        settings.setInstrumentEmptyMethods(false);\n        settings.setInstrumentGetterSetterMethods(false);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentSpawnedThreads(true);\n        settings.setExcludeWaitTime(true);\n        //addJVMArgs(settings, \"-Dorg.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO=true\");\n        settings.setThreadCPUTimerOn(false);\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);\n\n        return settings;\n    }\n\n    protected void refOfCCTNodes(PrestimeCPUCCTNode node, String pre, boolean time, boolean percent, boolean invocations) {\n        ref(complete(pre + getNodeName(node), 62)\n            + ((!time) ? \"\" : (complete(String.valueOf(node.getTotalTime0() / 1000.0), 9) + \" ms   \"))\n            + ((!percent) ? \"\" : (complete(String.valueOf(node.getTotalTime0InPerCent()), 7) + \" %  \"))\n            + ((!invocations) ? \"\" : complete(String.valueOf(node.getNCalls()), 3)));\n\n        for (int i = 0; i < node.getNChildren(); i++) {\n            PrestimeCPUCCTNode pnode = (PrestimeCPUCCTNode) (node.getChild(i));\n            refOfCCTNodes(pnode, pre + \" \", time, percent, invocations);\n        }\n    }\n\n    protected void startSnapshotTest(ProfilerEngineSettings settings, String[] reverseMethod, long initDelay, double diffPercent,\n                                     String[] filterout) {\n        CPUCallGraphBuilder builder = new CPUCallGraphBuilder();\n\n        TargetAppRunner runner = new TargetAppRunner(settings, new TestProfilerAppHandler(this),\n                                                     new TestProfilingPointsProcessor());\n        runner.addProfilingEventListener(Utils.createProfilingListener(this));\n\n        builder.removeAllListeners();\n        ProfilingResultsDispatcher.getDefault().removeAllListeners();\n\n        CPUResultListener resultListener = new CPUResultListener();\n        builder.addListener(resultListener);\n\n        FlatProfileBuilder flattener = new FlatProfileBuilder();\n        builder.addListener(flattener);\n        flattener.setContext(runner.getProfilerClient(),null,null);\n\n        ProfilingResultsDispatcher.getDefault().addListener(builder);\n\n        builder.startup(runner.getProfilerClient());\n\n        try {\n            runner.readSavedCalibrationData();\n            runner.getProfilerClient().initiateRecursiveCPUProfInstrumentation(settings.getInstrumentationRootMethods());\n\n            Process p = startTargetVM(runner);\n            assertNotNull(\"Target JVM is not started\", p);\n            bindStreams(p);\n            runner.attachToTargetVMOnStartup();\n\n            waitForStatus(STATUS_RUNNING);\n            assertTrue(\"runner is not running\", runner.targetAppIsRunning());\n\n            if (initDelay == 0) {\n                waitForStatus(STATUS_APP_FINISHED);\n            } else {\n                Thread.sleep(initDelay);\n            }\n\n            if (runner.targetJVMIsAlive()) {\n                log(\"obtaining results \" + String.valueOf(System.currentTimeMillis()));\n                assertTrue(\"Results do not exist - issue 65185.\", runner.getProfilerClient().cpuResultsExist());\n\n                if (initDelay == 0) {\n                    Thread.sleep(200); // wait a while so that client can process all CPU results\n                }\n                CPUResultsSnapshot snapshot = runner.getProfilerClient().getCPUProfilingResultsSnapshot();\n                log(\"\\nSnapshot:\");\n\n                //test tree values\n                PrestimeCPUCCTNode root = snapshot.getRootNode(CPUResultsSnapshot.METHOD_LEVEL_VIEW);\n                log(\"Snapshot taken: \" + snapshot.getTimeTaken());\n                log(\"Checking tree ...\");\n                checkSumsOfCCTNodes(root, \"\", diffPercent, filterout, 0);\n\n                log(\"Checking serialization\");\n                assertTrue(\"The snapshot is not serialized/deserialized right.\", checkSerialization(snapshot));\n\n                log(\"Checking reverse call\");\n\n                if (reverseMethod != null) {\n                    int[] sigs = findThreadAndMethod(root, reverseMethod, filterout);\n\n                    if (sigs != null) {\n                        PrestimeCPUCCTNode revers = snapshot.getReverseCCT(-1, sigs[1], CPUResultsSnapshot.METHOD_LEVEL_VIEW);\n\n                        if (initDelay > 0) {\n                            refOfCCTNodes(revers, \"\", false, false, false);\n                        } else {\n                            refOfCCTNodes(revers, \"\", false, false, true);\n                        }\n                    }\n                }\n\n                log(\"\");\n            }\n\n            setStatus(STATUS_MEASURED);\n        } catch (Exception ex) {\n            log(ex);\n            assertTrue(\"Exception thrown: \" + ex.getMessage(), false);\n        } finally {\n            ProfilingResultsDispatcher.getDefault().pause(true);\n            builder.shutdown();\n            flattener.setContext(null,null,null);\n            builder.removeListener(flattener);\n            builder.removeListener(resultListener);\n            ProfilingResultsDispatcher.getDefault().removeListener(builder);\n            finalizeTest(runner);\n        }\n    }\n\n    static String getNodeName(PrestimeCPUCCTNode node) {\n        String name = node.getNodeName();\n        if (node.isContextCallsNode()) {\n            return \"when called from \"+name;       // NOI18N\n        }\n        return name;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/cpu/CPUTestCase.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * CPUTestCase.java\n *\n * Created on July 19, 2005, 5:20 PM\n */\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.EventBufferResultsProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.ProfilingResultsDispatcher;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCallGraphBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainerFree;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.*;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.*;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport java.text.NumberFormat;\nimport java.util.*;\n\n\n/**\n *\n * @author ehucka\n */\npublic abstract class CPUTestCase extends CommonProfilerTestCase {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    class Measured {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        public int invocations = 0;\n        public long time = 0;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void setInvocations(int invc) {\n            this.invocations = invc;\n        }\n\n        public void setTime(long time) {\n            this.time = time;\n        }\n    }\n\n    private class CPUResultListener implements CPUCCTProvider.Listener {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private final Object resultsLock = new Object();\n        private boolean hasResults = false;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void cctEstablished(RuntimeCCTNode appRootNode) {\n            synchronized (resultsLock) {\n                hasResults = true;\n                resultsLock.notify();\n            }\n        }\n\n        public void cctReset() {\n            synchronized (resultsLock) {\n                hasResults = false;\n                log(\"cctReset \"+System.currentTimeMillis());\n                resultsLock.notify();\n            }\n        }\n\n        public boolean wait4results(long timeout) {\n            synchronized (resultsLock) {\n                if (!hasResults) {\n                    try {\n                        log(\"wait4results \"+System.currentTimeMillis());\n                        resultsLock.wait(timeout);\n                    } catch (InterruptedException e) {\n                    }\n                }\n\n                return hasResults;\n            }\n        }\n\n        public void cctEstablished(RuntimeCCTNode appRootNode, boolean empty) {\n            log(\"cctEstablished \"+empty+\" \"+System.currentTimeMillis());\n            if (!empty) {\n                cctEstablished(appRootNode);\n            }\n            //throw new UnsupportedOperationException(\"Not supported yet.\");\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static int ALL_INV_ERROR_METHOD = 0;\n    static int LAST_INV_ERROR_METHOD = 1;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    NumberFormat percentFormat;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of CPUTestCase\n     */\n    public CPUTestCase(String name) {\n        super(name);\n        percentFormat = NumberFormat.getPercentInstance();\n        percentFormat.setMaximumFractionDigits(1);\n        percentFormat.setMinimumFractionDigits(0);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getALL_INV_ERROR_METHOD() {\n        return ALL_INV_ERROR_METHOD;\n    }\n\n    protected double getError(int invocations, long mctime, long idealtime) {\n        double ideal = idealtime * invocations * 1000.0;\n\n        return Math.abs(ideal - mctime) / 1000;\n    }\n\n    protected double getPercentAtRow(FlatProfileContainer fpc, int row) {\n        double wholeNetTime = fpc.getWholeGraphNetTime0();\n        long tm = fpc.getTimeInMcs0AtRow(row);\n\n        return ((double)tm / wholeNetTime * 100);\n    }\n\n    protected void checkCPUResults(FlatProfileContainer fpc, HashMap methods, String[] measuredMethodsFilter) {\n        double percent = 0.0;\n\n        for (int row = 0; row < fpc.getNRows(); row++) {\n            percent += getPercentAtRow(fpc, row);\n\n            for (String measuredMethodsFilter1 : measuredMethodsFilter) {\n                if (fpc.getMethodNameAtRow(row).startsWith(measuredMethodsFilter1)) {\n                    Measured m = (Measured) (methods.get(fpc.getMethodNameAtRow(row)));\n\n                    if (m == null) {\n                        m = new Measured();\n                        m.time = fpc.getTimeInMcs0AtRow(row);\n                        m.invocations = fpc.getNInvocationsAtRow(row);\n                        methods.put(fpc.getMethodNameAtRow(row), m);\n                    } else {\n                        long tm = m.time;\n                        int inv = m.invocations;\n                        m.setTime(fpc.getTimeInMcs0AtRow(row));\n                        m.setInvocations(fpc.getNInvocationsAtRow(row));\n\n                        if ((tm > m.time) || (inv > m.invocations)) {\n                            log(\"\\n!!!Decreasing values: method \" + fpc.getMethodNameAtRow(row) + \" current time \" + m.time\n                                    + \" invocations \" + m.invocations + \" but was time=\" + tm + \" invocations=\" + inv + \"\\n\");\n                            assertFalse(\"Unacceptable results - decresing values (issue 65187)\", true);\n                        }\n                    }\n                }\n            }\n        }\n\n        if (Math.abs(percent - 100.0) > 0.1) {\n            log(\"\\n!!!Sum of percents is not 100% - \" + percent + \"\\n\");\n\n            for (int row = 0; row < fpc.getNRows(); row++) {\n                log(fpc.getMethodIdAtRow(row) + \" \" + percentFormat.format(fpc.getPercentAtRow(row) / 100) + \" %\");\n            }\n\n            assertFalse(\"Unacceptable results - sum of percents != 100\", true);\n        }\n    }\n\n    protected void checkCPUResults(FlatProfileContainer fpc, String[] methodsNames, long[] idealTimes, double diffMillis,\n                                   String[] refMethods, ArrayList refMethodsList, int errorMethod) {\n        double[] errors = new double[methodsNames.length];\n        int[] nInv = new int[methodsNames.length];\n        long[] times = new long[methodsNames.length];\n\n        for (int row = 0; row < fpc.getNRows(); row++) {\n            for (int mets = 0; mets < methodsNames.length; mets++) {\n                if (fpc.getMethodNameAtRow(row).equals(methodsNames[mets])) {\n                    nInv[mets] = fpc.getNInvocationsAtRow(row);\n                    times[mets] = fpc.getTimeInMcs0AtRow(row);\n                    errors[mets] = getError(nInv[mets], times[mets], idealTimes[mets]);\n                }\n            }\n\n            if (refMethods != null) {\n                for (String refMethod : refMethods) {\n                    String mname = fpc.getMethodNameAtRow(row);\n                    if (mname.startsWith(refMethod) && !refMethodsList.contains(mname)) {\n                        refMethodsList.add(mname);\n                    }\n                }\n            }\n        }\n\n        double best = diffMillis / 4.0;\n        int bestcount = 0;\n        boolean bigdifference = false;\n\n        for (int cntr = 0; cntr < errors.length; cntr++) {\n            if (errors[cntr] <= best) {\n                bestcount++;\n            }\n\n            bigdifference |= (errors[cntr] > diffMillis);\n        }\n\n        boolean accepted = !bigdifference || ((bestcount * 1.0) >= (errors.length * 0.5));\n        logFractions(errors, nInv, times, idealTimes, methodsNames);\n        log(\"\");\n\n        if (!accepted) {\n            log(\"\\nRESULTS WITH BIG DIFFERENCES - differences are greater than given tolerance: \" + diffMillis + \" ms\");\n            log(\"Best count \" + bestcount + \" errors.length \" + errors.length);\n        }\n\n        //assertTrue(\"Not acceptable results - big differences\", accepted);\n    }\n\n    protected ProfilerEngineSettings initCpuTest(String projectName, String mainClass) {\n        return initCpuTest(projectName, mainClass, null);\n    }\n\n    protected ProfilerEngineSettings initCpuTest(String projectName, String mainClass, String[][] rootMethods) {\n        //System.setProperty(\"org.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO\", \"true\");\n        ProfilerEngineSettings settings = initTest(projectName, mainClass, rootMethods);\n        //defaults\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_LAZY);\n        settings.setInstrumentEmptyMethods(false);\n        settings.setInstrumentGetterSetterMethods(false);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentSpawnedThreads(rootMethods == null);\n        settings.setExcludeWaitTime(true);\n\n        //        addJVMArgs(settings, \"-Dorg.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO=true\");\n        //addJVMArgs(settings, \"-Dorg.graalvm.visualvm.lib.jfluid.server.ProfilerServer=true\");\n        //        if (rootMethods == null) {\n        //            addJVMArgs(settings, \"-Dorg.graalvm.visualvm.lib.jfluid.server.ProfilerServer=true\");\n        //        }\n        settings.setThreadCPUTimerOn(false);\n\n        return settings;\n    }\n\n    protected void logFractions(double[] errors, int[] inv, long[] times, long[] ideals, String[] methods) {\n        log(complete(\"Error[ms]\", 10) + complete(\"Invocs\", 10) + complete(\"Time[ms]\", 10) + complete(\"Ideal[ms]\", 10) + \"Method\");\n\n        for (int i = 0; i < errors.length; i++) {\n            log(complete(String.valueOf(errors[i]), 9) + \" \" + complete(String.valueOf(inv[i]), 9) + \" \"\n                + complete(StringUtils.mcsTimeToString(times[i]), 9) + \" \" + complete(String.valueOf(ideals[i] * inv[i]), 9)\n                + \" \" + methods[i]);\n        }\n    }\n\n    protected void logInstrumented(TargetAppRunner runner)\n                            throws Exception {\n        CPUResultsSnapshot snapshot = runner.getProfilerClient().getCPUProfilingResultsSnapshot();\n        String[] mets = snapshot.getInstrMethodNames();\n        log(\"Instrumented methods:\");\n\n        for (String met : mets) {\n            log(met);\n        }\n    }\n\n    /**\n     * checks results after the profiled app is finished\n     */\n    protected void startCPUTest(ProfilerEngineSettings settings, String[] measuredMethods, long[] idealTimes, double diffMillis,\n                                String[] displayMethodsFilter, int errorMethod) {\n        CPUCallGraphBuilder builder = new CPUCallGraphBuilder();\n\n        //create runner\n        TargetAppRunner runner = new TargetAppRunner(settings, new TestProfilerAppHandler(this),\n                                                     new TestProfilingPointsProcessor());\n        runner.addProfilingEventListener(Utils.createProfilingListener(this));\n\n        ProfilingResultsDispatcher.getDefault().addListener(builder);\n\n        CPUResultListener resultListener = new CPUResultListener();\n        builder.addListener(resultListener);\n\n        FlatProfileBuilder flattener = new FlatProfileBuilder();\n        builder.addListener(flattener);\n        flattener.setContext(runner.getProfilerClient(),null,null);\n\n        builder.startup(runner.getProfilerClient());\n\n        try {\n            runner.readSavedCalibrationData();\n            runner.getProfilerClient().initiateRecursiveCPUProfInstrumentation(settings.getInstrumentationRootMethods());\n\n            Process p = startTargetVM(runner);\n            assertNotNull(\"Target JVM is not started\", p);\n            bindStreams(p);\n            runner.attachToTargetVMOnStartup();\n\n            waitForStatus(STATUS_RUNNING);\n            assertTrue(\"runner is not running\", runner.targetAppIsRunning());\n\n            ArrayList methods = new ArrayList();\n\n            waitForStatus(STATUS_APP_FINISHED);\n\n            Thread.sleep(1000);\n\n            if (runner.targetJVMIsAlive()) {\n                log(\"Get results: \" + System.currentTimeMillis());\n                assertTrue(\"Results do not exist - issue 65185.\", runner.getProfilerClient().cpuResultsExist());\n\n                boolean gotResults = false;\n                int retryCounter = 8; // was - 4\n\n                do {\n                    // just wait for the results to appear - forceObtainedResultsDump() has been alread called by ProfilerClient on shutdown\n                    //                    runner.getProfilerClient().forceObtainedResultsDump();\n                    gotResults = resultListener.wait4results(2500);\n                } while (!gotResults && (--retryCounter > 0));\n\n                assertTrue(\"Results are not available after 20 seconds.\", gotResults); // was - 10 seconds\n                log(\"obtaining results \" + String.valueOf(System.currentTimeMillis()));\n\n                //logInstrumented(runner);\n                FlatProfileContainerFree fpc = null;\n                int retry = 5;\n\n                while ((fpc == null) && (--retry > 0)) {\n                    fpc = (FlatProfileContainerFree) flattener.createFlatProfile();\n                    Thread.sleep(500);\n                }\n\n                fpc.filterOriginalData(new String[] { \"\" }, CommonConstants.FILTER_CONTAINS, 0.0D);\n                checkCPUResults(fpc, measuredMethods, idealTimes, diffMillis, displayMethodsFilter, methods, errorMethod);\n            }\n\n            setStatus(STATUS_MEASURED);\n\n            if (!methods.isEmpty()) {\n                Collections.sort(methods);\n\n                for (int mets = 0; mets < methods.size(); mets++) {\n                    ref(methods.get(mets));\n                }\n            }\n        } catch (Exception ex) {\n            log(ex);\n            assertTrue(\"Exception thrown: \" + ex.getMessage(), false);\n        } finally {\n            ProfilingResultsDispatcher.getDefault().pause(true);\n            builder.shutdown();\n            flattener.setContext(null,null,null);\n            builder.removeListener(flattener);\n            builder.removeListener(resultListener);\n            ProfilingResultsDispatcher.getDefault().removeListener(builder);\n            finalizeTest(runner);\n        }\n    }\n\n    /**\n     * check reulsts periodicaly - live results\n     */\n    protected void startCPUTest(ProfilerEngineSettings settings, String[] measuredMethodsFilter, long checkDelay, long maxDelay) {\n        CPUCallGraphBuilder builder = new CPUCallGraphBuilder();\n\n        //create runner\n        TargetAppRunner runner = new TargetAppRunner(settings, new TestProfilerAppHandler(this),\n                                                     new TestProfilingPointsProcessor());\n        runner.addProfilingEventListener(Utils.createProfilingListener(this));\n\n        ProfilingResultsDispatcher.getDefault().addListener(builder);\n\n        CPUResultListener resultListener = new CPUResultListener();\n        builder.addListener(resultListener);\n\n        FlatProfileBuilder flattener = new FlatProfileBuilder();\n        builder.addListener(flattener);\n        flattener.setContext(runner.getProfilerClient(),null,null);\n\n        builder.startup(runner.getProfilerClient());\n\n        try {\n            runner.readSavedCalibrationData();\n\n            runner.getProfilerClient().initiateRecursiveCPUProfInstrumentation(settings.getInstrumentationRootMethods());\n            Process p = startTargetVM(runner);\n            assertNotNull(\"Target JVM is not started\", p);\n            bindStreams(p);\n\n            runner.attachToTargetVMOnStartup();\n\n            waitForStatus(STATUS_RUNNING);\n            assertTrue(\"runner is not running\", runner.targetAppIsRunning());\n            waitForStatus(STATUS_RESULTS_AVAILABLE | STATUS_APP_FINISHED);\n            assertTrue(\"ResultsAvailable was not called - issue 69084\", (isStatus(STATUS_RESULTS_AVAILABLE) || isStatus(STATUS_LIVERESULTS_AVAILABLE)));\n\n            HashMap methods = new HashMap(128);\n            long alltime = 0;\n            long time = System.currentTimeMillis();\n            long oldtime = time - checkDelay;\n\n            while (!isStatus(STATUS_APP_FINISHED) && !isStatus(STATUS_ERROR) && (alltime < maxDelay)) {\n                if ((time - oldtime) < (2 * checkDelay)) {\n                    Thread.sleep((2 * checkDelay) - (time - oldtime));\n                }\n\n                if (!isStatus(STATUS_LIVERESULTS_AVAILABLE)) {\n                    waitForStatus(STATUS_LIVERESULTS_AVAILABLE, checkDelay / 2);\n                }\n\n                if (runner.targetJVMIsAlive() && isStatus(STATUS_LIVERESULTS_AVAILABLE)) {\n                    assertTrue(\"Results do not exist - issue 65185.\", runner.getProfilerClient().cpuResultsExist());\n                    log(\"Get Results: \" + System.currentTimeMillis());\n\n                    //                    runner.getProfilerClient().forceObtainedResultsDump();\n                    //                    assertTrue(\"Results do not exist on the server - issue 65185.\", runner.getProfilerClient().cpuResultsExist());\n                    boolean gotResults = false;\n                    int retryCounter = 4;\n\n                    do {\n                        runner.getProfilerClient().forceObtainedResultsDump();\n                        gotResults = resultListener.wait4results(2500);\n                    } while (!gotResults && (--retryCounter > 0));\n\n                    assertTrue(\"CallGraphBuilder: Results do not exist.\", gotResults);\n                    log(\"Results obtained \" + String.valueOf(System.currentTimeMillis()));\n\n                    //logInstrumented(runner);\n                    FlatProfileContainerFree fpc = null;\n                    int retry = 5;\n\n                    while ((fpc == null) && (--retry > 0)) {\n                        fpc = (FlatProfileContainerFree) flattener.createFlatProfile();\n                        Thread.sleep(500);\n                    }\n\n                    fpc.filterOriginalData(new String[] { \"\" }, CommonConstants.FILTER_CONTAINS, 0.0D);\n                    fpc.sortBy(FlatProfileContainer.SORT_BY_TIME, true);\n                    checkCPUResults(fpc, methods, measuredMethodsFilter);\n                }\n\n                alltime += (System.currentTimeMillis() - time);\n                oldtime = time;\n                time = System.currentTimeMillis();\n            }\n\n            if (methods.isEmpty()) {\n                assertTrue(\"Results were not on the server - issue 65185\", false);\n            }\n        } catch (Exception ex) {\n            log(ex);\n            assertTrue(\"Exception thrown: \" + ex.getMessage(), false);\n        } finally {\n            ProfilingResultsDispatcher.getDefault().pause(true);\n            builder.shutdown();\n            flattener.setContext(null,null,null);\n            builder.removeListener(flattener);\n            builder.removeListener(resultListener);\n            ProfilingResultsDispatcher.getDefault().removeListener(builder);\n            finalizeTest(runner);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/BasicTest.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.memory;\n\nimport junit.framework.Test;\nimport junit.textui.TestRunner;\nimport org.netbeans.junit.NbModuleSuite;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n\n/**\n *\n * @author ehucka\n */\npublic class BasicTest extends MemoryTestCase {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of BasicTest */\n    public BasicTest(String name) {\n        super(name);\n    }\n\n    public static void main(String[] args) {\n        TestRunner.run(suite());\n    }\n\n    public static Test suite() {\n        return NbModuleSuite.create(\n            NbModuleSuite.createConfiguration(BasicTest.class).addTest(\n            \"testSettingsAllocations\",\n            \"testSettingsAllocationsServer\",\n            \"testSettingsAllocationsStackTraces\",\n            \"testSettingsAllocationsStackTracesServer\",\n            \"testSettingsDefault\",\n            \"testSettingsLiveness\",\n            \"testSettingsLivenessServer\",\n            \"testSettingsLivenessStackTraces\",\n            \"testSettingsLivenessStackTracesServer\")\n            .honorAutoloadEager(true).enableModules(\".*\").clusters(\".*\").gui(false));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void testSettingsAllocations() {\n        ProfilerEngineSettings settings = initMemoryTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(0);\n        startMemoryTest(settings, CommonConstants.INSTR_OBJECT_ALLOCATIONS, new String[] { \"simple\" });\n    }\n\n    public void testSettingsAllocationsServer() {\n        ProfilerEngineSettings settings = initMemoryTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        addJVMArgs(settings, \"-server\");\n        settings.setAllocStackTraceLimit(0);\n        startMemoryTest(settings, CommonConstants.INSTR_OBJECT_ALLOCATIONS, new String[] { \"simple\" });\n    }\n\n    public void testSettingsAllocationsStackTraces() {\n        ProfilerEngineSettings settings = initMemoryTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(-1);\n        startMemoryTest(settings, CommonConstants.INSTR_OBJECT_ALLOCATIONS, new String[] { \"simple\" });\n    }\n\n    public void testSettingsAllocationsStackTracesServer() {\n        ProfilerEngineSettings settings = initMemoryTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(-1);\n        addJVMArgs(settings, \"-server\");\n        startMemoryTest(settings, CommonConstants.INSTR_OBJECT_ALLOCATIONS, new String[] { \"simple\" });\n    }\n\n    public void testSettingsDefault() {\n        ProfilerEngineSettings settings = initMemoryTest(\"j2se-simple\", \"simple.Memory\");\n        startMemoryTest(settings, CommonConstants.INSTR_OBJECT_ALLOCATIONS, new String[] { \"simple\" });\n    }\n\n    public void testSettingsLiveness() {\n        ProfilerEngineSettings settings = initMemoryTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(0);\n        startMemoryTest(settings, CommonConstants.INSTR_OBJECT_LIVENESS, new String[] { \"simple\" });\n    }\n\n    public void testSettingsLivenessServer() {\n        ProfilerEngineSettings settings = initMemoryTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(0);\n        addJVMArgs(settings, \"-server\");\n        startMemoryTest(settings, CommonConstants.INSTR_OBJECT_LIVENESS, new String[] { \"simple\" });\n    }\n\n    public void testSettingsLivenessStackTraces() {\n        ProfilerEngineSettings settings = initMemoryTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(-1);\n        startMemoryTest(settings, CommonConstants.INSTR_OBJECT_LIVENESS, new String[] { \"simple\" });\n    }\n\n    public void testSettingsLivenessStackTracesServer() {\n        ProfilerEngineSettings settings = initMemoryTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(-1);\n        addJVMArgs(settings, \"-server\");\n        startMemoryTest(settings, CommonConstants.INSTR_OBJECT_LIVENESS, new String[] { \"simple\" });\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/MemorySnapshotTest.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.memory;\n\nimport junit.framework.Test;\nimport junit.textui.TestRunner;\nimport org.netbeans.junit.NbModuleSuite;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n\n/**\n *\n * @author ehucka\n */\npublic class MemorySnapshotTest extends MemorySnapshotTestCase {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of BasicTest */\n    public MemorySnapshotTest(String name) {\n        super(name);\n    }\n    public static void main(String[] args) {\n        TestRunner.run(suite());\n    }\n\n    public static Test suite() {\n        return NbModuleSuite.create(\n            NbModuleSuite.createConfiguration(MemorySnapshotTest.class).addTest(\n            \"testSettingsAllocations\",\n            \"testSettingsAllocationsServer\",\n            \"testSettingsAllocationsStackTraces\",\n            \"testSettingsAllocationsStackTracesServer\",\n            \"testSettingsLiveness\",\n            \"testSettingsLivenessServer\",\n            \"testSettingsLivenessStackTraces\",\n            \"testSettingsLivenessStackTracesServer\")\n            .honorAutoloadEager(true).enableModules(\".*\").clusters(\".*\").gui(false));\n    }\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void testSettingsAllocations() {\n        ProfilerEngineSettings settings = initMemorySnapshotTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(0);\n        startMemorySnapshotTest(settings, CommonConstants.INSTR_OBJECT_ALLOCATIONS, new String[] { \"simple\" },\n                                \"simple.memory.Bean\");\n    }\n\n    public void testSettingsAllocationsServer() {\n        ProfilerEngineSettings settings = initMemorySnapshotTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        addJVMArgs(settings, \"-server\");\n        settings.setAllocStackTraceLimit(0);\n        startMemorySnapshotTest(settings, CommonConstants.INSTR_OBJECT_ALLOCATIONS, new String[] { \"simple\" },\n                                \"simple.memory.Bean\");\n    }\n\n    public void testSettingsAllocationsStackTraces() {\n        ProfilerEngineSettings settings = initMemorySnapshotTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(-1);\n        startMemorySnapshotTest(settings, CommonConstants.INSTR_OBJECT_ALLOCATIONS, new String[] { \"simple\" },\n                                \"simple.memory.Bean\");\n    }\n\n    public void testSettingsAllocationsStackTracesServer() {\n        ProfilerEngineSettings settings = initMemorySnapshotTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(-1);\n        addJVMArgs(settings, \"-server\");\n        startMemorySnapshotTest(settings, CommonConstants.INSTR_OBJECT_ALLOCATIONS, new String[] { \"simple\" },\n                                \"simple.memory.Bean\");\n    }\n\n    public void testSettingsLiveness() {\n        ProfilerEngineSettings settings = initMemorySnapshotTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(0);\n        startMemorySnapshotTest(settings, CommonConstants.INSTR_OBJECT_LIVENESS, new String[] { \"simple\" }, \"simple.memory.Bean\");\n    }\n\n    public void testSettingsLivenessServer() {\n        ProfilerEngineSettings settings = initMemorySnapshotTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(0);\n        addJVMArgs(settings, \"-server\");\n        startMemorySnapshotTest(settings, CommonConstants.INSTR_OBJECT_LIVENESS, new String[] { \"simple\" }, \"simple.memory.Bean\");\n    }\n\n    public void testSettingsLivenessStackTraces() {\n        ProfilerEngineSettings settings = initMemorySnapshotTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(-1);\n        startMemorySnapshotTest(settings, CommonConstants.INSTR_OBJECT_LIVENESS, new String[] { \"simple\" }, \"simple.memory.Bean\");\n    }\n\n    public void testSettingsLivenessStackTracesServer() {\n        ProfilerEngineSettings settings = initMemorySnapshotTest(\"j2se-simple\", \"simple.memory.Memory1\");\n        settings.setAllocStackTraceLimit(-1);\n        addJVMArgs(settings, \"-server\");\n        startMemorySnapshotTest(settings, CommonConstants.INSTR_OBJECT_LIVENESS, new String[] { \"simple\" }, \"simple.memory.Bean\");\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/MemorySnapshotTestCase.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * MemoryTestCase.java\n *\n * Created on July 19, 2005, 5:21 PM\n */\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.memory;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.EventBufferResultsProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.ProfilingResultsDispatcher;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.AllocMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.LivenessMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCCTManager;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCallGraphBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.RuntimeMemoryCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.*;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.*;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.lang.reflect.Field;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Date;\n\n\n/**\n *\n * @author ehucka\n */\npublic abstract class MemorySnapshotTestCase extends CommonProfilerTestCase {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private static class MemoryResultListener implements MemoryCCTProvider.Listener {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private final Object resultsLock = new Object();\n        private boolean hasResults = false;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void cctEstablished(RuntimeCCTNode appRootNode) {\n            System.out.println(\"Memory CCT Established\");\n\n            synchronized (resultsLock) {\n                hasResults = true;\n                resultsLock.notify();\n            }\n        }\n\n        public void cctReset() {\n            synchronized (resultsLock) {\n                hasResults = false;\n                resultsLock.notify();\n            }\n        }\n\n        public boolean wait4results(long timeout) {\n            synchronized (resultsLock) {\n                if (!hasResults) {\n                    try {\n                        resultsLock.wait(timeout);\n                    } catch (InterruptedException e) {\n                    }\n                }\n\n                return hasResults;\n            }\n        }\n\n        public void cctEstablished(RuntimeCCTNode appRootNode, boolean empty) {\n            if (!empty) {\n                cctEstablished(appRootNode);\n            }\n            //throw new UnsupportedOperationException(\"Not supported yet.\");\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    MemoryCallGraphBuilder builder = new MemoryCallGraphBuilder();\n    MemoryResultListener resultListener = null;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of MemoryTestCase\n     */\n    public MemorySnapshotTestCase(String name) {\n        super(name);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    protected void checkClasses(MemoryResultsSnapshot snapshot, String[] prefixes) {\n        ArrayList list = new ArrayList(128);\n\n        if (snapshot instanceof AllocMemoryResultsSnapshot) {\n            AllocMemoryResultsSnapshot alsnapshot = (AllocMemoryResultsSnapshot) snapshot;\n\n            int[] objcnts = alsnapshot.getObjectsCounts();\n            long[] objsizes = alsnapshot.getObjectsSizePerClass();\n            String[] classnames = alsnapshot.getClassNames();\n\n            for (int i = 0; i < snapshot.getNProfiledClasses(); i++) {\n                boolean match = false;\n\n                for (String prefixe : prefixes) {\n                    if (classnames[i].startsWith(prefixe)) {\n                        match = true;\n\n                        break;\n                    }\n                }\n\n                if (match) {\n                    StringBuilder out = new StringBuilder();\n                    out.append(complete(StringUtils.userFormClassName(classnames[i]), 32));\n                    //out.append(complete(StringUtils.nBytesToString(objsizes[i]), 10));\n                    out.append(complete(String.valueOf(objcnts[i]), 8));\n                    list.add(out.toString());\n                }\n            }\n\n            ref(complete(\"Name\", 32) /*complete(\"Bytes\", 10)+*/ + complete(\"Objects\", 8));\n        } else if (snapshot instanceof LivenessMemoryResultsSnapshot) {\n            LivenessMemoryResultsSnapshot lsnapshot = (LivenessMemoryResultsSnapshot) snapshot;\n\n            log(\"Max Value:        \" + lsnapshot.getMaxValue());\n            log(\"Number Alloc:     \" + lsnapshot.getNAlloc());\n            log(\"Instr Classes:    \" + lsnapshot.getNInstrClasses());\n            log(\"Total tracked:    \" + lsnapshot.getNTotalTracked());\n            log(\"Tracked bytes:    \" + lsnapshot.getNTotalTrackedBytes());\n            log(\"Tracked items:    \" + lsnapshot.getNTrackedItems());\n\n            float[] avgage = lsnapshot.getAvgObjectAge();\n            int[] maxSurvGen = lsnapshot.getMaxSurvGen();\n            long[] ntrackedallocobjects = lsnapshot.getNTrackedAllocObjects();\n            int[] ntrackedliveobjects = lsnapshot.getNTrackedLiveObjects();\n            int[] totalAllocObjects = lsnapshot.getnTotalAllocObjects();\n            String[] classnames = lsnapshot.getClassNames();\n            long[] trackedLiveObjectsSize = lsnapshot.getTrackedLiveObjectsSize();\n\n            for (int i = 0; i < snapshot.getNProfiledClasses(); i++) {\n                boolean match = false;\n\n                for (String prefixe : prefixes) {\n                    if (classnames[i].startsWith(prefixe)) {\n                        match = true;\n\n                        break;\n                    }\n                }\n\n                if (match) {\n                    StringBuilder out = new StringBuilder();\n                    out.append(complete(StringUtils.userFormClassName(classnames[i]), 32));\n                    //out.append(complete(StringUtils.nBytesToString(trackedLiveObjectsSize[i]), 10));\n                    out.append(complete(String.valueOf(ntrackedliveobjects[i]), 10));\n                    out.append(complete(String.valueOf(ntrackedallocobjects[i]), 8));\n                    //out.append(complete(String.valueOf((int)avgage[i]), 8));\n                    //out.append(complete(String.valueOf(maxSurvGen[i]), 8));\n                    out.append(complete(String.valueOf(totalAllocObjects[i]), 8));\n                    list.add(out.toString());\n                }\n            }\n\n            ref(complete(\"Name\", 32) /*complete(\"LiveBytes\", 10)+*/ + complete(\"LiveObjs\", 10)\n                + complete(\"Allocs\", 8) /*+complete(\"AvgAge\", 8)+complete(\"MaxSurv\", 8)*/ + complete(\"Total\", 8));\n        }\n\n        //log results\n        Collections.sort(list);\n\n        for (int i = 0; i < list.size(); i++) {\n            ref(list.get(i));\n        }\n\n        ref(\"\");\n    }\n\n    protected void checkMemoryResults(TargetAppRunner targetAppRunner, String[] classPrefixes, String stacktraceClass)\n                               throws Exception {\n        targetAppRunner.getProfilerClient().forceObtainedResultsDump();\n\n        boolean gotResults = resultListener.wait4results(10000);\n\n        assertTrue(\"No memory results available after 10s\", gotResults);\n        log(\"results obtained: \" + System.currentTimeMillis());\n\n        MemoryResultsSnapshot snapshot = targetAppRunner.getProfilerClient().getMemoryProfilingResultsSnapshot(false);\n        assertTrue(snapshot != null);\n        log(\"snapshot taken: \" + snapshot);\n\n        ref((snapshot.containsStacks()) ? \"Contains stacks.\" : \"Does not contain stacks.\");\n        log(\"Begin time:       \" + new Date(snapshot.getBeginTime()));\n        log(\"Profiled classes: \" + snapshot.getNProfiledClasses());\n        log(\"Time Taken:       \" + new Date(snapshot.getTimeTaken()));\n        checkClasses(snapshot, classPrefixes);\n\n        //stacktrace\n        if (snapshot.containsStacks()) {\n            int classid = -1;\n            String[] classes = snapshot.getClassNames();\n\n            for (int i = 0; i < snapshot.getNProfiledClasses(); i++) {\n                if (classes[i].replace('/', '.').equals(stacktraceClass)) {\n                    classid = i;\n                }\n            }\n\n            assertTrue(\"Stack trace class wasn't find \" + stacktraceClass, (classid > -1));\n\n            MemoryCCTManager manager = new MemoryCCTManager(snapshot, classid, false);\n\n            if (!manager.isEmpty()) {\n                PresoObjAllocCCTNode root = manager.getRootNode();\n                refNodes(root, \"\");\n            }\n        }\n\n        testSerialization(snapshot);\n    }\n\n    protected boolean equals(String[] a1, String[] a2, int length) {\n        for (int i = 0; i < length; i++) {\n            if (!a1[i].equals(a2[i])) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    protected boolean equals(int[] a1, int[] a2, int length) {\n        for (int i = 0; i < length; i++) {\n            if (a1[i] != a2[i]) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    protected boolean equals(long[] a1, long[] a2, int length) {\n        for (int i = 0; i < length; i++) {\n            if (a1[i] != a2[i]) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    protected boolean equals(float[] a1, float[] a2, int length) {\n        for (int i = 0; i < length; i++) {\n            if (a1[i] != a2[i]) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    protected boolean equals(RuntimeMemoryCCTNode a1, RuntimeMemoryCCTNode a2)\n                      throws Exception {\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        DataOutputStream dos = new DataOutputStream(baos);\n        a1.writeToStream(dos);\n        dos.close();\n\n        byte[] bytes = baos.toByteArray();\n        //write to bytes 2\n        baos = new ByteArrayOutputStream();\n        dos = new DataOutputStream(baos);\n        a2.writeToStream(dos);\n        dos.close();\n\n        byte[] bytes2 = baos.toByteArray();\n\n        if (bytes.length != bytes2.length) {\n            return false;\n        }\n\n        for (int i = 0; i < bytes.length; i++) {\n            if (bytes[i] != bytes2[i]) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    protected ProfilerEngineSettings initMemorySnapshotTest(String projectName, String className) {\n        ProfilerEngineSettings settings = initTest(projectName, className, null);\n        //defaults\n        settings.setThreadCPUTimerOn(false);\n        settings.setAllocTrackEvery(1); //default is not strict - cannot be measured in test\n        settings.setRunGCOnGetResultsInMemoryProfiling(true);\n\n        return settings;\n    }\n\n    protected void refNodes(PresoObjAllocCCTNode root, String tab) {\n        ref(tab + (PresoObjAllocCCTNode) root);\n\n        if (root.getNChildren() > 0) {\n            root.sortChildren(PresoObjAllocCCTNode.SORT_BY_NAME, false);\n\n            CCTNode[] nodes = root.getChildren();\n\n            for (CCTNode node : nodes) {\n                refNodes((PresoObjAllocCCTNode) node, tab + \" \");\n            }\n        }\n    }\n\n    protected void startMemorySnapshotTest(ProfilerEngineSettings settings, int instrMode, String[] classPrefixes,\n                                           String stacktraceClass) {\n        //create runner //instrMode CommonConstants.INSTR_OBJECT_ALLOCATIONS\n        assertTrue(builder != null);\n\n        TestProfilerAppHandler handler = new TestProfilerAppHandler(this);\n        TargetAppRunner runner = new TargetAppRunner(settings, handler, new TestProfilingPointsProcessor());\n        runner.addProfilingEventListener(Utils.createProfilingListener(this));\n\n        builder.removeAllListeners();\n        ProfilingResultsDispatcher.getDefault().removeAllListeners();\n\n        resultListener = new MemoryResultListener();\n        builder.addListener(resultListener);\n\n        ProfilingResultsDispatcher.getDefault().addListener(builder);\n        builder.startup(runner.getProfilerClient());\n\n        try {\n            assertTrue(\"not read calibration data\", runner.readSavedCalibrationData());\n            runner.getProfilerClient().initiateMemoryProfInstrumentation(instrMode);\n\n            Process p = startTargetVM(runner);\n            assertNotNull(\"Target JVM is not started\", p);\n            bindStreams(p);\n            runner.attachToTargetVMOnStartup();\n            \n            waitForStatus(STATUS_RUNNING);\n            assertTrue(\"runner is not running\", runner.targetAppIsRunning());\n\n            waitForStatus(STATUS_RESULTS_AVAILABLE | STATUS_APP_FINISHED);\n\n            if (!isStatus(STATUS_APP_FINISHED)) {\n                waitForStatus(STATUS_APP_FINISHED);\n            }\n            Thread.sleep(1000);\n            checkMemoryResults(runner, classPrefixes, stacktraceClass);\n            setStatus(STATUS_MEASURED);\n        } catch (Exception ex) {\n            log(ex);\n            assertTrue(\"Exception thrown: \" + ex.getMessage(), false);\n        } finally {\n            ProfilingResultsDispatcher.getDefault().pause(true);\n            builder.shutdown();\n\n            builder.removeListener(resultListener);\n            ProfilingResultsDispatcher.getDefault().removeListener(builder);\n\n            finalizeTest(runner);\n        }\n    }\n\n    protected void testSerialization(MemoryResultsSnapshot snapshot) {\n        try {\n            //write to bytes\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            DataOutputStream dos = new DataOutputStream(baos);\n            snapshot.writeToStream(dos);\n            dos.close();\n\n            byte[] bytes = baos.toByteArray();\n            MemoryResultsSnapshot snapshot2;\n\n            if (snapshot instanceof LivenessMemoryResultsSnapshot) {\n                snapshot2 = new LivenessMemoryResultsSnapshot();\n            } else {\n                snapshot2 = new AllocMemoryResultsSnapshot();\n            }\n\n            //read from bytes\n            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);\n            DataInputStream dis = new DataInputStream(bis);\n            snapshot2.readFromStream(dis);\n            dis.close();\n\n            //compare\n            if (snapshot instanceof LivenessMemoryResultsSnapshot) {\n                LivenessMemoryResultsSnapshot s1;\n                LivenessMemoryResultsSnapshot s2;\n                s1 = (LivenessMemoryResultsSnapshot) snapshot;\n                s2 = (LivenessMemoryResultsSnapshot) snapshot2;\n                assertEquals(\"Snapshot Serialization: diff containsStacks\", s1.containsStacks(), s2.containsStacks());\n                assertEquals(\"Snapshot Serialization: diff beginTime\", s1.getBeginTime(), s2.getBeginTime());\n                assertEquals(\"Snapshot Serialization: diff MaxValue\", s1.getMaxValue(), s2.getMaxValue());\n                assertEquals(\"Snapshot Serialization: diff NAlloc\", s1.getNAlloc(), s2.getNAlloc());\n                assertEquals(\"Snapshot Serialization: diff NInstrClasses\", s1.getNInstrClasses(), s2.getNInstrClasses());\n                assertEquals(\"Snapshot Serialization: diff NProfiledClasses\", s1.getNProfiledClasses(), s2.getNProfiledClasses());\n                assertEquals(\"Snapshot Serialization: diff NTotalTracked\", s1.getNTotalTracked(), s2.getNTotalTracked());\n                assertEquals(\"Snapshot Serialization: diff NTotalTrackedBytes\", s1.getNTotalTrackedBytes(),\n                             s2.getNTotalTrackedBytes());\n                assertEquals(\"Snapshot Serialization: diff NTrackedItems\", s1.getNTrackedItems(), s2.getNTrackedItems());\n                assertEquals(\"Snapshot Serialization: diff TimeTaken\", s1.getTimeTaken(), s2.getTimeTaken());\n\n                assertTrue(\"Snapshot Serialization: diff AvgObjectAge\",\n                           equals(s1.getAvgObjectAge(), s2.getAvgObjectAge(), s1.getNProfiledClasses()));\n                assertTrue(\"Snapshot Serialization: diff ClassNames\",\n                           equals(s1.getClassNames(), s2.getClassNames(), s1.getNProfiledClasses()));\n                assertTrue(\"Snapshot Serialization: diff MaxSurvGen\",\n                           equals(s1.getMaxSurvGen(), s2.getMaxSurvGen(), s1.getNProfiledClasses()));\n                assertTrue(\"Snapshot Serialization: diff NTrackedAllocObjects\",\n                           equals(s1.getNTrackedAllocObjects(), s2.getNTrackedAllocObjects(), s1.getNProfiledClasses()));\n                assertTrue(\"Snapshot Serialization: diff NTrackedLiveObjects\",\n                           equals(s1.getNTrackedLiveObjects(), s2.getNTrackedLiveObjects(), s1.getNProfiledClasses()));\n                assertTrue(\"Snapshot Serialization: diff ObjectsSizePerClass\",\n                           equals(s1.getObjectsSizePerClass(), s2.getObjectsSizePerClass(), s1.getNProfiledClasses()));\n                assertTrue(\"Snapshot Serialization: diff TrackedLiveObjectsSize\",\n                           equals(s1.getTrackedLiveObjectsSize(), s2.getTrackedLiveObjectsSize(), s1.getNProfiledClasses()));\n                assertTrue(\"Snapshot Serialization: diff nTotalAllocObjects\",\n                           equals(s1.getnTotalAllocObjects(), s2.getnTotalAllocObjects(), s1.getNProfiledClasses()));\n            } else {\n                AllocMemoryResultsSnapshot s1;\n                AllocMemoryResultsSnapshot s2;\n                s1 = (AllocMemoryResultsSnapshot) snapshot;\n                s2 = (AllocMemoryResultsSnapshot) snapshot2;\n                assertEquals(\"Snapshot Serialization: diff containsStacks\", s1.containsStacks(), s2.containsStacks());\n                assertEquals(\"Snapshot Serialization: diff beginTime\", s1.getBeginTime(), s2.getBeginTime());\n                assertEquals(\"Snapshot Serialization: diff NProfiledClasses\", s1.getNProfiledClasses(), s2.getNProfiledClasses());\n                assertEquals(\"Snapshot Serialization: diff TimeTaken\", s1.getTimeTaken(), s2.getTimeTaken());\n\n                assertTrue(\"Snapshot Serialization: diff ClassNames\",\n                           equals(s1.getClassNames(), s2.getClassNames(), s1.getNProfiledClasses()));\n                assertTrue(\"Snapshot Serialization: diff ObjectsSizePerClass\",\n                           equals(s1.getObjectsSizePerClass(), s2.getObjectsSizePerClass(), s1.getNProfiledClasses()));\n            }\n\n            if (snapshot.containsStacks()) {\n                Field field = snapshot.getClass().getSuperclass().getDeclaredField(\"stacksForClasses\");\n                field.setAccessible(true);\n\n                RuntimeMemoryCCTNode[] stacksForClasses = (RuntimeMemoryCCTNode[]) field.get(snapshot);\n                RuntimeMemoryCCTNode[] stacksForClasses2 = (RuntimeMemoryCCTNode[]) field.get(snapshot2);\n\n                for (int i = 0; i < stacksForClasses.length; i++) {\n                    if (stacksForClasses[i] != null) {\n                        assertTrue(\"Snapshot Serialization: diff stacktraces \" + snapshot.getClassName(i),\n                                   equals(stacksForClasses[i], stacksForClasses2[i]));\n                    }\n                }\n            }\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            assertTrue(\"Snapshot Serialization: \" + ex.getClass().getName() + \": \" + ex.getMessage(), false);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/memory/MemoryTestCase.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * MemoryTestCase.java\n *\n * Created on July 19, 2005, 5:21 PM\n */\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.memory;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.results.EventBufferResultsProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.ProfilingResultsDispatcher;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCallGraphBuilder;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.*;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.*;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n/**\n *\n * @author ehucka\n */\npublic abstract class MemoryTestCase extends CommonProfilerTestCase {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private static class MemoryResultListener implements MemoryCCTProvider.Listener {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private final Object resultsLock = new Object();\n        private boolean hasResults = false;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n        public void cctEstablished(RuntimeCCTNode appRootNode) {\n            System.out.println(\"Memory CCT Established\");\n\n            synchronized (resultsLock) {\n                hasResults = true;\n                resultsLock.notify();\n            }\n        }\n\n        public void cctReset() {\n            synchronized (resultsLock) {\n                hasResults = false;\n                resultsLock.notify();\n            }\n        }\n\n        public boolean wait4results(long timeout) {\n            synchronized (resultsLock) {\n                if (!hasResults) {\n                    try {\n                        resultsLock.wait(timeout);\n                    } catch (InterruptedException e) {\n                    }\n                }\n\n                return hasResults;\n            }\n        }\n\n        public void cctEstablished(RuntimeCCTNode appRootNode, boolean empty) {\n            if (!empty) {\n                cctEstablished(appRootNode);\n            }\n        //throw new UnsupportedOperationException(\"Not supported yet.\");\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n    MemoryCallGraphBuilder builder = new MemoryCallGraphBuilder();\n    MemoryResultListener resultListener = null;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n    /**\n     * Creates a new instance of MemoryTestCase\n     */\n    public MemoryTestCase(String name) {\n        super(name);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    protected void checkMemoryResults(TargetAppRunner targetAppRunner, String[] matchingPrefixes,\n            MemoryResultListener resultListener, int instrMode)\n            throws Exception {\n        boolean gotResults = false;\n        int retryCounter = 4;\n\n        do {\n            targetAppRunner.getProfilerClient().forceObtainedResultsDump();\n            gotResults = resultListener.wait4results(2500);\n        } while (!gotResults && (--retryCounter > 0));\n\n        assertTrue(\"CallGraphBuilder: Results do not exist.\", gotResults);\n        log(\"results obtained: \" + System.currentTimeMillis());\n\n        int[] totalAllocObjects = targetAppRunner.getProfilerClient().getAllocatedObjectsCountResults();\n        String[] classnames = targetAppRunner.getProfilerClient().getStatus().getClassNames();\n        long[] totalAllocObjectsSize = null;\n        ArrayList list = new ArrayList(128);\n        totalAllocObjectsSize = builder.getAllocObjectNumbers();\n        \n        if (instrMode == CommonConstants.INSTR_OBJECT_ALLOCATIONS) {\n            for (int i = 0; i < totalAllocObjectsSize.length; i++) {\n                boolean match = false;\n\n                for (String matchingPrefixe : matchingPrefixes) {\n                    if (classnames[i].startsWith(matchingPrefixe)) {\n                        match = true;\n\n                        break;\n                    }\n                }\n\n                if (match) {\n                    StringBuilder out = new StringBuilder();\n                    out.append(complete(StringUtils.userFormClassName(classnames[i]), 32));\n                    out.append(complete(String.valueOf(totalAllocObjects[i]), 8));\n                    //out.append(complete(StringUtils.nBytesToString(totalAllocObjectsSize[i]), 10));\n                    list.add(out.toString());\n                }\n            }\n\n            ref(complete(\"Name\", 32) + complete(\"DCount\", 8)); //+complete(\"DSize\", 10));\n        }\n\n        if (instrMode == CommonConstants.INSTR_OBJECT_LIVENESS) {\n            try {\n                MemoryCCTProvider.ObjectNumbersContainer liveness = builder.getLivenessObjectNumbers();\n\n                totalAllocObjectsSize = liveness.trackedLiveObjectsSize;\n\n                float[] avgage = liveness.avgObjectAge;\n                int[] maxSurvGen = liveness.maxSurvGen;\n                long[] ntrackedallocobjects = liveness.nTrackedAllocObjects;\n                int[] ntrackedliveobjects = liveness.nTrackedLiveObjects;\n\n                for (int i = 0; i < totalAllocObjectsSize.length; i++) {\n                    boolean match = false;\n\n                    for (String matchingPrefixe : matchingPrefixes) {\n                        if (classnames[i].startsWith(matchingPrefixe)) {\n                            match = true;\n\n                            break;\n                        }\n                    }\n\n                    if (match) {\n                        StringBuilder out = new StringBuilder();\n                        out.append(complete(StringUtils.userFormClassName(classnames[i]), 32));\n                        //out.append(complete(StringUtils.nBytesToString(totalAllocObjectsSize[i]), 10));\n                        out.append(complete(String.valueOf(ntrackedliveobjects[i]), 10));\n                        out.append(complete(String.valueOf(ntrackedallocobjects[i]), 8));\n                        //out.append(complete(String.valueOf((int)avgage[i]), 8));\n                        //out.append(complete(String.valueOf(maxSurvGen[i]), 8));\n                        list.add(out.toString());\n                    }\n                }\n\n                ref(complete(\"Name\", 32) /*complete(\"LiveBytes\", 10)+*/ + complete(\"LiveObjs\", 10) + complete(\"Allocs\", 8)); //+complete(\"AvgAge\", 8)+complete(\"MaxSurv\", 8));\n            } catch (IllegalStateException e) {\n            }\n        }\n        //log results\n        Collections.sort(list);\n\n        for (int i = 0; i < list.size(); i++) {\n            ref(list.get(i));\n        }\n\n        ref(\"\");\n    }\n\n    protected ProfilerEngineSettings initMemoryTest(String projectName, String className) {\n        ProfilerEngineSettings settings = initTest(projectName, className, null);\n        //defaults\n        settings.setThreadCPUTimerOn(false);\n        settings.setAllocTrackEvery(1); //default is not strict - cannot be measured in test\n        settings.setRunGCOnGetResultsInMemoryProfiling(true);\n\n        return settings;\n    }\n\n    protected void startMemoryTest(ProfilerEngineSettings settings, int instrMode, String[] classPrefixes) {\n        //create runner //instrMode CommonConstants.INSTR_OBJECT_ALLOCATIONS\n        assertTrue(builder != null);\n\n        TestProfilerAppHandler handler = new TestProfilerAppHandler(this);\n        TargetAppRunner runner = new TargetAppRunner(settings, handler, new TestProfilingPointsProcessor());\n        runner.addProfilingEventListener(Utils.createProfilingListener(this));\n\n        builder.removeAllListeners();\n        ProfilingResultsDispatcher.getDefault().removeAllListeners();\n\n        resultListener = new MemoryResultListener();\n        builder.addListener(resultListener);\n\n        ProfilingResultsDispatcher.getDefault().addListener(builder);\n        builder.startup(runner.getProfilerClient());\n\n        try {\n            assertTrue(\"not read calibration data\", runner.readSavedCalibrationData());\n            runner.getProfilerClient().initiateMemoryProfInstrumentation(instrMode);\n\n            Process p = startTargetVM(runner);\n            assertNotNull(\"Target JVM is not started\", p);\n            bindStreams(p);\n            runner.attachToTargetVMOnStartup();\n\n            waitForStatus(STATUS_RUNNING);\n            assertTrue(\"runner is not running\", runner.targetAppIsRunning());\n\n            waitForStatus(STATUS_RESULTS_AVAILABLE | STATUS_APP_FINISHED);\n\n            if (!isStatus(STATUS_APP_FINISHED)) {\n                waitForStatus(STATUS_APP_FINISHED);\n            }\n            Thread.sleep(1000);\n            checkMemoryResults(runner, classPrefixes, resultListener, instrMode);\n            setStatus(STATUS_MEASURED);\n        } catch (Exception ex) {\n            log(ex);\n            assertTrue(\"Exception thrown: \" + ex.getMessage(), false);\n        } finally {\n            ProfilingResultsDispatcher.getDefault().pause(true);\n            builder.shutdown();\n\n            builder.removeListener(resultListener);\n            ProfilingResultsDispatcher.getDefault().removeListener(builder);\n\n            finalizeTest(runner);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/monitor/BasicTest.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.monitor;\n\nimport junit.framework.Test;\nimport junit.textui.TestRunner;\nimport org.netbeans.junit.NbModuleSuite;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\n\n\n/**\n *\n * @author ehucka\n */\npublic class BasicTest extends MonitorTestCase {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of BasicTest */\n    public BasicTest(String name) {\n        super(name);\n    }\n\n    public static void main(String[] args) {\n        TestRunner.run(suite());\n    }\n\n    public static Test suite() {\n        return NbModuleSuite.create(\n            NbModuleSuite.createConfiguration(BasicTest.class).addTest(\n            \"testBasic\",\n            \"testBasicCPU\",\n            \"testBasicMemory\",\n            \"testCascadeThreads\",\n            \"testCascadeThreadsCPU\",\n            \"testCascadeThreadsMemory\").honorAutoloadEager(true).enableModules(\".*\").clusters(\".*\").gui(false));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void testBasic() {\n        ProfilerEngineSettings settings = initMonitorTest(\"j2se-simple\", \"simple.Monitor\");\n        startMonitorTest(settings, 12, 1000, new String[] { \"main\", \"Consumer\", \"Producer\" },\n                         new byte[][] {\n                             { ST_SLEEPING | ST_WAIT | ST_RUNNING | ST_MONITOR },\n                             { ST_UNKNOWN | ST_ZOMBIE, ST_WAIT | ST_RUNNING | ST_MONITOR },\n                             { ST_UNKNOWN | ST_ZOMBIE, ST_WAIT | ST_RUNNING | ST_SLEEPING | ST_MONITOR }\n                         }, MONITOR_ONLY);\n    }\n\n    public void testBasicCPU() {\n        ProfilerEngineSettings settings = initMonitorTest(\"j2se-simple\", \"simple.Monitor\");\n        startMonitorTest(settings, 12, 1000, new String[] { \"main\", \"Consumer\", \"Producer\" },\n                         new byte[][] {\n                             { ST_SLEEPING | ST_WAIT | ST_RUNNING | ST_MONITOR },\n                             { ST_UNKNOWN | ST_ZOMBIE, ST_WAIT | ST_RUNNING | ST_MONITOR },\n                             { ST_UNKNOWN | ST_ZOMBIE, ST_WAIT | ST_RUNNING | ST_SLEEPING | ST_MONITOR }\n                         }, WITH_CPU);\n    }\n\n    public void testBasicMemory() {\n        ProfilerEngineSettings settings = initMonitorTest(\"j2se-simple\", \"simple.Monitor\");\n        startMonitorTest(settings, 12, 1000, new String[] { \"main\", \"Consumer\", \"Producer\" },\n                         new byte[][] {\n                             { ST_SLEEPING | ST_WAIT | ST_RUNNING | ST_MONITOR },\n                             { ST_UNKNOWN | ST_ZOMBIE, ST_WAIT | ST_RUNNING | ST_MONITOR },\n                             { ST_UNKNOWN | ST_ZOMBIE, ST_WAIT | ST_RUNNING | ST_SLEEPING | ST_MONITOR }\n                         }, WITH_MEMORY);\n    }\n\n    public void testCascadeThreads() {\n        ProfilerEngineSettings settings = initMonitorTest(\"j2se-simple\", \"simple.monitor.Monitor1\");\n        startMonitorTest(settings, 12, 1000, new String[] { \"main\", \"Cascade\" },\n                         new byte[][] {\n                             { ST_SLEEPING | ST_WAIT | ST_RUNNING | ST_MONITOR, ST_ZOMBIE },\n                             { ST_UNKNOWN | ST_ZOMBIE, ST_RUNNING, ST_ZOMBIE }\n                         }, MONITOR_ONLY);\n    }\n\n    public void testCascadeThreadsCPU() {\n        ProfilerEngineSettings settings = initMonitorTest(\"j2se-simple\", \"simple.monitor.Monitor1\");\n        startMonitorTest(settings, 12, 1000, new String[] { \"main\", \"Cascade\" },\n                         new byte[][] {\n                             { ST_SLEEPING | ST_WAIT | ST_RUNNING | ST_MONITOR, ST_ZOMBIE },\n                             { ST_UNKNOWN | ST_ZOMBIE, ST_RUNNING, ST_ZOMBIE }\n                         }, WITH_CPU);\n    }\n\n    public void testCascadeThreadsMemory() {\n        ProfilerEngineSettings settings = initMonitorTest(\"j2se-simple\", \"simple.monitor.Monitor1\");\n        startMonitorTest(settings, 12, 1000, new String[] { \"main\", \"Cascade\" },\n                         new byte[][] {\n                             { ST_UNKNOWN | ST_SLEEPING | ST_WAIT | ST_RUNNING | ST_MONITOR, ST_ZOMBIE },\n                             { ST_UNKNOWN | ST_ZOMBIE, ST_RUNNING, ST_ZOMBIE }\n                         }, WITH_MEMORY);\n    }\n\n    /*public void testGUICPU() {\n       ProfilerEngineSettings settings = initMonitorTest(\"j2se-java2demo\", \"java2d.Intro\");\n       startMonitorTest(settings, 30, 1000, new String[] {\"main\"},\n               new byte[][] {{ST_UNKNOWN|ST_ZOMBIE, ST_SLEEPING|ST_WAIT|ST_RUNNING|ST_MONITOR,ST_UNKNOWN|ST_ZOMBIE}}, WITH_CPU);\n       }*/\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/monitor/MonitorTestCase.java",
    "content": "/*\n * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * MonitorTestCase.java\n *\n * Created on July 19, 2005, 5:21 PM\n */\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.monitor;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.client.MonitoredData;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.monitor.VMTelemetryDataManager;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadData;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadsDataManager;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.*;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.*;\nimport java.awt.Color;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\n\n\n/**\n *\n * @author ehucka\n */\npublic abstract class MonitorTestCase extends CommonProfilerTestCase {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static final byte ST_UNKNOWN = 1;\n    static final byte ST_ZOMBIE = 2;\n    static final byte ST_RUNNING = 4;\n    static final byte ST_SLEEPING = 8;\n    static final byte ST_MONITOR = 16;\n    static final byte ST_WAIT = 32;\n    static final byte ST_PARK = 64;\n    static final int MONITOR_ONLY = 0;\n    static final int WITH_CPU = 1;\n    static final int WITH_MEMORY = 2;\n    static final int WITH_CODEREGION = 3;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of MonitorTestCase\n     */\n    public MonitorTestCase(String name) {\n        super(name);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    protected char getState(byte state) {\n        if (state == ST_UNKNOWN) {\n            return ('U');\n        } else if (state == ST_ZOMBIE) {\n            return ('Z');\n        } else if (state == ST_RUNNING) {\n            return ('R');\n        } else if (state == ST_SLEEPING) {\n            return ('S');\n        } else if (state == ST_MONITOR) {\n            return ('M');\n        } else if (state == ST_WAIT) {\n            return ('W');\n        } else if (state == ST_PARK) {\n            return ('P');\n        }\n\n        return '-';\n    }\n\n    protected String getStates(byte[] states) {\n        StringBuilder sb = new StringBuilder(states.length);\n\n        for (int i = 0; i < states.length; i++) {\n            sb.append(getState(states[i]));\n        }\n\n        return sb.toString();\n    }\n\n    protected void detectStates(byte[] states, byte[] detectStates) {\n        int detectionindex = 0;\n\n        for (int i = 0; i < states.length; i++) {\n            if ((states[i] & detectStates[detectionindex]) == 0) {\n                detectionindex++;\n\n                if ((detectionindex >= detectStates.length) || ((states[i] & detectStates[detectionindex]) == 0)) {\n                    log(\"\\n*********NOT MATCHING STATES\");\n                    log(getStates(states));\n                    log(\"Matching states: \" + getStates(detectStates));\n                    log(\"Wrong state \" + getState(states[i]) + \" index \" + i);\n                    assertTrue(\"States do not match with pattern\", false);\n                }\n            }\n        }\n    }\n\n    protected ProfilerEngineSettings initMonitorTest(String projectName, String className) {\n        //System.setProperty(\"org.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO\", \"true\");\n        ProfilerEngineSettings settings = initTest(projectName, className, null);\n        //defaults\n        settings.setThreadCPUTimerOn(false);\n        settings.setThreadsSamplingEnabled(true);\n        return settings;\n    }\n\n    protected void logLongs(long[] longs, int count) {\n        double average = 0.0;\n        long max = 0;\n        long min = Long.MAX_VALUE;\n\n        for (int i = 0; i < count; i++) {\n            average += longs[i];\n\n            if (max < longs[i]) {\n                max = longs[i];\n            }\n\n            if (min > longs[i]) {\n                min = longs[i];\n            }\n        }\n\n        average /= count;\n        log(\"Average = \" + average + \" Max = \" + max + \" Min = \" + min + \" Values = \" + count);\n    }\n\n    protected void startMonitorTest(ProfilerEngineSettings settings, int times, long delay, String[] detects,\n                                    byte[][] detectstates, int profilingType) {\n        TargetAppRunner runner = new TargetAppRunner(settings, new TestProfilerAppHandler(this),\n                                                     new TestProfilingPointsProcessor());\n        runner.addProfilingEventListener(Utils.createProfilingListener(this));\n\n        try {\n            runner.readSavedCalibrationData();\n\n            Process p = startTargetVM(runner);\n            assertNotNull(\"Target JVM is not started\", p);\n            bindStreams(p);\n\n            runner.connectToStartedVMAndStartTA();\n\n            if (profilingType == WITH_CPU) {\n                runner.getProfilerClient().initiateRecursiveCPUProfInstrumentation(settings.getInstrumentationRootMethods());\n            } else if (profilingType == WITH_MEMORY) {\n                runner.getProfilerClient().initiateMemoryProfInstrumentation(CommonConstants.INSTR_OBJECT_LIVENESS);\n            } else if (profilingType == WITH_CODEREGION) {\n                runner.getProfilerClient().initiateCodeRegionInstrumentation(settings.getInstrumentationRootMethods());\n            }\n            assert runner.targetAppIsRunning();\n            waitForStatus(STATUS_RUNNING);\n\n            VMTelemetryDataManager dataManager = new VMTelemetryDataManager();\n            dataManager.setArrayBufferSize(10);\n\n            ThreadsDataManager threadsManager = new ThreadsDataManager();\n\n            //run monitoring - data are stored into states map\n            for (int cntr = 0; cntr < times; cntr++) {\n                Thread.sleep(delay);\n\n                if (isStatus(STATUS_APP_FINISHED)) {\n                    break;\n                }\n\n                if (!runner.targetJVMIsAlive()) {\n                    break;\n                }\n\n                runner.getProfilerClient().forceObtainedResultsDump();\n\n                MonitoredData data = runner.getProfilerClient().getMonitoredData();\n\n                dataManager.processData(data);\n                threadsManager.processData(data);\n            }\n\n            setStatus(STATUS_MEASURED);\n\n            //detect stored data - sign defined state and OR them from all matching threads\n            HashMap threads = new HashMap(32);\n            HashMap timestamps = new HashMap(32);\n\n            assertTrue(\"Threads manager has not data\", threadsManager.hasData());\n\n            int statesNumber = 128;\n            long deltat = threadsManager.getEndTime() - threadsManager.getStartTime();\n            double tick = (double) deltat / (double) statesNumber;\n            ArrayList names = new ArrayList();\n\n            for (int i = 0; i < threadsManager.getThreadsCount(); i++) {\n                ThreadData td = threadsManager.getThreadData(i);\n                String tname = td.getName();\n                String className = td.getClassName();\n\n                if (!tname.startsWith(\"process reaper\") // JDK-8284165\n                 && !tname.equals(\"DestroyJavaVM\")\n                 && !tname.equals(\"Common-Cleaner\")\n                 && !tname.equals(\"Notification Thread\")                            // disable system threads\n                 && !\"java.util.logging.LogManager$Cleaner\".equals(className)) {    // disable shutdown hook\n\n                    byte[] states = new byte[statesNumber];\n                    String n = tname + \", class: \" + className;\n                    byte state = ST_UNKNOWN;\n                    long time = threadsManager.getStartTime();\n                    int tdindex = 0;\n\n                    for (int j = 0; j < states.length; j++) {\n                        if ((tdindex < td.size()) && (time >= td.getTimeStampAt(tdindex))) {\n                            state = toBinState(td.getStateAt(tdindex));\n\n                            Color color = td.getThreadStateColorAt(tdindex);\n                            // new threads have null color before their start\n                            // assertNotNull(\"Threads state color is null\", color);\n                            tdindex++;\n                        }\n\n                        states[j] = state;\n                        time = (long) ((j * tick) + threadsManager.getStartTime());\n                    }\n\n                    td.clearStates();\n                    assertTrue(\"Error in threadData.clearStates\", (td.size() == 0));\n                    names.add(tname);\n                    threads.put(n, states);\n                    timestamps.put(n, new Long(td.getFirstTimeStamp()));\n                }\n            }\n\n            String[] keys = (String[]) threads.keySet().toArray(new String[0]);\n            Arrays.sort(keys);\n            Collections.sort(names);\n\n            for (int i = 0; i < names.size(); i++) {\n                ref(names.get(i));\n            }\n\n            boolean[] ret = null;\n            int maxindex = 0;\n\n            for (String key : keys) {\n                byte[] sts = (byte[]) (threads.get(key));\n                log(key);\n                log(getStates(sts));\n                for (int j = 0; j < detects.length; j++) {\n                    if (key.startsWith(detects[j])) {\n                        detectStates(sts, detectstates[j]);\n                    }\n                }\n            }\n\n            assertEquals(\"Some threads are multiple - issue 68266\", names.size(), keys.length);\n            //log datas\n            log(\"\\nDataManager item counts \" + dataManager.getItemCount());\n            log(\"Free Memory\");\n            logLongs(dataManager.freeMemory, dataManager.getItemCount());\n            log(\"lastGCPauseInMS\");\n            logLongs(dataManager.lastGCPauseInMS, dataManager.getItemCount());\n            log(\"nSurvivingGenerations\");\n            logLongs(dataManager.nSurvivingGenerations, dataManager.getItemCount());\n            log(\"nSystemThreads\");\n            logLongs(dataManager.nSystemThreads, dataManager.getItemCount());\n            log(\"nTotalThreads\");\n            logLongs(dataManager.nTotalThreads, dataManager.getItemCount());\n            log(\"nUserThreads\");\n            logLongs(dataManager.nUserThreads, dataManager.getItemCount());\n            log(\"relativeGCTimeInPerMil\");\n            logLongs(dataManager.relativeGCTimeInPerMil, dataManager.getItemCount());\n            log(\"timeStamps\");\n            logLongs(dataManager.timeStamps, dataManager.getItemCount());\n            log(\"totalMemory\");\n            logLongs(dataManager.totalMemory, dataManager.getItemCount());\n            log(\"usedMemory\");\n            logLongs(dataManager.usedMemory, dataManager.getItemCount());\n        } catch (Exception ex) {\n            log(ex);\n            assertTrue(\"Exception thrown: \" + ex.getMessage(), false);\n        } finally {\n            finalizeTest(runner);\n        }\n    }\n\n    protected byte toBinState(byte state) {\n        if (state == CommonConstants.THREAD_STATUS_UNKNOWN) {\n            return ST_UNKNOWN;\n        } else if (state == CommonConstants.THREAD_STATUS_ZOMBIE) {\n            return ST_ZOMBIE;\n        } else if (state == CommonConstants.THREAD_STATUS_RUNNING) {\n            return ST_RUNNING;\n        } else if (state == CommonConstants.THREAD_STATUS_SLEEPING) {\n            return ST_SLEEPING;\n        } else if (state == CommonConstants.THREAD_STATUS_MONITOR) {\n            return ST_MONITOR;\n        } else if (state == CommonConstants.THREAD_STATUS_WAIT) {\n            return ST_WAIT;\n        } else if (state == CommonConstants.THREAD_STATUS_PARK) {\n            return ST_PARK;\n        }\n\n        return 0;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/others/MeasureDiffsTest.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.others;\n\nimport junit.framework.Test;\nimport junit.framework.TestSuite;\nimport junit.textui.TestRunner;\nimport org.netbeans.junit.NbModuleSuite;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n\n/**\n *\n * @author ehucka\n */\npublic class MeasureDiffsTest extends MeasureDiffsTestCase {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of MeasureDiffsTest\n     */\n    public MeasureDiffsTest(String name) {\n        super(name);\n    }\n\n    public static void main(String[] args) {\n        TestRunner.run(suite());\n    }\n\n    public static Test suite() {\n        return NbModuleSuite.create(\n            NbModuleSuite.createConfiguration(MeasureDiffsTest.class).addTest(\n            \"testSettingsInstrumentAllEager\",\n            \"testSettingsInstrumentAllEagerServer\",\n            \"testSettingsInstrumentAllLazy\",\n            \"testSettingsInstrumentAllLazyServer\",\n            \"testSettingsInstrumentAllTotal\",\n            \"testSettingsInstrumentAllTotalServer\")\n            .honorAutoloadEager(true).enableModules(\".*\").clusters(\".*\").gui(false));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void testSettingsInstrumentAllEager() {\n        temptestSettingsInstrumentAll(CommonConstants.INSTRSCHEME_EAGER, false);\n    }\n\n    public void testSettingsInstrumentAllEagerServer() {\n        temptestSettingsInstrumentAll(CommonConstants.INSTRSCHEME_EAGER, true);\n    }\n\n    public void testSettingsInstrumentAllLazy() {\n        temptestSettingsInstrumentAll(CommonConstants.INSTRSCHEME_LAZY, false);\n    }\n\n    public void testSettingsInstrumentAllLazyServer() {\n        temptestSettingsInstrumentAll(CommonConstants.INSTRSCHEME_LAZY, true);\n    }\n\n    public void testSettingsInstrumentAllTotal() {\n        temptestSettingsInstrumentAll(CommonConstants.INSTRSCHEME_TOTAL, false);\n    }\n\n    public void testSettingsInstrumentAllTotalServer() {\n        temptestSettingsInstrumentAll(CommonConstants.INSTRSCHEME_TOTAL, true);\n    }\n\n    protected void temptestSettingsInstrumentAll(int instrScheme, boolean server) {\n        ProfilerEngineSettings settings = initCpuTest(\"j2se-simple\", \"simple.cpu.Measure\");\n        settings.setInstrScheme(instrScheme);\n\n        if (server) {\n            addJVMArgs(settings, \"-server\");\n        }\n\n        startCPUTest(settings, new String[] { \"simple.cpu.Measure.run\" });\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/others/MeasureDiffsTestCase.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * MeasureDiffsTestCase.java\n *\n * Created on July 19, 2005, 5:20 PM\n */\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.others;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.ProfilingResultsDispatcher;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCallGraphBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainerFree;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.*;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.*;\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.util.*;\n\n\n/**\n *\n * @author ehucka\n */\npublic abstract class MeasureDiffsTestCase extends CommonProfilerTestCase {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    class Results {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        double ideal;\n        double measalone;\n        double measprofiler;\n        double profiled;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void setIdeal(String val) {\n            try {\n                ideal = Double.parseDouble(val);\n            } catch (NumberFormatException ex) {\n            }\n        }\n\n        public void setMeasuredAlone(String val) {\n            try {\n                measalone = Double.parseDouble(val);\n            } catch (NumberFormatException ex) {\n            }\n        }\n\n        public void setMeasuredProfiled(String val) {\n            try {\n                measprofiler = Double.parseDouble(val);\n            } catch (NumberFormatException ex) {\n            }\n        }\n\n        public void setProfiled(double val) {\n            profiled = val;\n        }\n\n        public String toString() {\n            return String.valueOf(ideal) + \";\" + String.valueOf(measalone) + \";\" + String.valueOf(measprofiler) + \";\"\n                   + String.valueOf(profiled);\n        }\n    }\n\n    private static class CPUResultListener implements CPUCCTProvider.Listener {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private final Object resultsLock = new Object();\n        private boolean hasResults = false;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void cctEstablished(RuntimeCCTNode appRootNode) {\n            synchronized (resultsLock) {\n                hasResults = true;\n                resultsLock.notify();\n            }\n        }\n\n        public void cctReset() {\n            synchronized (resultsLock) {\n                hasResults = false;\n                resultsLock.notify();\n            }\n        }\n\n        public boolean wait4results(long timeout) {\n            synchronized (resultsLock) {\n                if (!hasResults) {\n                    try {\n                        resultsLock.wait(timeout);\n                    } catch (InterruptedException e) {\n                    }\n                }\n\n                return hasResults;\n            }\n        }\n\n        public void cctEstablished(RuntimeCCTNode appRootNode, boolean empty) {\n            if (!empty) {\n                cctEstablished(appRootNode);\n            }\n            //throw new UnsupportedOperationException(\"Not supported yet.\");\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static int ALL_INV_ERROR_METHOD = 0;\n    static int LAST_INV_ERROR_METHOD = 1;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    File outFile;\n    private CPUCallGraphBuilder builder;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of MeasureDiffsTestCase\n     */\n    public MeasureDiffsTestCase(String name) {\n        super(name);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void startAppAlone(ProfilerEngineSettings settings) {\n        ArrayList commands = new ArrayList(10);\n        commands.add(settings.getTargetJVMExeFile());\n        commands.add(\"-classpath\");\n        commands.add(settings.getMainClassPath());\n        commands.add(settings.getMainClassName());\n        commands.add(outFile.getAbsolutePath());\n\n        String[] cmds = (String[]) commands.toArray(new String[0]);\n\n        try {\n            Runtime.getRuntime().exec(cmds, null, new File(settings.getWorkingDir())).waitFor();\n        } catch (Exception ex) {\n            ex.printStackTrace();\n        }\n    }\n\n    protected ProfilerEngineSettings initCpuTest(String projectName, String mainClass) {\n        ProfilerEngineSettings settings = initTest(projectName, mainClass, null);\n        //defaults\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_TOTAL);\n        settings.setInstrumentEmptyMethods(false);\n        settings.setInstrumentGetterSetterMethods(false);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentSpawnedThreads(true);\n        settings.setExcludeWaitTime(true);\n\n        //addJVMArgs(settings, \"-Dorg.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO=true\");\n        settings.setThreadCPUTimerOn(false);\n\n        return settings;\n    }\n\n    protected ProfilerEngineSettings initCpuTest(String projectName, String mainClass, String[][] rootMethods) {\n        ProfilerEngineSettings settings = initTest(projectName, mainClass, rootMethods);\n        //defaults\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_LAZY);\n        settings.setInstrumentEmptyMethods(false);\n        settings.setInstrumentGetterSetterMethods(false);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentSpawnedThreads(false);\n        settings.setExcludeWaitTime(true);\n\n        //addJVMArgs(settings, \"-Dorg.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO=true\");\n        settings.setThreadCPUTimerOn(false);\n\n        return settings;\n    }\n\n    protected void readIdealTimes(HashMap results) {\n        try {\n            BufferedReader br = new BufferedReader(new FileReader(outFile));\n            String line;\n            boolean first = true;\n\n            while ((line = br.readLine()) != null) {\n                if (first) {\n                    first = false;\n                } else {\n                    StringTokenizer st = new StringTokenizer(line, \";\");\n                    String met = st.nextToken();\n                    Results res = new Results();\n                    res.setIdeal(st.nextToken());\n                    res.setMeasuredAlone(st.nextToken());\n                    results.put(met, res);\n                }\n            }\n\n            br.close();\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n    }\n\n    protected void readProfiledTimes(HashMap results) {\n        try {\n            BufferedReader br = new BufferedReader(new FileReader(outFile));\n            String line;\n            boolean first = true;\n\n            while ((line = br.readLine()) != null) {\n                if (first) {\n                    first = false;\n                } else {\n                    StringTokenizer st = new StringTokenizer(line, \";\");\n                    String met = st.nextToken();\n                    st.nextToken(); //skip ideal\n\n                    Results res = (Results) (results.get(met));\n\n                    if (res != null) {\n                        res.setMeasuredProfiled(st.nextToken());\n                    }\n                }\n            }\n\n            br.close();\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n    }\n\n    protected void refCPUResults(FlatProfileContainer fpc, String[] methodsOrder, HashMap results) {\n        for (int row = 0; row < fpc.getNRows(); row++) {\n            for (String methodsOrder1 : methodsOrder) {\n                if (fpc.getMethodNameAtRow(row).startsWith(methodsOrder1)) {\n                    double tm = fpc.getTimeInMcs0AtRow(row) / (fpc.getNInvocationsAtRow(row) * 1000.0);\n                    String name = fpc.getMethodNameAtRow(row);\n\n                    if (name.indexOf('.') > -1) {\n                        name = name.substring(name.lastIndexOf('.') + 1);\n                    }\n\n                    name = name.substring(0, name.indexOf('('));\n\n                    Results res = (Results) (results.get(name));\n\n                    if (res != null) {\n                        res.setProfiled(tm);\n                    }\n                }\n            }\n        }\n    }\n\n    protected void startCPUTest(ProfilerEngineSettings settings, String[] methodsOrder) {\n        HashMap results = new HashMap(64);\n        builder = new CPUCallGraphBuilder();\n\n        //get results with alone run\n        try {\n            outFile = File.createTempFile(\"profiler\", \"test\", getWorkDir());\n            startAppAlone(settings);\n            System.err.println(\">>> startAppAlone\");\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n\n        readIdealTimes(results);\n\n        settings.setMainArgs(outFile.getAbsolutePath());\n\n        //create runner\n        TargetAppRunner runner = new TargetAppRunner(settings, new TestProfilerAppHandler(this),\n                                                     new TestProfilingPointsProcessor());\n        runner.addProfilingEventListener(Utils.createProfilingListener(this));\n\n        ProfilingResultsDispatcher.getDefault().addListener(builder);\n\n        CPUResultListener resultListener = new CPUResultListener();\n        builder.addListener(resultListener);\n\n        FlatProfileBuilder flattener = new FlatProfileBuilder();\n        builder.addListener(flattener);\n        flattener.setContext(runner.getProfilerClient(),null,null);\n        \n        builder.startup(runner.getProfilerClient());\n\n        try {\n            runner.readSavedCalibrationData();\n            runner.getProfilerClient().initiateRecursiveCPUProfInstrumentation(settings.getInstrumentationRootMethods());\n\n            Process p = startTargetVM(runner);\n            assertNotNull(\"Target JVM is not started\", p);\n            bindStreams(p);\n            runner.attachToTargetVMOnStartup();\n\n            waitForStatus(STATUS_RUNNING);\n            assertTrue(\"runner is not running\", runner.targetAppIsRunning());\n\n            ArrayList methods = new ArrayList();\n\n            waitForStatus(STATUS_APP_FINISHED);\n\n            if (runner.targetJVMIsAlive()) {\n                log(\"Get results: \" + System.currentTimeMillis());\n                assertTrue(\"Results do not exist - issue 65185.\", runner.getProfilerClient().cpuResultsExist());\n\n                runner.getProfilerClient().forceObtainedResultsDump();\n\n                boolean gotResults = resultListener.wait4results(10000);\n                assertTrue(\"Results are not available after 10 seconds.\", gotResults);\n                log(\"obtaining results \" + String.valueOf(System.currentTimeMillis()));\n\n                //logInstrumented(runner);\n                FlatProfileContainerFree fpc = (FlatProfileContainerFree) flattener.createFlatProfile();\n                fpc.filterOriginalData(new String[0], 0, 0.0D);\n                refCPUResults(fpc, methodsOrder, results);\n            }\n\n            setStatus(STATUS_MEASURED);\n            readProfiledTimes(results);\n            writeResults(results);\n        } catch (Exception ex) {\n            log(ex);\n            assertTrue(\"Exception thrown: \" + ex.getMessage(), false);\n        } finally {\n            finalizeTest(runner);\n        }\n    }\n\n    protected void writeResults(HashMap results) {\n        Object[] keys = results.keySet().toArray();\n        Arrays.sort(keys);\n        log(\"\\nMethod Name;Ideal Time;Measured Time;Measured during profiling;Measured by profiler\");\n\n        for (Object key : keys) {\n            Results res = (Results) (results.get(key));\n            log(key + \";\" + res.toString());\n        }\n\n        log(\"\\n\");\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/perf/InstrumentationTest.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * InstrumentationTest.java\n * JUnit based test\n *\n * Created on November 7, 2006, 2:14 PM\n */\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.perf;\n\nimport java.io.BufferedInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.PrintStream;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.HashSet;\nimport java.util.jar.JarEntry;\nimport java.util.jar.JarFile;\nimport junit.framework.*;\nimport junit.textui.TestRunner;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.Instrumentor;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.CommonProfilerTestCase;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.InstrumentMethodGroupResponse;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.RootClassLoadedCommand;\nimport org.netbeans.junit.NbModuleSuite;\nimport org.netbeans.junit.NbPerformanceTest;\n\n\n/**\n *\n * @author ehucka\n */\npublic class InstrumentationTest extends CommonProfilerTestCase implements NbPerformanceTest {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    ArrayList<NbPerformanceTest.PerformanceData> data = new ArrayList();\n    ProfilerEngineSettings settings;\n    String[] classNames;\n    byte[][] classesBytes;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public InstrumentationTest(String testName) {\n        super(testName);\n    }\n\n    public static void main(String[] args) {\n        TestRunner.run(suite());\n    }\n\n    public static Test suite() {\n        return NbModuleSuite.create(\n            NbModuleSuite.createConfiguration(InstrumentationTest.class).addTest(\n            \"testJ2SE\",\n            \"testJaxb\",\n            \"testJaxbNoGettersEmpties\",\n            \"testSimple\",\n            \"testSimpleNoEmpties\",\n            \"testSimpleNoGetters\")\n            .honorAutoloadEager(true).enableModules(\".*\").clusters(\".*\").gui(false));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public NbPerformanceTest.PerformanceData[] getPerformanceData() {\n        return data.toArray(new NbPerformanceTest.PerformanceData[0]);\n    }\n\n    public void reportPerformance(String name, long value, String unit) {\n        NbPerformanceTest.PerformanceData d = new NbPerformanceTest.PerformanceData();\n        d.name = name;\n        d.value = value;\n        d.unit = unit;\n        d.threshold = NbPerformanceTest.PerformanceData.NO_THRESHOLD;\n        data.add(d);\n    }\n\n    public void testJ2SE() {\n        try {\n            String jarPath = \"/perfdata/j2se-simple.jar\";\n            File f = new File(getDataDir(), jarPath);\n            assertTrue(\"Instrumented jar file doesn't exist.\", f.exists());\n            initTest(f.getAbsolutePath());\n            startInstrumentationTest(f.getAbsolutePath());\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            fail();\n        }\n    }\n\n    public void testJaxb() {\n        try {\n            String jarPath = \"/perfdata/jaxb-xjc.jar\";\n            File f = new File(getDataDir(), jarPath);\n            assertTrue(\"Instrumented jar file doesn't exist.\", f.exists());\n            initTest(f.getAbsolutePath());\n            startInstrumentationTest(f.getAbsolutePath());\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            fail();\n        }\n    }\n\n    public void testJaxbNoGettersEmpties() {\n        try {\n            String jarPath = \"/perfdata/jaxb-xjc.jar\";\n            File f = new File(getDataDir(), jarPath);\n            assertTrue(\"Instrumented jar file doesn't exist.\", f.exists());\n            initTest(f.getAbsolutePath());\n            settings.setInstrumentGetterSetterMethods(false);\n            settings.setInstrumentEmptyMethods(false);\n            startInstrumentationTest(f.getAbsolutePath());\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            fail();\n        }\n    }\n\n    public void testSimple() {\n        try {\n            String jarPath = \"/perfdata/oneclass.jar\";\n            File f = new File(getDataDir(), jarPath);\n            assertTrue(\"Instrumented jar file doesn't exist.\", f.exists());\n            initTest(f.getAbsolutePath());\n            startInstrumentationTest(f.getAbsolutePath());\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            fail();\n        }\n    }\n\n    public void testSimpleNoEmpties() {\n        try {\n            String jarPath = \"/perfdata/oneclass.jar\";\n            File f = new File(getDataDir(), jarPath);\n            assertTrue(\"Instrumented jar file doesn't exist.\", f.exists());\n            initTest(f.getAbsolutePath());\n            settings.setInstrumentEmptyMethods(false);\n            startInstrumentationTest(f.getAbsolutePath());\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            fail();\n        }\n    }\n\n    public void testSimpleNoGetters() {\n        try {\n            String jarPath = \"/perfdata/oneclass.jar\";\n            File f = new File(getDataDir(), jarPath);\n            assertTrue(\"Instrumented jar file doesn't exist.\", f.exists());\n            initTest(f.getAbsolutePath());\n            settings.setInstrumentGetterSetterMethods(false);\n            startInstrumentationTest(f.getAbsolutePath());\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            fail();\n        }\n    }\n\n    protected void setClasses(String jarPath) throws Exception {\n        ArrayList<String> names = new ArrayList(16);\n        ArrayList<byte[]> bytes = new ArrayList(16);\n        JarFile file = new JarFile(jarPath);\n        Enumeration<JarEntry> entries = file.entries();\n        ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);\n        int read = 0;\n        byte[] buffer = new byte[1024];\n\n        while (entries.hasMoreElements()) {\n            JarEntry entry = entries.nextElement();\n\n            if (entry.getName().endsWith(\".class\")) {\n                String nm = entry.getName();\n                nm = nm.substring(0, nm.lastIndexOf('.'));\n                names.add(nm);\n\n                BufferedInputStream bis = new BufferedInputStream(file.getInputStream(entry));\n\n                while ((read = bis.read(buffer)) > -1) {\n                    bos.write(buffer, 0, read);\n                }\n\n                bis.close();\n                bytes.add(bos.toByteArray());\n                bos.reset();\n            }\n        }\n\n        classNames = names.toArray(new String[0]);\n        classesBytes = bytes.toArray(new byte[0][]);\n    }\n\n    protected void setRootMethods(String jarFile) throws Exception {\n        JarFile file = new JarFile(jarFile);\n        HashSet<String> list = new HashSet(8);\n\n        for (Enumeration<JarEntry> entries = file.entries(); entries.hasMoreElements();) {\n            JarEntry entry = entries.nextElement();\n\n            if (entry.getName().endsWith(\".class\")) {\n                String name = entry.getName();\n                int idx = name.lastIndexOf('/');\n                String packageName = (idx == -1) ? name : name.substring(0, idx);\n                packageName = packageName.replace('/', '.');\n                list.add(packageName);\n            }\n        }\n\n        ClientUtils.SourceCodeSelection[] ret = new ClientUtils.SourceCodeSelection[list.size()];\n        String[] cls = list.toArray(new String[0]);\n\n        for (int i = 0; i < list.size(); i++) {\n            ret[i] = new ClientUtils.SourceCodeSelection(cls[i] + \".\", \"\", \"\"); //NOI18N\n        }\n\n        settings.setInstrumentationRootMethods(ret);\n    }\n\n    protected boolean checkBytes(String className, byte[] bytes) {\n        String clnm = className.replace('.', '/');\n        int clindex = -1;\n\n        for (int i = 0; i < classNames.length; i++) {\n            if (classNames[i].equals(clnm)) {\n                clindex = i;\n\n                break;\n            }\n        }\n\n        if (clindex == -1) {\n            throw new IllegalStateException(\"Class \" + className + \" has not original.\");\n        }\n\n        byte[] origbytes = classesBytes[clindex];\n\n        if (origbytes.length != bytes.length) {\n            return false;\n        }\n\n        for (int i = 0; i < bytes.length; i++) {\n            if (bytes[i] != origbytes[i]) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    protected ProfilerEngineSettings initTest(String pathToJar)\n                                       throws Exception {\n        settings = new ProfilerEngineSettings();\n        settings.setPortNo(5140);\n        settings.setSeparateConsole(false);\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);\n        settings.setInstrScheme(CommonConstants.INSTRSCHEME_TOTAL);\n        settings.setInstrumentEmptyMethods(true);\n        settings.setInstrumentGetterSetterMethods(true);\n        settings.setInstrumentMethodInvoke(true);\n        settings.setInstrumentSpawnedThreads(true);\n        settings.setJVMArgs(\"\");\n\n        setRootMethods(pathToJar);\n\n        setTargetVM(settings);\n        //setClassPath(settings);\n        setProfilerHome(settings);\n\n        setStatus(STATUS_NONE);\n\n        return settings;\n    }\n\n    protected void startInstrumentationTest(String jarFile)\n                                     throws Exception {\n        ProfilingSessionStatus status = new ProfilingSessionStatus();\n        status.targetJDKVersionString = settings.getTargetJDKVersionString();\n\n        PrintStream oldOutStream = System.out;\n        PrintStream oldErrStream = System.err;\n        System.setOut(getLogStream());\n        System.setErr(getLogStream());\n\n        ClassRepository classRepo = new ClassRepository();\n        classRepo.initClassPaths(settings.getWorkingDir(), settings.getVMClassPaths());\n        Instrumentor instr = new Instrumentor(classRepo, status, settings);\n        instr.setStatusInfoFromSourceCodeSelection(settings.getInstrumentationRootMethods());\n        status.currentInstrType = CommonConstants.INSTR_RECURSIVE_FULL;\n\n        setClasses(jarFile);\n\n        int[] loadersIDs = new int[classNames.length];\n\n        for (int i = 0; i < classNames.length; i++) {\n            loadersIDs[i] = 20;\n        }\n\n        int[] parentloadersIDs = new int[classNames.length];\n\n        for (int i = 0; i < classNames.length; i++) {\n            parentloadersIDs[i] = 0;\n        }\n\n        int[] superClasses = new int[classNames.length];\n        int[][] ifaces = new int[classNames.length][];\n        \n        RootClassLoadedCommand cmd = new RootClassLoadedCommand(classNames, loadersIDs, classesBytes, superClasses, ifaces,\n                                                                classNames.length, parentloadersIDs);\n        log(\"Start instrumenting ...\");\n\n        InstrumentMethodGroupResponse resp = null;\n        long time = System.currentTimeMillis();\n        resp = instr.createInitialInstrumentMethodGroupResponse(cmd);\n        time = System.currentTimeMillis() - time;\n        ref(\"Number of Classes: \" + classNames.length);\n\n        byte[][] clbytes = resp.getReplacementClassFileBytes();\n        ref(\"Instrumented Classes: \" + resp.getBase().getNClasses());\n        ref(\"Instrumented Methods: \" + resp.getBase().getNMethods());\n\n        if (resp.getErrorMessage() != null) {\n            log(\"Error Message: \" + resp.getErrorMessage());\n        }\n\n        String[] clnames = resp.getMethodClasses();\n        byte[][] bts = resp.getReplacementClassFileBytes();\n        boolean comp = false;\n\n        for (int i = 0; i < clnames.length; i++) {\n            if (checkBytes(clnames[i], bts[i])) {\n                log(\"Equals bytes: \" + clnames[i]);\n            }\n        }\n\n        System.setOut(oldOutStream);\n        System.setErr(oldErrStream);\n        reportPerformance(getName(), time, \"ms\");\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/profilingpoints/BasicTest.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.profilingpoints;\n\n\n//import org.graalvm.visualvm.lib.jfluid.tests.jfluid.profilingpoints.ProfilingPointsTestCase.StopWatchPP;\nimport junit.framework.Test;\nimport junit.framework.TestSuite;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\n\n\n/**\n *\n * @author ehucka\n */\n//public class BasicTest extends ProfilingPointsTestCase {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of BasicTest */\n//    public BasicTest(String name) {\n//        super(name);\n//    }\n\n    //    public static Test suite() {\n    //        TestSuite suite = new TestSuite(org.graalvm.visualvm.lib.jfluid.tests.jfluid.profilingpoints.BasicTest.class);\n    //        return suite;\n    //    }\n    /*\n       public void testStartMethodMultiCommands() {\n           ProfilerEngineSettings settings = initPPTest(\"j2se-simple\", \"simple.cpu.Region\", null);\n           startPPStopwatchTest(settings, new StopWatchPP[] {new StopWatchPP(\"simple.cpu.Region\", 19, 20, 20)});\n       }\n\n       public void testFirstEmptyLineEndMethod() {\n           ProfilerEngineSettings settings = initPPTest(\"j2se-simple\", \"simple.cpu.Region\", null);\n           startPPStopwatchTest(settings, new StopWatchPP[] {new StopWatchPP(\"simple.cpu.Region\", 26, 30, 20)});\n       }\n\n       public void testSimpleBlock() {\n           ProfilerEngineSettings settings = initPPTest(\"j2se-simple\", \"simple.cpu.Region\", null);\n           startPPStopwatchTest(settings, new StopWatchPP[] {new StopWatchPP(\"simple.cpu.Region\", 27, 29, 20)});\n       }*/\n\n    //    public void testEmpytBlock() {\n    //        ProfilerEngineSettings settings = initPPTest(\"j2se-simple\", \"simple.cpu.Region\", null);\n    //        startPPStopwatchTest(settings, new StopWatchPP[] {new StopWatchPP(\"simple.cpu.Region\", 33, 34, 20)});\n    //    }\n    /*\n       public void testWholeMethod() {\n           ProfilerEngineSettings settings = initPPTest(\"j2se-simple\", \"simple.cpu.Region\", null);\n           startPPStopwatchTest(settings, new StopWatchPP[] {new StopWatchPP(\"simple.cpu.Region\", 32, 35, 20)});\n       }\n    \n       public void testLinesCodeEmptyBlockEmptyLine() {\n           ProfilerEngineSettings settings = initPPTest(\"j2se-simple\", \"simple.cpu.Region\", null);\n           startPPStopwatchTest(settings, new StopWatchPP[] {new StopWatchPP(\"simple.cpu.Region\", 38, 40, 20)});\n       }\n    \n       public void testSimpleBlockServer() {\n           ProfilerEngineSettings settings = initPPTest(\"j2se-simple\", \"simple.cpu.Region\", null);\n           addJVMArgs(settings, \"-server\");\n           startPPStopwatchTest(settings, new StopWatchPP[] {new StopWatchPP(\"simple.cpu.Region\", 27, 29, 20)});\n       }\n    \n       public void testLinesWithWait() {\n           ProfilerEngineSettings settings = initPPTest(\"j2se-simple\", \"simple.cpu.WaitingTest\", null);\n           startPPStopwatchTest(settings, new StopWatchPP[] {new StopWatchPP(\"simple.cpu.WaitingTest\", 17, 40, 20)});\n       }*/\n//}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/profilingpoints/ProfilingPointsTestCase.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/*\n * ProfilingPointsTestCase.java\n *\n * Created on July 19, 2005, 5:20 PM\n */\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.profilingpoints;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.*;\n\n//import org.graalvm.visualvm.lib.jfluid.client.ProfilingPoint;\n//import org.graalvm.visualvm.lib.jfluid.client.ProfilingPoint.HitEvent;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.TestProfilerAppHandler;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils.Utils;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\n\n\n/**\n *\n * @author ehucka\n */\npublic abstract class ProfilingPointsTestCase extends CommonProfilerTestCase {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static boolean CHECK_ACCURACY = false;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    double MAX_DIFF_PERC = 70;\n    int ppid = 0;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    //    StartStopwatch startStopWatch = null;\n    //    StopStopwatch stopStopWatch = null;\n\n    //    HashMap<StopWatchPP, ArrayList<Long>> results = new HashMap(128);\n    public ProfilingPointsTestCase(String name) {\n        super(name);\n    }\n\n    //    protected ProfilerEngineSettings initPPTest(String projectName, String mainClass, String[][] rootMethods) {\n    //        ProfilerEngineSettings settings = initTest(projectName, mainClass, rootMethods);\n    //        //defaults\n    //        settings.setInstrumentSpawnedThreads(true);\n    //        settings.setExcludeWaitTime(true);\n    //        settings.setNProfiledThreadsLimit(32);\n    //        //addJVMArgs(settings, \"-Dorg.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO=true\");\n    //        \n    //        settings.setThreadCPUTimerOn(false);\n    //        \n    //        return settings;\n    //    }\n\n    //    protected void startPPStopwatchTest(ProfilerEngineSettings settings, StopWatchPP[] stopwatches) {\n    //        \n    //        startStopWatch = new StartStopwatch();\n    //        stopStopWatch = new StopStopwatch();\n    //        \n    //        ProfilingPoint[] points;\n    //        ArrayList<ProfilingPoint> list=new ArrayList(64);\n    //        for (StopWatchPP stopw:stopwatches) {\n    //            points = stopw.getPPoints(this);\n    //            for (ProfilingPoint pp:points) {\n    //                list.add(pp);\n    //            }\n    //        }\n    //        settings.setProfilingPoints(list.toArray(new ProfilingPoint[0]));\n    //        \n    //        TargetAppRunner runner = new TargetAppRunner(settings, new TestProfilerAppHandler(this));\n    //        runner.getProfilingSessionStatus().startProfilingPointsActive = true;\n    //        runner.addProfilingEventListener(Utils.createProfilingListener(this));\n    //        try {\n    //            runner.readSavedCalibrationData();\n    //            runner.getProfilerClient().initiateRecursiveCPUProfInstrumentation(settings.getInstrumentationRootMethods());\n    //\n    //            Process p = startTargetVM(runner);\n    //            assertNotNull(\"Target JVM is not started\", p);\n    //            bindStreams(p);            \n    //            runner.attachToTargetVMOnStartup();\n    //            \n    //            waitForStatus(STATUS_RUNNING);\n    //            assertTrue(\"runner is not running\", runner.targetAppIsRunning());\n    //            \n    //            waitForStatus(STATUS_APP_FINISHED);\n    //            if (runner.targetJVMIsAlive()) {\n    //                log(\"JVM is Alive: \"+System.currentTimeMillis());\n    //            }\n    //            setStatus(STATUS_MEASURED);\n    //            \n    //            ref(\"Stopwatches:\");\n    //            for (StopWatchPP stopw:stopwatches) {\n    //                if (results.get(stopw) != null)\n    //                    stopw.measureStopwatch(results.get(stopw), this);\n    //                else\n    //                    log(\"\\nStopwatch \"+stopw+\" has null results.\");\n    //            }\n    //            \n    //            setStatus(STATUS_MEASURED);\n    //        } catch (Exception ex) {\n    //            log(ex);\n    //            assertTrue(\"Exception thrown: \"+ex.getMessage(), false);\n    //        } finally {\n    //            finalizeTest(runner);\n    //        }\n    //    }\n\n    //    HashMap<Integer, StopWatchPP> stopwatches = new HashMap(32);\n\n    //    protected ProfilingPoint[] createStopwatch(StopWatchPP stopwatch) {\n    //        ProfilingPoint[] points=new ProfilingPoint[2];\n    //        points[0] = new ProfilingPoint(ppid++, stopwatch.className, stopwatch.startLine, startStopWatch, \"org.graalvm.visualvm.lib.jfluid.global.ProfilingPointServerHandler\");\n    //        points[1] = new ProfilingPoint(ppid++, stopwatch.className, -stopwatch.stopLine, stopStopWatch, \"org.graalvm.visualvm.lib.jfluid.global.ProfilingPointServerHandler\");\n    //        stopwatches.put(ppid-2, stopwatch);\n    //        stopwatches.put(ppid-1, stopwatch);\n    //        \n    //        return points;\n    //    }\n    //    /*\n    //    protected void startPPTest(ProfilerEngineSettings settings, String crClasse,\n    //            String crMethod, String crSignature, long idealTime, double diffPercent) {\n    //        //create runner\n    //     \n    //        TargetAppRunner runner = new TargetAppRunner(settings, new TestProfilerAppHandler(this));\n    //        runner.addProfilingEventListener(Utils.createProfilingListener(this));\n    //        try {\n    //            runner.readSavedCalibrationData();\n    //            //create selection\n    //            SourceCodeSelection select = new SourceCodeSelection(crClasse, crMethod, crSignature);\n    //            runner.getProfilerClient().initiateCodeRegionInstrumentation(select);\n    //     \n    //            //measureCR(runner, idealTime, diffPercent);\n    //        } catch (Exception ex) {\n    //            log(ex);\n    //            assertTrue(\"Exception thrown: \"+ex.getMessage(), false);\n    //        } finally {\n    //            finalizeTest(runner);\n    //        }\n    //    }*/\n    //    \n    //    static int counts = 0;\n    //    static int counte = 0;\n    //    \n    //    HashMap<StopWatchPP, HashMap<Integer, Long>> hits = new HashMap(32);\n    //    \n    //    class StartStopwatch implements ProfilingPoint.Executor {\n    //        public void profilePointHit(HitEvent event) {\n    //            System.out.println(\"start id \"+counts++);\n    //            //log(\"start \"+event.getId()+\"\");\n    //            StopWatchPP stopwatch = stopwatches.get(event.getId());\n    //            HashMap<Integer, Long> map = hits.get(stopwatch);\n    //            if (map == null) {\n    //                map = new HashMap(32);\n    //                hits.put(stopwatch, map);\n    //            }\n    //            map.put(event.getThreadId(), event.getTimestamp());\n    //        }\n    //    }\n    //    \n    //    class StopStopwatch implements ProfilingPoint.Executor {\n    //        public void profilePointHit(HitEvent event) {\n    //            System.out.println(\"end id \"+counte++);\n    //            StopWatchPP stopwatch = stopwatches.get(event.getId());\n    //            HashMap<Integer, Long> map = hits.get(stopwatch);\n    //            if (map != null && map.get(event.getThreadId()) != null) {\n    //                long tms = map.remove(event.getThreadId());\n    //                ArrayList<Long> res = results.get(stopwatch);\n    //                if (res == null) {\n    //                    res = new ArrayList(128);\n    //                    results.put(stopwatch, res);\n    //                }\n    //                res.add((event.getTimestamp() - tms)/1000);\n    //            }\n    //        }\n    //    }\n    //    \n    //    public static class StopWatchPP {\n    //        String className;\n    //        int startLine, stopLine, diffMillis;\n    //        \n    //        public StopWatchPP(String classname, int start, int end, int diff) {\n    //            className = classname;\n    //            startLine = start;\n    //            stopLine = end;\n    //            diffMillis = diff;\n    //        }\n    //        \n    //        public ProfilingPoint[] getPPoints(ProfilingPointsTestCase test) {\n    //            return test.createStopwatch(this);\n    //        }\n    //        \n    //        \n    //        protected void measureStopwatch(ArrayList<Long> results, ProfilingPointsTestCase test) throws Exception {\n    //            ArrayList<Long> times = new ArrayList(results.size());\n    //            times.addAll(results);\n    //            Collections.sort(times);\n    //            \n    //            double all=0.0;\n    //            StringBuilder sb=new StringBuilder();\n    //            for (int i=0;i < times.size();i++) {\n    //                all+=times.get(i);\n    //                sb.append(StringUtils.mcsTimeToString(results.get(i)));\n    //                sb.append(\" \");\n    //            }\n    //            \n    //            double median;\n    //            if (times.size()%2 > 0)\n    //                median=times.get(times.size()/2);\n    //            else\n    //                median=(times.get(times.size()/2)+times.get(times.size()/2-1))/2;\n    //            int match=0;\n    //            for (int i = 0; i < times.size(); i++) {\n    //                if (Math.abs(times.get(i)-median)/1000 <= diffMillis) {\n    //                    match++;\n    //                }\n    //            }\n    //            double max=times.get(times.size()-1);\n    //            double min=times.get(0);\n    //            test.log(\"\\nStopWatch \"+this+\"\\n---------------------------------------------\");\n    //            test.log(\"Values:\");\n    //            test.log(sb);\n    //            test.log(\"match=\"+match);\n    //            test.log(\"Invocations: \"+results.size());\n    //            test.log(\"Total=\"+StringUtils.mcsTimeToString((long)all)+\" ms  Median=\"+\n    //                    StringUtils.mcsTimeToString((long)median)+\" ms  Min=\"+\n    //                    StringUtils.mcsTimeToString((long)min)+\n    //                    \" ms  Max=\"+StringUtils.mcsTimeToString((long)max)+\" ms\");\n    //            test.ref(this+\", \"+results.size()+\" pass(es)\");\n    //            if (match < times.size()*test.MAX_DIFF_PERC/100.0) {\n    //                test.log(\"\\n!!!Results don't match: \"+test.complete(String.valueOf((times.size()-match)*100.0/times.size()), 6)+\n    //                        \" %  of values are different more than \"+diffMillis+\" ms than median value \"+StringUtils.mcsTimeToString((long)median)+\"\\n\");\n    //                if (CHECK_ACCURACY)\n    //                    assertTrue(\"Results are too different\", false);\n    //            }\n    //        }\n    //        \n    //        public String toString() {\n    //            return className+\":\"+startLine+\"->\"+stopLine;\n    //        }\n    //    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/utils/DumpStream.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils;\n\nimport java.io.*;\n\n\npublic class DumpStream extends Thread {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private BufferedReader reader;\n    private PrintStream out;\n    private Process process;\n    private String prefix;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public DumpStream(Process p, InputStream ins, PrintStream out, String prefix) {\n        this.process = p;\n        this.reader = new BufferedReader(new InputStreamReader(ins));\n        this.out = out;\n        this.prefix = prefix;\n\n        if (this.prefix == null) {\n            this.prefix = \"\";\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void run() {\n        String line;\n\n        try {\n            while ((line = reader.readLine()) != null) {\n                out.println(prefix + line);\n\n                try {\n                    sleep(10);\n                } catch (InterruptedException ex) {\n                }\n            }\n\n            reader.close();\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/utils/TestAsyncDialog.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils;\n\nimport org.graalvm.visualvm.lib.jfluid.client.AppStatusHandler.AsyncDialog;\n\n\npublic class TestAsyncDialog implements AsyncDialog {\n\n    public synchronized void close() {\n        //        if (closed)\n        //            return;\n//        closed = true;\n\n        //        notifyAll();\n    }\n\n    public synchronized void display() {\n//        opened = true;\n\n        //        while (!closed) {\n        //            try {\n        //                wait();\n        //            } catch (InterruptedException e) {\n        //                e.printStackTrace();\n        //            }\n        //        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/utils/TestProfilerAppHandler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils;\n\nimport org.graalvm.visualvm.lib.jfluid.client.AppStatusHandler;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.CommonProfilerTestCase;\n\n\npublic class TestProfilerAppHandler implements AppStatusHandler {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    CommonProfilerTestCase test;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public TestProfilerAppHandler(CommonProfilerTestCase t) {\n        test = t;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public AsyncDialog getAsyncDialogInstance(String message, boolean showProgress, Runnable cancelHandler) {\n        return new TestAsyncDialog();\n    }\n\n    public boolean confirmWaitForConnectionReply() {\n        return false;\n    }\n\n    public void displayError(String msg) {\n        test.log(\"\\n!!!error\");\n        test.log(\"mesage=\" + msg);\n        test.getLog().flush();\n        System.err.println(\"Error: \" + msg);\n        new Exception().printStackTrace();\n        test.setStatus(CommonProfilerTestCase.STATUS_ERROR);\n    }\n\n    public void displayErrorAndWaitForConfirm(String msg) {\n        test.getLog().flush();\n        test.log(\"error\");\n        test.log(\"mesg=\" + msg);\n        System.err.println(\"Error: \" + msg);\n        new Exception().printStackTrace();\n        test.setStatus(CommonProfilerTestCase.STATUS_ERROR);\n    }\n\n    public void displayErrorWithDetailsAndWaitForConfirm(String shortMsg, String detailsMsg) {\n        test.getLog().flush();\n        test.log(\"error\");\n        test.log(\"mesg=\" + shortMsg);\n        test.log(\"details=\" + detailsMsg);\n        System.err.println(\"Error: \" + shortMsg + \"; Details: \" + detailsMsg);\n        new Exception().printStackTrace();\n        test.setStatus(CommonProfilerTestCase.STATUS_ERROR);\n    }\n\n    public void displayNotification(String msg) {\n        test.log(\"notification: \" + msg);\n    }\n\n    public void displayNotificationAndWaitForConfirm(String msg) {\n        test.log(\"notification: \" + msg);\n    }\n\n    public void displayNotificationWithDetailsAndWaitForConfirm(String shortMsg, String detailsMsg) {\n        test.log(\"notification: \" + shortMsg + \", detail: \" + detailsMsg);\n    }\n\n    public void displayWarning(String msg) {\n        test.log(\"warning: \" + msg);\n    }\n\n    public void displayWarningAndWaitForConfirm(String msg) {\n        test.log(\"warning: \" + msg);\n    }\n\n    public void handleShutdown() {\n        test.log(\"Handler shutdown\");\n        test.setStatus(CommonProfilerTestCase.STATUS_APP_FINISHED);\n        test.waitForStatus(CommonProfilerTestCase.STATUS_MEASURED);\n        test.log(\"Handled shutdown\");\n    }\n\n    public void pauseLiveUpdates() {\n        test.unsetStatus(CommonProfilerTestCase.STATUS_LIVERESULTS_AVAILABLE);\n    }\n\n    public void resultsAvailable() {\n        test.log(\"Result Available\");\n        test.setStatus(CommonProfilerTestCase.STATUS_RESULTS_AVAILABLE);\n    }\n\n    public void resumeLiveUpdates() {\n        test.setStatus(CommonProfilerTestCase.STATUS_LIVERESULTS_AVAILABLE);\n    }\n\n    public void takeSnapshot() {\n        test.log(\"take snapshot\");\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/utils/TestProfilingPointsProcessor.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ProfilingPointsProcessor;\nimport org.graalvm.visualvm.lib.jfluid.client.RuntimeProfilingPoint;\n\n\npublic class TestProfilingPointsProcessor extends ProfilingPointsProcessor {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void profilingPointHit(RuntimeProfilingPoint.HitEvent event) {\n        // do nothing\n    }\n\n    public void timeAdjust(final int threadId, final long timeDiff0, final long timeDiff1) {\n        // do nothing\n    }\n\n    @Override\n    public RuntimeProfilingPoint[] getSupportedProfilingPoints() {\n        return new RuntimeProfilingPoint[0];\n    }\n\n    @Override\n    public void init(Object project) {\n        // do nothing\n    }\n\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/utils/Utils.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.utils;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilingEventListener;\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.CommonProfilerTestCase;\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\n\n\npublic class Utils {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public Utils() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void copyFile(File file, File target) {\n        try {\n            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));\n            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(target));\n            byte[] buffer = new byte[10240];\n            int len = 0;\n\n            while ((len = bis.read(buffer)) > 0) {\n                bos.write(buffer, 0, len);\n            }\n\n            bis.close();\n            bos.close();\n        } catch (FileNotFoundException ex) {\n            ex.printStackTrace();\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n    }\n\n    public static void copyFolder(File folder, File target) {\n        File[] lst = folder.listFiles();\n\n        if (!target.exists()) {\n            target.mkdirs();\n        }\n\n        for (File lst1 : lst) {\n            File nw = new File(target, lst1.getName());\n            if (lst1.isDirectory()) {\n                copyFolder(lst1, nw);\n            } else {\n                copyFile(lst1, nw);\n            }\n        }\n    }\n\n    public static ProfilingEventListener createProfilingListener(final CommonProfilerTestCase test) {\n        return new ProfilingEventListener() {\n                public void targetAppStarted() {\n                    test.log(\"app started\");\n                    test.setStatus(CommonProfilerTestCase.STATUS_RUNNING);\n                }\n\n                public void targetAppStopped() {\n                    test.log(\"app stoped\");\n                }\n\n                public void targetAppSuspended() {\n                    test.log(\"app suspended\");\n                }\n\n                public void targetAppResumed() {\n                    test.log(\"app resumed\");\n                }\n\n                public void attachedToTarget() {\n                    test.log(\"app attached to target\");\n                    test.setStatus(CommonProfilerTestCase.STATUS_RUNNING);\n                }\n\n                public void detachedFromTarget() {\n                    test.log(\"app detached from target\");\n                }\n\n                public void targetVMTerminated() {\n                    test.log(\"vm terminated\");\n                    test.setStatus(CommonProfilerTestCase.STATUS_FINISHED);\n                }\n            };\n    }\n\n    public static void removeFolder(File folder) {\n        File[] lst = folder.listFiles();\n\n        if (lst == null) {\n            System.err.println(\"null files \" + folder.getAbsolutePath());\n\n            return;\n        }\n\n        for (File lst1 : lst) {\n            if (lst1.isDirectory()) {\n                removeFolder(lst1);\n            } else {\n                lst1.delete();\n            }\n        }\n\n        folder.delete();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/wireio/BasicTest.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.wireio;\n\nimport junit.framework.Test;\nimport junit.textui.TestRunner;\nimport org.netbeans.junit.NbModuleSuite;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.*;\nimport java.net.Socket;\n\n\n/**\n *\n * @author ehucka\n */\npublic class BasicTest extends CommonWireIOTestCase {\n\n    private Socket clientSocket = null;\n    private LoggingThread t = null;\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of BasicTest */\n    public BasicTest(String name) {\n        super(name);\n    }\n\n    public static void main(String[] args) {\n        TestRunner.run(suite());\n    }\n\n    public static Test suite() {\n        return NbModuleSuite.create(\n            NbModuleSuite.createConfiguration(BasicTest.class).addTest(\n            \"testComplexCommands\",\n            \"testComplexResponse\",\n            \"testSimpleCommands\",\n            \"testSimpleResponse\",\n            \"testUnknownSimpleCommand\").enableModules(\".*\").clusters(\".*\").honorAutoloadEager(true).gui(false));\n    }\n\n    protected void tearDown() throws Exception {\n        //To prevent chain failures due to occupied socket or unclosed logging thread\n        try {\n            t.setRunning(false);\n            clientSocket.close();\n        } catch (Exception e) {}\n        super.tearDown();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void testComplexCommands() {\n        t = new LoggingThread();\n        t.start();\n        try {\n            while (!t.isPrepared()) {\n                Thread.sleep(1000);\n            }\n\n            clientSocket = new Socket(\"localhost\", PORT);\n            WireIO wireIO = createWireIOClient(clientSocket);\n\n            Command cmd;\n            cmd = new AsyncMessageCommand(true, \"async message text\");\n            log(\"sending command \" + cmd);\n            wireIO.sendComplexCommand(cmd);\n\n            cmd = new ClassLoadedCommand(\"java.lang.String\", new int[3], new byte[0], true);\n            log(\"sending command \" + cmd);\n            wireIO.sendComplexCommand(cmd);\n\n            cmd = new RootClassLoadedCommand(new String[] { \"java.lang.String\" }, new int[1], new byte[1][0], new int[1], new int[1][], 1, new int[1]);\n            log(\"sending command \" + cmd);\n            wireIO.sendComplexCommand(cmd);\n\n            cmd = new SetUnchangeableInstrParamsCommand(false, true, false, 0, 1024);\n            log(\"sending command \" + cmd);\n            wireIO.sendComplexCommand(cmd);\n\n            cmd = new MethodInvokedFirstTimeCommand('\\0');\n            log(\"sending command \" + cmd);\n            wireIO.sendComplexCommand(cmd);\n\n            cmd = new GetMethodNamesForJMethodIdsCommand(new int[] { 1 });\n            log(\"sending command \" + cmd);\n            wireIO.sendComplexCommand(cmd);\n\n            cmd = new MethodLoadedCommand(\"java.lang.String\", 7, \"toString()\", \"\");\n            log(\"sending command \" + cmd);\n            wireIO.sendComplexCommand(cmd);\n\n            cmd = new EventBufferDumpedCommand(1024, null, -1);\n            log(\"sending command \" + cmd);\n            wireIO.sendComplexCommand(cmd);\n\n            cmd = new SetChangeableInstrParamsCommand(false, 32, 1024, 12, 10, 5, 10, true, true, true, true, 10);\n            log(\"sending command \" + cmd);\n            wireIO.sendComplexCommand(cmd);\n\n            cmd = new InitiateProfilingCommand(CommonConstants.CPU_INSTR_FULL, \"java.lang.String\");\n            log(\"sending command \" + cmd);\n            wireIO.sendComplexCommand(cmd);\n\n            cmd = new InstrumentMethodGroupCommand(CommonConstants.CPU_INSTR_FULL, new String[] { \"java.lang.String\" },\n                                                   new int[1], new byte[1][0], new boolean[1], 0);\n            log(\"sending command \" + cmd);\n            wireIO.sendComplexCommand(cmd);\n\n            cmd = new GetDefiningClassLoaderCommand(\"java.lang.String\", 1);\n            log(\"sending command \" + cmd);\n            wireIO.sendComplexCommand(cmd);\n\n            clientSocket.close();\n            log(\"wait for thread\");\n\n            long tm = 0;\n\n            while ((tm < 20000) && t.isRunning()) {\n                Thread.sleep(1000);\n                tm += 1000;\n            }\n\n            log(\"finished.\");\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            assertTrue(ex.getMessage(), false);\n        }\n    }\n\n    public void testComplexResponse() {\n        t = new LoggingThread();\n        t.start();\n        try {\n            while (!t.isPrepared()) {\n                Thread.sleep(1000);\n            }\n\n            clientSocket = new Socket(\"localhost\", PORT);\n            WireIO wireIO = createWireIOClient(clientSocket);\n\n            Response resp;\n            resp = new CodeRegionCPUResultsResponse(new long[] { 10L, 20L, 30L });\n            log(\"send response \" + resp);\n            wireIO.sendComplexResponse(resp);\n\n            resp = new ThreadLivenessStatusResponse(\"status\".getBytes());\n            log(\"send response \" + resp);\n            wireIO.sendComplexResponse(resp);\n\n            // Testing VMProperties against a golden file may fail because of different environemtn; ommiting this response\n            //            resp = new VMPropertiesResponse(\n            //          System.getProperty(\"java.version\"), // NOI18N\n            //          System.getProperty(\"java.class.path\"), // NOI18N\n            //          System.getProperty(\"java.ext.dirs\"), // NOI18N\n            //          System.getProperty(\"sun.boot.class.path\"), // NOI18N\n            //          System.getProperty(\"user.dir\"), // NOI18N\n            //          \"-cp\",\n            //          \"Run\",\n            //          System.getProperty(\"os.name\"), // NOI18N\n            //          Runtime.getRuntime().maxMemory(),\n            //          System.currentTimeMillis(),\n            //          Timers.getCurrentTimeInCounts(),\n            //          10\n            //          ); // NOI18N\n            //            \n            ////            resp=new VMPropertiesResponse(\"1.5.0_04\", \"rt.jar\", \"/tmp\" , \"agentpath\", \".\", \"-cp\", \"Run\", \"linux\", 128, 10);\n            //            log(\"send response \"+resp);\n            //            wireIO.sendComplexResponse(resp);\n            resp = new DumpResultsResponse(true, 200508181215L);\n            log(\"send response \" + resp);\n            wireIO.sendComplexResponse(resp);\n\n            resp = new InstrumentMethodGroupResponse(new String[] { \"java.lang.String\" }, new int[1], new byte[1][0],\n                                                     new boolean[1], 0);\n            log(\"send response \" + resp);\n            wireIO.sendComplexResponse(resp);\n\n            resp = new MethodNamesResponse(new byte[0], new int[0]);\n            log(\"send response \" + resp);\n            wireIO.sendComplexResponse(resp);\n\n            resp = new DefiningLoaderResponse(1);\n            log(\"send response \" + resp);\n            wireIO.sendComplexResponse(resp);\n\n            resp = new CalibrationDataResponse(new double[] { 12.4 }, new double[] { 10.4 }, new double[] { 13.54 },\n                                               new long[] { 3, 10 });\n            log(\"send response \" + resp);\n            wireIO.sendComplexResponse(resp);\n\n            resp = new InternalStatsResponse();\n            log(\"send response \" + resp);\n            wireIO.sendComplexResponse(resp);\n\n            resp = new ObjectAllocationResultsResponse(new int[] { 20 }, 1);\n            log(\"send response \" + resp);\n            wireIO.sendComplexResponse(resp);\n\n            MonitoredNumbersResponse r = new MonitoredNumbersResponse(new long[] { 20L }, 0, 0);\n            log(\"send response \" + r);\n            // to prevent NPE due to null fields gcStarts, gcFinishes\n            r.setGCstartFinishData(new long[] { 0L }, new long[] { 20L });\n            wireIO.sendComplexResponse(r);\n            \n            clientSocket.close();\n            log(\"wait for thread\");\n\n            long tm = 0;\n\n            while ((tm < 20000) && t.isRunning()) {\n                Thread.sleep(1000);\n                tm += 1000;\n            }\n\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            assertTrue(ex.getMessage(), false);\n        }\n    }\n\n    public void testSimpleCommands() {\n        t = new LoggingThread();\n        t.start();\n        try {\n            while (!t.isPrepared()) {\n                Thread.sleep(1000);\n            }\n\n            clientSocket = new Socket(\"localhost\", PORT);\n            WireIO wireIO = createWireIOClient(clientSocket);\n\n            for (int cmd = 1; cmd < 40; cmd++) {\n                wireIO.sendSimpleCommand(cmd);\n                log(\"send command \" + cmd);\n            }\n\n            clientSocket.close();\n            log(\"wait for thread\");\n\n            long tm = 0;\n\n            while ((tm < 20000) && t.isRunning()) {\n                Thread.sleep(1000);\n                tm += 1000;\n            }\n\n            log(\"finished.\");\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            assertTrue(ex.getMessage(), false);\n        }\n    }\n\n    public void testSimpleResponse() {\n        t = new LoggingThread();\n        t.start();\n        try {\n            while (!t.isPrepared()) {\n                Thread.sleep(1000);\n            }\n\n            clientSocket = new Socket(\"localhost\", PORT);\n            WireIO wireIO = createWireIOClient(clientSocket);\n\n            wireIO.sendSimpleResponse(true, \"Error message.\");\n            log(\"response send\");\n            clientSocket.close();\n            log(\"wait for thread\");\n\n            long tm = 0;\n\n            while ((tm < 20000) && t.isRunning()) {\n                Thread.sleep(1000);\n                tm += 1000;\n            }\n\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            assertTrue(ex.getMessage(), false);\n        }\n    }\n\n    public void testUnknownSimpleCommand() {\n        t = new LoggingThread();\n        t.start();\n        try {\n            while (!t.isPrepared()) {\n                Thread.sleep(1000);\n            }\n\n            clientSocket = new Socket(\"localhost\", PORT);\n            WireIO wireIO = createWireIOClient(clientSocket);\n\n            int cmd = 0;\n            wireIO.sendSimpleCommand(cmd);\n            log(\"send command \" + cmd);\n            clientSocket.close();\n            log(\"wait for thread\");\n\n            long tm = 0;\n\n            while ((tm < 20000) && t.isRunning()) {\n                Thread.sleep(1000);\n                tm += 1000;\n            }\n\n        } catch (Exception ex) {\n            ex.printStackTrace();\n            assertTrue(ex.getMessage(), false);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/qa-functional/src/org/graalvm/visualvm/lib/jfluid/tests/jfluid/wireio/CommonWireIOTestCase.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.tests.jfluid.wireio;\n\nimport org.graalvm.visualvm.lib.jfluid.tests.jfluid.CommonProfilerTestCase;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.Command;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.net.ServerSocket;\nimport java.net.Socket;\n\n\n/**\n *\n * @author ehucka\n */\npublic class CommonWireIOTestCase extends CommonProfilerTestCase {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    protected class LoggingThread extends Thread {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        boolean prepared = false;\n        private boolean running = true;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public boolean isPrepared() {\n            return prepared;\n        }\n\n        public void setRunning(boolean running) {\n            this.running = running;\n        }\n\n        public boolean isRunning() {\n            return running;\n        }\n\n        public void run() {\n            try {\n                ServerSocket serverSocket = new ServerSocket(PORT);\n                ref(\"Server start to listen on port \" + String.valueOf(PORT));\n                prepared = true;\n\n                Socket clientSocket = serverSocket.accept();\n\n                WireIO wireIO = createWireIO(clientSocket);\n\n                while (running) {\n                    running &= simpleLogCommands(wireIO);\n                }\n\n                serverSocket.close();\n            } catch (IOException ex) {\n                ex.printStackTrace();\n            }\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    protected static int PORT = 5140;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of CommonWireIOTestCase */\n    public CommonWireIOTestCase(String name) {\n        super(name);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public WireIO createWireIO(Socket clientSocket) {\n        try {\n            clientSocket.setTcpNoDelay(true); // Necessary at least on Solaris to avoid delays in e.g. readInt() etc.\n\n            ObjectInputStream socketIn = new ObjectInputStream(clientSocket.getInputStream());\n            ObjectOutputStream socketOut = new ObjectOutputStream(clientSocket.getOutputStream());\n            WireIO wireIO = new WireIO(socketOut, socketIn);\n\n            return wireIO;\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n\n        return null;\n    }\n\n    public WireIO createWireIOClient(Socket clientSocket) {\n        try {\n            clientSocket.setSoTimeout(0);\n            clientSocket.setTcpNoDelay(true); // Necessary at least on Solaris to avoid delays in e.g. readInt() etc.\n\n            ObjectOutputStream socketOut = new ObjectOutputStream(clientSocket.getOutputStream());\n            ObjectInputStream socketIn = new ObjectInputStream(clientSocket.getInputStream());\n            WireIO wireIO = new WireIO(socketOut, socketIn);\n\n            return wireIO;\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n\n        return null;\n    }\n\n    public boolean simpleLogCommands(WireIO wireIO) {\n        try {\n            Object o = wireIO.receiveCommandOrResponse();\n\n            if (o == null) {\n                ref(\"Connection interrupted.\");\n\n                return false;\n            } else {\n                if (o instanceof Command) {\n                    ref(\" received command \" + o.toString());\n                } else {\n                    ref(\" received object \" + o.getClass().getName() + \" \" + o.toString());\n                }\n            }\n        } catch (IOException ex) {\n            return false;\n        }\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/unit/src/org/graalvm/visualvm/lib/jfluid/results/cpu/StackTraceSnapshotBuilderTest.java",
    "content": "/*\n * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.results.cpu;\n\nimport java.lang.Thread.State;\nimport java.lang.management.ManagementFactory;\nimport java.lang.management.ThreadInfo;\nimport java.lang.management.ThreadMXBean;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.Collections;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.openmbean.CompositeData;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport static org.junit.Assert.*;\n\n\n/**\n *\n * @author Jaroslav Bachorik, Tomas Hurka\n */\npublic class StackTraceSnapshotBuilderTest {\n\n    private StackTraceSnapshotBuilder instance;\n\n    private final StackTraceElement[] elements0 = new StackTraceElement[] {\n        new StackTraceElement(\"test.Class1\", \"method3\", \"Class1.java\", 30),\n        new StackTraceElement(\"test.Class1\", \"method2\", \"Class1.java\", 20),\n        new StackTraceElement(\"test.Class1\", \"method1\", \"Class1.java\", 10)\n    };\n\n    private final StackTraceElement[] elementsDif = new StackTraceElement[] {\n        new StackTraceElement(\"test.Class1\", \"method3\", \"Class1.java\", 40),\n        new StackTraceElement(\"test.Class1\", \"method4\", \"Class1.java\", 30),\n        new StackTraceElement(\"test.Class1\", \"method2\", \"Class1.java\", 20),\n        new StackTraceElement(\"test.Class1\", \"method1\", \"Class1.java\", 10)\n    };\n\n    private final StackTraceElement[] elementsPlus = new StackTraceElement[] {\n        new StackTraceElement(\"test.Class1\", \"method4\", \"Class1.java\", 40),\n        new StackTraceElement(\"test.Class1\", \"method3\", \"Class1.java\", 30),\n        new StackTraceElement(\"test.Class1\", \"method2\", \"Class1.java\", 20),\n        new StackTraceElement(\"test.Class1\", \"method1\", \"Class1.java\", 10)\n    };\n\n    private final StackTraceElement[] elementsMinus = new StackTraceElement[] {\n        new StackTraceElement(\"test.Class1\", \"method2\", \"Class1.java\", 20),\n        new StackTraceElement(\"test.Class1\", \"method1\", \"Class1.java\", 10)\n    };\n\n    private final StackTraceElement[] elementsDup = new StackTraceElement[] {\n        new StackTraceElement(\"test.Class1\", \"method3\", \"Class1.java\", 30),\n        new StackTraceElement(\"test.Class1\", \"method2\", \"Class1.java\", 21),\n        new StackTraceElement(\"test.Class1\", \"method1\", \"Class1.java\", 10)\n    };\n\n    private Thread thread0;\n    private Thread thread1;\n    private Thread thread2;\n\n    private java.lang.management.ThreadInfo[] stack0;\n    private java.lang.management.ThreadInfo[] stackPlus;\n    private java.lang.management.ThreadInfo[] stackMinus;\n    private java.lang.management.ThreadInfo[] stackDif;\n    private java.lang.management.ThreadInfo[] stackDup;\n    \n\n    public StackTraceSnapshotBuilderTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n    }\n\n    @Before\n    public void setUp() {\n        instance = new StackTraceSnapshotBuilder();\n\n        thread0 = new Thread(\"Test thread 0\");\n        thread1 = new Thread(\"Test thread 1\");\n        thread2 = new Thread(\"Test thread 2\");\n        \n        stack0 = new java.lang.management.ThreadInfo[] {\n                createThreadInfo(thread0, elements0),\n                createThreadInfo(thread1, elements0)\n        };\n\n        stackPlus = new java.lang.management.ThreadInfo[] {\n                createThreadInfo(thread0, elementsPlus),\n                createThreadInfo(thread1, elements0),\n                createThreadInfo(thread2, elements0)\n        };\n\n        stackMinus = new java.lang.management.ThreadInfo[] {\n                createThreadInfo(thread0, elementsMinus)\n        };\n\n        stackDif = new java.lang.management.ThreadInfo[] {\n                createThreadInfo(thread0, elementsDif)\n        };\n\n        stackDup = new java.lang.management.ThreadInfo[] {\n                createThreadInfo(thread0, elementsDup),\n                createThreadInfo(thread1, elements0)\n        };\n\n    }\n\n    @After\n    public void tearDown() {\n        instance = null;\n    }\n\n    /**\n     * Test of createSnapshot method, of class StackTraceSnapshotBuilder.\n     * Empty data\n     */\n    @Test\n    public void testCreateSnapshotEmpty() {\n        System.out.println(\"create snapshot : empty\");\n\n        try {\n            instance.createSnapshot(System.currentTimeMillis());\n            fail(\"Attempt to create an empty snapshot should throw NoDataAvailableException\");\n        } catch (CPUResultsSnapshot.NoDataAvailableException ex) {\n        }\n    }\n\n    @Test\n    public void testCreateSnapshotOneSample() throws CPUResultsSnapshot.NoDataAvailableException {\n        System.out.println(\"create snapshot : one sample\");\n\n        instance.addStacktrace(stack0, 0);\n        CPUResultsSnapshot snapshot = instance.createSnapshot(System.currentTimeMillis());\n        assertTrue(snapshot.collectingTwoTimeStamps);\n        assertEquals(instance.methodInfos.size(), snapshot.nInstrMethods);\n    }\n\n    @Test\n    public void testCreateSnapshotNoChanges() throws CPUResultsSnapshot.NoDataAvailableException {\n        System.out.println(\"create snapshot : two samples\");\n\n        instance.addStacktrace(stack0, 0);\n        instance.addStacktrace(stack0, 500000);\n\n        CPUResultsSnapshot snapshot = instance.createSnapshot(System.currentTimeMillis());\n        assertTrue(snapshot.collectingTwoTimeStamps);\n        assertEquals(instance.methodInfos.size(), snapshot.nInstrMethods);\n    }\n\n    @Test\n    public void testCreateSnapshotMinus() throws CPUResultsSnapshot.NoDataAvailableException {\n        System.out.println(\"create snapshot : minus\");\n\n        instance.addStacktrace(stack0, 0);\n        instance.addStacktrace(stackMinus, 500000);\n\n        CPUResultsSnapshot snapshot = instance.createSnapshot(System.currentTimeMillis());\n        assertTrue(snapshot.collectingTwoTimeStamps);\n        assertEquals(instance.methodInfos.size(), snapshot.nInstrMethods);\n    }\n\n    @Test\n    public void testCreateSnapshotPlus() throws CPUResultsSnapshot.NoDataAvailableException {\n        System.out.println(\"create snapshot : plus\");\n\n        instance.addStacktrace(stack0, 0);\n        instance.addStacktrace(stackPlus, 500000);\n\n        CPUResultsSnapshot snapshot = instance.createSnapshot(System.currentTimeMillis());\n        assertTrue(snapshot.collectingTwoTimeStamps);\n        assertEquals(instance.methodInfos.size(), snapshot.nInstrMethods);\n    }\n\n    @Test\n    public void testCreateSnapshotPlusMinus() throws CPUResultsSnapshot.NoDataAvailableException {\n        System.out.println(\"create snapshot : plus->minus\");\n\n        instance.addStacktrace(stack0, 0);\n        instance.addStacktrace(stackPlus, 500000);\n        instance.addStacktrace(stackMinus, 1000000);\n\n        CPUResultsSnapshot snapshot = instance.createSnapshot(System.currentTimeMillis());\n        assertTrue(snapshot.collectingTwoTimeStamps);\n        assertEquals(instance.methodInfos.size(), snapshot.nInstrMethods);\n    }\n\n    @Test\n    public void testCreateSnapshotMinusPlus() throws CPUResultsSnapshot.NoDataAvailableException {\n        System.out.println(\"create snapshot : minus->plus\");\n\n        instance.addStacktrace(stack0, 0);\n        instance.addStacktrace(stackMinus, 500000);\n        instance.addStacktrace(stackPlus, 1000000);\n\n        CPUResultsSnapshot snapshot = instance.createSnapshot(System.currentTimeMillis());\n        assertTrue(snapshot.collectingTwoTimeStamps);\n        assertEquals(instance.methodInfos.size(), snapshot.nInstrMethods);\n    }\n\n    @Test\n    public void testCreateSnapshotDup() throws CPUResultsSnapshot.NoDataAvailableException {\n        System.out.println(\"create snapshot : dup\");\n\n        instance.addStacktrace(stack0, 0);\n        instance.addStacktrace(stackDup, 500000);\n\n        CPUResultsSnapshot snapshot = instance.createSnapshot(System.currentTimeMillis());\n        assertTrue(snapshot.collectingTwoTimeStamps);\n        assertEquals(instance.methodInfos.size(), snapshot.nInstrMethods);\n        CPUCCTContainer container = snapshot.getContainerForThread((int) stack0[0].getThreadId(), CPUResultsSnapshot.METHOD_LEVEL_VIEW);\n        assertEquals(container.getThreadName(),thread0.getName());\n        PrestimeCPUCCTNode root = container.getRootNode();\n        assertEquals(1, root.getNCalls());\n        CCTNode[] childrens = root.getChildren();\n        assertEquals(1, childrens.length);\n        PrestimeCPUCCTNode ch = (PrestimeCPUCCTNode) childrens[0];\n        assertEquals(\"test.Class1.method1()\", ch.getNodeName());\n        assertEquals(1, ch.getNCalls());\n        CCTNode[] childrens1 = ch.getChildren();\n        assertEquals(2, childrens1.length);\n        PrestimeCPUCCTNode ch1 = (PrestimeCPUCCTNode) childrens1[0];\n        if (ch1.isSelfTimeNode()) {\n            ch1 = (PrestimeCPUCCTNode) childrens1[1];\n        }\n        assertEquals(\"test.Class1.method2()\", ch1.getNodeName());\n        assertEquals(1, ch1.getNCalls());\n        CCTNode[] childrens2 = ch1.getChildren();\n        assertEquals(2, childrens2.length);\n        PrestimeCPUCCTNode ch2 = (PrestimeCPUCCTNode) childrens2[0];\n        if (ch2.isSelfTimeNode()) {\n            ch2 = (PrestimeCPUCCTNode) childrens2[1];\n        }\n        assertEquals(\"test.Class1.method3()\", ch2.getNodeName());\n        assertEquals(2, ch2.getNCalls());\n    }\n\n    @Test\n    public void testAddStacktrace() {\n        System.out.println(\"add stacktrace\");\n\n        instance.addStacktrace(stack0, 0);\n        assertTrue(instance.methodInfos.size()-1  == elements0.length);\n        assertTrue(instance.threadIds.size() == stack0.length);\n        assertTrue(instance.threadNames.size() == stack0.length);\n        assertFalse(-1L == instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktraceDuplicate() {\n        System.out.println(\"add stacktrace : duplicate\");\n\n        long stamp = 0;\n        instance.addStacktrace(stack0, stamp);\n\n        int miSize = instance.methodInfos.size()-1;\n        int tIdSize = instance.threadIds.size();\n        long timestamp = instance.currentDumpTimeStamp;\n\n        instance.addStacktrace(stack0, stamp);\n        assertTrue(instance.stackTraceCount == 1);\n\n    }\n\n    @Test\n    public void testAddStacktracePlus() {\n        System.out.println(\"add stacktrace : plus\");\n\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n\n        instance.addStacktrace(stackPlus, timestamp);\n\n        assertEquals(Math.max(stack0.length, stackPlus.length), instance.threadIds.size());\n        assertEquals(Math.max(elements0.length, elementsPlus.length), instance.methodInfos.size()-1);\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktracePlusWaiting() {\n        System.out.println(\"add stacktrace : plus/waiting\");\n\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n        setState(stackPlus[0],Thread.State.WAITING);\n\n        instance.addStacktrace(stackPlus, timestamp);\n\n        assertEquals(Math.max(stack0.length, stackPlus.length), instance.threadIds.size());\n        assertEquals(Math.max(elements0.length, elementsPlus.length), instance.methodInfos.size()-1);\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktracePlusWaitingThread() {\n        System.out.println(\"add stacktrace : plus/waiting; additional thread\");\n\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n        setState(stackPlus[2],Thread.State.WAITING);\n\n        instance.addStacktrace(stackPlus, timestamp);\n\n        assertEquals(Math.max(stack0.length, stackPlus.length), instance.threadIds.size());\n        assertEquals(Math.max(elements0.length, elementsPlus.length), instance.methodInfos.size()-1);\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktraceWaitingPlus() {\n        System.out.println(\"add stacktrace : waiting/plus\");\n\n        setState(stack0[0],Thread.State.WAITING);\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n        setState(stackPlus[2],Thread.State.RUNNABLE);\n\n        instance.addStacktrace(stackPlus, timestamp);\n\n        assertEquals(Math.max(stack0.length, stackPlus.length), instance.threadIds.size());\n        assertEquals(Math.max(elements0.length, elementsPlus.length), instance.methodInfos.size()-1);\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktraceMinus() {\n        System.out.println(\"add stacktrace : minus\");\n\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n\n        instance.addStacktrace(stackMinus, timestamp);\n\n        assertEquals(Math.max(stack0.length, stackMinus.length), instance.threadIds.size());\n        assertEquals(Math.max(elements0.length, elementsMinus.length), instance.methodInfos.size()-1);\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktraceMinusWaiting() {\n        System.out.println(\"add stacktrace : minus/waiting\");\n\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n        setState(stackMinus[0], Thread.State.WAITING);\n        instance.addStacktrace(stackMinus, timestamp);\n\n        assertEquals(Math.max(stack0.length, stackMinus.length), instance.threadIds.size());\n        assertEquals(Math.max(elements0.length, elementsMinus.length), instance.methodInfos.size()-1);\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktraceMinusWaitingThread() {\n        System.out.println(\"add stacktrace : minus/waiting; additional thread\");\n\n        setState(stack0[1], Thread.State.WAITING);\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n        setState(stackMinus[0], Thread.State.WAITING);\n        instance.addStacktrace(stackMinus, timestamp);\n\n        assertEquals(Math.max(stack0.length, stackMinus.length), instance.threadIds.size());\n        assertEquals(Math.max(elements0.length, elementsMinus.length), instance.methodInfos.size()-1);\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktraceWaitingMinus() {\n        System.out.println(\"add stacktrace : waiting/minus\");\n\n        setState(stack0[0], Thread.State.WAITING);\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n        setState(stackMinus[0], Thread.State.RUNNABLE);\n        instance.addStacktrace(stackMinus, timestamp);\n\n        assertEquals(Math.max(stack0.length, stackMinus.length), instance.threadIds.size());\n        assertEquals(Math.max(elements0.length, elementsMinus.length), instance.methodInfos.size()-1);\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktraceDif() {\n        System.out.println(\"add stacktrace : diff\");\n\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n\n        instance.addStacktrace(stackDif, timestamp);\n\n        assertEquals(Math.max(stack0.length, stackDif.length), instance.threadIds.size());\n        for(StackTraceElement element : elements0) {\n            if (!instance.methodInfos.contains(new StackTraceSnapshotBuilder.MethodInfo(element))) {\n                fail();\n            }\n        }\n        for(StackTraceElement element : elementsDif) {\n            if (!instance.methodInfos.contains(new StackTraceSnapshotBuilder.MethodInfo(element))) {\n                fail();\n            }\n        }\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktraceDifWaiting() {\n        System.out.println(\"add stacktrace : diff/waiting\");\n\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n        setState(stackDif[0], Thread.State.WAITING);\n        \n        instance.addStacktrace(stackDif, timestamp);\n\n        assertEquals(Thread.State.WAITING, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n\n        assertEquals(Math.max(stack0.length, stackDif.length), instance.threadIds.size());\n        for(StackTraceElement element : elements0) {\n            if (!instance.methodInfos.contains(new StackTraceSnapshotBuilder.MethodInfo(element))) {\n                fail();\n            }\n        }\n        for(StackTraceElement element : elementsDif) {\n            if (!instance.methodInfos.contains(new StackTraceSnapshotBuilder.MethodInfo(element))) {\n                fail();\n            }\n        }\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktraceDifWaitingBlocked() {\n        System.out.println(\"add stacktrace : diff/waiting/blocked\");\n\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n        setState(stackDif[0], Thread.State.WAITING);\n\n        instance.addStacktrace(stackDif, timestamp);\n\n        setState(stack0[0], Thread.State.BLOCKED);\n\n        timestamp += 500000;\n\n        instance.addStacktrace(stack0, timestamp);\n\n        assertEquals(Thread.State.BLOCKED, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n\n        assertEquals(Math.max(stack0.length, stackDif.length), instance.threadIds.size());\n        for(StackTraceElement element : elements0) {\n            if (!instance.methodInfos.contains(new StackTraceSnapshotBuilder.MethodInfo(element))) {\n                fail();\n            }\n        }\n        for(StackTraceElement element : elementsDif) {\n            if (!instance.methodInfos.contains(new StackTraceSnapshotBuilder.MethodInfo(element))) {\n                fail();\n            }\n        }\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktraceDifBlockedWaiting() {\n        System.out.println(\"add stacktrace : diff/blocked/waiting\");\n\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n        setState(stackDif[0], Thread.State.BLOCKED);\n\n        instance.addStacktrace(stackDif, timestamp);\n\n        setState(stack0[0], Thread.State.WAITING);\n\n        timestamp += 500000;\n\n        instance.addStacktrace(stack0, timestamp);\n\n        assertEquals(Thread.State.WAITING, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n\n        assertEquals(Math.max(stack0.length, stackDif.length), instance.threadIds.size());\n        for(StackTraceElement element : elements0) {\n            if (!instance.methodInfos.contains(new StackTraceSnapshotBuilder.MethodInfo(element))) {\n                fail();\n            }\n        }\n        for(StackTraceElement element : elementsDif) {\n            if (!instance.methodInfos.contains(new StackTraceSnapshotBuilder.MethodInfo(element))) {\n                fail();\n            }\n        }\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktraceWaitingDif() {\n        System.out.println(\"add stacktrace : waiting/diff\");\n\n        setState(stack0[0], Thread.State.WAITING);\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n\n\n        instance.addStacktrace(stackDif, timestamp);\n\n        assertEquals(Math.max(stack0.length, stackDif.length), instance.threadIds.size());\n        for(StackTraceElement element : elements0) {\n            if (!instance.methodInfos.contains(new StackTraceSnapshotBuilder.MethodInfo(element))) {\n                fail();\n            }\n        }\n        for(StackTraceElement element : elementsDif) {\n            if (!instance.methodInfos.contains(new StackTraceSnapshotBuilder.MethodInfo(element))) {\n                fail();\n            }\n        }\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStacktraceWaitingDifRunnable() {\n        System.out.println(\"add stacktrace : waiting/diff/runnable\");\n\n        setState(stack0[0], Thread.State.WAITING);\n        instance.addStacktrace(stack0, 0);\n\n        long timestamp = 500000;\n\n        setState(stackDif[0], Thread.State.RUNNABLE);\n        instance.addStacktrace(stackDif, timestamp);\n\n        assertEquals(Math.max(stack0.length, stackDif.length), instance.threadIds.size());\n        for(StackTraceElement element : elements0) {\n            if (!instance.methodInfos.contains(new StackTraceSnapshotBuilder.MethodInfo(element))) {\n                fail();\n            }\n        }\n        for(StackTraceElement element : elementsDif) {\n            if (!instance.methodInfos.contains(new StackTraceSnapshotBuilder.MethodInfo(element))) {\n                fail();\n            }\n        }\n        assertEquals(timestamp, instance.currentDumpTimeStamp);\n    }\n\n    @Test\n    public void testAddStackTraceNew() {\n        System.out.println(\"add stacktrace : new\");\n\n        setState(stack0[0], Thread.State.NEW);\n\n        try {\n            instance.addStacktrace(stack0, 500000);\n            assertFalse(instance.threadNames.contains(stack0[0].getThreadName()));\n        } catch (IllegalStateException ex) {}\n    }\n\n    @Test\n    public void testAddStackTraceWasTerminated() {\n        System.out.println(\"add stacktrace : terminated->runnable\");\n\n        setState(stack0[0], Thread.State.TERMINATED);\n\n        try {\n            instance.addStacktrace(stack0, 0);\n            setState(stack0[0], Thread.State.RUNNABLE);\n            instance.addStacktrace(stack0, 500000);\n            fail();\n        } catch (IllegalStateException ex) {}\n    }\n\n\n    @Test\n    public void testAddStackTraceRunnable() {\n        System.out.println(\"add stacktrace : runnable\");\n\n        setState(stack0[0], Thread.State.RUNNABLE);\n\n        instance.addStacktrace(stack0, 500000);\n\n        assertEquals(500000, instance.currentDumpTimeStamp);\n        assertEquals(Thread.State.RUNNABLE, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n    }\n\n    @Test\n    public void testAddStackTraceWaiting() {\n        System.out.println(\"add stacktrace : waiting\");\n\n        setState(stack0[0], Thread.State.WAITING);\n\n        instance.addStacktrace(stack0, 500000);\n\n        assertEquals(500000, instance.currentDumpTimeStamp);\n        assertEquals(Thread.State.WAITING, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n    }\n\n    @Test\n    public void testAddStackTraceTimedWaiting() {\n        System.out.println(\"add stacktrace : timed waiting\");\n\n        setState(stack0[0], Thread.State.TIMED_WAITING);\n\n        instance.addStacktrace(stack0, 500000);\n\n        assertEquals(500000, instance.currentDumpTimeStamp);\n        assertEquals(Thread.State.TIMED_WAITING, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n    }\n\n    @Test\n    public void testAddStackTraceBlocked() {\n        System.out.println(\"add stacktrace : blocked\");\n\n        setState(stack0[0], Thread.State.BLOCKED);\n\n        instance.addStacktrace(stack0, 500000);\n\n        assertEquals(500000, instance.currentDumpTimeStamp);\n        assertEquals(Thread.State.BLOCKED, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n    }\n\n    @Test\n    public void testAddStackTraceTerminated() {\n        System.out.println(\"add stacktrace : terminated\");\n\n        setState(stack0[0], Thread.State.TERMINATED);\n\n        instance.addStacktrace(stack0, 500000);\n\n        assertEquals(500000, instance.currentDumpTimeStamp);\n        assertEquals(Thread.State.TERMINATED, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n    }\n\n    @Test\n    public void testAddStackTraceWaitRun() {\n        System.out.println(\"add stacktrace : wait->run\");\n\n        instance.addStacktrace(stack0, 0);\n        setState(stack0[0], Thread.State.WAITING);\n        \n        instance.addStacktrace(stack0, 500000);\n\n        assertEquals(500000, instance.currentDumpTimeStamp);\n        assertEquals(Thread.State.WAITING, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n\n        setState(stack0[0], Thread.State.RUNNABLE);\n        instance.addStacktrace(stack0, 1000000);\n\n        assertEquals(1000000, instance.currentDumpTimeStamp);\n        assertEquals(Thread.State.RUNNABLE, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n    }\n\n    @Test\n    public void testAddStackTraceWaitWait() {\n        System.out.println(\"add stacktrace : wait->wait\");\n\n        instance.addStacktrace(stack0, 0);\n        setState(stack0[0], Thread.State.WAITING);\n\n        instance.addStacktrace(stack0, 500000);\n\n        assertEquals(500000, instance.currentDumpTimeStamp);\n        assertEquals(Thread.State.WAITING, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n        instance.addStacktrace(stack0, 1000000);\n\n        assertEquals(1000000, instance.currentDumpTimeStamp);\n        assertEquals(Thread.State.WAITING, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n    }\n\n    @Test\n    public void testAddStackTraceWaitBlocked() {\n        System.out.println(\"add stacktrace : wait->blocked\");\n\n        instance.addStacktrace(stack0, 0);\n        setState(stack0[0], Thread.State.WAITING);\n\n        instance.addStacktrace(stack0, 500000);\n\n        assertEquals(500000, instance.currentDumpTimeStamp);\n        assertEquals(Thread.State.WAITING, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n        setState(stack0[0], Thread.State.BLOCKED);\n        instance.addStacktrace(stack0, 1000000);\n\n        assertEquals(1000000, instance.currentDumpTimeStamp);\n        assertEquals(Thread.State.BLOCKED, instance.lastStackTrace.get().get(thread0.getId()).getThreadState());\n    }\n\n\n\n    @Test\n    public void testReset() {\n        System.out.println(\"reset\");\n        ThreadMXBean tbean = ManagementFactory.getThreadMXBean();\n        instance.addStacktrace(tbean.getThreadInfo(tbean.getAllThreadIds(), Integer.MAX_VALUE), System.nanoTime());\n        instance.addStacktrace(tbean.getThreadInfo(tbean.getAllThreadIds(), Integer.MAX_VALUE), System.nanoTime());\n\n        instance.reset();\n        assertTrue(instance.methodInfos.size()-1 == 0);\n        assertTrue(instance.threadIds.isEmpty());\n        assertTrue(instance.threadNames.isEmpty());\n        assertEquals(-1L, instance.currentDumpTimeStamp);\n        //assertEquals(-1L, instance.firstDumpTimeStamp);\n        assertEquals(0, instance.stackTraceCount);\n\n        try {\n            instance.createSnapshot(System.currentTimeMillis());\n            fail();\n        } catch (CPUResultsSnapshot.NoDataAvailableException ex) {\n        }\n    }\n\n    @Test\n    public void testIgnoredThreadName() {\n        System.out.println(\"ignored thread name\");\n\n        String ignoredThread = \"Thread 0\";\n        instance.setIgnoredThreads(Collections.singleton(ignoredThread));\n\n        instance.addStacktrace(stack0, 0);\n        assertFalse(instance.threadNames.contains(ignoredThread));\n    }\n\n    private java.lang.management.ThreadInfo createThreadInfo(Thread t, StackTraceElement[] stack) {\n        try {\n            Constructor tinfoConstructor = java.lang.management.ThreadInfo.class.getDeclaredConstructor(\n                    Thread.class,Integer.TYPE,Object.class,Thread.class,Long.TYPE,Long.TYPE,\n                    Long.TYPE,Long.TYPE,StackTraceElement[].class);\n            tinfoConstructor.setAccessible(true);\n            ThreadInfo tinfo =  (ThreadInfo) tinfoConstructor.newInstance(t,0,null,null,0,0,0,0,stack);\n            setState(tinfo,State.RUNNABLE);\n            return tinfo;\n        } catch (NoSuchMethodException ex) {\n            Logger.getLogger(StackTraceSnapshotBuilderTest.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);\n        } catch (InstantiationException ex) {\n            Logger.getLogger(StackTraceSnapshotBuilderTest.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);\n        } catch (IllegalAccessException ex) {\n            Logger.getLogger(StackTraceSnapshotBuilderTest.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);\n        } catch (IllegalArgumentException ex) {\n            Logger.getLogger(StackTraceSnapshotBuilderTest.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);\n        } catch (InvocationTargetException ex) {\n            Logger.getLogger(StackTraceSnapshotBuilderTest.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);\n        }\n        return null;\n    }\n\n    private void setState(java.lang.management.ThreadInfo tinfo, State s) {\n        try {\n            Field tstateField = tinfo.getClass().getDeclaredField(\"threadState\");\n            tstateField.setAccessible(true);\n            tstateField.set(tinfo, s);\n        } catch (IllegalArgumentException ex) {\n            Logger.getLogger(StackTraceSnapshotBuilderTest.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (IllegalAccessException ex) {\n            Logger.getLogger(StackTraceSnapshotBuilderTest.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (NoSuchFieldException ex) {\n            Logger.getLogger(StackTraceSnapshotBuilderTest.class.getName()).log(Level.SEVERE, null, ex);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/unit/src/org/graalvm/visualvm/lib/jfluid/utils/VMUtilsTest.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils;\n\nimport junit.framework.TestCase;\n\n\n/**\n * TestCase for Method Name formatter class.\n *\n * @author Ian Formanek\n */\npublic final class VMUtilsTest extends TestCase {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final String[] patternSourcesAndResults = {\n                                                                 // primitive types\n    \"int\", \"I\", \"byte\", \"B\", \"char\", \"C\", \"double\", \"D\", \"float\", \"F\", \"boolean\", \"Z\", \"long\", \"J\", \"short\", \"S\", \"void\", \"V\",\n                                                                 // class type\n    \"java.lang.String\", \"Ljava/lang/String;\", \"ClassInDefaultPackage\", \"LClassInDefaultPackage;\", \"foo.bar.Class$InnerClass\",\n                                                                 \"Lfoo/bar/Class$InnerClass;\", // arrays\n    \"int[]\", \"[I\", \"byte[][]\", \"[[B\", \"char[][][]\", \"[[[C\", \"double[][][][]\", \"[[[[D\", \"java.lang.String[]\", \"[Ljava/lang/String;\",\n                                                                 \"ClassInDefaultPackage[][]\", \"[[LClassInDefaultPackage;\",\n                                                                 \"foo.bar.Class$InnerClass[][][]\", \"[[[Lfoo/bar/Class$InnerClass;\",\n                                                                 // special cases\n    \"java.awt.Point\", \"Ljava/awt/Point;\", // tricky, as it contains String \"int\" inside\n                                                             };\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Test to ensure that the formatting of test methods is as expected.\n     */\n    public void testFormatting() {\n        for (int i = 0; i < patternSourcesAndResults.length; i += 2) {\n            assertEquals(\"Wrong results for \" + i, patternSourcesAndResults[i + 1],\n                         VMUtils.typeToVMSignature(patternSourcesAndResults[i]));\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler/test/unit/src/org/graalvm/visualvm/lib/jfluid/utils/formatting/PlainFormattableMethodNameTest.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.utils.formatting;\n\nimport junit.framework.TestCase;\n\n\n/**\n * TestCase for Method Name formatter class.\n *\n * @author Ian Formanek\n */\npublic final class PlainFormattableMethodNameTest extends TestCase {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final String[] patternSources = {\n                                                       \"java/lang/String\", \"concat\", \"(Ljava.lang.String;)Ljava.lang.String;\",\n                                                       \"java/lang/String\", \"getBytes\", \"()[B\", \"classNameInDefaultPackage\", \"doIt\",\n                                                       \"()V\", \"foo/bar/LongArrays\", \"createArray\", \"([[[[[[[[I)[[[[[[[[[F\",\n                                                       \"foo/bar/Constr\", \"\", \"()V\", \"foo/bar/Constr\", \"<init>\", \"()V\",\n                                                       \"foo/bar/Constr\", null, null, \"foo/bar/Constr\", \"<clinit>\", null,\n                                                   };\n    private static final String[] patternResults = {\n                                                       \"java.lang.String\", // formattedClass\n    \"java.lang.String.concat(java.lang.String)\", // formattedClassAndMethod\n    \"concat(java.lang.String)\", // formattedMethod\n    \"java.lang.String.concat(java.lang.String) : java.lang.String\", // fullFormattedClassAndMethod\n    \"concat(java.lang.String) : java.lang.String\", // fullFormattedMethod\n    \"java.lang.String\", // paramsString\n    \"java.lang.String\", // returnType\n    \"java.lang.String\", // formattedClass\n    \"java.lang.String.getBytes()\", // formattedClassAndMethod\n    \"getBytes()\", // formattedMethod\n    \"java.lang.String.getBytes() : byte[]\", // fullFormattedClassAndMethod\n    \"getBytes() : byte[]\", // fullFormattedMethod\n    \"\", // paramsString\n    \"byte[]\", // returnType\n    \"classNameInDefaultPackage\", // formattedClass\n    \"classNameInDefaultPackage.doIt()\", // formattedClassAndMethod\n    \"doIt()\", // formattedMethod\n    \"classNameInDefaultPackage.doIt() : void\", // fullFormattedClassAndMethod\n    \"doIt() : void\", // fullFormattedMethod\n    \"\", // paramsString\n    \"void\", // returnType\n    \"foo.bar.LongArrays\", // formattedClass\n    \"foo.bar.LongArrays.createArray(int[][][][][][][][])\", // formattedClassAndMethod\n    \"createArray(int[][][][][][][][])\", // formattedMethod\n    \"foo.bar.LongArrays.createArray(int[][][][][][][][]) : float[][][][][][][][][]\", // fullFormattedClassAndMethod\n    \"createArray(int[][][][][][][][]) : float[][][][][][][][][]\", // fullFormattedMethod\n    \"int[][][][][][][][]\", // paramsString\n    \"float[][][][][][][][][]\", // returnType\n    \"foo.bar.Constr\", // formattedClass\n    \"foo.bar.Constr\", // formattedClassAndMethod\n    \"\", // formattedMethod\n    \"foo.bar.Constr\", // fullFormattedClassAndMethod\n    \"\", // fullFormattedMethod\n    \"\", // paramsString\n    \"\", // returnType\n    \"foo.bar.Constr\", // formattedClass\n    \"foo.bar.Constr.<init>()\", // formattedClassAndMethod\n    \"<init>()\", // formattedMethod\n    \"foo.bar.Constr.<init>()\", // fullFormattedClassAndMethod\n    \"<init>()\", // fullFormattedMethod\n    \"\", // paramsString\n    \"\", // returnType\n    \"foo.bar.Constr\", // formattedClass\n    \"foo.bar.Constr\", // formattedClassAndMethod\n    \"\", // formattedMethod\n    \"foo.bar.Constr\", // fullFormattedClassAndMethod\n    \"\", // fullFormattedMethod\n    \"\", // paramsString\n    \"\", // returnType\n    \"foo.bar.Constr\", // formattedClass\n    \"foo.bar.Constr.<clinit>()\", // formattedClassAndMethod\n    \"<clinit>()\", // formattedMethod\n    \"foo.bar.Constr.<clinit>()\", // fullFormattedClassAndMethod\n    \"<clinit>()\", // fullFormattedMethod\n    \"\", // paramsString\n    \"\", // returnType\n                                                   };\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Test to ensure that the formatting of test methods is as expected.\n     */\n    public void testFormatting() {\n        PlainFormattableMethodName mnf;\n\n        int count = 0;\n\n        for (int i = 0; (i + 2) < patternSources.length; i += 3) {\n            mnf = new PlainFormattableMethodName(patternSources[i], patternSources[i + 1], patternSources[i + 2], 0);\n\n            assertEquals(\"Wrong results for getFormattedClass \" + mnf, patternResults[count++], mnf.getFormattedClass());\n            assertEquals(\"Wrong results for getFormattedClassAndMethod \" + mnf, patternResults[count++],\n                         mnf.getFormattedClassAndMethod());\n            assertEquals(\"Wrong results for getFormattedMethod \" + mnf, patternResults[count++], mnf.getFormattedMethod());\n            assertEquals(\"Wrong results for getFullFormattedClassAndMethod \" + mnf, patternResults[count++],\n                         mnf.getFullFormattedClassAndMethod());\n            assertEquals(\"Wrong results for getFullFormattedMethod \" + mnf, patternResults[count++], mnf.getFullFormattedMethod());\n            assertEquals(\"Wrong results for getParamsString \" + mnf, patternResults[count++], mnf.getParamsString());\n            assertEquals(\"Wrong results for getReturnType \" + mnf, patternResults[count++], mnf.getReturnTypeX());\n        }\n    }\n\n    protected void setUp() throws Exception {\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project basedir=\".\" default=\"netbeans\" name=\"lib.profiler.charts\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.lib.charts</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.lib.charts/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/lib/charts/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.1\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.lib.charts-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/nbproject/genfiles.properties",
    "content": "# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=e03b2166\nnbproject/build-impl.xml.script.CRC32=87fe86bc\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/nbproject/project.properties",
    "content": "# Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nis.autoload=true\njavac.source=1.8\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.lib.charts</code-name-base>\n            <suite-component/>\n            <module-dependencies/>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.charts</friend>\n                <friend>org.graalvm.visualvm.modules.tracer</friend>\n                <friend>org.graalvm.visualvm.lib.ui</friend>\n                <friend>org.graalvm.visualvm.lib.profiler</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.snaptracer</friend>\n                <package>org.graalvm.visualvm.lib.charts</package>\n                <package>org.graalvm.visualvm.lib.charts.axis</package>\n                <package>org.graalvm.visualvm.lib.charts.canvas</package>\n                <package>org.graalvm.visualvm.lib.charts.swing</package>\n                <package>org.graalvm.visualvm.lib.charts.xy</package>\n                <package>org.graalvm.visualvm.lib.charts.xy.synchronous</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/../..\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Name=Java Profiler (Charts)\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ChartComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.canvas.InteractiveCanvasComponent;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport java.awt.RenderingHints;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ChartComponent extends InteractiveCanvasComponent {\n\n    private RenderingHints renderingHints;\n\n    private List<ChartDecorator> preDecorators;\n    private List<ChartDecorator> postDecorators;\n\n    private ItemsModel itemsModel;\n    private PaintersModel paintersModel;\n\n    protected LongRect dataBounds;\n    private LongRect initialDataBounds;\n    private ChartContext chartContext;\n\n    private ItemsModelListener itemsListener;\n    private PaintersModelListener paintersListener;\n\n    private List<ChartOverlay> overlays;\n\n    private ChartSelectionModel selectionModel;\n    private SelectionListener selectionListener;\n\n    private List<ChartConfigurationListener> configurationListeners;\n\n\n    public ChartComponent() {\n        initRenderingHints();\n\n        itemsListener = new ItemsModelListener();\n        paintersListener = new PaintersModelListener();\n\n        dataBounds = new LongRect();\n        initialDataBounds = new LongRect();\n\n        setLayout(null);\n\n        setSelectionModel(new ChartSelectionManager());\n    }\n\n\n    // --- Models --------------------------------------------------------------\n\n    public final void setItemsModel(ItemsModel itemsModel) {\n        if (itemsModel == null) throw new IllegalArgumentException(\"ItemsModel cannot be null\");\n        if (itemsModel == this.itemsModel) return;\n\n        if (this.itemsModel != null) this.itemsModel.removeItemsListener(itemsListener);\n\n        this.itemsModel = itemsModel;\n        this.itemsModel.addItemsListener(itemsListener);\n\n        updateChart();\n    }\n\n    public final ItemsModel getItemsModel() {\n        return itemsModel;\n    }\n\n    public final void setPaintersModel(PaintersModel paintersModel) {\n        if (paintersModel == null) throw new IllegalArgumentException(\"PaintersModel cannot be null\");\n        if (paintersModel == this.paintersModel) return;\n\n        if (this.paintersModel != null) this.paintersModel.removePaintersListener(paintersListener);\n\n        this.paintersModel = paintersModel;\n        this.paintersModel.addPaintersListener(paintersListener);\n\n        updateChart();\n    }\n\n    public final PaintersModel getPaintersModel() {\n        return paintersModel;\n    }\n\n    public final void setSelectionModel(ChartSelectionModel selectionModel) {\n        // Cleanup previous model\n        if (this.selectionModel != null) {\n            this.selectionModel.removeSelectionListener(selectionListener);\n            if (this.selectionModel instanceof ChartSelectionManager)\n                ((ChartSelectionManager)this.selectionModel).unregisterChart(this);\n        }\n\n        // Assign new model\n        this.selectionModel = selectionModel;\n\n        // Setup new model\n        if (selectionModel != null) {\n            if (selectionListener == null) selectionListener = new SelectionListener();\n            selectionModel.addSelectionListener(selectionListener);\n            if (selectionModel instanceof ChartSelectionManager)\n                ((ChartSelectionManager)selectionModel).registerChart(this);\n        } else {\n            selectionListener = null;\n        }\n    }\n\n    public final ChartSelectionModel getSelectionModel() {\n        return selectionModel;\n    }\n\n\n    // --- Initial data bounds -------------------------------------------------\n\n    public final void setInitialDataBounds(LongRect bounds) {\n        if (LongRect.equals(bounds, initialDataBounds)) return;\n        LongRect.set(initialDataBounds, bounds);\n        if (LongRect.isEmpty(dataBounds)) {\n            resizeChart();\n            invalidateImage();\n            repaintDirty();\n        }\n    }\n\n    public final LongRect getInitialDataBounds() {\n        return initialDataBounds;\n    }\n\n    // --- Customizable RenderingHints -----------------------------------------\n\n    public final void setRenderingHints(RenderingHints renderingHints) {\n        this.renderingHints = Utils.checkedRenderingHints(renderingHints);\n    }\n\n    public final RenderingHints getRenderingHints() {\n        return (RenderingHints)renderingHints.clone();\n    }\n\n    private void applyRenderingHints(Graphics2D g) {\n        if (renderingHints != null) g.setRenderingHints(renderingHints);\n    }\n\n    private void initRenderingHints() {\n        RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\n        hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);\n        setRenderingHints(hints);\n    }\n\n\n    // --- ChartContext --------------------------------------------------------\n\n    public final ChartContext getChartContext() {\n        return getChartContext(null);\n    }\n\n    protected ChartContext getChartContext(ChartItem item) {\n        if (chartContext == null) chartContext = createChartContext();\n        return chartContext;\n    }\n\n    protected ChartContext createChartContext() {\n        return new Context(this);\n    }\n\n\n    // --- Configuration Listeners ---------------------------------------------\n\n    public final void addConfigurationListener(ChartConfigurationListener listener) {\n        if (configurationListeners == null) configurationListeners = new ArrayList<>();\n        configurationListeners.add(listener);\n    }\n\n    public final void removeConfigurationListener(ChartConfigurationListener listener) {\n        if (configurationListeners == null) return;\n        configurationListeners.remove(listener);\n    }\n\n\n    protected final void offsetChanged(long oldOffsetX, long oldOffsetY,\n                              long newOffsetX, long newOffsetY) {\n        super.offsetChanged(oldOffsetX, oldOffsetY, newOffsetX, newOffsetY);\n        fireOffsetChanged(oldOffsetX, oldOffsetY, newOffsetX, newOffsetY);\n    }\n\n    protected final void scaleChanged(double oldScaleX, double oldScaleY,\n                             double newScaleX, double newScaleY) {\n        super.scaleChanged(oldScaleX, oldScaleY, newScaleX, newScaleY);\n        fireScaleChanged(oldScaleX, oldScaleY, newScaleX, newScaleY);\n    }\n\n    protected final void dataBoundsChanged(long dataOffsetX, long dataOffsetY,\n                                  long dataWidth, long dataHeight,\n                                  long oldDataOffsetX, long oldDataOffsetY,\n                                  long oldDataWidth, long oldDataHeight) {\n        super.dataBoundsChanged(dataOffsetX, dataOffsetY, dataWidth, dataHeight,\n                                oldDataOffsetX, oldDataOffsetY, oldDataWidth, oldDataHeight);\n        fireDataBoundsChanged(dataOffsetX, dataOffsetY, dataWidth, dataHeight,\n                              oldDataOffsetX, oldDataOffsetY, oldDataWidth, oldDataHeight);\n    }\n\n    protected final void contentsWillBeUpdated(long offsetX, long offsetY,\n                               double scaleX, double scaleY,\n                               long lastOffsetX, long lastOffsetY,\n                               double lastScaleX, double lastScaleY) {\n        super.contentsWillBeUpdated(offsetX, offsetY, scaleX, scaleY, lastOffsetX,\n                          lastOffsetY, lastScaleX, lastScaleY);\n        fireContentsWillBeUpdated(offsetX, offsetY, scaleX, scaleY,\n                                  lastOffsetX, lastOffsetY, lastScaleX, lastScaleY);\n    }\n\n    protected final void contentsUpdated(long offsetX, long offsetY,\n                            double scaleX, double scaleY,\n                            long lastOffsetX, long lastOffsetY,\n                            double lastScaleX, double lastScaleY,\n                            int shiftX, int shiftY) {\n        super.contentsUpdated(offsetX, offsetY, scaleX, scaleY, lastOffsetX,\n                          lastOffsetY, lastScaleX, lastScaleY, shiftX, shiftY);\n        fireContentsUpdated(offsetX, offsetY, scaleX, scaleY, lastOffsetX, lastOffsetY,\n                        lastScaleX, lastScaleY, shiftX, shiftY);\n    }\n\n\n    private void fireOffsetChanged(long oldOffsetX, long oldOffsetY,\n                                   long newOffsetX, long newOffsetY) {\n        if (configurationListeners == null) return;\n        for (ChartConfigurationListener listener : configurationListeners)\n            listener.offsetChanged(oldOffsetX, oldOffsetY, newOffsetX, newOffsetY);\n    }\n\n    private void fireScaleChanged(double oldScaleX, double oldScaleY,\n                                  double newScaleX, double newScaleY) {\n        if (configurationListeners == null) return;\n        for (ChartConfigurationListener listener : configurationListeners)\n            listener.scaleChanged(oldScaleX, oldScaleY, newScaleX, newScaleY);\n    }\n\n    private void fireDataBoundsChanged(long dataOffsetX, long dataOffsetY,\n                                       long dataWidth, long dataHeight,\n                                       long oldDataOffsetX, long oldDataOffsetY,\n                                       long oldDataWidth, long oldDataHeight) {\n        if (configurationListeners == null) return;\n        for (ChartConfigurationListener listener : configurationListeners)\n            listener.dataBoundsChanged(dataOffsetX, dataOffsetY, dataWidth,\n                                       dataHeight, oldDataOffsetX, oldDataOffsetY,\n                                       oldDataWidth, oldDataHeight);\n    }\n\n    private void fireContentsWillBeUpdated(long offsetX, long offsetY,\n                            double scaleX, double scaleY,\n                            long lastOffsetX, long lastOffsetY,\n                            double lastScaleX, double lastScaleY) {\n        if (configurationListeners == null) return;\n        for (ChartConfigurationListener listener : configurationListeners)\n            listener.contentsWillBeUpdated(offsetX, offsetY, scaleX, scaleY,\n                              lastOffsetX, lastOffsetY, lastScaleX, lastScaleY);\n    }\n\n    private void fireContentsUpdated(long offsetX, long offsetY,\n                            double scaleX, double scaleY,\n                            long lastOffsetX, long lastOffsetY,\n                            double lastScaleX, double lastScaleY,\n                            int shiftX, int shiftY) {\n        if (configurationListeners == null) return;\n        for (ChartConfigurationListener listener : configurationListeners)\n            listener.contentsUpdated(offsetX, offsetY, scaleX, scaleY, lastOffsetX,\n                                 lastOffsetY, lastScaleX, lastScaleY, shiftX, shiftY);\n    }\n\n\n    // --- Pre & post painters support -----------------------------------------\n\n    public final void addPreDecorator(ChartDecorator decorator) {\n        if (preDecorators == null) preDecorators = new ArrayList<>(2);\n        preDecorators.add(decorator);\n    }\n\n    public final void removePreDecorator(ChartDecorator decorator) {\n        if (preDecorators != null) preDecorators.remove(decorator);\n    }\n\n    final List<ChartDecorator> getPreDecorators() {\n        return preDecorators;\n    }\n\n    public final void addPostDecorator(ChartDecorator decorator) {\n        if (postDecorators == null) postDecorators = new ArrayList<>(2);\n        postDecorators.add(decorator);\n    }\n\n    public final void removePostDecorator(ChartDecorator decorator) {\n        if (postDecorators != null) postDecorators.remove(decorator);\n    }\n\n    final List<ChartDecorator> getPostDecorators() {\n        return postDecorators;\n    }\n\n\n    // --- Overlays ------------------------------------------------------------\n\n    public final void addOverlayComponent(ChartOverlay overlay) {\n        if (overlays == null) overlays = new ArrayList<>();\n\n        overlay.setChartContext(getChartContext());\n\n        overlays.add(overlay);\n        add(overlay);\n    }\n\n    public final void removeOverlayComponent(ChartOverlay overlay) {\n        remove(overlay);\n        overlays.remove(overlay);\n\n        overlay.setChartContext(null);\n    }\n\n\n    protected void reshaped(Rectangle oldBounds, Rectangle newBounds) {\n        super.reshaped(oldBounds, newBounds);\n\n        if (overlays == null) return;\n\n        for (ChartOverlay overlay : overlays)\n            overlay.setBounds(0, 0, newBounds.width, newBounds.height);\n    }\n\n\n    // --- Paint implementation ------------------------------------------------\n\n    protected void paintContents(Graphics g, Rectangle invalidArea) {\n        Graphics2D g2 = (Graphics2D)g;\n\n        // Set clip\n        g2.setClip(invalidArea);\n\n        // Set rendering hints\n        applyRenderingHints(g2);\n\n        // Paint background if opaque\n        if (isOpaque()) {\n            g2.setColor(getBackground());\n            g2.fillRect(invalidArea.x, invalidArea.y,\n                       invalidArea.width, invalidArea.height);\n        }\n\n        // Paint registered prepainters\n        if (preDecorators != null)\n            for (ChartDecorator decorator : preDecorators)\n                decorator.paint(g2, invalidArea, getChartContext());\n\n        // Paint chart items\n        if (itemsModel != null && paintersModel != null) {\n            int itemsCount = itemsModel.getItemsCount();\n\n            if (itemsCount != 0) {\n                boolean sel = selectionModel != null;\n\n                List<ItemSelection> highlightedSelection = sel ? selectionModel.getHighlightedItems() : null;\n                List<ItemSelection> selectedSelection = sel ? selectionModel.getSelectedItems() : null;\n                List<ItemSelection> filteredHighlighted = sel ? new ArrayList<>() : Collections.emptyList();\n                List<ItemSelection> filteredSelected = sel ? new ArrayList<>() : Collections.emptyList();\n\n                for (int i = 0; i < itemsCount; i++) {\n                    ChartItem item = itemsModel.getItem(i);\n                    ItemPainter painter = paintersModel.getPainter(item);\n\n                    if (sel) {\n                        filteredHighlighted.clear();\n                        if (painter.supportsHovering(item))\n                            filterSelection(highlightedSelection, filteredHighlighted, item);\n                        filteredSelected.clear();\n                        if (painter.supportsSelecting(item))\n                            filterSelection(selectedSelection, filteredSelected, item);\n                    }\n\n                    painter.paintItem(item, filteredHighlighted, filteredSelected,\n                                      g2, invalidArea, getChartContext(item));\n                }\n            }\n        }\n\n        // Paint registered postpainters\n        if (postDecorators != null)\n            for (ChartDecorator decorator : postDecorators)\n                decorator.paint(g2, invalidArea, getChartContext());\n    }\n\n\n    private static void filterSelection(List<ItemSelection> selection, List<ItemSelection> result, ChartItem filter) {\n        if (filter == null) return;\n        for (ItemSelection sel : selection)\n            if (sel.getItem().equals(filter)) result.add(sel);\n    }\n\n\n    // --- UI tweaks -----------------------------------------------------------\n\n    public void setBackground(Color bg) {\n        super.setBackground(Utils.checkedColor(bg));\n    }\n\n\n    // --- Protected implementation ----------------------------------------------\n\n    protected void computeDataBounds() {\n        LongRect.clear(dataBounds);\n        if (itemsModel == null || paintersModel == null) return;\n\n        int itemsCount = itemsModel.getItemsCount();\n        for (int i = 0; i < itemsCount; i++) {\n            ChartItem item = itemsModel.getItem(i);\n            ItemPainter painter = paintersModel.getPainter(item);\n            if (i == 0)\n                LongRect.set(dataBounds, painter.getItemBounds(item));\n            else\n                LongRect.add(dataBounds, painter.getItemBounds(item));\n        }\n    }\n\n    protected void resizeChart() {\n        if (LongRect.isEmpty(dataBounds)) {\n            LongRect bounds = new LongRect(dataBounds);\n            if (bounds.width == 0) {\n                bounds.width = initialDataBounds.width;\n                if (bounds.x == 0) bounds.x = initialDataBounds.x;\n            }\n            if (bounds.height == 0) {\n                bounds.height = initialDataBounds.height;\n                if (bounds.y == 0) bounds.y = initialDataBounds.y;\n            }\n            setDataBounds(bounds.x, bounds.y, bounds.width, bounds.height);\n        } else {\n            setDataBounds(dataBounds.x, dataBounds.y, dataBounds.width, dataBounds.height);\n        }\n    }\n\n    protected void updateChart() {\n        computeDataBounds();\n        resizeChart();\n        invalidateImage();\n        repaintDirty();\n    }\n\n    protected void itemsAdded(List<ChartItem> addedItems) {\n        // Update chart size\n        LongRect oldBounds = new LongRect(dataBounds);\n        for (ChartItem item : addedItems) {\n            ItemPainter painter = paintersModel.getPainter(item);\n            LongRect.add(dataBounds, painter.getItemBounds(item));\n        }\n        if (!LongRect.equals(oldBounds, dataBounds)) resizeChart();\n\n        // Update chart appearance\n        LongRect uiBounds = null;\n        for (ChartItem item : addedItems) {\n            ItemPainter painter = paintersModel.getPainter(item);\n            if (uiBounds == null) uiBounds =\n                new LongRect(painter.getItemBounds(item, getChartContext(item)));\n            else\n                LongRect.add(uiBounds, painter.getItemBounds(item, getChartContext(item)));\n        }\n        invalidateImage(Utils.checkedRectangle(uiBounds));\n        repaintDirty();\n    }\n\n    protected void itemsRemoved(List<ChartItem> removedItems) {\n        List<ItemPainter> painters = new ArrayList<>(removedItems.size());\n\n        // Try to resolve painters for all removed items\n        for (ChartItem item : removedItems) {\n            ItemPainter painter = paintersModel.getPainter(item);\n            if (painter == null) {\n                painters = null;\n                break;\n            }\n            painters.add(painter);\n        }\n\n        if (painters == null) {\n            // Some or all painters for removed items not available\n            updateChart();\n        } else {\n            // All painters for removed items available\n\n            // Update chart size\n            LongRect oldBounds = new LongRect(dataBounds);\n            computeDataBounds();\n            if (!LongRect.equals(oldBounds, dataBounds)) resizeChart();\n\n            // Update chart appearance\n            LongRect uiBounds = null;\n            for (int i = 0; i < removedItems.size(); i++) {\n                ChartItem item = removedItems.get(i);\n                ItemPainter painter = painters.get(i);\n                if (uiBounds == null) uiBounds =\n                    new LongRect(painter.getItemBounds(item, getChartContext(item)));\n                else\n                    LongRect.add(uiBounds, painter.getItemBounds(item, getChartContext(item)));\n            }\n            invalidateImage(Utils.checkedRectangle(uiBounds));\n            repaintDirty();\n        }\n    }\n\n    protected void itemsChanged(List<ChartItemChange> itemChanges) {\n        // Resolve painters for changedItems\n        List<ItemPainter> painters = new ArrayList<>(itemChanges.size());\n        for (ChartItemChange change : itemChanges)\n            painters.add(paintersModel.getPainter(change.getItem()));\n\n        // Check if items bounds changed\n        boolean boundsChange = false;\n        for (int i = 0; i < itemChanges.size(); i++) {\n            ChartItemChange change = itemChanges.get(i);\n            ItemPainter painter = painters.get(i);\n            boundsChange = painter.isBoundsChange(change);\n            if (boundsChange) break;\n        }\n\n        // Update chart size\n        if (boundsChange) {\n            LongRect oldBounds = new LongRect(dataBounds);\n            computeDataBounds();\n            if (!LongRect.equals(oldBounds, dataBounds)) resizeChart();\n        }\n\n        // Check if items appearance changed\n        boolean appearanceChange = false;\n        for (int i = 0; i < itemChanges.size(); i++) {\n            ChartItemChange change = itemChanges.get(i);\n            ItemPainter painter = painters.get(i);\n            appearanceChange = painter.isAppearanceChange(change);\n            if (appearanceChange) break;\n        }\n\n        // Update chart appearance\n        if (appearanceChange) {\n            LongRect uiBounds = null;\n            for (ChartItemChange change : itemChanges) {\n                ChartItem item = change.getItem();\n                ItemPainter painter = paintersModel.getPainter(item);\n                if (painter.isAppearanceChange(change)) {\n                    if (uiBounds == null)\n                        uiBounds = new LongRect(painter.getDirtyBounds(change, getChartContext(item)));\n                    else\n                        LongRect.add(uiBounds, painter.getDirtyBounds(change, getChartContext(item)));\n                }\n            }\n            invalidateImage(Utils.checkedRectangle(uiBounds));\n            repaintDirtyAccel();\n        } else {\n            repaintDirty();\n        }\n    }\n\n    protected void paintersChanged() {\n        updateChart();\n    }\n\n    protected void paintersChanged(List<ItemPainter> changedPainters) {\n        Set<ChartItem> changedItems = new HashSet<>();\n\n        // Update chart size\n        LongRect oldBounds = new LongRect(dataBounds);\n        computeDataBounds();\n        if (!LongRect.equals(oldBounds, dataBounds)) resizeChart();\n\n        // Resolve changed items\n        for (int i = 0; i < itemsModel.getItemsCount(); i++) {\n            ChartItem item = itemsModel.getItem(i);\n            if (changedPainters.contains(paintersModel.getPainter(item)))\n                changedItems.add(item);\n        }\n\n        // Update chart appearance\n        LongRect uiBounds = null;\n        for (ChartItem item : changedItems) {\n            ItemPainter painter = paintersModel.getPainter(item);\n            if (uiBounds == null) uiBounds =\n                new LongRect(painter.getItemBounds(item, getChartContext(item)));\n            else\n                LongRect.add(uiBounds, painter.getItemBounds(item, getChartContext(item)));\n        }\n        invalidateImage(Utils.checkedRectangle(uiBounds));\n        repaintDirty();\n    }\n\n\n    // --- ItemsModel change support -------------------------------------------\n\n    private class ItemsModelListener implements ItemsListener {\n\n        public void itemsAdded(List<ChartItem> addedItems) {\n            ChartComponent.this.itemsAdded(addedItems);\n        }\n\n        public void itemsRemoved(List<ChartItem> removedItems) {\n            ChartComponent.this.itemsRemoved(removedItems);\n        }\n\n        public void itemsChanged(List<ChartItemChange> itemChanges) {\n            ChartComponent.this.itemsChanged(itemChanges);\n        }\n\n    }\n\n\n    // --- PaintersModel change support ----------------------------------------\n\n    private class PaintersModelListener implements PaintersListener {\n\n        public void paintersChanged() {\n            ChartComponent.this.paintersChanged();\n        }\n\n        public void paintersChanged(List<ItemPainter> changedPainters) {\n            ChartComponent.this.paintersChanged(changedPainters);\n        }\n\n    }\n\n\n    // --- Selection listener --------------------------------------------------\n\n    private class SelectionListener implements ChartSelectionListener {\n\n        public void selectionModeChanged(int newMode, int oldMode) {}\n\n        public void selectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds) {}\n\n        public void highlightedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n            refreshSelection(addedItems, removedItems);\n        }\n\n        public void selectedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n            refreshSelection(addedItems, removedItems);\n        }\n\n\n        private void refreshSelection(List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n            // TODO: should be optimized!\n            Rectangle dirtyArea = new Rectangle();\n\n            if (!removedItems.isEmpty() && removedItems.get(0) != null)\n                for (ItemSelection sel : removedItems) {\n                    ChartItem item = sel.getItem();\n                    ItemPainter painter = paintersModel.getPainter(item);\n                    if (painter.supportsHovering(item)) {\n                        if (dirtyArea.isEmpty())\n                            dirtyArea.setBounds(Utils.checkedRectangle(\n                            painter.getSelectionBounds(sel, getChartContext(item))));\n                        else\n                            dirtyArea.add(Utils.checkedRectangle(\n                            painter.getSelectionBounds(sel, getChartContext(item))));\n                    }\n                }\n\n            if (!dirtyArea.isEmpty()) {\n                invalidateImage(dirtyArea);\n                paintImmediately(dirtyArea);\n//                repaintDirty();\n                dirtyArea = new Rectangle();\n            }\n\n            if (!addedItems.isEmpty() && addedItems.get(0) != null)\n                for (ItemSelection sel : addedItems) {\n                    ChartItem item = sel.getItem();\n                    ItemPainter painter = paintersModel.getPainter(item);\n                    if (painter.supportsHovering(item)) {\n                        if (dirtyArea.isEmpty())\n                            dirtyArea.setBounds(Utils.checkedRectangle(\n                            painter.getSelectionBounds(sel, getChartContext(item))));\n                        else\n                            dirtyArea.add(Utils.checkedRectangle(\n                            painter.getSelectionBounds(sel, getChartContext(item))));\n                    }\n                }\n\n            if (!dirtyArea.isEmpty()) {\n                invalidateImage(dirtyArea);\n                paintImmediately(dirtyArea);\n//                repaintDirty();\n            }\n\n//            invalidateImage(dirtyArea);\n//            immediatelyRepaintDirty();\n//            repaintDirty(dirtyArea);\n        }\n\n    }\n\n\n    // --- ChartContext implementation -----------------------------------------\n\n    protected static class Context implements ChartContext {\n\n        private ChartComponent chart;\n\n\n        protected Context(ChartComponent chart) { this.chart = chart; }\n\n        protected ChartComponent getChartComponent() { return chart; }\n\n\n        public boolean isRightBased() { return chart.isRightBased(); }\n\n        public boolean isBottomBased() { return chart.isBottomBased(); }\n\n        public boolean fitsWidth() { return chart.fitsWidth(); }\n\n        public boolean fitsHeight() { return chart.fitsHeight(); }\n\n        public long getDataOffsetX() { return chart.getDataOffsetX(); }\n\n        public long getDataOffsetY() { return chart.getDataOffsetY(); }\n\n        public long getDataWidth() { return chart.getDataWidth(); }\n\n        public long getDataHeight() { return chart.getDataHeight(); }\n\n        public long getViewWidth() { return chart.getContentsWidth(); }\n\n        public long getViewHeight() { return chart.getContentsHeight(); }\n\n        public long getViewportOffsetX() { return 0; }\n\n        public long getViewportOffsetY() { return 0; }\n\n        public int getViewportWidth() { return chart.getWidth(); }\n\n        public int getViewportHeight() { return chart.getHeight(); }\n\n        public double getViewX(double dataX) { return chart.getViewX(dataX); }\n\n        public double getReversedViewX(double dataX) { return chart.getReversedViewX(dataX); }\n\n        public double getViewY(double dataY) { return chart.getViewY(dataY); }\n\n        public double getReversedViewY(double dataY) { return chart.getReversedViewY(dataY); }\n\n        public double getViewWidth(double dataWidth) { return chart.getViewWidth(dataWidth); }\n\n        public double getViewHeight(double dataHeight) { return chart.getViewHeight(dataHeight); }\n\n        public LongRect getViewRect(LongRect dataRect) { return getViewRectImpl(dataRect); }\n\n        public double getDataX(double viewX) { return chart.getDataX(viewX); }\n\n        public double getReversedDataX(double viewX) { return chart.getReversedDataX(viewX); }\n\n        public double getDataY(double viewY) { return chart.getDataY(viewY); }\n\n        public double getReversedDataY(double viewY) { return chart.getReversedDataY(viewY); }\n\n        public double getDataWidth(double viewWidth) { return chart.getDataWidth(viewWidth); }\n\n        public double getDataHeight(double viewHeight) { return chart.getDataHeight(viewHeight); }\n\n\n        private LongRect getViewRectImpl(LongRect dataRect) {\n            LongRect viewRect = new LongRect();\n\n            viewRect.x = (long)Math.ceil(getViewX(dataRect.x));\n            viewRect.width = (long)Math.ceil(getViewWidth(dataRect.width));\n            if (isRightBased()) viewRect.x -= viewRect.width;\n\n            viewRect.y = (long)Math.ceil(getViewY(dataRect.y));\n            viewRect.height = (long)Math.ceil(getViewHeight(dataRect.height));\n            if (isBottomBased()) viewRect.y -= viewRect.height;\n\n            return viewRect;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ChartConfigurationListener.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ChartConfigurationListener {\n\n    // Called immediately after the change\n    public void offsetChanged(long oldOffsetX, long oldOffsetY,\n                              long newOffsetX, long newOffsetY);\n\n    // Called immediately after the change\n    public void scaleChanged(double oldScaleX, double oldScaleY,\n                             double newScaleX, double newScaleY);\n\n    // Called immediately after the change\n    public void dataBoundsChanged(long dataOffsetX, long dataOffsetY,\n                                  long dataWidth, long dataHeight,\n                                  long oldDataOffsetX, long oldDataOffsetY,\n                                  long oldDataWidth, long oldDataHeight);\n\n    // Called before paintContents(Graphics, Rectangle)\n    public void contentsWillBeUpdated(long offsetX, long offsetY,\n                            double scaleX, double scaleY,\n                            long lastOffsetX, long lastOffsetY,\n                            double lastScaleX, double lastScaleY);\n\n    // Called after paintContents(Graphics, Rectangle)\n    // The actual change may/not be already displayed depending on buffer type\n    public void contentsUpdated(long offsetX, long offsetY,\n                            double scaleX, double scaleY,\n                            long lastOffsetX, long lastOffsetY,\n                            double lastScaleX, double lastScaleY,\n                            int shiftX, int shiftY);\n\n\n    public abstract class Adapter implements ChartConfigurationListener {\n\n        public void offsetChanged(long oldOffsetX, long oldOffsetY,\n                                  long newOffsetX, long newOffsetY) {}\n\n        public void scaleChanged(double oldScaleX, double oldScaleY,\n                                 double newScaleX, double newScaleY) {}\n\n        public void dataBoundsChanged(long dataOffsetX, long dataOffsetY,\n                                      long dataWidth, long dataHeight,\n                                      long oldDataOffsetX, long oldDataOffsetY,\n                                      long oldDataWidth, long oldDataHeight) {}\n\n        public void contentsWillBeUpdated(long offsetX, long offsetY,\n                                double scaleX, double scaleY,\n                                long lastOffsetX, long lastOffsetY,\n                                double lastScaleX, double lastScaleY) {}\n\n        public void contentsUpdated(long offsetX, long offsetY,\n                                double scaleX, double scaleY,\n                                long lastOffsetX, long lastOffsetY,\n                                double lastScaleX, double lastScaleY,\n                                int shiftX, int shiftY) {}\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ChartContext.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ChartContext {\n\n    // --- Chart orientation ---------------------------------------------------\n\n    public boolean isRightBased();\n\n    public boolean isBottomBased();\n\n\n    // --- Fixed scale ---------------------------------------------------------\n\n    public boolean fitsWidth();\n\n    public boolean fitsHeight();\n\n\n    // --- Chart bounds --------------------------------------------------------\n\n    public long getDataOffsetX();\n\n    public long getDataOffsetY();\n\n    public long getDataWidth();\n\n    public long getDataHeight();\n\n    public long getViewWidth();\n\n    public long getViewHeight();\n\n\n    // --- Viewport bounds -----------------------------------------------------\n\n    public long getViewportOffsetX();\n\n    public long getViewportOffsetY();\n\n    public int getViewportWidth();\n\n    public int getViewportHeight();\n\n\n    // --- Data to View --------------------------------------------------------\n\n    public double getViewX(double dataX);\n\n    public double getReversedViewX(double dataX);\n\n    public double getViewY(double dataY);\n\n    public double getReversedViewY(double dataY);\n\n    public double getViewWidth(double dataWidth);\n\n    public double getViewHeight(double dataHeight);\n\n    public LongRect getViewRect(LongRect dataRect);\n\n//    public LongRect getReversedViewRect(LongRect dataRect);\n\n\n    // --- View to Data --------------------------------------------------------\n\n    public double getDataX(double viewX);\n\n    public double getReversedDataX(double viewX);\n\n    public double getDataY(double viewY);\n\n    public double getReversedDataY(double viewY);\n\n    public double getDataWidth(double viewWidth);\n\n    public double getDataHeight(double viewHeight);\n\n//    public LongRect getDataRect(LongRect viewRect);\n//\n//    public LongRect getReversedDataRect(LongRect viewRect);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ChartDecorator.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ChartDecorator {\n\n    public void paint(Graphics2D g, Rectangle dirtyArea, ChartContext context);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ChartItem.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ChartItem {\n\n    public void addItemListener(ChartItemListener listener);\n\n    public void removeItemListener(ChartItemListener listener);\n\n\n    public static abstract class Abstract implements ChartItem {\n\n\n        private List<ChartItemListener> listeners;\n\n\n        public void addItemListener(ChartItemListener listener) {\n            if (listeners == null) listeners = new ArrayList<>();\n            if (!listeners.contains(listener)) listeners.add(listener);\n        }\n\n        public void removeItemListener(ChartItemListener listener) {\n            if (listeners != null) listeners.remove(listener);\n        }\n\n\n        protected void fireItemChanged(ChartItemChange itemChange) {\n            if (listeners != null)\n                for (ChartItemListener listener : listeners)\n                    listener.chartItemChanged(itemChange);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ChartItemChange.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ChartItemChange {\n\n    public ChartItem getItem();\n\n\n    public static class Default implements ChartItemChange {\n\n        private ChartItem item;\n\n        public Default(ChartItem item) { this.item = item; }\n\n        public ChartItem getItem() { return item; }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ChartItemListener.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ChartItemListener {\n\n    public void chartItemChanged(ChartItemChange itemChange);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ChartOverlay.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport javax.swing.JComponent;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ChartOverlay extends JComponent {\n\n    private ChartContext context;\n\n\n    void setChartContext(ChartContext context) {\n        this.context = context;\n    }\n\n    protected final ChartContext getChartContext() {\n        return context;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ChartSelectionListener.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport java.awt.Rectangle;\nimport java.util.List;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ChartSelectionListener {\n\n    public void selectionModeChanged(int newMode, int oldMode);\n\n    public void selectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds);\n\n    public void highlightedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems);\n\n    public void selectedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ChartSelectionManager.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport java.awt.Rectangle;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseMotionListener;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport javax.swing.SwingUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ChartSelectionManager implements ChartSelectionModel {\n\n    private ChartComponent chart;\n\n    private ChartListener chartListener;\n    private MouseListener mouseListener;\n\n    private int selectionMode;\n    private int moveMode;\n    private int dragMode;\n\n    private int hoverMode;\n    private int hoverDistanceLimit;\n\n    private int mouseX;\n    private int mouseY;\n    private boolean inChart;\n\n    private Rectangle selectionBounds;\n\n    private List<ItemSelection> highlightedSelection;\n    private List<ItemSelection> selectedSelection;\n\n    private boolean mousePanningBackup;\n\n    private List<ChartSelectionListener> selectionListeners;\n\n\n    ChartSelectionManager() {\n        mouseX = -1;\n        mouseY = -1;\n        inChart = false;\n\n        chartListener = new ChartListener();\n        mouseListener = new MouseListener();\n\n        setMoveMode(SELECTION_NONE);\n        setDragMode(SELECTION_NONE);\n        setSelectionMode(moveMode);\n\n        setHoverMode(HOVER_NONE);\n        setHoverDistanceLimit(HOVER_DISTANCE_LIMIT_NONE);\n    }\n\n\n    // --- Internal API --------------------------------------------------------\n\n    void registerChart(ChartComponent chart) {\n        unregisterListener();\n        this.chart = chart;\n        registerListener();\n    }\n\n    void unregisterChart(ChartComponent chart) {\n        unregisterListener();\n        this.chart = null;\n    }\n\n\n    // --- Selection mode ------------------------------------------------------\n\n    public final void setMoveMode(int mode) {\n        moveMode = mode;\n        if (selectionMode != moveMode) setSelectionMode(moveMode);\n    }\n\n    public final int getMoveMode() {\n        return moveMode;\n    }\n\n    public final void setDragMode(int mode) {\n        dragMode = mode;\n    }\n\n    public final int getDragMode() {\n        return dragMode;\n    }\n\n    public final int getSelectionMode() {\n        return selectionMode;\n    }\n\n    public final void setHoverMode(int mode) {\n        hoverMode = mode;\n        updateHighlightedItems();\n    }\n\n    public final int getHoverMode() {\n        return hoverMode;\n    }\n\n    public final void setHoverDistanceLimit(int limit) {\n        hoverDistanceLimit = limit;\n    }\n\n    public final int getHoverDistanceLimit() {\n        return hoverDistanceLimit;\n    }\n\n\n    // --- Selection bounds ----------------------------------------------------\n\n    public final void setSelectionBounds(int x, int y, int w, int h) {\n        setSelectionBounds(new Rectangle(x, y, w, h));\n    }\n\n    public final void setSelectionBounds(Rectangle selectionBounds) {\n        if (selectionBounds == null && this.selectionBounds == null) return;\n        if (this.selectionBounds != null && this.selectionBounds.equals(selectionBounds) ||\n            selectionBounds != null && selectionBounds.equals(this.selectionBounds)) return;\n\n        Rectangle oldSelectionBounds = this.selectionBounds == null ? null :\n                                       new Rectangle(this.selectionBounds);\n\n        if (selectionBounds == null) this.selectionBounds = null;\n        else if (this.selectionBounds == null) this.selectionBounds = new Rectangle(selectionBounds);\n        else this.selectionBounds.setBounds(selectionBounds);\n\n        fireSelectionBoundsChanged(this.selectionBounds, oldSelectionBounds);\n    }\n\n    public final Rectangle getSelectionBounds() {\n        return new Rectangle(selectionBounds);\n    }\n\n\n    // --- Highlighted items ---------------------------------------------------\n\n    public final void setHighlightedItems(List<ItemSelection> items) {\n        if (highlightedSelection == null) {\n            if (items.isEmpty()) return;\n            highlightedSelection = new ArrayList<>(items);\n            fireHighlightedItemsChanged(items, items, Collections.emptyList());\n        } else {\n            List<ItemSelection> addedItems = new ArrayList<>();\n            List<ItemSelection> removedItems = new ArrayList<>();\n\n            for (ItemSelection item : items)\n                if (!highlightedSelection.contains(item)) addedItems.add(item);\n\n            for (ItemSelection item : highlightedSelection)\n                if (!items.contains(item)) removedItems.add(item);\n\n            if (addedItems.isEmpty() && removedItems.isEmpty()) return;\n\n            highlightedSelection = new ArrayList<>(items);\n            fireHighlightedItemsChanged(items, addedItems, removedItems);\n        }\n    }\n\n    public final List<ItemSelection> getHighlightedItems() {\n        return highlightedSelection == null ? Collections.emptyList() :\n                                              new ArrayList<>(highlightedSelection);\n    }\n\n\n    // --- Selected items ------------------------------------------------------\n\n    public final void setSelectedItems(List<ItemSelection> items) {\n        if (selectedSelection == null) {\n            if (items.isEmpty()) return;\n            selectedSelection = new ArrayList<>(items);\n            fireSelectedItemsChanged(items, items, Collections.emptyList());\n        } else {\n            List<ItemSelection> addedItems = new ArrayList<>();\n            List<ItemSelection> removedItems = new ArrayList<>();\n\n            for (ItemSelection item : items)\n                if (!selectedSelection.contains(item)) addedItems.add(item);\n\n            for (ItemSelection item : selectedSelection)\n                if (!items.contains(item)) removedItems.add(item);\n\n            if (addedItems.isEmpty() && removedItems.isEmpty()) return;\n\n            selectedSelection = new ArrayList<>(items);\n            fireSelectedItemsChanged(items, addedItems, removedItems);\n        }\n    }\n\n    public final List<ItemSelection> getSelectedItems() {\n        return selectedSelection == null ? Collections.emptyList() :\n                                           new ArrayList<>(selectedSelection);\n    }\n\n\n    // --- Selection listeners -------------------------------------------------\n\n    public final void addSelectionListener(ChartSelectionListener listener) {\n        if (selectionListeners == null) selectionListeners = new ArrayList<>();\n        selectionListeners.add(listener);\n    }\n\n    public final void removeSelectionListener(ChartSelectionListener listener) {\n        if (selectionListeners == null) return;\n        selectionListeners.remove(listener);\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void setSelectionMode(int selectionMode) {\n        if (this.selectionMode == selectionMode) return;\n        int oldSelectionMode = this.selectionMode;\n        this.selectionMode = selectionMode;\n        fireSelectionModeChanged(this.selectionMode, oldSelectionMode);\n    }\n\n\n    private void registerListener() {\n        if (chart == null) return;\n        chart.addMouseListener(mouseListener);\n        chart.addMouseMotionListener(mouseListener);\n        chart.addConfigurationListener(chartListener);\n    }\n\n    private void unregisterListener() {\n        if (chart == null) return;\n        chart.removeMouseListener(mouseListener);\n        chart.removeMouseMotionListener(mouseListener);\n        chart.removeConfigurationListener(chartListener);\n    }\n\n\n    private void updateHighlightedItems() {\n        final int x = mouseX;\n        final int y = mouseY;\n\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (hoverMode == HOVER_NONE || !inChart) {\n                    setHighlightedItems(Collections.emptyList());\n                    return;\n                }\n\n                ItemsModel itemsModel = chart.getItemsModel();\n                PaintersModel paintersModel = chart.getPaintersModel();\n\n                int itemsCount = itemsModel.getItemsCount();\n                List<ItemSelection> closestSelection = new ArrayList<>(itemsCount);\n\n                for (int i = 0; i < itemsCount; i++) {\n                    ChartItem item = itemsModel.getItem(i);\n                    ItemPainter painter = paintersModel.getPainter(item);\n                    ItemSelection selection = painter.getClosestSelection(item, x, y,\n                                                            chart.getChartContext());\n\n                    if (selection != null) {\n                        int distance = selection.getDistance();\n                        if (hoverMode == HOVER_EACH_NEAREST || closestSelection.isEmpty()) {\n                            if (hoverDistanceLimit == HOVER_DISTANCE_LIMIT_NONE ||\n                                distance <= hoverDistanceLimit)\n                                closestSelection.add(selection);\n                        } else {\n                            if (closestSelection.get(0).getDistance() > distance) {\n                                if (hoverDistanceLimit == HOVER_DISTANCE_LIMIT_NONE ||\n                                    distance <= hoverDistanceLimit)\n                                    closestSelection.set(0, selection);\n                            }\n                        }\n                    }\n                }\n\n                setHighlightedItems(closestSelection);\n            }\n        });\n    }\n\n\n    private void fireSelectionModeChanged(int newMode, int oldMode) {\n        if (selectionListeners == null) return;\n        for (ChartSelectionListener listener : selectionListeners)\n            listener.selectionModeChanged(newMode, oldMode);\n    }\n\n    private void fireSelectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds) {\n        if (selectionListeners == null) return;\n        for (ChartSelectionListener listener : selectionListeners)\n            listener.selectionBoundsChanged(newBounds, oldBounds);\n    }\n\n    private void fireHighlightedItemsChanged(List<ItemSelection> currentItems,\n            List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n        if (selectionListeners == null) return;\n        for (ChartSelectionListener listener : selectionListeners)\n            listener.highlightedItemsChanged(currentItems, addedItems, removedItems);\n    }\n\n    private void fireSelectedItemsChanged(List<ItemSelection> currentItems,\n            List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n        if (selectionListeners == null) return;\n        for (ChartSelectionListener listener : selectionListeners)\n            listener.selectedItemsChanged(currentItems, addedItems, removedItems);\n    }\n\n\n    private class ChartListener extends ChartConfigurationListener.Adapter {\n\n        public void contentsWillBeUpdated(long offsetX, long offsetY,\n                                double scaleX, double scaleY,\n                                long lastOffsetX, long lastOffsetY,\n                                double lastScaleX, double lastScaleY) {\n            updateHighlightedItems();\n        }\n\n    }\n\n\n    private class MouseListener extends MouseAdapter implements MouseMotionListener {\n\n        public void mousePressed(MouseEvent e) {\n            mousePanningBackup = chart.isMousePanningEnabled();\n\n            setSelectionMode(dragMode);\n            if (selectionMode != SELECTION_NONE) {\n                chart.disableMousePanning();\n                setSelectionBounds(e.getX(), e.getY(), 0, 0);\n            }\n        }\n\n        public void mouseReleased(MouseEvent e) {\n            // Clear previous selection\n            setSelectionBounds(null);\n\n            setSelectionMode(moveMode);\n            if (selectionMode == SELECTION_NONE)\n                chart.setMousePanningEnabled(mousePanningBackup);\n\n            // Refresh selection if needed\n            if (selectionMode != SELECTION_NONE)\n                setSelectionBounds(e.getX(), e.getY(), 0, 0);\n        }\n\n        public void mouseEntered(MouseEvent e) {\n            inChart = true;\n            mouseX = e.getX();\n            mouseY = e.getY();\n        }\n\n        public void mouseExited(MouseEvent e) {\n            inChart = false;\n\n            if (selectionMode == SELECTION_LINE_V ||\n                selectionMode == SELECTION_LINE_H ||\n                selectionMode == SELECTION_CROSS) {\n                setSelectionBounds(null);\n            }\n\n            updateHighlightedItems();\n        }\n\n        public void mouseDragged(MouseEvent e) {\n            if (selectionMode == SELECTION_RECT) {\n                setSelectionBounds(selectionBounds.x, selectionBounds.y,\n                        e.getX() - selectionBounds.x, e.getY() - selectionBounds.y);\n            }\n        }\n\n        public void mouseMoved(MouseEvent e) {\n            mouseX = e.getX();\n            mouseY = e.getY();\n\n            if (selectionMode == SELECTION_NONE) setSelectionBounds(null);\n            else setSelectionBounds(mouseX, mouseY, 0, 0);\n\n            updateHighlightedItems();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ChartSelectionModel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport java.awt.Rectangle;\nimport java.util.List;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ChartSelectionModel {\n\n    public static final int SELECTION_NONE = 0;\n    public static final int SELECTION_LINE_V = 1;\n    public static final int SELECTION_LINE_H = 2;\n    public static final int SELECTION_CROSS = 3;\n    public static final int SELECTION_RECT = 4;\n\n    public static final int HOVER_NONE = 100;\n    public static final int HOVER_NEAREST = 101;\n    public static final int HOVER_EACH_NEAREST = 102;\n\n    public static final int HOVER_DISTANCE_LIMIT_NONE = -1;\n\n\n    // --- Selection mode ------------------------------------------------------\n\n    public void setMoveMode(int mode);\n\n    public int getMoveMode();\n\n    public void setDragMode(int mode);\n\n    public int getDragMode();\n\n    public int getSelectionMode();\n\n    public void setHoverMode(int mode);\n\n    public int getHoverMode();\n\n    public void setHoverDistanceLimit(int limit);\n\n    public int getHoverDistanceLimit();\n\n\n    // --- Bounds selection ----------------------------------------------------\n\n    public void setSelectionBounds(Rectangle selectionBounds);\n\n    public Rectangle getSelectionBounds();\n\n\n    // --- Items selection -----------------------------------------------------\n\n    public void setHighlightedItems(List<ItemSelection> items);\n\n    public List<ItemSelection> getHighlightedItems();\n\n    public void setSelectedItems(List<ItemSelection> items);\n\n    public List<ItemSelection> getSelectedItems();\n\n\n    // --- Selection listeners -------------------------------------------------\n\n    public void addSelectionListener(ChartSelectionListener listener);\n\n    public void removeSelectionListener(ChartSelectionListener listener);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/CompoundItemPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport java.util.List;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class CompoundItemPainter implements ItemPainter {\n\n    private ItemPainter painter1;\n    private ItemPainter painter2;\n\n\n    public CompoundItemPainter(ItemPainter painter1, ItemPainter painter2) {\n        this.painter1 = painter1;\n        this.painter2 = painter2;\n    }\n\n\n    public LongRect getItemBounds(ChartItem item) {\n        LongRect itemBounds = painter1.getItemBounds(item);\n        LongRect.add(itemBounds, painter2.getItemBounds(item));\n        return itemBounds;\n    }\n\n    public LongRect getItemBounds(ChartItem item, ChartContext context) {\n        LongRect itemBounds = painter1.getItemBounds(item, context);\n        LongRect.add(itemBounds, painter2.getItemBounds(item, context));\n        return itemBounds;\n    }\n\n\n    public boolean isBoundsChange(ChartItemChange itemChange) {\n        return painter1.isBoundsChange(itemChange) ||\n               painter2.isBoundsChange(itemChange);\n    }\n\n    public boolean isAppearanceChange(ChartItemChange itemChange) {\n        return painter1.isAppearanceChange(itemChange) ||\n               painter2.isAppearanceChange(itemChange);\n    }\n\n    public LongRect getDirtyBounds(ChartItemChange itemChange, ChartContext context) {\n        LongRect dirtyBounds = painter1.getDirtyBounds(itemChange, context);\n        LongRect.add(dirtyBounds, painter2.getDirtyBounds(itemChange, context));\n        return dirtyBounds;\n    }\n\n\n    public boolean supportsHovering(ChartItem item) {\n        return painter1.supportsHovering(item) || painter2.supportsHovering(item);\n    }\n\n    public boolean supportsSelecting(ChartItem item) {\n        return painter1.supportsSelecting(item) || painter2.supportsSelecting(item);\n    }\n\n    public LongRect getSelectionBounds(ItemSelection selection, ChartContext context) {\n        LongRect bounds1 = painter1.supportsHovering(selection.getItem()) ? painter1.getSelectionBounds(selection, context) : new LongRect();\n        LongRect bounds2 = painter2.supportsHovering(selection.getItem()) ? painter2.getSelectionBounds(selection, context) : new LongRect();\n        LongRect.add(bounds1, bounds2);\n        return bounds1;\n    }\n\n    public ItemSelection getClosestSelection(ChartItem item, int viewX, int viewY, ChartContext context) {\n        ItemSelection selection1 = painter1.supportsHovering(item) ? painter1.getClosestSelection(item, viewX, viewY, context) : null;\n        ItemSelection selection2 = painter2.supportsHovering(item) ? painter2.getClosestSelection(item, viewX, viewY, context) : null;\n\n        if (selection1 == null) return selection2;\n        else if (selection2 == null) return selection1;\n        else if (selection1.getDistance() < selection2.getDistance()) return selection1;\n        else return selection2;\n    }\n\n\n    public void paintItem(ChartItem item, List<ItemSelection> highlighted, List<ItemSelection> selected, Graphics2D g, Rectangle dirtyArea, ChartContext context) {\n        painter1.paintItem(item, highlighted, selected, g, dirtyArea, context);\n        painter2.paintItem(item, highlighted, selected, g, dirtyArea, context);\n    }\n\n\n    protected ItemPainter getPainter1() {\n        return painter1;\n    }\n\n    protected ItemPainter getPainter2() {\n        return painter2;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ItemPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport java.util.List;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ItemPainter {\n\n    // --- Item bounds ---------------------------------------------------------\n\n    // General item bounds without decorations, data space [0, 0]-based\n    public LongRect getItemBounds(ChartItem item);\n\n    // Concrete item bounds for given ChartContext, display space\n    public LongRect getItemBounds(ChartItem item, ChartContext context);\n\n\n    // --- Item change support -------------------------------------------------\n\n    public boolean isBoundsChange(ChartItemChange itemChange);\n\n    public boolean isAppearanceChange(ChartItemChange itemChange);\n\n    public LongRect getDirtyBounds(ChartItemChange itemChange, ChartContext context);\n\n\n    // --- Item location -------------------------------------------------------\n\n    public boolean supportsHovering(ChartItem item);\n\n    public boolean supportsSelecting(ChartItem item);\n\n    public LongRect getSelectionBounds(ItemSelection selection, ChartContext context);\n\n    public ItemSelection getClosestSelection(ChartItem item, int viewX, int viewY, ChartContext context);\n\n\n    // --- Item appearance -----------------------------------------------------\n\n    public void paintItem(ChartItem item, List<ItemSelection> highlighted,\n                          List<ItemSelection> selected, Graphics2D g,\n                          Rectangle dirtyArea, ChartContext context);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ItemSelection.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ItemSelection {\n\n    public static final int DISTANCE_UNKNOWN = Integer.MAX_VALUE;\n\n\n    public ChartItem getItem();\n\n    public int getDistance();\n\n\n    public static class Default implements ItemSelection {\n\n        private ChartItem item;\n        private int distance;\n\n\n        public Default(ChartItem item) {\n            this(item, DISTANCE_UNKNOWN);\n        }\n\n        public Default(ChartItem item, int distance) {\n            this.item = item;\n            this.distance = distance;\n        }\n\n\n        public ChartItem getItem() {\n            return item;\n        }\n\n        public int getDistance() {\n            return distance;\n        }\n\n\n        public boolean equals(Object o) {\n            if (!(o instanceof ItemSelection)) return false;\n            ItemSelection selection = (ItemSelection)o;\n            return selection.getItem() == item;\n        }\n\n        public int hashCode() {\n            return item.hashCode();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ItemsListener.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport java.util.List;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ItemsListener {\n\n    // One or more items added\n    public void itemsAdded(List<ChartItem> addedItems);\n\n    // One or more items removed\n    public void itemsRemoved(List<ChartItem> removedItems);\n\n    // Items bounds and/or appearance changed\n    public void itemsChanged(List<ChartItemChange> itemChanges);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/ItemsModel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ItemsModel {\n\n    public int getItemsCount();\n\n    public ChartItem getItem(int index);\n\n    public void addItemsListener(ItemsListener listener);\n\n    public void removeItemsListener(ItemsListener listener);\n\n\n    public static abstract class Abstract implements ItemsModel {\n\n        private List<ItemsListener> listeners;\n\n\n        public void addItemsListener(ItemsListener listener) {\n            if (listeners == null) listeners = new ArrayList<>();\n            if (!listeners.contains(listener)) listeners.add(listener);\n        }\n\n        public void removeItemsListener(ItemsListener listener) {\n            if (listeners != null) {\n                listeners.remove(listener);\n                if (listeners.isEmpty()) listeners = null;\n            }\n        }\n\n\n        protected void fireItemsAdded(List<ChartItem> addedItems) {\n            if (listeners != null)\n                for (ItemsListener listener : listeners)\n                    listener.itemsAdded(addedItems);\n        }\n\n        protected void fireItemsRemoved(List<ChartItem> removedItems) {\n            if (listeners != null)\n                for (ItemsListener listener : listeners)\n                    listener.itemsRemoved(removedItems);\n        }\n\n        protected void fireItemsChanged(List<ChartItemChange> itemChanges) {\n            if (listeners != null)\n                for (ItemsListener listener : listeners)\n                    listener.itemsChanged(itemChanges);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/PaintersListener.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport java.util.List;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface PaintersListener {\n\n    // Painters changed, high impact on appearance (most of the chart dirty)\n    public void paintersChanged();\n\n    // Painters changed, low impact on appearance (several items dirty)\n    public void paintersChanged(List<ItemPainter> changedPainters);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/PaintersModel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface PaintersModel {\n\n    public ItemPainter getPainter(ChartItem item);\n\n    public void addPaintersListener(PaintersListener listener);\n\n    public void removePaintersListener(PaintersListener listener);\n\n\n    public static abstract class Abstract implements PaintersModel {\n\n        private List<PaintersListener> listeners;\n\n\n        public void addPaintersListener(PaintersListener listener) {\n            if (listeners == null) listeners = new ArrayList<>();\n            if (!listeners.contains(listener)) listeners.add(listener);\n        }\n\n        public void removePaintersListener(PaintersListener listener) {\n            if (listeners != null) {\n                listeners.remove(listener);\n                if (listeners.isEmpty()) listeners = null;\n            }\n        }\n\n\n        protected void firePaintersChanged() {\n            if (listeners != null)\n                for (PaintersListener listener : listeners)\n                    listener.paintersChanged();\n        }\n\n        protected void firePaintersChanged(List<ItemPainter> changedPainters) {\n            if (listeners != null)\n                for (PaintersListener listener : listeners)\n                    listener.paintersChanged(changedPainters);\n        }\n\n    }\n\n\n    public static class Default extends Abstract {\n\n        private final Map<ChartItem, ItemPainter> painters;\n\n\n        public Default() {\n            painters = new HashMap<>();\n        }\n\n        public Default(ChartItem[] items, ItemPainter[] painters) {\n            this();\n\n            if (items == null)\n                throw new IllegalArgumentException(\"Items cannot be null\"); // NOI18N\n            if (painters == null)\n                throw new IllegalArgumentException(\"Painters cannot be null\"); // NOI18N\n            if (items.length != painters.length)\n                throw new IllegalArgumentException(\"Items don't match painters\"); // NOI18N\n\n            addPainters(items, painters);\n        }\n\n\n        public void addPainters(ChartItem[] addedItems, ItemPainter[] addedPainters) {\n            for (int i = 0; i < addedItems.length; i++)\n                painters.put(addedItems[i], addedPainters[i]);\n        }\n\n        public void removePainters(ChartItem[] removedItems) {\n            for (ChartItem removedItem : removedItems) {\n                painters.remove(removedItem);\n            }\n        }\n\n\n        public ItemPainter getPainter(ChartItem item) {\n            return painters.get(item);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/Timeline.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface Timeline {\n\n    public int getTimestampsCount();\n\n    public long getTimestamp(int index);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/AxisComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Paint;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.util.Iterator;\nimport javax.swing.JComponent;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartComponent;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartDecorator;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class AxisComponent extends JComponent {\n\n    public static final int NO_MESH         = 0;\n    public static final int MESH_BACKGROUND = 1;\n    public static final int MESH_FOREGROUND = 2;\n\n    private final int location;\n    private final boolean horizontal;\n\n    private final ChartComponent chart;\n    private final AxisMarksComputer marksComputer;\n    private final AxisMarksPainter marksPainter;\n\n    private int maxExtent = 0;\n\n    private final Paint meshPaint = Utils.checkedColor(new Color(80, 80, 80, 50));\n    private final Stroke meshStroke = new BasicStroke(1);\n\n\n    // --- Constructors --------------------------------------------------------\n\n    public AxisComponent(ChartComponent chart, AxisMarksComputer marksComputer,\n                         AxisMarksPainter marksPainter, int location, int mesh) {\n\n        this.location = location;\n        horizontal = location == SwingConstants.NORTH ||\n                     location == SwingConstants.SOUTH;\n\n        this.chart = chart;\n        this.marksComputer = marksComputer;\n        this.marksPainter = marksPainter;\n\n        setOpaque(false);\n\n        chart.addConfigurationListener(new ChartListener());\n\n        if (mesh == MESH_BACKGROUND) chart.addPreDecorator(createMeshPainter());\n        else if (mesh == MESH_FOREGROUND) chart.addPostDecorator(createMeshPainter());\n    }\n\n\n    // --- Component paint -----------------------------------------------------\n\n    public void paint(Graphics g) {\n        Rectangle clip = g.getClipBounds();\n        if (clip == null) clip = new Rectangle(0, 0, getWidth(), getHeight());\n\n        final Dimension dim = getPreferredSize();\n        final int axisBasisExtent = getAxisBasisExtent();\n\n        Rectangle chartBounds = SwingUtilities.convertRectangle(chart.getParent(),\n                                                        chart.getBounds(), this);\n        if (horizontal) {\n            chartBounds.y = clip.y;\n            chartBounds.height = clip.height;\n        } else {\n            chartBounds.x = clip.x;\n            chartBounds.width = clip.width;\n        }\n\n        if (marksComputer instanceof AxisMarksComputer.Abstract)\n            ((AxisMarksComputer.Abstract)marksComputer).refreshConfiguration();\n\n        paintAxis(g, clip, chartBounds);\n\n        if (horizontal) {\n            if (dim.height < maxExtent + axisBasisExtent) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        dim.height = maxExtent + axisBasisExtent;\n                        setPreferredSize(dim);\n                        invalidate();\n                        getParent().revalidate();\n                        getParent().repaint();\n                    }\n                });\n            }\n        } else {\n            if (dim.width < maxExtent + axisBasisExtent) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        dim.width = maxExtent + axisBasisExtent;\n                        setPreferredSize(dim);\n                        invalidate();\n                        getParent().revalidate();\n                        getParent().repaint();\n                    }\n                });\n            }\n        }\n    }\n\n\n    // --- Mesh painter --------------------------------------------------------\n\n    protected void paintAxisMesh(Graphics2D g, Rectangle clip, Rectangle chartMask) {\n        if (horizontal) paintHorizontalMesh(g, clip, chartMask);\n        else paintVerticalMesh(g, clip, chartMask);\n    }\n\n    protected void paintHorizontalMesh(Graphics2D g, Rectangle clip, Rectangle chartMask) {\n        Iterator<AxisMark> marks = marksComputer.marksIterator(\n                                                 chartMask.x, chartMask.x + chartMask.width);\n\n        while (marks.hasNext()) {\n            AxisMark mark = marks.next();\n            int x = mark.getPosition();\n\n            g.setPaint(meshPaint);\n            g.setStroke(meshStroke);\n            g.drawLine(x, chartMask.y, x, chartMask.y + chartMask.height);\n        }\n    }\n\n    protected void paintVerticalMesh(Graphics2D g, Rectangle clip, Rectangle chartMask) {\n        Iterator<AxisMark> marks = marksComputer.marksIterator(\n                                             chartMask.y, chartMask.y + chartMask.height);\n\n        while (marks.hasNext()) {\n            AxisMark mark = marks.next();\n            int y = mark.getPosition();\n\n            g.setPaint(meshPaint);\n            g.setStroke(meshStroke);\n            g.drawLine(chartMask.x, y, chartMask.x + chartMask.width, y);\n        }\n    }\n\n\n    // --- Axis contents painter -----------------------------------------------\n\n    protected void paintAxis(Graphics g, Rectangle clip, Rectangle chartMask) {\n        if (horizontal) paintHorizontalAxis(g, clip, chartMask);\n        else paintVerticalAxis(g, clip, chartMask);\n    }\n\n    protected int getAxisBasisExtent() {\n        return 5;\n    }\n\n    protected void paintHorizontalBasis(Graphics g, Rectangle clip, Rectangle chartMask) {\n        Rectangle dirty = clip.intersection(chartMask);\n        g.setColor(getForeground());\n        if (location == SwingConstants.NORTH) {\n            g.drawLine(dirty.x - 1, getHeight() - 1, dirty.x + dirty.width, getHeight() - 1);\n        } else {\n            g.drawLine(dirty.x, 0, dirty.x + dirty.width, 0);\n        }\n    }\n\n    protected void paintHorizontalTick(Graphics g, AxisMark mark, int x,\n                                       Rectangle clip, Rectangle chartMask) {\n        g.setColor(getForeground());\n        if (location == SwingConstants.NORTH) {\n            g.drawLine(x, getHeight() - 2 - getAxisBasisExtent(), x, getHeight() - 2);\n        } else {\n            g.drawLine(x, 1, x, 1 + getAxisBasisExtent());\n        }\n    }\n\n    protected void paintHorizontalAxis(Graphics g, Rectangle clip, Rectangle chartMask) {\n        paintHorizontalBasis(g, clip, chartMask);\n\n        int viewStart = SwingUtilities.convertPoint(this, chartMask.x, 0, chart).x - 1; // -1: extra 1px for axis\n        int viewEnd = viewStart + chartMask.width + 2; // +2 extra 1px + 1px for axis\n\n        Iterator<AxisMark> marks = marksComputer.marksIterator(viewStart, viewEnd);\n\n        int lZeroOffset = chart.isRightBased() ? 0 : 1;\n        int rZeroOffset = chart.isRightBased() ? 1 : 0;\n\n        while (marks.hasNext()) {\n            AxisMark mark = marks.next();\n\n            int x = SwingUtilities.convertPoint(chart, mark.getPosition(), 0, this).x;\n\n            if (x < chartMask.x - lZeroOffset ||\n                x >= chartMask.x + chartMask.width + rZeroOffset) continue;\n\n            Component painter = marksPainter.getPainter(mark);\n            painter.setSize(painter.getPreferredSize());\n            int markHeight = painter.getHeight();\n            int markOffsetX = painter.getWidth() / 2;\n\n            if (x + markOffsetX < clip.x ||\n                x - markOffsetX >= clip.x + clip.width) continue;\n\n            maxExtent = Math.max(maxExtent, markHeight);\n\n            paintHorizontalTick(g, mark, x, clip, chartMask);\n\n            g.setColor(getForeground());\n            if (location == SwingConstants.NORTH) {\n                g.translate(x - markOffsetX, 0);\n                painter.paint(g);\n                g.translate(-x + markOffsetX, 0);\n            } else {\n                g.translate(x - markOffsetX, getAxisBasisExtent());\n                painter.paint(g);\n                g.translate(-x + markOffsetX, -getAxisBasisExtent());\n            }\n        }\n    }\n\n    protected void paintVerticalBasis(Graphics g, Rectangle clip, Rectangle chartMask) {\n        g.setColor(getForeground());\n        if (location == SwingConstants.WEST) {\n            g.drawLine(getWidth() - 1, chartMask.y - 1, getWidth() - 1, chartMask.y + chartMask.height);\n        } else {\n            g.drawLine(0, chartMask.y, 0, chartMask.y + chartMask.height);\n        }\n    }\n\n    protected void paintVerticalTick(Graphics g, AxisMark mark, int y,\n                                       Rectangle clip, Rectangle chartMask) {\n        g.setColor(getForeground());\n        if (location == SwingConstants.WEST) {\n            g.drawLine(getWidth() - 2 - getAxisBasisExtent(), y, getWidth() - 2, y);\n        } else {\n            g.drawLine(1, y, 1 + getAxisBasisExtent(), y);\n        }\n    }\n\n    protected void paintVerticalAxis(Graphics g, Rectangle clip, Rectangle chartMask) {\n        paintVerticalBasis(g, clip, chartMask);\n\n        int viewStart = SwingUtilities.convertPoint(this, 0, chartMask.y, chart).y;\n        int viewEnd = viewStart + chartMask.height;\n\n        Iterator<AxisMark> marks = marksComputer.marksIterator(viewStart, viewEnd);\n\n        int tZeroOffset = chart.isBottomBased() ? 0 : 1;\n        int bZeroOffset = chart.isBottomBased() ? 1 : 0;\n\n        int currentExtent = maxExtent;\n\n        while (marks.hasNext()) {\n            AxisMark mark = marks.next();\n\n            int y = SwingUtilities.convertPoint(chart, 0, mark.getPosition(), this).y;\n\n            if (y < chartMask.y - tZeroOffset ||\n                y >= chartMask.y + chartMask.height + bZeroOffset) continue;\n\n            Component painter = marksPainter.getPainter(mark);\n            painter.setSize(painter.getPreferredSize());\n            int markWidth = painter.getWidth();\n            int markOffsetY = painter.getHeight() / 2;\n\n            if (y + markOffsetY < clip.y ||\n                y - markOffsetY >= clip.y + clip.height) continue;\n\n            maxExtent = Math.max(maxExtent, markWidth);\n\n            paintVerticalTick(g, mark, y, clip, chartMask);\n\n            g.setColor(getForeground());\n            if (location == SwingConstants.WEST) {\n                g.translate(currentExtent - markWidth, y - markOffsetY);\n                painter.paint(g);\n                g.translate(-currentExtent + markWidth, -y + markOffsetY);\n            } else {\n                g.translate(getAxisBasisExtent(), y - markOffsetY);\n                painter.paint(g);\n                g.translate(-getAxisBasisExtent(), -y + markOffsetY);\n            }\n        }\n    }\n\n\n    private ChartDecorator createMeshPainter() {\n        return new ChartDecorator() {\n            public void paint(Graphics2D g, Rectangle dirtyArea, ChartContext context) {\n                paintAxisMesh(g, dirtyArea, dirtyArea);\n            }\n        };\n    }\n\n\n    private class ChartListener extends ChartConfigurationListener.Adapter {\n\n        private boolean updateAxis;\n\n        public void contentsWillBeUpdated(long offsetX, long offsetY,\n                                double scaleX, double scaleY,\n                                long lastOffsetX, long lastOffsetY,\n                                double lastScaleX, double lastScaleY) {\n\n            if (marksComputer instanceof AxisMarksComputer.Abstract) {\n                AxisMarksComputer.Abstract computer =\n                        (AxisMarksComputer.Abstract)marksComputer;\n                updateAxis = computer.refreshConfiguration();\n            } else {\n                updateAxis = true;\n            }\n        }\n\n        public void contentsUpdated(long offsetX, long offsetY,\n                                double scaleX, double scaleY,\n                                long lastOffsetX, long lastOffsetY,\n                                double lastScaleX, double lastScaleY,\n                                int shiftX, int shiftY) {\n\n            if (!updateAxis) {\n                if (horizontal) {\n                    updateAxis = shiftX != 0 ||\n                            lastOffsetX != offsetX ||\n                             lastScaleX != scaleX;\n                } else {\n                    updateAxis = shiftY != 0 ||\n                            lastOffsetY != offsetY ||\n                             lastScaleY != scaleY;\n                }\n            }\n\n            if (updateAxis) repaint();\n\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/AxisMark.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface AxisMark {\n\n    public int getPosition();\n\n\n    public static abstract class Abstract implements AxisMark {\n\n        private final int position;\n\n        public Abstract(int position) {\n            this.position = position;\n        }\n\n        public int getPosition() {\n            return position;\n        }\n\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/AxisMarksComputer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface AxisMarksComputer {\n\n    public static final Iterator<AxisMark> EMPTY_ITERATOR =\n        new Iterator<AxisMark>() {\n            public boolean hasNext() { return false; }\n            public AxisMark next() { throw new NoSuchElementException(); }\n            public void remove() { throw new IllegalStateException(); }\n        };\n\n\n    public Iterator<AxisMark> marksIterator(int start, int end);\n\n\n    public static abstract class Abstract implements AxisMarksComputer {\n\n        protected final ChartContext context;\n\n        protected final int orientation;\n\n        protected final boolean horizontal;\n        protected final boolean reverse;\n\n\n        public Abstract(ChartContext context, int orientation) {\n\n            this.context = context;\n\n            this.orientation = orientation;\n\n            horizontal = orientation == SwingConstants.HORIZONTAL;\n            reverse = horizontal ? context.isRightBased() :\n                                   context.isBottomBased();\n        }\n\n        // Return minimum distance between two axis marks\n        protected int getMinMarksDistance() {\n            return 50;\n        }\n\n        // Returns true if the configuration changed and axis should be repainted\n        protected boolean refreshConfiguration() {\n            return true;\n        }\n\n    }\n\n\n    public static abstract class AbstractIterator implements Iterator<AxisMark> {\n        public void remove() {\n            throw new UnsupportedOperationException(\n                      \"AxisMarksComputer does not support remove()\"); // NOI18N\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/AxisMarksPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\nimport java.awt.Component;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface AxisMarksPainter {\n\n    public Component getPainter(AxisMark mark);\n\n\n    public static abstract class Abstract extends JLabel implements AxisMarksPainter {\n\n        public Abstract() { setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4)); }\n\n        protected abstract String formatMark(AxisMark mark);\n\n        public Component getPainter(AxisMark mark) {\n            setText(formatMark(mark));\n            return this;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/BitsPerSecMarksPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class BitsPerSecMarksPainter extends AxisMarksPainter.Abstract {\n\n    protected String formatMark(AxisMark mark) {\n        if (!(mark instanceof BytesMark)) return mark.toString();\n        return BytesAxisUtils.formatBitsPerSec((BytesMark)mark);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/Bundle.properties",
    "content": "# Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nBytesAxisUtils_AbbrBytes=B\nBytesAxisUtils_AbbrKiloBytes=KB\nBytesAxisUtils_AbbrMegaBytes=MB\nBytesAxisUtils_AbbrGigaBytes=GB\nBytesAxisUtils_AbbrTeraBytes=TB\nBytesAxisUtils_AbbrPetaBytes=PB\n# Size format, default EN: {value} {units} example: 100 KB\nBytesAxisUtils_SizeFormat={0} {1}\n\nBytesAxisUtils_AbbrBitsPerSec=bit/s\nBytesAxisUtils_AbbrKiloBitsPerSec=Kibit/s\nBytesAxisUtils_AbbrMegaBitsPerSec=Mibit/s\nBytesAxisUtils_AbbrGigaBitsPerSec=Gibit/s\nBytesAxisUtils_AbbrTeraBitsPerSec=Tibit/s\nBytesAxisUtils_AbbrPetaBitsPerSec=Pibit/s\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/BytesAxisUtils.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\nimport java.text.MessageFormat;\nimport java.text.NumberFormat;\nimport java.util.ResourceBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class BytesAxisUtils {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.charts.axis.Bundle\"); // NOI18N\n    public static final String UNITS_B = messages.getString(\"BytesAxisUtils_AbbrBytes\"); // NOI18N\n    public static final String UNITS_KB = messages.getString(\"BytesAxisUtils_AbbrKiloBytes\"); // NOI18N\n    public static final String UNITS_MB = messages.getString(\"BytesAxisUtils_AbbrMegaBytes\"); // NOI18N\n    public static final String UNITS_GB = messages.getString(\"BytesAxisUtils_AbbrGigaBytes\"); // NOI18N\n    public static final String UNITS_TB = messages.getString(\"BytesAxisUtils_AbbrTeraBytes\"); // NOI18N\n    public static final String UNITS_PB = messages.getString(\"BytesAxisUtils_AbbrPetaBytes\"); // NOI18N\n    public static final String UNITS_BPS = messages.getString(\"BytesAxisUtils_AbbrBitsPerSec\"); // NOI18N\n    public static final String UNITS_KBPS = messages.getString(\"BytesAxisUtils_AbbrKiloBitsPerSec\"); // NOI18N\n    public static final String UNITS_MBPS = messages.getString(\"BytesAxisUtils_AbbrMegaBitsPerSec\"); // NOI18N\n    public static final String UNITS_GBPS = messages.getString(\"BytesAxisUtils_AbbrGigaBitsPerSec\"); // NOI18N\n    public static final String UNITS_TBPS = messages.getString(\"BytesAxisUtils_AbbrTeraBitsPerSec\"); // NOI18N\n    public static final String UNITS_PBPS = messages.getString(\"BytesAxisUtils_AbbrPetaBitsPerSec\"); // NOI18N\n    private static final String SIZE_FORMAT = messages.getString(\"BytesAxisUtils_SizeFormat\"); // NOI18N\n    // -----\n\n    public static final long[] bytesUnitsGrid = new long[] { 1, 2, 5, 10, 25, 50, 100, 250, 500 };\n    public static final String[] radixUnits = new String[] { UNITS_B, UNITS_KB, UNITS_MB, UNITS_GB, UNITS_TB, UNITS_PB };\n    public static final String[] radixUnitsBps = new String[] { UNITS_BPS, UNITS_KBPS, UNITS_MBPS, UNITS_GBPS, UNITS_TBPS, UNITS_PBPS };\n\n    private static final NumberFormat FORMAT = NumberFormat.getInstance();\n\n    public static long[] getBytesUnits(double scale, int minDistance) {\n        if (Double.isNaN(scale) || scale == Double.POSITIVE_INFINITY || scale <= 0)\n            return new long[] { -1, -1 };\n\n        long bytesFactor = 1;\n        long bytesRadix  = 0;\n\n        while (true) {\n            for (long l : bytesUnitsGrid)\n                if ((l * scale * bytesFactor) >= minDistance)\n                    return new long[]{l * bytesFactor, bytesRadix};\n\n            bytesFactor *= 1024;\n            bytesRadix  += 1;\n        }\n    }\n\n    public static String getRadixUnits(BytesMark mark) {\n        int radix = mark.getRadix();\n        if (radix < 0 || radix >= radixUnits.length) return \"\"; // NOI18N\n        return radixUnits[radix];\n    }\n\n    public static String getRadixUnitsBps(BytesMark mark) {\n        int radix = mark.getRadix();\n        if (radix < 0 || radix >= radixUnitsBps.length) return \"\"; // NOI18N\n        return radixUnitsBps[radix];\n    }\n\n    public static String formatBytes(BytesMark mark) {\n        int radix = mark.getRadix();\n        long value = mark.getValue() / (long)Math.pow(1024, radix);\n        String units = getRadixUnits(mark);\n\n        return MessageFormat.format(SIZE_FORMAT, FORMAT.format(value), units);\n    }\n\n    public static String formatBitsPerSec(BytesMark mark) {\n        int radix = mark.getRadix();\n        long value = mark.getValue() / (long)Math.pow(1024, radix);\n        String units = getRadixUnitsBps(mark);\n\n        return MessageFormat.format(SIZE_FORMAT, FORMAT.format(value), units);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/BytesMark.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class BytesMark extends LongMark {\n\n    private final int radix;\n\n\n    public BytesMark(long value, int position, int radix) {\n        super(value, position);\n        this.radix = radix;\n    }\n\n\n    public int getRadix() {\n        return radix;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/BytesMarksPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class BytesMarksPainter extends AxisMarksPainter.Abstract {\n\n    protected String formatMark(AxisMark mark) {\n        if (!(mark instanceof BytesMark)) return mark.toString();\n        return BytesAxisUtils.formatBytes((BytesMark)mark);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/DecimalAxisUtils.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DecimalAxisUtils {\n\n    public static final long[] decimalUnitsGrid = new long[] { 1, 2, 5 };\n\n    public static long getDecimalUnits(double scale, int minDistance) {\n        if (Double.isNaN(scale) || scale == Double.POSITIVE_INFINITY || scale <= 0) return -1;\n\n        long decimalFactor = 1;\n\n        while (true) {\n            for (long l : decimalUnitsGrid)\n                if ((l * scale * decimalFactor) >= minDistance)\n                    return l * decimalFactor;\n\n            decimalFactor *= 10;\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/LongMark.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class LongMark extends AxisMark.Abstract {\n\n    private final long value;\n\n\n    public LongMark(long value, int position) {\n        super(position);\n        this.value = value;\n    }\n\n\n    public long getValue() {\n        return value;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/PercentLongMarksPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\nimport java.text.NumberFormat;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class PercentLongMarksPainter extends AxisMarksPainter.Abstract {\n\n    protected final long minValue;\n    protected final long maxValue;\n\n    protected NumberFormat format;\n\n\n    public PercentLongMarksPainter(long minValue, long maxValue) {\n        this.minValue = minValue;\n        this.maxValue = maxValue;\n\n        format = NumberFormat.getPercentInstance();\n    }\n\n\n    protected String formatMark(AxisMark mark) {\n        if (!(mark instanceof LongMark)) return mark.toString();\n        long value = ((LongMark)mark).getValue();\n        float relValue = (float)(value - minValue) / (float)maxValue;\n        return format.format(relValue);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/SimpleLongMarksPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\nimport java.text.NumberFormat;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class SimpleLongMarksPainter extends AxisMarksPainter.Abstract {\n\n    private static final NumberFormat FORMAT = NumberFormat.getInstance();\n\n    protected String formatMark(AxisMark mark) {\n        if (!(mark instanceof LongMark)) return mark.toString();\n        return FORMAT.format(((LongMark)mark).getValue());\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/TimeAxisUtils.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\nimport java.text.DateFormat;\nimport java.text.Format;\nimport java.text.MessageFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.Calendar;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class TimeAxisUtils {\n\n    public static final int NTHNG_NEEDED = 0;\n    public static final int DAY_NEEDED  = 1;\n    public static final int MONTH_NEEDED = 2;\n    public static final int YEAR_NEEDED  = 4;\n\n    public static final int STEP_MSEC    = 1;\n    public static final int STEP_SEC     = 2;\n    public static final int STEP_MIN     = 4;\n    public static final int STEP_HOUR    = 8;\n    public static final int STEP_DAY     = 16;\n    public static final int STEP_WEEK    = 32;\n    public static final int STEP_MONTH   = 64;\n    public static final int STEP_YEAR    = 128;\n\n    public static final String TIME_SEC = createTimeSec();\n    public static final String TIME_MSEC = createTimeMSec(TIME_SEC);\n    public static final String TIME_MIN = createTimeMin();\n\n    public static final String DATE_YEAR = createDateYear();\n    public static final String DATE_MONTH = createDateMonth(DATE_YEAR);\n\n    public static final String DATE_WEEKDAY_SHORT = \"EEE\"; // NOI18N\n    public static final String DATE_WEEKDAY = \"EEEE\"; // NOI18N\n    public static final String DATE_YEARMONTH = \"MMMM\"; // NOI18N\n    public static final String DATE_SINGLEYEAR = \"yyyy\"; // NOI18N\n\n    // time: {0}, date: {1}, time should be first\n    public static final String TIME_DATE_FORMAT = \"{0}, {1}\";\n\n    private static final String PATTERN_CHARS = \"GyMwWDdFEaHkKhmsSzZ\"; // NOI18N\n    private static final Map<String, Format> FORMATS = new HashMap<>();\n    private static final Calendar c1 = Calendar.getInstance();\n    private static final Calendar c2 = Calendar.getInstance();\n\n    public static final long[] timeUnitsGrid = new long[] {\n        1 /*1*/, 2 /*2*/, 5 /*5*/, 10 /*10*/, 20 /*20*/, 50 /*50*/, 100 /*100*/, 250 /*250*/, 500 /*500*/,  // milliseconds\n        1000 /*1*/, 2000 /*2*/, 5000 /*5*/, 10000 /*10*/, 15000 /*15*/, 30000 /*30*/,                       // seconds\n        60000 /*1*/, 120000 /*2*/, 300000 /*5*/, 600000 /*10*/, 900000 /*15*/, 1800000 /*30*/,              // minutes\n        3600000 /*1*/, 7200000 /*2*/, 10800000 /*3*/, 21600000 /*6*/, 43200000 /*12*/,                      // hours\n        86400000 /*1*/, //172800000 /*2*/,                                                                  // days\n        604800000 /*1*/, //1209600000 /*2*/,                                                                // weeks\n        2628000000l /*1*/, 5256000000l /*2*/, 7884000000l /*3*/, 15768000000l /*6*/,                        // months (NOTE: not exactly!!!)\n        31536000000l /*1*/, 63072000000l /*2*/, 157680000000l /*5*/, 315360000000l /*10*/                   // years (NOTE: not exactly!!!)\n    };\n\n    public static long getTimeUnits(double scale, int minDistance) {\n        if (Double.isNaN(scale) || scale == Double.POSITIVE_INFINITY || scale <= 0) return -1;\n\n        for (long l : timeUnitsGrid)\n            if (l * scale >= minDistance)\n                return l;\n        return timeUnitsGrid[timeUnitsGrid.length - 1];\n    }\n\n    public static int getStepFlag(long step) {\n        if (step > 15768000000l) return STEP_YEAR;\n        if (step > 1209600000) return STEP_MONTH;\n        if (step > 172800000) return STEP_WEEK;\n        if (step > 43200000) return STEP_DAY;\n        if (step > 1800000) return STEP_HOUR;\n        if (step > 30000) return STEP_MIN;\n        if (step > 500) return STEP_SEC;\n        return STEP_MSEC;\n    }\n\n    public static int getRangeFlag(long startTime, long endTime) {\n        c1.setTimeInMillis(startTime);\n        c2.setTimeInMillis(endTime);\n\n        if (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR))\n            return YEAR_NEEDED;\n\n        if (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH))\n            return MONTH_NEEDED;\n\n        if (c1.get(Calendar.DAY_OF_YEAR) != c2.get(Calendar.DAY_OF_YEAR))\n            return DAY_NEEDED;\n\n        return NTHNG_NEEDED;\n    }\n\n    public static String getFormatString(long step, long startTime, long endTime) {\n        int stepFlag = getStepFlag(step);\n        int rangeFlag = getRangeFlag(startTime, endTime);\n\n        String time = null;\n        String date = null;\n\n        // time necessary\n        if (stepFlag < STEP_DAY) {\n            // 12:34\n            if (stepFlag > STEP_SEC) time = TIME_MIN;\n            // 12:34:55\n            else if (stepFlag > STEP_MSEC) time = TIME_SEC;\n            // 12:34:55.666\n            else time = TIME_MSEC;\n        }\n\n        // date necessary\n        if (stepFlag > STEP_HOUR || rangeFlag != NTHNG_NEEDED) {\n            // 2009\n            if (stepFlag == STEP_YEAR) date = DATE_SINGLEYEAR;\n            // January\n            else if (stepFlag == STEP_MONTH && rangeFlag < YEAR_NEEDED) date = DATE_YEARMONTH;\n            // Monday\n            else if (stepFlag == STEP_DAY && rangeFlag < MONTH_NEEDED) date = DATE_WEEKDAY;\n            // Jan 10, 2009\n            else if (rangeFlag == YEAR_NEEDED) date = DATE_YEAR;\n            // Jan 10\n            else if (rangeFlag == MONTH_NEEDED || stepFlag > STEP_DAY) date = DATE_MONTH;\n            // Mon\n            else if (rangeFlag == DAY_NEEDED) date = DATE_WEEKDAY_SHORT;\n        }\n\n        if (time == null) return date;\n        else if (date == null) return time;\n        else return MessageFormat.format(TIME_DATE_FORMAT,\n                    time, date);\n    }\n\n    public static String formatTime(Long value, String formatString) {\n        Format format = FORMATS.get(formatString);\n        if (format == null) {\n            format = new SimpleDateFormat(formatString);\n            FORMATS.put(formatString, format);\n        }\n\n        return format.format(value);\n    }\n    \n    public static String formatTime(TimeMark mark) {\n        return formatTime(mark.getValue(), mark.getFormat());\n    }\n\n\n    private static String createTimeSec() {\n        return ((SimpleDateFormat)DateFormat.\n                getTimeInstance(DateFormat.MEDIUM)).\n                toPattern();\n    }\n\n    private static String createTimeMin() {\n        return ((SimpleDateFormat)DateFormat.\n                getTimeInstance(DateFormat.SHORT)).\n                toPattern();\n    }\n\n    private static String createTimeMSec(String timeSec) {\n        return timeSec.replace(\"ss\", \"ss.SSS\"); // NOI18N\n    }\n\n    private static String createDateYear() {\n        return ((SimpleDateFormat)DateFormat.\n                getDateInstance(DateFormat.MEDIUM)).\n                toPattern();\n    }\n\n    private static String createDateMonth(String dateYear) {\n        try {\n            // Remove the year\n            String dateDay = dateYear.replace(\"y\", \"\"); // NOI18N\n            if (dateDay.isEmpty()) return dateDay;\n\n            // Cleanup any leading formatting\n            String firstLetter = dateDay.substring(0, 1);\n            while (!dateDay.isEmpty() && !isPatternChar(firstLetter)) {\n                dateDay = dateDay.substring(1);\n                firstLetter = dateDay.substring(0, 1);\n            }\n\n            // Cleanup any trailing formatting\n            int length = dateDay.length();\n            String lastLetter = dateDay.substring(length - 1, length);\n            // NOTE: '.' seems to be a valid separator to be left here\n            while (length > 0 &&\n                   !\".\".equals(lastLetter) && // NOI18N\n                   !isPatternChar(lastLetter)) {\n                dateDay = dateDay.substring(0, length-- - 1);\n                lastLetter = dateDay.substring(length - 1, length);\n            }\n\n            return dateDay;\n        } catch (Exception e) {\n            // The above is not absolutely failproof\n            return \"MMM d\"; // NOI18N\n        }\n    }\n\n    private static boolean isPatternChar(String s) {\n        return PATTERN_CHARS.contains(s);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/TimeMark.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class TimeMark extends LongMark {\n\n    private final String format;\n\n\n    public TimeMark(long value, int position, String format) {\n        super(value, position);\n        this.format = format;\n    }\n\n\n    public String getFormat() {\n        return format;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/TimeMarksPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class TimeMarksPainter extends AxisMarksPainter.Abstract {\n\n    protected String formatMark(AxisMark mark) {\n        if (!(mark instanceof TimeMark)) return mark.toString();\n        return TimeAxisUtils.formatTime((TimeMark)mark);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/axis/TimelineMarksComputer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.axis;\n\nimport java.util.Iterator;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class TimelineMarksComputer extends AxisMarksComputer.Abstract {\n\n    private final Timeline timeline;\n\n    private double scale;\n    private long step;\n\n    private long firstTimestamp;\n    private long lastTimestamp;\n\n\n    public TimelineMarksComputer(Timeline timeline,\n                                 ChartContext context,\n                                 int orientation) {\n\n        super(context, orientation);\n        this.timeline = timeline;\n\n        scale = -1;\n        step = -1;\n    }\n\n\n    protected int getMinMarksDistance() {\n            return 120;\n        }\n\n    protected boolean refreshConfiguration() {\n        double oldScale = scale;\n        long oldFirstTimestamp = firstTimestamp;\n        long oldLastTimestamp = lastTimestamp;\n\n        if ((horizontal && context.getViewWidth() == 0) ||\n            (!horizontal && context.getViewHeight() == 0)) {\n            scale = -1;\n//        } else if (timeline.getTimestampsCount() == 0) {\n//            // Initial scale\n//            scale = -1;\n        } else {\n            scale = horizontal ? context.getViewWidth(1d) :\n                                 context.getViewHeight(1d);\n        }\n\n        int timestampsCount = timeline.getTimestampsCount();\n        if (horizontal) {\n            firstTimestamp = timestampsCount == 0 ? (long)context.getDataX(0) :\n                                                     timeline.getTimestamp(0);\n            lastTimestamp = timestampsCount == 0 ? (long)context.getDataX(\n                                                    context.getViewportWidth()):\n                                                    Math.max(timeline.getTimestamp\n                                                    (timestampsCount - 1),\n                                                    (long)context.getDataX(\n                                                    context.getViewportWidth()));\n        } else {\n            firstTimestamp = timestampsCount == 0 ? (long)context.getDataY(0) :\n                                                     timeline.getTimestamp(0);\n            lastTimestamp = timestampsCount == 0 ? (long)context.getDataY(\n                                                    context.getViewportWidth()):\n                                                    Math.max(timeline.getTimestamp\n                                                    (timestampsCount - 1),\n                                                    (long)context.getDataY(\n                                                    context.getViewportWidth()));\n        }\n        \n        if (oldScale != scale) {\n\n            if (scale == -1) {\n                step = -1;\n            } else {\n                step = TimeAxisUtils.getTimeUnits(scale, getMinMarksDistance());\n            }\n\n            oldScale = scale;\n            return true;\n        } else {\n            return oldFirstTimestamp != firstTimestamp ||\n                   oldLastTimestamp != lastTimestamp;\n        }\n    }\n\n\n    public Iterator<AxisMark> marksIterator(int start, int end) {\n        if (step == -1) return EMPTY_ITERATOR;\n\n        final long dataStart = horizontal ?\n                               ((long)context.getDataX(start) / step) * step :\n                               ((long)context.getDataY(start) / step) * step;\n        final long dataEnd = horizontal ?\n                               ((long)context.getDataX(end) / step) * step :\n                               ((long)context.getDataY(end) / step) * step;\n        final long iterCount = Math.abs(dataEnd - dataStart) / step + 2;\n        final long[] iterIndex = new long[] { 0 };\n\n        final String format = TimeAxisUtils.getFormatString(step, firstTimestamp,\n                                                            lastTimestamp);\n\n\n        return new AxisMarksComputer.AbstractIterator() {\n\n            public boolean hasNext() {\n                return iterIndex[0] < iterCount;\n            }\n\n            public AxisMark next() {\n                long value = reverse ? dataStart - iterIndex[0] * step :\n                                       dataStart + iterIndex[0] * step;\n                iterIndex[0]++;\n                int position = horizontal ?\n                               Utils.checkedInt(Math.ceil(context.getViewX(value))) :\n                               Utils.checkedInt(Math.ceil(context.getViewY(value)));\n                return new TimeMark(value, position, format);\n            }\n\n        };\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/canvas/BufferedCanvasComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.canvas;\n\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Graphics;\nimport java.awt.GraphicsConfiguration;\nimport java.awt.Image;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport java.awt.Window;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.WindowAdapter;\nimport java.awt.event.WindowEvent;\nimport java.awt.image.VolatileImage;\nimport java.lang.ref.WeakReference;\nimport javax.swing.JComponent;\nimport javax.swing.RepaintManager;\nimport javax.swing.SwingUtilities;\nimport javax.swing.border.Border;\n\n\n/**\n * JComponent optionally using an offscreen buffer to store its appearance. The\n * component can paint its appearance either directly or into an offscreen buffer\n * which may be a BufferedImage or VolatileImage. The buffer type can be changed\n * anytime during the runtime.\n *\n * Setting a Border to BufferedComponent and its descendants isn't supported,\n * setBorder(Border) with a non-null value throws an IllegalArgumentException.\n * To define a border for BufferedComponent, create a container for the component\n * and assign it the Border.\n *\n * WARNING: Methods of this component must be strictly called in EDT unless\n * allowed otherwise for a particular method.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class BufferedCanvasComponent extends JComponent {\n\n    // No offscreen buffer\n    public static final int BUFFER_NONE = 0;\n    // BufferedImage offscreen buffer\n    public static final int BUFFER_IMAGE = 1;\n    // VolatileImage offscreen buffer\n    public static final int BUFFER_VOLATILE_IMAGE = 2;\n\n\n    // Not a public API, for testing purposes only\n    private static final int DEFAULT_BUFFER =\n            Integer.getInteger(\"graphs.defaultBuffer\", BUFFER_VOLATILE_IMAGE); // NOI18N\n    // Not a public API, for testing purposes only\n//    private static final boolean ACCEL_DISABLED =\n//            Boolean.getBoolean(\"graphs.noAcceleration\"); // NOI18N\n    private static final boolean ACCEL_DISABLED = true;\n\n\n    private static final Insets ZERO_INSETS = new Insets(0, 0, 0, 0);\n    \n    private int bufferType = -1; // Defined in constructor\n    private float accelerationPriority = .5f;\n    \n    private Image offscreenImage = null;\n    private WeakReference<Image> offscreenImageReference = new WeakReference<>(offscreenImage);\n    \n    private Rectangle invalidOffscreenArea = new Rectangle();\n    \n    \n    // --- Public constructors -------------------------------------------------\n    \n    public BufferedCanvasComponent() {\n         this(DEFAULT_BUFFER);\n    }\n    \n    public BufferedCanvasComponent(int bufferType) {\n        super();\n        setOpaque(true);\n        setBufferType(bufferType);\n        addHierarchyListener(new VisibilityHandler());\n    }\n    \n    \n    // --- Protected paintContents ---------------------------------------------\n    \n    protected abstract void paintComponent(Graphics g, Rectangle invalidArea);\n    \n    \n    // --- Protected event handlers --------------------------------------------\n    \n    /**\n     * Called when bounds of the component changed. Default implementation calls\n     * weaklyReleaseOffscreenImage() if the component has been resized.\n     * \n     * @param oldBounds old bounds of the component.\n     * @param newBounds new bounds of the component.\n     */\n    protected void reshaped(Rectangle oldBounds, Rectangle newBounds) {\n        if (!oldBounds.getSize().equals(newBounds.getSize()))\n            releaseOffscreenImage();\n        }\n    \n    /**\n     * Called when the component has been shown. Default implementation does\n     * nothing.\n     */\n    protected void shown() {\n        invalidateImage();\n        repaintDirty();\n    }\n    \n    /**\n     * Called when the component has been hidden. Default implementation calls\n     * weaklyReleaseOffscreenImage().\n     */\n    protected void hidden() {\n        weaklyReleaseOffscreenImage();\n    }\n    \n    /**\n     * Called when the owner window becomes iconified (minimized). Default\n     * implementation calls hidden().\n     */\n    protected void windowIconified() {\n        hidden();\n    }\n    \n    /**\n     * Called when the owner window becomes deiconified (restored). Default\n     * implementation calls shown().\n     */\n    protected void windowDeiconified() {\n        shown();\n    }\n    \n    \n    // --- Protected offscreen image access ------------------------------------\n    \n    protected final void setBufferType(int bufferType) {\n        if (this.bufferType == bufferType) return;\n        if (bufferType == BUFFER_NONE ||\n            bufferType == BUFFER_IMAGE ||\n            bufferType == BUFFER_VOLATILE_IMAGE) {\n            this.bufferType = bufferType;\n            releaseOffscreenImage();\n            repaintImpl(0, 0, getWidth(), getHeight());\n        } else {\n            throw new IllegalArgumentException(\"Unknown buffer type: \" + bufferType); // NOI18N\n        }\n    }\n    \n    protected final int getBufferType() {\n        return bufferType;\n    }\n    \n    protected final boolean isBuffered() {\n        return bufferType != BUFFER_NONE;\n    }\n\n    protected final void setAccelerationPriority(float priority) {\n        accelerationPriority = priority;\n\n        Image image = offscreenImageReference.get();\n        if (image != null) image.setAccelerationPriority(accelerationPriority);\n    }\n\n    protected final float getAccelerationPriority() {\n        return accelerationPriority;\n    }\n    \n    /**\n     * Releases reference to the offscreen image. The image will be re-created\n     * and its entire area painted on next paintComponent(Graphics) invocation.\n     */\n    protected final void releaseOffscreenImage() {\n        if (offscreenImage != null) offscreenImage.flush();\n        offscreenImage = null;\n        offscreenImageReference.clear();\n    }\n    \n    /**\n     * Releases reference to the offscreen image but keeps a weak reference.\n     * The image will be reused on next paintComponent(Graphics) invocation if\n     * still referenced, otherwise it will be re-created.\n     * \n     * Note that invocation of this method doesn't invalidate the offscreen image,\n     * it will be eventually reused without updating. To be sure that reused image\n     * will be updated on next paintComponent(Graphics) invocation, invoke the\n     * invalidateOffscreenImage() or invalidateOffscreenImage(Rectangle) method\n     * after weakly releasing the offscreen image.\n     */\n    protected final void weaklyReleaseOffscreenImage() {\n        if (offscreenImage != null) offscreenImage.flush();\n        offscreenImage = null;\n    }\n    \n    /**\n     * Marks the whole offscreen image as invalid. The image will be updated on\n     * next paintComponent(Graphics) invocation.\n     */\n    protected final void invalidateImage() {\n        invalidOffscreenArea.setBounds(0, 0, getWidth(), getHeight());\n    }\n    \n    /**\n     * Marks part of the offscreen image as invalid. Invalid area of the image\n     * will be updated on next paintComponent(Graphics) invocation.\n     * \n     * @param invalidArea the part of the offscreen image to be marked as invalid.\n     */\n    protected final void invalidateImage(Rectangle invalidArea) {\n        if (invalidArea.isEmpty()) return;\n        addInvalidArea(invalidArea);\n    }\n    \n    /**\n     * Repaints the whole component if needed.\n     */\n    public final void repaintDirty() {\n        if (!isDirty()) return;\n        repaintImpl(0, 0, getWidth(), getHeight());\n    }\n\n    /**\n     * Invalidates and repaints the component.\n     */\n    public final void repaintDirty(Rectangle dirtyArea) {\n        addInvalidArea(dirtyArea);\n        repaintImpl(invalidOffscreenArea.x, invalidOffscreenArea.y,\n                    invalidOffscreenArea.width, invalidOffscreenArea.height);\n    }\n\n    /**\n     * Repaints the whole component - either calls repaint() or performs\n     * an accelerated repaint directly accessing component's Graphics.\n     */\n    public final void repaintDirtyAccel() {\n        if (!isDirty()) return;\n//        if (bufferType != BUFFER_NONE && offscreenImage == null) return;\n\n        if (!ACCEL_DISABLED && canDirectlyAccessGraphics()) {\n            Graphics g = getGraphics();\n            try {\n                if (bufferType != BUFFER_NONE) { // Painting to an offscreen image\n                    Graphics offscreenGraphics = offscreenImage.getGraphics();\n                    try {\n                        paintComponent(offscreenGraphics, invalidOffscreenArea);\n                    } finally {\n                        offscreenGraphics.dispose();\n                    }\n                    g.drawImage(offscreenImage, 0, 0, null);\n                } else { // Painting directly to the provided Graphics\n                    paintComponent(g, invalidOffscreenArea);\n                }\n                invalidOffscreenArea.setBounds(0, 0, 0, 0);\n            } finally {\n                g.dispose();\n            }\n        } else {\n            repaintImpl(0, 0, getWidth(), getHeight());\n        }\n    }\n\n    private void repaintImpl(int x, int y, int w, int h) {\n        repaint(x, y, w, h);\n//        paintImmediately(0, 0, getWidth(), getHeight());\n    }\n\n    boolean isDirty() {\n        return !invalidOffscreenArea.isEmpty();\n    }\n    \n    \n    // --- Core implementation -------------------------------------------------\n    \n    private void addInvalidArea(Rectangle invalidArea) {\n        if (invalidArea.x > getWidth() ||\n                (invalidArea.x + invalidArea.width < 0)) return;\n        if (invalidArea.y > getHeight() ||\n                (invalidArea.y + invalidArea.height < 0)) return;\n\n        int origX = invalidArea.x;\n        int origY = invalidArea.y;\n\n        invalidArea.x = Math.max(invalidArea.x, 0);\n        invalidArea.y = Math.max(invalidArea.y, 0);\n        invalidArea.width = Math.min(origX + invalidArea.width, getWidth()) -\n                invalidArea.x;\n        invalidArea.height = Math.min(origY + invalidArea.height, getHeight()) -\n                invalidArea.y;\n        \n        if (invalidOffscreenArea.isEmpty())\n            invalidOffscreenArea.setBounds(invalidArea);\n        else invalidOffscreenArea.add(invalidArea);\n    }\n    \n    public final void paint(Graphics g) {\n        super.paint(g);\n    }\n    \n    protected final void paintComponent(Graphics g) {\n        if (bufferType != BUFFER_NONE) { // Painting to an offscreen image\n            \n            // Determine offscreen image state\n            int imageState = updateOffscreenImage();\n\n            // Offscreen image has to be recreated\n            if (imageState == VolatileImage.IMAGE_INCOMPATIBLE) {\n                // Create new offscreen image\n                offscreenImage = createOffscreenImage();\n                // Return if VolatileImage not supported\n                if (offscreenImage == null) return;\n                // Set image acceleration\n                offscreenImage.setAccelerationPriority(accelerationPriority);\n                // Weakly reference new offscreen image\n                offscreenImageReference = new WeakReference<>(offscreenImage);\n                // Set IMAGE_RESTORED flag to repaint the offscreen image\n                imageState = VolatileImage.IMAGE_RESTORED;\n\n//                try {\n//                    Graphics2D gr = (Graphics2D)offscreenImage.getGraphics();\n//\n//                    // These commands cause the Graphics2D object to clear to (0,0,0,0).\n//                    gr.setComposite(AlphaComposite.Src);\n//                    gr.setColor(Color.black);\n//                    gr.fillRect(0, 0, getWidth(), getHeight()); // Clears the image.\n//\n////                    g.drawImage(bimage,null,0,0);\n//                } finally {\n//                    // It's always best to dispose of your Graphics objects.\n//                    g.dispose();\n//                }\n            }\n\n            // Offscreen image has to be repainted\n            if (imageState == VolatileImage.IMAGE_RESTORED)\n                invalidOffscreenArea.setBounds(0, 0, getWidth(), getHeight());\n\n            // Update the offscreen image if needed\n            if (isDirty()) {\n                Graphics offscreenGraphics = offscreenImage.getGraphics();\n                try {\n                    paintComponent(offscreenGraphics, invalidOffscreenArea);\n                } finally {\n                    offscreenGraphics.dispose();\n                }\n            }\n            \n            // Paint the offscreen image to onscreen graphics\n            g.drawImage(offscreenImage, 0, 0, null);\n//                try {\n//                    javax.imageio.ImageIO.write((java.awt.image.BufferedImage)offscreenImage, \"png\", new java.io.File(\"C:\\\\Temp\\\\debugimg\\\\image\" + System.currentTimeMillis() + \".png\"));\n//                } catch (Exception e) {System.err.println(e);}\n        \n        } else { // Painting directly to the provided Graphics\n            \n            // Resolve clipping rectangle\n            Rectangle clipRect = g.getClipBounds();\n            if (clipRect == null) clipRect = new Rectangle(0, 0, getWidth(), getHeight());\n\n            // Paint directly to the Graphics\n            paintComponent(g, clipRect);\n            \n        }\n\n        invalidOffscreenArea.setBounds(0, 0, 0, 0);\n    }\n    \n    protected final void paintChildren(Graphics g) {\n        super.paintChildren(g);\n    }\n    \n    protected final void paintBorder(Graphics g) {\n        // Not implemented\n    }\n    \n    public final void update(Graphics g) {\n        // Not implemented\n    }\n\n\n    protected boolean canDirectlyAccessGraphics() {\n        // TODO: what about popup windows / tooltips???\n\n        // TODO: some of the queries could be cached instead of polling,\n        // for example isShowing(), isOpaque(), getParent() etc.\n\n//////        // Shouldn't access graphics - no buffering would cause flickering\n//////        if (bufferType == BUFFER_NONE) return false;\n\n        // Cannot access graphics - there are some child components\n        if (getComponentCount() != 0) return false;\n\n        // Cannot access graphics - component doesn't fully control its area\n        if (!isOpaque()) return false;\n\n        // Cannot access graphics - not in Swing tree\n        if (!(getParent() instanceof JComponent)) return false;\n\n        // Cannot access graphics - component not showing, doesn't make sense\n        if (!isShowing()) return false;\n\n        // Cannot access graphics - component area is not up-to-date\n        Rectangle dirtyRegion = RepaintManager.currentManager(this).\n                                getDirtyRegion((JComponent)getParent());\n        if (dirtyRegion != null && dirtyRegion.width > 0 &&\n            dirtyRegion.height > 0) return false;\n\n        // --- Reused from JViewport -------------------------------------------\n\n        Rectangle clip = new Rectangle(0, 0, getWidth(), getHeight());\n        Rectangle oldClip = new Rectangle();\n        Rectangle tmp2 = null;\n        Container parent;\n        Component lastParent = null;\n        int x, y, w, h;\n\n        for (parent = this; parent != null && isLightweightComponent(parent); parent = parent.getParent()) {\n            x = parent.getX();\n            y = parent.getY();\n            w = parent.getWidth();\n            h = parent.getHeight();\n\n            oldClip.setBounds(clip);\n            SwingUtilities.computeIntersection(0, 0, w, h, clip);\n            if (!clip.equals(oldClip)) return false;\n\n            if (lastParent != null && parent instanceof JComponent &&\n               !((JComponent)parent).isOptimizedDrawingEnabled()) {\n                Component comps[] = parent.getComponents();\n                int index = 0;\n\n                for (int i = comps.length - 1 ;i >= 0; i--) {\n                    if (comps[i] == lastParent) {\n                    index = i - 1;\n                    break;\n                    }\n                }\n\n                while (index >= 0) {\n                    tmp2 = comps[index].getBounds(tmp2);\n                    if (tmp2.intersects(clip)) return false;\n                    index--;\n                }\n            }\n            clip.x += x;\n            clip.y += y;\n            lastParent = parent;\n        }\n\n        // No Window parent.\n        if (parent == null) return false;\n\n        return true;\n    }\n    \n    \n    private Image createOffscreenImage() {\n        switch (bufferType) {\n            case BUFFER_VOLATILE_IMAGE:\n                // Flush current offscreen image to release resources\n                if (offscreenImage != null) offscreenImage.flush();\n                return createVolatileImage(getWidth(), getHeight());\n            case BUFFER_IMAGE:\n                // Flush current offscreen image to release resources\n                // TODO: is flush() really needed for BufferedImage?\n                if (offscreenImage != null) offscreenImage.flush();\n                return createImage(getWidth(), getHeight());\n            default:\n                return null;\n        }\n    }\n    \n    private int updateOffscreenImage() {\n        // Update offscreen image reference\n        if (offscreenImage == null) offscreenImage = offscreenImageReference.get();\n        \n        // Offscreen image not available\n        if (offscreenImage == null) return VolatileImage.IMAGE_INCOMPATIBLE;\n        \n        // Buffered image is always valid\n        if (bufferType != BUFFER_VOLATILE_IMAGE) return VolatileImage.IMAGE_OK;\n        \n        // Determine GraphicsConfiguration context\n        GraphicsConfiguration gConfiguration = getGraphicsConfiguration();\n        if (gConfiguration == null) return VolatileImage.IMAGE_INCOMPATIBLE;\n        \n        // Return Volatile image state\n        return ((VolatileImage)offscreenImage).validate(gConfiguration);\n    }\n    \n    \n    public final void reshape(int x, int y, int w, int h) {\n        Rectangle oldBounds = getBounds();\n        Rectangle newBounds = new Rectangle(x, y, w, h);\n\t\n        super.reshape(x, y, w, h);\n        reshaped(oldBounds, newBounds);\n    }\n    \n    /**\n     * The viewport \"scrolls\" its child (called the \"view\") by the\n     * normal parent/child clipping (typically the view is moved in\n     * the opposite direction of the scroll).  A non-<code>null</code> border,\n     * or non-zero insets, isn't supported, to prevent the geometry\n     * of this component from becoming complex enough to inhibit\n     * subclassing.  To create a <code>JViewport</code> with a border,\n     * add it to a <code>JPanel</code> that has a border.\n     * <p>Note:  If <code>border</code> is non-<code>null</code>, this\n     * method will throw an exception as borders are not supported on\n     * a <code>JViewPort</code>.\n     *\n     * @param border the <code>Border</code> to set\n     * @exception IllegalArgumentException this method is not implemented\n     */\n    public final void setBorder(Border border) {\n        if (border != null)\n            throw new IllegalArgumentException(\"setBorder() not supported\"); // NOI18N\n    }\n    \n    /**\n     * Returns the insets (border) dimensions as (0,0,0,0), since borders\n     * are not supported on a <code>JViewport</code>.\n     *\n     * @return a <code>Rectange</code> of zero dimension and zero origin\n     * @see #setBorder\n     */\n    public final Insets getInsets() {\n        return ZERO_INSETS;\n    }\n\n    /**\n     * Returns an <code>Insets</code> object containing this\n     * <code>JViewport</code>s inset values.  The passed-in\n     * <code>Insets</code> object will be reinitialized, and\n     * all existing values within this object are overwritten.\n     *\n     * @param insets the <code>Insets</code> object which can be reused\n     * @return this viewports inset values\n     * @see #getInsets\n     * @beaninfo\n     *   expert: true\n     */\n    public final Insets getInsets(Insets insets) {\n        insets.set(0, 0, 0, 0);\n        return insets;\n    }\n    \n    \n    // --- Visibility Handler --------------------------------------------------\n    \n    private class VisibilityHandler extends WindowAdapter implements HierarchyListener {\n        private Window lastParentWindow;\n        \n        public void hierarchyChanged(HierarchyEvent e) {\n            if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) != 0) {\n                Window parentWindow = SwingUtilities.getWindowAncestor(BufferedCanvasComponent.this);\n                if (lastParentWindow != parentWindow) {\n                    if (lastParentWindow != null) lastParentWindow.removeWindowListener(VisibilityHandler.this);\n                    if (parentWindow != null) parentWindow.addWindowListener(VisibilityHandler.this);\n                    lastParentWindow = parentWindow;\n                }\n            }\n            \n            if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                if (isShowing()) BufferedCanvasComponent.this.shown();\n                else BufferedCanvasComponent.this.hidden();\n            }\n        }\n        \n        public void windowDeiconified(WindowEvent e) {\n            BufferedCanvasComponent.this.windowDeiconified();\n        }\n        \n        public void windowIconified(WindowEvent e) {\n            BufferedCanvasComponent.this.windowIconified();\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/canvas/InteractiveCanvasComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.canvas;\n\nimport java.awt.Cursor;\nimport java.awt.Rectangle;\nimport java.awt.event.AdjustmentEvent;\nimport java.awt.event.AdjustmentListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseMotionListener;\nimport java.awt.event.MouseWheelEvent;\nimport java.awt.event.MouseWheelListener;\nimport javax.swing.JScrollBar;\nimport javax.swing.SwingUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class InteractiveCanvasComponent extends TransformableCanvasComponent {\n\n    public static final int ZOOM_ALL = 0;\n    public static final int ZOOM_X = 1;\n    public static final int ZOOM_Y = 2;\n\n    private ScrollBarManager hScrollBarManager;\n    private ScrollBarManager vScrollBarManager;\n\n    private MousePanHandler mousePanHandler;\n    private int mousePanningButton;\n    private Cursor mousePanningCursor;\n\n    private int zoomMode;\n    private double mouseZoomingFactor;\n    private MouseZoomHandler mouseZoomHandler;\n\n\n    public InteractiveCanvasComponent() {\n        mousePanningButton = MouseEvent.BUTTON1;\n        mousePanningCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);\n        enableMousePanning();\n\n        zoomMode = ZOOM_ALL;\n        mouseZoomingFactor = 1.05d;\n        enableMouseZooming();\n    }\n\n\n    public final void attachHorizontalScrollBar(JScrollBar scrollBar) {\n        if (hScrollBarManager == null) hScrollBarManager = new ScrollBarManager();\n        hScrollBarManager.attachScrollBar(scrollBar, true);\n    }\n\n    public final void detachHorizontalScrollBar() {\n        if (hScrollBarManager != null) hScrollBarManager.detachScrollBar();\n        hScrollBarManager = null;\n    }\n\n    public final void attachVerticalScrollBar(JScrollBar scrollBar) {\n        if (vScrollBarManager == null) vScrollBarManager = new ScrollBarManager();\n        vScrollBarManager.attachScrollBar(scrollBar, false);\n    }\n\n    public final void detachVerticalScrollBar() {\n        if (vScrollBarManager != null) vScrollBarManager.detachScrollBar();\n        vScrollBarManager = null;\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void updateScrollBars(boolean valueOnly) {\n        if (hScrollBarManager != null) hScrollBarManager.syncScrollBar(valueOnly);\n        if (vScrollBarManager != null) vScrollBarManager.syncScrollBar(valueOnly);\n    }\n\n    protected void offsetChanged(long oldOffsetX, long oldOffsetY,\n                                 long newOffsetX, long newOffsetY) {\n        super.offsetChanged(oldOffsetX, oldOffsetY, newOffsetX, newOffsetY);\n        updateScrollBars(true);\n    }\n\n    protected void scaleChanged(double oldScaleX, double oldScaleY,\n                                double newScaleX, double newScaleY) {\n        super.scaleChanged(oldScaleX, oldScaleY, newScaleX, newScaleY);\n        updateScrollBars(false);\n    }\n\n    protected void dataBoundsChanged(long dataOffsetX, long dataOffsetY,\n                                     long dataWidth, long dataHeight,\n                                     long oldDataOffsetX, long oldDataOffsetY,\n                                     long oldDataWidth, long oldDataHeight) {\n        super.dataBoundsChanged(dataOffsetX, dataOffsetY, dataWidth, dataHeight,\n                                oldDataOffsetX, oldDataOffsetY, oldDataWidth, oldDataHeight);\n        updateScrollBars(false);\n    }\n\n    protected void reshaped(Rectangle oldBounds, Rectangle newBounds) {\n        super.reshaped(oldBounds, newBounds);\n        updateScrollBars(false);\n    }\n\n\n    // --- ScrollBarManager ----------------------------------------------------\n\n    private class ScrollBarManager implements AdjustmentListener, MouseWheelListener {\n\n        private static final int SCROLLBAR_UNIT_INCREMENT = 20;\n\n        private JScrollBar scrollBar;\n        private double scrollBarFactor;\n        boolean horizontal;\n\n        boolean internalChange;\n\n\n        public void attachScrollBar(JScrollBar scrollBar, boolean horizontal) {\n            if (this.scrollBar == scrollBar) return;\n            if (this.scrollBar != null) detachScrollBar();\n            this.scrollBar = scrollBar;\n            this.horizontal = horizontal;\n            scrollBar.addAdjustmentListener(this);\n            scrollBar.addMouseWheelListener(this);\n            if (!horizontal)\n                InteractiveCanvasComponent.this.addMouseWheelListener(this);\n        }\n\n        public void detachScrollBar() {\n            if (scrollBar == null) return;\n            if (!horizontal)\n                InteractiveCanvasComponent.this.removeMouseWheelListener(this);\n            scrollBar.removeMouseWheelListener(this);\n            scrollBar.removeAdjustmentListener(this);\n            scrollBar = null;\n        }\n\n        public void syncScrollBar(boolean valueOnly) {\n            internalChange = true;\n\n            if (valueOnly) {\n\n                long offsetX = getOffsetX();\n                long offsetY = getOffsetY();\n\n                int value = horizontal ? getInt(offsetX) : getInt(offsetY);\n                if (reversedValue()) value = scrollBar.getMaximum() -\n                                           scrollBar.getVisibleAmount() - value;\n\n                scrollBar.setValue(value);\n\n            } else {\n\n                updateFactor();\n\n                long offsetX = getOffsetX();\n                long offsetY = getOffsetY();\n                long maxOffsetX = getMaxOffsetX();\n                long maxOffsetY = getMaxOffsetY();\n\n                int value   = horizontal ? getInt(offsetX) : getInt(offsetY);\n                int extent  = horizontal ? getInt(getWidth()) : getInt(getHeight());\n                int maximum = horizontal ? getInt(maxOffsetX) : getInt(maxOffsetY);\n\n                int unitIncr =  horizontal ? getInt(SCROLLBAR_UNIT_INCREMENT) :\n                                       getInt(SCROLLBAR_UNIT_INCREMENT);\n                int blockIncr = horizontal ? getInt(getWidth() - 20) :\n                                       getInt(getHeight() - 20);\n\n                if (reversedValue()) value = maximum - value;\n\n                scrollBar.setEnabled(maximum > 0);\n                scrollBar.setValues(value, extent, 0, maximum + extent);\n                scrollBar.setUnitIncrement(unitIncr);\n                scrollBar.setBlockIncrement(blockIncr);\n\n            }\n\n            internalChange = false;\n        }\n\n        public void adjustmentValueChanged(AdjustmentEvent e) {\n            if (internalChange) return;\n\n            boolean valueAdjusting = e.getValueIsAdjusting();\n            boolean offsetAdjusting;\n\n            if (horizontal) {\n                offsetAdjusting = isHOffsetAdjusting();\n                if (valueAdjusting && !offsetAdjusting) hOffsetAdjustingStarted();\n                setOffset(getValue(), getOffsetY());\n            } else {\n                offsetAdjusting = isVOffsetAdjusting();\n                if (valueAdjusting && !offsetAdjusting) vOffsetAdjustingStarted();\n                setOffset(getOffsetX(), getValue());\n            }\n\n            repaintDirtyAccel();\n            //            repaintDirty();\n\n            if (!valueAdjusting && offsetAdjusting)\n                // Bugfix #165020, process after all pending updates\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        if (horizontal) hOffsetAdjustingFinished();\n                        else vOffsetAdjustingFinished();\n                        repaintDirty();\n                    }\n                });\n        }\n\n        public long getValue() {\n            long value = scrollBar.getValue();\n            if (reversedValue()) value = scrollBar.getMaximum() -\n                                         scrollBar.getVisibleAmount() - value;\n            return (long)((double)value / scrollBarFactor);\n        }\n\n\n        private void updateFactor() {\n            long maxOffsetX = getMaxOffsetX();\n            long maxOffsetY = getMaxOffsetY();\n\n            if (horizontal) {\n                int width = getWidth();\n                scrollBarFactor = ((maxOffsetX + width) > Integer.MAX_VALUE) ?\n                ((double)Integer.MAX_VALUE / (double)(maxOffsetX + width)) : 1;\n            } else {\n                int height = getHeight();\n                scrollBarFactor = ((maxOffsetY + height) > Integer.MAX_VALUE) ?\n                ((double)Integer.MAX_VALUE / (double)(maxOffsetY + height)) : 1;\n            }\n        }\n\n        private boolean reversedValue() {\n            return horizontal ? isRightBased() : isBottomBased();\n        }\n\n        private int getInt(long value) {\n            return (int)((double)value * scrollBarFactor);\n        }\n\n\n        public void mouseWheelMoved(MouseWheelEvent e) {\n            // Mouse wheel zooming takes precedence over scrolling\n            if (isMouseZoomingEnabled() &&\n                e.getSource() == InteractiveCanvasComponent.this) return;\n\n            // Change the ScrollBar value\n            if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {\n                int unitsToScroll = e.getUnitsToScroll();\n                int direction = unitsToScroll < 0 ? -1 : 1;\n                if (unitsToScroll != 0) {\n                    int increment = scrollBar.getUnitIncrement(direction);\n                    int oldValue = scrollBar.getValue();\n                    int newValue = oldValue + increment * unitsToScroll;\n                    newValue = Math.max(Math.min(newValue, scrollBar.getMaximum() -\n                            scrollBar.getVisibleAmount()), scrollBar.getMinimum());\n                    if (oldValue != newValue) scrollBar.setValue(newValue);\n                }\n            }\n        }\n\n    }\n\n\n    // --- Mouse panning support -----------------------------------------------\n\n    public final void setMousePanningEnabled(boolean enabled) {\n        if (enabled) enableMousePanning();\n        else disableMousePanning();\n    }\n\n    public final void enableMousePanning() {\n        if (mousePanHandler != null) return;\n\n        mousePanHandler = new MousePanHandler();\n        addMouseListener(mousePanHandler);\n        addMouseMotionListener(mousePanHandler);\n    }\n\n    public final void disableMousePanning() {\n        if (mousePanHandler == null) return;\n\n        removeMouseListener(mousePanHandler);\n        removeMouseMotionListener(mousePanHandler);\n        mousePanHandler = null;\n\n        setCursor(Cursor.getDefaultCursor());\n    }\n\n    public final boolean isMousePanningEnabled() {\n        return mousePanHandler != null;\n    }\n\n    public final boolean panningPossible() {\n        return getContentsWidth() > getWidth() ||\n               getContentsHeight() > getHeight();\n    }\n\n    public final void setMousePanningButton(int mousePanningButton) {\n        this.mousePanningButton = mousePanningButton;\n    }\n\n    public final int getMousePanningButton() {\n        return mousePanningButton;\n    }\n\n    public final void setMousePanningCursor(Cursor mousePanningCursor) {\n        this.mousePanningCursor = mousePanningCursor;\n    }\n\n    public final Cursor getMousePanningCursor() {\n        return mousePanningCursor;\n    }\n\n    private class MousePanHandler extends MouseAdapter implements MouseMotionListener {\n\n        private boolean dragging;\n        private int lastMouseDragX;\n        private int lastMouseDragY;\n\n        public void mousePressed(MouseEvent e) {\n            dragging = panningPossible() && e.getButton() == mousePanningButton;\n            if (!dragging) return;\n\n            lastMouseDragX = e.getX();\n            lastMouseDragY = e.getY();\n\n            if (mousePanningCursor != null && isMousePanningEnabled())\n                setCursor(mousePanningCursor);\n\n            if (!isOffsetAdjusting()) offsetAdjustingStarted();\n        }\n\n        public void mouseReleased(MouseEvent e) {\n            dragging = false;\n            if (mousePanningCursor != null) setCursor(Cursor.getDefaultCursor());\n\n            if (isOffsetAdjusting())\n                // Bugfix #165020, process after all pending updates\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        offsetAdjustingFinished();\n                        repaintDirty();\n                    }\n                });\n        }\n\n        public void mouseDragged(MouseEvent e) {\n            if (!dragging) return;\n\n            int mouseDragX = e.getX();\n            int mouseDragY = e.getY();\n\n            long oldOffsetX = getOffsetX();\n            long oldOffsetY = getOffsetY();\n\n            if (lastMouseDragX != 0 && lastMouseDragY != 0) {\n                int mouseDragDx = isRightBased()  ? mouseDragX - lastMouseDragX :\n                                                    lastMouseDragX - mouseDragX;\n                int mouseDragDy = isBottomBased() ? mouseDragY - lastMouseDragY :\n                                                    lastMouseDragY - mouseDragY;\n\n                setOffset(oldOffsetX + mouseDragDx, oldOffsetY + mouseDragDy);\n\n                repaintDirtyAccel();\n//                repaintDirty();\n            }\n\n            if (getOffsetX() != oldOffsetX) lastMouseDragX = mouseDragX;\n            if (getOffsetY() != oldOffsetY) lastMouseDragY = mouseDragY;\n        }\n\n        public void mouseMoved(MouseEvent e) {}\n    }\n\n\n    // --- Generic zooming support ---------------------------------------------\n\n    public final void setZoomMode(int zoomMode) {\n        this.zoomMode = zoomMode;\n    }\n\n    public final int getZoomMode() {\n        return zoomMode;\n    }\n\n    public final void zoom(int centerX, int centerY, double factor) {\n\n        // Cache current fitting\n        boolean fitsWidth = fitsWidth();\n        boolean fitsHeight = fitsHeight();\n\n        // Both fits, no zoom\n        if (fitsWidth && fitsHeight) return;\n\n        // Resolve current scale\n        double scaleX = getScaleX();\n        double scaleY = getScaleY();\n\n        // Bad scale, no zoom\n        if (scaleX * scaleY == 0) return;\n\n        // Compute new scale\n        double newScaleX = zoomMode == ZOOM_Y || fitsWidth ? scaleX : scaleX * factor;\n        double newScaleY = zoomMode == ZOOM_X || fitsHeight ? scaleY : scaleY * factor;\n\n        // Cache data at zoom center\n        double dataX = getDataX(centerX);\n        double dataY = getDataY(centerY);\n\n        // Set new scale\n        setScale(newScaleX, newScaleY);\n\n        // Cache current offset\n        long offsetX = getOffsetX();\n        long offsetY = getOffsetY();\n\n        // Update x-offset to centerX if needed\n        if (!fitsWidth && zoomMode != ZOOM_Y) {\n            double dataWidth = dataX - getDataOffsetX();\n            long viewWidth = (long)Math.ceil(getViewWidth(dataWidth));\n            offsetX = isRightBased() ?\n                      viewWidth - getWidth() + centerX : viewWidth - centerX;\n        }\n\n        // Update y-offset to centerY if needed\n        if (!fitsHeight && zoomMode != ZOOM_X) {\n            double dataHeight = dataY - getDataOffsetY();\n            long viewHeight = (long)Math.ceil(getViewHeight(dataHeight));\n            offsetY = isBottomBased() ?\n                      viewHeight - getHeight() + centerY : viewHeight - centerY;\n        }\n\n        // Set new offset\n        setOffset(offsetX, offsetY);\n\n    }\n\n\n    // --- Mouse zooming support -----------------------------------------------\n\n    public final void setMouseZoomingEnabled(boolean enabled) {\n        if (enabled) enableMouseZooming();\n        else disableMouseZooming();\n    }\n\n    public final void enableMouseZooming() {\n        if (mouseZoomHandler != null) return;\n\n        mouseZoomHandler = new MouseZoomHandler();\n        addMouseWheelListener(mouseZoomHandler);\n    }\n\n    public final void disableMouseZooming() {\n        if (mouseZoomHandler == null) return;\n\n        removeMouseWheelListener(mouseZoomHandler);\n        mouseZoomHandler = null;\n    }\n\n    public final boolean isMouseZoomingEnabled() {\n        return mouseZoomHandler != null;\n    }\n\n    public final double getMouseZoomingFactor() {\n        return mouseZoomingFactor;\n    }\n\n    public final void setMouseZoomingFactor(double mouseZoomingFactor) {\n        this.mouseZoomingFactor = mouseZoomingFactor;\n    }\n\n    private class MouseZoomHandler implements MouseWheelListener {\n        public void mouseWheelMoved(MouseWheelEvent e) {\n            if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {\n                zoom(e.getX(), e.getY(), Math.pow(mouseZoomingFactor,\n                                                  -e.getUnitsToScroll()));\n                repaintDirty();\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/canvas/TransformableCanvasComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.canvas;\n\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class TransformableCanvasComponent extends BufferedCanvasComponent {\n\n    // Decides whether to repaint whole contents or just a dirty area\n    // for a whole shift including incoming invalidArea:\n    //\n    // shiftedSaved - invalidArea / total >= SHIFT_ACCEL_LIMIT is accelerated\n    // shiftedSaved - invalidArea / total <  SHIFT_ACCEL_LIMIT is repainted\n    //\n    // TODO: should probably be customizable\n    private static final float SHIFT_ACCEL_LIMIT = 0.15f;\n\n    // Decides whether to repaint whole contents or just a dirty area\n    // for a diagonal shift:\n    //\n    // shiftedSaved / total >= DIAGONAL_SHIFT_ACCEL_LIMIT is accelerated\n    // shiftedSaved / total <  DIAGONAL_SHIFT_ACCEL_LIMIT is repainted\n    //\n    // TODO: should probably be customizable\n    private static final float DIAGONAL_SHIFT_ACCEL_LIMIT = 0.3f;\n\n    // Displayed data insets\n    private Insets viewInsets;\n\n    // Displayed data bounds; data coordinate system\n    private long dataOffsetX, pendingDataOffsetX;\n    private long dataOffsetY, pendingDataOffsetY;\n    private long dataWidth, pendingDataWidth;\n    private long dataHeight, pendingDataHeight;\n\n    // Displayed data bounds; component coordinate system\n    private long contentsOffsetX;\n    private long contentsOffsetY;\n    private long contentsWidth;\n    private long contentsHeight;\n\n    // Transform from data to component coordinate system\n    private double scaleX, lastScaleX, oldScaleX /* just for setDataBounds*/;\n    private double scaleY, lastScaleY, oldScaleY /* just for setDataBounds*/;\n\n    // Viewport (JComponent) bounds, component coordinate system\n    private long offsetX, maxOffsetX, lastOffsetX;\n    private long offsetY, maxOffsetY, lastOffsetY;\n\n    // Horizontal and vertical basis\n    private boolean rightBased;\n    private boolean bottomBased;\n\n    // Sticky sides\n    private boolean tracksDataOffsetX;\n    private boolean tracksDataOffsetY;\n    private boolean tracksDataWidth;\n    private boolean tracksDataHeight;\n\n    // Fit to chart\n    private boolean fitsWidth;\n    private boolean fitsHeight;\n\n    // Accelerated shift\n    private long dx;\n    private long dy;\n\n    // Offset adjusting\n    private int hOffsetAdjustingCounter = 0;\n    private int vOffsetAdjustingCounter = 0;\n\n\n    public TransformableCanvasComponent() {\n        viewInsets = new Insets(0, 0, 0, 0);\n\n        scaleX = 1d;\n        scaleY = 1d;\n\n        tracksDataOffsetX = true;\n        tracksDataWidth = true;\n\n        dx = 0;\n        dy = 0;\n    }\n\n\n    // --- Paint support -------------------------------------------------------\n\n    protected abstract void paintContents(Graphics g, Rectangle invalidArea);\n\n    protected void contentsWillBeUpdated(long offsetX, long offsetY,\n                               double scaleX, double scaleY,\n                               long lastOffsetX, long lastOffsetY,\n                               double lastScaleX, double lastScaleY) {\n    }\n\n    protected void contentsUpdated(long offsetX, long offsetY,\n                               double scaleX, double scaleY,\n                               long lastOffsetX, long lastOffsetY,\n                               double lastScaleX, double lastScaleY,\n                               int shiftX, int shiftY) {\n    }\n\n\n    // --- Insets --------------------------------------------------------------\n\n    public final void setViewInsets(Insets insets) {\n        viewInsets.set(insets.top, insets.left, insets.bottom, insets.right);\n    }\n\n    public final Insets getViewInsets() {\n        return new Insets(viewInsets.top, viewInsets.left,\n                          viewInsets.bottom, viewInsets.right);\n    }\n\n\n    // --- Canvas orientation --------------------------------------------------\n\n    public final void setRightBased(boolean rightBased) {\n        this.rightBased = rightBased;\n    }\n\n    public final boolean isRightBased() {\n        return rightBased;\n    }\n\n    public final void setBottomBased(boolean bottomBased) {\n        this.bottomBased = bottomBased;\n    }\n\n    public final boolean isBottomBased() {\n        return bottomBased;\n    }\n\n\n    // --- Sticky data ---------------------------------------------------------\n\n    public final void setTracksDataOffsetX(boolean tracksDataOffsetX) {\n        this.tracksDataOffsetX = tracksDataOffsetX;\n        // TODO: anything special for runtime change???\n    }\n\n    public final boolean tracksDataOffsetX() {\n        return tracksDataOffsetX;\n    }\n\n    public final void setTracksDataOffsetY(boolean tracksDataOffsetY) {\n        this.tracksDataOffsetY = tracksDataOffsetY;\n        // TODO: anything special for runtime change???\n    }\n\n    public final boolean tracksDataOffsetY() {\n        return tracksDataOffsetY;\n    }\n\n    public final void setTracksDataWidth(boolean tracksDataWidth) {\n        this.tracksDataWidth = tracksDataWidth;\n        // TODO: anything special for runtime change???\n    }\n\n    public final boolean tracksDataWidth() {\n        return tracksDataWidth;\n    }\n\n    public final boolean currentlyFollowingDataWidth() {\n        return tracksDataWidth && !fitsWidth && offsetX == maxOffsetX;\n    }\n\n    public final void setTracksDataHeight(boolean tracksDataHeight) {\n        this.tracksDataHeight = tracksDataHeight;\n        // TODO: anything special for runtime change???\n    }\n\n    public final boolean tracksDataHeight() {\n        return tracksDataHeight;\n    }\n\n    public final boolean currentlyFollowingDataHeight() {\n        return tracksDataHeight && !fitsHeight && offsetY == maxOffsetY;\n    }\n\n\n    // --- Fixed scale ---------------------------------------------------------\n\n    public final void setFitsWidth(boolean fitsWidth) {\n        if (this.fitsWidth == fitsWidth) return;\n        this.fitsWidth = fitsWidth;\n\n        if (fitsWidth) {\n            updateScale();\n        } else {\n            updateContentsWidths();\n            updateMaxOffsets();\n        }\n    }\n\n    public final boolean fitsWidth() {\n        return fitsWidth;\n    }\n\n    public final void setFitsHeight(boolean fitsHeight) {\n        if (this.fitsHeight == fitsHeight) return;\n        this.fitsHeight = fitsHeight;\n\n        if (fitsHeight) {\n            updateScale();\n        } else {\n            updateContentsWidths();\n            updateMaxOffsets();\n        }\n    }\n\n    public final boolean fitsHeight() {\n        return fitsHeight;\n    }\n\n\n    // --- Transform support ---------------------------------------------------\n\n    public final long getOffsetX() {\n        return offsetX;\n    }\n\n    protected final long getMaxOffsetX() {\n        return maxOffsetX;\n    }\n\n    public final long getOffsetY() {\n        return offsetY;\n    }\n\n    protected final long getMaxOffsetY() {\n        return maxOffsetY;\n    }\n\n    public final void setOffset(long offsetX, long offsetY) {\n        offsetX = Math.max(Math.min(offsetX, maxOffsetX), 0);\n        offsetY = Math.max(Math.min(offsetY, maxOffsetY), 0);\n\n        if (this.offsetX == offsetX &&\n            this.offsetY == offsetY) return;\n\n        long oldOffsetX = this.offsetX;\n        long oldoffsetY = this.offsetY;\n\n        dx += this.offsetX - offsetX;\n        this.offsetX = offsetX;\n\n        dy += this.offsetY - offsetY;\n        this.offsetY = offsetY;\n\n        offsetChanged(oldOffsetX, oldoffsetY, offsetX, offsetY);\n    }\n\n    protected void offsetChanged(long oldOffsetX, long oldOffsetY,\n                                 long newOffsetX, long newOffsetY) {\n        // To be overridden by descendants\n    }\n\n\n    public final double getScaleX() {\n        return scaleX;\n    }\n\n    public final double getScaleY() {\n        return scaleY;\n    }\n\n    public final void setScale(double scaleX, double scaleY) {\n        if (this.scaleX == scaleX && this.scaleY == scaleY) return;\n\n        double origScaleX = this.scaleX;\n        double origScaleY = this.scaleY;\n\n        this.scaleX = scaleX;\n        this.scaleY = scaleY;\n\n        updateContentsWidths();\n        updateMaxOffsets();\n\n        // Fix offsets according to changed maxOffsets\n        setOffset(offsetX, offsetY);\n\n        scaleChanged(origScaleX, origScaleY, scaleX, scaleY);\n//        dataBoundsChanged();\n\n        invalidateImage();\n    }\n\n    protected void scaleChanged(double oldScaleX, double oldScaleY,\n                                double newScaleX, double newScaleY) {\n        // To be overridden by descendants\n    }\n\n\n    // --- Bounds support ------------------------------------------------------\n\n    public final long getDataOffsetX() {\n        return dataOffsetX;\n    }\n\n    public final long getDataOffsetY() {\n        return dataOffsetY;\n    }\n\n    public final long getDataWidth() {\n        return dataWidth;\n    }\n\n    public final long getDataHeight() {\n        return dataHeight;\n    }\n\n    public final long getContentsWidth() {\n        return contentsWidth;\n    }\n\n    public final long getContentsHeight() {\n        return contentsHeight;\n    }\n\n    public final void setDataBounds(long dataOffsetX, long dataOffsetY, long dataWidth, long dataHeight) {\n        if (this.dataOffsetX == dataOffsetX && this.dataOffsetY == dataOffsetY &&\n            this.dataWidth == dataWidth && this.dataHeight == dataHeight) return;\n\n        if (isHOffsetAdjusting() && contentsWidth >= getWidth() && this.dataWidth != dataWidth ||\n            isVOffsetAdjusting() && contentsHeight >= getHeight() && this.dataHeight != dataHeight) {\n            pendingDataOffsetX = dataOffsetX;\n            pendingDataOffsetY = dataOffsetY;\n            pendingDataWidth = dataWidth;\n            pendingDataHeight = dataHeight;\n        } else {\n            long oldOffsetX = offsetX;\n            long oldOffsetY = offsetY;\n            long oldContentsOffsetX = contentsOffsetX;\n            long oldContentsOffsetY = contentsOffsetY;\n            long oldMaxOffsetX = maxOffsetX;\n            long oldMaxOffsetY = maxOffsetY;\n\n            long oldDataOffsetX = this.dataOffsetX;\n            long oldDataOffsetY = this.dataOffsetY;\n            long oldDataWidth = this.dataWidth;\n            long oldDataHeight = this.dataHeight;\n\n            this.dataOffsetX = dataOffsetX;\n            this.dataOffsetY = dataOffsetY;\n            this.dataWidth = dataWidth;\n            this.dataHeight = dataHeight;\n\n            contentsOffsetX = (long)Math.ceil(getViewWidth(dataOffsetX));\n            contentsOffsetY = (long)Math.ceil(getViewHeight(dataOffsetY));\n\n            updateScale();\n            updateContentsWidths();\n            updateMaxOffsets();\n\n            long newOffsetX = offsetX;\n            long newOffsetY = offsetY;\n\n            if (!fitsWidth) {\n                if (tracksDataWidth && offsetX == oldMaxOffsetX) {\n                    newOffsetX = maxOffsetX;\n                } else if (oldScaleX == scaleX &&\n                          (!tracksDataOffsetX || offsetX != 0)) {\n                    newOffsetX = offsetX + oldContentsOffsetX - contentsOffsetX;\n                }\n            }\n\n            if (!fitsHeight) {\n                if (tracksDataHeight && offsetY == oldMaxOffsetY) {\n                    newOffsetY = maxOffsetY;\n                } else if (oldScaleY == scaleY &&\n                          (!tracksDataOffsetY || offsetY != 0)) {\n                    newOffsetY = offsetY + oldContentsOffsetY - contentsOffsetY;\n                }\n            }\n\n            long dxx = dx;\n            long dyy = dy;\n\n            setOffset(newOffsetX, newOffsetY);\n\n            dataBoundsChanged(dataOffsetX, dataOffsetY, dataWidth, dataHeight,\n                              oldDataOffsetX, oldDataOffsetY, oldDataWidth, oldDataHeight);\n\n            dx = fitsWidth ? 0 : dxx + (oldContentsOffsetX - contentsOffsetX) - (offsetX - oldOffsetX);\n            dy = fitsHeight ? 0 : dyy + (oldContentsOffsetY - contentsOffsetY) - (offsetY - oldOffsetY);\n\n            oldScaleX = scaleX;\n            oldScaleY = scaleY;\n\n            pendingDataOffsetX = -1;\n            pendingDataOffsetY = -1;\n            pendingDataWidth = -1;\n            pendingDataHeight = -1;\n        }\n    }\n\n    protected void dataBoundsChanged(long dataOffsetX, long dataOffsetY,\n                                     long dataWidth, long dataHeight,\n                                     long oldDataOffsetX, long oldDataOffsetY,\n                                     long oldDataWidth, long oldDataHeight) {\n        // To be overridden by descendants\n    }\n\n\n    // --- Offset adjusting ----------------------------------------------------\n\n    protected final void offsetAdjustingStarted() {\n        hOffsetAdjustingCounter++;\n        vOffsetAdjustingCounter++;\n\n        pendingDataOffsetX = -1;\n        pendingDataOffsetY = -1;\n        pendingDataWidth = -1;\n        pendingDataHeight = -1;\n    }\n\n    protected final void offsetAdjustingFinished() {\n        hOffsetAdjustingCounter--;\n        vOffsetAdjustingCounter--;\n\n        if (!isOffsetAdjusting() && (pendingDataWidth != -1 || pendingDataHeight != -1))\n            setDataBounds(pendingDataOffsetX, pendingDataOffsetY,\n                          pendingDataWidth, pendingDataHeight);\n    }\n\n    protected final boolean isOffsetAdjusting() {\n        return isHOffsetAdjusting() || isVOffsetAdjusting();\n    }\n\n    protected final void hOffsetAdjustingStarted() {\n        hOffsetAdjustingCounter++;\n\n        pendingDataOffsetX = -1;\n        pendingDataOffsetY = -1;\n        pendingDataWidth = -1;\n        pendingDataHeight = -1;\n    }\n\n    protected final void hOffsetAdjustingFinished() {\n        hOffsetAdjustingCounter--;\n\n        if (!isOffsetAdjusting() && pendingDataWidth != -1)\n            setDataBounds(pendingDataOffsetX, pendingDataOffsetY,\n                          pendingDataWidth, pendingDataHeight);\n    }\n\n    protected final boolean isHOffsetAdjusting() {\n        return hOffsetAdjustingCounter > 0;\n    }\n\n    protected final void vOffsetAdjustingStarted() {\n        vOffsetAdjustingCounter++;\n\n        pendingDataOffsetX = -1;\n        pendingDataOffsetY = -1;\n        pendingDataWidth = -1;\n        pendingDataHeight = -1;\n    }\n\n    protected final void vOffsetAdjustingFinished() {\n        vOffsetAdjustingCounter--;\n\n        if (!isOffsetAdjusting() && pendingDataHeight != -1)\n            setDataBounds(pendingDataOffsetX, pendingDataOffsetY,\n                          pendingDataWidth, pendingDataHeight);\n    }\n\n    protected final boolean isVOffsetAdjusting() {\n        return vOffsetAdjustingCounter > 0;\n    }\n\n\n    // --- Coordinate systems conversion support -------------------------------\n\n    protected final double getViewX(double dataX) {\n        return getViewX(dataX, false);\n    }\n\n    protected final double getReversedViewX(double dataX) {\n        return getViewX(dataX, true);\n    }\n\n    private double getViewX(double dataX, boolean reverse) {\n        if ((rightBased && !reverse) || (!rightBased && reverse)) {\n            return ((dataOffsetX - dataX) * scaleX) +\n                    offsetX + getWidth() - viewInsets.right;\n        } else {\n            return ((dataX - dataOffsetX) * scaleX) -\n                               offsetX + viewInsets.left;\n        }\n    }\n\n    protected final double getViewY(double dataY) {\n        return getViewY(dataY, false);\n    }\n\n    protected final double getReversedViewY(double dataY) {\n        return getViewY(dataY, true);\n    }\n\n    private double getViewY(double dataY, boolean reverse) {\n        if ((bottomBased && !reverse) || (!bottomBased && reverse)) {\n            return ((dataOffsetY - dataY) * scaleY) +\n                    offsetY + getHeight() - viewInsets.bottom;\n        } else {\n            return ((dataY - dataOffsetY) * scaleY) -\n                               offsetY + viewInsets.top;\n        }\n    }\n\n    protected final double getViewWidth(double dataWidth) {\n        return dataWidth * scaleX;\n    }\n\n    protected final double getViewHeight(double dataHeight) {\n        return dataHeight * scaleY;\n    }\n\n\n    protected final double getDataX(double viewX) {\n        return getDataX(viewX, false);\n    }\n\n    protected final double getReversedDataX(double viewX) {\n        return getDataX(viewX, true);\n    }\n\n    private double getDataX(double viewX, boolean reverse) {\n        if ((rightBased && !reverse) || (!rightBased && reverse)) {\n            return dataOffsetX - ((viewX + viewInsets.right -\n                                            offsetX - getWidth()) / scaleX);\n        } else {\n            return ((viewX + offsetX - viewInsets.left) /\n                               scaleX) + dataOffsetX;\n        }\n    }\n\n    protected final double getDataY(double viewY) {\n        return getDataY(viewY, false);\n    }\n\n    protected final double getReversedDataY(double viewY) {\n        return getDataY(viewY, true);\n    }\n\n    private double getDataY(double viewY, boolean reverse) {\n        if ((bottomBased && !reverse) || (!bottomBased && reverse)) {\n            return dataOffsetY - ((viewY + viewInsets.bottom -\n                                            offsetY - getHeight()) / scaleY);\n        } else {\n            return ((viewY + offsetY - viewInsets.top) /\n                               scaleY) + dataOffsetY;\n        }\n    }\n\n    protected final double getDataWidth(double viewWidth) {\n        return viewWidth / scaleX;\n    }\n\n    protected final double getDataHeight(double viewHeight) {\n        return viewHeight / scaleY;\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    boolean isDirty() {\n        if (translationPending()) return true;\n        else return super.isDirty();\n    }\n\n    private boolean translationPending() {\n        if (lastScaleX != scaleX || lastScaleY != scaleY) return false;\n        return dx != 0 || dy != 0;\n    }\n\n    protected void reshaped(Rectangle oldBounds, Rectangle newBounds) {\n        super.reshaped(oldBounds, newBounds);\n\n        // Save sticky sides\n        // TODO: implement also followsOffsetX, followsOffsetY!\n        boolean followsWidth = currentlyFollowingDataWidth();\n        boolean followsHeight = currentlyFollowingDataHeight();\n\n        updateScale();\n        updateContentsWidths();\n        updateMaxOffsets();\n\n        // Fix offsets according to changed maxOffsets\n        setOffset(followsWidth ? maxOffsetX : offsetX,\n                  followsHeight ? maxOffsetY : offsetY);\n    }\n\n    protected final void paintComponent(Graphics g, Rectangle invalidArea) {\n        int shiftX = 0;\n        int shiftY = 0;\n\n        contentsWillBeUpdated(offsetX, offsetY, scaleX, scaleY,\n                              lastOffsetX, lastOffsetY, lastScaleX, lastScaleY);\n\n        if (!translationPending()) {\n            // No translation\n            paintContents(g, invalidArea);\n        } else {\n            // Translation\n            int width = getWidth();\n            int height = getHeight();\n\n            if (Math.abs(dx) >= width || Math.abs(dy) >= height) {\n                // Translation outside of visible area\n                paintContents(g, new Rectangle(0, 0, width, height));\n            } else {\n                // Translation in visible area\n                int idx = rightBased ? -(int)dx : (int)dx;\n                int idy = bottomBased ? -(int)dy : (int)dy;\n\n                // Total component area\n                int total = width * height;\n                // Area of the contents saved by shift\n                int shiftedSaved = (width - Math.abs(idx)) * (height - Math.abs(idy));\n\n                if (idx != 0 && idy != 0 && shiftedSaved < total * DIAGONAL_SHIFT_ACCEL_LIMIT) {\n                    // DIAGONAL_SHIFT_ACCEL_LIMIT not met for diagonal shift\n                    paintContents(g, new Rectangle(0, 0, width, height));\n                } else {\n                    // Saved rectangle\n                    Rectangle viewport = new Rectangle(idx, idy, width, height);\n                    Rectangle savedRect = viewport.intersection(\n                            new Rectangle(0, 0, width, height));\n\n                    // InvalidArea to repaint\n                    Rectangle invalidRect = invalidArea.intersection(savedRect);\n\n                    // Area of invalidRect\n                    int invalidAfterShift = invalidRect.isEmpty() ? 0 :\n                                         invalidRect.width * invalidRect.height;\n\n                    // Total saved area\n                    int savedTotal = shiftedSaved - invalidAfterShift;\n\n                    if (savedTotal < total * SHIFT_ACCEL_LIMIT) {\n                        // SHIFT_ACCEL_LIMIT not met for shift\n                        paintContents(g, new Rectangle(0, 0, width, height));\n                    } else {\n                        // Shift\n                        shift(g, idx, idy, width, height);\n\n                        // Repaint original invalidArea if needed\n                        if (invalidAfterShift != 0) paintContents(g, invalidRect);\n\n                        shiftX = idx;\n                        shiftY = idy;\n                    }\n                }\n            }\n        }\n\n        contentsUpdated(offsetX, offsetY, scaleX, scaleY, lastOffsetX, lastOffsetY,\n                        lastScaleX, lastScaleY, shiftX, shiftY);\n\n        dx = 0;\n        dy = 0;\n        lastOffsetX = offsetX;\n        lastOffsetY = offsetY;\n        lastScaleX = scaleX;\n        lastScaleY = scaleY;\n    }\n\n    private void shift(Graphics g, int idx, int idy, int width, int height) {\n        Rectangle areaToRepaint = new Rectangle();\n\n        if (idx == 0) {\n            // Vertical shift\n            if (idy > 0) {\n                // --- Shift down --------------------------------------\n                g.copyArea(0, 0, width, height - idy, 0, idy);\n                areaToRepaint.setBounds(0, 0, width, idy);\n            } else {\n                // --- Shift up ----------------------------------------\n                g.copyArea(0, -idy, width, height + idy, 0, idy);\n                areaToRepaint.setBounds(0, height + idy, width, -idy);\n            }\n        } else if (idy == 0) {\n            // Horizontal shift\n            if (idx > 0) {\n                // --- Shift right -------------------------------------\n                g.copyArea(0, 0, width - idx, height, idx, 0);\n                areaToRepaint.setBounds(0, 0, idx, height);\n            } else {\n                // --- Shift left --------------------------------------\n                g.copyArea(-idx, 0, width + idx, height, idx, 0);\n                areaToRepaint.setBounds(width + idx, 0, -idx, height);\n            }\n        } else {\n            // Diagonal shift\n            if (idx > 0) {\n                // Shift right\n                if (idy > 0) {\n                    // --- Shift right down ------------------------\n                    g.copyArea(0, 0, width - idx, height - idy, idx, idy);\n                    areaToRepaint.setBounds(0, 0, width, idy);\n                    paintContents(g, areaToRepaint);\n                    areaToRepaint.setBounds(0, idy, idx, height - idy);\n                } else {\n                    // --- Shift right up --------------------------\n                    g.copyArea(0, -idy, width - idx, height + idy, idx, idy);\n                    areaToRepaint.setBounds(0, height + idy, width, -idy);\n                    paintContents(g, areaToRepaint);\n                    areaToRepaint.setBounds(0, 0, idx, height + idy);\n                }\n            } else {\n                // Shift left\n                if (idy > 0) {\n                    // --- Shift left down -------------------------\n                    g.copyArea(-idx, 0, width + idx, height - idy, idx, idy);\n                    areaToRepaint.setBounds(0, 0, width, idy);\n                    paintContents(g, areaToRepaint);\n                    areaToRepaint.setBounds(width + idx, idy, -idx, height - idy);\n                } else {\n                    // --- Shift left up ---------------------------\n                    g.copyArea(-idx, -idy, width + idx, height + idy, idx, idy);\n                    areaToRepaint.setBounds(0, height + idy, width, -idy);\n                    paintContents(g, areaToRepaint);\n                    areaToRepaint.setBounds(width + idx, 0, -idx, height + idy);\n                }\n            }\n        }\n\n        paintContents(g, areaToRepaint);\n    }\n\n\n    private void updateScale() {\n        if (!fitsWidth && !fitsHeight) return;\n\n        double newScaleX;\n        double newScaleY;\n\n        if (fitsWidth)\n             newScaleX = (double)(getWidth() - viewInsets.left - viewInsets.right) /\n                         (double)dataWidth;\n        else newScaleX = scaleX;\n\n        if (fitsHeight)\n             newScaleY = (double)(getHeight() - viewInsets.top - viewInsets.bottom) /\n                         (double)dataHeight;\n        else newScaleY = scaleY;\n\n        setScale(newScaleX, newScaleY);\n    }\n\n    private void updateContentsWidths() {\n        if (fitsWidth) contentsWidth = getWidth();\n        else contentsWidth = (long)Math.floor(getViewWidth(dataWidth)) + viewInsets.left +\n                             viewInsets.right;\n\n        if (fitsHeight) contentsHeight = getHeight();\n        else contentsHeight = (long)Math.floor(getViewHeight(dataHeight)) + viewInsets.top +\n                              viewInsets.bottom;\n    }\n\n    private void updateMaxOffsets() {\n        int width = getWidth();\n        int height = getHeight();\n\n        maxOffsetX = width == 0 ? 0 : Math.max(contentsWidth - width, 0);\n        maxOffsetY = height == 0 ? 0 : Math.max(contentsHeight - height, 0);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/swing/CrossBorderLayout.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.swing;\n\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Insets;\nimport java.awt.LayoutManager2;\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.swing.SwingConstants;\n\n/**\n * A BorderLayout-like layout manager allowing to cross the border components in\n * corners. Use addLayoutComponent(Component, CONSTRAINT[])\n * to add the components. CONSTRAINT is one of the following: SwingConstants.CENTER,\n * SwingConstants.NORTH, SwingConstants.WEST, SwingConstants.SOUTH, SwingConstants.EAST,\n * SwingConstants.NORTH_WEST, SwingConstants.NORTH_EAST, SwingConstants.SOUTH_WEST,\n * SwingConstants.SOUTH_EAST.\n *\n * Note: addLayoutComponent(String, Component) is not supported by CrossBorderLayout.\n *\n * @author Jiri Sedlacek\n */\npublic class CrossBorderLayout implements LayoutManager2 {\n\n    private static final int NONE = Integer.MIN_VALUE;\n\n    private Map<Component, Integer[]> map = new HashMap<>();\n\n    private Component north;\n    private Component west;\n    private Component south;\n    private Component east;\n    private Component center;\n\n\n    // --- Public API ----------------------------------------------------------\n\n    public void addLayoutComponent(Component comp, Object constraints) {\n        if (constraints instanceof Integer[]) {\n            addLayoutComponent(comp, (Integer[])constraints);\n        } else {\n            throw new IllegalArgumentException(\"Illegal constraints: \" + constraints); // NOI18N\n        }\n    }\n\n    public void removeLayoutComponent(Component comp) {\n        synchronized (comp.getTreeLock()) {\n            if (comp == center) {\n                center = null;\n                map.remove(center);\n            } else if (comp == north) {\n                north = null;\n                map.remove(north);\n            } else if (comp == south) {\n                south = null;\n                map.remove(south);\n            } else if (comp == east) {\n                east = null;\n                map.remove(east);\n            } else if (comp == west) {\n                west = null;\n                map.remove(west);\n            }\n        }\n    }\n\n    public Component getLayoutComponent(int constraint) {\n        if (constraint == SwingConstants.NORTH) return north;\n        if (constraint == SwingConstants.WEST) return west;\n        if (constraint == SwingConstants.SOUTH) return south;\n        if (constraint == SwingConstants.EAST) return east;\n        if (constraint == SwingConstants.CENTER) return center;\n        throw new IllegalArgumentException(\"Illegal constraint: \" + // NOI18N\n                constraintName(constraint));\n    }\n\n    public Object getConstraints(Component comp) {\n        if (comp == null) return null;\n        return map.get(comp);\n    }\n    \n    public Object getConstraints(int constraint) {\n        Component comp = getLayoutComponent(constraint);\n        if (comp == null) return null;\n        return map.get(comp);\n    }\n\n    public Dimension preferredLayoutSize(Container parent) {\n        synchronized (parent.getTreeLock()) {\n            Dimension dim = new Dimension(0, 0);\n            Dimension cen = center != null ? center.getPreferredSize() : null;\n\n            if (north != null) dim.height += north.getPreferredSize().height;\n            if (cen   != null) dim.height += cen.height;\n            if (south != null) dim.height += south.getPreferredSize().height;\n\n            if (west != null) dim.width += west.getPreferredSize().width;\n            if (cen  != null) dim.width += cen.width;\n            if (east != null) dim.width += east.getPreferredSize().width;\n\n            Insets insets = parent.getInsets();\n            dim.width += insets.left + insets.right;\n            dim.height += insets.top + insets.bottom;\n\n            return dim;\n        }\n    }\n\n    public Dimension minimumLayoutSize(Container parent) {\n        synchronized (parent.getTreeLock()) {\n            Dimension dim = new Dimension(0, 0);\n            Dimension cen = center != null ? center.getMinimumSize() : null;\n\n            if (north != null) dim.height += north.getMinimumSize().height;\n            if (cen   != null) dim.height += cen.height;\n            if (south != null) dim.height += south.getMinimumSize().height;\n\n            if (west != null) dim.width += west.getMinimumSize().width;\n            if (cen   != null) dim.width += cen.width;\n            if (east != null) dim.width += east.getMinimumSize().width;\n\n            Insets insets = parent.getInsets();\n            dim.width += insets.left + insets.right;\n            dim.height += insets.top + insets.bottom;\n\n            return dim;\n        }\n    }\n\n    public void layoutContainer(Container parent) {\n        synchronized (parent.getTreeLock()) {\n            Insets insets = parent.getInsets();\n            int top = insets.top;\n            int bottom = parent.getHeight() - insets.bottom;\n            int height = parent.getHeight() - insets.bottom - insets.top;\n\n            int left = insets.left;\n            int right = parent.getWidth() - insets.right;\n            int width = parent.getWidth() - insets.right - insets.left;\n\n            int northHeight = north != null ? north.getPreferredSize().height : 0;\n            int southHeight = south != null ? south.getPreferredSize().height : 0;\n            int westWidth = west != null ? west.getPreferredSize().width : 0;\n            int eastWidth = east != null ? east.getPreferredSize().width : 0;\n\n            if (center != null) {\n                center.setBounds(left + westWidth, top + northHeight,\n                width - eastWidth - westWidth, height - southHeight - northHeight);\n            }\n\n            if (north != null) {\n                Integer[] constraints = map.get(north);\n                int leftOffset = constraints[0] != NONE ? westWidth : 0;\n                int rightOffset = constraints[2] != NONE ? eastWidth : 0;\n                north.setBounds(left + westWidth - leftOffset, top,\n                width - eastWidth - westWidth + leftOffset + rightOffset, northHeight);\n            }\n\n            if (south != null) {\n                Integer[] constraints = map.get(south);\n                int leftOffset = constraints[0] != NONE ? westWidth : 0;\n                int rightOffset = constraints[2] != NONE ? eastWidth : 0;\n                south.setBounds(left + westWidth - leftOffset, bottom - southHeight,\n                width - eastWidth - westWidth + leftOffset + rightOffset, southHeight);\n            }\n\n            if (west != null) {\n                Integer[] constraints = map.get(west);\n                int topOffset = constraints[0] != NONE ? northHeight : 0;\n                int bottomOffset = constraints[2] != NONE ? southHeight : 0;\n                west.setBounds(left, top + northHeight - topOffset, westWidth,\n                height - southHeight - northHeight + topOffset + bottomOffset);\n            }\n\n            if (east != null) {\n                Integer[] constraints = map.get(east);\n                int topOffset = constraints[0] != NONE ? northHeight : 0;\n                int bottomOffset = constraints[2] != NONE ? southHeight : 0;\n                east.setBounds(right - eastWidth, top + northHeight - topOffset,\n                eastWidth, height - southHeight - northHeight + topOffset + bottomOffset);\n            }\n        }\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void addLayoutComponent(Component comp, Integer[] constraints) {\n        if (constraints.length == 0)\n            throw new IllegalArgumentException(\"At least one location is required: \" + // NOI18N\n                                               toString(constraints));\n        if (constraints.length > 3)\n            throw new IllegalArgumentException(\"Up to three locations are required: \" + // NOI18N\n                                               toString(constraints));\n\n        constraints = normalizedConstraints(constraints);\n\n        synchronized (comp.getTreeLock()) {\n            if (isNorth(constraints)) {\n                north = comp;\n                map.put(comp, constraints);\n            } else if (isWest(constraints)) {\n                west = comp;\n                map.put(comp, constraints);\n            } else if (isSouth(constraints)) {\n                south = comp;\n                map.put(comp, constraints);\n            } else if (isEast(constraints)) {\n                east = comp;\n                map.put(comp, constraints);\n            } else if (isCenter(constraints)) {\n                center = comp;\n                map.put(comp, constraints);\n            }\n        }\n    }\n\n    \n    private static boolean isNorth(Integer[] constraints) {\n        return constraints[1] == SwingConstants.NORTH;\n    }\n\n    private static boolean isWest(Integer[] constraints) {\n        return constraints[1] == SwingConstants.WEST;\n    }\n\n    private static boolean isSouth(Integer[] constraints) {\n        return constraints[1] == SwingConstants.SOUTH;\n    }\n\n    private static boolean isEast(Integer[] constraints) {\n        return constraints[1] == SwingConstants.EAST;\n    }\n\n    private static boolean isCenter(Integer[] constraints) {\n        return constraints[1] == SwingConstants.CENTER;\n    }\n\n\n    private static boolean isBasis(int constraint) {\n        if (constraint == SwingConstants.NORTH) return true;\n        if (constraint == SwingConstants.WEST) return true;\n        if (constraint == SwingConstants.SOUTH) return true;\n        if (constraint == SwingConstants.EAST) return true;\n        if (constraint == SwingConstants.CENTER) return true;\n        return false;\n    }\n\n\n    private static void checkSupported(int constraint) {\n        if (constraint == SwingConstants.NORTH) return;\n        if (constraint == SwingConstants.WEST) return;\n        if (constraint == SwingConstants.SOUTH) return;\n        if (constraint == SwingConstants.EAST) return;\n        if (constraint == SwingConstants.NORTH_WEST) return;\n        if (constraint == SwingConstants.NORTH_EAST) return;\n        if (constraint == SwingConstants.SOUTH_WEST) return;\n        if (constraint == SwingConstants.SOUTH_EAST) return;\n        if (constraint == SwingConstants.CENTER) return;\n        \n        throw new IllegalArgumentException(\"Unsupported constraint: \" + constraint); // NOI18N\n    }\n\n    private static void checkDefining(Integer[] constraints) {\n        boolean b1 = isBasis(constraints[0]);\n        boolean b2 = constraints.length > 1 && isBasis(constraints[1]);\n        boolean b3 = constraints.length == 3 && isBasis(constraints[2]);\n\n        if (!b1 && !b2 && !b3)\n            throw new IllegalArgumentException(\"Constraint does not define position: \" + // NOI18N\n                                               toString(constraints));\n\n        if ((b1 && b2) || (b1 && b3) || (b2 && b3))\n            throw new IllegalArgumentException(\"Constraint defines more than one position: \" + // NOI18N\n                                               toString(constraints));\n    }\n\n    private static Integer[] normalizedConstraints(Integer[] constraints) {\n        // Check that all constraints are supported\n        for (int c : constraints) checkSupported(c);\n\n        // Check that exactly one constraint defines a position\n        checkDefining(constraints);\n\n        Integer[] normalized = null;\n\n        // Create normalized Integer[3] constraint\n        if (constraints.length == 1) {\n            normalized = new Integer[] {NONE, constraints[0], NONE};\n        } else if (constraints.length == 2) {\n            normalized = new Integer[] {constraints[0], constraints[1], NONE};\n        } else {\n            normalized = constraints;\n        }\n\n        // Move the constraint defining a position to Integer[1]\n        if (isBasis(normalized[0])) {\n            int basis = normalized[0];\n            normalized[0] = normalized[1];\n            normalized[1] = basis;\n        } else if (isBasis(normalized[2])) {\n            int basis = normalized[2];\n            normalized[2] = normalized[1];\n            normalized[1] = basis;\n        }\n\n        // Check and normalize Integer[0] and Integer[2]\n        int c0 = normalized[0];\n        int c2 = normalized[2];\n\n        if (c0 != NONE && c0 == c2)\n            throw new IllegalArgumentException(\"Duplicite constraints: \" + // NOI18N\n                                               toString(constraints));\n\n        if (isCenter(normalized)) {\n            if (c0 != NONE || c2 != NONE)\n                throw new IllegalArgumentException(\"Constraint CENTER must be used standalone: \" + // NOI18N\n                                                   toString(constraints));\n        } else {\n            if (isNorth(normalized)) {\n                if (c0 == SwingConstants.NORTH_EAST) {\n                    normalized[2] = c0;\n                    normalized[0] = c2;\n                }\n\n                c0 = normalized[0];\n                c2 = normalized[2];\n\n                if (c0 != NONE && c0 != SwingConstants.NORTH_WEST)\n                    throw new IllegalArgumentException(\"Constraints not compatible: \" + // NOI18N\n                                                       toString(constraints));\n                if (c2 != NONE && c2 != SwingConstants.NORTH_EAST)\n                    throw new IllegalArgumentException(\"Constraints not compatible: \" + // NOI18N\n                                                       toString(constraints));\n            } else if (isSouth(normalized)) {\n                if (c0 == SwingConstants.SOUTH_EAST) {\n                    normalized[2] = c0;\n                    normalized[0] = c2;\n                }\n\n                c0 = normalized[0];\n                c2 = normalized[2];\n\n                if (c0 != NONE && c0 != SwingConstants.SOUTH_WEST)\n                    throw new IllegalArgumentException(\"Constraints not compatible: \" + // NOI18N\n                                                       toString(constraints));\n                if (c2 != NONE && c2 != SwingConstants.SOUTH_EAST)\n                    throw new IllegalArgumentException(\"Constraints not compatible: \" + // NOI18N\n                                                       toString(constraints));\n            } else if (isWest(normalized)) {\n                if (c0 == SwingConstants.SOUTH_WEST) {\n                    normalized[2] = c0;\n                    normalized[0] = c2;\n                }\n\n                c0 = normalized[0];\n                c2 = normalized[2];\n\n                if (c0 != NONE && c0 != SwingConstants.NORTH_WEST)\n                    throw new IllegalArgumentException(\"Constraints not compatible: \" + // NOI18N\n                                                       toString(constraints));\n                if (c2 != NONE && c2 != SwingConstants.SOUTH_WEST)\n                    throw new IllegalArgumentException(\"Constraints not compatible: \" + // NOI18N\n                                                       toString(constraints));\n            } if (isEast(normalized)) {\n                if (c0 == SwingConstants.SOUTH_EAST) {\n                    normalized[2] = c0;\n                    normalized[0] = c2;\n                }\n\n                c0 = normalized[0];\n                c2 = normalized[2];\n\n                if (c0 != NONE && c0 != SwingConstants.NORTH_EAST)\n                    throw new IllegalArgumentException(\"Constraints not compatible: \" + // NOI18N\n                                                       toString(constraints));\n                if (c2 != NONE && c2 != SwingConstants.SOUTH_EAST)\n                    throw new IllegalArgumentException(\"Constraints not compatible: \" + // NOI18N\n                                                       toString(constraints));\n            }\n        }\n\n        return normalized;\n    }\n\n    private static String toString(Integer[] constraints) {\n        StringBuilder buffer = new StringBuilder();\n\n\n        for (int constraint : constraints)\n            buffer.append(buffer.length() == 0 ? constraintName(constraint) :\n                          \", \" + constraintName(constraint)); // NOI18N\n\n        if (buffer.length() == 0) buffer.append(\"[\"); // NOI18N\n        else buffer.insert(0, \"[\"); // NOI18N\n        buffer.append(\"]\"); // NOI18N\n\n        return buffer.toString();\n    }\n\n    private static String constraintName(int constraint) {\n        if (constraint == SwingConstants.NORTH) return \"NORTH\"; // NOI18N\n        if (constraint == SwingConstants.WEST) return \"WEST\"; // NOI18N\n        if (constraint == SwingConstants.SOUTH) return \"SOUTH\"; // NOI18N\n        if (constraint == SwingConstants.EAST) return \"EAST\"; // NOI18N\n        if (constraint == SwingConstants.NORTH_WEST) return \"NORTH_WEST\"; // NOI18N\n        if (constraint == SwingConstants.NORTH_EAST) return \"NORTH_EAST\"; // NOI18N\n        if (constraint == SwingConstants.SOUTH_WEST) return \"SOUTH_WEST\"; // NOI18N\n        if (constraint == SwingConstants.SOUTH_EAST) return \"SOUTH_EAST\"; // NOI18N\n        if (constraint == SwingConstants.CENTER) return \"CENTER\"; // NOI18N\n\n        return \"UNSUPPORTED_CONSTRAINT (value=\" + constraint + \")\"; // NOI18N\n    }\n\n\n    // --- Implicit implementation ---------------------------------------------\n\n    public Dimension maximumLayoutSize(Container target) {\n        return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);\n    }\n\n    public float getLayoutAlignmentX(Container target) {\n        return 0.5f;\n    }\n\n    public float getLayoutAlignmentY(Container target) {\n        return 0.5f;\n    }\n\n    public void invalidateLayout(Container target) {\n    }\n\n    public void addLayoutComponent(String name, Component comp) {\n        throw new UnsupportedOperationException(\"CrossBorderLayout.addLayoutComponent(String, Component) not supported, use CrossBorderLayout.addLayoutComponent(Component, Object)\"); // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/swing/LongRect.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.swing;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class LongRect {\n\n    public long x;\n    public long y;\n    public long width;\n    public long height;\n\n\n    public LongRect() {\n        this(0, 0, 0, 0);\n    }\n\n    public LongRect(LongRect longRect) {\n        this(longRect.x, longRect.y, longRect.width, longRect.height);\n    }\n\n    public LongRect(long x, long y, long width, long height) {\n        this.x = x;\n        this.y = y;\n        this.width = width;\n        this.height = height;\n    }\n\n\n    public String toString() {\n        return \"LongRect: [\" + x + \", \" + y + \", \" + width + \", \" + height + \"]\"; // NOI18N\n    }\n\n\n    // Sets lr to [0, 0, 0, 0]\n    public static void clear(LongRect lr) {\n        lr.x = 0;\n        lr.y = 0;\n        lr.width = 0;\n        lr.height = 0;\n    }\n\n    // Returns true if lr.x == 0 and lr.y == 0 and lr.width == 0 and lr.height == 0\n    public static boolean isClear(LongRect lr) {\n        if (lr.x != 0) return false;\n        if (lr.y != 0) return false;\n        if (lr.width != 0) return false;\n        if (lr.height != 0) return false;\n        return true;\n    }\n\n    // Returns true if lr.width <= 0 or lr.height <= 0\n    public static boolean isEmpty(LongRect lr) {\n        if (lr.width <= 0) return true;\n        if (lr.height <= 0) return true;\n        return false;\n    }\n\n    public static void set(LongRect lr1, LongRect lr2) {\n        set(lr1, lr2.x, lr2.y, lr2.width, lr2.height);\n    }\n\n    public static void set(LongRect lr, long x, long y, long width, long height) {\n        lr.x = x;\n        lr.y = y;\n        lr.width = width;\n        lr.height = height;\n    }\n\n    // Does nothing if isEmpty(lr2) == true,\n    // sets lr1 to be lr2 if isEmpty(lr1) == true,\n    // sets lr1 to be lr1 + lr2 otherwise\n    public static void add(LongRect lr1, LongRect lr2) {\n        if (isEmpty(lr2)) return;\n        if (isEmpty(lr1)) {\n            lr1.x = lr2.x;\n            lr1.y = lr2.y;\n            lr1.width = lr2.width;\n            lr1.height = lr2.height;\n        } else {\n            long xx = lr1.x;\n            long yy = lr1.y;\n            lr1.x = Math.min(lr1.x, lr2.x);\n            lr1.y = Math.min(lr1.y, lr2.y);\n            lr1.width = Math.max(xx + lr1.width, lr2.x + lr2.width) - lr1.x;\n            lr1.height = Math.max(yy + lr1.height, lr2.y + lr2.height) - lr1.y;\n        }\n    }\n    \n//    // If isEmpty(lr) == true sets the lr to [x, y, 1, 1],\n//    // otherwise extends the lr to contain [x, y] if necessary\n    public static void add(LongRect lr, long x, long y) {\n//        if (isEmpty(lr)) {\n//            lr.x = x;\n//            lr.y = y;\n//            lr.width = 1;\n//            lr.height = 1;\n//        } else {\n            long xx = lr.x;\n            long yy = lr.y;\n            lr.x = Math.min(lr.x, x);\n            lr.y = Math.min(lr.y, y);\n            lr.width = Math.max(xx + lr.width, x) - lr.x;\n            lr.height = Math.max(yy + lr.height, y) - lr.y;\n//        }\n    }\n    \n    // Returns true if lr1 fully contains lr2\n    public static boolean contains(LongRect lr1, LongRect lr2) {\n        if (isEmpty(lr1) || isEmpty(lr2)) return false;\n        if (lr1.x > lr2.x) return false;\n        if (lr1.y > lr2.y) return false;\n        if (lr1.x + lr1.width < lr2.x + lr2.width) return false;\n        if (lr1.y + lr1.height < lr2.y + lr2.height) return false;\n        return true;\n    }\n    \n    // Returns true if lr1 describes the same bounds as lr2\n    public static boolean equals(LongRect lr1, LongRect lr2) {\n        if (lr1.x != lr2.x) return false;\n        if (lr1.y != lr2.y) return false;\n        if (lr1.width != lr2.width) return false;\n        if (lr1.height != lr2.height) return false;\n        return true;\n    }\n    \n    // Returns true if at least one side of lr1 touches a side of lr2\n    // Requires that contains(lr2, lr1) == true\n    public static boolean touches(LongRect lr1, LongRect lr2) {\n        if (isEmpty(lr1) || isEmpty(lr2)) return false;\n        if (lr1.x == lr2.x) return true;\n        if (lr1.y == lr2.y) return true;\n        if (lr1.x + lr1.width == lr2.x + lr2.width) return true;\n        if (lr1.y + lr1.height == lr2.y + lr2.height) return true;\n        return false;\n    }\n    \n    public static void addBorder(LongRect lr, long border) {\n//        if (isEmpty(lr)) return;\n        lr.x -= border;\n        lr.y -= border;\n        lr.width += border * 2;\n        lr.height += border * 2;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/swing/RoundBorder.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.swing;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Insets;\nimport java.awt.RenderingHints;\nimport java.awt.Stroke;\nimport javax.swing.border.AbstractBorder;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class RoundBorder extends AbstractBorder {\n\n    private final Color lineColor;\n    private final Color fillColor;\n    private final Stroke borderStroke;\n\n    private final int arcRadius;\n    private final int borderExtent;\n\n    private final int borderStrokeWidth;\n    private final int halfBorderStrokeWidth;\n    private final int inset;\n\n    private final boolean forceSpeed;\n\n\n    public RoundBorder(float lineWidth, Color lineColor, Color fillColor,\n                       int arcRadius, int borderExtent) {\n        this.lineColor = Utils.checkedColor(lineColor);\n        this.fillColor = Utils.checkedColor(fillColor);\n        this.arcRadius = arcRadius;\n        this.borderExtent = borderExtent;\n\n        borderStroke = new BasicStroke(lineWidth);\n\n        borderStrokeWidth = (int)lineWidth;\n        halfBorderStrokeWidth = borderStrokeWidth / 2;\n        inset = borderStrokeWidth + borderExtent;\n\n        forceSpeed = Utils.forceSpeed();\n    }\n\n\n    public Insets getBorderInsets(Component c)       {\n        return new Insets(inset, inset, inset, inset);\n    }\n\n    public Insets getBorderInsets(Component c, Insets insets) {\n        insets.left = insets.top = insets.right = insets.bottom = inset;\n        return insets;\n    }\n\n\n    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {\n        Graphics2D g2 = (Graphics2D)g;\n\n        g2.setPaint(fillColor);\n        // NOTE: fillRoundRect seems to have poor performance on Linux\n//            g2.fillRoundRect(x + halfBorderStrokeWidth, y + halfBorderStrokeWidth,\n//                             width - borderStrokeWidth, height - borderStrokeWidth,\n//                             arcRadius * 2, arcRadius * 2);\n\n        int arcRadius2 = arcRadius * 2;\n        int arcRadius2p1 = arcRadius2 + 1;\n\n        g2.fillArc(x, y, arcRadius2, arcRadius2, 90, 90);\n        g2.fillArc(x + width - arcRadius2p1, y, arcRadius2, arcRadius2, 0, 90);\n        g2.fillArc(x, y + height - arcRadius2p1, arcRadius2, arcRadius2, 180, 90);\n        g2.fillArc(x + width - arcRadius2p1, y + height - arcRadius2p1, arcRadius2, arcRadius2, 270, 90);\n\n        g2.fillRect(x + arcRadius, y, width - arcRadius2p1, height);\n        g2.fillRect(x, y + arcRadius, arcRadius, height - arcRadius2p1);\n        g2.fillRect(x + width - arcRadius - 1, y + arcRadius, arcRadius, height - arcRadius2p1);\n\n        Object aa = null;\n        Object sc = null;\n        if (!forceSpeed) {\n            aa = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);\n            sc = g2.getRenderingHint(RenderingHints.KEY_STROKE_CONTROL);\n            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\n            g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);\n        }\n\n        g2.setStroke(borderStroke);\n        g2.setPaint(lineColor);\n        g2.drawRoundRect(x + halfBorderStrokeWidth, y + halfBorderStrokeWidth,\n                         width - borderStrokeWidth, height - borderStrokeWidth,\n                         arcRadius * 2, arcRadius * 2);\n\n        if (!forceSpeed) {\n            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aa);\n            g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, sc);\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/swing/Utils.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.swing;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Rectangle;\nimport java.awt.RenderingHints;\nimport java.awt.Stroke;\nimport java.lang.reflect.Method;\nimport javax.swing.UIManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class Utils {\n\n    private static boolean FORCE_SPEED = Boolean.getBoolean(\"graphs.forceSpeed\"); // NOI18N\n\n    private static boolean forceSpeed = FORCE_SPEED || !isLocalDisplay();\n//    private static boolean forceSpeed = true;\n\n\n    public static boolean forceSpeed() {\n        return forceSpeed;\n    }\n\n\n    public static Color checkedColor(Color color) {\n        if (color == null) return null;\n        if (!forceSpeed || color.getAlpha() == 255) return color;\n        return new Color(color.getRed(), color.getGreen(), color.getBlue());\n    }\n\n    public static RenderingHints checkedRenderingHints(RenderingHints rHints) {\n        if (!forceSpeed) return rHints;\n        RenderingHints hints = (RenderingHints)rHints.clone();\n        hints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);\n        hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);\n        hints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);\n        hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);\n        hints.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);\n        hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);\n        return hints;\n    }\n\n\n    /**\n     * Returns width of the Stroke. Note that this only works correctly for instances\n     * of BasicStroke, for other Strokes it always returns 1. Returns zero width\n     * for null Stroke.\n     *\n     * @param stroke Stroke\n     * @return width of Stroke for instances of BasicStroke, 1 for other Stroke, 0 for null Stroke\n     */\n    public static float getStrokeWidth(Stroke stroke) {\n        if (stroke == null) return 0f;\n        if (!(stroke instanceof BasicStroke)) return 1f;\n        return ((BasicStroke)stroke).getLineWidth();\n    }\n\n\n    public static Color getSystemSelection() {\n        Color sel = UIManager.getColor(\"List.selectionBackground\"); // NOI18N\n        if (sel == null) sel = UIManager.getColor(\"nimbusSelectionBackground\"); // NOI18N\n        if (sel == null) sel = new Color(0, 0, 200);\n        return sel;\n    }\n\n\n    private static boolean isLocalDisplay() {\n        try {\n            Class<?> x11Class = Class.forName(\"sun.swing.SwingUtilities2\"); // NOI18N\n            Method isDisplayLocalMethod = x11Class.getMethod(\"isLocalDisplay\"); // NOI18N\n            return (Boolean)isDisplayLocalMethod.invoke(null, (Object[])null);\n        } catch (Throwable t) {\n            return true;\n        }\n    }\n\n\n    // --- long <-> int conversions --------------------------------------------\n\n    public static final int VALUE_OUT_OF_RANGE_NEG = Integer.MIN_VALUE;\n    public static final int VALUE_OUT_OF_RANGE_POS = Integer.MAX_VALUE;\n\n\n    public static final int checkedInt(double value) {\n        if (value < Integer.MIN_VALUE) return VALUE_OUT_OF_RANGE_NEG;\n        if (value > Integer.MAX_VALUE) return VALUE_OUT_OF_RANGE_POS;\n        else return (int)value;\n    }\n\n    public static final Rectangle checkedRectangle(LongRect rect) {\n        // TODO: this is incorrect, width/height don't reflect x/y truncation!\n        return new Rectangle(checkedInt(rect.x),\n                            checkedInt(rect.y),\n                            checkedInt(rect.width),\n                            checkedInt(rect.height));\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/BytesXYItemMarksComputer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy;\n\nimport java.util.Iterator;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMark;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMarksComputer;\nimport org.graalvm.visualvm.lib.charts.axis.BytesAxisUtils;\nimport org.graalvm.visualvm.lib.charts.axis.BytesMark;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class BytesXYItemMarksComputer extends XYItemMarksComputer {\n\n    private double scale;\n    private long step;\n    private int radix;\n\n\n    public BytesXYItemMarksComputer(XYItem item,\n                                    XYItemPainter painter,\n                                    ChartContext context,\n                                    int orientation) {\n\n        super(item, painter, context, orientation);\n\n        scale = -1;\n        step = -1;\n        radix = -1;\n\n    }\n\n    protected boolean refreshConfiguration() {\n        double oldScale = scale;\n\n        if (context.getViewWidth() == 0) {\n            scale = -1;\n//        } else if (item.getValuesCount() == 0) {\n//            // Initial scale\n//            scale = -1;\n        } else {\n            scale = painter.getItemValueScale(item, context);\n        }\n\n        if (oldScale != scale) {\n            if (scale == -1) {\n                step = -1;\n                radix = -1;\n            } else {\n                long[] units = BytesAxisUtils.getBytesUnits(scale, getMinMarksDistance());\n                step = units[0];\n                radix = step == -1 ? -1 : (int)units[1];\n            }\n\n            oldScale = scale;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n\n    public Iterator<AxisMark> marksIterator(int start, int end) {\n            if (step == -1) return EMPTY_ITERATOR;\n\n            final long dataStart = ((long)painter.getItemValue(start, item,\n                                          context) / step) * step;\n            final long dataEnd = ((long)painter.getItemValue(end, item,\n                                          context) / step) * step;\n            final long iterCount = Math.abs(dataEnd - dataStart) / step + 2;\n            final long[] iterIndex = new long[] { 0 };\n\n\n            return new AxisMarksComputer.AbstractIterator() {\n\n                public boolean hasNext() {\n                    return iterIndex[0] < iterCount;\n                }\n\n                public AxisMark next() {\n                    long value = reverse ? dataStart - iterIndex[0] * step :\n                                           dataStart + iterIndex[0] * step;\n\n                    iterIndex[0]++;\n                    int position = Utils.checkedInt(Math.floor(\n                                         painter.getItemView(value, item, context)));\n                    return new BytesMark(value, position, radix);\n                }\n\n            };\n\n        }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/CompoundXYItemPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy;\n\nimport org.graalvm.visualvm.lib.charts.CompoundItemPainter;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class CompoundXYItemPainter extends CompoundItemPainter implements XYItemPainter {\n\n    public CompoundXYItemPainter(XYItemPainter painter1, XYItemPainter painter2) {\n        super(painter1, painter2);\n    }\n\n\n    public double getItemView(double dataY, XYItem item, ChartContext context) {\n        return getPainter1().getItemView(dataY, item, context);\n    }\n\n    public double getItemValue(double viewY, XYItem item, ChartContext context) {\n        return getPainter1().getItemValue(viewY, item, context);\n    }\n\n    public double getItemValueScale(XYItem item, ChartContext context) {\n        return getPainter1().getItemValueScale(item, context);\n    }\n\n\n    protected XYItemPainter getPainter1() {\n        return (XYItemPainter)super.getPainter1();\n    }\n\n    protected XYItemPainter getPainter2() {\n        return (XYItemPainter)super.getPainter2();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/DecimalXYItemMarksComputer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy;\n\nimport java.util.Iterator;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMark;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMarksComputer;\nimport org.graalvm.visualvm.lib.charts.axis.DecimalAxisUtils;\nimport org.graalvm.visualvm.lib.charts.axis.LongMark;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DecimalXYItemMarksComputer extends XYItemMarksComputer {\n\n    private double scale;\n    private long step;\n\n\n    public DecimalXYItemMarksComputer(XYItem item,\n                                      XYItemPainter painter,\n                                      ChartContext context,\n                                      int orientation) {\n\n        super(item, painter, context, orientation);\n\n        scale = -1;\n        step = -1;\n\n    }\n\n\n    protected boolean refreshConfiguration() {\n        double oldScale = scale;\n\n        if (context.getViewWidth() == 0) {\n            scale = -1;\n//        } else if (item.getValuesCount() == 0) {\n//            // Initial scale\n//            scale = -1;\n        } else {\n            scale = painter.getItemValueScale(item, context);\n        }\n\n        if (oldScale != scale) {\n\n            if (scale == -1) {\n                step = -1;\n            } else {\n                step = DecimalAxisUtils.getDecimalUnits(scale, getMinMarksDistance());\n            }\n\n            oldScale = scale;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n\n    public Iterator<AxisMark> marksIterator(int start, int end) {\n            if (step == -1) return EMPTY_ITERATOR;\n\n            final long dataStart = ((long)painter.getItemValue(start, item,\n                                          context) / step) * step;\n            final long dataEnd = ((long)painter.getItemValue(end, item,\n                                          context) / step) * step;\n            final long iterCount = Math.abs(dataEnd - dataStart) / step + 2;\n            final long[] iterIndex = new long[] { 0 };\n\n\n            return new AxisMarksComputer.AbstractIterator() {\n\n                public boolean hasNext() {\n                    return iterIndex[0] < iterCount;\n                }\n\n                public AxisMark next() {\n                    long value = reverse ? dataStart - iterIndex[0] * step :\n                                           dataStart + iterIndex[0] * step;\n\n                    iterIndex[0]++;\n                    int position = Utils.checkedInt(\n                                         painter.getItemView(value, item, context));\n                    return new LongMark(value, position);\n                }\n\n            };\n\n        }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/XYItem.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy;\n\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface XYItem extends ChartItem {\n\n    public long getXValue(int valueIndex);\n\n    public long getYValue(int valueIndex);\n\n    public int getValuesCount();\n\n\n    public LongRect getBounds();\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/XYItemChange.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy;\n\nimport org.graalvm.visualvm.lib.charts.ChartItemChange;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface XYItemChange extends ChartItemChange {\n\n    public XYItem getItem();\n\n    public int[] getValuesIndexes();\n\n    public LongRect getOldValuesBounds();\n\n    public LongRect getNewValuesBounds();\n\n    public LongRect getDirtyValuesBounds();\n\n\n    public static class Default extends ChartItemChange.Default implements XYItemChange {\n\n        private final int[] valuesIndexes;\n        private final LongRect oldBounds;\n        private final LongRect newBounds;\n        private final LongRect dirtyBounds;\n\n\n        public Default(XYItem item, int[] valuesIndexes, LongRect oldBounds,\n                       LongRect newBounds, LongRect dirtyBounds) {\n            super(item);\n            this.valuesIndexes = valuesIndexes;\n            this.oldBounds = oldBounds;\n            this.newBounds = newBounds;\n            this.dirtyBounds = dirtyBounds;\n        }\n\n\n        public XYItem getItem() { return (XYItem)super.getItem(); }\n\n        public int[] getValuesIndexes() { return valuesIndexes; }\n\n        public LongRect getOldValuesBounds() { return oldBounds; }\n\n        public LongRect getNewValuesBounds() { return newBounds; }\n\n        public LongRect getDirtyValuesBounds() { return dirtyBounds; }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/XYItemMarksComputer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy;\n\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMarksComputer;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class XYItemMarksComputer extends AxisMarksComputer.Abstract {\n\n    protected final XYItem item;\n    protected final XYItemPainter painter;\n\n\n    public XYItemMarksComputer(XYItem item,\n                               XYItemPainter painter,\n                               ChartContext context,\n                               int orientation) {\n\n        super(context, orientation);\n\n        this.item = item;\n        this.painter = painter;\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/XYItemPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy;\n\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ItemPainter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface XYItemPainter extends ItemPainter {\n\n    public static final int TYPE_ABSOLUTE = 0;\n    public static final int TYPE_RELATIVE = 1;\n\n\n    public double getItemView(double dataY, XYItem item, ChartContext context);\n\n    public double getItemValue(double viewY, XYItem item, ChartContext context);\n\n    public double getItemValueScale(XYItem item, ChartContext context);\n\n\n    public static abstract class Abstract implements XYItemPainter {\n\n        public double getItemView(double dataY, XYItem item, ChartContext context) {\n            return context.getViewY(dataY);\n        }\n\n        public double getItemValue(double viewY, XYItem item, ChartContext context) {\n            return context.getDataY(viewY);\n        }\n\n        public double getItemValueScale(XYItem item, ChartContext context) {\n            double scale = context.getViewHeight(1d);\n            if (scale <= 0) scale = -1;\n            return scale;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/XYItemSelection.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy;\n\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface XYItemSelection extends ItemSelection {\n\n    public int getValueIndex();\n\n    public XYItem getItem();\n\n\n    public static class Default extends ItemSelection.Default implements XYItemSelection {\n\n        private int valueIndex;\n\n\n        public Default(XYItem item, int valueIndex) {\n            this(item, valueIndex, DISTANCE_UNKNOWN);\n        }\n\n        public Default(XYItem item, int valueIndex, int distance) {\n            super(item, distance);\n            this.valueIndex = valueIndex;\n        }\n\n\n        public XYItem getItem() {\n            return (XYItem)super.getItem();\n        }\n\n        public int getValueIndex() {\n            return valueIndex;\n        }\n\n\n        public boolean equals(Object o) {\n            if (!super.equals(o)) return false;\n            if (!(o instanceof XYItemSelection)) return false;\n\n            XYItemSelection selection = (XYItemSelection)o;\n            return selection.getValueIndex() == valueIndex;\n        }\n\n        public int hashCode() {\n            return super.hashCode() + valueIndex;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/synchronous/SynchronousXYChart.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy.synchronous;\n\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.ChartComponent;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport java.awt.Rectangle;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class SynchronousXYChart extends ChartComponent {\n\n    private static final int[] VISIBLE_NONE = new int[] { -1, -1 };\n\n    private final Timeline timeline;\n\n    private int firstVisibleIndex[]; // first item visible, second item invisible\n    private int lastVisibleIndex[]; // first item visible, second item invisible\n    private Map<Rectangle, int[][]> indexesCache;\n\n    private boolean visibleIndexesDirty;\n    private boolean contentsWidthChanged;\n    private int oldBoundsWidth, newBoundsWidth;\n    private long oldOffsetX, newOffsetX;\n    private double oldScaleX, newScaleX;\n\n\n    // --- Constructors --------------------------------------------------------\n\n    private SynchronousXYChart() {\n        throw new UnsupportedOperationException(\n                \"new SynchronousXYChart() not supported\"); // NOI18N\n    }\n\n    public SynchronousXYChart(final SynchronousXYItemsModel itemsModel,\n                              final PaintersModel paintersModel) {\n        super();\n\n        timeline = itemsModel.getTimeline();\n\n        indexesCache = new HashMap<>();\n\n        firstVisibleIndex = VISIBLE_NONE;\n        lastVisibleIndex  = VISIBLE_NONE;\n        visibleIndexesDirty = true;\n\n        setItemsModel(itemsModel);\n        setPaintersModel(paintersModel);\n\n        addConfigurationListener(new VisibleBoundsListener());\n    }\n\n\n    // --- Protected implementation --------------------------------------------\n\n    protected Context createChartContext() {\n        return new Context(this);\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    // startIndex: first visible or invisible\n    private int[] findFirstVisibleL(int[] startIndex, int viewStart, int viewEnd) {\n        if (startIndex == VISIBLE_NONE) return VISIBLE_NONE;\n        \n        if (timeline.getTimestampsCount() == 0) return VISIBLE_NONE;\n        \n        int index = startIndex[0];\n        if (index == -1) index = startIndex[1];\n        \n        double dataStart = getDataX(viewStart);\n        \n        while (index > 0 && timeline.getTimestamp(index - 1) >= dataStart) index--;\n        \n        long timestamp = timeline.getTimestamp(index);\n        \n        if (timestamp > getDataX(viewEnd)) {\n            if (index == 0) {\n                return VISIBLE_NONE;\n            } else {\n                return new int[] { -1, index - 1 };\n            }\n        } else {\n            if (timestamp >= dataStart) {\n                return new int[] { index, -1 };\n            } else {\n                return new int[] { -1, index };\n            }\n        }\n    }\n\n    // startIndex: last visible or invisible\n    private int[] findLastVisibleL(int[] startIndex, int viewStart, int viewEnd) {\n        if (startIndex == VISIBLE_NONE) return VISIBLE_NONE;\n        \n        if (timeline.getTimestampsCount() == 0) return VISIBLE_NONE;\n\n        int index = startIndex[0];\n        if (index == -1) index = startIndex[1];\n        \n        double dataEnd = getDataX(viewEnd);\n        \n        while (index > 0 && timeline.getTimestamp(index - 1) > dataEnd) index--;\n        \n        long timestamp = timeline.getTimestamp(index);\n        \n        if (timestamp > dataEnd) {\n            if (index == 0 || timeline.getTimestamp(index - 1) < getDataX(viewStart)) {\n                return new int[] { -1, index };\n            } else {\n                return new int[] { index - 1, -1 };\n            }\n        } else {\n            if (timestamp >= getDataX(viewStart)) {\n                return new int[] { index, -1 };\n            } else {\n                return VISIBLE_NONE;\n            }\n        }\n    }\n\n    // startIndex: first visible or invisible\n    private int[] findFirstVisibleR(int[] startIndex, int viewStart, int viewEnd) {\n        if (startIndex == VISIBLE_NONE) return VISIBLE_NONE;\n        \n        int timestampsCount = timeline.getTimestampsCount();\n        if (timestampsCount == 0) return VISIBLE_NONE;\n        \n        int index = startIndex[0];\n        if (index == -1) index = startIndex[1];\n        \n        double dataStart = getDataX(viewStart);\n        \n        while (index < timestampsCount - 1 && timeline.getTimestamp(index + 1) < dataStart) index++;\n        long timestamp = timeline.getTimestamp(index);\n        \n        if (timestamp >= dataStart) {\n            if (timestamp > getDataX(viewEnd)) {\n                return VISIBLE_NONE;\n            } else {\n                return new int[] { index, -1 };\n            }\n        } else {\n            if (index == timestampsCount - 1 || timeline.getTimestamp(index + 1) > getDataX(viewEnd)) {\n                return new int[] { -1, index };\n            } else {\n                return new int[] { index + 1, -1 };\n            }\n        }\n    }\n\n    // startIndex: last visible or invisible\n    private int[] findLastVisibleR(int[] startIndex, int viewStart, int viewEnd) {\n        if (startIndex == VISIBLE_NONE) return VISIBLE_NONE;\n        \n        int timestampsCount = timeline.getTimestampsCount();\n        if (timestampsCount == 0) return VISIBLE_NONE;\n        \n        int index = startIndex[0];\n        if (index == -1) index = startIndex[1];\n        \n        double dataEnd = getDataX(viewEnd);\n        \n        while (index < timestampsCount - 1 && timeline.getTimestamp(index + 1) <= dataEnd) index++;\n        \n        long timestamp = timeline.getTimestamp(index);\n        \n        if (timestamp < getDataX(viewStart)) {\n            if (index == timestampsCount - 1) {\n                return VISIBLE_NONE;\n            } else {\n                return new int[] { -1, index + 1 };\n            }\n        } else {\n            if (timestamp > dataEnd) {\n                return new int[] { -1, index };\n            } else {\n                return new int[] { index, -1 };\n            }\n        }\n    }\n\n    // Use in case of absolute panic, will always work\n    // Note: doesn't clear cache, indexesCache.clear() must be invoked explicitly\n    private void recomputeVisibleBounds() {\n        int timestampsCount = timeline.getTimestampsCount();\n        if (timestampsCount == 0) {\n            firstVisibleIndex = VISIBLE_NONE;\n            lastVisibleIndex  = VISIBLE_NONE;\n        } else {\n            firstVisibleIndex = new int[] { 0, -1 };\n            lastVisibleIndex  = new int[] { timestampsCount - 1, -1 };\n            if (!fitsWidth()) {\n                firstVisibleIndex = findFirstVisibleR(firstVisibleIndex, 0, getWidth());\n                lastVisibleIndex  = findLastVisibleL(lastVisibleIndex, 0, getWidth());\n            }\n        }\n    }\n\n    protected void reshaped(Rectangle oldBounds, Rectangle newBounds) {\n        if (!fitsWidth() && oldBounds.width != newBounds.width) {\n            visibleIndexesDirty = true;\n            oldBoundsWidth = oldBounds.width;\n            newBoundsWidth = newBounds.width;\n        }\n\n        super.reshaped(oldBounds, newBounds);\n    }\n\n\n    private void updateVisibleIndexes() {\n        if (!visibleIndexesDirty) return;\n\n        indexesCache.clear();\n\n        if (fitsWidth()) {\n            recomputeVisibleBounds();\n        } else if (contentsWidthChanged) {\n            recomputeVisibleBounds();\n        } else if (firstVisibleIndex == VISIBLE_NONE) {\n            recomputeVisibleBounds();\n        } else if (oldBoundsWidth != newBoundsWidth) {\n            if (oldBoundsWidth < newBoundsWidth) {\n                firstVisibleIndex = findFirstVisibleL(firstVisibleIndex, 0, getWidth());\n                if (currentlyFollowingDataWidth()) {\n                    lastVisibleIndex[0] = timeline.getTimestampsCount() - 1;\n                    lastVisibleIndex[1] = -1;\n                } else {\n                    lastVisibleIndex = findLastVisibleR(lastVisibleIndex, 0, getWidth());\n                }\n            } else {\n                firstVisibleIndex = findFirstVisibleR(firstVisibleIndex, 0, getWidth());\n                if (currentlyFollowingDataWidth()) {\n                    lastVisibleIndex[0] = timeline.getTimestampsCount() - 1;\n                    lastVisibleIndex[1] = -1;\n                } else {\n                    lastVisibleIndex = findLastVisibleL(lastVisibleIndex, 0, getWidth());\n                }\n            }\n        } else if (oldScaleX != newScaleX) {\n            if (oldScaleX < newScaleX) {\n                int[] firstVisibleI = findFirstVisibleR(firstVisibleIndex, 0, getWidth());\n                if (firstVisibleI == VISIBLE_NONE) firstVisibleI = findFirstVisibleL(firstVisibleIndex, 0, getWidth());\n                firstVisibleIndex = firstVisibleI;\n                int[] lastVisibleI = findLastVisibleL(lastVisibleIndex, 0, getWidth());\n                if (lastVisibleI == VISIBLE_NONE) lastVisibleI = findLastVisibleR(lastVisibleIndex, 0, getWidth());\n                lastVisibleIndex = lastVisibleI;\n            } else {\n                firstVisibleIndex = findFirstVisibleL(firstVisibleIndex, 0, getWidth());\n                lastVisibleIndex = findLastVisibleR(lastVisibleIndex, 0, getWidth());\n            }\n        } else if (oldOffsetX != newOffsetX) {\n            if (newOffsetX > oldOffsetX) {\n                firstVisibleIndex = findFirstVisibleR(firstVisibleIndex, 0, getWidth());\n                lastVisibleIndex = findLastVisibleR(lastVisibleIndex, 0, getWidth());\n            } else {\n                firstVisibleIndex = findFirstVisibleL(firstVisibleIndex, 0, getWidth());\n                lastVisibleIndex = findLastVisibleL(lastVisibleIndex, 0, getWidth());\n            }\n        }\n\n        // clear dirty flags\n        contentsWidthChanged = false;\n        oldBoundsWidth = newBoundsWidth;\n        oldScaleX = newScaleX;\n        oldOffsetX = newOffsetX;\n        visibleIndexesDirty = false;\n    }\n    \n    private int[][] getVisibleBounds(Rectangle viewRect) {\n        updateVisibleIndexes();\n        \n        if (fitsWidth() || viewRect.x == 0 && viewRect.width == getWidth())\n            return new int[][] { firstVisibleIndex, lastVisibleIndex };\n\n        Rectangle rect = new Rectangle(viewRect.x, 0, viewRect.width, 0);\n        int[][] bounds = indexesCache.get(rect);\n\n        if (bounds == null) {\n            int firstI = firstVisibleIndex[0];\n            if (firstI == -1) firstI = firstVisibleIndex[1];\n            int[] firstIndex = firstI == -1 ? VISIBLE_NONE : getDataX(viewRect.x) > timeline.getTimestamp(firstI) ?\n                    findFirstVisibleR(firstVisibleIndex, viewRect.x, viewRect.x + viewRect.width) :\n                    findFirstVisibleL(firstVisibleIndex, viewRect.x, viewRect.x + viewRect.width);\n\n            int lastI = lastVisibleIndex[0];\n            if (lastI == -1) lastI = lastVisibleIndex[1];\n            int[] lastIndex = lastI == -1 ? VISIBLE_NONE : getDataX(viewRect.x + viewRect.width) < timeline.getTimestamp(lastI) ?\n                    findLastVisibleL(lastVisibleIndex, viewRect.x, viewRect.x + viewRect.width) :\n                    findLastVisibleR(lastVisibleIndex, viewRect.x, viewRect.x + viewRect.width);\n            \n            bounds = new int[][] { firstIndex, lastIndex };\n            \n            indexesCache.put(rect, bounds);\n        }\n\n        return bounds;\n    }\n\n\n    public int getNearestTimestampIndex(int x, int y) {\n        int timestampsCount = timeline.getTimestampsCount();\n\n        if (timestampsCount == 0) return -1;\n        if (timestampsCount == 1) return 0;\n\n        long dataX = (long)getDataX(x);\n\n        if (firstVisibleIndex == VISIBLE_NONE) return -1;\n        int nearestIndex = firstVisibleIndex[0];\n        if (nearestIndex == -1) nearestIndex = firstVisibleIndex[1];\n        \n        long itemDataX = timeline.getTimestamp(nearestIndex);\n        long nearestDistance = Math.abs(dataX - itemDataX);\n\n        int lastIndex = lastVisibleIndex[0];\n        if (lastIndex == -1) lastIndex = lastVisibleIndex[1];\n        else if (currentlyFollowingDataWidth()) lastIndex = timestampsCount - 1;\n        while(nearestIndex + 1 <= lastIndex) {\n            itemDataX = timeline.getTimestamp(nearestIndex + 1);\n            long distance = Math.abs(dataX - itemDataX);\n\n            if (distance >= nearestDistance) break;\n\n            nearestIndex++;\n            nearestDistance = distance;\n        }\n\n        return nearestIndex;\n    }\n\n\n    // --- ChartConfigurationListener implementation ---------------------------\n\n    private class VisibleBoundsListener extends ChartConfigurationListener.Adapter {\n        public void offsetChanged(long oldOffsetX, long oldOffsetY,\n                                  long newOffsetX, long newOffsetY) {\n            if (!fitsWidth() && oldOffsetX != newOffsetX) {\n                visibleIndexesDirty = true;\n                SynchronousXYChart.this.oldOffsetX = oldOffsetX;\n                SynchronousXYChart.this.newOffsetX = newOffsetX;\n            }\n        }\n\n        public void dataBoundsChanged(long dataOffsetX, long dataOffsetY,\n                                      long dataWidth, long dataHeight,\n                                      long oldDataOffsetX, long oldDataOffsetY,\n                                      long oldDataWidth, long oldDataHeight) {\n\n            if (getContentsWidth() <= getWidth()) {\n                visibleIndexesDirty = true;\n                contentsWidthChanged = true;\n            }\n        }\n\n        public void scaleChanged(double oldScaleX, double oldScaleY,\n                                 double newScaleX, double newScaleY) {\n\n            visibleIndexesDirty = true;\n            if (!fitsWidth() && oldScaleX != newScaleX) {\n                SynchronousXYChart.this.oldScaleX = oldScaleX;\n                SynchronousXYChart.this.newScaleX = newScaleX;\n            }\n        }\n    }\n\n\n    // --- ChartContext implementation -----------------------------------------\n\n    protected static class Context extends ChartComponent.Context\n                                   implements SynchronousXYChartContext {\n\n        protected Context(SynchronousXYChart chart) {\n            super(chart);\n        }\n\n        protected SynchronousXYChart getChartComponent() {\n            return (SynchronousXYChart)super.getChartComponent();\n        }\n\n\n        public int[][] getVisibleBounds(Rectangle viewRect) {\n            return getChartComponent().getVisibleBounds(viewRect);\n        }\n\n        public int getNearestTimestampIndex(int x, int y) {\n            return getChartComponent().getNearestTimestampIndex(x, y);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/synchronous/SynchronousXYChartContext.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy.synchronous;\n\n\nimport java.awt.Rectangle;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface SynchronousXYChartContext extends ChartContext {\n\n    public int[][] getVisibleBounds(Rectangle viewRect);\n\n    public int getNearestTimestampIndex(int x, int y);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/synchronous/SynchronousXYItem.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy.synchronous;\n\nimport org.graalvm.visualvm.lib.charts.ChartItemListener;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemChange;\nimport org.graalvm.visualvm.lib.charts.Timeline;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class SynchronousXYItem implements XYItem {\n\n    private final String name;\n\n    private Timeline timeline;\n\n    private int lastIndex;\n\n    private final LongRect bounds;\n    private long initialMinY;\n    private long initialMaxY;\n\n    private LongRect initialBounds;\n\n    private long minY;\n    private long maxY;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    public SynchronousXYItem(String name) {\n        this(name, Long.MAX_VALUE);\n    }\n\n    public SynchronousXYItem(String name, long initialMinY) {\n        this(name, initialMinY, Long.MIN_VALUE);\n    }\n\n    public SynchronousXYItem(String name, long initialMinY, long initialMaxY) {\n        this.name = name;\n        this.initialMinY = initialMinY;\n        this.initialMaxY = initialMaxY;\n        minY = Long.MAX_VALUE;\n        maxY = Long.MIN_VALUE;\n        bounds = new LongRect();\n        initialBounds = new LongRect();\n        lastIndex = -1;\n    }\n\n\n    // --- Item telemetry ------------------------------------------------------\n\n    public String getName() { return name; }\n\n    public void setInitialBounds(LongRect initialBounds) { this.initialBounds = initialBounds; }\n\n    public LongRect getInitialBounds() { return initialBounds; }\n\n    public XYItemChange valuesChanged() {\n\n        int index = timeline.getTimestampsCount() - 1;\n        XYItemChange change = null;\n\n        if (lastIndex == index) { // No change\n\n            LongRect b = new LongRect(bounds);\n            change = new XYItemChange.Default(this, new int[] { -1 }, b, b, b);\n\n        } else if (index > -1) { // New item(s)\n\n            // Save oldBounds, setup dirtyBounds\n            LongRect oldBounds = new LongRect(bounds);\n            LongRect dirtyBounds = new LongRect();\n\n            boolean initBounds = lastIndex == -1;\n            int dirtyIndex = lastIndex == -1 ? 0 : lastIndex;\n\n            // Process other values\n            for (int i = dirtyIndex; i <= index; i++) {\n\n                long timestamp = timeline.getTimestamp(i);\n                long value = getYValue(i);\n\n                // Update item minY/maxY\n                minY = Math.min(value, minY);\n                maxY = Math.max(value, maxY);\n\n                // Process item bounds\n                if (initBounds) {\n                    // Initialize item bounds\n                    bounds.x = timestamp;\n                    bounds.y = Math.min(value, initialMinY);\n                    bounds.width = 0;\n                    bounds.height = Math.max(value, initialMaxY) - bounds.y;\n                    initBounds = false;\n                } else {\n                    // Update item bounds\n                    LongRect.add(bounds, timestamp, value);\n                }\n\n                // Process dirty bounds\n                if (i == dirtyIndex) {\n                    // Setup dirty bounds\n                    dirtyBounds.x = timestamp;\n                    dirtyBounds.y = value;\n                    dirtyBounds.width = timeline.getTimestamp(index) - dirtyBounds.x;\n                } else {\n                    // Update dirty y/height\n                    long dirtyY = dirtyBounds.y;\n                    dirtyBounds.y = Math.min(dirtyY, value);\n                    dirtyBounds.height = Math.max(dirtyY, value) - dirtyBounds.y;\n                }\n\n            }\n\n            // Return ItemChange\n            int indexesCount = index - lastIndex;\n            int[] indexes = new int[indexesCount];\n            for (int i = 0; i < indexesCount; i++) indexes[i] = lastIndex + 1 + i;\n            change = new XYItemChange.Default(this, indexes, oldBounds,\n                                              new LongRect(bounds), dirtyBounds);\n\n        } else { // Reset\n\n            minY = Long.MAX_VALUE;\n            maxY = Long.MIN_VALUE;\n\n            // Save oldBounds\n            LongRect oldBounds = new LongRect(bounds);\n            LongRect.set(bounds, 0, 0, 0, 0);\n\n            // Return ItemChange\n            change = new XYItemChange.Default(this, new int[] { -1 }, oldBounds,\n                                            new LongRect(bounds), oldBounds);\n\n        }\n        \n        lastIndex = index;\n        return change;\n        \n    }\n\n    public int getValuesCount() { return timeline.getTimestampsCount(); }\n\n    public long getXValue(int index) { return timeline.getTimestamp(index); }\n\n    public abstract long getYValue(int index);\n\n    public long getMinYValue() { return minY; }\n\n    public long getMaxYValue() { return maxY; }\n    \n    public LongRect getBounds() {\n        if (getValuesCount() == 0) return initialBounds;\n        else return bounds;\n    }\n\n\n    // --- ChartItem implementation (ChartItemListener not supported) ----------\n\n    public void addItemListener(ChartItemListener listener) {}\n\n    public void removeItemListener(ChartItemListener listener) {}\n\n\n    // --- Internal interface --------------------------------------------------\n\n    void setTimeline(Timeline timeline) { this.timeline = timeline; }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/synchronous/SynchronousXYItemMarker.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy.synchronous;\n\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartItemChange;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemChange;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.util.List;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class SynchronousXYItemMarker extends XYItemPainter.Abstract {\n\n    protected final int markRadius;\n    protected final int line1Width;\n    protected final Color line1Color;\n    protected final int line2Width;\n    protected final Color line2Color;\n    protected final Color fillColor;\n\n    protected final Stroke line1Stroke;\n    protected final Stroke line2Stroke;\n\n    protected final int decorationRadius;\n\n    protected final int type;\n    protected final int maxValueOffset;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    public static SynchronousXYItemMarker absolutePainter(int markRadius,\n                                                       float line1Width,\n                                                       Color line1Color,\n                                                       float line2Width,\n                                                       Color line2Color,\n                                                       Color fillColor) {\n\n        return new SynchronousXYItemMarker(markRadius, line1Width, line1Color,\n                                        line2Width, line2Color, fillColor,\n                                        TYPE_ABSOLUTE, 0);\n    }\n\n    public static SynchronousXYItemMarker relativePainter(int markRadius,\n                                                       float line1Width,\n                                                       Color line1Color,\n                                                       float line2Width,\n                                                       Color line2Color,\n                                                       Color fillColor,\n                                                       int maxOffset) {\n\n        return new SynchronousXYItemMarker(markRadius, line1Width, line1Color,\n                                        line2Width, line2Color, fillColor,\n                                        TYPE_RELATIVE, maxOffset);\n    }\n\n\n    public SynchronousXYItemMarker(int markRadius, float line1Width, Color line1Color,\n                                 float line2Width, Color line2Color, Color fillColor,\n                                 int type, int maxValueOffset) {\n\n        if (line1Color == null && line2Color == null && fillColor == null)\n            throw new IllegalArgumentException(\"No parameters defined\"); // NOI18N\n\n        this.markRadius = markRadius;\n        this.line1Width = (int)Math.ceil(line1Width);\n        this.line1Color = Utils.checkedColor(line1Color);\n        this.line2Width = (int)Math.ceil(line2Width);\n        this.line2Color = Utils.checkedColor(line2Color);\n        this.fillColor = Utils.checkedColor(fillColor);\n\n        this.line1Stroke = line1Color == null ? null :\n                           new BasicStroke(line1Width, BasicStroke.CAP_ROUND,\n                                           BasicStroke.JOIN_ROUND);\n        this.line2Stroke = line2Color == null ? null :\n                           new BasicStroke(line2Width, BasicStroke.CAP_ROUND,\n                                         BasicStroke.JOIN_ROUND);\n\n\n        decorationRadius = markRadius + this.line1Width + this.line2Width;\n\n        this.type = type;\n        this.maxValueOffset = maxValueOffset;\n    }\n\n\n    // --- ItemPainter implementation ------------------------------------------\n    \n    public LongRect getItemBounds(ChartItem item) {\n//        if (!(item instanceof ProfilerXYItem))\n//            throw new UnsupportedOperationException(\"Unsupported item: \" + item); // NOI18N\n\n        SynchronousXYItem xyItem = (SynchronousXYItem)item;\n        if (type == TYPE_ABSOLUTE) {\n            return xyItem.getBounds();\n        } else {\n            LongRect itemBounds1 = new LongRect(xyItem.getBounds());\n            itemBounds1.y = 0;\n            itemBounds1.height = 0;\n            return itemBounds1;\n        }\n    }\n\n    public LongRect getItemBounds(ChartItem item, ChartContext context) {\n//        if (!(item instanceof ProfilerXYItem))\n//            throw new UnsupportedOperationException(\"Unsupported item: \" + item); // NOI18N\n\n        SynchronousXYItem xyItem = (SynchronousXYItem)item;\n        return getViewBounds(xyItem, null, context);\n    }\n\n\n    public boolean isBoundsChange(ChartItemChange itemChange) {\n//        if (!(itemChange instanceof XYItemChange))\n//            throw new UnsupportedOperationException(\"Unsupported itemChange: \" + itemChange);\n\n        // Items can only be added => always bounds change\n        XYItemChange change = (XYItemChange)itemChange;\n        return !LongRect.equals(change.getOldValuesBounds(),\n                                change.getNewValuesBounds());\n    }\n\n    public boolean isAppearanceChange(ChartItemChange itemChange) {\n//        if (!(itemChange instanceof XYItemChange))\n//            throw new UnsupportedOperationException(\"Unsupported itemChange: \" + itemChange);\n        \n        // Items can only be added => always appearance change\n        XYItemChange change = (XYItemChange)itemChange;\n        LongRect dirtyBounds = change.getDirtyValuesBounds();\n        return dirtyBounds.width != 0 || dirtyBounds.height != 0;\n    }\n\n    public LongRect getDirtyBounds(ChartItemChange itemChange, ChartContext context) {\n//        if (!(itemChange instanceof XYItemChange))\n//            throw new UnsupportedOperationException(\"Unsupported itemChange: \" + itemChange);\n        \n        // Items can only be added => always dirty bounds for last value\n        XYItemChange change = (XYItemChange)itemChange;\n        return getViewBounds(change.getItem(), change.getValuesIndexes(), context);\n    }\n\n\n    public boolean supportsHovering(ChartItem item) {\n        return true;\n    }\n\n    public boolean supportsSelecting(ChartItem item) {\n        return true;\n    }\n\n    public LongRect getSelectionBounds(ItemSelection selection, ChartContext context) {\n//        if (!(selection instanceof XYItemSelection))\n//            throw new UnsupportedOperationException(\"Unsupported selection: \" + selection); // NOI18N\n\n        XYItemSelection sel = (XYItemSelection)selection;\n        XYItem item  = sel.getItem();\n        int selectedValueIndex = sel.getValueIndex();\n\n        if (selectedValueIndex == -1 ||\n            selectedValueIndex >= item.getValuesCount())\n            // This happens on reset - bounds of the selection are unknown, let's clear whole area\n            return new LongRect(0, 0, context.getViewportWidth(),\n                                context.getViewportHeight());\n        else\n            return getViewBounds(item, new int[] { sel.getValueIndex() }, context);\n    }\n\n    public XYItemSelection getClosestSelection(ChartItem item, int viewX,\n                                               int viewY, ChartContext context) {\n//        if (!(item instanceof ProfilerXYItem))\n//            throw new UnsupportedOperationException(\"Unsupported item: \" + item); // NOI18N\n//        if (!(context instanceof ProfilerXYChartComponent.Context))\n//            throw new UnsupportedOperationException(\"Unsupported context: \" + context);\n\n        SynchronousXYChartContext contx = (SynchronousXYChartContext)context;\n\n        int nearestTimestampIndex = contx.getNearestTimestampIndex(viewX, viewY);\n        if (nearestTimestampIndex == -1) return null; // item not visible\n\n        SynchronousXYItem xyItem = (SynchronousXYItem)item;\n        return new XYItemSelection.Default(xyItem, nearestTimestampIndex);\n    }\n\n    public void paintItem(ChartItem item, List<ItemSelection> highlighted,\n                          List<ItemSelection> selected, Graphics2D g,\n                          Rectangle dirtyArea, ChartContext context) {\n//        if (!(item instanceof ProfilerXYItem))\n//            throw new UnsupportedOperationException(\"Unsupported item: \" + item); // NOI18N\n//        if (!(context instanceof ProfilerXYChartComponent.Context))\n//            throw new UnsupportedOperationException(\"Unsupported context: \" + context);\n        \n        paint((SynchronousXYItem)item, highlighted, selected, g, dirtyArea,\n              (SynchronousXYChartContext)context);\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private LongRect getViewBoundsRelative(LongRect dataBounds, XYItem item,\n                                           ChartContext context) {\n        LongRect itemBounds = item.getBounds();\n\n        double itemValueFactor = getItemValueFactor(context, maxValueOffset,\n                                                    itemBounds.height);\n\n        // TODO: fix the math!!!\n        double value1 = context.getDataOffsetY() + itemValueFactor *\n                      (double)(dataBounds.y - itemBounds.y);\n        double value2 = context.getDataOffsetY() + itemValueFactor *\n                      (double)(dataBounds.y + dataBounds.height - itemBounds.y);\n\n        long viewX = (long)Math.ceil(context.getViewX(dataBounds.x));\n        long viewWidth = (long)Math.ceil(context.getViewWidth(dataBounds.width));\n        if (context.isRightBased()) viewX -= viewWidth;\n\n        long viewY1 = (long)Math.ceil(context.getViewY(value1));\n        long viewY2 = (long)Math.ceil(context.getViewY(value2));\n        long viewHeight = context.isBottomBased() ? viewY1 - viewY2 :\n                                                    viewY2 - viewY1;\n        if (!context.isBottomBased()) viewY2 -= viewHeight;\n\n        LongRect viewBounds =  new LongRect(viewX, viewY2, viewWidth, viewHeight);\n        LongRect.addBorder(viewBounds, decorationRadius);\n\n        return viewBounds;\n    }\n\n    private LongRect getViewBounds(XYItem item, int[] valuesIndexes, ChartContext context) {\n        \n        LongRect dataBounds = new LongRect();\n\n        if (valuesIndexes == null) {\n            LongRect.set(dataBounds, item.getBounds());\n        } else {\n            boolean firstPoint = true;\n            for (int valueIndex : valuesIndexes) {\n                if (valueIndex == -1) continue;\n                long xValue = item.getXValue(valueIndex);\n                long yValue = item.getYValue(valueIndex);\n                if (firstPoint) {\n                    LongRect.set(dataBounds, xValue, yValue, 0, 0);\n                    firstPoint = false;\n                } else {\n                    LongRect.add(dataBounds, xValue, yValue);\n                }\n            }\n        }\n\n//        if (type == TYPE_RELATIVE)\n//            LongRect.set(dataBounds, getRelativeDataBounds(dataBounds, item,\n//                                                           context, maxOffset));\n\n        if (type == TYPE_RELATIVE) {\n\n            return getViewBoundsRelative(dataBounds, item, context);\n\n        } else {\n\n            LongRect viewBounds = context.getViewRect(dataBounds);\n            LongRect.addBorder(viewBounds, decorationRadius);\n            return viewBounds;\n\n        }\n    }\n\n    \n    private void paint(SynchronousXYItem item, List<ItemSelection> highlighted,\n                       List<ItemSelection> selected, Graphics2D g,\n                       Rectangle dirtyArea, SynchronousXYChartContext context) {\n\n        if (highlighted.isEmpty()) return;\n        if (item.getValuesCount() < 1) return;\n        if (context.getViewWidth() == 0 || context.getViewHeight() == 0) return;\n\n        double itemValueFactor = type == TYPE_RELATIVE ?\n                                         getItemValueFactor(context, maxValueOffset,\n                                         item.getBounds().height) : 0;\n\n        for (ItemSelection selection : highlighted) {\n\n            XYItemSelection sel = (XYItemSelection)selection;\n            int valueIndex = sel.getValueIndex();\n            if (valueIndex == -1) continue;\n\n            int itemX = Utils.checkedInt(context.getViewX(\n                                                 item.getXValue(valueIndex)));\n            int itemY = Utils.checkedInt(getYValue(item, valueIndex,\n                                                 type, context, itemValueFactor));\n\n            if (fillColor != null) {\n                g.setPaint(fillColor);\n                g.fillOval(itemX - markRadius, itemY - markRadius,\n                           markRadius * 2, markRadius * 2);\n            }\n\n            if (line2Color != null) {\n                g.setPaint(line2Color);\n                g.setStroke(line2Stroke);\n                g.drawOval(itemX - markRadius, itemY - markRadius,\n                           markRadius * 2, markRadius * 2);\n            }\n\n            if (line1Color != null) {\n                int radius = markRadius + line2Width / 2;\n                g.setPaint(line1Color);\n                g.setStroke(line1Stroke);\n                g.drawOval(itemX - radius, itemY - radius,\n                           radius * 2, radius * 2);\n            }\n\n        }\n\n//        System.err.println(\">>> paintItem, dirtyArea: \" + dirtyArea);\n        \n    }\n\n    private static double getYValue(XYItem item, int valueIndex,\n                                  int type, ChartContext context, double itemValueFactor) {\n        if (type == TYPE_ABSOLUTE) {\n            return context.getViewY(item.getYValue(valueIndex));\n        } else {\n            return context.getViewY(context.getDataOffsetY() + (itemValueFactor *\n                        (item.getYValue(valueIndex) - item.getBounds().y)));\n        }\n    }\n\n    private static double getItemValueFactor(ChartContext context,\n                                             double maxValueOffset,\n                                             double itemHeight) {\n        return ((double)context.getDataHeight() -\n               context.getDataHeight(maxValueOffset)) / itemHeight;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/synchronous/SynchronousXYItemPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy.synchronous;\n\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartItemChange;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemChange;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemPainter;\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Polygon;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class SynchronousXYItemPainter extends XYItemPainter.Abstract {\n\n    protected final int lineWidth;\n    protected final Color lineColor;\n    protected final Color fillColor;\n\n    protected final Stroke lineStroke;\n\n    protected final int type;\n    protected final int maxValueOffset;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    public static SynchronousXYItemPainter absolutePainter(float lineWidth,\n                                                       Color lineColor,\n                                                       Color fillColor) {\n\n        return new SynchronousXYItemPainter(lineWidth, lineColor, fillColor,\n                                         TYPE_ABSOLUTE, 0);\n    }\n\n    public static SynchronousXYItemPainter relativePainter(float lineWidth,\n                                                       Color lineColor,\n                                                       Color fillColor,\n                                                       int maxOffset) {\n\n        return new SynchronousXYItemPainter(lineWidth, lineColor, fillColor,\n                                         TYPE_RELATIVE, maxOffset);\n    }\n\n\n    public SynchronousXYItemPainter(float lineWidth, Color lineColor, Color fillColor,\n                          int type, int maxValueOffset) {\n\n        if (lineColor == null && fillColor == null)\n            throw new IllegalArgumentException(\"No parameters defined\"); // NOI18N\n\n        this.lineWidth = (int)Math.ceil(lineWidth);\n        this.lineColor = Utils.checkedColor(lineColor);\n        this.fillColor = Utils.checkedColor(fillColor);\n\n        this.lineStroke = new BasicStroke(lineWidth, BasicStroke.CAP_ROUND,\n                                          BasicStroke.JOIN_ROUND);\n\n        this.type = type;\n        this.maxValueOffset = maxValueOffset;\n    }\n\n\n    // --- ItemPainter implementation ------------------------------------------\n    \n    public LongRect getItemBounds(ChartItem item) {\n//        if (!(item instanceof XYItem))\n//            throw new UnsupportedOperationException(\"Unsupported item: \" + item); // NOI18N\n\n        XYItem xyItem = (XYItem)item;\n        if (type == TYPE_ABSOLUTE) {\n            return getDataBounds(xyItem.getBounds());\n        } else {\n            LongRect itemBounds1 = new LongRect(xyItem.getBounds());\n            itemBounds1.y = 0;\n            itemBounds1.height = 0;\n            return itemBounds1;\n        }\n    }\n\n    public LongRect getItemBounds(ChartItem item, ChartContext context) {\n//        if (!(item instanceof XYItem))\n//            throw new UnsupportedOperationException(\"Unsupported item: \" + item); // NOI18N\n\n        XYItem xyItem = (XYItem)item;\n        if (type == TYPE_ABSOLUTE) {\n            return getViewBounds(xyItem.getBounds(), context);\n        } else {\n            return getViewBoundsRelative(xyItem.getBounds(), xyItem, context);\n        }\n    }\n\n\n    public boolean isBoundsChange(ChartItemChange itemChange) {\n//        if (!(itemChange instanceof XYItemChange))\n//            throw new UnsupportedOperationException(\"Unsupported itemChange: \" + itemChange);\n\n        // Items can only be added => always bounds change\n        XYItemChange change = (XYItemChange)itemChange;\n        return !LongRect.equals(change.getOldValuesBounds(),\n                                change.getNewValuesBounds());\n    }\n\n    public boolean isAppearanceChange(ChartItemChange itemChange) {\n//        if (!(itemChange instanceof XYItemChange))\n//            throw new UnsupportedOperationException(\"Unsupported itemChange: \" + itemChange);\n        \n        // Items can only be added => always appearance change\n        XYItemChange change = (XYItemChange)itemChange;\n        LongRect dirtyBounds = change.getDirtyValuesBounds();\n        return dirtyBounds.width != 0 || dirtyBounds.height != 0;\n    }\n\n    public LongRect getDirtyBounds(ChartItemChange itemChange, ChartContext context) {\n//        if (!(itemChange instanceof XYItemChange))\n//            throw new UnsupportedOperationException(\"Unsupported itemChange: \" + itemChange);\n        \n        // Items can only be added => always dirty bounds for last value\n        XYItemChange change = (XYItemChange)itemChange;\n        if (type == TYPE_ABSOLUTE) {\n\n            return getViewBounds(change.getDirtyValuesBounds(), context);\n        } else {\n            LongRect oldValuesBounds = change.getOldValuesBounds();\n            LongRect newValuesBounds = change.getNewValuesBounds();\n            if (oldValuesBounds.y != newValuesBounds.y ||\n                oldValuesBounds.height != newValuesBounds.height) {\n\n                return getItemBounds(change.getItem(), context);\n            } else {\n                return getViewBoundsRelative(change.getDirtyValuesBounds(),\n                                             change.getItem(), context);\n            }\n//            return new LongRect(0, 0, context.getViewportWidth(), context.getViewportHeight());\n        }\n//        return new LongRect(0, 0, context.getViewportWidth(), context.getViewportHeight());\n    }\n\n\n    public double getItemView(double dataY, XYItem item, ChartContext context) {\n        if (type == TYPE_ABSOLUTE) {\n            return super.getItemView(dataY, item, context);\n        } else {\n            double itemValueFactor = getItemValueFactor(context,\n                                     maxValueOffset, item.getBounds().height);\n            return context.getViewY(context.getDataOffsetY() + (itemValueFactor * dataY));\n        }\n    }\n\n    public double getItemValue(double viewY, XYItem item, ChartContext context) {\n        if (type == TYPE_ABSOLUTE) {\n            return super.getItemValue(viewY, item, context);\n        } else {\n            double itemValueFactor = getItemValueFactor(context,\n                                     maxValueOffset, item.getBounds().height);\n            return context.getDataY(viewY) / itemValueFactor;\n        }\n    }\n\n    public double getItemValueScale(XYItem item, ChartContext context) {\n        if (type == TYPE_ABSOLUTE) {\n            return super.getItemValueScale(item, context);\n        } else {\n            long itemHeight = item.getBounds().height;\n            if (itemHeight == 0) return 1;\n            double itemValueFactor = getItemValueFactor(context,\n                                     maxValueOffset, itemHeight);\n            return itemValueFactor / context.getDataHeight(1d);\n        }\n    }\n\n\n    public boolean supportsHovering(ChartItem item) {\n        return false;\n    }\n\n    public boolean supportsSelecting(ChartItem item) {\n        return false;\n    }\n\n    public LongRect getSelectionBounds(ItemSelection selection, ChartContext context) {\n        throw new UnsupportedOperationException(\"getSelectionBounds() not supported\"); // NOI18N\n    }\n\n    public ItemSelection getClosestSelection(ChartItem item, int viewX,\n                                             int viewY, ChartContext context) {\n        return null;\n    }\n\n    public void paintItem(ChartItem item, List<ItemSelection> highlighted,\n                          List<ItemSelection> selected, Graphics2D g,\n                          Rectangle dirtyArea, ChartContext context) {\n//        if (!(item instanceof XYItem))\n//            throw new UnsupportedOperationException(\"Unsupported item: \" + item); // NOI18N\n//        if (!(context instanceof ProfilerXYChartComponent.Context))\n//            throw new UnsupportedOperationException(\"Unsupported context: \" + context);\n        \n        paint((XYItem)item, highlighted, selected, g, dirtyArea,\n              (SynchronousXYChartContext)context);\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private LongRect getDataBounds(LongRect itemBounds) {\n        LongRect bounds = new LongRect(itemBounds);\n\n        if (fillColor != null) {\n            bounds.height += bounds.y;\n            bounds.y = 0;\n        }\n\n        return bounds;\n    }\n\n    private LongRect getViewBounds(LongRect itemBounds, ChartContext context) {\n        LongRect dataBounds = getDataBounds(itemBounds);\n\n        LongRect viewBounds = context.getViewRect(dataBounds);\n        LongRect.addBorder(viewBounds, lineWidth);\n\n        return viewBounds;\n    }\n\n    private LongRect getViewBoundsRelative(LongRect dataBounds, XYItem item,\n                                           ChartContext context) {\n        LongRect itemBounds = item.getBounds();\n\n        double itemValueFactor = getItemValueFactor(context,\n                                 maxValueOffset, itemBounds.height);\n\n        // TODO: fix the math!!!\n        double value1 = context.getDataOffsetY() + itemValueFactor *\n                      (double)(dataBounds.y - itemBounds.y);\n        double value2 = context.getDataOffsetY() + itemValueFactor *\n                      (double)(dataBounds.y + dataBounds.height - itemBounds.y);\n\n        long viewX = (long)Math.ceil(context.getViewX(dataBounds.x));\n        long viewWidth = (long)Math.ceil(context.getViewWidth(dataBounds.width));\n        if (context.isRightBased()) viewX -= viewWidth;\n\n        long viewY1 = (long)Math.ceil(context.getViewY(value1));\n        long viewY2 = (long)Math.ceil(context.getViewY(value2));\n        long viewHeight = context.isBottomBased() ? viewY1 - viewY2 :\n                                                    viewY2 - viewY1;\n        if (!context.isBottomBased()) viewY2 -= viewHeight;\n\n        LongRect viewBounds =  new LongRect(viewX, viewY2, viewWidth, viewHeight);\n        LongRect.addBorder(viewBounds, lineWidth);\n\n        return viewBounds;\n    }\n\n    \n    protected void paint(XYItem item, List<ItemSelection> highlighted,\n                       List<ItemSelection> selected, Graphics2D g,\n                       Rectangle dirtyArea, SynchronousXYChartContext context) {\n\n        if (item.getValuesCount() < 2) return;\n        if (context.getViewWidth() == 0 || context.getViewHeight() == 0) return;\n\n        int[][] points = createPoints(item, dirtyArea, context, type, maxValueOffset);\n        if (points == null) return;\n\n        int[] xPoints  = points[0];\n        int[] yPoints  = points[1];\n        int npoints = xPoints.length;\n\n//long start = System.nanoTime();\n        if (fillColor != null) {\n            int zeroY = Utils.checkedInt(context.getViewY(context.getDataOffsetY()));\n            zeroY = Math.max(Utils.checkedInt(context.getViewportOffsetY()), zeroY);\n            zeroY = Math.min(Utils.checkedInt(context.getViewportOffsetY() +\n                                                      context.getViewportHeight()), zeroY);\n\n            Polygon polygon = new Polygon();\n            polygon.xpoints = xPoints;\n            polygon.ypoints = yPoints;\n            polygon.npoints = npoints;\n            polygon.xpoints[npoints - 2] = xPoints[npoints - 3];\n            polygon.ypoints[npoints - 2] = zeroY;\n            polygon.xpoints[npoints - 1] = xPoints[0];\n            polygon.ypoints[npoints - 1] = zeroY;\n            g.setPaint(fillColor);\n            g.fill(polygon);\n        }\n\n        if (lineColor != null) {\n            g.setPaint(lineColor);\n            g.setStroke(lineStroke);\n            g.drawPolyline(xPoints, yPoints, npoints - 2);\n        }\n//System.err.println(\">>> Paint: \" + (System.nanoTime() - start) / 1000 + \" [ms], dirtyArea: \" + dirtyArea);\n//        if (type == TYPE_RELATIVE) {\n//        g.setColor(Color.RED);\n//        Rectangle bbox = new Rectangle(dirtyArea);\n////        bbox.width -= 1;\n////        bbox.height -= 1;\n//            g.draw(bbox);\n////            System.err.println(\">>> Here\");\n//        }\n\n//        if (type == TYPE_RELATIVE_BOUNDED) {\n//            System.err.println(\">>> paintItem, dirtyArea: \" + dirtyArea);\n//        }\n        \n    }\n\n    private static int[][] createPoints(XYItem item, Rectangle dirtyArea,\n                                 SynchronousXYChartContext context,\n                                 int type, int maxValueOffset) {\n\n        int valuesCount = item.getValuesCount();\n//        long st = System.currentTimeMillis();\n        int[][] visibleBounds = context.getVisibleBounds(dirtyArea);\n//        System.err.println(\">>> Create points: \" + (System.currentTimeMillis() - st));\n\n        int firstFirst = visibleBounds[0][0];\n        int firstIndex = firstFirst;\n        if (firstIndex == -1) firstIndex = visibleBounds[0][1];\n        if (firstIndex == -1) return null;\n        if (firstFirst != -1 && firstIndex > 0) firstIndex -= 1;\n\n        int lastFirst = visibleBounds[1][0];\n        int lastIndex = lastFirst;\n        if (lastIndex == -1) lastIndex = visibleBounds[1][1];\n        if (lastIndex == -1) lastIndex = valuesCount - 1;\n        if (lastFirst != -1 && lastIndex < valuesCount - 1) lastIndex += 1;\n\n//        System.err.println(\">>> First: \" + firstIndex + \", last: \" + lastIndex);\n//        if (firstIndex > lastIndex) {\n//            System.err.println(\">>> First: \" + firstIndex + \", last: \" + lastIndex);\n//            Thread.dumpStack();\n//        }\n\n        int itemsStep = (int)Math.ceil((double)valuesCount / (double)context.getViewWidth());\n        if (itemsStep == 0) itemsStep = 1;\n\n        int visibleCount = lastIndex - firstIndex + 1;\n//        if (visibleCount + 2 < 0) System.err.println(\">>> Negative, first: \" + Arrays.toString(visibleBounds[0]) + \", last: \" + Arrays.toString(visibleBounds[1]));\n//        System.err.println(\">>> first: \" + Arrays.toString(visibleBounds[0]) + \", last: \" + Arrays.toString(visibleBounds[1]));\n\n        if (itemsStep > 1) {\n            int firstMod = firstIndex % itemsStep;\n            firstIndex -= firstMod;\n            int lastMod = lastIndex % itemsStep;\n            lastIndex = lastIndex - lastMod + itemsStep;\n            visibleCount = (lastIndex - firstIndex) / itemsStep + 1;\n            lastIndex = Math.min(lastIndex, valuesCount - 1);\n        }\n\n//        if (visibleCount + 2 < 0) System.err.println(\">>> Negative, first: \" + firstIndex + \", last: \" + lastIndex);\n\n        int[] xPoints = new int[visibleCount + 2];\n        int[] yPoints = new int[visibleCount + 2];\n\n\n        double itemValueFactor = type == TYPE_RELATIVE ? getItemValueFactor(context,\n                                 maxValueOffset, item.getBounds().height) : 0;\n//        System.err.println(\">>> Painting: \" + visibleCount);\n        for (int i = 0; i < visibleCount; i++) {\n            int dataIndex = i == visibleCount - 1 ? lastIndex :\n                                 firstIndex + i * itemsStep;\n            xPoints[i] = Utils.checkedInt(Math.ceil(\n                         context.getViewX(item.getXValue(dataIndex))));\n            yPoints[i] = Utils.checkedInt(Math.ceil(\n                         getYValue(item, dataIndex,\n                         type, context, itemValueFactor)));\n        }\n        \n        return new int[][] { xPoints, yPoints };\n    }\n\n    private static double getYValue(XYItem item, int valueIndex,\n                                  int type, ChartContext context, double itemValueFactor) {\n        if (type == TYPE_ABSOLUTE) {\n            return context.getViewY(item.getYValue(valueIndex));\n        } else {\n            return context.getViewY(context.getDataOffsetY() + (itemValueFactor *\n                        (item.getYValue(valueIndex) - item.getBounds().y)));\n        }\n    }\n\n    private static double getItemValueFactor(ChartContext context,\n                                             double maxValueOffset,\n                                             double itemHeight) {\n        return ((double)context.getDataHeight() -\n               context.getDataHeight(maxValueOffset)) / itemHeight;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.charts/src/org/graalvm/visualvm/lib/charts/xy/synchronous/SynchronousXYItemsModel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.charts.xy.synchronous;\n\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.ChartItemChange;\nimport org.graalvm.visualvm.lib.charts.ItemsModel;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class SynchronousXYItemsModel extends ItemsModel.Abstract {\n\n    private final ArrayList<SynchronousXYItem> items = new ArrayList<>();\n    private final Timeline timeline;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    public SynchronousXYItemsModel(Timeline timeline) {\n        this.timeline = timeline;\n    }\n\n    public SynchronousXYItemsModel(Timeline timeline, SynchronousXYItem[] items) {\n        this(timeline);\n\n        if (items == null)\n            throw new IllegalArgumentException(\"Items cannot be null\"); // NOI18N\n        if (items.length == 0)\n            throw new IllegalArgumentException(\"Items cannot be empty\"); // NOI18N\n\n        addItems(items);\n    }\n\n\n    // --- Public interface ----------------------------------------------------\n\n    public void addItems(SynchronousXYItem[] addedItems) {\n        for (SynchronousXYItem addedItem : addedItems) {\n            addedItem.setTimeline(timeline);\n            items.add(addedItem);\n        }\n\n        fireItemsAdded(Arrays.asList(addedItems));\n\n        if (timeline.getTimestampsCount() > 0) valuesAdded();\n    }\n\n    public void removeItems(SynchronousXYItem[] removedItems) {\n        for (SynchronousXYItem item : removedItems) items.remove(item);\n        fireItemsRemoved(Arrays.asList(removedItems));\n    }\n\n\n    public final void valuesAdded() {\n        // Update values\n        List<ChartItemChange> itemChanges = new ArrayList<>(items.size());\n        for (SynchronousXYItem item : items) itemChanges.add(item.valuesChanged());\n        fireItemsChanged(itemChanges);\n\n        // Check timestamp\n        int valueIndex = timeline.getTimestampsCount() - 1;\n        long timestamp = timeline.getTimestamp(valueIndex);\n        long previousTimestamp = valueIndex == 0 ? -1 :\n                                 timeline.getTimestamp(valueIndex - 1);\n        \n        if (previousTimestamp != -1 && previousTimestamp >= timestamp)\n// See #168544\n//            throw new IllegalArgumentException(\n//                           \"ProfilerXYItemsModel: new timestamp \" + timestamp + // NOI18N\n//                           \" not greater than previous \" + previousTimestamp + // NOI18N\n//                           \", skipping the values.\"); // NOI18N\n            System.err.println(\"WARNING [\" + SynchronousXYItemsModel.class.getName() + // NOI18N\n                               \"]: ProfilerXYItemsModel: new timestamp \" + // NOI18N\n                               timestamp + \" not greater than previous \" + // NOI18N\n                               previousTimestamp + \", skipping the values.\"); // NOI18N\n    }\n\n    public final void valuesReset() {\n        // Update values\n        List<ChartItemChange> itemChanges = new ArrayList<>(items.size());\n        for (SynchronousXYItem item : items) itemChanges.add(item.valuesChanged());\n        fireItemsChanged(itemChanges);\n    }\n\n\n    public final Timeline getTimeline() {\n        return timeline;\n    }\n\n\n    // --- AbstractItemsModel implementation -----------------------------------\n\n    public final int getItemsCount() { return items.size(); }\n\n    public final SynchronousXYItem getItem(int index) { return items.get(index); }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project basedir=\".\" default=\"netbeans\" name=\"lib.profiler.common\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.lib.common</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.lib.common/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/lib/common/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.13\nOpenIDE-Module-Needs: org.graalvm.visualvm.lib.common.Profiler\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.lib.common-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/nbproject/genfiles.properties",
    "content": "# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=d0716bc0\nnbproject/build-impl.xml.script.CRC32=9dc5437f\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/nbproject/project.properties",
    "content": "# Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nis.autoload=true\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.lib.common</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.20</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.2</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.core</friend>\n                <friend>org.graalvm.visualvm.lib.profiler</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.api</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.attach</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.heapwalker</friend>\n                <friend>org.graalvm.visualvm.lib.ui</friend>\n                <friend>org.graalvm.visualvm.modules.appui</friend>\n                <friend>org.graalvm.visualvm.profiler</friend>\n                <friend>org.graalvm.visualvm.profiling</friend>\n                <friend>org.graalvm.visualvm.sampler</friend>\n                <friend>org.graalvm.visualvm.sampler.truffle</friend>\n                <package>org.graalvm.visualvm.lib.common</package>\n                <package>org.graalvm.visualvm.lib.common.event</package>\n                <package>org.graalvm.visualvm.lib.common.integration</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/../..\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/AttachSettings.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.common;\n\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.common.integration.IntegrationUtils;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\n\n\n/**\n * Storage of all settings that affect the method of attaching.\n *\n * @author Tomas Hurka\n * @author Ian Formanek\n * @author Misha Dmitriev\n */\npublic final class AttachSettings {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final String PROP_ATTACH_DIRECT = \"profiler.attach.direct\"; //NOI18N\n    public static final String PROP_ATTACH_REMOTE = \"profiler.attach.remote\"; //NOI18N\n    public static final String PROP_ATTACH_DYNAMIC_JDK16 = \"profiler.attach.dynamic.jdk16\"; //NOI18N\n    public static final String PROP_ATTACH_HOST = \"profiler.attach.host\"; //NOI18N\n    public static final String PROP_ATTACH_PORT = \"profiler.attach.port\"; //NOI18N\n    public static final String PROP_ATTACH_DYNAMIC_PID = \"profiler.attach.dynamic.pid\"; //NOI18N\n    public static final String PROP_ATTACH_DYNAMIC_PROCESS_NAME = \"profiler.attach.dynamic.processName\"; //NOI18N\n    public static final String PROP_ATTACH_DYNAMIC_AUTO = \"profiler.attach.dynamic.auto\"; //NOI18N\n\n    // following items are for settings persistency only, they don't affect attaching at all\n    public static final String PROP_ATTACH_TARGET_TYPE = \"profiler.attach.target.type\"; //NOI18N\n    public static final String PROP_ATTACH_SERVER_TYPE = \"profiler.attach.server.type\"; //NOI18N\n    public static final String PROP_ATTACH_HOST_OS = \"profiler.attach.host.os\"; //NOI18N\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    // for remote:\n    private String host = \"\"; // NOI18N\n    private String hostOS;\n    private String serverType = \"\"; // NOI18N\n\n    // for persistence only:\n    private String targetType = \"\"; // NOI18N\n\n    // Direct is true means what we also call \"attach on startup\" - when the target VM is started with all necessary options\n    // and waits for us to connect. It can be used both for local and remote profiling. In fact, currently remote profiling\n    // can only be done in this way, but later we can implement an equivalent of \"remote Ctrl+Break\" or something. In that case,\n    // the constructor of the AttachSettings for remote profiling will have to be modified.\n    private boolean direct = true;\n\n    // for local:\n    private boolean dynamic16 = false;\n    private boolean remote = false;\n    private int pid = -1;\n    private String processName;\n    private boolean autoSelect;\n    private int transientPort = -1;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Create AttachSettings for direct local profiling */\n    public AttachSettings() {\n        remote = false;\n        direct = true;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setDirect(final boolean direct) {\n        this.direct = direct;\n    }\n\n    public boolean isDirect() {\n        return direct;\n    }\n\n    public void setDynamic16(final boolean dynamic) {\n        this.dynamic16 = dynamic;\n    }\n\n    public boolean isDynamic16() {\n        return dynamic16;\n    }\n\n    public void setHost(final String host) {\n        if (host == null) {\n            throw new IllegalArgumentException();\n        }\n\n        this.host = host;\n    }\n\n    public String getHost() {\n        return host;\n    }\n\n    public void setHostOS(final String hostOS) {\n        this.hostOS = hostOS;\n    }\n\n    public String getHostOS() {\n        return hostOS == null ? IntegrationUtils.getLocalPlatform(-1) : hostOS;\n    }\n\n    public void setPid(final int pid) {\n        this.pid = pid;\n    }\n\n    public int getPid() {\n        return pid;\n    }\n    \n    public void setProcessName(String processName) {\n        this.processName = processName;\n    }\n    \n    public String getProcessName() {\n        return processName;\n    }\n    \n    public void setAutoSelectProcess(boolean autoSelect) {\n        this.autoSelect = autoSelect;\n    }\n    \n    public boolean isAutoSelectProcess() {\n        return autoSelect;\n    }\n\n    /** This is only intended to be used to handle AttachSettings defined via ant.\n     *\n     * @param port A port to use instead of globally defined port. The value is transient and will not be persisted.\n     */\n    public void setPort(final int port) {\n        this.transientPort = port;\n    }\n\n    public int getPort() {\n        if (transientPort != -1) {\n            return transientPort;\n        } else {\n            return Profiler.getDefault().getGlobalProfilingSettings().getPortNo();\n        }\n    }\n\n    public void setRemote(final boolean remote) {\n        this.remote = remote;\n    }\n\n    public boolean isRemote() {\n        return remote;\n    }\n\n    public void setServerType(final String serverType) {\n        this.serverType = serverType;\n    }\n\n    public String getServerType() {\n        return serverType;\n    }\n\n    public void setTargetType(final String targetType) {\n        this.targetType = targetType;\n    }\n\n    public String getTargetType() {\n        return targetType;\n    }\n\n    public void applySettings(final ProfilerEngineSettings sharedSettings) {\n        sharedSettings.setPortNo(getPort());\n\n        if (remote) {\n            sharedSettings.setRemoteHost(host);\n        } else {\n            sharedSettings.setRemoteHost(\"\"); // NOI18N\n        }\n        if (isDynamic16()) {\n            sharedSettings.setInstrumentObjectInit(true);\n        } else {\n            sharedSettings.setInstrumentObjectInit(false);            \n        }\n    }\n\n    public void copyInto(AttachSettings as) {\n        as.direct = direct;\n        as.remote = remote;\n        as.dynamic16 = dynamic16;\n        as.pid = pid;\n        as.processName = processName;\n        as.autoSelect = autoSelect;\n        as.host = host;\n        as.targetType = targetType;\n        as.serverType = serverType;\n        as.hostOS = hostOS;\n    }\n\n    public String debug() {\n        return toString();\n    }\n\n    public void load(final Map props) {\n        direct = Boolean.valueOf(ProfilingSettings.getProperty(props, PROP_ATTACH_DIRECT, \"true\")).booleanValue(); //NOI18N\n        remote = Boolean.valueOf(ProfilingSettings.getProperty(props, PROP_ATTACH_REMOTE, \"false\")).booleanValue(); //NOI18N\n        dynamic16 = Boolean.valueOf(ProfilingSettings.getProperty(props, PROP_ATTACH_DYNAMIC_JDK16, \"false\")).booleanValue(); //NOI18N\n        host = ProfilingSettings.getProperty(props, PROP_ATTACH_HOST, \"\"); //NOI18N\n        targetType = ProfilingSettings.getProperty(props, PROP_ATTACH_TARGET_TYPE, \"\"); //NOI18N\n        serverType = ProfilingSettings.getProperty(props, PROP_ATTACH_SERVER_TYPE, \"\"); //NOI18N\n        hostOS = ProfilingSettings.getProperty(props, PROP_ATTACH_HOST_OS, null); //NOI18N\n        pid = Integer.parseInt(ProfilingSettings.getProperty(props, PROP_ATTACH_DYNAMIC_PID, \"-1\")); //NOI18N\n        processName = ProfilingSettings.getProperty(props, PROP_ATTACH_DYNAMIC_PROCESS_NAME, null); //NOI18\n        autoSelect = Boolean.valueOf(ProfilingSettings.getProperty(props, PROP_ATTACH_DYNAMIC_AUTO, \"false\")).booleanValue(); //NOI18N\n    }\n\n    public void store(final Map props) {\n        props.put(PROP_ATTACH_DIRECT, Boolean.toString(direct));\n        props.put(PROP_ATTACH_REMOTE, Boolean.toString(remote));\n        props.put(PROP_ATTACH_DYNAMIC_JDK16, Boolean.toString(dynamic16));\n        props.put(PROP_ATTACH_HOST, host);\n        props.put(PROP_ATTACH_TARGET_TYPE, targetType);\n        props.put(PROP_ATTACH_SERVER_TYPE, serverType);\n        if (hostOS == null)  props.remove(PROP_ATTACH_HOST_OS);\n        else props.put(PROP_ATTACH_HOST_OS, hostOS);\n        if (pid == -1) props.remove(PROP_ATTACH_DYNAMIC_PID);\n        else props.put(PROP_ATTACH_DYNAMIC_PID, Integer.toString(pid));\n        if (processName == null) props.remove(PROP_ATTACH_DYNAMIC_PROCESS_NAME);\n        else props.put(PROP_ATTACH_DYNAMIC_PROCESS_NAME, processName);\n        if (!autoSelect) props.remove(PROP_ATTACH_DYNAMIC_AUTO);\n        else props.put(PROP_ATTACH_DYNAMIC_AUTO, Boolean.TRUE.toString());\n    }\n\n    public String toString() {\n        final StringBuffer sb = new StringBuffer();\n        sb.append(\"target type =\").append(targetType); //NOI18N\n        sb.append(\"\\n\"); //NOI18N\n        sb.append(\"server type =\").append(serverType); //NOI18N\n        sb.append(\"\\n\"); //NOI18N\n        sb.append(\"remote =\").append(remote); //NOI18N\n        sb.append(\"\\n\"); //NOI18N\n        sb.append(\"direct =\").append(direct); //NOI18N\n        sb.append(\"\\n\"); //NOI18N\n        sb.append(\"dynamic JDK16 =\").append(dynamic16); //NOI18N\n        sb.append(\"\\n\"); //NOI18N\n        sb.append(\"pid =\").append(pid); //NOI18N\n        sb.append(\"\\n\"); //NOI18N\n        sb.append(\"process name =\").append(processName); //NOI18N\n        sb.append(\"\\n\"); //NOI18N\n        sb.append(\"auto select =\").append(autoSelect); //NOI18N\n        sb.append(\"\\n\"); //NOI18N\n        sb.append(\"host =\").append(host); //NOI18N\n        sb.append(\"\\n\"); //NOI18N\n        sb.append(\"host os =\").append(hostOS == null ? IntegrationUtils.getLocalPlatform(-1) : hostOS); //NOI18N\n        sb.append(\"\\n\"); //NOI18N\n        sb.append(\"transient port =\").append(transientPort); //NOI18N\n        sb.append(\"\\n\"); //NOI18N\n\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n# Sample ResourceBundle properties file\n\nGlobalProfilingSettings_InvalidWorkingDirectoryWarning=Invalid working directory specified\\: {0}\nGlobalProfilingSettings_InvalidTargetJVMExeFileError=Invalid target JVM executable file specified\\: {0}\\n{1}\n\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Name=Java Profiler (Common)\nProfilingSettings_DefaultProfilingSettingsName=Unnamed\nProfilingSettings_UnknownProfilingSettingsName=Unknown\n\nSessionSettings_IncorrectPortMsg=Wrong port number loaded, default port will be used\nSessionSettings_IncorrectArchMsg=Wrong architecture number loaded, 32bit will be used\n\nProfilingSettingsPresets_MonitorPresetName=Monitor Application\nProfilingSettingsPresets_CpuPresetName=Analyze Performance\nProfilingSettingsPresets_MemoryPresetName=Analyze Memory\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/CommonUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.common;\n\nimport java.lang.reflect.InvocationTargetException;\nimport javax.swing.*;\n\n\n/**\n * Various utilities independent of the NetBeans IDE\n *\n * @author Tomas Hurka\n * @author Ian Formanek\n */\npublic final class CommonUtils {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void runInEventDispatchThread(final Runnable r) {\n        if (SwingUtilities.isEventDispatchThread()) {\n            r.run();\n        } else {\n            SwingUtilities.invokeLater(r);\n        }\n    }\n\n    public static void runInEventDispatchThreadAndWait(final Runnable r) {\n        if (SwingUtilities.isEventDispatchThread()) {\n            r.run();\n        } else {\n            try {\n                SwingUtilities.invokeAndWait(r);\n            } catch (InvocationTargetException e) {\n                Profiler.getDefault().notifyException(Profiler.EXCEPTION, e);\n            } catch (InterruptedException e) {\n                Profiler.getDefault().notifyException(Profiler.EXCEPTION, e);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/GlobalProfilingSettings.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.common;\n\n\n/**\n * Access of global profiling settings (settings such as communication port number or working directory,\n * that are independent of the kind of profiling, such as CPU or Memory).\n *\n * @author Tomas Hurka\n * @author Ian Formanek\n * @author Misha Dmitriev\n */\npublic interface GlobalProfilingSettings {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    void setCalibrationPortNo(final int value);\n\n    int getCalibrationPortNo();\n\n    /** @param value Name of Java platform to use for profiling. Null value indicates no global platform is selected */\n    void setJavaPlatformForProfiling(String value);\n\n    /** @return Name of Java platform to use for profiling. Null value indicates no global platform is selected */\n    String getJavaPlatformForProfiling();\n\n    void setPortNo(final int value);\n\n    int getPortNo();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/Profiler.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.common;\n\nimport java.awt.EventQueue;\nimport java.io.IOException;\nimport java.util.Iterator;\nimport java.util.Vector;\nimport org.graalvm.visualvm.lib.common.event.ProfilingStateEvent;\nimport org.graalvm.visualvm.lib.common.event.ProfilingStateListener;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils.SourceCodeSelection;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.BadLocationException;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.InstrumentationException;\nimport org.graalvm.visualvm.lib.jfluid.results.monitor.VMTelemetryDataManager;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadsDataManager;\nimport org.openide.util.Lookup;\n\n\n/** An abstract superclass representing the entire Profiler.  The Profiler class should add a \"state\" on top of the\n * underlying JFluid engine, providing easier access to its various functions.\n *\n * A concrete subclass would implement the abstract methods in a specific way (integrated into an IDE, standalone GUI\n * tool, non-gui tool, etc.).\n *\n * This class can also be used by any profiling code to obtain the concrete implementation of the Profiler at any given\n * moment by calling the getDefault () method. Such parts, if they only need to call methods of the Profiler class\n * and/or any of the underlying libraries (jfluid.jar, jfluid-ui.jar) would then be independent of a concrete form of\n * the profiler, whether it if GUI/Non-GUI or Integrated/Standalone.\n *\n * @author Tomas Hurka\n * @author Ian Formanek\n */\npublic abstract class Profiler {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // Profiling states\n    public static final int PROFILING_INACTIVE = 1; // no profiling session in progress\n    public static final int PROFILING_STARTED = 2; // profiling session started but TA not yet running\n    public static final int PROFILING_RUNNING = 4; // profiling session in progress and TA running\n    public static final int PROFILING_PAUSED = 8; // profiling session in progress and TA paused (all threads suspended)\n    public static final int PROFILING_STOPPED = 16; // profiling session finished, some results still available\n    public static final int PROFILING_IN_TRANSITION = 128; // profiling state is in transition between states\n\n    // Profiling modes\n    public static final int MODE_ATTACH = 0;\n    public static final int MODE_PROFILE = 1;\n\n    // Logging & error management\n\n    /** Message that would be useful for tracing events but which need not be a problem. */\n    public static final int INFORMATIONAL = 1;\n\n    /** Something went wrong in the software, but it is continuing and the user need not be bothered. */\n    public static final int WARNING = 2;\n\n    /** Something the user should be aware of. */\n    public static final int USER = 4;\n\n    /** Something went wrong, though it can be recovered. */\n    public static final int EXCEPTION = 8;\n\n    /** Serious problem, application may be crippled. */\n    public static final int ERROR = 16;\n    private static final boolean DEBUG = System.getProperty(\"org.graalvm.visualvm.lib.common.Profiler\") != null; // NOI18N\n    private static Profiler defaultProfiler;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Vector profilingStateListeners;\n    private int currentProfilingState = PROFILING_INACTIVE;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static synchronized Profiler getDefault() {\n        if (defaultProfiler == null) {\n            defaultProfiler = (Profiler) Lookup.getDefault().lookup(Profiler.class);\n            if (defaultProfiler == null) {\n                throw new InternalError(\"Should never happen\"); // NOI18N\n            } else if (DEBUG) {\n                System.err.println(\"Default Profiler succesfully installed: \" + defaultProfiler); // NOI18N\n            }\n        }\n        return defaultProfiler;\n    }\n\n    /** Obtains a state for agent listening on given port, checking whether it has the expected agentId.\n     *\n     * @param host Ignored for now\n     * @param port Port number to be used to communicate with the agent\n     * @param agentId Expected agent Id\n     * @return the state of the agent\n     * @see CommonConstants#AGENT_STATE_CONNECTED\n     * @see CommonConstants#AGENT_STATE_DIFFERENT_ID\n     * @see CommonConstants#AGENT_STATE_NOT_RUNNING\n     * @see CommonConstants#AGENT_STATE_OTHER_SESSION_IN_PROGRESS\n     * @see CommonConstants#AGENT_STATE_READY_DIRECT\n     * @see CommonConstants#AGENT_STATE_READY_DYNAMIC\n     */\n    public abstract int getAgentState(String host, int port, int agentId);\n\n    public abstract SessionSettings getCurrentSessionSettings();\n\n    public abstract GlobalProfilingSettings getGlobalProfilingSettings();\n\n    public abstract ProfilingSettings getLastProfilingSettings();\n\n    public abstract int getProfilingMode();\n\n    public abstract int getProfilingState();\n\n    public abstract int getServerState();\n\n    public abstract int getServerProgress();\n\n    public abstract TargetAppRunner getTargetAppRunner();\n\n    public abstract ThreadsDataManager getThreadsManager();\n\n    public abstract void setThreadsMonitoringEnabled(boolean enabled);\n\n    public abstract boolean getThreadsMonitoringEnabled();\n    \n    public abstract void setLockContentionMonitoringEnabled(boolean enabled);\n\n    public abstract boolean getLockContentionMonitoringEnabled();\n\n    public abstract VMTelemetryDataManager getVMTelemetryManager();\n\n    public abstract boolean attachToApp(ProfilingSettings profilingSettings, AttachSettings as);\n\n    public abstract boolean connectToStartedApp(ProfilingSettings profilingSettings, SessionSettings sessionSettings);\n\n    public abstract void detachFromApp();\n\n    public abstract void instrumentSelectedRoots(ClientUtils.SourceCodeSelection[] rootMethods)\n                                          throws ClassNotFoundException, InstrumentationException, BadLocationException,\n                                                 IOException, ClassFormatError, ClientUtils.TargetAppOrVMTerminated;\n\n    /** Silently log a message. This is not intended for user-level error notification, but rather for\n     * internal messages that would be logged based on the severity level.\n     *\n     * @param severity The severity of the problem\n     * @param message The message to log\n     */\n    public abstract void log(int severity, String message);\n\n    public abstract void modifyCurrentProfiling(ProfilingSettings profilingSettings);\n\n    /** Notify the user about an internal error. This is not intended for user-level error notification, but rather for\n     * internal unexpected problems that usually represent a bug in our code.\n     *\n     * @param severity The severity of the problem\n     * @param e The exception that occurred\n     */\n    public abstract void notifyException(int severity, Exception e);\n\n    public abstract void openJavaSource(String classname, String methodName, String methodSig);\n\n    public abstract boolean profileClass(ProfilingSettings profilingSettings, SessionSettings sessionSettings);\n\n    public abstract boolean rerunAvailable();\n\n    public abstract boolean modifyAvailable();\n\n    public abstract void rerunLastProfiling();\n\n    public abstract boolean runCalibration(boolean checkForSaved, String jvmExecutable, String jdkString, int architecture);\n\n    public abstract boolean shutdownBlockedAgent(String host, int port, int agentId);\n\n    public abstract void stopApp();\n\n    // ProfilingStateListener stuff\n    public final void addProfilingStateListener(final ProfilingStateListener profilingStateListener) {\n        if (profilingStateListeners == null) {\n            profilingStateListeners = new Vector();\n        }\n\n        if (!profilingStateListeners.contains(profilingStateListener)) {\n            profilingStateListeners.add(profilingStateListener);\n            profilingStateListener.profilingStateChanged(new ProfilingStateEvent(-1, currentProfilingState, defaultProfiler));\n            // should not add listeners in the middle of profiling session\n            // profilingStateListener.instrumentationChanged(-1, getTargetAppRunner().getProfilerClient().getCurrentInstrType());\n        }\n    }\n\n    public boolean prepareInstrumentation(ProfilingSettings profilingSettings)\n            throws ClientUtils.TargetAppOrVMTerminated, InstrumentationException,\n            BadLocationException, ClassNotFoundException, IOException, ClassFormatError {\n        final ProfilerClient client = getTargetAppRunner().getProfilerClient();\n        final int oldInstrType = client.getStatus().currentInstrType;\n\n        switch (profilingSettings.getProfilingType()) {\n            case ProfilingSettings.PROFILE_MONITOR:\n                client.initiateMonitoring();\n\n                break;\n            case ProfilingSettings.PROFILE_MEMORY_SAMPLING:\n                client.initiateMemoryProfInstrumentation(CommonConstants.INSTR_NONE_MEMORY_SAMPLING);\n\n                break;\n            case ProfilingSettings.PROFILE_MEMORY_ALLOCATIONS:\n                client.initiateMemoryProfInstrumentation(CommonConstants.INSTR_OBJECT_ALLOCATIONS);\n\n                break;\n            case ProfilingSettings.PROFILE_MEMORY_LIVENESS:\n                client.initiateMemoryProfInstrumentation(CommonConstants.INSTR_OBJECT_LIVENESS);\n\n                break;\n            case ProfilingSettings.PROFILE_CPU_ENTIRE:\n            case ProfilingSettings.PROFILE_CPU_PART:\n            case ProfilingSettings.PROFILE_CPU_JDBC:\n                instrumentSelectedRoots(profilingSettings.getInstrumentationMethods());\n\n                break;\n            case ProfilingSettings.PROFILE_CPU_SAMPLING:\n                client.initiateCPUSampling();\n                break;\n                \n            case ProfilingSettings.PROFILE_CPU_STOPWATCH:\n\n                SourceCodeSelection[] fragment = new SourceCodeSelection[] { profilingSettings.getCodeFragmentSelection() };\n                client.initiateCodeRegionInstrumentation(fragment);\n\n                break;\n        }\n\n        fireInstrumentationChanged(oldInstrType, client.getStatus().currentInstrType);\n\n        return true;\n    }\n\n    public final boolean profilingInProgress() {\n        final int state = getProfilingState();\n\n        return ((state == PROFILING_PAUSED) || (state == PROFILING_RUNNING));\n    }\n\n    public final void removeProfilingStateListener(final ProfilingStateListener profilingStateListener) {\n        if (profilingStateListeners != null) {\n            profilingStateListeners.remove(profilingStateListener);\n        }\n    }\n\n    public static void debug(String s) {\n        if (DEBUG) {\n            System.err.println(\"Profiler.DEBUG: \" + s); // NOI18N\n        }\n    }\n\n    public static void debug(Exception e) {\n        if (DEBUG) {\n            System.err.print(\"Profiler.DEBUG: \"); // NOI18N\n            e.printStackTrace(System.err);\n        }\n    }\n\n    public abstract String getLibsDir();\n\n    public abstract int getPlatformArchitecture(String platformName);\n\n    public abstract String getPlatformJDKVersion(String platformName);\n\n    public abstract String getPlatformJavaFile(String platformName);\n\n    protected final void fireInstrumentationChanged(final int oldInstrType, final int currentInstrType) {\n        if (profilingStateListeners == null) {\n            return;\n        }\n\n        final Vector toNotify;\n\n        synchronized (this) {\n            toNotify = (Vector) profilingStateListeners.clone();\n        }\n\n        final Iterator iterator = toNotify.iterator();\n        final Runnable r = new Runnable() {\n            public void run() {\n                while (iterator.hasNext()) {\n                    ((ProfilingStateListener) iterator.next()).instrumentationChanged(oldInstrType, currentInstrType);\n                }\n            }\n        };\n\n        if (EventQueue.isDispatchThread()) {\n            r.run();\n        } else {\n            EventQueue.invokeLater(r);\n        }\n    }\n\n    protected final void fireProfilingStateChange(final int oldProfilingState, final int newProfilingState) {\n        currentProfilingState = newProfilingState;\n\n        if (profilingStateListeners == null) {\n            return;\n        }\n\n        if (oldProfilingState == newProfilingState) {\n            return;\n        }\n\n        final Vector toNotify;\n\n        synchronized (this) {\n            toNotify = (Vector) profilingStateListeners.clone();\n        }\n\n        final Iterator iterator = toNotify.iterator();\n        final ProfilingStateEvent event = new ProfilingStateEvent(oldProfilingState, newProfilingState, this);\n        final Runnable r = new Runnable() {\n            public void run() {\n                while (iterator.hasNext()) {\n                    ((ProfilingStateListener) iterator.next()).profilingStateChanged(event);\n                }\n            }\n        };\n\n        if (EventQueue.isDispatchThread()) {\n            r.run();\n        } else {\n            EventQueue.invokeLater(r);\n        }\n    }\n\n    protected final void fireThreadsMonitoringChange() {\n        if (profilingStateListeners == null) {\n            return;\n        }\n\n        final Vector toNotify;\n\n        synchronized (this) {\n            toNotify = (Vector) profilingStateListeners.clone();\n        }\n\n        final Iterator iterator = toNotify.iterator();\n        final Runnable r = new Runnable() {\n            public void run() {\n                while (iterator.hasNext()) {\n                    ((ProfilingStateListener) iterator.next()).threadsMonitoringChanged();\n                }\n            }\n        };\n\n        if (EventQueue.isDispatchThread()) {\n            r.run();\n        } else {\n            EventQueue.invokeLater(r);\n        }\n    }\n    \n    protected final void fireLockContentionMonitoringChange() {\n        if (profilingStateListeners == null) {\n            return;\n        }\n\n        final Vector toNotify;\n\n        synchronized (this) {\n            toNotify = (Vector) profilingStateListeners.clone();\n        }\n\n        final Iterator iterator = toNotify.iterator();\n        final Runnable r = new Runnable() {\n            public void run() {\n                while (iterator.hasNext()) {\n                    ((ProfilingStateListener) iterator.next()).lockContentionMonitoringChanged();\n                }\n            }\n        };\n\n        if (EventQueue.isDispatchThread()) {\n            r.run();\n        } else {\n            EventQueue.invokeLater(r);\n        }\n    }\n\n    protected final void fireServerStateChanged(final int serverState, final int serverProgress) {\n        if (profilingStateListeners == null) {\n            return;\n        }\n\n        final Vector toNotify;\n\n        synchronized (this) {\n            toNotify = (Vector) profilingStateListeners.clone();\n        }\n\n        final Iterator iterator = toNotify.iterator();\n        final Runnable r = new Runnable() {\n            public void run() {\n                while (iterator.hasNext()) {\n                    ((ProfilingStateListener) iterator.next()).serverStateChanged(serverState, serverProgress);\n                }\n            }\n        };\n\n        if (EventQueue.isDispatchThread()) {\n            r.run();\n        } else {\n            EventQueue.invokeLater(r);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/ProfilingSettings.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.common;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.filters.JavaTypeFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n\n/**\n * A Class holding a single named profiling configuration settings within the IDE.\n *\n * @author Tomas Hurka\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic class ProfilingSettings {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle bundle = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.common.Bundle\"); // NOI18N\n    static final String DEFAULT_PROFILING_SETTINGS_NAME = bundle.getString(\"ProfilingSettings_DefaultProfilingSettingsName\"); // NOI18N\n    private static final String UNKNOWN_PROFILING_SETTINGS_NAME = bundle.getString(\"ProfilingSettings_UnknownProfilingSettingsName\"); // NOI18N\n                                                                                                                                      // -----\n\n    // Profiling modes\n    public static final int PROFILE_MONITOR = 1; // just monitoring\n    public static final int PROFILE_MEMORY_ALLOCATIONS = 2; // memory: allocations\n    public static final int PROFILE_MEMORY_LIVENESS = 4; // memory: liveness\n    public static final int PROFILE_CPU_ENTIRE = 8; // cpu: entire app (root = main)\n    public static final int PROFILE_CPU_PART = 16; // cpu: root methods\n    public static final int PROFILE_CPU_STOPWATCH = 32; // cpu: code fragment\n    public static final int PROFILE_CPU_SAMPLING = 64; // cpu: sampled profiling\n    public static final int PROFILE_MEMORY_SAMPLING = 128; // memory: sampling \n    public static final int PROFILE_CPU_JDBC = 256; // special type of cpu profiling (uses marker methods) \n    public static final boolean QUICK_FILTER_INCLUSIVE = true;\n    public static final boolean QUICK_FILTER_EXCLUSIVE = false;\n    public static final String LINES_PREFIX = \"[lines]\"; //NOI18N\n    public static final String PROP_OVERRIDE_GLOBAL_SETTINGS = \"profiler.settings.override\"; //NOI18N\n    public static final String PROP_WORKING_DIR = \"profiler.settings.override.working.dir\"; //NOI18N\n    public static final String PROP_JVM_ARGS = \"profiler.settings.override.jvm.args\"; //NOI18N\n    public static final String PROP_JAVA_PLATFORM = \"profiler.settings.override.java.platform\"; //NOI18N\n    public static final String PROP_IS_PRESET = \"profiler.settigns.ispreset\"; // NOI18N\n    public static final String PROP_SETTINGS_NAME = \"profiler.settings.settings.name\"; //NOI18N\n    public static final String PROP_PROFILING_TYPE = \"profiler.settings.profiling.type\"; //NOI18N\n    public static final String PROP_THREADS_MONITORING_ENABLED = \"profiler.settings.threads.monitoring.enabled\"; //NOI18N\n    public static final String PROP_LOCKCONTENTION_MONITORING_ENABLED = \"profiler.settings.lockcontention.monitoring.enabled\"; //NOI18N\n    public static final String PROP_THREADS_SAMPLING_ENABLED = \"profiler.settings.threads.sampling.enabled\"; //NOI18N\n    public static final String PROP_CPU_PROFILING_TYPE = \"profiler.settings.cpu.profiling.type\"; //NOI18N\n    public static final String PROP_EXCLUDE_WAIT_TIME = \"profiler.settings.cpu.exclude.wait.time\"; // NOI18N\n    public static final String PROP_INSTR_SCHEME = \"profiler.settings.instr.scheme\"; //NOI18N\n    public static final String PROP_THREAD_CPU_TIMER_ON = \"profiler.settings.thread.cpu.timer.on\"; //NOI18N\n    public static final String PROP_INSTRUMENT_GETTER_SETTER_METHODS = \"profiler.settings.istrument.getter.setter.methods\"; //NOI18N\n    public static final String PROP_INSTRUMENT_EMPTY_METHODS = \"profiler.settings.instrument.empty.methods\"; //NOI18N\n    public static final String PROP_INSTRUMENT_METHOD_INVOKE = \"profiler.settings.instrument.method.invoke\"; //NOI18N\n    public static final String PROP_INSTRUMENT_SPAWNED_THREADS = \"profiler.settings.instrument.spawned.threads\"; //NOI18N\n    public static final String PROP_N_PROFILED_THREADS_LIMIT = \"profiler.settings.n.profiled.threads.limit\"; //NOI18N\n    public static final String PROP_MAX_STRING_LENGTH = \"profiler.settings.max.string.length\"; //NOI18N\n    public static final String PROP_STACK_DEPTH_LIMIT = \"profiler.settings.stack.depth.limit\"; //NOI18N\n    public static final String PROP_SORT_RESULTS_BY_THREAD_CPU_TIME = \"profiler.settings.sort.results.by.thread.cpu.time\"; //NOI18N\n    public static final String PROP_SAMPLING_INTERVAL = \"profiler.settings.sampling.interval\"; //NOI18N\n    public static final String PROP_INSTRUMENTATION_ROOT_METHODS_SIZE = \"profiler.settings.instrumentation.root.methods.size\"; //NOI18N\n    public static final String PROP_INSTRUMENTATION_ROOT_METHODS_PREFIX = \"profiler.settings.istrumentation.root.methods-\"; //NOI18N\n    public static final String PROP_INSTRUMENTATION_MARKER_METHODS_SIZE = \"profiler.settings.instrumentation.marker.methods.size\"; //NOI18N\n    public static final String PROP_INSTRUMENTATION_MARKER_METHODS_PREFIX = \"profiler.settings.istrumentation.marker.methods-\"; //NOI18N\n    public static final String PROP_FRAGMENT_SELECTION = \"profiler.settings.fragment.selection\"; //NOI18N\n    public static final String PROP_CODE_REGION_CPU_RES_BUF_SIZE = \"profiler.settings.code.region.cpu.res.buf.size\"; //NOI18N\n    public static final String PROP_RUN_GC_ON_GET_RESULTS_IN_MEMORY_PROFILING = \"profiler.settings.run.gc.on.get.results.in.memory.profiling\"; //NOI18N\n    public static final String PROP_OBJ_ALLOC_STACK_SAMPLING_INTERVAL = \"profiler.settings.obj.alloc.stack.sampling.interval\"; //NOI18N\n    public static final String PROP_OBJ_ALLOC_STACK_SAMPLING_DEPTH = \"profiler.settings.obj.alloc.stack.sampling.depth\"; //NOI18N\n    public static final String PROP_INSTR_FILTER = \"profiler.settings.instrumentation.filter.\"; //NOI18N\n    public static final String PROP_PROFILE_UNDERLYING_FRAMEWORK = \"profiler.settings.profile.underlying.framework\"; // NOI18N\n    public static final String PROP_PROFILING_POINTS_ENABLED = \"profiler.settings.profilingpoints.enabled\"; //NOI18N\n    public static final String PROP_QUICK_FILTER = \"profiler.settings.cpu.quick.filter\"; //NOI18N\n    public static final String PROP_SAMPLING_FREQUENCY = \"profiler.settings.cpu.sampling.frequency\"; //NOI18N\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    // CPU Profiling: Code Fragment\n    private ClientUtils.SourceCodeSelection fragmentSelection = null;\n    private List instrumentationMarkerMethods = new ArrayList();\n\n    // CPU Profiling: Part of Application\n    private List instrumentationRootMethods = new ArrayList();\n\n    // CPU instrumentation filter related settings\n    private GenericFilter instrumentationFilter = new GenericFilter();\n    \n    private String jvmArgs = \"\"; //NOI18N\n    private String platformName = null; // from project\n    private String settingsName = DEFAULT_PROFILING_SETTINGS_NAME;\n    private String workingDir = \"\"; //NOI18N\n\n    // CPU and Code Fragment common\n    private boolean excludeWaitTime = true;\n    private boolean instrumentEmptyMethods = false;\n    private boolean instrumentGetterSetterMethods = false;\n    private boolean instrumentMethodInvoke = true;\n    private boolean instrumentSpawnedThreads = false;\n\n    // General (global) settings\n    private boolean isPreset = false;\n    private boolean overrideGlobalSettings = false;\n    private boolean profileUnderlyingFramework = false;\n\n    // -- Memory profiling settings\n    private boolean runGCOnGetResultsInMemoryProfiling = true;\n    private boolean sortResultsByThreadCPUTime = false;\n    private boolean threadCPUTimerOn = true;\n    private boolean threadsMonitoringEnabled = false;\n    private boolean lockContentionMonitoringEnabled = false;\n    private boolean threadsSamplingEnabled = true;\n\n    // General CPU Profiling settings\n    private boolean useProfilingPoints = true;\n    private int allocStackTraceLimit = 0; // 0 means no stack sampling performed\n    private int allocTrackEvery = 10; // limits the number of allocations tracked to each n-th\n    private int codeRegionCPUResBufSize = 1000;\n    private int cpuProfilingType = CommonConstants.CPU_INSTR_FULL;\n    private int instrScheme = CommonConstants.INSTRSCHEME_LAZY;\n    private int maxStringLength = CommonConstants.MAX_STRING_LENGTH_DEFAULT;\n    private int nProfiledThreadsLimit = 32;\n    private int stackDepthLimit = Integer.MAX_VALUE;\n    private int profilingType = PROFILE_MONITOR;\n\n    // CPU Profiling: Sampled\n    private int samplingInterval = -10; // hybrid\n    private int samplingFrequency = 10; // pure sampling\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    // -- Constructors ---------------------------------------------------------------------------------------------------\n    public ProfilingSettings() {\n    }\n\n    public ProfilingSettings(final String name) {\n        this.settingsName = name;\n    }\n    \n    \n    // -- Static methods ---\n    \n    public static boolean isCPUSettings(ProfilingSettings settings) {\n        if (settings == null) {\n            return false;\n        }\n\n        return isCPUSettings(settings.getProfilingType());\n    }\n\n    public static boolean isCPUSettings(int type) {\n        return (type == ProfilingSettings.PROFILE_CPU_ENTIRE) || (type == ProfilingSettings.PROFILE_CPU_PART)\n               || (type == ProfilingSettings.PROFILE_CPU_STOPWATCH || type == PROFILE_CPU_SAMPLING);\n    }\n    \n    public static boolean isJDBCSettings(ProfilingSettings settings) {\n        if (settings == null) {\n            return false;\n        }\n\n        return isJDBCSettings(settings.getProfilingType());\n    }\n    \n    public static boolean isJDBCSettings(int type) {\n        return type == ProfilingSettings.PROFILE_CPU_JDBC;\n    }\n\n    public static boolean isMemorySettings(ProfilingSettings settings) {\n        if (settings == null) {\n            return false;\n        }\n\n        return isMemorySettings(settings.getProfilingType());\n    }\n\n    public static boolean isMemorySettings(int type) {\n        return (type == PROFILE_MEMORY_ALLOCATIONS) || (type == PROFILE_MEMORY_LIVENESS) || (type == PROFILE_MEMORY_SAMPLING);\n    }\n\n    public static boolean isMonitorSettings(ProfilingSettings settings) {\n        if (settings == null) {\n            return false;\n        }\n\n        return isMonitorSettings(settings.getProfilingType());\n    }\n\n    public static boolean isMonitorSettings(int type) {\n        return type == ProfilingSettings.PROFILE_MONITOR;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setAllocStackTraceLimit(final int allocStackTraceLimit) {\n        this.allocStackTraceLimit = allocStackTraceLimit;\n    }\n\n    public int getAllocStackTraceLimit() {\n        return allocStackTraceLimit;\n    }\n\n    public void setAllocTrackEvery(final int value) {\n        this.allocTrackEvery = value;\n    }\n\n    public int getAllocTrackEvery() {\n        return allocTrackEvery;\n    }\n\n    /** @param cpuProfilingType Type of CPU instrumentation.\n     * @see CommonConstants#CPU_INSTR_FULL\n     * @see CommonConstants#CPU_INSTR_SAMPLED\n     * @see CommonConstants#CPU_SAMPLED\n     */\n    public void setCPUProfilingType(final int cpuProfilingType) {\n        this.cpuProfilingType = cpuProfilingType;\n    }\n\n    // -- General CPU Profiling settings ---------------------------------------------------------------------------------\n\n    /** @return Type of CPU instrumentation\n     * @see CommonConstants#CPU_INSTR_FULL\n     * @see CommonConstants#CPU_INSTR_SAMPLED\n     * @see CommonConstants#CPU_SAMPLED\n     */\n    public int getCPUProfilingType() {\n        return cpuProfilingType;\n    }\n\n    /** @param fragmentSel code fragment to profile, can be null which indicates no code fragment selected */\n    public void setCodeFragmentSelection(final ClientUtils.SourceCodeSelection fragmentSel) {\n        this.fragmentSelection = fragmentSel;\n    }\n\n    /** @return code fragment to profile, can be null which indicates no code fragment selected */\n    public ClientUtils.SourceCodeSelection getCodeFragmentSelection() {\n        return fragmentSelection;\n    }\n\n    /** @param codeRegionCPUResBufSize Buffer size for code region results */\n    public void setCodeRegionCPUResBufSize(final int codeRegionCPUResBufSize) {\n        this.codeRegionCPUResBufSize = codeRegionCPUResBufSize;\n    }\n\n    /** @return Buffer size for code region results */\n    public int getCodeRegionCPUResBufSize() {\n        return codeRegionCPUResBufSize;\n    }\n\n    public void setExcludeWaitTime(boolean value) {\n        excludeWaitTime = value;\n    }\n\n    // -- CPU and Code Fragment Profiling settings -----------------------------------------------------------------------\n    public boolean getExcludeWaitTime() {\n        return excludeWaitTime;\n    }\n\n    public void setInstrScheme(final int instrScheme) {\n        this.instrScheme = instrScheme;\n    }\n\n    public int getInstrScheme() {\n        return instrScheme;\n    }\n\n    public void setInstrumentEmptyMethods(final boolean instrumentEmptyMethods) {\n        this.instrumentEmptyMethods = instrumentEmptyMethods;\n    }\n\n    public boolean getInstrumentEmptyMethods() {\n        return instrumentEmptyMethods;\n    }\n\n    public void setInstrumentGetterSetterMethods(final boolean instrumentGetterSetterMethods) {\n        this.instrumentGetterSetterMethods = instrumentGetterSetterMethods;\n    }\n\n    public boolean getInstrumentGetterSetterMethods() {\n        return instrumentGetterSetterMethods;\n    }\n\n    public void setInstrumentMethodInvoke(final boolean instrumentMethodInvoke) {\n        this.instrumentMethodInvoke = instrumentMethodInvoke;\n    }\n\n    public boolean getInstrumentMethodInvoke() {\n        return instrumentMethodInvoke;\n    }\n\n    public void setInstrumentSpawnedThreads(final boolean instrumentSpawnedThreads) {\n        this.instrumentSpawnedThreads = instrumentSpawnedThreads;\n    }\n\n    public boolean getInstrumentSpawnedThreads() {\n        return instrumentSpawnedThreads;\n    }\n\n    public void setInstrumentationMarkerMethods(final ClientUtils.SourceCodeSelection[] markers) {\n        instrumentationMarkerMethods.clear();\n\n        for (int i = 0; i < markers.length; i++) {\n            ClientUtils.SourceCodeSelection marker = markers[i];\n\n            if (marker.isMarkerMethod()) {\n                instrumentationMarkerMethods.add(marker);\n            }\n        }\n    }\n\n    public ClientUtils.SourceCodeSelection[] getInstrumentationMarkerMethods() {\n        return (ClientUtils.SourceCodeSelection[]) instrumentationMarkerMethods.toArray(new ClientUtils.SourceCodeSelection[0]);\n    }\n\n    public ClientUtils.SourceCodeSelection[] getInstrumentationMethods() {\n        Set methods = new HashSet();\n        // Keep the order:\n        // 1. Root methods; 2. Marker methods\n        methods.addAll(instrumentationRootMethods);\n        methods.addAll(instrumentationMarkerMethods);\n\n        return (ClientUtils.SourceCodeSelection[]) methods.toArray(new ClientUtils.SourceCodeSelection[0]);\n    }\n\n    public void setInstrumentationRootMethods(final ClientUtils.SourceCodeSelection[] roots) {\n        instrumentationRootMethods.clear();\n\n        for (int i = 0; i < roots.length; i++) {\n            ClientUtils.SourceCodeSelection root = roots[i];\n\n            if (!root.isMarkerMethod()) {\n                instrumentationRootMethods.add(root);\n            }\n        }\n    }\n\n    public ClientUtils.SourceCodeSelection[] getInstrumentationRootMethods() {\n        return (ClientUtils.SourceCodeSelection[]) instrumentationRootMethods.toArray(new ClientUtils.SourceCodeSelection[0]);\n    }\n    \n    public void setSamplingFrequency(int samplingFrequency) {\n        this.samplingFrequency = samplingFrequency;\n    }\n    \n    public int getSamplingFrequency() {\n        return samplingFrequency;\n    }\n\n    public void setIsPreset(boolean isPreset) {\n        this.isPreset = isPreset;\n    }\n\n    public void setJVMArgs(final String args) {\n        this.jvmArgs = args;\n    }\n\n    public String getJVMArgs() {\n        return jvmArgs;\n    }\n\n    public void setJavaPlatformName(String value) {\n        platformName = value;\n    }\n\n    public String getJavaPlatformName() {\n        return platformName;\n    }\n\n    public void setNProfiledThreadsLimit(final int nProfiledThreadsLimit) {\n        this.nProfiledThreadsLimit = nProfiledThreadsLimit;\n    }\n\n    public int getNProfiledThreadsLimit() {\n        return nProfiledThreadsLimit;\n    }\n\n    public void setMaxStringLength(int maxLength) {\n        maxStringLength = maxLength;\n    }\n\n    public int getMaxStringLength() {\n        return maxStringLength;\n    }\n\n    public void setStackDepthLimit(int num) {\n        stackDepthLimit = num;\n    }\n\n    public int getStackDepthLimit() {\n        return stackDepthLimit;\n    }\n\n    public void setOverrideGlobalSettings(final boolean override) {\n        overrideGlobalSettings = override;\n    }\n\n    public boolean getOverrideGlobalSettings() {\n        return overrideGlobalSettings;\n    }\n\n    // -- General (global) settings --------------------------------------------------------------------------------------\n    public boolean isPreset() {\n        return isPreset;\n    }\n\n    public void setProfileUnderlyingFramework(final boolean profileUF) {\n        profileUnderlyingFramework = profileUF;\n    }\n\n    public boolean getProfileUnderlyingFramework() {\n        return profileUnderlyingFramework;\n    }\n\n    public void setProfilingType(final int profilingType) {\n        this.profilingType = profilingType;\n    }\n\n    public int getProfilingType() {\n        return profilingType;\n    }\n\n    public void setRunGCOnGetResultsInMemoryProfiling(final boolean runGCOnGetResultsInMemoryProfiling) {\n        this.runGCOnGetResultsInMemoryProfiling = runGCOnGetResultsInMemoryProfiling;\n    }\n\n    // -- Memory profiling settings --------------------------------------------------------------------------------------\n    public boolean getRunGCOnGetResultsInMemoryProfiling() {\n        return runGCOnGetResultsInMemoryProfiling;\n    }\n\n    public void setSamplingInterval(final int samplingInterval) {\n        this.samplingInterval = samplingInterval;\n    }\n\n    public int getSamplingInterval() {\n        return samplingInterval;\n    }\n\n    public void setInstrumentationFilter(final GenericFilter filter) {\n        instrumentationFilter = filter;\n    }\n\n    public GenericFilter getInstrumentationFilter() {\n        return instrumentationFilter;\n    }\n\n    public void setSettingsName(final String name) {\n        this.settingsName = name;\n    }\n\n    // -- Constructors ---------------------------------------------------------------------------------------------------\n    public String getSettingsName() {\n        return settingsName;\n    }\n\n    public void setSortResultsByThreadCPUTime(final boolean sortResultsByThreadCPUTime) {\n        this.sortResultsByThreadCPUTime = sortResultsByThreadCPUTime;\n    }\n\n    public boolean getSortResultsByThreadCPUTime() {\n        return sortResultsByThreadCPUTime;\n    }\n\n    public void setThreadCPUTimerOn(final boolean threadCPUTimerOn) {\n        this.threadCPUTimerOn = threadCPUTimerOn;\n    }\n\n    public boolean getThreadCPUTimerOn() {\n        return threadCPUTimerOn;\n    }\n\n    public void setThreadsMonitoringEnabled(final boolean enabled) {\n        threadsMonitoringEnabled = enabled;\n    }\n\n    public boolean getThreadsMonitoringEnabled() {\n        return threadsMonitoringEnabled;\n    }\n    \n    public void setLockContentionMonitoringEnabled(final boolean enabled) {\n        lockContentionMonitoringEnabled = enabled;\n    }\n\n    public boolean getLockContentionMonitoringEnabled() {\n        return lockContentionMonitoringEnabled;\n    }\n    \n    public void setThreadsSamplingEnabled(final boolean enabled) {\n        threadsSamplingEnabled = enabled;\n    }\n\n    public boolean getThreadsSamplingEnabled() {\n        return threadsSamplingEnabled;\n    }\n\n    public void setUseProfilingPoints(boolean enabled) {\n        useProfilingPoints = enabled;\n    }\n\n    public void setWorkingDir(final String workingDir) {\n        this.workingDir = workingDir;\n    }\n\n    public String getWorkingDir() {\n        return workingDir;\n    }\n\n    public void addRootMethod(final String className, final String methodName, final String signature) {\n        ClientUtils.SourceCodeSelection scs = new ClientUtils.SourceCodeSelection(className, methodName, signature);\n\n        if (!instrumentationRootMethods.contains(scs)) {\n            instrumentationRootMethods.add(scs);\n        }\n    }\n\n    public void addRootMethods(final ClientUtils.SourceCodeSelection[] selections) {\n        for (int i = 0; i < selections.length; i++) {\n            if (!instrumentationRootMethods.contains(selections[i])) {\n                instrumentationRootMethods.add(selections[i]);\n            }\n        }\n    }\n\n    public void applySettings(final ProfilerEngineSettings settings) {\n        if (getOverrideGlobalSettings()) {\n            settings.setWorkingDir(getWorkingDir());\n            settings.setJVMArgs(getJVMArgs());\n\n            if (getJavaPlatformName() != null) {\n                settings.setTargetJVMExeFile(Profiler.getDefault().getPlatformJavaFile(getJavaPlatformName()));\n                settings.setTargetJDKVersionString(Profiler.getDefault().getPlatformJDKVersion(getJavaPlatformName()));\n                settings.setSystemArchitecture(Profiler.getDefault().getPlatformArchitecture(getJavaPlatformName()));\n            }\n        }\n\n        settings.setExcludeWaitTime(getExcludeWaitTime());\n        settings.setCPUProfilingType(getCPUProfilingType());\n        settings.setInstrScheme(getInstrScheme());\n        settings.setAbsoluteTimerOn(true);\n        settings.setThreadCPUTimerOn(getThreadCPUTimerOn());\n        settings.setInstrumentGetterSetterMethods(getInstrumentGetterSetterMethods());\n        settings.setInstrumentEmptyMethods(getInstrumentEmptyMethods());\n        settings.setInstrumentMethodInvoke(getInstrumentMethodInvoke());\n        settings.setInstrumentSpawnedThreads(getInstrumentSpawnedThreads());\n        settings.setThreadsMonitoringEnabled(getThreadsMonitoringEnabled());\n        settings.setLockContentionMonitoringEnabled(getLockContentionMonitoringEnabled());\n        settings.setThreadsSamplingEnabled(getThreadsSamplingEnabled());\n\n        if (getNProfiledThreadsLimit() > 0) {\n            settings.setNProfiledThreadsLimit(getNProfiledThreadsLimit());\n        } else {\n            settings.setNProfiledThreadsLimit(Integer.MAX_VALUE); // zero or negative value means we do not limit it, just remember value for the UI\n        }\n\n        settings.setMaxStringLength(getMaxStringLength());\n        settings.setStackDepthLimit(getStackDepthLimit());\n        settings.setSortResultsByThreadCPUTime(getSortResultsByThreadCPUTime());\n\n        settings.setSamplingInterval(getSamplingInterval());\n        settings.setSamplingFrequency(getSamplingFrequency());\n\n        settings.setCodeRegionCPUResBufSize(getCodeRegionCPUResBufSize());\n\n        settings.setRunGCOnGetResultsInMemoryProfiling(getRunGCOnGetResultsInMemoryProfiling());\n        settings.setAllocTrackEvery(getAllocTrackEvery());\n        settings.setAllocStackTraceLimit(getAllocStackTraceLimit());\n\n        //    Set rootMethods = new HashSet();\n        //    // Keep the order:\n        //    // 1. Root methods; 2. Marker methods\n        //    rootMethods.addAll(Arrays.asList(getInstrumentationRootMethods()));\n        //    rootMethods.addAll(Arrays.asList(getInstrumentationMarkerMethods()));\n        //    for(Iterator iter=rootMethods.iterator();iter.hasNext();) {\n        //      ((ClientUtils.SourceCodeSelection)iter.next()).setMarkerMethod(true);\n        //    }\n        //    settings.setInstrumentationRootMethods((ClientUtils.SourceCodeSelection[])rootMethods.toArray(new ClientUtils.SourceCodeSelection[0]));\n        settings.setInstrumentationRootMethods(getInstrumentationMethods());\n\n        // Now apply the filters to the Engine's instrumentation filter\n        settings.setInstrumentationFilter(instrumentationFilter);\n\n    }\n\n    // -- Settings duplication -------------------------------------------------------------------------------------------\n\n    /**\n     * Copies only profiling settings (not session-related ones) into the given\n     * ProfilingSettings instance\n     *\n     * @param settings the instance to copy the current settings into\n     */\n    public void copySettingsInto(final ProfilingSettings settings) {\n        //    settings.setIsPreset(isPreset()); // Preset flag should not be copied, copy isn't preset\n        settings.setProfilingType(getProfilingType());\n        settings.setOverrideGlobalSettings(getOverrideGlobalSettings());\n        settings.setWorkingDir(getWorkingDir());\n        settings.setJVMArgs(getJVMArgs());\n        settings.setJavaPlatformName(getJavaPlatformName());\n        settings.setThreadsMonitoringEnabled(getThreadsMonitoringEnabled());\n        settings.setLockContentionMonitoringEnabled(getLockContentionMonitoringEnabled());\n        settings.setThreadsSamplingEnabled(getThreadsSamplingEnabled());\n        settings.setUseProfilingPoints(useProfilingPoints());\n\n        settings.setExcludeWaitTime(getExcludeWaitTime());\n        settings.setCPUProfilingType(getCPUProfilingType());\n        settings.setInstrScheme(getInstrScheme());\n        settings.setThreadCPUTimerOn(getThreadCPUTimerOn());\n        settings.setInstrumentGetterSetterMethods(getInstrumentGetterSetterMethods());\n        settings.setInstrumentEmptyMethods(getInstrumentEmptyMethods());\n        settings.setInstrumentMethodInvoke(getInstrumentMethodInvoke());\n        settings.setInstrumentSpawnedThreads(getInstrumentSpawnedThreads());\n        settings.setNProfiledThreadsLimit(getNProfiledThreadsLimit());\n        settings.setMaxStringLength(getMaxStringLength());\n        settings.setStackDepthLimit(getStackDepthLimit());\n        settings.setSortResultsByThreadCPUTime(getSortResultsByThreadCPUTime());\n\n        settings.setSamplingInterval(getSamplingInterval());\n        settings.setSamplingFrequency(getSamplingFrequency());\n        settings.setInstrumentationRootMethods(getInstrumentationRootMethods());\n\n        settings.setCodeFragmentSelection(getCodeFragmentSelection());\n        settings.setCodeRegionCPUResBufSize(getCodeRegionCPUResBufSize());\n\n        settings.setRunGCOnGetResultsInMemoryProfiling(getRunGCOnGetResultsInMemoryProfiling());\n        settings.setAllocTrackEvery(getAllocTrackEvery());\n        settings.setAllocStackTraceLimit(getAllocStackTraceLimit());\n\n        settings.setInstrumentationFilter(getInstrumentationFilter());\n\n        settings.setProfileUnderlyingFramework(getProfileUnderlyingFramework());\n    }\n\n    public String debug() {\n        final StringBuffer sb = new StringBuffer();\n        sb.append(\"isPreset: \").append(isPreset()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"name: \").append(getSettingsName()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"profilingType: \").append(getProfilingType()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"overrideGlobalSettings: \").append(getOverrideGlobalSettings()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"workingDir: \").append(getWorkingDir()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"jvmArgs: \").append(getJVMArgs()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"javaPlatform: \").append((getJavaPlatformName() == null) ? \"<project>\" : getJavaPlatformName()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"threadsMonitoringEnabled: \").append(getThreadsMonitoringEnabled()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"lockContentionMonitoringEnabled: \").append(getLockContentionMonitoringEnabled()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"threadsSamplingEnabled: \").append(getThreadsSamplingEnabled()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"useProfilingPoints: \").append(useProfilingPoints()); // NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"excludeWaitTime: \").append(getExcludeWaitTime()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"cpuProfilingType: \").append(getCPUProfilingType()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"instrScheme: \").append(getInstrScheme()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"threadCPUTimerOn: \").append(getThreadCPUTimerOn()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"instrumentGetterSetterMethods: \").append(getInstrumentGetterSetterMethods()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"instrumentEmptyMethods: \").append(getInstrumentEmptyMethods()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"instrumentMethodInvoke: \").append(getInstrumentMethodInvoke()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"instrumentSpawnedThreads: \").append(getInstrumentSpawnedThreads()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"nProfiledThreadsLimit: \").append(getNProfiledThreadsLimit()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"maxStringLength: \").append(getMaxStringLength()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"stackDepthLimit: \").append(getStackDepthLimit()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"sortResultsByThreadCPUTime: \").append(getSortResultsByThreadCPUTime()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"samplingInterval: \").append(getSamplingInterval()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"samplingFrequency: \").append(getSamplingFrequency()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"instrumentationRootMethods: \").append(instrumentationRootMethods); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"codeFragmentSelection: \").append(getCodeFragmentSelection()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"codeRegionCPUResBufSize: \").append(getCodeRegionCPUResBufSize()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"runGCOnGetResultsInMemoryProfiling: \").append(getRunGCOnGetResultsInMemoryProfiling()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"allocTrackEvery: \").append(getAllocTrackEvery()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"allocStackTraceLimit: \").append(getAllocStackTraceLimit()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"selectedInstrFilter: \").append(getInstrumentationFilter()); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"profileUnderlyingFramework: \").append(getProfileUnderlyingFramework()); //NOI18N\n        sb.append('\\n'); //NOI18N\n\n        return sb.toString();\n    }\n\n    // TODO: just to keep backward compatibility, should be removed after code cleanup!!!\n    public void load(final Map props) {\n        load(props, \"\"); //NOI18N\n    }\n\n    public void load(final Map props, final String prefix) {\n        setIsPreset(Boolean.valueOf(getProperty(props, prefix + PROP_IS_PRESET, \"false\")).booleanValue()); //NOI18N\n        setSettingsName(getProperty(props, prefix + PROP_SETTINGS_NAME, UNKNOWN_PROFILING_SETTINGS_NAME));\n        setProfilingType(Integer.parseInt(getProperty(props, prefix + PROP_PROFILING_TYPE, \"8\"))); //NOI18N\n        setOverrideGlobalSettings(Boolean.valueOf(getProperty(props, prefix + PROP_OVERRIDE_GLOBAL_SETTINGS, \"false\"))\n                                         .booleanValue()); //NOI18N\n        setWorkingDir(getProperty(props, prefix + PROP_WORKING_DIR, \"\")); //NOI18N\n        setJVMArgs(getProperty(props, prefix + PROP_JVM_ARGS, \"\")); //NOI18N\n\n        setJavaPlatformName(getProperty(props, prefix + PROP_JAVA_PLATFORM, null));\n\n        setThreadsMonitoringEnabled(Boolean.valueOf(getProperty(props, prefix + PROP_THREADS_MONITORING_ENABLED, \"false\")) //NOI18N\n                                           .booleanValue());\n        \n        setLockContentionMonitoringEnabled(Boolean.valueOf(getProperty(props, prefix + PROP_LOCKCONTENTION_MONITORING_ENABLED, \"false\")) //NOI18N\n                                           .booleanValue());\n        \n        setThreadsSamplingEnabled(Boolean.valueOf(getProperty(props, prefix + PROP_THREADS_SAMPLING_ENABLED, \"true\")) //NOI18N\n                                           .booleanValue());\n\n        // CPU and Code Fragment common\n        // default for exclude wait time is false, to reflect the setting stored in snapshots before the wait time\n        // exclusion was introduced\n        setExcludeWaitTime(Boolean.valueOf(getProperty(props, prefix + PROP_EXCLUDE_WAIT_TIME, \"false\")).booleanValue());\n\n        // General CPU Profiling settings\n        setCPUProfilingType(Integer.parseInt(getProperty(props, prefix + PROP_CPU_PROFILING_TYPE, \"0\"))); //NOI18N\n        setInstrScheme(Integer.parseInt(getProperty(props, prefix + PROP_INSTR_SCHEME, \"1\"))); //NOI18N\n        setThreadCPUTimerOn(Boolean.valueOf(getProperty(props, prefix + PROP_THREAD_CPU_TIMER_ON, \"false\")).booleanValue()); //NOI18N\n        setInstrumentGetterSetterMethods(Boolean.valueOf(getProperty(props, prefix + PROP_INSTRUMENT_GETTER_SETTER_METHODS,\n                                                                     \"false\")).booleanValue()); //NOI18N\n        setInstrumentEmptyMethods(Boolean.valueOf(getProperty(props, prefix + PROP_INSTRUMENT_EMPTY_METHODS, \"false\"))\n                                         .booleanValue()); //NOI18N\n        setInstrumentMethodInvoke(Boolean.valueOf(getProperty(props, prefix + PROP_INSTRUMENT_METHOD_INVOKE, \"true\"))\n                                         .booleanValue()); //NOI18N\n        setInstrumentSpawnedThreads(Boolean.valueOf(getProperty(props, prefix + PROP_INSTRUMENT_SPAWNED_THREADS, \"false\"))\n                                           .booleanValue()); //NOI18N\n        setNProfiledThreadsLimit(Integer.parseInt(getProperty(props, prefix + PROP_N_PROFILED_THREADS_LIMIT, \"32\"))); //NOI18N\n        setMaxStringLength(Integer.parseInt(getProperty(props, prefix + PROP_MAX_STRING_LENGTH, Integer.toString(CommonConstants.MAX_STRING_LENGTH_DEFAULT))));\n        setStackDepthLimit(Integer.parseInt(getProperty(props, prefix + PROP_STACK_DEPTH_LIMIT, String.valueOf(Integer.MAX_VALUE))));\n        setSortResultsByThreadCPUTime(Boolean.valueOf(getProperty(props, prefix + PROP_SORT_RESULTS_BY_THREAD_CPU_TIME, \"false\"))\n                                             .booleanValue()); //NOI18N\n        setProfileUnderlyingFramework(Boolean.valueOf(getProperty(props, prefix + PROP_PROFILE_UNDERLYING_FRAMEWORK, \"false\"))\n                                             .booleanValue()); //NOI18N\n        setSamplingFrequency(Integer.parseInt(getProperty(props, prefix + PROP_SAMPLING_FREQUENCY, \"10\"))); // NOI18N\n\n        Properties pr = new Properties();\n        pr.putAll(props);\n        try {\n            // Try to load JavaTypeFilter, covers the most typical scenario for saved snapshots\n            setInstrumentationFilter(new JavaTypeFilter(pr, prefix + PROP_INSTR_FILTER));\n        } catch (GenericFilter.InvalidFilterIdException e) {\n            if (\"profiler.simple.filter\".equals(getProperty(props, prefix + \"profiler.settings.instrumentation.filter.selectedprofiler.filter.type\", null))) { // NOI18N\n                // Import previously used SimpleFilter\n                String filterValue = getProperty(props, prefix + \"profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.value\", \"\"); // NOI18N\n                int filterType = Integer.parseInt(getProperty(props, prefix + \"profiler.settings.instrumentation.filter.selectedprofiler.simple.filter.type\", \"0\")); // NOI18N\n                if (filterType == 1 || filterType == 3) setInstrumentationFilter(new JavaTypeFilter(filterValue, JavaTypeFilter.TYPE_EXCLUSIVE));\n                else if (filterType == 2 || filterType == 4) setInstrumentationFilter(new JavaTypeFilter(filterValue, JavaTypeFilter.TYPE_INCLUSIVE));\n                else setInstrumentationFilter(new JavaTypeFilter(filterValue, JavaTypeFilter.TYPE_NONE));\n            } else {\n                // Fallback to GenericFilter if no filter is stored for this instance\n               setInstrumentationFilter(new GenericFilter(\"#fallback#\", \"\", GenericFilter.TYPE_NONE)); // NOI18N\n            }\n        }\n\n        // CPU Profiling: Sampled\n        setSamplingInterval(Integer.parseInt(getProperty(props, prefix + PROP_SAMPLING_INTERVAL, \"10\"))); //NOI18N\n\n        // CPU Profiling: Part of Application\n        final int instrumentationRootMethodsSize = Integer.parseInt(getProperty(props,\n                                                                                prefix + PROP_INSTRUMENTATION_ROOT_METHODS_SIZE,\n                                                                                \"0\")); //NOI18N\n\n        for (int i = 0; i < instrumentationRootMethodsSize; i++) {\n            final ClientUtils.SourceCodeSelection scs = ClientUtils.stringToSelection(getProperty(props,\n                                                                                                  prefix\n                                                                                                  + PROP_INSTRUMENTATION_ROOT_METHODS_PREFIX\n                                                                                                  + i, null));\n\n            if (scs != null) {\n                instrumentationRootMethods.add(scs);\n            }\n        }\n\n        final int instrumentationMarkerMethodsSize = Integer.parseInt(getProperty(props,\n                                                                                  prefix\n                                                                                  + PROP_INSTRUMENTATION_MARKER_METHODS_SIZE, \"0\")); //NOI18N\n\n        for (int i = 0; i < instrumentationMarkerMethodsSize; i++) {\n            final ClientUtils.SourceCodeSelection scs = ClientUtils.stringToSelection(getProperty(props,\n                                                                                                  prefix\n                                                                                                  + PROP_INSTRUMENTATION_MARKER_METHODS_PREFIX\n                                                                                                  + i, null));\n\n            if (scs != null) {\n                scs.setMarkerMethod(true);\n                instrumentationMarkerMethods.add(scs);\n            }\n        }\n\n        // CPU Profiling: Code Fragment\n        setCodeFragmentSelection(ClientUtils.stringToSelection(getProperty(props, prefix + PROP_FRAGMENT_SELECTION, \"\"))); //NOI18N\n        setCodeRegionCPUResBufSize(Integer.parseInt(getProperty(props, prefix + PROP_CODE_REGION_CPU_RES_BUF_SIZE, \"1000\"))); //NOI18N\n\n        // Memory profiling settings\n        setRunGCOnGetResultsInMemoryProfiling(Boolean.valueOf(getProperty(props,\n                                                                          prefix + PROP_RUN_GC_ON_GET_RESULTS_IN_MEMORY_PROFILING,\n                                                                          \"true\")).booleanValue()); //NOI18N\n        setAllocTrackEvery(Integer.parseInt(getProperty(props, prefix + PROP_OBJ_ALLOC_STACK_SAMPLING_INTERVAL, \"10\"))); //NOI18N\n        setAllocStackTraceLimit(Integer.parseInt(getProperty(props, prefix + PROP_OBJ_ALLOC_STACK_SAMPLING_DEPTH, \"-5\"))); //NOI18N\n\n        setUseProfilingPoints(Boolean.valueOf(getProperty(props, prefix + PROP_PROFILING_POINTS_ENABLED, \"false\")).booleanValue()); //NOI18N\n    }\n\n    /** Only used for global storage of UI setting in SelectTaskPanel. TODO [ian]: refactor */\n    public static void saveRootMethods(final ClientUtils.SourceCodeSelection[] roots, final Map props) {\n        props.put(PROP_INSTRUMENTATION_ROOT_METHODS_SIZE, Integer.toString(roots.length));\n\n        for (int i = 0; i < roots.length; i++) {\n            props.put(PROP_INSTRUMENTATION_ROOT_METHODS_PREFIX + i,\n                      ClientUtils.selectionToString((ClientUtils.SourceCodeSelection) roots[i]));\n        }\n    }\n\n    // TODO: just to keep backward compatibility, should be removed after code cleanup!!!\n    public void store(final Map props) {\n        store(props, \"\"); //NOI18N\n    }\n\n    public void store(final Map props, final String prefix) {\n        props.put(prefix + PROP_IS_PRESET, Boolean.toString(isPreset()));\n        props.put(prefix + PROP_SETTINGS_NAME, getSettingsName());\n        props.put(prefix + PROP_PROFILING_TYPE, Integer.toString(getProfilingType()));\n        props.put(prefix + PROP_OVERRIDE_GLOBAL_SETTINGS, Boolean.toString(getOverrideGlobalSettings()));\n        props.put(prefix + PROP_WORKING_DIR, getWorkingDir());\n        props.put(prefix + PROP_JVM_ARGS, getJVMArgs());\n\n        if (getJavaPlatformName() != null) {\n            props.put(prefix + PROP_JAVA_PLATFORM, getJavaPlatformName());\n        }\n\n        props.put(prefix + PROP_THREADS_MONITORING_ENABLED, Boolean.toString(getThreadsMonitoringEnabled()));\n        props.put(prefix + PROP_LOCKCONTENTION_MONITORING_ENABLED, Boolean.toString(getLockContentionMonitoringEnabled()));\n        props.put(prefix + PROP_THREADS_SAMPLING_ENABLED, Boolean.toString(getThreadsSamplingEnabled()));\n\n        // CPU and Code Fragment common\n        props.put(prefix + PROP_EXCLUDE_WAIT_TIME, Boolean.toString(getExcludeWaitTime()));\n\n        // General CPU Profiling settings\n        props.put(prefix + PROP_CPU_PROFILING_TYPE, Integer.toString(getCPUProfilingType()));\n        props.put(prefix + PROP_INSTR_SCHEME, Integer.toString(getInstrScheme()));\n        props.put(prefix + PROP_THREAD_CPU_TIMER_ON, Boolean.toString(getThreadCPUTimerOn()));\n        props.put(prefix + PROP_INSTRUMENT_GETTER_SETTER_METHODS, Boolean.toString(getInstrumentGetterSetterMethods()));\n        props.put(prefix + PROP_INSTRUMENT_EMPTY_METHODS, Boolean.toString(getInstrumentEmptyMethods()));\n        props.put(prefix + PROP_INSTRUMENT_METHOD_INVOKE, Boolean.toString(getInstrumentMethodInvoke()));\n        props.put(prefix + PROP_INSTRUMENT_SPAWNED_THREADS, Boolean.toString(getInstrumentSpawnedThreads()));\n        props.put(prefix + PROP_N_PROFILED_THREADS_LIMIT, Integer.toString(getNProfiledThreadsLimit()));\n        props.put(prefix + PROP_MAX_STRING_LENGTH, Integer.toString(getMaxStringLength()));\n        props.put(prefix + PROP_STACK_DEPTH_LIMIT, Integer.toString(getStackDepthLimit()));\n        props.put(prefix + PROP_SORT_RESULTS_BY_THREAD_CPU_TIME, Boolean.toString(getSortResultsByThreadCPUTime()));\n        props.put(prefix + PROP_SAMPLING_FREQUENCY, Integer.toString(getSamplingFrequency()));\n\n        if (instrumentationFilter != null) {\n            Properties pr = new Properties();\n            instrumentationFilter.store(pr, prefix + PROP_INSTR_FILTER);\n            props.putAll(pr);\n        } else {\n            props.remove(prefix + PROP_INSTR_FILTER);\n        }\n\n        props.put(prefix + PROP_PROFILE_UNDERLYING_FRAMEWORK, Boolean.toString(getProfileUnderlyingFramework()));\n\n        // CPU Profiling: Sampled\n        props.put(prefix + PROP_SAMPLING_INTERVAL, Integer.toString(getSamplingInterval()));\n\n        // CPU Profiling: Part of Application\n        props.put(prefix + PROP_INSTRUMENTATION_ROOT_METHODS_SIZE, Integer.toString(instrumentationRootMethods.size()));\n\n        for (int i = 0; i < instrumentationRootMethods.size(); i++) {\n            props.put(prefix + PROP_INSTRUMENTATION_ROOT_METHODS_PREFIX + i,\n                      ClientUtils.selectionToString((ClientUtils.SourceCodeSelection) instrumentationRootMethods.get(i)));\n        }\n\n        props.put(prefix + PROP_INSTRUMENTATION_MARKER_METHODS_SIZE, Integer.toString(instrumentationMarkerMethods.size()));\n\n        for (int i = 0; i < instrumentationMarkerMethods.size(); i++) {\n            props.put(prefix + PROP_INSTRUMENTATION_MARKER_METHODS_PREFIX + i,\n                      ClientUtils.selectionToString((ClientUtils.SourceCodeSelection) instrumentationMarkerMethods.get(i)));\n        }\n\n        // CPU Profiling: Code Fragment\n        if (getCodeFragmentSelection() != null) {\n            props.put(prefix + PROP_FRAGMENT_SELECTION, ClientUtils.selectionToString(getCodeFragmentSelection()));\n        }\n\n        props.put(prefix + PROP_CODE_REGION_CPU_RES_BUF_SIZE, Integer.toString(getCodeRegionCPUResBufSize()));\n\n        // Memory profiling settings\n        props.put(prefix + PROP_RUN_GC_ON_GET_RESULTS_IN_MEMORY_PROFILING,\n                  Boolean.toString(getRunGCOnGetResultsInMemoryProfiling()));\n        props.put(prefix + PROP_OBJ_ALLOC_STACK_SAMPLING_INTERVAL, Integer.toString(getAllocTrackEvery()));\n        props.put(prefix + PROP_OBJ_ALLOC_STACK_SAMPLING_DEPTH, Integer.toString(getAllocStackTraceLimit()));\n\n        props.put(prefix + PROP_PROFILING_POINTS_ENABLED, Boolean.toString(useProfilingPoints()));\n    }\n\n    // -------------------------------------------------------------------------------------------------------------------\n    // debug & print stuff\n    public String toString() {\n        return getSettingsName();\n    }\n\n    public boolean useProfilingPoints() {\n        return useProfilingPoints;\n    }\n\n    static String getProperty(final Map props, final Object key, final String defaultValue) {\n        final Object ret = props.get(key);\n\n        return (ret != null) ? (String) ret : defaultValue;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/ProfilingSettingsPresets.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.common;\n\nimport java.util.ResourceBundle;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\n\n\n/**\n * Factory class to create preset ProfilingSettings\n *\n * @author Jiri Sedlacek\n */\npublic class ProfilingSettingsPresets {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private static final class CPUPreset extends ProfilingSettings {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        CPUPreset(int type) {\n            setIsPreset(true);\n            setProfilingType(type);\n            setSettingsName(CPU_PRESET_NAME);\n\n            setCPUProfilingType(type == ProfilingSettings.PROFILE_CPU_SAMPLING ?\n                    CommonConstants.CPU_SAMPLED : CommonConstants.CPU_INSTR_FULL);\n            setInstrumentGetterSetterMethods(false);\n            setInstrumentEmptyMethods(false);\n            setInstrumentMethodInvoke(true);\n            setExcludeWaitTime(true);\n\n            if (type == ProfilingSettings.PROFILE_CPU_ENTIRE) {\n                setInstrScheme(CommonConstants.INSTRSCHEME_TOTAL);\n                //        setInstrumentSpawnedThreads(true);\n                setInstrumentSpawnedThreads(false); // Should work better with Marker Methods\n            } else if (type == ProfilingSettings.PROFILE_CPU_PART) {\n                setInstrScheme(CommonConstants.INSTRSCHEME_LAZY);\n                setInstrumentSpawnedThreads(false);\n            } else if (type == ProfilingSettings.PROFILE_CPU_JDBC) {\n                setInstrScheme(CommonConstants.INSTRSCHEME_LAZY);\n                setInstrumentSpawnedThreads(false);\n            } else if (type == ProfilingSettings.PROFILE_CPU_SAMPLING) {\n                setSamplingFrequency(10);\n                setThreadCPUTimerOn(true);\n            }\n        }\n    }\n\n    private static final class MemoryPreset extends ProfilingSettings {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        MemoryPreset(int type) {\n            setIsPreset(true);\n            setProfilingType(type);\n            setSettingsName(MEMORY_PRESET_NAME);\n        }\n    }\n\n    private static final class MonitorPreset extends ProfilingSettings {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        MonitorPreset() {\n            setIsPreset(true);\n            setProfilingType(ProfilingSettings.PROFILE_MONITOR);\n            setSettingsName(MONITOR_PRESET_NAME);\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle bundle = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.common.Bundle\"); // NOI18N\n    private static final String MONITOR_PRESET_NAME = bundle.getString(\"ProfilingSettingsPresets_MonitorPresetName\"); // NOI18N\n    private static final String CPU_PRESET_NAME = bundle.getString(\"ProfilingSettingsPresets_CpuPresetName\"); // NOI18N\n    private static final String MEMORY_PRESET_NAME = bundle.getString(\"ProfilingSettingsPresets_MemoryPresetName\"); // NOI18N\n                                                                                                                    // -----\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static ProfilingSettings createCPUPreset() {\n        return createCPUPreset(ProfilingSettings.PROFILE_CPU_SAMPLING);\n    }\n\n    public static ProfilingSettings createCPUPreset(int type) {\n        return new CPUPreset(type);\n    }\n\n    public static ProfilingSettings createMemoryPreset() {\n        return createMemoryPreset(ProfilingSettings.PROFILE_MEMORY_SAMPLING);\n    }\n\n    public static ProfilingSettings createMemoryPreset(int type) {\n        return new MemoryPreset(type);\n    }\n\n    public static ProfilingSettings createMonitorPreset() {\n        return new MonitorPreset();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/SessionSettings.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.common;\n\nimport java.util.Map;\nimport java.util.ResourceBundle;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\n\n\n/**\n * A Class holding transient data for a single profiling session. Typical usage is creating this class based on context\n * and then call applySettings () on ProfilingEngineSettings. Not used for Attach.\n *\n * The class travels through Ant, and thus can store/load itself to/from Properties.\n *\n * @author Tomas Hurka\n * @author Ian Formanek\n */\npublic final class SessionSettings {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle bundle = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.common.Bundle\"); // NOI18N\n    private static final String INCORRECT_PORT_MSG = bundle.getString(\"SessionSettings_IncorrectPortMsg\"); // NOI18N\n    private static final String INCORRECT_ARCH_MSG = bundle.getString(\"SessionSettings_IncorrectArchMsg\"); // NOI18N\n                                                                                                           // -----\n    public static final String PROP_CLASS_NAME = \"profiler.session.class.name\"; //NOI18N\n    public static final String PROP_CLASS_PATH = \"profiler.session.class.path\"; //NOI18N\n    public static final String PROP_ARGS = \"profiler.session.args\"; //NOI18N\n    public static final String PROP_JVM_ARGS = \"profiler.session.jvm.args\"; //NOI18N\n    public static final String PROP_WORKING_DIR = \"profiler.session.working.dir\"; //NOI18N\n    public static final String PROP_JAVA_EXECUTABLE = \"profiler.session.java.executable\"; //NOI18N\n    public static final String PROP_JAVA_VERSION = \"profiler.session.java.version\"; //NOI18N\n    public static final String PROP_ARCHITECTURE = \"profiler.session.java.architecture\"; //NOI18N\n    public static final String PROP_PORT_NO = \"profiler.session.port.no\"; //NOI18N\n    public static final String PROP_REMOTE_HOST = \"profiler.session.remote.host\"; //NOI18N\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private String javaExecutable = \"\"; //NOI18N\n    private String javaVersionString = \"\"; //NOI18N\n    private String jvmArgs = \"\"; //NOI18N  // Only used for Profile, not for Attach\n    private String mainArgs = \"\"; //NOI18N // Only used for Profile, not for Attach\n    private String mainClass = \"\"; //NOI18N\n    private String mainClassPath = \"\"; //NOI18N\n    private String workingDir = System.getProperty(\"user.dir\"); //NOI18N // Only used for Profile, not for Attach\n    private int architecture = Platform.ARCH_32;\n    private int portNo = 5140;\n    private String remoteHost = \"\"; //NOI18N\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SessionSettings() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setJVMArgs(final String value) {\n        if (value == null) {\n            throw new IllegalArgumentException();\n        }\n\n        jvmArgs = value;\n    }\n\n    public String getJVMArgs() {\n        return jvmArgs;\n    }\n\n    public void setJavaExecutable(String value) {\n        if (value == null) {\n            throw new IllegalArgumentException();\n        }\n\n        javaExecutable = value;\n    }\n\n    public String getJavaExecutable() {\n        return javaExecutable;\n    }\n\n    public void setJavaVersionString(String value) {\n        if (value == null) {\n            throw new IllegalArgumentException();\n        }\n\n        javaVersionString = value;\n    }\n\n    public String getJavaVersionString() {\n        return javaVersionString;\n    }\n\n    public void setMainArgs(final String value) {\n        if (value == null) {\n            throw new IllegalArgumentException();\n        }\n\n        mainArgs = value;\n    }\n\n    public String getMainArgs() {\n        return mainArgs;\n    }\n\n    public void setMainClass(final String value) {\n        if (value == null) {\n            throw new IllegalArgumentException();\n        }\n\n        mainClass = value;\n    }\n\n    // -- Session-related settings ---------------------------------------------------------------------------------------\n    public String getMainClass() {\n        return mainClass;\n    }\n\n    public void setMainClassPath(final String value) {\n        if (value == null) {\n            throw new IllegalArgumentException();\n        }\n\n        mainClassPath = value;\n    }\n\n    public String getMainClassPath() {\n        return mainClassPath;\n    }\n\n    public void setPortNo(int value) {\n        portNo = value;\n    }\n\n    public int getPortNo() {\n        return portNo;\n    }\n    \n    public String getRemoteHost() {\n        return remoteHost;\n    }\n    \n    public void setRemoteHost(String remoteHost) {\n        this.remoteHost = remoteHost;\n    }\n\n    public void setSystemArchitecture(int value) {\n        architecture = value;\n    }\n\n    public int getSystemArchitecture() {\n        return architecture;\n    }\n\n    public void setWorkingDir(final String value) {\n        if (value == null) {\n            throw new IllegalArgumentException();\n        }\n\n        workingDir = value;\n    }\n\n    public String getWorkingDir() {\n        return workingDir;\n    }\n\n    public void applySettings(final ProfilerEngineSettings settings) {\n        settings.setMainClass(mainClass);\n        settings.setMainClassPath(mainClassPath);\n        settings.setMainArgs(mainArgs);\n        settings.setJVMArgs(jvmArgs);\n        settings.setWorkingDir(workingDir);\n        settings.setTargetJVMExeFile(javaExecutable);\n        settings.setTargetJDKVersionString(javaVersionString);\n        settings.setSystemArchitecture(architecture);\n        settings.setPortNo(portNo);\n        settings.setRemoteHost(remoteHost);\n    }\n\n    public String debug() {\n        final StringBuffer sb = new StringBuffer();\n        sb.append(\"mainClass: \").append(mainClass); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"mainClassPath: \").append(mainClassPath); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"mainArgs: \").append(mainArgs); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"jvmArgs =\").append(jvmArgs); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"workingDir =\").append(workingDir); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"javaExecutable =\").append(javaExecutable); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"javaVersionString =\").append(javaVersionString); //NOI18N\n        sb.append('\\n'); //NOI18N\n        sb.append(\"architecture =\").append(architecture);\n        sb.append('\\n');\n        sb.append(\"remoteHost =\").append(remoteHost); //NOI18N\n        sb.append('\\n');\n        sb.append(\"portNo =\").append(portNo); //NOI18N\n        sb.append('\\n');\n\n        return sb.toString();\n    }\n\n    public void load(Map props) throws IllegalArgumentException {\n        setMainClass(getProperty(props, PROP_CLASS_NAME, \"\")); //NOI18N\n        setMainClassPath(getProperty(props, PROP_CLASS_PATH, \"\")); //NOI18N\n        setMainArgs(getProperty(props, PROP_ARGS, \"\")); //NOI18N\n        setJVMArgs(getProperty(props, PROP_JVM_ARGS, \"\")); //NOI18N\n        setWorkingDir(getProperty(props, PROP_WORKING_DIR, System.getProperty(\"user.home\"))); //NOI18N\n        setJavaExecutable(getProperty(props, PROP_JAVA_EXECUTABLE, \"\")); //NOI18N\n        setJavaVersionString(getProperty(props, PROP_JAVA_VERSION, \"\")); //NOI18N\n\n        String arch = getProperty(props, PROP_ARCHITECTURE, String.valueOf(Platform.ARCH_32)); //NOI18N\n\n        try {\n            setSystemArchitecture(Integer.parseInt(arch));\n        } catch (NumberFormatException e) {\n            architecture = 32;\n            throw new IllegalArgumentException(INCORRECT_ARCH_MSG, e);\n        }\n\n        setRemoteHost(getProperty(props, PROP_REMOTE_HOST, \"\"));\n        String port = getProperty(props, PROP_PORT_NO, \"5140\"); //NOI18N\n\n        try {\n            setPortNo(Integer.parseInt(port));\n        } catch (NumberFormatException e) {\n            portNo = 5140;\n            throw new IllegalArgumentException(INCORRECT_PORT_MSG, e);\n        }\n    }\n\n    public void store(Map props) {\n        props.put(PROP_CLASS_NAME, mainClass);\n        props.put(PROP_CLASS_PATH, mainClassPath);\n        props.put(PROP_ARGS, mainArgs);\n        props.put(PROP_JVM_ARGS, jvmArgs);\n        props.put(PROP_WORKING_DIR, workingDir);\n        props.put(PROP_JAVA_EXECUTABLE, javaExecutable);\n        props.put(PROP_JAVA_VERSION, javaVersionString);\n        props.put(PROP_ARCHITECTURE, Integer.toString(architecture));\n        props.put(PROP_REMOTE_HOST, remoteHost);\n        props.put(PROP_PORT_NO, Integer.toString(portNo));\n    }\n\n    private static String getProperty(Map props, String key, String defaultValue) {\n        String ret = (String) props.get(key);\n\n        if (ret == null) {\n            ret = defaultValue;\n        }\n\n        return ret;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/event/ProfilingStateAdapter.java",
    "content": "/*\n * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.common.event;\n\n/** Empty implementation of ProfilingStateListener.\n *\n * @author jan.taus@oracle.com\n */\npublic class ProfilingStateAdapter implements ProfilingStateListener {\n\n    public void instrumentationChanged(int oldInstrType, int currentInstrType) {\n        //ignore\n    }\n\n    public void profilingStateChanged(ProfilingStateEvent e) {\n        //ignore\n    }\n\n    public void threadsMonitoringChanged() {\n        //ignore\n    }\n\n    public void lockContentionMonitoringChanged() {\n        //ignore\n    }\n\n    public void serverStateChanged(int serverState, int serverProgress) {\n        //ignore\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/event/ProfilingStateEvent.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.common.event;\n\nimport org.graalvm.visualvm.lib.common.Profiler;\n\n\n/**\n * An event describing profiling state change.\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic final class ProfilingStateEvent {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final int newState; // new profiling state\n    private final int oldState; // old profiling state\n    private Profiler source; // profiler where the profiling state change originate\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of ProfilingStateEvent */\n    public ProfilingStateEvent(final int oldState, final int newState, final Profiler source) {\n        this.oldState = oldState;\n        this.newState = newState;\n        this.source = source;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getNewState() {\n        return newState;\n    }\n\n    public int getOldState() {\n        return oldState;\n    }\n\n    public Profiler getSource() {\n        return source;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/event/ProfilingStateListener.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.common.event;\n\n\n/**\n * Listener of profiling state changes.\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n * @author Ian Formanek\n */\npublic interface ProfilingStateListener {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    void instrumentationChanged(int oldInstrType, int currentInstrType);\n\n    void profilingStateChanged(ProfilingStateEvent e);\n\n    void threadsMonitoringChanged();\n\n    void lockContentionMonitoringChanged();\n\n    void serverStateChanged(int serverState, int serverProgress);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/event/SimpleProfilingStateAdapter.java",
    "content": "/*\n * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.common.event;\n\n/** Implementation of ProfilingStateListener redirecting all calls to one method.\n *\n * @author jan.taus@oracle.com\n */\npublic abstract class SimpleProfilingStateAdapter implements ProfilingStateListener {\n\n    public void instrumentationChanged(int oldInstrType, int currentInstrType) {\n        update();\n    }\n\n    public void profilingStateChanged(ProfilingStateEvent e) {\n        update();\n    }\n\n    public void threadsMonitoringChanged() {\n        update();\n    }\n\n    public void lockContentionMonitoringChanged() {\n        update();\n    }\n\n    public void serverStateChanged(int serverState, int serverProgress) {\n        update();\n    }\n\n    protected abstract void update();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/integration/Bundle.properties",
    "content": "# Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nIntegrationUtils_PlatformJava50=Java SE 5.0 (Update 4 and higher)\nIntegrationUtils_PlatformJava60=Java SE 6.0\nIntegrationUtils_PlatformJava70=Java SE 7.0\nIntegrationUtils_PlatformJava80=Java SE 8.0\nIntegrationUtils_PlatformJava90=Java SE 9.0\nIntegrationUtils_PlatformJava100=Java SE 10.0\nIntegrationUtils_PlatformJava110=Java SE 11\nIntegrationUtils_PlatformJava120=Java SE 12\nIntegrationUtils_PlatformJava130=Java SE 13\nIntegrationUtils_PlatformJava140=Java SE 14\nIntegrationUtils_PlatformJava150=Java SE 15\nIntegrationUtils_PlatformJava160=Java SE 16\nIntegrationUtils_PlatformJava170=Java SE 17\nIntegrationUtils_PlatformJava180=Java SE 18\nIntegrationUtils_PlatformJava190=Java SE 19\nIntegrationUtils_PlatformJava200=Java SE 20\nIntegrationUtils_PlatformJava210=Java SE 21\nIntegrationUtils_PlatformJava220=Java SE 22\nIntegrationUtils_PlatformJava230=Java SE 23\nIntegrationUtils_PlatformJava240=Java SE 24\nIntegrationUtils_PlatformJava250=Java SE 25\nIntegrationUtils_PlatformJavaCvm=CVM\nIntegrationUtils_PlatformWindowsOs=Windows, 32bit JVM\nIntegrationUtils_PlatformWindowsAmd64Os=Windows, 64bit JVM\nIntegrationUtils_PlatformWindowsCvm=Windows, CVM\nIntegrationUtils_PlatformLinuxOs=Linux (Intel), 32bit JVM\nIntegrationUtils_PlatformLinuxAmd64Os=Linux (Intel/AMD), 64bit JVM\nIntegrationUtils_PlatformLinuxArmOs=Linux (ARM), 32bit JVM\nIntegrationUtils_PlatformLinuxArmVfpHfltOs=Linux (ARM VFP HFLT), 32bit JVM\nIntegrationUtils_PlatformLinuxAarch64Os=Linux (ARM Aarch64), 64bit JVM\nIntegrationUtils_PlatformLinuxCvm=Linux, CVM\nIntegrationUtils_PlatformSolarisIntelOs=Solaris (x86), 32bit JVM\nIntegrationUtils_PlatformSolarisAmd64Os=Solaris (x86), 64bit JVM\nIntegrationUtils_PlatformSolarisSparcOs=Solaris (Sparc), 32bit JVM\nIntegrationUtils_PlatformSolarisSparc64Os=Solaris (Sparc), 64bit JVM\nIntegrationUtils_PlatformMacOs=macOS\n# IntegrationUtils_ModifiedForProfilerString is placed into every file modified by the Profiler\nIntegrationUtils_ModifiedForProfilerString=This file was modified to allow integration with NetBeans Profiler\n# IntegrationUtils_OriginalBackupLocationString is placed into every file modified by the Profiler\nIntegrationUtils_OriginalBackupLocationString=Backup of original version of this file should be located in the same directory with .backup extension\n# Must start by uppercase for languages which support it, will be programatically converted to lowercase for some messages\nIntegrationUtils_ApplicationString=Application\n# Must start by uppercase for languages which support it, will be programatically converted to lowercase for some messages\nIntegrationUtils_AppletString=Applet\n# Must start by uppercase for languages which support it, will be programatically converted to lowercase for some messages\nIntegrationUtils_ServerString=Server\n# Must start by uppercase for languages which support it, will be programatically converted to lowercase for some messages\nIntegrationUtils_DatabaseString=Database\n# Must start by uppercase for languages which support it, will be programatically converted to lowercase for some messages\nIntegrationUtils_TargetString=Target\nIntegrationUtils_Jdk50Name=Java SE 5 (JRE or JDK)\nIntegrationUtils_Jdk60Name=Java SE 6 (JRE or JDK)\nIntegrationUtils_Jdk70Name=Java SE 7 (JRE or JDK)\nIntegrationUtils_Jdk80Name=Java SE 8 (JRE or JDK)\nIntegrationUtils_Jdk90Name=Java SE 9 (JRE or JDK)\nIntegrationUtils_Jdk100Name=Java SE 10 (JRE or JDK)\nIntegrationUtils_Jdk110Name=Java SE 11 (JRE or JDK)\nIntegrationUtils_Jdk120Name=Java SE 12 (JRE or JDK)\nIntegrationUtils_Jdk130Name=Java SE 13 (JRE or JDK)\nIntegrationUtils_Jdk140Name=Java SE 14 (JRE or JDK)\nIntegrationUtils_Jdk150Name=Java SE 15 (JRE or JDK)\nIntegrationUtils_Jdk160Name=Java SE 16 (JRE or JDK)\nIntegrationUtils_Jdk170Name=Java SE 17 (JRE or JDK)\nIntegrationUtils_Jdk180Name=Java SE 18 (JRE or JDK)\nIntegrationUtils_Jdk190Name=Java SE 19 (JRE or JDK)\nIntegrationUtils_Jdk200Name=Java SE 20 (JRE or JDK)\nIntegrationUtils_Jdk210Name=Java SE 21 (JRE or JDK)\nIntegrationUtils_Jdk220Name=Java SE 22 (JRE or JDK)\nIntegrationUtils_Jdk230Name=Java SE 23 (JRE or JDK)\nIntegrationUtils_Jdk240Name=Java SE 24 (JRE or JDK)\nIntegrationUtils_Jdk250Name=Java SE 25 (JRE or JDK)\nIntegrationUtils_JdkCvmName=CVM\nIntegrationUtils_RemoteString=remote\n# HTML-formatted\nIntegrationUtils_ExportSetenvMessage=<p><b>Note\\:</b> Depending on the version shell used, you may need to use \\\"<code>setenv</code>\\\" command instead of \\\"<code>export</code>\\\".</p>\n# HTML-formatted\nIntegrationUtils_ReduceOverheadMessage=<p><b>Hint\\:</b> When profiling CPU, you should set a meaningful instrumentation filter and/or profile only Part of Application to reduce profiling overhead.</p>\nIntegrationUtils_CopyFileNotFoundMessage=IntegrationUtils\\: {0} to be copied not found\nIntegrationUtils_CopyCannotDeleteFileMessage=IntegrationUtils\\: cannot delete {0}\nIntegrationUtils_CopyErrorMessage=IntegrationUtils\\: error copying {0} to {1}\nIntegrationUtils_BackupFileNotFoundMessage=IntegrationUtils\\: {0} to be backed up not found\nIntegrationUtils_BackupCannotDeleteFileMessage=IntegrationUtils\\: cannot delete backup target {0}\nIntegrationUtils_BackupErrorMessage=IntegrationUtils\\: cannot backup {0} to {1}\nIntegrationUtils_BackupErrorCopyFileMessage=IntegrationUtils\\: error during copying {0} to {1}\\n{2}\nIntegrationUtils_RestoreFileNotFoundMessage=IntegrationUtils\\: cannot find {0} to restore {1}\nIntegrationUtils_RestoreCannotDeleteFileMessage=IntegrationUtils\\: cannot delete modified {0}\nIntegrationUtils_RestoreErrorMessage=IntegrationUtils\\: cannot restore {0} to {1}\n# HTML-formatted\nIntegrationUtils_ManualRemoteStep1Message=<p><b>Step 1.</b> Download Profiler Remote pack for {0} - {1} from http://profiler.netbeans.org and install it on the remote machine. The Remote pack root directory will be referred as \\\"<code>{2}</code>\\\".</p>\n# HTML-formatted\nIntegrationUtils_ManualRemoteStep2Message=<p><b>Step 2.</b> If you have not run profiling on this remote machine, run the <code>{0}</code> script first.</p>\n# HTML-formatted\nIntegrationUtils_RemoteAbsolutePathHint=<code>{0}</code> must be an absolute path\n# HTML-formatted\nIntegrationUtils_SpacesInPathWarningMsg=<p><b>Warning:</b> On some systems/configurations problems may occur when starting the Profiler agent using parameters with spaces in path. To fix these problems, please remove the quotes from agent parameters and modify these parameters to use 8.3 (DOS) path format.</p>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.common/src/org/graalvm/visualvm/lib/common/integration/IntegrationUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.common.integration;\n\nimport java.io.*;\nimport java.nio.channels.FileChannel;\nimport java.text.MessageFormat;\nimport java.util.ResourceBundle;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\n\n\n/**\n * Utils for platform- and settings-specific integration instructions.\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic class IntegrationUtils {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.common.integration.Bundle\"); // NOI18N\n    public static final String PLATFORM_JAVA_50 = messages.getString(\"IntegrationUtils_PlatformJava50\"); // NOI18N\n    public static final String PLATFORM_JAVA_60 = messages.getString(\"IntegrationUtils_PlatformJava60\"); // NOI18N\n    public static final String PLATFORM_JAVA_70 = messages.getString(\"IntegrationUtils_PlatformJava70\"); // NOI18N\n    public static final String PLATFORM_JAVA_80 = messages.getString(\"IntegrationUtils_PlatformJava80\"); // NOI18N\n    public static final String PLATFORM_JAVA_90 = messages.getString(\"IntegrationUtils_PlatformJava90\"); // NOI18N\n    public static final String PLATFORM_JAVA_100 = messages.getString(\"IntegrationUtils_PlatformJava100\"); // NOI18N\n    public static final String PLATFORM_JAVA_110 = messages.getString(\"IntegrationUtils_PlatformJava110\"); // NOI18N\n    public static final String PLATFORM_JAVA_120 = messages.getString(\"IntegrationUtils_PlatformJava120\"); // NOI18N\n    public static final String PLATFORM_JAVA_130 = messages.getString(\"IntegrationUtils_PlatformJava130\"); // NOI18N\n    public static final String PLATFORM_JAVA_140 = messages.getString(\"IntegrationUtils_PlatformJava140\"); // NOI18N\n    public static final String PLATFORM_JAVA_150 = messages.getString(\"IntegrationUtils_PlatformJava150\"); // NOI18N\n    public static final String PLATFORM_JAVA_160 = messages.getString(\"IntegrationUtils_PlatformJava160\"); // NOI18N\n    public static final String PLATFORM_JAVA_170 = messages.getString(\"IntegrationUtils_PlatformJava170\"); // NOI18N\n    public static final String PLATFORM_JAVA_180 = messages.getString(\"IntegrationUtils_PlatformJava180\"); // NOI18N\n    public static final String PLATFORM_JAVA_190 = messages.getString(\"IntegrationUtils_PlatformJava190\"); // NOI18N\n    public static final String PLATFORM_JAVA_200 = messages.getString(\"IntegrationUtils_PlatformJava200\"); // NOI18N\n    public static final String PLATFORM_JAVA_210 = messages.getString(\"IntegrationUtils_PlatformJava210\"); // NOI18N\n    public static final String PLATFORM_JAVA_220 = messages.getString(\"IntegrationUtils_PlatformJava220\"); // NOI18N\n    public static final String PLATFORM_JAVA_230 = messages.getString(\"IntegrationUtils_PlatformJava230\"); // NOI18N\n    public static final String PLATFORM_JAVA_240 = messages.getString(\"IntegrationUtils_PlatformJava240\"); // NOI18N\n    public static final String PLATFORM_JAVA_250 = messages.getString(\"IntegrationUtils_PlatformJava250\"); // NOI18N\n    public static final String PLATFORM_JAVA_CVM = messages.getString(\"IntegrationUtils_PlatformJavaCvm\"); // NOI18N\n    public static final String PLATFORM_WINDOWS_OS = messages.getString(\"IntegrationUtils_PlatformWindowsOs\"); // NOI18N\n    public static final String PLATFORM_WINDOWS_AMD64_OS = messages.getString(\"IntegrationUtils_PlatformWindowsAmd64Os\"); // NOI18N\n    public static final String PLATFORM_WINDOWS_CVM = messages.getString(\"IntegrationUtils_PlatformWindowsCvm\"); // NOI18N\n    public static final String PLATFORM_LINUX_OS = messages.getString(\"IntegrationUtils_PlatformLinuxOs\"); // NOI18N\n    public static final String PLATFORM_LINUX_AMD64_OS = messages.getString(\"IntegrationUtils_PlatformLinuxAmd64Os\"); // NOI18N\n    public static final String PLATFORM_LINUX_ARM_OS = messages.getString(\"IntegrationUtils_PlatformLinuxArmOs\"); // NOI18N\n    public static final String PLATFORM_LINUX_ARM_VFP_HFLT_OS = messages.getString(\"IntegrationUtils_PlatformLinuxArmVfpHfltOs\"); // NOI18N\n    public static final String PLATFORM_LINUX_ARM_AARCH64_OS = messages.getString(\"IntegrationUtils_PlatformLinuxAarch64Os\"); // NOI18N\n    public static final String PLATFORM_LINUX_CVM = messages.getString(\"IntegrationUtils_PlatformLinuxCvm\"); // NOI18N\n    public static final String PLATFORM_SOLARIS_INTEL_OS = messages.getString(\"IntegrationUtils_PlatformSolarisIntelOs\"); // NOI18N\n    public static final String PLATFORM_SOLARIS_AMD64_OS = messages.getString(\"IntegrationUtils_PlatformSolarisAmd64Os\"); // NOI18N\n    public static final String PLATFORM_SOLARIS_SPARC_OS = messages.getString(\"IntegrationUtils_PlatformSolarisSparcOs\"); // NOI18N\n    public static final String PLATFORM_SOLARIS_SPARC64_OS = messages.getString(\"IntegrationUtils_PlatformSolarisSparc64Os\"); // NOI18N\n    public static final String PLATFORM_MAC_OS = messages.getString(\"IntegrationUtils_PlatformMacOs\"); // NOI18N\n    public static final String MODIFIED_FOR_PROFILER_STRING = messages.getString(\"IntegrationUtils_ModifiedForProfilerString\"); // NOI18N\n    public static final String ORIGINAL_BACKUP_LOCATION_STRING = messages.getString(\"IntegrationUtils_OriginalBackupLocationString\"); // NOI18N\n    private static final String APPLICATION_STRING = messages.getString(\"IntegrationUtils_ApplicationString\"); // NOI18N\n    private static final String APPLET_STRING = messages.getString(\"IntegrationUtils_AppletString\"); // NOI18N\n    private static final String SERVER_STRING = messages.getString(\"IntegrationUtils_ServerString\"); // NOI18N\n    private static final String DATABASE_STRING = messages.getString(\"IntegrationUtils_DatabaseString\"); // NOI18N\n    private static final String TARGET_STRING = messages.getString(\"IntegrationUtils_TargetString\"); // NOI18N\n    private static final String JDK_50_NAME = messages.getString(\"IntegrationUtils_Jdk50Name\"); // NOI18N\n    private static final String JDK_60_NAME = messages.getString(\"IntegrationUtils_Jdk60Name\"); // NOI18N\n    private static final String JDK_70_NAME = messages.getString(\"IntegrationUtils_Jdk70Name\"); // NOI18N\n    private static final String JDK_80_NAME = messages.getString(\"IntegrationUtils_Jdk80Name\"); // NOI18N\n    private static final String JDK_90_NAME = messages.getString(\"IntegrationUtils_Jdk90Name\"); // NOI18N\n    private static final String JDK_100_NAME = messages.getString(\"IntegrationUtils_Jdk100Name\"); // NOI18N\n    private static final String JDK_110_NAME = messages.getString(\"IntegrationUtils_Jdk110Name\"); // NOI18N\n    private static final String JDK_120_NAME = messages.getString(\"IntegrationUtils_Jdk120Name\"); // NOI18N\n    private static final String JDK_130_NAME = messages.getString(\"IntegrationUtils_Jdk130Name\"); // NOI18N\n    private static final String JDK_140_NAME = messages.getString(\"IntegrationUtils_Jdk140Name\"); // NOI18N\n    private static final String JDK_150_NAME = messages.getString(\"IntegrationUtils_Jdk150Name\"); // NOI18N\n    private static final String JDK_160_NAME = messages.getString(\"IntegrationUtils_Jdk160Name\"); // NOI18N\n    private static final String JDK_170_NAME = messages.getString(\"IntegrationUtils_Jdk170Name\"); // NOI18N\n    private static final String JDK_180_NAME = messages.getString(\"IntegrationUtils_Jdk180Name\"); // NOI18N\n    private static final String JDK_190_NAME = messages.getString(\"IntegrationUtils_Jdk190Name\"); // NOI18N\n    private static final String JDK_200_NAME = messages.getString(\"IntegrationUtils_Jdk200Name\"); // NOI18N\n    private static final String JDK_210_NAME = messages.getString(\"IntegrationUtils_Jdk210Name\"); // NOI18N\n    private static final String JDK_220_NAME = messages.getString(\"IntegrationUtils_Jdk220Name\"); // NOI18N\n    private static final String JDK_230_NAME = messages.getString(\"IntegrationUtils_Jdk230Name\"); // NOI18N\n    private static final String JDK_240_NAME = messages.getString(\"IntegrationUtils_Jdk240Name\"); // NOI18N\n    private static final String JDK_250_NAME = messages.getString(\"IntegrationUtils_Jdk250Name\"); // NOI18N\n    private static final String JDK_CVM_NAME = messages.getString(\"IntegrationUtils_JdkCvmName\"); // NOI18N\n    private static final String HTML_REMOTE_STRING = \"&lt;\" + messages.getString(\"IntegrationUtils_RemoteString\") + \"&gt;\"; // NOI18N\n    private static final String EXPORT_SETENV_MESSAGE = messages.getString(\"IntegrationUtils_ExportSetenvMessage\"); // NOI18N\n    private static final String REDUCE_OVERHEAD_MESSAGE = messages.getString(\"IntegrationUtils_ReduceOverheadMessage\"); // NOI18N\n    private static final String COPY_FILE_NOT_FOUND_MESSAGE = messages.getString(\"IntegrationUtils_CopyFileNotFoundMessage\"); // NOI18N\n    private static final String COPY_CANNOT_DELETE_FILE_MESSAGE = messages.getString(\"IntegrationUtils_CopyCannotDeleteFileMessage\"); // NOI18N\n    private static final String COPY_ERROR_MESSAGE = messages.getString(\"IntegrationUtils_CopyErrorMessage\"); // NOI18N\n    private static final String BACKUP_FILE_NOT_FOUND_MESSAGE = messages.getString(\"IntegrationUtils_BackupFileNotFoundMessage\"); // NOI18N\n    private static final String BACKUP_CANNOT_DELETE_FILE_MESSAGE = messages.getString(\"IntegrationUtils_BackupCannotDeleteFileMessage\"); // NOI18N\n    private static final String BACKUP_ERROR_MESSAGE = messages.getString(\"IntegrationUtils_BackupErrorMessage\"); // NOI18N\n    private static final String BACKUP_ERROR_COPY_FILE_MESSAGE = messages.getString(\"IntegrationUtils_BackupErrorCopyFileMessage\"); // NOI18N\n    private static final String RESTORE_FILE_NOT_FOUND_MESSAGE = messages.getString(\"IntegrationUtils_RestoreFileNotFoundMessage\"); // NOI18N\n    private static final String RESTORE_CANNOT_DELETE_FILE_MESSAGE = messages.getString(\"IntegrationUtils_RestoreCannotDeleteFileMessage\"); // NOI18N\n    private static final String RESTORE_ERROR_MESSAGE = messages.getString(\"IntegrationUtils_RestoreErrorMessage\"); // NOI18N\n    private static final String MANUAL_REMOTE_STEP1_MESSAGE = messages.getString(\"IntegrationUtils_ManualRemoteStep1Message\"); // NOI18N\n    private static final String MANUAL_REMOTE_STEP2_MESSAGE = messages.getString(\"IntegrationUtils_ManualRemoteStep2Message\"); // NOI18N\n    private static final String REMOTE_ABSOLUTE_PATH_HINT = messages.getString(\"IntegrationUtils_RemoteAbsolutePathHint\"); // NOI18N\n    private static final String SPACES_IN_PATH_WARNING_MSG = messages.getString(\"IntegrationUtils_SpacesInPathWarningMsg\"); // NOI18N\n\n    // -----\n    public static final String FILE_BACKUP_EXTENSION = \".backup\"; //NOI18N\n    private static final String BINARIES_TMP_PREFIX = \"NBProfiler\";\n    private static final String BINARIES_TMP_EXT = \".link\";\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    // Returns command for adding profiler native libraries to path\n    public static String getAddProfilerLibrariesToPathString(String targetPlatform, String targetJVM, boolean isRemote,\n                                                             boolean formatAsHTML) {\n        return getExportEnvVariableValueString(targetPlatform, getNativePathEnvVariableString(targetPlatform),\n                                               getNativeLibrariesPath(targetPlatform, targetJVM, isRemote)\n                                               + getClassPathSeparator(targetPlatform)\n                                               + getEnvVariableReference(getNativePathEnvVariableString(targetPlatform),\n                                                                         targetPlatform), formatAsHTML);\n    }\n\n    public static String getAssignEnvVariableValueString(String targetPlatform, String variableName, String variableValue) {\n        variableValue = variableValue.trim();\n        if (isWindowsPlatform(targetPlatform)) {\n            return getExportCommandString(targetPlatform) + \" \" + variableName + \"=\" + variableValue; //NOI18N\n        }\n\n        return variableName + \"=\" + (variableValue.contains(\" \") ? \"\\\"\" + variableValue + \"\\\"\" : variableValue); //NOI18N\n    }\n\n    // Returns batch file extension bat / sh according to current / selected OS\n    public static String getBatchExtensionString(String targetPlatform, String customExt) {\n        if (isWindowsPlatform(targetPlatform)) {\n            return customExt + \".bat\"; //NOI18N\n        }\n        return customExt + \".sh\"; //NOI18N\n    }\n\n    public static String getBatchExtensionString(String targetPlatform) {\n        if (isWindowsPlatform(targetPlatform)) {\n            return \".bat\"; //NOI18N\n        }\n\n        return \".sh\"; //NOI18N\n    }\n\n    // Returns HTML-formatted hint about how to reduce CPU profiling overhead\n    public static String getCPUReduceOverheadHint() {\n        return REDUCE_OVERHEAD_MESSAGE;\n    }\n\n    // Returns \"\\\" or \"/\" according to provided platform\n    public static String getDirectorySeparator(String targetPlatform) {\n        if (isWindowsPlatform(targetPlatform)) {\n            return \"\\\\\"; //NOI18N\n        }\n\n        return \"/\"; //NOI18N\n    }\n\n    // Returns reference to given environment variable according to current / selected OS\n    public static String getEnvVariableReference(String envVariable, String targetPlatform) {\n        if (isWindowsPlatform(targetPlatform)) {\n            return \"%\" + envVariable + \"%\"; //NOI18N\n        }\n\n        return \"$\" + envVariable; //NOI18N\n    }\n\n    // Returns SET / export command  according to current / selected OS\n    public static String getExportCommandString(String targetPlatform) {\n        if (isWindowsPlatform(targetPlatform)) {\n            return \"SET\"; //NOI18N\n        }\n\n        return \"export\"; //NOI18N\n    }\n\n    // Returns expression for exporting environment variable value\n    public static String getExportEnvVariableValueString(String targetPlatform, String variableName, String variableValue,\n                                                         boolean formatAsHTML) {\n        if (isWindowsPlatform(targetPlatform)) {\n            return getAssignEnvVariableValueString(targetPlatform, variableName, variableValue);\n        }\n\n        if (targetPlatform.equals(PLATFORM_LINUX_OS)) {\n            return getExportCommandString(targetPlatform) + \" \"\n                   + getAssignEnvVariableValueString(targetPlatform, variableName, variableValue); //NOI18N\n        }\n\n        return getAssignEnvVariableValueString(targetPlatform, variableName, variableValue)\n               + (formatAsHTML ? \"<br>\" : getLineBreak(targetPlatform)) + getExportCommandString(targetPlatform) + \" \"\n               + variableName; //NOI18N\n    }\n\n    // Returns HTML-formatted note about export vs. setenv on UNIXes\n    public static String getExportVSSetenvNote() {\n        return EXPORT_SETENV_MESSAGE;\n    }\n\n    public static boolean isFileModifiedForProfiler(File file) {\n        try {\n            FileReader fr = new FileReader(file);\n            BufferedReader br = new BufferedReader(fr);\n\n            // check if first line contains Profiler header\n            String line = br.readLine();\n\n            if (line == null) {\n                br.close();\n\n                return false;\n            }\n\n            if (line.contains(MODIFIED_FOR_PROFILER_STRING)) {\n                br.close();\n\n                return true;\n            }\n\n            // check if second line contains Profiler header (first line can contain #!/bin/sh for UNIX scripts or <?xml version...> for xml file)\n            line = br.readLine();\n\n            if (line == null) {\n                br.close();\n\n                return false;\n            }\n\n            if (line.contains(MODIFIED_FOR_PROFILER_STRING)) {\n                br.close();\n\n                return true;\n            }\n\n            br.close();\n\n            return false;\n        } catch (Exception ex) {\n            return false;\n        }\n    }\n\n    // converts CommonConstants.JDK_15_STRING and CommonConstants.JDK_16_STRING to\n    // IntegrationUtils.PLATFORM_JAVA_50 and IntegrationUtils.PLATFORM_JAVA_60.\n    public static String getJavaPlatformFromJavaVersionString(String javaVersionString) {\n        if (javaVersionString.equals(CommonConstants.JDK_15_STRING)) {\n            return PLATFORM_JAVA_50;\n        } else if (javaVersionString.equals(CommonConstants.JDK_16_STRING)) {\n            return PLATFORM_JAVA_60;\n        } else if (javaVersionString.equals(CommonConstants.JDK_17_STRING)) {\n            return PLATFORM_JAVA_70;\n        } else if (javaVersionString.equals(CommonConstants.JDK_18_STRING)) {\n            return PLATFORM_JAVA_80;\n        } else if (javaVersionString.equals(CommonConstants.JDK_19_STRING)) {\n            return PLATFORM_JAVA_90;\n        } else if (javaVersionString.equals(CommonConstants.JDK_100_STRING)) {\n            return PLATFORM_JAVA_100;\n        } else if (javaVersionString.equals(CommonConstants.JDK_110_STRING)) {\n            return PLATFORM_JAVA_110;\n        } else if (javaVersionString.equals(CommonConstants.JDK_120_STRING)) {\n            return PLATFORM_JAVA_120;\n        } else if (javaVersionString.equals(CommonConstants.JDK_130_STRING)) {\n            return PLATFORM_JAVA_130;\n        } else if (javaVersionString.equals(CommonConstants.JDK_140_STRING)) {\n            return PLATFORM_JAVA_140;\n        } else if (javaVersionString.equals(CommonConstants.JDK_150_STRING)) {\n            return PLATFORM_JAVA_150;\n        } else if (javaVersionString.equals(CommonConstants.JDK_160_STRING)) {\n            return PLATFORM_JAVA_160;\n        } else if (javaVersionString.equals(CommonConstants.JDK_170_STRING)) {\n            return PLATFORM_JAVA_170;\n        } else if (javaVersionString.equals(CommonConstants.JDK_180_STRING)) {\n            return PLATFORM_JAVA_180;\n        } else if (javaVersionString.equals(CommonConstants.JDK_190_STRING)) {\n            return PLATFORM_JAVA_190;\n        } else if (javaVersionString.equals(CommonConstants.JDK_200_STRING)) {\n            return PLATFORM_JAVA_200;\n        } else if (javaVersionString.equals(CommonConstants.JDK_210_STRING)) {\n            return PLATFORM_JAVA_210;\n        } else if (javaVersionString.equals(CommonConstants.JDK_220_STRING)) {\n            return PLATFORM_JAVA_220;\n        } else if (javaVersionString.equals(CommonConstants.JDK_230_STRING)) {\n            return PLATFORM_JAVA_230;\n        } else if (javaVersionString.equals(CommonConstants.JDK_240_STRING)) {\n            return PLATFORM_JAVA_240;\n        } else if (javaVersionString.equals(CommonConstants.JDK_250_STRING)) {\n            return PLATFORM_JAVA_250;\n        } else if (javaVersionString.equals(CommonConstants.JDK_CVM_STRING)) {\n            return PLATFORM_JAVA_CVM;\n        }\n        return null;\n    }\n    \n    public static String getPlatformByOSAndArch(int platform, int dataModel, String arch, String archAbi) {\n        switch (dataModel) {\n            case Platform.ARCH_32:\n                if (platform == Platform.OS_LINUX) {\n                    if (arch.startsWith(\"arm\")) {   //NOI18N\n                        if (archAbi != null &&\n                              archAbi.toLowerCase().contains(\"abihf\")) {   //NOI18N\n                            return PLATFORM_LINUX_ARM_VFP_HFLT_OS;\n                        } \n                        return PLATFORM_LINUX_ARM_OS;\n                    } else {\n                        return PLATFORM_LINUX_OS;\n                    }\n                } else if ((Platform.OS_WINDOWS_MASK & platform) != 0) {\n                    return PLATFORM_WINDOWS_OS;\n                } else if (platform == Platform.OS_SOLARIS) {\n                    if (arch.startsWith(\"x86\")) {   //NOI18N\n                        return PLATFORM_SOLARIS_INTEL_OS;\n                    } else {\n                        return PLATFORM_SOLARIS_SPARC_OS;\n                    }\n                } else {\n                    throw new UnsupportedOperationException(); //Mac32, Unknown\n                }\n            case Platform.ARCH_64:\n                if (platform == Platform.OS_LINUX) {\n                    return PLATFORM_LINUX_AMD64_OS;\n                } else if ((Platform.OS_WINDOWS_MASK & platform) != 0) {\n                    return PLATFORM_WINDOWS_AMD64_OS;\n                } else if (platform == Platform.OS_MAC) {\n                    return PLATFORM_MAC_OS;\n                } else if (platform == Platform.OS_SOLARIS) {\n                    if (arch.startsWith(\"x86\")) {   //NOI18N\n                        return PLATFORM_SOLARIS_AMD64_OS;\n                    } else {\n                        return PLATFORM_SOLARIS_SPARC64_OS;\n                    }\n                } else {\n                    throw new UnsupportedOperationException();\n                }\n            default:\n                throw new UnsupportedOperationException();\n        }\n    }\n\n    // Returns friendly java platform name\n    public static String getJavaPlatformName(String javaPlatform) {\n        if (javaPlatform.equals(PLATFORM_JAVA_50)) {\n            return JDK_50_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_60)) {\n            return JDK_60_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_70)) {\n            return JDK_70_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_80)) {\n            return JDK_80_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_90)) {\n            return JDK_90_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_100)) {\n            return JDK_100_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_110)) {\n            return JDK_110_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_120)) {\n            return JDK_120_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_130)) {\n            return JDK_130_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_140)) {\n            return JDK_140_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_150)) {\n            return JDK_150_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_160)) {\n            return JDK_160_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_170)) {\n            return JDK_170_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_180)) {\n            return JDK_180_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_190)) {\n            return JDK_190_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_200)) {\n            return JDK_200_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_210)) {\n            return JDK_210_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_220)) {\n            return JDK_220_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_230)) {\n            return JDK_230_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_240)) {\n            return JDK_240_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_250)) {\n            return JDK_250_NAME;\n        } else if (javaPlatform.equals(PLATFORM_JAVA_CVM)) {\n            return JDK_CVM_NAME;\n        }\n\n        return javaPlatform;\n    }\n\n    // Returns java platform-specific directory: jdk15 / jdk16\n    public static String getJavaPlatformNativeLibrariesDirectoryName(String javaPlatform) {\n        if (javaPlatform.equals(PLATFORM_JAVA_50)) {\n            return \"jdk15\"; //NOI18N\n        } else if (javaPlatform.equals(PLATFORM_JAVA_60)) {\n            return \"jdk16\"; //NOI18N \n        } else if (javaPlatform.equals(PLATFORM_JAVA_70)) {\n            return \"jdk16\"; //NOI18N // for JDK 7.0 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_80)) {\n            return \"jdk16\"; //NOI18N // for JDK 8.0 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_90)) {\n            return \"jdk16\"; //NOI18N // for JDK 9.0 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_100)) {\n            return \"jdk16\"; //NOI18N // for JDK 10 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_110)) {\n            return \"jdk16\"; //NOI18N // for JDK 11 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_120)) {\n            return \"jdk16\"; //NOI18N // for JDK 12 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_130)) {\n            return \"jdk16\"; //NOI18N // for JDK 13 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_140)) {\n            return \"jdk16\"; //NOI18N // for JDK 14 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_150)) {\n            return \"jdk16\"; //NOI18N // for JDK 15 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_160)) {\n            return \"jdk16\"; //NOI18N // for JDK 16 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_170)) {\n            return \"jdk16\"; //NOI18N // for JDK 17 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_180)) {\n            return \"jdk16\"; //NOI18N // for JDK 18 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_190)) {\n            return \"jdk16\"; //NOI18N // for JDK 19 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_200)) {\n            return \"jdk16\"; //NOI18N // for JDK 20 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_210)) {\n            return \"jdk16\"; //NOI18N // for JDK 21 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_220)) {\n            return \"jdk16\"; //NOI18N // for JDK 22 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_230)) {\n            return \"jdk16\"; //NOI18N // for JDK 23 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_240)) {\n            return \"jdk16\"; //NOI18N // for JDK 24 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_250)) {\n            return \"jdk16\"; //NOI18N // for JDK 25 we use the same as for 6.0 for now\n        } else if (javaPlatform.equals(PLATFORM_JAVA_CVM)) {\n            return \"cvm\";  // NOI18N\n        }\n\n        throw new IllegalArgumentException(\"Unsupported platform \" + javaPlatform); // NOI18N\n    }\n\n    // Returns the path to agent native libraries according to current / selected OS\n    public static String getLibsDir(String targetPlatform, boolean isRemote) {\n        if (isRemote) {\n            return getRemoteLibsDir(HTML_REMOTE_STRING, targetPlatform);\n        }\n\n        return Profiler.getDefault().getLibsDir();\n    }\n    \n    private static String getRemoteLibsDir(String prefix, String targetPlatform) {\n        return prefix + getDirectorySeparator(targetPlatform) + \"lib\"; //NOI18N;\n    }\n\n    public static String getLineBreak(String targetPlatform) {\n        if (isWindowsPlatform(targetPlatform)) {\n            return \"\\r\\n\"; //NOI18N\n        }\n\n        return \"\\n\"; //NOI18N\n    }\n\n    // Returns current underlying Java platform\n    public static String getLocalJavaPlatform() {\n        int jdkVersion = Platform.getJDKVersionNumber();\n\n        if (jdkVersion == Platform.JDK_15) {\n            return PLATFORM_JAVA_50;\n        } else if (jdkVersion == Platform.JDK_16) {\n            return PLATFORM_JAVA_60;\n        } else if (jdkVersion == Platform.JDK_17) {\n            return PLATFORM_JAVA_70;\n        } else if (jdkVersion == Platform.JDK_18) {\n            return PLATFORM_JAVA_80;\n        } else if (jdkVersion == Platform.JDK_19) {\n            return PLATFORM_JAVA_90;\n        } else if (jdkVersion == Platform.JDK_100) {\n            return PLATFORM_JAVA_100;\n        } else if (jdkVersion == Platform.JDK_110) {\n            return PLATFORM_JAVA_110;\n        } else if (jdkVersion == Platform.JDK_120) {\n            return PLATFORM_JAVA_120;\n        } else if (jdkVersion == Platform.JDK_130) {\n            return PLATFORM_JAVA_130;\n        } else if (jdkVersion == Platform.JDK_140) {\n            return PLATFORM_JAVA_140;\n        } else if (jdkVersion == Platform.JDK_150) {\n            return PLATFORM_JAVA_150;\n        } else if (jdkVersion == Platform.JDK_160) {\n            return PLATFORM_JAVA_160;\n        } else if (jdkVersion == Platform.JDK_170) {\n            return PLATFORM_JAVA_170;\n        } else if (jdkVersion == Platform.JDK_180) {\n            return PLATFORM_JAVA_180;\n        } else if (jdkVersion == Platform.JDK_190) {\n            return PLATFORM_JAVA_190;\n        } else if (jdkVersion == Platform.JDK_200) {\n            return PLATFORM_JAVA_200;\n        } else if (jdkVersion == Platform.JDK_210) {\n            return PLATFORM_JAVA_210;\n        } else if (jdkVersion == Platform.JDK_220) {\n            return PLATFORM_JAVA_220;\n        } else if (jdkVersion == Platform.JDK_230) {\n            return PLATFORM_JAVA_230;\n        } else if (jdkVersion == Platform.JDK_240) {\n            return PLATFORM_JAVA_240;\n        } else if (jdkVersion == Platform.JDK_250) {\n            return PLATFORM_JAVA_250;\n        }\n\n        return null;\n    }\n\n    // Returns locally running OS platform\n    public static String getLocalPlatform(int architecture) {\n        if (architecture == -1) {\n            architecture = Platform.getSystemArchitecture();\n        }\n\n        if (architecture == Platform.ARCH_32) {\n            if (Platform.isWindows()) {\n                return PLATFORM_WINDOWS_OS;\n            } else if (Platform.isLinux()) {\n                return PLATFORM_LINUX_OS;\n            } else if (Platform.isSolarisIntel()) {\n                return PLATFORM_SOLARIS_INTEL_OS;\n            } else if (Platform.isSolarisSparc()) {\n                return PLATFORM_SOLARIS_SPARC_OS;\n            } else if (Platform.isMac()) {\n                return PLATFORM_MAC_OS;\n            }\n\n            return PLATFORM_SOLARIS_SPARC_OS; // Not supported platform => assume UNIX\n        } else {\n            if (Platform.isWindows()) {\n                return PLATFORM_WINDOWS_AMD64_OS;\n            } else if (Platform.isLinux()) {\n                return PLATFORM_LINUX_AMD64_OS;\n            } else if (Platform.isSolarisIntel()) {\n                return PLATFORM_SOLARIS_AMD64_OS;\n            } else if (Platform.isSolarisSparc()) {\n                return PLATFORM_SOLARIS_SPARC64_OS;\n            } else if (Platform.isMac()) {\n                return PLATFORM_MAC_OS;\n            }\n\n            return PLATFORM_SOLARIS_SPARC64_OS; // Not supported platform => assume UNIX\n        }\n    }\n\n    public static String getManualRemoteStep1(String targetOS, String targetJVM) {\n        return MessageFormat.format(MANUAL_REMOTE_STEP1_MESSAGE, new Object[] { \"JDK 5.0/6.0/7.0/8.0\", targetOS, HTML_REMOTE_STRING }); //NOI18N\n    }\n\n    public static String getManualRemoteStep2(String targetOS, String targetJVM) {\n        return MessageFormat.format(MANUAL_REMOTE_STEP2_MESSAGE, new Object[] { getRemoteCalibrateCommandString(targetOS, targetJVM) }); //NOI18N\n    }\n\n    // Returns getLibsDir()/deployed/jdk<15>/<OS> appropriate for current / selected OS\n    public static String getNativeLibrariesPath(String targetPlatform, String targetJVM, boolean isRemote) {\n        return getLibsDir(targetPlatform, isRemote) + getDirectorySeparator(targetPlatform) + \"deployed\" //NOI18N\n               + getDirectorySeparator(targetPlatform) + getJavaPlatformNativeLibrariesDirectoryName(targetJVM)\n               + getDirectorySeparator(targetPlatform) + getOSPlatformNativeLibrariesDirectoryName(targetPlatform, isRemote);\n    }\n    \n    private static String getRemoteNativeLibrariesPath(String prefix, String targetPlatform, String targetJVM) {\n        return getRemoteLibsDir(prefix, targetPlatform) + getDirectorySeparator(targetPlatform) + \"deployed\" //NOI18N\n                + getDirectorySeparator(targetPlatform) + getJavaPlatformNativeLibrariesDirectoryName(targetJVM)\n                + getDirectorySeparator(targetPlatform) + getOSPlatformNativeLibrariesDirectoryName(targetPlatform, true);\n    }\n\n    // Returns name of the environment variable for system path to Profiler native libraries appropriate for current / selected OS\n    public static String getNativePathEnvVariableString(String targetPlatform) {\n        if (isWindowsPlatform(targetPlatform)) {\n            return \"Path\"; //NOI18N\n        }\n\n        return \"LD_LIBRARY_PATH\"; //NOI18N\n    }\n\n    // returns OS platform- and location-specific directory\n    public static String getOSPlatformNativeLibrariesDirectoryName(String targetPlatform, boolean isRemote) {\n        if (targetPlatform.equals(PLATFORM_WINDOWS_OS)) {\n            return \"windows\"; //NOI18N\n        } else if (targetPlatform.equals(PLATFORM_WINDOWS_AMD64_OS)) {\n            return \"windows-amd64\"; //NOI18N\n        } else if (targetPlatform.equals(PLATFORM_LINUX_OS)) {\n            return \"linux\"; //NOI18N\n        } else if (targetPlatform.equals(PLATFORM_LINUX_AMD64_OS)) {\n            return \"linux-amd64\"; //NOI18N\n        } else if (targetPlatform.equals(PLATFORM_LINUX_ARM_OS)) {\n            return \"linux-arm\"; //NOI18N\n        } else if (targetPlatform.equals(PLATFORM_LINUX_ARM_VFP_HFLT_OS)) {\n            return \"linux-arm-vfp-hflt\"; //NOI18N\n        } else if (targetPlatform.equals(PLATFORM_LINUX_ARM_AARCH64_OS)) {\n            return \"linux-aarch64\"; //NOI18N\n        } else if (targetPlatform.equals(PLATFORM_SOLARIS_INTEL_OS)) {\n            return \"solaris-i386\"; //NOI18N\n        } else if (targetPlatform.equals(PLATFORM_SOLARIS_AMD64_OS)) {\n            return \"solaris-amd64\"; //NOI18N\n        } else if (targetPlatform.equals(PLATFORM_SOLARIS_SPARC_OS)) {\n            return \"solaris-sparc\"; //NOI18N\n        } else if (targetPlatform.equals(PLATFORM_SOLARIS_SPARC64_OS)) {\n            return \"solaris-sparcv9\"; //NOI18N\n        } else if (targetPlatform.equals(PLATFORM_MAC_OS)) {\n            return \"mac\"; //NOI18N\n        }\n\n        return null;\n    }\n\n    /**\n     * The separator used in the classpath construction\n     * @return Returns \";\" or \":\" according to provided platform\n     */ \n    public static String getClassPathSeparator(String targetPlatform) {\n        if (isWindowsPlatform(targetPlatform)) {\n            return \";\"; //NOI18N\n        }\n\n        return \":\"; //NOI18N\n    }\n\n    // Returns extra command line arguments required when attaching on startup\n    public static String getProfilerAgentCommandLineArgs(String targetPlatform, String targetJVM, boolean isRemote, int portNumber) {\n        return getProfilerAgentCommandLineArgs(targetPlatform, targetJVM, isRemote, portNumber, true);\n    }\n    \n    public static String getProfilerAgentCommandLineArgs(String targetPlatform, String targetJVM, boolean isRemote, int portNumber, boolean createTemp) {\n        if ((getNativeLibrariesPath(targetPlatform, targetJVM, isRemote).indexOf(' ') == -1)) {\n            return getProfilerAgentCommandLineArgsWithoutQuotes(targetPlatform, targetJVM, isRemote, portNumber); //NOI18N\n        }\n        if (!isWindowsPlatform(targetPlatform)) { \n            // Profiler is installed in directory with space on Unix (Linux, Solaris, macOS)\n            // create temporary link in /tmp directory and use it instead of directory with space\n            String libsDirPath = getLibsDir(targetPlatform, isRemote);\n            String args = getProfilerAgentCommandLineArgsWithoutQuotes(targetPlatform, targetJVM, isRemote, portNumber);\n            return fixLibsDirPath(libsDirPath, args, createTemp);\n        }\n\n        return \"-agentpath:\" + \"\\\"\" + getNativeLibrariesPath(targetPlatform, targetJVM, isRemote)\n               + getDirectorySeparator(targetPlatform) + getProfilerAgentLibraryFile(targetPlatform) + \"=\" //NOI18N\n               + getLibsDir(targetPlatform, isRemote) + \"\\\"\" + \",\" + portNumber; //NOI18N\n    }\n\n    public static String fixLibsDirPath(final String libsDirPath, final String args) {\n        return fixLibsDirPath(libsDirPath, args, true);\n    }\n    \n    public static String fixLibsDirPath(final String libsDirPath, final String args, boolean createTmp) {\n        if (createTmp) {\n            try {\n                File tmpFile = File.createTempFile(BINARIES_TMP_PREFIX, BINARIES_TMP_EXT);\n                String tmpPath = tmpFile.getAbsolutePath();\n                tmpFile.delete();\n                Runtime.getRuntime().exec(new String[]{\"/bin/ln\",\"-s\",libsDirPath,tmpPath});    // NOI18N\n                new File(tmpPath).deleteOnExit();\n                return args.replace(libsDirPath,tmpPath);\n            } catch (IOException ex) {\n                throw new RuntimeException(ex);\n            }\n        } else {\n            return args.replaceAll(\"agentpath:(.*?)=(.*?),(.*)\", \"agentpath:\\\"$1\\\"=\\\"$2\\\",$3\");\n        }\n    }\n\n    // Returns extra command line arguments without additional quotes required when attaching on startup\n    public static String getRemoteProfilerAgentCommandLineArgsWithoutQuotes(\n            String prefix, String targetPlatform, String targetJVM, int portNumber) {\n        final StringBuilder args = new StringBuilder();\n        if ((targetJVM.equals(PLATFORM_JAVA_60) || targetJVM.equals(PLATFORM_JAVA_70) || targetJVM.equals(PLATFORM_JAVA_80) || targetJVM.equals(PLATFORM_JAVA_90)) &&\n                isLinuxPlatform(targetPlatform)) {\n            args.append(\" -XX:+UseLinuxPosixThreadCPUClocks \"); // NOI18N\n        }\n        args.append(\"-agentpath:\").append(getRemoteNativeLibrariesPath(prefix, targetPlatform, targetJVM)). // NOI18N\n                append(getDirectorySeparator(targetPlatform)).append(getProfilerAgentLibraryFile(targetPlatform)).append(\"=\"). //NOI18N\n                append(getRemoteLibsDir(prefix,targetPlatform)).append(\",\").append(portNumber); //NOI18N\n        return args.toString();\n    }\n    \n    public static String getProfilerAgentCommandLineArgsWithoutQuotes(String targetPlatform, String targetJVM, boolean isRemote,\n                                                                      int portNumber) {\n        StringBuilder args = new StringBuilder();\n        \n        if ((targetJVM.equals(PLATFORM_JAVA_60) || targetJVM.equals(PLATFORM_JAVA_70) || targetJVM.equals(PLATFORM_JAVA_80) || targetJVM.equals(PLATFORM_JAVA_90)) && \n            isLinuxPlatform(targetPlatform)) {\n            args.append(\" -XX:+UseLinuxPosixThreadCPUClocks \"); // NOI18N\n        }\n        args.append(\"-agentpath:\").append(getNativeLibrariesPath(targetPlatform, targetJVM, isRemote)). // NOI18N\n               append(getDirectorySeparator(targetPlatform)).append(getProfilerAgentLibraryFile(targetPlatform)).append(\"=\"). //NOI18N\n               append(getLibsDir(targetPlatform, isRemote)).append(\",\").append(portNumber); //NOI18N\n        return args.toString();\n    }\n    \n    public static String getProfilerAgentCommandLineArgsWithoutQuotes(String targetPlatform, String targetJVM, boolean isRemote,\n                                                                      int portNumber, String pathSpaceChar) {\n        StringBuilder args = new StringBuilder();\n        \n        if ((targetJVM.equals(PLATFORM_JAVA_60) || targetJVM.equals(PLATFORM_JAVA_70) || targetJVM.equals(PLATFORM_JAVA_80) || targetJVM.equals(PLATFORM_JAVA_90)) && \n            isLinuxPlatform(targetPlatform)) {\n            args.append(\" -XX:+UseLinuxPosixThreadCPUClocks \"); // NOI18N\n        }\n        String natLibs = getNativeLibrariesPath(targetPlatform, targetJVM, isRemote).replace(\" \", pathSpaceChar != null ? pathSpaceChar : \" \");\n        String libsDir = getLibsDir(targetPlatform, isRemote).replace(\" \", pathSpaceChar != null ? pathSpaceChar : \" \");\n        String agentFile = getProfilerAgentLibraryFile(targetPlatform).replace(\" \", pathSpaceChar != null ? pathSpaceChar : \" \");\n        args.append(\"-agentpath:\").append(natLibs). // NOI18N\n               append(getDirectorySeparator(targetPlatform)).append(agentFile).append(\"=\"). //NOI18N\n               append(libsDir).append(\",\").append(portNumber); //NOI18N\n        return args.toString();\n    }\n\n    // Returns filename of profiler agent library\n    public static String getProfilerAgentLibraryFile(String targetPlatform) {\n        if (isWindowsPlatform(targetPlatform)) {\n            return \"profilerinterface.dll\"; //NOI18N\n        } else if (targetPlatform.equals(PLATFORM_MAC_OS)) {\n            return \"libprofilerinterface.jnilib\"; //NOI18N\n        } else {\n            return \"libprofilerinterface.so\"; //NOI18N\n        }\n    }\n\n    public static String getProfilerModifiedFileHeader(String targetPlatform) {\n        return getSilentScriptCommentSign(targetPlatform) + \" \" + MODIFIED_FOR_PROFILER_STRING + getLineBreak(targetPlatform); //NOI18N\n    }\n\n    public static String getProfilerModifiedReplaceFileHeader(String targetPlatform) {\n        return getProfilerModifiedFileHeader(targetPlatform) + getSilentScriptCommentSign(targetPlatform) + \" \" // NOI18N\n               + ORIGINAL_BACKUP_LOCATION_STRING + getLineBreak(targetPlatform); //NOI18N\n    }\n\n    public static String getRemoteAbsolutePathHint() {\n        return MessageFormat.format(REMOTE_ABSOLUTE_PATH_HINT, new Object[] { HTML_REMOTE_STRING });\n    }\n\n    // Returns calibration batch filename\n    public static String getRemoteCalibrateCommandString(String targetPlatform, String targetJava) {\n        String customExt = isLinuxPlatform(targetPlatform) ? (PLATFORM_JAVA_60.equals(targetJava) ? \"-16\" : \"-15\") : \"\"; // NOI18N\n        return HTML_REMOTE_STRING + getDirectorySeparator(targetPlatform) + \"bin\" + getDirectorySeparator(targetPlatform) // NOI18N\n               + \"calibrate\" + getBatchExtensionString(targetPlatform,  customExt); //NOI18N\n    }\n\n    // Returns profile batch filename\n    public static String getRemoteProfileCommandString(String targetPlatform, String targetJava) {\n        String customExt = PLATFORM_JAVA_50.equals(targetJava) ? \"-15\" : \"-16\"; // NOI18N\n        return HTML_REMOTE_STRING + getDirectorySeparator(targetPlatform) + \"bin\" + getDirectorySeparator(targetPlatform) // NOI18N\n               + \"profile\" + getBatchExtensionString(targetPlatform, customExt); //NOI18N\n    }\n\n    // returns \"rem\" or \"#\" according to provided platform\n    public static String getScriptCommentSign(String targetPlatform) {\n        if (isWindowsPlatform(targetPlatform)) {\n            return \"rem\"; //NOI18N\n        }\n\n        return \"#\"; //NOI18N\n    }\n\n    // returns \"@rem\" or \"#\" according to provided platform\n    public static String getSilentScriptCommentSign(String targetPlatform) {\n        if (isWindowsPlatform(targetPlatform)) {\n            return \"@rem\"; //NOI18N\n        }\n\n        return \"#\"; //NOI18N\n    }\n\n    public static String getSpacesInPathWarning() {\n        return SPACES_IN_PATH_WARNING_MSG;\n    }\n\n    public static boolean isWindowsPlatform(String targetPlatform) {\n        return targetPlatform.equals(PLATFORM_WINDOWS_OS) || targetPlatform.equals(PLATFORM_WINDOWS_AMD64_OS) || targetPlatform.equals(PLATFORM_WINDOWS_CVM);\n    }\n    \n    public static boolean isSolarisPlatform(String targetPlatform) {\n        return targetPlatform.equals(PLATFORM_SOLARIS_AMD64_OS) || targetPlatform.equals(PLATFORM_SOLARIS_INTEL_OS) \n                || targetPlatform.equals(PLATFORM_SOLARIS_SPARC64_OS) || targetPlatform.equals(PLATFORM_SOLARIS_SPARC_OS);\n    }\n    \n    public static boolean isMacPlatform(String targetPlatform) {\n        return targetPlatform.equals(PLATFORM_MAC_OS); \n    }\n\n    public static boolean isLinuxPlatform(String targetPlatform) {\n        return targetPlatform.equals(PLATFORM_LINUX_OS) || targetPlatform.equals(PLATFORM_LINUX_AMD64_OS)\n            || targetPlatform.equals(PLATFORM_LINUX_ARM_OS) || targetPlatform.equals(PLATFORM_LINUX_ARM_VFP_HFLT_OS)\n            || targetPlatform.equals(PLATFORM_LINUX_ARM_AARCH64_OS) || targetPlatform.equals(PLATFORM_LINUX_CVM);\n    }\n\n    public static String getXMLCommendEndSign() {\n        return \"-->\"; //NOI18N\n    }\n\n    public static String getXMLCommentStartSign() {\n        return \"<!--\"; //NOI18N\n    }\n\n    public static boolean backupFile(File file) {\n        File source = new File(file.getAbsolutePath());\n        File target = new File(source.getAbsolutePath() + FILE_BACKUP_EXTENSION);\n\n        if (!source.exists()) {\n            ProfilerLogger.severe(MessageFormat.format(BACKUP_FILE_NOT_FOUND_MESSAGE, new Object[] { source.getAbsolutePath() })); //NOI18N\n\n            return false;\n        }\n\n        if (target.exists()) {\n            if (!target.delete()) {\n                ProfilerLogger.severe(MessageFormat.format(BACKUP_CANNOT_DELETE_FILE_MESSAGE,\n                                                           new Object[] { target.getAbsolutePath() })); //NOI18N\n\n                return false;\n            }\n        }\n\n        // move source to target to correctly preserve file permissions\n        if (!source.renameTo(target)) {\n            ProfilerLogger.severe(MessageFormat.format(BACKUP_ERROR_MESSAGE,\n                                                       new Object[] { source.getAbsolutePath(), target.getAbsolutePath() })); //NOI18N\n\n            return false;\n        }\n\n        // re-create source file for further processing\n        try {\n            source = new File(file.getAbsolutePath());\n            source.createNewFile();\n            target = new File(source.getAbsolutePath() + FILE_BACKUP_EXTENSION);\n\n            FileChannel sourceChannel = new FileOutputStream(source).getChannel();\n            try {\n                FileChannel targetChannel = new FileInputStream(target).getChannel();\n                try {\n                    targetChannel.transferTo(0, targetChannel.size(), sourceChannel);\n                    return true;\n                } finally {\n                    targetChannel.close();\n                }\n            } finally {\n                sourceChannel.close();\n            }\n        } catch (Exception ex) {\n            ProfilerLogger.severe(MessageFormat.format(BACKUP_ERROR_COPY_FILE_MESSAGE,\n                                                       new Object[] { target.getAbsolutePath(), source.getAbsolutePath(), ex })); //NOI18N\n\n            return false;\n        }\n    }\n\n    public static boolean copyFile(File sourceFile, File targetFile) {\n        if (!sourceFile.exists()) {\n            ProfilerLogger.severe(MessageFormat.format(COPY_FILE_NOT_FOUND_MESSAGE, new Object[] { sourceFile.getAbsolutePath() })); //NOI18N\n\n            return false;\n        }\n\n        if (targetFile.exists()) {\n            if (!targetFile.delete()) {\n                ProfilerLogger.severe(MessageFormat.format(COPY_CANNOT_DELETE_FILE_MESSAGE,\n                                                           new Object[] { targetFile.getAbsolutePath() })); //NOI18N\n\n                return false;\n            }\n        }\n\n        try {\n            FileChannel sourceChannel = new FileInputStream(sourceFile).getChannel();\n            try {\n                FileChannel destinationChannel = new FileOutputStream(targetFile).getChannel();\n                try {\n                    sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);\n                    return true;\n                } finally {\n                    destinationChannel.close();\n                }\n            } finally {\n                sourceChannel.close();                \n            }\n        } catch (Exception ex) {\n            ProfilerLogger.log(ex);\n            ProfilerLogger.severe(MessageFormat.format(COPY_ERROR_MESSAGE,\n                                                       new Object[] { sourceFile.getAbsolutePath(), targetFile.getAbsolutePath() })); //NOI18N\n\n            return false;\n        }\n    }\n\n    public static boolean fileBackupExists(File file) {\n        File target = new File(file.getAbsolutePath()); // file to be restored\n        File source = new File(target.getAbsolutePath() + FILE_BACKUP_EXTENSION); // backup image of this file (file.backup)\n\n        return source.exists();\n    }\n\n    public static boolean restoreFile(File file) {\n        File target = file;\n        File source = new File(target.getAbsolutePath() + FILE_BACKUP_EXTENSION);\n\n        if (!source.exists()) {\n            ProfilerLogger.severe(MessageFormat.format(RESTORE_FILE_NOT_FOUND_MESSAGE,\n                                                       new Object[] { source.getAbsolutePath(), target.getAbsolutePath() })); //NOI18N\n\n            return false;\n        }\n\n        if (target.exists()) {\n            if (!target.delete()) {\n                ProfilerLogger.severe(MessageFormat.format(RESTORE_CANNOT_DELETE_FILE_MESSAGE,\n                                                           new Object[] { target.getAbsolutePath() })); //NOI18N\n\n                return false;\n            }\n        }\n\n        if (!source.renameTo(target)) {\n            ProfilerLogger.severe(MessageFormat.format(RESTORE_ERROR_MESSAGE,\n                                                       new Object[] { source.getAbsolutePath(), target.getAbsolutePath() })); //NOI18N\n\n            return false;\n        }\n\n        return true;\n    }\n    \n    public static String getTemporaryBinariesLink(String agentCmds) {\n        Pattern p = Pattern.compile(\"(/.*?\" + BINARIES_TMP_PREFIX + \".*?\" + BINARIES_TMP_EXT + \")\");\n        Matcher m = p.matcher(agentCmds);\n        \n        if (m.find()) {\n            return m.group(1);\n        }\n        \n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project basedir=\".\" default=\"netbeans\" name=\"lib.profiler.heap\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.lib.jfluid.heap</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.lib.jfluid.heap\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/lib/jfluid/heap/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.3\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.lib.jfluid.heap-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/nbproject/genfiles.properties",
    "content": "# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=d0716bc0\nnbproject/build-impl.xml.script.CRC32=9dc5437f\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/nbproject/project.properties",
    "content": "# Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nis.autoload=true\njavac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.lib.jfluid.heap</code-name-base>\n            <suite-component/>\n            <module-dependencies/>\n            <test-dependencies>\n                <test-type>\n                    <name>unit</name>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.libs.junit4</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                </test-type>\n            </test-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.heapviewer</friend>\n                <friend>org.graalvm.visualvm.heapviewer.console</friend>\n                <friend>org.graalvm.visualvm.heapviewer.truffle</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.heapwalker</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.oql</friend>\n                <package>org.graalvm.visualvm.lib.jfluid.heap</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/../..\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/AbstractLongMap.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\nimport java.nio.MappedByteBuffer;\nimport java.nio.channels.FileChannel;\nimport static java.nio.channels.FileChannel.MapMode.*;\n\n/**\n * @author Tomas Hurka\n */\nabstract class AbstractLongMap {\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    abstract class Entry {\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final int VALUE_SIZE;\n    final int ENTRY_SIZE;\n    long fileSize;\n    private long keys;\n    final int KEY_SIZE;\n    final int ID_SIZE;\n    final int FOFFSET_SIZE;\n    Data dumpBuffer;\n    CacheDirectory cacheDirectory;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    AbstractLongMap(int size,int idSize,int foffsetSize,int valueSize,CacheDirectory cacheDir) throws FileNotFoundException, IOException {\n        assert idSize == 4 || idSize == 8;\n        assert foffsetSize == 4 || foffsetSize == 8;\n        keys = (size * 4L) / 3L;\n        ID_SIZE = idSize;\n        FOFFSET_SIZE = foffsetSize;\n        KEY_SIZE = ID_SIZE;\n        VALUE_SIZE = valueSize;\n        ENTRY_SIZE = KEY_SIZE + VALUE_SIZE;\n        fileSize = keys * ENTRY_SIZE;\n        cacheDirectory = cacheDir;\n        dumpBuffer = cacheDir.createDumpBuffer(fileSize, ENTRY_SIZE);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    protected void finalize() throws Throwable {\n        if (cacheDirectory.isTemporary()) {\n            dumpBuffer.deleteFile();\n        }\n        super.finalize();\n    }\n\n    Entry get(long key) {\n        long index = getIndex(key);\n\n        while (true) {\n            long mapKey = getID(index, 0);\n\n            if (mapKey == key) {\n                return createEntry(index);\n            }\n\n            if (mapKey == 0L) {\n                return null;\n            }\n\n            index = getNextIndex(index);\n        }\n    }\n\n    Entry put(long key, long value) {\n        long index = getIndex(key);\n\n        while (true) {\n            long mapKey = getID(index, 0);\n            if (mapKey == 0L) {\n                putID(index, 0, key);\n                return createEntry(index,value);\n            } else if (mapKey == key) {\n                return createEntry(index);\n            }\n\n            index = getNextIndex(index);\n        }\n    }\n\n    static Data getDumpBuffer(File f, RandomAccessFile file, int entrySize) throws IOException {\n        long length = file.length();\n\n        try {\n            if (length > Integer.MAX_VALUE) {\n                return new LongMemoryMappedData(f, file, length, entrySize);\n            } else {\n                return new MemoryMappedData(f, file, length);\n            }\n        } catch (IOException ex) {\n            if (ex.getCause() instanceof OutOfMemoryError) {\n                return new FileData(f, file, length, entrySize);\n            } else {\n                throw ex;\n            }\n        }\n    }\n\n    long getID(long base, int offset) {\n        if (ID_SIZE == 4) {\n            return ((long)dumpBuffer.getInt(base, offset)) & 0xFFFFFFFFL;\n        }\n        return dumpBuffer.getLong(base, offset);\n    }\n    \n    void putID(long base, int offset,long key) {\n        if (ID_SIZE == 4) {\n            dumpBuffer.putInt(base, offset,(int)key);\n        } else {\n            dumpBuffer.putLong(base, offset, key);\n        }\n    }\n    \n    long getFoffset(long base, int offset) {\n        if (FOFFSET_SIZE == 4) {\n            return dumpBuffer.getInt(base, offset);\n        }\n        return dumpBuffer.getLong(base, offset);\n    }\n    \n    void putFoffset(long base, int offset,long key) {\n        if (FOFFSET_SIZE == 4) {\n            dumpBuffer.putInt(base, offset, (int)key);\n        } else {\n            dumpBuffer.putLong(base, offset, key);\n        }\n    }\n\n    //---- Serialization support\n    void writeToStream(DataOutputStream out) throws IOException {\n        out.writeLong(keys);\n        out.writeInt(ID_SIZE);\n        out.writeInt(FOFFSET_SIZE);\n        out.writeInt(VALUE_SIZE);\n        dumpBuffer.writeToStream(out);\n    }\n\n    AbstractLongMap(DataInputStream dis, CacheDirectory cacheDir) throws IOException {\n        keys = dis.readLong();\n        ID_SIZE = dis.readInt();\n        FOFFSET_SIZE = dis.readInt();\n        VALUE_SIZE = dis.readInt();\n        \n        KEY_SIZE = ID_SIZE;\n        ENTRY_SIZE = KEY_SIZE + VALUE_SIZE;\n        fileSize = keys * ENTRY_SIZE;\n        dumpBuffer = Data.readFromStream(dis, cacheDir, ENTRY_SIZE);\n        cacheDirectory = cacheDir;\n    }\n    \n    private long getIndex(long key) {\n        long hash = key & 0x7FFFFFFFFFFFFFFFL;\n        return (hash % keys) * ENTRY_SIZE;\n    }\n\n    private long getNextIndex(long index) {\n        index += ENTRY_SIZE;\n        if (index >= fileSize) {\n            index = 0;\n        }\n        return index;\n    }\n    \n    private static boolean isLinux() {\n        String osName = System.getProperty(\"os.name\");  // NOI18N\n        \n        return osName.endsWith(\"Linux\"); // NOI18N\n    }\n\n    private static boolean isMacOS() {\n        String osName = System.getProperty(\"os.name\");  // NOI18N\n\n        return \"Mac OS X\".equals(osName); // NOI18N\n    }\n\n    private static boolean isAarch64() {\n        String osArch = System.getProperty(\"os.arch\");  // NOI18N\n\n        return \"aarch64\".equals(osArch); // NOI18N\n    }\n\n    abstract Entry createEntry(long index);\n    \n    abstract Entry createEntry(long index,long value);\n    \n    interface Data {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n        static Data readFromStream(DataInputStream dis, CacheDirectory cacheDir, int entrySize) throws IOException {\n            File tempFile = cacheDir.getCacheFile(dis.readUTF());\n            try (RandomAccessFile file = new RandomAccessFile(tempFile, \"rw\")) {  // NOI18N\n                return getDumpBuffer(tempFile, file, entrySize);\n            }\n        }\n        \n        byte getByte(long base, int offset);\n        \n        int getInt(long base, int offset);\n\n        long getLong(long base, int offset);\n\n        void putByte(long base, int offset, byte data);\n\n        void putInt(long base, int offset, int data);\n\n        void putLong(long base, int offset, long data);\n\n        void force() throws IOException;\n\n        void writeToStream(DataOutputStream out) throws IOException;\n\n        void deleteFile();\n    }\n\n    private static abstract class AbstractData implements Data {\n\n        File bufferFile;\n\n        private AbstractData(File file) {\n            bufferFile = file;\n        }\n\n        //---- Serialization support\n        public void writeToStream(DataOutputStream out) throws IOException {\n            out.writeUTF(bufferFile.getAbsolutePath());\n            force();\n        }\n\n        public void deleteFile() {\n            bufferFile.delete();\n        }\n\n    }\n\n    private static class FileData extends AbstractData {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        RandomAccessFile file;\n        byte[] buf;\n        boolean bufferModified;\n        long offset;\n        int entrySize;\n        long fileSize;\n        final static int BUFFER_SIZE = 128;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        FileData(File fl, RandomAccessFile f, long length, int entry) throws IOException {\n            super(fl);\n            file = f;\n            fileSize = length;\n            entrySize = entry;\n            buf = new byte[entrySize*BUFFER_SIZE];\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public synchronized byte getByte(long base, int offset) {\n            int i = loadBufferIfNeeded(base+offset);\n            return buf[i];\n        }\n\n        public synchronized int getInt(long base, int offset) {\n            int i = loadBufferIfNeeded(base+offset);\n            int ch1 = ((int) buf[i++]) & 0xFF;\n            int ch2 = ((int) buf[i++]) & 0xFF;\n            int ch3 = ((int) buf[i++]) & 0xFF;\n            int ch4 = ((int) buf[i]) & 0xFF;\n\n            return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));\n        }\n\n        public synchronized long getLong(long base, int offset) {\n           int i = loadBufferIfNeeded(base+offset);\n           return (((long)buf[i++] << 56) +\n                  ((long)(buf[i++] & 255) << 48) +\n                  ((long)(buf[i++] & 255) << 40) +\n                  ((long)(buf[i++] & 255) << 32) +\n                  ((long)(buf[i++] & 255) << 24) +\n                  ((buf[i++] & 255) << 16) +\n                  ((buf[i++] & 255) <<  8) +\n                  ((buf[i++] & 255) <<  0));\n        }\n\n        public synchronized void putByte(long base, int offset, byte data) {\n            int i = loadBufferIfNeeded(base+offset);\n            buf[i] = data;\n            bufferModified = true;\n        }\n\n        public synchronized void putInt(long base, int offset, int data) {\n            int i = loadBufferIfNeeded(base+offset);\n            buf[i++] = (byte) (data >>> 24);\n            buf[i++] = (byte) (data >>> 16);\n            buf[i++] = (byte) (data >>> 8);\n            buf[i++] = (byte) (data >>> 0);\n            bufferModified = true;\n        }\n\n        public synchronized void putLong(long base, int offset, long data) {\n            int i = loadBufferIfNeeded(base+offset);\n            buf[i++] = (byte) (data >>> 56);\n            buf[i++] = (byte) (data >>> 48);\n            buf[i++] = (byte) (data >>> 40);\n            buf[i++] = (byte) (data >>> 32);\n            buf[i++] = (byte) (data >>> 24);\n            buf[i++] = (byte) (data >>> 16);\n            buf[i++] = (byte) (data >>> 8);\n            buf[i++] = (byte) (data >>> 0);\n            bufferModified = true;\n        }\n\n        private int loadBufferIfNeeded(long index) {\n            int i = (int) (index % (entrySize * BUFFER_SIZE));\n            long newOffset = index - i;\n\n            if (offset != newOffset) {\n                try {\n                    flush();\n                    file.seek(newOffset);\n                    file.readFully(buf,0,getBufferSize(newOffset));\n                } catch (IOException ex) {\n                    ex.printStackTrace();\n                }\n\n                offset = newOffset;\n            }\n\n            return i;\n        }\n\n        private int getBufferSize(long off) {\n            int size = buf.length;\n            \n            if (fileSize-off<buf.length) {\n                size = (int)(fileSize-off);\n            }\n            return size;\n        }\n\n        private void flush() throws IOException {\n            if (bufferModified) {\n                file.seek(offset);\n                file.write(buf,0,getBufferSize(offset));\n                bufferModified = false;\n            }\n        }\n\n        @Override\n        public void force() throws IOException {\n            flush();\n        }\n    }\n    \n    private static class MemoryMappedData extends AbstractData {\n        \n        private static final FileChannel.MapMode MAP_MODE = computeMapMode();\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        MappedByteBuffer buf;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        MemoryMappedData(File f, RandomAccessFile file, long length)\n                  throws IOException {\n            super(f);\n            buf = createBuffer(file, length);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public byte getByte(long base, int offset) {\n            return buf.get((int) base+offset);\n        }\n\n        public int getInt(long base, int offset) {\n            return buf.getInt((int) base+offset);\n        }\n\n        public long getLong(long base, int offset) {\n            return buf.getLong((int) base+offset);\n        }\n\n        public void putByte(long base, int offset, byte data) {\n            buf.put((int) base+offset, data);\n        }\n\n        public void putInt(long base, int offset, int data) {\n            buf.putInt((int) base+offset, data);\n        }\n\n        public void putLong(long base, int offset, long data) {\n            buf.putLong((int) base+offset, data);\n        }\n\n        @Override\n        public void force() throws IOException {\n            if (MAP_MODE == PRIVATE) {\n                File newBufferFile = new File(bufferFile.getAbsolutePath()+\".new\"); // NOI18N\n                int length = buf.capacity();\n                new FileOutputStream(newBufferFile).getChannel().write(buf);\n                buf = null;\n                bufferFile.delete();\n                newBufferFile.renameTo(bufferFile);\n                buf = createBuffer(new RandomAccessFile(bufferFile, \"rw\"), length); // NOI18N\n            } else {\n                buf.force();\n            }\n        }\n\n        private static MappedByteBuffer createBuffer(RandomAccessFile file, long length) throws IOException {\n            try (FileChannel channel = file.getChannel()) {\n                return channel.map(MAP_MODE, 0, length);\n            }\n        }\n\n        private static FileChannel.MapMode computeMapMode() {\n            String mode = System.getProperty(\"org.graalvm.visualvm.lib.jfluid.heap.mapmode\");   // NOI18N\n            if (mode != null) {\n                if (\"private\".equals(mode)) return PRIVATE;     // NOI18N\n                return READ_WRITE;\n            }\n            if (isLinux()) return PRIVATE;\n            if (isMacOS() && isAarch64()) return PRIVATE;\n            return READ_WRITE;\n        }\n    }\n\n    private static class LongMemoryMappedData extends AbstractData {\n\n        private static int BUFFER_SIZE_BITS = 30;\n        private static long BUFFER_SIZE = 1L << BUFFER_SIZE_BITS;\n        private static int BUFFER_SIZE_MASK = (int) ((BUFFER_SIZE) - 1);\n        private static int BUFFER_EXT = 32 * 1024;\n\n        //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n        private MappedByteBuffer[] dumpBuffer;\n        private final int entrySize;\n\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        LongMemoryMappedData(File f, RandomAccessFile file, long length, int entry)\n                  throws IOException {\n            super(f);\n            dumpBuffer = createBuffers(file, length);\n            entrySize = entry;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public byte getByte(long base, int offset) {\n            return dumpBuffer[getBufferIndex(base)].get(getBufferOffset(base)+offset);\n        }\n\n        public int getInt(long base, int offset) {\n            return dumpBuffer[getBufferIndex(base)].getInt(getBufferOffset(base)+offset);\n        }\n\n        public long getLong(long base, int offset) {\n            return dumpBuffer[getBufferIndex(base)].getLong(getBufferOffset(base)+offset);\n        }\n\n        public void putByte(long base, int offset, byte data) {\n            dumpBuffer[getBufferIndex(base)].put(getBufferOffset(base)+offset,data);\n        }\n\n        public void putInt(long base, int offset, int data) {\n            dumpBuffer[getBufferIndex(base)].putInt(getBufferOffset(base)+offset,data);\n        }\n\n        public void putLong(long base, int offset, long data) {\n            dumpBuffer[getBufferIndex(base)].putLong(getBufferOffset(base)+offset,data);\n        }\n\n        private int getBufferIndex(long index) {\n            return (int) (index >> BUFFER_SIZE_BITS);\n        }\n\n        private int getBufferOffset(long index) {\n            return (int) (index & BUFFER_SIZE_MASK);\n        }\n\n        @Override\n        public void force() throws IOException{\n            if (MemoryMappedData.MAP_MODE == PRIVATE) {\n                File newBufferFile = new File(bufferFile.getAbsolutePath()+\".new\"); // NOI18N\n                long length = bufferFile.length();\n                try (FileChannel channel = new FileOutputStream(newBufferFile).getChannel()) {\n                    int offset_start = 0;\n\n                    for (int i = 0; i < dumpBuffer.length; i++) {\n                        MappedByteBuffer buf = dumpBuffer[i];\n                        long offset_end = (((i+1)*BUFFER_SIZE)/entrySize)*entrySize + entrySize;\n\n                        if (offset_end > length) {\n                            offset_end = length;\n                        }\n                        buf.limit((int)(offset_end - i*BUFFER_SIZE));\n                        buf.position(offset_start);\n                        channel.write(buf);\n                        offset_start = (int)(offset_end - (i+1)*BUFFER_SIZE);\n                    }\n                }\n                dumpBuffer = null;\n                bufferFile.delete();\n                newBufferFile.renameTo(bufferFile);\n                dumpBuffer = createBuffers(new RandomAccessFile(bufferFile, \"rw\"), length); // NOI18N\n            } else {\n                for (MappedByteBuffer buf : dumpBuffer) {\n                    buf.force();\n                }\n            }\n        }\n\n        private static MappedByteBuffer[] createBuffers(RandomAccessFile file, long length) throws IOException {\n            MappedByteBuffer[] dumpBuffer;\n            try (FileChannel channel = file.getChannel()) {\n                dumpBuffer = new MappedByteBuffer[(int) (((length + BUFFER_SIZE) - 1) / BUFFER_SIZE)];\n                for (int i = 0; i < dumpBuffer.length; i++) {\n                    long position = i * BUFFER_SIZE;\n                    long size = Math.min(BUFFER_SIZE + BUFFER_EXT, length - position);\n                    dumpBuffer[i] = channel.map(MemoryMappedData.MAP_MODE, position, size);\n                }\n            }\n            file.close();\n            return dumpBuffer;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ArrayDump.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.Collections;\nimport java.util.List;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nabstract class ArrayDump extends InstanceDump {\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    ArrayDump(ClassDump cls, long offset) {\n        super(cls, offset);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public List<FieldValue> getFieldValues() {\n        return Collections.emptyList();\n    }\n\n    public int getLength() {\n        HprofByteBuffer dumpBuffer = dumpClass.getHprofBuffer();\n        int idSize = dumpBuffer.getIDSize();\n\n        return dumpBuffer.getInt(fileOffset + 1 + idSize + 4);\n    }\n\n    public List<FieldValue> getStaticFieldValues() {\n        return Collections.emptyList();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ArrayItemValue.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n * This represents value in an array.\n * @author Tomas Hurka\n */\npublic interface ArrayItemValue extends Value {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * returns the corresponding index in array represented by this ArrayItemValue.\n     * The following is true\n     * <CODE>x.getDefiningInstance().getValues().get(x.getIndex()).equals(x.getInstance())</CODE>\n     * <br>\n     * Speed: fast\n     *\n     * @return the corresponding index in array represented by this ArrayItemValue\n     */\n    int getIndex();\n\n    /**\n     * returns corresponding {@link Instance}.\n     * <br>\n     * Speed: normal\n     * @return corresponding {@link Instance}\n     */\n    Instance getInstance();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/Bundle.properties",
    "content": "# Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Name=Java Profiler (Heap)\n\nHprofByteBuffer_ShortFile=File too short\n\nHprofByteBuffer_InvalidFormat=Invalid HPROF version or format\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/CacheDirectory.java",
    "content": "/*\n * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass CacheDirectory {\n\n    private static final String DIR_EXT = \".hwcache\";   // NOI18N\n    private static final String DUMP_AUX_FILE = \"NBProfiler.nphd\";   // NOI18N\n    private static final String DIRTY_FILENAME = \"dirty.lck\";   // NOI18N\n\n    private File cacheDirectory;\n\n    static CacheDirectory getHeapDumpCacheDirectory(File heapDump, int seg) {\n        String dumpName = heapDump.getName();\n        String suffix = seg==0 ? \"\" : \"_\"+seg;\n        File parent = heapDump.getParentFile();\n        File dir = new File(parent, dumpName+suffix+DIR_EXT);\n        return new CacheDirectory(dir);\n    }\n\n    CacheDirectory(File cacheDir) {\n        cacheDirectory = cacheDir;\n        if (cacheDir != null) {\n            if (!cacheDir.exists()) {\n                if (!cacheDir.mkdir()) {\n                    cacheDirectory = null;\n                }\n            }\n        }\n        if (cacheDirectory != null) {\n            assert cacheDirectory.isDirectory() && cacheDirectory.canRead() && cacheDirectory.canWrite();\n        }\n    }\n\n    File createTempFile(String prefix, String suffix) throws IOException {\n        File newFile;\n\n        if (isTemporary()) {\n            newFile = File.createTempFile(prefix, suffix);\n            newFile.deleteOnExit();\n        } else {\n            newFile = File.createTempFile(prefix, suffix, cacheDirectory);\n        }\n        return newFile;\n    }\n\n    File getHeapDumpAuxFile() {\n        assert !isTemporary();\n        return new File(cacheDirectory, DUMP_AUX_FILE);\n    }\n\n    boolean isTemporary() {\n        return cacheDirectory == null;\n    }\n\n    File getCacheFile(String fileName) throws FileNotFoundException {\n        File file = lookupFile(fileName, false);\n        if (file.canWrite()) {\n            return file;\n        }\n        throw new FileNotFoundException(fileName);\n    }\n\n    File getHeapFile(String fileName) throws FileNotFoundException {\n        return lookupFile(fileName, true);\n    }\n    \n    void deleteAllCachedFiles() {\n        assert !isTemporary();\n        for (File f : cacheDirectory.listFiles()) {\n            f.delete();\n        }\n    }\n\n    boolean isDirty() {\n        if (isTemporary()) return true;\n        File dirtyFile = new File(cacheDirectory,DIRTY_FILENAME);\n        return isFileR(dirtyFile);\n    }\n\n    void setDirty(boolean dirty) {\n        if (!isTemporary()) {\n            File dirtyFile = new File(cacheDirectory, DIRTY_FILENAME);\n            try {\n                if (dirty) {\n                    assert !isFileR(dirtyFile);\n                    dirtyFile.createNewFile();\n                } else {\n                    assert isFileRW(dirtyFile);\n                    dirtyFile.delete();\n                }\n            } catch (IOException ex) {\n                ex.printStackTrace();\n            }\n        }\n    }\n\n    HprofByteBuffer createHprofByteBuffer(File dumpFile)  throws IOException{\n        return HprofByteBuffer.createHprofByteBuffer(dumpFile);\n    }\n\n    AbstractLongMap.Data createDumpBuffer(long fileSize, int entrySize) throws IOException {\n        File tempFile = createTempFile(\"NBProfiler\", \".map\"); // NOI18N\n        try (RandomAccessFile file = new RandomAccessFile(tempFile, \"rw\")) { // NOI18N\n            if (Boolean.getBoolean(\"org.graalvm.visualvm.lib.jfluid.heap.zerofile\")) {    // NOI18N\n                byte[] zeros = new byte[512*1024];\n                while(file.length()+zeros.length<fileSize) {\n                    file.write(zeros);\n                }\n                file.write(zeros,0,(int)(fileSize-file.length()));\n            }\n            file.setLength(fileSize);\n            return AbstractLongMap.getDumpBuffer(tempFile, file, entrySize);\n        }\n    }\n\n    NumberList createNumberList(int idSize) throws IOException {\n        return new NumberList(idSize, this);\n    }\n\n    private File lookupFile(String fileName, boolean checkParent) throws FileNotFoundException {\n        File f = new File(fileName);\n        if (isFileR(f)) {\n            return f;\n        }\n        // try to find file next to cache directory  or in cache directory\n        File dir = checkParent ? cacheDirectory.getParentFile() : cacheDirectory;\n        f = new File(dir, f.getName());\n        if (isFileR(f)) {\n            return f;\n        }\n        if (!fileName.contains(File.separator)) {\n            // OS mismatch, try opposite separator\n            char sep = File.separatorChar == '/' ? '\\\\' : '/';      // NOI18N\n            int lastSep = fileName.lastIndexOf(sep);\n            if (lastSep != -1) {\n                f = new File(dir, fileName.substring(lastSep+1));\n                if (isFileR(f)) {\n                    return f;\n                }\n            }\n        }\n        throw new FileNotFoundException(fileName);\n    }\n\n    private static boolean isFileR(File f) {\n        return f.exists() && f.isFile() && f.canRead();\n    }\n    \n    private static boolean isFileRW(File f) {\n        return isFileR(f) && f.canWrite();\n    }\n\n    private static boolean isLinux() {\n        String osName = System.getProperty(\"os.name\");  // NOI18N\n\n        return osName.endsWith(\"Linux\"); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ClassDump.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.NoSuchElementException;\nimport java.util.Set;\nimport static org.graalvm.visualvm.lib.jfluid.heap.ObjectSizeSettings.OBJECT_ALIGNMENT;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ClassDump extends HprofObject implements JavaClass {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final boolean DEBUG = false;\n    private static final Set<String> CANNOT_CONTAIN_ITSELF = new HashSet<>(Arrays.asList(\"java.lang.String\",         // NOI18N\n            \"java.lang.StringBuffer\",   // NOI18N\n            \"java.lang.StringBuilder\",  // NOI18N\n            \"java.io.File\"              // NOI18N\n    ));\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    final ClassDumpSegment classDumpSegment;\n    private int instances;\n    private int instanceSize;\n    private long firstInstanceOffset;\n    private long loadClassOffset;\n    private long retainedSizeByClass;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    ClassDump(ClassDumpSegment segment, long offset) {\n        super(offset);\n        classDumpSegment = segment;\n        assert getHprofBuffer().get(offset) == HprofHeap.CLASS_DUMP;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public long getAllInstancesSize() {\n        long[] totalElements = classDumpSegment.arrayMap.get(this);\n\n        if (totalElements != null) {\n            int elSize = classDumpSegment.getArrayElSize(this);\n            int minArrayInstanceSize = classDumpSegment.sizeSettings.getMinimumInstanceSize() + ObjectSizeSettings.ARRAY_OVERHEAD;\n            long size = totalElements[OBJECT_ALIGNMENT]*OBJECT_ALIGNMENT*elSize;\n            for (int i=0; i<OBJECT_ALIGNMENT; i++) {\n                long psize = classDumpSegment.alignObjectSize(minArrayInstanceSize+elSize*i);\n                size += psize*totalElements[i];\n            }\n            return size;\n        }\n\n        return ((long)getInstancesCount()) * getInstanceSize();\n    }\n\n    public boolean isArray() {\n        boolean isArrayWithInstances = classDumpSegment.arrayMap.get(this) != null;\n\n        if (isArrayWithInstances) {\n            return true;\n        }\n        if (instances != 0) {\n            return false;\n        }\n        return getName().endsWith(\"[]\");\n    }\n\n    public Instance getClassLoader() {\n        return getHprof().getInstanceByID(getClassLoaderId());\n    }\n\n    public ObjectArrayInstance getSigners() {\n        return (ObjectArrayInstance) getHprof().getInstanceByID(getSignersId());\n    }\n\n    public Instance getProtectionDomain() {\n        return getHprof().getInstanceByID(getProtectionDomainId());\n    }\n\n    public Field getField(String name) {\n        for (Field field : getFields()) {\n            if (field.getName().equals(name)) {\n                return field;\n            }\n        }\n\n        return null;\n    }\n\n    public List<Field> getFields() {\n        List<Field> filedsList = classDumpSegment.fieldsCache.get(this);\n        if (filedsList == null) {\n            filedsList = Collections.unmodifiableList(computeFields());\n            classDumpSegment.fieldsCache.put(this,filedsList);\n        }\n        return filedsList;\n    }\n\n    public int getInstanceSize() {\n        if (isArray()) {\n            return -1;\n        }\n        int size = getUnalignedSize();\n        if (classDumpSegment.newSize) {\n            return size;\n        }\n        return (int)classDumpSegment.alignObjectSize(size);\n    }\n\n    public long getRetainedSizeByClass() {\n        getHprof().computeRetainedSizeByClass();\n        return retainedSizeByClass;\n    }\n\n    public List<Instance> getInstances() {\n        int instancesCount = getInstancesCount();\n\n        if (instancesCount == 0) {\n            return Collections.emptyList();\n        }\n\n        long classId = getJavaClassId();\n        HprofHeap heap = getHprof();\n        HprofByteBuffer dumpBuffer = getHprofBuffer();\n        int idSize = dumpBuffer.getIDSize();\n        List<Instance> instancesList = new ArrayList<>(instancesCount);\n        TagBounds allInstanceDumpBounds = heap.getAllInstanceDumpBounds();\n        long[] offset = new long[] { firstInstanceOffset };\n\n        while (offset[0] < allInstanceDumpBounds.endOffset) {\n            long start = offset[0];\n            int classIdOffset = 0;\n            long instanceClassId = 0L;\n            int tag = heap.readDumpTag(offset);\n            Instance instance;\n\n            if (tag == HprofHeap.INSTANCE_DUMP) {\n                classIdOffset = idSize + 4;\n            } else if (tag == HprofHeap.OBJECT_ARRAY_DUMP) {\n                classIdOffset = idSize + 4 + 4;\n            } else if (tag == HprofHeap.PRIMITIVE_ARRAY_DUMP) {\n                byte type = dumpBuffer.get(start + 1 + idSize + 4 + 4);\n                instanceClassId = classDumpSegment.getPrimitiveArrayClass(type).getJavaClassId();\n            }\n\n            if (classIdOffset != 0) {\n                instanceClassId = dumpBuffer.getID(start + 1 + classIdOffset);\n            }\n\n            if (instanceClassId == classId) {\n                if (tag == HprofHeap.INSTANCE_DUMP) {\n                    instance = new InstanceDump(this, start);\n                } else if (tag == HprofHeap.OBJECT_ARRAY_DUMP) {\n                    instance = new ObjectArrayDump(this, start);\n                } else if (tag == HprofHeap.PRIMITIVE_ARRAY_DUMP) {\n                    instance = new PrimitiveArrayDump(this, start);\n                } else {\n                    throw new IllegalArgumentException(\"Illegal tag \" + tag); // NOI18N\n                }\n\n                instancesList.add(instance);\n\n                if (--instancesCount == 0) {\n                    return instancesList;\n                }\n            }\n        }\n\n        if (DEBUG) {\n            System.out.println(\"Class \" + getName() + \" Col \" + instancesList.size() + \" instances \" + getInstancesCount()); // NOI18N\n        }\n\n        return instancesList;\n    }\n\n    public Iterator<Instance> getInstancesIterator() {\n        int instancesCount = getInstancesCount();\n        if (instancesCount == 0) {\n            return Collections.emptyIterator();\n        }\n        return new InstancesIterator(instancesCount);\n    }\n\n    public int getInstancesCount() {\n        if (instances == 0) {\n            getHprof().computeInstances();\n        }\n\n        return instances;\n    }\n\n    public long getJavaClassId() {\n        return getHprofBuffer().getID(fileOffset + classDumpSegment.classIDOffset);\n    }\n\n    public String getName() {\n        return getLoadClass().getName();\n    }\n\n    public List<FieldValue> getStaticFieldValues() {\n        return getStaticFieldValues(true);\n    }\n\n    public Collection<JavaClass> getSubClasses() {\n        List<JavaClass> classes = getHprof().getAllClasses();\n        List<JavaClass> subclasses = new ArrayList<>(classes.size() / 10);\n        Map<JavaClass,Boolean> subclassesMap = new HashMap<>((classes.size() * 4) / 3);\n\n        subclassesMap.put(this, Boolean.TRUE);\n\n        for (JavaClass jcls : classes) {\n            Boolean b = subclassesMap.get(jcls);\n\n            if (b == null) {\n                b = isSubClass(jcls, subclassesMap);\n            }\n\n            if (b.booleanValue() && (jcls != this)) {\n                subclasses.add(jcls);\n            }\n        }\n\n        return subclasses;\n    }\n\n    public JavaClass getSuperClass() {\n        long superClassId = getHprofBuffer().getID(fileOffset + classDumpSegment.superClassIDOffset);\n\n        return classDumpSegment.getClassDumpByID(superClassId);\n    }\n\n    public Object getValueOfStaticField(String name) {\n        for (FieldValue fieldValue : getStaticFieldValues()) {\n            if (fieldValue.getField().getName().equals(name)) {\n                if (fieldValue instanceof HprofFieldObjectValue) {\n                    return ((HprofFieldObjectValue) fieldValue).getInstance();\n                } else {\n                    return ((HprofFieldValue) fieldValue).getTypeValue();\n                }\n            }\n        }\n\n        return null;\n    }\n\n    public Heap getHeap() {\n        return getHprof();\n    }\n\n    private int getUnalignedSize() {\n        if (instanceSize == 0) {\n            int size;\n            if (classDumpSegment.newSize) {\n                size = getRawInstanceSize();\n            } else {\n                ClassDump jcls = (ClassDump) getSuperClass();\n                if (jcls == null) {\n                    size = classDumpSegment.sizeSettings.getMinimumInstanceSize();\n                } else {\n                    size = jcls.getUnalignedSize();\n                }\n                for (Field f : getFields()) {\n                    HprofField hf = (HprofField)f;\n                    size+=classDumpSegment.sizeSettings.getElementSize(hf.getValueType());\n                }\n            }\n            instanceSize = size;\n        }\n        return instanceSize;\n    }\n\n    private List<Field> computeFields() {\n        HprofByteBuffer buffer = getHprofBuffer();\n        long offset = fileOffset + getInstanceFieldOffset();\n        int i;\n        int fields = buffer.getShort(offset);\n        List<Field> filedsList = new ArrayList<>(fields);\n\n        for (i = 0; i < fields; i++) {\n            filedsList.add(new HprofField(this, offset + 2 + (i * classDumpSegment.fieldSize)));\n        }\n\n        return filedsList;\n    }\n\n    List<FieldValue> getStaticFieldValues(boolean addClassLoader) {\n        HprofByteBuffer buffer = getHprofBuffer();\n        long offset = fileOffset + getStaticFieldOffset();\n        int i;\n        int fields;\n        List<FieldValue> filedsList;\n        HprofHeap heap = getHprof();\n\n        fields = buffer.getShort(offset);\n        offset += 2;\n        filedsList = new ArrayList<>(fields+(addClassLoader?0:1));\n\n        for (i = 0; i < fields; i++) {\n            byte type = buffer.get(offset + classDumpSegment.fieldTypeOffset);\n            int fieldSize = classDumpSegment.fieldSize + heap.getValueSize(type);\n            HprofFieldValue value;\n\n            if (type == HprofHeap.OBJECT) {\n                value = new HprofFieldObjectValue(this, offset);\n            } else {\n                value = new HprofFieldValue(this, offset);\n            }\n\n            filedsList.add(value);\n            offset += fieldSize;\n        }\n        if (addClassLoader) {\n            long classLoaderOffset = fileOffset + classDumpSegment.classLoaderIDOffset;\n            \n            filedsList.add(new ClassLoaderFieldValue(this, classLoaderOffset));\n        }\n        return filedsList;\n    }\n    \n    List<Field> getAllInstanceFields() {\n        List<Field> fields = new ArrayList<>(50);\n\n        for (JavaClass jcls = this; jcls != null; jcls = jcls.getSuperClass()) {\n            fields.addAll(jcls.getFields());\n        }\n\n        return fields;\n    }\n\n    void setClassLoadOffset(long offset) {\n        loadClassOffset = offset;\n    }\n\n    int getConstantPoolSize() {\n        long cpOffset = fileOffset + classDumpSegment.constantPoolSizeOffset;\n        HprofByteBuffer buffer = getHprofBuffer();\n        int cpRecords = buffer.getShort(cpOffset);\n        HprofHeap heap = getHprof();\n\n        cpOffset += 2;\n\n        for (int i = 0; i < cpRecords; i++) {\n            byte type = buffer.get(cpOffset + 2);\n            int size = heap.getValueSize(type);\n            cpOffset += (2 + 1 + size);\n        }\n\n        return (int) (cpOffset - (fileOffset + classDumpSegment.constantPoolSizeOffset));\n    }\n\n    int getRawInstanceSize() {\n        return getHprofBuffer().getInt(fileOffset + classDumpSegment.instanceSizeOffset);\n    }\n\n    HprofHeap getHprof() {\n        return classDumpSegment.hprofHeap;\n    }\n\n    HprofByteBuffer getHprofBuffer() {\n        return classDumpSegment.hprofHeap.dumpBuffer;\n    }\n\n    int getInstanceFieldOffset() {\n        int staticFieldOffset = getStaticFieldOffset();\n\n        return staticFieldOffset + getStaticFieldSize(staticFieldOffset);\n    }\n\n    LoadClass getLoadClass() {\n        return new LoadClass(getHprof().getLoadClassSegment(), loadClassOffset);\n    }\n\n    long getClassLoaderId() {\n        return getHprofBuffer().getID(fileOffset + classDumpSegment.classLoaderIDOffset);\n    }\n\n    long getSignersId() {\n        return getHprofBuffer().getID(fileOffset + classDumpSegment.signersID);\n    }\n\n    long getProtectionDomainId() {\n        return getHprofBuffer().getID(fileOffset + classDumpSegment.protectionDomainIDOffset);\n    }\n\n    List<Value> getReferences() {\n        return getHprof().findReferencesFor(getJavaClassId());\n    }\n\n    int getStaticFieldOffset() {\n        return classDumpSegment.constantPoolSizeOffset + getConstantPoolSize();\n    }\n\n    int getStaticFieldSize(int staticFieldOffset) {\n        int i;\n        HprofByteBuffer buffer = getHprofBuffer();\n        int idSize = buffer.getIDSize();\n        long fieldOffset = fileOffset + staticFieldOffset;\n        int fields = buffer.getShort(fieldOffset);\n        HprofHeap heap = getHprof();\n\n        fieldOffset += 2;\n\n        for (i = 0; i < fields; i++) {\n            byte type = buffer.get(fieldOffset + idSize);\n            int size = heap.getValueSize(type);\n            fieldOffset += (idSize + 1 + size);\n        }\n\n        return (int) (fieldOffset - staticFieldOffset - fileOffset);\n    }\n\n    void findStaticReferencesFor(long instanceId, List<Value> refs) {\n        int i;\n        HprofByteBuffer buffer = getHprofBuffer();\n        int idSize = buffer.getIDSize();\n        long fieldOffset = fileOffset + getStaticFieldOffset();\n        int fields = buffer.getShort(fieldOffset);\n        List<FieldValue> staticFields = null;\n        HprofHeap heap = getHprof();\n\n        fieldOffset += 2;\n\n        for (i = 0; i < fields; i++) {\n            byte type = buffer.get(fieldOffset + idSize);\n            int size = heap.getValueSize(type);\n\n            if ((type == HprofHeap.OBJECT) && (instanceId == buffer.getID(fieldOffset + idSize + 1))) {\n                if (staticFields == null) {\n                    staticFields = getStaticFieldValues();\n                }\n\n                refs.add(staticFields.get(i));\n            }\n\n            fieldOffset += (idSize + 1 + size);\n        }\n        if (instanceId == getClassLoaderId()) {\n            if (staticFields == null) {\n                staticFields = getStaticFieldValues();\n            }\n            refs.add(staticFields.get(fields));\n        }\n    }\n\n    void registerInstance(long offset) {\n        instances++;\n        if (firstInstanceOffset == 0) {\n            firstInstanceOffset = offset;\n            if (DEBUG) {\n                System.out.println(\"First instance :\"+getName()+\" \"+offset/1024/1024); // NOI18N\n            }\n        }\n    }\n\n    void addSizeForInstance(Instance i) {\n        retainedSizeByClass+=i.getRetainedSize();\n    }\n\n    boolean canContainItself() {\n        if (getInstancesCount()>=2 && !CANNOT_CONTAIN_ITSELF.contains(getName())) {\n            for (Field f : getAllInstanceFields()) {\n                if (f.getType().getName().equals(\"object\")) {   // NOI18N\n                    return true;\n                }\n            }\n        }\n        if (DEBUG) {\n            if (instances>10) System.out.println(getName()+\" cannot contain itself \"+instances);    // NOI18N\n        }\n        return false;\n    }\n    \n    private static Boolean isSubClass(JavaClass jcls, Map<JavaClass,Boolean> subclassesMap) {\n        JavaClass superClass = jcls.getSuperClass();\n        Boolean b;\n\n        if (superClass == null) {\n            b = Boolean.FALSE;\n        } else {\n            b = subclassesMap.get(superClass);\n\n            if (b == null) {\n                b = isSubClass(superClass, subclassesMap);\n            }\n        }\n\n        subclassesMap.put(jcls, b);\n\n        return b;\n    }\n    \n    private class InstancesIterator implements Iterator<Instance> {\n        \n        private long instancesCount;\n        private long[] offset;\n        TagBounds allInstanceDumpBounds;\n        HprofHeap heap;\n        long classId;\n        \n        private InstancesIterator(long ic) {\n            instancesCount = ic;\n            heap = getHprof();\n            allInstanceDumpBounds = heap.getAllInstanceDumpBounds();\n            offset = new long[] { firstInstanceOffset };\n            classId = getJavaClassId();\n\n        }\n        \n        public boolean hasNext() {\n            if (instancesCount>0 && offset[0] < allInstanceDumpBounds.endOffset) {\n                return true;\n            }\n            return false;\n        }\n\n        public Instance next() {\n            while (hasNext()) {\n                Instance i = heap.getInstanceByOffset(offset, ClassDump.this, classId);\n                if (i != null) {\n                    instancesCount--;\n                    return i;\n                }\n            }\n            throw new NoSuchElementException();\n        } \n    }\n\n    //---- Serialization support\n    void writeToStream(DataOutputStream out) throws IOException {\n        out.writeLong(fileOffset);\n        out.writeInt(instances);\n        out.writeLong(firstInstanceOffset);\n        out.writeLong(loadClassOffset);\n        out.writeLong(retainedSizeByClass);        \n    }\n\n    ClassDump(ClassDumpSegment segment, long offset, DataInputStream dis) throws IOException {\n        this(segment, offset);\n        instances = dis.readInt();\n        firstInstanceOffset = dis.readLong();\n        loadClassOffset = dis.readLong();\n        retainedSizeByClass = dis.readLong();        \n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ClassDumpInstance.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.Collections;\nimport java.util.List;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ClassDumpInstance implements Instance {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    ClassDump classDump;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    ClassDumpInstance(ClassDump cls) {\n        classDump = cls;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public List<FieldValue> getFieldValues() {\n        return Collections.emptyList();\n    }\n\n    public boolean isGCRoot() {\n        return classDump.getHprof().isGCRoot(this);\n    }\n\n    public long getInstanceId() {\n        return classDump.getJavaClassId();\n    }\n\n    public int getInstanceNumber() {\n        return classDump.getHprof().idToOffsetMap.get(getInstanceId()).getIndex();\n    }\n\n    public JavaClass getJavaClass() {\n        return classDump.classDumpSegment.java_lang_Class;\n    }\n\n    public Instance getNearestGCRootPointer() {\n        return classDump.getHprof().getNearestGCRootPointer(this);\n    }\n\n    public long getReachableSize() {\n        return 0;\n    }\n\n    public List<Value> getReferences() {\n        return classDump.getReferences();\n    }\n\n    public long getRetainedSize() {\n        return classDump.getHprof().getRetainedSize(this);\n    }\n\n    public long getSize() {\n        return getJavaClass().getInstanceSize();\n    }\n\n    public List<FieldValue> getStaticFieldValues() {\n        return getJavaClass().getStaticFieldValues();\n    }\n\n    public Object getValueOfField(String name) {\n        return null;\n    }\n\n    public boolean equals(Object obj) {\n        if (obj instanceof ClassDumpInstance) {\n            return classDump.equals(((ClassDumpInstance) obj).classDump);\n        } else {\n            return false;\n        }\n    }\n\n    public int hashCode() {\n        return classDump.hashCode();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ClassDumpSegment.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.regex.Pattern;\nimport static org.graalvm.visualvm.lib.jfluid.heap.ObjectSizeSettings.*;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ClassDumpSegment extends TagBounds {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    HprofHeap hprofHeap;\n    final ObjectSizeSettings sizeSettings;\n    // Map <JavaClass represeting array,Long - allInstanceSize>\n    Map<JavaClass,long[]> arrayMap;\n    final int classIDOffset;\n    final int classLoaderIDOffset;\n    final int constantPoolSizeOffset;\n    final int fieldNameIDOffset;\n    final int fieldSize;\n    final int fieldTypeOffset;\n    final int fieldValueOffset;\n    final int instanceSizeOffset;\n    final int protectionDomainIDOffset;\n    final int reserved1;\n    final int reserver2;\n    final int signersID;\n    final int stackTraceSerialNumberOffset;\n    final int superClassIDOffset;\n    ClassDump java_lang_Class;\n    boolean newSize;\n    Map<JavaClass,List<Field>> fieldsCache;\n    private List<JavaClass> classes;\n    private Map<Integer,JavaClass> primitiveArrayMap;\n    private Map<JavaClass,Integer> primitiveTypeMap;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    ClassDumpSegment(HprofHeap heap, long start, long end) {\n        super(HprofHeap.CLASS_DUMP, start, end);\n\n        int idSize = heap.dumpBuffer.getIDSize();\n        hprofHeap = heap;\n        sizeSettings = new ObjectSizeSettings(hprofHeap);\n        // initialize offsets\n        classIDOffset = 1;\n        stackTraceSerialNumberOffset = classIDOffset + idSize;\n        superClassIDOffset = stackTraceSerialNumberOffset + 4;\n        classLoaderIDOffset = superClassIDOffset + idSize;\n        signersID = classLoaderIDOffset + idSize;\n        protectionDomainIDOffset = signersID + idSize;\n        reserved1 = protectionDomainIDOffset + idSize;\n        reserver2 = reserved1 + idSize;\n        instanceSizeOffset = reserver2 + idSize;\n        constantPoolSizeOffset = instanceSizeOffset + 4;\n\n        fieldNameIDOffset = 0;\n        fieldTypeOffset = fieldNameIDOffset + idSize;\n        fieldValueOffset = fieldTypeOffset + 1;\n\n        fieldSize = fieldTypeOffset + 1;\n        \n        fieldsCache = Collections.synchronizedMap(new FieldsCache<>());\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    ClassDump getClassDumpByID(long classObjectID) {\n        if (classObjectID == 0) {\n            return null;\n        }\n        List<JavaClass> allClasses = createClassCollection();\n        LongMap.Entry entry = hprofHeap.idToOffsetMap.get(classObjectID);\n\n        if (entry != null) {\n            try {\n                ClassDump dump = (ClassDump) allClasses.get(entry.getIndex() - 1);\n                if (dump.fileOffset == entry.getOffset()) {\n                    return dump;\n                }\n            } catch (IndexOutOfBoundsException ex) { // classObjectID do not reffer to ClassDump, its instance number is > classes.size()\n                return null;\n            } catch (ClassCastException ex) { // classObjectID do not reffer to ClassDump\n                return null;\n            }\n        }\n\n        return null;\n    }\n\n    JavaClass getJavaClassByName(String fqn) {\n        for (JavaClass cls : createClassCollection()) {\n            if (fqn.equals(cls.getName())) {\n                return cls;\n            }\n        }\n\n        return null;\n    }\n\n    Collection<JavaClass> getJavaClassesByRegExp(String regexp) {\n        Collection<JavaClass> result = new ArrayList<>(256);\n        Pattern pattern = Pattern.compile(regexp);\n        \n        for (JavaClass cls : createClassCollection()) {\n            if (pattern.matcher(cls.getName()).matches()) {\n                result.add(cls);\n            }\n        }\n        return result;\n    }\n\n    long getArraySize(byte type, int elements) {\n        long size;\n        long elementSize = sizeSettings.getElementSize(type);\n        size = sizeSettings.getMinimumInstanceSize() + ARRAY_OVERHEAD + (elementSize * elements);\n        return alignObjectSize(size);\n    }\n\n    ClassDump getPrimitiveArrayClass(byte type) {\n        ClassDump primitiveArray = (ClassDump) primitiveArrayMap.get(Integer.valueOf(type));\n\n        if (primitiveArray == null) {\n            throw new IllegalArgumentException(\"Invalid type \" + type); // NOI18N\n        }\n\n        return primitiveArray;\n    }\n\n    Map<Long,JavaClass> getClassIdToClassMap() {\n        List<JavaClass> allClasses = createClassCollection();\n        Map<Long,JavaClass> map = new HashMap<>(allClasses.size()*4/3);\n        \n        for (JavaClass cls : allClasses) {\n            map.put(new Long(cls.getJavaClassId()),cls);\n        }\n        return map;\n    }\n    \n    void addInstanceSize(ClassDump cls, int tag, long instanceOffset) {\n        if ((tag == HprofHeap.OBJECT_ARRAY_DUMP) || (tag == HprofHeap.PRIMITIVE_ARRAY_DUMP)) {\n            long sizeLong[] = arrayMap.get(cls);\n            HprofByteBuffer dumpBuffer = hprofHeap.dumpBuffer;\n            int idSize = dumpBuffer.getIDSize();\n            long elementsOffset = instanceOffset + 1 + idSize + 4;\n\n            if (sizeLong == null) {\n                sizeLong = new long[OBJECT_ALIGNMENT+1];\n                arrayMap.put(cls, sizeLong);\n            }\n\n            int elements = dumpBuffer.getInt(elementsOffset);\n            sizeLong[OBJECT_ALIGNMENT] += elements/OBJECT_ALIGNMENT;\n            sizeLong[elements%OBJECT_ALIGNMENT]++;\n        }\n    }\n\n    long alignObjectSize(long size) {\n        return (size+OBJECT_ALIGNMENT-1) & (~(OBJECT_ALIGNMENT-1));\n    }\n\n    synchronized List<JavaClass> createClassCollection() {\n        if (classes != null) {\n            return classes;\n        }\n\n        List<JavaClass> cls = new ArrayList<>(1000);\n\n        long[] offset = new long[] { startOffset };\n\n        while (offset[0] < endOffset) {\n            long start = offset[0];\n            int tag = hprofHeap.readDumpTag(offset);\n\n            if (tag == HprofHeap.CLASS_DUMP) {\n                ClassDump classDump = new ClassDump(this, start);\n                long classId = classDump.getJavaClassId();\n                LongMap.Entry classEntry = hprofHeap.idToOffsetMap.put(classId, start);\n\n                cls.add(classDump);\n                classEntry.setIndex(cls.size());\n            }\n        }\n\n        classes = Collections.unmodifiableList(cls);\n        hprofHeap.getLoadClassSegment().setLoadClassOffsets();\n        arrayMap = new HashMap<>(classes.size() / 15);\n        extractSpecialClasses();\n\n        return classes;\n    }\n\n    void extractSpecialClasses() {\n        ClassDump java_lang_Object = null;\n        primitiveArrayMap = new HashMap<>();\n        primitiveTypeMap = new HashMap<>();\n\n        for (JavaClass jc : classes) {\n            ClassDump jcls = (ClassDump)jc;\n            String vmName = jcls.getLoadClass().getVMName();\n            int type = -1;\n\n            switch (vmName) {\n                case \"[Z\":        // NOI18N\n                case \"boolean[]\": // NOI18N\n                    type = HprofHeap.BOOLEAN;\n                    break;\n                case \"[C\":        // NOI18N\n                case \"char[]\":    // NOI18N\n                    type = HprofHeap.CHAR;\n                    break;\n                case \"[F\":        // NOI18N\n                case \"float[]\":   // NOI18N\n                    type = HprofHeap.FLOAT;\n                    break;\n                case \"[D\":        // NOI18N\n                case \"double[]\":  // NOI18N\n                    type = HprofHeap.DOUBLE;\n                    break;\n                case \"[B\":        // NOI18N\n                case \"byte[]\":    // NOI18N\n                    type = HprofHeap.BYTE;\n                    break;\n                case \"[S\":        // NOI18N\n                case \"short[]\":   // NOI18N\n                    type = HprofHeap.SHORT;\n                    break;\n                case \"[I\":        // NOI18N\n                case \"int[]\":     // NOI18N\n                    type = HprofHeap.INT;\n                    break;\n                case \"[J\":        // NOI18N\n                case \"long[]\":    // NOI18N\n                    type = HprofHeap.LONG;\n                    break;\n                case \"java/lang/Class\":  // NOI18N\n                case \"java.lang.Class\":  // NOI18N\n                    java_lang_Class = jcls;\n                    break;\n                case \"java/lang/Object\": // NOI18N\n                case \"java.lang.Object\": // NOI18N\n                    java_lang_Object = jcls;\n                    break;\n                default:\n                    break;\n            }\n\n            if (type != -1) {\n                Integer typeObj = Integer.valueOf(type);\n                primitiveArrayMap.put(typeObj, jcls);\n                primitiveTypeMap.put(jcls, typeObj);\n            }\n        }\n        if (java_lang_Object != null) {\n            int objectSize = java_lang_Object.getRawInstanceSize();\n            if (objectSize > 0) {\n                newSize = true;\n                sizeSettings.setMinimumInstanceSize(objectSize);\n            }\n        }\n    }\n\n    //---- Serialization support\n    void writeToStream(DataOutputStream out) throws IOException {\n        super.writeToStream(out);\n        if (classes == null) {\n            out.writeInt(0);\n        } else {\n            out.writeInt(classes.size());\n            for (JavaClass aClass : classes) {\n                ClassDump classDump = (ClassDump) aClass;\n\n                classDump.writeToStream(out);\n                long[] size = arrayMap.get(classDump);\n                out.writeBoolean(size != null);\n                if (size != null) {\n                    for (long l : size) {\n                        out.writeLong(l);\n                    }\n                }\n            }\n        }\n    }\n\n    ClassDumpSegment(HprofHeap heap, long start, long end, DataInputStream dis) throws IOException {\n        this(heap, start, end);\n        int classesSize = dis.readInt();\n        if (classesSize != 0) {\n            List<JavaClass> cls = new ArrayList<>(classesSize);\n            arrayMap = new HashMap<>(classesSize / 15);\n            \n            for (int i=0; i<classesSize; i++) {\n                ClassDump c = new ClassDump(this, dis.readLong(), dis);\n                cls.add(c);\n                if (dis.readBoolean()) {\n                    long[] size = new long[OBJECT_ALIGNMENT+1];\n                    for (int si = 0; si < size.length; si++) {\n                        size[si] = dis.readLong();\n                    }\n                    arrayMap.put(c, size);\n                }\n            }\n            classes = Collections.unmodifiableList(cls);\n        }\n    }\n    \n    int getArrayElSize(ClassDump cls) {\n        Integer typeObj = primitiveTypeMap.get(cls);\n        byte type = typeObj != null ? typeObj.byteValue() : HprofHeap.OBJECT;\n        return sizeSettings.getElementSize(type);\n    }\n\n    private static class FieldsCache<K,V> extends LinkedHashMap<K,V> {\n        private static final int SIZE = 500;\n        \n        FieldsCache() {\n            super(SIZE,0.75f,true);\n        }\n\n        protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {\n            return size() > SIZE;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ClassLoaderFieldValue.java",
    "content": "/*\n * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ClassLoaderFieldValue extends HprofFieldObjectValue {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    ClassLoaderFieldValue(ClassDump cls, long offset) {\n        super(cls, offset);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getName() {\n        return \"<classLoader>\";  // NOI18N\n    }\n\n    byte getValueType() {\n        return (byte)HprofHeap.OBJECT;\n    }\n\n    public Instance getInstance() {\n        return classDump.getClassLoader();\n    }\n\n    long getInstanceID() {\n        return classDump.getClassLoaderId();\n    }\n\n    Object getTypeValue() {\n        return Long.valueOf(getInstanceID());\n    }\n\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ComputedSummary.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ComputedSummary implements HeapSummary {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final long bytes;\n    private final long instances;\n    private final long time;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    ComputedSummary(HprofHeap heap) {\n        long bytesCount = 0;\n        long instancesCount = 0;\n\n        for (JavaClass jcls : heap.getAllClasses()) {\n            instancesCount += jcls.getInstancesCount();\n            bytesCount += jcls.getAllInstancesSize();\n        }\n        bytes = bytesCount;\n        instances = instancesCount;\n        long headerTime = heap.dumpBuffer.getTime();\n        long tagTime = heap.getHeapTime() / 1000;\n        time = headerTime + tagTime;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public long getTime() {\n        return time;\n    }\n\n    public long getTotalAllocatedBytes() {\n        return -1;\n    }\n\n    public long getTotalAllocatedInstances() {\n        return -1;\n    }\n\n    public long getTotalLiveBytes() {\n        return bytes;\n    }\n\n    public long getTotalLiveInstances() {\n        return instances;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/DominatorTree.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.TreeMap;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass DominatorTree {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final int BUFFER_SIZE = (64 * 1024) / 8;\n    private static final int ADDITIONAL_IDS_THRESHOLD = 30;\n    private static final int ADDITIONAL_IDS_THRESHOLD_DIRTYSET_SAME_SIZE = 5;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private HprofHeap heap;\n    private LongBuffer multipleParents;\n    private LongBuffer revertedMultipleParents;\n    private LongBuffer currentMultipleParents;\n    private LongHashMap map;\n    private LongSet dirtySet;\n    private int dirtySetSameSize;\n    private Map<ClassDump,Boolean> canContainItself;\n    private Map<Long,Long> nearestGCRootCache = new NearestGCRootCache<>(400000);\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    DominatorTree(HprofHeap h, LongBuffer multiParents) {\n        heap = h;\n        multipleParents = multiParents;\n        currentMultipleParents = multipleParents;\n        map = new LongHashMap(multiParents.getSize());\n        dirtySet = new LongSet();\n        try {\n            revertedMultipleParents = multiParents.revertBuffer();\n        } catch (IOException ex) {\n            throw new IllegalArgumentException(ex.getLocalizedMessage(),ex);\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------    \n    \n    synchronized void computeDominators() {\n        boolean changed = true;\n        boolean ignoreDirty;\n        try {\n            do {\n                currentMultipleParents.startReading();\n                ignoreDirty = !changed;\n                changed = computeOneLevel(ignoreDirty);\n                switchParents();\n            } while (changed || !ignoreDirty);\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n        deleteBuffers();\n        dirtySet = new LongSet();\n    }\n    \n    private boolean computeOneLevel(boolean ignoreDirty) throws IOException {\n        boolean changed = false;\n        LongSet newDirtySet = new LongSet(map.size()/10);\n        List<Long> additionalIds = new ArrayList<>();\n        int additionalIndex = 0;\n        // debug \n//        long processedId = 0;\n//        long changedId = 0;\n//        long index = 0;\n//        List<Long> changedIds = new ArrayList();\n//        List<Long> changedIdx = new ArrayList();\n//        List<Boolean> addedBynewDirtySet = new ArrayList();\n//        List<Long> oldDomIds = new ArrayList();\n//        List<Long> newDomIds = new ArrayList();\n\n//System.out.println(\"New level, dirtyset size: \"+dirtySet.size());\n        for (;;) {\n            long instanceId = readLong();\n            if (instanceId == 0) {  // end of level\n                if (additionalIndex >= additionalIds.size()) {\n                    if (additionalIndex>0) {\n//System.out.println(\"Additional instances \"+additionalIndex);\n                    }\n                    break;\n                }\n                instanceId = additionalIds.get(additionalIndex++).longValue();\n            }\n            long oldIdom = map.get(instanceId);\n//index++;\n            if (oldIdom == -1 || (oldIdom > 0 && (ignoreDirty || dirtySet.contains(oldIdom) || dirtySet.contains(instanceId)))) {            \n//processedId++;\n                LongMap.Entry entry = heap.idToOffsetMap.get(instanceId);\n                LongIterator refIt = entry.getReferences();\n                long newIdomId = refIt.next();\n                boolean dirty = false;\n                \n                while(refIt.hasNext() && newIdomId != 0) {\n                    long refIdObj = refIt.next();\n                    newIdomId = intersect(newIdomId, refIdObj);\n                }\n                if (oldIdom == -1) {\n//addedBynewDirtySet.add(newDirtySet.contains(instanceId) && !dirtySet.contains(instanceId));\n                    map.put(instanceId, newIdomId);\n                    if (newIdomId != 0) newDirtySet.add(newIdomId);\n                    changed = true;\n//changedId++;\n//changedIds.add(instanceId);\n//changedIdx.add(index);\n//oldDomIds.add(null);\n//newDomIds.add(newIdomId);\n                } else if (oldIdom != newIdomId) {\n//addedBynewDirtySet.add((newDirtySet.contains(oldIdom) || newDirtySet.contains(instanceId)) && !(dirtySet.contains(oldIdom) || dirtySet.contains(instanceId)));\n                    newDirtySet.add(oldIdom);\n                    if (newIdomId != 0) newDirtySet.add(newIdomId);\n                    map.put(instanceId,newIdomId);\n                    if (dirtySet.size() < ADDITIONAL_IDS_THRESHOLD || dirtySetSameSize >= ADDITIONAL_IDS_THRESHOLD_DIRTYSET_SAME_SIZE) {\n                        updateAdditionalIds(instanceId, additionalIds);\n                    }\n                    changed = true;\n//changedId++;\n//changedIds.add(instanceId);\n//changedIdx.add(index);\n//oldDomIds.add(oldIdom);\n//newDomIds.add(newIdomId);\n                }\n            }\n        }\n        if (dirtySet.size() != newDirtySet.size()) {\n            dirtySetSameSize = 0;\n        } else {\n            dirtySetSameSize++;\n        }\n        dirtySet = newDirtySet;\n//System.out.println(\"Processed: \"+processedId);\n//System.out.println(\"Changed:   \"+changedId);\n//System.out.println(\"-------------------\");\n//printObjs(changedIds,oldDomIds,newDomIds, addedBynewDirtySet, changedIdx);\n//System.out.println(\"-------------------\");\n        return changed;\n    }\n        \n    private void updateAdditionalIds(final long instanceId, final List<Long> additionalIds) {\n        Instance i = heap.getInstanceByID(instanceId);\n//System.out.println(\"Inspecting \"+printInstance(instanceId));\n        if (i != null) {\n            for (FieldValue v : i.getFieldValues()) {\n                if (v instanceof ObjectFieldValue) {\n                    Instance val = ((ObjectFieldValue)v).getInstance();\n                    if (val != null) {\n                        long idp = val.getInstanceId();\n                        Long idO = new Long(idp);\n                        long idomO = map.get(idp);\n                        if (idomO > 0) {\n                            additionalIds.add(idO);\n//System.out.println(\"  Adding \"+printInstance(idO));\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    private void deleteBuffers() {\n        multipleParents.delete();\n        revertedMultipleParents.delete();\n    }\n        \n    private long readLong() throws IOException {\n        return currentMultipleParents.readLong();\n    }\n    \n    long getIdomId(long instanceId, LongMap.Entry entry) {\n        long idomEntry = map.get(instanceId);\n        if (idomEntry != -1) {\n            return idomEntry;\n        }\n        if (entry == null) {\n            entry = heap.idToOffsetMap.get(instanceId);\n        }\n        return entry.getNearestGCRootPointer();\n    }\n    \n    boolean hasInstanceInChain(int tag, Instance i) {\n        ClassDump javaClass;\n        long idom;\n        long instanceId;\n        \n        if (tag == HprofHeap.PRIMITIVE_ARRAY_DUMP) {\n            return false;\n        }        \n        javaClass = (ClassDump) i.getJavaClass();\n        if (canContainItself == null) {\n            canContainItself = new HashMap<>(heap.getAllClasses().size()/2);\n        }\n        if (tag == HprofHeap.INSTANCE_DUMP) {\n            Boolean canContain = canContainItself.get(javaClass);\n\n            if (canContain == null) {\n                canContain = Boolean.valueOf(javaClass.canContainItself());\n                canContainItself.put(javaClass,canContain);\n            }\n            if (!canContain.booleanValue()) {\n                return false;\n            }\n        }\n        instanceId = i.getInstanceId();\n        idom = getIdomId(instanceId);\n        for (;idom!=0;idom=getIdomId(idom)) {\n            Instance ip = heap.getInstanceByID(idom);\n            JavaClass cls = ip.getJavaClass();\n            \n            if (javaClass.equals(cls)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private Long getNearestGCRootPointer(Long instanceIdLong) {\n        LongMap.Entry entry;\n        Long nearestGCLong = nearestGCRootCache.get(instanceIdLong);\n        Long nearestGC;\n        if (nearestGCLong != null) {\n            return nearestGCLong;\n        }\n        entry = heap.idToOffsetMap.get(instanceIdLong.longValue());\n        nearestGC = Long.valueOf(entry.getNearestGCRootPointer());\n        nearestGCRootCache.put(instanceIdLong,nearestGC);\n        return nearestGC;\n    }\n    \n    private long getIdomId(long instanceIdLong) {\n        long idom = map.get(instanceIdLong);\n        \n        if (idom != -1) {\n            return idom;\n        }\n        return getNearestGCRootPointer(instanceIdLong);\n    }\n    \n    private long intersect(long idomId, long refId) {\n        if (idomId == refId) {\n            return idomId;\n        }\n        if (idomId == 0 || refId == 0) {\n            return 0;\n        }\n        LongSet leftIdoms = new LongSet(200);\n        LongSet rightIdoms = new LongSet(200);        \n        long leftIdom = idomId;\n        long rightIdom = refId;\n\n        \n        leftIdoms.add(leftIdom);\n        rightIdoms.add(rightIdom);\n        while(true) {\n            if (rightIdom == 0 && leftIdom == 0) return 0;\n            if (leftIdom != 0) {\n                leftIdom = getIdomId(leftIdom);\n                if (leftIdom != 0) {\n                    if (rightIdoms.contains(leftIdom)) {\n                        return leftIdom;\n                    }\n                    leftIdoms.add(leftIdom);\n                }\n            }\n            if (rightIdom != 0) {\n                rightIdom = getIdomId(rightIdom);\n                if (rightIdom != 0) {\n                    if (leftIdoms.contains(rightIdom)) {\n                        return rightIdom;\n                    }\n                    rightIdoms.add(rightIdom);\n                }\n            }\n        }\n    }\n\n    private void switchParents() {\n        if (currentMultipleParents == revertedMultipleParents) {\n            currentMultipleParents = multipleParents;\n        } else {\n            currentMultipleParents = revertedMultipleParents;\n        }\n    }\n\n    // debugging \n    private void printObjs(List<Long> changedIds, List<Long> oldDomIds, List<Long> newDomIds, List<Boolean> addedByDirtySet, List<Long> changedIdx) {\n        if (changedIds.size()>20) return;\n        TreeMap<Integer,String> m = new TreeMap<>();\n        \n        for (int i=0; i<changedIds.size(); i++) {\n            Long iid = changedIds.get(i);\n            Long oldDom = oldDomIds.get(i);\n            Long newDom = newDomIds.get(i);\n            Long index = changedIdx.get(i);\n            Boolean addedByDirt = addedByDirtySet.get(i);\n            Instance ii = heap.getInstanceByID(iid.longValue());\n            int number = ii.getInstanceNumber();\n            String text = \"Index: \"+index+(addedByDirt?\" New \":\" Old \")+printInstance(iid);\n            \n            text+=\" OldDom \"+printInstance(oldDom);\n            text+=\" NewDom: \"+printInstance(newDom);\n            m.put(number,text);\n        }\n        for (Integer in : m.keySet()) {\n            System.out.println(m.get(in));\n        }\n    }\n    \n    // debugging\n    String printInstance(Long instanceid) {\n        if (instanceid == null || instanceid.longValue() == 0) {\n            return \"null\";\n        }\n        Instance ii = heap.getInstanceByID(instanceid.longValue());\n        return ii.getJavaClass().getName()+\"#\"+ii.getInstanceNumber();\n        \n    }\n\n    //---- Serialization support\n    void writeToStream(DataOutputStream out) throws IOException {\n        map.writeToStream(out);\n    }\n\n    DominatorTree(HprofHeap h, DataInputStream dis) throws IOException {\n        heap = h;\n        map = new LongHashMap(dis);\n    }\n    \n    private static final class NearestGCRootCache<K,V> extends LinkedHashMap<K,V> {\n        private final int maxSize;\n        \n        private NearestGCRootCache(int size) {\n            super(size,0.75F,true);\n            maxSize = size;\n        }\n\n        protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {\n            return size() > maxSize;\n        }\n\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/Field.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n * represents field (static or instance) of the class.\n * @author Tomas Hurka\n */\npublic interface Field {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * returns declaring class for this field.\n     * <br>\n     * speed: fast\n     * @return {@link JavaClass} where this field is declared\n     */\n    JavaClass getDeclaringClass();\n\n    /**\n     * returns name of the field.\n     * <br>\n     * speed: fast\n     * @return name of the field\n     */\n    String getName();\n\n    /**\n     * distinguish between static and instance field.\n     * <br>\n     * speed: fast\n     * @return returns <CODE>true</CODE> if the field is defined as static, <CODE>false</CODE> otherwise\n     */\n    boolean isStatic();\n\n    /**\n     * returns the type of field (object, int, boolean, etc.). Note that all java objects\n     * have type \"object\", there is no difference between java.lang.String and java.util.List.\n     * <br>\n     * Speed: fast\n     * @return type of field\n     */\n    Type getType();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/FieldValue.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n * represents value of instance or static field\n * @author Tomas Hurka\n */\npublic interface FieldValue extends Value {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * get corresponding {@link Field} for this field value.\n     * <br>\n     * Speed: fast\n     * @return {@link Field} for this field value\n     */\n    Field getField();\n\n    /**\n     * returns String representation of the value.\n     * If the value refers to {@link Instance}, instance id\n     * is used to compute its String representation\n     * <br>\n     * Speed: fast\n     * @return String representation of the value\n     */\n    String getValue();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/GCRoot.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n * This represents one GC root. It has kind ({@link GCRoot#JNI_GLOBAL}, etc.) and also corresponding\n * {@link Instance}, which is actual GC root.\n * @author Tomas Hurka\n */\npublic interface GCRoot {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    /**\n     * JNI global GC root kind.\n     */\n    public static final String JNI_GLOBAL = \"JNI global\"; // NOI18N\n\n    /**\n     * JNI local GC root kind.\n     */\n    public static final String JNI_LOCAL = \"JNI local\"; // NOI18N\n\n    /**\n     * Java frame GC root kind.\n     */\n    public static final String JAVA_FRAME = \"Java frame\"; // NOI18N\n\n    /**\n     * Native stack GC root kind.\n     */\n    public static final String NATIVE_STACK = \"native stack\"; // NOI18N\n\n    /**\n     * Sticky class GC root kind.\n     */\n    public static final String STICKY_CLASS = \"sticky class\"; // NOI18N\n\n    /**\n     * Thread block GC root kind.\n     */\n    public static final String THREAD_BLOCK = \"thread block\"; // NOI18N\n\n    /**\n     * Monitor used GC root kind.\n     */\n    public static final String MONITOR_USED = \"monitor used\"; // NOI18N\n\n    /**\n     * Thread object GC root kind.\n     */\n    public static final String THREAD_OBJECT = \"thread object\"; // NOI18N\n\n    /**\n     * Unknown GC root kind.\n     */\n    public static final String UNKNOWN = \"unknown\"; // NOI18N\n\n    /**\n     * Interned string GC root kind.\n     */\n    public static final String INTERNED_STRING = \"interned string\"; // NOI18N\n\n    /**\n     * Finalizing GC root kind.\n     */\n    public static final String FINALIZING = \"finalizing\"; // NOI18N\n\n    /**\n     * Debugger GC root kind.\n     */\n    public static final String DEBUGGER = \"debugger\"; // NOI18N\n\n    /**\n     * Reference cleanup GC root kind.\n     */\n    public static final String REFERENCE_CLEANUP = \"reference cleanup\"; // NOI18N\n\n    /**\n     * VM internal GC root kind.\n     */\n    public static final String VM_INTERNAL = \"VM internal\"; // NOI18N\n\n    /**\n     * JNI monitor GC root kind.\n     */\n    public static final String JNI_MONITOR = \"JNI monitor\"; // NOI18N\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * returns corresponding {@link Instance}, which is GC root.\n     * <br>\n     * Speed:normal\n     * @return GC root instance\n     */\n    Instance getInstance();\n\n    /**\n     * returns kind of this GC root.\n     * <br>\n     * Speed:fast\n     * @return human readable GC root kind.\n     */\n    String getKind();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/Heap.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Properties;\n\n\n/**\n * This is top-level interface representing one instance of heap dump.\n * @author Tomas Hurka\n */\npublic interface Heap {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * computes List of all {@link JavaClass} instances in this heap.\n     * The classes are ordered according to the position in the dump file.\n     * <br>\n     * Speed: slow for the first time, subsequent invocations are fast.\n     * @return list of all {@link JavaClass} in the heap.\n     */\n    List<JavaClass> getAllClasses();\n\n    /**\n     * computes List of N biggest {@link Instance}-s in this heap.\n     * The instances are ordered according to their retained size.\n     * <br>\n     * Speed: slow for the first time, subsequent invocations are normal.\n     * @param number size of the returned List\n     * @return list of N biggest {@link Instance}.\n     */\n    List<Instance> getBiggestObjectsByRetainedSize(int number);\n\n    /**\n     * returns list of {@link GCRoot} for {@link Instance}.\n     * <br>\n     * Speed: normal for first invocation, fast for subsequent\n     * @param instance {@link Instance} whose associated list of {@link GCRoot} is to be returned.\n     * @return list of {@link GCRoot} for corresponding instance or empty list if instance is not GC root.\n     */\n    Collection<GCRoot> getGCRoots(Instance instance);\n\n    /**\n     * returns list of all GC roots.\n     * <br>\n     * Speed: normal for first invocation, fast for subsequent\n     * @return list of {@link GCRoot} instances representing all GC roots.\n     */\n    Collection<GCRoot> getGCRoots();\n\n    /**\n     * computes {@link Instance} for instanceId.\n     * <br>\n     * Speed: fast\n     * @param instanceId unique ID of {@link Instance}\n     * @return return <CODE>null</CODE> if there is no {@link Instance} with instanceId, otherwise\n     * corresponding {@link Instance} is returned so that\n     * <CODE>heap.getInstanceByID(instanceId).getInstanceId() == instanceId</CODE>\n     */\n    Instance getInstanceByID(long instanceId);\n\n    /**\n     * computes {@link JavaClass} for javaclassId.\n     * <br>\n     * Speed: fast\n     * @param javaclassId unique ID of {@link JavaClass}\n     * @return return <CODE>null</CODE> if there is no java class with javaclassId, otherwise corresponding {@link JavaClass}\n     * is returned so that <CODE>heap.getJavaClassByID(javaclassId).getJavaClassId() == javaclassId</CODE>\n     */\n    JavaClass getJavaClassByID(long javaclassId);\n\n    /**\n     * computes {@link JavaClass} for fully qualified name.\n     * <br>\n     * Speed: slow\n     * @param fqn fully qualified name of the java class.\n     * @return return <CODE>null</CODE> if there is no class with fqn name, otherwise corresponding {@link JavaClass}\n     * is returned so that <CODE>heap.getJavaClassByName(fqn).getName().equals(fqn)</CODE>\n     */\n    JavaClass getJavaClassByName(String fqn);\n\n    /**\n     * computes collection of {@link JavaClass} filtered by regular expression.\n     * <br>\n     * Speed: slow\n     * @param regexp regular expression for java class name.\n     * @return return collection of {@link JavaClass} instances, which names satisfy the regexp expression. This\n     * collection is empty if no class matches the regular expression\n     */\n    Collection<JavaClass> getJavaClassesByRegExp(String regexp);\n\n    /**\n     * returns an iterator over the {@link Instance}es in the whole heap. There are no\n     * guarantees concerning the order in which the {@link Instance}es are returned.\n     * <br>\n     * Speed: fast\n     *\n     * @return an <tt>Iterator</tt> over the {@link Instance}es in this heap\n     */\n    public Iterator<Instance> getAllInstancesIterator();\n    \n    /**\n     * returns optional summary information of the heap.\n     * If this information is not available in the dump,\n     * some data (like number of instances) are computed\n     * from the dump itself.\n     * <br>\n     * Speed: fast if the summary is available in dump, slow if\n     * summary needs to be computed from dump.\n     * @return {@link HeapSummary} of the heap\n     */\n    HeapSummary getSummary();\n\n    /**\n     * Determines the system properties of the {@link Heap}. It returns {@link Properties} with the same\n     * content as if {@link System#getProperties()} was invoked in JVM, where this heap dump was taken.\n     * <br>\n     * Speed: slow\n     * @return the system properties or <CODE>null</CODE> if the system properties cannot be computed from\n     * this {@link Heap}\n     */\n    Properties getSystemProperties();\n\n    boolean isRetainedSizeComputed();\n    boolean isRetainedSizeByClassComputed();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HeapFactory.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.BufferedInputStream;\nimport java.io.DataInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.InputStream;\n\n\n/**\n * This is factory class for creating {@link Heap} from the file in Hprof dump format.\n * @author Tomas Hurka\n */\npublic class HeapFactory {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * this factory method creates {@link Heap} from a memory dump file in Hprof format.\n     * <br>\n     * Speed: slow\n     * @param heapDump file which contains memory dump\n     * @return implementation of {@link Heap} corresponding to the memory dump\n     * passed in heapDump parameter\n     * @throws java.io.FileNotFoundException if heapDump file does not exist\n     * @throws java.io.IOException if I/O error occurred while accessing heapDump file\n     */\n    public static Heap createHeap(File heapDump) throws FileNotFoundException, IOException {\n        return createHeap(heapDump, 0);\n    }\n\n    /**\n     * this factory method creates {@link Heap} from a memory dump file in Hprof format.\n     * If the memory dump file contains more than one dump, parameter segment is used to\n     * select particular dump.\n     * <br>\n     * Speed: slow\n     * @return implementation of {@link Heap} corresponding to the memory dump\n     * passed in heapDump parameter\n     * @param segment select corresponding dump from multi-dump file\n     * @param heapDump file which contains memory dump\n     * @throws java.io.FileNotFoundException if heapDump file does not exist\n     * @throws java.io.IOException if I/O error occurred while accessing heapDump file\n     */\n    public static Heap createHeap(File heapDump, int segment)\n                           throws FileNotFoundException, IOException {\n        CacheDirectory cacheDir = CacheDirectory.getHeapDumpCacheDirectory(heapDump, segment);\n        if (!cacheDir.isTemporary()) {\n            File savedDump = cacheDir.getHeapDumpAuxFile();\n\n            if (savedDump.exists() && savedDump.isFile() && savedDump.canRead()) {\n                try {\n                    return loadHeap(cacheDir);\n                } catch (IOException ex) {\n                    System.err.println(\"Loading heap dump \"+heapDump+\" from cache failed.\");\n                    ex.printStackTrace(System.err);\n                    cacheDir.deleteAllCachedFiles();\n                }\n            }\n        }\n        return new HprofHeap(heapDump, segment, cacheDir);\n\n    }\n    \n    /**\n     * this method is used to get a total number of heap dumps (segments) in\n     * multi-dump file.\n     * <br>\n     * Speed: fast\n     * @param heap {@link Heap} instance, which part of multi-dump file\n     * @return if the heap is part of multi-dump file, returns number of heap\n     * dumps (segments) in multi-dump file, otherwise returns 1\n     * @throws IOException\n     */\n    public static int getTotalNumberOfSegments(Heap heap) throws IOException {\n        if (heap instanceof HprofHeap) {\n            return ((HprofHeap)heap).computeTotalNumberSegments();\n        }\n        return 1;\n    }\n\n    static Heap loadHeap(CacheDirectory cacheDir)\n                           throws FileNotFoundException, IOException {\n        File savedDump = cacheDir.getHeapDumpAuxFile();\n        InputStream is = new BufferedInputStream(new FileInputStream(savedDump), 64*1024);\n        try (DataInputStream dis = new DataInputStream(is)) {\n            return new HprofHeap(dis, cacheDir);\n        }\n    }\n\n    private HeapFactory() {\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HeapProgress.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicLong;\n\n\n/**\n * @author Tomas Hurka\n */\npublic final class HeapProgress {\n\n    public static final int PROGRESS_MAX = 1000;\n    private static ThreadLocal<ModelInfo> progressThreadLocal = new ThreadLocal<>();\n    private static Map<Long,ModelInfo> progresses = Collections.synchronizedMap(new HashMap<>());\n\n    private HeapProgress() {\n    }\n\n    public static long getProgressId() {\n        ModelInfo info = progressThreadLocal.get();\n\n        if (info == null) {\n            info = new ModelInfo();\n            progressThreadLocal.set(info);\n            progresses.put(info.progressId, info);\n        }\n        return info.progressId;\n    }\n\n    public static int getProgressValue(long progressId) {\n        ModelInfo info = progresses.get(progressId);\n        if (info != null) {\n            return info.value;\n        }\n        return -1;\n     }\n\n    static void progress(long counter, long startOffset, long value, long endOffset) {\n        // keep this method short so that it can be inlined\n        if (counter % 100000 == 0) {\n            progress(value, endOffset, startOffset);\n        }\n    }\n\n    static void progress(long value, long endValue) {\n        progress(value,0,value,endValue);\n    }\n\n    private static void progress(final long value, final long endOffset, final long startOffset) {\n        ModelInfo info = progressThreadLocal.get();\n        if (info != null) {\n            if (info.level>info.divider) {\n                info.divider = info.level;\n            }\n            long val = PROGRESS_MAX*(value - startOffset)/(endOffset - startOffset);\n            int modelVal = (int) (info.offset + val/info.divider);\n            info.value = modelVal;\n        }\n    }\n\n    private static int levelAdd(ModelInfo info, int diff) {\n        info.level+=diff;\n        return info.level;\n    }\n\n    static void progressStart() {\n        ModelInfo info = progressThreadLocal.get();\n        if (info != null) {\n            levelAdd(info, 1);\n        }\n    }\n\n    static void progressFinish() {\n        ModelInfo info = progressThreadLocal.get();\n        if (info != null) {\n            int level = levelAdd(info, -1);\n\n            assert level >= 0;\n            if (level == 0) {\n                progressThreadLocal.remove();\n                progresses.remove(info.progressId);\n            }\n            info.offset = info.value;\n        }\n    }\n    \n    private static class ModelInfo {\n        private static final AtomicLong PROGRESS_ID = new AtomicLong(0);\n\n        private final long progressId;\n        private int level;\n        private int divider;\n        private int offset;\n        private int value;\n\n        private ModelInfo() {\n            progressId = PROGRESS_ID.incrementAndGet();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HeapSummary.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n * This is optional summary information. It contains summary heap data and\n * time of the heap dump.\n * @author Tomas Hurka\n */\npublic interface HeapSummary {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * the time when the memory heap dump occurred.\n     * @return the time when the memory heap dump occurred in milliseconds since 0:00 GMT 1/1/1970\n     */\n    long getTime();\n\n    /**\n     * number of total bytes allocated on the heap during the run of JVM.\n     * Returned only if this summary information is available in heap dump.\n     * @return number of total allocated bytes on the heap during the run of JVM\n     * or -1 if the information is not available in the heap dump.\n     */\n    long getTotalAllocatedBytes();\n\n    /**\n     * number of all instances allocated on the heap during the run of JVM.\n     * Returned only if this summary information is available in heap dump.\n     * @return number of instances allocated on the heap during the run of JVM\n     * or -1 if the information is not available in the heap dump.\n     */\n    long getTotalAllocatedInstances();\n\n    /**\n     * number of total bytes allocated on the heap at the time of the heap dump.\n     * If this summary information is not available in heap dump, it is computed\n     * from the dump.\n     * @return number of total allocated bytes in the heap\n     */\n    long getTotalLiveBytes();\n\n    /**\n     * total number of instances allocated on the heap at the time of the heap dump.\n     * If this summary information is not available in heap dump, it is computed\n     * from the dump.\n     * @return number of total live instances in the heap\n     */\n    long getTotalLiveInstances();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofArrayValue.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofArrayValue extends HprofObject implements ArrayItemValue {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    final ClassDump dumpClass;\n    final int index;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HprofArrayValue(ClassDump cls, long offset, int number) {\n        // compute HprofArrayValue unique (file) offset.\n        // (+1) added to differ this instance with number == 0 from defining instance\n        super(offset + number + 1);\n        dumpClass = cls;\n        index = number;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Instance getDefiningInstance() {\n        return new ObjectArrayDump(dumpClass, getInstanceArrayOffset());\n    }\n\n    public int getIndex() {\n        return index;\n    }\n\n    public Instance getInstance() {\n        HprofHeap heap = dumpClass.getHprof();\n        HprofByteBuffer dumpBuffer = heap.dumpBuffer;\n        int idSize = dumpBuffer.getIDSize();\n\n        long instanceId = dumpBuffer.getID(getInstanceArrayOffset() + 1 + idSize + 4 + 4 + idSize + ((long)index * (long)idSize));\n\n        return heap.getInstanceByID(instanceId);\n    }\n\n    private long getInstanceArrayOffset() {\n        // see computation in super() above\n        return fileOffset - index - 1;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofByteBuffer.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Date;\nimport java.util.ResourceBundle;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nabstract class HprofByteBuffer {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // Magic header\n    static final String magic1 = \"JAVA PROFILE 1.0.1\"; // NOI18N\n    static final String magic2 = \"JAVA PROFILE 1.0.2\"; // NOI18N\n    static final String magic3 = \"JAVA PROFILE 1.0.3\"; // NOI18N\n    static final int JAVA_PROFILE_1_0_1 = 1;\n    static final int JAVA_PROFILE_1_0_2 = 2;\n    static final int JAVA_PROFILE_1_0_3 = 3;\n    static final int MINIMAL_SIZE = 30;\n    static final boolean DEBUG = false;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    int idSize;\n    int version;\n    long headerSize;\n    long length;\n    long time;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    static HprofByteBuffer createHprofByteBuffer(File dumpFile)\n                                          throws IOException {\n        long fileLen = dumpFile.length();\n\n        if (fileLen < MINIMAL_SIZE) {\n            String errText = ResourceBundle.getBundle(\"org/graalvm/visualvm/lib/jfluid/heap/Bundle\")\n                                           .getString(\"HprofByteBuffer_ShortFile\"); // NOI18N\n            throw new IOException(errText);\n        }\n\n        try {\n            if (fileLen < Integer.MAX_VALUE) {\n                return new HprofMappedByteBuffer(dumpFile);\n            } else {\n                return new HprofLongMappedByteBuffer(dumpFile);\n            }\n        } catch (IOException ex) {\n            if (ex.getCause() instanceof OutOfMemoryError) { // can happen on 32bit Windows, since there is only 2G for memory mapped data for whole java process.\n\n                return new HprofFileBuffer(dumpFile);\n            }\n\n            throw ex;\n        }\n    }\n\n    abstract char getChar(long index);\n\n    abstract double getDouble(long index);\n\n    abstract float getFloat(long index);\n\n    long getHeaderSize() {\n        return headerSize;\n    }\n\n    long getID(long offset) {\n        if (idSize == 4) {\n            return ((long)getInt(offset)) & 0xFFFFFFFFL;\n        } else if (idSize == 8) {\n            return getLong(offset);\n        }\n        assert false;\n\n        return -1;\n    }\n\n    int getIDSize() {\n        return idSize;\n    }\n\n    int getFoffsetSize() {\n        return length<Integer.MAX_VALUE ? 4 : 8;        \n    }\n    \n    abstract int getInt(long index);\n\n    abstract long getLong(long index);\n\n    abstract short getShort(long index);\n\n    long getTime() {\n        return time;\n    }\n\n    long capacity() {\n        return length;\n    }\n\n    abstract byte get(long index);\n\n    abstract void get(long position, byte[] chars);\n\n    final void readHeader() throws IOException {\n        long[] offset = new long[1];\n        String magic = readStringNull(offset, MINIMAL_SIZE);\n\n        if (DEBUG) {\n            System.out.println(\"Magic \" + magic); // NOI18N\n        }\n\n        if (magic1.equals(magic)) {\n            version = JAVA_PROFILE_1_0_1;\n        } else if (magic2.equals(magic)) {\n            version = JAVA_PROFILE_1_0_2;\n        } else if (magic3.equals(magic)) {\n            version = JAVA_PROFILE_1_0_3;\n        } else {\n            if (DEBUG) {\n                System.out.println(\"Invalid version\"); // NOI18N\n            }\n\n            String errText = ResourceBundle.getBundle(\"org/graalvm/visualvm/lib/jfluid/heap/Bundle\")\n                                           .getString(\"HprofByteBuffer_InvalidFormat\");\n            throw new IOException(errText);\n        }\n\n        idSize = getInt(offset[0]);\n        offset[0] += 4;\n        time = getLong(offset[0]);\n        offset[0] += 8;\n\n        if (DEBUG) {\n            System.out.println(\"ID \" + idSize); // NOI18N\n        }\n\n        if (DEBUG) {\n            System.out.println(\"Date \" + new Date(time).toString()); // NOI18N\n        }\n\n        headerSize = offset[0];\n    }\n\n    private String readStringNull(long[] offset, int len) {\n        StringBuilder s = new StringBuilder(20);\n        byte b = get(offset[0]++);\n\n        for (; (b > 0) && (s.length() < len); b = get(offset[0]++)) {\n            s.append((char) b);\n        }\n\n        return s.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofField.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofField extends HprofObject implements Field {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    ClassDump classDump;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HprofField(ClassDump cls, long offset) {\n        super(offset);\n        classDump = cls;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public JavaClass getDeclaringClass() {\n        return classDump;\n    }\n\n    public String getName() {\n        long nameID = classDump.getHprofBuffer().getID(fileOffset);\n\n        return classDump.getHprof().getStringSegment().getStringByID(nameID);\n    }\n\n    public boolean isStatic() {\n        return false;\n    }\n\n    public Type getType() {\n        return ObjectType.getType(getValueType());\n    }\n\n    int getValueSize() {\n        return classDump.getHprof().getValueSize(getValueType());\n    }\n\n    byte getValueType() {\n        HprofByteBuffer buffer = classDump.getHprofBuffer();\n\n        return buffer.get(fileOffset + buffer.getIDSize());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofFieldObjectValue.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofFieldObjectValue extends HprofFieldValue implements ObjectFieldValue {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HprofFieldObjectValue(ClassDump cls, long offset) {\n        super(cls, offset);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    long getInstanceID() {\n        HprofByteBuffer dumpBuffer = classDump.getHprofBuffer();\n        return dumpBuffer.getID(fileOffset + classDump.classDumpSegment.fieldValueOffset);\n    }\n\n    public Instance getInstance() {\n        return classDump.getHprof().getInstanceByID(getInstanceID());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofFieldValue.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofFieldValue extends HprofField implements FieldValue {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HprofFieldValue(ClassDump cls, long offset) {\n        super(cls, offset);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Instance getDefiningInstance() {\n        return classDump.getHprof().getInstanceByID(classDump.getJavaClassId());\n    }\n\n    public Field getField() {\n        return this;\n    }\n\n    public boolean isStatic() {\n        return true;\n    }\n\n    public String getValue() {\n        return getTypeValue().toString();\n    }\n\n    Object getTypeValue() {\n        HprofByteBuffer dumpBuffer = classDump.getHprofBuffer();\n        long position = fileOffset + classDump.classDumpSegment.fieldTypeOffset;\n        byte type = dumpBuffer.get(position);\n\n        return HprofInstanceValue.getTypeValue(dumpBuffer, position + 1, type);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofFileBuffer.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.EOFException;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofFileBuffer extends HprofByteBuffer {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final int MAX_bufferSizeBits = 17;\n    private static final int MIN_bufferSizeBits = 7;\n    private static final int MIN_bufferSize = 1 << MIN_bufferSizeBits;\n    private static final int MIN_bufferSizeMask = MIN_bufferSize - 1;\n    private static final int BUFFER_EXT = 8;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    RandomAccessFile fis;\n    private byte[] dumpBuffer;\n    private long bufferStartOffset;\n    private int bufferSizeBits;\n    private int bufferSize;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HprofFileBuffer(File dumpFile) throws IOException {\n        fis = new RandomAccessFile(dumpFile, \"r\");\n        length = fis.length();\n        bufferStartOffset = Long.MAX_VALUE;\n        readHeader();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    synchronized char getChar(long index) {\n        int i = loadBufferIfNeeded(index);\n        int ch1 = ((int) dumpBuffer[i++]) & 0xFF;\n        int ch2 = ((int) dumpBuffer[i]) & 0xFF;\n\n        return (char) ((ch1 << 8) + (ch2 << 0));\n    }\n\n    synchronized double getDouble(long index) {\n        int i = loadBufferIfNeeded(index);\n\n        return Double.longBitsToDouble(getLong(i));\n    }\n\n    synchronized float getFloat(long index) {\n        int i = loadBufferIfNeeded(index);\n\n        return Float.intBitsToFloat(getInt(i));\n    }\n\n    synchronized int getInt(long index) {\n        int i = loadBufferIfNeeded(index);\n        int ch1 = ((int) dumpBuffer[i++]) & 0xFF;\n        int ch2 = ((int) dumpBuffer[i++]) & 0xFF;\n        int ch3 = ((int) dumpBuffer[i++]) & 0xFF;\n        int ch4 = ((int) dumpBuffer[i]) & 0xFF;\n\n        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));\n    }\n\n    synchronized long getLong(long index) {\n        return ((long) (getInt(index)) << 32) + (getInt(index + 4) & 0xFFFFFFFFL);\n    }\n\n    synchronized short getShort(long index) {\n        int i = loadBufferIfNeeded(index);\n        int ch1 = ((int) dumpBuffer[i++]) & 0xFF;\n        int ch2 = ((int) dumpBuffer[i]) & 0xFF;\n\n        return (short) ((ch1 << 8) + (ch2 << 0));\n    }\n\n    // delegate to MappedByteBuffer    \n    synchronized byte get(long index) {\n        int i = loadBufferIfNeeded(index);\n\n        return dumpBuffer[i];\n    }\n\n    synchronized void get(long position, byte[] chars) {\n        int i = loadBufferIfNeeded(position);\n\n        if ((i + chars.length) < dumpBuffer.length) {\n            System.arraycopy(dumpBuffer, i, chars, 0, chars.length);\n        } else {\n            try {\n                fis.seek(position);\n                fis.readFully(chars);\n            } catch (IOException ex) {\n                ex.printStackTrace();\n            }\n        }\n    }\n\n    private void setBufferSize(long newBufferStart) {\n        if ((newBufferStart > bufferStartOffset) && (newBufferStart < (bufferStartOffset + (2 * bufferSize)))) { // sequential read -> increase buffer size\n\n            if (bufferSizeBits < MAX_bufferSizeBits) {\n                setBufferSize(bufferSizeBits + 1);\n            }\n        } else { // reset buffer size\n            setBufferSize(MIN_bufferSizeBits);\n        }\n    }\n\n    private void setBufferSize(int newBufferSizeBits) {\n        bufferSizeBits = newBufferSizeBits;\n        bufferSize = 1 << bufferSizeBits;\n        dumpBuffer = new byte[bufferSize + BUFFER_EXT];\n    }\n\n    private int loadBufferIfNeeded(long index) {\n        if ((index >= bufferStartOffset) && (index < (bufferStartOffset + bufferSize))) {\n            return (int) (index - bufferStartOffset);\n        }\n\n        long newBufferStart = index & ~MIN_bufferSizeMask;\n        setBufferSize(newBufferStart);\n\n        try {\n            fis.seek(newBufferStart);\n            fis.readFully(dumpBuffer);\n\n            //System.out.println(\"Reading at \"+newBufferStart+\" size \"+dumpBuffer.length+\" thread \"+Thread.currentThread().getName());\n        } catch (EOFException ex) {\n            // ignore\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n\n        bufferStartOffset = newBufferStart;\n\n        return (int) (index - bufferStartOffset);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofGCRoot.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofGCRoot extends HprofObject implements GCRoot {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static Map<Integer,String> kindMap;\n\n    static {\n        kindMap = new HashMap<>();\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_UNKNOWN), GCRoot.UNKNOWN);\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_JNI_GLOBAL), GCRoot.JNI_GLOBAL);\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_JNI_LOCAL), GCRoot.JNI_LOCAL);\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_JAVA_FRAME), GCRoot.JAVA_FRAME);\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_NATIVE_STACK), GCRoot.NATIVE_STACK);\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_STICKY_CLASS), GCRoot.STICKY_CLASS);\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_THREAD_BLOCK), GCRoot.THREAD_BLOCK);\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_MONITOR_USED), GCRoot.MONITOR_USED);\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_THREAD_OBJECT), GCRoot.THREAD_OBJECT);\n        // HPROF HEAP 1.0.3\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_INTERNED_STRING), GCRoot.INTERNED_STRING);\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_FINALIZING), GCRoot.FINALIZING);\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_DEBUGGER), GCRoot.DEBUGGER);\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_REFERENCE_CLEANUP), GCRoot.REFERENCE_CLEANUP);\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_VM_INTERNAL), GCRoot.VM_INTERNAL);\n        kindMap.put(Integer.valueOf(HprofHeap.ROOT_JNI_MONITOR), GCRoot.JNI_MONITOR);\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    HprofGCRoots roots;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HprofGCRoot(HprofGCRoots r, long offset) {\n        super(offset);\n        roots = r;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Instance getInstance() {\n        return roots.heap.getInstanceByID(getInstanceId());\n    }\n\n    public String getKind() {\n        int k = getHprofBuffer().get(fileOffset);\n\n        return kindMap.get(Integer.valueOf(k & 0xff));\n    }\n\n    long getInstanceId() {\n        return getHprofBuffer().getID(fileOffset + 1);\n    }\n    \n    HprofByteBuffer getHprofBuffer() {\n        return roots.heap.dumpBuffer;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofGCRoots.java",
    "content": "/*\n * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofGCRoots {\n\n    final HprofHeap heap;\n    final private Object threadSerialMapLock = new Object();\n    private ThreadMap threadSerialMap;\n    private int rootThreadsCount;\n    private Map<Long,Object> gcRoots;\n    final private Object gcRootLock = new Object();\n    private List<GCRoot> gcRootsList;\n\n    HprofGCRoots(HprofHeap h) {\n        heap = h;\n    }\n\n    List<GCRoot> getGCRoots() {\n        synchronized (gcRootLock) {\n            if (gcRoots == null) {\n                gcRoots = new HashMap<>(16384);\n                gcRootsList = new ArrayList<>(16384);\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_UNKNOWN));\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_JNI_GLOBAL));\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_JNI_LOCAL));\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_JAVA_FRAME));\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_NATIVE_STACK));\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_STICKY_CLASS));\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_THREAD_BLOCK));\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_MONITOR_USED));\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_THREAD_OBJECT));\n\n                // HPROF HEAP 1.0.3\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_INTERNED_STRING));\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_FINALIZING));\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_DEBUGGER));\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_REFERENCE_CLEANUP));\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_VM_INTERNAL));\n                computeGCRootsFor(heap.getHeapTagBound(HprofHeap.ROOT_JNI_MONITOR));\n\n                gcRootsList = Collections.unmodifiableList(gcRootsList);\n            }\n\n            return gcRootsList;\n        }\n    }\n    \n    Object getGCRoots(Long instanceId) {\n        synchronized (gcRootLock) {\n            if (gcRoots == null) {\n                heap.getGCRoots();\n            }\n\n            return gcRoots.get(instanceId);\n        }\n    }\n    \n    ThreadObjectGCRoot getThreadGCRoot(int threadSerialNumber) {\n        List<GCRoot> roots = getGCRoots();\n        synchronized (threadSerialMapLock) {\n            if (threadSerialMap == null) {\n                threadSerialMap = new ThreadMap(rootThreadsCount);\n            \n                for (int i = 0; i < roots.size(); i++) {\n                    GCRoot gcRoot = roots.get(i);\n                    if (gcRoot instanceof ThreadObjectHprofGCRoot) {\n                        threadSerialMap.putThreadIndex((ThreadObjectHprofGCRoot) gcRoot, i);\n                    }\n                }\n            }\n            int threadIndex = threadSerialMap.getThreadIndex(threadSerialNumber);\n\n            if (threadIndex != -1) {\n                return (ThreadObjectGCRoot)roots.get(threadIndex);\n            }\n            return null;\n        }\n    }\n    \n\n    private void computeGCRootsFor(TagBounds tagBounds) {\n        if (tagBounds != null) {\n            int rootTag = tagBounds.tag;\n            long[] offset = new long[] { tagBounds.startOffset };\n\n            while (offset[0] < tagBounds.endOffset) {\n                long start = offset[0];\n\n                if (heap.readDumpTag(offset) == rootTag) {\n                    HprofGCRoot root;\n                    if (rootTag == HprofHeap.ROOT_THREAD_OBJECT) {\n                        root = new ThreadObjectHprofGCRoot(this, start);\n                        rootThreadsCount++;\n                    } else if (rootTag == HprofHeap.ROOT_JAVA_FRAME) {\n                        root = new JavaFrameHprofGCRoot(this, start);\n                    } else if (rootTag == HprofHeap.ROOT_JNI_LOCAL) {\n                        root = new JniLocalHprofGCRoot(this, start);\n                    } else {\n                        root = new HprofGCRoot(this, start);\n                    }\n                    Long objectId = Long.valueOf(root.getInstanceId());\n                    Object val = gcRoots.get(objectId);\n                    if (val == null) {\n                        gcRoots.put(objectId, root);\n                    } else if (val instanceof GCRoot) {\n                        Collection<GCRoot> vals = new ArrayList<>(2);\n                        vals.add((GCRoot)val);\n                        vals.add(root);\n                        gcRoots.put(objectId, vals);\n                    } else {\n                        ((Collection)val).add(root);\n                    }\n                    gcRootsList.add(root);\n                }\n            }\n        }\n    }\n\n    private static class ThreadMap {\n        private final int[] serialMap;\n        // gracefully handle hprof dumps, which does not follow spec -\n        // thread serial number should be sequential starting from 1\n        private final Map<Integer,Integer> serialMapOverflow = new HashMap<>();\n\n        ThreadMap(int threadCount) {\n            serialMap = new int[threadCount+1];\n        }\n\n        private void putThreadIndex(ThreadObjectHprofGCRoot threadGCRoot, int index) {\n            int serialNum = threadGCRoot.getThreadSerialNumber();\n            if (serialNum < serialMap.length) {\n                serialMap[serialNum] = index;\n            } else {\n                serialMapOverflow.put(serialNum, index);\n            }\n        }\n\n        private int getThreadIndex(int serialNum) {\n            if (serialNum >= 0 && serialNum < serialMap.length) {\n                return serialMap[serialNum];\n            } else {\n                Integer threadIndexObj = serialMapOverflow.get(serialNum);\n                if (threadIndexObj == null) return -1;\n                return threadIndexObj.intValue();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofHeap.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.BufferedOutputStream;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.NoSuchElementException;\nimport java.util.Properties;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofHeap implements Heap {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // dump tags\n    static final int STRING = 1;\n    static final int LOAD_CLASS = 2;\n    private static final int UNLOAD_CLASS = 3;\n    static final int STACK_FRAME = 4;\n    static final int STACK_TRACE = 5;\n    private static final int ALLOC_SITES = 6;\n    static final int HEAP_SUMMARY = 7;\n    private static final int START_THREAD = 0xa;\n    private static final int END_THREAD = 0xb;\n    private static final int HEAP_DUMP = 0xc;\n    private static final int HEAP_DUMP_SEGMENT = 0x1c;\n    private static final int HEAP_DUMP_END = 0x2c;\n    private static final int CPU_SAMPLES = 0xd;\n    private static final int CONTROL_SETTINGS = 0xe;\n\n    // heap dump tags\n    static final int ROOT_UNKNOWN = 0xff;\n    static final int ROOT_JNI_GLOBAL = 1;\n    static final int ROOT_JNI_LOCAL = 2;\n    static final int ROOT_JAVA_FRAME = 3;\n    static final int ROOT_NATIVE_STACK = 4;\n    static final int ROOT_STICKY_CLASS = 5;\n    static final int ROOT_THREAD_BLOCK = 6;\n    static final int ROOT_MONITOR_USED = 7;\n    static final int ROOT_THREAD_OBJECT = 8;\n    static final int CLASS_DUMP = 0x20;\n    static final int INSTANCE_DUMP = 0x21;\n    static final int OBJECT_ARRAY_DUMP = 0x22;\n    static final int PRIMITIVE_ARRAY_DUMP = 0x23;\n\n    //  HPROF HEAP 1.0.3 tags\n    static final int HEAP_DUMP_INFO                = 0xfe;\n    static final int ROOT_INTERNED_STRING          = 0x89;\n    static final int ROOT_FINALIZING               = 0x8a;\n    static final int ROOT_DEBUGGER                 = 0x8b;\n    static final int ROOT_REFERENCE_CLEANUP        = 0x8c;\n    static final int ROOT_VM_INTERNAL              = 0x8d;\n    static final int ROOT_JNI_MONITOR              = 0x8e;\n    static final int UNREACHABLE                   = 0x90; /* deprecated */\n    static final int PRIMITIVE_ARRAY_NODATA_DUMP   = 0xc3;\n\n    // basic type\n    static final int OBJECT = 2;\n    static final int BOOLEAN = 4;\n    static final int CHAR = 5;\n    static final int FLOAT = 6;\n    static final int DOUBLE = 7;\n    static final int BYTE = 8;\n    static final int SHORT = 9;\n    static final int INT = 10;\n    static final int LONG = 11;\n    private static final boolean DEBUG = false;\n\n    private static final String SNAPSHOT_ID = \"NBPHD\";\n    private static final int SNAPSHOT_VERSION  = 5;\n    private static final String OS_PROP = \"os.name\";\n    \n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    HprofByteBuffer dumpBuffer;\n    LongMap idToOffsetMap;\n    private NearestGCRoot nearestGCRoot;\n    final HprofGCRoots gcRoots;\n    private ComputedSummary computedSummary;\n    private final Object computedSummaryLock = new Object();\n    private DominatorTree domTree;\n    private TagBounds allInstanceDumpBounds;\n    private TagBounds heapDumpSegment;\n    private TagBounds[] heapTagBounds;\n    private TagBounds[] tagBounds = new TagBounds[0xff];\n    private boolean instancesCountComputed;\n    private final Object instancesCountLock = new Object();\n    private boolean referencesComputed;\n    private final Object referencesLock = new Object();\n    private boolean retainedSizeComputed;\n    private final Object retainedSizeLock = new Object();\n    private boolean retainedSizeByClassComputed;\n    private final Object retainedSizeByClassLock = new Object();\n    private int idMapSize;\n    private int segment;\n\n    // for serialization\n    File heapDumpFile;\n    CacheDirectory cacheDirectory;\n    \n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HprofHeap(File dumpFile, int seg, CacheDirectory cacheDir) throws FileNotFoundException, IOException {\n        cacheDirectory = cacheDir;\n        dumpBuffer = cacheDir.createHprofByteBuffer(dumpFile);\n        segment = seg;\n        fillTagBounds(dumpBuffer.getHeaderSize());\n        heapDumpSegment = computeHeapDumpStart();\n\n        if (heapDumpSegment != null) {\n            fillHeapTagBounds();\n        }\n\n        idToOffsetMap = new LongMap(idMapSize,dumpBuffer.getIDSize(),dumpBuffer.getFoffsetSize(), cacheDirectory);\n        nearestGCRoot = new NearestGCRoot(this);\n        gcRoots = new HprofGCRoots(this);\n        heapDumpFile = dumpFile;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public List<JavaClass> getAllClasses() {\n        ClassDumpSegment classDumpBounds;\n\n        if (heapDumpSegment == null) {\n            return Collections.emptyList();\n        }\n\n        classDumpBounds = getClassDumpSegment();\n\n        if (classDumpBounds == null) {\n            return Collections.emptyList();\n        }\n\n        return classDumpBounds.createClassCollection();\n    }\n\n    public List<Instance> getBiggestObjectsByRetainedSize(int number) {\n        long[] ids;\n        List<Instance> bigObjects = new ArrayList<>(number);\n        \n        computeRetainedSize();\n        ids = idToOffsetMap.getBiggestObjectsByRetainedSize(number);\n        for (long id : ids) {\n            bigObjects.add(getInstanceByID(id));\n        }\n        return bigObjects;\n    }\n    \n    public Collection<GCRoot> getGCRoots(Instance instance) {\n       Long instanceId = Long.valueOf(instance.getInstanceId());\n       Object gcroot = gcRoots.getGCRoots(instanceId);\n       if (gcroot == null) {\n           return Collections.emptyList();\n       }\n       if (gcroot instanceof GCRoot) {\n           return Collections.singletonList((GCRoot)gcroot);\n       }\n       return Collections.unmodifiableCollection((Collection<GCRoot>)gcroot);\n    }\n\n    public Collection<GCRoot> getGCRoots() {\n        if (heapDumpSegment == null) {\n            return Collections.emptyList();\n        }\n        return gcRoots.getGCRoots();\n    }\n\n    public Instance getInstanceByID(long instanceID) {\n        if (instanceID == 0L) {\n            return null;\n        }\n\n        computeInstances();\n        LongMap.Entry entry = idToOffsetMap.get(instanceID);\n\n        if (entry == null) {\n            return null;\n        }\n        return getInstanceByOffset(new long[] {entry.getOffset()});\n    }\n\n    public JavaClass getJavaClassByID(long javaclassId) {\n        return getClassDumpSegment().getClassDumpByID(javaclassId);\n    }\n\n    public JavaClass getJavaClassByName(String fqn) {\n        if (heapDumpSegment == null) {\n            return null;\n        }\n        return getClassDumpSegment().getJavaClassByName(fqn);\n    }\n\n    public Collection<JavaClass> getJavaClassesByRegExp(String regexp) {\n        if (heapDumpSegment == null) {\n            return Collections.emptyList();\n        }\n        return getClassDumpSegment().getJavaClassesByRegExp(regexp);\n    }\n    \n    \n    private class InstancesIterator implements Iterator<Instance> {\n        private long[] offset;\n        private Instance nextInstance;\n        \n        private InstancesIterator() {\n            offset = new long[] { allInstanceDumpBounds.startOffset };\n        }\n\n        public boolean hasNext() {\n            while (offset[0] < allInstanceDumpBounds.endOffset && nextInstance == null) {\n                nextInstance = getInstanceByOffset(offset);\n            }\n            return nextInstance != null;\n        }\n\n        public Instance next() {\n            if (hasNext()) {\n                Instance ni = nextInstance;\n\n                nextInstance = null;\n                return ni;\n            }\n            throw new NoSuchElementException();\n        }\n    }\n        \n    public Iterator<Instance> getAllInstancesIterator() {\n        // make sure java classes are initialized\n        List<JavaClass> classes = getAllClasses();\n        if (classes.isEmpty()) {\n            return Collections.emptyIterator();\n        }\n        return new InstancesIterator();\n    }\n    \n    public HeapSummary getSummary() {\n        TagBounds summaryBound = tagBounds[HEAP_SUMMARY];\n\n        if (summaryBound != null) {\n            return new Summary(dumpBuffer, summaryBound.startOffset);\n        }\n\n        synchronized (computedSummaryLock) {\n            if (computedSummary == null) {\n                computedSummary = new ComputedSummary(this);\n            }\n        }\n\n        return computedSummary;\n    }\n\n    public Properties getSystemProperties() {\n        JavaClass systemClass = getJavaClassByName(\"java.lang.System\"); // NOI18N\n        if (systemClass != null) {\n            Instance props = (Instance) systemClass.getValueOfStaticField(\"props\"); //NOI18N\n\n            if (props == null) {\n                props = (Instance) systemClass.getValueOfStaticField(\"systemProperties\"); //NOI18N\n            }\n            if (props != null) {\n                return HprofProxy.getProperties(props);\n            }\n        }\n        // Substrate VM\n        systemClass = getJavaClassByName(\"com.oracle.svm.core.jdk.SystemPropertiesSupport\"); // NOI18N\n        if (systemClass != null) {\n            for (JavaClass propSupportSubClass : systemClass.getSubClasses()) {\n                List<Instance> propSupportInstances = propSupportSubClass.getInstances();\n\n                if (!propSupportInstances.isEmpty()) {\n                    Instance propSupportInstance = propSupportInstances.get(0);\n                    Object props = propSupportInstance.getValueOfField(\"properties\");   // NOI18N\n\n                    if (props instanceof Instance) {\n                        return HprofProxy.getProperties((Instance) props);\n                    }\n                }\n            }\n        }\n        return null;\n    }\n\n    public boolean isRetainedSizeComputed() {\n        return retainedSizeComputed;\n    }\n\n    public boolean isRetainedSizeByClassComputed() {\n        return retainedSizeByClassComputed;\n    }\n\n    //---- Serialization support\n    void writeToFile() {\n        if (!cacheDirectory.isTemporary()) {\n            try {\n                DataOutputStream out;\n                File outFile = cacheDirectory.getHeapDumpAuxFile();\n                out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(outFile), 32768));\n                writeToStream(out);\n                out.close();\n                cacheDirectory.setDirty(false);\n            } catch (IOException ex) {\n                ex.printStackTrace(System.err);\n            }\n        }\n    }\n    \n    void writeToStream(DataOutputStream out) throws IOException {\n        out.writeUTF(SNAPSHOT_ID);\n        out.writeInt(SNAPSHOT_VERSION);\n        out.writeUTF(heapDumpFile.getAbsolutePath());\n        out.writeLong(dumpBuffer.getTime());\n        out.writeUTF(System.getProperty(OS_PROP));\n        nearestGCRoot.writeToStream(out);\n        allInstanceDumpBounds.writeToStream(out);\n        heapDumpSegment.writeToStream(out);\n        TagBounds.writeToStream(heapTagBounds, out);\n        TagBounds.writeToStream(tagBounds, out);\n        out.writeBoolean(instancesCountComputed);\n        out.writeBoolean(referencesComputed);\n        out.writeBoolean(retainedSizeComputed);\n        out.writeBoolean(retainedSizeByClassComputed);\n        out.writeInt(idMapSize);\n        out.writeInt(segment);        \n        idToOffsetMap.writeToStream(out);\n        out.writeBoolean(domTree != null);\n        if (domTree != null) {\n            domTree.writeToStream(out);\n        }\n    }\n\n    HprofHeap(DataInputStream dis, CacheDirectory cacheDir) throws IOException {\n        if (cacheDir.isDirty()) {\n            throw new IOException(\"Dirty cache \"+cacheDir);\n        }\n        String id = dis.readUTF();\n        if (!SNAPSHOT_ID.equals(id)) {\n            throw new IOException(\"Invalid HPROF dump id \"+id);\n        }\n        int version = dis.readInt();\n        if (version != SNAPSHOT_VERSION) {\n            throw new IOException(\"Invalid HPROF version \"+SNAPSHOT_VERSION+\" loaded \"+version);            \n        }\n        heapDumpFile = cacheDir.getHeapFile(dis.readUTF());\n        cacheDirectory = cacheDir;\n        dumpBuffer = HprofByteBuffer.createHprofByteBuffer(heapDumpFile);\n        long time = dis.readLong();\n        if (time != dumpBuffer.getTime()) {\n            throw new IOException(\"HPROF time mismatch. Cached \"+time+\" from heap dump \"+dumpBuffer.getTime());\n        }\n        String os = dis.readUTF();\n        if (!os.equals(System.getProperty(OS_PROP))) {\n            System.err.println(\"Warning: HPROF OS mismatch. Cached \"+os+\" current OS \"+System.getProperty(OS_PROP));\n        }\n        nearestGCRoot = new NearestGCRoot(this, dis);\n        allInstanceDumpBounds = new TagBounds(dis);\n        heapDumpSegment = new TagBounds(dis);\n        heapTagBounds = new TagBounds[0x100];\n        TagBounds.readFromStream(dis, this, heapTagBounds);\n        TagBounds.readFromStream(dis, this, tagBounds);        \n        instancesCountComputed = dis.readBoolean();\n        referencesComputed = dis.readBoolean();\n        retainedSizeComputed = dis.readBoolean();\n        retainedSizeByClassComputed = dis.readBoolean();\n        idMapSize = dis.readInt();\n        segment = dis.readInt();\n        idToOffsetMap = new LongMap(dis, cacheDirectory);\n        if (dis.readBoolean()) {\n            domTree = new DominatorTree(this, dis);\n        }\n        gcRoots = new HprofGCRoots(this);\n        getClassDumpSegment().extractSpecialClasses();            \n    }\n    \n    ClassDumpSegment getClassDumpSegment() {\n        return (ClassDumpSegment) heapTagBounds[CLASS_DUMP];\n    }\n\n    LoadClassSegment getLoadClassSegment() {\n        return (LoadClassSegment) tagBounds[LOAD_CLASS];\n    }\n\n    StringSegment getStringSegment() {\n        return (StringSegment) tagBounds[STRING];\n    }\n    \n    StackTraceSegment getStackTraceSegment() {\n        return (StackTraceSegment) tagBounds[STACK_TRACE];\n    }\n    \n    StackFrameSegment getStackFrameSegment() {\n        return (StackFrameSegment) tagBounds[STACK_FRAME];\n    }\n    \n    TagBounds getAllInstanceDumpBounds() {\n        return allInstanceDumpBounds;\n    }\n    \n    long getRetainedSize(Instance instance) {\n        computeRetainedSize();\n        return idToOffsetMap.get(instance.getInstanceId()).getRetainedSize();\n    }\n\n    int getValueSize(final byte type) {\n        switch (type) {\n            case HprofHeap.OBJECT:\n                return dumpBuffer.getIDSize();\n            case HprofHeap.BOOLEAN:\n                return 1;\n            case HprofHeap.CHAR:\n                return 2;\n            case HprofHeap.FLOAT:\n                return 4;\n            case HprofHeap.DOUBLE:\n                return 8;\n            case HprofHeap.BYTE:\n                return 1;\n            case HprofHeap.SHORT:\n                return 2;\n            case HprofHeap.INT:\n                return 4;\n            case HprofHeap.LONG:\n                return 8;\n            default:\n                throw new IllegalArgumentException(\"Invalid type \" + type); // NOI18N\n        }\n    }\n\n    Instance getInstanceByOffset(long[] offset) {\n        return getInstanceByOffset(offset, null, -1);\n    }\n\n    Instance getInstanceByOffset(long[] offset, ClassDump instanceClassDump, long instanceClassId) {\n        long start = offset[0];\n        assert start != 0L;\n        ClassDump classDump;\n        ClassDumpSegment classDumpBounds = getClassDumpSegment();\n        int idSize = dumpBuffer.getIDSize();\n        int classIdOffset = 0;\n\n        int tag = readDumpTag(offset);\n\n        if (tag == INSTANCE_DUMP) {\n            classIdOffset = idSize + 4;\n        } else if (tag == OBJECT_ARRAY_DUMP) {\n            classIdOffset = idSize + 4 + 4;\n        } else if (tag == PRIMITIVE_ARRAY_DUMP) {\n            classIdOffset = idSize + 4 + 4;\n        }\n\n        if (tag == PRIMITIVE_ARRAY_DUMP) {\n            classDump = classDumpBounds.getPrimitiveArrayClass(dumpBuffer.get(start + 1 + classIdOffset));\n            if (instanceClassId != -1 && classDump.getJavaClassId() != instanceClassId) {\n                return null;\n            }\n\n            return new PrimitiveArrayDump(classDump, start);\n        } else {\n            long classId = dumpBuffer.getID(start + 1 + classIdOffset);\n            if (instanceClassId != -1 && classId != instanceClassId) {\n                return null;\n            }\n            if (instanceClassDump == null) {\n                classDump = classDumpBounds.getClassDumpByID(classId);\n            } else {\n                classDump = instanceClassDump;        \n            }\n        }\n\n        if (classDump == null) {\n            return null;\n        }\n        if (tag == INSTANCE_DUMP) {\n            return new InstanceDump(classDump, start);\n        } else if (tag == OBJECT_ARRAY_DUMP) {\n            return new ObjectArrayDump(classDump, start);\n        } else if (tag == CLASS_DUMP) {\n            return new ClassDumpInstance(classDump);\n        }\n        // other heap dump tags, ROOT_ etc.\n        return null;\n    }\n\n    void computeInstances() {\n        synchronized (instancesCountLock) {\n        if (instancesCountComputed) {\n            return;\n        }\n\n        HeapProgress.progressStart();\n        cacheDirectory.setDirty(true);\n        ClassDumpSegment classDumpBounds = getClassDumpSegment();\n        int idSize = dumpBuffer.getIDSize();\n        long[] offset = new long[] { allInstanceDumpBounds.startOffset };\n        Map<Long,JavaClass> classIdToClassMap = classDumpBounds.getClassIdToClassMap();\n\n        for (long counter = 0; offset[0] < allInstanceDumpBounds.endOffset; counter++) {\n            int classIdOffset = 0;\n            int instanceIdOffset = 0;\n            ClassDump classDump = null;\n            long start = offset[0];\n            int tag = readDumpTag(offset);\n            LongMap.Entry instanceEntry = null;\n\n            if (tag == INSTANCE_DUMP) {\n                instanceIdOffset = 1;\n                classIdOffset = idSize + 4;\n            } else if (tag == OBJECT_ARRAY_DUMP) {\n                instanceIdOffset = 1;\n                classIdOffset = idSize + 4 + 4;\n            } else if (tag == PRIMITIVE_ARRAY_DUMP) {\n                byte type = dumpBuffer.get(start + 1 + idSize + 4 + 4);\n                instanceIdOffset = 1;\n                classDump = classDumpBounds.getPrimitiveArrayClass(type);\n            }\n\n            if (instanceIdOffset != 0) {\n                long instanceId = dumpBuffer.getID(start + instanceIdOffset);\n                instanceEntry = idToOffsetMap.put(instanceId, start);\n            }\n\n            if (classIdOffset != 0) {\n                long classId = dumpBuffer.getID(start + 1 + classIdOffset);\n                classDump = (ClassDump) classIdToClassMap.get(new Long(classId));\n            }\n\n            if (classDump != null) {\n                classDump.registerInstance(start);\n                instanceEntry.setIndex(classDump.getInstancesCount());\n                classDumpBounds.addInstanceSize(classDump, tag, start);\n            }\n            HeapProgress.progress(counter,allInstanceDumpBounds.startOffset,start,allInstanceDumpBounds.endOffset);\n        }\n        instancesCountComputed = true;\n        writeToFile();\n        }\n        HeapProgress.progressFinish();\n    }\n\n    List<Value> findReferencesFor(long instanceId) {\n        assert instanceId != 0L : \"InstanceID is null\";\n        computeReferences();\n        \n        List<Value> refs = new ArrayList<>();\n        LongIterator refIdsIt = idToOffsetMap.get(instanceId).getReferences();\n        int idSize = dumpBuffer.getIDSize();\n        ClassDumpSegment classDumpBounds = getClassDumpSegment();\n        long[] offset = new long[1];\n        \n        while (refIdsIt.hasNext()) {\n            long foundInstanceId = refIdsIt.next();\n            offset[0] = idToOffsetMap.get(foundInstanceId).getOffset();\n            long start = offset[0];\n            int tag = readDumpTag(offset);\n\n            if (tag == INSTANCE_DUMP) {\n                int size = dumpBuffer.getInt(start + 1 + idSize + 4 + idSize);\n                byte[] fields = new byte[size];\n                dumpBuffer.get(start + 1 + idSize + 4 + idSize + 4, fields);\n                long classId = dumpBuffer.getID(start + 1 + idSize + 4);\n                ClassDump classDump = classDumpBounds.getClassDumpByID(classId);\n                InstanceDump instance = new InstanceDump(classDump, start);\n\n                for (Object field : instance.getFieldValues()) {\n                    if (field instanceof HprofInstanceObjectValue) {\n                        HprofInstanceObjectValue objectValue = (HprofInstanceObjectValue) field;\n\n                        if (objectValue.getInstanceId() == instanceId) {\n                            refs.add(objectValue);\n                        }\n                    }\n                }\n                if (refs.isEmpty() && classId == instanceId) {\n                    SyntheticClassField syntheticClassField = new SyntheticClassField(classDump);\n                    long fieldOffset = start + 1 + dumpBuffer.getIDSize() + 4;\n                    \n                    refs.add(new SyntheticClassObjectValue(instance,syntheticClassField,fieldOffset));\n                }\n            } else if (tag == OBJECT_ARRAY_DUMP) {\n                int elements = dumpBuffer.getInt(start + 1 + idSize + 4);\n                long classId = dumpBuffer.getID(start + 1 + idSize + 4 + 4);\n                ClassDump classDump = classDumpBounds.getClassDumpByID(classId);\n                long position = start + 1 + idSize + 4 + 4 + idSize;\n\n                for (int i = 0; i < elements; i++, position += idSize) {\n                    if (dumpBuffer.getID(position) == instanceId) {\n                        refs.add(new HprofArrayValue(classDump, start, i));\n                    }\n                }\n            } else if (tag == CLASS_DUMP) {\n                ClassDump cls = classDumpBounds.getClassDumpByID(foundInstanceId);\n                cls.findStaticReferencesFor(instanceId, refs);\n            }\n        }\n\n        return refs;\n    }\n\n    void computeReferences() {\n        synchronized (referencesLock) {\n        if (referencesComputed) {\n            return;\n        }\n\n        HeapProgress.progressStart();\n        ClassDumpSegment classDumpBounds = getClassDumpSegment();\n        int idSize = dumpBuffer.getIDSize();\n        long[] offset = new long[] { allInstanceDumpBounds.startOffset };\n        Map<Long,JavaClass> classIdToClassMap = classDumpBounds.getClassIdToClassMap();\n\n        computeInstances();\n        cacheDirectory.setDirty(true);\n        for (long counter=0; offset[0] < allInstanceDumpBounds.endOffset; counter++) {\n            long start = offset[0];\n            int tag = readDumpTag(offset);\n\n            if (tag == INSTANCE_DUMP) {\n                long classId = dumpBuffer.getID(start+1+idSize+4);\n                ClassDump classDump = (ClassDump) classIdToClassMap.get(new Long(classId));\n                if (classDump != null) {\n                    long instanceId = dumpBuffer.getID(start+1);\n                    long inOff = start+1+idSize+4+idSize+4;\n\n                    for (Field f : classDump.getAllInstanceFields()) {\n                        HprofField field = (HprofField)f;\n                        if (field.getValueType() == HprofHeap.OBJECT) {\n                            long outId = dumpBuffer.getID(inOff);\n\n                            if (outId != 0) {\n                                LongMap.Entry entry = idToOffsetMap.get(outId);\n                                if (entry != null) {\n                                    entry.addReference(instanceId);\n                                } else {\n                                    //    System.err.println(\"instance entry:\" + Long.toHexString(outId));\n                                }\n                            }\n                        }\n                        inOff += field.getValueSize();\n                    }\n                }\n            } else if (tag == OBJECT_ARRAY_DUMP) {\n                long instanceId = dumpBuffer.getID(start+1);\n                int elements = dumpBuffer.getInt(start+1+idSize+4);\n                long position = start+1+idSize+4+4+idSize;\n                \n                for(int i=0;i<elements;i++,position+=idSize) {\n                    long outId = dumpBuffer.getID(position);\n                    \n                    if (outId == 0) continue;\n                    LongMap.Entry entry = idToOffsetMap.get(outId);\n                    if (entry != null) {\n                        entry.addReference(instanceId);\n                    } else {\n                        //    System.err.println(\"bad array entry:\" + Long.toHexString(outId));\n                    }\n                }\n            }\n            HeapProgress.progress(counter,allInstanceDumpBounds.startOffset,start,allInstanceDumpBounds.endOffset);\n        }\n        \n        for (JavaClass cls : getClassDumpSegment().createClassCollection()) {\n            for (FieldValue field : cls.getStaticFieldValues()) {\n                if (field instanceof HprofFieldObjectValue) {\n                    long outId = ((HprofFieldObjectValue)field).getInstanceID();\n\n                    if (outId != 0) {\n                        LongMap.Entry entry = idToOffsetMap.get(outId);\n                        if (entry == null) {\n                            //    System.err.println(\"instance entry:\" + Long.toHexString(outId));\n                            continue;\n                        }\n                        entry.addReference(cls.getJavaClassId());\n                    }\n                }\n            }\n        }\n        idToOffsetMap.flush();\n        referencesComputed = true;\n        writeToFile();\n        }\n        HeapProgress.progressFinish();        \n    }\n    \n    void computeRetainedSize() {\n        synchronized (retainedSizeLock) {\n        if (retainedSizeComputed) {\n            return;\n        }\n        HeapProgress.progressStart();\n        LongBuffer leaves = nearestGCRoot.getLeaves();\n        cacheDirectory.setDirty(true);\n        new TreeObject(this,leaves).computeTrees();\n        domTree = new DominatorTree(this,nearestGCRoot.getMultipleParents());\n        domTree.computeDominators();\n\n        // deep path first\n        try {\n            LongBuffer deepPathBuffer = nearestGCRoot.getDeepPathBuffer();\n            LongBuffer deepPath = deepPathBuffer.revertBuffer();\n\n            deepPathBuffer.reset();\n            deepPathBuffer.delete();\n            if (deepPath.hasData()) {\n                for (long deepObjId = deepPath.readLong(); deepObjId != 0; deepObjId = deepPath.readLong()) {\n                    LongMap.Entry deepObjEntry = idToOffsetMap.get(deepObjId);\n                    assert deepObjEntry.isDeepObj();\n                    long idomId = domTree.getIdomId(deepObjId, deepObjEntry);\n                    LongMap.Entry idomEntry = idToOffsetMap.get(idomId);\n\n                    if (!deepObjEntry.isTreeObj()) {\n                        Instance deepInstance = getInstanceByID(deepObjId);\n                        long size = deepInstance.getSize();\n                        long origSize = deepObjEntry.getRetainedSize();\n\n                        if (origSize < 0) origSize = 0;\n                        deepObjEntry.setRetainedSize(origSize + size);\n                    }\n                    if (idomEntry.isDeepObj() && !idomEntry.isTreeObj()) {\n                        long origSize = idomEntry.getRetainedSize();\n                        if (origSize < 0) origSize = 0;\n                        idomEntry.setRetainedSize(origSize + deepObjEntry.getRetainedSize());\n                    }\n                }\n            }\n            deepPath.delete();\n        } catch (IOException ex) {\n            throw new IllegalArgumentException(ex.getLocalizedMessage(), ex);\n        }\n\n        long[] offset = new long[] { allInstanceDumpBounds.startOffset };\n\n        for (long counter=0; offset[0] < allInstanceDumpBounds.endOffset; counter++) {\n            int instanceIdOffset = 0;\n            long start = offset[0];\n            int tag = readDumpTag(offset);\n\n            if (tag == INSTANCE_DUMP) {\n                instanceIdOffset = 1;\n            } else if (tag == OBJECT_ARRAY_DUMP) {\n                instanceIdOffset = 1;\n            } else if (tag == PRIMITIVE_ARRAY_DUMP) {\n                instanceIdOffset = 1;\n            } else {\n                continue;\n            }\n            long instanceId = dumpBuffer.getID(start + instanceIdOffset);\n            LongMap.Entry instanceEntry = idToOffsetMap.get(instanceId);\n            long idom = domTree.getIdomId(instanceId,instanceEntry);\n            boolean isTreeObj = instanceEntry.isTreeObj();\n            boolean deepObj = instanceEntry.isDeepObj();\n            long instSize = 0;\n            \n            if (!deepObj && !isTreeObj && (instanceEntry.getNearestGCRootPointer() != 0 || gcRoots.getGCRoots(new Long(instanceId)) != null)) {\n                long origSize = instanceEntry.getRetainedSize();\n                if (origSize < 0) origSize = 0;\n                Instance instance = getInstanceByOffset(new long[] {start});\n                instSize = instance != null ? instance.getSize() : getClassDumpSegment().sizeSettings.getMinimumInstanceSize();\n                instanceEntry.setRetainedSize(origSize + instSize);\n            }\n            if (idom != 0) {\n                long size;\n                LongMap.Entry entry = idToOffsetMap.get(idom);\n                \n                if (entry.isDeepObj()) {\n                    continue;\n                } else if (isTreeObj) {\n                    size = instanceEntry.getRetainedSize();\n                } else if (deepObj) {\n                    size = instanceEntry.getRetainedSize();\n                } else {\n                    assert instSize != 0;\n                    size = instSize;\n                }\n                for (;idom!=0;idom=domTree.getIdomId(idom,entry)) {\n                    entry = idToOffsetMap.get(idom);\n                    if (entry.isTreeObj()) {\n                        break;\n                    }\n                    long retainedSize = entry.getRetainedSize();\n                    if (retainedSize < 0) retainedSize = 0;\n                    entry.setRetainedSize(retainedSize+size);\n                }\n            }\n            HeapProgress.progress(counter,allInstanceDumpBounds.startOffset,start,allInstanceDumpBounds.endOffset);\n        }\n        retainedSizeComputed = true;\n        writeToFile();\n        }\n        HeapProgress.progressFinish();\n    }\n\n    void computeRetainedSizeByClass() {\n        synchronized (retainedSizeByClassLock) {\n        if (retainedSizeByClassComputed) {\n            return;\n        }\n        computeRetainedSize();\n        cacheDirectory.setDirty(true);\n        HeapProgress.progressStart();\n        long[] offset = new long[] { allInstanceDumpBounds.startOffset };\n\n        for (long counter=0; offset[0] < allInstanceDumpBounds.endOffset; counter++) {\n            long start = offset[0];\n            int tag = readDumpTag(offset);\n\n            if (tag == INSTANCE_DUMP || tag == OBJECT_ARRAY_DUMP || tag == PRIMITIVE_ARRAY_DUMP) {\n                Instance i = getInstanceByOffset(new long[] {start});\n                if (i != null) {\n                    ClassDump javaClass = (ClassDump) i.getJavaClass();\n                    if (javaClass != null && !domTree.hasInstanceInChain(tag, i)) {\n                        javaClass.addSizeForInstance(i);\n                    }\n                }\n            }\n            HeapProgress.progress(counter,allInstanceDumpBounds.startOffset,start,allInstanceDumpBounds.endOffset);\n        }\n        // all done, release domTree\n        domTree = null;\n        retainedSizeByClassComputed = true;\n        writeToFile();\n        }\n        HeapProgress.progressFinish();\n    }\n\n    Instance getNearestGCRootPointer(Instance instance) {\n        return nearestGCRoot.getNearestGCRootPointer(instance);\n    }\n    \n    boolean isGCRoot(Instance instance) {\n       Long instanceId = Long.valueOf(instance.getInstanceId());\n       return gcRoots.getGCRoots(instanceId) != null;\n    }\n\n    int readDumpTag(long[] offset) {\n        long position = offset[0];\n        int dumpTag = dumpBuffer.get(position++) & 0xFF;\n        long size = 0;\n        long tagOffset = position;\n        int idSize = dumpBuffer.getIDSize();\n\n        switch (dumpTag) {\n            case -1:\n            case ROOT_UNKNOWN:\n\n                if (DEBUG) {\n                    System.out.println(\"Tag ROOT_UNKNOWN\"); // NOI18N\n                }\n\n                size = idSize;\n                dumpTag = ROOT_UNKNOWN;\n\n                break;\n            case ROOT_JNI_GLOBAL:\n\n                if (DEBUG) {\n                    System.out.println(\"Tag ROOT_JNI_GLOBAL\"); // NOI18N\n                }\n\n                size = 2 * idSize;\n\n                break;\n            case ROOT_JNI_LOCAL: {\n                if (DEBUG) {\n                    System.out.print(\"Tag ROOT_JNI_LOCAL\"); // NOI18N\n\n                    long objId = dumpBuffer.getID(position);\n                    position += idSize;\n\n                    int threadSerial = dumpBuffer.getInt(position);\n                    position += 4;\n\n                    int frameNum = dumpBuffer.getInt(position);\n                    position += 4;\n                    System.out.println(\" Object ID \" + objId + \" Thread serial \" + threadSerial + \" Frame num \" + frameNum); // NOI18N\n                }\n\n                size = idSize + (2 * 4);\n\n                break;\n            }\n            case ROOT_JAVA_FRAME:\n\n                if (DEBUG) {\n                    System.out.println(\"Tag ROOT_JAVA_FRAME\"); // NOI18N\n                    int threadSerial = dumpBuffer.getInt(position);\n                    position += 4;\n\n                    int frameNum = dumpBuffer.getInt(position);\n                    position += 4;\n                    System.out.println(\" Thread serial \" + threadSerial + \" Frame num \" + frameNum); // NOI18N\n                }\n\n                size = idSize + (2 * 4);\n\n                break;\n            case ROOT_NATIVE_STACK:\n\n                if (DEBUG) {\n                    System.out.println(\"Tag ROOT_NATIVE_STACK\"); // NOI18N\n                }\n\n                size = idSize + 4;\n\n                break;\n            case ROOT_STICKY_CLASS:\n\n                if (DEBUG) {\n                    System.out.println(\"Tag ROOT_STICKY_CLASS\"); // NOI18N\n                }\n\n                size = idSize;\n\n                break;\n            case ROOT_THREAD_BLOCK:\n\n                if (DEBUG) {\n                    System.out.println(\"Tag ROOT_THREAD_BLOCK\"); // NOI18N\n                }\n\n                size = idSize + 4;\n\n                break;\n            case ROOT_MONITOR_USED:\n\n                if (DEBUG) {\n                    System.out.println(\"Tag ROOT_MONITOR_USED\"); // NOI18N\n                }\n\n                size = idSize;\n\n                break;\n            case ROOT_THREAD_OBJECT:\n\n                if (DEBUG) {\n                    System.out.println(\"Tag ROOT_THREAD_OBJECT\"); // NOI18N\n                }\n\n                size = idSize + (2 * 4);\n\n                break;\n            case CLASS_DUMP: {\n                int constantSize = idSize + 4 + (6 * idSize) + 4;\n                int cpoolSize;\n                int sfSize;\n                int ifSize;\n\n                if (DEBUG) {\n                    System.out.println(\"Tag CLASS_DUMP, start offset \" + tagOffset); // NOI18N\n\n                    long classId = dumpBuffer.getID(position);\n                    position += idSize;\n\n                    int stackSerial = dumpBuffer.getInt(position);\n                    position += 4;\n\n                    long superId = dumpBuffer.getID(position);\n                    position += idSize;\n\n                    long classLoaderId = dumpBuffer.getID(position);\n                    position += idSize;\n\n                    long signersId = dumpBuffer.getID(position);\n                    position += idSize;\n\n                    long protDomainId = dumpBuffer.getID(position);\n                    position += idSize;\n                    dumpBuffer.getID(position);\n                    position += idSize;\n                    dumpBuffer.getID(position);\n                    position += idSize;\n\n                    int instSize = dumpBuffer.getInt(position);\n                    position += 4;\n                    offset[0] = position;\n                    cpoolSize = readConstantPool(offset);\n                    sfSize = readStaticFields(offset);\n                    ifSize = readInstanceFields(offset);\n                    System.out.println(\"ClassId \" + classId + \" stack Serial \" + stackSerial + \" Super ID \" + superId       // NOI18N\n                                       + \" ClassLoader ID \" + classLoaderId + \" signers \" + signersId + \" Protect Dom Id \"  // NOI18N\n                                       + protDomainId + \" Size \" + instSize);                                               // NOI18N\n                    System.out.println(\" Cpool \" + cpoolSize + \" Static fields \" + sfSize + \" Instance fileds \" + ifSize);  // NOI18N\n                } else {\n                    offset[0] = position + constantSize;\n                    cpoolSize = readConstantPool(offset);\n                    sfSize = readStaticFields(offset);\n                    ifSize = readInstanceFields(offset);\n                }\n                size = constantSize + cpoolSize + sfSize + ifSize;\n\n                break;\n            }\n            case INSTANCE_DUMP: {\n                int fieldSize;\n\n                if (DEBUG) {\n                    System.out.println(\"Tag INSTANCE_DUMP\"); // NOI18N\n\n                    long objId = dumpBuffer.getID(position);\n                    position += idSize;\n\n                    int stackSerial = dumpBuffer.getInt(position);\n                    position += 4;\n\n                    long classId = dumpBuffer.getID(position);\n                    position += idSize;\n                    fieldSize = dumpBuffer.getInt(position);\n                    position += 4;\n                    System.out.println(\"Obj ID \" + objId + \" Stack serial \" + stackSerial + \" Class ID \" + classId\n                                       + \" Field size \" + fieldSize); // NOI18N\n                } else {\n                    fieldSize = dumpBuffer.getInt(position + idSize + 4 + idSize);\n                }\n\n                size = idSize + 4 + idSize + 4 + fieldSize;\n\n                break;\n            }\n            case OBJECT_ARRAY_DUMP: {\n                long elements;\n\n                if (DEBUG) {\n                    System.out.println(\"Tag OBJECT_ARRAY_DUMP\"); // NOI18N\n\n                    long objId = dumpBuffer.getID(position);\n                    position += idSize;\n\n                    int stackSerial = dumpBuffer.getInt(position);\n                    position += 4;\n                    elements = dumpBuffer.getInt(position);\n                    position += 4;\n\n                    long classId = dumpBuffer.getID(position);\n                    position += idSize;\n\n                    int dataSize = 0;\n\n                    System.out.println(\"Obj ID \" + objId + \" Stack serial \" + stackSerial + \" Elements \" + elements // NOI18N\n                                           + \" Type \" + classId); // NOI18N\n\n                    for (int i = 0; i < elements; i++) {\n                        dataSize += dumpBuffer.getIDSize();\n                        System.out.println(\"Instance ID \" + dumpBuffer.getID(position)); // NOI18N\n                        position += idSize;\n                    }\n                } else {\n                    elements = dumpBuffer.getInt(position + idSize + 4);\n                }\n\n                size = idSize + 4 + 4 + idSize + (elements * idSize);\n\n                break;\n            }\n            case PRIMITIVE_ARRAY_DUMP: {\n                long elements;\n                byte type;\n\n                if (DEBUG) {\n                    System.out.println(\"Tag PRIMITINE_ARRAY_DUMP\"); // NOI18N\n\n                    long objId = dumpBuffer.getID(position);\n                    position += idSize;\n\n                    int stackSerial = dumpBuffer.getInt(position);\n                    position += 4;\n                    elements = dumpBuffer.getInt(position);\n                    position += 4;\n                    type = dumpBuffer.get(position++);\n\n                    int dataSize = 0;\n                    System.out.println(\"Obj ID \" + objId + \" Stack serial \" + stackSerial + \" Elements \" + elements + \" Type \" + type); // NOI18N\n\n                    for (int i = 0; i < elements; i++) {\n                        dataSize += getValueSize(type);\n                    }\n                } else {\n                    elements = dumpBuffer.getInt(position + idSize + 4);\n                    type = dumpBuffer.get(position + idSize + 4 + 4);\n                }\n\n                size = idSize + 4 + 4 + 1 + (elements * getValueSize(type));\n\n                break;\n            }\n            case HEAP_DUMP_SEGMENT: { // to handle big dumps\n                size = 4 + 4;\n\n                break;\n            }\n\n             /* HPROF HEAP 1.0.3 tags */\n            case HEAP_DUMP_INFO: {\n\n                if (DEBUG) {\n                    System.out.println(\"Tag HPROF_HEAP_DUMP_INFO\"); // NOI18N\n                    int heapId = dumpBuffer.getInt(position);\n                    position += 4;\n\n                    long stringID = dumpBuffer.getID(position);\n                    position += idSize;\n                    System.out.println(\" Dump info id \" + heapId + \" String ID \" + stringID); // NOI18N\n                }\n\n                size = 4 + idSize;\n\n                break;\n            }\n            case ROOT_INTERNED_STRING: {\n\n                if (DEBUG) {\n                    System.out.println(\"Tag HPROF_ROOT_INTERNED_STRING\"); // NOI18N\n                }\n\n                size = idSize;\n\n                break;\n          }\n            case ROOT_FINALIZING: {\n\n                if (DEBUG) {\n                    System.out.println(\"Tag HPROF_ROOT_FINALIZING\"); // NOI18N\n                }\n\n                size = idSize;\n\n                break;\n            }\n            case ROOT_DEBUGGER: {\n\n                if (DEBUG) {\n                    System.out.println(\"Tag HPROF_ROOT_DEBUGGER\"); // NOI18N\n                }\n\n                size = idSize;\n\n                break;\n            }\n            case ROOT_REFERENCE_CLEANUP: {\n\n                if (DEBUG) {\n                    System.out.println(\"Tag HPROF_ROOT_REFERENCE_CLEANUP\"); // NOI18N\n                }\n\n                size = idSize;\n\n                break;\n            }\n            case ROOT_VM_INTERNAL: {\n\n                if (DEBUG) {\n                    System.out.println(\"Tag HPROF_ROOT_VM_INTERNAL\"); // NOI18N\n                }\n\n                size = idSize;\n\n                break;\n            }\n            case ROOT_JNI_MONITOR: {\n\n                if (DEBUG) {\n                    System.out.println(\"Tag HPROF_ROOT_JNI_MONITOR\"); // NOI18N\n                }\n\n                size = idSize;\n\n                break;\n            }\n            case UNREACHABLE: {\n\n                if (DEBUG) {\n                    System.out.println(\"Tag HPROF_UNREACHABLE\"); // NOI18N\n                }\n\n                size = idSize;\n\n                break;\n            }\n            case PRIMITIVE_ARRAY_NODATA_DUMP: {\n                    throw new IllegalArgumentException(\n                        \"Don't know how to load a nodata array\");\n                //break;\n            }\n\n            default:throw new IllegalArgumentException(\"Invalid dump tag \" + dumpTag + \" at position \" + (position - 1)); // NOI18N              \n        }\n\n        offset[0] = tagOffset + size;\n\n        return dumpTag;\n    }\n\n    int readTag(long[] offset) {\n        long start = offset[0];\n        int tag = dumpBuffer.get(start);\n\n        //int time = dumpBuffer.getInt(start+1);\n        long len = dumpBuffer.getInt(start + 1 + 4) & 0xFFFFFFFFL;  // len is unsigned int\n         // only HEAP_DUMP_END can have zero length\n        if (len == 0 && tag != HEAP_DUMP_END && dumpBuffer.version != HprofByteBuffer.JAVA_PROFILE_1_0_3) {\n            // broken tag length\n            offset[0] = -1;\n        } else {\n            offset[0] = start + 1 + 4 + 4 + len;\n        }\n\n        return tag;\n    }\n\n    TagBounds getHeapTagBound(int heapTag) {\n        return heapTagBounds[heapTag];\n    }\n\n    /**\n     *\n     * @return number of microseconds since the time stamp in the header\n     */\n    long getHeapTime() {\n        if (heapDumpSegment == null) return 0;\n        return getTagTime(heapDumpSegment.startOffset);\n    }\n\n    private long getTagTime(long start) {\n        int time = dumpBuffer.getInt(start+1);\n        return time & 0xFFFFFFFFL; // time is unsigned int\n    }\n\n    private abstract class SegmentConsumer {\n        int i;\n        TagBounds heapDumpTag;\n\n        abstract boolean accept(long start, long end);\n    }\n\n    int computeTotalNumberSegments() throws IOException {\n        SegmentConsumer sc = new SegmentConsumer() {\n            boolean accept(long start, long end) {\n                i++;\n                return false;\n            }\n        };\n        heapDumpSegIterator(sc);\n        return sc.i;\n    }\n\n    private TagBounds computeHeapDumpStart() throws IOException {\n        SegmentConsumer sc = new SegmentConsumer() {\n            boolean accept(long start, long end) {\n                if (i++ == segment) {\n                    heapDumpTag = new TagBounds(HEAP_DUMP, start, end);\n                    return true;\n                }\n                return false;\n            }\n        };\n        heapDumpSegIterator(sc);\n        if (sc.heapDumpTag == null) {\n            throw new IOException(\"Invalid segment \" + segment); // NOI18N\n        }\n        return sc.heapDumpTag;\n    }\n\n    private void heapDumpSegIterator(SegmentConsumer sc) throws IOException {\n        TagBounds heapDumpBounds = tagBounds[HEAP_DUMP];\n\n        if (heapDumpBounds != null) {\n            long start = heapDumpBounds.startOffset;\n            long[] offset = new long[] { start };\n\n            for (;start < heapDumpBounds.endOffset; start = offset[0]) {\n                int tag = readTag(offset);\n\n                if (tag == HEAP_DUMP) {\n                    if (sc.accept(start,offset[0])) return;\n                }\n            }\n        } else {\n            TagBounds heapDumpSegmentBounds = tagBounds[HEAP_DUMP_SEGMENT];\n\n            if (heapDumpSegmentBounds != null) {\n                TagBounds heapDumpEndBounds = tagBounds[HEAP_DUMP_END];\n                if (heapDumpEndBounds == null) {\n                    throw new IOException(\"Heap dump is broken.\\nTag 0x\"+Integer.toHexString(HEAP_DUMP_END)+\" is missing.\"); // NOI18N\n                }\n                if (heapDumpSegmentBounds.endOffset == heapDumpEndBounds.startOffset) {\n                    // shortcut - just one segment\n                    sc.accept(heapDumpSegmentBounds.startOffset,heapDumpSegmentBounds.endOffset);\n                    return;\n                }\n                heapDumpSegmentBounds = heapDumpSegmentBounds.union(heapDumpEndBounds);\n                long start = heapDumpSegmentBounds.startOffset;\n                long[] offset = new long[] { start };\n                long segmentStart = 0;\n                long segmentEnd = 0;\n\n                for (;start < heapDumpSegmentBounds.endOffset; start = offset[0]) {\n                    int tag = readTag(offset);\n\n                    if (tag == HEAP_DUMP_SEGMENT) {\n                        if (segmentStart == 0) segmentStart = start;\n                        segmentEnd = offset[0];\n                    }\n                    if (tag == HEAP_DUMP_END) {\n                        if (sc.accept(segmentStart,segmentEnd)) return;\n                        segmentStart = 0;\n                    }\n                }\n            }\n        }\n    }\n\n    private void fillHeapTagBounds() {\n        if (heapTagBounds != null) {\n            return;\n        }\n\n        HeapProgress.progressStart();\n        heapTagBounds = new TagBounds[0x100];\n\n        long[] offset = new long[] { heapDumpSegment.startOffset + 1 + 4 + 4 };\n        \n        for (long counter=0; offset[0] < heapDumpSegment.endOffset; counter++) {\n            long start = offset[0];\n            int tag = readDumpTag(offset);\n            TagBounds bounds = heapTagBounds[tag];\n            long end = offset[0];\n\n            if (bounds == null) {\n                TagBounds newBounds;\n\n                if (tag == CLASS_DUMP) {\n                    newBounds = new ClassDumpSegment(this, start, end);\n                } else {\n                    newBounds = new TagBounds(tag, start, end);\n                }\n\n                heapTagBounds[tag] = newBounds;\n            } else {\n                bounds.endOffset = end;\n            }\n\n            if ((tag == CLASS_DUMP) || (tag == INSTANCE_DUMP) || (tag == OBJECT_ARRAY_DUMP) || (tag == PRIMITIVE_ARRAY_DUMP)) {\n                idMapSize++;\n            }\n            HeapProgress.progress(counter,heapDumpSegment.startOffset,start,heapDumpSegment.endOffset);\n        }\n\n        TagBounds instanceDumpBounds = heapTagBounds[INSTANCE_DUMP];\n        TagBounds objArrayDumpBounds = heapTagBounds[OBJECT_ARRAY_DUMP];\n        TagBounds primArrayDumpBounds = heapTagBounds[PRIMITIVE_ARRAY_DUMP];\n        if (instanceDumpBounds == null) {\n            instanceDumpBounds = new TagBounds(-1, heapDumpSegment.endOffset, heapDumpSegment.endOffset);\n        }\n        allInstanceDumpBounds = instanceDumpBounds.union(objArrayDumpBounds);\n        allInstanceDumpBounds = allInstanceDumpBounds.union(primArrayDumpBounds);\n        HeapProgress.progressFinish();\n    }\n\n    private void fillTagBounds(long tagStart) throws IOException {\n        long[] offset = new long[] { tagStart };\n\n        while (offset[0] < dumpBuffer.capacity()) {\n            long start = offset[0];\n            int tag = readTag(offset);\n            TagBounds bounds = tagBounds[tag];\n            long end = offset[0];\n\n            if (end == -1) {\n                // tag with zero-length -> broken heap dump\n                throw new IOException(\"Heap dump is broken.\\nTag 0x\"+Integer.toHexString(tag)+\" at offset \"+start+\" has zero length.\");\n            }\n            if (bounds == null) {\n                TagBounds newBounds;\n\n                if (tag == LOAD_CLASS) {\n                    newBounds = new LoadClassSegment(this, start, end);\n                } else if (tag == STRING) {\n                    newBounds = new StringSegment(this, start, end);\n                } else if (tag == STACK_TRACE) {\n                    newBounds = new StackTraceSegment(this, start, end);\n                } else if (tag == STACK_FRAME) {\n                    newBounds = new StackFrameSegment(this, start, end);\n                } else {\n                    newBounds = new TagBounds(tag, start, end);\n                }\n\n                tagBounds[tag] = newBounds;\n            } else {\n                bounds.endOffset = end;\n            }\n        }\n    }\n\n    private int readConstantPool(long[] offset) {\n        long start = offset[0];\n        int size = dumpBuffer.getShort(start);\n        offset[0] += 2;\n\n        for (int i = 0; i < size; i++) {\n            offset[0] += 2;\n            readValue(offset);\n        }\n\n        return (int) (offset[0] - start);\n    }\n\n    private int readInstanceFields(long[] offset) {\n        long position = offset[0];\n        int fields = dumpBuffer.getShort(offset[0]);\n        offset[0] += 2;\n\n        if (DEBUG) {\n            for (int i = 0; i < fields; i++) {\n                long nameId = dumpBuffer.getID(offset[0]);\n                offset[0] += dumpBuffer.getIDSize();\n\n                byte type = dumpBuffer.get(offset[0]++);\n                System.out.println(\"Instance field name ID \" + nameId + \" Type \" + type); // NOI18N\n            }\n        } else {\n            offset[0] += (fields * (dumpBuffer.getIDSize() + 1));\n        }\n\n        return (int) (offset[0] - position);\n    }\n\n    private int readStaticFields(long[] offset) {\n        long start = offset[0];\n        int fields = dumpBuffer.getShort(start);\n        offset[0] += 2;\n\n        int idSize = dumpBuffer.getIDSize();\n\n        for (int i = 0; i < fields; i++) {\n            if (DEBUG) {\n                long nameId = dumpBuffer.getID(offset[0]);\n                System.out.print(\"Static field name ID \" + nameId + \" \"); // NOI18N\n            }\n\n            offset[0] += idSize;\n\n            byte type = readValue(offset);\n        }\n\n        return (int) (offset[0] - start);\n    }\n\n    private byte readValue(long[] offset) {\n        byte type = dumpBuffer.get(offset[0]++);\n        offset[0] += getValueSize(type);\n\n        return type;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofInstanceObjectValue.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofInstanceObjectValue extends HprofInstanceValue implements ObjectFieldValue {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HprofInstanceObjectValue(InstanceDump i, HprofField f, long offset) {\n        super(i, f, offset);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Instance getInstance() {\n        return field.classDump.getHprof().getInstanceByID(getInstanceId());\n    }\n\n    long getInstanceId() {\n        HprofByteBuffer dumpBuffer = field.classDump.getHprofBuffer();\n\n        return dumpBuffer.getID(fileOffset);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofInstanceValue.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofInstanceValue extends HprofObject implements FieldValue {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    HprofField field;\n    long instanceOffset;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HprofInstanceValue(InstanceDump i, HprofField f, long fieldOffset) {\n        super(fieldOffset);\n        instanceOffset = i.fileOffset;\n        field = f;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Instance getDefiningInstance() {\n        return field.classDump.getHprof().getInstanceByOffset(new long[] {instanceOffset});\n    }\n\n    public Field getField() {\n        return field;\n    }\n\n    public String getValue() {\n        return getTypeValue().toString();\n    }\n\n    Object getTypeValue() {\n        byte type = field.getValueType();\n        HprofByteBuffer dumpBuffer = field.classDump.getHprofBuffer();\n\n        return getTypeValue(dumpBuffer, fileOffset, type);\n    }\n\n    static Object getTypeValue(final HprofByteBuffer dumpBuffer, final long position, final byte type) {\n        switch (type) {\n            case HprofHeap.OBJECT:\n\n                long obj = dumpBuffer.getID(position);\n\n                return new Long(obj);\n            case HprofHeap.BOOLEAN:\n\n                byte b = dumpBuffer.get(position);\n\n                return Boolean.valueOf(b != 0);\n            case HprofHeap.CHAR:\n\n                char ch = dumpBuffer.getChar(position);\n\n                return Character.valueOf(ch);\n            case HprofHeap.FLOAT:\n\n                float f = dumpBuffer.getFloat(position);\n\n                return new Float(f);\n            case HprofHeap.DOUBLE:\n\n                double d = dumpBuffer.getDouble(position);\n\n                return new Double(d);\n            case HprofHeap.BYTE:\n\n                byte bt = dumpBuffer.get(position);\n\n                return Byte.valueOf(bt);\n            case HprofHeap.SHORT:\n\n                short sh = dumpBuffer.getShort(position);\n\n                return Short.valueOf(sh);\n            case HprofHeap.INT:\n\n                int i = dumpBuffer.getInt(position);\n\n                return Integer.valueOf(i);\n            case HprofHeap.LONG:\n\n                long lg = dumpBuffer.getLong(position);\n\n                return Long.valueOf(lg);\n            default:\n                return \"Invalid type \" + type; // NOI18N\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofLongMappedByteBuffer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.nio.MappedByteBuffer;\nimport java.nio.channels.FileChannel;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofLongMappedByteBuffer extends HprofByteBuffer {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static int BUFFER_SIZE_BITS = 30;\n    private static long BUFFER_SIZE = 1L << BUFFER_SIZE_BITS;\n    private static int BUFFER_SIZE_MASK = (int) ((BUFFER_SIZE) - 1);\n    private static int BUFFER_EXT = 32 * 1024;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private MappedByteBuffer[] dumpBuffer;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HprofLongMappedByteBuffer(File dumpFile) throws IOException {\n        FileInputStream fis = new FileInputStream(dumpFile);\n        try (FileChannel channel = fis.getChannel()) {\n            length = channel.size();\n            dumpBuffer = new MappedByteBuffer[(int) (((length + BUFFER_SIZE) - 1) / BUFFER_SIZE)];\n\n            for (int i = 0; i < dumpBuffer.length; i++) {\n                long position = i * BUFFER_SIZE;\n                long size = Math.min(BUFFER_SIZE + BUFFER_EXT, length - position);\n                dumpBuffer[i] = channel.map(FileChannel.MapMode.READ_ONLY, position, size);\n            }\n        }\n        readHeader();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    char getChar(long index) {\n        return dumpBuffer[getBufferIndex(index)].getChar(getBufferOffset(index));\n    }\n\n    double getDouble(long index) {\n        return dumpBuffer[getBufferIndex(index)].getDouble(getBufferOffset(index));\n    }\n\n    float getFloat(long index) {\n        return dumpBuffer[getBufferIndex(index)].getFloat(getBufferOffset(index));\n    }\n\n    int getInt(long index) {\n        return dumpBuffer[getBufferIndex(index)].getInt(getBufferOffset(index));\n    }\n\n    long getLong(long index) {\n        return dumpBuffer[getBufferIndex(index)].getLong(getBufferOffset(index));\n    }\n\n    short getShort(long index) {\n        return dumpBuffer[getBufferIndex(index)].getShort(getBufferOffset(index));\n    }\n\n    // delegate to MappedByteBuffer        \n    byte get(long index) {\n        return dumpBuffer[getBufferIndex(index)].get(getBufferOffset(index));\n    }\n\n    synchronized void get(long position, byte[] chars) {\n        MappedByteBuffer buffer = dumpBuffer[getBufferIndex(position)];\n        buffer.position(getBufferOffset(position));\n        buffer.get(chars);\n    }\n\n    private int getBufferIndex(long index) {\n        return (int) (index >> BUFFER_SIZE_BITS);\n    }\n\n    private int getBufferOffset(long index) {\n        return (int) (index & BUFFER_SIZE_MASK);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofMappedByteBuffer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.nio.MappedByteBuffer;\nimport java.nio.channels.FileChannel;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofMappedByteBuffer extends HprofByteBuffer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private MappedByteBuffer dumpBuffer;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HprofMappedByteBuffer(File dumpFile) throws IOException {\n        FileInputStream fis = new FileInputStream(dumpFile);\n        try (FileChannel channel = fis.getChannel()) {\n            length = channel.size();\n            dumpBuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, length);\n        }\n        readHeader();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    char getChar(long index) {\n        return dumpBuffer.getChar((int) index);\n    }\n\n    double getDouble(long index) {\n        return dumpBuffer.getDouble((int) index);\n    }\n\n    float getFloat(long index) {\n        return dumpBuffer.getFloat((int) index);\n    }\n\n    int getInt(long index) {\n        return dumpBuffer.getInt((int) index);\n    }\n\n    long getLong(long index) {\n        return dumpBuffer.getLong((int) index);\n    }\n\n    short getShort(long index) {\n        return dumpBuffer.getShort((int) index);\n    }\n\n    // delegate to MappedByteBuffer\n    byte get(long index) {\n        return dumpBuffer.get((int) index);\n    }\n\n    synchronized void get(long position, byte[] chars) {\n        dumpBuffer.position((int) position);\n        dumpBuffer.get(chars);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofObject.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nabstract class HprofObject {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    final long fileOffset;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HprofObject(long offset) {\n        fileOffset = offset;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public boolean equals(Object obj) {\n        if (obj instanceof HprofObject) {\n            HprofObject hprofObject = (HprofObject) obj;\n\n            return hprofObject.fileOffset == fileOffset;\n        } else {\n            return false;\n        }\n    }\n\n    public int hashCode() {\n        return (int) (fileOffset ^ (fileOffset >>> 32));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofPrimitiveType.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofPrimitiveType implements PrimitiveType {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static Map<Integer,Type> primitiveTypeMap;\n\n    static {\n        primitiveTypeMap = new HashMap<>(10);\n        primitiveTypeMap.put(Integer.valueOf(HprofHeap.BOOLEAN), new HprofPrimitiveType(\"boolean\")); //NOI18N\n        primitiveTypeMap.put(Integer.valueOf(HprofHeap.CHAR), new HprofPrimitiveType(\"char\")); //NOI18N\n        primitiveTypeMap.put(Integer.valueOf(HprofHeap.FLOAT), new HprofPrimitiveType(\"float\")); //NOI18N\n        primitiveTypeMap.put(Integer.valueOf(HprofHeap.DOUBLE), new HprofPrimitiveType(\"double\")); //NOI18N\n        primitiveTypeMap.put(Integer.valueOf(HprofHeap.BYTE), new HprofPrimitiveType(\"byte\")); //NOI18N\n        primitiveTypeMap.put(Integer.valueOf(HprofHeap.SHORT), new HprofPrimitiveType(\"short\")); //NOI18N\n        primitiveTypeMap.put(Integer.valueOf(HprofHeap.INT), new HprofPrimitiveType(\"int\")); //NOI18N\n        primitiveTypeMap.put(Integer.valueOf(HprofHeap.LONG), new HprofPrimitiveType(\"long\")); //NOI18N\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private String typeName;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private HprofPrimitiveType(String name) {\n        typeName = name;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getName() {\n        return typeName;\n    }\n\n    static Type getType(byte type) {\n        return primitiveTypeMap.get(Integer.valueOf(type));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/HprofProxy.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.WeakHashMap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass HprofProxy {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    HprofProxy() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    static Properties getProperties(Instance propertiesInstance) {\n        Instance defaultsObj = (Instance) propertiesInstance.getValueOfField(\"defaults\"); // NOI18N\n        ObjectArrayDump entriesObj = (ObjectArrayDump) propertiesInstance.getValueOfField(\"table\"); // NOI18N\n        Properties props;\n\n        if (defaultsObj != null) {\n            props = new Properties(getProperties(defaultsObj));\n        } else {\n            props = new Properties();\n        }\n        if (entriesObj != null) {\n            return getPropertiesFromTable(entriesObj, props, \"key\", \"value\");   // NOI18N\n        } else {    // JDK 9\n            Instance map = (Instance) propertiesInstance.getValueOfField(\"map\"); // NOI18N\n            if (map != null) {\n                entriesObj = (ObjectArrayDump) map.getValueOfField(\"table\"); // NOI18N\n                if (entriesObj != null) {\n                    return getPropertiesFromTable(entriesObj, props, \"key\", \"val\"); // NOI18N\n                }\n            } else {    // old Hashtable\n                entriesObj = (ObjectArrayDump) propertiesInstance.getValueOfField(\"elementData\"); // NOI18N\n                if (entriesObj != null) {\n                    return getPropertiesFromTable(entriesObj, props, \"key\", \"value\");   // NOI18N\n                }\n            }\n        }\n        return null;\n    }\n\n    private static Properties getPropertiesFromTable(ObjectArrayDump entriesObj, Properties props, String keyName, String valueName) {\n        for (Instance entry : entriesObj.getValues()) {\n            for (; entry != null; entry = (Instance) entry.getValueOfField(\"next\")) { // NOI18N\n                Instance key = (Instance) entry.getValueOfField(keyName);\n                Instance val = (Instance) entry.getValueOfField(valueName);\n                if (key != null) {\n                    props.setProperty(getString(key), getString(val));\n                }\n            }\n        }\n        \n        return props;\n    }\n\n    static String getString(Instance stringInstance) {\n        if (stringInstance == null) {\n            return \"*null*\"; // NOI18N\n        }\n        String className = stringInstance.getJavaClass().getName();\n        if (String.class.getName().equals(className)) {\n            Byte coder = (Byte) stringInstance.getValueOfField(\"coder\"); // NOI18N\n            PrimitiveArrayDump chars = (PrimitiveArrayDump) stringInstance.getValueOfField(\"value\"); // NOI18N\n            if (chars != null) {\n                Integer offset = (Integer) stringInstance.getValueOfField(\"offset\"); // NOI18N\n                Integer len = (Integer) stringInstance.getValueOfField(\"count\"); // NOI18N\n                if (offset == null) {\n                    offset = Integer.valueOf(0);\n                }\n                if (len == null) {\n                    len = new Integer(chars.getLength());\n                }\n                char[] charArr = getChars(chars, coder, offset.intValue(), len.intValue());\n\n                return new String(charArr).intern();\n            }\n            return \"*null*\"; // NOI18N\n        }\n        // what? Non-string in system properties?\n        return \"*\"+className+\"#\"+stringInstance.getInstanceNumber()+\"*\";  // NOI18N\n    }\n\n    private static char[] getChars(PrimitiveArrayDump chars, Byte coder, int offset, int len) {\n        if (coder == null) {\n            return chars.getChars(offset, len);\n        }\n        int cdr = coder.intValue();\n        switch (cdr) {\n            case 0: {\n                char[] charArr = new char[len];\n                byte[] bytes = chars.getBytes(offset, len);\n                for (int i=0; i<bytes.length; i++) {\n                    charArr[i] = (char)(bytes[i] & 0xff);\n                }\n                return charArr;\n            }\n            case 1: {\n                final int HI_BYTE_SHIFT;\n                final int LO_BYTE_SHIFT;\n                int shifts[] = getStringUTF16ShiftBytes(chars.dumpClass.getHprof());\n                char[] charArr = new char[len/2];\n                byte[] bytes = chars.getBytes(offset, len);\n\n                HI_BYTE_SHIFT = shifts[0];\n                LO_BYTE_SHIFT = shifts[1];\n                for (int i=0; i<bytes.length; i+=2) {\n                    charArr[i/2] = (char) (((bytes[i] & 0xff) << HI_BYTE_SHIFT) |\n                      ((bytes[i+1] & 0xff) << LO_BYTE_SHIFT));\n                }\n                return charArr;\n            }\n            default:\n                return \"*unknown coder*\".toCharArray();\n        }\n    }\n\n    private static final Map<Heap,int[]> CACHE = new WeakHashMap<>();\n\n    private static int[] getStringUTF16ShiftBytes(Heap heap) {\n        int[] shiftBytes = CACHE.get(heap);\n        \n        if (shiftBytes == null) {\n            JavaClass utf16Class = heap.getJavaClassByName(\"java.lang.StringUTF16\");                  // NOI18N\n            Integer HI_BYTE_SHIFT = (Integer) utf16Class.getValueOfStaticField(\"HI_BYTE_SHIFT\");      // NOI18N\n            Integer LO_BYTE_SHIFT = (Integer) utf16Class.getValueOfStaticField(\"LO_BYTE_SHIFT\");      // NOI18N\n\n            if (HI_BYTE_SHIFT != null && LO_BYTE_SHIFT != null) {\n                shiftBytes = new int[] {HI_BYTE_SHIFT.intValue(), LO_BYTE_SHIFT.intValue()};\n            } else {\n                // use default\n                shiftBytes = new int[] {0, 8};\n            }\n            CACHE.put(heap, shiftBytes);\n        }\n        return shiftBytes;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/Instance.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.List;\n\n\n/**\n * This object represents one instance of java class.\n * @author Tomas Hurka\n */\npublic interface Instance {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * computes the list of instance field values. The order is: fields of this class followed by\n     * super class, etc.\n     * <br>\n     * Speed: normal\n     * @return list of {@link FieldValue} instance field values.\n     */\n    List<FieldValue> getFieldValues();\n\n    /**\n     * returns <CODE>true</CODE> if this is instance of GC root.\n     * <br>\n     * Speed: normal for first invocation, fast for subsequent\n     * @return <CODE>true</CODE> if this is instance of GC root, <CODE>false</CODE> otherwise.\n     */\n    boolean isGCRoot();\n\n    /**\n     * gets unique (in whole heap) ID of this {@link Instance}.\n     * <br>\n     * Speed: fast\n     * @return ID of this {@link Instance}\n     */\n    long getInstanceId();\n\n    /**\n     * gets unique number of this {@link Instance} among all instances of the same Java Class.\n     * Instances are numbered sequentially starting from 1.\n     * <br>\n     * Speed: fast\n     * @return unique number of this {@link Instance}\n     */\n    int getInstanceNumber();\n\n    /**\n     * returns corresponding {@link JavaClass} for this instance.\n     * <br>\n     * Speed: fast\n     * @return {@link JavaClass} of this instance.\n     */\n    JavaClass getJavaClass();\n\n    /**\n     * returns next {@link Instance} on the path to the nearest GC root.\n     * <br>\n     * Speed: first invocation is slow, all subsequent invocations are fast\n     * @return next {@link Instance} on the path to the nearest GC root, itself if the instance is GC root,\n     * <CODE>null</CODE> if path to the nearest GC root does not exist\n     */\n    Instance getNearestGCRootPointer();\n\n    long getReachableSize();\n\n    /**\n     * returns the list of references to this instance. The references can be of two kinds.\n     * The first one is from {@link ObjectFieldValue} and the second one if from {@link ArrayItemValue}\n     * <br>\n     * Speed: first invocation is slow, all subsequent invocations are fast\n     * @return list of {@link Value} representing all references to this instance\n     */\n    List<Value> getReferences();\n\n    long getRetainedSize();\n\n    /**\n     * returns the size of the {@link Instance} in bytes. If the instance is not\n     * {@link PrimitiveArrayInstance} or {@link ObjectArrayInstance} this size is\n     * equal to <CODE>getJavaClass().getInstanceSize()</CODE>.\n     * <br>\n     * Speed: fast\n     * @return size of this {@link Instance}\n     */\n    long getSize();\n\n    /**\n     * returns the list of static field values.\n     * This is delegated to {@link JavaClass#getStaticFieldValues()}\n     * <br>\n     * Speed: normal\n     * @return list of {@link FieldValue} static field values.\n     */\n    List<FieldValue> getStaticFieldValues();\n\n    /**\n     * Returns a value object that reflects the specified field of the instance\n     * represented by this {@link Instance} object. Fields are searched from the java.lang.Object.\n     * The first field with the matching name is used.\n     * The name parameter is a String that specifies the simple name of the desired field.\n     * <br>\n     * Speed: normal\n     * @param name the name of the field\n     * @return the value for the specified static field in this class.\n     * If a field with the specified name is not found <CODE>null</CODE> is returned.\n     * If the field.getType() is {@link Type} object {@link Instance} is returned as a field value,\n     * for primitive types its corresponding object wrapper (Boolean, Integer, Float, etc.) is returned.\n     */\n    Object getValueOfField(String name);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/InstanceDump.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass InstanceDump extends HprofObject implements Instance {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    final ClassDump dumpClass;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    InstanceDump(ClassDump cls, long offset) {\n        super(offset);\n        dumpClass = cls;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public List<FieldValue> getFieldValues() {\n        long offset = fileOffset + getInstanceFieldValuesOffset();\n        List<Field> fields = dumpClass.getAllInstanceFields();\n        List<FieldValue> values = new ArrayList<>(fields.size());\n\n        for (Field f : fields) {\n            HprofField field = (HprofField)f;\n\n            if (field.getValueType() == HprofHeap.OBJECT) {\n                values.add(new HprofInstanceObjectValue(this, field, offset));\n            } else {\n                values.add(new HprofInstanceValue(this, field, offset));\n            }\n\n            offset += field.getValueSize();\n        }\n\n        return values;\n    }\n\n    public boolean isGCRoot() {\n        return getHprof().isGCRoot(this);\n    }\n\n    public long getInstanceId() {\n        return dumpClass.getHprofBuffer().getID(fileOffset + 1);\n    }\n\n    public int getInstanceNumber() {\n        return getHprof().idToOffsetMap.get(getInstanceId()).getIndex();\n    }\n\n    public JavaClass getJavaClass() {\n        return dumpClass;\n    }\n\n    public Instance getNearestGCRootPointer() {\n        return getHprof().getNearestGCRootPointer(this);\n    }\n\n    public long getReachableSize() {\n        return 0;\n    }\n\n    public List<Value> getReferences() {\n        return getHprof().findReferencesFor(getInstanceId());\n    }\n\n    public long getRetainedSize() {\n        return getHprof().getRetainedSize(this);\n    }\n\n    public long getSize() {\n        return dumpClass.getInstanceSize();\n    }\n\n    public List<FieldValue> getStaticFieldValues() {\n        return dumpClass.getStaticFieldValues();\n    }\n\n    public Object getValueOfField(String name) {\n        List<FieldValue> fieldValues = getFieldValues();\n        \n        for (int i = fieldValues.size() - 1; i >= 0; i--) {\n            FieldValue fieldValue = fieldValues.get(i);\n            if (fieldValue.getField().getName().equals(name)) {\n                if (fieldValue instanceof HprofInstanceObjectValue) {\n                    return ((HprofInstanceObjectValue) fieldValue).getInstance();\n                } else {\n                    return ((HprofInstanceValue) fieldValue).getTypeValue();\n                }\n            }\n        }\n        \n        return null;\n        \n//        Iterator fIt = getFieldValues().iterator();\n//        FieldValue matchingFieldValue = null;\n//\n//        while (fIt.hasNext()) {\n//            FieldValue fieldValue = (FieldValue) fIt.next();\n//\n//            if (fieldValue.getField().getName().equals(name)) {\n//                matchingFieldValue = fieldValue;\n//            }\n//        }\n//\n//        if (matchingFieldValue == null) {\n//            return null;\n//        }\n//\n//        if (matchingFieldValue instanceof HprofInstanceObjectValue) {\n//            return ((HprofInstanceObjectValue) matchingFieldValue).getInstance();\n//        } else {\n//            return ((HprofInstanceValue) matchingFieldValue).getTypeValue();\n//        }\n    }\n\n    private int getInstanceFieldValuesOffset() {\n        int idSize = dumpClass.getHprofBuffer().getIDSize();\n\n        return 1 + idSize + 4 + idSize + 4;\n    }\n    \n    private HprofHeap getHprof() {\n        return dumpClass.getHprof();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/JavaClass.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.List;\n\n\n/**\n * This class represents java.lang.Class instances on the heap.\n * @author Tomas Hurka\n */\npublic interface JavaClass {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns a value object that reflects the specified static field of the class\n     * represented by this {@link JavaClass} object.\n     * The name parameter is a String that specifies the simple name of the desired static field.\n     * <br>\n     * Speed: normal\n     * @param name the name of the field\n     * @return the value for the specified static field in this class.\n     * If a static field with the specified name is not found <CODE>null</CODE> is returned.\n     * If the field.getType() is {@link Type} object {@link Instance} is returned as field value,\n     * for primitive types its corresponding object wrapper (Boolean, Integer, Float, etc.) is returned.\n     */\n    public Object getValueOfStaticField(String name);\n\n    /**\n     * returns the size of all instances in bytes. For non array classes\n     * this is computed as getInstancesCount()*getInstanceSize().\n     * Instance size of all instances is summed for arrays.\n     * <br>\n     * Speed: normal\n     * @return the size of all instances in bytes\n     */\n    long getAllInstancesSize();\n\n    /**\n     * returns true if this JavaClass represents array (for example: java.lang.String[]).\n     * <br>\n     * Speed: fast\n     * @return <CODE>true</CODE> if this class represents array, <CODE>false</CODE> otherwise\n     */\n    boolean isArray();\n\n    /**\n     * returns {@link Instance} representing class loader of this class.\n     * <br>\n     * Speed: fast\n     * @return class loader\n     */\n    Instance getClassLoader();\n\n    /**\n     * returns {@link ObjectArrayInstance} representing the signers of this class.\n     * <br>\n     * Speed: fast\n     * @return the signers of this class, or null if there are no signers. In\n     *          particular, this method returns null if this object represents\n     *          a primitive type or void.\n     */\n    ObjectArrayInstance getSigners();\n\n    /**\n     * returns {@link Instance} representing protection domain of this class.\n     * <br>\n     * Speed: fast\n     * @return the ProtectionDomain of this class\n     */\n    Instance getProtectionDomain();\n\n    /**\n     * returns List of instance fields of this {@link JavaClass}.\n     * <br>\n     * Speed: normal\n     * @return list of {@link Field} instance fields\n     */\n    List<Field> getFields();\n\n    /**\n     * returns the size of the {@link Instance} in bytes if this JavaClass does\n     * not represent array. For arrays -1 is returned\n     * <br>\n     * Speed: fast\n     * @return returns the size of the {@link Instance} in bytes, for arrays -1 is returned.\n     */\n    int getInstanceSize();\n\n    /**\n     * computes the list of all {@link Instance} of this class.\n     * The instances are ordered according to {@link Instance#getInstanceNumber()}\n     * <br>\n     * Speed: slow\n     * @return list {@link Instance} of instances\n     */\n    List<Instance> getInstances();\n\n   /**\n     * returns an iterator over the {@link Instance}es of this {@link JavaClass}. \n     * The instances are ordered according to {@link Instance#getInstanceNumber()}.\n     * <br>\n     * Speed: fast\n     *\n     * @return an <tt>Iterator</tt> over the {@link Instance}es of this {@link JavaClass}.\n     */\n    public Iterator<Instance> getInstancesIterator();\n\n    /**\n     * gets number of instances of this class.\n     * <br>\n     * Speed: first invocation is slow, all subsequent invocations are fast\n     * @return number of instances\n     */\n    int getInstancesCount();\n\n    /**\n     * gets sum of retained sizes of all class instances.\n     * <br>\n     * Speed: first invocation is slow, all subsequent invocations are fast\n     * @return sum of retained sizes of all class instances\n     */\n    long getRetainedSizeByClass();\n\n    /**\n     * gets unique (in whole heap) ID of this {@link JavaClass}.\n     * <br>\n     * Speed: fast\n     * @return ID of this {@link JavaClass}\n     */\n    long getJavaClassId();\n\n    /**\n     * return human readable name of the class.\n     * Innerclasses are separated by $. Anonymous classes uses $1 $2 etc.\n     * Arrays uses [] after the class or primitive type name\n     * <br>\n     * Speed: fast\n     * @return name of the class\n     */\n    String getName();\n\n    /**\n     * Returns a {@link Field} object that reflects the specified field of the class\n     * represented by this {@link JavaClass} object.\n     * The name parameter is a String that specifies the simple name of the desired field.\n     * <br>\n     * Speed: normal\n     * @param name the name of the field\n     * @return the {@link Field} object for the specified field in this class.\n     * If a field with the specified name is not found <CODE>null</CODE> is returned.\n     */\n\n    /*    public Field getField(String name); */\n    /**\n     * computes the list of instance field values. The order is fields of this class followed by\n     * super class, etc.\n     * <br>\n     * Speed: normal\n     * @return list of {@link FieldValue} instance field values.\n     */\n    List<FieldValue> getStaticFieldValues();\n\n    /**\n     * returns all subclasses of this class. This method works recursively\n     * so it returns also subclasses of subclasses etc.\n     * <br>\n     * Speed: slow\n     * @return returns the {@link Collection} of {@link JavaClass}.\n     */\n    Collection<JavaClass> getSubClasses();\n\n    /**\n     * returns {@link JavaClass} representing super class of this class.\n     * <br>\n     * Speed: fast\n     * @return super class (super class of java.lang.Object is null)\n     */\n    JavaClass getSuperClass();\n\n    /**\n     * returns {@link Heap} to which this {@link JavaClass} belongs.\n     * <br>\n     * Speed: fast\n     * @return heap\n     */\n    Heap getHeap();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/JavaFrameGCRoot.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n * This represents one Java Frame GC root. It has kind ({@link GCRoot#JAVA_FRAME}) and also corresponding\n * {@link Instance}, which is actual GC root and represent a local variable held on the stack.\n * @author Tomas Hurka\n */\npublic interface JavaFrameGCRoot extends GCRoot {\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * returns Thread root GC object for the thread where this local variable is held.\n     * <br>\n     * speed:normal\n     * @return {@link ThreadObjectGCRoot} for the corresponding thread.\n     */\n    ThreadObjectGCRoot getThreadGCRoot();\n\n    /**\n     * frame number in stack trace.\n     * <br>\n     * Speed:fast\n     * @return frame number in stack trace (-1 for empty)\n     */\n    int getFrameNumber();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/JavaFrameHprofGCRoot.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JavaFrameHprofGCRoot extends HprofGCRoot implements JavaFrameGCRoot {\n\n    JavaFrameHprofGCRoot(HprofGCRoots r, long offset) {\n        super(r, offset);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n\n\n    private int getThreadSerialNumber() {\n        return getHprofBuffer().getInt(fileOffset + 1 + getHprofBuffer().getIDSize());\n    }\n\n    public int getFrameNumber() {\n        return getHprofBuffer().getInt(fileOffset + 1 + getHprofBuffer().getIDSize() + 4);\n    }\n\n    public ThreadObjectGCRoot getThreadGCRoot() {\n        return roots.getThreadGCRoot(getThreadSerialNumber());\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/JniLocalGCRoot.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n * This represents one JNI Local GC root. It has kind ({@link GCRoot#JNI_LOCAL}) and also corresponding\n * {@link Instance}, which is actual GC root and represent a JNI local held on the stack.\n * @author Tomas Hurka\n */\npublic interface JniLocalGCRoot extends GCRoot {\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * returns Thread root GC object for the thread where this JNI local is held.\n     * <br>\n     * speed:normal\n     * @return {@link ThreadObjectGCRoot} for the corresponding thread.\n     */\n    ThreadObjectGCRoot getThreadGCRoot();\n\n    /**\n     * frame number in stack trace.\n     * <br>\n     * Speed:fast\n     * @return frame number in stack trace (-1 for empty)\n     */\n    int getFrameNumber();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/JniLocalHprofGCRoot.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass JniLocalHprofGCRoot extends HprofGCRoot implements JniLocalGCRoot {\n\n    JniLocalHprofGCRoot(HprofGCRoots r, long offset) {\n        super(r, offset);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n\n\n    private int getThreadSerialNumber() {\n        return getHprofBuffer().getInt(fileOffset + 1 + getHprofBuffer().getIDSize());\n    }\n\n    public int getFrameNumber() {\n        return getHprofBuffer().getInt(fileOffset + 1 + getHprofBuffer().getIDSize() + 4);\n    }\n\n    public ThreadObjectGCRoot getThreadGCRoot() {\n        return roots.getThreadGCRoot(getThreadSerialNumber());\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/LoadClass.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass LoadClass extends HprofObject {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final LoadClassSegment loadClassSegment;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    LoadClass(LoadClassSegment segment, long offset) {\n        super(offset);\n        loadClassSegment = segment;\n        assert getHprofBuffer().get(offset) == HprofHeap.LOAD_CLASS;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    long getClassObjectID() {\n        return getHprofBuffer().getID(fileOffset + loadClassSegment.classIDOffset);\n    }\n\n    String getName() {\n        return convertToName(getVMName());\n    }\n\n    long getNameID() {\n        return getHprofBuffer().getID(fileOffset + loadClassSegment.nameStringIDOffset);\n    }\n\n    String getVMName() {\n        StringSegment stringSegment = loadClassSegment.hprofHeap.getStringSegment();\n\n        return stringSegment.getStringByID(getNameID());\n    }\n\n    private HprofByteBuffer getHprofBuffer() {\n        return loadClassSegment.hprofHeap.dumpBuffer;\n    }\n\n    private static String convertToName(String vmName) {\n        String name = vmName.replace('/', '.'); // NOI18N\n        int i;\n\n        for (i = 0; i < name.length(); i++) {\n            if (name.charAt(i) != '[') { // NOI18N    // arrays\n                break;\n            }\n        }\n\n        if (i != 0) {\n            name = name.substring(i);\n\n            char firstChar = name.charAt(0);\n\n            if (firstChar == 'L') { // NOI18N      // object array\n                name = name.substring(1, name.length() - 1);\n            } else {\n                switch (firstChar) {\n                    case 'C':\n                        name = \"char\"; // NOI18N\n                        break;\n                    case 'B':\n                        name = \"byte\"; // NOI18N\n                        break;\n                    case 'I':\n                        name = \"int\"; // NOI18N\n                        break;\n                    case 'Z':\n                        name = \"boolean\"; // NOI18N\n                        break;\n                    case 'F':\n                        name = \"float\"; // NOI18N\n                        break;\n                    case 'D':\n                        name = \"double\"; // NOI18N\n                        break;\n                    case 'S':\n                        name = \"short\"; // NOI18N\n                        break;\n                    case 'J':\n                        name = \"long\"; // NOI18N\n                        break;\n                }\n            }\n\n            for (; i > 0; i--) {\n                name = name.concat(\"[]\"); // NOI18N\n            }\n        }\n\n        return name;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/LoadClassSegment.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass LoadClassSegment extends TagBounds {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    HprofHeap hprofHeap;\n    final int classIDOffset;\n    final int classSerialNumberOffset;\n    final int lengthOffset;\n    final int nameStringIDOffset;\n    final int stackTraceSerialOffset;\n    final int timeOffset;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    LoadClassSegment(HprofHeap heap, long start, long end) {\n        super(HprofHeap.LOAD_CLASS, start, end);\n\n        int idSize = heap.dumpBuffer.getIDSize();\n        hprofHeap = heap;\n        timeOffset = 1;\n        lengthOffset = timeOffset + 4;\n        classSerialNumberOffset = lengthOffset + 4;\n        classIDOffset = classSerialNumberOffset + 4;\n        stackTraceSerialOffset = classIDOffset + idSize;\n        nameStringIDOffset = stackTraceSerialOffset + 4;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    LoadClass getClassByID(long classObjectID) {\n        long[] offset = new long[] { startOffset };\n\n        while (offset[0] < endOffset) {\n            long start = offset[0];\n            long classID = readLoadClassID(offset);\n\n            if (classID == classObjectID) {\n                return new LoadClass(this, start);\n            }\n        }\n\n        return null;\n    }\n\n    LoadClass getClassBySerialNumber(int classSerialNumber) {\n        long[] offset = new long[] { startOffset };\n\n        while (offset[0] < endOffset) {\n            long start = offset[0];\n            int serial = readLoadClassSerialNumber(offset);\n\n            if (serial == classSerialNumber) {\n                return new LoadClass(this, start);\n            }\n        }\n\n        return null;\n    }\n    \n    void setLoadClassOffsets() {\n        ClassDumpSegment classDumpSegment = hprofHeap.getClassDumpSegment();\n        long[] offset = new long[] { startOffset };\n\n        while (offset[0] < endOffset) {\n            long start = offset[0];\n            long classID = readLoadClassID(offset);\n            ClassDump classDump = classDumpSegment.getClassDumpByID(classID);\n\n            if (classDump != null) {\n                classDump.setClassLoadOffset(start);\n            }\n        }\n    }\n\n    private HprofByteBuffer getDumpBuffer() {\n        HprofByteBuffer dumpBuffer = hprofHeap.dumpBuffer;\n\n        return dumpBuffer;\n    }\n\n    private int readLoadClassSerialNumber(long[] offset) {\n        long start = offset[0];\n\n        if (hprofHeap.readTag(offset) != HprofHeap.LOAD_CLASS) {\n            return 0;\n        }\n\n        return getDumpBuffer().getInt(start + classSerialNumberOffset);\n    }\n    \n    private long readLoadClassID(long[] offset) {\n        long start = offset[0];\n\n        if (hprofHeap.readTag(offset) != HprofHeap.LOAD_CLASS) {\n            return 0;\n        }\n\n        return getDumpBuffer().getID(start + classIDOffset);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/LongBuffer.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.EOFException;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\n\n\n/**\n * LongBuffer is a special kind of buffer for storing longs. It uses array of longs if there is only few longs\n * stored, otherwise longs are saved to backing temporary file.\n * @author Tomas Hurka\n */\nclass LongBuffer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private DataInputStream readStream;\n    private boolean readStreamClosed;\n    private DataOutputStream writeStream;\n    private File backingFile;\n    private long[] buffer;\n    private boolean useBackingFile;\n    private int bufferSize;\n    private int readOffset;\n    private int longs;\n    private CacheDirectory cacheDirectory;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    LongBuffer(int size, CacheDirectory cacheDir) {\n        buffer = new long[size];\n        cacheDirectory = cacheDir;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    void delete() {\n        if (backingFile != null) {\n            assert writeStream == null;\n            assert readStreamClosed || readStream == null;\n            backingFile.delete();\n            useBackingFile = false;\n            backingFile = null;\n            longs = 0;\n        }\n    }\n\n    boolean hasData() {\n        return longs > 0;\n    }\n\n    long readLong() throws IOException {\n        if (!useBackingFile) {\n            if (readOffset < bufferSize) {\n                return buffer[readOffset++];\n            } else {\n                return 0;\n            }\n        }\n        if (readStreamClosed) {\n            return 0;\n        }\n        try {\n            return readStream.readLong();\n        } catch (EOFException ex) {\n            readStreamClosed = true;\n            readStream.close();\n            return 0L;\n        }\n    }\n\n    void reset() throws IOException {\n        bufferSize = 0;\n        if (writeStream != null) {\n            writeStream.close();\n        }\n        if (readStream != null) {\n            readStream.close();\n        }\n        writeStream = null;\n        readStream = null;\n        readStreamClosed = false;\n        longs = 0;\n        useBackingFile = false;\n        readOffset = 0;\n    }\n\n    void startReading() throws IOException {\n        if (writeStream != null) {\n            writeStream.close();\n        }\n\n        writeStream = null;\n        rewind();\n    }\n\n    void rewind() {\n        readOffset = 0;\n\n        if (useBackingFile) {\n            try {\n                if (readStream != null) {\n                    readStream.close();\n                }\n                readStream = new DataInputStream(new BufferedInputStream(new FileInputStream(backingFile), buffer.length * Long.BYTES));\n                readStreamClosed = false;\n            } catch (IOException ex) {\n                ex.printStackTrace();\n            }\n        }\n    }\n\n    void writeLong(long data) throws IOException {\n        longs++;\n        if (bufferSize < buffer.length) {\n            buffer[bufferSize++] = data;\n            return;\n        }\n\n        if (backingFile == null) {\n            backingFile = cacheDirectory.createTempFile(\"NBProfiler\", \".gc\"); // NOI18N\n        }\n\n        if (writeStream == null) {\n            writeStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(backingFile), buffer.length * Long.BYTES));\n\n            for (long l : buffer) {\n                writeStream.writeLong(l);\n            }\n\n            useBackingFile = true;\n        }\n\n        writeStream.writeLong(data);\n    }\n    \n    LongBuffer revertBuffer() throws IOException {\n        LongBuffer reverted = new LongBuffer(buffer.length, cacheDirectory);\n        \n        if (bufferSize < buffer.length) {\n            for (int i=0;i<bufferSize;i++) {\n                reverted.writeLong(buffer[bufferSize - 1 - i]);\n            }\n        } else {\n            if (writeStream != null) writeStream.flush();\n            try (RandomAccessFile raf = new RandomAccessFile(backingFile,\"r\")) {\n                long offset = raf.length();\n                while(offset > 0) {\n                    offset-=8;\n                    raf.seek(offset);\n                    reverted.writeLong(raf.readLong());\n                }\n            }\n        }\n        reverted.startReading();\n        return reverted;\n    }\n    \n    int getSize() {\n        return longs;\n    }\n    \n    // serialization support\n    void writeToStream(DataOutputStream out) throws IOException {\n        out.writeInt(bufferSize);\n        out.writeInt(readOffset);\n        out.writeInt(longs);\n        out.writeInt(buffer.length);\n        out.writeBoolean(useBackingFile);\n        if (useBackingFile) {\n            if (writeStream != null) writeStream.flush();\n            out.writeUTF(backingFile.getAbsolutePath());\n        } else {\n            for (int i=0; i<bufferSize; i++) {\n                out.writeLong(buffer[i]);\n            }\n        }\n    }\n\n    LongBuffer(DataInputStream dis, CacheDirectory cacheDir) throws IOException {\n        bufferSize = dis.readInt();\n        readOffset = dis.readInt();\n        longs = dis.readInt();\n        buffer = new long[dis.readInt()];\n        useBackingFile = dis.readBoolean();\n        if (useBackingFile) {\n            backingFile = cacheDir.getCacheFile(dis.readUTF());\n        } else {\n            for (int i=0; i<bufferSize; i++) {\n                buffer[i] = dis.readLong();\n            }\n        }\n        cacheDirectory = cacheDir;\n    } \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/LongHashMap.java",
    "content": "/*\n * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.util.Arrays;\nimport java.util.Map;\n\n/**\n * Map for longs. IdentityHashMap was used as template.\n * Zero cannot be used as key. Load factor is 3/4.\n * @author Tomas Hurka\n */\nclass LongHashMap {\n    /**\n     * The initial capacity used by the no-args constructor.\n     * MUST be a power of two.\n     */\n    private static final int DEFAULT_CAPACITY = 32;\n\n    /**\n     * The minimum capacity, used if a lower value is implicitly specified\n     * by either of the constructors with arguments.  The value 4 corresponds\n     * to an expected maximum size of 2, given a load factor of 2/3.\n     * MUST be a power of two.\n     */\n    private static final int MINIMUM_CAPACITY = 4;\n\n    /**\n     * The maximum capacity, used if a higher value is implicitly specified\n     * by either of the constructors with arguments.\n     * MUST be a power of two <= 1<<29.\n     */\n    private static final int MAXIMUM_CAPACITY = 1 << 29;\n\n    /**\n     * The table, resized as necessary. Length MUST always be a power of two.\n     */\n    private transient long[] table;\n\n    /**\n     * The number of key-value mappings contained in this identity hash map.\n     *\n     * @serial\n     */\n    private int size;\n\n    /**\n     * The number of modifications, to support fast-fail iterators\n     */\n    private transient int modCount;\n\n    /**\n     * The next size value at which to resize (capacity * load factor).\n     */\n    private transient int threshold;\n\n    /**\n     * Constructs a new, empty identity hash map with a default expected\n     * maximum size.\n     */\n    LongHashMap() {\n        init(DEFAULT_CAPACITY);\n    }\n\n    /**\n     * Constructs a new, empty map with the specified expected maximum size.\n     * Putting more than the expected number of key-value mappings into\n     * the map may cause the internal data structure to grow, which may be\n     * somewhat time-consuming.\n     *\n     * @param expectedMaxSize the expected maximum size of the map\n     * @throws IllegalArgumentException if <tt>expectedMaxSize</tt> is negative\n     */\n    LongHashMap(int expectedMaxSize) {\n        if (expectedMaxSize < 0)\n            throw new IllegalArgumentException(\"expectedMaxSize is negative: \"\n                                               + expectedMaxSize);\n        init(capacity(expectedMaxSize));\n    }\n\n    /**\n     * Returns the appropriate capacity for the specified expected maximum\n     * size.  Returns the smallest power of two between MINIMUM_CAPACITY\n     * and MAXIMUM_CAPACITY, inclusive, that is greater than\n     * (4 * expectedMaxSize)/3, if such a number exists.  Otherwise\n     * returns MAXIMUM_CAPACITY.  If (4 * expectedMaxSize)/3 is negative, it\n     * is assumed that overflow has occurred, and MAXIMUM_CAPACITY is returned.\n     */\n    private int capacity(int expectedMaxSize) {\n        // Compute min capacity for expectedMaxSize given a load factor of 3/4\n        int minCapacity = (4 * expectedMaxSize)/3;\n\n        // Compute the appropriate capacity\n        int result;\n        if (minCapacity > MAXIMUM_CAPACITY || minCapacity < 0) {\n            result = MAXIMUM_CAPACITY;\n        } else {\n            result = MINIMUM_CAPACITY;\n            while (result < minCapacity)\n                result <<= 1;\n        }\n        return result;\n    }\n\n    /**\n     * Initializes object to be an empty map with the specified initial\n     * capacity, which is assumed to be a power of two between\n     * MINIMUM_CAPACITY and MAXIMUM_CAPACITY inclusive.\n     */\n    private void init(int initCapacity) {\n        assert (initCapacity & -initCapacity) == initCapacity; // power of 2\n        assert initCapacity >= MINIMUM_CAPACITY;\n        assert initCapacity <= MAXIMUM_CAPACITY;\n\n        threshold = (initCapacity * 3)/ 4;\n        table = new long[2 * initCapacity];\n    }\n\n    /**\n     * Returns the number of key-value mappings in this identity hash map.\n     *\n     * @return the number of key-value mappings in this map\n     */\n    int size() {\n        return size;\n    }\n\n    /**\n     * Returns <tt>true</tt> if this identity hash map contains no key-value\n     * mappings.\n     *\n     * @return <tt>true</tt> if this identity hash map contains no key-value\n     *         mappings\n     */\n    boolean isEmpty() {\n        return size == 0;\n    }\n\n    /**\n     * Returns index for Object x.\n     */\n    private static int hash(long x, int length) {\n        int h = (int)(x ^ (x >>> 32));\n        // This function ensures that hashCodes that differ only by\n        // constant multiples at each bit position have a bounded\n        // number of collisions (approximately 8 at default load factor).\n        h ^= (h >>> 20) ^ (h >>> 12);\n        h ^= (h >>> 7) ^ (h >>> 4);\n        return (h) & (length - 2);\n    }\n\n    /**\n     * Circularly traverses table of size len.\n     */\n    private static int nextKeyIndex(int i, int len) {\n        return (i + 2 < len ? i + 2 : 0);\n    }\n\n    /**\n     * Returns the value to which the specified key is mapped,\n     * or {@code null} if this map contains no mapping for the key.\n     *\n     * <p>More formally, if this map contains a mapping from a key\n     * {@code k} to a value {@code v} such that {@code (key == k)},\n     * then this method returns {@code v}; otherwise it returns\n     * {@code null}.  (There can be at most one such mapping.)\n     *\n     * <p>A return value of {@code null} does not <i>necessarily</i>\n     * indicate that the map contains no mapping for the key; it's also\n     * possible that the map explicitly maps the key to {@code null}.\n     * The {@link #containsKey containsKey} operation may be used to\n     * distinguish these two cases.\n     *\n     * @see #put(Object, Object)\n     */\n    long get(long key) {\n        long k = key;\n        long[] tab = table;\n        int len = tab.length;\n        int i = hash(k, len);\n        while (true) {\n            long item = tab[i];\n            if (item == k)\n                return tab[i + 1];\n            if (item == 0)\n                return -1;\n            i = nextKeyIndex(i, len);\n        }\n    }\n\n    /**\n     * Tests whether the specified object reference is a key in this identity\n     * hash map.\n     *\n     * @param   key   possible key\n     * @return  <code>true</code> if the specified object reference is a key\n     *          in this map\n     * @see     #containsValue(Object)\n     */\n    boolean containsKey(long key) {\n        long k = key;\n        long[] tab = table;\n        int len = tab.length;\n        int i = hash(k, len);\n        while (true) {\n            long item = tab[i];\n            if (item == k)\n                return true;\n            if (item == 0)\n                return false;\n            i = nextKeyIndex(i, len);\n        }\n    }\n\n    /**\n     * Tests whether the specified object reference is a value in this identity\n     * hash map.\n     *\n     * @param value value whose presence in this map is to be tested\n     * @return <tt>true</tt> if this map maps one or more keys to the\n     *         specified object reference\n     * @see     #containsKey(Object)\n     */\n    boolean containsValue(long value) {\n        long[] tab = table;\n        for (int i = 1; i < tab.length; i += 2)\n            if (tab[i] == value && tab[i - 1] != 0)\n                return true;\n\n        return false;\n    }\n\n    /**\n     * Tests if the specified key-value mapping is in the map.\n     *\n     * @param   key   possible key\n     * @param   value possible value\n     * @return  <code>true</code> if and only if the specified key-value\n     *          mapping is in the map\n     */\n    private boolean containsMapping(long key, long value) {\n        long k = key;\n        long[] tab = table;\n        int len = tab.length;\n        int i = hash(k, len);\n        while (true) {\n            long item = tab[i];\n            if (item == k)\n                return tab[i + 1] == value;\n            if (item == 0)\n                return false;\n            i = nextKeyIndex(i, len);\n        }\n    }\n\n    /**\n     * Associates the specified value with the specified key in this identity\n     * hash map.  If the map previously contained a mapping for the key, the\n     * old value is replaced.\n     *\n     * @param key the key with which the specified value is to be associated\n     * @param value the value to be associated with the specified key\n     * @return the previous value associated with <tt>key</tt>, or\n     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.\n     *         (A <tt>null</tt> return can also indicate that the map\n     *         previously associated <tt>null</tt> with <tt>key</tt>.)\n     * @see     Object#equals(Object)\n     * @see     #get(Object)\n     * @see     #containsKey(Object)\n     */\n    long put(long key, long value) {\n        assert key != 0;\n        assert value != -1;\n        long k = key;\n        long[] tab = table;\n        int len = tab.length;\n        int i = hash(k, len);\n\n        long item;\n        while ( (item = tab[i]) != 0) {\n            if (item == k) {\n                long oldValue = tab[i + 1];\n                tab[i + 1] = value;\n                return oldValue;\n            }\n            i = nextKeyIndex(i, len);\n        }\n\n        modCount++;\n        tab[i] = k;\n        tab[i + 1] = value;\n        if (++size >= threshold)\n            resize(len); // len == 2 * current capacity.\n        return -1;\n    }\n\n    /**\n     * Resize the table to hold given capacity.\n     *\n     * @param newCapacity the new capacity, must be a power of two.\n     */\n    private void resize(int newCapacity) {\n        // assert (newCapacity & -newCapacity) == newCapacity; // power of 2\n        int newLength = newCapacity * 2;\n\n        long[] oldTable = table;\n        int oldLength = oldTable.length;\n        if (oldLength == 2*MAXIMUM_CAPACITY) { // can't expand any further\n            if (threshold == MAXIMUM_CAPACITY-1)\n                throw new IllegalStateException(\"Capacity exhausted.\");\n            threshold = MAXIMUM_CAPACITY-1;  // Gigantic map!\n            return;\n        }\n        if (oldLength >= newLength)\n            return;\n\n        long[] newTable = new long[newLength];\n        threshold = (newCapacity * 3) / 4;\n\n        for (int j = 0; j < oldLength; j += 2) {\n            long key = oldTable[j];\n            if (key != 0) {\n                long value = oldTable[j+1];\n                int i = hash(key, newLength);\n                while (newTable[i] != 0)\n                    i = nextKeyIndex(i, newLength);\n                newTable[i] = key;\n                newTable[i + 1] = value;\n            }\n        }\n        table = newTable;\n    }\n\n    /**\n     * Copies all of the mappings from the specified map to this map.\n     * These mappings will replace any mappings that this map had for\n     * any of the keys currently in the specified map.\n     *\n     * @param m mappings to be stored in this map\n     * @throws NullPointerException if the specified map is null\n     */\n    void putAll(Map<Long,Long> m) {\n        int n = m.size();\n        if (n == 0)\n            return;\n        if (n > threshold) // conservatively pre-expand\n            resize(capacity(n));\n\n        for (Map.Entry<Long,Long> e : m.entrySet())\n            put(e.getKey(), e.getValue());\n    }\n\n    /**\n     * Removes the mapping for this key from this map if present.\n     *\n     * @param key key whose mapping is to be removed from the map\n     * @return the previous value associated with <tt>key</tt>, or\n     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.\n     *         (A <tt>null</tt> return can also indicate that the map\n     *         previously associated <tt>null</tt> with <tt>key</tt>.)\n     */\n    long remove(long key) {\n        long k = key;\n        long[] tab = table;\n        int len = tab.length;\n        int i = hash(k, len);\n\n        while (true) {\n            long item = tab[i];\n            if (item == k) {\n                modCount++;\n                size--;\n                long oldValue = tab[i + 1];\n                tab[i + 1] = 0;\n                tab[i] = 0;\n                closeDeletion(i);\n                return oldValue;\n            }\n            if (item == 0)\n                return -1;\n            i = nextKeyIndex(i, len);\n        }\n\n    }\n\n    /**\n     * Removes the specified key-value mapping from the map if it is present.\n     *\n     * @param   key   possible key\n     * @param   value possible value\n     * @return  <code>true</code> if and only if the specified key-value\n     *          mapping was in the map\n     */\n    private boolean removeMapping(long key, long value) {\n        long k = key;\n        long[] tab = table;\n        int len = tab.length;\n        int i = hash(k, len);\n\n        while (true) {\n            long item = tab[i];\n            if (item == k) {\n                if (tab[i + 1] != value)\n                    return false;\n                modCount++;\n                size--;\n                tab[i] = 0;\n                tab[i + 1] = 0;\n                closeDeletion(i);\n                return true;\n            }\n            if (item == 0)\n                return false;\n            i = nextKeyIndex(i, len);\n        }\n    }\n\n    /**\n     * Rehash all possibly-colliding entries following a\n     * deletion. This preserves the linear-probe\n     * collision properties required by get, put, etc.\n     *\n     * @param d the index of a newly empty deleted slot\n     */\n    private void closeDeletion(int d) {\n        // Adapted from Knuth Section 6.4 Algorithm R\n        long[] tab = table;\n        int len = tab.length;\n\n        // Look for items to swap into newly vacated slot\n        // starting at index immediately following deletion,\n        // and continuing until a null slot is seen, indicating\n        // the end of a run of possibly-colliding keys.\n        long item;\n        for (int i = nextKeyIndex(d, len); (item = tab[i]) != 0;\n             i = nextKeyIndex(i, len) ) {\n            // The following test triggers if the item at slot i (which\n            // hashes to be at slot r) should take the spot vacated by d.\n            // If so, we swap it in, and then continue with d now at the\n            // newly vacated i.  This process will terminate when we hit\n            // the null slot at the end of this run.\n            // The test is messy because we are using a circular table.\n            int r = hash(item, len);\n            if ((i < r && (r <= d || d <= i)) || (r <= d && d <= i)) {\n                tab[d] = item;\n                tab[d + 1] = tab[i + 1];\n                tab[i] = 0;\n                tab[i + 1] = 0;\n                d = i;\n            }\n        }\n    }\n\n    /**\n     * Removes all of the mappings from this map.\n     * The map will be empty after this call returns.\n     */\n    void clear() {\n        modCount++;\n        long[] tab = table;\n        Arrays.fill(tab, 0);\n        size = 0;\n    }\n\n    /**\n     * Compares the specified object with this map for equality.  Returns\n     * <tt>true</tt> if the given object is also a map and the two maps\n     * represent identical object-reference mappings.  More formally, this\n     * map is equal to another map <tt>m</tt> if and only if\n     * <tt>this.entrySet().equals(m.entrySet())</tt>.\n     *\n     * <p><b>Owing to the reference-equality-based semantics of this map it is\n     * possible that the symmetry and transitivity requirements of the\n     * <tt>Object.equals</tt> contract may be violated if this map is compared\n     * to a normal map.  However, the <tt>Object.equals</tt> contract is\n     * guaranteed to hold among <tt>LongHashMap</tt> instances.</b>\n     *\n     * @param  o object to be compared for equality with this map\n     * @return <tt>true</tt> if the specified object is equal to this map\n     * @see Object#equals(Object)\n     */\n    @Override\n    public boolean equals(Object o) {\n        if (o == this) {\n            return true;\n        } else if (o instanceof LongHashMap) {\n            LongHashMap m = (LongHashMap) o;\n            if (m.size() != size)\n                return false;\n\n            long[] tab = m.table;\n            for (int i = 0; i < tab.length; i+=2) {\n                long k = tab[i];\n                if (k != 0 && !containsMapping(k, tab[i + 1]))\n                    return false;\n            }\n            return true;\n        } else {\n            return false;  // o is not a LongHashMap\n        }\n    }\n\n    /**\n     * Returns the hash code value for this map.  The hash code of a map is\n     * defined to be the sum of the hash codes of each entry in the map's\n     * <tt>entrySet()</tt> view.  This ensures that <tt>m1.equals(m2)</tt>\n     * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two\n     * <tt>IdentityHashMap</tt> instances <tt>m1</tt> and <tt>m2</tt>, as\n     * required by the general contract of {@link Object#hashCode}.\n     *\n     * <p><b>Owing to the reference-equality-based semantics of the\n     * <tt>Map.Entry</tt> instances in the set returned by this map's\n     * <tt>entrySet</tt> method, it is possible that the contractual\n     * requirement of <tt>Object.hashCode</tt> mentioned in the previous\n     * paragraph will be violated if one of the two objects being compared is\n     * an <tt>LongHashMap</tt> instance and the other is a normal map.</b>\n     *\n     * @return the hash code value for this map\n     * @see Object#equals(Object)\n     * @see #equals(Object)\n     */\n    @Override\n    public int hashCode() {\n        int result = 0;\n        long[] tab = table;\n        for (int i = 0; i < tab.length; i +=2) {\n            long key = tab[i];\n            if (key != 0) {\n                long k = key;\n                result += hash(k,tab.length) ^\n                          hash(tab[i + 1],tab.length);\n            }\n        }\n        return result;\n    }\n\n    //---- Serialization support\n    void writeToStream(DataOutputStream out) throws IOException {\n        out.writeInt(modCount);\n        out.writeInt(size);\n        out.writeInt(threshold);\n        out.writeInt(table.length);\n        for (long l : table) {\n            out.writeLong(l);\n        }\n    }\n\n    LongHashMap(DataInputStream dis) throws IOException {\n        modCount = dis.readInt();\n        size = dis.readInt();\n        threshold = dis.readInt();\n        table = new long[dis.readInt()];\n        for (int i = 0; i < table.length; i++) {\n            table[i] = dis.readLong();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/LongIterator.java",
    "content": "/*\n * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.NoSuchElementException;\n\n/**\n *\n * @author Tomas Hurka\n */\nabstract class LongIterator {\n\n    static LongIterator EMPTY_ITERATOR = new Empty();\n\n    static LongIterator singleton(long i) {\n        return new Singleton(i);\n    }\n\n    abstract boolean hasNext();\n\n    abstract long next();\n\n    private static class Empty extends LongIterator {\n\n        @Override\n        boolean hasNext() {\n            return false;\n        }\n\n        @Override\n        long next() {\n            throw new NoSuchElementException();\n        }\n    }\n\n    private static class Singleton extends LongIterator {\n\n        private final long item;\n        private boolean skipped;\n\n        private Singleton(long i) {\n            item = i;\n        }\n\n        @Override\n        boolean hasNext() {\n            return !skipped;\n        }\n\n        @Override\n        long next() {\n            if (hasNext()) {\n                skipped = true;\n                return item;\n            }\n            throw new NoSuchElementException();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/LongMap.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.util.SortedSet;\nimport java.util.TreeSet;\n\n/**\n * key - ID (long/int) of heap object\n * value (8/4) + 4 + 1 + (8/4)\n *  - offset (long/int) to dump file\n *  - instance index (int) - unique number of this {@link Instance} among all instances of the same Java Class\n *  - references flags (byte) - bit 0 set - has zero or one reference,\n *                            - bit 1 set - has GC root\n *                            - bit 2 set - tree object\n *                            - bit 3 set - deep object\n *  - ID/offset (long/int) - ID if reference flag bit 0 is set, otherwise offset to reference list file\n *  - retained size (long/int)\n *\n * @author Tomas Hurka\n */\nclass LongMap extends AbstractLongMap {\n\n    private NumberList referenceList;\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    class Entry extends AbstractLongMap.Entry {\n\n        private static final byte NUMBER_LIST = 1;\n        private static final byte GC_ROOT = 2;\n        private static final byte TREE_OBJ = 4;\n        private static final byte DEEP_OBJ = 8;\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private long offset;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        private Entry(long off) {\n            offset = off;\n        }\n\n        private Entry(long off,long value) {\n            offset = off;\n            putFoffset(offset, KEY_SIZE, value);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        void setIndex(int index) {\n            dumpBuffer.putInt(offset, KEY_SIZE + FOFFSET_SIZE, index);\n        }\n\n        int getIndex() {\n            return dumpBuffer.getInt(offset, KEY_SIZE + FOFFSET_SIZE);\n        }\n\n        void setTreeObj() {\n            byte flags = (byte)(getFlags() | TREE_OBJ);\n            setFlags(flags);\n        }\n        \n        boolean isTreeObj() {\n            return (getFlags() & TREE_OBJ) != 0;\n        }\n\n        void setDeepObj() {\n            byte flags = (byte)(getFlags() | DEEP_OBJ);\n            setFlags(flags);\n        }\n\n        boolean isDeepObj() {\n            return (getFlags() & DEEP_OBJ) != 0;\n        }\n\n        boolean hasOnlyOneReference() {\n            return (getFlags() & NUMBER_LIST) == 0;\n        }\n        \n        void setNearestGCRootPointer(long instanceId) {\n            byte flags = (byte)(getFlags() | GC_ROOT);\n            setFlags(flags);\n            if ((flags & NUMBER_LIST) != 0) {   // put GC root pointer on the first place in references list\n                try {\n                    referenceList.putFirst(getReferencesPointer(),instanceId);\n                } catch (IOException ex) {\n                    ex.printStackTrace();\n                }\n            }\n        }\n\n        long getNearestGCRootPointer() {\n            try {\n                byte flag = getFlags();\n                if ((flag & GC_ROOT) != 0) { // has GC root pointer\n                    long ref = getReferencesPointer();\n                    if ((flag & NUMBER_LIST) != 0) { // get GC root pointer from number list\n                        return referenceList.getFirstNumber(ref);\n                    }\n                    return ref;\n                }\n            } catch (IOException ex) {\n                ex.printStackTrace();\n            }\n            return 0L;\n        }\n        \n        void addReference(long instanceId) {\n            try {\n                byte flags = getFlags();\n                long ref = getReferencesPointer();\n                if ((flags & NUMBER_LIST) == 0) { // reference list is not used\n                    if (ref == 0L) {    // no reference was set\n                        setReferencesPointer(instanceId);\n                    } else if (ref != instanceId) {    // one reference was set, switch to reference list\n                       setFlags((byte)(flags | NUMBER_LIST));\n                       long list = referenceList.addFirstNumber(ref,instanceId);\n                       setReferencesPointer(list);\n                    }\n                } else { // use reference list\n                    long newRef = referenceList.addNumber(ref,instanceId);\n                    if (newRef != ref) {\n                        setReferencesPointer(newRef);\n                    }\n                }\n            } catch (IOException ex) {\n                ex.printStackTrace();\n            }\n        }\n        \n        LongIterator getReferences() {\n            byte flags = getFlags();\n            long ref = getReferencesPointer();\n            if ((flags & NUMBER_LIST) == 0) {\n                if (ref == 0L) {\n                    return LongIterator.EMPTY_ITERATOR;\n                } else {\n                    return LongIterator.singleton(ref);\n                }\n            } else {\n                try {\n                    return referenceList.getNumbersIterator(ref);\n                } catch (IOException ex) {\n                    ex.printStackTrace();\n                }\n            }\n            return LongIterator.EMPTY_ITERATOR;\n        }\n        \n        long getOffset() {\n            return getFoffset(offset, KEY_SIZE);\n        }\n\n        void setRetainedSize(long size) {\n            if (FOFFSET_SIZE == 4) {\n                dumpBuffer.putInt(offset, KEY_SIZE + FOFFSET_SIZE + 4 + 1 + ID_SIZE, (int)size);\n            } else {\n                dumpBuffer.putLong(offset, KEY_SIZE + FOFFSET_SIZE + 4 + 1 + ID_SIZE, size);\n            }\n        }\n\n        long getRetainedSize() {\n            if (FOFFSET_SIZE == 4) {\n                return dumpBuffer.getInt(offset, KEY_SIZE + FOFFSET_SIZE + 4 + 1 + ID_SIZE);\n            }\n            return dumpBuffer.getLong(offset, KEY_SIZE + FOFFSET_SIZE + 4 + 1 + ID_SIZE);\n        }\n\n        private void setReferencesPointer(long instanceId) {\n            putID(offset, KEY_SIZE + FOFFSET_SIZE + 4 + 1, instanceId);\n        }\n\n        private long getReferencesPointer() {\n            return getID(offset, KEY_SIZE + FOFFSET_SIZE + 4 + 1);\n        }\n\n        private void setFlags(byte flags) {\n            dumpBuffer.putByte(offset, KEY_SIZE + FOFFSET_SIZE + 4, flags);\n        }\n\n        private byte getFlags() {\n            return dumpBuffer.getByte(offset, KEY_SIZE + FOFFSET_SIZE + 4);\n        }\n    }\n\n    private static class RetainedSizeEntry implements Comparable<RetainedSizeEntry> {\n        private final long instanceId;\n        private final long retainedSize;\n        \n        private RetainedSizeEntry(long id,long size) {\n            instanceId = id;\n            retainedSize = size;\n        }\n\n        public int compareTo(RetainedSizeEntry other) {\n            // bigger object are at beginning\n            int diff = Long.compare(other.retainedSize, retainedSize);\n            if (diff == 0) {\n                // sizes are the same, compare ids\n                return Long.compare(instanceId, other.instanceId);\n            }\n            return diff;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj == null) {\n                return false;\n            }\n            if (getClass() != obj.getClass()) {\n                return false;\n            }\n            final RetainedSizeEntry other = (RetainedSizeEntry) obj;\n            return this.instanceId == other.instanceId;\n        }\n\n        @Override\n        public int hashCode() {\n            int hash = 7;\n            hash = 31 * hash + (int) (this.instanceId ^ (this.instanceId >>> 32));\n            return hash;\n        }\n    }\n    \n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    LongMap(int size,int idSize,int foffsetSize,CacheDirectory cacheDir) throws FileNotFoundException, IOException {\n        super(size,idSize,foffsetSize,foffsetSize + 4 + 1 + idSize + foffsetSize, cacheDir);\n        referenceList = cacheDir.createNumberList(ID_SIZE);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    Entry createEntry(long index) {\n        return new Entry(index);\n    }\n    \n    Entry createEntry(long index,long value) {\n        return new Entry(index,value);\n    }\n    \n    Entry get(long key) {\n        return (Entry)super.get(key);\n    }\n\n    Entry put(long key, long value) {\n        return (Entry)super.put(key,value);\n    }\n\n    void flush() {\n        referenceList.flush();\n    }\n\n    long[] getBiggestObjectsByRetainedSize(int number) {\n        SortedSet<RetainedSizeEntry> bigObjects = new TreeSet<>();\n        long[] bigIds = new long[number];\n        long min = 0;\n        for (long index=0;index<fileSize;index+=ENTRY_SIZE) {\n            long id = getID(index, 0);\n            if (id != 0) {\n                long retainedSize = createEntry(index).getRetainedSize();\n                if (bigObjects.size()<number) {\n                    bigObjects.add(new RetainedSizeEntry(id,retainedSize));\n                    min = bigObjects.last().retainedSize;\n                } else if (retainedSize>min) {\n                    bigObjects.remove(bigObjects.last());\n                    bigObjects.add(new RetainedSizeEntry(id,retainedSize));\n                    min = bigObjects.last().retainedSize;\n                }\n            }\n        }\n        int i = 0;\n        for (RetainedSizeEntry rse : bigObjects) {\n            bigIds[i++]=rse.instanceId;\n        }\n        return bigIds;\n    }\n\n    //---- Serialization support    \n    void writeToStream(DataOutputStream out) throws IOException {\n        super.writeToStream(out);\n        referenceList.writeToStream(out);\n    }\n    \n    LongMap(DataInputStream dis, CacheDirectory cacheDir) throws IOException {\n        super(dis, cacheDir);\n        referenceList = new NumberList(dis, cacheDir);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/LongSet.java",
    "content": "/*\n * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.Arrays;\nimport java.util.Set;\n\n/**\n * Set for longs. IdentityHashMap was used as template.\n * Zero cannot be used as key. Load factor is 3/4.\n * @author Tomas Hurka\n */\nclass LongSet\n{\n    /**\n     * The initial capacity used by the no-args constructor.\n     * MUST be a power of two.  The value 32 corresponds to the\n     * (specified) expected maximum size of 21, given a load factor\n     * of 2/3.\n     */\n    private static final int DEFAULT_CAPACITY = 32;\n\n    /**\n     * The minimum capacity, used if a lower value is implicitly specified\n     * by either of the constructors with arguments.  The value 4 corresponds\n     * to an expected maximum size of 2, given a load factor of 2/3.\n     * MUST be a power of two.\n     */\n    private static final int MINIMUM_CAPACITY = 4;\n\n    /**\n     * The maximum capacity, used if a higher value is implicitly specified\n     * by either of the constructors with arguments.\n     * MUST be a power of two <= 1<<29.\n     */\n    private static final int MAXIMUM_CAPACITY = 1 << 30;\n\n    /**\n     * The table, resized as necessary. Length MUST always be a power of two.\n     */\n    private transient long[] table;\n\n    /**\n     * The number of key-value mappings contained in this identity hash map.\n     *\n     * @serial\n     */\n    private int size;\n\n    /**\n     * The number of modifications, to support fast-fail iterators\n     */\n    private transient volatile int modCount;\n\n    /**\n     * The next size value at which to resize (capacity * load factor).\n     */\n    private transient int threshold;\n\n    /**\n     * Constructs a new, empty identity hash map with a default expected\n     * maximum size (21).\n     */\n    LongSet() {\n        init(DEFAULT_CAPACITY);\n    }\n\n    /**\n     * Constructs a new, empty map with the specified expected maximum size.\n     * Putting more than the expected number of key-value mappings into\n     * the map may cause the internal data structure to grow, which may be\n     * somewhat time-consuming.\n     *\n     * @param expectedMaxSize the expected maximum size of the map\n     * @throws IllegalArgumentException if <tt>expectedMaxSize</tt> is negative\n     */\n    LongSet(int expectedMaxSize) {\n        if (expectedMaxSize < 0)\n            throw new IllegalArgumentException(\"expectedMaxSize is negative: \"\n                                               + expectedMaxSize);\n        init(capacity(expectedMaxSize));\n    }\n\n    /**\n     * Returns the appropriate capacity for the specified expected maximum\n     * size.  Returns the smallest power of two between MINIMUM_CAPACITY\n     * and MAXIMUM_CAPACITY, inclusive, that is greater than\n     * (4 * expectedMaxSize)/3, if such a number exists.  Otherwise\n     * returns MAXIMUM_CAPACITY.  If (4 * expectedMaxSize)/3 is negative, it\n     * is assumed that overflow has occurred, and MAXIMUM_CAPACITY is returned.\n     */\n    private int capacity(int expectedMaxSize) {\n        // Compute min capacity for expectedMaxSize given a load factor of 3/4\n        int minCapacity = (4 * expectedMaxSize)/3;\n\n        // Compute the appropriate capacity\n        int result;\n        if (minCapacity > MAXIMUM_CAPACITY || minCapacity < 0) {\n            result = MAXIMUM_CAPACITY;\n        } else {\n            result = MINIMUM_CAPACITY;\n            while (result < minCapacity)\n                result <<= 1;\n        }\n        return result;\n    }\n\n    /**\n     * Initializes object to be an empty map with the specified initial\n     * capacity, which is assumed to be a power of two between\n     * MINIMUM_CAPACITY and MAXIMUM_CAPACITY inclusive.\n     */\n    private void init(int initCapacity) {\n        // assert (initCapacity & -initCapacity) == initCapacity; // power of 2\n        // assert initCapacity >= MINIMUM_CAPACITY;\n        // assert initCapacity <= MAXIMUM_CAPACITY;\n\n        threshold = (initCapacity * 3) / 4;\n        table = new long[initCapacity];\n    }\n\n    /**\n     * Constructs a new identity hash map containing the keys-value mappings\n     * in the specified map.\n     *\n     * @param m the map whose mappings are to be placed into this map\n     * @throws NullPointerException if the specified map is null\n     */\n    LongSet(Set<Long> m) {\n        // Allow for a bit of growth\n        this((int) ((1 + m.size()) * 1.1));\n        putAll(m);\n    }\n\n    /**\n     * Returns the number of key-value mappings in this identity hash map.\n     *\n     * @return the number of key-value mappings in this map\n     */\n    int size() {\n        return size;\n    }\n\n    /**\n     * Returns <tt>true</tt> if this identity hash map contains no key-value\n     * mappings.\n     *\n     * @return <tt>true</tt> if this identity hash map contains no key-value\n     *         mappings\n     */\n    boolean isEmpty() {\n        return size == 0;\n    }\n\n    /**\n     * Returns index for Object x.\n     */\n    private static int hash(long x, int length) {\n        int h = (int)(x ^ (x >>> 32));\n        // This function ensures that hashCodes that differ only by\n        // constant multiples at each bit position have a bounded\n        // number of collisions (approximately 8 at default load factor).\n        h ^= (h >>> 20) ^ (h >>> 12);\n        h ^= (h >>> 7) ^ (h >>> 4);\n        return (h) & (length - 1);\n    }\n\n    /**\n     * Circularly traverses table of size len.\n     */\n    private static int nextKeyIndex(int i, int len) {\n        return (i + 1 < len ? i + 1 : 0);\n    }\n\n    /**\n     * Tests whether the specified object reference is a key in this identity\n     * hash map.\n     *\n     * @param   key   possible key\n     * @return  <code>true</code> if the specified object reference is a key\n     *          in this map\n     * @see     #containsValue(Object)\n     */\n    boolean contains(long key) {\n        assert key != 0;\n        long[] tab = table;\n        int len = tab.length;\n        int i = hash(key, len);\n        while (true) {\n            long item = tab[i];\n            if (item == key)\n                return true;\n            if (item == 0)\n                return false;\n            i = nextKeyIndex(i, len);\n        }\n    }\n\n    /**\n     * Associates the specified value with the specified key in this identity\n     * hash map.  If the map previously contained a mapping for the key, the\n     * old value is replaced.\n     *\n     * @param key the key with which the specified value is to be associated\n     * @param value the value to be associated with the specified key\n     * @return the previous value associated with <tt>key</tt>, or\n     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.\n     *         (A <tt>null</tt> return can also indicate that the map\n     *         previously associated <tt>null</tt> with <tt>key</tt>.)\n     * @see     Object#equals(Object)\n     * @see     #get(Object)\n     * @see     #containsKey(Object)\n     */\n    boolean add(long key) {\n        assert key != 0;\n        long[] tab = table;\n        int len = tab.length;\n        int i = hash(key, len);\n\n        long item;\n        while ( (item = tab[i]) != 0) {\n            if (item == key) {\n                return true;\n            }\n            i = nextKeyIndex(i, len);\n        }\n\n        modCount++;\n        tab[i] = key;\n        if (++size >= threshold)\n            resize(2*len);\n        return false;\n    }\n\n    /**\n     * Resize the table to hold given capacity.\n     *\n     * @param newCapacity the new capacity, must be a power of two.\n     */\n    private void resize(int newCapacity) {\n        // assert (newCapacity & -newCapacity) == newCapacity; // power of 2\n        int newLength = newCapacity;\n\n\tlong[] oldTable = table;\n        int oldLength = oldTable.length;\n        if (oldLength == MAXIMUM_CAPACITY) { // can't expand any further\n            if (threshold == MAXIMUM_CAPACITY-1)\n                throw new IllegalStateException(\"Capacity exhausted.\");\n            threshold = MAXIMUM_CAPACITY-1;  // Gigantic map!\n            return;\n        }\n        if (oldLength >= newLength)\n            return;\n\n\tlong[] newTable = new long[newLength];\n        threshold = (newLength * 3) / 4;\n\n        for (long key : oldTable) {\n            if (key != 0) {\n                int i = hash(key, newLength);\n                while (newTable[i] != 0)\n                    i = nextKeyIndex(i, newLength);\n                newTable[i] = key;\n            }\n        }\n        table = newTable;\n    }\n\n    /**\n     * Copies all of the mappings from the specified map to this map.\n     * These mappings will replace any mappings that this map had for\n     * any of the keys currently in the specified map.\n     *\n     * @param m mappings to be stored in this map\n     * @throws NullPointerException if the specified map is null\n     */\n    void putAll(Set<Long> m) {\n        int n = m.size();\n        if (n == 0)\n            return;\n        if (n > threshold) // conservatively pre-expand\n            resize(capacity(n));\n\n\tfor (Long e : m) {\n            add(e);\n        }\n    }\n\n    /**\n     * Removes the mapping for this key from this map if present.\n     *\n     * @param key key whose mapping is to be removed from the map\n     * @return the previous value associated with <tt>key</tt>, or\n     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.\n     *         (A <tt>null</tt> return can also indicate that the map\n     *         previously associated <tt>null</tt> with <tt>key</tt>.)\n     */\n    boolean remove(long key) {\n        key++;\n        long[] tab = table;\n        int len = tab.length;\n        int i = hash(key, len);\n\n        while (true) {\n            long item = tab[i];\n            if (item == key) {\n                modCount++;\n                size--;\n                tab[i] = 0;\n                closeDeletion(i);\n                return true;\n            }\n            if (item == 0)\n                return false;\n            i = nextKeyIndex(i, len);\n        }\n\n    }\n\n    /**\n     * Rehash all possibly-colliding entries following a\n     * deletion. This preserves the linear-probe\n     * collision properties required by get, put, etc.\n     *\n     * @param d the index of a newly empty deleted slot\n     */\n    private void closeDeletion(int d) {\n        // Adapted from Knuth Section 6.4 Algorithm R\n        long[] tab = table;\n        int len = tab.length;\n\n        // Look for items to swap into newly vacated slot\n        // starting at index immediately following deletion,\n        // and continuing until a null slot is seen, indicating\n        // the end of a run of possibly-colliding keys.\n        long item;\n        for (int i = nextKeyIndex(d, len); (item = tab[i]) != 0;\n             i = nextKeyIndex(i, len) ) {\n            // The following test triggers if the item at slot i (which\n            // hashes to be at slot r) should take the spot vacated by d.\n            // If so, we swap it in, and then continue with d now at the\n            // newly vacated i.  This process will terminate when we hit\n            // the null slot at the end of this run.\n            // The test is messy because we are using a circular table.\n            int r = hash(item, len);\n            if ((i < r && (r <= d || d <= i)) || (r <= d && d <= i)) {\n                tab[d] = item;\n                tab[i] = 0;\n                d = i;\n            }\n        }\n    }\n\n    /**\n     * Removes all of the mappings from this map.\n     * The map will be empty after this call returns.\n     */\n    void clear() {\n        modCount++;\n        long[] tab = table;\n        Arrays.fill(tab,0);\n        size = 0;\n    }\n\n    /**\n     * Compares the specified object with this map for equality.  Returns\n     * <tt>true</tt> if the given object is also a map and the two maps\n     * represent identical object-reference mappings.  More formally, this\n     * map is equal to another map <tt>m</tt> if and only if\n     * <tt>this.entrySet().equals(m.entrySet())</tt>.\n     *\n     * <p><b>Owing to the reference-equality-based semantics of this map it is\n     * possible that the symmetry and transitivity requirements of the\n     * <tt>Object.equals</tt> contract may be violated if this map is compared\n     * to a normal map.  However, the <tt>Object.equals</tt> contract is\n     * guaranteed to hold among <tt>IdentityHashMap</tt> instances.</b>\n     *\n     * @param  o object to be compared for equality with this map\n     * @return <tt>true</tt> if the specified object is equal to this map\n     * @see Object#equals(Object)\n     */\n    public boolean equals(Object o) {\n        if (o == this) {\n            return true;\n        } else if (o instanceof LongSet) {\n            LongSet m = (LongSet) o;\n            if (m.size() != size)\n                return false;\n\n            long[] tab = m.table;\n            for (long k : tab) {\n                if (k != 0 && !contains(k))\n                    return false;\n            }\n            return true;\n        } else {\n            return false;  // o is not a Map\n        }\n    }\n\n    /**\n     * Returns the hash code value for this map.  The hash code of a map is\n     * defined to be the sum of the hash codes of each entry in the map's\n     * <tt>entrySet()</tt> view.  This ensures that <tt>m1.equals(m2)</tt>\n     * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two\n     * <tt>IdentityHashMap</tt> instances <tt>m1</tt> and <tt>m2</tt>, as\n     * required by the general contract of {@link Object#hashCode}.\n     *\n     * <p><b>Owing to the reference-equality-based semantics of the\n     * <tt>Map.Entry</tt> instances in the set returned by this map's\n     * <tt>entrySet</tt> method, it is possible that the contractual\n     * requirement of <tt>Object.hashCode</tt> mentioned in the previous\n     * paragraph will be violated if one of the two objects being compared is\n     * an <tt>IdentityHashMap</tt> instance and the other is a normal map.</b>\n     *\n     * @return the hash code value for this map\n     * @see Object#equals(Object)\n     * @see #equals(Object)\n     */\n    public int hashCode() {\n        int result = 0;\n        long[] tab = table;\n        for (long key : tab) {\n            if (key != 0) {\n                result += hash(key, tab.length);\n            }\n        }\n        return result;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/NearestGCRoot.java",
    "content": "/*\n * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass NearestGCRoot {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final int BUFFER_SIZE = (64 * 1024) / 8;\n    private static final String[] REF_CLASSES = {\n        \"java.lang.ref.WeakReference\",    // NOI18N\n        \"java.lang.ref.SoftReference\",    // NOI18N\n        \"java.lang.ref.FinalReference\",   // NOI18N\n        \"java.lang.ref.PhantomReference\"  // NOI18N\n    };\n    private static final String JAVA_LANG_REF_REFERENCE = \"java.lang.ref.Reference\";   // NOI18N\n    private static final String REFERENT_FIELD_NAME = \"referent\"; // NOI18N\n    private static final String SVM_REFFERENCE = \"com.oracle.svm.core.heap.heapImpl.DiscoverableReference\";    // NOI18N\n    private static final String SVM_REFFERENCE_1 = \"com.oracle.svm.core.heap.DiscoverableReference\";    // NOI18N\n    private static final String SVM_REFERENT_FIELD_NAME = \"rawReferent\"; // NOI18N\n    private static final int DEEP_LEVEL = 10000;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Field referentField;\n    private HprofHeap heap;\n    private LongBuffer readBuffer;\n    private LongBuffer writeBuffer;\n    private LongBuffer deepPathBuffer;\n    private LongBuffer leaves;\n    private LongBuffer multipleParents;\n    private Set<JavaClass> referenceClasses;\n    private boolean gcRootsComputed;\n    private long allInstances;\n    private long processedInstances;\n    private long level;\n//private long leavesCount;\n//private long firstLevel;\n//private long multiParentsCount;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    NearestGCRoot(HprofHeap h) {\n        heap = h;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    Instance getNearestGCRootPointer(Instance instance) {\n        if (heap.isGCRoot(instance)) {\n            return instance;\n        }\n        computeGCRoots();\n        long nextGCPathId = heap.idToOffsetMap.get(instance.getInstanceId()).getNearestGCRootPointer();\n        return heap.getInstanceByID(nextGCPathId);\n    }\n\n    private boolean isSpecialReference(FieldValue value, Instance instance) {\n        Field f = value.getField();\n\n        return f.equals(referentField) && referenceClasses.contains(instance.getJavaClass());\n    }\n\n    private synchronized void computeGCRoots() {\n        if (gcRootsComputed) {\n            return;\n        }\n        HeapProgress.progressStart();\n        if (!initHotSpotReference()) {\n            if (!initSVMReference()) {\n                throw new IllegalArgumentException(\"reference field not found\"); // NOI18N\n            }\n        }\n        heap.computeReferences(); // make sure references are computed first\n        heap.cacheDirectory.setDirty(true);\n        allInstances = heap.getSummary().getTotalLiveInstances();\n        Set<JavaClass> processedClasses = new HashSet<>(heap.getAllClasses().size()*4/3);\n        \n        try {\n            createBuffers();\n            fillZeroLevel();\n\n            do {\n                switchBuffers();\n                computeOneLevel(processedClasses);\n            } while (hasMoreLevels());\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n\n        deleteBuffers();\n        heap.idToOffsetMap.flush();\n        gcRootsComputed = true;\n        heap.writeToFile();\n        HeapProgress.progressFinish();\n    }\n\n    private boolean initHotSpotReference() {\n        referentField = computeReferentField(JAVA_LANG_REF_REFERENCE, REFERENT_FIELD_NAME);\n        if (referentField != null) {\n            referenceClasses = new HashSet<>();\n            for (String refClass : REF_CLASSES) {\n                JavaClass ref = heap.getJavaClassByName(refClass);\n                if (ref != null) {\n                    referenceClasses.add(ref);\n                    referenceClasses.addAll(ref.getSubClasses());\n                }\n            }\n            return referenceClasses.size() >= REF_CLASSES.length;\n        }\n        return false;\n    }\n\n    private boolean initSVMReference() {\n        referentField = computeReferentField(SVM_REFFERENCE, SVM_REFERENT_FIELD_NAME);\n        if (referentField == null) {\n            referentField = computeReferentField(SVM_REFFERENCE_1, SVM_REFERENT_FIELD_NAME);\n        }\n        if (referentField != null) {\n            JavaClass ref = referentField.getDeclaringClass();\n\n            referenceClasses = new HashSet<>();\n            referenceClasses.add(ref);\n            referenceClasses.addAll(ref.getSubClasses());\n            return !referenceClasses.isEmpty();\n        }\n        return false;\n    }\n\n    private void computeOneLevel(Set<JavaClass> processedClasses) throws IOException {\n        int idSize = heap.dumpBuffer.getIDSize();\n        level++;\n        for (;;) {\n            Instance instance;\n            long instanceOffset = readLong();\n            List<FieldValue> fieldValues;\n            boolean hasValues = false;\n            \n            if (instanceOffset == 0L) { // end of level\n                break;\n            }\n            HeapProgress.progress(processedInstances++,allInstances);\n            instance = heap.getInstanceByOffset(new long[] {instanceOffset});\n            if (instance instanceof ObjectArrayInstance) {\n                ObjectArrayDump array = (ObjectArrayDump) instance;\n                int size = array.getLength();\n                long offset = array.getOffset();\n                long instanceId = instance.getInstanceId();\n\n                for (int i=0;i<size;i++) {\n                    long referenceId = heap.dumpBuffer.getID(offset + (i * idSize));\n\n                    if (writeConnection(instanceId, referenceId)) {\n                        hasValues = true;\n                    }\n                }\n                if (!hasValues) {\n                    writeLeaf(instanceId,instance.getSize());\n                }\n                continue;\n            } else if (instance instanceof PrimitiveArrayInstance) {\n                writeLeaf(instance.getInstanceId(),instance.getSize());\n                continue;\n            } else if (instance instanceof ClassDumpInstance) {\n                ClassDump javaClass = ((ClassDumpInstance) instance).classDump;\n\n                fieldValues = javaClass.getStaticFieldValues();\n            } else if (instance instanceof InstanceDump) {\n                fieldValues = instance.getFieldValues();\n            } else {\n                if (instance == null) {\n                    System.err.println(\"HeapWalker Warning - null instance for \" + heap.dumpBuffer.getID(instanceOffset + 1)); // NOI18N\n                    continue;\n                }\n                throw new IllegalArgumentException(\"Illegal type \" + instance.getClass()); // NOI18N\n            }\n            long instanceId = instance.getInstanceId();\n            for (FieldValue val : fieldValues) {\n                if (val instanceof ObjectFieldValue) {\n                     // skip Soft, Weak, Final and Phantom References\n                    if (!isSpecialReference(val, instance)) {\n                        long refInstanceId;\n\n                        if (val instanceof HprofFieldObjectValue) {\n                            refInstanceId = ((HprofFieldObjectValue) val).getInstanceID();\n                        } else {\n                             refInstanceId = ((HprofInstanceObjectValue) val).getInstanceId();\n                        }\n                        if (writeConnection(instanceId, refInstanceId)) {\n                            hasValues = true;\n                        }\n                    }\n                }\n            }\n            if (writeClassConnection(processedClasses, instanceId, instance.getJavaClass())) {\n                hasValues = true;\n            }\n            if (!hasValues) {\n                writeLeaf(instanceId,instance.getSize());\n            }\n\n        }\n    }\n\n    private Field computeReferentField(String className, String fieldName) {\n        JavaClass reference = heap.getJavaClassByName(className);\n\n        if (reference != null) {\n            for (Field f : reference.getFields()) {\n                if (f.getName().equals(fieldName)) {\n                    return f;\n                }\n            }\n        }\n        return null;\n    }\n\n    private void createBuffers() {\n        readBuffer = new LongBuffer(BUFFER_SIZE, heap.cacheDirectory);\n        writeBuffer = new LongBuffer(BUFFER_SIZE, heap.cacheDirectory);\n        leaves = new LongBuffer(BUFFER_SIZE, heap.cacheDirectory);\n        multipleParents = new LongBuffer(BUFFER_SIZE, heap.cacheDirectory);\n        deepPathBuffer = new LongBuffer(BUFFER_SIZE, heap.cacheDirectory);\n    }\n\n    private void deleteBuffers() {\n        readBuffer.delete();\n        writeBuffer.delete();\n    }\n\n    private void fillZeroLevel() throws IOException {\n        for (GCRoot gcr : heap.getGCRoots()) {\n            HprofGCRoot root = (HprofGCRoot)gcr;\n            long id = root.getInstanceId();\n            LongMap.Entry entry = heap.idToOffsetMap.get(id);\n            \n            if (entry != null) {\n                writeLong(entry.getOffset());\n            }\n        }\n    }\n\n    private boolean hasMoreLevels() {\n        return writeBuffer.hasData();\n    }\n\n    private long readLong() throws IOException {\n        return readBuffer.readLong();\n    }\n\n    private void switchBuffers() throws IOException {\n        LongBuffer b = readBuffer;\n        readBuffer = writeBuffer;\n        writeBuffer = b;\n        readBuffer.startReading();\n        writeBuffer.reset();\n    }\n\n    private boolean writeClassConnection(final Set<JavaClass> processedClasses, final long instanceId, final JavaClass jcls) throws IOException {\n        if (!processedClasses.contains(jcls)) {\n            long jclsId = jcls.getJavaClassId();\n            \n            processedClasses.add(jcls);\n            if (writeConnection(instanceId, jclsId, true)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private boolean writeConnection(long instanceId, long refInstanceId)\n                          throws IOException {\n        return writeConnection(instanceId, refInstanceId, false);\n    }\n    \n    private boolean writeConnection(long instanceId, long refInstanceId, boolean addRefInstanceId)\n                          throws IOException {\n        if (refInstanceId != 0) {\n            LongMap.Entry entry = heap.idToOffsetMap.get(refInstanceId);\n\n            if (entry != null && entry.getNearestGCRootPointer() == 0L && heap.gcRoots.getGCRoots(refInstanceId) == null) {\n                writeLong(entry.getOffset());\n                if (level > DEEP_LEVEL) {\n                    deepPathBuffer.writeLong(refInstanceId);\n                    entry.setDeepObj();\n                }\n                if (addRefInstanceId) {\n                    if (!checkReferences(refInstanceId, instanceId)) {\n                        entry.addReference(instanceId);\n                    }\n                }\n                entry.setNearestGCRootPointer(instanceId);\n                if (!entry.hasOnlyOneReference()) {\n                    multipleParents.writeLong(refInstanceId);\n//multiParentsCount++;\n                }\n                return true;\n            }\n            return !addRefInstanceId && entry != null;\n        }\n        return false;\n    }\n\n    private boolean checkReferences(final long refInstanceId, final long instanceId) {\n        Instance instance = heap.getInstanceByID(instanceId);        \n        \n        for (FieldValue field : instance.getFieldValues()) {\n            if (field instanceof HprofInstanceObjectValue) {\n                HprofInstanceObjectValue objectValue = (HprofInstanceObjectValue) field;\n\n                if (objectValue.getInstanceId() == refInstanceId) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    private void writeLong(long instanceOffset) throws IOException {\n        writeBuffer.writeLong(instanceOffset);\n    }\n\n    private void writeLeaf(long instanceId, long size) throws IOException {\n        LongMap.Entry entry = heap.idToOffsetMap.get(instanceId);\n        \n        entry.setTreeObj();\n        entry.setRetainedSize(size);\n//leavesCount++;\n        if (entry.hasOnlyOneReference()) {\n            long gcRootPointer = entry.getNearestGCRootPointer();\n            if (gcRootPointer != 0) {\n                LongMap.Entry gcRootPointerEntry = heap.idToOffsetMap.get(gcRootPointer);\n                \n                if (gcRootPointerEntry.getRetainedSize() == 0) {\n                    gcRootPointerEntry.setRetainedSize(-1);\n                    leaves.writeLong(gcRootPointer);\n//firstLevel++;\n                }\n            }\n        }\n    }\n\n    LongBuffer getLeaves() {\n        computeGCRoots();\n//System.out.println(\"Multi par.  \"+multiParentsCount);\n//System.out.println(\"Leaves      \"+leavesCount);\n//System.out.println(\"Tree obj.   \"+heap.idToOffsetMap.treeObj);\n//System.out.println(\"First level \"+firstLevel);\n        return leaves;\n    }\n    \n    LongBuffer getMultipleParents() {\n        computeGCRoots();\n        return multipleParents;\n    }\n\n    LongBuffer getDeepPathBuffer() {\n        computeGCRoots();\n        return deepPathBuffer;\n    }\n\n    //---- Serialization support\n    void writeToStream(DataOutputStream out) throws IOException {\n        out.writeBoolean(gcRootsComputed);\n        if (gcRootsComputed) {\n            leaves.writeToStream(out);\n            multipleParents.writeToStream(out);\n            deepPathBuffer.writeToStream(out);\n        }\n    }\n\n    NearestGCRoot(HprofHeap h, DataInputStream dis) throws IOException {\n        this(h);\n        gcRootsComputed = dis.readBoolean();\n        if (gcRootsComputed) {\n            leaves = new LongBuffer(dis, heap.cacheDirectory);\n            multipleParents = new LongBuffer(dis, heap.cacheDirectory);\n            deepPathBuffer = new LongBuffer(dis, heap.cacheDirectory);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/NumberList.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\nimport java.nio.MappedByteBuffer;\nimport java.nio.channels.FileChannel;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.NoSuchElementException;\nimport java.util.Set;\n\n/**\n * @author Tomas Hurka\n */\nclass NumberList {\n\n    private static final int NUMBERS_IN_BLOCK = 3;\n    private final File dataFile;\n    private final RandomAccessFile data;\n    private final int numberSize;\n    private final int blockSize;\n    // Map <offset,block>\n    private final Map<Long,byte[]> blockCache;\n    private final Set<Long> dirtyBlocks;\n    private long blocks;\n    private MappedByteBuffer buf;\n    private long mappedSize;\n    private CacheDirectory cacheDirectory;\n\n    NumberList(long dumpFileSize, CacheDirectory cacheDir) throws IOException {\n        this(bytes(dumpFileSize), cacheDir);\n    }\n\n    NumberList(int elSize, CacheDirectory cacheDir) throws IOException {\n        dataFile = cacheDir.createTempFile(\"NBProfiler\", \".ref\"); // NOI18N\n        data = new RandomAccessFile(dataFile, \"rw\"); // NOI18N\n        numberSize = elSize;\n        blockCache = new BlockLRUCache<>();\n        dirtyBlocks = new HashSet<>(100000);\n        blockSize = (NUMBERS_IN_BLOCK + 1) * numberSize;\n        cacheDirectory = cacheDir;\n        addBlock(); // first block is unused, since it starts at offset 0\n    }\n\n    private static int bytes(long number) {\n        if ((number & ~0xFFL) == 0L) {\n            return 1;\n        }\n        if ((number & ~0xFFFFL) == 0L) {\n            return 2;\n        }\n        if ((number & ~0xFFFFFFL) == 0L) {\n            return 3;\n        }\n        if ((number & ~0xFFFFFFFFL) == 0L) {\n            return 4;\n        }\n        if ((number & ~0xFFFFFFFFFFL) == 0L) {\n            return 5;\n        }\n        if ((number & ~0xFFFFFFFFFFFFL) == 0L) {\n            return 6;\n        }\n        if ((number & ~0xFFFFFFFFFFFFFFL) == 0L) {\n            return 7;\n        }\n        return 8;\n    }\n    \n    protected void finalize() throws Throwable {\n        if (cacheDirectory.isTemporary()) {\n            dataFile.delete();\n        }\n        super.finalize();\n    }\n    \n    long addNumber(long startOffset,long number) throws IOException {\n        int slot;\n        byte[] block = getBlock(startOffset);\n        for (slot=0;slot<NUMBERS_IN_BLOCK;slot++) {\n            long el = readNumber(block,slot);\n            if (el == 0L) {\n                writeNumber(startOffset,block,slot,number);\n                return startOffset;\n            }\n            if (el == number) { // number is already in the list\n                return startOffset; // do nothing\n            }\n        }\n        long nextBlock = addBlock(); // create next blok\n        block = getBlock(nextBlock);\n        writeNumber(nextBlock,block,slot,startOffset); // put next block in front of old block\n        writeNumber(nextBlock,block,0,number); // write number to first position in the new block\n        return nextBlock;\n    }\n    \n    long addFirstNumber(long number1,long number2) throws IOException {\n        long blockOffset = addBlock();\n        byte[] block = getBlock(blockOffset);\n        writeNumber(blockOffset,block,0,number1);\n        writeNumber(blockOffset,block,1,number2);\n        return blockOffset;\n    }\n    \n    void putFirst(long startOffset,long number) throws IOException {\n        int slot;\n        long offset = startOffset;\n        long movedNumber = 0;\n        for(;;) {\n            byte[] block = getBlock(offset);\n            for (slot=0;slot<NUMBERS_IN_BLOCK;slot++) {\n                long el = readNumber(block,slot);\n                if (offset == startOffset && slot == 0) { // first block\n                    if (number == el) { // already first element \n                        return;\n                    }\n                    movedNumber = el;\n                    writeNumber(offset,block,slot,number);\n                } else if (el == 0L) { // end of the block, move to next one\n                    break;\n                } else if (el == number) { // number is already in the list\n                    writeNumber(offset,block,slot,movedNumber);    // replace number and return                \n                    return;\n                }\n            }\n            offset = getOffsetToNextBlock(block);\n            if (offset == 0L) {\n                System.out.println(\"Error - number not found at end\");\n                return;\n            }\n        }\n    }\n    \n    long getFirstNumber(long startOffset) throws IOException {\n        byte[] block = getBlock(startOffset);\n        return readNumber(block,0);\n    }\n    \n    LongIterator getNumbersIterator(long startOffset) throws IOException {\n        return new NumberIterator(startOffset);\n    }\n\n    List<Long> getNumbers(long startOffset) throws IOException {\n        int slot;\n        List<Long> numbers = new ArrayList<>();\n        \n        for(;;) {\n            byte[] block = getBlock(startOffset);\n            for (slot=0;slot<NUMBERS_IN_BLOCK;slot++) {\n                long el = readNumber(block,slot);\n                if (el == 0L) {     // end of the block, move to next one\n                    break;\n                }\n                numbers.add(new Long(el));\n            }\n            long nextBlock = getOffsetToNextBlock(block);\n            if (nextBlock == 0L) {\n                return numbers;\n            }\n            startOffset = nextBlock;\n        }\n    }\n    \n    private void mmapData() {\n        if (buf == null) {\n            try {\n                mappedSize = Math.min(blockSize*blocks, Integer.MAX_VALUE-blockSize+1);\n                buf = data.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, mappedSize);\n            } catch (IOException ex) {\n                // map() failed\n                mappedSize = 0;\n                ex.printStackTrace();\n            }\n        }\n    }\n    \n    void flush() {\n        try {\n            flushDirtyBlocks();\n            blockCache.clear();\n            mmapData();\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n    }\n    \n    private long getOffsetToNextBlock(byte[] block) {\n        return readNumber(block,NUMBERS_IN_BLOCK);\n    }\n    \n    private long readNumber(byte[] block,int slot) {\n        int offset = slot*numberSize;\n        long el = 0;\n//        for (int i=0;i<numberSize;i++) {\n//            el <<= 8;\n//            el |= ((int)block[offset+i]) & 0xFF;\n//        }    \n        if (numberSize == 4) {\n            return ((long)getInt(block,offset)) & 0xFFFFFFFFL;\n        } else if (numberSize == 8) {\n            return getLong(block,offset);\n        }\n        return el;\n    }\n\n    private int getInt(byte[] buf, int i) {\n        int ch1 = ((int) buf[i++]) & 0xFF;\n        int ch2 = ((int) buf[i++]) & 0xFF;\n        int ch3 = ((int) buf[i++]) & 0xFF;\n        int ch4 = ((int) buf[i]) & 0xFF;\n\n        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));\n    }\n\n    private long getLong(byte[] buf, int i) {\n       return (((long)buf[i++] << 56) +\n              ((long)(buf[i++] & 255) << 48) +\n              ((long)(buf[i++] & 255) << 40) +\n              ((long)(buf[i++] & 255) << 32) +\n              ((long)(buf[i++] & 255) << 24) +\n              ((buf[i++] & 255) << 16) +\n              ((buf[i++] & 255) <<  8) +\n              ((buf[i++] & 255) <<  0));\n    }\n        \n    private synchronized void writeNumber(long blockOffset,byte[] block,int slot,long element) throws IOException {\n        if (blockOffset < mappedSize) {\n            long offset = blockOffset+slot*numberSize;\n            buf.position((int)offset);\n            for (int i=numberSize-1;i>=0;i--) {\n                byte el = (byte)(element >> (i*8));\n                \n                buf.put(el);\n            }            \n        } else {\n            Long offsetObj = new Long(blockOffset);\n            int offset = slot*numberSize;\n            for (int i=numberSize-1;i>=0;i--) {\n                byte el = (byte)(element >> (i*8));\n                block[offset++]=el;\n            }\n            dirtyBlocks.add(offsetObj);\n            if (dirtyBlocks.size()>10000) {\n                flushDirtyBlocks();\n            }\n        }\n    }\n    \n    private synchronized byte[] getBlock(long offset) throws IOException {\n        byte[] block;\n        if (offset < mappedSize) {\n            block = new byte[blockSize];\n            buf.position((int)offset);\n            buf.get(block);\n            return block;\n        } else {\n            Long offsetObj = new Long(offset);\n\n            block = blockCache.get(offsetObj);\n            if (block == null) {\n                block = new byte[blockSize];\n                data.seek(offset);\n                data.readFully(block);\n                blockCache.put(offsetObj,block);\n            }\n            return block;\n        }\n    }\n\n    private long addBlock() throws IOException {\n        long offset=blocks*blockSize;\n        blockCache.put(new Long(offset),new byte[blockSize]);\n        blocks++;\n        return offset;\n    }\n\n    private void flushDirtyBlocks() throws IOException {\n        if (dirtyBlocks.isEmpty()) {\n            return;\n        }\n        Long[] dirty=dirtyBlocks.toArray(new Long[0]);\n        Arrays.sort(dirty);\n        byte blocks[] = new byte[1024*blockSize];\n        int dataOffset = 0;\n        long lastBlockOffset = 0;\n        for (Long blockOffsetLong : dirty) {\n            byte[] block = blockCache.get(blockOffsetLong);\n            long blockOffset = blockOffsetLong.longValue();\n            if (lastBlockOffset+dataOffset==blockOffset && dataOffset <= blocks.length - blockSize) {\n                System.arraycopy(block,0,blocks,dataOffset,blockSize);\n                dataOffset+=blockSize;\n            } else {\n                data.seek(lastBlockOffset);\n                data.write(blocks,0,dataOffset);\n                dataOffset = 0;\n                System.arraycopy(block,0,blocks,dataOffset,blockSize);\n                dataOffset+=blockSize;                \n                lastBlockOffset = blockOffset;\n            }\n        }\n        data.seek(lastBlockOffset);\n        data.write(blocks,0,dataOffset);\n        dirtyBlocks.clear();\n    }\n\n    //---- Serialization support\n    void writeToStream(DataOutputStream out) throws IOException {\n        out.writeUTF(dataFile.getAbsolutePath());\n        out.writeInt(numberSize);\n        out.writeLong(blocks);\n        out.writeBoolean(buf != null);        \n    }\n\n    NumberList(DataInputStream dis, CacheDirectory cacheDir) throws IOException {\n        boolean mmaped;\n        \n        cacheDirectory = cacheDir;\n        dataFile = cacheDirectory.getCacheFile(dis.readUTF());\n        data = new RandomAccessFile(dataFile, \"rw\"); // NOI18N\n        numberSize = dis.readInt();\n        blocks = dis.readLong();\n        mmaped = dis.readBoolean();\n        blockCache = new BlockLRUCache<>();\n        dirtyBlocks = new HashSet<>(100000);\n        blockSize = (NUMBERS_IN_BLOCK + 1) * numberSize;\n        if (mmaped) {\n            mmapData();\n        }\n    }    \n    \n    private class NumberIterator extends LongIterator {\n        private int slot;\n        private byte[] block;\n        private long nextNumber;\n\n        private NumberIterator(long startOffset) throws IOException {\n            slot = 0;\n            block = getBlock(startOffset);\n            nextNumber();\n        }\n\n        @Override\n        boolean hasNext() {\n            return nextNumber != 0;\n        }\n\n        @Override\n        long next() {\n            if (hasNext()) {\n                long num = nextNumber;\n                try {\n                    nextNumber();\n                } catch (IOException ex) {\n                    ex.printStackTrace();\n                    nextNumber = 0;\n                }\n                return num;\n            }\n            throw new NoSuchElementException();\n        }\n\n        private void nextNumber() throws IOException {\n            if (slot < NUMBERS_IN_BLOCK) {\n                long nextNum = readNumber(block,slot++);\n                if (nextNum == 0) {     // end of the block, move to next one\n                    nextBlock();\n                } else {\n                    nextNumber = nextNum;\n                }\n            } else {\n               nextBlock();\n            }\n        }\n\n        private void nextBlock() throws IOException {\n            long nextBlock = getOffsetToNextBlock(block);\n\n            if (nextBlock == 0) { // end of list\n                nextNumber = 0;\n                return;\n            }\n            block = getBlock(nextBlock);\n            slot = 0;\n            nextNumber();\n        }\n    }\n\n    private class BlockLRUCache<V> extends LinkedHashMap<Long,V> {\n        \n        private static final int MAX_CAPACITY = 10000;\n        \n        private BlockLRUCache() {\n            super(MAX_CAPACITY,0.75f,true);\n        }\n\n        protected boolean removeEldestEntry(Map.Entry<Long,V> eldest) {\n            if (size()>MAX_CAPACITY) {\n                Long key = eldest.getKey();\n                if (!dirtyBlocks.contains(key)) {\n                    return true;\n                }\n                get(key);\n            }\n            return false;\n        }\n\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ObjectArrayDump.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.List;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ObjectArrayDump extends ArrayDump implements ObjectArrayInstance {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    ObjectArrayDump(ClassDump cls, long offset) {\n        super(cls, offset);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public long getSize() {\n        return dumpClass.classDumpSegment.getArraySize((byte)HprofHeap.OBJECT, getLength());\n    }\n\n    public List<Instance> getValues() {\n        HprofByteBuffer dumpBuffer = dumpClass.getHprofBuffer();\n        HprofHeap heap = dumpClass.getHprof();\n\n        return new ObjectArrayLazyList(heap, dumpBuffer, getLength(), getOffset());\n    }\n\n    public List<ArrayItemValue> getItems() {\n        return new ObjectArrayValuesLazyList(dumpClass, getLength(), fileOffset);\n    }\n\n    long getOffset() {\n        int idSize = dumpClass.getHprofBuffer().getIDSize();\n\n        return fileOffset + 1 + idSize + 4 + 4 + idSize;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ObjectArrayInstance.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.List;\n\n\n/**\n * represents instance of array of objects\n * @author Tomas Hurka\n */\npublic interface ObjectArrayInstance extends Instance {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * return number of elements in the array (arr.length).\n     * <br>\n     * Speed: fast\n     * @return number of elements in the array\n     */\n    int getLength();\n\n    /**\n     * returns list of elements. The elements are instances of {@link Instance}.\n     * The list is ordered as the original array.\n     * <br>\n     * Speed: fast\n     * @return list {@link Instance} of elements.\n     */\n    List<Instance> getValues();\n\n    List<ArrayItemValue> getItems();\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ObjectArrayLazyList.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.AbstractList;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ObjectArrayLazyList extends AbstractList<Instance> {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final HprofByteBuffer dumpBuffer;\n    private final HprofHeap heap;\n    private final int idSize;\n    private final int length;\n    private final long offset;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    ObjectArrayLazyList(HprofHeap h, HprofByteBuffer buf, int len, long off) {\n        heap = h;\n        dumpBuffer = buf;\n        length = len;\n        offset = off;\n        idSize = dumpBuffer.getIDSize();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Instance get(int index) {\n        return heap.getInstanceByID(dumpBuffer.getID(offset + ((long)index * (long)idSize)));\n    }\n\n    public int size() {\n        return length;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ObjectArrayValuesLazyList.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.AbstractList;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ObjectArrayValuesLazyList extends AbstractList<ArrayItemValue> {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final ClassDump dumpClass;\n    private final int length;\n    private final long offset;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    ObjectArrayValuesLazyList(ClassDump dump, int len, long off) {\n        dumpClass = dump;\n        length = len;\n        offset = off;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public ArrayItemValue get(int index) {\n        return new HprofArrayValue(dumpClass, offset, index);\n    }\n\n    public int size() {\n        return length;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ObjectFieldValue.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n * represents field which refers to object represented by {@link Instance}\n * @author Tomas Hurka\n */\npublic interface ObjectFieldValue extends FieldValue {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * returns corresponding {@link Instance}.\n     * <br>\n     * Speed: normal\n     * @return corresponding {@link Instance}\n     */\n    Instance getInstance();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ObjectSizeSettings.java",
    "content": "/*\n * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.Properties;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n/**\n *\n * @author Tomas Hurka\n *\n * This class encapsulates different settings, which controls size of object.\n */\nclass ObjectSizeSettings {\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n    static final int OBJECT_ALIGNMENT = 8; // must be power of 2\n    static final int ARRAY_OVERHEAD = 4; // difference between size of java.lang.Object and java.lang.Object[0]\n\n    static final Logger LOG = Logger.getLogger(ObjectSizeSettings.class.getName());\n\n    private final HprofHeap hprofHeap;\n    private int minimumInstanceSize;\n    private int oopSize;\n\n    ObjectSizeSettings(HprofHeap heap) {\n        hprofHeap = heap;\n    }\n\n    int getMinimumInstanceSize() {\n        if (minimumInstanceSize == 0) {\n            minimumInstanceSize = hprofHeap.dumpBuffer.getIDSize() + getOopSize();\n            LOG.log(Level.CONFIG, \"MinimumInstanceSize computed as {0}\", minimumInstanceSize); // NOI18N\n        }\n        return minimumInstanceSize;\n    }\n\n    int getElementSize(byte type) {\n        if (type == HprofHeap.OBJECT) {\n            return getOopSize();\n        }\n        return hprofHeap.getValueSize(type);\n    }\n\n    void setMinimumInstanceSize(int objectSize) {\n        minimumInstanceSize = objectSize;\n        LOG.log(Level.CONFIG, \"MinimumInstanceSize set to {0}\", minimumInstanceSize);  // NOI18N\n    }\n\n    int getOopSize() {\n        if (oopSize == 0) {\n            int idSize = hprofHeap.dumpBuffer.getIDSize();\n            LOG.log(Level.CONFIG, \"OopSize uses idSize {0}\", idSize);           // NOI18N\n            if (idSize == 8) {  // can be compressed oops\n                if (hprofHeap.getClassDumpSegment().newSize) {\n                    oopSize = guessNewOopSize(idSize);\n                } else {\n                    oopSize = guessOopSize(idSize);\n                }\n            } else {\n                LOG.log(Level.CONFIG, \"OopSize set to idSize {0}\", idSize);     // NOI18N\n                oopSize = idSize;\n            }\n        }\n        return oopSize;\n    }\n\n    private int guessNewOopSize(int idSize) {\n        int size = getMinimumInstanceSize() - idSize;\n        LOG.log(Level.CONFIG, \"OopSize computed as {0}\", size);  // NOI18N\n        if (size == 4 || size == 8) {\n            return size;\n        }\n        size = (size < 8) ? 4 : 8;\n        LOG.log(Level.CONFIG, \"OopSize set to {0}\", size);  // NOI18N\n        return size;\n    }\n\n    private int guessOopSize(int idSize) {\n        // detect compressed oops\n        int size = getFieldsDiff(\"java.lang.Class$Atomic\", \"annotationDataOffset\", \"annotationTypeOffset\"); // NOI18N\n        if (size != 0) return size;\n\n        size = getFieldsDiff(\"java.util.concurrent.FutureTask\", \"runnerOffset\", \"waitersOffset\"); // NOI18N\n        if (size != 0) return size;\n\n        Properties sysProp = hprofHeap.getSystemProperties();\n        // See test/hotspot/jtreg/runtime/FieldLayout/FieldDensityTest.java\n        if (sysProp.getProperty(\"java.vm.compressedOopsMode\") != null) {        // NOI18N\n            // compressed oops\n            LOG.log(Level.CONFIG, \"OopSize guessed (A2) as {0}\", 4);            // NOI18N\n            return 4;\n        }\n        LOG.log(Level.CONFIG, \"OopSize defaults to {0}\", idSize);               // NOI18N\n        return idSize;\n    }\n\n    private int getFieldsDiff(String javaClass, String field1Name, String field2Name) {\n        JavaClass jcls = hprofHeap.getJavaClassByName(javaClass);\n        if (jcls != null) {\n            Object field1Offset = jcls.getValueOfStaticField(field1Name);\n            Object field2Offset = jcls.getValueOfStaticField(field2Name);\n            if (field1Offset instanceof Long && field2Offset instanceof Long) {\n                int guessedSize = (int) ((Long) field2Offset - (Long) field1Offset);\n                if (guessedSize == 4 || guessedSize == 8) {\n                    LOG.log(Level.CONFIG, \"OopSize guessed ({0}) as {1}\", new Object[]{javaClass, guessedSize});        // NOI18N\n                    return guessedSize;\n                }\n            }\n        }\n        return 0;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ObjectType.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ObjectType implements Type {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    static ObjectType objectType = new ObjectType();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private ObjectType() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getName() {\n        return \"object\"; // NOI18N\n    }\n\n    static Type getType(byte type) {\n        if (type == HprofHeap.OBJECT) {\n            return objectType;\n        }\n\n        return HprofPrimitiveType.getType(type);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/PrimitiveArrayDump.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.List;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass PrimitiveArrayDump extends ArrayDump implements PrimitiveArrayInstance {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final int charSize = 2;  // Character.BYTES\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    PrimitiveArrayDump(ClassDump cls, long offset) {\n        super(cls, offset);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public long getSize() {\n        return dumpClass.classDumpSegment.getArraySize(getType(), getLength());\n    }\n\n    public List<String> getValues() {\n        HprofByteBuffer dumpBuffer = dumpClass.getHprofBuffer();\n        HprofHeap heap = dumpClass.getHprof();\n        byte type = getType();\n        long offset = getArrayStartOffset();\n\n        return new PrimitiveArrayLazyList(dumpBuffer, getLength(), offset, heap.getValueSize(type), type);\n    }\n\n    char[] getChars(int start, int length) {\n        assert getType() == HprofHeap.CHAR;\n\n        char[] chars = new char[length];\n        long offset = getArrayStartOffset() + ((long)start * (long)charSize);\n        HprofByteBuffer dumpBuffer = dumpClass.getHprofBuffer();\n\n        for (int i = 0; i < length; i++) {\n            chars[i] = dumpBuffer.getChar(offset + (i * charSize));\n        }\n\n        return chars;\n    }\n\n    byte[] getBytes(int start, int length) {\n        assert getType() == HprofHeap.BYTE;\n\n        byte[] bytes = new byte[length];\n        long offset = getArrayStartOffset() + ((long)start);\n        HprofByteBuffer dumpBuffer = dumpClass.getHprofBuffer();\n\n        for (int i = 0; i < length; i++) {\n            bytes[i] = dumpBuffer.get(offset+i);\n        }\n\n        return bytes;\n    }\n\n    private long getArrayStartOffset() {\n        int idSize = dumpClass.getHprofBuffer().getIDSize();\n\n        return fileOffset + 1 + idSize + 4 + 4 + 1;\n    }\n\n    private byte getType() {\n        HprofByteBuffer dumpBuffer = dumpClass.getHprofBuffer();\n        int idSize = dumpBuffer.getIDSize();\n\n        return dumpBuffer.get(fileOffset + 1 + idSize + 4 + 4);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/PrimitiveArrayInstance.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.List;\n\n\n/**\n * represents instance of array of primitive type\n * @author Tomas Hurka\n */\npublic interface PrimitiveArrayInstance extends Instance {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * returns number of elements in the array (arr.length).\n     * <br>\n     * Speed: fast\n     * @return number of elements in the array\n     */\n    int getLength();\n\n    /**\n     * returns list of element values. The elements are instances of {@link String}.\n     * The list is ordered as the original array.\n     * <br>\n     * Speed: fast\n     * @return list of {@link String} of element values.\n     */\n    List<String> getValues();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/PrimitiveArrayLazyList.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.AbstractList;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass PrimitiveArrayLazyList extends AbstractList<String> {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final HprofByteBuffer dumpBuffer;\n    private final byte type;\n    private final int elSize;\n    private final int length;\n    private final long offset;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    PrimitiveArrayLazyList(HprofByteBuffer buf, int len, long off, int els, byte t) {\n        dumpBuffer = buf;\n        length = len;\n        offset = off;\n        elSize = els;\n        type = t;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String get(int index) {\n        return HprofInstanceValue.getTypeValue(dumpBuffer, offset + ((long)index * (long)elSize), type).toString();\n    }\n\n    public int size() {\n        return length;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/PrimitiveType.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n * represents primitive type.\n * getName() returns \"int\" \"boolean\" \"byte\" etc.\n * @author Tomas Hurka\n */\npublic interface PrimitiveType extends Type {\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/StackFrame.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass StackFrame extends HprofObject {\n\n    static final int NO_LINE_INFO = 0;\n    static final int UNKNOWN_LOCATION = -1;\n    static final int COMPILED_METHOD = -2;\n    static final int NATIVE_METHOD = -3;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final StackFrameSegment stackFrameSegment;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    StackFrame(StackFrameSegment segment, long offset) {\n        super(offset);\n        stackFrameSegment = segment;\n        assert getHprofBuffer().get(offset) == HprofHeap.STACK_FRAME;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    long getStackFrameID() {\n        return getHprofBuffer().getID(fileOffset + stackFrameSegment.stackFrameIDOffset);\n    }\n\n    String getMethodName() {\n        return getStringByOffset(stackFrameSegment.methodIDOffset);\n    }\n\n    String getMethodSignature() {\n        return getStringByOffset(stackFrameSegment.methodSignatureIDOffset);\n    }\n\n    String getSourceFile() {\n        return getStringByOffset(stackFrameSegment.sourceIDOffset);\n    }\n\n    String getClassName() {\n        int classSerial = getHprofBuffer().getInt(fileOffset + stackFrameSegment.classSerialNumberOffset);\n        return stackFrameSegment.getClassNameBySerialNumber(classSerial);\n    }\n\n    int getLineNumber() {\n        return getHprofBuffer().getInt(fileOffset + stackFrameSegment.lineNumberOffset);\n    }\n\n    private HprofByteBuffer getHprofBuffer() {\n        return stackFrameSegment.hprofHeap.dumpBuffer;\n    }\n    \n    private String getStringByOffset(long offset) {\n        long stringID = getHprofBuffer().getID(fileOffset + offset);\n        return stackFrameSegment.hprofHeap.getStringSegment().getStringByID(stringID);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/StackFrameSegment.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass StackFrameSegment extends TagBounds {\n\n    private static final int FRAME_DIV = 512;\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    HprofHeap hprofHeap;\n    final int methodIDOffset;\n    final int stackFrameIDOffset;\n    final int lengthOffset;\n    final int sourceIDOffset;\n    final int methodSignatureIDOffset;\n    final int timeOffset;\n    final int classSerialNumberOffset;\n    final int lineNumberOffset;\n    private Map<Long,Long> idToFrame;\n    private Map<Integer,String> classCache = Collections.synchronizedMap(new LoadClassCache<>());\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    StackFrameSegment(HprofHeap heap, long start, long end) {\n        super(HprofHeap.STACK_FRAME, start, end);\n\n        int idSize = heap.dumpBuffer.getIDSize();\n        hprofHeap = heap;\n        timeOffset = 1;\n        lengthOffset = timeOffset + 4;\n        stackFrameIDOffset = lengthOffset + 4;\n        methodIDOffset = stackFrameIDOffset + idSize;\n        methodSignatureIDOffset = methodIDOffset + idSize;\n        sourceIDOffset = methodSignatureIDOffset + idSize;\n        classSerialNumberOffset = sourceIDOffset + idSize;\n        lineNumberOffset = classSerialNumberOffset + 4;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    StackFrame getStackFrameByID(long stackFrameID) {\n        Long initialOffset;\n        long[] offset;\n\n        initIdToFrame();\n        initialOffset = idToFrame.get(new Long(stackFrameID/FRAME_DIV));\n        if (initialOffset == null) {\n            initialOffset = new Long(startOffset);\n        }\n        offset = new long[] { initialOffset.longValue() };\n        while (offset[0] < endOffset) {\n            long start = offset[0];\n            long frameID = readStackFrameTag(offset);\n\n            if (frameID == stackFrameID) {\n                return new StackFrame(this, start);\n            }\n        }\n        return null;\n    }\n\n    private HprofByteBuffer getDumpBuffer() {\n        return  hprofHeap.dumpBuffer;\n    }\n\n    private long readStackFrameTag(long[] offset) {\n        long start = offset[0];\n\n        if (hprofHeap.readTag(offset) != HprofHeap.STACK_FRAME) {\n            return 0;\n        }\n\n        return getDumpBuffer().getID(start + stackFrameIDOffset);\n    }\n    \n    private synchronized void initIdToFrame() {\n        if (idToFrame == null) {\n            long[] offset = new long[] { startOffset };\n\n            idToFrame = new HashMap<>();\n            while (offset[0] < endOffset) {\n                long start = offset[0];\n                long frameID = readStackFrameTag(offset);\n                Long frameIDMask = new Long(frameID/FRAME_DIV);\n                Long minOffset = idToFrame.get(frameIDMask);\n                \n                if (minOffset == null || minOffset > start) {\n                    idToFrame.put(frameIDMask, new Long(start));\n                }\n            }\n//            System.out.println(\"idToFrame size:\"+idToFrame.size());\n        }\n    }\n    \n    String getClassNameBySerialNumber(int classSerialNumber) {\n        Integer classSerialNumberObj = Integer.valueOf(classSerialNumber);\n        String className = classCache.get(classSerialNumberObj);\n        \n        if (className == null) {\n            LoadClass loadClass = hprofHeap.getLoadClassSegment().getClassBySerialNumber(classSerialNumber);\n            \n            if (loadClass != null) {\n                className = loadClass.getName();\n            } else {\n                className = \"N/A\";      // NOI18N\n            }\n            classCache.put(classSerialNumberObj, className);\n        }\n        return className;\n    }\n\n    private static class LoadClassCache<K,V> extends LinkedHashMap<K,V> {\n        private static final int SIZE = 1000;\n        \n        LoadClassCache() {\n            super(SIZE,0.75f,true);\n        }\n\n        protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {\n            return size() > SIZE;\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/StackTrace.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass StackTrace extends HprofObject {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final StackTraceSegment stackTraceSegment;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    StackTrace(StackTraceSegment segment, long offset) {\n        super(offset);\n        stackTraceSegment = segment;\n        assert getHprofBuffer().get(offset) == HprofHeap.STACK_TRACE;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    long getSerialNumber() {\n        return getHprofBuffer().getInt(fileOffset + stackTraceSegment.stackTraceSerialNumberOffset);\n    }\n\n    long getThreadSerialNumber() {\n        return getHprofBuffer().getInt(fileOffset + stackTraceSegment.threadSerialNumberOffset);\n    }\n\n    StackFrame[] getStackFrames() {\n        HprofByteBuffer buf = getHprofBuffer();\n        int frames = buf.getInt(fileOffset + stackTraceSegment.numberOfFramesOffset);\n        StackFrame[] fr = new StackFrame[frames];\n        long idOffset = fileOffset + stackTraceSegment.framesListOffset;\n        StackFrameSegment stackFrameSegment = stackTraceSegment.hprofHeap.getStackFrameSegment();\n\n         for (int i=0;i<frames;i++,idOffset+=buf.getIDSize()) {\n             long frameID = buf.getID(idOffset);\n             fr[i] = stackFrameSegment.getStackFrameByID(frameID);\n        }\n        return fr;\n    }\n\n    private HprofByteBuffer getHprofBuffer() {\n        return stackTraceSegment.hprofHeap.dumpBuffer;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/StackTraceSegment.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass StackTraceSegment extends TagBounds {\n\n    private static final int SERIALNUM_DIV = 16;\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    HprofHeap hprofHeap;\n    final int threadSerialNumberOffset;\n    final int stackTraceSerialNumberOffset;\n    final int lengthOffset;\n    final int framesListOffset;\n    final int numberOfFramesOffset;\n    final int timeOffset;\n    private Map<Long,Long> serialNumToStackTrace;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    StackTraceSegment(HprofHeap heap, long start, long end) {\n        super(HprofHeap.STACK_TRACE, start, end);\n\n        hprofHeap = heap;\n        timeOffset = 1;\n        lengthOffset = timeOffset + 4;\n        stackTraceSerialNumberOffset = lengthOffset + 4;\n        threadSerialNumberOffset = stackTraceSerialNumberOffset + 4;\n        numberOfFramesOffset = threadSerialNumberOffset + 4;\n        framesListOffset = numberOfFramesOffset + 4;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    StackTrace getStackTraceBySerialNumber(long stackTraceSerialNumber) {\n        Long initialOffset;\n        long[] offset;\n\n        initSerialNumToFrame();\n        initialOffset = serialNumToStackTrace.get(new Long(stackTraceSerialNumber/SERIALNUM_DIV));\n        if (initialOffset == null) {\n            initialOffset = new Long(startOffset);\n        }\n        offset = new long[] { initialOffset.longValue() };\n        while (offset[0] < endOffset) {\n            long start = offset[0];\n            long serialNumber = readStackTraceTag(offset);\n\n            if (serialNumber == stackTraceSerialNumber) {\n                return new StackTrace(this, start);\n            }\n        }\n        return null;\n    }\n\n    private HprofByteBuffer getDumpBuffer() {\n        HprofByteBuffer dumpBuffer = hprofHeap.dumpBuffer;\n\n        return dumpBuffer;\n    }\n\n    private int readStackTraceTag(long[] offset) {\n        long start = offset[0];\n\n        if (hprofHeap.readTag(offset) != HprofHeap.STACK_TRACE) {\n            return 0;\n        }\n        return getDumpBuffer().getInt(start + stackTraceSerialNumberOffset);\n    }\n\n    private synchronized void initSerialNumToFrame() {\n        if (serialNumToStackTrace == null) {\n            long[] offset = new long[] { startOffset };\n\n            serialNumToStackTrace = new HashMap<>();\n            while (offset[0] < endOffset) {\n                long start = offset[0];\n                long serialNumber = readStackTraceTag(offset);\n                Long serialNumberMask = new Long(serialNumber/SERIALNUM_DIV);\n                Long minOffset = serialNumToStackTrace.get(serialNumberMask);\n                \n                if (minOffset == null || minOffset > start) {\n                    serialNumToStackTrace.put(serialNumberMask, new Long(start));\n                }\n            }\n//            System.out.println(\"serialNumToStackTrace size:\"+serialNumToStackTrace.size());\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/StringSegment.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.UnsupportedEncodingException;\nimport java.util.Collections;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass StringSegment extends TagBounds {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final int UTF8CharsOffset;\n    private final int lengthOffset;\n    private final int stringIDOffset;\n    private final int timeOffset;\n    private LongHashMap stringIDMap;\n    private HprofHeap hprofHeap;\n    private Map<Long,String> stringCache = Collections.synchronizedMap(new StringCache<>());\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    StringSegment(HprofHeap heap, long start, long end) {\n        super(HprofHeap.STRING, start, end);\n\n        int idSize = heap.dumpBuffer.getIDSize();\n        hprofHeap = heap;\n        timeOffset = 1;\n        lengthOffset = timeOffset + 4;\n        stringIDOffset = lengthOffset + 4;\n        UTF8CharsOffset = stringIDOffset + idSize;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    String getStringByID(long stringID) {\n        Long stringIDObj = new Long(stringID);\n        String string = stringCache.get(stringIDObj);\n        if (string == null) {\n            string = createStringByID(stringID);\n            stringCache.put(stringIDObj,string);\n        }\n        return string;\n    }\n\n    private String createStringByID(long stringID) {\n        long start = getStringOffsetByID(stringID);\n\n        if (start == -1) {\n            return \"<unresolved string 0x\"+Long.toHexString(stringID)+\">\"; // NOI18N\n        }\n        return getString(start);\n    }\n\n    private String getString(long start) {\n        HprofByteBuffer dumpBuffer = getDumpBuffer();\n\n        int len = dumpBuffer.getInt(start + lengthOffset);\n        byte[] chars = new byte[len - dumpBuffer.getIDSize()];\n        dumpBuffer.get(start + UTF8CharsOffset, chars);\n\n        String s = \"Error\"; // NOI18N\n\n        try {\n            s = new String(chars, \"UTF-8\"); // NOI18N\n        } catch (UnsupportedEncodingException ex) {\n            ex.printStackTrace();\n        }\n\n        return s;\n    }\n\n    private synchronized long getStringOffsetByID(long stringID) {\n        if (stringIDMap == null) {\n            stringIDMap = new LongHashMap(32768);\n\n            long[] offset = new long[] { startOffset };\n\n            while (offset[0] < endOffset) {\n                long start = offset[0];\n                long sID = readStringTag(offset);\n                if (sID != 0) {\n                    stringIDMap.put(sID, start);\n                }\n            }\n        }\n        if (stringID == 0) {\n            return -1; // string not found\n        }\n        return stringIDMap.get(stringID);\n    }\n\n    private HprofByteBuffer getDumpBuffer() {\n        HprofByteBuffer dumpBuffer = hprofHeap.dumpBuffer;\n\n        return dumpBuffer;\n    }\n\n    private long readStringTag(long[] offset) {\n        long start = offset[0];\n\n        if (hprofHeap.readTag(offset) != HprofHeap.STRING) {\n            return 0;\n        }\n\n        return getDumpBuffer().getID(start + stringIDOffset);\n    }\n\n    private static class StringCache<K,V> extends LinkedHashMap<K,V> {\n        private static final int SIZE = 1000;\n        \n        StringCache() {\n            super(SIZE,0.75f,true);\n        }\n\n        protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {\n            return size() > SIZE;\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/Summary.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class Summary implements HeapSummary {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    final int totalLiveBytes;\n    final int totalLiveInstances;\n    final long time;\n    final long totalAllocatedBytes;\n    final long totalAllocatedInstances;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    Summary(HprofByteBuffer dumpBuffer, long startOffset) {\n        assert dumpBuffer.get(startOffset) == HprofHeap.HEAP_SUMMARY;\n        dumpBuffer.getInt(startOffset + 1); // time\n        dumpBuffer.getInt(startOffset + 1 + 4); // tag length\n        totalLiveBytes = dumpBuffer.getInt(startOffset + 1 + 4 + 4);\n        totalLiveInstances = dumpBuffer.getInt(startOffset + 1 + 4 + 4 + 4);\n        totalAllocatedBytes = dumpBuffer.getLong(startOffset + 1 + 4 + 4 + 4 + 4);\n        totalAllocatedInstances = dumpBuffer.getLong(startOffset + 1 + 4 + 4 + 4 + 4 + 8);\n        time = dumpBuffer.getTime();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public long getTime() {\n        return time;\n    }\n\n    public long getTotalAllocatedBytes() {\n        return totalAllocatedBytes;\n    }\n\n    public long getTotalAllocatedInstances() {\n        return totalAllocatedInstances;\n    }\n\n    public long getTotalLiveBytes() {\n        return totalLiveBytes;\n    }\n\n    public long getTotalLiveInstances() {\n        return totalLiveInstances;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/SyntheticClassField.java",
    "content": "/*\n * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass SyntheticClassField extends HprofField {\n    private static final byte valueType = (byte)HprofHeap.OBJECT;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    SyntheticClassField(ClassDump cls) {\n        super(cls,cls.fileOffset);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getName() {\n        return \"<class>\";   // NOI18N\n    }\n\n    byte getValueType() {\n        return valueType;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/SyntheticClassObjectValue.java",
    "content": "/*\n * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass SyntheticClassObjectValue extends HprofInstanceObjectValue {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    SyntheticClassObjectValue(InstanceDump i, HprofField f, long fieldOffset) {\n        super(i, f, fieldOffset);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    Object getTypeValue() {\n        return new Long(getInstanceId());\n    }\n\n    public Instance getInstance() {\n        return new ClassDumpInstance(field.classDump);\n    }\n\n    long getInstanceId() {\n        return field.classDump.getJavaClassId();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/TagBounds.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport static org.graalvm.visualvm.lib.jfluid.heap.HprofHeap.*;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass TagBounds {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    final int tag;\n    final long startOffset;\n    long endOffset;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    TagBounds(int t, long start, long end) {\n        tag = t;\n        startOffset = start;\n        endOffset = end;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    TagBounds union(TagBounds otherTagBounds) {\n        if (otherTagBounds == null) {\n            return this;\n        }\n\n        long start = Math.min(startOffset, otherTagBounds.startOffset);\n        long end = Math.max(endOffset, otherTagBounds.endOffset);\n\n        return new TagBounds(-1, start, end);\n    }\n\n    //---- Serialization support\n    void writeToStream(DataOutputStream out) throws IOException {\n        out.writeInt(tag);\n        out.writeLong(startOffset);\n        out.writeLong(endOffset);\n    }\n\n    TagBounds(DataInputStream dis) throws IOException {\n        tag = dis.readInt();\n        startOffset = dis.readLong();\n        endOffset = dis.readLong();\n    }\n\n    static void writeToStream(TagBounds[] bounds, DataOutputStream out) throws IOException {\n        int tags = 0;\n        for (TagBounds bound : bounds) {\n            if (bound != null) {\n                tags++;\n            }\n        }\n        out.writeInt(tags);\n        for (TagBounds bound : bounds) {\n            if (bound != null) {\n                bound.writeToStream(out);\n            }\n        }\n    }\n\n    static void readFromStream(DataInputStream dis, HprofHeap heap, TagBounds[] heapTagBounds) throws IOException {\n        int tags = dis.readInt();\n        for (int i = 0; i<tags; i++) {\n            int tag = dis.readInt();\n            long startOffset = dis.readLong();\n            long endOffset = dis.readLong();\n            TagBounds newBounds;\n                        \n            if (tag == LOAD_CLASS) {\n                newBounds = new LoadClassSegment(heap, startOffset, endOffset);\n            } else if (tag == STRING) {\n                newBounds = new StringSegment(heap, startOffset, endOffset);\n            } else if (tag == STACK_TRACE) {\n                newBounds = new StackTraceSegment(heap, startOffset, endOffset);\n            } else if (tag == STACK_FRAME) {\n                newBounds = new StackFrameSegment(heap, startOffset, endOffset);\n            } else if (tag == CLASS_DUMP) {\n                newBounds = new ClassDumpSegment(heap, startOffset, endOffset, dis);\n            } else {\n                newBounds = new TagBounds(tag, startOffset, endOffset);\n            }\n            heapTagBounds[newBounds.tag] = newBounds;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ThreadObjectGCRoot.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n * This represents one Thread Object GC root. It has kind ({@link GCRoot#THREAD_OBJECT}) and also corresponding\n * {@link Instance}, which is actual GC root.\n * @author Tomas Hurka\n */\npublic interface ThreadObjectGCRoot extends GCRoot {\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns an array of stack trace elements,\n     * each representing one stack frame.  The zeroth element of the array\n     * (assuming the array's length is non-zero) represents the top of the\n     * stack, which is the last method invocation in the sequence.  Typically,\n     * this is the point at which this throwable was created and thrown.\n     * The last element of the array (assuming the array's length is non-zero)\n     * represents the bottom of the stack, which is the first method invocation\n     * in the sequence.\n     * <br>\n     * Speed:normal\n     * @return an array of stack trace elements representing the stack trace\n     *         pertaining to this throwable.\n     */\n    StackTraceElement[] getStackTrace();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/ThreadObjectHprofGCRoot.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ThreadObjectHprofGCRoot extends HprofGCRoot implements ThreadObjectGCRoot {\n\n    ThreadObjectHprofGCRoot(HprofGCRoots r, long offset) {\n        super(r, offset);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public StackTraceElement[] getStackTrace() {\n        int stackTraceSerialNumber = getStackTraceSerialNumber();\n\n        if (stackTraceSerialNumber != 0) {\n            StackTrace stackTrace = roots.heap.getStackTraceSegment().getStackTraceBySerialNumber(stackTraceSerialNumber);\n            if (stackTrace != null) {\n                StackFrame[] frames = stackTrace.getStackFrames();\n                StackTraceElement[] stackElements = new StackTraceElement[frames.length];\n\n                for (int i=0;i<frames.length;i++) {\n                    StackFrame f = frames[i];\n                    String className = f.getClassName();\n                    String method = f.getMethodName();\n                    String source = f.getSourceFile();\n                    int number = f.getLineNumber();\n\n                    if (number == StackFrame.NATIVE_METHOD) {\n                        number = -2;\n                    } else if (number == StackFrame.NO_LINE_INFO || number == StackFrame.UNKNOWN_LOCATION) {\n                        number = -1;\n                    }\n                    stackElements[i] = new StackTraceElement(className,method,source,number);\n                }\n                return stackElements;\n            }\n        }\n        return null;\n    }\n\n    int getThreadSerialNumber() {\n        return getHprofBuffer().getInt(fileOffset + 1 + getHprofBuffer().getIDSize());\n    }\n\n    private int getStackTraceSerialNumber() {\n        return getHprofBuffer().getInt(fileOffset + 1 + getHprofBuffer().getIDSize() + 4);\n    }    \n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/TreeObject.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.IOException;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass TreeObject {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final int BUFFER_SIZE = (64 * 1024) / 8;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private HprofHeap heap;\n    private LongBuffer readBuffer;\n    private LongBuffer writeBuffer;\n    private Set<Long> unique;\n//private long nextLevelSize;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    TreeObject(HprofHeap h, LongBuffer leaves) {\n        heap = h;\n        writeBuffer = leaves;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n\n    synchronized void computeTrees() {\n        boolean changed;\n        try {\n            createBuffers();\n            do {\n                switchBuffers();\n                changed = computeOneLevel();\n//System.out.println(\"Tree obj.   \"+heap.idToOffsetMap.treeObj);\n//if (changed) System.out.println(\"Next level  \"+nextLevelSize);\n            } while (changed);\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n        deleteBuffers();\n//System.out.println(\"Done!\");\n    }\n\n    private boolean computeOneLevel() throws IOException {\n//nextLevelSize = 0;\n        boolean changed = false;\n        int idSize = heap.dumpBuffer.getIDSize();\n        for (;;) {\n            long instanceId = readLong();\n            Instance instance;\n            List<FieldValue> fieldValues;\n            Iterator<FieldValue> valuesIt;\n            long retainedSize = 0;\n            \n            if (instanceId == 0) {  // end of level\n                break;\n            }\n            instance = heap.getInstanceByID(instanceId);\n            if (instance instanceof ObjectArrayInstance) {\n                ObjectArrayDump array = (ObjectArrayDump) instance;\n                int arrSize = array.getLength();\n                long offset = array.getOffset();\n                long size = 0;\n                LongSet refs = new LongSet();\n                \n                for  (int i=0; i<arrSize && size != -1; i++) {\n                    long refInstanceId = heap.dumpBuffer.getID(offset + (i * idSize));\n                    size = checkInstance(refInstanceId, refs);\n                    retainedSize += size;\n                }\n                changed |= processInstance(instance, size, retainedSize);\n                continue;\n            } else if (instance instanceof PrimitiveArrayInstance) {\n                assert false:\"Error - PrimitiveArrayInstance not allowed \"+instance.getJavaClass().getName()+\"#\"+instance.getInstanceNumber();\n                continue;\n            } else if (instance instanceof ClassDumpInstance) {\n                ClassDump javaClass = ((ClassDumpInstance) instance).classDump;\n                \n                fieldValues = javaClass.getStaticFieldValues();\n            } else if (instance instanceof InstanceDump) {\n                fieldValues = instance.getFieldValues();\n            } else {\n                if (instance == null) {\n                    System.err.println(\"HeapWalker Warning - null instance for \" + instanceId); // NOI18N\n                    continue;\n                }\n                throw new IllegalArgumentException(\"Illegal type \" + instance.getClass()); // NOI18N\n            }\n            long size = 0;\n            LongSet refs = new LongSet();\n            valuesIt = fieldValues.iterator();\n            while (valuesIt.hasNext() && size != -1) {\n                FieldValue val = valuesIt.next();\n                \n                if (val instanceof ObjectFieldValue) {\n                    Instance refInstance = ((ObjectFieldValue) val).getInstance();\n                    size = checkInstance(refInstance, refs);\n                    retainedSize += size;\n                }\n            }\n            changed |= processInstance(instance, size, retainedSize);\n        }\n        return changed;\n    }\n    \n    private boolean processInstance(Instance instance, long size, long retainedSize) throws IOException {\n        if (size != -1) {\n            LongMap.Entry entry = heap.idToOffsetMap.get(instance.getInstanceId());\n            entry.setRetainedSize(instance.getSize()+retainedSize);\n            entry.setTreeObj();\n            if (entry.hasOnlyOneReference()) {\n                long gcRootPointer = entry.getNearestGCRootPointer();\n                if (gcRootPointer != 0) {\n                    if (unique.add(gcRootPointer)) {\n                        writeLong(gcRootPointer);\n                    }\n                }\n            }\n            return true;\n        }\n        return false;\n    }\n    \n    private void createBuffers() {\n        readBuffer = new LongBuffer(BUFFER_SIZE, heap.cacheDirectory);\n    }\n    \n    private void deleteBuffers() {\n        readBuffer.delete();\n        writeBuffer.delete();\n    }\n        \n    private long readLong() throws IOException {\n        return readBuffer.readLong();\n    }\n    \n    private void switchBuffers() throws IOException {\n        LongBuffer b = readBuffer;\n        readBuffer = writeBuffer;\n        writeBuffer = b;\n        readBuffer.startReading();\n        writeBuffer.reset();\n        unique = new HashSet<>(4000);\n    }\n    \n    private void writeLong(long instanceId) throws IOException {\n        if (instanceId != 0) {\n            writeBuffer.writeLong(instanceId);\n//nextLevelSize++;\n        }\n    }\n    \n    private long checkInstance(Instance refInstance, LongSet refs) throws IOException {\n        if (refInstance != null) {\n            return checkInstance(refInstance.getInstanceId(), refs);\n        }\n        return 0;\n    }\n    \n    private long checkInstance(long refInstanceId, LongSet refs) throws IOException {\n        if (refInstanceId != 0L) {\n            LongMap.Entry refEntry = heap.idToOffsetMap.get(refInstanceId);\n            \n            if (refEntry == null) {\n                return 0;\n            }\n            if (!refEntry.hasOnlyOneReference()) {\n                return -1;\n            }\n            if (!refEntry.isTreeObj()) {\n                return -1;\n            }\n            if (refs.add(refInstanceId)) {\n                return 0;\n            }\n            return refEntry.getRetainedSize();\n        }\n        return 0;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/Type.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n * represents primitive type or object. Heap does not distinguish different\n * type of objects. All sub classes of java.lang.Object has type \"object\".\n *\n * @author Tomas Hurka\n */\npublic interface Type {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * return the human readable name of the type. \"object\" is returned\n     * for object type.\n     * @return name of the type\n     */\n    String getName();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/src/org/graalvm/visualvm/lib/jfluid/heap/Value.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\n\n/**\n * This is common interface representing value. There are two types of value.\n * One is {@link ObjectFieldValue} and the second one is {@link ArrayItemValue}\n * @author Tomas Hurka\n */\npublic interface Value {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * return the {@link Instance} where this value is defined.\n     * <br>\n     * Speed: fast\n     * @return the {@link Instance} where this value is defined.\n     */\n    Instance getDefiningInstance();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/test/unit/src/org/graalvm/visualvm/lib/jfluid/heap/HeapTest.java",
    "content": "/*\n * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.jfluid.heap;\n\nimport java.io.BufferedOutputStream;\nimport java.util.Map;\nimport java.util.Date;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.io.LineNumberReader;\nimport java.io.OutputStream;\nimport java.io.PrintStream;\nimport java.net.URISyntaxException;\nimport java.net.URL;\nimport java.text.DateFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Properties;\nimport java.util.TimeZone;\nimport java.util.TreeMap;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport static org.junit.Assert.*;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class HeapTest {\n    private Heap heap;\n\n    public HeapTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n    }\n\n    @Before\n    public void setUp() throws IOException, URISyntaxException {\n        URL url = getClass().getResource(\"small_heap.bin\");\n        heap = HeapFactory.createHeap(new File(url.toURI()));\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    /**\n     * Test of getAllClasses method, of class Heap.\n     */\n    @Test\n    public void testGetAllClasses() {\n        System.out.println(\"getAllClasses\");\n        List<JavaClass> result = heap.getAllClasses();\n        assertEquals(443, result.size());\n    }\n\n    /**\n     * Test of getGCRoot method, of class Heap.\n     */\n    @Test\n    public void testGetGCRoot() {\n        System.out.println(\"getGCRoot\");\n        Instance instance_2 = heap.getInstanceByID(1684081264);\n        Collection<GCRoot> resultList = heap.getGCRoots(instance_2);\n        assertEquals(resultList.size(), 2);\n        GCRoot[] results = resultList.toArray(new GCRoot[0]);\n        GCRoot result = results[0];\n        assertEquals(instance_2, result.getInstance());\n        assertEquals(GCRoot.JAVA_FRAME, result.getKind());\n        result = results[1];\n        assertEquals(instance_2, result.getInstance());\n        assertEquals(GCRoot.MONITOR_USED, result.getKind());\n    }\n\n    /**\n     * Test of getGCRoots method, of class Heap.\n     */\n    @Test\n    public void testGetGCRoots() {\n        System.out.println(\"getGCRoots\");\n        Collection<GCRoot> result = heap.getGCRoots();\n        assertEquals(491, result.size());\n    }\n    \n    /**\n     * Test of getJavaClassByName method, of class Heap.\n     */\n    @Test\n    public void testGetJavaClassByName() {\n        System.out.println(\"getJavaClassByName\");\n        String fqn = \"java.io.PrintStream\";\n        JavaClass result = heap.getJavaClassByName(fqn);\n        assertEquals(fqn, result.getName());\n    }\n    \n    /**\n     * Test of getInstanceByID method, of class Heap.\n     */\n    @Test\n    public void testGetInstanceByID() {\n        System.out.println(\"getInstanceByID\");\n        String fqn = \"java.io.PrintStream\";\n        JavaClass printStream = heap.getJavaClassByName(fqn);\n        Instance printStreamInstance = printStream.getInstances().get(0);\n        long instanceId = printStreamInstance.getInstanceId();\n        Instance result = heap.getInstanceByID(instanceId);\n        assertEquals(instanceId, result.getInstanceId());\n    }\n\n    /**\n     * Test of getJavaClassByID method, of class Heap.\n     */\n    @Test\n    public void testGetJavaClassByID() {\n        System.out.println(\"getJavaClassByID\");\n        String fqn = \"java.io.PrintStream\";\n        JavaClass printStream = heap.getJavaClassByName(fqn);\n        long javaclassId = printStream.getJavaClassId();\n        JavaClass result = heap.getJavaClassByID(javaclassId);\n        assertEquals(javaclassId, result.getJavaClassId());\n    }\n\n    /**\n     * Test of getJavaClassesByRegExp method, of class Heap.\n     */\n    @Test\n    public void testGetJavaClassesByRegExp() {\n        System.out.println(\"getJavaClassesByRegExp\");\n        String regexp = \".*Lock.*\";\n        Collection<JavaClass> result = heap.getJavaClassesByRegExp(regexp);\n        assertEquals(9, result.size());\n    }\n\n    /**\n     * Test of getSummary method, of class Heap.\n     */\n    @Test\n    public void testGetSummary() {\n        System.out.println(\"getSummary\");\n        HeapSummary result = heap.getSummary();\n        assertEquals(140120,result.getTotalLiveBytes());\n        assertEquals(2208,result.getTotalLiveInstances());\n    }\n\n    /**\n     * Test of getSystemProperties method, of class Heap.\n     */\n    @Test\n    public void testGetSystemProperties() {\n        System.out.println(\"getSystemProperties\");\n        Properties result = heap.getSystemProperties();\n        assertEquals(\"2.4.18-openmosix4\", result.getProperty(\"os.version\"));\n    }\n\n    /**\n     * Test of getBiggestObjectsByRetainedSize method, of class Heap.\n     */\n    @Test\n    public void testGetBiggestObjectsByRetainedSize() {\n        System.out.println(\"getBiggestObjectsByRetainedSize\");\n        List<Instance> result = heap.getBiggestObjectsByRetainedSize(2);\n        Instance i1 = result.get(0);\n        Instance i2 = result.get(1);\n        assertEquals(66544, i1.getRetainedSize());\n        assertEquals(25080, i2.getRetainedSize());\n    }\n    \n    /**\n     * Test of getRetainedSizeByClass method, of class JavaClass.\n     */\n    @Test\n    public void testGetRetainedSizeByClass() {\n        System.out.println(\"getRetainedSizeByClass\");\n        JavaClass string = heap.getJavaClassByName(String.class.getName());\n        JavaClass hashMap = heap.getJavaClassByName(HashMap.class.getName());\n        JavaClass array = heap.getJavaClassByName(ArrayList.class.getName());\n        \n        assertEquals(17864, string.getRetainedSizeByClass());\n        assertEquals(11712, hashMap.getRetainedSizeByClass());\n        assertEquals(600, array.getRetainedSizeByClass());\n    }\n\n    /**\n     * Test of getAllInstancesIterator method, of class Heap.\n     */\n    @Test\n    public void getAllInstancesIterator() {\n        System.out.println(\"getAllInstancesIterator\");\n        Iterator<Instance> instanceIt = heap.getAllInstancesIterator();\n        int instances = 0;\n        \n        while (instanceIt.hasNext()) {\n            Instance i = instanceIt.next();\n            instances++;\n        }\n        assertEquals(instances, heap.getSummary().getTotalLiveInstances());\n    }\n\n    /**\n     * Test of getInstancesIterator method, of class JavaClass.\n     */\n    @Test\n    public void getInstancesIterator() {\n        System.out.println(\"getInstancesIterator\");\n        List<JavaClass> classes = heap.getAllClasses();\n        \n        for (JavaClass clazz : classes) {\n            List<Instance> instances = clazz.getInstances();\n            Iterator<Instance> instIt = clazz.getInstancesIterator();\n            \n            for (Instance i : instances) {\n                assertTrue(instIt.hasNext());\n                assertEquals(i, instIt.next());\n            }\n            assertFalse(instIt.hasNext());\n        }\n    }\n    \n    @Test\n    public void testHeapDumpLog() throws IOException, URISyntaxException {\n        System.out.println(\"testHeapDumpLog\");\n        File outFile = File.createTempFile(\"testHeapDumpLog\", \".txt\");\n        URL url = getClass().getResource(\"testHeapDumpLog.txt\");\n        File goledFile = new File(url.toURI()); \n        OutputStream outs = new FileOutputStream(outFile);\n        PrintStream out = new PrintStream(new BufferedOutputStream(outs,128*1024),false,\"UTF-8\");\n        HeapSummary summary = heap.getSummary();\n        out.println(\"Heap Summary\");\n        DateFormat df = new SimpleDateFormat(\"MMM dd, yyyy hh:mm:ss aaa\");\n        df.setTimeZone(TimeZone.getTimeZone(\"UTC\"));\n        out.println(\"Time \"+df.format(new Date(summary.getTime())));\n        out.println(\"Live instances \"+summary.getTotalLiveInstances());\n        out.println(\"Live bytes \"+summary.getTotalLiveBytes());\n        out.println(\"Total alloc instances \"+summary.getTotalAllocatedInstances());\n        out.println(\"Total alloc bytes \"+summary.getTotalAllocatedBytes());\n        Collection<JavaClass> classes = heap.getAllClasses();\n        out.println(\"Classes size \"+classes.size());\n        out.println(\"System properties: \");\n        Properties props = heap.getSystemProperties();\n        for(Map.Entry<?, ?> entry : new TreeMap<>(props).entrySet()) {\n            \n            out.println(entry.getKey()+\" \"+entry.getValue());\n        }\n        for (JavaClass jc : classes) {\n            JavaClass sc = jc.getSuperClass();\n            out.println(\" Id 0x\"+Long.toHexString(jc.getJavaClassId())+\" Class \"+jc.getName()+\" SuperClass \"+(sc==null?\"null\":sc.getName())+\n                    \" Instance size \"+jc.getInstanceSize()+\" Instance count \"+jc.getInstancesCount()+\" All Instances Size \"+jc.getAllInstancesSize());\n            \n            for (FieldValue fv : jc.getStaticFieldValues()) {\n                out.println(\"  Static Field name \"+fv.getField().getName()+\" type \"+fv.getField().getType().getName()+\" value \"+fv.getValue());\n                if (fv instanceof ObjectFieldValue) {\n                    ObjectFieldValue objectField = (ObjectFieldValue)fv;\n                    Instance refInstance = objectField.getInstance();\n                    if (refInstance != null) {\n                        out.println(\"   Ref object \"+refInstance.getJavaClass().getName()+\"#\"+refInstance.getInstanceNumber());\n                    }\n                }\n            }\n                        \n            for (Field in : jc.getFields()) {\n                out.println(\"  Field name \"+in.getName()+\" type \"+in.getType().getName());\n            }\n            \n            for (Instance in : jc.getInstances()) {\n                out.println(\"  Instance Id 0x\"+Long.toHexString(in.getInstanceId())+\" number \"+in.getInstanceNumber()+\" retained size \"+in.getRetainedSize());\n                \n                for (FieldValue inField : in.getFieldValues()) {\n                    out.println(\"   Instance Field name \"+inField.getField().getName()+\" type \"+inField.getField().getType().getName()+\" value \"+inField.getValue());\n                    if (inField instanceof ObjectFieldValue) {\n                        ObjectFieldValue objectField = (ObjectFieldValue) inField;\n                        Instance refInstance = objectField.getInstance();\n                        if (refInstance != null) {\n                            out.println(\"    Ref object \"+refInstance.getJavaClass().getName()+\"#\"+refInstance.getInstanceNumber());\n                        }\n                    }\n                }\n                Collection<Value> references = in.getReferences();\n                out.println(\"   References count \"+references.size());\n                for (Value val : references) {\n                    \n                    if (val instanceof ArrayItemValue) {\n                        ArrayItemValue arrVal = (ArrayItemValue) val;\n                        \n                        out.println(\"   Element \"+arrVal.getIndex()+\" of array 0x\"+Long.toHexString(arrVal.getDefiningInstance().getInstanceId()));\n                    } else if (val instanceof FieldValue) {\n                        FieldValue fieldVal = (FieldValue) val;\n                        Field f = fieldVal.getField();\n                        \n                        if (f.isStatic()) {\n                            out.println(\"   Field \"+f.getName()+\" of Class \"+f.getDeclaringClass().getName());\n                        } else {\n                            out.println(\"   Field \"+f.getName()+\" of instance 0x\"+Long.toHexString(fieldVal.getDefiningInstance().getInstanceId()));\n                        }\n                    } else {\n                        out.println(\"   Error \"+val);\n                    }\n                }\n                out.println(\"   Path to nearest GC root\");\n                Instance p = in;\n                Instance next = p.getNearestGCRootPointer();\n                while (!p.equals(next)) {\n                    if (next == null) {\n                        out.println(\"    Null\");\n                        break;\n                    }\n                    out.println(\"    Next object \"+next.getJavaClass().getName()+\"#\"+next.getInstanceNumber());\n                    p = next;\n                    next = next.getNearestGCRootPointer();\n                }\n            }\n        }\n        Collection<GCRoot> roots = heap.getGCRoots();\n        out.println(\"GC roots \"+roots.size());\n        \n        for(GCRoot root : roots) {\n            Instance i = root.getInstance();\n            \n            out.println(\"Root kind \"+root.getKind()+\" Class \"+i.getJavaClass().getName()+\"#\"+i.getInstanceNumber());\n        }\n        out.close();\n        compareTextFiles(goledFile,outFile);\n        outFile.delete();\n    }\n\n    private void compareTextFiles(File goledFile, File outFile) throws IOException {\n        InputStreamReader goldenIsr = new InputStreamReader(new FileInputStream(goledFile),\"UTF-8\");\n        LineNumberReader goldenReader = new LineNumberReader(goldenIsr);\n        InputStreamReader isr = new InputStreamReader(new FileInputStream(outFile),\"UTF-8\");\n        LineNumberReader reader = new LineNumberReader(isr);\n        String goldenLine = \"\";\n        String line = \"\";\n        \n        while(goldenLine != null && goldenLine.equals(line)) {\n            goldenLine = goldenReader.readLine();\n            line = reader.readLine();\n        }\n        assertEquals(\"File \"+goledFile.getAbsolutePath()+\" and \"+outFile.getAbsolutePath()+\" differs on line \"+goldenReader.getLineNumber(), goldenLine, line);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.heap/test/unit/src/org/graalvm/visualvm/lib/jfluid/heap/testHeapDumpLog.txt",
    "content": "Heap Summary\nTime Jun 16, 2006 11:46:11 AM\nLive instances 2208\nLive bytes 140120\nTotal alloc instances -1\nTotal alloc bytes -1\nClasses size 443\nSystem properties: \nfile.encoding ISO-8859-1\nfile.encoding.pkg sun.io\nfile.separator /\njava.awt.graphicsenv sun.awt.X11GraphicsEnvironment\njava.awt.printerjob sun.print.PSPrinterJob\njava.class.path TestApp.jar\njava.class.version 50.0\njava.endorsed.dirs /usr/java/jdk1.6.0/jre/lib/endorsed\njava.ext.dirs /usr/java/jdk1.6.0/jre/lib/ext:/usr/java/packages/lib/ext\njava.home /usr/java/jdk1.6.0/jre\njava.io.tmpdir /tmp\njava.library.path /usr/java/jdk1.6.0/jre/lib/i386/client:/usr/java/jdk1.6.0/jre/lib/i386:/usr/java/jdk1.6.0/jre/../lib/i386:/usr/java/packages/lib/i386:/lib:/usr/lib\njava.specification.name Java Platform API Specification\njava.specification.vendor Sun Microsystems Inc.\njava.specification.version 1.6\njava.vendor Sun Microsystems Inc.\njava.vendor.url http://java.sun.com/\njava.vendor.url.bug http://java.sun.com/cgi-bin/bugreport.cgi\njava.version *null*\njava.vm.info mixed mode, sharing\njava.vm.name Java HotSpot(TM) Client VM\njava.vm.specification.name Java Virtual Machine Specification\njava.vm.specification.vendor Sun Microsystems Inc.\njava.vm.specification.version 1.0\njava.vm.vendor Sun Microsystems Inc.\njava.vm.version 1.6.0-rc-b87\nline.separator \n\nos.arch i386\nos.name Linux\nos.version 2.4.18-openmosix4\npath.separator :\nsun.arch.data.model 32\nsun.boot.class.path /usr/java/jdk1.6.0/jre/lib/resources.jar:/usr/java/jdk1.6.0/jre/lib/rt.jar:/usr/java/jdk1.6.0/jre/lib/sunrsasign.jar:/usr/java/jdk1.6.0/jre/lib/jsse.jar:/usr/java/jdk1.6.0/jre/lib/jce.jar:/usr/java/jdk1.6.0/jre/lib/charsets.jar:/usr/java/jdk1.6.0/jre/classes\nsun.boot.library.path /usr/java/jdk1.6.0/jre/lib/i386\nsun.cpu.endian little\nsun.cpu.isalist \nsun.io.unicode.encoding UnicodeLittle\nsun.java.launcher SUN_STANDARD\nsun.jnu.encoding ISO-8859-1\nsun.management.compiler HotSpot Client Compiler\nsun.os.patch.level unknown\nuser.country US\nuser.dir /tmp\nuser.home /home/th125165\nuser.language en\nuser.name th125165\nuser.timezone \n Id 0x6c98e828 Class sun.nio.cs.HistoricallyNamedCharset SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cae7dc8 Class java.io.DataInputStream SuperClass java.io.FilterInputStream Instance size 32 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name lineBuffer type object\n  Field name readBuffer type object\n  Field name chararr type object\n  Field name bytearr type object\n Id 0x6c9ca470 Class sun.misc.OSEnvironment SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9c7940 Class java.lang.StringCoding$StringEncoder SuperClass java.lang.Object Instance size 24 Instance count 1 All Instances Size 24\n  Static Field name <classLoader> type object value 0\n  Field name requestedCharsetName type object\n  Field name ce type object\n  Field name cs type object\n  Instance Id 0x64625090 number 1 retained size 0\n   Instance Field name requestedCharsetName type object value 1684084200\n    Ref object java.lang.String#41\n   Instance Field name ce type object value 1684164776\n    Ref object sun.nio.cs.ISO_8859_1$Encoder#3\n   Instance Field name cs type object value 1684099224\n    Ref object sun.nio.cs.ISO_8859_1#1\n   References count 1\n   Field referent of instance 0x64625140\n   Path to nearest GC root\n    Null\n Id 0x6c992340 Class java.lang.StringCoding$StringDecoder SuperClass java.lang.Object Instance size 24 Instance count 1 All Instances Size 24\n  Static Field name <classLoader> type object value 0\n  Field name cd type object\n  Field name cs type object\n  Field name requestedCharsetName type object\n  Instance Id 0x6462a468 number 1 retained size 0\n   Instance Field name cd type object value 1684186240\n    Ref object sun.nio.cs.UTF_8$Decoder#1\n   Instance Field name cs type object value 1684181928\n    Ref object sun.nio.cs.UTF_8#1\n   Instance Field name requestedCharsetName type object value 0\n   References count 1\n   Field referent of instance 0x6462a4b8\n   Path to nearest GC root\n    Null\n Id 0x6c9a9410 Class java.nio.charset.CoderResult SuperClass java.lang.Object Instance size 16 Instance count 2 All Instances Size 32\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name unmappableCache type object value 1684099696\n   Ref object java.nio.charset.CoderResult$2#1\n  Static Field name malformedCache type object value 1684099680\n   Ref object java.nio.charset.CoderResult$1#1\n  Static Field name OVERFLOW type object value 1684099664\n   Ref object java.nio.charset.CoderResult#2\n  Static Field name UNDERFLOW type object value 1684099648\n   Ref object java.nio.charset.CoderResult#1\n  Static Field name names type object value 1684099616\n   Ref object java.lang.String[]#40\n  Static Field name CR_UNMAPPABLE type int value 3\n  Static Field name CR_MALFORMED type int value 2\n  Static Field name CR_ERROR_MIN type int value 2\n  Static Field name CR_OVERFLOW type int value 1\n  Static Field name CR_UNDERFLOW type int value 0\n  Static Field name <classLoader> type object value 0\n  Field name length type int\n  Field name type type int\n  Instance Id 0x64615240 number 1 retained size 16\n   Instance Field name length type int value 0\n   Instance Field name type type int value 0\n   References count 4\n   Field UNDERFLOW of Class java.nio.charset.CoderResult\n   Field error of instance 0x64616a58\n   Field error of instance 0x64616c30\n   Field error of instance 0x64625128\n   Path to nearest GC root\n    Next object java.lang.Class#6\n  Instance Id 0x64615250 number 2 retained size 16\n   Instance Field name length type int value 0\n   Instance Field name type type int value 1\n   References count 2\n   Field OVERFLOW of Class java.nio.charset.CoderResult\n   Field error of instance 0x6462a4a8\n   Path to nearest GC root\n    Next object java.lang.Class#6\n Id 0x6813b630 Class testapp.Main SuperClass java.lang.Object Instance size 8 Instance count 2 All Instances Size 16\n  Static Field name b type object value 1684213104\n   Ref object testapp.Main#2\n  Static Field name a type object value 1684213096\n   Ref object testapp.Main#1\n  Static Field name <classLoader> type object value 1684178464\n   Ref object sun.misc.Launcher$AppClassLoader#1\n  Instance Id 0x64630d68 number 1 retained size 8\n   References count 1\n   Field a of Class testapp.Main\n   Path to nearest GC root\n    Next object java.lang.Class#7\n    Next object java.lang.Object[]#307\n    Next object java.util.Vector#5\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64630d70 number 2 retained size 8\n   References count 1\n   Field b of Class testapp.Main\n   Path to nearest GC root\n    Next object java.lang.Class#7\n    Next object java.lang.Object[]#307\n    Next object java.util.Vector#5\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c9a6070 Class java.nio.ByteOrder SuperClass java.lang.Object Instance size 16 Instance count 2 All Instances Size 32\n  Static Field name LITTLE_ENDIAN type object value 1684099600\n   Ref object java.nio.ByteOrder#2\n  Static Field name BIG_ENDIAN type object value 1684099584\n   Ref object java.nio.ByteOrder#1\n  Static Field name <classLoader> type object value 0\n  Field name name type object\n  Instance Id 0x64615200 number 1 retained size 16\n   Instance Field name name type object value 0\n   References count 1\n   Field BIG_ENDIAN of Class java.nio.ByteOrder\n   Path to nearest GC root\n    Next object java.lang.Class#8\n  Instance Id 0x64615210 number 2 retained size 16\n   Instance Field name name type object value 0\n   References count 2\n   Field LITTLE_ENDIAN of Class java.nio.ByteOrder\n   Field byteOrder of Class java.nio.Bits\n   Path to nearest GC root\n    Next object java.lang.Class#8\n Id 0x6c99b7e8 Class java.nio.Bits SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name JNI_COPY_FROM_ARRAY_THRESHOLD type int value 6\n  Static Field name JNI_COPY_TO_ARRAY_THRESHOLD type int value 6\n  Static Field name memoryLimitSet type boolean value false\n  Static Field name reservedMemory type long value 0\n  Static Field name maxMemory type long value 67108864\n  Static Field name unalignedKnown type boolean value false\n  Static Field name unaligned type boolean value false\n  Static Field name pageSize type int value -1\n  Static Field name byteOrder type object value 1684099600\n   Ref object java.nio.ByteOrder#2\n  Static Field name unsafe type object value 1684098296\n   Ref object sun.misc.Unsafe#1\n  Static Field name <classLoader> type object value 0\n Id 0x6c997f08 Class java.nio.HeapByteBuffer SuperClass java.nio.ByteBuffer Instance size 48 Instance count 2 All Instances Size 96\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64616a70 number 1 retained size 8256\n   Instance Field name nativeByteOrder type boolean value false\n   Instance Field name bigEndian type boolean value true\n   Instance Field name isReadOnly type boolean value false\n   Instance Field name offset type int value 0\n   Instance Field name hb type object value 1684115152\n    Ref object byte[]#6\n   Instance Field name address type long value 0\n   Instance Field name capacity type int value 8192\n   Instance Field name limit type int value 8192\n   Instance Field name position type int value 0\n   Instance Field name mark type int value -1\n   References count 1\n   Field bb of instance 0x646169b0\n   Path to nearest GC root\n    Next object sun.nio.cs.StreamEncoder#1\n    Next object java.io.OutputStreamWriter#1\n    Next object java.io.PrintStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616c48 number 2 retained size 8256\n   Instance Field name nativeByteOrder type boolean value false\n   Instance Field name bigEndian type boolean value true\n   Instance Field name isReadOnly type boolean value false\n   Instance Field name offset type int value 0\n   Instance Field name hb type object value 1684139760\n    Ref object byte[]#7\n   Instance Field name address type long value 0\n   Instance Field name capacity type int value 8192\n   Instance Field name limit type int value 8192\n   Instance Field name position type int value 0\n   Instance Field name mark type int value -1\n   References count 1\n   Field bb of instance 0x64616ba8\n   Path to nearest GC root\n    Next object sun.nio.cs.StreamEncoder#2\n    Next object java.io.OutputStreamWriter#2\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n Id 0x68137c60 Class java.io.Console$1 SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x646256a0 number 1 retained size 8\n   References count 2\n   Field javaIOAccess of Class sun.misc.SharedSecrets\n   Field this$0 of instance 0x646256a8\n   Path to nearest GC root\n    Next object java.lang.Class#312\n Id 0x6cab40a0 Class java.util.regex.Pattern$6 SuperClass java.util.regex.Pattern$CharProperty Instance size 24 Instance count 1 All Instances Size 24\n  Static Field name <classLoader> type object value 0\n  Field name val$upper type int\n  Field name val$lower type int\n  Instance Id 0x6462ed70 number 1 retained size 24\n   Instance Field name val$upper type int value 57\n   Instance Field name val$lower type int value 48\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field atom of instance 0x6462ed88\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Curly#4\n    Next object java.util.regex.Pattern$GroupHead#9\n    Next object java.util.regex.Pattern$BranchConn#3\n    Next object java.util.regex.Pattern$Branch#3\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n Id 0x6cae0600 Class java.util.regex.Pattern$5 SuperClass java.util.regex.Pattern$BmpCharProperty Instance size 24 Instance count 3 All Instances Size 72\n  Static Field name <classLoader> type object value 0\n  Field name this$0 type object\n  Field name val$ch type int\n  Instance Id 0x6462d940 number 1 retained size 1920\n   Instance Field name this$0 type object value 1684199288\n    Ref object java.util.regex.Pattern#1\n   Instance Field name val$ch type int value 48\n   Instance Field name next type object value 1684199768\n    Ref object java.util.regex.Pattern$BitClass#2\n   References count 1\n   Field next of instance 0x6462d900\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462e940 number 2 retained size 24\n   Instance Field name this$0 type object value 1684199288\n    Ref object java.util.regex.Pattern#1\n   Instance Field name val$ch type int value 46\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field atom of instance 0x6462e958\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Ques#1\n    Next object java.util.regex.Pattern$GroupTail#4\n    Next object java.util.regex.Pattern$Curly#1\n    Next object java.util.regex.Pattern$GroupHead#4\n    Next object java.util.regex.Pattern$GroupHead#3\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462e9f0 number 3 retained size 136\n   Instance Field name this$0 type object value 1684199288\n    Ref object java.util.regex.Pattern#1\n   Instance Field name val$ch type int value 46\n   Instance Field name next type object value 1684204040\n    Ref object java.util.regex.Pattern$GroupHead#7\n   References count 1\n   Field next of instance 0x6462e9a8\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupTail#6\n    Next object java.util.regex.Pattern$Curly#2\n    Next object java.util.regex.Pattern$GroupHead#6\n    Next object java.util.regex.Pattern$GroupHead#5\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n Id 0x6cae12d0 Class java.util.regex.Pattern$8 SuperClass java.util.regex.Pattern$Node Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462d748 number 1 retained size 16\n   Instance Field name next type object value 0\n   References count 1\n   Field lookbehindEnd of Class java.util.regex.Pattern\n   Path to nearest GC root\n    Next object java.lang.Class#224\n Id 0x6cab20e8 Class java.util.regex.Pattern$Begin SuperClass java.util.regex.Pattern$Node Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cab3c88 Class java.util.regex.Pattern$BitClass SuperClass java.util.regex.Pattern$BmpCharProperty Instance size 16 Instance count 5 All Instances Size 80\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name <classLoader> type object value 0\n  Field name bits type object\n  Instance Id 0x6462d7e0 number 1 retained size 312\n   Instance Field name bits type object value 1684199408\n    Ref object boolean[]#1\n   Instance Field name next type object value 1684199368\n    Ref object java.util.regex.Pattern$GroupTail#1\n   References count 1\n   Field next of instance 0x6462d7b8\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupHead#1\n    Next object java.util.regex.Pattern$Node[]#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462d958 number 2 retained size 1896\n   Instance Field name bits type object value 1684199784\n    Ref object boolean[]#2\n   Instance Field name next type object value 1684200056\n    Ref object java.util.regex.Pattern$GroupHead#2\n   References count 1\n   Field next of instance 0x6462d940\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462eaa0 number 3 retained size 1088\n   Instance Field name bits type object value 1684204208\n    Ref object boolean[]#3\n   Instance Field name next type object value 1684204824\n    Ref object java.util.regex.Pattern$Branch#3\n   References count 1\n   Field next of instance 0x6462da88\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ebe8 number 4 retained size 312\n   Instance Field name bits type object value 1684204536\n    Ref object boolean[]#4\n   Instance Field name next type object value 1684204496\n    Ref object java.util.regex.Pattern$GroupTail#8\n   References count 1\n   Field next of instance 0x6462ebc0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupHead#8\n    Next object java.util.regex.Pattern$Node[]#3\n    Next object java.util.regex.Pattern$Branch#3\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462eda8 number 5 retained size 288\n   Instance Field name bits type object value 1684204984\n    Ref object boolean[]#5\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field atom of instance 0x6462eec8\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Ques#2\n    Next object java.util.regex.Pattern$GroupTail#9\n    Next object java.util.regex.Pattern$Curly#4\n    Next object java.util.regex.Pattern$GroupHead#9\n    Next object java.util.regex.Pattern$BranchConn#3\n    Next object java.util.regex.Pattern$Branch#3\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n Id 0x6cab36f0 Class java.util.regex.Pattern$BmpCharProperty SuperClass java.util.regex.Pattern$CharProperty Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cae17e8 Class java.util.regex.Pattern$Branch SuperClass java.util.regex.Pattern$Node Instance size 24 Instance count 3 All Instances Size 72\n  Static Field name <classLoader> type object value 0\n  Field name conn type object\n  Field name size type int\n  Field name atoms type object\n  Instance Id 0x6462d910 number 1 retained size 2312\n   Instance Field name conn type object value 1684199680\n    Ref object java.util.regex.Pattern$BranchConn#1\n   Instance Field name size type int value 2\n   Instance Field name atoms type object value 1684199720\n    Ref object java.util.regex.Pattern$Node[]#1\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 2\n   Field matchRoot of instance 0x6462d778\n   Field next of instance 0x6462eee0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ea70 number 2 retained size 1592\n   Instance Field name conn type object value 1684204128\n    Ref object java.util.regex.Pattern$BranchConn#2\n   Instance Field name size type int value 2\n   Instance Field name atoms type object value 1684204168\n    Ref object java.util.regex.Pattern$Node[]#2\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field next of instance 0x6462da78\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ed18 number 3 retained size 800\n   Instance Field name conn type object value 1684204808\n    Ref object java.util.regex.Pattern$BranchConn#3\n   Instance Field name size type int value 2\n   Instance Field name atoms type object value 1684204848\n    Ref object java.util.regex.Pattern$Node[]#3\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field next of instance 0x6462eaa0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n Id 0x6813ab30 Class java.util.regex.Pattern$BranchConn SuperClass java.util.regex.Pattern$Node Instance size 16 Instance count 3 All Instances Size 48\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462d900 number 1 retained size 1936\n   Instance Field name next type object value 1684199744\n    Ref object java.util.regex.Pattern$5#1\n   References count 2\n   Field conn of instance 0x6462d910\n   Field next of instance 0x6462d7c8\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ea60 number 2 retained size 1128\n   Instance Field name next type object value 1684200072\n    Ref object java.util.regex.Pattern$GroupTail#2\n   References count 3\n   Field conn of instance 0x6462ea70\n   Field next of instance 0x6462e980\n   Field next of instance 0x6462dab0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ed08 number 3 retained size 424\n   Instance Field name next type object value 1684204872\n    Ref object java.util.regex.Pattern$GroupHead#9\n   References count 2\n   Field conn of instance 0x6462ed18\n   Field next of instance 0x6462ebd0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Branch#3\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n Id 0x6caad070 Class java.util.regex.Pattern$CharProperty SuperClass java.util.regex.Pattern$Node Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6caab658 Class java.util.regex.Pattern$CharPropertyNames SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name map type object value 1684200176\n   Ref object java.util.HashMap#20\n  Static Field name <classLoader> type object value 0\n Id 0x6cab1760 Class java.util.regex.Pattern$Curly SuperClass java.util.regex.Pattern$Node Instance size 32 Instance count 4 All Instances Size 128\n  Static Field name <classLoader> type object value 0\n  Field name cmax type int\n  Field name cmin type int\n  Field name type type int\n  Field name atom type object\n  Instance Id 0x6462e920 number 1 retained size 144\n   Instance Field name cmax type int value 2147483647\n   Instance Field name cmin type int value 1\n   Instance Field name type type int value 0\n   Instance Field name atom type object value 1684203792\n    Ref object java.util.regex.Pattern$Ctype#1\n   Instance Field name next type object value 1684200152\n    Ref object java.util.regex.Pattern$GroupTail#4\n   References count 1\n   Field next of instance 0x6462dac8\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupHead#4\n    Next object java.util.regex.Pattern$GroupHead#3\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462e9d0 number 2 retained size 208\n   Instance Field name cmax type int value 2147483647\n   Instance Field name cmin type int value 0\n   Instance Field name type type int value 0\n   Instance Field name atom type object value 1684203968\n    Ref object java.util.regex.Pattern$Ctype#2\n   Instance Field name next type object value 1684203944\n    Ref object java.util.regex.Pattern$GroupTail#6\n   References count 1\n   Field next of instance 0x6462e998\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupHead#6\n    Next object java.util.regex.Pattern$GroupHead#5\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ea40 number 3 retained size 96\n   Instance Field name cmax type int value 2147483647\n   Instance Field name cmin type int value 1\n   Instance Field name type type int value 0\n   Instance Field name atom type object value 1684204080\n    Ref object java.util.regex.Pattern$Ctype#3\n   Instance Field name next type object value 1684204056\n    Ref object java.util.regex.Pattern$GroupTail#7\n   References count 1\n   Field next of instance 0x6462ea08\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupHead#7\n    Next object java.util.regex.Pattern$5#3\n    Next object java.util.regex.Pattern$GroupTail#6\n    Next object java.util.regex.Pattern$Curly#2\n    Next object java.util.regex.Pattern$GroupHead#6\n    Next object java.util.regex.Pattern$GroupHead#5\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ed88 number 4 retained size 392\n   Instance Field name cmax type int value 2147483647\n   Instance Field name cmin type int value 1\n   Instance Field name type type int value 0\n   Instance Field name atom type object value 1684204912\n    Ref object java.util.regex.Pattern$6#1\n   Instance Field name next type object value 1684204888\n    Ref object java.util.regex.Pattern$GroupTail#9\n   References count 1\n   Field next of instance 0x6462ed48\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupHead#9\n    Next object java.util.regex.Pattern$BranchConn#3\n    Next object java.util.regex.Pattern$Branch#3\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n Id 0x6cadf650 Class java.util.regex.Pattern$Ctype SuperClass java.util.regex.Pattern$BmpCharProperty Instance size 16 Instance count 3 All Instances Size 48\n  Static Field name <classLoader> type object value 0\n  Field name ctype type int\n  Instance Id 0x6462e910 number 1 retained size 16\n   Instance Field name ctype type int value 32768\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field atom of instance 0x6462e920\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Curly#1\n    Next object java.util.regex.Pattern$GroupHead#4\n    Next object java.util.regex.Pattern$GroupHead#3\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462e9c0 number 2 retained size 16\n   Instance Field name ctype type int value 32768\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field atom of instance 0x6462e9d0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Curly#2\n    Next object java.util.regex.Pattern$GroupHead#6\n    Next object java.util.regex.Pattern$GroupHead#5\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ea30 number 3 retained size 16\n   Instance Field name ctype type int value 32768\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field atom of instance 0x6462ea40\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Curly#3\n    Next object java.util.regex.Pattern$GroupHead#7\n    Next object java.util.regex.Pattern$5#3\n    Next object java.util.regex.Pattern$GroupTail#6\n    Next object java.util.regex.Pattern$Curly#2\n    Next object java.util.regex.Pattern$GroupHead#6\n    Next object java.util.regex.Pattern$GroupHead#5\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n Id 0x6cab25d8 Class java.util.regex.Pattern$First SuperClass java.util.regex.Pattern$Node Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name atom type object\n Id 0x6caaabe0 Class java.util.regex.Pattern$GroupHead SuperClass java.util.regex.Pattern$Node Instance size 16 Instance count 9 All Instances Size 144\n  Static Field name <classLoader> type object value 0\n  Field name localIndex type int\n  Instance Id 0x6462d7b8 number 1 retained size 328\n   Instance Field name localIndex type int value 0\n   Instance Field name next type object value 1684199392\n    Ref object java.util.regex.Pattern$BitClass#1\n   References count 1\n   Element 0 of array 0x6462d928\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Node[]#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462da78 number 2 retained size 1608\n   Instance Field name localIndex type int value 1\n   Instance Field name next type object value 1684204144\n    Ref object java.util.regex.Pattern$Branch#2\n   References count 1\n   Field next of instance 0x6462d958\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462daa0 number 3 retained size 176\n   Instance Field name localIndex type int value 2\n   Instance Field name next type object value 1684200136\n    Ref object java.util.regex.Pattern$GroupHead#4\n   References count 1\n   Element 0 of array 0x6462ea88\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462dac8 number 4 retained size 160\n   Instance Field name localIndex type int value 3\n   Instance Field name next type object value 1684203808\n    Ref object java.util.regex.Pattern$Curly#1\n   References count 1\n   Field next of instance 0x6462daa0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupHead#3\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462e970 number 5 retained size 240\n   Instance Field name localIndex type int value 4\n   Instance Field name next type object value 1684203928\n    Ref object java.util.regex.Pattern$GroupHead#6\n   References count 1\n   Element 1 of array 0x6462ea88\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462e998 number 6 retained size 224\n   Instance Field name localIndex type int value 5\n   Instance Field name next type object value 1684203984\n    Ref object java.util.regex.Pattern$Curly#2\n   References count 1\n   Field next of instance 0x6462e970\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupHead#5\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ea08 number 7 retained size 112\n   Instance Field name localIndex type int value 6\n   Instance Field name next type object value 1684204096\n    Ref object java.util.regex.Pattern$Curly#3\n   References count 1\n   Field next of instance 0x6462e9f0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$5#3\n    Next object java.util.regex.Pattern$GroupTail#6\n    Next object java.util.regex.Pattern$Curly#2\n    Next object java.util.regex.Pattern$GroupHead#6\n    Next object java.util.regex.Pattern$GroupHead#5\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ebc0 number 8 retained size 328\n   Instance Field name localIndex type int value 7\n   Instance Field name next type object value 1684204520\n    Ref object java.util.regex.Pattern$BitClass#4\n   References count 1\n   Element 0 of array 0x6462ed30\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Node[]#3\n    Next object java.util.regex.Pattern$Branch#3\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ed48 number 9 retained size 408\n   Instance Field name localIndex type int value 8\n   Instance Field name next type object value 1684204936\n    Ref object java.util.regex.Pattern$Curly#4\n   References count 1\n   Field next of instance 0x6462ed08\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$BranchConn#3\n    Next object java.util.regex.Pattern$Branch#3\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n Id 0x6813a6d0 Class java.util.regex.Pattern$GroupHead[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cadf270 Class java.util.regex.Pattern$GroupTail SuperClass java.util.regex.Pattern$Node Instance size 24 Instance count 9 All Instances Size 216\n  Static Field name <classLoader> type object value 0\n  Field name groupIndex type int\n  Field name localIndex type int\n  Instance Id 0x6462d7c8 number 1 retained size 24\n   Instance Field name groupIndex type int value 2\n   Instance Field name localIndex type int value 0\n   Instance Field name next type object value 1684199680\n    Ref object java.util.regex.Pattern$BranchConn#1\n   References count 1\n   Field next of instance 0x6462d7e0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$BitClass#1\n    Next object java.util.regex.Pattern$GroupHead#1\n    Next object java.util.regex.Pattern$Node[]#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462da88 number 2 retained size 1112\n   Instance Field name groupIndex type int value 4\n   Instance Field name localIndex type int value 1\n   Instance Field name next type object value 1684204192\n    Ref object java.util.regex.Pattern$BitClass#3\n   References count 1\n   Field next of instance 0x6462ea60\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462dab0 number 3 retained size 24\n   Instance Field name groupIndex type int value 6\n   Instance Field name localIndex type int value 2\n   Instance Field name next type object value 1684204128\n    Ref object java.util.regex.Pattern$BranchConn#2\n   References count 1\n   Field next of instance 0x6462e958\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Ques#1\n    Next object java.util.regex.Pattern$GroupTail#4\n    Next object java.util.regex.Pattern$Curly#1\n    Next object java.util.regex.Pattern$GroupHead#4\n    Next object java.util.regex.Pattern$GroupHead#3\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462dad8 number 4 retained size 96\n   Instance Field name groupIndex type int value 8\n   Instance Field name localIndex type int value 3\n   Instance Field name next type object value 1684203864\n    Ref object java.util.regex.Pattern$Ques#1\n   References count 1\n   Field next of instance 0x6462e920\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Curly#1\n    Next object java.util.regex.Pattern$GroupHead#4\n    Next object java.util.regex.Pattern$GroupHead#3\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462e980 number 5 retained size 24\n   Instance Field name groupIndex type int value 10\n   Instance Field name localIndex type int value 4\n   Instance Field name next type object value 1684204128\n    Ref object java.util.regex.Pattern$BranchConn#2\n   References count 1\n   Field next of instance 0x6462ea18\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupTail#7\n    Next object java.util.regex.Pattern$Curly#3\n    Next object java.util.regex.Pattern$GroupHead#7\n    Next object java.util.regex.Pattern$5#3\n    Next object java.util.regex.Pattern$GroupTail#6\n    Next object java.util.regex.Pattern$Curly#2\n    Next object java.util.regex.Pattern$GroupHead#6\n    Next object java.util.regex.Pattern$GroupHead#5\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462e9a8 number 6 retained size 160\n   Instance Field name groupIndex type int value 12\n   Instance Field name localIndex type int value 5\n   Instance Field name next type object value 1684204016\n    Ref object java.util.regex.Pattern$5#3\n   References count 1\n   Field next of instance 0x6462e9d0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Curly#2\n    Next object java.util.regex.Pattern$GroupHead#6\n    Next object java.util.regex.Pattern$GroupHead#5\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ea18 number 7 retained size 48\n   Instance Field name groupIndex type int value 14\n   Instance Field name localIndex type int value 6\n   Instance Field name next type object value 1684203904\n    Ref object java.util.regex.Pattern$GroupTail#5\n   References count 1\n   Field next of instance 0x6462ea40\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Curly#3\n    Next object java.util.regex.Pattern$GroupHead#7\n    Next object java.util.regex.Pattern$5#3\n    Next object java.util.regex.Pattern$GroupTail#6\n    Next object java.util.regex.Pattern$Curly#2\n    Next object java.util.regex.Pattern$GroupHead#6\n    Next object java.util.regex.Pattern$GroupHead#5\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ebd0 number 8 retained size 24\n   Instance Field name groupIndex type int value 16\n   Instance Field name localIndex type int value 7\n   Instance Field name next type object value 1684204808\n    Ref object java.util.regex.Pattern$BranchConn#3\n   References count 1\n   Field next of instance 0x6462ebe8\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$BitClass#4\n    Next object java.util.regex.Pattern$GroupHead#8\n    Next object java.util.regex.Pattern$Node[]#3\n    Next object java.util.regex.Pattern$Branch#3\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ed58 number 9 retained size 336\n   Instance Field name groupIndex type int value 18\n   Instance Field name localIndex type int value 8\n   Instance Field name next type object value 1684205256\n    Ref object java.util.regex.Pattern$Ques#2\n   References count 1\n   Field next of instance 0x6462ed88\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Curly#4\n    Next object java.util.regex.Pattern$GroupHead#9\n    Next object java.util.regex.Pattern$BranchConn#3\n    Next object java.util.regex.Pattern$Branch#3\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n Id 0x6caaa7b0 Class java.util.regex.Pattern$LastNode SuperClass java.util.regex.Pattern$Node Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462d768 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 2\n   Field lastAccept of Class java.util.regex.Pattern\n   Field next of instance 0x6462eec8\n   Path to nearest GC root\n    Next object java.lang.Class#224\n Id 0x6caaa3b8 Class java.util.regex.Pattern$Node SuperClass java.lang.Object Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Field name next type object\n  Instance Id 0x6462d758 number 1 retained size 16\n   Instance Field name next type object value 0\n   References count 27\n   Field accept of Class java.util.regex.Pattern\n   Field next of instance 0x6462eda8\n   Field next of instance 0x6462ed70\n   Field next of instance 0x6462ea30\n   Field next of instance 0x6462ea70\n   Field next of instance 0x6462ed18\n   Field next of instance 0x6462e910\n   Field next of instance 0x6462e940\n   Field next of instance 0x6462e9c0\n   Field next of instance 0x6462e868\n   Field next of instance 0x6462e8a0\n   Field next of instance 0x6462e8d8\n   Field next of instance 0x6462e7c0\n   Field next of instance 0x6462e7f8\n   Field next of instance 0x6462e830\n   Field next of instance 0x6462e718\n   Field next of instance 0x6462e750\n   Field next of instance 0x6462e788\n   Field next of instance 0x6462e670\n   Field next of instance 0x6462e6a8\n   Field next of instance 0x6462e6e0\n   Field next of instance 0x6462e5c8\n   Field next of instance 0x6462e600\n   Field next of instance 0x6462e638\n   Field next of instance 0x6462d768\n   Field next of instance 0x6462d910\n   Field next of instance 0x6462e590\n   Path to nearest GC root\n    Next object java.lang.Class#224\n Id 0x6813a530 Class java.util.regex.Pattern$Node[] SuperClass java.lang.Object Instance size -1 Instance count 3 All Instances Size 72\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462d928 number 1 retained size 352\n   References count 1\n   Field atoms of instance 0x6462d910\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ea88 number 2 retained size 440\n   References count 1\n   Field atoms of instance 0x6462ea70\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ed30 number 3 retained size 352\n   References count 1\n   Field atoms of instance 0x6462ed18\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$Branch#3\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n Id 0x6cadfa98 Class java.util.regex.Pattern$Ques SuperClass java.util.regex.Pattern$Node Instance size 24 Instance count 2 All Instances Size 48\n  Static Field name <classLoader> type object value 0\n  Field name type type int\n  Field name atom type object\n  Instance Id 0x6462e958 number 1 retained size 72\n   Instance Field name type type int value 0\n   Instance Field name atom type object value 1684203840\n    Ref object java.util.regex.Pattern$5#2\n   Instance Field name next type object value 1684200112\n    Ref object java.util.regex.Pattern$GroupTail#3\n   References count 1\n   Field next of instance 0x6462dad8\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupTail#4\n    Next object java.util.regex.Pattern$Curly#1\n    Next object java.util.regex.Pattern$GroupHead#4\n    Next object java.util.regex.Pattern$GroupHead#3\n    Next object java.util.regex.Pattern$Node[]#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462eec8 number 2 retained size 312\n   Instance Field name type type int value 0\n   Instance Field name atom type object value 1684204968\n    Ref object java.util.regex.Pattern$BitClass#5\n   Instance Field name next type object value 1684199272\n    Ref object java.util.regex.Pattern$LastNode#1\n   References count 1\n   Field next of instance 0x6462ed58\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$GroupTail#9\n    Next object java.util.regex.Pattern$Curly#4\n    Next object java.util.regex.Pattern$GroupHead#9\n    Next object java.util.regex.Pattern$BranchConn#3\n    Next object java.util.regex.Pattern$Branch#3\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n Id 0x6cab1ca8 Class java.util.regex.Pattern$Slice SuperClass java.util.regex.Pattern$Node Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name buffer type object\n Id 0x6cab2af8 Class java.util.regex.Pattern$Start SuperClass java.util.regex.Pattern$Node Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Field name minLength type int\n  Instance Id 0x6462eee0 number 1 retained size 16\n   Instance Field name minLength type int value 5\n   Instance Field name next type object value 1684199696\n    Ref object java.util.regex.Pattern$Branch#1\n   References count 1\n   Field root of instance 0x6462d778\n   Path to nearest GC root\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n Id 0x6cab2f28 Class java.util.regex.Pattern$TreeInfo SuperClass java.lang.Object Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name deterministic type boolean\n  Field name maxValid type boolean\n  Field name maxLength type int\n  Field name minLength type int\n Id 0x6c9a49a8 Class java.util.Collections$EmptyMap SuperClass java.util.AbstractMap Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name serialVersionUID type long value 6428348081105594320\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64614d90 number 1 retained size 16\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field EMPTY_MAP of Class java.util.Collections\n   Path to nearest GC root\n    Next object java.lang.Class#369\n Id 0x6c9a40d0 Class java.util.Collections$EmptyList SuperClass java.util.AbstractList Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name serialVersionUID type long value 8842843931221139166\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64614d80 number 1 retained size 16\n   Instance Field name modCount type int value 0\n   References count 1\n   Field EMPTY_LIST of Class java.util.Collections\n   Path to nearest GC root\n    Next object java.lang.Class#369\n Id 0x6c9a4ec8 Class java.util.Collections$ReverseComparator SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name serialVersionUID type long value 7207038068494060240\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64614da0 number 1 retained size 8\n   References count 1\n   Field REVERSE_ORDER of Class java.util.Collections\n   Path to nearest GC root\n    Next object java.lang.Class#369\n Id 0x6c9a3a10 Class java.util.Collections$EmptySet SuperClass java.util.AbstractSet Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name serialVersionUID type long value 1582296315990362920\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64614d78 number 1 retained size 8\n   References count 1\n   Field EMPTY_SET of Class java.util.Collections\n   Path to nearest GC root\n    Next object java.lang.Class#369\n Id 0x6c9a5ab0 Class java.util.Collections$SynchronizedMap SuperClass java.lang.Object Instance size 32 Instance count 1 All Instances Size 32\n  Static Field name serialVersionUID type long value 1978198479659022715\n  Static Field name <classLoader> type object value 0\n  Field name values type object\n  Field name entrySet type object\n  Field name keySet type object\n  Field name mutex type object\n  Field name m type object\n  Instance Id 0x64614da8 number 1 retained size 152\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name mutex type object value 1684098472\n    Ref object java.util.Collections$SynchronizedMap#1\n   Instance Field name m type object value 1684098304\n    Ref object java.util.HashMap#2\n   References count 2\n   Field fieldFilterMap of Class sun.reflect.Reflection\n   Field mutex of instance 0x64614da8\n   Path to nearest GC root\n    Next object java.lang.Class#189\n Id 0x6caaee90 Class java.util.regex.Pattern$CharPropertyNames$11 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e6a8 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e6b8\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#6\n    Next object java.util.HashMap$Entry#142\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caaeb10 Class java.util.regex.Pattern$CharPropertyNames$10 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e670 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e680\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#5\n    Next object java.util.HashMap$Entry#141\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caabf68 Class java.util.regex.Pattern$CharPropertyNames$1 SuperClass java.util.regex.Pattern$CharPropertyNames$CharPropertyFactory Instance size 16 Instance count 39 All Instances Size 624\n  Static Field name <classLoader> type object value 0\n  Field name val$typeMask type int\n  Instance Id 0x6462db18 number 1 retained size 16\n   Instance Field name val$typeMask type int value 1\n   References count 1\n   Field value of instance 0x6462db28\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#83\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462db40 number 2 retained size 16\n   Instance Field name val$typeMask type int value 2\n   References count 1\n   Field value of instance 0x6462db50\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#84\n    Next object java.util.HashMap$Entry#104\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462db68 number 3 retained size 16\n   Instance Field name val$typeMask type int value 4\n   References count 1\n   Field value of instance 0x6462db78\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#85\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462db90 number 4 retained size 16\n   Instance Field name val$typeMask type int value 8\n   References count 1\n   Field value of instance 0x6462dba0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#86\n    Next object java.util.HashMap$Entry#102\n    Next object java.util.HashMap$Entry#144\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dbb8 number 5 retained size 16\n   Instance Field name val$typeMask type int value 16\n   References count 1\n   Field value of instance 0x6462dbc8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#87\n    Next object java.util.HashMap$Entry#148\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dbe0 number 6 retained size 16\n   Instance Field name val$typeMask type int value 32\n   References count 1\n   Field value of instance 0x6462dbf0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#88\n    Next object java.util.HashMap$Entry#106\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dc08 number 7 retained size 16\n   Instance Field name val$typeMask type int value 64\n   References count 1\n   Field value of instance 0x6462dc18\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#89\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dc30 number 8 retained size 16\n   Instance Field name val$typeMask type int value 128\n   References count 1\n   Field value of instance 0x6462dc40\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#90\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dc58 number 9 retained size 16\n   Instance Field name val$typeMask type int value 256\n   References count 1\n   Field value of instance 0x6462dc68\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#91\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dc80 number 10 retained size 16\n   Instance Field name val$typeMask type int value 512\n   References count 1\n   Field value of instance 0x6462dc90\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#92\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dca8 number 11 retained size 16\n   Instance Field name val$typeMask type int value 1024\n   References count 1\n   Field value of instance 0x6462dcb8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#93\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dcd0 number 12 retained size 16\n   Instance Field name val$typeMask type int value 2048\n   References count 1\n   Field value of instance 0x6462dce0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#94\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dcf8 number 13 retained size 16\n   Instance Field name val$typeMask type int value 4096\n   References count 1\n   Field value of instance 0x6462dd08\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#95\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dd20 number 14 retained size 16\n   Instance Field name val$typeMask type int value 8192\n   References count 1\n   Field value of instance 0x6462dd30\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#96\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dd48 number 15 retained size 16\n   Instance Field name val$typeMask type int value 16384\n   References count 1\n   Field value of instance 0x6462dd58\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#97\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dd70 number 16 retained size 16\n   Instance Field name val$typeMask type int value 32768\n   References count 1\n   Field value of instance 0x6462dd80\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#98\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dd98 number 17 retained size 16\n   Instance Field name val$typeMask type int value 65536\n   References count 1\n   Field value of instance 0x6462dda8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#99\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462ddc0 number 18 retained size 16\n   Instance Field name val$typeMask type int value 262144\n   References count 1\n   Field value of instance 0x6462ddd0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#100\n    Next object java.util.HashMap$Entry#103\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dde8 number 19 retained size 16\n   Instance Field name val$typeMask type int value 524288\n   References count 1\n   Field value of instance 0x6462ddf8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#101\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462de10 number 20 retained size 16\n   Instance Field name val$typeMask type int value 1048576\n   References count 1\n   Field value of instance 0x6462de20\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#102\n    Next object java.util.HashMap$Entry#144\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462de38 number 21 retained size 16\n   Instance Field name val$typeMask type int value 2097152\n   References count 1\n   Field value of instance 0x6462de48\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#103\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462de60 number 22 retained size 16\n   Instance Field name val$typeMask type int value 4194304\n   References count 1\n   Field value of instance 0x6462de70\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#104\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462de88 number 23 retained size 16\n   Instance Field name val$typeMask type int value 8388608\n   References count 1\n   Field value of instance 0x6462de98\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#105\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462deb0 number 24 retained size 16\n   Instance Field name val$typeMask type int value 16777216\n   References count 1\n   Field value of instance 0x6462dec0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#106\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462ded8 number 25 retained size 16\n   Instance Field name val$typeMask type int value 33554432\n   References count 1\n   Field value of instance 0x6462dee8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#107\n    Next object java.util.HashMap$Entry#135\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462df00 number 26 retained size 16\n   Instance Field name val$typeMask type int value 67108864\n   References count 1\n   Field value of instance 0x6462df10\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#108\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462df28 number 27 retained size 16\n   Instance Field name val$typeMask type int value 134217728\n   References count 1\n   Field value of instance 0x6462df38\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#109\n    Next object java.util.HashMap$Entry#146\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462df50 number 28 retained size 16\n   Instance Field name val$typeMask type int value 268435456\n   References count 1\n   Field value of instance 0x6462df60\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#110\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462df78 number 29 retained size 16\n   Instance Field name val$typeMask type int value 536870912\n   References count 1\n   Field value of instance 0x6462df88\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#111\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dfa0 number 30 retained size 16\n   Instance Field name val$typeMask type int value 1073741824\n   References count 1\n   Field value of instance 0x6462dfb0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#112\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dfc8 number 31 retained size 16\n   Instance Field name val$typeMask type int value 62\n   References count 1\n   Field value of instance 0x6462dfd8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#113\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dff0 number 32 retained size 16\n   Instance Field name val$typeMask type int value 448\n   References count 1\n   Field value of instance 0x6462e000\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#114\n    Next object java.util.HashMap$Entry#107\n    Next object java.util.HashMap$Entry#135\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e018 number 33 retained size 16\n   Instance Field name val$typeMask type int value 3584\n   References count 1\n   Field value of instance 0x6462e028\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#115\n    Next object java.util.HashMap$Entry#133\n    Next object java.util.HashMap$Entry#147\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e040 number 34 retained size 16\n   Instance Field name val$typeMask type int value 28672\n   References count 1\n   Field value of instance 0x6462e050\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#116\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e068 number 35 retained size 16\n   Instance Field name val$typeMask type int value 884736\n   References count 1\n   Field value of instance 0x6462e078\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#117\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e090 number 36 retained size 16\n   Instance Field name val$typeMask type int value 1643118592\n   References count 1\n   Field value of instance 0x6462e0a0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#118\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e0b8 number 37 retained size 16\n   Instance Field name val$typeMask type int value 503316480\n   References count 1\n   Field value of instance 0x6462e0c8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#119\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e0e0 number 38 retained size 16\n   Instance Field name val$typeMask type int value 14\n   References count 1\n   Field value of instance 0x6462e0f0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#120\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e108 number 39 retained size 16\n   Instance Field name val$typeMask type int value 574\n   References count 1\n   Field value of instance 0x6462e118\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#121\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caaf590 Class java.util.regex.Pattern$CharPropertyNames$13 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e718 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e728\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#8\n    Next object java.util.HashMap$Entry#144\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caaf210 Class java.util.regex.Pattern$CharPropertyNames$12 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e6e0 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e6f0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#7\n    Next object java.util.HashMap$Entry#143\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caafc90 Class java.util.regex.Pattern$CharPropertyNames$15 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e788 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e798\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#10\n    Next object java.util.HashMap$Entry#146\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caaf910 Class java.util.regex.Pattern$CharPropertyNames$14 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e750 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e760\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#9\n    Next object java.util.HashMap$Entry#145\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6cab0390 Class java.util.regex.Pattern$CharPropertyNames$17 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e7f8 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e808\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#12\n    Next object java.util.HashMap$Entry#148\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6cab0010 Class java.util.regex.Pattern$CharPropertyNames$16 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e7c0 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e7d0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#11\n    Next object java.util.HashMap$Entry#147\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6cab0a90 Class java.util.regex.Pattern$CharPropertyNames$19 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e868 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e878\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#14\n    Next object java.util.HashMap$Entry#150\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6cab0710 Class java.util.regex.Pattern$CharPropertyNames$18 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e830 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e840\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#13\n    Next object java.util.HashMap$Entry#149\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caac310 Class java.util.regex.Pattern$CharPropertyNames$2 SuperClass java.util.regex.Pattern$CharPropertyNames$CharPropertyFactory Instance size 16 Instance count 6 All Instances Size 96\n  Static Field name <classLoader> type object value 0\n  Field name val$upper type int\n  Field name val$lower type int\n  Instance Id 0x6462e130 number 1 retained size 16\n   Instance Field name val$upper type int value 255\n   Instance Field name val$lower type int value 0\n   References count 1\n   Field value of instance 0x6462e140\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#122\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e178 number 2 retained size 16\n   Instance Field name val$upper type int value 127\n   Instance Field name val$lower type int value 0\n   References count 1\n   Field value of instance 0x6462e188\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#124\n    Next object java.util.HashMap$Entry#120\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e240 number 3 retained size 16\n   Instance Field name val$upper type int value 57\n   Instance Field name val$lower type int value 48\n   References count 1\n   Field value of instance 0x6462e250\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#129\n    Next object java.util.HashMap$Entry#92\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e290 number 4 retained size 16\n   Instance Field name val$upper type int value 122\n   Instance Field name val$lower type int value 97\n   References count 1\n   Field value of instance 0x6462e2a0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#131\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e4c8 number 5 retained size 16\n   Instance Field name val$upper type int value 126\n   Instance Field name val$lower type int value 32\n   References count 1\n   Field value of instance 0x6462e4d8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#132\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e540 number 6 retained size 16\n   Instance Field name val$upper type int value 90\n   Instance Field name val$lower type int value 65\n   References count 1\n   Field value of instance 0x6462e550\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#135\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6cab1190 Class java.util.regex.Pattern$CharPropertyNames$21 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e8d8 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e8e8\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#16\n    Next object java.util.HashMap$Entry#152\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6cab0e10 Class java.util.regex.Pattern$CharPropertyNames$20 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e8a0 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e8b0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#15\n    Next object java.util.HashMap$Entry#151\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caadd00 Class java.util.regex.Pattern$CharPropertyNames$4 SuperClass java.util.regex.Pattern$CharPropertyNames$CharPropertyFactory Instance size 16 Instance count 16 All Instances Size 256\n  Static Field name <classLoader> type object value 0\n  Field name val$p type object\n  Instance Id 0x6462e5a0 number 1 retained size 32\n   Instance Field name val$p type object value 1684202896\n    Ref object java.util.regex.Pattern$CharPropertyNames$6#1\n   References count 1\n   Field value of instance 0x6462e5b0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#137\n    Next object java.util.HashMap$Entry#151\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e5d8 number 2 retained size 32\n   Instance Field name val$p type object value 1684202952\n    Ref object java.util.regex.Pattern$CharPropertyNames$7#1\n   References count 1\n   Field value of instance 0x6462e5e8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#138\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e610 number 3 retained size 32\n   Instance Field name val$p type object value 1684203008\n    Ref object java.util.regex.Pattern$CharPropertyNames$8#1\n   References count 1\n   Field value of instance 0x6462e620\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#139\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e648 number 4 retained size 32\n   Instance Field name val$p type object value 1684203064\n    Ref object java.util.regex.Pattern$CharPropertyNames$9#1\n   References count 1\n   Field value of instance 0x6462e658\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#140\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e680 number 5 retained size 32\n   Instance Field name val$p type object value 1684203120\n    Ref object java.util.regex.Pattern$CharPropertyNames$10#1\n   References count 1\n   Field value of instance 0x6462e690\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#141\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e6b8 number 6 retained size 32\n   Instance Field name val$p type object value 1684203176\n    Ref object java.util.regex.Pattern$CharPropertyNames$11#1\n   References count 1\n   Field value of instance 0x6462e6c8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#142\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e6f0 number 7 retained size 32\n   Instance Field name val$p type object value 1684203232\n    Ref object java.util.regex.Pattern$CharPropertyNames$12#1\n   References count 1\n   Field value of instance 0x6462e700\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#143\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e728 number 8 retained size 32\n   Instance Field name val$p type object value 1684203288\n    Ref object java.util.regex.Pattern$CharPropertyNames$13#1\n   References count 1\n   Field value of instance 0x6462e738\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#144\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e760 number 9 retained size 32\n   Instance Field name val$p type object value 1684203344\n    Ref object java.util.regex.Pattern$CharPropertyNames$14#1\n   References count 1\n   Field value of instance 0x6462e770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#145\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e798 number 10 retained size 32\n   Instance Field name val$p type object value 1684203400\n    Ref object java.util.regex.Pattern$CharPropertyNames$15#1\n   References count 1\n   Field value of instance 0x6462e7a8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#146\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e7d0 number 11 retained size 32\n   Instance Field name val$p type object value 1684203456\n    Ref object java.util.regex.Pattern$CharPropertyNames$16#1\n   References count 1\n   Field value of instance 0x6462e7e0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#147\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e808 number 12 retained size 32\n   Instance Field name val$p type object value 1684203512\n    Ref object java.util.regex.Pattern$CharPropertyNames$17#1\n   References count 1\n   Field value of instance 0x6462e818\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#148\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e840 number 13 retained size 32\n   Instance Field name val$p type object value 1684203568\n    Ref object java.util.regex.Pattern$CharPropertyNames$18#1\n   References count 1\n   Field value of instance 0x6462e850\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#149\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e878 number 14 retained size 32\n   Instance Field name val$p type object value 1684203624\n    Ref object java.util.regex.Pattern$CharPropertyNames$19#1\n   References count 1\n   Field value of instance 0x6462e888\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#150\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e8b0 number 15 retained size 32\n   Instance Field name val$p type object value 1684203680\n    Ref object java.util.regex.Pattern$CharPropertyNames$20#1\n   References count 1\n   Field value of instance 0x6462e8c0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#151\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e8e8 number 16 retained size 32\n   Instance Field name val$p type object value 1684203736\n    Ref object java.util.regex.Pattern$CharPropertyNames$21#1\n   References count 1\n   Field value of instance 0x6462e8f8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#152\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caaca30 Class java.util.regex.Pattern$CharPropertyNames$3 SuperClass java.util.regex.Pattern$CharPropertyNames$CharPropertyFactory Instance size 16 Instance count 8 All Instances Size 128\n  Static Field name <classLoader> type object value 0\n  Field name val$ctype type int\n  Instance Id 0x6462e1a0 number 1 retained size 16\n   Instance Field name val$ctype type int value 1792\n   References count 1\n   Field value of instance 0x6462e1b0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#125\n    Next object java.util.HashMap$Entry#124\n    Next object java.util.HashMap$Entry#120\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e1c8 number 2 retained size 16\n   Instance Field name val$ctype type int value 768\n   References count 1\n   Field value of instance 0x6462e1d8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#126\n    Next object java.util.HashMap$Entry#140\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e1f0 number 3 retained size 16\n   Instance Field name val$ctype type int value 16384\n   References count 1\n   Field value of instance 0x6462e200\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#127\n    Next object java.util.HashMap$Entry#149\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e218 number 4 retained size 16\n   Instance Field name val$ctype type int value 8192\n   References count 1\n   Field value of instance 0x6462e228\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#128\n    Next object java.util.HashMap$Entry#98\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e268 number 5 retained size 16\n   Instance Field name val$ctype type int value 5888\n   References count 1\n   Field value of instance 0x6462e278\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#130\n    Next object java.util.HashMap$Entry#152\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e4f0 number 6 retained size 16\n   Instance Field name val$ctype type int value 4096\n   References count 1\n   Field value of instance 0x6462e500\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#133\n    Next object java.util.HashMap$Entry#147\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e518 number 7 retained size 16\n   Instance Field name val$ctype type int value 2048\n   References count 1\n   Field value of instance 0x6462e528\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#134\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e568 number 8 retained size 16\n   Instance Field name val$ctype type int value 32768\n   References count 1\n   Field value of instance 0x6462e578\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#136\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caae090 Class java.util.regex.Pattern$CharPropertyNames$7 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e5c8 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e5d8\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#2\n    Next object java.util.HashMap$Entry#138\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caad960 Class java.util.regex.Pattern$CharPropertyNames$6 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e590 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e5a0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#1\n    Next object java.util.HashMap$Entry#137\n    Next object java.util.HashMap$Entry#151\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caac6a0 Class java.util.regex.Pattern$CharPropertyNames$5 SuperClass java.util.regex.Pattern$CharPropertyNames$CharPropertyFactory Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e158 number 1 retained size 8\n   References count 1\n   Field value of instance 0x6462e160\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#123\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caae790 Class java.util.regex.Pattern$CharPropertyNames$9 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e638 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e648\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#4\n    Next object java.util.HashMap$Entry#140\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caae410 Class java.util.regex.Pattern$CharPropertyNames$8 SuperClass java.util.regex.Pattern$CharPropertyNames$CloneableProperty Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462e600 number 1 retained size 16\n   Instance Field name next type object value 1684199256\n    Ref object java.util.regex.Pattern$Node#1\n   References count 1\n   Field val$p of instance 0x6462e610\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$CharPropertyNames$4#3\n    Next object java.util.HashMap$Entry#139\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n Id 0x6caad5b0 Class java.util.regex.Pattern$CharPropertyNames$CloneableProperty SuperClass java.util.regex.Pattern$CharProperty Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6caabbd8 Class java.util.regex.Pattern$CharPropertyNames$CharPropertyFactory SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9a3370 Class java.util.AbstractSet SuperClass java.util.AbstractCollection Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9a6350 Class java.lang.Readable SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9a88b0 Class java.nio.HeapCharBuffer SuperClass java.nio.CharBuffer Instance size 48 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9a9ea0 Class java.nio.charset.CoderResult$1 SuperClass java.nio.charset.CoderResult$Cache Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64615260 number 1 retained size 16\n   Instance Field name cache type object value 0\n   References count 1\n   Field malformedCache of Class java.nio.charset.CoderResult\n   Path to nearest GC root\n    Next object java.lang.Class#6\n Id 0x6c9aa1f8 Class java.nio.charset.CoderResult$2 SuperClass java.nio.charset.CoderResult$Cache Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64615270 number 1 retained size 16\n   Instance Field name cache type object value 0\n   References count 1\n   Field unmappableCache of Class java.nio.charset.CoderResult\n   Path to nearest GC root\n    Next object java.lang.Class#6\n Id 0x6c9a9ab0 Class java.nio.charset.CoderResult$Cache SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name cache type object\n Id 0x6c9abc80 Class java.io.InputStream SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name skipBuffer type object value 0\n  Static Field name SKIP_BUFFER_SIZE type int value 2048\n  Static Field name <classLoader> type object value 0\n Id 0x6c9ab588 Class java.io.Closeable SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9ad0a0 Class java.io.Flushable SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9ae920 Class java.io.FilterInputStream SuperClass java.io.InputStream Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name in type object\n Id 0x6c9afb00 Class java.util.concurrent.atomic.AtomicReferenceFieldUpdater SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9b0458 Class java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl SuperClass java.util.concurrent.atomic.AtomicReferenceFieldUpdater Instance size 32 Instance count 1 All Instances Size 32\n  Static Field name unsafe type object value 1684098296\n   Ref object sun.misc.Unsafe#1\n  Static Field name <classLoader> type object value 0\n  Field name cclass type object\n  Field name vclass type object\n  Field name tclass type object\n  Field name offset type long\n  Instance Id 0x64616578 number 1 retained size 32\n   Instance Field name cclass type object value 0\n   Instance Field name vclass type object value 0\n   Instance Field name tclass type object value 0\n   Instance Field name offset type long value 12\n   References count 1\n   Field bufUpdater of Class java.io.BufferedInputStream\n   Path to nearest GC root\n    Next object java.lang.Class#300\n Id 0x68134bc0 Class sun.reflect.misc.ReflectUtil SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9b2728 Class java.lang.reflect.ReflectAccess SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64614f38 number 1 retained size 8\n   References count 1\n   Field langReflectAccess of Class sun.reflect.ReflectionFactory\n   Path to nearest GC root\n    Next object java.lang.Class#258\n Id 0x6c9b2d28 Class java.io.FilterOutputStream SuperClass java.io.OutputStream Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name out type object\n Id 0x6c9b5a78 Class java.io.Writer SuperClass java.lang.Object Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name lock type object\n  Field name writeBufferSize type int\n  Field name writeBuffer type object\n Id 0x6c9b74e0 Class sun.nio.cs.StreamEncoder SuperClass java.io.Writer Instance size 48 Instance count 2 All Instances Size 96\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name DEFAULT_BYTE_BUFFER_SIZE type int value 8192\n  Static Field name <classLoader> type object value 0\n  Field name lcb type object\n  Field name leftoverChar type char\n  Field name haveLeftoverChar type boolean\n  Field name ch type object\n  Field name out type object\n  Field name bb type object\n  Field name encoder type object\n  Field name cs type object\n  Field name isOpen type boolean\n  Instance Id 0x646169b0 number 1 retained size 8416\n   Instance Field name lcb type object value 0\n   Instance Field name leftoverChar type char value \u0000\n   Instance Field name haveLeftoverChar type boolean value false\n   Instance Field name ch type object value 0\n   Instance Field name out type object value 1684105424\n    Ref object java.io.PrintStream#1\n   Instance Field name bb type object value 1684105840\n    Ref object java.nio.HeapByteBuffer#1\n   Instance Field name encoder type object value 1684105728\n    Ref object sun.nio.cs.ISO_8859_1$Encoder#1\n   Instance Field name cs type object value 1684099224\n    Ref object sun.nio.cs.ISO_8859_1#1\n   Instance Field name isOpen type boolean value true\n   Instance Field name lock type object value 1684105624\n    Ref object java.io.OutputStreamWriter#1\n   Instance Field name writeBufferSize type int value 1024\n   Instance Field name writeBuffer type object value 0\n   References count 1\n   Field se of instance 0x64616998\n   Path to nearest GC root\n    Next object java.io.OutputStreamWriter#1\n    Next object java.io.PrintStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616ba8 number 2 retained size 8416\n   Instance Field name lcb type object value 0\n   Instance Field name leftoverChar type char value \u0000\n   Instance Field name haveLeftoverChar type boolean value false\n   Instance Field name ch type object value 0\n   Instance Field name out type object value 1684105928\n    Ref object java.io.PrintStream#2\n   Instance Field name bb type object value 1684106312\n    Ref object java.nio.HeapByteBuffer#2\n   Instance Field name encoder type object value 1684106200\n    Ref object sun.nio.cs.ISO_8859_1$Encoder#2\n   Instance Field name cs type object value 1684099224\n    Ref object sun.nio.cs.ISO_8859_1#1\n   Instance Field name isOpen type boolean value true\n   Instance Field name lock type object value 1684106128\n    Ref object java.io.OutputStreamWriter#2\n   Instance Field name writeBufferSize type int value 1024\n   Instance Field name writeBuffer type object value 0\n   References count 1\n   Field se of instance 0x64616b90\n   Path to nearest GC root\n    Next object java.io.OutputStreamWriter#2\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n Id 0x6c9bacc8 Class sun.nio.cs.Surrogate SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name $assertionsDisabled type boolean value false\n  Static Field name UCS4_MAX type int value 1114111\n  Static Field name UCS4_MIN type int value 65536\n  Static Field name MAX type char value ?\n  Static Field name MIN type char value ?\n  Static Field name MAX_LOW type char value ?\n  Static Field name MIN_LOW type char value ?\n  Static Field name MAX_HIGH type char value ?\n  Static Field name MIN_HIGH type char value ?\n  Static Field name <classLoader> type object value 0\n Id 0x6c9ba550 Class sun.nio.cs.Surrogate$Parser SuperClass java.lang.Object Instance size 24 Instance count 3 All Instances Size 72\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name <classLoader> type object value 0\n  Field name isPair type boolean\n  Field name error type object\n  Field name character type int\n  Instance Id 0x64616a58 number 1 retained size 24\n   Instance Field name isPair type boolean value false\n   Instance Field name error type object value 1684099648\n    Ref object java.nio.charset.CoderResult#1\n   Instance Field name character type int value 0\n   References count 1\n   Field sgp of instance 0x64616a00\n   Path to nearest GC root\n    Next object sun.nio.cs.ISO_8859_1$Encoder#1\n    Next object sun.nio.cs.StreamEncoder#1\n    Next object java.io.OutputStreamWriter#1\n    Next object java.io.PrintStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616c30 number 2 retained size 24\n   Instance Field name isPair type boolean value false\n   Instance Field name error type object value 1684099648\n    Ref object java.nio.charset.CoderResult#1\n   Instance Field name character type int value 0\n   References count 1\n   Field sgp of instance 0x64616bd8\n   Path to nearest GC root\n    Next object sun.nio.cs.ISO_8859_1$Encoder#2\n    Next object sun.nio.cs.StreamEncoder#2\n    Next object java.io.OutputStreamWriter#2\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n  Instance Id 0x64625128 number 3 retained size 0\n   Instance Field name isPair type boolean value false\n   Instance Field name error type object value 1684099648\n    Ref object java.nio.charset.CoderResult#1\n   Instance Field name character type int value 0\n   References count 1\n   Field sgp of instance 0x646250a8\n   Path to nearest GC root\n    Null\n Id 0x6cbae2e0 Class sun.nio.cs.Surrogate$Generator SuperClass java.lang.Object Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name <classLoader> type object value 0\n  Field name error type object\n  Instance Id 0x6462a4a8 number 1 retained size 0\n   Instance Field name error type object value 1684099664\n    Ref object java.nio.charset.CoderResult#2\n   References count 1\n   Field sgg of instance 0x6462a480\n   Path to nearest GC root\n    Null\n Id 0x6c9d1610 Class java.util.StringTokenizer SuperClass java.lang.Object Instance size 40 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name delimiterCodePoints type object\n  Field name hasSurrogates type boolean\n  Field name maxDelimCodePoint type int\n  Field name delimsChanged type boolean\n  Field name retDelims type boolean\n  Field name delimiters type object\n  Field name str type object\n  Field name maxPosition type int\n  Field name newPosition type int\n  Field name currentPosition type int\n Id 0x6cc345a8 Class java.util.jar.JarEntry SuperClass java.util.zip.ZipEntry Instance size 72 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name signers type object\n  Field name certs type object\n  Field name attr type object\n Id 0x6c93ded0 Class java.lang.System SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name props type object value 1684081520\n   Ref object java.util.Properties#1\n  Static Field name cons type object value 0\n  Static Field name security type object value 0\n  Static Field name err type object value 1684105928\n   Ref object java.io.PrintStream#2\n  Static Field name out type object value 1684105424\n   Ref object java.io.PrintStream#1\n  Static Field name in type object value 1684105392\n   Ref object java.io.BufferedInputStream#1\n  Static Field name <classLoader> type object value 0\n Id 0x6c939b40 Class java.lang.Class SuperClass java.lang.Object Instance size 88 Instance count 9 All Instances Size 792\n  Static Field name EMPTY_ANNOTATIONS_ARRAY type object value 1684080432\n   Ref object java.lang.annotation.Annotation[]#1\n  Static Field name initted type boolean value true\n  Static Field name reflectionFactory type object value 1684080984\n   Ref object sun.reflect.ReflectionFactory#1\n  Static Field name serialPersistentFields type object value 1684080416\n   Ref object java.io.ObjectStreamField[]#2\n  Static Field name serialVersionUID type long value 3206093459760846163\n  Static Field name useCaches type boolean value true\n  Static Field name allPermDomain type object value 0\n  Static Field name SYNTHETIC type int value 4096\n  Static Field name ENUM type int value 16384\n  Static Field name ANNOTATION type int value 8192\n  Static Field name <classLoader> type object value 0\n  Field name annotationType type object\n  Field name declaredAnnotations type object\n  Field name annotations type object\n  Field name enumConstantDirectory type object\n  Field name enumConstants type object\n  Field name genericInfo type object\n  Field name lastRedefinedCount type int\n  Field name classRedefinedCount type int\n  Field name declaredPublicMethods type object\n  Field name declaredPublicFields type object\n  Field name publicConstructors type object\n  Field name declaredConstructors type object\n  Field name publicMethods type object\n  Field name declaredMethods type object\n  Field name publicFields type object\n  Field name declaredFields type object\n  Field name name type object\n  Field name newInstanceCallerCache type object\n  Field name cachedConstructor type object\n  Instance Id 0x68130010 number 1 retained size 88\n   Instance Field name annotationType type object value 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name enumConstantDirectory type object value 0\n   Instance Field name enumConstants type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name lastRedefinedCount type int value 0\n   Instance Field name classRedefinedCount type int value 0\n   Instance Field name declaredPublicMethods type object value 0\n   Instance Field name declaredPublicFields type object value 0\n   Instance Field name publicConstructors type object value 0\n   Instance Field name declaredConstructors type object value 0\n   Instance Field name publicMethods type object value 0\n   Instance Field name declaredMethods type object value 0\n   Instance Field name publicFields type object value 0\n   Instance Field name declaredFields type object value 0\n   Instance Field name name type object value 0\n   Instance Field name newInstanceCallerCache type object value 0\n   Instance Field name cachedConstructor type object value 0\n   References count 13\n   Field TYPE of Class java.lang.Integer\n   Field type of instance 0x64626968\n   Field type of instance 0x64626a40\n   Field type of instance 0x64629a98\n   Field type of instance 0x64626688\n   Field type of instance 0x646268d8\n   Field type of instance 0x64626920\n   Field type of instance 0x646167b8\n   Field type of instance 0x64616800\n   Field type of instance 0x64616848\n   Field type of instance 0x64614ed0\n   Field type of instance 0x646165c0\n   Field type of instance 0x64616770\n   Path to nearest GC root\n    Next object java.lang.Class#107\n  Instance Id 0x68130070 number 2 retained size 88\n   Instance Field name annotationType type object value 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name enumConstantDirectory type object value 0\n   Instance Field name enumConstants type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name lastRedefinedCount type int value 0\n   Instance Field name classRedefinedCount type int value 0\n   Instance Field name declaredPublicMethods type object value 0\n   Instance Field name declaredPublicFields type object value 0\n   Instance Field name publicConstructors type object value 0\n   Instance Field name declaredConstructors type object value 0\n   Instance Field name publicMethods type object value 0\n   Instance Field name declaredMethods type object value 0\n   Instance Field name publicFields type object value 0\n   Instance Field name declaredFields type object value 0\n   Instance Field name name type object value 0\n   Instance Field name newInstanceCallerCache type object value 0\n   Instance Field name cachedConstructor type object value 0\n   References count 1\n   Field TYPE of Class java.lang.Float\n   Path to nearest GC root\n    Next object java.lang.Class#103\n  Instance Id 0x681300d0 number 3 retained size 88\n   Instance Field name annotationType type object value 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name enumConstantDirectory type object value 0\n   Instance Field name enumConstants type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name lastRedefinedCount type int value 0\n   Instance Field name classRedefinedCount type int value 0\n   Instance Field name declaredPublicMethods type object value 0\n   Instance Field name declaredPublicFields type object value 0\n   Instance Field name publicConstructors type object value 0\n   Instance Field name declaredConstructors type object value 0\n   Instance Field name publicMethods type object value 0\n   Instance Field name declaredMethods type object value 0\n   Instance Field name publicFields type object value 0\n   Instance Field name declaredFields type object value 0\n   Instance Field name name type object value 0\n   Instance Field name newInstanceCallerCache type object value 0\n   Instance Field name cachedConstructor type object value 0\n   References count 1\n   Field TYPE of Class java.lang.Double\n   Path to nearest GC root\n    Next object java.lang.Class#102\n  Instance Id 0x68130130 number 4 retained size 88\n   Instance Field name annotationType type object value 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name enumConstantDirectory type object value 0\n   Instance Field name enumConstants type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name lastRedefinedCount type int value 0\n   Instance Field name classRedefinedCount type int value 0\n   Instance Field name declaredPublicMethods type object value 0\n   Instance Field name declaredPublicFields type object value 0\n   Instance Field name publicConstructors type object value 0\n   Instance Field name declaredConstructors type object value 0\n   Instance Field name publicMethods type object value 0\n   Instance Field name declaredMethods type object value 0\n   Instance Field name publicFields type object value 0\n   Instance Field name declaredFields type object value 0\n   Instance Field name name type object value 0\n   Instance Field name newInstanceCallerCache type object value 0\n   Instance Field name cachedConstructor type object value 0\n   References count 1\n   Field TYPE of Class java.lang.Byte\n   Path to nearest GC root\n    Next object java.lang.Class#109\n  Instance Id 0x68130190 number 5 retained size 88\n   Instance Field name annotationType type object value 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name enumConstantDirectory type object value 0\n   Instance Field name enumConstants type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name lastRedefinedCount type int value 0\n   Instance Field name classRedefinedCount type int value 0\n   Instance Field name declaredPublicMethods type object value 0\n   Instance Field name declaredPublicFields type object value 0\n   Instance Field name publicConstructors type object value 0\n   Instance Field name declaredConstructors type object value 0\n   Instance Field name publicMethods type object value 0\n   Instance Field name declaredMethods type object value 0\n   Instance Field name publicFields type object value 0\n   Instance Field name declaredFields type object value 0\n   Instance Field name name type object value 0\n   Instance Field name newInstanceCallerCache type object value 0\n   Instance Field name cachedConstructor type object value 0\n   References count 3\n   Field TYPE of Class java.lang.Boolean\n   Field type of instance 0x64630b58\n   Field type of instance 0x64629ab8\n   Path to nearest GC root\n    Next object java.lang.Class#105\n  Instance Id 0x681301f0 number 6 retained size 88\n   Instance Field name annotationType type object value 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name enumConstantDirectory type object value 0\n   Instance Field name enumConstants type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name lastRedefinedCount type int value 0\n   Instance Field name classRedefinedCount type int value 0\n   Instance Field name declaredPublicMethods type object value 0\n   Instance Field name declaredPublicFields type object value 0\n   Instance Field name publicConstructors type object value 0\n   Instance Field name declaredConstructors type object value 0\n   Instance Field name publicMethods type object value 0\n   Instance Field name declaredMethods type object value 0\n   Instance Field name publicFields type object value 0\n   Instance Field name declaredFields type object value 0\n   Instance Field name name type object value 0\n   Instance Field name newInstanceCallerCache type object value 0\n   Instance Field name cachedConstructor type object value 0\n   References count 1\n   Field TYPE of Class java.lang.Character\n   Path to nearest GC root\n    Next object java.lang.Class#104\n  Instance Id 0x68130250 number 7 retained size 88\n   Instance Field name annotationType type object value 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name enumConstantDirectory type object value 0\n   Instance Field name enumConstants type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name lastRedefinedCount type int value 0\n   Instance Field name classRedefinedCount type int value 0\n   Instance Field name declaredPublicMethods type object value 0\n   Instance Field name declaredPublicFields type object value 0\n   Instance Field name publicConstructors type object value 0\n   Instance Field name declaredConstructors type object value 0\n   Instance Field name publicMethods type object value 0\n   Instance Field name declaredMethods type object value 0\n   Instance Field name publicFields type object value 0\n   Instance Field name declaredFields type object value 0\n   Instance Field name name type object value 0\n   Instance Field name newInstanceCallerCache type object value 0\n   Instance Field name cachedConstructor type object value 0\n   References count 9\n   Field TYPE of Class java.lang.Long\n   Field type of instance 0x64626838\n   Field type of instance 0x646267f0\n   Field type of instance 0x646266d0\n   Field type of instance 0x64626760\n   Field type of instance 0x646267a8\n   Field type of instance 0x64614df8\n   Field type of instance 0x64614e88\n   Field type of instance 0x646265b0\n   Path to nearest GC root\n    Next object java.lang.Class#106\n  Instance Id 0x681302b0 number 8 retained size 88\n   Instance Field name annotationType type object value 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name enumConstantDirectory type object value 0\n   Instance Field name enumConstants type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name lastRedefinedCount type int value 0\n   Instance Field name classRedefinedCount type int value 0\n   Instance Field name declaredPublicMethods type object value 0\n   Instance Field name declaredPublicFields type object value 0\n   Instance Field name publicConstructors type object value 0\n   Instance Field name declaredConstructors type object value 0\n   Instance Field name publicMethods type object value 0\n   Instance Field name declaredMethods type object value 0\n   Instance Field name publicFields type object value 0\n   Instance Field name declaredFields type object value 0\n   Instance Field name name type object value 0\n   Instance Field name newInstanceCallerCache type object value 0\n   Instance Field name cachedConstructor type object value 0\n   References count 1\n   Field TYPE of Class java.lang.Short\n   Path to nearest GC root\n    Next object java.lang.Class#108\n  Instance Id 0x68130310 number 9 retained size 0\n   Instance Field name annotationType type object value 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name enumConstantDirectory type object value 0\n   Instance Field name enumConstants type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name lastRedefinedCount type int value 0\n   Instance Field name classRedefinedCount type int value 0\n   Instance Field name declaredPublicMethods type object value 0\n   Instance Field name declaredPublicFields type object value 0\n   Instance Field name publicConstructors type object value 0\n   Instance Field name declaredConstructors type object value 0\n   Instance Field name publicMethods type object value 0\n   Instance Field name declaredMethods type object value 0\n   Instance Field name publicFields type object value 0\n   Instance Field name declaredFields type object value 0\n   Instance Field name name type object value 0\n   Instance Field name newInstanceCallerCache type object value 0\n   Instance Field name cachedConstructor type object value 0\n   References count 1\n   Field returnType of instance 0x64630d08\n   Path to nearest GC root\n    Null\n Id 0x6c96bd98 Class java.lang.Class[] SuperClass java.lang.Object Instance size -1 Instance count 8 All Instances Size 136\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64614fb0 number 1 retained size 0\n   References count 2\n   Field parameterTypes of instance 0x64614fd0\n   Field parameterTypes of instance 0x64615030\n   Path to nearest GC root\n    Null\n  Instance Id 0x64627918 number 2 retained size 0\n   References count 2\n   Field parameterTypes of instance 0x64627928\n   Field parameterTypes of instance 0x64627988\n   Path to nearest GC root\n    Null\n  Instance Id 0x646283e0 number 3 retained size 0\n   References count 2\n   Field parameterTypes of instance 0x646283f0\n   Field parameterTypes of instance 0x64628450\n   Path to nearest GC root\n    Null\n  Instance Id 0x646292d0 number 4 retained size 0\n   References count 2\n   Field parameterTypes of instance 0x646292e0\n   Field parameterTypes of instance 0x64629340\n   Path to nearest GC root\n    Null\n  Instance Id 0x64630a28 number 5 retained size 16\n   References count 1\n   Field PARAMS0 of Class sun.security.provider.PolicyFile\n   Path to nearest GC root\n    Next object java.lang.Class#377\n  Instance Id 0x64630a38 number 6 retained size 16\n   References count 1\n   Field PARAMS1 of Class sun.security.provider.PolicyFile\n   Path to nearest GC root\n    Next object java.lang.Class#377\n  Instance Id 0x64630a48 number 7 retained size 24\n   References count 1\n   Field PARAMS2 of Class sun.security.provider.PolicyFile\n   Path to nearest GC root\n    Next object java.lang.Class#377\n  Instance Id 0x64630cf8 number 8 retained size 0\n   References count 1\n   Field parameterTypes of instance 0x64630d08\n   Path to nearest GC root\n    Null\n Id 0x6c939840 Class java.lang.Object SuperClass null Instance size 8 Instance count 17 All Instances Size 136\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610800 number 1 retained size 8\n   References count 1\n   Field blockerLock of instance 0x64610790\n   Path to nearest GC root\n    Next object java.lang.Thread#1\n  Instance Id 0x646109e8 number 2 retained size 8\n   References count 1\n   Field blockerLock of instance 0x64610978\n   Path to nearest GC root\n    Next object java.lang.ref.Reference$ReferenceHandler#1\n  Instance Id 0x64610a78 number 3 retained size 8\n   References count 1\n   Field lock of Class java.lang.ref.Finalizer\n   Path to nearest GC root\n    Next object java.lang.Class#118\n  Instance Id 0x64610af0 number 4 retained size 8\n   References count 1\n   Field blockerLock of instance 0x64610a80\n   Path to nearest GC root\n    Next object java.lang.ref.Finalizer$FinalizerThread#1\n  Instance Id 0x64614f60 number 5 retained size 8\n   References count 1\n   Field extendedProviderLock of Class java.nio.charset.Charset\n   Path to nearest GC root\n    Next object java.lang.Class#419\n  Instance Id 0x64616eb0 number 6 retained size 8\n   References count 1\n   Field tmpFileLock of Class java.io.File\n   Path to nearest GC root\n    Next object java.lang.Class#270\n  Instance Id 0x64625718 number 7 retained size 8\n   References count 1\n   Field NULL_KEY of Class java.util.IdentityHashMap\n   Path to nearest GC root\n    Next object java.lang.Class#191\n  Instance Id 0x646264a0 number 8 retained size 8\n   References count 1\n   Field streamHandlerLock of Class java.net.URL\n   Path to nearest GC root\n    Next object java.lang.Class#273\n  Instance Id 0x64628078 number 9 retained size 8\n   References count 2\n   Field PRESENT of Class java.util.HashSet\n   Field value of instance 0x64630ce0\n   Path to nearest GC root\n    Next object java.lang.Class#249\n  Instance Id 0x64628af8 number 10 retained size 8\n   References count 1\n   Field blockerLock of instance 0x64628a88\n   Path to nearest GC root\n    Next object java.lang.Thread#2\n  Instance Id 0x64628bb8 number 11 retained size 0\n   References count 1\n   Field blockerLock of instance 0x64628b48\n   Path to nearest GC root\n    Null\n  Instance Id 0x64628c78 number 12 retained size 0\n   References count 1\n   Field blockerLock of instance 0x64628c08\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462f000 number 13 retained size 8\n   References count 1\n   Field LOCK_GET_BYTES of instance 0x6462efc8\n   Path to nearest GC root\n    Next object sun.security.provider.NativePRNG$RandomIO#1\n    Next object java.lang.Class#339\n  Instance Id 0x6462f008 number 14 retained size 8\n   References count 1\n   Field LOCK_GET_SEED of instance 0x6462efc8\n   Path to nearest GC root\n    Next object sun.security.provider.NativePRNG$RandomIO#1\n    Next object java.lang.Class#339\n  Instance Id 0x6462f010 number 15 retained size 8\n   References count 1\n   Field LOCK_SET_SEED of instance 0x6462efc8\n   Path to nearest GC root\n    Next object sun.security.provider.NativePRNG$RandomIO#1\n    Next object java.lang.Class#339\n  Instance Id 0x64630e30 number 16 retained size 8\n   References count 1\n   Field blockerLock of instance 0x64630d78\n   Path to nearest GC root\n    Next object java.lang.Thread#5\n  Instance Id 0x68130370 number 17 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n Id 0x6c96b578 Class java.lang.Object[] SuperClass java.lang.Object Instance size -1 Instance count 316 All Instances Size 13216\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x646101a8 number 1 retained size 0\n   References count 1\n   Field backtrace of instance 0x68130af8\n   Path to nearest GC root\n    Null\n  Instance Id 0x646101c0 number 2 retained size 0\n   References count 1\n   Element 0 of array 0x646101a8\n   Path to nearest GC root\n    Null\n  Instance Id 0x646102a0 number 3 retained size 0\n   References count 1\n   Field backtrace of instance 0x68130b10\n   Path to nearest GC root\n    Null\n  Instance Id 0x646102b8 number 4 retained size 0\n   References count 1\n   Element 0 of array 0x646102a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610398 number 5 retained size 0\n   References count 1\n   Field backtrace of instance 0x68130b28\n   Path to nearest GC root\n    Null\n  Instance Id 0x646103b0 number 6 retained size 0\n   References count 1\n   Element 0 of array 0x64610398\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610490 number 7 retained size 0\n   References count 1\n   Field backtrace of instance 0x68130b40\n   Path to nearest GC root\n    Null\n  Instance Id 0x646104a8 number 8 retained size 0\n   References count 1\n   Element 0 of array 0x64610490\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610868 number 9 retained size 56\n   References count 1\n   Field elementData of instance 0x64610850\n   Path to nearest GC root\n    Next object java.util.Vector#1\n    Next object java.lang.Class#101\n  Instance Id 0x646108b8 number 10 retained size 56\n   References count 1\n   Field elementData of instance 0x646108a0\n   Path to nearest GC root\n    Next object java.util.Vector#2\n    Next object java.lang.Class#101\n  Instance Id 0x64610908 number 11 retained size 56\n   References count 1\n   Field elementData of instance 0x646108f0\n   Path to nearest GC root\n    Next object java.util.Stack#1\n    Next object java.lang.Class#101\n  Instance Id 0x646120d8 number 12 retained size 9104\n   References count 1\n   Field ht of instance 0x646120b0\n   Path to nearest GC root\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646130e8 number 13 retained size 24\n   References count 1\n   Element 1 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613100 number 14 retained size 24\n   References count 1\n   Element 2 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613118 number 15 retained size 24\n   References count 1\n   Element 3 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613130 number 16 retained size 24\n   References count 1\n   Element 5 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613148 number 17 retained size 24\n   References count 1\n   Element 6 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613160 number 18 retained size 24\n   References count 1\n   Element 10 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613178 number 19 retained size 24\n   References count 1\n   Element 19 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613190 number 20 retained size 24\n   References count 1\n   Element 24 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646131a8 number 21 retained size 24\n   References count 1\n   Element 25 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646131c0 number 22 retained size 24\n   References count 1\n   Element 26 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646131d8 number 23 retained size 24\n   References count 1\n   Element 28 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646131f0 number 24 retained size 24\n   References count 1\n   Element 29 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613208 number 25 retained size 24\n   References count 1\n   Element 55 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613220 number 26 retained size 24\n   References count 1\n   Element 58 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613238 number 27 retained size 48\n   References count 1\n   Element 86 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613250 number 28 retained size 24\n   References count 1\n   Element 2 of array 0x64613238\n   Path to nearest GC root\n    Next object java.lang.Object[]#27\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613268 number 29 retained size 24\n   References count 1\n   Element 87 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613280 number 30 retained size 24\n   References count 1\n   Element 89 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613298 number 31 retained size 48\n   References count 1\n   Element 90 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646132b0 number 32 retained size 24\n   References count 1\n   Element 2 of array 0x64613298\n   Path to nearest GC root\n    Next object java.lang.Object[]#31\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646132c8 number 33 retained size 24\n   References count 1\n   Element 92 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646132e0 number 34 retained size 24\n   References count 1\n   Element 94 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646132f8 number 35 retained size 24\n   References count 1\n   Element 95 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613310 number 36 retained size 24\n   References count 1\n   Element 96 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613328 number 37 retained size 24\n   References count 1\n   Element 106 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613340 number 38 retained size 24\n   References count 1\n   Element 121 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613358 number 39 retained size 24\n   References count 1\n   Element 125 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613370 number 40 retained size 24\n   References count 1\n   Element 134 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613388 number 41 retained size 24\n   References count 1\n   Element 137 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646133a0 number 42 retained size 24\n   References count 1\n   Element 141 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646133b8 number 43 retained size 24\n   References count 1\n   Element 143 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646133d0 number 44 retained size 24\n   References count 1\n   Element 144 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646133e8 number 45 retained size 24\n   References count 1\n   Element 170 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613400 number 46 retained size 24\n   References count 1\n   Element 173 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613418 number 47 retained size 24\n   References count 1\n   Element 177 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613430 number 48 retained size 24\n   References count 1\n   Element 192 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613448 number 49 retained size 48\n   References count 1\n   Element 199 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613460 number 50 retained size 24\n   References count 1\n   Element 2 of array 0x64613448\n   Path to nearest GC root\n    Next object java.lang.Object[]#49\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613478 number 51 retained size 24\n   References count 1\n   Element 205 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613490 number 52 retained size 48\n   References count 1\n   Element 211 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646134a8 number 53 retained size 24\n   References count 1\n   Element 2 of array 0x64613490\n   Path to nearest GC root\n    Next object java.lang.Object[]#52\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646134c0 number 54 retained size 24\n   References count 1\n   Element 213 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646134d8 number 55 retained size 24\n   References count 1\n   Element 216 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646134f0 number 56 retained size 48\n   References count 1\n   Element 218 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613508 number 57 retained size 24\n   References count 1\n   Element 2 of array 0x646134f0\n   Path to nearest GC root\n    Next object java.lang.Object[]#56\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613520 number 58 retained size 48\n   References count 1\n   Element 219 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613538 number 59 retained size 24\n   References count 1\n   Element 2 of array 0x64613520\n   Path to nearest GC root\n    Next object java.lang.Object[]#58\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613550 number 60 retained size 24\n   References count 1\n   Element 225 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613568 number 61 retained size 24\n   References count 1\n   Element 244 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613580 number 62 retained size 24\n   References count 1\n   Element 248 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613598 number 63 retained size 24\n   References count 1\n   Element 253 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646135b0 number 64 retained size 24\n   References count 1\n   Element 254 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646135c8 number 65 retained size 24\n   References count 1\n   Element 259 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646135e0 number 66 retained size 24\n   References count 1\n   Element 269 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646135f8 number 67 retained size 24\n   References count 1\n   Element 277 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613610 number 68 retained size 24\n   References count 1\n   Element 280 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613628 number 69 retained size 24\n   References count 1\n   Element 283 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613640 number 70 retained size 24\n   References count 1\n   Element 284 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613658 number 71 retained size 24\n   References count 1\n   Element 286 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613670 number 72 retained size 24\n   References count 1\n   Element 287 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613688 number 73 retained size 24\n   References count 1\n   Element 289 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646136a0 number 74 retained size 24\n   References count 1\n   Element 291 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646136b8 number 75 retained size 24\n   References count 1\n   Element 294 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646136d0 number 76 retained size 24\n   References count 1\n   Element 296 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646136e8 number 77 retained size 24\n   References count 1\n   Element 297 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613700 number 78 retained size 24\n   References count 1\n   Element 305 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613718 number 79 retained size 24\n   References count 1\n   Element 307 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613730 number 80 retained size 48\n   References count 1\n   Element 312 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613748 number 81 retained size 24\n   References count 1\n   Element 2 of array 0x64613730\n   Path to nearest GC root\n    Next object java.lang.Object[]#80\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613760 number 82 retained size 24\n   References count 1\n   Element 321 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613778 number 83 retained size 48\n   References count 1\n   Element 323 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613790 number 84 retained size 24\n   References count 1\n   Element 2 of array 0x64613778\n   Path to nearest GC root\n    Next object java.lang.Object[]#83\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646137a8 number 85 retained size 24\n   References count 1\n   Element 324 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646137c0 number 86 retained size 24\n   References count 1\n   Element 325 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646137d8 number 87 retained size 72\n   References count 1\n   Element 326 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646137f0 number 88 retained size 48\n   References count 1\n   Element 2 of array 0x646137d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#87\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613808 number 89 retained size 24\n   References count 1\n   Element 2 of array 0x646137f0\n   Path to nearest GC root\n    Next object java.lang.Object[]#88\n    Next object java.lang.Object[]#87\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613820 number 90 retained size 24\n   References count 1\n   Element 327 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613838 number 91 retained size 48\n   References count 1\n   Element 328 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613850 number 92 retained size 24\n   References count 1\n   Element 2 of array 0x64613838\n   Path to nearest GC root\n    Next object java.lang.Object[]#91\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613868 number 93 retained size 24\n   References count 1\n   Element 329 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613880 number 94 retained size 24\n   References count 1\n   Element 331 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613898 number 95 retained size 48\n   References count 1\n   Element 333 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646138b0 number 96 retained size 24\n   References count 1\n   Element 2 of array 0x64613898\n   Path to nearest GC root\n    Next object java.lang.Object[]#95\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646138c8 number 97 retained size 48\n   References count 1\n   Element 334 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646138e0 number 98 retained size 24\n   References count 1\n   Element 2 of array 0x646138c8\n   Path to nearest GC root\n    Next object java.lang.Object[]#97\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646138f8 number 99 retained size 24\n   References count 1\n   Element 336 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613910 number 100 retained size 24\n   References count 1\n   Element 339 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613928 number 101 retained size 24\n   References count 1\n   Element 341 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613940 number 102 retained size 24\n   References count 1\n   Element 345 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613958 number 103 retained size 24\n   References count 1\n   Element 350 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613970 number 104 retained size 24\n   References count 1\n   Element 353 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613988 number 105 retained size 24\n   References count 1\n   Element 358 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646139a0 number 106 retained size 24\n   References count 1\n   Element 359 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646139b8 number 107 retained size 24\n   References count 1\n   Element 363 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646139d0 number 108 retained size 24\n   References count 1\n   Element 364 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646139e8 number 109 retained size 24\n   References count 1\n   Element 378 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613a00 number 110 retained size 24\n   References count 1\n   Element 385 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613a18 number 111 retained size 24\n   References count 1\n   Element 391 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613a30 number 112 retained size 24\n   References count 1\n   Element 392 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613a48 number 113 retained size 24\n   References count 1\n   Element 405 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613a60 number 114 retained size 24\n   References count 1\n   Element 406 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613a78 number 115 retained size 24\n   References count 1\n   Element 408 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613a90 number 116 retained size 24\n   References count 1\n   Element 421 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613aa8 number 117 retained size 24\n   References count 1\n   Element 428 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613ac0 number 118 retained size 24\n   References count 1\n   Element 429 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613ad8 number 119 retained size 24\n   References count 1\n   Element 430 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613af0 number 120 retained size 24\n   References count 1\n   Element 432 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613b08 number 121 retained size 24\n   References count 1\n   Element 433 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613b20 number 122 retained size 24\n   References count 1\n   Element 436 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613b38 number 123 retained size 24\n   References count 1\n   Element 437 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613b50 number 124 retained size 24\n   References count 1\n   Element 438 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613b68 number 125 retained size 24\n   References count 1\n   Element 443 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613b80 number 126 retained size 24\n   References count 1\n   Element 456 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613b98 number 127 retained size 24\n   References count 1\n   Element 473 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613bb0 number 128 retained size 24\n   References count 1\n   Element 479 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613bc8 number 129 retained size 24\n   References count 1\n   Element 481 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613be0 number 130 retained size 24\n   References count 1\n   Element 484 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613bf8 number 131 retained size 24\n   References count 1\n   Element 486 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613c10 number 132 retained size 24\n   References count 1\n   Element 487 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613c28 number 133 retained size 24\n   References count 1\n   Element 502 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613c40 number 134 retained size 24\n   References count 1\n   Element 506 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613c58 number 135 retained size 24\n   References count 1\n   Element 508 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613c70 number 136 retained size 24\n   References count 1\n   Element 511 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613c88 number 137 retained size 24\n   References count 1\n   Element 512 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613ca0 number 138 retained size 24\n   References count 1\n   Element 513 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613cb8 number 139 retained size 24\n   References count 1\n   Element 514 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613cd0 number 140 retained size 24\n   References count 1\n   Element 516 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613ce8 number 141 retained size 24\n   References count 1\n   Element 520 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613d00 number 142 retained size 24\n   References count 1\n   Element 523 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613d18 number 143 retained size 24\n   References count 1\n   Element 524 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613d30 number 144 retained size 24\n   References count 1\n   Element 533 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613d48 number 145 retained size 24\n   References count 1\n   Element 537 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613d60 number 146 retained size 24\n   References count 1\n   Element 539 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613d78 number 147 retained size 24\n   References count 1\n   Element 543 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613d90 number 148 retained size 24\n   References count 1\n   Element 545 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613da8 number 149 retained size 24\n   References count 1\n   Element 563 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613dc0 number 150 retained size 24\n   References count 1\n   Element 572 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613dd8 number 151 retained size 24\n   References count 1\n   Element 573 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613df0 number 152 retained size 24\n   References count 1\n   Element 577 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613e08 number 153 retained size 24\n   References count 1\n   Element 582 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613e20 number 154 retained size 24\n   References count 1\n   Element 588 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613e38 number 155 retained size 24\n   References count 1\n   Element 593 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613e50 number 156 retained size 24\n   References count 1\n   Element 598 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613e68 number 157 retained size 24\n   References count 1\n   Element 609 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613e80 number 158 retained size 24\n   References count 1\n   Element 617 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613e98 number 159 retained size 24\n   References count 1\n   Element 618 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613eb0 number 160 retained size 24\n   References count 1\n   Element 619 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613ec8 number 161 retained size 24\n   References count 1\n   Element 620 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613ee0 number 162 retained size 24\n   References count 1\n   Element 621 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613ef8 number 163 retained size 48\n   References count 1\n   Element 624 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613f10 number 164 retained size 24\n   References count 1\n   Element 2 of array 0x64613ef8\n   Path to nearest GC root\n    Next object java.lang.Object[]#163\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613f28 number 165 retained size 24\n   References count 1\n   Element 628 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613f40 number 166 retained size 24\n   References count 1\n   Element 632 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613f58 number 167 retained size 48\n   References count 1\n   Element 634 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613f70 number 168 retained size 24\n   References count 1\n   Element 2 of array 0x64613f58\n   Path to nearest GC root\n    Next object java.lang.Object[]#167\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613f88 number 169 retained size 24\n   References count 1\n   Element 635 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613fa0 number 170 retained size 24\n   References count 1\n   Element 636 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613fb8 number 171 retained size 24\n   References count 1\n   Element 654 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613fd0 number 172 retained size 24\n   References count 1\n   Element 669 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64613fe8 number 173 retained size 24\n   References count 1\n   Element 670 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614000 number 174 retained size 24\n   References count 1\n   Element 671 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614018 number 175 retained size 24\n   References count 1\n   Element 676 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614030 number 176 retained size 24\n   References count 1\n   Element 679 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614048 number 177 retained size 24\n   References count 1\n   Element 686 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614060 number 178 retained size 24\n   References count 1\n   Element 703 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614078 number 179 retained size 24\n   References count 1\n   Element 710 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614090 number 180 retained size 24\n   References count 1\n   Element 712 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646140a8 number 181 retained size 24\n   References count 1\n   Element 732 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646140c0 number 182 retained size 24\n   References count 1\n   Element 733 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646140d8 number 183 retained size 24\n   References count 1\n   Element 768 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646140f0 number 184 retained size 24\n   References count 1\n   Element 774 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614108 number 185 retained size 24\n   References count 1\n   Element 781 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614120 number 186 retained size 24\n   References count 1\n   Element 782 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614138 number 187 retained size 24\n   References count 1\n   Element 783 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614150 number 188 retained size 24\n   References count 1\n   Element 784 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614168 number 189 retained size 24\n   References count 1\n   Element 785 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614180 number 190 retained size 24\n   References count 1\n   Element 787 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614198 number 191 retained size 24\n   References count 1\n   Element 789 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646141b0 number 192 retained size 24\n   References count 1\n   Element 813 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646141c8 number 193 retained size 24\n   References count 1\n   Element 818 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646141e0 number 194 retained size 24\n   References count 1\n   Element 832 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646141f8 number 195 retained size 24\n   References count 1\n   Element 834 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614210 number 196 retained size 48\n   References count 1\n   Element 835 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614228 number 197 retained size 24\n   References count 1\n   Element 2 of array 0x64614210\n   Path to nearest GC root\n    Next object java.lang.Object[]#196\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614240 number 198 retained size 24\n   References count 1\n   Element 836 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614258 number 199 retained size 24\n   References count 1\n   Element 837 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614270 number 200 retained size 24\n   References count 1\n   Element 838 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614288 number 201 retained size 48\n   References count 1\n   Element 840 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646142a0 number 202 retained size 24\n   References count 1\n   Element 2 of array 0x64614288\n   Path to nearest GC root\n    Next object java.lang.Object[]#201\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646142b8 number 203 retained size 24\n   References count 1\n   Element 842 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646142d0 number 204 retained size 24\n   References count 1\n   Element 843 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646142e8 number 205 retained size 24\n   References count 1\n   Element 846 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614300 number 206 retained size 24\n   References count 1\n   Element 849 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614318 number 207 retained size 24\n   References count 1\n   Element 881 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614330 number 208 retained size 24\n   References count 1\n   Element 896 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614348 number 209 retained size 24\n   References count 1\n   Element 909 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614360 number 210 retained size 24\n   References count 1\n   Element 910 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614378 number 211 retained size 24\n   References count 1\n   Element 911 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614390 number 212 retained size 24\n   References count 1\n   Element 912 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646143a8 number 213 retained size 24\n   References count 1\n   Element 925 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646143c0 number 214 retained size 24\n   References count 1\n   Element 934 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646143d8 number 215 retained size 24\n   References count 1\n   Element 937 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646143f0 number 216 retained size 24\n   References count 1\n   Element 944 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614408 number 217 retained size 24\n   References count 1\n   Element 957 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614420 number 218 retained size 24\n   References count 1\n   Element 993 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614438 number 219 retained size 24\n   References count 1\n   Element 1009 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614450 number 220 retained size 24\n   References count 1\n   Element 1015 of array 0x646120d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#12\n    Next object sun.nio.cs.StandardCharsets$Aliases#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614490 number 221 retained size 1056\n   References count 1\n   Field ht of instance 0x64614468\n   Path to nearest GC root\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614520 number 222 retained size 24\n   References count 1\n   Element 0 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614538 number 223 retained size 72\n   References count 1\n   Element 2 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614550 number 224 retained size 48\n   References count 1\n   Element 2 of array 0x64614538\n   Path to nearest GC root\n    Next object java.lang.Object[]#223\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614568 number 225 retained size 24\n   References count 1\n   Element 2 of array 0x64614550\n   Path to nearest GC root\n    Next object java.lang.Object[]#224\n    Next object java.lang.Object[]#223\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614580 number 226 retained size 48\n   References count 1\n   Element 3 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614598 number 227 retained size 24\n   References count 1\n   Element 2 of array 0x64614580\n   Path to nearest GC root\n    Next object java.lang.Object[]#226\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646145b0 number 228 retained size 72\n   References count 1\n   Element 4 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646145c8 number 229 retained size 48\n   References count 1\n   Element 2 of array 0x646145b0\n   Path to nearest GC root\n    Next object java.lang.Object[]#228\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646145e0 number 230 retained size 24\n   References count 1\n   Element 2 of array 0x646145c8\n   Path to nearest GC root\n    Next object java.lang.Object[]#229\n    Next object java.lang.Object[]#228\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646145f8 number 231 retained size 48\n   References count 1\n   Element 5 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614610 number 232 retained size 24\n   References count 1\n   Element 2 of array 0x646145f8\n   Path to nearest GC root\n    Next object java.lang.Object[]#231\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614628 number 233 retained size 24\n   References count 1\n   Element 6 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614640 number 234 retained size 24\n   References count 1\n   Element 7 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614658 number 235 retained size 48\n   References count 1\n   Element 8 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614670 number 236 retained size 24\n   References count 1\n   Element 2 of array 0x64614658\n   Path to nearest GC root\n    Next object java.lang.Object[]#235\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614688 number 237 retained size 48\n   References count 1\n   Element 9 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646146a0 number 238 retained size 24\n   References count 1\n   Element 2 of array 0x64614688\n   Path to nearest GC root\n    Next object java.lang.Object[]#237\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646146b8 number 239 retained size 24\n   References count 1\n   Element 10 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646146d0 number 240 retained size 48\n   References count 1\n   Element 11 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646146e8 number 241 retained size 24\n   References count 1\n   Element 2 of array 0x646146d0\n   Path to nearest GC root\n    Next object java.lang.Object[]#240\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614700 number 242 retained size 24\n   References count 1\n   Element 12 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614718 number 243 retained size 24\n   References count 1\n   Element 14 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614730 number 244 retained size 24\n   References count 1\n   Element 15 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614748 number 245 retained size 48\n   References count 1\n   Element 16 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614760 number 246 retained size 24\n   References count 1\n   Element 2 of array 0x64614748\n   Path to nearest GC root\n    Next object java.lang.Object[]#245\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614778 number 247 retained size 48\n   References count 1\n   Element 17 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614790 number 248 retained size 24\n   References count 1\n   Element 2 of array 0x64614778\n   Path to nearest GC root\n    Next object java.lang.Object[]#247\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646147a8 number 249 retained size 72\n   References count 1\n   Element 18 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646147c0 number 250 retained size 48\n   References count 1\n   Element 2 of array 0x646147a8\n   Path to nearest GC root\n    Next object java.lang.Object[]#249\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646147d8 number 251 retained size 24\n   References count 1\n   Element 2 of array 0x646147c0\n   Path to nearest GC root\n    Next object java.lang.Object[]#250\n    Next object java.lang.Object[]#249\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646147f0 number 252 retained size 72\n   References count 1\n   Element 19 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614808 number 253 retained size 48\n   References count 1\n   Element 2 of array 0x646147f0\n   Path to nearest GC root\n    Next object java.lang.Object[]#252\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614820 number 254 retained size 24\n   References count 1\n   Element 2 of array 0x64614808\n   Path to nearest GC root\n    Next object java.lang.Object[]#253\n    Next object java.lang.Object[]#252\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614838 number 255 retained size 24\n   References count 1\n   Element 22 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614850 number 256 retained size 24\n   References count 1\n   Element 24 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614868 number 257 retained size 24\n   References count 1\n   Element 28 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614880 number 258 retained size 24\n   References count 1\n   Element 29 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614898 number 259 retained size 24\n   References count 1\n   Element 31 of array 0x64614490\n   Path to nearest GC root\n    Next object java.lang.Object[]#221\n    Next object sun.nio.cs.StandardCharsets$Classes#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646148d8 number 260 retained size 1056\n   References count 1\n   Field ht of instance 0x646148b0\n   Path to nearest GC root\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614968 number 261 retained size 24\n   References count 1\n   Element 0 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614980 number 262 retained size 72\n   References count 1\n   Element 2 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614998 number 263 retained size 48\n   References count 1\n   Element 2 of array 0x64614980\n   Path to nearest GC root\n    Next object java.lang.Object[]#262\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646149b0 number 264 retained size 24\n   References count 1\n   Element 2 of array 0x64614998\n   Path to nearest GC root\n    Next object java.lang.Object[]#263\n    Next object java.lang.Object[]#262\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646149c8 number 265 retained size 48\n   References count 1\n   Element 3 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646149e0 number 266 retained size 24\n   References count 1\n   Element 2 of array 0x646149c8\n   Path to nearest GC root\n    Next object java.lang.Object[]#265\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646149f8 number 267 retained size 72\n   References count 1\n   Element 4 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614a10 number 268 retained size 48\n   References count 1\n   Element 2 of array 0x646149f8\n   Path to nearest GC root\n    Next object java.lang.Object[]#267\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614a28 number 269 retained size 24\n   References count 1\n   Element 2 of array 0x64614a10\n   Path to nearest GC root\n    Next object java.lang.Object[]#268\n    Next object java.lang.Object[]#267\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614a40 number 270 retained size 48\n   References count 1\n   Element 5 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614a58 number 271 retained size 24\n   References count 1\n   Element 2 of array 0x64614a40\n   Path to nearest GC root\n    Next object java.lang.Object[]#270\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614a70 number 272 retained size 24\n   References count 1\n   Element 6 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614a88 number 273 retained size 24\n   References count 1\n   Element 7 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614aa0 number 274 retained size 48\n   References count 1\n   Element 8 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614ab8 number 275 retained size 24\n   References count 1\n   Element 2 of array 0x64614aa0\n   Path to nearest GC root\n    Next object java.lang.Object[]#274\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614ad0 number 276 retained size 48\n   References count 1\n   Element 9 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614ae8 number 277 retained size 24\n   References count 1\n   Element 2 of array 0x64614ad0\n   Path to nearest GC root\n    Next object java.lang.Object[]#276\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614b00 number 278 retained size 24\n   References count 1\n   Element 10 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614b18 number 279 retained size 48\n   References count 1\n   Element 11 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614b30 number 280 retained size 24\n   References count 1\n   Element 2 of array 0x64614b18\n   Path to nearest GC root\n    Next object java.lang.Object[]#279\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614b48 number 281 retained size 24\n   References count 1\n   Element 12 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614b60 number 282 retained size 24\n   References count 1\n   Element 14 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614b78 number 283 retained size 24\n   References count 1\n   Element 15 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614b90 number 284 retained size 48\n   References count 1\n   Element 16 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614ba8 number 285 retained size 24\n   References count 1\n   Element 2 of array 0x64614b90\n   Path to nearest GC root\n    Next object java.lang.Object[]#284\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614bc0 number 286 retained size 48\n   References count 1\n   Element 17 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614bd8 number 287 retained size 24\n   References count 1\n   Element 2 of array 0x64614bc0\n   Path to nearest GC root\n    Next object java.lang.Object[]#286\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614bf0 number 288 retained size 72\n   References count 1\n   Element 18 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614c08 number 289 retained size 48\n   References count 1\n   Element 2 of array 0x64614bf0\n   Path to nearest GC root\n    Next object java.lang.Object[]#288\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614c20 number 290 retained size 24\n   References count 1\n   Element 2 of array 0x64614c08\n   Path to nearest GC root\n    Next object java.lang.Object[]#289\n    Next object java.lang.Object[]#288\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614c38 number 291 retained size 72\n   References count 1\n   Element 19 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614c50 number 292 retained size 48\n   References count 1\n   Element 2 of array 0x64614c38\n   Path to nearest GC root\n    Next object java.lang.Object[]#291\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614c68 number 293 retained size 24\n   References count 1\n   Element 2 of array 0x64614c50\n   Path to nearest GC root\n    Next object java.lang.Object[]#292\n    Next object java.lang.Object[]#291\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614c80 number 294 retained size 24\n   References count 1\n   Element 22 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614c98 number 295 retained size 24\n   References count 1\n   Element 24 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614cb0 number 296 retained size 24\n   References count 1\n   Element 28 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614cc8 number 297 retained size 24\n   References count 1\n   Element 29 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x64614ce0 number 298 retained size 24\n   References count 1\n   Element 31 of array 0x646148d8\n   Path to nearest GC root\n    Next object java.lang.Object[]#260\n    Next object sun.nio.cs.StandardCharsets$Cache#1\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n  Instance Id 0x646150b0 number 299 retained size 24\n   References count 1\n   Field cache2 of Class java.nio.charset.Charset\n   Path to nearest GC root\n    Next object java.lang.Class#419\n  Instance Id 0x646256d0 number 300 retained size 72\n   References count 1\n   Field elementData of instance 0x646256b8\n   Path to nearest GC root\n    Next object java.util.ArrayList#1\n    Next object java.lang.Class#110\n  Instance Id 0x64625748 number 301 retained size 272\n   References count 1\n   Field table of instance 0x64625720\n   Path to nearest GC root\n    Next object java.util.IdentityHashMap#1\n    Next object java.lang.Class#305\n  Instance Id 0x64628040 number 302 retained size 56\n   References count 1\n   Field elementData of instance 0x64628028\n   Path to nearest GC root\n    Next object java.util.Vector#3\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628198 number 303 retained size 56\n   References count 1\n   Field elementData of instance 0x64628180\n   Path to nearest GC root\n    Next object java.util.Vector#4\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628280 number 304 retained size 56\n   References count 1\n   Field elementData of instance 0x64628268\n   Path to nearest GC root\n    Next object java.util.ArrayList#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646282d0 number 305 retained size 56\n   References count 1\n   Field elementData of instance 0x646282b8\n   Path to nearest GC root\n    Next object java.util.Stack#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628320 number 306 retained size 56\n   References count 1\n   Field elementData of instance 0x64628308\n   Path to nearest GC root\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646286e0 number 307 retained size 56\n   References count 1\n   Field elementData of instance 0x646286c8\n   Path to nearest GC root\n    Next object java.util.Vector#5\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628830 number 308 retained size 56\n   References count 1\n   Field elementData of instance 0x64628818\n   Path to nearest GC root\n    Next object java.util.Vector#6\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628918 number 309 retained size 56\n   References count 1\n   Field elementData of instance 0x64628900\n   Path to nearest GC root\n    Next object java.util.ArrayList#4\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628968 number 310 retained size 56\n   References count 1\n   Field elementData of instance 0x64628950\n   Path to nearest GC root\n    Next object java.util.Stack#3\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646289b8 number 311 retained size 56\n   References count 1\n   Field elementData of instance 0x646289a0\n   Path to nearest GC root\n    Next object java.util.ArrayList#5\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629030 number 312 retained size 0\n   References count 1\n   Field elementData of instance 0x64629018\n   Path to nearest GC root\n    Null\n  Instance Id 0x646293c0 number 313 retained size 24\n   References count 1\n   Field cache1 of Class java.nio.charset.Charset\n   Path to nearest GC root\n    Next object java.lang.Class#419\n  Instance Id 0x64629908 number 314 retained size 0\n   References count 1\n   Field elementData of instance 0x646298f0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a000 number 315 retained size 56\n   References count 1\n   Field elementData of instance 0x64629fe8\n   Path to nearest GC root\n    Next object java.util.Vector#8\n    Next object java.util.jar.JarFile#2\n    Next object sun.misc.URLClassPath$JarLoader#5\n    Next object java.lang.Object[]#311\n    Next object java.util.ArrayList#5\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64630ab8 number 316 retained size 160\n   References count 1\n   Field elementData of instance 0x64630aa0\n   Path to nearest GC root\n    Next object java.util.ArrayList#7\n    Next object java.io.FilePermissionCollection#1\n    Next object java.util.HashMap$Entry#153\n    Next object java.util.HashMap$Entry[]#24\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c948d60 Class java.lang.ThreadGroup SuperClass java.lang.Object Instance size 48 Instance count 2 All Instances Size 96\n  Static Field name <classLoader> type object value 0\n  Field name groups type object\n  Field name ngroups type int\n  Field name threads type object\n  Field name nthreads type int\n  Field name nUnstartedThreads type int\n  Field name vmAllowSuspension type boolean\n  Field name daemon type boolean\n  Field name destroyed type boolean\n  Field name maxPriority type int\n  Field name name type object\n  Field name parent type object\n  Instance Id 0x646105a0 number 1 retained size 112\n   Instance Field name groups type object value 1684080176\n    Ref object java.lang.ThreadGroup[]#1\n   Instance Field name ngroups type int value 1\n   Instance Field name threads type object value 1684081208\n    Ref object java.lang.Thread[]#1\n   Instance Field name nthreads type int value 4\n   Instance Field name nUnstartedThreads type int value 2\n   Instance Field name vmAllowSuspension type boolean value false\n   Instance Field name daemon type boolean value false\n   Instance Field name destroyed type boolean value false\n   Instance Field name maxPriority type int value 10\n   Instance Field name name type object value 0\n   Instance Field name parent type object value 0\n   References count 7\n   Field group of instance 0x64610a80\n   Field group of instance 0x64628a88\n   Field group of instance 0x64628b48\n   Field group of instance 0x64628c08\n   Field parent of instance 0x646105d0\n   Field group of instance 0x64610978\n   Field group of instance 0x64630d78\n   Path to nearest GC root\n    Next object java.lang.ref.Finalizer$FinalizerThread#1\n  Instance Id 0x646105d0 number 2 retained size 128\n   Instance Field name groups type object value 0\n   Instance Field name ngroups type int value 0\n   Instance Field name threads type object value 1684166752\n    Ref object java.lang.Thread[]#2\n   Instance Field name nthreads type int value 1\n   Instance Field name nUnstartedThreads type int value 0\n   Instance Field name vmAllowSuspension type boolean value false\n   Instance Field name daemon type boolean value false\n   Instance Field name destroyed type boolean value false\n   Instance Field name maxPriority type int value 10\n   Instance Field name name type object value 1684080128\n    Ref object java.lang.String#6\n   Instance Field name parent type object value 1684080032\n    Ref object java.lang.ThreadGroup#1\n   References count 2\n   Field group of instance 0x64610790\n   Element 0 of array 0x64610630\n   Path to nearest GC root\n    Next object java.lang.Thread#1\n Id 0x68131208 Class java.lang.ThreadGroup[] SuperClass java.lang.Object Instance size -1 Instance count 1 All Instances Size 32\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610630 number 1 retained size 32\n   References count 1\n   Field groups of instance 0x646105a0\n   Path to nearest GC root\n    Next object java.lang.ThreadGroup#1\n    Next object java.lang.ref.Finalizer$FinalizerThread#1\n Id 0x6c9476c8 Class java.lang.Thread SuperClass java.lang.Object Instance size 104 Instance count 5 All Instances Size 520\n  Static Field name defaultUncaughtExceptionHandler type object value 0\n  Static Field name subclassAudits type object value 1684080248\n   Ref object sun.misc.SoftCache#1\n  Static Field name SUBCLASS_IMPLEMENTATION_PERMISSION type object value 1684080224\n   Ref object java.lang.RuntimePermission#1\n  Static Field name EMPTY_STACK_TRACE type object value 1684080208\n   Ref object java.lang.StackTraceElement[]#1\n  Static Field name MAX_PRIORITY type int value 10\n  Static Field name NORM_PRIORITY type int value 5\n  Static Field name MIN_PRIORITY type int value 1\n  Static Field name threadSeqNumber type long value 7\n  Static Field name threadInitNumber type int value 0\n  Static Field name <classLoader> type object value 0\n  Field name uncaughtExceptionHandler type object\n  Field name throwableFromStop type object\n  Field name stopBeforeStart type boolean\n  Field name blockerLock type object\n  Field name blocker type object\n  Field name parkBlocker type object\n  Field name threadStatus type int\n  Field name tid type long\n  Field name nativeParkEventPointer type long\n  Field name stackSize type long\n  Field name inheritableThreadLocals type object\n  Field name threadLocals type object\n  Field name inheritedAccessControlContext type object\n  Field name contextClassLoader type object\n  Field name group type object\n  Field name target type object\n  Field name stillborn type boolean\n  Field name daemon type boolean\n  Field name single_step type boolean\n  Field name eetop type long\n  Field name threadQ type object\n  Field name priority type int\n  Field name name type object\n  Instance Id 0x64610790 number 1 retained size 488\n   Instance Field name uncaughtExceptionHandler type object value 0\n   Instance Field name throwableFromStop type object value 0\n   Instance Field name stopBeforeStart type boolean value false\n   Instance Field name blockerLock type object value 1684080640\n    Ref object java.lang.Object#1\n   Instance Field name blocker type object value 0\n   Instance Field name parkBlocker type object value 0\n   Instance Field name threadStatus type int value 225\n   Instance Field name tid type long value 1\n   Instance Field name nativeParkEventPointer type long value 0\n   Instance Field name stackSize type long value 0\n   Instance Field name inheritableThreadLocals type object value 0\n   Instance Field name threadLocals type object value 1684099328\n    Ref object java.lang.ThreadLocal$ThreadLocalMap#1\n   Instance Field name inheritedAccessControlContext type object value 1684080672\n    Ref object java.security.AccessControlContext#1\n   Instance Field name contextClassLoader type object value 1684178464\n    Ref object sun.misc.Launcher$AppClassLoader#1\n   Instance Field name group type object value 1684080080\n    Ref object java.lang.ThreadGroup#2\n   Instance Field name target type object value 0\n   Instance Field name stillborn type boolean value false\n   Instance Field name daemon type boolean value false\n   Instance Field name single_step type boolean value false\n   Instance Field name eetop type long value 134579200\n   Instance Field name threadQ type object value 0\n   Instance Field name priority type int value 5\n   Instance Field name name type object value 1684080648\n    Ref object char[]#7\n   References count 1\n   Element 0 of array 0x64625860\n   Path to nearest GC root\n  Instance Id 0x64628a88 number 2 retained size 184\n   Instance Field name uncaughtExceptionHandler type object value 0\n   Instance Field name throwableFromStop type object value 0\n   Instance Field name stopBeforeStart type boolean value false\n   Instance Field name blockerLock type object value 1684179704\n    Ref object java.lang.Object#10\n   Instance Field name blocker type object value 0\n   Instance Field name parkBlocker type object value 0\n   Instance Field name threadStatus type int value 5\n   Instance Field name tid type long value 4\n   Instance Field name nativeParkEventPointer type long value 0\n   Instance Field name stackSize type long value 0\n   Instance Field name inheritableThreadLocals type object value 0\n   Instance Field name threadLocals type object value 0\n   Instance Field name inheritedAccessControlContext type object value 1684179760\n    Ref object java.security.AccessControlContext#6\n   Instance Field name contextClassLoader type object value 1684178464\n    Ref object sun.misc.Launcher$AppClassLoader#1\n   Instance Field name group type object value 1684080032\n    Ref object java.lang.ThreadGroup#1\n   Instance Field name target type object value 0\n   Instance Field name stillborn type boolean value false\n   Instance Field name daemon type boolean value true\n   Instance Field name single_step type boolean value false\n   Instance Field name eetop type long value 134821888\n   Instance Field name threadQ type object value 0\n   Instance Field name priority type int value 9\n   Instance Field name name type object value 1684179712\n    Ref object char[]#146\n   References count 1\n   Element 2 of array 0x64610a38\n   Path to nearest GC root\n  Instance Id 0x64628b48 number 3 retained size 0\n   Instance Field name uncaughtExceptionHandler type object value 0\n   Instance Field name throwableFromStop type object value 0\n   Instance Field name stopBeforeStart type boolean value false\n   Instance Field name blockerLock type object value 1684179896\n    Ref object java.lang.Object#11\n   Instance Field name blocker type object value 0\n   Instance Field name parkBlocker type object value 0\n   Instance Field name threadStatus type int value 5\n   Instance Field name tid type long value 5\n   Instance Field name nativeParkEventPointer type long value 0\n   Instance Field name stackSize type long value 0\n   Instance Field name inheritableThreadLocals type object value 0\n   Instance Field name threadLocals type object value 0\n   Instance Field name inheritedAccessControlContext type object value 1684179952\n    Ref object java.security.AccessControlContext#7\n   Instance Field name contextClassLoader type object value 1684178464\n    Ref object sun.misc.Launcher$AppClassLoader#1\n   Instance Field name group type object value 1684080032\n    Ref object java.lang.ThreadGroup#1\n   Instance Field name target type object value 0\n   Instance Field name stillborn type boolean value false\n   Instance Field name daemon type boolean value true\n   Instance Field name single_step type boolean value false\n   Instance Field name eetop type long value 134827008\n   Instance Field name threadQ type object value 0\n   Instance Field name priority type int value 9\n   Instance Field name name type object value 1684179904\n    Ref object char[]#147\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64628c08 number 4 retained size 0\n   Instance Field name uncaughtExceptionHandler type object value 0\n   Instance Field name throwableFromStop type object value 0\n   Instance Field name stopBeforeStart type boolean value false\n   Instance Field name blockerLock type object value 1684180088\n    Ref object java.lang.Object#12\n   Instance Field name blocker type object value 0\n   Instance Field name parkBlocker type object value 0\n   Instance Field name threadStatus type int value 5\n   Instance Field name tid type long value 6\n   Instance Field name nativeParkEventPointer type long value 0\n   Instance Field name stackSize type long value 0\n   Instance Field name inheritableThreadLocals type object value 0\n   Instance Field name threadLocals type object value 0\n   Instance Field name inheritedAccessControlContext type object value 1684180152\n    Ref object java.security.AccessControlContext#8\n   Instance Field name contextClassLoader type object value 1684178464\n    Ref object sun.misc.Launcher$AppClassLoader#1\n   Instance Field name group type object value 1684080032\n    Ref object java.lang.ThreadGroup#1\n   Instance Field name target type object value 0\n   Instance Field name stillborn type boolean value false\n   Instance Field name daemon type boolean value true\n   Instance Field name single_step type boolean value false\n   Instance Field name eetop type long value 134833152\n   Instance Field name threadQ type object value 0\n   Instance Field name priority type int value 9\n   Instance Field name name type object value 1684180096\n    Ref object char[]#148\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64630d78 number 5 retained size 184\n   Instance Field name uncaughtExceptionHandler type object value 0\n   Instance Field name throwableFromStop type object value 0\n   Instance Field name stopBeforeStart type boolean value false\n   Instance Field name blockerLock type object value 1684213296\n    Ref object java.lang.Object#16\n   Instance Field name blocker type object value 0\n   Instance Field name parkBlocker type object value 0\n   Instance Field name threadStatus type int value 5\n   Instance Field name tid type long value 7\n   Instance Field name nativeParkEventPointer type long value 0\n   Instance Field name stackSize type long value 0\n   Instance Field name inheritableThreadLocals type object value 0\n   Instance Field name threadLocals type object value 0\n   Instance Field name inheritedAccessControlContext type object value 1684213352\n    Ref object java.security.AccessControlContext#9\n   Instance Field name contextClassLoader type object value 1684178464\n    Ref object sun.misc.Launcher$AppClassLoader#1\n   Instance Field name group type object value 1684080032\n    Ref object java.lang.ThreadGroup#1\n   Instance Field name target type object value 0\n   Instance Field name stillborn type boolean value false\n   Instance Field name daemon type boolean value true\n   Instance Field name single_step type boolean value false\n   Instance Field name eetop type long value 134855680\n   Instance Field name threadQ type object value 0\n   Instance Field name priority type int value 9\n   Instance Field name name type object value 1684213304\n    Ref object char[]#269\n   References count 1\n   Element 3 of array 0x64610a38\n   Path to nearest GC root\n Id 0x68131c30 Class java.lang.Thread[] SuperClass java.lang.Object Instance size -1 Instance count 2 All Instances Size 64\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610a38 number 1 retained size 32\n   References count 1\n   Field threads of instance 0x646105a0\n   Path to nearest GC root\n    Next object java.lang.ThreadGroup#1\n    Next object java.lang.ref.Finalizer$FinalizerThread#1\n  Instance Id 0x64625860 number 2 retained size 32\n   References count 1\n   Field threads of instance 0x646105d0\n   Path to nearest GC root\n    Next object java.lang.ThreadGroup#2\n    Next object java.lang.Thread#1\n Id 0x6c939d30 Class java.lang.Cloneable SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9399c0 Class java.lang.String SuperClass java.lang.Object Instance size 24 Instance count 295 All Instances Size 7080\n  Static Field name CASE_INSENSITIVE_ORDER type object value 1684080024\n   Ref object java.lang.String$CaseInsensitiveComparator#1\n  Static Field name serialPersistentFields type object value 1684080008\n   Ref object java.io.ObjectStreamField[]#1\n  Static Field name serialVersionUID type long value -6849794470754667710\n  Static Field name <classLoader> type object value 0\n  Field name hash type int\n  Field name count type int\n  Field name offset type int\n  Field name value type object\n  Instance Id 0x64610000 number 1 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684078616\n    Ref object char[]#1\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610048 number 2 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 13\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684078688\n    Ref object char[]#2\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610088 number 3 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 37\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684078752\n    Ref object char[]#3\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x646100f8 number 4 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 26\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684078864\n    Ref object char[]#4\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610150 number 5 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 9\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684078952\n    Ref object char[]#5\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610600 number 6 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 4\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684080152\n    Ref object char[]#6\n   References count 1\n   Field name of instance 0x646105d0\n   Path to nearest GC root\n    Next object java.lang.ThreadGroup#2\n    Next object java.lang.Thread#1\n  Instance Id 0x64610ba0 number 7 retained size 88\n   Instance Field name hash type int value -333068255\n   Instance Field name count type int value 26\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684081592\n    Ref object char[]#11\n   References count 1\n   Field key of instance 0x64610c28\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#1\n    Next object java.util.Hashtable$Entry#17\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610bf8 number 8 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 3\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684081680\n    Ref object char[]#12\n   References count 1\n   Field value of instance 0x64610c28\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#1\n    Next object java.util.Hashtable$Entry#17\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610c40 number 9 retained size 88\n   Instance Field name hash type int value -2704414\n   Instance Field name count type int value 23\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684081752\n    Ref object char[]#13\n   References count 1\n   Field key of instance 0x64610d00\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#2\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610c98 number 10 retained size 104\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 31\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684081840\n    Ref object char[]#14\n   References count 1\n   Field value of instance 0x64610d00\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#2\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610d18 number 11 retained size 88\n   Instance Field name hash type int value 1928785119\n   Instance Field name count type int value 25\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684081968\n    Ref object char[]#15\n   References count 1\n   Field key of instance 0x64610dc0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#3\n    Next object java.util.Hashtable$Entry#15\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610d70 number 12 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 21\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684082056\n    Ref object char[]#16\n   References count 1\n   Field value of instance 0x64610dc0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#3\n    Next object java.util.Hashtable$Entry#15\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610dd8 number 13 retained size 64\n   Instance Field name hash type int value 560567564\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684082160\n    Ref object char[]#17\n   References count 1\n   Field key of instance 0x64610e18\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#4\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610e30 number 14 retained size 64\n   Instance Field name hash type int value 987780756\n   Instance Field name count type int value 11\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684082248\n    Ref object char[]#18\n   References count 1\n   Field key of instance 0x64610ec0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#5\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610e70 number 15 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 21\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684082312\n    Ref object char[]#19\n   References count 1\n   Field value of instance 0x64610ec0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#5\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610ed8 number 16 retained size 72\n   Instance Field name hash type int value -1895720171\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684082416\n    Ref object char[]#20\n   References count 1\n   Field key of instance 0x64610f70\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#6\n    Next object java.util.Hashtable$Entry#37\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610f20 number 17 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 20\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684082488\n    Ref object char[]#21\n   References count 1\n   Field value of instance 0x64610f70\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#6\n    Next object java.util.Hashtable$Entry#37\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610f88 number 18 retained size 80\n   Instance Field name hash type int value -1342541797\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684082592\n    Ref object char[]#22\n   References count 1\n   Field key of instance 0x64611050\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#7\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610fd8 number 19 retained size 120\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 41\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684082672\n    Ref object char[]#23\n   References count 1\n   Field value of instance 0x64611050\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#7\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611068 number 20 retained size 72\n   Instance Field name hash type int value -1922408554\n   Instance Field name count type int value 18\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684082816\n    Ref object char[]#24\n   References count 1\n   Field key of instance 0x646110e0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#8\n    Next object java.util.Hashtable$Entry#2\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646110b0 number 21 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 4\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684082888\n    Ref object char[]#25\n   References count 1\n   Field value of instance 0x646110e0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#8\n    Next object java.util.Hashtable$Entry#2\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646110f8 number 22 retained size 56\n   Instance Field name hash type int value -1228098475\n   Instance Field name count type int value 7\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684082960\n    Ref object char[]#26\n   References count 1\n   Field key of instance 0x64611160\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#9\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611130 number 23 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 5\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083016\n    Ref object char[]#27\n   References count 1\n   Field value of instance 0x64611160\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#9\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611178 number 24 retained size 56\n   Instance Field name hash type int value 1174476494\n   Instance Field name count type int value 10\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083088\n    Ref object char[]#28\n   References count 1\n   Field key of instance 0x646111f8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#10\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646111b0 number 25 retained size 72\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 17\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083144\n    Ref object char[]#29\n   References count 1\n   Field value of instance 0x646111f8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#10\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611210 number 26 retained size 56\n   Instance Field name hash type int value -1228469728\n   Instance Field name count type int value 7\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083240\n    Ref object char[]#30\n   References count 1\n   Field key of instance 0x64611278\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#11\n    Next object java.util.Hashtable$Entry#40\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611248 number 27 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 4\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083296\n    Ref object char[]#31\n   References count 1\n   Field value of instance 0x64611278\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#11\n    Next object java.util.Hashtable$Entry#40\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611290 number 28 retained size 64\n   Instance Field name hash type int value 465797363\n   Instance Field name count type int value 14\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083368\n    Ref object char[]#32\n   References count 1\n   Field key of instance 0x646112f8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#12\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646112d0 number 29 retained size 40\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 1\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083432\n    Ref object char[]#33\n   References count 1\n   Field value of instance 0x646112f8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#12\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611310 number 30 retained size 64\n   Instance Field name hash type int value 1989177436\n   Instance Field name count type int value 14\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083496\n    Ref object char[]#34\n   References count 1\n   Field key of instance 0x64611378\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#13\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611350 number 31 retained size 40\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 1\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083560\n    Ref object char[]#35\n   References count 1\n   Field value of instance 0x64611378\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#13\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611390 number 32 retained size 64\n   Instance Field name hash type int value 1985578347\n   Instance Field name count type int value 14\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083624\n    Ref object char[]#36\n   References count 1\n   Field key of instance 0x646113f8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#14\n    Next object java.util.Hashtable$Entry#27\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646113d0 number 33 retained size 40\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 1\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083688\n    Ref object char[]#37\n   References count 3\n   Field lineSeparator of instance 0x64616c78\n   Field lineSeparator of instance 0x64616aa0\n   Field value of instance 0x646113f8\n   Path to nearest GC root\n    Next object java.io.BufferedWriter#2\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n  Instance Id 0x64611410 number 34 retained size 64\n   Instance Field name hash type int value 1102884379\n   Instance Field name count type int value 13\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083752\n    Ref object char[]#38\n   References count 1\n   Field key of instance 0x64611478\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#15\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611450 number 35 retained size 40\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 2\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083816\n    Ref object char[]#39\n   References count 1\n   Field value of instance 0x64611478\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#15\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611490 number 36 retained size 64\n   Instance Field name hash type int value -1309845389\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083880\n    Ref object char[]#40\n   References count 1\n   Field key of instance 0x646114f8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#16\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646114d0 number 37 retained size 40\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 2\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684083944\n    Ref object char[]#41\n   References count 1\n   Field value of instance 0x646114f8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#16\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611510 number 38 retained size 64\n   Instance Field name hash type int value 1808897413\n   Instance Field name count type int value 13\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084008\n    Ref object char[]#42\n   References count 1\n   Field key of instance 0x64611588\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#17\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611550 number 39 retained size 56\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 10\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084072\n    Ref object char[]#43\n   References count 1\n   Field value of instance 0x64611588\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#17\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646115a0 number 40 retained size 72\n   Instance Field name hash type int value 676668242\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084152\n    Ref object char[]#44\n   References count 1\n   Field key of instance 0x64611620\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#18\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646115e8 number 41 retained size 56\n   Instance Field name hash type int value 2027158704\n   Instance Field name count type int value 10\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084224\n    Ref object char[]#45\n   References count 3\n   Field value of instance 0x64611620\n   Element 0 of array 0x646150b0\n   Field requestedCharsetName of instance 0x64625090\n   Path to nearest GC root\n  Instance Id 0x64611638 number 42 retained size 72\n   Instance Field name hash type int value 1449649635\n   Instance Field name count type int value 17\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084304\n    Ref object char[]#46\n   References count 1\n   Field key of instance 0x646116b0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#19\n    Next object java.util.Hashtable$Entry#36\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611680 number 43 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 6\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084376\n    Ref object char[]#47\n   References count 1\n   Field value of instance 0x646116b0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#19\n    Next object java.util.Hashtable$Entry#36\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646116c8 number 44 retained size 88\n   Instance Field name hash type int value 1813232234\n   Instance Field name count type int value 23\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084448\n    Ref object char[]#48\n   References count 1\n   Field key of instance 0x64611760\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#20\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611720 number 45 retained size 64\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 13\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084536\n    Ref object char[]#49\n   References count 1\n   Field value of instance 0x64611760\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#20\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611778 number 46 retained size 72\n   Instance Field name hash type int value -726990163\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084624\n    Ref object char[]#50\n   References count 1\n   Field key of instance 0x646117e8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#21\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646117c0 number 47 retained size 40\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 0\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084696\n    Ref object char[]#51\n   References count 1\n   Field value of instance 0x646117e8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#21\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611800 number 48 retained size 64\n   Instance Field name hash type int value -1943614589\n   Instance Field name count type int value 14\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084760\n    Ref object char[]#52\n   References count 1\n   Field key of instance 0x64611870\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#22\n    Next object java.util.Hashtable$Entry#20\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611840 number 49 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 6\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084824\n    Ref object char[]#53\n   References count 1\n   Field value of instance 0x64611870\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#22\n    Next object java.util.Hashtable$Entry#20\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611888 number 50 retained size 80\n   Instance Field name hash type int value 703906719\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084896\n    Ref object char[]#54\n   References count 1\n   Field key of instance 0x64611928\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#23\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646118d8 number 51 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 22\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684084976\n    Ref object char[]#55\n   References count 1\n   Field value of instance 0x64611928\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#23\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611940 number 52 retained size 80\n   Instance Field name hash type int value 919949531\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684085080\n    Ref object char[]#56\n   References count 1\n   Field key of instance 0x646119b8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#24\n    Next object java.util.Hashtable$Entry#43\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611990 number 53 retained size 40\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 2\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684085160\n    Ref object char[]#57\n   References count 1\n   Field value of instance 0x646119b8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#24\n    Next object java.util.Hashtable$Entry#43\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646119d0 number 54 retained size 72\n   Instance Field name hash type int value -1806116554\n   Instance Field name count type int value 18\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684085224\n    Ref object char[]#58\n   References count 1\n   Field key of instance 0x64611a50\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#25\n    Next object java.util.Hashtable$Entry#16\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611a18 number 55 retained size 56\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 7\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684085296\n    Ref object char[]#59\n   References count 1\n   Field value of instance 0x64611a50\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#25\n    Next object java.util.Hashtable$Entry#16\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611a68 number 56 retained size 80\n   Instance Field name hash type int value -1854834746\n   Instance Field name count type int value 20\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684085376\n    Ref object char[]#60\n   References count 1\n   Field key of instance 0x64611b18\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#26\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611ab8 number 57 retained size 96\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 30\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684085456\n    Ref object char[]#61\n   References count 1\n   Field value of instance 0x64611b18\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#26\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646150c8 number 58 retained size 64\n   Instance Field name hash type int value -378505966\n   Instance Field name count type int value 14\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684099544\n    Ref object char[]#62\n   References count 1\n   Field key of instance 0x646152b0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#27\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615280 number 59 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 4\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684099736\n    Ref object char[]#63\n   References count 1\n   Field value of instance 0x646152b0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#27\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646152c8 number 60 retained size 56\n   Instance Field name hash type int value 294088398\n   Instance Field name count type int value 9\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684099808\n    Ref object char[]#64\n   References count 1\n   Field key of instance 0x64615338\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#28\n    Next object java.util.Hashtable$Entry#44\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615300 number 61 retained size 56\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 8\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684099864\n    Ref object char[]#65\n   References count 1\n   Field value of instance 0x64615338\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#28\n    Next object java.util.Hashtable$Entry#44\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615350 number 62 retained size 56\n   Instance Field name hash type int value 293923106\n   Instance Field name count type int value 9\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684099944\n    Ref object char[]#66\n   References count 1\n   Field key of instance 0x646153c8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#29\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615388 number 63 retained size 64\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 14\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684100000\n    Ref object char[]#67\n   References count 1\n   Field value of instance 0x646153c8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#29\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646153e0 number 64 retained size 64\n   Instance Field name hash type int value 640246460\n   Instance Field name count type int value 13\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684100088\n    Ref object char[]#68\n   References count 1\n   Field key of instance 0x64615448\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#30\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615420 number 65 retained size 40\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 0\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684100152\n    Ref object char[]#69\n   References count 1\n   Field value of instance 0x64615448\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#30\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615460 number 66 retained size 56\n   Instance Field name hash type int value -267617302\n   Instance Field name count type int value 8\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684100216\n    Ref object char[]#70\n   References count 1\n   Field key of instance 0x646154c8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#31\n    Next object java.util.Hashtable$Entry#33\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615498 number 67 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 4\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684100272\n    Ref object char[]#71\n   References count 1\n   Field value of instance 0x646154c8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#31\n    Next object java.util.Hashtable$Entry#33\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646154e0 number 68 retained size 96\n   Instance Field name hash type int value -975448766\n   Instance Field name count type int value 29\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684100344\n    Ref object char[]#72\n   References count 1\n   Field key of instance 0x64615570\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#32\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615540 number 69 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 3\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684100440\n    Ref object char[]#73\n   References count 1\n   Field value of instance 0x64615570\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#32\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615588 number 70 retained size 88\n   Instance Field name hash type int value 1980476001\n   Instance Field name count type int value 26\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684100512\n    Ref object char[]#74\n   References count 1\n   Field key of instance 0x64615648\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#33\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646155e0 number 71 retained size 104\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 34\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684100600\n    Ref object char[]#75\n   References count 1\n   Field value of instance 0x64615648\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#33\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615660 number 72 retained size 96\n   Instance Field name hash type int value 799684510\n   Instance Field name count type int value 28\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684100728\n    Ref object char[]#76\n   References count 1\n   Field key of instance 0x64615710\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#34\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646156c0 number 73 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 21\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684100824\n    Ref object char[]#77\n   References count 1\n   Field value of instance 0x64615710\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#34\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615728 number 74 retained size 72\n   Instance Field name hash type int value -535248915\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684100928\n    Ref object char[]#78\n   References count 1\n   Field key of instance 0x646157b0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#35\n    Next object java.util.Hashtable$Entry#41\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615770 number 75 retained size 64\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684101000\n    Ref object char[]#79\n   References count 1\n   Field value of instance 0x646157b0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#35\n    Next object java.util.Hashtable$Entry#41\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646157c8 number 76 retained size 64\n   Instance Field name hash type int value 726644630\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684101088\n    Ref object char[]#80\n   References count 1\n   Field key of instance 0x646159e8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#36\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615808 number 77 retained size 88\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 26\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684101152\n    Ref object char[]#81\n   References count 1\n   Field value of instance 0x646159e8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#36\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615a00 number 78 retained size 64\n   Instance Field name hash type int value -1541420141\n   Instance Field name count type int value 14\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684101656\n    Ref object char[]#82\n   References count 1\n   Field key of instance 0x64615a90\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#37\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615a40 number 79 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 21\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684101720\n    Ref object char[]#83\n   References count 1\n   Field value of instance 0x64615a90\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#37\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615aa8 number 80 retained size 64\n   Instance Field name hash type int value 726507961\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684101824\n    Ref object char[]#84\n   References count 1\n   Field key of instance 0x64615ae8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#38\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615b00 number 81 retained size 64\n   Instance Field name hash type int value 310802303\n   Instance Field name count type int value 13\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684101912\n    Ref object char[]#85\n   References count 1\n   Field key of instance 0x64615bd8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#39\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615b40 number 82 retained size 24\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 57\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684101976\n    Ref object char[]#86\n   References count 1\n   Field value of instance 0x64615bd8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#39\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615bf0 number 83 retained size 72\n   Instance Field name hash type int value 1241832660\n   Instance Field name count type int value 18\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684102152\n    Ref object char[]#87\n   References count 1\n   Field key of instance 0x64615ca8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#40\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615c38 number 84 retained size 112\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 35\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684102224\n    Ref object char[]#88\n   References count 1\n   Field value of instance 0x64615ca8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#40\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615cc0 number 85 retained size 80\n   Instance Field name hash type int value -1477254190\n   Instance Field name count type int value 21\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684102360\n    Ref object char[]#89\n   References count 1\n   Field key of instance 0x64615d78\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#41\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615d10 number 86 retained size 104\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 31\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684102440\n    Ref object char[]#90\n   References count 2\n   Element 0 of array 0x64624fc8\n   Field value of instance 0x64615d78\n   Path to nearest GC root\n    Next object java.lang.String[]#43\n    Next object java.lang.Class#101\n  Instance Id 0x64615d90 number 87 retained size 72\n   Instance Field name hash type int value 1370996164\n   Instance Field name count type int value 17\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684102568\n    Ref object char[]#91\n   References count 1\n   Field key of instance 0x64615f28\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#42\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615dd8 number 88 retained size 24\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 147\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684102640\n    Ref object char[]#92\n   References count 1\n   Field value of instance 0x64615f28\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#42\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615f40 number 89 retained size 56\n   Instance Field name hash type int value -888764117\n   Instance Field name count type int value 9\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684103000\n    Ref object char[]#93\n   References count 1\n   Field key of instance 0x64615fc8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#43\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615f78 number 90 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 22\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684103056\n    Ref object char[]#94\n   References count 3\n   Field javaHome of Class java.util.jar.JarFile\n   Field javaHome of instance 0x64616ca8\n   Field value of instance 0x64615fc8\n   Path to nearest GC root\n    Next object java.lang.Class#184\n  Instance Id 0x64615fe0 number 91 retained size 72\n   Instance Field name hash type int value 1370376743\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684103160\n    Ref object char[]#95\n   References count 1\n   Field key of instance 0x64616068\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#44\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616028 number 92 retained size 64\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 11\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684103232\n    Ref object char[]#96\n   References count 1\n   Field value of instance 0x64616068\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#44\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616080 number 93 retained size 80\n   Instance Field name hash type int value 1425513397\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684103320\n    Ref object char[]#97\n   References count 1\n   Field key of instance 0x646162f8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#45\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646160d0 number 94 retained size 552\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 258\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684103400\n    Ref object char[]#98\n   References count 1\n   Field value of instance 0x646162f8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#45\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616310 number 95 retained size 72\n   Instance Field name hash type int value -1269521974\n   Instance Field name count type int value 17\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684103976\n    Ref object char[]#99\n   References count 1\n   Field key of instance 0x64616398\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616358 number 96 retained size 64\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684104048\n    Ref object char[]#100\n   References count 1\n   Field value of instance 0x64616398\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646163b0 number 97 retained size 88\n   Instance Field name hash type int value 218965832\n   Instance Field name count type int value 23\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684104136\n    Ref object char[]#101\n   References count 1\n   Field key of instance 0x64616460\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#47\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616408 number 98 retained size 88\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 23\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684104224\n    Ref object char[]#102\n   References count 1\n   Field value of instance 0x64616460\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#47\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616698 number 99 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 90\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684104880\n    Ref object char[]#103\n   References count 1\n   Field signature of instance 0x64616650\n   Path to nearest GC root\n    Null\n  Instance Id 0x64616e60 number 100 retained size 40\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 1\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684106872\n    Ref object char[]#104\n   References count 1\n   Field separator of Class java.io.File\n   Path to nearest GC root\n    Next object java.lang.Class#270\n  Instance Id 0x64616e88 number 101 retained size 40\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 1\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684106912\n    Ref object char[]#105\n   References count 1\n   Field pathSeparator of Class java.io.File\n   Path to nearest GC root\n    Next object java.lang.Class#270\n  Instance Id 0x64624f38 number 102 retained size 24\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 38\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684102640\n    Ref object char[]#92\n   References count 1\n   Element 0 of array 0x64624f10\n   Path to nearest GC root\n    Next object java.lang.String[]#42\n    Next object java.lang.Class#101\n  Instance Id 0x64624f50 number 103 retained size 24\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 31\n   Instance Field name offset type int value 39\n   Instance Field name value type object value 1684102640\n    Ref object char[]#92\n   References count 1\n   Element 1 of array 0x64624f10\n   Path to nearest GC root\n    Next object java.lang.String[]#42\n    Next object java.lang.Class#101\n  Instance Id 0x64624f68 number 104 retained size 24\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 34\n   Instance Field name offset type int value 71\n   Instance Field name value type object value 1684102640\n    Ref object char[]#92\n   References count 1\n   Element 2 of array 0x64624f10\n   Path to nearest GC root\n    Next object java.lang.String[]#42\n    Next object java.lang.Class#101\n  Instance Id 0x64624f80 number 105 retained size 24\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 27\n   Instance Field name offset type int value 106\n   Instance Field name value type object value 1684102640\n    Ref object char[]#92\n   References count 1\n   Element 3 of array 0x64624f10\n   Path to nearest GC root\n    Next object java.lang.String[]#42\n    Next object java.lang.Class#101\n  Instance Id 0x64624f98 number 106 retained size 24\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 4\n   Instance Field name offset type int value 134\n   Instance Field name value type object value 1684102640\n    Ref object char[]#92\n   References count 1\n   Element 4 of array 0x64624f10\n   Path to nearest GC root\n    Next object java.lang.String[]#42\n    Next object java.lang.Class#101\n  Instance Id 0x64624fb0 number 107 retained size 24\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 8\n   Instance Field name offset type int value 139\n   Instance Field name value type object value 1684102640\n    Ref object char[]#92\n   References count 1\n   Element 5 of array 0x64624f10\n   Path to nearest GC root\n    Next object java.lang.String[]#42\n    Next object java.lang.Class#101\n  Instance Id 0x64624fd8 number 108 retained size 24\n   Instance Field name hash type int value 394871365\n   Instance Field name count type int value 41\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684164592\n    Ref object char[]#108\n   References count 1\n   Field key of instance 0x64625208\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#3\n    Next object java.util.LinkedHashMap$Entry#1\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64625160 number 109 retained size 24\n   Instance Field name hash type int value 893869574\n   Instance Field name count type int value 31\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684164592\n    Ref object char[]#108\n   References count 1\n   Field key of instance 0x64625258\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#4\n    Next object java.util.LinkedHashMap$Entry#2\n    Next object java.io.ExpiringCache$1#2\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64625178 number 110 retained size 24\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 41\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684165008\n    Ref object char[]#109\n   References count 3\n   Element 0 of array 0x64610868\n   Field val of instance 0x646251f0\n   Field name of instance 0x64625278\n   Path to nearest GC root\n    Next object java.lang.Object[]#9\n    Next object java.util.Vector#1\n    Next object java.lang.Class#101\n  Instance Id 0x64625228 number 111 retained size 24\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 31\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684165008\n    Ref object char[]#109\n   References count 1\n   Field val of instance 0x64625240\n   Path to nearest GC root\n    Next object java.io.ExpiringCache$Entry#2\n    Next object java.util.LinkedHashMap$Entry#4\n    Next object java.util.LinkedHashMap$Entry#2\n    Next object java.io.ExpiringCache$1#2\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64625888 number 112 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684166816\n    Ref object char[]#113\n   References count 1\n   Field value of instance 0x64615ae8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#38\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64625950 number 113 retained size 24\n   Instance Field name hash type int value -663903805\n   Instance Field name count type int value 30\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684101976\n    Ref object char[]#86\n   References count 2\n   Field path of instance 0x64625940\n   Field key of instance 0x64625ac0\n   Path to nearest GC root\n    Next object java.io.File#1\n    Next object java.io.File[]#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64625978 number 114 retained size 24\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 26\n   Instance Field name offset type int value 31\n   Instance Field name value type object value 1684101976\n    Ref object char[]#86\n   References count 1\n   Field path of instance 0x64625968\n   Path to nearest GC root\n    Next object java.io.File#2\n    Next object java.io.File[]#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64625a48 number 115 retained size 96\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 30\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684167264\n    Ref object char[]#115\n   References count 1\n   Field val of instance 0x64625aa8\n   Path to nearest GC root\n    Next object java.io.ExpiringCache$Entry#3\n    Next object java.util.LinkedHashMap$Entry#5\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64625ae0 number 116 retained size 168\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 63\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684167416\n    Ref object char[]#116\n   References count 1\n   Element 0 of array 0x64625c58\n   Path to nearest GC root\n    Next object java.lang.String[]#44\n    Next object sun.misc.MetaIndex#1\n    Next object java.util.HashMap$Entry#1\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625b88 number 117 retained size 56\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 7\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684167584\n    Ref object char[]#117\n   References count 1\n   Element 1 of array 0x64625c58\n   Path to nearest GC root\n    Next object java.lang.String[]#44\n    Next object sun.misc.MetaIndex#1\n    Next object java.util.HashMap$Entry#1\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625bd0 number 118 retained size 120\n   Instance Field name hash type int value 525449103\n   Instance Field name count type int value 40\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684167656\n    Ref object char[]#118\n   References count 1\n   Field path of instance 0x64625bc0\n   Path to nearest GC root\n    Next object java.io.File#3\n    Next object java.util.HashMap$Entry#1\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625c88 number 119 retained size 56\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 8\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684167840\n    Ref object char[]#119\n   References count 1\n   Element 0 of array 0x64625d98\n   Path to nearest GC root\n    Next object java.lang.String[]#45\n    Next object sun.misc.MetaIndex#2\n    Next object java.util.HashMap$Entry#2\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625cc0 number 120 retained size 56\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 8\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684167896\n    Ref object char[]#120\n   References count 1\n   Element 1 of array 0x64625d98\n   Path to nearest GC root\n    Next object java.lang.String[]#45\n    Next object sun.misc.MetaIndex#2\n    Next object java.util.HashMap$Entry#2\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625d08 number 121 retained size 128\n   Instance Field name hash type int value -1087806467\n   Instance Field name count type int value 45\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684167968\n    Ref object char[]#121\n   References count 1\n   Field path of instance 0x64625cf8\n   Path to nearest GC root\n    Next object java.io.File#4\n    Next object java.util.HashMap$Entry#2\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625dc8 number 122 retained size 72\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684168160\n    Ref object char[]#122\n   References count 1\n   Element 0 of array 0x64625f58\n   Path to nearest GC root\n    Next object java.lang.String[]#46\n    Next object sun.misc.MetaIndex#3\n    Next object java.util.HashMap$Entry#3\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625e10 number 123 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 20\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684168232\n    Ref object char[]#123\n   References count 1\n   Element 1 of array 0x64625f58\n   Path to nearest GC root\n    Next object java.lang.String[]#46\n    Next object sun.misc.MetaIndex#3\n    Next object java.util.HashMap$Entry#3\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625e60 number 124 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684168312\n    Ref object char[]#124\n   References count 1\n   Element 2 of array 0x64625f58\n   Path to nearest GC root\n    Next object java.lang.String[]#46\n    Next object sun.misc.MetaIndex#3\n    Next object java.util.HashMap$Entry#3\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625ec0 number 125 retained size 136\n   Instance Field name hash type int value 1091844017\n   Instance Field name count type int value 50\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684168408\n    Ref object char[]#125\n   References count 1\n   Field path of instance 0x64625eb0\n   Path to nearest GC root\n    Next object java.io.File#5\n    Next object java.util.HashMap$Entry#3\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625f88 number 126 retained size 64\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684168608\n    Ref object char[]#126\n   References count 1\n   Element 0 of array 0x64626108\n   Path to nearest GC root\n    Next object java.lang.String[]#47\n    Next object sun.misc.MetaIndex#4\n    Next object java.util.HashMap$Entry#4\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625fc8 number 127 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 20\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684168672\n    Ref object char[]#127\n   References count 1\n   Element 1 of array 0x64626108\n   Path to nearest GC root\n    Next object java.lang.String[]#47\n    Next object sun.misc.MetaIndex#4\n    Next object java.util.HashMap$Entry#4\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64626018 number 128 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684168752\n    Ref object char[]#128\n   References count 1\n   Element 2 of array 0x64626108\n   Path to nearest GC root\n    Next object java.lang.String[]#47\n    Next object sun.misc.MetaIndex#4\n    Next object java.util.HashMap$Entry#4\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64626078 number 129 retained size 128\n   Instance Field name hash type int value -1085376328\n   Instance Field name count type int value 44\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684168848\n    Ref object char[]#129\n   References count 1\n   Field path of instance 0x64626068\n   Path to nearest GC root\n    Next object java.io.File#6\n    Next object java.util.HashMap$Entry#4\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64626180 number 130 retained size 24\n   Instance Field name hash type int value 1091844017\n   Instance Field name count type int value 50\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684169112\n    Ref object char[]#130\n   References count 1\n   Field key of instance 0x646262c0\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#6\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64626208 number 131 retained size 24\n   Instance Field name hash type int value -663903805\n   Instance Field name count type int value 30\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684169112\n    Ref object char[]#130\n   References count 1\n   Field key of instance 0x64626310\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#7\n    Next object java.util.LinkedHashMap$Entry#2\n    Next object java.io.ExpiringCache$1#2\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64626220 number 132 retained size 24\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 50\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684169272\n    Ref object char[]#131\n   References count 1\n   Field val of instance 0x646262a8\n   Path to nearest GC root\n    Next object java.io.ExpiringCache$Entry#4\n    Next object java.util.LinkedHashMap$Entry#6\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x646262e0 number 133 retained size 24\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 30\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684169272\n    Ref object char[]#131\n   References count 1\n   Field val of instance 0x646262f8\n   Path to nearest GC root\n    Next object java.io.ExpiringCache$Entry#5\n    Next object java.util.LinkedHashMap$Entry#7\n    Next object java.util.LinkedHashMap$Entry#2\n    Next object java.io.ExpiringCache$1#2\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x646263b8 number 134 retained size 136\n   Instance Field name hash type int value 1091844017\n   Instance Field name count type int value 50\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684169680\n    Ref object char[]#132\n   References count 2\n   Field path of instance 0x646264a8\n   Field file of instance 0x646264a8\n   Path to nearest GC root\n    Next object java.net.URL#1\n    Next object java.lang.Object[]#304\n    Next object java.util.ArrayList#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64627a10 number 135 retained size 128\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 44\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684175400\n    Ref object char[]#134\n   References count 1\n   Field val of instance 0x64627b10\n   Path to nearest GC root\n    Next object java.io.ExpiringCache$Entry#6\n    Next object java.util.LinkedHashMap$Entry#8\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627a90 number 136 retained size 128\n   Instance Field name hash type int value -1085376328\n   Instance Field name count type int value 44\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684175528\n    Ref object char[]#135\n   References count 1\n   Field key of instance 0x64627b28\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#8\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627b48 number 137 retained size 128\n   Instance Field name hash type int value -1085376328\n   Instance Field name count type int value 44\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684175712\n    Ref object char[]#136\n   References count 2\n   Field path of instance 0x64627bc8\n   Field file of instance 0x64627bc8\n   Path to nearest GC root\n    Next object java.net.URL#2\n    Next object java.lang.Object[]#304\n    Next object java.util.ArrayList#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64627c00 number 138 retained size 120\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 40\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684175896\n    Ref object char[]#137\n   References count 1\n   Field val of instance 0x64627cf0\n   Path to nearest GC root\n    Next object java.io.ExpiringCache$Entry#7\n    Next object java.util.LinkedHashMap$Entry#9\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627c78 number 139 retained size 120\n   Instance Field name hash type int value 525449103\n   Instance Field name count type int value 40\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684176016\n    Ref object char[]#138\n   References count 1\n   Field key of instance 0x64627d08\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#9\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627d28 number 140 retained size 120\n   Instance Field name hash type int value 525449103\n   Instance Field name count type int value 40\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684176192\n    Ref object char[]#139\n   References count 2\n   Field path of instance 0x64627da0\n   Field file of instance 0x64627da0\n   Path to nearest GC root\n    Next object java.net.URL#3\n    Next object java.lang.Object[]#304\n    Next object java.util.ArrayList#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64627dd8 number 141 retained size 128\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 45\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684176368\n    Ref object char[]#140\n   References count 1\n   Field val of instance 0x64627ed8\n   Path to nearest GC root\n    Next object java.io.ExpiringCache$Entry#8\n    Next object java.util.LinkedHashMap$Entry#10\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627e58 number 142 retained size 128\n   Instance Field name hash type int value -1087806467\n   Instance Field name count type int value 45\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684176496\n    Ref object char[]#141\n   References count 1\n   Field key of instance 0x64627ef0\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#10\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627f10 number 143 retained size 128\n   Instance Field name hash type int value -1087806467\n   Instance Field name count type int value 45\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684176680\n    Ref object char[]#142\n   References count 2\n   Field path of instance 0x64627f90\n   Field file of instance 0x64627f90\n   Path to nearest GC root\n    Next object java.net.URL#4\n    Next object java.lang.Object[]#304\n    Next object java.util.ArrayList#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646284d8 number 144 retained size 72\n   Instance Field name hash type int value 741476021\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684178160\n    Ref object char[]#143\n   References count 1\n   Field key of instance 0x64628580\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#11\n    Next object java.util.LinkedHashMap$Entry#1\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64628520 number 145 retained size 72\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684178232\n    Ref object char[]#144\n   References count 2\n   Field val of instance 0x64628568\n   Field cpath of instance 0x64630968\n   Path to nearest GC root\n    Next object java.io.ExpiringCache$Entry#9\n    Next object java.util.LinkedHashMap$Entry#11\n    Next object java.util.LinkedHashMap$Entry#1\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x646285a0 number 146 retained size 72\n   Instance Field name hash type int value 741476021\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684178360\n    Ref object char[]#145\n   References count 2\n   Field path of instance 0x646285e8\n   Field file of instance 0x646285e8\n   Path to nearest GC root\n    Next object java.net.URL#5\n    Next object java.lang.Object[]#309\n    Next object java.util.ArrayList#4\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628f40 number 147 retained size 0\n   Instance Field name hash type int value 676668242\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684180824\n    Ref object char[]#150\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64628f88 number 148 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 11\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684180896\n    Ref object char[]#151\n   References count 1\n   Field name of instance 0x64628fc8\n   Path to nearest GC root\n    Null\n  Instance Id 0x646292a8 number 149 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 3\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684181976\n    Ref object char[]#152\n   References count 1\n   Field value of instance 0x64629518\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629530 number 150 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684182344\n    Ref object char[]#153\n   References count 1\n   Field value of instance 0x64629588\n   Path to nearest GC root\n    Null\n  Instance Id 0x646295a0 number 151 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 36\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684182456\n    Ref object char[]#154\n   References count 1\n   Field value of instance 0x64629620\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629638 number 152 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684182608\n    Ref object char[]#155\n   References count 1\n   Field value of instance 0x64629688\n   Path to nearest GC root\n    Null\n  Instance Id 0x646296a0 number 153 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 0\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684182712\n    Ref object char[]#156\n   References count 1\n   Field value of instance 0x646296d8\n   Path to nearest GC root\n    Null\n  Instance Id 0x646296f0 number 154 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 47\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684182792\n    Ref object char[]#157\n   References count 1\n   Field value of instance 0x64629788\n   Path to nearest GC root\n    Null\n  Instance Id 0x646299a0 number 155 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 10\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684183480\n    Ref object char[]#158\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629ad8 number 156 retained size 152\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 57\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684183792\n    Ref object char[]#160\n   References count 2\n   Field path of instance 0x64629a28\n   Field file of instance 0x64629a28\n   Path to nearest GC root\n    Next object java.net.URL#6\n    Next object sun.misc.URLClassPath$JarLoader#1\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629be8 number 157 retained size 144\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 51\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684184064\n    Ref object char[]#161\n   References count 2\n   Field path of instance 0x64629bb0\n   Field file of instance 0x64629bb0\n   Path to nearest GC root\n    Next object java.net.URL#7\n    Next object sun.misc.URLClassPath$JarLoader#2\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629cf0 number 158 retained size 136\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 47\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684184328\n    Ref object char[]#162\n   References count 2\n   Field path of instance 0x64629cb8\n   Field file of instance 0x64629cb8\n   Path to nearest GC root\n    Next object java.net.URL#8\n    Next object sun.misc.URLClassPath$JarLoader#3\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629df0 number 159 retained size 144\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 52\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684184584\n    Ref object char[]#163\n   References count 2\n   Field path of instance 0x64629db8\n   Field file of instance 0x64629db8\n   Path to nearest GC root\n    Next object java.net.URL#9\n    Next object sun.misc.URLClassPath$JarLoader#4\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629ef8 number 160 retained size 88\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 23\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684184848\n    Ref object char[]#164\n   References count 2\n   Field path of instance 0x64629ec0\n   Field file of instance 0x64629ec0\n   Path to nearest GC root\n    Next object java.net.URL#10\n    Next object sun.misc.URLClassPath$JarLoader#5\n    Next object java.lang.Object[]#311\n    Next object java.util.ArrayList#5\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629f50 number 161 retained size 72\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684184936\n    Ref object char[]#165\n   References count 1\n   Field name of instance 0x64629f98\n   Path to nearest GC root\n    Next object java.util.jar.JarFile#2\n    Next object sun.misc.URLClassPath$JarLoader#5\n    Next object java.lang.Object[]#311\n    Next object java.util.ArrayList#5\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x6462a070 number 162 retained size 56\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 7\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684185224\n    Ref object char[]#166\n   References count 1\n   Element 0 of array 0x6462a038\n   Path to nearest GC root\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a0a8 number 163 retained size 72\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684185280\n    Ref object char[]#167\n   References count 1\n   Element 1 of array 0x6462a038\n   Path to nearest GC root\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a0f0 number 164 retained size 56\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 9\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684185352\n    Ref object char[]#168\n   References count 1\n   Element 2 of array 0x6462a038\n   Path to nearest GC root\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a128 number 165 retained size 56\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 8\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684185408\n    Ref object char[]#169\n   References count 1\n   Element 3 of array 0x6462a038\n   Path to nearest GC root\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a160 number 166 retained size 64\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 13\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684185464\n    Ref object char[]#170\n   References count 1\n   Element 4 of array 0x6462a038\n   Path to nearest GC root\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a1a0 number 167 retained size 56\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 10\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684185528\n    Ref object char[]#171\n   References count 1\n   Element 5 of array 0x6462a038\n   Path to nearest GC root\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a1d8 number 168 retained size 64\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684185584\n    Ref object char[]#172\n   References count 1\n   Element 6 of array 0x6462a038\n   Path to nearest GC root\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a218 number 169 retained size 72\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684185648\n    Ref object char[]#173\n   References count 1\n   Element 7 of array 0x6462a038\n   Path to nearest GC root\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a260 number 170 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 20\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684185720\n    Ref object char[]#174\n   References count 1\n   Element 8 of array 0x6462a038\n   Path to nearest GC root\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a2b0 number 171 retained size 64\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 14\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684185800\n    Ref object char[]#175\n   References count 1\n   Element 9 of array 0x6462a038\n   Path to nearest GC root\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a450 number 172 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 3\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684186328\n    Ref object char[]#176\n   References count 1\n   Field value of instance 0x6462a500\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a518 number 173 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684186416\n    Ref object char[]#177\n   References count 1\n   Field value of instance 0x6462a570\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a588 number 174 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 36\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684186528\n    Ref object char[]#178\n   References count 1\n   Field value of instance 0x6462a608\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a620 number 175 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684186680\n    Ref object char[]#179\n   References count 1\n   Field value of instance 0x6462a670\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a688 number 176 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 0\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684186784\n    Ref object char[]#180\n   References count 1\n   Field value of instance 0x6462a6c0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a6d8 number 177 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 47\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684186864\n    Ref object char[]#181\n   References count 1\n   Field value of instance 0x6462a770\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a7c0 number 178 retained size 24\n   Instance Field name hash type int value -1422453681\n   Instance Field name count type int value 7\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684183512\n    Ref object char[]#159\n   References count 2\n   Field key of instance 0x6462a9b0\n   Field pkgName of instance 0x6462a980\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#22\n    Next object java.util.HashMap$Entry[]#11\n    Next object java.util.HashMap#9\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x6462aa68 number 179 retained size 96\n   Instance Field name hash type int value -201520135\n   Instance Field name count type int value 27\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684187680\n    Ref object char[]#182\n   References count 1\n   Field key of instance 0x6462aa80\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#23\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ab00 number 180 retained size 80\n   Instance Field name hash type int value 2040592281\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684187848\n    Ref object char[]#183\n   References count 1\n   Field key of instance 0x6462ab18\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#25\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ab80 number 181 retained size 56\n   Instance Field name hash type int value 1913354699\n   Instance Field name count type int value 10\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684188000\n    Ref object char[]#184\n   References count 1\n   Field key of instance 0x6462ab98\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#27\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ac10 number 182 retained size 72\n   Instance Field name hash type int value -1399078598\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684188128\n    Ref object char[]#185\n   References count 1\n   Field key of instance 0x6462ac28\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#29\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ac90 number 183 retained size 56\n   Instance Field name hash type int value 519601634\n   Instance Field name count type int value 8\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684188272\n    Ref object char[]#186\n   References count 1\n   Field key of instance 0x6462aca8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#31\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ad18 number 184 retained size 64\n   Instance Field name hash type int value -1080869749\n   Instance Field name count type int value 13\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684188400\n    Ref object char[]#187\n   References count 1\n   Field key of instance 0x6462ad30\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#33\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ada0 number 185 retained size 64\n   Instance Field name hash type int value 1474530042\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684188536\n    Ref object char[]#188\n   References count 1\n   Field key of instance 0x6462adb8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#35\n    Next object java.util.HashMap$Entry#42\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ae20 number 186 retained size 56\n   Instance Field name hash type int value 1073584312\n   Instance Field name count type int value 9\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684188672\n    Ref object char[]#189\n   References count 1\n   Field key of instance 0x6462ae38\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#37\n    Next object java.util.HashMap$Entry#39\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462aeb0 number 187 retained size 72\n   Instance Field name hash type int value -471709805\n   Instance Field name count type int value 18\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684188800\n    Ref object char[]#190\n   References count 1\n   Field key of instance 0x6462aec8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#39\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462af40 number 188 retained size 72\n   Instance Field name hash type int value -1286275278\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684188944\n    Ref object char[]#191\n   References count 1\n   Field key of instance 0x6462af58\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#41\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462afd0 number 189 retained size 72\n   Instance Field name hash type int value 1130729769\n   Instance Field name count type int value 17\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684189088\n    Ref object char[]#192\n   References count 1\n   Field key of instance 0x6462afe8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#43\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b050 number 190 retained size 56\n   Instance Field name hash type int value -1387190979\n   Instance Field name count type int value 9\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684189232\n    Ref object char[]#193\n   References count 1\n   Field key of instance 0x6462b068\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#45\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b0c8 number 191 retained size 48\n   Instance Field name hash type int value -1360271861\n   Instance Field name count type int value 6\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684189360\n    Ref object char[]#194\n   References count 1\n   Field key of instance 0x6462b0e0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#47\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b158 number 192 retained size 72\n   Instance Field name hash type int value 2049477040\n   Instance Field name count type int value 18\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684189480\n    Ref object char[]#195\n   References count 1\n   Field key of instance 0x6462b170\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#49\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b1d0 number 193 retained size 48\n   Instance Field name hash type int value 107855\n   Instance Field name count type int value 3\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684189624\n    Ref object char[]#196\n   References count 1\n   Field key of instance 0x6462b1e8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#51\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b258 number 194 retained size 64\n   Instance Field name hash type int value -1504022901\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684189744\n    Ref object char[]#197\n   References count 1\n   Field key of instance 0x6462b270\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#53\n    Next object java.util.HashMap$Entry#40\n    Next object java.util.HashMap$Entry#41\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b2e0 number 195 retained size 64\n   Instance Field name hash type int value 2102114132\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684189880\n    Ref object char[]#198\n   References count 1\n   Field key of instance 0x6462b2f8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#55\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b370 number 196 retained size 72\n   Instance Field name hash type int value 1241001083\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684190016\n    Ref object char[]#199\n   References count 1\n   Field key of instance 0x6462b388\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#57\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b400 number 197 retained size 72\n   Instance Field name hash type int value 1007689948\n   Instance Field name count type int value 17\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684190160\n    Ref object char[]#200\n   References count 1\n   Field key of instance 0x6462b418\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#59\n    Next object java.util.HashMap$Entry#47\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b480 number 198 retained size 56\n   Instance Field name hash type int value 1668403747\n   Instance Field name count type int value 10\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684190304\n    Ref object char[]#201\n   References count 1\n   Field key of instance 0x6462b498\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#61\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b518 number 199 retained size 80\n   Instance Field name hash type int value -1316038379\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684190432\n    Ref object char[]#202\n   References count 1\n   Field key of instance 0x6462b530\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#63\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b5a8 number 200 retained size 72\n   Instance Field name hash type int value 1279780102\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684190584\n    Ref object char[]#203\n   References count 1\n   Field key of instance 0x6462b5c0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#65\n    Next object java.util.HashMap$Entry#75\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b638 number 201 retained size 72\n   Instance Field name hash type int value -797636328\n   Instance Field name count type int value 17\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684190728\n    Ref object char[]#204\n   References count 1\n   Field key of instance 0x6462b650\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#67\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b6c8 number 202 retained size 72\n   Instance Field name hash type int value -242583904\n   Instance Field name count type int value 17\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684190872\n    Ref object char[]#205\n   References count 1\n   Field key of instance 0x6462b6e0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#69\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b740 number 203 retained size 48\n   Instance Field name hash type int value -982670030\n   Instance Field name count type int value 6\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684191016\n    Ref object char[]#206\n   References count 1\n   Field key of instance 0x6462b758\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#71\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b9d8 number 204 retained size 64\n   Instance Field name hash type int value 1932752118\n   Instance Field name count type int value 13\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684191664\n    Ref object char[]#207\n   References count 1\n   Field key of instance 0x6462b9f0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#73\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ba70 number 205 retained size 80\n   Instance Field name hash type int value 1987025769\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684191800\n    Ref object char[]#208\n   References count 1\n   Field key of instance 0x6462ba88\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#75\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462baf8 number 206 retained size 64\n   Instance Field name hash type int value 176803037\n   Instance Field name count type int value 14\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684191952\n    Ref object char[]#209\n   References count 1\n   Field key of instance 0x6462bb10\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#77\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bb88 number 207 retained size 72\n   Instance Field name hash type int value -1232737847\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684192088\n    Ref object char[]#210\n   References count 1\n   Field key of instance 0x6462bba0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#79\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bc18 number 208 retained size 72\n   Instance Field name hash type int value 438115086\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684192232\n    Ref object char[]#211\n   References count 1\n   Field key of instance 0x6462bc30\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#81\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bcd0 number 209 retained size 80\n   Instance Field name hash type int value 1707668194\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684192488\n    Ref object char[]#212\n   References count 1\n   Field key of instance 0x6462bd78\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#57\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bd20 number 210 retained size 88\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 25\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684192568\n    Ref object char[]#213\n   References count 1\n   Field value of instance 0x6462bd78\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#57\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bd90 number 211 retained size 80\n   Instance Field name hash type int value 1707668195\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684192680\n    Ref object char[]#214\n   References count 1\n   Field key of instance 0x6462be40\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#58\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bde0 number 212 retained size 96\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 27\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684192760\n    Ref object char[]#215\n   References count 1\n   Field value of instance 0x6462be40\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#58\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462be58 number 213 retained size 80\n   Instance Field name hash type int value 1707668196\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684192880\n    Ref object char[]#216\n   References count 1\n   Field key of instance 0x6462bf18\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#59\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bea8 number 214 retained size 112\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 37\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684192960\n    Ref object char[]#217\n   References count 1\n   Field value of instance 0x6462bf18\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#59\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bf30 number 215 retained size 80\n   Instance Field name hash type int value 1707668197\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684193096\n    Ref object char[]#218\n   References count 1\n   Field key of instance 0x6462bfe0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#60\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bf80 number 216 retained size 96\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 30\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684193176\n    Ref object char[]#219\n   References count 1\n   Field value of instance 0x6462bfe0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#60\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bff8 number 217 retained size 80\n   Instance Field name hash type int value 1707668198\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684193296\n    Ref object char[]#220\n   References count 1\n   Field key of instance 0x6462c0a8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#61\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c048 number 218 retained size 96\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 29\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684193376\n    Ref object char[]#221\n   References count 1\n   Field value of instance 0x6462c0a8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#61\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c0c0 number 219 retained size 80\n   Instance Field name hash type int value 1707668199\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684193496\n    Ref object char[]#222\n   References count 1\n   Field key of instance 0x6462c170\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#62\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c110 number 220 retained size 96\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 30\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684193576\n    Ref object char[]#223\n   References count 1\n   Field value of instance 0x6462c170\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#62\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c188 number 221 retained size 80\n   Instance Field name hash type int value 1707668200\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684193696\n    Ref object char[]#224\n   References count 1\n   Field key of instance 0x6462c250\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#63\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c1d8 number 222 retained size 120\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 39\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684193776\n    Ref object char[]#225\n   References count 1\n   Field value of instance 0x6462c250\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#63\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c268 number 223 retained size 80\n   Instance Field name hash type int value 1707668201\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684193920\n    Ref object char[]#226\n   References count 1\n   Field key of instance 0x6462c320\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#64\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c2b8 number 224 retained size 104\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 32\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684194000\n    Ref object char[]#227\n   References count 1\n   Field value of instance 0x6462c320\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#64\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c338 number 225 retained size 80\n   Instance Field name hash type int value -1295903345\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684194128\n    Ref object char[]#228\n   References count 1\n   Field key of instance 0x6462c3d0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#65\n    Next object java.util.Hashtable$Entry#58\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c388 number 226 retained size 72\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 17\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684194208\n    Ref object char[]#229\n   References count 2\n   Field seedSource of Class sun.security.provider.Sun\n   Field value of instance 0x6462c3d0\n   Path to nearest GC root\n    Next object java.lang.Class#326\n  Instance Id 0x6462c3e8 number 227 retained size 96\n   Instance Field name hash type int value -342094834\n   Instance Field name count type int value 28\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684194304\n    Ref object char[]#230\n   References count 1\n   Field key of instance 0x6462c4b8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#66\n    Next object java.util.Hashtable$Entry#63\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c448 number 228 retained size 112\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 38\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684194400\n    Ref object char[]#231\n   References count 1\n   Field value of instance 0x6462c4b8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#66\n    Next object java.util.Hashtable$Entry#63\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c4d0 number 229 retained size 72\n   Instance Field name hash type int value 2061765421\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684194536\n    Ref object char[]#232\n   References count 1\n   Field key of instance 0x6462c580\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#67\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c518 number 230 retained size 104\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 32\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684194608\n    Ref object char[]#233\n   References count 1\n   Field value of instance 0x6462c580\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#67\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c598 number 231 retained size 64\n   Instance Field name hash type int value 1308266422\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684194736\n    Ref object char[]#234\n   References count 1\n   Field key of instance 0x6462c650\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#68\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c5d8 number 232 retained size 120\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 42\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684194800\n    Ref object char[]#235\n   References count 1\n   Field value of instance 0x6462c650\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#68\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c668 number 233 retained size 64\n   Instance Field name hash type int value 1308266423\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684194944\n    Ref object char[]#236\n   References count 1\n   Field key of instance 0x6462c708\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#69\n    Next object java.util.Hashtable$Entry#71\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c6a8 number 234 retained size 96\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 30\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684195008\n    Ref object char[]#237\n   References count 1\n   Field value of instance 0x6462c708\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#69\n    Next object java.util.Hashtable$Entry#71\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c720 number 235 retained size 88\n   Instance Field name hash type int value 290674857\n   Instance Field name count type int value 23\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684195128\n    Ref object char[]#238\n   References count 1\n   Field key of instance 0x6462c7a8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#70\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c778 number 236 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 4\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684195216\n    Ref object char[]#239\n   References count 1\n   Field value of instance 0x6462c7a8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#70\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c7c0 number 237 retained size 88\n   Instance Field name hash type int value 472460817\n   Instance Field name count type int value 26\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684195288\n    Ref object char[]#240\n   References count 1\n   Field key of instance 0x6462c848\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#71\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c818 number 238 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 4\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684195376\n    Ref object char[]#241\n   References count 1\n   Field value of instance 0x6462c848\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#71\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c860 number 239 retained size 88\n   Instance Field name hash type int value -778438456\n   Instance Field name count type int value 26\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684195448\n    Ref object char[]#242\n   References count 1\n   Field key of instance 0x6462c8e8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#72\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c8b8 number 240 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 5\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684195536\n    Ref object char[]#243\n   References count 1\n   Field value of instance 0x6462c8e8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#72\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c900 number 241 retained size 64\n   Instance Field name hash type int value 1312008134\n   Instance Field name count type int value 13\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684195608\n    Ref object char[]#244\n   References count 1\n   Field key of instance 0x6462c970\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#73\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c940 number 242 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 3\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684195672\n    Ref object char[]#245\n   References count 1\n   Field value of instance 0x6462c970\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#73\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c988 number 243 retained size 64\n   Instance Field name hash type int value -1748632107\n   Instance Field name count type int value 12\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684195744\n    Ref object char[]#246\n   References count 1\n   Field key of instance 0x6462cb00\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#74\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c9c8 number 244 retained size 112\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 38\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684195808\n    Ref object char[]#247\n   References count 1\n   Field value of instance 0x6462cb00\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#74\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cb18 number 245 retained size 64\n   Instance Field name hash type int value -978260980\n   Instance Field name count type int value 14\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684196144\n    Ref object char[]#248\n   References count 1\n   Field key of instance 0x6462cb88\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#75\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cb58 number 246 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 4\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684196208\n    Ref object char[]#249\n   References count 1\n   Field value of instance 0x6462cb88\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#75\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cba0 number 247 retained size 104\n   Instance Field name hash type int value -1061199191\n   Instance Field name count type int value 31\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684196280\n    Ref object char[]#250\n   References count 1\n   Field key of instance 0x6462cc38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#76\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cc08 number 248 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 4\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684196384\n    Ref object char[]#251\n   References count 1\n   Field value of instance 0x6462cc38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#76\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cc50 number 249 retained size 104\n   Instance Field name hash type int value -1955866405\n   Instance Field name count type int value 31\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684196456\n    Ref object char[]#252\n   References count 1\n   Field key of instance 0x6462ccf0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#77\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462ccb8 number 250 retained size 56\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 7\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684196560\n    Ref object char[]#253\n   References count 1\n   Field value of instance 0x6462ccf0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#77\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cd08 number 251 retained size 104\n   Instance Field name hash type int value -2074044844\n   Instance Field name count type int value 33\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684196640\n    Ref object char[]#254\n   References count 1\n   Field key of instance 0x6462cda0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#78\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cd70 number 252 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 4\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684196744\n    Ref object char[]#255\n   References count 1\n   Field value of instance 0x6462cda0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#78\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cdb8 number 253 retained size 104\n   Instance Field name hash type int value -1565910905\n   Instance Field name count type int value 33\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684196816\n    Ref object char[]#256\n   References count 1\n   Field key of instance 0x6462ce48\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#79\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462ce20 number 254 retained size 40\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 2\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684196920\n    Ref object char[]#257\n   References count 1\n   Field value of instance 0x6462ce48\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#79\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462ef50 number 255 retained size 48\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 3\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684205416\n    Ref object char[]#262\n   References count 1\n   Field value of instance 0x6462ef80\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#81\n    Next object java.util.Hashtable$Entry#149\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630768 number 256 retained size 104\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 32\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684211480\n    Ref object char[]#265\n   References count 1\n   Field ATTR_DIGEST of Class sun.security.util.SignatureFileVerifier\n   Path to nearest GC root\n    Next object java.lang.Class#301\n  Instance Id 0x64630920 number 257 retained size 72\n   Instance Field name hash type int value 741476021\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684212024\n    Ref object char[]#267\n   References count 1\n   Field name of instance 0x64630968\n   Path to nearest GC root\n    Next object java.io.FilePermission#1\n    Next object java.lang.Object[]#316\n    Next object java.util.ArrayList#7\n    Next object java.io.FilePermissionCollection#1\n    Next object java.util.HashMap$Entry#153\n    Next object java.util.HashMap$Entry[]#24\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64630ca0 number 258 retained size 24\n   Instance Field name hash type int value -1422453681\n   Instance Field name count type int value 7\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684183512\n    Ref object char[]#159\n   References count 1\n   Field key of instance 0x64630cc8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#153\n    Next object java.util.Hashtable$Entry[]#6\n    Next object java.util.Hashtable#5\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64630de8 number 259 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1684213248\n    Ref object char[]#268\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68133910 number 260 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 6\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746090280\n    Ref object char[]#270\n   References count 2\n   Field name of instance 0x64614e40\n   Field name of instance 0x64626718\n   Path to nearest GC root\n    Null\n  Instance Id 0x68133940 number 261 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 11\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746090328\n    Ref object char[]#271\n   References count 1\n   Field name of instance 0x64614e88\n   Path to nearest GC root\n    Null\n  Instance Id 0x68133b40 number 262 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 30\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746090840\n    Ref object char[]#272\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68133ba0 number 263 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 21\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746090936\n    Ref object char[]#273\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68134120 number 264 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 17\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746092344\n    Ref object char[]#274\n   References count 1\n   Field name of instance 0x646165c0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68134168 number 265 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 10\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746092416\n    Ref object char[]#275\n   References count 1\n   Field name of instance 0x64616650\n   Path to nearest GC root\n    Null\n  Instance Id 0x681341a0 number 266 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 3\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746092472\n    Ref object char[]#276\n   References count 1\n   Field name of instance 0x646167b8\n   Path to nearest GC root\n    Null\n  Instance Id 0x681341d0 number 267 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 7\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746092520\n    Ref object char[]#277\n   References count 1\n   Field name of instance 0x64616800\n   Path to nearest GC root\n    Null\n  Instance Id 0x68134208 number 268 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 9\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746092576\n    Ref object char[]#278\n   References count 1\n   Field name of instance 0x64616848\n   Path to nearest GC root\n    Null\n  Instance Id 0x68134d50 number 269 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 27\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746095464\n    Ref object char[]#279\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681396b8 number 270 retained size 40\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 2\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746114256\n    Ref object char[]#280\n   References count 1\n   Field signature of instance 0x64626340\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField#1\n    Next object java.io.ObjectStreamField[]#3\n    Next object java.lang.Class#228\n  Instance Id 0x68139c68 number 271 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 23\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746115712\n    Ref object char[]#281\n   References count 1\n   Field name of instance 0x646266d0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139cc0 number 272 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 11\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746115800\n    Ref object char[]#282\n   References count 1\n   Field name of instance 0x64626760\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139d00 number 273 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 10\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746115864\n    Ref object char[]#283\n   References count 1\n   Field name of instance 0x646267a8\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139d38 number 274 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 10\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746115920\n    Ref object char[]#284\n   References count 1\n   Field name of instance 0x646267f0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139d70 number 275 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746115976\n    Ref object char[]#285\n   References count 1\n   Field name of instance 0x64626838\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139db8 number 276 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 9\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746116048\n    Ref object char[]#286\n   References count 1\n   Field name of instance 0x646268d8\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139df0 number 277 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 6\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746116104\n    Ref object char[]#287\n   References count 1\n   Field name of instance 0x64626920\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139e20 number 278 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 9\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746116152\n    Ref object char[]#288\n   References count 1\n   Field name of instance 0x64626968\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139e58 number 279 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 6\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746116208\n    Ref object char[]#289\n   References count 1\n   Field name of instance 0x646269b0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139e88 number 280 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 9\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746116256\n    Ref object char[]#290\n   References count 1\n   Field name of instance 0x646269f8\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139ec0 number 281 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 4\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746116312\n    Ref object char[]#291\n   References count 1\n   Field name of instance 0x64626a88\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139ef0 number 282 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 4\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746116360\n    Ref object char[]#292\n   References count 1\n   Field name of instance 0x64626ad0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139f20 number 283 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 6\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746116408\n    Ref object char[]#293\n   References count 1\n   Field name of instance 0x64626b18\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139f50 number 284 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 10\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746116456\n    Ref object char[]#294\n   References count 1\n   Field name of instance 0x64626b60\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813a2e0 number 285 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746117368\n    Ref object char[]#295\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813a328 number 286 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 11\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746117440\n    Ref object char[]#296\n   References count 2\n   Field name of instance 0x64629578\n   Field name of instance 0x6462a560\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813a368 number 287 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 10\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746117504\n    Ref object char[]#297\n   References count 2\n   Field name of instance 0x64629610\n   Field name of instance 0x6462a5f8\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813a3a0 number 288 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 9\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746117560\n    Ref object char[]#298\n   References count 2\n   Field name of instance 0x64629778\n   Field name of instance 0x6462a760\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813ac08 number 289 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 19\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746119712\n    Ref object char[]#299\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813ac58 number 290 retained size 80\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 21\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746119792\n    Ref object char[]#300\n   References count 2\n   Field signature of instance 0x646307e8\n   Field signature of instance 0x64630b38\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField#5\n    Next object java.io.ObjectStreamField[]#6\n    Next object java.lang.Class#246\n  Instance Id 0x6813aca8 number 291 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 34\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746119872\n    Ref object char[]#301\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813ad10 number 292 retained size 112\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 36\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746119976\n    Ref object char[]#302\n   References count 1\n   Field signature of instance 0x64630808\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField#6\n    Next object java.io.ObjectStreamField[]#6\n    Next object java.lang.Class#246\n  Instance Id 0x6813ad80 number 293 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 16\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746120088\n    Ref object char[]#303\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813adc8 number 294 retained size 72\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 18\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746120160\n    Ref object char[]#304\n   References count 1\n   Field signature of instance 0x64630a70\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField#7\n    Next object java.io.ObjectStreamField[]#7\n    Next object java.lang.Class#376\n  Instance Id 0x6813ae10 number 295 retained size 0\n   Instance Field name hash type int value 0\n   Instance Field name count type int value 15\n   Instance Field name offset type int value 0\n   Instance Field name value type object value 1746120232\n    Ref object char[]#305\n   References count 0\n   Path to nearest GC root\n    Null\n Id 0x68132170 Class java.lang.String[] SuperClass java.lang.Object Instance size -1 Instance count 49 All Instances Size 1704\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64611b30 number 1 retained size 72\n   References count 1\n   Field aliases_US_ASCII of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611b78 number 2 retained size 24\n   References count 2\n   Field aliases_UTF_8 of Class sun.nio.cs.StandardCharsets\n   Field aliases of instance 0x646293a8\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611b90 number 3 retained size 32\n   References count 1\n   Field aliases_UTF_16 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611bb0 number 4 retained size 32\n   References count 1\n   Field aliases_UTF_16BE of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611bd0 number 5 retained size 24\n   References count 1\n   Field aliases_UTF_16LE of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611be8 number 6 retained size 16\n   References count 1\n   Field aliases_UTF_16LE_BOM of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611bf8 number 7 retained size 24\n   References count 1\n   Field aliases_UTF_32 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611c10 number 8 retained size 24\n   References count 1\n   Field aliases_UTF_32LE of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611c28 number 9 retained size 24\n   References count 1\n   Field aliases_UTF_32BE of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611c40 number 10 retained size 24\n   References count 1\n   Field aliases_UTF_32LE_BOM of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611c58 number 11 retained size 24\n   References count 1\n   Field aliases_UTF_32BE_BOM of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611c70 number 12 retained size 72\n   References count 2\n   Field aliases_ISO_8859_1 of Class sun.nio.cs.StandardCharsets\n   Field aliases of instance 0x64615098\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611cb8 number 13 retained size 64\n   References count 1\n   Field aliases_ISO_8859_2 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611cf8 number 14 retained size 64\n   References count 1\n   Field aliases_ISO_8859_4 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611d38 number 15 retained size 64\n   References count 1\n   Field aliases_ISO_8859_5 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611d78 number 16 retained size 80\n   References count 1\n   Field aliases_ISO_8859_7 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611dc8 number 17 retained size 64\n   References count 1\n   Field aliases_ISO_8859_9 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611e08 number 18 retained size 32\n   References count 1\n   Field aliases_ISO_8859_13 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611e28 number 19 retained size 72\n   References count 1\n   Field aliases_ISO_8859_15 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611e70 number 20 retained size 24\n   References count 1\n   Field aliases_KOI8_R of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611e88 number 21 retained size 16\n   References count 1\n   Field aliases_KOI8_U of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611e98 number 22 retained size 24\n   References count 1\n   Field aliases_MS1250 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611eb0 number 23 retained size 24\n   References count 1\n   Field aliases_MS1251 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611ec8 number 24 retained size 24\n   References count 1\n   Field aliases_MS1252 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611ee0 number 25 retained size 24\n   References count 1\n   Field aliases_MS1253 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611ef8 number 26 retained size 24\n   References count 1\n   Field aliases_MS1254 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611f10 number 27 retained size 24\n   References count 1\n   Field aliases_MS1257 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611f28 number 28 retained size 40\n   References count 1\n   Field aliases_IBM437 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611f50 number 29 retained size 32\n   References count 1\n   Field aliases_IBM737 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611f70 number 30 retained size 32\n   References count 1\n   Field aliases_IBM775 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611f90 number 31 retained size 32\n   References count 1\n   Field aliases_IBM850 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611fb0 number 32 retained size 32\n   References count 1\n   Field aliases_IBM852 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611fd0 number 33 retained size 32\n   References count 1\n   Field aliases_IBM855 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64611ff0 number 34 retained size 32\n   References count 1\n   Field aliases_IBM857 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64612010 number 35 retained size 32\n   References count 1\n   Field aliases_IBM858 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64612030 number 36 retained size 40\n   References count 1\n   Field aliases_IBM862 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64612058 number 37 retained size 32\n   References count 1\n   Field aliases_IBM866 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64612078 number 38 retained size 32\n   References count 1\n   Field aliases_IBM874 of Class sun.nio.cs.StandardCharsets\n   Path to nearest GC root\n    Next object java.lang.Class#426\n  Instance Id 0x64615188 number 39 retained size 32\n   References count 1\n   Field stateNames of Class java.nio.charset.CharsetDecoder\n   Path to nearest GC root\n    Next object java.lang.Class#423\n  Instance Id 0x64615220 number 40 retained size 32\n   References count 1\n   Field names of Class java.nio.charset.CoderResult\n   Path to nearest GC root\n    Next object java.lang.Class#6\n  Instance Id 0x646169e0 number 41 retained size 32\n   References count 1\n   Field stateNames of Class java.nio.charset.CharsetEncoder\n   Path to nearest GC root\n    Next object java.lang.Class#422\n  Instance Id 0x64624f10 number 42 retained size 184\n   References count 1\n   Field usr_paths of Class java.lang.ClassLoader\n   Path to nearest GC root\n    Next object java.lang.Class#101\n  Instance Id 0x64624fc8 number 43 retained size 16\n   References count 1\n   Field sys_paths of Class java.lang.ClassLoader\n   Path to nearest GC root\n    Next object java.lang.Class#101\n  Instance Id 0x64625c58 number 44 retained size 248\n   References count 1\n   Field contents of instance 0x64625c48\n   Path to nearest GC root\n    Next object sun.misc.MetaIndex#1\n    Next object java.util.HashMap$Entry#1\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625d98 number 45 retained size 136\n   References count 1\n   Field contents of instance 0x64625d88\n   Path to nearest GC root\n    Next object sun.misc.MetaIndex#2\n    Next object java.util.HashMap$Entry#2\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625f58 number 46 retained size 256\n   References count 1\n   Field contents of instance 0x64625f48\n   Path to nearest GC root\n    Next object sun.misc.MetaIndex#3\n    Next object java.util.HashMap$Entry#3\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64626108 number 47 retained size 248\n   References count 1\n   Field contents of instance 0x646260f8\n   Path to nearest GC root\n    Next object sun.misc.MetaIndex#4\n    Next object java.util.HashMap$Entry#4\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x6462a038 number 48 retained size 696\n   References count 1\n   Field jarNames of Class java.util.jar.JarFile\n   Path to nearest GC root\n    Next object java.lang.Class#184\n  Instance Id 0x64630d58 number 49 retained size 16\n   References count 0\n   Path to nearest GC root\n Id 0x6c9c85a8 Class java.lang.ClassLoader$NativeLibrary SuperClass java.lang.Object Instance size 32 Instance count 1 All Instances Size 32\n  Static Field name <classLoader> type object value 0\n  Field name name type object\n  Field name fromClass type object\n  Field name jniVersion type int\n  Field name handle type long\n  Instance Id 0x64625278 number 1 retained size 32\n   Instance Field name name type object value 1684164984\n    Ref object java.lang.String#110\n   Instance Field name fromClass type object value 0\n   Instance Field name jniVersion type int value 65538\n   Instance Field name handle type long value 134590568\n   References count 2\n   Element 0 of array 0x646108b8\n   Field referent of instance 0x64625298\n   Path to nearest GC root\n    Next object java.lang.Object[]#10\n    Next object java.util.Vector#2\n    Next object java.lang.Class#101\n Id 0x6c93f2f0 Class java.lang.ThreadDeath SuperClass java.lang.Error Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c93ec10 Class java.lang.Throwable SuperClass java.lang.Object Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value -3042686055658047285\n  Static Field name <classLoader> type object value 0\n  Field name stackTrace type object\n  Field name cause type object\n  Field name detailMessage type object\n  Field name backtrace type object\n Id 0x681304f8 Class java.lang.Throwable[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c93c6a0 Class java.lang.ClassLoader SuperClass java.lang.Object Instance size 56 Instance count 0 All Instances Size 0\n  Static Field name sys_paths type object value 1684164552\n   Ref object java.lang.String[]#43\n  Static Field name usr_paths type object value 1684164368\n   Ref object java.lang.String[]#42\n  Static Field name nativeLibraryContext type object value 1684080880\n   Ref object java.util.Stack#1\n  Static Field name systemNativeLibraries type object value 1684080800\n   Ref object java.util.Vector#2\n  Static Field name loadedLibraryNames type object value 1684080720\n   Ref object java.util.Vector#1\n  Static Field name sclSet type boolean value true\n  Static Field name scl type object value 1684178464\n   Ref object sun.misc.Launcher$AppClassLoader#1\n  Static Field name bootstrapClassPath type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name classAssertionStatus type object\n  Field name packageAssertionStatus type object\n  Field name defaultAssertionStatus type boolean\n  Field name nativeLibraries type object\n  Field name defaultDomain type object\n  Field name packages type object\n  Field name domains type object\n  Field name classes type object\n  Field name nocerts type object\n  Field name package2certs type object\n  Field name parent type object\n  Field name initialized type boolean\n Id 0x6c966b08 Class java.lang.Double SuperClass java.lang.Number Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value -9172774392245257468\n  Static Field name TYPE type object value 1746075856\n   Ref object java.lang.Class#3\n  Static Field name SIZE type int value 64\n  Static Field name MIN_EXPONENT type int value -1022\n  Static Field name MAX_EXPONENT type int value 1023\n  Static Field name MIN_VALUE type double value 4.9E-324\n  Static Field name MIN_NORMAL type double value 2.2250738585072014E-308\n  Static Field name MAX_VALUE type double value 1.7976931348623157E308\n  Static Field name NaN type double value NaN\n  Static Field name NEGATIVE_INFINITY type double value -Infinity\n  Static Field name POSITIVE_INFINITY type double value Infinity\n  Static Field name <classLoader> type object value 0\n  Field name value type double\n Id 0x6c965a80 Class java.lang.Float SuperClass java.lang.Number Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value -2671257302660747028\n  Static Field name TYPE type object value 1746075760\n   Ref object java.lang.Class#2\n  Static Field name SIZE type int value 32\n  Static Field name MIN_EXPONENT type int value -126\n  Static Field name MAX_EXPONENT type int value 127\n  Static Field name MIN_VALUE type float value 1.4E-45\n  Static Field name MIN_NORMAL type float value 1.17549435E-38\n  Static Field name MAX_VALUE type float value 3.4028235E38\n  Static Field name NaN type float value NaN\n  Static Field name NEGATIVE_INFINITY type float value -Infinity\n  Static Field name POSITIVE_INFINITY type float value Infinity\n  Static Field name <classLoader> type object value 0\n  Field name value type float\n Id 0x6c9645c8 Class java.lang.Character SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name SIZE type int value 16\n  Static Field name FAST_PATH_MAX type int value 255\n  Static Field name serialVersionUID type long value 3786198910865385080\n  Static Field name MAX_CODE_POINT type int value 1114111\n  Static Field name MIN_CODE_POINT type int value 0\n  Static Field name MIN_SUPPLEMENTARY_CODE_POINT type int value 65536\n  Static Field name MAX_SURROGATE type char value ?\n  Static Field name MIN_SURROGATE type char value ?\n  Static Field name MAX_LOW_SURROGATE type char value ?\n  Static Field name MIN_LOW_SURROGATE type char value ?\n  Static Field name MAX_HIGH_SURROGATE type char value ?\n  Static Field name MIN_HIGH_SURROGATE type char value ?\n  Static Field name DIRECTIONALITY_POP_DIRECTIONAL_FORMAT type byte value 18\n  Static Field name DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE type byte value 17\n  Static Field name DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING type byte value 16\n  Static Field name DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE type byte value 15\n  Static Field name DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING type byte value 14\n  Static Field name DIRECTIONALITY_OTHER_NEUTRALS type byte value 13\n  Static Field name DIRECTIONALITY_WHITESPACE type byte value 12\n  Static Field name DIRECTIONALITY_SEGMENT_SEPARATOR type byte value 11\n  Static Field name DIRECTIONALITY_PARAGRAPH_SEPARATOR type byte value 10\n  Static Field name DIRECTIONALITY_BOUNDARY_NEUTRAL type byte value 9\n  Static Field name DIRECTIONALITY_NONSPACING_MARK type byte value 8\n  Static Field name DIRECTIONALITY_COMMON_NUMBER_SEPARATOR type byte value 7\n  Static Field name DIRECTIONALITY_ARABIC_NUMBER type byte value 6\n  Static Field name DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR type byte value 5\n  Static Field name DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR type byte value 4\n  Static Field name DIRECTIONALITY_EUROPEAN_NUMBER type byte value 3\n  Static Field name DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC type byte value 2\n  Static Field name DIRECTIONALITY_RIGHT_TO_LEFT type byte value 1\n  Static Field name DIRECTIONALITY_LEFT_TO_RIGHT type byte value 0\n  Static Field name DIRECTIONALITY_UNDEFINED type byte value -1\n  Static Field name ERROR type int value -1\n  Static Field name FINAL_QUOTE_PUNCTUATION type byte value 30\n  Static Field name INITIAL_QUOTE_PUNCTUATION type byte value 29\n  Static Field name OTHER_SYMBOL type byte value 28\n  Static Field name MODIFIER_SYMBOL type byte value 27\n  Static Field name CURRENCY_SYMBOL type byte value 26\n  Static Field name MATH_SYMBOL type byte value 25\n  Static Field name OTHER_PUNCTUATION type byte value 24\n  Static Field name CONNECTOR_PUNCTUATION type byte value 23\n  Static Field name END_PUNCTUATION type byte value 22\n  Static Field name START_PUNCTUATION type byte value 21\n  Static Field name DASH_PUNCTUATION type byte value 20\n  Static Field name SURROGATE type byte value 19\n  Static Field name PRIVATE_USE type byte value 18\n  Static Field name FORMAT type byte value 16\n  Static Field name CONTROL type byte value 15\n  Static Field name PARAGRAPH_SEPARATOR type byte value 14\n  Static Field name LINE_SEPARATOR type byte value 13\n  Static Field name SPACE_SEPARATOR type byte value 12\n  Static Field name OTHER_NUMBER type byte value 11\n  Static Field name LETTER_NUMBER type byte value 10\n  Static Field name DECIMAL_DIGIT_NUMBER type byte value 9\n  Static Field name COMBINING_SPACING_MARK type byte value 8\n  Static Field name ENCLOSING_MARK type byte value 7\n  Static Field name NON_SPACING_MARK type byte value 6\n  Static Field name OTHER_LETTER type byte value 5\n  Static Field name MODIFIER_LETTER type byte value 4\n  Static Field name TITLECASE_LETTER type byte value 3\n  Static Field name LOWERCASE_LETTER type byte value 2\n  Static Field name UPPERCASE_LETTER type byte value 1\n  Static Field name UNASSIGNED type byte value 0\n  Static Field name TYPE type object value 1746076144\n   Ref object java.lang.Class#6\n  Static Field name MAX_VALUE type char value ￿\n  Static Field name MIN_VALUE type char value \u0000\n  Static Field name MAX_RADIX type int value 36\n  Static Field name MIN_RADIX type int value 2\n  Static Field name <classLoader> type object value 0\n  Field name value type char\n Id 0x6c961940 Class java.lang.Boolean SuperClass java.lang.Object Instance size 16 Instance count 2 All Instances Size 32\n  Static Field name serialVersionUID type long value -3665804199014368530\n  Static Field name TYPE type object value 1746076048\n   Ref object java.lang.Class#5\n  Static Field name FALSE type object value 1684164704\n   Ref object java.lang.Boolean#2\n  Static Field name TRUE type object value 1684164688\n   Ref object java.lang.Boolean#1\n  Static Field name <classLoader> type object value 0\n  Field name value type boolean\n  Instance Id 0x64625050 number 1 retained size 16\n   Instance Field name value type boolean value true\n   References count 1\n   Field TRUE of Class java.lang.Boolean\n   Path to nearest GC root\n    Next object java.lang.Class#105\n  Instance Id 0x64625060 number 2 retained size 16\n   Instance Field name value type boolean value false\n   References count 1\n   Field FALSE of Class java.lang.Boolean\n   Path to nearest GC root\n    Next object java.lang.Class#105\n Id 0x6c96b078 Class java.lang.Long SuperClass java.lang.Number Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value 4290774380558885855\n  Static Field name SIZE type int value 64\n  Static Field name TYPE type object value 1746076240\n   Ref object java.lang.Class#7\n  Static Field name MAX_VALUE type long value 9223372036854775807\n  Static Field name MIN_VALUE type long value -9223372036854775808\n  Static Field name <classLoader> type object value 0\n  Field name value type long\n Id 0x6c969a90 Class java.lang.Integer SuperClass java.lang.Number Instance size 16 Instance count 3 All Instances Size 48\n  Static Field name serialVersionUID type long value 1360826667806852920\n  Static Field name SIZE type int value 32\n  Static Field name sizeTable type object value 1684165992\n   Ref object int[]#2\n  Static Field name DigitOnes type object value 1684165776\n   Ref object char[]#112\n  Static Field name DigitTens type object value 1684165560\n   Ref object char[]#111\n  Static Field name digits type object value 1684165472\n   Ref object char[]#110\n  Static Field name TYPE type object value 1746075664\n   Ref object java.lang.Class#1\n  Static Field name MAX_VALUE type int value 2147483647\n  Static Field name MIN_VALUE type int value -2147483648\n  Static Field name <classLoader> type object value 0\n  Field name value type int\n  Instance Id 0x646255a0 number 1 retained size 16\n   Instance Field name value type int value 1\n   References count 1\n   Field key of instance 0x646255b0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#50\n    Next object java.util.Hashtable$Entry[]#3\n    Next object java.util.Hashtable#2\n    Next object java.lang.Class#145\n  Instance Id 0x64625610 number 2 retained size 16\n   Instance Field name value type int value 2\n   References count 1\n   Field key of instance 0x64625620\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#52\n    Next object java.util.Hashtable$Entry[]#3\n    Next object java.util.Hashtable#2\n    Next object java.lang.Class#145\n  Instance Id 0x64625660 number 3 retained size 16\n   Instance Field name value type int value 15\n   References count 1\n   Field key of instance 0x64625670\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#54\n    Next object java.util.Hashtable$Entry[]#3\n    Next object java.util.Hashtable#2\n    Next object java.lang.Class#145\n Id 0x6c9684e8 Class java.lang.Short SuperClass java.lang.Number Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value 7515723908773894738\n  Static Field name SIZE type int value 16\n  Static Field name TYPE type object value 1746076336\n   Ref object java.lang.Class#8\n  Static Field name MAX_VALUE type short value 32767\n  Static Field name MIN_VALUE type short value -32768\n  Static Field name <classLoader> type object value 0\n  Field name value type short\n Id 0x6c9677c0 Class java.lang.Byte SuperClass java.lang.Number Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value -7183698231559129828\n  Static Field name SIZE type int value 8\n  Static Field name TYPE type object value 1746075952\n   Ref object java.lang.Class#4\n  Static Field name MAX_VALUE type byte value 127\n  Static Field name MIN_VALUE type byte value -128\n  Static Field name <classLoader> type object value 0\n  Field name value type byte\n Id 0x6ca07b80 Class java.lang.Shutdown SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name haltLock type object value 1684166416\n   Ref object java.lang.Shutdown$Lock#2\n  Static Field name lock type object value 1684166408\n   Ref object java.lang.Shutdown$Lock#1\n  Static Field name hooks type object value 1684166328\n   Ref object java.util.ArrayList#1\n  Static Field name runFinalizersOnExit type boolean value false\n  Static Field name state type int value 0\n  Static Field name FINALIZERS type int value 2\n  Static Field name HOOKS type int value 1\n  Static Field name RUNNING type int value 0\n  Static Field name <classLoader> type object value 0\n Id 0x68135460 Class java.io.File$1 SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64616eb8 number 1 retained size 8\n   References count 2\n   Field javaIODeleteOnExitAccess of Class sun.misc.SharedSecrets\n   Element 2 of array 0x646256d0\n   Path to nearest GC root\n    Next object java.lang.Class#312\n Id 0x6c9c05b0 Class java.io.FileSystem SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name useCanonPrefixCache type boolean value true\n  Static Field name useCanonCaches type boolean value true\n  Static Field name SPACE_USABLE type int value 2\n  Static Field name SPACE_FREE type int value 1\n  Static Field name SPACE_TOTAL type int value 0\n  Static Field name ACCESS_EXECUTE type int value 1\n  Static Field name ACCESS_WRITE type int value 2\n  Static Field name ACCESS_READ type int value 4\n  Static Field name BA_HIDDEN type int value 8\n  Static Field name BA_DIRECTORY type int value 4\n  Static Field name BA_REGULAR type int value 2\n  Static Field name BA_EXISTS type int value 1\n  Static Field name <classLoader> type object value 0\n Id 0x6c943e40 Class java.lang.ref.WeakReference SuperClass java.lang.ref.Reference Instance size 24 Instance count 3 All Instances Size 72\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64616a40 number 1 retained size 24\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 1684105792\n    Ref object java.lang.ref.WeakReference#1\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 0\n   References count 2\n   Field cachedDecoder of instance 0x64616a00\n   Field next of instance 0x64616a40\n   Path to nearest GC root\n    Next object sun.nio.cs.ISO_8859_1$Encoder#1\n    Next object sun.nio.cs.StreamEncoder#1\n    Next object java.io.OutputStreamWriter#1\n    Next object java.io.PrintStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616c18 number 2 retained size 24\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 1684106264\n    Ref object java.lang.ref.WeakReference#2\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 0\n   References count 2\n   Field cachedDecoder of instance 0x64616bd8\n   Field next of instance 0x64616c18\n   Path to nearest GC root\n    Next object sun.nio.cs.ISO_8859_1$Encoder#2\n    Next object sun.nio.cs.StreamEncoder#2\n    Next object java.io.OutputStreamWriter#2\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n  Instance Id 0x64625110 number 3 retained size 0\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684164840\n    Ref object sun.nio.cs.ISO_8859_1$Decoder#1\n   References count 1\n   Field cachedDecoder of instance 0x646250a8\n   Path to nearest GC root\n    Null\n Id 0x68133f20 Class java.lang.ref.WeakReference[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c943b30 Class java.lang.ref.SoftReference SuperClass java.lang.ref.Reference Instance size 32 Instance count 12 All Instances Size 384\n  Static Field name clock type long value 1150458371933\n  Static Field name <classLoader> type object value 0\n  Field name timestamp type long\n  Instance Id 0x64614f18 number 1 retained size 0\n   Instance Field name timestamp type long value 1150458355618\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684098504\n    Ref object java.lang.reflect.Field[]#1\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64615010 number 2 retained size 0\n   Instance Field name timestamp type long value 1150458355618\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684098976\n    Ref object java.lang.reflect.Constructor[]#1\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64616890 number 3 retained size 0\n   Instance Field name timestamp type long value 1150458355618\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684104600\n    Ref object java.lang.reflect.Field[]#2\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64625140 number 4 retained size 32\n   Instance Field name timestamp type long value 1150458355618\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684164752\n    Ref object java.lang.StringCoding$StringEncoder#1\n   References count 1\n   Field value of instance 0x64625070\n   Path to nearest GC root\n    Next object java.lang.ThreadLocal$ThreadLocalMap$Entry#2\n    Next object java.lang.ThreadLocal$ThreadLocalMap$Entry[]#1\n    Next object java.lang.ThreadLocal$ThreadLocalMap#1\n    Next object java.lang.Thread#1\n  Instance Id 0x64626880 number 5 retained size 0\n   Instance Field name timestamp type long value 1150458355618\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684170104\n    Ref object java.lang.reflect.Field[]#3\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626ba8 number 6 retained size 0\n   Instance Field name timestamp type long value 1150458355618\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684170912\n    Ref object java.lang.reflect.Field[]#4\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64627968 number 7 retained size 0\n   Instance Field name timestamp type long value 1150458355618\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684175112\n    Ref object java.lang.reflect.Constructor[]#2\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64628430 number 8 retained size 0\n   Instance Field name timestamp type long value 1150458355618\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684177872\n    Ref object java.lang.reflect.Constructor[]#3\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629320 number 9 retained size 0\n   Instance Field name timestamp type long value 1150458355618\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684181696\n    Ref object java.lang.reflect.Constructor[]#4\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629980 number 10 retained size 0\n   Instance Field name timestamp type long value 1150458355618\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684181400\n    Ref object java.util.jar.Manifest#1\n   References count 1\n   Field manRef of instance 0x64628fc8\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a4b8 number 11 retained size 32\n   Instance Field name timestamp type long value 1150458355618\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684186216\n    Ref object java.lang.StringCoding$StringDecoder#1\n   References count 1\n   Field value of instance 0x64615168\n   Path to nearest GC root\n    Next object java.lang.ThreadLocal$ThreadLocalMap$Entry#1\n    Next object java.lang.ThreadLocal$ThreadLocalMap$Entry[]#1\n    Next object java.lang.ThreadLocal$ThreadLocalMap#1\n    Next object java.lang.Thread#1\n  Instance Id 0x6462a788 number 12 retained size 32\n   Instance Field name timestamp type long value 1150458355618\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684185920\n    Ref object java.util.jar.Manifest#2\n   References count 1\n   Field manRef of instance 0x64629f98\n   Path to nearest GC root\n    Next object java.util.jar.JarFile#2\n    Next object sun.misc.URLClassPath$JarLoader#5\n    Next object java.lang.Object[]#311\n    Next object java.util.ArrayList#5\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c943780 Class java.lang.ref.Reference SuperClass java.lang.Object Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name pending type object value 0\n  Static Field name lock type object value 1684081008\n   Ref object java.lang.ref.Reference$Lock#1\n  Static Field name <classLoader> type object value 0\n  Field name discovered type object\n  Field name next type object\n  Field name queue type object\n  Field name referent type object\n Id 0x68133d58 Class java.lang.ref.Reference[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c944eb8 Class java.lang.ref.Finalizer SuperClass java.lang.ref.FinalReference Instance size 32 Instance count 8 All Instances Size 256\n  Static Field name lock type object value 1684081272\n   Ref object java.lang.Object#3\n  Static Field name unfinalized type object value 1684205672\n   Ref object java.lang.ref.Finalizer#8\n  Static Field name queue type object value 1684081240\n   Ref object java.lang.ref.ReferenceQueue#2\n  Static Field name <classLoader> type object value 0\n  Field name prev type object\n  Field name next type object\n  Instance Id 0x646164e8 number 1 retained size 32\n   Instance Field name prev type object value 1684104480\n    Ref object java.lang.ref.Finalizer#2\n   Instance Field name next type object value 0\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684081240\n    Ref object java.lang.ref.ReferenceQueue#2\n   Instance Field name referent type object value 1684104360\n    Ref object java.io.FileInputStream#1\n   References count 1\n   Field next of instance 0x64616520\n   Path to nearest GC root\n    Next object java.lang.ref.Finalizer#2\n    Next object java.lang.ref.Finalizer#3\n    Next object java.lang.ref.Finalizer#4\n    Next object java.lang.ref.Finalizer#5\n    Next object java.lang.ref.Finalizer#6\n    Next object java.lang.ref.Finalizer#7\n    Next object java.lang.ref.Finalizer#8\n    Next object java.lang.Class#118\n  Instance Id 0x64616520 number 2 retained size 64\n   Instance Field name prev type object value 1684104536\n    Ref object java.lang.ref.Finalizer#3\n   Instance Field name next type object value 1684104424\n    Ref object java.lang.ref.Finalizer#1\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684081240\n    Ref object java.lang.ref.ReferenceQueue#2\n   Instance Field name referent type object value 1684104456\n    Ref object java.io.FileOutputStream#1\n   References count 2\n   Field next of instance 0x64616558\n   Field prev of instance 0x646164e8\n   Path to nearest GC root\n    Next object java.lang.ref.Finalizer#3\n    Next object java.lang.ref.Finalizer#4\n    Next object java.lang.ref.Finalizer#5\n    Next object java.lang.ref.Finalizer#6\n    Next object java.lang.ref.Finalizer#7\n    Next object java.lang.ref.Finalizer#8\n    Next object java.lang.Class#118\n  Instance Id 0x64616558 number 3 retained size 96\n   Instance Field name prev type object value 1684165272\n    Ref object java.lang.ref.Finalizer#4\n   Instance Field name next type object value 1684104480\n    Ref object java.lang.ref.Finalizer#2\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684081240\n    Ref object java.lang.ref.ReferenceQueue#2\n   Instance Field name referent type object value 1684104512\n    Ref object java.io.FileOutputStream#2\n   References count 2\n   Field next of instance 0x64625298\n   Field prev of instance 0x64616520\n   Path to nearest GC root\n    Next object java.lang.ref.Finalizer#4\n    Next object java.lang.ref.Finalizer#5\n    Next object java.lang.ref.Finalizer#6\n    Next object java.lang.ref.Finalizer#7\n    Next object java.lang.ref.Finalizer#8\n    Next object java.lang.Class#118\n  Instance Id 0x64625298 number 4 retained size 128\n   Instance Field name prev type object value 1684180984\n    Ref object java.lang.ref.Finalizer#5\n   Instance Field name next type object value 1684104536\n    Ref object java.lang.ref.Finalizer#3\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684081240\n    Ref object java.lang.ref.ReferenceQueue#2\n   Instance Field name referent type object value 1684165240\n    Ref object java.lang.ClassLoader$NativeLibrary#1\n   References count 2\n   Field next of instance 0x64628ff8\n   Field prev of instance 0x64616558\n   Path to nearest GC root\n    Next object java.lang.ref.Finalizer#5\n    Next object java.lang.ref.Finalizer#6\n    Next object java.lang.ref.Finalizer#7\n    Next object java.lang.ref.Finalizer#8\n    Next object java.lang.Class#118\n  Instance Id 0x64628ff8 number 5 retained size 160\n   Instance Field name prev type object value 1684185032\n    Ref object java.lang.ref.Finalizer#6\n   Instance Field name next type object value 1684165272\n    Ref object java.lang.ref.Finalizer#4\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684081240\n    Ref object java.lang.ref.ReferenceQueue#2\n   Instance Field name referent type object value 1684180936\n    Ref object java.util.jar.JarFile#1\n   References count 2\n   Field next of instance 0x64629fc8\n   Field prev of instance 0x64625298\n   Path to nearest GC root\n    Next object java.lang.ref.Finalizer#6\n    Next object java.lang.ref.Finalizer#7\n    Next object java.lang.ref.Finalizer#8\n    Next object java.lang.Class#118\n  Instance Id 0x64629fc8 number 6 retained size 192\n   Instance Field name prev type object value 1684205608\n    Ref object java.lang.ref.Finalizer#7\n   Instance Field name next type object value 1684180984\n    Ref object java.lang.ref.Finalizer#5\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684081240\n    Ref object java.lang.ref.ReferenceQueue#2\n   Instance Field name referent type object value 1684184984\n    Ref object java.util.jar.JarFile#2\n   References count 2\n   Field next of instance 0x6462f028\n   Field prev of instance 0x64628ff8\n   Path to nearest GC root\n    Next object java.lang.ref.Finalizer#7\n    Next object java.lang.ref.Finalizer#8\n    Next object java.lang.Class#118\n  Instance Id 0x6462f028 number 7 retained size 224\n   Instance Field name prev type object value 1684205672\n    Ref object java.lang.ref.Finalizer#8\n   Instance Field name next type object value 1684185032\n    Ref object java.lang.ref.Finalizer#6\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684081240\n    Ref object java.lang.ref.ReferenceQueue#2\n   Instance Field name referent type object value 1684205592\n    Ref object java.io.FileInputStream#2\n   References count 2\n   Field next of instance 0x6462f068\n   Field prev of instance 0x64629fc8\n   Path to nearest GC root\n    Next object java.lang.ref.Finalizer#8\n    Next object java.lang.Class#118\n  Instance Id 0x6462f068 number 8 retained size 256\n   Instance Field name prev type object value 0\n   Instance Field name next type object value 1684205608\n    Ref object java.lang.ref.Finalizer#7\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684081240\n    Ref object java.lang.ref.ReferenceQueue#2\n   Instance Field name referent type object value 1684205656\n    Ref object java.io.FileInputStream#3\n   References count 2\n   Field unfinalized of Class java.lang.ref.Finalizer\n   Field prev of instance 0x6462f028\n   Path to nearest GC root\n    Next object java.lang.Class#118\n Id 0x6c9443e8 Class java.lang.ref.PhantomReference SuperClass java.lang.ref.Reference Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9440e0 Class java.lang.ref.FinalReference SuperClass java.lang.ref.Reference Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c951070 Class java.lang.reflect.Constructor SuperClass java.lang.reflect.AccessibleObject Instance size 64 Instance count 8 All Instances Size 512\n  Static Field name EMPTY_ANNOTATION_ARRAY type object value 1684099008\n   Ref object java.lang.annotation.Annotation[]#4\n  Static Field name LANGUAGE_MODIFIERS type int value 7\n  Static Field name <classLoader> type object value 0\n  Field name declaredAnnotations type object\n  Field name root type object\n  Field name constructorAccessor type object\n  Field name parameterAnnotations type object\n  Field name annotations type object\n  Field name genericInfo type object\n  Field name signature type object\n  Field name modifiers type int\n  Field name exceptionTypes type object\n  Field name parameterTypes type object\n  Field name slot type int\n  Field name clazz type object\n  Instance Id 0x64614fd0 number 1 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name root type object value 0\n   Instance Field name constructorAccessor type object value 1684099208\n    Ref object sun.reflect.DelegatingConstructorAccessorImpl#1\n   Instance Field name parameterAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 1\n   Instance Field name exceptionTypes type object value 0\n   Instance Field name parameterTypes type object value 1684098992\n    Ref object java.lang.Class[]#1\n   Instance Field name slot type int value 0\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 2\n   Element 0 of array 0x64614fa0\n   Field root of instance 0x64615030\n   Path to nearest GC root\n    Null\n  Instance Id 0x64615030 number 2 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name root type object value 1684099024\n    Ref object java.lang.reflect.Constructor#1\n   Instance Field name constructorAccessor type object value 1684099208\n    Ref object sun.reflect.DelegatingConstructorAccessorImpl#1\n   Instance Field name parameterAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 1\n   Instance Field name exceptionTypes type object value 0\n   Instance Field name parameterTypes type object value 1684098992\n    Ref object java.lang.Class[]#1\n   Instance Field name slot type int value 0\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value true\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Field c of instance 0x64615070\n   Path to nearest GC root\n    Null\n  Instance Id 0x64627928 number 3 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name root type object value 0\n   Instance Field name constructorAccessor type object value 1684175328\n    Ref object sun.reflect.DelegatingConstructorAccessorImpl#2\n   Instance Field name parameterAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 1\n   Instance Field name exceptionTypes type object value 0\n   Instance Field name parameterTypes type object value 1684175128\n    Ref object java.lang.Class[]#2\n   Instance Field name slot type int value 0\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 2\n   Element 0 of array 0x64627908\n   Field root of instance 0x64627988\n   Path to nearest GC root\n    Null\n  Instance Id 0x64627988 number 4 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name root type object value 1684175144\n    Ref object java.lang.reflect.Constructor#3\n   Instance Field name constructorAccessor type object value 1684175328\n    Ref object sun.reflect.DelegatingConstructorAccessorImpl#2\n   Instance Field name parameterAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 1\n   Instance Field name exceptionTypes type object value 0\n   Instance Field name parameterTypes type object value 1684175128\n    Ref object java.lang.Class[]#2\n   Instance Field name slot type int value 0\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value true\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Field c of instance 0x646279c8\n   Path to nearest GC root\n    Null\n  Instance Id 0x646283f0 number 5 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name root type object value 0\n   Instance Field name constructorAccessor type object value 1684178088\n    Ref object sun.reflect.DelegatingConstructorAccessorImpl#3\n   Instance Field name parameterAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 1\n   Instance Field name exceptionTypes type object value 0\n   Instance Field name parameterTypes type object value 1684177888\n    Ref object java.lang.Class[]#3\n   Instance Field name slot type int value 0\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 2\n   Element 0 of array 0x646283d0\n   Field root of instance 0x64628450\n   Path to nearest GC root\n    Null\n  Instance Id 0x64628450 number 6 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name root type object value 1684177904\n    Ref object java.lang.reflect.Constructor#5\n   Instance Field name constructorAccessor type object value 1684178088\n    Ref object sun.reflect.DelegatingConstructorAccessorImpl#3\n   Instance Field name parameterAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 1\n   Instance Field name exceptionTypes type object value 0\n   Instance Field name parameterTypes type object value 1684177888\n    Ref object java.lang.Class[]#3\n   Instance Field name slot type int value 0\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value true\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Field c of instance 0x64628490\n   Path to nearest GC root\n    Null\n  Instance Id 0x646292e0 number 7 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name root type object value 0\n   Instance Field name constructorAccessor type object value 1684181912\n    Ref object sun.reflect.DelegatingConstructorAccessorImpl#4\n   Instance Field name parameterAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 1\n   Instance Field name exceptionTypes type object value 0\n   Instance Field name parameterTypes type object value 1684181712\n    Ref object java.lang.Class[]#4\n   Instance Field name slot type int value 0\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 2\n   Element 0 of array 0x646292c0\n   Field root of instance 0x64629340\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629340 number 8 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name root type object value 1684181728\n    Ref object java.lang.reflect.Constructor#7\n   Instance Field name constructorAccessor type object value 1684181912\n    Ref object sun.reflect.DelegatingConstructorAccessorImpl#4\n   Instance Field name parameterAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 1\n   Instance Field name exceptionTypes type object value 0\n   Instance Field name parameterTypes type object value 1684181712\n    Ref object java.lang.Class[]#4\n   Instance Field name slot type int value 0\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value true\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Field c of instance 0x64629380\n   Path to nearest GC root\n    Null\n Id 0x68133ae0 Class java.lang.reflect.Constructor[] SuperClass java.lang.Object Instance size -1 Instance count 4 All Instances Size 64\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64614fa0 number 1 retained size 0\n   References count 1\n   Field referent of instance 0x64615010\n   Path to nearest GC root\n    Null\n  Instance Id 0x64627908 number 2 retained size 0\n   References count 1\n   Field referent of instance 0x64627968\n   Path to nearest GC root\n    Null\n  Instance Id 0x646283d0 number 3 retained size 0\n   References count 1\n   Field referent of instance 0x64628430\n   Path to nearest GC root\n    Null\n  Instance Id 0x646292c0 number 4 retained size 0\n   References count 1\n   Field referent of instance 0x64629320\n   Path to nearest GC root\n    Null\n Id 0x6c94fbe0 Class java.lang.reflect.Method SuperClass java.lang.reflect.AccessibleObject Instance size 80 Instance count 1 All Instances Size 80\n  Static Field name EMPTY_ANNOTATION_ARRAY type object value 1684080992\n   Ref object java.lang.annotation.Annotation[]#2\n  Static Field name LANGUAGE_MODIFIERS type int value 1343\n  Static Field name <classLoader> type object value 0\n  Field name declaredAnnotations type object\n  Field name securityCheckTargetClassCache type object\n  Field name root type object\n  Field name methodAccessor type object\n  Field name annotationDefault type object\n  Field name parameterAnnotations type object\n  Field name annotations type object\n  Field name genericInfo type object\n  Field name signature type object\n  Field name modifiers type int\n  Field name exceptionTypes type object\n  Field name parameterTypes type object\n  Field name returnType type object\n  Field name name type object\n  Field name slot type int\n  Field name clazz type object\n  Instance Id 0x64630d08 number 1 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name methodAccessor type object value 0\n   Instance Field name annotationDefault type object value 0\n   Instance Field name parameterAnnotations type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 9\n   Instance Field name exceptionTypes type object value 0\n   Instance Field name parameterTypes type object value 1684212984\n    Ref object java.lang.Class[]#8\n   Instance Field name returnType type object value 1746076432\n    Ref object java.lang.Class#9\n   Instance Field name name type object value 0\n   Instance Field name slot type int value 1\n   Instance Field name clazz type object value 1746122288\n    Ref object java.lang.Class#7\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 0\n   Path to nearest GC root\n    Null\n Id 0x6c94c988 Class java.lang.reflect.AccessibleObject SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name reflectionFactory type object value 1684080984\n   Ref object sun.reflect.ReflectionFactory#1\n  Static Field name ACCESS_PERMISSION type object value 1684080696\n   Ref object java.lang.reflect.ReflectPermission#1\n  Static Field name <classLoader> type object value 0\n  Field name override type boolean\n  Field name securityCheckCache type object\n Id 0x68133528 Class java.lang.reflect.AccessibleObject[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c95f1b8 Class java.lang.StringBuffer SuperClass java.lang.AbstractStringBuilder Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name serialPersistentFields type object value 1684183648\n   Ref object java.io.ObjectStreamField[]#5\n  Static Field name serialVersionUID type long value 3388685877147921107\n  Static Field name <classLoader> type object value 0\n Id 0x6c94e670 Class java.lang.reflect.Field SuperClass java.lang.reflect.AccessibleObject Instance size 72 Instance count 31 All Instances Size 2232\n  Static Field name EMPTY_ANNOTATION_ARRAY type object value 1684098536\n   Ref object java.lang.annotation.Annotation[]#3\n  Static Field name <classLoader> type object value 0\n  Field name declaredAnnotations type object\n  Field name securityCheckTargetClassCache type object\n  Field name root type object\n  Field name overrideFieldAccessor type object\n  Field name fieldAccessor type object\n  Field name annotations type object\n  Field name genericInfo type object\n  Field name signature type object\n  Field name modifiers type int\n  Field name type type object\n  Field name name type object\n  Field name slot type int\n  Field name clazz type object\n  Instance Id 0x64614df8 number 1 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 26\n   Instance Field name type type object value 1746076240\n    Ref object java.lang.Class#7\n   Instance Field name name type object value 0\n   Instance Field name slot type int value 0\n   Instance Field name clazz type object value 1746088544\n    Ref object java.lang.Class#435\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 0 of array 0x64614dc8\n   Path to nearest GC root\n    Null\n  Instance Id 0x64614e40 number 2 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 26\n   Instance Field name type type object value 0\n   Instance Field name name type object value 1746090256\n    Ref object java.lang.String#260\n   Instance Field name slot type int value 7\n   Instance Field name clazz type object value 1746088544\n    Ref object java.lang.Class#435\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 1 of array 0x64614dc8\n   Path to nearest GC root\n    Null\n  Instance Id 0x64614e88 number 3 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 26\n   Instance Field name type type object value 1746076240\n    Ref object java.lang.Class#7\n   Instance Field name name type object value 1746090304\n    Ref object java.lang.String#261\n   Instance Field name slot type int value 14\n   Instance Field name clazz type object value 1746088544\n    Ref object java.lang.Class#435\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 2 of array 0x64614dc8\n   Path to nearest GC root\n    Null\n  Instance Id 0x64614ed0 number 4 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 66\n   Instance Field name type type object value 1746075664\n    Ref object java.lang.Class#1\n   Instance Field name name type object value 0\n   Instance Field name slot type int value 21\n   Instance Field name clazz type object value 1746088544\n    Ref object java.lang.Class#435\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 3 of array 0x64614dc8\n   Path to nearest GC root\n    Null\n  Instance Id 0x646165c0 number 5 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 10\n   Instance Field name type type object value 1746075664\n    Ref object java.lang.Class#1\n   Instance Field name name type object value 1746092320\n    Ref object java.lang.String#264\n   Instance Field name slot type int value 0\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 0 of array 0x64616598\n   Path to nearest GC root\n    Null\n  Instance Id 0x64616608 number 6 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 68\n   Instance Field name type type object value 0\n   Instance Field name name type object value 0\n   Instance Field name slot type int value 7\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 1 of array 0x64616598\n   Path to nearest GC root\n    Null\n  Instance Id 0x64616650 number 7 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 1684104856\n    Ref object java.lang.String#99\n   Instance Field name modifiers type int value 26\n   Instance Field name type type object value 0\n   Instance Field name name type object value 1746092392\n    Ref object java.lang.String#265\n   Instance Field name slot type int value 14\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 2 of array 0x64616598\n   Path to nearest GC root\n    Null\n  Instance Id 0x64616770 number 8 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 4\n   Instance Field name type type object value 1746075664\n    Ref object java.lang.Class#1\n   Instance Field name name type object value 0\n   Instance Field name slot type int value 21\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 3 of array 0x64616598\n   Path to nearest GC root\n    Null\n  Instance Id 0x646167b8 number 9 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 4\n   Instance Field name type type object value 1746075664\n    Ref object java.lang.Class#1\n   Instance Field name name type object value 1746092448\n    Ref object java.lang.String#266\n   Instance Field name slot type int value 28\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 4 of array 0x64616598\n   Path to nearest GC root\n    Null\n  Instance Id 0x64616800 number 10 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 4\n   Instance Field name type type object value 1746075664\n    Ref object java.lang.Class#1\n   Instance Field name name type object value 1746092496\n    Ref object java.lang.String#267\n   Instance Field name slot type int value 35\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 5 of array 0x64616598\n   Path to nearest GC root\n    Null\n  Instance Id 0x64616848 number 11 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 4\n   Instance Field name type type object value 1746075664\n    Ref object java.lang.Class#1\n   Instance Field name name type object value 1746092552\n    Ref object java.lang.String#268\n   Instance Field name slot type int value 42\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 6 of array 0x64616598\n   Path to nearest GC root\n    Null\n  Instance Id 0x646265b0 number 12 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 26\n   Instance Field name type type object value 1746076240\n    Ref object java.lang.Class#7\n   Instance Field name name type object value 0\n   Instance Field name slot type int value 0\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 0 of array 0x64626578\n   Path to nearest GC root\n    Null\n  Instance Id 0x646265f8 number 13 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 194\n   Instance Field name type type object value 0\n   Instance Field name name type object value 0\n   Instance Field name slot type int value 7\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 1 of array 0x64626578\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626640 number 14 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 194\n   Instance Field name type type object value 0\n   Instance Field name name type object value 0\n   Instance Field name slot type int value 14\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 2 of array 0x64626578\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626688 number 15 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 66\n   Instance Field name type type object value 1746075664\n    Ref object java.lang.Class#1\n   Instance Field name name type object value 0\n   Instance Field name slot type int value 21\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 3 of array 0x64626578\n   Path to nearest GC root\n    Null\n  Instance Id 0x646266d0 number 16 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 24\n   Instance Field name type type object value 1746076240\n    Ref object java.lang.Class#7\n   Instance Field name name type object value 1746115688\n    Ref object java.lang.String#271\n   Instance Field name slot type int value 28\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 4 of array 0x64626578\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626718 number 17 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 26\n   Instance Field name type type object value 0\n   Instance Field name name type object value 1746090256\n    Ref object java.lang.String#260\n   Instance Field name slot type int value 35\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 5 of array 0x64626578\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626760 number 18 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 26\n   Instance Field name type type object value 1746076240\n    Ref object java.lang.Class#7\n   Instance Field name name type object value 1746115776\n    Ref object java.lang.String#272\n   Instance Field name slot type int value 42\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 6 of array 0x64626578\n   Path to nearest GC root\n    Null\n  Instance Id 0x646267a8 number 19 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 26\n   Instance Field name type type object value 1746076240\n    Ref object java.lang.Class#7\n   Instance Field name name type object value 1746115840\n    Ref object java.lang.String#273\n   Instance Field name slot type int value 49\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 7 of array 0x64626578\n   Path to nearest GC root\n    Null\n  Instance Id 0x646267f0 number 20 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 26\n   Instance Field name type type object value 1746076240\n    Ref object java.lang.Class#7\n   Instance Field name name type object value 1746115896\n    Ref object java.lang.String#274\n   Instance Field name slot type int value 56\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 8 of array 0x64626578\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626838 number 21 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 26\n   Instance Field name type type object value 1746076240\n    Ref object java.lang.Class#7\n   Instance Field name name type object value 1746115952\n    Ref object java.lang.String#275\n   Instance Field name slot type int value 63\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 9 of array 0x64626578\n   Path to nearest GC root\n    Null\n  Instance Id 0x646268d8 number 22 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 24\n   Instance Field name type type object value 1746075664\n    Ref object java.lang.Class#1\n   Instance Field name name type object value 1746116024\n    Ref object java.lang.String#276\n   Instance Field name slot type int value 0\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 0 of array 0x646268a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626920 number 23 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 24\n   Instance Field name type type object value 1746075664\n    Ref object java.lang.Class#1\n   Instance Field name name type object value 1746116080\n    Ref object java.lang.String#277\n   Instance Field name slot type int value 7\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 1 of array 0x646268a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626968 number 24 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 24\n   Instance Field name type type object value 1746075664\n    Ref object java.lang.Class#1\n   Instance Field name name type object value 1746116128\n    Ref object java.lang.String#278\n   Instance Field name slot type int value 14\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 2 of array 0x646268a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x646269b0 number 25 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 24\n   Instance Field name type type object value 0\n   Instance Field name name type object value 1746116184\n    Ref object java.lang.String#279\n   Instance Field name slot type int value 21\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 3 of array 0x646268a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x646269f8 number 26 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 24\n   Instance Field name type type object value 0\n   Instance Field name name type object value 1746116232\n    Ref object java.lang.String#280\n   Instance Field name slot type int value 28\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 4 of array 0x646268a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626a40 number 27 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 64\n   Instance Field name type type object value 1746075664\n    Ref object java.lang.Class#1\n   Instance Field name name type object value 0\n   Instance Field name slot type int value 35\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 5 of array 0x646268a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626a88 number 28 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 64\n   Instance Field name type type object value 0\n   Instance Field name name type object value 1746116288\n    Ref object java.lang.String#281\n   Instance Field name slot type int value 42\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 6 of array 0x646268a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626ad0 number 29 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 64\n   Instance Field name type type object value 0\n   Instance Field name name type object value 1746116336\n    Ref object java.lang.String#282\n   Instance Field name slot type int value 49\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 7 of array 0x646268a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626b18 number 30 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 64\n   Instance Field name type type object value 0\n   Instance Field name name type object value 1746116384\n    Ref object java.lang.String#283\n   Instance Field name slot type int value 56\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 8 of array 0x646268a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626b60 number 31 retained size 0\n   Instance Field name declaredAnnotations type object value 0\n   Instance Field name securityCheckTargetClassCache type object value 0\n   Instance Field name root type object value 0\n   Instance Field name overrideFieldAccessor type object value 0\n   Instance Field name fieldAccessor type object value 0\n   Instance Field name annotations type object value 0\n   Instance Field name genericInfo type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name modifiers type int value 0\n   Instance Field name type type object value 0\n   Instance Field name name type object value 1746116432\n    Ref object java.lang.String#284\n   Instance Field name slot type int value 63\n   Instance Field name clazz type object value 0\n   Instance Field name override type boolean value false\n   Instance Field name securityCheckCache type object value 0\n   References count 1\n   Element 9 of array 0x646268a0\n   Path to nearest GC root\n    Null\n Id 0x681338b0 Class java.lang.reflect.Field[] SuperClass java.lang.Object Instance size -1 Instance count 4 All Instances Size 184\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64614dc8 number 1 retained size 0\n   References count 1\n   Field referent of instance 0x64614f18\n   Path to nearest GC root\n    Null\n  Instance Id 0x64616598 number 2 retained size 0\n   References count 1\n   Field referent of instance 0x64616890\n   Path to nearest GC root\n    Null\n  Instance Id 0x64626578 number 3 retained size 0\n   References count 1\n   Field referent of instance 0x64626880\n   Path to nearest GC root\n    Null\n  Instance Id 0x646268a0 number 4 retained size 0\n   References count 1\n   Field referent of instance 0x64626ba8\n   Path to nearest GC root\n    Null\n Id 0x6c9411b0 Class java.security.AccessControlContext SuperClass java.lang.Object Instance size 24 Instance count 9 All Instances Size 216\n  Static Field name debug type object value 0\n  Static Field name debugInit type boolean value false\n  Static Field name <classLoader> type object value 0\n  Field name combiner type object\n  Field name privilegedContext type object\n  Field name isPrivileged type boolean\n  Field name context type object\n  Instance Id 0x64610820 number 1 retained size 24\n   Instance Field name combiner type object value 0\n   Instance Field name privilegedContext type object value 0\n   Instance Field name isPrivileged type boolean value false\n   Instance Field name context type object value 0\n   References count 1\n   Field inheritedAccessControlContext of instance 0x64610790\n   Path to nearest GC root\n    Next object java.lang.Thread#1\n  Instance Id 0x64610a20 number 2 retained size 24\n   Instance Field name combiner type object value 0\n   Instance Field name privilegedContext type object value 0\n   Instance Field name isPrivileged type boolean value false\n   Instance Field name context type object value 0\n   References count 1\n   Field inheritedAccessControlContext of instance 0x64610978\n   Path to nearest GC root\n    Next object java.lang.ref.Reference$ReferenceHandler#1\n  Instance Id 0x64610b18 number 3 retained size 24\n   Instance Field name combiner type object value 0\n   Instance Field name privilegedContext type object value 0\n   Instance Field name isPrivileged type boolean value false\n   Instance Field name context type object value 0\n   References count 1\n   Field inheritedAccessControlContext of instance 0x64610a80\n   Path to nearest GC root\n    Next object java.lang.ref.Finalizer$FinalizerThread#1\n  Instance Id 0x646284c0 number 4 retained size 24\n   Instance Field name combiner type object value 0\n   Instance Field name privilegedContext type object value 0\n   Instance Field name isPrivileged type boolean value true\n   Instance Field name context type object value 0\n   References count 1\n   Field acc of instance 0x64626138\n   Path to nearest GC root\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628a70 number 5 retained size 24\n   Instance Field name combiner type object value 0\n   Instance Field name privilegedContext type object value 0\n   Instance Field name isPrivileged type boolean value true\n   Instance Field name context type object value 0\n   References count 1\n   Field acc of instance 0x64628620\n   Path to nearest GC root\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628b30 number 6 retained size 24\n   Instance Field name combiner type object value 0\n   Instance Field name privilegedContext type object value 0\n   Instance Field name isPrivileged type boolean value false\n   Instance Field name context type object value 0\n   References count 1\n   Field inheritedAccessControlContext of instance 0x64628a88\n   Path to nearest GC root\n    Next object java.lang.Thread#2\n  Instance Id 0x64628bf0 number 7 retained size 0\n   Instance Field name combiner type object value 0\n   Instance Field name privilegedContext type object value 0\n   Instance Field name isPrivileged type boolean value false\n   Instance Field name context type object value 0\n   References count 1\n   Field inheritedAccessControlContext of instance 0x64628b48\n   Path to nearest GC root\n    Null\n  Instance Id 0x64628cb8 number 8 retained size 0\n   Instance Field name combiner type object value 0\n   Instance Field name privilegedContext type object value 0\n   Instance Field name isPrivileged type boolean value false\n   Instance Field name context type object value 0\n   References count 1\n   Field inheritedAccessControlContext of instance 0x64628c08\n   Path to nearest GC root\n    Null\n  Instance Id 0x64630e68 number 9 retained size 24\n   Instance Field name combiner type object value 0\n   Instance Field name privilegedContext type object value 0\n   Instance Field name isPrivileged type boolean value false\n   Instance Field name context type object value 0\n   References count 1\n   Field inheritedAccessControlContext of instance 0x64630d78\n   Path to nearest GC root\n    Next object java.lang.Thread#5\n Id 0x6c939960 Class java.lang.CharSequence SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x68131fb0 Class java.lang.CharSequence[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9d2f10 Class java.io.Reader SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name maxSkipBufferSize type int value 8192\n  Static Field name <classLoader> type object value 0\n  Field name skipBuffer type object\n  Field name lock type object\n Id 0x6c9ad590 Class java.io.OutputStream SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c940590 Class java.security.ProtectionDomain SuperClass java.lang.Object Instance size 32 Instance count 1 All Instances Size 32\n  Static Field name debug type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name staticPermissions type boolean\n  Field name hasAllPerm type boolean\n  Field name permissions type object\n  Field name principals type object\n  Field name classloader type object\n  Field name codesource type object\n  Instance Id 0x64630c58 number 1 retained size 632\n   Instance Field name staticPermissions type boolean value false\n   Instance Field name hasAllPerm type boolean value false\n   Instance Field name permissions type object value 1684211752\n    Ref object java.security.Permissions#1\n   Instance Field name principals type object value 1684212856\n    Ref object java.security.Principal[]#1\n   Instance Field name classloader type object value 1684178464\n    Ref object sun.misc.Launcher$AppClassLoader#1\n   Instance Field name codesource type object value 1684211632\n    Ref object java.security.CodeSource#1\n   References count 2\n   Field value of instance 0x64630c88\n   Field key of instance 0x64630ce0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6cc36948 Class java.io.ByteArrayInputStream SuperClass java.io.InputStream Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name count type int\n  Field name mark type int\n  Field name pos type int\n  Field name buf type object\n Id 0x6c9d3ab8 Class java.io.BufferedReader SuperClass java.io.Reader Instance size 48 Instance count 0 All Instances Size 0\n  Static Field name defaultExpectedLineLength type int value 80\n  Static Field name defaultCharBufferSize type int value 8192\n  Static Field name UNMARKED type int value -1\n  Static Field name INVALIDATED type int value -2\n  Static Field name <classLoader> type object value 0\n  Field name markedSkipLF type boolean\n  Field name skipLF type boolean\n  Field name readAheadLimit type int\n  Field name markedChar type int\n  Field name nextChar type int\n  Field name nChars type int\n  Field name cb type object\n  Field name in type object\n Id 0x6c9ac770 Class java.io.FileInputStream SuperClass java.io.InputStream Instance size 16 Instance count 3 All Instances Size 48\n  Static Field name <classLoader> type object value 0\n  Field name channel type object\n  Field name fd type object\n  Instance Id 0x646164a8 number 1 retained size 16\n   Instance Field name channel type object value 0\n   Instance Field name fd type object value 1684104376\n    Ref object java.io.FileDescriptor#1\n   References count 2\n   Field in of instance 0x646168b0\n   Field referent of instance 0x646164e8\n   Path to nearest GC root\n    Next object java.io.BufferedInputStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x6462f018 number 2 retained size 32\n   Instance Field name channel type object value 0\n   Instance Field name fd type object value 1684205640\n    Ref object java.io.FileDescriptor#4\n   References count 2\n   Field randomIn of instance 0x6462efc8\n   Field referent of instance 0x6462f028\n   Path to nearest GC root\n    Next object sun.security.provider.NativePRNG$RandomIO#1\n    Next object java.lang.Class#339\n  Instance Id 0x6462f058 number 3 retained size 32\n   Instance Field name channel type object value 0\n   Instance Field name fd type object value 1684205704\n    Ref object java.io.FileDescriptor#5\n   References count 2\n   Field urandomIn of instance 0x6462efc8\n   Field referent of instance 0x6462f068\n   Path to nearest GC root\n    Next object sun.security.provider.NativePRNG$RandomIO#1\n    Next object java.lang.Class#339\n Id 0x6c9398a0 Class java.io.Serializable SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c96bbf8 Class java.io.Serializable[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c95a598 Class java.util.Vector SuperClass java.util.AbstractList Instance size 24 Instance count 8 All Instances Size 192\n  Static Field name serialVersionUID type long value -2767605614048989439\n  Static Field name <classLoader> type object value 0\n  Field name capacityIncrement type int\n  Field name elementCount type int\n  Field name elementData type object\n  Instance Id 0x64610850 number 1 retained size 80\n   Instance Field name capacityIncrement type int value 0\n   Instance Field name elementCount type int value 1\n   Instance Field name elementData type object value 1684080744\n    Ref object java.lang.Object[]#9\n   Instance Field name modCount type int value 1\n   References count 1\n   Field loadedLibraryNames of Class java.lang.ClassLoader\n   Path to nearest GC root\n    Next object java.lang.Class#101\n  Instance Id 0x646108a0 number 2 retained size 80\n   Instance Field name capacityIncrement type int value 0\n   Instance Field name elementCount type int value 1\n   Instance Field name elementData type object value 1684080824\n    Ref object java.lang.Object[]#10\n   Instance Field name modCount type int value 1\n   References count 1\n   Field systemNativeLibraries of Class java.lang.ClassLoader\n   Path to nearest GC root\n    Next object java.lang.Class#101\n  Instance Id 0x64628028 number 3 retained size 80\n   Instance Field name capacityIncrement type int value 0\n   Instance Field name elementCount type int value 0\n   Instance Field name elementData type object value 1684176960\n    Ref object java.lang.Object[]#302\n   Instance Field name modCount type int value 0\n   References count 1\n   Field classes of instance 0x64626138\n   Path to nearest GC root\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628180 number 4 retained size 80\n   Instance Field name capacityIncrement type int value 0\n   Instance Field name elementCount type int value 0\n   Instance Field name elementData type object value 1684177304\n    Ref object java.lang.Object[]#303\n   Instance Field name modCount type int value 0\n   References count 1\n   Field nativeLibraries of instance 0x64626138\n   Path to nearest GC root\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646286c8 number 5 retained size 80\n   Instance Field name capacityIncrement type int value 0\n   Instance Field name elementCount type int value 1\n   Instance Field name elementData type object value 1684178656\n    Ref object java.lang.Object[]#307\n   Instance Field name modCount type int value 1\n   References count 1\n   Field classes of instance 0x64628620\n   Path to nearest GC root\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628818 number 6 retained size 80\n   Instance Field name capacityIncrement type int value 0\n   Instance Field name elementCount type int value 0\n   Instance Field name elementData type object value 1684178992\n    Ref object java.lang.Object[]#308\n   Instance Field name modCount type int value 0\n   References count 1\n   Field nativeLibraries of instance 0x64628620\n   Path to nearest GC root\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629018 number 7 retained size 0\n   Instance Field name capacityIncrement type int value 0\n   Instance Field name elementCount type int value 0\n   Instance Field name elementData type object value 1684181040\n    Ref object java.lang.Object[]#312\n   Instance Field name modCount type int value 0\n   References count 1\n   Field inflaters of instance 0x64628fc8\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629fe8 number 8 retained size 80\n   Instance Field name capacityIncrement type int value 0\n   Instance Field name elementCount type int value 0\n   Instance Field name elementData type object value 1684185088\n    Ref object java.lang.Object[]#315\n   Instance Field name modCount type int value 0\n   References count 1\n   Field inflaters of instance 0x64629f98\n   Path to nearest GC root\n    Next object java.util.jar.JarFile#2\n    Next object sun.misc.URLClassPath$JarLoader#5\n    Next object java.lang.Object[]#311\n    Next object java.util.ArrayList#5\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c95a280 Class java.util.AbstractList SuperClass java.util.AbstractCollection Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name modCount type int\n Id 0x6c94c1c0 Class java.util.Properties SuperClass java.util.Hashtable Instance size 48 Instance count 2 All Instances Size 96\n  Static Field name hexDigit type object value 1684081472\n   Ref object char[]#10\n  Static Field name serialVersionUID type long value 4112578634029874840\n  Static Field name <classLoader> type object value 0\n  Field name defaults type object\n  Instance Id 0x64610b70 number 1 retained size 8104\n   Instance Field name defaults type object value 0\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name modCount type int value 54\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 71\n   Instance Field name count type int value 49\n   Instance Field name table type object value 1684101216\n    Ref object java.util.Hashtable$Entry[]#1\n   References count 1\n   Field props of Class java.lang.System\n   Path to nearest GC root\n    Next object java.lang.Class#85\n  Instance Id 0x6462bc60 number 2 retained size 4472\n   Instance Field name defaults type object value 0\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name modCount type int value 25\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 35\n   Instance Field name count type int value 23\n   Instance Field name table type object value 1684195896\n    Ref object java.util.Hashtable$Entry[]#10\n   References count 1\n   Field props of Class java.security.Security\n   Path to nearest GC root\n    Next object java.lang.Class#341\n Id 0x6c94bf20 Class java.util.Hashtable SuperClass java.util.Dictionary Instance size 40 Instance count 9 All Instances Size 360\n  Static Field name emptyIterator type object value 1684081464\n   Ref object java.util.Hashtable$EmptyIterator#1\n  Static Field name emptyEnumerator type object value 1684081456\n   Ref object java.util.Hashtable$EmptyEnumerator#1\n  Static Field name ENTRIES type int value 2\n  Static Field name VALUES type int value 1\n  Static Field name KEYS type int value 0\n  Static Field name serialVersionUID type long value 1421746759512286392\n  Static Field name <classLoader> type object value 0\n  Field name values type object\n  Field name entrySet type object\n  Field name keySet type object\n  Field name modCount type int\n  Field name loadFactor type float\n  Field name threshold type int\n  Field name count type int\n  Field name table type object\n  Instance Id 0x646252c0 number 1 retained size 144\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name modCount type int value 3\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 3\n   Instance Field name count type int value 3\n   Instance Field name table type object value 1684165352\n    Ref object java.util.Hashtable$Entry[]#2\n   References count 1\n   Field handlers of Class sun.misc.Signal\n   Path to nearest GC root\n    Next object java.lang.Class#145\n  Instance Id 0x64625308 number 2 retained size 192\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name modCount type int value 3\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 3\n   Instance Field name count type int value 3\n   Instance Field name table type object value 1684165424\n    Ref object java.util.Hashtable$Entry[]#3\n   References count 1\n   Field signals of Class sun.misc.Signal\n   Path to nearest GC root\n    Next object java.lang.Class#145\n  Instance Id 0x64626440 number 3 retained size 120\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name modCount type int value 1\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 8\n   Instance Field name count type int value 1\n   Instance Field name table type object value 1684169832\n    Ref object java.util.Hashtable$Entry[]#4\n   References count 1\n   Field handlers of Class java.net.URL\n   Path to nearest GC root\n    Next object java.lang.Class#273\n  Instance Id 0x64627fc8 number 4 retained size 96\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 8\n   Instance Field name count type int value 0\n   Instance Field name table type object value 1684176880\n    Ref object java.util.Hashtable$Entry[]#5\n   References count 1\n   Field package2certs of instance 0x64626138\n   Path to nearest GC root\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628668 number 5 retained size 144\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name modCount type int value 1\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 8\n   Instance Field name count type int value 1\n   Instance Field name table type object value 1684178576\n    Ref object java.util.Hashtable$Entry[]#6\n   References count 1\n   Field package2certs of instance 0x64628620\n   Path to nearest GC root\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646297d0 number 6 retained size 0\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 8\n   Instance Field name count type int value 0\n   Instance Field name table type object value 1684183032\n    Ref object java.util.Hashtable$Entry[]#7\n   References count 1\n   Field sigFileSigners of instance 0x646297a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629830 number 7 retained size 0\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 8\n   Instance Field name count type int value 0\n   Instance Field name table type object value 1684183128\n    Ref object java.util.Hashtable$Entry[]#8\n   References count 1\n   Field verifiedSigners of instance 0x646297a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629890 number 8 retained size 0\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 8\n   Instance Field name count type int value 0\n   Instance Field name table type object value 1684183224\n    Ref object java.util.Hashtable$Entry[]#9\n   References count 1\n   Field sigFileData of instance 0x646297a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x646308b8 number 9 retained size 96\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 8\n   Instance Field name count type int value 0\n   Instance Field name table type object value 1684211936\n    Ref object java.util.Hashtable$Entry[]#12\n   References count 1\n   Field handlers of Class java.net.URLConnection\n   Path to nearest GC root\n    Next object java.lang.Class#206\n Id 0x6c9cbd20 Class java.lang.Compiler SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9c9b80 Class sun.misc.Signal SuperClass java.lang.Object Instance size 16 Instance count 3 All Instances Size 48\n  Static Field name signals type object value 1684165384\n   Ref object java.util.Hashtable#2\n  Static Field name handlers type object value 1684165312\n   Ref object java.util.Hashtable#1\n  Static Field name <classLoader> type object value 0\n  Field name name type object\n  Field name number type int\n  Instance Id 0x64625350 number 1 retained size 16\n   Instance Field name name type object value 0\n   Instance Field name number type int value 1\n   References count 2\n   Field value of instance 0x646255b0\n   Field key of instance 0x646255c8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#50\n    Next object java.util.Hashtable$Entry[]#3\n    Next object java.util.Hashtable#2\n    Next object java.lang.Class#145\n  Instance Id 0x64625600 number 2 retained size 16\n   Instance Field name name type object value 0\n   Instance Field name number type int value 2\n   References count 2\n   Field value of instance 0x64625620\n   Field key of instance 0x64625638\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#52\n    Next object java.util.Hashtable$Entry[]#3\n    Next object java.util.Hashtable#2\n    Next object java.lang.Class#145\n  Instance Id 0x64625650 number 3 retained size 16\n   Instance Field name name type object value 0\n   Instance Field name number type int value 15\n   References count 2\n   Field value of instance 0x64625670\n   Field key of instance 0x64625688\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#54\n    Next object java.util.Hashtable$Entry[]#3\n    Next object java.util.Hashtable#2\n    Next object java.lang.Class#145\n Id 0x6c96c470 Class java.lang.ArithmeticException SuperClass java.lang.RuntimeException Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c942308 Class java.lang.ArrayStoreException SuperClass java.lang.RuntimeException Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c941fd8 Class java.lang.ClassCastException SuperClass java.lang.RuntimeException Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c941648 Class java.lang.ClassNotFoundException SuperClass java.lang.Exception Instance size 32 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value 9176873029745254542\n  Static Field name <classLoader> type object value 0\n  Field name ex type object\n Id 0x6c942fc8 Class java.lang.IllegalMonitorStateException SuperClass java.lang.RuntimeException Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6ca23ae8 Class java.lang.InterruptedException SuperClass java.lang.Exception Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c941ac0 Class java.lang.LinkageError SuperClass java.lang.Error Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c96c128 Class java.lang.NullPointerException SuperClass java.lang.RuntimeException Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c93fb30 Class java.lang.RuntimeException SuperClass java.lang.Exception Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value -7034897190745766939\n  Static Field name <classLoader> type object value 0\n Id 0x6c93f710 Class java.lang.Exception SuperClass java.lang.Throwable Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value -3387516993124229948\n  Static Field name <classLoader> type object value 0\n Id 0x6c9f4670 Class java.security.PrivilegedActionException SuperClass java.lang.Exception Instance size 32 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value 4724086851538908602\n  Static Field name <classLoader> type object value 0\n  Field name exception type object\n Id 0x6c93f030 Class java.lang.Error SuperClass java.lang.Throwable Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value 4980196508277280342\n  Static Field name <classLoader> type object value 0\n Id 0x681306d0 Class java.lang.Error[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9de8d8 Class java.lang.IncompatibleClassChangeError SuperClass java.lang.LinkageError Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c941ca8 Class java.lang.NoClassDefFoundError SuperClass java.lang.LinkageError Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9dec38 Class java.lang.NoSuchMethodError SuperClass java.lang.IncompatibleClassChangeError Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c942968 Class java.lang.OutOfMemoryError SuperClass java.lang.VirtualMachineError Instance size 24 Instance count 4 All Instances Size 96\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x68130af8 number 1 retained size 0\n   Instance Field name stackTrace type object value 0\n   Instance Field name cause type object value 0\n   Instance Field name detailMessage type object value 0\n   Instance Field name backtrace type object value 1684079016\n    Ref object java.lang.Object[]#1\n   References count 1\n   Element 0 of array 0x64610188\n   Path to nearest GC root\n    Null\n  Instance Id 0x68130b10 number 2 retained size 0\n   Instance Field name stackTrace type object value 0\n   Instance Field name cause type object value 0\n   Instance Field name detailMessage type object value 0\n   Instance Field name backtrace type object value 1684079264\n    Ref object java.lang.Object[]#3\n   References count 1\n   Element 1 of array 0x64610188\n   Path to nearest GC root\n    Null\n  Instance Id 0x68130b28 number 3 retained size 0\n   Instance Field name stackTrace type object value 0\n   Instance Field name cause type object value 0\n   Instance Field name detailMessage type object value 0\n   Instance Field name backtrace type object value 1684079512\n    Ref object java.lang.Object[]#5\n   References count 1\n   Element 2 of array 0x64610188\n   Path to nearest GC root\n    Null\n  Instance Id 0x68130b40 number 4 retained size 0\n   Instance Field name stackTrace type object value 0\n   Instance Field name cause type object value 0\n   Instance Field name detailMessage type object value 0\n   Instance Field name backtrace type object value 1684079760\n    Ref object java.lang.Object[]#7\n   References count 1\n   Element 3 of array 0x64610188\n   Path to nearest GC root\n    Null\n Id 0x68130a98 Class java.lang.OutOfMemoryError[] SuperClass java.lang.Object Instance size -1 Instance count 1 All Instances Size 32\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610188 number 1 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n Id 0x6c95f918 Class java.lang.StackTraceElement SuperClass java.lang.Object Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value 6992337162326171013\n  Static Field name <classLoader> type object value 0\n  Field name lineNumber type int\n  Field name fileName type object\n  Field name methodName type object\n  Field name declaringClass type object\n Id 0x681313c0 Class java.lang.StackTraceElement[] SuperClass java.lang.Object Instance size -1 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610650 number 1 retained size 16\n   References count 1\n   Field EMPTY_STACK_TRACE of Class java.lang.Thread\n   Path to nearest GC root\n    Next object java.lang.Class#92\n Id 0x6c942c98 Class java.lang.StackOverflowError SuperClass java.lang.VirtualMachineError Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c942638 Class java.lang.VirtualMachineError SuperClass java.lang.Error Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x681308b8 Class java.lang.VirtualMachineError[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cba8a60 Class java.lang.StrictMath SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name negativeZeroDoubleBits type long value -9223372036854775808\n  Static Field name negativeZeroFloatBits type long value -2147483648\n  Static Field name randomNumberGenerator type object value 0\n  Static Field name PI type double value 3.141592653589793\n  Static Field name E type double value 2.718281828459045\n  Static Field name <classLoader> type object value 0\n Id 0x6c9c1a78 Class java.io.UnixFileSystem SuperClass java.io.FileSystem Instance size 24 Instance count 1 All Instances Size 24\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name <classLoader> type object value 0\n  Field name javaHomePrefixCache type object\n  Field name cache type object\n  Field name javaHome type object\n  Field name colon type char\n  Field name slash type char\n  Instance Id 0x64616ca8 number 1 retained size 2336\n   Instance Field name javaHomePrefixCache type object value 1684106640\n    Ref object java.io.ExpiringCache#2\n   Instance Field name cache type object value 1684106432\n    Ref object java.io.ExpiringCache#1\n   Instance Field name javaHome type object value 1684103032\n    Ref object java.lang.String#90\n   Instance Field name colon type char value :\n   Instance Field name slash type char value /\n   References count 1\n   Field fs of Class java.io.File\n   Path to nearest GC root\n    Next object java.lang.Class#270\n Id 0x6c98e2c8 Class java.lang.Math SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name negativeZeroDoubleBits type long value -9223372036854775808\n  Static Field name negativeZeroFloatBits type long value -2147483648\n  Static Field name randomNumberGenerator type object value 0\n  Static Field name PI type double value 3.141592653589793\n  Static Field name E type double value 2.718281828459045\n  Static Field name <classLoader> type object value 0\n Id 0x6c9c2508 Class java.io.ExpiringCache SuperClass java.lang.Object Instance size 32 Instance count 2 All Instances Size 64\n  Static Field name <classLoader> type object value 0\n  Field name MAX_ENTRIES type int\n  Field name queryOverflow type int\n  Field name queryCount type int\n  Field name map type object\n  Field name millisUntilExpiration type long\n  Instance Id 0x64616cc0 number 1 retained size 1584\n   Instance Field name MAX_ENTRIES type int value 200\n   Instance Field name queryOverflow type int value 300\n   Instance Field name queryCount type int value 15\n   Instance Field name map type object value 1684106472\n    Ref object java.io.ExpiringCache$1#1\n   Instance Field name millisUntilExpiration type long value 30000\n   References count 2\n   Field cache of instance 0x64616ca8\n   Field this$0 of instance 0x64616ce8\n   Path to nearest GC root\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64616d90 number 2 retained size 408\n   Instance Field name MAX_ENTRIES type int value 200\n   Instance Field name queryOverflow type int value 300\n   Instance Field name queryCount type int value 9\n   Instance Field name map type object value 1684106680\n    Ref object java.io.ExpiringCache$1#2\n   Instance Field name millisUntilExpiration type long value 30000\n   References count 2\n   Field javaHomePrefixCache of instance 0x64616ca8\n   Field this$0 of instance 0x64616db8\n   Path to nearest GC root\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n Id 0x6c9c7f20 Class java.io.ExpiringCache$Entry SuperClass java.lang.Object Instance size 24 Instance count 9 All Instances Size 216\n  Static Field name <classLoader> type object value 0\n  Field name val type object\n  Field name timestamp type long\n  Instance Id 0x646251f0 number 1 retained size 24\n   Instance Field name val type object value 1684164984\n    Ref object java.lang.String#110\n   Instance Field name timestamp type long value 1150458355667\n   References count 1\n   Field value of instance 0x64625208\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#3\n    Next object java.util.LinkedHashMap$Entry#1\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64625240 number 2 retained size 48\n   Instance Field name val type object value 1684165160\n    Ref object java.lang.String#111\n   Instance Field name timestamp type long value 1150458355667\n   References count 1\n   Field value of instance 0x64625258\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#4\n    Next object java.util.LinkedHashMap$Entry#2\n    Next object java.io.ExpiringCache$1#2\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64625aa8 number 3 retained size 120\n   Instance Field name val type object value 1684167240\n    Ref object java.lang.String#115\n   Instance Field name timestamp type long value 1150458355675\n   References count 1\n   Field value of instance 0x64625ac0\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#5\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x646262a8 number 4 retained size 48\n   Instance Field name val type object value 1684169248\n    Ref object java.lang.String#132\n   Instance Field name timestamp type long value 1150458355678\n   References count 1\n   Field value of instance 0x646262c0\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#6\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x646262f8 number 5 retained size 48\n   Instance Field name val type object value 1684169440\n    Ref object java.lang.String#133\n   Instance Field name timestamp type long value 1150458355678\n   References count 1\n   Field value of instance 0x64626310\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#7\n    Next object java.util.LinkedHashMap$Entry#2\n    Next object java.io.ExpiringCache$1#2\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627b10 number 6 retained size 152\n   Instance Field name val type object value 1684175376\n    Ref object java.lang.String#135\n   Instance Field name timestamp type long value 1150458355684\n   References count 1\n   Field value of instance 0x64627b28\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#8\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627cf0 number 7 retained size 144\n   Instance Field name val type object value 1684175872\n    Ref object java.lang.String#138\n   Instance Field name timestamp type long value 1150458355685\n   References count 1\n   Field value of instance 0x64627d08\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#9\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627ed8 number 8 retained size 152\n   Instance Field name val type object value 1684176344\n    Ref object java.lang.String#141\n   Instance Field name timestamp type long value 1150458355685\n   References count 1\n   Field value of instance 0x64627ef0\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#10\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64628568 number 9 retained size 24\n   Instance Field name val type object value 1684178208\n    Ref object java.lang.String#145\n   Instance Field name timestamp type long value 1150458355687\n   References count 1\n   Field value of instance 0x64628580\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#11\n    Next object java.util.LinkedHashMap$Entry#1\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n Id 0x6c9c38f0 Class java.io.ExpiringCache$1 SuperClass java.util.LinkedHashMap Instance size 56 Instance count 2 All Instances Size 112\n  Static Field name <classLoader> type object value 0\n  Field name this$0 type object\n  Instance Id 0x64616ce8 number 1 retained size 1552\n   Instance Field name this$0 type object value 1684106432\n    Ref object java.io.ExpiringCache#1\n   Instance Field name accessOrder type boolean value false\n   Instance Field name header type object value 1684106608\n    Ref object java.util.LinkedHashMap$Entry#1\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 7\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 7\n   Instance Field name table type object value 1684106528\n    Ref object java.util.HashMap$Entry[]#3\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field map of instance 0x64616cc0\n   Path to nearest GC root\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64616db8 number 2 retained size 376\n   Instance Field name this$0 type object value 1684106640\n    Ref object java.io.ExpiringCache#2\n   Instance Field name accessOrder type boolean value false\n   Instance Field name header type object value 1684106816\n    Ref object java.util.LinkedHashMap$Entry#2\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 2\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 2\n   Instance Field name table type object value 1684106736\n    Ref object java.util.HashMap$Entry[]#4\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field map of instance 0x64616d90\n   Path to nearest GC root\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n Id 0x6c9c32f0 Class java.util.LinkedHashMap SuperClass java.util.HashMap Instance size 48 Instance count 1 All Instances Size 48\n  Static Field name serialVersionUID type long value 3801124242820219131\n  Static Field name <classLoader> type object value 0\n  Field name accessOrder type boolean\n  Field name header type object\n  Instance Id 0x6462f0c8 number 1 retained size 2816\n   Instance Field name accessOrder type boolean value false\n   Instance Field name header type object value 1684205816\n    Ref object java.util.LinkedHashMap$Entry#12\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 69\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 96\n   Instance Field name size type int value 69\n   Instance Field name table type object value 1684208512\n    Ref object java.util.HashMap$Entry[]#23\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field legacyStrings of instance 0x6462d358\n   Path to nearest GC root\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n Id 0x6c960ff8 Class sun.misc.AtomicLongCSImpl SuperClass sun.misc.AtomicLong Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name value type long\n Id 0x6c9605c8 Class java.nio.Buffer SuperClass java.lang.Object Instance size 32 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name address type long\n  Field name capacity type int\n  Field name limit type int\n  Field name position type int\n  Field name mark type int\n Id 0x6c9e6648 Class java.util.concurrent.locks.AbstractOwnableSynchronizer SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value 3737899427754241961\n  Static Field name <classLoader> type object value 0\n  Field name exclusiveOwnerThread type object\n Id 0x6c9c3e98 Class java.util.LinkedHashMap$Entry SuperClass java.util.HashMap$Entry Instance size 32 Instance count 81 All Instances Size 2592\n  Static Field name <classLoader> type object value 0\n  Field name after type object\n  Field name before type object\n  Instance Id 0x64616d70 number 1 retained size 32\n   Instance Field name after type object value 1684165128\n    Ref object java.util.LinkedHashMap$Entry#3\n   Instance Field name before type object value 1684178304\n    Ref object java.util.LinkedHashMap$Entry#11\n   Instance Field name hash type int value -1\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field header of instance 0x64616ce8\n   Field before of instance 0x64625208\n   Field after of instance 0x64628580\n   Path to nearest GC root\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64616e40 number 2 retained size 32\n   Instance Field name after type object value 1684165208\n    Ref object java.util.LinkedHashMap$Entry#4\n   Instance Field name before type object value 1684169488\n    Ref object java.util.LinkedHashMap$Entry#7\n   Instance Field name hash type int value -1\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field header of instance 0x64616db8\n   Field before of instance 0x64625258\n   Field after of instance 0x64626310\n   Path to nearest GC root\n    Next object java.io.ExpiringCache$1#2\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64625208 number 3 retained size 80\n   Instance Field name after type object value 1684167360\n    Ref object java.util.LinkedHashMap$Entry#5\n   Instance Field name before type object value 1684106608\n    Ref object java.util.LinkedHashMap$Entry#1\n   Instance Field name hash type int value 383756388\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684165104\n    Ref object java.io.ExpiringCache$Entry#1\n   Instance Field name key type object value 1684164568\n    Ref object java.lang.String#108\n   References count 3\n   Field after of instance 0x64616d70\n   Element 4 of array 0x64616d20\n   Field before of instance 0x64625ac0\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#1\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64625258 number 4 retained size 104\n   Instance Field name after type object value 1684169488\n    Ref object java.util.LinkedHashMap$Entry#7\n   Instance Field name before type object value 1684106816\n    Ref object java.util.LinkedHashMap$Entry#2\n   Instance Field name hash type int value 914014631\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684165184\n    Ref object java.io.ExpiringCache$Entry#2\n   Instance Field name key type object value 1684164960\n    Ref object java.lang.String#109\n   References count 3\n   Field after of instance 0x64616e40\n   Element 7 of array 0x64616df0\n   Field before of instance 0x64626310\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#2\n    Next object java.io.ExpiringCache$1#2\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64625ac0 number 5 retained size 152\n   Instance Field name after type object value 1684169408\n    Ref object java.util.LinkedHashMap$Entry#6\n   Instance Field name before type object value 1684165128\n    Ref object java.util.LinkedHashMap$Entry#3\n   Instance Field name hash type int value -732501917\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684167336\n    Ref object java.io.ExpiringCache$Entry#3\n   Instance Field name key type object value 1684166992\n    Ref object java.lang.String#113\n   References count 3\n   Element 3 of array 0x64616d20\n   Field after of instance 0x64625208\n   Field before of instance 0x646262c0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x646262c0 number 6 retained size 104\n   Instance Field name after type object value 1684175656\n    Ref object java.util.LinkedHashMap$Entry#8\n   Instance Field name before type object value 1684167360\n    Ref object java.util.LinkedHashMap$Entry#5\n   Instance Field name hash type int value 1166213256\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684169384\n    Ref object java.io.ExpiringCache$Entry#4\n   Instance Field name key type object value 1684169088\n    Ref object java.lang.String#130\n   References count 3\n   Element 8 of array 0x64616d20\n   Field after of instance 0x64625ac0\n   Field before of instance 0x64627b28\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64626310 number 7 retained size 104\n   Instance Field name after type object value 1684106816\n    Ref object java.util.LinkedHashMap$Entry#2\n   Instance Field name before type object value 1684165208\n    Ref object java.util.LinkedHashMap$Entry#4\n   Instance Field name hash type int value -732501917\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684169464\n    Ref object java.io.ExpiringCache$Entry#5\n   Instance Field name key type object value 1684169224\n    Ref object java.lang.String#131\n   References count 3\n   Field before of instance 0x64616e40\n   Element 3 of array 0x64616df0\n   Field after of instance 0x64625258\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#2\n    Next object java.io.ExpiringCache$1#2\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627b28 number 8 retained size 312\n   Instance Field name after type object value 1684176136\n    Ref object java.util.LinkedHashMap$Entry#9\n   Instance Field name before type object value 1684169408\n    Ref object java.util.LinkedHashMap$Entry#6\n   Instance Field name hash type int value -1244703522\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684175632\n    Ref object java.io.ExpiringCache$Entry#6\n   Instance Field name key type object value 1684175504\n    Ref object java.lang.String#136\n   References count 3\n   Element 14 of array 0x64616d20\n   Field after of instance 0x646262c0\n   Field before of instance 0x64627d08\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627d08 number 9 retained size 296\n   Instance Field name after type object value 1684176624\n    Ref object java.util.LinkedHashMap$Entry#10\n   Instance Field name before type object value 1684175656\n    Ref object java.util.LinkedHashMap$Entry#8\n   Instance Field name hash type int value 513533905\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684176112\n    Ref object java.io.ExpiringCache$Entry#7\n   Instance Field name key type object value 1684175992\n    Ref object java.lang.String#139\n   References count 3\n   Element 1 of array 0x64616d20\n   Field after of instance 0x64627b28\n   Field before of instance 0x64627ef0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627ef0 number 10 retained size 312\n   Instance Field name after type object value 1684178304\n    Ref object java.util.LinkedHashMap$Entry#11\n   Instance Field name before type object value 1684176136\n    Ref object java.util.LinkedHashMap$Entry#9\n   Instance Field name hash type int value -1246824955\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684176600\n    Ref object java.io.ExpiringCache$Entry#8\n   Instance Field name key type object value 1684176472\n    Ref object java.lang.String#142\n   References count 3\n   Element 5 of array 0x64616d20\n   Field after of instance 0x64627d08\n   Field before of instance 0x64628580\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64628580 number 11 retained size 128\n   Instance Field name after type object value 1684106608\n    Ref object java.util.LinkedHashMap$Entry#1\n   Instance Field name before type object value 1684176624\n    Ref object java.util.LinkedHashMap$Entry#10\n   Instance Field name hash type int value 783002285\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684178280\n    Ref object java.io.ExpiringCache$Entry#9\n   Instance Field name key type object value 1684178136\n    Ref object java.lang.String#144\n   References count 3\n   Field before of instance 0x64616d70\n   Element 13 of array 0x64616d20\n   Field after of instance 0x64627ef0\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#1\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x6462f0f8 number 12 retained size 32\n   Instance Field name after type object value 1684205848\n    Ref object java.util.LinkedHashMap$Entry#13\n   Instance Field name before type object value 1684210960\n    Ref object java.util.LinkedHashMap$Entry#81\n   Instance Field name hash type int value -1\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field header of instance 0x6462f0c8\n   Field before of instance 0x6462f118\n   Field after of instance 0x64630510\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f118 number 13 retained size 32\n   Instance Field name after type object value 1684205904\n    Ref object java.util.LinkedHashMap$Entry#14\n   Instance Field name before type object value 1684205816\n    Ref object java.util.LinkedHashMap$Entry#12\n   Instance Field name hash type int value -985275771\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field after of instance 0x6462f0f8\n   Field before of instance 0x6462f150\n   Element 5 of array 0x6462fb80\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#12\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f150 number 14 retained size 32\n   Instance Field name after type object value 1684205960\n    Ref object java.util.LinkedHashMap$Entry#15\n   Instance Field name before type object value 1684205848\n    Ref object java.util.LinkedHashMap$Entry#13\n   Instance Field name hash type int value -661175452\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 100 of array 0x6462fb80\n   Field before of instance 0x6462f188\n   Field after of instance 0x6462f118\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f188 number 15 retained size 32\n   Instance Field name after type object value 1684206016\n    Ref object java.util.LinkedHashMap$Entry#16\n   Instance Field name before type object value 1684205904\n    Ref object java.util.LinkedHashMap$Entry#14\n   Instance Field name hash type int value 150371693\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 109 of array 0x6462fb80\n   Field before of instance 0x6462f1c0\n   Field after of instance 0x6462f150\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f1c0 number 16 retained size 32\n   Instance Field name after type object value 1684206072\n    Ref object java.util.LinkedHashMap$Entry#17\n   Instance Field name before type object value 1684205960\n    Ref object java.util.LinkedHashMap$Entry#15\n   Instance Field name hash type int value 1966533841\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 81 of array 0x6462fb80\n   Field before of instance 0x6462f1f8\n   Field after of instance 0x6462f188\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f1f8 number 17 retained size 32\n   Instance Field name after type object value 1684206128\n    Ref object java.util.LinkedHashMap$Entry#18\n   Instance Field name before type object value 1684206016\n    Ref object java.util.LinkedHashMap$Entry#16\n   Instance Field name hash type int value -1420071181\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field after of instance 0x6462f1c0\n   Field before of instance 0x6462f230\n   Field next of instance 0x6462f968\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#16\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f230 number 18 retained size 32\n   Instance Field name after type object value 1684206184\n    Ref object java.util.LinkedHashMap$Entry#19\n   Instance Field name before type object value 1684206072\n    Ref object java.util.LinkedHashMap$Entry#17\n   Instance Field name hash type int value 1022017533\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 125 of array 0x6462fb80\n   Field before of instance 0x6462f268\n   Field after of instance 0x6462f1f8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f268 number 19 retained size 32\n   Instance Field name after type object value 1684206240\n    Ref object java.util.LinkedHashMap$Entry#20\n   Instance Field name before type object value 1684206128\n    Ref object java.util.LinkedHashMap$Entry#18\n   Instance Field name hash type int value -918829086\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 98 of array 0x6462fb80\n   Field before of instance 0x6462f2a0\n   Field after of instance 0x6462f230\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f2a0 number 20 retained size 32\n   Instance Field name after type object value 1684206296\n    Ref object java.util.LinkedHashMap$Entry#21\n   Instance Field name before type object value 1684206184\n    Ref object java.util.LinkedHashMap$Entry#19\n   Instance Field name hash type int value -1994760384\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 64 of array 0x6462fb80\n   Field before of instance 0x6462f2d8\n   Field after of instance 0x6462f268\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f2d8 number 21 retained size 32\n   Instance Field name after type object value 1684206352\n    Ref object java.util.LinkedHashMap$Entry#22\n   Instance Field name before type object value 1684206240\n    Ref object java.util.LinkedHashMap$Entry#20\n   Instance Field name hash type int value -1994760365\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field after of instance 0x6462f2a0\n   Field before of instance 0x6462f310\n   Field next of instance 0x64630160\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#20\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f310 number 22 retained size 32\n   Instance Field name after type object value 1684206408\n    Ref object java.util.LinkedHashMap$Entry#23\n   Instance Field name before type object value 1684206296\n    Ref object java.util.LinkedHashMap$Entry#21\n   Instance Field name hash type int value 1862907770\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field next of instance 0x6462fec0\n   Field before of instance 0x6462f348\n   Field after of instance 0x6462f2d8\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#66\n    Next object java.util.LinkedHashMap$Entry#67\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f348 number 23 retained size 32\n   Instance Field name after type object value 1684206464\n    Ref object java.util.LinkedHashMap$Entry#24\n   Instance Field name before type object value 1684206352\n    Ref object java.util.LinkedHashMap$Entry#22\n   Instance Field name hash type int value 882604510\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field next of instance 0x6462f428\n   Field before of instance 0x6462f380\n   Field after of instance 0x6462f310\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#27\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f380 number 24 retained size 32\n   Instance Field name after type object value 1684206520\n    Ref object java.util.LinkedHashMap$Entry#25\n   Instance Field name before type object value 1684206408\n    Ref object java.util.LinkedHashMap$Entry#23\n   Instance Field name hash type int value -1250324521\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field next of instance 0x6462f540\n   Field before of instance 0x6462f3b8\n   Field after of instance 0x6462f348\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#32\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f3b8 number 25 retained size 32\n   Instance Field name after type object value 1684206576\n    Ref object java.util.LinkedHashMap$Entry#26\n   Instance Field name before type object value 1684206464\n    Ref object java.util.LinkedHashMap$Entry#24\n   Instance Field name hash type int value 1848865273\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 121 of array 0x6462fb80\n   Field before of instance 0x6462f3f0\n   Field after of instance 0x6462f380\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f3f0 number 26 retained size 32\n   Instance Field name after type object value 1684206632\n    Ref object java.util.LinkedHashMap$Entry#27\n   Instance Field name before type object value 1684206520\n    Ref object java.util.LinkedHashMap$Entry#25\n   Instance Field name hash type int value 1806496503\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 119 of array 0x6462fb80\n   Field before of instance 0x6462f428\n   Field after of instance 0x6462f3b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f428 number 27 retained size 32\n   Instance Field name after type object value 1684206688\n    Ref object java.util.LinkedHashMap$Entry#28\n   Instance Field name before type object value 1684206576\n    Ref object java.util.LinkedHashMap$Entry#26\n   Instance Field name hash type int value -1580147234\n   Instance Field name next type object value 1684206408\n    Ref object java.util.LinkedHashMap$Entry#23\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 94 of array 0x6462fb80\n   Field before of instance 0x6462f460\n   Field after of instance 0x6462f3f0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f460 number 28 retained size 32\n   Instance Field name after type object value 1684206744\n    Ref object java.util.LinkedHashMap$Entry#29\n   Instance Field name before type object value 1684206632\n    Ref object java.util.LinkedHashMap$Entry#27\n   Instance Field name hash type int value -1992391619\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 61 of array 0x6462fb80\n   Field before of instance 0x6462f498\n   Field after of instance 0x6462f428\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f498 number 29 retained size 32\n   Instance Field name after type object value 1684206800\n    Ref object java.util.LinkedHashMap$Entry#30\n   Instance Field name before type object value 1684206688\n    Ref object java.util.LinkedHashMap$Entry#28\n   Instance Field name hash type int value 20468618\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 10 of array 0x6462fb80\n   Field before of instance 0x6462f4d0\n   Field after of instance 0x6462f460\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f4d0 number 30 retained size 32\n   Instance Field name after type object value 1684206856\n    Ref object java.util.LinkedHashMap$Entry#31\n   Instance Field name before type object value 1684206744\n    Ref object java.util.LinkedHashMap$Entry#29\n   Instance Field name hash type int value 20468707\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 99 of array 0x6462fb80\n   Field before of instance 0x6462f508\n   Field after of instance 0x6462f498\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f508 number 31 retained size 32\n   Instance Field name after type object value 1684206912\n    Ref object java.util.LinkedHashMap$Entry#32\n   Instance Field name before type object value 1684206800\n    Ref object java.util.LinkedHashMap$Entry#30\n   Instance Field name hash type int value -1171507301\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 27 of array 0x6462fb80\n   Field before of instance 0x6462f540\n   Field after of instance 0x6462f4d0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f540 number 32 retained size 32\n   Instance Field name after type object value 1684206968\n    Ref object java.util.LinkedHashMap$Entry#33\n   Instance Field name before type object value 1684206856\n    Ref object java.util.LinkedHashMap$Entry#31\n   Instance Field name hash type int value 1230527959\n   Instance Field name next type object value 1684206464\n    Ref object java.util.LinkedHashMap$Entry#24\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 87 of array 0x6462fb80\n   Field before of instance 0x6462f578\n   Field after of instance 0x6462f508\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f578 number 33 retained size 32\n   Instance Field name after type object value 1684207024\n    Ref object java.util.LinkedHashMap$Entry#34\n   Instance Field name before type object value 1684206912\n    Ref object java.util.LinkedHashMap$Entry#32\n   Instance Field name hash type int value 164860305\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 17 of array 0x6462fb80\n   Field before of instance 0x6462f5b0\n   Field after of instance 0x6462f540\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f5b0 number 34 retained size 32\n   Instance Field name after type object value 1684207080\n    Ref object java.util.LinkedHashMap$Entry#35\n   Instance Field name before type object value 1684206968\n    Ref object java.util.LinkedHashMap$Entry#33\n   Instance Field name hash type int value -157965144\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field after of instance 0x6462f578\n   Field before of instance 0x6462f5e8\n   Field next of instance 0x6462fda8\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#33\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f5e8 number 35 retained size 32\n   Instance Field name after type object value 1684207136\n    Ref object java.util.LinkedHashMap$Entry#36\n   Instance Field name before type object value 1684207024\n    Ref object java.util.LinkedHashMap$Entry#34\n   Instance Field name hash type int value 1934118105\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 89 of array 0x6462fb80\n   Field before of instance 0x6462f620\n   Field after of instance 0x6462f5b0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f620 number 36 retained size 32\n   Instance Field name after type object value 1684207192\n    Ref object java.util.LinkedHashMap$Entry#37\n   Instance Field name before type object value 1684207080\n    Ref object java.util.LinkedHashMap$Entry#35\n   Instance Field name hash type int value 1934118106\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 90 of array 0x6462fb80\n   Field before of instance 0x6462f658\n   Field after of instance 0x6462f5e8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f658 number 37 retained size 32\n   Instance Field name after type object value 1684207248\n    Ref object java.util.LinkedHashMap$Entry#38\n   Instance Field name before type object value 1684207136\n    Ref object java.util.LinkedHashMap$Entry#36\n   Instance Field name hash type int value 1934107567\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 47 of array 0x6462fb80\n   Field before of instance 0x6462f690\n   Field after of instance 0x6462f620\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f690 number 38 retained size 32\n   Instance Field name after type object value 1684207304\n    Ref object java.util.LinkedHashMap$Entry#39\n   Instance Field name before type object value 1684207192\n    Ref object java.util.LinkedHashMap$Entry#37\n   Instance Field name hash type int value -362836171\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 53 of array 0x6462fb80\n   Field before of instance 0x6462f6c8\n   Field after of instance 0x6462f658\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f6c8 number 39 retained size 32\n   Instance Field name after type object value 1684207360\n    Ref object java.util.LinkedHashMap$Entry#40\n   Instance Field name before type object value 1684207248\n    Ref object java.util.LinkedHashMap$Entry#38\n   Instance Field name hash type int value 990438338\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field before of instance 0x6462f700\n   Field after of instance 0x6462f690\n   Field next of instance 0x6462fde0\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#40\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f700 number 40 retained size 32\n   Instance Field name after type object value 1684207416\n    Ref object java.util.LinkedHashMap$Entry#41\n   Instance Field name before type object value 1684207304\n    Ref object java.util.LinkedHashMap$Entry#39\n   Instance Field name hash type int value -2129037276\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 36 of array 0x6462fb80\n   Field before of instance 0x6462f738\n   Field after of instance 0x6462f6c8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f738 number 41 retained size 32\n   Instance Field name after type object value 1684207472\n    Ref object java.util.LinkedHashMap$Entry#42\n   Instance Field name before type object value 1684207360\n    Ref object java.util.LinkedHashMap$Entry#40\n   Instance Field name hash type int value -2129094560\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 96 of array 0x6462fb80\n   Field before of instance 0x6462f770\n   Field after of instance 0x6462f700\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f770 number 42 retained size 32\n   Instance Field name after type object value 1684207528\n    Ref object java.util.LinkedHashMap$Entry#43\n   Instance Field name before type object value 1684207416\n    Ref object java.util.LinkedHashMap$Entry#41\n   Instance Field name hash type int value -2129096089\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 103 of array 0x6462fb80\n   Field before of instance 0x6462f7a8\n   Field after of instance 0x6462f738\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f7a8 number 43 retained size 32\n   Instance Field name after type object value 1684207584\n    Ref object java.util.LinkedHashMap$Entry#44\n   Instance Field name before type object value 1684207472\n    Ref object java.util.LinkedHashMap$Entry#42\n   Instance Field name hash type int value 430511723\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field before of instance 0x6462f7e0\n   Field after of instance 0x6462f770\n   Field next of instance 0x64630048\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#44\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f7e0 number 44 retained size 32\n   Instance Field name after type object value 1684207640\n    Ref object java.util.LinkedHashMap$Entry#45\n   Instance Field name before type object value 1684207528\n    Ref object java.util.LinkedHashMap$Entry#43\n   Instance Field name hash type int value -974078588\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 4 of array 0x6462fb80\n   Field before of instance 0x6462f818\n   Field after of instance 0x6462f7a8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f818 number 45 retained size 32\n   Instance Field name after type object value 1684207696\n    Ref object java.util.LinkedHashMap$Entry#46\n   Instance Field name before type object value 1684207584\n    Ref object java.util.LinkedHashMap$Entry#44\n   Instance Field name hash type int value -916364494\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field after of instance 0x6462f7e0\n   Field before of instance 0x6462f850\n   Field next of instance 0x6462fe50\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#44\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f850 number 46 retained size 32\n   Instance Field name after type object value 1684207752\n    Ref object java.util.LinkedHashMap$Entry#47\n   Instance Field name before type object value 1684207640\n    Ref object java.util.LinkedHashMap$Entry#45\n   Instance Field name hash type int value 1315383934\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field before of instance 0x6462f888\n   Field after of instance 0x6462f818\n   Field next of instance 0x6462f9d8\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#47\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f888 number 47 retained size 32\n   Instance Field name after type object value 1684207808\n    Ref object java.util.LinkedHashMap$Entry#48\n   Instance Field name before type object value 1684207696\n    Ref object java.util.LinkedHashMap$Entry#46\n   Instance Field name hash type int value 1429717182\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 62 of array 0x6462fb80\n   Field before of instance 0x6462f8c0\n   Field after of instance 0x6462f850\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f8c0 number 48 retained size 32\n   Instance Field name after type object value 1684207864\n    Ref object java.util.LinkedHashMap$Entry#49\n   Instance Field name before type object value 1684207752\n    Ref object java.util.LinkedHashMap$Entry#47\n   Instance Field name hash type int value -1268968328\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field before of instance 0x6462f8f8\n   Field after of instance 0x6462f888\n   Field next of instance 0x6462fe88\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#49\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f8f8 number 49 retained size 32\n   Instance Field name after type object value 1684207920\n    Ref object java.util.LinkedHashMap$Entry#50\n   Instance Field name before type object value 1684207808\n    Ref object java.util.LinkedHashMap$Entry#48\n   Instance Field name hash type int value -1748694771\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 13 of array 0x6462fb80\n   Field before of instance 0x6462f930\n   Field after of instance 0x6462f8c0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f930 number 50 retained size 32\n   Instance Field name after type object value 1684207976\n    Ref object java.util.LinkedHashMap$Entry#51\n   Instance Field name before type object value 1684207864\n    Ref object java.util.LinkedHashMap$Entry#49\n   Instance Field name hash type int value 763331323\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 123 of array 0x6462fb80\n   Field before of instance 0x6462f968\n   Field after of instance 0x6462f8f8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f968 number 51 retained size 32\n   Instance Field name after type object value 1684208032\n    Ref object java.util.LinkedHashMap$Entry#52\n   Instance Field name before type object value 1684207920\n    Ref object java.util.LinkedHashMap$Entry#50\n   Instance Field name hash type int value 150544627\n   Instance Field name next type object value 1684206072\n    Ref object java.util.LinkedHashMap$Entry#17\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field next of instance 0x6462fb28\n   Field before of instance 0x6462f9a0\n   Field after of instance 0x6462f930\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#59\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f9a0 number 52 retained size 32\n   Instance Field name after type object value 1684208088\n    Ref object java.util.LinkedHashMap$Entry#53\n   Instance Field name before type object value 1684207976\n    Ref object java.util.LinkedHashMap$Entry#51\n   Instance Field name hash type int value 1471432878\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field next of instance 0x6462ff68\n   Field before of instance 0x6462f9d8\n   Field after of instance 0x6462f968\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#69\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f9d8 number 53 retained size 32\n   Instance Field name after type object value 1684208144\n    Ref object java.util.LinkedHashMap$Entry#54\n   Instance Field name before type object value 1684208032\n    Ref object java.util.LinkedHashMap$Entry#52\n   Instance Field name hash type int value 2069840126\n   Instance Field name next type object value 1684207696\n    Ref object java.util.LinkedHashMap$Entry#46\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 126 of array 0x6462fb80\n   Field before of instance 0x6462fa10\n   Field after of instance 0x6462f9a0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fa10 number 54 retained size 32\n   Instance Field name after type object value 1684208200\n    Ref object java.util.LinkedHashMap$Entry#55\n   Instance Field name before type object value 1684208088\n    Ref object java.util.LinkedHashMap$Entry#53\n   Instance Field name hash type int value 1879820935\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field next of instance 0x6462ffa0\n   Field before of instance 0x6462fa48\n   Field after of instance 0x6462f9d8\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#70\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fa48 number 55 retained size 32\n   Instance Field name after type object value 1684208256\n    Ref object java.util.LinkedHashMap$Entry#56\n   Instance Field name before type object value 1684208144\n    Ref object java.util.LinkedHashMap$Entry#54\n   Instance Field name hash type int value -1879966443\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 21 of array 0x6462fb80\n   Field before of instance 0x6462fa80\n   Field after of instance 0x6462fa10\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fa80 number 56 retained size 32\n   Instance Field name after type object value 1684208312\n    Ref object java.util.LinkedHashMap$Entry#57\n   Instance Field name before type object value 1684208200\n    Ref object java.util.LinkedHashMap$Entry#55\n   Instance Field name hash type int value -1425444474\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 6 of array 0x6462fb80\n   Field before of instance 0x6462fab8\n   Field after of instance 0x6462fa48\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fab8 number 57 retained size 32\n   Instance Field name after type object value 1684208368\n    Ref object java.util.LinkedHashMap$Entry#58\n   Instance Field name before type object value 1684208256\n    Ref object java.util.LinkedHashMap$Entry#56\n   Instance Field name hash type int value 1250014643\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field after of instance 0x6462fa80\n   Field before of instance 0x6462faf0\n   Field next of instance 0x646300f0\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#56\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462faf0 number 58 retained size 32\n   Instance Field name after type object value 1684208424\n    Ref object java.util.LinkedHashMap$Entry#59\n   Instance Field name before type object value 1684208312\n    Ref object java.util.LinkedHashMap$Entry#57\n   Instance Field name hash type int value 788054168\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 24 of array 0x6462fb80\n   Field before of instance 0x6462fb28\n   Field after of instance 0x6462fab8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fb28 number 59 retained size 32\n   Instance Field name after type object value 1684208480\n    Ref object java.util.LinkedHashMap$Entry#60\n   Instance Field name before type object value 1684208368\n    Ref object java.util.LinkedHashMap$Entry#58\n   Instance Field name hash type int value -2114240653\n   Instance Field name next type object value 1684207976\n    Ref object java.util.LinkedHashMap$Entry#51\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 115 of array 0x6462fb80\n   Field before of instance 0x6462fb60\n   Field after of instance 0x6462faf0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fb60 number 60 retained size 32\n   Instance Field name after type object value 1684209064\n    Ref object java.util.LinkedHashMap$Entry#61\n   Instance Field name before type object value 1684208424\n    Ref object java.util.LinkedHashMap$Entry#59\n   Instance Field name hash type int value -878842736\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 16 of array 0x6462fb80\n   Field after of instance 0x6462fb28\n   Field before of instance 0x6462fda8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fda8 number 61 retained size 32\n   Instance Field name after type object value 1684209120\n    Ref object java.util.LinkedHashMap$Entry#62\n   Instance Field name before type object value 1684208480\n    Ref object java.util.LinkedHashMap$Entry#60\n   Instance Field name hash type int value -820488792\n   Instance Field name next type object value 1684207024\n    Ref object java.util.LinkedHashMap$Entry#34\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 40 of array 0x6462fb80\n   Field after of instance 0x6462fb60\n   Field before of instance 0x6462fde0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fde0 number 62 retained size 32\n   Instance Field name after type object value 1684209176\n    Ref object java.util.LinkedHashMap$Entry#63\n   Instance Field name before type object value 1684209064\n    Ref object java.util.LinkedHashMap$Entry#61\n   Instance Field name hash type int value -1148967486\n   Instance Field name next type object value 1684207304\n    Ref object java.util.LinkedHashMap$Entry#39\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 66 of array 0x6462fb80\n   Field after of instance 0x6462fda8\n   Field before of instance 0x6462fe18\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fe18 number 63 retained size 32\n   Instance Field name after type object value 1684209232\n    Ref object java.util.LinkedHashMap$Entry#64\n   Instance Field name before type object value 1684209120\n    Ref object java.util.LinkedHashMap$Entry#62\n   Instance Field name hash type int value 446674962\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 18 of array 0x6462fb80\n   Field after of instance 0x6462fde0\n   Field before of instance 0x6462fe50\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fe50 number 64 retained size 32\n   Instance Field name after type object value 1684209288\n    Ref object java.util.LinkedHashMap$Entry#65\n   Instance Field name before type object value 1684209176\n    Ref object java.util.LinkedHashMap$Entry#63\n   Instance Field name hash type int value -1920783822\n   Instance Field name next type object value 1684207640\n    Ref object java.util.LinkedHashMap$Entry#45\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 50 of array 0x6462fb80\n   Field after of instance 0x6462fe18\n   Field before of instance 0x6462fe88\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fe88 number 65 retained size 32\n   Instance Field name after type object value 1684209344\n    Ref object java.util.LinkedHashMap$Entry#66\n   Instance Field name before type object value 1684209232\n    Ref object java.util.LinkedHashMap$Entry#64\n   Instance Field name hash type int value 846669176\n   Instance Field name next type object value 1684207808\n    Ref object java.util.LinkedHashMap$Entry#48\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 120 of array 0x6462fb80\n   Field after of instance 0x6462fe50\n   Field before of instance 0x6462fec0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fec0 number 66 retained size 32\n   Instance Field name after type object value 1684209400\n    Ref object java.util.LinkedHashMap$Entry#67\n   Instance Field name before type object value 1684209288\n    Ref object java.util.LinkedHashMap$Entry#65\n   Instance Field name hash type int value -1501505542\n   Instance Field name next type object value 1684206352\n    Ref object java.util.LinkedHashMap$Entry#22\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field before of instance 0x6462fef8\n   Field after of instance 0x6462fe88\n   Field next of instance 0x64630128\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#67\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fef8 number 67 retained size 32\n   Instance Field name after type object value 1684209456\n    Ref object java.util.LinkedHashMap$Entry#68\n   Instance Field name before type object value 1684209344\n    Ref object java.util.LinkedHashMap$Entry#66\n   Instance Field name hash type int value -2102708821\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 43 of array 0x6462fb80\n   Field after of instance 0x6462fec0\n   Field before of instance 0x6462ff30\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462ff30 number 68 retained size 32\n   Instance Field name after type object value 1684209512\n    Ref object java.util.LinkedHashMap$Entry#69\n   Instance Field name before type object value 1684209400\n    Ref object java.util.LinkedHashMap$Entry#67\n   Instance Field name hash type int value 1203280291\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 35 of array 0x6462fb80\n   Field after of instance 0x6462fef8\n   Field before of instance 0x6462ff68\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462ff68 number 69 retained size 32\n   Instance Field name after type object value 1684209568\n    Ref object java.util.LinkedHashMap$Entry#70\n   Instance Field name before type object value 1684209456\n    Ref object java.util.LinkedHashMap$Entry#68\n   Instance Field name hash type int value -1049084754\n   Instance Field name next type object value 1684208032\n    Ref object java.util.LinkedHashMap$Entry#52\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 46 of array 0x6462fb80\n   Field after of instance 0x6462ff30\n   Field before of instance 0x6462ffa0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462ffa0 number 70 retained size 32\n   Instance Field name after type object value 1684209624\n    Ref object java.util.LinkedHashMap$Entry#71\n   Instance Field name before type object value 1684209512\n    Ref object java.util.LinkedHashMap$Entry#69\n   Instance Field name hash type int value 1789804935\n   Instance Field name next type object value 1684208144\n    Ref object java.util.LinkedHashMap$Entry#54\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 7 of array 0x6462fb80\n   Field after of instance 0x6462ff68\n   Field before of instance 0x6462ffd8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462ffd8 number 71 retained size 32\n   Instance Field name after type object value 1684209680\n    Ref object java.util.LinkedHashMap$Entry#72\n   Instance Field name before type object value 1684209568\n    Ref object java.util.LinkedHashMap$Entry#70\n   Instance Field name hash type int value -453060337\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 15 of array 0x6462fb80\n   Field after of instance 0x6462ffa0\n   Field before of instance 0x64630010\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630010 number 72 retained size 32\n   Instance Field name after type object value 1684209736\n    Ref object java.util.LinkedHashMap$Entry#73\n   Instance Field name before type object value 1684209624\n    Ref object java.util.LinkedHashMap$Entry#71\n   Instance Field name hash type int value -618747659\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field after of instance 0x6462ffd8\n   Field before of instance 0x64630048\n   Field next of instance 0x646300b8\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#71\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630048 number 73 retained size 32\n   Instance Field name after type object value 1684209792\n    Ref object java.util.LinkedHashMap$Entry#74\n   Instance Field name before type object value 1684209680\n    Ref object java.util.LinkedHashMap$Entry#72\n   Instance Field name hash type int value -423394837\n   Instance Field name next type object value 1684207528\n    Ref object java.util.LinkedHashMap$Entry#43\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 107 of array 0x6462fb80\n   Field after of instance 0x64630010\n   Field before of instance 0x64630080\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630080 number 74 retained size 32\n   Instance Field name after type object value 1684209848\n    Ref object java.util.LinkedHashMap$Entry#75\n   Instance Field name before type object value 1684209736\n    Ref object java.util.LinkedHashMap$Entry#73\n   Instance Field name hash type int value 234192550\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 38 of array 0x6462fb80\n   Field after of instance 0x64630048\n   Field before of instance 0x646300b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x646300b8 number 75 retained size 32\n   Instance Field name after type object value 1684209904\n    Ref object java.util.LinkedHashMap$Entry#76\n   Instance Field name before type object value 1684209792\n    Ref object java.util.LinkedHashMap$Entry#74\n   Instance Field name hash type int value 681627125\n   Instance Field name next type object value 1684209680\n    Ref object java.util.LinkedHashMap$Entry#72\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 117 of array 0x6462fb80\n   Field after of instance 0x64630080\n   Field before of instance 0x646300f0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x646300f0 number 76 retained size 32\n   Instance Field name after type object value 1684209960\n    Ref object java.util.LinkedHashMap$Entry#77\n   Instance Field name before type object value 1684209848\n    Ref object java.util.LinkedHashMap$Entry#75\n   Instance Field name hash type int value -1984765389\n   Instance Field name next type object value 1684208312\n    Ref object java.util.LinkedHashMap$Entry#57\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 51 of array 0x6462fb80\n   Field after of instance 0x646300b8\n   Field before of instance 0x64630128\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630128 number 77 retained size 32\n   Instance Field name after type object value 1684210016\n    Ref object java.util.LinkedHashMap$Entry#78\n   Instance Field name before type object value 1684209904\n    Ref object java.util.LinkedHashMap$Entry#76\n   Instance Field name hash type int value -715700614\n   Instance Field name next type object value 1684209344\n    Ref object java.util.LinkedHashMap$Entry#66\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 122 of array 0x6462fb80\n   Field after of instance 0x646300f0\n   Field before of instance 0x64630160\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630160 number 78 retained size 32\n   Instance Field name after type object value 1684210072\n    Ref object java.util.LinkedHashMap$Entry#79\n   Instance Field name before type object value 1684209960\n    Ref object java.util.LinkedHashMap$Entry#77\n   Instance Field name hash type int value -2034852653\n   Instance Field name next type object value 1684206296\n    Ref object java.util.LinkedHashMap$Entry#21\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 83 of array 0x6462fb80\n   Field after of instance 0x64630128\n   Field before of instance 0x64630198\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630198 number 79 retained size 32\n   Instance Field name after type object value 1684210128\n    Ref object java.util.LinkedHashMap$Entry#80\n   Instance Field name before type object value 1684210016\n    Ref object java.util.LinkedHashMap$Entry#78\n   Instance Field name hash type int value 791495099\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Element 59 of array 0x6462fb80\n   Field after of instance 0x64630160\n   Field before of instance 0x646301d0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#23\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x646301d0 number 80 retained size 32\n   Instance Field name after type object value 1684210960\n    Ref object java.util.LinkedHashMap$Entry#81\n   Instance Field name before type object value 1684210072\n    Ref object java.util.LinkedHashMap$Entry#79\n   Instance Field name hash type int value -325073399\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field before of instance 0x64630510\n   Field next of instance 0x64630510\n   Field after of instance 0x64630198\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#81\n    Next object java.util.LinkedHashMap$Entry#12\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630510 number 81 retained size 32\n   Instance Field name after type object value 1684205816\n    Ref object java.util.LinkedHashMap$Entry#12\n   Instance Field name before type object value 1684210128\n    Ref object java.util.LinkedHashMap$Entry#80\n   Instance Field name hash type int value -1894376951\n   Instance Field name next type object value 1684210128\n    Ref object java.util.LinkedHashMap$Entry#80\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   References count 3\n   Field before of instance 0x6462f0f8\n   Element 9 of array 0x6462fb80\n   Field after of instance 0x646301d0\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap$Entry#12\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n Id 0x6c99ee10 Class sun.misc.Unsafe SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name INVALID_FIELD_OFFSET type int value -1\n  Static Field name theUnsafe type object value 1684098296\n   Ref object sun.misc.Unsafe#1\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64614cf8 number 1 retained size 8\n   References count 6\n   Field unsafe of Class java.nio.Bits\n   Field unsafe of Class sun.misc.SharedSecrets\n   Field unsafe of Class java.util.concurrent.atomic.AtomicInteger\n   Field unsafe of Class java.util.concurrent.locks.AbstractQueuedSynchronizer\n   Field unsafe of Class java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl\n   Field theUnsafe of Class sun.misc.Unsafe\n   Path to nearest GC root\n    Next object java.lang.Class#9\n Id 0x6c9c91d8 Class java.lang.Terminator$1 SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x646252b8 number 1 retained size 8\n   References count 4\n   Field handler of Class java.lang.Terminator\n   Field value of instance 0x646255c8\n   Field value of instance 0x64625638\n   Field value of instance 0x64625688\n   Path to nearest GC root\n    Next object java.lang.Class#310\n Id 0x6c9c8e48 Class sun.misc.SignalHandler SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name SIG_IGN type object value 1684166128\n   Ref object sun.misc.NativeSignalHandler#2\n  Static Field name SIG_DFL type object value 1684166112\n   Ref object sun.misc.NativeSignalHandler#1\n  Static Field name <classLoader> type object value 0\n Id 0x6c9ca140 Class sun.misc.NativeSignalHandler SuperClass java.lang.Object Instance size 16 Instance count 2 All Instances Size 32\n  Static Field name <classLoader> type object value 0\n  Field name handler type long\n  Instance Id 0x646255e0 number 1 retained size 16\n   Instance Field name handler type long value 0\n   References count 1\n   Field SIG_DFL of Class sun.misc.SignalHandler\n   Path to nearest GC root\n    Next object java.lang.Class#182\n  Instance Id 0x646255f0 number 2 retained size 16\n   Instance Field name handler type long value 1\n   References count 1\n   Field SIG_IGN of Class sun.misc.SignalHandler\n   Path to nearest GC root\n    Next object java.lang.Class#182\n Id 0x6cc32450 Class java.util.jar.JarFile SuperClass java.util.zip.ZipFile Instance size 48 Instance count 2 All Instances Size 96\n  Static Field name jarNames type object value 1684185144\n   Ref object java.lang.String[]#48\n  Static Field name javaHome type object value 1684103032\n   Ref object java.lang.String#90\n  Static Field name src type object value 1684180184\n   Ref object char[]#149\n  Static Field name optoSft type object value 1684180744\n   Ref object int[]#6\n  Static Field name lastOcc type object value 1684180216\n   Ref object int[]#5\n  Static Field name MANIFEST_NAME type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name hasClassPathAttribute type boolean\n  Field name computedHasClassPathAttribute type boolean\n  Field name verify type boolean\n  Field name jvInitialized type boolean\n  Field name jv type object\n  Field name manEntry type object\n  Field name manRef type object\n  Instance Id 0x64628fc8 number 1 retained size 0\n   Instance Field name hasClassPathAttribute type boolean value false\n   Instance Field name computedHasClassPathAttribute type boolean value false\n   Instance Field name verify type boolean value true\n   Instance Field name jvInitialized type boolean value false\n   Instance Field name jv type object value 1684182944\n    Ref object java.util.jar.JarVerifier#1\n   Instance Field name manEntry type object value 1684181096\n    Ref object java.util.jar.JarFile$JarFileEntry#1\n   Instance Field name manRef type object value 1684183424\n    Ref object java.lang.ref.SoftReference#10\n   Instance Field name inflaters type object value 1684181016\n    Ref object java.util.Vector#7\n   Instance Field name closeRequested type boolean value false\n   Instance Field name total type int value 4\n   Instance Field name name type object value 1684180872\n    Ref object java.lang.String#148\n   Instance Field name jzfile type long value 134843736\n   References count 2\n   Field referent of instance 0x64628ff8\n   Field this$0 of instance 0x64629068\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629f98 number 2 retained size 304\n   Instance Field name hasClassPathAttribute type boolean value true\n   Instance Field name computedHasClassPathAttribute type boolean value true\n   Instance Field name verify type boolean value false\n   Instance Field name jvInitialized type boolean value true\n   Instance Field name jv type object value 0\n   Instance Field name manEntry type object value 1684185840\n    Ref object java.util.jar.JarFile$JarFileEntry#2\n   Instance Field name manRef type object value 1684187016\n    Ref object java.lang.ref.SoftReference#12\n   Instance Field name inflaters type object value 1684185064\n    Ref object java.util.Vector#8\n   Instance Field name closeRequested type boolean value false\n   Instance Field name total type int value 4\n   Instance Field name name type object value 1684184912\n    Ref object java.lang.String#161\n   Instance Field name jzfile type long value 134844808\n   References count 3\n   Field jar of instance 0x64629e98\n   Field referent of instance 0x64629fc8\n   Field this$0 of instance 0x6462a2f0\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath$JarLoader#5\n    Next object java.lang.Object[]#311\n    Next object java.util.ArrayList#5\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x68137110 Class java.io.Console SuperClass java.lang.Object Instance size 40 Instance count 0 All Instances Size 0\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name cons type object value 0\n  Static Field name echoOff type boolean value false\n  Static Field name <classLoader> type object value 0\n  Field name rcb type object\n  Field name cs type object\n  Field name formatter type object\n  Field name pw type object\n  Field name out type object\n  Field name reader type object\n  Field name writeLock type object\n  Field name readLock type object\n Id 0x6c9512e8 Class sun.reflect.MagicAccessorImpl SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c951e28 Class sun.reflect.ConstructorAccessorImpl SuperClass sun.reflect.MagicAccessorImpl Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c951880 Class sun.reflect.MethodAccessorImpl SuperClass sun.reflect.MagicAccessorImpl Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c99f930 Class sun.reflect.Reflection SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name fieldFilterMap type object value 1684098472\n   Ref object java.util.Collections$SynchronizedMap#1\n  Static Field name <classLoader> type object value 0\n Id 0x6c952138 Class sun.reflect.DelegatingClassLoader SuperClass java.lang.ClassLoader Instance size 56 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cc14160 Class java.util.IdentityHashMap SuperClass java.util.AbstractMap Instance size 40 Instance count 1 All Instances Size 40\n  Static Field name serialVersionUID type long value 8188218128353913216\n  Static Field name NULL_KEY type object value 1684166424\n   Ref object java.lang.Object#7\n  Static Field name MAXIMUM_CAPACITY type int value 536870912\n  Static Field name MINIMUM_CAPACITY type int value 4\n  Static Field name DEFAULT_CAPACITY type int value 32\n  Static Field name <classLoader> type object value 0\n  Field name entrySet type object\n  Field name threshold type int\n  Field name modCount type int\n  Field name size type int\n  Field name table type object\n  Instance Id 0x64625720 number 1 retained size 312\n   Instance Field name entrySet type object value 0\n   Instance Field name threshold type int value 21\n   Instance Field name modCount type int value 0\n   Instance Field name size type int value 0\n   Instance Field name table type object value 1684166472\n    Ref object java.lang.Object[]#301\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field hooks of Class java.lang.ApplicationShutdownHooks\n   Path to nearest GC root\n    Next object java.lang.Class#305\n Id 0x6c955cc8 Class sun.reflect.UnsafeStaticFieldAccessorImpl SuperClass sun.reflect.UnsafeFieldAccessorImpl Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name base type object\n Id 0x6c9530c8 Class sun.reflect.ConstantPool SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name constantPoolOop type object\n Id 0x6c9cc1c0 Class java.lang.Compiler$1 SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9f0f98 Class sun.misc.Launcher$AppClassLoader SuperClass java.net.URLClassLoader Instance size 64 Instance count 1 All Instances Size 64\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64628620 number 1 retained size 5368\n   Instance Field name acc type object value 1684179568\n    Ref object java.security.AccessControlContext#5\n   Instance Field name ucp type object value 1684179168\n    Ref object sun.misc.URLClassPath#2\n   Instance Field name pdcache type object value 1684179048\n    Ref object java.util.HashMap#10\n   Instance Field name initialized type boolean value true\n   Instance Field name classAssertionStatus type object value 0\n   Instance Field name packageAssertionStatus type object value 0\n   Instance Field name defaultAssertionStatus type boolean value false\n   Instance Field name nativeLibraries type object value 1684178968\n    Ref object java.util.Vector#6\n   Instance Field name defaultDomain type object value 0\n   Instance Field name packages type object value 1684178848\n    Ref object java.util.HashMap#9\n   Instance Field name domains type object value 1684178712\n    Ref object java.util.HashSet#2\n   Instance Field name classes type object value 1684178632\n    Ref object java.util.Vector#5\n   Instance Field name nocerts type object value 1684212920\n    Ref object java.security.cert.Certificate[]#1\n   Instance Field name package2certs type object value 1684178536\n    Ref object java.util.Hashtable#5\n   Instance Field name parent type object value 1684169016\n    Ref object sun.misc.Launcher$ExtClassLoader#1\n   Instance Field name initialized type boolean value true\n   References count 10\n   Field scl of Class java.lang.ClassLoader\n   Field classloader of instance 0x64630c58\n   Field contextClassLoader of instance 0x64630d78\n   Field <classLoader> of Class testapp.Main\n   Field contextClassLoader of instance 0x64628b48\n   Field contextClassLoader of instance 0x64628c08\n   Field loader of instance 0x6462a980\n   Field contextClassLoader of instance 0x64610790\n   Field loader of instance 0x646258e0\n   Field contextClassLoader of instance 0x64628a88\n   Path to nearest GC root\n    Next object java.lang.Class#101\n Id 0x6c9cfdd8 Class sun.misc.Launcher$ExtClassLoader SuperClass java.net.URLClassLoader Instance size 72 Instance count 1 All Instances Size 72\n  Static Field name <classLoader> type object value 0\n  Field name dirs type object\n  Instance Id 0x64626138 number 1 retained size 3000\n   Instance Field name dirs type object value 1684166952\n    Ref object java.io.File[]#1\n   Instance Field name acc type object value 1684178112\n    Ref object java.security.AccessControlContext#4\n   Instance Field name ucp type object value 1684177480\n    Ref object sun.misc.URLClassPath#1\n   Instance Field name pdcache type object value 1684177360\n    Ref object java.util.HashMap#6\n   Instance Field name initialized type boolean value true\n   Instance Field name classAssertionStatus type object value 0\n   Instance Field name packageAssertionStatus type object value 0\n   Instance Field name defaultAssertionStatus type boolean value false\n   Instance Field name nativeLibraries type object value 1684177280\n    Ref object java.util.Vector#4\n   Instance Field name defaultDomain type object value 0\n   Instance Field name packages type object value 1684177160\n    Ref object java.util.HashMap#5\n   Instance Field name domains type object value 1684177024\n    Ref object java.util.HashSet#1\n   Instance Field name classes type object value 1684176936\n    Ref object java.util.Vector#3\n   Instance Field name nocerts type object value 0\n   Instance Field name package2certs type object value 1684176840\n    Ref object java.util.Hashtable#4\n   Instance Field name parent type object value 0\n   Instance Field name initialized type boolean value true\n   References count 1\n   Field parent of instance 0x64628620\n   Path to nearest GC root\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c9d8598 Class sun.net.www.ParseUtil SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name encodedInPath type object value 1684169584\n   Ref object java.util.BitSet#1\n  Static Field name <classLoader> type object value 0\n Id 0x6c9cd650 Class sun.misc.Launcher$Factory SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name PREFIX type object value 0\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x646258d8 number 1 retained size 8\n   References count 1\n   Field factory of Class sun.misc.Launcher\n   Path to nearest GC root\n    Next object java.lang.Class#286\n Id 0x6c9cd150 Class java.net.URLStreamHandlerFactory SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9ebef8 Class java.net.URLStreamHandler SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9cdef0 Class java.security.SecureClassLoader SuperClass java.lang.ClassLoader Instance size 56 Instance count 0 All Instances Size 0\n  Static Field name debug type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name pdcache type object\n  Field name initialized type boolean\n Id 0x6c9cf0a8 Class java.net.URLClassLoader SuperClass java.security.SecureClassLoader Instance size 64 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name acc type object\n  Field name ucp type object\n Id 0x6c9fecc0 Class java.io.FilePermission SuperClass java.security.Permission Instance size 32 Instance count 1 All Instances Size 32\n  Static Field name serialVersionUID type long value 7930732926638008763\n  Static Field name WILD_CHAR type char value *\n  Static Field name RECURSIVE_CHAR type char value -\n  Static Field name NONE type int value 0\n  Static Field name ALL type int value 15\n  Static Field name DELETE type int value 8\n  Static Field name READ type int value 4\n  Static Field name WRITE type int value 2\n  Static Field name EXECUTE type int value 1\n  Static Field name <classLoader> type object value 0\n  Field name cpath type object\n  Field name actions type object\n  Field name recursive type boolean\n  Field name directory type boolean\n  Field name mask type int\n  Instance Id 0x64630968 number 1 retained size 104\n   Instance Field name cpath type object value 1684178208\n    Ref object java.lang.String#145\n   Instance Field name actions type object value 0\n   Instance Field name recursive type boolean value false\n   Instance Field name directory type boolean value false\n   Instance Field name mask type int value 4\n   Instance Field name name type object value 1684212000\n    Ref object java.lang.String#257\n   References count 1\n   Element 0 of array 0x64630ab8\n   Path to nearest GC root\n    Next object java.lang.Object[]#316\n    Next object java.util.ArrayList#7\n    Next object java.io.FilePermissionCollection#1\n    Next object java.util.HashMap$Entry#153\n    Next object java.util.HashMap$Entry[]#24\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c9f1dd0 Class java.net.URLClassLoader$1 SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name this$0 type object\n  Field name val$name type object\n Id 0x68139440 Class java.net.URLClassLoader$7 SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64625920 number 1 retained size 8\n   References count 1\n   Field javaNetAccess of Class sun.misc.SharedSecrets\n   Path to nearest GC root\n    Next object java.lang.Class#312\n Id 0x6c9fa4a0 Class java.net.URLConnection SuperClass java.lang.Object Instance size 40 Instance count 0 All Instances Size 0\n  Static Field name contentPathProp type object value 0\n  Static Field name contentClassPrefix type object value 0\n  Static Field name UnknownContentHandlerP type object value 1684211992\n   Ref object java.net.UnknownContentHandler#1\n  Static Field name handlers type object value 1684211896\n   Ref object java.util.Hashtable#9\n  Static Field name factory type object value 0\n  Static Field name fileNameMapLoaded type boolean value false\n  Static Field name fileNameMap type object value 0\n  Static Field name defaultUseCaches type boolean value true\n  Static Field name defaultAllowUserInteraction type boolean value false\n  Static Field name <classLoader> type object value 0\n  Field name requests type object\n  Field name readTimeout type int\n  Field name connectTimeout type int\n  Field name connected type boolean\n  Field name ifModifiedSince type long\n  Field name useCaches type boolean\n  Field name allowUserInteraction type boolean\n  Field name doOutput type boolean\n  Field name doInput type boolean\n  Field name url type object\n Id 0x6cc38e68 Class java.util.jar.Attributes$Name SuperClass java.lang.Object Instance size 16 Instance count 29 All Instances Size 464\n  Static Field name SPECIFICATION_VENDOR type object value 1684182256\n   Ref object java.util.jar.Attributes$Name#17\n  Static Field name SPECIFICATION_VERSION type object value 1684182240\n   Ref object java.util.jar.Attributes$Name#16\n  Static Field name SPECIFICATION_TITLE type object value 1684182224\n   Ref object java.util.jar.Attributes$Name#15\n  Static Field name IMPLEMENTATION_URL type object value 1684182208\n   Ref object java.util.jar.Attributes$Name#14\n  Static Field name IMPLEMENTATION_VENDOR_ID type object value 1684182192\n   Ref object java.util.jar.Attributes$Name#13\n  Static Field name IMPLEMENTATION_VENDOR type object value 1684182176\n   Ref object java.util.jar.Attributes$Name#12\n  Static Field name IMPLEMENTATION_VERSION type object value 1684182160\n   Ref object java.util.jar.Attributes$Name#11\n  Static Field name IMPLEMENTATION_TITLE type object value 1684182144\n   Ref object java.util.jar.Attributes$Name#10\n  Static Field name EXTENSION_INSTALLATION type object value 1684182128\n   Ref object java.util.jar.Attributes$Name#9\n  Static Field name EXTENSION_NAME type object value 1684182112\n   Ref object java.util.jar.Attributes$Name#8\n  Static Field name EXTENSION_LIST type object value 1684182096\n   Ref object java.util.jar.Attributes$Name#7\n  Static Field name SEALED type object value 1684182080\n   Ref object java.util.jar.Attributes$Name#6\n  Static Field name MAIN_CLASS type object value 1684182064\n   Ref object java.util.jar.Attributes$Name#5\n  Static Field name CLASS_PATH type object value 1684182048\n   Ref object java.util.jar.Attributes$Name#4\n  Static Field name CONTENT_TYPE type object value 1684182032\n   Ref object java.util.jar.Attributes$Name#3\n  Static Field name SIGNATURE_VERSION type object value 1684182016\n   Ref object java.util.jar.Attributes$Name#2\n  Static Field name MANIFEST_VERSION type object value 1684182000\n   Ref object java.util.jar.Attributes$Name#1\n  Static Field name <classLoader> type object value 0\n  Field name hashCode type int\n  Field name name type object\n  Instance Id 0x646293f0 number 1 retained size 16\n   Instance Field name hashCode type int value -1\n   Instance Field name name type object value 0\n   References count 1\n   Field MANIFEST_VERSION of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x64629400 number 2 retained size 16\n   Instance Field name hashCode type int value -1\n   Instance Field name name type object value 0\n   References count 1\n   Field SIGNATURE_VERSION of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x64629410 number 3 retained size 16\n   Instance Field name hashCode type int value -1\n   Instance Field name name type object value 0\n   References count 1\n   Field CONTENT_TYPE of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x64629420 number 4 retained size 16\n   Instance Field name hashCode type int value -336591014\n   Instance Field name name type object value 0\n   References count 1\n   Field CLASS_PATH of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x64629430 number 5 retained size 16\n   Instance Field name hashCode type int value -1\n   Instance Field name name type object value 0\n   References count 1\n   Field MAIN_CLASS of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x64629440 number 6 retained size 16\n   Instance Field name hashCode type int value -906342564\n   Instance Field name name type object value 0\n   References count 1\n   Field SEALED of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x64629450 number 7 retained size 16\n   Instance Field name hashCode type int value -1\n   Instance Field name name type object value 0\n   References count 1\n   Field EXTENSION_LIST of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x64629460 number 8 retained size 16\n   Instance Field name hashCode type int value -1\n   Instance Field name name type object value 0\n   References count 1\n   Field EXTENSION_NAME of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x64629470 number 9 retained size 16\n   Instance Field name hashCode type int value -1\n   Instance Field name name type object value 0\n   References count 1\n   Field EXTENSION_INSTALLATION of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x64629480 number 10 retained size 16\n   Instance Field name hashCode type int value -174271363\n   Instance Field name name type object value 0\n   References count 1\n   Field IMPLEMENTATION_TITLE of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x64629490 number 11 retained size 16\n   Instance Field name hashCode type int value 1687804349\n   Instance Field name name type object value 0\n   References count 1\n   Field IMPLEMENTATION_VERSION of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x646294a0 number 12 retained size 16\n   Instance Field name hashCode type int value -1054066749\n   Instance Field name name type object value 0\n   References count 1\n   Field IMPLEMENTATION_VENDOR of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x646294b0 number 13 retained size 16\n   Instance Field name hashCode type int value -1\n   Instance Field name name type object value 0\n   References count 1\n   Field IMPLEMENTATION_VENDOR_ID of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x646294c0 number 14 retained size 16\n   Instance Field name hashCode type int value -1\n   Instance Field name name type object value 0\n   References count 1\n   Field IMPLEMENTATION_URL of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x646294d0 number 15 retained size 16\n   Instance Field name hashCode type int value 495347982\n   Instance Field name name type object value 0\n   References count 1\n   Field SPECIFICATION_TITLE of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x646294e0 number 16 retained size 16\n   Instance Field name hashCode type int value 946900494\n   Instance Field name name type object value 0\n   References count 1\n   Field SPECIFICATION_VERSION of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x646294f0 number 17 retained size 16\n   Instance Field name hashCode type int value -1770703534\n   Instance Field name name type object value 0\n   References count 1\n   Field SPECIFICATION_VENDOR of Class java.util.jar.Attributes$Name\n   Path to nearest GC root\n    Next object java.lang.Class#207\n  Instance Id 0x64629500 number 18 retained size 0\n   Instance Field name hashCode type int value 181767994\n   Instance Field name name type object value 0\n   References count 1\n   Field key of instance 0x64629518\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629578 number 19 retained size 0\n   Instance Field name hashCode type int value -389897486\n   Instance Field name name type object value 1746117416\n    Ref object java.lang.String#286\n   References count 1\n   Field key of instance 0x64629588\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629610 number 20 retained size 0\n   Instance Field name hashCode type int value 1369632092\n   Instance Field name name type object value 1746117480\n    Ref object java.lang.String#287\n   References count 1\n   Field key of instance 0x64629620\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629678 number 21 retained size 0\n   Instance Field name hashCode type int value -638856092\n   Instance Field name name type object value 0\n   References count 1\n   Field key of instance 0x64629688\n   Path to nearest GC root\n    Null\n  Instance Id 0x646296c8 number 22 retained size 0\n   Instance Field name hashCode type int value -336591014\n   Instance Field name name type object value 0\n   References count 1\n   Field key of instance 0x646296d8\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629778 number 23 retained size 0\n   Instance Field name hashCode type int value -78718454\n   Instance Field name name type object value 1746117536\n    Ref object java.lang.String#288\n   References count 1\n   Field key of instance 0x64629788\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a4f0 number 24 retained size 0\n   Instance Field name hashCode type int value 181767994\n   Instance Field name name type object value 0\n   References count 1\n   Field key of instance 0x6462a500\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a560 number 25 retained size 0\n   Instance Field name hashCode type int value -389897486\n   Instance Field name name type object value 1746117416\n    Ref object java.lang.String#286\n   References count 1\n   Field key of instance 0x6462a570\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a5f8 number 26 retained size 0\n   Instance Field name hashCode type int value 1369632092\n   Instance Field name name type object value 1746117480\n    Ref object java.lang.String#287\n   References count 1\n   Field key of instance 0x6462a608\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a660 number 27 retained size 0\n   Instance Field name hashCode type int value -638856092\n   Instance Field name name type object value 0\n   References count 1\n   Field key of instance 0x6462a670\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a6b0 number 28 retained size 0\n   Instance Field name hashCode type int value -336591014\n   Instance Field name name type object value 0\n   References count 1\n   Field key of instance 0x6462a6c0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a760 number 29 retained size 0\n   Instance Field name hashCode type int value -78718454\n   Instance Field name name type object value 1746117536\n    Ref object java.lang.String#288\n   References count 1\n   Field key of instance 0x6462a770\n   Path to nearest GC root\n    Null\n Id 0x6cc37a08 Class java.util.jar.Attributes SuperClass java.lang.Object Instance size 16 Instance count 2 All Instances Size 32\n  Static Field name <classLoader> type object value 0\n  Field name map type object\n  Instance Id 0x646291a8 number 1 retained size 0\n   Instance Field name map type object value 1684181432\n    Ref object java.util.HashMap#12\n   References count 1\n   Field attr of instance 0x64629198\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a350 number 2 retained size 0\n   Instance Field name map type object value 1684185952\n    Ref object java.util.HashMap#14\n   References count 1\n   Field attr of instance 0x6462a340\n   Path to nearest GC root\n    Null\n Id 0x6cc35f28 Class java.util.jar.Manifest SuperClass java.lang.Object Instance size 16 Instance count 2 All Instances Size 32\n  Static Field name <classLoader> type object value 0\n  Field name entries type object\n  Field name attr type object\n  Instance Id 0x64629198 number 1 retained size 0\n   Instance Field name entries type object value 1684181552\n    Ref object java.util.HashMap#13\n   Instance Field name attr type object value 1684181416\n    Ref object java.util.jar.Attributes#1\n   References count 1\n   Field referent of instance 0x64629980\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a340 number 2 retained size 0\n   Instance Field name entries type object value 1684186072\n    Ref object java.util.HashMap#15\n   Instance Field name attr type object value 1684185936\n    Ref object java.util.jar.Attributes#2\n   References count 1\n   Field referent of instance 0x6462a788\n   Path to nearest GC root\n    Null\n Id 0x6c9c6910 Class java.lang.StringBuilder SuperClass java.lang.AbstractStringBuilder Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value 4383685877147921099\n  Static Field name <classLoader> type object value 0\n Id 0x6c9d1dd0 Class sun.misc.Launcher$ExtClassLoader$1 SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name val$dirs type object\n Id 0x6c975328 Class java.io.ObjectStreamField SuperClass java.lang.Object Instance size 32 Instance count 10 All Instances Size 320\n  Static Field name <classLoader> type object value 0\n  Field name offset type int\n  Field name field type object\n  Field name unshared type boolean\n  Field name type type object\n  Field name signature type object\n  Field name name type object\n  Instance Id 0x64626340 number 1 retained size 72\n   Instance Field name offset type int value 0\n   Instance Field name field type object value 0\n   Instance Field name unshared type boolean value false\n   Instance Field name type type object value 0\n   Instance Field name signature type object value 1746114232\n    Ref object java.lang.String#270\n   Instance Field name name type object value 0\n   References count 1\n   Element 0 of array 0x64626330\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField[]#3\n    Next object java.lang.Class#228\n  Instance Id 0x64629a78 number 2 retained size 32\n   Instance Field name offset type int value 0\n   Instance Field name field type object value 0\n   Instance Field name unshared type boolean value false\n   Instance Field name type type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name name type object value 0\n   References count 1\n   Element 0 of array 0x64629a60\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField[]#5\n    Next object java.lang.Class#126\n  Instance Id 0x64629a98 number 3 retained size 32\n   Instance Field name offset type int value 0\n   Instance Field name field type object value 0\n   Instance Field name unshared type boolean value false\n   Instance Field name type type object value 1746075664\n    Ref object java.lang.Class#1\n   Instance Field name signature type object value 0\n   Instance Field name name type object value 0\n   References count 1\n   Element 1 of array 0x64629a60\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField[]#5\n    Next object java.lang.Class#126\n  Instance Id 0x64629ab8 number 4 retained size 32\n   Instance Field name offset type int value 0\n   Instance Field name field type object value 0\n   Instance Field name unshared type boolean value false\n   Instance Field name type type object value 1746076048\n    Ref object java.lang.Class#5\n   Instance Field name signature type object value 0\n   Instance Field name name type object value 0\n   References count 1\n   Element 2 of array 0x64629a60\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField[]#5\n    Next object java.lang.Class#126\n  Instance Id 0x646307e8 number 5 retained size 32\n   Instance Field name offset type int value 0\n   Instance Field name field type object value 0\n   Instance Field name unshared type boolean value false\n   Instance Field name type type object value 0\n   Instance Field name signature type object value 1746119768\n    Ref object java.lang.String#290\n   Instance Field name name type object value 0\n   References count 1\n   Element 0 of array 0x646307d0\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField[]#6\n    Next object java.lang.Class#246\n  Instance Id 0x64630808 number 6 retained size 144\n   Instance Field name offset type int value 0\n   Instance Field name field type object value 0\n   Instance Field name unshared type boolean value false\n   Instance Field name type type object value 0\n   Instance Field name signature type object value 1746119952\n    Ref object java.lang.String#292\n   Instance Field name name type object value 0\n   References count 1\n   Element 1 of array 0x646307d0\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField[]#6\n    Next object java.lang.Class#246\n  Instance Id 0x64630a70 number 7 retained size 104\n   Instance Field name offset type int value 0\n   Instance Field name field type object value 0\n   Instance Field name unshared type boolean value false\n   Instance Field name type type object value 0\n   Instance Field name signature type object value 1746120136\n    Ref object java.lang.String#294\n   Instance Field name name type object value 0\n   References count 1\n   Element 0 of array 0x64630a60\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField[]#7\n    Next object java.lang.Class#376\n  Instance Id 0x64630b38 number 8 retained size 32\n   Instance Field name offset type int value 0\n   Instance Field name field type object value 0\n   Instance Field name unshared type boolean value false\n   Instance Field name type type object value 0\n   Instance Field name signature type object value 1746119768\n    Ref object java.lang.String#290\n   Instance Field name name type object value 0\n   References count 1\n   Element 0 of array 0x64630b20\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField[]#8\n    Next object java.lang.Class#407\n  Instance Id 0x64630b58 number 9 retained size 32\n   Instance Field name offset type int value 0\n   Instance Field name field type object value 0\n   Instance Field name unshared type boolean value false\n   Instance Field name type type object value 1746076048\n    Ref object java.lang.Class#5\n   Instance Field name signature type object value 0\n   Instance Field name name type object value 0\n   References count 1\n   Element 1 of array 0x64630b20\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField[]#8\n    Next object java.lang.Class#407\n  Instance Id 0x64630b78 number 10 retained size 32\n   Instance Field name offset type int value 0\n   Instance Field name field type object value 0\n   Instance Field name unshared type boolean value false\n   Instance Field name type type object value 0\n   Instance Field name signature type object value 0\n   Instance Field name name type object value 0\n   References count 1\n   Element 2 of array 0x64630b20\n   Path to nearest GC root\n    Next object java.io.ObjectStreamField[]#8\n    Next object java.lang.Class#407\n Id 0x68130e78 Class java.io.ObjectStreamField[] SuperClass java.lang.Object Instance size -1 Instance count 8 All Instances Size 152\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610588 number 1 retained size 16\n   References count 1\n   Field serialPersistentFields of Class java.lang.String\n   Path to nearest GC root\n    Next object java.lang.Class#95\n  Instance Id 0x64610720 number 2 retained size 16\n   References count 1\n   Field serialPersistentFields of Class java.lang.Class\n   Path to nearest GC root\n    Next object java.lang.Class#86\n  Instance Id 0x64626330 number 3 retained size 88\n   References count 1\n   Field serialPersistentFields of Class java.util.BitSet\n   Path to nearest GC root\n    Next object java.lang.Class#228\n  Instance Id 0x64626360 number 4 retained size 16\n   References count 2\n   Field serialPersistentFields of Class java.io.ObjectStreamClass\n   Field NO_FIELDS of Class java.io.ObjectStreamClass\n   Path to nearest GC root\n    Next object java.lang.Class#404\n  Instance Id 0x64629a60 number 5 retained size 120\n   References count 1\n   Field serialPersistentFields of Class java.lang.StringBuffer\n   Path to nearest GC root\n    Next object java.lang.Class#126\n  Instance Id 0x646307d0 number 6 retained size 200\n   References count 1\n   Field serialPersistentFields of Class java.security.Permissions\n   Path to nearest GC root\n    Next object java.lang.Class#246\n  Instance Id 0x64630a60 number 7 retained size 120\n   References count 1\n   Field serialPersistentFields of Class java.io.FilePermissionCollection\n   Path to nearest GC root\n    Next object java.lang.Class#376\n  Instance Id 0x64630b20 number 8 retained size 120\n   References count 1\n   Field serialPersistentFields of Class java.security.BasicPermissionCollection\n   Path to nearest GC root\n    Next object java.lang.Class#407\n Id 0x6c95ef00 Class java.lang.AbstractStringBuilder SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name sizeTable type object value 1684098920\n   Ref object int[]#1\n  Static Field name <classLoader> type object value 0\n  Field name count type int\n  Field name value type object\n Id 0x6c939900 Class java.lang.Comparable SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x68130cc0 Class java.lang.Comparable[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9d1a40 Class java.security.PrivilegedExceptionAction SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c990a60 Class java.lang.StringCoding SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name warnUnsupportedCharset type boolean value true\n  Static Field name encoder type object value 1684099312\n   Ref object java.lang.ThreadLocal#3\n  Static Field name decoder type object value 1684099296\n   Ref object java.lang.ThreadLocal#2\n  Static Field name <classLoader> type object value 0\n Id 0x6c98c148 Class java.util.Arrays SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name INSERTIONSORT_THRESHOLD type int value 7\n  Static Field name <classLoader> type object value 0\n Id 0x6c975c88 Class java.lang.String$CaseInsensitiveComparator SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name serialVersionUID type long value 8575799808933029326\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610598 number 1 retained size 8\n   References count 1\n   Field CASE_INSENSITIVE_ORDER of Class java.lang.String\n   Path to nearest GC root\n    Next object java.lang.Class#95\n Id 0x6c9e2488 Class java.util.Locale SuperClass java.lang.Object Instance size 32 Instance count 19 All Instances Size 608\n  Static Field name isoCountries type object value 0\n  Static Field name isoLanguages type object value 0\n  Static Field name defaultLocale type object value 1684173744\n   Ref object java.util.Locale#16\n  Static Field name DISPLAY_VARIANT type int value 2\n  Static Field name DISPLAY_COUNTRY type int value 1\n  Static Field name DISPLAY_LANGUAGE type int value 0\n  Static Field name serialVersionUID type long value 9149081749638150636\n  Static Field name ROOT type object value 1684173944\n   Ref object java.util.Locale#19\n  Static Field name CANADA_FRENCH type object value 1684173888\n   Ref object java.util.Locale#18\n  Static Field name CANADA type object value 1684173800\n   Ref object java.util.Locale#17\n  Static Field name US type object value 1684173744\n   Ref object java.util.Locale#16\n  Static Field name UK type object value 1684173688\n   Ref object java.util.Locale#15\n  Static Field name TAIWAN type object value 1684173344\n   Ref object java.util.Locale#9\n  Static Field name PRC type object value 1684173288\n   Ref object java.util.Locale#8\n  Static Field name CHINA type object value 1684173288\n   Ref object java.util.Locale#8\n  Static Field name KOREA type object value 1684173632\n   Ref object java.util.Locale#14\n  Static Field name JAPAN type object value 1684173600\n   Ref object java.util.Locale#13\n  Static Field name ITALY type object value 1684173544\n   Ref object java.util.Locale#12\n  Static Field name GERMANY type object value 1684173488\n   Ref object java.util.Locale#11\n  Static Field name FRANCE type object value 1684173432\n   Ref object java.util.Locale#10\n  Static Field name TRADITIONAL_CHINESE type object value 1684173344\n   Ref object java.util.Locale#9\n  Static Field name SIMPLIFIED_CHINESE type object value 1684173288\n   Ref object java.util.Locale#8\n  Static Field name CHINESE type object value 1684173232\n   Ref object java.util.Locale#7\n  Static Field name KOREAN type object value 1684173176\n   Ref object java.util.Locale#6\n  Static Field name JAPANESE type object value 1684173120\n   Ref object java.util.Locale#5\n  Static Field name ITALIAN type object value 1684173064\n   Ref object java.util.Locale#4\n  Static Field name GERMAN type object value 1684173008\n   Ref object java.util.Locale#3\n  Static Field name FRENCH type object value 1684172952\n   Ref object java.util.Locale#2\n  Static Field name ENGLISH type object value 1684172896\n   Ref object java.util.Locale#1\n  Static Field name cache type object value 1684169952\n   Ref object java.util.concurrent.ConcurrentHashMap#1\n  Static Field name <classLoader> type object value 0\n  Field name hashCodeValue type int\n  Field name hashcode type int\n  Field name variant type object\n  Field name country type object\n  Field name language type object\n  Instance Id 0x64627060 number 1 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field ENGLISH of Class java.util.Locale\n   Field value of instance 0x64627080\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x64627098 number 2 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field FRENCH of Class java.util.Locale\n   Field value of instance 0x646270b8\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x646270d0 number 3 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field GERMAN of Class java.util.Locale\n   Field value of instance 0x646270f0\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x64627108 number 4 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field ITALIAN of Class java.util.Locale\n   Field value of instance 0x64627128\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x64627140 number 5 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field JAPANESE of Class java.util.Locale\n   Field value of instance 0x64627160\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x64627178 number 6 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field KOREAN of Class java.util.Locale\n   Field value of instance 0x64627198\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x646271b0 number 7 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field CHINESE of Class java.util.Locale\n   Field value of instance 0x646271d0\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x646271e8 number 8 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 4\n   Field PRC of Class java.util.Locale\n   Field CHINA of Class java.util.Locale\n   Field SIMPLIFIED_CHINESE of Class java.util.Locale\n   Field value of instance 0x64627208\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x64627220 number 9 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 3\n   Field TAIWAN of Class java.util.Locale\n   Field TRADITIONAL_CHINESE of Class java.util.Locale\n   Field value of instance 0x64627260\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x64627278 number 10 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field FRANCE of Class java.util.Locale\n   Field value of instance 0x64627298\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x646272b0 number 11 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field GERMANY of Class java.util.Locale\n   Field value of instance 0x646272d0\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x646272e8 number 12 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field ITALY of Class java.util.Locale\n   Field value of instance 0x64627308\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x64627320 number 13 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field JAPAN of Class java.util.Locale\n   Field value of instance 0x646274b8\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x64627340 number 14 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field KOREA of Class java.util.Locale\n   Field value of instance 0x64627360\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x64627378 number 15 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field UK of Class java.util.Locale\n   Field value of instance 0x64627398\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x646273b0 number 16 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 3\n   Field defaultLocale of Class java.util.Locale\n   Field US of Class java.util.Locale\n   Field value of instance 0x646273d0\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x646273e8 number 17 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field CANADA of Class java.util.Locale\n   Field value of instance 0x64627428\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x64627440 number 18 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field CANADA_FRENCH of Class java.util.Locale\n   Field value of instance 0x64627460\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x64627478 number 19 retained size 32\n   Instance Field name hashCodeValue type int value 0\n   Instance Field name hashcode type int value -1\n   Instance Field name variant type object value 0\n   Instance Field name country type object value 0\n   Instance Field name language type object value 0\n   References count 2\n   Field ROOT of Class java.util.Locale\n   Field value of instance 0x646274d0\n   Path to nearest GC root\n    Next object java.lang.Class#221\n Id 0x6c9d2518 Class sun.misc.MetaIndex SuperClass java.lang.Object Instance size 16 Instance count 4 All Instances Size 64\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name jarMap type object value 1684167120\n   Ref object java.util.HashMap#3\n  Static Field name <classLoader> type object value 0\n  Field name isClassOnlyJar type boolean\n  Field name contents type object\n  Instance Id 0x64625c48 number 1 retained size 264\n   Instance Field name isClassOnlyJar type boolean value false\n   Instance Field name contents type object value 1684167768\n    Ref object java.lang.String[]#44\n   References count 2\n   Field value of instance 0x64625c70\n   Field metaIndex of instance 0x64629c90\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#1\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625d88 number 2 retained size 152\n   Instance Field name isClassOnlyJar type boolean value false\n   Instance Field name contents type object value 1684168088\n    Ref object java.lang.String[]#45\n   References count 2\n   Field value of instance 0x64625db0\n   Field metaIndex of instance 0x64629d90\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#2\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625f48 number 3 retained size 272\n   Instance Field name isClassOnlyJar type boolean value false\n   Instance Field name contents type object value 1684168536\n    Ref object java.lang.String[]#46\n   References count 2\n   Field value of instance 0x64625f70\n   Field metaIndex of instance 0x64629a00\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#3\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x646260f8 number 4 retained size 264\n   Instance Field name isClassOnlyJar type boolean value false\n   Instance Field name contents type object value 1684168968\n    Ref object java.lang.String[]#47\n   References count 2\n   Field value of instance 0x64626120\n   Field metaIndex of instance 0x64629b88\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#4\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n Id 0x6c9757f8 Class java.util.Comparator SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6caa9180 Class java.util.regex.Pattern SuperClass java.lang.Object Instance size 64 Instance count 1 All Instances Size 64\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name lastAccept type object value 1684199272\n   Ref object java.util.regex.Pattern$LastNode#1\n  Static Field name accept type object value 1684199256\n   Ref object java.util.regex.Pattern$Node#1\n  Static Field name lookbehindEnd type object value 1684199240\n   Ref object java.util.regex.Pattern$8#1\n  Static Field name INDEPENDENT type int value 3\n  Static Field name POSSESSIVE type int value 2\n  Static Field name LAZY type int value 1\n  Static Field name GREEDY type int value 0\n  Static Field name MAX_REPS type int value 2147483647\n  Static Field name serialVersionUID type long value 5073258162644648461\n  Static Field name CANON_EQ type int value 128\n  Static Field name UNICODE_CASE type int value 64\n  Static Field name DOTALL type int value 32\n  Static Field name LITERAL type int value 16\n  Static Field name MULTILINE type int value 8\n  Static Field name COMMENTS type int value 4\n  Static Field name CASE_INSENSITIVE type int value 2\n  Static Field name UNIX_LINES type int value 1\n  Static Field name <classLoader> type object value 0\n  Field name patternLength type int\n  Field name cursor type int\n  Field name localCount type int\n  Field name capturingGroupCount type int\n  Field name temp type object\n  Field name groupNodes type object\n  Field name buffer type object\n  Field name matchRoot type object\n  Field name root type object\n  Field name normalizedPattern type object\n  Field name compiled type boolean\n  Field name flags type int\n  Field name pattern type object\n  Instance Id 0x6462d778 number 1 retained size 2392\n   Instance Field name patternLength type int value 0\n   Instance Field name cursor type int value 93\n   Instance Field name localCount type int value 9\n   Instance Field name capturingGroupCount type int value 10\n   Instance Field name temp type object value 0\n   Instance Field name groupNodes type object value 0\n   Instance Field name buffer type object value 0\n   Instance Field name matchRoot type object value 1684199696\n    Ref object java.util.regex.Pattern$Branch#1\n   Instance Field name root type object value 1684205280\n    Ref object java.util.regex.Pattern$Start#1\n   Instance Field name normalizedPattern type object value 0\n   Instance Field name compiled type boolean value true\n   Instance Field name flags type int value 0\n   Instance Field name pattern type object value 0\n   References count 4\n   Field hexFloatPattern of Class sun.misc.FloatingDecimal\n   Field this$0 of instance 0x6462d940\n   Field this$0 of instance 0x6462e940\n   Field this$0 of instance 0x6462e9f0\n   Path to nearest GC root\n    Next object java.lang.Class#394\n Id 0x6c9d4800 Class java.io.FileReader SuperClass java.io.InputStreamReader Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9d4378 Class java.io.InputStreamReader SuperClass java.io.Reader Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name sd type object\n Id 0x6c9d58b8 Class sun.nio.cs.StreamDecoder SuperClass java.io.Reader Instance size 40 Instance count 0 All Instances Size 0\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name channelsAvailable type boolean value true\n  Static Field name DEFAULT_BYTE_BUFFER_SIZE type int value 8192\n  Static Field name MIN_BYTE_BUFFER_SIZE type int value 32\n  Static Field name <classLoader> type object value 0\n  Field name ch type object\n  Field name in type object\n  Field name bb type object\n  Field name decoder type object\n  Field name cs type object\n  Field name leftoverChar type char\n  Field name haveLeftoverChar type boolean\n  Field name isOpen type boolean\n Id 0x6c9d9d98 Class java.util.BitSet SuperClass java.lang.Object Instance size 24 Instance count 1 All Instances Size 24\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name serialVersionUID type long value 7997698588986878753\n  Static Field name serialPersistentFields type object value 1684169520\n   Ref object java.io.ObjectStreamField[]#3\n  Static Field name WORD_MASK type long value -1\n  Static Field name BIT_INDEX_MASK type int value 63\n  Static Field name BITS_PER_WORD type int value 64\n  Static Field name ADDRESS_BITS_PER_WORD type int value 6\n  Static Field name <classLoader> type object value 0\n  Field name sizeIsSticky type boolean\n  Field name wordsInUse type int\n  Field name words type object\n  Instance Id 0x64626370 number 1 retained size 72\n   Instance Field name sizeIsSticky type boolean value true\n   Instance Field name wordsInUse type int value 2\n   Instance Field name words type object value 1684169608\n    Ref object long[]#1\n   References count 1\n   Field encodedInPath of Class sun.net.www.ParseUtil\n   Path to nearest GC root\n    Next object java.lang.Class#197\n Id 0x6cc3b020 Class java.io.ByteArrayOutputStream SuperClass java.io.OutputStream Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Field name count type int\n  Field name buf type object\n  Instance Id 0x64629940 number 1 retained size 0\n   Instance Field name count type int value 0\n   Instance Field name buf type object value 1684183376\n    Ref object byte[]#10\n   References count 1\n   Field baos of instance 0x646297a0\n   Path to nearest GC root\n    Null\n Id 0x6c9e2ec0 Class java.util.concurrent.ConcurrentMap SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x68135148 Class sun.misc.JavaIODeleteOnExitAccess SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9ece10 Class java.lang.Class$1 SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name this$0 type object\n  Field name val$c type object\n Id 0x6c9b0a18 Class java.lang.Class$3 SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6ca635b0 Class java.lang.Enum SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name ordinal type int\n  Field name name type object\n Id 0x6cc3f220 Class java.lang.Package SuperClass java.lang.Object Instance size 48 Instance count 1 All Instances Size 48\n  Static Field name mans type object value 1684187400\n   Ref object java.util.HashMap#18\n  Static Field name urls type object value 1684187280\n   Ref object java.util.HashMap#17\n  Static Field name pkgs type object value 1684187096\n   Ref object java.util.HashMap#16\n  Static Field name <classLoader> type object value 0\n  Field name packageInfo type object\n  Field name loader type object\n  Field name sealBase type object\n  Field name implVendor type object\n  Field name implVersion type object\n  Field name implTitle type object\n  Field name specVendor type object\n  Field name specVersion type object\n  Field name specTitle type object\n  Field name pkgName type object\n  Instance Id 0x6462a980 number 1 retained size 48\n   Instance Field name packageInfo type object value 0\n   Instance Field name loader type object value 1684178464\n    Ref object sun.misc.Launcher$AppClassLoader#1\n   Instance Field name sealBase type object value 0\n   Instance Field name implVendor type object value 0\n   Instance Field name implVersion type object value 0\n   Instance Field name implTitle type object value 0\n   Instance Field name specVendor type object value 0\n   Instance Field name specVersion type object value 0\n   Instance Field name specTitle type object value 0\n   Instance Field name pkgName type object value 1684187072\n    Ref object java.lang.String#178\n   References count 1\n   Field value of instance 0x6462a9b0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#22\n    Next object java.util.HashMap$Entry[]#11\n    Next object java.util.HashMap#9\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c97bc18 Class java.lang.annotation.Annotation SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x68131560 Class java.lang.annotation.Annotation[] SuperClass java.lang.Object Instance size -1 Instance count 4 All Instances Size 64\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610730 number 1 retained size 16\n   References count 1\n   Field EMPTY_ANNOTATIONS_ARRAY of Class java.lang.Class\n   Path to nearest GC root\n    Next object java.lang.Class#86\n  Instance Id 0x64610960 number 2 retained size 16\n   References count 1\n   Field EMPTY_ANNOTATION_ARRAY of Class java.lang.reflect.Method\n   Path to nearest GC root\n    Next object java.lang.Class#123\n  Instance Id 0x64614de8 number 3 retained size 16\n   References count 1\n   Field EMPTY_ANNOTATION_ARRAY of Class java.lang.reflect.Field\n   Path to nearest GC root\n    Next object java.lang.Class#127\n  Instance Id 0x64614fc0 number 4 retained size 16\n   References count 1\n   Field EMPTY_ANNOTATION_ARRAY of Class java.lang.reflect.Constructor\n   Path to nearest GC root\n    Next object java.lang.Class#121\n Id 0x6c939ae0 Class java.lang.reflect.AnnotatedElement SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c96b718 Class java.lang.reflect.AnnotatedElement[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9d7c38 Class java.lang.reflect.Array SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c939a20 Class java.lang.reflect.GenericDeclaration SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c96ba58 Class java.lang.reflect.GenericDeclaration[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9b14f8 Class java.lang.reflect.Modifier SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name ENUM type int value 16384\n  Static Field name ANNOTATION type int value 8192\n  Static Field name SYNTHETIC type int value 4096\n  Static Field name VARARGS type int value 128\n  Static Field name BRIDGE type int value 64\n  Static Field name STRICT type int value 2048\n  Static Field name ABSTRACT type int value 1024\n  Static Field name INTERFACE type int value 512\n  Static Field name NATIVE type int value 256\n  Static Field name TRANSIENT type int value 128\n  Static Field name VOLATILE type int value 64\n  Static Field name SYNCHRONIZED type int value 32\n  Static Field name FINAL type int value 16\n  Static Field name STATIC type int value 8\n  Static Field name PROTECTED type int value 4\n  Static Field name PRIVATE type int value 2\n  Static Field name PUBLIC type int value 1\n  Static Field name <classLoader> type object value 0\n Id 0x6c939a80 Class java.lang.reflect.Type SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c96b8b8 Class java.lang.reflect.Type[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9f8038 Class java.security.Permissions SuperClass java.security.PermissionCollection Instance size 24 Instance count 2 All Instances Size 48\n  Static Field name serialPersistentFields type object value 1684211664\n   Ref object java.io.ObjectStreamField[]#6\n  Static Field name serialVersionUID type long value 4858622370623524688\n  Static Field name <classLoader> type object value 0\n  Field name allPermission type object\n  Field name hasUnresolved type boolean\n  Field name permsMap type object\n  Instance Id 0x64630828 number 1 retained size 584\n   Instance Field name allPermission type object value 0\n   Instance Field name hasUnresolved type boolean value false\n   Instance Field name permsMap type object value 1684211776\n    Ref object java.util.HashMap#21\n   Instance Field name readOnly type boolean value true\n   References count 1\n   Field permissions of instance 0x64630c58\n   Path to nearest GC root\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64630998 number 2 retained size 144\n   Instance Field name allPermission type object value 0\n   Instance Field name hasUnresolved type boolean value false\n   Instance Field name permsMap type object value 1684212144\n    Ref object java.util.HashMap#22\n   Instance Field name readOnly type boolean value true\n   References count 1\n   Field perms of instance 0x64630988\n   Path to nearest GC root\n    Next object java.security.Policy$UnsupportedEmptyCollection#1\n    Next object java.lang.Class#325\n Id 0x6c9d6dc0 Class java.util.ArrayList SuperClass java.util.AbstractList Instance size 24 Instance count 7 All Instances Size 168\n  Static Field name serialVersionUID type long value 8683452581122892189\n  Static Field name <classLoader> type object value 0\n  Field name size type int\n  Field name elementData type object\n  Instance Id 0x646256b8 number 1 retained size 96\n   Instance Field name size type int value 3\n   Instance Field name elementData type object value 1684166352\n    Ref object java.lang.Object[]#300\n   Instance Field name modCount type int value 3\n   References count 1\n   Field hooks of Class java.lang.Shutdown\n   Path to nearest GC root\n    Next object java.lang.Class#110\n  Instance Id 0x64628268 number 2 retained size 80\n   Instance Field name size type int value 4\n   Instance Field name elementData type object value 1684177536\n    Ref object java.lang.Object[]#304\n   Instance Field name modCount type int value 4\n   References count 1\n   Field path of instance 0x64628248\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628308 number 3 retained size 80\n   Instance Field name size type int value 4\n   Instance Field name elementData type object value 1684177696\n    Ref object java.lang.Object[]#306\n   Instance Field name modCount type int value 4\n   References count 1\n   Field loaders of instance 0x64628248\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628900 number 4 retained size 80\n   Instance Field name size type int value 1\n   Instance Field name elementData type object value 1684179224\n    Ref object java.lang.Object[]#309\n   Instance Field name modCount type int value 1\n   References count 1\n   Field path of instance 0x646288e0\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646289a0 number 5 retained size 80\n   Instance Field name size type int value 1\n   Instance Field name elementData type object value 1684179384\n    Ref object java.lang.Object[]#311\n   Instance Field name modCount type int value 1\n   References count 1\n   Field loaders of instance 0x646288e0\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646298f0 number 6 retained size 0\n   Instance Field name size type int value 0\n   Instance Field name elementData type object value 1684183304\n    Ref object java.lang.Object[]#314\n   Instance Field name modCount type int value 0\n   References count 1\n   Field pendingBlocks of instance 0x646297a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64630aa0 number 7 retained size 184\n   Instance Field name size type int value 1\n   Instance Field name elementData type object value 1684212408\n    Ref object java.lang.Object[]#316\n   Instance Field name modCount type int value 1\n   References count 1\n   Field perms of instance 0x64630a90\n   Path to nearest GC root\n    Next object java.io.FilePermissionCollection#1\n    Next object java.util.HashMap$Entry#153\n    Next object java.util.HashMap$Entry[]#24\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c97d1a0 Class java.security.AccessController SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9ee8c0 Class java.util.HashSet SuperClass java.util.AbstractSet Instance size 16 Instance count 2 All Instances Size 32\n  Static Field name PRESENT type object value 1684177016\n   Ref object java.lang.Object#9\n  Static Field name serialVersionUID type long value -5024744406713321676\n  Static Field name <classLoader> type object value 0\n  Field name map type object\n  Instance Id 0x64628080 number 1 retained size 136\n   Instance Field name map type object value 1684177040\n    Ref object java.util.HashMap#4\n   References count 1\n   Field domains of instance 0x64626138\n   Path to nearest GC root\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628718 number 2 retained size 160\n   Instance Field name map type object value 1684178728\n    Ref object java.util.HashMap#8\n   References count 1\n   Field domains of instance 0x64628620\n   Path to nearest GC root\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c980da8 Class java.util.Iterator SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c97b468 Class java.util.HashMap SuperClass java.util.AbstractMap Instance size 40 Instance count 23 All Instances Size 920\n  Static Field name serialVersionUID type long value 362498820763181265\n  Static Field name DEFAULT_LOAD_FACTOR type float value 0.75\n  Static Field name MAXIMUM_CAPACITY type int value 1073741824\n  Static Field name DEFAULT_INITIAL_CAPACITY type int value 16\n  Static Field name <classLoader> type object value 0\n  Field name entrySet type object\n  Field name modCount type int\n  Field name loadFactor type float\n  Field name threshold type int\n  Field name size type int\n  Field name table type object\n  Instance Id 0x646106f8 number 1 retained size 120\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 0\n   Instance Field name table type object value 1684080448\n    Ref object java.util.HashMap$Entry[]#1\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field hash of instance 0x64610678\n   Path to nearest GC root\n    Next object sun.misc.SoftCache#1\n    Next object java.lang.Class#92\n  Instance Id 0x64614d00 number 2 retained size 120\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 0\n   Instance Field name table type object value 1684098344\n    Ref object java.util.HashMap$Entry[]#2\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field m of instance 0x64614da8\n   Path to nearest GC root\n    Next object java.util.Collections$SynchronizedMap#1\n    Next object java.lang.Class#189\n  Instance Id 0x646259d0 number 3 retained size 792\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 4\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 4\n   Instance Field name table type object value 1684167160\n    Ref object java.util.HashMap$Entry[]#5\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field jarMap of Class sun.misc.MetaIndex\n   Path to nearest GC root\n    Next object java.lang.Class#222\n  Instance Id 0x64628090 number 4 retained size 120\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 0\n   Instance Field name table type object value 1684177080\n    Ref object java.util.HashMap$Entry[]#6\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field map of instance 0x64628080\n   Path to nearest GC root\n    Next object java.util.HashSet#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628108 number 5 retained size 120\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 0\n   Instance Field name table type object value 1684177200\n    Ref object java.util.HashMap$Entry[]#7\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field packages of instance 0x64626138\n   Path to nearest GC root\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646281d0 number 6 retained size 120\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 0\n   Instance Field name table type object value 1684177400\n    Ref object java.util.HashMap$Entry[]#8\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field pdcache of instance 0x64626138\n   Path to nearest GC root\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628358 number 7 retained size 216\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 4\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 4\n   Instance Field name table type object value 1684177792\n    Ref object java.util.HashMap$Entry[]#9\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 5\n   Field lmap of instance 0x64628248\n   Field lmap of instance 0x64629d90\n   Field lmap of instance 0x64629c90\n   Field lmap of instance 0x64629a00\n   Field lmap of instance 0x64629b88\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628728 number 8 retained size 144\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 1\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 1\n   Instance Field name table type object value 1684178768\n    Ref object java.util.HashMap$Entry[]#10\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field map of instance 0x64628718\n   Path to nearest GC root\n    Next object java.util.HashSet#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646287a0 number 9 retained size 216\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 1\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 1\n   Instance Field name table type object value 1684178888\n    Ref object java.util.HashMap$Entry[]#11\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field packages of instance 0x64628620\n   Path to nearest GC root\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628868 number 10 retained size 144\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 1\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 1\n   Instance Field name table type object value 1684179088\n    Ref object java.util.HashMap$Entry[]#12\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field pdcache of instance 0x64628620\n   Path to nearest GC root\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646289f0 number 11 retained size 144\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 1\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 1\n   Instance Field name table type object value 1684179480\n    Ref object java.util.HashMap$Entry[]#13\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 2\n   Field lmap of instance 0x646288e0\n   Field lmap of instance 0x64629e98\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646291b8 number 12 retained size 0\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 6\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 6\n   Instance Field name table type object value 1684181472\n    Ref object java.util.HashMap$Entry[]#14\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field map of instance 0x646291a8\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629230 number 13 retained size 0\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 0\n   Instance Field name table type object value 1684181592\n    Ref object java.util.HashMap$Entry[]#15\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field entries of instance 0x64629198\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a360 number 14 retained size 0\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 6\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 6\n   Instance Field name table type object value 1684185992\n    Ref object java.util.HashMap$Entry[]#16\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field map of instance 0x6462a350\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a3d8 number 15 retained size 0\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 0\n   Instance Field name table type object value 1684186112\n    Ref object java.util.HashMap$Entry[]#17\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field entries of instance 0x6462a340\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a7d8 number 16 retained size 184\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 24\n   Instance Field name size type int value 0\n   Instance Field name table type object value 1684187136\n    Ref object java.util.HashMap$Entry[]#18\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field pkgs of Class java.lang.Package\n   Path to nearest GC root\n    Next object java.lang.Class#235\n  Instance Id 0x6462a890 number 17 retained size 120\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 0\n   Instance Field name table type object value 1684187320\n    Ref object java.util.HashMap$Entry[]#19\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field urls of Class java.lang.Package\n   Path to nearest GC root\n    Next object java.lang.Class#235\n  Instance Id 0x6462a908 number 18 retained size 120\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 0\n   Instance Field name table type object value 1684187440\n    Ref object java.util.HashMap$Entry[]#20\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field mans of Class java.lang.Package\n   Path to nearest GC root\n    Next object java.lang.Class#235\n  Instance Id 0x6462a9e0 number 19 retained size 4736\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 60\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 96\n   Instance Field name size type int value 60\n   Instance Field name table type object value 1684191088\n    Ref object java.util.HashMap$Entry[]#21\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field knownEngines of Class java.security.Provider\n   Path to nearest GC root\n    Next object java.lang.Class#328\n  Instance Id 0x6462daf0 number 20 retained size 3616\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 70\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 96\n   Instance Field name size type int value 70\n   Instance Field name table type object value 1684202168\n    Ref object java.util.HashMap$Entry[]#22\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field map of Class java.util.regex.Pattern$CharPropertyNames\n   Path to nearest GC root\n    Next object java.lang.Class#21\n  Instance Id 0x64630840 number 21 retained size 560\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 2\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 2\n   Instance Field name table type object value 1684211816\n    Ref object java.util.HashMap$Entry[]#24\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field permsMap of instance 0x64630828\n   Path to nearest GC root\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646309b0 number 22 retained size 120\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 0\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 0\n   Instance Field name table type object value 1684212184\n    Ref object java.util.HashMap$Entry[]#25\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field permsMap of instance 0x64630998\n   Path to nearest GC root\n    Next object java.security.Permissions#2\n    Next object java.security.Policy$UnsupportedEmptyCollection#1\n    Next object java.lang.Class#325\n  Instance Id 0x64630bb0 number 23 retained size 168\n   Instance Field name entrySet type object value 0\n   Instance Field name modCount type int value 1\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 12\n   Instance Field name size type int value 1\n   Instance Field name table type object value 1684212696\n    Ref object java.util.HashMap$Entry[]#26\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field perms of instance 0x64630b98\n   Path to nearest GC root\n    Next object java.security.BasicPermissionCollection#1\n    Next object java.util.HashMap$Entry#154\n    Next object java.util.HashMap$Entry[]#24\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c956d88 Class java.util.Collection SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9a2e08 Class java.util.Set SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c97c050 Class java.util.Map$Entry SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x68131700 Class java.util.Map$Entry[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c957888 Class java.util.List SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c94aa60 Class java.util.Map SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c97f398 Class sun.reflect.ReflectionFactory SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name inflationThreshold type int value 15\n  Static Field name noInflation type boolean value false\n  Static Field name langReflectAccess type object value 1684098872\n   Ref object java.lang.reflect.ReflectAccess#1\n  Static Field name soleInstance type object value 1684080984\n   Ref object sun.reflect.ReflectionFactory#1\n  Static Field name reflectionFactoryAccessPerm type object value 1684080960\n   Ref object java.lang.RuntimePermission#2\n  Static Field name initted type boolean value true\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610958 number 1 retained size 8\n   References count 4\n   Field reflectionFactory of Class java.lang.Class\n   Field reflFactory of Class java.io.ObjectStreamClass\n   Field reflectionFactory of Class java.lang.reflect.AccessibleObject\n   Field soleInstance of Class sun.reflect.ReflectionFactory\n   Path to nearest GC root\n    Next object java.lang.Class#86\n Id 0x6c97dc68 Class sun.reflect.ReflectionFactory$GetReflectionFactoryAction SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cae7190 Class java.io.DataInput SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9eb338 Class java.net.Parts SuperClass java.lang.Object Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name ref type object\n  Field name query type object\n  Field name path type object\n Id 0x6c9e4128 Class java.util.concurrent.ConcurrentHashMap SuperClass java.util.AbstractMap Instance size 40 Instance count 2 All Instances Size 80\n  Static Field name RETRIES_BEFORE_LOCK type int value 2\n  Static Field name MAX_SEGMENTS type int value 65536\n  Static Field name MAXIMUM_CAPACITY type int value 1073741824\n  Static Field name DEFAULT_CONCURRENCY_LEVEL type int value 16\n  Static Field name DEFAULT_LOAD_FACTOR type float value 0.75\n  Static Field name DEFAULT_INITIAL_CAPACITY type int value 16\n  Static Field name serialVersionUID type long value 7249069246763182397\n  Static Field name <classLoader> type object value 0\n  Field name values type object\n  Field name entrySet type object\n  Field name keySet type object\n  Field name segments type object\n  Field name segmentShift type int\n  Field name segmentMask type int\n  Instance Id 0x646264e0 number 1 retained size 1880\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name segments type object value 1684169992\n    Ref object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n   Instance Field name segmentShift type int value 28\n   Instance Field name segmentMask type int value 15\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field cache of Class java.util.Locale\n   Path to nearest GC root\n    Next object java.lang.Class#221\n  Instance Id 0x6462ce60 number 2 retained size 1272\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name segments type object value 1684197000\n    Ref object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n   Instance Field name segmentShift type int value 28\n   Instance Field name segmentMask type int value 15\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field spiMap of Class java.security.Security\n   Path to nearest GC root\n    Next object java.lang.Class#341\n Id 0x6c9ea0a0 Class java.util.concurrent.ConcurrentHashMap$HashEntry SuperClass java.lang.Object Instance size 24 Instance count 19 All Instances Size 456\n  Static Field name <classLoader> type object value 0\n  Field name next type object\n  Field name value type object\n  Field name hash type int\n  Field name key type object\n  Instance Id 0x64627080 number 1 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684172896\n    Ref object java.util.Locale#1\n   Instance Field name hash type int value -1316117802\n   Instance Field name key type object value 0\n   References count 1\n   Element 0 of array 0x64626f20\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#10\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#12\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x646270b8 number 2 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684172952\n    Ref object java.util.Locale#2\n   Instance Field name hash type int value -1606286385\n   Instance Field name key type object value 0\n   References count 1\n   Element 1 of array 0x64626ed0\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#9\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#11\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x646270f0 number 3 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684173008\n    Ref object java.util.Locale#3\n   Instance Field name hash type int value -985252030\n   Instance Field name key type object value 0\n   References count 1\n   Element 0 of array 0x64626f70\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#11\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#13\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627128 number 4 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684173064\n    Ref object java.util.Locale#4\n   Instance Field name hash type int value 1899746734\n   Instance Field name key type object value 0\n   References count 1\n   Element 0 of array 0x64626de0\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#6\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#8\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627160 number 5 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684173120\n    Ref object java.util.Locale#5\n   Instance Field name hash type int value 1794343651\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x64627208\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry#8\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#14\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#7\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627198 number 6 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684173176\n    Ref object java.util.Locale#6\n   Instance Field name hash type int value 1423652293\n   Instance Field name key type object value 0\n   References count 1\n   Element 1 of array 0x64626d58\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#5\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#6\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x646271d0 number 7 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684173232\n    Ref object java.util.Locale#7\n   Instance Field name hash type int value 1895120779\n   Instance Field name key type object value 0\n   References count 1\n   Element 1 of array 0x64626de0\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#6\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#8\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627208 number 8 retained size 48\n   Instance Field name next type object value 1684173152\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry#5\n   Instance Field name value type object value 1684173288\n    Ref object java.util.Locale#8\n   Instance Field name hash type int value 1840077843\n   Instance Field name key type object value 0\n   References count 1\n   Element 3 of array 0x64627240\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#14\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#7\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627260 number 9 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684173344\n    Ref object java.util.Locale#9\n   Instance Field name hash type int value 1700181348\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x64627308\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry#12\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#14\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#7\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627298 number 10 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684173432\n    Ref object java.util.Locale#10\n   Instance Field name hash type int value -649682901\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x64627460\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry#17\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#12\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#14\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x646272d0 number 11 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684173488\n    Ref object java.util.Locale#11\n   Instance Field name hash type int value -219373268\n   Instance Field name key type object value 0\n   References count 1\n   Element 0 of array 0x64627498\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#16\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#16\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627308 number 12 retained size 48\n   Instance Field name next type object value 1684173408\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry#9\n   Instance Field name value type object value 1684173544\n    Ref object java.util.Locale#12\n   Instance Field name hash type int value 1687888428\n   Instance Field name key type object value 0\n   References count 1\n   Element 0 of array 0x64627240\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#14\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#7\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627360 number 13 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684173632\n    Ref object java.util.Locale#14\n   Instance Field name hash type int value -354787699\n   Instance Field name key type object value 0\n   References count 1\n   Element 1 of array 0x64627010\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#13\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#15\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627398 number 14 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684173688\n    Ref object java.util.Locale#15\n   Instance Field name hash type int value 967873214\n   Instance Field name key type object value 0\n   References count 1\n   Element 2 of array 0x64627408\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#15\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#4\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x646273d0 number 15 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684173744\n    Ref object java.util.Locale#16\n   Instance Field name hash type int value 848103275\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x64627428\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry#16\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#15\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#4\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627428 number 16 retained size 48\n   Instance Field name next type object value 1684173776\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry#15\n   Instance Field name value type object value 1684173800\n    Ref object java.util.Locale#17\n   Instance Field name hash type int value 1007440859\n   Instance Field name key type object value 0\n   References count 1\n   Element 3 of array 0x64627408\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#15\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#4\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627460 number 17 retained size 48\n   Instance Field name next type object value 1684173464\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry#10\n   Instance Field name value type object value 1684173888\n    Ref object java.util.Locale#18\n   Instance Field name hash type int value -608176835\n   Instance Field name key type object value 0\n   References count 1\n   Element 1 of array 0x64626fc0\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#12\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#14\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x646274b8 number 18 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684173600\n    Ref object java.util.Locale#13\n   Instance Field name hash type int value -106518434\n   Instance Field name key type object value 0\n   References count 1\n   Element 2 of array 0x64627498\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#16\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#16\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x646274d0 number 19 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684173944\n    Ref object java.util.Locale#19\n   Instance Field name hash type int value -23505439\n   Instance Field name key type object value 0\n   References count 1\n   Element 1 of array 0x64627498\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$HashEntry[]#16\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#16\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n Id 0x6813a0c8 Class java.util.concurrent.ConcurrentHashMap$HashEntry[] SuperClass java.lang.Object Instance size -1 Instance count 32 All Instances Size 664\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64626be0 number 1 retained size 24\n   References count 1\n   Field table of instance 0x64626558\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#1\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626c30 number 2 retained size 24\n   References count 1\n   Field table of instance 0x64626bf8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#2\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626c80 number 3 retained size 24\n   References count 1\n   Field table of instance 0x64626c48\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#3\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626d08 number 4 retained size 24\n   References count 1\n   Field table of instance 0x64626cd0\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#5\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626d58 number 5 retained size 48\n   References count 1\n   Field table of instance 0x64626d20\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#6\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626de0 number 6 retained size 72\n   References count 1\n   Field table of instance 0x64626da8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#8\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626e30 number 7 retained size 24\n   References count 1\n   Field table of instance 0x64626df8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#9\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626e80 number 8 retained size 24\n   References count 1\n   Field table of instance 0x64626e48\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#10\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626ed0 number 9 retained size 48\n   References count 1\n   Field table of instance 0x64626e98\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#11\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626f20 number 10 retained size 48\n   References count 1\n   Field table of instance 0x64626ee8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#12\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626f70 number 11 retained size 48\n   References count 1\n   Field table of instance 0x64626f38\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#13\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626fc0 number 12 retained size 72\n   References count 1\n   Field table of instance 0x64626f88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#14\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627010 number 13 retained size 48\n   References count 1\n   Field table of instance 0x64626fd8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#15\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627240 number 14 retained size 128\n   References count 1\n   Field table of instance 0x64626d70\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#7\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627408 number 15 retained size 104\n   References count 1\n   Field table of instance 0x64626c98\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#4\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627498 number 16 retained size 104\n   References count 1\n   Field table of instance 0x64627028\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#16\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x6462cf10 number 17 retained size 16\n   References count 1\n   Field table of instance 0x6462ced8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#17\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cf58 number 18 retained size 16\n   References count 1\n   Field table of instance 0x6462cf20\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#18\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cfa0 number 19 retained size 16\n   References count 1\n   Field table of instance 0x6462cf68\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#19\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cfe8 number 20 retained size 16\n   References count 1\n   Field table of instance 0x6462cfb0\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#20\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d030 number 21 retained size 16\n   References count 1\n   Field table of instance 0x6462cff8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#21\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d078 number 22 retained size 16\n   References count 1\n   Field table of instance 0x6462d040\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#22\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d0c0 number 23 retained size 16\n   References count 1\n   Field table of instance 0x6462d088\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#23\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d108 number 24 retained size 16\n   References count 1\n   Field table of instance 0x6462d0d0\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#24\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d150 number 25 retained size 16\n   References count 1\n   Field table of instance 0x6462d118\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#25\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d198 number 26 retained size 16\n   References count 1\n   Field table of instance 0x6462d160\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#26\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d1e0 number 27 retained size 16\n   References count 1\n   Field table of instance 0x6462d1a8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#27\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d228 number 28 retained size 16\n   References count 1\n   Field table of instance 0x6462d1f0\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#28\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d270 number 29 retained size 16\n   References count 1\n   Field table of instance 0x6462d238\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#29\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d2b8 number 30 retained size 16\n   References count 1\n   Field table of instance 0x6462d280\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#30\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d300 number 31 retained size 16\n   References count 1\n   Field table of instance 0x6462d2c8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#31\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d348 number 32 retained size 16\n   References count 1\n   Field table of instance 0x6462d310\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#32\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n Id 0x6cc2fa60 Class java.util.zip.ZipConstants SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name ENDCOM type int value 20\n  Static Field name ENDOFF type int value 16\n  Static Field name ENDSIZ type int value 12\n  Static Field name ENDTOT type int value 10\n  Static Field name ENDSUB type int value 8\n  Static Field name CENOFF type int value 42\n  Static Field name CENATX type int value 38\n  Static Field name CENATT type int value 36\n  Static Field name CENDSK type int value 34\n  Static Field name CENCOM type int value 32\n  Static Field name CENEXT type int value 30\n  Static Field name CENNAM type int value 28\n  Static Field name CENLEN type int value 24\n  Static Field name CENSIZ type int value 20\n  Static Field name CENCRC type int value 16\n  Static Field name CENTIM type int value 12\n  Static Field name CENHOW type int value 10\n  Static Field name CENFLG type int value 8\n  Static Field name CENVER type int value 6\n  Static Field name CENVEM type int value 4\n  Static Field name EXTLEN type int value 12\n  Static Field name EXTSIZ type int value 8\n  Static Field name EXTCRC type int value 4\n  Static Field name LOCEXT type int value 28\n  Static Field name LOCNAM type int value 26\n  Static Field name LOCLEN type int value 22\n  Static Field name LOCSIZ type int value 18\n  Static Field name LOCCRC type int value 14\n  Static Field name LOCTIM type int value 10\n  Static Field name LOCHOW type int value 8\n  Static Field name LOCFLG type int value 6\n  Static Field name LOCVER type int value 4\n  Static Field name ENDHDR type int value 22\n  Static Field name CENHDR type int value 46\n  Static Field name EXTHDR type int value 16\n  Static Field name LOCHDR type int value 30\n  Static Field name ENDSIG type long value 101010256\n  Static Field name CENSIG type long value 33639248\n  Static Field name EXTSIG type long value 134695760\n  Static Field name LOCSIG type long value 67324752\n  Static Field name <classLoader> type object value 0\n Id 0x6c9e6180 Class java.util.concurrent.ConcurrentHashMap$Segment SuperClass java.util.concurrent.locks.ReentrantLock Instance size 32 Instance count 32 All Instances Size 1024\n  Static Field name serialVersionUID type long value 2249069246763182397\n  Static Field name <classLoader> type object value 0\n  Field name loadFactor type float\n  Field name table type object\n  Field name threshold type int\n  Field name modCount type int\n  Field name count type int\n  Instance Id 0x64626558 number 1 retained size 80\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684171744\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#1\n   Instance Field name threshold type int value 1\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684171720\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#1\n   References count 1\n   Element 0 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626bf8 number 2 retained size 80\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684171824\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#2\n   Instance Field name threshold type int value 1\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684171800\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#2\n   References count 1\n   Element 1 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626c48 number 3 retained size 80\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684171904\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#3\n   Instance Field name threshold type int value 1\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684171880\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#3\n   References count 1\n   Element 2 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626c98 number 4 retained size 160\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684173832\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#15\n   Instance Field name threshold type int value 3\n   Instance Field name modCount type int value 3\n   Instance Field name count type int value 3\n   Instance Field name sync type object value 1684171960\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#4\n   References count 1\n   Element 3 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626cd0 number 5 retained size 80\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684172040\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#4\n   Instance Field name threshold type int value 1\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684172016\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#5\n   References count 1\n   Element 4 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626d20 number 6 retained size 104\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684172120\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#5\n   Instance Field name threshold type int value 1\n   Instance Field name modCount type int value 1\n   Instance Field name count type int value 1\n   Instance Field name sync type object value 1684172096\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#6\n   References count 1\n   Element 5 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626d70 number 7 retained size 184\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684173376\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#14\n   Instance Field name threshold type int value 3\n   Instance Field name modCount type int value 4\n   Instance Field name count type int value 4\n   Instance Field name sync type object value 1684172176\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#7\n   References count 1\n   Element 6 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626da8 number 8 retained size 128\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684172256\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#6\n   Instance Field name threshold type int value 1\n   Instance Field name modCount type int value 2\n   Instance Field name count type int value 2\n   Instance Field name sync type object value 1684172232\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#8\n   References count 1\n   Element 7 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626df8 number 9 retained size 80\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684172336\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#7\n   Instance Field name threshold type int value 1\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684172312\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#9\n   References count 1\n   Element 8 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626e48 number 10 retained size 80\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684172416\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#8\n   Instance Field name threshold type int value 1\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684172392\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#10\n   References count 1\n   Element 9 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626e98 number 11 retained size 104\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684172496\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#9\n   Instance Field name threshold type int value 1\n   Instance Field name modCount type int value 1\n   Instance Field name count type int value 1\n   Instance Field name sync type object value 1684172472\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#11\n   References count 1\n   Element 10 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626ee8 number 12 retained size 104\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684172576\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#10\n   Instance Field name threshold type int value 1\n   Instance Field name modCount type int value 1\n   Instance Field name count type int value 1\n   Instance Field name sync type object value 1684172552\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#12\n   References count 1\n   Element 11 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626f38 number 13 retained size 104\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684172656\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#11\n   Instance Field name threshold type int value 1\n   Instance Field name modCount type int value 1\n   Instance Field name count type int value 1\n   Instance Field name sync type object value 1684172632\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#13\n   References count 1\n   Element 12 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626f88 number 14 retained size 128\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684172736\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#12\n   Instance Field name threshold type int value 1\n   Instance Field name modCount type int value 2\n   Instance Field name count type int value 2\n   Instance Field name sync type object value 1684172712\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#14\n   References count 1\n   Element 13 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626fd8 number 15 retained size 104\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684172816\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#13\n   Instance Field name threshold type int value 1\n   Instance Field name modCount type int value 1\n   Instance Field name count type int value 1\n   Instance Field name sync type object value 1684172792\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#15\n   References count 1\n   Element 14 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627028 number 16 retained size 160\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684173976\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#16\n   Instance Field name threshold type int value 3\n   Instance Field name modCount type int value 3\n   Instance Field name count type int value 3\n   Instance Field name sync type object value 1684172872\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#16\n   References count 1\n   Element 15 of array 0x64626508\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x6462ced8 number 17 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684197136\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#17\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684197112\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#17\n   References count 1\n   Element 0 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cf20 number 18 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684197208\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#18\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684197184\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#18\n   References count 1\n   Element 1 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cf68 number 19 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684197280\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#19\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684197256\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#19\n   References count 1\n   Element 2 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cfb0 number 20 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684197352\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#20\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684197328\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#20\n   References count 1\n   Element 3 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cff8 number 21 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684197424\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#21\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684197400\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#21\n   References count 1\n   Element 4 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d040 number 22 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684197496\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#22\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684197472\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#22\n   References count 1\n   Element 5 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d088 number 23 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684197568\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#23\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684197544\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#23\n   References count 1\n   Element 6 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d0d0 number 24 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684197640\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#24\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684197616\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#24\n   References count 1\n   Element 7 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d118 number 25 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684197712\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#25\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684197688\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#25\n   References count 1\n   Element 8 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d160 number 26 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684197784\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#26\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684197760\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#26\n   References count 1\n   Element 9 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d1a8 number 27 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684197856\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#27\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684197832\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#27\n   References count 1\n   Element 10 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d1f0 number 28 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684197928\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#28\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684197904\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#28\n   References count 1\n   Element 11 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d238 number 29 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684198000\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#29\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684197976\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#29\n   References count 1\n   Element 12 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d280 number 30 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684198072\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#30\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684198048\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#30\n   References count 1\n   Element 13 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d2c8 number 31 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684198144\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#31\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684198120\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#31\n   References count 1\n   Element 14 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d310 number 32 retained size 72\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name table type object value 1684198216\n    Ref object java.util.concurrent.ConcurrentHashMap$HashEntry[]#32\n   Instance Field name threshold type int value 0\n   Instance Field name modCount type int value 0\n   Instance Field name count type int value 0\n   Instance Field name sync type object value 1684198192\n    Ref object java.util.concurrent.locks.ReentrantLock$NonfairSync#32\n   References count 1\n   Element 15 of array 0x6462ce88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n Id 0x68139c08 Class java.util.concurrent.ConcurrentHashMap$Segment[] SuperClass java.lang.Object Instance size -1 Instance count 2 All Instances Size 160\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64626508 number 1 retained size 1840\n   References count 1\n   Field segments of instance 0x646264e0\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x6462ce88 number 2 retained size 1232\n   References count 1\n   Field segments of instance 0x6462ce60\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n Id 0x6cc310e8 Class java.util.zip.ZipFile SuperClass java.lang.Object Instance size 32 Instance count 0 All Instances Size 0\n  Static Field name OPEN_DELETE type int value 4\n  Static Field name OPEN_READ type int value 1\n  Static Field name DEFLATED type int value 8\n  Static Field name STORED type int value 0\n  Static Field name <classLoader> type object value 0\n  Field name inflaters type object\n  Field name closeRequested type boolean\n  Field name total type int\n  Field name name type object\n  Field name jzfile type long\n Id 0x6c9c7278 Class java.lang.ClassLoader$3 SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name val$file type object\n Id 0x6c9bef18 Class java.io.File SuperClass java.lang.Object Instance size 16 Instance count 6 All Instances Size 96\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name serialVersionUID type long value 301077366599181567\n  Static Field name tmpdir type object value 0\n  Static Field name counter type int value -1\n  Static Field name tmpFileLock type object value 1684106928\n   Ref object java.lang.Object#6\n  Static Field name pathSeparator type object value 1684106888\n   Ref object java.lang.String#101\n  Static Field name pathSeparatorChar type char value :\n  Static Field name separator type object value 1684106848\n   Ref object java.lang.String#100\n  Static Field name separatorChar type char value /\n  Static Field name fs type object value 1684106408\n   Ref object java.io.UnixFileSystem#1\n  Static Field name <classLoader> type object value 0\n  Field name prefixLength type int\n  Field name path type object\n  Instance Id 0x64625940 number 1 retained size 16\n   Instance Field name prefixLength type int value 1\n   Instance Field name path type object value 1684166992\n    Ref object java.lang.String#113\n   References count 1\n   Element 0 of array 0x64625928\n   Path to nearest GC root\n    Next object java.io.File[]#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64625968 number 2 retained size 40\n   Instance Field name prefixLength type int value 1\n   Instance Field name path type object value 1684167032\n    Ref object java.lang.String#114\n   References count 1\n   Element 1 of array 0x64625928\n   Path to nearest GC root\n    Next object java.io.File[]#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64625bc0 number 3 retained size 136\n   Instance Field name prefixLength type int value 1\n   Instance Field name path type object value 1684167632\n    Ref object java.lang.String#118\n   References count 1\n   Field key of instance 0x64625c70\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#1\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625cf8 number 4 retained size 144\n   Instance Field name prefixLength type int value 1\n   Instance Field name path type object value 1684167944\n    Ref object java.lang.String#121\n   References count 1\n   Field key of instance 0x64625db0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#2\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625eb0 number 5 retained size 152\n   Instance Field name prefixLength type int value 1\n   Instance Field name path type object value 1684168384\n    Ref object java.lang.String#125\n   References count 1\n   Field key of instance 0x64625f70\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#3\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64626068 number 6 retained size 144\n   Instance Field name prefixLength type int value 1\n   Instance Field name path type object value 1684168824\n    Ref object java.lang.String#129\n   References count 1\n   Field key of instance 0x64626120\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#4\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n Id 0x68139658 Class java.io.File[] SuperClass java.lang.Object Instance size -1 Instance count 1 All Instances Size 24\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64625928 number 1 retained size 80\n   References count 1\n   Field dirs of instance 0x64626138\n   Path to nearest GC root\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c9f1930 Class java.lang.SystemClassLoaderAction SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name parent type object\n Id 0x6c9e03e8 Class java.net.URL SuperClass java.lang.Object Instance size 56 Instance count 10 All Instances Size 560\n  Static Field name streamHandlerLock type object value 1684169888\n   Ref object java.lang.Object#8\n  Static Field name handlers type object value 1684169792\n   Ref object java.util.Hashtable#3\n  Static Field name factory type object value 0\n  Static Field name protocolPathProp type object value 0\n  Static Field name serialVersionUID type long value -7627629688361524110\n  Static Field name <classLoader> type object value 0\n  Field name hashCode type int\n  Field name handler type object\n  Field name hostAddress type object\n  Field name ref type object\n  Field name userInfo type object\n  Field name path type object\n  Field name authority type object\n  Field name query type object\n  Field name file type object\n  Field name port type int\n  Field name host type object\n  Field name protocol type object\n  Instance Id 0x646264a8 number 1 retained size 192\n   Instance Field name hashCode type int value 1094987052\n   Instance Field name handler type object value 1684175344\n    Ref object sun.net.www.protocol.file.Handler#1\n   Instance Field name hostAddress type object value 0\n   Instance Field name ref type object value 0\n   Instance Field name userInfo type object value 0\n   Instance Field name path type object value 1684169656\n    Ref object java.lang.String#134\n   Instance Field name authority type object value 0\n   Instance Field name query type object value 0\n   Instance Field name file type object value 1684169656\n    Ref object java.lang.String#134\n   Instance Field name port type int value -1\n   Instance Field name host type object value 0\n   Instance Field name protocol type object value 0\n   References count 3\n   Element 0 of array 0x64628280\n   Field csu of instance 0x64629a00\n   Field key of instance 0x64629b70\n   Path to nearest GC root\n    Next object java.lang.Object[]#304\n    Next object java.util.ArrayList#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64627bc8 number 2 retained size 184\n   Instance Field name hashCode type int value -1082233293\n   Instance Field name handler type object value 1684175344\n    Ref object sun.net.www.protocol.file.Handler#1\n   Instance Field name hostAddress type object value 0\n   Instance Field name ref type object value 0\n   Instance Field name userInfo type object value 0\n   Instance Field name path type object value 1684175688\n    Ref object java.lang.String#137\n   Instance Field name authority type object value 0\n   Instance Field name query type object value 0\n   Instance Field name file type object value 1684175688\n    Ref object java.lang.String#137\n   Instance Field name port type int value -1\n   Instance Field name host type object value 0\n   Instance Field name protocol type object value 0\n   References count 3\n   Element 1 of array 0x64628280\n   Field csu of instance 0x64629b88\n   Field key of instance 0x64629c78\n   Path to nearest GC root\n    Next object java.lang.Object[]#304\n    Next object java.util.ArrayList#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64627da0 number 3 retained size 176\n   Instance Field name hashCode type int value 528592138\n   Instance Field name handler type object value 1684175344\n    Ref object sun.net.www.protocol.file.Handler#1\n   Instance Field name hostAddress type object value 0\n   Instance Field name ref type object value 0\n   Instance Field name userInfo type object value 0\n   Instance Field name path type object value 1684176168\n    Ref object java.lang.String#140\n   Instance Field name authority type object value 0\n   Instance Field name query type object value 0\n   Instance Field name file type object value 1684176168\n    Ref object java.lang.String#140\n   Instance Field name port type int value -1\n   Instance Field name host type object value 0\n   Instance Field name protocol type object value 0\n   References count 3\n   Element 2 of array 0x64628280\n   Field csu of instance 0x64629c90\n   Field key of instance 0x64629d78\n   Path to nearest GC root\n    Next object java.lang.Object[]#304\n    Next object java.util.ArrayList#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64627f90 number 4 retained size 184\n   Instance Field name hashCode type int value -1084663432\n   Instance Field name handler type object value 1684175344\n    Ref object sun.net.www.protocol.file.Handler#1\n   Instance Field name hostAddress type object value 0\n   Instance Field name ref type object value 0\n   Instance Field name userInfo type object value 0\n   Instance Field name path type object value 1684176656\n    Ref object java.lang.String#143\n   Instance Field name authority type object value 0\n   Instance Field name query type object value 0\n   Instance Field name file type object value 1684176656\n    Ref object java.lang.String#143\n   Instance Field name port type int value -1\n   Instance Field name host type object value 0\n   Instance Field name protocol type object value 0\n   References count 3\n   Element 3 of array 0x64628280\n   Field csu of instance 0x64629d90\n   Field key of instance 0x64629e80\n   Path to nearest GC root\n    Next object java.lang.Object[]#304\n    Next object java.util.ArrayList#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646285e8 number 5 retained size 128\n   Instance Field name hashCode type int value 744619056\n   Instance Field name handler type object value 1684175344\n    Ref object sun.net.www.protocol.file.Handler#1\n   Instance Field name hostAddress type object value 0\n   Instance Field name ref type object value 0\n   Instance Field name userInfo type object value 0\n   Instance Field name path type object value 1684178336\n    Ref object java.lang.String#146\n   Instance Field name authority type object value 0\n   Instance Field name query type object value 0\n   Instance Field name file type object value 1684178336\n    Ref object java.lang.String#146\n   Instance Field name port type int value -1\n   Instance Field name host type object value 0\n   Instance Field name protocol type object value 0\n   References count 4\n   Element 0 of array 0x64628918\n   Field location of instance 0x646307b0\n   Field csu of instance 0x64629e98\n   Field key of instance 0x6462a7a8\n   Path to nearest GC root\n    Next object java.lang.Object[]#309\n    Next object java.util.ArrayList#4\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629a28 number 6 retained size 208\n   Instance Field name hashCode type int value -1\n   Instance Field name handler type object value 1684178104\n    Ref object sun.net.www.protocol.jar.Handler#1\n   Instance Field name hostAddress type object value 0\n   Instance Field name ref type object value 0\n   Instance Field name userInfo type object value 0\n   Instance Field name path type object value 1684183768\n    Ref object java.lang.String#156\n   Instance Field name authority type object value 0\n   Instance Field name query type object value 0\n   Instance Field name file type object value 1684183768\n    Ref object java.lang.String#156\n   Instance Field name port type int value -1\n   Instance Field name host type object value 0\n   Instance Field name protocol type object value 0\n   References count 1\n   Field base of instance 0x64629a00\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath$JarLoader#1\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629bb0 number 7 retained size 200\n   Instance Field name hashCode type int value -1\n   Instance Field name handler type object value 1684178104\n    Ref object sun.net.www.protocol.jar.Handler#1\n   Instance Field name hostAddress type object value 0\n   Instance Field name ref type object value 0\n   Instance Field name userInfo type object value 0\n   Instance Field name path type object value 1684184040\n    Ref object java.lang.String#157\n   Instance Field name authority type object value 0\n   Instance Field name query type object value 0\n   Instance Field name file type object value 1684184040\n    Ref object java.lang.String#157\n   Instance Field name port type int value -1\n   Instance Field name host type object value 0\n   Instance Field name protocol type object value 0\n   References count 1\n   Field base of instance 0x64629b88\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath$JarLoader#2\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629cb8 number 8 retained size 192\n   Instance Field name hashCode type int value -1\n   Instance Field name handler type object value 1684178104\n    Ref object sun.net.www.protocol.jar.Handler#1\n   Instance Field name hostAddress type object value 0\n   Instance Field name ref type object value 0\n   Instance Field name userInfo type object value 0\n   Instance Field name path type object value 1684184304\n    Ref object java.lang.String#158\n   Instance Field name authority type object value 0\n   Instance Field name query type object value 0\n   Instance Field name file type object value 1684184304\n    Ref object java.lang.String#158\n   Instance Field name port type int value -1\n   Instance Field name host type object value 0\n   Instance Field name protocol type object value 0\n   References count 1\n   Field base of instance 0x64629c90\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath$JarLoader#3\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629db8 number 9 retained size 200\n   Instance Field name hashCode type int value -1\n   Instance Field name handler type object value 1684178104\n    Ref object sun.net.www.protocol.jar.Handler#1\n   Instance Field name hostAddress type object value 0\n   Instance Field name ref type object value 0\n   Instance Field name userInfo type object value 0\n   Instance Field name path type object value 1684184560\n    Ref object java.lang.String#159\n   Instance Field name authority type object value 0\n   Instance Field name query type object value 0\n   Instance Field name file type object value 1684184560\n    Ref object java.lang.String#159\n   Instance Field name port type int value -1\n   Instance Field name host type object value 0\n   Instance Field name protocol type object value 0\n   References count 1\n   Field base of instance 0x64629d90\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath$JarLoader#4\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629ec0 number 10 retained size 144\n   Instance Field name hashCode type int value -1\n   Instance Field name handler type object value 1684179560\n    Ref object sun.net.www.protocol.jar.Handler#2\n   Instance Field name hostAddress type object value 0\n   Instance Field name ref type object value 0\n   Instance Field name userInfo type object value 0\n   Instance Field name path type object value 1684184824\n    Ref object java.lang.String#160\n   Instance Field name authority type object value 0\n   Instance Field name query type object value 0\n   Instance Field name file type object value 1684184824\n    Ref object java.lang.String#160\n   Instance Field name port type int value -1\n   Instance Field name host type object value 0\n   Instance Field name protocol type object value 0\n   References count 1\n   Field base of instance 0x64629e98\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath$JarLoader#5\n    Next object java.lang.Object[]#311\n    Next object java.util.ArrayList#5\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6813a280 Class java.net.URL[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6ca07220 Class java.security.cert.Certificate SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value -3585440601605666277\n  Static Field name <classLoader> type object value 0\n  Field name type type object\n Id 0x6813b150 Class java.security.cert.Certificate[] SuperClass java.lang.Object Instance size -1 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64630cb8 number 1 retained size 16\n   References count 2\n   Field nocerts of instance 0x64628620\n   Field value of instance 0x64630cc8\n   Path to nearest GC root\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c9f6c28 Class java.security.CodeSource SuperClass java.lang.Object Instance size 32 Instance count 1 All Instances Size 32\n  Static Field name serialVersionUID type long value 4977541819976013951\n  Static Field name <classLoader> type object value 0\n  Field name factory type object\n  Field name sp type object\n  Field name certs type object\n  Field name signers type object\n  Field name location type object\n  Instance Id 0x646307b0 number 1 retained size 32\n   Instance Field name factory type object value 0\n   Instance Field name sp type object value 0\n   Instance Field name certs type object value 0\n   Instance Field name signers type object value 0\n   Instance Field name location type object value 1684178408\n    Ref object java.net.URL#5\n   References count 2\n   Field key of instance 0x64630c88\n   Field codesource of instance 0x64630c58\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c996370 Class java.nio.ByteBuffer SuperClass java.nio.Buffer Instance size 48 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name nativeByteOrder type boolean\n  Field name bigEndian type boolean\n  Field name isReadOnly type boolean\n  Field name offset type int\n  Field name hb type object\n Id 0x6cc35270 Class java.util.zip.ZipFile$ZipFileInputStream SuperClass java.io.InputStream Instance size 48 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name this$0 type object\n  Field name size type long\n  Field name rem type long\n  Field name pos type long\n  Field name jzentry type long\n Id 0x6c980678 Class java.util.Enumeration SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c97e340 Class java.util.Stack SuperClass java.util.Vector Instance size 24 Instance count 3 All Instances Size 72\n  Static Field name serialVersionUID type long value 1224463164541339165\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x646108f0 number 1 retained size 80\n   Instance Field name capacityIncrement type int value 0\n   Instance Field name elementCount type int value 0\n   Instance Field name elementData type object value 1684080904\n    Ref object java.lang.Object[]#11\n   Instance Field name modCount type int value 2\n   References count 1\n   Field nativeLibraryContext of Class java.lang.ClassLoader\n   Path to nearest GC root\n    Next object java.lang.Class#101\n  Instance Id 0x646282b8 number 2 retained size 80\n   Instance Field name capacityIncrement type int value 0\n   Instance Field name elementCount type int value 0\n   Instance Field name elementData type object value 1684177616\n    Ref object java.lang.Object[]#305\n   Instance Field name modCount type int value 8\n   References count 1\n   Field urls of instance 0x64628248\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628950 number 3 retained size 80\n   Instance Field name capacityIncrement type int value 0\n   Instance Field name elementCount type int value 0\n   Instance Field name elementData type object value 1684179304\n    Ref object java.lang.Object[]#310\n   Instance Field name modCount type int value 2\n   References count 1\n   Field urls of instance 0x646288e0\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c9e48f0 Class java.util.concurrent.locks.Lock SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x68139850 Class java.util.concurrent.locks.Lock[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9e55f8 Class java.util.concurrent.locks.ReentrantLock SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value 7373984872572414699\n  Static Field name <classLoader> type object value 0\n  Field name sync type object\n Id 0x68139a48 Class java.util.concurrent.locks.ReentrantLock[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9ccc90 Class sun.misc.Launcher SuperClass java.lang.Object Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name fileHandler type object value 0\n  Static Field name launcher type object value 1684166880\n   Ref object sun.misc.Launcher#1\n  Static Field name factory type object value 1684166872\n   Ref object sun.misc.Launcher$Factory#1\n  Static Field name <classLoader> type object value 0\n  Field name loader type object\n  Instance Id 0x646258e0 number 1 retained size 16\n   Instance Field name loader type object value 1684178464\n    Ref object sun.misc.Launcher$AppClassLoader#1\n   References count 1\n   Field launcher of Class sun.misc.Launcher\n   Path to nearest GC root\n    Next object java.lang.Class#286\n Id 0x6c9f5588 Class sun.misc.Resource SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name cis type object\n Id 0x6c9efaa8 Class sun.misc.URLClassPath SuperClass java.lang.Object Instance size 32 Instance count 2 All Instances Size 64\n  Static Field name DEBUG type boolean value false\n  Static Field name JAVA_VERSION type object value 0\n  Static Field name USER_AGENT_JAVA_VERSION type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name jarHandler type object\n  Field name lmap type object\n  Field name loaders type object\n  Field name urls type object\n  Field name path type object\n  Instance Id 0x64628248 number 1 retained size 2192\n   Instance Field name jarHandler type object value 1684178104\n    Ref object sun.net.www.protocol.jar.Handler#1\n   Instance Field name lmap type object value 1684177752\n    Ref object java.util.HashMap#7\n   Instance Field name loaders type object value 1684177672\n    Ref object java.util.ArrayList#3\n   Instance Field name urls type object value 1684177592\n    Ref object java.util.Stack#2\n   Instance Field name path type object value 1684177512\n    Ref object java.util.ArrayList#2\n   References count 1\n   Field ucp of instance 0x64626138\n   Path to nearest GC root\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646288e0 number 2 retained size 608\n   Instance Field name jarHandler type object value 1684179560\n    Ref object sun.net.www.protocol.jar.Handler#2\n   Instance Field name lmap type object value 1684179440\n    Ref object java.util.HashMap#11\n   Instance Field name loaders type object value 1684179360\n    Ref object java.util.ArrayList#5\n   Instance Field name urls type object value 1684179280\n    Ref object java.util.Stack#3\n   Instance Field name path type object value 1684179200\n    Ref object java.util.ArrayList#4\n   References count 1\n   Field ucp of instance 0x64628620\n   Path to nearest GC root\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c9e8538 Class java.util.concurrent.locks.AbstractQueuedSynchronizer SuperClass java.util.concurrent.locks.AbstractOwnableSynchronizer Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name waitStatusOffset type long value 24\n  Static Field name tailOffset type long value 16\n  Static Field name headOffset type long value 12\n  Static Field name stateOffset type long value 20\n  Static Field name unsafe type object value 1684098296\n   Ref object sun.misc.Unsafe#1\n  Static Field name spinForTimeoutThreshold type long value 1000\n  Static Field name serialVersionUID type long value 7373984972572414691\n  Static Field name <classLoader> type object value 0\n  Field name state type int\n  Field name tail type object\n  Field name head type object\n Id 0x6c98fc00 Class sun.misc.VM SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name threadStateNames type object value 0\n  Static Field name threadStateMap type object value 0\n  Static Field name peakFinalRefCount type int value 2\n  Static Field name finalRefCount type int value 0\n  Static Field name allowArraySyntax type boolean value false\n  Static Field name defaultAllowArraySyntax type boolean value false\n  Static Field name directMemory type long value 66650112\n  Static Field name booted type boolean value true\n  Static Field name STATE_RED type int value 3\n  Static Field name STATE_YELLOW type int value 2\n  Static Field name STATE_GREEN type int value 1\n  Static Field name suspended type boolean value false\n  Static Field name <classLoader> type object value 0\n Id 0x6c9e96e0 Class java.util.concurrent.locks.ReentrantLock$NonfairSync SuperClass java.util.concurrent.locks.ReentrantLock$Sync Instance size 24 Instance count 32 All Instances Size 768\n  Static Field name serialVersionUID type long value 7316153563782823691\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64626bc8 number 1 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626558\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#1\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626c18 number 2 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626bf8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#2\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626c68 number 3 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626c48\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#3\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626cb8 number 4 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626c98\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#4\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626cf0 number 5 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626cd0\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#5\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626d40 number 6 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626d20\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#6\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626d90 number 7 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626d70\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#7\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626dc8 number 8 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626da8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#8\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626e18 number 9 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626df8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#9\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626e68 number 10 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626e48\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#10\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626eb8 number 11 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626e98\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#11\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626f08 number 12 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626ee8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#12\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626f58 number 13 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626f38\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#13\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626fa8 number 14 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626f88\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#14\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64626ff8 number 15 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64626fd8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#15\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x64627048 number 16 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x64627028\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#16\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#1\n    Next object java.util.concurrent.ConcurrentHashMap#1\n    Next object java.lang.Class#221\n  Instance Id 0x6462cef8 number 17 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462ced8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#17\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cf40 number 18 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462cf20\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#18\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cf88 number 19 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462cf68\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#19\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cfd0 number 20 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462cfb0\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#20\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d018 number 21 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462cff8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#21\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d060 number 22 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462d040\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#22\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d0a8 number 23 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462d088\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#23\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d0f0 number 24 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462d0d0\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#24\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d138 number 25 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462d118\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#25\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d180 number 26 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462d160\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#26\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d1c8 number 27 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462d1a8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#27\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d210 number 28 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462d1f0\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#28\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d258 number 29 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462d238\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#29\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d2a0 number 30 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462d280\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#30\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d2e8 number 31 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462d2c8\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#31\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d330 number 32 retained size 24\n   Instance Field name state type int value 0\n   Instance Field name tail type object value 0\n   Instance Field name head type object value 0\n   Instance Field name exclusiveOwnerThread type object value 0\n   References count 1\n   Field sync of instance 0x6462d310\n   Path to nearest GC root\n    Next object java.util.concurrent.ConcurrentHashMap$Segment#32\n    Next object java.util.concurrent.ConcurrentHashMap$Segment[]#2\n    Next object java.util.concurrent.ConcurrentHashMap#2\n    Next object java.lang.Class#341\n Id 0x6c9e91d8 Class java.util.concurrent.locks.ReentrantLock$Sync SuperClass java.util.concurrent.locks.AbstractQueuedSynchronizer Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value -5179523762034025860\n  Static Field name <classLoader> type object value 0\n Id 0x6cc3a380 Class java.util.jar.JarVerifier SuperClass java.lang.Object Instance size 48 Instance count 1 All Instances Size 48\n  Static Field name debug type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name manifestRawBytes type object\n  Field name manDig type object\n  Field name baos type object\n  Field name anyToVerify type boolean\n  Field name parsingMeta type boolean\n  Field name parsingBlockOrSF type boolean\n  Field name signerCache type object\n  Field name pendingBlocks type object\n  Field name sigFileData type object\n  Field name sigFileSigners type object\n  Field name verifiedSigners type object\n  Instance Id 0x646297a0 number 1 retained size 0\n   Instance Field name manifestRawBytes type object value 1684181176\n    Ref object byte[]#9\n   Instance Field name manDig type object value 0\n   Instance Field name baos type object value 1684183360\n    Ref object java.io.ByteArrayOutputStream#1\n   Instance Field name anyToVerify type boolean value true\n   Instance Field name parsingMeta type boolean value true\n   Instance Field name parsingBlockOrSF type boolean value false\n   Instance Field name signerCache type object value 0\n   Instance Field name pendingBlocks type object value 1684183280\n    Ref object java.util.ArrayList#6\n   Instance Field name sigFileData type object value 1684183184\n    Ref object java.util.Hashtable#8\n   Instance Field name sigFileSigners type object value 1684182992\n    Ref object java.util.Hashtable#6\n   Instance Field name verifiedSigners type object value 1684183088\n    Ref object java.util.Hashtable#7\n   References count 1\n   Field jv of instance 0x64628fc8\n   Path to nearest GC root\n    Null\n Id 0x6cc34b70 Class java.util.jar.JarFile$JarFileEntry SuperClass java.util.jar.JarEntry Instance size 72 Instance count 2 All Instances Size 144\n  Static Field name <classLoader> type object value 0\n  Field name this$0 type object\n  Instance Id 0x64629068 number 1 retained size 0\n   Instance Field name this$0 type object value 1684180936\n    Ref object java.util.jar.JarFile#1\n   Instance Field name signers type object value 0\n   Instance Field name certs type object value 0\n   Instance Field name attr type object value 0\n   Instance Field name comment type object value 0\n   Instance Field name extra type object value 0\n   Instance Field name method type int value 0\n   Instance Field name csize type long value 206\n   Instance Field name size type long value 206\n   Instance Field name crc type long value 1076925003\n   Instance Field name time type long value 886074516\n   Instance Field name name type object value 0\n   References count 1\n   Field manEntry of instance 0x64628fc8\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a2f0 number 2 retained size 72\n   Instance Field name this$0 type object value 1684184984\n    Ref object java.util.jar.JarFile#2\n   Instance Field name signers type object value 0\n   Instance Field name certs type object value 0\n   Instance Field name attr type object value 0\n   Instance Field name comment type object value 0\n   Instance Field name extra type object value 0\n   Instance Field name method type int value 0\n   Instance Field name csize type long value 206\n   Instance Field name size type long value 206\n   Instance Field name crc type long value 1076925003\n   Instance Field name time type long value 886074516\n   Instance Field name name type object value 0\n   References count 1\n   Field manEntry of instance 0x64629f98\n   Path to nearest GC root\n    Next object java.util.jar.JarFile#2\n    Next object sun.misc.URLClassPath$JarLoader#5\n    Next object java.lang.Object[]#311\n    Next object java.util.ArrayList#5\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6cc32e18 Class java.util.jar.JavaUtilJarAccessImpl SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64628cd0 number 1 retained size 8\n   References count 1\n   Field javaUtilJarAccess of Class sun.misc.SharedSecrets\n   Path to nearest GC root\n    Next object java.lang.Class#312\n Id 0x6cc400b8 Class sun.security.util.ManifestEntryVerifier SuperClass java.lang.Object Instance size 48 Instance count 0 All Instances Size 0\n  Static Field name hexc type object value 1684211016\n   Ref object char[]#263\n  Static Field name sunProvider type object value 1684198232\n   Ref object sun.security.provider.Sun#1\n  Static Field name debug type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name signers type object\n  Field name entry type object\n  Field name skip type boolean\n  Field name man type object\n  Field name name type object\n  Field name decoder type object\n  Field name manifestHashes type object\n  Field name digests type object\n  Field name createdDigests type object\n Id 0x6cc384e0 Class java.util.jar.Manifest$FastInputStream SuperClass java.io.FilterInputStream Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name pos type int\n  Field name count type int\n  Field name buf type object\n Id 0x6c9e9c90 Class java.util.concurrent.locks.AbstractQueuedSynchronizer$Node SuperClass java.lang.Object Instance size 32 Instance count 0 All Instances Size 0\n  Static Field name EXCLUSIVE type object value 0\n  Static Field name SHARED type object value 0\n  Static Field name CONDITION type int value -2\n  Static Field name SIGNAL type int value -1\n  Static Field name CANCELLED type int value 1\n  Static Field name <classLoader> type object value 0\n  Field name nextWaiter type object\n  Field name thread type object\n  Field name next type object\n  Field name prev type object\n  Field name waitStatus type int\n Id 0x6cc39688 Class sun.misc.ASCIICaseInsensitiveComparator SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name CASE_INSENSITIVE_ORDER type object value 1684182288\n   Ref object sun.misc.ASCIICaseInsensitiveComparator#1\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64629510 number 1 retained size 8\n   References count 1\n   Field CASE_INSENSITIVE_ORDER of Class sun.misc.ASCIICaseInsensitiveComparator\n   Path to nearest GC root\n    Next object java.lang.Class#299\n Id 0x6c9af3c8 Class java.io.BufferedInputStream SuperClass java.io.FilterInputStream Instance size 32 Instance count 1 All Instances Size 32\n  Static Field name bufUpdater type object value 1684104568\n   Ref object java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl#1\n  Static Field name defaultBufferSize type int value 8192\n  Static Field name <classLoader> type object value 0\n  Field name marklimit type int\n  Field name markpos type int\n  Field name pos type int\n  Field name count type int\n  Field name buf type object\n  Instance Id 0x646168b0 number 1 retained size 8240\n   Instance Field name marklimit type int value 0\n   Instance Field name markpos type int value -1\n   Instance Field name pos type int value 0\n   Instance Field name count type int value 0\n   Instance Field name buf type object value 1684106944\n    Ref object byte[]#5\n   Instance Field name in type object value 1684104360\n    Ref object java.io.FileInputStream#1\n   References count 1\n   Field in of Class java.lang.System\n   Path to nearest GC root\n    Next object java.lang.Class#85\n Id 0x6cc4be58 Class sun.security.util.SignatureFileVerifier SuperClass java.lang.Object Instance size 40 Instance count 0 All Instances Size 0\n  Static Field name hexc type object value 1684211584\n   Ref object char[]#266\n  Static Field name ATTR_DIGEST type object value 1684211560\n   Ref object java.lang.String#256\n  Static Field name debug type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name certificateFactory type object\n  Field name workaround type boolean\n  Field name createdDigests type object\n  Field name md type object\n  Field name name type object\n  Field name sfBytes type object\n  Field name block type object\n  Field name signerCache type object\n Id 0x6c9b5060 Class java.io.BufferedOutputStream SuperClass java.io.FilterOutputStream Instance size 24 Instance count 2 All Instances Size 48\n  Static Field name <classLoader> type object value 0\n  Field name count type int\n  Field name buf type object\n  Instance Id 0x646168f0 number 1 retained size 168\n   Instance Field name count type int value 0\n   Instance Field name buf type object value 1684105480\n    Ref object byte[]#1\n   Instance Field name out type object value 1684104456\n    Ref object java.io.FileOutputStream#1\n   References count 1\n   Field out of instance 0x646168d0\n   Path to nearest GC root\n    Next object java.io.PrintStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616ae8 number 2 retained size 168\n   Instance Field name count type int value 0\n   Instance Field name buf type object value 1684105984\n    Ref object byte[]#3\n   Instance Field name out type object value 1684104512\n    Ref object java.io.FileOutputStream#2\n   References count 1\n   Field out of instance 0x64616ac8\n   Path to nearest GC root\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n Id 0x6c9ae0e8 Class java.io.FileOutputStream SuperClass java.io.OutputStream Instance size 24 Instance count 2 All Instances Size 48\n  Static Field name <classLoader> type object value 0\n  Field name append type boolean\n  Field name channel type object\n  Field name fd type object\n  Instance Id 0x64616508 number 1 retained size 24\n   Instance Field name append type boolean value false\n   Instance Field name channel type object value 0\n   Instance Field name fd type object value 1684104392\n    Ref object java.io.FileDescriptor#2\n   References count 2\n   Field out of instance 0x646168f0\n   Field referent of instance 0x64616520\n   Path to nearest GC root\n    Next object java.io.BufferedOutputStream#1\n    Next object java.io.PrintStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616540 number 2 retained size 24\n   Instance Field name append type boolean value false\n   Instance Field name channel type object value 0\n   Instance Field name fd type object value 1684104408\n    Ref object java.io.FileDescriptor#3\n   References count 2\n   Field out of instance 0x64616ae8\n   Field referent of instance 0x64616558\n   Path to nearest GC root\n    Next object java.io.BufferedOutputStream#2\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n Id 0x6c9acdb0 Class java.io.FileDescriptor SuperClass java.lang.Object Instance size 16 Instance count 5 All Instances Size 80\n  Static Field name err type object value 1684104408\n   Ref object java.io.FileDescriptor#3\n  Static Field name out type object value 1684104392\n   Ref object java.io.FileDescriptor#2\n  Static Field name in type object value 1684104376\n   Ref object java.io.FileDescriptor#1\n  Static Field name <classLoader> type object value 0\n  Field name fd type int\n  Instance Id 0x646164b8 number 1 retained size 16\n   Instance Field name fd type int value 0\n   References count 2\n   Field in of Class java.io.FileDescriptor\n   Field fd of instance 0x646164a8\n   Path to nearest GC root\n    Next object java.lang.Class#304\n  Instance Id 0x646164c8 number 2 retained size 16\n   Instance Field name fd type int value 1\n   References count 2\n   Field out of Class java.io.FileDescriptor\n   Field fd of instance 0x64616508\n   Path to nearest GC root\n    Next object java.lang.Class#304\n  Instance Id 0x646164d8 number 3 retained size 16\n   Instance Field name fd type int value 2\n   References count 2\n   Field err of Class java.io.FileDescriptor\n   Field fd of instance 0x64616540\n   Path to nearest GC root\n    Next object java.lang.Class#304\n  Instance Id 0x6462f048 number 4 retained size 16\n   Instance Field name fd type int value 8\n   References count 1\n   Field fd of instance 0x6462f018\n   Path to nearest GC root\n    Next object java.io.FileInputStream#2\n    Next object sun.security.provider.NativePRNG$RandomIO#1\n    Next object java.lang.Class#339\n  Instance Id 0x6462f088 number 5 retained size 16\n   Instance Field name fd type int value 9\n   References count 1\n   Field fd of instance 0x6462f058\n   Path to nearest GC root\n    Next object java.io.FileInputStream#3\n    Next object sun.security.provider.NativePRNG$RandomIO#1\n    Next object java.lang.Class#339\n Id 0x68138c28 Class java.lang.ApplicationShutdownHooks SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name hooks type object value 1684166432\n   Ref object java.util.IdentityHashMap#1\n  Static Field name instance type object value 1684166744\n   Ref object java.lang.ApplicationShutdownHooks#1\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64625858 number 1 retained size 8\n   References count 2\n   Field instance of Class java.lang.ApplicationShutdownHooks\n   Element 1 of array 0x646256d0\n   Path to nearest GC root\n    Next object java.lang.Class#305\n Id 0x6c9b4700 Class java.io.PrintStream SuperClass java.io.FilterOutputStream Instance size 32 Instance count 2 All Instances Size 64\n  Static Field name <classLoader> type object value 0\n  Field name closing type boolean\n  Field name charOut type object\n  Field name textOut type object\n  Field name formatter type object\n  Field name trouble type boolean\n  Field name autoFlush type boolean\n  Instance Id 0x646168d0 number 1 retained size 25080\n   Instance Field name closing type boolean value false\n   Instance Field name charOut type object value 1684105624\n    Ref object java.io.OutputStreamWriter#1\n   Instance Field name textOut type object value 1684105888\n    Ref object java.io.BufferedWriter#1\n   Instance Field name formatter type object value 0\n   Instance Field name trouble type boolean value false\n   Instance Field name autoFlush type boolean value true\n   Instance Field name out type object value 1684105456\n    Ref object java.io.BufferedOutputStream#1\n   References count 3\n   Field out of Class java.lang.System\n   Field out of instance 0x646169b0\n   Field lock of instance 0x64616998\n   Path to nearest GC root\n    Next object java.lang.Class#85\n  Instance Id 0x64616ac8 number 2 retained size 25080\n   Instance Field name closing type boolean value false\n   Instance Field name charOut type object value 1684106128\n    Ref object java.io.OutputStreamWriter#2\n   Instance Field name textOut type object value 1684106360\n    Ref object java.io.BufferedWriter#2\n   Instance Field name formatter type object value 0\n   Instance Field name trouble type boolean value false\n   Instance Field name autoFlush type boolean value true\n   Instance Field name out type object value 1684105960\n    Ref object java.io.BufferedOutputStream#2\n   References count 3\n   Field err of Class java.lang.System\n   Field out of instance 0x64616ba8\n   Field lock of instance 0x64616b90\n   Path to nearest GC root\n    Next object java.lang.Class#85\n Id 0x6c9cade8 Class java.lang.System$2 SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64625880 number 1 retained size 8\n   References count 1\n   Field javaLangAccess of Class sun.misc.SharedSecrets\n   Path to nearest GC root\n    Next object java.lang.Class#312\n Id 0x6c9bc878 Class java.lang.Runtime SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name currentRuntime type object value 1684106400\n   Ref object java.lang.Runtime#1\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64616ca0 number 1 retained size 8\n   References count 1\n   Field currentRuntime of Class java.lang.Runtime\n   Path to nearest GC root\n    Next object java.lang.Class#308\n Id 0x6c977388 Class java.lang.RuntimePermission SuperClass java.security.BasicPermission Instance size 24 Instance count 3 All Instances Size 72\n  Static Field name serialVersionUID type long value 7399184964622342223\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610660 number 1 retained size 24\n   Instance Field name exitVM type boolean value false\n   Instance Field name path type object value 0\n   Instance Field name wildcard type boolean value false\n   Instance Field name name type object value 0\n   References count 1\n   Field SUBCLASS_IMPLEMENTATION_PERMISSION of Class java.lang.Thread\n   Path to nearest GC root\n    Next object java.lang.Class#92\n  Instance Id 0x64610940 number 2 retained size 24\n   Instance Field name exitVM type boolean value false\n   Instance Field name path type object value 0\n   Instance Field name wildcard type boolean value false\n   Instance Field name name type object value 0\n   References count 1\n   Field reflectionFactoryAccessPerm of Class sun.reflect.ReflectionFactory\n   Path to nearest GC root\n    Next object java.lang.Class#258\n  Instance Id 0x64630b08 number 3 retained size 24\n   Instance Field name exitVM type boolean value true\n   Instance Field name path type object value 0\n   Instance Field name wildcard type boolean value true\n   Instance Field name name type object value 0\n   References count 1\n   Field value of instance 0x64630c40\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#155\n    Next object java.util.HashMap$Entry[]#26\n    Next object java.util.HashMap#23\n    Next object java.security.BasicPermissionCollection#1\n    Next object java.util.HashMap$Entry#154\n    Next object java.util.HashMap$Entry[]#24\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c9c8ac8 Class java.lang.Terminator SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name handler type object value 1684165304\n   Ref object java.lang.Terminator$1#1\n  Static Field name <classLoader> type object value 0\n Id 0x681378c0 Class sun.misc.JavaIOAccess SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9cb608 Class sun.misc.SharedSecrets SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name javaNetAccess type object value 1684166944\n   Ref object java.net.URLClassLoader$7#1\n  Static Field name javaIODeleteOnExitAccess type object value 1684106936\n   Ref object java.io.File$1#1\n  Static Field name javaIOAccess type object value 1684166304\n   Ref object java.io.Console$1#1\n  Static Field name javaLangAccess type object value 1684166784\n   Ref object java.lang.System$2#1\n  Static Field name javaUtilJarAccess type object value 1684180176\n   Ref object java.util.jar.JavaUtilJarAccessImpl#1\n  Static Field name unsafe type object value 1684098296\n   Ref object sun.misc.Unsafe#1\n  Static Field name <classLoader> type object value 0\n Id 0x6c9ab068 Class sun.misc.Version SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name jvmVersionInfoAvailable type boolean value false\n  Static Field name jdk_special_version type object value 0\n  Static Field name jdk_build_number type int value 0\n  Static Field name jdk_update_version type int value 0\n  Static Field name jdk_micro_version type int value 0\n  Static Field name jdk_minor_version type int value 0\n  Static Field name jdk_major_version type int value 0\n  Static Field name jvm_special_version type object value 0\n  Static Field name jvm_build_number type int value 0\n  Static Field name jvm_update_version type int value 0\n  Static Field name jvm_micro_version type int value 0\n  Static Field name jvm_minor_version type int value 0\n  Static Field name jvm_major_version type int value 0\n  Static Field name versionsInitialized type boolean value false\n  Static Field name java_runtime_version type object value 0\n  Static Field name java_runtime_name type object value 0\n  Static Field name java_version type object value 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9ec910 Class sun.net.www.protocol.file.Handler SuperClass java.net.URLStreamHandler Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x646279f0 number 1 retained size 8\n   References count 6\n   Field value of instance 0x646279f8\n   Field handler of instance 0x64627f90\n   Field handler of instance 0x646285e8\n   Field handler of instance 0x646264a8\n   Field handler of instance 0x64627da0\n   Field handler of instance 0x64627bc8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#56\n    Next object java.util.Hashtable$Entry[]#4\n    Next object java.util.Hashtable#3\n    Next object java.lang.Class#273\n Id 0x6c9fc488 Class sun.net.www.protocol.file.FileURLConnection SuperClass sun.net.www.URLConnection Instance size 96 Instance count 0 All Instances Size 0\n  Static Field name LAST_MODIFIED type object value 0\n  Static Field name TEXT_PLAIN type object value 0\n  Static Field name CONTENT_TYPE type object value 0\n  Static Field name CONTENT_LENGTH type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name permission type object\n  Field name initializedHeaders type boolean\n  Field name lastModified type long\n  Field name length type long\n  Field name files type object\n  Field name exists type boolean\n  Field name isDirectory type boolean\n  Field name filename type object\n  Field name file type object\n  Field name is type object\n  Field name contentType type object\n Id 0x6c9f22c8 Class sun.misc.URLClassPath$3 SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name this$0 type object\n  Field name val$url type object\n Id 0x6c9f3cc8 Class sun.misc.URLClassPath$JarLoader SuperClass sun.misc.URLClassPath$Loader Instance size 40 Instance count 5 All Instances Size 200\n  Static Field name <classLoader> type object value 0\n  Field name lmap type object\n  Field name handler type object\n  Field name metaIndex type object\n  Field name index type object\n  Field name csu type object\n  Field name jar type object\n  Instance Id 0x64629a00 number 1 retained size 248\n   Instance Field name lmap type object value 1684177752\n    Ref object java.util.HashMap#7\n   Instance Field name handler type object value 1684178104\n    Ref object sun.net.www.protocol.jar.Handler#1\n   Instance Field name metaIndex type object value 1684168520\n    Ref object sun.misc.MetaIndex#3\n   Instance Field name index type object value 0\n   Instance Field name csu type object value 1684169896\n    Ref object java.net.URL#1\n   Instance Field name jar type object value 0\n   Instance Field name base type object value 1684183592\n    Ref object java.net.URL#6\n   References count 2\n   Element 0 of array 0x64628320\n   Field value of instance 0x64629b70\n   Path to nearest GC root\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629b88 number 2 retained size 240\n   Instance Field name lmap type object value 1684177752\n    Ref object java.util.HashMap#7\n   Instance Field name handler type object value 1684178104\n    Ref object sun.net.www.protocol.jar.Handler#1\n   Instance Field name metaIndex type object value 1684168952\n    Ref object sun.misc.MetaIndex#4\n   Instance Field name index type object value 0\n   Instance Field name csu type object value 1684175816\n    Ref object java.net.URL#2\n   Instance Field name jar type object value 0\n   Instance Field name base type object value 1684183984\n    Ref object java.net.URL#7\n   References count 2\n   Element 1 of array 0x64628320\n   Field value of instance 0x64629c78\n   Path to nearest GC root\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629c90 number 3 retained size 232\n   Instance Field name lmap type object value 1684177752\n    Ref object java.util.HashMap#7\n   Instance Field name handler type object value 1684178104\n    Ref object sun.net.www.protocol.jar.Handler#1\n   Instance Field name metaIndex type object value 1684167752\n    Ref object sun.misc.MetaIndex#1\n   Instance Field name index type object value 0\n   Instance Field name csu type object value 1684176288\n    Ref object java.net.URL#3\n   Instance Field name jar type object value 0\n   Instance Field name base type object value 1684184248\n    Ref object java.net.URL#8\n   References count 2\n   Element 2 of array 0x64628320\n   Field value of instance 0x64629d78\n   Path to nearest GC root\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629d90 number 4 retained size 240\n   Instance Field name lmap type object value 1684177752\n    Ref object java.util.HashMap#7\n   Instance Field name handler type object value 1684178104\n    Ref object sun.net.www.protocol.jar.Handler#1\n   Instance Field name metaIndex type object value 1684168072\n    Ref object sun.misc.MetaIndex#2\n   Instance Field name index type object value 0\n   Instance Field name csu type object value 1684176784\n    Ref object java.net.URL#4\n   Instance Field name jar type object value 0\n   Instance Field name base type object value 1684184504\n    Ref object java.net.URL#9\n   References count 2\n   Element 3 of array 0x64628320\n   Field value of instance 0x64629e80\n   Path to nearest GC root\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629e98 number 5 retained size 184\n   Instance Field name lmap type object value 1684179440\n    Ref object java.util.HashMap#11\n   Instance Field name handler type object value 1684179560\n    Ref object sun.net.www.protocol.jar.Handler#2\n   Instance Field name metaIndex type object value 0\n   Instance Field name index type object value 0\n   Instance Field name csu type object value 1684178408\n    Ref object java.net.URL#5\n   Instance Field name jar type object value 1684184984\n    Ref object java.util.jar.JarFile#2\n   Instance Field name base type object value 1684184768\n    Ref object java.net.URL#10\n   References count 2\n   Element 0 of array 0x646289b8\n   Field value of instance 0x6462a7a8\n   Path to nearest GC root\n    Next object java.lang.Object[]#311\n    Next object java.util.ArrayList#5\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c9f29f0 Class sun.misc.URLClassPath$Loader SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name base type object\n Id 0x6c9f05c8 Class sun.net.www.protocol.jar.Handler SuperClass java.net.URLStreamHandler Instance size 8 Instance count 2 All Instances Size 16\n  Static Field name separator type object value 0\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x646284b8 number 1 retained size 8\n   References count 9\n   Field jarHandler of instance 0x64628248\n   Field handler of instance 0x64629d90\n   Field handler of instance 0x64629db8\n   Field handler of instance 0x64629b88\n   Field handler of instance 0x64629bb0\n   Field handler of instance 0x64629c90\n   Field handler of instance 0x64629cb8\n   Field handler of instance 0x64629a00\n   Field handler of instance 0x64629a28\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628a68 number 2 retained size 8\n   References count 3\n   Field jarHandler of instance 0x646288e0\n   Field handler of instance 0x64629e98\n   Field handler of instance 0x64629ec0\n   Path to nearest GC root\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c9f7650 Class java.security.PermissionCollection SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value -6727011328946861783\n  Static Field name <classLoader> type object value 0\n  Field name readOnly type boolean\n Id 0x6cc4ab68 Class sun.misc.BASE64Decoder SuperClass sun.misc.CharacterDecoder Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name pem_convert_array type object value 1684211208\n   Ref object byte[]#12\n  Static Field name pem_array type object value 1684211064\n   Ref object char[]#264\n  Static Field name <classLoader> type object value 0\n  Field name decode_buffer type object\n Id 0x6c976680 Class java.security.Permission SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value -5636570222231596674\n  Static Field name <classLoader> type object value 0\n  Field name name type object\n Id 0x6ca06a98 Class java.security.Principal SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6813af98 Class java.security.Principal[] SuperClass java.lang.Object Instance size -1 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64630c78 number 1 retained size 16\n   References count 1\n   Field principals of instance 0x64630c58\n   Path to nearest GC root\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6ca001f8 Class java.security.Policy SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name debug type object value 0\n  Static Field name policy type object value 0\n  Static Field name UNSUPPORTED_EMPTY_COLLECTION type object value 1684212104\n   Ref object java.security.Policy$UnsupportedEmptyCollection#1\n  Static Field name <classLoader> type object value 0\n  Field name pdMapping type object\n Id 0x6cc43008 Class sun.security.provider.Sun SuperClass java.security.Provider Instance size 88 Instance count 1 All Instances Size 88\n  Static Field name seedSource type object value 1684194184\n   Ref object java.lang.String#226\n  Static Field name URL_DEV_URANDOM type object value 0\n  Static Field name URL_DEV_RANDOM type object value 0\n  Static Field name PROP_RNDSOURCE type object value 0\n  Static Field name PROP_EGD type object value 0\n  Static Field name INFO type object value 0\n  Static Field name serialVersionUID type long value 6440182097568097204\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462d358 number 1 retained size 5480\n   Instance Field name serviceSet type object value 0\n   Instance Field name legacyMap type object value 0\n   Instance Field name serviceMap type object value 0\n   Instance Field name legacyStrings type object value 1684205768\n    Ref object java.util.LinkedHashMap#1\n   Instance Field name servicesChanged type boolean value false\n   Instance Field name legacyChanged type boolean value true\n   Instance Field name entrySetCallCount type int value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name version type double value 1.6\n   Instance Field name info type object value 0\n   Instance Field name name type object value 0\n   Instance Field name defaults type object value 0\n   Instance Field name values type object value 0\n   Instance Field name entrySet type object value 0\n   Instance Field name keySet type object value 0\n   Instance Field name modCount type int value 77\n   Instance Field name loadFactor type float value 0.75\n   Instance Field name threshold type int value 143\n   Instance Field name count type int value 73\n   Instance Field name table type object value 1684210160\n    Ref object java.util.Hashtable$Entry[]#11\n   References count 1\n   Field sunProvider of Class sun.security.util.ManifestEntryVerifier\n   Path to nearest GC root\n    Next object java.lang.Class#296\n Id 0x6c9f14e8 Class sun.misc.Launcher$AppClassLoader$1 SuperClass java.lang.Object Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name val$extcl type object\n  Field name val$path type object\n  Field name val$s type object\n Id 0x6cc41f78 Class java.security.Provider SuperClass java.util.Properties Instance size 88 Instance count 0 All Instances Size 0\n  Static Field name knownEngines type object value 1684187616\n   Ref object java.util.HashMap#19\n  Static Field name previousKey type object value 1684187592\n   Ref object java.security.Provider$ServiceKey#1\n  Static Field name ALIAS_LENGTH type int value 10\n  Static Field name ALIAS_PREFIX_LOWER type object value 0\n  Static Field name ALIAS_PREFIX type object value 0\n  Static Field name debug type object value 0\n  Static Field name serialVersionUID type long value -4298000515446427739\n  Static Field name <classLoader> type object value 0\n  Field name serviceSet type object\n  Field name legacyMap type object\n  Field name serviceMap type object\n  Field name legacyStrings type object\n  Field name servicesChanged type boolean\n  Field name legacyChanged type boolean\n  Field name entrySetCallCount type int\n  Field name entrySet type object\n  Field name version type double\n  Field name info type object\n  Field name name type object\n Id 0x6c9d0a88 Class sun.security.util.Debug SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name hexDigits type object value 1684166896\n   Ref object char[]#114\n  Static Field name args type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name prefix type object\n Id 0x6cc439b0 Class java.security.Provider$EngineDescription SuperClass java.lang.Object Instance size 24 Instance count 30 All Instances Size 720\n  Static Field name <classLoader> type object value 0\n  Field name constructorParameterClass type object\n  Field name constructorParameterClassName type object\n  Field name supportsParameter type boolean\n  Field name name type object\n  Instance Id 0x6462aa08 number 1 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462aa98\n   Field value of instance 0x6462aa80\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#24\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462aab0 number 2 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462ab30\n   Field value of instance 0x6462ab18\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#26\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ab48 number 3 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462abb0\n   Field value of instance 0x6462ab98\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#28\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462abc8 number 4 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462ac40\n   Field value of instance 0x6462ac28\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#30\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ac58 number 5 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462aca8\n   Field value of instance 0x6462acc0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#31\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462acd8 number 6 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462ad30\n   Field value of instance 0x6462ad48\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#33\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ad60 number 7 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462add0\n   Field value of instance 0x6462adb8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#36\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ade8 number 8 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value true\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462ae50\n   Field value of instance 0x6462ae38\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#38\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ae68 number 9 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462aec8\n   Field value of instance 0x6462aee0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#39\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462aef8 number 10 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462af70\n   Field value of instance 0x6462af58\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#42\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462af88 number 11 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462afe8\n   Field value of instance 0x6462b000\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#43\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b018 number 12 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b068\n   Field value of instance 0x6462b080\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#45\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b098 number 13 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value true\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b0f8\n   Field value of instance 0x6462b0e0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#48\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b110 number 14 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b170\n   Field value of instance 0x6462b188\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#49\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b1a0 number 15 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value true\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b1e8\n   Field value of instance 0x6462b200\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#51\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b218 number 16 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value true\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b288\n   Field value of instance 0x6462b270\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#54\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b2a0 number 17 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b2f8\n   Field value of instance 0x6462b310\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#55\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b328 number 18 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b388\n   Field value of instance 0x6462b3a0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#57\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b3b8 number 19 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b430\n   Field value of instance 0x6462b418\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#60\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b448 number 20 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b498\n   Field value of instance 0x6462b4b0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#61\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b4c8 number 21 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b530\n   Field value of instance 0x6462b548\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#63\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b560 number 22 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b5c0\n   Field value of instance 0x6462b5d8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#65\n    Next object java.util.HashMap$Entry#75\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b5f0 number 23 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b668\n   Field value of instance 0x6462b650\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#68\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b680 number 24 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b6e0\n   Field value of instance 0x6462b6f8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#69\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b710 number 25 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462b980\n   Field value of instance 0x6462b758\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#72\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b998 number 26 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462ba08\n   Field value of instance 0x6462b9f0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#74\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ba20 number 27 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462baa0\n   Field value of instance 0x6462ba88\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#76\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bab8 number 28 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462bb28\n   Field value of instance 0x6462bb10\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#78\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bb40 number 29 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462bbb8\n   Field value of instance 0x6462bba0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#80\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bbd0 number 30 retained size 24\n   Instance Field name constructorParameterClass type object value 0\n   Instance Field name constructorParameterClassName type object value 0\n   Instance Field name supportsParameter type boolean value false\n   Instance Field name name type object value 0\n   References count 2\n   Field value of instance 0x6462bc48\n   Field value of instance 0x6462bc30\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#82\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n Id 0x6cc43588 Class java.security.Provider$ServiceKey SuperClass java.lang.Object Instance size 24 Instance count 1 All Instances Size 24\n  Static Field name <classLoader> type object value 0\n  Field name originalAlgorithm type object\n  Field name algorithm type object\n  Field name type type object\n  Instance Id 0x6462a9c8 number 1 retained size 24\n   Instance Field name originalAlgorithm type object value 0\n   Instance Field name algorithm type object value 0\n   Instance Field name type type object value 0\n   References count 1\n   Field previousKey of Class java.security.Provider\n   Path to nearest GC root\n    Next object java.lang.Class#328\n Id 0x6cc33e50 Class java.util.zip.ZipEntry SuperClass java.lang.Object Instance size 56 Instance count 0 All Instances Size 0\n  Static Field name DEFLATED type int value 8\n  Static Field name STORED type int value 0\n  Static Field name <classLoader> type object value 0\n  Field name comment type object\n  Field name extra type object\n  Field name method type int\n  Field name csize type long\n  Field name size type long\n  Field name crc type long\n  Field name time type long\n  Field name name type object\n Id 0x6cc3d0b0 Class sun.misc.ExtensionDependency SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name DEBUG type boolean value false\n  Static Field name providers type object value 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cc3bc98 Class sun.misc.JarIndex SuperClass java.lang.Object Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name INDEX_NAME type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name jarFiles type object\n  Field name jarMap type object\n  Field name indexMap type object\n Id 0x6cad0c10 Class sun.misc.FileURLMapper SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name path type object\n  Field name url type object\n Id 0x6cc3dc10 Class sun.misc.URLClassPath$JarLoader$2 SuperClass sun.misc.Resource Instance size 32 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name this$0 type object\n  Field name val$entry type object\n  Field name val$url type object\n  Field name val$name type object\n Id 0x6cad0658 Class sun.misc.URLClassPath$JarLoader$1 SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name this$0 type object\n Id 0x6cc32ae0 Class sun.misc.JavaUtilJarAccess SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cc48c78 Class sun.security.provider.NativePRNG SuperClass java.security.SecureRandomSpi Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name INSTANCE type object value 1684205512\n   Ref object sun.security.provider.NativePRNG$RandomIO#1\n  Static Field name NAME_URANDOM type object value 0\n  Static Field name NAME_RANDOM type object value 0\n  Static Field name serialVersionUID type long value -6599091113397072932\n  Static Field name <classLoader> type object value 0\n Id 0x6cc43da0 Class sun.security.provider.Sun$1 SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cc45658 Class java.security.Security SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name spiMap type object value 1684196960\n   Ref object java.util.concurrent.ConcurrentHashMap#2\n  Static Field name props type object value 1684192352\n   Ref object java.util.Properties#2\n  Static Field name sdebug type object value 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c97fec0 Class java.lang.ref.Reference$ReferenceHandler SuperClass java.lang.Thread Instance size 104 Instance count 1 All Instances Size 104\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610978 number 1 retained size 184\n   Instance Field name uncaughtExceptionHandler type object value 0\n   Instance Field name throwableFromStop type object value 0\n   Instance Field name stopBeforeStart type boolean value false\n   Instance Field name blockerLock type object value 1684081128\n    Ref object java.lang.Object#2\n   Instance Field name blocker type object value 0\n   Instance Field name parkBlocker type object value 0\n   Instance Field name threadStatus type int value 401\n   Instance Field name tid type long value 2\n   Instance Field name nativeParkEventPointer type long value 0\n   Instance Field name stackSize type long value 0\n   Instance Field name inheritableThreadLocals type object value 0\n   Instance Field name threadLocals type object value 0\n   Instance Field name inheritedAccessControlContext type object value 1684081184\n    Ref object java.security.AccessControlContext#2\n   Instance Field name contextClassLoader type object value 0\n   Instance Field name group type object value 1684080032\n    Ref object java.lang.ThreadGroup#1\n   Instance Field name target type object value 0\n   Instance Field name stillborn type boolean value false\n   Instance Field name daemon type boolean value true\n   Instance Field name single_step type boolean value false\n   Instance Field name eetop type long value 134743040\n   Instance Field name threadQ type object value 0\n   Instance Field name priority type int value 10\n   Instance Field name name type object value 1684081136\n    Ref object char[]#8\n   References count 1\n   Element 0 of array 0x64610a38\n   Path to nearest GC root\n Id 0x6c97fa48 Class java.lang.ref.Reference$Lock SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610970 number 1 retained size 8\n   References count 1\n   Field lock of Class java.lang.ref.Reference\n   Path to nearest GC root\n Id 0x6c979538 Class java.lang.ref.ReferenceQueue SuperClass java.lang.Object Instance size 24 Instance count 2 All Instances Size 48\n  Static Field name ENQUEUED type object value 1684080312\n   Ref object java.lang.ref.ReferenceQueue$Null#2\n  Static Field name NULL type object value 1684080280\n   Ref object java.lang.ref.ReferenceQueue$Null#1\n  Static Field name <classLoader> type object value 0\n  Field name queueLength type long\n  Field name head type object\n  Field name lock type object\n  Instance Id 0x646106d8 number 1 retained size 32\n   Instance Field name queueLength type long value 0\n   Instance Field name head type object value 0\n   Instance Field name lock type object value 1684080368\n    Ref object java.lang.ref.ReferenceQueue$Lock#3\n   References count 1\n   Field queue of instance 0x64610678\n   Path to nearest GC root\n    Next object sun.misc.SoftCache#1\n    Next object java.lang.Class#92\n  Instance Id 0x64610a58 number 2 retained size 24\n   Instance Field name queueLength type long value 0\n   Instance Field name head type object value 0\n   Instance Field name lock type object value 1684081264\n    Ref object java.lang.ref.ReferenceQueue$Lock#4\n   References count 9\n   Field queue of instance 0x6462f028\n   Field queue of instance 0x6462f068\n   Field queue of Class java.lang.ref.Finalizer\n   Field queue of instance 0x64625298\n   Field queue of instance 0x64628ff8\n   Field queue of instance 0x64629fc8\n   Field queue of instance 0x646164e8\n   Field queue of instance 0x64616520\n   Field queue of instance 0x64616558\n   Path to nearest GC root\n Id 0x6c9f5ef0 Class sun.nio.ByteBuffered SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cc460b8 Class java.security.Security$1 SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c980340 Class java.lang.ref.Finalizer$FinalizerThread SuperClass java.lang.Thread Instance size 104 Instance count 1 All Instances Size 104\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610a80 number 1 retained size 168\n   Instance Field name uncaughtExceptionHandler type object value 0\n   Instance Field name throwableFromStop type object value 0\n   Instance Field name stopBeforeStart type boolean value false\n   Instance Field name blockerLock type object value 1684081392\n    Ref object java.lang.Object#4\n   Instance Field name blocker type object value 0\n   Instance Field name parkBlocker type object value 0\n   Instance Field name threadStatus type int value 401\n   Instance Field name tid type long value 3\n   Instance Field name nativeParkEventPointer type long value 0\n   Instance Field name stackSize type long value 0\n   Instance Field name inheritableThreadLocals type object value 0\n   Instance Field name threadLocals type object value 0\n   Instance Field name inheritedAccessControlContext type object value 1684081432\n    Ref object java.security.AccessControlContext#3\n   Instance Field name contextClassLoader type object value 0\n   Instance Field name group type object value 1684080032\n    Ref object java.lang.ThreadGroup#1\n   Instance Field name target type object value 0\n   Instance Field name stillborn type boolean value false\n   Instance Field name daemon type boolean value true\n   Instance Field name single_step type boolean value false\n   Instance Field name eetop type long value 134760448\n   Instance Field name threadQ type object value 0\n   Instance Field name priority type int value 8\n   Instance Field name name type object value 1684081400\n    Ref object char[]#9\n   References count 1\n   Element 1 of array 0x64610a38\n   Path to nearest GC root\n Id 0x6ca04b28 Class java.security.AllPermission SuperClass java.security.Permission Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value -2916474571451318075\n  Static Field name <classLoader> type object value 0\n Id 0x6ca05830 Class java.security.UnresolvedPermission SuperClass java.security.Permission Instance size 32 Instance count 0 All Instances Size 0\n  Static Field name PARAMS2 type object value 0\n  Static Field name PARAMS1 type object value 0\n  Static Field name PARAMS0 type object value 0\n  Static Field name debug type object value 0\n  Static Field name serialVersionUID type long value -4821973115467008846\n  Static Field name <classLoader> type object value 0\n  Field name certs type object\n  Field name actions type object\n  Field name name type object\n  Field name type type object\n Id 0x6c945ad0 Class java.lang.Runnable SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x68131a78 Class java.lang.Runnable[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c991838 Class java.lang.ThreadLocal$ThreadLocalMap SuperClass java.lang.Object Instance size 24 Instance count 1 All Instances Size 24\n  Static Field name INITIAL_CAPACITY type int value 16\n  Static Field name <classLoader> type object value 0\n  Field name threshold type int\n  Field name size type int\n  Field name table type object\n  Instance Id 0x64615100 number 1 retained size 328\n   Instance Field name threshold type int value 10\n   Instance Field name size type int value 3\n   Instance Field name table type object value 1684099352\n    Ref object java.lang.ThreadLocal$ThreadLocalMap$Entry[]#1\n   References count 1\n   Field threadLocals of instance 0x64610790\n   Path to nearest GC root\n    Next object java.lang.Thread#1\n Id 0x6c987e80 Class java.lang.ThreadLocal SuperClass java.lang.Object Instance size 16 Instance count 3 All Instances Size 48\n  Static Field name HASH_INCREMENT type int value 1640531527\n  Static Field name nextHashCode type object value 1684098880\n   Ref object java.util.concurrent.atomic.AtomicInteger#1\n  Static Field name <classLoader> type object value 0\n  Field name threadLocalHashCode type int\n  Instance Id 0x64614f50 number 1 retained size 16\n   Instance Field name threadLocalHashCode type int value 0\n   References count 1\n   Field gate of Class java.nio.charset.Charset\n   Path to nearest GC root\n    Next object java.lang.Class#419\n  Instance Id 0x646150e0 number 2 retained size 16\n   Instance Field name threadLocalHashCode type int value 1640531527\n   References count 2\n   Field decoder of Class java.lang.StringCoding\n   Field referent of instance 0x64615168\n   Path to nearest GC root\n    Next object java.lang.Class#218\n  Instance Id 0x646150f0 number 3 retained size 16\n   Instance Field name threadLocalHashCode type int value -1013904242\n   References count 2\n   Field encoder of Class java.lang.StringCoding\n   Field referent of instance 0x64625070\n   Path to nearest GC root\n    Next object java.lang.Class#218\n Id 0x6c947e60 Class java.lang.Thread$UncaughtExceptionHandler SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x68131050 Class java.lang.Thread$UncaughtExceptionHandler[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c978d28 Class sun.misc.SoftCache SuperClass java.util.AbstractMap Instance size 32 Instance count 1 All Instances Size 32\n  Static Field name <classLoader> type object value 0\n  Field name entrySet type object\n  Field name queue type object\n  Field name hash type object\n  Instance Id 0x64610678 number 1 retained size 184\n   Instance Field name entrySet type object value 0\n   Instance Field name queue type object value 1684080344\n    Ref object java.lang.ref.ReferenceQueue#1\n   Instance Field name hash type object value 1684080376\n    Ref object java.util.HashMap#1\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field subclassAudits of Class java.lang.Thread\n   Path to nearest GC root\n    Next object java.lang.Class#92\n Id 0x6c9fcc00 Class java.net.ContentHandler SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9fcf58 Class java.net.UnknownContentHandler SuperClass java.net.ContentHandler Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64630918 number 1 retained size 8\n   References count 1\n   Field UnknownContentHandlerP of Class java.net.URLConnection\n   Path to nearest GC root\n    Next object java.lang.Class#206\n Id 0x6cc48278 Class sun.misc.FloatingDecimal$1 SuperClass java.lang.ThreadLocal Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462d3c8 number 1 retained size 16\n   Instance Field name threadLocalHashCode type int value 626627285\n   References count 2\n   Field perThreadBuffer of Class sun.misc.FloatingDecimal\n   Field referent of instance 0x6462ef30\n   Path to nearest GC root\n    Next object java.lang.Class#394\n Id 0x6c9fdef0 Class sun.net.www.MessageHeader SuperClass java.lang.Object Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name nkeys type int\n  Field name values type object\n  Field name keys type object\n Id 0x6cc48670 Class java.security.SecureRandomSpi SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value -2991854161009191830\n  Static Field name <classLoader> type object value 0\n Id 0x6cc490a0 Class sun.security.provider.NativePRNG$1 SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9bb620 Class java.io.BufferedWriter SuperClass java.io.Writer Instance size 40 Instance count 2 All Instances Size 80\n  Static Field name defaultCharBufferSize type int value 8192\n  Static Field name <classLoader> type object value 0\n  Field name lineSeparator type object\n  Field name nextChar type int\n  Field name nChars type int\n  Field name cb type object\n  Field name out type object\n  Instance Id 0x64616aa0 number 1 retained size 16440\n   Instance Field name lineSeparator type object value 1684083664\n    Ref object java.lang.String#33\n   Instance Field name nextChar type int value 0\n   Instance Field name nChars type int value 8192\n   Instance Field name cb type object value 1684123360\n    Ref object char[]#106\n   Instance Field name out type object value 1684105624\n    Ref object java.io.OutputStreamWriter#1\n   Instance Field name lock type object value 1684105624\n    Ref object java.io.OutputStreamWriter#1\n   Instance Field name writeBufferSize type int value 1024\n   Instance Field name writeBuffer type object value 0\n   References count 1\n   Field textOut of instance 0x646168d0\n   Path to nearest GC root\n    Next object java.io.PrintStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616c78 number 2 retained size 16440\n   Instance Field name lineSeparator type object value 1684083664\n    Ref object java.lang.String#33\n   Instance Field name nextChar type int value 0\n   Instance Field name nChars type int value 8192\n   Instance Field name cb type object value 1684147968\n    Ref object char[]#107\n   Instance Field name out type object value 1684106128\n    Ref object java.io.OutputStreamWriter#2\n   Instance Field name lock type object value 1684106128\n    Ref object java.io.OutputStreamWriter#2\n   Instance Field name writeBufferSize type int value 1024\n   Instance Field name writeBuffer type object value 0\n   References count 1\n   Field textOut of instance 0x64616ac8\n   Path to nearest GC root\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n Id 0x6cc49a18 Class sun.security.provider.NativePRNG$RandomIO SuperClass java.lang.Object Instance size 56 Instance count 1 All Instances Size 56\n  Static Field name BUFFER_SIZE type int value 32\n  Static Field name MAX_BUFFER_TIME type long value 100\n  Static Field name <classLoader> type object value 0\n  Field name LOCK_SET_SEED type object\n  Field name LOCK_GET_SEED type object\n  Field name LOCK_GET_BYTES type object\n  Field name lastRead type long\n  Field name buffered type int\n  Field name urandomBuffer type object\n  Field name mixRandom type object\n  Field name randomOutInitialized type boolean\n  Field name randomOut type object\n  Field name urandomIn type object\n  Field name randomIn type object\n  Instance Id 0x6462efc8 number 1 retained size 128\n   Instance Field name LOCK_SET_SEED type object value 1684205584\n    Ref object java.lang.Object#15\n   Instance Field name LOCK_GET_SEED type object value 1684205576\n    Ref object java.lang.Object#14\n   Instance Field name LOCK_GET_BYTES type object value 1684205568\n    Ref object java.lang.Object#13\n   Instance Field name lastRead type long value 0\n   Instance Field name buffered type int value 0\n   Instance Field name urandomBuffer type object value 1684205720\n    Ref object byte[]#11\n   Instance Field name mixRandom type object value 0\n   Instance Field name randomOutInitialized type boolean value false\n   Instance Field name randomOut type object value 0\n   Instance Field name urandomIn type object value 1684205656\n    Ref object java.io.FileInputStream#3\n   Instance Field name randomIn type object value 1684205592\n    Ref object java.io.FileInputStream#2\n   References count 1\n   Field INSTANCE of Class sun.security.provider.NativePRNG\n   Path to nearest GC root\n    Next object java.lang.Class#339\n Id 0x6c9b6358 Class java.io.OutputStreamWriter SuperClass java.io.Writer Instance size 24 Instance count 2 All Instances Size 48\n  Static Field name <classLoader> type object value 0\n  Field name se type object\n  Instance Id 0x64616998 number 1 retained size 8440\n   Instance Field name se type object value 1684105648\n    Ref object sun.nio.cs.StreamEncoder#1\n   Instance Field name lock type object value 1684105424\n    Ref object java.io.PrintStream#1\n   Instance Field name writeBufferSize type int value 1024\n   Instance Field name writeBuffer type object value 0\n   References count 4\n   Field charOut of instance 0x646168d0\n   Field lock of instance 0x646169b0\n   Field out of instance 0x64616aa0\n   Field lock of instance 0x64616aa0\n   Path to nearest GC root\n    Next object java.io.PrintStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616b90 number 2 retained size 8440\n   Instance Field name se type object value 1684106152\n    Ref object sun.nio.cs.StreamEncoder#2\n   Instance Field name lock type object value 1684105928\n    Ref object java.io.PrintStream#2\n   Instance Field name writeBufferSize type int value 1024\n   Instance Field name writeBuffer type object value 0\n   References count 4\n   Field charOut of instance 0x64616ac8\n   Field lock of instance 0x64616ba8\n   Field out of instance 0x64616c78\n   Field lock of instance 0x64616c78\n   Path to nearest GC root\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n Id 0x6ca2de60 Class java.util.Properties$LineReader SuperClass java.lang.Object Instance size 40 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name this$0 type object\n  Field name reader type object\n  Field name inStream type object\n  Field name inOff type int\n  Field name inLimit type int\n  Field name lineBuf type object\n  Field name inCharBuf type object\n  Field name inByteBuf type object\n Id 0x6c9fb5c8 Class sun.net.www.URLConnection SuperClass java.net.URLConnection Instance size 56 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name properties type object\n  Field name contentLength type int\n  Field name contentType type object\n Id 0x6cc4a510 Class sun.misc.CharacterDecoder SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9a1ff8 Class java.util.Collections SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name REVERSE_ORDER type object value 1684098464\n   Ref object java.util.Collections$ReverseComparator#1\n  Static Field name EMPTY_MAP type object value 1684098448\n   Ref object java.util.Collections$EmptyMap#1\n  Static Field name EMPTY_LIST type object value 1684098432\n   Ref object java.util.Collections$EmptyList#1\n  Static Field name EMPTY_SET type object value 1684098424\n   Ref object java.util.Collections$EmptySet#1\n  Static Field name r type object value 0\n  Static Field name INDEXOFSUBLIST_THRESHOLD type int value 35\n  Static Field name REPLACEALL_THRESHOLD type int value 11\n  Static Field name COPY_THRESHOLD type int value 10\n  Static Field name ROTATE_THRESHOLD type int value 100\n  Static Field name FILL_THRESHOLD type int value 25\n  Static Field name SHUFFLE_THRESHOLD type int value 5\n  Static Field name REVERSE_THRESHOLD type int value 18\n  Static Field name BINARYSEARCH_THRESHOLD type int value 5000\n  Static Field name <classLoader> type object value 0\n Id 0x6c980a30 Class java.util.Hashtable$EmptyEnumerator SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610b30 number 1 retained size 8\n   References count 1\n   Field emptyEnumerator of Class java.util.Hashtable\n   Path to nearest GC root\n    Next object java.lang.Class#143\n Id 0x6c94bcd0 Class java.util.Dictionary SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9818b0 Class java.util.Hashtable$Entry SuperClass java.lang.Object Instance size 24 Instance count 153 All Instances Size 3672\n  Static Field name <classLoader> type object value 0\n  Field name next type object\n  Field name value type object\n  Field name key type object\n  Field name hash type int\n  Instance Id 0x64610c28 number 1 retained size 160\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684081656\n    Ref object java.lang.String#8\n   Instance Field name key type object value 1684081568\n    Ref object java.lang.String#7\n   Instance Field name hash type int value -333068255\n   References count 1\n   Field next of instance 0x64611588\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#17\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610d00 number 2 retained size 360\n   Instance Field name next type object value 1684082912\n    Ref object java.util.Hashtable$Entry#8\n   Instance Field name value type object value 1684081816\n    Ref object java.lang.String#10\n   Instance Field name key type object value 1684081728\n    Ref object java.lang.String#9\n   Instance Field name hash type int value -2704414\n   References count 1\n   Element 49 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610dc0 number 3 retained size 192\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684082032\n    Ref object java.lang.String#12\n   Instance Field name key type object value 1684081944\n    Ref object java.lang.String#11\n   Instance Field name hash type int value 1928785119\n   References count 1\n   Field next of instance 0x64611478\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#15\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610e18 number 4 retained size 88\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 1684082136\n    Ref object java.lang.String#13\n   Instance Field name hash type int value 560567564\n   References count 1\n   Element 19 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610ec0 number 5 retained size 168\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684082288\n    Ref object java.lang.String#15\n   Instance Field name key type object value 1684082224\n    Ref object java.lang.String#14\n   Instance Field name hash type int value 987780756\n   References count 1\n   Element 16 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610f70 number 6 retained size 176\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684082464\n    Ref object java.lang.String#17\n   Instance Field name key type object value 1684082392\n    Ref object java.lang.String#16\n   Instance Field name hash type int value -1895720171\n   References count 1\n   Field next of instance 0x64615a90\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#37\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611050 number 7 retained size 224\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684082648\n    Ref object java.lang.String#19\n   Instance Field name key type object value 1684082568\n    Ref object java.lang.String#18\n   Instance Field name hash type int value -1342541797\n   References count 1\n   Element 11 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646110e0 number 8 retained size 144\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684082864\n    Ref object java.lang.String#21\n   Instance Field name key type object value 1684082792\n    Ref object java.lang.String#20\n   Instance Field name hash type int value -1922408554\n   References count 1\n   Field next of instance 0x64610d00\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#2\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611160 number 9 retained size 128\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684082992\n    Ref object java.lang.String#23\n   Instance Field name key type object value 1684082936\n    Ref object java.lang.String#22\n   Instance Field name hash type int value -1228098475\n   References count 1\n   Element 63 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646111f8 number 10 retained size 152\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684083120\n    Ref object java.lang.String#25\n   Instance Field name key type object value 1684083064\n    Ref object java.lang.String#24\n   Instance Field name hash type int value 1174476494\n   References count 1\n   Element 44 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611278 number 11 retained size 128\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684083272\n    Ref object java.lang.String#27\n   Instance Field name key type object value 1684083216\n    Ref object java.lang.String#26\n   Instance Field name hash type int value -1228469728\n   References count 1\n   Field next of instance 0x64615ca8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#40\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646112f8 number 12 retained size 128\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684083408\n    Ref object java.lang.String#29\n   Instance Field name key type object value 1684083344\n    Ref object java.lang.String#28\n   Instance Field name hash type int value 465797363\n   References count 1\n   Element 13 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611378 number 13 retained size 128\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684083536\n    Ref object java.lang.String#31\n   Instance Field name key type object value 1684083472\n    Ref object java.lang.String#30\n   Instance Field name hash type int value 1989177436\n   References count 1\n   Element 81 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646113f8 number 14 retained size 88\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684083664\n    Ref object java.lang.String#33\n   Instance Field name key type object value 1684083600\n    Ref object java.lang.String#32\n   Instance Field name hash type int value 1985578347\n   References count 1\n   Field next of instance 0x646152b0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#27\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611478 number 15 retained size 320\n   Instance Field name next type object value 1684082112\n    Ref object java.util.Hashtable$Entry#3\n   Instance Field name value type object value 1684083792\n    Ref object java.lang.String#35\n   Instance Field name key type object value 1684083728\n    Ref object java.lang.String#34\n   Instance Field name hash type int value 1102884379\n   References count 1\n   Element 24 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646114f8 number 16 retained size 280\n   Instance Field name next type object value 1684085328\n    Ref object java.util.Hashtable$Entry#25\n   Instance Field name value type object value 1684083920\n    Ref object java.lang.String#37\n   Instance Field name key type object value 1684083856\n    Ref object java.lang.String#36\n   Instance Field name hash type int value -1309845389\n   References count 1\n   Field next of instance 0x64616398\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611588 number 17 retained size 304\n   Instance Field name next type object value 1684081704\n    Ref object java.util.Hashtable$Entry#1\n   Instance Field name value type object value 1684084048\n    Ref object java.lang.String#39\n   Instance Field name key type object value 1684083984\n    Ref object java.lang.String#38\n   Instance Field name hash type int value 1808897413\n   References count 1\n   Element 38 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611620 number 18 retained size 96\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684084200\n    Ref object java.lang.String#41\n   Instance Field name key type object value 1684084128\n    Ref object java.lang.String#40\n   Instance Field name hash type int value 676668242\n   References count 1\n   Element 57 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646116b0 number 19 retained size 144\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684084352\n    Ref object java.lang.String#43\n   Instance Field name key type object value 1684084280\n    Ref object java.lang.String#42\n   Instance Field name hash type int value 1449649635\n   References count 1\n   Field next of instance 0x646159e8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#36\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611760 number 20 retained size 312\n   Instance Field name next type object value 1684084848\n    Ref object java.util.Hashtable$Entry#22\n   Instance Field name value type object value 1684084512\n    Ref object java.lang.String#45\n   Instance Field name key type object value 1684084424\n    Ref object java.lang.String#44\n   Instance Field name hash type int value 1813232234\n   References count 1\n   Element 9 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646117e8 number 21 retained size 136\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684084672\n    Ref object java.lang.String#47\n   Instance Field name key type object value 1684084600\n    Ref object java.lang.String#46\n   Instance Field name hash type int value -726990163\n   References count 1\n   Element 0 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611870 number 22 retained size 136\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684084800\n    Ref object java.lang.String#49\n   Instance Field name key type object value 1684084736\n    Ref object java.lang.String#48\n   Instance Field name hash type int value -1943614589\n   References count 1\n   Field next of instance 0x64611760\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#20\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611928 number 23 retained size 184\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684084952\n    Ref object java.lang.String#51\n   Instance Field name key type object value 1684084872\n    Ref object java.lang.String#50\n   Instance Field name hash type int value 703906719\n   References count 1\n   Element 39 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646119b8 number 24 retained size 144\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684085136\n    Ref object java.lang.String#53\n   Instance Field name key type object value 1684085056\n    Ref object java.lang.String#52\n   Instance Field name hash type int value 919949531\n   References count 1\n   Field next of instance 0x64615fc8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#43\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611a50 number 25 retained size 152\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684085272\n    Ref object java.lang.String#55\n   Instance Field name key type object value 1684085200\n    Ref object java.lang.String#54\n   Instance Field name hash type int value -1806116554\n   References count 1\n   Field next of instance 0x646114f8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#16\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611b18 number 26 retained size 200\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684085432\n    Ref object java.lang.String#57\n   Instance Field name key type object value 1684085352\n    Ref object java.lang.String#56\n   Instance Field name hash type int value -1854834746\n   References count 1\n   Element 72 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646152b0 number 27 retained size 224\n   Instance Field name next type object value 1684083704\n    Ref object java.util.Hashtable$Entry#14\n   Instance Field name value type object value 1684099712\n    Ref object java.lang.String#59\n   Instance Field name key type object value 1684099272\n    Ref object java.lang.String#58\n   Instance Field name hash type int value -378505966\n   References count 1\n   Element 67 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615338 number 28 retained size 136\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684099840\n    Ref object java.lang.String#61\n   Instance Field name key type object value 1684099784\n    Ref object java.lang.String#60\n   Instance Field name hash type int value 294088398\n   References count 1\n   Field next of instance 0x64616068\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#44\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646153c8 number 29 retained size 144\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684099976\n    Ref object java.lang.String#63\n   Instance Field name key type object value 1684099920\n    Ref object java.lang.String#62\n   Instance Field name hash type int value 293923106\n   References count 1\n   Element 41 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615448 number 30 retained size 128\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684100128\n    Ref object java.lang.String#65\n   Instance Field name key type object value 1684100064\n    Ref object java.lang.String#64\n   Instance Field name hash type int value 640246460\n   References count 1\n   Element 40 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646154c8 number 31 retained size 128\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684100248\n    Ref object java.lang.String#67\n   Instance Field name key type object value 1684100192\n    Ref object java.lang.String#66\n   Instance Field name hash type int value -267617302\n   References count 1\n   Field next of instance 0x64615648\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#33\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615570 number 32 retained size 168\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684100416\n    Ref object java.lang.String#69\n   Instance Field name key type object value 1684100320\n    Ref object java.lang.String#68\n   Instance Field name hash type int value -975448766\n   References count 1\n   Element 27 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615648 number 33 retained size 344\n   Instance Field name next type object value 1684100296\n    Ref object java.util.Hashtable$Entry#31\n   Instance Field name value type object value 1684100576\n    Ref object java.lang.String#71\n   Instance Field name key type object value 1684100488\n    Ref object java.lang.String#70\n   Instance Field name hash type int value 1980476001\n   References count 1\n   Element 76 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615710 number 34 retained size 200\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684100800\n    Ref object java.lang.String#73\n   Instance Field name key type object value 1684100704\n    Ref object java.lang.String#72\n   Instance Field name hash type int value 799684510\n   References count 1\n   Element 65 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646157b0 number 35 retained size 160\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684100976\n    Ref object java.lang.String#75\n   Instance Field name key type object value 1684100904\n    Ref object java.lang.String#74\n   Instance Field name hash type int value -535248915\n   References count 1\n   Field next of instance 0x64615d78\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#41\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646159e8 number 36 retained size 320\n   Instance Field name next type object value 1684084400\n    Ref object java.util.Hashtable$Entry#19\n   Instance Field name value type object value 1684101128\n    Ref object java.lang.String#77\n   Instance Field name key type object value 1684101064\n    Ref object java.lang.String#76\n   Instance Field name hash type int value 726644630\n   References count 1\n   Element 80 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615a90 number 37 retained size 344\n   Instance Field name next type object value 1684082544\n    Ref object java.util.Hashtable$Entry#6\n   Instance Field name value type object value 1684101696\n    Ref object java.lang.String#79\n   Instance Field name key type object value 1684101632\n    Ref object java.lang.String#78\n   Instance Field name hash type int value -1541420141\n   References count 1\n   Element 82 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615ae8 number 38 retained size 168\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684166792\n    Ref object java.lang.String#112\n   Instance Field name key type object value 1684101800\n    Ref object java.lang.String#80\n   Instance Field name hash type int value 726507961\n   References count 1\n   Element 21 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615bd8 number 39 retained size 112\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684101952\n    Ref object java.lang.String#82\n   Instance Field name key type object value 1684101888\n    Ref object java.lang.String#81\n   Instance Field name hash type int value 310802303\n   References count 1\n   Element 18 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615ca8 number 40 retained size 336\n   Instance Field name next type object value 1684083320\n    Ref object java.util.Hashtable$Entry#11\n   Instance Field name value type object value 1684102200\n    Ref object java.lang.String#84\n   Instance Field name key type object value 1684102128\n    Ref object java.lang.String#83\n   Instance Field name hash type int value 1241832660\n   References count 1\n   Element 70 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615d78 number 41 retained size 264\n   Instance Field name next type object value 1684101040\n    Ref object java.util.Hashtable$Entry#35\n   Instance Field name value type object value 1684102416\n    Ref object java.lang.String#86\n   Instance Field name key type object value 1684102336\n    Ref object java.lang.String#85\n   Instance Field name hash type int value -1477254190\n   References count 1\n   Element 88 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615f28 number 42 retained size 120\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684102616\n    Ref object java.lang.String#88\n   Instance Field name key type object value 1684102544\n    Ref object java.lang.String#87\n   Instance Field name hash type int value 1370996164\n   References count 1\n   Element 54 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615fc8 number 43 retained size 224\n   Instance Field name next type object value 1684085176\n    Ref object java.util.Hashtable$Entry#24\n   Instance Field name value type object value 1684103032\n    Ref object java.lang.String#90\n   Instance Field name key type object value 1684102976\n    Ref object java.lang.String#89\n   Instance Field name hash type int value -888764117\n   References count 1\n   Element 26 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616068 number 44 retained size 296\n   Instance Field name next type object value 1684099896\n    Ref object java.util.Hashtable$Entry#28\n   Instance Field name value type object value 1684103208\n    Ref object java.lang.String#92\n   Instance Field name key type object value 1684103136\n    Ref object java.lang.String#91\n   Instance Field name hash type int value 1370376743\n   References count 1\n   Element 33 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646162f8 number 45 retained size 656\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684103376\n    Ref object java.lang.String#94\n   Instance Field name key type object value 1684103296\n    Ref object java.lang.String#93\n   Instance Field name hash type int value 1425513397\n   References count 1\n   Element 17 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616398 number 46 retained size 440\n   Instance Field name next type object value 1684083960\n    Ref object java.util.Hashtable$Entry#16\n   Instance Field name value type object value 1684104024\n    Ref object java.lang.String#96\n   Instance Field name key type object value 1684103952\n    Ref object java.lang.String#95\n   Instance Field name hash type int value -1269521974\n   References count 1\n   Element 79 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616460 number 47 retained size 200\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684104200\n    Ref object java.lang.String#98\n   Instance Field name key type object value 1684104112\n    Ref object java.lang.String#97\n   Instance Field name hash type int value 218965832\n   References count 1\n   Element 47 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616478 number 48 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 348039414\n   References count 1\n   Element 74 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616490 number 49 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 721195821\n   References count 1\n   Element 91 of array 0x64615860\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646255b0 number 50 retained size 40\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684165456\n    Ref object sun.misc.Signal#1\n   Instance Field name key type object value 1684166048\n    Ref object java.lang.Integer#1\n   Instance Field name hash type int value 1\n   References count 1\n   Element 1 of array 0x64625330\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#3\n    Next object java.util.Hashtable#2\n    Next object java.lang.Class#145\n  Instance Id 0x646255c8 number 51 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684165304\n    Ref object java.lang.Terminator$1#1\n   Instance Field name key type object value 1684165456\n    Ref object sun.misc.Signal#1\n   Instance Field name hash type int value 1\n   References count 1\n   Element 1 of array 0x646252e8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#2\n    Next object java.util.Hashtable#1\n    Next object java.lang.Class#145\n  Instance Id 0x64625620 number 52 retained size 40\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684166144\n    Ref object sun.misc.Signal#2\n   Instance Field name key type object value 1684166160\n    Ref object java.lang.Integer#2\n   Instance Field name hash type int value 2\n   References count 1\n   Element 2 of array 0x64625330\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#3\n    Next object java.util.Hashtable#2\n    Next object java.lang.Class#145\n  Instance Id 0x64625638 number 53 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684165304\n    Ref object java.lang.Terminator$1#1\n   Instance Field name key type object value 1684166144\n    Ref object sun.misc.Signal#2\n   Instance Field name hash type int value 2\n   References count 1\n   Element 2 of array 0x646252e8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#2\n    Next object java.util.Hashtable#1\n    Next object java.lang.Class#145\n  Instance Id 0x64625670 number 54 retained size 40\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684166224\n    Ref object sun.misc.Signal#3\n   Instance Field name key type object value 1684166240\n    Ref object java.lang.Integer#3\n   Instance Field name hash type int value 15\n   References count 1\n   Element 3 of array 0x64625330\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#3\n    Next object java.util.Hashtable#2\n    Next object java.lang.Class#145\n  Instance Id 0x64625688 number 55 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684165304\n    Ref object java.lang.Terminator$1#1\n   Instance Field name key type object value 1684166224\n    Ref object sun.misc.Signal#3\n   Instance Field name hash type int value 15\n   References count 1\n   Element 3 of array 0x646252e8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#2\n    Next object java.util.Hashtable#1\n    Next object java.lang.Class#145\n  Instance Id 0x646279f8 number 56 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684175344\n    Ref object sun.net.www.protocol.file.Handler#1\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 3143036\n   References count 1\n   Element 6 of array 0x64626468\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#4\n    Next object java.util.Hashtable#3\n    Next object java.lang.Class#273\n  Instance Id 0x6462bd78 number 57 retained size 192\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684192544\n    Ref object java.lang.String#210\n   Instance Field name key type object value 1684192464\n    Ref object java.lang.String#209\n   Instance Field name hash type int value 1707668194\n   References count 1\n   Element 39 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462be40 number 58 retained size 304\n   Instance Field name next type object value 1684194256\n    Ref object java.util.Hashtable$Entry#65\n   Instance Field name value type object value 1684192736\n    Ref object java.lang.String#212\n   Instance Field name key type object value 1684192656\n    Ref object java.lang.String#211\n   Instance Field name hash type int value 1707668195\n   References count 1\n   Element 40 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bf18 number 59 retained size 216\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684192936\n    Ref object java.lang.String#214\n   Instance Field name key type object value 1684192856\n    Ref object java.lang.String#213\n   Instance Field name hash type int value 1707668196\n   References count 1\n   Element 41 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bfe0 number 60 retained size 200\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684193152\n    Ref object java.lang.String#216\n   Instance Field name key type object value 1684193072\n    Ref object java.lang.String#215\n   Instance Field name hash type int value 1707668197\n   References count 1\n   Element 42 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c0a8 number 61 retained size 200\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684193352\n    Ref object java.lang.String#218\n   Instance Field name key type object value 1684193272\n    Ref object java.lang.String#217\n   Instance Field name hash type int value 1707668198\n   References count 1\n   Element 43 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c170 number 62 retained size 200\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684193552\n    Ref object java.lang.String#220\n   Instance Field name key type object value 1684193472\n    Ref object java.lang.String#219\n   Instance Field name hash type int value 1707668199\n   References count 1\n   Element 44 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c250 number 63 retained size 456\n   Instance Field name next type object value 1684194488\n    Ref object java.util.Hashtable$Entry#66\n   Instance Field name value type object value 1684193752\n    Ref object java.lang.String#222\n   Instance Field name key type object value 1684193672\n    Ref object java.lang.String#221\n   Instance Field name hash type int value 1707668200\n   References count 1\n   Element 45 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c320 number 64 retained size 208\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684193976\n    Ref object java.lang.String#224\n   Instance Field name key type object value 1684193896\n    Ref object java.lang.String#223\n   Instance Field name hash type int value 1707668201\n   References count 1\n   Element 46 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c3d0 number 65 retained size 104\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684194184\n    Ref object java.lang.String#226\n   Instance Field name key type object value 1684194104\n    Ref object java.lang.String#225\n   Instance Field name hash type int value -1295903345\n   References count 1\n   Field next of instance 0x6462be40\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#58\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c4b8 number 66 retained size 232\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684194376\n    Ref object java.lang.String#228\n   Instance Field name key type object value 1684194280\n    Ref object java.lang.String#227\n   Instance Field name hash type int value -342094834\n   References count 1\n   Field next of instance 0x6462c250\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#63\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c580 number 67 retained size 200\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684194584\n    Ref object java.lang.String#230\n   Instance Field name key type object value 1684194512\n    Ref object java.lang.String#229\n   Instance Field name hash type int value 2061765421\n   References count 1\n   Element 18 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c650 number 68 retained size 208\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684194776\n    Ref object java.lang.String#232\n   Instance Field name key type object value 1684194712\n    Ref object java.lang.String#231\n   Instance Field name hash type int value 1308266422\n   References count 1\n   Element 37 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c708 number 69 retained size 184\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684194984\n    Ref object java.lang.String#234\n   Instance Field name key type object value 1684194920\n    Ref object java.lang.String#233\n   Instance Field name hash type int value 1308266423\n   References count 1\n   Field next of instance 0x6462c848\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#71\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c7a8 number 70 retained size 160\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684195192\n    Ref object java.lang.String#236\n   Instance Field name key type object value 1684195104\n    Ref object java.lang.String#235\n   Instance Field name hash type int value 290674857\n   References count 1\n   Element 20 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c848 number 71 retained size 344\n   Instance Field name next type object value 1684195080\n    Ref object java.util.Hashtable$Entry#69\n   Instance Field name value type object value 1684195352\n    Ref object java.lang.String#238\n   Instance Field name key type object value 1684195264\n    Ref object java.lang.String#237\n   Instance Field name hash type int value 472460817\n   References count 1\n   Element 38 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c8e8 number 72 retained size 160\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684195512\n    Ref object java.lang.String#240\n   Instance Field name key type object value 1684195424\n    Ref object java.lang.String#239\n   Instance Field name hash type int value -778438456\n   References count 1\n   Element 5 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c970 number 73 retained size 136\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684195648\n    Ref object java.lang.String#242\n   Instance Field name key type object value 1684195584\n    Ref object java.lang.String#241\n   Instance Field name hash type int value 1312008134\n   References count 1\n   Element 32 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cb00 number 74 retained size 200\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684195784\n    Ref object java.lang.String#244\n   Instance Field name key type object value 1684195720\n    Ref object java.lang.String#243\n   Instance Field name hash type int value -1748632107\n   References count 1\n   Element 0 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cb88 number 75 retained size 136\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684196184\n    Ref object java.lang.String#246\n   Instance Field name key type object value 1684196120\n    Ref object java.lang.String#245\n   Instance Field name hash type int value -978260980\n   References count 1\n   Element 2 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cc38 number 76 retained size 176\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684196360\n    Ref object java.lang.String#248\n   Instance Field name key type object value 1684196256\n    Ref object java.lang.String#247\n   Instance Field name hash type int value -1061199191\n   References count 1\n   Element 12 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462ccf0 number 77 retained size 184\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684196536\n    Ref object java.lang.String#250\n   Instance Field name key type object value 1684196432\n    Ref object java.lang.String#249\n   Instance Field name hash type int value -1955866405\n   References count 1\n   Element 29 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cda0 number 78 retained size 176\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684196720\n    Ref object java.lang.String#252\n   Instance Field name key type object value 1684196616\n    Ref object java.lang.String#251\n   Instance Field name hash type int value -2074044844\n   References count 1\n   Element 35 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462ce48 number 79 retained size 168\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684196896\n    Ref object java.lang.String#254\n   Instance Field name key type object value 1684196792\n    Ref object java.lang.String#253\n   Instance Field name hash type int value -1565910905\n   References count 1\n   Element 7 of array 0x6462ca38\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d3b0 number 80 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 587149203\n   References count 1\n   Field next of instance 0x6462f218\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#88\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462ef80 number 81 retained size 72\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684205392\n    Ref object java.lang.String#255\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1284827856\n   References count 1\n   Field next of instance 0x64630180\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#149\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462ef98 number 82 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 587012534\n   References count 1\n   Element 10 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462efb0 number 83 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -833795045\n   References count 1\n   Element 153 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f138 number 84 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -933441754\n   References count 1\n   Element 54 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f170 number 85 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -730498540\n   References count 1\n   Element 38 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f1a8 number 86 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 140521969\n   References count 1\n   Element 22 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f1e0 number 87 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1929113726\n   References count 1\n   Element 165 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f218 number 88 retained size 48\n   Instance Field name next type object value 1684198320\n    Ref object java.util.Hashtable$Entry#80\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -1609498800\n   References count 1\n   Element 114 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f250 number 89 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1063365446\n   References count 1\n   Element 68 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f288 number 90 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -990797485\n   References count 1\n   Element 95 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f2c0 number 91 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -2146182004\n   References count 1\n   Element 170 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f2f8 number 92 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -2146181986\n   References count 1\n   Element 188 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f330 number 93 retained size 72\n   Instance Field name next type object value 1684207056\n    Ref object java.util.Hashtable$Entry#105\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1766410121\n   References count 1\n   Field next of instance 0x6462f838\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#116\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f368 number 94 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 932172205\n   References count 1\n   Element 143 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f3a0 number 95 retained size 48\n   Instance Field name next type object value 1684206720\n    Ref object java.util.Hashtable$Entry#99\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -1074653458\n   References count 1\n   Element 189 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f3d8 number 96 retained size 96\n   Instance Field name next type object value 1684207168\n    Ref object java.util.Hashtable$Entry#107\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1751344326\n   References count 1\n   Element 4 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f410 number 97 retained size 48\n   Instance Field name next type object value 1684207392\n    Ref object java.util.Hashtable$Entry#111\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1839965079\n   References count 1\n   Field next of instance 0x6462f640\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#107\n    Next object java.util.Hashtable$Entry#96\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f448 number 98 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -1439934533\n   References count 1\n   Field next of instance 0x6462fa68\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#126\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f480 number 99 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -2144000001\n   References count 1\n   Field next of instance 0x6462f3a0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#95\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f4b8 number 100 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 19437734\n   References count 1\n   Element 46 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f4f0 number 101 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 19437769\n   References count 1\n   Element 81 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f528 number 102 retained size 48\n   Instance Field name next type object value 1684209600\n    Ref object java.util.Hashtable$Entry#141\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -1337775426\n   References count 1\n   Element 12 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f560 number 103 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1293392411\n   References count 1\n   Element 3 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f598 number 104 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 156560223\n   References count 1\n   Element 6 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f5d0 number 105 retained size 48\n   Instance Field name next type object value 1684207448\n    Ref object java.util.Hashtable$Entry#112\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -119186169\n   References count 1\n   Field next of instance 0x6462f330\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#93\n    Next object java.util.Hashtable$Entry#116\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f608 number 106 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1961373080\n   References count 1\n   Element 1 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f640 number 107 retained size 72\n   Instance Field name next type object value 1684206608\n    Ref object java.util.Hashtable$Entry#97\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1961373083\n   References count 1\n   Field next of instance 0x6462f3d8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#96\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f678 number 108 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1961378985\n   References count 1\n   Field next of instance 0x6462f6b0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#109\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f6b0 number 109 retained size 48\n   Instance Field name next type object value 1684207224\n    Ref object java.util.Hashtable$Entry#108\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -439958179\n   References count 1\n   Element 176 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f6e8 number 110 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 955639128\n   References count 1\n   Element 42 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f720 number 111 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -2004287697\n   References count 1\n   Field next of instance 0x6462f410\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#97\n    Next object java.util.Hashtable$Entry#107\n    Next object java.util.Hashtable$Entry#96\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f758 number 112 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -2004286645\n   References count 1\n   Field next of instance 0x6462f5d0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#105\n    Next object java.util.Hashtable$Entry#93\n    Next object java.util.Hashtable$Entry#116\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f790 number 113 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -2004284942\n   References count 1\n   Element 85 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f7c8 number 114 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 404303357\n   References count 1\n   Element 96 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f800 number 115 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -924640835\n   References count 1\n   Element 75 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f838 number 116 retained size 96\n   Instance Field name next type object value 1684206384\n    Ref object java.util.Hashtable$Entry#93\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -995212826\n   References count 1\n   Element 101 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f870 number 117 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1246906558\n   References count 1\n   Element 112 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f8a8 number 118 retained size 48\n   Instance Field name next type object value 1684209992\n    Ref object java.util.Hashtable$Entry#148\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1352270575\n   References count 1\n   Element 125 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f8e0 number 119 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -1094209544\n   References count 1\n   Element 20 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f918 number 120 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -1627234864\n   References count 1\n   Element 119 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f950 number 121 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 803149901\n   References count 1\n   Element 58 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f988 number 122 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 141527153\n   References count 1\n   Element 164 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f9c0 number 123 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1379285286\n   References count 1\n   Element 178 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462f9f8 number 124 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 2087082959\n   References count 1\n   Element 174 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fa30 number 125 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 2006604848\n   References count 1\n   Element 104 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fa68 number 126 retained size 48\n   Instance Field name next type object value 1684206664\n    Ref object java.util.Hashtable$Entry#98\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -2036469935\n   References count 1\n   Element 120 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462faa0 number 127 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -1605945850\n   References count 1\n   Element 82 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fad8 number 128 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1324846780\n   References count 1\n   Element 110 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fb10 number 129 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 744795759\n   References count 1\n   Element 45 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fb48 number 130 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -2006599515\n   References count 1\n   Element 50 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fd90 number 131 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -965079560\n   References count 1\n   Element 61 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fdc8 number 132 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -1027966128\n   References count 1\n   Element 52 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fe00 number 133 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -1309457329\n   References count 1\n   Element 67 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fe38 number 134 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 454670497\n   References count 1\n   Element 154 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fe70 number 135 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -2066837583\n   References count 1\n   Element 135 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fea8 number 136 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 822504318\n   References count 1\n   Element 63 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fee0 number 137 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -1392459843\n   References count 1\n   Element 41 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462ff18 number 138 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -1962587720\n   References count 1\n   Element 97 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462ff50 number 139 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1124751301\n   References count 1\n   Field next of instance 0x646301b8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#150\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462ff88 number 140 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -869362718\n   References count 1\n   Element 118 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462ffc0 number 141 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 1824143984\n   References count 1\n   Field next of instance 0x6462f528\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#102\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x6462fff8 number 142 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -341950268\n   References count 1\n   Element 66 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630030 number 143 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -675242876\n   References count 1\n   Element 166 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630068 number 144 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -377059786\n   References count 1\n   Element 168 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x646300a0 number 145 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 222042267\n   References count 1\n   Element 183 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x646300d8 number 146 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 710139668\n   References count 1\n   Element 140 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630110 number 147 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -2135945171\n   References count 1\n   Element 167 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630148 number 148 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -645983818\n   References count 1\n   Field next of instance 0x6462f8a8\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry#118\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630180 number 149 retained size 96\n   Instance Field name next type object value 1684205440\n    Ref object java.util.Hashtable$Entry#81\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -1890253555\n   References count 1\n   Element 79 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x646301b8 number 150 retained size 48\n   Instance Field name next type object value 1684209488\n    Ref object java.util.Hashtable$Entry#139\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value 766381439\n   References count 1\n   Element 51 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x646304f8 number 151 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -480125034\n   References count 1\n   Element 48 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630530 number 152 retained size 24\n   Instance Field name next type object value 0\n   Instance Field name value type object value 0\n   Instance Field name key type object value 0\n   Instance Field name hash type int value -2039128984\n   References count 1\n   Element 173 of array 0x646301f0\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630cc8 number 153 retained size 48\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684212920\n    Ref object java.security.cert.Certificate[]#1\n   Instance Field name key type object value 1684212896\n    Ref object java.lang.String#258\n   Instance Field name hash type int value -1422453681\n   References count 1\n   Element 2 of array 0x64628690\n   Path to nearest GC root\n    Next object java.util.Hashtable$Entry[]#6\n    Next object java.util.Hashtable#5\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x68131de8 Class java.util.Hashtable$Entry[] SuperClass java.lang.Object Instance size -1 Instance count 12 All Instances Size 1824\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64615860 number 1 retained size 8056\n   References count 1\n   Field table of instance 0x64610b70\n   Path to nearest GC root\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646252e8 number 2 retained size 104\n   References count 1\n   Field table of instance 0x646252c0\n   Path to nearest GC root\n    Next object java.util.Hashtable#1\n    Next object java.lang.Class#145\n  Instance Id 0x64625330 number 3 retained size 152\n   References count 1\n   Field table of instance 0x64625308\n   Path to nearest GC root\n    Next object java.util.Hashtable#2\n    Next object java.lang.Class#145\n  Instance Id 0x64626468 number 4 retained size 80\n   References count 1\n   Field table of instance 0x64626440\n   Path to nearest GC root\n    Next object java.util.Hashtable#3\n    Next object java.lang.Class#273\n  Instance Id 0x64627ff0 number 5 retained size 56\n   References count 1\n   Field table of instance 0x64627fc8\n   Path to nearest GC root\n    Next object java.util.Hashtable#4\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628690 number 6 retained size 104\n   References count 1\n   Field table of instance 0x64628668\n   Path to nearest GC root\n    Next object java.util.Hashtable#5\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646297f8 number 7 retained size 0\n   References count 1\n   Field table of instance 0x646297d0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629858 number 8 retained size 0\n   References count 1\n   Field table of instance 0x64629830\n   Path to nearest GC root\n    Null\n  Instance Id 0x646298b8 number 9 retained size 0\n   References count 1\n   Field table of instance 0x64629890\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462ca38 number 10 retained size 4424\n   References count 1\n   Field table of instance 0x6462bc60\n   Path to nearest GC root\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x646301f0 number 11 retained size 2576\n   References count 1\n   Field table of instance 0x6462d358\n   Path to nearest GC root\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x646308e0 number 12 retained size 56\n   References count 1\n   Field table of instance 0x646308b8\n   Path to nearest GC root\n    Next object java.util.Hashtable#9\n    Next object java.lang.Class#206\n Id 0x6c9811d8 Class java.util.Hashtable$EmptyIterator SuperClass java.lang.Object Instance size 8 Instance count 1 All Instances Size 8\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610b38 number 1 retained size 8\n   References count 1\n   Field emptyIterator of Class java.util.Hashtable\n   Path to nearest GC root\n    Next object java.lang.Class#143\n Id 0x6c9ff2d0 Class java.io.FilePermission$1 SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name this$0 type object\n Id 0x6ca04408 Class java.io.FilePermissionCollection SuperClass java.security.PermissionCollection Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name serialPersistentFields type object value 1684212320\n   Ref object java.io.ObjectStreamField[]#7\n  Static Field name serialVersionUID type long value 2202956749081564585\n  Static Field name <classLoader> type object value 0\n  Field name perms type object\n  Instance Id 0x64630a90 number 1 retained size 200\n   Instance Field name perms type object value 1684212384\n    Ref object java.util.ArrayList#7\n   Instance Field name readOnly type boolean value false\n   References count 1\n   Field value of instance 0x64630af0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#153\n    Next object java.util.HashMap$Entry[]#24\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6ca02b08 Class sun.security.provider.PolicyFile SuperClass java.security.Policy Instance size 32 Instance count 0 All Instances Size 0\n  Static Field name PARAMS2 type object value 1684212296\n   Ref object java.lang.Class[]#7\n  Static Field name PARAMS1 type object value 1684212280\n   Ref object java.lang.Class[]#6\n  Static Field name PARAMS0 type object value 1684212264\n   Ref object java.lang.Class[]#5\n  Static Field name scope type object value 0\n  Static Field name DEFAULT_CACHE_SIZE type int value 1\n  Static Field name AUTH_POLICY_URL type object value 0\n  Static Field name AUTH_POLICY type object value 0\n  Static Field name POLICY_URL type object value 0\n  Static Field name SECURITY_MANAGER type object value 0\n  Static Field name POLICY type object value 0\n  Static Field name X500PRINCIPAL type object value 0\n  Static Field name SELF type object value 0\n  Static Field name P11KEYSTORE type object value 0\n  Static Field name NONE type object value 0\n  Static Field name debug type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name url type object\n  Field name notUtf8 type boolean\n  Field name allowSystemProperties type boolean\n  Field name ignoreIdentityScope type boolean\n  Field name expandProperties type boolean\n  Field name constructed type boolean\n  Field name policyInfo type object\n Id 0x6ca03c08 Class java.security.Policy$UnsupportedEmptyCollection SuperClass java.security.PermissionCollection Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Field name perms type object\n  Instance Id 0x64630988 number 1 retained size 160\n   Instance Field name perms type object value 1684212120\n    Ref object java.security.Permissions#2\n   Instance Field name readOnly type boolean value false\n   References count 1\n   Field UNSUPPORTED_EMPTY_COLLECTION of Class java.security.Policy\n   Path to nearest GC root\n    Next object java.lang.Class#325\n Id 0x68139148 Class sun.misc.JavaNetAccess SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c97d698 Class java.lang.reflect.ReflectPermission SuperClass java.security.BasicPermission Instance size 24 Instance count 1 All Instances Size 24\n  Static Field name serialVersionUID type long value 7412737110241507485\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610838 number 1 retained size 24\n   Instance Field name exitVM type boolean value false\n   Instance Field name path type object value 0\n   Instance Field name wildcard type boolean value false\n   Instance Field name name type object value 0\n   References count 1\n   Field ACCESS_PERMISSION of Class java.lang.reflect.AccessibleObject\n   Path to nearest GC root\n    Next object java.lang.Class#124\n Id 0x6c94d498 Class java.lang.reflect.Member SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name DECLARED type int value 1\n  Static Field name PUBLIC type int value 0\n  Static Field name <classLoader> type object value 0\n Id 0x681336f0 Class java.lang.reflect.Member[] SuperClass java.lang.Object Instance size -1 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9ca8a0 Class sun.misc.JavaLangAccess SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c954e30 Class sun.reflect.FieldAccessor SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c951608 Class sun.reflect.MethodAccessor SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c951bb0 Class sun.reflect.ConstructorAccessor SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c955a08 Class sun.reflect.UnsafeFieldAccessorImpl SuperClass sun.reflect.FieldAccessorImpl Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name unsafe type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name isFinal type boolean\n  Field name fieldOffset type int\n  Field name field type object\n Id 0x6c955748 Class sun.reflect.FieldAccessorImpl SuperClass sun.reflect.MagicAccessorImpl Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c957a78 Class java.util.RandomAccess SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6ca07fe0 Class java.lang.Shutdown$Lock SuperClass java.lang.Object Instance size 8 Instance count 2 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64625708 number 1 retained size 8\n   References count 1\n   Field lock of Class java.lang.Shutdown\n   Path to nearest GC root\n    Next object java.lang.Class#110\n  Instance Id 0x64625710 number 2 retained size 8\n   References count 1\n   Field haltLock of Class java.lang.Shutdown\n   Path to nearest GC root\n    Next object java.lang.Class#110\n Id 0x6c956648 Class java.lang.Iterable SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c959fc0 Class java.util.AbstractCollection SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c95d6b8 Class java.lang.Appendable SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cc47958 Class sun.misc.FloatingDecimal SuperClass java.lang.Object Instance size 40 Instance count 0 All Instances Size 0\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name hexFloatPattern type object value 1684199288\n   Ref object java.util.regex.Pattern#1\n  Static Field name zero type object value 1684199208\n   Ref object char[]#260\n  Static Field name notANumber type object value 1684199184\n   Ref object char[]#259\n  Static Field name infinity type object value 1684199152\n   Ref object char[]#258\n  Static Field name n5bits type object value 1684199032\n   Ref object int[]#9\n  Static Field name long5pow type object value 1684198800\n   Ref object long[]#2\n  Static Field name small5pow type object value 1684198728\n   Ref object int[]#8\n  Static Field name singleMaxSmallTen type int value 10\n  Static Field name maxSmallTen type int value 22\n  Static Field name tiny10pow type object value 1684198672\n   Ref object double[]#3\n  Static Field name big10pow type object value 1684198616\n   Ref object double[]#2\n  Static Field name singleSmall10pow type object value 1684198560\n   Ref object float[]#1\n  Static Field name small10pow type object value 1684198360\n   Ref object double[]#1\n  Static Field name perThreadBuffer type object value 1684198344\n   Ref object sun.misc.FloatingDecimal$1#1\n  Static Field name b5p type object value 0\n  Static Field name intDecimalDigits type int value 9\n  Static Field name singleMinDecimalExponent type int value -45\n  Static Field name singleMaxDecimalExponent type int value 38\n  Static Field name singleMaxDecimalDigits type int value 7\n  Static Field name singleExpBias type int value 127\n  Static Field name singleFractHOB type int value 8388608\n  Static Field name singleExpShift type int value 23\n  Static Field name singleFractMask type int value 8388607\n  Static Field name singleExpMask type int value 2139095040\n  Static Field name singleSignMask type int value -2147483648\n  Static Field name lowbytes type long value 72057594037927935\n  Static Field name highbit type long value -9223372036854775808\n  Static Field name highbyte type long value -72057594037927936\n  Static Field name bigDecimalExponent type int value 324\n  Static Field name minDecimalExponent type int value -324\n  Static Field name maxDecimalExponent type int value 308\n  Static Field name maxDecimalDigits type int value 15\n  Static Field name minSmallBinExp type int value -21\n  Static Field name maxSmallBinExp type int value 62\n  Static Field name expOne type long value 4607182418800017408\n  Static Field name fractHOB type long value 4503599627370496\n  Static Field name expBias type int value 1023\n  Static Field name expShift type int value 52\n  Static Field name fractMask type long value 4503599627370495\n  Static Field name expMask type long value 9218868437227405312\n  Static Field name signMask type long value -9223372036854775808\n  Static Field name <classLoader> type object value 0\n  Field name roundDir type int\n  Field name fromHex type boolean\n  Field name mustSetRoundDir type boolean\n  Field name bigIntNBits type int\n  Field name bigIntExp type int\n  Field name nDigits type int\n  Field name digits type object\n  Field name decExponent type int\n  Field name isNegative type boolean\n  Field name isExceptional type boolean\n Id 0x6c960e48 Class sun.misc.AtomicLong SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cbac600 Class sun.nio.cs.Unicode SuperClass java.nio.charset.Charset Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cbb3d50 Class sun.nio.cs.ISO_8859_1 SuperClass java.nio.charset.Charset Instance size 24 Instance count 1 All Instances Size 24\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64615098 number 1 retained size 24\n   Instance Field name aliasSet type object value 0\n   Instance Field name aliases type object value 1684085872\n    Ref object java.lang.String[]#12\n   Instance Field name name type object value 0\n   References count 10\n   Field defaultCharset of Class java.nio.charset.Charset\n   Field cs of instance 0x64625090\n   Field charset of instance 0x646250a8\n   Field charset of instance 0x646250e8\n   Field charset of instance 0x64616a00\n   Field cs of instance 0x64616ba8\n   Field charset of instance 0x64616bd8\n   Element 1 of array 0x64614ab8\n   Element 1 of array 0x646150b0\n   Field cs of instance 0x646169b0\n   Path to nearest GC root\n    Next object java.lang.Class#419\n Id 0x6cbacaa0 Class sun.nio.cs.UTF_8 SuperClass sun.nio.cs.Unicode Instance size 24 Instance count 1 All Instances Size 24\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x646293a8 number 1 retained size 24\n   Instance Field name aliasSet type object value 0\n   Instance Field name aliases type object value 1684085624\n    Ref object java.lang.String[]#2\n   Instance Field name name type object value 0\n   References count 4\n   Element 1 of array 0x646293c0\n   Element 1 of array 0x64614ae8\n   Field charset of instance 0x6462a480\n   Field cs of instance 0x6462a468\n   Path to nearest GC root\n    Next object java.lang.Object[]#313\n    Next object java.lang.Class#419\n Id 0x6cbadb98 Class sun.nio.cs.UTF_8$Decoder SuperClass java.nio.charset.CharsetDecoder Instance size 40 Instance count 1 All Instances Size 40\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name <classLoader> type object value 0\n  Field name sgg type object\n  Instance Id 0x6462a480 number 1 retained size 0\n   Instance Field name sgg type object value 1684186280\n    Ref object sun.nio.cs.Surrogate$Generator#1\n   Instance Field name state type int value 3\n   Instance Field name unmappableCharacterAction type object value 1684099512\n    Ref object java.nio.charset.CodingErrorAction#2\n   Instance Field name malformedInputAction type object value 1684099512\n    Ref object java.nio.charset.CodingErrorAction#2\n   Instance Field name replacement type object value 0\n   Instance Field name maxCharsPerByte type float value 1.0\n   Instance Field name averageCharsPerByte type float value 1.0\n   Instance Field name charset type object value 1684181928\n    Ref object sun.nio.cs.UTF_8#1\n   References count 1\n   Field cd of instance 0x6462a468\n   Path to nearest GC root\n    Null\n Id 0x6c9eae50 Class java.lang.CharacterDataLatin1 SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name A_DATA type object value 0\n  Static Field name A type object value 1684174072\n   Ref object int[]#4\n  Static Field name sharpsMap type object value 1684174056\n   Ref object char[]#133\n  Static Field name <classLoader> type object value 0\n Id 0x6c965880 Class java.lang.Number SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value -8742448824652078965\n  Static Field name <classLoader> type object value 0\n Id 0x6cbb4cf8 Class sun.nio.cs.ISO_8859_1$Decoder SuperClass java.nio.charset.CharsetDecoder Instance size 40 Instance count 1 All Instances Size 40\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x646250e8 number 1 retained size 0\n   Instance Field name state type int value 2\n   Instance Field name unmappableCharacterAction type object value 1684099528\n    Ref object java.nio.charset.CodingErrorAction#3\n   Instance Field name malformedInputAction type object value 1684099528\n    Ref object java.nio.charset.CodingErrorAction#3\n   Instance Field name replacement type object value 0\n   Instance Field name maxCharsPerByte type float value 1.0\n   Instance Field name averageCharsPerByte type float value 1.0\n   Instance Field name charset type object value 1684099224\n    Ref object sun.nio.cs.ISO_8859_1#1\n   References count 1\n   Field referent of instance 0x64625110\n   Path to nearest GC root\n    Null\n Id 0x6cbb44c0 Class sun.nio.cs.ISO_8859_1$Encoder SuperClass java.nio.charset.CharsetEncoder Instance size 48 Instance count 3 All Instances Size 144\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name <classLoader> type object value 0\n  Field name sgp type object\n  Instance Id 0x64616a00 number 1 retained size 112\n   Instance Field name sgp type object value 1684105816\n    Ref object sun.nio.cs.Surrogate$Parser#1\n   Instance Field name cachedDecoder type object value 1684105792\n    Ref object java.lang.ref.WeakReference#1\n   Instance Field name state type int value 0\n   Instance Field name unmappableCharacterAction type object value 1684099512\n    Ref object java.nio.charset.CodingErrorAction#2\n   Instance Field name malformedInputAction type object value 1684099512\n    Ref object java.nio.charset.CodingErrorAction#2\n   Instance Field name replacement type object value 1684105776\n    Ref object byte[]#2\n   Instance Field name maxBytesPerChar type float value 1.0\n   Instance Field name averageBytesPerChar type float value 1.0\n   Instance Field name charset type object value 1684099224\n    Ref object sun.nio.cs.ISO_8859_1#1\n   References count 1\n   Field encoder of instance 0x646169b0\n   Path to nearest GC root\n    Next object sun.nio.cs.StreamEncoder#1\n    Next object java.io.OutputStreamWriter#1\n    Next object java.io.PrintStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616bd8 number 2 retained size 112\n   Instance Field name sgp type object value 1684106288\n    Ref object sun.nio.cs.Surrogate$Parser#2\n   Instance Field name cachedDecoder type object value 1684106264\n    Ref object java.lang.ref.WeakReference#2\n   Instance Field name state type int value 0\n   Instance Field name unmappableCharacterAction type object value 1684099512\n    Ref object java.nio.charset.CodingErrorAction#2\n   Instance Field name malformedInputAction type object value 1684099512\n    Ref object java.nio.charset.CodingErrorAction#2\n   Instance Field name replacement type object value 1684106248\n    Ref object byte[]#4\n   Instance Field name maxBytesPerChar type float value 1.0\n   Instance Field name averageBytesPerChar type float value 1.0\n   Instance Field name charset type object value 1684099224\n    Ref object sun.nio.cs.ISO_8859_1#1\n   References count 1\n   Field encoder of instance 0x64616ba8\n   Path to nearest GC root\n    Next object sun.nio.cs.StreamEncoder#2\n    Next object java.io.OutputStreamWriter#2\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n  Instance Id 0x646250a8 number 3 retained size 0\n   Instance Field name sgp type object value 1684164904\n    Ref object sun.nio.cs.Surrogate$Parser#3\n   Instance Field name cachedDecoder type object value 1684164880\n    Ref object java.lang.ref.WeakReference#3\n   Instance Field name state type int value 3\n   Instance Field name unmappableCharacterAction type object value 1684099512\n    Ref object java.nio.charset.CodingErrorAction#2\n   Instance Field name malformedInputAction type object value 1684099512\n    Ref object java.nio.charset.CodingErrorAction#2\n   Instance Field name replacement type object value 1684164824\n    Ref object byte[]#8\n   Instance Field name maxBytesPerChar type float value 1.0\n   Instance Field name averageBytesPerChar type float value 1.0\n   Instance Field name charset type object value 1684099224\n    Ref object sun.nio.cs.ISO_8859_1#1\n   References count 1\n   Field ce of instance 0x64625090\n   Path to nearest GC root\n    Null\n Id 0x6c9dd858 Class java.io.ObjectStreamClass SuperClass java.lang.Object Instance size 96 Instance count 0 All Instances Size 0\n  Static Field name reflFactory type object value 1684080984\n   Ref object sun.reflect.ReflectionFactory#1\n  Static Field name serialPersistentFields type object value 1684169568\n   Ref object java.io.ObjectStreamField[]#4\n  Static Field name serialVersionUID type long value -6120832682080437368\n  Static Field name NO_FIELDS type object value 1684169568\n   Ref object java.io.ObjectStreamField[]#4\n  Static Field name <classLoader> type object value 0\n  Field name superDesc type object\n  Field name localDesc type object\n  Field name readResolveMethod type object\n  Field name writeReplaceMethod type object\n  Field name readObjectNoDataMethod type object\n  Field name readObjectMethod type object\n  Field name writeObjectMethod type object\n  Field name cons type object\n  Field name dataLayout type object\n  Field name fieldRefl type object\n  Field name numObjFields type int\n  Field name primDataSize type int\n  Field name fields type object\n  Field name defaultSerializeEx type object\n  Field name serializeEx type object\n  Field name deserializeEx type object\n  Field name resolveEx type object\n  Field name hasBlockExternalData type boolean\n  Field name hasWriteObjectData type boolean\n  Field name externalizable type boolean\n  Field name serializable type boolean\n  Field name isEnum type boolean\n  Field name isProxy type boolean\n  Field name suid type object\n  Field name name type object\n  Field name cl type object\n Id 0x6c975f78 Class java.security.Guard SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c976f20 Class java.security.BasicPermission SuperClass java.security.Permission Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name serialVersionUID type long value 6279438298436773498\n  Static Field name <classLoader> type object value 0\n  Field name exitVM type boolean\n  Field name path type object\n  Field name wildcard type boolean\n Id 0x6ca06460 Class java.security.BasicPermissionCollection SuperClass java.security.PermissionCollection Instance size 24 Instance count 1 All Instances Size 24\n  Static Field name serialPersistentFields type object value 1684212512\n   Ref object java.io.ObjectStreamField[]#8\n  Static Field name serialVersionUID type long value 739301742472979399\n  Static Field name <classLoader> type object value 0\n  Field name permClass type object\n  Field name all_allowed type boolean\n  Field name perms type object\n  Instance Id 0x64630b98 number 1 retained size 192\n   Instance Field name permClass type object value 0\n   Instance Field name all_allowed type boolean value false\n   Instance Field name perms type object value 1684212656\n    Ref object java.util.HashMap#23\n   Instance Field name readOnly type boolean value false\n   References count 1\n   Field value of instance 0x64630c28\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#154\n    Next object java.util.HashMap$Entry[]#24\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c977fe0 Class java.util.AbstractMap SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name values type object\n  Field name keySet type object\n Id 0x6c979ce8 Class java.lang.ref.ReferenceQueue$Lock SuperClass java.lang.Object Instance size 8 Instance count 4 All Instances Size 32\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x646106b0 number 1 retained size 8\n   References count 1\n   Field lock of instance 0x64610698\n   Path to nearest GC root\n    Next object java.lang.ref.ReferenceQueue$Null#1\n    Next object java.lang.Class#344\n  Instance Id 0x646106d0 number 2 retained size 8\n   References count 1\n   Field lock of instance 0x646106b8\n   Path to nearest GC root\n    Next object java.lang.ref.ReferenceQueue$Null#2\n    Next object java.lang.Class#344\n  Instance Id 0x646106f0 number 3 retained size 8\n   References count 1\n   Field lock of instance 0x646106d8\n   Path to nearest GC root\n    Next object java.lang.ref.ReferenceQueue#1\n    Next object sun.misc.SoftCache#1\n    Next object java.lang.Class#92\n  Instance Id 0x64610a70 number 4 retained size 8\n   References count 1\n   Field lock of instance 0x64610a58\n   Path to nearest GC root\n Id 0x6c9799b8 Class java.lang.ref.ReferenceQueue$Null SuperClass java.lang.ref.ReferenceQueue Instance size 24 Instance count 2 All Instances Size 48\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610698 number 1 retained size 32\n   Instance Field name queueLength type long value 0\n   Instance Field name head type object value 0\n   Instance Field name lock type object value 1684080304\n    Ref object java.lang.ref.ReferenceQueue$Lock#1\n   References count 19\n   Field NULL of Class java.lang.ref.ReferenceQueue\n   Field queue of instance 0x6462a4b8\n   Field queue of instance 0x6462a788\n   Field queue of instance 0x6462ef30\n   Field queue of instance 0x64628430\n   Field queue of instance 0x64629320\n   Field queue of instance 0x64629980\n   Field queue of instance 0x64626880\n   Field queue of instance 0x64626ba8\n   Field queue of instance 0x64627968\n   Field queue of instance 0x64625070\n   Field queue of instance 0x64625110\n   Field queue of instance 0x64625140\n   Field queue of instance 0x64616890\n   Field queue of instance 0x64616a40\n   Field queue of instance 0x64616c18\n   Field queue of instance 0x64614f18\n   Field queue of instance 0x64615010\n   Field queue of instance 0x64615168\n   Path to nearest GC root\n    Next object java.lang.Class#344\n  Instance Id 0x646106b8 number 2 retained size 32\n   Instance Field name queueLength type long value 0\n   Instance Field name head type object value 0\n   Instance Field name lock type object value 1684080336\n    Ref object java.lang.ref.ReferenceQueue$Lock#2\n   References count 1\n   Field ENQUEUED of Class java.lang.ref.ReferenceQueue\n   Path to nearest GC root\n    Next object java.lang.Class#344\n Id 0x6c97c750 Class java.util.HashMap$Entry SuperClass java.lang.Object Instance size 24 Instance count 157 All Instances Size 3768\n  Static Field name <classLoader> type object value 0\n  Field name hash type int\n  Field name next type object\n  Field name value type object\n  Field name key type object\n  Instance Id 0x64625c70 number 1 retained size 160\n   Instance Field name hash type int value 512244622\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684167752\n    Ref object sun.misc.MetaIndex#1\n   Instance Field name key type object value 1684167616\n    Ref object java.io.File#3\n   References count 1\n   Element 14 of array 0x646259f8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625db0 number 2 retained size 168\n   Instance Field name hash type int value -1245894054\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684168072\n    Ref object sun.misc.MetaIndex#2\n   Instance Field name key type object value 1684167928\n    Ref object java.io.File#4\n   References count 1\n   Element 10 of array 0x646259f8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625f70 number 3 retained size 176\n   Instance Field name hash type int value 1167121623\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684168520\n    Ref object sun.misc.MetaIndex#3\n   Instance Field name key type object value 1684168368\n    Ref object java.io.File#5\n   References count 1\n   Element 7 of array 0x646259f8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64626120 number 4 retained size 168\n   Instance Field name hash type int value -1243838335\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684168952\n    Ref object sun.misc.MetaIndex#4\n   Instance Field name key type object value 1684168808\n    Ref object java.io.File#6\n   References count 1\n   Element 1 of array 0x646259f8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64629518 number 5 retained size 0\n   Instance Field name hash type int value 174971558\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684181672\n    Ref object java.lang.String#149\n   Instance Field name key type object value 1684182272\n    Ref object java.util.jar.Attributes$Name#18\n   References count 1\n   Field next of instance 0x646296d8\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629588 number 6 retained size 0\n   Instance Field name hash type int value -409896431\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684182320\n    Ref object java.lang.String#150\n   Instance Field name key type object value 1684182392\n    Ref object java.util.jar.Attributes$Name#19\n   References count 1\n   Element 1 of array 0x646291e0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629620 number 7 retained size 0\n   Instance Field name hash type int value 1411302058\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684182432\n    Ref object java.lang.String#151\n   Instance Field name key type object value 1684182544\n    Ref object java.util.jar.Attributes$Name#20\n   References count 1\n   Element 10 of array 0x646291e0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629688 number 8 retained size 0\n   Instance Field name hash type int value -708055107\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684182584\n    Ref object java.lang.String#152\n   Instance Field name key type object value 1684182648\n    Ref object java.util.jar.Attributes$Name#21\n   References count 1\n   Element 13 of array 0x646291e0\n   Path to nearest GC root\n    Null\n  Instance Id 0x646296d8 number 9 retained size 0\n   Instance Field name hash type int value -459890458\n   Instance Field name next type object value 1684182296\n    Ref object java.util.HashMap$Entry#5\n   Instance Field name value type object value 1684182688\n    Ref object java.lang.String#153\n   Instance Field name key type object value 1684182728\n    Ref object java.util.jar.Attributes$Name#22\n   References count 1\n   Element 6 of array 0x646291e0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629788 number 10 retained size 0\n   Instance Field name hash type int value -184289916\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684182768\n    Ref object java.lang.String#154\n   Instance Field name key type object value 1684182904\n    Ref object java.util.jar.Attributes$Name#23\n   References count 1\n   Element 4 of array 0x646291e0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629b70 number 11 retained size 24\n   Instance Field name hash type int value 1171701463\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684183552\n    Ref object sun.misc.URLClassPath$JarLoader#1\n   Instance Field name key type object value 1684169896\n    Ref object java.net.URL#1\n   References count 1\n   Field next of instance 0x64629e80\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#14\n    Next object java.util.HashMap$Entry[]#9\n    Next object java.util.HashMap#7\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629c78 number 12 retained size 24\n   Instance Field name hash type int value -1241767900\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684183944\n    Ref object sun.misc.URLClassPath$JarLoader#2\n   Instance Field name key type object value 1684175816\n    Ref object java.net.URL#2\n   References count 1\n   Element 4 of array 0x64628380\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#9\n    Next object java.util.HashMap#7\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629d78 number 13 retained size 24\n   Instance Field name hash type int value 507990287\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684184208\n    Ref object sun.misc.URLClassPath$JarLoader#3\n   Instance Field name key type object value 1684176288\n    Ref object java.net.URL#3\n   References count 1\n   Element 15 of array 0x64628380\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#9\n    Next object java.util.HashMap#7\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629e80 number 14 retained size 48\n   Instance Field name hash type int value -1244059609\n   Instance Field name next type object value 1684183920\n    Ref object java.util.HashMap$Entry#11\n   Instance Field name value type object value 1684184464\n    Ref object sun.misc.URLClassPath$JarLoader#4\n   Instance Field name key type object value 1684176784\n    Ref object java.net.URL#4\n   References count 1\n   Element 7 of array 0x64628380\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#9\n    Next object java.util.HashMap#7\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x6462a500 number 15 retained size 0\n   Instance Field name hash type int value 174971558\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684186192\n    Ref object java.lang.String#172\n   Instance Field name key type object value 1684186352\n    Ref object java.util.jar.Attributes$Name#24\n   References count 1\n   Field next of instance 0x6462a6c0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a570 number 16 retained size 0\n   Instance Field name hash type int value -409896431\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684186392\n    Ref object java.lang.String#173\n   Instance Field name key type object value 1684186464\n    Ref object java.util.jar.Attributes$Name#25\n   References count 1\n   Element 1 of array 0x6462a388\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a608 number 17 retained size 0\n   Instance Field name hash type int value 1411302058\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684186504\n    Ref object java.lang.String#174\n   Instance Field name key type object value 1684186616\n    Ref object java.util.jar.Attributes$Name#26\n   References count 1\n   Element 10 of array 0x6462a388\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a670 number 18 retained size 0\n   Instance Field name hash type int value -708055107\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684186656\n    Ref object java.lang.String#175\n   Instance Field name key type object value 1684186720\n    Ref object java.util.jar.Attributes$Name#27\n   References count 1\n   Element 13 of array 0x6462a388\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a6c0 number 19 retained size 0\n   Instance Field name hash type int value -459890458\n   Instance Field name next type object value 1684186368\n    Ref object java.util.HashMap$Entry#15\n   Instance Field name value type object value 1684186760\n    Ref object java.lang.String#176\n   Instance Field name key type object value 1684186800\n    Ref object java.util.jar.Attributes$Name#28\n   References count 1\n   Element 6 of array 0x6462a388\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a770 number 20 retained size 0\n   Instance Field name hash type int value -184289916\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684186840\n    Ref object java.lang.String#177\n   Instance Field name key type object value 1684186976\n    Ref object java.util.jar.Attributes$Name#29\n   References count 1\n   Element 4 of array 0x6462a388\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a7a8 number 21 retained size 24\n   Instance Field name hash type int value 788385046\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684184728\n    Ref object sun.misc.URLClassPath$JarLoader#5\n   Instance Field name key type object value 1684178408\n    Ref object java.net.URL#5\n   References count 1\n   Element 6 of array 0x64628a18\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#13\n    Next object java.util.HashMap#11\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x6462a9b0 number 22 retained size 96\n   Instance Field name hash type int value -1596453874\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684187520\n    Ref object java.lang.Package#1\n   Instance Field name key type object value 1684187072\n    Ref object java.lang.String#178\n   References count 1\n   Element 14 of array 0x646287c8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#11\n    Next object java.util.HashMap#9\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x6462aa80 number 23 retained size 120\n   Instance Field name hash type int value -47514415\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684187656\n    Ref object java.security.Provider$EngineDescription#1\n   Instance Field name key type object value 1684187752\n    Ref object java.lang.String#179\n   References count 1\n   Element 81 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462aa98 number 24 retained size 24\n   Instance Field name hash type int value -1531600114\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684187656\n    Ref object java.security.Provider$EngineDescription#1\n   Instance Field name key type object value 0\n   References count 1\n   Element 14 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ab18 number 25 retained size 128\n   Instance Field name hash type int value 2127450744\n   Instance Field name next type object value 1684190112\n    Ref object java.util.HashMap$Entry#58\n   Instance Field name value type object value 1684187824\n    Ref object java.security.Provider$EngineDescription#2\n   Instance Field name key type object value 1684187904\n    Ref object java.lang.String#180\n   References count 1\n   Element 120 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ab30 number 26 retained size 72\n   Instance Field name hash type int value 954282674\n   Instance Field name next type object value 1684190536\n    Ref object java.util.HashMap$Entry#64\n   Instance Field name value type object value 1684187824\n    Ref object java.security.Provider$EngineDescription#2\n   Instance Field name key type object value 0\n   References count 1\n   Element 50 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ab98 number 27 retained size 80\n   Instance Field name hash type int value 1976075013\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684187976\n    Ref object java.security.Provider$EngineDescription#3\n   Instance Field name key type object value 1684188032\n    Ref object java.lang.String#181\n   References count 1\n   Element 5 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462abb0 number 28 retained size 24\n   Instance Field name hash type int value 1212684417\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684187976\n    Ref object java.security.Provider$EngineDescription#3\n   Instance Field name key type object value 0\n   References count 1\n   Element 1 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ac28 number 29 retained size 96\n   Instance Field name hash type int value -1493094289\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684188104\n    Ref object java.security.Provider$EngineDescription#4\n   Instance Field name key type object value 1684188176\n    Ref object java.lang.String#182\n   References count 1\n   Element 111 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ac40 number 30 retained size 24\n   Instance Field name hash type int value 589730457\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684188104\n    Ref object java.security.Provider$EngineDescription#4\n   Instance Field name key type object value 0\n   References count 1\n   Element 25 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462aca8 number 31 retained size 80\n   Instance Field name hash type int value 522975637\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684188248\n    Ref object java.security.Provider$EngineDescription#5\n   Instance Field name key type object value 1684188304\n    Ref object java.lang.String#183\n   References count 1\n   Element 21 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462acc0 number 32 retained size 24\n   Instance Field name hash type int value 593438459\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684188248\n    Ref object java.security.Provider$EngineDescription#5\n   Instance Field name key type object value 0\n   References count 1\n   Element 123 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ad30 number 33 retained size 88\n   Instance Field name hash type int value -1256295623\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684188376\n    Ref object java.security.Provider$EngineDescription#6\n   Instance Field name key type object value 1684188440\n    Ref object java.lang.String#184\n   References count 1\n   Element 57 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ad48 number 34 retained size 24\n   Instance Field name hash type int value -1302057372\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684188376\n    Ref object java.security.Provider$EngineDescription#6\n   Instance Field name key type object value 0\n   References count 1\n   Element 100 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462adb8 number 35 retained size 88\n   Instance Field name hash type int value 1379357508\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684188512\n    Ref object java.security.Provider$EngineDescription#7\n   Instance Field name key type object value 1684188576\n    Ref object java.lang.String#185\n   References count 1\n   Field next of instance 0x6462af70\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#42\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462add0 number 36 retained size 24\n   Instance Field name hash type int value 704007629\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684188512\n    Ref object java.security.Provider$EngineDescription#7\n   Instance Field name key type object value 0\n   References count 1\n   Element 77 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ae38 number 37 retained size 80\n   Instance Field name hash type int value 1014922782\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684188648\n    Ref object java.security.Provider$EngineDescription#8\n   Instance Field name key type object value 1684188704\n    Ref object java.lang.String#186\n   References count 1\n   Field next of instance 0x6462aec8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#39\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ae50 number 38 retained size 24\n   Instance Field name hash type int value -1115930418\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684188648\n    Ref object java.security.Provider$EngineDescription#8\n   Instance Field name key type object value 0\n   References count 1\n   Element 78 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462aec8 number 39 retained size 176\n   Instance Field name hash type int value -334141410\n   Instance Field name next type object value 1684188728\n    Ref object java.util.HashMap$Entry#37\n   Instance Field name value type object value 1684188776\n    Ref object java.security.Provider$EngineDescription#9\n   Instance Field name key type object value 1684188848\n    Ref object java.lang.String#187\n   References count 1\n   Element 30 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462aee0 number 40 retained size 112\n   Instance Field name hash type int value -1091490978\n   Instance Field name next type object value 1684189808\n    Ref object java.util.HashMap$Entry#53\n   Instance Field name value type object value 1684188776\n    Ref object java.security.Provider$EngineDescription#9\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462af58\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#41\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462af58 number 41 retained size 208\n   Instance Field name hash type int value -1190362402\n   Instance Field name next type object value 1684188896\n    Ref object java.util.HashMap$Entry#40\n   Instance Field name value type object value 1684188920\n    Ref object java.security.Provider$EngineDescription#10\n   Instance Field name key type object value 1684188992\n    Ref object java.lang.String#188\n   References count 1\n   Element 94 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462af70 number 42 retained size 112\n   Instance Field name hash type int value 1025484868\n   Instance Field name next type object value 1684188600\n    Ref object java.util.HashMap$Entry#35\n   Instance Field name value type object value 1684188920\n    Ref object java.security.Provider$EngineDescription#10\n   Instance Field name key type object value 0\n   References count 1\n   Element 68 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462afe8 number 43 retained size 120\n   Instance Field name hash type int value 1204910644\n   Instance Field name next type object value 1684189696\n    Ref object java.util.HashMap$Entry#52\n   Instance Field name value type object value 1684189064\n    Ref object java.security.Provider$EngineDescription#11\n   Instance Field name key type object value 1684189136\n    Ref object java.lang.String#189\n   References count 1\n   Element 52 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b000 number 44 retained size 24\n   Instance Field name hash type int value -640715466\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189064\n    Ref object java.security.Provider$EngineDescription#11\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462b980\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#72\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b068 number 45 retained size 80\n   Instance Field name hash type int value -1495993696\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189208\n    Ref object java.security.Provider$EngineDescription#12\n   Instance Field name key type object value 1684189264\n    Ref object java.lang.String#190\n   References count 1\n   Element 32 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b080 number 46 retained size 24\n   Instance Field name hash type int value 561267817\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189208\n    Ref object java.security.Provider$EngineDescription#12\n   Instance Field name key type object value 0\n   References count 1\n   Element 105 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b0e0 number 47 retained size 168\n   Instance Field name hash type int value -1521299334\n   Instance Field name next type object value 1684190232\n    Ref object java.util.HashMap$Entry#59\n   Instance Field name value type object value 1684189336\n    Ref object java.security.Provider$EngineDescription#13\n   Instance Field name key type object value 1684189384\n    Ref object java.lang.String#191\n   References count 1\n   Element 122 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b0f8 number 48 retained size 24\n   Instance Field name hash type int value 2132970248\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189336\n    Ref object java.security.Provider$EngineDescription#13\n   Instance Field name key type object value 0\n   References count 1\n   Element 8 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b170 number 49 retained size 96\n   Instance Field name hash type int value 2105114634\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189456\n    Ref object java.security.Provider$EngineDescription#14\n   Instance Field name key type object value 1684189528\n    Ref object java.lang.String#192\n   References count 1\n   Element 10 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b188 number 50 retained size 24\n   Instance Field name hash type int value 1511037906\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189456\n    Ref object java.security.Provider$EngineDescription#14\n   Instance Field name key type object value 0\n   References count 1\n   Element 82 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b1e8 number 51 retained size 72\n   Instance Field name hash type int value 113738\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189600\n    Ref object java.security.Provider$EngineDescription#15\n   Instance Field name key type object value 1684189648\n    Ref object java.lang.String#193\n   References count 1\n   Element 74 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b200 number 52 retained size 24\n   Instance Field name hash type int value 81332\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189600\n    Ref object java.security.Provider$EngineDescription#15\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462afe8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#43\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b270 number 53 retained size 88\n   Instance Field name hash type int value -1384537762\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189720\n    Ref object java.security.Provider$EngineDescription#16\n   Instance Field name key type object value 1684189784\n    Ref object java.lang.String#194\n   References count 1\n   Field next of instance 0x6462aee0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#40\n    Next object java.util.HashMap$Entry#41\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b288 number 54 retained size 24\n   Instance Field name hash type int value 631499559\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189720\n    Ref object java.security.Provider$EngineDescription#16\n   Instance Field name key type object value 0\n   References count 1\n   Element 39 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b2f8 number 55 retained size 88\n   Instance Field name hash type int value 2053257904\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189856\n    Ref object java.security.Provider$EngineDescription#17\n   Instance Field name key type object value 1684189920\n    Ref object java.lang.String#195\n   References count 1\n   Element 48 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b310 number 56 retained size 24\n   Instance Field name hash type int value -258757260\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189856\n    Ref object java.security.Provider$EngineDescription#17\n   Instance Field name key type object value 0\n   References count 1\n   Element 116 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b388 number 57 retained size 96\n   Instance Field name hash type int value 1307608446\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189992\n    Ref object java.security.Provider$EngineDescription#18\n   Instance Field name key type object value 1684190064\n    Ref object java.lang.String#196\n   References count 1\n   Element 126 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b3a0 number 58 retained size 24\n   Instance Field name hash type int value -13173896\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684189992\n    Ref object java.security.Provider$EngineDescription#18\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462ab18\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#25\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b418 number 59 retained size 96\n   Instance Field name hash type int value 1068170234\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684190136\n    Ref object java.security.Provider$EngineDescription#19\n   Instance Field name key type object value 1684190208\n    Ref object java.lang.String#197\n   References count 1\n   Field next of instance 0x6462b0e0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#47\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b430 number 60 retained size 24\n   Instance Field name hash type int value 1244592505\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684190136\n    Ref object java.security.Provider$EngineDescription#19\n   Instance Field name key type object value 0\n   References count 1\n   Element 121 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b498 number 61 retained size 80\n   Instance Field name hash type int value 1703310079\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684190280\n    Ref object java.security.Provider$EngineDescription#20\n   Instance Field name key type object value 1684190336\n    Ref object java.lang.String#198\n   References count 1\n   Element 127 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b4b0 number 62 retained size 24\n   Instance Field name hash type int value -1304494229\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684190280\n    Ref object java.security.Provider$EngineDescription#20\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462ba08\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#74\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b530 number 63 retained size 104\n   Instance Field name hash type int value -1140941349\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684190408\n    Ref object java.security.Provider$EngineDescription#21\n   Instance Field name key type object value 1684190488\n    Ref object java.lang.String#199\n   References count 1\n   Element 91 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b548 number 64 retained size 48\n   Instance Field name hash type int value 565950770\n   Instance Field name next type object value 1684190680\n    Ref object java.util.HashMap$Entry#66\n   Instance Field name value type object value 1684190408\n    Ref object java.security.Provider$EngineDescription#21\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462ab30\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#26\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b5c0 number 65 retained size 96\n   Instance Field name hash type int value 1210028460\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684190560\n    Ref object java.security.Provider$EngineDescription#22\n   Instance Field name key type object value 1684190632\n    Ref object java.lang.String#200\n   References count 1\n   Field next of instance 0x6462ba88\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#75\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b5d8 number 66 retained size 24\n   Instance Field name hash type int value -1709962830\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684190560\n    Ref object java.security.Provider$EngineDescription#22\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462b548\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#64\n    Next object java.util.HashMap$Entry#26\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b650 number 67 retained size 96\n   Instance Field name hash type int value -589335683\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684190704\n    Ref object java.security.Provider$EngineDescription#23\n   Instance Field name key type object value 1684190776\n    Ref object java.lang.String#201\n   References count 1\n   Element 125 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b668 number 68 retained size 24\n   Instance Field name hash type int value 1248362998\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684190704\n    Ref object java.security.Provider$EngineDescription#23\n   Instance Field name key type object value 0\n   References count 1\n   Element 118 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b6e0 number 69 retained size 96\n   Instance Field name hash type int value -8503860\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684190848\n    Ref object java.security.Provider$EngineDescription#24\n   Instance Field name key type object value 1684190920\n    Ref object java.lang.String#202\n   References count 1\n   Element 76 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b6f8 number 70 retained size 24\n   Instance Field name hash type int value 1762444141\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684190848\n    Ref object java.security.Provider$EngineDescription#24\n   Instance Field name key type object value 0\n   References count 1\n   Element 109 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b758 number 71 retained size 72\n   Instance Field name hash type int value -927128646\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684190992\n    Ref object java.security.Provider$EngineDescription#25\n   Instance Field name key type object value 1684191040\n    Ref object java.lang.String#203\n   References count 1\n   Element 58 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b980 number 72 retained size 48\n   Instance Field name hash type int value -2027264202\n   Instance Field name next type object value 1684189184\n    Ref object java.util.HashMap$Entry#44\n   Instance Field name value type object value 1684190992\n    Ref object java.security.Provider$EngineDescription#25\n   Instance Field name key type object value 0\n   References count 1\n   Element 54 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b9f0 number 73 retained size 88\n   Instance Field name hash type int value 1960930428\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684191640\n    Ref object java.security.Provider$EngineDescription#26\n   Instance Field name key type object value 1684191704\n    Ref object java.lang.String#204\n   References count 1\n   Element 124 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ba08 number 74 retained size 48\n   Instance Field name hash type int value -1448035605\n   Instance Field name next type object value 1684190384\n    Ref object java.util.HashMap$Entry#62\n   Instance Field name value type object value 1684191640\n    Ref object java.security.Provider$EngineDescription#26\n   Instance Field name key type object value 0\n   References count 1\n   Element 107 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ba88 number 75 retained size 200\n   Instance Field name hash type int value 1910678700\n   Instance Field name next type object value 1684190656\n    Ref object java.util.HashMap$Entry#65\n   Instance Field name value type object value 1684191776\n    Ref object java.security.Provider$EngineDescription#27\n   Instance Field name key type object value 1684191856\n    Ref object java.lang.String#205\n   References count 1\n   Element 44 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462baa0 number 76 retained size 24\n   Instance Field name hash type int value 1318257948\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684191776\n    Ref object java.security.Provider$EngineDescription#27\n   Instance Field name key type object value 0\n   References count 1\n   Element 28 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bb10 number 77 retained size 88\n   Instance Field name hash type int value 171237486\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684191928\n    Ref object java.security.Provider$EngineDescription#28\n   Instance Field name key type object value 1684191992\n    Ref object java.lang.String#206\n   References count 1\n   Element 110 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bb28 number 78 retained size 24\n   Instance Field name hash type int value -1660499546\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684191928\n    Ref object java.security.Provider$EngineDescription#28\n   Instance Field name key type object value 0\n   References count 1\n   Element 38 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bba0 number 79 retained size 96\n   Instance Field name hash type int value -1131708603\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684192064\n    Ref object java.security.Provider$EngineDescription#29\n   Instance Field name key type object value 1684192136\n    Ref object java.lang.String#207\n   References count 1\n   Element 69 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bbb8 number 80 retained size 24\n   Instance Field name hash type int value -398761533\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684192064\n    Ref object java.security.Provider$EngineDescription#29\n   Instance Field name key type object value 0\n   References count 1\n   Element 67 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bc30 number 81 retained size 96\n   Instance Field name hash type int value 461982143\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684192208\n    Ref object java.security.Provider$EngineDescription#30\n   Instance Field name key type object value 1684192280\n    Ref object java.lang.String#208\n   References count 1\n   Element 63 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bc48 number 82 retained size 24\n   Instance Field name hash type int value 1165062067\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684192208\n    Ref object java.security.Provider$EngineDescription#30\n   Instance Field name key type object value 0\n   References count 1\n   Element 51 of array 0x6462b770\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462db28 number 83 retained size 40\n   Instance Field name hash type int value 2066\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200216\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#1\n   Instance Field name key type object value 0\n   References count 1\n   Element 18 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462db50 number 84 retained size 40\n   Instance Field name hash type int value 2336\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200256\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#2\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462de70\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#104\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462db78 number 85 retained size 40\n   Instance Field name hash type int value 2345\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200296\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#3\n   Instance Field name key type object value 0\n   References count 1\n   Element 41 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dba0 number 86 retained size 40\n   Instance Field name hash type int value 2337\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200336\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#4\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462de20\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#102\n    Next object java.util.HashMap$Entry#144\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dbc8 number 87 retained size 40\n   Instance Field name hash type int value 2344\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200376\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#5\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462e818\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#148\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dbf0 number 88 retained size 40\n   Instance Field name hash type int value 2346\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200416\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#6\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462dec0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#106\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dc18 number 89 retained size 40\n   Instance Field name hash type int value 2382\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200456\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#7\n   Instance Field name key type object value 0\n   References count 1\n   Element 78 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dc40 number 90 retained size 40\n   Instance Field name hash type int value 2352\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200496\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#8\n   Instance Field name key type object value 0\n   References count 1\n   Element 48 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dc68 number 91 retained size 40\n   Instance Field name hash type int value 2366\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200536\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#9\n   Instance Field name key type object value 0\n   References count 1\n   Element 62 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dc90 number 92 retained size 80\n   Instance Field name hash type int value 2392\n   Instance Field name next type object value 1684202064\n    Ref object java.util.HashMap$Entry#129\n   Instance Field name value type object value 1684200576\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#10\n   Instance Field name key type object value 0\n   References count 1\n   Element 88 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dcb8 number 93 retained size 40\n   Instance Field name hash type int value 2384\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200616\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#11\n   Instance Field name key type object value 0\n   References count 1\n   Element 80 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dce0 number 94 retained size 40\n   Instance Field name hash type int value 2412\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200656\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#12\n   Instance Field name key type object value 0\n   References count 1\n   Element 108 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dd08 number 95 retained size 40\n   Instance Field name hash type int value 3066\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200696\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#13\n   Instance Field name key type object value 0\n   References count 1\n   Element 122 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dd30 number 96 retained size 40\n   Instance Field name hash type int value 3057\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200736\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#14\n   Instance Field name key type object value 0\n   References count 1\n   Element 113 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dd58 number 97 retained size 40\n   Instance Field name hash type int value 3061\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200776\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#15\n   Instance Field name key type object value 0\n   References count 1\n   Element 117 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dd80 number 98 retained size 80\n   Instance Field name hash type int value 2073\n   Instance Field name next type object value 1684202024\n    Ref object java.util.HashMap$Entry#128\n   Instance Field name value type object value 1684200816\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#16\n   Instance Field name key type object value 0\n   References count 1\n   Element 25 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dda8 number 99 retained size 40\n   Instance Field name hash type int value 2074\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200856\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#17\n   Instance Field name key type object value 0\n   References count 1\n   Element 26 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462ddd0 number 100 retained size 40\n   Instance Field name hash type int value 2069\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200896\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#18\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462de48\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#103\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462ddf8 number 101 retained size 40\n   Instance Field name hash type int value 2056\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684200936\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#19\n   Instance Field name key type object value 0\n   References count 1\n   Element 8 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462de20 number 102 retained size 80\n   Instance Field name hash type int value 2721\n   Instance Field name next type object value 1684200352\n    Ref object java.util.HashMap$Entry#86\n   Instance Field name value type object value 1684200976\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#20\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462e738\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#144\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462de48 number 103 retained size 80\n   Instance Field name hash type int value 2709\n   Instance Field name next type object value 1684200912\n    Ref object java.util.HashMap$Entry#100\n   Instance Field name value type object value 1684201016\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#21\n   Instance Field name key type object value 0\n   References count 1\n   Element 21 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462de70 number 104 retained size 80\n   Instance Field name hash type int value 2720\n   Instance Field name next type object value 1684200272\n    Ref object java.util.HashMap$Entry#84\n   Instance Field name value type object value 1684201056\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#22\n   Instance Field name key type object value 0\n   References count 1\n   Element 32 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462de98 number 105 retained size 40\n   Instance Field name hash type int value 2726\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201096\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#23\n   Instance Field name key type object value 0\n   References count 1\n   Element 38 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dec0 number 106 retained size 80\n   Instance Field name hash type int value 2730\n   Instance Field name next type object value 1684200432\n    Ref object java.util.HashMap$Entry#88\n   Instance Field name value type object value 1684201136\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#24\n   Instance Field name key type object value 0\n   References count 1\n   Element 42 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dee8 number 107 retained size 80\n   Instance Field name hash type int value 2761\n   Instance Field name next type object value 1684201472\n    Ref object java.util.HashMap$Entry#114\n   Instance Field name value type object value 1684201176\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#25\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462e550\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#135\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462df10 number 108 retained size 40\n   Instance Field name hash type int value 2755\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201216\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#26\n   Instance Field name key type object value 0\n   References count 1\n   Element 67 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462df38 number 109 retained size 40\n   Instance Field name hash type int value 2763\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201256\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#27\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462e7a8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#146\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462df60 number 110 retained size 40\n   Instance Field name hash type int value 2767\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201296\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#28\n   Instance Field name key type object value 0\n   References count 1\n   Element 79 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462df88 number 111 retained size 40\n   Instance Field name hash type int value 2732\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201336\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#29\n   Instance Field name key type object value 0\n   References count 1\n   Element 44 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dfb0 number 112 retained size 40\n   Instance Field name hash type int value 2723\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201376\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#30\n   Instance Field name key type object value 0\n   References count 1\n   Element 35 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462dfd8 number 113 retained size 40\n   Instance Field name hash type int value 72\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201416\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#31\n   Instance Field name key type object value 0\n   References count 1\n   Element 72 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e000 number 114 retained size 40\n   Instance Field name hash type int value 73\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201456\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#32\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462dee8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#107\n    Next object java.util.HashMap$Entry#135\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e028 number 115 retained size 40\n   Instance Field name hash type int value 74\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201496\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#33\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462e500\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#133\n    Next object java.util.HashMap$Entry#147\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e050 number 116 retained size 40\n   Instance Field name hash type int value 95\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201536\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#34\n   Instance Field name key type object value 0\n   References count 1\n   Element 95 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e078 number 117 retained size 40\n   Instance Field name hash type int value 71\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201576\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#35\n   Instance Field name key type object value 0\n   References count 1\n   Element 71 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e0a0 number 118 retained size 40\n   Instance Field name hash type int value 85\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201616\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#36\n   Instance Field name key type object value 0\n   References count 1\n   Element 85 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e0c8 number 119 retained size 40\n   Instance Field name hash type int value 86\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201656\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#37\n   Instance Field name key type object value 0\n   References count 1\n   Element 86 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e0f0 number 120 retained size 120\n   Instance Field name hash type int value 2546\n   Instance Field name next type object value 1684201864\n    Ref object java.util.HashMap$Entry#124\n   Instance Field name value type object value 1684201696\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#38\n   Instance Field name key type object value 0\n   References count 1\n   Element 114 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e118 number 121 retained size 40\n   Instance Field name hash type int value 2557\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201736\n    Ref object java.util.regex.Pattern$CharPropertyNames$1#39\n   Instance Field name key type object value 0\n   References count 1\n   Element 125 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e140 number 122 retained size 40\n   Instance Field name hash type int value 2529\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201776\n    Ref object java.util.regex.Pattern$CharPropertyNames$2#1\n   Instance Field name key type object value 0\n   References count 1\n   Element 97 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e160 number 123 retained size 32\n   Instance Field name hash type int value 93406\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201816\n    Ref object java.util.regex.Pattern$CharPropertyNames$5#1\n   Instance Field name key type object value 0\n   References count 1\n   Element 94 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e188 number 124 retained size 80\n   Instance Field name hash type int value 59134322\n   Instance Field name next type object value 1684201904\n    Ref object java.util.HashMap$Entry#125\n   Instance Field name value type object value 1684201848\n    Ref object java.util.regex.Pattern$CharPropertyNames$2#2\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462e0f0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#120\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e1b0 number 125 retained size 40\n   Instance Field name hash type int value 66937458\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201888\n    Ref object java.util.regex.Pattern$CharPropertyNames$3#1\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462e188\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#124\n    Next object java.util.HashMap$Entry#120\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e1d8 number 126 retained size 40\n   Instance Field name hash type int value 66920258\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201928\n    Ref object java.util.regex.Pattern$CharPropertyNames$3#2\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462e658\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#140\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e200 number 127 retained size 40\n   Instance Field name hash type int value 65961151\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684201968\n    Ref object java.util.regex.Pattern$CharPropertyNames$3#3\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462e850\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#149\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e228 number 128 retained size 40\n   Instance Field name hash type int value 64630169\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684202008\n    Ref object java.util.regex.Pattern$CharPropertyNames$3#4\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462dd80\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#98\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e250 number 129 retained size 40\n   Instance Field name hash type int value 64394200\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684202048\n    Ref object java.util.regex.Pattern$CharPropertyNames$2#3\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462dc90\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#92\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e278 number 130 retained size 40\n   Instance Field name hash type int value 72643224\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684202088\n    Ref object java.util.regex.Pattern$CharPropertyNames$3#5\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462e8f8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#152\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e2a0 number 131 retained size 40\n   Instance Field name hash type int value 70094244\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684202128\n    Ref object java.util.regex.Pattern$CharPropertyNames$2#4\n   Instance Field name key type object value 0\n   References count 1\n   Element 36 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e4d8 number 132 retained size 40\n   Instance Field name hash type int value 81558190\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684202696\n    Ref object java.util.regex.Pattern$CharPropertyNames$2#5\n   Instance Field name key type object value 0\n   References count 1\n   Element 46 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e500 number 133 retained size 80\n   Instance Field name hash type int value 81699786\n   Instance Field name next type object value 1684201512\n    Ref object java.util.HashMap$Entry#115\n   Instance Field name value type object value 1684202736\n    Ref object java.util.regex.Pattern$CharPropertyNames$3#6\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462e7e0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#147\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e528 number 134 retained size 40\n   Instance Field name hash type int value 75736223\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684202776\n    Ref object java.util.regex.Pattern$CharPropertyNames$3#7\n   Instance Field name key type object value 0\n   References count 1\n   Element 31 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e550 number 135 retained size 120\n   Instance Field name hash type int value 77971657\n   Instance Field name next type object value 1684201192\n    Ref object java.util.HashMap$Entry#107\n   Instance Field name value type object value 1684202816\n    Ref object java.util.regex.Pattern$CharPropertyNames$2#6\n   Instance Field name key type object value 0\n   References count 1\n   Element 73 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e578 number 136 retained size 40\n   Instance Field name hash type int value -1836748196\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684202856\n    Ref object java.util.regex.Pattern$CharPropertyNames$3#8\n   Instance Field name key type object value 0\n   References count 1\n   Element 92 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e5b0 number 137 retained size 56\n   Instance Field name hash type int value 897666737\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684202912\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#1\n   Instance Field name key type object value 0\n   References count 1\n   Field next of instance 0x6462e8c0\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry#151\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e5e8 number 138 retained size 56\n   Instance Field name hash type int value 1685054918\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684202968\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#2\n   Instance Field name key type object value 0\n   References count 1\n   Element 70 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e620 number 139 retained size 56\n   Instance Field name hash type int value -653061114\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684203024\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#3\n   Instance Field name key type object value 0\n   References count 1\n   Element 6 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e658 number 140 retained size 96\n   Instance Field name hash type int value -1049933374\n   Instance Field name next type object value 1684201944\n    Ref object java.util.HashMap$Entry#126\n   Instance Field name value type object value 1684203080\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#4\n   Instance Field name key type object value 0\n   References count 1\n   Element 66 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e690 number 141 retained size 56\n   Instance Field name hash type int value -1569621490\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684203136\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#5\n   Instance Field name key type object value 0\n   References count 1\n   Element 14 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e6c8 number 142 retained size 56\n   Instance Field name hash type int value -976969340\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684203192\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#6\n   Instance Field name key type object value 0\n   References count 1\n   Element 4 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e700 number 143 retained size 56\n   Instance Field name hash type int value -1330811800\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684203248\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#7\n   Instance Field name key type object value 0\n   References count 1\n   Element 104 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e738 number 144 retained size 136\n   Instance Field name hash type int value 407705249\n   Instance Field name next type object value 1684200992\n    Ref object java.util.HashMap$Entry#102\n   Instance Field name value type object value 1684203304\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#8\n   Instance Field name key type object value 0\n   References count 1\n   Element 33 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e770 number 145 retained size 56\n   Instance Field name hash type int value 1943545913\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684203360\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#9\n   Instance Field name key type object value 0\n   References count 1\n   Element 57 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e7a8 number 146 retained size 96\n   Instance Field name hash type int value -1311316661\n   Instance Field name next type object value 1684201272\n    Ref object java.util.HashMap$Entry#109\n   Instance Field name value type object value 1684203416\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#10\n   Instance Field name key type object value 0\n   References count 1\n   Element 75 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e7e0 number 147 retained size 136\n   Instance Field name hash type int value -344489142\n   Instance Field name next type object value 1684202752\n    Ref object java.util.HashMap$Entry#133\n   Instance Field name value type object value 1684203472\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#11\n   Instance Field name key type object value 0\n   References count 1\n   Element 74 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e818 number 148 retained size 96\n   Instance Field name hash type int value 400375336\n   Instance Field name next type object value 1684200392\n    Ref object java.util.HashMap$Entry#87\n   Instance Field name value type object value 1684203528\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#12\n   Instance Field name key type object value 0\n   References count 1\n   Element 40 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e850 number 149 retained size 96\n   Instance Field name hash type int value 497122623\n   Instance Field name next type object value 1684201984\n    Ref object java.util.HashMap$Entry#127\n   Instance Field name value type object value 1684203584\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#13\n   Instance Field name key type object value 0\n   References count 1\n   Element 63 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e888 number 150 retained size 56\n   Instance Field name hash type int value 1705867072\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684203640\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#14\n   Instance Field name key type object value 0\n   References count 1\n   Element 64 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e8c0 number 151 retained size 112\n   Instance Field name hash type int value 1158455857\n   Instance Field name next type object value 1684202928\n    Ref object java.util.HashMap$Entry#137\n   Instance Field name value type object value 1684203696\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#15\n   Instance Field name key type object value 0\n   References count 1\n   Element 49 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462e8f8 number 152 retained size 96\n   Instance Field name hash type int value 500268440\n   Instance Field name next type object value 1684202104\n    Ref object java.util.HashMap$Entry#130\n   Instance Field name value type object value 1684203752\n    Ref object java.util.regex.Pattern$CharPropertyNames$4#16\n   Instance Field name key type object value 0\n   References count 1\n   Element 24 of array 0x6462e2b8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#22\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x64630af0 number 153 retained size 224\n   Instance Field name hash type int value 4044908\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684212368\n    Ref object java.io.FilePermissionCollection#1\n   Instance Field name key type object value 0\n   References count 1\n   Element 12 of array 0x64630868\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#24\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64630c28 number 154 retained size 216\n   Instance Field name hash type int value 1583289\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684212632\n    Ref object java.security.BasicPermissionCollection#1\n   Instance Field name key type object value 0\n   References count 1\n   Element 9 of array 0x64630868\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#24\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64630c40 number 155 retained size 48\n   Instance Field name hash type int value -2006458019\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684212488\n    Ref object java.lang.RuntimePermission#3\n   Instance Field name key type object value 0\n   References count 1\n   Element 13 of array 0x64630bd8\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#26\n    Next object java.util.HashMap#23\n    Next object java.security.BasicPermissionCollection#1\n    Next object java.util.HashMap$Entry#154\n    Next object java.util.HashMap$Entry[]#24\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64630c88 number 156 retained size 24\n   Instance Field name hash type int value 788385046\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684212824\n    Ref object java.security.ProtectionDomain#1\n   Instance Field name key type object value 1684211632\n    Ref object java.security.CodeSource#1\n   References count 1\n   Element 6 of array 0x64628890\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64630ce0 number 157 retained size 24\n   Instance Field name hash type int value 10901398\n   Instance Field name next type object value 0\n   Instance Field name value type object value 1684177016\n    Ref object java.lang.Object#9\n   Instance Field name key type object value 1684212824\n    Ref object java.security.ProtectionDomain#1\n   References count 1\n   Element 6 of array 0x64628750\n   Path to nearest GC root\n    Next object java.util.HashMap$Entry[]#10\n    Next object java.util.HashMap#8\n    Next object java.util.HashSet#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x681318b8 Class java.util.HashMap$Entry[] SuperClass java.lang.Object Instance size -1 Instance count 26 All Instances Size 3488\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610740 number 1 retained size 80\n   References count 1\n   Field table of instance 0x646106f8\n   Path to nearest GC root\n    Next object java.util.HashMap#1\n    Next object sun.misc.SoftCache#1\n    Next object java.lang.Class#92\n  Instance Id 0x64614d28 number 2 retained size 80\n   References count 1\n   Field table of instance 0x64614d00\n   Path to nearest GC root\n    Next object java.util.HashMap#2\n    Next object java.util.Collections$SynchronizedMap#1\n    Next object java.lang.Class#189\n  Instance Id 0x64616d20 number 3 retained size 80\n   References count 1\n   Field table of instance 0x64616ce8\n   Path to nearest GC root\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64616df0 number 4 retained size 80\n   References count 1\n   Field table of instance 0x64616db8\n   Path to nearest GC root\n    Next object java.io.ExpiringCache$1#2\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x646259f8 number 5 retained size 752\n   References count 1\n   Field table of instance 0x646259d0\n   Path to nearest GC root\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x646280b8 number 6 retained size 80\n   References count 1\n   Field table of instance 0x64628090\n   Path to nearest GC root\n    Next object java.util.HashMap#4\n    Next object java.util.HashSet#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628130 number 7 retained size 80\n   References count 1\n   Field table of instance 0x64628108\n   Path to nearest GC root\n    Next object java.util.HashMap#5\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646281f8 number 8 retained size 80\n   References count 1\n   Field table of instance 0x646281d0\n   Path to nearest GC root\n    Next object java.util.HashMap#6\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628380 number 9 retained size 176\n   References count 1\n   Field table of instance 0x64628358\n   Path to nearest GC root\n    Next object java.util.HashMap#7\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628750 number 10 retained size 104\n   References count 1\n   Field table of instance 0x64628728\n   Path to nearest GC root\n    Next object java.util.HashMap#8\n    Next object java.util.HashSet#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646287c8 number 11 retained size 176\n   References count 1\n   Field table of instance 0x646287a0\n   Path to nearest GC root\n    Next object java.util.HashMap#9\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628890 number 12 retained size 104\n   References count 1\n   Field table of instance 0x64628868\n   Path to nearest GC root\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628a18 number 13 retained size 104\n   References count 1\n   Field table of instance 0x646289f0\n   Path to nearest GC root\n    Next object java.util.HashMap#11\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646291e0 number 14 retained size 0\n   References count 1\n   Field table of instance 0x646291b8\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629258 number 15 retained size 0\n   References count 1\n   Field table of instance 0x64629230\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a388 number 16 retained size 0\n   References count 1\n   Field table of instance 0x6462a360\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a400 number 17 retained size 0\n   References count 1\n   Field table of instance 0x6462a3d8\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a800 number 18 retained size 144\n   References count 1\n   Field table of instance 0x6462a7d8\n   Path to nearest GC root\n    Next object java.util.HashMap#16\n    Next object java.lang.Class#235\n  Instance Id 0x6462a8b8 number 19 retained size 80\n   References count 1\n   Field table of instance 0x6462a890\n   Path to nearest GC root\n    Next object java.util.HashMap#17\n    Next object java.lang.Class#235\n  Instance Id 0x6462a930 number 20 retained size 80\n   References count 1\n   Field table of instance 0x6462a908\n   Path to nearest GC root\n    Next object java.util.HashMap#18\n    Next object java.lang.Class#235\n  Instance Id 0x6462b770 number 21 retained size 4696\n   References count 1\n   Field table of instance 0x6462a9e0\n   Path to nearest GC root\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462e2b8 number 22 retained size 3576\n   References count 1\n   Field table of instance 0x6462daf0\n   Path to nearest GC root\n    Next object java.util.HashMap#20\n    Next object java.lang.Class#21\n  Instance Id 0x6462fb80 number 23 retained size 528\n   References count 1\n   Field table of instance 0x6462f0c8\n   Path to nearest GC root\n    Next object java.util.LinkedHashMap#1\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630868 number 24 retained size 520\n   References count 1\n   Field table of instance 0x64630840\n   Path to nearest GC root\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646309d8 number 25 retained size 80\n   References count 1\n   Field table of instance 0x646309b0\n   Path to nearest GC root\n    Next object java.util.HashMap#22\n    Next object java.security.Permissions#2\n    Next object java.security.Policy$UnsupportedEmptyCollection#1\n    Next object java.lang.Class#325\n  Instance Id 0x64630bd8 number 26 retained size 128\n   References count 1\n   Field table of instance 0x64630bb0\n   Path to nearest GC root\n    Next object java.util.HashMap#23\n    Next object java.security.BasicPermissionCollection#1\n    Next object java.util.HashMap$Entry#154\n    Next object java.util.HashMap$Entry[]#24\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n Id 0x6c97d938 Class java.security.PrivilegedAction SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9edca8 Class sun.reflect.DelegatingConstructorAccessorImpl SuperClass sun.reflect.ConstructorAccessorImpl Instance size 16 Instance count 4 All Instances Size 64\n  Static Field name <classLoader> type object value 0\n  Field name delegate type object\n  Instance Id 0x64615088 number 1 retained size 0\n   Instance Field name delegate type object value 1684099184\n    Ref object sun.reflect.NativeConstructorAccessorImpl#1\n   References count 3\n   Field constructorAccessor of instance 0x64614fd0\n   Field constructorAccessor of instance 0x64615030\n   Field parent of instance 0x64615070\n   Path to nearest GC root\n    Null\n  Instance Id 0x646279e0 number 2 retained size 0\n   Instance Field name delegate type object value 1684175304\n    Ref object sun.reflect.NativeConstructorAccessorImpl#2\n   References count 3\n   Field constructorAccessor of instance 0x64627928\n   Field constructorAccessor of instance 0x64627988\n   Field parent of instance 0x646279c8\n   Path to nearest GC root\n    Null\n  Instance Id 0x646284a8 number 3 retained size 0\n   Instance Field name delegate type object value 1684178064\n    Ref object sun.reflect.NativeConstructorAccessorImpl#3\n   References count 3\n   Field constructorAccessor of instance 0x646283f0\n   Field constructorAccessor of instance 0x64628450\n   Field parent of instance 0x64628490\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629398 number 4 retained size 0\n   Instance Field name delegate type object value 1684181888\n    Ref object sun.reflect.NativeConstructorAccessorImpl#4\n   References count 3\n   Field constructorAccessor of instance 0x646292e0\n   Field constructorAccessor of instance 0x64629340\n   Field parent of instance 0x64629380\n   Path to nearest GC root\n    Null\n Id 0x6c9b1d80 Class sun.reflect.LangReflectAccess SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c9ed818 Class sun.reflect.NativeConstructorAccessorImpl SuperClass sun.reflect.ConstructorAccessorImpl Instance size 24 Instance count 4 All Instances Size 96\n  Static Field name <classLoader> type object value 0\n  Field name numInvocations type int\n  Field name parent type object\n  Field name c type object\n  Instance Id 0x64615070 number 1 retained size 0\n   Instance Field name numInvocations type int value 1\n   Instance Field name parent type object value 1684099208\n    Ref object sun.reflect.DelegatingConstructorAccessorImpl#1\n   Instance Field name c type object value 1684099120\n    Ref object java.lang.reflect.Constructor#2\n   References count 1\n   Field delegate of instance 0x64615088\n   Path to nearest GC root\n    Null\n  Instance Id 0x646279c8 number 2 retained size 0\n   Instance Field name numInvocations type int value 1\n   Instance Field name parent type object value 1684175328\n    Ref object sun.reflect.DelegatingConstructorAccessorImpl#2\n   Instance Field name c type object value 1684175240\n    Ref object java.lang.reflect.Constructor#4\n   References count 1\n   Field delegate of instance 0x646279e0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64628490 number 3 retained size 0\n   Instance Field name numInvocations type int value 2\n   Instance Field name parent type object value 1684178088\n    Ref object sun.reflect.DelegatingConstructorAccessorImpl#3\n   Instance Field name c type object value 1684178000\n    Ref object java.lang.reflect.Constructor#6\n   References count 1\n   Field delegate of instance 0x646284a8\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629380 number 4 retained size 0\n   Instance Field name numInvocations type int value 1\n   Instance Field name parent type object value 1684181912\n    Ref object sun.reflect.DelegatingConstructorAccessorImpl#4\n   Instance Field name c type object value 1684181824\n    Ref object java.lang.reflect.Constructor#8\n   References count 1\n   Field delegate of instance 0x64629398\n   Path to nearest GC root\n    Null\n Id 0x6c9ed278 Class sun.reflect.ReflectionFactory$1 SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6cae5768 Class sun.misc.Cleaner SuperClass java.lang.ref.PhantomReference Instance size 40 Instance count 0 All Instances Size 0\n  Static Field name first type object value 0\n  Static Field name dummyQueue type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name thunk type object\n  Field name prev type object\n  Field name next type object\n Id 0x6c982f70 Class java.nio.charset.Charset SuperClass java.lang.Object Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name defaultCharset type object value 1684099224\n   Ref object sun.nio.cs.ISO_8859_1#1\n  Static Field name extendedProvider type object value 0\n  Static Field name extendedProviderProbed type boolean value false\n  Static Field name extendedProviderLock type object value 1684098912\n   Ref object java.lang.Object#5\n  Static Field name gate type object value 1684098896\n   Ref object java.lang.ThreadLocal#1\n  Static Field name cache2 type object value 1684099248\n   Ref object java.lang.Object[]#299\n  Static Field name cache1 type object value 1684181952\n   Ref object java.lang.Object[]#313\n  Static Field name standardProvider type object value 1684086936\n   Ref object sun.nio.cs.StandardCharsets#1\n  Static Field name bugLevel type object value 0\n  Static Field name <classLoader> type object value 0\n  Field name aliasSet type object\n  Field name aliases type object\n  Field name name type object\n Id 0x68138160 Class java.io.Console$1$1 SuperClass java.lang.Object Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name <classLoader> type object value 0\n  Field name this$0 type object\n  Instance Id 0x646256a8 number 1 retained size 16\n   Instance Field name this$0 type object value 1684166304\n    Ref object java.io.Console$1#1\n   References count 1\n   Element 0 of array 0x646256d0\n   Path to nearest GC root\n    Next object java.lang.Object[]#300\n    Next object java.util.ArrayList#1\n    Next object java.lang.Class#110\n Id 0x6c9a79a0 Class java.nio.CharBuffer SuperClass java.nio.Buffer Instance size 48 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name isReadOnly type boolean\n  Field name offset type int\n  Field name hb type object\n Id 0x6c9b9058 Class java.nio.charset.CharsetEncoder SuperClass java.lang.Object Instance size 40 Instance count 0 All Instances Size 0\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name stateNames type object value 1684105696\n   Ref object java.lang.String[]#41\n  Static Field name ST_FLUSHED type int value 3\n  Static Field name ST_END type int value 2\n  Static Field name ST_CODING type int value 1\n  Static Field name ST_RESET type int value 0\n  Static Field name <classLoader> type object value 0\n  Field name cachedDecoder type object\n  Field name state type int\n  Field name unmappableCharacterAction type object\n  Field name malformedInputAction type object\n  Field name replacement type object\n  Field name maxBytesPerChar type float\n  Field name averageBytesPerChar type float\n  Field name charset type object\n Id 0x6c9935a0 Class java.nio.charset.CharsetDecoder SuperClass java.lang.Object Instance size 40 Instance count 0 All Instances Size 0\n  Static Field name $assertionsDisabled type boolean value true\n  Static Field name stateNames type object value 1684099464\n   Ref object java.lang.String[]#39\n  Static Field name ST_FLUSHED type int value 3\n  Static Field name ST_END type int value 2\n  Static Field name ST_CODING type int value 1\n  Static Field name ST_RESET type int value 0\n  Static Field name <classLoader> type object value 0\n  Field name state type int\n  Field name unmappableCharacterAction type object\n  Field name malformedInputAction type object\n  Field name replacement type object\n  Field name maxCharsPerByte type float\n  Field name averageCharsPerByte type float\n  Field name charset type object\n Id 0x6c9944f0 Class java.nio.charset.CodingErrorAction SuperClass java.lang.Object Instance size 16 Instance count 3 All Instances Size 48\n  Static Field name REPORT type object value 1684099528\n   Ref object java.nio.charset.CodingErrorAction#3\n  Static Field name REPLACE type object value 1684099512\n   Ref object java.nio.charset.CodingErrorAction#2\n  Static Field name IGNORE type object value 1684099496\n   Ref object java.nio.charset.CodingErrorAction#1\n  Static Field name <classLoader> type object value 0\n  Field name name type object\n  Instance Id 0x646151a8 number 1 retained size 16\n   Instance Field name name type object value 0\n   References count 1\n   Field IGNORE of Class java.nio.charset.CodingErrorAction\n   Path to nearest GC root\n    Next object java.lang.Class#424\n  Instance Id 0x646151b8 number 2 retained size 16\n   Instance Field name name type object value 0\n   References count 9\n   Field REPLACE of Class java.nio.charset.CodingErrorAction\n   Field unmappableCharacterAction of instance 0x6462a480\n   Field malformedInputAction of instance 0x6462a480\n   Field unmappableCharacterAction of instance 0x64616a00\n   Field malformedInputAction of instance 0x64616a00\n   Field unmappableCharacterAction of instance 0x64616bd8\n   Field malformedInputAction of instance 0x64616bd8\n   Field unmappableCharacterAction of instance 0x646250a8\n   Field malformedInputAction of instance 0x646250a8\n   Path to nearest GC root\n    Next object java.lang.Class#424\n  Instance Id 0x646151c8 number 3 retained size 16\n   Instance Field name name type object value 0\n   References count 3\n   Field REPORT of Class java.nio.charset.CodingErrorAction\n   Field unmappableCharacterAction of instance 0x646250e8\n   Field malformedInputAction of instance 0x646250e8\n   Path to nearest GC root\n    Next object java.lang.Class#424\n Id 0x6c983758 Class java.nio.charset.spi.CharsetProvider SuperClass java.lang.Object Instance size 8 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n Id 0x6c984ee0 Class sun.nio.cs.StandardCharsets SuperClass sun.nio.cs.FastCharsetProvider Instance size 24 Instance count 1 All Instances Size 24\n  Static Field name aliases_IBM874 type object value 1684086904\n   Ref object java.lang.String[]#38\n  Static Field name aliases_IBM866 type object value 1684086872\n   Ref object java.lang.String[]#37\n  Static Field name aliases_IBM862 type object value 1684086832\n   Ref object java.lang.String[]#36\n  Static Field name aliases_IBM858 type object value 1684086800\n   Ref object java.lang.String[]#35\n  Static Field name aliases_IBM857 type object value 1684086768\n   Ref object java.lang.String[]#34\n  Static Field name aliases_IBM855 type object value 1684086736\n   Ref object java.lang.String[]#33\n  Static Field name aliases_IBM852 type object value 1684086704\n   Ref object java.lang.String[]#32\n  Static Field name aliases_IBM850 type object value 1684086672\n   Ref object java.lang.String[]#31\n  Static Field name aliases_IBM775 type object value 1684086640\n   Ref object java.lang.String[]#30\n  Static Field name aliases_IBM737 type object value 1684086608\n   Ref object java.lang.String[]#29\n  Static Field name aliases_IBM437 type object value 1684086568\n   Ref object java.lang.String[]#28\n  Static Field name aliases_MS1257 type object value 1684086544\n   Ref object java.lang.String[]#27\n  Static Field name aliases_MS1254 type object value 1684086520\n   Ref object java.lang.String[]#26\n  Static Field name aliases_MS1253 type object value 1684086496\n   Ref object java.lang.String[]#25\n  Static Field name aliases_MS1252 type object value 1684086472\n   Ref object java.lang.String[]#24\n  Static Field name aliases_MS1251 type object value 1684086448\n   Ref object java.lang.String[]#23\n  Static Field name aliases_MS1250 type object value 1684086424\n   Ref object java.lang.String[]#22\n  Static Field name aliases_KOI8_U type object value 1684086408\n   Ref object java.lang.String[]#21\n  Static Field name aliases_KOI8_R type object value 1684086384\n   Ref object java.lang.String[]#20\n  Static Field name aliases_ISO_8859_15 type object value 1684086312\n   Ref object java.lang.String[]#19\n  Static Field name aliases_ISO_8859_13 type object value 1684086280\n   Ref object java.lang.String[]#18\n  Static Field name aliases_ISO_8859_9 type object value 1684086216\n   Ref object java.lang.String[]#17\n  Static Field name aliases_ISO_8859_7 type object value 1684086136\n   Ref object java.lang.String[]#16\n  Static Field name aliases_ISO_8859_5 type object value 1684086072\n   Ref object java.lang.String[]#15\n  Static Field name aliases_ISO_8859_4 type object value 1684086008\n   Ref object java.lang.String[]#14\n  Static Field name aliases_ISO_8859_2 type object value 1684085944\n   Ref object java.lang.String[]#13\n  Static Field name aliases_ISO_8859_1 type object value 1684085872\n   Ref object java.lang.String[]#12\n  Static Field name aliases_UTF_32BE_BOM type object value 1684085848\n   Ref object java.lang.String[]#11\n  Static Field name aliases_UTF_32LE_BOM type object value 1684085824\n   Ref object java.lang.String[]#10\n  Static Field name aliases_UTF_32BE type object value 1684085800\n   Ref object java.lang.String[]#9\n  Static Field name aliases_UTF_32LE type object value 1684085776\n   Ref object java.lang.String[]#8\n  Static Field name aliases_UTF_32 type object value 1684085752\n   Ref object java.lang.String[]#7\n  Static Field name aliases_UTF_16LE_BOM type object value 1684085736\n   Ref object java.lang.String[]#6\n  Static Field name aliases_UTF_16LE type object value 1684085712\n   Ref object java.lang.String[]#5\n  Static Field name aliases_UTF_16BE type object value 1684085680\n   Ref object java.lang.String[]#4\n  Static Field name aliases_UTF_16 type object value 1684085648\n   Ref object java.lang.String[]#3\n  Static Field name aliases_UTF_8 type object value 1684085624\n   Ref object java.lang.String[]#2\n  Static Field name aliases_US_ASCII type object value 1684085552\n   Ref object java.lang.String[]#1\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64612098 number 1 retained size 11360\n   Instance Field name packagePrefix type object value 0\n   Instance Field name cache type object value 1684097200\n    Ref object sun.nio.cs.StandardCharsets$Cache#1\n   Instance Field name aliasMap type object value 1684086960\n    Ref object sun.nio.cs.StandardCharsets$Aliases#1\n   Instance Field name classMap type object value 1684096104\n    Ref object sun.nio.cs.StandardCharsets$Classes#1\n   References count 1\n   Field standardProvider of Class java.nio.charset.Charset\n   Path to nearest GC root\n    Next object java.lang.Class#419\n Id 0x6c9b7d68 Class sun.security.action.GetPropertyAction SuperClass java.lang.Object Instance size 16 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name defaultVal type object\n  Field name theProp type object\n Id 0x6c983f08 Class sun.nio.cs.FastCharsetProvider SuperClass java.nio.charset.spi.CharsetProvider Instance size 24 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name packagePrefix type object\n  Field name cache type object\n  Field name aliasMap type object\n  Field name classMap type object\n Id 0x6c986828 Class sun.nio.cs.StandardCharsets$Aliases SuperClass sun.util.PreHashedMap Instance size 40 Instance count 1 All Instances Size 40\n  Static Field name MASK type int value 1023\n  Static Field name SHIFT type int value 0\n  Static Field name SIZE type int value 208\n  Static Field name ROWS type int value 1024\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x646120b0 number 1 retained size 9144\n   Instance Field name ht type object value 1684087000\n    Ref object java.lang.Object[]#12\n   Instance Field name mask type int value 1023\n   Instance Field name shift type int value 0\n   Instance Field name size type int value 208\n   Instance Field name rows type int value 1024\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field aliasMap of instance 0x64612098\n   Path to nearest GC root\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n Id 0x6c987578 Class sun.nio.cs.StandardCharsets$Cache SuperClass sun.util.PreHashedMap Instance size 40 Instance count 1 All Instances Size 40\n  Static Field name MASK type int value 31\n  Static Field name SHIFT type int value 1\n  Static Field name SIZE type int value 38\n  Static Field name ROWS type int value 32\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x646148b0 number 1 retained size 1096\n   Instance Field name ht type object value 1684097240\n    Ref object java.lang.Object[]#260\n   Instance Field name mask type int value 31\n   Instance Field name shift type int value 1\n   Instance Field name size type int value 38\n   Instance Field name rows type int value 32\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field cache of instance 0x64612098\n   Path to nearest GC root\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n Id 0x6c986f90 Class sun.nio.cs.StandardCharsets$Classes SuperClass sun.util.PreHashedMap Instance size 40 Instance count 1 All Instances Size 40\n  Static Field name MASK type int value 31\n  Static Field name SHIFT type int value 1\n  Static Field name SIZE type int value 38\n  Static Field name ROWS type int value 32\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64614468 number 1 retained size 1096\n   Instance Field name ht type object value 1684096144\n    Ref object java.lang.Object[]#221\n   Instance Field name mask type int value 31\n   Instance Field name shift type int value 1\n   Instance Field name size type int value 38\n   Instance Field name rows type int value 32\n   Instance Field name values type object value 0\n   Instance Field name keySet type object value 0\n   References count 1\n   Field classMap of instance 0x64612098\n   Path to nearest GC root\n    Next object sun.nio.cs.StandardCharsets#1\n    Next object java.lang.Class#419\n Id 0x6c9859a8 Class sun.util.PreHashedMap SuperClass java.util.AbstractMap Instance size 40 Instance count 0 All Instances Size 0\n  Static Field name <classLoader> type object value 0\n  Field name ht type object\n  Field name mask type int\n  Field name shift type int\n  Field name size type int\n  Field name rows type int\n Id 0x6c991c98 Class java.lang.ThreadLocal$ThreadLocalMap$Entry SuperClass java.lang.ref.WeakReference Instance size 32 Instance count 3 All Instances Size 96\n  Static Field name <classLoader> type object value 0\n  Field name value type object\n  Instance Id 0x64615168 number 1 retained size 64\n   Instance Field name value type object value 1684186296\n    Ref object java.lang.ref.SoftReference#11\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684099296\n    Ref object java.lang.ThreadLocal#2\n   References count 1\n   Element 7 of array 0x64615118\n   Path to nearest GC root\n    Next object java.lang.ThreadLocal$ThreadLocalMap$Entry[]#1\n    Next object java.lang.ThreadLocal$ThreadLocalMap#1\n    Next object java.lang.Thread#1\n  Instance Id 0x64625070 number 2 retained size 64\n   Instance Field name value type object value 1684164928\n    Ref object java.lang.ref.SoftReference#4\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684099312\n    Ref object java.lang.ThreadLocal#3\n   References count 1\n   Element 14 of array 0x64615118\n   Path to nearest GC root\n    Next object java.lang.ThreadLocal$ThreadLocalMap$Entry[]#1\n    Next object java.lang.ThreadLocal$ThreadLocalMap#1\n    Next object java.lang.Thread#1\n  Instance Id 0x6462ef30 number 3 retained size 96\n   Instance Field name value type object value 1684205296\n    Ref object char[]#261\n   Instance Field name discovered type object value 0\n   Instance Field name next type object value 0\n   Instance Field name queue type object value 1684080280\n    Ref object java.lang.ref.ReferenceQueue$Null#1\n   Instance Field name referent type object value 1684198344\n    Ref object sun.misc.FloatingDecimal$1#1\n   References count 1\n   Element 5 of array 0x64615118\n   Path to nearest GC root\n    Next object java.lang.ThreadLocal$ThreadLocalMap$Entry[]#1\n    Next object java.lang.ThreadLocal$ThreadLocalMap#1\n    Next object java.lang.Thread#1\n Id 0x681340c0 Class java.lang.ThreadLocal$ThreadLocalMap$Entry[] SuperClass java.lang.Object Instance size -1 Instance count 1 All Instances Size 80\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64615118 number 1 retained size 304\n   References count 1\n   Field table of instance 0x64615100\n   Path to nearest GC root\n    Next object java.lang.ThreadLocal$ThreadLocalMap#1\n    Next object java.lang.Thread#1\n Id 0x68133260 Class java.util.concurrent.atomic.AtomicInteger SuperClass java.lang.Number Instance size 16 Instance count 1 All Instances Size 16\n  Static Field name valueOffset type long value 8\n  Static Field name unsafe type object value 1684098296\n   Ref object sun.misc.Unsafe#1\n  Static Field name serialVersionUID type long value 6214790243416807050\n  Static Field name <classLoader> type object value 0\n  Field name value type int\n  Instance Id 0x64614f40 number 1 retained size 16\n   Instance Field name value type int value -2027808484\n   References count 1\n   Field nextHashCode of Class java.lang.ThreadLocal\n   Path to nearest GC root\n    Next object java.lang.Class#353\n Id 0x6c9392a0 Class boolean[] SuperClass java.lang.Object Instance size -1 Instance count 5 All Instances Size 1360\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462d7f0 number 1 retained size 272\n   References count 1\n   Field bits of instance 0x6462d7e0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$BitClass#1\n    Next object java.util.regex.Pattern$GroupHead#1\n    Next object java.util.regex.Pattern$Node[]#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462d968 number 2 retained size 272\n   References count 1\n   Field bits of instance 0x6462d958\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462eab0 number 3 retained size 272\n   References count 1\n   Field bits of instance 0x6462eaa0\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462ebf8 number 4 retained size 272\n   References count 1\n   Field bits of instance 0x6462ebe8\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$BitClass#4\n    Next object java.util.regex.Pattern$GroupHead#8\n    Next object java.util.regex.Pattern$Node[]#3\n    Next object java.util.regex.Pattern$Branch#3\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n  Instance Id 0x6462edb8 number 5 retained size 272\n   References count 1\n   Field bits of instance 0x6462eda8\n   Path to nearest GC root\n    Next object java.util.regex.Pattern$BitClass#5\n    Next object java.util.regex.Pattern$Ques#2\n    Next object java.util.regex.Pattern$GroupTail#9\n    Next object java.util.regex.Pattern$Curly#4\n    Next object java.util.regex.Pattern$GroupHead#9\n    Next object java.util.regex.Pattern$BranchConn#3\n    Next object java.util.regex.Pattern$Branch#3\n    Next object java.util.regex.Pattern$BitClass#3\n    Next object java.util.regex.Pattern$GroupTail#2\n    Next object java.util.regex.Pattern$BranchConn#2\n    Next object java.util.regex.Pattern$Branch#2\n    Next object java.util.regex.Pattern$GroupHead#2\n    Next object java.util.regex.Pattern$BitClass#2\n    Next object java.util.regex.Pattern$5#1\n    Next object java.util.regex.Pattern$BranchConn#1\n    Next object java.util.regex.Pattern$Branch#1\n    Next object java.util.regex.Pattern#1\n    Next object java.lang.Class#394\n Id 0x6c939420 Class byte[] SuperClass java.lang.Object Instance size -1 Instance count 25 All Instances Size 26528\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64616908 number 1 retained size 144\n   References count 1\n   Field buf of instance 0x646168f0\n   Path to nearest GC root\n    Next object java.io.BufferedOutputStream#1\n    Next object java.io.PrintStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616a30 number 2 retained size 16\n   References count 1\n   Field replacement of instance 0x64616a00\n   Path to nearest GC root\n    Next object sun.nio.cs.ISO_8859_1$Encoder#1\n    Next object sun.nio.cs.StreamEncoder#1\n    Next object java.io.OutputStreamWriter#1\n    Next object java.io.PrintStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616b00 number 3 retained size 144\n   References count 1\n   Field buf of instance 0x64616ae8\n   Path to nearest GC root\n    Next object java.io.BufferedOutputStream#2\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n  Instance Id 0x64616c08 number 4 retained size 16\n   References count 1\n   Field replacement of instance 0x64616bd8\n   Path to nearest GC root\n    Next object sun.nio.cs.ISO_8859_1$Encoder#2\n    Next object sun.nio.cs.StreamEncoder#2\n    Next object java.io.OutputStreamWriter#2\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n  Instance Id 0x64616ec0 number 5 retained size 8208\n   References count 1\n   Field buf of instance 0x646168b0\n   Path to nearest GC root\n    Next object java.io.BufferedInputStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x64618ed0 number 6 retained size 8208\n   References count 1\n   Field hb of instance 0x64616a70\n   Path to nearest GC root\n    Next object java.nio.HeapByteBuffer#1\n    Next object sun.nio.cs.StreamEncoder#1\n    Next object java.io.OutputStreamWriter#1\n    Next object java.io.PrintStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x6461eef0 number 7 retained size 8208\n   References count 1\n   Field hb of instance 0x64616c48\n   Path to nearest GC root\n    Next object java.nio.HeapByteBuffer#2\n    Next object sun.nio.cs.StreamEncoder#2\n    Next object java.io.OutputStreamWriter#2\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n  Instance Id 0x646250d8 number 8 retained size 0\n   References count 1\n   Field replacement of instance 0x646250a8\n   Path to nearest GC root\n    Null\n  Instance Id 0x646290b8 number 9 retained size 0\n   References count 1\n   Field manifestRawBytes of instance 0x646297a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629950 number 10 retained size 0\n   References count 1\n   Field buf of instance 0x64629940\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462f098 number 11 retained size 48\n   References count 1\n   Field urandomBuffer of instance 0x6462efc8\n   Path to nearest GC root\n    Next object sun.security.provider.NativePRNG$RandomIO#1\n    Next object java.lang.Class#339\n  Instance Id 0x64630608 number 12 retained size 272\n   References count 1\n   Field pem_convert_array of Class sun.misc.BASE64Decoder\n   Path to nearest GC root\n    Next object java.lang.Class#321\n  Instance Id 0x68132378 number 13 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681343f8 number 14 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68134e40 number 15 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68134f18 number 16 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68135908 number 17 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68137568 number 18 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68137618 number 19 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68137e20 number 20 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681383d8 number 21 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68138e38 number 22 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68138f30 number 23 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813a7d8 number 24 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813b288 number 25 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n Id 0x6c939300 Class char[] SuperClass java.lang.Object Instance size -1 Instance count 305 All Instances Size 49704\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610018 number 1 retained size 0\n   References count 1\n   Field value of instance 0x64610000\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610060 number 2 retained size 0\n   References count 1\n   Field value of instance 0x64610048\n   Path to nearest GC root\n    Null\n  Instance Id 0x646100a0 number 3 retained size 0\n   References count 1\n   Field value of instance 0x64610088\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610110 number 4 retained size 0\n   References count 1\n   Field value of instance 0x646100f8\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610168 number 5 retained size 0\n   References count 1\n   Field value of instance 0x64610150\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610618 number 6 retained size 24\n   References count 1\n   Field value of instance 0x64610600\n   Path to nearest GC root\n    Next object java.lang.String#6\n    Next object java.lang.ThreadGroup#2\n    Next object java.lang.Thread#1\n  Instance Id 0x64610808 number 7 retained size 24\n   References count 1\n   Field name of instance 0x64610790\n   Path to nearest GC root\n    Next object java.lang.Thread#1\n  Instance Id 0x646109f0 number 8 retained size 48\n   References count 1\n   Field name of instance 0x64610978\n   Path to nearest GC root\n    Next object java.lang.ref.Reference$ReferenceHandler#1\n  Instance Id 0x64610af8 number 9 retained size 32\n   References count 1\n   Field name of instance 0x64610a80\n   Path to nearest GC root\n    Next object java.lang.ref.Finalizer$FinalizerThread#1\n  Instance Id 0x64610b40 number 10 retained size 48\n   References count 1\n   Field hexDigit of Class java.util.Properties\n   Path to nearest GC root\n    Next object java.lang.Class#142\n  Instance Id 0x64610bb8 number 11 retained size 64\n   References count 1\n   Field value of instance 0x64610ba0\n   Path to nearest GC root\n    Next object java.lang.String#7\n    Next object java.util.Hashtable$Entry#1\n    Next object java.util.Hashtable$Entry#17\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610c10 number 12 retained size 24\n   References count 1\n   Field value of instance 0x64610bf8\n   Path to nearest GC root\n    Next object java.lang.String#8\n    Next object java.util.Hashtable$Entry#1\n    Next object java.util.Hashtable$Entry#17\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610c58 number 13 retained size 64\n   References count 1\n   Field value of instance 0x64610c40\n   Path to nearest GC root\n    Next object java.lang.String#9\n    Next object java.util.Hashtable$Entry#2\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610cb0 number 14 retained size 80\n   References count 1\n   Field value of instance 0x64610c98\n   Path to nearest GC root\n    Next object java.lang.String#10\n    Next object java.util.Hashtable$Entry#2\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610d30 number 15 retained size 64\n   References count 1\n   Field value of instance 0x64610d18\n   Path to nearest GC root\n    Next object java.lang.String#11\n    Next object java.util.Hashtable$Entry#3\n    Next object java.util.Hashtable$Entry#15\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610d88 number 16 retained size 56\n   References count 1\n   Field value of instance 0x64610d70\n   Path to nearest GC root\n    Next object java.lang.String#12\n    Next object java.util.Hashtable$Entry#3\n    Next object java.util.Hashtable$Entry#15\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610df0 number 17 retained size 40\n   References count 1\n   Field value of instance 0x64610dd8\n   Path to nearest GC root\n    Next object java.lang.String#13\n    Next object java.util.Hashtable$Entry#4\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610e48 number 18 retained size 40\n   References count 1\n   Field value of instance 0x64610e30\n   Path to nearest GC root\n    Next object java.lang.String#14\n    Next object java.util.Hashtable$Entry#5\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610e88 number 19 retained size 56\n   References count 1\n   Field value of instance 0x64610e70\n   Path to nearest GC root\n    Next object java.lang.String#15\n    Next object java.util.Hashtable$Entry#5\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610ef0 number 20 retained size 48\n   References count 1\n   Field value of instance 0x64610ed8\n   Path to nearest GC root\n    Next object java.lang.String#16\n    Next object java.util.Hashtable$Entry#6\n    Next object java.util.Hashtable$Entry#37\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610f38 number 21 retained size 56\n   References count 1\n   Field value of instance 0x64610f20\n   Path to nearest GC root\n    Next object java.lang.String#17\n    Next object java.util.Hashtable$Entry#6\n    Next object java.util.Hashtable$Entry#37\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610fa0 number 22 retained size 56\n   References count 1\n   Field value of instance 0x64610f88\n   Path to nearest GC root\n    Next object java.lang.String#18\n    Next object java.util.Hashtable$Entry#7\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64610ff0 number 23 retained size 96\n   References count 1\n   Field value of instance 0x64610fd8\n   Path to nearest GC root\n    Next object java.lang.String#19\n    Next object java.util.Hashtable$Entry#7\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611080 number 24 retained size 48\n   References count 1\n   Field value of instance 0x64611068\n   Path to nearest GC root\n    Next object java.lang.String#20\n    Next object java.util.Hashtable$Entry#8\n    Next object java.util.Hashtable$Entry#2\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646110c8 number 25 retained size 24\n   References count 1\n   Field value of instance 0x646110b0\n   Path to nearest GC root\n    Next object java.lang.String#21\n    Next object java.util.Hashtable$Entry#8\n    Next object java.util.Hashtable$Entry#2\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611110 number 26 retained size 32\n   References count 1\n   Field value of instance 0x646110f8\n   Path to nearest GC root\n    Next object java.lang.String#22\n    Next object java.util.Hashtable$Entry#9\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611148 number 27 retained size 24\n   References count 1\n   Field value of instance 0x64611130\n   Path to nearest GC root\n    Next object java.lang.String#23\n    Next object java.util.Hashtable$Entry#9\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611190 number 28 retained size 32\n   References count 1\n   Field value of instance 0x64611178\n   Path to nearest GC root\n    Next object java.lang.String#24\n    Next object java.util.Hashtable$Entry#10\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646111c8 number 29 retained size 48\n   References count 1\n   Field value of instance 0x646111b0\n   Path to nearest GC root\n    Next object java.lang.String#25\n    Next object java.util.Hashtable$Entry#10\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611228 number 30 retained size 32\n   References count 1\n   Field value of instance 0x64611210\n   Path to nearest GC root\n    Next object java.lang.String#26\n    Next object java.util.Hashtable$Entry#11\n    Next object java.util.Hashtable$Entry#40\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611260 number 31 retained size 24\n   References count 1\n   Field value of instance 0x64611248\n   Path to nearest GC root\n    Next object java.lang.String#27\n    Next object java.util.Hashtable$Entry#11\n    Next object java.util.Hashtable$Entry#40\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646112a8 number 32 retained size 40\n   References count 1\n   Field value of instance 0x64611290\n   Path to nearest GC root\n    Next object java.lang.String#28\n    Next object java.util.Hashtable$Entry#12\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646112e8 number 33 retained size 16\n   References count 1\n   Field value of instance 0x646112d0\n   Path to nearest GC root\n    Next object java.lang.String#29\n    Next object java.util.Hashtable$Entry#12\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611328 number 34 retained size 40\n   References count 1\n   Field value of instance 0x64611310\n   Path to nearest GC root\n    Next object java.lang.String#30\n    Next object java.util.Hashtable$Entry#13\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611368 number 35 retained size 16\n   References count 1\n   Field value of instance 0x64611350\n   Path to nearest GC root\n    Next object java.lang.String#31\n    Next object java.util.Hashtable$Entry#13\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646113a8 number 36 retained size 40\n   References count 1\n   Field value of instance 0x64611390\n   Path to nearest GC root\n    Next object java.lang.String#32\n    Next object java.util.Hashtable$Entry#14\n    Next object java.util.Hashtable$Entry#27\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646113e8 number 37 retained size 16\n   References count 1\n   Field value of instance 0x646113d0\n   Path to nearest GC root\n    Next object java.lang.String#33\n    Next object java.io.BufferedWriter#2\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n  Instance Id 0x64611428 number 38 retained size 40\n   References count 1\n   Field value of instance 0x64611410\n   Path to nearest GC root\n    Next object java.lang.String#34\n    Next object java.util.Hashtable$Entry#15\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611468 number 39 retained size 16\n   References count 1\n   Field value of instance 0x64611450\n   Path to nearest GC root\n    Next object java.lang.String#35\n    Next object java.util.Hashtable$Entry#15\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646114a8 number 40 retained size 40\n   References count 1\n   Field value of instance 0x64611490\n   Path to nearest GC root\n    Next object java.lang.String#36\n    Next object java.util.Hashtable$Entry#16\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646114e8 number 41 retained size 16\n   References count 1\n   Field value of instance 0x646114d0\n   Path to nearest GC root\n    Next object java.lang.String#37\n    Next object java.util.Hashtable$Entry#16\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611528 number 42 retained size 40\n   References count 1\n   Field value of instance 0x64611510\n   Path to nearest GC root\n    Next object java.lang.String#38\n    Next object java.util.Hashtable$Entry#17\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611568 number 43 retained size 32\n   References count 1\n   Field value of instance 0x64611550\n   Path to nearest GC root\n    Next object java.lang.String#39\n    Next object java.util.Hashtable$Entry#17\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646115b8 number 44 retained size 48\n   References count 1\n   Field value of instance 0x646115a0\n   Path to nearest GC root\n    Next object java.lang.String#40\n    Next object java.util.Hashtable$Entry#18\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611600 number 45 retained size 32\n   References count 1\n   Field value of instance 0x646115e8\n   Path to nearest GC root\n    Next object java.lang.String#41\n  Instance Id 0x64611650 number 46 retained size 48\n   References count 1\n   Field value of instance 0x64611638\n   Path to nearest GC root\n    Next object java.lang.String#42\n    Next object java.util.Hashtable$Entry#19\n    Next object java.util.Hashtable$Entry#36\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611698 number 47 retained size 24\n   References count 1\n   Field value of instance 0x64611680\n   Path to nearest GC root\n    Next object java.lang.String#43\n    Next object java.util.Hashtable$Entry#19\n    Next object java.util.Hashtable$Entry#36\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646116e0 number 48 retained size 64\n   References count 1\n   Field value of instance 0x646116c8\n   Path to nearest GC root\n    Next object java.lang.String#44\n    Next object java.util.Hashtable$Entry#20\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611738 number 49 retained size 40\n   References count 1\n   Field value of instance 0x64611720\n   Path to nearest GC root\n    Next object java.lang.String#45\n    Next object java.util.Hashtable$Entry#20\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611790 number 50 retained size 48\n   References count 1\n   Field value of instance 0x64611778\n   Path to nearest GC root\n    Next object java.lang.String#46\n    Next object java.util.Hashtable$Entry#21\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646117d8 number 51 retained size 16\n   References count 1\n   Field value of instance 0x646117c0\n   Path to nearest GC root\n    Next object java.lang.String#47\n    Next object java.util.Hashtable$Entry#21\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611818 number 52 retained size 40\n   References count 1\n   Field value of instance 0x64611800\n   Path to nearest GC root\n    Next object java.lang.String#48\n    Next object java.util.Hashtable$Entry#22\n    Next object java.util.Hashtable$Entry#20\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611858 number 53 retained size 24\n   References count 1\n   Field value of instance 0x64611840\n   Path to nearest GC root\n    Next object java.lang.String#49\n    Next object java.util.Hashtable$Entry#22\n    Next object java.util.Hashtable$Entry#20\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646118a0 number 54 retained size 56\n   References count 1\n   Field value of instance 0x64611888\n   Path to nearest GC root\n    Next object java.lang.String#50\n    Next object java.util.Hashtable$Entry#23\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646118f0 number 55 retained size 56\n   References count 1\n   Field value of instance 0x646118d8\n   Path to nearest GC root\n    Next object java.lang.String#51\n    Next object java.util.Hashtable$Entry#23\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611958 number 56 retained size 56\n   References count 1\n   Field value of instance 0x64611940\n   Path to nearest GC root\n    Next object java.lang.String#52\n    Next object java.util.Hashtable$Entry#24\n    Next object java.util.Hashtable$Entry#43\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646119a8 number 57 retained size 16\n   References count 1\n   Field value of instance 0x64611990\n   Path to nearest GC root\n    Next object java.lang.String#53\n    Next object java.util.Hashtable$Entry#24\n    Next object java.util.Hashtable$Entry#43\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646119e8 number 58 retained size 48\n   References count 1\n   Field value of instance 0x646119d0\n   Path to nearest GC root\n    Next object java.lang.String#54\n    Next object java.util.Hashtable$Entry#25\n    Next object java.util.Hashtable$Entry#16\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611a30 number 59 retained size 32\n   References count 1\n   Field value of instance 0x64611a18\n   Path to nearest GC root\n    Next object java.lang.String#55\n    Next object java.util.Hashtable$Entry#25\n    Next object java.util.Hashtable$Entry#16\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611a80 number 60 retained size 56\n   References count 1\n   Field value of instance 0x64611a68\n   Path to nearest GC root\n    Next object java.lang.String#56\n    Next object java.util.Hashtable$Entry#26\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64611ad0 number 61 retained size 72\n   References count 1\n   Field value of instance 0x64611ab8\n   Path to nearest GC root\n    Next object java.lang.String#57\n    Next object java.util.Hashtable$Entry#26\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646151d8 number 62 retained size 40\n   References count 1\n   Field value of instance 0x646150c8\n   Path to nearest GC root\n    Next object java.lang.String#58\n    Next object java.util.Hashtable$Entry#27\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615298 number 63 retained size 24\n   References count 1\n   Field value of instance 0x64615280\n   Path to nearest GC root\n    Next object java.lang.String#59\n    Next object java.util.Hashtable$Entry#27\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646152e0 number 64 retained size 32\n   References count 1\n   Field value of instance 0x646152c8\n   Path to nearest GC root\n    Next object java.lang.String#60\n    Next object java.util.Hashtable$Entry#28\n    Next object java.util.Hashtable$Entry#44\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615318 number 65 retained size 32\n   References count 1\n   Field value of instance 0x64615300\n   Path to nearest GC root\n    Next object java.lang.String#61\n    Next object java.util.Hashtable$Entry#28\n    Next object java.util.Hashtable$Entry#44\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615368 number 66 retained size 32\n   References count 1\n   Field value of instance 0x64615350\n   Path to nearest GC root\n    Next object java.lang.String#62\n    Next object java.util.Hashtable$Entry#29\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646153a0 number 67 retained size 40\n   References count 1\n   Field value of instance 0x64615388\n   Path to nearest GC root\n    Next object java.lang.String#63\n    Next object java.util.Hashtable$Entry#29\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646153f8 number 68 retained size 40\n   References count 1\n   Field value of instance 0x646153e0\n   Path to nearest GC root\n    Next object java.lang.String#64\n    Next object java.util.Hashtable$Entry#30\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615438 number 69 retained size 16\n   References count 1\n   Field value of instance 0x64615420\n   Path to nearest GC root\n    Next object java.lang.String#65\n    Next object java.util.Hashtable$Entry#30\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615478 number 70 retained size 32\n   References count 1\n   Field value of instance 0x64615460\n   Path to nearest GC root\n    Next object java.lang.String#66\n    Next object java.util.Hashtable$Entry#31\n    Next object java.util.Hashtable$Entry#33\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646154b0 number 71 retained size 24\n   References count 1\n   Field value of instance 0x64615498\n   Path to nearest GC root\n    Next object java.lang.String#67\n    Next object java.util.Hashtable$Entry#31\n    Next object java.util.Hashtable$Entry#33\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646154f8 number 72 retained size 72\n   References count 1\n   Field value of instance 0x646154e0\n   Path to nearest GC root\n    Next object java.lang.String#68\n    Next object java.util.Hashtable$Entry#32\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615558 number 73 retained size 24\n   References count 1\n   Field value of instance 0x64615540\n   Path to nearest GC root\n    Next object java.lang.String#69\n    Next object java.util.Hashtable$Entry#32\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646155a0 number 74 retained size 64\n   References count 1\n   Field value of instance 0x64615588\n   Path to nearest GC root\n    Next object java.lang.String#70\n    Next object java.util.Hashtable$Entry#33\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646155f8 number 75 retained size 80\n   References count 1\n   Field value of instance 0x646155e0\n   Path to nearest GC root\n    Next object java.lang.String#71\n    Next object java.util.Hashtable$Entry#33\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615678 number 76 retained size 72\n   References count 1\n   Field value of instance 0x64615660\n   Path to nearest GC root\n    Next object java.lang.String#72\n    Next object java.util.Hashtable$Entry#34\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646156d8 number 77 retained size 56\n   References count 1\n   Field value of instance 0x646156c0\n   Path to nearest GC root\n    Next object java.lang.String#73\n    Next object java.util.Hashtable$Entry#34\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615740 number 78 retained size 48\n   References count 1\n   Field value of instance 0x64615728\n   Path to nearest GC root\n    Next object java.lang.String#74\n    Next object java.util.Hashtable$Entry#35\n    Next object java.util.Hashtable$Entry#41\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615788 number 79 retained size 40\n   References count 1\n   Field value of instance 0x64615770\n   Path to nearest GC root\n    Next object java.lang.String#75\n    Next object java.util.Hashtable$Entry#35\n    Next object java.util.Hashtable$Entry#41\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646157e0 number 80 retained size 40\n   References count 1\n   Field value of instance 0x646157c8\n   Path to nearest GC root\n    Next object java.lang.String#76\n    Next object java.util.Hashtable$Entry#36\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615820 number 81 retained size 64\n   References count 1\n   Field value of instance 0x64615808\n   Path to nearest GC root\n    Next object java.lang.String#77\n    Next object java.util.Hashtable$Entry#36\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615a18 number 82 retained size 40\n   References count 1\n   Field value of instance 0x64615a00\n   Path to nearest GC root\n    Next object java.lang.String#78\n    Next object java.util.Hashtable$Entry#37\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615a58 number 83 retained size 56\n   References count 1\n   Field value of instance 0x64615a40\n   Path to nearest GC root\n    Next object java.lang.String#79\n    Next object java.util.Hashtable$Entry#37\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615ac0 number 84 retained size 40\n   References count 1\n   Field value of instance 0x64615aa8\n   Path to nearest GC root\n    Next object java.lang.String#80\n    Next object java.util.Hashtable$Entry#38\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615b18 number 85 retained size 40\n   References count 1\n   Field value of instance 0x64615b00\n   Path to nearest GC root\n    Next object java.lang.String#81\n    Next object java.util.Hashtable$Entry#39\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615b58 number 86 retained size 128\n   References count 3\n   Field value of instance 0x64615b40\n   Field value of instance 0x64625950\n   Field value of instance 0x64625978\n   Path to nearest GC root\n    Next object java.lang.String#82\n    Next object java.util.Hashtable$Entry#39\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615c08 number 87 retained size 48\n   References count 1\n   Field value of instance 0x64615bf0\n   Path to nearest GC root\n    Next object java.lang.String#83\n    Next object java.util.Hashtable$Entry#40\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615c50 number 88 retained size 88\n   References count 1\n   Field value of instance 0x64615c38\n   Path to nearest GC root\n    Next object java.lang.String#84\n    Next object java.util.Hashtable$Entry#40\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615cd8 number 89 retained size 56\n   References count 1\n   Field value of instance 0x64615cc0\n   Path to nearest GC root\n    Next object java.lang.String#85\n    Next object java.util.Hashtable$Entry#41\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615d28 number 90 retained size 80\n   References count 1\n   Field value of instance 0x64615d10\n   Path to nearest GC root\n    Next object java.lang.String#86\n    Next object java.lang.String[]#43\n    Next object java.lang.Class#101\n  Instance Id 0x64615da8 number 91 retained size 48\n   References count 1\n   Field value of instance 0x64615d90\n   Path to nearest GC root\n    Next object java.lang.String#87\n    Next object java.util.Hashtable$Entry#42\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615df0 number 92 retained size 312\n   References count 7\n   Field value of instance 0x64624f38\n   Field value of instance 0x64624f68\n   Field value of instance 0x64624f80\n   Field value of instance 0x64624f98\n   Field value of instance 0x64615dd8\n   Field value of instance 0x64624fb0\n   Field value of instance 0x64624f50\n   Path to nearest GC root\n    Next object java.lang.String#102\n    Next object java.lang.String[]#42\n    Next object java.lang.Class#101\n  Instance Id 0x64615f58 number 93 retained size 32\n   References count 1\n   Field value of instance 0x64615f40\n   Path to nearest GC root\n    Next object java.lang.String#89\n    Next object java.util.Hashtable$Entry#43\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64615f90 number 94 retained size 56\n   References count 1\n   Field value of instance 0x64615f78\n   Path to nearest GC root\n    Next object java.lang.String#90\n    Next object java.lang.Class#184\n  Instance Id 0x64615ff8 number 95 retained size 48\n   References count 1\n   Field value of instance 0x64615fe0\n   Path to nearest GC root\n    Next object java.lang.String#91\n    Next object java.util.Hashtable$Entry#44\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616040 number 96 retained size 40\n   References count 1\n   Field value of instance 0x64616028\n   Path to nearest GC root\n    Next object java.lang.String#92\n    Next object java.util.Hashtable$Entry#44\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616098 number 97 retained size 56\n   References count 1\n   Field value of instance 0x64616080\n   Path to nearest GC root\n    Next object java.lang.String#93\n    Next object java.util.Hashtable$Entry#45\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646160e8 number 98 retained size 528\n   References count 1\n   Field value of instance 0x646160d0\n   Path to nearest GC root\n    Next object java.lang.String#94\n    Next object java.util.Hashtable$Entry#45\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616328 number 99 retained size 48\n   References count 1\n   Field value of instance 0x64616310\n   Path to nearest GC root\n    Next object java.lang.String#95\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616370 number 100 retained size 40\n   References count 1\n   Field value of instance 0x64616358\n   Path to nearest GC root\n    Next object java.lang.String#96\n    Next object java.util.Hashtable$Entry#46\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646163c8 number 101 retained size 64\n   References count 1\n   Field value of instance 0x646163b0\n   Path to nearest GC root\n    Next object java.lang.String#97\n    Next object java.util.Hashtable$Entry#47\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x64616420 number 102 retained size 64\n   References count 1\n   Field value of instance 0x64616408\n   Path to nearest GC root\n    Next object java.lang.String#98\n    Next object java.util.Hashtable$Entry#47\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646166b0 number 103 retained size 0\n   References count 1\n   Field value of instance 0x64616698\n   Path to nearest GC root\n    Null\n  Instance Id 0x64616e78 number 104 retained size 16\n   References count 1\n   Field value of instance 0x64616e60\n   Path to nearest GC root\n    Next object java.lang.String#100\n    Next object java.lang.Class#270\n  Instance Id 0x64616ea0 number 105 retained size 16\n   References count 1\n   Field value of instance 0x64616e88\n   Path to nearest GC root\n    Next object java.lang.String#101\n    Next object java.lang.Class#270\n  Instance Id 0x6461aee0 number 106 retained size 16400\n   References count 1\n   Field cb of instance 0x64616aa0\n   Path to nearest GC root\n    Next object java.io.BufferedWriter#1\n    Next object java.io.PrintStream#1\n    Next object java.lang.Class#85\n  Instance Id 0x64620f00 number 107 retained size 16400\n   References count 1\n   Field cb of instance 0x64616c78\n   Path to nearest GC root\n    Next object java.io.BufferedWriter#2\n    Next object java.io.PrintStream#2\n    Next object java.lang.Class#85\n  Instance Id 0x64624ff0 number 108 retained size 96\n   References count 2\n   Field value of instance 0x64625160\n   Field value of instance 0x64624fd8\n   Path to nearest GC root\n    Next object java.lang.String#109\n    Next object java.util.LinkedHashMap$Entry#4\n    Next object java.util.LinkedHashMap$Entry#2\n    Next object java.io.ExpiringCache$1#2\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64625190 number 109 retained size 96\n   References count 2\n   Field value of instance 0x64625178\n   Field value of instance 0x64625228\n   Path to nearest GC root\n    Next object java.lang.String#110\n    Next object java.lang.Object[]#9\n    Next object java.util.Vector#1\n    Next object java.lang.Class#101\n  Instance Id 0x64625360 number 110 retained size 88\n   References count 1\n   Field digits of Class java.lang.Integer\n   Path to nearest GC root\n    Next object java.lang.Class#107\n  Instance Id 0x646253b8 number 111 retained size 216\n   References count 1\n   Field DigitTens of Class java.lang.Integer\n   Path to nearest GC root\n    Next object java.lang.Class#107\n  Instance Id 0x64625490 number 112 retained size 216\n   References count 1\n   Field DigitOnes of Class java.lang.Integer\n   Path to nearest GC root\n    Next object java.lang.Class#107\n  Instance Id 0x646258a0 number 113 retained size 56\n   References count 1\n   Field value of instance 0x64625888\n   Path to nearest GC root\n    Next object java.lang.String#112\n    Next object java.util.Hashtable$Entry#38\n    Next object java.util.Hashtable$Entry[]#1\n    Next object java.util.Properties#1\n    Next object java.lang.Class#85\n  Instance Id 0x646258f0 number 114 retained size 48\n   References count 1\n   Field hexDigits of Class sun.security.util.Debug\n   Path to nearest GC root\n    Next object java.lang.Class#329\n  Instance Id 0x64625a60 number 115 retained size 72\n   References count 1\n   Field value of instance 0x64625a48\n   Path to nearest GC root\n    Next object java.lang.String#115\n    Next object java.io.ExpiringCache$Entry#3\n    Next object java.util.LinkedHashMap$Entry#5\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64625af8 number 116 retained size 144\n   References count 1\n   Field value of instance 0x64625ae0\n   Path to nearest GC root\n    Next object java.lang.String#116\n    Next object java.lang.String[]#44\n    Next object sun.misc.MetaIndex#1\n    Next object java.util.HashMap$Entry#1\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625ba0 number 117 retained size 32\n   References count 1\n   Field value of instance 0x64625b88\n   Path to nearest GC root\n    Next object java.lang.String#117\n    Next object java.lang.String[]#44\n    Next object sun.misc.MetaIndex#1\n    Next object java.util.HashMap$Entry#1\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625be8 number 118 retained size 96\n   References count 1\n   Field value of instance 0x64625bd0\n   Path to nearest GC root\n    Next object java.lang.String#118\n    Next object java.io.File#3\n    Next object java.util.HashMap$Entry#1\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625ca0 number 119 retained size 32\n   References count 1\n   Field value of instance 0x64625c88\n   Path to nearest GC root\n    Next object java.lang.String#119\n    Next object java.lang.String[]#45\n    Next object sun.misc.MetaIndex#2\n    Next object java.util.HashMap$Entry#2\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625cd8 number 120 retained size 32\n   References count 1\n   Field value of instance 0x64625cc0\n   Path to nearest GC root\n    Next object java.lang.String#120\n    Next object java.lang.String[]#45\n    Next object sun.misc.MetaIndex#2\n    Next object java.util.HashMap$Entry#2\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625d20 number 121 retained size 104\n   References count 1\n   Field value of instance 0x64625d08\n   Path to nearest GC root\n    Next object java.lang.String#121\n    Next object java.io.File#4\n    Next object java.util.HashMap$Entry#2\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625de0 number 122 retained size 48\n   References count 1\n   Field value of instance 0x64625dc8\n   Path to nearest GC root\n    Next object java.lang.String#122\n    Next object java.lang.String[]#46\n    Next object sun.misc.MetaIndex#3\n    Next object java.util.HashMap$Entry#3\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625e28 number 123 retained size 56\n   References count 1\n   Field value of instance 0x64625e10\n   Path to nearest GC root\n    Next object java.lang.String#123\n    Next object java.lang.String[]#46\n    Next object sun.misc.MetaIndex#3\n    Next object java.util.HashMap$Entry#3\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625e78 number 124 retained size 56\n   References count 1\n   Field value of instance 0x64625e60\n   Path to nearest GC root\n    Next object java.lang.String#124\n    Next object java.lang.String[]#46\n    Next object sun.misc.MetaIndex#3\n    Next object java.util.HashMap$Entry#3\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625ed8 number 125 retained size 112\n   References count 1\n   Field value of instance 0x64625ec0\n   Path to nearest GC root\n    Next object java.lang.String#125\n    Next object java.io.File#5\n    Next object java.util.HashMap$Entry#3\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625fa0 number 126 retained size 40\n   References count 1\n   Field value of instance 0x64625f88\n   Path to nearest GC root\n    Next object java.lang.String#126\n    Next object java.lang.String[]#47\n    Next object sun.misc.MetaIndex#4\n    Next object java.util.HashMap$Entry#4\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64625fe0 number 127 retained size 56\n   References count 1\n   Field value of instance 0x64625fc8\n   Path to nearest GC root\n    Next object java.lang.String#127\n    Next object java.lang.String[]#47\n    Next object sun.misc.MetaIndex#4\n    Next object java.util.HashMap$Entry#4\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64626030 number 128 retained size 56\n   References count 1\n   Field value of instance 0x64626018\n   Path to nearest GC root\n    Next object java.lang.String#128\n    Next object java.lang.String[]#47\n    Next object sun.misc.MetaIndex#4\n    Next object java.util.HashMap$Entry#4\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64626090 number 129 retained size 104\n   References count 1\n   Field value of instance 0x64626078\n   Path to nearest GC root\n    Next object java.lang.String#129\n    Next object java.io.File#6\n    Next object java.util.HashMap$Entry#4\n    Next object java.util.HashMap$Entry[]#5\n    Next object java.util.HashMap#3\n    Next object java.lang.Class#222\n  Instance Id 0x64626198 number 130 retained size 112\n   References count 2\n   Field value of instance 0x64626208\n   Field value of instance 0x64626180\n   Path to nearest GC root\n    Next object java.lang.String#131\n    Next object java.util.LinkedHashMap$Entry#7\n    Next object java.util.LinkedHashMap$Entry#2\n    Next object java.io.ExpiringCache$1#2\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64626238 number 131 retained size 112\n   References count 2\n   Field value of instance 0x646262e0\n   Field value of instance 0x64626220\n   Path to nearest GC root\n    Next object java.lang.String#133\n    Next object java.io.ExpiringCache$Entry#5\n    Next object java.util.LinkedHashMap$Entry#7\n    Next object java.util.LinkedHashMap$Entry#2\n    Next object java.io.ExpiringCache$1#2\n    Next object java.io.ExpiringCache#2\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x646263d0 number 132 retained size 112\n   References count 1\n   Field value of instance 0x646263b8\n   Path to nearest GC root\n    Next object java.lang.String#134\n    Next object java.net.URL#1\n    Next object java.lang.Object[]#304\n    Next object java.util.ArrayList#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646274e8 number 133 retained size 16\n   References count 1\n   Field sharpsMap of Class java.lang.CharacterDataLatin1\n   Path to nearest GC root\n    Next object java.lang.Class#400\n  Instance Id 0x64627a28 number 134 retained size 104\n   References count 1\n   Field value of instance 0x64627a10\n   Path to nearest GC root\n    Next object java.lang.String#135\n    Next object java.io.ExpiringCache$Entry#6\n    Next object java.util.LinkedHashMap$Entry#8\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627aa8 number 135 retained size 104\n   References count 1\n   Field value of instance 0x64627a90\n   Path to nearest GC root\n    Next object java.lang.String#136\n    Next object java.util.LinkedHashMap$Entry#8\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627b60 number 136 retained size 104\n   References count 1\n   Field value of instance 0x64627b48\n   Path to nearest GC root\n    Next object java.lang.String#137\n    Next object java.net.URL#2\n    Next object java.lang.Object[]#304\n    Next object java.util.ArrayList#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64627c18 number 137 retained size 96\n   References count 1\n   Field value of instance 0x64627c00\n   Path to nearest GC root\n    Next object java.lang.String#138\n    Next object java.io.ExpiringCache$Entry#7\n    Next object java.util.LinkedHashMap$Entry#9\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627c90 number 138 retained size 96\n   References count 1\n   Field value of instance 0x64627c78\n   Path to nearest GC root\n    Next object java.lang.String#139\n    Next object java.util.LinkedHashMap$Entry#9\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627d40 number 139 retained size 96\n   References count 1\n   Field value of instance 0x64627d28\n   Path to nearest GC root\n    Next object java.lang.String#140\n    Next object java.net.URL#3\n    Next object java.lang.Object[]#304\n    Next object java.util.ArrayList#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64627df0 number 140 retained size 104\n   References count 1\n   Field value of instance 0x64627dd8\n   Path to nearest GC root\n    Next object java.lang.String#141\n    Next object java.io.ExpiringCache$Entry#8\n    Next object java.util.LinkedHashMap$Entry#10\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627e70 number 141 retained size 104\n   References count 1\n   Field value of instance 0x64627e58\n   Path to nearest GC root\n    Next object java.lang.String#142\n    Next object java.util.LinkedHashMap$Entry#10\n    Next object java.util.HashMap$Entry[]#3\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64627f28 number 142 retained size 104\n   References count 1\n   Field value of instance 0x64627f10\n   Path to nearest GC root\n    Next object java.lang.String#143\n    Next object java.net.URL#4\n    Next object java.lang.Object[]#304\n    Next object java.util.ArrayList#2\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x646284f0 number 143 retained size 48\n   References count 1\n   Field value of instance 0x646284d8\n   Path to nearest GC root\n    Next object java.lang.String#144\n    Next object java.util.LinkedHashMap$Entry#11\n    Next object java.util.LinkedHashMap$Entry#1\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x64628538 number 144 retained size 48\n   References count 1\n   Field value of instance 0x64628520\n   Path to nearest GC root\n    Next object java.lang.String#145\n    Next object java.io.ExpiringCache$Entry#9\n    Next object java.util.LinkedHashMap$Entry#11\n    Next object java.util.LinkedHashMap$Entry#1\n    Next object java.io.ExpiringCache$1#1\n    Next object java.io.ExpiringCache#1\n    Next object java.io.UnixFileSystem#1\n    Next object java.lang.Class#270\n  Instance Id 0x646285b8 number 145 retained size 48\n   References count 1\n   Field value of instance 0x646285a0\n   Path to nearest GC root\n    Next object java.lang.String#146\n    Next object java.net.URL#5\n    Next object java.lang.Object[]#309\n    Next object java.util.ArrayList#4\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64628b00 number 146 retained size 48\n   References count 1\n   Field name of instance 0x64628a88\n   Path to nearest GC root\n    Next object java.lang.Thread#2\n  Instance Id 0x64628bc0 number 147 retained size 0\n   References count 1\n   Field name of instance 0x64628b48\n   Path to nearest GC root\n    Null\n  Instance Id 0x64628c80 number 148 retained size 0\n   References count 1\n   Field name of instance 0x64628c08\n   Path to nearest GC root\n    Null\n  Instance Id 0x64628cd8 number 149 retained size 32\n   References count 1\n   Field src of Class java.util.jar.JarFile\n   Path to nearest GC root\n    Next object java.lang.Class#184\n  Instance Id 0x64628f58 number 150 retained size 0\n   References count 1\n   Field value of instance 0x64628f40\n   Path to nearest GC root\n    Null\n  Instance Id 0x64628fa0 number 151 retained size 0\n   References count 1\n   Field value of instance 0x64628f88\n   Path to nearest GC root\n    Null\n  Instance Id 0x646293d8 number 152 retained size 0\n   References count 1\n   Field value of instance 0x646292a8\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629548 number 153 retained size 0\n   References count 1\n   Field value of instance 0x64629530\n   Path to nearest GC root\n    Null\n  Instance Id 0x646295b8 number 154 retained size 0\n   References count 1\n   Field value of instance 0x646295a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629650 number 155 retained size 0\n   References count 1\n   Field value of instance 0x64629638\n   Path to nearest GC root\n    Null\n  Instance Id 0x646296b8 number 156 retained size 0\n   References count 1\n   Field value of instance 0x646296a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64629708 number 157 retained size 0\n   References count 1\n   Field value of instance 0x646296f0\n   Path to nearest GC root\n    Null\n  Instance Id 0x646299b8 number 158 retained size 0\n   References count 1\n   Field value of instance 0x646299a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x646299d8 number 159 retained size 40\n   References count 2\n   Field value of instance 0x6462a7c0\n   Field value of instance 0x64630ca0\n   Path to nearest GC root\n    Next object java.lang.String#178\n    Next object java.util.HashMap$Entry#22\n    Next object java.util.HashMap$Entry[]#11\n    Next object java.util.HashMap#9\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629af0 number 160 retained size 128\n   References count 1\n   Field value of instance 0x64629ad8\n   Path to nearest GC root\n    Next object java.lang.String#156\n    Next object java.net.URL#6\n    Next object sun.misc.URLClassPath$JarLoader#1\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629c00 number 161 retained size 120\n   References count 1\n   Field value of instance 0x64629be8\n   Path to nearest GC root\n    Next object java.lang.String#157\n    Next object java.net.URL#7\n    Next object sun.misc.URLClassPath$JarLoader#2\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629d08 number 162 retained size 112\n   References count 1\n   Field value of instance 0x64629cf0\n   Path to nearest GC root\n    Next object java.lang.String#158\n    Next object java.net.URL#8\n    Next object sun.misc.URLClassPath$JarLoader#3\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629e08 number 163 retained size 120\n   References count 1\n   Field value of instance 0x64629df0\n   Path to nearest GC root\n    Next object java.lang.String#159\n    Next object java.net.URL#9\n    Next object sun.misc.URLClassPath$JarLoader#4\n    Next object java.lang.Object[]#306\n    Next object java.util.ArrayList#3\n    Next object sun.misc.URLClassPath#1\n    Next object sun.misc.Launcher$ExtClassLoader#1\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629f10 number 164 retained size 64\n   References count 1\n   Field value of instance 0x64629ef8\n   Path to nearest GC root\n    Next object java.lang.String#160\n    Next object java.net.URL#10\n    Next object sun.misc.URLClassPath$JarLoader#5\n    Next object java.lang.Object[]#311\n    Next object java.util.ArrayList#5\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64629f68 number 165 retained size 48\n   References count 1\n   Field value of instance 0x64629f50\n   Path to nearest GC root\n    Next object java.lang.String#161\n    Next object java.util.jar.JarFile#2\n    Next object sun.misc.URLClassPath$JarLoader#5\n    Next object java.lang.Object[]#311\n    Next object java.util.ArrayList#5\n    Next object sun.misc.URLClassPath#2\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x6462a088 number 166 retained size 32\n   References count 1\n   Field value of instance 0x6462a070\n   Path to nearest GC root\n    Next object java.lang.String#162\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a0c0 number 167 retained size 48\n   References count 1\n   Field value of instance 0x6462a0a8\n   Path to nearest GC root\n    Next object java.lang.String#163\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a108 number 168 retained size 32\n   References count 1\n   Field value of instance 0x6462a0f0\n   Path to nearest GC root\n    Next object java.lang.String#164\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a140 number 169 retained size 32\n   References count 1\n   Field value of instance 0x6462a128\n   Path to nearest GC root\n    Next object java.lang.String#165\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a178 number 170 retained size 40\n   References count 1\n   Field value of instance 0x6462a160\n   Path to nearest GC root\n    Next object java.lang.String#166\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a1b8 number 171 retained size 32\n   References count 1\n   Field value of instance 0x6462a1a0\n   Path to nearest GC root\n    Next object java.lang.String#167\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a1f0 number 172 retained size 40\n   References count 1\n   Field value of instance 0x6462a1d8\n   Path to nearest GC root\n    Next object java.lang.String#168\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a230 number 173 retained size 48\n   References count 1\n   Field value of instance 0x6462a218\n   Path to nearest GC root\n    Next object java.lang.String#169\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a278 number 174 retained size 56\n   References count 1\n   Field value of instance 0x6462a260\n   Path to nearest GC root\n    Next object java.lang.String#170\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a2c8 number 175 retained size 40\n   References count 1\n   Field value of instance 0x6462a2b0\n   Path to nearest GC root\n    Next object java.lang.String#171\n    Next object java.lang.String[]#48\n    Next object java.lang.Class#184\n  Instance Id 0x6462a4d8 number 176 retained size 0\n   References count 1\n   Field value of instance 0x6462a450\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a530 number 177 retained size 0\n   References count 1\n   Field value of instance 0x6462a518\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a5a0 number 178 retained size 0\n   References count 1\n   Field value of instance 0x6462a588\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a638 number 179 retained size 0\n   References count 1\n   Field value of instance 0x6462a620\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a6a0 number 180 retained size 0\n   References count 1\n   Field value of instance 0x6462a688\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462a6f0 number 181 retained size 0\n   References count 1\n   Field value of instance 0x6462a6d8\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462aa20 number 182 retained size 72\n   References count 1\n   Field value of instance 0x6462aa68\n   Path to nearest GC root\n    Next object java.lang.String#179\n    Next object java.util.HashMap$Entry#23\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462aac8 number 183 retained size 56\n   References count 1\n   Field value of instance 0x6462ab00\n   Path to nearest GC root\n    Next object java.lang.String#180\n    Next object java.util.HashMap$Entry#25\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ab60 number 184 retained size 32\n   References count 1\n   Field value of instance 0x6462ab80\n   Path to nearest GC root\n    Next object java.lang.String#181\n    Next object java.util.HashMap$Entry#27\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462abe0 number 185 retained size 48\n   References count 1\n   Field value of instance 0x6462ac10\n   Path to nearest GC root\n    Next object java.lang.String#182\n    Next object java.util.HashMap$Entry#29\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ac70 number 186 retained size 32\n   References count 1\n   Field value of instance 0x6462ac90\n   Path to nearest GC root\n    Next object java.lang.String#183\n    Next object java.util.HashMap$Entry#31\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462acf0 number 187 retained size 40\n   References count 1\n   Field value of instance 0x6462ad18\n   Path to nearest GC root\n    Next object java.lang.String#184\n    Next object java.util.HashMap$Entry#33\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ad78 number 188 retained size 40\n   References count 1\n   Field value of instance 0x6462ada0\n   Path to nearest GC root\n    Next object java.lang.String#185\n    Next object java.util.HashMap$Entry#35\n    Next object java.util.HashMap$Entry#42\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ae00 number 189 retained size 32\n   References count 1\n   Field value of instance 0x6462ae20\n   Path to nearest GC root\n    Next object java.lang.String#186\n    Next object java.util.HashMap$Entry#37\n    Next object java.util.HashMap$Entry#39\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ae80 number 190 retained size 48\n   References count 1\n   Field value of instance 0x6462aeb0\n   Path to nearest GC root\n    Next object java.lang.String#187\n    Next object java.util.HashMap$Entry#39\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462af10 number 191 retained size 48\n   References count 1\n   Field value of instance 0x6462af40\n   Path to nearest GC root\n    Next object java.lang.String#188\n    Next object java.util.HashMap$Entry#41\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462afa0 number 192 retained size 48\n   References count 1\n   Field value of instance 0x6462afd0\n   Path to nearest GC root\n    Next object java.lang.String#189\n    Next object java.util.HashMap$Entry#43\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b030 number 193 retained size 32\n   References count 1\n   Field value of instance 0x6462b050\n   Path to nearest GC root\n    Next object java.lang.String#190\n    Next object java.util.HashMap$Entry#45\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b0b0 number 194 retained size 24\n   References count 1\n   Field value of instance 0x6462b0c8\n   Path to nearest GC root\n    Next object java.lang.String#191\n    Next object java.util.HashMap$Entry#47\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b128 number 195 retained size 48\n   References count 1\n   Field value of instance 0x6462b158\n   Path to nearest GC root\n    Next object java.lang.String#192\n    Next object java.util.HashMap$Entry#49\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b1b8 number 196 retained size 24\n   References count 1\n   Field value of instance 0x6462b1d0\n   Path to nearest GC root\n    Next object java.lang.String#193\n    Next object java.util.HashMap$Entry#51\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b230 number 197 retained size 40\n   References count 1\n   Field value of instance 0x6462b258\n   Path to nearest GC root\n    Next object java.lang.String#194\n    Next object java.util.HashMap$Entry#53\n    Next object java.util.HashMap$Entry#40\n    Next object java.util.HashMap$Entry#41\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b2b8 number 198 retained size 40\n   References count 1\n   Field value of instance 0x6462b2e0\n   Path to nearest GC root\n    Next object java.lang.String#195\n    Next object java.util.HashMap$Entry#55\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b340 number 199 retained size 48\n   References count 1\n   Field value of instance 0x6462b370\n   Path to nearest GC root\n    Next object java.lang.String#196\n    Next object java.util.HashMap$Entry#57\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b3d0 number 200 retained size 48\n   References count 1\n   Field value of instance 0x6462b400\n   Path to nearest GC root\n    Next object java.lang.String#197\n    Next object java.util.HashMap$Entry#59\n    Next object java.util.HashMap$Entry#47\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b460 number 201 retained size 32\n   References count 1\n   Field value of instance 0x6462b480\n   Path to nearest GC root\n    Next object java.lang.String#198\n    Next object java.util.HashMap$Entry#61\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b4e0 number 202 retained size 56\n   References count 1\n   Field value of instance 0x6462b518\n   Path to nearest GC root\n    Next object java.lang.String#199\n    Next object java.util.HashMap$Entry#63\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b578 number 203 retained size 48\n   References count 1\n   Field value of instance 0x6462b5a8\n   Path to nearest GC root\n    Next object java.lang.String#200\n    Next object java.util.HashMap$Entry#65\n    Next object java.util.HashMap$Entry#75\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b608 number 204 retained size 48\n   References count 1\n   Field value of instance 0x6462b638\n   Path to nearest GC root\n    Next object java.lang.String#201\n    Next object java.util.HashMap$Entry#67\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b698 number 205 retained size 48\n   References count 1\n   Field value of instance 0x6462b6c8\n   Path to nearest GC root\n    Next object java.lang.String#202\n    Next object java.util.HashMap$Entry#69\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b728 number 206 retained size 24\n   References count 1\n   Field value of instance 0x6462b740\n   Path to nearest GC root\n    Next object java.lang.String#203\n    Next object java.util.HashMap$Entry#71\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462b9b0 number 207 retained size 40\n   References count 1\n   Field value of instance 0x6462b9d8\n   Path to nearest GC root\n    Next object java.lang.String#204\n    Next object java.util.HashMap$Entry#73\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462ba38 number 208 retained size 56\n   References count 1\n   Field value of instance 0x6462ba70\n   Path to nearest GC root\n    Next object java.lang.String#205\n    Next object java.util.HashMap$Entry#75\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bad0 number 209 retained size 40\n   References count 1\n   Field value of instance 0x6462baf8\n   Path to nearest GC root\n    Next object java.lang.String#206\n    Next object java.util.HashMap$Entry#77\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bb58 number 210 retained size 48\n   References count 1\n   Field value of instance 0x6462bb88\n   Path to nearest GC root\n    Next object java.lang.String#207\n    Next object java.util.HashMap$Entry#79\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bbe8 number 211 retained size 48\n   References count 1\n   Field value of instance 0x6462bc18\n   Path to nearest GC root\n    Next object java.lang.String#208\n    Next object java.util.HashMap$Entry#81\n    Next object java.util.HashMap$Entry[]#21\n    Next object java.util.HashMap#19\n    Next object java.lang.Class#328\n  Instance Id 0x6462bce8 number 212 retained size 56\n   References count 1\n   Field value of instance 0x6462bcd0\n   Path to nearest GC root\n    Next object java.lang.String#209\n    Next object java.util.Hashtable$Entry#57\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bd38 number 213 retained size 64\n   References count 1\n   Field value of instance 0x6462bd20\n   Path to nearest GC root\n    Next object java.lang.String#210\n    Next object java.util.Hashtable$Entry#57\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bda8 number 214 retained size 56\n   References count 1\n   Field value of instance 0x6462bd90\n   Path to nearest GC root\n    Next object java.lang.String#211\n    Next object java.util.Hashtable$Entry#58\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bdf8 number 215 retained size 72\n   References count 1\n   Field value of instance 0x6462bde0\n   Path to nearest GC root\n    Next object java.lang.String#212\n    Next object java.util.Hashtable$Entry#58\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462be70 number 216 retained size 56\n   References count 1\n   Field value of instance 0x6462be58\n   Path to nearest GC root\n    Next object java.lang.String#213\n    Next object java.util.Hashtable$Entry#59\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bec0 number 217 retained size 88\n   References count 1\n   Field value of instance 0x6462bea8\n   Path to nearest GC root\n    Next object java.lang.String#214\n    Next object java.util.Hashtable$Entry#59\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bf48 number 218 retained size 56\n   References count 1\n   Field value of instance 0x6462bf30\n   Path to nearest GC root\n    Next object java.lang.String#215\n    Next object java.util.Hashtable$Entry#60\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462bf98 number 219 retained size 72\n   References count 1\n   Field value of instance 0x6462bf80\n   Path to nearest GC root\n    Next object java.lang.String#216\n    Next object java.util.Hashtable$Entry#60\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c010 number 220 retained size 56\n   References count 1\n   Field value of instance 0x6462bff8\n   Path to nearest GC root\n    Next object java.lang.String#217\n    Next object java.util.Hashtable$Entry#61\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c060 number 221 retained size 72\n   References count 1\n   Field value of instance 0x6462c048\n   Path to nearest GC root\n    Next object java.lang.String#218\n    Next object java.util.Hashtable$Entry#61\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c0d8 number 222 retained size 56\n   References count 1\n   Field value of instance 0x6462c0c0\n   Path to nearest GC root\n    Next object java.lang.String#219\n    Next object java.util.Hashtable$Entry#62\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c128 number 223 retained size 72\n   References count 1\n   Field value of instance 0x6462c110\n   Path to nearest GC root\n    Next object java.lang.String#220\n    Next object java.util.Hashtable$Entry#62\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c1a0 number 224 retained size 56\n   References count 1\n   Field value of instance 0x6462c188\n   Path to nearest GC root\n    Next object java.lang.String#221\n    Next object java.util.Hashtable$Entry#63\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c1f0 number 225 retained size 96\n   References count 1\n   Field value of instance 0x6462c1d8\n   Path to nearest GC root\n    Next object java.lang.String#222\n    Next object java.util.Hashtable$Entry#63\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c280 number 226 retained size 56\n   References count 1\n   Field value of instance 0x6462c268\n   Path to nearest GC root\n    Next object java.lang.String#223\n    Next object java.util.Hashtable$Entry#64\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c2d0 number 227 retained size 80\n   References count 1\n   Field value of instance 0x6462c2b8\n   Path to nearest GC root\n    Next object java.lang.String#224\n    Next object java.util.Hashtable$Entry#64\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c350 number 228 retained size 56\n   References count 1\n   Field value of instance 0x6462c338\n   Path to nearest GC root\n    Next object java.lang.String#225\n    Next object java.util.Hashtable$Entry#65\n    Next object java.util.Hashtable$Entry#58\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c3a0 number 229 retained size 48\n   References count 1\n   Field value of instance 0x6462c388\n   Path to nearest GC root\n    Next object java.lang.String#226\n    Next object java.lang.Class#326\n  Instance Id 0x6462c400 number 230 retained size 72\n   References count 1\n   Field value of instance 0x6462c3e8\n   Path to nearest GC root\n    Next object java.lang.String#227\n    Next object java.util.Hashtable$Entry#66\n    Next object java.util.Hashtable$Entry#63\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c460 number 231 retained size 88\n   References count 1\n   Field value of instance 0x6462c448\n   Path to nearest GC root\n    Next object java.lang.String#228\n    Next object java.util.Hashtable$Entry#66\n    Next object java.util.Hashtable$Entry#63\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c4e8 number 232 retained size 48\n   References count 1\n   Field value of instance 0x6462c4d0\n   Path to nearest GC root\n    Next object java.lang.String#229\n    Next object java.util.Hashtable$Entry#67\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c530 number 233 retained size 80\n   References count 1\n   Field value of instance 0x6462c518\n   Path to nearest GC root\n    Next object java.lang.String#230\n    Next object java.util.Hashtable$Entry#67\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c5b0 number 234 retained size 40\n   References count 1\n   Field value of instance 0x6462c598\n   Path to nearest GC root\n    Next object java.lang.String#231\n    Next object java.util.Hashtable$Entry#68\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c5f0 number 235 retained size 96\n   References count 1\n   Field value of instance 0x6462c5d8\n   Path to nearest GC root\n    Next object java.lang.String#232\n    Next object java.util.Hashtable$Entry#68\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c680 number 236 retained size 40\n   References count 1\n   Field value of instance 0x6462c668\n   Path to nearest GC root\n    Next object java.lang.String#233\n    Next object java.util.Hashtable$Entry#69\n    Next object java.util.Hashtable$Entry#71\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c6c0 number 237 retained size 72\n   References count 1\n   Field value of instance 0x6462c6a8\n   Path to nearest GC root\n    Next object java.lang.String#234\n    Next object java.util.Hashtable$Entry#69\n    Next object java.util.Hashtable$Entry#71\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c738 number 238 retained size 64\n   References count 1\n   Field value of instance 0x6462c720\n   Path to nearest GC root\n    Next object java.lang.String#235\n    Next object java.util.Hashtable$Entry#70\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c790 number 239 retained size 24\n   References count 1\n   Field value of instance 0x6462c778\n   Path to nearest GC root\n    Next object java.lang.String#236\n    Next object java.util.Hashtable$Entry#70\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c7d8 number 240 retained size 64\n   References count 1\n   Field value of instance 0x6462c7c0\n   Path to nearest GC root\n    Next object java.lang.String#237\n    Next object java.util.Hashtable$Entry#71\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c830 number 241 retained size 24\n   References count 1\n   Field value of instance 0x6462c818\n   Path to nearest GC root\n    Next object java.lang.String#238\n    Next object java.util.Hashtable$Entry#71\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c878 number 242 retained size 64\n   References count 1\n   Field value of instance 0x6462c860\n   Path to nearest GC root\n    Next object java.lang.String#239\n    Next object java.util.Hashtable$Entry#72\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c8d0 number 243 retained size 24\n   References count 1\n   Field value of instance 0x6462c8b8\n   Path to nearest GC root\n    Next object java.lang.String#240\n    Next object java.util.Hashtable$Entry#72\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c918 number 244 retained size 40\n   References count 1\n   Field value of instance 0x6462c900\n   Path to nearest GC root\n    Next object java.lang.String#241\n    Next object java.util.Hashtable$Entry#73\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c958 number 245 retained size 24\n   References count 1\n   Field value of instance 0x6462c940\n   Path to nearest GC root\n    Next object java.lang.String#242\n    Next object java.util.Hashtable$Entry#73\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c9a0 number 246 retained size 40\n   References count 1\n   Field value of instance 0x6462c988\n   Path to nearest GC root\n    Next object java.lang.String#243\n    Next object java.util.Hashtable$Entry#74\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462c9e0 number 247 retained size 88\n   References count 1\n   Field value of instance 0x6462c9c8\n   Path to nearest GC root\n    Next object java.lang.String#244\n    Next object java.util.Hashtable$Entry#74\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cb30 number 248 retained size 40\n   References count 1\n   Field value of instance 0x6462cb18\n   Path to nearest GC root\n    Next object java.lang.String#245\n    Next object java.util.Hashtable$Entry#75\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cb70 number 249 retained size 24\n   References count 1\n   Field value of instance 0x6462cb58\n   Path to nearest GC root\n    Next object java.lang.String#246\n    Next object java.util.Hashtable$Entry#75\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cbb8 number 250 retained size 80\n   References count 1\n   Field value of instance 0x6462cba0\n   Path to nearest GC root\n    Next object java.lang.String#247\n    Next object java.util.Hashtable$Entry#76\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cc20 number 251 retained size 24\n   References count 1\n   Field value of instance 0x6462cc08\n   Path to nearest GC root\n    Next object java.lang.String#248\n    Next object java.util.Hashtable$Entry#76\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cc68 number 252 retained size 80\n   References count 1\n   Field value of instance 0x6462cc50\n   Path to nearest GC root\n    Next object java.lang.String#249\n    Next object java.util.Hashtable$Entry#77\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462ccd0 number 253 retained size 32\n   References count 1\n   Field value of instance 0x6462ccb8\n   Path to nearest GC root\n    Next object java.lang.String#250\n    Next object java.util.Hashtable$Entry#77\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cd20 number 254 retained size 80\n   References count 1\n   Field value of instance 0x6462cd08\n   Path to nearest GC root\n    Next object java.lang.String#251\n    Next object java.util.Hashtable$Entry#78\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cd88 number 255 retained size 24\n   References count 1\n   Field value of instance 0x6462cd70\n   Path to nearest GC root\n    Next object java.lang.String#252\n    Next object java.util.Hashtable$Entry#78\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462cdd0 number 256 retained size 80\n   References count 1\n   Field value of instance 0x6462cdb8\n   Path to nearest GC root\n    Next object java.lang.String#253\n    Next object java.util.Hashtable$Entry#79\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462ce38 number 257 retained size 16\n   References count 1\n   Field value of instance 0x6462ce20\n   Path to nearest GC root\n    Next object java.lang.String#254\n    Next object java.util.Hashtable$Entry#79\n    Next object java.util.Hashtable$Entry[]#10\n    Next object java.util.Properties#2\n    Next object java.lang.Class#341\n  Instance Id 0x6462d6f0 number 258 retained size 32\n   References count 1\n   Field infinity of Class sun.misc.FloatingDecimal\n   Path to nearest GC root\n    Next object java.lang.Class#394\n  Instance Id 0x6462d710 number 259 retained size 24\n   References count 1\n   Field notANumber of Class sun.misc.FloatingDecimal\n   Path to nearest GC root\n    Next object java.lang.Class#394\n  Instance Id 0x6462d728 number 260 retained size 32\n   References count 1\n   Field zero of Class sun.misc.FloatingDecimal\n   Path to nearest GC root\n    Next object java.lang.Class#394\n  Instance Id 0x6462eef0 number 261 retained size 64\n   References count 1\n   Field value of instance 0x6462ef30\n   Path to nearest GC root\n    Next object java.lang.ThreadLocal$ThreadLocalMap$Entry#3\n    Next object java.lang.ThreadLocal$ThreadLocalMap$Entry[]#1\n    Next object java.lang.ThreadLocal$ThreadLocalMap#1\n    Next object java.lang.Thread#1\n  Instance Id 0x6462ef68 number 262 retained size 24\n   References count 1\n   Field value of instance 0x6462ef50\n   Path to nearest GC root\n    Next object java.lang.String#255\n    Next object java.util.Hashtable$Entry#81\n    Next object java.util.Hashtable$Entry#149\n    Next object java.util.Hashtable$Entry[]#11\n    Next object sun.security.provider.Sun#1\n    Next object java.lang.Class#296\n  Instance Id 0x64630548 number 263 retained size 48\n   References count 1\n   Field hexc of Class sun.security.util.ManifestEntryVerifier\n   Path to nearest GC root\n    Next object java.lang.Class#296\n  Instance Id 0x64630578 number 264 retained size 144\n   References count 1\n   Field pem_array of Class sun.misc.BASE64Decoder\n   Path to nearest GC root\n    Next object java.lang.Class#321\n  Instance Id 0x64630718 number 265 retained size 80\n   References count 1\n   Field value of instance 0x64630768\n   Path to nearest GC root\n    Next object java.lang.String#256\n    Next object java.lang.Class#301\n  Instance Id 0x64630780 number 266 retained size 48\n   References count 1\n   Field hexc of Class sun.security.util.SignatureFileVerifier\n   Path to nearest GC root\n    Next object java.lang.Class#301\n  Instance Id 0x64630938 number 267 retained size 48\n   References count 1\n   Field value of instance 0x64630920\n   Path to nearest GC root\n    Next object java.lang.String#257\n    Next object java.io.FilePermission#1\n    Next object java.lang.Object[]#316\n    Next object java.util.ArrayList#7\n    Next object java.io.FilePermissionCollection#1\n    Next object java.util.HashMap$Entry#153\n    Next object java.util.HashMap$Entry[]#24\n    Next object java.util.HashMap#21\n    Next object java.security.Permissions#1\n    Next object java.security.ProtectionDomain#1\n    Next object java.util.HashMap$Entry#156\n    Next object java.util.HashMap$Entry[]#12\n    Next object java.util.HashMap#10\n    Next object sun.misc.Launcher$AppClassLoader#1\n    Next object java.lang.Class#101\n  Instance Id 0x64630e00 number 268 retained size 0\n   References count 1\n   Field value of instance 0x64630de8\n   Path to nearest GC root\n    Null\n  Instance Id 0x64630e38 number 269 retained size 48\n   References count 1\n   Field name of instance 0x64630d78\n   Path to nearest GC root\n    Next object java.lang.Thread#5\n  Instance Id 0x68133928 number 270 retained size 0\n   References count 1\n   Field value of instance 0x68133910\n   Path to nearest GC root\n    Null\n  Instance Id 0x68133958 number 271 retained size 0\n   References count 1\n   Field value of instance 0x68133940\n   Path to nearest GC root\n    Null\n  Instance Id 0x68133b58 number 272 retained size 0\n   References count 1\n   Field value of instance 0x68133b40\n   Path to nearest GC root\n    Null\n  Instance Id 0x68133bb8 number 273 retained size 0\n   References count 1\n   Field value of instance 0x68133ba0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68134138 number 274 retained size 0\n   References count 1\n   Field value of instance 0x68134120\n   Path to nearest GC root\n    Null\n  Instance Id 0x68134180 number 275 retained size 0\n   References count 1\n   Field value of instance 0x68134168\n   Path to nearest GC root\n    Null\n  Instance Id 0x681341b8 number 276 retained size 0\n   References count 1\n   Field value of instance 0x681341a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681341e8 number 277 retained size 0\n   References count 1\n   Field value of instance 0x681341d0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68134220 number 278 retained size 0\n   References count 1\n   Field value of instance 0x68134208\n   Path to nearest GC root\n    Null\n  Instance Id 0x68134d68 number 279 retained size 0\n   References count 1\n   Field value of instance 0x68134d50\n   Path to nearest GC root\n    Null\n  Instance Id 0x681396d0 number 280 retained size 16\n   References count 1\n   Field value of instance 0x681396b8\n   Path to nearest GC root\n    Next object java.lang.String#270\n    Next object java.io.ObjectStreamField#1\n    Next object java.io.ObjectStreamField[]#3\n    Next object java.lang.Class#228\n  Instance Id 0x68139c80 number 281 retained size 0\n   References count 1\n   Field value of instance 0x68139c68\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139cd8 number 282 retained size 0\n   References count 1\n   Field value of instance 0x68139cc0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139d18 number 283 retained size 0\n   References count 1\n   Field value of instance 0x68139d00\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139d50 number 284 retained size 0\n   References count 1\n   Field value of instance 0x68139d38\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139d88 number 285 retained size 0\n   References count 1\n   Field value of instance 0x68139d70\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139dd0 number 286 retained size 0\n   References count 1\n   Field value of instance 0x68139db8\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139e08 number 287 retained size 0\n   References count 1\n   Field value of instance 0x68139df0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139e38 number 288 retained size 0\n   References count 1\n   Field value of instance 0x68139e20\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139e70 number 289 retained size 0\n   References count 1\n   Field value of instance 0x68139e58\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139ea0 number 290 retained size 0\n   References count 1\n   Field value of instance 0x68139e88\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139ed8 number 291 retained size 0\n   References count 1\n   Field value of instance 0x68139ec0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139f08 number 292 retained size 0\n   References count 1\n   Field value of instance 0x68139ef0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139f38 number 293 retained size 0\n   References count 1\n   Field value of instance 0x68139f20\n   Path to nearest GC root\n    Null\n  Instance Id 0x68139f68 number 294 retained size 0\n   References count 1\n   Field value of instance 0x68139f50\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813a2f8 number 295 retained size 0\n   References count 1\n   Field value of instance 0x6813a2e0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813a340 number 296 retained size 0\n   References count 1\n   Field value of instance 0x6813a328\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813a380 number 297 retained size 0\n   References count 1\n   Field value of instance 0x6813a368\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813a3b8 number 298 retained size 0\n   References count 1\n   Field value of instance 0x6813a3a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813ac20 number 299 retained size 0\n   References count 1\n   Field value of instance 0x6813ac08\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813ac70 number 300 retained size 56\n   References count 1\n   Field value of instance 0x6813ac58\n   Path to nearest GC root\n    Next object java.lang.String#290\n    Next object java.io.ObjectStreamField#5\n    Next object java.io.ObjectStreamField[]#6\n    Next object java.lang.Class#246\n  Instance Id 0x6813acc0 number 301 retained size 0\n   References count 1\n   Field value of instance 0x6813aca8\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813ad28 number 302 retained size 88\n   References count 1\n   Field value of instance 0x6813ad10\n   Path to nearest GC root\n    Next object java.lang.String#292\n    Next object java.io.ObjectStreamField#6\n    Next object java.io.ObjectStreamField[]#6\n    Next object java.lang.Class#246\n  Instance Id 0x6813ad98 number 303 retained size 0\n   References count 1\n   Field value of instance 0x6813ad80\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813ade0 number 304 retained size 48\n   References count 1\n   Field value of instance 0x6813adc8\n   Path to nearest GC root\n    Next object java.lang.String#294\n    Next object java.io.ObjectStreamField#7\n    Next object java.io.ObjectStreamField[]#7\n    Next object java.lang.Class#376\n  Instance Id 0x6813ae28 number 305 retained size 0\n   References count 1\n   Field value of instance 0x6813ae10\n   Path to nearest GC root\n    Null\n Id 0x6c9394e0 Class int[] SuperClass java.lang.Object Instance size -1 Instance count 19 All Instances Size 2592\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64614f68 number 1 retained size 56\n   References count 1\n   Field sizeTable of Class java.lang.AbstractStringBuilder\n   Path to nearest GC root\n    Next object java.lang.Class#214\n  Instance Id 0x64625568 number 2 retained size 56\n   References count 1\n   Field sizeTable of Class java.lang.Integer\n   Path to nearest GC root\n    Next object java.lang.Class#107\n  Instance Id 0x64625990 number 3 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x646274f8 number 4 retained size 1040\n   References count 1\n   Field A of Class java.lang.CharacterDataLatin1\n   Path to nearest GC root\n    Next object java.lang.Class#400\n  Instance Id 0x64628cf8 number 5 retained size 528\n   References count 1\n   Field lastOcc of Class java.util.jar.JarFile\n   Path to nearest GC root\n    Next object java.lang.Class#184\n  Instance Id 0x64628f08 number 6 retained size 56\n   References count 1\n   Field optoSft of Class java.util.jar.JarFile\n   Path to nearest GC root\n    Next object java.lang.Class#184\n  Instance Id 0x6462bc90 number 7 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6462d548 number 8 retained size 72\n   References count 1\n   Field small5pow of Class sun.misc.FloatingDecimal\n   Path to nearest GC root\n    Next object java.lang.Class#394\n  Instance Id 0x6462d678 number 9 retained size 120\n   References count 1\n   Field n5bits of Class sun.misc.FloatingDecimal\n   Path to nearest GC root\n    Next object java.lang.Class#394\n  Instance Id 0x68132ff8 number 10 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681330c8 number 11 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681346b0 number 12 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681349c8 number 13 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68136070 number 14 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68136260 number 15 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681368b8 number 16 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68137f50 number 17 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68138900 number 18 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813b3f8 number 19 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n Id 0x6c939480 Class short[] SuperClass java.lang.Object Instance size -1 Instance count 23 All Instances Size 992\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64610250 number 1 retained size 0\n   References count 1\n   Element 1 of array 0x646101a8\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610348 number 2 retained size 0\n   References count 1\n   Element 1 of array 0x646102a0\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610440 number 3 retained size 0\n   References count 1\n   Element 1 of array 0x64610398\n   Path to nearest GC root\n    Null\n  Instance Id 0x64610538 number 4 retained size 0\n   References count 1\n   Element 1 of array 0x64610490\n   Path to nearest GC root\n    Null\n  Instance Id 0x68132418 number 5 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681344b0 number 6 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68134f68 number 7 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681351a8 number 8 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681354c0 number 9 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68135d10 number 10 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68137170 number 11 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68137650 number 12 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68137920 number 13 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68137cc0 number 14 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68137e88 number 15 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681381c0 number 16 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68138570 number 17 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x68138f68 number 18 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681391a8 number 19 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x681394a0 number 20 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813a808 number 21 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813ab90 number 22 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n  Instance Id 0x6813b320 number 23 retained size 0\n   References count 0\n   Path to nearest GC root\n    Null\n Id 0x6c939540 Class long[] SuperClass java.lang.Object Instance size -1 Instance count 2 All Instances Size 280\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x64626388 number 1 retained size 48\n   References count 1\n   Field words of instance 0x64626370\n   Path to nearest GC root\n    Next object java.util.BitSet#1\n    Next object java.lang.Class#197\n  Instance Id 0x6462d590 number 2 retained size 232\n   References count 1\n   Field long5pow of Class sun.misc.FloatingDecimal\n   Path to nearest GC root\n    Next object java.lang.Class#394\n Id 0x6c939360 Class float[] SuperClass java.lang.Object Instance size -1 Instance count 1 All Instances Size 56\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462d4a0 number 1 retained size 56\n   References count 1\n   Field singleSmall10pow of Class sun.misc.FloatingDecimal\n   Path to nearest GC root\n    Next object java.lang.Class#394\n Id 0x6c9393c0 Class double[] SuperClass java.lang.Object Instance size -1 Instance count 3 All Instances Size 312\n  Static Field name <classLoader> type object value 0\n  Instance Id 0x6462d3d8 number 1 retained size 200\n   References count 1\n   Field small10pow of Class sun.misc.FloatingDecimal\n   Path to nearest GC root\n    Next object java.lang.Class#394\n  Instance Id 0x6462d4d8 number 2 retained size 56\n   References count 1\n   Field big10pow of Class sun.misc.FloatingDecimal\n   Path to nearest GC root\n    Next object java.lang.Class#394\n  Instance Id 0x6462d510 number 3 retained size 56\n   References count 1\n   Field tiny10pow of Class sun.misc.FloatingDecimal\n   Path to nearest GC root\n    Next object java.lang.Class#394\nGC roots 491\nRoot kind JNI global Class java.lang.String#41\nRoot kind JNI global Class java.lang.Class#95\nRoot kind JNI global Class java.lang.Class#161\nRoot kind JNI global Class java.lang.Class#88\nRoot kind JNI global Class java.lang.Class#99\nRoot kind JNI global Class java.lang.Class#155\nRoot kind JNI global Class java.lang.Class#154\nRoot kind JNI global Class java.lang.Class#147\nRoot kind JNI global Class java.lang.Class#86\nRoot kind JNI global Class java.lang.Class#148\nRoot kind JNI global Class java.lang.Class#92\nRoot kind JNI global Class java.lang.Class#157\nRoot kind JNI global Class java.lang.Class#167\nRoot kind JNI global Class java.lang.Class#162\nRoot kind JNI global Class java.lang.Class#95\nRoot kind Java frame Class java.lang.ref.ReferenceQueue#2\nRoot kind Java frame Class java.lang.ref.ReferenceQueue$Lock#4\nRoot kind Java frame Class java.lang.ref.ReferenceQueue#2\nRoot kind Java frame Class java.lang.ref.Finalizer$FinalizerThread#1\nRoot kind Java frame Class java.lang.ref.Reference$Lock#1\nRoot kind Java frame Class java.lang.ref.Reference$ReferenceHandler#1\nRoot kind Java frame Class java.lang.ref.Reference$Lock#1\nRoot kind Java frame Class java.lang.String[]#49\nRoot kind sticky class Class java.lang.Class#95\nRoot kind sticky class Class java.lang.Class#88\nRoot kind sticky class Class java.lang.Class#86\nRoot kind sticky class Class java.lang.Class#94\nRoot kind sticky class Class java.lang.Class#101\nRoot kind sticky class Class java.lang.Class#138\nRoot kind sticky class Class java.lang.Class#85\nRoot kind sticky class Class java.lang.Class#99\nRoot kind sticky class Class java.lang.Class#157\nRoot kind sticky class Class java.lang.Class#98\nRoot kind sticky class Class java.lang.Class#155\nRoot kind sticky class Class java.lang.Class#154\nRoot kind sticky class Class java.lang.Class#149\nRoot kind sticky class Class java.lang.Class#160\nRoot kind sticky class Class java.lang.Class#152\nRoot kind sticky class Class java.lang.Class#148\nRoot kind sticky class Class java.lang.Class#147\nRoot kind sticky class Class java.lang.Class#167\nRoot kind sticky class Class java.lang.Class#162\nRoot kind sticky class Class java.lang.Class#166\nRoot kind sticky class Class java.lang.Class#150\nRoot kind sticky class Class java.lang.Class#134\nRoot kind sticky class Class java.lang.Class#129\nRoot kind sticky class Class java.lang.Class#116\nRoot kind sticky class Class java.lang.Class#115\nRoot kind sticky class Class java.lang.Class#113\nRoot kind sticky class Class java.lang.Class#120\nRoot kind sticky class Class java.lang.Class#119\nRoot kind sticky class Class java.lang.Class#118\nRoot kind sticky class Class java.lang.Class#92\nRoot kind sticky class Class java.lang.Class#90\nRoot kind sticky class Class java.lang.Class#142\nRoot kind sticky class Class java.lang.Class#124\nRoot kind sticky class Class java.lang.Class#127\nRoot kind sticky class Class java.lang.Class#123\nRoot kind sticky class Class java.lang.Class#121\nRoot kind sticky class Class java.lang.Class#186\nRoot kind sticky class Class java.lang.Class#188\nRoot kind sticky class Class java.lang.Class#187\nRoot kind sticky class Class java.lang.Class#190\nRoot kind sticky class Class java.lang.Class#193\nRoot kind sticky class Class java.lang.Class#192\nRoot kind sticky class Class java.lang.Class#126\nRoot kind sticky class Class java.lang.Class#140\nRoot kind sticky class Class java.lang.Class#143\nRoot kind sticky class Class java.lang.Class#164\nRoot kind sticky class Class java.lang.Class#177\nRoot kind sticky class Class java.lang.Class#176\nRoot kind sticky class Class java.lang.Class#105\nRoot kind sticky class Class java.lang.Class#104\nRoot kind sticky class Class java.lang.Class#103\nRoot kind sticky class Class java.lang.Class#102\nRoot kind sticky class Class java.lang.Class#109\nRoot kind sticky class Class java.lang.Class#108\nRoot kind sticky class Class java.lang.Class#107\nRoot kind sticky class Class java.lang.Class#106\nRoot kind sticky class Class java.lang.Class#105\nRoot kind sticky class Class java.lang.Class#104\nRoot kind sticky class Class java.lang.Class#103\nRoot kind sticky class Class java.lang.Class#102\nRoot kind sticky class Class java.lang.Class#109\nRoot kind sticky class Class java.lang.Class#108\nRoot kind sticky class Class java.lang.Class#107\nRoot kind sticky class Class java.lang.Class#106\nRoot kind sticky class Class java.lang.Class#99\nRoot kind sticky class Class java.lang.Class#193\nRoot kind sticky class Class java.lang.Class#192\nRoot kind sticky class Class java.lang.Class#1\nRoot kind sticky class Class java.lang.Class#2\nRoot kind sticky class Class java.lang.Class#3\nRoot kind sticky class Class java.lang.Class#4\nRoot kind sticky class Class java.lang.Class#5\nRoot kind sticky class Class java.lang.Class#6\nRoot kind sticky class Class java.lang.Class#8\nRoot kind sticky class Class java.lang.Class#9\nRoot kind sticky class Class java.lang.Class#10\nRoot kind sticky class Class java.lang.Class#11\nRoot kind sticky class Class java.lang.Class#12\nRoot kind sticky class Class java.lang.Class#13\nRoot kind sticky class Class java.lang.Class#14\nRoot kind sticky class Class java.lang.Class#15\nRoot kind sticky class Class java.lang.Class#16\nRoot kind sticky class Class java.lang.Class#17\nRoot kind sticky class Class java.lang.Class#18\nRoot kind sticky class Class java.lang.Class#19\nRoot kind sticky class Class java.lang.Class#20\nRoot kind sticky class Class java.lang.Class#21\nRoot kind sticky class Class java.lang.Class#22\nRoot kind sticky class Class java.lang.Class#23\nRoot kind sticky class Class java.lang.Class#24\nRoot kind sticky class Class java.lang.Class#25\nRoot kind sticky class Class java.lang.Class#27\nRoot kind sticky class Class java.lang.Class#28\nRoot kind sticky class Class java.lang.Class#29\nRoot kind sticky class Class java.lang.Class#31\nRoot kind sticky class Class java.lang.Class#32\nRoot kind sticky class Class java.lang.Class#33\nRoot kind sticky class Class java.lang.Class#34\nRoot kind sticky class Class java.lang.Class#35\nRoot kind sticky class Class java.lang.Class#36\nRoot kind sticky class Class java.lang.Class#37\nRoot kind sticky class Class java.lang.Class#38\nRoot kind sticky class Class java.lang.Class#39\nRoot kind sticky class Class java.lang.Class#40\nRoot kind sticky class Class java.lang.Class#41\nRoot kind sticky class Class java.lang.Class#42\nRoot kind sticky class Class java.lang.Class#43\nRoot kind sticky class Class java.lang.Class#44\nRoot kind sticky class Class java.lang.Class#45\nRoot kind sticky class Class java.lang.Class#46\nRoot kind sticky class Class java.lang.Class#47\nRoot kind sticky class Class java.lang.Class#48\nRoot kind sticky class Class java.lang.Class#49\nRoot kind sticky class Class java.lang.Class#50\nRoot kind sticky class Class java.lang.Class#51\nRoot kind sticky class Class java.lang.Class#52\nRoot kind sticky class Class java.lang.Class#53\nRoot kind sticky class Class java.lang.Class#54\nRoot kind sticky class Class java.lang.Class#55\nRoot kind sticky class Class java.lang.Class#56\nRoot kind sticky class Class java.lang.Class#57\nRoot kind sticky class Class java.lang.Class#58\nRoot kind sticky class Class java.lang.Class#59\nRoot kind sticky class Class java.lang.Class#60\nRoot kind sticky class Class java.lang.Class#61\nRoot kind sticky class Class java.lang.Class#62\nRoot kind sticky class Class java.lang.Class#63\nRoot kind sticky class Class java.lang.Class#64\nRoot kind sticky class Class java.lang.Class#65\nRoot kind sticky class Class java.lang.Class#66\nRoot kind sticky class Class java.lang.Class#67\nRoot kind sticky class Class java.lang.Class#68\nRoot kind sticky class Class java.lang.Class#69\nRoot kind sticky class Class java.lang.Class#70\nRoot kind sticky class Class java.lang.Class#71\nRoot kind sticky class Class java.lang.Class#72\nRoot kind sticky class Class java.lang.Class#73\nRoot kind sticky class Class java.lang.Class#74\nRoot kind sticky class Class java.lang.Class#75\nRoot kind sticky class Class java.lang.Class#76\nRoot kind sticky class Class java.lang.Class#77\nRoot kind sticky class Class java.lang.Class#78\nRoot kind sticky class Class java.lang.Class#79\nRoot kind sticky class Class java.lang.Class#80\nRoot kind sticky class Class java.lang.Class#81\nRoot kind sticky class Class java.lang.Class#82\nRoot kind sticky class Class java.lang.Class#83\nRoot kind sticky class Class java.lang.Class#84\nRoot kind sticky class Class java.lang.Class#85\nRoot kind sticky class Class java.lang.Class#86\nRoot kind sticky class Class java.lang.Class#88\nRoot kind sticky class Class java.lang.Class#90\nRoot kind sticky class Class java.lang.Class#92\nRoot kind sticky class Class java.lang.Class#94\nRoot kind sticky class Class java.lang.Class#95\nRoot kind sticky class Class java.lang.Class#97\nRoot kind sticky class Class java.lang.Class#98\nRoot kind sticky class Class java.lang.Class#99\nRoot kind sticky class Class java.lang.Class#101\nRoot kind sticky class Class java.lang.Class#102\nRoot kind sticky class Class java.lang.Class#103\nRoot kind sticky class Class java.lang.Class#104\nRoot kind sticky class Class java.lang.Class#105\nRoot kind sticky class Class java.lang.Class#106\nRoot kind sticky class Class java.lang.Class#107\nRoot kind sticky class Class java.lang.Class#108\nRoot kind sticky class Class java.lang.Class#109\nRoot kind sticky class Class java.lang.Class#110\nRoot kind sticky class Class java.lang.Class#111\nRoot kind sticky class Class java.lang.Class#112\nRoot kind sticky class Class java.lang.Class#113\nRoot kind sticky class Class java.lang.Class#115\nRoot kind sticky class Class java.lang.Class#116\nRoot kind sticky class Class java.lang.Class#118\nRoot kind sticky class Class java.lang.Class#119\nRoot kind sticky class Class java.lang.Class#120\nRoot kind sticky class Class java.lang.Class#121\nRoot kind sticky class Class java.lang.Class#123\nRoot kind sticky class Class java.lang.Class#124\nRoot kind sticky class Class java.lang.Class#126\nRoot kind sticky class Class java.lang.Class#127\nRoot kind sticky class Class java.lang.Class#129\nRoot kind sticky class Class java.lang.Class#130\nRoot kind sticky class Class java.lang.Class#132\nRoot kind sticky class Class java.lang.Class#133\nRoot kind sticky class Class java.lang.Class#134\nRoot kind sticky class Class java.lang.Class#135\nRoot kind sticky class Class java.lang.Class#136\nRoot kind sticky class Class java.lang.Class#137\nRoot kind sticky class Class java.lang.Class#138\nRoot kind sticky class Class java.lang.Class#140\nRoot kind sticky class Class java.lang.Class#141\nRoot kind sticky class Class java.lang.Class#142\nRoot kind sticky class Class java.lang.Class#143\nRoot kind sticky class Class java.lang.Class#144\nRoot kind sticky class Class java.lang.Class#145\nRoot kind sticky class Class java.lang.Class#146\nRoot kind sticky class Class java.lang.Class#147\nRoot kind sticky class Class java.lang.Class#148\nRoot kind sticky class Class java.lang.Class#149\nRoot kind sticky class Class java.lang.Class#150\nRoot kind sticky class Class java.lang.Class#151\nRoot kind sticky class Class java.lang.Class#152\nRoot kind sticky class Class java.lang.Class#153\nRoot kind sticky class Class java.lang.Class#154\nRoot kind sticky class Class java.lang.Class#155\nRoot kind sticky class Class java.lang.Class#156\nRoot kind sticky class Class java.lang.Class#157\nRoot kind sticky class Class java.lang.Class#159\nRoot kind sticky class Class java.lang.Class#160\nRoot kind sticky class Class java.lang.Class#161\nRoot kind sticky class Class java.lang.Class#162\nRoot kind sticky class Class java.lang.Class#164\nRoot kind sticky class Class java.lang.Class#166\nRoot kind sticky class Class java.lang.Class#167\nRoot kind sticky class Class java.lang.Class#169\nRoot kind sticky class Class java.lang.Class#170\nRoot kind sticky class Class java.lang.Class#171\nRoot kind sticky class Class java.lang.Class#172\nRoot kind sticky class Class java.lang.Class#173\nRoot kind sticky class Class java.lang.Class#174\nRoot kind sticky class Class java.lang.Class#175\nRoot kind sticky class Class java.lang.Class#176\nRoot kind sticky class Class java.lang.Class#177\nRoot kind sticky class Class java.lang.Class#178\nRoot kind sticky class Class java.lang.Class#179\nRoot kind sticky class Class java.lang.Class#180\nRoot kind sticky class Class java.lang.Class#181\nRoot kind sticky class Class java.lang.Class#182\nRoot kind sticky class Class java.lang.Class#183\nRoot kind sticky class Class java.lang.Class#184\nRoot kind sticky class Class java.lang.Class#185\nRoot kind sticky class Class java.lang.Class#186\nRoot kind sticky class Class java.lang.Class#187\nRoot kind sticky class Class java.lang.Class#188\nRoot kind sticky class Class java.lang.Class#189\nRoot kind sticky class Class java.lang.Class#190\nRoot kind sticky class Class java.lang.Class#191\nRoot kind sticky class Class java.lang.Class#192\nRoot kind sticky class Class java.lang.Class#193\nRoot kind sticky class Class java.lang.Class#194\nRoot kind sticky class Class java.lang.Class#195\nRoot kind sticky class Class java.lang.Class#196\nRoot kind sticky class Class java.lang.Class#197\nRoot kind sticky class Class java.lang.Class#198\nRoot kind sticky class Class java.lang.Class#199\nRoot kind sticky class Class java.lang.Class#200\nRoot kind sticky class Class java.lang.Class#201\nRoot kind sticky class Class java.lang.Class#202\nRoot kind sticky class Class java.lang.Class#203\nRoot kind sticky class Class java.lang.Class#204\nRoot kind sticky class Class java.lang.Class#205\nRoot kind sticky class Class java.lang.Class#206\nRoot kind sticky class Class java.lang.Class#207\nRoot kind sticky class Class java.lang.Class#208\nRoot kind sticky class Class java.lang.Class#209\nRoot kind sticky class Class java.lang.Class#210\nRoot kind sticky class Class java.lang.Class#211\nRoot kind sticky class Class java.lang.Class#212\nRoot kind sticky class Class java.lang.Class#214\nRoot kind sticky class Class java.lang.Class#215\nRoot kind sticky class Class java.lang.Class#217\nRoot kind sticky class Class java.lang.Class#218\nRoot kind sticky class Class java.lang.Class#219\nRoot kind sticky class Class java.lang.Class#220\nRoot kind sticky class Class java.lang.Class#221\nRoot kind sticky class Class java.lang.Class#222\nRoot kind sticky class Class java.lang.Class#223\nRoot kind sticky class Class java.lang.Class#224\nRoot kind sticky class Class java.lang.Class#225\nRoot kind sticky class Class java.lang.Class#226\nRoot kind sticky class Class java.lang.Class#227\nRoot kind sticky class Class java.lang.Class#228\nRoot kind sticky class Class java.lang.Class#229\nRoot kind sticky class Class java.lang.Class#230\nRoot kind sticky class Class java.lang.Class#231\nRoot kind sticky class Class java.lang.Class#232\nRoot kind sticky class Class java.lang.Class#233\nRoot kind sticky class Class java.lang.Class#234\nRoot kind sticky class Class java.lang.Class#235\nRoot kind sticky class Class java.lang.Class#236\nRoot kind sticky class Class java.lang.Class#238\nRoot kind sticky class Class java.lang.Class#240\nRoot kind sticky class Class java.lang.Class#241\nRoot kind sticky class Class java.lang.Class#243\nRoot kind sticky class Class java.lang.Class#244\nRoot kind sticky class Class java.lang.Class#246\nRoot kind sticky class Class java.lang.Class#247\nRoot kind sticky class Class java.lang.Class#248\nRoot kind sticky class Class java.lang.Class#249\nRoot kind sticky class Class java.lang.Class#250\nRoot kind sticky class Class java.lang.Class#251\nRoot kind sticky class Class java.lang.Class#252\nRoot kind sticky class Class java.lang.Class#253\nRoot kind sticky class Class java.lang.Class#254\nRoot kind sticky class Class java.lang.Class#256\nRoot kind sticky class Class java.lang.Class#257\nRoot kind sticky class Class java.lang.Class#258\nRoot kind sticky class Class java.lang.Class#259\nRoot kind sticky class Class java.lang.Class#260\nRoot kind sticky class Class java.lang.Class#261\nRoot kind sticky class Class java.lang.Class#262\nRoot kind sticky class Class java.lang.Class#263\nRoot kind sticky class Class java.lang.Class#265\nRoot kind sticky class Class java.lang.Class#266\nRoot kind sticky class Class java.lang.Class#268\nRoot kind sticky class Class java.lang.Class#269\nRoot kind sticky class Class java.lang.Class#270\nRoot kind sticky class Class java.lang.Class#272\nRoot kind sticky class Class java.lang.Class#273\nRoot kind sticky class Class java.lang.Class#275\nRoot kind sticky class Class java.lang.Class#277\nRoot kind sticky class Class java.lang.Class#278\nRoot kind sticky class Class java.lang.Class#279\nRoot kind sticky class Class java.lang.Class#280\nRoot kind sticky class Class java.lang.Class#281\nRoot kind sticky class Class java.lang.Class#282\nRoot kind sticky class Class java.lang.Class#284\nRoot kind sticky class Class java.lang.Class#286\nRoot kind sticky class Class java.lang.Class#287\nRoot kind sticky class Class java.lang.Class#288\nRoot kind sticky class Class java.lang.Class#289\nRoot kind sticky class Class java.lang.Class#290\nRoot kind sticky class Class java.lang.Class#291\nRoot kind sticky class Class java.lang.Class#292\nRoot kind sticky class Class java.lang.Class#293\nRoot kind sticky class Class java.lang.Class#294\nRoot kind sticky class Class java.lang.Class#295\nRoot kind sticky class Class java.lang.Class#296\nRoot kind sticky class Class java.lang.Class#297\nRoot kind sticky class Class java.lang.Class#298\nRoot kind sticky class Class java.lang.Class#299\nRoot kind sticky class Class java.lang.Class#300\nRoot kind sticky class Class java.lang.Class#301\nRoot kind sticky class Class java.lang.Class#302\nRoot kind sticky class Class java.lang.Class#303\nRoot kind sticky class Class java.lang.Class#304\nRoot kind sticky class Class java.lang.Class#305\nRoot kind sticky class Class java.lang.Class#306\nRoot kind sticky class Class java.lang.Class#307\nRoot kind sticky class Class java.lang.Class#308\nRoot kind sticky class Class java.lang.Class#309\nRoot kind sticky class Class java.lang.Class#310\nRoot kind sticky class Class java.lang.Class#311\nRoot kind sticky class Class java.lang.Class#312\nRoot kind sticky class Class java.lang.Class#313\nRoot kind sticky class Class java.lang.Class#314\nRoot kind sticky class Class java.lang.Class#315\nRoot kind sticky class Class java.lang.Class#316\nRoot kind sticky class Class java.lang.Class#317\nRoot kind sticky class Class java.lang.Class#318\nRoot kind sticky class Class java.lang.Class#319\nRoot kind sticky class Class java.lang.Class#320\nRoot kind sticky class Class java.lang.Class#321\nRoot kind sticky class Class java.lang.Class#322\nRoot kind sticky class Class java.lang.Class#323\nRoot kind sticky class Class java.lang.Class#325\nRoot kind sticky class Class java.lang.Class#326\nRoot kind sticky class Class java.lang.Class#327\nRoot kind sticky class Class java.lang.Class#328\nRoot kind sticky class Class java.lang.Class#329\nRoot kind sticky class Class java.lang.Class#330\nRoot kind sticky class Class java.lang.Class#331\nRoot kind sticky class Class java.lang.Class#332\nRoot kind sticky class Class java.lang.Class#333\nRoot kind sticky class Class java.lang.Class#334\nRoot kind sticky class Class java.lang.Class#335\nRoot kind sticky class Class java.lang.Class#336\nRoot kind sticky class Class java.lang.Class#337\nRoot kind sticky class Class java.lang.Class#338\nRoot kind sticky class Class java.lang.Class#339\nRoot kind sticky class Class java.lang.Class#340\nRoot kind sticky class Class java.lang.Class#341\nRoot kind sticky class Class java.lang.Class#342\nRoot kind sticky class Class java.lang.Class#343\nRoot kind sticky class Class java.lang.Class#344\nRoot kind sticky class Class java.lang.Class#345\nRoot kind sticky class Class java.lang.Class#346\nRoot kind sticky class Class java.lang.Class#347\nRoot kind sticky class Class java.lang.Class#348\nRoot kind sticky class Class java.lang.Class#349\nRoot kind sticky class Class java.lang.Class#350\nRoot kind sticky class Class java.lang.Class#352\nRoot kind sticky class Class java.lang.Class#353\nRoot kind sticky class Class java.lang.Class#354\nRoot kind sticky class Class java.lang.Class#356\nRoot kind sticky class Class java.lang.Class#357\nRoot kind sticky class Class java.lang.Class#358\nRoot kind sticky class Class java.lang.Class#359\nRoot kind sticky class Class java.lang.Class#360\nRoot kind sticky class Class java.lang.Class#361\nRoot kind sticky class Class java.lang.Class#362\nRoot kind sticky class Class java.lang.Class#363\nRoot kind sticky class Class java.lang.Class#364\nRoot kind sticky class Class java.lang.Class#365\nRoot kind sticky class Class java.lang.Class#366\nRoot kind sticky class Class java.lang.Class#367\nRoot kind sticky class Class java.lang.Class#368\nRoot kind sticky class Class java.lang.Class#369\nRoot kind sticky class Class java.lang.Class#370\nRoot kind sticky class Class java.lang.Class#371\nRoot kind sticky class Class java.lang.Class#372\nRoot kind sticky class Class java.lang.Class#374\nRoot kind sticky class Class java.lang.Class#375\nRoot kind sticky class Class java.lang.Class#376\nRoot kind sticky class Class java.lang.Class#377\nRoot kind sticky class Class java.lang.Class#378\nRoot kind sticky class Class java.lang.Class#379\nRoot kind sticky class Class java.lang.Class#380\nRoot kind sticky class Class java.lang.Class#381\nRoot kind sticky class Class java.lang.Class#383\nRoot kind sticky class Class java.lang.Class#384\nRoot kind sticky class Class java.lang.Class#385\nRoot kind sticky class Class java.lang.Class#386\nRoot kind sticky class Class java.lang.Class#387\nRoot kind sticky class Class java.lang.Class#388\nRoot kind sticky class Class java.lang.Class#389\nRoot kind sticky class Class java.lang.Class#390\nRoot kind sticky class Class java.lang.Class#391\nRoot kind sticky class Class java.lang.Class#392\nRoot kind sticky class Class java.lang.Class#393\nRoot kind sticky class Class java.lang.Class#394\nRoot kind sticky class Class java.lang.Class#395\nRoot kind sticky class Class java.lang.Class#396\nRoot kind sticky class Class java.lang.Class#397\nRoot kind sticky class Class java.lang.Class#398\nRoot kind sticky class Class java.lang.Class#399\nRoot kind sticky class Class java.lang.Class#400\nRoot kind sticky class Class java.lang.Class#401\nRoot kind sticky class Class java.lang.Class#402\nRoot kind sticky class Class java.lang.Class#403\nRoot kind sticky class Class java.lang.Class#404\nRoot kind sticky class Class java.lang.Class#405\nRoot kind sticky class Class java.lang.Class#406\nRoot kind sticky class Class java.lang.Class#407\nRoot kind sticky class Class java.lang.Class#408\nRoot kind sticky class Class java.lang.Class#409\nRoot kind sticky class Class java.lang.Class#410\nRoot kind sticky class Class java.lang.Class#411\nRoot kind sticky class Class java.lang.Class#413\nRoot kind sticky class Class java.lang.Class#414\nRoot kind sticky class Class java.lang.Class#415\nRoot kind sticky class Class java.lang.Class#416\nRoot kind sticky class Class java.lang.Class#417\nRoot kind sticky class Class java.lang.Class#418\nRoot kind sticky class Class java.lang.Class#419\nRoot kind sticky class Class java.lang.Class#420\nRoot kind sticky class Class java.lang.Class#421\nRoot kind sticky class Class java.lang.Class#422\nRoot kind sticky class Class java.lang.Class#423\nRoot kind sticky class Class java.lang.Class#424\nRoot kind sticky class Class java.lang.Class#425\nRoot kind sticky class Class java.lang.Class#426\nRoot kind sticky class Class java.lang.Class#427\nRoot kind sticky class Class java.lang.Class#428\nRoot kind sticky class Class java.lang.Class#429\nRoot kind sticky class Class java.lang.Class#430\nRoot kind sticky class Class java.lang.Class#431\nRoot kind sticky class Class java.lang.Class#432\nRoot kind sticky class Class java.lang.Class#433\nRoot kind sticky class Class java.lang.Class#435\nRoot kind monitor used Class java.lang.ref.Reference$Lock#1\nRoot kind monitor used Class java.lang.ref.ReferenceQueue$Lock#4\nRoot kind thread object Class java.lang.Thread#5\nRoot kind thread object Class java.lang.Thread#2\nRoot kind thread object Class java.lang.ref.Finalizer$FinalizerThread#1\nRoot kind thread object Class java.lang.ref.Reference$ReferenceHandler#1\nRoot kind thread object Class java.lang.Thread#1\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project basedir=\".\" default=\"netbeans\" name=\"lib.profiler.ui\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.lib.ui</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.lib.ui/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/lib/ui/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.4\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.lib.ui-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/nbproject/genfiles.properties",
    "content": "# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=68ca5712\nnbproject/build-impl.xml.script.CRC32=ce2c0505\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/nbproject/project.properties",
    "content": "# Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nis.autoload=true\njavac.source=1.8\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.charts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.common</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.9</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <test-dependencies>\n                <test-type>\n                    <name>unit</name>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.libs.junit4</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                </test-type>\n            </test-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.application.views</friend>\n                <friend>org.graalvm.visualvm.core</friend>\n                <friend>org.graalvm.visualvm.coredump</friend>\n                <friend>org.graalvm.visualvm.heapviewer</friend>\n                <friend>org.graalvm.visualvm.heapviewer.console</friend>\n                <friend>org.graalvm.visualvm.heapviewer.truffle</friend>\n                <friend>org.graalvm.visualvm.jfr</friend>\n                <friend>org.graalvm.visualvm.lib.profiler</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.attach</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.heapwalker</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.snaptracer</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.utilities</friend>\n                <friend>org.graalvm.visualvm.modules.appui</friend>\n                <friend>org.graalvm.visualvm.profiler</friend>\n                <friend>org.graalvm.visualvm.profiling</friend>\n                <friend>org.graalvm.visualvm.sampler</friend>\n                <friend>org.graalvm.visualvm.sampler.truffle</friend>\n                <friend>org.graalvm.visualvm.gotosource</friend>\n                <friend>org.graalvm.visualvm.threaddump</friend>\n                <friend>org.graalvm.visualvm.uisupport</friend>\n                <package>org.graalvm.visualvm.lib.ui</package>\n                <package>org.graalvm.visualvm.lib.ui.charts</package>\n                <package>org.graalvm.visualvm.lib.ui.charts.xy</package>\n                <package>org.graalvm.visualvm.lib.ui.components</package>\n                <package>org.graalvm.visualvm.lib.ui.components.table</package>\n                <package>org.graalvm.visualvm.lib.ui.components.tree</package>\n                <package>org.graalvm.visualvm.lib.ui.components.treetable</package>\n                <package>org.graalvm.visualvm.lib.ui.cpu</package>\n                <package>org.graalvm.visualvm.lib.ui.cpu.statistics</package>\n                <package>org.graalvm.visualvm.lib.ui.graphs</package>\n                <package>org.graalvm.visualvm.lib.ui.jdbc</package>\n                <package>org.graalvm.visualvm.lib.ui.locks</package>\n                <package>org.graalvm.visualvm.lib.ui.memory</package>\n                <package>org.graalvm.visualvm.lib.ui.monitor</package>\n                <package>org.graalvm.visualvm.lib.ui.results</package>\n                <package>org.graalvm.visualvm.lib.ui.swing</package>\n                <package>org.graalvm.visualvm.lib.ui.swing.renderer</package>\n                <package>org.graalvm.visualvm.lib.ui.threads</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/../..\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/META-INF/services/org.graalvm.visualvm.lib.ui.cpu.statistics.StatisticalModuleContainer",
    "content": "org.graalvm.visualvm.lib.ui.cpu.statistics.StatisticalModuleContainer"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Name=Java Profiler (JFluid-UI)\nResultsPanel_CornerButtonToolTip=Show or hide result columns\n\nFormatters.MillisecondsFormat={0} ms\nFormatters.BytesFormat={0} B\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/Formatters.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui;\n\nimport java.text.Format;\nimport java.text.MessageFormat;\nimport java.text.NumberFormat;\nimport java.util.ResourceBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class Formatters {\n\n    private static final ResourceBundle BUNDLE = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.Bundle\"); // NOI18N\n\n    private static NumberFormat NUMBER_FORMAT;\n    /**\n     * Returns Format instance for formatting numbers according to current Locale.\n     *\n     * @return Format instance for formatting numbers according to current Locale\n     */\n    public static Format numberFormat() {\n        if (NUMBER_FORMAT == null) {\n            NUMBER_FORMAT = NumberFormat.getNumberInstance();\n            NUMBER_FORMAT.setGroupingUsed(true);\n        }\n        return NUMBER_FORMAT;\n    }\n\n    private static NumberFormat PERCENT_FORMAT;\n    /**\n     * Returns Format instance for formatting percents according to current Locale.\n     *\n     * @return Format instance for formatting percents according to current Locale\n     */\n    public static Format percentFormat() {\n        if (PERCENT_FORMAT == null) {\n            PERCENT_FORMAT = NumberFormat.getPercentInstance();\n            PERCENT_FORMAT.setMaximumFractionDigits(1);\n            PERCENT_FORMAT.setMinimumFractionDigits(0);\n        }\n        return PERCENT_FORMAT;\n    }\n\n    private static Format MILLISECONDS_FORMAT;\n    /**\n     * Returns Format instance to post-process a formatted milliseconds value.\n     * By default adds a \" ms\" suffix to a formatted long value.\n     *\n     * @return Format instance to post-process a formatted milliseconds value\n     */\n    public static Format millisecondsFormat() {\n        if (MILLISECONDS_FORMAT == null) {\n            MILLISECONDS_FORMAT = new MessageFormat(BUNDLE.getString(\"Formatters.MillisecondsFormat\")); // NOI18N\n        }\n        return MILLISECONDS_FORMAT;\n    }\n    \n    private static Format BYTES_FORMAT;\n    /**\n     * Returns Format instance to post-process a formatted Bytes (B) value.\n     * By default adds a \" B\" suffix to a formatted long value.\n     * \n     * @return Format instance to post-process a formatted Bytes value\n     */\n    public static Format bytesFormat() {\n        if (BYTES_FORMAT == null) {\n            BYTES_FORMAT = new MessageFormat(BUNDLE.getString(\"Formatters.BytesFormat\")); // NOI18N\n        }\n        return BYTES_FORMAT;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/LiveResultsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui;\n\nimport java.awt.image.BufferedImage;\n\n\npublic interface LiveResultsPanel {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getSortingColumn();\n\n    public boolean getSortingOrder();\n\n    public BufferedImage getViewImage(boolean onlyVisibleArea);\n\n    public String getViewName();\n\n    public boolean fitsVisibleArea();\n\n    public void handleRemove();\n\n    /**\n     * Called when auto refresh is on and profiling session will finish\n     * to give the panel chance to do some cleanup before asynchronous\n     * call to updateLiveResults() will happen.\n     *\n     * Here the context menu should be closed if open, otherwise it\n     * would block updating the results.\n     */\n    public void handleShutdown();\n\n    // --- Save Current View action support --------------------------------------\n    public boolean hasView();\n\n    public void reset();\n\n    public boolean supports(int instrumentationType);\n\n    public void updateLiveResults();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/LiveResultsWindowContributor.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.cpu.LiveFlatProfilePanel;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface LiveResultsWindowContributor {\n\n    public static abstract class Adapter implements LiveResultsWindowContributor {\n\n        @Override\n        public void addToCpuResults(LiveFlatProfilePanel cpuPanel, ProfilerToolbar toolbar, ProfilerClient client, Lookup.Provider project) {\n        }\n\n        @Override\n        public void addToMemoryResults(LiveFlatProfilePanel memoryPanel, ProfilerToolbar toolbar, ProfilerClient client, Lookup.Provider project) {\n        }\n\n        @Override\n        public void hide() {\n        }\n\n        @Override\n        public void show() {\n        }\n\n        @Override\n        public void refresh() {\n        }\n\n        @Override\n        public void reset() {\n        }\n    }\n\n    void addToCpuResults(LiveFlatProfilePanel cpuPanel, ProfilerToolbar toolbar, ProfilerClient client, Lookup.Provider project);\n\n    void addToMemoryResults(LiveFlatProfilePanel memoryPanel, ProfilerToolbar toolbar, ProfilerClient client, Lookup.Provider project);\n\n    void show();\n\n    void hide();\n\n    void refresh();\n\n    void reset();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/ResultsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui;\n\nimport java.awt.*;\nimport java.awt.event.KeyAdapter;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.text.NumberFormat;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\n\n\n/**\n * The very base functionality common for various types of results displays.\n *\n * @author Ian Formanek\n * @author Misha Dmitriev\n * @author Jiri Sedlacek\n */\npublic abstract class ResultsPanel extends JPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.Bundle\"); // NOI18N\n    private static final String CORNER_BUTTON_TOOLTIP = messages.getString(\"ResultsPanel_CornerButtonToolTip\"); // NOI18N\n                                                                                                                // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected NumberFormat intFormat;\n    protected NumberFormat percentFormat;\n    private boolean internalCornerButtonClick = false; // flag for closing columns popup by pressing cornerButton\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ResultsPanel() {\n        setLayout(new BorderLayout());\n\n        intFormat = NumberFormat.getIntegerInstance();\n        intFormat.setGroupingUsed(true);\n\n        percentFormat = NumberFormat.getPercentInstance();\n        percentFormat.setMaximumFractionDigits(1);\n        percentFormat.setMinimumFractionDigits(0);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /** Generate the data that can then be presented in this panel */\n    public abstract void prepareResults();\n\n    protected JButton createHeaderPopupCornerButton(final JPopupMenu headerPopup) {\n        final JButton cornerButton = new JButton(Icons.getIcon(GeneralIcons.HIDE_COLUMN));\n        cornerButton.setToolTipText(CORNER_BUTTON_TOOLTIP);\n        cornerButton.setDefaultCapable(false);\n\n        if (UIUtils.isWindowsClassicLookAndFeel()) {\n            cornerButton.setMargin(new Insets(0, 0, 2, 2));\n        } else if (UIUtils.isWindowsXPLookAndFeel()) {\n            cornerButton.setMargin(new Insets(0, 0, 0, 1));\n        } else if (UIUtils.isMetalLookAndFeel()) {\n            cornerButton.setMargin(new Insets(0, 0, 2, 1));\n        }\n\n        cornerButton.addKeyListener(new KeyAdapter() {\n                public void keyPressed(final KeyEvent evt) {\n                    if (evt.getKeyCode() == KeyEvent.VK_SPACE) {\n                        showColumnSelectionPopup(headerPopup, cornerButton);\n                    }\n                }\n            });\n\n        cornerButton.addMouseListener(new MouseAdapter() {\n                public void mousePressed(MouseEvent mouseEvent) {\n                    if (headerPopup.isVisible()) {\n                        internalCornerButtonClick = true;\n                        cornerButton.getModel().setArmed(false);\n                    } else {\n                        internalCornerButtonClick = false;\n\n                        if (mouseEvent.isPopupTrigger()) {\n                            showColumnSelectionPopup(headerPopup, cornerButton);\n                        }\n                    }\n                }\n\n                public void mouseClicked(MouseEvent mouseEvent) {\n                    if (SwingUtilities.isLeftMouseButton(mouseEvent) && (!internalCornerButtonClick)) {\n                        showColumnSelectionPopup(headerPopup, cornerButton);\n                    }\n                }\n            });\n\n        return cornerButton;\n    }\n\n    /**\n     * Creates instance of JScrollPane and adds it to the BorderLayout.CENTER of the ResultsPanel.\n     */\n    protected JScrollPane createScrollPane() {\n        JScrollPane jScrollPane = new JScrollPane();\n        add(jScrollPane, BorderLayout.CENTER);\n\n        return jScrollPane;\n    }\n\n    /**\n     * Creates instance of JScrollPane and adds it to the BorderLayout.CENTER of the ResultsPanel.\n     * Sets ScrollBar policies JScrollPane.VERTICAL_SCROLLBAR_ALWAYS and JScrollPane.HORIZONTAL_SCROLLBAR_NEVER\n     * and enables vertical ScrollBar only if needed.\n     */\n    protected JScrollPane createScrollPaneVerticalScrollBarAlways() {\n        final JScrollPane jScrollPane = createScrollPane();\n        jScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);\n        jScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n        // Enable vertical scrollbar only if needed\n        final JScrollBar vScrollbar = jScrollPane.getVerticalScrollBar();\n        vScrollbar.getModel().addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                vScrollbar.setEnabled(ResultsPanel.this.isEnabled() &&\n                vScrollbar.getVisibleAmount() < vScrollbar.getMaximum());\n            }\n        });\n\n        return jScrollPane;\n    }\n\n    protected abstract void initColumnSelectorItems();\n\n    private void showColumnSelectionPopup(final JPopupMenu headerPopup, final JButton cornerButton) {\n        initColumnSelectorItems();\n        headerPopup.show(cornerButton, cornerButton.getWidth() - headerPopup.getPreferredSize().width, cornerButton.getHeight());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/ResultsView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ResultsView extends JPanel {\n\n    private Component mainToolbar;\n    private Component currentToolbar;\n    private final List<Component> toolbars = new ArrayList<>();\n\n    private JTabbedPane tabs;\n\n    private Component firstView;\n    private String firstName;\n    private Icon firstIcon;\n    private String firstDescription;\n\n    private final Set<ChangeListener> listeners = new HashSet<>();\n\n\n    public ResultsView() {\n        setOpaque(false);\n        setBorder(BorderFactory.createEmptyBorder());\n        setLayout(new BorderLayout(0, 0));\n    }\n\n\n    public final void setMainToolbar(Component toolbar) {\n        if (mainToolbar == toolbar) return;\n        mainToolbar = toolbar;\n        setToolbar(mainToolbar);\n    }\n\n\n    public final void addView(String name, Icon icon, String description, Component view, Component toolbar) {\n        if (view == null) return;\n        if (tabs == null) {\n            if (firstView == null) {\n                firstView = view;\n                firstName = name;\n                firstIcon = icon;\n                firstDescription = description;\n                toolbars.add(toolbar);\n                add(view, BorderLayout.CENTER);\n                setToolbar(toolbar);\n                fireViewOrIndexChanged();\n            } else {\n                remove(firstView);\n                toolbars.add(toolbar);\n                tabs = createTabs();\n                tabs.addTab(firstName, firstIcon, firstView, firstDescription);\n                tabs.addTab(name, icon, view, description);\n                add(tabs, BorderLayout.CENTER);\n                firstView = null;\n                firstName = null;\n                firstIcon = null;\n                firstDescription = null;\n            }\n        } else {\n            if (tabs.indexOfComponent(view) != -1) return;\n            tabs.addTab(name, icon, view, description);\n            toolbars.add(toolbar);\n        }\n    }\n    \n    public final void removeView(Component view) {\n        if (view == null) return;\n        if (tabs != null) {\n            int viewIndex = tabs.indexOfComponent(view);\n            if (viewIndex == -1) return;\n            if (tabs.getTabCount() > 2) {\n                toolbars.remove(viewIndex);\n                tabs.remove(view);\n            } else {\n                tabs.remove(view);\n                firstView = tabs.getComponentAt(0);\n                firstName = tabs.getTitleAt(0);\n                firstIcon = tabs.getIconAt(0);\n                firstDescription = tabs.getToolTipTextAt(0);\n                remove(tabs);\n                add(firstView);\n                setToolbar(toolbars.get(0));\n                tabs = null;\n            }\n        } else if (firstView == view) {\n            remove(firstView);\n            setToolbar(null);\n            toolbars.clear();\n            firstView = null;\n            firstName = null;\n            firstIcon = null;\n            firstDescription = null;\n            fireViewOrIndexChanged();\n        }\n    }\n    \n    public final void removeViews() {\n        if (getViewsCount() == 0) return;\n        setToolbar(null);\n        removeAll();\n        toolbars.clear();\n        tabs = null;\n        firstView = null;\n        firstName = null;\n        firstIcon = null;\n        firstDescription = null;\n        fireViewOrIndexChanged();\n    }\n    \n    public final void setViewName(Component view, String name) {\n        int viewIndex = getViewIndex(view);\n        if (viewIndex == -1) return;\n        if (tabs == null) firstName = name;\n        else tabs.setTitleAt(viewIndex, name);\n    }\n    \n    public final String getViewName(Component view) {\n        int viewIndex = getViewIndex(view);\n        if (viewIndex == -1) return null;\n        if (tabs == null) return firstName;\n        else return tabs.getTitleAt(viewIndex);\n    }\n    \n    public final void setViewEnabled(Component view, boolean enabled) {\n        int viewIndex = getViewIndex(view);\n        if (viewIndex == -1) return;\n        if (tabs != null) tabs.setEnabledAt(viewIndex, enabled);\n        // TODO: handle single view (no tabs) - introduce firstEnabled?\n    }\n    \n    public final boolean isViewEnabled(Component view) {\n        int viewIndex = getViewIndex(view);\n        if (viewIndex == -1) return false;\n        return tabs != null && tabs.isEnabledAt(viewIndex);\n        // TODO: handle single view (no tabs) - introduce firstEnabled?\n    }\n    \n    public final void selectView(Component view) {\n        if (tabs == null) return;\n        tabs.setSelectedComponent(view);\n    }\n    \n    public final void selectView(int index) {\n        if (tabs == null) return;\n        tabs.setSelectedIndex(index);\n    }\n    \n    public final void selectPreviousView() {\n        if (tabs == null) return;\n        int index = UIUtils.getPreviousSubTabIndex(tabs, tabs.getSelectedIndex());\n        tabs.setSelectedIndex(index);\n    }\n    \n    public final void selectNextView() {\n        if (tabs == null) return;\n        int index = UIUtils.getNextSubTabIndex(tabs, tabs.getSelectedIndex());\n        tabs.setSelectedIndex(index);\n    }\n    \n    public final Component getSelectedView() {\n        return tabs != null ? tabs.getSelectedComponent() :\n               (firstView != null ? firstView : null);\n    }\n    \n    public final int getSelectedViewIndex() {\n        return tabs != null ? tabs.getSelectedIndex() :\n               (firstView != null ? 0 : -1);\n    }\n    \n    public final int getViewsCount() {\n        return tabs != null ? tabs.getTabCount() :\n               (firstView != null ? 1 : 0);\n    }\n    \n    \n    public final void addChangeListener(ChangeListener listener) {\n        listeners.add(listener);\n    }\n    \n    public final void removeChangeListener(ChangeListener listener) {\n        listeners.remove(listener);\n    }\n    \n    public final void fireViewOrIndexChanged() {\n        if (listeners.isEmpty()) return;\n        ChangeEvent event = new ChangeEvent(this);\n        for (ChangeListener listener : listeners)\n            listener.stateChanged(event);\n    }\n    \n    \n    private int getViewIndex(Component view) {\n        if (view == null) return -1;\n        if (tabs != null) {\n            return tabs.indexOfComponent(view);\n        } else {\n            return view == firstView ? 0 : -1;\n        }\n    }\n    \n    private void setToolbar(Component toolbar) {\n        if (currentToolbar == toolbar) return;\n        if (currentToolbar != null) remove(currentToolbar);\n        if (toolbar != null) currentToolbar = toolbar;\n        else currentToolbar = mainToolbar;\n        if (currentToolbar != null) add(currentToolbar, BorderLayout.NORTH);\n        revalidate();\n        repaint();\n    }\n    \n    private void updateToolbar() {\n        setToolbar(toolbars.get(getSelectedViewIndex()));\n    }\n    \n    private JTabbedPane createTabs() {\n        JTabbedPane tp = new JTabbedPane(JTabbedPane.BOTTOM) {\n            protected final void fireStateChanged() {\n                super.fireStateChanged();\n                updateToolbar();\n                fireViewOrIndexChanged();\n            }\n        };\n        tp.setOpaque(false);\n        if (UIUtils.isAquaLookAndFeel()) {\n            tp.setBorder(BorderFactory.createEmptyBorder(-13, -11, 0, -10));\n        } else {\n            tp.setBorder(BorderFactory.createEmptyBorder());\n            Insets i = UIManager.getInsets(\"TabbedPane.contentBorderInsets\"); // NOI18N\n            if (i != null) tp.setBorder(BorderFactory.createEmptyBorder(-i.top, -i.left, 0, -i.right));\n        }\n        \n        // Fix for Issue 115062 (CTRL-PageUp/PageDown should move between snapshot tabs)\n        tp.getActionMap().getParent().remove(\"navigatePageUp\"); // NOI18N\n        tp.getActionMap().getParent().remove(\"navigatePageDown\"); // NOI18N\n        \n        // support for traversing subtabs using Ctrl-Alt-PgDn/PgUp\n        getActionMap().put(\"PreviousViewAction\", new AbstractAction() { // NOI18N\n            public void actionPerformed(ActionEvent e) { selectPreviousView(); }\n        });\n        getActionMap().put(\"NextViewAction\", new AbstractAction() { // NOI18N\n            public void actionPerformed(ActionEvent e) { selectNextView(); }\n        });\n        \n        return tp;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/StringDecorator.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface StringDecorator {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final StringDecorator DEFAULT = new StringDecorator() {\n        public String decorate(String stringToDecorate) {\n            return stringToDecorate;\n        }\n    };\n\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    String decorate(String stringToDecorate);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/SwingWorker.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.Semaphore;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n\n/**\n * Mimics the functionality of the SwingWorker from JDK6+\n * @author Jaroslav Bachorik\n */\npublic abstract class SwingWorker {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static ExecutorService warmupService;\n    private static ExecutorService taskService;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final Object warmupLock = new Object();\n    private boolean useEQ;\n    final private Semaphore throughputSemaphore;\n    final private AtomicBoolean cancelFlag = new AtomicBoolean(false);\n    final private AtomicBoolean primed= new AtomicBoolean(true);\n\n    //@GuardedBy warmupLock\n    private boolean workerRunning;\n    private Runnable warmupTimer = new Runnable() {\n        public void run() {\n            synchronized (warmupLock) {\n                try {\n                    if (workerRunning) {\n                        warmupLock.wait(getWarmup());\n                    }\n\n                    if (workerRunning && !isCancelled()) {\n                        nonResponding();\n                    }\n                } catch (InterruptedException ex) {\n                    ex.printStackTrace();\n                }\n            }\n        }\n    };\n\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of SwingWorker\n     * @param forceEQ When set the corresponding {@linkplain SwingWorker#done() } method is executed on EDT\n     */\n    public SwingWorker(boolean forceEQ) {\n        this(forceEQ, null);\n    }\n\n    /**\n     * Creates a new instance of SwingWorker with <b>forceEQ=true</b>\n     */\n    public SwingWorker() {\n        this(true, null);\n    }\n    \n    /**\n     * Creates a new instance of SwingWorker with <b>forceEQ=true</b>. Allows to control the throughput by a given {@linkplain Semaphore} instance\n     * @param throughputSemaphore A semaphore instance used to control the worker throughput\n     */\n    public SwingWorker(Semaphore throughputSemaphore) {\n        this(true, throughputSemaphore);\n    }\n    /**\n     * Creates a new instance of SwingWorker. Allows to control the throughput by a given {@linkplain Semaphore} instance\n     * @param forceEQ When set the corresponding {@linkplain SwingWorker#done() } method is executed on EDT\n     * @param throughputSemaphore A semaphore instance used to control the worker throughput\n     */\n    public SwingWorker(boolean forceEQ, Semaphore throughputSemaphore) {\n        sinit();\n        this.useEQ = forceEQ;\n        this.throughputSemaphore = throughputSemaphore;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Executes the UI task. Starts the background task and handles it's execution cycle.\n     * If the background task blocks for more than getWarmup() millis the nonResponding() method is invoked\n     * \n     * The background task should check for {@linkplain SwingWorker#isCancelled()} to cancel its execution properly.\n     * \n     * <b>Each swing worker instance may be used at most once.</b>\n     * @throws IllegalStateException In case of attempted reuse of an instance\n     */\n    public void execute() {\n        if (!primed.compareAndSet(true, false)) {\n            throw new IllegalStateException(\"SwingWorker instance may be used only once\");\n        }\n        postRunnable(new Runnable() {\n            public void run() {\n                try {\n                    if (throughputSemaphore != null) {\n                        throughputSemaphore.acquire();\n                    }\n                    if (!isCancelled()) {\n                        synchronized (warmupLock) {\n                            workerRunning = true;\n                        }\n\n                        warmupService.submit(warmupTimer);\n\n                        try {\n                            doInBackground();\n                        } catch (Throwable ex) {\n                            Logger.getLogger(SwingWorker.class.getName()).log(Level.SEVERE, \"SwingWorker\", ex);\n                        } finally {\n                            synchronized (warmupLock) {\n                                workerRunning = false;\n                                warmupLock.notify();\n                            }\n                            if (!isCancelled()) {\n                                if (useEQ) {\n                                    UIUtils.runInEventDispatchThread(new Runnable() {\n                                        public void run() {\n                                            done();\n                                        }\n                                    });\n                                } else {\n                                    done();\n                                }\n                            }\n                        }\n                    }\n                } catch (InterruptedException e) {\n                    Thread.currentThread().interrupt();\n                } finally {\n                    if (throughputSemaphore != null) {\n                        throughputSemaphore.release();\n                    }\n                }\n            }\n        });\n    }\n    \n    /**\n     * Cancels the background task.\n     * Sets a flag which can be checked by calling {@linkplain SwingWorker#isCancelled()} from the subclass.\n     * Does not handle the background task interruption.\n     * \n     * @since 1.18\n     */\n    final public void cancel() {\n         if (cancelFlag.compareAndSet(false, true)) {\n             cancelled();\n             if (throughputSemaphore != null) {\n                 throughputSemaphore.release(); // release the semaphore\n             }\n         }\n    }\n\n    /**\n     * Used to check for the cancellation status\n     * @return Returns the cancellation status\n     * \n     * @since 1.18\n     */\n    final protected boolean isCancelled() {\n        return cancelFlag.get();\n    }\n    \n    /**\n     * @return Returns a warmup time - time in ms before a \"non responding\"  message is shown; default is 500ms\n     */\n    protected int getWarmup() {\n        return 500;\n    }\n\n    /**\n     * Implementors will implement this method to provide the background task logic\n     */\n    protected abstract void doInBackground();\n\n    /**\n     * Executed after the background task had finished\n     * It's run in EQ if specified in the constructor\n     * It is not called if the task has been cancelled\n     */\n    protected void done() {\n        // override to provide a functionality\n    }\n    \n    /**\n     * Called upon task cancellation.\n     * Can be used in cases when checking for {@linkplain SwingWorker#isCancelled()} is unwieldy for any reason\n     * \n     * @since 1.18\n     */\n    protected void cancelled() {\n        // override to provide a functionality\n    }\n\n    /**\n     * Called when the background thread lasts longer than the warmup time\n     * The implementor must take care of rescheduling on AWT thread if appropriate\n     * \n     * It is not called if the task has been cancelled previously\n     */\n    protected void nonResponding() {\n        // override to provide functionality\n    }\n\n    protected void postRunnable(Runnable runnable) {\n        taskService.submit(runnable);\n    }\n\n    static synchronized void sinit() {\n        if (warmupService == null) {\n            UIUtils.runInEventDispatchThreadAndWait(new Runnable() {\n                public void run() {\n                    warmupService = Executors.newCachedThreadPool();\n                    taskService = Executors.newCachedThreadPool();\n                }\n            });\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/UIConstants.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui;\n\nimport java.awt.*;\n\n\n/** Various UI Constants used in the JFluid UI\n *\n * @author Ian Formanek\n */\npublic interface UIConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    /** Color used to draw vertical gridlines in JTables */\n    public static final Color TABLE_VERTICAL_GRID_COLOR = !UIUtils.isDarkResultsBackground() ?\n                              new Color(214, 223, 247) : new Color(84, 93, 117);\n\n    /** if true, results tables display the horizontal grid lines */\n    public static final boolean SHOW_TABLE_HORIZONTAL_GRID = false;\n\n    /** if true, results tables display the vertical grid lines */\n    public static final boolean SHOW_TABLE_VERTICAL_GRID = true;\n\n    /** Color used for painting selected cell background in JTables */\n    public static final Color TABLE_SELECTION_BACKGROUND_COLOR = new Color(193, 210, 238); //(253, 249, 237)\n\n    /** Color used for painting selected cell foreground in JTables */\n    public static final Color TABLE_SELECTION_FOREGROUND_COLOR = Color.BLACK;\n    public static final int TABLE_ROW_MARGIN = 0;\n\n    public static final String PROFILER_PANELS_BACKGROUND = \"ProfilerPanels.background\"; // NOI18N\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/UIUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui;\n\nimport java.awt.*;\nimport java.awt.event.ComponentAdapter;\nimport java.awt.event.ComponentEvent;\nimport java.awt.image.BufferedImage;\nimport java.awt.image.PixelGrabber;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.logging.Logger;\nimport javax.swing.*;\nimport javax.swing.border.Border;\nimport javax.swing.border.CompoundBorder;\nimport javax.swing.event.TableModelListener;\nimport javax.swing.event.TreeExpansionEvent;\nimport javax.swing.event.TreeExpansionListener;\nimport javax.swing.plaf.TableUI;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableModel;\nimport javax.swing.tree.TreeModel;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\n\n\n/** Various UI utilities used in the JFluid UI\n *\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic final class UIUtils {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // Used to mark explicit expand/collapse on JTree which shouldn't be handled by automatic expander\n    public static final String PROP_AUTO_EXPANDING = \"auto_expanding\"; // NOI18N\n    public static final String PROP_EXPANSION_TRANSACTION = \"expansion_transaction\"; // NOI18N\n    public static Dimension DIMENSION_SMALLEST = new Dimension(0, 0);\n\n    private static final Logger LOGGER = Logger.getLogger(UIUtils.class.getName());\n    public static final float ALTERNATE_ROW_DARKER_FACTOR = 0.96f;\n    private static final int MAX_TREE_AUTOEXPAND_LINES = 50;\n    private static boolean toolTipValuesInitialized = false;\n    private static Color unfocusedSelBg;\n    private static Color unfocusedSelFg;\n    private static Color disabledLineColor;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    public static void decorateProfilerPanel(JPanel panel) {\n        Color panelBackground = UIManager.getColor(UIConstants.PROFILER_PANELS_BACKGROUND);\n        if (panelBackground != null) {\n            panel.setOpaque(true);\n            panel.setBackground(panelBackground);\n        }\n    }\n    \n    public static JPanel createFillerPanel() {\n        JPanel fillerPanel = new JPanel(null) {\n            public Dimension getPreferredSize() {\n                return DIMENSION_SMALLEST;\n            }\n        };\n        fillerPanel.setOpaque(false);\n        return fillerPanel;\n    }\n\n    public static JSeparator createHorizontalSeparator() {\n        JSeparator horizontalSeparator = new JSeparator() {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n\n        return horizontalSeparator;\n    }\n    \n    public static JSeparator createHorizontalLine() {\n        JSeparator horizontalSeparator = new JSeparator() {\n            private final int maxHeight = isNimbusLookAndFeel() ? 2 :\n                                          isGTKLookAndFeel() ? 3 :\n                                          isAquaLookAndFeel() ? 6 :\n                                          1;\n            private final boolean customPaint = isAquaLookAndFeel();\n            \n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            public Dimension getMaximumSize() {\n                return getPreferredSize();\n            }\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.height = customPaint ? 1 : Math.min(dim.height, maxHeight);\n                return dim;\n            }\n            public void paint(Graphics g) {\n                if (customPaint) g.translate(0, -maxHeight + 1);\n                super.paint(g);\n                if (customPaint) g.translate(0, maxHeight - 1);\n            }\n        };\n\n        return horizontalSeparator;\n    }\n    \n    public static JSeparator createHorizontalLine(Color background) {\n        final boolean customPaint = isNimbus() || isAquaLookAndFeel();\n        JSeparator separator = new JSeparator() {\n            public Dimension getMaximumSize() {\n                return new Dimension(super.getMaximumSize().width, 1);\n            }\n            public Dimension getPreferredSize() {\n                return new Dimension(super.getPreferredSize().width, 1);\n            }\n            public void paint(Graphics g) {\n                if (customPaint) {\n                    g.setColor(getDisabledLineColor());\n                    g.fillRect(0, 0, getWidth(), getHeight());\n                } else {\n                    super.paint(g);\n                }\n            }\n        };\n        separator.setBackground(background);\n        return separator;\n    }\n    \n    /** Determines if current L&amp;F is AquaLookAndFeel */\n    public static boolean isAquaLookAndFeel() {\n        // is current L&F some kind of AquaLookAndFeel?\n        return UIManager.getLookAndFeel().getID().equals(\"Aqua\"); //NOI18N\n    }\n\n    private static Map<Integer, Color> DARKER_CACHE;\n    public static Color getDarker(Color c) {\n        if (DARKER_CACHE == null) DARKER_CACHE = new HashMap<>();\n        \n        int rgb = c.getRGB();\n        Color d = DARKER_CACHE.get(rgb);\n        \n        if (d == null) {\n            if (c.equals(Color.WHITE)) {\n                d = new Color(244, 244, 244);\n            } else {\n                d = getSafeColor((int)(c.getRed() * ALTERNATE_ROW_DARKER_FACTOR),\n                                 (int)(c.getGreen() * ALTERNATE_ROW_DARKER_FACTOR),\n                                 (int)(c.getBlue() * ALTERNATE_ROW_DARKER_FACTOR));\n            }\n            DARKER_CACHE.put(rgb, d);\n        }\n        \n        return d;\n    }\n\n    public static Color getDarkerLine(Color c, float alternateRowDarkerFactor) {\n        return getSafeColor((int) (c.getRed() * alternateRowDarkerFactor), (int) (c.getGreen() * alternateRowDarkerFactor),\n                            (int) (c.getBlue() * alternateRowDarkerFactor));\n    }\n    \n    public static Color getDisabledForeground(Color c) {\n        Color b = c.brighter();\n        if (c.getRGB() == b.getRGB()) return b; // Selection foreground\n        else if (isNimbusLookAndFeel()) return UIManager.getColor(\"nimbusDisabledText\").darker(); //NOI18N\n        else if (isMetalLookAndFeel()) return UIManager.getColor(\"Label.disabledForeground\"); //NOI18N\n        else if (Color.BLACK.getRGB() == c.getRGB()) return Color.GRAY;\n        else return b;\n    }\n\n    public static int getDefaultRowHeight() {\n        return new JLabel(\"X\").getPreferredSize().height + 2; //NOI18N\n    }\n\n    /** Determines if current L&amp;F is GTKLookAndFeel */\n    public static boolean isGTKLookAndFeel() {\n        // is current L&F some kind of GTKLookAndFeel?\n        return UIManager.getLookAndFeel().getID().equals(\"GTK\"); //NOI18N\n    }\n    \n    /** Determines if current L&amp;F is Nimbus */\n    public static boolean isNimbusLookAndFeel() {\n        // is current L&F Nimbus?\n        return UIManager.getLookAndFeel().getID().equals(\"Nimbus\"); //NOI18N\n    }\n    \n    /** Determines if current L&amp;F is GTK using Nimbus theme */\n    public static boolean isNimbusGTKTheme() {\n        // is current L&F GTK using Nimbus theme?\n        return isGTKLookAndFeel() && \"nimbus\".equals(Toolkit.getDefaultToolkit().getDesktopProperty(\"gnome.Net/ThemeName\")); //NOI18N\n    }\n    \n    /** Determines if current L&amp;F is Nimbus or GTK with Nimbus theme*/\n    public static boolean isNimbus() {\n        // is current L&F Nimbus or GTK with Nimbus theme?\n        return isNimbusLookAndFeel() || isNimbusGTKTheme();\n    }\n\n    /** Determines if current L&amp;F is MetalLookAndFeel */\n    public static boolean isMetalLookAndFeel() {\n        // is current L&F some kind of MetalLookAndFeel?\n        return UIManager.getLookAndFeel().getID().equals(\"Metal\"); //NOI18N\n    }\n\n    // Returns next enabled tab of JTabbedPane\n    public static int getNextSubTabIndex(JTabbedPane tabs, int tabIndex) {\n        int nextTabIndex = tabIndex;\n\n        for (int i = 0; i < tabs.getComponentCount(); i++) {\n            nextTabIndex++;\n\n            if (nextTabIndex == tabs.getComponentCount()) {\n                nextTabIndex = 0;\n            }\n\n            if (tabs.isEnabledAt(nextTabIndex)) {\n                break;\n            }\n        }\n\n        return nextTabIndex;\n    }\n\n    public static Window getParentWindow(Component comp) {\n        while ((comp != null) && !(comp instanceof Window)) {\n            comp = comp.getParent();\n        }\n\n        return (Window) comp;\n    }\n\n    // Returns previous enabled tab of JTabbedPane\n    public static int getPreviousSubTabIndex(JTabbedPane tabs, int tabIndex) {\n        int previousTabIndex = tabIndex;\n\n        for (int i = 0; i < tabs.getComponentCount(); i++) {\n            previousTabIndex--;\n\n            if (previousTabIndex < 0) {\n                previousTabIndex = tabs.getComponentCount() - 1;\n            }\n\n            if (tabs.isEnabledAt(previousTabIndex)) {\n                break;\n            }\n        }\n\n        return previousTabIndex;\n    }\n\n    public static Color getSafeColor(int red, int green, int blue) {\n        red = Math.max(red, 0);\n        red = Math.min(red, 255);\n        green = Math.max(green, 0);\n        green = Math.min(green, 255);\n        blue = Math.max(blue, 0);\n        blue = Math.min(blue, 255);\n\n        return new Color(red, green, blue);\n    }\n\n    // Copied from org.openide.awt.HtmlLabelUI\n    /** Get the system-wide unfocused selection background color */\n    public static Color getUnfocusedSelectionBackground() {\n        if (unfocusedSelBg == null) {\n            //allow theme/ui custom definition\n            unfocusedSelBg = UIManager.getColor(\"nb.explorer.unfocusedSelBg\"); //NOI18N\n\n            if (unfocusedSelBg == null) {\n                // try Aqua L&F\n                unfocusedSelBg = UIManager.getColor(\"Table.selectionInactiveBackground\"); //NOI18N\n\n                if (unfocusedSelBg == null) {\n                    //try to get standard shadow color\n                    unfocusedSelBg = UIManager.getColor(\"controlShadow\"); //NOI18N\n\n                    if (unfocusedSelBg == null) {\n                        //Okay, the look and feel doesn't suport it, punt\n                        unfocusedSelBg = Color.lightGray;\n                    }\n\n                    //Lighten it a bit because disabled text will use controlShadow/\n                    //gray\n                    if (!Color.WHITE.equals(unfocusedSelBg.brighter())) {\n                        unfocusedSelBg = unfocusedSelBg.brighter();\n                    }\n                }\n            }\n        }\n\n        return unfocusedSelBg;\n    }\n\n    // Copied from org.openide.awt.HtmlLabelUI\n    /** Get the system-wide unfocused selection foreground color */\n    public static Color getUnfocusedSelectionForeground() {\n        if (unfocusedSelFg == null) {\n            //allow theme/ui custom definition\n            unfocusedSelFg = UIManager.getColor(\"nb.explorer.unfocusedSelFg\"); //NOI18N\n\n            if (unfocusedSelFg == null) {\n                //try to get standard shadow color\n                unfocusedSelFg = UIManager.getColor(\"textText\"); //NOI18N\n\n                if (unfocusedSelFg == null) {\n                    //Okay, the look and feel doesn't suport it, punt\n                    unfocusedSelFg = Color.BLACK;\n                }\n            }\n        }\n\n        return unfocusedSelFg;\n    }\n\n    private static Color defaultTableForeground;\n    \n    public static Color getDefaultTableForeground() {\n        if (defaultTableForeground == null) {\n            defaultTableForeground = new JTable() {\n                @Override protected void initializeLocalVars() {}\n                @Override protected void createDefaultRenderers() {}\n                @Override protected void createDefaultEditors() {}\n                @Override protected TableModel createDefaultDataModel() {\n                    return new TableModel() {\n                        @Override public int getRowCount() { return 0; }\n                        @Override public int getColumnCount() { return 0; }\n                        @Override public String getColumnName(int columnIndex) { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n                        @Override public Class<?> getColumnClass(int columnIndex) { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n                        @Override public boolean isCellEditable(int rowIndex, int columnIndex){ throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n                        @Override public Object getValueAt(int rowIndex, int columnIndex) { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n                        @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { throw new UnsupportedOperationException(\"Not supported.\"); } // NOI18N\n                        @Override public void addTableModelListener(TableModelListener l) {}\n                        @Override public void removeTableModelListener(TableModelListener l) {}\n                    };\n                }\n                @Override public TableCellRenderer getDefaultRenderer(Class<?> columnClass) { return ProfilerTable.createTableCellRenderer(new LabelRenderer()); }\n                @Override public void updateUI() { setUI((TableUI)UIManager.getUI(this)); }\n            }.getForeground();\n        }\n        return defaultTableForeground;\n    }\n    \n    private static Color profilerResultsBackground;\n    \n    private static Color getGTKProfilerResultsBackground() {\n        int[] pixels = new int[1];\n        pixels[0] = -1;\n        \n        // Prepare textarea to grab the color from\n        JTextArea textArea = new JTextArea();\n        textArea.setSize(new Dimension(10, 10));\n        textArea.doLayout();\n        \n        // Print the textarea to an image\n        Image image = new BufferedImage(textArea.getSize().width, textArea.getSize().height, BufferedImage.TYPE_INT_RGB);\n        textArea.printAll(image.getGraphics());\n        \n        // Grab appropriate pixels to get the color\n        PixelGrabber pixelGrabber = new PixelGrabber(image, 5, 5, 1, 1, pixels, 0, 1);\n        try {\n            pixelGrabber.grabPixels();\n            if (pixels[0] == -1) return Color.WHITE; // System background not customized\n        } catch (InterruptedException e) {\n            return getNonGTKProfilerResultsBackground();\n        }\n        \n        return pixels[0] != -1 ? new Color(pixels[0]) : getNonGTKProfilerResultsBackground();\n    }\n    \n    private static Color getNonGTKProfilerResultsBackground() {\n        return UIManager.getColor(\"Table.background\"); // NOI18N\n    }\n    \n    public static Color getProfilerResultsBackground() {\n        if (profilerResultsBackground == null) {\n            if (isGTKLookAndFeel() || isNimbusLookAndFeel()) {\n                profilerResultsBackground = getGTKProfilerResultsBackground();\n            } else {\n                profilerResultsBackground = getNonGTKProfilerResultsBackground();\n            }\n            if (profilerResultsBackground == null) profilerResultsBackground = Color.WHITE;\n        }\n        \n        return profilerResultsBackground;\n    }\n    \n    private static Boolean darkResultsBackground;\n    \n    public static boolean isDarkResultsBackground() {\n        if (darkResultsBackground == null) {\n            Color c = getProfilerResultsBackground();\n            int b = (int)(0.3 * c.getRed() + 0.59 * c.getGreen() + 0.11 * c.getBlue());\n            darkResultsBackground = b < 85;\n        }\n        \n        return darkResultsBackground;\n    }\n\n    /** Determines if current L&amp;F is Windows Classic LookAndFeel */\n    public static boolean isWindowsClassicLookAndFeel() {\n        if (\"Windows Classic\".equals(UIManager.getLookAndFeel().getName())) return true; //NOI18N\n        \n        if (!isWindowsLookAndFeel()) {\n            return false;\n        }\n\n        return (!isWindowsXPLookAndFeel());\n    }\n\n    /** Determines if current L&amp;F is WindowsLookAndFeel */\n    public static boolean isWindowsLookAndFeel() {\n        // is current L&F some kind of WindowsLookAndFeel?\n        return UIManager.getLookAndFeel().getID().equals(\"Windows\"); //NOI18N\n    }\n\n    /** Determines if current L&amp;F is Windows XP LookAndFeel */\n    public static boolean isWindowsXPLookAndFeel() {\n        if (!isWindowsLookAndFeel()) {\n            return false;\n        }\n\n        // is XP theme active in the underlying OS?\n        boolean xpThemeActiveOS = Boolean.TRUE.equals(Toolkit.getDefaultToolkit().getDesktopProperty(\"win.xpstyle.themeActive\")); //NOI18N\n                                                                                                                                  // is XP theme disabled by the application?\n\n        boolean xpThemeDisabled = (System.getProperty(\"swing.noxp\") != null); // NOI18N\n\n        return ((xpThemeActiveOS) && (!xpThemeDisabled));\n    }\n    \n    public static boolean isWindowsModernLookAndFeel() {\n        if (!isWindowsXPLookAndFeel()) return false;\n        String osName = System.getProperty(\"os.name\"); // NOI18N\n        return osName != null && (osName.contains(\"Windows 8\") || osName.contains(\"Windows 10\")); // NOI18N\n    }\n    \n    public static boolean isOracleLookAndFeel() {\n        // is current L&F some kind of WindowsLookAndFeel?\n        return UIManager.getLookAndFeel().getID().contains(\"Oracle\"); //NOI18N\n    }\n\n    /** Checks give TreePath for the last node, and if it ends with a node with just one child,\n     * it keeps expanding further.\n     * Current implementation expands through the first child that is not leaf. To more correctly\n     * fulfill expected semantics in case maxChildToExpand is &gt; 1, it should expand all paths through\n     * all children.\n     *\n     * @param tree\n     * @param path\n     * @param maxChildToExpand\n     */\n    public static void autoExpand(JTree tree, TreePath path, int maxLines, int maxChildToExpand, boolean dontExpandToLeafs) {\n        TreeModel model = tree.getModel();\n        Object node = path.getLastPathComponent();\n        TreePath newPath = path;\n\n        int currentLines = 0;\n\n        while (currentLines++ < maxLines &&\n                !model.isLeaf(node) &&\n                (model.getChildCount(node) > 0) &&\n                (model.getChildCount(node) <= maxChildToExpand)) {\n            for (int i = 0; i < model.getChildCount(node); i++) {\n                node = tree.getModel().getChild(node, i);\n\n                if (!model.isLeaf(node)) {\n                    if (dontExpandToLeafs && hasOnlyLeafs(tree, node)) {\n                        break;\n                    }\n\n                    newPath = newPath.pathByAddingChild(node); // if the leaf is added the path will not expand\n\n                    break; // from for\n                }\n            }\n        }\n\n        tree.expandPath(newPath);\n    }\n\n    /** Checks if the root of the provided tree has only one child, and if so,\n     * it autoexpands it.\n     *\n     * @param tree The tree whose root should be autoexpanded\n     */\n    public static void autoExpandRoot(JTree tree) {\n        autoExpandRoot(tree, 1);\n    }\n\n    /** Checks if the root of the provided tree has only one child, and if so,\n     * it autoexpands it.\n     *\n     * @param tree The tree whose root should be autoexpanded\n     */\n    public static void autoExpandRoot(JTree tree, int maxChildToExpand) {\n        Object root = tree.getModel().getRoot();\n\n        if (root == null) {\n            return;\n        }\n\n        TreePath rootPath = new TreePath(root);\n        autoExpand(tree, rootPath, MAX_TREE_AUTOEXPAND_LINES, maxChildToExpand, false);\n    }\n\n    public static long[] copyArray(long[] array) {\n        if (array == null) {\n            return new long[0];\n        }\n\n        if (array.length == 0) {\n            return new long[0];\n        } else {\n            long[] ret = new long[array.length];\n            System.arraycopy(array, 0, ret, 0, array.length);\n\n            return ret;\n        }\n    }\n\n    public static int[] copyArray(int[] array) {\n        if (array == null) {\n            return new int[0];\n        }\n\n        if (array.length == 0) {\n            return new int[0];\n        } else {\n            int[] ret = new int[array.length];\n            System.arraycopy(array, 0, ret, 0, array.length);\n\n            return ret;\n        }\n    }\n\n    public static float[] copyArray(float[] array) {\n        if (array == null) {\n            return new float[0];\n        }\n\n        if (array.length == 0) {\n            return new float[0];\n        } else {\n            float[] ret = new float[array.length];\n            System.arraycopy(array, 0, ret, 0, array.length);\n\n            return ret;\n        }\n    }\n\n    public static void ensureMinimumSize(Component comp) {\n        comp = getParentWindow(comp);\n\n        if (comp != null) {\n            final Component top = comp;\n            top.addComponentListener(new ComponentAdapter() {\n                    public void componentResized(ComponentEvent e) {\n                        Dimension d = top.getSize();\n                        Dimension min = top.getMinimumSize();\n\n                        if ((d.width < min.width) || (d.height < min.height)) {\n                            top.setSize(Math.max(d.width, min.width), Math.max(d.height, min.height));\n                        }\n                    }\n                });\n        }\n    }\n\n    // Classic Windows LaF doesn't draw dotted focus rectangle inside JButton if parent is JToolBar,\n    // XP Windows LaF doesn't draw dotted focus rectangle inside JButton at all\n    // This method installs customized Windows LaF that draws dotted focus rectangle inside JButton always\n\n    // On JDK 1.5 the XP Windows LaF enforces special border to all buttons, overriding any custom border\n    // set by setBorder(). Class responsible for this is WindowsButtonListener. See Issue 71546.\n    // Also fixes buttons size in JToolbar.\n\n    /** Ensures that focus will be really painted if button is focused\n     * and fixes using custom border for JDK 1.5 &amp; XP L&amp;F\n     */\n    public static void fixButtonUI(AbstractButton button) {\n        // Doesn't seem to be necessary any more, conflicts with Jigsaw\n    }\n\n    public static boolean hasOnlyLeafs(JTree tree, Object node) {\n        TreeModel model = tree.getModel();\n\n        for (int i = 0; i < model.getChildCount(node); i++) {\n            if (!model.isLeaf(model.getChild(node, i))) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /** By calling this method, the provided tree will become auto-expandable, i.e.\n     * When a node is expanded, if it has only one child, that child gets expanded, and so on.\n     * This is very useful for trees that have a deep node hierarchy with typical paths from\n     * root to leaves containing only one node along the whole path.\n     *\n     * @param tree The tree to make auto-expandable\n     */\n    public static void makeTreeAutoExpandable(JTree tree) {\n        makeTreeAutoExpandable(tree, 1, false);\n    }\n\n    public static void makeTreeAutoExpandable(JTree tree, final boolean dontExpandToLeafs) {\n        makeTreeAutoExpandable(tree, 1, dontExpandToLeafs);\n    }\n\n    /** By calling this method, the provided tree will become auto-expandable, i.e.\n     * When a node is expanded, if it has only one child, that child gets expanded, and so on.\n     * This is very useful for trees that have a deep node hierarchy with typical paths from\n     * root to leaves containing only one node along the whole path.\n     *\n     * @param tree The tree to make auto-expandable\n     */\n    public static void makeTreeAutoExpandable(JTree tree, final int maxChildToExpand) {\n        makeTreeAutoExpandable(tree, maxChildToExpand, false);\n    }\n\n    public static void makeTreeAutoExpandable(final JTree tree, final int maxChildToExpand, final boolean dontExpandToLeafs) {\n        tree.addTreeExpansionListener(new TreeExpansionListener() {\n                boolean internalChange = false;\n\n                public void treeCollapsed(TreeExpansionEvent event) {\n                }\n\n                public void treeExpanded(TreeExpansionEvent event) {\n                    if (internalChange || Boolean.TRUE.equals(tree.getClientProperty(PROP_EXPANSION_TRANSACTION))) { // NOI18N\n                        return;\n                    }\n\n                    // Auto expand more if the just expanded child has only one child\n                    TreePath path = event.getPath();\n                    JTree tree = (JTree) event.getSource();\n                    internalChange = true;\n                    tree.putClientProperty(PROP_AUTO_EXPANDING, Boolean.TRUE);\n                    try {\n                        autoExpand(tree, path, MAX_TREE_AUTOEXPAND_LINES, maxChildToExpand, dontExpandToLeafs);\n                    } finally {\n                        tree.putClientProperty(PROP_AUTO_EXPANDING, null);\n                        internalChange = false;\n                    }\n                }\n            });\n    }\n\n    public static void runInEventDispatchThread(final Runnable r) {\n        if (SwingUtilities.isEventDispatchThread()) {\n            r.run();\n        } else {\n            SwingUtilities.invokeLater(r);\n        }\n    }\n\n    public static void runInEventDispatchThreadAndWait(final Runnable r) {\n        if (SwingUtilities.isEventDispatchThread()) {\n            r.run();\n        } else {\n            try {\n                SwingUtilities.invokeAndWait(r);\n            } catch (InvocationTargetException e) {\n                LOGGER.severe(e.getMessage());\n            } catch (InterruptedException e) {\n                LOGGER.severe(e.getMessage());\n            }\n        }\n    }\n    \n    public static void addBorder(JComponent c, Border b) {\n        Border cb = c.getBorder();\n        Border nb = cb == null ? b : new CompoundBorder(cb, b);\n        c.setBorder(nb);\n    }\n    \n    public static Color getDisabledLineColor() {\n        if (disabledLineColor == null) {\n            disabledLineColor = UIManager.getColor(isAquaLookAndFeel() ? \"controlShadow\" : // NOI18N\n                                                   \"Label.disabledForeground\"); // NOI18N\n            if (disabledLineColor == null)\n                disabledLineColor = UIManager.getColor(\"Label.disabledText\"); // NOI18N\n            if (disabledLineColor == null || disabledLineColor.equals(getProfilerResultsBackground()))\n                disabledLineColor = Color.GRAY;\n        }\n        return disabledLineColor;\n    }    \n    \n    public static BufferedImage createScreenshot(Component component) {\n        assert SwingUtilities.isEventDispatchThread();\n        \n        if (component instanceof JScrollPane) {\n            JScrollPane scrollPane = (JScrollPane) component;\n            return createComponentScreenshot(scrollPane.getViewport());\n        } else {\n            return createComponentScreenshot(component);\n        }\n    }\n\n    private static BufferedImage createComponentScreenshot(Component component) {\n        if (component instanceof JTable || (component instanceof JViewport &&\n                                           ((JViewport) component).getView() instanceof JTable)) {\n            return createTableScreenshot(component);\n        } else {\n            return createGeneralComponentScreenshot(component);\n        }\n    }\n\n    private static BufferedImage createGeneralComponentScreenshot(Component component) {\n        Component source;\n        Dimension sourceSize;\n\n        if (component instanceof JViewport) {\n            JViewport viewport = (JViewport) component;\n            Component contents = viewport.getView();\n\n            if (contents.getSize().height > viewport.getSize().height) {\n                source = component;\n                sourceSize = component.getSize();\n            } else {\n                source = contents;\n                sourceSize = contents.getSize();\n            }\n        } else {\n            source = component;\n            sourceSize = component.getSize();\n        }\n\n        BufferedImage componentScreenshot = new BufferedImage(sourceSize.width, sourceSize.height, BufferedImage.TYPE_INT_RGB);\n        Graphics componentScreenshotGraphics = componentScreenshot.getGraphics();\n        source.printAll(componentScreenshotGraphics);\n\n        return componentScreenshot;\n    }\n\n    private static BufferedImage createTableScreenshot(Component component) {\n        Component source;\n        Dimension sourceSize;\n        JTable table;\n\n        if (component instanceof JTable) {\n            table = (JTable) component;\n\n            if ((table.getTableHeader() == null) || !table.getTableHeader().isVisible()) {\n                return createGeneralComponentScreenshot(component);\n            }\n\n            source = table;\n            sourceSize = table.getSize();\n        } else if (component instanceof JViewport && ((JViewport) component).getView() instanceof JTable) {\n            JViewport viewport = (JViewport) component;\n            table = (JTable) viewport.getView();\n\n            if ((table.getTableHeader() == null) || !table.getTableHeader().isVisible()) {\n                return createGeneralComponentScreenshot(component);\n            }\n\n            if (table.getSize().height > viewport.getSize().height) {\n                source = viewport;\n                sourceSize = viewport.getSize();\n            } else {\n                source = table;\n                sourceSize = table.getSize();\n            }\n        } else {\n            throw new IllegalArgumentException(\"Component can only be JTable or JViewport holding JTable\"); // NOI18N\n        }\n\n        final JTableHeader tableHeader = table.getTableHeader();\n        Dimension tableHeaderSize = tableHeader.getSize();\n\n        BufferedImage tableScreenshot = new BufferedImage(sourceSize.width, tableHeaderSize.height + sourceSize.height,\n                                                          BufferedImage.TYPE_INT_RGB);\n        Graphics tableScreenshotGraphics = tableScreenshot.getGraphics();\n        tableHeader.printAll(tableScreenshotGraphics);\n        tableScreenshotGraphics.translate(0, tableHeaderSize.height);\n        source.printAll(tableScreenshotGraphics);\n        return tableScreenshot;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/AbstractBarChartModel.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts;\n\nimport java.util.Collection;\nimport java.util.concurrent.CopyOnWriteArraySet;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class AbstractBarChartModel implements BarChartModel {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Collection<ChartModelListener> listeners = new CopyOnWriteArraySet<>(); // Data change listeners\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of AbstractBarChartModel */\n    public AbstractBarChartModel() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public abstract String getXAxisDesc();\n\n    // --- Abstract BarChartModel ------------------------------------------------\n    public abstract String[] getXLabels();\n\n    public abstract String getYAxisDesc();\n\n    public abstract int[] getYValues();\n\n    // ---------------------------------------------------------------------------\n\n    // --- Listeners -------------------------------------------------------------\n\n    /**\n     * Adds new ChartModel listener.\n     * @param listener ChartModel listener to add\n     */\n    public synchronized void addChartModelListener(ChartModelListener listener) {\n        listeners.add(listener);\n    }\n\n    /**\n     * Removes ChartModel listener.\n     * @param listener ChartModel listener to remove\n     */\n    public synchronized void removeChartModelListener(ChartModelListener listener) {\n        listeners.remove(listener);\n    }\n\n    /**\n     * Notifies all listeners about the data change.\n     */\n    protected void fireChartDataChanged() {\n        for(ChartModelListener l : listeners) {\n            l.chartDataChanged();\n        }\n    }\n\n    // ---------------------------------------------------------------------------\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/AbstractPieChartModel.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts;\n\nimport java.awt.Color;\nimport java.util.Collection;\nimport java.util.concurrent.CopyOnWriteArraySet;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class AbstractPieChartModel implements PieChartModel {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Collection<ChartModelListener> listeners = new CopyOnWriteArraySet<>(); // Data change listeners\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public abstract Color getItemColor(int index); // color of item\n\n    // --- Abstract PieChartModel ------------------------------------------------\n    public abstract int getItemCount(); // number of displayed (processed) items\n\n    public abstract String getItemName(int index); // name of item\n\n    public abstract double getItemValue(int index); // value of item\n\n    public abstract double getItemValueRel(int index); // relative item value (<0, 1>, E(items) = 1)\n\n    public abstract boolean hasData(); // does the model contain some non-zero item?\n\n    // --- Listeners -------------------------------------------------------------\n\n    /**\n     * Adds new ChartModel listener.\n     * @param listener ChartModel listener to add\n     */\n    public synchronized void addChartModelListener(ChartModelListener listener) {\n        listeners.add(listener);\n    }\n\n    /**\n     * Removes ChartModel listener.\n     * @param listener ChartModel listener to remove\n     */\n    public synchronized void removeChartModelListener(ChartModelListener listener) {\n        listeners.remove(listener);\n    }\n\n    /**\n     * Notifies all listeners about the data change.\n     */\n    protected void fireChartDataChanged() {\n        for(ChartModelListener l : listeners) {\n            l.chartDataChanged();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/BarChart.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Image;\nimport java.awt.Insets;\nimport java.awt.Paint;\nimport java.awt.Polygon;\nimport java.awt.RenderingHints;\nimport java.awt.Stroke;\nimport java.awt.event.ComponentEvent;\nimport java.awt.event.ComponentListener;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.accessibility.Accessible;\nimport javax.accessibility.AccessibleContext;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JFrame;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.AncestorEvent;\nimport javax.swing.event.AncestorListener;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class BarChart extends JComponent implements ComponentListener, AncestorListener, ChartModelListener, Accessible {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    List<Integer> horizAxisXes = new ArrayList<>();\n    int horizAxisHeight = 0;\n    int horizLegendWidth = 0;\n    int vertAxisWidth = 0;\n    int vertLegendHeight = 0;\n    private AccessibleContext accessibleContext;\n    private BarChartModel model;\n    private Graphics2D offScreenGraphics;\n    private Image offScreenImage;\n    private Insets insets;\n    private Paint axisMeshPaint = new Color(80, 80, 80, 50);\n    private Paint axisPaint = Color.BLACK;\n    private Paint fillPaint = Color.CYAN;\n    private Paint outlinePaint = Color.BLACK;\n    private Stroke axisStroke = new BasicStroke(1f);\n    private Stroke outlineStroke = new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND);\n    private boolean draw3D = false;\n    private boolean modelIncorrect = true;\n    private boolean offScreenImageInvalid;\n    private boolean offScreenImageSizeInvalid;\n    private int drawHeight;\n    private int drawWidth;\n    private int leftOffset = 0;\n    private int maxHeight;\n    private int rightOffset = 0;\n    private int topOffset = 0;\n    private int xSpacing = 0;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of BarChart */\n    public BarChart() {\n        offScreenImageSizeInvalid = true;\n        addAncestorListener(this);\n        addComponentListener(this);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setAccessibleContext(AccessibleContext accessibleContext) {\n        this.accessibleContext = accessibleContext;\n    }\n\n    public AccessibleContext getAccessibleContext() {\n        return accessibleContext;\n    }\n\n    // --- Public interface ------------------------------------------------------\n    public void setDraw3D(boolean draw3D) {\n        if (this.draw3D != draw3D) {\n            this.draw3D = draw3D;\n            chartDataChanged();\n        }\n    }\n\n    public boolean getDraw3D() {\n        return draw3D;\n    }\n\n    public void setFillPaint(Paint fillPaint) {\n        if (!this.fillPaint.equals(fillPaint)) {\n            this.fillPaint = fillPaint;\n            chartDataChanged();\n        }\n    }\n\n    public Paint getFillPaint() {\n        return fillPaint;\n    }\n\n    public void setFont(Font font) {\n        if (!getFont().equals(font)) {\n            super.setFont(font);\n            chartDataChanged();\n        }\n    }\n\n    public void setLeftOffset(int leftOffset) {\n        if (this.leftOffset != leftOffset) {\n            this.leftOffset = leftOffset;\n            chartDataChanged();\n        }\n    }\n\n    public int getLeftOffset() {\n        return leftOffset;\n    }\n\n    public void setModel(BarChartModel model) {\n        // automatically unregister itself as a ChartModelListener from current model\n        if (this.model != null) {\n            this.model.removeChartModelListener(this);\n        }\n\n        // automatically register itself as a ChartModelListener for new model\n        if (model != null) {\n            model.addChartModelListener(this);\n        }\n\n        // set new model\n        this.model = model;\n\n        // process data change\n        chartDataChanged();\n    }\n\n    public BarChartModel getModel() {\n        return model;\n    }\n\n    public void setOutlinePaint(Paint outlinePaint) {\n        if (!this.outlinePaint.equals(outlinePaint)) {\n            this.outlinePaint = outlinePaint;\n            chartDataChanged();\n        }\n    }\n\n    public Paint getOutlinePaint() {\n        return outlinePaint;\n    }\n\n    public void setOutlineStroke(Stroke outlineStroke) {\n        if (!this.outlineStroke.equals(outlineStroke)) {\n            this.outlineStroke = outlineStroke;\n            chartDataChanged();\n        }\n    }\n\n    public Stroke getOutlineStroke() {\n        return outlineStroke;\n    }\n\n    public void setRightOffset(int rightOffset) {\n        if (this.rightOffset != rightOffset) {\n            this.rightOffset = rightOffset;\n            chartDataChanged();\n        }\n    }\n\n    public int getRightOffset() {\n        return rightOffset;\n    }\n\n    public void setTopOffset(int topOffset) {\n        if (this.topOffset != topOffset) {\n            this.topOffset = topOffset;\n            chartDataChanged();\n        }\n    }\n\n    public int getTopOffset() {\n        return topOffset;\n    }\n\n    public void setXSpacing(int xSpacing) {\n        if (this.xSpacing != xSpacing) {\n            this.xSpacing = xSpacing;\n            chartDataChanged();\n        }\n    }\n\n    public int getXSpacing() {\n        return xSpacing;\n    }\n\n    public void ancestorAdded(AncestorEvent event) {\n        chartDataChanged();\n    }\n\n    public void ancestorMoved(AncestorEvent event) {\n    }\n\n    public void ancestorRemoved(AncestorEvent event) {\n    }\n\n    // Used for public chart update & listener implementation\n    public void chartDataChanged() {\n        if (model != null) {\n            // assume model is incorrect\n            modelIncorrect = true;\n\n            // check model correctness\n            String[] xItems = model.getXLabels();\n            int[] yItems = model.getYValues();\n\n            if (xItems == null) {\n                throw new RuntimeException(\"X labels cannot be null!\"); // NOI18N\n            }\n\n            if (yItems == null) {\n                throw new RuntimeException(\"Y values cannot be null!\"); // NOI18N\n            }\n\n            if ((xItems.length - 1) != yItems.length) {\n                throw new RuntimeException(\"Incorrect x-y values count!\"); // NOI18N\n            }\n\n            // model is correct\n            modelIncorrect = false;\n\n            // update max yvalue\n            maxHeight = getMaxY(yItems);\n\n            // update axes metrics\n            if ((getFont() != null) && (getGraphics() != null) && (getGraphics().getFontMetrics() != null)) {\n                horizAxisHeight = getFont().getSize() + 10;\n                horizLegendWidth = (int) getGraphics().getFontMetrics().getStringBounds(model.getXAxisDesc(), getGraphics())\n                                             .getWidth();\n\n                int maxYMarkWidth = (int) getGraphics().getFontMetrics()\n                                              .getStringBounds(Integer.toString(maxHeight) + \"0\", getGraphics()).getWidth() + 10;\n                int vertLegendWidth = (int) getGraphics().getFontMetrics().getStringBounds(model.getYAxisDesc(), getGraphics())\n                                                .getWidth();\n                vertLegendHeight = getFont().getSize();\n                vertAxisWidth = Math.max(maxYMarkWidth, vertLegendWidth + 4);\n            } else {\n                horizAxisHeight = 0;\n                horizLegendWidth = 0;\n                vertAxisWidth = 0;\n            }\n        }\n\n        // paintComponent() may be running and would clear offScreenImageInvalid flag,\n        // so this code has to be invoked later\n        SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    offScreenImageInvalid = true;\n                    repaint();\n                }\n            });\n    }\n\n    public void componentHidden(ComponentEvent e) {\n    }\n\n    public void componentMoved(ComponentEvent e) {\n    }\n\n    public void componentResized(ComponentEvent e) {\n        offScreenImageSizeInvalid = true;\n        repaint();\n    }\n\n    // ---------------------------------------------------------------------------\n\n    // --- ComponentListener & AncestorListener implementation ---------------------\n    public void componentShown(ComponentEvent e) {\n    }\n\n    // ---------------------------------------------------------------------------\n\n    // --- Static tester ---------------------------------------------------------\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        BarChart barChart = new BarChart();\n\n        BarChartModel barChartModel = new AbstractBarChartModel() {\n            public String[] getXLabels() {\n                return new String[] { \"37\", \"41\", \"45\", \"49\", \"53\", \"57\" };\n            } // NOI18N\n\n            public String getXAxisDesc() {\n                return \"[ms]\";\n            } // NOI18N\n\n            public String getYAxisDesc() {\n                return \"[freq]\";\n            } // NOI18N\n\n            public int[] getYValues() {\n                return new int[] { 55, 60, 90, 80, 10 };\n            }\n        };\n\n        barChart.setModel(barChartModel);\n\n        barChart.setBackground(Color.WHITE);\n        barChart.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n        barChart.setPreferredSize(new Dimension(300, 200));\n\n        barChart.setDraw3D(true);\n        barChart.setLeftOffset(20);\n        barChart.setRightOffset(5);\n        barChart.setTopOffset(30);\n        barChart.setXSpacing(10);\n\n        JFrame frame = new JFrame(\"BarChart Tester\"); // NOI18N\n        frame.getContentPane().add(barChart);\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.pack();\n        frame.setVisible(true);\n    }\n\n    // ---------------------------------------------------------------------------\n\n    // --- Internal implementation -----------------------------------------------\n    public void paintComponent(Graphics g) {\n        // super.paintComponent\n        super.paintComponent(g);\n\n        // check if ChartModel is assigned\n        if ((model == null) || modelIncorrect) {\n            return;\n        }\n\n        // check if the offScreenImage has to be updated\n        if (offScreenImageSizeInvalid) {\n            updateOffScreenImageSize();\n        }\n\n        // paint component to the offScreenImage\n        if (offScreenImageInvalid) {\n            drawChart(offScreenGraphics);\n        }\n\n        // paint offScreenImage to the output Graphics\n        g.drawImage(offScreenImage, insets.left, insets.top, this);\n    }\n\n    protected void drawBar(Graphics2D g2, int startX, int startY, int width, int height) {\n        Polygon topSide = null;\n        Polygon rightSide = null;\n\n        g2.setPaint(fillPaint);\n        g2.fillRect(startX, startY, width, height);\n\n        if (draw3D) {\n            topSide = new Polygon();\n            topSide.addPoint(startX, startY);\n            topSide.addPoint(startX + (width / 3), startY - (width / 3));\n            topSide.addPoint(startX + width + (width / 3), startY - (width / 3));\n            topSide.addPoint(startX + width, startY);\n\n            rightSide = new Polygon();\n            rightSide.addPoint(startX + width, startY);\n            rightSide.addPoint(startX + width + (width / 3), startY - (width / 3));\n            rightSide.addPoint(startX + width + (width / 3), (startY + height) - (width / 3));\n            rightSide.addPoint(startX + width, startY + height);\n\n            if (fillPaint instanceof Color) {\n                g2.setPaint(((Color) fillPaint).brighter());\n            }\n\n            g2.fillPolygon(topSide);\n\n            if (fillPaint instanceof Color) {\n                g2.setPaint(((Color) fillPaint).darker());\n            }\n\n            g2.fillPolygon(rightSide);\n        }\n\n        g2.setStroke(outlineStroke);\n        g2.setPaint(outlinePaint);\n        g2.drawRect(startX, startY, width, height);\n\n        if (draw3D) {\n            g2.drawPolygon(topSide);\n            g2.drawPolygon(rightSide);\n        }\n    }\n\n    protected void drawChart(Graphics2D g2) {\n        // clear component area\n        g2.setColor(getBackground());\n        g2.fillRect(0, 0, drawWidth + 1, drawHeight + 1);\n\n        // fetch data from model\n        String[] xItems = model.getXLabels();\n        int[] yItems = model.getYValues();\n\n        // process only if data available and component has valid size\n        if ((yItems.length > 0) && (drawWidth > 0) && (drawHeight > 0)) {\n            // default outline stroke\n            int outlineStrokeWidth = 0;\n\n            // most likely stroke will be descendant of BasicStroke, set correct stroke width\n            if (outlineStroke instanceof BasicStroke) {\n                outlineStrokeWidth = (int) Math.ceil((((BasicStroke) outlineStroke).getLineWidth() - 1) / 2);\n            }\n\n            // initialize basic scene description\n            int barsCount = yItems.length; // number of bars to be drawn\n            int drawableWidth = drawWidth // effective width of drawing area\n                                - vertAxisWidth // width of vertical axis\n                                - horizLegendWidth // width of horizontal axis legend\n                                - leftOffset // extra left spacing (between vertical axis and first bar)\n                                - rightOffset // extra right spacing (betweel last bar and end of horizontal axis)\n                                - (barsCount * xSpacing) // spacing between bars + one more before horizontal axis legend\n                                - ((horizLegendWidth == 0) ? 0 : 5) // extra space before horizontal axis legend\n                                - (outlineStrokeWidth * 2); // effective stroke width\n            int drawableHeight = drawHeight // effective height of drawing area\n                                 - topOffset // extra top spacing (between highest bar and end of vertical axis)\n                                 - horizAxisHeight // height of horizontal axis\n                                 - (outlineStrokeWidth * 2); // effective stroke width\n\n            // initialize drawing status\n            int drawnWidth = 0;\n            int horizontal3DCorrection = 0;\n            int vertical3DCorrection = 0;\n            int currentX = vertAxisWidth + leftOffset + outlineStrokeWidth;\n            horizAxisXes.clear();\n\n            if (draw3D) {\n                horizontal3DCorrection = drawableWidth / barsCount / 3;\n                drawableWidth -= horizontal3DCorrection;\n                vertical3DCorrection = drawableWidth / barsCount / 3;\n                drawableHeight -= vertical3DCorrection;\n            }\n\n            // draw vertical chart axis\n            drawVerticalAxis(g2, vertical3DCorrection, yItems);\n\n            // draw each bar\n            for (int i = 0; i < barsCount; i++) {\n                int width = (int) ((drawableWidth - drawnWidth) / (barsCount - i));\n                int height = (int) ((drawableHeight * yItems[i]) / (float) maxHeight);\n                int horizLegendX = ((i == 0) ? Math.max(currentX - (xSpacing / 2), vertAxisWidth) : (currentX - (xSpacing / 2)));\n                drawBar(g2, currentX, drawHeight - horizAxisHeight - height - outlineStrokeWidth, width, height);\n                horizAxisXes.add(Integer.valueOf(horizLegendX));\n                currentX += (width + xSpacing);\n                drawnWidth += width;\n            }\n\n            horizAxisXes.add(Integer.valueOf(Math.min(currentX - (xSpacing / 2), drawWidth)));\n\n            // draw horizontal chart axis\n            drawHorizontalAxis(g2, horizAxisXes, xItems);\n        }\n\n        // offScreen image is now valid\n        offScreenImageInvalid = false;\n    }\n\n    protected void drawHorizontalAxis(Graphics2D g2, List<Integer> horizAxisXes, String[] xItems) {\n        g2.setPaint(axisPaint);\n        g2.setStroke(axisStroke);\n\n        g2.drawLine(vertAxisWidth - 3, drawHeight - horizAxisHeight, drawWidth, drawHeight - horizAxisHeight);\n\n        for (int i = 0; i < horizAxisXes.size(); i++) {\n            int x = horizAxisXes.get(i).intValue();\n            g2.drawLine(x, drawHeight - horizAxisHeight + 1, x, drawHeight - horizAxisHeight + 3);\n            drawHorizontalAxisLegendItem(g2, x, xItems[i]);\n        }\n\n        g2.drawString(model.getXAxisDesc(), drawWidth - horizLegendWidth - 2, drawHeight - 5);\n    }\n\n    protected void drawHorizontalAxisLegendItem(Graphics2D g2, int x, String string) {\n        int legendWidth = (int) g2.getFontMetrics().getStringBounds(string, g2).getWidth();\n        int legendX = Math.min(x - (legendWidth / 2), drawWidth - legendWidth - horizLegendWidth - 3);\n        g2.drawString(string, legendX, drawHeight - 5);\n    }\n\n    protected void drawVerticalAxis(Graphics2D g2, int vertical3DCorrection, int[] yItems) {\n        g2.setPaint(axisPaint);\n        g2.setStroke(axisStroke);\n\n        g2.drawLine(vertAxisWidth, 0, vertAxisWidth, drawHeight - horizAxisHeight);\n\n        double factor = (double) (drawHeight - horizAxisHeight - topOffset - vertical3DCorrection) / (double) (maxHeight);\n        long optimalUnits = DecimalAxisUtils.getOptimalUnits(factor, 30);\n\n        long firstMark = 0;\n        long currentMark = firstMark;\n        int markPosition = drawHeight - horizAxisHeight - (int) (currentMark * factor);\n\n        while (markPosition >= (vertLegendHeight + 5)) {\n            g2.setPaint(axisPaint);\n            g2.setStroke(axisStroke);\n            g2.drawLine(vertAxisWidth - 3, markPosition, vertAxisWidth - 1, markPosition);\n\n            drawVerticalAxisLegendItem(g2, markPosition, Long.toString(currentMark));\n\n            g2.setPaint(axisMeshPaint);\n            g2.drawLine(vertAxisWidth, markPosition, vertAxisWidth + drawWidth, markPosition);\n\n            currentMark += optimalUnits;\n            markPosition = drawHeight - horizAxisHeight - (int) (currentMark * factor);\n        }\n\n        g2.setPaint(axisPaint);\n        g2.drawString(model.getYAxisDesc(), 2, vertLegendHeight);\n    }\n\n    protected void drawVerticalAxisLegendItem(Graphics2D g2, int y, String string) {\n        int legendWidth = (int) g2.getFontMetrics().getStringBounds(string, g2).getWidth();\n        int legendHeight = vertLegendHeight;\n        int legendX = vertAxisWidth - legendWidth - 5;\n        int legendY = Math.max((y + (legendHeight / 2)) - 2, (2 * legendHeight) + 3);\n        g2.drawString(string, legendX, legendY);\n    }\n\n    protected void updateOffScreenImageSize() {\n        insets = getInsets();\n\n        drawWidth = getWidth() - insets.left - insets.right;\n        drawHeight = getHeight() - insets.top - insets.bottom - 1;\n\n        offScreenImage = createImage(drawWidth + 1, drawHeight + 1);\n        offScreenGraphics = (Graphics2D) offScreenImage.getGraphics();\n\n        offScreenGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\n\n        offScreenImageSizeInvalid = false;\n        offScreenImageInvalid = true;\n    }\n\n    private int getMaxY(int[] yItems) {\n        int max = Integer.MIN_VALUE;\n\n        for (int yItem : yItems) {\n            if (max < yItem) {\n                max = yItem;\n            }\n        }\n\n        return max;\n    }\n\n    // ---------------------------------------------------------------------------\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/BarChartModel.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts;\n\n\n/**\n *\n * @author Maros Sandor\n * @author Jiri Sedlacek\n */\npublic interface BarChartModel {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Adds new ChartModel listener.\n     * @param listener ChartModel listener to add\n     */\n    public void addChartModelListener(ChartModelListener listener);\n\n    /**\n     * Removes ChartModel listener.\n     * @param listener ChartModel listener to remove\n     */\n    public void removeChartModelListener(ChartModelListener listener);\n\n    String getXAxisDesc();\n\n    String[] getXLabels();\n\n    String getYAxisDesc();\n\n    int[] getYValues();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nSynchronousXYChart_FitToWindowString=Zoom Out to Fit Window\n\n# ------------------------------------------------------------------------------\n# Following are formats for time/date used according to actual display mode\n# Used for timeline in VM Telemetry charts (both big and small)\n# ------------------------------------------------------------------------------\n# Formatting patterns are described in Java API - java.text.SimpleDateFormat\n# ------------------------------------------------------------------------------\n\n# [Name of Day], [Name of Month] [day in month] (for default [en])\nDateTimeAxisUtils_DaysFormat=EEE, MMM d\n# [Hour in day] (0-23) (for default [en])\nDateTimeAxisUtils_HoursFormat=H\n# [Name of Day], [Hour in day] (0-23) (for default [en])\nDateTimeAxisUtils_HoursExtFormat=EEE, H\n# [Hour in day] (0-23):[minute in hour] (for default [en])\nDateTimeAxisUtils_MinutesFormat=H:mm\n# [Name of Day], [Hour in day] (0-23):[minute in hour] (for default [en])\nDateTimeAxisUtils_MinutesExtFormat=EEE, H:mm\n# [Hour in day] (0-23):[minute in hour]:[second in minute] (for default [en])\nDateTimeAxisUtils_SecondsFormat=H:mm:ss\n# [Name of Day], [Hour in day] (0-23):[minute in hour]:[second in minute] (for default [en])\nDateTimeAxisUtils_SecondsExtFormat=EEE, H:mm:ss\n# [Hour in day] (0-23):[minute in hour]:[second in minute].[millisecond in second] (for default [en])\nDateTimeAxisUtils_MillisFormat=H:mm:ss.SSS\n# [Name of Day], [Hour in day] (0-23):[minute in hour]:[second in minute].[millisecond in second] (for default [en])\nDateTimeAxisUtils_MillisExtFormat=EEE, H:mm:ss.SSS\n# [Name of Day], [Name of Month] [day in month], [Hour in day] (0-23):[minute in hour]:[second in minute].[millisecond in second] (for default [en])\nDateTimeAxisUtils_MillisFullFormat=EEE, MMM d, H:mm:ss.SSS\n# [millisecond in second] (for default [en])\nDateTimeAxisUtils_MillisOnlyFormat=SSS\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/ChartActionListener.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ChartActionListener {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void chartDataChanged();\n\n    public void chartFitToWindowChanged();\n\n    public void chartPanned();\n\n    public void chartTrackingEndChanged();\n\n    public void chartZoomed();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/ChartModelListener.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ChartModelListener {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void chartDataChanged();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/DateTimeAxisUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts;\n\nimport java.awt.*;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.ResourceBundle;\n\n\n/**\n *\n * @author  Jiri Sedlacek\n */\npublic class DateTimeAxisUtils {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.charts.Bundle\"); // NOI18N\n    private static final String DAYS_FORMAT = messages.getString(\"DateTimeAxisUtils_DaysFormat\"); // NOI18N\n    private static final String HOURS_FORMAT = messages.getString(\"DateTimeAxisUtils_HoursFormat\"); // NOI18N\n    private static final String HOURS_EXT_FORMAT = messages.getString(\"DateTimeAxisUtils_HoursExtFormat\"); // NOI18N\n    private static final String MINUTES_FORMAT = messages.getString(\"DateTimeAxisUtils_MinutesFormat\"); // NOI18N\n    private static final String MINUTES_EXT_FORMAT = messages.getString(\"DateTimeAxisUtils_MinutesExtFormat\"); // NOI18N\n    private static final String SECONDS_FORMAT = messages.getString(\"DateTimeAxisUtils_SecondsFormat\"); // NOI18N\n    private static final String SECONDS_EXT_FORMAT = messages.getString(\"DateTimeAxisUtils_SecondsExtFormat\"); // NOI18N\n    private static final String MILLIS_FORMAT = messages.getString(\"DateTimeAxisUtils_MillisFormat\"); // NOI18N\n    private static final String MILLIS_EXT_FORMAT = messages.getString(\"DateTimeAxisUtils_MillisExtFormat\"); // NOI18N\n    private static final String MILLIS_FULL_FORMAT = messages.getString(\"DateTimeAxisUtils_MillisFullFormat\"); // NOI18N\n    private static final String MILLIS_ONLY_FORMAT = messages.getString(\"DateTimeAxisUtils_MillisOnlyFormat\"); // NOI18N\n                                                                                                               // -----\n    public static final int MIN_TIMEMARK_STEP = 100; // The minimal distance between two time marks\n    public static final Color BASE_TIMELINE_COLOR = new Color(0, 0, 0);\n    public static final Color MAIN_TIMELINE_COLOR = new Color(150, 150, 150);\n    public static final Color TICK_TIMELINE_COLOR = new Color(230, 230, 230);\n    private static final int TIME_FORMAT_UNKNOWN = -1;\n    private static final int TIME_FORMAT_MILLIS = 10;\n    private static final int TIME_FORMAT_SECONDS = 20;\n    private static final int TIME_FORMAT_MINUTES = 30;\n    private static final int TIME_FORMAT_HOURS = 40;\n    private static final int TIME_FORMAT_DAYS = 50;\n    private static final SimpleDateFormat daysDateFormat = new SimpleDateFormat(DAYS_FORMAT);\n    private static final SimpleDateFormat hoursDateFormat = new SimpleDateFormat(HOURS_FORMAT);\n    private static final SimpleDateFormat hoursDateFormatD = new SimpleDateFormat(HOURS_EXT_FORMAT);\n    private static final SimpleDateFormat minutesDateFormat = new SimpleDateFormat(MINUTES_FORMAT);\n    private static final SimpleDateFormat minutesDateFormatD = new SimpleDateFormat(MINUTES_EXT_FORMAT);\n    private static final SimpleDateFormat secondsDateFormat = new SimpleDateFormat(SECONDS_FORMAT);\n    private static final SimpleDateFormat secondsDateFormatD = new SimpleDateFormat(SECONDS_EXT_FORMAT);\n    private static final SimpleDateFormat millisDateFormat = new SimpleDateFormat(MILLIS_FORMAT);\n    private static final SimpleDateFormat millisDateFormatD = new SimpleDateFormat(MILLIS_EXT_FORMAT);\n    private static final SimpleDateFormat millisDateFormatF = new SimpleDateFormat(MILLIS_FULL_FORMAT);\n    private static final SimpleDateFormat onlyMillisDateFormat = new SimpleDateFormat(MILLIS_ONLY_FORMAT);\n    private static final long[] timeUnitsGrid = new long[] {\n                                                    10, 20, 50, 100, 250, 500, // milliseconds\n    1000, 2000, 5000, 10000, 15000, 30000, // seconds\n    60000, 120000, 300000, 600000, 900000, 1800000, // minutes\n    3600000, 7200000, 10800000, 21600000, 43200000, // hours\n    86400000, 172800000, 259200000, 432000000\n                                                }; // days\n    private static final int[] timeUnitsFormat = new int[] {\n                                                     TIME_FORMAT_MILLIS, TIME_FORMAT_MILLIS, TIME_FORMAT_MILLIS,\n                                                     TIME_FORMAT_MILLIS, TIME_FORMAT_MILLIS, TIME_FORMAT_MILLIS,\n                                                     TIME_FORMAT_SECONDS, TIME_FORMAT_SECONDS, TIME_FORMAT_SECONDS,\n                                                     TIME_FORMAT_SECONDS, TIME_FORMAT_SECONDS, TIME_FORMAT_SECONDS,\n                                                     TIME_FORMAT_MINUTES, TIME_FORMAT_MINUTES, TIME_FORMAT_MINUTES,\n                                                     TIME_FORMAT_MINUTES, TIME_FORMAT_MINUTES, TIME_FORMAT_MINUTES,\n                                                     TIME_FORMAT_HOURS, TIME_FORMAT_HOURS, TIME_FORMAT_HOURS, TIME_FORMAT_HOURS,\n                                                     TIME_FORMAT_HOURS, TIME_FORMAT_DAYS, TIME_FORMAT_DAYS, TIME_FORMAT_DAYS,\n                                                     TIME_FORMAT_DAYS\n                                                 };\n    private static final HashMap<Long, Integer> timeUnitsToIndex = new HashMap<>();\n\n    static {\n        for (int i = 0; i < timeUnitsGrid.length; i++) {\n            timeUnitsToIndex.put(new Long(timeUnitsGrid[i]), Integer.valueOf(i));\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static String getDaysValue(long mark, boolean useDayMark) {\n        return daysDateFormat.format(new Date(mark));\n    }\n\n    public static String getHoursValue(long mark, boolean useDayMark) {\n        return (useDayMark ? hoursDateFormatD.format(new Date(mark)) : hoursDateFormat.format(new Date(mark)));\n    }\n\n    public static double getMaximumScale(long optimalUnits) {\n        return (double) MIN_TIMEMARK_STEP / (double) optimalUnits;\n    }\n\n    public static String getMillisValue(long mark, boolean useDayMark) {\n        return (useDayMark ? millisDateFormatD.format(new Date(mark)) : millisDateFormat.format(new Date(mark)));\n    }\n\n    public static String getMillisValueFull(long mark) {\n        return millisDateFormatF.format(new Date(mark));\n    }\n\n    public static String getMinutesValue(long mark, boolean useDayMark) {\n        return (useDayMark ? minutesDateFormatD.format(new Date(mark)) : minutesDateFormat.format(new Date(mark)));\n    }\n\n    public static long getOptimalUnits(double factor) {\n        for (long l : timeUnitsGrid) {\n            if ((l * factor) >= MIN_TIMEMARK_STEP) {\n                return l;\n            }\n        }\n\n        return timeUnitsGrid[timeUnitsGrid.length - 1];\n    }\n\n    public static String getSecondsValue(long mark, boolean useDayMark) {\n        return (useDayMark ? secondsDateFormatD.format(new Date(mark)) : secondsDateFormat.format(new Date(mark)));\n    }\n\n    public static String getTimeMarkMillisString(long mark, long optimalUnits) {\n        int format = getTimeUnitsFormat(optimalUnits);\n\n        if (format != TIME_FORMAT_MILLIS) {\n            return \"\"; // NOI18N\n        }\n\n        return onlyMillisDateFormat.format(new Date(mark));\n    }\n\n    public static String getTimeMarkNoMillisString(long mark, long optimalUnits, boolean useDayMark) {\n        int format = getTimeUnitsFormat(optimalUnits);\n\n        if (format == TIME_FORMAT_UNKNOWN) {\n            return \"\"; // NOI18N\n        }\n\n        if (format == TIME_FORMAT_MILLIS) {\n            format = TIME_FORMAT_SECONDS;\n        }\n\n        return getTimeMarkStringFromFormat(mark, format, useDayMark);\n    }\n\n    public static String getTimeMarkString(long mark, long optimalUnits, boolean useDayMark) {\n        int format = getTimeUnitsFormat(optimalUnits);\n\n        if (format == TIME_FORMAT_UNKNOWN) {\n            return \"\"; // NOI18N\n        }\n\n        return getTimeMarkStringFromFormat(mark, format, useDayMark);\n    }\n\n    private static String getTimeMarkStringFromFormat(long mark, int format, boolean useDayMark) {\n        switch (format) {\n            case TIME_FORMAT_MILLIS:\n                return getMillisValue(mark, useDayMark);\n            case TIME_FORMAT_SECONDS:\n\n            //return getSecondsValue(mark, useDayMark);\n            case TIME_FORMAT_MINUTES:\n\n            //return getMinutesValue(mark, useDayMark);\n            case TIME_FORMAT_HOURS:\n\n                //return getHoursValue(mark, useDayMark);\n                return getSecondsValue(mark, useDayMark);\n            case TIME_FORMAT_DAYS:\n                return getDaysValue(mark, useDayMark);\n            default:\n                return \"\"; // NOI18N\n        }\n    }\n\n    private static int getTimeUnitsFormat(long optimalUnits) {\n        int timeUnitsFormatIndex = getUnitsIndex(optimalUnits);\n\n        if (timeUnitsFormatIndex == -1) {\n            return TIME_FORMAT_UNKNOWN;\n        }\n\n        return timeUnitsFormat[timeUnitsFormatIndex];\n    }\n\n    private static int getUnitsIndex(long optimalUnits) {\n        Integer oTimeUnitsFormatIndex = timeUnitsToIndex.get(new Long(optimalUnits));\n\n        if (oTimeUnitsFormatIndex == null) {\n            return -1;\n        }\n\n        return oTimeUnitsFormatIndex.intValue();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/DecimalAxisUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts;\n\n\n/**\n *\n * @author  Jiri Sedlacek\n */\npublic class DecimalAxisUtils {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final long[] timeUnitsGrid = new long[] { 1, 2, 5 };\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static long getOptimalUnits(double factor, int minimumVerticalMarksDistance) {\n        if (factor <= 0) {\n            return 0;\n        }\n\n        long decimalFactor = 1;\n\n        while (true) {\n            for (long l : timeUnitsGrid) {\n                if ((l * decimalFactor * factor) >= minimumVerticalMarksDistance) {\n                    return l * decimalFactor;\n                }\n            }\n\n            decimalFactor *= 10;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/DynamicPieChartModel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts;\n\nimport java.awt.Color;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DynamicPieChartModel extends AbstractPieChartModel {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected Color[] itemColors;\n    protected String[] itemNames;\n    protected double[] itemValues;\n    protected double[] itemValuesRel;\n    protected boolean hasData = false;\n    protected int itemCount = 0;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Color getItemColor(int index) {\n        return itemColors[index];\n    }\n\n    // --- Abstract PieChartModel ------------------------------------------------\n    public int getItemCount() {\n        return itemCount;\n    }\n\n    public String getItemName(int index) {\n        return itemNames[index];\n    }\n\n    public double getItemValue(int index) {\n        return itemValues[index];\n    }\n\n    public double getItemValueRel(int index) {\n        return itemValuesRel[index];\n    }\n\n    public void setItemValues(double[] itemValues) {\n        if (itemValues.length != itemCount) {\n            hasData = false;\n            throw new RuntimeException(\"Unexpected number of values.\"); // NOI18N\n        } else {\n            this.itemValues = itemValues;\n            updateItemValuesRel();\n        }\n\n        fireChartDataChanged();\n    }\n\n    public boolean isSelectable(int index) {\n        return true;\n    }\n\n    public boolean hasData() {\n        return hasData;\n    }\n\n    public void setupModel(String[] itemNames, Color[] itemColors) {\n        this.itemNames = itemNames;\n        this.itemColors = itemColors;\n\n        if (itemNames.length != itemColors.length) {\n            itemCount = 0;\n            throw new RuntimeException(\"Counts of item names and item colors don't match.\"); // NOI18N\n        } else {\n            itemCount = itemNames.length;\n        }\n\n        itemValues = null;\n        itemValuesRel = new double[itemCount];\n        hasData = false;\n    }\n\n    // --- Private Implementation ------------------------------------------------\n\n    // computes relative item values\n    // O(n) = 2n\n    private void updateItemValuesRel() {\n        double sum = 0d;\n\n        // compute sum of all item values\n        for (double itemValue : itemValues) {\n            sum += itemValue;\n        }\n\n        // compute new relative item values\n        if (sum == 0) {\n            for (int i = 0; i < itemValues.length; i++) {\n                itemValuesRel[i] = 0;\n            }\n\n            hasData = false;\n        } else {\n            for (int i = 0; i < itemValues.length; i++) {\n                itemValuesRel[i] = itemValues[i] / sum;\n            }\n\n            hasData = true;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/PieChart.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.awt.geom.*;\nimport java.util.ArrayList;\nimport javax.accessibility.Accessible;\nimport javax.accessibility.AccessibleContext;\nimport javax.swing.*;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class PieChart extends JComponent implements ComponentListener, ChartModelListener, Accessible {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static Color evenSelectionSegmentsColor = Color.WHITE;\n    private static Stroke evenSelectionSegmentsStroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0,\n                                                                        new float[] { 5, 5 }, 0);\n    private static Color oddSelectionSegmentColor = Color.BLACK;\n    private static Stroke oddSelectionSegmentStroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0,\n                                                                      new float[] { 5, 5 }, 5);\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private AccessibleContext accessibleContext;\n    private Area pieArea;\n    private Graphics2D offScreenGraphics;\n    private Image offScreenImage;\n    private Insets insets = new Insets(0, 0, 0, 0);\n    private PieChartModel model;\n    private java.util.List<Arc2D> arcs = new ArrayList<>();\n    private java.util.List<Area> bottoms = new ArrayList<>();\n    private java.util.List<Integer> selectedItems = new ArrayList<>();\n    private boolean draw3D = true; // (chartHeight > 0)\n    private boolean offScreenImageInvalid;\n    private boolean offScreenImageSizeInvalid;\n    private int chartHeight = 15; // height of the 3D chart (0 means 2D chart)\n    private int drawHeight;\n    private int drawWidth;\n    private int focusedItem = -1;\n    private int initialAngle = 0; // start of first item (degrees)\n    private int pieCenterY; // (pieHeight / 2)\n    private int pieHeight; // (drawHeight - chartHeight)\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of PieChart */\n    public PieChart() {\n        offScreenImageSizeInvalid = true;\n\n        addComponentListener(this);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setAccessibleContext(AccessibleContext accessibleContext) {\n        this.accessibleContext = accessibleContext;\n    }\n\n    public AccessibleContext getAccessibleContext() {\n        return accessibleContext;\n    }\n\n    public void setChartHeight(int chartHeight) {\n        this.chartHeight = chartHeight;\n        draw3D = (chartHeight > 0);\n    }\n\n    public int getChartHeight() {\n        return chartHeight;\n    }\n\n    public void setFocusedItem(int focusedItem) {\n        if (this.focusedItem != focusedItem) {\n            this.focusedItem = focusedItem;\n            offScreenImageInvalid = true;\n            repaint();\n        }\n    }\n\n    public int getItemIndexAt(int x, int y) {\n        // switch to geometry coordinate space\n        x -= insets.left;\n        y -= insets.top;\n\n        // test arcs\n        int i = 0;\n        for (Arc2D a : arcs) {\n            if (a.contains(x, y)) {\n                return i;\n            }\n            i++;\n        }\n\n        // test 3D bottoms\n        i = 0;\n        if (draw3D) {\n            for (Area area : bottoms) {\n                if (area == null) {\n                    continue;\n                } else if (area.contains(x, y)) {\n                    return i;\n                }\n            }\n        }\n\n        // no item hit\n        return -1;\n    }\n\n    public void setModel(PieChartModel model) {\n        // automatically unregister itself as a ChartModelListener from current model\n        if (this.model != null) {\n            this.model.removeChartModelListener(this);\n        }\n\n        // automatically register itself as a ChartModelListener for new model\n        if (model != null) {\n            model.addChartModelListener(this);\n        }\n\n        this.model = model;\n\n        chartDataChanged();\n    }\n\n    public PieChartModel getModel() {\n        return model;\n    }\n\n    public void setSelectedItem(int selectedItem) {\n        if (selectedItems.contains(selectedItem) && (selectedItems.size() == 1)) {\n            return;\n        }\n\n        selectedItems.clear();\n        selectedItems.add(selectedItem);\n\n        offScreenImageInvalid = true;\n        repaint();\n    }\n\n    public int[] getSelectedItems() {\n        int[] items = new int[selectedItems.size()];\n\n        for (int i = 0; i < selectedItems.size(); i++) {\n            items[i] = selectedItems.get(i).intValue();\n        }\n\n        return items;\n    }\n\n    public void setStartAngle(int initialAngle) {\n        this.initialAngle = initialAngle;\n    }\n\n    public int getStartAngle() {\n        return initialAngle;\n    }\n\n    public void addSelectedItem(int selectedItem) {\n        if (selectedItems.contains(selectedItem)) {\n            return;\n        }\n\n        selectedItems.add(selectedItem);\n\n        offScreenImageInvalid = true;\n        repaint();\n    }\n\n    // Used for public chart update & listener implementation\n    public void chartDataChanged() {\n        //    offScreenImageInvalid = true;\n        //    repaint();\n        selectAllItems(); // also invalidates offscreen image and repaints\n    }\n\n    // --- ComponentListener implementation --------------------------------------\n    public void componentHidden(ComponentEvent e) {\n    }\n\n    public void componentMoved(ComponentEvent e) {\n    }\n\n    public void componentResized(ComponentEvent e) {\n        offScreenImageSizeInvalid = true;\n        repaint();\n    }\n\n    public void componentShown(ComponentEvent e) {\n    }\n\n    public void deselectAllItems() {\n        selectedItems.clear();\n\n        offScreenImageInvalid = true;\n        repaint();\n    }\n\n    // --- Main (Tester Frame) ---------------------------------------------------\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        final PieChart pieChart = new PieChart();\n        pieChart.setBorder(BorderFactory.createEmptyBorder(5, 20, 5, 20));\n        pieChart.setPreferredSize(new Dimension(300, 200));\n\n        DynamicPieChartModel pieChartModel = new DynamicPieChartModel();\n        pieChartModel.setupModel(new String[] { \"Item 1\", \"Item 2\", \"Item 3\", \"Item 4\" }, // NOI18N\n                                 new Color[] { Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW });\n        pieChartModel.setItemValues(new double[] { 10, 5, 15, 7 });\n\n        JFrame frame = new JFrame(\"PieChart Tester\"); // NOI18N\n        frame.getContentPane().add(pieChart);\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.pack();\n        frame.setVisible(true);\n\n        pieChart.addMouseListener(new MouseAdapter() {\n                public void mouseClicked(MouseEvent e) {\n                    int clickedItem = pieChart.getItemIndexAt(e.getX(), e.getY());\n                    pieChart.toggleItemSelection(clickedItem);\n                }\n            });\n\n        pieChart.addMouseMotionListener(new MouseMotionAdapter() {\n                public void mouseMoved(MouseEvent e) {\n                    int focusedItem = pieChart.getItemIndexAt(e.getX(), e.getY());\n\n                    if (focusedItem != -1) {\n                        pieChart.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n                    } else {\n                        pieChart.setCursor(Cursor.getDefaultCursor());\n                    }\n\n                    pieChart.setFocusedItem(focusedItem);\n                }\n            });\n\n        pieChart.setModel(pieChartModel);\n    }\n\n    public void paintComponent(Graphics g) {\n        // super.paintComponent\n        super.paintComponent(g);\n\n        // check if ChartModel is assigned\n        if (model == null) {\n            return;\n        }\n\n        // check if the offScreenImage has to be updated\n        if (offScreenImageSizeInvalid) {\n            updateOffScreenImageSize();\n        }\n\n        // paint component to the offScreenImage\n        if (offScreenImageInvalid) {\n            drawChart(offScreenGraphics);\n        }\n\n        // paint offScreenImage to the output Graphics\n        g.drawImage(offScreenImage, insets.left, insets.top, this);\n    }\n\n    public void removeSelectedItem(int selectedItem) {\n        if (!selectedItems.contains(selectedItem)) {\n            return;\n        }\n\n        selectedItems.remove((Integer) selectedItem);\n\n        offScreenImageInvalid = true;\n        repaint();\n    }\n\n    public void resetFocusedItem() {\n        if (focusedItem != -1) {\n            focusedItem = -1;\n            offScreenImageInvalid = true;\n            repaint();\n        }\n    }\n\n    public void selectAllItems() {\n        for (int i = 0; i < model.getItemCount(); i++) {\n            selectedItems.add(i);\n        }\n\n        offScreenImageInvalid = true;\n        repaint();\n    }\n\n    public void toggleItemSelection(int selectedItem) {\n        if (selectedItems.contains(selectedItem)) {\n            removeSelectedItem(selectedItem);\n        } else {\n            addSelectedItem(selectedItem);\n        }\n    }\n\n    protected Color getDisabledColor(Color color) {\n        int r = color.getRed();\n        int g = color.getGreen();\n        int b = color.getBlue();\n\n        return new Color(r, g, b, 50);\n    }\n\n    protected void drawChart(Graphics2D g2) {\n        arcs.clear();\n        bottoms.clear();\n\n        Area focusedItemArea = null;\n\n        g2.setColor(getBackground());\n        g2.fillRect(0, 0, drawWidth + 1, drawHeight + 1);\n\n        g2.setStroke(new BasicStroke(0.5f));\n\n        if (!model.hasData()) {\n            // no data to display, draws only pie outline\n            Area rectAreaUpper = new Area(new Rectangle2D.Double(0, pieCenterY + 1, drawWidth - 1, pieCenterY + pieHeight));\n            rectAreaUpper.subtract(pieArea);\n\n            Area rectAreaLower = new Area(rectAreaUpper);\n            rectAreaLower.transform(AffineTransform.getTranslateInstance(0, chartHeight));\n            rectAreaUpper.subtract(rectAreaLower);\n\n            g2.setPaint(Color.BLACK);\n            g2.draw(rectAreaUpper);\n            g2.drawArc(0, 0, drawWidth - 1, pieHeight, 0, 180);\n        } else {\n            // data collected, draws standard pie\n            int startAngle = this.initialAngle;\n            int extentAngle;\n\n            Point2D startPoint;\n            Point2D endPoint;\n\n            Point2D bottomStartPoint;\n            Point2D bottomEndPoint;\n\n            boolean startPointVisible;\n            boolean endPointVisible;\n\n            double left = 0;\n            double right = 0;\n            double width = 0;\n\n            double top = 0;\n            double bottom = 0;\n            double height = 0;\n\n            Arc2D.Double arc;\n            Rectangle2D.Double rectangle;\n\n            int pieParts = model.getItemCount();\n\n            for (int i = 0; i < pieParts; i++) {\n                if (model.getItemValueRel(i) == 0) {\n                    continue;\n                }\n\n                extentAngle = (int) Math.min(Math.ceil(model.getItemValueRel(i) * 360), 360 - startAngle);\n\n                if (extentAngle == 0) {\n                    continue;\n                }\n\n                arc = new Arc2D.Double(0, 1, drawWidth - 1, pieHeight, startAngle, extentAngle, Arc2D.PIE);\n\n                arcs.add(arc);\n\n                if (i == focusedItem) {\n                    if (pieParts == 1) {\n                        focusedItemArea = new Area(new Ellipse2D.Double(0, 1, drawWidth - 1, pieHeight));\n                    } else {\n                        focusedItemArea = new Area(arc);\n                    }\n                }\n\n                if (draw3D) {\n                    startPoint = arc.getStartPoint();\n                    endPoint = arc.getEndPoint();\n\n                    startPointVisible = ((startAngle < 0) || (startAngle > 180));\n                    endPointVisible = (((startAngle + extentAngle) < 0) || ((startAngle + extentAngle) > 180));\n\n                    if (startPointVisible && endPointVisible) {\n                        // both endpoints visible\n                        if (startPoint.getX() < endPoint.getX()) {\n                            // whole pie is visible\n                            left = startPoint.getX();\n                            right = endPoint.getX();\n                            width = right - left;\n\n                            top = Math.min(startPoint.getY(), endPoint.getY()) - 1;\n                            bottom = drawHeight;\n                            height = bottom - top;\n\n                            Area bottomArea = drawChartPartSide(g2, pieArea, left, top, width, height,\n                                                                selectedItems.contains(i) ? model.getItemColor(i).darker()\n                                                                                          : getDisabledColor(model.getItemColor(i)\n                                                                                                                  .darker()));\n                            bottoms.add(bottomArea);\n\n                            if ((i == focusedItem) && (focusedItemArea != null)) {\n                                focusedItemArea.add(bottomArea);\n                            }\n                        } else {\n                            // pie is splitted into two parts\n                            left = startPoint.getX();\n                            right = drawWidth - 1;\n                            width = right - left;\n\n                            top = pieCenterY + 1;\n                            bottom = drawHeight;\n                            height = bottom - top;\n\n                            Area bottomArea = drawChartPartSide(g2, pieArea, left, top, width, height,\n                                                                selectedItems.contains(i) ? model.getItemColor(i).darker()\n                                                                                          : getDisabledColor(model.getItemColor(i)\n                                                                                                                  .darker()));\n\n                            left = 0;\n                            right = endPoint.getX();\n                            width = right - left;\n\n                            top = pieCenterY + 1;\n                            bottom = drawHeight;\n                            height = bottom - top;\n\n                            Area bottomArea2 = drawChartPartSide(g2, pieArea, left, top, width, height,\n                                                                 selectedItems.contains(i) ? model.getItemColor(i).darker()\n                                                                                           : getDisabledColor(model.getItemColor(i)\n                                                                                                                   .darker()));\n                            bottomArea.add(bottomArea2);\n                            bottoms.add(bottomArea);\n\n                            if ((i == focusedItem) && (focusedItemArea != null)) {\n                                focusedItemArea.add(bottomArea);\n                            }\n                        }\n                    } else if (startPointVisible || endPointVisible) {\n                        // one endpoint visible\n                        if (startPointVisible && !endPointVisible) {\n                            left = startPoint.getX();\n                            right = drawWidth - 1;\n                            width = right - left;\n\n                            top = pieCenterY + 1;\n                            bottom = drawHeight;\n                            height = bottom - top;\n\n                            Area bottomArea = drawChartPartSide(g2, pieArea, left, top, width, height,\n                                                                selectedItems.contains(i) ? model.getItemColor(i).darker()\n                                                                                          : getDisabledColor(model.getItemColor(i)\n                                                                                                                  .darker()));\n                            bottoms.add(bottomArea);\n\n                            if ((i == focusedItem) && (focusedItemArea != null)) {\n                                focusedItemArea.add(bottomArea);\n                            }\n                        } else {\n                            left = 0;\n                            right = endPoint.getX();\n                            width = right - left;\n\n                            top = pieCenterY + 1;\n                            bottom = drawHeight;\n                            height = bottom - top;\n\n                            Area bottomArea = drawChartPartSide(g2, pieArea, left, top, width, height,\n                                                                selectedItems.contains(i) ? model.getItemColor(i).darker()\n                                                                                          : getDisabledColor(model.getItemColor(i)\n                                                                                                                  .darker()));\n                            bottoms.add(bottomArea);\n\n                            if ((i == focusedItem) && (focusedItemArea != null)) {\n                                focusedItemArea.add(bottomArea);\n                            }\n                        }\n                    } else if (extentAngle >= 180) {\n                        // no endpoint visible\n                        left = 0;\n                        right = drawWidth - 1;\n                        width = right - left;\n\n                        top = pieCenterY + 1;\n                        bottom = drawHeight;\n                        height = bottom - top;\n\n                        Area bottomArea = drawChartPartSide(g2, pieArea, left, top, width, height,\n                                                            selectedItems.contains(i) ? model.getItemColor(i).darker()\n                                                                                      : getDisabledColor(model.getItemColor(i)\n                                                                                                              .darker()));\n                        bottoms.add(bottomArea);\n\n                        if ((i == focusedItem) && (focusedItemArea != null)) {\n                            focusedItemArea.add(bottomArea);\n                        }\n                    } else {\n                        // no bottom visible\n                        bottoms.add(null);\n                    }\n                }\n\n                g2.setPaint(selectedItems.contains(i) ? model.getItemColor(i) : getDisabledColor(model.getItemColor(i)));\n                g2.fill(arc);\n                //        g2.setPaint(model.getItemColor(i).darker().darker());\n                //        g2.setPaint(Color.BLACK);\n                //        g2.draw(arc);\n                startAngle += extentAngle;\n            }\n        }\n\n        if (focusedItemArea != null) {\n            g2.setColor(evenSelectionSegmentsColor);\n            g2.setStroke(evenSelectionSegmentsStroke);\n            g2.draw(focusedItemArea);\n\n            g2.setColor(oddSelectionSegmentColor);\n            g2.setStroke(oddSelectionSegmentStroke);\n            g2.draw(focusedItemArea);\n        }\n\n        offScreenImageInvalid = false;\n    }\n\n    protected Area drawChartPartSide(Graphics2D g2, Area pieArea, double left, double top, double width, double height,\n                                     Color color) {\n        Area rectAreaUpper = new Area(new Rectangle2D.Double(left, top, width, height));\n        rectAreaUpper.subtract(pieArea);\n\n        Area rectAreaLower = new Area(rectAreaUpper);\n        rectAreaLower.transform(AffineTransform.getTranslateInstance(0, chartHeight));\n        rectAreaUpper.subtract(rectAreaLower);\n        rectAreaUpper.transform(AffineTransform.getTranslateInstance(0, -1));\n        rectAreaUpper.subtract(pieArea);\n\n        g2.setPaint(color);\n        g2.fill(rectAreaUpper);\n\n        //    g2.setPaint(Color.BLACK);\n        //    g2.draw(rectAreaUpper);\n        return rectAreaUpper;\n    }\n\n    // --- Protected implementation ------------------------------------------------\n    protected void updateOffScreenImageSize() {\n        insets = getInsets();\n\n        drawWidth = getWidth() - insets.left - insets.right;\n        drawHeight = getHeight() - insets.top - insets.bottom - 1;\n\n        pieHeight = drawHeight - chartHeight;\n        pieCenterY = pieHeight / 2;\n\n        offScreenImage = createImage(drawWidth + 1, drawHeight + 1);\n        offScreenGraphics = (Graphics2D) offScreenImage.getGraphics();\n\n        offScreenGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\n\n        offScreenImageSizeInvalid = false;\n        offScreenImageInvalid = true;\n\n        pieArea = new Area(new Ellipse2D.Double(0, 0, drawWidth - 1, pieHeight));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/PieChartModel.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts;\n\nimport java.awt.Color;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface PieChartModel {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Color getItemColor(int index); // color of item\n\n    public int getItemCount(); // number of displayed (processed) items\n\n    public String getItemName(int index); // name of item\n\n    public double getItemValue(int index); // value of item\n\n    public double getItemValueRel(int index); // relative item value (<0, 1>, E(items) = 1)\n\n    public boolean isSelectable(int index); // is the given item ready to be selected?\n\n    /**\n     * Adds new ChartModel listener.\n     * @param listener ChartModel listener to add\n     */\n    public void addChartModelListener(ChartModelListener listener);\n\n    public boolean hasData(); // does the model contain some non-zero item?\n\n    /**\n     * Removes ChartModel listener.\n     * @param listener ChartModel listener to remove\n     */\n    public void removeChartModelListener(ChartModelListener listener);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/xy/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nProfilerXYChart_ZoomInString=Zoom In (Mouse Wheel)\nProfilerXYChart_ZoomOutString=Zoom Out (Mouse Wheel)\nProfilerXYChart_FixedScaleString=Fixed Scale (Mouse Wheel Click)\nProfilerXYChart_ScaleToFitString=Scale To Fit (Mouse Wheel Click)\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/xy/ProfilerGCXYItem.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts.xy;\n\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerGCXYItem extends SynchronousXYItem {\n\n    // --- Constructor ---------------------------------------------------------\n\n    public ProfilerGCXYItem(String name) {\n        super(name, Long.MAX_VALUE, Long.MIN_VALUE);\n    }\n\n\n    // --- Item telemetry ------------------------------------------------------\n\n    public abstract long[] getGCStarts(int index);\n\n    public abstract long[] getGCEnds(int index);\n\n\n    public long getYValue(int index) { return 0; }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/xy/ProfilerGCXYItemPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts.xy;\n\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartItemChange;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemChange;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemPainter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ProfilerGCXYItemPainter extends SynchronousXYItemPainter {\n\n    // --- Constructor ---------------------------------------------------------\n\n    public static ProfilerGCXYItemPainter painter(Color fillColor) {\n\n        return new ProfilerGCXYItemPainter(fillColor);\n    }\n\n\n    ProfilerGCXYItemPainter(Color fillColor) {\n        super(0, null, fillColor, TYPE_ABSOLUTE, 0);\n    }\n\n\n    // --- ItemPainter implementation ------------------------------------------\n\n    public LongRect getItemBounds(ChartItem item, ChartContext context) {\n//        if (!(item instanceof ProfilerGCXYItem))\n//            throw new UnsupportedOperationException(\"Unsupported item: \" + item); // NOI18N\n\n        // TODO: should return real bounds (== empty bounds for no gc)\n\n        LongRect viewBounds = super.getItemBounds(item, context);\n        viewBounds.y = 0;\n        viewBounds.height = context.getViewportHeight();\n        return viewBounds;\n    }\n\n    public LongRect getDirtyBounds(ChartItemChange itemChange, ChartContext context) {\n//        if (!(itemChange instanceof XYItemChange))\n//            throw new UnsupportedOperationException(\"Unsupported itemChange: \" + itemChange);\n        \n        XYItemChange change = (XYItemChange)itemChange;\n        ProfilerGCXYItem item = (ProfilerGCXYItem)change.getItem();\n        \n        int[] indexes = change.getValuesIndexes();\n\n        if (indexes.length == 1 && indexes[0] == -1) {\n            // Data reset\n            LongRect dirtyBounds = change.getDirtyValuesBounds();\n            \n            long x = (long)context.getViewX(dirtyBounds.x);\n            long y = (long)context.getViewY(context.getDataOffsetY() +\n                                            context.getDataHeight());\n            long width = (long)context.getViewWidth(dirtyBounds.width);\n            long height = context.getViewportHeight();\n\n            return new LongRect(x, y, width, height);\n        } else {\n            // New data\n            int index = indexes[0];\n            int lastIndex = indexes[indexes.length - 1];\n\n            long dataStart = -1;\n            long dataEnd   = -1;\n\n            while (index <= lastIndex) {\n                long[] gcEnds = item.getGCEnds(index);\n                if (gcEnds.length > 0) {\n                    dataEnd = gcEnds[gcEnds.length - 1];\n                    if (dataStart == -1) {\n                        long[] gcStarts = item.getGCStarts(index);\n                        dataStart = gcStarts[0];\n                    }\n                }\n                index++;\n            }\n\n            if (dataStart == -1) return new LongRect();\n            if (dataEnd == -1) dataEnd = item.getXValue(item.getValuesCount() - 1);\n\n            long x = (long)context.getViewX(dataStart);\n            long y = (long)context.getViewY(context.getDataOffsetY() +\n                                            context.getDataHeight());\n            long width = (long)context.getViewWidth(dataEnd - dataStart);\n            width = Math.max(width, 1);\n            long height = context.getViewportHeight();\n\n            return new LongRect(x, y, width, height);\n\n        }\n    }\n\n\n    public double getItemView(double dataY, XYItem item, ChartContext context) {\n        return 0;\n    }\n\n    public double getItemValue(double viewY, XYItem item, ChartContext context) {\n        return 0;\n    }\n\n    public double getItemValueScale(XYItem item, ChartContext context) {\n        return -1;\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    \n    protected void paint(XYItem item, List<ItemSelection> highlighted,\n                       List<ItemSelection> selected, Graphics2D g,\n                       Rectangle dirtyArea, SynchronousXYChartContext context) {\n//        if (!(item instanceof ProfilerGCXYItem))\n//            throw new UnsupportedOperationException(\"Unsupported item: \" + item); // NOI18N\n\n        int valuesCount = item.getValuesCount();\n        if (valuesCount < 2) return;\n        if (context.getViewWidth() == 0 || context.getViewHeight() == 0) return;\n\n        int[][] visibleBounds = context.getVisibleBounds(dirtyArea);\n\n        int firstFirst = visibleBounds[0][0];\n        int index = firstFirst;\n        if (index == -1) index = visibleBounds[0][1];\n        if (index == -1) return;\n\n        int lastFirst = visibleBounds[1][0];\n        int lastIndex = lastFirst;\n        if (lastIndex == -1) lastIndex = visibleBounds[1][1];\n        if (lastIndex == -1) lastIndex = valuesCount - 1;\n        if (lastFirst != -1 && lastIndex < valuesCount - 1) lastIndex += 1;\n\n        int itemsStep = (int)Math.ceil((double)valuesCount / (double)context.getViewWidth());\n        if (itemsStep == 0) itemsStep = 1;\n\n        int visibleCount = lastIndex - index + 1;\n\n        if (itemsStep > 1) {\n            int firstMod = index % itemsStep;\n            index -= firstMod;\n            int lastMod = lastIndex % itemsStep;\n            lastIndex = lastIndex - lastMod + itemsStep;\n            visibleCount = (lastIndex - index) / itemsStep + 1;\n            lastIndex = Math.min(lastIndex, valuesCount - 1);\n        }\n\n        ProfilerGCXYItem xyItem = (ProfilerGCXYItem)item;\n\n        g.setColor(fillColor);\n\n        int startY = (int)context.getViewY(context.getDataOffsetY() +\n                                           context.getDataHeight());\n        int height = context.getViewportHeight();\n\n        for (int iter = 0; iter < visibleCount; iter++) {\n            long[] gcStarts = xyItem.getGCStarts(index);\n            if (gcStarts.length > 0) {\n                long[] gcEnds = xyItem.getGCEnds(index);\n                for (int i = 0; i < gcStarts.length; i++) {\n                    int itemStart = Utils.checkedInt(\n                                          context.getViewX(gcStarts[i]));\n                    long gcEnd = gcEnds[i];\n                    if (gcEnd == -1)\n                        gcEnd =  item.getXValue(item.getValuesCount() - 1);\n                    int itemLength = Utils.checkedInt(\n                                           context.getViewWidth(\n                                           gcEnd - gcStarts[i]));\n\n                    g.fillRect(itemStart, startY, Math.max(itemLength, 1), height);\n                }\n            }\n            \n            index = Math.min(index + itemsStep, lastIndex);\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/xy/ProfilerXYChart.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts.xy;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.util.ResourceBundle;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.Icon;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChart;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ProfilerXYChart extends SynchronousXYChart {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.charts.xy.Bundle\"); // NOI18N\n    private static final String ZOOM_IN_STRING = messages.getString(\"ProfilerXYChart_ZoomInString\"); // NOI18N\n    private static final String ZOOM_OUT_STRING = messages.getString(\"ProfilerXYChart_ZoomOutString\"); // NOI18N\n    private static final String FIXED_SCALE_STRING = messages.getString(\"ProfilerXYChart_FixedScaleString\"); // NOI18N\n    private static final String SCALE_TO_FIT_STRING = messages.getString(\"ProfilerXYChart_ScaleToFitString\"); // NOI18N\n    // -----\n\n    private static final Icon ZOOM_IN_ICON = Icons.getIcon(GeneralIcons.ZOOM_IN);\n    private static final Icon ZOOM_OUT_ICON = Icons.getIcon(GeneralIcons.ZOOM_OUT);\n    private static final Icon FIXED_SCALE_ICON = Icons.getIcon(GeneralIcons.ZOOM);\n    private static final Icon SCALE_TO_FIT_ICON = Icons.getIcon(GeneralIcons.SCALE_TO_FIT);\n\n\n    private ZoomInAction zoomInAction;\n    private ZoomOutAction zoomOutAction;\n    private ToggleViewAction toggleViewAction;\n\n\n    // --- Constructors --------------------------------------------------------\n\n    public ProfilerXYChart(SynchronousXYItemsModel itemsModel,\n                           PaintersModel paintersModel) {\n        super(itemsModel, paintersModel);\n\n        setBottomBased(true);\n        setFitsHeight(true);\n\n        setMousePanningEnabled(false);\n\n        addConfigurationListener(new VisibleBoundsListener());\n    }\n\n\n    // --- Public interface ----------------------------------------------------\n\n    public Action zoomInAction() {\n        if (zoomInAction == null) zoomInAction = new ZoomInAction();\n        return zoomInAction;\n    }\n\n    public Action zoomOutAction() {\n        if (zoomOutAction == null) zoomOutAction = new ZoomOutAction();\n        return zoomOutAction;\n    }\n\n    public Action toggleViewAction() {\n        if (toggleViewAction == null) toggleViewAction = new ToggleViewAction();\n        return toggleViewAction;\n    }\n\n\n    // --- Actions support -----------------------------------------------------\n\n    private class ZoomInAction extends AbstractAction {\n\n//        private static final int ONE_SECOND_WIDTH_THRESHOLD = 200;\n\n        ZoomInAction() {\n            super();\n\n            putValue(SHORT_DESCRIPTION, ZOOM_IN_STRING);\n            putValue(SMALL_ICON, ZOOM_IN_ICON);\n\n            updateAction();\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            boolean followsWidth = currentlyFollowingDataWidth();\n            zoom(getWidth() / 2, getHeight() / 2, 2d);\n            if (followsWidth) setOffset(getMaxOffsetX(), getOffsetY());\n            \n            repaintDirty();\n        }\n\n        private void updateAction() {\n            Timeline timeline = ((SynchronousXYItemsModel)getItemsModel()).getTimeline();\n            setEnabled(timeline.getTimestampsCount() > 1 && !fitsWidth() /*&&\n                       getViewWidth(1000) < ONE_SECOND_WIDTH_THRESHOLD*/);\n            // #165429 - don't disable zoom icons until mouse zoom is also disabled\n        }\n\n    }\n\n    private class ZoomOutAction extends AbstractAction {\n\n//        private static final float USED_CHART_WIDTH_THRESHOLD = 0.33f;\n\n        ZoomOutAction() {\n            super();\n\n            putValue(SHORT_DESCRIPTION, ZOOM_OUT_STRING);\n            putValue(SMALL_ICON, ZOOM_OUT_ICON);\n\n            updateAction();\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            boolean followsWidth = currentlyFollowingDataWidth();\n            zoom(getWidth() / 2, getHeight() / 2, 0.5d);\n            if (followsWidth) setOffset(getMaxOffsetX(), getOffsetY());\n            \n            repaintDirty();\n        }\n\n        private void updateAction() {\n            Timeline timeline = ((SynchronousXYItemsModel)getItemsModel()).getTimeline();\n            setEnabled(timeline.getTimestampsCount() > 1 && !fitsWidth() /*&&\n                       getContentsWidth() > getWidth() * USED_CHART_WIDTH_THRESHOLD*/);\n            // #165429 - don't disable zoom icons until mouse zoom is also disabled\n        }\n\n    }\n\n    private class ToggleViewAction extends AbstractAction {\n\n        private long origOffsetX  = -1;\n        private double origScaleX = -1;\n\n        ToggleViewAction() {\n            super();\n            updateAction();\n            addMouseListener(new MouseAdapter() {\n                public void mouseClicked(MouseEvent e) {\n                    if (SwingUtilities.isMiddleMouseButton(e))\n                        actionPerformed(null);\n                }\n            });\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            boolean fitsWidth = fitsWidth();\n\n            if (!fitsWidth) {\n                origOffsetX = getOffsetX();\n                if (tracksDataWidth() && origOffsetX == getMaxOffsetX())\n                    origOffsetX = Long.MAX_VALUE;\n                origScaleX  = getScaleX();\n            }\n\n            setFitsWidth(!fitsWidth);\n            \n            if (fitsWidth && origOffsetX != -1 && origScaleX != -1) {\n                setScale(origScaleX, getScaleY());\n                setOffset(origOffsetX, getOffsetY());\n            }\n\n            updateAction();\n            if (zoomInAction != null) zoomInAction.updateAction();\n            if (zoomOutAction != null) zoomOutAction.updateAction();\n            \n            repaintDirty();\n            \n        }\n\n        private void updateAction() {\n            boolean fitsWidth = fitsWidth();\n            Icon icon = fitsWidth ? FIXED_SCALE_ICON : SCALE_TO_FIT_ICON;\n            String name = fitsWidth ? FIXED_SCALE_STRING : SCALE_TO_FIT_STRING;\n            putValue(SHORT_DESCRIPTION, name);\n            putValue(SMALL_ICON, icon);\n        }\n\n    }\n\n\n    // --- ChartConfigurationListener implementation ---------------------------\n\n    private class VisibleBoundsListener extends ChartConfigurationListener.Adapter {\n\n        public void dataBoundsChanged(long dataOffsetX, long dataOffsetY,\n                                      long dataWidth, long dataHeight,\n                                      long oldDataOffsetX, long oldDataOffsetY,\n                                      long oldDataWidth, long oldDataHeight) {\n\n            if (zoomInAction != null) zoomInAction.updateAction();\n            if (zoomOutAction != null) zoomOutAction.updateAction();\n        }\n\n        public void scaleChanged(double oldScaleX, double oldScaleY,\n                                 double newScaleX, double newScaleY) {\n\n            if (zoomInAction != null) zoomInAction.updateAction();\n            if (zoomOutAction != null) zoomOutAction.updateAction();\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/xy/ProfilerXYItemPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.charts.xy;\n\nimport java.awt.Color;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemPainter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ProfilerXYItemPainter extends SynchronousXYItemPainter {\n\n    public static ProfilerXYItemPainter absolutePainter(float lineWidth,\n                                                       Color lineColor,\n                                                       Color fillColor) {\n\n        return new ProfilerXYItemPainter(lineWidth, lineColor, fillColor,\n                                         TYPE_ABSOLUTE, 0);\n    }\n\n    public static ProfilerXYItemPainter relativePainter(float lineWidth,\n                                                       Color lineColor,\n                                                       Color fillColor,\n                                                       int maxOffset) {\n\n        return new ProfilerXYItemPainter(lineWidth, lineColor, fillColor,\n                                         TYPE_RELATIVE, maxOffset);\n    }\n\n\n    public ProfilerXYItemPainter(float lineWidth, Color lineColor, Color fillColor,\n                          int type, int maxValueOffset) {\n        super(lineWidth, lineColor, fillColor, type, maxValueOffset);\n    }\n\n\n    public boolean supportsHovering(ChartItem item) {\n        return true;\n    }\n    \n    \n    public LongRect getSelectionBounds(ItemSelection selection, ChartContext context) {\n        XYItemSelection sel = (XYItemSelection)selection;\n        XYItem item  = sel.getItem();\n        int selectedValueIndex = sel.getValueIndex();\n\n        if (selectedValueIndex == -1 ||\n            selectedValueIndex >= item.getValuesCount())\n            // This happens on reset - bounds of the selection are unknown, let's clear whole area\n            return new LongRect(0, 0, context.getViewportWidth(),\n                                context.getViewportHeight());\n        else\n            return getViewBounds(item, new int[] { sel.getValueIndex() }, context);\n    }\n    \n    public ItemSelection getClosestSelection(ChartItem item, int viewX,\n                                             int viewY, ChartContext context) {\n        SynchronousXYChartContext contx = (SynchronousXYChartContext)context;\n\n        int nearestTimestampIndex = contx.getNearestTimestampIndex(viewX, viewY);\n        if (nearestTimestampIndex == -1) return null; // item not visible\n\n        SynchronousXYItem xyItem = (SynchronousXYItem)item;\n        return new XYItemSelection.Default(xyItem, nearestTimestampIndex,\n                                           ItemSelection.DISTANCE_UNKNOWN);\n    }\n    \n    \n    private LongRect getViewBounds(XYItem item, int[] valuesIndexes, ChartContext context) {\n\n        LongRect dataBounds = new LongRect();\n\n        if (valuesIndexes == null) {\n            LongRect.set(dataBounds, item.getBounds());\n        } else {\n            boolean firstPoint = true;\n            for (int valueIndex : valuesIndexes) {\n                if (valueIndex == -1) continue;\n                long xValue = item.getXValue(valueIndex);\n                long yValue = item.getYValue(valueIndex);\n                if (firstPoint) {\n                    LongRect.set(dataBounds, xValue, yValue, 0, 0);\n                    firstPoint = false;\n                } else {\n                    LongRect.add(dataBounds, xValue, yValue);\n                }\n            }\n        }\n\n        if (type == TYPE_RELATIVE) {\n            return getViewBoundsRelative(dataBounds, item, context);\n        } else {\n            LongRect viewBounds = context.getViewRect(dataBounds);\n            LongRect.addBorder(viewBounds, lineWidth);\n            return viewBounds;\n        }\n    }\n    \n    private LongRect getViewBoundsRelative(LongRect dataBounds, XYItem item,\n                                           ChartContext context) {\n        LongRect itemBounds = item.getBounds();\n\n        double itemValueFactor = getItemValueFactor(context, maxValueOffset,\n                                                    itemBounds.height);\n\n        // TODO: fix the math!!!\n        double value1 = context.getDataOffsetY() + itemValueFactor *\n                      (double)(dataBounds.y - itemBounds.y);\n        double value2 = context.getDataOffsetY() + itemValueFactor *\n                      (double)(dataBounds.y + dataBounds.height - itemBounds.y);\n\n        long viewX = (long)Math.ceil(context.getViewX(dataBounds.x));\n        long viewWidth = (long)Math.ceil(context.getViewWidth(dataBounds.width));\n        if (context.isRightBased()) viewX -= viewWidth;\n\n        long viewY1 = (long)Math.ceil(context.getViewY(value1));\n        long viewY2 = (long)Math.ceil(context.getViewY(value2));\n        long viewHeight = context.isBottomBased() ? viewY1 - viewY2 :\n                                                    viewY2 - viewY1;\n        if (!context.isBottomBased()) viewY2 -= viewHeight;\n\n        LongRect viewBounds =  new LongRect(viewX, viewY2, viewWidth, viewHeight);\n        LongRect.addBorder(viewBounds, lineWidth);\n\n        return viewBounds;\n    }\n    \n    private static double getItemValueFactor(ChartContext context,\n                                             double maxValueOffset,\n                                             double itemHeight) {\n        return ((double)context.getDataHeight() -\n               context.getDataHeight(maxValueOffset)) / itemHeight;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/xy/ProfilerXYSelectionOverlay.java",
    "content": "/*\n * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.charts.xy;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Paint;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartComponent;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartOverlay;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionListener;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ProfilerXYSelectionOverlay extends ChartOverlay {\n\n    private ChartComponent chart;\n\n    private int selectionExtent;\n\n    private final ConfigurationListener configurationListener;\n    private final SelectionListener selectionListener;\n    private final Set<Point> selectedValues;\n\n    private Paint markPaint;\n    private Paint oddPerfPaint;\n    private Paint evenPerfPaint;\n\n    private Stroke markStroke;\n    private Stroke oddPerfStroke;\n    private Stroke evenPerfStroke;\n\n\n    public ProfilerXYSelectionOverlay() {\n        configurationListener = new ConfigurationListener();\n        selectionListener = new SelectionListener();\n        selectedValues = new HashSet<>();\n        initDefaultValues();\n    }\n\n\n    // --- Public API ----------------------------------------------------------\n\n    public final void registerChart(ChartComponent chart) {\n        unregisterListener();\n        this.chart = chart;\n        registerListener();\n    }\n\n    public final void unregisterChart(ChartComponent chart) {\n        unregisterListener();\n        this.chart = null;\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void registerListener() {\n        if (chart == null) return;\n        chart.addConfigurationListener(configurationListener);\n        chart.getSelectionModel().addSelectionListener(selectionListener);\n    }\n\n    private void unregisterListener() {\n        if (chart == null) return;\n        chart.removeConfigurationListener(configurationListener);\n        chart.getSelectionModel().removeSelectionListener(selectionListener);\n    }\n\n    private void initDefaultValues() {\n        markPaint = new Color(80, 80, 80);\n        oddPerfPaint = Color.BLACK;\n        evenPerfPaint = Color.WHITE;\n\n        markStroke = new BasicStroke(2.8f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);\n        oddPerfStroke = new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 0, new float[] { 1.0f, 3.0f }, 0);\n        evenPerfStroke = new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 0, new float[] { 1.0f, 3.0f }, 2);\n\n        selectionExtent = 3;\n    }\n\n\n    public void paint(Graphics g) {\n        if (selectedValues.isEmpty()) return;\n\n        Graphics2D g2 = (Graphics2D)g;\n        g2.setRenderingHints(chart.getRenderingHints());\n\n        Iterator<Point> it = selectedValues.iterator();\n        boolean linePainted = false;\n\n        while (it.hasNext()) {\n            Point p = it.next();\n\n            if (!linePainted) {\n                g2.setPaint(evenPerfPaint);\n                g2.setStroke(evenPerfStroke);\n                g2.drawLine(p.x, 0, p.x, getHeight());\n                g2.setPaint(oddPerfPaint);\n                g2.setStroke(oddPerfStroke);\n                g2.drawLine(p.x, 0, p.x, getHeight());\n\n                g2.setPaint(markPaint);\n                g2.setStroke(markStroke);\n\n                linePainted = true;\n            }\n\n            g2.fillOval(p.x - selectionExtent + 1, p.y - selectionExtent + 1,\n                        selectionExtent * 2 - 1, selectionExtent * 2 - 1);\n        }\n\n    }\n\n    private void vLineBoundsChanged(Set<Point> oldSelection, Set<Point> newSelection) {\n        Point oldSel = oldSelection.isEmpty() ? null : oldSelection.iterator().next();\n        Point newSel = newSelection.isEmpty() ? null : newSelection.iterator().next();\n\n        if (oldSel != null) repaint(oldSel.x - selectionExtent, 0,\n                                             selectionExtent * 2, getHeight());\n        if (newSel != null) repaint(newSel.x - selectionExtent, 0,\n                                             selectionExtent * 2, getHeight());\n    }\n\n    private static void updateSelectedValues(Set<Point> selectedValues,\n                                             List<ItemSelection> selectedItems,\n                                             ChartComponent chart) {\n        selectedValues.clear();\n        for (ItemSelection sel : selectedItems) {\n            ProfilerXYItemPainter painter = (ProfilerXYItemPainter)chart.getPaintersModel().getPainter(sel.getItem());\n            LongRect bounds = painter.getSelectionBounds(sel, chart.getChartContext());\n            selectedValues.add(new Point(Utils.checkedInt(bounds.x + (bounds.width >> 2) + 1),\n                                         Utils.checkedInt(bounds.y + (bounds.height >> 2) + 1)));\n        }\n    }\n\n\n    private class ConfigurationListener extends ChartConfigurationListener.Adapter {\n        public void contentsUpdated(long offsetX, long offsetY,\n                                    double scaleX, double scaleY,\n                                    long lastOffsetX, long lastOffsetY,\n                                    double lastScaleX, double lastScaleY,\n                                    int shiftX, int shiftY) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        Set<Point> oldSelectedValues = new HashSet<>(selectedValues);\n                        updateSelectedValues(selectedValues, chart.getSelectionModel().getHighlightedItems(), chart);\n                        vLineBoundsChanged(oldSelectedValues, selectedValues);\n                    }\n                });\n        }\n    }\n\n    private class SelectionListener implements ChartSelectionListener {\n\n        public void selectionModeChanged(int newMode, int oldMode) {}\n\n        public void selectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds) {}\n\n        public void selectedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems) {}\n\n        public void highlightedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n            Set<Point> oldSelectedValues = new HashSet<>(selectedValues);\n            updateSelectedValues(selectedValues, currentItems, chart);\n            vLineBoundsChanged(oldSelectedValues, selectedValues);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/xy/ProfilerXYTooltipModel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts.xy;\n\nimport java.awt.Color;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ProfilerXYTooltipModel {\n\n    public String getTimeValue      (long timestamp);\n\n    public int    getRowsCount      ();\n    public String getRowName        (int index);\n    public Color  getRowColor       (int index);\n    public String getRowValue       (int index, long itemValue);\n    public String getRowUnits       (int index);\n\n    public int    getExtraRowsCount ();\n    public String getExtraRowName   (int index);\n    public Color  getExtraRowColor  (int index);\n    public String getExtraRowValue  (int index);\n    public String getExtraRowUnits  (int index);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/xy/ProfilerXYTooltipOverlay.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts.xy;\n\nimport java.awt.Graphics;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseMotionAdapter;\nimport java.util.List;\nimport javax.swing.Timer;\nimport org.graalvm.visualvm.lib.charts.ChartComponent;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartOverlay;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionListener;\nimport org.graalvm.visualvm.lib.charts.ItemPainter;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ProfilerXYTooltipOverlay extends ChartOverlay implements ActionListener {\n\n    private static final int TOOLTIP_OFFSET = 15;\n    private static final int TOOLTIP_MARGIN = 10;\n    private static final int TOOLTIP_RESPONSE = 50;\n    private static final int ANIMATION_STEPS = 5;\n\n    private ProfilerXYTooltipPainter tooltipPainter;\n\n    private Timer timer;\n    private int currentStep;\n    private Point mousePosition;\n    private Point targetPosition;\n\n\n    public ProfilerXYTooltipOverlay(final ChartComponent chart,\n                                    ProfilerXYTooltipPainter tooltipPainter) {\n        if (chart.getSelectionModel() == null)\n            throw new NullPointerException(\"No ChartSelectionModel set for \" + chart); // NOI18N\n\n        if (!Utils.forceSpeed()) {\n            timer = new Timer(TOOLTIP_RESPONSE / ANIMATION_STEPS, this);\n            timer.setInitialDelay(0);\n        }\n\n        setLayout(null);\n\n        this.tooltipPainter = tooltipPainter;\n        add(tooltipPainter);\n        tooltipPainter.setVisible(false);\n\n        chart.getSelectionModel().addSelectionListener(new ChartSelectionListener() {\n\n            public void selectionModeChanged(int newMode, int oldMode) {}\n\n            public void selectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds) {}\n\n            public void highlightedItemsChanged(List<ItemSelection> currentItems,\n                List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n                updateTooltip(chart);\n            }\n\n            public void selectedItemsChanged(List<ItemSelection> currentItems,\n                List<ItemSelection> addedItems, List<ItemSelection> removedItems) {}\n\n        });\n\n        chart.addConfigurationListener(new ChartConfigurationListener.Adapter() {\n\n            public void contentsUpdated(long offsetX, long offsetY,\n                                    double scaleX, double scaleY,\n                                    long lastOffsetX, long lastOffsetY,\n                                    double lastScaleX, double lastScaleY,\n                                    int shiftX, int shiftY) {\n                updateTooltip(chart);\n            }\n\n        });\n\n        chart.addMouseMotionListener(new MouseMotionAdapter() {\n            public void mouseMoved(MouseEvent e) {\n                mousePosition = e.getPoint();\n                updateTooltip(chart);\n            }\n        });\n    }\n\n    public final void setPosition(Point p) {\n        if (tooltipPainter != null) {\n            if (p == null) {\n                if (tooltipPainter.isVisible()) tooltipPainter.setVisible(false);\n                if (timer != null) timer.stop();\n            } else {\n                if (!tooltipPainter.isVisible() || timer == null) {\n                    tooltipPainter.setVisible(true);\n                    tooltipPainter.setLocation(p);\n                } else {\n                    currentStep = 0;\n                    targetPosition = p;\n                    timer.restart();\n                }\n            }\n        }\n    }\n\n    public final Point getPosition() {\n        if (tooltipPainter == null) return null;\n        return tooltipPainter.getLocation();\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        Point currentPosition = tooltipPainter.getLocation();\n\n        currentPosition.x += (targetPosition.x - currentPosition.x) /\n                             (ANIMATION_STEPS - currentStep);\n        currentPosition.y += (targetPosition.y - currentPosition.y) /\n                             (ANIMATION_STEPS - currentStep);\n        tooltipPainter.setLocation(currentPosition);\n\n        if (++currentStep == ANIMATION_STEPS) timer.stop();\n    }\n\n\n    private void updateTooltip(ChartComponent chart) {\n        if (mousePosition == null) return;\n\n        List<ItemSelection> highlightedItems =\n                chart.getSelectionModel().getHighlightedItems();\n\n        XYItemSelection selection = highlightedItems.isEmpty() ? null :\n                                    (XYItemSelection)highlightedItems.get(0);\n\n        if (selection == null ||\n            selection.getItem().getValuesCount() <= selection.getValueIndex()) {\n            setPosition(null);\n        } else {\n            tooltipPainter.update(highlightedItems);\n            tooltipPainter.setSize(tooltipPainter.getPreferredSize());\n            setPosition(highlightedItems, chart.getPaintersModel(), chart.getChartContext());\n        }\n    }\n\n    private void setPosition(List<ItemSelection> selectedItems, PaintersModel paintersModel, ChartContext chartContext) {\n        int tooltipX = -1;\n        int tooltipY = mousePosition.y;\n        for (ItemSelection selection : selectedItems) {\n            ChartItem item = selection.getItem();\n            ItemPainter painter = paintersModel.getPainter(item);\n            Rectangle bounds = Utils.checkedRectangle(\n                               painter.getSelectionBounds(selection,\n                               chartContext));\n            if (tooltipX == -1) tooltipX += bounds.x + bounds.width / 2;\n        }\n\n        setPosition(normalizePosition(new Point(tooltipX, tooltipY)));\n    }\n\n    private Point normalizePosition(Point basePoint) {\n        int w = getWidth();\n        int h = getHeight();\n        int cw = tooltipPainter.getWidth();\n        int ch = tooltipPainter.getHeight();\n\n        basePoint.x += TOOLTIP_OFFSET;\n        if (basePoint.x + cw + TOOLTIP_MARGIN > w)\n            basePoint.x -= TOOLTIP_OFFSET + cw + TOOLTIP_MARGIN;\n        if (basePoint.x < TOOLTIP_OFFSET)\n            basePoint.x = TOOLTIP_OFFSET;\n\n        basePoint.y -= ch + TOOLTIP_MARGIN;\n        if (basePoint.y + ch + TOOLTIP_MARGIN > h)\n            basePoint.y = h - ch - TOOLTIP_MARGIN;\n        if (basePoint.y < TOOLTIP_MARGIN)\n            basePoint.y = TOOLTIP_MARGIN;\n\n        return basePoint;\n    }\n\n\n    public void paint(Graphics g) {\n        if (tooltipPainter == null) return;\n\n        Rectangle bounds = new Rectangle(0, 0, getWidth(), getHeight());\n        Rectangle clip = g.getClipBounds();\n        if (clip == null) g.setClip(bounds);\n        else g.setClip(clip.intersection(bounds));\n\n        super.paint(g);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/charts/xy/ProfilerXYTooltipPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.charts.xy;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ProfilerXYTooltipPainter extends JPanel {\n\n    private static Color BACKGROUND_COLOR = Utils.forceSpeed() ?\n                                            new Color(80, 80, 80) :\n                                            new Color(0, 0, 0, 170);\n\n    private JLabel caption;\n    private JLabel[] valuePainters;\n    private JLabel[] extraValuePainters;\n\n    private final ProfilerXYTooltipModel model;\n\n    private boolean initialized;\n\n\n    public ProfilerXYTooltipPainter(ProfilerXYTooltipModel model) {\n        this.model = model;\n        initialized = false;\n    }\n\n\n    public void update(List<ItemSelection> selectedItems) {\n        if (!initialized) initComponents();\n\n        int rowsCount = model.getRowsCount();\n        if (selectedItems.size() != rowsCount)\n            throw new IllegalStateException(\"Rows and selected items don't match\"); // NOI18N\n\n        XYItemSelection selection = (XYItemSelection)selectedItems.get(0);\n        long timestamp = selection.getItem().getXValue(selection.getValueIndex());\n        caption.setText(model.getTimeValue(timestamp));\n\n        for (int i = 0; i < rowsCount; i++) {\n            XYItemSelection sel = (XYItemSelection)selectedItems.get(i);\n            long itemValue = sel.getItem().getYValue(sel.getValueIndex());\n            valuePainters[i].setText(model.getRowValue(i, itemValue));\n        }\n        \n        int extraRowsCount = model.getExtraRowsCount();\n        for (int i = 0; i < extraRowsCount; i++)\n            extraValuePainters[i].setText(model.getExtraRowValue(i));\n    }\n\n\n    protected void paintComponent(Graphics g) {\n        g.setColor(BACKGROUND_COLOR);\n        g.fillRect(0, 0, getWidth(), getHeight());\n        super.paintComponent(g);\n    }\n\n\n    private void initComponents() {\n        setOpaque(false);\n        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));\n\n        setLayout(new GridBagLayout());\n        GridBagConstraints constraints;\n        \n        Color GRAY = new Color(230, 230, 230);\n\n        caption = new JLabel();\n        caption.setFont(smallerFont(caption.getFont()));\n        caption.setForeground(GRAY);\n        caption.setOpaque(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 0;\n        constraints.weighty = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.insets = new Insets(0, 0, 5, 0);\n        add(caption, constraints);\n\n        final Dimension ZERO = new Dimension(0, 0);\n        \n        int count = model.getRowsCount();\n        valuePainters = new JLabel[count];\n        for (int i = 1; i <= count; i++) {\n            JLabel itemLabel = new JLabel();\n            itemLabel.setText(model.getRowName(i - 1));\n            itemLabel.setForeground(Color.WHITE);\n            itemLabel.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = i;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            add(itemLabel, constraints);\n\n            JLabel valueLabel = new JLabel();\n            valuePainters[i - 1] = valueLabel;\n            valueLabel.setForeground(Color.WHITE);\n            valueLabel.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = i;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.insets = new Insets(0, 8, 0, 0);\n            add(valueLabel, constraints);\n            \n            JLabel itemUnits = new JLabel();\n            String units = model.getRowUnits(i - 1);\n            if (!units.isEmpty()) units = \" \" + units; // NOI18N\n            itemUnits.setText(units);\n            itemUnits.setForeground(Color.WHITE);\n            itemUnits.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 2;\n            constraints.gridy = i;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            add(itemUnits, constraints);\n\n            JPanel valueSpacer = new JPanel(null) {\n                public Dimension getPreferredSize() { return ZERO; }\n            };\n            valueSpacer.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 3;\n            constraints.gridy = i;\n            constraints.weightx = 1;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            add(valueSpacer, constraints);\n        }\n        \n        int extraCount = model.getExtraRowsCount();\n        extraValuePainters = new JLabel[count];\n        for (int i = 1; i <= extraCount; i++) {\n            int top = i == 1 ? 5 : 0;\n            \n            JLabel maxItemLabel = new JLabel();\n            maxItemLabel.setText(model.getExtraRowName(i - 1));\n            maxItemLabel.setFont(smallerFont(maxItemLabel.getFont()));\n            maxItemLabel.setForeground(GRAY);\n            maxItemLabel.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = count + i;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.insets = new Insets(top, 0, 0, 0);\n            add(maxItemLabel, constraints);\n\n            JLabel extraValueLabel = new JLabel();\n            extraValuePainters[i - 1] = extraValueLabel;\n            extraValueLabel.setFont(smallerFont(extraValueLabel.getFont()));\n            extraValueLabel.setForeground(GRAY);\n            extraValueLabel.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = count + i;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.insets = new Insets(top, 8, 0, 0);\n            add(extraValueLabel, constraints);\n            \n            JLabel maxItemUnits = new JLabel();\n            String units = model.getExtraRowUnits(i - 1);\n            if (!units.isEmpty()) units = \" \" + units; // NOI18N\n            maxItemUnits.setText(units);\n            maxItemUnits.setFont(smallerFont(maxItemUnits.getFont()));\n            maxItemUnits.setForeground(GRAY);\n            maxItemUnits.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 2;\n            constraints.gridy = count + i;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.insets = new Insets(top, 0, 0, 0);\n            add(maxItemUnits, constraints);\n\n            JPanel extraValueSpacer = new JPanel(null) {\n                public Dimension getPreferredSize() { return ZERO; }\n            };\n            extraValueSpacer.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 3;\n            constraints.gridy = count + i;\n            constraints.weightx = 1;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.insets = new Insets(top, 0, 0, 0);\n            add(extraValueSpacer, constraints);\n        }\n\n        initialized = true;\n    }\n    \n    \n    private static Font smallerFont(Font font) {\n        return font.deriveFont((float)font.getSize() - 2);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/AnimatedContainer.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\nimport javax.swing.*;\n\n\n/**\n * A container for two contents that are animated in transition between them.\n *\n * @author Vlada Nemec\n */\npublic class AnimatedContainer extends javax.swing.JPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int WIDTH = 10;\n    public static final int HEIGHT = 20;\n    private static final int BOTH = 30;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    //custom layout manager used for placing content component\n    private AnimationLayout layout = new AnimationLayout();\n    private CustomTaskButtonBorder border;\n\n    //content of the container - limited to one component\n    private JComponent content;\n\n    //target content for the animation\n    private JComponent targetContent;\n\n    //temporary content used during animation\n    private JComponent transContent;\n    private int animatedDimension = BOTH;\n    private int origHeight;\n\n    //original dimensions\n    private int origWidth;\n    private int targetHeight;\n\n    //new dimension for animation (if needed)\n    private int targetWidth;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of AnimatedContainer\n     */\n    public AnimatedContainer(Color backgroundColor) {\n        setLayout(layout);\n\n        border = new CustomTaskButtonBorder(backgroundColor, super.getBackground());\n        setBorder(border);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setAnimatedDimension(int dimension) {\n        animatedDimension = dimension;\n    }\n\n    /**\n     * Setups animation parameters.\n     */\n    public void setAnimation(JComponent targetContent, JComponent transContent) {\n        //setup starting point dimension\n        origWidth = content.getWidth();\n        origHeight = content.getHeight();\n\n        //set contents\n        if (targetContent == null) {\n            this.targetContent = content;\n        } else if (transContent == null) {\n            this.transContent = content;\n        } else {\n            this.targetContent = targetContent;\n            this.transContent = transContent;\n\n            targetWidth = (int) targetContent.getPreferredSize().getWidth();\n            targetHeight = (int) targetContent.getPreferredSize().getHeight();\n        }\n    }\n\n    /**\n     * Setups animation parameters. <code>transContent</code> is set to <code>content</code>\n     */\n    public void setAnimation(JComponent aTargetContent) {\n        //setup starting point dimension\n        origWidth = content.getWidth();\n        origHeight = content.getHeight();\n\n        if (aTargetContent == null) {\n            targetContent = content;\n        } else {\n            targetContent = aTargetContent;\n\n            targetWidth = (int) targetContent.getPreferredSize().getWidth();\n            targetHeight = (int) targetContent.getPreferredSize().getHeight();\n        }\n    }\n\n    public void setAnimation(Dimension dimension) {\n        //setup starting point dimension\n        origWidth = content.getWidth();\n        origHeight = content.getHeight();\n\n        targetContent = null;\n        transContent = content;\n\n        targetWidth = (int) dimension.getWidth();\n        targetHeight = (int) dimension.getHeight();\n    }\n\n    public void setAnimation() {\n        origWidth = content.getWidth();\n        origHeight = content.getHeight();\n\n        transContent = content;\n        targetContent = content;\n    }\n\n    /**\n     * Sets content component reference. This method does NOT place any component into container.\n     */\n    public void setContent(JComponent content) {\n        this.content = content;\n    }\n\n    public void setDefaultBorder() {\n        border.setDefault();\n        repaint();\n    }\n\n    /**\n     * Sets the state of the container to finish state  with target size and content\n     */\n    public void setFinishState() {\n        //empty container\n        removeAll();\n\n        //add target content\n        if (targetContent != null) {\n            add(targetContent);\n            //resize to final size\n            setPreferredSize(new Dimension(targetWidth, targetHeight));\n            setMinimumSize(new Dimension(targetWidth, targetHeight));\n        } else if (transContent != null) {\n            add(transContent);\n            //resize to final size\n            setPreferredSize(transContent.getPreferredSize());\n            setMinimumSize(transContent.getPreferredSize());\n        }\n\n        //resize to final size\n        setPreferredSize(content.getPreferredSize());\n        setMinimumSize(content.getPreferredSize());\n    }\n\n    public void setFocusedBorder() {\n        border.setFocused();\n        repaint();\n    }\n\n    public void setSelectedBorder() {\n        border.setSelected();\n        repaint();\n    }\n\n    /**\n     * Sets the state of the container - this method provides the resizing of container for animation\n     */\n    public void setState(int percents) {\n        int newWidth;\n        int newHeight;\n\n        newWidth = targetWidth;\n        newHeight = targetHeight;\n\n        origWidth = (int) getSize().getWidth();\n        origHeight = (int) getSize().getHeight();\n\n        int deltaWidth = newWidth - origWidth;\n        int deltaHeight = newHeight - origHeight;\n\n        double perc = (double) percents / 100.0;\n\n        Dimension d;\n\n        if (animatedDimension == WIDTH) {\n            d = new Dimension((int) (origWidth + (deltaWidth * perc)), origHeight);\n        } else if (animatedDimension == HEIGHT) {\n            d = new Dimension(origWidth, (int) (origHeight + (deltaHeight * perc)));\n        } else {\n            d = new Dimension((int) (origWidth + (deltaWidth * perc)), (int) (origHeight + (deltaHeight * perc)));\n        }\n\n        setPreferredSize(d);\n        setMinimumSize(d);\n    }\n\n    /**\n     * Sets target content component reference. This method does NOT place any component into container.\n     */\n    public void setTargetContent(JComponent targetContent) {\n        this.targetContent = targetContent;\n    }\n\n    /**\n     * Sets transient content component reference. This method does NOT place any component into container.\n     */\n    public void setTransContent(JComponent transContent) {\n        this.transContent = transContent;\n    }\n\n    /**\n     * Overridden - we need to store reference to the content component\n     */\n    public Component add(Component component) {\n        content = (JComponent) component;\n\n        return super.add(component);\n    }\n\n    /**\n     * locks the content size - while resizing the content component size and layout remains the same\n     */\n    public void lockContentResizing(boolean lock) {\n        if ((lock) && (transContent != null)) {\n            layout.setLockedSize(transContent.getSize());\n        } else {\n            layout.setLockedSize(null);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/AnimationLayout.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\n\n\npublic class AnimationLayout implements LayoutManager {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Dimension lockedSize;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Constructs a new <code>AnimationLayout</code>.\n     */\n    public AnimationLayout() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setLockedSize(Dimension lockedSize) {\n        this.lockedSize = lockedSize;\n    }\n\n    /**\n     * Adds the specified component to the layout. Not used by this class.\n     * @param name the name of the component\n     * @param comp the component to be added\n     */\n    public void addLayoutComponent(String name, Component comp) {\n    }\n\n    /**\n     * Lays out the container. This method lets each component take\n     * its preferred size by reshaping the components in the\n     * target container in order to satisfy the alignment of\n     * this <code>AnimationLayout</code> object.\n     *\n     * @param target the specified component being laid out\n     * @see Container\n     * @see java.awt.Container#doLayout\n     */\n    public void layoutContainer(Container target) {\n        synchronized (target.getTreeLock()) {\n            Insets insets = target.getInsets();\n\n            if (target.getComponentCount() > 0) {\n                Component m = target.getComponent(0);\n\n                if (m.isVisible()) {\n                    Dimension d = lockedSize;\n\n                    if (d == null) {\n                        d = target.getSize();\n                        d.width -= insets.left;\n                        d.width -= insets.right;\n                        d.height -= insets.top;\n                        d.height -= insets.bottom;\n                    }\n\n                    m.setLocation(insets.left, insets.top);\n                    m.setSize(d.width, d.height);\n                }\n            }\n        }\n    }\n\n    /**\n     * Returns the minimum dimensions needed to layout the <i>visible</i>\n     * components contained in the specified target container.\n     *\n     * @param target the component which needs to be laid out\n     * @return the minimum dimensions to lay out the\n     *         subcomponents of the specified container\n     * @see #preferredLayoutSize\n     * @see java.awt.Container\n     * @see java.awt.Container#doLayout\n     */\n    public Dimension minimumLayoutSize(Container target) {\n        synchronized (target.getTreeLock()) {\n            Dimension dim = new Dimension(0, 0);\n\n            if (target.getComponentCount() > 0) {\n                Component m = target.getComponent(0);\n\n                if (m.isVisible()) {\n                    dim = m.getMinimumSize();\n                }\n            }\n\n            // actually this resizes the component instead of container - cannot be here      \n            //    \tInsets insets = target.getInsets();\n            //    \tdim.width += insets.left + insets.right;\n            //    \tdim.height += insets.top + insets.bottom;\n            return dim;\n        }\n    }\n\n    /**\n     * Returns the preferred dimensions for this layout given the\n     * <i>visible</i> components in the specified target container.\n     *\n     * @param target the component which needs to be laid out\n     * @return the preferred dimensions to lay out the\n     *         subcomponents of the specified container\n     * @see Container\n     * @see #minimumLayoutSize\n     * @see java.awt.Container#getPreferredSize\n     */\n    public Dimension preferredLayoutSize(Container target) {\n        synchronized (target.getTreeLock()) {\n            Dimension dim = new Dimension(0, 0);\n\n            if (target.getComponentCount() > 0) {\n                Component m = target.getComponent(0);\n\n                if (m.isVisible()) {\n                    dim = m.getPreferredSize();\n                }\n            }\n\n            // actually this resizes the component instead of container - cannot be here\n            //    \tInsets insets = target.getInsets();\n            //    \tdim.width += insets.left + insets.right;\n            //    \tdim.height += insets.top + insets.bottom;\n            //    \t\n            return dim;\n        }\n    }\n\n    /**\n     * Removes the specified component from the layout. Not used by\n     * this class.\n     * @param comp the component to remove\n     * @see       java.awt.Container#removeAll\n     */\n    public void removeLayoutComponent(Component comp) {\n    }\n\n    /**\n     * Returns a string representation of this <code>AnimationLayout</code>\n     * object and its values.\n     *\n     * @return a string representation of this layout\n     */\n    public String toString() {\n        return getClass().getName() + \", lockedSize: \" + lockedSize; // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/Animator.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.event.ActionListener;\nimport javax.swing.*;\n\n\n/**\n * This class animates two <code>AnimatedContainers</code> - the selected one is enlarging, the previously selected container is shrinking.\n * The animation parameters are set here as static final fields.\n * CURRENTLY WE DO NOT USE THIS CLASS.\n */\npublic class Animator implements ActionListener {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final int STEPS = 5;\n    private static final int DURATION = 100; //milliseconds\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    //containers that will be animated\n    AnimatedContainer cont1;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    //containers that will be animated\n    AnimatedContainer cont2;\n\n    //timer producing animation frames events\n    Timer timer;\n    private int stepsCounter;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of Animator */\n    public Animator(AnimatedContainer cont1, AnimatedContainer cont2) {\n        this.cont1 = cont1;\n        this.cont2 = cont2;\n\n        timer = new Timer(DURATION / STEPS, null);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void actionPerformed(java.awt.event.ActionEvent e) {\n        performAnimationStep();\n    }\n\n    public void startAnimation() {\n        //reset counter\n        stepsCounter = 0;\n\n        //register itself to timer\n        timer.addActionListener(this);\n\n        //start animation\n        timer.start();\n    }\n\n    private void performAnimationStep() {\n        int percIncrement = (int) 100 / STEPS;\n\n        stepsCounter++;\n\n        if (stepsCounter == STEPS) {\n            cont1.setFinishState();\n\n            if (cont2 != null) {\n                cont2.setFinishState();\n            }\n\n            cont1.revalidate();\n\n            if (cont2 != null) {\n                cont2.revalidate();\n            }\n\n            //stop animation\n            timer.stop();\n            //unregister\n            timer.removeActionListener(this);\n        } else {\n            cont1.setState(stepsCounter * percIncrement);\n\n            if (cont2 != null) {\n                cont2.setState(stepsCounter * percIncrement);\n            }\n\n            cont1.revalidate();\n\n            if (cont2 != null) {\n                cont2.revalidate();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n#FilterComponent_DefaultTextFieldString=[Filter]\n#FilterComponent_InvalidRegExpString=Invalid regular expression!\nFilterComponent_FilterTypeToolTip=Filter\\: {0}\nFilterComponent_FilterValueToolTip=Case insensitive filter (except regular expression). You can enter multiple filter values separated by space.\nFilterComponent_SetFilterButtonToolTip=Apply filter\nFilterComponent_ClearFilterButtonToolTip=Clear filter\n#FilterComponent_FilterStringComboAccessName=Results filter with history.\n#FilterComponent_FilterStringComboAccessDescr=Enter results filter here or choose previously entered filter from history.\nFilterComponent_AccessName=Results filter\nFilterComponent_AccessDescr=Enter value to filter displayed results\nFilterComponent_FilterContains=Contains\nFilterComponent_FilterNotContains=Does Not Contain\nFilterComponent_FilterRegexp=Regular Expression\n# Filter Hint (Filter Type), example: Class Name Filter (Does Not Contain)\nFilterComponent_FilterHint={0} ({1})\n\nHTMLTextArea_CutString=Cut\nHTMLTextArea_CopyString=Copy\nHTMLTextArea_PasteString=Paste\nHTMLTextArea_DeleteString=Delete\nHTMLTextArea_SelectAllString=Select All\n\nHTMLTextAreaSearchUtils_FindActionName=Find\nHTMLTextAreaSearchUtils_MatchesPattern={0} of {1} matches\nHTMLTextAreaSearchUtils_NoMatches=no matches\nHTMLTextAreaSearchUtils_MatchesTooltip=Highlight matches\nHTMLTextAreaSearchUtils_SidebarCaption=Find\\:\nHTMLTextAreaSearchUtils_BtnPrevious=Previous\n#Tooltip, {0} stands for action accelerator\nHTMLTextAreaSearchUtils_BtnPreviousTooltip=Find previous occurence ({0})\nHTMLTextAreaSearchUtils_BtnNext=Next\n#Tooltip, {0} stands for action accelerator\nHTMLTextAreaSearchUtils_BtnNextTooltip=Find next occurence ({0})\nHTMLTextAreaSearchUtils_BtnMatchCaseTooltip=Match case\n#Tooltip, {0} stands for action accelerator\nHTMLTextAreaSearchUtils_BtnCloseTooltip=Close Find sidebar ({0})\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/CellTipAware.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.Point;\nimport java.awt.event.MouseEvent;\nimport javax.swing.JToolTip;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface CellTipAware {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public JToolTip getCellTip();\n\n    public Point getCellTipLocation();\n\n    public void processMouseEvent(MouseEvent e);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/CellTipManager.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\n\n\npublic class CellTipManager implements MouseListener, MouseMotionListener, MouseWheelListener {\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private class MoveBeforeEnterListener extends MouseMotionAdapter {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void mouseMoved(MouseEvent e) {\n            initiateCellTip(e);\n        }\n    }\n\n    private class UniversalCellTipListener implements ComponentListener, KeyListener, FocusListener, PropertyChangeListener,\n                                                      HierarchyListener, HierarchyBoundsListener {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void ancestorMoved(HierarchyEvent e) {\n            hideCellTipForOwner(e.getSource());\n        }\n\n        public void ancestorResized(HierarchyEvent e) {\n            hideCellTipForOwner(e.getSource());\n        }\n\n        public void componentHidden(ComponentEvent e) {\n            hideCellTipForOwner(e.getSource());\n        }\n\n        public void componentMoved(ComponentEvent e) {\n            hideCellTipForOwner(e.getSource());\n        }\n\n        public void componentResized(ComponentEvent e) {\n            hideCellTipForOwner(e.getSource());\n        }\n\n        public void componentShown(ComponentEvent e) {\n            hideCellTipForOwner(e.getSource());\n        }\n\n        public void focusGained(FocusEvent e) {\n            //\n        }\n\n        public void focusLost(FocusEvent e) {\n            hideCellTipForOwner(e.getSource());\n        }\n\n        public void hierarchyChanged(HierarchyEvent e) {\n            hideCellTipForOwner(e.getSource());\n        }\n\n        public void keyPressed(KeyEvent e) {\n            hideCellTipAlways();\n        }\n\n        public void keyReleased(KeyEvent e) {\n            //\n        }\n\n        public void keyTyped(KeyEvent e) {\n            //\n        }\n\n        public void propertyChange(PropertyChangeEvent e) {\n            hideCellTipForOwner(e.getSource());\n        }\n\n        void registerForComponent(JComponent component) {\n            if (component == null) {\n                return;\n            }\n\n            component.addComponentListener(this);\n            component.addKeyListener(this);\n            component.addFocusListener(this);\n            component.addPropertyChangeListener(this);\n            component.addHierarchyListener(this);\n            component.addHierarchyBoundsListener(this);\n        }\n\n        void unregisterForComponent(JComponent component) {\n            if (component == null) {\n                return;\n            }\n\n            component.removeComponentListener(this);\n            component.removeKeyListener(this);\n            component.removeFocusListener(this);\n            component.removePropertyChangeListener(this);\n            component.removeHierarchyListener(this);\n            component.removeHierarchyBoundsListener(this);\n        }\n\n        private void hideCellTipAlways() {\n            hideCellTip();\n        }\n\n        private void hideCellTipForOwner(Object owner) {\n            if (cellTipComponent == owner) {\n                hideCellTip();\n            }\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final CellTipManager sharedInstance = new CellTipManager();\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JComponent cellTipComponent;\n    private JToolTip cellTip;\n    private transient Popup cellTipPopup;\n    private MouseMotionListener moveBeforeEnterListener = new MoveBeforeEnterListener();\n    private Rectangle popupFrameRect;\n    private Rectangle popupRect;\n    private UniversalCellTipListener universalCellTipListener = new UniversalCellTipListener();\n    private Window cellTipWindow;\n    private boolean enabled = true;\n    private boolean heavyweightPopupClosed = false;\n    private boolean internalMousePressed = false;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    // --- Public interface ------------------------------------------------------\n    public static CellTipManager sharedInstance() {\n        return sharedInstance;\n    }\n\n    public void setEnabled(boolean enabled) {\n        this.enabled = enabled;\n\n        if (!enabled) {\n            hideCellTip();\n        }\n    }\n\n    public boolean isEnabled() {\n        return enabled;\n    }\n\n    public void hideCellTip() {\n        hideCellTipWindow();\n        cellTipComponent = null;\n    }\n\n    public void mouseClicked(MouseEvent event) {\n    }\n\n    public void mouseDragged(MouseEvent event) {\n    }\n\n    public void mouseEntered(MouseEvent event) {\n        initiateCellTip(event);\n    }\n\n    public void mouseExited(MouseEvent event) {\n        boolean shouldHide = true;\n\n        if ((cellTipWindow != null) && (event.getSource() == cellTipWindow)) {\n            Container cellTipComponentWindow = cellTipComponent.getTopLevelAncestor();\n            Point location = event.getPoint();\n            SwingUtilities.convertPointToScreen(location, cellTipWindow);\n\n            location.x -= cellTipComponentWindow.getX();\n            location.y -= cellTipComponentWindow.getY();\n\n            location = SwingUtilities.convertPoint(null, location, cellTipComponent);\n\n            if ((location.x >= 0) && (location.x < cellTipComponent.getWidth()) && (location.y >= 0)\n                    && (location.y < cellTipComponent.getHeight())) {\n                shouldHide = false;\n            } else {\n                shouldHide = true;\n            }\n        } else if ((event.getSource() == cellTipComponent) && (cellTipPopup != null)) {\n            Window win = SwingUtilities.getWindowAncestor(cellTipComponent);\n\n            if (win != null) {\n                Point location = SwingUtilities.convertPoint(cellTipComponent, event.getPoint(), win);\n                Rectangle bounds = cellTipComponent.getTopLevelAncestor().getBounds();\n                location.x += bounds.x;\n                location.y += bounds.y;\n\n                Point loc = new Point(0, 0);\n                SwingUtilities.convertPointToScreen(loc, cellTip);\n                bounds.x = loc.x;\n                bounds.y = loc.y;\n                bounds.width = cellTip.getWidth();\n                bounds.height = cellTip.getHeight();\n\n                if ((location.x >= bounds.x) && (location.x < (bounds.x + bounds.width)) && (location.y >= bounds.y)\n                        && (location.y < (bounds.y + bounds.height))) {\n                    shouldHide = false;\n                } else {\n                    shouldHide = true;\n                }\n            }\n        }\n\n        if (shouldHide) {\n            if (cellTipComponent != null) {\n                cellTipComponent.removeMouseMotionListener(this);\n            }\n\n            hideCellTip();\n        }\n    }\n\n    public void mouseMoved(MouseEvent event) {\n        if (heavyweightPopupClosed) {\n            heavyweightPopupClosed = false;\n\n            return;\n        }\n\n        JComponent component = (JComponent) event.getSource();\n        cellTipComponent = component;\n        showCellTipWindow();\n    }\n\n    public void mousePressed(MouseEvent event) {\n        if (internalMousePressed) {\n            return;\n        }\n\n        JComponent component = cellTipComponent;\n        hideCellTip();\n\n        Object source = event.getSource();\n\n        if (source instanceof Component && !JComponent.isLightweightComponent((Component) source)) {\n            heavyweightPopupClosed = true;\n            internalMousePressed = true;\n            ((CellTipAware) component).processMouseEvent(SwingUtilities.convertMouseEvent((Component)source, event,\n                                                                                          component));\n            // #241878 immediately send mouseReleased which won't be called automatically on closing the popup\n            MouseEvent event2 = new MouseEvent((Component)source, MouseEvent.MOUSE_RELEASED,\n                                               event.getWhen() + 1, event.getModifiers(),\n                                               event.getX(), event.getY(), event.getClickCount(),\n                                               event.isPopupTrigger());\n            ((CellTipAware) component).processMouseEvent(SwingUtilities.convertMouseEvent(\n                                               (Component)source, event2, component));\n            internalMousePressed = false;\n        } else {\n            heavyweightPopupClosed = false;\n        }\n    }\n\n    public void mouseReleased(MouseEvent event) {\n    }\n    \n    public void mouseWheelMoved(MouseWheelEvent e) {\n        if (cellTipComponent instanceof CellTipAware)\n            ((CellTipAware)cellTipComponent).processMouseEvent(\n                    SwingUtilities.convertMouseEvent(\n                    (Component)e.getSource(), e, cellTipComponent));\n    }\n\n    public void registerComponent(JComponent component) {\n        if (Platform.isMac()) return; // CellTips don't work reliably on Mac (see Issue 89216) => disabled\n            \n        if (!(component instanceof CellTipAware)) {\n            throw new RuntimeException(\"Only components implementing org.graalvm.visualvm.lib.ui.components.CellTipAware interface can be registered!\"); // NOI18N\n        }\n\n        unregisterComponent(component);\n\n        component.addMouseListener(this);\n        component.addMouseMotionListener(moveBeforeEnterListener);\n\n        universalCellTipListener.registerForComponent(component);\n    }\n\n    public void unregisterComponent(JComponent component) {\n        if (Platform.isMac()) return; // CellTips don't work reliably on Mac (see Issue 89216) => disabled\n        \n        if (!(component instanceof CellTipAware)) {\n            throw new RuntimeException(\"Only components implementing org.graalvm.visualvm.lib.ui.components.CellTipAware interface can be unregistered!\"); // NOI18N\n        }\n\n        component.removeMouseListener(this);\n        component.removeMouseMotionListener(moveBeforeEnterListener);\n\n        universalCellTipListener.unregisterForComponent(component);\n    }\n\n    private static Frame frameForComponent(Component component) {\n        while (!(component instanceof Frame)) {\n            component = component.getParent();\n        }\n\n        return (Frame) component;\n    }\n\n    private int getHeightAdjust(Rectangle a, Rectangle b) {\n        if ((b.y >= a.y) && ((b.y + b.height) <= (a.y + a.height))) {\n            return 0;\n        } else {\n            return (((b.y + b.height) - (a.y + a.height)) + 5);\n        }\n    }\n\n    private int getPopupFitHeight(Rectangle popupRectInScreen, Component invoker) {\n        if (invoker != null) {\n            Container parent;\n\n            for (parent = invoker.getParent(); parent != null; parent = parent.getParent()) {\n                if (parent instanceof JFrame || parent instanceof JDialog || parent instanceof JWindow) {\n                    return getHeightAdjust(parent.getBounds(), popupRectInScreen);\n                } else if (parent instanceof JApplet || parent instanceof JInternalFrame) {\n                    if (popupFrameRect == null) {\n                        popupFrameRect = new Rectangle();\n                    }\n\n                    Point p = parent.getLocationOnScreen();\n                    popupFrameRect.setBounds(p.x, p.y, parent.getBounds().width, parent.getBounds().height);\n\n                    return getHeightAdjust(popupFrameRect, popupRectInScreen);\n                }\n            }\n        }\n\n        return 0;\n    }\n\n    private int getPopupFitWidth(Rectangle popupRectInScreen, Component invoker) {\n        if (invoker != null) {\n            Container parent;\n\n            for (parent = invoker.getParent(); parent != null; parent = parent.getParent()) {\n                if (parent instanceof JFrame || parent instanceof JDialog || parent instanceof JWindow) {\n                    return getWidthAdjust(parent.getBounds(), popupRectInScreen);\n                } else if (parent instanceof JApplet || parent instanceof JInternalFrame) {\n                    if (popupFrameRect == null) {\n                        popupFrameRect = new Rectangle();\n                    }\n\n                    Point p = parent.getLocationOnScreen();\n                    popupFrameRect.setBounds(p.x, p.y, parent.getBounds().width, parent.getBounds().height);\n\n                    return getWidthAdjust(popupFrameRect, popupRectInScreen);\n                }\n            }\n        }\n\n        return 0;\n    }\n\n    private int getWidthAdjust(Rectangle a, Rectangle b) {\n        if ((b.x >= a.x) && ((b.x + b.width) <= (a.x + a.width))) {\n            return 0;\n        } else {\n            return (((b.x + b.width) - (a.x + a.width)) + 5);\n        }\n    }\n\n    private void hideCellTipWindow() {\n        if (cellTipPopup != null) {\n            if (cellTipWindow != null) {\n                cellTipWindow.removeMouseListener(this);\n                cellTipWindow.removeMouseWheelListener(this);\n                cellTipWindow = null;\n            }\n\n            cellTipPopup.hide();\n            cellTipPopup = null;\n            cellTip = null;\n        }\n    }\n\n    private void initiateCellTip(MouseEvent event) {\n        if (event.getSource() == cellTipWindow) {\n            return;\n        }\n\n        JComponent component = (JComponent) event.getSource();\n        component.removeMouseMotionListener(moveBeforeEnterListener);\n\n        Point location = event.getPoint();\n\n        if ((location.x < 0) || (location.x >= component.getWidth()) || (location.y < 0) || (location.y >= component.getHeight())) {\n            return;\n        }\n\n        component.removeMouseMotionListener(this);\n        component.addMouseMotionListener(this);\n\n        boolean sameComponent = (cellTipComponent == component);\n\n        cellTipComponent = component;\n\n        if ((cellTipPopup != null) && !sameComponent) {\n            showCellTipWindow();\n        }\n    }\n\n    // ---------------------------------------------------------------------------\n    private void showCellTipWindow() {\n        if ((cellTipComponent == null) || !cellTipComponent.isShowing()) {\n            return;\n        }\n\n        for (Container p = cellTipComponent.getParent(); p != null; p = p.getParent()) {\n            if (p instanceof JPopupMenu) {\n                break;\n            }\n\n            if (p instanceof Window) {\n                if (!((Window) p).isFocused()) {\n                    return;\n                }\n\n                break;\n            }\n        }\n\n        if (enabled) {\n            Dimension size;\n            Point screenLocation = cellTipComponent.getLocationOnScreen();\n            Point location = new Point();\n            Rectangle sBounds = cellTipComponent.getGraphicsConfiguration().getBounds();\n\n            hideCellTipWindow();\n\n            if (!(cellTipComponent instanceof CellTipAware)) {\n                return;\n            }\n\n            CellTipAware cellTipAware = (CellTipAware) cellTipComponent;\n\n            Point cellTipLocation = cellTipAware.getCellTipLocation();\n\n            if (cellTipLocation == null) {\n                return;\n            }\n\n            cellTip = cellTipAware.getCellTip();\n            size = cellTip.getPreferredSize();\n\n            location.x = screenLocation.x + cellTipLocation.x;\n            location.y = screenLocation.y + cellTipLocation.y;\n\n            if (popupRect == null) {\n                popupRect = new Rectangle();\n            }\n\n            popupRect.setBounds(location.x, location.y, size.width, size.height);\n\n            if (location.x < sBounds.x) {\n                location.x = sBounds.x;\n            } else if ((location.x - sBounds.x + size.width) > sBounds.width) {\n                location.x = sBounds.x + Math.max(0, sBounds.width - size.width);\n            }\n\n            if (location.y < sBounds.y) {\n                location.y = sBounds.y;\n            } else if ((location.y - sBounds.y + size.height) > sBounds.height) {\n                location.y = sBounds.y + Math.max(0, sBounds.height - size.height);\n            }\n\n            PopupFactory popupFactory = PopupFactory.getSharedInstance();\n            cellTipPopup = popupFactory.getPopup(cellTipComponent, cellTip, location.x, location.y);\n            cellTipPopup.show();\n\n            Window componentWindow = SwingUtilities.windowForComponent(cellTipComponent);\n            cellTipWindow = SwingUtilities.windowForComponent(cellTip);\n\n            if ((cellTipWindow != null) && (cellTipWindow != componentWindow)) {\n                cellTipWindow.addMouseListener(this);\n                cellTipWindow.addMouseWheelListener(this);\n            } else {\n                cellTipWindow = null;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/CloseButton.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport javax.swing.JButton;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class CloseButton {\n\n    public static JButton create(Runnable onClose) {\n        Provider provider = Lookup.getDefault().lookup(Provider.class);\n        return provider != null ? provider.create(onClose) : new Impl(onClose);\n    }\n\n    public static JButton createSmall(Runnable onClose) {\n        Provider provider = Lookup.getDefault().lookup(Provider.class);\n        return provider != null ? provider.createSmall(onClose) : new Impl(onClose);\n    }\n\n    protected CloseButton() {}\n\n\n    public static abstract class Provider {\n\n        public abstract JButton create(Runnable onClose);\n\n        public JButton createSmall(Runnable onClose) { return create(onClose); }\n\n    }\n\n    public static class Impl extends JButton {\n        public Impl(final Runnable onClose) {\n            super(\"Close\");\n            if (onClose != null) addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) { onClose.run(); }\n            });\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/ColorIcon.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\n\n\n/**\n * @author Jiri Sedlacek\n */\npublic class ColorIcon implements javax.swing.Icon {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Color borderColor = Color.BLACK;\n    private Color color = Color.BLACK;\n    private int height = 5;\n    private int width = 5;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of ColorIcon */\n    public ColorIcon() {\n    }\n\n    public ColorIcon(Color color) {\n        this();\n        setColor(color);\n    }\n\n    public ColorIcon(Color color, int width, int height) {\n        this(color);\n        setIconWidth(width);\n        setIconHeight(height);\n    }\n\n    public ColorIcon(Color color, Color borderColor, int width, int height) {\n        this(color, width, height);\n        setBorderColor(borderColor);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setBorderColor(Color borderColor) {\n        this.borderColor = borderColor;\n    }\n\n    public Color getBorderColor() {\n        return borderColor;\n    }\n\n    public void setColor(Color color) {\n        this.color = color;\n    }\n\n    public Color getColor() {\n        return color;\n    }\n\n    public void setIconHeight(int height) {\n        this.height = height;\n    }\n\n    public int getIconHeight() {\n        return height;\n    }\n\n    public void setIconWidth(int width) {\n        this.width = width;\n    }\n\n    public int getIconWidth() {\n        return width;\n    }\n\n    public void paintIcon(java.awt.Component c, java.awt.Graphics g, int x, int y) {\n        if (color != null) {\n            g.setColor(color);\n            g.fillRect(x, y, width, height);\n        }\n\n        if (borderColor != null) {\n            g.setColor(borderColor);\n            g.drawRect(x, y, width - 1, height - 1);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/ComponentMorpher.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.Dimension;\nimport java.awt.Insets;\nimport java.awt.event.ComponentEvent;\nimport java.awt.event.ComponentListener;\nimport javax.accessibility.Accessible;\nimport javax.accessibility.AccessibleContext;\nimport javax.accessibility.AccessibleRole;\nimport javax.swing.JComponent;\nimport javax.swing.border.Border;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ComponentMorpher extends JComponent implements ComponentListener, Accessible {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private class MorpherThread extends Thread {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void run() {\n            setupMorphing();\n\n            while (isMorphing()) {\n                morphingStep();\n\n                try {\n                    Thread.sleep(morphingDelay);\n                } catch (InterruptedException ie) {\n                }\n            }\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ImageBlenderPanel blenderPanel;\n    private JComponent component1;\n    private JComponent component2;\n    private JComponent currentComponent;\n    private JComponent endComponent;\n\n    // --- Morphing stuff --------------------------------------------------------\n    private JComponent startComponent;\n    private boolean isMorphing = false;\n    private float heightDelta;\n    private int morphingDelay;\n    private int morphingStep;\n    private int morphingSteps;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ComponentMorpher(JComponent component1, JComponent component2) {\n        this(component1, component2, 10, 15);\n    }\n\n    public ComponentMorpher(JComponent component1, JComponent component2, int morphingSteps, int morphingDelay) {\n        this.component1 = component1;\n        this.component2 = component2;\n\n        setMorphingSteps(morphingSteps);\n        setMorphingDelay(morphingDelay);\n\n        setLayout(null);\n        setCurrentComponent(component1);\n\n        addComponentListener(this);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public AccessibleContext getAccessibleContext() {\n        if (accessibleContext == null)\n            accessibleContext = new AccessibleComponentMorpher();\n        return accessibleContext;\n    }\n    \n    public void setBorder(Border border) {\n        super.setBorder(border);\n        setClientPreferredSize(currentComponent.getPreferredSize());\n    }\n\n    public boolean isExpanded() {\n        return currentComponent == component2;\n    }\n\n    public boolean isMorphing() {\n        return isMorphing;\n    }\n\n    public void setMorphingDelay(int morphingDelay) {\n        this.morphingDelay = morphingDelay;\n    }\n\n    public int getMorphingDelay() {\n        return morphingDelay;\n    }\n\n    public void setMorphingSteps(int morphingSteps) {\n        this.morphingSteps = morphingSteps;\n    }\n\n    public int getMorphingSteps() {\n        return morphingSteps;\n    }\n\n    public void componentHidden(ComponentEvent e) {\n    }\n\n    public void componentMoved(ComponentEvent e) {\n    }\n\n    public void componentResized(ComponentEvent e) {\n        if (!isMorphing && (currentComponent != null)) {\n            setCurrentComponent(currentComponent);\n            revalidate();\n        }\n    }\n\n    public void componentShown(ComponentEvent e) {\n    }\n\n    public void expand() {\n        if (currentComponent != component2) {\n            setCurrentComponent(component2);\n        }\n    }\n\n    public void morph() {\n        if (!isMorphing()) {\n            new MorpherThread().start();\n        }\n    }\n\n    public void morphingStep() {\n        if (morphingStep > morphingSteps) {\n            return;\n        }\n\n        // --- Workaround to update data for incorrectly sized endComponent due to nested multiline textcomponent (HTMLTextArea, JEditorPane, JTextArea...)\n        if (endComponent.getSize().height != endComponent.getPreferredSize().height) {\n            endComponent.setSize(new Dimension(getClientSize().width, endComponent.getPreferredSize().height));\n            heightDelta = (float) (endComponent.getSize().height - startComponent.getSize().height) / (float) ((morphingStep == 0)\n                                                                                                               ? morphingSteps\n                                                                                                               : (morphingSteps\n                                                                                                               - morphingStep + 1));\n        }\n\n        // ---\n        if (morphingStep == 0) { // First step\n\n            if (endComponent == component2) {\n                setCurrentComponent(endComponent);\n            }\n\n            setClientPreferredSize(startComponent.getSize());\n        } else if (morphingStep == morphingSteps) { // Last step\n\n            if (endComponent == component1) {\n                setCurrentComponent(endComponent);\n            }\n\n            setClientPreferredSize(endComponent.getSize());\n            isMorphing = false;\n        } else { // Intermediate step\n            setClientPreferredSize(new Dimension(endComponent.getSize().width,\n                                                 startComponent.getSize().height + (int) (morphingStep * heightDelta)));\n        }\n\n        revalidate();\n        morphingStep++;\n    }\n\n    public void refreshLayout() {\n        if (currentComponent != null) {\n            setCurrentComponent(currentComponent);\n        }\n\n        revalidate();\n    }\n\n    public void reset() {\n        if (currentComponent != component1) {\n            setCurrentComponent(component1);\n        }\n    }\n\n    public void setupMorphing() {\n        startComponent = layoutComponent((currentComponent == component1) ? component1 : component2);\n        endComponent = layoutComponent((currentComponent == component1) ? component2 : component1);\n\n        heightDelta = (float) (endComponent.getSize().height - startComponent.getSize().height) / (float) morphingSteps;\n\n        morphingStep = 0;\n        isMorphing = true;\n\n        setCurrentComponent(startComponent);\n    }\n\n    private void setClientPreferredSize(Dimension size) {\n        Insets insets = getInsets();\n        setPreferredSize(new Dimension(size.width + insets.left + insets.right, size.height + insets.top + insets.bottom));\n    }\n\n    private Dimension getClientSize() {\n        Dimension size = getSize();\n        Insets insets = getInsets();\n\n        return new Dimension(size.width - insets.left - insets.right, size.height - insets.top - insets.bottom);\n    }\n\n    private void setCurrentComponent(JComponent component) {\n        boolean sameComponents = component == currentComponent;\n\n        if (!sameComponents && (currentComponent != null)) {\n            remove(currentComponent);\n        }\n\n        component = layoutComponent(component);\n        currentComponent = component;\n\n        if (!sameComponents) {\n            add(currentComponent);\n        }\n\n        Insets insets = getInsets();\n        currentComponent.setLocation(insets.left, insets.top);\n        setClientPreferredSize(component.getSize());\n    }\n\n    private JComponent layoutComponent(JComponent component) {\n        // Initial component sizing & layout\n        if (getClientSize().width > 0) {\n            component.setSize(getClientSize()); // try to fit the component to ComponentMorpher\n            component.validate(); // layout component\n\n            // Correct component sizing & layout\n            component.setSize(new Dimension(getClientSize().width, component.getPreferredSize().height)); // Width of component is fixed, update height\n            component.validate(); // layout component\n        }\n\n        return component;\n    }\n    \n    \n    protected class AccessibleComponentMorpher extends AccessibleJComponent {\n        \n        public AccessibleRole getAccessibleRole() {\n            return AccessibleRole.PUSH_BUTTON;\n        }\n        \n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/ComponentMorpher2.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.Image;\nimport java.awt.Insets;\nimport java.awt.image.BufferedImage;\nimport javax.swing.JComponent;\nimport javax.swing.border.Border;\n\n\n/**\n * Not used now, getting component2 image on macOS doesn't work\n *\n * @author Jiri Sedlacek\n */\npublic class ComponentMorpher2 extends JComponent {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private class MorpherThread extends Thread {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void run() {\n            setupMorphing();\n\n            while (isMorphing()) {\n                morphingStep();\n\n                try {\n                    Thread.sleep(morphingDelay);\n                } catch (InterruptedException ie) {\n                }\n            }\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Image endComponentImage;\n    private Image startComponentImage;\n    private ImageBlenderPanel blenderPanel;\n    private JComponent component1;\n    private JComponent component2;\n    private JComponent currentComponent;\n    private JComponent endComponent;\n\n    // --- Morphing stuff --------------------------------------------------------\n    private JComponent startComponent;\n    private boolean isMorphing = false;\n    private float heightDelta;\n    private int morphingDelay;\n    private int morphingStep;\n    private int morphingSteps;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ComponentMorpher2(JComponent component1, JComponent component2) {\n        this(component1, component2, 10, 15);\n    }\n\n    public ComponentMorpher2(JComponent component1, JComponent component2, int morphingSteps, int morphingDelay) {\n        this.component1 = component1;\n        this.component2 = component2;\n\n        setMorphingSteps(morphingSteps);\n        setMorphingDelay(morphingDelay);\n\n        setLayout(new BorderLayout());\n        setCurrentComponent(component1);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setBorder(Border border) {\n        super.setBorder(border);\n        setClientPreferredSize(currentComponent.getPreferredSize());\n    }\n\n    public boolean isExpanded() {\n        return currentComponent == component2;\n    }\n\n    public boolean isMorphing() {\n        return isMorphing;\n    }\n\n    public void setMorphingDelay(int morphingDelay) {\n        this.morphingDelay = morphingDelay;\n    }\n\n    public int getMorphingDelay() {\n        return morphingDelay;\n    }\n\n    public void setMorphingSteps(int morphingSteps) {\n        this.morphingSteps = morphingSteps;\n    }\n\n    public int getMorphingSteps() {\n        return morphingSteps;\n    }\n\n    public void morph() {\n        if (!isMorphing()) {\n            new MorpherThread().start();\n        }\n    }\n\n    public void morphingStep() {\n        if (morphingStep > morphingSteps) {\n            return;\n        }\n\n        if (morphingStep == 0) { // First step\n            setCurrentComponent(blenderPanel);\n        } else if (morphingStep == morphingSteps) { // Last step\n            setCurrentComponent(endComponent);\n            isMorphing = false;\n        } else { // Intermediate step\n\n            Dimension newDim = new Dimension(getClientSize().width,\n                                             startComponentImage.getHeight(null) + (int) (morphingStep * heightDelta));\n            blenderPanel.setBlendAlpha((float) morphingStep / (float) morphingSteps);\n            blenderPanel.setSize(newDim);\n            setClientPreferredSize(newDim);\n        }\n\n        refresh();\n        morphingStep++;\n    }\n\n    public void refresh() {\n        revalidate();\n        repaint();\n    }\n\n    public void setupMorphing() {\n        startComponent = (currentComponent == component1) ? component1 : component2;\n        endComponent = (currentComponent == component1) ? component2 : component1;\n\n        startComponentImage = getComponentImage(startComponent);\n        endComponentImage = getComponentImage(endComponent);\n\n        heightDelta = (float) (endComponentImage.getHeight(null) - startComponentImage.getHeight(null)) / (float) morphingSteps;\n\n        blenderPanel = new ImageBlenderPanel(startComponentImage, endComponentImage, component1.getBackground(), 0);\n        blenderPanel.setPreferredSize(new Dimension(startComponentImage.getWidth(null), startComponentImage.getHeight(null)));\n\n        morphingStep = 0;\n        isMorphing = true;\n    }\n\n    private void setClientPreferredSize(Dimension size) {\n        Insets insets = getInsets();\n        setPreferredSize(new Dimension(size.width + insets.left + insets.right, size.height + insets.top + insets.bottom));\n    }\n\n    private Dimension getClientSize() {\n        Dimension size = getSize();\n        Insets insets = getInsets();\n\n        return new Dimension(size.width - insets.left - insets.right, size.height - insets.top - insets.bottom);\n    }\n\n    private Image getComponentImage(JComponent component) {\n        // Initial component sizing & layout\n        component.setSize((getClientSize().width == 0) ? component.getPreferredSize() : getClientSize()); // try to fit the component to ComponentMorpher\n        component.doLayout(); // layout component\n\n        // Correct component sizing & layout\n        component.setSize(new Dimension(getClientSize().width, component.getPreferredSize().height)); // Width of component is fixed, update height\n        component.doLayout(); // layout component\n\n        // One more iteration because of nested JTextAreas\n        component.setSize(new Dimension(getClientSize().width, component.getPreferredSize().height)); // Width of component is fixed, update height\n        component.doLayout(); // layout component\n\n        // Paint component into BufferedImage\n        BufferedImage componentImage = new BufferedImage(component.getSize().width, component.getSize().height,\n                                                         BufferedImage.TYPE_INT_RGB);\n        component.printAll(componentImage.getGraphics());\n\n        return componentImage;\n    }\n\n    private void setCurrentComponent(JComponent component) {\n        if (currentComponent != null) {\n            remove(currentComponent);\n        }\n\n        currentComponent = component;\n        add(currentComponent, BorderLayout.CENTER);\n        setClientPreferredSize(currentComponent.getPreferredSize());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/CustomTaskButtonBorder.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\nimport javax.swing.border.AbstractBorder;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n *\n * @author  Jiri Sedlacek\n */\npublic class CustomTaskButtonBorder extends AbstractBorder {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int BORDER_STATE_DEFAULT = 10;\n    public static final int BORDER_STATE_FOCUSED = 20;\n    public static final int BORDER_STATE_SELECTED = 30;\n    private static final Color OUTLINE_CLR = new Color(0, 0, 0);\n    private static final Color FOCUSED_TOP_LIGHT_CLR = new Color(206, 231, 255);\n    private static final Color FOCUSED_TOP_DARK_CLR = new Color(188, 212, 246);\n    private static final Color FOCUSED_BOTTOM_LIGHT_CLR = new Color(137, 173, 228);\n    private static final Color FOCUSED_BOTTOM_DARK_CLR = new Color(105, 130, 238);\n    private static final Color SELECTED_TOP_LIGHT_CLR = new Color(255, 240, 207);\n    private static final Color SELECTED_TOP_DARK_CLR = new Color(253, 216, 137);\n    private static final Color SELECTED_BOTTOM_LIGHT_CLR = new Color(248, 178, 48);\n    private static final Color SELECTED_BOTTOM_DARK_CLR = new Color(229, 151, 0);\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Color DEFAULT_BOTTOM_DARK_CLR;\n    private Color DEFAULT_BOTTOM_LIGHT_CLR;\n    private Color DEFAULT_TOP_DARK_CLR;\n    private Color DEFAULT_TOP_LIGHT_CLR;\n    private Color backgroundColor;\n    private Color backgroundFade;\n    private Color startColor;\n    private Color stopColor;\n    private int borderState;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of CustomTaskButtonBorder */\n    public CustomTaskButtonBorder(Color foreground, Color background) {\n        super();\n        setForegroundColor(foreground);\n        setBackgroundColor(background);\n        setDefault();\n    }\n\n    public CustomTaskButtonBorder(Color foreground, Color background, int state) {\n        this(foreground, background);\n        setBorderState(state);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setBackgroundColor(Color background) {\n        backgroundColor = background;\n        backgroundFade = UIUtils.getSafeColor(((3 * background.getRed()) + (1 * OUTLINE_CLR.getRed())) / 4,\n                                              ((3 * background.getGreen()) + (1 * OUTLINE_CLR.getGreen())) / 4,\n                                              ((3 * background.getBlue()) + (1 * OUTLINE_CLR.getBlue())) / 4);\n    }\n\n    public Color getBackgroundColor() {\n        return backgroundColor;\n    }\n\n    public static Insets getBorderInsets() {\n        return new Insets(4, 4, 4, 4);\n    }\n\n    public static CustomTaskButtonBorder getDefaultInstance(Color foreground, Color background) {\n        return new CustomTaskButtonBorder(foreground, background, BORDER_STATE_DEFAULT);\n    }\n\n    public static CustomTaskButtonBorder getFocusedInstance(Color foreground, Color background) {\n        return new CustomTaskButtonBorder(foreground, background, BORDER_STATE_FOCUSED);\n    }\n\n    public Insets getBorderInsets(Component c) {\n        return CustomTaskButtonBorder.getBorderInsets();\n    }\n\n    public boolean isBorderOpaque() {\n        return false;\n    }\n\n    public void setBorderState(int state) {\n        borderState = state;\n    }\n\n    public int getBorderState() {\n        return borderState;\n    }\n\n    public void setFocused() {\n        setBorderState(CustomTaskButtonBorder.BORDER_STATE_FOCUSED);\n    }\n\n    public void setForegroundColor(Color foreground) {\n        DEFAULT_TOP_LIGHT_CLR = UIUtils.getSafeColor(foreground.getRed() + 15, foreground.getGreen() + 15,\n                                                     foreground.getBlue() + 15);\n        DEFAULT_TOP_DARK_CLR = UIUtils.getSafeColor(foreground.getRed() + 8, foreground.getGreen() + 8, foreground.getBlue() + 8);\n        DEFAULT_BOTTOM_LIGHT_CLR = UIUtils.getSafeColor(foreground.getRed() - 11, foreground.getGreen() - 11,\n                                                        foreground.getBlue() - 11);\n        DEFAULT_BOTTOM_DARK_CLR = UIUtils.getSafeColor(foreground.getRed() - 25, foreground.getGreen() - 25,\n                                                       foreground.getBlue() - 25);\n    }\n\n    public Color getForegroundColor() {\n        return UIUtils.getSafeColor(DEFAULT_TOP_LIGHT_CLR.getRed() - 15, DEFAULT_TOP_LIGHT_CLR.getGreen() - 15,\n                                    DEFAULT_TOP_LIGHT_CLR.getBlue() - 15);\n    }\n\n    public static CustomTaskButtonBorder getSelectedInstance(Color foreground, Color background) {\n        return new CustomTaskButtonBorder(foreground, background, BORDER_STATE_SELECTED);\n    }\n\n    public void setDefault() {\n        setBorderState(CustomTaskButtonBorder.BORDER_STATE_DEFAULT);\n    }\n\n    public void setSelected() {\n        setBorderState(CustomTaskButtonBorder.BORDER_STATE_SELECTED);\n    }\n\n    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {\n        if (!(g instanceof Graphics2D)) {\n            return;\n        }\n\n        Graphics2D g2d = (Graphics2D) g;\n\n        // Background points for \"rounded\" edges\n        g2d.setColor(backgroundColor);\n        g2d.drawLine(x, y, x, y);\n        g2d.drawLine(x, (y + height) - 1, x, (y + height) - 1);\n        g2d.drawLine((x + width) - 1, y, (x + width) - 1, y);\n        g2d.drawLine((x + width) - 1, (y + height) - 1, (x + width) - 1, (y + height) - 1);\n\n        // Fade points for smooth \"rounded\" edges\n        g2d.setColor(backgroundFade);\n        g2d.drawLine(x + 1, y, x + 1, y);\n        g2d.drawLine(x, y + 1, x, y + 1);\n        g2d.drawLine(x + 1, (y + height) - 1, x + 1, (y + height) - 1);\n        g2d.drawLine(x, (y + height) - 2, x, (y + height) - 2);\n        g2d.drawLine((x + width) - 1, y + 1, (x + width) - 1, y + 1);\n        g2d.drawLine((x + width) - 2, y, (x + width) - 2, y);\n        g2d.drawLine((x + width) - 2, (y + height) - 1, (x + width) - 2, (y + height) - 1);\n        g2d.drawLine((x + width) - 1, (y + height) - 2, (x + width) - 1, (y + height) - 2);\n\n        // Points connecting outer black borders\n        g2d.setColor(OUTLINE_CLR);\n        g2d.drawLine(x + 1, y + 1, x + 1, y + 1);\n        g2d.drawLine((x + width) - 2, y + 1, (x + width) - 2, y + 1);\n        g2d.drawLine(x + 1, (y + height) - 2, x + 1, (y + height) - 2);\n        g2d.drawLine((x + width) - 2, (y + height) - 2, (x + width) - 2, (y + height) - 2);\n\n        // Outer black borders\n        g2d.setColor(OUTLINE_CLR);\n        g2d.drawLine(x + 2, y, (x + width) - 3, y);\n        g2d.drawLine(x, y + 2, x, (y + height) - 3);\n        g2d.drawLine((x + width) - 1, y + 2, (x + width) - 1, (y + height) - 3);\n        g2d.drawLine(x + 2, (y + height) - 1, (x + width) - 3, (y + height) - 1);\n\n        // Top light line\n        switch (borderState) {\n            case BORDER_STATE_DEFAULT:\n                g2d.setColor(DEFAULT_TOP_LIGHT_CLR);\n\n                break;\n            case BORDER_STATE_FOCUSED:\n                g2d.setColor(FOCUSED_TOP_LIGHT_CLR);\n\n                break;\n            case BORDER_STATE_SELECTED:\n                g2d.setColor(SELECTED_TOP_LIGHT_CLR);\n\n                break;\n        }\n\n        g.drawLine(x + 2, y + 1, (x + width) - 3, y + 1);\n\n        // Top dark lines\n        switch (borderState) {\n            case BORDER_STATE_DEFAULT:\n                g2d.setColor(DEFAULT_TOP_DARK_CLR);\n\n                break;\n            case BORDER_STATE_FOCUSED:\n                g2d.setColor(FOCUSED_TOP_DARK_CLR);\n\n                break;\n            case BORDER_STATE_SELECTED:\n                g2d.setColor(SELECTED_TOP_DARK_CLR);\n\n                break;\n        }\n\n        g2d.drawLine(x + 1, y + 2, (x + width) - 2, y + 2);\n        g2d.drawLine(x + 1, y + 3, (x + width) - 2, y + 3);\n\n        // Bottom light lines\n        switch (borderState) {\n            case BORDER_STATE_DEFAULT:\n                g2d.setColor(DEFAULT_BOTTOM_LIGHT_CLR);\n\n                break;\n            case BORDER_STATE_FOCUSED:\n                g2d.setColor(FOCUSED_BOTTOM_LIGHT_CLR);\n\n                break;\n            case BORDER_STATE_SELECTED:\n                g2d.setColor(SELECTED_BOTTOM_LIGHT_CLR);\n\n                break;\n        }\n\n        g2d.drawLine(x + 1, (y + height) - 4, (x + width) - 2, (y + height) - 4);\n        g2d.drawLine(x + 1, (y + height) - 3, (x + width) - 2, (y + height) - 3);\n\n        // Bottom dark line\n        switch (borderState) {\n            case BORDER_STATE_DEFAULT:\n                g2d.setColor(DEFAULT_BOTTOM_DARK_CLR);\n\n                break;\n            case BORDER_STATE_FOCUSED:\n                g2d.setColor(FOCUSED_BOTTOM_DARK_CLR);\n\n                break;\n            case BORDER_STATE_SELECTED:\n                g2d.setColor(SELECTED_BOTTOM_DARK_CLR);\n\n                break;\n        }\n\n        g2d.drawLine(x + 2, (y + height) - 2, (x + width) - 3, (y + height) - 2);\n\n        // Side gradients\n        switch (borderState) {\n            case BORDER_STATE_DEFAULT:\n                startColor = DEFAULT_TOP_DARK_CLR;\n                stopColor = DEFAULT_BOTTOM_LIGHT_CLR;\n\n                break;\n            case BORDER_STATE_FOCUSED:\n                startColor = FOCUSED_TOP_DARK_CLR;\n                stopColor = FOCUSED_BOTTOM_LIGHT_CLR;\n\n                break;\n            case BORDER_STATE_SELECTED:\n                startColor = SELECTED_TOP_DARK_CLR;\n                stopColor = SELECTED_BOTTOM_LIGHT_CLR;\n\n                break;\n        }\n\n        g2d.setPaint(new GradientPaint(x + 1, y + 3, startColor, x + 1, (y + height) - 5, stopColor));\n        g2d.fillRect(x + 1, y + 3, 3, height - 7);\n        g2d.fillRect((x + width) - 4, y + 3, 3, height - 7);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/DiscreteProgress.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport javax.swing.DefaultBoundedRangeModel;\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\nimport javax.swing.JProgressBar;\nimport javax.swing.UIManager;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DiscreteProgress extends JPanel {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Color disabledColor = new Color(220, 220, 220);\n    private Color enabledColor = new Color(128, 128, 255);\n    private int activeUnits = 0;\n    private int totalUnits = 10;\n    private int unitHeight = 13;\n    private int unitWidth = 10;\n\n    private JProgressBar progressDelegate;\n    private DefaultBoundedRangeModel progressDelegateModel;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public DiscreteProgress() {\n        initComponents();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setActiveUnits(int activeUnits) {\n        if (progressDelegateModel != null) {\n            this.activeUnits = activeUnits;\n            progressDelegateModel.setValue(activeUnits);\n        } else if (this.activeUnits != activeUnits) {\n            this.activeUnits = activeUnits;\n            repaint();\n        }\n    }\n\n    public int getActiveUnits() {\n        return activeUnits;\n    }\n\n    public Dimension getMaximumSize() {\n        return getPreferredSize();\n    }\n\n    public Dimension getMinimumSize() {\n        return getPreferredSize();\n    }\n\n    public Dimension getPreferredSize() {\n        return new Dimension(((totalUnits * unitWidth) + totalUnits) - 1 + 4, unitHeight + 4);\n    }\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void main(String[] args) {\n        try {\n            //UIManager.setLookAndFeel(\"com.sun.java.swing.plaf.windows.WindowsLookAndFeel\");\n            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());\n        } catch (Exception e) {\n        }\n\n        DiscreteProgress progress = new DiscreteProgress();\n\n        JFrame testFrame = new JFrame(\"Decimal Progress Test Frame\"); // NOI18N\n        testFrame.getContentPane().add(progress);\n        testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        testFrame.pack();\n        testFrame.setVisible(true);\n    }\n\n    public void paintComponent(Graphics g) {\n        if (progressDelegate == null) {\n            Insets insets = getInsets();\n            int offsetX = insets.left;\n            int offsetY = insets.top;\n\n            for (int i = 0; i < totalUnits; i++) {\n                g.setColor((i < activeUnits) ? enabledColor : disabledColor);\n                g.fillRect(offsetX + (i * unitWidth) + i, offsetY, unitWidth, unitHeight);\n            }\n        } else {\n            super.paintComponent(g);\n        }\n    }\n    \n    \n    private void initComponents() {\n        setLayout(new BorderLayout());\n        \n//        if (UIUtils.isNimbus()) {\n            progressDelegateModel = new DefaultBoundedRangeModel(4, 1, 0, 10);\n            progressDelegate = new JProgressBar(progressDelegateModel);\n            add(progressDelegate, BorderLayout.CENTER);\n//        } else {\n//            setBorder(new ThinBevelBorder(BevelBorder.LOWERED));\n//            setOpaque(false);\n//        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/EqualFlowLayout.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\n\n\n/** EqualFlowLayout is a layout manager that works the same way as FlowLayout.\n * The only difference is that it sizes the components so that they all have the same width\n * (a width of widest component).\n *\n * @author   Ian Formanek\n * @version  1.00, Nov 12, 1998\n */\npublic class EqualFlowLayout extends FlowLayout {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    /** A JDK 1.1 serial version UID */\n    static final long serialVersionUID = -1996929627282401218L;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Constructs a new Flow Layout with a centered alignment and a\n     * default 5-unit horizontal and vertical gap.\n     * @since JDK1.0\n     */\n    public EqualFlowLayout() {\n        super();\n    }\n\n    /**\n     * Constructs a new Flow Layout with the specified alignment and a\n     * default 5-unit horizontal and vertical gap.\n     * The value of the alignment argument must be one of\n     * <code>FlowLayout.LEFT</code>, <code>FlowLayout.RIGHT</code>,\n     * or <code>FlowLayout.CENTER</code>.\n     * @param align the alignment value\n     * @since JDK1.0\n     */\n    public EqualFlowLayout(int align) {\n        super(align);\n    }\n\n    /**\n     * Creates a new flow layout manager with the indicated alignment\n     * and the indicated horizontal and vertical gaps.\n     * <p>\n     * The value of the alignment argument must be one of\n     * <code>FlowLayout.LEFT</code>, <code>FlowLayout.RIGHT</code>,\n     * or <code>FlowLayout.CENTER</code>.\n     * @param      align   the alignment value.\n     * @param      hgap    the horizontal gap between components.\n     * @param      vgap    the vertical gap between components.\n     * @since      JDK1.0\n     */\n    public EqualFlowLayout(int align, int hgap, int vgap) {\n        super(align, hgap, vgap);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Lays out the container. This method lets each component take\n     * its preferred size by reshaping the components in the\n     * target container in order to satisfy the constraints of\n     * this <code>FlowLayout</code> object.\n     * @param target the specified component being laid out.\n     * @see java.awt.Container\n     * @see       java.awt.Container#doLayout\n     * @since     JDK1.0\n     */\n    public void layoutContainer(Container target) {\n        int maxWidth = getMaximumWidth(target);\n\n        synchronized (target.getTreeLock()) {\n            Insets insets = target.getInsets();\n            int maxwidth = target.getSize().width - (insets.left + insets.right + (getHgap() * 2));\n            int nmembers = target.getComponentCount();\n            int x = 0;\n            int y = insets.top + getVgap();\n            int rowh = 0;\n            int start = 0;\n\n            for (int i = 0; i < nmembers; i++) {\n                Component m = target.getComponent(i);\n\n                if (m.isVisible()) {\n                    Dimension d = m.getPreferredSize();\n                    d.width = maxWidth;\n                    m.setSize(d.width, d.height);\n\n                    if ((x == 0) || ((x + d.width) <= maxwidth)) {\n                        if (x > 0) {\n                            x += getHgap();\n                        }\n\n                        x += d.width;\n                        rowh = Math.max(rowh, d.height);\n                    } else {\n                        moveComponents2(target, insets.left + getHgap(), y, maxwidth - x, rowh, start, i);\n                        x = d.width;\n                        y += (getVgap() + rowh);\n                        rowh = d.height;\n                        start = i;\n                    }\n                }\n            }\n\n            moveComponents2(target, insets.left + getHgap(), y, maxwidth - x, rowh, start, nmembers);\n        }\n    }\n\n    /**\n     * Returns the minimum dimensions needed to layout the components\n     * contained in the specified target container.\n     * @param target the component which needs to be laid out\n     * @return    the minimum dimensions to lay out the\n     *                    subcomponents of the specified container.\n     * @see #preferredLayoutSize\n     * @see       java.awt.Container\n     * @see       java.awt.Container#doLayout\n     * @since     JDK1.0\n     */\n    public Dimension minimumLayoutSize(Container target) {\n        synchronized (target.getTreeLock()) {\n            Dimension dim = new Dimension(0, 0);\n            int nmembers = target.getComponentCount();\n\n            for (int i = 0; i < nmembers; i++) {\n                Component m = target.getComponent(i);\n\n                if (m.isVisible()) {\n                    Dimension d = m.getMinimumSize();\n                    dim.height = Math.max(dim.height, d.height);\n\n                    if (i > 0) {\n                        dim.width += getHgap();\n                    }\n\n                    dim.width += d.width;\n                }\n            }\n\n            Insets insets = target.getInsets();\n            dim.width += (insets.left + insets.right + (getHgap() * 2));\n            dim.height += (insets.top + insets.bottom + (getVgap() * 2));\n\n            return dim;\n        }\n    }\n\n    /**\n     * Returns the preferred dimensions for this layout given the components\n     * in the specified target container.\n     * @param target the component which needs to be laid out\n     * @return    the preferred dimensions to lay out the\n     *                    subcomponents of the specified container.\n     * @see java.awt.Container\n     * @see #minimumLayoutSize\n     * @see       java.awt.Container#getPreferredSize\n     * @since     JDK1.0\n     */\n    public Dimension preferredLayoutSize(Container target) {\n        int maxWidth = getMaximumWidth(target);\n\n        synchronized (target.getTreeLock()) {\n            Dimension dim = new Dimension(0, 0);\n            int nmembers = target.getComponentCount();\n\n            for (int i = 0; i < nmembers; i++) {\n                Component m = target.getComponent(i);\n\n                if (m.isVisible()) {\n                    Dimension d = m.getPreferredSize();\n                    dim.height = Math.max(dim.height, d.height);\n\n                    if (i > 0) {\n                        dim.width += getHgap();\n                    }\n\n                    dim.width += maxWidth;\n                }\n            }\n\n            Insets insets = target.getInsets();\n            dim.width += (insets.left + insets.right + (getHgap() * 2));\n            dim.height += (insets.top + insets.bottom + (getVgap() * 2));\n\n            return dim;\n        }\n    }\n\n    private static int getMaximumWidth(Container target) {\n        int maxWidth = 0;\n\n        synchronized (target.getTreeLock()) {\n            int nmembers = target.getComponentCount();\n\n            for (int i = 0; i < nmembers; i++) {\n                Component m = target.getComponent(i);\n\n                if (m.isVisible()) {\n                    Dimension d = m.getPreferredSize();\n                    maxWidth = Math.max(d.width, maxWidth);\n                }\n            }\n        }\n\n        return maxWidth;\n    }\n\n    /**\n     * Centers the elements in the specified row, if there is any slack.\n     * @param target the component which needs to be moved\n     * @param x the x coordinate\n     * @param y the y coordinate\n     * @param width the width dimensions\n     * @param height the height dimensions\n     * @param rowStart the beginning of the row\n     * @param rowEnd the ending of the row\n     */\n    private void moveComponents2(Container target, int x, int y, int width, int height, int rowStart, int rowEnd) {\n        synchronized (target.getTreeLock()) {\n            switch (getAlignment()) {\n                case LEFT:\n                    break;\n                case CENTER:\n                    x += (width / 2);\n\n                    break;\n                case RIGHT:\n                    x += width;\n\n                    break;\n            }\n\n            for (int i = rowStart; i < rowEnd; i++) {\n                Component m = target.getComponent(i);\n\n                if (m.isVisible()) {\n                    m.setLocation(x, y + ((height - m.getSize().height) / 2));\n                    x += (getHgap() + m.getSize().width);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/FilterComponent.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.text.MessageFormat;\nimport java.util.List;\nimport java.util.*;\nimport javax.swing.*;\nimport javax.swing.border.Border;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class FilterComponent implements CommonConstants {\n\n    public static FilterComponent create(boolean createDefaultFilters,\n                                         boolean toLowerCase) {\n        return new Impl(createDefaultFilters, toLowerCase);\n    }\n\n\n    public abstract JComponent getComponent();\n\n\n    public abstract void setFilterValue(String filterValue);\n\n    public abstract String getFilterValue();\n\n    public abstract void addFilterType(String filterName, int filterType);\n\n    public abstract void setFilterType(int filterType);\n\n    public abstract int getFilterType();\n\n    public abstract void setFilter(String filterValue, int filterType);\n\n    public abstract void setHint(String hint);\n\n    public abstract String getHint();\n\n    public abstract void addChangeListener(ChangeListener listener);\n\n    public abstract void removeChangeListener(ChangeListener listener);\n\n\n    public static String[] getFilterValues(String filterValue) {\n        return filterValue == null ? null :\n                filterValue.trim().split(\" +\"); // NOI18N\n    }\n\n\n    protected FilterComponent() {}\n    \n    \n    \n    private static class Impl extends FilterComponent {\n        \n        // -----\n        // I18N String constants\n        private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.components.Bundle\"); // NOI18N\n        private static final String STRING_FILTER_CONTAINS = messages.getString(\"FilterComponent_FilterContains\"); // NOI18N\n        private static final String STRING_FILTER_NOT_CONTAINS = messages.getString(\"FilterComponent_FilterNotContains\"); // NOI18N\n        private static final String STRING_FILTER_REGEXP = messages.getString(\"FilterComponent_FilterRegexp\"); // NOI18N\n        private static final String FILTER_TYPE_TOOLTIP = messages.getString(\"FilterComponent_FilterTypeToolTip\"); // NOI18N\n        private static final String FILTER_TOOLTIP = messages.getString(\"FilterComponent_FilterValueToolTip\"); // NOI18N\n        private static final String SUBMIT_TOOLTIP = messages.getString(\"FilterComponent_SetFilterButtonToolTip\"); // NOI18N\n        private static final String CLEAR_TOOLTIP = messages.getString(\"FilterComponent_ClearFilterButtonToolTip\"); // NOI18N\n        private static final String ACCESS_NAME = messages.getString(\"FilterComponent_AccessName\"); // NOI18N\n        private static final String ACCESS_DESCR = messages.getString(\"FilterComponent_AccessDescr\"); // NOI18N\n        private static final String FILTER_HINT = messages.getString(\"FilterComponent_FilterHint\"); // NOI18N\n        // -----\n\n        private static final String FILTER_EMPTY = \"\"; // NOI18N\n        \n        private final Set<ChangeListener> listeners = new HashSet<>();\n        private final List<String> filterTypeNames = new ArrayList<>();\n        private final List<Integer> filterTypes = new ArrayList<>();\n\n        private final boolean toLowerCase;\n        private String filterValue = FILTER_EMPTY;\n        private int filterType = FILTER_NONE;\n        private String filterHint;\n\n        private final JComponent component;\n        private final FilterCombo filterCombo;\n        \n        private boolean suppressEvents = false;\n\n\n        Impl(boolean createDefaultFilters, boolean lowerCase) {\n            toLowerCase = lowerCase;\n            \n            filterCombo = new FilterCombo();\n            filterCombo.setToolTipText(FILTER_TOOLTIP);\n        \n            component = new JPanel(new BorderLayout()) {\n                public void setBounds(int x, int y, int w, int h) {\n                    if (UIUtils.isAquaLookAndFeel()) w += 2;\n                    super.setBounds(x, y, w, h);\n                }\n            };\n            component.setOpaque(false);\n            \n            if (UIUtils.isWindowsLookAndFeel() || UIUtils.isMetalLookAndFeel()) {\n                Insets i = filterCombo.getInsets();\n                component.setBorder(BorderFactory.createEmptyBorder(0, -i.left, 0, -i.right));\n            } else if (UIUtils.isGTKLookAndFeel()) {\n                component.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 1));\n            }\n            component.add(filterCombo, BorderLayout.CENTER);\n            \n            if (createDefaultFilters) {\n                addFilterType(STRING_FILTER_CONTAINS, FILTER_CONTAINS);\n                addFilterType(STRING_FILTER_NOT_CONTAINS, FILTER_NOT_CONTAINS);\n                addFilterType(STRING_FILTER_REGEXP, FILTER_REGEXP);\n            }\n        }\n        \n        \n        public JComponent getComponent() {\n            return component;\n        }\n\n\n        public void setFilterValue(String value) {\n            value = value == null ? value : value.trim();\n            if (filterValue.equals(value)) return;\n            filterValue = value;\n            filterCombo.setText(value);\n        }\n    \n        public String getFilterValue() {\n            return toLowerCase && isCaseInsensitiveFilter() ?\n                    filterValue.toLowerCase() : filterValue;\n        }\n        \n        private boolean isCaseInsensitiveFilter() {\n            return filterType == FILTER_CONTAINS ||\n                   filterType == FILTER_NOT_CONTAINS;\n        }\n    \n        public void addFilterType(String name, int type) {\n            filterTypeNames.add(name);\n            filterTypes.add(type);\n            if (filterType == FILTER_NONE) setFilterType(type);\n        }\n    \n        public void setFilterType(int type) {\n            if (type != FILTER_NONE) filterTypeChanged(type);\n        }\n    \n        public int getFilterType() {\n            return getFilterValue().isEmpty() ? FILTER_NONE : filterType;\n        }\n    \n        public void setFilter(String value, int type) {\n            if (filterValue.equals(value) && filterType == type) return;\n            suppressEvents = true;\n            try {\n                setFilterType(type);\n                setFilterValue(value);\n            } finally {\n                suppressEvents = false;\n            }\n            \n            fireChange();\n        }\n\n        public void setHint(String hint) {\n            if (filterHint != null && filterHint.equals(hint)) return;\n            filterHint = hint;\n            setHintImpl();\n        }\n        \n        private void setHintImpl() {\n            String type = filterTypeNames.get(filterTypes.indexOf(filterType));\n            filterCombo.setHint(MessageFormat.format(FILTER_HINT, filterHint, type));\n        }\n        \n        public String getHint() {\n            return filterHint;\n        }\n        \n        public void addChangeListener(ChangeListener listener) {\n            listeners.add(listener);\n        }\n    \n        public void removeChangeListener(ChangeListener listener) {\n            listeners.remove(listener);\n        }\n\n        \n        private void filterValueChanged(String newFilter) {\n            if (filterValue.equals(newFilter)) return;\n            filterValue = newFilter;\n            fireChange();\n        }\n\n        private void filterTypeChanged(int newType) {\n            if (filterType == newType) return;\n            filterType = newType;\n            setHintImpl();\n            fireChange();\n        }\n        \n        private void fireChange() {\n            if (suppressEvents) return;\n            ChangeEvent event = new ChangeEvent(this);\n            for (ChangeListener listener : listeners)\n                listener.stateChanged(event);\n        }\n\n        private void submitFilter() {\n            String filter = filterCombo.getText();\n            filterCombo.addItem(filter);\n            filterCombo.setSelectedItem(filter);\n        }\n\n        private void clearFilter() {\n            filterCombo.setSelectedItem(FILTER_EMPTY);\n        }\n\n        private void showPopup() {\n            JPopupMenu menu = new JPopupMenu();\n            for (int i = 0; i < filterTypeNames.size(); i++) {\n                final int type = filterTypes.get(i);\n                JMenuItem m = new JRadioButtonMenuItem(filterTypeNames.get(i)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        setFilterType(type);\n                    }\n                };\n                m.setSelected(type == filterType);\n                menu.add(m);\n            }\n\n            menu.show(filterCombo, 0, filterCombo.getHeight() - filterCombo.getInsets().bottom);\n        }\n\n\n        private final class FilterCombo extends JComboBox {\n\n            FilterCombo() {\n                super(new DefaultComboBoxModel());\n                setEditor(new FilterComboEditor(getEditor()));\n                setEditable(true); // must be invoked after setEditor\n            }\n\n            public void setHint(String hint) {\n                getEditorImpl().setHint(hint);\n            }\n\n            public String getText() {\n                return getEditorImpl().getItem().toString().trim();\n            }\n            \n            public void setText(String text) {\n                getEditorImpl().setItem(text);\n            }\n\n            public void setSelectedItem(final Object newObject) {\n                super.setSelectedItem(newObject);\n\n                final FilterComboEditor editorImpl = getEditorImpl();\n                editorImpl.setItem(newObject);\n\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        if (!isPopupVisible()) {\n                            editorImpl.requestFocusInWindow();\n                            filterValueChanged(newObject.toString());\n                            editorImpl.textChanged();\n                        }\n                    }\n                });\n            }\n\n            public Object getSelectedItem() {\n                Object selected = super.getSelectedItem();\n                return selected == null ? FILTER_EMPTY : selected;\n            }\n\n            public void addItem(Object anObject) {\n                String item = anObject == null ? null : anObject.toString();\n                if (item == null || item.isEmpty()) return;\n\n                DefaultComboBoxModel model = getModelImpl();\n                Object selected = model.getSelectedItem();\n                int index = model.getIndexOf(item);\n                if (index > 0) model.removeElement(item);\n                if (index != 0) model.insertElementAt(item, 0);\n                model.setSelectedItem(selected);\n            }\n\n            public DefaultComboBoxModel getModelImpl() {\n                return (DefaultComboBoxModel)super.getModel();\n            }\n\n            public FilterComboEditor getEditorImpl() {\n                return (FilterComboEditor)super.getEditor();\n            }\n\n        }\n\n        private final class FilterComboEditor extends JTextField implements ComboBoxEditor {\n\n            private final IconButton filterButton;\n            private final IconButton confirmButton;\n            private final IconButton clearButton;\n            private final JPanel buttonsPanel;\n            private final JLabel hintLabel;\n\n            FilterComboEditor(ComboBoxEditor impl) {\n\n                // Filter button ---------------------------------------------------\n                filterButton = new IconButton(Icons.getIcon(GeneralIcons.FILTER)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        showPopup();\n                    }\n                    public String getToolTipText() {\n                        int filterIndex = filterTypes.indexOf(filterType);\n                        return filterIndex != -1 ? MessageFormat.format(FILTER_TYPE_TOOLTIP,\n                                filterTypeNames.get(filterIndex)) : null;\n                    }\n                };\n                filterButton.setRolloverIcon(Icons.getIcon(GeneralIcons.FILTER_HIGHL));\n                filterButton.setToolTipText(\"\"); // NOI18N // Enable tooltip\n\n                // Confirm button --------------------------------------------------\n                confirmButton = new IconButton(Icons.getIcon(GeneralIcons.SET_FILTER)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        submitFilter();\n                    }\n                };\n                confirmButton.setRolloverIcon(Icons.getIcon(GeneralIcons.SET_FILTER_HIGHL));\n                confirmButton.setToolTipText(SUBMIT_TOOLTIP);\n\n                // Clear button ----------------------------------------------------\n                clearButton = new IconButton(Icons.getIcon(GeneralIcons.CLEAR_FILTER)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        clearFilter();\n                    }\n                };\n                clearButton.setRolloverIcon(Icons.getIcon(GeneralIcons.CLEAR_FILTER_HIGHL));\n                clearButton.setToolTipText(CLEAR_TOOLTIP);\n\n                // Confirm & Clear container ---------------------------------------\n                buttonsPanel = new JPanel(new BorderLayout(0, 0));\n                buttonsPanel.setOpaque(false);\n                buttonsPanel.add(confirmButton, BorderLayout.WEST);\n                buttonsPanel.add(clearButton, BorderLayout.EAST);\n                \n                getAccessibleContext().setAccessibleName(ACCESS_NAME);\n                getAccessibleContext().setAccessibleDescription(ACCESS_DESCR);\n\n                setLayout(null);\n                add(filterButton);\n                add(buttonsPanel);\n\n                tweakAppearance((JComponent)impl.getEditorComponent());\n\n                hintLabel = new JLabel() {\n                    protected void paintBorder(Graphics g) {}\n                };\n                hintLabel.setOpaque(false);\n                hintLabel.setEnabled(false);\n                hintLabel.setBorder(getBorder());\n\n                getDocument().addDocumentListener(new DocumentListener() {\n                    @Override\n                    public void insertUpdate(DocumentEvent e) { textChanged(); }\n                    @Override\n                    public void removeUpdate(DocumentEvent e) { textChanged(); }\n                    @Override\n                    public void changedUpdate(DocumentEvent e) { textChanged(); }\n                });\n\n                addFocusListener(new FocusListener() {\n                    @Override\n                    public void focusGained(FocusEvent e) { repaint(); }\n                    @Override\n                    public void focusLost(FocusEvent e) { repaint(); }\n                });\n\n                textChanged();\n\n            }\n\n            private void tweakAppearance(JComponent impl) {\n                // Mark as ComboBox editor\n                setName(\"ComboBox.textField\"); // Nimbus\n\n                // Button margins\n                if (UIUtils.isNimbusLookAndFeel() || UIUtils.isAquaLookAndFeel()) {\n                    filterButton.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 4));\n                } else if (UIUtils.isWindowsLookAndFeel()) {\n                    filterButton.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 1));\n                } else { // Metal, GTK\n                    filterButton.setBorder(BorderFactory.createEmptyBorder(0, 7, 0, 2));\n                }\n                confirmButton.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 4));\n                clearButton.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 4));\n\n                // Set border and margin\n                int leftMargin = filterButton.getPreferredSize().width + 2;\n                if (UIUtils.isGTKLookAndFeel()) leftMargin -= 4;\n                else if (UIUtils.isAquaLookAndFeel()) leftMargin -= 8;\n                int rightMargin = buttonsPanel.getPreferredSize().width + 2;\n                if (UIUtils.isAquaLookAndFeel()) rightMargin += 10;\n                else if (UIUtils.isWindowsLookAndFeel()) rightMargin -= 2;\n                Border margin = BorderFactory.createEmptyBorder(0, leftMargin, 0, rightMargin);\n                if (UIUtils.isNimbusLookAndFeel()) {\n                    setBorder(margin);\n                } else {\n                    setBorder(impl.getBorder());\n                    UIUtils.addBorder(this, margin);\n                }\n\n                // Set size\n                if (UIUtils.isMetalLookAndFeel()) {\n                    setPreferredSize(impl.getPreferredSize());\n                }\n            }\n\n            public void paint(Graphics g) {\n                super.paint(g);\n                if (!isFocusOwner() && getText().isEmpty())\n                    hintLabel.paint(g);\n            }\n\n            public void setBounds(int x, int y, int w, int  h) {\n                int woffset = UIUtils.isAquaLookAndFeel() ? 14 : 0;\n                super.setBounds(x, y, w + woffset, h);\n                hintLabel.setBounds(x, y, w + woffset, h);\n            }\n\n            public void doLayout() {\n                Dimension d = filterButton.getPreferredSize();\n                filterButton.setBounds(0, 0, d.width, getHeight());\n\n                int woffset = UIUtils.isAquaLookAndFeel() ? 14 : 0;\n                int xoffset = UIUtils.isAquaLookAndFeel() ? 5 + woffset : 0;\n                d = buttonsPanel.getPreferredSize();\n                buttonsPanel.setBounds(getWidth() - d.width  - xoffset, 0, d.width, getHeight());\n            }\n\n            public void processKeyEvent(KeyEvent e) {\n                super.processKeyEvent(e);\n                if (e.getID() != KeyEvent.KEY_PRESSED) return;\n                \n                int keyCode = e.getKeyCode();\n\n                if (keyCode == KeyEvent.VK_ENTER) submitFilter();\n                else if (keyCode == KeyEvent.VK_ESCAPE) clearFilter();\n                else if ((keyCode == KeyEvent.VK_CONTEXT_MENU) ||\n                        ((keyCode == KeyEvent.VK_F10) &&\n                        (e.getModifiers() == InputEvent.SHIFT_MASK))) showPopup();\n            }\n\n            public boolean isOptimizedDrawingEnabled() {\n                return false;\n            }\n\n            public void setHint(String hint) {\n                hintLabel.setText(hint);\n                repaint();\n            }\n\n            @Override\n            public Component getEditorComponent() {\n                return this;\n            }\n\n            @Override\n            public void setItem(Object anObject) {\n                setText(anObject == null ? FILTER_EMPTY : anObject.toString());\n            }\n\n            @Override\n            public Object getItem() {\n                return getText();\n            }\n\n            @Override\n            public void selectAll() {\n                super.selectAll();\n                requestFocus();\n            }\n\n            @Override\n            public void addActionListener(ActionListener l) {\n                super.addActionListener(l);\n            }\n\n            @Override\n            public void removeActionListener(ActionListener l) {\n                super.removeActionListener(l);\n            }\n\n            public void textChanged() {\n                String text = getText();\n                confirmButton.setVisible(!text.equals(filterValue));\n                clearButton.setVisible(!text.isEmpty());\n            }\n\n        }\n\n        private static class IconButton extends JButton {\n\n            IconButton(Icon icon) {\n                super(icon);\n                setOpaque(false);\n                setRolloverEnabled(true);\n                setMargin(new Insets(0, 0, 0, 0));\n                setBorderPainted(false);\n                setContentAreaFilled(false);\n                setRequestFocusEnabled(false);\n                setDefaultCapable(false);\n                setCursor(Cursor.getDefaultCursor());\n            }\n\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/FlatToolBar.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\nimport java.net.URL;\nimport javax.swing.*;\nimport javax.swing.border.AbstractBorder;\nimport javax.swing.border.CompoundBorder;\nimport javax.swing.plaf.UIResource;\nimport javax.swing.plaf.basic.BasicToolBarUI;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * A special version of ToolBar that has transparent background and rollover button style.\n * Can be used e.g. on on a white background form-like UI.\n *\n * @author Ian Formanek\n */\npublic class FlatToolBar extends JToolBar {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class FlatMarginBorder extends AbstractBorder {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public Insets getBorderInsets(Component c) {\n            return getBorderInsets(c, new Insets(0, 0, 0, 0));\n        }\n\n        public Insets getBorderInsets(Component c, Insets insets) {\n            Insets margin = null;\n\n            if (c instanceof AbstractButton) {\n                AbstractButton b = (AbstractButton) c;\n                margin = b.getMargin();\n            }\n\n            insets.top = (margin != null) ? margin.top : 0;\n            insets.left = (margin != null) ? margin.left : 0;\n            insets.bottom = (margin != null) ? margin.bottom : 0;\n            insets.right = (margin != null) ? margin.right : 0;\n\n            return insets;\n        }\n    }\n\n    /**\n     * Special thin border for rollover toolbar buttons.\n     */\n    public static class FlatRolloverButtonBorder extends AbstractBorder {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private Color normal;\n        private Color pressed;\n        private Color roll;\n        private boolean borderPainted = false;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public FlatRolloverButtonBorder(Color pressed, Color roll) {\n            super();\n            this.pressed = pressed;\n            this.roll = roll;\n            this.borderPainted = false;\n        }\n\n        public FlatRolloverButtonBorder(Color pressed, Color roll, Color normal) {\n            super();\n            this.pressed = pressed;\n            this.roll = roll;\n            this.normal = normal;\n            this.borderPainted = true;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public Insets getBorderInsets(Component c) {\n            return getBorderInsets(c, new Insets(0, 0, 0, 0));\n        }\n\n        public Insets getBorderInsets(Component c, Insets insets) {\n            // leave room for default visual\n            insets.top = 2;\n            insets.left = insets.bottom = insets.right = 3;\n\n            return insets;\n        }\n\n        public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {\n            AbstractButton b = (AbstractButton) c;\n            ButtonModel model = b.getModel();\n\n            if ((model.isRollover() && !(model.isPressed() && !model.isArmed())) || model.isSelected()) {\n                Color oldColor = g.getColor();\n                g.translate(x, y);\n\n                if ((model.isPressed() && model.isArmed()) || model.isSelected()) {\n                    // Draw the pressed button\n                    g.setColor(pressed);\n                    g.drawRect(0, 0, w - 1, h - 1);\n                } else {\n                    // Draw a rollover button\n                    g.setColor(roll);\n                    g.drawRect(0, 0, w - 1, h - 1);\n                }\n\n                g.translate(-x, -y);\n                g.setColor(oldColor);\n            } else if (borderPainted) {\n                Color oldColor = g.getColor();\n                g.translate(x, y);\n                g.setColor(normal);\n                g.drawRect(0, 0, w - 1, h - 1);\n                g.translate(-x, -y);\n                g.setColor(oldColor);\n            }\n        }\n    }\n\n    private static class MyToolBarUI extends BasicToolBarUI {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private AbstractBorder myRolloverBorder;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        MyToolBarUI() {\n            myRolloverBorder = new CompoundBorder(new FlatRolloverButtonBorder(Color.GRAY, Color.LIGHT_GRAY),\n                                                  new FlatMarginBorder());\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        protected void setBorderToRollover(Component c) {\n            if (c instanceof AbstractButton) {\n                AbstractButton b = (AbstractButton) c;\n\n                if (b.getBorder() instanceof UIResource) {\n                    b.setBorder(myRolloverBorder);\n                }\n\n                b.setRolloverEnabled(true);\n            }\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int BUTTON_STYLE_HORIZONTAL = 1;\n    public static final int BUTTON_STYLE_VERICAL = 2;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    int buttonStyle = BUTTON_STYLE_HORIZONTAL;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a horizontal toolbar with horizontal button style (i.e. icon left to text)\n     */\n    public FlatToolBar() {\n        this(HORIZONTAL, BUTTON_STYLE_HORIZONTAL);\n    }\n\n    /**\n     * Creates a toolbar with specified orientation and horizontal button style (i.e. icon left to text)\n     *\n     * @see JToolBar#HORIZONTAL\n     * @see JToolBar#VERTICAL\n     * @param orientation\n     */\n    public FlatToolBar(int orientation) {\n        this(orientation, BUTTON_STYLE_HORIZONTAL);\n    }\n\n    /**\n     * Creates a toolbar with specified orientation and button style\n     *\n     * @see JToolBar#HORIZONTAL\n     * @see JToolBar#VERTICAL\n     *\n     * @param orientation\n     * @param buttonStyle\n     */\n    public FlatToolBar(int orientation, int buttonStyle) {\n        super(orientation);\n        this.buttonStyle = buttonStyle;\n\n        if (!UIUtils.isGTKLookAndFeel()) {\n            setUI(new MyToolBarUI());\n        }\n\n        setFloatable(false);\n        setOpaque(false);\n        putClientProperty(\"JToolBar.isRollover\", Boolean.TRUE); //NOI18N\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    protected void addImpl(Component comp, Object constraints, int index) {\n        if (comp instanceof AbstractButton) {\n            AbstractButton ab = (AbstractButton) comp;\n            ab.setContentAreaFilled(false);\n            ab.setMargin(new Insets(3, 3, 3, 3));\n\n            if (buttonStyle == BUTTON_STYLE_VERICAL) {\n                ab.setVerticalTextPosition(SwingConstants.BOTTOM);\n                ab.setHorizontalTextPosition(SwingConstants.CENTER);\n            }\n        }\n\n        super.addImpl(comp, constraints, index);\n    }\n\n    protected JButton createActionComponent(Action a) {\n        JButton b = super.createActionComponent(a);\n\n        if (buttonStyle == BUTTON_STYLE_VERICAL) {\n            b.putClientProperty(\"hideActionText\", Boolean.FALSE); //NOI18N\n\n            String iconBase = (String) a.getValue(\"iconBase\"); //NOI18N\n\n            if (iconBase != null) {\n                try {\n                    System.err.println(\"URL for: \" + insertBeforeSuffix(iconBase, \"32\")); //NOI18N\n\n                    URL url = a.getClass().getResource(insertBeforeSuffix(iconBase, \"32\")); //NOI18N\n                    System.err.println(\"is: \" + url); //NOI18N\n                    b.setIcon(new ImageIcon(url));\n                } catch (Exception e) {\n                    e.printStackTrace(System.err);\n                }\n            }\n        }\n\n        return b;\n    }\n\n    static String insertBeforeSuffix(String path, String toInsert) {\n        String withoutSuffix = path;\n        String suffix = \"\"; // NOI18N\n\n        if (path.lastIndexOf('.') >= 0) { //NOI18N\n            withoutSuffix = path.substring(0, path.lastIndexOf('.')); //NOI18N\n            suffix = path.substring(path.lastIndexOf('.')); //NOI18N\n        }\n\n        return withoutSuffix + toInsert + suffix;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/HTMLLabel.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.Color;\nimport java.awt.Cursor;\nimport java.awt.Font;\nimport java.net.URL;\nimport javax.swing.JEditorPane;\nimport javax.swing.SwingConstants;\nimport javax.swing.UIManager;\nimport javax.swing.event.HyperlinkEvent;\nimport javax.swing.event.HyperlinkListener;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.NavigationFilter;\nimport javax.swing.text.Position;\nimport javax.swing.text.html.HTMLEditorKit;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * @author Ian Formanek\n */\npublic class HTMLLabel extends JEditorPane implements HyperlinkListener {\n\n    private int halign = SwingConstants.LEADING;\n\n\n    public HTMLLabel() {\n        this(null);\n    }\n\n    public HTMLLabel(String text) {\n        setEditorKit(new HTMLEditorKit());\n        setEditable(false);\n        setOpaque(false);\n        setNavigationFilter(new NavigationFilter() {\n                public void moveDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias) {\n                    super.moveDot(fb, 0, bias);\n                }\n\n                public void setDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias) {\n                    super.setDot(fb, 0, bias);\n                }\n\n                public int getNextVisualPositionFrom(JTextComponent text, int pos, Position.Bias bias, int direction,\n                                                     Position.Bias[] biasRet)\n                                              throws BadLocationException {\n                    return 0;\n                }\n            });\n        setFont(UIManager.getFont(\"Label.font\")); //NOI18N\n        addHyperlinkListener(this);\n\n        if (text != null) setText(text);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    public void setOpaque(boolean o) {\n        super.setOpaque(o);\n        if (UIUtils.isNimbusLookAndFeel() && !o)\n            setBackground(new Color(0, 0, 0, 0));\n        if (txt != null) setText(txt);\n    }\n    \n    private String txt;\n\n    public void setText(String value) {\n        txt = value;\n        \n        Font font = getFont();\n        Color fgColor = getForeground();\n        Color bgColor = getBackground();\n        \n        value = value.replaceAll(\"\\\\n\\\\r|\\\\r\\\\n|\\\\n|\\\\r\", \"<br>\"); //NOI18N\n        value = value.replace(\"<code>\", \"<code style=\\\"font-size: \" + font.getSize() + \"pt;\\\">\"); //NOI18N\n        \n        String fgText = \"rgb(\" + fgColor.getRed() + \",\" + fgColor.getGreen() + \",\" + fgColor.getBlue() + \")\"; //NOI18N\n        String bgText = isOpaque() ? \"rgb(\" + bgColor.getRed() + \",\" + bgColor.getGreen() + \",\" + bgColor.getBlue() + \")\" : null; //NOI18N\n        \n        String alignText = null;\n        switch (halign) {\n            case SwingConstants.CENTER:\n                alignText = \"center\"; //NOI18N\n                break;\n            case SwingConstants.RIGHT:\n            case SwingConstants.TRAILING:\n                alignText = \"right\"; //NOI18N\n                break;\n        }\n        \n        String bodyFlags = \"text=\\\"\" + fgText + \"\\\"\"; //NOI18N\n        if (bgText != null) bodyFlags += \" bgcolor=\\\"\" + bgText + \"\\\"\"; //NOI18N\n        if (alignText != null) bodyFlags += \" align=\\\"\" + alignText + \"\\\"\"; //NOI18N\n        \n        super.setText(\"<html><body \" + bodyFlags + \" style=\\\"font-size: \" + font.getSize() //NOI18N\n                      + \"pt; font-family: \" + font.getName() + \";\\\">\" + value + \"</body></html>\"); //NOI18N\n    }\n    \n    public void setForeground(Color fg) {\n        super.setForeground(fg);\n        if (txt != null) setText(txt);\n    }\n    \n    public void setBackground(Color bg) {\n        super.setBackground(bg);\n//        setBorder(getBorder());\n        if (txt != null) setText(txt);\n    }\n    \n//    public void setBorder(Border b) {\n//        Insets i = b == null ? new Insets(0, 0, 0, 0) : b.getBorderInsets(this);\n//        if (!isOpaque()) super.setBorder(BorderFactory.createEmptyBorder(i.top, i.left, i.bottom, i.right));\n//        else super.setBorder(BorderFactory.createMatteBorder(i.top, i.left, i.bottom, i.right, getBackground()));\n//    }\n    \n    public void setHorizontalAlignment(int alignment) {\n        if (alignment == halign) return;\n        halign = alignment;\n        if (txt != null) setText(txt);\n    }\n\n    public void hyperlinkUpdate(HyperlinkEvent e) {\n        if (!isEnabled()) {\n            return;\n        }\n\n        if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {\n            showURL(e.getURL());\n        } else if (e.getEventType() == HyperlinkEvent.EventType.ENTERED) {\n            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n        } else if (e.getEventType() == HyperlinkEvent.EventType.EXITED) {\n            setCursor(Cursor.getDefaultCursor());\n        }\n    }\n\n    protected void showURL(URL url) {\n        // override to react to URL clicks\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/HTMLTextArea.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\nimport java.awt.datatransfer.Clipboard;\nimport java.awt.datatransfer.DataFlavor;\nimport java.awt.datatransfer.StringSelection;\nimport java.awt.datatransfer.Transferable;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyAdapter;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseEvent;\nimport java.io.IOException;\nimport java.io.StringWriter;\nimport java.io.Writer;\nimport java.net.URL;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport javax.swing.event.HyperlinkEvent;\nimport javax.swing.event.HyperlinkListener;\nimport javax.swing.text.AttributeSet;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.EditorKit;\nimport javax.swing.text.Element;\nimport javax.swing.text.StyleConstants;\nimport javax.swing.text.html.HTML;\nimport javax.swing.text.html.HTMLDocument;\nimport javax.swing.text.html.HTMLEditorKit;\nimport javax.swing.text.html.HTMLWriter;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic class HTMLTextArea extends JEditorPane implements HyperlinkListener {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    /** Private Writer that extracts correctly formatted string from HTMLDocument */\n    private static class ExtendedHTMLWriter extends HTMLWriter {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ExtendedHTMLWriter(Writer w, HTMLDocument doc, int pos, int len) {\n            super(w, doc, pos, len);\n            setLineLength(Integer.MAX_VALUE);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        protected boolean isSupportedBreakFlowTag(AttributeSet attr) {\n            Object o = attr.getAttribute(StyleConstants.NameAttribute);\n\n            if (o instanceof HTML.Tag) {\n                HTML.Tag tag = (HTML.Tag) o;\n\n                if ((tag == HTML.Tag.HTML) || (tag == HTML.Tag.HEAD) || (tag == HTML.Tag.BODY) || (tag == HTML.Tag.HR)) {\n                    return false;\n                }\n\n                return (tag).breaksFlow();\n            }\n\n            return false;\n        }\n\n        protected void emptyTag(Element elem) throws BadLocationException, IOException {\n            if (isSupportedBreakFlowTag(elem.getAttributes())) {\n                writeLineSeparator();\n            }\n\n            if (matchNameAttribute(elem.getAttributes(), HTML.Tag.CONTENT)) {\n                text(elem);\n            }\n        }\n\n        protected void endTag(Element elem) throws IOException {\n            if (isSupportedBreakFlowTag(elem.getAttributes())) {\n                writeLineSeparator();\n            }\n        }\n\n        protected void startTag(Element elem) throws IOException, BadLocationException {\n        }\n    }\n\n    // --- Private classes for copy/paste support --------------------------------\n    //\n    // NOTE: only vertical formatting is correctly copy/pasted,\n    //       horizontal formatting (ul, li) is ignored.\n\n    /** Private TransferHandler that copies correctly formatted string from HTMLDocument to system clipboard */\n    private class HTMLTextAreaTransferHandler extends TransferHandler {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void exportToClipboard(JComponent comp, Clipboard clip, int action) {\n            try {\n                int selStart = getSelectionStart();\n                int selLength = getSelectionEnd() - selStart;\n\n                StringWriter plainTextWriter = new StringWriter();\n\n                try {\n                    new ExtendedHTMLWriter(plainTextWriter, (HTMLDocument) getDocument(), selStart, selLength).write();\n                } catch (Exception e) {\n                }\n\n                String plainText = NcrToUnicode.decode(plainTextWriter.toString());\n                clip.setContents(new StringSelection(plainText), null);\n\n                if (action == TransferHandler.MOVE) {\n                    getDocument().remove(selStart, selLength);\n                }\n            } catch (BadLocationException ble) {\n            }\n        }\n    }\n\n    /** Class for decoding strings from NCR to Unicode */\n    private static class NcrToUnicode {\n        //~ Static fields/initializers -------------------------------------------------------------------------------------------\n\n        private static Map<String,String> entities;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public static String decode(String str) {\n            StringBuilder ostr = new StringBuilder();\n            int i1 = 0;\n            int i2 = 0;\n\n            while (i2 < str.length()) {\n                i1 = str.indexOf('&', i2); //NOI18N\n\n                if (i1 == -1) {\n                    ostr.append(str, i2, str.length());\n\n                    break;\n                }\n\n                ostr.append(str, i2, i1);\n                i2 = str.indexOf(';', i1); //NOI18N\n\n                if (i2 == -1) {\n                    ostr.append(str, i1, str.length());\n\n                    break;\n                }\n\n                String tok = str.substring(i1 + 1, i2);\n\n                if (tok.charAt(0) == '#') { //NOI18N\n\n                    if (tok.equals(\"#160\")) { //NOI18N\n                        ostr.append(getEntities().get(\"nbsp\")); //NOI18N // Fixes Issue 92818, \"&nbsp;\" is resolved as \"&#160;\" before decoding, so redirecting back to \"&nbsp;\"\n                    } else {\n                        tok = tok.substring(1);\n\n                        try {\n                            int radix = 10;\n\n                            if (tok.trim().charAt(0) == 'x') { //NOI18N\n                                radix = 16;\n                                tok = tok.substring(1);\n                            }\n\n                            ostr.append((char) Integer.parseInt(tok, radix));\n                        } catch (NumberFormatException exp) {\n                            ostr.append('?'); //NOI18N\n                        }\n                    }\n                } else {\n                    tok = getEntities().get(tok);\n\n                    if (tok != null) {\n                        ostr.append(tok);\n                    } else {\n                        ostr.append('?'); //NOI18N\n                    }\n                }\n\n                i2++;\n            }\n\n            return ostr.toString();\n        }\n\n        private static synchronized Map<String,String> getEntities() {\n            if (entities == null) {\n                entities = new HashMap<>();\n                //Quotation mark\n                entities.put(\"quot\", \"\\\"\"); //NOI18N\n                                            //Ampersand\n\n                entities.put(\"amp\", \"\\u0026\"); //NOI18N\n                                               //Less than\n\n                entities.put(\"lt\", \"\\u003C\"); //NOI18N\n                                              //Greater than\n\n                entities.put(\"gt\", \"\\u003E\"); //NOI18N\n                                              //Nonbreaking space\n\n                entities.put(\"nbsp\", \"\\u0020\"); //NOI18N // Fixes Issue 92818, \"\\u00A0\" (&nbsp; equivalent) is resolved as incorrect character, thus mapping to standard space\n                                                //Inverted exclamation point\n\n                entities.put(\"iexcl\", \"\\u00A1\"); //NOI18N\n                                                 //Cent sign\n\n                entities.put(\"cent\", \"\\u00A2\"); //NOI18N\n                                                //Pound sign\n\n                entities.put(\"pound\", \"\\u00A3\"); //NOI18N\n                                                 //General currency sign\n\n                entities.put(\"curren\", \"\\u00A4\"); //NOI18N\n                                                  //Yen sign\n\n                entities.put(\"yen\", \"\\u00A5\"); //NOI18N\n                                               //Broken vertical bar\n\n                entities.put(\"brvbar\", \"\\u00A6\"); //NOI18N\n                                                  //Section sign\n\n                entities.put(\"sect\", \"\\u00A7\"); //NOI18N\n                                                //Umlaut\n\n                entities.put(\"uml\", \"\\u00A8\"); //NOI18N\n                                               //Copyright\n\n                entities.put(\"copy\", \"\\u00A9\"); //NOI18N\n                                                //Feminine ordinal\n\n                entities.put(\"ordf\", \"\\u00AA\"); //NOI18N\n                                                //Left angle quote\n\n                entities.put(\"laquo\", \"\\u00AB\"); //NOI18N\n                                                 //Not sign\n\n                entities.put(\"not\", \"\\u00AC\"); //NOI18N\n                                               //Soft hyphen\n\n                entities.put(\"shy\", \"\\u00AD\"); //NOI18N\n                                               //Registered trademark\n\n                entities.put(\"reg\", \"\\u00AE\"); //NOI18N\n                                               //Macron accent\n\n                entities.put(\"macr\", \"\\u00AF\"); //NOI18N\n                                                //Degree sign\n\n                entities.put(\"deg\", \"\\u00B0\"); //NOI18N\n                                               //Plus or minus\n\n                entities.put(\"plusmn\", \"\\u00B1\"); //NOI18N\n                                                  //Superscript 2\n\n                entities.put(\"sup2\", \"\\u00B2\"); //NOI18N\n                                                //Superscript 3\n\n                entities.put(\"sup3\", \"\\u00B3\"); //NOI18N\n                                                //Acute accent\n\n                entities.put(\"acute\", \"\\u00B4\"); //NOI18N\n                                                 //Micro sign (Greek mu)\n\n                entities.put(\"micro\", \"\\u00B5\"); //NOI18N\n                                                 //Paragraph sign\n\n                entities.put(\"para\", \"\\u00B6\"); //NOI18N\n                                                //Middle dot\n\n                entities.put(\"middot\", \"\\u00B7\"); //NOI18N\n                                                  //Cedilla\n\n                entities.put(\"cedil\", \"\\u00B8\"); //NOI18N\n                                                 //Superscript 1\n\n                entities.put(\"sup1\", \"\\u00B9\"); //NOI18N\n                                                //Masculine ordinal\n\n                entities.put(\"ordm\", \"\\u00BA\"); //NOI18N\n                                                //Right angle quote\n\n                entities.put(\"raquo\", \"\\u00BB\"); //NOI18N\n                                                 //Fraction one-fourth\n\n                entities.put(\"frac14\", \"\\u00BC\"); //NOI18N\n                                                  //Fraction one-half\n\n                entities.put(\"frac12\", \"\\u00BD\"); //NOI18N\n                                                  //Fraction three-fourths\n\n                entities.put(\"frac34\", \"\\u00BE\"); //NOI18N\n                                                  //Inverted question mark\n\n                entities.put(\"iquest\", \"\\u00BF\"); //NOI18N\n                                                  //Capital A, grave accent\n\n                entities.put(\"Agrave\", \"\\u00C0\"); //NOI18N\n                                                  //Capital A, acute accent\n\n                entities.put(\"Aacute\", \"\\u00C1\"); //NOI18N\n                                                  //Capital A, circumflex accent\n\n                entities.put(\"Acirc\", \"\\u00C2\"); //NOI18N\n                                                 //Capital A, tilde\n\n                entities.put(\"Atilde\", \"\\u00C3\"); //NOI18N\n                                                  //Capital A, umlaut\n\n                entities.put(\"Auml\", \"\\u00C4\"); //NOI18N\n                                                //Capital A, ring\n\n                entities.put(\"Aring\", \"\\u00C5\"); //NOI18N\n                                                 //Capital AE ligature\n\n                entities.put(\"AElig\", \"\\u00C6\"); //NOI18N\n                                                 //Capital C, cedilla\n\n                entities.put(\"Ccedil\", \"\\u00C7\"); //NOI18N\n                                                  //Capital E, grave accent\n\n                entities.put(\"Egrave\", \"\\u00C8\"); //NOI18N\n                                                  //Capital E, acute accent\n\n                entities.put(\"Eacute\", \"\\u00C9\"); //NOI18N\n                                                  //Capital E, circumflex accent\n\n                entities.put(\"Ecirc\", \"\\u00CA\"); //NOI18N\n                                                 //Capital E, umlaut\n\n                entities.put(\"Euml\", \"\\u00CB\"); //NOI18N\n                                                //Capital I, grave accent\n\n                entities.put(\"Igrave\", \"\\u00CC\"); //NOI18N\n                                                  //Capital I, acute accent\n\n                entities.put(\"Iacute\", \"\\u00CD\"); //NOI18N\n                                                  //Capital I, circumflex accent\n\n                entities.put(\"Icirc\", \"\\u00CE\"); //NOI18N\n                                                 //Capital I, umlaut\n\n                entities.put(\"Iuml\", \"\\u00CF\"); //NOI18N\n                                                //Capital eth, Icelandic\n\n                entities.put(\"ETH\", \"\\u00D0\"); //NOI18N\n                                               //Capital N, tilde\n\n                entities.put(\"Ntilde\", \"\\u00D1\"); //NOI18N\n                                                  //Capital O, grave accent\n\n                entities.put(\"Ograve\", \"\\u00D2\"); //NOI18N\n                                                  //Capital O, acute accent\n\n                entities.put(\"Oacute\", \"\\u00D3\"); //NOI18N\n                                                  //Capital O, circumflex accent\n\n                entities.put(\"Ocirc\", \"\\u00D4\"); //NOI18N\n                                                 //Capital O, tilde\n\n                entities.put(\"Otilde\", \"\\u00D5\"); //NOI18N\n                                                  //Capital O, umlaut\n\n                entities.put(\"Ouml\", \"\\u00D6\"); //NOI18N\n                                                //Multiply sign\n\n                entities.put(\"times\", \"\\u00D7\"); //NOI18N\n                                                 //Capital O, slash\n\n                entities.put(\"Oslash\", \"\\u00D8\"); //NOI18N\n                                                  //Capital U, grave accent\n\n                entities.put(\"Ugrave\", \"\\u00D9\"); //NOI18N\n                                                  //Capital U, acute accent\n\n                entities.put(\"Uacute\", \"\\u00DA\"); //NOI18N\n                                                  //Capital U, circumflex accent\n\n                entities.put(\"Ucirc\", \"\\u00DB\"); //NOI18N\n                                                 //Capital U, umlaut\n\n                entities.put(\"Uuml\", \"\\u00DC\"); //NOI18N\n                                                //Capital Y, acute accent\n\n                entities.put(\"Yacute\", \"\\u00DD\"); //NOI18N\n                                                  //Capital thorn, Icelandic\n\n                entities.put(\"THORN\", \"\\u00DE\"); //NOI18N\n                                                 //Small sz ligature, German\n\n                entities.put(\"szlig\", \"\\u00DF\"); //NOI18N\n                                                 //Small a, grave accent\n\n                entities.put(\"agrave\", \"\\u00E0\"); //NOI18N\n                                                  //Small a, acute accent\n\n                entities.put(\"aacute\", \"\\u00E1\"); //NOI18N\n                                                  //Small a, circumflex accent\n\n                entities.put(\"acirc\", \"\\u00E2\"); //NOI18N\n                                                 //Small a, tilde\n\n                entities.put(\"atilde\", \"\\u00E3\"); //NOI18N\n                                                  //Small a, umlaut\n\n                entities.put(\"auml\", \"\\u00E4\"); //NOI18N\n                                                //Small a, ring\n\n                entities.put(\"aring\", \"\\u00E5\"); //NOI18N\n                                                 //Small ae ligature\n\n                entities.put(\"aelig\", \"\\u00E6\"); //NOI18N\n                                                 //Small c, cedilla\n\n                entities.put(\"ccedil\", \"\\u00E7\"); //NOI18N\n                                                  //Small e, grave accent\n\n                entities.put(\"egrave\", \"\\u00E8\"); //NOI18N\n                                                  //Small e, acute accent\n\n                entities.put(\"eacute\", \"\\u00E9\"); //NOI18N\n                                                  //Small e, circumflex accent\n\n                entities.put(\"ecirc\", \"\\u00EA\"); //NOI18N\n                                                 //Small e, umlaut\n\n                entities.put(\"euml\", \"\\u00EB\"); //NOI18N\n                                                //Small i, grave accent\n\n                entities.put(\"igrave\", \"\\u00EC\"); //NOI18N\n                                                  //Small i, acute accent\n\n                entities.put(\"iacute\", \"\\u00ED\"); //NOI18N\n                                                  //Small i, circumflex accent\n\n                entities.put(\"icirc\", \"\\u00EE\"); //NOI18N\n                                                 //Small i, umlaut\n\n                entities.put(\"iuml\", \"\\u00EF\"); //NOI18N\n                                                //Small eth, Icelandic\n\n                entities.put(\"eth\", \"\\u00F0\"); //NOI18N\n                                               //Small n, tilde\n\n                entities.put(\"ntilde\", \"\\u00F1\"); //NOI18N\n                                                  //Small o, grave accent\n\n                entities.put(\"ograve\", \"\\u00F2\"); //NOI18N\n                                                  //Small o, acute accent\n\n                entities.put(\"oacute\", \"\\u00F3\"); //NOI18N\n                                                  //Small o, circumflex accent\n\n                entities.put(\"ocirc\", \"\\u00F4\"); //NOI18N\n                                                 //Small o, tilde\n\n                entities.put(\"otilde\", \"\\u00F5\"); //NOI18N\n                                                  //Small o, umlaut\n\n                entities.put(\"ouml\", \"\\u00F6\"); //NOI18N\n                                                //Division sign\n\n                entities.put(\"divide\", \"\\u00F7\"); //NOI18N\n                                                  //Small o, slash\n\n                entities.put(\"oslash\", \"\\u00F8\"); //NOI18N\n                                                  //Small u, grave accent\n\n                entities.put(\"ugrave\", \"\\u00F9\"); //NOI18N\n                                                  //Small u, acute accent\n\n                entities.put(\"uacute\", \"\\u00FA\"); //NOI18N\n                                                  //Small u, circumflex accent\n\n                entities.put(\"ucirc\", \"\\u00FB\"); //NOI18N\n                                                 //Small u, umlaut\n\n                entities.put(\"uuml\", \"\\u00FC\"); //NOI18N\n                                                //Small y, acute accent\n\n                entities.put(\"yacute\", \"\\u00FD\"); //NOI18N\n                                                  //Small thorn, Icelandic\n\n                entities.put(\"thorn\", \"\\u00FE\"); //NOI18N\n                                                 //Small y, umlaut\n\n                entities.put(\"yuml\", \"\\u00FF\"); //NOI18N\n            }\n\n            return entities;\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.components.Bundle\"); // NOI18N\n    private static final String CUT_STRING = messages.getString(\"HTMLTextArea_CutString\"); // NOI18N\n    private static final String COPY_STRING = messages.getString(\"HTMLTextArea_CopyString\"); // NOI18N\n    private static final String PASTE_STRING = messages.getString(\"HTMLTextArea_PasteString\"); // NOI18N\n    private static final String DELETE_STRING = messages.getString(\"HTMLTextArea_DeleteString\"); // NOI18N\n    private static final String SELECT_ALL_STRING = messages.getString(\"HTMLTextArea_SelectAllString\"); // NOI18N\n                                                                                                        // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private URL activeLink;\n\n    private boolean showPopup = true;\n\n    // --- Lazy setting text ---------------------------------------------------\n    private String pendingText;\n    private int pendingDot = -1;\n    \n    private String currentText;\n    private boolean forceSetText;\n    \n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public HTMLTextArea() {\n        setContentType(\"text/html\"); // NOI18N\n        setEditable(false);\n        setOpaque(true);\n        setAutoscrolls(true);\n        addHyperlinkListener(this);\n        setTransferHandler(new HTMLTextAreaTransferHandler());\n        setFont(UIManager.getFont(\"Label.font\")); //NOI18N\n        setBackground(UIUtils.getProfilerResultsBackground());\n        \n        addKeyListener(new KeyAdapter() {\n            public void keyPressed(KeyEvent e) {\n                if (e.getKeyCode() == KeyEvent.VK_SPACE)\n                    invokeSelectedLink();\n            }\n        });\n\n        // Bugfix #185777, update text only if visible\n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (isShowing() && pendingText != null) setText(pendingText);\n                    }\n                }\n        });\n    }\n\n    public HTMLTextArea(String text) {\n        this();\n        setText(text);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    public EditorKit getEditorKitForContentType(String type) {\n        // Always assumes \"text/html\" as this is a HTML displayer\n        return new HTMLEditorKit();\n    }\n    \n    public void setOpaque(boolean o) {\n        super.setOpaque(o);\n        if (UIUtils.isNimbusLookAndFeel() && !o)\n            setBackground(new Color(0, 0, 0, 0));\n    }\n\n    public void setForeground(Color color) {\n        Color foreground = getForeground();\n        if (foreground != null && foreground.equals(color)) return;\n\n        super.setForeground(color);\n        forceSetText = true;\n        setText(getText());\n    }\n\n    public void setShowPopup(boolean showPopup) {\n        this.showPopup = showPopup;\n    }\n\n    public boolean getShowPopup() {\n        return showPopup;\n    }\n    \n    public void setCaretPosition(int position) {\n        if (pendingText == null) super.setCaretPosition(position);\n        else pendingDot = position;\n    }\n\n    public void setText(String value) {\n        if (value == null) return;\n\n        if (!isShowing() && !forceSetText) {\n\n            pendingText = value;\n\n        } else {\n\n            if (!forceSetText && value.equals(currentText)) return;\n\n            currentText = value;\n            pendingText = null;\n\n            Font font = getFont();\n            Color textColor = getForeground();\n            value = value.replaceAll(\"\\\\n\\\\r|\\\\r\\\\n|\\\\n|\\\\r\", \"<br>\"); //NOI18N\n            value = value.replace(\"<code>\", \"<code style=\\\"font-size: \" + font.getSize() + \"pt;\\\">\"); //NOI18N\n\n            int index = getHeaderEndIndex(value);\n            String header = \"\";\n            if (index != -1) {\n                header = value.substring(0, index);\n                value = value.substring(index);\n            }\n            String colorText = \"rgb(\" + textColor.getRed() + \",\" + textColor.getGreen() + \",\" + textColor.getBlue() + \")\"; //NOI18N\n            String newText = \"<html>\" + header + \"<body text=\\\"\" + colorText + \"\\\" style=\\\"font-size: \" + font.getSize() + //NOI18N\n                             \"pt; font-family: \" + font.getName() + \";\\\">\" + value + \"</body></html>\"; //NOI18N\n\n            setDocument(getEditorKit().createDefaultDocument()); // Workaround for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5042872\n            super.setText(newText);\n\n            if (pendingDot != -1) {\n                try { setCaretPosition(pendingDot); }\n                catch (IllegalArgumentException ex) {} // expected\n                pendingDot = -1;\n            }\n        }\n\n        forceSetText = false;\n    }\n\n    public String getText() {\n        return pendingText != null ? pendingText : currentText;\n    }\n\n    public Dimension getMinimumSize() {\n        if (pendingText != null) {\n            forceSetText = true;\n            setText(pendingText);\n        }\n        return super.getMinimumSize();\n    }\n\n    public Dimension getPreferredSize() {\n        if (pendingText != null) {\n            forceSetText = true;\n            setText(pendingText);\n        }\n        return super.getPreferredSize();\n    }\n\n    public Dimension getMaximumSize() {\n        if (pendingText != null) {\n            forceSetText = true;\n            setText(pendingText);\n        }\n        return super.getMaximumSize();\n    }\n\n    public void deleteSelection() {\n        try {\n            getDocument().remove(getSelectionStart(), getSelectionEnd() - getSelectionStart());\n        } catch (Exception ex) {}\n    }\n    \n    private void invokeSelectedLink() {\n        for (Action action : getEditorKit().getActions()) {\n            if (\"activate-link-action\".equals(action.getValue(Action.NAME))) {  // NOI18N\n                action.actionPerformed(new ActionEvent(this, 0, null));\n                return;\n            }\n        }\n    }\n\n    public void hyperlinkUpdate(HyperlinkEvent e) {\n        if (!isEnabled()) {\n            return;\n        }\n\n        if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {\n            activeLink = e.getURL();\n            showURL(activeLink, e.getInputEvent());\n        } else if (e.getEventType() == HyperlinkEvent.EventType.ENTERED) {\n            activeLink = e.getURL();\n            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n        } else if (e.getEventType() == HyperlinkEvent.EventType.EXITED) {\n            activeLink = null;\n            setCursor(Cursor.getDefaultCursor());\n        }\n    }\n    \n    public URL getActiveLink() {\n        return activeLink;\n    }\n    \n    protected void processMouseEvent(MouseEvent e) {\n        if (e.isPopupTrigger()) showPopupMenu(e);\n        super.processMouseEvent(e);\n    }\n    \n    protected void processKeyEvent(KeyEvent e) {\n        int code = e.getKeyCode();\n        if (code == KeyEvent.VK_CONTEXT_MENU ||\n           (code == KeyEvent.VK_F10 && e.getModifiers() == InputEvent.SHIFT_MASK)) {\n            e.consume();\n            showPopupMenu(null);\n        }\n        \n        super.processKeyEvent(e);\n    }\n    \n    private void showPopupMenu(MouseEvent e) {\n        if (isEnabled() && isFocusable() && showPopup) {\n            JPopupMenu popup = new JPopupMenu();\n            populatePopup(popup);\n\n            if (popup.getComponentCount() > 0) {\n\n                if (!hasFocus()) requestFocus(); // required for Select All functionality\n                \n                int x, y;\n                if (e != null) {\n                    x = e.getX();\n                    y = e.getY();\n                } else {\n                    Rectangle vis = getVisibleRect();\n                    x = vis.x + vis.width / 2;\n                    y = vis.y + vis.height / 2;\n                    \n                    try {\n                        Rectangle pos = modelToView(getCaretPosition());\n                        if (pos != null) {\n                            pos.width = Math.max(pos.width, 1); // must have nonzero width for the intersects() to work\n                            if (vis.intersects(pos)) {\n                                x = pos.x + pos.width;\n                                y = pos.y + pos.height;\n                            }\n                        }\n                    } catch (BadLocationException ex) {}\n                }\n\n                popup.show(this, x, y);\n            }\n        }\n    }\n\n    protected void populatePopup(JPopupMenu popup) {\n        popup.add(createCutMenuItem());\n        popup.add(createCopyMenuItem());\n        popup.add(createPasteMenuItem());\n        popup.add(createDeleteMenuItem());\n        popup.addSeparator();\n        popup.add(createSelectAllMenuItem());\n        \n        Action find = getActionMap().get(HTMLTextAreaSearchUtils.FIND_ACTION_KEY); \n        if (find != null) {\n            popup.addSeparator();\n            popup.add(new JMenuItem(find));\n        }\n    }\n    \n    protected JMenuItem createCutMenuItem() {\n        return new JMenuItem(CUT_STRING) {\n            { setEnabled(isEditable() && getSelectedText() != null); }\n            protected void fireActionPerformed(ActionEvent e) { cut(); }\n        };\n    }\n    \n    protected JMenuItem createCopyMenuItem() {\n        return new JMenuItem(COPY_STRING) {\n            { setEnabled(getSelectedText() != null); }\n            protected void fireActionPerformed(ActionEvent e) { copy(); }\n        };\n    }\n    \n    protected JMenuItem createPasteMenuItem() {\n        return new JMenuItem(PASTE_STRING) {\n            {\n                if (isEditable()) {\n                    try {\n                        Transferable clipboardContent = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this);\n                        setEnabled(clipboardContent != null && clipboardContent.isDataFlavorSupported(DataFlavor.stringFlavor));\n                    } catch (Exception e) {\n                        setEnabled(false);\n                    }\n                } else {\n                    setEnabled(false);\n                }\n            }\n            protected void fireActionPerformed(ActionEvent e) { paste(); }\n        };\n    }\n    \n    protected JMenuItem createDeleteMenuItem() {\n        return new JMenuItem(DELETE_STRING) {\n            {\n                if (isEditable()) {\n                    setEnabled(getSelectedText() != null);\n                } else {\n                    setVisible(false);\n                }\n            }\n            protected void fireActionPerformed(ActionEvent e) { deleteSelection(); }\n        };\n    }\n    \n    protected JMenuItem createSelectAllMenuItem() {\n        return new JMenuItem(SELECT_ALL_STRING) {\n            protected void fireActionPerformed(ActionEvent e) { selectAll(); }\n        };\n    }\n    \n    public void paste() {\n        try {\n            replaceSelection(Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this)\n                                    .getTransferData(DataFlavor.stringFlavor).toString());\n        } catch (Exception ex) {}\n    }\n    \n    protected void showURL(URL url, InputEvent e) {\n        showURL(url);\n    }\n\n    protected void showURL(URL url) {\n        // override to react to URL clicks\n    }\n    \n    private static int getHeaderEndIndex(String htmlText) {\n        if (htmlText.startsWith(\"<head>\")) {\n            return htmlText.indexOf(\"</head>\")+\"</head>\".length();\n        }\n        return -1;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/HTMLTextAreaSearchUtils.java",
    "content": "/*\n * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Shape;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyEvent;\nimport java.text.MessageFormat;\nimport java.text.NumberFormat;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.ResourceBundle;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.JToolBar;\nimport javax.swing.KeyStroke;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.Caret;\nimport javax.swing.text.DefaultCaret;\nimport javax.swing.text.DefaultHighlighter.DefaultHighlightPainter;\nimport javax.swing.text.Document;\nimport javax.swing.text.Highlighter;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.View;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.EditableHistoryCombo;\nimport org.graalvm.visualvm.lib.ui.swing.InvisibleToolbar;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class HTMLTextAreaSearchUtils {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.components.Bundle\"); // NOI18N\n    private static final String FIND_ACTION_NAME = messages.getString(\"HTMLTextAreaSearchUtils_FindActionName\"); // NOI18N\n    private static final String MATCHES_PATTERN = messages.getString(\"HTMLTextAreaSearchUtils_MatchesPattern\"); // NOI18N\n    private static final String NO_MATCHES = messages.getString(\"HTMLTextAreaSearchUtils_NoMatches\"); // NOI18N\n    private static final String MATCHES_TOOLTIP = messages.getString(\"HTMLTextAreaSearchUtils_MatchesTooltip\"); // NOI18N\n    private static final String SIDEBAR_CAPTION = messages.getString(\"HTMLTextAreaSearchUtils_SidebarCaption\"); // NOI18N\n    private static final String BTN_PREVIOUS = messages.getString(\"HTMLTextAreaSearchUtils_BtnPrevious\"); // NOI18N\n    private static final String BTN_PREVIOUS_TOOLTIP = messages.getString(\"HTMLTextAreaSearchUtils_BtnPreviousTooltip\"); // NOI18N\n    private static final String BTN_NEXT = messages.getString(\"HTMLTextAreaSearchUtils_BtnNext\"); // NOI18N\n    private static final String BTN_NEXT_TOOLTIP = messages.getString(\"HTMLTextAreaSearchUtils_BtnNextTooltip\"); // NOI18N\n    private static final String BTN_MATCH_CASE_TOOLTIP = messages.getString(\"HTMLTextAreaSearchUtils_BtnMatchCaseTooltip\"); // NOI18N\n    private static final String BTN_CLOSE_TOOLTIP = messages.getString(\"HTMLTextAreaSearchUtils_BtnCloseTooltip\"); // NOI18N\n    // -----\n    \n    public static final String FIND_ACTION_KEY = \"find-action-key\"; // NOI18N\n    public static final String FIND_NEXT_ACTION_KEY = \"find-next-action-key\"; // NOI18N\n    public static final String FIND_PREV_ACTION_KEY = \"find-prev-action-key\"; // NOI18N\n    public static final String FIND_SEL_ACTION_KEY = \"find-sel-action-key\"; // NOI18N\n    \n    private static final String FIND_CLOSE_ACTION_KEY = \"find-close-action-key\"; // NOI18N\n    \n    private static final String PROP_LAST_FIND_TEXT = \"last-find-text\"; // NOI18N\n    private static final String PROP_LAST_FIND_MATCH_CASE = \"last-find-match-case\"; // NOI18N\n    private static final String PROP_SEARCH_PANEL = \"search-panel\"; // NOI18N\n    private static final String PROP_SEARCH_RESULT = \"search-result\"; // NOI18N\n    \n    \n    public static boolean findString(HTMLTextArea area, String text) {\n        return findString(area, text, true, true);\n    }\n    \n    public static boolean findString(HTMLTextArea area, String text, boolean matchCase, boolean next) {\n        DocumentSearchResult result = findStringImpl(area, text, matchCase);\n        if (result == null) return false;\n        \n        int offset = next ? area.getSelectionEnd() : area.getSelectionStart();\n        int closest = next ? result.getNextIndex(offset) : result.getPreviousIndex(offset);\n        \n        if (closest < 0) {\n            area.select(area.getSelectionStart(), area.getSelectionStart());\n            return false;\n        } else {\n            offset = result.getOffset(closest);\n            area.select(offset, offset + text.length());\n            return true;\n        }\n    }\n    \n    \n    public static void textChanged(HTMLTextArea area) {\n        DocumentSearchResult result = DocumentSearchResult.reset(area);\n        SearchPanel search = (SearchPanel)area.getClientProperty(PROP_SEARCH_PANEL);\n        if (search.isVisible()) search.clearResultsFeedback(result);\n    }\n    \n    \n    private static DocumentSearchResult findStringImpl(HTMLTextArea area, String text, boolean matchCase) {\n        area.putClientProperty(PROP_LAST_FIND_TEXT, text);\n        area.putClientProperty(PROP_LAST_FIND_MATCH_CASE, Boolean.toString(matchCase));\n        \n        return DocumentSearchResult.get(text, matchCase, area);\n    }\n    \n    \n    private static class DocumentSearchResult {\n        \n        private final String search;\n        private final boolean matchCase;\n        \n        private final List<Integer> result;\n        private final List<Object> highlights;\n        \n        \n        static DocumentSearchResult current(JTextComponent component) {\n            return (DocumentSearchResult)component.getClientProperty(PROP_SEARCH_RESULT);\n        }\n        \n        static DocumentSearchResult get(String search, boolean matchCase, JTextComponent component) {\n            DocumentSearchResult result = current(component);\n            if (result != null) {\n                if (result.compatibleSearch(search, matchCase)) return result;\n                else result.clearHighlightedResults(component.getHighlighter());\n            }\n                \n            try {\n                Document document = component.getDocument();\n                result = new DocumentSearchResult(search, matchCase, document.getText(0, document.getLength()));\n                component.putClientProperty(PROP_SEARCH_RESULT, result);\n                return result;\n            } catch (BadLocationException ex) {\n                return null;\n            }\n        }\n        \n        static DocumentSearchResult reset(JTextComponent component) {\n            DocumentSearchResult result = DocumentSearchResult.current(component);\n            \n            if (result != null) {\n                result.clearHighlightedResults(component.getHighlighter());\n                component.putClientProperty(PROP_SEARCH_RESULT, null);\n            }\n            \n            return result;\n        }\n        \n        \n        private DocumentSearchResult(String search, boolean matchCase, String text) {\n            if (!matchCase) {\n                search = search.toLowerCase(Locale.ENGLISH);\n                text = text.toLowerCase(Locale.ENGLISH);\n            }\n            \n            this.search = search;\n            this.matchCase = matchCase;\n            \n            this.result = new ArrayList<>();\n            this.highlights = new ArrayList<>();\n            \n            int searchLength = search.length();\n            int offset = text.indexOf(search);\n            \n            while (offset >= 0) {\n                result.add(offset);\n                offset = text.indexOf(search, offset + searchLength);\n            }\n        }\n        \n        \n        private boolean compatibleSearch(String string, boolean match) {\n            if (matchCase != match) return false;\n            return search.equals(matchCase ? string : string.toLowerCase(Locale.ENGLISH));\n        }\n        \n        \n        void highlightResults(Highlighter hl) {\n            clearHighlightedResults(hl);\n            \n            for (int offset : result) {\n                try { highlights.add(hl.addHighlight(offset, offset + search.length(), new CustomHighlightPainter())); }\n                catch (BadLocationException ex) {}\n            }\n        }\n        \n        void clearHighlightedResults(Highlighter hl) {\n            for (Object highlight : highlights) hl.removeHighlight(highlight);\n            \n            highlights.clear();\n        }\n        \n        int getResultsCount() {\n            return result.size();\n        }\n        \n        int getOffset(int index) {\n            return result.get(index);\n        }\n        \n        int getNextIndex(int offset) {\n            if (result.isEmpty()) return -1;            \n            \n            for (int index = 0; index < result.size(); index++)\n                if (result.get(index) > offset) return index;\n            \n            return 0;\n        }\n        \n        int getPreviousIndex(int offset) {\n            if (result.isEmpty()) return -1;            \n            \n            for (int i = result.size() - 1; i >= 0; i--)\n                if (result.get(i) < offset) return i;\n            \n            return result.size() - 1;\n        }\n        \n    }\n    \n    \n//    // NOTE: must not be direct subclass of DefaultHighlightPainter to not overlap selection\n//    private static final class ResultsHighlightPainter implements Highlighter.HighlightPainter {\n//        \n//        private static final Highlighter.HighlightPainter IMPL = new DefaultHighlightPainter(Color.ORANGE);\n//\n//        @Override\n//        public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c) {\n//            IMPL.paint(g, p0, p1, bounds, c);\n//        }\n//        \n//    }\n    \n    \n    private static final class CustomHighlightPainter extends DefaultHighlightPainter {\n        \n        CustomHighlightPainter() {\n            super(Color.ORANGE);\n        }\n        \n        public Shape paintLayer(Graphics g, int offs0, int offs1,\n                                Shape bounds, JTextComponent c, View view) {\n            \n            int selStart = c.getSelectionStart();\n            int selEnd = c.getSelectionEnd();\n            \n            // No selection or selection fully outside of the highlight\n            if (selEnd - selStart == 0 || offs0 >= selEnd || offs1 <= selStart) return super.paintLayer(g, offs0, offs1, bounds, c, view);\n            \n            // Selection fully covers the highlight\n            if (offs0 >= selStart && offs1 <= selEnd) return bounds;\n            \n            // Selection partially covers the highlight\n            if (offs0 < selStart || offs1 > selEnd) {\n                // Selection ends inside of the highlight\n                if (offs0 >= selStart) return super.paintLayer(g, selEnd, offs1, bounds, c, view);\n                // Selection starts inside of the highlight\n                else if (offs1 <= selEnd) return super.paintLayer(g, offs0, selStart, bounds, c, view);\n                \n                // Selection fully inside of the highlight\n                super.paintLayer(g, offs0, selStart, bounds, c, view);\n                super.paintLayer(g, selEnd, offs1, bounds, c, view);\n            }\n            \n            return bounds;\n        }\n        \n    }\n    \n    \n    public static JComponent createSearchPanel(final HTMLTextArea area) {\n        SearchPanel sp = new SearchPanel(area) {\n            public void setVisible(boolean visible) {\n                super.setVisible(visible);\n                if (!visible) area.requestFocusInWindow();\n            }\n        };\n        area.putClientProperty(PROP_SEARCH_PANEL, sp);\n        enableSearchActions(area);\n        \n        // Make sure selection is visible even if the text area is not focused\n        Caret caret = area.getCaret();\n        if (caret instanceof DefaultCaret) {\n            area.setCaret(new DefaultCaret() {\n                public void setSelectionVisible(boolean visible) {\n                   super.setSelectionVisible(true);\n                }\n            });\n        }\n        \n        return sp;\n    }\n    \n    \n    private static class SearchPanel extends JPanel {\n        \n        private final HTMLTextArea area;\n        \n        private final EditableHistoryCombo combo;\n        private final JTextComponent textC;\n        \n        private final JToggleButton matchCase;\n        private final JToggleButton highlightResults;\n        \n        private final JLabel feedback;\n        \n        \n        SearchPanel(final HTMLTextArea area) {\n            super(new BorderLayout());\n            setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UIManager.getColor(\"controlShadow\"))); // NOI18N       \n            \n            this.area = area;\n            \n            feedback = new JLabel();\n            feedback.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));\n            \n            JToolBar toolbar = new InvisibleToolbar();\n            if (UIUtils.isWindowsModernLookAndFeel())\n                toolbar.setBorder(BorderFactory.createEmptyBorder(2, 2, 1, 2));\n            else if (!UIUtils.isNimbusLookAndFeel() && !UIUtils.isAquaLookAndFeel())\n                toolbar.setBorder(BorderFactory.createEmptyBorder(1, 2, 1, 2));\n\n            toolbar.add(Box.createHorizontalStrut(6));\n            toolbar.add(new JLabel(SIDEBAR_CAPTION));\n            toolbar.add(Box.createHorizontalStrut(3));\n            add(toolbar, BorderLayout.CENTER);\n            \n            combo = new EditableHistoryCombo();        \n            textC = combo.getTextComponent();\n\n            JPanel comboContainer = new JPanel(new BorderLayout());\n            comboContainer.add(combo, BorderLayout.CENTER);\n            comboContainer.setMinimumSize(combo.getMinimumSize());\n            comboContainer.setPreferredSize(combo.getPreferredSize());\n            comboContainer.setMaximumSize(combo.getMaximumSize());\n\n            toolbar.add(comboContainer);\n            \n            toolbar.add(Box.createHorizontalStrut(5));\n        \n            KeyStroke escKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);\n            KeyStroke prevKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_MASK);\n            KeyStroke nextKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);\n\n            matchCase = new JToggleButton(Icons.getIcon(GeneralIcons.MATCH_CASE)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            clearResultsFeedback(DocumentSearchResult.current(area));\n                        }\n                    });\n                }\n            };\n            matchCase.setToolTipText(BTN_MATCH_CASE_TOOLTIP);\n            // NOTE: added below\n            \n            highlightResults = new JToggleButton(Icons.getIcon(GeneralIcons.HIGHLIGHT_RESULTS), true) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            DocumentSearchResult result = DocumentSearchResult.current(area);\n                            if (result != null) {\n                                Highlighter hl = area.getHighlighter();\n                                result.clearHighlightedResults(hl);\n                                \n                                if (isSelected() && !feedback.getText().isEmpty() && result.getResultsCount() > 0)\n                                    result.highlightResults(hl);\n                            }\n                        }\n                    });\n                }\n            };\n            highlightResults.setToolTipText(MATCHES_TOOLTIP);\n            // NOTE: added below\n\n            final JButton prev = new JButton(BTN_PREVIOUS, Icons.getIcon(GeneralIcons.FIND_PREVIOUS)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            String search = getSearchString();\n                            if (search.isEmpty()) return;\n                            \n                            DocumentSearchResult result = findStringImpl(area, search, matchCase.isSelected());\n                            int results = result.getResultsCount();\n                            \n                            if (results > 0) {\n                                int index = result.getPreviousIndex(area.getSelectionStart());\n                                setResultsFeedback(index, results, result);\n                                combo.addItem(search);\n                                \n                                int offset = result.getOffset(index);\n                                area.select(offset, offset + search.length());\n                            } else {\n                                feedback.setText(NO_MATCHES);\n                                area.select(area.getSelectionStart(), area.getSelectionStart());\n                            }\n                        }\n                    });\n                }\n            };\n            prev.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            prev.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n            String prevAccelerator = ActionsSupport.keyAcceleratorString(prevKey);\n            prev.setToolTipText(MessageFormat.format(BTN_PREVIOUS_TOOLTIP, prevAccelerator));\n            prev.setEnabled(false);\n            toolbar.add(prev);\n\n            if (!UIUtils.isAquaLookAndFeel()) toolbar.add(Box.createHorizontalStrut(2));\n\n            final JButton next = new JButton(BTN_NEXT, Icons.getIcon(GeneralIcons.FIND_NEXT)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            String search = getSearchString();\n                            if (search.isEmpty()) return;\n                            \n                            DocumentSearchResult result = findStringImpl(area, search, matchCase.isSelected());\n                            int results = result.getResultsCount();\n                            \n                            if (results > 0) {\n                                int index = result.getNextIndex(area.getSelectionEnd());\n                                setResultsFeedback(index, results, result);\n                                combo.addItem(search);\n                                \n                                int offset = result.getOffset(index);\n                                area.select(offset, offset + search.length());\n                            } else {\n                                feedback.setText(NO_MATCHES);\n                                area.select(area.getSelectionStart(), area.getSelectionStart());\n                            }\n                        }\n                    });\n                }\n            };\n            next.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            next.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n            String nextAccelerator = ActionsSupport.keyAcceleratorString(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));\n            next.setToolTipText(MessageFormat.format(BTN_NEXT_TOOLTIP, nextAccelerator));\n            next.setEnabled(false);\n            toolbar.add(next);\n\n            toolbar.add(Box.createHorizontalStrut(2));\n\n            toolbar.addSeparator();\n\n            toolbar.add(Box.createHorizontalStrut(1));\n\n            toolbar.add(matchCase);\n            toolbar.add(highlightResults);\n\n//            if (options != null) for (Component option : options) toolbar.add(option);\n\n            toolbar.add(Box.createHorizontalStrut(2));\n\n            combo.setOnTextChangeHandler(new Runnable() {\n                public void run() {\n                    boolean enable = !combo.getText().trim().isEmpty();\n                    prev.setEnabled(enable);\n                    next.setEnabled(enable);\n                }\n            });\n            \n            final Runnable hider = new Runnable() { public void run() { setVisible(false); } };\n            JButton closeButton = CloseButton.create(hider);\n            String escAccelerator = ActionsSupport.keyAcceleratorString(escKey);\n            closeButton.setToolTipText(MessageFormat.format(BTN_CLOSE_TOOLTIP, escAccelerator));\n            \n            String HIDE = \"hide-action\"; // NOI18N\n            InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n            Action hiderAction = new AbstractAction() {\n                public void actionPerformed(ActionEvent e) { hider.run(); }\n            };\n            getActionMap().put(HIDE, hiderAction);\n            inputMap.put(escKey, HIDE);\n            \n            if (textC != null) {\n//                inputMap = textC.getInputMap();\n//                ActionMap actionMap = textC.getActionMap();\n                ActionMap actionMap = getActionMap();\n\n                String NEXT = \"search-next-action\"; // NOI18N\n                Action nextAction = new AbstractAction() {\n                    public void actionPerformed(final ActionEvent e) {\n                        if (combo.isPopupVisible()) combo.hidePopup();\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() { if (next.isEnabled()) next.doClick(); }\n                        });\n                    }\n                };\n                actionMap.put(NEXT, nextAction);\n                inputMap.put(nextKey, NEXT);\n                if (textC != null) {\n                    textC.getActionMap().put(NEXT, nextAction);\n                    textC.getInputMap().put(nextKey, NEXT);\n                }\n\n                KeyStroke nextKey2 = ActionsSupport.registerAction(FIND_NEXT_ACTION_KEY, nextAction, actionMap, inputMap);\n                String nextAccelerator2 = ActionsSupport.keyAcceleratorString(nextKey2);\n                if (nextAccelerator2 != null) next.setToolTipText(MessageFormat.format(BTN_NEXT_TOOLTIP,\n                                                             nextAccelerator + \", \" + nextAccelerator2)); // NOI18N\n\n                String PREV = \"search-prev-action\"; // NOI18N\n                Action prevAction = new AbstractAction() {\n                    public void actionPerformed(final ActionEvent e) {\n                        if (combo.isPopupVisible()) combo.hidePopup();\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() { if (next.isEnabled()) prev.doClick(); }\n                        });\n                    }\n                };\n                actionMap.put(PREV, prevAction);\n                inputMap.put(prevKey, PREV);\n                if (textC != null) {\n                    textC.getActionMap().put(PREV, prevAction);\n                    textC.getInputMap().put(prevKey, PREV);\n                }\n\n                KeyStroke prevKey2 = ActionsSupport.registerAction(FIND_PREV_ACTION_KEY, prevAction, actionMap, inputMap);\n                String prevAccelerator2 = ActionsSupport.keyAcceleratorString(prevKey2);\n                if (prevAccelerator2 != null) prev.setToolTipText(MessageFormat.format(BTN_PREVIOUS_TOOLTIP,\n                                                             prevAccelerator + \", \" + prevAccelerator2)); // NOI18N\n            }\n            \n            JPanel rightPanel = new JPanel(new BorderLayout());            \n            rightPanel.add(feedback, BorderLayout.WEST);\n            rightPanel.add(closeButton, BorderLayout.EAST);\n            \n            add(rightPanel, BorderLayout.EAST);\n            \n            setVisible(false);\n        }\n        \n        private String getSearchString() {\n            String search = combo.getText();\n            return search == null ? \"\" : search.trim(); // NOI18N\n        }\n        \n        private void setResultsFeedback(int index, int count, DocumentSearchResult result) {\n            NumberFormat format = NumberFormat.getInstance();\n            feedback.setText(MessageFormat.format(MATCHES_PATTERN, format.format(index + 1), format.format(count)));\n            \n            if (result != null) {\n                if (highlightResults.isSelected()) result.highlightResults(area.getHighlighter());\n                else result.clearHighlightedResults(area.getHighlighter());\n            }\n        }\n        \n        void clearResultsFeedback(DocumentSearchResult result) {\n            feedback.setText(\"\"); // NOI18N\n            if (result != null) result.clearHighlightedResults(area.getHighlighter());\n        }\n        \n        \n        public void setVisible(boolean visible) {\n            super.setVisible(visible);\n            \n            clearResultsFeedback(DocumentSearchResult.current(area));\n            \n            if (visible) {\n                String search = (String)area.getClientProperty(PROP_LAST_FIND_TEXT);\n                textC.setText(search == null ? \"\" : search); // NOI18N\n                \n                boolean match = Boolean.parseBoolean((String)area.getClientProperty(PROP_LAST_FIND_MATCH_CASE));\n                matchCase.setSelected(match);\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        ((JComponent)SearchPanel.this.getParent()).scrollRectToVisible(getBounds());\n                    }\n                });\n                \n                requestFocusInWindow();\n            } else {\n                if (getSearchString().isEmpty()) area.putClientProperty(PROP_LAST_FIND_TEXT, null);\n                area.putClientProperty(PROP_LAST_FIND_MATCH_CASE, Boolean.toString(matchCase.isSelected()));\n            }\n        }\n        \n        public boolean requestFocusInWindow() {\n            if (textC != null) {\n                textC.selectAll();\n                return textC.requestFocusInWindow();\n            }\n            return super.requestFocusInWindow();\n        }\n        \n    }\n    \n    \n    public static void enableSearchActions(final HTMLTextArea area) {\n        ActionMap actionMapArea = area.getActionMap();\n        InputMap inputMapArea = area.getInputMap();\n        \n        Action findAction = new AbstractAction(FIND_ACTION_NAME) {\n            public void actionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        String selected = area.getSelectedText();\n                        if (selected != null) area.putClientProperty(PROP_LAST_FIND_TEXT, selected);\n                        \n                        ((SearchPanel)area.getClientProperty(PROP_SEARCH_PANEL)).setVisible(true);\n                    }\n                });\n            }\n        };\n        ActionsSupport.registerAction(FIND_ACTION_KEY, findAction, actionMapArea, inputMapArea);\n        \n        Action nextAction = new AbstractAction() {\n            public void actionPerformed(final ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        String search = (String)area.getClientProperty(PROP_LAST_FIND_TEXT);\n                        \n                        if (search != null) {\n                            boolean matchCase = Boolean.parseBoolean((String)area.getClientProperty(PROP_LAST_FIND_MATCH_CASE));\n                            findString(area, search, matchCase, true);\n                        } else {\n                            ((SearchPanel)area.getClientProperty(PROP_SEARCH_PANEL)).setVisible(true);\n                        }\n                    }\n                });\n            }\n        };\n        ActionsSupport.registerAction(FIND_NEXT_ACTION_KEY, nextAction, actionMapArea, inputMapArea);\n        \n        Action prevAction = new AbstractAction() {\n            public void actionPerformed(final ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        String search = (String)area.getClientProperty(PROP_LAST_FIND_TEXT);\n                        \n                        if (search != null) {\n                            boolean matchCase = Boolean.parseBoolean((String)area.getClientProperty(PROP_LAST_FIND_MATCH_CASE));\n                            findString(area, search, matchCase, false);\n                        } else {\n                            ((SearchPanel)area.getClientProperty(PROP_SEARCH_PANEL)).setVisible(true);\n                        }\n                    }\n                });\n            }\n        };\n        ActionsSupport.registerAction(FIND_PREV_ACTION_KEY, prevAction, actionMapArea, inputMapArea);\n        \n        Action selAction = new AbstractAction() {\n            public void actionPerformed(final ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        String selected = area.getSelectedText();\n                        area.putClientProperty(PROP_LAST_FIND_TEXT, selected);\n                        \n                        if (selected != null) {\n                            boolean matchCase = Boolean.parseBoolean((String)area.getClientProperty(PROP_LAST_FIND_MATCH_CASE));\n                            findString(area, selected, matchCase, true);\n                        } else {\n                            ((SearchPanel)area.getClientProperty(PROP_SEARCH_PANEL)).setVisible(true);\n                        }\n                    }\n                });\n            }\n        };\n        ActionsSupport.registerAction(FIND_SEL_ACTION_KEY, selAction, actionMapArea, inputMapArea);\n        \n        \n        \n        Action closeAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        ((SearchPanel)area.getClientProperty(PROP_SEARCH_PANEL)).setVisible(false);\n                    }\n                });\n            }\n        };\n        actionMapArea.put(FIND_CLOSE_ACTION_KEY, closeAction);\n        inputMapArea.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), FIND_CLOSE_ACTION_KEY);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/ImageBlenderPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.AlphaComposite;\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Image;\nimport java.awt.image.BufferedImage;\nimport javax.swing.UIManager;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ImageBlenderPanel extends ImagePanel {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Color background;\n    private Image image1;\n    private Image image2;\n    private float blendAlpha;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ImageBlenderPanel(Image image1, Image image2) {\n        this(image1, image2, UIManager.getColor(\"Panel.background\"), 0); // NOI18N\n    }\n\n    public ImageBlenderPanel(Image image1, Image image2, Color background, float blendAlpha) {\n        super(createBlendedImage(image1, image2, background, blendAlpha));\n        this.background = background;\n        this.blendAlpha = blendAlpha;\n        this.image1 = image1;\n        this.image2 = image2;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setBlendAlpha(float blendAlpha) {\n        setImage(createBlendedImage(image1, image2, background, blendAlpha));\n        this.blendAlpha = blendAlpha;\n    }\n\n    private static Image createBlendedImage(Image image1, Image image2, Color background, float blendAlpha) {\n        Image i1 = loadImage(image1);\n        Image i2 = loadImage(image2);\n\n        int blendedImageWidth = Math.max(i1.getWidth(null), i2.getWidth(null));\n        int blendedImageHeight = Math.max(i1.getHeight(null), i2.getHeight(null));\n\n        BufferedImage blendedImage = new BufferedImage(blendedImageWidth, blendedImageHeight, BufferedImage.TYPE_INT_RGB);\n        Graphics2D blendedImageGraphics = (Graphics2D) blendedImage.getGraphics();\n\n        blendedImageGraphics.setColor(background);\n        blendedImageGraphics.fillRect(0, 0, blendedImageWidth, blendedImageHeight);\n        blendedImageGraphics.drawImage(i1, 0, 0, null);\n        blendedImageGraphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, blendAlpha));\n        blendedImageGraphics.drawImage(i2, 0, 0, null);\n\n        return blendedImage;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/ImagePanel.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Image;\nimport java.awt.MediaTracker;\nimport java.awt.image.PixelGrabber;\nimport javax.swing.JPanel;\nimport javax.swing.SwingConstants;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ImagePanel extends JPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static MediaTracker mTracker = new MediaTracker(new JPanel());\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Image image;\n    private int imageAlign; // Use SwingConstants.TOP, BOTTOM (LEFT & RIGHT not implemented)\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ImagePanel(Image image) {\n        this(image, SwingConstants.TOP);\n    }\n\n    public ImagePanel(Image image, int imageAlign) {\n        setImage(image);\n        setImageAlign(imageAlign);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setImage(Image image) {\n        this.image = loadImage(image);\n\n        if (this.image == null) {\n            throw new RuntimeException(\"Failed to load image\"); // NOI18N\n        }\n\n        setPreferredBackground();\n        setPreferredSize(new Dimension(this.image.getWidth(null), this.image.getHeight(null)));\n\n        refresh();\n    }\n\n    public void setImageAlign(int imageAlign) {\n        this.imageAlign = imageAlign;\n\n        setPreferredBackground();\n\n        refresh();\n    }\n\n    protected static Image loadImage(Image image) {\n        mTracker.addImage(image, 0);\n\n        try {\n            mTracker.waitForID(0);\n        } catch (InterruptedException e) {\n            return null;\n        }\n\n        mTracker.removeImage(image, 0);\n\n        return image;\n    }\n\n    protected void setPreferredBackground() {\n        int[] pixels = new int[1];\n\n        PixelGrabber pg = null;\n\n        switch (imageAlign) {\n            case (SwingConstants.TOP):\n                pg = new PixelGrabber(image, 0, image.getHeight(null) - 1, 1, 1, pixels, 0, 1);\n\n                break;\n            case (SwingConstants.BOTTOM):\n                pg = new PixelGrabber(image, 0, 0, 1, 1, pixels, 0, 1);\n\n                break;\n            default:\n                pg = new PixelGrabber(image, 0, image.getHeight(null) - 1, 1, 1, pixels, 0, 1);\n        }\n\n        try {\n            if ((pg != null) && pg.grabPixels()) {\n                setBackground(new Color(pixels[0]));\n            }\n        } catch (InterruptedException e) {\n        }\n    }\n\n    protected void paintComponent(Graphics graphics) {\n        graphics.setColor(getBackground());\n        graphics.fillRect(0, 0, getWidth(), getHeight());\n\n        switch (imageAlign) {\n            case (SwingConstants.TOP):\n                graphics.drawImage(image, (getWidth() - image.getWidth(null)) / 2, 0, this);\n\n                break;\n            case (SwingConstants.BOTTOM):\n                graphics.drawImage(image, (getWidth() - image.getWidth(null)) / 2, getHeight() - image.getHeight(null), this);\n\n                break;\n            default:\n                graphics.drawImage(image, (getWidth() - image.getWidth(null)) / 2, 0, this);\n        }\n    }\n\n    private void refresh() {\n        if (isShowing()) {\n            invalidate();\n            repaint();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/JAntiLabel.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\nimport javax.swing.*;\n\n\n/**\n * Anti-aliased JLabel.\n *\n * @author Ian Formanek\n */\npublic class JAntiLabel extends JLabel {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a <code>JLabel</code> instance with\n     * no image and with an empty string for the title.\n     * The label is centered vertically\n     * in its display area.\n     * The label's contents, once set, will be displayed on the leading edge\n     * of the label's display area.\n     */\n    public JAntiLabel() {\n        super();\n    }\n\n    /**\n     * Creates a <code>JLabel</code> instance with the specified text.\n     * The label is aligned against the leading edge of its display area,\n     * and centered vertically.\n     *\n     * @param text The text to be displayed by the label.\n     */\n    public JAntiLabel(String text) {\n        super(text);\n    }\n\n    /**\n     * Creates a <code>JLabel</code> instance with the specified image.\n     * The label is centered vertically and horizontally\n     * in its display area.\n     *\n     * @param image The image to be displayed by the label.\n     */\n    public JAntiLabel(Icon image) {\n        super(image);\n    }\n\n    /**\n     * Creates a <code>JLabel</code> instance with the specified\n     * text and horizontal alignment.\n     * The label is centered vertically in its display area.\n     *\n     * @param text                The text to be displayed by the label.\n     * @param horizontalAlignment One of the following constants\n     *                            defined in <code>SwingConstants</code>:\n     *                            <code>LEFT</code>,\n     *                            <code>CENTER</code>,\n     *                            <code>RIGHT</code>,\n     *                            <code>LEADING</code> or\n     *                            <code>TRAILING</code>.\n     */\n    public JAntiLabel(String text, int horizontalAlignment) {\n        super(text, horizontalAlignment);\n    }\n\n    /**\n     * Creates a <code>JLabel</code> instance with the specified\n     * image and horizontal alignment.\n     * The label is centered vertically in its display area.\n     *\n     * @param image               The image to be displayed by the label.\n     * @param horizontalAlignment One of the following constants\n     *                            defined in <code>SwingConstants</code>:\n     *                            <code>LEFT</code>,\n     *                            <code>CENTER</code>,\n     *                            <code>RIGHT</code>,\n     *                            <code>LEADING</code> or\n     *                            <code>TRAILING</code>.\n     */\n    public JAntiLabel(Icon image, int horizontalAlignment) {\n        super(image, horizontalAlignment);\n    }\n\n    /**\n     * Creates a <code>JLabel</code> instance with the specified\n     * text, image, and horizontal alignment.\n     * The label is centered vertically in its display area.\n     * The text is on the trailing edge of the image.\n     *\n     * @param text                The text to be displayed by the label.\n     * @param icon                The image to be displayed by the label.\n     * @param horizontalAlignment One of the following constants\n     *                            defined in <code>SwingConstants</code>:\n     *                            <code>LEFT</code>,\n     *                            <code>CENTER</code>,\n     *                            <code>RIGHT</code>,\n     *                            <code>LEADING</code> or\n     *                            <code>TRAILING</code>.\n     */\n    public JAntiLabel(String text, Icon icon, int horizontalAlignment) {\n        super(text, icon, horizontalAlignment);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void paintComponent(Graphics g) {\n        if (g instanceof Graphics2D) {\n            ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);\n        }\n\n        super.paintComponent(g);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/JCheckTree.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.KeyListener;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport java.awt.event.MouseWheelEvent;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.concurrent.CopyOnWriteArraySet;\nimport javax.swing.JFrame;\nimport javax.swing.JScrollPane;\nimport javax.swing.JViewport;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.plaf.basic.BasicTreeUI;\nimport javax.swing.tree.DefaultTreeModel;\nimport javax.swing.tree.TreeCellRenderer;\nimport javax.swing.tree.TreeModel;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.tree.CheckTreeCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.tree.CheckTreeNode;\nimport org.graalvm.visualvm.lib.ui.components.tree.TreeCellRendererPersistent;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JCheckTree extends JExtendedTree {\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    // ---------------------------------------------------------------------------\n\n    // --- CheckTreeListener interface definition --------------------------------\n    public static interface CheckTreeListener {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        void checkNodeToggled(TreePath node, boolean before);\n\n        void checkTreeChanged(Collection<CheckTreeNode> changedNodes);\n    }\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    // ---------------------------------------------------------------------------\n\n    // --- Custom TreeUI implementation ------------------------------------------\n    private class CheckTreeUI extends BasicTreeUI {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        protected boolean isToggleEvent(MouseEvent event) {\n            if (isOverCheckBox(event.getX(), event.getY())) {\n                return false;\n            }\n\n            return super.isToggleEvent(event);\n        }\n    }\n\n    // ---------------------------------------------------------------------------\n\n    // --- Listeners implementation ----------------------------------------------\n    private class PrivateComponentListener implements MouseListener, KeyListener {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void keyPressed(KeyEvent e) {\n            if (e.getKeyCode() == KeyEvent.VK_SPACE) {\n                TreePath[] paths = getSelectionPaths();\n\n                if ((paths != null) && (paths.length > 0)) {\n                    Collection changedNodes = new ArrayList();\n\n                    for (int i = 0; i < paths.length; i++) {\n                        TreePath path = paths[i];\n\n                        if ((path != null) && (path.getPathCount() > 0) && path.getLastPathComponent() instanceof CheckTreeNode\n                                && (((CheckTreeNode) path.getLastPathComponent()).isLeaf() || (i == (paths.length - 1)))) {\n                            fireNodeToggled(path, true);\n                        }\n\n                        changedNodes.addAll(togglePathState(path));\n                        fireNodeToggled(path, false);\n                    }\n\n                    treeDidChange();\n                    fireCheckTreeChanged(changedNodes);\n                }\n            }\n        }\n\n        public void keyReleased(KeyEvent e) {\n        }\n\n        public void keyTyped(KeyEvent e) {\n        }\n\n        public void mouseClicked(MouseEvent e) {\n        }\n\n        public void mouseEntered(MouseEvent e) {\n        }\n\n        public void mouseExited(MouseEvent e) {\n        }\n\n        public void mousePressed(MouseEvent e) {\n            if (isOverCheckBox(e.getX(), e.getY())) {\n                TreePath path = getPathForLocation(e.getX(), e.getY());\n                fireNodeToggled(path, true);\n\n                Collection changedNodes = togglePathState(getPathForLocation(e.getX(), e.getY()));\n                treeDidChange();\n                fireNodeToggled(path, false);\n                fireCheckTreeChanged(changedNodes);\n            }\n        }\n\n        public void mouseReleased(MouseEvent e) {\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private PrivateComponentListener componentListener = new PrivateComponentListener();\n\n    // ---------------------------------------------------------------------------\n\n    // --- CheckTreeListener implementation --------------------------------------\n    private Collection<CheckTreeListener> checkTreeListeners = new CopyOnWriteArraySet<>();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of JCheckTree\n     */\n    public JCheckTree() {\n        if (!UIUtils.isGTKLookAndFeel()) {\n            setUI(new CheckTreeUI());\n        }\n\n        setCellRenderer(new CheckTreeCellRenderer());\n        setModel(getDefaultTreeModel());\n        addMouseListener(componentListener);\n        addKeyListener(componentListener);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    // --- CellTip support -------------------------------------------------------\n    public Point getCellTipLocation() {\n        if (rendererRect == null) {\n            return null;\n        }\n\n        if (getCellRenderer() instanceof TreeCellRendererPersistent) {\n            return new Point((rendererRect.getLocation().x + CheckTreeCellRenderer.getCheckBoxDimension().width) - 1,\n                             rendererRect.getLocation().y - 1);\n        } else {\n            return super.getCellTipLocation();\n        }\n    }\n\n    public void addCheckTreeListener(CheckTreeListener listener) {\n        if (listener != null) {\n            checkTreeListeners.add(listener);\n        }\n    }\n\n    // ---------------------------------------------------------------------------\n\n    // --- Static test frame -----------------------------------------------------\n    public static void main(String[] args) {\n        JFrame frame = new JFrame(\"JCheckTreeTester\"); // NOI18N\n\n        try {\n            UIManager.setLookAndFeel(\"com.sun.java.swing.plaf.windows.WindowsLookAndFeel\"); // NOI18N\n        } catch (Exception e) {\n        }\n\n        JCheckTree checkTree = new JCheckTree();\n        checkTree.addCheckTreeListener(new CheckTreeListener() {\n                public void checkTreeChanged(Collection changedNodes) {\n                    System.out.println(changedNodes);\n                }\n\n                public void checkNodeToggled(TreePath path, boolean before) {\n                    System.out.println(\"Node toggled\"); // NOI18N\n                }\n            });\n\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.getContentPane().add(new JScrollPane(checkTree));\n        frame.pack();\n        frame.setVisible(true);\n    }\n\n    public void processMouseEvent(MouseEvent e) {\n        if (e instanceof MouseWheelEvent) {\n            Component target = JCheckTree.this.getParent();\n            if (!(target instanceof JViewport))\n                target = JCheckTree.this;\n            MouseEvent mwe = SwingUtilities.convertMouseEvent(\n                    JCheckTree.this, e, target);\n            target.dispatchEvent(mwe);\n        } else {\n            super.processMouseEvent(e);\n        }\n    }\n\n    public void removeCheckTreeListener(CheckTreeListener listener) {\n        checkTreeListeners.remove(listener);\n    }\n\n    // ---------------------------------------------------------------------------\n\n    // --- Default model definition ----------------------------------------------\n    protected static TreeModel getDefaultTreeModel() {\n        CheckTreeNode root = new CheckTreeNode(\"JTree\"); // NOI18N\n        CheckTreeNode parent;\n\n        parent = new CheckTreeNode(\"colors\"); // NOI18N\n        root.add(parent);\n        parent.add(new CheckTreeNode(\"blue\")); // NOI18N\n        parent.add(new CheckTreeNode(\"violet\")); // NOI18N\n        parent.add(new CheckTreeNode(\"red\")); // NOI18N\n        parent.add(new CheckTreeNode(\"yellow\")); // NOI18N\n\n        parent = new CheckTreeNode(\"sports\"); // NOI18N\n        root.add(parent);\n        parent.add(new CheckTreeNode(\"basketball\")); // NOI18N\n        parent.add(new CheckTreeNode(\"soccer\")); // NOI18N\n        parent.add(new CheckTreeNode(\"football\")); // NOI18N\n        parent.add(new CheckTreeNode(\"hockey\")); // NOI18N\n\n        parent = new CheckTreeNode(\"food\"); // NOI18N\n        root.add(parent);\n        parent.add(new CheckTreeNode(\"hot dogs\")); // NOI18N\n        parent.add(new CheckTreeNode(\"pizza\")); // NOI18N\n        parent.add(new CheckTreeNode(\"ravioli\")); // NOI18N\n        parent.add(new CheckTreeNode(\"bananas\")); // NOI18N\n\n        return new DefaultTreeModel(root);\n    }\n\n    protected void processCellTipMouseMove(MouseEvent e) {\n        // Identify treetable row and column at cursor\n        TreePath currentTreePath = null;\n\n        try {\n            currentTreePath = getPathForLocation(e.getX(), e.getY()); // workaround for random Issue 113634\n        } catch (Exception ex) {\n        }\n\n        // Return if cursor isn't at any cell\n        if (currentTreePath == null) {\n            CellTipManager.sharedInstance().setEnabled(false);\n            lastTreePath = currentTreePath;\n\n            return;\n        }\n\n        Component cellRenderer;\n        Component cellRendererPersistent;\n        int row = getRowForPath(lastTreePath);\n\n        TreeCellRenderer treeCellRenderer = getCellRenderer();\n\n        if (!(treeCellRenderer instanceof TreeCellRendererPersistent)) {\n            return;\n        }\n\n        cellRenderer = treeCellRenderer.getTreeCellRendererComponent(JCheckTree.this, currentTreePath.getLastPathComponent(),\n                                                                     false, isExpanded(row),\n                                                                     getModel().isLeaf(currentTreePath.getLastPathComponent()),\n                                                                     row, false);\n        cellRendererPersistent = ((TreeCellRendererPersistent) treeCellRenderer).getTreeCellRendererComponentPersistent(JCheckTree.this,\n                                                                                                                        currentTreePath\n                                                                                                                        .getLastPathComponent(),\n                                                                                                                        false,\n                                                                                                                        isExpanded(row),\n                                                                                                                        getModel()\n                                                                                                                            .isLeaf(currentTreePath\n                                                                                                                                    .getLastPathComponent()),\n                                                                                                                        row, false);\n\n        // Return if celltip is not supported for the cell\n        if (cellRenderer == null) {\n            CellTipManager.sharedInstance().setEnabled(false);\n            lastTreePath = currentTreePath;\n\n            return;\n        }\n\n        Point cellStart = getPathBounds(currentTreePath).getLocation();\n        rendererRect = new Rectangle(cellStart.x, cellStart.y, cellRenderer.getPreferredSize().width,\n                                     cellRenderer.getPreferredSize().height + 2);\n\n        // Reset lastTreePath if over checkbox\n        if (e.getX() <= (rendererRect.x + CheckTreeCellRenderer.getCheckBoxDimension().width)) {\n            lastTreePath = new TreePath(new Object());\n            CellTipManager.sharedInstance().setEnabled(false);\n\n            return;\n        }\n\n        // Return if treetable cell is the same as in previous event\n        if (currentTreePath == lastTreePath) {\n            return;\n        }\n\n        lastTreePath = currentTreePath;\n\n        if (!rendererRect.contains(e.getPoint())) {\n            CellTipManager.sharedInstance().setEnabled(false);\n\n            return;\n        }\n\n        // Return if cell contents is fully visible\n        Rectangle visibleRect = getVisibleRect();\n\n        if (((rendererRect.x + CheckTreeCellRenderer.getCheckBoxDimension().width) >= visibleRect.x)\n                && ((rendererRect.x + rendererRect.width) <= (visibleRect.x + visibleRect.width))) {\n            CellTipManager.sharedInstance().setEnabled(false);\n\n            return;\n        }\n\n        while (cellTip.getComponentCount() > 0) {\n            cellTip.remove(0);\n        }\n\n        cellTip.add(cellRendererPersistent, BorderLayout.CENTER);\n        cellTip.setPreferredSize(new Dimension(cellRendererPersistent.getPreferredSize().width + 2, getRowHeight() + 2));\n\n        CellTipManager.sharedInstance().setEnabled(true);\n    }\n\n    protected boolean shouldShowCellTipAt(Point position) {\n        if (rendererRect == null) {\n            return false;\n        }\n\n        return position.x > (rendererRect.x + CheckTreeCellRenderer.getCheckBoxDimension().width);\n    }\n\n    // ---------------------------------------------------------------------------\n\n    // --- Utility methods -------------------------------------------------------\n    private boolean isOverCheckBox(int x, int y) {\n        TreePath path = getPathForLocation(x, y);\n\n        if ((path == null) || (path.getPathCount() == 0) || !(path.getLastPathComponent() instanceof CheckTreeNode)\n                || (x > (getPathBounds(path).x + CheckTreeCellRenderer.getCheckBoxDimension().width))) {\n            return false;\n        }\n\n        return true;\n    }\n\n    private void fireCheckTreeChanged(Collection changedNodes) {\n        if (!changedNodes.isEmpty()) {\n            for (CheckTreeListener  l : checkTreeListeners) {\n                l.checkTreeChanged(changedNodes);\n            }\n        }\n    }\n\n    private void fireNodeToggled(TreePath path, boolean before) {\n        for (CheckTreeListener  l : checkTreeListeners) {\n            l.checkNodeToggled(path, before);\n        }\n    }\n\n    private Collection togglePathState(TreePath path) {\n        return ((CheckTreeNode) path.getLastPathComponent()).toggleState();\n    }\n\n    // ---------------------------------------------------------------------------\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/JCompoundSplitPane.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.JSplitPane;\nimport javax.swing.SwingUtilities;\nimport javax.swing.plaf.basic.BasicSplitPaneDivider;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JCompoundSplitPane extends JExtendedSplitPane {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private class DividerMouseListener extends MouseAdapter {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private double firstResizeWeight = 0;\n        private double secondResizeWeight = 1;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void mouseEntered(MouseEvent e) {\n            configureComponents();\n        }\n\n        public void mousePressed(MouseEvent e) {\n            SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        JSplitPane firstSplit = (JSplitPane) getFirstComponent();\n                        JSplitPane secondSplit = (JSplitPane) getSecondComponent();\n                        firstResizeWeight = firstSplit.getResizeWeight();\n                        secondResizeWeight = secondSplit.getResizeWeight();\n                        firstSplit.setResizeWeight(0);\n                        secondSplit.setResizeWeight(1);\n                    }\n                });\n        }\n\n        public void mouseReleased(MouseEvent e) {\n            SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        ((JSplitPane) getFirstComponent()).setResizeWeight(firstResizeWeight);\n                        ((JSplitPane) getSecondComponent()).setResizeWeight(secondResizeWeight);\n                    }\n                });\n        }\n\n        private void configureComponents() {\n            configureFirstComponent();\n            configureSecondComponent();\n        }\n\n        private void configureFirstComponent() {\n            JSplitPane firstSplit = (JSplitPane) getFirstComponent();\n            int newWidth;\n            int newHeight;\n\n            newWidth = firstSplit.getMinimumSize().width;\n            newHeight = 0;\n\n            if (getFirstComponent(firstSplit).isVisible() && getSecondComponent(firstSplit).isVisible()) {\n                newHeight = getFirstComponent(firstSplit).getSize().height\n                            + getSecondComponent(firstSplit).getMinimumSize().height + firstSplit.getDividerSize();\n            } else if (getFirstComponent(firstSplit).isVisible()) {\n                newHeight = getFirstComponent(firstSplit).getMinimumSize().height;\n            } else {\n                newHeight = getSecondComponent(firstSplit).getMinimumSize().height;\n            }\n\n            firstSplit.setMinimumSize(new Dimension(newWidth, newHeight));\n        }\n\n        private void configureSecondComponent() {\n            JSplitPane secondSplit = (JSplitPane) getSecondComponent();\n            int newWidth = secondSplit.getMinimumSize().width;\n            int newHeight = 0;\n\n            if (getFirstComponent(secondSplit).isVisible() && getSecondComponent(secondSplit).isVisible()) {\n                newHeight = getSecondComponent(secondSplit).getSize().height\n                            + (getFirstComponent(secondSplit).isVisible()\n                               ? (getFirstComponent(secondSplit).getMinimumSize().height + secondSplit.getDividerSize()) : 0);\n            } else if (getFirstComponent(secondSplit).isVisible()) {\n                newHeight = getFirstComponent(secondSplit).getMinimumSize().height;\n            } else {\n                newHeight = getSecondComponent(secondSplit).getMinimumSize().height;\n            }\n\n            secondSplit.setMinimumSize(new Dimension(newWidth, newHeight));\n        }\n    }\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public JCompoundSplitPane() {\n        super();\n        tweakUI();\n    }\n\n    public JCompoundSplitPane(int newOrientation) {\n        super(newOrientation);\n        tweakUI();\n    }\n\n    public JCompoundSplitPane(int newOrientation, boolean newContinuousLayout) {\n        super(newOrientation, newContinuousLayout);\n        tweakUI();\n    }\n\n    public JCompoundSplitPane(int newOrientation, boolean newContinuousLayout, Component newLeftComponent,\n                              Component newRightComponent) {\n        super(newOrientation, newContinuousLayout, newLeftComponent, newRightComponent);\n        tweakUI();\n    }\n\n    public JCompoundSplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent) {\n        super(newOrientation, newLeftComponent, newRightComponent);\n        tweakUI();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    private Component getFirstComponent() {\n        return getFirstComponent(this);\n    }\n\n    private Component getFirstComponent(JSplitPane splitPane) {\n        if (splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {\n            return splitPane.getLeftComponent();\n        } else {\n            return splitPane.getTopComponent();\n        }\n    }\n\n    private Component getSecondComponent() {\n        return getSecondComponent(this);\n    }\n\n    private Component getSecondComponent(JSplitPane splitPane) {\n        if (splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {\n            return splitPane.getRightComponent();\n        } else {\n            return splitPane.getBottomComponent();\n        }\n    }\n\n    private void tweakUI() {\n        if (!(getUI() instanceof BasicSplitPaneUI)) {\n            return;\n        }\n\n        BasicSplitPaneDivider divider = ((BasicSplitPaneUI) getUI()).getDivider();\n\n        if (divider != null) {\n            divider.addMouseListener(new DividerMouseListener());\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/JExtendedComboBox.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.Component;\nimport java.awt.event.ItemEvent;\nimport javax.swing.ComboBoxModel;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.DefaultListCellRenderer;\nimport javax.swing.JComboBox;\nimport javax.swing.JList;\nimport javax.swing.JSeparator;\nimport javax.swing.SwingUtilities;\n\n\n/**\n * JComboBox which supports JSeparator inside its popup menu.\n *\n * @author Jiri Sedlacek\n */\npublic class JExtendedComboBox extends JComboBox {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private static class ExtendedComboListRenderer extends DefaultListCellRenderer {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,\n                                                      boolean cellHasFocus) {\n            if (value instanceof JSeparator) {\n                return (JSeparator) value;\n            } else {\n                return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);\n            }\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private DefaultComboBoxModel model = new DefaultComboBoxModel();\n    private boolean closingWithSeparator = false;\n    private int lastSelectedIndex = 0;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public JExtendedComboBox() {\n        setModel(model);\n        setRenderer(new ExtendedComboListRenderer());\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setModel(ComboBoxModel aModel) {\n        if (!(aModel instanceof DefaultComboBoxModel)) {\n            throw new RuntimeException(\"Only DefaultComboBoxModel is supported for this component\"); //NOI18N\n        }\n\n        model = (DefaultComboBoxModel) aModel;\n        super.setModel(model);\n    }\n\n    public void firePopupMenuWillBecomeInvisible() {\n        if (getSelectedItem() instanceof JSeparator) {\n            closingWithSeparator = true;\n        }\n\n        super.firePopupMenuWillBecomeInvisible();\n    }\n\n    protected void fireItemStateChanged(ItemEvent e) {\n        switch (e.getStateChange()) {\n            case ItemEvent.SELECTED:\n\n                if (e.getItem() instanceof JSeparator) {\n                    SwingUtilities.invokeLater(this::selectNextItem);\n                }\n\n                break;\n            case ItemEvent.DESELECTED:\n\n                if (!(e.getItem() instanceof JSeparator)) {\n                    lastSelectedIndex = model.getIndexOf(e.getItem());\n                }\n\n                break;\n        }\n\n        super.fireItemStateChanged(e);\n    }\n\n    private void selectNextItem() {\n        int currentSelectedIndex = getSelectedIndex();\n\n        if (closingWithSeparator) {\n            setSelectedIndex(lastSelectedIndex);\n            closingWithSeparator = false;\n        } else if (currentSelectedIndex > lastSelectedIndex) {\n            setSelectedIndex(currentSelectedIndex + 1);\n        } else {\n            setSelectedIndex(currentSelectedIndex - 1);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/JExtendedRadioButton.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.Component;\nimport java.awt.Graphics;\nimport javax.swing.Icon;\nimport javax.swing.JRadioButton;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JExtendedRadioButton extends JRadioButton {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class DoubleIcon implements Icon {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private Icon icon1;\n        private Icon icon2;\n        private int icon1VertOffset = 0;\n        private int icon2HorzOffset;\n        private int icon2VertOffset = 0;\n        private int iconHeight;\n        private int iconWidth;\n        private int iconsGap;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public DoubleIcon(Icon icon1, Icon icon2, int iconsGap) {\n            this.icon1 = icon1;\n            this.icon2 = icon2;\n            this.iconsGap = iconsGap;\n\n            initInternals();\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public Icon getIcon1() {\n            return icon1;\n        }\n\n        public Icon getIcon2() {\n            return icon2;\n        }\n\n        public int getIconHeight() {\n            return iconHeight;\n        }\n\n        public int getIconWidth() {\n            return iconWidth;\n        }\n\n        public int getIconsGap() {\n            return iconsGap;\n        }\n\n        public void paintIcon(Component c, Graphics g, int x, int y) {\n            icon1.paintIcon(c, g, x, y + icon1VertOffset);\n            icon2.paintIcon(c, g, x + icon2HorzOffset, y + icon2VertOffset);\n        }\n\n        private void initInternals() {\n            int icon1Width = icon1.getIconWidth();\n            int icon1Height = icon1.getIconHeight();\n            int icon2Height = icon2.getIconHeight();\n\n            iconWidth = icon1Width + icon2.getIconWidth() + iconsGap;\n            iconHeight = Math.max(icon1Height, icon2Height);\n\n            if (icon1Height > icon2Height) {\n                icon2VertOffset = (int) Math.ceil((float) (icon1Height - icon2Height) / (float) 2);\n            } else if (icon1Height < icon2Height) {\n                icon1VertOffset = (int) Math.ceil((float) (icon2Height - icon1Height) / (float) 2);\n            }\n\n            icon2HorzOffset = icon1Width + iconsGap;\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Icon extraIcon;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public JExtendedRadioButton(Icon extraIcon) {\n        super();\n        setExtraIcon(extraIcon);\n    }\n\n    public JExtendedRadioButton(String text) {\n        super(text);\n    }\n\n    public JExtendedRadioButton(String text, Icon extraIcon) {\n        this(text);\n        setExtraIcon(extraIcon);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setExtraIcon(Icon extraIcon) {\n        if (!isSupportedLaF()) {\n            return;\n        }\n\n        this.extraIcon = extraIcon;\n\n        if (extraIcon != null) {\n            createExtraIcon();\n        } else {\n            resetExtraIcon();\n        }\n    }\n\n    public Icon getExtraIcon() {\n        return extraIcon;\n    }\n\n    private static Icon getDefaultIcon() {\n        return UIManager.getIcon(\"RadioButton.icon\"); // NOI18N\n    }\n\n    private static Icon getDisabledIconSafe(JRadioButton radio) {\n        Icon icon = radio.getIcon();\n\n        if (icon == null) {\n            return getDefaultIcon();\n        }\n\n        Icon disabledIcon = radio.getDisabledIcon();\n\n        return (disabledIcon != null) ? disabledIcon : getIconSafe(radio);\n    }\n\n    private static Icon getDisabledSelectedIconSafe(JRadioButton radio) {\n        Icon icon = radio.getIcon();\n\n        if (icon == null) {\n            return getDefaultIcon();\n        }\n\n        Icon disabledSelectedIcon = radio.getDisabledSelectedIcon();\n\n        return (disabledSelectedIcon != null) ? disabledSelectedIcon : getIconSafe(radio);\n    }\n\n    private static Icon getIconSafe(JRadioButton radio) {\n        Icon icon = radio.getIcon();\n\n        return (icon != null) ? icon : getDefaultIcon();\n    }\n\n    private static Icon getPressedIconSafe(JRadioButton radio) {\n        Icon icon = radio.getIcon();\n\n        if (icon == null) {\n            return getDefaultIcon();\n        }\n\n        Icon pressedIcon = radio.getPressedIcon();\n\n        if (pressedIcon == null) {\n            pressedIcon = radio.getSelectedIcon();\n        }\n\n        return (pressedIcon != null) ? pressedIcon : getIconSafe(radio);\n    }\n\n    private static Icon getRolloverIconSafe(JRadioButton radio) {\n        Icon icon = radio.getIcon();\n\n        if (icon == null) {\n            return getDefaultIcon();\n        }\n\n        Icon rolloverIcon = radio.getRolloverIcon();\n\n        return (rolloverIcon != null) ? rolloverIcon : getIconSafe(radio);\n    }\n\n    private static Icon getRolloverSelectedIconSafe(JRadioButton radio) {\n        Icon icon = radio.getIcon();\n\n        if (icon == null) {\n            return getDefaultIcon();\n        }\n\n        Icon rolloverSelectedIcon = radio.getRolloverSelectedIcon();\n\n        if (rolloverSelectedIcon == null) {\n            rolloverSelectedIcon = radio.getSelectedIcon();\n        }\n\n        return (rolloverSelectedIcon != null) ? rolloverSelectedIcon : getIconSafe(radio);\n    }\n\n    private static Icon getSelectedIconSafe(JRadioButton radio) {\n        Icon icon = radio.getIcon();\n\n        if (icon == null) {\n            return getDefaultIcon();\n        }\n\n        Icon selectedIcon = radio.getSelectedIcon();\n\n        return (selectedIcon != null) ? selectedIcon : getIconSafe(radio);\n    }\n\n    private static boolean isSupportedLaF() {\n        return !UIUtils.isGTKLookAndFeel() && !UIUtils.isAquaLookAndFeel();\n    }\n\n    private void createExtraIcon() {\n        JRadioButton reference = new JRadioButton();\n        int iconTextGap = reference.getIconTextGap();\n\n        Icon disabledIcon = getDisabledIconSafe(reference);\n        Icon disabledSelectedIcon = getDisabledSelectedIconSafe(reference);\n        Icon icon = getIconSafe(reference);\n        Icon pressedIcon = getPressedIconSafe(reference);\n        Icon rolloverIcon = getRolloverIconSafe(reference);\n        Icon rolloverSelectedIcon = getRolloverSelectedIconSafe(reference);\n        Icon selectedIcon = getSelectedIconSafe(reference);\n\n        setDisabledIcon((disabledIcon == null) ? extraIcon : new DoubleIcon(disabledIcon, extraIcon, iconTextGap));\n        setDisabledSelectedIcon((disabledSelectedIcon == null) ? extraIcon\n                                                               : new DoubleIcon(disabledSelectedIcon, extraIcon, iconTextGap));\n        setIcon((icon == null) ? extraIcon : new DoubleIcon(icon, extraIcon, iconTextGap));\n        setPressedIcon((pressedIcon == null) ? extraIcon : new DoubleIcon(pressedIcon, extraIcon, iconTextGap));\n        setRolloverIcon((rolloverIcon == null) ? extraIcon : new DoubleIcon(rolloverIcon, extraIcon, iconTextGap));\n        setRolloverSelectedIcon((rolloverSelectedIcon == null) ? extraIcon\n                                                               : new DoubleIcon(rolloverSelectedIcon, extraIcon, iconTextGap));\n        setSelectedIcon((selectedIcon == null) ? extraIcon : new DoubleIcon(selectedIcon, extraIcon, iconTextGap));\n    }\n\n    private void resetExtraIcon() {\n        JRadioButton reference = new JRadioButton();\n\n        setDisabledIcon(reference.getDisabledIcon());\n        setDisabledSelectedIcon(reference.getDisabledSelectedIcon());\n        setIcon(reference.getIcon());\n        setPressedIcon(reference.getPressedIcon());\n        setRolloverIcon(reference.getRolloverIcon());\n        setRolloverSelectedIcon(reference.getRolloverSelectedIcon());\n        setSelectedIcon(reference.getSelectedIcon());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/JExtendedSpinner.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.event.MouseWheelEvent;\nimport java.awt.event.MouseWheelListener;\nimport javax.swing.JSpinner;\nimport javax.swing.JTextField;\nimport javax.swing.SpinnerModel;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * JSpinner with some bugfixes\n *\n * - setModel doesn't break font\n * - setModel doesn't break accessible name and description\n * - can propagate accessible name and description to its editor (JFormattedTextField)\n * - doesn't consume ESC key\n *\n * @author Jiri Sedlacek\n */\npublic class JExtendedSpinner extends JSpinner {\n\n    private static int defaultSpinnerHeight = -1;\n\n    public static int getDefaultSpinnerHeight() {\n        if (defaultSpinnerHeight == -1) {\n            defaultSpinnerHeight = new JTextField().getPreferredSize().height;\n        }\n\n        return defaultSpinnerHeight;\n    }\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public JExtendedSpinner() {\n        super();\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().setFont(UIManager.getFont(\"Label.font\")); // NOI18N\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().addKeyListener(new java.awt.event.KeyAdapter() {\n                public void keyPressed(final java.awt.event.KeyEvent e) {\n                    if (e.getKeyCode() == java.awt.event.KeyEvent.VK_ESCAPE) {\n                        processKeyEvent(e);\n                    }\n                }\n            });\n        configureWheelListener();\n    }\n\n    public JExtendedSpinner(SpinnerModel model) {\n        super(model);\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().setFont(UIManager.getFont(\"Label.font\")); // NOI18N\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().addKeyListener(new java.awt.event.KeyAdapter() {\n                public void keyPressed(final java.awt.event.KeyEvent e) {\n                    if (e.getKeyCode() == java.awt.event.KeyEvent.VK_ESCAPE) {\n                        processKeyEvent(e);\n                    }\n                }\n            });\n        configureWheelListener();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setModel(SpinnerModel model) {\n        Font font = ((JSpinner.DefaultEditor) getEditor()).getTextField().getFont();\n        String accessibleName = ((JSpinner.DefaultEditor) getEditor()).getTextField().getAccessibleContext().getAccessibleName();\n        String accessibleDescription = ((JSpinner.DefaultEditor) getEditor()).getTextField().getAccessibleContext()\n                                        .getAccessibleDescription();\n        super.setModel(model);\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().setFont(font);\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().getAccessibleContext().setAccessibleName(accessibleName);\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().getAccessibleContext()\n         .setAccessibleDescription(accessibleDescription);\n    }\n\n    public void fixAccessibility() {\n        if (getAccessibleContext() != null) {\n            ((JSpinner.DefaultEditor) getEditor()).getTextField().getAccessibleContext()\n             .setAccessibleName(getAccessibleContext().getAccessibleName());\n            ((JSpinner.DefaultEditor) getEditor()).getTextField().getAccessibleContext()\n             .setAccessibleDescription(getAccessibleContext().getAccessibleDescription());\n        }\n    }\n    \n    \n    public Dimension getPreferredSize() {\n        if (UIUtils.isWindowsClassicLookAndFeel()) {\n            return new Dimension(super.getPreferredSize().width, getDefaultSpinnerHeight());\n        } else {\n            return super.getPreferredSize();\n        }\n    }\n\n    public Dimension getMinimumSize() {\n        if (UIUtils.isWindowsClassicLookAndFeel()) {\n            return getPreferredSize();\n        } else {\n            return super.getMinimumSize();\n        }\n    }\n    \n    \n    private void configureWheelListener() {\n        addMouseWheelListener(new MouseWheelListener() {\n            public void mouseWheelMoved(MouseWheelEvent e) {\n                if (e.getScrollType() != MouseWheelEvent.WHEEL_UNIT_SCROLL) return;\n                Object newValue = (e.getWheelRotation() < 0 ?\n                                   JExtendedSpinner.this.getNextValue() :\n                                   JExtendedSpinner.this.getPreviousValue());\n                if (newValue != null) JExtendedSpinner.this.setValue(newValue);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/JExtendedSplitPane.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.Component;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ComponentAdapter;\nimport java.awt.event.ComponentEvent;\nimport java.awt.event.ComponentListener;\nimport javax.swing.JSplitPane;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JExtendedSplitPane extends JSplitPane {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private class SplitPaneActionListener implements ActionListener {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void actionPerformed(ActionEvent e) {\n            switch (e.getID()) {\n                case JTitledPanel.STATE_CLOSED:\n\n                    //System.err.println(\">>> STATE_CLOSED\");\n                    break;\n                case JTitledPanel.STATE_RESTORED:\n                    setDividerLocation(getLastDividerLocation());\n\n                    break;\n                case JTitledPanel.STATE_MAXIMIZED:\n\n                    //System.err.println(\">>> STATE_MAXIMIZED\");\n                    break;\n                case JTitledPanel.STATE_MINIMIZED:\n\n                    if (e.getSource() == getFirstComponent()) {\n                        setDividerLocation(getFirstComponent().getPreferredSize().height);\n                    } else {\n                        setDividerLocation(getSize().height - dividerSize - getSecondComponent().getPreferredSize().height);\n                    }\n\n                    break;\n            }\n        }\n    }\n\n    private class SplitPaneComponentListener extends ComponentAdapter {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void componentHidden(ComponentEvent e) {\n            computeDividerLocationWhenHidden(e.getComponent());\n\n            if ((dividerLocation == 0) || (dividerLocation == 1)) {\n                dividerLocation = 0.5;\n            }\n\n            updateVisibility();\n        }\n\n        public void componentShown(ComponentEvent e) {\n            updateVisibility();\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ActionListener splitPaneActionListener = new SplitPaneActionListener();\n    private ComponentListener splitPaneComponentListener = new SplitPaneComponentListener();\n    private double dividerLocation;\n    private int dividerSize;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public JExtendedSplitPane() {\n        super();\n    }\n\n    public JExtendedSplitPane(int newOrientation) {\n        super(newOrientation);\n    }\n\n    public JExtendedSplitPane(int newOrientation, boolean newContinuousLayout) {\n        super(newOrientation, newContinuousLayout);\n    }\n\n    public JExtendedSplitPane(int newOrientation, boolean newContinuousLayout, Component newLeftComponent,\n                              Component newRightComponent) {\n        super(newOrientation, newContinuousLayout, newLeftComponent, newRightComponent);\n        registerListeners(newLeftComponent);\n        registerListeners(newRightComponent);\n        updateVisibility();\n\n        if (!newLeftComponent.isVisible()) {\n            computeDividerLocationWhenInitiallyHidden(newLeftComponent);\n        }\n\n        if (!newRightComponent.isVisible()) {\n            computeDividerLocationWhenInitiallyHidden(newRightComponent);\n        }\n    }\n\n    public JExtendedSplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent) {\n        super(newOrientation, newLeftComponent, newRightComponent);\n        registerListeners(newLeftComponent);\n        registerListeners(newRightComponent);\n        updateVisibility();\n\n        if (!newLeftComponent.isVisible()) {\n            computeDividerLocationWhenInitiallyHidden(newLeftComponent);\n        }\n\n        if (!newRightComponent.isVisible()) {\n            computeDividerLocationWhenInitiallyHidden(newRightComponent);\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setBottomComponent(Component comp) {\n        setRightComponent(comp);\n    }\n\n    public void setDividerSize(int newSize) {\n        super.setDividerSize(newSize);\n        dividerSize = newSize;\n    }\n\n    public void setLeftComponent(Component comp) { // Actually setTopComponent is implemented as setLeftComponent\n\n        if (getLeftComponent() != null) {\n            unregisterListeners(getLeftComponent());\n        }\n\n        super.setLeftComponent(comp);\n\n        if (getLeftComponent() != null) {\n            registerListeners(getLeftComponent());\n        }\n\n        updateVisibility();\n    }\n\n    public void setRightComponent(Component comp) { // Actually setBottomComponent is implemented as setRightComponent\n\n        if (getRightComponent() != null) {\n            unregisterListeners(getRightComponent());\n        }\n\n        super.setRightComponent(comp);\n\n        if (getRightComponent() != null) {\n            registerListeners(getRightComponent());\n        }\n\n        updateVisibility();\n    }\n\n    public void setTopComponent(Component comp) {\n        setLeftComponent(comp);\n    }\n\n    private Component getDivider() {\n        if (getUI() == null) {\n            return null;\n        }\n\n        return ((BasicSplitPaneUI) getUI()).getDivider();\n    }\n\n    private Component getFirstComponent() {\n        if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {\n            return getLeftComponent();\n        } else {\n            return getTopComponent();\n        }\n    }\n\n    private Component getSecondComponent() {\n        if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {\n            return getRightComponent();\n        } else {\n            return getBottomComponent();\n        }\n    }\n\n    private void computeDividerLocationWhenHidden(Component hiddenComponent) {\n        if (getTopComponent().isVisible() || getBottomComponent().isVisible()) {\n            if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {\n                if (hiddenComponent == getFirstComponent()) {\n                    dividerLocation = hiddenComponent.getSize().width / (getSize().getWidth() - dividerSize);\n                } else {\n                    dividerLocation = (getSize().getWidth() - dividerSize - hiddenComponent.getSize().width) / (getSize()\n                                                                                                                    .getWidth()\n                                                                                                               - dividerSize);\n                }\n            } else {\n                if (hiddenComponent == getFirstComponent()) {\n                    dividerLocation = hiddenComponent.getSize().height / (getSize().getHeight() - dividerSize);\n                } else {\n                    dividerLocation = (getSize().getHeight() - dividerSize - hiddenComponent.getSize().height) / (getSize()\n                                                                                                                      .getHeight()\n                                                                                                                 - dividerSize);\n                }\n            }\n            dividerLocation = Math.max(0, dividerLocation);\n            dividerLocation = Math.min(1, dividerLocation);\n        }\n    }\n\n    private void computeDividerLocationWhenInitiallyHidden(Component hiddenComponent) {\n        if (getTopComponent().isVisible() || getBottomComponent().isVisible()) {\n            if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {\n                if (hiddenComponent == getFirstComponent()) {\n                    dividerLocation = hiddenComponent.getPreferredSize().width / (getPreferredSize().getWidth() - dividerSize);\n                } else {\n                    dividerLocation = (getPreferredSize().getWidth() - dividerSize - hiddenComponent.getPreferredSize().width) / (getPreferredSize()\n                                                                                                                                      .getWidth()\n                                                                                                                                 - dividerSize);\n                }\n            } else {\n                if (hiddenComponent == getFirstComponent()) {\n                    dividerLocation = hiddenComponent.getPreferredSize().height / (getPreferredSize().getHeight() - dividerSize);\n                } else {\n                    dividerLocation = (getPreferredSize().getHeight() - dividerSize - hiddenComponent.getPreferredSize().height) / (getPreferredSize()\n                                                                                                                                        .getHeight()\n                                                                                                                                   - dividerSize);\n                }\n            }\n            dividerLocation = Math.max(0, dividerLocation);\n            dividerLocation = Math.min(1, dividerLocation);\n        }\n    }\n\n    private void registerListeners(Component component) {\n        if (splitPaneComponentListener != null) {\n            component.addComponentListener(splitPaneComponentListener);\n        }\n\n        if (splitPaneActionListener != null) {\n            if (component instanceof JTitledPanel) {\n                ((JTitledPanel) component).addActionListener(splitPaneActionListener);\n            }\n\n            //else if (component instanceof JExtendedSplitPane) ((JTitledPanel)component).addActionListener(splitPaneActionListener);\n        }\n    }\n\n    private void unregisterListeners(Component component) {\n        if (splitPaneComponentListener != null) {\n            component.removeComponentListener(splitPaneComponentListener);\n        }\n\n        if (splitPaneActionListener != null) {\n            if (component instanceof JTitledPanel) {\n                ((JTitledPanel) component).removeActionListener(splitPaneActionListener);\n            }\n\n            //else if (component instanceof JExtendedSplitPane) ((JTitledPanel)component).removeActionListener(splitPaneActionListener);\n        }\n    }\n\n    private void updateVisibility() {\n        Component firstComponent = getFirstComponent();\n        Component secondComponent = getSecondComponent();\n        Component divider = getDivider();\n\n        if ((firstComponent == null) || (secondComponent == null) || (divider == null)) {\n            return;\n        }\n\n        if (firstComponent.isVisible() && secondComponent.isVisible()) {\n            if (!divider.isVisible()) {\n                super.setDividerSize(dividerSize);\n                divider.setVisible(true);\n                setDividerLocation(dividerLocation);\n            }\n\n            if (!isVisible()) {\n                setVisible(true);\n            }\n        } else if (!firstComponent.isVisible() && !secondComponent.isVisible()) {\n            if (isVisible()) {\n                setVisible(false);\n            }\n        } else {\n            if (divider.isVisible()) {\n                super.setDividerSize(0);\n                divider.setVisible(false);\n                setDividerLocation(0);\n            }\n\n            if (!isVisible()) {\n                setVisible(true);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/JExtendedTable.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.util.Arrays;\nimport java.util.List;\nimport javax.swing.*;\nimport javax.swing.table.*;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.table.*;\n\n\n/**\n * This class implements JTable with extended CellTip support.\n * Added support for handling Home &amp; End keys.\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic class JExtendedTable extends JTable implements CellTipAware, MouseListener, MouseMotionListener, MouseWheelListener {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected JToolTip cellTip;\n    protected Rectangle rendererRect;\n    protected int lastColumn = -1;\n    protected int lastRow = -1;\n    private String internalFindString;\n\n    //------------------------------------\n    // Find functionality stuff\n    private String userFindString;\n    private int userFindColumn;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public JExtendedTable(TableModel model) {\n        super(model);\n\n        setBackground(UIUtils.getProfilerResultsBackground());\n\n        cellTip = createCellTip();\n        cellTip.setBorder(BorderFactory.createLineBorder(getGridColor()));\n        cellTip.setLayout(new BorderLayout());\n\n        initListeners();\n\n        CellTipManager.sharedInstance().registerComponent(this);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public JToolTip getCellTip() {\n        return cellTip;\n    }\n\n    public Point getCellTipLocation() {\n        if (rendererRect == null) {\n            return null;\n        }\n\n        return new Point(rendererRect.getLocation().x - 1, rendererRect.getLocation().y - 1);\n    }\n\n    public int getFindColumn() {\n        return userFindColumn;\n    }\n\n    public boolean isFindColumnValid() {\n        return ((userFindColumn >= 0) && (userFindColumn < getColumnCount()));\n    }\n\n    public void setFindParameters(String findString, int findColumn) {\n        userFindString = findString;\n        userFindColumn = findColumn;\n        internalFindString = getInternalFindString(userFindString);\n    }\n\n    public String getFindString() {\n        return userFindString;\n    }\n\n    public boolean isFindStringDefined() {\n        return ((userFindString != null) && (!userFindString.trim().isEmpty()));\n    }\n\n    public void setGridColor(Color gridColor) {\n        super.setGridColor(gridColor);\n\n        if ((gridColor == null) || (cellTip == null)) {\n            return;\n        }\n\n        cellTip.setBorder(BorderFactory.createLineBorder(gridColor));\n    }\n\n    public boolean canFindBePerformed() {\n        return (getRowCount() > 0) && isFindColumnValid() && isFindStringDefined();\n    }\n\n    public void ensureRowVisible(int row) {\n        scrollRectToVisible(getCellRect(row, 0, true));\n    }\n\n    public boolean findFirst() {\n        if (!canFindBePerformed()) {\n            return false;\n        }\n\n        if (matchesFindCriterion(0)) {\n            return selectFoundNode(0);\n        } else {\n            return doFindNext(0);\n        }\n    }\n\n    public boolean findNext() {\n        if (!canFindBePerformed()) {\n            return false;\n        }\n\n        return doFindNext(getSearchRoot());\n    }\n\n    public boolean findPrevious() {\n        if (!canFindBePerformed()) {\n            return false;\n        }\n\n        return doFindPrevious(getSearchRoot());\n    }\n\n    public void mouseClicked(MouseEvent e) {\n    }\n\n    public void mouseDragged(MouseEvent event) {\n    }\n\n    public void mouseEntered(MouseEvent e) {\n        CellTipManager.sharedInstance().setEnabled(false);\n    }\n\n    public void mouseExited(MouseEvent e) {\n        // Return if mouseExit occured because of showing heavyweight celltip\n        if (contains(e.getPoint()) && cellTip.isShowing()) {\n            return;\n        }\n\n        CellTipManager.sharedInstance().setEnabled(false);\n        lastRow = -1;\n        lastColumn = -1;\n    }\n\n    public void mouseMoved(MouseEvent event) {\n        // Identify table row and column at cursor\n        int row = rowAtPoint(event.getPoint());\n        int column = columnAtPoint(event.getPoint());\n\n        // Return if table cell is the same as in previous event\n        if ((row == lastRow) && (column == lastColumn)) {\n            return;\n        }\n\n        lastRow = row;\n        lastColumn = column;\n\n        if ((row < 0) || (column < 0)) {\n            CellTipManager.sharedInstance().setEnabled(false);\n\n            return;\n        }\n\n        TableCellRenderer tableCellRenderer = getCellRenderer(row, column);\n\n        if (!(tableCellRenderer instanceof TableCellRendererPersistent)) {\n            return;\n        }\n\n        Component cellRenderer = ((TableCellRendererPersistent) tableCellRenderer).getTableCellRendererComponentPersistent(this,\n                                                                                                                           getValueAt(row,\n                                                                                                                                      column),\n                                                                                                                           false,\n                                                                                                                           false,\n                                                                                                                           row,\n                                                                                                                           column);\n        Rectangle cellRect = getCellRect(row, column, false);\n\n        // Return if celltip is not supported for the cell\n        if (cellRenderer == null) {\n            CellTipManager.sharedInstance().setEnabled(false);\n\n            return;\n        }\n\n        int horizontalAlignment = ((EnhancedTableCellRenderer) cellRenderer).getHorizontalAlignment();\n\n        if ((horizontalAlignment == SwingConstants.TRAILING) || (horizontalAlignment == SwingConstants.RIGHT)) {\n            rendererRect = new Rectangle((cellRect.x + cellRect.width) - cellRenderer.getPreferredSize().width, cellRect.y,\n                                         cellRenderer.getPreferredSize().width, cellRenderer.getPreferredSize().height);\n        } else {\n            rendererRect = new Rectangle(cellRect.x, cellRect.y, cellRenderer.getPreferredSize().width,\n                                         cellRenderer.getPreferredSize().height);\n        }\n\n        // Return if cell contents is fully visible\n        if ((rendererRect.x >= cellRect.x) && ((rendererRect.x + rendererRect.width) <= (cellRect.x + cellRect.width))) {\n            CellTipManager.sharedInstance().setEnabled(false);\n\n            return;\n        }\n\n        while (cellTip.getComponentCount() > 0) {\n            cellTip.remove(0);\n        }\n\n        cellTip.add(cellRenderer, BorderLayout.CENTER);\n        cellTip.setPreferredSize(new Dimension(rendererRect.width + 2, getRowHeight(row) + 2));\n\n        CellTipManager.sharedInstance().setEnabled(true);\n    }\n\n    public void mousePressed(MouseEvent e) {\n    }\n\n    public void mouseReleased(MouseEvent e) {\n    }\n\n    public void mouseWheelMoved(MouseWheelEvent e) {\n        mouseMoved(e);\n        CellTipManager.sharedInstance().setEnabled(false);\n    }\n    \n    public void processMouseEvent(final MouseEvent e) {\n        if (e instanceof MouseWheelEvent) {\n            Component target = JExtendedTable.this.getParent();\n            if (!(target instanceof JViewport))\n                target = JExtendedTable.this;\n            MouseEvent mwe = SwingUtilities.convertMouseEvent(\n                    JExtendedTable.this, e, target);\n            target.dispatchEvent(mwe);\n        } else {\n            super.processMouseEvent(e);\n        }\n    }\n\n    public void selectRowByContents(String rowString, int columnIndex, boolean setVisible) {\n        for (int i = 0; i < getRowCount(); i++) {\n            if (getValueAt(i, columnIndex).toString().equals(rowString)) {\n                getSelectionModel().setSelectionInterval(i, i);\n\n                if (setVisible) {\n                    ensureRowVisible(i);\n                }\n\n                return;\n            }\n        }\n\n        getSelectionModel().clearSelection();\n    }\n\n    public void selectRowByInstance(Object instance, int columnIndex, boolean setVisible) {\n        for (int i = 0; i < getRowCount(); i++) {\n            if (getValueAt(i, columnIndex) == instance) {\n                getSelectionModel().setSelectionInterval(i, i);\n\n                if (setVisible) {\n                    ensureRowVisible(i);\n                }\n\n                return;\n            }\n        }\n\n        getSelectionModel().clearSelection();\n    }\n\n    public void selectRowsByInstances(Object[] instances, int columnIndex, boolean setVisible) {\n        List instancesList = Arrays.asList(instances);\n\n        getSelectionModel().clearSelection();\n\n        for (int i = 0; i < getRowCount(); i++) {\n            if (instancesList.contains(getValueAt(i, columnIndex))) {\n                getSelectionModel().addSelectionInterval(i, i);\n            }\n        }\n\n        if (setVisible && (getSelectedRow() != -1)) {\n            ensureRowVisible(getSelectedRow());\n        }\n    }\n\n    protected JToolTip createCellTip() {\n        return new JToolTip();\n    }\n\n    private boolean isAnyRowSelected() {\n        return getSelectedRow() != -1;\n    }\n\n    private String getInternalFindString(String findString) {\n        if (findString == null) {\n            return null;\n        }\n\n        return findString.toLowerCase();\n    }\n\n    private int getSearchRoot() {\n        if (!isAnyRowSelected()) {\n            return 0;\n        } else {\n            return getSelectedRow();\n        }\n    }\n\n    private boolean doFindNext(int lastFoundRow) {\n        for (int row = lastFoundRow + 1; row < getRowCount(); row++) {\n            if (matchesFindCriterion(row)) {\n                return selectFoundNode(row);\n            }\n        }\n\n        return false;\n    }\n\n    private boolean doFindPrevious(int lastFoundRow) {\n        for (int row = lastFoundRow - 1; row >= 0; row--) {\n            if (matchesFindCriterion(row)) {\n                return selectFoundNode(row);\n            }\n        }\n\n        return false;\n    }\n\n    private void initListeners() {\n        addMouseListener(this);\n        addMouseMotionListener(this);\n\n        // Required for correct updating of focused/unfocused selection\n        addFocusListener(new FocusListener() {\n                public void focusGained(FocusEvent e) {\n                    if (getSelectedRows().length > 0) {\n                        repaint();\n                    }\n                }\n\n                public void focusLost(FocusEvent e) {\n                    if (getSelectedRows().length > 0) {\n                        repaint();\n                    }\n                }\n            });\n\n        addKeyListener(new KeyAdapter() {\n                public void keyPressed(KeyEvent e) {\n                    int rowCount = getRowCount();\n\n                    switch (e.getKeyCode()) {\n                        case KeyEvent.VK_HOME:\n\n                            if (rowCount > 0) {\n                                setRowSelectionInterval(0, 0);\n                            }\n\n                            break;\n                        case KeyEvent.VK_END:\n\n                            if (rowCount > 0) {\n                                setRowSelectionInterval(rowCount - 1, rowCount - 1);\n                            }\n\n                            break;\n                    }\n                }\n            });\n    }\n\n    private boolean matchesFindCriterion(int row) {\n        return getValueAt(row, userFindColumn).toString().toLowerCase().contains(internalFindString);\n    }\n\n    private boolean selectFoundNode(int row) {\n        getSelectionModel().setSelectionInterval(row, row);\n        requestFocusInWindow();\n\n        Rectangle rect = getCellRect(row, userFindColumn, true);\n\n        if (rect != null) {\n            scrollRectToVisible(rect);\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    //------------------------------------\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/JExtendedTree.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport java.awt.event.MouseMotionListener;\nimport java.awt.event.MouseWheelEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.JToolTip;\nimport javax.swing.JTree;\nimport javax.swing.JViewport;\nimport javax.swing.SwingUtilities;\nimport javax.swing.tree.TreeCellRenderer;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.tree.TreeCellRendererPersistent;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JExtendedTree extends JTree implements CellTipAware {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private class PrivateComponentListener implements MouseListener, MouseMotionListener {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void mouseClicked(MouseEvent e) {\n        }\n\n        public void mouseDragged(MouseEvent e) {\n        }\n\n        public void mouseEntered(MouseEvent e) {\n            // --- CellTip support ------------------\n            CellTipManager.sharedInstance().setEnabled(false);\n        }\n\n        public void mouseExited(MouseEvent e) {\n            // --- CellTip support ------------------\n            // Return if mouseExit occured because of showing heavyweight celltip\n            if (contains(e.getPoint()) && cellTip.isShowing()) {\n                return;\n            }\n\n            CellTipManager.sharedInstance().setEnabled(false);\n            lastTreePath = null;\n        }\n\n        public void mouseMoved(MouseEvent e) {\n            // --- CellTip support ------------------\n            processCellTipMouseMove(e);\n        }\n\n        public void mousePressed(MouseEvent e) {\n        }\n\n        public void mouseReleased(MouseEvent e) {\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected JToolTip cellTip;\n    protected Rectangle rendererRect;\n    protected TreePath lastTreePath = null;\n    private PrivateComponentListener componentListener = new PrivateComponentListener();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of JExtendedTree */\n    public JExtendedTree() {\n        addMouseListener(componentListener);\n        addMouseMotionListener(componentListener);\n\n        setRowHeight(UIUtils.getDefaultRowHeight()); // celltips require to have row height initialized!\n\n        // --- CellTip support ------------------\n        cellTip = createCellTip();\n        cellTip.setBackground(getBackground());\n        cellTip.setBorder(BorderFactory.createLineBorder(UIConstants.TABLE_VERTICAL_GRID_COLOR));\n        cellTip.setLayout(new BorderLayout());\n\n        CellTipManager.sharedInstance().registerComponent(this);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public JToolTip getCellTip() {\n        return cellTip;\n    }\n\n    public Point getCellTipLocation() {\n        if (rendererRect == null) {\n            return null;\n        }\n\n        return new Point(rendererRect.getLocation().x - 1, rendererRect.getLocation().y - 1);\n    }\n\n    public void processMouseEvent(MouseEvent e) {\n        if (e instanceof MouseWheelEvent) {\n            Component target = JExtendedTree.this.getParent();\n            if (!(target instanceof JViewport))\n                target = JExtendedTree.this;\n            MouseEvent mwe = SwingUtilities.convertMouseEvent(\n                    JExtendedTree.this, e, target);\n            target.dispatchEvent(mwe);\n        } else {\n            super.processMouseEvent(e);\n        }\n    }\n\n    protected JToolTip createCellTip() {\n        return new JToolTip();\n    }\n\n    protected void processCellTipMouseMove(MouseEvent e) {\n        // Identify treetable row and column at cursor\n        TreePath currentTreePath = getPathForLocation(e.getX(), e.getY());\n\n        // Return if treetable cell is the same as in previous event\n        if (currentTreePath == lastTreePath) {\n            return;\n        }\n\n        lastTreePath = currentTreePath;\n\n        // Return if cursor isn't at any cell\n        if (lastTreePath == null) {\n            CellTipManager.sharedInstance().setEnabled(false);\n\n            return;\n        }\n\n        Component cellRenderer;\n        Component cellRendererPersistent;\n        int row = getRowForPath(lastTreePath);\n\n        TreeCellRenderer treeCellRenderer = getCellRenderer();\n\n        if (!(treeCellRenderer instanceof TreeCellRendererPersistent)) {\n            return;\n        }\n\n        cellRenderer = treeCellRenderer.getTreeCellRendererComponent(JExtendedTree.this, lastTreePath.getLastPathComponent(),\n                                                                     false, isExpanded(row),\n                                                                     getModel().isLeaf(lastTreePath.getLastPathComponent()), row,\n                                                                     false);\n        cellRendererPersistent = ((TreeCellRendererPersistent) treeCellRenderer).getTreeCellRendererComponentPersistent(JExtendedTree.this,\n                                                                                                                        lastTreePath\n                                                                                                                        .getLastPathComponent(),\n                                                                                                                        false,\n                                                                                                                        isExpanded(row),\n                                                                                                                        getModel()\n                                                                                                                            .isLeaf(lastTreePath\n                                                                                                                                    .getLastPathComponent()),\n                                                                                                                        row, false);\n\n        // Return if celltip is not supported for the cell\n        if (cellRenderer == null) {\n            CellTipManager.sharedInstance().setEnabled(false);\n\n            return;\n        }\n\n        Point cellStart = getPathBounds(lastTreePath).getLocation();\n        rendererRect = new Rectangle(cellStart.x, cellStart.y, cellRenderer.getPreferredSize().width,\n                                     cellRenderer.getPreferredSize().height + 2);\n\n        if (!rendererRect.contains(e.getPoint())) {\n            CellTipManager.sharedInstance().setEnabled(false);\n\n            return;\n        }\n\n        // Return if cell contents is fully visible\n        Rectangle visibleRect = getVisibleRect();\n\n        if ((rendererRect.x >= visibleRect.x) && ((rendererRect.x + rendererRect.width) <= (visibleRect.x + visibleRect.width))) {\n            CellTipManager.sharedInstance().setEnabled(false);\n\n            return;\n        }\n\n        while (cellTip.getComponentCount() > 0) {\n            cellTip.remove(0);\n        }\n\n        cellTip.add(cellRendererPersistent, BorderLayout.CENTER);\n        cellTip.setPreferredSize(new Dimension(cellRendererPersistent.getPreferredSize().width + 2, getRowHeight() + 2));\n\n        CellTipManager.sharedInstance().setEnabled(true);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/JTitledPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.LayoutManager;\nimport java.awt.MenuComponent;\nimport java.awt.PopupMenu;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ComponentAdapter;\nimport java.awt.event.ComponentEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport java.awt.image.FilteredImageSource;\nimport java.awt.image.ImageProducer;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.Collection;\nimport java.util.concurrent.CopyOnWriteArraySet;\nimport javax.swing.AbstractButton;\nimport javax.swing.BorderFactory;\nimport javax.swing.GrayFilter;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.border.BevelBorder;\nimport javax.swing.border.Border;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JTitledPanel extends JPanel {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private static class ThinBevelBorder extends BevelBorder {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ThinBevelBorder(int bevelType, Color highlight, Color shadow) {\n            super(bevelType, highlight.brighter(), highlight, shadow, shadow.brighter());\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public Insets getBorderInsets(Component c) {\n            return new Insets(1, 1, 1, 1);\n        }\n\n        public Insets getBorderInsets(Component c, Insets insets) {\n            insets.left = insets.top = insets.right = insets.bottom = 1;\n\n            return insets;\n        }\n\n        protected void paintLoweredBevel(Component c, Graphics g, int x, int y, int width, int height) {\n            if (!c.isEnabled()) {\n                return;\n            }\n\n            Color oldColor = g.getColor();\n            int h = height;\n            int w = width;\n\n            g.translate(x, y);\n\n            g.setColor(getShadowOuterColor(c));\n            g.drawLine(0, 0, 0, h - 1);\n            g.drawLine(1, 0, w - 1, 0);\n\n            g.setColor(getHighlightInnerColor(c));\n            g.drawLine(1, h - 1, w - 1, h - 1);\n            g.drawLine(w - 1, 1, w - 1, h - 2);\n\n            g.translate(-x, -y);\n            g.setColor(oldColor);\n        }\n\n        protected void paintRaisedBevel(Component c, Graphics g, int x, int y, int width, int height) {\n            if (!c.isEnabled()) {\n                return;\n            }\n\n            Color oldColor = g.getColor();\n            int h = height;\n            int w = width;\n\n            g.translate(x, y);\n\n            g.setColor(getHighlightInnerColor(c));\n            g.drawLine(0, 0, 0, h - 1);\n            g.drawLine(1, 0, w - 1, 0);\n\n            g.setColor(getShadowOuterColor(c));\n            g.drawLine(0, h - 1, w - 1, h - 1);\n            g.drawLine(w - 1, 0, w - 1, h - 2);\n\n            g.translate(-x, -y);\n            g.setColor(oldColor);\n        }\n    }\n\n    private class DoubleClickListener extends MouseAdapter {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void mouseClicked(MouseEvent e) {\n            if (SwingUtilities.isLeftMouseButton(e) && (e.getClickCount() == 2)) {\n                if (isMaximized()) {\n                    restore();\n                } else {\n                    maximize();\n                }\n            }\n        }\n    }\n\n    private static class ImageIconButton extends JButton implements MouseListener {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private Border emptyBorder = BorderFactory.createEmptyBorder(1, 1, 1, 1);\n        private Border loweredBorder = new ThinBevelBorder(BevelBorder.LOWERED, Color.WHITE, Color.GRAY);\n        private Border raisedBorder = new ThinBevelBorder(BevelBorder.RAISED, Color.WHITE, Color.GRAY);\n        private boolean focused = false;\n        private boolean pressed = false;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ImageIconButton(ImageIcon icon) {\n            super();\n\n            GrayFilter enabledFilter = new GrayFilter(true, 35);\n            ImageProducer prod = new FilteredImageSource(icon.getImage().getSource(), enabledFilter);\n            Icon grayIcon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(prod));\n            GrayFilter disabledFilter = new GrayFilter(true, 60);\n            prod = new FilteredImageSource(icon.getImage().getSource(), disabledFilter);\n\n            Icon disabledIcon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(prod));\n\n            setIcon(grayIcon);\n            setRolloverIcon(icon);\n            setPressedIcon(icon);\n            setDisabledIcon(disabledIcon);\n            setIconTextGap(0);\n            setBorder(emptyBorder);\n            setFocusable(false);\n            setContentAreaFilled(false);\n\n            setPreferredSize(new Dimension(icon.getIconWidth() + 8, icon.getIconHeight() + 8));\n\n            addMouseListener(this);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void mouseClicked(MouseEvent e) {\n        }\n\n        public void mouseEntered(MouseEvent e) {\n            focused = true;\n\n            if (pressed) {\n                setBorder(loweredBorder);\n            } else {\n                setBorder(raisedBorder);\n            }\n        }\n\n        public void mouseExited(MouseEvent e) {\n            focused = false;\n            setBorder(emptyBorder);\n        }\n\n        public void mousePressed(MouseEvent e) {\n            pressed = true;\n            setBorder(loweredBorder);\n        }\n\n        public void mouseReleased(MouseEvent e) {\n            pressed = false;\n\n            if (focused) {\n                setBorder(raisedBorder);\n            } else {\n                setBorder(emptyBorder);\n            }\n        }\n    }\n\n    // --- Presenter -------------------------------------------------------------\n    private class Presenter extends JToggleButton {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        Presenter() {\n            super();\n\n            if (JTitledPanel.this.getIcon() == null) {\n                setText(JTitledPanel.this.getTitle());\n                setToolTipText(JTitledPanel.this.getTitle());\n            } else {\n                setIcon(JTitledPanel.this.getIcon());\n                setToolTipText(JTitledPanel.this.getTitle());\n            }\n\n            setSelected(JTitledPanel.this.isVisible());\n            addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        JTitledPanel.this.setVisible(isSelected());\n                    }\n                });\n            JTitledPanel.this.addComponentListener(new ComponentAdapter() {\n                    public void componentShown(ComponentEvent e) {\n                        setSelected(true);\n                    }\n\n                    public void componentHidden(ComponentEvent e) {\n                        setSelected(false);\n                    }\n                });\n            addPropertyChangeListener(new PropertyChangeListener() {\n                    public void propertyChange(PropertyChangeEvent evt) {\n                        if (\"enabled\".equals(evt.getPropertyName())) {\n                            JTitledPanel.this.setButtonsEnabled(isEnabled()); // NOI18N\n                        }\n                    }\n                });\n        }\n        \n        public Dimension getPreferredSize() {\n            Dimension d = super.getPreferredSize();\n            d.width += 20;\n            return d;\n        }\n        \n        public Dimension getMinimumSize() {\n            return getPreferredSize();\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final ImageIcon closePanelIcon = Icons.getImageIcon(GeneralIcons.CLOSE_PANEL);\n    private static final ImageIcon maximizePanelIcon = Icons.getImageIcon(GeneralIcons.MAXIMIZE_PANEL);\n    private static final ImageIcon restorePanelIcon = Icons.getImageIcon(GeneralIcons.RESTORE_PANEL);\n    private static final ImageIcon minimizePanelIcon = Icons.getImageIcon(GeneralIcons.MINIMIZE_PANEL);\n    public static final int STATE_CLOSED = 1000;\n    public static final int STATE_RESTORED = 1001;\n    public static final int STATE_MAXIMIZED = 1002;\n    public static final int STATE_MINIMIZED = 1003;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private AbstractButton presenter;\n    private Icon icon;\n    private JButton closePanelButton;\n    private JButton maximizePanelButton;\n    private JButton minimizePanelButton;\n    private JButton restorePanelButton;\n    private JPanel contentPanel;\n    private JPanel titlePanel;\n    private String title;\n    private Collection<ActionListener> actionListeners = new CopyOnWriteArraySet<>();\n    private boolean showButtons;\n    private int state;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public JTitledPanel(String title) {\n        this(title, null);\n    }\n\n    public JTitledPanel(String title, Icon icon) {\n        this(title, icon, false);\n    }\n\n    public JTitledPanel(String title, Icon icon, boolean showButtons) {\n        super();\n        this.title = title;\n        this.icon = icon;\n        this.showButtons = showButtons;\n        initComponents();\n        restore();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setButtonsEnabled(boolean enabled) {\n        closePanelButton.setEnabled(enabled);\n        maximizePanelButton.setEnabled(enabled);\n        restorePanelButton.setEnabled(enabled);\n        minimizePanelButton.setEnabled(enabled);\n    }\n\n    public boolean isClosed() {\n        return getState() == STATE_CLOSED;\n    }\n\n    public JPanel getContentPanel() {\n        if (contentPanel == null) {\n            contentPanel = new JPanel();\n        }\n\n        return contentPanel;\n    }\n\n    public Icon getIcon() {\n        return icon;\n    }\n\n    public void setLayout(LayoutManager mgr) {\n        getContentPanel().setLayout(mgr);\n    }\n\n    public LayoutManager getLayout() {\n        return getContentPanel().getLayout();\n    }\n\n    public boolean isMaximized() {\n        return getState() == STATE_MAXIMIZED;\n    }\n\n    public boolean isMinimized() {\n        return getState() == STATE_MINIMIZED;\n    }\n\n    public Dimension getMinimumSize() {\n        return new Dimension(0, titlePanel.getPreferredSize().height);\n    }\n\n    public AbstractButton getPresenter() {\n        if (presenter == null) {\n            presenter = new Presenter();\n        }\n\n        return presenter;\n    }\n\n    public boolean isRestored() {\n        return getState() == STATE_RESTORED;\n    }\n\n    public int getState() {\n        if (!isVisible()) {\n            state = STATE_CLOSED;\n        }\n\n        if (isVisible() && (state == STATE_CLOSED)) {\n            state = STATE_RESTORED;\n        }\n\n        return state;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    public Component add(Component comp) {\n        return getContentPanel().add(comp);\n    }\n\n    public Component add(Component comp, int index) {\n        return getContentPanel().add(comp, index);\n    }\n\n    public void add(Component comp, Object constraints) {\n        getContentPanel().add(comp, constraints);\n    }\n\n    public void add(Component comp, Object constraints, int index) {\n        getContentPanel().add(comp, constraints, index);\n    }\n\n    public Component add(String name, Component comp) {\n        return getContentPanel().add(name, comp);\n    }\n\n    public void add(PopupMenu popup) {\n        getContentPanel().add(popup);\n    }\n\n    public void addActionListener(ActionListener listener) {\n        actionListeners.add(listener);\n    }\n\n    public boolean areButtonsEnabled() {\n        return closePanelButton.isEnabled();\n    }\n\n    public void close() {\n        if (isClosed()) {\n            return;\n        }\n\n        setVisible(false);\n        state = STATE_CLOSED;\n        fireActionPerformed();\n    }\n\n    public void maximize() {\n        if (isMaximized()) {\n            return;\n        }\n\n        maximizePanelButton.setVisible(false);\n        restorePanelButton.setVisible(true);\n        minimizePanelButton.setVisible(true);\n        contentPanel.setVisible(true);\n        state = STATE_MAXIMIZED;\n        fireActionPerformed();\n    }\n\n    public void minimize() {\n        if (isMinimized()) {\n            return;\n        }\n\n        maximizePanelButton.setVisible(true);\n        restorePanelButton.setVisible(true);\n        minimizePanelButton.setVisible(false);\n        contentPanel.setVisible(false);\n        state = STATE_MINIMIZED;\n        fireActionPerformed();\n    }\n\n    public void remove(Component component) {\n        getContentPanel().remove(component);\n    }\n\n    public void remove(MenuComponent component) {\n        getContentPanel().remove(component);\n    }\n\n    public void remove(int index) {\n        getContentPanel().remove(index);\n    }\n\n    public void removeActionListener(ActionListener listener) {\n        actionListeners.remove(listener);\n    }\n\n    public void removeAll() {\n        getContentPanel().removeAll();\n    }\n\n    public void restore() {\n        if (isRestored()) {\n            return;\n        }\n\n        maximizePanelButton.setVisible(true);\n        restorePanelButton.setVisible(false);\n        minimizePanelButton.setVisible(true);\n        contentPanel.setVisible(true);\n        state = STATE_RESTORED;\n        fireActionPerformed();\n    }\n    \n    protected Component[] getAdditionalControls() {\n        return null;\n    }\n\n    protected Color getTitleBorderColor() {\n        return UIManager.getLookAndFeel().getID().equals(\"Metal\") ? // NOI18N\n                          UIManager.getColor(\"Button.darkShadow\") : // NOI18N\n                          UIManager.getColor(\"Button.shadow\"); // NOI18N\n    }\n\n    private void fireActionPerformed() {\n        for (ActionListener l : actionListeners) {\n            l.actionPerformed(new ActionEvent(this, getState(), \"\"));\n        }\n    }\n\n    private void initComponents() {\n        DoubleClickListener dblClickListener = new DoubleClickListener();\n        \n        titlePanel = new JPanel(new GridBagLayout());\n        titlePanel.addMouseListener(dblClickListener);\n        titlePanel.setBorder(BorderFactory.createCompoundBorder(\n                             BorderFactory.createLineBorder(getTitleBorderColor()),\n                             BorderFactory.createEmptyBorder(2, 5, 2, 2)));\n        titlePanel.setOpaque(true);\n        titlePanel.setBackground(UIUtils.getDarker(UIUtils.getProfilerResultsBackground()));\n        \n        GridBagConstraints gbc;\n        \n        if (icon != null) {\n            gbc = new GridBagConstraints();\n            gbc.insets = new Insets(0, 0, 0, 4);\n            JLabel iconLabel = new JLabel(icon) {\n                public Dimension getMinimumSize() {\n                    return getPreferredSize();\n                }\n            };\n            iconLabel.setOpaque(false);\n            iconLabel.addMouseListener(dblClickListener);\n            titlePanel.add(iconLabel, gbc);\n        }\n        \n        JLabel titleLabel = new JLabel(title) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n        titleLabel.setForeground(UIManager.getColor(\"ToolTip.foreground\")); // NOI18N\n        titleLabel.setFont(UIManager.getFont(\"ToolTip.font\")); // NOI18N\n        titleLabel.setOpaque(false);\n        titleLabel.addMouseListener(dblClickListener);\n        titlePanel.add(titleLabel, new GridBagConstraints());\n        \n        gbc = new GridBagConstraints();\n        gbc.weightx = 1f;\n        gbc.weighty = 1f;\n        JPanel spacer = new JPanel(null);\n        spacer.addMouseListener(dblClickListener);\n        spacer.setOpaque(false);\n        titlePanel.add(spacer, gbc);\n        \n        Component[] additionalControls = getAdditionalControls();\n        if (additionalControls != null && additionalControls.length > 0)\n            for (Component c : additionalControls)\n                titlePanel.add(c, new GridBagConstraints());\n\n        minimizePanelButton = new ImageIconButton(minimizePanelIcon) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n        minimizePanelButton.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    minimize();\n                }\n        });\n        //if (showButtons) titlePanel.add(minimizePanelButton, new GridBagConstraints());\n\n        maximizePanelButton = new ImageIconButton(maximizePanelIcon) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n        maximizePanelButton.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    maximize();\n                }\n        });\n        //if (showButtons) titlePanel.add(maximizePanelButton, new GridBagConstraints());\n\n        restorePanelButton = new ImageIconButton(restorePanelIcon) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n        restorePanelButton.setVisible(false);\n        restorePanelButton.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    restore();\n                }\n        });\n        //if (showButtons) titlePanel.add(restorePanelButton, new GridBagConstraints());\n        \n        closePanelButton = new ImageIconButton(closePanelIcon) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n        closePanelButton.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    close();\n                }\n        });\n        if (showButtons) titlePanel.add(closePanelButton, new GridBagConstraints());\n\n        super.setLayout(new BorderLayout()); // overridden for 'this'\n        super.add(titlePanel, BorderLayout.NORTH); // overridden for 'this'\n        super.add(contentPanel, BorderLayout.CENTER); // overridden for 'this'\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/JTreeTable.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\nimport java.awt.datatransfer.Clipboard;\nimport java.awt.event.*;\nimport java.util.List;\nimport javax.swing.*;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.plaf.basic.BasicTreeUI;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumnModel;\nimport javax.swing.tree.DefaultTreeSelectionModel;\nimport javax.swing.tree.TreeCellRenderer;\nimport javax.swing.tree.TreeModel;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.table.*;\nimport org.graalvm.visualvm.lib.ui.components.tree.EnhancedTreeCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.tree.TreeCellRendererPersistent;\nimport org.graalvm.visualvm.lib.ui.components.treetable.*;\n\n\n/**\n * JTreeTable component implementation\n *\n * @author Jiri Sedlacek\n * @author Ian Formanek\n */\npublic class JTreeTable extends JTable implements CellTipAware, MouseListener, MouseMotionListener, MouseWheelListener,\n                                                  KeyListener {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    /**\n     * ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel to\n     * listen for changes in the ListSelectionModel it maintains. Once a change\n     * in the ListSelectionModel happens, the paths are updated in the\n     * DefaultTreeSelectionModel.\n     */\n    class ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel {\n        //~ Inner Classes --------------------------------------------------------------------------------------------------------\n\n        /**\n         * Class responsible for calling updateSelectedPathsFromSelectedRows\n         * when the selection of the list changse.\n         */\n        class ListSelectionHandler implements ListSelectionListener {\n            //~ Methods ----------------------------------------------------------------------------------------------------------\n\n            public void valueChanged(ListSelectionEvent e) {\n                if (treeTableModelAdapter.isFiringChange()) return;\n                updateSelectedPathsFromSelectedRows();\n            }\n        }\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        /**\n         * Set to true when we are updating the ListSelectionModel.\n         */\n        protected boolean updatingListSelectionModel;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ListToTreeSelectionModelWrapper() {\n            super();\n            getListSelectionModel().addListSelectionListener(createListSelectionListener());\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        /**\n         * This is overridden to set <code>updatingListSelectionModel</code>\n         * and message super. This is the only place DefaultTreeSelectionModel\n         * alters the ListSelectionModel.\n         */\n        public void resetRowSelection() {\n            if (!updatingListSelectionModel) {\n                updatingListSelectionModel = true;\n\n                try {\n                    super.resetRowSelection();\n                } finally {\n                    updatingListSelectionModel = false;\n                }\n            }\n\n            // Notice how we don't message super if\n            // updatingListSelectionModel is true. If\n            // updatingListSelectionModel is true, it implies the\n            // ListSelectionModel has already been updated and the\n            // paths are the only thing that needs to be updated.\n        }\n\n        /**\n         * Creates and returns an instance of ListSelectionHandler.\n         */\n        protected ListSelectionListener createListSelectionListener() {\n            return new ListSelectionHandler();\n        }\n\n        /**\n         * If <code>updatingListSelectionModel</code> is false, this will\n         * reset the selected paths from the selected rows in the list\n         * selection model.\n         */\n        protected void updateSelectedPathsFromSelectedRows() {\n            if (!updatingListSelectionModel) {\n                updatingListSelectionModel = true;\n\n                try {\n                    // This is way expensive, ListSelectionModel needs an\n                    // enumerator for iterating.\n                    int min = listSelectionModel.getMinSelectionIndex();\n                    int max = listSelectionModel.getMaxSelectionIndex();\n\n                    clearSelection();\n\n                    if ((min != -1) && (max != -1)) {\n                        for (int counter = min; counter <= max; counter++) {\n                            if (listSelectionModel.isSelectedIndex(counter)) {\n                                TreePath selPath = tree.getPathForRow(counter);\n\n                                if (selPath != null) {\n                                    addSelectionPath(selPath);\n                                }\n                            }\n                        }\n                    }\n                } finally {\n                    updatingListSelectionModel = false;\n                }\n            }\n        }\n\n        /**\n         * Returns the list selection model. ListToTreeSelectionModelWrapper\n         * listens for changes to this model and updates the selected paths\n         * accordingly.\n         */\n        ListSelectionModel getListSelectionModel() {\n            return listSelectionModel;\n        }\n    }\n\n    //------------------------------------\n\n    /**\n     * This class is used for listening to the table header mouse events.\n     */\n    private class TableHeaderListener extends MouseAdapter implements MouseMotionListener {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        /*\n         * If the user clicks to the sorting column (column defining the sort criterium and order), the sorting order is reversed.\n         * If new sorting column is selected, the appropriate sorting order for column's datatype is set.\n         */\n        public void mouseClicked(MouseEvent e) {\n            if (SwingUtilities.isLeftMouseButton(e)) {\n                int column = tableHeader.columnAtPoint(e.getPoint());\n                int sortingColumn = headerRenderer.getSortingColumn();\n\n                if (column == sortingColumn) {\n                    headerRenderer.reverseSortingOrder();\n                } else {\n                    headerRenderer.setSortingColumn(column);\n\n                    if (treeTableModel.getInitialSorting(column)) {\n                        headerRenderer.setSortingOrder(SORT_ORDER_ASC); // Default sort order for strings is Ascending\n                    } else {\n                        headerRenderer.setSortingOrder(SORT_ORDER_DESC); // Default sort order for numbers is Descending\n                    }\n                }\n\n                tableHeader.repaint();\n\n                treeTableModel.sortByColumn(column, headerRenderer.getSortingOrder());\n                updateTreeTable();\n            }\n        }\n\n        public void mouseDragged(MouseEvent e) {\n        }\n\n        public void mouseMoved(MouseEvent e) {\n            int focusedColumn = tableHeader.columnAtPoint(e.getPoint());\n\n            if (focusedColumn != lastFocusedColumn) {\n                if (focusedColumn != -1) {\n                    tableHeader.setToolTipText(treeTableModel.getColumnToolTipText(focusedColumn));\n                } else {\n                    tableHeader.setToolTipText(null);\n                }\n\n                lastFocusedColumn = focusedColumn;\n            }\n        }\n\n        /*\n         * Here the active header button is programatically pressed\n         */\n        public void mousePressed(MouseEvent e) {\n            if (SwingUtilities.isLeftMouseButton(e) && (tableHeader.getResizingColumn() == null)) {\n                headerRenderer.setPressedColumn(tableHeader.columnAtPoint(e.getPoint()));\n                tableHeader.repaint();\n            }\n        }\n\n        /*\n         * Here the active header button is programatically released\n         */\n        public void mouseReleased(MouseEvent e) {\n            if (SwingUtilities.isLeftMouseButton(e)) {\n                headerRenderer.setPressedColumn(-1);\n                tableHeader.repaint();\n            }\n        }\n    }\n\n    private class TreeTableCellRenderer extends JTree implements TableCellRenderer {\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        protected int currentlyPaintedRow;\n        private Color darkerUnselectedBackground;\n        private Color unselectedBackground;\n        private Color unselectedForeground;\n        private EnhancedTreeCellRenderer treeCellRenderer;\n        private int offsetX; // x-offsed used for scrolling the TreeTable cell\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        TreeTableCellRenderer(TreeModel model) {\n            super(model);\n\n            offsetX = 0;\n            setOpaque(false);\n            treeCellRenderer = new EnhancedTreeCellRenderer();\n            setCellRenderer(treeCellRenderer);\n            unselectedBackground = UIUtils.getProfilerResultsBackground();\n            darkerUnselectedBackground = UIUtils.getDarker(unselectedBackground);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        // Overridden for performance reasons.\n        public void validate() {}\n\n        // Overridden for performance reasons.\n        public void revalidate() {}\n\n        // Overridden for performance reasons.\n        public Insets getInsets() { return ZERO_INSETS; }\n\n        public void setBounds(int x, int y, int w, int h) {\n            super.setBounds(x, 0, w, JTreeTable.this.getHeight());\n        }\n\n        public void setOffsetX(int offsetX) {\n            this.offsetX = offsetX;\n        }\n\n        public int getOffsetX() {\n            return offsetX;\n        }\n\n        public void setRowHeight(int rowHeight) {\n            if (rowHeight > 0) {\n                super.setRowHeight(rowHeight);\n\n                if ((JTreeTable.this != null) && (JTreeTable.this.getRowHeight() != rowHeight)) {\n                    JTreeTable.this.setRowHeight(getRowHeight());\n                }\n            }\n        }\n\n        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,\n                                                       int column) {\n            if (isSelected) {\n                setRowForeground(table.isFocusOwner() ? table.getSelectionForeground() : UIUtils.getUnfocusedSelectionForeground());\n                setRowBackground(table.isFocusOwner() ? table.getSelectionBackground() : UIUtils.getUnfocusedSelectionBackground());\n            } else {\n                if ((row & 0x1) == 0) { //even row\n                    setRowForeground((unselectedForeground != null) ? unselectedForeground : table.getForeground());\n                    setRowBackground((darkerUnselectedBackground != null) ? darkerUnselectedBackground\n                                                                          : UIUtils.getDarker(table.getBackground()));\n                } else {\n                    setRowForeground((unselectedForeground != null) ? unselectedForeground : table.getForeground());\n                    setRowBackground((unselectedBackground != null) ? unselectedBackground : table.getBackground());\n                }\n            }\n\n            currentlyPaintedRow = row;\n\n            return this;\n        }\n\n        public void setTreeCellRenderer(EnhancedTreeCellRenderer renderer) {\n            treeCellRenderer = renderer;\n            setCellRenderer(treeCellRenderer);\n        }\n\n        public EnhancedTreeCellRenderer getTreeCellRenderer() {\n            return treeCellRenderer;\n        }\n\n        public void customProcessKeyEvent(KeyEvent e) {\n            processKeyEvent(e);\n        }\n\n        public void paint(Graphics g) {\n            boolean selected;\n            boolean focused;\n            int xpos;\n\n            selected = isRowSelected(currentlyPaintedRow);\n            focused = JTreeTable.this.isFocusOwner();\n\n            int rHeight = getRowHeight();\n\n            // move tree according to offsetX\n            g.translate(-offsetX, -currentlyPaintedRow * rHeight);\n\n            if (isGTK) { // Optimized for GTK but doesn't paint selection on the left side of renderer\n                // paint tree row, according to current Clip only one row is painted\n                super.paint(g);\n\n                // draw row background\n                Rectangle rowBounds = getRowBounds(currentlyPaintedRow);\n                xpos = rowBounds.x + rowBounds.width;\n                g.setColor(getRowColor(currentlyPaintedRow, selected, focused));\n                g.fillRect(xpos, currentlyPaintedRow * rHeight, getWidth() + offsetX - xpos, rHeight);\n            } else {\n                // draw row background\n                xpos = selected ? 0 : getRowBounds(currentlyPaintedRow).x;\n                g.setColor(getRowColor(currentlyPaintedRow, selected, focused));\n                    g.fillRect(xpos, currentlyPaintedRow * rHeight, getWidth() + offsetX, rHeight);\n\n                // paint tree row, according to current Clip only one row is painted\n                super.paint(g);\n            }\n            \n        }\n\n        protected void setRowBackground(Color c) {\n            //setBackground(c);\n            treeCellRenderer.setBackground(c);\n            treeCellRenderer.setBackgroundNonSelectionColor(c);\n            treeCellRenderer.setBackgroundSelectionColor(c);\n        }\n\n        protected void setRowForeground(Color c) {\n            //setForeground(c);\n            treeCellRenderer.setForeground(c);\n            treeCellRenderer.setTextNonSelectionColor(c);\n            treeCellRenderer.setTextSelectionColor(c);\n        }\n\n        private Color getRowColor(int row, boolean selected, boolean focused) {\n            if (selected) {\n                return focused ? JTreeTable.this.getSelectionBackground() : UIUtils.getUnfocusedSelectionBackground();\n            } else {\n                Color backgroundColor = UIUtils.getProfilerResultsBackground();\n                if ((row & 0x1) == 0) { //even row\n                    return UIUtils.getDarker(backgroundColor);\n                } else {\n                    return backgroundColor;\n                }\n            }\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Insets ZERO_INSETS = new Insets(0, 0, 0, 0);\n\n    public static final boolean SORT_ORDER_DESC = false;\n    public static final boolean SORT_ORDER_ASC = true;\n\n    private static final boolean isGTK = UIUtils.isGTKLookAndFeel();\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    // --- CellTip support declarations -------\n    protected JToolTip cellTip;\n    protected Rectangle rendererRect;\n\n    /**\n     * A subclass of JTree.\n     */\n    TreeTableCellRenderer tree;\n    protected int lastColumn = -1;\n    protected int lastRow = -1;\n    private AbstractTreeTableModel treeTableModel;\n    private CustomSortableHeaderRenderer headerRenderer;\n    private ImageIcon sortAscIcon = Icons.getImageIcon(GeneralIcons.SORT_ASCENDING);\n    private ImageIcon sortDescIcon = Icons.getImageIcon(GeneralIcons.SORT_DESCENDING);\n    private JTableHeader tableHeader;\n    private String internalFindString;\n\n    //------------------------------------\n    // Find functionality stuff\n    private String userFindString;\n    private TableHeaderListener headerListener;\n    private TreeTableModelAdapter treeTableModelAdapter;\n    private int lastFocusedColumn = -1;\n    private int treeSignExtent; // width/2 of the tree \"+\"/\"-\" sign\n    private int treeSignRightMargin; // value of BasicTreeUI.getRightChildIndent()\n    private int userFindColumn;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public JTreeTable(AbstractTreeTableModel treeTableModel) {\n        super();\n        this.treeTableModel = treeTableModel;\n        \n        setBackground(UIUtils.getProfilerResultsBackground());\n\n        int initialSortingColumn = treeTableModel.getInitialSortingColumn();\n        boolean initialSortingOrder = treeTableModel.getInitialSortingOrder();\n\n        if (treeTableModel.supportsSorting()) {\n            treeTableModel.sortByColumn(initialSortingColumn, initialSortingOrder);\n        }\n\n        addKeyListener(this);\n        addMouseListener(this);\n        addMouseMotionListener(this);\n\n        // Required for correct updating of focused/unfocused selection\n        addFocusListener(new FocusListener() {\n                public void focusGained(FocusEvent e) {\n                    if (getSelectedRows().length > 0) {\n                        repaint();\n                    }\n                }\n\n                public void focusLost(FocusEvent e) {\n                    if (getSelectedRows().length > 0) {\n                        repaint();\n                    }\n                }\n            });\n\n        // Create the tree. It will be used as a renderer and editor.\n        tree = new TreeTableCellRenderer(treeTableModel);\n        setTreeUIVariables();\n        tree.setTransferHandler(new TransferHandler() {\n            public void exportToClipboard(JComponent comp, Clipboard clip, int action)\n                                                  throws IllegalStateException {\n                JTreeTable.this.getTransferHandler().exportToClipboard(\n                        JTreeTable.this, clip, action);\n            }\n        });\n\n        // Install a tableModel representing the visible rows in the tree.\n        treeTableModelAdapter = new TreeTableModelAdapter(treeTableModel, this);\n        setModel(treeTableModelAdapter);\n\n        if (treeTableModel.supportsSorting()) {\n            headerListener = new TableHeaderListener();\n\n            headerRenderer = new CustomSortableHeaderRenderer(sortAscIcon, sortDescIcon);\n            headerRenderer.setSortingColumn(initialSortingColumn);\n            headerRenderer.setSortingOrder(initialSortingOrder);\n\n            updateTreeTableHeader();\n        }\n\n        getTableHeader().setReorderingAllowed(false);\n\n        // Force the JTable and JTree to share their row selection models.\n        ListToTreeSelectionModelWrapper selectionWrapper = new ListToTreeSelectionModelWrapper();\n        tree.setSelectionModel(selectionWrapper);\n        setSelectionModel(selectionWrapper.getListSelectionModel());\n\n        // Install the tree editor renderer and editor.\n        setDefaultRenderer(TreeTableModel.class, tree);\n\n        // --- CellTip support ------------------\n        cellTip = createCellTip();\n        cellTip.setBorder(BorderFactory.createLineBorder(getGridColor()));\n        cellTip.setLayout(new BorderLayout());\n\n        CellTipManager.sharedInstance().registerComponent(this);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public JToolTip getCellTip() {\n        return cellTip;\n    }\n\n    public Point getCellTipLocation() {\n        if (rendererRect == null) {\n            return null;\n        }\n\n        return new Point(rendererRect.getLocation().x - 1, rendererRect.getLocation().y - 1);\n    }\n\n    public int getFindColumn() {\n        return userFindColumn;\n    }\n\n    public boolean isFindColumnValid() {\n        return ((userFindColumn >= 0) && (userFindColumn < getColumnCount()));\n    }\n\n    public void setFindParameters(String findString, int findColumn) {\n        userFindString = findString;\n        userFindColumn = findColumn;\n        internalFindString = getInternalFindString(userFindString);\n    }\n\n    public String getFindString() {\n        return userFindString;\n    }\n\n    public boolean isFindStringDefined() {\n        return ((userFindString != null) && (!userFindString.trim().isEmpty()));\n    }\n\n    //------------------------------------\n    // CellTip support\n    public void setGridColor(Color gridColor) {\n        super.setGridColor(gridColor);\n\n        if ((gridColor == null) || (cellTip == null)) {\n            return;\n        }\n\n        cellTip.setBorder(BorderFactory.createLineBorder(gridColor));\n    }\n\n    /**\n     * Overridden to pass the new rowHeight to the tree.\n     */\n    public void setRowHeight(int rowHeight) {\n        super.setRowHeight(rowHeight);\n\n        if ((tree != null) && (tree.getRowHeight() != rowHeight)) {\n            tree.setRowHeight(getRowHeight());\n        }\n    }\n\n    public void setSortingColumn(int column) {\n        headerRenderer.setSortingColumn(column);\n    }\n\n    public int getSortingColumn() {\n        return headerRenderer.getSortingColumn();\n    }\n\n    public void setSortingOrder(boolean order) {\n        headerRenderer.setSortingOrder(order);\n    }\n\n    public boolean getSortingOrder() {\n        return headerRenderer.getSortingOrder();\n    }\n\n    /**\n     * Returns the tree that is being shared between the model.\n     */\n    public JTree getTree() {\n        return tree;\n    }\n\n    /** Sets the x-offsed used for scrolling the TreeTable cell */\n    public void setTreeCellOffsetX(int offsetX) {\n        if (getTreeCellOffsetX() != offsetX) {\n            tree.setOffsetX(offsetX);\n            repaint(0, 0, getColumnModel().getColumn(0).getWidth(), getHeight());\n        }\n    }\n\n    /** Gets the x-offsed used for scrolling the TreeTable cell */\n    public int getTreeCellOffsetX() {\n        return tree.getOffsetX();\n    }\n\n    public void setTreeCellRenderer(EnhancedTreeCellRenderer renderer) {\n        tree.setTreeCellRenderer(renderer);\n    }\n\n    public EnhancedTreeCellRenderer getTreeCellRenderer() {\n        return tree.getTreeCellRenderer();\n    }\n\n    public boolean canFindBePerformed() {\n        return (tree != null) && (treeTableModel.getRoot() != null) && isFindColumnValid() && isFindStringDefined();\n    }\n\n    public boolean findFirst() {\n        return findFirst(true);\n    }\n\n    public boolean findNext() {\n        if (!canFindBePerformed()) {\n            return false;\n        }\n\n        CCTNode searchRoot = getSearchRoot();\n\n        // check current search root's subtree\n        if (doFindNext(searchRoot, 0, true)) {\n            return true;\n        }\n\n        CCTNode searchRootParent = searchRoot.getParent();\n\n        // nothing found, process next siblings\n        while (searchRootParent != null) {\n            if (doFindNext(searchRootParent, searchRootParent.getIndexOfChild(searchRoot) + 1, true)) {\n                return true;\n            }\n\n            searchRoot = searchRootParent;\n            searchRootParent = searchRoot.getParent();\n        }\n\n        return false;\n    }\n\n    public boolean findPrevious() {\n        if (!canFindBePerformed()) {\n            return false;\n        }\n\n        // selected/last found node\n        CCTNode searchRoot = getSearchRoot();\n\n        if (!isAnyRowSelected()) {\n            return findFirst();\n        }\n\n        // parent of this node than could contain previous node\n        CCTNode searchRootParent = searchRoot.getParent();\n\n        while (searchRootParent != null) {\n            // if nothing found in previous siblings\n            if (doFindPrevious(searchRootParent, searchRootParent.getIndexOfChild(searchRoot) - 1, true)) {\n                return true;\n            }\n\n            // swith one level up\n            searchRoot = searchRootParent;\n            searchRootParent = searchRoot.getParent();\n        }\n\n        return false;\n    }\n\n    //------------------------------------\n    // Keyboard processing\n    public void keyPressed(KeyEvent e) {\n        if (shouldBeForwarded(e)) {\n            dispatchKeyboardEvent(e);\n        }\n    }\n\n    public void keyReleased(KeyEvent e) {\n        if (shouldBeForwarded(e)) {\n            dispatchKeyboardEvent(e);\n        }\n    }\n\n    public void keyTyped(KeyEvent e) {\n        if (shouldBeForwarded(e)) {\n            dispatchKeyboardEvent(e);\n        }\n    }\n\n    //------------------------------------\n    // Mouse processing\n    public void mouseClicked(MouseEvent e) {\n        dispatchMouseEvent(e);\n    }\n\n    public void mouseDragged(MouseEvent e) {\n        dispatchMouseEvent(e);\n    }\n\n    public void mouseEntered(MouseEvent e) {\n        //dispatchMouseEvent(e);\n\n        // --- CellTip support ------------------\n        CellTipManager.sharedInstance().setEnabled(false);\n    }\n\n    public void mouseExited(MouseEvent e) {\n        //dispatchMouseEvent(e);\n\n        // --- CellTip support ------------------\n        // Return if mouseExit occured because of showing heavyweight celltip\n        if (contains(e.getPoint()) && cellTip.isShowing()) {\n            return;\n        }\n\n        CellTipManager.sharedInstance().setEnabled(false);\n        lastRow = -1;\n        lastColumn = -1;\n    }\n\n    public void mouseMoved(MouseEvent e) {\n        //dispatchMouseEvent(e);\n\n        // --- CellTip support ------------------\n\n        // Identify treetable row and column at cursor\n        int row = rowAtPoint(e.getPoint());\n        int column = columnAtPoint(e.getPoint());\n\n        boolean isForTreeCell = (getColumnClass(column) == TreeTableModel.class);\n\n        // Return if treetable cell is the same as in previous event\n        if (!isForTreeCell && (row == lastRow) && (column == lastColumn)) {\n            return;\n        }\n\n        lastRow = row;\n        lastColumn = column;\n\n        // Return if cursor isn't at any cell\n        if ((row < 0) || (column < 0)) {\n            CellTipManager.sharedInstance().setEnabled(false);\n\n            return;\n        }\n\n        Component cellRenderer;\n        Rectangle cellRect = getCellRect(row, column, false);\n\n        if (isForTreeCell) {\n            // Cursor at tree cell\n            TreeCellRenderer treeCellRenderer = tree.getTreeCellRenderer();\n            cellRenderer = ((TreeCellRendererPersistent) treeCellRenderer).getTreeCellRendererComponentPersistent(tree,\n                                                                                                                  treeTableModel\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     .getValueAt(tree.getPathForRow(row)\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     .getLastPathComponent(),\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 0),\n                                                                                                                  false,\n                                                                                                                  tree.isExpanded(row),\n                                                                                                                  treeTableModel\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           .isLeaf(tree.getPathForRow(row)\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       .getLastPathComponent()),\n                                                                                                                  row, false);\n\n            // Return if celltip is not supported for the cell\n            if (cellRenderer == null) {\n                CellTipManager.sharedInstance().setEnabled(false);\n\n                return;\n            }\n\n            Point treeCellStart = tree.getPathBounds(tree.getPathForRow(row)).getLocation();\n            rendererRect = new Rectangle((cellRect.x + treeCellStart.x) - tree.getOffsetX(), treeCellStart.y,\n                                         cellRenderer.getPreferredSize().width, cellRenderer.getPreferredSize().height + 2);\n        } else {\n            // Cursor at table cell\n            TableCellRenderer tableCellRenderer = getCellRenderer(row, column);\n\n            if (!(tableCellRenderer instanceof TableCellRendererPersistent)) {\n                return;\n            }\n\n            cellRenderer = ((TableCellRendererPersistent) tableCellRenderer).getTableCellRendererComponentPersistent(this,\n                                                                                                                     getValueAt(row,\n                                                                                                                                column),\n                                                                                                                     false,\n                                                                                                                     false, row,\n                                                                                                                     column);\n\n            // Return if celltip is not supported for the cell\n            if (cellRenderer == null) {\n                CellTipManager.sharedInstance().setEnabled(false);\n\n                return;\n            }\n\n            int horizontalAlignment = ((EnhancedTableCellRenderer) cellRenderer).getHorizontalAlignment();\n\n            if ((horizontalAlignment == SwingConstants.TRAILING) || (horizontalAlignment == SwingConstants.RIGHT)) {\n                rendererRect = new Rectangle((cellRect.x + cellRect.width) - cellRenderer.getPreferredSize().width, cellRect.y,\n                                             cellRenderer.getPreferredSize().width, cellRenderer.getPreferredSize().height);\n            } else {\n                rendererRect = new Rectangle(cellRect.x, cellRect.y, cellRenderer.getPreferredSize().width,\n                                             cellRenderer.getPreferredSize().height);\n            }\n        }\n\n        if (isForTreeCell && !rendererRect.contains(e.getPoint())) {\n            CellTipManager.sharedInstance().setEnabled(false);\n\n            return;\n        }\n\n        // Return if cell contents is fully visible\n        if ((rendererRect.x >= cellRect.x) && ((rendererRect.x + rendererRect.width) <= (cellRect.x + cellRect.width))) {\n            CellTipManager.sharedInstance().setEnabled(false);\n\n            return;\n        }\n\n        while (cellTip.getComponentCount() > 0) {\n            cellTip.remove(0);\n        }\n\n        cellTip.add(cellRenderer, BorderLayout.CENTER);\n        cellTip.setPreferredSize(new Dimension(rendererRect.width + 2, getRowHeight(row) + 2));\n\n        CellTipManager.sharedInstance().setEnabled(true);\n    }\n\n    public void mousePressed(MouseEvent e) {\n        dispatchMouseEvent(e);\n    }\n\n    public void mouseReleased(MouseEvent e) {\n        dispatchMouseEvent(e);\n    }\n\n    public void mouseWheelMoved(MouseWheelEvent e) {\n        mouseMoved(e);\n        CellTipManager.sharedInstance().setEnabled(false);\n    }\n\n    public void processMouseEvent(MouseEvent e) {\n        if (e instanceof MouseWheelEvent) {\n            Component target = JTreeTable.this.getParent();\n            if (!(target instanceof JViewport))\n                target = JTreeTable.this;\n            MouseEvent mwe = SwingUtilities.convertMouseEvent(\n                    JTreeTable.this, e, target);\n            target.dispatchEvent(mwe);\n        } else {\n            super.processMouseEvent(e);\n        }\n    }\n\n    public void resetTreeCellOffsetX() {\n        setTreeCellOffsetX(0);\n    }\n\n    public CCTNode[] getPathToRoot(CCTNode node) {\n        return treeTableModel.getPathToRoot(node);\n    }\n\n    //------------------------------------\n    public void selectNode(CCTNode node, boolean setVisible) {\n        TreePath path = new TreePath(treeTableModel.getPathToRoot(node));\n        getTree().setSelectionPath(path);\n\n        if (setVisible) {\n            scrollRectToVisible(getCellRect(getSelectedRow(), 0, true));\n        }\n    }\n    \n    public void selectRowByContents(String rowString, int columnIndex, boolean setVisible) {\n        for (int i = 0; i < getRowCount(); i++) {\n            if (getValueAt(i, columnIndex).toString().equals(rowString)) {\n                getSelectionModel().setSelectionInterval(i, i);\n\n                if (setVisible) {\n                    scrollRectToVisible(getCellRect(i, columnIndex, true));\n                }\n\n                return;\n            }\n        }\n\n        getSelectionModel().clearSelection();\n    }\n\n    public boolean silentlyFindFirst() {\n        return findFirst(false);\n    }\n\n    public void updateTreeTable() {\n        treeTableModelAdapter.updateTreeTable();\n    }\n    \n    public void changeRoot(CCTNode newRoot) {\n        treeTableModelAdapter.changeRoot(newRoot);\n    }\n    \n    public void setup(List expanded, TreePath selected) {\n        treeTableModelAdapter.setup(expanded, selected);\n    }\n    \n    public List getExpandedPaths() {\n        return treeTableModelAdapter.getExpandedPaths();\n    }\n\n    public void updateTreeTableHeader() {\n        TableColumnModel tableColumnModel = getColumnModel();\n        int n = tableColumnModel.getColumnCount();\n\n        for (int i = 0; i < n; i++) {\n            tableColumnModel.getColumn(i).setHeaderRenderer(headerRenderer);\n        }\n\n        if (tableHeader != getTableHeader()) {\n            if (tableHeader != null) {\n                tableHeader.removeMouseListener(headerListener);\n            }\n\n            if (tableHeader != null) {\n                tableHeader.removeMouseMotionListener(headerListener);\n            }\n\n            tableHeader = getTableHeader();\n            tableHeader.addMouseListener(headerListener);\n            tableHeader.addMouseMotionListener(headerListener);\n            updateTreeTable();\n        }\n    }\n\n    /**\n     * Overridden to message super and forward the method to the tree. Since\n     * the tree is not actually in the component hieachy it will never receive\n     * this unless we forward it in this manner.\n     */\n    public void updateUI() {\n        super.updateUI();\n\n        if (tree != null) {\n            tree.updateUI();\n            setTreeUIVariables();\n        }\n    }\n\n    protected JToolTip createCellTip() {\n        return new JToolTip();\n    }\n\n    private boolean isAnyRowSelected() {\n        TreePath treeSelectionPath = tree.getSelectionPath();\n\n        return ((treeSelectionPath != null) && (treeSelectionPath.getPathCount() > 0));\n    }\n\n    private String getInternalFindString(String findString) {\n        if (findString == null) {\n            return null;\n        }\n\n        return findString.toLowerCase();\n    }\n\n    private CCTNode getSearchRoot() {\n        if (!isAnyRowSelected()) {\n            return (CCTNode) treeTableModel.getRoot();\n        } else {\n            return (CCTNode) tree.getSelectionPath().getLastPathComponent();\n        }\n    }\n\n    private void setTreeUIVariables() {\n        if (tree.getUI() instanceof BasicTreeUI) {\n            BasicTreeUI treeUI = (BasicTreeUI) tree.getUI();\n            treeSignExtent = treeUI.getExpandedIcon().getIconWidth() / 2;\n            treeSignRightMargin = treeUI.getRightChildIndent();\n        }\n    }\n\n    private void dispatchKeyboardEvent(KeyEvent e) {\n        JTreeTable.this.tree.customProcessKeyEvent(e);\n        \n        if (!isModifierKey(e)) {\n            int selectedRow = getSelectedRow();\n            if (selectedRow > -1)\n                scrollRectToVisible(getCellRect(selectedRow, 0, false));\n        }\n    }\n    \n    private static boolean isModifierKey(KeyEvent e) {\n        switch (e.getKeyCode()) {\n            case KeyEvent.VK_ALT:\n            case KeyEvent.VK_ALT_GRAPH:\n            case KeyEvent.VK_SHIFT:\n            case KeyEvent.VK_CONTROL:\n                return true;\n            default:\n                return false;\n        }\n    }\n\n    private void dispatchMouseEvent(MouseEvent e) {\n        if (e != null) {\n            int row = rowAtPoint(e.getPoint());\n            int column = columnAtPoint(e.getPoint());\n\n            Rectangle tableCellRect = getCellRect(row, column, true);\n            Rectangle treeCellRect = tree.getRowBounds(row);\n\n            if (treeCellRect != null) {\n                // x-coordinate of the mouseclick must be mapped to the tree coordinate system\n                int xClick;\n                Class<?> columnClass = getColumnClass(column);\n\n                if (columnClass == TreeTableModel.class) {\n                    // Clicked inside tree cell\n                    xClick = e.getX() - tableCellRect.x;\n                    xClick += tree.getOffsetX();\n\n                    if ((xClick < (treeCellRect.x - treeSignExtent - treeSignRightMargin))\n                            || (xClick > ((treeCellRect.x + treeSignExtent) - treeSignRightMargin + 1))) {\n                        // Clicked on \"+\"/\"-\" sign\n                        xClick = (treeCellRect.x + treeCellRect.width) - 1;\n                    }\n                } else {\n                    // Clicked outside tree cell\n                    xClick = (treeCellRect.x + treeCellRect.width) - 1;\n                }\n\n                int clickCount = 2 - (e.getClickCount() % 2);\n\n                MouseEvent newEvent = new MouseEvent(JTreeTable.this.tree, e.getID(), e.getWhen(), e.getModifiers(), xClick,\n                                                     e.getY(), clickCount, e.isPopupTrigger());\n                JTreeTable.this.tree.dispatchEvent(newEvent);\n            }\n        }\n    }\n\n    private boolean doFindNext(CCTNode rootForSearch, int childToSearchIndex, boolean requestFocus) {\n        int nChildren = rootForSearch.getNChildren();\n\n        // for all not processed children\n        while (childToSearchIndex < nChildren) {\n            CCTNode childToSearch = rootForSearch.getChild(childToSearchIndex);\n\n            // check the child itself\n            if (matchesFindCriterion(childToSearch)) {\n                return selectFoundNode(childToSearch, requestFocus);\n            }\n            // and then its subtree\n            else if ((childToSearch.getNChildren() > 0) && doFindNext(childToSearch, 0, requestFocus)) {\n                return true;\n            }\n\n            childToSearchIndex++;\n        }\n\n        // nothing found\n        return false;\n    }\n\n    private boolean doFindPrevious(CCTNode rootForSearch, int childToSearchIndex, boolean requestFocus) {\n        // check all not processed children\n        while (childToSearchIndex >= 0) {\n            CCTNode childToSearch = rootForSearch.getChild(childToSearchIndex);\n\n            if (doFindPrevious(childToSearch, childToSearch.getNChildren() - 1, requestFocus)) {\n                return true;\n            }\n\n            childToSearchIndex--;\n        }\n\n        // check itself\n        if (matchesFindCriterion(rootForSearch)) {\n            return selectFoundNode(rootForSearch, requestFocus);\n        }\n\n        // nothing found\n        return false;\n    }\n\n    private boolean findFirst(boolean requestFocus) {\n        if (!canFindBePerformed()) {\n            return false;\n        }\n\n        CCTNode searchRoot = (CCTNode) treeTableModel.getRoot();\n\n        if (matchesFindCriterion(searchRoot)) {\n            return selectFoundNode(searchRoot, requestFocus);\n        } else {\n            return doFindNext(searchRoot, 0, requestFocus);\n        }\n    }\n\n    private boolean matchesFindCriterion(Object node) {\n        // find is always performed on values of the first column\n        // first column is always visible and has always index=0\n        Object o = treeTableModel.getValueAt(node, 0);\n        if (o == null) return false; // #207622, probably caused by updating the table while searching\n        String s = o.toString();\n        if (s == null) return false; // #207622, likely won't happen but just to be sure\n        return s.toLowerCase().contains(internalFindString);\n    }\n\n    private boolean selectFoundNode(CCTNode nodeToSelect, boolean requestFocus) {\n        TreePath nodeToSelectPath = new TreePath(treeTableModel.getPathToRoot(nodeToSelect));\n        tree.expandPath(nodeToSelectPath);\n        tree.setSelectionPath(nodeToSelectPath);\n\n        if (requestFocus) {\n            requestFocusInWindow();\n        }\n\n        Rectangle rect = tree.getPathBounds(nodeToSelectPath);\n\n        if (rect != null) {\n            scrollRectToVisible(rect);\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    // Filters-out actions handled by the JTable itself,\n    // see http://www.netbeans.org/issues/show_bug.cgi?id=112848\n    private boolean shouldBeForwarded(KeyEvent e) {\n        switch (e.getKeyCode()) {\n            case KeyEvent.VK_PAGE_UP:\n            case KeyEvent.VK_PAGE_DOWN:\n                return false;\n            default:\n                return true;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/LazyComboBox.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.Dimension;\nimport java.awt.event.ItemEvent;\nimport java.util.Objects;\nimport javax.swing.AbstractListModel;\nimport javax.swing.ComboBoxModel;\nimport javax.swing.JComboBox;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class LazyComboBox<E> extends JComboBox<E> {\n\n    public LazyComboBox(Populator<E> populator) {\n        super(new LazyComboBoxModel<>(populator));\n        setPrototypeDisplayValue(populator.initial());\n    }\n\n\n    public final void setModel(ComboBoxModel<E> model) {\n        if (!(model instanceof LazyComboBoxModel))\n            throw new IllegalArgumentException(\"Can only use private LazyComboBoxModel\"); // NOI18N\n        super.setModel(model);\n    }\n\n    private LazyComboBoxModel<E> _getModel() {\n        return (LazyComboBoxModel<E>)super.getModel();\n    }\n\n    public final int getSelectedIndex() {\n        return _getModel().isPopulated() ? super.getSelectedIndex() : -1;\n    }\n\n    public final void setSelectedItem(Object newSelected) {\n        LazyComboBoxModel<E> m = _getModel();\n        E oldSelected = m.getSelectedItem();\n\n        m.setSelectedItem(newSelected);\n\n        if (!Objects.equals(oldSelected, newSelected)) {\n            repaint();\n            selectionChanged();\n        }\n    }\n\n    protected void fireItemStateChanged(ItemEvent e) {\n        super.fireItemStateChanged(e);\n        if (e.getStateChange() == ItemEvent.SELECTED) selectionChanged();\n    }\n\n    // Override this method to get notifications about selection changes\n    protected void selectionChanged() {}\n\n    public final void resetModel() {\n        LazyComboBoxModel<E> m = _getModel();\n        E oldSelected = m.getSelectedItem();\n\n        m.reset(true);\n\n        if (!Objects.equals(oldSelected, m.getSelectedItem())) {\n            repaint();\n            selectionChanged();\n        }\n    }\n    \n    public final Dimension getPreferredSize() {\n        Dimension d;\n        if (getPrototypeDisplayValue() != null || _getModel().isPopulated()) d = super.getPreferredSize();\n        else d = new JComboBox<>(new Object[] { _getModel().getSelectedItem() }).getPreferredSize();\n        if (getPreferredWidth() >= 0) d.width = Math.max(d.width, getPreferredWidth());\n        return d;\n    }\n    \n    public final Dimension getMinimumSize() {\n        Dimension d = getPreferredSize();\n        if (getPreferredWidth() < 0) d.width = 0;\n        else d.width = Math.max(0, getPreferredWidth());\n        return d;\n    }\n    \n    public final Dimension getMaximumSize() {\n        Dimension d = getPreferredSize();\n        if (getPreferredWidth() < 0) d.width = Integer.MAX_VALUE;\n        else d.width = Math.max(d.width, getPreferredWidth());\n        return d;\n    }\n    \n    // Override this method to define preferred width of the component\n    protected int getPreferredWidth() { return -1; }\n\n\n    public static abstract class Populator<E> {\n        \n        protected abstract E initial();\n\n        protected abstract E[] populate();\n\n    }\n\n    private static class LazyComboBoxModel<E> extends AbstractListModel<E> implements ComboBoxModel<E> {\n\n        private E[] items;\n        private E selected;\n\n        private final Populator<E> populator;\n\n\n        LazyComboBoxModel(Populator<E> populator) {\n            this.populator = populator;\n            this.selected = populator.initial();\n        }\n\n\n        public void setSelectedItem(Object selected) { this.selected = (E)selected; }\n\n        public E getSelectedItem() { return selected; }\n\n        public int getSize() { return getItems().length; }\n\n        public E getElementAt(int index) { return getItems()[index]; }\n\n\n        boolean isPopulated() { return items != null; }\n\n        private E[] getItems() {\n            if (items == null) {\n                items = populator.populate();\n                if (items == null) throw new UnsupportedOperationException(\"Populator returned null\"); // NOI18N\n                fireContentsChanged(this, -1, -1);\n            }\n            return items;\n        }\n        \n        void reset(boolean selection) {\n            items = null;\n            if (selection && !Objects.equals(selected, populator.initial()) && !containsItem(selected))\n                selected = populator.initial();\n        }\n        \n        private boolean containsItem(E item) {\n            for (E e : populator.populate())\n                if (Objects.equals(e, item)) return true;\n            return false;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/NoCaret.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.Graphics;\nimport java.awt.Point;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.text.Caret;\nimport javax.swing.text.JTextComponent;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class NoCaret implements Caret {\n\n    public void install(JTextComponent c) {}\n    public void deinstall(JTextComponent c) {}\n    public void paint(Graphics g) {}\n    public void addChangeListener(ChangeListener l) {}\n    public void removeChangeListener(ChangeListener l) {}\n    public boolean isVisible() { return false; }\n    public void setVisible(boolean v) {}\n    public boolean isSelectionVisible() { return false; }\n    public void setSelectionVisible(boolean v) {}\n    public void setMagicCaretPosition(Point p) {}\n    public Point getMagicCaretPosition() { return new Point(0, 0); }\n    public void setBlinkRate(int rate) {}\n    public int getBlinkRate() { return 1; }\n    public int getDot() { return 0; }\n    public int getMark() { return 0; }\n    public void setDot(int dot) {}\n    public void moveDot(int dot) {}\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/ProfilerToolbar.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.FocusTraversalPolicy;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JToolBar;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.InvisibleToolbar;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerToolbar {\n\n    public static ProfilerToolbar create(boolean showSeparator) {\n        Provider provider = Lookup.getDefault().lookup(Provider.class);\n        return provider != null ? provider.create(showSeparator) :\n                                  new Impl(showSeparator);\n    }\n\n\n    public abstract JComponent getComponent();\n\n\n    public Component add(ProfilerToolbar toolbar) { return toolbar.getComponent(); }\n\n    public Component add(ProfilerToolbar toolbar, int index) { return toolbar.getComponent(); }\n\n    public void remove(ProfilerToolbar toolbar) {}\n\n\n    public abstract Component add(Action action);\n\n    public abstract Component add(Component component);\n\n    public abstract Component add(Component component, int index);\n\n    public abstract void addSeparator();\n\n    public abstract void addSpace(int width);\n\n    public abstract void addFiller();\n\n    public abstract void remove(Component component);\n\n    public abstract void remove(int index);\n\n    public abstract int getComponentCount();\n\n\n    protected ProfilerToolbar() {}\n\n\n    public static abstract class Provider {\n\n        public abstract ProfilerToolbar create(boolean showSeparator);\n        \n    }\n    \n    public static class Impl extends ProfilerToolbar {\n        \n        protected final JComponent component;\n        protected final JToolBar toolbar;\n        \n        protected Impl(boolean showSeparator) {\n            toolbar = new InvisibleToolbar();\n            if (UIUtils.isWindowsModernLookAndFeel())\n                toolbar.setBorder(BorderFactory.createEmptyBorder(2, 2, 1, 2));\n            else if (UIUtils.isMetalLookAndFeel())\n                toolbar.setBorder(BorderFactory.createEmptyBorder(2, 2, 1, 2));\n            else if (UIUtils.isNimbusLookAndFeel())\n                toolbar.setBorder(BorderFactory.createEmptyBorder(-1, 0, -2, 0));\n            else if (UIUtils.isGTKLookAndFeel())\n                toolbar.setBorder(BorderFactory.createEmptyBorder(2, 2, 0, 2));\n            else if (!UIUtils.isAquaLookAndFeel())\n                toolbar.setBorder(BorderFactory.createEmptyBorder(1, 2, 0, 2));\n            toolbar.setBorderPainted(false);\n            toolbar.setRollover(true);\n            toolbar.setFloatable(false);\n            \n            toolbar.setFocusTraversalPolicyProvider(true);\n            toolbar.setFocusTraversalPolicy(new SimpleFocusTraversalPolicy());\n            \n            if (showSeparator) {\n                component = new JPanel(new BorderLayout(0, 0));\n                component.setOpaque(false);\n                component.add(toolbar, BorderLayout.CENTER);\n                component.add(UIUtils.createHorizontalLine(), BorderLayout.SOUTH);\n            } else {\n                component = toolbar;\n            }\n        }\n        \n        @Override\n        public JComponent getComponent() {\n            return component;\n        }\n        \n        @Override\n        public Component add(ProfilerToolbar toolbar) {\n            return add(toolbar, getComponentCount());\n        }\n    \n        @Override\n        public Component add(ProfilerToolbar toolbar, int index) {\n            JToolBar implToolbar = ((Impl)toolbar).toolbar;\n            implToolbar.setBorder(BorderFactory.createEmptyBorder());\n            implToolbar.setOpaque(false);\n            implToolbar.putClientProperty(\"Toolbar.noGTKBorder\", Boolean.TRUE); // NOI18N\n            return add(implToolbar, index);\n        }\n        \n        @Override\n        public void remove(ProfilerToolbar toolbar) {\n            remove(((Impl)toolbar).toolbar);\n        }\n\n        @Override\n        public Component add(Action action) {\n            Component c = toolbar.add(action);\n            tweakComponent(c);\n            toolbar.repaint();\n            return c;\n        }\n\n        @Override\n        public Component add(Component component) {\n            Component c = toolbar.add(component);\n            tweakComponent(c);\n            toolbar.repaint();\n            return c;\n        }\n        \n        @Override\n        public Component add(Component component, int index) {\n            Component c = toolbar.add(component, index);\n            tweakComponent(c);\n            toolbar.repaint();\n            return c;\n        }\n\n        @Override\n        public void addSeparator() {\n            toolbar.addSeparator();\n            toolbar.repaint();\n        }\n        \n        @Override\n        public void addSpace(int width) {\n            toolbar.addSeparator(new Dimension(width, 0));\n            toolbar.repaint();\n        }\n        \n        @Override\n        public void addFiller() {\n            Dimension minDim = new Dimension(0, 0);\n            Dimension maxDim = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);\n            toolbar.add(new Box.Filler(minDim, minDim, maxDim));\n            toolbar.repaint();\n        }\n        \n        @Override\n        public void remove(Component component) {\n            toolbar.remove(component);\n            toolbar.repaint();\n        }\n        \n        @Override\n        public void remove(int index) {\n            toolbar.remove(index);\n            toolbar.repaint();\n        }\n        \n        @Override\n        public int getComponentCount() {\n            return toolbar.getComponentCount();\n        }\n        \n        \n        private void tweakComponent(Component c) {\n            if (c instanceof JComponent) ((JComponent)c).setOpaque(false);\n        }\n        \n    }\n    \n    \n    public static class SimpleFocusTraversalPolicy extends FocusTraversalPolicy {\n        \n        public Component getComponentAfter(Container aContainer, Component aComponent) {\n            List<Component> l = components(topContainer(aContainer));\n            int i = l.indexOf(aComponent);\n            return i == -1 || i == l.size() - 1 ? null : l.get(i + 1);\n        }\n\n        public Component getComponentBefore(Container aContainer, Component aComponent) {\n            List<Component> l = components(topContainer(aContainer));\n            int i = l.indexOf(aComponent);\n            return i == -1 || i == 0 ? null : l.get(i - 1);\n        }\n\n        public Component getFirstComponent(Container aContainer) {\n            List<Component> l = components(topContainer(aContainer));\n            return l.isEmpty() ? null : l.get(0);\n        }\n\n        public Component getLastComponent(Container aContainer) {\n            List<Component> l = components(topContainer(aContainer));\n            return l.isEmpty() ? null : l.get(l.size() - 1);\n        }\n\n        public Component getDefaultComponent(Container aContainer) {\n            return getFirstComponent(aContainer);\n        }\n\n        protected Container topContainer(Container aContainer) {\n            while (aContainer.getParent() instanceof JToolBar)\n                aContainer = aContainer.getParent();\n            return aContainer;\n        }\n\n        protected List<Component> components(Container aContainer) {\n            List<Component> l = new ArrayList<>();\n\n            for (int i = 0; i < aContainer.getComponentCount(); i++) {\n                Component c = aContainer.getComponent(i);\n                if (c instanceof JToolBar || c instanceof JPanel)\n                    l.addAll(components((Container)c));\n                else if (focusable(c)) l.add(c);\n            }\n\n            return l;\n        }\n        \n        protected boolean focusable(Component c) {\n            return c.isVisible() && c.isEnabled() && c.isFocusable();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/SnippetPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.FocusListener;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.KeyListener;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport javax.swing.*;\nimport javax.swing.plaf.ComponentUI;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\npublic class SnippetPanel extends JPanel implements MouseListener, KeyListener, FocusListener {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class Padding extends JPanel {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        public Padding() {\n            setBackground(UIUtils.getProfilerResultsBackground());\n            setOpaque(true);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        protected void paintComponent(Graphics g) {\n            super.paintComponent(g);\n            g.setColor(lineColor);\n            g.drawLine(0, 0, getWidth(), 0);\n        }\n    }\n\n    private static class Title extends JPanel {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        String name;\n        private boolean collapsed;\n        private boolean rollOver;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        private Title(String name) {\n            this.name = name;\n            setUI(new TitleUI());\n            getAccessibleContext().setAccessibleName(name);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void setRollOver(boolean rollOver) {\n            if (rollOver == this.rollOver) {\n                return;\n            }\n\n            this.rollOver = rollOver;\n            repaint();\n        }\n\n        public void collapse() {\n            collapsed = true;\n            repaint();\n        }\n\n        public void expand() {\n            collapsed = false;\n            repaint();\n        }\n    }\n\n    private static class TitleUI extends ComponentUI {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private final int TITLE_X_OFFSET = 5;\n        private final int TITLE_Y_OFFSET = 2;\n\n        private final ImageIcon collapsedIcon = Icons.getImageIcon(GeneralIcons.COLLAPSED_SNIPPET);\n        private final ImageIcon expandedIcon = Icons.getImageIcon(GeneralIcons.EXPANDED_SNIPPET);\n        private final JLabel plainPainter = new JLabel();\n        private final JLabel boldPainter = new JLabel();\n        private final Font plainFont = plainPainter.getFont().deriveFont(Font.PLAIN);\n        private final Font boldFont = boldPainter.getFont().deriveFont(Font.BOLD);\n        private Dimension preferredSize;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public Dimension getPreferredSize(JComponent c) {\n            return preferredSize;\n        }\n\n        public void installUI(JComponent c) {\n            plainPainter.setText(((Title)c).name);\n            plainPainter.setIcon(collapsedIcon);\n            plainPainter.setFont(plainFont);\n            plainPainter.setIconTextGap(5);\n            boldPainter.setText(((Title)c).name);\n            boldPainter.setIcon(expandedIcon);\n            boldPainter.setFont(boldFont);\n            boldPainter.setIconTextGap(5);\n\n            plainPainter.setSize(plainPainter.getPreferredSize());\n            Dimension titlePreferredSize = boldPainter.getPreferredSize();\n            boldPainter.setSize(titlePreferredSize);\n            preferredSize = new Dimension(TITLE_X_OFFSET + titlePreferredSize.width,\n                                          titlePreferredSize.height + TITLE_Y_OFFSET * 2);\n        }\n\n        public void paint(Graphics g, JComponent c) {\n\n            Title title = (Title)c;\n\n            g.setColor(lineColor);\n            g.drawLine(0, 0, c.getWidth(), 0);\n\n            if (title.collapsed) { // do not draw bottom line if collapsed\n\n                if (title.rollOver || title.isFocusOwner()) {\n                    g.setColor(focusedBackgroundColor);\n                } else {\n                    g.setColor(backgroundColor);\n                }\n            }\n\n            g.drawLine(0, 1 + plainPainter.getHeight() + TITLE_Y_OFFSET,\n                       c.getWidth(), 1 + plainPainter.getHeight() + TITLE_Y_OFFSET);\n\n            if (title.rollOver || title.isFocusOwner()) {\n                g.setColor(focusedBackgroundColor);\n            } else {\n                g.setColor(backgroundColor);\n            }\n\n            g.fillRect(0, 1, c.getWidth(), plainPainter.getHeight() + TITLE_Y_OFFSET);\n\n            g.translate(TITLE_X_OFFSET, TITLE_Y_OFFSET);\n            if (title.collapsed) {\n                plainPainter.paint(g);\n            } else {\n                boldPainter.paint(g);\n            }\n            g.translate(-TITLE_X_OFFSET, -TITLE_Y_OFFSET);\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static Color lineColor;\n    private static Color backgroundColor;\n    private static Color focusedBackgroundColor;\n    \n    static { initColors(); }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JComponent content;\n    private String snippetName;\n    private Title title;\n    private boolean collapsed = false;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SnippetPanel(String snippetName, JComponent content) {\n        this.snippetName = snippetName;\n        this.content = content;\n        setLayout(new BorderLayout());\n        title = new Title(snippetName);\n        title.setFocusable(true);\n        title.addKeyListener(this);\n        title.addMouseListener(this);\n        title.addFocusListener(this);\n        // transfer the tooltip from the content to the snippet panel\n        title.setToolTipText(content.getToolTipText());\n        content.setToolTipText(null);\n        //**\n        add(title, BorderLayout.NORTH);\n        add(content, BorderLayout.CENTER);\n        getAccessibleContext().setAccessibleName(snippetName);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    private static void initColors() {\n        Color systemBackgroundColor = UIUtils.getProfilerResultsBackground();\n        \n        int backgroundRed = systemBackgroundColor.getRed(); \n        int backgroundGreen = systemBackgroundColor.getGreen();\n        int backgroundBlue = systemBackgroundColor.getBlue();\n        boolean inverseColors = backgroundRed < 41 || backgroundGreen < 32 || backgroundBlue < 25;\n\n        if (inverseColors) {\n            lineColor = UIUtils.getSafeColor(backgroundRed + 41, backgroundGreen + 32, backgroundBlue + 8);\n            backgroundColor = UIUtils.getSafeColor(backgroundRed + 7, backgroundGreen + 7, backgroundBlue + 7);\n            focusedBackgroundColor = UIUtils.getSafeColor(backgroundRed + 25, backgroundGreen + 25, backgroundBlue + 25);\n        } else {\n            lineColor = UIUtils.getSafeColor(backgroundRed - 41 /*214*/, backgroundGreen - 32 /*223*/, backgroundBlue - 8 /*247*/);\n            backgroundColor = UIUtils.getSafeColor(backgroundRed - 7 /*248*/, backgroundGreen - 7 /*248*/, backgroundBlue - 7 /*248*/);\n            focusedBackgroundColor = UIUtils.getSafeColor(backgroundRed - 25 /*230*/, backgroundGreen - 25 /*230*/, backgroundBlue - 25 /*230*/);\n        }\n    }\n\n    public void setCollapsed(boolean collapsed) {\n        if (this.collapsed == collapsed) {\n            return;\n        }\n\n        this.collapsed = collapsed;\n\n        if (collapsed) {\n            title.collapse();\n        } else {\n            title.expand();\n        }\n\n        content.setVisible(!collapsed);\n        revalidate();\n    }\n\n    public boolean isCollapsed() {\n        return collapsed;\n    }\n\n    public void setContent(JComponent content) {\n        this.content = content;\n    }\n\n    public JComponent getContent() {\n        return content;\n    }\n\n    public void setSnippetName(String snippetName) {\n        this.snippetName = snippetName;\n    }\n\n    public String getSnippetName() {\n        return snippetName;\n    }\n\n    public void focusGained(FocusEvent e) {\n        title.repaint();\n    }\n\n    public void focusLost(FocusEvent e) {\n        title.repaint();\n    }\n\n    public void keyPressed(final KeyEvent evt) {\n        if (evt.getKeyCode() == KeyEvent.VK_SPACE) {\n            setCollapsed(!isCollapsed());\n        }\n    }\n\n    public void keyReleased(final KeyEvent evt) {\n    } // not used\n\n    public void keyTyped(final KeyEvent evt) {\n    } // not used\n\n    public void mouseClicked(MouseEvent e) {\n    } // not used\n\n    public void mouseEntered(MouseEvent e) {\n        title.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n        title.setRollOver(true);\n    }\n\n    public void mouseExited(MouseEvent e) {\n        title.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));\n        title.setRollOver(false);\n    }\n\n    public void mousePressed(MouseEvent e) {\n        setCollapsed(!collapsed);\n        requestFocus();\n    }\n\n    public void mouseReleased(MouseEvent e) {\n    } // not used\n\n    public void requestFocus() {\n        if (title != null) {\n            title.requestFocus();\n        }\n    }\n\n    /*public static void main (String args[]) {\n       try {\n         UIManager.setLookAndFeel(\"com.sun.java.swing.plaf.windows.WindowsLookAndFeel\");\n       } catch (ClassNotFoundException e) {\n         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.\n       } catch (InstantiationException e) {\n         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.\n       } catch (IllegalAccessException e) {\n         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.\n       } catch (UnsupportedLookAndFeelException e) {\n         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.\n       }\n       JFrame jf = new JFrame ();\n       jf.setSize(400, 400);\n       jf.getContentPane().setLayout(new GridBagLayout());\n       JPanel content = new JPanel (); content.setBackground(Color.WHITE); content.setOpaque(true);\n       JPanel content2 = new JPanel (); content2.setBackground(Color.WHITE); content2.setOpaque(true);\n       JPanel content3 = new JPanel (); content3.setBackground(Color.WHITE); content3.setOpaque(true);\n       JPanel content4 = new JPanel (); content4.setBackground(Color.WHITE); content4.setOpaque(true);\n       JPanel content5 = new JPanel (); content5.setBackground(Color.WHITE); content5.setOpaque(true);\n       JPanel padding = new JPanel (); padding.setBackground(Color.WHITE); padding.setOpaque(true);\n       GridBagConstraints gbc = new GridBagConstraints();\n       gbc.gridwidth = GridBagConstraints.REMAINDER;\n       gbc.fill = GridBagConstraints.BOTH;\n       gbc.weightx = 1;\n       jf.getContentPane().add (new SnippetPanel (\"Controls\", content), gbc);\n       jf.getContentPane().add (new SnippetPanel (\"Status\", content2), gbc);\n       jf.getContentPane().add (new SnippetPanel (\"View\", content3), gbc);\n       jf.getContentPane().add (new SnippetPanel (\"Snapshots\", content4), gbc);\n       jf.getContentPane().add (new SnippetPanel (\"Timeline\", content5), gbc);\n       gbc.weighty = 1;\n       jf.getContentPane().add (padding, gbc);\n       jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n       jf.show();\n       }\n     */\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/ThinBevelBorder.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Graphics;\nimport javax.swing.border.BevelBorder;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ThinBevelBorder extends BevelBorder {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ThinBevelBorder(int bevelType) {\n        super(bevelType);\n    }\n\n    public ThinBevelBorder(int bevelType, Color highlight, Color shadow) {\n        super(bevelType, highlight, shadow);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    protected void paintLoweredBevel(Component c, Graphics g, int x, int y, int width, int height) {\n        Color oldColor = g.getColor();\n        int h = height;\n        int w = width;\n\n        g.translate(x, y);\n\n        g.setColor(getShadowInnerColor(c));\n        g.drawLine(0, 0, 0, h - 1);\n        g.drawLine(1, 0, w - 1, 0);\n\n        g.setColor(getHighlightOuterColor(c));\n        g.drawLine(1, h - 1, w - 1, h - 1);\n        g.drawLine(w - 1, 1, w - 1, h - 2);\n\n        g.translate(-x, -y);\n        g.setColor(oldColor);\n    }\n\n    protected void paintRaisedBevel(Component c, Graphics g, int x, int y, int width, int height) {\n        Color oldColor = g.getColor();\n        int h = height;\n        int w = width;\n\n        g.translate(x, y);\n\n        g.setColor(getHighlightOuterColor(c));\n        g.drawLine(0, 0, 0, h - 2);\n        g.drawLine(1, 0, w - 2, 0);\n\n        g.setColor(getShadowOuterColor(c));\n        g.drawLine(0, h - 1, w - 1, h - 1);\n        g.drawLine(w - 1, 0, w - 1, h - 2);\n\n        g.translate(-x, -y);\n        g.setColor(oldColor);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/VerticalLayout.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class VerticalLayout implements LayoutManager {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int hgap;\n    private int vgap;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public VerticalLayout() {\n        this(10, 10);\n    }\n\n    public VerticalLayout(int hgap, int vgap) {\n        this.hgap = hgap;\n        this.vgap = vgap;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getHGap() {\n        return hgap;\n    }\n\n    public int getVGap() {\n        return vgap;\n    }\n\n    public void addLayoutComponent(String name, Component comp) {\n    }\n\n    public void layoutContainer(Container container) {\n        synchronized (container.getTreeLock()) {\n            Insets insets = container.getInsets();\n\n            int x = insets.left + hgap;\n            int y = insets.top + vgap;\n            int w = container.getSize().width - insets.left - insets.right - (2 * hgap);\n            int h;\n\n            for (int i = 0; i < container.getComponentCount(); i++) {\n                Component component = container.getComponent(i);\n\n                if (component.isVisible()) {\n                    h = component.getPreferredSize().height;\n                    component.setBounds(x, y, w, h);\n                    y += (h + vgap);\n                }\n            }\n        }\n    }\n\n    public Dimension minimumLayoutSize(Container container) {\n        return preferredLayoutSize(container);\n    }\n\n    public Dimension preferredLayoutSize(Container container) {\n        synchronized (container.getTreeLock()) {\n            Insets insets = container.getInsets();\n\n            int width = insets.left + insets.right + (2 * hgap);\n            int height = insets.top + insets.bottom + vgap;\n\n            for (int i = 0; i < container.getComponentCount(); i++) {\n                Component component = container.getComponent(i);\n\n                if (component.isVisible()) {\n                    Dimension preferredDim = component.getPreferredSize();\n                    width = Math.max(width, preferredDim.width + insets.left + insets.right + (2 * hgap));\n                    height += (preferredDim.height + vgap);\n                }\n            }\n\n            return new Dimension(width, height);\n        }\n    }\n\n    public void removeLayoutComponent(Component comp) {\n    }\n\n    public String toString() {\n        return getClass().getName() + \"[hgap=\" + hgap + \", vgap=\" + vgap + \"]\"; // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/XPStyleBorder.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components;\n\nimport java.awt.*;\nimport javax.swing.border.AbstractBorder;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n *\n * @author  Jiri Sedlacek\n */\npublic class XPStyleBorder extends AbstractBorder {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static boolean isNimbus = UIUtils.isNimbus();\n\n    public static final int BORDER_STATE_DEFAULT = 10;\n    public static final int BORDER_STATE_FOCUSED = 20;\n    public static final int BORDER_STATE_SELECTED = 30;\n    private static final Color OUTLINE_CLR = new Color(0, 0, 0);\n    private static final Color FOCUSED_TOP_LIGHT_CLR = isNimbus ? new Color(200, 212, 222) : new Color(206, 231, 255);\n    private static final Color FOCUSED_TOP_DARK_CLR = isNimbus ? new Color(200, 212, 222) : new Color(188, 212, 246);\n    private static final Color FOCUSED_BOTTOM_LIGHT_CLR = isNimbus ? new Color(200, 212, 222) : new Color(137, 173, 228);\n    private static final Color FOCUSED_BOTTOM_DARK_CLR = isNimbus ? new Color(200, 212, 222) : new Color(105, 130, 238);\n    private static final Color SELECTED_TOP_LIGHT_CLR = isNimbus ? new Color(182, 203, 222) : new Color(255, 240, 207);\n    private static final Color SELECTED_TOP_DARK_CLR = isNimbus ? new Color(182, 203, 222) : new Color(253, 216, 137);\n    private static final Color SELECTED_BOTTOM_LIGHT_CLR = isNimbus ? new Color(182, 203, 222) : new Color(248, 178, 48);\n    private static final Color SELECTED_BOTTOM_DARK_CLR = isNimbus ? new Color(182, 203, 222) : new Color(229, 151, 0);\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Color DEFAULT_BOTTOM_DARK_CLR;\n    private Color DEFAULT_BOTTOM_LIGHT_CLR;\n    private Color DEFAULT_TOP_DARK_CLR;\n    private Color DEFAULT_TOP_LIGHT_CLR;\n    private Color backgroundColor;\n    private Color backgroundFade;\n    private Color startColor;\n    private Color stopColor;\n    private int borderState;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of CustomTaskButtonBorder */\n    public XPStyleBorder(Color foreground, Color background) {\n        super();\n        setForegroundColor(foreground);\n        setBackgroundColor(background);\n        setSelected();\n    }\n\n    public XPStyleBorder(Color foreground, Color background, int state) {\n        this(foreground, background);\n        setBorderState(state);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setBackgroundColor(Color background) {\n        backgroundColor = background;\n        backgroundFade = UIUtils.getSafeColor(((3 * background.getRed()) + (1 * OUTLINE_CLR.getRed())) / 4,\n                                              ((3 * background.getGreen()) + (1 * OUTLINE_CLR.getGreen())) / 4,\n                                              ((3 * background.getBlue()) + (1 * OUTLINE_CLR.getBlue())) / 4);\n    }\n\n    public Color getBackgroundColor() {\n        return backgroundColor;\n    }\n\n    public static Insets getBorderInsets() {\n        return new Insets(4, 4, 4, 4);\n    }\n\n    public static XPStyleBorder getDefaultInstance(Color foreground, Color background) {\n        return new XPStyleBorder(foreground, background, BORDER_STATE_DEFAULT);\n    }\n\n    public static XPStyleBorder getFocusedInstance(Color foreground, Color background) {\n        return new XPStyleBorder(foreground, background, BORDER_STATE_FOCUSED);\n    }\n\n    public Insets getBorderInsets(Component c) {\n        return XPStyleBorder.getBorderInsets();\n    }\n\n    public boolean isBorderOpaque() {\n        return false;\n    }\n\n    public void setBorderState(int state) {\n        borderState = state;\n    }\n\n    public int getBorderState() {\n        return borderState;\n    }\n\n    public void setFocused() {\n        setBorderState(XPStyleBorder.BORDER_STATE_FOCUSED);\n    }\n\n    public boolean isFocused() {\n        return getBorderState() == XPStyleBorder.BORDER_STATE_FOCUSED;\n    }\n\n    public void setForegroundColor(Color foreground) {\n        DEFAULT_TOP_LIGHT_CLR = UIUtils.getSafeColor(foreground.getRed() + 15, foreground.getGreen() + 15,\n                                                     foreground.getBlue() + 15);\n        DEFAULT_TOP_DARK_CLR = UIUtils.getSafeColor(foreground.getRed() + 8, foreground.getGreen() + 8, foreground.getBlue() + 8);\n        DEFAULT_BOTTOM_LIGHT_CLR = UIUtils.getSafeColor(foreground.getRed() - 11, foreground.getGreen() - 11,\n                                                        foreground.getBlue() - 11);\n        DEFAULT_BOTTOM_DARK_CLR = UIUtils.getSafeColor(foreground.getRed() - 25, foreground.getGreen() - 25,\n                                                       foreground.getBlue() - 25);\n    }\n\n    public Color getForegroundColor() {\n        return UIUtils.getSafeColor(Math.max(DEFAULT_TOP_LIGHT_CLR.getRed() - 15, 0),\n                                    Math.max(DEFAULT_TOP_LIGHT_CLR.getGreen() - 15, 0),\n                                    Math.max(DEFAULT_TOP_LIGHT_CLR.getBlue() - 15, 0));\n    }\n\n    public static XPStyleBorder getSelectedInstance(Color foreground, Color background) {\n        return new XPStyleBorder(foreground, background, BORDER_STATE_SELECTED);\n    }\n\n    public void setDefault() {\n        setBorderState(XPStyleBorder.BORDER_STATE_DEFAULT);\n    }\n\n    public boolean isDefault() {\n        return getBorderState() == XPStyleBorder.BORDER_STATE_DEFAULT;\n    }\n\n    public void setSelected() {\n        setBorderState(XPStyleBorder.BORDER_STATE_SELECTED);\n    }\n\n    public boolean isSelected() {\n        return getBorderState() == XPStyleBorder.BORDER_STATE_SELECTED;\n    }\n\n    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {\n        if (!(g instanceof Graphics2D)) {\n            return;\n        }\n\n        Graphics2D g2d = (Graphics2D) g;\n\n        // Background points for \"rounded\" edges\n        g2d.setColor(backgroundColor);\n        g2d.drawLine(x, y, x, y);\n        g2d.drawLine(x, (y + height) - 1, x, (y + height) - 1);\n        g2d.drawLine((x + width) - 1, y, (x + width) - 1, y);\n        g2d.drawLine((x + width) - 1, (y + height) - 1, (x + width) - 1, (y + height) - 1);\n\n        // Fade points for smooth \"rounded\" edges\n        g2d.setColor(backgroundFade);\n        g2d.drawLine(x + 1, y, x + 1, y);\n        g2d.drawLine(x, y + 1, x, y + 1);\n        g2d.drawLine(x + 1, (y + height) - 1, x + 1, (y + height) - 1);\n        g2d.drawLine(x, (y + height) - 2, x, (y + height) - 2);\n        g2d.drawLine((x + width) - 1, y + 1, (x + width) - 1, y + 1);\n        g2d.drawLine((x + width) - 2, y, (x + width) - 2, y);\n        g2d.drawLine((x + width) - 2, (y + height) - 1, (x + width) - 2, (y + height) - 1);\n        g2d.drawLine((x + width) - 1, (y + height) - 2, (x + width) - 1, (y + height) - 2);\n\n        // Points connecting outer black borders\n        g2d.setColor(OUTLINE_CLR);\n        g2d.drawLine(x + 1, y + 1, x + 1, y + 1);\n        g2d.drawLine((x + width) - 2, y + 1, (x + width) - 2, y + 1);\n        g2d.drawLine(x + 1, (y + height) - 2, x + 1, (y + height) - 2);\n        g2d.drawLine((x + width) - 2, (y + height) - 2, (x + width) - 2, (y + height) - 2);\n\n        // Outer black borders\n        g2d.setColor(OUTLINE_CLR);\n        g2d.drawLine(x + 2, y, (x + width) - 3, y);\n        g2d.drawLine(x, y + 2, x, (y + height) - 3);\n        g2d.drawLine((x + width) - 1, y + 2, (x + width) - 1, (y + height) - 3);\n        g2d.drawLine(x + 2, (y + height) - 1, (x + width) - 3, (y + height) - 1);\n\n        // Top light line\n        switch (borderState) {\n            case BORDER_STATE_DEFAULT:\n                g2d.setColor(DEFAULT_TOP_LIGHT_CLR);\n\n                break;\n            case BORDER_STATE_FOCUSED:\n                g2d.setColor(FOCUSED_TOP_LIGHT_CLR);\n\n                break;\n            case BORDER_STATE_SELECTED:\n                g2d.setColor(SELECTED_TOP_LIGHT_CLR);\n\n                break;\n        }\n\n        g.drawLine(x + 2, y + 1, (x + width) - 3, y + 1);\n\n        // Top dark lines\n        switch (borderState) {\n            case BORDER_STATE_DEFAULT:\n                g2d.setColor(DEFAULT_TOP_DARK_CLR);\n\n                break;\n            case BORDER_STATE_FOCUSED:\n                g2d.setColor(FOCUSED_TOP_DARK_CLR);\n\n                break;\n            case BORDER_STATE_SELECTED:\n                g2d.setColor(SELECTED_TOP_DARK_CLR);\n\n                break;\n        }\n\n        g2d.drawLine(x + 1, y + 2, (x + width) - 2, y + 2);\n        g2d.drawLine(x + 1, y + 3, (x + width) - 2, y + 3);\n\n        // Bottom light lines\n        switch (borderState) {\n            case BORDER_STATE_DEFAULT:\n                g2d.setColor(DEFAULT_BOTTOM_LIGHT_CLR);\n\n                break;\n            case BORDER_STATE_FOCUSED:\n                g2d.setColor(FOCUSED_BOTTOM_LIGHT_CLR);\n\n                break;\n            case BORDER_STATE_SELECTED:\n                g2d.setColor(SELECTED_BOTTOM_LIGHT_CLR);\n\n                break;\n        }\n\n        g2d.drawLine(x + 1, (y + height) - 4, (x + width) - 2, (y + height) - 4);\n        g2d.drawLine(x + 1, (y + height) - 3, (x + width) - 2, (y + height) - 3);\n\n        // Bottom dark line\n        switch (borderState) {\n            case BORDER_STATE_DEFAULT:\n                g2d.setColor(DEFAULT_BOTTOM_DARK_CLR);\n\n                break;\n            case BORDER_STATE_FOCUSED:\n                g2d.setColor(FOCUSED_BOTTOM_DARK_CLR);\n\n                break;\n            case BORDER_STATE_SELECTED:\n                g2d.setColor(SELECTED_BOTTOM_DARK_CLR);\n\n                break;\n        }\n\n        g2d.drawLine(x + 2, (y + height) - 2, (x + width) - 3, (y + height) - 2);\n\n        // Side gradients\n        switch (borderState) {\n            case BORDER_STATE_DEFAULT:\n                startColor = DEFAULT_TOP_DARK_CLR;\n                stopColor = DEFAULT_BOTTOM_LIGHT_CLR;\n\n                break;\n            case BORDER_STATE_FOCUSED:\n                startColor = FOCUSED_TOP_DARK_CLR;\n                stopColor = FOCUSED_BOTTOM_LIGHT_CLR;\n\n                break;\n            case BORDER_STATE_SELECTED:\n                startColor = SELECTED_TOP_DARK_CLR;\n                stopColor = SELECTED_BOTTOM_LIGHT_CLR;\n\n                break;\n        }\n\n        g2d.setPaint(new GradientPaint(x + 1, y + 3, startColor, x + 1, (y + height) - 5, stopColor));\n        g2d.fillRect(x + 1, y + 3, 3, height - 7);\n        g2d.fillRect((x + width) - 4, y + 3, 3, height - 7);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/BooleanTableCellRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\nimport java.awt.*;\nimport javax.swing.*;\n\n\n/**\n *\n * @author  Jiri Sedlacek\n */\npublic class BooleanTableCellRenderer extends EnhancedTableCellRenderer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JCheckBox checkBox;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of BooleanTableCellRenderer */\n    public BooleanTableCellRenderer() {\n        super();\n        super.setLayout(new BorderLayout(0, 0));\n\n        checkBox = new JCheckBox();\n        checkBox.setHorizontalAlignment(JCheckBox.CENTER);\n        checkBox.setOpaque(false);\n\n        add(checkBox, BorderLayout.CENTER);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Component getTableCellRendererComponentPersistent(JTable table, Object value, boolean isSelected, boolean hasFocus,\n                                                             int row, int column) {\n        return null;\n    }\n\n    protected void setState(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {\n        if ((supportsFocusBorder) && (hasFocus) && (isSelected)) {\n            checkBox.setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 0));\n        } else {\n            checkBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));\n        }\n    }\n\n    protected void setValue(javax.swing.JTable table, Object value, int row, int column) {\n        checkBox.setSelected(((value != null) && ((Boolean) value).booleanValue()));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/ClassNameTableCellRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\nimport java.awt.*;\nimport javax.swing.*;\n\n\n/** Enhanced Table cell rendered that paints text labels using provided text alignment\n *\n * @author Ian Formanek\n */\npublic class ClassNameTableCellRenderer extends EnhancedTableCellRenderer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JLabel label1;\n    private JLabel label2;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a default table cell renderer with LEADING horizontal alignment showing border when focused. */\n    public ClassNameTableCellRenderer() {\n        this(JLabel.LEADING);\n    }\n\n    public ClassNameTableCellRenderer(int horizontalAlignment) {\n        setHorizontalAlignment(horizontalAlignment);\n        label1 = new JLabel(\"\", horizontalAlignment); // NOI18N\n        label2 = new JLabel(\"\", horizontalAlignment); // NOI18N\n\n        Font f = label2.getFont();\n        label2.setFont(f.deriveFont(Font.BOLD));\n\n        setLayout(new BorderLayout());\n\n        if (horizontalAlignment == JLabel.LEADING) {\n            add(label1, BorderLayout.WEST);\n            add(label2, BorderLayout.CENTER);\n        } else {\n            add(label1, BorderLayout.CENTER);\n            add(label2, BorderLayout.EAST);\n        }\n\n        setBorder(BorderFactory.createEmptyBorder(1, 3, 1, 3));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Component getTableCellRendererComponentPersistent(JTable table, Object value, boolean isSelected, boolean hasFocus,\n                                                             int row, int column) {\n        return new ClassNameTableCellRenderer(label1.getHorizontalAlignment()).getTableCellRendererComponent(table, value,\n                                                                                                             isSelected,\n                                                                                                             hasFocus, row, column);\n    }\n\n    protected void setRowForeground(Color c) {\n        super.setRowForeground(c);\n        label1.setForeground(c);\n        label2.setForeground(c);\n    }\n\n    protected void setValue(JTable table, Object value, int row, int column) {\n        if (table != null) {\n            setFont(table.getFont());\n        }\n\n        if (value != null) {\n            String str = value.toString();\n            label1.setText(str.substring(0, str.lastIndexOf('.') + 1)); // NOI18N\n            label2.setText(str.substring(str.lastIndexOf('.') + 1)); // NOI18N\n        } else {\n            label1.setText(\"\"); // NOI18N\n            label2.setText(\"\"); // NOI18N\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/CustomBarCellRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\nimport java.awt.*;\nimport javax.swing.*;\n\n\n/** Custom Table cell renderer that paints a bar based on numerical value within min/max bounds.\n *\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic class CustomBarCellRenderer extends EnhancedTableCellRenderer {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final Color BAR_FOREGROUND_COLOR = new Color(195, 41, 41);\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected double relValue; // relative part of max - min, <0, 1>\n    protected long max;\n    protected long min;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CustomBarCellRenderer(long min, long max) {\n        setMinimum(min);\n        setMaximum(max);\n        setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setMaximum(long n) {\n        max = n;\n    }\n\n    public void setMinimum(long n) {\n        min = n;\n    }\n\n    public void setRelValue(double n) {\n        relValue = n;\n    }\n\n    public Component getTableCellRendererComponentPersistent(JTable table, Object value, boolean isSelected, boolean hasFocus,\n                                                             int row, int column) {\n        return null;\n    }\n\n    public void paintComponent(Graphics g) {\n        super.paintComponent(g);\n\n        Insets insets = getInsets();\n        g.setColor(BAR_FOREGROUND_COLOR);\n        g.fillRect(insets.left, insets.top, (int) Math.round(relValue * (getWidth() - insets.right - insets.left)),\n                   getHeight() - insets.bottom - insets.top);\n    }\n\n    /**\n     * Called each time this renderer is to be used to render a specific value on specified row/column.\n     * Subclasses need to implement this method to render the value.\n     *\n     * @param table  the table in which the rendering occurs\n     * @param value  the value to be rendered\n     * @param row    the row at which the value is located\n     * @param column the column at which the value is located\n     */\n    protected void setValue(JTable table, Object value, int row, int column) {\n        if (value instanceof Long) {\n            //multiplying by 10 to allow displaying graphs for values < 1\n            // - same done for maxi and min values of progress bar, should be ok\n            setRelValue(calculateViewValue(((Long) value).longValue()));\n        } else if (value instanceof Number) {\n            //multiplying by 10 to allow displaying graphs for values < 1\n            // - same done for maxi and min values of progress bar, should be ok\n            setRelValue(calculateViewValue(((Number) value).doubleValue()));\n        } else if (value instanceof String) {\n            //multiplying by 10 to allow displaying graphs for values < 1\n            // - same done for maxi and min values of progress bar, should be ok\n            setRelValue(calculateViewValue(Double.parseDouble((String) value)));\n        } else {\n            setRelValue(min);\n        }\n    }\n\n    protected double calculateViewValue(long n) {\n        return (double) (n - min) / (double) (max - min);\n    }\n\n    protected double calculateViewValue(double n) {\n        return (double) (n - min) / (double) (max - min);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/CustomSortableHeaderRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\nimport java.awt.*;\nimport javax.swing.*;\nimport javax.swing.table.TableCellRenderer;\n\n\n/**\n * This class is used for rendering the JTable header. It also holds information about current sorting column and sorting order.\n * The column header is rendered by the JButton using the appropriate icon.\n * @author Jiri Sedlacek\n */\npublic class CustomSortableHeaderRenderer implements TableCellRenderer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ImageIcon ascIcon;\n    private ImageIcon descIcon;\n    private boolean sortOrder = SortableTableModel.SORT_ORDER_DESC;\n\n    /**\n     * The column which is currently being pressed.\n     * The button has to be pressed programmatically because the mouse events are not delivered to the JButton from the table header.\n     */\n    private int pressedColumn = -1;\n\n    /**\n     * The column which currently defines the sorting order. Only this column header contains the appropriate icon.\n     */\n    private int sortingColumn = -1;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new instance of CustomSortableHeaderRenderer\n     * @param asc The icon representing ascending sort order.\n     * @param desc The icon representing descending sort order.\n     */\n    public CustomSortableHeaderRenderer(ImageIcon asc, ImageIcon desc) {\n        ascIcon = asc;\n        descIcon = desc;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setPressedColumn(int column) {\n        pressedColumn = column;\n    }\n\n    public int getPressedColumn() {\n        return pressedColumn;\n    }\n\n    public void setSortingColumn(int column) {\n        sortingColumn = column;\n    }\n\n    public int getSortingColumn() {\n        return sortingColumn;\n    }\n\n    public void setSortingOrder(boolean order) {\n        sortOrder = order;\n    }\n\n    public boolean getSortingOrder() {\n        return sortOrder;\n    }\n\n    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,\n                                                   int column) {\n        TableCellRenderer tableCellRenderer = table.getTableHeader().getDefaultRenderer();\n        Component c = tableCellRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);\n\n        if (c instanceof JLabel) {\n            JLabel l = (JLabel) c;\n\n            if (column == sortingColumn) { // only for sorting column the icon is displayed\n                l.setIcon((sortOrder == SortableTableModel.SORT_ORDER_ASC) ? ascIcon : descIcon);\n                l.setFont(l.getFont().deriveFont(Font.BOLD));\n            } else {\n                l.setIcon(null);\n            }\n\n            l.setHorizontalTextPosition(JLabel.LEFT);\n        }\n\n        return c;\n    }\n\n    public void reverseSortingOrder() {\n        sortOrder = !sortOrder;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/DiffBarCellRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\nimport java.awt.*;\n\n\n/** Custom Table cell renderer that paints a bar based on numerical value within min/max bounds.\n *\n * @author Jiri Sedlacek\n */\npublic class DiffBarCellRenderer extends CustomBarCellRenderer {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final Color BAR_FOREGROUND2_COLOR = new Color(41, 195, 41);\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public DiffBarCellRenderer(long min, long max) {\n        super(min, max);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void paintComponent(Graphics g) {\n        g.setColor(getBackground());\n        g.fillRect(0, 0, getWidth(), getHeight());\n\n        Insets insets = getInsets();\n        int clientWidth = getWidth() - insets.right - insets.left;\n        int horizCenter = insets.left + (clientWidth / 2);\n        int barExtent = (int) Math.ceil((Math.abs(relValue) * ((double) clientWidth)) / 2d);\n\n        if (relValue > 0) {\n            g.setColor(BAR_FOREGROUND_COLOR);\n            g.fillRect(horizCenter, insets.top, barExtent, getHeight() - insets.bottom - insets.top);\n        } else if (relValue < 0) {\n            g.setColor(BAR_FOREGROUND2_COLOR);\n            g.fillRect(horizCenter - barExtent, insets.top, barExtent, getHeight() - insets.bottom - insets.top);\n        }\n    }\n\n    protected double calculateViewValue(long n) {\n        long absMax = Math.max(Math.abs(min), max);\n\n        return (double) (n) / (double) (absMax);\n    }\n\n    protected double calculateViewValue(double n) {\n        long absMax = Math.max(Math.abs(min), max);\n\n        return (double) (n) / (double) (absMax);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/EnhancedTableCellRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\nimport java.awt.*;\nimport javax.swing.*;\nimport javax.swing.border.Border;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/** An abstract superclass for table cell renderers to be used throughout the profiler.\n * It implements alrenating background colors for odd and even rows, and simplifies the writing of\n * concrete renderers by masking Swing's ugly CellRenderer API (by forcing \"this\" to be returned as the renderer).\n *\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic abstract class EnhancedTableCellRenderer extends JPanel implements TableCellRendererPersistent {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected boolean supportsFocusBorder;\n    private Border originalBorder;\n    private Color darkerUnselectedBackground;\n    private Color unselectedBackground;\n    private Color unselectedForeground;\n    private Insets originalBorderInsets;\n    private int horizontalAlignment;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a default table cell renderer with LEADING horizontal alignment showing border when focused.\n     *  Rendering of focused cell border is disabled by default, to enable it, use setSupportsFocusBorder(true).\n     */\n    public EnhancedTableCellRenderer() {\n        setOpaque(true);\n        supportsFocusBorder = false;\n        horizontalAlignment = SwingConstants.LEADING;\n        unselectedBackground = UIUtils.getProfilerResultsBackground();\n        darkerUnselectedBackground = UIUtils.getDarker(unselectedBackground);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setBorder(Border border) {\n        super.setBorder(border);\n        originalBorder = border;\n\n        if (originalBorder != null) {\n            originalBorderInsets = originalBorder.getBorderInsets(this);\n        }\n    }\n\n    public void setHorizontalAlignment(int horizontalAlignment) {\n        this.horizontalAlignment = horizontalAlignment;\n    }\n\n    public int getHorizontalAlignment() {\n        return horizontalAlignment;\n    }\n\n    /** Sets whether or not the renderer supports drawing border around the focused cell */\n    public void setSupportsFocusBorder(boolean supportsFocusBorder) {\n        this.supportsFocusBorder = supportsFocusBorder;\n\n        if ((supportsFocusBorder) && (originalBorder == null)) {\n            setBorder(BorderFactory.createEmptyBorder());\n        }\n    }\n\n    public boolean getSupportsFocusBorder() {\n        return supportsFocusBorder;\n    }\n\n    // ----------------------------------------------------------------------------\n    // Cell renderer functionality\n\n    /**\n     * Returns the default table cell renderer.\n     *\n     * @param table      the <code>JTable</code>\n     * @param value      the value to assign to the cell at\n     *                   <code>[row, column]</code>\n     * @param isSelected true if cell is selected\n     * @param hasFocus   true if cell has focus\n     * @param row        the row of the cell to render\n     * @param column     the column of the cell to render\n     * @return the default table cell renderer\n     */\n    public final Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,\n                                                         int row, int column) {\n        if (supportsFocusBorder) {\n            if ((hasFocus) && (isSelected) && (originalBorder != null)) {\n                Border focusBorder = BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(UIUtils.getDarkerLine(table\n                                                                                                                             .getSelectionBackground(),\n                                                                                                                             0.65f)),\n                                                                        BorderFactory.createEmptyBorder(originalBorderInsets.top,\n                                                                                                        originalBorderInsets.left\n                                                                                                        - 1,\n                                                                                                        originalBorderInsets.bottom,\n                                                                                                        originalBorderInsets.right));\n                super.setBorder(focusBorder);\n            } else {\n                super.setBorder(originalBorder);\n            }\n        }\n\n        if (isSelected && table.isEnabled()) {\n            setRowForeground(table.isFocusOwner() ? table.getSelectionForeground() : UIUtils.getUnfocusedSelectionForeground());\n            setRowBackground(table.isFocusOwner() ? table.getSelectionBackground() : UIUtils.getUnfocusedSelectionBackground());\n        } else if (!table.isEnabled()) {\n            setRowForeground(UIManager.getColor(\"TextField.inactiveForeground\")); // NOI18N\n            setRowBackground(UIManager.getColor(\"TextField.inactiveBackground\")); // NOI18N\n        } else {\n            if ((row & 0x1) == 0) { //even row\n                setRowForeground((unselectedForeground != null) ? unselectedForeground : table.getForeground());\n                setRowBackground((darkerUnselectedBackground != null) ? darkerUnselectedBackground\n                                                                      : UIUtils.getDarker(table.getBackground()));\n            } else {\n                setRowForeground((unselectedForeground != null) ? unselectedForeground : table.getForeground());\n                setRowBackground((unselectedBackground != null) ? unselectedBackground : table.getBackground());\n            }\n        }\n\n        setState(table, value, isSelected, hasFocus, row, column);\n        setValue(table, value, row, column);\n\n        return this;\n    }\n\n    /**\n     * Returns persistent (new) table cell renderer with provided parameters.\n     *\n     * @param table      the <code>JTable</code>\n     * @param value      the value to assign to the cell at\n     *                   <code>[row, column]</code>\n     * @param isSelected true if cell is selected\n     * @param hasFocus   true if cell has focus\n     * @param row        the row of the cell to render\n     * @param column     the column of the cell to render\n     * @return the default table cell renderer\n     */\n    public abstract Component getTableCellRendererComponentPersistent(JTable table, Object value, boolean isSelected,\n                                                                      boolean hasFocus, int row, int column);\n\n    // ----------------------------------------------------------------------------\n    // Private impl\n    public static Color getDarker(Color c) {\n        return UIUtils.getSafeColor((int) (c.getRed() - 30), (int) (c.getGreen() - 30), (int) (c.getBlue() - 30));\n    }\n\n    /**\n     * Called each time this renderer is to be used to render a specific row, with the color\n     * to be used for painting background of this row. The default implementation sets the\n     * background of the panel to this color, so this method does not need to be overridden unless\n     * the subclass has any opaque components placed into the panel that should alternate their background\n     * on each line and change on selected lines.\n     *\n     * @param c the color to be used for row background\n     */\n    protected void setRowBackground(Color c) {\n        setBackground(c);\n    }\n\n    // ----------------------------------------------------------------------------\n    // API for subclasses\n\n    /**\n     * Called each time this renderer is to be used to render a specific row, with the color\n     * to be used for painting foreground of this row (based on table's getSelectionForeground).\n     * The default implementation sets the foreground of the panel to this color.\n     * Subclasses should override this to meaningfully change the rendering when the selection changes.\n     *\n     * @param c the color to be used for row foreground\n     */\n    protected void setRowForeground(Color c) {\n        setForeground(c);\n    }\n\n    /**\n     * Called each time this renderer is to be used to render a specific value on specified row/column.\n     * Subclasses need to implement this method to render the value.\n     *\n     * @param table the table in which the rendering occurs\n     * @param value the value to be rendered\n     * @param row the row at which the value is located\n     * @param column the column at which the value is located\n     */\n    protected abstract void setValue(JTable table, Object value, int row, int column);\n\n    /**\n     * Called each time this renderer is to be used to render a specific value on specified row/column.\n     * Subclasses can override this method to set their states according to provided values.\n     *\n     * @param table      the <code>JTable</code>\n     * @param value      the value to assign to the cell at\n     *                   <code>[row, column]</code>\n     * @param isSelected true if cell is selected\n     * @param hasFocus   true if cell has focus\n     * @param row        the row of the cell to render\n     * @param column     the column of the cell to render\n     */\n    protected void setState(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/ExtendedTableModel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\n\n/**\n * Table model that extends SortableTableModel and allows to hide columns\n *\n * @author  Jiri Sedlacek\n */\npublic class ExtendedTableModel extends SortableTableModel {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private SortableTableModel realModel;\n    private int[] columnsMapping; // mapping virtual columns -> real columns\n    private boolean[] columnsVisibility; // visibility flags of real columns\n    private int realColumnsCount;\n    private int virtualColumnsCount;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ExtendedTableModel(SortableTableModel realModel) {\n        realColumnsCount = realModel.getColumnCount();\n        virtualColumnsCount = realColumnsCount;\n\n        this.realModel = realModel;\n        columnsMapping = new int[realColumnsCount];\n\n        boolean[] initialColumnsVisibility = new boolean[realColumnsCount];\n\n        for (int i = 0; i < realColumnsCount; i++) {\n            initialColumnsVisibility[i] = true;\n        }\n\n        setColumnsVisibility(initialColumnsVisibility);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Class<?> getColumnClass(int col) {\n        return realModel.getColumnClass(getRealColumn(col));\n    }\n\n    public int getColumnCount() {\n        return virtualColumnsCount;\n    }\n\n    //---------------------\n    // SortableTableModel interface\n    public String getColumnName(int col) {\n        return realModel.getColumnName(getRealColumn(col));\n    }\n\n    public String getColumnToolTipText(int columnIndex) {\n        return realModel.getColumnToolTipText(getRealColumn(columnIndex));\n    }\n\n    public void setColumnsVisibility(boolean[] columnsVisibility) {\n        this.columnsVisibility = columnsVisibility;\n        recomputeColumnsMapping();\n    }\n\n    public boolean[] getColumnsVisibility() {\n        return columnsVisibility;\n    }\n\n    public boolean getInitialSorting(int column) {\n        return realModel.getInitialSorting(getRealColumn(column));\n    }\n\n    public int getRealColumn(int column) {\n        return columnsMapping[column];\n    }\n\n    public void setRealColumnVisibility(int column, boolean visible) {\n        if (visible) {\n            showRealColumn(column);\n        } else {\n            hideRealColumn(column);\n        }\n    }\n\n    public boolean isRealColumnVisible(int column) {\n        return columnsVisibility[column];\n    }\n\n    public int getRowCount() {\n        return realModel.getRowCount();\n    }\n\n    public Object getValueAt(int rowIndex, int columnIndex) {\n        return realModel.getValueAt(rowIndex, getRealColumn(columnIndex));\n    }\n\n    public int getVirtualColumn(int column) {\n        for (int i = 0; i < virtualColumnsCount; i++) {\n            if (getRealColumn(i) == column) {\n                return i;\n            }\n        }\n\n        return -1;\n    }\n\n    public void hideRealColumn(int column) {\n        if (isRealColumnVisible(column)) {\n            columnsVisibility[column] = false;\n            recomputeColumnsMapping();\n        }\n    }\n\n    public void showRealColumn(int column) {\n        if (!isRealColumnVisible(column)) {\n            columnsVisibility[column] = true;\n            recomputeColumnsMapping();\n        }\n    }\n\n    public void sortByColumn(int column, boolean order) {\n        realModel.sortByColumn(getRealColumn(column), order);\n    }\n\n    private void recomputeColumnsMapping() {\n        virtualColumnsCount = 0;\n\n        int virtualColumnIndex = 0;\n\n        // set indexes virtual columns -> real columns\n        for (int i = 0; i < realColumnsCount; i++) {\n            if (columnsVisibility[i]) {\n                columnsMapping[virtualColumnIndex] = i;\n                virtualColumnsCount++;\n                virtualColumnIndex++;\n            }\n        }\n\n        // clear mappings of unused real columns\n        for (int i = virtualColumnIndex; i < realColumnsCount; i++) {\n            columnsMapping[i] = -1;\n        }\n        \n        fireTableStructureChanged();\n        realModel.fireTableStructureChanged();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/HTMLLabelTableCellRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\nimport java.awt.*;\nimport java.net.URL;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.ui.components.HTMLLabel;\n\n\n/** Enhanced Table cell rendered that paints text labels using provided text alignment\n *\n * @author Tomas Hurka\n * @author Ian Formanek\n */\npublic class HTMLLabelTableCellRenderer extends EnhancedTableCellRenderer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected HTMLLabel label;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a default table cell renderer with LEADING horizontal alignment showing border when focused. */\n    public HTMLLabelTableCellRenderer() {\n        this(JLabel.LEADING);\n    }\n\n    public HTMLLabelTableCellRenderer(int horizontalAlignment) {\n        this(horizontalAlignment, false);\n    }\n\n    public HTMLLabelTableCellRenderer(int horizontalAlignment, final boolean persistent) {\n        setHorizontalAlignment(horizontalAlignment);\n        label = new HTMLLabel() {\n                protected void showURL(URL url) {\n                    HTMLLabelTableCellRenderer.this.handleLink(url);\n                }\n\n                public void setCursor(Cursor cursor) {\n                    if (persistent) {\n                        super.setCursor(cursor);\n                    } else {\n                        HTMLLabelTableCellRenderer.this.handleCursor(cursor);\n                    }\n                }\n            };\n\n        setLayout(new BorderLayout());\n        add(label,\n            ((horizontalAlignment == JLabel.LEADING) || (horizontalAlignment == JLabel.LEFT)) ? BorderLayout.WEST\n                                                                                              : BorderLayout.EAST);\n\n        //    setBorder (BorderFactory.createEmptyBorder(1, 3, 1, 3));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Component getTableCellRendererComponentPersistent(JTable table, Object value, boolean isSelected, boolean hasFocus,\n                                                             int row, int column) {\n        return new HTMLLabelTableCellRenderer(getHorizontalAlignment(), true).getTableCellRendererComponent(table, value,\n                                                                                                            isSelected, hasFocus,\n                                                                                                            row, column);\n    }\n\n    protected void setRowBackground(Color c) {\n        super.setRowBackground(c);\n        label.setBackground(c);\n    }\n\n    protected void setValue(JTable table, Object value, int row, int column) {\n        if (table != null) {\n            setFont(table.getFont());\n        }\n\n        label.setText((value == null) ? \"\" : value.toString()); //NOI18N\n    }\n\n    protected void handleCursor(Cursor cursor) {\n        // override to react to setCursor\n    }\n\n    protected void handleLink(URL url) {\n        // override to react to URL clicks\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/JExtendedTablePanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\nimport java.awt.*;\nimport javax.swing.*;\nimport javax.swing.event.*;\nimport javax.swing.table.JTableHeader;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedTable;\n\n\n/**\n * A subclass of JPanel that provides additional functionality for displaying JExtendedTable.\n * JExtendedTablePanel provides JScrollPane for displaying JExtendedTable and customized Viewport.\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic class JExtendedTablePanel extends JPanel {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    //-----------------------------------------------------------------------\n    // Custom ExtendedTable Viewport\n    private class CustomExtendedTableViewport extends JViewport {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private JTableHeader tableHeader;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        CustomExtendedTableViewport(JExtendedTable extendedTable) {\n            super();\n            setView(extendedTable);\n            updateBackgroundColor();\n            this.tableHeader = extendedTable.getTableHeader();\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        @Override\n        public void paint(Graphics g) {\n            super.paint(g);\n\n            if (UIConstants.SHOW_TABLE_VERTICAL_GRID) {\n                paintVerticalLines(g);\n            }\n        }\n\n        private int getEmptySpaceY() {\n            if (getView() == null) {\n                return 0;\n            }\n\n            return getView().getHeight();\n        }\n\n        private void paintVerticalLines(Graphics g) {\n            int emptySpaceY = getEmptySpaceY();\n\n            if (emptySpaceY > 0) {\n                g.setColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);\n\n                int cellX = 0;\n                int cellWidth;\n\n                for (int i = 0; i < extendedTable.getColumnModel().getColumnCount(); i++) {\n                    cellWidth = extendedTable.getColumnModel().getColumn(i).getWidth();\n                    g.drawLine((cellX + cellWidth) - 1, emptySpaceY, (cellX + cellWidth) - 1, getHeight() - 1);\n                    cellX += cellWidth;\n                }\n            }\n        }\n\n        private void updateBackgroundColor() {\n            setBackground(extendedTable.isEnabled() ? extendedTable.getBackground()\n                                                    : UIManager.getColor(\"TextField.inactiveBackground\")); // NOI18N\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    CustomExtendedTableViewport extendedTableViewport;\n    protected JExtendedTable extendedTable;\n    protected JScrollPane extendedTableScrollPane;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of JExtendedTablePanel */\n    public JExtendedTablePanel(JExtendedTable extendedTable) {\n        super(new BorderLayout());\n        this.extendedTable = extendedTable;\n\n        initComponents();\n        hookHeaderColumnResize();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void clearBorders() {\n        extendedTableScrollPane.setBorder(BorderFactory.createEmptyBorder());\n        extendedTableScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());\n    }\n    \n    public void setCorner(String key, java.awt.Component corner) {\n        extendedTableScrollPane.setCorner(key, corner);\n    }\n\n    @Override\n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        updateVerticalScrollbar();\n        extendedTable.setEnabled(enabled);\n        extendedTableViewport.updateBackgroundColor();\n    }\n\n    public JScrollPane getScrollPane() {\n        return extendedTableScrollPane;\n    }\n\n    private void hookHeaderColumnResize() {\n        if (extendedTable.getTableHeader() != null) {\n            extendedTable.getTableHeader().getColumnModel().addColumnModelListener(new TableColumnModelListener() {\n                    public void columnAdded(TableColumnModelEvent e) {\n                        extendedTableViewport.repaint();\n                    }\n\n                    public void columnMoved(TableColumnModelEvent e) {\n                        extendedTableViewport.repaint();\n                    }\n\n                    public void columnRemoved(TableColumnModelEvent e) {\n                        extendedTableViewport.repaint();\n                    }\n\n                    public void columnMarginChanged(ChangeEvent e) {\n                        extendedTableViewport.repaint();\n                    }\n\n                    public void columnSelectionChanged(ListSelectionEvent e) {\n                    } // Ignored\n                });\n\n        }\n    }\n\n    private void initComponents() {\n        setBorder(BorderFactory.createEmptyBorder());\n\n        extendedTableScrollPane = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,\n                                                  JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n        extendedTableViewport = new CustomExtendedTableViewport(extendedTable);\n        extendedTableScrollPane.setViewport(extendedTableViewport);\n        extendedTableScrollPane.addMouseWheelListener(extendedTable);\n        // Enable vertical scrollbar only if needed\n        JScrollBar vScrollbar = extendedTableScrollPane.getVerticalScrollBar();\n        vScrollbar.getModel().addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                updateVerticalScrollbar();\n            }\n        });\n\n        add(extendedTableScrollPane, BorderLayout.CENTER);\n    }\n\n    private void updateVerticalScrollbar() {\n        JScrollBar vScrollbar = extendedTableScrollPane.getVerticalScrollBar();\n        vScrollbar.setEnabled(JExtendedTablePanel.this.isEnabled() &&\n                              vScrollbar.getVisibleAmount() < vScrollbar.getMaximum());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/LabelBracketTableCellRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\nimport java.awt.*;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/** Enhanced Table cell rendered that paints text labels using provided text alignment\n *\n * @author Ian Formanek\n */\npublic class LabelBracketTableCellRenderer extends EnhancedTableCellRenderer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JLabel label1;\n    private JLabel label2;\n    private int digitsWidth = -1;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a default table cell renderer with LEADING horizontal alignment showing border when focused. */\n    public LabelBracketTableCellRenderer() {\n        this(JLabel.LEADING);\n    }\n\n    public LabelBracketTableCellRenderer(int horizontalAlignment) {\n        this(horizontalAlignment, \"(99.9%)\"); //NOI18N\n    }\n\n    public LabelBracketTableCellRenderer(int horizontalAlignment, final String widestBracketText) {\n        setHorizontalAlignment(horizontalAlignment);\n        label1 = new JLabel(\"\", horizontalAlignment); //NOI18N\n        label2 = new JLabel(\"\", horizontalAlignment) { //NOI18N\n                public Dimension getPreferredSize() {\n                    Dimension d = super.getPreferredSize();\n\n                    if (digitsWidth == -1) {\n                        digitsWidth = getFontMetrics(getFont()).stringWidth(widestBracketText);\n                    }\n\n                    if (d.width < digitsWidth) {\n                        return new Dimension(digitsWidth, d.height);\n                    } else {\n                        return d;\n                    }\n                }\n            };\n\n        Font f = label2.getFont();\n        label2.setFont(f.deriveFont((float)f.getSize() - 1));\n\n        setLayout(new BorderLayout());\n\n        if (horizontalAlignment == JLabel.LEADING) {\n            add(label1, BorderLayout.WEST);\n            add(label2, BorderLayout.CENTER);\n        } else {\n            add(label1, BorderLayout.CENTER);\n            add(label2, BorderLayout.EAST);\n        }\n\n        setBorder(BorderFactory.createEmptyBorder(1, 3, 1, 3));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Component getTableCellRendererComponentPersistent(JTable table, Object value, boolean isSelected, boolean hasFocus,\n                                                             int row, int column) {\n        return new LabelBracketTableCellRenderer(label1.getHorizontalAlignment()).getTableCellRendererComponent(table, value,\n                                                                                                                isSelected,\n                                                                                                                hasFocus, row,\n                                                                                                                column);\n    }\n\n    protected void setRowForeground(Color c) {\n        super.setRowForeground(c);\n        label1.setForeground(c);\n        label2.setForeground(UIUtils.getDisabledForeground(c));\n    }\n\n    protected void setValue(JTable table, Object value, int row, int column) {\n        if (table != null) {\n            setFont(table.getFont());\n        }\n\n        if (value != null) {\n            String str = value.toString();\n            int bracketIdx = str.lastIndexOf('('); // NOI18N\n\n            if (bracketIdx != -1) {\n                label1.setText(str.substring(0, bracketIdx));\n                label2.setText(str.substring(bracketIdx));\n            } else {\n                label1.setText(str);\n                label2.setText(\"\"); // NOI18N\n            }\n        } else {\n            label1.setText(\"\"); // NOI18N\n            label2.setText(\"\"); // NOI18N\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/LabelTableCellRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\nimport java.awt.*;\nimport javax.swing.*;\n\n\n/** Enhanced Table cell rendered that paints text labels using provided text alignment\n *\n * @author Ian Formanek\n */\npublic class LabelTableCellRenderer extends EnhancedTableCellRenderer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected JLabel label;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a default table cell renderer with LEADING horizontal alignment showing border when focused. */\n    public LabelTableCellRenderer() {\n        this(JLabel.LEADING);\n    }\n\n    public LabelTableCellRenderer(int horizontalAlignment) {\n        setHorizontalAlignment(horizontalAlignment);\n        label = new JLabel(\"\", horizontalAlignment); //NOI18N\n\n        setLayout(new BorderLayout());\n        add(label, BorderLayout.CENTER);\n        setBorder(BorderFactory.createEmptyBorder(1, 3, 1, 3));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Component getTableCellRendererComponentPersistent(JTable table, Object value, boolean isSelected, boolean hasFocus,\n                                                             int row, int column) {\n        return new LabelTableCellRenderer(label.getHorizontalAlignment()).getTableCellRendererComponent(table, value, isSelected,\n                                                                                                        hasFocus, row, column);\n    }\n\n    protected void setRowForeground(Color c) {\n        super.setRowForeground(c);\n        label.setForeground(c);\n    }\n\n    protected void setValue(JTable table, Object value, int row, int column) {\n        if (table != null) {\n            setFont(table.getFont());\n        }\n\n        label.setText((value == null) ? \"\" : value.toString()); //NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/MethodNameTableCellRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\nimport java.awt.*;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/** Enhanced Table cell rendered that paints text labels using provided text alignment\n *\n * @author Ian Formanek\n */\npublic class MethodNameTableCellRenderer extends EnhancedTableCellRenderer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JLabel label1;\n    private JLabel label2;\n    private JLabel label3;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a default table cell renderer with LEADING horizontal alignment showing border when focused. */\n    public MethodNameTableCellRenderer() {\n        label1 = new JLabel(\"\"); //NOI18N\n        label2 = new JLabel(\"\"); //NOI18N\n        label3 = new JLabel(\"\"); //NOI18N\n\n        label2.setFont(label1.getFont().deriveFont(Font.BOLD));\n\n        setLayout(new BorderLayout());\n\n        JPanel in = new JPanel();\n        in.setOpaque(false);\n        in.setLayout(new BorderLayout());\n        add(label1, BorderLayout.WEST);\n        add(in, BorderLayout.CENTER);\n        in.add(label2, BorderLayout.WEST);\n        in.add(label3, BorderLayout.CENTER);\n\n        setBorder(BorderFactory.createEmptyBorder(1, 3, 1, 3));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Component getTableCellRendererComponentPersistent(JTable table, Object value, boolean isSelected, boolean hasFocus,\n                                                             int row, int column) {\n        return new MethodNameTableCellRenderer().getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);\n    }\n\n    protected void setRowForeground(Color c) {\n        super.setRowForeground(c);\n        label1.setForeground(c);\n        label2.setForeground(c);\n        label3.setForeground(UIUtils.getDisabledForeground(c));\n    }\n    \n    protected void setValue(JTable table, Object value, int row, int column) {\n        if (table != null) {\n            setFont(table.getFont());\n        }\n\n        if (value != null) {\n            String str = value.toString();\n            int bracketIndex = str.indexOf('('); //NOI18N\n            String text3 = \"\"; //NOI18N\n\n            if (bracketIndex != -1) {\n                text3 = \" \" + str.substring(bracketIndex); //NOI18N\n                str = str.substring(0, bracketIndex);\n            }\n\n            int dotIndex = str.lastIndexOf('.'); //NOI18N\n            label1.setText(str.substring(0, dotIndex + 1));\n            label2.setText(str.substring(dotIndex + 1));\n            label3.setText(text3);\n        } else {\n            label1.setText(\"\"); //NOI18N\n            label2.setText(\"\"); //NOI18N\n            label3.setText(\"\"); //NOI18N\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/SortableTableModel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseMotionListener;\nimport javax.swing.*;\nimport javax.swing.table.AbstractTableModel;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\n\n\n/**\n * This class provides a superclass, from which Table Models can be derived, that will support\n * sorting by a column on which the user clicks. A subclass should call setTable(table),\n * and should provide an implementation of the sortByColumn(int column) method.\n *\n * @author Misha Dmitriev\n * @author Jiri Sedlacek\n */\npublic abstract class SortableTableModel extends AbstractTableModel {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    /**\n     * This class is used for listening to the table header mouse events.\n     */\n    private class HeaderListener extends MouseAdapter implements MouseMotionListener {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        /*\n         * If the user clicks to the sorting column (column defining the sort criterium and order), the sorting order is reversed.\n         * If new sorting column is selected, the appropriate sorting order for column's datatype is set.\n         */\n        public void mouseClicked(MouseEvent e) {\n            if (SwingUtilities.isLeftMouseButton(e)) {\n                int column = tableHeader.columnAtPoint(e.getPoint());\n                int sortingColumn = headerRenderer.getSortingColumn();\n\n                if (column == sortingColumn) {\n                    headerRenderer.reverseSortingOrder();\n                } else {\n                    headerRenderer.setSortingColumn(column);\n\n                    if (getInitialSorting(column)) {\n                        headerRenderer.setSortingOrder(SORT_ORDER_ASC); // Default sort order for strings is Ascending\n                    } else {\n                        headerRenderer.setSortingOrder(SORT_ORDER_DESC); // Default sort order for numbers is Descending\n                    }\n                }\n\n                tableHeader.repaint();\n\n                sortByColumn(column, headerRenderer.getSortingOrder());\n            }\n        }\n\n        public void mouseDragged(MouseEvent e) {\n        }\n\n        public void mouseMoved(MouseEvent e) {\n            int focusedColumn = tableHeader.columnAtPoint(e.getPoint());\n\n            if ((focusedColumn != lastFocusedColumn) && (focusedColumn != -1)) {\n                tableHeader.setToolTipText(SortableTableModel.this.getColumnToolTipText(focusedColumn));\n                lastFocusedColumn = focusedColumn;\n            }\n        }\n\n        /*\n         * Here the active header button is programmatically pressed\n         */\n        public void mousePressed(MouseEvent e) {\n            if (SwingUtilities.isLeftMouseButton(e) && (tableHeader.getResizingColumn() == null)) {\n                headerRenderer.setPressedColumn(tableHeader.columnAtPoint(e.getPoint()));\n                tableHeader.repaint();\n            }\n        }\n\n        /*\n         * Here the active header button is programmatically released\n         */\n        public void mouseReleased(MouseEvent e) {\n            if (SwingUtilities.isLeftMouseButton(e)) {\n                headerRenderer.setPressedColumn(-1);\n                tableHeader.repaint();\n            }\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final boolean SORT_ORDER_DESC = false;\n    public static final boolean SORT_ORDER_ASC = true;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private CustomSortableHeaderRenderer headerRenderer;\n    private HeaderListener headerListener;\n    private ImageIcon sortAscIcon = Icons.getImageIcon(GeneralIcons.SORT_ASCENDING);\n    private ImageIcon sortDescIcon = Icons.getImageIcon(GeneralIcons.SORT_DESCENDING);\n    private JTableHeader tableHeader;\n    private int lastFocusedColumn = -1;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SortableTableModel() {\n        headerListener = new HeaderListener();\n        headerRenderer = new CustomSortableHeaderRenderer(sortAscIcon, sortDescIcon);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * After the table to which this model belongs has been set, this method allows to set the initial sorting column and sorting order.\n     * @param sortingColumn The initial sorting column\n     * @param sortingOrder The initial sorting order\n     */\n    public void setInitialSorting(int sortingColumn, boolean sortingOrder) {\n        if (headerRenderer != null) {\n            headerRenderer.setSortingColumn(sortingColumn);\n            headerRenderer.setSortingOrder(sortingOrder);\n        }\n    }\n\n    /**\n     * @param column The table column index\n     * @return Initial sorting for the specified column - if true, ascending, if false descending\n     */\n    public abstract boolean getInitialSorting(int column); /* {\n       return (getColumnClass(column).equals(String.class));\n       }*/\n\n    public int getSortingColumn() {\n        return headerRenderer.getSortingColumn();\n    }\n\n    public boolean getSortingOrder() {\n        return headerRenderer.getSortingOrder();\n    }\n\n    /**\n     * Assigns this SortableTableModel to the JTable and sets the custom renderer for the selectable table header.\n     * @param table The JTable to set this table model to\n     */\n    public void setTable(JTable table) {\n        TableColumnModel tableModel = table.getColumnModel();\n        int n = tableModel.getColumnCount();\n\n        for (int i = 0; i < n; i++) {\n            tableModel.getColumn(i).setHeaderRenderer(headerRenderer);\n        }\n\n        if (tableHeader != table.getTableHeader()) {\n            if (tableHeader != null) {\n                tableHeader.removeMouseListener(headerListener);\n                tableHeader.removeMouseMotionListener(headerListener);\n                lastFocusedColumn = -1;\n            }\n\n            tableHeader = table.getTableHeader();\n            tableHeader.setReorderingAllowed(false);\n            tableHeader.addMouseListener(headerListener);\n            tableHeader.addMouseMotionListener(headerListener);\n        }\n    }\n\n    public abstract void sortByColumn(int column, boolean order);\n\n    public String getColumnToolTipText(int column) {\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/table/TableCellRendererPersistent.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.table;\n\nimport java.awt.Component;\nimport javax.swing.JTable;\nimport javax.swing.table.TableCellRenderer;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface TableCellRendererPersistent extends TableCellRenderer {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    Component getTableCellRendererComponentPersistent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,\n                                                      int column);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/tree/CheckTreeCellRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.tree;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport javax.swing.ButtonModel;\nimport javax.swing.Icon;\nimport javax.swing.JCheckBox;\nimport javax.swing.JPanel;\nimport javax.swing.JTree;\nimport javax.swing.UIManager;\nimport javax.swing.tree.DefaultTreeCellRenderer;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class CheckTreeCellRenderer extends JPanel implements TreeCellRendererPersistent {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static Dimension checkBoxDimension = new JCheckBox().getPreferredSize();\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JCheckBox checkBox = new JCheckBox();\n    private ButtonModel checkBoxModel = checkBox.getModel();\n    private Component treeRendererComponent;\n    private DefaultTreeCellRenderer treeRenderer = new DefaultTreeCellRenderer();\n    private boolean persistentRenderer = false;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CheckTreeCellRenderer() {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n        checkBox.setOpaque(false);\n        // --- Workaround for #205932 - not sure why, but works fine...\n        Font f = UIManager.getFont(\"Label.font\"); // NOI18N\n        if (f != null) treeRenderer.setFont(f.deriveFont(f.getStyle()));\n        // ---\n        add(checkBox, BorderLayout.WEST);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static Dimension getCheckBoxDimension() {\n        return checkBoxDimension;\n    }\n\n    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf,\n                                                  int row, boolean hasFocus) {\n        // Get CheckTreeNode from current Node\n        CheckTreeNode treeNode = (value instanceof CheckTreeNode) ? (CheckTreeNode) value : null;\n\n        // Update UI\n        if (treeRendererComponent != null) {\n            remove(treeRendererComponent);\n        }\n\n        if (treeNode != null) {\n            checkBox.setVisible(!persistentRenderer);\n            setupCellRendererIcon(treeRenderer, treeNode.getIcon());\n        } else {\n            checkBox.setVisible(false);\n            setupCellRendererIcon(treeRenderer, null);\n        }\n\n        treeRendererComponent = treeRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);\n        add(treeRendererComponent, BorderLayout.CENTER);\n\n        // Return if no path or not a CheckTreeNode\n        if (treeNode == null) {\n            return this;\n        }\n\n        // If tree model supports checking (uses CheckTreeNodes), setup CheckBox\n        if (treeNode.isFullyChecked()) {\n            setupCheckBox(Boolean.TRUE);\n        } else {\n            setupCheckBox(treeNode.isPartiallyChecked() ? null : Boolean.FALSE);\n        }\n\n        return this;\n    }\n\n    public Component getTreeCellRendererComponentPersistent(JTree tree, Object value, boolean selected, boolean expanded,\n                                                            boolean leaf, int row, boolean hasFocus) {\n        CheckTreeCellRenderer ctcr = new CheckTreeCellRenderer();\n        ctcr.persistentRenderer = true;\n\n        return ctcr.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);\n    }\n\n    private void setupCellRendererIcon(DefaultTreeCellRenderer renderer, Icon icon) {\n        renderer.setLeafIcon(icon);\n        renderer.setOpenIcon(icon);\n        renderer.setClosedIcon(icon);\n    }\n\n    private void setupCheckBox(Boolean state) {\n        if (state == Boolean.TRUE) {\n            // Fully checked\n            checkBoxModel.setArmed(false);\n            checkBoxModel.setPressed(false);\n            checkBoxModel.setSelected(true);\n        } else if (state == Boolean.FALSE) {\n            // Fully unchecked\n            checkBoxModel.setArmed(false);\n            checkBoxModel.setPressed(false);\n            checkBoxModel.setSelected(false);\n        } else {\n            // Partially checked\n            checkBoxModel.setArmed(true);\n            checkBoxModel.setPressed(true);\n            checkBoxModel.setSelected(true);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/tree/CheckTreeNode.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.tree;\n\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.Icon;\nimport javax.swing.tree.DefaultMutableTreeNode;\nimport javax.swing.tree.TreeNode;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class CheckTreeNode extends DefaultMutableTreeNode {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int STATE_CHECKED = 1;\n    public static final int STATE_UNCHECKED = 2;\n    public static final int STATE_PARTIALLY_CHECKED = 4;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected int checkState = STATE_UNCHECKED;\n    private Icon icon;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    // --- Public interface ------------------------------------------------------\n\n    // Creates new CheckTreeNode, no user object, initially unchecked\n    public CheckTreeNode() {\n        this(null);\n    }\n\n    // Creates new CheckTreeNode with user object, initially unchecked\n    public CheckTreeNode(Object userObject) {\n        this(userObject, null);\n    }\n\n    /**\n     * Creates new CheckTreeNode with given icon, initially unchecked\n     */\n    public CheckTreeNode(Object userObject, final Icon icon) {\n        super(userObject);\n        checkState = STATE_UNCHECKED;\n        this.icon = icon;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    // Returns CheckTreeNode's check state - STATE_CHECKED, STATE_UNCHECKED or STATE_PARTIALLY_CHECKED\n    public int getCheckState() {\n        return checkState;\n    }\n\n    // Sets the CheckTreeNode to be fully checked or fully unchecked\n    // Returns Collection of leaf nodes changed by this operation\n    public Collection setChecked(boolean checked) {\n        if (checked) {\n            return setFullyChecked();\n        } else {\n            return setUnchecked();\n        }\n    }\n\n    // Check if CheckTreeNode is fully checked\n    public boolean isFullyChecked() {\n        return getCheckState() == STATE_CHECKED;\n    }\n\n    /**\n     * The icon property getter\n     */\n    public Icon getIcon() {\n        return icon;\n    }\n\n    // Check if CheckTreeNode is partially checked\n    public boolean isPartiallyChecked() {\n        return getCheckState() == STATE_PARTIALLY_CHECKED;\n    }\n\n    // Toggles CheckTreeNode's check state to next state\n    // Returns Collection of leaf nodes changed by this operation\n    public Collection toggleState() {\n        if (getCheckState() == STATE_CHECKED) {\n            return setUnchecked();\n        } else {\n            return setFullyChecked();\n        }\n    }\n\n    protected Collection setPartiallyChecked() {\n        Set changedNodes = new HashSet();\n        changedNodes.add(this);\n\n        // Check if change is needed\n        if (checkState == STATE_PARTIALLY_CHECKED) {\n            return changedNodes;\n        }\n\n        // Update checkState of this node\n        checkState = STATE_PARTIALLY_CHECKED;\n\n        // Update checkState of parent\n        TreeNode parent = getParent();\n\n        if ((parent != null) && parent instanceof CheckTreeNode) {\n            changedNodes.addAll(((CheckTreeNode) parent).setPartiallyChecked());\n        }\n\n        // Return Collection of leaf nodes changed by this operation\n        return changedNodes;\n    }\n\n    // ---------------------------------------------------------------------------\n\n    // --- Private implementation ------------------------------------------------\n    private Collection setFullyChecked() {\n        Set changedNodes = new HashSet();\n        changedNodes.add(this);\n\n        // Check if change is needed\n        if (checkState == STATE_CHECKED) {\n            return changedNodes;\n        }\n\n        // Update checkState of this node\n        checkState = STATE_CHECKED;\n\n        // Update checkState of all children if any\n        if (!isLeaf()) {\n            for (int i = 0; i < getChildCount(); i++) {\n                TreeNode node = getChildAt(i);\n\n                if (node instanceof CheckTreeNode) {\n                    changedNodes.addAll(((CheckTreeNode) node).setFullyChecked());\n                }\n            }\n        }\n\n        // Update checkState of parent\n        TreeNode parent = getParent();\n\n        if ((parent != null) && parent instanceof CheckTreeNode) {\n            if (areSiblingsFullyChecked()) {\n                changedNodes.addAll(((CheckTreeNode) parent).setFullyChecked());\n            } else {\n                changedNodes.addAll(((CheckTreeNode) parent).setPartiallyChecked());\n            }\n        }\n\n        // Return Collection of leaf nodes changed by this operation\n        return changedNodes;\n    }\n\n    private Collection setUnchecked() {\n        Set changedNodes = new HashSet();\n        changedNodes.add(this);\n\n        // Check if change is needed\n        if (checkState == STATE_UNCHECKED) {\n            return changedNodes;\n        }\n\n        // Update checkState of this node\n        checkState = STATE_UNCHECKED;\n\n        // Update checkState of all children if any\n        if (!isLeaf()) {\n            for (int i = 0; i < getChildCount(); i++) {\n                TreeNode node = getChildAt(i);\n\n                if (node instanceof CheckTreeNode) {\n                    changedNodes.addAll(((CheckTreeNode) node).setUnchecked());\n                }\n            }\n        }\n\n        // Update checkState of parent\n        TreeNode parent = getParent();\n\n        if (parent instanceof CheckTreeNode) {\n            if (areSiblingsUnchecked()) {\n                changedNodes.addAll(((CheckTreeNode) parent).setUnchecked());\n            } else {\n                changedNodes.addAll(((CheckTreeNode) parent).setPartiallyChecked());\n            }\n        }\n\n        // Return Collection of leaf nodes changed by this operation\n        return changedNodes;\n    }\n\n    private boolean areSiblingsFullyChecked() {\n        TreeNode parent = getParent();\n\n        for (int i = 0; i < parent.getChildCount(); i++) {\n            TreeNode node = parent.getChildAt(i);\n\n            if (node == this) {\n                continue;\n            }\n\n            if (!(node instanceof CheckTreeNode) || (((CheckTreeNode) node).getCheckState() != STATE_CHECKED)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    private boolean areSiblingsUnchecked() {\n        TreeNode parent = getParent();\n\n        for (int i = 0; i < parent.getChildCount(); i++) {\n            TreeNode node = parent.getChildAt(i);\n\n            if (node == this) {\n                continue;\n            }\n\n            if (!(node instanceof CheckTreeNode) || (((CheckTreeNode) node).getCheckState() != STATE_UNCHECKED)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    // ---------------------------------------------------------------------------  \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/tree/EnhancedTreeCellRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.tree;\n\nimport java.awt.*;\nimport javax.swing.*;\nimport javax.swing.plaf.ColorUIResource;\nimport javax.swing.plaf.FontUIResource;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\npublic class EnhancedTreeCellRenderer extends JPanel implements TreeCellRendererPersistent {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected Color backgroundNonSelectionColor;\n    protected Color backgroundSelectionColor = UIConstants.TABLE_SELECTION_BACKGROUND_COLOR;\n    protected Color borderSelectionColor;\n    protected Color textNonSelectionColor;\n\n    // Colors\n    protected Color textSelectionColor = UIConstants.TABLE_SELECTION_FOREGROUND_COLOR;\n    protected boolean hasFocus;\n    protected boolean selected;\n\n    // Icons\n    private transient Icon closedIcon = UIManager.getIcon(\"Tree.closedIcon\"); // NOI18N\n    private transient Icon leafIcon = UIManager.getIcon(\"Tree.leafIcon\"); // NOI18N\n    private transient Icon openIcon = UIManager.getIcon(\"Tree.openIcon\"); // NOI18N\n\n    // subcomponents\n    private JLabel label1;\n    private JLabel label2;\n    private JLabel label3;\n    private JTree tree;\n\n    private static final Insets ZERO_INSETS = new Insets(0, 0, 0, 0);\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns a new instance of DefaultTreeCellRenderer.  Alignment is\n     * set to left aligned. Icons and text color are determined from the\n     * UIManager.\n     */\n    public EnhancedTreeCellRenderer() {\n        super(null);\n        setOpaque(false);\n\n        label1 = new InternalLabel();\n        label2 = new InternalLabel();\n        label3 = new InternalLabel();\n\n        label2.setFont(label1.getFont().deriveFont(Font.BOLD));\n\n        add(label1);\n        add(label2);\n        add(label3);\n\n        label1.setHorizontalAlignment(JLabel.LEFT);\n\n        setLeafIcon(UIManager.getIcon(\"Tree.leafIcon\")); // NOI18N\n        setClosedIcon(UIManager.getIcon(\"Tree.closedIcon\")); // NOI18N\n        setOpenIcon(UIManager.getIcon(\"Tree.openIcon\")); // NOI18N\n\n        setTextSelectionColor(UIManager.getColor(\"Tree.selectionForeground\")); // NOI18N\n        setTextNonSelectionColor(UIManager.getColor(\"Tree.textForeground\")); // NOI18N\n        setBackgroundSelectionColor(UIManager.getColor(\"Tree.selectionBackground\")); // NOI18N\n        setBackgroundNonSelectionColor(UIManager.getColor(\"Tree.textBackground\")); // NOI18N\n        setBorderSelectionColor(UIManager.getColor(\"Tree.selectionBorderColor\")); // NOI18N\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void doLayout() {\n        Dimension size  = getSize();\n\tDimension size1 = label1.getPreferredSize();\n        Dimension size2 = label2.getPreferredSize();\n        Dimension size3 = label3.getPreferredSize();\n\n        size.height = Math.max(size.height, size1.height);\n        size.height = Math.max(size.height, size2.height);\n        size.height = Math.max(size.height, size3.height);\n\n        int x = 0;\n\n        if (\"\".equals(label1.getText())) size1.width += label1.getIconTextGap(); // NOI18N\n        label1.setBounds(x, 0, size1.width, size.height);\n        x += size1.width;\n\n        label2.setBounds(x, 0, size2.width, size.height);\n        x += size2.width;\n\n        label3.setBounds(x, 0, size3.width, size.height);\n    }\n\n    public Dimension getPreferredSize() {\n\tDimension size = label1.getPreferredSize();\n        if (\"\".equals(label1.getText())) size.width += label1.getIconTextGap(); // NOI18N\n        size.width += label2.getPreferredSize().width;\n        size.width += label3.getPreferredSize().width;\n        return size;\n    }\n\n    public Dimension getMaximumSize() {\n\treturn getPreferredSize();\n    }\n\n    public Dimension getMinimumSize() {\n\treturn getPreferredSize();\n    }\n\n    /**\n     * Subclassed to map <code>ColorUIResource</code>s to null. If\n     * <code>color</code> is null, or a <code>ColorUIResource</code>, this\n     * has the effect of letting the background color of the JTree show\n     * through. On the other hand, if <code>color</code> is non-null, and not\n     * a <code>ColorUIResource</code>, the background becomes\n     * <code>color</code>.\n     */\n    public void setBackground(Color color) {\n        if (color instanceof ColorUIResource) {\n            color = null;\n        }\n\n        super.setBackground(color);\n    }\n\n    /**\n     * Sets the background color to be used for non selected nodes.\n     */\n    public void setBackgroundNonSelectionColor(Color newColor) {\n        backgroundNonSelectionColor = newColor;\n    }\n\n    /**\n     * Returns the background color to be used for non selected nodes.\n     */\n    public Color getBackgroundNonSelectionColor() {\n        return backgroundNonSelectionColor;\n    }\n\n    /**\n     * Sets the color to use for the background if node is selected.\n     */\n    public void setBackgroundSelectionColor(Color newColor) {\n        backgroundSelectionColor = newColor;\n    }\n\n    /**\n     * Returns the color to use for the background if node is selected.\n     */\n    public Color getBackgroundSelectionColor() {\n        return backgroundSelectionColor;\n    }\n\n    /**\n     * Sets the color to use for the border.\n     */\n    public void setBorderSelectionColor(Color newColor) {\n        borderSelectionColor = newColor;\n    }\n\n    /**\n     * Returns the color the border is drawn.\n     */\n    public Color getBorderSelectionColor() {\n        return borderSelectionColor;\n    }\n\n    /**\n     * Sets the icon used to represent non-leaf nodes that are not expanded.\n     */\n    public void setClosedIcon(Icon newIcon) {\n        closedIcon = newIcon;\n    }\n\n    /**\n     * Returns the icon used to represent non-leaf nodes that are not\n     * expanded.\n     */\n    public Icon getClosedIcon() {\n        return closedIcon;\n    }\n\n    /**\n     * Subclassed to map <code>FontUIResource</code>s to null. If\n     * <code>font</code> is null, or a <code>FontUIResource</code>, this\n     * has the effect of letting the font of the JTree show\n     * through. On the other hand, if <code>font</code> is non-null, and not\n     * a <code>FontUIResource</code>, the font becomes <code>font</code>.\n     */\n    public void setFont(Font font) {\n        if (font instanceof FontUIResource) {\n            font = null;\n        }\n\n        super.setFont(font);\n    }\n\n    /**\n     * Gets the font of this component.\n     *\n     * @return this component's font; if a font has not been set\n     *         for this component, the font of its parent is returned\n     */\n    public Font getFont() {\n        Font font = super.getFont();\n\n        if ((font == null) && (tree != null)) {\n            // Strive to return a non-null value, otherwise the html support\n            // will typically pick up the wrong font in certain situations.\n            font = tree.getFont();\n        }\n\n        return font;\n    }\n\n    /**\n     * Sets the icon used to represent leaf nodes.\n     */\n    public void setLeafIcon(Icon newIcon) {\n        leafIcon = newIcon;\n    }\n\n    /**\n     * Returns the icon used to represent leaf nodes.\n     */\n    public Icon getLeafIcon() {\n        return leafIcon;\n    }\n\n    /**\n     * Sets the icon used to represent non-leaf nodes that are expanded.\n     */\n    public void setOpenIcon(Icon newIcon) {\n        openIcon = newIcon;\n    }\n\n    /**\n     * Returns the icon used to represent non-leaf nodes that are expanded.\n     */\n    public Icon getOpenIcon() {\n        return openIcon;\n    }\n\n    /**\n     * Sets the color the text is drawn with when the node isn't selected.\n     */\n    public void setTextNonSelectionColor(Color newColor) {\n        textNonSelectionColor = newColor;\n    }\n\n    /**\n     * Returns the color the text is drawn with when the node isn't selected.\n     */\n    public Color getTextNonSelectionColor() {\n        return textNonSelectionColor;\n    }\n\n    /**\n     * Sets the color the text is drawn with when the node is selected.\n     */\n    public void setTextSelectionColor(Color newColor) {\n        textSelectionColor = newColor;\n    }\n\n    /**\n     * Returns the color the text is drawn with when the node is selected.\n     */\n    public Color getTextSelectionColor() {\n        return textSelectionColor;\n    }\n\n    /**\n     * Configures the renderer based on the passed in components.\n     * The value is set from messaging the tree with\n     * <code>convertValueToText</code>, which ultimately invokes\n     * <code>toString</code> on <code>value</code>.\n     * The foreground color is set based on the selection and the icon\n     * is set based on leaf and expanded.\n     */\n    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row,\n                                                  boolean hasFocus) {\n\n        String stringValue = value != null ? value.toString() : \"\"; // NOI18N\n\n        this.tree = tree;\n        this.hasFocus = hasFocus;\n\n        label1.setText(getLabel1Text(value, stringValue));\n        label2.setText(getLabel2Text(value, stringValue));\n        label3.setText(getLabel3Text(value, stringValue));\n\n        if (sel) {\n            label1.setForeground(getTextSelectionColor());\n            label2.setForeground(getTextSelectionColor());\n\n            Color c = getTextSelectionColor();\n            label3.setForeground(UIUtils.getDisabledForeground(c));\n        } else {\n            label1.setForeground(getTextNonSelectionColor());\n            label2.setForeground(getTextNonSelectionColor());\n\n            Color c = getTextNonSelectionColor();\n            label3.setForeground(UIUtils.getDisabledForeground(c));\n        }\n\n        if (!tree.isEnabled()) {\n            label1.setEnabled(false);\n            label2.setEnabled(false);\n            label3.setEnabled(false);\n\n            if (leaf) {\n                label1.setDisabledIcon(getLeafIcon(value));\n            } else if (expanded) {\n                label1.setDisabledIcon(getOpenIcon(value));\n            } else {\n                label1.setDisabledIcon(getClosedIcon(value));\n            }\n        } else {\n            label1.setEnabled(true);\n            label2.setEnabled(true);\n            label3.setEnabled(true);\n\n            if (leaf) {\n                label1.setIcon(getLeafIcon(value));\n            } else if (expanded) {\n                label1.setIcon(getOpenIcon(value));\n            } else {\n                label1.setIcon(getClosedIcon(value));\n            }\n        }\n\n        label1.setComponentOrientation(tree.getComponentOrientation()); // TODO [ian]: what does this mean wrt label2, label3\n\n        selected = sel;\n\n        return this;\n    }\n\n    public Component getTreeCellRendererComponentPersistent(JTree tree, Object value, boolean sel, boolean expanded,\n                                                            boolean leaf, int row, boolean hasFocus) {\n        EnhancedTreeCellRenderer renderer = new EnhancedTreeCellRenderer();\n        renderer.setLeafIcon(leafIcon);\n        renderer.setClosedIcon(closedIcon);\n        renderer.setOpenIcon(openIcon);\n\n        return renderer.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);\n    }\n\n    /**\n     * Paints the value. The background is filled based on selected.\n     */\n    public void paint(Graphics g) {\n        Color bColor;\n\n        if (selected) {\n            bColor = getBackgroundSelectionColor();\n        } else {\n            bColor = getBackgroundNonSelectionColor();\n\n            if (bColor == null) {\n                bColor = getBackground();\n            }\n        }\n\n        if (bColor != null) {\n            g.setColor(bColor);\n            g.fillRect(0, 0, getWidth(), getHeight());\n        }\n\n        if (hasFocus) {\n            Color bsColor = getBorderSelectionColor();\n\n            if (bsColor != null) {\n                g.setColor(bsColor);\n                g.drawRect(0, 0, getWidth(), getHeight());\n            }\n        }\n\n        super.paint(g);\n\n    }\n\n    protected Icon getClosedIcon(Object value) {\n        return getClosedIcon();\n    }\n\n    /**\n     * @param   node  The node value\n     * @param   value Entire tree node text\n     * @return  First part to display in plain font\n     */\n    protected String getLabel1Text(Object node, String value) {\n        return value;\n    }\n\n    /**\n     * @param   node  The node value\n     * @param   value Entire tree node text\n     * @return  Middle part to display in bold font\n     */\n    protected String getLabel2Text(Object node, String value) {\n        return \"\"; // NOI18N\n    }\n\n    /**\n     * @param   node  The node value\n     * @param   value Entire tree node text\n     * @return  Lat part to display in gray font\n     */\n    protected String getLabel3Text(Object node, String value) {\n        return \"\"; // NOI18N\n    }\n\n    protected Icon getLeafIcon(Object value) {\n        return getLeafIcon();\n    }\n\n    protected Icon getOpenIcon(Object value) {\n        return getOpenIcon();\n    }\n\n    // --- Performance tweaks\n\n    // Overridden for performance reasons.\n    public Insets getInsets() { return ZERO_INSETS; }\n    \n    // Overridden for performance reasons.\n    public void validate() { if (!isValid()) doLayout(); }\n    \n    // Overridden for performance reasons.\n    public void revalidate() {}\n\n    // Overridden for performance reasons.\n    public void repaint(long tm, int x, int y, int width, int height) {}\n\n    // Overridden for performance reasons.\n    public void repaint(Rectangle r) {}\n\n    // Overridden for performance reasons.\n    public void repaint() {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, char oldValue, char newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, short oldValue, short newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, int oldValue, int newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, long oldValue, long newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, float oldValue, float newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, double oldValue, double newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}\n\n    /// Overridden for performance reasons.\n    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}\n\n    // ---\n\n\n    /**\n     * Tweaked JLabel optimized for performance - use only as component renderer!\n     */\n    private static class InternalLabel extends JLabel {\n\n        private FontMetrics fontMetrics;\n        private String text;\n        private Color foreground;\n        private boolean enabled;\n\n\n        // Overridden for performance reasons.\n        public void setText(String text) {\n            this.text = text;\n        }\n\n        // Overridden for performance reasons.\n        public String getText() {\n            return text;\n        }\n\n        // Overridden for performance reasons.\n        public void setForeground(Color foreground) {\n            this.foreground = foreground;\n        }\n\n        // Overridden for performance reasons.\n        public Color getForeground() {\n            return foreground;\n        }\n\n        // Overridden for performance reasons.\n        public void setEnabled(boolean enabled) {\n            this.enabled = enabled;\n        }\n\n        // Overridden for performance reasons.\n        public boolean isEnabled() {\n            return enabled;\n        }\n\n        // Overridden for performance reasons.\n        public FontMetrics getFontMetrics(Font font) {\n            if (fontMetrics == null) fontMetrics = super.getFontMetrics(font);\n            return fontMetrics;\n        }\n\n        // Overridden for performance reasons.\n        public void setFont(Font font) {\n            fontMetrics = null;\n            super.setFont(font);\n        }\n\n        // Overridden for performance reasons.\n        public void validate() {}\n\n        // Overridden for performance reasons.\n        public void revalidate() {}\n\n        // Overridden for performance reasons.\n        public void repaint(long tm, int x, int y, int width, int height) {}\n\n        // Overridden for performance reasons.\n        public void repaint(Rectangle r) {}\n\n        // Overridden for performance reasons.\n        public void repaint() {}\n\n        // Overridden for performance reasons.\n        public void setDisplayedMnemonic(int key) {}\n\n        // Overridden for performance reasons.\n        public void setDisplayedMnemonic(char aChar) {}\n\n        // Overridden for performance reasons.\n        public void setDisplayedMnemonicIndex(int index) {}\n\n        // Overridden for performance reasons.\n        public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {}\n\n        // Overridden for performance reasons.\n        public void firePropertyChange(String propertyName, char oldValue, char newValue) {}\n\n        // Overridden for performance reasons.\n        public void firePropertyChange(String propertyName, short oldValue, short newValue) {}\n\n        // Overridden for performance reasons.\n        public void firePropertyChange(String propertyName, int oldValue, int newValue) {}\n\n        // Overridden for performance reasons.\n        public void firePropertyChange(String propertyName, long oldValue, long newValue) {}\n\n        // Overridden for performance reasons.\n        public void firePropertyChange(String propertyName, float oldValue, float newValue) {}\n\n        // Overridden for performance reasons.\n        public void firePropertyChange(String propertyName, double oldValue, double newValue) {}\n\n        // Overridden for performance reasons.\n        public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}\n\n        // Overridden for performance reasons.\n        protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}\n\n        // Overridden for performance reasons.\n        public void paint(Graphics g) {\n            Graphics componentGraphics = getComponentGraphics(g);\n            Graphics co = (componentGraphics == null) ? null :\n                          componentGraphics.create();\n            try {\n                paintComponent(co);\n            } finally {\n                if (co != null) co.dispose();\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/tree/MethodNameTreeCellRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.tree;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * Formats the node as follows:\n *   - if node does not contain either '.' or '(', format the node in plain font (typically if not a class or method name)\n *   - anything after '(' is formatted using gray font                           (typically method arguments)\n *   - anything between last '.' and before '(' is formatted using bold font     (typically method name)\n */\npublic class MethodNameTreeCellRenderer extends EnhancedTreeCellRenderer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Icon allThreadsIcon = Icons.getIcon(ProfilerIcons.ALL_THREADS);\n    private Icon threadIcon = Icons.getIcon(ProfilerIcons.THREAD);\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Component getTreeCellRendererComponentPersistent(JTree tree, Object value, boolean sel, boolean expanded,\n                                                            boolean leaf, int row, boolean hasFocus) {\n        MethodNameTreeCellRenderer renderer = new MethodNameTreeCellRenderer();\n        renderer.setLeafIcon(getLeafIcon(value));\n        renderer.setClosedIcon(getClosedIcon(value));\n        renderer.setOpenIcon(getOpenIcon(value));\n        Color backgroundColor = UIUtils.getProfilerResultsBackground();\n\n        if ((row & 0x1) == 0) { //even row\n            renderer.setBackgroundNonSelectionColor(UIUtils.getDarker(backgroundColor));\n        } else {\n            renderer.setBackgroundNonSelectionColor(backgroundColor);\n        }\n\n        return renderer.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);\n    }\n\n    protected Icon getClosedIcon(Object value) {\n        if (value instanceof PrestimeCPUCCTNode) {\n            PrestimeCPUCCTNode cct = (PrestimeCPUCCTNode) value;\n\n            if (cct.isThreadNode()) {\n                if (cct.getThreadId() == -1) {\n                    return allThreadsIcon;\n                } else {\n                    return threadIcon;\n                }\n            } else if (cct.isFiltered()) {\n                return UIManager.getLookAndFeel().getDisabledIcon(this, super.getClosedIcon(value));\n            }\n        } else if (value instanceof PresoObjAllocCCTNode) {\n            if (((PresoObjAllocCCTNode)value).isFiltered()) {\n                return UIManager.getLookAndFeel().getDisabledIcon(this, super.getClosedIcon(value));\n            }\n        }\n\n        // not a thread node or not instance of PrestimeCPUCCTNode\n        return super.getClosedIcon(value);\n    }\n\n    protected String getLabel1Text(Object node, String value) {\n        if (node instanceof PrestimeCPUCCTNode) {\n            if (((PrestimeCPUCCTNode)node).isThreadNode() ||\n                ((PrestimeCPUCCTNode)node).isFiltered())\n                return \"\"; //NOI18N\n        } else if (node instanceof PresoObjAllocCCTNode) {\n            if (((PresoObjAllocCCTNode)node).isFiltered())\n                return \"\"; //NOI18N\n        }\n        \n        int bracketIndex = value.indexOf('('); //NOI18N\n        int dotIndex = value.lastIndexOf('.'); //NOI18N\n\n        if ((dotIndex == -1) && (bracketIndex == -1)) {\n            return value; // not a method -> we will format it in plain text\n        }\n\n        if (bracketIndex != -1) {\n            value = value.substring(0, bracketIndex);\n            dotIndex = value.lastIndexOf('.'); //NOI18N\n        }\n\n        return value.substring(0, dotIndex + 1);\n    }\n\n    protected String getLabel2Text(Object node, String value) {\n        if (node instanceof PrestimeCPUCCTNode) {\n            if (((PrestimeCPUCCTNode)node).isThreadNode())\n                return value;\n            else if (((PrestimeCPUCCTNode)node).isFiltered())\n                return \"\"; // NOI18N\n        } else if (node instanceof PresoObjAllocCCTNode) {\n            if (((PresoObjAllocCCTNode)node).isFiltered())\n                return \"\"; //NOI18N\n        }\n        \n        int bracketIndex = value.indexOf('('); //NOI18N\n        int dotIndex = value.lastIndexOf('.'); //NOI18N\n\n        if ((dotIndex == -1) && (bracketIndex == -1)) {\n            return \"\"; //NOI18N // not a method -> we will format it in plain text\n        }\n\n        if (bracketIndex != -1) {\n            value = value.substring(0, bracketIndex);\n            dotIndex = value.lastIndexOf('.'); //NOI18N\n        }\n\n        return value.substring(dotIndex + 1);\n    }\n\n    protected String getLabel3Text(Object node, String value) {\n        if (node instanceof PrestimeCPUCCTNode) {\n            if (((PrestimeCPUCCTNode)node).isThreadNode())\n                return \"\"; //NOI18N\n            else if (((PrestimeCPUCCTNode)node).isFiltered())\n                return value;\n        } else if (node instanceof PresoObjAllocCCTNode) {\n            if (((PresoObjAllocCCTNode)node).isFiltered())\n                return value;\n        }\n        \n        int bracketIndex = value.indexOf('('); //NOI18N\n\n        if (bracketIndex != -1) {\n            return \" \" + value.substring(bracketIndex); //NOI18N\n        } else {\n            return \"\"; //NOI18N\n        }\n    }\n\n    protected Icon getLeafIcon(Object value) {\n        if (value instanceof PrestimeCPUCCTNode) {\n            PrestimeCPUCCTNode cct = (PrestimeCPUCCTNode) value;\n\n            if (cct.isThreadNode()) {\n                if (cct.getThreadId() == -1) {\n                    return allThreadsIcon;\n                } else {\n                    return threadIcon;\n                }\n            } else if (cct.isFiltered()) {\n                return UIManager.getLookAndFeel().getDisabledIcon(this, super.getLeafIcon(value));\n            }\n        } else if (value instanceof PresoObjAllocCCTNode) {\n            if (((PresoObjAllocCCTNode)value).isFiltered()) {\n                return UIManager.getLookAndFeel().getDisabledIcon(this, super.getLeafIcon(value));\n            }\n        }\n\n        // not a thread node or not instance of PrestimeCPUCCTNode\n        return super.getLeafIcon(value);\n    }\n\n    protected Icon getOpenIcon(Object value) {\n        if (value instanceof PrestimeCPUCCTNode) {\n            PrestimeCPUCCTNode cct = (PrestimeCPUCCTNode) value;\n\n            if (cct.isThreadNode()) {\n                if (cct.getThreadId() == -1) {\n                    return allThreadsIcon;\n                } else {\n                    return threadIcon;\n                }\n            } else if (cct.isFiltered()) {\n                return UIManager.getLookAndFeel().getDisabledIcon(this, super.getOpenIcon(value));\n            }\n        } else if (value instanceof PresoObjAllocCCTNode) {\n            if (((PresoObjAllocCCTNode)value).isFiltered()) {\n                return UIManager.getLookAndFeel().getDisabledIcon(this, super.getOpenIcon(value));\n            }\n        }\n\n        // not a thread node or not instance of PrestimeCPUCCTNode\n        return super.getOpenIcon(value);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/tree/TreeCellRendererPersistent.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.tree;\n\nimport java.awt.Component;\nimport javax.swing.JTree;\nimport javax.swing.tree.TreeCellRenderer;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface TreeCellRendererPersistent extends TreeCellRenderer {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    Component getTreeCellRendererComponentPersistent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf,\n                                                     int row, boolean hasFocus);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/treetable/AbstractTreeTableModel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.treetable;\n\nimport javax.swing.event.TreeModelEvent;\nimport javax.swing.event.TreeModelListener;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\n\n\npublic abstract class AbstractTreeTableModel extends DefaultTableModel implements TreeTableModel {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    /**\n     * The root of the tree.\n     */\n    protected CCTNode root;\n    protected boolean initialSortingOrder;\n    protected boolean supportsSorting;\n    protected int initialSortingColumn;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new AbstractTreeTableModel which supports sorting.\n     */\n    public AbstractTreeTableModel(CCTNode root) {\n        this(root, false, -1, false);\n    }\n\n    public AbstractTreeTableModel(CCTNode root, int sortingColumn, boolean sortingOrder) {\n        this(root, true, sortingColumn, sortingOrder);\n    }\n\n    public AbstractTreeTableModel(CCTNode root, boolean supportsSorting, int sortingColumn, boolean sortingOrder) {\n        super();\n        this.root = root;\n        this.supportsSorting = supportsSorting;\n        this.initialSortingColumn = sortingColumn;\n        this.initialSortingOrder = sortingOrder;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns the child at index 'num' of the given node.\n     * <p>\n     * Although the method expects an Object because of the TreeModel contract,\n     * in reality it assumes the given node is a 'TreeTableNode'.\n     *\n     * @see javax.swing.tree.TreeModel#getChild(java.lang.Object, int)\n     */\n    public Object getChild(Object node, int num) {\n        return ((CCTNode) node).getChild(num);\n    }\n\n    /**\n     * Returns the number of children a given node has.\n     * <p>\n     * Although the method expects an Object because of the TreeModel contract,\n     * in reality it assumes the given node is a 'TreeTableNode'.\n     *\n     * @see javax.swing.tree.TreeModel#getChildCount(java.lang.Object)\n     */\n    public int getChildCount(Object node) {\n        return ((CCTNode) node).getNChildren();\n    }\n\n    /**\n     * Returns the column class for column <code>column</code>. This is set\n     * in the constructor.\n     */\n    public abstract Class<?> getColumnClass(int column);\n\n    /**\n     * Returns the number of column names passed into the constructor.\n     */\n    public abstract int getColumnCount();\n\n    /**\n     * Returns the column name passed into the constructor.\n     */\n    public abstract String getColumnName(int column);\n\n    public String getColumnToolTipText(int column) {\n        return null;\n    }\n\n    /**\n     * Returns the index of the child node in the parent node.\n     * <p>\n     * Although the method expects Objects because of the TreeModel contract,\n     * it assumes both parent and child are TreeTableNodes.\n     */\n    public int getIndexOfChild(Object parent, Object child) {\n        if ((parent == null) || (child == null)) {\n            return -1;\n        }\n\n        return ((CCTNode) parent).getIndexOfChild(child);\n    }\n\n    /**\n     * This method should be overridden for TreeTableModel descendant which supports sorting.\n     *\n     * @param column The table column index\n     * @return Initial sorting for the specified column - if true, ascending, if false descending\n     */\n    public boolean getInitialSorting(int column) {\n        return false;\n    }\n\n    public int getInitialSortingColumn() {\n        return initialSortingColumn;\n    }\n\n    public boolean getInitialSortingOrder() {\n        return initialSortingOrder;\n    }\n\n    /**\n     * Returns true when the given node is a 'leaf'.\n     * <p>\n     * Although the method expects an Object because of the TreeModel contract,\n     * in reality it assumes the given node is a 'TreeTableNode'.\n     *\n     * @see javax.swing.tree.TreeModel#isLeaf(java.lang.Object)\n     */\n    public boolean isLeaf(Object node) {\n        return ((CCTNode) node).getNChildren() == 0;\n    }\n\n    public void setRoot(Object root) {\n        this.root = (CCTNode) root;\n    }\n\n    /**\n     * Returns the root node.\n     */\n    public Object getRoot() {\n        return root;\n    }\n\n    /**\n     * Returns the value for the column <code>column</code> and object <code>node</code>.\n     * The return value is determined by invoking the method specified in\n     * constructor for the passed in column.\n     */\n    public abstract Object getValueAt(Object node, int column);\n\n    /**\n     * Returns true if there is a setter method name for column <code>column</code>.\n     * This is set in the constructor.\n     */\n    public boolean isCellEditable(Object node, int column) {\n        return false;\n    }\n\n    /**\n     * Builds the parents of the node up to and including the root node, where\n     * the original node is the last element in the returned array. The length\n     * of the returned array gives the node's depth in the tree.\n     *\n     * @param aNode the TreeNode to get the path for\n     */\n    public CCTNode[] getPathToRoot(CCTNode aNode) {\n        return getPathToRoot(aNode, 0);\n    }\n\n    /**\n     * Sets the value to <code>aValue</code> for the object <code>node</code>\n     * in column <code>column</code>. This is done by using the setter\n     * method name, and coercing the passed in value to the specified type.\n     */\n\n    // Note: This looks up the methods each time! This is rather inefficient;\n    // it should really be changed to cache matching methods/constructors\n    // based on <code>node</code>'s class, and <code>aValue</code>'s class.\n    public void setValueAt(Object aValue, Object node, int column) {\n    }\n\n    /**\n     * Adds a listener for the TreeModelEvent posted after the tree changes.\n     */\n    public void addTreeModelListener(TreeModelListener l) {\n        listenerList.add(TreeModelListener.class, l);\n    }\n\n    /**\n     * Notify all listeners that have registered interest for notification on\n     * this event type. The event instance is lazily created using the\n     * parameters passed into the fire method.\n     *\n     * @see javax.swing.event.EventListenerList\n     */\n    public void fireTreeNodesChanged(Object source, Object[] path, int[] childIndices, Object[] children) {\n        // Guaranteed to return a non-null array\n        Object[] listeners = listenerList.getListenerList();\n        TreeModelEvent e = null;\n\n        // Process the listeners last to first, notifying\n        // those that are interested in this event\n        for (int i = listeners.length - 2; i >= 0; i -= 2) {\n            if (listeners[i] == TreeModelListener.class) {\n                // Lazily create the event:\n                if (e == null) {\n                    e = new TreeModelEvent(source, path, childIndices, children);\n                }\n\n                ((TreeModelListener) listeners[i + 1]).treeNodesChanged(e);\n            }\n        }\n    }\n\n    /**\n     * Notify all listeners that have registered interest for notification on\n     * this event type. The event instance is lazily created using the\n     * parameters passed into the fire method.\n     *\n     * @see javax.swing.event.EventListenerList\n     */\n    public void fireTreeNodesInserted(Object source, Object[] path, int[] childIndices, Object[] children) {\n        // Guaranteed to return a non-null array\n        Object[] listeners = listenerList.getListenerList();\n        TreeModelEvent e = null;\n\n        // Process the listeners last to first, notifying\n        // those that are interested in this event\n        for (int i = listeners.length - 2; i >= 0; i -= 2) {\n            if (listeners[i] == TreeModelListener.class) {\n                // Lazily create the event:\n                if (e == null) {\n                    e = new TreeModelEvent(source, path, childIndices, children);\n                }\n\n                ((TreeModelListener) listeners[i + 1]).treeNodesInserted(e);\n            }\n        }\n    }\n\n    /**\n     * Notify all listeners that have registered interest for notification on\n     * this event type. The event instance is lazily created using the\n     * parameters passed into the fire method.\n     *\n     * @see javax.swing.event.EventListenerList\n     */\n    public void fireTreeNodesRemoved(Object source, Object[] path, int[] childIndices, Object[] children) {\n        // Guaranteed to return a non-null array\n        Object[] listeners = listenerList.getListenerList();\n        TreeModelEvent e = null;\n\n        // Process the listeners last to first, notifying\n        // those that are interested in this event\n        for (int i = listeners.length - 2; i >= 0; i -= 2) {\n            if (listeners[i] == TreeModelListener.class) {\n                // Lazily create the event:\n                if (e == null) {\n                    e = new TreeModelEvent(source, path, childIndices, children);\n                }\n\n                ((TreeModelListener) listeners[i + 1]).treeNodesRemoved(e);\n            }\n        }\n    }\n\n    /**\n     * Notify all listeners that have registered interest for notification on\n     * this event type. The event instance is lazily created using the\n     * parameters passed into the fire method.\n     *\n     * @see javax.swing.event.EventListenerList\n     */\n    public void fireTreeStructureChanged(Object source, Object[] path, int[] childIndices, Object[] children) {\n        // Guaranteed to return a non-null array\n        Object[] listeners = listenerList.getListenerList();\n        TreeModelEvent e = null;\n\n        // Process the listeners last to first, notifying\n        // those that are interested in this event\n        for (int i = listeners.length - 2; i >= 0; i -= 2) {\n            if (listeners[i] == TreeModelListener.class) {\n                // Lazily create the event:\n                if (e == null) {\n                    e = new TreeModelEvent(source, path, childIndices, children);\n                }\n\n                ((TreeModelListener) listeners[i + 1]).treeStructureChanged(e);\n            }\n        }\n    }\n\n    /**\n     * Removes a listener previously added with addTreeModelListener().\n     */\n    public void removeTreeModelListener(TreeModelListener l) {\n        listenerList.remove(TreeModelListener.class, l);\n    }\n\n    /**\n     * This method should be overridden for TreeTableModel descendant which supports sorting.\n     *\n     * @param column The table column index\n     * @param order sorting for the specified column - if true, ascending, if false descending\n     */\n    public void sortByColumn(int column, boolean order) {\n    }\n\n    public boolean supportsSorting() {\n        return supportsSorting;\n    }\n\n    /**\n     * Overwrite if you are going to user editors in the JTree.\n     * <p>\n     * The default implementation does nothing (dummy method).\n     *\n     * @see javax.swing.tree.DefaultTreeModel#valueForPathChanged(javax.swing.tree.TreePath, java.lang.Object)\n     */\n    public void valueForPathChanged(TreePath path, Object newValue) {\n    }\n\n    /**\n     * Builds the parents of the node up to and including the root node, where\n     * the original node is the last element in the returned array. The length\n     * of the returned array gives the node's depth in the tree.\n     *\n     * @param aNode the TreeNode to get the path for\n     * @param depth an int giving the number of steps already taken towards the\n     *              root (on recursive calls), used to size the returned array\n     * @return an array of TreeNodes giving the path from the root to the\n     *         specified node\n     */\n    private CCTNode[] getPathToRoot(CCTNode aNode, int depth) {\n        CCTNode[] retNodes;\n\n        // This method recurses, traversing towards the root in order\n        // size the array. On the way back, it fills in the nodes,\n        // starting from the root and working back to the original node.\n\n        /*\n         * Check for null, in case someone passed in a null node, or\n         */\n        if (aNode == null) {\n            if (depth == 0) {\n                return null;\n            } else {\n                retNodes = new CCTNode[depth];\n            }\n        } else {\n            depth++;\n\n            if (aNode == root) {\n                retNodes = new CCTNode[depth];\n            } else {\n                retNodes = getPathToRoot(aNode.getParent(), depth);\n            }\n\n            retNodes[retNodes.length - depth] = aNode;\n        }\n\n        return retNodes;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/treetable/ExtendedTreeTableModel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.treetable;\n\n\n/**\n * TreeTable model that extends AbstractTableModel and allows to hide columns\n *\n * @author  Jiri Sedlacek\n */\npublic class ExtendedTreeTableModel extends AbstractTreeTableModel {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private AbstractTreeTableModel realModel;\n    private int[] columnsMapping; // mapping virtual columns -> real columns\n    private boolean[] columnsVisibility; // visibility flags of real columns\n    private int realColumnsCount;\n    private int virtualColumnsCount;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ExtendedTreeTableModel(AbstractTreeTableModel realModel) {\n        super(realModel.root, realModel.supportsSorting, realModel.initialSortingColumn, realModel.initialSortingOrder);\n\n        realColumnsCount = realModel.getColumnCount();\n        virtualColumnsCount = realColumnsCount;\n\n        this.realModel = realModel;\n        columnsMapping = new int[realColumnsCount];\n\n        boolean[] initialColumnsVisibility = new boolean[realColumnsCount];\n\n        for (int i = 0; i < realColumnsCount; i++) {\n            initialColumnsVisibility[i] = true;\n        }\n\n        setColumnsVisibility(initialColumnsVisibility);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public boolean isCellEditable(Object node, int column) {\n        return realModel.isCellEditable(node, getRealColumn(column));\n    }\n\n    public Class<?> getColumnClass(int col) {\n        return realModel.getColumnClass(getRealColumn(col));\n    }\n\n    public int getColumnCount() {\n        return virtualColumnsCount;\n    }\n\n    //---------------------\n    // AbstractTreeTableModel interface\n    public String getColumnName(int col) {\n        return realModel.getColumnName(getRealColumn(col));\n    }\n\n    public String getColumnToolTipText(int columnIndex) {\n        int realColumn = getRealColumn(columnIndex);\n\n        if (realColumn == -1) {\n            return null;\n        }\n\n        return realModel.getColumnToolTipText(realColumn);\n    }\n\n    public void setColumnsVisibility(boolean[] columnsVisibility) {\n        this.columnsVisibility = columnsVisibility;\n        recomputeColumnsMapping();\n    }\n\n    public boolean[] getColumnsVisibility() {\n        return columnsVisibility;\n    }\n\n    public boolean getInitialSorting(int column) {\n        return realModel.getInitialSorting(getRealColumn(column));\n    }\n\n    public int getInitialSortingColumn() {\n        return realModel.getInitialSortingColumn();\n    }\n\n    public boolean getInitialSortingOrder() {\n        return realModel.getInitialSortingOrder();\n    }\n\n    public boolean isLeaf(Object node) {\n        return realModel.isLeaf(node);\n    }\n\n    public int getRealColumn(int column) {\n        if ((column > -1) && (column < columnsMapping.length)) {\n            return columnsMapping[column];\n        }\n\n        return -1;\n    }\n\n    public void setRealColumnVisibility(int column, boolean visible) {\n        if (visible) {\n            showRealColumn(column);\n        } else {\n            hideRealColumn(column);\n        }\n    }\n\n    public boolean isRealColumnVisible(int column) {\n        if ((column > -1) && (column < columnsMapping.length)) {\n            return columnsVisibility[column];\n        }\n\n        return false;\n    }\n\n    public void setRoot(Object root) {\n        realModel.setRoot(root);\n    }\n\n    public Object getRoot() {\n        return realModel.getRoot();\n    }\n\n    public void setValueAt(Object aValue, Object node, int column) {\n        realModel.setValueAt(aValue, node, getRealColumn(column));\n    }\n\n    /*public Object getValueAt (int rowIndex, int columnIndex) {\n       return realModel.getValueAt(rowIndex, getRealColumn(columnIndex));\n       }*/\n    public Object getValueAt(Object node, int column) {\n        return realModel.getValueAt(node, getRealColumn(column));\n    }\n\n    public int getVirtualColumn(int column) {\n        for (int i = 0; i < virtualColumnsCount; i++) {\n            if (getRealColumn(i) == column) {\n                return i;\n            }\n        }\n\n        return -1;\n    }\n\n    public void hideRealColumn(int column) {\n        if (isRealColumnVisible(column)) {\n            columnsVisibility[column] = false;\n            recomputeColumnsMapping();\n        }\n    }\n\n    public void showRealColumn(int column) {\n        if (!isRealColumnVisible(column)) {\n            columnsVisibility[column] = true;\n            recomputeColumnsMapping();\n        }\n    }\n\n    public void sortByColumn(int column, boolean order) {\n        realModel.sortByColumn(getRealColumn(column), order);\n    }\n\n    private void recomputeColumnsMapping() {\n        virtualColumnsCount = 0;\n\n        int virtualColumnIndex = 0;\n\n        // set indexes virtual columns -> real columns\n        for (int i = 0; i < realColumnsCount; i++) {\n            if (columnsVisibility[i]) {\n                columnsMapping[virtualColumnIndex] = i;\n                virtualColumnsCount++;\n                virtualColumnIndex++;\n            }\n        }\n\n        // clear mappings of unused real columns\n        for (int i = virtualColumnIndex; i < realColumnsCount; i++) {\n            columnsMapping[i] = -1;\n        }\n        \n        fireTableStructureChanged();\n        realModel.fireTableStructureChanged();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/treetable/JTreeTablePanel.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.treetable;\n\nimport java.awt.*;\nimport java.awt.event.AdjustmentEvent;\nimport java.awt.event.AdjustmentListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseWheelEvent;\nimport java.awt.event.MouseWheelListener;\nimport javax.swing.*;\nimport javax.swing.event.*;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.components.JTreeTable;\n\n\n/**\n * A subclass of JPanel that provides additional functionality for displaying JTreeTable.\n * JTreeTablePanel provides JScrollPane for displaying JTreeTable and JScrollBar for JTree\n * column of JTreeTable if necessary.\n *\n * @author Jiri Sedlacek\n */\npublic class JTreeTablePanel extends JPanel {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    //-----------------------------------------------------------------------\n    // Custom TreeTable Viewport\n    private static class CustomTreeTableViewport extends JViewport {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private JTableHeader tableHeader;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        CustomTreeTableViewport(JTreeTable treeTable) {\n            super();\n            setView(treeTable);\n            setBackground(treeTable.getBackground());\n            this.tableHeader = treeTable.getTableHeader();\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        @Override\n        public void paint(Graphics g) {\n            super.paint(g);\n\n            if (UIConstants.SHOW_TABLE_VERTICAL_GRID) {\n                paintVerticalLines(g);\n            }\n        }\n\n        private void paintVerticalLines(Graphics g) {\n            Component view = getView();\n            int linesTop = view == null ? 0 : view.getHeight();\n            int linesBottom = getHeight() - 1;\n            if (linesTop > 0 && linesTop <= linesBottom) {\n                g.setColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);\n                int columnCount = tableHeader.getColumnModel().getColumnCount();\n                for (int i = 0; i < columnCount; i++) {\n                    Rectangle cellRect = tableHeader.getHeaderRect(i);\n                    int cellX = cellRect.x + cellRect.width - 1;\n                    g.drawLine(cellX, linesTop, cellX, linesBottom);\n                }\n            }\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    CustomTreeTableViewport treeTableViewport;\n    protected JPanel scrollBarPanel;\n    protected JScrollBar scrollBar;\n    protected JScrollPane treeTableScrollPane;\n    protected JTreeTable treeTable;\n\n    private int invisibleRowsCount = -1;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of JTreeTablePanel */\n    public JTreeTablePanel(JTreeTable treeTable) {\n        super(new BorderLayout());\n        this.treeTable = treeTable;\n\n        initComponents();\n        hookHeaderColumnResize();\n        hookScrollBarValueChange();\n        hookTreeCollapsedExpanded();\n\n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (isShowing()) {\n                        updateScrollBar(true);\n                    }\n                }\n            }\n        });\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void clearBorders() {\n        treeTableScrollPane.setBorder(BorderFactory.createEmptyBorder());\n        treeTableScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());\n    }\n    \n    public void setCorner(String key, java.awt.Component corner) {\n        treeTableScrollPane.setCorner(key, corner);\n    }\n\n    public JScrollPane getScrollPane() {\n        return treeTableScrollPane;\n    }\n\n    private void hookHeaderColumnResize() {\n        treeTable.getTableHeader().getColumnModel().addColumnModelListener(new TableColumnModelListener() {\n            public void columnAdded(TableColumnModelEvent e) {\n                treeTableViewport.repaint();\n            }\n\n            public void columnMoved(TableColumnModelEvent e) {\n                treeTableViewport.repaint();\n            }\n\n            public void columnRemoved(TableColumnModelEvent e) {\n                treeTableViewport.repaint();\n            }\n\n            public void columnMarginChanged(ChangeEvent e) {\n                treeTableViewport.repaint();\n                updateScrollBar(true);\n            }\n\n            public void columnSelectionChanged(ListSelectionEvent e) {}\n        });\n    }\n\n    private void hookScrollBarValueChange() {\n        scrollBar.addAdjustmentListener(new AdjustmentListener() {\n            public void adjustmentValueChanged(final AdjustmentEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        treeTable.setTreeCellOffsetX(e.getValue());\n                        if (!e.getValueIsAdjusting()) updateScrollBar(false);\n                    }\n                });\n            }\n        });\n    }\n\n    private void hookTreeCollapsedExpanded() {\n        treeTable.getTree().addTreeExpansionListener(new TreeExpansionListener() {\n            public void treeCollapsed(TreeExpansionEvent event) {\n                updateSB();\n            }\n            public void treeExpanded(TreeExpansionEvent event) {\n                updateSB();\n            }\n            private void updateSB() {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { updateScrollBar(false); }\n                });\n            }\n        });\n    }\n\n    private void initComponents() {\n        setBorder(BorderFactory.createEmptyBorder());\n\n        treeTableScrollPane = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n        treeTableViewport = new CustomTreeTableViewport(treeTable);\n        treeTableScrollPane.setViewport(treeTableViewport);\n        // Enable vertical scrollbar only if needed\n        final JScrollBar vScrollBar = treeTableScrollPane.getVerticalScrollBar();\n        vScrollBar.getModel().addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                Component c = treeTableViewport.getView();\n                vScrollBar.setEnabled(JTreeTablePanel.this.isEnabled() &&\n                vScrollBar.getVisibleAmount() < vScrollBar.getMaximum());\n            }\n        });\n        vScrollBar.addAdjustmentListener(new AdjustmentListener() {\n            public void adjustmentValueChanged(AdjustmentEvent e) {\n                if (!e.getValueIsAdjusting()) updateScrollBar(false);\n            }\n        });\n        scrollBar = new JScrollBar(JScrollBar.HORIZONTAL);\n        scrollBar.setUnitIncrement(10);\n        scrollBarPanel = new JPanel(new BorderLayout());\n        scrollBarPanel.add(scrollBar, BorderLayout.WEST);\n        treeTable.setTreeCellOffsetX(0);\n        scrollBarPanel.setVisible(false);\n        scrollBar.addMouseWheelListener(new MouseWheelListener() {\n            public void mouseWheelMoved(MouseWheelEvent e) {\n                scroll(scrollBar, e);\n            }\n        });\n        \n        MouseWheelListener[] listeners = treeTableScrollPane.getMouseWheelListeners();\n        if (listeners != null && listeners.length == 1) {\n            final MouseWheelListener listener = listeners[0];\n            treeTableScrollPane.removeMouseWheelListener(listener);\n            treeTableScrollPane.addMouseWheelListener(new MouseWheelListener() {\n                public void mouseWheelMoved(MouseWheelEvent e) {\n                    if (onlyShift(e) && treeTable.columnAtPoint(e.getPoint()) == 0) {\n                        scroll(scrollBar, e);\n                    } else {\n                        listener.mouseWheelMoved(e);\n                    }\n                    treeTable.mouseWheelMoved(e);\n                }\n            });\n        }\n\n        add(treeTableScrollPane, BorderLayout.CENTER);\n        add(scrollBarPanel, BorderLayout.SOUTH);\n    }\n    \n    private static void scroll(final JScrollBar scroller, final MouseWheelEvent event) {\n        if (event.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {\n            int unitsToScroll = event.getUnitsToScroll();\n            if (unitsToScroll != 0) {\n                int direction = unitsToScroll < 0 ? -1 : 1;\n                int increment = scroller.getUnitIncrement(direction);\n                int oldValue = scroller.getValue();\n                int newValue = oldValue + increment * unitsToScroll;\n                newValue = Math.max(Math.min(newValue, scroller.getMaximum() -\n                           scroller.getVisibleAmount()), scroller.getMinimum());\n                if (oldValue != newValue) scroller.setValue(newValue);\n            }\n            event.consume();\n        }\n    }\n    \n    private static boolean onlyShift(MouseEvent e) {\n        return e.isShiftDown() && !(e.isAltDown() || e.isAltGraphDown() ||\n                                    e.isControlDown() || e.isMetaDown());\n    }\n\n    private void updateScrollBar(boolean updateWidth) {\n        if (!isShowing()) return;\n\n        boolean refreshScrollBar = false;\n\n        JTree tree = treeTable.getTree();\n        Point viewPos = treeTableViewport.getViewPosition();\n        int viewHeight = treeTableViewport.getHeight();\n        TreePath firstVisiblePath = tree.getClosestPathForLocation(viewPos.x, viewPos.y);\n        TreePath lastVisiblePath =  tree.getClosestPathForLocation(viewPos.x, viewPos.y + viewHeight - 1);\n        int firstVisibleRow = tree.getRowForPath(firstVisiblePath);\n        int lastVisibleRow = tree.getRowForPath(lastVisiblePath);\n\n        if (firstVisibleRow < 0) return;\n\n        Rectangle size = new Rectangle();\n        for (int row = firstVisibleRow; row <= lastVisibleRow; row++)\n            size.add(tree.getRowBounds(row));\n\n        int treeWidth = size.width + 3; // +3 means extra right margin\n        int columnWidth = treeTable.getColumnModel().getColumn(0).getWidth();\n        int treeOffset = treeTable.getTreeCellOffsetX();\n        int maximum = Math.max(treeWidth - columnWidth, treeOffset);\n\n        if (scrollBarPanel.isVisible() && maximum <= 0) {\n            int firstInvisibleRow = lastVisibleRow + 1;\n            int lastInvisibleRow = Math.min(lastVisibleRow + getInvisibleRowsCount(),\n                                            treeTable.getRowCount() - 1);\n            if (firstInvisibleRow <= lastInvisibleRow) {\n                size = new Rectangle();\n                for (int row = firstInvisibleRow; row <= lastInvisibleRow; row++)\n                    size.add(tree.getRowBounds(row));\n                size.width += 3;\n                int maximum2 = Math.max(size.width - columnWidth, treeOffset);\n                if (maximum2 > 0) {\n                    treeWidth = size.width;\n                    maximum = maximum2;\n                }\n            }\n        }\n\n        if (maximum <= 0) {\n            if (scrollBarPanel.isVisible()) {\n                treeTable.setTreeCellOffsetX(0);\n                scrollBarPanel.setVisible(false);\n                refreshScrollBar = true;\n            }\n        } else {\n            int value = treeOffset;\n            int extent = treeWidth;\n            if (!scrollBarPanel.isVisible()) {\n                scrollBarPanel.setVisible(true);\n                refreshScrollBar = true;\n            }\n            scrollBar.setValues(value, extent, 0, maximum + extent);\n        }\n\n        if (updateWidth) {\n            Dimension dim = scrollBar.getPreferredSize();\n            dim.width = treeTable.getColumnModel().getColumn(0).getWidth();\n            scrollBar.setPreferredSize(dim);\n            scrollBar.setBlockIncrement((int)((float)scrollBar.getModel().getExtent() * 0.95f));\n            refreshScrollBar = true;\n        }\n\n        if (refreshScrollBar) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    scrollBar.invalidate();\n                    validate();\n                    repaint();\n                }\n            });\n        }\n    }\n\n    private int getInvisibleRowsCount() {\n        if (invisibleRowsCount == -1)\n            invisibleRowsCount =\n                    (int)Math.ceil((float)scrollBar.getPreferredSize().height /\n                                   (float)treeTable.getRowHeight());\n\n        return invisibleRowsCount;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/treetable/TreeTableModel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.treetable;\n\nimport javax.swing.tree.TreeModel;\n\n\npublic interface TreeTableModel extends TreeModel {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Indicates whether the the value for node <code>node</code>,\n     * at column number <code>column</code> is editable.\n     */\n    public boolean isCellEditable(Object node, int column);\n\n    /**\n     * Returns the type for column number <code>column</code>.\n     */\n    public Class<?> getColumnClass(int column);\n\n    /**\n     * Returns the number ofs available column.\n     */\n    public int getColumnCount();\n\n    /**\n     * Returns the name for column number <code>column</code>.\n     */\n    public String getColumnName(int column);\n\n    /**\n     * Sets the value for node <code>node</code>,\n     * at column number <code>column</code>.\n     */\n    public void setValueAt(Object aValue, Object node, int column);\n\n    /**\n     * Returns the value to be displayed for node <code>node</code>,\n     * at column number <code>column</code>.\n     */\n    public Object getValueAt(Object node, int column);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/components/treetable/TreeTableModelAdapter.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.components.treetable;\n\nimport java.awt.Rectangle;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.List;\nimport javax.swing.*;\nimport javax.swing.event.TreeExpansionEvent;\nimport javax.swing.event.TreeExpansionListener;\nimport javax.swing.event.TreeModelEvent;\nimport javax.swing.event.TreeModelListener;\nimport javax.swing.table.AbstractTableModel;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.JTreeTable;\n\n\npublic class TreeTableModelAdapter extends AbstractTableModel {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected AbstractTreeTableModel treeTableModel;\n    protected JTree tree;\n    protected JTreeTable treeTable;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Constructs a TreeTableModelAdapter, bridging the given treeTable and the model\n     *\n     * @param treeTableModel the model to use\n     * @param treeTable      the table which is going to use this model\n     */\n    public TreeTableModelAdapter(AbstractTreeTableModel treeTableModel, JTreeTable treeTable) {\n        this.treeTable = treeTable;\n        this.tree = treeTable.getTree();\n        this.treeTableModel = treeTableModel;\n\n        tree.addTreeExpansionListener(new TreeExpansionListener() {\n                // Don't use fireTableRowsInserted() here; the selection model\n                // would get updated twice.\n                public void treeExpanded(TreeExpansionEvent event) {\n                    TreePath[] selectedPaths = tree.getSelectionPaths();\n                    fireTableDataChanged();\n                    tree.setSelectionPaths(selectedPaths);\n                }\n\n                public void treeCollapsed(TreeExpansionEvent event) {\n                    TreePath[] selectedPaths = tree.getSelectionPaths();\n                    fireTableDataChanged();\n                    tree.setSelectionPaths(selectedPaths);\n                }\n            });\n\n        // Install a TreeModelListener that can updateState the table when\n        // tree changes. We use delayedFireTableDataChanged as we can\n        // not be guaranteed the tree will have finished processing\n        // the event before us.\n        treeTableModel.addTreeModelListener(new TreeModelListener() {\n                public void treeNodesChanged(TreeModelEvent e) {\n                    delayedFireTableDataChanged();\n                }\n\n                public void treeNodesInserted(TreeModelEvent e) {\n                    delayedFireTableDataChanged();\n                }\n\n                public void treeNodesRemoved(TreeModelEvent e) {\n                    delayedFireTableDataChanged();\n                }\n\n                public void treeStructureChanged(TreeModelEvent e) {\n                    delayedFireTableDataChanged();\n                }\n            });\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * TableModel wrapper, passes it through to the model after\n     * fetching the right TreeTableNode for the given row.\n     */\n    public boolean isCellEditable(int row, int column) {\n        return treeTableModel.isCellEditable(nodeForRow(row), column);\n    }\n\n    /**\n     * TableModel wrapper, passes it through to the model.\n     */\n    public Class<?> getColumnClass(int column) {\n        return treeTableModel.getColumnClass(column);\n    }\n\n    /**\n     * TableModel wrapper, passes it through to the model.\n     */\n    public int getColumnCount() {\n        return treeTableModel.getColumnCount();\n    }\n\n    /**\n     * TableModel wrapper, passes it through to the model.\n     */\n    public String getColumnName(int column) {\n        return treeTableModel.getColumnName(column);\n    }\n\n    /**\n     * Returns a list of open paths in the tree, can be used to\n     * re-open the paths in a tree after a call to 'treeStructureChanged'\n     * (which causes all open paths to collapse)\n     */\n    public List<TreePath> getExpandedPaths() {\n        Enumeration<TreePath> expanded = tree.getExpandedDescendants(getRootPath());\n        List<TreePath> paths = new ArrayList<>();\n\n        if (expanded != null) {\n            while (expanded.hasMoreElements()) {\n                paths.add(expanded.nextElement());\n            }\n        }\n    \n        return paths;\n    }\n\n    /**\n     * Returns the (tree)path to the root of the model.\n     *\n     * @return\n     */\n    public TreePath getRootPath() {\n        return new TreePath(treeTableModel.getPathToRoot((CCTNode) treeTableModel.getRoot()));\n    }\n\n    /**\n     * TableModel wrapper, passes it through to the model.\n     */\n    public int getRowCount() {\n        return tree.getRowCount();\n    }\n\n    /**\n     * TableModel wrapper, passes it through to the model after\n     * fetching the right TreeTableNode for the given row.\n     */\n    public void setValueAt(Object value, int row, int column) {\n        treeTableModel.setValueAt(value, nodeForRow(row), column);\n    }\n\n    /**\n     * Returns the object on the given row and column.\n     */\n    public Object getValueAt(int row, int column) {\n        Object j = treeTableModel.getValueAt(nodeForRow(row), column);\n\n        return j;\n    }\n\n    /**\n     * Opens the root node.\n     */\n    public void expandRoot() {\n        tree.expandPath(getRootPath());\n    }\n\n    /**\n     * Restores the given open paths on the treeModel.\n     *\n     * @param paths a List of TreePaths which are going to be opened.\n     */\n    public void restoreExpandedPaths(List<TreePath> paths) {\n        tree.putClientProperty(UIUtils.PROP_EXPANSION_TRANSACTION, Boolean.TRUE); // NOI18N\n        for (TreePath p : paths) {\n            tree.expandPath(p);\n        }\n        tree.putClientProperty(UIUtils.PROP_EXPANSION_TRANSACTION, Boolean.FALSE); // NOI18N\n    }\n    \n    private TreePath getCurrentPath(TreePath oldPath) {\n        if (oldPath == null || oldPath.getPathCount() < 1) return null;\n        if (!treeTableModel.getRoot().equals(oldPath.getPathComponent(0))) return null;\n        \n        TreePath p = getRootPath();\n        Object[] op = oldPath.getPath();\n        CCTNode n = (CCTNode)treeTableModel.getRoot();\n        \n        for (int i = 1; i < op.length; i++) {\n            // #241115\n            CCTNode[] children = n.getChildren();\n            if (children == null) return null;\n            \n            CCTNode nn = null;\n            \n            for (CCTNode c : children)\n                if (c.equals(op[i])) {\n                    nn = c;\n                    break;\n                }\n            \n            if (nn == null) return null;\n            \n            n = nn;\n            p = p.pathByAddingChild(n);\n        }\n        \n        return p;\n    }\n\n    public void updateTreeTable() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                List<TreePath> pathState = getExpandedPaths();\n\n                TreePath[] selectedPaths = tree.getSelectionPaths();\n                tree.getSelectionModel().clearSelection();\n                treeTableModel.fireTreeStructureChanged(this,\n                        treeTableModel.getPathToRoot((CCTNode) treeTableModel.getRoot()),\n                        null, null);\n                \n                if (selectedPaths != null)\n                    for (int i = 0; i < selectedPaths.length; i++)\n                        selectedPaths[i] = getCurrentPath(selectedPaths[i]);\n                tree.setSelectionPaths(selectedPaths);\n\n                restoreExpandedPaths(pathState);\n\n                treeTable.getTableHeader().repaint();\n\n                delayedFireTableDataChanged();\n            }\n        });\n    }\n    \n    public void changeRoot(final CCTNode newRoot) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                List<TreePath> pathState = getExpandedPaths();\n                TreePath[] selectedPaths = tree.getSelectionPaths();\n\n                treeTableModel.setRoot(newRoot);\n                tree.getSelectionModel().clearSelection();\n                treeTableModel.fireTreeStructureChanged(this,\n                                                        treeTableModel.getPathToRoot((CCTNode) treeTableModel.getRoot()),\n                                                        null, null);\n\n                if (selectedPaths != null)\n                    for (int i = 0; i < selectedPaths.length; i++)\n                        selectedPaths[i] = getCurrentPath(selectedPaths[i]);\n                List<TreePath> expandedPaths = new ArrayList<>();\n                for (TreePath tp : pathState)\n                    expandedPaths.add(getCurrentPath(tp));\n\n                tree.setSelectionPaths(selectedPaths);\n                restoreExpandedPaths(expandedPaths);\n\n                treeTable.getTableHeader().repaint();\n\n                delayedFireTableDataChanged();\n            }\n        });\n    }\n    \n    public void setup(List<TreePath> expanded, final TreePath selected) {\n        tree.getSelectionModel().clearSelection();\n        treeTableModel.fireTreeStructureChanged(this,\n                                                treeTableModel.getPathToRoot((CCTNode) treeTableModel.getRoot()),\n                                                null, null);\n        treeTable.getTableHeader().repaint();\n        fireTableDataChanged();\n        \n        if (expanded != null) restoreExpandedPaths(expanded);\n        if (selected != null) {\n            tree.setSelectionPath(selected);\n            final Rectangle rect = tree.getPathBounds(selected);\n            if (rect != null) {\n                // scroll immediately\n                treeTable.scrollRectToVisible(tree.getPathBounds(selected));\n                // make sure the rect is still visible after eventually showing the horizontal scrollbar\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { treeTable.scrollRectToVisible(rect); }\n                });\n            }\n        }\n    }\n    \n    private boolean firingChange;\n    public final boolean isFiringChange() {\n        return firingChange;\n    }\n\n    /**\n     * Invokes fireTableDataChanged after all the pending events have been\n     * processed. SwingUtilities.invokeLater is used to handle this.\n     */\n    protected void delayedFireTableDataChanged() {\n        SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    TreePath[] selectedPaths = tree.getSelectionPaths();\n                    firingChange = true;\n                    try {\n                        fireTableDataChanged();\n                    } finally {\n                        firingChange = false;\n                    }\n                    tree.setSelectionPaths(selectedPaths);\n                }\n            });\n    }\n    \n    /**\n     * Returns the object (TreeTableNode) on the given row in the tree.\n     */\n    protected Object nodeForRow(int row) {\n        TreePath treePath = tree.getPathForRow(row);\n\n        if (treePath != null) {\n            return treePath.getLastPathComponent();\n        } else {\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/Bundle.properties",
    "content": "# Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nCCTDisplay_MethodColumnName=Call Tree - Method\nCCTDisplay_MethodColumnToolTip=Call Tree - Method calls\nCCTDisplay_ClassColumnName=Call Tree - Class\nCCTDisplay_ClassColumnToolTip=Call Tree - Method calls aggregated per class\nCCTDisplay_PackageColumnName=Call Tree - Package\nCCTDisplay_PackageColumnToolTip=Call Tree - Method calls aggregated per package\nCCTDisplay_TimeRelColumnName=Total Time [%]\nCCTDisplay_TimeColumnName=Total Time\nCCTDisplay_TimeCpuColumnName=Total Time (CPU)\nCCTDisplay_ExportedAdditionalColumnName=Parent Node\nCCTDisplay_InvocationsColumnName=Invocations\nCCTDisplay_SamplesColumnName=Samples\nCCTDisplay_TimeRelColumnToolTip=Time spent in all invocations of the method [%]\nCCTDisplay_TimeColumnToolTip=Time spent in all invocations of the method\nCCTDisplay_TimeCpuColumnToolTip=Time spent in all invocations of the method (CPU Timer - estimated real CPU use time)\nCCTDisplay_InvocationsColumnToolTip=Number of times the method was called\nCCTDisplay_SamplesColumnToolTip=Minimum number of times the method was called\nCCTDisplay_TreeTableAccessName=Treetable with collected profiling results.\n\nCPUResultsPanel_GoToSourceItemName=Go To Source\nCPUResultsPanel_BackTracesItemName=Show Back Traces\nCPUResultsPanel_SubtreeItemName=Show Subtree\nCPUResultsPanel_RootMethodsItemName=Add to Instrumentation Roots...\n\nCodeRegionLivePanel_PanelName=Live Code Fragment Results\nCodeRegionLivePanel_NoResultsTerminatedMsg=No results to display, the target application has terminated.\nCodeRegionLivePanel_NoResultsRegionMsg=No results to display yet.\\nProbably the program entered the profiled code region, but not yet exited it.\nCodeRegionLivePanel_IndividualTimesMsg={0} ms.\nCodeRegionLivePanel_SummaryTimesMsg={0} ms. total, {1} ms. average, {2} ms. minimum, {3} ms. maximum\n# HTML-formatted\nCodeRegionLivePanel_TotalInvocationsMsg=Total of <b>{0}</b> invocations\nCodeRegionLivePanel_AllRememberedMsg=all results remembered\n# HTML-formatted\nCodeRegionLivePanel_LastRememberedMsg=last <b>{0}</b> results remembered\n# HTML-formatted\nCodeRegionLivePanel_InvocationsListedMsg=<b>{0}</b> invocations listed\nCodeRegionLivePanel_AreaAccessName=Collected profiling results.\n\nCodeRegionSnapshotPanel_PanelName=Code Fragment\\: {0}\nCodeRegionSnapshotPanel_NoResultsRegionMsg=No results to display yet.\\nProbably the program entered the profiled code region, but not yet exited it.\nCodeRegionSnapshotPanel_IndividualTimesMsg={0} ms.\nCodeRegionSnapshotPanel_SummaryTimesMsg={0} ms. total, {1} ms. average, {2} ms. minimum, {3} ms. maximum\n# HTML-formatted\nCodeRegionSnapshotPanel_TotalInvocationsMsg=Total of <b>{0}</b> invocations\nCodeRegionSnapshotPanel_AllRememberedMsg=all results remembered\n# HTML-formatted\nCodeRegionSnapshotPanel_LastRememberedMsg=last <b>{0}</b> results remembered\n# HTML-formatted\nCodeRegionSnapshotPanel_InvocationsListedMsg=<b>{0}</b> invocations listed\nCodeRegionSnapshotPanel_AreaAccessName=Collected profiling results.\n\nFlatProfilePanel_FilterItemName=Filter\nFlatProfilePanel_MethodColumnName=Hot Spots - Method\nFlatProfilePanel_MethodColumnToolTip=Hot Spots - Methods with largest self time\nFlatProfilePanel_MethodFilterHint=Method Name Filter\nFlatProfilePanel_ClassColumnName=Hot Spots - Class\nFlatProfilePanel_ClassColumnToolTip=Hot Spots - Classes with largest self time\nFlatProfilePanel_ClassFilterHint=Class Name Filter\nFlatProfilePanel_PackageColumnName=Hot Spots - Package\nFlatProfilePanel_PackageColumnToolTip=Hot Spots - Packages with largest self time\nFlatProfilePanel_PackageFilterHint=Package Name Filter\nFlatProfilePanel_SelfTimeRelColumnName=Self Time [%]\nFlatProfilePanel_SelfTimeRelColumnToolTip=Time spent in all invocations on this method (excluding further method calls) [%]\nFlatProfilePanel_SelfTimeColumnName=Self Time\nFlatProfilePanel_SelfTimeColumnToolTip=Time spent in all invocations on this method (excluding further method calls)\nFlatProfilePanel_SelfTimeCpuColumnName=Self Time (CPU)\nFlatProfilePanel_SelfTimeCpuColumnToolTip=Time spent in all invocations on this method (excluding further method calls) (CPU Timer - estimated real CPU use time)\nFlatProfilePanel_TotalTimeColumnName=Total Time\nFlatProfilePanel_TotalTimeColumnToolTip=Time spent in all invocations on this method (including further method calls)\nFlatProfilePanel_TotalTimeCpuColumnName=Total Time (CPU)\nFlatProfilePanel_TotalTimeCpuColumnToolTip=Time spent in all invocations on this method (including further method calls) (CPU Timer - estimated real CPU use time)\nFlatProfilePanel_InvocationsColumnName=Invocations\nFlatProfilePanel_SamplesColumnName=Samples\nFlatProfilePanel_InvocationsColumnToolTip=Number of times the method was called\nFlatProfilePanel_SamplesColumnToolTip=Minimum number of times the method was called\nFlatProfilePanel_TableAccessName=Table with collected profiling results.\nFlatProfilePanel_NoRelevantData=No relevant data available.\n\nLiveFlatProfilePanel_NoResultsString=No profiling results matching selected criteria available\n\nReverseCallGraphPanel_PanelTitle=Back Traces for {0}\nReverseCallGraphPanel_PanelTitleShort=Back Traces for\\: {0}\nReverseCallGraphPanel_GoToSourcePopupItem=Go To Source\nReverseCallGraphPanel_AddRootMethodPopupItem=Add to Instrumentation Roots...\nReverseCallGraphPanel_MethodColumnName=Back Traces - Method\nReverseCallGraphPanel_MethodColumnToolTip=Back Traces - Reverse method invocation call tree\nReverseCallGraphPanel_ClassColumnName=Back Traces - Class\nReverseCallGraphPanel_ClassColumnToolTip=Back Traces - Reverse method invocation call tree aggregated per class\nReverseCallGraphPanel_PackageColumnName=Back Traces - Package\nReverseCallGraphPanel_PackageColumnToolTip=Back Traces - Reverse method invocation call tree aggregated per package\nReverseCallGraphPanel_TimeRelColumnName=Total Time [%]\nReverseCallGraphPanel_TimeRelColumnToolTip=Time spent in all invocations of the method [%]\nReverseCallGraphPanel_TimeColumnName=Total Time\nReverseCallGraphPanel_TimeColumnToolTip=Time spent in all invocations of the method\nReverseCallGraphPanel_TimeCpuColumnName=Total Time (CPU)\nReverseCallGraphPanel_TimeCpuColumnToolTip=Time spent in all invocations of the method (CPU Timer - estimated real CPU use time)\nReverseCallGraphPanel_InvocationsColumnName=Invocations\nReverseCallGraphPanel_InvocationsColumnToolTip=Number of times the method was called\nReverseCallGraphPanel_TreeTableAccessName=Treetable with collected profiling results.\n\nStatisticsPanel_ScopeLabelText=Scope\\:\n\nSubtreeCallGraphPanel_PanelTitle=Subtree for\\: Method={1}; Thread={0}\nSubtreeCallGraphPanel_PanelTitleShort=Subtree for\\: {1}[{0}]\nSubtreeCallGraphPanel_GoToSourcePopupItem=Go To Source\nSubtreeCallGraphPanel_AddRootMethodPopupItem=Add to Instrumentation Roots...\nSubtreeCallGraphPanel_MethodColumnName=Subtree - Method\nSubtreeCallGraphPanel_MethodColumnToolTip=Subtree - Invocation call tree\nSubtreeCallGraphPanel_ClassColumnName=Subtree - Class\nSubtreeCallGraphPanel_ClassColumnToolTip=Subtree - Invocation call tree aggregated per class\nSubtreeCallGraphPanel_PackageColumnName=Subtree - Package\nSubtreeCallGraphPanel_PackageColumnToolTip=Subtree - Invocation call tree aggregated per package\nSubtreeCallGraphPanel_TimeRelColumnName=Total Time [%]\nSubtreeCallGraphPanel_TimeRelColumnToolTip=Time spent in all invocations of the method [%]\nSubtreeCallGraphPanel_TimeColumnName=Total Time\nSubtreeCallGraphPanel_TimeColumnToolTip=Time spent in all invocations of the method\nSubtreeCallGraphPanel_TimeCpuColumnName=Total Time (CPU)\nSubtreeCallGraphPanel_TimeCpuColumnToolTip=Time spent in all invocations of the method (CPU Timer - estimated real CPU use time)\nSubtreeCallGraphPanel_InvocationsColumnName=Invocations\nSubtreeCallGraphPanel_InvocationsColumnToolTip=Number of times the method was called\nSubtreeCallGraphPanel_TreeTableAccessName=Treetable with collected profiling results.\n\nCPUView_ExportTooltip=Export data to file or image\nCPUView_ExportMethods=Export {0}\nCPUView_ExportForwardCalls=Forward Calls\nCPUView_ExportHotSpots=Hot Spots\nCPUView_ExportReverseCalls=Reverse Calls\nCPUView_ColumnName=Name\nCPUView_ColumnSelfTime=Self Time\nCPUView_ColumnSelfTimeCpu=Self Time (CPU)\nCPUView_ColumnTotalTime=Total Time\nCPUView_ColumnTotalTimeCpu=Total Time (CPU)\nCPUView_ColumnHits=Hits\nCPUView_ColumnInvocations=Invocations\nCPUView_ColumnSelected=Selected\nCPUView_ActionGoToSource=Go to Source\nCPUView_ActionProfileMethod=Profile Method\nCPUView_ActionProfileClass=Profile Class\nCPUView_FindInForwardCalls=Find in Forward Calls\nCPUView_FindInHotSpots=Find in Hot Spots\nCPUView_FindInReverseCalls=Find in Reverse Calls\nCPUView_SelectedColumnTooltip=Selected for focused (instrumented) profiling\nCPUView_NameColumnTooltip=Method name\nCPUView_SelfTimeColumnTooltip=Time spent in all invocations excluding outgoing calls\nCPUView_SelfTimeCpuColumnTooltip=Time spent in all invocations excluding outgoing calls (real CPU time)\nCPUView_TotalTimeColumnTooltip=Time spent in all invocations including outgoing calls\nCPUView_TotalTimeCpuColumnTooltip=Time spent in all invocations including outgoing calls (real CPU time)\nCPUView_HitsColumnTooltip=Minimum number of invocations\nCPUView_InvocationsColumnTooltip=Number of invocations\nCPUView_FilterCalleesScope=Filter Callees\nCPUView_FilterCallersScope=Filter Callers\nCPUView_FilterScopeTooltip=Filter scope\nCPUView_SearchCalleesScope=Search Callees\nCPUView_SearchCallersScope=Search Callers\nCPUView_SearchScopeTooltip=Search scope\nCPUView_HideZeroSelfTimeTooltip=Hide Nodes With Zero Self Time\nCPUView_ExpandMenu=Expand / Collapse\nCPUView_ExpandPlainItem=Expand Plain Path\nCPUView_ExpandTopmostItem=Expand Topmost Path\nCPUView_CollapseChildrenItem=Collapse Children\nCPUView_CollapseAllItem=Collapse All\nCPUView_ShowMenu=Show / Hide\nCPUView_ShowThreadItem=Show Only This Thread\nCPUView_HideThreadItem=Hide This Thread\n\nSnapshotCPUView_ToolbarView=View\\:\nSnapshotCPUView_ViewForward=Forward calls\nSnapshotCPUView_ViewHotSpots=Hot spots\nSnapshotCPUView_ViewReverse=Reverse calls\nSnapshotCPUView_ToolbarAggregation=Aggregation\\:\nSnapshotCPUView_AggregationMethods=Methods\nSnapshotCPUView_AggregationClasses=Classes\nSnapshotCPUView_AggregationPackages=Packages\nSnapshotCPUView_CompareSnapshots=Compare with another snapshot...\nSnapshotCPUView_ResetCompareSnapshots=Reset snapshots comparison\n\nThreadsSelector_SelectThreads=Select threads\\:\nThreadsSelector_SelectedThreads=Select threads ({0} selected)\nThreadsSelector_SelectedThreadsAll=Select threads (all selected)\nThreadsSelector_NoThreads=No threads available\nThreadsSelector_AllThreads=Show all threads\nThreadsSelector_FilterThreads=Filter threads\nThreadsSelector_MergeThreads=Merge selected threads\nThreadsSelector_AllThreadsToolTip=Show results for all threads\nThreadsSelector_MergeThreadsToolTip=Merge results for selected threads\nThreadsSelector_MergeThreadsToolTipDisabled=Merge results for selected threads (disabled for all threads)\nThreadsSelector_ColumnSelected=Selected\nThreadsSelector_ColumnThread=Thread\nThreadsSelector_ColumnSelectedToolTip=Selected for displaying\nThreadsSelector_ColumnThreadToolTip=Thread name\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/CCTDisplay.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.AWTKeyStroke;\nimport java.awt.BorderLayout;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.FocusListener;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyAdapter;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.image.BufferedImage;\nimport java.util.HashSet;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.jfluid.results.FilterSortSupport;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNodeBacked;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.FilterComponent;\nimport org.graalvm.visualvm.lib.ui.components.JTreeTable;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelBracketTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.SortableTableModel;\nimport org.graalvm.visualvm.lib.ui.components.tree.EnhancedTreeCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.tree.MethodNameTreeCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.treetable.AbstractTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.ExtendedTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.JTreeTablePanel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.TreeTableModel;\n\n\n/**\n * A display containing a CCT (calling context tree). Always appears together with flat profile display.\n *\n * @author Misha Dmitriev\n * @author Jiri Sedlacek\n * @author Ian Formanek\n */\npublic class CCTDisplay extends SnapshotCPUResultsPanel implements ScreenshotProvider {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.cpu.Bundle\"); // NOI18N\n    private static final String METHOD_COLUMN_NAME = messages.getString(\"CCTDisplay_MethodColumnName\"); // NOI18N\n    private static final String METHOD_COLUMN_TOOLTIP = messages.getString(\"CCTDisplay_MethodColumnToolTip\"); // NOI18N\n    private static final String METHOD_FILTER_HINT = messages.getString(\"FlatProfilePanel_MethodFilterHint\"); // NOI18N\n    private static final String CLASS_COLUMN_NAME = messages.getString(\"CCTDisplay_ClassColumnName\"); // NOI18N\n    private static final String CLASS_COLUMN_TOOLTIP = messages.getString(\"CCTDisplay_ClassColumnToolTip\"); // NOI18N\n    private static final String CLASS_FILTER_HINT = messages.getString(\"FlatProfilePanel_ClassFilterHint\"); // NOI18N\n    private static final String PACKAGE_COLUMN_NAME = messages.getString(\"CCTDisplay_PackageColumnName\"); // NOI18N\n    private static final String PACKAGE_COLUMN_TOOLTIP = messages.getString(\"CCTDisplay_PackageColumnToolTip\"); // NOI18N\n    private static final String PACKAGE_FILTER_HINT = messages.getString(\"FlatProfilePanel_PackageFilterHint\"); // NOI18N\n    private static final String TIME_REL_COLUMN_NAME = messages.getString(\"CCTDisplay_TimeRelColumnName\"); // NOI18N\n    private static final String TIME_COLUMN_NAME = messages.getString(\"CCTDisplay_TimeColumnName\"); // NOI18N\n    private static final String TIME_CPU_COLUMN_NAME = messages.getString(\"CCTDisplay_TimeCpuColumnName\"); // NOI18N\n    private static final String INVOCATIONS_COLUMN_NAME = messages.getString(\"CCTDisplay_InvocationsColumnName\"); // NOI18N\n    private static final String SAMPLES_COLUMN_NAME = messages.getString(\"CCTDisplay_SamplesColumnName\"); // NOI18N\n    private static final String TIME_REL_COLUMN_TOOLTIP = messages.getString(\"CCTDisplay_TimeRelColumnToolTip\"); // NOI18N\n    private static final String TIME_COLUMN_TOOLTIP = messages.getString(\"CCTDisplay_TimeColumnToolTip\"); // NOI18N\n    private static final String TIME_CPU_COLUMN_TOOLTIP = messages.getString(\"CCTDisplay_TimeCpuColumnToolTip\"); // NOI18N\n    private static final String INVOCATIONS_COLUMN_TOOLTIP = messages.getString(\"CCTDisplay_InvocationsColumnToolTip\"); // NOI18N\n    private static final String SAMPLES_COLUMN_TOOLTIP = messages.getString(\"CCTDisplay_SamplesColumnToolTip\"); // NOI18N\n    private static final String TREETABLE_ACCESS_NAME = messages.getString(\"CCTDisplay_TreeTableAccessName\"); // NOI18N\n    private static final String FILTER_ITEM_NAME = messages.getString(\"FlatProfilePanel_FilterItemName\"); // NOI18N\n                                                                                                              // -----\n    private static final boolean DEBUG = System.getProperty(\"org.graalvm.visualvm.lib.ui.cpu.CCTDisplay\") != null; // NOI18N\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected JTreeTable treeTable;\n    protected JTreeTablePanel treeTablePanel;\n    protected FilterComponent filterComponent;\n    protected boolean sortOrder;\n    protected int sortingColumn;\n    private AbstractTreeTableModel abstractTreeTableModel;\n    private CPUSelectionHandler selectionHandler;\n    private EnhancedTreeCellRenderer enhancedTreeCellRenderer = new MethodNameTreeCellRenderer();\n    private ExtendedTreeTableModel treeTableModel;\n    private Icon leafIcon = Icons.getIcon(ProfilerIcons.NODE_LEAF);\n    private Icon nodeIcon = Icons.getIcon(ProfilerIcons.NODE_FORWARD);\n    private JButton cornerButton;\n    private int minNamesColumnWidth; // minimal width of classnames columns\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CCTDisplay(CPUResUserActionsHandler actionsHandler, Boolean sampling) {\n        this(actionsHandler, null, sampling);\n    }\n\n    public CCTDisplay(CPUResUserActionsHandler actionsHandler, CPUSelectionHandler selectionHandler, Boolean sampling) {\n        super(actionsHandler, sampling);\n\n        this.selectionHandler = selectionHandler;\n\n        enhancedTreeCellRenderer.setLeafIcon(leafIcon);\n        enhancedTreeCellRenderer.setClosedIcon(nodeIcon);\n        enhancedTreeCellRenderer.setOpenIcon(nodeIcon);\n\n        minNamesColumnWidth = getFontMetrics(getFont()).charWidth('W') * 30; // NOI18N\n\n        cornerPopup = new JPopupMenu();\n        cornerButton = createHeaderPopupCornerButton(cornerPopup);\n\n        setDefaultSorting();\n    }\n\n    public void exportData(int exportedFileType, ExportDataDumper eDD, boolean combine, String viewName) {\n        percentFormat.setMaximumFractionDigits(2);\n        percentFormat.setMinimumFractionDigits(2);\n        PrestimeCPUCCTNodeBacked.setPercentFormat(percentFormat);\n        switch (exportedFileType) {\n            case 1: eDD.dumpData(getCSVHeader(\",\")); //NOI18N\n                    ((PrestimeCPUCCTNodeBacked)abstractTreeTableModel.getRoot()).exportCSVData(\",\",exportedFileType, eDD);\n                    if (!combine) {\n                        eDD.close();\n                    }\n                    break;\n            case 2: eDD.dumpData(getCSVHeader(\";\")); //NOI18N\n                    ((PrestimeCPUCCTNodeBacked)abstractTreeTableModel.getRoot()).exportCSVData(\";\", exportedFileType, eDD);\n                    if (!combine) {\n                        eDD.close();\n                    }\n                    break;\n            case 3: eDD.dumpData(getXMLHeader(combine, viewName));\n                    ((PrestimeCPUCCTNodeBacked)abstractTreeTableModel.getRoot()).exportXMLData(eDD, \"  \");\n                    if (!combine) {\n                        eDD.dumpDataAndClose(getXMLFooter(combine));\n                    } else {\n                        eDD.dumpData(getXMLFooter(combine));\n                    }\n                    break;\n            case 4: eDD.dumpData(getHTMLHeader(viewName));\n                    ((PrestimeCPUCCTNodeBacked)abstractTreeTableModel.getRoot()).exportHTMLData(eDD, 0);\n                    if (!combine) {\n                        eDD.dumpDataAndClose(getHTMLFooter(combine));\n                    } else {\n                        eDD.dumpData(getHTMLFooter(combine));\n                    }\n\n                    break;\n        }\n        percentFormat.setMaximumFractionDigits(1);\n        percentFormat.setMinimumFractionDigits(0);\n    }\n    \n    public void clearSelection() {\n        treeTable.clearSelection();\n    }\n\n    private StringBuffer getCSVHeader(String separator) {\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n        StringBuffer result = new StringBuffer();\n        for (int i = 0; i < (columnCount); i++) {\n            result.append(quote).append(columnNames[i]).append(quote).append(separator);\n        }\n        result.append(newLine);\n        return result;\n    }\n\n    private StringBuffer getHTMLHeader(String viewName) {\n        StringBuffer result;\n        result=new StringBuffer(\"<HTML><HEAD><meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" /><TITLE>\"+viewName+\"</TITLE><style type=\\\"text/css\\\">pre.method{overflow:auto;width:600;height:30;vertical-align:baseline}pre.parent{overflow:auto;width:400;height:30;vertical-align:baseline}td.method{text-align:left;width:600}td.parent{text-align:left;width:400}td.right{text-align:right;white-space:nowrap}</style></HEAD><BODY><table border=\\\"1\\\"><tr>\"); // NOI18N\n        for (int i = 0; i < columnCount; i++) {\n            result.append(\"<th>\").append(columnNames[i]).append(columnNames[i].equals(\"Total Time\")?\" [&micro;s]\":\"\").append(\"</th>\"); // NOI18N\n        }\n        result.append(\"</tr>\"); //NOI18N\n\n        return result;\n    }\n\n    private StringBuffer getHTMLFooter(boolean combine) {\n        if (combine) {\n            return new StringBuffer(\"</TABLE>\"); //NOI18N\n        } else {\n            return new StringBuffer(\"</TABLE></BODY></HTML>\"); //NOI18N\n        }\n    }\n\n    private StringBuffer getXMLHeader(boolean combine, String viewName) {\n        String newline = System.lineSeparator();\n        StringBuffer result;\n        result = new StringBuffer(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"+newline+\"<ExportedView Name=\\\"\"+viewName+\"\\\" type=\\\"\"+((combine)?(\"combined\"):(\"tree\"))+\"\\\">\"+newline+\"<tree>\"+newline); // NOI18N\n        return result;\n    }\n\n    private StringBuffer getXMLFooter(boolean combine) {\n        String newline = System.lineSeparator();\n        StringBuffer result;\n        if (!combine) {\n            result = new StringBuffer(\"</tree>\"+newline+\"</ExportedView>\"); // NOI18N\n        } else {\n            result = new StringBuffer(\"</tree>\"+newline+newline); // NOI18N\n        }\n        \n        return result;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getCurrentThreadId() {\n        return -10;\n    } // A meaningless value to denote we don't display results for any\n      // single thread in this window\n\n    public BufferedImage getCurrentViewScreenshot(boolean onlyVisibleArea) {\n        if ((treeTablePanel == null) || (treeTable == null)) {\n            return null;\n        }\n\n        if (onlyVisibleArea) {\n            return UIUtils.createScreenshot(treeTablePanel.getScrollPane());\n        } else {\n            return UIUtils.createScreenshot(treeTable);\n        }\n    }\n\n    // NOTE: this method only sets sortingColumn, sortOrder and sortBy, it doesn't refresh UI!\n    public void setDefaultSorting() {\n        setSorting(1, SortableTableModel.SORT_ORDER_DESC);\n    }\n\n    public String getDefaultViewName() {\n        return \"cpu-calltree\"; // NOI18N\n    }\n\n    // --- Find functionality stuff\n    public void setFindString(String findString) {\n        treeTable.setFindParameters(findString, 0);\n    }\n\n    public String getFindString() {\n        return treeTable.getFindString();\n    }\n\n    public boolean isFindStringDefined() {\n        return treeTable.isFindStringDefined();\n    }\n\n    public Object getResultsViewReference() {\n        return treeTable;\n    }\n\n    // NOTE: this method only sets sortingColumn, sortOrder and sortBy, it doesn't refresh UI!\n    public void setSorting(int sColumn, boolean sOrder) {\n        setSorting(sColumn, sOrder, false);\n    }\n    \n    public void setSorting(int sColumn, boolean sOrder, boolean refreshUI) {\n        if (!refreshUI && sColumn == CommonConstants.SORTING_COLUMN_DEFAULT) {\n            setDefaultSorting();\n        } else {\n            sortingColumn = sColumn;\n            sortOrder = sOrder;\n\n            //sortBy = getSortBy(sortingColumn);\n        }\n        if (refreshUI) {\n            treeTable.setSortingColumn(treeTableModel.getVirtualColumn(sColumn));\n            treeTable.setSortingOrder(sOrder);\n            treeTableModel.sortByColumn(sColumn, sOrder);\n        }\n    }\n\n    public int getSortingColumn() {\n        if ((treeTable == null) || (treeTableModel == null)) {\n            return CommonConstants.SORTING_COLUMN_DEFAULT;\n        }\n\n        return treeTableModel.getRealColumn(treeTable.getSortingColumn());\n    }\n\n    public boolean getSortingOrder() {\n        if (treeTable == null) {\n            return false;\n        }\n\n        return treeTable.getSortingOrder();\n    }\n\n    public void addResultsViewFocusListener(FocusListener listener) {\n        treeTable.addFocusListener(listener);\n    }\n\n    public boolean findFirst() {\n        return treeTable.findFirst();\n    }\n\n    public boolean findNext() {\n        return treeTable.findNext();\n    }\n\n    public boolean findPrevious() {\n        return treeTable.findPrevious();\n    }\n\n    public boolean fitsVisibleArea() {\n        return !treeTablePanel.getScrollPane().getVerticalScrollBar().isEnabled();\n    }\n\n    public void prepareResults() {\n        int currentColumnCount = snapshot.isCollectingTwoTimeStamps() ? 5 : 4;\n\n        if (DEBUG) {\n            columnCount++; // one extra column for jMethodID\n        }\n\n        if (columnCount != currentColumnCount) {\n            initColumnsData();\n        } else {\n            if (treeTable != null) {\n                saveColumnsData();\n            }\n        }\n\n        if (treeTable != null) {\n            sortingColumn = treeTable.getSortingColumn();\n        }\n        \n        reset();\n        \n        if (filterComponent == null)\n            filterComponent = FilterComponent.create(true, true);\n        \n        initVariableColumnNames();\n\n        abstractTreeTableModel = new AbstractTreeTableModel(snapshot.getRootNode(currentView), sortingColumn, sortOrder) {\n                public int getColumnCount() {\n                    return columnCount;\n                }\n\n                public String getColumnName(int column) {\n                    return columnNames[column];\n                }\n\n                public Class<?> getColumnClass(int column) {\n                    if (column == 0) {\n                        return TreeTableModel.class;\n                    } else {\n                        return Object.class;\n                    }\n                }\n\n                public Object getValueAt(Object node, int column) {\n                    if (!snapshot.isCollectingTwoTimeStamps()) {\n                        if (column > 2) {\n                            column += 1;\n                        }\n                    }\n\n                    PrestimeCPUCCTNode pNode = (PrestimeCPUCCTNode) node;\n\n                    switch (column) {\n                        case 0:\n                            return pNode;\n                        case 1:\n                            return getNodeTimeRel(pNode.getTotalTime0(), pNode.getTotalTime0InPerCent());\n                        case 2:\n                            return getNodeTime(pNode.getTotalTime0(), pNode.getTotalTime0InPerCent());\n                        case 3:\n                            return getNodeSecondaryTime(pNode.getTotalTime1());\n                        case 4:\n                            return getNodeInvocations(pNode.getNCalls());\n                        case 5:\n                            return getNodeMethodId(pNode);\n                    }\n\n                    return null;\n                }\n\n                public String getColumnToolTipText(int col) {\n                    return columnToolTips[col];\n                }\n\n//                private Float getNodeTimeRel(PrestimeCPUCCTNode pNode) {\n//                    return new Float(pNode.getTotalTime0InPerCent());\n//                }\n//\n//                private String getNodeTime(PrestimeCPUCCTNode pNode) {\n//                    return StringUtils.mcsTimeToString(pNode.getTotalTime0()) + \" ms (\" // NOI18N\n//                           + percentFormat.format(pNode.getTotalTime0InPerCent() / 100) + \")\"; // NOI18N\n//                }\n//\n//                private String getNodeWaitTime(PrestimeCPUCCTNode pNode) {\n//                    return StringUtils.mcsTimeToString(pNode.getWaitTime0()) + \" ms\"; // NOI18N\n//                }\n//\n//                private String getNodeSleepTime(PrestimeCPUCCTNode pNode) {\n//                    return StringUtils.mcsTimeToString(pNode.getSleepTime0()) + \" ms\"; // NOI18N\n//                }\n//\n//                private String getNodeSecondaryTime(PrestimeCPUCCTNode pNode) {\n//                    return StringUtils.mcsTimeToString(pNode.getTotalTime1()) + \" ms\"; // NOI18N\n//                }\n//\n//                private Integer getNodeInvocations(PrestimeCPUCCTNode pNode) {\n//                    return Integer.valueOf(pNode.getNCalls());\n//                }\n\n                private Integer getNodeMethodId(PrestimeCPUCCTNode pNode) {\n                    return Integer.valueOf(pNode.getMethodId());\n                }\n\n                public void sortByColumn(int column, boolean order) {\n                    sortOrder = order;\n\n                    //sortingColumn = column;\n                    if (!snapshot.isCollectingTwoTimeStamps()) {\n                        if (column > 2) {\n                            column += 1;\n                        }\n                    }\n\n                    PrestimeCPUCCTNode pRoot = (PrestimeCPUCCTNode) root;\n\n                    //System.err.println(\">> CCT: \" + CCTDisplay.this.hashCode() + \" sortByColumn \" + column + \", \" + order);\n                    switch (column) {\n                        case 0:\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_NAME, order);\n\n                            break;\n                        case 1:\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_TIME_0, order);\n\n                            break;\n                        case 2:\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_TIME_0, order);\n\n                            break;\n                        case 3:\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_TIME_1, order);\n\n                            break;\n                        case 4:\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_INVOCATIONS, order);\n\n                            break;\n                    }\n                }\n\n                public boolean getInitialSorting(int column) {\n                    return (column == 0);\n                }\n            };\n\n        treeTableModel = new ExtendedTreeTableModel(abstractTreeTableModel);\n\n        if (columnsVisibility != null) {\n            treeTableModel.setColumnsVisibility(columnsVisibility);\n        }\n\n        treeTable = new JTreeTable(treeTableModel) {\n                public void doLayout() {\n                    int columnsWidthsSum = 0;\n                    int realFirstColumn = -1;\n\n                    int index;\n                    TableColumnModel colModel = getColumnModel();\n\n                    for (int i = 0; i < treeTableModel.getColumnCount(); i++) {\n                        index = treeTableModel.getRealColumn(i);\n\n                        if (index == 0) {\n                            realFirstColumn = i;\n                        } else {\n                            columnsWidthsSum += colModel.getColumn(i).getPreferredWidth();\n                        }\n                    }\n\n                    if (realFirstColumn != -1) {\n                        colModel.getColumn(realFirstColumn)\n                                .setPreferredWidth(Math.max(getWidth() - columnsWidthsSum, minNamesColumnWidth));\n                    }\n\n                    super.doLayout();\n                }\n        };\n        treeTable.getAccessibleContext().setAccessibleName(TREETABLE_ACCESS_NAME);\n\n        treeTable.setRowSelectionAllowed(true);\n        treeTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        treeTable.setGridColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);\n        treeTable.setSelectionBackground(UIConstants.TABLE_SELECTION_BACKGROUND_COLOR);\n        treeTable.setSelectionForeground(UIConstants.TABLE_SELECTION_FOREGROUND_COLOR);\n        treeTable.setShowHorizontalLines(UIConstants.SHOW_TABLE_HORIZONTAL_GRID);\n        treeTable.setShowVerticalLines(UIConstants.SHOW_TABLE_VERTICAL_GRID);\n        treeTable.setRowMargin(UIConstants.TABLE_ROW_MARGIN);\n        treeTable.setRowHeight(UIUtils.getDefaultRowHeight() + 2);\n        treeTable.getTree().setRootVisible(false);\n        treeTable.getTree().setShowsRootHandles(true);\n        treeTable.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)\n                 .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), \"DEFAULT_ACTION\"); // NOI18N\n        treeTable.getActionMap().put(\"DEFAULT_ACTION\",\n                                     new AbstractAction() {\n                public void actionPerformed(ActionEvent e) {\n                    performDefaultAction();\n                }\n            }); // NOI18N\n\n        // Disable traversing table cells using TAB and Shift+TAB\n        Set<AWTKeyStroke> keys = new HashSet<>(treeTable.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));\n        keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));\n        treeTable.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys);\n\n        keys = new HashSet<>(treeTable.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));\n        keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));\n        treeTable.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys);\n\n        setColumnsData();\n\n        UIUtils.autoExpandRoot(treeTable.getTree(), 2);\n        UIUtils.makeTreeAutoExpandable(treeTable.getTree(), 2);\n\n        treeTable.addKeyListener(new KeyAdapter() {\n                public void keyPressed(KeyEvent e) {\n                    if ((e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU)\n                            || ((e.getKeyCode() == KeyEvent.VK_F10) && (e.getModifiers() == InputEvent.SHIFT_MASK))) {\n                        int selectedRow = treeTable.getSelectedRow();\n\n                        if (selectedRow != -1) {\n                            popupPath = treeTable.getTree().getPathForRow(selectedRow);\n\n                            PrestimeCPUCCTNode node = (PrestimeCPUCCTNode) popupPath.getLastPathComponent();\n                            enableDisablePopup(node);\n\n                            Rectangle cellRect = treeTable.getCellRect(selectedRow, 0, false);\n                            callGraphPopupMenu.show(e.getComponent(), ((cellRect.x + treeTable.getSize().width) > 50) ? 50 : 5,\n                                                    cellRect.y);\n                        }\n                    }\n                }\n            });\n\n        treeTable.addMouseListener(new MouseAdapter() {\n                private void showPopupMenu(MouseEvent e) {\n                    popupPath = treeTable.getTree().getPathForRow(treeTable.rowAtPoint(e.getPoint()));\n\n                    if (popupPath == null) {\n                        treeTable.getTree().clearSelection();\n                    } else {\n                        treeTable.getTree().setSelectionPath(popupPath);\n                        PrestimeCPUCCTNode node = (PrestimeCPUCCTNode) popupPath.getLastPathComponent();\n\n                        enableDisablePopup(node);\n\n                        callGraphPopupMenu.show(e.getComponent(), e.getX(), e.getY());\n                    }\n                }\n                public void mousePressed(MouseEvent e) {\n                    if (e.isPopupTrigger()) showPopupMenu(e);\n                }\n                public void mouseReleased(MouseEvent e) {\n                    if (e.isPopupTrigger()) showPopupMenu(e);\n                }\n\n                public void mouseClicked(MouseEvent e) {\n                    popupPath = treeTable.getTree().getPathForRow(treeTable.rowAtPoint(e.getPoint()));\n\n                    if (popupPath != null) {\n                        treeTable.getTree().setSelectionPath(popupPath);\n\n                        if (SwingUtilities.isLeftMouseButton(e) && (e.getClickCount() == 2)) {\n                            if (treeTableModel.isLeaf(popupPath.getPath()[popupPath.getPath().length - 1])) {\n                                    showSourceForMethod(popupPath);\n                            }\n                        }\n                    }\n                }\n            });\n\n        treeTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent e) {\n                    int selectedRow = treeTable.getSelectedRow();\n\n                    if (selectedRow == -1) {\n                        return;\n                    }\n\n                    popupPath = treeTable.getTree().getPathForRow(selectedRow);\n\n                    PrestimeCPUCCTNode node = (PrestimeCPUCCTNode) popupPath.getLastPathComponent();\n\n                    if (selectionHandler != null) {\n                        selectionHandler.methodSelected(node.getThreadId(), node.getMethodId(), currentView);\n                    }\n                }\n            });\n\n        treeTablePanel = new JTreeTablePanel(treeTable);\n        treeTablePanel.clearBorders();\n        treeTablePanel.setCorner(JScrollPane.UPPER_RIGHT_CORNER, cornerButton);\n        add(treeTablePanel, java.awt.BorderLayout.CENTER);\n        initFilterPanel();\n    }\n    \n    protected Float getNodeTimeRel(long time, float percent) {\n        return new Float(percent);\n    }\n\n    protected String getNodeTime(long time, float percent) {\n        return StringUtils.mcsTimeToString(time) + \" ms (\" // NOI18N\n                + percentFormat.format(percent / 100) + \")\"; // NOI18N\n    }\n\n//    protected String getNodeWaitTime(PrestimeCPUCCTNode pNode) {\n//        return StringUtils.mcsTimeToString(pNode.getWaitTime0()) + \" ms\"; // NOI18N\n//    }\n//\n//    protected String getNodeSleepTime(PrestimeCPUCCTNode pNode) {\n//        return StringUtils.mcsTimeToString(pNode.getSleepTime0()) + \" ms\"; // NOI18N\n//    }\n\n    protected String getNodeSecondaryTime(long time) {\n        return StringUtils.mcsTimeToString(time) + \" ms\"; // NOI18N\n    }\n\n    protected String getNodeInvocations(int nCalls) {\n        return Integer.toString(nCalls);\n    }\n    \n    private void initFilterPanel() {        \n        FilterSortSupport.Configuration config = snapshot.getFilterSortInfo(\n                (PrestimeCPUCCTNode)treeTableModel.getRoot());\n        filterComponent.setFilter(config.getFilterString(), config.getFilterType());\n\n        filterComponent.addChangeListener(new ChangeListener() {\n                public void stateChanged(ChangeEvent e) {\n                    String filterString = filterComponent.getFilterValue();\n                    int filterType = filterComponent.getFilterType();\n                    snapshot.filterForward(filterString, filterType, (PrestimeCPUCCTNodeBacked)treeTableModel.getRoot());\n                    \n                    treeTable.updateTreeTable();\n                }\n            });\n\n        add(filterComponent.getComponent(), BorderLayout.SOUTH);\n    }\n\n    public void removeResultsViewFocusListener(FocusListener listener) {\n        treeTable.removeFocusListener(listener);\n    }\n\n    public void requestFocus() {\n        if (treeTable != null) {\n            SwingUtilities.invokeLater(new Runnable() { // must be invoked lazily to override default focus of first component (top-right cornerButton)\n                    public void run() {\n                        treeTable.requestFocus();\n                    }\n                });\n        }\n    }\n\n    public void reset() {\n        if (treeTablePanel != null) {\n            remove(treeTablePanel);\n            treeTablePanel = null;\n            remove(filterComponent.getComponent());\n            filterComponent = null;\n        }\n\n        treeTable = null;\n        abstractTreeTableModel = null;\n        treeTableModel = null;\n    }\n\n    public boolean silentlyFindFirst() {\n        return treeTable.silentlyFindFirst();\n    }\n\n    protected String getSelectedMethodName() {\n        if ((treeTable == null) || (treeTableModel == null)) {\n            return null;\n        }\n\n        if (treeTable.getSelectedRow() == -1) {\n            return null;\n        }\n\n        PrestimeCPUCCTNode pNode = (PrestimeCPUCCTNode) treeTable.getTree().getSelectionPath().getLastPathComponent();\n\n        if (pNode.isSelfTimeNode()) {\n            // Self time represents the same method as its parent Node, and the parent's display name is\n            // the actual method name\n            pNode = (PrestimeCPUCCTNode) pNode.getParent();\n        }\n\n        if (pNode.isThreadNode()) {\n            // For thread node, the method name is display name of its single child\n            pNode = (PrestimeCPUCCTNode) pNode.getChildren()[0];\n        }\n\n        return treeTableModel.getValueAt(pNode, 0).toString();\n    }\n\n    protected void initColumnSelectorItems() {\n        cornerPopup.removeAll();\n\n        JCheckBoxMenuItem menuItem;\n\n        for (int i = 0; i < columnCount; i++) {\n            menuItem = new JCheckBoxMenuItem(columnNames[i]);\n            menuItem.setActionCommand(Integer.toString(i));\n            addMenuItemListener(menuItem);\n\n            if (treeTable != null) {\n                menuItem.setState(treeTableModel.isRealColumnVisible(i));\n\n                if (i == 0) {\n                    menuItem.setEnabled(false);\n                }\n            } else {\n                menuItem.setState(true);\n            }\n\n            cornerPopup.add(menuItem);\n        }\n        \n        cornerPopup.addSeparator();\n\n        JCheckBoxMenuItem filterMenuItem = new JCheckBoxMenuItem(FILTER_ITEM_NAME);\n        filterMenuItem.setActionCommand(\"Filter\"); // NOI18N\n        addMenuItemListener(filterMenuItem);\n\n        if (filterComponent == null) {\n            filterMenuItem.setState(true);\n        } else {\n            filterMenuItem.setState(filterComponent.getComponent().isVisible());\n        }\n        \n        cornerPopup.add(filterMenuItem);\n\n        cornerPopup.pack();\n    }\n\n    private void setColumnsData() {\n        int index;\n        TableColumnModel colModel = treeTable.getColumnModel();\n\n        treeTable.setTreeCellRenderer(enhancedTreeCellRenderer);\n        colModel.getColumn(0).setPreferredWidth(minNamesColumnWidth);\n\n        for (int i = 0; i < treeTableModel.getColumnCount(); i++) {\n            index = treeTableModel.getRealColumn(i);\n\n            if (index != 0) {\n                colModel.getColumn(i).setPreferredWidth(columnWidths[index - 1]);\n                colModel.getColumn(i).setCellRenderer(columnRenderers[index]);\n            }\n        }\n    }\n\n    private void addMenuItemListener(JCheckBoxMenuItem menuItem) {\n        menuItem.addActionListener(new java.awt.event.ActionListener() {\n                public void actionPerformed(java.awt.event.ActionEvent e) {\n                    if (e.getActionCommand().equals(\"Filter\")) { // NOI18N\n                        filterComponent.getComponent().setVisible(!filterComponent.getComponent().isVisible());\n\n                        return;\n                    }\n                    \n                    boolean sortResults = false;\n                    int column = Integer.parseInt(e.getActionCommand());\n                    sortingColumn = treeTable.getSortingColumn();\n\n                    int realSortingColumn = treeTableModel.getRealColumn(sortingColumn);\n                    boolean isColumnVisible = treeTableModel.isRealColumnVisible(column);\n\n                    // Current sorting column is going to be hidden\n                    if ((isColumnVisible) && (column == realSortingColumn)) {\n                        // Try to set next column as a sortingColumn. If currentSortingColumn is the last column, set previous\n                        // column as a sorting Column (one column is always visible).\n                        sortingColumn = ((sortingColumn + 1) == treeTableModel.getColumnCount()) ? (sortingColumn - 1)\n                                                                                                 : (sortingColumn + 1);\n                        realSortingColumn = treeTableModel.getRealColumn(sortingColumn);\n                        sortResults = true;\n                    }\n\n                    treeTableModel.setRealColumnVisibility(column, !isColumnVisible);\n                    treeTable.createDefaultColumnsFromModel();\n                    treeTable.updateTreeTableHeader();\n                    sortingColumn = treeTableModel.getVirtualColumn(realSortingColumn);\n\n                    if (sortResults) {\n                        sortOrder = treeTableModel.getInitialSorting(sortingColumn);\n                        treeTableModel.sortByColumn(sortingColumn, sortOrder);\n                        treeTable.updateTreeTable();\n                    }\n\n                    treeTable.setSortingColumn(sortingColumn);\n                    treeTable.setSortingOrder(sortOrder);\n                    treeTable.getTableHeader().repaint();\n                    setColumnsData();\n\n                    // TODO [ui-persistence]\n                }\n            });\n    }\n\n    protected void enableDisablePopup(PrestimeCPUCCTNode node) {\n        boolean regularNode = node.getThreadId() != -1 && node.getMethodId() != 0 && !node.isFiltered();\n        if (popupShowSource != null) popupShowSource.setEnabled(regularNode && isShowSourceAvailable());\n        if (popupShowSubtree != null) popupShowSubtree.setEnabled(regularNode);\n        if (popupShowReverse != null) popupShowReverse.setEnabled(regularNode);\n        popupFind.setEnabled(regularNode);\n        // Allow the selection handler to change state of popupFind\n        if (selectionHandler != null) selectionHandler.methodSelected(node.getThreadId(), node.getMethodId(), currentView);\n    }\n\n    protected void initColumnsData() {\n        columnCount = snapshot.isCollectingTwoTimeStamps() ? 5 : 4;\n\n        if (DEBUG) {\n            columnCount++; // one extra column for jMethodID\n        }\n\n        columnWidths = new int[columnCount - 1]; // Width of the first column fits to width\n        columnNames = new String[columnCount];\n        columnRenderers = new TableCellRenderer[columnCount];\n        columnsVisibility = new boolean[columnCount];\n        for (int i = 0; i < columnCount - 1; i++)\n            columnsVisibility[i] = true;\n        if (isSampling() != null && !isSampling()) columnsVisibility[columnCount - 1] = true;\n\n        int idx = 0;\n        columnNames = new String[columnCount];\n        columnNames[idx++] = \"\"; // NOI18N\n        columnNames[idx++] = TIME_REL_COLUMN_NAME;\n        columnNames[idx++] = TIME_COLUMN_NAME;\n\n        if (snapshot.isCollectingTwoTimeStamps()) {\n            columnNames[idx++] = TIME_CPU_COLUMN_NAME;\n        }\n\n        columnNames[idx++] = isSampling() != null && isSampling() ? SAMPLES_COLUMN_NAME :\n                                        INVOCATIONS_COLUMN_NAME;\n\n        if (DEBUG) {\n            columnNames[idx++] = \"JMethodID\"; // NOI18N\n        }\n\n        idx = 0;\n        columnToolTips = new String[columnCount];\n        columnToolTips[idx++] = \"\"; // NOI18N\n        columnToolTips[idx++] = TIME_REL_COLUMN_TOOLTIP;\n        columnToolTips[idx++] = TIME_COLUMN_TOOLTIP;\n\n        if (snapshot.isCollectingTwoTimeStamps()) {\n            columnToolTips[idx++] = TIME_CPU_COLUMN_TOOLTIP;\n        }\n\n        columnToolTips[idx++] = isSampling() != null && isSampling() ? SAMPLES_COLUMN_TOOLTIP :\n                                           INVOCATIONS_COLUMN_TOOLTIP;\n\n        if (DEBUG) {\n            columnToolTips[idx++] = \"JMethodID for the method\"; // NOI18N\n        }\n\n        int maxWidth = getFontMetrics(getFont()).charWidth('W') * 12; // NOI18N // initial width of data columns\n\n        CustomBarCellRenderer customBarCellRenderer = new CustomBarCellRenderer(0, 100);\n        LabelTableCellRenderer labelTableCellRenderer = new LabelTableCellRenderer(JLabel.TRAILING);\n        LabelBracketTableCellRenderer labelBracketTableCellRenderer = new LabelBracketTableCellRenderer(JLabel.TRAILING);\n\n        columnRenderers[0] = null;\n\n        // Inclusive (total) time bar\n        columnWidths[1 - 1] = maxWidth;\n        columnRenderers[1] = customBarCellRenderer;\n\n        // Inclusive (total) time\n        columnWidths[2 - 1] = maxWidth;\n        columnRenderers[2] = labelBracketTableCellRenderer;\n\n        for (int i = 3; i < columnCount; i++) {\n            columnWidths[i - 1] = maxWidth;\n            columnRenderers[i] = labelTableCellRenderer;\n        }\n        \n        if (isSampling() == null) columnCount--;\n    }\n\n    private void initVariableColumnNames() {\n        switch (currentView) {\n            case CPUResultsSnapshot.METHOD_LEVEL_VIEW:\n                columnNames[0] = METHOD_COLUMN_NAME;\n                columnToolTips[0] = METHOD_COLUMN_TOOLTIP;\n                filterComponent.setHint(METHOD_FILTER_HINT);\n\n                break;\n            case CPUResultsSnapshot.CLASS_LEVEL_VIEW:\n                columnNames[0] = CLASS_COLUMN_NAME;\n                columnToolTips[0] = CLASS_COLUMN_TOOLTIP;\n                filterComponent.setHint(CLASS_FILTER_HINT);\n\n                break;\n            case CPUResultsSnapshot.PACKAGE_LEVEL_VIEW:\n                columnNames[0] = PACKAGE_COLUMN_NAME;\n                columnToolTips[0] = PACKAGE_COLUMN_TOOLTIP;\n                filterComponent.setHint(PACKAGE_FILTER_HINT);\n\n                break;\n        }\n\n        if (treeTable != null) {\n            treeTable.getTableHeader().repaint();\n        }\n    }\n\n    private void saveColumnsData() {\n        int index;\n        TableColumnModel colModel = treeTable.getColumnModel();\n\n        for (int i = 0; i < treeTableModel.getColumnCount(); i++) {\n            index = treeTableModel.getRealColumn(i);\n\n            if (index != 0) {\n                columnWidths[index - 1] = colModel.getColumn(i).getPreferredWidth();\n            }\n        }\n\n        columnsVisibility = treeTableModel.getColumnsVisibility();\n    }\n    \n    public void setColumnsVisibility(boolean[] columnsVisibility) {\n        treeTableModel.setColumnsVisibility(columnsVisibility);\n        treeTable.createDefaultColumnsFromModel();\n        treeTable.updateTreeTableHeader();\n        setColumnsData();\n    }\n    \n    public boolean[] getColumnsVisibility() {\n        return treeTableModel.getColumnsVisibility();\n    }\n    \n    public void setFilterVisible(boolean visible) {\n        if (filterComponent != null) filterComponent.getComponent().setVisible(visible);\n    }\n    \n    public boolean isFilterVisible() {\n        return filterComponent != null && filterComponent.getComponent().isVisible();\n    }\n    \n    public int getFilterType() {\n        return filterComponent.getFilterType();\n    }\n\n    public String getFilterValue() {\n        return filterComponent.getFilterValue();\n    }\n\n    public void setFilterValues(String filterValue, int filterType) {\n        filterComponent.setFilter(filterValue, filterType);\n    }\n\n    /*\n       public StringBuffer getResultsInCSVFormat(int callChainTypeCode, ExportDataDumper dataDumper) {\n         return snapshot.getResultsInCSVFormat(callChainTypeCode, dataDumper);\n       } */\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/CPUJavaNameRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport javax.swing.Icon;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class CPUJavaNameRenderer extends JavaNameRenderer {\n\n    private static final Icon THREAD_ICON = Icons.getIcon(ProfilerIcons.THREAD);\n    private static final Icon THREAD_ICON_DISABLED = UIManager.getLookAndFeel().getDisabledIcon(null, THREAD_ICON);\n    private static final Icon LEAF_ICON = Icons.getIcon(ProfilerIcons.NODE_LEAF);\n    private static final Icon LEAF_ICON_DISABLED = UIManager.getLookAndFeel().getDisabledIcon(null, LEAF_ICON);\n\n    private final Icon icon;\n    private final Icon iconDisabled;\n\n    public CPUJavaNameRenderer() {\n        this(ProfilerIcons.NODE_FORWARD);\n    }\n\n    public CPUJavaNameRenderer(String iconKey) {\n        this.icon = Icons.getIcon(iconKey);\n        this.iconDisabled = UIManager.getLookAndFeel().getDisabledIcon(null, icon);\n    }\n\n    public void setValue(Object value, int row) {\n        if (value instanceof PrestimeCPUCCTNode) {\n            PrestimeCPUCCTNode node = (PrestimeCPUCCTNode)value;\n\n            if (node.isSelfTimeNode()) {\n                setNormalValue(node.getNodeName());\n                setBoldValue(\"\"); // NOI18N\n                setGrayValue(\"\"); // NOI18N\n            } else if (node.isThreadNode()) {\n                setNormalValueEx(\"\"); // NOI18N\n                setBoldValue(node.getNodeName());\n                setGrayValue(\"\"); // NOI18N\n            } else if (node.isFiltered()) {\n                setNormalValue(\"\"); // NOI18N\n                setBoldValue(\"\");\n                setGrayValue(node.getNodeName()); // NOI18N\n            } else {\n                super.setValue(node.getNodeName(), row);\n            }\n            \n            if (node.isThreadNode()) {\n                setIcon(node.isFiltered() ? THREAD_ICON_DISABLED : THREAD_ICON);\n            } else if (node.isLeaf()) {\n                setIcon(node.isFiltered() ? LEAF_ICON_DISABLED : LEAF_ICON);\n            } else {\n                setIcon(node.isFiltered() ? iconDisabled : icon);\n            }\n        } else {\n            super.setValue(value, row);\n        }\n    }\n    \n    \n    // TODO: optimize to not slow down sort/search/filter by resolving color!\n    private void setNormalValueEx(String value) {\n        super.setNormalValue(value);\n        setCustomForeground(null);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/CPUResUserActionsHandler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\n\n\n/**\n * This interface declares actions that the user may initiate when browsing profiling results.\n * For example, the user may move the cursor to some method and request the tool to show its source\n * code, etc.\n *\n * @author Ian Formanek\n * @author Misha Dmitriev\n */\npublic interface CPUResUserActionsHandler {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class Adapter implements CPUResUserActionsHandler {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void addMethodToRoots(String className, String methodName, String methodSig) {\n            throw new UnsupportedOperationException();\n        }\n\n        public void find(Object source, String findString) {\n            throw new UnsupportedOperationException();\n        }\n\n        public void showReverseCallGraph(CPUResultsSnapshot snapshot, int threadId, int methodId, int view, int sortingColumn,\n                                         boolean sortingOrder) {\n            throw new UnsupportedOperationException();\n        }\n\n        public void showSourceForMethod(String className, String methodName, String methodSig) {\n            throw new UnsupportedOperationException();\n        }\n\n        public void showSubtreeCallGraph(CPUResultsSnapshot snapshot, CCTNode node, int view, int sortingColumn,\n                                         boolean sortingOrder) {\n            throw new UnsupportedOperationException();\n        }\n\n        public void viewChanged(int viewType) {\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void addMethodToRoots(String className, String methodName, String methodSig);\n\n    public void find(Object source, String findString);\n\n    public void showReverseCallGraph(CPUResultsSnapshot snapshot, int threadId, int methodId, int view, int sortingColumn,\n                                     boolean sortingOrder);\n\n    /**\n     * Display the source for the given method. className should never be null, but methodName and methodSig\n     * may be null (for example, if we are viewing results at class level). In that case, just the class\n     * source code should be displayed.\n     * @param className  The fully qualified class name in VM format (\"org/profiler/Main\");\n     * @param methodName The method name\n     * @param methodSig  The method signature in VM format\n     */\n    public void showSourceForMethod(String className, String methodName, String methodSig);\n\n    public void showSubtreeCallGraph(CPUResultsSnapshot snapshot, CCTNode node, int view, int sortingColumn, boolean sortingOrder);\n\n    /**\n     * Called when a view type change has been initiated from within a results component and the change should perhaps\n     * be reflected in other views / ui as well.\n     *\n     * @param viewType the new view type\n     */\n    public void viewChanged(int viewType);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/CPUResultsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.ui.ResultsPanel;\n\n\n/**\n * Common superclass for all results displays displaying CPU results.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic abstract class CPUResultsPanel extends ResultsPanel implements CommonConstants {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.cpu.Bundle\"); // NOI18N\n    private static final String GO_TO_SOURCE_ITEM_NAME = messages.getString(\"CPUResultsPanel_GoToSourceItemName\"); // NOI18N\n    private static final String BACKTRACES_ITEM_NAME = messages.getString(\"CPUResultsPanel_BackTracesItemName\"); // NOI18N\n    private static final String SUBTREE_ITEM_NAME = messages.getString(\"CPUResultsPanel_SubtreeItemName\"); // NOI18N\n    private static final String ROOT_METHODS_ITEM_NAME = messages.getString(\"CPUResultsPanel_RootMethodsItemName\"); // NOI18N\n                                                                                                                    // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected CPUResUserActionsHandler actionsHandler;\n    protected JMenuItem popupFind;\n    protected JMenuItem popupShowReverse;\n    protected JMenuItem popupShowSource;\n    protected JMenuItem popupShowSubtree;\n    protected JPopupMenu callGraphPopupMenu;\n    protected JPopupMenu cornerPopup;\n    protected TreePath popupPath;\n    protected String[] columnNames;\n    protected TableCellRenderer[] columnRenderers;\n    protected String[] columnToolTips;\n    protected int[] columnWidths;\n    protected boolean[] columnsVisibility;\n    protected int columnCount = 0;\n    protected int currentView; // View AKA aggregation level: CPUResultsSnapshot.METHOD_LEVEL, CLASS_LEVEL or PACKAGE_LEVEL\n    protected int methodId;\n    private Boolean sampling;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CPUResultsPanel(CPUResUserActionsHandler actionsHandler, Boolean sampling) {\n        this.actionsHandler = actionsHandler;\n        this.sampling = sampling;\n        callGraphPopupMenu = createPopupMenu();\n\n        if (popupFind != null) {\n            popupFind.setVisible(false);\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /** Returns a meaningful value only for those subclasses that present data for a single thread */\n    public abstract int getCurrentThreadId();\n\n    public int getCurrentView() {\n        return currentView;\n    }\n\n    public JMenuItem getPopupFindItem() {\n        return popupFind;\n    }\n\n    // Should be overridden whenever possible\n    public boolean getSortingOrder() {\n        return false;\n    }\n    \n    public Boolean isSampling() {\n        return sampling;\n    }\n\n    /** Changes the aggregation level for the CPU Results\n     *\n     * @param view one of CPUResultsSnapshot.METHOD_LEVEL_VIEW, CPUResultsSnapshot.CLASS_LEVEL_VIEW, CPUResultsSnapshot.PACKAGE_LEVEL_VIEW\n     *\n     * @see CPUResultsSnapshot#METHOD_LEVEL_VIEW\n     * @see CPUResultsSnapshot#CLASS_LEVEL_VIEW\n     * @see CPUResultsSnapshot#PACKAGE_LEVEL_VIEW\n     */\n    public void changeView(int view) {\n        if (currentView == view) {\n            return;\n        }\n\n        currentView = view;\n\n        if (popupShowSource != null) popupShowSource.setEnabled(isShowSourceAvailable());\n\n        actionsHandler.viewChanged(view); // notify the actions handler about this\n    }\n\n    public abstract void reset();\n\n    // Should be overridden whenever possible\n    public int getSortingColumn() {\n        return CommonConstants.SORTING_COLUMN_DEFAULT;\n    }\n\n    protected boolean isAddToRootsAvailable() {\n        return (currentView == CPUResultsSnapshot.METHOD_LEVEL_VIEW);\n    }\n\n    protected abstract String[] getMethodClassNameAndSig(int methodId, int currentView);\n\n    protected abstract String getSelectedMethodName();\n\n    protected boolean isShowSourceAvailable() {\n        return (currentView != CPUResultsSnapshot.PACKAGE_LEVEL_VIEW);\n    }\n\n    // ------------------------------------------------------------------\n    // Popup menu behavior\n    protected JPopupMenu createPopupMenu() {\n        JPopupMenu popup = new JPopupMenu();\n        if (GoToSource.isAvailable()) popupShowSource = new JMenuItem();\n        popupFind = new JMenuItem();\n\n        Font boldfont = popup.getFont().deriveFont(Font.BOLD);\n\n        ActionListener menuListener = this::menuActionPerformed;\n\n        boolean separator = true;\n        if (popupShowSource != null) {\n            popupShowSource.setFont(boldfont);\n            popupShowSource.setText(GO_TO_SOURCE_ITEM_NAME);\n            popup.add(popupShowSource);\n            separator = false;\n        }\n\n        if (supportsSubtreeCallGraph()) {\n            if (!separator) {\n                popup.addSeparator();\n                separator = true;\n            }\n\n            popupShowSubtree = new JMenuItem();\n            popupShowSubtree.setText(SUBTREE_ITEM_NAME);\n            popup.add(popupShowSubtree);\n            popupShowSubtree.addActionListener(menuListener);\n        }\n\n        if (supportsReverseCallGraph()) {\n            if (!separator) {\n                popup.addSeparator();\n                separator = true;\n            }\n\n            popupShowReverse = new JMenuItem();\n            popupShowReverse.setText(BACKTRACES_ITEM_NAME);\n            popup.add(popupShowReverse);\n            popupShowReverse.addActionListener(menuListener);\n        }\n\n        popup.add(popupFind);\n\n        if (popupShowSource != null) popupShowSource.addActionListener(menuListener);\n        popupFind.addActionListener(menuListener);\n\n        return popup;\n    }\n\n    protected void performDefaultAction() {\n        if (popupPath != null) {\n            showSourceForMethod(popupPath);\n        } else {\n            showSourceForMethod(methodId);\n        }\n    }\n\n    protected void showSourceForMethod(int methodId) {\n        if (currentView != CPUResultsSnapshot.PACKAGE_LEVEL_VIEW) {\n            boolean methodLevelView = (currentView == CPUResultsSnapshot.METHOD_LEVEL_VIEW);\n            String[] classMethodAndSig = getMethodClassNameAndSig(methodId, currentView);\n            actionsHandler.showSourceForMethod(classMethodAndSig[0], methodLevelView ? classMethodAndSig[1] : null,\n                                               methodLevelView ? classMethodAndSig[2] : null);\n        }\n    }\n\n    protected void showSourceForMethod(TreePath popupPath) {\n        PrestimeCPUCCTNode node = (PrestimeCPUCCTNode)popupPath.getLastPathComponent();\n        if (node.getMethodId() == 0 || node.isFiltered()) return;\n        \n        if (currentView != CPUResultsSnapshot.PACKAGE_LEVEL_VIEW) {\n            boolean methodLevelView = (currentView == CPUResultsSnapshot.METHOD_LEVEL_VIEW);\n            String[] classMethodAndSig = getMethodClassNameAndSig(node.getMethodId(), currentView);\n            actionsHandler.showSourceForMethod(classMethodAndSig[0], methodLevelView ? classMethodAndSig[1] : null,\n                                               methodLevelView ? classMethodAndSig[2] : null);\n        }\n    }\n\n    protected abstract boolean supportsReverseCallGraph();\n\n    protected abstract boolean supportsSubtreeCallGraph();\n\n    protected void showReverseCallGraph(int threadId, int methodId, int currentView, int sortingColumn, boolean sortingOrder) {\n        // do nothing, has to be overridden by classes that do support showing reverse call graphs and return\n        // true from supportsReverseCallGraph\n    }\n\n    protected void showSubtreeCallGraph(final CCTNode node, int currentView, int sortingColumn, boolean sortingOrder) {\n        // do nothing, has to be overridden by classes that do support showing subtree call graphs and return\n        // true from supportsSubtreeCallGraph\n    }\n    \n    public void setColumnsVisibility(boolean[] columnsVisibility) {}\n    \n    public boolean[] getColumnsVisibility() { return null; }\n\n    void menuActionPerformed(ActionEvent evt) {\n        Object src = evt.getSource();\n\n        if (src == popupShowSource && popupShowSource != null) {\n            performDefaultAction();\n        } else if (src == popupShowReverse) {\n            int threadId = 0;\n\n            if (popupPath != null) {\n                PrestimeCPUCCTNode selectedNode = (PrestimeCPUCCTNode) popupPath.getLastPathComponent();\n\n                if (selectedNode.getParent() == null) {\n                    return; // Nothing to do for root node\n                }\n\n                if (selectedNode.isSelfTimeNode()) {\n                    selectedNode = (PrestimeCPUCCTNode) selectedNode.getParent();\n                }\n\n                if (selectedNode == null) {\n                    return; // Nothing to do for root node\n                }\n\n                if (selectedNode.getMethodId() == 0) {\n                    if (selectedNode.getNChildren() > 0) {\n                        methodId = ((PrestimeCPUCCTNode) selectedNode.getChild(0)).getMethodId();\n                    }\n                } else {\n                    methodId = selectedNode.getMethodId();\n                }\n\n                threadId = selectedNode.getThreadId();\n            } else {\n                // methodId is already set\n                threadId = getCurrentThreadId(); // It's a flat profile window or something and we request a path for its single thread\n            }\n\n            showReverseCallGraph(threadId, methodId, currentView, getSortingColumn(), getSortingOrder());\n        } else if (src == popupShowSubtree) {\n            if (popupPath != null) {\n                if (popupPath.getParentPath() == null) {\n                    return; // Nothing to do for root node\n                }\n\n                PrestimeCPUCCTNode selectedNode = (PrestimeCPUCCTNode) popupPath.getLastPathComponent();\n\n                if (selectedNode.isSelfTimeNode()) {\n                    selectedNode = (PrestimeCPUCCTNode) selectedNode.getParent();\n                }\n\n                if (selectedNode == null) {\n                    return; // Nothing to do for root node\n                }\n\n                showSubtreeCallGraph(selectedNode, currentView, getSortingColumn(), getSortingOrder());\n            }\n        } else if (src == popupFind) {\n            actionsHandler.find(this, getSelectedMethodName());\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/CPUSelectionHandler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\n\n/**\n * This interface allows to track selection changes on a CPU panel\n *\n * @author Ian Formanek\n */\npublic interface CPUSelectionHandler {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void methodSelected(int threadId, int methodId, int view);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/CPUTableView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.BorderLayout;\nimport java.awt.Graphics;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.swing.JLabel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SortOrder;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.CheckBoxRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.McsTimeRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class CPUTableView extends CPUView {\n\n    private CPUTableModel tableModel;\n    private ProfilerTable table;\n\n    private FlatProfileContainer data;\n\n    private Map<Integer, ClientUtils.SourceCodeSelection> idMap;\n    private final Set<ClientUtils.SourceCodeSelection> selection;\n\n    private boolean sampled = true;\n    private boolean twoTimeStamps;\n\n    private boolean hitsVisible = false;\n    private boolean invocationsVisible = true;\n\n\n    CPUTableView(Set<ClientUtils.SourceCodeSelection> selection) {\n        this.selection = selection;\n\n        initUI();\n    }\n\n\n    void setData(final FlatProfileContainer newData, final Map<Integer, ClientUtils.SourceCodeSelection> newIdMap, final boolean _sampled, final boolean _diff) {\n        boolean structureChange = sampled != _sampled;\n        sampled = _sampled;\n        twoTimeStamps = newData != null && newData.isCollectingTwoTimeStamps();\n        idMap = newIdMap;\n        if (tableModel != null) {\n            data = newData;\n\n            if (_diff) {\n                long[] maxTimes = new long[4];\n                long[] minTimes = new long[4];\n                int maxInvocations = 0;\n                int minInvocations = 0;\n                for (int row = 0; row < tableModel.getRowCount(); row++) {\n                    maxTimes[0] = Math.max(maxTimes[0], data.getTimeInMcs0AtRow(row));\n                    minTimes[0] = Math.min(minTimes[0], data.getTimeInMcs0AtRow(row));\n                    if (twoTimeStamps) {\n                        maxTimes[1] = Math.max(maxTimes[1], data.getTimeInMcs1AtRow(row));\n                        minTimes[1] = Math.min(minTimes[1], data.getTimeInMcs1AtRow(row));\n                    }\n                    maxTimes[2] = Math.max(maxTimes[2], data.getTotalTimeInMcs0AtRow(row));\n                    minTimes[2] = Math.min(minTimes[2], data.getTotalTimeInMcs0AtRow(row));\n                    if (twoTimeStamps) {\n                        maxTimes[3] = Math.max(maxTimes[3], data.getTotalTimeInMcs1AtRow(row));\n                        minTimes[3] = Math.min(minTimes[3], data.getTotalTimeInMcs1AtRow(row));\n                    }\n                    maxInvocations = Math.max(maxInvocations, data.getNInvocationsAtRow(row));\n                    minInvocations = Math.min(minInvocations, data.getNInvocationsAtRow(row));\n                }\n\n                renderers[0].setMaxValue(Math.max(Math.abs(maxTimes[0]), Math.abs(minTimes[0])));\n                renderers[1].setMaxValue(Math.max(Math.abs(maxTimes[1]), Math.abs(minTimes[1])));\n                renderers[2].setMaxValue(Math.max(Math.abs(maxTimes[2]), Math.abs(minTimes[2])));\n                renderers[3].setMaxValue(Math.max(Math.abs(maxTimes[3]), Math.abs(minTimes[3])));\n                renderers[4].setMaxValue(Math.max(Math.abs(maxInvocations), Math.abs(minInvocations)));\n            } else {\n                long[] maxTimes = new long[4];\n                int maxInvocations = 0;\n                for (int row = 0; row < tableModel.getRowCount(); row++) {\n                    maxTimes[0] += data.getTimeInMcs0AtRow(row);\n                    if (twoTimeStamps) maxTimes[1] += data.getTimeInMcs1AtRow(row);\n                    maxTimes[2] += data.getTotalTimeInMcs0AtRow(row);\n                    if (twoTimeStamps) maxTimes[3] += data.getTotalTimeInMcs1AtRow(row);\n                    maxInvocations += data.getNInvocationsAtRow(row);\n                }\n\n                renderers[0].setMaxValue(maxTimes[0]);\n                renderers[1].setMaxValue(maxTimes[1]);\n                renderers[2].setMaxValue(maxTimes[2]);\n                renderers[3].setMaxValue(maxTimes[3]);\n                renderers[4].setMaxValue(maxInvocations);\n            }\n\n            renderers[0].setDiffMode(_diff);\n            renderers[1].setDiffMode(_diff);\n            renderers[2].setDiffMode(_diff);\n            renderers[3].setDiffMode(_diff);\n            renderers[4].setDiffMode(_diff);\n\n            tableModel.fireTableDataChanged();\n        }\n        if (structureChange) {\n            // Resolve Hits/Invocations column\n            int col = table.convertColumnIndexToView(selection == null ? 5 : 6);\n            String colN = tableModel.getColumnName(selection == null ? 5 : 6);\n\n            // Persist current Hits/Invocations column visibility\n            if (sampled) invocationsVisible = table.isColumnVisible(col);\n            else hitsVisible = table.isColumnVisible(col);\n\n            // Update Hits/Invocations column name\n            table.getColumnModel().getColumn(col).setHeaderValue(colN);\n\n            // Set new Hits/Invocations column visibility\n            table.setColumnVisibility(col, sampled ? hitsVisible : invocationsVisible);\n\n            setToolTips();\n\n            repaint();\n        }\n\n        if (newData != null && !twoTimeStamps) {\n            int selfColumn = selection == null ? 2 : 3;\n            int totalColumn = selection == null ? 4 : 5;\n            if (table.isColumnVisible(selfColumn)) {\n                table.setColumnVisibility(selfColumn, false);\n                table.setColumnVisibility(selfColumn - 1, true);\n            }\n            if (table.isColumnVisible(totalColumn)) {\n                table.setColumnVisibility(totalColumn, false);\n                table.setColumnVisibility(totalColumn - 1, true);\n            }\n        }\n    }\n    \n    public void resetData() {\n        setData(null, null, sampled, false);\n    }\n    \n    \n    public void showSelectionColumn() {\n        table.setColumnVisibility(0, true);\n    }\n    \n    public void refreshSelection() {\n        tableModel.fireTableDataChanged();\n    }\n    \n    \n    ExportUtils.ExportProvider[] getExportProviders() {\n        return table.getRowCount() == 0 ? null : new ExportUtils.ExportProvider[] {\n            new ExportUtils.CSVExportProvider(table),\n            new ExportUtils.HTMLExportProvider(table, EXPORT_HOTSPOTS),\n            new ExportUtils.XMLExportProvider(table, EXPORT_HOTSPOTS),\n            new ExportUtils.PNGExportProvider(table)\n        };\n    }\n    \n    \n    protected abstract void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue);\n    \n    protected void popupShowing() {}\n\n    protected void popupHidden()  {}\n\n\n    private HideableBarRenderer[] renderers;\n    \n    HideableBarRenderer.BarDiffMode barDiffMode() {\n        return HideableBarRenderer.BarDiffMode.MODE_BAR_DIFF;\n    }\n    \n    private void initUI() {\n        tableModel = new CPUTableModel();\n        \n        table = new ProfilerTable(tableModel, true, true, null) {\n            public ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n                return CPUTableView.this.getUserValueForRow(row);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                CPUTableView.this.populatePopup(popup, value, (ClientUtils.SourceCodeSelection)userValue);\n            }\n            protected void popupShowing() {\n                CPUTableView.this.popupShowing();\n            }\n            protected void popupHidden() {\n                CPUTableView.this.popupHidden();\n            }\n        };\n        \n        setToolTips();\n        \n        table.providePopupMenu(true);\n        installDefaultAction();\n        \n        int offset = selection == null ? -1 : 0;\n        \n        table.setMainColumn(1 + offset);\n        table.setFitWidthColumn(1 + offset);\n        \n        table.setSortColumn(3 + offset);\n        table.setDefaultSortOrder(1 + offset, SortOrder.ASCENDING);\n        \n        if (selection != null) table.setColumnVisibility(0, false);\n        table.setColumnVisibility(2 + offset, false);\n        table.setColumnVisibility(4 + offset, false);\n        table.setColumnVisibility(6 + offset, false);\n        \n        renderers = new HideableBarRenderer[5];\n        \n        HideableBarRenderer.BarDiffMode barDiffMode = barDiffMode();\n        renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(new McsTimeRenderer()));\n        renderers[0].setBarDiffMode(barDiffMode);\n        renderers[1] = new HideableBarRenderer(new NumberPercentRenderer(new McsTimeRenderer()));\n        renderers[1].setBarDiffMode(barDiffMode);\n        renderers[2] = new HideableBarRenderer(new NumberPercentRenderer(new McsTimeRenderer()));\n        renderers[2].setBarDiffMode(barDiffMode);\n        renderers[3] = new HideableBarRenderer(new NumberPercentRenderer(new McsTimeRenderer()));\n        renderers[3].setBarDiffMode(barDiffMode);\n        renderers[4] = new HideableBarRenderer(new NumberRenderer());\n        renderers[4].setBarDiffMode(barDiffMode);\n        \n        long refTime = 123456;\n        renderers[0].setMaxValue(refTime);\n        renderers[1].setMaxValue(refTime);\n        renderers[2].setMaxValue(refTime);\n        renderers[3].setMaxValue(refTime);\n        renderers[4].setMaxValue(refTime);\n        \n        if (selection != null) table.setColumnRenderer(0, new CheckBoxRenderer() {\n            private boolean visible;\n            public void setValue(Object value, int row) {\n                visible = isSelectable(idMap.get(data.getMethodIdAtRow(row)));\n                if (visible) super.setValue(value, row);\n            }\n            public void paint(Graphics g) {\n                if (visible) {\n                    super.paint(g);\n                } else {\n                    g.setColor(getBackground());\n                    g.fillRect(0, 0, size.width, size.height);\n                }\n            }\n        });\n        table.setColumnRenderer(1 + offset, new JavaNameRenderer(Icons.getIcon(ProfilerIcons.NODE_LEAF)));\n        table.setColumnRenderer(2 + offset, renderers[0]);\n        table.setColumnRenderer(3 + offset, renderers[1]);\n        table.setColumnRenderer(4 + offset, renderers[2]);\n        table.setColumnRenderer(5 + offset, renderers[3]);\n        table.setColumnRenderer(6 + offset, renderers[4]);\n        \n        int w;\n        if (selection != null) {\n            w = new JLabel(table.getColumnName(0)).getPreferredSize().width;\n            table.setDefaultColumnWidth(0, w + 15);\n        }\n        table.setDefaultColumnWidth(2 + offset, renderers[0].getMaxNoBarWidth());\n        table.setDefaultColumnWidth(3 + offset, renderers[1].getOptimalWidth());\n        table.setDefaultColumnWidth(4 + offset, renderers[2].getMaxNoBarWidth());\n        table.setDefaultColumnWidth(5 + offset, renderers[3].getMaxNoBarWidth());\n        \n        sampled = !sampled;\n        w = new JLabel(table.getColumnName(6 + offset)).getPreferredSize().width;\n        sampled = !sampled;\n        w = Math.max(w, new JLabel(table.getColumnName(6 + offset)).getPreferredSize().width);\n        table.setDefaultColumnWidth(6 + offset, Math.max(renderers[4].getNoBarWidth(), w + 15));\n        \n        ProfilerTableContainer tableContainer = new ProfilerTableContainer(table, false, null);\n        \n        setLayout(new BorderLayout());\n        add(tableContainer, BorderLayout.CENTER);\n    }\n    \n    private void setToolTips() {\n        table.setColumnToolTips(selection == null ? new String[] {\n                                        NAME_COLUMN_TOOLTIP,\n                                        SELF_TIME_COLUMN_TOOLTIP,\n                                        SELF_TIME_CPU_COLUMN_TOOLTIP,\n                                        TOTAL_TIME_COLUMN_TOOLTIP,\n                                        TOTAL_TIME_CPU_COLUMN_TOOLTIP,\n                                        sampled ? HITS_COLUMN_TOOLTIP :\n                                                  INVOCATIONS_COLUMN_TOOLTIP\n                                      } : new String[] {\n                                        SELECTED_COLUMN_TOOLTIP,\n                                        NAME_COLUMN_TOOLTIP,\n                                        SELF_TIME_COLUMN_TOOLTIP,\n                                        SELF_TIME_CPU_COLUMN_TOOLTIP,\n                                        TOTAL_TIME_COLUMN_TOOLTIP,\n                                        TOTAL_TIME_CPU_COLUMN_TOOLTIP,\n                                        sampled ? HITS_COLUMN_TOOLTIP :\n                                                  INVOCATIONS_COLUMN_TOOLTIP\n                                      });\n    }\n    \n    protected ProfilerTable getResultsComponent() {\n        return table;\n    }\n    \n    \n    protected ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n        if (data == null || row == -1) return null;\n        if (row >= tableModel.getRowCount()) return null; // #239936\n        row = table.convertRowIndexToModel(row);\n        return idMap.get(data.getMethodIdAtRow(row));\n//        return selectionForId(data.getMethodIdAtRow(row));\n    }\n    \n//    private ClientUtils.SourceCodeSelection selectionForId(int methodId) {\n//        ProfilingSessionStatus sessionStatus = client.getStatus();\n//        sessionStatus.beginTrans(false);\n//        try {\n//            String className = sessionStatus.getInstrMethodClasses()[methodId];\n//            String methodName = sessionStatus.getInstrMethodNames()[methodId];\n//            String methodSig = sessionStatus.getInstrMethodSignatures()[methodId];\n//            return new ClientUtils.SourceCodeSelection(className, methodName, methodSig);\n//        } finally {\n//            sessionStatus.endTrans();\n//        }\n//    }\n    \n    static boolean isSelectable(ClientUtils.SourceCodeSelection method) {\n        return !method.getMethodName().endsWith(\"[native]\"); // NOI18N\n    }\n    \n    \n    private class CPUTableModel extends AbstractTableModel {\n        \n        public String getColumnName(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return COLUMN_NAME;\n            } else if (columnIndex == 2) {\n                return COLUMN_SELFTIME;\n            } else if (columnIndex == 3) {\n                return COLUMN_SELFTIME_CPU;\n            } else if (columnIndex == 4) {\n                return COLUMN_TOTALTIME;\n            } else if (columnIndex == 5) {\n                return COLUMN_TOTALTIME_CPU;\n            } else if (columnIndex == 6) {\n                return sampled ? COLUMN_HITS : COLUMN_INVOCATIONS;\n            } else if (columnIndex == 0) {\n                return COLUMN_SELECTED;\n            }\n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return String.class;\n            } else if (columnIndex == 6) {\n                return Integer.class;\n            } else if (columnIndex == 0) {\n                return Boolean.class;\n            } else {\n                return Long.class;\n            }\n        }\n\n        public int getRowCount() {\n            return data == null ? 0 : data.getNRows();\n        }\n\n        public int getColumnCount() {\n            return selection == null ? 6 : 7;\n        }\n\n        public Object getValueAt(int rowIndex, int columnIndex) {\n            if (data == null) return null;\n            \n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return data.getMethodNameAtRow(rowIndex);\n            } else if (columnIndex == 2) {\n                return data.getTimeInMcs0AtRow(rowIndex);\n            } else if (columnIndex == 3) {\n                return twoTimeStamps ? data.getTimeInMcs1AtRow(rowIndex) : 0;\n            } else if (columnIndex == 4) {\n                return data.getTotalTimeInMcs0AtRow(rowIndex);\n            } else if (columnIndex == 5) {\n                return twoTimeStamps ? data.getTotalTimeInMcs1AtRow(rowIndex) : 0;\n            } else if (columnIndex == 6) {\n                return data.getNInvocationsAtRow(rowIndex);\n            } else if (columnIndex == 0) {\n                if (selection.isEmpty()) return Boolean.FALSE;\n                return selection.contains(idMap.get(data.getMethodIdAtRow(rowIndex)));\n            }\n\n            return null;\n        }\n        \n        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 0) {\n                int methodId = data.getMethodIdAtRow(rowIndex);\n                if (Boolean.TRUE.equals(aValue)) selection.add(idMap.get(methodId));\n                else selection.remove(idMap.get(methodId));\n            }\n        }\n\n        public boolean isCellEditable(int rowIndex, int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex != 0) return false;\n            return isSelectable(idMap.get(data.getMethodIdAtRow(rowIndex)));\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/CPUTreeTableView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Graphics;\nimport java.awt.event.ActionEvent;\nimport java.util.Collection;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.swing.Box;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JLabel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.JTree;\nimport javax.swing.RowFilter;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.tree.TreeNode;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.CheckBoxRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.McsTimeRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class CPUTreeTableView extends CPUView {\n\n    private CPUTreeTableModel treeTableModel;\n    private ProfilerTreeTable treeTable;\n\n    private Map<Integer, ClientUtils.SourceCodeSelection> idMap;\n    private final Set<ClientUtils.SourceCodeSelection> selection;\n    \n    private final boolean reverse;\n    \n    private boolean sampled = true;\n    private boolean twoTimeStamps;\n    \n    private boolean hitsVisible = false;\n    private boolean invocationsVisible = true;\n    \n    private boolean filterTopMethods = true;\n    private boolean filterCallerMethods = false;\n    private boolean searchTopMethods = true;\n    private boolean searchCallerMethods = false;\n    \n    \n    CPUTreeTableView(Set<ClientUtils.SourceCodeSelection> selection, boolean reverse) {\n        this.selection = selection;\n        this.reverse = reverse;\n        \n        initUI();\n    }\n    \n    \n    void setData(final CPUResultsSnapshot newData, final Map<Integer, ClientUtils.SourceCodeSelection> newIdMap, final int aggregation, final Collection<Integer> selectedThreads, final boolean mergeThreads, final boolean _sampled, final boolean _diff) {\n        boolean structureChange = sampled != _sampled;\n        sampled = _sampled;\n        boolean _twoTimeStamps = twoTimeStamps;\n        twoTimeStamps = newData == null ? !_twoTimeStamps : newData.isCollectingTwoTimeStamps();\n        idMap = newIdMap;\n        renderers[0].setDiffMode(_diff);\n        renderers[1].setDiffMode(_diff);\n        renderers[2].setDiffMode(_diff);\n        if (treeTableModel != null) {\n            treeTableModel.setRoot(newData == null ? PrestimeCPUCCTNode.EMPTY :\n                                   !reverse ? newData.getRootNode(aggregation, selectedThreads, mergeThreads):\n                                   newData.getReverseRootNode(aggregation, selectedThreads, mergeThreads));\n        }\n        if (structureChange) {\n            // Resolve Hits/Invocations column\n            int col = treeTable.convertColumnIndexToView(selection == null ? 3 : 4);\n            String colN = treeTableModel.getColumnName(selection == null ? 3 : 4);\n\n            // Persist current Hits/Invocations column visibility\n            if (sampled) invocationsVisible = treeTable.isColumnVisible(col);\n            else hitsVisible = treeTable.isColumnVisible(col);\n\n            // Update Hits/Invocations column name\n            treeTable.getColumnModel().getColumn(col).setHeaderValue(colN);\n\n            // Set new Hits/Invocations column visibility\n            treeTable.setColumnVisibility(col, sampled ? hitsVisible : invocationsVisible);\n\n            setToolTips();\n\n            repaint();\n        }\n\n        if (newData != null && twoTimeStamps != _twoTimeStamps) {\n            int column = selection == null ? 2 : 3;\n            boolean cpuColumnVisible = treeTable.isColumnVisible(column);\n            if (twoTimeStamps && !cpuColumnVisible) treeTable.setColumnVisibility(column, true);\n            else if (!twoTimeStamps && cpuColumnVisible) treeTable.setColumnVisibility(column, false);\n        }\n    }\n    \n    public void resetData() {\n        setData(null, null, -1, null, false, sampled, false);\n    }\n    \n    \n    public void showSelectionColumn() {\n        treeTable.setColumnVisibility(0, true);\n    }\n    \n    public void refreshSelection() {\n        treeTableModel.dataChanged();\n    }\n    \n    \n    ExportUtils.ExportProvider[] getExportProviders() {\n        final String name = reverse ? EXPORT_REVERSE_CALLS : EXPORT_FORWARD_CALLS;\n        return treeTable.getRowCount() == 0 ? null : new ExportUtils.ExportProvider[] {\n            new ExportUtils.CSVExportProvider(treeTable),\n            new ExportUtils.HTMLExportProvider(treeTable, name),\n            new ExportUtils.XMLExportProvider(treeTable, name),\n            new ExportUtils.PNGExportProvider(treeTable)\n        };\n    }\n    \n    \n    protected abstract void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue);\n    \n    protected void popupShowing() {}\n\n    protected void popupHidden()  {}\n\n\n    private HideableBarRenderer[] renderers;\n    \n    HideableBarRenderer.BarDiffMode barDiffMode() {\n        return HideableBarRenderer.BarDiffMode.MODE_BAR_DIFF;\n    }\n    \n    private void initUI() {\n        treeTableModel = new CPUTreeTableModel(PrestimeCPUCCTNode.EMPTY);\n        \n        int offset = selection == null ? -1 : 0;\n        \n        treeTable = new ProfilerTreeTable(treeTableModel, true, true, new int[] { 1 + offset }) {\n            public ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n                return CPUTreeTableView.this.getUserValueForRow(row);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                CPUTreeTableView.this.populatePopup(popup, value, (ClientUtils.SourceCodeSelection)userValue);\n            }\n            protected void popupShowing() {\n                CPUTreeTableView.this.popupShowing();\n            }\n            protected void popupHidden() {\n                CPUTreeTableView.this.popupHidden();\n            }\n        };\n        \n        setToolTips();\n        \n        treeTable.providePopupMenu(true);\n        installDefaultAction();\n        \n        treeTable.setRootVisible(false);\n        treeTable.setShowsRootHandles(true);\n        treeTable.makeTreeAutoExpandable(2);\n        \n        treeTable.setMainColumn(1 + offset);\n        treeTable.setFitWidthColumn(1 + offset);\n        \n        treeTable.setSortColumn(2 + offset);\n        treeTable.setDefaultSortOrder(1 + offset, SortOrder.ASCENDING);\n        \n        if (selection != null) treeTable.setColumnVisibility(0, false);\n        treeTable.setColumnVisibility(4 + offset, false);\n        \n        renderers = new HideableBarRenderer[3];\n        \n        HideableBarRenderer.BarDiffMode barDiffMode = barDiffMode();\n        renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(new McsTimeRenderer())) {\n            public void setValue(Object value, int row) {\n                super.setMaxValue(getMaxValue(row, 0));\n                super.setValue(value, row);\n            }\n        };\n        renderers[0].setBarDiffMode(barDiffMode);\n        renderers[1] = new HideableBarRenderer(new NumberPercentRenderer(new McsTimeRenderer())) {\n            public void setValue(Object value, int row) {\n                super.setMaxValue(getMaxValue(row, 1));\n                super.setValue(value, row);\n            }\n        };\n        renderers[1].setBarDiffMode(barDiffMode);\n        renderers[2] = new HideableBarRenderer(new NumberRenderer()) {\n            public void setValue(Object value, int row) {\n                super.setMaxValue(getMaxValue(row, 2));\n                super.setValue(value, row);\n            }\n        };\n        renderers[2].setBarDiffMode(barDiffMode);\n        \n        long refTime = 123456;\n        renderers[0].setMaxValue(refTime);\n        renderers[1].setMaxValue(refTime);\n        renderers[2].setMaxValue(refTime);\n        \n        if (selection != null) treeTable.setColumnRenderer(0, new CheckBoxRenderer() {\n            private boolean visible;\n            public void setValue(Object value, int row) {\n                TreePath path = treeTable.getPathForRow(row);\n                visible = isSelectable((PrestimeCPUCCTNode)path.getLastPathComponent());\n                if (visible) super.setValue(value, row);\n            }\n            public void paint(Graphics g) {\n                if (visible) {\n                    super.paint(g);\n                } else {\n                    g.setColor(getBackground());\n                    g.fillRect(0, 0, size.width, size.height);\n                }\n            }\n        });\n        treeTable.setTreeCellRenderer(new CPUJavaNameRenderer(reverse ? ProfilerIcons.NODE_REVERSE : ProfilerIcons.NODE_FORWARD));\n        treeTable.setColumnRenderer(2 + offset, renderers[0]);\n        treeTable.setColumnRenderer(3 + offset, renderers[1]);\n        treeTable.setColumnRenderer(4 + offset, renderers[2]);\n        \n        int w;\n        if (selection != null) {\n            w = new JLabel(treeTable.getColumnName(0)).getPreferredSize().width;\n            treeTable.setDefaultColumnWidth(0, w + 15);\n        }\n        treeTable.setDefaultColumnWidth(2 + offset, renderers[0].getOptimalWidth());\n        treeTable.setDefaultColumnWidth(3 + offset, renderers[1].getMaxNoBarWidth());\n        \n        sampled = !sampled;\n        w = new JLabel(treeTable.getColumnName(4 + offset)).getPreferredSize().width;\n        sampled = !sampled;\n        w = Math.max(w, new JLabel(treeTable.getColumnName(4 + offset)).getPreferredSize().width);\n        treeTable.setDefaultColumnWidth(4 + offset, Math.max(renderers[2].getNoBarWidth(), w + 15));\n        \n        ProfilerTableContainer tableContainer = new ProfilerTableContainer(treeTable, false, null);\n        \n        setLayout(new BorderLayout());\n        add(tableContainer, BorderLayout.CENTER);\n    }\n    \n    private void setToolTips() {\n        treeTable.setColumnToolTips(selection == null ? new String[] {\n                                        NAME_COLUMN_TOOLTIP,\n                                        TOTAL_TIME_COLUMN_TOOLTIP,\n                                        TOTAL_TIME_CPU_COLUMN_TOOLTIP,\n                                        sampled ? HITS_COLUMN_TOOLTIP :\n                                                  INVOCATIONS_COLUMN_TOOLTIP\n                                      } : new String[] {\n                                        SELECTED_COLUMN_TOOLTIP,\n                                        NAME_COLUMN_TOOLTIP,\n                                        TOTAL_TIME_COLUMN_TOOLTIP,\n                                        TOTAL_TIME_CPU_COLUMN_TOOLTIP,\n                                        sampled ? HITS_COLUMN_TOOLTIP :\n                                                  INVOCATIONS_COLUMN_TOOLTIP\n                                      });\n    }\n    \n    \n    protected RowFilter getExcludesFilter() {\n        if (!reverse) return new RowFilter() { // Do not filter threads and self time nodes\n            public boolean include(RowFilter.Entry entry) {\n                PrestimeCPUCCTNode node = (PrestimeCPUCCTNode)entry.getIdentifier();\n                return node.isThreadNode() || node.isSelfTimeNode();\n            }\n        }; else return new RowFilter() { // Do not filter threads and self time nodes\n            public boolean include(RowFilter.Entry entry) {\n                PrestimeCPUCCTNode node = (PrestimeCPUCCTNode)entry.getIdentifier();\n                CCTNode parent = node.getParent();\n                if (parent == null) return true; // invisible root\n                \n                if (node.isThreadNode() || node.isSelfTimeNode()) return true; // thread or self time node\n                \n                if (((PrestimeCPUCCTNode)parent).isThreadNode() || // toplevel method node (children of thread)\n                    parent.getParent() == null) // toplevel method node (merged threads)\n                        return !filterTopMethods;\n                \n                return !filterCallerMethods; // reverse call tree node\n            }\n        };\n    }\n    \n    protected Component[] getFilterOptions() {\n        if (reverse) {\n            PopupButton pb = new PopupButton (Icons.getIcon(ProfilerIcons.TAB_CALL_TREE)) {\n                protected void populatePopup(JPopupMenu popup) {\n                    popup.add(new JCheckBoxMenuItem(FILTER_CALLEES_SCOPE, filterTopMethods) {\n                        {\n                            if (!filterCallerMethods) setEnabled(false);\n                        }\n                        protected void fireActionPerformed(ActionEvent e) {\n                            super.fireActionPerformed(e);\n                            filterTopMethods = !filterTopMethods;\n                            enableFilter();\n                        }\n                    });\n                    popup.add(new JCheckBoxMenuItem(FILTER_CALLERS_SCOPE, filterCallerMethods) {\n                        {\n                            if (!filterTopMethods) setEnabled(false);\n                        }\n                        protected void fireActionPerformed(ActionEvent e) {\n                            super.fireActionPerformed(e);\n                            filterCallerMethods = !filterCallerMethods;\n                            enableFilter();\n                        }\n                    });\n                }\n            };\n            pb.setToolTipText(FILTER_SCOPE_TOOLTIP);\n            return new Component[] { Box.createHorizontalStrut(5), pb };\n        } else {\n            final RowFilter zeroFilter = new RowFilterImpl();\n            final JToggleButton zeroSelfTime = new JToggleButton(Icons.getIcon(ProfilerIcons.NODE_LEAF)) {\n\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    boolean selected = isSelected();\n\n                    SwingUtilities.invokeLater(() -> {\n                        if (selected) {\n                            treeTable.addRowFilter(zeroFilter);\n                        } else {\n                            treeTable.removeRowFilter(zeroFilter);\n                        }\n                    });\n                }\n            };\n            zeroSelfTime.setToolTipText(HIDE_ZERO_SELF_TIME_TOOLTIP);\n            return new Component[]{Box.createHorizontalStrut(5), zeroSelfTime};\n        }\n    }\n\n    private static class RowFilterImpl extends RowFilter implements ProfilerTreeTable.DeleteNodes {\n\n        public boolean include(RowFilter.Entry entry) {\n            PrestimeCPUCCTNode node = (PrestimeCPUCCTNode) entry.getIdentifier();\n            if (node.isSelfTimeNode() && node.getTotalTime0() == 0) {\n                return false;\n            }\n            return true;\n        }\n    }\n    \n    protected SearchUtils.TreeHelper getSearchHelper() {\n        if (!reverse) return super.getSearchHelper();\n        \n        return new SearchUtils.TreeHelper() {\n            public int getNodeType(TreeNode tnode) {\n                PrestimeCPUCCTNode node = (PrestimeCPUCCTNode)tnode;\n                CCTNode parent = node.getParent();\n                if (parent == null) return SearchUtils.TreeHelper.NODE_SKIP_DOWN; // invisible root\n                \n                if (node.isThreadNode()) return SearchUtils.TreeHelper.NODE_SKIP_DOWN; // thread node\n                if (node.isSelfTimeNode()) return SearchUtils.TreeHelper.NODE_SKIP_NEXT; // self time node\n                \n                if (((PrestimeCPUCCTNode)parent).isThreadNode() || // toplevel method node (children of thread)\n                    parent.getParent() == null) {                  // toplevel method node (merged threads)\n                    if (searchTopMethods) {\n                        return searchCallerMethods ? SearchUtils.TreeHelper.NODE_SEARCH_DOWN :\n                                                     SearchUtils.TreeHelper.NODE_SEARCH_NEXT;\n                    } else {\n                        return searchCallerMethods ? SearchUtils.TreeHelper.NODE_SKIP_DOWN :\n                                                     SearchUtils.TreeHelper.NODE_SKIP_NEXT;\n                    }\n                }\n                \n                return searchCallerMethods ? // reverse call tree node\n                       SearchUtils.TreeHelper.NODE_SEARCH_DOWN :\n                       SearchUtils.TreeHelper.NODE_SKIP_NEXT;\n            }\n        };\n    }\n    \n    protected Component[] getSearchOptions() {\n        if (!reverse) return super.getSearchOptions();\n        \n        PopupButton pb = new PopupButton (Icons.getIcon(ProfilerIcons.TAB_CALL_TREE)) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new JCheckBoxMenuItem(SEARCH_CALLEES_SCOPE, searchTopMethods) {\n                    {\n                        if (!searchCallerMethods) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        searchTopMethods = !searchTopMethods;\n                    }\n                });\n                popup.add(new JCheckBoxMenuItem(SEARCH_CALLERS_SCOPE, searchCallerMethods) {\n                    {\n                        if (!searchTopMethods) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        searchCallerMethods = !searchCallerMethods;\n                    }\n                });\n            }\n        };\n        pb.setToolTipText(SEARCH_SCOPE_TOOLTIP);\n        return new Component[] { Box.createHorizontalStrut(5), pb };\n    }\n    \n    protected ProfilerTable getResultsComponent() {\n        return treeTable;\n    }\n    \n    \n    private long getMaxValue(int row, int val) {\n        TreePath path = treeTable.getPathForRow(row);\n        if (path == null) return Long.MIN_VALUE; // TODO: prevents NPE from export but doesn't provide the actual value!\n        if (path.getPathCount() < 2) return 1;\n        \n        PrestimeCPUCCTNode node = (PrestimeCPUCCTNode)path.getPathComponent(1);\n        if (val == 0) return Math.abs(node.getTotalTime0());\n        else if (val == 1) return Math.abs(node.getTotalTime1());\n        else return Math.abs(node.getNCalls());\n    }\n    \n    protected ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n        PrestimeCPUCCTNode node = (PrestimeCPUCCTNode)treeTable.getValueForRow(row);\n        if (node == null) return null;\n        else if (node.isThreadNode() || node.isFiltered() || node.isSelfTimeNode()) return null;\n//        else return selectionForId(node.getMethodId());\n        else return idMap.get(node.getMethodId());\n    }\n    \n//    private ClientUtils.SourceCodeSelection selectionForId(int methodId) {\n//        ProfilingSessionStatus sessionStatus = client.getStatus();\n//        sessionStatus.beginTrans(false);\n//        try {\n//            String className = sessionStatus.getInstrMethodClasses()[methodId];\n//            String methodName = sessionStatus.getInstrMethodNames()[methodId];\n//            String methodSig = sessionStatus.getInstrMethodSignatures()[methodId];\n//            return new ClientUtils.SourceCodeSelection(className, methodName, methodSig);\n//        } finally {\n//            sessionStatus.endTrans();\n//        }\n//    }\n    \n    private static boolean isSelectable(PrestimeCPUCCTNode node) {\n        if (node.isThreadNode() || node.isFiltered() || node.isSelfTimeNode()) return false;\n        if (node.getMethodClassNameAndSig()[1].endsWith(\"[native]\")) return false; // NOI18N\n        return true;\n    }\n    \n    \n    private class CPUTreeTableModel extends ProfilerTreeTableModel.Abstract {\n        \n        CPUTreeTableModel(TreeNode root) {\n            super(root);\n        }\n        \n        public String getColumnName(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return COLUMN_NAME;\n            } else if (columnIndex == 2) {\n                return COLUMN_TOTALTIME;\n            } else if (columnIndex == 3) {\n                return COLUMN_TOTALTIME_CPU;\n            } else if (columnIndex == 4) {\n                return sampled ? COLUMN_HITS : COLUMN_INVOCATIONS;\n            } else if (columnIndex == 0) {\n                return COLUMN_SELECTED;\n            }\n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return JTree.class;\n            } else if (columnIndex == 4) {\n                return Integer.class;\n            } else if (columnIndex == 0) {\n                return Boolean.class;\n            } else {\n                return Long.class;\n            }\n        }\n\n        public int getColumnCount() {\n            return selection == null ? 4 : 5;\n        }\n\n        public Object getValueAt(TreeNode node, int columnIndex) {\n            PrestimeCPUCCTNode cpuNode = (PrestimeCPUCCTNode)node;\n            \n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return cpuNode.getNodeName();\n            } else if (columnIndex == 2) {\n                return cpuNode.getTotalTime0();\n            } else if (columnIndex == 3) {\n                return twoTimeStamps ? cpuNode.getTotalTime1() : 0;\n            } else if (columnIndex == 4) {\n                return cpuNode.getNCalls();\n            } else if (columnIndex == 0) {\n                if (selection.isEmpty()) return Boolean.FALSE;\n                return selection.contains(idMap.get(cpuNode.getMethodId()));\n            }\n\n            return null;\n        }\n        \n        public void setValueAt(Object aValue, TreeNode node, int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 0) {\n                PrestimeCPUCCTNode cpuNode = (PrestimeCPUCCTNode)node;\n                int methodId = cpuNode.getMethodId();\n                if (Boolean.TRUE.equals(aValue)) selection.add(idMap.get(methodId));\n                else selection.remove(idMap.get(methodId));\n            }\n        }\n\n        public boolean isCellEditable(TreeNode node, int columnIndex) {\n            if (selection == null) columnIndex++;\n            if (columnIndex != 0) return false;\n            return (isSelectable((PrestimeCPUCCTNode)node));\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/CPUView.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.util.ResourceBundle;\nimport org.graalvm.visualvm.lib.ui.results.DataView;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class CPUView extends DataView {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.cpu.Bundle\"); // NOI18N\n    static final String EXPORT_TOOLTIP = messages.getString(\"CPUView_ExportTooltip\"); // NOI18N\n    static final String EXPORT_METHODS = messages.getString(\"CPUView_ExportMethods\"); // NOI18N\n    static final String EXPORT_FORWARD_CALLS = messages.getString(\"CPUView_ExportForwardCalls\"); // NOI18N\n    static final String EXPORT_HOTSPOTS = messages.getString(\"CPUView_ExportHotSpots\"); // NOI18N\n    static final String EXPORT_REVERSE_CALLS = messages.getString(\"CPUView_ExportReverseCalls\"); // NOI18N\n    static final String COLUMN_NAME = messages.getString(\"CPUView_ColumnName\"); // NOI18N\n    static final String COLUMN_SELFTIME = messages.getString(\"CPUView_ColumnSelfTime\"); // NOI18N\n    static final String COLUMN_SELFTIME_CPU = messages.getString(\"CPUView_ColumnSelfTimeCpu\"); // NOI18N\n    static final String COLUMN_TOTALTIME = messages.getString(\"CPUView_ColumnTotalTime\"); // NOI18N\n    static final String COLUMN_TOTALTIME_CPU = messages.getString(\"CPUView_ColumnTotalTimeCpu\"); // NOI18N\n    static final String COLUMN_HITS = messages.getString(\"CPUView_ColumnHits\"); // NOI18N\n    static final String COLUMN_INVOCATIONS = messages.getString(\"CPUView_ColumnInvocations\"); // NOI18N\n    static final String COLUMN_SELECTED = messages.getString(\"CPUView_ColumnSelected\"); // NOI18N\n    static final String ACTION_GOTOSOURCE = messages.getString(\"CPUView_ActionGoToSource\"); // NOI18N\n    static final String ACTION_PROFILE_METHOD = messages.getString(\"CPUView_ActionProfileMethod\"); // NOI18N\n    static final String ACTION_PROFILE_CLASS = messages.getString(\"CPUView_ActionProfileClass\"); // NOI18N\n    static final String FIND_IN_FORWARDCALLS = messages.getString(\"CPUView_FindInForwardCalls\"); // NOI18N\n    static final String FIND_IN_HOTSPOTS = messages.getString(\"CPUView_FindInHotSpots\"); // NOI18N\n    static final String FIND_IN_REVERSECALLS = messages.getString(\"CPUView_FindInReverseCalls\"); // NOI18N\n    static final String SELECTED_COLUMN_TOOLTIP = messages.getString(\"CPUView_SelectedColumnTooltip\"); // NOI18N\n    static final String NAME_COLUMN_TOOLTIP = messages.getString(\"CPUView_NameColumnTooltip\"); // NOI18N\n    static final String SELF_TIME_COLUMN_TOOLTIP = messages.getString(\"CPUView_SelfTimeColumnTooltip\"); // NOI18N\n    static final String SELF_TIME_CPU_COLUMN_TOOLTIP = messages.getString(\"CPUView_SelfTimeCpuColumnTooltip\"); // NOI18N\n    static final String TOTAL_TIME_COLUMN_TOOLTIP = messages.getString(\"CPUView_TotalTimeColumnTooltip\"); // NOI18N\n    static final String TOTAL_TIME_CPU_COLUMN_TOOLTIP = messages.getString(\"CPUView_TotalTimeCpuColumnTooltip\"); // NOI18N\n    static final String HITS_COLUMN_TOOLTIP = messages.getString(\"CPUView_HitsColumnTooltip\"); // NOI18N\n    static final String INVOCATIONS_COLUMN_TOOLTIP = messages.getString(\"CPUView_InvocationsColumnTooltip\"); // NOI18N\n    static final String FILTER_CALLEES_SCOPE = messages.getString(\"CPUView_FilterCalleesScope\"); // NOI18N\n    static final String FILTER_CALLERS_SCOPE = messages.getString(\"CPUView_FilterCallersScope\"); // NOI18N\n    static final String FILTER_SCOPE_TOOLTIP = messages.getString(\"CPUView_FilterScopeTooltip\"); // NOI18N\n    static final String SEARCH_CALLEES_SCOPE = messages.getString(\"CPUView_SearchCalleesScope\"); // NOI18N\n    static final String SEARCH_CALLERS_SCOPE = messages.getString(\"CPUView_SearchCallersScope\"); // NOI18N\n    static final String SEARCH_SCOPE_TOOLTIP = messages.getString(\"CPUView_SearchScopeTooltip\"); // NOI18N\n    static final String HIDE_ZERO_SELF_TIME_TOOLTIP = messages.getString(\"CPUView_HideZeroSelfTimeTooltip\"); // NOI18N\n    static final String EXPAND_MENU = messages.getString(\"CPUView_ExpandMenu\"); // NOI18N\n    static final String EXPAND_PLAIN_ITEM = messages.getString(\"CPUView_ExpandPlainItem\"); // NOI18N\n    static final String EXPAND_TOPMOST_ITEM = messages.getString(\"CPUView_ExpandTopmostItem\"); // NOI18N\n    static final String COLLAPSE_CHILDREN_ITEM = messages.getString(\"CPUView_CollapseChildrenItem\"); // NOI18N\n    static final String COLLAPSE_ALL_ITEM = messages.getString(\"CPUView_CollapseAllItem\"); // NOI18N\n    static final String SHOW_MENU = messages.getString(\"CPUView_ShowMenu\"); // NOI18N\n    static final String SHOW_THREAD_ITEM = messages.getString(\"CPUView_ShowThreadItem\"); // NOI18N\n    static final String HIDE_THREAD_ITEM = messages.getString(\"CPUView_HideThreadItem\"); // NOI18N\n    // -----\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/CodeRegionLivePanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.*;\nimport java.awt.image.BufferedImage;\nimport java.text.MessageFormat;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.coderegion.CodeRegionResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.ui.LiveResultsPanel;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\n\n\n/**\n * A display for live code region profiling results\n *\n * @author Ian Formanek\n */\npublic class CodeRegionLivePanel extends JPanel implements LiveResultsPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.cpu.Bundle\"); // NOI18N\n    private static final String PANEL_NAME = messages.getString(\"CodeRegionLivePanel_PanelName\"); // NOI18N\n    private static final String NO_RESULTS_TERMINATED_MSG = messages.getString(\"CodeRegionLivePanel_NoResultsTerminatedMsg\"); // NOI18N\n    private static final String NO_RESULTS_REGION_MSG = messages.getString(\"CodeRegionLivePanel_NoResultsRegionMsg\"); // NOI18N\n    private static final String INDIVIDUAL_TIMES_MSG = messages.getString(\"CodeRegionLivePanel_IndividualTimesMsg\"); // NOI18N\n    private static final String SUMMARY_TIMES_MSG = messages.getString(\"CodeRegionLivePanel_SummaryTimesMsg\"); // NOI18N\n    private static final String TOTAL_INVOCATIONS_MSG = messages.getString(\"CodeRegionLivePanel_TotalInvocationsMsg\"); // NOI18N\n    private static final String ALL_REMEMBERED_MSG = messages.getString(\"CodeRegionLivePanel_AllRememberedMsg\"); // NOI18N\n    private static final String LAST_REMEMBERED_MSG = messages.getString(\"CodeRegionLivePanel_LastRememberedMsg\"); // NOI18N\n    private static final String INVOCATIONS_LISTED_MSG = messages.getString(\"CodeRegionLivePanel_InvocationsListedMsg\"); // NOI18N\n    private static final String AREA_ACCESS_NAME = messages.getString(\"CodeRegionLivePanel_AreaAccessName\"); // NOI18N\n                                                                                                             // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private HTMLTextArea resArea;\n    private ProfilerClient profilerClient;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CodeRegionLivePanel(ProfilerClient client) {\n        this.profilerClient = client;\n        setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));\n        setLayout(new BorderLayout());\n        resArea = new HTMLTextArea();\n        resArea.getAccessibleContext().setAccessibleName(AREA_ACCESS_NAME);\n        add(new JScrollPane(resArea), BorderLayout.CENTER);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getSortingColumn() {\n        return CommonConstants.SORTING_COLUMN_DEFAULT; // Not used for code region\n    }\n\n    public boolean getSortingOrder() {\n        return false; // Not used for code region\n    }\n\n    public String getTitle() {\n        return PANEL_NAME;\n    }\n\n    public BufferedImage getViewImage(boolean onlyVisibleArea) {\n        return null;\n    }\n\n    public String getViewName() {\n        return null;\n    }\n\n    public boolean fitsVisibleArea() {\n        return true;\n    }\n\n    public void handleRemove() {\n    }\n\n    /**\n     * Called when auto refresh is on and profiling session will finish\n     * to give the panel chance to do some cleanup before asynchrounous\n     * call to updateLiveResults() will happen.\n     */\n    public void handleShutdown() {\n        // Nothing to do for Code Region live results, updateLiveResults will be called explicitely from outside\n    }\n\n    // --- Save current View action support --------------------------------------\n    // Code Region not used in 6.0\n    public boolean hasView() {\n        return false;\n    }\n\n    public void reset() {\n        updateLiveResults();\n    }\n\n    public boolean supports(int instrumentationType) {\n        return instrumentationType == CommonConstants.INSTR_CODE_REGION;\n    }\n\n    public void updateLiveResults() {\n        try {\n            CodeRegionResultsSnapshot sn = profilerClient.getCodeRegionProfilingResultsSnapshot();\n            resArea.setText(getResultsText(sn.getTimes(), sn.getTimerCountsInSecond()));\n        } catch (ClientUtils.TargetAppOrVMTerminated e) {\n            resArea.setText(\"<i>\" + NO_RESULTS_TERMINATED_MSG + \"</i>\"); // NOI18N\n        }\n    }\n\n    private String getResultsText(long[] results, long timerCountsInSecond) {\n        StringBuilder resultText = new StringBuilder(results.length * 10);\n        StringBuilder summaryOfTimes = new StringBuilder();\n        long sum = 0;\n        long min;\n        long max;\n\n        if (results.length < 2) {\n            resultText.append(\"<i>\").append(NO_RESULTS_REGION_MSG).append(\"</i>\"); // NOI18N\n        } else {\n            min = max = results[1];\n\n            int nRes = results.length - 1;\n\n            StringBuilder individualTimes = new StringBuilder();\n\n            for (int i = 1; i < results.length; i++) {\n                long time = results[i];\n                sum += time;\n\n                if (time > max) {\n                    max = time;\n                } else if (time < min) {\n                    min = time;\n                }\n\n                individualTimes.append(MessageFormat.format(INDIVIDUAL_TIMES_MSG,\n                        StringUtils.mcsTimeToString((time * 1000000) / timerCountsInSecond)));\n                individualTimes.append(\"<br>\"); // NOI18N\n            }\n\n            summaryOfTimes.append(MessageFormat.format(SUMMARY_TIMES_MSG,\n                    StringUtils.mcsTimeToString((sum * 1000000) / timerCountsInSecond), // total\n                    StringUtils.mcsTimeToString((long) (((double) sum * 1000000) / nRes / timerCountsInSecond)), // average\n                    StringUtils.mcsTimeToString((min * 1000000) / timerCountsInSecond), // minimum\n                    StringUtils.mcsTimeToString((max * 1000000) / timerCountsInSecond) // maximum\n            ));\n\n            resultText.append(MessageFormat.format(TOTAL_INVOCATIONS_MSG, \"\" + results[0])); // NOI18N\n            resultText.append(\", \"); // NOI18N\n\n            if (results[0] <= nRes) {\n                resultText.append(ALL_REMEMBERED_MSG);\n            } else {\n                resultText.append(MessageFormat.format(LAST_REMEMBERED_MSG, \"\" + nRes)); // NOI18N\n            }\n\n            resultText.append(\"<br>\"); // NOI18N\n            resultText.append(summaryOfTimes);\n            resultText.append(\"<br><br><hr><br>\"); // NOI18N\n            resultText.append(individualTimes);\n            resultText.append(\"<br><hr><br>\"); // NOI18N\n            resultText.append(MessageFormat.format(INVOCATIONS_LISTED_MSG, \"\" + nRes)); // NOI18N\n            resultText.append(\", \"); // NOI18N\n            resultText.append(summaryOfTimes);\n        }\n\n        return resultText.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/CodeRegionSnapshotPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.*;\nimport java.text.MessageFormat;\nimport java.util.Date;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.jfluid.results.ResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.coderegion.CodeRegionResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\n\n\n/**\n * A display for snapshot of code region profiling results\n *\n * @author Ian Formanek\n */\npublic class CodeRegionSnapshotPanel extends JPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.cpu.Bundle\"); // NOI18N\n    private static final String PANEL_NAME = messages.getString(\"CodeRegionSnapshotPanel_PanelName\"); // NOI18N\n    private static final String NO_RESULTS_REGION_MSG = messages.getString(\"CodeRegionSnapshotPanel_NoResultsRegionMsg\"); // NOI18N\n    private static final String INDIVIDUAL_TIMES_MSG = messages.getString(\"CodeRegionSnapshotPanel_IndividualTimesMsg\"); // NOI18N\n    private static final String SUMMARY_TIMES_MSG = messages.getString(\"CodeRegionSnapshotPanel_SummaryTimesMsg\"); // NOI18N\n    private static final String TOTAL_INVOCATIONS_MSG = messages.getString(\"CodeRegionSnapshotPanel_TotalInvocationsMsg\"); // NOI18N\n    private static final String ALL_REMEMBERED_MSG = messages.getString(\"CodeRegionSnapshotPanel_AllRememberedMsg\"); // NOI18N\n    private static final String LAST_REMEMBERED_MSG = messages.getString(\"CodeRegionSnapshotPanel_LastRememberedMsg\"); // NOI18N\n    private static final String INVOCATIONS_LISTED_MSG = messages.getString(\"CodeRegionSnapshotPanel_InvocationsListedMsg\"); // NOI18N\n    private static final String AREA_ACCESS_NAME = messages.getString(\"CodeRegionSnapshotPanel_AreaAccessName\"); // NOI18N\n                                                                                                                 // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private CodeRegionResultsSnapshot snapshot;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CodeRegionSnapshotPanel(CodeRegionResultsSnapshot snapshot) {\n        this.snapshot = snapshot;\n        setLayout(new BorderLayout());\n        setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));\n\n        long[] results = snapshot.getTimes();\n        long timerCountsInSecond = snapshot.getTimerCountsInSecond();\n        StringBuilder resultText = new StringBuilder(results.length * 10);\n        StringBuilder summaryOfTimes = new StringBuilder();\n        long sum = 0;\n        long min;\n        long max;\n\n        if (results.length < 2) {\n            resultText.append(\"<i>\").append(NO_RESULTS_REGION_MSG).append(\"</i>\"); // NOI18N\n        } else {\n            min = max = results[1];\n\n            int nRes = results.length - 1;\n\n            StringBuilder individualTimes = new StringBuilder();\n\n            for (int i = 1; i < results.length; i++) {\n                long time = results[i];\n                sum += time;\n\n                if (time > max) {\n                    max = time;\n                } else if (time < min) {\n                    min = time;\n                }\n\n                individualTimes.append(MessageFormat.format(INDIVIDUAL_TIMES_MSG,\n                        StringUtils.mcsTimeToString((time * 1000000) / timerCountsInSecond)));\n                individualTimes.append(\"<br>\"); // NOI18N\n            }\n\n            summaryOfTimes.append(MessageFormat.format(SUMMARY_TIMES_MSG,\n                    StringUtils.mcsTimeToString((sum * 1000000) / timerCountsInSecond), // total\n                    StringUtils.mcsTimeToString((long) (((double) sum * 1000000) / nRes / timerCountsInSecond)), // average\n                    StringUtils.mcsTimeToString((min * 1000000) / timerCountsInSecond), // minimum\n                    StringUtils.mcsTimeToString((max * 1000000) / timerCountsInSecond) // maximum\n            ));\n\n            resultText.append(MessageFormat.format(TOTAL_INVOCATIONS_MSG, \"\" + results[0])); // NOI18N\n            resultText.append(\", \"); // NOI18N\n\n            if (results[0] <= nRes) {\n                resultText.append(ALL_REMEMBERED_MSG);\n            } else {\n                resultText.append(MessageFormat.format(LAST_REMEMBERED_MSG, \"\" + nRes)); // NOI18N\n            }\n\n            resultText.append(\"<br>\"); // NOI18N\n            resultText.append(summaryOfTimes);\n            resultText.append(\"<br><br><hr><br>\"); // NOI18N\n            resultText.append(individualTimes);\n            resultText.append(\"<br><hr><br>\"); // NOI18N\n            resultText.append(MessageFormat.format(INVOCATIONS_LISTED_MSG, \"\" + nRes)); // NOI18N\n            resultText.append(\", \"); // NOI18N\n            resultText.append(summaryOfTimes);\n        }\n\n        HTMLTextArea resArea = new HTMLTextArea(resultText.toString());\n        resArea.getAccessibleContext().setAccessibleName(AREA_ACCESS_NAME);\n        add(new JScrollPane(resArea), BorderLayout.CENTER);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public ResultsSnapshot getSnapshot() {\n        return snapshot;\n    }\n\n    public String getTitle() {\n        return MessageFormat.format(PANEL_NAME, StringUtils.formatUserDate(new Date(snapshot.getTimeTaken())));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/CombinedPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.image.BufferedImage;\nimport javax.swing.BorderFactory;\nimport javax.swing.JSeparator;\nimport javax.swing.JSplitPane;\nimport javax.swing.plaf.basic.BasicSplitPaneDivider;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class CombinedPanel extends JSplitPane implements ScreenshotProvider {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CombinedPanel(int splitOrientation, Component component1, Component component2) {\n        super(splitOrientation, component1, component2);\n        tweakUI();\n    }\n\n    public void exportData(int exportedFileType, ExportDataDumper eDD, String viewName) {\n        ((CCTDisplay)leftComponent).exportData(exportedFileType, eDD, true, viewName);\n        ((SnapshotFlatProfilePanel)rightComponent).exportData(exportedFileType, eDD, true, viewName);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public BufferedImage getCurrentViewScreenshot(boolean onlyVisible) {\n        return UIUtils.createScreenshot(this);\n    }\n\n    public String getDefaultViewName() {\n        return \"cpu-combined\"; // NOI18N\n    }\n\n    public boolean fitsVisibleArea() {\n        return true;\n    }\n\n    private void tweakUI() {\n        setBorder(null);\n        setDividerSize(5);\n\n        if (!(getUI() instanceof BasicSplitPaneUI)) return;\n\n        BasicSplitPaneDivider divider = ((BasicSplitPaneUI)getUI()).getDivider();\n        if (divider != null) {\n            Color c = UIUtils.isNimbus() ? UIUtils.getDisabledLineColor() :\n                    new JSeparator().getForeground();\n            divider.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, c));\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/DiffCCTDisplay.java",
    "content": "/*\n * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport javax.swing.JLabel;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.ui.components.table.DiffBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelTableCellRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DiffCCTDisplay extends CCTDisplay {\n\n    public DiffCCTDisplay(CPUResUserActionsHandler actionsHandler, Boolean sampling) {\n        super(actionsHandler, sampling);\n    }\n\n\n    protected boolean supportsReverseCallGraph() {\n        return false;\n    }\n\n    protected boolean supportsSubtreeCallGraph() {\n        return false;\n    }\n\n\n    protected Float getNodeTimeRel(long time, float percent) {\n        return new Float(time);\n    }\n\n    protected String getNodeTime(long time, float percent) {\n        return getNodeSecondaryTime(time);\n    }\n\n    protected String getNodeSecondaryTime(long time) {\n        return (time > 0 ? \"+\" : \"\") + StringUtils.mcsTimeToString(time) + \" ms\"; // NOI18N\n    }\n\n    protected String getNodeInvocations(int nCalls) {\n        return (nCalls > 0 ? \"+\" : \"\") + Integer.toString(nCalls); // NOI18N\n    }\n\n    protected void initColumnsData() {\n        super.initColumnsData();\n        columnRenderers[1] = new DiffBarCellRenderer(0, 0);\n        columnRenderers[2] = new LabelTableCellRenderer(JLabel.TRAILING);\n    }\n\n    public void prepareResults() {\n        super.prepareResults();\n        DiffBarCellRenderer renderer = (DiffBarCellRenderer)columnRenderers[1];\n        long bound = ((CPUResultsDiff)snapshot).getBound(currentView);\n        renderer.setMinimum(-bound);\n        renderer.setMaximum(bound);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/DiffFlatProfilePanel.java",
    "content": "/*\n * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport javax.swing.JLabel;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.DiffFlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.ui.components.table.DiffBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelTableCellRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DiffFlatProfilePanel extends SnapshotFlatProfilePanel {\n\n    public DiffFlatProfilePanel(CPUResUserActionsHandler actionsHandler, Boolean sampling) {\n        super(actionsHandler, sampling);\n    }\n\n\n    protected boolean supportsReverseCallGraph() {\n        return false;\n    }\n\n    protected boolean supportsSubtreeCallGraph() {\n        return false;\n    }\n\n\n    protected Object computeValueAt(int row, int col) {\n        long value;\n        switch (col) {\n            case 0:\n                return flatProfileContainer.getMethodNameAtRow(row);\n            case 1:\n                return new Float(flatProfileContainer.getTimeInMcs0AtRow(row));\n            case 2:\n                value = flatProfileContainer.getTimeInMcs0AtRow(row);\n                return (value > 0 ? \"+\" : \"\") + StringUtils.mcsTimeToString(value) + \" ms\"; // NOI18N\n            case 3:\n                if (collectingTwoTimeStamps) {\n                    value = flatProfileContainer.getTimeInMcs1AtRow(row);\n                    return (value > 0 ? \"+\" : \"\") + StringUtils.mcsTimeToString(value) + \" ms\"; // NOI18N\n                } else {\n                    value = flatProfileContainer.getTotalTimeInMcs0AtRow(row);\n                    return (value > 0 ? \"+\" : \"\") + StringUtils.mcsTimeToString(value) + \" ms\"; // NOI18N\n                }\n            case 4:\n                if (collectingTwoTimeStamps) {\n                    value = flatProfileContainer.getTotalTimeInMcs0AtRow(row);\n                    return (value > 0 ? \"+\" : \"\") + StringUtils.mcsTimeToString(value) + \" ms\"; // NOI18N\n                } else {\n                    value = flatProfileContainer.getNInvocationsAtRow(row);\n                    return (value > 0 ? \"+\" : \"\") + intFormat.format(value); // NOI18N\n                }\n            case 5:\n                value = flatProfileContainer.getTotalTimeInMcs1AtRow(row);\n                return (value > 0 ? \"+\" : \"\") + StringUtils.mcsTimeToString(value) + \" ms\"; // NOI18N\n            case 6:\n                value = flatProfileContainer.getNInvocationsAtRow(row);\n                return (value > 0 ? \"+\" : \"\") + intFormat.format(value); // NOI18N\n            default:\n                return null;\n        }\n    }\n    \n    protected void initColumnsData() {\n        super.initColumnsData();\n        columnRenderers[1] = new DiffBarCellRenderer(0, 0);\n        columnRenderers[2] = new LabelTableCellRenderer(JLabel.TRAILING);\n    }\n    \n    protected void obtainResults() {\n        super.obtainResults();\n        DiffFlatProfileContainer container = (DiffFlatProfileContainer)flatProfileContainer;\n        DiffBarCellRenderer renderer = (DiffBarCellRenderer)columnRenderers[1];\n        renderer.setMinimum(container.getMinTime());\n        renderer.setMaximum(container.getMaxTime());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/FlatProfilePanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.util.HashSet;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.FilterComponent;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedTable;\nimport org.graalvm.visualvm.lib.ui.components.table.ClassNameTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.ExtendedTableModel;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelBracketTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.MethodNameTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.SortableTableModel;\n\n\n/**\n * A common abstract superclass for Hotspots display containing a flat profile.\n * <p>\n * The subclasses need to implement these methods:\n * obtainResults () to initialize the data either from snapshot or from live data.\n * getTitle () to provide title for the panel\n * getMethodClassNameAndSig () to map methodId to class/method names\n * supportsReverseCallGraph () to declare if displaying reverse call graph is supported\n * showReverseCallGraph () to display the reverse call graph (utilizing actionsHandler)\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic abstract class FlatProfilePanel extends CPUResultsPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.cpu.Bundle\"); // NOI18N\n    private static final String FILTER_ITEM_NAME = messages.getString(\"FlatProfilePanel_FilterItemName\"); // NOI18N\n    private static final String METHOD_COLUMN_NAME = messages.getString(\"FlatProfilePanel_MethodColumnName\"); // NOI18N\n    private static final String METHOD_COLUMN_TOOLTIP = messages.getString(\"FlatProfilePanel_MethodColumnToolTip\"); // NOI18N\n    private static final String METHOD_FILTER_HINT = messages.getString(\"FlatProfilePanel_MethodFilterHint\"); // NOI18N\n    private static final String CLASS_COLUMN_NAME = messages.getString(\"FlatProfilePanel_ClassColumnName\"); // NOI18N\n    private static final String CLASS_COLUMN_TOOLTIP = messages.getString(\"FlatProfilePanel_ClassColumnToolTip\"); // NOI18N\n    private static final String CLASS_FILTER_HINT = messages.getString(\"FlatProfilePanel_ClassFilterHint\"); // NOI18N\n    private static final String PACKAGE_COLUMN_NAME = messages.getString(\"FlatProfilePanel_PackageColumnName\"); // NOI18N\n    private static final String PACKAGE_COLUMN_TOOLTIP = messages.getString(\"FlatProfilePanel_PackageColumnToolTip\"); // NOI18N\n    private static final String PACKAGE_FILTER_HINT = messages.getString(\"FlatProfilePanel_PackageFilterHint\"); // NOI18N\n    private static final String SELFTIME_REL_COLUMN_NAME = messages.getString(\"FlatProfilePanel_SelfTimeRelColumnName\"); // NOI18N\n    private static final String SELFTIME_REL_COLUMN_TOOLTIP = messages.getString(\"FlatProfilePanel_SelfTimeRelColumnToolTip\"); // NOI18N\n    private static final String SELFTIME_COLUMN_NAME = messages.getString(\"FlatProfilePanel_SelfTimeColumnName\"); // NOI18N\n    private static final String SELFTIME_COLUMN_TOOLTIP = messages.getString(\"FlatProfilePanel_SelfTimeColumnToolTip\"); // NOI18N\n    private static final String SELFTIME_CPU_COLUMN_NAME = messages.getString(\"FlatProfilePanel_SelfTimeCpuColumnName\"); // NOI18N\n    private static final String SELFTIME_CPU_COLUMN_TOOLTIP = messages.getString(\"FlatProfilePanel_SelfTimeCpuColumnToolTip\"); // NOI18N\n    private static final String TOTALTIME_COLUMN_NAME = messages.getString(\"FlatProfilePanel_TotalTimeColumnName\"); // NOI18N\n    private static final String TOTALTIME_COLUMN_TOOLTIP = messages.getString(\"FlatProfilePanel_TotalTimeColumnToolTip\"); // NOI18N\n    private static final String TOTALTIME_CPU_COLUMN_NAME = messages.getString(\"FlatProfilePanel_TotalTimeCpuColumnName\"); // NOI18N\n    private static final String TOTALTIME_CPU_COLUMN_TOOLTIP = messages.getString(\"FlatProfilePanel_TotalTimeCpuColumnToolTip\"); // NOI18N\n    private static final String INVOCATIONS_COLUMN_NAME = messages.getString(\"FlatProfilePanel_InvocationsColumnName\"); // NOI18N\n    private static final String SAMPLES_COLUMN_NAME = messages.getString(\"FlatProfilePanel_SamplesColumnName\"); // NOI18N\n    private static final String INVOCATIONS_COLUMN_TOOLTIP = messages.getString(\"FlatProfilePanel_InvocationsColumnToolTip\"); // NOI18N\n    private static final String SAMPLES_COLUMN_TOOLTIP = messages.getString(\"FlatProfilePanel_SamplesColumnToolTip\"); // NOI18N\n    private static final String TABLE_ACCESS_NAME = messages.getString(\"FlatProfilePanel_TableAccessName\"); // NOI18N\n    private static final String NO_RELEVANT_DATA = messages.getString(\"FlatProfilePanel_NoRelevantData\"); // NOI18N\n// -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    //float maxValue;\n    protected CustomBarCellRenderer barRenderer;\n    protected ExtendedTableModel resTableModel;\n    protected FilterComponent filterComponent;\n    protected FlatProfileContainer flatProfileContainer;\n    protected JExtendedTable resTable;\n    protected JScrollPane jScrollPane;\n    protected String filterString = \"\"; // NOI18N\n    protected boolean collectingTwoTimeStamps;\n    protected boolean sortOrder;\n    protected double valueFilterValue = 0.0d;\n    protected int filterType = CommonConstants.FILTER_CONTAINS;\n    protected int sortBy;\n    protected int threadId;\n    private CPUSelectionHandler selectionHandler;\n    private JPanel noDataPanel;\n    private int minNamesColumnWidth; // minimal width of classnames columns\n    private int sortingColumn;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public FlatProfilePanel(CPUResUserActionsHandler actionsHandler, Boolean sampling) {\n        this(actionsHandler, null, sampling);\n    }\n\n    public FlatProfilePanel(CPUResUserActionsHandler actionsHandler, CPUSelectionHandler selectionHandler, Boolean sampling) {\n        super(actionsHandler, sampling);\n        this.selectionHandler = selectionHandler;\n        setDefaultSorting();\n\n        minNamesColumnWidth = getFontMetrics(getFont()).charWidth('W') * 30; // NOI18N\n\n        cornerPopup = new JPopupMenu();\n\n        jScrollPane = createScrollPaneVerticalScrollBarAlways();\n        jScrollPane.setCorner(JScrollPane.UPPER_RIGHT_CORNER, createHeaderPopupCornerButton(cornerPopup));\n        jScrollPane.setBorder(BorderFactory.createEmptyBorder());\n        jScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());\n        jScrollPane.addMouseWheelListener(new MouseWheelListener() {\n                public void mouseWheelMoved(MouseWheelEvent e) {\n                    if (resTable != null) {\n                        resTable.mouseWheelMoved(e);\n                    }\n                }\n            });\n        initFilterPanel();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void clearSelection() {\n        resTable.clearSelection();\n    }\n    \n    public void setCPUSelectionHandler(CPUSelectionHandler handler) {\n        selectionHandler = handler;\n    }\n\n    @Override\n    public int getCurrentThreadId() {\n        return threadId;\n    }\n\n    // NOTE: this method only sets sortingColumn, sortOrder and sortBy, it doesn't refresh UI!\n    public void setDefaultSorting() {\n        setSorting(1, SortableTableModel.SORT_ORDER_DESC);\n    }\n\n    public int getFilterType() {\n        return filterComponent.getFilterType();\n    }\n\n    public String getFilterValue() {\n        return filterComponent.getFilterValue();\n    }\n\n    public void setFilterValues(String filterValue, int filterType) {\n        filterComponent.setFilter(filterValue, filterType);\n    }\n\n    /*  private void printPercents() {\n       double sum = 0;\n    \n       for (int i = 0; i < flatProfileContainer.getNRows(); i++) {\n         sum += flatProfileContainer.getPercentAtRow(i);\n       }\n    \n       System.err.println(\"Sum: \"+sum);\n       }\n     */\n\n    // --- Find functionality stuff\n    public void setFindString(String findString) {\n        resTable.setFindParameters(findString, 0);\n    }\n\n    public String getFindString() {\n        return resTable.getFindString();\n    }\n\n    public boolean isFindStringDefined() {\n        return resTable.isFindStringDefined();\n    }\n\n    public void setResultsAvailable(boolean available) {\n        JViewport viewport = jScrollPane.getViewport();\n        Component viewComponent = available ? resTable : noDataPanel;\n        if (viewComponent != viewport.getView()) {\n            viewport.setView(viewComponent);\n            revalidate();\n            repaint();\n        }\n    }\n\n    public Object getResultsViewReference() {\n        return resTable;\n    }\n\n    public int getSortBy(int column) {\n        switch (column) {\n            case 0:\n                return FlatProfileContainer.SORT_BY_NAME;\n            case 1:\n            case 2:\n                return FlatProfileContainer.SORT_BY_TIME;\n            case 3:\n                return collectingTwoTimeStamps ? FlatProfileContainer.SORT_BY_SECONDARY_TIME\n                                               : FlatProfileContainer.SORT_BY_TOTAL_TIME;\n            case 4:\n                return collectingTwoTimeStamps ? FlatProfileContainer.SORT_BY_TOTAL_TIME\n                                               : FlatProfileContainer.SORT_BY_INV_NUMBER;\n            case 5:\n                return FlatProfileContainer.SORT_BY_SECONDARY_TOTAL_TIME;\n            case 6:\n                return FlatProfileContainer.SORT_BY_INV_NUMBER;\n        }\n\n        return FlatProfileContainer.SORT_BY_TIME;\n    }\n\n    // NOTE: this method only sets sortingColumn, sortOrder and sortBy, it doesn't refresh UI!\n    public void setSorting(int sColumn, boolean sOrder) {\n        setSorting(sColumn, sOrder, false);\n    }\n    \n    public void setSorting(int sColumn, boolean sOrder, boolean refreshUI) {\n        if (!refreshUI && sColumn == CommonConstants.SORTING_COLUMN_DEFAULT) {\n            setDefaultSorting();\n        } else {\n            sortingColumn = sColumn;\n            sortOrder = sOrder;\n            sortBy = getSortBy(sortingColumn);\n        }\n        if (refreshUI) {\n            resTableModel.setInitialSorting(resTableModel.getVirtualColumn(sColumn), sOrder);\n            resTableModel.sortByColumn(sColumn, sOrder);\n        }\n    }\n\n    @Override\n    public int getSortingColumn() {\n        if (resTableModel == null) {\n            return CommonConstants.SORTING_COLUMN_DEFAULT;\n        }\n\n        return resTableModel.getRealColumn(resTableModel.getSortingColumn());\n    }\n\n    @Override\n    public boolean getSortingOrder() {\n        if (resTableModel == null) {\n            return false;\n        }\n\n        return resTableModel.getSortingOrder();\n    }\n\n    public void addFilterListener(ChangeListener listener) {\n        filterComponent.addChangeListener(listener);\n    }\n\n    public void addResultsViewFocusListener(FocusListener listener) {\n        resTable.addFocusListener(listener);\n    }\n\n    public boolean findFirst() {\n        return resTable.findFirst();\n    }\n\n    public boolean findNext() {\n        return resTable.findNext();\n    }\n\n    public boolean findPrevious() {\n        return resTable.findPrevious();\n    }\n\n    @Override\n    public void prepareResults() {\n        prepareResults(true);\n    }\n\n    public void removeFilterListener(ChangeListener listener) {\n        filterComponent.removeChangeListener(listener);\n    }\n\n    public void removeResultsViewFocusListener(FocusListener listener) {\n        resTable.removeFocusListener(listener);\n    }\n\n    @Override\n    public void requestFocus() {\n        if (resTable != null) {\n            SwingUtilities.invokeLater(new Runnable() { // must be invoked lazily to override default focus of first component (top-right cornerButton)\n                    public void run() {\n                        resTable.requestFocus();\n                    }\n                });\n        }\n    }\n\n    // ---\n\n    // components are discarded between profiling sessions\n    @Override\n    public void reset() {\n        jScrollPane.setViewportView(null);\n        flatProfileContainer = null;\n        resTable = null;\n        resTableModel = null;\n    }\n\n    public void selectMethod(int methodId) {\n        //    System.err.println(\"Select method: \"+methodId);\n        if (methodId == 0) {\n            resTable.getSelectionModel().clearSelection();\n\n            return;\n        }\n\n        int sel = resTable.getSelectedRow();\n\n        if (sel >= flatProfileContainer.getNRows()) {\n            sel = flatProfileContainer.getNRows() - 1; // no idea how can this happen, but it happens - see #100355\n        }\n\n        if ((sel != -1) && (getCurrentThreadId() == threadId) && (flatProfileContainer.getMethodIdAtRow(sel) == methodId)) {\n            return; // the right method is already selected\n        }\n\n        // lookup the row index with the matching methodId\n        for (int i = 0; i < flatProfileContainer.getNRows(); i++) {\n            //      System.err.println(\"Checking: \"+flatProfileContainer.getMethodIdAtRow(i));\n            if (flatProfileContainer.getMethodIdAtRow(i) == methodId) {\n                resTable.getSelectionModel().setSelectionInterval(i, i);\n                resTable.scrollRectToVisible(resTable.getCellRect(i, 0, true));\n\n                break;\n            }\n        }\n    }\n\n    public void selectMethod(String methodName) {\n        for (int i = 0; i < resTable.getRowCount(); i++) {\n            if (resTable.getValueAt(i, 0).toString().equals(methodName)) {\n                resTable.getSelectionModel().setSelectionInterval(i, i);\n                resTable.scrollRectToVisible(resTable.getCellRect(i, 0, true));\n\n                return;\n            }\n        }\n\n        resTable.getSelectionModel().clearSelection();\n    }\n\n    @Override\n    protected String getSelectedMethodName() {\n        if ((resTable == null) || (resTableModel == null)) {\n            return null;\n        }\n\n        if (resTable.getSelectedRow() == -1) {\n            return null;\n        }\n\n        return resTable.getValueAt(resTable.getSelectedRow(), 0).toString();\n    }\n\n    @Override\n    protected void initColumnSelectorItems() {\n        cornerPopup.removeAll();\n\n        JCheckBoxMenuItem menuItem;\n\n        for (int i = 0; i < columnCount; i++) {\n            menuItem = new JCheckBoxMenuItem(columnNames[i]);\n            menuItem.setActionCommand(Integer.toString(i));\n            addMenuItemListener(menuItem);\n\n            if (resTable != null) {\n                menuItem.setState(resTableModel.isRealColumnVisible(i));\n\n                if (i == 0) {\n                    menuItem.setEnabled(false);\n                }\n            } else {\n                menuItem.setState(true);\n            }\n\n            cornerPopup.add(menuItem);\n        }\n\n        cornerPopup.addSeparator();\n\n        JCheckBoxMenuItem filterMenuItem = new JCheckBoxMenuItem(FILTER_ITEM_NAME);\n        filterMenuItem.setActionCommand(\"Filter\"); // NOI18N\n        addMenuItemListener(filterMenuItem);\n\n        if (filterComponent == null) {\n            filterMenuItem.setState(true);\n        } else {\n            filterMenuItem.setState(filterComponent.getComponent().isVisible());\n        }\n\n        cornerPopup.add(filterMenuItem);\n\n        cornerPopup.pack();\n    }\n\n    protected void initColumnsData() {\n        columnCount = collectingTwoTimeStamps ? 7 : 5;\n\n        columnsVisibility = new boolean[columnCount];\n        for (int i = 0; i < columnCount - 1; i++)\n            columnsVisibility[i] = true;\n        if (isSampling() != null && !isSampling()) columnsVisibility[columnCount - 1] = true;\n\n        columnWidths = new int[columnCount - 1]; // Width of the first column fits to width\n        columnNames = new String[columnCount];\n        columnToolTips = new String[columnCount];\n        columnRenderers = new TableCellRenderer[columnCount];\n\n        columnNames[0] = METHOD_COLUMN_NAME;\n        columnToolTips[0] = METHOD_COLUMN_TOOLTIP;\n\n        columnNames[1] = SELFTIME_REL_COLUMN_NAME;\n        columnToolTips[1] = SELFTIME_REL_COLUMN_TOOLTIP;\n\n        columnNames[2] = SELFTIME_COLUMN_NAME;\n        columnToolTips[2] = SELFTIME_COLUMN_TOOLTIP;\n\n        if (collectingTwoTimeStamps) {\n            columnNames[3] = SELFTIME_CPU_COLUMN_NAME;\n            columnToolTips[3] = SELFTIME_CPU_COLUMN_TOOLTIP;\n            columnNames[4] = TOTALTIME_COLUMN_NAME;\n            columnToolTips[4] = TOTALTIME_COLUMN_TOOLTIP;\n            columnNames[5] = TOTALTIME_CPU_COLUMN_NAME;\n            columnToolTips[5] = TOTALTIME_CPU_COLUMN_TOOLTIP;\n            if (isSampling() != null && isSampling()) {\n                columnNames[6] = SAMPLES_COLUMN_NAME;\n                columnToolTips[6] = SAMPLES_COLUMN_TOOLTIP;\n            } else {\n                columnNames[6] = INVOCATIONS_COLUMN_NAME;\n                columnToolTips[6] = INVOCATIONS_COLUMN_TOOLTIP;\n            }\n        } else { // just absolute\n            columnNames[3] = TOTALTIME_COLUMN_NAME;\n            columnToolTips[3] = TOTALTIME_COLUMN_TOOLTIP;\n            if (isSampling() != null && isSampling()) {\n                columnNames[4] = SAMPLES_COLUMN_NAME;\n                columnToolTips[4] = SAMPLES_COLUMN_TOOLTIP;\n            } else {\n                columnNames[4] = INVOCATIONS_COLUMN_NAME;\n                columnToolTips[4] = INVOCATIONS_COLUMN_TOOLTIP;\n            }\n        }\n\n        int maxWidth = getFontMetrics(getFont()).charWidth('W') * 12; // NOI18N // initial width of data columns\n\n        CustomBarCellRenderer customBarCellRenderer = new CustomBarCellRenderer(0, 100);\n        LabelTableCellRenderer labelTableCellRenderer = new LabelTableCellRenderer(JLabel.TRAILING);\n        LabelBracketTableCellRenderer labelBracketTableCellRenderer = new LabelBracketTableCellRenderer(JLabel.TRAILING);\n\n        // method / class / package name\n        columnRenderers[0] = null;\n\n        columnWidths[1 - 1] = maxWidth;\n        columnRenderers[1] = customBarCellRenderer;\n\n        columnWidths[2 - 1] = maxWidth;\n        columnRenderers[2] = labelBracketTableCellRenderer;\n\n        for (int i = 3; i < columnCount; i++) {\n            columnWidths[i - 1] = maxWidth;\n            columnRenderers[i] = labelTableCellRenderer;\n        }\n        \n        if (isSampling() == null) columnCount--;\n    }\n\n    /*  public void updateValueFilter(double value) {\n       System.err.println(\"Update value filter to: \"+value);\n    \n       valueFilterValue = value/3f; // maximum 33.3%\n    \n       flatProfileContainer.filterOriginalData(\n       FilterComponent.getFilterStrings(filterString), filterType, valueFilterValue);\n       flatProfileContainer.sortBy(sortBy, sortOrder);\n       resTable.invalidate();\n       jScrollPane.revalidate();\n       resTable.repaint();\n       } */\n    protected abstract void obtainResults();\n\n    /**\n     * If firstTime is true, it means we need to go and get results from the CCT, which means walking the\n     * nodes of the CCT and doing some calculations, i.e. non-zero cost. Otherwise, we just use the cached\n     * results in flatProfileContainer, and sort them by the current sorting criterion.\n     */\n    protected void prepareResults(boolean firstTime) {\n        if (threadId < -1) {\n            return; // -1 is reserved for all threads merged flat profile;\n        }\n\n        // non-negative numbers are actual thread ids\n        int currentColumnCount = collectingTwoTimeStamps ? 7 : 5;\n\n        if (columnCount != currentColumnCount) {\n            initColumnsData();\n        } else {\n            if (resTable != null) {\n                saveColumnsData();\n            }\n        }\n\n        // first create the UI component model\n        if ((resTableModel == null) || (resTable == null)) {\n            initComponents(); // new components (table & tableModel) are created for each profiling session\n        }\n\n        // then try to fetch some data\n        if (firstTime) {\n            obtainResults(); // This also sorts the results by the appropriate timer\n\n            String firstColumnName = columnNames[0];\n            initFirstColumnName();\n\n            if ((resTable != null) && !columnNames[0].equals(firstColumnName)) {\n                resTable.getColumnModel().getColumn(0).setHeaderValue(columnNames[0]);\n            }\n        }\n\n        flatProfileContainer.sortBy(sortBy, sortOrder);\n\n        //    resTable.clearSelection();\n        resTable.invalidate();\n        jScrollPane.revalidate();\n        resTable.repaint();\n    }\n\n    protected void saveColumnsData() {\n        int index;\n        TableColumnModel colModel = resTable.getColumnModel();\n\n        for (int i = 0; i < resTableModel.getColumnCount(); i++) {\n            index = resTableModel.getRealColumn(i);\n\n            if (index != 0) {\n                columnWidths[index - 1] = colModel.getColumn(i).getPreferredWidth();\n            }\n        }\n\n        columnsVisibility = resTableModel.getColumnsVisibility();\n    }\n\n    protected void updateResults() {\n        if (threadId < -1) {\n            return; // -1 is reserved for all threads merged flat profile;\n        }\n\n        // non-negative numbers are actual thread ids\n        int currentColumnCount = collectingTwoTimeStamps ? 7 : 5;\n\n        if (columnCount != currentColumnCount) {\n            initColumnsData();\n        } else {\n            if (resTable != null) {\n                saveColumnsData();\n            }\n        }\n\n        flatProfileContainer.sortBy(sortBy, sortOrder);\n\n        jScrollPane.setViewportView(resTable);\n        jScrollPane.getViewport().setBackground(resTable.getBackground());\n    }\n\n    private void setColumnsData() {\n        switch (currentView) {\n            case CPUResultsSnapshot.METHOD_LEVEL_VIEW:\n                columnRenderers[0] = new MethodNameTableCellRenderer();\n\n                break;\n            case CPUResultsSnapshot.CLASS_LEVEL_VIEW:\n                columnRenderers[0] = new ClassNameTableCellRenderer();\n\n                break;\n            case CPUResultsSnapshot.PACKAGE_LEVEL_VIEW:\n                columnRenderers[0] = new LabelTableCellRenderer();\n\n                break;\n        }\n\n        int index;\n        TableColumnModel colModel = resTable.getColumnModel();\n\n        for (int i = 0; i < resTableModel.getColumnCount(); i++) {\n            index = resTableModel.getRealColumn(i);\n\n            if (index == 0) {\n                colModel.getColumn(i).setPreferredWidth(minNamesColumnWidth);\n            } else {\n                colModel.getColumn(i).setPreferredWidth(columnWidths[index - 1]);\n            }\n\n            colModel.getColumn(i).setCellRenderer(columnRenderers[index]);\n        }\n    }\n\n    private void addMenuItemListener(JCheckBoxMenuItem menuItem) {\n        menuItem.addActionListener(new java.awt.event.ActionListener() {\n                public void actionPerformed(java.awt.event.ActionEvent e) {\n                    if (e.getActionCommand().equals(\"Filter\")) { // NOI18N\n                        filterComponent.getComponent().setVisible(!filterComponent.getComponent().isVisible());\n\n                        return;\n                    }\n\n                    boolean sortResults = false;\n                    int column = Integer.parseInt(e.getActionCommand());\n                    int currentSortingColumn = resTableModel.getSortingColumn();\n                    int realSortingColumn = resTableModel.getRealColumn(currentSortingColumn);\n                    boolean isColumnVisible = resTableModel.isRealColumnVisible(column);\n\n                    // Current sorting column is going to be hidden\n                    if ((isColumnVisible) && (column == realSortingColumn)) {\n                        // Try to set next column as a currentSortingColumn. If currentSortingColumn is the last column,\n                        // set previous column as a sorting Column (one column is always visible).\n                        currentSortingColumn = ((currentSortingColumn + 1) == resTableModel.getColumnCount())\n                                               ? (currentSortingColumn - 1) : (currentSortingColumn + 1);\n                        realSortingColumn = resTableModel.getRealColumn(currentSortingColumn);\n                        sortResults = true;\n                    }\n\n                    resTableModel.setRealColumnVisibility(column, !isColumnVisible);\n                    resTable.createDefaultColumnsFromModel();\n                    resTableModel.setTable(resTable);\n                    currentSortingColumn = resTableModel.getVirtualColumn(realSortingColumn);\n\n                    if (sortResults) {\n                        sortOrder = resTableModel.getInitialSorting(currentSortingColumn);\n                        sortBy = getSortBy(realSortingColumn);\n                        flatProfileContainer.sortBy(sortBy, sortOrder);\n                        resTable.repaint();\n                    }\n\n                    sortingColumn = realSortingColumn;\n                    resTableModel.setInitialSorting(currentSortingColumn, sortOrder);\n                    resTable.getTableHeader().repaint();\n                    setColumnsData();\n\n                    // TODO [ui-persistence]\n                }\n            });\n    }\n\n    private void initComponents() {\n        resTableModel = new ExtendedTableModel(new SortableTableModel() {\n                @Override\n                public String getColumnName(int col) {\n                    return columnNames[col];\n                }\n\n                public int getRowCount() {\n                    if (flatProfileContainer == null) {\n                        return 0;\n                    }\n\n                    return flatProfileContainer.getNRows();\n                }\n\n                public int getColumnCount() {\n                    return columnCount;\n                }\n\n                @Override\n                public Class<?> getColumnClass(int col) {\n                    if (col == 1) {\n                        return Number.class;\n                    }\n\n                    return String.class;\n                }\n\n                public Object getValueAt(int row, int col) {\n                    return computeValueAt(row, col);\n                }\n\n                @Override\n                public String getColumnToolTipText(int col) {\n                    return columnToolTips[col];\n                }\n\n                @Override\n                public void sortByColumn(int column, boolean order) {\n                    sortingColumn = column;\n                    sortBy = getSortBy(column);\n                    sortOrder = order;\n\n                    int selectedRow = resTable.getSelectedRow();\n                    String selectedRowContents = null;\n\n                    if (selectedRow != -1) {\n                        selectedRowContents = (String) resTable.getValueAt(selectedRow, 0);\n                    }\n\n                    updateResults();\n\n                    if (selectedRowContents != null) {\n                        resTable.selectRowByContents(selectedRowContents, 0, true);\n                    }\n                }\n\n                /**\n                 * @param column The table column index\n                 * @return Initial sorting for the specified column - if true, ascending, if false descending\n                 */\n                @Override\n                public boolean getInitialSorting(int column) {\n                    switch (column) {\n                        case 0:\n                            return true;\n                        default:\n                            return false;\n                    }\n                }\n            });\n\n        if (columnsVisibility != null) {\n            resTableModel.setColumnsVisibility(columnsVisibility);\n        }\n\n        resTable = new JExtendedTable(resTableModel) {\n                @Override\n                public void doLayout() {\n                    int columnsWidthsSum = 0;\n                    int realFirstColumn = -1;\n                    int index;\n\n                    for (int i = 0; i < resTableModel.getColumnCount(); i++) {\n                        index = resTableModel.getRealColumn(i);\n\n                        if (index == 0) {\n                            realFirstColumn = i;\n                        } else {\n                            columnsWidthsSum += getColumnModel().getColumn(i).getPreferredWidth();\n                        }\n                    }\n\n                    if (realFirstColumn != -1) {\n                        getColumnModel().getColumn(realFirstColumn)\n                            .setPreferredWidth(Math.max(getWidth() - columnsWidthsSum, minNamesColumnWidth));\n                    }\n\n                    super.doLayout();\n                }\n\n            };\n        resTable.getAccessibleContext().setAccessibleName(TABLE_ACCESS_NAME);\n\n        resTableModel.setTable(resTable);\n        resTableModel.setInitialSorting(sortingColumn, sortOrder);\n        resTable.setRowSelectionAllowed(true);\n        resTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        resTable.setGridColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);\n        resTable.setSelectionBackground(UIConstants.TABLE_SELECTION_BACKGROUND_COLOR);\n        resTable.setSelectionForeground(UIConstants.TABLE_SELECTION_FOREGROUND_COLOR);\n        resTable.setShowHorizontalLines(UIConstants.SHOW_TABLE_HORIZONTAL_GRID);\n        resTable.setShowVerticalLines(UIConstants.SHOW_TABLE_VERTICAL_GRID);\n        resTable.setRowMargin(UIConstants.TABLE_ROW_MARGIN);\n        resTable.setRowHeight(UIUtils.getDefaultRowHeight() + 2);\n        resTable.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)\n                .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), \"DEFAULT_ACTION\"); // NOI18N\n        resTable.getActionMap().put(\"DEFAULT_ACTION\",\n                                    new AbstractAction() {\n                public void actionPerformed(ActionEvent e) {\n                    performDefaultAction();\n                }\n            }); // NOI18N\n\n        // Disable traversing table cells using TAB and Shift+TAB\n        Set<AWTKeyStroke> keys = new HashSet<>(resTable.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));\n        keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));\n        resTable.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys);\n\n        keys = new HashSet<>(resTable.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));\n        keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));\n        resTable.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys);\n\n        setColumnsData();\n\n        // -------------------------------------\n        resTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n                private int lastSelection = -1;\n\n                public void valueChanged(ListSelectionEvent e) {\n                    int selectedRow = resTable.getSelectedRow();\n                    methodId = (selectedRow != -1) ? flatProfileContainer.getMethodIdAtRow(selectedRow) : (-1);\n\n                    if (selectionHandler != null) {\n                        selectionHandler.methodSelected(lastSelection, methodId, currentView);\n                    }\n\n                    lastSelection = methodId;\n                }\n            });\n\n        resTable.addKeyListener(new KeyAdapter() {\n                @Override\n                public void keyPressed(KeyEvent e) {\n                    if ((e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU)\n                            || ((e.getKeyCode() == KeyEvent.VK_F10) && (e.getModifiers() == InputEvent.SHIFT_MASK))) {\n                        int selectedRow = resTable.getSelectedRow();\n\n                        if (selectedRow != -1) {\n                            if (popupShowSource != null) popupShowSource.setVisible(true);\n                            if (popupShowReverse != null) popupShowReverse.setVisible(true);\n\n                            popupPath = null;\n                            methodId = flatProfileContainer.getMethodIdAtRow(selectedRow);\n\n                            Rectangle cellRect = resTable.getCellRect(selectedRow, 0, false);\n\n                            callGraphPopupMenu.show(e.getComponent(), ((cellRect.x + resTable.getSize().width) > 50) ? 50 : 5,\n                                                    cellRect.y);\n                        }\n                    }\n                }\n            });\n\n        resTable.addMouseListener(new MouseAdapter() {\n                private void showPopupMenu(MouseEvent e) {\n                    int line = resTable.rowAtPoint(e.getPoint());\n\n                    if (popupShowSource != null) popupShowSource.setVisible(false);\n                    if (popupShowReverse != null) popupShowReverse.setVisible(false);\n                    if (line != -1) {\n                        resTable.getSelectionModel().setSelectionInterval(line, line);\n                        methodId = flatProfileContainer.getMethodIdAtRow(line);\n                    }\n                    popupPath = null;\n                    callGraphPopupMenu.show(e.getComponent(), e.getX(), e.getY());\n                }\n                @Override\n                public void mousePressed(MouseEvent e) {\n                    if (e.isPopupTrigger()) showPopupMenu(e);\n                }\n                @Override\n                public void mouseReleased(MouseEvent e) {\n                    if (e.isPopupTrigger()) showPopupMenu(e);\n                }\n\n                @Override\n                public void mouseClicked(MouseEvent e) {\n                    int line = resTable.rowAtPoint(e.getPoint());\n\n                    if (line != -1) {\n                        resTable.getSelectionModel().setSelectionInterval(line, line);\n                        methodId = flatProfileContainer.getMethodIdAtRow(line);\n\n                        if (SwingUtilities.isLeftMouseButton(e) && (e.getClickCount() == 2)) {\n                            showSourceForMethod(methodId);\n                        }\n                    }\n                }\n            });\n        noDataPanel = new JPanel(new BorderLayout());\n        noDataPanel.add(new JLabel(NO_RELEVANT_DATA), BorderLayout.NORTH);\n        noDataPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));\n        noDataPanel.setBackground(resTable.getBackground());\n        jScrollPane.setViewportView(null);\n        //    jScrollPane.setViewportView(resTable);\n        jScrollPane.getViewport().setBackground(resTable.getBackground());\n    }\n    \n    protected Object computeValueAt(int row, int col) {\n        switch (col) {\n            case 0:\n                return flatProfileContainer.getMethodNameAtRow(row);\n            case 1:\n                return new Float(flatProfileContainer.getPercentAtRow(row));\n            case 2:\n                return StringUtils.mcsTimeToString(flatProfileContainer.getTimeInMcs0AtRow(row)) + \" ms (\" // NOI18N\n                        + percentFormat.format(flatProfileContainer.getPercentAtRow(row) / 100) + \")\"; // NOI18N\n            case 3:\n                return collectingTwoTimeStamps\n                        ? (StringUtils.mcsTimeToString(flatProfileContainer.getTimeInMcs1AtRow(row)) + \" ms\" // NOI18N\n                ) : (StringUtils.mcsTimeToString(flatProfileContainer.getTotalTimeInMcs0AtRow(row)) + \" ms\"); // NOI18N\n            case 4:\n                return collectingTwoTimeStamps\n                        ? (StringUtils.mcsTimeToString(flatProfileContainer.getTotalTimeInMcs0AtRow(row)) + \" ms\" // NOI18N\n                ) : intFormat.format(flatProfileContainer.getNInvocationsAtRow(row));\n            case 5:\n                return (StringUtils.mcsTimeToString(flatProfileContainer.getTotalTimeInMcs1AtRow(row)) + \" ms\"); // NOI18N\n            case 6:\n                return intFormat.format(flatProfileContainer.getNInvocationsAtRow(row));\n            default:\n                return null;\n        }\n    }\n\n    private void initFilterPanel() {\n        filterComponent = FilterComponent.create(true, true);\n        filterComponent.setFilter(filterString, filterType);\n\n        filterComponent.addChangeListener(new ChangeListener() {\n                public void stateChanged(ChangeEvent e) {\n                    String selectedRowContents = null;\n\n                    if (resTable != null) {\n                        int selectedRow = resTable.getSelectedRow();\n\n                        if (selectedRow != -1) {\n                            selectedRowContents = (String) resTable.getValueAt(selectedRow, 0);\n                        }\n                    }\n\n                    filterString = filterComponent.getFilterValue();\n                    filterType = filterComponent.getFilterType();\n\n                    if (flatProfileContainer != null) { // can be null after reset, see Issue 65866\n                        flatProfileContainer.filterOriginalData(FilterComponent.getFilterValues(filterString), filterType,\n                                                                valueFilterValue);\n                        flatProfileContainer.sortBy(sortBy, sortOrder);\n                    }\n\n                    if (resTable != null) { // can be null after reset, see Issue 65866\n                        resTable.invalidate();\n                        jScrollPane.revalidate();\n                        resTable.repaint();\n\n                        if (selectedRowContents != null) {\n                            resTable.selectRowByContents(selectedRowContents, 0, true);\n                        }\n                    }\n                }\n            });\n\n        add(filterComponent.getComponent(), BorderLayout.SOUTH);\n    }\n\n    private void initFirstColumnName() {\n        switch (currentView) {\n            case CPUResultsSnapshot.METHOD_LEVEL_VIEW:\n                columnNames[0] = METHOD_COLUMN_NAME;\n                columnToolTips[0] = METHOD_COLUMN_TOOLTIP;\n                filterComponent.setHint(METHOD_FILTER_HINT);\n\n                break;\n            case CPUResultsSnapshot.CLASS_LEVEL_VIEW:\n                columnNames[0] = CLASS_COLUMN_NAME;\n                columnToolTips[0] = CLASS_COLUMN_TOOLTIP;\n                filterComponent.setHint(CLASS_FILTER_HINT);\n\n                break;\n            case CPUResultsSnapshot.PACKAGE_LEVEL_VIEW:\n                columnNames[0] = PACKAGE_COLUMN_NAME;\n                columnToolTips[0] = PACKAGE_COLUMN_TOOLTIP;\n                filterComponent.setHint(PACKAGE_FILTER_HINT);\n\n                break;\n        }\n\n        if (resTable != null) {\n            resTable.getTableHeader().repaint();\n        }\n    }\n    \n    public void setColumnsVisibility(boolean[] columnsVisibility) {\n        resTableModel.setColumnsVisibility(columnsVisibility);\n        resTable.createDefaultColumnsFromModel();\n        resTableModel.setTable(resTable);\n        setColumnsData();\n    }\n    \n    public boolean[] getColumnsVisibility() {\n        return resTableModel.getColumnsVisibility();\n    }\n    \n    public void setFilterVisible(boolean visible) {\n        if (filterComponent != null) filterComponent.getComponent().setVisible(visible);\n    }\n    \n    public boolean isFilterVisible() {\n        return filterComponent != null && filterComponent.getComponent().isVisible();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/LiveCPUView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.awt.event.ActionEvent;\nimport java.util.Collection;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport javax.swing.AbstractAction;\nimport javax.swing.ActionMap;\nimport javax.swing.BorderFactory;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JSeparator;\nimport javax.swing.JSplitPane;\nimport javax.swing.SwingUtilities;\nimport javax.swing.plaf.basic.BasicSplitPaneDivider;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\nimport javax.swing.tree.TreeNode;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedSplitPane;\nimport org.graalvm.visualvm.lib.ui.results.DataView;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class LiveCPUView extends JPanel {\n\n    private CPUResultsSnapshot snapshot;\n    private CPUResultsSnapshot refSnapshot;\n    private boolean sampled;\n    private boolean mergedThreads;\n    private Collection<Integer> selectedThreads;\n    \n    private DataView lastFocused;\n    private CPUTableView hotSpotsView;\n    private CPUTreeTableView forwardCallsView;\n    private CPUTreeTableView reverseCallsView;\n    \n    private ThreadsSelector threadsSelector;\n    \n    private long lastupdate;\n    private volatile boolean refreshIsRunning;\n    \n    private ExecutorService executor;\n    \n    \n    public LiveCPUView(Set<ClientUtils.SourceCodeSelection> selection) {\n        initUI(selection);\n        registerActions();\n    }\n    \n    \n    public void setView(boolean forwardCalls, boolean hotSpots, boolean reverseCalls) {\n        forwardCallsView.setVisible(forwardCalls);\n        hotSpotsView.setVisible(hotSpots);\n        reverseCallsView.setVisible(reverseCalls);\n    }\n    \n    public ThreadsSelector createThreadSelector() {\n        threadsSelector = new ThreadsSelector() {\n            protected CPUResultsSnapshot getSnapshot() { return snapshot; }\n            protected void selectionChanged(Collection<Integer> selected, boolean mergeThreads) {\n                mergedThreads = mergeThreads;\n                selectedThreads = selected;\n                setData();\n            }\n            void reset() {\n                super.reset();\n                mergedThreads = false;\n                selectedThreads = null;\n            }\n        };\n        return threadsSelector;\n    }\n    \n    public boolean isRefreshRunning() {\n        return refreshIsRunning;\n    }\n    \n    public long getLastUpdate() {\n        return lastupdate;\n    }\n\n    public void setData(final CPUResultsSnapshot snapshotData, final boolean sampledData) {\n        if (refreshIsRunning) return;\n        refreshIsRunning = true;\n        \n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                snapshot = snapshotData;\n                sampled = sampledData;\n\n                setData();\n            }\n        });\n    }\n    \n    private void setData() {\n        if (snapshot == null) {\n            resetData();\n            refreshIsRunning = false;\n        } else {\n            getExecutor().submit(new Runnable() {\n                public void run() {\n                    final CPUResultsSnapshot _snapshot = refSnapshot == null ? snapshot :\n                                                         refSnapshot.createDiff(snapshot);\n\n                    final FlatProfileContainer flatData = _snapshot.getFlatProfile(selectedThreads, CPUResultsSnapshot.METHOD_LEVEL_VIEW);\n\n                    final Map<Integer, ClientUtils.SourceCodeSelection> idMap = _snapshot.getMethodIDMap(CPUResultsSnapshot.METHOD_LEVEL_VIEW);\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            try {\n                                boolean diff = _snapshot instanceof CPUResultsDiff;\n                                forwardCallsView.setData(_snapshot, idMap, CPUResultsSnapshot.METHOD_LEVEL_VIEW, selectedThreads, mergedThreads, sampled, diff);\n                                hotSpotsView.setData(flatData, idMap, sampled, diff);\n                                reverseCallsView.setData(_snapshot, idMap, CPUResultsSnapshot.METHOD_LEVEL_VIEW, selectedThreads, mergedThreads, sampled, diff);\n                            } finally {\n                                refreshIsRunning = false;\n                                lastupdate = System.currentTimeMillis();\n                            }\n                        }\n                    });\n                }\n            });\n        }\n    }\n    \n    public boolean setDiffView(final boolean diff) {\n        if (snapshot == null) return false;\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                refSnapshot = diff ? snapshot : null;\n                setData();\n            }\n        });\n        return true;\n    }\n    \n    public void resetData() {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                forwardCallsView.resetData();\n                hotSpotsView.resetData();\n                reverseCallsView.resetData();\n                snapshot = null;\n                refSnapshot = null;\n                sampled = true;\n                if (threadsSelector != null) threadsSelector.reset();\n            }\n        });\n    }\n    \n    \n    public void showSelectionColumn() {\n        forwardCallsView.showSelectionColumn();\n        hotSpotsView.showSelectionColumn();\n        reverseCallsView.showSelectionColumn();\n    }\n    \n    public void refreshSelection() {\n        forwardCallsView.refreshSelection();\n        hotSpotsView.refreshSelection();\n        reverseCallsView.refreshSelection();\n    }\n    \n    \n    protected boolean profileMethodSupported() { return true; }\n    \n    protected boolean profileClassSupported() { return true; }\n    \n    \n    protected abstract boolean showSourceSupported();\n    \n    protected abstract void showSource(ClientUtils.SourceCodeSelection value);\n    \n    protected abstract void selectForProfiling(ClientUtils.SourceCodeSelection value);\n    \n    protected void popupShowing() {}\n\n    protected void popupHidden() {}\n\n\n    protected void foundInForwardCalls() {}\n    \n    protected void foundInHotSpots() {}\n    \n    protected void foundInReverseCalls() {}\n    \n    \n    private void profileMethod(ClientUtils.SourceCodeSelection value) {\n        selectForProfiling(value);\n    }\n    \n    private void profileClass(ClientUtils.SourceCodeSelection value) {\n        selectForProfiling(new ClientUtils.SourceCodeSelection(\n                           value.getClassName(), Wildcards.ALLWILDCARD, null));\n    }\n    \n    \n    private void initUI(Set<ClientUtils.SourceCodeSelection> selection) {\n        setLayout(new BorderLayout(0, 0));\n        \n        forwardCallsView = new CPUTreeTableView(selection, false) {\n            protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                if (showSourceSupported()) showSource(userValue);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                LiveCPUView.this.populatePopup(this, popup, value, userValue);\n            }\n            protected void popupShowing() { LiveCPUView.this.popupShowing(); }\n            protected void popupHidden()  { LiveCPUView.this.popupHidden(); }\n            protected boolean hasBottomFilterFindMargin() { return true; }\n            HideableBarRenderer.BarDiffMode barDiffMode() { return HideableBarRenderer.BarDiffMode.MODE_BAR_NORMAL; }\n        };\n        forwardCallsView.notifyOnFocus(new Runnable() {\n            public void run() { lastFocused = forwardCallsView; }\n        });\n        \n        hotSpotsView = new CPUTableView(selection) {\n            protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                if (showSourceSupported()) showSource(userValue);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                LiveCPUView.this.populatePopup(this, popup, value, userValue);\n            }\n            protected void popupShowing() { LiveCPUView.this.popupShowing(); }\n            protected void popupHidden()  { LiveCPUView.this.popupHidden(); }\n            protected boolean hasBottomFilterFindMargin() { return true; }\n            HideableBarRenderer.BarDiffMode barDiffMode() { return HideableBarRenderer.BarDiffMode.MODE_BAR_NORMAL; }\n        };\n        hotSpotsView.notifyOnFocus(new Runnable() {\n            public void run() { lastFocused = hotSpotsView; }\n        });\n        \n        reverseCallsView = new CPUTreeTableView(selection, true) {\n            protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                if (showSourceSupported()) showSource(userValue);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                LiveCPUView.this.populatePopup(this, popup, value, userValue);\n            }\n            protected void popupShowing() { LiveCPUView.this.popupShowing(); }\n            protected void popupHidden()  { LiveCPUView.this.popupHidden(); }\n            protected boolean hasBottomFilterFindMargin() { return true; }\n        };\n        reverseCallsView.notifyOnFocus(new Runnable() {\n            public void run() { lastFocused = reverseCallsView; }\n        });\n        \n        JSplitPane upperSplit = new JExtendedSplitPane(JSplitPane.VERTICAL_SPLIT) {\n            {\n                setBorder(null);\n                setDividerSize(5);\n\n                if (getUI() instanceof BasicSplitPaneUI) {\n                    BasicSplitPaneDivider divider = ((BasicSplitPaneUI)getUI()).getDivider();\n                    if (divider != null) {\n                        Color c = UIUtils.isNimbus() || UIUtils.isAquaLookAndFeel() ?\n                                  UIUtils.getDisabledLineColor() : new JSeparator().getForeground();\n                        divider.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, c));\n                    }\n                }\n            }\n        };\n        upperSplit.setBorder(BorderFactory.createEmptyBorder());\n        upperSplit.setTopComponent(forwardCallsView);\n        upperSplit.setBottomComponent(hotSpotsView);\n        upperSplit.setDividerLocation(0.5d);\n        upperSplit.setResizeWeight(0.5d);\n        \n        JSplitPane lowerSplit = new JExtendedSplitPane(JSplitPane.VERTICAL_SPLIT) {\n            {\n                setBorder(null);\n                setDividerSize(5);\n\n                if (getUI() instanceof BasicSplitPaneUI) {\n                    BasicSplitPaneDivider divider = ((BasicSplitPaneUI)getUI()).getDivider();\n                    if (divider != null) {\n                        Color c = UIUtils.isNimbus() || UIUtils.isAquaLookAndFeel() ?\n                                  UIUtils.getDisabledLineColor() : new JSeparator().getForeground();\n                        divider.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, c));\n                    }\n                }\n            }\n        };\n        lowerSplit.setBorder(BorderFactory.createEmptyBorder());\n        lowerSplit.setTopComponent(upperSplit);\n        lowerSplit.setBottomComponent(reverseCallsView);\n        lowerSplit.setDividerLocation(0.66d);\n        lowerSplit.setResizeWeight(0.66d);\n        \n        add(lowerSplit, BorderLayout.CENTER);\n        \n//        // TODO: read last state?\n//        setView(true, false);\n    }\n    \n    private void registerActions() {\n        ActionMap map = getActionMap();\n        \n        map.put(FilterUtils.FILTER_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                DataView active = getLastFocused();\n                if (active != null) active.activateFilter();\n            }\n        });\n        \n        map.put(SearchUtils.FIND_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                DataView active = getLastFocused();\n                if (active != null) active.activateSearch();\n            }\n        });\n    }\n    \n    private DataView getLastFocused() {\n        if (lastFocused != null && !lastFocused.isShowing()) lastFocused = null;\n        \n        if (lastFocused == null) {\n            if (forwardCallsView.isShowing()) lastFocused = forwardCallsView;\n            else if (hotSpotsView.isShowing()) lastFocused = hotSpotsView;\n            else if (reverseCallsView.isShowing()) lastFocused = reverseCallsView;\n        }\n        \n        return lastFocused;\n    }\n    \n    private void populatePopup(final DataView invoker, JPopupMenu popup, final Object value, final ClientUtils.SourceCodeSelection userValue) {\n        if (showSourceSupported()) {\n            popup.add(new JMenuItem(CPUView.ACTION_GOTOSOURCE) {\n                { setEnabled(userValue != null); setFont(getFont().deriveFont(Font.BOLD)); }\n                protected void fireActionPerformed(ActionEvent e) { showSource(userValue); }\n            });\n            popup.addSeparator();\n        }\n        \n        if (profileMethodSupported()) popup.add(new JMenuItem(CPUView.ACTION_PROFILE_METHOD) {\n            { setEnabled(userValue != null && CPUTableView.isSelectable(userValue)); }\n            protected void fireActionPerformed(ActionEvent e) { profileMethod(userValue); }\n        });\n        \n        if (profileClassSupported()) popup.add(new JMenuItem(CPUView.ACTION_PROFILE_CLASS) {\n            { setEnabled(userValue != null); }\n            protected void fireActionPerformed(ActionEvent e) { profileClass(userValue); }\n        });\n        \n        if (profileMethodSupported() || profileClassSupported()) popup.addSeparator();\n        \n        JMenuItem[] customItems = invoker.createCustomMenuItems(this, value, userValue);\n        if (customItems != null) {\n            for (JMenuItem customItem : customItems) popup.add(customItem);\n            popup.addSeparator();\n        }\n        \n        customizeNodePopup(invoker, popup, value, userValue);\n        \n        if (invoker == forwardCallsView) {\n            final ProfilerTreeTable ttable = (ProfilerTreeTable)forwardCallsView.getResultsComponent();\n            int column = ttable.convertColumnIndexToView(ttable.getMainColumn());\n            final String searchString = ttable.getStringValue((TreeNode)value, column);\n            \n            popup.add(new JMenuItem(CPUView.FIND_IN_HOTSPOTS) {\n                { setEnabled(userValue != null); }\n                protected void fireActionPerformed(ActionEvent e) {\n                    ProfilerTable table = hotSpotsView.getResultsComponent();\n                    if (SearchUtils.findString(table, searchString)) {\n                        hotSpotsView.setVisible(true);\n                        foundInHotSpots();\n                        table.requestFocusInWindow();\n                    }\n                }\n            });\n            \n            popup.add(new JMenuItem(CPUView.FIND_IN_REVERSECALLS) {\n                { setEnabled(userValue != null); }\n                protected void fireActionPerformed(ActionEvent e) {\n                    ProfilerTreeTable table = (ProfilerTreeTable)reverseCallsView.getResultsComponent();\n                    if (SearchUtils.findString(table, searchString, true, true, createSearchHelper())) {\n                        reverseCallsView.setVisible(true);\n                        foundInReverseCalls();\n                        table.requestFocusInWindow();\n                    }\n                }\n            });\n            \n            popup.addSeparator();\n            \n            JMenu threads = new JMenu(CPUView.SHOW_MENU);\n            popup.add(threads);\n            \n            threads.add(new JMenuItem(CPUView.SHOW_THREAD_ITEM) {\n                {\n                    setEnabled(!mergedThreads && threadsSelector != null && value instanceof PrestimeCPUCCTNode &&\n                               snapshot.getNThreads() > 1 && (selectedThreads == null || selectedThreads.size() > 1));\n                }\n                protected void fireActionPerformed(ActionEvent e) {\n                    PrestimeCPUCCTNode thread = (PrestimeCPUCCTNode)value;\n                    threadsSelector.addThread(thread.getThreadId(), true);\n                }\n            });\n            \n            threads.add(new JMenuItem(CPUView.HIDE_THREAD_ITEM) {\n                {\n                    setEnabled(!mergedThreads && threadsSelector != null && value instanceof PrestimeCPUCCTNode &&\n                               snapshot.getNThreads() > 1 && (selectedThreads == null || selectedThreads.size() > 1));\n                }\n                protected void fireActionPerformed(ActionEvent e) {\n                    PrestimeCPUCCTNode thread = (PrestimeCPUCCTNode)value;\n                    threadsSelector.removeThread(thread.getThreadId());\n                }\n            });\n            \n            JMenu expand = new JMenu(CPUView.EXPAND_MENU);\n            popup.add(expand);\n            \n            expand.add(new JMenuItem(CPUView.EXPAND_PLAIN_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.expandPlainPath(ttable.getSelectedRow(), 2);\n                }\n            });\n            \n            expand.add(new JMenuItem(CPUView.EXPAND_TOPMOST_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.expandFirstPath(ttable.getSelectedRow());\n                }\n            });\n            \n            expand.addSeparator();\n            \n            expand.add(new JMenuItem(CPUView.COLLAPSE_CHILDREN_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.collapseChildren(ttable.getSelectedRow());\n                }\n            });\n            \n            expand.add(new JMenuItem(CPUView.COLLAPSE_ALL_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.collapseAll();\n                }\n            });\n        } else if (invoker == hotSpotsView) {\n            // Ugly hack - there's a space between method name and parameters\n            final String searchString = value.toString().replace(\"(\", \" (\"); // NOI18N\n            \n            popup.add(new JMenuItem(CPUView.FIND_IN_FORWARDCALLS) {\n                { setEnabled(userValue != null); }\n                protected void fireActionPerformed(ActionEvent e) {\n                    ProfilerTable table = forwardCallsView.getResultsComponent();\n                    if (SearchUtils.findString(table, searchString)) {\n                        forwardCallsView.setVisible(true);\n                        foundInForwardCalls();\n                        table.requestFocusInWindow();\n                    }\n                }\n            });\n            \n            popup.add(new JMenuItem(CPUView.FIND_IN_REVERSECALLS) {\n                { setEnabled(userValue != null); }\n                protected void fireActionPerformed(ActionEvent e) {\n                    ProfilerTreeTable table = (ProfilerTreeTable)reverseCallsView.getResultsComponent();\n                    if (SearchUtils.findString(table, searchString, true, true, createSearchHelper())) {\n                        reverseCallsView.setVisible(true);\n                        foundInReverseCalls();\n                        table.requestFocusInWindow();\n                    }\n                }\n            });\n        } else if (invoker == reverseCallsView) {\n            final ProfilerTreeTable ttable = (ProfilerTreeTable)reverseCallsView.getResultsComponent();\n            int column = ttable.convertColumnIndexToView(ttable.getMainColumn());\n            final String searchString = ttable.getStringValue((TreeNode)value, column);\n            \n            popup.add(new JMenuItem(CPUView.FIND_IN_FORWARDCALLS) {\n                { setEnabled(userValue != null); }\n                protected void fireActionPerformed(ActionEvent e) {\n                    ProfilerTable table = forwardCallsView.getResultsComponent();\n                    if (SearchUtils.findString(table, searchString)) {\n                        forwardCallsView.setVisible(true);\n                        foundInForwardCalls();\n                        table.requestFocusInWindow();\n                    }\n                }\n            });\n            \n            popup.add(new JMenuItem(CPUView.FIND_IN_HOTSPOTS) {\n                { setEnabled(userValue != null); }\n                protected void fireActionPerformed(ActionEvent e) {\n                    ProfilerTable table = hotSpotsView.getResultsComponent();\n                    if (SearchUtils.findString(table, searchString)) {\n                        hotSpotsView.setVisible(true);\n                        foundInHotSpots();\n                        table.requestFocusInWindow();\n                    }\n                }\n            });\n            \n            popup.addSeparator();\n            \n            JMenu threads = new JMenu(CPUView.SHOW_MENU);\n            popup.add(threads);\n            \n            threads.add(new JMenuItem(CPUView.SHOW_THREAD_ITEM) {\n                {\n                    setEnabled(!mergedThreads && threadsSelector != null && value instanceof PrestimeCPUCCTNode &&\n                               snapshot.getNThreads() > 1 && (selectedThreads == null || selectedThreads.size() > 1));\n                }\n                protected void fireActionPerformed(ActionEvent e) {\n                    PrestimeCPUCCTNode thread = (PrestimeCPUCCTNode)value;\n                    threadsSelector.addThread(thread.getThreadId(), true);\n                }\n            });\n            \n            threads.add(new JMenuItem(CPUView.HIDE_THREAD_ITEM) {\n                {\n                    setEnabled(!mergedThreads && threadsSelector != null && value instanceof PrestimeCPUCCTNode &&\n                               snapshot.getNThreads() > 1 && (selectedThreads == null || selectedThreads.size() > 1));\n                }\n                protected void fireActionPerformed(ActionEvent e) {\n                    PrestimeCPUCCTNode thread = (PrestimeCPUCCTNode)value;\n                    threadsSelector.removeThread(thread.getThreadId());\n                }\n            });\n            \n            JMenu expand = new JMenu(CPUView.EXPAND_MENU);\n            popup.add(expand);\n            \n            expand.add(new JMenuItem(CPUView.EXPAND_PLAIN_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.expandPlainPath(ttable.getSelectedRow(), 1);\n                }\n            });\n            \n            expand.add(new JMenuItem(CPUView.EXPAND_TOPMOST_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.expandFirstPath(ttable.getSelectedRow());\n                }\n            });\n            \n            expand.addSeparator();\n            \n            expand.add(new JMenuItem(CPUView.COLLAPSE_CHILDREN_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.collapseChildren(ttable.getSelectedRow());\n                }\n            });\n            \n            expand.add(new JMenuItem(CPUView.COLLAPSE_ALL_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.collapseAll();\n                }\n            });\n        }\n        \n        popup.addSeparator();\n        popup.add(invoker.createCopyMenuItem());\n        \n        popup.addSeparator();\n        popup.add(new JMenuItem(FilterUtils.ACTION_FILTER) {\n            protected void fireActionPerformed(ActionEvent e) { invoker.activateFilter(); }\n        });\n        popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {\n            protected void fireActionPerformed(ActionEvent e) { invoker.activateSearch(); }\n        });\n    }\n    \n    private static SearchUtils.TreeHelper createSearchHelper() {\n        return new SearchUtils.TreeHelper() {\n            public int getNodeType(TreeNode tnode) {\n                PrestimeCPUCCTNode node = (PrestimeCPUCCTNode)tnode;\n                CCTNode parent = node.getParent();\n                if (parent == null) return SearchUtils.TreeHelper.NODE_SKIP_DOWN; // invisible root\n                \n                if (node.isThreadNode()) return SearchUtils.TreeHelper.NODE_SKIP_DOWN; // thread node\n                if (node.isSelfTimeNode()) return SearchUtils.TreeHelper.NODE_SKIP_NEXT; // self time node\n                \n                if (((PrestimeCPUCCTNode)parent).isThreadNode() || // toplevel method node (children of thread)\n                    parent.getParent() == null) {                  // toplevel method node (merged threads)\n                    return SearchUtils.TreeHelper.NODE_SEARCH_NEXT;\n                }\n                \n                return SearchUtils.TreeHelper.NODE_SKIP_NEXT; // reverse call tree node\n            }\n        };\n    }\n    \n    protected void customizeNodePopup(DataView invoker, JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {}\n    \n    \n    private synchronized ExecutorService getExecutor() {\n        if (executor == null) executor = Executors.newSingleThreadExecutor();\n        return executor;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/LiveCPUViewUpdater.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.openide.util.Lookup;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class LiveCPUViewUpdater {\n\n    private static final int MIN_UPDATE_DIFF = 900;\n    private static final int MAX_UPDATE_DIFF = 1400;\n\n\n    private CCTHandler handler;\n\n    private final LiveCPUView cpuView;\n    private final ProfilerClient client;\n\n    private volatile boolean paused;\n    private volatile boolean forceRefresh;\n\n\n\n    public LiveCPUViewUpdater(LiveCPUView cpuView, ProfilerClient client) {\n        this.cpuView = cpuView;\n        this.client = client;\n\n        handler = CCTHandler.registerUpdater(this);\n    }\n\n\n\n    public void setPaused(boolean paused) {\n        this.paused = paused;\n    }\n\n    public void setForceRefresh(boolean forceRefresh) {\n        this.forceRefresh = forceRefresh;\n    }\n\n    public void update() throws ClientUtils.TargetAppOrVMTerminated {\n        if (forceRefresh || (!paused && cpuView.getLastUpdate() + MAX_UPDATE_DIFF < System.currentTimeMillis()))\n            client.forceObtainedResultsDump(true);\n    }\n\n    public void cleanup() {\n        handler.unregisterUpdater(this);\n        handler = null;\n    }\n\n\n    private void updateData() throws ClientUtils.TargetAppOrVMTerminated, CPUResultsSnapshot.NoDataAvailableException {\n        if (!forceRefresh && (paused || cpuView.getLastUpdate() + MIN_UPDATE_DIFF > System.currentTimeMillis())) return;\n        \n        boolean sampling = client.getCurrentInstrType() == ProfilerClient.INSTR_NONE_SAMPLING;\n        CPUResultsSnapshot data = client.getStatus().getInstrMethodClasses() == null ?\n                           null : client.getCPUProfilingResultsSnapshot(false);\n        cpuView.setData(data, sampling);\n        \n        forceRefresh = false;\n    }\n    \n    private void resetData() {\n        cpuView.resetData();\n    }\n    \n    \n    @ServiceProvider(service=CPUCCTProvider.Listener.class)\n    public static class CCTHandler implements CPUCCTProvider.Listener {\n        \n        private final List<LiveCPUViewUpdater> updaters = new ArrayList<>();\n        \n        \n        public static CCTHandler registerUpdater(LiveCPUViewUpdater updater) {\n            CCTHandler handler = Lookup.getDefault().lookup(CCTHandler.class);\n            handler.updaters.add(updater);\n            return handler;\n        }\n        \n        public void unregisterUpdater(LiveCPUViewUpdater updater) {\n            updaters.remove(updater);\n        }\n        \n\n        public final void cctEstablished(RuntimeCCTNode appRootNode, boolean empty) {\n            if (!empty) {\n                for (LiveCPUViewUpdater updater : updaters) try {\n                    updater.updateData();\n                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                } catch (CPUResultsSnapshot.NoDataAvailableException ex) {\n                    Logger.getLogger(LiveCPUView.class.getName()).log(Level.FINE, null, ex);\n                }\n            }\n        }\n\n        public final void cctReset() {\n            for (LiveCPUViewUpdater updater : updaters) updater.resetData();\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/LiveFlatProfileCollectorPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.Dimension;\nimport java.awt.image.BufferedImage;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.PopupMenuEvent;\nimport javax.swing.event.PopupMenuListener;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileProvider;\nimport org.graalvm.visualvm.lib.ui.LiveResultsPanel;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.FilterComponent;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class LiveFlatProfileCollectorPanel extends FlatProfilePanel implements LiveResultsPanel {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JPopupMenu popup;\n    private TargetAppRunner runner = null;\n    private boolean firstTime = true;\n    private boolean updateResultsInProgress = false;\n    private boolean updateResultsPending = false;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public LiveFlatProfileCollectorPanel(TargetAppRunner runner, CPUResUserActionsHandler actionsHandler,\n                                         CPUSelectionHandler selectionHandler, boolean sampling) {\n        super(actionsHandler, selectionHandler, sampling);\n        //    setCPUSelectionHandler(selectionHandler);\n        this.runner = runner;\n\n        addFilterListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                if (flatProfileContainer != null) {\n                    setDataToDisplay(flatProfileContainer);\n                }\n            }\n        });\n\n        initComponents();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * This method is supposed to be used for displaying data in live update mode. The data is initialized using a\n     * \"lightweight\" flat profile container, not backed by the snapshot, that does not allow any operations listed\n     * above, i.e. switching views, obtaining reverse call graph, and going to method's source.\n     */\n    public void setDataToDisplay(final FlatProfileContainer fpc) {\n        threadId = -1;\n        flatProfileContainer = fpc;\n        collectingTwoTimeStamps = flatProfileContainer.isCollectingTwoTimeStamps();\n\n        flatProfileContainer.filterOriginalData(FilterComponent.getFilterValues(filterString), filterType, valueFilterValue);\n\n        prepareResults(firstTime);\n        firstTime = false;\n\n        setResultsAvailable(hasData());\n\n        //    flatProfileContainer.sortBy(sortBy, sortOrder);   // This will actually create the below-used percent() thing for proper timer\n    }\n\n    public BufferedImage getViewImage(boolean onlyVisibleArea) {\n        if (onlyVisibleArea) {\n            return UIUtils.createScreenshot(jScrollPane);\n        }\n\n        return UIUtils.createScreenshot(resTable);\n    }\n\n    public String getViewName() {\n        return \"cpu-live\"; // NOI18N\n    }\n\n    public boolean fitsVisibleArea() {\n        return !jScrollPane.getVerticalScrollBar().isEnabled();\n    }\n\n    public void handleRemove() {\n    }\n\n    /**\n     * Called when auto refresh is on and profiling session will finish\n     * to give the panel chance to do some cleanup before asynchronous\n     * call to updateLiveResults() will happen.\n     *\n     * Currently, it closes the context menu if open, which would otherwise\n     * block updating the results.\n     */\n    public void handleShutdown() {\n        // Profiling session will finish and context menu is opened, this would block last live results update -> menu will be closed\n        if ((popup != null) && popup.isVisible()) {\n            updateResultsPending = false; // clear the flag, updateLiveResults() will be called explicitly from outside\n            popup.setVisible(false); // close the context menu\n        }\n    }\n\n    public boolean hasData() {\n        return (flatProfileContainer != null) && (flatProfileContainer.getNRows() > 0);\n    }\n\n    public boolean hasView() {\n        return resTable != null;\n    }\n\n    @Override\n    public void prepareResults() {\n        super.prepareResults();\n    }\n\n    public boolean supports(int instrumentationType) {\n        return (instrumentationType == CommonConstants.INSTR_RECURSIVE_FULL)\n               || (instrumentationType == CommonConstants.INSTR_RECURSIVE_SAMPLED)\n               || (instrumentationType == CommonConstants.INSTR_NONE_SAMPLING);\n    }\n\n    public void updateLiveResults() {\n        if ((popup != null) && popup.isVisible()) {\n            updateResultsPending = true;\n\n            return;\n        }\n\n        if (updateResultsInProgress) {\n            return;\n        }\n\n        updateResultsInProgress = true;\n\n        String selectedRowString = null;\n\n        if (resTable != null) {\n            int selectedRowIndex = resTable.getSelectedRow();\n\n            if (selectedRowIndex >= resTable.getRowCount()) {\n                selectedRowIndex = -1;\n                resTable.clearSelection();\n            }\n\n            if (selectedRowIndex != -1) {\n                selectedRowString = resTable.getValueAt(selectedRowIndex, 0).toString();\n            }\n        }\n        FlatProfileProvider flatProvider = getFlatProfileProvider();\n\n        if (flatProvider != null) {\n            FlatProfileContainer fpc = flatProvider.createFlatProfile();\n            int retryCounter = 2;\n            boolean doRetry = false;\n\n            do {\n                doRetry = false;\n\n                if (fpc != null) {\n                    setDataToDisplay(fpc);\n\n                    if (selectedRowString != null) {\n                        resTable.selectRowByContents(selectedRowString, 0, false);\n                    }\n                } else {\n                    doRetry = true;\n                }\n\n                if (doRetry) {\n                    try {\n                        Thread.sleep(200);\n                    } catch (InterruptedException e) {\n                        doRetry = false;\n                    }\n                }\n            } while ((--retryCounter > 0) && doRetry);\n        }\n\n        updateResultsInProgress = false;\n    }\n\n    public FlatProfileProvider getFlatProfileProvider() {\n        return runner.getProfilerClient().getFlatProfileProvider();\n    }\n\n    protected String[] getMethodClassNameAndSig(int methodId, int currentView) {\n        ProfilingSessionStatus status = runner.getProfilingSessionStatus();\n        String className = status.getInstrMethodClasses()[methodId];\n\n        if (currentView == CPUResultsSnapshot.METHOD_LEVEL_VIEW) {\n            String methodName = (status.getInstrMethodNames() != null) ? status.getInstrMethodNames()[methodId] : null;\n            String methodSig = (status.getInstrMethodSignatures() != null) ? status.getInstrMethodSignatures()[methodId] : null;\n\n            return new String[] { className, methodName, methodSig };\n        }\n\n        return new String[] { className, null, null };\n    }\n\n    @Override\n    protected JPopupMenu createPopupMenu() {\n        if (popup == null) {\n            popup = super.createPopupMenu();\n        }\n\n        popup.addPopupMenuListener(new PopupMenuListener() {\n                public void popupMenuCanceled(PopupMenuEvent e) {\n                }\n\n                public void popupMenuWillBecomeVisible(PopupMenuEvent e) {\n                }\n\n                public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                if (updateResultsPending) {\n                                    updateLiveResults();\n                                    updateResultsPending = false;\n                                }\n                            }\n                        });\n                }\n            });\n\n        return popup;\n    }\n\n    protected void obtainResults() {\n        // If a now-inapplicable setting remained from previous run, reset it\n        if ((!collectingTwoTimeStamps && (sortBy == FlatProfileContainer.SORT_BY_SECONDARY_TIME))) {\n            sortBy = FlatProfileContainer.SORT_BY_TIME;\n        }\n\n        // Reinit bar max value here - operations necessary for correct bar representation of results\n        flatProfileContainer.filterOriginalData(FilterComponent.getFilterValues(filterString), filterType, valueFilterValue);\n        flatProfileContainer.sortBy(sortBy, sortOrder); // This will actually create the below-used percent() thing for proper timer\n    }\n\n    /**\n     * Default implementation throwing IllegalStateException, needs to be overridden by classes that do support showReverseCallGraph\n     */\n    @Override\n    protected void showReverseCallGraph(int threadId, int methodId, int currentView, int sortingColumn, boolean sortingOrder) {\n        throw new IllegalStateException();\n    }\n\n    protected boolean supportsReverseCallGraph() {\n        return false;\n    }\n\n    protected boolean supportsSubtreeCallGraph() {\n        return false;\n    }\n\n    void setSelectedRowString(String rowString) {\n        if (rowString != null) {\n            resTable.selectRowByContents(rowString, 0, false);\n        }\n    }\n\n    String getSelectedRowString() {\n        String selectedRowString = null;\n\n        if (resTable != null) {\n            int selectedRowIndex = resTable.getSelectedRow();\n\n            if (selectedRowIndex >= resTable.getRowCount()) {\n                selectedRowIndex = -1;\n                resTable.clearSelection();\n            }\n\n            if (selectedRowIndex != -1) {\n                selectedRowString = resTable.getValueAt(selectedRowIndex, 0).toString();\n            }\n        }\n\n        return selectedRowString;\n    }\n\n    private void initComponents() {\n        this.setPreferredSize(new Dimension(800, 600));\n    }\n\n    public void exportData(int exportedFileType, ExportDataDumper eDD, String viewName) {\n        percentFormat.setMaximumFractionDigits(2);\n        percentFormat.setMinimumFractionDigits(2);\n        switch (exportedFileType) {\n            case 1: exportCSV(\",\", eDD); break; //NOI18N\n            case 2: exportCSV(\";\", eDD); break; //NOI18N\n            case 3: exportXML(eDD, viewName); break;\n            case 4: exportHTML(eDD, viewName); break;\n        }\n        percentFormat.setMaximumFractionDigits(1);\n        percentFormat.setMinimumFractionDigits(0);\n    }\n\n    private void exportHTML(ExportDataDumper eDD, String viewName) {\n         // Header\n        StringBuffer result = new StringBuffer(\"<HTML><HEAD><meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" /><TITLE>\"+viewName+\"</TITLE></HEAD><BODY><TABLE border=\\\"1\\\"><tr>\"); // NOI18N\n        for (int i = 0; i < ( columnCount); i++) {\n            result.append(\"<th>\").append(columnNames[i]).append(columnNames[i].equals(\"Total Time\")?\" [&micro;s]\":\"\").append(\"</th>\"); //NOI18N\n        }\n        result.append(\"</tr>\"); //NOI18N\n\n\n        eDD.dumpData(result);\n        for (int i=0; i < flatProfileContainer.getNRows(); i++) {\n            result = new StringBuffer(\"<tr><td>\"+replaceHTMLCharacters(flatProfileContainer.getMethodNameAtRow(i))+\"</td>\"); //NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(percentFormat.format(flatProfileContainer.getPercentAtRow(i)/100)).append((flatProfileContainer.getTimeInMcs0AtRow(i)%10==0)?((flatProfileContainer.getTimeInMcs0AtRow(i)%100==0)?((flatProfileContainer.getTimeInMcs0AtRow(i)%1000==0)?(\"    \"):(\"  \")):(\" \")):(\"\")).append(\"</td>\"); //NOI18N\n            result.append(\"<td align=right>\").append((double) flatProfileContainer.getTimeInMcs0AtRow(i)/1000).append(\" ms</td>\"); //NOI18N\n            if (collectingTwoTimeStamps) {\n                result.append(\"<td align=right>\").append((double) flatProfileContainer.getTimeInMcs1AtRow(i)/1000).append(\" ms</td>\"); //NOI18N\n            }\n            result.append(\"<td align=right>\").append((double) flatProfileContainer.getTotalTimeInMcs0AtRow(i)/1000).append(\" ms</td>\"); //NOI18N\n            if (collectingTwoTimeStamps) {\n                result.append(\"<td align=right>\").append((double) flatProfileContainer.getTotalTimeInMcs1AtRow(i)/1000).append(\" ms</td>\"); //NOI18N\n            }\n            result.append(\"<td align=\\\"right\\\">\").append(flatProfileContainer.getNInvocationsAtRow(i)).append(\"</td></tr>\"); //NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TABLE></BODY></HTML>\")); //NOI18N\n    }\n\n    private void exportXML(ExportDataDumper eDD, String viewName) {\n         // Header\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"+newline+\"<ExportedView Name=\\\"\"+viewName+\"\\\" type=\\\"table\\\">\"+newline+\" <TableData NumRows=\\\"\"+flatProfileContainer.getNRows()+\"\\\" NumColumns=\\\"4\\\">\"+newline+\"  <TableHeader>\"); // NOI18N\n        for (int i = 0; i < ( columnCount); i++) {\n            result.append(\"   <TableColumn><![CDATA[\").append(columnNames[i]).append(\"]]></TableColumn>\").append(newline); //NOI18N\n        }\n        result.append(\"  </TableHeader>\").append(newline).append(\"  <TableBody>\").append(newline); //NOI18N\n        eDD.dumpData(result);\n\n        for (int i=0; i < flatProfileContainer.getNRows(); i++) {\n            result = new StringBuffer(\"   <TableRow>\"+newline+\"    <TableColumn><![CDATA[\"+flatProfileContainer.getMethodNameAtRow(i)+\"]]></TableColumn>\"+newline); //NOI18N\n            result.append(\"    <TableColumn><![CDATA[\").append(percentFormat.format(flatProfileContainer.getPercentAtRow(i)/100)).append(\"]]></TableColumn>\").append(newline); //NOI18N\n            result.append(\"    <TableColumn><![CDATA[\").append(((double) flatProfileContainer.getTimeInMcs0AtRow(i))/1000).append(\" ms]]></TableColumn>\").append(newline); //NOI18N\n            if (collectingTwoTimeStamps) {\n                result.append(\"    <TableColumn><![CDATA[\").append(((double) flatProfileContainer.getTimeInMcs1AtRow(i))/1000).append(\" ms]]></TableColumn>\").append(newline); //NOI18N\n            }\n            result.append(\"    <TableColumn><![CDATA[\").append(((double) flatProfileContainer.getTotalTimeInMcs0AtRow(i))/1000).append(\" ms]]></TableColumn>\").append(newline); //NOI18N\n            if (collectingTwoTimeStamps) {\n                result.append(\"    <TableColumn><![CDATA[\").append(((double) flatProfileContainer.getTotalTimeInMcs1AtRow(i))/1000).append(\" ms]]></TableColumn>\").append(newline); //NOI18N\n            }\n            result.append(\"    <TableColumn><![CDATA[\").append(flatProfileContainer.getNInvocationsAtRow(i)).append(\"]]></TableColumn>\").append(newline).append(\"  </TableRow>\").append(newline); //NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\"  </TableBody>\"+\" </TableData>\"+newline+\"</ExportedView>\")); //NOI18N\n    }\n\n    private void exportCSV(String separator, ExportDataDumper eDD) {\n        // Header\n        StringBuffer result = new StringBuffer();\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n\n        for (int i = 0; i < (columnCount); i++) {\n            result.append(quote).append(columnNames[i]).append(quote).append(separator);\n        }\n        result.deleteCharAt(result.length()-1);\n        result.append(newLine);\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < flatProfileContainer.getNRows(); i++) {\n            result = new StringBuffer();\n            result.append(quote).append(flatProfileContainer.getMethodNameAtRow(i)).append(quote).append(separator);\n            result.append(quote).append(flatProfileContainer.getPercentAtRow(i)).append(quote).append(separator);\n            result.append(quote).append((double)flatProfileContainer.getTimeInMcs0AtRow(i)/1000).append(\" ms\").append(quote).append(separator);\n            if (collectingTwoTimeStamps) {\n                result.append(quote).append((double)flatProfileContainer.getTimeInMcs1AtRow(i)/1000).append(\" ms\").append(quote).append(separator);\n            }\n            result.append(quote).append((double)flatProfileContainer.getTotalTimeInMcs0AtRow(i)/1000).append(\" ms\").append(quote).append(separator);\n            if (collectingTwoTimeStamps) {\n                result.append(quote).append((double)flatProfileContainer.getTotalTimeInMcs1AtRow(i)/1000).append(\" ms\").append(quote).append(separator);\n            }\n            result.append(quote).append(flatProfileContainer.getNInvocationsAtRow(i)).append(quote).append(newLine);\n            eDD.dumpData(result);\n        }\n        eDD.close();\n    }\n\n    private String replaceHTMLCharacters(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break; //NOI18N\n              case '>': sb.append(\"&gt;\"); break; //NOI18N\n              case '&': sb.append(\"&amp;\"); break; //NOI18N\n              case '\"': sb.append(\"&quot;\"); break; //NOI18N\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/LiveFlatProfilePanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.BorderLayout;\nimport java.awt.CardLayout;\nimport java.awt.image.BufferedImage;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.ResourceBundle;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.ui.LiveResultsPanel;\nimport org.graalvm.visualvm.lib.ui.cpu.statistics.StatisticalModule;\n\n\n/**\n * A display containing a flat profile (always appears together with CCT)\n *\n * @author Ian Formanek\n */\n\n//public class LiveFlatProfilePanel extends FlatProfilePanel implements LiveResultsPanel {\npublic class LiveFlatProfilePanel extends JPanel implements LiveResultsPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.cpu.Bundle\"); // NOI18N\n    private static final String NO_RESULTS_STRING = messages.getString(\"LiveFlatProfilePanel_NoResultsString\"); // NOI18N\n                                                                                                                // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private CPUResUserActionsHandler actionsHandler = null;\n    private Collection<StatisticalModule> statModules = null;\n    private CPUSelectionHandler handler = new CPUSelectionHandler() {\n        public void methodSelected(int threadId, int methodId, int view) {\n            for (StatisticalModule statModule : statModules) {\n                statModule.setSelectedMethodId(methodId);\n            }\n        }\n    };\n\n    private JPanel noResultsPanel = null;\n    private JPanel resultsTable = null;\n    private LiveFlatProfileCollectorPanel fpCollectorPanel = null;\n    private TargetAppRunner runner;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    //  public LiveFlatProfilePanel(TargetAppRunner runner, CPUResUserActionsHandler actionsHandler, DrillDownContext context, List additionalStats) {\n    public LiveFlatProfilePanel(TargetAppRunner runner, CPUResUserActionsHandler actionsHandler, Collection<StatisticalModule> additionalStats, boolean sampling) {\n        this.actionsHandler = actionsHandler;\n        this.runner = runner;\n\n        statModules = additionalStats;\n\n        //    drilldownContext = context;\n        //    drilldownContext.update(); // get the latest context state\n        initComponents();\n\n        setupFlatCollector(sampling);\n    }\n    \n    public LiveFlatProfilePanel(TargetAppRunner runner, CPUResUserActionsHandler actionsHandler, boolean sampling) {\n        this(runner, actionsHandler, Collections.emptyList(), sampling);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setAdditionalStats(Collection<StatisticalModule> stats) {\n        statModules = stats;\n    }\n    \n    public int getSortingColumn() {\n        return fpCollectorPanel.getSortingColumn();\n    }\n\n    public boolean getSortingOrder() {\n        return fpCollectorPanel.getSortingOrder();\n    }\n\n    public BufferedImage getViewImage(boolean onlyVisibleArea) {\n        return fpCollectorPanel.getViewImage(onlyVisibleArea);\n    }\n\n    public String getViewName() {\n        return fpCollectorPanel.getViewName();\n    }\n\n    public boolean fitsVisibleArea() {\n        return fpCollectorPanel.fitsVisibleArea();\n    }\n\n    public void handleRemove() {\n        fpCollectorPanel.handleRemove();\n    }\n\n    /**\n     * Called when auto refresh is on and profiling session will finish\n     * to give the panel chance to do some cleanup before asynchrounous\n     * call to updateLiveResults() will happen.\n     *\n     * Currently it closes the context menu if open, which would otherwise\n     * block updating the results.\n     */\n    public void handleShutdown() {\n        handleRemove();\n        fpCollectorPanel.handleShutdown();\n    }\n\n    public boolean hasValidDrillDown() {\n        return false;\n    }\n\n    // --- Save current View action support --------------------------------------\n    public boolean hasView() {\n        return fpCollectorPanel.hasView();\n    }\n\n    public void reset() {\n        fpCollectorPanel.reset();\n    }\n\n    public boolean supports(int instrumentationType) {\n        return fpCollectorPanel.supports(instrumentationType);\n    }\n\n    public void updateLiveResults() {\n        fpCollectorPanel.updateLiveResults();\n    }\n\n    public void exportData(int exportedFileType, ExportDataDumper eDD, String viewName) {\n        fpCollectorPanel.exportData(exportedFileType, eDD, viewName);\n    }\n\n    private void initComponents() {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n\n        noResultsPanel = new JPanel();\n        noResultsPanel.setLayout(new BorderLayout());\n        noResultsPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));\n\n        final JLabel noResultsLabel = new JLabel(NO_RESULTS_STRING);\n\n        noResultsLabel.setFont(noResultsLabel.getFont().deriveFont(14));\n        noResultsLabel.setEnabled(false);\n        noResultsPanel.add(noResultsLabel, BorderLayout.NORTH);\n\n        resultsTable = new JPanel(new CardLayout());\n        resultsTable.add(noResultsLabel, \"NORESULTS\"); // NOI18N\n\n        add(resultsTable, BorderLayout.CENTER);\n    }\n\n    private void setupFlatCollector(boolean sampling) {\n        fpCollectorPanel = new LiveFlatProfileCollectorPanel(runner, actionsHandler, handler, sampling);\n        resultsTable.add(fpCollectorPanel, \"RESULTS\"); // NOI18N\n                                                       //    ((CardLayout)resultsTable.getLayout()).show(resultsTable, \"NORESULTS\");\n\n        ((CardLayout) resultsTable.getLayout()).show(resultsTable, \"RESULTS\"); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/ReverseCallGraphPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.awt.image.BufferedImage;\nimport java.text.MessageFormat;\nimport java.util.HashSet;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.jfluid.results.FilterSortSupport;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNodeFree;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.FilterComponent;\nimport org.graalvm.visualvm.lib.ui.components.JTreeTable;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelBracketTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.SortableTableModel;\nimport org.graalvm.visualvm.lib.ui.components.tree.EnhancedTreeCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.tree.MethodNameTreeCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.treetable.AbstractTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.ExtendedTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.JTreeTablePanel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.TreeTableModel;\n\n\n/**\n * A display containing reverse call graph\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic class ReverseCallGraphPanel extends SnapshotCPUResultsPanel implements ScreenshotProvider {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.cpu.Bundle\"); // NOI18N\n    private static final String PANEL_TITLE = messages.getString(\"ReverseCallGraphPanel_PanelTitle\"); // NOI18N\n    private static final String PANEL_TITLE_SHORT = messages.getString(\"ReverseCallGraphPanel_PanelTitleShort\"); // NOI18N\n    private static final String GO_TO_SOURCE_POPUP_ITEM = messages.getString(\"ReverseCallGraphPanel_GoToSourcePopupItem\"); // NOI18N\n    private static final String ADD_ROOT_METHOD_POPUP_ITEM = messages.getString(\"ReverseCallGraphPanel_AddRootMethodPopupItem\"); // NOI18N\n    private static final String METHOD_COLUMN_NAME = messages.getString(\"ReverseCallGraphPanel_MethodColumnName\"); // NOI18N\n    private static final String METHOD_COLUMN_TOOLTIP = messages.getString(\"ReverseCallGraphPanel_MethodColumnToolTip\"); // NOI18N\n    private static final String METHOD_FILTER_HINT = messages.getString(\"FlatProfilePanel_MethodFilterHint\"); // NOI18N\n    private static final String CLASS_COLUMN_NAME = messages.getString(\"ReverseCallGraphPanel_ClassColumnName\"); // NOI18N\n    private static final String CLASS_COLUMN_TOOLTIP = messages.getString(\"ReverseCallGraphPanel_ClassColumnToolTip\"); // NOI18N\n    private static final String CLASS_FILTER_HINT = messages.getString(\"FlatProfilePanel_ClassFilterHint\"); // NOI18N\n    private static final String PACKAGE_COLUMN_NAME = messages.getString(\"ReverseCallGraphPanel_PackageColumnName\"); // NOI18N\n    private static final String PACKAGE_COLUMN_TOOLTIP = messages.getString(\"ReverseCallGraphPanel_PackageColumnToolTip\"); // NOI18N\n    private static final String PACKAGE_FILTER_HINT = messages.getString(\"FlatProfilePanel_PackageFilterHint\"); // NOI18N\n    private static final String TIME_REL_COLUMN_NAME = messages.getString(\"ReverseCallGraphPanel_TimeRelColumnName\"); // NOI18N\n    private static final String TIME_REL_COLUMN_TOOLTIP = messages.getString(\"ReverseCallGraphPanel_TimeRelColumnToolTip\"); // NOI18N\n    private static final String TIME_COLUMN_NAME = messages.getString(\"ReverseCallGraphPanel_TimeColumnName\"); // NOI18N\n    private static final String TIME_COLUMN_TOOLTIP = messages.getString(\"ReverseCallGraphPanel_TimeColumnToolTip\"); // NOI18N\n    private static final String TIME_CPU_COLUMN_NAME = messages.getString(\"ReverseCallGraphPanel_TimeCpuColumnName\"); // NOI18N\n    private static final String TIME_CPU_COLUMN_TOOLTIP = messages.getString(\"ReverseCallGraphPanel_TimeCpuColumnToolTip\"); // NOI18N\n    private static final String INVOCATIONS_COLUMN_NAME = messages.getString(\"ReverseCallGraphPanel_InvocationsColumnName\"); // NOI18N\n    private static final String INVOCATIONS_COLUMN_TOOLTIP = messages.getString(\"ReverseCallGraphPanel_InvocationsColumnToolTip\"); // NOI18N\n    private static final String TREETABLE_ACCESS_NAME = messages.getString(\"ReverseCallGraphPanel_TreeTableAccessName\"); // NOI18N\n    private static final String FILTER_ITEM_NAME = messages.getString(\"FlatProfilePanel_FilterItemName\"); // NOI18N\n    private static final String SAMPLES_COLUMN_NAME = messages.getString(\"CCTDisplay_SamplesColumnName\"); // NOI18N\n    private static final String SAMPLES_COLUMN_TOOLTIP = messages.getString(\"CCTDisplay_SamplesColumnToolTip\"); // NOI18N\n                                                                                                                         // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected JButton cornerButton;\n    protected JTreeTable treeTable;\n    protected JTreeTablePanel treeTablePanel;\n    protected FilterComponent filterComponent;\n    protected boolean sortOrder;\n    protected int selectedMethodId;\n    protected int sortingColumn;\n    protected int threadId;\n    private AbstractTreeTableModel abstractTreeTableModel;\n    private EnhancedTreeCellRenderer enhancedTreeCellRenderer = new MethodNameTreeCellRenderer();\n    private ExtendedTreeTableModel treeTableModel;\n    private Icon leafIcon = Icons.getIcon(ProfilerIcons.NODE_REVERSE);\n    private Icon nodeIcon = Icons.getIcon(ProfilerIcons.NODE_REVERSE);\n    private int minNamesColumnWidth; // minimal width of classnames columns\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ReverseCallGraphPanel(CPUResUserActionsHandler actionsHandler, Boolean sampling) {\n        super(actionsHandler, sampling);\n\n        enhancedTreeCellRenderer.setLeafIcon(leafIcon);\n        enhancedTreeCellRenderer.setClosedIcon(nodeIcon);\n        enhancedTreeCellRenderer.setOpenIcon(nodeIcon);\n\n        minNamesColumnWidth = getFontMetrics(getFont()).charWidth('W') * 30; // NOI18N\n\n        cornerPopup = new JPopupMenu();\n        cornerButton = createHeaderPopupCornerButton(cornerPopup);\n\n        setDefaultSorting();\n    }\n\n    public void exportData(int exportedFileType, ExportDataDumper eDD, String viewName) {\n        percentFormat.setMaximumFractionDigits(2);\n        percentFormat.setMinimumFractionDigits(2);\n        PrestimeCPUCCTNodeFree.setPercentFormat(percentFormat);\n        switch (exportedFileType) {\n            case 1: eDD.dumpData(getCSVHeader(\",\")); //NOI18N\n                    ((PrestimeCPUCCTNodeFree) abstractTreeTableModel.getRoot()).exportCSVData(\",\",exportedFileType, eDD);\n                    eDD.close();\n                    break;\n            case 2: eDD.dumpData(getCSVHeader(\";\")); //NOI18N\n                    ((PrestimeCPUCCTNodeFree)abstractTreeTableModel.getRoot()).exportCSVData(\";\", exportedFileType, eDD);\n                    eDD.close();\n                    break;\n            case 3: eDD.dumpData(getXMLHeader(viewName));\n                    ((PrestimeCPUCCTNodeFree)abstractTreeTableModel.getRoot()).exportXMLData(eDD, \"  \");\n                    eDD.dumpDataAndClose(getXMLFooter());\n                    break;\n            case 4: eDD.dumpData(getHTMLHeader(viewName));\n                    ((PrestimeCPUCCTNodeFree)abstractTreeTableModel.getRoot()).exportHTMLData(eDD, 0);\n                    eDD.dumpDataAndClose(getHTMLFooter());\n                    break;\n        }\n        percentFormat.setMaximumFractionDigits(1);\n        percentFormat.setMinimumFractionDigits(0);\n    }\n\n    private StringBuffer getCSVHeader(String separator) {\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n        StringBuffer result = new StringBuffer();\n        for (int i = 0; i < (columnCount); i++) {\n            result.append(quote).append(columnNames[i]).append(quote).append(separator);\n        }\n        result.append(newLine);\n        return result;\n    }\n\n    private StringBuffer getHTMLHeader(String viewName) {\n        StringBuffer result = new StringBuffer(\"<HTML><HEAD><meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" /><TITLE>\"+viewName+\"</TITLE><style type=\\\"text/css\\\">pre.method{overflow:auto;width:600;height:30;vertical-align:baseline}pre.parent{overflow:auto;width:400;height:30;vertical-align:baseline}td.method{text-align:left;width:600}td.parent{text-align:left;width:400}td.right{text-align:right;white-space:nowrap}</style></HEAD><BODY><table border=\\\"1\\\"><tr>\"); // NOI18N\n        for (int i = 0; i < (columnCount); i++) {\n            result.append(\"<th>\").append(columnNames[i]).append(columnNames[i].equals(\"Total Time\")?\" [&micro;s]\":\"\").append(\"</th>\"); //NOI18N\n        }\n        result.append(\"</tr>\"); //NOI18N\n        return result;\n    }\n\n    private StringBuffer getHTMLFooter() {\n        return new StringBuffer(\"</TABLE></BODY></HTML>\"); //NOI18N\n    }\n\n    private StringBuffer getXMLHeader(String viewName) {\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"+newline+\"<ExportedView Name=\\\"\"+viewName+\"\\\" type=\\\"tree\\\">\"+newline+\"<tree>\"+newline); // NOI18N\n        return result;\n    }\n\n    private StringBuffer getXMLFooter() {\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"</tree>\"+newline+\"</ExportedView>\"); // NOI18N\n        return result;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getCurrentThreadId() {\n        return threadId;\n    }\n\n    public BufferedImage getCurrentViewScreenshot(boolean onlyVisibleArea) {\n        if ((treeTablePanel == null) || (treeTable == null)) {\n            return null;\n        }\n\n        if (onlyVisibleArea) {\n            return UIUtils.createScreenshot(treeTablePanel.getScrollPane());\n        } else {\n            return UIUtils.createScreenshot(treeTable);\n        }\n    }\n\n    public void setDataToDisplay(CPUResultsSnapshot snapshot, int threadId, int view) {\n        super.setDataToDisplay(snapshot, view);\n        this.threadId = threadId;\n    }\n\n    // NOTE: this method only sets sortingColumn and sortOrder, it doesn't refresh UI!\n    public void setDefaultSorting() {\n        setSorting(1, SortableTableModel.SORT_ORDER_DESC);\n    }\n\n    public String getDefaultViewName() {\n        return \"cpu-backtraces\"; // NOI18N\n    }\n\n    // --- Find functionality stuff\n    public void setFindString(String findString) {\n        treeTable.setFindParameters(findString, 0);\n    }\n\n    public String getFindString() {\n        return treeTable.getFindString();\n    }\n\n    public boolean isFindStringDefined() {\n        return treeTable.isFindStringDefined();\n    }\n\n    public void setSelectedMethodId(int selectedMethodId) {\n        this.selectedMethodId = selectedMethodId;\n    }\n\n    public int getSelectedMethodId() {\n        return selectedMethodId;\n    }\n\n    public String getSelectedMethodName() {\n        String name = snapshot.getInstrMethodClasses(currentView)[selectedMethodId];\n\n        if (currentView == CPUResultsSnapshot.METHOD_LEVEL_VIEW) {\n            name += (\".\" + snapshot.getInstrMethodNames()[selectedMethodId]\n                    + snapshot.getInstrMethodSignatures()[selectedMethodId]);\n        }\n\n        return name;\n    }\n\n    public String getSelectedMethodNameShort() {\n        if (currentView == CPUResultsSnapshot.METHOD_LEVEL_VIEW) {\n            return snapshot.getInstrMethodNames()[selectedMethodId];\n        } else {\n            return snapshot.getInstrMethodClasses(currentView)[selectedMethodId];\n        }\n    }\n\n    public String getShortTitle() {\n        return MessageFormat.format(PANEL_TITLE_SHORT, getSelectedMethodNameShort());\n    }\n\n    // NOTE: this method only sets sortingColumn and sortOrder, it doesn't refresh UI!\n    public void setSorting(int sColumn, boolean sOrder) {\n        if (sColumn == CommonConstants.SORTING_COLUMN_DEFAULT) {\n            setDefaultSorting();\n        } else {\n            sortingColumn = sColumn;\n            sortOrder = sOrder;\n        }\n    }\n\n    public int getSortingColumn() {\n        return sortingColumn;\n    }\n\n    public boolean getSortingOrder() {\n        return sortOrder;\n    }\n\n    public String getTitle() {\n        return MessageFormat.format(PANEL_TITLE, getSelectedMethodName());\n    }\n\n    public boolean findFirst() {\n        return treeTable.findFirst();\n    }\n\n    public boolean findNext() {\n        return treeTable.findNext();\n    }\n\n    public boolean findPrevious() {\n        return treeTable.findPrevious();\n    }\n\n    public boolean fitsVisibleArea() {\n        return !treeTablePanel.getScrollPane().getVerticalScrollBar().isEnabled();\n    }\n\n    public void prepareResults() {\n        initColumnsData();\n\n        PrestimeCPUCCTNode rootNode = snapshot.getReverseCCT(threadId, selectedMethodId, currentView);\n\n        abstractTreeTableModel = new AbstractTreeTableModel(rootNode, sortingColumn, sortOrder) {\n                public int getColumnCount() {\n                    return columnCount;\n                }\n\n                public String getColumnName(int column) {\n                    return columnNames[column];\n                }\n\n                public Class<?> getColumnClass(int column) {\n                    if (column == 0) {\n                        return TreeTableModel.class;\n                    } else {\n                        return Object.class;\n                    }\n                }\n\n                public Object getValueAt(Object node, int column) {\n                    if (!snapshot.isCollectingTwoTimeStamps()) {\n                        if (column > 2) {\n                            column += 1;\n                        }\n                    }\n\n                    PrestimeCPUCCTNode pNode = (PrestimeCPUCCTNode) node;\n\n                    switch (column) {\n                        case 0:\n                            return getNodeName(pNode);\n                        case 1:\n                            return getNodeTimeRel(pNode);\n                        case 2:\n                            return getNodeTime(pNode);\n                        case 3:\n                            return getNodeSecondaryTime(pNode);\n                        case 4:\n                            return getNodeInvocations(pNode);\n                    }\n\n                    return null;\n                }\n\n                public String getColumnToolTipText(int col) {\n                    return columnToolTips[col];\n                }\n\n                private String getNodeName(PrestimeCPUCCTNode pNode) {\n                    return pNode.toString();\n                }\n\n                private Float getNodeTimeRel(PrestimeCPUCCTNode pNode) {\n                    return new Float(pNode.getTotalTime0InPerCent());\n                }\n\n                private String getNodeTime(PrestimeCPUCCTNode pNode) {\n                    return StringUtils.mcsTimeToString(pNode.getTotalTime0()) + \" ms (\" // NOI18N\n                           + percentFormat.format(pNode.getTotalTime0InPerCent() / 100) + \")\"; // NOI18N\n                }\n\n                private String getNodeSecondaryTime(PrestimeCPUCCTNode pNode) {\n                    /*!!! FIX THIS! if (pNode instanceof PresoCPUCCTClassNode) {\n                       PresoCPUCCTClassNode.Extended extNode = (PresoCPUCCTClassNode.Extended)pNode;\n                       return StringUtils.mcsTimeToString(extNode.getTotalTime1()) + \" ms\";\n                       } else {*/\n                    return StringUtils.mcsTimeToString(pNode.getTotalTime1()) + \" ms\"; // NOI18N\n                }\n\n                private Integer getNodeInvocations(PrestimeCPUCCTNode pNode) {\n                    return Integer.valueOf(pNode.getNCalls());\n                }\n\n                public void sortByColumn(int column, boolean order) {\n                    sortOrder = order;\n\n                    if (!snapshot.isCollectingTwoTimeStamps()) {\n                        if (column > 2) {\n                            column += 1;\n                        }\n                    }\n\n                    PrestimeCPUCCTNode pRoot = (PrestimeCPUCCTNode) root;\n\n                    switch (column) {\n                        case 0:\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_NAME, order);\n\n                            break;\n                        case 1:\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_TIME_0, order);\n\n                            break;\n                        case 2:\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_TIME_0, order);\n\n                            break;\n                        case 3:\n                            /*!!! FIX THIS! if (pRoot instanceof PrestimeCPUCCTClassNode) {\n                               pRoot.sortChildren(PrestimeCPUCCTClassNode.Extended.SORT_BY_TIME_1, order);\n                               } else { */\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_TIME_1, order);\n\n                            break;\n                        case 4:\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_INVOCATIONS, order);\n\n                            break;\n                    }\n                }\n\n                public boolean getInitialSorting(int column) {\n                    return (column == 0);\n                }\n            };\n\n        treeTableModel = new ExtendedTreeTableModel(abstractTreeTableModel);\n\n        if (columnsVisibility != null) {\n            treeTableModel.setColumnsVisibility(columnsVisibility);\n        }\n\n        treeTable = new JTreeTable(treeTableModel) {\n                public void doLayout() {\n                    int columnsWidthsSum = 0;\n                    int realFirstColumn = -1;\n\n                    int index;\n                    TableColumnModel colModel = getColumnModel();\n\n                    for (int i = 0; i < treeTableModel.getColumnCount(); i++) {\n                        index = treeTableModel.getRealColumn(i);\n\n                        if (index == 0) {\n                            realFirstColumn = i;\n                        } else {\n                            columnsWidthsSum += colModel.getColumn(i).getPreferredWidth();\n                        }\n                    }\n\n                    if (realFirstColumn != -1) {\n                        colModel.getColumn(realFirstColumn)\n                                .setPreferredWidth(Math.max(getWidth() - columnsWidthsSum, minNamesColumnWidth));\n                    }\n\n                    super.doLayout();\n                }\n\n            };\n        treeTable.getAccessibleContext().setAccessibleName(TREETABLE_ACCESS_NAME);\n\n        treeTable.setRowSelectionAllowed(true);\n        treeTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        treeTable.setGridColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);\n        treeTable.setSelectionBackground(UIConstants.TABLE_SELECTION_BACKGROUND_COLOR);\n        treeTable.setSelectionForeground(UIConstants.TABLE_SELECTION_FOREGROUND_COLOR);\n        treeTable.setShowHorizontalLines(UIConstants.SHOW_TABLE_HORIZONTAL_GRID);\n        treeTable.setShowVerticalLines(UIConstants.SHOW_TABLE_VERTICAL_GRID);\n        treeTable.setRowMargin(UIConstants.TABLE_ROW_MARGIN);\n        treeTable.setRowHeight(UIUtils.getDefaultRowHeight() + 2);\n        treeTable.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)\n                 .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), \"DEFAULT_ACTION\"); // NOI18N\n        treeTable.getActionMap().put(\"DEFAULT_ACTION\",\n                                     new AbstractAction() {\n                public void actionPerformed(ActionEvent e) {\n                    performDefaultAction();\n                }\n            }); // NOI18N\n\n        // Disable traversing table cells using TAB and Shift+TAB\n        Set<AWTKeyStroke> keys = new HashSet<>(treeTable.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));\n        keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));\n        treeTable.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys);\n\n        keys = new HashSet<>(treeTable.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));\n        keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));\n        treeTable.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys);\n\n        setColumnsData();\n\n        UIUtils.autoExpandRoot(treeTable.getTree(), 2);\n        UIUtils.makeTreeAutoExpandable(treeTable.getTree(), 2);\n\n        treeTable.addKeyListener(new KeyAdapter() {\n                public void keyPressed(KeyEvent e) {\n                    if ((e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU)\n                            || ((e.getKeyCode() == KeyEvent.VK_F10) && (e.getModifiers() == InputEvent.SHIFT_MASK))) {\n                        int selectedRow = treeTable.getSelectedRow();\n\n                        if (selectedRow != -1) {\n                            popupPath = treeTable.getTree().getPathForRow(selectedRow);\n                            \n                            PrestimeCPUCCTNode node = (PrestimeCPUCCTNode) popupPath.getLastPathComponent();\n                            enableDisablePopup(node);\n\n                            Rectangle cellRect = treeTable.getCellRect(selectedRow, 0, false);\n                            callGraphPopupMenu.show(e.getComponent(), ((cellRect.x + treeTable.getSize().width) > 50) ? 50 : 5,\n                                                    cellRect.y);\n                        }\n                    }\n                }\n            });\n\n        treeTable.addMouseListener(new MouseAdapter() {\n                private void showPopupMenu(MouseEvent e) {\n                    popupPath = treeTable.getTree().getPathForRow(treeTable.rowAtPoint(e.getPoint()));\n                    if (popupPath == null) {\n                            treeTable.getTree().clearSelection();\n                    } else {\n                        treeTable.getTree().setSelectionPath(popupPath);\n                        PrestimeCPUCCTNode node = (PrestimeCPUCCTNode) popupPath.getLastPathComponent();\n                        enableDisablePopup(node);\n                        callGraphPopupMenu.show(e.getComponent(), e.getX(), e.getY());\n                    }\n                }\n                public void mousePressed(MouseEvent e) {\n                    if (e.isPopupTrigger()) showPopupMenu(e);\n                }\n\n                public void mouseReleased(MouseEvent e) {\n                    if (e.isPopupTrigger()) showPopupMenu(e);\n                }\n\n                public void mouseClicked(MouseEvent e) {\n                    popupPath = treeTable.getTree().getPathForRow(treeTable.rowAtPoint(e.getPoint()));\n\n                    if (popupPath != null) {\n                        treeTable.getTree().setSelectionPath(popupPath);\n                        if (SwingUtilities.isLeftMouseButton(e) && (e.getClickCount() == 2)) {\n                            if (treeTableModel.isLeaf(popupPath.getPath()[popupPath.getPath().length - 1])) {\n                                showSourceForMethod(popupPath);\n                            }\n                        }\n                    }\n                }\n            });\n\n        treeTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent e) {\n                    int selectedRow = treeTable.getSelectedRow();\n\n                    if (selectedRow == -1) {\n                        return;\n                    }\n\n                    popupPath = treeTable.getTree().getPathForRow(selectedRow);\n                }\n            });\n\n        treeTablePanel = new JTreeTablePanel(treeTable);\n        treeTablePanel.setCorner(JScrollPane.UPPER_RIGHT_CORNER, cornerButton);\n        treeTablePanel.clearBorders();\n        add(treeTablePanel, BorderLayout.CENTER);\n        initFilterPanel();\n        initFirstColumnName();\n    }\n    \n    private void initFilterPanel() {\n        filterComponent = FilterComponent.create(true, true);\n        \n        FilterSortSupport.Configuration config = snapshot.getFilterSortInfo(\n                (PrestimeCPUCCTNode)treeTableModel.getRoot());\n        filterComponent.setFilter(config.getFilterString(), config.getFilterType());\n\n        filterComponent.addChangeListener(new ChangeListener() {\n                public void stateChanged(ChangeEvent e) {\n                    String filterString = filterComponent.getFilterValue();\n                    int filterType = filterComponent.getFilterType();\n                    snapshot.filterReverse(filterString, filterType,\n                            (PrestimeCPUCCTNodeFree)abstractTreeTableModel.getRoot(), currentView);\n                    \n                    treeTable.updateTreeTable();\n                }\n            });\n\n        add(filterComponent.getComponent(), BorderLayout.SOUTH);\n    }\n    \n    private void enableDisablePopup(PrestimeCPUCCTNode node) {\n        boolean regularNode = node.getMethodId() != 0 && !node.isFiltered();\n        if (popupShowSource != null) popupShowSource.setEnabled(regularNode && isShowSourceAvailable());\n    }\n\n    public void requestFocus() {\n        if (treeTable != null) {\n            SwingUtilities.invokeLater(new Runnable() { // must be invoked lazily to override default focus of first component (top-right cornerButton)\n                    public void run() {\n                        treeTable.requestFocus();\n                    }\n                });\n        }\n    }\n\n    public void reset() {\n        if (treeTablePanel != null) {\n            remove(treeTablePanel);\n            treeTablePanel = null;\n        }\n\n        treeTable = null;\n        abstractTreeTableModel = null;\n        treeTableModel = null;\n    }\n\n    protected JPopupMenu createPopupMenu() {\n        JPopupMenu popup = new JPopupMenu();\n        if (GoToSource.isAvailable()) popupShowSource = new JMenuItem();\n\n        Font boldfont = popup.getFont().deriveFont(Font.BOLD);\n\n        if (popupShowSource != null) {\n            popupShowSource.setFont(boldfont);\n            popupShowSource.setText(GO_TO_SOURCE_POPUP_ITEM);\n            popup.add(popupShowSource);\n            popup.addSeparator();\n        }\n\n        if (popupShowSource != null) popupShowSource.addActionListener(this::menuActionPerformed);\n\n        return popup;\n    }\n\n    protected void initColumnSelectorItems() {\n        cornerPopup.removeAll();\n\n        JCheckBoxMenuItem menuItem;\n\n        for (int i = 0; i < columnCount; i++) {\n            menuItem = new JCheckBoxMenuItem(columnNames[i]);\n            menuItem.setActionCommand(Integer.toString(i));\n            addMenuItemListener(menuItem);\n\n            if (treeTable != null) {\n                menuItem.setState(treeTableModel.isRealColumnVisible(i));\n\n                if (i == 0) {\n                    menuItem.setEnabled(false);\n                }\n            } else {\n                menuItem.setState(true);\n            }\n\n            cornerPopup.add(menuItem);\n        }\n        \n        cornerPopup.addSeparator();\n\n        JCheckBoxMenuItem filterMenuItem = new JCheckBoxMenuItem(FILTER_ITEM_NAME);\n        filterMenuItem.setActionCommand(\"Filter\"); // NOI18N\n        addMenuItemListener(filterMenuItem);\n\n        if (filterComponent == null) {\n            filterMenuItem.setState(true);\n        } else {\n            filterMenuItem.setState(filterComponent.getComponent().isVisible());\n        }\n        \n        cornerPopup.add(filterMenuItem);\n\n        cornerPopup.pack();\n    }\n\n    private void setColumnsData() {\n        int index;\n        TableColumnModel colModel = treeTable.getColumnModel();\n\n        treeTable.setTreeCellRenderer(enhancedTreeCellRenderer);\n        colModel.getColumn(0).setPreferredWidth(minNamesColumnWidth);\n\n        for (int i = 0; i < treeTableModel.getColumnCount(); i++) {\n            index = treeTableModel.getRealColumn(i);\n\n            if (index != 0) {\n                colModel.getColumn(i).setPreferredWidth(columnWidths[index - 1]);\n                colModel.getColumn(i).setCellRenderer(columnRenderers[index]);\n            }\n        }\n    }\n\n    private void addMenuItemListener(JCheckBoxMenuItem menuItem) {\n        menuItem.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    if (e.getActionCommand().equals(\"Filter\")) { // NOI18N\n                        filterComponent.getComponent().setVisible(!filterComponent.getComponent().isVisible());\n\n                        return;\n                    }\n                    \n                    boolean sortResults = false;\n                    int column = Integer.parseInt(e.getActionCommand());\n                    boolean sortOrder = treeTable.getSortingOrder();\n                    int sortingColumn = treeTable.getSortingColumn();\n                    int realSortingColumn = treeTableModel.getRealColumn(sortingColumn);\n                    boolean isColumnVisible = treeTableModel.isRealColumnVisible(column);\n\n                    // Current sorting column is going to be hidden\n                    if ((isColumnVisible) && (column == realSortingColumn)) {\n                        // Try to set next column as a sortingColumn. If currentSortingColumn is the last column, set previous\n                        // column as a sorting Column (one column is always visible).\n                        sortingColumn = ((sortingColumn + 1) == treeTableModel.getColumnCount()) ? (sortingColumn - 1)\n                                                                                                 : (sortingColumn + 1);\n                        realSortingColumn = treeTableModel.getRealColumn(sortingColumn);\n                        sortResults = true;\n                    }\n\n                    treeTableModel.setRealColumnVisibility(column, !isColumnVisible);\n                    treeTable.createDefaultColumnsFromModel();\n                    treeTable.updateTreeTableHeader();\n                    sortingColumn = treeTableModel.getVirtualColumn(realSortingColumn);\n\n                    if (sortResults) {\n                        sortOrder = treeTableModel.getInitialSorting(sortingColumn);\n                        treeTableModel.sortByColumn(sortingColumn, sortOrder);\n                        treeTable.updateTreeTable();\n                    }\n\n                    treeTable.setSortingColumn(sortingColumn);\n                    treeTable.setSortingOrder(sortOrder);\n                    treeTable.getTableHeader().repaint();\n                    setColumnsData();\n\n                    // TODO [ui-persistence]\n                }\n            });\n    }\n\n    private void initColumnsData() {\n        columnCount = snapshot.isCollectingTwoTimeStamps() ? 5 : 4;\n\n        columnWidths = new int[columnCount - 1]; // Width of the first column fits to width\n        columnNames = new String[columnCount];\n        columnRenderers = new TableCellRenderer[columnCount];\n        \n        columnsVisibility = new boolean[columnCount];\n        for (int i = 0; i < columnCount - 1; i++)\n            columnsVisibility[i] = true;\n        if (isSampling() != null && !isSampling())\n            columnsVisibility[columnCount - 1] = true;\n\n        if (columnCount == 5) {\n            columnNames = new String[] {\n                              METHOD_COLUMN_NAME, TIME_REL_COLUMN_NAME, TIME_COLUMN_NAME, TIME_CPU_COLUMN_NAME,\n                              INVOCATIONS_COLUMN_NAME\n                          };\n            columnToolTips = new String[] {\n                                 METHOD_COLUMN_TOOLTIP, TIME_REL_COLUMN_TOOLTIP, TIME_COLUMN_TOOLTIP, TIME_CPU_COLUMN_TOOLTIP,\n                                 INVOCATIONS_COLUMN_TOOLTIP\n                             };\n        } else {\n            columnNames = new String[] { METHOD_COLUMN_NAME, TIME_REL_COLUMN_NAME, TIME_COLUMN_NAME, INVOCATIONS_COLUMN_NAME };\n            columnToolTips = new String[] {\n                                 METHOD_COLUMN_TOOLTIP, TIME_REL_COLUMN_TOOLTIP, TIME_COLUMN_TOOLTIP, INVOCATIONS_COLUMN_TOOLTIP\n                             };\n        }\n        \n        if (isSampling() != null && isSampling()) {\n            columnNames[columnCount - 1] = SAMPLES_COLUMN_NAME;\n            columnToolTips[columnCount - 1] = SAMPLES_COLUMN_TOOLTIP;\n        }\n\n        int maxWidth = getFontMetrics(getFont()).charWidth('W') * 12; // NOI18N // initial width of data columns\n\n        CustomBarCellRenderer customBarCellRenderer = new CustomBarCellRenderer(0, 100);\n        LabelTableCellRenderer labelTableCellRenderer = new LabelTableCellRenderer(JLabel.TRAILING);\n        LabelBracketTableCellRenderer labelBracketTableCellRenderer = new LabelBracketTableCellRenderer(JLabel.TRAILING);\n\n        columnRenderers[0] = null;\n\n        // Inclusive (total) time bar\n        columnWidths[1 - 1] = maxWidth;\n        columnRenderers[1] = customBarCellRenderer;\n\n        // Inclusive (total) time\n        columnWidths[2 - 1] = maxWidth;\n        columnRenderers[2] = labelBracketTableCellRenderer;\n\n        for (int i = 3; i < columnCount; i++) {\n            columnWidths[i - 1] = maxWidth;\n            columnRenderers[i] = labelTableCellRenderer;\n        }\n        \n        if (isSampling() == null) columnCount--;\n    }\n\n    private void initFirstColumnName() {\n        switch (currentView) {\n            case CPUResultsSnapshot.METHOD_LEVEL_VIEW:\n                columnNames[0] = METHOD_COLUMN_NAME;\n                columnToolTips[0] = METHOD_COLUMN_TOOLTIP;\n                filterComponent.setHint(METHOD_FILTER_HINT);\n\n                break;\n            case CPUResultsSnapshot.CLASS_LEVEL_VIEW:\n                columnNames[0] = CLASS_COLUMN_NAME;\n                columnToolTips[0] = CLASS_COLUMN_TOOLTIP;\n                filterComponent.setHint(CLASS_FILTER_HINT);\n\n                break;\n            case CPUResultsSnapshot.PACKAGE_LEVEL_VIEW:\n                columnNames[0] = PACKAGE_COLUMN_NAME;\n                columnToolTips[0] = PACKAGE_COLUMN_TOOLTIP;\n                filterComponent.setHint(PACKAGE_FILTER_HINT);\n\n                break;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/ScreenshotProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.image.BufferedImage;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface ScreenshotProvider {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    BufferedImage getCurrentViewScreenshot(boolean onlyVisible);\n\n    String getDefaultViewName();\n\n    boolean fitsVisibleArea();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/SnapshotCPUResultsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\n\n\n/**\n * Superclass providing common support for results displays displaying CPU results backed by CPUResultsSnapshot.\n *\n * @author Ian Formanek\n */\npublic abstract class SnapshotCPUResultsPanel extends CPUResultsPanel implements CommonConstants, ScreenshotProvider {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected CPUResultsSnapshot snapshot;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SnapshotCPUResultsPanel(CPUResUserActionsHandler actionsHandler, Boolean sampling) {\n        super(actionsHandler, sampling);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setDataToDisplay(CPUResultsSnapshot snapshot, int view) {\n        this.snapshot = snapshot;\n        this.currentView = view;\n    }\n\n    public CPUResultsSnapshot getSnapshot() {\n        return snapshot;\n    }\n\n    /**\n     * Gives a hint whether a tab panel is explicitly closeable\n     * Subclasses should override the default implementation\n     */\n    protected boolean isCloseable() {\n        return false;\n    }\n\n    protected String[] getMethodClassNameAndSig(int methodId, int currentView) {\n        return snapshot.getMethodClassNameAndSig(methodId, currentView);\n    }\n\n    protected void showReverseCallGraph(int threadId, int methodId, int currentView, int sortingColumn, boolean sortingOrder) {\n        actionsHandler.showReverseCallGraph(snapshot, threadId, methodId, currentView, sortingColumn, sortingOrder);\n    }\n\n    protected void showSubtreeCallGraph(CCTNode node, int currentView, int sortingColumn, boolean sortingOrder) {\n        actionsHandler.showSubtreeCallGraph(snapshot, node, currentView, sortingColumn, sortingOrder);\n    }\n\n    protected boolean supportsReverseCallGraph() {\n        return true;\n    }\n\n    protected boolean supportsSubtreeCallGraph() {\n        return true;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/SnapshotCPUView.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.awt.event.ActionEvent;\nimport java.text.MessageFormat;\nimport java.util.Collection;\nimport java.util.Map;\nimport java.util.ResourceBundle;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JSeparator;\nimport javax.swing.JSplitPane;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport javax.swing.plaf.basic.BasicSplitPaneDivider;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\nimport javax.swing.tree.TreeNode;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedSplitPane;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.results.DataView;\nimport org.graalvm.visualvm.lib.ui.swing.ActionPopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.MultiButtonGroup;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class SnapshotCPUView extends JPanel {\n    \n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.cpu.Bundle\"); // NOI18N\n    private static final String TOOLBAR_VIEW = messages.getString(\"SnapshotCPUView_ToolbarView\"); // NOI18N\n    private static final String VIEW_FORWARD = messages.getString(\"SnapshotCPUView_ViewForward\"); // NOI18N\n    private static final String VIEW_HOTSPOTS = messages.getString(\"SnapshotCPUView_ViewHotSpots\"); // NOI18N\n    private static final String VIEW_REVERSE = messages.getString(\"SnapshotCPUView_ViewReverse\"); // NOI18N\n    private static final String TOOLBAR_AGGREGATION = messages.getString(\"SnapshotCPUView_ToolbarAggregation\"); // NOI18N\n    private static final String AGGREGATION_METHODS = messages.getString(\"SnapshotCPUView_AggregationMethods\"); // NOI18N\n    private static final String AGGREGATION_CLASSES = messages.getString(\"SnapshotCPUView_AggregationClasses\"); // NOI18N\n    private static final String AGGREGATION_PACKAGES = messages.getString(\"SnapshotCPUView_AggregationPackages\"); // NOI18N\n    private static final String COMPARE_SNAPSHOTS = messages.getString(\"SnapshotCPUView_CompareSnapshots\"); // NOI18N\n    private static final String RESET_COMPARE_SNAPSHOTS = messages.getString(\"SnapshotCPUView_ResetCompareSnapshots\"); // NOI18N\n    // -----\n    \n    private boolean sampled;\n    private CPUResultsSnapshot snapshot;\n    private CPUResultsSnapshot refSnapshot;\n    \n    private int aggregation;\n    private boolean mergedThreads;\n    private Collection<Integer> selectedThreads;\n    \n    private DataView lastFocused;\n    private CPUTableView hotSpotsView;\n    private CPUTreeTableView forwardCallsView;\n    private CPUTreeTableView reverseCallsView;\n    \n    private JToggleButton[] toggles;\n    private JToggleButton compareButton;\n    \n    private ThreadsSelector threadsSelector;\n    \n    private ExecutorService executor;\n    \n    \n    public SnapshotCPUView(CPUResultsSnapshot snapshot, boolean sampled, Action saveAction, Action compareAction, Action infoAction, ExportUtils.Exportable exportProvider) {\n        initUI(saveAction, compareAction, infoAction, exportProvider);\n        registerActions();\n        \n        aggregation = CPUResultsSnapshot.METHOD_LEVEL_VIEW;\n        setSnapshot(snapshot, sampled);\n    }\n    \n    \n    public void setRefSnapshot(CPUResultsSnapshot snapshot) {\n        refSnapshot = snapshot;\n        \n        if (compareButton != null && snapshot != null) {\n            compareButton.setSelected(true);\n            compareButton.setToolTipText(RESET_COMPARE_SNAPSHOTS);\n        }\n        \n        setAggregation(aggregation);\n    }\n    \n    \n    protected boolean profileMethodEnabled() { return true; }\n    \n    protected boolean profileMethodSupported() { return true; }\n    \n    protected boolean profileClassSupported() { return true; }\n    \n    \n    protected abstract boolean showSourceSupported();\n    \n    protected abstract void showSource(ClientUtils.SourceCodeSelection value);\n    \n    protected abstract void selectForProfiling(ClientUtils.SourceCodeSelection value);\n    \n    \n    protected void foundInForwardCalls() {\n        toggles[0].setSelected(true);\n    }\n    protected void foundInHotSpots() {\n        toggles[1].setSelected(true);\n    }\n    protected void foundInReverseCalls() {\n        toggles[2].setSelected(true);\n    }\n    \n    \n    private void profileMethod(ClientUtils.SourceCodeSelection value) {\n        selectForProfiling(value);\n    }\n    \n    private void profileClass(ClientUtils.SourceCodeSelection value) {\n        selectForProfiling(new ClientUtils.SourceCodeSelection(\n                           value.getClassName(), Wildcards.ALLWILDCARD, null));\n    }\n    \n    \n    private void initUI(Action saveAction, final Action compareAction, Action infoAction, ExportUtils.Exportable exportProvider) {\n        setOpaque(false);\n        setLayout(new BorderLayout(0, 0));\n        \n        forwardCallsView = new CPUTreeTableView(null, false) {\n            protected void performDefaultAction(ClientUtils.SourceCodeSelection value) {\n                if (showSourceSupported()) showSource(value);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                SnapshotCPUView.this.populatePopup(forwardCallsView, popup, value, userValue);\n            }\n        };\n        forwardCallsView.notifyOnFocus(new Runnable() {\n            public void run() { lastFocused = forwardCallsView; }\n        });\n        \n        hotSpotsView = new CPUTableView(null) {\n            protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                if (showSourceSupported()) showSource(userValue);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                SnapshotCPUView.this.populatePopup(hotSpotsView, popup, value, userValue);\n            }\n        };\n        hotSpotsView.notifyOnFocus(new Runnable() {\n            public void run() { lastFocused = hotSpotsView; }\n        });\n        \n        reverseCallsView = new CPUTreeTableView(null, true) {\n            protected void performDefaultAction(ClientUtils.SourceCodeSelection value) {\n                if (showSourceSupported()) showSource(value);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                SnapshotCPUView.this.populatePopup(reverseCallsView, popup, value, userValue);\n            }\n        };\n        reverseCallsView.notifyOnFocus(new Runnable() {\n            public void run() { lastFocused = reverseCallsView; }\n        });\n        \n        JSplitPane upperSplit = new JExtendedSplitPane(JSplitPane.VERTICAL_SPLIT) {\n            {\n                setBorder(null);\n                setDividerSize(5);\n\n                if (getUI() instanceof BasicSplitPaneUI) {\n                    BasicSplitPaneDivider divider = ((BasicSplitPaneUI)getUI()).getDivider();\n                    if (divider != null) {\n                        Color c = UIUtils.isNimbus() || UIUtils.isAquaLookAndFeel() ?\n                                  UIUtils.getDisabledLineColor() : new JSeparator().getForeground();\n                        divider.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, c));\n                    }\n                }\n            }\n        };\n        upperSplit.setBorder(BorderFactory.createEmptyBorder());\n        upperSplit.setTopComponent(forwardCallsView);\n        upperSplit.setBottomComponent(hotSpotsView);\n        upperSplit.setDividerLocation(0.5d);\n        upperSplit.setResizeWeight(0.5d);\n        \n        JSplitPane lowerSplit = new JExtendedSplitPane(JSplitPane.VERTICAL_SPLIT) {\n            {\n                setBorder(null);\n                setDividerSize(5);\n\n                if (getUI() instanceof BasicSplitPaneUI) {\n                    BasicSplitPaneDivider divider = ((BasicSplitPaneUI)getUI()).getDivider();\n                    if (divider != null) {\n                        Color c = UIUtils.isNimbus() || UIUtils.isAquaLookAndFeel() ?\n                                  UIUtils.getDisabledLineColor() : new JSeparator().getForeground();\n                        divider.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, c));\n                    }\n                }\n            }\n        };\n        lowerSplit.setBorder(BorderFactory.createEmptyBorder());\n        lowerSplit.setTopComponent(upperSplit);\n        lowerSplit.setBottomComponent(reverseCallsView);\n        lowerSplit.setDividerLocation(0.66d);\n        lowerSplit.setResizeWeight(0.66d);\n        \n        add(lowerSplit, BorderLayout.CENTER);\n        \n        ProfilerToolbar toolbar = ProfilerToolbar.create(true);\n        \n        if (saveAction != null) toolbar.add(saveAction);\n        \n        if (exportProvider != null) toolbar.add(ExportUtils.exportButton(this, CPUView.EXPORT_TOOLTIP, getExportables(exportProvider)));\n        \n        if (compareAction != null) {\n            toolbar.addSpace(2);\n            toolbar.addSeparator();\n            toolbar.addSpace(2);\n        \n            Icon icon = (Icon)compareAction.getValue(Action.SMALL_ICON);\n            compareButton = new JToggleButton(icon) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    boolean sel = isSelected();\n                    if (sel) {\n                        compareAction.actionPerformed(e);\n                        if (refSnapshot == null) setSelected(false);\n                    } else {\n                        setRefSnapshot(null);\n                    }\n                    setToolTipText(isSelected() ? RESET_COMPARE_SNAPSHOTS :\n                                                  COMPARE_SNAPSHOTS);\n                }\n            };\n            compareButton.setToolTipText(COMPARE_SNAPSHOTS);\n            toolbar.add(compareButton);\n        }\n        \n        if (saveAction != null || exportProvider != null || compareAction != null) {\n            toolbar.addSpace(2);\n            toolbar.addSeparator();\n        }\n        \n        toolbar.addSpace(5);\n        \n        GrayLabel viewL = new GrayLabel(TOOLBAR_VIEW);\n        toolbar.add(viewL);\n        \n        toolbar.addSpace(5);\n        \n        MultiButtonGroup group = new MultiButtonGroup();\n        toggles = new JToggleButton[3];\n        \n        toggles[0] = new JToggleButton(Icons.getIcon(ProfilerIcons.NODE_FORWARD)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                setView(isSelected(), hotSpotsView.isVisible(), reverseCallsView.isVisible());\n            }\n        };\n        toggles[0].setToolTipText(VIEW_FORWARD);\n        group.add(toggles[0]);\n        toolbar.add(toggles[0]);\n        forwardCallsView.setVisible(true);\n        toggles[0].setSelected(true);\n        \n        toggles[1] = new JToggleButton(Icons.getIcon(ProfilerIcons.TAB_HOTSPOTS)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                setView(forwardCallsView.isVisible(), isSelected(), reverseCallsView.isVisible());\n            }\n        };\n        toggles[1].setToolTipText(VIEW_HOTSPOTS);\n        group.add(toggles[1]);\n        toolbar.add(toggles[1]);\n        hotSpotsView.setVisible(false);\n        toggles[1].setSelected(false);\n        \n        toggles[2] = new JToggleButton(Icons.getIcon(ProfilerIcons.NODE_REVERSE)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                setView(forwardCallsView.isVisible(), hotSpotsView.isVisible(), isSelected());\n            }\n        };\n        toggles[2].setToolTipText(VIEW_REVERSE);\n        group.add(toggles[2]);\n        toolbar.add(toggles[2]);\n        reverseCallsView.setVisible(false);\n        toggles[2].setSelected(false);\n        \n//        Action aCallTree = new AbstractAction() {\n//            { putValue(NAME, VIEW_CALLTREE); }\n//            public void actionPerformed(ActionEvent e) { setView(true, false); }\n//            \n//        };\n//        Action aHotSpots = new AbstractAction() {\n//            { putValue(NAME, VIEW_HOTSPOTS); }\n//            public void actionPerformed(ActionEvent e) { setView(false, true); }\n//            \n//        };\n//        Action aCombined = new AbstractAction() {\n//            { putValue(NAME, VIEW_COMBINED); }\n//            public void actionPerformed(ActionEvent e) { setView(true, true); }\n//            \n//        };\n//        toolbar.add(new ActionPopupButton(2, aCallTree, aHotSpots, aCombined));\n        \n        toolbar.addSpace(5);\n        threadsSelector = new ThreadsSelector() {\n            protected CPUResultsSnapshot getSnapshot() { return snapshot; }\n            protected void selectionChanged(Collection<Integer> selected, boolean mergeThreads) {\n                mergedThreads = mergeThreads;\n                selectedThreads = selected;\n                setAggregation(aggregation);\n            }\n            \n        };\n        toolbar.add(threadsSelector);\n        \n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n        \n//        GrayLabel threadsL = new GrayLabel(\"Threads:\");\n//        toolbar.add(threadsL);\n//        \n//        toolbar.addSpace(2);\n//        \n//        PopupButton threads = new PopupButton(\"All threads\") {\n//            protected void populatePopup(JPopupMenu popup) {\n//                popup.add(new JRadioButtonMenuItem(\"All threads\"));\n//                popup.add(new JRadioButtonMenuItem(\"main\"));\n//                popup.add(new JRadioButtonMenuItem(\"AWT-EventQueue-0\"));\n//            }\n//        };\n//        toolbar.add(threads);\n//        \n//        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n//        toolbar.addSpace(5);\n        \n        GrayLabel aggregationL = new GrayLabel(TOOLBAR_AGGREGATION);\n        toolbar.add(aggregationL);\n        \n        toolbar.addSpace(2);\n        \n        Action aMethods = new AbstractAction() {\n            { putValue(NAME, AGGREGATION_METHODS); }\n            public void actionPerformed(ActionEvent e) { setAggregation(CPUResultsSnapshot.METHOD_LEVEL_VIEW); }\n            \n        };\n        Action aClasses = new AbstractAction() {\n            { putValue(NAME, AGGREGATION_CLASSES); }\n            public void actionPerformed(ActionEvent e) { setAggregation(CPUResultsSnapshot.CLASS_LEVEL_VIEW); }\n            \n        };\n        Action aPackages = new AbstractAction() {\n            { putValue(NAME, AGGREGATION_PACKAGES); }\n            public void actionPerformed(ActionEvent e) { setAggregation(CPUResultsSnapshot.PACKAGE_LEVEL_VIEW); }\n            \n        };\n        \n        ActionPopupButton aggregation = new ActionPopupButton(aMethods, aClasses, aPackages);\n        toolbar.add(aggregation);\n        \n        if (infoAction != null) {\n            toolbar.addFiller();\n            toolbar.add(infoAction);\n        }\n        \n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        \n//        // TODO: read last state?\n//        setView(true, false);\n    }\n    \n    private void registerActions() {\n        ActionMap map = getActionMap();\n        \n        map.put(FilterUtils.FILTER_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                DataView active = getLastFocused();\n                if (active != null) active.activateFilter();\n            }\n        });\n        \n        map.put(SearchUtils.FIND_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                DataView active = getLastFocused();\n                if (active != null) active.activateSearch();\n            }\n        });\n    }\n    \n    private DataView getLastFocused() {\n        if (lastFocused != null && !lastFocused.isShowing()) lastFocused = null;\n        \n        if (lastFocused == null) {\n            if (forwardCallsView.isShowing()) lastFocused = forwardCallsView;\n            else if (hotSpotsView.isShowing()) lastFocused = hotSpotsView;\n            else if (reverseCallsView.isShowing()) lastFocused = reverseCallsView;\n        }\n        \n        return lastFocused;\n    }\n    \n    private void populatePopup(final DataView invoker, JPopupMenu popup, final Object value, final ClientUtils.SourceCodeSelection userValue) {\n        if (showSourceSupported()) {\n            popup.add(new JMenuItem(CPUView.ACTION_GOTOSOURCE) {\n                { setEnabled(userValue != null && aggregation != CPUResultsSnapshot.PACKAGE_LEVEL_VIEW); setFont(getFont().deriveFont(Font.BOLD)); }\n                protected void fireActionPerformed(ActionEvent e) { showSource(userValue); }\n            });\n            popup.addSeparator();\n        }\n        \n        if (profileMethodSupported()) popup.add(new JMenuItem(CPUView.ACTION_PROFILE_METHOD) {\n            { setEnabled(profileMethodEnabled() && userValue != null && aggregation == CPUResultsSnapshot.METHOD_LEVEL_VIEW && CPUTableView.isSelectable(userValue)); }\n            protected void fireActionPerformed(ActionEvent e) { profileMethod(userValue); }\n        });\n        \n        if (profileClassSupported()) popup.add(new JMenuItem(CPUView.ACTION_PROFILE_CLASS) {\n            { setEnabled(userValue != null && aggregation != CPUResultsSnapshot.PACKAGE_LEVEL_VIEW); }\n            protected void fireActionPerformed(ActionEvent e) { profileClass(userValue); }\n        });\n        \n        if (profileMethodSupported() || profileClassSupported()) popup.addSeparator();\n        \n        JMenuItem[] customItems = invoker.createCustomMenuItems(this, value, userValue);\n        if (customItems != null) {\n            for (JMenuItem customItem : customItems) popup.add(customItem);\n            popup.addSeparator();\n        }\n        \n        customizeNodePopup(invoker, popup, value, userValue);\n        \n        if (invoker == forwardCallsView) {\n            final ProfilerTreeTable ttable = (ProfilerTreeTable)forwardCallsView.getResultsComponent();\n            int column = ttable.convertColumnIndexToView(ttable.getMainColumn());\n            final String searchString = ttable.getStringValue((TreeNode)value, column);\n            \n            popup.add(new JMenuItem(CPUView.FIND_IN_HOTSPOTS) {\n                { setEnabled(userValue != null); }\n                protected void fireActionPerformed(ActionEvent e) {\n                    ProfilerTable table = hotSpotsView.getResultsComponent();\n                    if (SearchUtils.findString(table, searchString)) {\n                        toggles[1].setSelected(true);\n                        hotSpotsView.setVisible(true);\n                        table.requestFocusInWindow();\n                    }\n                }\n            });\n            \n            popup.add(new JMenuItem(CPUView.FIND_IN_REVERSECALLS) {\n                { setEnabled(userValue != null); }\n                protected void fireActionPerformed(ActionEvent e) {\n                    ProfilerTreeTable table = (ProfilerTreeTable)reverseCallsView.getResultsComponent();\n                    if (SearchUtils.findString(table, searchString, true, true, createSearchHelper())) {\n                        toggles[2].setSelected(true);\n                        reverseCallsView.setVisible(true);\n                        table.requestFocusInWindow();\n                    }\n                }\n            });\n            \n            popup.addSeparator();\n            \n            JMenu threads = new JMenu(CPUView.SHOW_MENU);\n            popup.add(threads);\n            \n            threads.add(new JMenuItem(CPUView.SHOW_THREAD_ITEM) {\n                {\n                    setEnabled(!mergedThreads && threadsSelector != null && value instanceof PrestimeCPUCCTNode &&\n                               snapshot.getNThreads() > 1 && (selectedThreads == null || selectedThreads.size() > 1));\n                }\n                protected void fireActionPerformed(ActionEvent e) {\n                    PrestimeCPUCCTNode thread = (PrestimeCPUCCTNode)value;\n                    threadsSelector.addThread(thread.getThreadId(), true);\n                }\n            });\n            \n            threads.add(new JMenuItem(CPUView.HIDE_THREAD_ITEM) {\n                {\n                    setEnabled(!mergedThreads && threadsSelector != null && value instanceof PrestimeCPUCCTNode &&\n                               snapshot.getNThreads() > 1 && (selectedThreads == null || selectedThreads.size() > 1));\n                }\n                protected void fireActionPerformed(ActionEvent e) {\n                    PrestimeCPUCCTNode thread = (PrestimeCPUCCTNode)value;\n                    threadsSelector.removeThread(thread.getThreadId());\n                }\n            });\n            \n            JMenu expand = new JMenu(CPUView.EXPAND_MENU);\n            popup.add(expand);\n            \n            expand.add(new JMenuItem(CPUView.EXPAND_PLAIN_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.expandPlainPath(ttable.getSelectedRow(), 2);\n                }\n            });\n            \n            expand.add(new JMenuItem(CPUView.EXPAND_TOPMOST_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.expandFirstPath(ttable.getSelectedRow());\n                }\n            });\n            \n            expand.addSeparator();\n            \n            expand.add(new JMenuItem(CPUView.COLLAPSE_CHILDREN_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.collapseChildren(ttable.getSelectedRow());\n                }\n            });\n            \n            expand.add(new JMenuItem(CPUView.COLLAPSE_ALL_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.collapseAll();\n                }\n            });\n        } else if (invoker == hotSpotsView) {\n            // Ugly hack - there's a space between method name and parameters\n            final String searchString = value.toString().replace(\"(\", \" (\"); // NOI18N\n            \n            popup.add(new JMenuItem(CPUView.FIND_IN_FORWARDCALLS) {\n                { setEnabled(userValue != null); }\n                protected void fireActionPerformed(ActionEvent e) {\n                    ProfilerTable table = forwardCallsView.getResultsComponent();\n                    if (SearchUtils.findString(table, searchString)) {\n                        toggles[0].setSelected(true);\n                        forwardCallsView.setVisible(true);\n                        table.requestFocusInWindow();\n                    }\n                }\n            });\n            \n            popup.add(new JMenuItem(CPUView.FIND_IN_REVERSECALLS) {\n                { setEnabled(userValue != null); }\n                protected void fireActionPerformed(ActionEvent e) {\n                    ProfilerTreeTable table = (ProfilerTreeTable)reverseCallsView.getResultsComponent();\n                    if (SearchUtils.findString(table, searchString, true, true, createSearchHelper())) {\n                        toggles[2].setSelected(true);\n                        reverseCallsView.setVisible(true);\n                        table.requestFocusInWindow();\n                    }\n                }\n            });\n        } else if (invoker == reverseCallsView) {\n            final ProfilerTreeTable ttable = (ProfilerTreeTable)reverseCallsView.getResultsComponent();\n            int column = ttable.convertColumnIndexToView(ttable.getMainColumn());\n            final String searchString = ttable.getStringValue((TreeNode)value, column);\n            \n            popup.add(new JMenuItem(CPUView.FIND_IN_FORWARDCALLS) {\n                { setEnabled(userValue != null); }\n                protected void fireActionPerformed(ActionEvent e) {\n                    ProfilerTable table = forwardCallsView.getResultsComponent();\n                    if (SearchUtils.findString(table, searchString)) {\n                        toggles[0].setSelected(true);\n                        forwardCallsView.setVisible(true);\n                        table.requestFocusInWindow();\n                    }\n                }\n            });\n            \n            popup.add(new JMenuItem(CPUView.FIND_IN_HOTSPOTS) {\n                { setEnabled(userValue != null); }\n                protected void fireActionPerformed(ActionEvent e) {\n                    ProfilerTable table = hotSpotsView.getResultsComponent();\n                    if (SearchUtils.findString(table, searchString)) {\n                        toggles[1].setSelected(true);\n                        hotSpotsView.setVisible(true);\n                        table.requestFocusInWindow();\n                    }\n                }\n            });\n            \n            popup.addSeparator();\n            \n            JMenu threads = new JMenu(CPUView.SHOW_MENU);\n            popup.add(threads);\n            \n            threads.add(new JMenuItem(CPUView.SHOW_THREAD_ITEM) {\n                {\n                    setEnabled(!mergedThreads && threadsSelector != null && value instanceof PrestimeCPUCCTNode &&\n                              snapshot.getNThreads() > 1 && (selectedThreads == null || selectedThreads.size() > 1));\n                }\n                protected void fireActionPerformed(ActionEvent e) {\n                    PrestimeCPUCCTNode thread = (PrestimeCPUCCTNode)value;\n                    threadsSelector.addThread(thread.getThreadId(), true);\n                }\n            });\n            \n            threads.add(new JMenuItem(CPUView.HIDE_THREAD_ITEM) {\n                {\n                    setEnabled(!mergedThreads && threadsSelector != null && value instanceof PrestimeCPUCCTNode &&\n                              snapshot.getNThreads() > 1 && (selectedThreads == null || selectedThreads.size() > 1));\n                }\n                protected void fireActionPerformed(ActionEvent e) {\n                    PrestimeCPUCCTNode thread = (PrestimeCPUCCTNode)value;\n                    threadsSelector.removeThread(thread.getThreadId());\n                }\n            });\n            \n            JMenu expand = new JMenu(CPUView.EXPAND_MENU);\n            popup.add(expand);\n            \n            expand.add(new JMenuItem(CPUView.EXPAND_PLAIN_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.expandPlainPath(ttable.getSelectedRow(), 1);\n                }\n            });\n            \n            expand.add(new JMenuItem(CPUView.EXPAND_TOPMOST_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.expandFirstPath(ttable.getSelectedRow());\n                }\n            });\n            \n            expand.addSeparator();\n            \n            expand.add(new JMenuItem(CPUView.COLLAPSE_CHILDREN_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.collapseChildren(ttable.getSelectedRow());\n                }\n            });\n            \n            expand.add(new JMenuItem(CPUView.COLLAPSE_ALL_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.collapseAll();\n                }\n            });\n        }\n        \n        popup.addSeparator();\n        popup.add(invoker.createCopyMenuItem());\n        \n        popup.addSeparator();\n        popup.add(new JMenuItem(FilterUtils.ACTION_FILTER) {\n            protected void fireActionPerformed(ActionEvent e) { invoker.activateFilter(); }\n        });\n        popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {\n            protected void fireActionPerformed(ActionEvent e) { invoker.activateSearch(); }\n        });\n        \n    }\n    \n    private static SearchUtils.TreeHelper createSearchHelper() {\n        return new SearchUtils.TreeHelper() {\n            public int getNodeType(TreeNode tnode) {\n                PrestimeCPUCCTNode node = (PrestimeCPUCCTNode)tnode;\n                CCTNode parent = node.getParent();\n                if (parent == null) return SearchUtils.TreeHelper.NODE_SKIP_DOWN; // invisible root\n                \n                if (node.isThreadNode()) return SearchUtils.TreeHelper.NODE_SKIP_DOWN; // thread node\n                if (node.isSelfTimeNode()) return SearchUtils.TreeHelper.NODE_SKIP_NEXT; // self time node\n                \n                if (((PrestimeCPUCCTNode)parent).isThreadNode() || // toplevel method node (children of thread)\n                    parent.getParent() == null) {                  // toplevel method node (merged threads)\n                    return SearchUtils.TreeHelper.NODE_SEARCH_NEXT;\n                }\n                \n                return SearchUtils.TreeHelper.NODE_SKIP_NEXT; // reverse call tree node\n            }\n        };\n    }\n    \n    protected void customizeNodePopup(DataView invoker, JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {}\n    \n    private void setView(boolean forwardCalls, boolean hotSpots, boolean reverseCalls) {\n        forwardCallsView.setVisible(forwardCalls);\n        hotSpotsView.setVisible(hotSpots);\n        reverseCallsView.setVisible(reverseCalls);\n    }\n    \n    private void setAggregation(int _aggregation) {\n        aggregation = _aggregation;\n        \n        getExecutor().submit(new Runnable() {\n            public void run() {\n                final CPUResultsSnapshot _snapshot = refSnapshot == null ? snapshot :\n                                               snapshot.createDiff(refSnapshot);\n\n                final FlatProfileContainer flatData = _snapshot.getFlatProfile(selectedThreads, aggregation);\n\n                final Map<Integer, ClientUtils.SourceCodeSelection> idMap = _snapshot.getMethodIDMap(aggregation);\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        boolean diff = _snapshot instanceof CPUResultsDiff;\n                        forwardCallsView.setData(_snapshot, idMap, aggregation, selectedThreads, mergedThreads, sampled, diff);\n                        hotSpotsView.setData(flatData, idMap, sampled, diff);\n                        reverseCallsView.setData(_snapshot, idMap, aggregation, selectedThreads, mergedThreads, sampled, diff);\n                    }\n                });\n            }\n        });\n    }\n    \n    protected final void setSnapshot(CPUResultsSnapshot snapshot, boolean sampled) {\n        this.snapshot = snapshot;\n        this.sampled = sampled;\n        \n        setAggregation(aggregation);\n    }\n    \n    private ExportUtils.Exportable[] getExportables(final ExportUtils.Exportable snapshotExporter) {\n        return new ExportUtils.Exportable[] {\n            new ExportUtils.Exportable() {\n                public boolean isEnabled() {\n                    return refSnapshot == null && snapshotExporter.isEnabled();\n                }\n                public String getName() {\n                    return snapshotExporter.getName();\n                }\n                public ExportUtils.ExportProvider[] getProviders() {\n                    return snapshotExporter.getProviders();\n                }\n            },\n            new ExportUtils.Exportable() {\n                public boolean isEnabled() {\n                    return forwardCallsView.isVisible();\n                }\n                public String getName() {\n                    return MessageFormat.format(CPUView.EXPORT_METHODS, CPUView.EXPORT_FORWARD_CALLS);\n                }\n                public ExportUtils.ExportProvider[] getProviders() {\n                    return forwardCallsView.getExportProviders();\n                }\n            },\n            new ExportUtils.Exportable() {\n                public boolean isEnabled() {\n                    return hotSpotsView.isVisible();\n                }\n                public String getName() {\n                    return MessageFormat.format(CPUView.EXPORT_METHODS, CPUView.EXPORT_HOTSPOTS);\n                }\n                public ExportUtils.ExportProvider[] getProviders() {\n                    return hotSpotsView.getExportProviders();\n                }\n            },\n            new ExportUtils.Exportable() {\n                public boolean isEnabled() {\n                    return reverseCallsView.isVisible();\n                }\n                public String getName() {\n                    return MessageFormat.format(CPUView.EXPORT_METHODS, CPUView.EXPORT_REVERSE_CALLS);\n                }\n                public ExportUtils.ExportProvider[] getProviders() {\n                    return reverseCallsView.getExportProviders();\n                }\n            }\n        };\n    }\n    \n    private synchronized ExecutorService getExecutor() {\n        if (executor == null) executor = Executors.newSingleThreadExecutor();\n        return executor;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/SnapshotFlatProfilePanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.image.BufferedImage;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.FilterComponent;\n\n\n/**\n * A display containing a flat profile (always appears together with CCT)\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic class SnapshotFlatProfilePanel extends FlatProfilePanel implements ScreenshotProvider {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private CPUResultsSnapshot snapshot;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SnapshotFlatProfilePanel(CPUResUserActionsHandler actionsHandler, Boolean sampling) {\n        this(actionsHandler, null, sampling);\n    }\n\n    public SnapshotFlatProfilePanel(CPUResUserActionsHandler actionsHandler, CPUSelectionHandler selectionHandler, Boolean sampling) {\n        super(actionsHandler, selectionHandler, sampling);\n    }\n\n    public void exportData(int exportedFileType, ExportDataDumper eDD, boolean combine, String viewName) {\n        percentFormat.setMinimumFractionDigits(2);\n        percentFormat.setMaximumFractionDigits(2);\n        switch (exportedFileType) {\n            case 1: exportCSV(\",\", eDD,combine); break; // normal CSV\n            case 2: exportCSV(\";\", eDD,combine); break; // Excel CSV\n            case 3: exportXML(eDD, combine, viewName); break;\n            case 4: exportHTML(eDD, combine, viewName); break;\n        }\n        percentFormat.setMinimumFractionDigits(0);\n        percentFormat.setMaximumFractionDigits(1);\n    }\n\n    private void exportHTML(ExportDataDumper eDD, boolean combine, String viewName) {\n         // Header\n        StringBuffer result;\n        boolean iCTTS = flatProfileContainer.isCollectingTwoTimeStamps();\n        if (!combine) {\n            result = new StringBuffer(\"<HTML><HEAD><meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" /><TITLE>\"+viewName+\"</TITLE><style type=\\\"text/css\\\">pre.method{overflow:auto;width:600;height:30;vertical-align:baseline}pre.parent{overflow:auto;width:400;height:30;vertical-align:baseline}td.method{text-align:left;width:600}td.parent{text-align:left;width:400}td.right{text-align:right;white-space:nowrap}</style></HEAD><BODY><TABLE border=\\\"1\\\"><tr>\");\n        } else {\n            result = new StringBuffer(\"<br><br><TABLE border=\\\"1\\\"><tr>\"); // NOI18N\n        }\n\n         // NOI18N\n        for (int i = 0; i < (columnCount); i++) {\n            result.append(\"<th>\").append(columnNames[i]).append(columnNames[i].equals(\"Total Time\")?\" [&micro;s]\":\"\").append(\"</th>\");\n        }\n        result.append(\"</tr>\");\n        eDD.dumpData(result);\n\n        for (int i=0; i < flatProfileContainer.getNRows(); i++) {\n            result = new StringBuffer(\"<tr><td class=\\\"method\\\"><pre class=\\\"method\\\">\"+replaceHTMLCharacters(flatProfileContainer.getMethodNameAtRow(i))+\"</pre></td>\");\n            result.append(\"<td class=\\\"right\\\">\").append(percentFormat.format(((double)flatProfileContainer.getPercentAtRow(i))/100)).append(\"</td>\");\n            result.append(\"<td class=\\\"right\\\">\").append((double) flatProfileContainer.getTimeInMcs0AtRow(i)/1000).append(\" ms</td>\");\n            if (iCTTS) {\n                result.append(\"<td class=\\\"right\\\">\").append((double) flatProfileContainer.getTimeInMcs1AtRow(i)/1000).append(\" ms</td>\");\n            }\n            result.append(\"<td class=\\\"right\\\">\").append((double) flatProfileContainer.getTotalTimeInMcs0AtRow(i)/1000).append(\" ms</td>\");\n            if (iCTTS) {\n                result.append(\"<td class=\\\"right\\\">\").append((double) flatProfileContainer.getTotalTimeInMcs1AtRow(i)/1000).append(\" ms</td>\");\n            }\n            result.append(\"<td class=\\\"right\\\">\").append(flatProfileContainer.getNInvocationsAtRow(i)).append(\"</td></tr>\");\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TABLE></BODY></HTML>\"));\n    }\n\n    private void exportXML(ExportDataDumper eDD, boolean combine, String viewName) {\n         // Header\n        String newline = System.lineSeparator();\n        StringBuffer result;\n        boolean iCTTS = flatProfileContainer.isCollectingTwoTimeStamps();\n        if (!combine) {\n            result = new StringBuffer(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"+newline+\"<ExportedView Name=\\\"\"+viewName+\"\\\" type=\\\"table\\\">\"+newline+\" <TableData NumRows=\\\"\"+flatProfileContainer.getNRows()+\"\\\" NumColumns=\\\"4\\\">\"+newline+\"  <TableHeader>\"); // NOI18N\n        } else {\n            result = new StringBuffer(newline+\"<TableData NumRows=\\\"\"+flatProfileContainer.getNRows()+\"\\\" NumColumns=\\\"4\\\">\"+newline+\"  <TableHeader>\"); // NOI18N\n        }\n        for (int i = 0; i < ( columnCount); i++) {\n            result.append(\"   <TableColumn><![CDATA[\").append(columnNames[i]).append(\"]]></TableColumn>\").append(newline);\n        }\n        result.append(\"  </TableHeader>\").append(newline).append(\"  <TableBody>\").append(newline);\n        eDD.dumpData(result);\n\n        for (int i=0; i < flatProfileContainer.getNRows(); i++) {\n            result = new StringBuffer(\"   <TableRow>\"+newline+\"    <TableColumn><![CDATA[\"+flatProfileContainer.getMethodNameAtRow(i)+\"]]></TableColumn>\"+newline);\n            result.append(\"    <TableColumn><![CDATA[\").append(percentFormat.format(((double)flatProfileContainer.getPercentAtRow(i))/100)).append(\"]]></TableColumn>\").append(newline);\n            result.append(\"    <TableColumn><![CDATA[\").append(((double) flatProfileContainer.getTimeInMcs0AtRow(i))/1000).append(\" ms]]></TableColumn>\").append(newline);\n            if (iCTTS) {\n                result.append(\"    <TableColumn><![CDATA[\").append(((double) flatProfileContainer.getTimeInMcs1AtRow(i))/1000).append(\" ms]]></TableColumn>\").append(newline);\n            }\n            result.append(\"    <TableColumn><![CDATA[\").append(((double) flatProfileContainer.getTotalTimeInMcs0AtRow(i))/1000).append(\" ms]]></TableColumn>\").append(newline);\n            if (iCTTS) {\n                result.append(\"    <TableColumn><![CDATA[\").append(((double) flatProfileContainer.getTotalTimeInMcs1AtRow(i))/1000).append(\" ms]]></TableColumn>\").append(newline);\n            }\n            result.append(\"    <TableColumn><![CDATA[\").append(flatProfileContainer.getNInvocationsAtRow(i)).append(\"]]></TableColumn>\").append(newline).append(\"  </TableRow>\").append(newline);\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\"  </TableBody>\"+\" </TableData>\"+newline+\"</ExportedView>\"));\n    }\n\n    private void exportCSV(String separator, ExportDataDumper eDD, boolean combine) {\n        // Header\n        StringBuffer result = new StringBuffer();\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n        boolean iCTTS = flatProfileContainer.isCollectingTwoTimeStamps();\n        if (combine) {\n            result.append(quote).append(quote).append(separator).append(quote).append(quote).append(separator).append(quote).append(quote).append(separator).append(quote).append(quote).append(newLine);\n        }\n        for (int i = 0; i < (columnCount); i++) {\n            result.append(quote).append(columnNames[i]).append(quote).append(separator);\n        }\n        result.deleteCharAt(result.length()-1);\n        result.append(newLine);\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < flatProfileContainer.getNRows(); i++) {\n            result = new StringBuffer();\n            result.append(quote).append(flatProfileContainer.getMethodNameAtRow(i)).append(quote).append(separator);\n            result.append(quote).append(flatProfileContainer.getPercentAtRow(i)).append(quote).append(separator);\n            result.append(quote).append((double)flatProfileContainer.getTimeInMcs0AtRow(i)/1000).append(\" ms\").append(quote).append(separator);\n            if (iCTTS) {\n                result.append(quote).append((double)flatProfileContainer.getTimeInMcs1AtRow(i)/1000).append(\" ms\").append(quote).append(separator);\n            }\n            result.append(quote).append((double)flatProfileContainer.getTotalTimeInMcs0AtRow(i)/1000).append(\" ms\").append(quote).append(separator);\n            if (iCTTS) {\n                result.append(quote).append((double)flatProfileContainer.getTotalTimeInMcs1AtRow(i)/1000).append(\" ms\").append(quote).append(separator);\n            }\n            result.append(quote).append(flatProfileContainer.getNInvocationsAtRow(i)).append(quote).append(newLine);\n            eDD.dumpData(result);\n        }\n        eDD.close();\n    }\n\n    private String replaceHTMLCharacters(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break;\n              case '>': sb.append(\"&gt;\"); break;\n              case '&': sb.append(\"&amp;\"); break;\n              case '\"': sb.append(\"&quot;\"); break;\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public BufferedImage getCurrentViewScreenshot(boolean onlyVisibleArea) {\n        if (resTable == null) {\n            return null;\n        }\n\n        if (onlyVisibleArea) {\n            return UIUtils.createScreenshot(jScrollPane);\n        } else {\n            return UIUtils.createScreenshot(resTable);\n        }\n    }\n\n    /**\n     * This method is supposed to be used for displaying data obtained in a snapshot. threadId is either an actual\n     * threadId &gt;= 0, or -1 to mean \"display data for all threads\". When data is initialized in this way, all operations\n     * such as switching views (aggregation level), obtaining reverse call graph, going to method's source, are allowed.\n     */\n    public void setDataToDisplay(CPUResultsSnapshot snapshot, int threadId, int view) {\n        this.snapshot = snapshot;\n        this.currentView = view;\n        this.threadId = threadId;\n        this.flatProfileContainer = null;\n        collectingTwoTimeStamps = snapshot.isCollectingTwoTimeStamps();\n    }\n\n    public String getDefaultViewName() {\n        return \"cpu-hotspots\";\n    }\n\n    public CPUResultsSnapshot getSnapshot() {\n        return snapshot;\n    }\n\n    public boolean fitsVisibleArea() {\n        return !jScrollPane.getVerticalScrollBar().isEnabled();\n    }\n\n    protected String[] getMethodClassNameAndSig(int methodId, int currentView) {\n        return snapshot.getMethodClassNameAndSig(methodId, currentView);\n    }\n\n    protected void obtainResults() {\n        if (snapshot != null) {\n            flatProfileContainer = snapshot.getFlatProfile(threadId, currentView);\n        }\n        \n        initDataUponResultsFetch();\n\n        // If a now-inapplicable setting remained from previous run, reset it\n        if ((snapshot == null) || (!collectingTwoTimeStamps && (sortBy == FlatProfileContainer.SORT_BY_SECONDARY_TIME))) {\n            sortBy = FlatProfileContainer.SORT_BY_TIME;\n        }\n\n        // Reinit bar max value here - operations necessary for correct bar representation of results\n        flatProfileContainer.filterOriginalData(FilterComponent.getFilterValues(filterString), filterType, valueFilterValue);\n        flatProfileContainer.sortBy(sortBy, sortOrder); // This will actually create the below-used percent()\n                                                        // thing for proper timer\n\n        setResultsAvailable(true);\n    }\n    \n    protected void initDataUponResultsFetch() {}\n\n    protected void showReverseCallGraph(int threadId, int methodId, int currentView, int sortingColumn, boolean sortingOrder) {\n        actionsHandler.showReverseCallGraph(snapshot, threadId, methodId, currentView, sortingColumn, sortingOrder);\n    }\n\n    protected boolean supportsReverseCallGraph() {\n        return true;\n    }\n\n    protected boolean supportsSubtreeCallGraph() {\n        return false;\n    }\n\n    protected void updateResults() {\n        if (threadId < -1) {\n            return; // -1 is reserved for all threads merged flat profile; non-negative numbers are actual thread ids\n        }\n\n        int currentColumnCount = collectingTwoTimeStamps ? 5 : 4;\n\n        if (columnCount != currentColumnCount) {\n            initColumnsData();\n        } else {\n            if (resTable != null) {\n                saveColumnsData();\n            }\n        }\n\n        flatProfileContainer.sortBy(sortBy, sortOrder);\n\n        jScrollPane.setViewportView(resTable);\n        jScrollPane.getViewport().setBackground(resTable.getBackground());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/StatisticsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.FlowLayout;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.Rectangle;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.FocusListener;\nimport java.awt.event.KeyAdapter;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport java.awt.event.MouseMotionAdapter;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.ResourceBundle;\nimport java.util.concurrent.CopyOnWriteArraySet;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.Scrollable;\nimport javax.swing.SwingConstants;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.charts.PieChart;\nimport org.graalvm.visualvm.lib.ui.charts.PieChartModel;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.SnippetPanel;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class StatisticsPanel extends JPanel {\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    public static interface Listener {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void itemClicked(int itemIndex);\n    }\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private class ChartItemPresenter {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        public JLabel valueLabel = new JLabel(\"\"); // NOI18N\n        public JPanel filler = new JPanel(new FlowLayout(0, 0, FlowLayout.LEADING));\n        public KeyboardAwareLabel nameLabel; // NOI18N\n        private ColorIcon colorIcon = new ColorIcon(UIUtils.getProfilerResultsBackground());\n        private PieChartModel model;\n        private int index;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ChartItemPresenter(PieChart pieChart, int index) {\n            this.model = pieChart.getModel();\n            this.index = index;\n\n            initComponents();\n            refresh();\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void refresh() {\n            double percentage = model.getItemValueRel(index);\n\n            if (percentage == 0d) {\n                nameLabel.setVisible(false);\n                valueLabel.setVisible(false);\n            } else {\n                colorIcon.setColor(model.getItemColor(index));\n                nameLabel.setIcon(colorIcon);\n                nameLabel.setText(model.getItemName(index));\n                valueLabel.setText(getRelValue(percentage));\n\n                nameLabel.setVisible(true);\n                valueLabel.setVisible(true);\n            }\n        }\n\n        private String getRelValue(double value) {\n            int percent = (int) Math.floor(value * 100);\n            int permille = (int) Math.round(value * 1000) - (10 * percent);\n\n            return percent + \".\" + permille + \"%\"; // NOI18N\n        }\n\n        private void initComponents() {\n            filler.setOpaque(false);\n            nameLabel = new KeyboardAwareLabel(model.isSelectable(index), () -> {\n                for (Listener l : listeners) {\n                    l.itemClicked(index);\n                }\n            });\n\n            valueLabel.setOpaque(false);\n            valueLabel.setHorizontalAlignment(SwingConstants.TRAILING);\n        }\n    }\n\n    private class ChartPanel extends JPanel {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ChartPanel(PieChart pieChart) {\n            initComponents(pieChart);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        private void initComponents(final PieChart pieChart) {\n            pieChart.setBackground(UIUtils.getProfilerResultsBackground());\n\n            pieChart.addMouseListener(new MouseAdapter() {\n                    @Override\n                    public void mouseClicked(MouseEvent e) {\n                        int clickedItem = pieChart.getItemIndexAt(e.getX(), e.getY());\n\n                        for (Listener l : listeners) {\n                            l.itemClicked(clickedItem);\n                        }\n                    }\n\n                    @Override\n                    public void mouseExited(MouseEvent e) {\n                        pieChart.resetFocusedItem();\n                    }\n                });\n            pieChart.addMouseMotionListener(new MouseMotionAdapter() {\n                    @Override\n                    public void mouseMoved(MouseEvent e) {\n                        int focusedItem = pieChart.getItemIndexAt(e.getX(), e.getY());\n\n                        if ((focusedItem != -1) && pieChart.getModel().isSelectable(focusedItem)) {\n                            pieChart.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n                        } else {\n                            pieChart.setCursor(Cursor.getDefaultCursor());\n                        }\n\n                        pieChart.setFocusedItem(focusedItem);\n                    }\n                });\n\n            setOpaque(false);\n            setBorder(BorderFactory.createEmptyBorder(8, 5, 8, 5));\n            setPreferredSize(new Dimension(240, 220));\n            setMinimumSize(new Dimension(50, 220));\n\n            setLayout(new BorderLayout());\n            add(pieChart, BorderLayout.CENTER);\n        }\n    }\n\n    private static class ColorIcon implements Icon {\n        //~ Static fields/initializers -------------------------------------------------------------------------------------------\n\n        public static final int ICON_SIZE = 9;\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        protected Color color;\n        protected int height;\n        protected int width;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ColorIcon(Color color) {\n            this(ICON_SIZE, ICON_SIZE, color);\n        }\n\n        ColorIcon(int width, int height, Color color) {\n            this.width = width;\n            this.height = height;\n            setColor(color);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void setColor(Color color) {\n            this.color = color;\n        }\n\n        public Color getColor() {\n            return color;\n        }\n\n        public int getIconHeight() {\n            return height;\n        }\n\n        public int getIconWidth() {\n            return width;\n        }\n\n        public void paintIcon(java.awt.Component c, java.awt.Graphics g, int x, int y) {\n            g.setColor(color);\n            g.fillRect(x, y, width, height);\n            g.setColor(Color.BLACK);\n            g.drawRect(x, y, width - 1, height - 1);\n        }\n    }\n\n    private static class Container extends JPanel implements Scrollable {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        Container() {\n            setLayout(new BorderLayout());\n            setOpaque(true);\n            setBackground(UIUtils.getProfilerResultsBackground());\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public Dimension getPreferredScrollableViewportSize() {\n            return new Dimension(250, 500);\n        }\n\n        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {\n            return 50;\n        }\n\n        public boolean getScrollableTracksViewportHeight() {\n            return false;\n        }\n\n        public boolean getScrollableTracksViewportWidth() {\n            return true;\n        }\n\n        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {\n            return 10;\n        }\n    }\n\n    private static class KeyboardAwareLabel extends JLabel {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private String originalText;\n        private boolean isMouseOver;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        KeyboardAwareLabel(final boolean selectable, final Runnable actionPerformer) {\n            super();\n\n            setOpaque(false);\n            setFocusable(true);\n\n            addFocusListener(new FocusListener() {\n                    public void focusGained(FocusEvent e) {\n                        updateText();\n                    }\n\n                    public void focusLost(FocusEvent e) {\n                        updateText();\n                    }\n                });\n\n            addMouseListener(new MouseAdapter() {\n                    public void mouseClicked(MouseEvent e) {\n                        if (selectable) {\n                            requestFocusInWindow();\n                            actionPerformer.run();\n                        }\n                    }\n\n                    public void mouseEntered(MouseEvent e) {\n                        if (selectable) {\n                            isMouseOver = true;\n                            updateText();\n                            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n                        }\n                    }\n\n                    public void mouseExited(MouseEvent e) {\n                        if (selectable) {\n                            isMouseOver = false;\n                            updateText();\n                            setCursor(Cursor.getDefaultCursor());\n                        }\n                    }\n                });\n\n            addKeyListener(new KeyAdapter() {\n                    public void keyPressed(KeyEvent e) {\n                        if (selectable) {\n                            if (e.getKeyCode() == KeyEvent.VK_SPACE) {\n                                actionPerformer.run();\n                            }\n                        }\n                    }\n                });\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void setText(String value) {\n            this.originalText = value;\n            updateText();\n        }\n\n        private void updateText() {\n            setForeground(isFocusOwner() ? Color.RED : UIManager.getColor(\"Label.foreground\")); // NOI18N\n\n            if (isMouseOver) {\n                super.setText(\"<html><nobr><u>\" + originalText + \":\" + \"</u></nobr></html>\"); // NOI18N\n            } else {\n                super.setText(\"<html><nobr>\" + originalText + \":\" + \"</nobr></html>\"); // NOI18N\n            }\n        }\n    }\n\n    private class NavPanel extends JPanel {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private Color lineColor;\n        private Color backgroundColor;\n        private Color focusedBackgroundColor;\n        private final MouseListener focusGrabber = new MouseAdapter() {\n            public void mouseClicked(MouseEvent e) {\n                requestFocusInWindow();\n            }\n        };\n\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        NavPanel(HTMLTextArea navArea) {\n            initColors();\n            initComponents(navArea);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        private void initComponents(HTMLTextArea navArea) {\n            setBackground(backgroundColor);\n            setBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, lineColor),\n                                                         BorderFactory.createEmptyBorder(4, 0, 4, 0)));\n\n            navArea.setHighlighter(null);\n            navArea.setShowPopup(false);\n            navArea.setBorder(BorderFactory.createEmptyBorder());\n            navArea.setOpaque(false);\n            navArea.setFocusable(false);\n\n            GridBagConstraints constraints;\n            setLayout(new GridBagLayout());\n\n            JLabel scopeLabel = new JLabel(SCOPE_LABEL_TEXT);\n            scopeLabel.setFont(UIManager.getFont(\"Label.font\").deriveFont(Font.BOLD)); //NOI18N\n            scopeLabel.setOpaque(false);\n\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 0;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.fill = GridBagConstraints.NONE;\n            constraints.insets = new Insets(1, 5, 1, 5);\n            add(scopeLabel, constraints);\n\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = 0;\n            constraints.weightx = 1;\n            constraints.weighty = 1;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.fill = GridBagConstraints.BOTH;\n            constraints.insets = new Insets(1, 0, 1, 5);\n            add(navArea, constraints);\n\n            setFocusable(true);\n            addFocusListener(new FocusListener() {\n                    public void focusGained(FocusEvent e) {\n                        setBackground(focusedBackgroundColor);\n                    }\n\n                    public void focusLost(FocusEvent e) {\n                        setBackground(backgroundColor);\n                    }\n                });\n\n            addKeyListener(new KeyAdapter() {\n                    public void keyPressed(KeyEvent e) {\n                        if (e.getKeyCode() == KeyEvent.VK_SPACE) {\n                            navigationBackPerformer.run();\n                        }\n                    }\n                });\n\n            addMouseListener(focusGrabber);\n            scopeLabel.addMouseListener(focusGrabber);\n            navArea.addMouseListener(focusGrabber);\n        }\n        \n        private void initColors() {\n            Color systemBackgroundColor = UIUtils.getProfilerResultsBackground();\n\n            int backgroundRed = systemBackgroundColor.getRed(); \n            int backgroundGreen = systemBackgroundColor.getGreen();\n            int backgroundBlue = systemBackgroundColor.getBlue();\n            boolean inverseColors = backgroundRed < 41 || backgroundGreen < 32 || backgroundBlue < 25;\n\n            if (inverseColors) {\n                lineColor = UIUtils.getSafeColor(backgroundRed + 41, backgroundGreen + 32, backgroundBlue + 8);\n                backgroundColor = UIUtils.getSafeColor(backgroundRed + 7, backgroundGreen + 7, backgroundBlue + 7);\n                focusedBackgroundColor = UIUtils.getSafeColor(backgroundRed + 25, backgroundGreen + 25, backgroundBlue + 25);\n            } else {\n                lineColor = UIUtils.getSafeColor(backgroundRed - 41 /*214*/, backgroundGreen - 32 /*223*/, backgroundBlue - 8 /*247*/);\n                backgroundColor = UIUtils.getSafeColor(backgroundRed - 7 /*248*/, backgroundGreen - 7 /*248*/, backgroundBlue - 7 /*248*/);\n                focusedBackgroundColor = UIUtils.getSafeColor(backgroundRed - 25 /*230*/, backgroundGreen - 25 /*230*/, backgroundBlue - 25 /*230*/);\n            }\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.cpu.Bundle\"); // NOI18N\n    private static final String SCOPE_LABEL_TEXT = messages.getString(\"StatisticsPanel_ScopeLabelText\"); // NOI18N\n                                                                                                         // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private SnippetPanel.Padding snippetsBottomFiller;\n    private List<ChartItemPresenter> itemPresenters = new ArrayList<>();\n    private List<SnippetPanel> snippets = new ArrayList<>();\n\n    // --- Declarations ----------------------------------------------------------\n    private JPanel container;\n    private JPanel noSnippetsBottomFiller;\n    private NavPanel navPanel;\n    private PieChart pieChart;\n    private Runnable navigationBackPerformer;\n    private Collection<Listener> listeners = new CopyOnWriteArraySet<>();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    // --- Constructors ----------------------------------------------------------\n    public StatisticsPanel(HTMLTextArea navArea, PieChart pieChart, Runnable navigationBackPerformer) {\n        this.pieChart = pieChart;\n        this.navigationBackPerformer = navigationBackPerformer;\n\n        initComponents(navArea, pieChart);\n\n        pieChart.getModel().addChartModelListener(this::updateItemPresenters);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    // --- Listener stuff --------------------------------------------------------\n    public void addListener(Listener listener) {\n        listeners.add(listener);\n    }\n\n    // --- Public interface ------------------------------------------------------\n    public void addSnippet(JComponent component) {\n        SnippetPanel snippet = new SnippetPanel(component.getName(), component);\n        snippet.setOpaque(false);\n        snippets.add(snippet);\n        updateSnippets();\n    }\n\n    public void removeListener(Listener listener) {\n        listeners.remove(listener);\n    }\n\n    public void removeSnippet(JComponent component) {\n        for (int i = 0; i < snippets.size(); i++) {\n            if (snippets.get(i).getContent() == component) {\n                snippets.remove(i);\n\n                break;\n            }\n        }\n\n        updateSnippets();\n    }\n\n    private void initComponents(HTMLTextArea navArea, PieChart pieChart) {\n        noSnippetsBottomFiller = new JPanel(new FlowLayout(0, 0, FlowLayout.LEADING));\n        noSnippetsBottomFiller.setOpaque(false);\n        snippetsBottomFiller = new SnippetPanel.Padding();\n\n        container = new Container();\n\n        GridBagConstraints constraints;\n        container.setLayout(new GridBagLayout());\n\n        navPanel = new NavPanel(navArea);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 0;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.fill = GridBagConstraints.HORIZONTAL;\n        constraints.insets = new Insets(0, 0, 0, 0);\n        container.add(navPanel, constraints);\n\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 1;\n        constraints.weightx = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.fill = GridBagConstraints.HORIZONTAL;\n        constraints.insets = new Insets(5, 0, 5, 0);\n        container.add(new ChartPanel(pieChart), constraints);\n\n        updateItemPresenters();\n\n        JScrollPane contentsScrollPane = new JScrollPane(container, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                                                         JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n        contentsScrollPane.setBorder(BorderFactory.createEmptyBorder());\n        contentsScrollPane.getViewport().setOpaque(true);\n        contentsScrollPane.getViewport().setBackground(UIUtils.getProfilerResultsBackground());\n\n        setLayout(new BorderLayout());\n        add(contentsScrollPane, BorderLayout.CENTER);\n    }\n\n    private void refreshItemPresenters() {\n        for (ChartItemPresenter itemPresenter : itemPresenters) {\n            itemPresenter.refresh();\n        }\n    }\n\n    // --- Private implementation ------------------------------------------------\n    private void repopulateItemPresenters() {\n        for (ChartItemPresenter itemPresenter : itemPresenters) {\n            container.remove(itemPresenter.nameLabel);\n            container.remove(itemPresenter.valueLabel);\n            container.remove(itemPresenter.filler);\n        }\n\n        itemPresenters.clear();\n\n        GridBagConstraints constraints;\n        ChartItemPresenter itemPresenter;\n\n        //    JPanel filler;\n        for (int i = 0; i < pieChart.getModel().getItemCount(); i++) {\n            itemPresenter = new ChartItemPresenter(pieChart, i);\n            itemPresenters.add(itemPresenter);\n\n            int bottomInset = (i == (pieChart.getModel().getItemCount() - 1)) ? 16 : 6;\n\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 2 + i;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.fill = GridBagConstraints.NONE;\n            constraints.insets = new Insets(0, 15, bottomInset, 8);\n            container.add(itemPresenter.nameLabel, constraints);\n\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = 2 + i;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.fill = GridBagConstraints.NONE;\n            constraints.insets = new Insets(0, 22, bottomInset, 0);\n            container.add(itemPresenter.valueLabel, constraints);\n\n            constraints = new GridBagConstraints();\n            constraints.gridx = 2;\n            constraints.gridy = 2 + i;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.insets = new Insets(0, 0, bottomInset, 8);\n            container.add(itemPresenter.filler, constraints);\n        }\n\n        container.revalidate();\n    }\n\n    private void updateItemPresenters() {\n        if (pieChart.getModel().getItemCount() != itemPresenters.size()) {\n            repopulateItemPresenters();\n            updateSnippets();\n        } else {\n            refreshItemPresenters();\n        }\n\n        Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();\n\n        if ((focusOwner != null) && !focusOwner.isShowing()) {\n            navPanel.requestFocusInWindow();\n        }\n    }\n\n    private void updateSnippets() {\n        for (SnippetPanel snippet : snippets) {\n            container.remove(snippet);\n        }\n\n        container.remove(snippetsBottomFiller);\n        container.remove(noSnippetsBottomFiller);\n\n        GridBagConstraints constraints;\n\n        //    SnippetPanel snippet;\n        for (int i = 0; i < snippets.size(); i++) {\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 2 + itemPresenters.size() + i + 1;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.fill = GridBagConstraints.HORIZONTAL;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            container.add(snippets.get(i), constraints);\n        }\n\n        if (snippets.isEmpty()) {\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 2 + itemPresenters.size() + 1;\n            constraints.weighty = 1;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.fill = GridBagConstraints.BOTH;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            container.add(noSnippetsBottomFiller, constraints);\n        } else {\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = 2 + itemPresenters.size() + snippets.size() + 1;\n            constraints.weighty = 1;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.fill = GridBagConstraints.BOTH;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            container.add(snippetsBottomFiller, constraints);\n        }\n\n        container.revalidate();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/SubtreeCallGraphPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.awt.image.BufferedImage;\nimport java.text.MessageFormat;\nimport java.util.HashSet;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.jfluid.results.FilterSortSupport;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNodeBacked;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.FilterComponent;\nimport org.graalvm.visualvm.lib.ui.components.JTreeTable;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelBracketTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.SortableTableModel;\nimport org.graalvm.visualvm.lib.ui.components.tree.EnhancedTreeCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.tree.MethodNameTreeCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.treetable.AbstractTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.ExtendedTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.JTreeTablePanel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.TreeTableModel;\n\n\n/**\n * A display containing reverse call graph\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Jiri Sedlacek\n * @author Jaroslav Bachorik\n */\npublic class SubtreeCallGraphPanel extends SnapshotCPUResultsPanel implements ScreenshotProvider {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.cpu.Bundle\"); // NOI18N\n    private static final String PANEL_TITLE = messages.getString(\"SubtreeCallGraphPanel_PanelTitle\"); // NOI18N\n    private static final String PANEL_TITLE_SHORT = messages.getString(\"SubtreeCallGraphPanel_PanelTitleShort\"); // NOI18N\n    private static final String METHOD_COLUMN_NAME = messages.getString(\"SubtreeCallGraphPanel_MethodColumnName\"); // NOI18N\n    private static final String METHOD_COLUMN_TOOLTIP = messages.getString(\"SubtreeCallGraphPanel_MethodColumnToolTip\"); // NOI18N\n    private static final String METHOD_FILTER_HINT = messages.getString(\"FlatProfilePanel_MethodFilterHint\"); // NOI18N\n    private static final String CLASS_COLUMN_NAME = messages.getString(\"SubtreeCallGraphPanel_ClassColumnName\"); // NOI18N\n    private static final String CLASS_COLUMN_TOOLTIP = messages.getString(\"SubtreeCallGraphPanel_ClassColumnToolTip\"); // NOI18N\n    private static final String CLASS_FILTER_HINT = messages.getString(\"FlatProfilePanel_ClassFilterHint\"); // NOI18N\n    private static final String PACKAGE_COLUMN_NAME = messages.getString(\"SubtreeCallGraphPanel_PackageColumnName\"); // NOI18N\n    private static final String PACKAGE_COLUMN_TOOLTIP = messages.getString(\"SubtreeCallGraphPanel_PackageColumnToolTip\"); // NOI18N\n    private static final String PACKAGE_FILTER_HINT = messages.getString(\"FlatProfilePanel_PackageFilterHint\"); // NOI18N\n    private static final String TIME_REL_COLUMN_NAME = messages.getString(\"SubtreeCallGraphPanel_TimeRelColumnName\"); // NOI18N\n    private static final String TIME_REL_COLUMN_TOOLTIP = messages.getString(\"SubtreeCallGraphPanel_TimeRelColumnToolTip\"); // NOI18N\n    private static final String TIME_COLUMN_NAME = messages.getString(\"SubtreeCallGraphPanel_TimeColumnName\"); // NOI18N\n    private static final String TIME_COLUMN_TOOLTIP = messages.getString(\"SubtreeCallGraphPanel_TimeColumnToolTip\"); // NOI18N\n    private static final String TIME_CPU_COLUMN_NAME = messages.getString(\"SubtreeCallGraphPanel_TimeCpuColumnName\"); // NOI18N\n    private static final String TIME_CPU_COLUMN_TOOLTIP = messages.getString(\"SubtreeCallGraphPanel_TimeCpuColumnToolTip\"); // NOI18N\n    private static final String INVOCATIONS_COLUMN_NAME = messages.getString(\"SubtreeCallGraphPanel_InvocationsColumnName\"); // NOI18N\n    private static final String INVOCATIONS_COLUMN_TOOLTIP = messages.getString(\"SubtreeCallGraphPanel_InvocationsColumnToolTip\"); // NOI18N\n    private static final String TREETABLE_ACCESS_NAME = messages.getString(\"SubtreeCallGraphPanel_TreeTableAccessName\"); // NOI18N\n    private static final String FILTER_ITEM_NAME = messages.getString(\"FlatProfilePanel_FilterItemName\"); // NOI18N\n    private static final String SAMPLES_COLUMN_NAME = messages.getString(\"CCTDisplay_SamplesColumnName\"); // NOI18N\n    private static final String SAMPLES_COLUMN_TOOLTIP = messages.getString(\"CCTDisplay_SamplesColumnToolTip\"); // NOI18N\n                                                                                                                         // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected JButton cornerButton;\n    protected JTreeTable treeTable;\n    protected JTreeTablePanel treeTablePanel;\n    protected FilterComponent filterComponent;\n    protected PrestimeCPUCCTNode rootNode = null;\n    protected boolean sortOrder;\n    protected int sortingColumn;\n    private AbstractTreeTableModel abstractTreeTableModel;\n    private EnhancedTreeCellRenderer enhancedTreeCellRenderer = new MethodNameTreeCellRenderer();\n    private ExtendedTreeTableModel treeTableModel;\n    private Icon leafIcon = Icons.getIcon(ProfilerIcons.NODE_LEAF);\n    private Icon nodeIcon = Icons.getIcon(ProfilerIcons.NODE_FORWARD);\n    private int minNamesColumnWidth; // minimal width of classnames columns\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SubtreeCallGraphPanel(CPUResUserActionsHandler actionsHandler, Boolean sampling) {\n        super(actionsHandler, sampling);\n\n        enhancedTreeCellRenderer.setLeafIcon(leafIcon);\n        enhancedTreeCellRenderer.setClosedIcon(nodeIcon);\n        enhancedTreeCellRenderer.setOpenIcon(nodeIcon);\n\n        minNamesColumnWidth = getFontMetrics(getFont()).charWidth('W') * 30; // NOI18N\n\n        cornerPopup = new JPopupMenu();\n        cornerButton = createHeaderPopupCornerButton(cornerPopup);\n\n        setDefaultSorting();\n    }\n\n    public void exportData(int exportedFileType, ExportDataDumper eDD, String viewName) {\n        percentFormat.setMaximumFractionDigits(2);\n        percentFormat.setMinimumFractionDigits(2);\n        PrestimeCPUCCTNodeBacked.setPercentFormat(percentFormat);\n        switch (exportedFileType) {\n            case 1: eDD.dumpData(getCSVHeader(\",\")); //NOI18N\n                    ((PrestimeCPUCCTNodeBacked)abstractTreeTableModel.getRoot()).exportCSVData(\",\",exportedFileType, eDD);\n                    eDD.close();\n                    break;\n            case 2: eDD.dumpData(getCSVHeader(\";\")); //NOI18N\n                    ((PrestimeCPUCCTNodeBacked)abstractTreeTableModel.getRoot()).exportCSVData(\";\", exportedFileType, eDD);\n                    eDD.close();\n                    break;\n            case 3: eDD.dumpData(getXMLHeader(viewName));\n                    ((PrestimeCPUCCTNodeBacked)abstractTreeTableModel.getRoot()).exportXMLData(eDD, \"  \");\n                    eDD.dumpDataAndClose(getXMLFooter());\n                    break;\n            case 4: eDD.dumpData(getHTMLHeader(viewName));\n                    ((PrestimeCPUCCTNodeBacked)abstractTreeTableModel.getRoot()).exportHTMLData(eDD, 0);\n                    eDD.dumpDataAndClose(getHTMLFooter());\n                    break;\n        }\n        percentFormat.setMaximumFractionDigits(1);\n        percentFormat.setMinimumFractionDigits(0);\n    }\n\n    private StringBuffer getCSVHeader(String separator) {\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n        StringBuffer result = new StringBuffer();\n        for (int i = 0; i < (columnCount); i++) {\n            result.append(quote).append(columnNames[i]).append(quote).append(separator);\n        }\n        result.append(newLine);\n        return result;\n    }\n\n    private StringBuffer getHTMLHeader(String viewName) {\n        StringBuffer result = new StringBuffer(\"<HTML><HEAD><meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" /><TITLE>\"+viewName+\"</TITLE><style type=\\\"text/css\\\">pre.method{overflow:auto;width:600;height:30;vertical-align:baseline}pre.parent{overflow:auto;width:400;height:30;vertical-align:baseline}td.method{text-align:left;width:600}td.parent{text-align:left;width:400}td.right{text-align:right;white-space:nowrap}</style></HEAD><BODY><table border=\\\"1\\\"><tr>\"); // NOI18N\n        for (int i = 0; i < columnCount; i++) {\n            result.append(\"<th>\").append(columnNames[i]).append(columnNames[i].equals(\"Total Time\")?\" [&micro;s]\":\"\").append(\"</th>\"); //NOI18N\n        }\n        result.append(\"</tr>\"); //NOI18N\n        return result;\n    }\n\n    private StringBuffer getHTMLFooter() {\n        return new StringBuffer(\"</TABLE></BODY></HTML>\"); //NOI18N\n    }\n\n    private StringBuffer getXMLHeader(String viewName) {\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"+newline+\"<ExportedView Name=\\\"\"+viewName+\"\\\" type=\\\"tree\\\">\"+newline+\"<tree>\"+newline); // NOI18N\n        return result;\n    }\n\n    private StringBuffer getXMLFooter() {\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"</tree>\"+newline+\"</ExportedView>\"); // NOI18N\n        return result;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getCurrentThreadId() {\n        return (rootNode != null) ? rootNode.getThreadId() : 0;\n    }\n\n    public BufferedImage getCurrentViewScreenshot(boolean onlyVisibleArea) {\n        if ((treeTablePanel == null) || (treeTable == null)) {\n            return null;\n        }\n\n        if (onlyVisibleArea) {\n            return UIUtils.createScreenshot(treeTablePanel.getScrollPane());\n        } else {\n            return UIUtils.createScreenshot(treeTable);\n        }\n    }\n\n    public void setDataToDisplay(CPUResultsSnapshot snapshot, PrestimeCPUCCTNode node, int view) {\n        super.setDataToDisplay(snapshot, view);\n        this.rootNode = ((PrestimeCPUCCTNodeBacked)node).createRootCopy();\n        if (popupShowSource != null) popupShowSource.setEnabled(isShowSourceAvailable());\n    }\n\n    // NOTE: this method only sets sortingColumn and sortOrder, it doesn't refresh UI!\n    public void setDefaultSorting() {\n        setSorting(1, SortableTableModel.SORT_ORDER_DESC);\n    }\n\n    public String getDefaultViewName() {\n        return \"cpu-subtree\"; // NOI18N\n    }\n\n    // --- Find functionality stuff\n    public void setFindString(String findString) {\n        treeTable.setFindParameters(findString, 0);\n    }\n\n    public String getFindString() {\n        return treeTable.getFindString();\n    }\n\n    public boolean isFindStringDefined() {\n        return treeTable.isFindStringDefined();\n    }\n\n    public String getSelectedMethodName() {\n        int selectedMethodId = rootNode.getMethodId();\n        String name = snapshot.getInstrMethodClasses(currentView)[selectedMethodId];\n\n        if (currentView == CPUResultsSnapshot.METHOD_LEVEL_VIEW) {\n            name += (\".\" + snapshot.getInstrMethodNames()[selectedMethodId]\n                    + snapshot.getInstrMethodSignatures()[selectedMethodId]);\n        }\n\n        return name;\n    }\n\n    public String getSelectedMethodNameShort() {\n        int selectedMethodId = rootNode.getMethodId();\n\n        if (currentView == CPUResultsSnapshot.METHOD_LEVEL_VIEW) {\n            return snapshot.getInstrMethodNames()[selectedMethodId];\n        } else {\n            return snapshot.getInstrMethodClasses(currentView)[selectedMethodId];\n        }\n    }\n\n    public String getSelectedThreadName() {\n        int threadId = rootNode.getThreadId();\n\n        return snapshot.getThreadNameForId(threadId);\n    }\n\n    public String getShortTitle() {\n        return MessageFormat.format(PANEL_TITLE_SHORT, getSelectedThreadName(), getSelectedMethodNameShort());\n    }\n\n    // NOTE: this method only sets sortingColumn and sortOrder, it doesn't refresh UI!\n    public void setSorting(int sColumn, boolean sOrder) {\n        if (sColumn == CommonConstants.SORTING_COLUMN_DEFAULT) {\n            setDefaultSorting();\n        } else {\n            sortingColumn = sColumn;\n            sortOrder = sOrder;\n        }\n    }\n\n    public int getSortingColumn() {\n        return sortingColumn;\n    }\n\n    public boolean getSortingOrder() {\n        return sortOrder;\n    }\n\n    public String getTitle() {\n        return MessageFormat.format(PANEL_TITLE, getSelectedThreadName(), getSelectedMethodName());\n    }\n\n    public boolean findFirst() {\n        return treeTable.findFirst();\n    }\n\n    public boolean findNext() {\n        return treeTable.findNext();\n    }\n\n    public boolean findPrevious() {\n        return treeTable.findPrevious();\n    }\n\n    public boolean fitsVisibleArea() {\n        return !treeTablePanel.getScrollPane().getVerticalScrollBar().isEnabled();\n    }\n\n    public void prepareResults() {\n        initColumnsData();\n\n        //    PrestimeCPUCCTNode newRoot = snapshot.getSubtreeCCT(rootNode, currentView);\n        \n        abstractTreeTableModel = new AbstractTreeTableModel(rootNode, sortingColumn, sortOrder) {\n                public int getColumnCount() {\n                    return columnCount;\n                }\n\n                public String getColumnName(int column) {\n                    return columnNames[column];\n                }\n\n                public Class<?> getColumnClass(int column) {\n                    if (column == 0) {\n                        return TreeTableModel.class;\n                    } else {\n                        return Object.class;\n                    }\n                }\n\n                public Object getValueAt(Object node, int column) {\n                    if (!snapshot.isCollectingTwoTimeStamps()) {\n                        if (column > 2) {\n                            column += 1;\n                        }\n                    }\n\n                    PrestimeCPUCCTNode pNode = (PrestimeCPUCCTNode) node;\n\n                    switch (column) {\n                        case 0:\n                            return getNodeName(pNode);\n                        case 1:\n                            return getNodeTimeRel(pNode);\n                        case 2:\n                            return getNodeTime(pNode);\n                        case 3:\n                            return getNodeSecondaryTime(pNode);\n                        case 4:\n                            return getNodeInvocations(pNode);\n                    }\n\n                    return null;\n                }\n\n                public String getColumnToolTipText(int col) {\n                    return columnToolTips[col];\n                }\n\n                private String getNodeName(PrestimeCPUCCTNode pNode) {\n                    return pNode.toString();\n                }\n\n                private Float getNodeTimeRel(PrestimeCPUCCTNode pNode) {\n                    return new Float(pNode.getTotalTime0InPerCent());\n                }\n\n                private String getNodeTime(PrestimeCPUCCTNode pNode) {\n                    return StringUtils.mcsTimeToString(pNode.getTotalTime0()) + \" ms (\" // NOI18N\n                           + percentFormat.format(pNode.getTotalTime0InPerCent() / 100) + \")\"; // NOI18N\n                }\n\n                private String getNodeSecondaryTime(PrestimeCPUCCTNode pNode) {\n                    /*!!! FIX THIS! if (pNode instanceof PresoCPUCCTClassNode) {\n                       PresoCPUCCTClassNode.Extended extNode = (PresoCPUCCTClassNode.Extended)pNode;\n                       return StringUtils.mcsTimeToString(extNode.getTotalTime1()) + \" ms\";\n                       } else {*/\n                    return StringUtils.mcsTimeToString(pNode.getTotalTime1()) + \" ms\"; // NOI18N\n                }\n\n                private Integer getNodeInvocations(PrestimeCPUCCTNode pNode) {\n                    return Integer.valueOf(pNode.getNCalls());\n                }\n\n                public void sortByColumn(int column, boolean order) {\n                    sortOrder = order;\n\n                    if (!snapshot.isCollectingTwoTimeStamps()) {\n                        if (column > 2) {\n                            column += 1;\n                        }\n                    }\n\n                    PrestimeCPUCCTNode pRoot = (PrestimeCPUCCTNode) root;\n\n                    switch (column) {\n                        case 0:\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_NAME, order);\n\n                            break;\n                        case 1:\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_TIME_0, order);\n\n                            break;\n                        case 2:\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_TIME_0, order);\n\n                            break;\n                        case 3:\n                            /*!!! FIX THIS! if (pRoot instanceof PrestimeCPUCCTClassNode) {\n                               pRoot.sortChildren(PrestimeCPUCCTClassNode.Extended.SORT_BY_TIME_1, order);\n                               } else { */\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_TIME_1, order);\n\n                            break;\n                        case 4:\n                            pRoot.sortChildren(PrestimeCPUCCTNode.SORT_BY_INVOCATIONS, order);\n\n                            break;\n                    }\n                }\n\n                public boolean getInitialSorting(int column) {\n                    return (column == 0);\n                }\n            };\n\n        treeTableModel = new ExtendedTreeTableModel(abstractTreeTableModel);\n\n        if (columnsVisibility != null) {\n            treeTableModel.setColumnsVisibility(columnsVisibility);\n        }\n\n        treeTable = new JTreeTable(treeTableModel) {\n                public void doLayout() {\n                    int columnsWidthsSum = 0;\n                    int realFirstColumn = -1;\n\n                    int index;\n                    TableColumnModel colModel = getColumnModel();\n\n                    for (int i = 0; i < treeTableModel.getColumnCount(); i++) {\n                        index = treeTableModel.getRealColumn(i);\n\n                        if (index == 0) {\n                            realFirstColumn = i;\n                        } else {\n                            columnsWidthsSum += colModel.getColumn(i).getPreferredWidth();\n                        }\n                    }\n\n                    if (realFirstColumn != -1) {\n                        colModel.getColumn(realFirstColumn)\n                                .setPreferredWidth(Math.max(getWidth() - columnsWidthsSum, minNamesColumnWidth));\n                    }\n\n                    super.doLayout();\n                }\n\n            };\n        treeTable.getAccessibleContext().setAccessibleName(TREETABLE_ACCESS_NAME);\n\n        treeTable.setRowSelectionAllowed(true);\n        treeTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        treeTable.setGridColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);\n        treeTable.setSelectionBackground(UIConstants.TABLE_SELECTION_BACKGROUND_COLOR);\n        treeTable.setSelectionForeground(UIConstants.TABLE_SELECTION_FOREGROUND_COLOR);\n        treeTable.setShowHorizontalLines(UIConstants.SHOW_TABLE_HORIZONTAL_GRID);\n        treeTable.setShowVerticalLines(UIConstants.SHOW_TABLE_VERTICAL_GRID);\n        treeTable.setRowMargin(UIConstants.TABLE_ROW_MARGIN);\n        treeTable.setRowHeight(UIUtils.getDefaultRowHeight() + 2);\n        treeTable.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)\n                 .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), \"DEFAULT_ACTION\"); // NOI18N\n        treeTable.getActionMap().put(\"DEFAULT_ACTION\",\n                                     new AbstractAction() {\n                public void actionPerformed(ActionEvent e) {\n                    performDefaultAction();\n                }\n            }); // NOI18N\n\n        // Disable traversing table cells using TAB and Shift+TAB\n        Set<AWTKeyStroke> keys = new HashSet<>(treeTable.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));\n        keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));\n        treeTable.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys);\n\n        keys = new HashSet<>(treeTable.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));\n        keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));\n        treeTable.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys);\n\n        setColumnsData();\n\n        UIUtils.autoExpandRoot(treeTable.getTree(), 2);\n        UIUtils.makeTreeAutoExpandable(treeTable.getTree(), 2);\n\n        treeTable.addKeyListener(new KeyAdapter() {\n                public void keyPressed(KeyEvent e) {\n                    if ((e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU)\n                            || ((e.getKeyCode() == KeyEvent.VK_F10) && (e.getModifiers() == InputEvent.SHIFT_MASK))) {\n                        int selectedRow = treeTable.getSelectedRow();\n\n                        if (selectedRow != -1) {\n                            popupPath = treeTable.getTree().getPathForRow(selectedRow);\n                            \n                            PrestimeCPUCCTNode node = (PrestimeCPUCCTNode) popupPath.getLastPathComponent();\n                            enableDisablePopup(node);\n\n                            Rectangle cellRect = treeTable.getCellRect(selectedRow, 0, false);\n                            callGraphPopupMenu.show(e.getComponent(), ((cellRect.x + treeTable.getSize().width) > 50) ? 50 : 5,\n                                                    cellRect.y);\n                        }\n                    }\n                }\n            });\n\n        treeTable.addMouseListener(new MouseAdapter() {\n                private void showPopupMenu(MouseEvent e) {\n                    popupPath = treeTable.getTree().getPathForRow(treeTable.rowAtPoint(e.getPoint()));\n\n                    if (popupPath == null) {\n                            treeTable.getTree().clearSelection();\n                    } else {\n                        treeTable.getTree().setSelectionPath(popupPath);\n                        PrestimeCPUCCTNode node = (PrestimeCPUCCTNode) popupPath.getLastPathComponent();\n                        enableDisablePopup(node);\n                        callGraphPopupMenu.show(e.getComponent(), e.getX(), e.getY());\n                    }\n                }\n\n                public void mousePressed(MouseEvent e) {\n                    if (e.isPopupTrigger()) showPopupMenu(e);\n                }\n\n                public void mouseReleased(MouseEvent e) {\n                    if (e.isPopupTrigger()) showPopupMenu(e);\n                }\n\n                public void mouseClicked(MouseEvent e) {\n                    popupPath = treeTable.getTree().getPathForRow(treeTable.rowAtPoint(e.getPoint()));\n\n                    if (popupPath != null) {\n                        treeTable.getTree().setSelectionPath(popupPath);\n                        if (SwingUtilities.isLeftMouseButton(e) && (e.getClickCount() == 2)) {\n                            if (treeTableModel.isLeaf(popupPath.getPath()[popupPath.getPath().length - 1])) {\n                                showSourceForMethod(popupPath);\n                            }\n                        }\n                    }\n                }\n            });\n\n        treeTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent e) {\n                    int selectedRow = treeTable.getSelectedRow();\n\n                    if (selectedRow == -1) {\n                        return;\n                    }\n\n                    popupPath = treeTable.getTree().getPathForRow(selectedRow);\n                }\n            });\n\n        treeTablePanel = new JTreeTablePanel(treeTable);\n        treeTablePanel.setCorner(JScrollPane.UPPER_RIGHT_CORNER, cornerButton);\n        treeTablePanel.clearBorders();\n        add(treeTablePanel, BorderLayout.CENTER);\n        initFilterPanel();\n        initFirstColumnName();\n    }\n    \n    private void initFilterPanel() {\n        filterComponent = FilterComponent.create(true, true);\n        \n        FilterSortSupport.Configuration config = snapshot.getFilterSortInfo(\n                (PrestimeCPUCCTNode)treeTableModel.getRoot());\n        filterComponent.setFilter(config.getFilterString(), config.getFilterType());\n\n        filterComponent.addChangeListener(new ChangeListener() {\n                public void stateChanged(ChangeEvent e) {\n                    String filterString = filterComponent.getFilterValue();\n                    int filterType = filterComponent.getFilterType();\n                    snapshot.filterForward(filterString, filterType, (PrestimeCPUCCTNodeBacked)treeTableModel.getRoot());\n//                    SwingUtilities.invokeLater(new Runnable() {\n//            public void run() {\n                    treeTable.updateTreeTable();\n//            }});\n                }\n            });\n\n        add(filterComponent.getComponent(), BorderLayout.SOUTH);\n    }\n\n    public void requestFocus() {\n        if (treeTable != null) {\n            SwingUtilities.invokeLater(new Runnable() { // must be invoked lazily to override default focus of first component (top-right cornerButton)\n                    public void run() {\n                        treeTable.requestFocus();\n                    }\n                });\n        }\n    }\n\n    public void reset() {\n        if (treeTablePanel != null) {\n            remove(treeTablePanel);\n            treeTablePanel = null;\n            remove(filterComponent.getComponent());\n            filterComponent = null;\n        }\n\n        treeTable = null;\n        abstractTreeTableModel = null;\n        treeTableModel = null;\n    }\n\n    protected boolean isCloseable() {\n        return true;\n    }\n\n    protected void initColumnSelectorItems() {\n        cornerPopup.removeAll();\n\n        JCheckBoxMenuItem menuItem;\n\n        for (int i = 0; i < columnCount; i++) {\n            menuItem = new JCheckBoxMenuItem(columnNames[i]);\n            menuItem.setActionCommand(Integer.toString(i));\n            addMenuItemListener(menuItem);\n\n            if (treeTable != null) {\n                menuItem.setState(treeTableModel.isRealColumnVisible(i));\n\n                if (i == 0) {\n                    menuItem.setEnabled(false);\n                }\n            } else {\n                menuItem.setState(true);\n            }\n\n            cornerPopup.add(menuItem);\n        }\n        \n        cornerPopup.addSeparator();\n\n        JCheckBoxMenuItem filterMenuItem = new JCheckBoxMenuItem(FILTER_ITEM_NAME);\n        filterMenuItem.setActionCommand(\"Filter\"); // NOI18N\n        addMenuItemListener(filterMenuItem);\n\n        if (filterComponent == null) {\n            filterMenuItem.setState(true);\n        } else {\n            filterMenuItem.setState(filterComponent.getComponent().isVisible());\n        }\n        \n        cornerPopup.add(filterMenuItem);\n\n        cornerPopup.pack();\n    }\n\n    private void setColumnsData() {\n        int index;\n        TableColumnModel colModel = treeTable.getColumnModel();\n\n        treeTable.setTreeCellRenderer(enhancedTreeCellRenderer);\n        colModel.getColumn(0).setPreferredWidth(minNamesColumnWidth);\n\n        for (int i = 0; i < treeTableModel.getColumnCount(); i++) {\n            index = treeTableModel.getRealColumn(i);\n\n            if (index != 0) {\n                colModel.getColumn(i).setPreferredWidth(columnWidths[index - 1]);\n                colModel.getColumn(i).setCellRenderer(columnRenderers[index]);\n            }\n        }\n    }\n\n    //  protected JPopupMenu createPopupMenu() {\n    //    JPopupMenu popup = new JPopupMenu();\n    //    popupShowSource = new JMenuItem();\n    //    popupShowSubtree = new JMenuItem();\n    //    popupShowReverse = new JMenuItem();\n    //    popupAddToRoots = new JMenuItem();\n    //\n    //    Font boldfont = popup.getFont ().deriveFont(Font.BOLD);\n    //\n    //    popupShowSource.setFont(boldfont);\n    //    popupShowSource.setText(GO_TO_SOURCE_POPUP_ITEM);\n    //    popup.add(popupShowSource);\n    //\n    //    popup.addSeparator();\n    //\n    //    popupAddToRoots.setText(ADD_ROOT_METHOD_POPUP_ITEM);\n    //    popup.add(popupAddToRoots);\n    //\n    //    ActionListener menuListener = new ActionListener() {\n    //      public void actionPerformed(ActionEvent evt) {\n    //        menuActionPerformed(evt);\n    //      }\n    //    };\n    //\n    //    popupShowSource.addActionListener(menuListener);\n    //    popupAddToRoots.addActionListener(menuListener);\n    //\n    //    return popup;\n    //  }\n    private void addMenuItemListener(JCheckBoxMenuItem menuItem) {\n        menuItem.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    if (e.getActionCommand().equals(\"Filter\")) { // NOI18N\n                        filterComponent.getComponent().setVisible(!filterComponent.getComponent().isVisible());\n\n                        return;\n                    }\n                    \n                    boolean sortResults = false;\n                    int column = Integer.parseInt(e.getActionCommand());\n                    boolean sortOrder = treeTable.getSortingOrder();\n                    int sortingColumn = treeTable.getSortingColumn();\n                    int realSortingColumn = treeTableModel.getRealColumn(sortingColumn);\n                    boolean isColumnVisible = treeTableModel.isRealColumnVisible(column);\n\n                    // Current sorting column is going to be hidden\n                    if ((isColumnVisible) && (column == realSortingColumn)) {\n                        // Try to set next column as a sortingColumn. If currentSortingColumn is the last column, set previous\n                        // column as a sorting Column (one column is always visible).\n                        sortingColumn = ((sortingColumn + 1) == treeTableModel.getColumnCount()) ? (sortingColumn - 1)\n                                                                                                 : (sortingColumn + 1);\n                        realSortingColumn = treeTableModel.getRealColumn(sortingColumn);\n                        sortResults = true;\n                    }\n\n                    treeTableModel.setRealColumnVisibility(column, !isColumnVisible);\n                    treeTable.createDefaultColumnsFromModel();\n                    treeTable.updateTreeTableHeader();\n                    sortingColumn = treeTableModel.getVirtualColumn(realSortingColumn);\n\n                    if (sortResults) {\n                        sortOrder = treeTableModel.getInitialSorting(sortingColumn);\n                        treeTableModel.sortByColumn(sortingColumn, sortOrder);\n                        treeTable.updateTreeTable();\n                    }\n\n                    treeTable.setSortingColumn(sortingColumn);\n                    treeTable.setSortingOrder(sortOrder);\n                    treeTable.getTableHeader().repaint();\n                    setColumnsData();\n\n                    // TODO [ui-persistence]\n                }\n            });\n    }\n    \n    private void enableDisablePopup(PrestimeCPUCCTNode node) {\n        boolean regularNode = node.getThreadId() != -1 && node.getMethodId() != 0 && !node.isFiltered();\n        if (popupShowSource != null) popupShowSource.setEnabled(regularNode && isShowSourceAvailable());\n        if (popupShowSubtree != null) popupShowSubtree.setEnabled(regularNode);\n        if (popupShowReverse != null) popupShowReverse.setEnabled(regularNode);\n        popupFind.setEnabled(regularNode);\n    }\n\n    private void initColumnsData() {\n        columnCount = snapshot.isCollectingTwoTimeStamps() ? 5 : 4;\n\n        columnWidths = new int[columnCount - 1]; // Width of the first column fits to width\n        columnNames = new String[columnCount];\n        columnRenderers = new TableCellRenderer[columnCount];\n        columnsVisibility = new boolean[columnCount];\n        for (int i = 0; i < columnCount - 1; i++)\n            columnsVisibility[i] = true;\n        if (isSampling() != null && !isSampling())\n            columnsVisibility[columnCount - 1] = true;\n\n        if (columnCount == 5) {\n            columnNames = new String[] {\n                              METHOD_COLUMN_NAME, TIME_REL_COLUMN_NAME, TIME_COLUMN_NAME, TIME_CPU_COLUMN_NAME,\n                              INVOCATIONS_COLUMN_NAME\n                          };\n            columnToolTips = new String[] {\n                                 METHOD_COLUMN_TOOLTIP, TIME_REL_COLUMN_TOOLTIP, TIME_COLUMN_TOOLTIP, TIME_CPU_COLUMN_TOOLTIP,\n                                 INVOCATIONS_COLUMN_TOOLTIP\n                             };\n        } else {\n            columnNames = new String[] { METHOD_COLUMN_NAME, TIME_REL_COLUMN_NAME, TIME_COLUMN_NAME, INVOCATIONS_COLUMN_NAME };\n            columnToolTips = new String[] {\n                                 METHOD_COLUMN_TOOLTIP, TIME_REL_COLUMN_TOOLTIP, TIME_COLUMN_TOOLTIP, INVOCATIONS_COLUMN_TOOLTIP\n                             };\n        }\n        \n        if (isSampling() != null && isSampling()) {\n            columnNames[columnCount - 1] = SAMPLES_COLUMN_NAME;\n            columnToolTips[columnCount - 1] = SAMPLES_COLUMN_TOOLTIP;\n        }\n\n        int maxWidth = getFontMetrics(getFont()).charWidth('W') * 12; // NOI18N // initial width of data columns\n\n        CustomBarCellRenderer customBarCellRenderer = new CustomBarCellRenderer(0, 100);\n        LabelTableCellRenderer labelTableCellRenderer = new LabelTableCellRenderer(JLabel.TRAILING);\n        LabelBracketTableCellRenderer labelBracketTableCellRenderer = new LabelBracketTableCellRenderer(JLabel.TRAILING);\n\n        columnRenderers[0] = null;\n\n        // Inclusive (total) time bar\n        columnWidths[1 - 1] = maxWidth;\n        columnRenderers[1] = customBarCellRenderer;\n\n        // Inclusive (total) time\n        columnWidths[2 - 1] = maxWidth;\n        columnRenderers[2] = labelBracketTableCellRenderer;\n\n        for (int i = 3; i < columnCount; i++) {\n            columnWidths[i - 1] = maxWidth;\n            columnRenderers[i] = labelTableCellRenderer;\n        }\n        \n        if (isSampling() == null) columnCount--;\n    }\n\n    private void initFirstColumnName() {\n        switch (currentView) {\n            case CPUResultsSnapshot.METHOD_LEVEL_VIEW:\n                columnNames[0] = METHOD_COLUMN_NAME;\n                columnToolTips[0] = METHOD_COLUMN_TOOLTIP;\n                filterComponent.setHint(METHOD_FILTER_HINT);\n\n                break;\n            case CPUResultsSnapshot.CLASS_LEVEL_VIEW:\n                columnNames[0] = CLASS_COLUMN_NAME;\n                columnToolTips[0] = CLASS_COLUMN_TOOLTIP;\n                filterComponent.setHint(CLASS_FILTER_HINT);\n\n                break;\n            case CPUResultsSnapshot.PACKAGE_LEVEL_VIEW:\n                columnNames[0] = PACKAGE_COLUMN_NAME;\n                columnToolTips[0] = PACKAGE_COLUMN_TOOLTIP;\n                filterComponent.setHint(PACKAGE_FILTER_HINT);\n\n                break;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/ThreadsSelector.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.cpu;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.event.ItemEvent;\nimport java.text.MessageFormat;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToolBar;\nimport javax.swing.RowFilter;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingConstants;\nimport javax.swing.ToolTipManager;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.FilteringToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerPopup;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.CheckBoxRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ThreadsSelector extends PopupButton {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.cpu.Bundle\"); // NOI18N\n    private static final String SELECT_THREADS = messages.getString(\"ThreadsSelector_SelectThreads\"); // NOI18N\n    private static final String SELECTED_THREADS = messages.getString(\"ThreadsSelector_SelectedThreads\"); // NOI18N\n    private static final String SELECTED_THREADS_ALL = messages.getString(\"ThreadsSelector_SelectedThreadsAll\"); // NOI18N\n    private static final String NO_THREADS = messages.getString(\"ThreadsSelector_NoThreads\"); // NOI18N\n    private static final String ALL_THREADS = messages.getString(\"ThreadsSelector_AllThreads\"); // NOI18N\n    private static final String FILTER_THREADS = messages.getString(\"ThreadsSelector_FilterThreads\"); // NOI18N\n    private static final String MERGE_THREADS = messages.getString(\"ThreadsSelector_MergeThreads\"); // NOI18N\n    private static final String ALL_THREADS_TOOLTIP = messages.getString(\"ThreadsSelector_AllThreadsToolTip\"); // NOI18N\n    private static final String MERGE_THREADS_TOOLTIP = messages.getString(\"ThreadsSelector_MergeThreadsToolTip\"); // NOI18N\n    private static final String MERGE_THREADS_TOOLTIP_DISABLED = messages.getString(\"ThreadsSelector_MergeThreadsToolTipDisabled\"); // NOI18N\n    private static final String COLUMN_SELECTED = messages.getString(\"ThreadsSelector_ColumnSelected\"); // NOI18N\n    private static final String COLUMN_THREAD = messages.getString(\"ThreadsSelector_ColumnThread\"); // NOI18N\n    private static final String COLUMN_SELECTED_TOOLTIP = messages.getString(\"ThreadsSelector_ColumnSelectedToolTip\"); // NOI18N\n    private static final String COLUMN_THREAD_TOOLTIP = messages.getString(\"ThreadsSelector_ColumnThreadToolTip\"); // NOI18N\n    // -----\n    \n    \n    private final Set<Integer> selection = new HashSet<>();\n    \n    private boolean displayAllThreads = true;\n    private boolean mergeSelectedThreads = false;\n    \n    private Runnable allThreadsResetter;\n    \n    \n    public ThreadsSelector() {\n        super(Icons.getIcon(ProfilerIcons.ALL_THREADS));\n        ToolTipManager.sharedInstance().registerComponent(this);\n    }\n    \n    \n    protected abstract CPUResultsSnapshot getSnapshot();\n    \n    protected abstract void selectionChanged(Collection<Integer> selected, boolean mergeThreads);\n    \n    \n    void reset() {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                displayAllThreads = true;\n                mergeSelectedThreads = false;\n                selection.clear();\n            }\n        });\n    }\n    \n    void addThread(final int id, final boolean exclusive) {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                if (exclusive) selection.clear();\n                if (selection.add(id)) {\n                    displayAllThreads = false;\n                    fireSelectionChanged();\n                }\n            }\n        });\n    }\n    \n    void removeThread(final int id) {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                if (displayAllThreads) {\n                    Set<Integer> threads = new HashSet<>();\n                    CPUResultsSnapshot snapshot = getSnapshot();\n                    if (snapshot != null)\n                        for (int i = 0; i < snapshot.getNThreads(); i++)\n                            threads.add(snapshot.getThreadIds()[i]);\n                    \n                    if (!threads.remove(id)) return;\n                    selection.clear();\n                    selection.addAll(threads);\n                } else {\n                    if (!selection.remove(id)) return;\n                }\n                \n                displayAllThreads = false;\n                fireSelectionChanged();\n            }\n        });\n    }\n    \n    \n    public String getToolTipText() {\n        return displayAllThreads ? SELECTED_THREADS_ALL :\n               MessageFormat.format(SELECTED_THREADS, selection.size());\n    }\n    \n    \n    protected void displayPopup() {\n        CPUResultsSnapshot snapshot = getSnapshot();\n        int[] threadIDs = snapshot == null ? null : snapshot.getThreadIds();\n//        String[] threadNames = snapshot == null ? null : snapshot.getThreadNames();\n        \n        int resizeMode;\n        JComponent content;\n        \n        if (threadIDs == null || threadIDs.length == 0) {\n            content = new JLabel(NO_THREADS);\n            content.setBorder(BorderFactory.createEmptyBorder(9, 6, 9, 6));\n            resizeMode = ProfilerPopup.RESIZE_NONE;\n        } else {\n            content = new JPanel(new BorderLayout());\n            \n            JLabel hint = new JLabel(SELECT_THREADS, JLabel.LEADING);\n            hint.setBorder(BorderFactory.createEmptyBorder(0, 0, 6, 0));\n            content.add(hint, BorderLayout.NORTH);\n            \n            final SelectedThreadsModel threadsModel = new SelectedThreadsModel();\n            final ProfilerTable threadsTable = new ProfilerTable(threadsModel, true, false, null);\n            threadsTable.setColumnToolTips(new String[] { COLUMN_SELECTED_TOOLTIP, COLUMN_THREAD_TOOLTIP });\n            threadsTable.setMainColumn(1);\n            threadsTable.setFitWidthColumn(1);\n            threadsTable.setDefaultSortOrder(1, SortOrder.ASCENDING);\n            threadsTable.setSortColumn(1);\n            threadsTable.setFixedColumnSelection(0); // #268298 - make sure SPACE always hits the Boolean column\n            threadsTable.setColumnRenderer(0, new CheckBoxRenderer());\n            LabelRenderer threadsRenderer = new LabelRenderer();\n            threadsRenderer.setIcon(Icons.getIcon(ProfilerIcons.THREAD));\n            threadsRenderer.setFont(threadsRenderer.getFont().deriveFont(Font.BOLD));\n            threadsTable.setColumnRenderer(1, threadsRenderer);\n            int w = new JLabel(threadsTable.getColumnName(0)).getPreferredSize().width;\n            threadsTable.setDefaultColumnWidth(0, w + 15);\n            int h = threadsTable.getRowHeight() * 8;\n            h += threadsTable.getTableHeader().getPreferredSize().height;\n            threadsRenderer.setValue(\"Inactive RequestProcessor thread [Was:Just template/AWT-EventQueue-0]\", -1); // NOI18N\n            Dimension prefSize = new Dimension(threadsRenderer.getPreferredSize().width, h);\n            threadsTable.setPreferredScrollableViewportSize(prefSize);\n            ProfilerTableContainer tableContainer = new ProfilerTableContainer(threadsTable, true, null);\n            JPanel tableContent = new JPanel(new BorderLayout());\n            tableContent.setBorder(BorderFactory.createEmptyBorder(0, 0, 4, 0));\n            tableContent.add(tableContainer, BorderLayout.CENTER);\n            content.add(tableContent, BorderLayout.CENTER);\n            \n            JToolBar controls = new FilteringToolbar(FILTER_THREADS) {\n                protected void filterChanged() {\n                    if (isAll()) threadsTable.setRowFilter(null);\n                    else threadsTable.setRowFilter(new RowFilter() {\n                        public boolean include(RowFilter.Entry entry) {\n                            return passes(entry.getStringValue(1));\n                        }\n                    });\n                }\n            };\n            \n            controls.add(Box.createHorizontalStrut(2));\n            controls.addSeparator();\n            controls.add(Box.createHorizontalStrut(3));\n            \n            final JCheckBox mergeThreads = new JCheckBox(MERGE_THREADS, mergeSelectedThreads) {\n                protected void fireItemStateChanged(ItemEvent e) {\n                    mergeSelectedThreads = isSelected() && !displayAllThreads;\n                    fireSelectionChanged();\n                }\n                public String getToolTipText() {\n                    return isEnabled() ? super.getToolTipText() : MERGE_THREADS_TOOLTIP_DISABLED;\n                }\n            };\n            mergeThreads.setToolTipText(MERGE_THREADS_TOOLTIP);\n            \n            final boolean[] resetterEvent = new boolean[1];\n            final JCheckBox allThreads = new JCheckBox(ALL_THREADS, displayAllThreads) {\n                protected void fireItemStateChanged(ItemEvent e) {\n                    if (resetterEvent[0]) return;\n                    displayAllThreads = isSelected();\n                    CPUResultsSnapshot snapshot = getSnapshot();\n                    if (snapshot != null && displayAllThreads)\n                        for (int i = 0; i < snapshot.getNThreads(); i++)\n                            selection.add(snapshot.getThreadIds()[i]);\n                    else selection.clear();\n                    mergeThreads.setEnabled(!displayAllThreads);\n                    if (displayAllThreads) {\n                        mergeThreads.setSelected(false);\n                        mergeSelectedThreads = false;\n                    }\n                    threadsModel.fireTableDataChanged();\n                    fireSelectionChanged();\n                }\n            };\n            allThreads.setToolTipText(ALL_THREADS_TOOLTIP);\n            allThreadsResetter = new Runnable() {\n                public void run() {\n                    resetterEvent[0] = true;\n                    allThreads.setSelected(false);\n                    mergeThreads.setEnabled(true);\n                    resetterEvent[0] = false;\n                }\n            };\n            controls.add(allThreads);\n            \n            controls.add(Box.createHorizontalStrut(7));\n            \n            controls.add(mergeThreads);\n            \n            controls.add(Box.createHorizontalStrut(20));\n            \n            content.add(controls, BorderLayout.SOUTH);\n            \n            resizeMode = ProfilerPopup.RESIZE_BOTTOM | ProfilerPopup.RESIZE_RIGHT;\n        }\n\n        ProfilerPopup.Listener listener = new ProfilerPopup.Listener() {\n            protected void popupHidden() {\n                if (!displayAllThreads && selection.isEmpty()) {\n                    displayAllThreads = true;\n                    mergeSelectedThreads = false;\n                    fireSelectionChanged();\n                }\n                allThreadsResetter = null;\n            }\n        };\n        \n        ProfilerPopup.createRelative(this, content, SwingConstants.SOUTH_WEST, resizeMode, listener).show();\n    }\n    \n    \n    private void fireSelectionChanged() {\n        Collection<Integer> selected = displayAllThreads ? null : new HashSet<>(selection);\n        selectionChanged(selected, mergeSelectedThreads);\n    }\n    \n    \n    private class SelectedThreadsModel extends AbstractTableModel {\n        \n        public String getColumnName(int columnIndex) {\n            if (columnIndex == 0) {\n                return COLUMN_SELECTED;\n            } else if (columnIndex == 1) {\n                return COLUMN_THREAD;\n            }\n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (columnIndex == 0) {\n                return Boolean.class;\n            } else if (columnIndex == 1) {\n                return String.class;\n            }\n            return null;\n        }\n\n        public int getRowCount() {\n            CPUResultsSnapshot snapshot = getSnapshot();\n            return snapshot == null ? 0 : snapshot.getNThreads();\n        }\n\n        public int getColumnCount() {\n            return 2;\n        }\n\n        public Object getValueAt(int rowIndex, int columnIndex) {\n            if (columnIndex == 0) {\n                return selection.contains(getSnapshot().getThreadIds()[rowIndex]);\n            } else if (columnIndex == 1) {\n                return getSnapshot().getThreadNames()[rowIndex];\n            }\n            return null;\n        }\n        \n        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {\n            if (columnIndex == 0) {\n                int threadId = getSnapshot().getThreadIds()[rowIndex];\n                if (Boolean.TRUE.equals(aValue)) selection.add(threadId);\n                else selection.remove(threadId);\n                if (allThreadsResetter != null) allThreadsResetter.run();\n                displayAllThreads = false;\n                fireSelectionChanged();\n            }\n        }\n\n        public boolean isCellEditable(int rowIndex, int columnIndex) {\n            return columnIndex == 0;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/statistics/StatisticalModule.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu.statistics;\n\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.jfluid.marker.Mark;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.RuntimeCPUCCTNode;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic abstract class StatisticalModule extends JPanel {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int mId = -1;\n    private Mark mark = Mark.DEFAULT;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    final public void setSelectedMethodId(int methodId) {\n        int oldId = this.mId;\n        this.mId = methodId;\n        if (oldId != this.mId) {\n            onMethodSelectionChange(oldId, this.mId);\n        }\n    }\n\n    final protected int getSelectedMethodId() {\n        return mId;\n    }\n\n    final public void setSelectedMark(Mark mark) {\n        Mark oldMark = this.mark;\n        this.mark = mark;\n\n        if (!oldMark.equals(this.mark)) {\n            onMarkSelectionChange(oldMark, this.mark);\n        }\n    }\n\n    final protected Mark getSelectedMark() {\n        return this.mark;\n    }\n\n    public abstract void refresh(RuntimeCPUCCTNode appNode);\n\n    protected void onMarkSelectionChange(Mark oldMark, Mark newMark) {\n    }\n\n    protected void onMethodSelectionChange(int oldMethodId, int newMethodId) {\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/statistics/StatisticalModuleContainer.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu.statistics;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.RuntimeCPUCCTNode;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\n//@ServiceProvider(service=CPUCCTProvider.Listener.class)\npublic class StatisticalModuleContainer implements CPUCCTProvider.Listener {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final Set /*<StatisticalModule>*/ modules = new HashSet();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of StatisticalModuleContainer */\n    public StatisticalModuleContainer() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Collection getAllModules() {\n        return new ArrayList(modules);\n    }\n\n    public void addModule(StatisticalModule module) {\n        modules.add(module);\n    }\n\n    public void cctEstablished(RuntimeCCTNode appNode, boolean empty) {\n        if (empty) {\n            return;\n        }\n\n        if (!(appNode instanceof RuntimeCPUCCTNode)) {\n            return;\n        }\n\n        Set tmpModules;\n\n        synchronized (modules) {\n            if (modules.isEmpty()) {\n                return;\n            }\n\n            tmpModules = new HashSet(modules);\n        }\n\n        for (Iterator iter = tmpModules.iterator(); iter.hasNext();) {\n            ((StatisticalModule) iter.next()).refresh((RuntimeCPUCCTNode) appNode);\n        }\n    }\n\n    public void cctReset() {\n        cctEstablished(null, false);\n    }\n\n    public void removeAllModules() {\n        modules.clear();\n    }\n\n    public void removeModule(StatisticalModule module) {\n        modules.remove(module);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/cpu/statistics/TimingData.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.cpu.statistics;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class TimingData {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int incInv;\n    private int outInv;\n    private long time0Acc;\n    private long time1Acc;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public TimingData() {\n        time0Acc = 0;\n        time1Acc = 0;\n        incInv = 0;\n        outInv = 0;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public synchronized int getIncInv() {\n        return incInv;\n    }\n\n    public synchronized int getOutInv() {\n        return outInv;\n    }\n\n    public synchronized long getTime0Acc() {\n        return time0Acc;\n    }\n\n    public synchronized long getTime1Acc() {\n        return time1Acc;\n    }\n\n    public synchronized void addIncomming(int invocations) {\n        incInv += invocations;\n    }\n\n    public synchronized void addOutgoing(int invocations) {\n        outInv += invocations;\n    }\n\n    public synchronized void addTime0(long time0) {\n        time0Acc += time0;\n    }\n\n    public synchronized void addTime1(long time1) {\n        time1Acc += time1;\n    }\n\n    public synchronized void incrementIncomming() {\n        incInv++;\n    }\n\n    public synchronized void incrementOutgoing() {\n        outInv++;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/graphs/AllocationsHistoryGraphPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.graphs;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.FlowLayout;\nimport java.awt.Insets;\nimport java.util.Date;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemsModel;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.axis.AxisComponent;\nimport org.graalvm.visualvm.lib.charts.axis.BytesAxisUtils;\nimport org.graalvm.visualvm.lib.charts.axis.BytesMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.SimpleLongMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimeMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimelineMarksComputer;\nimport org.graalvm.visualvm.lib.charts.swing.CrossBorderLayout;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.BytesXYItemMarksComputer;\nimport org.graalvm.visualvm.lib.charts.xy.CompoundXYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.DecimalXYItemMarksComputer;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemMarker;\nimport org.graalvm.visualvm.lib.jfluid.results.DataManagerListener;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYChart;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYItemPainter;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYSelectionOverlay;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipModel;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipOverlay;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipPainter;\nimport org.graalvm.visualvm.lib.ui.components.ColorIcon;\nimport org.graalvm.visualvm.lib.ui.memory.ClassHistoryModels;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class AllocationsHistoryGraphPanel extends GraphPanel {\n\n    private ProfilerXYChart chart;\n    private Action[] chartActions;\n\n    private final ClassHistoryModels models;\n\n\n    // --- Constructors --------------------------------------------------------\n\n    public static AllocationsHistoryGraphPanel createPanel(ClassHistoryModels models) {\n        return new AllocationsHistoryGraphPanel(models);\n    }\n\n    private AllocationsHistoryGraphPanel(ClassHistoryModels models) {\n\n        // Save models and panel type\n        this.models = models;\n\n        // Create UI\n        initComponents();\n\n        // Register listener\n        models.getDataManager().addDataListener(new DataManagerListener() {\n            public void dataChanged() { updateData(); }\n            public void dataReset() { resetData(); }\n        });\n\n        // Initialize chart & legend\n        resetData();\n    }\n\n\n    // --- GraphPanel implementation -------------------------------------------\n\n    public Action[] getActions() {\n        return chartActions;\n    }\n    \n    public void cleanup() {}\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void updateData() {\n    }\n\n    private void resetData() {\n        chart.setScale(INITIAL_CHART_SCALEX, 1);\n        chart.setOffset(0, 0);\n        chart.setFitsWidth(false);\n        chart.setInitialDataBounds(new LongRect(System.currentTimeMillis(), 0,\n                                       2500, GraphsUI.A_ALLOC_OBJECTS_INITIAL_VALUE));\n    }\n\n\n    private void initComponents() {\n        // Painters model\n        PaintersModel paintersModel = createAllocPaintersModel();\n\n        // Chart\n        chart = createChart(models.allocationsItemsModel(),\n                            paintersModel, false);\n        chart.setBackground(GraphsUI.CHART_BACKGROUND_COLOR);\n        chart.setViewInsets(new Insets(10, 0, 0, 0));\n\n        // Horizontal axis\n        AxisComponent hAxis =\n                new AxisComponent(chart, new TimelineMarksComputer(\n                         models.allocationsItemsModel().getTimeline(),\n                         chart.getChartContext(), SwingConstants.HORIZONTAL),\n                         new TimeMarksPainter(),\n                         SwingConstants.SOUTH, AxisComponent.MESH_FOREGROUND);\n\n        // Allocated objects axis\n        XYItem allocObjectsItem = models.allocationsItemsModel().getItem(0);\n        XYItemPainter allocObjectsPainter = (XYItemPainter)paintersModel.getPainter(allocObjectsItem);\n        SimpleLongMarksPainter allocObjectsMarksPainter = new SimpleLongMarksPainter();\n        allocObjectsMarksPainter.setForeground(GraphsUI.A_ALLOC_OBJECTS_PAINTER_LINE_COLOR);\n        AxisComponent tAxis =\n                new AxisComponent(chart, new DecimalXYItemMarksComputer(\n                         allocObjectsItem, allocObjectsPainter, chart.getChartContext(),\n                         SwingConstants.VERTICAL),\n                         allocObjectsMarksPainter, SwingConstants.WEST,\n                         AxisComponent.MESH_FOREGROUND);\n\n        // Allocated bytes axis\n        XYItem allocBytesItem = models.allocationsItemsModel().getItem(1);\n        XYItemPainter allocBytesPainter = (XYItemPainter)paintersModel.getPainter(allocBytesItem);\n        BytesMarksPainter allocBytesMarksPainter = new BytesMarksPainter();\n        allocBytesMarksPainter.setForeground(GraphsUI.A_ALLOC_BYTES_PAINTER_LINE_COLOR);\n        AxisComponent cAxis =\n                new AxisComponent(chart, new BytesXYItemMarksComputer(\n                         allocBytesItem, allocBytesPainter, chart.getChartContext(),\n                         SwingConstants.VERTICAL),\n                         allocBytesMarksPainter, SwingConstants.EAST,\n                         AxisComponent.NO_MESH);\n\n        // Chart panel (chart & axes)\n        JPanel chartPanel = new JPanel(new CrossBorderLayout());\n        chartPanel.setBackground(GraphsUI.CHART_BACKGROUND_COLOR);\n        chartPanel.setBorder(BorderFactory.createMatteBorder(\n                             10, 10, 10, 10, GraphsUI.CHART_BACKGROUND_COLOR));\n        chartPanel.add(chart, new Integer[] { SwingConstants.CENTER });\n        chartPanel.add(hAxis, new Integer[] { SwingConstants.SOUTH,\n                                              SwingConstants.SOUTH_WEST,\n                                              SwingConstants.SOUTH_EAST });\n        chartPanel.add(tAxis, new Integer[] { SwingConstants.WEST,\n                                              SwingConstants.SOUTH_WEST });\n        chartPanel.add(cAxis, new Integer[] { SwingConstants.EAST,\n                                              SwingConstants.SOUTH_EAST });\n        \n        // Tooltip support\n        ProfilerXYTooltipPainter tooltipPainter = new ProfilerXYTooltipPainter(createTooltipModel());\n        chart.addOverlayComponent(new ProfilerXYTooltipOverlay(chart, tooltipPainter));\n        chart.getSelectionModel().setHoverMode(ChartSelectionModel.HOVER_EACH_NEAREST);\n\n        // Hovering support\n        ProfilerXYSelectionOverlay selectionOverlay = new ProfilerXYSelectionOverlay();\n        chart.addOverlayComponent(selectionOverlay);\n        selectionOverlay.registerChart(chart);\n        chart.getSelectionModel().setMoveMode(ChartSelectionModel.SELECTION_LINE_V);\n\n//        // Setup tooltip painter\n//        ProfilerXYTooltipPainter tooltipPainter = new ProfilerXYTooltipPainter(\n//                                            GraphsUI.TOOLTIP_OVERLAY_LINE_WIDTH,\n//                                            GraphsUI.TOOLTIP_OVERLAY_LINE_COLOR,\n//                                            GraphsUI.TOOLTIP_OVERLAY_FILL_COLOR,\n//                                            getTooltipModel());\n//\n//        // Customize chart\n//        chart.addOverlayComponent(new ProfilerXYTooltipOverlay(chart,\n//                                                               tooltipPainter));\n//\n//        // Chart scrollbar\n//        JScrollBar hScrollBar = new JScrollBar(JScrollBar.HORIZONTAL);\n//        chart.attachHorizontalScrollBar(hScrollBar);\n\n        // Chart container (chart panel & scrollbar)\n        JPanel chartContainer = new JPanel(new BorderLayout());\n        chartContainer.setBorder(BorderFactory.createEmptyBorder());\n        chartContainer.add(chartPanel, BorderLayout.CENTER);\n//        chartContainer.add(hScrollBar, BorderLayout.SOUTH);\n\n        // Allocated Objects\n        JLabel allocObjectsBig = new JLabel(GraphsUI.A_ALLOC_OBJECTS_NAME,\n                                        new ColorIcon(GraphsUI.\n                                        A_ALLOC_OBJECTS_PAINTER_LINE_COLOR, Color.\n                                        BLACK, 18, 9), SwingConstants.LEADING);\n        allocObjectsBig.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n\n        // Allocated Bytes\n        JLabel allocBytesBig = new JLabel(GraphsUI.A_ALLOC_BYTES_NAME,\n                                        new ColorIcon(GraphsUI.\n                                        A_ALLOC_BYTES_PAINTER_LINE_COLOR, Color.\n                                        BLACK, 18, 9), SwingConstants.LEADING);\n        allocBytesBig.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n\n        // Legend container\n        JPanel bigLegendPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 7, 8));\n        bigLegendPanel.setOpaque(false);\n        bigLegendPanel.add(allocObjectsBig);\n        bigLegendPanel.add(allocBytesBig);\n        \n        JPanel legendContainer = new JPanel(new BorderLayout(0, 0));\n        UIUtils.decorateProfilerPanel(legendContainer);\n        legendContainer.add(UIUtils.createHorizontalLine(legendContainer.getBackground()), BorderLayout.NORTH);\n        legendContainer.add(bigLegendPanel, BorderLayout.CENTER);\n\n        // Master UI\n        setLayout(new BorderLayout());\n        add(chartContainer, BorderLayout.CENTER);\n        add(legendContainer, BorderLayout.SOUTH);\n\n\n        // Toolbar actions\n        chartActions = new Action[] { chart.zoomInAction(),\n                                      chart.zoomOutAction(),\n                                      chart.toggleViewAction()};\n\n    }\n\n    protected ProfilerXYTooltipModel createTooltipModel() {\n        return new ProfilerXYTooltipModel() {\n\n            public String getTimeValue(long timestamp) {\n                return DATE_FORMATTER.format(new Date(timestamp));\n            }\n\n            public int getRowsCount() {\n                return 2;\n            }\n\n            public String getRowName(int index) {\n                switch (index) {\n                    case 0:\n                        return GraphsUI.A_ALLOC_OBJECTS_NAME;\n                    case 1:\n                        return GraphsUI.A_ALLOC_BYTES_NAME;\n                    default:\n                        return null;\n                }\n            }\n\n            public Color getRowColor(int index) {\n                switch (index) {\n                    case 0:\n                        return GraphsUI.A_ALLOC_OBJECTS_PAINTER_LINE_COLOR;\n                    case 1:\n                        return GraphsUI.A_ALLOC_BYTES_PAINTER_LINE_COLOR;\n                    default:\n                        return null;\n                }\n            }\n\n            public String getRowValue(int index, long itemValue) {\n                return INT_FORMATTER.format(itemValue);\n            }\n\n            public String getRowUnits(int index) {\n                switch (index) {\n                    case 0:\n                        return \"\"; // NOI18N\n                    case 1:\n                        return BytesAxisUtils.UNITS_B;\n                    default:\n                        return null;\n                }\n            }\n\n            public int getExtraRowsCount() {\n                return getRowsCount();\n            }\n\n            public String getExtraRowName(int index) {\n                return getMaxValueString(getRowName(index));\n            }\n\n            public Color getExtraRowColor(int index) {\n                return getRowColor(index);\n            }\n\n            public String getExtraRowValue(int index) {\n                SynchronousXYItem item = models.allocationsItemsModel().getItem(index);\n                return INT_FORMATTER.format(item.getMaxYValue());\n            }\n\n            public String getExtraRowUnits(int index) {\n                return getRowUnits(index);\n            }\n\n        };\n    }\n\n    private PaintersModel createAllocPaintersModel() {\n        // Allocated Objects\n        ProfilerXYItemPainter allocObjectsPainter =\n                ProfilerXYItemPainter.absolutePainter(GraphsUI.A_ALLOC_OBJECTS_PAINTER_LINE_WIDTH,\n                                                      GraphsUI.A_ALLOC_OBJECTS_PAINTER_LINE_COLOR,\n                                                      GraphsUI.A_ALLOC_OBJECTS_PAINTER_FILL_COLOR);\n        SynchronousXYItemMarker allocObjectsMarker =\n                 SynchronousXYItemMarker.absolutePainter(GraphsUI.A_ALLOC_OBJECTS_MARKER_RADIUS,\n                                                      GraphsUI.A_ALLOC_OBJECTS_MARKER_LINE1_WIDTH,\n                                                      GraphsUI.A_ALLOC_OBJECTS_MARKER_LINE1_COLOR,\n                                                      GraphsUI.A_ALLOC_OBJECTS_MARKER_LINE2_WIDTH,\n                                                      GraphsUI.A_ALLOC_OBJECTS_MARKER_LINE2_COLOR,\n                                                      GraphsUI.A_ALLOC_OBJECTS_MARKER_FILL_COLOR);\n        XYItemPainter aop = new CompoundXYItemPainter(allocObjectsPainter,\n                                                      allocObjectsMarker);\n\n        // Allocated Bytes\n        ProfilerXYItemPainter allocatedBytesPainter =\n                ProfilerXYItemPainter.relativePainter(GraphsUI.A_ALLOC_BYTES_PAINTER_LINE_WIDTH,\n                                                      GraphsUI.A_ALLOC_BYTES_PAINTER_LINE_COLOR,\n                                                      GraphsUI.A_ALLOC_BYTES_PAINTER_FILL_COLOR,\n                                                      10);\n        SynchronousXYItemMarker allocatedBytesMarker =\n                 SynchronousXYItemMarker.relativePainter(GraphsUI.A_ALLOC_BYTES_MARKER_RADIUS,\n                                                      GraphsUI.A_ALLOC_BYTES_MARKER_LINE1_WIDTH,\n                                                      GraphsUI.A_ALLOC_BYTES_MARKER_LINE1_COLOR,\n                                                      GraphsUI.A_ALLOC_BYTES_MARKER_LINE2_WIDTH,\n                                                      GraphsUI.A_ALLOC_BYTES_MARKER_LINE2_COLOR,\n                                                      GraphsUI.A_ALLOC_BYTES_MARKER_FILL_COLOR,\n                                                      10);\n        XYItemPainter abp = new CompoundXYItemPainter(allocatedBytesPainter,\n                                                      allocatedBytesMarker);\n\n        // Model\n        ItemsModel items = models.allocationsItemsModel();\n        PaintersModel model = new PaintersModel.Default(\n                                            new ChartItem[] { items.getItem(0),\n                                                              items.getItem(1) },\n                                            new XYItemPainter[] { aop, abp });\n\n        return model;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/graphs/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nGraphPanel_NoDataTooltip=<No Data>\n# Max value of the provided metrics, default EN: Max {Metrics Name} example: Max Live Bytes\nGraphPanel_MaxValueString=Max {0}\n\nGraphsUI_AllocObjects=Allocated Objects\nGraphsUI_AllocBytes=Allocated Bytes\nGraphsUI_LiveObjects=Live Objects\nGraphsUI_LiveBytes=Live Bytes\nGraphsUI_HeapSize=Heap Size\nGraphsUI_UsedHeap=Used Heap\nGraphsUI_SurvGen=Surviving Generations\nGraphsUI_CpuTime=CPU Time\nGraphsUI_GcTime=GC Time\nGraphsUI_GcIntervals=GC Intervals\nGraphsUI_Threads=Threads\nGraphsUI_LoadedClasses=Loaded Classes\nGraphsUI_CpuGcCaption=CPU and GC\nGraphsUI_MemoryCaption=Memory\nGraphsUI_GarbageCollectionCaption=Garbage Collection\nGraphsUI_ThreadsClassesCaption=Threads and Classes\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/graphs/CPUGraphPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.graphs;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.FlowLayout;\nimport java.awt.Font;\nimport java.awt.Insets;\nimport java.util.Date;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemsModel;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.axis.AxisComponent;\nimport org.graalvm.visualvm.lib.charts.axis.PercentLongMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimeMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimelineMarksComputer;\nimport org.graalvm.visualvm.lib.charts.swing.CrossBorderLayout;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.DecimalXYItemMarksComputer;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.jfluid.results.DataManagerListener;\nimport org.graalvm.visualvm.lib.jfluid.results.monitor.VMTelemetryDataManager;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYChart;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYItemPainter;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYSelectionOverlay;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipModel;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipOverlay;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipPainter;\nimport org.graalvm.visualvm.lib.ui.components.ColorIcon;\nimport org.graalvm.visualvm.lib.ui.monitor.VMTelemetryModels;\nimport org.graalvm.visualvm.lib.ui.swing.InvisibleToolbar;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class CPUGraphPanel extends GraphPanel {\n\n    private ProfilerXYChart chart;\n    private Action[] chartActions;\n\n    private final VMTelemetryModels models;\n    private final DataManagerListener listener;\n\n    private final boolean smallPanel;\n    \n    private final Color CPU_COLOR = ColorFactory.getPredefinedColor(0);\n    private final Color GC_COLOR = ColorFactory.getPredefinedColor(1);\n\n\n    // --- Constructors --------------------------------------------------------\n\n    public static CPUGraphPanel createBigPanel(VMTelemetryModels models) {\n        return new CPUGraphPanel(models, false, null);\n    }\n\n    public static CPUGraphPanel createSmallPanel(VMTelemetryModels models,\n                                             Action chartAction) {\n        return new CPUGraphPanel(models, true, chartAction);\n    }\n\n    private CPUGraphPanel(VMTelemetryModels models,\n                             boolean smallPanel, Action chartAction) {\n\n        // Save models and panel type\n        this.models = models;\n        this.smallPanel = smallPanel;\n\n        // Create UI\n        initComponents(chartAction);\n\n        // Register listener\n        listener = new DataManagerListener() {\n            public void dataChanged() { updateData(); }\n            public void dataReset() { resetData(); }\n        };\n        models.getDataManager().addDataListener(listener);\n\n        // Initialize chart & legend\n        resetData();\n    }\n\n\n    // --- GraphPanel implementation -------------------------------------------\n\n    public Action[] getActions() {\n        return chartActions;\n    }\n    \n    public void cleanup() {\n        models.getDataManager().removeDataListener(listener);\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void updateData() {\n        if (smallPanel) {\n            if (chart.fitsWidth()) {\n                VMTelemetryDataManager manager = models.getDataManager();\n                long[] timestamps = manager.timeStamps;\n                if (timestamps[manager.getItemCount() - 1] - timestamps[0] >=\n                    SMALL_CHART_FIT_TO_WINDOW_PERIOD)\n                        chart.setFitsWidth(false);\n            }\n        } else {\n        }\n    }\n\n    private void resetData() {\n        if (smallPanel) {\n            chart.setScale(INITIAL_CHART_SCALEX, 1);\n            chart.setOffset(0, 0);\n            chart.setFitsWidth(true);\n        } else {\n            chart.setScale(INITIAL_CHART_SCALEX, 1);\n            chart.setOffset(0, 0);\n            chart.setFitsWidth(false);\n        }\n        chart.setInitialDataBounds(new LongRect(System.currentTimeMillis(), 0,\n                                       2500, 1000));\n    }\n\n\n    private void initComponents(final Action chartAction) {\n        // Painters model\n        PaintersModel paintersModel = createGenerationsPaintersModel();\n\n        // Chart\n        chart = createChart(models.cpuItemsModel(),\n                            paintersModel, smallPanel);\n        chart.setBackground(GraphsUI.CHART_BACKGROUND_COLOR);\n        chart.setViewInsets(new Insets(10, 0, 0, 0));\n\n        // Horizontal axis\n        AxisComponent hAxis =\n                new AxisComponent(chart, new TimelineMarksComputer(\n                         models.cpuItemsModel().getTimeline(),\n                         chart.getChartContext(), SwingConstants.HORIZONTAL),\n                         new TimeMarksPainter(),\n                         SwingConstants.NORTH, AxisComponent.MESH_FOREGROUND);\n        hAxis.setForeground(Color.GRAY);\n\n        // CPU time axis\n        XYItem cpuTimeItem = models.cpuItemsModel().getItem(0);\n        XYItemPainter cpuTimePainter = (XYItemPainter)paintersModel.getPainter(cpuTimeItem);\n        PercentLongMarksPainter cpuTimeMarksPainter = new PercentLongMarksPainter(0, 1000);\n        AxisComponent cAxis =\n                new AxisComponent(chart, new DecimalXYItemMarksComputer(\n                         cpuTimeItem, cpuTimePainter, chart.getChartContext(),\n                         SwingConstants.VERTICAL),\n                         cpuTimeMarksPainter, SwingConstants.WEST,\n                         AxisComponent.MESH_FOREGROUND);\n        cAxis.setForeground(Color.GRAY);\n\n        // Chart panel (chart & axes)\n        JPanel chartPanel = new JPanel(new CrossBorderLayout());\n        chartPanel.setBackground(GraphsUI.CHART_BACKGROUND_COLOR);\n        chartPanel.setBorder(BorderFactory.createMatteBorder(\n                             10, 10, 5, 5, GraphsUI.CHART_BACKGROUND_COLOR));\n        chartPanel.add(chart, new Integer[] { SwingConstants.CENTER });\n        chartPanel.add(hAxis, new Integer[] { SwingConstants.NORTH,\n                                              SwingConstants.NORTH_EAST,\n                                              SwingConstants.NORTH_WEST });\n        chartPanel.add(cAxis, new Integer[] { SwingConstants.WEST,\n                                              SwingConstants.SOUTH_WEST });\n        \n        JScrollBar scroller = new JScrollBar(JScrollBar.HORIZONTAL);\n        chart.attachHorizontalScrollBar(scroller);\n        chartPanel.add(scroller, new Integer[] { SwingConstants.SOUTH });\n\n        // Small panel UI\n        if (smallPanel) {\n\n        // Big panel UI\n        } else {\n            \n            // Tooltip support\n            ProfilerXYTooltipPainter tooltipPainter = new ProfilerXYTooltipPainter(createTooltipModel());\n            chart.addOverlayComponent(new ProfilerXYTooltipOverlay(chart, tooltipPainter));\n            chart.getSelectionModel().setHoverMode(ChartSelectionModel.HOVER_EACH_NEAREST);\n\n            // Hovering support\n            ProfilerXYSelectionOverlay selectionOverlay = new ProfilerXYSelectionOverlay();\n            chart.addOverlayComponent(selectionOverlay);\n            selectionOverlay.registerChart(chart);\n            chart.getSelectionModel().setMoveMode(ChartSelectionModel.SELECTION_LINE_V);\n\n            // Chart container (chart panel & scrollbar)\n            JPanel chartContainer = new JPanel(new BorderLayout());\n            chartContainer.setBorder(BorderFactory.createEmptyBorder());\n            chartContainer.add(chartPanel, BorderLayout.CENTER);\n            \n            \n            // Side panel\n            JPanel sidePanel = new JPanel(new BorderLayout());\n            sidePanel.setOpaque(false);\n            int h = new JLabel(\"XXX\").getPreferredSize().height; // NOI18N\n            sidePanel.setBorder(BorderFactory.createEmptyBorder(h + 17, 0, 0, 10));\n            InvisibleToolbar toolbar = new InvisibleToolbar(InvisibleToolbar.VERTICAL);\n            toolbar.setOpaque(true);\n            toolbar.setBackground(UIUtils.getProfilerResultsBackground());\n            toolbar.add(chart.toggleViewAction()).setBackground(UIUtils.getProfilerResultsBackground());\n            toolbar.add(chart.zoomInAction()).setBackground(UIUtils.getProfilerResultsBackground());\n            toolbar.add(chart.zoomOutAction()).setBackground(UIUtils.getProfilerResultsBackground());\n            sidePanel.add(toolbar, BorderLayout.CENTER);            \n\n            // Heap Size\n            JLabel heapSizeBig = new JLabel(GraphsUI.CPU_TIME_NAME,\n                                            new ColorIcon(CPU_COLOR, Color.\n                                            BLACK, 18, 9), SwingConstants.LEADING);\n            heapSizeBig.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n\n            // Used heap\n            JLabel usedHeapBig = new JLabel(GraphsUI.GC_TIME_NAME,\n                                            new ColorIcon(GC_COLOR, Color.\n                                            BLACK, 18, 9), SwingConstants.LEADING);\n            usedHeapBig.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n\n            // Legend container\n            JPanel bigLegendPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 7, 0));\n            bigLegendPanel.setBorder(BorderFactory.createEmptyBorder(4, 0, 8, 30));\n            bigLegendPanel.setOpaque(true);\n            bigLegendPanel.setBackground(UIUtils.getProfilerResultsBackground());\n            bigLegendPanel.add(heapSizeBig);\n            bigLegendPanel.add(usedHeapBig);\n\n            // Master UI\n            setLayout(new BorderLayout());\n            setBackground(UIUtils.getProfilerResultsBackground());\n            JLabel caption = new JLabel(GraphsUI.CPU_GC_CAPTION, JLabel.CENTER);\n            caption.setFont(caption.getFont().deriveFont(Font.BOLD));\n            caption.setBorder(BorderFactory.createEmptyBorder(15, 0, 0, 0));\n            caption.setOpaque(true);\n            caption.setBackground(UIUtils.getProfilerResultsBackground());\n            add(caption, BorderLayout.NORTH);\n            add(chartContainer, BorderLayout.CENTER);\n            add(bigLegendPanel, BorderLayout.SOUTH);\n            add(sidePanel, BorderLayout.EAST);\n\n\n            // Toolbar actions\n            chartActions = new Action[] { chart.zoomInAction(),\n                                          chart.zoomOutAction(),\n                                          chart.toggleViewAction()};\n\n        }\n\n    }\n\n    protected ProfilerXYTooltipModel createTooltipModel() {\n        return new ProfilerXYTooltipModel() {\n\n            public String getTimeValue(long timestamp) {\n                return DATE_FORMATTER.format(new Date(timestamp));\n            }\n\n            public int getRowsCount() {\n                return 2;\n            }\n\n            public String getRowName(int index) {\n                switch (index) {\n                    case 0:\n                        return GraphsUI.CPU_TIME_NAME;\n                    case 1:\n                        return GraphsUI.GC_TIME_NAME;\n                    default:\n                        return null;\n                }\n            }\n\n            public Color getRowColor(int index) {\n                switch (index) {\n                    case 0:\n                        return GraphsUI.PROFILER_RED;\n                    case 1:\n                        return GraphsUI.GC_TIME_PAINTER_LINE_COLOR;\n                    default:\n                        return null;\n                }\n            }\n\n            public String getRowValue(int index, long itemValue) {\n                if (itemValue < 0) return \"N/A\"; // NOI18N\n                String val = PERCENT_FORMATTER.format(itemValue / 1000f);\n                return trimPercents(val);\n            }\n\n            public String getRowUnits(int index) {\n                return \"%\"; // NOI18N\n            }\n\n            public int getExtraRowsCount() {\n                return getRowsCount();\n            }\n\n            public String getExtraRowName(int index) {\n                return getMaxValueString(getRowName(index));\n            }\n\n            public Color getExtraRowColor(int index) {\n                return getRowColor(index);\n            }\n\n            public String getExtraRowValue(int index) {\n                SynchronousXYItem item = models.cpuItemsModel().getItem(index);\n                long maxValue = item.getMaxYValue();\n                if (maxValue < 0) return \"N/A\"; // NOI18N\n                String val = PERCENT_FORMATTER.format(maxValue / 1000f);\n                return trimPercents(val);\n            }\n\n            public String getExtraRowUnits(int index) {\n                return getRowUnits(index);\n            }\n\n            private String trimPercents(String percents) {\n                return !percents.endsWith(\"%\") ? percents : // NOI18N\n                        percents.substring(0, percents.length() - 1).trim();\n            }\n\n        };\n    }\n\n    private PaintersModel createGenerationsPaintersModel() {\n        // CPU\n        ProfilerXYItemPainter cpuTimePainter =\n                ProfilerXYItemPainter.relativePainter(GraphsUI.GC_TIME_PAINTER_LINE_WIDTH,\n                                                      CPU_COLOR,\n                                                      null,\n                                                      10);\n        XYItemPainter ctp = cpuTimePainter;\n\n        // Relative time spent in GC\n        ProfilerXYItemPainter gcTimePainter =\n                ProfilerXYItemPainter.relativePainter(GraphsUI.GC_TIME_PAINTER_LINE_WIDTH,\n                                                      GC_COLOR,\n                                                      null,\n                                                      10);\n        XYItemPainter gtp = gcTimePainter;\n\n        // Model\n        ItemsModel items = models.cpuItemsModel();\n        PaintersModel model = new PaintersModel.Default(\n                                            new ChartItem[] { items.getItem(0),\n                                                              items.getItem(1) },\n                                            new XYItemPainter[] { ctp, gtp });\n\n        return model;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/graphs/ColorFactory.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.graphs;\n\nimport java.awt.Color;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n * Utility class to access colors predefined for VisualVM.\n *\n * @author Jiri Sedlacek\n */\nfinal class ColorFactory {\n\n    private static final Color[] PREDEFINED_COLORS = new Color[] {\n                                                new Color(241, 154,  42),\n                                                new Color( 32, 171, 217),\n                                                new Color(144,  97, 207),\n                                                new Color(158, 156,   0)\n    };\n\n    private static final Color[][] PREDEFINED_GRADIENTS = !UIUtils.isDarkResultsBackground() ?\n    new Color[][] {\n        new Color[] { new Color(245, 204, 152), new Color(255, 243, 226) },\n        new Color[] { new Color(151, 223, 246), new Color(227, 248, 255) },\n        new Color[] { new Color(200, 163, 248), new Color(242, 232, 255) },\n        new Color[] { new Color(212, 211, 131), new Color(244, 243, 217) }\n    } :\n    new Color[][] {\n        new Color[] { new Color(145, 104, 52), new Color(155, 143, 126) },\n        new Color[] { new Color(51, 123, 146), new Color(127, 148, 155) },\n        new Color[] { new Color(100, 63, 148), new Color(142, 132, 155) },\n        new Color[] { new Color(112, 111, 31), new Color(144, 143, 117) }\n    };\n\n\n    /**\n     * Returns number of colors predefined for VisualVM charts.\n     * Always contains at least 4 colors.\n     *\n     * @return number of colors predefined for VisualVM charts\n     */\n    public static int getPredefinedColorsCount() {\n        return PREDEFINED_COLORS.length;\n    }\n\n    /**\n     * Returns a color predefined for VisualVM charts.\n     *\n     * @param index index of the predefined color\n     * @return color predefined for VisualVM charts\n     */\n    public static Color getPredefinedColor(int index) {\n        return PREDEFINED_COLORS[index];\n    }\n\n\n    /**\n     * Returns number of color pairs predefined for VisualVM charts gradients.\n     * Always contains at least 4 color pairs.\n     *\n     * @return number of color pairs predefined for VisualVM charts gradients\n     */\n    public static int getPredefinedGradientsCount() {\n        return PREDEFINED_GRADIENTS.length;\n    }\n\n    /**\n     * Returns a color pair predefined for VisualVM charts gradients.\n     *\n     * @param index index of the predefined color pair\n     * @return color pair predefined for VisualVM charts gradients\n     */\n    public static Color[] getPredefinedGradient(int index) {\n        return PREDEFINED_GRADIENTS[index];\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/graphs/GraphPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.graphs;\n\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.MouseEvent;\nimport java.text.DateFormat;\nimport java.text.MessageFormat;\nimport java.text.NumberFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.List;\nimport java.util.ResourceBundle;\nimport javax.swing.Action;\nimport javax.swing.JPanel;\nimport javax.swing.JToolTip;\nimport javax.swing.Timer;\nimport javax.swing.ToolTipManager;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionListener;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.axis.TimeAxisUtils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYChart;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipModel;\n\n\n/**\n * @author Jiri Sedlacek\n */\npublic abstract class GraphPanel extends JPanel {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.graphs.Bundle\"); // NOI18N\n    private static final String NO_DATA_TOOLTIP = messages.getString(\"GraphPanel_NoDataTooltip\"); // NOI18N\n    private static final String MAX_VALUE_STRING = messages.getString(\"GraphPanel_MaxValueString\"); // NOI18N\n    // -----\n\n    protected static final DateFormat DATE_FORMATTER;\n    protected static final NumberFormat INT_FORMATTER;\n    protected static final NumberFormat PERCENT_FORMATTER;\n\n    protected static final double INITIAL_CHART_SCALEX = 0.02d;\n\n    // 3 minutes to switch from Scale To Fit to Fixed Scale\n    protected static final long SMALL_CHART_FIT_TO_WINDOW_PERIOD = 180000;\n\n\n    static {\n        String format = MessageFormat.format(TimeAxisUtils.TIME_DATE_FORMAT,\n                TimeAxisUtils.TIME_SEC,\n                TimeAxisUtils.DATE_YEAR);\n        DATE_FORMATTER = new SimpleDateFormat(format);\n\n        INT_FORMATTER = NumberFormat.getIntegerInstance();\n        INT_FORMATTER.setGroupingUsed(true);\n\n        PERCENT_FORMATTER = NumberFormat.getPercentInstance();\n        PERCENT_FORMATTER.setMinimumFractionDigits(1);\n        PERCENT_FORMATTER.setMaximumIntegerDigits(2);\n    }\n\n\n    // --- Messages support ----------------------------------------------------\n\n    protected String getMaxValueString(String origString) {\n        return MessageFormat.format(MAX_VALUE_STRING, origString);\n    }\n\n\n    // --- Chart support -------------------------------------------------------\n\n    protected ProfilerXYChart createChart(SynchronousXYItemsModel itemsModel,\n                                          PaintersModel paintersModel,\n                                          final boolean smallPanel) {\n\n        ProfilerXYChart chart;\n\n        if (smallPanel) {\n            chart = new ProfilerXYChart(itemsModel, paintersModel) {\n                public JToolTip createToolTip() {\n                    lastTooltip = new SmallTooltip(this);\n                    return lastTooltip;\n                }\n                public Point getToolTipLocation(MouseEvent e) {\n                    return getSmallTooltipLocation(e, smallTooltipManager);\n                }\n            };\n            smallTooltipManager = new SmallTooltipManager(chart);\n            chart.setToolTipText(NO_DATA_TOOLTIP); // Needed to enable the tooltip\n            ToolTipManager.sharedInstance().registerComponent(chart);\n        } else {\n            chart = new ProfilerXYChart(itemsModel, paintersModel);\n        }\n        \n        chart.addPreDecorator(new XYBackground());\n        chart.setFitsWidth(false);\n\n        chart.getSelectionModel().setHoverMode(ChartSelectionModel.HOVER_EACH_NEAREST);\n        return chart;\n\n    }\n\n    public abstract Action[] getActions();\n    \n    public abstract void cleanup();\n\n\n    // --- General tooltip support ---------------------------------------------\n\n    private ProfilerXYTooltipModel tooltipModel;\n\n    protected ProfilerXYTooltipModel getTooltipModel() {\n        if (tooltipModel == null) tooltipModel = createTooltipModel();\n        return tooltipModel;\n    }\n\n    protected abstract ProfilerXYTooltipModel createTooltipModel();\n\n\n    // --- Small tooltip support -----------------------------------------------\n\n    private SmallTooltip lastTooltip;\n    private SmallTooltipManager smallTooltipManager;\n\n\n    private static Point getSmallTooltipLocation(MouseEvent e, SmallTooltipManager tooltip) {\n        Point p = e.getPoint();\n        tooltip.setMousePosition(p);\n        p.y += 25;\n        return p;\n    }\n\n    private class SmallTooltip extends JToolTip {\n        SmallTooltip(ProfilerXYChart chart) {\n            super();\n            setComponent(chart);\n\n            addHierarchyListener(new HierarchyListener() {\n                public void hierarchyChanged(HierarchyEvent e) {\n                    if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                        if (isShowing()) smallTooltipManager.enableSelection();\n                        else smallTooltipManager.disableSelection();\n                    }\n                }\n            });\n        }\n    }\n\n    private class SmallTooltipManager implements ChartSelectionListener {\n\n        private boolean timerRunning = false;\n        private int mouseX;\n        private int mouseY;\n        private ProfilerXYChart chart;\n\n        SmallTooltipManager(ProfilerXYChart chart) {\n            this.chart = chart;\n            chart.getSelectionModel().addSelectionListener(this);\n        }\n\n        public void setMousePosition(Point p) {\n            this.mouseX = p.x;\n            this.mouseY = p.y;\n        }\n\n        private void enableSelection() {\n            chart.getSelectionModel().setHoverMode(ChartSelectionModel.\n                                                   HOVER_EACH_NEAREST);\n        }\n\n        private void disableSelection() {\n            // Another disableSelection() in progress?\n            if (timerRunning) return;\n            timerRunning = true;\n\n            // Tooltip is hidden when its location changes, let's wait for a while\n            Timer timer = new Timer(50, new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    if (!isTooltipShowing()) {\n                        chart.getSelectionModel().\n                                   setHoverMode(ChartSelectionModel.HOVER_NONE);\n                        chart.setToolTipText(NO_DATA_TOOLTIP);\n                    }\n                    timerRunning = false;\n                }\n            });\n            timer.setRepeats(false);\n            timer.start();\n        }\n\n        private boolean isTooltipShowing() {\n            return lastTooltip != null && lastTooltip.isShowing();\n        }\n\n        private void updateTooltipText(List<ItemSelection> selectedItems) {\n            if (!isTooltipShowing()) return;\n\n            if (selectedItems.isEmpty()) {\n                chart.setToolTipText(NO_DATA_TOOLTIP);\n            } else {\n                chart.setToolTipText(getTooltipText(selectedItems));\n            }\n\n            // A MouseEvent needs to be passed to the ToolTipManager to\n            // immediately update the displayed tooltip\n            MouseEvent e = new MouseEvent(chart, 0, 0, 0, mouseX, mouseY, 0, false);\n            ToolTipManager.sharedInstance().mouseMoved(e);\n        }\n\n        private String getTooltipText(List<ItemSelection> selectedItems) {\n            ProfilerXYTooltipModel model = getTooltipModel();\n\n            int rowsCount = model.getRowsCount();\n            if (selectedItems.size() != rowsCount)\n                 return \"Rows and selected items don't match\"; // NOI18N\n\n            StringBuilder builder = new StringBuilder();\n            builder.append(\"<html>\"); // NOI18N\n\n\n            XYItemSelection selection = (XYItemSelection)selectedItems.get(0);\n            long timestamp = selection.getItem().getXValue(selection.getValueIndex());\n            builder.append(\"&nbsp;&nbsp;\"); // NOI18N\n            builder.append(model.getTimeValue(timestamp));\n            builder.append(\"&nbsp;&nbsp;\"); // NOI18N\n            builder.append(\"<hr>\"); // NOI18N\n\n            for (int i = 0; i < rowsCount; i++) {\n                builder.append(\"<b>&nbsp;&nbsp;\"); // NOI18N\n                builder.append(model.getRowName(i));\n                builder.append(\":</b>&nbsp;&nbsp;\"); // NOI18N\n                XYItemSelection sel = (XYItemSelection)selectedItems.get(i);\n                long itemValue = sel.getItem().getYValue(sel.getValueIndex());\n                builder.append(model.getRowValue(i, itemValue));\n                builder.append(\"&nbsp;\"); // NOI18N\n                builder.append(model.getRowUnits(i));\n                builder.append(\"&nbsp;&nbsp;<br>\"); // NOI18N\n            }\n\n            int extraRowsCount = model.getExtraRowsCount();\n            if (extraRowsCount > 0) builder.append(\"<hr>\"); // NOI18N\n            for (int i = 0; i < extraRowsCount; i++) {\n                builder.append(\"<b>&nbsp;&nbsp;\"); // NOI18N\n                builder.append(model.getExtraRowName(i));\n                builder.append(\":</b>&nbsp;&nbsp;\"); // NOI18N\n                builder.append(model.getExtraRowValue(i));\n                builder.append(\"&nbsp;\"); // NOI18N\n                builder.append(model.getExtraRowUnits(i));\n                builder.append(\"&nbsp;&nbsp;<br>\"); // NOI18N\n            }\n\n            builder.append(\"</html>\"); // NOI18N\n            return builder.toString();\n        }\n\n\n        public void selectionModeChanged(int newMode, int oldMode) {}\n\n        public void selectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds) {}\n\n        public void highlightedItemsChanged(List<ItemSelection> currentItems,\n                                            List<ItemSelection> addedItems,\n                                            List<ItemSelection> removedItems) {\n\n            updateTooltipText(currentItems);\n        }\n\n        public void selectedItemsChanged(List<ItemSelection> currentItems,\n                                         List<ItemSelection> addedItems,\n                                         List<ItemSelection> removedItems) {}\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/graphs/GraphsUI.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.graphs;\n\nimport java.awt.Color;\nimport java.util.ResourceBundle;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface GraphsUI {\n\n    // -----\n    // I18N String constants\n    static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.graphs.Bundle\"); // NOI18N\n    public static final String A_ALLOC_OBJECTS_NAME = messages.getString(\"GraphsUI_AllocObjects\"); // NOI18N\n    public static final String A_ALLOC_BYTES_NAME = messages.getString(\"GraphsUI_AllocBytes\"); // NOI18N\n    public static final String L_LIVE_OBJECTS_NAME = messages.getString(\"GraphsUI_LiveObjects\"); // NOI18N\n    public static final String L_LIVE_BYTES_NAME = messages.getString(\"GraphsUI_LiveBytes\"); // NOI18N\n    public static final String HEAP_SIZE_NAME = messages.getString(\"GraphsUI_HeapSize\"); // NOI18N\n    public static final String USED_HEAP_NAME = messages.getString(\"GraphsUI_UsedHeap\"); // NOI18N\n    public static final String SURVGEN_NAME = messages.getString(\"GraphsUI_SurvGen\"); // NOI18N\n    public static final String CPU_TIME_NAME = messages.getString(\"GraphsUI_CpuTime\"); // NOI18N\n    public static final String GC_TIME_NAME = messages.getString(\"GraphsUI_GcTime\"); // NOI18N\n    public static final String GC_INTERVALS_NAME = messages.getString(\"GraphsUI_GcIntervals\"); // NOI18N\n    public static final String THREADS_NAME = messages.getString(\"GraphsUI_Threads\"); // NOI18N\n    public static final String LOADED_CLASSES_NAME = messages.getString(\"GraphsUI_LoadedClasses\"); // NOI18N\n    public static final String CPU_GC_CAPTION = messages.getString(\"GraphsUI_CpuGcCaption\"); // NOI18N\n    public static final String MEMORY_CAPTION = messages.getString(\"GraphsUI_MemoryCaption\"); // NOI18N\n    public static final String GC_CAPTION = messages.getString(\"GraphsUI_GarbageCollectionCaption\"); // NOI18N\n    public static final String THREADS_CLASSES_CAPTION = messages.getString(\"GraphsUI_ThreadsClassesCaption\"); // NOI18N\n    // -----\n\n    // --- General colors definition -------------------------------------------\n\n    public static final Color  PROFILER_BLUE = new Color(127, 63, 191);\n    public static final Color  PROFILER_RED = new Color(255, 127, 127);\n    public static final Color  PROFILER_GREEN = new Color(30, 157, 68);\n\n\n    // --- Charts colors definition --------------------------------------------\n\n    public static final Color  CHART_BACKGROUND_COLOR = UIUtils.getProfilerResultsBackground();\n    public static final Color  SMALL_LEGEND_BACKGROUND_COLOR = UIUtils.getProfilerResultsBackground();\n    public static final Color  SMALL_LEGEND_BORDER_COLOR = new Color(235, 235, 235);\n\n    public static final float  TOOLTIP_OVERLAY_LINE_WIDTH = 2.1f;\n    public static final Color  TOOLTIP_OVERLAY_LINE_COLOR = Color.DARK_GRAY;\n    public static final Color  TOOLTIP_OVERLAY_FILL_COLOR = UIUtils.getProfilerResultsBackground();\n\n\n    // --- Class History graphs ------------------------------------------------\n\n    public static final float  A_ALLOC_OBJECTS_PAINTER_LINE_WIDTH = 2f;\n    public static final Color  A_ALLOC_OBJECTS_PAINTER_LINE_COLOR = PROFILER_RED;\n    public static final Color  A_ALLOC_OBJECTS_PAINTER_FILL_COLOR = null;\n    public static final int    A_ALLOC_OBJECTS_MARKER_RADIUS = 5;\n    public static final float  A_ALLOC_OBJECTS_MARKER_LINE1_WIDTH = 0.75f;\n    public static final Color  A_ALLOC_OBJECTS_MARKER_LINE1_COLOR = Color.BLACK;\n    public static final float  A_ALLOC_OBJECTS_MARKER_LINE2_WIDTH = 3.5f;\n    public static final Color  A_ALLOC_OBJECTS_MARKER_LINE2_COLOR = Color.WHITE;\n    public static final Color  A_ALLOC_OBJECTS_MARKER_FILL_COLOR = PROFILER_RED;\n    public static final long   A_ALLOC_OBJECTS_INITIAL_VALUE = 100l;\n\n    public static final float  A_ALLOC_BYTES_PAINTER_LINE_WIDTH = 2f;\n    public static final Color  A_ALLOC_BYTES_PAINTER_LINE_COLOR = PROFILER_BLUE;\n    public static final Color  A_ALLOC_BYTES_PAINTER_FILL_COLOR = null;\n    public static final int    A_ALLOC_BYTES_MARKER_RADIUS = 5;\n    public static final float  A_ALLOC_BYTES_MARKER_LINE1_WIDTH = 0.75f;\n    public static final Color  A_ALLOC_BYTES_MARKER_LINE1_COLOR = Color.BLACK;\n    public static final float  A_ALLOC_BYTES_MARKER_LINE2_WIDTH = 3.5f;\n    public static final Color  A_ALLOC_BYTES_MARKER_LINE2_COLOR = Color.WHITE;\n    public static final Color  A_ALLOC_BYTES_MARKER_FILL_COLOR = PROFILER_BLUE;\n    public static final long   A_ALLOC_BYTES_INITIAL_VALUE = 102400l;\n\n    public static final float  L_LIVE_OBJECTS_PAINTER_LINE_WIDTH = 2f;\n    public static final Color  L_LIVE_OBJECTS_PAINTER_LINE_COLOR = PROFILER_RED;\n    public static final Color  L_LIVE_OBJECTS_PAINTER_FILL_COLOR = null;\n    public static final int    L_LIVE_OBJECTS_MARKER_RADIUS = 5;\n    public static final float  L_LIVE_OBJECTS_MARKER_LINE1_WIDTH = 0.75f;\n    public static final Color  L_LIVE_OBJECTS_MARKER_LINE1_COLOR = Color.BLACK;\n    public static final float  L_LIVE_OBJECTS_MARKER_LINE2_WIDTH = 3.5f;\n    public static final Color  L_LIVE_OBJECTS_MARKER_LINE2_COLOR = Color.WHITE;\n    public static final Color  L_LIVE_OBJECTS_MARKER_FILL_COLOR = PROFILER_RED;\n    public static final long   L_LIVE_OBJECTS_INITIAL_VALUE = 100l;\n\n    public static final float  L_LIVE_BYTES_PAINTER_LINE_WIDTH = 2f;\n    public static final Color  L_LIVE_BYTES_PAINTER_LINE_COLOR = PROFILER_BLUE;\n    public static final Color  L_LIVE_BYTES_PAINTER_FILL_COLOR = null;\n    public static final int    L_LIVE_BYTES_MARKER_RADIUS = 5;\n    public static final float  L_LIVE_BYTES_MARKER_LINE1_WIDTH = 0.75f;\n    public static final Color  L_LIVE_BYTES_MARKER_LINE1_COLOR = Color.BLACK;\n    public static final float  L_LIVE_BYTES_MARKER_LINE2_WIDTH = 3.5f;\n    public static final Color  L_LIVE_BYTES_MARKER_LINE2_COLOR = Color.WHITE;\n    public static final Color  L_LIVE_BYTES_MARKER_FILL_COLOR = PROFILER_BLUE;\n    public static final long   L_LIVE_BYTES_INITIAL_VALUE = 102400l;\n\n    public static final String L_ALLOC_OBJECTS_NAME = A_ALLOC_OBJECTS_NAME;\n    public static final float  L_ALLOC_OBJECTS_PAINTER_LINE_WIDTH = 2f;\n    public static final Color  L_ALLOC_OBJECTS_PAINTER_LINE_COLOR = PROFILER_GREEN;\n    public static final Color  L_ALLOC_OBJECTS_PAINTER_FILL_COLOR = null;\n    public static final int    L_ALLOC_OBJECTS_MARKER_RADIUS = 5;\n    public static final float  L_ALLOC_OBJECTS_MARKER_LINE1_WIDTH = 0.75f;\n    public static final Color  L_ALLOC_OBJECTS_MARKER_LINE1_COLOR = Color.BLACK;\n    public static final float  L_ALLOC_OBJECTS_MARKER_LINE2_WIDTH = 3.5f;\n    public static final Color  L_ALLOC_OBJECTS_MARKER_LINE2_COLOR = Color.WHITE;\n    public static final Color  L_ALLOC_OBJECTS_MARKER_FILL_COLOR = PROFILER_GREEN;\n    public static final long   L_ALLOC_OBJECTS_INITIAL_VALUE = 100l;\n\n\n    // --- VM Telemetry graphs -------------------------------------------------\n\n    public static final float  HEAP_SIZE_PAINTER_LINE_WIDTH = 2f;\n    public static final Color  HEAP_SIZE_PAINTER_LINE_COLOR = null;\n    public static final Color  HEAP_SIZE_PAINTER_FILL_COLOR = PROFILER_RED;\n    public static final int    HEAP_SIZE_MARKER_RADIUS = 5;\n    public static final float  HEAP_SIZE_MARKER_LINE1_WIDTH = 0.75f;\n    public static final Color  HEAP_SIZE_MARKER_LINE1_COLOR = Color.BLACK;\n    public static final float  HEAP_SIZE_MARKER_LINE2_WIDTH = 3.5f;\n    public static final Color  HEAP_SIZE_MARKER_LINE2_COLOR = Color.WHITE;\n    public static final Color  HEAP_SIZE_MARKER_FILL_COLOR = PROFILER_RED;\n    public static final long   HEAP_SIZE_INITIAL_VALUE = 67108864; // 64 MB\n\n    public static final float  USED_HEAP_PAINTER_LINE_WIDTH = 2f;\n    public static final Color  USED_HEAP_PAINTER_LINE_COLOR = null;\n    public static final Color  USED_HEAP_PAINTER_FILL_COLOR = PROFILER_BLUE;\n    public static final int    USED_HEAP_MARKER_RADIUS = 5;\n    public static final float  USED_HEAP_MARKER_LINE1_WIDTH = 0.75f;\n    public static final Color  USED_HEAP_MARKER_LINE1_COLOR = Color.BLACK;\n    public static final float  USED_HEAP_MARKER_LINE2_WIDTH = 3.5f;\n    public static final Color  USED_HEAP_MARKER_LINE2_COLOR = Color.WHITE;\n    public static final Color  USED_HEAP_MARKER_FILL_COLOR = PROFILER_BLUE;\n    public static final long   USED_HEAP_INITIAL_VALUE = 16777216; // 16 MB\n\n    public static final Color  HEAP_LIMIT_FILL_COLOR = !UIUtils.isDarkResultsBackground() ?\n                               new Color(220, 220, 220) : new Color(100, 100, 100);\n\n    public static final float  SURVGEN_PAINTER_LINE_WIDTH = 2f;\n    public static final Color  SURVGEN_PAINTER_LINE_COLOR = PROFILER_RED;\n    public static final Color  SURVGEN_PAINTER_FILL_COLOR = null;\n    public static final int    SURVGEN_MARKER_RADIUS = 5;\n    public static final float  SURVGEN_MARKER_LINE1_WIDTH = 0.75f;\n    public static final Color  SURVGEN_MARKER_LINE1_COLOR = Color.BLACK;\n    public static final float  SURVGEN_MARKER_LINE2_WIDTH = 3.5f;\n    public static final Color  SURVGEN_MARKER_LINE2_COLOR = Color.WHITE;\n    public static final Color  SURVGEN_MARKER_FILL_COLOR = PROFILER_RED;\n    public static final long   SURVGEN_INITIAL_VALUE = 11;\n\n    public static final float  GC_TIME_PAINTER_LINE_WIDTH = 2f;\n    public static final Color  GC_TIME_PAINTER_LINE_COLOR = PROFILER_BLUE;\n    public static final Color  GC_TIME_PAINTER_FILL_COLOR = null;\n    public static final int    GC_TIME_MARKER_RADIUS = 5;\n    public static final float  GC_TIME_MARKER_LINE1_WIDTH = 0.75f;\n    public static final Color  GC_TIME_MARKER_LINE1_COLOR = Color.BLACK;\n    public static final float  GC_TIME_MARKER_LINE2_WIDTH = 3.5f;\n    public static final Color  GC_TIME_MARKER_LINE2_COLOR = Color.WHITE;\n    public static final Color  GC_TIME_MARKER_FILL_COLOR = PROFILER_BLUE;\n\n    public static final Color  GC_ACTIVITY_FILL_COLOR = PROFILER_BLUE;\n\n    public static final float  THREADS_PAINTER_LINE_WIDTH = 2f;\n    public static final Color  THREADS_PAINTER_LINE_COLOR = PROFILER_RED;\n    public static final Color  THREADS_PAINTER_FILL_COLOR = null;\n    public static final int    THREADS_MARKER_RADIUS = 5;\n    public static final float  THREADS_MARKER_LINE1_WIDTH = 0.75f;\n    public static final Color  THREADS_MARKER_LINE1_COLOR = Color.BLACK;\n    public static final float  THREADS_MARKER_LINE2_WIDTH = 3.5f;\n    public static final Color  THREADS_MARKER_LINE2_COLOR = Color.WHITE;\n    public static final Color  THREADS_MARKER_FILL_COLOR = PROFILER_RED;\n    public static final long   THREADS_INITIAL_VALUE = 3;\n\n    public static final float  LOADED_CLASSES_PAINTER_LINE_WIDTH = 2f;\n    public static final Color  LOADED_CLASSES_PAINTER_LINE_COLOR = PROFILER_BLUE;\n    public static final Color  LOADED_CLASSES_PAINTER_FILL_COLOR = null;\n    public static final int    LOADED_CLASSES_MARKER_RADIUS = 5;\n    public static final float  LOADED_CLASSES_MARKER_LINE1_WIDTH = 0.75f;\n    public static final Color  LOADED_CLASSES_MARKER_LINE1_COLOR = Color.BLACK;\n    public static final float  LOADED_CLASSES_MARKER_LINE2_WIDTH = 3.5f;\n    public static final Color  LOADED_CLASSES_MARKER_LINE2_COLOR = Color.WHITE;\n    public static final Color  LOADED_CLASSES_MARKER_FILL_COLOR = PROFILER_BLUE;\n    public static final long   LOADED_CLASSES_INITIAL_VALUE = 732;\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/graphs/LivenessHistoryGraphPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.graphs;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.FlowLayout;\nimport java.awt.Insets;\nimport java.util.Date;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemsModel;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.axis.AxisComponent;\nimport org.graalvm.visualvm.lib.charts.axis.BytesAxisUtils;\nimport org.graalvm.visualvm.lib.charts.axis.BytesMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.SimpleLongMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimeMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimelineMarksComputer;\nimport org.graalvm.visualvm.lib.charts.swing.CrossBorderLayout;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.BytesXYItemMarksComputer;\nimport org.graalvm.visualvm.lib.charts.xy.CompoundXYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.DecimalXYItemMarksComputer;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemMarker;\nimport org.graalvm.visualvm.lib.jfluid.results.DataManagerListener;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYChart;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYItemPainter;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYSelectionOverlay;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipModel;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipOverlay;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipPainter;\nimport org.graalvm.visualvm.lib.ui.components.ColorIcon;\nimport org.graalvm.visualvm.lib.ui.memory.ClassHistoryModels;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class LivenessHistoryGraphPanel extends GraphPanel {\n\n    private ProfilerXYChart chart;\n    private Action[] chartActions;\n\n    private final ClassHistoryModels models;\n\n\n    // --- Constructors --------------------------------------------------------\n\n    public static LivenessHistoryGraphPanel createPanel(ClassHistoryModels models) {\n        return new LivenessHistoryGraphPanel(models);\n    }\n\n    private LivenessHistoryGraphPanel(ClassHistoryModels models) {\n\n        // Save models and panel type\n        this.models = models;\n\n        // Create UI\n        initComponents();\n\n        // Register listener\n        models.getDataManager().addDataListener(new DataManagerListener() {\n            public void dataChanged() { updateData(); }\n            public void dataReset() { resetData(); }\n        });\n\n        // Initialize chart & legend\n        resetData();\n    }\n\n\n    // --- GraphPanel implementation -------------------------------------------\n\n    public Action[] getActions() {\n        return chartActions;\n    }\n    \n    public void cleanup() {}\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void updateData() {\n    }\n\n    private void resetData() {\n        chart.setScale(INITIAL_CHART_SCALEX, 1);\n        chart.setOffset(0, 0);\n        chart.setFitsWidth(false);\n        chart.setInitialDataBounds(new LongRect(System.currentTimeMillis(), 0,\n                                       2500, GraphsUI.L_LIVE_OBJECTS_INITIAL_VALUE));\n    }\n\n\n    private void initComponents() {\n        // Painters model\n        PaintersModel paintersModel = createLivenessPaintersModel();\n\n        // Chart\n        chart = createChart(models.livenessItemsModel(),\n                            paintersModel, false);\n        chart.setBackground(GraphsUI.CHART_BACKGROUND_COLOR);\n        chart.setViewInsets(new Insets(10, 0, 0, 0));\n\n        // Horizontal axis\n        AxisComponent hAxis =\n                new AxisComponent(chart, new TimelineMarksComputer(\n                         models.livenessItemsModel().getTimeline(),\n                         chart.getChartContext(), SwingConstants.HORIZONTAL),\n                         new TimeMarksPainter(),\n                         SwingConstants.SOUTH, AxisComponent.MESH_FOREGROUND);\n\n        // Live objects axis\n        XYItem liveObjectsItem = models.livenessItemsModel().getItem(0);\n        XYItemPainter liveObjectsPainter = (XYItemPainter)paintersModel.getPainter(liveObjectsItem);\n        SimpleLongMarksPainter liveObjectsMarksPainter = new SimpleLongMarksPainter();\n        liveObjectsMarksPainter.setForeground(GraphsUI.L_LIVE_OBJECTS_PAINTER_LINE_COLOR);\n        AxisComponent loAxis =\n                new AxisComponent(chart, new DecimalXYItemMarksComputer(\n                         liveObjectsItem, liveObjectsPainter, chart.getChartContext(),\n                         SwingConstants.VERTICAL),\n                         liveObjectsMarksPainter, SwingConstants.WEST,\n                         AxisComponent.MESH_FOREGROUND);\n\n        // Live bytes axis\n        XYItem liveBytesItem = models.livenessItemsModel().getItem(1);\n        XYItemPainter liveBytesPainter = (XYItemPainter)paintersModel.getPainter(liveBytesItem);\n        BytesMarksPainter allocBytesMarksPainter = new BytesMarksPainter();\n        allocBytesMarksPainter.setForeground(GraphsUI.L_LIVE_BYTES_PAINTER_LINE_COLOR);\n        AxisComponent lbAxis =\n                new AxisComponent(chart, new BytesXYItemMarksComputer(\n                         liveBytesItem, liveBytesPainter, chart.getChartContext(),\n                         SwingConstants.VERTICAL),\n                         allocBytesMarksPainter, SwingConstants.EAST,\n                         AxisComponent.NO_MESH);\n\n        // Allocated objects axis\n        XYItem allocObjectsItem = models.livenessItemsModel().getItem(2);\n        XYItemPainter allocObjectsPainter = (XYItemPainter)paintersModel.getPainter(allocObjectsItem);\n        SimpleLongMarksPainter allocObjectsMarksPainter = new SimpleLongMarksPainter();\n        allocObjectsMarksPainter.setForeground(GraphsUI.L_ALLOC_OBJECTS_PAINTER_LINE_COLOR);\n        AxisComponent aoAxis =\n                new AxisComponent(chart, new DecimalXYItemMarksComputer(\n                         allocObjectsItem, allocObjectsPainter, chart.getChartContext(),\n                         SwingConstants.VERTICAL),\n                         allocObjectsMarksPainter, SwingConstants.EAST,\n                         AxisComponent.NO_MESH);\n\n        JPanel multiAxisContainer = new JPanel(new BorderLayout());\n        multiAxisContainer.add(lbAxis, BorderLayout.WEST);\n        multiAxisContainer.add(aoAxis, BorderLayout.EAST);\n        multiAxisContainer.setBackground(GraphsUI.CHART_BACKGROUND_COLOR);\n\n        // Chart panel (chart & axes)\n        JPanel chartPanel = new JPanel(new CrossBorderLayout());\n        chartPanel.setBackground(GraphsUI.CHART_BACKGROUND_COLOR);\n        chartPanel.setBorder(BorderFactory.createMatteBorder(\n                             10, 10, 10, 10, GraphsUI.CHART_BACKGROUND_COLOR));\n        chartPanel.add(chart, new Integer[] { SwingConstants.CENTER });\n        chartPanel.add(hAxis, new Integer[] { SwingConstants.SOUTH,\n                                              SwingConstants.SOUTH_WEST,\n                                              SwingConstants.SOUTH_EAST });\n        chartPanel.add(loAxis, new Integer[] { SwingConstants.WEST,\n                                              SwingConstants.SOUTH_WEST });\n        chartPanel.add(multiAxisContainer, new Integer[] { SwingConstants.EAST,\n                                              SwingConstants.SOUTH_EAST });\n\n        // Tooltip support\n        ProfilerXYTooltipPainter tooltipPainter = new ProfilerXYTooltipPainter(createTooltipModel());\n        chart.addOverlayComponent(new ProfilerXYTooltipOverlay(chart, tooltipPainter));\n        chart.getSelectionModel().setHoverMode(ChartSelectionModel.HOVER_EACH_NEAREST);\n\n        // Hovering support\n        ProfilerXYSelectionOverlay selectionOverlay = new ProfilerXYSelectionOverlay();\n        chart.addOverlayComponent(selectionOverlay);\n        selectionOverlay.registerChart(chart);\n        chart.getSelectionModel().setMoveMode(ChartSelectionModel.SELECTION_LINE_V);\n            \n//        // Setup tooltip painter\n//        ProfilerXYTooltipPainter tooltipPainter = new ProfilerXYTooltipPainter(\n//                                            GraphsUI.TOOLTIP_OVERLAY_LINE_WIDTH,\n//                                            GraphsUI.TOOLTIP_OVERLAY_LINE_COLOR,\n//                                            GraphsUI.TOOLTIP_OVERLAY_FILL_COLOR,\n//                                            getTooltipModel());\n//\n//        // Customize chart\n//        chart.addOverlayComponent(new ProfilerXYTooltipOverlay(chart,\n//                                                               tooltipPainter));\n//\n//        // Chart scrollbar\n//        JScrollBar hScrollBar = new JScrollBar(JScrollBar.HORIZONTAL);\n//        chart.attachHorizontalScrollBar(hScrollBar);\n\n        // Chart container (chart panel & scrollbar)\n        JPanel chartContainer = new JPanel(new BorderLayout());\n        chartContainer.setBorder(BorderFactory.createEmptyBorder());\n        chartContainer.add(chartPanel, BorderLayout.CENTER);\n//        chartContainer.add(hScrollBar, BorderLayout.SOUTH);\n\n        // Live Objects\n        JLabel liveObjectsBig = new JLabel(GraphsUI.L_LIVE_OBJECTS_NAME,\n                                        new ColorIcon(GraphsUI.\n                                        L_LIVE_OBJECTS_PAINTER_LINE_COLOR, Color.\n                                        BLACK, 18, 9), SwingConstants.LEADING);\n        liveObjectsBig.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n\n        // Live Bytes\n        JLabel liveBytesBig = new JLabel(GraphsUI.L_LIVE_BYTES_NAME,\n                                        new ColorIcon(GraphsUI.\n                                        L_LIVE_BYTES_PAINTER_LINE_COLOR, Color.\n                                        BLACK, 18, 9), SwingConstants.LEADING);\n        liveBytesBig.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n\n        // Allocated Objects\n        JLabel allocObjectsBig = new JLabel(GraphsUI.L_ALLOC_OBJECTS_NAME,\n                                        new ColorIcon(GraphsUI.\n                                        L_ALLOC_OBJECTS_PAINTER_LINE_COLOR, Color.\n                                        BLACK, 18, 9), SwingConstants.LEADING);\n        allocObjectsBig.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n\n        // Legend container\n        JPanel bigLegendPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 7, 8));\n        bigLegendPanel.setOpaque(false);\n        bigLegendPanel.add(liveObjectsBig);\n        bigLegendPanel.add(liveBytesBig);\n        bigLegendPanel.add(allocObjectsBig);\n        \n        JPanel legendContainer = new JPanel(new BorderLayout(0, 0));\n        UIUtils.decorateProfilerPanel(legendContainer);\n        legendContainer.add(UIUtils.createHorizontalLine(legendContainer.getBackground()), BorderLayout.NORTH);\n        legendContainer.add(bigLegendPanel, BorderLayout.CENTER);\n\n        // Master UI\n        setLayout(new BorderLayout());\n        add(chartContainer, BorderLayout.CENTER);\n        add(legendContainer, BorderLayout.SOUTH);\n\n\n        // Toolbar actions\n        chartActions = new Action[] { chart.zoomInAction(),\n                                      chart.zoomOutAction(),\n                                      chart.toggleViewAction()};\n\n    }\n\n    protected ProfilerXYTooltipModel createTooltipModel() {\n        return new ProfilerXYTooltipModel() {\n\n            public String getTimeValue(long timestamp) {\n                return DATE_FORMATTER.format(new Date(timestamp));\n            }\n\n            public int getRowsCount() {\n                return 3;\n            }\n\n            public String getRowName(int index) {\n                switch (index) {\n                    case 0:\n                        return GraphsUI.L_LIVE_OBJECTS_NAME;\n                    case 1:\n                        return GraphsUI.L_LIVE_BYTES_NAME;\n                    case 2:\n                        return GraphsUI.L_ALLOC_OBJECTS_NAME;\n                    default:\n                        return null;\n                }\n            }\n\n            public Color getRowColor(int index) {\n                switch (index) {\n                    case 0:\n                        return GraphsUI.L_LIVE_OBJECTS_PAINTER_LINE_COLOR;\n                    case 1:\n                        return GraphsUI.L_LIVE_BYTES_PAINTER_LINE_COLOR;\n                    case 2:\n                        return GraphsUI.L_ALLOC_OBJECTS_PAINTER_LINE_COLOR;\n                    default:\n                        return null;\n                }\n            }\n\n            public String getRowValue(int index, long itemValue) {\n                return INT_FORMATTER.format(itemValue);\n            }\n\n            public String getRowUnits(int index) {\n                switch (index) {\n                    case 0:\n                        return \"\"; // NOI18N\n                    case 1:\n                        return BytesAxisUtils.UNITS_B;\n                    case 2:\n                        return \"\"; // NOI18N\n                    default:\n                        return null;\n                }\n            }\n\n            public int getExtraRowsCount() {\n                return getRowsCount();\n            }\n\n            public String getExtraRowName(int index) {\n                return getMaxValueString(getRowName(index));\n            }\n\n            public Color getExtraRowColor(int index) {\n                return getRowColor(index);\n            }\n\n            public String getExtraRowValue(int index) {\n                SynchronousXYItem item = models.livenessItemsModel().getItem(index);\n                return INT_FORMATTER.format(item.getMaxYValue());\n            }\n\n            public String getExtraRowUnits(int index) {\n                return getRowUnits(index);\n            }\n\n        };\n    }\n\n    private PaintersModel createLivenessPaintersModel() {\n        // Live Objects\n        ProfilerXYItemPainter liveObjectsPainter =\n                ProfilerXYItemPainter.absolutePainter(GraphsUI.L_LIVE_OBJECTS_PAINTER_LINE_WIDTH,\n                                                      GraphsUI.L_LIVE_OBJECTS_PAINTER_LINE_COLOR,\n                                                      GraphsUI.L_LIVE_OBJECTS_PAINTER_FILL_COLOR);\n        SynchronousXYItemMarker liveObjectsMarker =\n                 SynchronousXYItemMarker.absolutePainter(GraphsUI.L_LIVE_OBJECTS_MARKER_RADIUS,\n                                                      GraphsUI.L_LIVE_OBJECTS_MARKER_LINE1_WIDTH,\n                                                      GraphsUI.L_LIVE_OBJECTS_MARKER_LINE1_COLOR,\n                                                      GraphsUI.L_LIVE_OBJECTS_MARKER_LINE2_WIDTH,\n                                                      GraphsUI.L_LIVE_OBJECTS_MARKER_LINE2_COLOR,\n                                                      GraphsUI.L_LIVE_OBJECTS_MARKER_FILL_COLOR);\n        XYItemPainter lop = new CompoundXYItemPainter(liveObjectsPainter,\n                                                      liveObjectsMarker);\n\n        // Live Bytes\n        ProfilerXYItemPainter liveBytesPainter =\n                ProfilerXYItemPainter.relativePainter(GraphsUI.L_LIVE_BYTES_PAINTER_LINE_WIDTH,\n                                                      GraphsUI.L_LIVE_BYTES_PAINTER_LINE_COLOR,\n                                                      GraphsUI.L_LIVE_BYTES_PAINTER_FILL_COLOR,\n                                                      10);\n        SynchronousXYItemMarker liveBytesMarker =\n                 SynchronousXYItemMarker.relativePainter(GraphsUI.L_LIVE_BYTES_MARKER_RADIUS,\n                                                      GraphsUI.L_LIVE_BYTES_MARKER_LINE1_WIDTH,\n                                                      GraphsUI.L_LIVE_BYTES_MARKER_LINE1_COLOR,\n                                                      GraphsUI.L_LIVE_BYTES_MARKER_LINE2_WIDTH,\n                                                      GraphsUI.L_LIVE_BYTES_MARKER_LINE2_COLOR,\n                                                      GraphsUI.L_LIVE_BYTES_MARKER_FILL_COLOR,\n                                                      10);\n        XYItemPainter lbp = new CompoundXYItemPainter(liveBytesPainter,\n                                                      liveBytesMarker);\n\n        // Allocated Objects\n        ProfilerXYItemPainter allocObjectsPainter =\n                ProfilerXYItemPainter.relativePainter(GraphsUI.L_ALLOC_OBJECTS_PAINTER_LINE_WIDTH,\n                                                      GraphsUI.L_ALLOC_OBJECTS_PAINTER_LINE_COLOR,\n                                                      GraphsUI.L_ALLOC_OBJECTS_PAINTER_FILL_COLOR,\n                                                      20);\n        SynchronousXYItemMarker allocObjectsMarker =\n                 SynchronousXYItemMarker.relativePainter(GraphsUI.L_ALLOC_OBJECTS_MARKER_RADIUS,\n                                                      GraphsUI.L_ALLOC_OBJECTS_MARKER_LINE1_WIDTH,\n                                                      GraphsUI.L_ALLOC_OBJECTS_MARKER_LINE1_COLOR,\n                                                      GraphsUI.L_ALLOC_OBJECTS_MARKER_LINE2_WIDTH,\n                                                      GraphsUI.L_ALLOC_OBJECTS_MARKER_LINE2_COLOR,\n                                                      GraphsUI.L_ALLOC_OBJECTS_MARKER_FILL_COLOR,\n                                                      20);\n        XYItemPainter aop = new CompoundXYItemPainter(allocObjectsPainter,\n                                                      allocObjectsMarker);\n\n        // Model\n        ItemsModel items = models.livenessItemsModel();\n        PaintersModel model = new PaintersModel.Default(\n                                            new ChartItem[] { items.getItem(0),\n                                                              items.getItem(1),\n                                                              items.getItem(2) },\n                                            new XYItemPainter[] { lop, lbp, aop });\n\n        return model;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/graphs/MemoryGraphPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.graphs;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.FlowLayout;\nimport java.awt.Font;\nimport java.awt.Graphics2D;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport java.util.Date;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartDecorator;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemsModel;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.axis.AxisComponent;\nimport org.graalvm.visualvm.lib.charts.axis.BytesAxisUtils;\nimport org.graalvm.visualvm.lib.charts.axis.BytesMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimeMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimelineMarksComputer;\nimport org.graalvm.visualvm.lib.charts.swing.CrossBorderLayout;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.BytesXYItemMarksComputer;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.jfluid.results.DataManagerListener;\nimport org.graalvm.visualvm.lib.jfluid.results.monitor.VMTelemetryDataManager;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYChart;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYItemPainter;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYSelectionOverlay;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipModel;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipOverlay;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipPainter;\nimport org.graalvm.visualvm.lib.ui.components.ColorIcon;\nimport org.graalvm.visualvm.lib.ui.monitor.VMTelemetryModels;\nimport org.graalvm.visualvm.lib.ui.swing.InvisibleToolbar;\n\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class MemoryGraphPanel extends GraphPanel {\n    \n    private final Color SIZE_COLOR = ColorFactory.getPredefinedColor(0);\n    private final Color[] SIZE_GRADIENT = ColorFactory.getPredefinedGradient(0);\n    private final Color USED_COLOR = ColorFactory.getPredefinedColor(1);\n    private final Color[] USED_GRADIENT = ColorFactory.getPredefinedGradient(1);\n\n    private ProfilerXYChart chart;\n    private Action[] chartActions;\n\n    private final VMTelemetryModels models;\n    private final DataManagerListener listener;\n\n    private final boolean smallPanel;\n\n\n    // --- Constructors --------------------------------------------------------\n    \n    public static MemoryGraphPanel createBigPanel(VMTelemetryModels models) {\n        return new MemoryGraphPanel(models, false, null);\n    }\n    \n    public static MemoryGraphPanel createSmallPanel(VMTelemetryModels models,\n                                             Action chartAction) {\n        return new MemoryGraphPanel(models, true, chartAction);\n    }\n\n    private MemoryGraphPanel(VMTelemetryModels models,\n                             boolean smallPanel, Action chartAction) {\n\n        // Save models and panel type\n        this.models = models;\n        this.smallPanel = smallPanel;\n\n        // Create UI\n        initComponents(chartAction);\n\n        // Register listener\n        listener = new DataManagerListener() {\n            public void dataChanged() { updateData(); }\n            public void dataReset() { resetData(); }\n        };\n        models.getDataManager().addDataListener(listener);\n\n        // Initialize chart & legend\n        resetData();\n    }\n\n\n    // --- GraphPanel implementation -------------------------------------------\n\n    public Action[] getActions() {\n        return chartActions;\n    }\n    \n    public void cleanup() {\n        models.getDataManager().removeDataListener(listener);\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void updateData() {\n        if (smallPanel) {\n            if (chart.fitsWidth()) {\n                VMTelemetryDataManager manager = models.getDataManager();\n                long[] timestamps = manager.timeStamps;\n                if (timestamps[manager.getItemCount() - 1] - timestamps[0] >=\n                    SMALL_CHART_FIT_TO_WINDOW_PERIOD)\n                        chart.setFitsWidth(false);\n            }\n        } else {\n        }\n    }\n\n    private void resetData() {\n        if (smallPanel) {\n            chart.setScale(INITIAL_CHART_SCALEX, 1);\n            chart.setOffset(0, 0);\n            chart.setFitsWidth(true);\n        } else {\n            chart.setScale(INITIAL_CHART_SCALEX, 1);\n            chart.setOffset(0, 0);\n            chart.setFitsWidth(false);\n        }\n        chart.setInitialDataBounds(new LongRect(System.currentTimeMillis(), 0,\n                                       2500, GraphsUI.HEAP_SIZE_INITIAL_VALUE));\n    }\n\n    \n    private void initComponents(final Action chartAction) {\n        // Painters model\n        PaintersModel paintersModel = createMemoryPaintersModel();\n\n        // Chart\n        chart = createChart(models.memoryItemsModel(),\n                            paintersModel, smallPanel);\n        chart.setBackground(GraphsUI.CHART_BACKGROUND_COLOR);\n        chart.setViewInsets(new Insets(10, 0, 0, 0));\n        \n        chart.addPreDecorator(createMaxHeapDecorator());\n\n        // Horizontal axis\n        AxisComponent hAxis =\n                new AxisComponent(chart, new TimelineMarksComputer(\n                         models.memoryItemsModel().getTimeline(),\n                         chart.getChartContext(), SwingConstants.HORIZONTAL),\n                         new TimeMarksPainter(),\n                         SwingConstants.NORTH, AxisComponent.MESH_FOREGROUND);\n        hAxis.setForeground(Color.GRAY);\n\n        // Vertical axis\n        XYItem memoryItem = models.memoryItemsModel().getItem(0);\n        XYItemPainter memoryPainter = (XYItemPainter)paintersModel.getPainter(memoryItem);\n        AxisComponent vAxis =\n                new AxisComponent(chart, new BytesXYItemMarksComputer(\n                         memoryItem, memoryPainter, chart.getChartContext(),\n                         SwingConstants.VERTICAL),\n                         new BytesMarksPainter(), SwingConstants.WEST,\n                         AxisComponent.MESH_FOREGROUND);\n        vAxis.setForeground(Color.GRAY);\n\n        // Chart panel (chart & axes)\n        JPanel chartPanel = new JPanel(new CrossBorderLayout());\n        chartPanel.setBackground(GraphsUI.CHART_BACKGROUND_COLOR);\n        chartPanel.setBorder(BorderFactory.createMatteBorder(\n                             10, 10, 5, 5, GraphsUI.CHART_BACKGROUND_COLOR));\n        chartPanel.add(chart, new Integer[] { SwingConstants.CENTER });\n        chartPanel.add(hAxis, new Integer[] { SwingConstants.NORTH,\n                                              SwingConstants.NORTH_EAST,\n                                              SwingConstants.NORTH_WEST });\n        chartPanel.add(vAxis, new Integer[] { SwingConstants.WEST,\n                                              SwingConstants.SOUTH_WEST });\n        \n        JScrollBar scroller = new JScrollBar(JScrollBar.HORIZONTAL);\n        chart.attachHorizontalScrollBar(scroller);\n        chartPanel.add(scroller, new Integer[] { SwingConstants.SOUTH });\n\n        // Small panel UI\n        if (smallPanel) {\n\n        // Big panel UI\n        } else {\n            \n            // Tooltip support\n            ProfilerXYTooltipPainter tooltipPainter = new ProfilerXYTooltipPainter(createTooltipModel());\n            chart.addOverlayComponent(new ProfilerXYTooltipOverlay(chart, tooltipPainter));\n            chart.getSelectionModel().setHoverMode(ChartSelectionModel.HOVER_EACH_NEAREST);\n\n            // Hovering support\n            ProfilerXYSelectionOverlay selectionOverlay = new ProfilerXYSelectionOverlay();\n            chart.addOverlayComponent(selectionOverlay);\n            selectionOverlay.registerChart(chart);\n            chart.getSelectionModel().setMoveMode(ChartSelectionModel.SELECTION_LINE_V);\n\n            // Chart container (chart panel & scrollbar)\n            JPanel chartContainer = new JPanel(new BorderLayout());\n            chartContainer.setBorder(BorderFactory.createEmptyBorder());\n            chartContainer.add(chartPanel, BorderLayout.CENTER);\n            \n            // Side panel\n            JPanel sidePanel = new JPanel(new BorderLayout());\n            sidePanel.setOpaque(false);\n            int h = new JLabel(\"XXX\").getPreferredSize().height; // NOI18N\n            sidePanel.setBorder(BorderFactory.createEmptyBorder(h + 17, 0, 0, 10));\n            InvisibleToolbar toolbar = new InvisibleToolbar(InvisibleToolbar.VERTICAL);\n            toolbar.setOpaque(true);\n            toolbar.setBackground(UIUtils.getProfilerResultsBackground());\n            toolbar.add(chart.toggleViewAction()).setBackground(UIUtils.getProfilerResultsBackground());\n            toolbar.add(chart.zoomInAction()).setBackground(UIUtils.getProfilerResultsBackground());\n            toolbar.add(chart.zoomOutAction()).setBackground(UIUtils.getProfilerResultsBackground());\n            sidePanel.add(toolbar, BorderLayout.CENTER);      \n\n            // Heap Size\n            JLabel heapSizeBig = new JLabel(GraphsUI.HEAP_SIZE_NAME,\n                                            new ColorIcon(SIZE_COLOR, Color.\n                                            BLACK, 18, 9), SwingConstants.LEADING);\n            heapSizeBig.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n\n            // Used heap\n            JLabel usedHeapBig = new JLabel(GraphsUI.USED_HEAP_NAME,\n                                            new ColorIcon(USED_COLOR, Color.\n                                            BLACK, 18, 9), SwingConstants.LEADING);\n            usedHeapBig.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n\n            // Legend container\n            JPanel bigLegendPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 7, 0));\n            bigLegendPanel.setBorder(BorderFactory.createEmptyBorder(4, 0, 8, 30));\n            bigLegendPanel.setOpaque(true);\n            bigLegendPanel.setBackground(UIUtils.getProfilerResultsBackground());\n            bigLegendPanel.add(heapSizeBig);\n            bigLegendPanel.add(usedHeapBig);\n\n            // Master UI\n            setLayout(new BorderLayout());\n            setBackground(UIUtils.getProfilerResultsBackground());\n            JLabel caption = new JLabel(GraphsUI.MEMORY_CAPTION, JLabel.CENTER);\n            caption.setFont(caption.getFont().deriveFont(Font.BOLD));\n            caption.setBorder(BorderFactory.createEmptyBorder(15, 0, 0, 0));\n            caption.setOpaque(true);\n            caption.setBackground(UIUtils.getProfilerResultsBackground());\n            add(caption, BorderLayout.NORTH);\n            add(chartContainer, BorderLayout.CENTER);\n            add(bigLegendPanel, BorderLayout.SOUTH);\n            add(sidePanel, BorderLayout.EAST);\n\n            // Toolbar actions\n            chartActions = new Action[] { chart.zoomInAction(),\n                                          chart.zoomOutAction(),\n                                          chart.toggleViewAction()};\n\n        }\n\n    }\n    \n\n    protected ProfilerXYTooltipModel createTooltipModel() {\n        return new ProfilerXYTooltipModel() {\n\n            public String getTimeValue(long timestamp) {\n                return DATE_FORMATTER.format(new Date(timestamp));\n            }\n\n            public int getRowsCount() {\n                return 2;\n            }\n\n            public String getRowName(int index) {\n                switch (index) {\n                    case 0:\n                        return GraphsUI.HEAP_SIZE_NAME;\n                    case 1:\n                        return GraphsUI.USED_HEAP_NAME;\n                    default:\n                        return null;\n                }\n            }\n\n            public Color getRowColor(int index) {\n                switch (index) {\n                    case 0:\n                        return GraphsUI.HEAP_SIZE_PAINTER_FILL_COLOR;\n                    case 1:\n                        return GraphsUI.USED_HEAP_PAINTER_FILL_COLOR;\n                    default:\n                        return null;\n                }\n            }\n\n            public String getRowValue(int index, long itemValue) {\n                return INT_FORMATTER.format(itemValue);\n            }\n\n            public String getRowUnits(int index) {\n                return BytesAxisUtils.UNITS_B;\n            }\n\n            public int getExtraRowsCount() {\n                return getRowsCount();\n            }\n\n            public String getExtraRowName(int index) {\n                return getMaxValueString(getRowName(index));\n            }\n\n            public Color getExtraRowColor(int index) {\n                return getRowColor(index);\n            }\n\n            public String getExtraRowValue(int index) {\n                SynchronousXYItem item = models.memoryItemsModel().getItem(index);\n                return INT_FORMATTER.format(item.getMaxYValue());\n            }\n\n            public String getExtraRowUnits(int index) {\n                return getRowUnits(index);\n            }\n\n        };\n    }\n\n    private PaintersModel createMemoryPaintersModel() {\n        // Heap size\n        ProfilerXYItemPainter heapSizePainter =\n                ProfilerXYItemPainter.absolutePainter(GraphsUI.HEAP_SIZE_PAINTER_LINE_WIDTH,\n                                                      SIZE_COLOR,\n                                                      SIZE_GRADIENT[0]);\n         XYItemPainter hsp = heapSizePainter;\n\n        // Used heap\n        ProfilerXYItemPainter usedHeapPainter =\n                ProfilerXYItemPainter.absolutePainter(GraphsUI.USED_HEAP_PAINTER_LINE_WIDTH,\n                                                      USED_COLOR,\n                                                      USED_GRADIENT[0]);\n        XYItemPainter uhp = usedHeapPainter;\n\n        // Model\n        ItemsModel items = models.memoryItemsModel();\n        PaintersModel model = new PaintersModel.Default(\n                                            new ChartItem[] { items.getItem(0),\n                                                              items.getItem(1) },\n                                            new XYItemPainter[] { hsp, uhp });\n\n        return model;\n    }\n\n    private ChartDecorator createMaxHeapDecorator() {\n        return new ChartDecorator() {\n            public void paint(Graphics2D g, Rectangle dirtyArea,\n                              ChartContext context) {\n\n                int limitHeight = Utils.checkedInt(\n                                  context.getViewY(models.getDataManager().\n                                  maxHeapSize));\n                if (limitHeight <= context.getViewportHeight()) {\n                    g.setColor(GraphsUI.HEAP_LIMIT_FILL_COLOR);\n                    if (context.isBottomBased())\n                        g.fillRect(0, 0, context.getViewportWidth(), limitHeight);\n                    else\n                        g.fillRect(0, limitHeight, context.getViewportWidth(),\n                                   context.getViewportHeight() - limitHeight);\n                }\n            }\n        };\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/graphs/SurvivingGenerationsGraphPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.graphs;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.FlowLayout;\nimport java.awt.Font;\nimport java.awt.Insets;\nimport java.util.Date;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemsModel;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.axis.AxisComponent;\nimport org.graalvm.visualvm.lib.charts.axis.SimpleLongMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimeMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimelineMarksComputer;\nimport org.graalvm.visualvm.lib.charts.swing.CrossBorderLayout;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.DecimalXYItemMarksComputer;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.jfluid.results.DataManagerListener;\nimport org.graalvm.visualvm.lib.jfluid.results.monitor.VMTelemetryDataManager;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerGCXYItemPainter;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYChart;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYItemPainter;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYSelectionOverlay;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipModel;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipOverlay;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipPainter;\nimport org.graalvm.visualvm.lib.ui.components.ColorIcon;\nimport org.graalvm.visualvm.lib.ui.monitor.VMTelemetryModels;\nimport org.graalvm.visualvm.lib.ui.swing.InvisibleToolbar;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class SurvivingGenerationsGraphPanel extends GraphPanel {\n    \n    private final Color GENERATIONS_COLOR = ColorFactory.getPredefinedColor(0);\n    private final Color GC_INTERVALS_COLOR = ColorFactory.getPredefinedColor(1);\n\n    private ProfilerXYChart chart;\n    private Action[] chartActions;\n\n    private final VMTelemetryModels models;\n    private final DataManagerListener listener;\n\n    private final boolean smallPanel;\n\n\n    // --- Constructors --------------------------------------------------------\n\n    public static SurvivingGenerationsGraphPanel createBigPanel(VMTelemetryModels models) {\n        return new SurvivingGenerationsGraphPanel(models, false, null);\n    }\n\n    public static SurvivingGenerationsGraphPanel createSmallPanel(VMTelemetryModels models,\n                                             Action chartAction) {\n        return new SurvivingGenerationsGraphPanel(models, true, chartAction);\n    }\n\n    private SurvivingGenerationsGraphPanel(VMTelemetryModels models,\n                             boolean smallPanel, Action chartAction) {\n\n        // Save models and panel type\n        this.models = models;\n        this.smallPanel = smallPanel;\n\n        // Create UI\n        initComponents(chartAction);\n\n        // Register listener\n        listener = new DataManagerListener() {\n            public void dataChanged() { updateData(); }\n            public void dataReset() { resetData(); }\n        };\n        models.getDataManager().addDataListener(listener);\n\n        // Initialize chart & legend\n        resetData();\n    }\n\n\n    // --- GraphPanel implementation -------------------------------------------\n\n    public Action[] getActions() {\n        return chartActions;\n    }\n    \n    public void cleanup() {\n        models.getDataManager().removeDataListener(listener);\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void updateData() {\n        if (smallPanel) {\n            if (chart.fitsWidth()) {\n                VMTelemetryDataManager manager = models.getDataManager();\n                long[] timestamps = manager.timeStamps;\n                if (timestamps[manager.getItemCount() - 1] - timestamps[0] >=\n                    SMALL_CHART_FIT_TO_WINDOW_PERIOD)\n                        chart.setFitsWidth(false);\n            }\n        } else {\n        }\n    }\n\n    private void resetData() {\n        if (smallPanel) {\n            chart.setScale(INITIAL_CHART_SCALEX, 1);\n            chart.setOffset(0, 0);\n            chart.setFitsWidth(true);\n        } else {\n            chart.setScale(INITIAL_CHART_SCALEX, 1);\n            chart.setOffset(0, 0);\n            chart.setFitsWidth(false);\n        }\n        chart.setInitialDataBounds(new LongRect(System.currentTimeMillis(), 0,\n                                       2500, GraphsUI.SURVGEN_INITIAL_VALUE));\n    }\n\n\n    private void initComponents(final Action chartAction) {\n        // Painters model\n        PaintersModel paintersModel = createGenerationsPaintersModel();\n\n        // Chart\n        chart = createChart(models.generationsItemsModel(),\n                            paintersModel, smallPanel);\n        chart.setBackground(GraphsUI.CHART_BACKGROUND_COLOR);\n        chart.setViewInsets(new Insets(10, 0, 0, 0));\n\n        // Horizontal axis\n        AxisComponent hAxis =\n                new AxisComponent(chart, new TimelineMarksComputer(\n                         models.generationsItemsModel().getTimeline(),\n                         chart.getChartContext(), SwingConstants.HORIZONTAL),\n                         new TimeMarksPainter(),\n                         SwingConstants.NORTH, AxisComponent.MESH_FOREGROUND);\n        hAxis.setForeground(Color.GRAY);\n\n        // Surviving generations axis\n        XYItem survgenItem = models.generationsItemsModel().getItem(1);\n        XYItemPainter survgenPainter = (XYItemPainter)paintersModel.getPainter(survgenItem);\n        SimpleLongMarksPainter survgenMarksPainter = new SimpleLongMarksPainter();\n        AxisComponent sAxis =\n                new AxisComponent(chart, new DecimalXYItemMarksComputer(\n                         survgenItem, survgenPainter, chart.getChartContext(),\n                         SwingConstants.VERTICAL),\n                         survgenMarksPainter, SwingConstants.WEST,\n                         AxisComponent.MESH_FOREGROUND);\n        sAxis.setForeground(Color.GRAY);\n\n        // Chart panel (chart & axes)\n        JPanel chartPanel = new JPanel(new CrossBorderLayout());\n        chartPanel.setBackground(GraphsUI.CHART_BACKGROUND_COLOR);\n        chartPanel.setBorder(BorderFactory.createMatteBorder(\n                             10, 10, 5, 5, GraphsUI.CHART_BACKGROUND_COLOR));\n        chartPanel.add(chart, new Integer[] { SwingConstants.CENTER });\n        chartPanel.add(hAxis, new Integer[] { SwingConstants.NORTH,\n                                              SwingConstants.NORTH_EAST,\n                                              SwingConstants.NORTH_WEST });\n        chartPanel.add(sAxis, new Integer[] { SwingConstants.WEST,\n                                              SwingConstants.SOUTH_WEST });\n        \n        JScrollBar scroller = new JScrollBar(JScrollBar.HORIZONTAL);\n        chart.attachHorizontalScrollBar(scroller);\n        chartPanel.add(scroller, new Integer[] { SwingConstants.SOUTH });\n\n        // Small panel UI\n        if (smallPanel) {\n            \n        // Big panel UI\n        } else {\n            \n            // Tooltip support\n            ProfilerXYTooltipPainter tooltipPainter = new ProfilerXYTooltipPainter(createTooltipModel());\n            chart.addOverlayComponent(new ProfilerXYTooltipOverlay(chart, tooltipPainter));\n            chart.getSelectionModel().setHoverMode(ChartSelectionModel.HOVER_EACH_NEAREST);\n\n            // Hovering support\n            ProfilerXYSelectionOverlay selectionOverlay = new ProfilerXYSelectionOverlay();\n            chart.addOverlayComponent(selectionOverlay);\n            selectionOverlay.registerChart(chart);\n            chart.getSelectionModel().setMoveMode(ChartSelectionModel.SELECTION_LINE_V);\n\n            // Chart container (chart panel & scrollbar)\n            JPanel chartContainer = new JPanel(new BorderLayout());\n            chartContainer.setBorder(BorderFactory.createEmptyBorder());\n            chartContainer.add(chartPanel, BorderLayout.CENTER);\n            \n            // Side panel\n            JPanel sidePanel = new JPanel(new BorderLayout());\n            sidePanel.setOpaque(false);\n            int h = new JLabel(\"XXX\").getPreferredSize().height; // NOI18N\n            sidePanel.setBorder(BorderFactory.createEmptyBorder(h + 17, 0, 0, 10));\n            InvisibleToolbar toolbar = new InvisibleToolbar(InvisibleToolbar.VERTICAL);\n            toolbar.setOpaque(true);\n            toolbar.setBackground(UIUtils.getProfilerResultsBackground());\n            toolbar.add(chart.toggleViewAction()).setBackground(UIUtils.getProfilerResultsBackground());\n            toolbar.add(chart.zoomInAction()).setBackground(UIUtils.getProfilerResultsBackground());\n            toolbar.add(chart.zoomOutAction()).setBackground(UIUtils.getProfilerResultsBackground());\n            sidePanel.add(toolbar, BorderLayout.CENTER);       \n\n            // Heap Size\n            JLabel heapSizeBig = new JLabel(GraphsUI.SURVGEN_NAME,\n                                            new ColorIcon(GENERATIONS_COLOR, Color.\n                                            BLACK, 18, 9), SwingConstants.LEADING);\n            heapSizeBig.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n\n            // Used heap\n            JLabel usedHeapBig = new JLabel(GraphsUI.GC_INTERVALS_NAME,\n                                            new ColorIcon(GC_INTERVALS_COLOR, Color.\n                                            BLACK, 18, 9), SwingConstants.LEADING);\n            usedHeapBig.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n\n            // Legend container\n            JPanel bigLegendPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 7, 0));\n            bigLegendPanel.setBorder(BorderFactory.createEmptyBorder(4, 0, 8, 30));\n            bigLegendPanel.setOpaque(true);\n            bigLegendPanel.setBackground(UIUtils.getProfilerResultsBackground());\n            bigLegendPanel.add(heapSizeBig);\n            bigLegendPanel.add(usedHeapBig);\n\n            // Master UI\n            setLayout(new BorderLayout());\n            setBackground(UIUtils.getProfilerResultsBackground());\n            JLabel caption = new JLabel(GraphsUI.GC_CAPTION, JLabel.CENTER);\n            caption.setFont(caption.getFont().deriveFont(Font.BOLD));\n            caption.setBorder(BorderFactory.createEmptyBorder(15, 0, 0, 0));\n            caption.setOpaque(true);\n            caption.setBackground(UIUtils.getProfilerResultsBackground());\n            add(caption, BorderLayout.NORTH);\n            add(chartContainer, BorderLayout.CENTER);\n            add(bigLegendPanel, BorderLayout.SOUTH);\n            add(sidePanel, BorderLayout.EAST);\n\n            // Toolbar actions\n            chartActions = new Action[] { chart.zoomInAction(),\n                                          chart.zoomOutAction(),\n                                          chart.toggleViewAction()};\n\n        }\n\n    }\n\n    protected ProfilerXYTooltipModel createTooltipModel() {\n        return new ProfilerXYTooltipModel() {\n\n            public String getTimeValue(long timestamp) {\n                return DATE_FORMATTER.format(new Date(timestamp));\n            }\n\n            public int getRowsCount() {\n                return 1;\n            }\n\n            public String getRowName(int index) {\n                switch (index) {\n                    case 0:\n                        return GraphsUI.SURVGEN_NAME;\n                    case 1:\n                        return GraphsUI.GC_TIME_NAME;\n                    default:\n                        return null;\n                }\n            }\n\n            public Color getRowColor(int index) {\n                switch (index) {\n                    case 0:\n                        return GraphsUI.SURVGEN_PAINTER_LINE_COLOR;\n                    case 1:\n                        return GraphsUI.GC_TIME_PAINTER_LINE_COLOR;\n                    default:\n                        return null;\n                }\n            }\n\n            public String getRowValue(int index, long itemValue) {\n                switch (index) {\n                    case 0:\n                        return INT_FORMATTER.format(itemValue);\n                    case 1:\n                        String val = PERCENT_FORMATTER.format(itemValue / 1000f);\n                        return trimPercents(val);\n                    default:\n                        return null;\n                }\n            }\n\n            public String getRowUnits(int index) {\n                switch (index) {\n                    case 0:\n                        return \"\"; // NOI18N\n                    case 1:\n                        return \"%\"; // NOI18N\n                    default:\n                        return null;\n                }\n            }\n\n            public int getExtraRowsCount() {\n                return getRowsCount();\n            }\n\n            public String getExtraRowName(int index) {\n                return getMaxValueString(getRowName(index));\n            }\n\n            public Color getExtraRowColor(int index) {\n                return getRowColor(index);\n            }\n\n            public String getExtraRowValue(int index) {\n                SynchronousXYItem item = models.generationsItemsModel().getItem(index+1);\n                switch (index) {\n                    case 0:\n                        return INT_FORMATTER.format(item.getMaxYValue());\n                    case 1:\n                        String val = PERCENT_FORMATTER.format(item.getMaxYValue() /\n                                                              1000f);\n                        return trimPercents(val);\n                    default:\n                        return null;\n                }\n            }\n\n            public String getExtraRowUnits(int index) {\n                return getRowUnits(index);\n            }\n\n            private String trimPercents(String percents) {\n                return !percents.endsWith(\"%\") ? percents : // NOI18N\n                        percents.substring(0, percents.length() - 1).trim();\n            }\n\n        };\n    }\n\n    private PaintersModel createGenerationsPaintersModel() {\n        // Surviving generations\n        ProfilerXYItemPainter survgenPainter =\n                ProfilerXYItemPainter.absolutePainter(GraphsUI.SURVGEN_PAINTER_LINE_WIDTH,\n                                                      GENERATIONS_COLOR,\n                                                      null);\n        XYItemPainter sgp = survgenPainter;\n\n        // GC events painter\n        XYItemPainter gep = ProfilerGCXYItemPainter.painter(GC_INTERVALS_COLOR);\n\n        // Model\n        ItemsModel items = models.generationsItemsModel();\n        PaintersModel model = new PaintersModel.Default(\n                                            new ChartItem[] { items.getItem(0),\n                                                              items.getItem(1) },\n                                            new XYItemPainter[] { gep, sgp });\n\n        return model;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/graphs/ThreadsGraphPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.graphs;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.FlowLayout;\nimport java.awt.Font;\nimport java.awt.Insets;\nimport java.util.Date;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemsModel;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.axis.AxisComponent;\nimport org.graalvm.visualvm.lib.charts.axis.SimpleLongMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimeMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimelineMarksComputer;\nimport org.graalvm.visualvm.lib.charts.swing.CrossBorderLayout;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.DecimalXYItemMarksComputer;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.jfluid.results.DataManagerListener;\nimport org.graalvm.visualvm.lib.jfluid.results.monitor.VMTelemetryDataManager;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYChart;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYItemPainter;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYSelectionOverlay;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipModel;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipOverlay;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerXYTooltipPainter;\nimport org.graalvm.visualvm.lib.ui.components.ColorIcon;\nimport org.graalvm.visualvm.lib.ui.monitor.VMTelemetryModels;\nimport org.graalvm.visualvm.lib.ui.swing.InvisibleToolbar;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ThreadsGraphPanel extends GraphPanel {\n    \n    private final Color THREADS_COLOR = ColorFactory.getPredefinedColor(0);\n    private final Color CLASSES_COLOR = ColorFactory.getPredefinedColor(1);\n\n    private ProfilerXYChart chart;\n    private Action[] chartActions;\n\n    private final VMTelemetryModels models;\n    private final DataManagerListener listener;\n\n    private final boolean smallPanel;\n\n\n    // --- Constructors --------------------------------------------------------\n\n    public static ThreadsGraphPanel createBigPanel(VMTelemetryModels models) {\n        return new ThreadsGraphPanel(models, false, null);\n    }\n\n    public static ThreadsGraphPanel createSmallPanel(VMTelemetryModels models,\n                                             Action chartAction) {\n        return new ThreadsGraphPanel(models, true, chartAction);\n    }\n\n    private ThreadsGraphPanel(VMTelemetryModels models,\n                             boolean smallPanel, Action chartAction) {\n\n        // Save models and panel type\n        this.models = models;\n        this.smallPanel = smallPanel;\n\n        // Create UI\n        initComponents(chartAction);\n\n        // Register listener\n        listener = new DataManagerListener() {\n            public void dataChanged() { updateData(); }\n            public void dataReset() { resetData(); }\n        };\n        models.getDataManager().addDataListener(listener);\n\n        // Initialize chart & legend\n        resetData();\n    }\n\n\n    // --- GraphPanel implementation -------------------------------------------\n\n    public Action[] getActions() {\n        return chartActions;\n    }\n    \n    public void cleanup() {\n        models.getDataManager().removeDataListener(listener);\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void updateData() {\n        if (smallPanel) {\n            if (chart.fitsWidth()) {\n                VMTelemetryDataManager manager = models.getDataManager();\n                long[] timestamps = manager.timeStamps;\n                if (timestamps[manager.getItemCount() - 1] - timestamps[0] >=\n                    SMALL_CHART_FIT_TO_WINDOW_PERIOD)\n                        chart.setFitsWidth(false);\n            }\n        } else {\n        }\n    }\n\n    private void resetData() {\n        if (smallPanel) {\n            chart.setScale(INITIAL_CHART_SCALEX, 1);\n            chart.setOffset(0, 0);\n            chart.setFitsWidth(true);\n        } else {\n            chart.setScale(INITIAL_CHART_SCALEX, 1);\n            chart.setOffset(0, 0);\n            chart.setFitsWidth(false);\n        }\n        chart.setInitialDataBounds(new LongRect(System.currentTimeMillis(), 0,\n                                       2500, GraphsUI.THREADS_INITIAL_VALUE));\n    }\n\n\n    private void initComponents(final Action chartAction) {\n        // Painters model\n        PaintersModel paintersModel = createThreadsPaintersModel();\n\n        // Chart\n        chart = createChart(models.threadsItemsModel(),\n                            paintersModel, smallPanel);\n        chart.setBackground(GraphsUI.CHART_BACKGROUND_COLOR);\n        chart.setViewInsets(new Insets(10, 0, 0, 0));\n\n        // Horizontal axis\n        AxisComponent hAxis =\n                new AxisComponent(chart, new TimelineMarksComputer(\n                         models.threadsItemsModel().getTimeline(),\n                         chart.getChartContext(), SwingConstants.HORIZONTAL),\n                         new TimeMarksPainter(),\n                         SwingConstants.NORTH, AxisComponent.MESH_FOREGROUND);\n        hAxis.setForeground(Color.GRAY);\n\n        // Threads axis\n        XYItem threadsItem = models.threadsItemsModel().getItem(0);\n        XYItemPainter threadsPainter = (XYItemPainter)paintersModel.getPainter(threadsItem);\n        SimpleLongMarksPainter threadsMarksPainter = new SimpleLongMarksPainter();\n        threadsMarksPainter.setForeground(THREADS_COLOR);\n        AxisComponent tAxis =\n                new AxisComponent(chart, new DecimalXYItemMarksComputer(\n                         threadsItem, threadsPainter, chart.getChartContext(),\n                         SwingConstants.VERTICAL),\n                         threadsMarksPainter, SwingConstants.WEST,\n                         AxisComponent.MESH_FOREGROUND);\n        tAxis.setForeground(Color.GRAY);\n\n        // Loaded classes axis\n        XYItem classesItem = models.threadsItemsModel().getItem(1);\n        XYItemPainter classesPainter = (XYItemPainter)paintersModel.getPainter(classesItem);\n        SimpleLongMarksPainter classesMarksPainter = new SimpleLongMarksPainter();\n        classesMarksPainter.setForeground(CLASSES_COLOR);\n        AxisComponent cAxis =\n                new AxisComponent(chart, new DecimalXYItemMarksComputer(\n                         classesItem, classesPainter, chart.getChartContext(),\n                         SwingConstants.VERTICAL),\n                         classesMarksPainter, SwingConstants.EAST,\n                         AxisComponent.NO_MESH);\n        cAxis.setForeground(Color.GRAY);\n\n        // Chart panel (chart & axes)\n        JPanel chartPanel = new JPanel(new CrossBorderLayout());\n        chartPanel.setBackground(GraphsUI.CHART_BACKGROUND_COLOR);\n        chartPanel.setBorder(BorderFactory.createMatteBorder(\n                             10, 10, 5, 5, GraphsUI.CHART_BACKGROUND_COLOR));\n        chartPanel.add(chart, new Integer[] { SwingConstants.CENTER });\n        chartPanel.add(hAxis, new Integer[] { SwingConstants.NORTH,\n                                              SwingConstants.NORTH_EAST,\n                                              SwingConstants.NORTH_WEST });\n        chartPanel.add(tAxis, new Integer[] { SwingConstants.WEST,\n                                              SwingConstants.SOUTH_WEST });\n        chartPanel.add(cAxis, new Integer[] { SwingConstants.EAST,\n                                              SwingConstants.SOUTH_EAST });\n        \n        JScrollBar scroller = new JScrollBar(JScrollBar.HORIZONTAL);\n        chart.attachHorizontalScrollBar(scroller);\n        chartPanel.add(scroller, new Integer[] { SwingConstants.SOUTH });\n\n        // Small panel UI\n        if (smallPanel) {\n\n        // Big panel UI\n        } else {\n            \n            // Tooltip support\n            ProfilerXYTooltipPainter tooltipPainter = new ProfilerXYTooltipPainter(createTooltipModel());\n            chart.addOverlayComponent(new ProfilerXYTooltipOverlay(chart, tooltipPainter));\n            chart.getSelectionModel().setHoverMode(ChartSelectionModel.HOVER_EACH_NEAREST);\n\n            // Hovering support\n            ProfilerXYSelectionOverlay selectionOverlay = new ProfilerXYSelectionOverlay();\n            chart.addOverlayComponent(selectionOverlay);\n            selectionOverlay.registerChart(chart);\n            chart.getSelectionModel().setMoveMode(ChartSelectionModel.SELECTION_LINE_V);\n\n            // Chart container (chart panel & scrollbar)\n            JPanel chartContainer = new JPanel(new BorderLayout());\n            chartContainer.setBorder(BorderFactory.createEmptyBorder());\n            chartContainer.add(chartPanel, BorderLayout.CENTER);\n            \n            // Side panel\n            JPanel sidePanel = new JPanel(new BorderLayout());\n            sidePanel.setOpaque(false);\n            int h = new JLabel(\"XXX\").getPreferredSize().height; // NOI18N\n            sidePanel.setBorder(BorderFactory.createEmptyBorder(h + 17, 0, 0, 10));\n            InvisibleToolbar toolbar = new InvisibleToolbar(InvisibleToolbar.VERTICAL);\n            toolbar.setOpaque(true);\n            toolbar.setBackground(UIUtils.getProfilerResultsBackground());\n            toolbar.add(chart.toggleViewAction()).setBackground(UIUtils.getProfilerResultsBackground());\n            toolbar.add(chart.zoomInAction()).setBackground(UIUtils.getProfilerResultsBackground());\n            toolbar.add(chart.zoomOutAction()).setBackground(UIUtils.getProfilerResultsBackground());\n            sidePanel.add(toolbar, BorderLayout.CENTER);      \n\n            // Heap Size\n            JLabel heapSizeBig = new JLabel(GraphsUI.THREADS_NAME,\n                                            new ColorIcon(THREADS_COLOR, Color.\n                                            BLACK, 18, 9), SwingConstants.LEADING);\n            heapSizeBig.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n\n            // Used heap\n            JLabel usedHeapBig = new JLabel(GraphsUI.LOADED_CLASSES_NAME,\n                                            new ColorIcon(CLASSES_COLOR, Color.\n                                            BLACK, 18, 9), SwingConstants.LEADING);\n            usedHeapBig.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n\n            // Legend container\n            JPanel bigLegendPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 7, 0));\n            bigLegendPanel.setBorder(BorderFactory.createEmptyBorder(4, 0, 8, 30));\n            bigLegendPanel.setOpaque(true);\n            bigLegendPanel.setBackground(UIUtils.getProfilerResultsBackground());\n            bigLegendPanel.add(heapSizeBig);\n            bigLegendPanel.add(usedHeapBig);\n\n            // Master UI\n            setLayout(new BorderLayout());\n            setBackground(UIUtils.getProfilerResultsBackground());\n            JLabel caption = new JLabel(GraphsUI.THREADS_CLASSES_CAPTION, JLabel.CENTER);\n            caption.setFont(caption.getFont().deriveFont(Font.BOLD));\n            caption.setBorder(BorderFactory.createEmptyBorder(15, 0, 0, 0));\n            caption.setOpaque(true);\n            caption.setBackground(UIUtils.getProfilerResultsBackground());\n            add(caption, BorderLayout.NORTH);\n            add(chartContainer, BorderLayout.CENTER);\n            add(bigLegendPanel, BorderLayout.SOUTH);\n            add(sidePanel, BorderLayout.EAST);\n\n\n            // Toolbar actions\n            chartActions = new Action[] { chart.zoomInAction(),\n                                          chart.zoomOutAction(),\n                                          chart.toggleViewAction()};\n\n        }\n\n    }\n\n    protected ProfilerXYTooltipModel createTooltipModel() {\n        return new ProfilerXYTooltipModel() {\n\n            public String getTimeValue(long timestamp) {\n                return DATE_FORMATTER.format(new Date(timestamp));\n            }\n\n            public int getRowsCount() {\n                return 2;\n            }\n\n            public String getRowName(int index) {\n                switch (index) {\n                    case 0:\n                        return GraphsUI.THREADS_NAME;\n                    case 1:\n                        return GraphsUI.LOADED_CLASSES_NAME;\n                    default:\n                        return null;\n                }\n            }\n\n            public Color getRowColor(int index) {\n                switch (index) {\n                    case 0:\n                        return GraphsUI.THREADS_PAINTER_LINE_COLOR;\n                    case 1:\n                        return GraphsUI.LOADED_CLASSES_PAINTER_LINE_COLOR;\n                    default:\n                        return null;\n                }\n            }\n\n            public String getRowValue(int index, long itemValue) {\n                return INT_FORMATTER.format(itemValue);\n            }\n\n            public String getRowUnits(int index) {\n                return \"\"; // NOI18N\n            }\n\n            public int getExtraRowsCount() {\n                return getRowsCount();\n            }\n\n            public String getExtraRowName(int index) {\n                return getMaxValueString(getRowName(index));\n            }\n\n            public Color getExtraRowColor(int index) {\n                return getRowColor(index);\n            }\n\n            public String getExtraRowValue(int index) {\n                SynchronousXYItem item = models.threadsItemsModel().getItem(index);\n                return INT_FORMATTER.format(item.getMaxYValue());\n            }\n\n            public String getExtraRowUnits(int index) {\n                return getRowUnits(index);\n            }\n\n        };\n    }\n\n    private PaintersModel createThreadsPaintersModel() {\n        // Threads\n        ProfilerXYItemPainter threadsPainter =\n                ProfilerXYItemPainter.absolutePainter(GraphsUI.THREADS_PAINTER_LINE_WIDTH,\n                                                      THREADS_COLOR,\n                                                      null);\n        XYItemPainter thp = threadsPainter;\n\n        // Loaded classes\n        ProfilerXYItemPainter loadedClassesPainter =\n                ProfilerXYItemPainter.relativePainter(GraphsUI.LOADED_CLASSES_PAINTER_LINE_WIDTH,\n                                                      CLASSES_COLOR,\n                                                      null,\n                                                      10);\n        XYItemPainter lcp = loadedClassesPainter;\n\n        // Model\n        ItemsModel items = models.threadsItemsModel();\n        PaintersModel model = new PaintersModel.Default(\n                                            new ChartItem[] { items.getItem(0),\n                                                              items.getItem(1) },\n                                            new XYItemPainter[] { thp, lcp });\n\n        return model;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/graphs/XYBackground.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.graphs;\n\nimport java.awt.Color;\nimport java.awt.GradientPaint;\nimport java.awt.Graphics2D;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartDecorator;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass XYBackground implements ChartDecorator {\n\n    private static final Color GRADIENT_TOP = !UIUtils.isDarkResultsBackground() ?\n                               new Color(240, 240, 240) : new Color(60, 60, 60);\n    private static final Color GRADIENT_BOTTOM = !UIUtils.isDarkResultsBackground() ?\n                               new Color(250, 250, 250) : new Color(75, 75, 75);\n\n    public void paint(Graphics2D g, Rectangle dirtyArea, ChartContext context) {\n        if (Utils.forceSpeed()) g.setPaint(GRADIENT_BOTTOM);\n        else g.setPaint(new GradientPaint(\n                        new Point(0, Utils.checkedInt(context.getViewportOffsetY())),\n                        GRADIENT_TOP,\n                        new Point(0, context.getViewportHeight()),\n                        GRADIENT_BOTTOM));\n        g.fill(dirtyArea);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/jdbc/Bundle.properties",
    "content": "# Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nJDBCView_ColumnName=SQL Query\nJDBCView_TimeColumnName=Total Time\nJDBCView_InvocationsColumnName=Invocations\nJDBCView_ColumnCommands=Command Type\nJDBCView_ColumnTables=Tables\nJDBCView_ColumnStatements=Statement Type\nJDBCView_ColumnAverage=Average Time\nJDBCView_ColumnToolTip=SQL query and calling methods\nJDBCView_TimeColumnToolTip=Time spent in all invocations of the SQL query\nJDBCView_InvocationsColumnToolTip=Number of times the SQL query was invoked\nJDBCView_ColumnCommandsToolTip=SQL Command Type\nJDBCView_ColumnTablesToolTip=Database Tables\nJDBCView_ColumnStatementsToolTip=SQL Statement Type\nJDBCView_ColumnAverageToolTip=Average time per invocation\nJDBCView_OtherCommand=other command\nJDBCView_RegularStatement=regular\nJDBCView_PreparedStatement=prepared\nJDBCView_CallableStatement=callable\nJDBCView_ActionViewSqlQuery=View SQL Query\nJDBCView_ExportTooltip=Export data to file or image\nJDBCView_ExportLbl=Export {0}\nJDBCView_ExportQueries=SQL Queries\nJDBCView_ActionGoToSource=Go to Source\nJDBCView_ActionProfileMethod=Profile Method\nJDBCView_ActionProfileClass=Profile Class\nJDBCView_SearchQueriesScope=Search SQL Queries\nJDBCView_SearchCallersScope=Search Invoking Methods\nJDBCView_SearchScopeTooltip=Search scope\nJDBCView_ExpandMenu=Expand / Collapse\nJDBCView_ExpandPlainItem=Expand Plain Path\nJDBCView_ExpandTopmostItem=Expand Topmost Path\nJDBCView_CollapseChildrenItem=Collapse Children\nJDBCView_CollapseAllItem=Collapse All\n\nSQLFilterPanel_QueriesCaption=Queries:\nSQLFilterPanel_FilterButton=Filter\nSQLFilterPanel_CommandsDropdown=Commands\nSQLFilterPanel_CommandsNotAvailable=No commands available\nSQLFilterPanel_TablesDropdown=Tables\nSQLFilterPanel_TablesNotAvailable=No tables available\nSQLFilterPanel_StatementsDropdown=Statements\nSQLFilterPanel_StatementRegular=Regular\nSQLFilterPanel_StatementPrepared=Prepared\nSQLFilterPanel_StatementCallable=Callable\nSQLFilterPanel_FilterTooltip=Filter SQL queries by substring ({0})\nSQLFilterPanel_CommandsTooltip=Filter SQL queries by used commands\nSQLFilterPanel_TablesTooltip=Filter SQL queries by referenced tables\nSQLFilterPanel_StatementsTooltip=Filter SQL queries by statement types\n\nSQLFormatter_DatabasePing=Database ping\n\nSnapshotJDBCView_CompareSnapshots=Compare with another snapshot...\nSnapshotJDBCView_ResetCompareSnapshots=Reset snapshots comparison\n\nTablesSelector_SelectTables=Select tables:\nTablesSelector_FilterTables=Filter tables\nTablesSelector_ColumnSelected=Selected\nTablesSelector_ColumnTable=Table\nTablesSelector_ColumnSelectedToolTip=Selected for displaying\nTablesSelector_ColumnTableToolTip=Table name\nTablesSelector_ActSelectAll=Select All\nTablesSelector_ActUnselectAll=Unselect All\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/jdbc/JDBCJavaNameRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.jdbc;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.UIManager;\nimport javax.swing.table.DefaultTableCellRenderer;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JDBCJavaNameRenderer extends JavaNameRenderer {\n\n    private static final Icon SQL_ICON = Icons.getIcon(ProfilerIcons.SQL_QUERY);\n    private static final Icon SQL_ICON_DISABLED = UIManager.getLookAndFeel().getDisabledIcon(null, SQL_ICON);\n    private static final Icon LEAF_ICON = Icons.getIcon(ProfilerIcons.NODE_LEAF);\n    private static final Icon LEAF_ICON_DISABLED = UIManager.getLookAndFeel().getDisabledIcon(null, LEAF_ICON);\n\n    private final Icon icon;\n    private final Icon iconDisabled;\n\n    private String currentValue;\n    private JLabel currentSQLRenderer;\n\n    JDBCJavaNameRenderer() {\n        this(ProfilerIcons.NODE_REVERSE);\n    }\n\n    JDBCJavaNameRenderer(String iconKey) {\n        this.icon = Icons.getIcon(iconKey);\n        this.iconDisabled = UIManager.getLookAndFeel().getDisabledIcon(null, icon);\n    }\n\n    public void setValue(Object value, int row) {\n        if (value instanceof PresoObjAllocCCTNode) {\n            PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)value;\n\n            boolean filtered = node.isFiltered();\n            currentValue = node.getNodeName();\n\n            if (JDBCTreeTableView.isSQL(node)) {\n                JDBCTreeTableView.SQLQueryNode sqlNode = (JDBCTreeTableView.SQLQueryNode)node;\n                String htmlName = sqlNode.htmlName;\n                if (htmlName == null) {\n                    htmlName = SQLFormatter.format(currentValue);\n                    sqlNode.htmlName = htmlName;\n                }\n                currentSQLRenderer = sqlRenderer(htmlName, filtered ? SQL_ICON_DISABLED : SQL_ICON);\n            } else {\n                if (filtered) {\n                    setNormalValue(\"\"); // NOI18N\n                    setBoldValue(\"\"); // NOI18N\n                    setGrayValue(currentValue);\n                } else {\n                    super.setValue(currentValue, row);\n                }\n\n                if (node.isLeaf()) {\n                    setIcon(filtered ? LEAF_ICON_DISABLED : LEAF_ICON);\n                } else {\n                    setIcon(filtered ? iconDisabled : icon);\n                }\n                currentSQLRenderer = null;\n            }\n        } else {\n            super.setValue(value, row);\n        }\n    }\n    \n    public JComponent getComponent() {\n        return currentSQLRenderer != null ? currentSQLRenderer : super.getComponent();\n    }\n    \n    public String toString() {\n        return currentValue;\n    }\n    \n    \n    private static int CACHE_SIZE = 100;\n    private List<String> sqlRenderersKeys;\n    private Map<String, JLabel> sqlRenderersCache;\n    \n    private JLabel sqlRenderer(String text, Icon icon) {\n        if (sqlRenderersCache == null) {\n            sqlRenderersKeys = new ArrayList<>(CACHE_SIZE);\n            sqlRenderersCache = new HashMap<>(CACHE_SIZE);\n        }\n        \n        JLabel sqlRenderer = sqlRenderersCache.get(text);\n        \n        if (sqlRenderer == null) {\n            if (sqlRenderersKeys.size() < CACHE_SIZE) {\n                sqlRenderer = new DefaultTableCellRenderer();\n            } else {\n                String key = sqlRenderersKeys.remove(0);\n                sqlRenderer = sqlRenderersCache.remove(key);\n            }\n            \n            sqlRenderersKeys.add(text);\n            sqlRenderersCache.put(text, sqlRenderer);\n            \n            sqlRenderer.setText(text);\n        }\n        \n        sqlRenderer.setIcon(icon);\n        \n        return sqlRenderer;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/jdbc/JDBCTreeTableView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.jdbc;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.swing.Box;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JTree;\nimport javax.swing.RowFilter;\nimport javax.swing.SortOrder;\nimport javax.swing.tree.TreeNode;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.McsTimeRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class JDBCTreeTableView extends JDBCView {\n    \n    private Set<String> commands;\n    private Set<String> tables;\n    \n    private JDBCTreeTableModel treeTableModel;\n    private ProfilerTreeTable treeTable;\n    \n    private JPanel bottomPanel;\n    private SQLFilterPanel sqlFilter;\n    \n    private JdbcResultsSnapshot currentData;\n    \n    private boolean searchQueries = true;\n    private boolean searchCallerMethods = false;\n    \n    \n    JDBCTreeTableView(Set<ClientUtils.SourceCodeSelection> selection, boolean reverse) {\n        initUI();\n    }\n    \n    \n    void setData(final JdbcResultsSnapshot newData, final Map<Integer, ClientUtils.SourceCodeSelection> newIdMap, final int aggregation, final Collection<Integer> selectedThreads, final boolean mergeThreads, final boolean _sampled, final boolean diff) {\n        \n        String[] _names = newData.getSelectNames();\n        long[] _nTotalAllocObjects = newData.getInvocationsPerSelectId();\n        long[] _totalAllocObjectsSize = newData.getTimePerSelectId();\n        \n        List<PresoObjAllocCCTNode> nodes = new ArrayList<>();\n        \n        long totalObjects = 0;\n        long _totalObjects = 0;\n        long totalBytes = 0;\n        long _totalBytes = 0;\n        \n        if (commands == null) commands = new HashSet<>();\n        commands.clear();\n        if (tables == null) tables = new HashSet<>();\n        tables.clear();\n        \n        for (int i = 1; i < _names.length; i++) {\n            if (diff) {\n                totalObjects = Math.max(totalObjects, _nTotalAllocObjects[i]);\n                _totalObjects = Math.min(_totalObjects, _nTotalAllocObjects[i]);\n                totalBytes = Math.max(totalBytes, _totalAllocObjectsSize[i]);\n                _totalBytes = Math.min(_totalBytes, _totalAllocObjectsSize[i]);\n            } else {\n                totalObjects += _nTotalAllocObjects[i];\n                totalBytes += _totalAllocObjectsSize[i];\n            }\n            \n            int statementType = newData.getTypeForSelectId()[i];\n            int commandType = newData.getCommandTypeForSelectId()[i];\n            String commandString = commandString(commandType);\n            String[] sqlTables = newData.getTablesForSelectId()[i];\n            \n            commands.add(commandString.toUpperCase(Locale.ENGLISH));\n            tables.addAll(Arrays.asList(sqlTables));\n            \n            if (sqlFilter.passes(_names[i], commandString, sqlTables, statementType)) {\n                final int _i = i;\n                nodes.add(new SQLQueryNode(_names[i], _nTotalAllocObjects[i], _totalAllocObjectsSize[i], statementType, commandType, sqlTables) {\n                    PresoObjAllocCCTNode computeChildren() { return newData.createPresentationCCT(_i, false); }\n                });\n            }\n        }\n        \n        long __totalBytes = !diff ? totalBytes : Math.max(Math.abs(totalBytes), Math.abs(_totalBytes));\n        long __totalObjects = !diff ? totalObjects : Math.max(Math.abs(totalObjects), Math.abs(_totalObjects));\n        \n        renderers[0].setMaxValue(__totalBytes);\n        renderers[1].setMaxValue(__totalObjects);\n        renderers[0].setDiffMode(diff);\n        renderers[1].setDiffMode(diff);\n        timeRenderer.setDiffMode(diff);\n        treeTableModel.setRoot(PresoObjAllocCCTNode.rootNode(nodes.toArray(new PresoObjAllocCCTNode[0])));\n\n        currentData = newData;\n    }\n    \n    public void resetData() {\n        renderers[0].setMaxValue(0);\n        renderers[1].setMaxValue(0);\n        renderers[0].setDiffMode(false);\n        renderers[1].setDiffMode(false);\n        timeRenderer.setDiffMode(false);\n\n        treeTableModel.setRoot(PresoObjAllocCCTNode.rootNode(new PresoObjAllocCCTNode[0]));\n\n        if (commands != null) commands.clear();\n        if (tables != null) tables.clear();\n\n        currentData = null;\n    }\n    \n    \n    public void showSelectionColumn() {\n        treeTable.setColumnVisibility(0, true);\n    }\n    \n    public void refreshSelection() {\n        treeTableModel.dataChanged();\n    }\n    \n    \n    ExportUtils.ExportProvider[] getExportProviders() {\n        final String name = EXPORT_QUERIES;\n        return treeTable.getRowCount() == 0 ? null : new ExportUtils.ExportProvider[] {\n            new ExportUtils.CSVExportProvider(treeTable),\n            new ExportUtils.HTMLExportProvider(treeTable, name),\n            new ExportUtils.XMLExportProvider(treeTable, name),\n            new ExportUtils.PNGExportProvider(treeTable)\n        };\n    }\n    \n    \n    protected abstract void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue);\n    \n    protected void popupShowing() {}\n    \n    protected void popupHidden()  {}\n    \n    \n    private HideableBarRenderer[] renderers;\n    private McsTimeRenderer timeRenderer;\n    \n    HideableBarRenderer.BarDiffMode barDiffMode() {\n        return HideableBarRenderer.BarDiffMode.MODE_BAR_DIFF;\n    }\n    \n    private void initUI() {\n        treeTableModel = new JDBCTreeTableModel(PrestimeCPUCCTNode.EMPTY);\n        \n        treeTable = new ProfilerTreeTable(treeTableModel, true, true, new int[] { 0 }) {\n            public ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n                return JDBCTreeTableView.this.getUserValueForRow(row);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                JDBCTreeTableView.this.populatePopup(popup, value, (ClientUtils.SourceCodeSelection)userValue);\n            }\n            protected void popupShowing() {\n                JDBCTreeTableView.this.popupShowing();\n            }\n            protected void popupHidden() {\n                JDBCTreeTableView.this.popupHidden();\n            }\n        };\n        \n        setToolTips();\n        \n        treeTable.providePopupMenu(true);\n        installDefaultAction();\n        \n        treeTable.setRootVisible(false);\n        treeTable.setShowsRootHandles(true);\n        treeTable.makeTreeAutoExpandable(2);\n        \n        treeTable.setMainColumn(0);\n        treeTable.setFitWidthColumn(0);\n        \n        treeTable.setSortColumn(1);\n        treeTable.setDefaultSortOrder(1, SortOrder.DESCENDING);\n        \n        renderers = new HideableBarRenderer[2];\n        \n        HideableBarRenderer.BarDiffMode barDiffMode = barDiffMode();\n        renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(new McsTimeRenderer()));\n        renderers[0].setBarDiffMode(barDiffMode);\n        renderers[1] = new HideableBarRenderer(new NumberRenderer());\n        renderers[1].setBarDiffMode(barDiffMode);\n        timeRenderer = new McsTimeRenderer();\n        \n        long refTime = 123456;\n        renderers[0].setMaxValue(refTime);\n        renderers[1].setMaxValue(refTime);\n        \n        treeTable.setTreeCellRenderer(new JDBCJavaNameRenderer());\n        treeTable.setColumnRenderer(1, renderers[0]);\n        treeTable.setColumnRenderer(2, renderers[1]);\n        \n        treeTable.setDefaultColumnWidth(1, renderers[0].getOptimalWidth());\n        treeTable.setDefaultColumnWidth(2, renderers[1].getMaxNoBarWidth());\n        \n        LabelRenderer tr = new LabelRenderer();\n        tr.setHorizontalAlignment(LabelRenderer.TRAILING);\n        tr.setValue(\"X\"+treeTableModel.getColumnName(3)+\"X\", -1);       // NOI18N\n        treeTable.setColumnRenderer(3, timeRenderer);\n        treeTable.setDefaultColumnWidth(3, tr.getPreferredSize().width);\n        treeTable.setColumnVisibility(3, false);\n\n        // Debug columns\n        LabelRenderer lr = new LabelRenderer();\n        lr.setHorizontalAlignment(LabelRenderer.TRAILING);\n        lr.setValue(\"XStatement TypeX\", -1);\n        \n        treeTable.setColumnRenderer(4, lr);\n        treeTable.setDefaultSortOrder(4, SortOrder.ASCENDING);\n        treeTable.setDefaultColumnWidth(4, lr.getPreferredSize().width);\n        treeTable.setColumnVisibility(4, false);\n        \n        treeTable.setColumnRenderer(5, lr);\n        treeTable.setDefaultSortOrder(5, SortOrder.ASCENDING);\n        treeTable.setDefaultColumnWidth(5, lr.getPreferredSize().width);\n        treeTable.setColumnVisibility(5, false);\n        \n        treeTable.setColumnRenderer(6, lr);\n        treeTable.setDefaultSortOrder(6, SortOrder.ASCENDING);\n        treeTable.setDefaultColumnWidth(6, lr.getPreferredSize().width);\n        treeTable.setColumnVisibility(6, false);\n\n        ProfilerTableContainer tableContainer = new ProfilerTableContainer(treeTable, false, null);\n        \n        setLayout(new BorderLayout());\n        add(tableContainer, BorderLayout.CENTER);\n        \n        sqlFilter = new SQLFilterPanel() {\n            Set<String> getCommands() {\n                if (commands == null) commands = new HashSet<>();\n                return commands;\n            }\n            \n            Set<String> getTables() {\n                if (tables == null) tables = new HashSet<>();\n                return tables;\n            }\n            \n            void applyFilter() {\n                if (currentData != null) setData(currentData, null, -1, null, false, false, false);\n            }\n        };\n        \n        bottomPanel = new JPanel(new BorderLayout());\n        bottomPanel.setOpaque(false);\n        bottomPanel.add(sqlFilter, BorderLayout.NORTH);\n        add(bottomPanel, BorderLayout.SOUTH);\n    }\n    \n    protected void addFilterFindPanel(JComponent comp) {\n        bottomPanel.add(comp, BorderLayout.SOUTH);\n    }\n    \n    private void setToolTips() {\n        treeTable.setColumnToolTips(new String[] {\n                                        NAME_COLUMN_TOOLTIP,\n                                        TOTAL_TIME_COLUMN_TOOLTIP,\n                                        INVOCATIONS_COLUMN_TOOLTIP,\n                                        COMMANDS_COLUMN_TOOLTIP,\n                                        TABLES_COLUMN_TOOLTIP,\n                                        STATEMENTS_COLUMN_TOOLTIP,\n                                        AVERAGE_COLUMN_TOOLTIP\n                                    });\n    }\n    \n    \n    protected RowFilter getExcludesFilter() {\n        return new RowFilter() { // Do not filter SQL commands\n            public boolean include(RowFilter.Entry entry) {\n                PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)entry.getIdentifier();\n                return isSQL(node);\n            }\n        };\n    }\n    \n    protected SearchUtils.TreeHelper getSearchHelper() {\n        return new SearchUtils.TreeHelper() {\n            public int getNodeType(TreeNode tnode) {\n                PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)tnode;\n                CCTNode parent = node.getParent();\n                if (parent == null) return SearchUtils.TreeHelper.NODE_SKIP_DOWN; // invisible root\n                \n                if (isSQL(node)) {\n                    if (searchQueries) {\n                        return searchCallerMethods ? SearchUtils.TreeHelper.NODE_SEARCH_DOWN :\n                                                     SearchUtils.TreeHelper.NODE_SEARCH_NEXT;\n                    } else {\n                        return searchCallerMethods ? SearchUtils.TreeHelper.NODE_SKIP_DOWN :\n                                                     SearchUtils.TreeHelper.NODE_SKIP_NEXT;\n                    }\n                }\n                \n                return searchCallerMethods ?\n                       SearchUtils.TreeHelper.NODE_SEARCH_DOWN :\n                       SearchUtils.TreeHelper.NODE_SKIP_NEXT;\n            }\n        };\n    }\n    \n    protected Component[] getSearchOptions() {\n        PopupButton pb = new PopupButton (Icons.getIcon(ProfilerIcons.TAB_CALL_TREE)) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new JCheckBoxMenuItem(SEARCH_QUERIES_SCOPE, searchQueries) {\n                    {\n                        if (!searchCallerMethods) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        searchQueries = !searchQueries;\n                    }\n                });\n                popup.add(new JCheckBoxMenuItem(SEARCH_CALLERS_SCOPE, searchCallerMethods) {\n                    {\n                        if (!searchQueries) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        searchCallerMethods = !searchCallerMethods;\n                    }\n                });\n            }\n        };\n        pb.setToolTipText(SEARCH_SCOPE_TOOLTIP);\n        return new Component[] { Box.createHorizontalStrut(5), pb };\n    }\n    \n    protected ProfilerTable getResultsComponent() {\n        return treeTable;\n    }\n    \n    \n    protected ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n        PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)treeTable.getValueForRow(row);\n        if (node == null || isSQL(node) || node.isFiltered()) return null;\n        String[] name = node.getMethodClassNameAndSig();\n        return new ClientUtils.SourceCodeSelection(name[0], name[1], name[2]);\n    }\n    \n    static boolean isSQL(PresoObjAllocCCTNode node) {\n        return node instanceof SQLQueryNode;\n    }\n    \n    static boolean isSelectable(PresoObjAllocCCTNode node) {\n        if (isSQL(node)) return false;\n        String methodName = node.getMethodClassNameAndSig()[1];\n        if (methodName == null || methodName.endsWith(\"[native]\")) return false; // NOI18N\n        return true;\n    }\n    \n    \n    private static class JDBCTreeTableModel extends ProfilerTreeTableModel.Abstract {\n        \n        JDBCTreeTableModel(TreeNode root) {\n            super(root);\n        }\n        \n        public String getColumnName(int columnIndex) {\n            if (columnIndex == 0) {\n                return COLUMN_NAME;\n            } else if (columnIndex == 1) {\n                return COLUMN_TOTALTIME;\n            } else if (columnIndex == 2) {\n                return COLUMN_INVOCATIONS;\n            } else if (columnIndex == 3) {\n                return COLUMN_AVEGARE;\n            } else if (columnIndex == 4) {\n                return COLUMN_COMMANDS;\n            } else if (columnIndex == 5) {\n                return COLUMN_TABLES;\n            } else if (columnIndex == 6) {\n                return COLUMN_STATEMENTS;\n            }\n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (columnIndex == 0) {\n                return JTree.class;\n            } else if (columnIndex == 1) {\n                return Long.class;\n            } else if (columnIndex == 2) {\n                return Integer.class;\n            } else if (columnIndex == 3) {\n                return Long.class;\n            } else if (columnIndex == 4) {\n                return String.class;\n            } else if (columnIndex == 5) {\n                return String.class;\n            } else if (columnIndex == 6) {\n                return String.class;\n            }\n            return Long.class;\n        }\n\n        public int getColumnCount() {\n            return 7;\n        }\n\n        public Object getValueAt(TreeNode node, int columnIndex) {\n            PresoObjAllocCCTNode jdbcNode = (PresoObjAllocCCTNode)node;\n            if (columnIndex == 0) {\n                return jdbcNode;\n            } else if (columnIndex == 1) {\n                return jdbcNode.totalObjSize;\n            } else if (columnIndex == 2) {\n                return jdbcNode.nCalls;\n            } else if (columnIndex == 3) {\n                return jdbcNode.totalObjSize/jdbcNode.nCalls;\n            } else if (columnIndex == 4) {\n                if (jdbcNode instanceof SQLQueryNode) {\n                    return commandString(((SQLQueryNode)jdbcNode).getCommandType());\n                } else {\n                    return \"-\"; // NOI18N\n                }\n                \n            } else if (columnIndex == 5) {\n                if (jdbcNode instanceof SQLQueryNode) {\n                    return formatTables(((SQLQueryNode)jdbcNode).getTables());\n                } else {\n                    return \"-\"; // NOI18N\n                }\n            } else if (columnIndex == 6) {\n                if (jdbcNode instanceof SQLQueryNode) {\n                    switch (((SQLQueryNode)jdbcNode).getStatementType()) {\n                        case JdbcCCTProvider.SQL_PREPARED_STATEMENT: return STATEMENT_PREPARED;\n                        case JdbcCCTProvider.SQL_CALLABLE_STATEMENT: return STATEMENT_CALLABLE;\n                        default: return STATEMENT_REGULAR;\n                    }\n                } else {\n                    return \"-\";\n                }\n            }\n            return null;\n        }\n        \n        public void setValueAt(Object aValue, TreeNode node, int columnIndex) {}\n\n        public boolean isCellEditable(TreeNode node, int columnIndex) {\n            return false;\n        }\n        \n        private String formatTables(String[] tables) {\n            int count = tables.length - 1;\n            if (count == -1) return \"-\"; // NOI18N\n            \n            StringBuilder b = new StringBuilder();\n            for (int i = 0; ; i++) {\n                b.append(tables[i]);\n                if (i == count) return b.toString();\n                b.append(\", \"); // NOI18N\n            }\n        }\n        \n    }\n    \n    abstract static class SQLQueryNode extends PresoObjAllocCCTNode {\n        String htmlName;\n        private final int statementType;\n        private final int commandType;\n        private final String[] tables;\n        SQLQueryNode(String className, long nTotalAllocObjects, long totalAllocObjectsSize, int statementType, int commandType, String[] tables) {\n            super(className, nTotalAllocObjects, totalAllocObjectsSize);\n            this.statementType = statementType;\n            this.commandType = commandType;\n            this.tables = tables;\n        }\n        public CCTNode[] getChildren() {\n            if (children == null) {\n                PresoObjAllocCCTNode root = computeChildren();\n                setChildren(root == null ? new PresoObjAllocCCTNode[0] :\n                            (PresoObjAllocCCTNode[])root.getChildren());\n            }\n            return children;\n        }\n        public boolean isLeaf() {\n            if (children == null) return /*includeEmpty ? nCalls == 0 :*/ false;\n            else return super.isLeaf();\n        }   \n        public int getChildCount() {\n            if (children == null) getChildren();\n            return super.getChildCount();\n        }\n        abstract PresoObjAllocCCTNode computeChildren();\n        int getStatementType() { return statementType; }\n        int getCommandType() { return commandType; }\n        String[] getTables() { return tables; }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/jdbc/JDBCView.java",
    "content": "/*\n * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.jdbc;\n\nimport java.util.ResourceBundle;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcCCTProvider;\nimport org.graalvm.visualvm.lib.ui.results.DataView;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JDBCView extends DataView {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.jdbc.Bundle\"); // NOI18N\n\n    static final String COLUMN_NAME = messages.getString(\"JDBCView_ColumnName\"); // NOI18N\n    static final String COLUMN_TOTALTIME = messages.getString(\"JDBCView_TimeColumnName\"); // NOI18N\n    static final String COLUMN_INVOCATIONS = messages.getString(\"JDBCView_InvocationsColumnName\"); // NOI18N\n    static final String COLUMN_COMMANDS = messages.getString(\"JDBCView_ColumnCommands\"); // NOI18N\n    static final String COLUMN_TABLES = messages.getString(\"JDBCView_ColumnTables\"); // NOI18N\n    static final String COLUMN_STATEMENTS = messages.getString(\"JDBCView_ColumnStatements\"); // NOI18N\n    static final String COLUMN_AVEGARE = messages.getString(\"JDBCView_ColumnAverage\"); // NOI18N\n    static final String NAME_COLUMN_TOOLTIP = messages.getString(\"JDBCView_ColumnToolTip\"); // NOI18N\n    static final String TOTAL_TIME_COLUMN_TOOLTIP = messages.getString(\"JDBCView_TimeColumnToolTip\"); // NOI18N\n    static final String INVOCATIONS_COLUMN_TOOLTIP = messages.getString(\"JDBCView_InvocationsColumnToolTip\"); // NOI18N\n    static final String COMMANDS_COLUMN_TOOLTIP = messages.getString(\"JDBCView_ColumnCommandsToolTip\"); // NOI18N\n    static final String TABLES_COLUMN_TOOLTIP = messages.getString(\"JDBCView_ColumnTablesToolTip\"); // NOI18N\n    static final String STATEMENTS_COLUMN_TOOLTIP = messages.getString(\"JDBCView_ColumnStatementsToolTip\"); // NOI18N\n    static final String AVERAGE_COLUMN_TOOLTIP = messages.getString(\"JDBCView_ColumnAverageToolTip\"); // NOI18N\n\n    static final String OTHER_COMMAND = messages.getString(\"JDBCView_OtherCommand\"); // NOI18N\n    \n    static final String STATEMENT_REGULAR = messages.getString(\"JDBCView_RegularStatement\"); // NOI18N\n    static final String STATEMENT_PREPARED = messages.getString(\"JDBCView_PreparedStatement\"); // NOI18N\n    static final String STATEMENT_CALLABLE = messages.getString(\"JDBCView_CallableStatement\"); // NOI18N\n    \n    static final String ACTION_VIEWSQLQUERY = messages.getString(\"JDBCView_ActionViewSqlQuery\"); // NOI18N\n    \n    \n    static final String EXPORT_TOOLTIP = messages.getString(\"JDBCView_ExportTooltip\"); // NOI18N\n    static final String EXPORT_LBL = messages.getString(\"JDBCView_ExportLbl\"); // NOI18N\n    static final String EXPORT_QUERIES = messages.getString(\"JDBCView_ExportQueries\"); // NOI18N\n    static final String ACTION_GOTOSOURCE = messages.getString(\"JDBCView_ActionGoToSource\"); // NOI18N\n    static final String ACTION_PROFILE_METHOD = messages.getString(\"JDBCView_ActionProfileMethod\"); // NOI18N\n    static final String ACTION_PROFILE_CLASS = messages.getString(\"JDBCView_ActionProfileClass\"); // NOI18N\n    static final String SEARCH_QUERIES_SCOPE = messages.getString(\"JDBCView_SearchQueriesScope\"); // NOI18N\n    static final String SEARCH_CALLERS_SCOPE = messages.getString(\"JDBCView_SearchCallersScope\"); // NOI18N\n    static final String SEARCH_SCOPE_TOOLTIP = messages.getString(\"JDBCView_SearchScopeTooltip\"); // NOI18N\n    \n    static final String EXPAND_MENU = messages.getString(\"JDBCView_ExpandMenu\"); // NOI18N\n    static final String EXPAND_PLAIN_ITEM = messages.getString(\"JDBCView_ExpandPlainItem\"); // NOI18N\n    static final String EXPAND_TOPMOST_ITEM = messages.getString(\"JDBCView_ExpandTopmostItem\"); // NOI18N\n    static final String COLLAPSE_CHILDREN_ITEM = messages.getString(\"JDBCView_CollapseChildrenItem\"); // NOI18N\n    static final String COLLAPSE_ALL_ITEM = messages.getString(\"JDBCView_CollapseAllItem\"); // NOI18N\n    // -----\n    \n    static String commandString(int command) {\n        switch (command) {\n            case JdbcCCTProvider.SQL_COMMAND_ALTER: return \"ALTER\"; // NOI18N\n            case JdbcCCTProvider.SQL_COMMAND_CREATE: return \"CREATE\"; // NOI18N\n            case JdbcCCTProvider.SQL_COMMAND_DELETE: return \"DELETE\"; // NOI18N\n            case JdbcCCTProvider.SQL_COMMAND_DESCRIBE: return \"DESCRIBE\"; // NOI18N\n            case JdbcCCTProvider.SQL_COMMAND_INSERT: return \"INSERT\"; // NOI18N\n            case JdbcCCTProvider.SQL_COMMAND_SELECT: return \"SELECT\"; // NOI18N\n            case JdbcCCTProvider.SQL_COMMAND_SET: return \"SET\"; // NOI18N\n            case JdbcCCTProvider.SQL_COMMAND_UPDATE: return \"UPDATE\"; // NOI18N\n            case JdbcCCTProvider.SQL_COMMAND_BATCH: return \"BATCH\"; // NOI18N\n            default: return OTHER_COMMAND;\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/jdbc/LiveJDBCView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.jdbc;\n\nimport java.awt.BorderLayout;\nimport java.awt.Font;\nimport java.awt.event.ActionEvent;\nimport java.util.Set;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport javax.swing.AbstractAction;\nimport javax.swing.ActionMap;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.results.DataView;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class LiveJDBCView extends JPanel {\n\n    private JdbcResultsSnapshot snapshot;\n    private JdbcResultsSnapshot refSnapshot;\n\n    private DataView lastFocused;\n    private JDBCTreeTableView jdbcCallsView;\n\n    private long lastupdate;\n    private volatile boolean refreshIsRunning;\n\n    private ExecutorService executor;\n\n\n    public LiveJDBCView(Set<ClientUtils.SourceCodeSelection> selection) {\n        initUI(selection);\n        registerActions();\n    }\n\n\n    public void setView(boolean forwardCalls, boolean hotSpots, boolean reverseCalls) {\n        jdbcCallsView.setVisible(forwardCalls);\n    }\n    \n    public boolean isRefreshRunning() {\n        return refreshIsRunning;\n    }\n    \n    public long getLastUpdate() {\n        return lastupdate;\n    }\n    \n    public void setData(final JdbcResultsSnapshot snapshotData) {\n        if (refreshIsRunning) return;\n        refreshIsRunning = true;\n        \n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                snapshot = snapshotData;\n                \n                setData();\n            }\n        });\n    }\n    \n    private void setData() {\n        if (snapshot == null) {\n            resetData();\n            refreshIsRunning = false;\n        } else {\n            getExecutor().submit(new Runnable() {\n                public void run() {\n                    final JdbcResultsSnapshot _snapshot = refSnapshot == null ? snapshot :\n                                                         refSnapshot.createDiff(snapshot);\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            try {\n                                boolean diff = _snapshot instanceof JdbcResultsDiff;\n                                jdbcCallsView.setData(_snapshot, null, -1, null, false, false, diff);\n                            } finally {\n                                refreshIsRunning = false;\n                                lastupdate = System.currentTimeMillis();\n                            }\n                        }\n                    });\n                }\n            });\n        }\n    }\n    \n    public boolean setDiffView(final boolean diff) {\n        if (snapshot == null) return false;\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                refSnapshot = diff ? snapshot : null;\n                setData();\n            }\n        });\n        return true;\n    }\n    \n    public void resetData() {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                jdbcCallsView.resetData();\n                snapshot = null;\n                refSnapshot = null;\n            }\n        });\n    }\n    \n    \n    public void showSelectionColumn() {\n        jdbcCallsView.showSelectionColumn();\n    }\n    \n    public void refreshSelection() {\n        jdbcCallsView.refreshSelection();\n    }\n    \n    \n    public void cleanup() {\n    }\n    \n    \n    protected abstract ProfilerClient getProfilerClient();\n    \n    \n    protected boolean profileMethodSupported() { return true; }\n    \n    protected boolean profileClassSupported() { return true; }\n    \n    \n    protected abstract boolean showSourceSupported();\n    \n    protected abstract void showSource(ClientUtils.SourceCodeSelection value);\n    \n    protected abstract void showSQLQuery(String query, String htmlQuery);\n    \n    protected abstract void selectForProfiling(ClientUtils.SourceCodeSelection value);\n    \n    protected void popupShowing() {}\n    \n    protected void popupHidden() {}\n    \n    \n    private void profileMethod(ClientUtils.SourceCodeSelection value) {\n        selectForProfiling(value);\n    }\n    \n    private void profileClass(ClientUtils.SourceCodeSelection value) {\n        selectForProfiling(new ClientUtils.SourceCodeSelection(\n                           value.getClassName(), Wildcards.ALLWILDCARD, null));\n    }\n    \n    \n    private void initUI(Set<ClientUtils.SourceCodeSelection> selection) {\n        setLayout(new BorderLayout(0, 0));\n        \n        jdbcCallsView = new JDBCTreeTableView(selection, false) {\n            protected void installDefaultAction() {\n                getResultsComponent().setDefaultAction(new AbstractAction() {\n                    public void actionPerformed(ActionEvent e) {\n                        ProfilerTable t = getResultsComponent();\n                        int row = t.getSelectedRow();\n                        PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)t.getValueForRow(row);\n                        if (isSQL(node)) {\n                            showQueryImpl(node);\n                        } else {\n                            ClientUtils.SourceCodeSelection userValue = getUserValueForRow(row);\n                            if (userValue != null) performDefaultAction(userValue);\n                        }\n                    }\n                });\n            }\n            protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                if (showSourceSupported()) showSource(userValue);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                LiveJDBCView.this.populatePopup(jdbcCallsView, popup, value, userValue);\n            }\n            protected void popupShowing() { LiveJDBCView.this.popupShowing(); }\n            protected void popupHidden()  { LiveJDBCView.this.popupHidden(); }\n            protected boolean hasBottomFilterFindMargin() { return true; }\n            HideableBarRenderer.BarDiffMode barDiffMode() { return HideableBarRenderer.BarDiffMode.MODE_BAR_NORMAL; }\n        };\n        jdbcCallsView.notifyOnFocus(new Runnable() {\n            public void run() { lastFocused = jdbcCallsView; }\n        });\n        \n        add(jdbcCallsView, BorderLayout.CENTER);\n        \n//        // TODO: read last state?\n//        setView(true, false);\n    }\n    \n    private void registerActions() {\n        ActionMap map = getActionMap();\n        \n        map.put(FilterUtils.FILTER_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                DataView active = getLastFocused();\n                if (active != null) active.activateFilter();\n            }\n        });\n        \n        map.put(SearchUtils.FIND_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                DataView active = getLastFocused();\n                if (active != null) active.activateSearch();\n            }\n        });\n    }\n    \n    private DataView getLastFocused() {\n        if (lastFocused != null && !lastFocused.isShowing()) lastFocused = null;\n        \n        if (lastFocused == null) {\n            if (jdbcCallsView.isShowing()) lastFocused = jdbcCallsView;\n        }\n        \n        return lastFocused;\n    }\n    \n    private void showQueryImpl(PresoObjAllocCCTNode node) {\n        showSQLQuery(node.getNodeName(), ((JDBCTreeTableView.SQLQueryNode)node).htmlName);\n    }\n    \n    private void populatePopup(final DataView invoker, JPopupMenu popup, final Object value, final ClientUtils.SourceCodeSelection userValue) {\n        final PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)value;\n        if (JDBCTreeTableView.isSQL(node)) {\n            popup.add(new JMenuItem(JDBCView.ACTION_VIEWSQLQUERY) {\n                { setFont(getFont().deriveFont(Font.BOLD)); }\n                protected void fireActionPerformed(ActionEvent e) { showQueryImpl((JDBCTreeTableView.SQLQueryNode)value); }\n            });\n            popup.addSeparator();\n        } else if (showSourceSupported()) {\n            popup.add(new JMenuItem(JDBCView.ACTION_GOTOSOURCE) {\n                { setEnabled(userValue != null); setFont(getFont().deriveFont(Font.BOLD)); }\n                protected void fireActionPerformed(ActionEvent e) { showSource(userValue); }\n            });\n            popup.addSeparator();\n        }\n        \n        if (profileMethodSupported()) popup.add(new JMenuItem(JDBCView.ACTION_PROFILE_METHOD) {\n            { setEnabled(userValue != null && JDBCTreeTableView.isSelectable(node)); }\n            protected void fireActionPerformed(ActionEvent e) { profileMethod(userValue); }\n        });\n        \n        if (profileClassSupported()) popup.add(new JMenuItem(JDBCView.ACTION_PROFILE_CLASS) {\n            { setEnabled(userValue != null); }\n            protected void fireActionPerformed(ActionEvent e) { profileClass(userValue); }\n        });\n        \n        if (profileMethodSupported() || profileClassSupported()) popup.addSeparator();\n        \n        JMenuItem[] customItems = invoker.createCustomMenuItems(this, value, userValue);\n        if (customItems != null) {\n            for (JMenuItem customItem : customItems) popup.add(customItem);\n            popup.addSeparator();\n        }\n        \n        customizeNodePopup(invoker, popup, value, userValue);\n        \n        final ProfilerTreeTable ttable = (ProfilerTreeTable)jdbcCallsView.getResultsComponent();\n        JMenu expand = new JMenu(JDBCView.EXPAND_MENU);\n        popup.add(expand);\n\n        expand.add(new JMenuItem(JDBCView.EXPAND_PLAIN_ITEM) {\n            protected void fireActionPerformed(ActionEvent e) {\n                ttable.expandPlainPath(ttable.getSelectedRow(), 1);\n            }\n        });\n\n        expand.add(new JMenuItem(JDBCView.EXPAND_TOPMOST_ITEM) {\n            protected void fireActionPerformed(ActionEvent e) {\n                ttable.expandFirstPath(ttable.getSelectedRow());\n            }\n        });\n        \n        expand.addSeparator();\n            \n        expand.add(new JMenuItem(JDBCView.COLLAPSE_CHILDREN_ITEM) {\n            protected void fireActionPerformed(ActionEvent e) {\n                ttable.collapseChildren(ttable.getSelectedRow());\n            }\n        });\n\n        expand.add(new JMenuItem(JDBCView.COLLAPSE_ALL_ITEM) {\n            protected void fireActionPerformed(ActionEvent e) {\n                ttable.collapseAll();\n            }\n        });\n        \n        popup.addSeparator();\n        popup.add(invoker.createCopyMenuItem());\n        \n        popup.addSeparator();\n        popup.add(new JMenuItem(FilterUtils.ACTION_FILTER) {\n            protected void fireActionPerformed(ActionEvent e) { invoker.activateFilter(); }\n        });\n        popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {\n            protected void fireActionPerformed(ActionEvent e) { invoker.activateSearch(); }\n        });\n    }\n    \n    protected void customizeNodePopup(DataView invoker, JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {}\n    \n    \n    private synchronized ExecutorService getExecutor() {\n        if (executor == null) executor = Executors.newSingleThreadExecutor();\n        return executor;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/jdbc/LiveJDBCViewUpdater.java",
    "content": "/*\n * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.jdbc;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcResultsSnapshot;\nimport org.openide.util.Lookup;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri\n */\npublic class LiveJDBCViewUpdater {\n\n    private static final int MIN_UPDATE_DIFF = 900;\n    private static final int MAX_UPDATE_DIFF = 1400;\n\n\n    private CCTHandler handler;\n\n    private final LiveJDBCView jdbcView;\n    private final ProfilerClient client;\n\n    private volatile boolean paused;\n    private volatile boolean forceRefresh;\n\n\n\n    public LiveJDBCViewUpdater(LiveJDBCView jdbcView, ProfilerClient client) {\n        this.jdbcView = jdbcView;\n        this.client = client;\n    }\n\n\n\n    public void setPaused(boolean paused) {\n        this.paused = paused;\n    }\n\n    public void setForceRefresh(boolean forceRefresh) {\n        this.forceRefresh = forceRefresh;\n    }\n\n    public void update() throws ClientUtils.TargetAppOrVMTerminated {\n        if (handler == null) handler = CCTHandler.registerUpdater(this);\n\n        if (forceRefresh || (!paused && jdbcView.getLastUpdate() + MAX_UPDATE_DIFF < System.currentTimeMillis()))\n            client.forceObtainedResultsDump(true);\n    }\n\n    public void cleanup() {\n        if (handler != null) handler.unregisterUpdater(this);\n        handler = null;\n    }\n\n\n    private void updateData() throws ClientUtils.TargetAppOrVMTerminated {\n        if (!forceRefresh && (paused || jdbcView.getLastUpdate() + MIN_UPDATE_DIFF > System.currentTimeMillis())) return;\n        \n        JdbcResultsSnapshot data = client.getStatus().getInstrMethodClasses() == null ?\n                            null : client.getJdbcProfilingResultsSnapshot(false);\n        jdbcView.setData(data);\n        \n        forceRefresh = false;\n    }\n    \n    private void resetData() {\n        jdbcView.resetData();\n    }\n    \n    \n    @ServiceProvider(service=JdbcCCTProvider.Listener.class)\n    public static class CCTHandler implements JdbcCCTProvider.Listener {\n        \n        private final List<LiveJDBCViewUpdater> updaters = new ArrayList<>();\n        \n        \n        public static CCTHandler registerUpdater(LiveJDBCViewUpdater updater) {\n            CCTHandler handler = Lookup.getDefault().lookup(CCTHandler.class);\n            \n            if (handler.updaters.isEmpty()) {\n                Collection<? extends JdbcCCTProvider> jdbcCCTProviders = Lookup.getDefault().lookupAll(JdbcCCTProvider.class);\n                assert !jdbcCCTProviders.isEmpty();\n                for (JdbcCCTProvider provider : jdbcCCTProviders) provider.addListener(handler);\n            }\n            \n            handler.updaters.add(updater);\n            return handler;\n        }\n        \n        public void unregisterUpdater(LiveJDBCViewUpdater updater) {\n            updaters.remove(updater);\n            \n            if (updaters.isEmpty()) {\n                Collection<? extends JdbcCCTProvider> jdbcCCTProviders = Lookup.getDefault().lookupAll(JdbcCCTProvider.class);\n                assert !jdbcCCTProviders.isEmpty();\n                for (JdbcCCTProvider provider : jdbcCCTProviders) provider.removeListener(this);\n            }\n        }\n        \n\n        public final void cctEstablished(RuntimeCCTNode appRootNode, boolean empty) {\n           if (!empty) {\n                for (LiveJDBCViewUpdater updater : updaters) try {\n                    updater.updateData();\n                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                    Logger.getLogger(LiveJDBCView.class.getName()).log(Level.FINE, null, ex);\n                }\n            }\n        }\n\n        public final void cctReset() {\n            for (LiveJDBCViewUpdater updater : updaters) updater.resetData();\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/jdbc/SQLFilterPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.jdbc;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.KeyEvent;\nimport java.text.MessageFormat;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JTextField;\nimport javax.swing.JToolBar;\nimport javax.swing.KeyStroke;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.border.CompoundBorder;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcCCTProvider;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.InvisibleToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class SQLFilterPanel extends JPanel {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.jdbc.Bundle\"); // NOI18N\n    private static final String QUERIES_CAPTION = messages.getString(\"SQLFilterPanel_QueriesCaption\"); // NOI18N\n    private static final String FILTER_BUTTON = messages.getString(\"SQLFilterPanel_FilterButton\"); // NOI18N\n    private static final String COMMANDS_DROPDOWN = messages.getString(\"SQLFilterPanel_CommandsDropdown\"); // NOI18N\n    private static final String COMMANDS_NOTAVAILABLE = messages.getString(\"SQLFilterPanel_CommandsNotAvailable\"); // NOI18N\n    private static final String TABLES_DROPDOWN = messages.getString(\"SQLFilterPanel_TablesDropdown\"); // NOI18N\n    private static final String TABLES_NOTAVAILABLE = messages.getString(\"SQLFilterPanel_TablesNotAvailable\"); // NOI18N\n    private static final String STATEMENTS_DROPDOWN = messages.getString(\"SQLFilterPanel_StatementsDropdown\"); // NOI18N\n    private static final String STATEMENT_REGULAR = messages.getString(\"SQLFilterPanel_StatementRegular\"); // NOI18N\n    private static final String STATEMENT_PREPARED = messages.getString(\"SQLFilterPanel_StatementPrepared\"); // NOI18N\n    private static final String STATEMENT_CALLABLE = messages.getString(\"SQLFilterPanel_StatementCallable\"); // NOI18N\n    private static final String FILTER_TOOLTIP = messages.getString(\"SQLFilterPanel_FilterTooltip\"); // NOI18N\n    private static final String COMMANDS_TOOLTIP = messages.getString(\"SQLFilterPanel_CommandsTooltip\"); // NOI18N\n    private static final String TABLES_TOOLTIP = messages.getString(\"SQLFilterPanel_TablesTooltip\"); // NOI18N\n    private static final String STATEMENTS_TOOLTIP = messages.getString(\"SQLFilterPanel_StatementsTooltip\"); // NOI18N\n    // -----\n    \n    \n    private static final String APPLY_ACTION_KEY = \"apply-action-key\"; // NOI18N\n    \n    private boolean initialized = false;\n    \n    private JButton applyB;\n    \n    private Configuration current = new Configuration();\n    private Configuration applied = new Configuration();\n    \n    SQLFilterPanel() {\n        super(new BorderLayout());\n        \n        setBorder(new CompoundBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UIManager.getColor(\"controlShadow\")), // NOI18N\n                                     BorderFactory.createMatteBorder(6, 3, 6, 3, UIUtils.getProfilerResultsBackground())));\n        setOpaque(true);\n        setBackground(UIUtils.getProfilerResultsBackground());\n        \n        JToolBar toolbar = new InvisibleToolbar();\n        if (UIUtils.isWindowsModernLookAndFeel())\n            toolbar.setBorder(BorderFactory.createEmptyBorder(2, 2, 1, 2));\n        else if (!UIUtils.isNimbusLookAndFeel() && !UIUtils.isAquaLookAndFeel())\n            toolbar.setBorder(BorderFactory.createEmptyBorder(1, 2, 1, 2));\n        \n        KeyStroke applyKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);\n        Action applyAction = new AbstractAction() {\n            public void actionPerformed(final ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { if (applyB.isEnabled()) applyB.doClick(); }\n                });\n            }\n        };\n        \n        toolbar.add(Box.createHorizontalStrut(3));\n        toolbar.add(new JLabel(QUERIES_CAPTION));\n        toolbar.add(Box.createHorizontalStrut(3));\n        \n        final JTextField filterF = new JTextField(20) {\n            public Dimension getMaximumSize() {\n                Dimension dim = super.getMaximumSize();\n                dim.height = super.getPreferredSize().height;\n                if (UIUtils.isMetalLookAndFeel()) dim.height += 4;\n                return dim;\n            }\n        };\n        filterF.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e)  { handle(); }\n            public void removeUpdate(DocumentEvent e)  { handle(); }\n            public void changedUpdate(DocumentEvent e) { handle(); }\n            private void handle() { current.filter = filterF.getText().trim().toLowerCase(Locale.ENGLISH); changed(); }\n        });\n        filterF.getActionMap().put(APPLY_ACTION_KEY, applyAction);\n        filterF.getInputMap().put(applyKey, APPLY_ACTION_KEY);\n        toolbar.add(filterF);\n        \n        toolbar.add(Box.createHorizontalStrut(10));\n        \n        applyB = new JButton(FILTER_BUTTON) {\n            protected void fireActionPerformed(ActionEvent e) { apply(); }\n        };\n        String filterAccelerator = ActionsSupport.keyAcceleratorString(applyKey);\n        applyB.setToolTipText(MessageFormat.format(FILTER_TOOLTIP, filterAccelerator));\n        applyB.setOpaque(false);\n        JPanel applyP = new JPanel(new BorderLayout()) {\n            public Dimension getMaximumSize() { return getMinimumSize(); }\n        };\n        applyP.add(applyB, BorderLayout.CENTER);\n        applyP.setOpaque(false);\n        toolbar.add(applyP);\n        \n        toolbar.add(Box.createHorizontalStrut(10));\n        \n        toolbar.addSeparator();\n        \n        toolbar.add(Box.createHorizontalStrut(8));\n        \n        PopupButton commands = new PopupButton(\" \" + COMMANDS_DROPDOWN + \" \") { // NOI18N\n            protected void populatePopup(JPopupMenu popup) {\n                List<String> commands = new ArrayList<>(getCommands());\n                if (commands.isEmpty()) {\n                    JLabel l = new JLabel(COMMANDS_NOTAVAILABLE);\n                    l.setBorder(BorderFactory.createEmptyBorder(9, 6, 9, 6));\n                    popup.add(l);\n                } else {\n                    Collections.sort(commands);\n                    current.commands.retainAll(commands);\n                    for (final String command : commands) {\n                        JCheckBoxMenuItem i = new JCheckBoxMenuItem(command, !current.commands.contains(command)) {\n                            protected void fireActionPerformed(ActionEvent e) {\n                                if (!isSelected()) current.commands.add(command);\n                                else current.commands.remove(command);\n                                SwingUtilities.invokeLater(SQLFilterPanel.this::apply);\n                            }\n                        };\n                        popup.add(i);\n                    }\n                }\n            }\n        };\n        commands.setToolTipText(COMMANDS_TOOLTIP);\n        commands.setPopupAlign(SwingConstants.NORTH_WEST);\n        toolbar.add(commands);\n        \n        toolbar.add(Box.createHorizontalStrut(5));\n        \n        PopupButton tables = new PopupButton(\" \" + TABLES_DROPDOWN + \" \") { // NOI18N\n            protected void displayPopup() {\n                Set<String> tablesSet = new HashSet<>(getTables());\n                if (tablesSet.isEmpty()) {\n                    super.displayPopup();\n                } else {\n                    current.tables.retainAll(tablesSet);\n                    new TablesSelector(tablesSet, current.tables) {\n                        protected void selectionChanged(Collection<String> selected) {\n                            current.tables.clear();\n                            current.tables.addAll(selected);\n                            SwingUtilities.invokeLater(SQLFilterPanel.this::apply);\n                        }\n                    }.show(this);\n                }\n            }\n            protected void populatePopup(JPopupMenu popup) {\n                JLabel l = new JLabel(TABLES_NOTAVAILABLE);\n                l.setBorder(BorderFactory.createEmptyBorder(9, 6, 9, 6));\n                popup.add(l);\n            }\n        };\n        tables.setToolTipText(TABLES_TOOLTIP);\n        toolbar.add(tables);\n        \n        toolbar.add(Box.createHorizontalStrut(5));\n        \n        PopupButton statements = new PopupButton(\" \" + STATEMENTS_DROPDOWN + \" \") { // NOI18N\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new JCheckBoxMenuItem(STATEMENT_REGULAR, !current.statements.contains(JdbcCCTProvider.SQL_STATEMENT)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        if (!isSelected()) current.statements.add(JdbcCCTProvider.SQL_STATEMENT);\n                        else current.statements.remove(JdbcCCTProvider.SQL_STATEMENT);\n                        SwingUtilities.invokeLater(SQLFilterPanel.this::apply);\n                    }\n                });\n                \n                popup.add(new JCheckBoxMenuItem(STATEMENT_PREPARED, !current.statements.contains(JdbcCCTProvider.SQL_PREPARED_STATEMENT)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        if (!isSelected()) current.statements.add(JdbcCCTProvider.SQL_PREPARED_STATEMENT);\n                        else current.statements.remove(JdbcCCTProvider.SQL_PREPARED_STATEMENT);\n                        SwingUtilities.invokeLater(SQLFilterPanel.this::apply);\n                    }\n                });\n                \n                popup.add(new JCheckBoxMenuItem(STATEMENT_CALLABLE, !current.statements.contains(JdbcCCTProvider.SQL_CALLABLE_STATEMENT)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        if (!isSelected()) current.statements.add(JdbcCCTProvider.SQL_CALLABLE_STATEMENT);\n                        else current.statements.remove(JdbcCCTProvider.SQL_CALLABLE_STATEMENT);\n                        SwingUtilities.invokeLater(SQLFilterPanel.this::apply);\n                    }\n                });\n            }\n        };\n        statements.setToolTipText(STATEMENTS_TOOLTIP);\n        statements.setPopupAlign(SwingConstants.NORTH_EAST);\n        toolbar.add(statements);\n        \n        toolbar.add(Box.createHorizontalStrut(3));\n        \n        add(toolbar, BorderLayout.CENTER);\n        \n        initialized = true;\n        changed();\n    }\n    \n    private void changed() {\n        if (initialized) applyB.setEnabled(!applied.equals(current));\n    }\n    \n    private void apply() {\n        applyB.setEnabled(false);\n        applied.set(current);\n        applyFilter();\n    }\n    \n    \n    abstract Set<String> getCommands();\n    \n    abstract Set<String> getTables();\n    \n    abstract void applyFilter();\n    \n    \n    boolean passes(String query, String command, String[] tables, int statement) {\n        \n        if (!applied.filter.isEmpty() && !query.toLowerCase(Locale.ENGLISH).contains(applied.filter)) return false;\n        \n        if (!applied.commands.isEmpty() && applied.commands.contains(command)) return false;\n        \n        if (!applied.statements.isEmpty() && applied.statements.contains(statement)) return false;\n        \n        if (applied.tables.isEmpty()) return true;\n        for (String table : tables) if (!applied.tables.contains(table)) return true;\n        \n        return false;\n    }\n    \n    \n    private static class Configuration {\n        \n        String filter = \"\"; // NOI18N\n        \n        final Set<String> commands = new HashSet<>();\n        final Set<String> tables = new HashSet<>();\n        final Set<Integer> statements = new HashSet<>();\n        \n        void set(Configuration o) {\n            filter = o.filter;\n            \n            commands.clear();\n            commands.addAll(o.commands);\n            \n            tables.clear();\n            tables.addAll(o.tables);\n            \n            statements.clear();\n            statements.addAll(o.statements);\n        }\n\n        @Override\n        public int hashCode() {\n            int hash = 7;\n            hash = 37 * hash + filter.hashCode();\n            hash = 37 * hash + commands.hashCode();\n            hash = 37 * hash + tables.hashCode();\n            hash = 37 * hash + statements.hashCode();\n            return hash;\n        }\n        \n        public boolean equals(Object o) {\n            Configuration c = (Configuration)o;\n            return filter.equals(c.filter) &&\n                   commands.equals(c.commands) &&\n                   tables.equals(c.tables) &&\n                   statements.equals(c.statements);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/jdbc/SQLFormatter.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.jdbc;\n\nimport java.awt.Color;\nimport java.util.ResourceBundle;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport javax.swing.JLabel;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class SQLFormatter {\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.jdbc.Bundle\"); // NOI18N\n    private static final String DATABASE_PING = messages.getString(\"SQLFormatter_DatabasePing\"); // NOI18N\n\n    private static final String PING_TEXT = \" - <b>\"+DATABASE_PING+\"</b>\";  // NOI18N\n\n    private static String keywords[] = {\n        \"AS\",\n        \"ALL\",\n        \"AND\",\n        \"ASC\",\n        \"AVG\",\n        \"BY\",\n        \"COUNT\",\n        \"CROSS\",\n        \"DESC\",\n        \"DISTINCT\",\n        \"FROM\",\n        \"FULL\",\n        \"GROUP\",\n        \"HAVING\",\n        \"INNER\",\n        \"LEFT\",\n        \"JOIN\",\n        \"MAX\",\n        \"MIN\",\n        \"NATURAL\",\n        \"NOT\",\n        \"ON\",\n        \"OR\",\n        \"ORDER\",\n        \"OUTER\",\n        \"RIGHT\",\n        \"SELECT\",\n        \"SUM\",\n        \"WHERE\",\n        \"CREATE TABLE\",\n        \"ALTER TABLE\",\n        \"TRUNCATE TABLE\",\n        \"DROP TABLE\",\n        \"INSERT INTO\",\n        \"ALTER SESSION\",\n        \"DELETE\",\n        \"UPDATE\",\n        \"VALUES\",\n        \"SET\",\n        \"'[^']*'\"\n    };\n\n    private static final Pattern keywordsPattern = Pattern.compile(getPattern(keywords), Pattern.CASE_INSENSITIVE);\n\n    private static String getPattern(String[] patterns) {\n        StringBuilder pattern = new StringBuilder();\n\n        for (String patternString : patterns) {\n            pattern.append(\"(\");    // NOI18N\n            if (Character.isLetter(patternString.charAt(0))) {\n                pattern.append(\"\\\\b\");  // NOI18N\n                pattern.append(patternString);\n                pattern.append(\"\\\\b\");  // NOI18N\n            } else {\n                pattern.append(patternString);\n            }\n            pattern.append(\")|\");   // NOI18N\n        }\n        return pattern.substring(0, pattern.length()-1);\n    }\n\n    private static final String pingSQL[] = {\n        \"^SELECT\\\\s+1\",\n        \"^VALUES\\\\s*\\\\(\\\\s*1\\\\s*\\\\)\"\n    };\n\n    private static final Pattern pingSQLPattern = Pattern.compile(getPattern(pingSQL), Pattern.CASE_INSENSITIVE);\n\n\n    static String format(String command) {\n        String formattedCommand;\n        StringBuilder s = new StringBuilder();\n        int offset = 0;\n        Matcher m;\n        \n        command = htmlize(command);\n        m = keywordsPattern.matcher(command);\n        s.append(\"<html>\"); // NOI18N\n        while(m.find()) {\n            String kw = m.group();\n            s.append(command, offset, m.start());\n            if (kw.startsWith(\"'\")) {       // NOI18N\n                // string literal\n                s.append(kw);\n            } else {\n                s.append(\"<b>\");    // NOI18N\n                s.append(kw);\n                s.append(\"</b>\");   // NOI18N\n            }\n            offset = m.end();\n        }\n        s.append(command, offset, command.length());\n        s.append(checkPingSQL(command));\n        s.append(\"</html>\"); // NOI18N\n\n        formattedCommand = s.toString();\n        formattedCommand = formattedCommand.replace(\")\", \")</font>\");   // NOI18N\n        formattedCommand = formattedCommand.replace(\"(\", \"<font color='\" + getGrayHTMLString() + \"'>(\");   // NOI18N\n        return formattedCommand;\n    }\n\n    private static String htmlize(String value) {\n        return value.replace(\">\", \"&gt;\").replace(\"<\", \"&lt;\");     // NOI18N\n    }\n    \n    private static String checkPingSQL(String command) {                         \n        Matcher m = pingSQLPattern.matcher(command);\n        if (m.find()) {\n            return PING_TEXT;\n        }\n        return \"\";\n    }\n    \n    \n    private static String grayHTMLString;\n    private static String getGrayHTMLString() {\n        if (grayHTMLString == null) {\n            Color grayColor = UIUtils.getDisabledForeground(new JLabel().getForeground());\n            grayHTMLString = \"rgb(\" + grayColor.getRed() + \",\" + grayColor.getGreen() + \",\" + grayColor.getBlue() + \")\"; //NOI18N\n        }\n        return grayHTMLString;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/jdbc/SnapshotJDBCView.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.jdbc;\n\nimport java.awt.BorderLayout;\nimport java.awt.Font;\nimport java.awt.event.ActionEvent;\nimport java.text.MessageFormat;\nimport java.util.ResourceBundle;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.Icon;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.results.DataView;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class SnapshotJDBCView extends JPanel {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.jdbc.Bundle\"); // NOI18N\n    private static final String COMPARE_SNAPSHOTS = messages.getString(\"SnapshotJDBCView_CompareSnapshots\"); // NOI18N\n    private static final String RESET_COMPARE_SNAPSHOTS = messages.getString(\"SnapshotJDBCView_ResetCompareSnapshots\"); // NOI18N\n    // -----\n    \n    private JdbcResultsSnapshot snapshot;\n    private JdbcResultsSnapshot refSnapshot;\n    \n//    private int aggregation;\n    \n    private DataView lastFocused;\n    private JDBCTreeTableView jdbcCallsView;\n    \n    private JToggleButton compareButton;\n    \n    private ExecutorService executor;\n    \n    \n    public SnapshotJDBCView(JdbcResultsSnapshot snapshot, Action saveAction, Action compareAction, Action infoAction, ExportUtils.Exportable exportProvider) {\n        initUI(saveAction, compareAction, infoAction, exportProvider);\n        registerActions();\n        \n//        aggregation = CPUResultsSnapshot.METHOD_LEVEL_VIEW;\n        setSnapshot(snapshot);\n    }\n    \n    \n    public void setRefSnapshot(JdbcResultsSnapshot snapshot) {\n        refSnapshot = snapshot;\n        \n        if (compareButton != null && snapshot != null) {\n            compareButton.setSelected(true);\n            compareButton.setToolTipText(RESET_COMPARE_SNAPSHOTS);\n        }\n        \n        setData();\n    }\n    \n    \n    protected abstract boolean showSourceSupported();\n    \n    protected abstract void showSource(ClientUtils.SourceCodeSelection value);\n    \n    protected abstract void showSQLQuery(String query, String htmlQuery);\n    \n    protected abstract void selectForProfiling(ClientUtils.SourceCodeSelection value);\n    \n    \n    private void profileMethod(ClientUtils.SourceCodeSelection value) {\n        selectForProfiling(value);\n    }\n    \n    private void profileClass(ClientUtils.SourceCodeSelection value) {\n        selectForProfiling(new ClientUtils.SourceCodeSelection(\n                           value.getClassName(), Wildcards.ALLWILDCARD, null));\n    }\n    \n    \n    private void initUI(Action saveAction, final Action compareAction, Action infoAction, ExportUtils.Exportable exportProvider) {\n        setLayout(new BorderLayout(0, 0));\n        \n        jdbcCallsView = new JDBCTreeTableView(null, false) {\n            protected void installDefaultAction() {\n                getResultsComponent().setDefaultAction(new AbstractAction() {\n                    public void actionPerformed(ActionEvent e) {\n                        ProfilerTable t = getResultsComponent();\n                        int row = t.getSelectedRow();\n                        PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)t.getValueForRow(row);\n                        if (isSQL(node)) {\n                            showQueryImpl(node);\n                        } else {\n                            ClientUtils.SourceCodeSelection userValue = getUserValueForRow(row);\n                            if (userValue != null) performDefaultAction(userValue);\n                        }\n                    }\n                });\n            }\n            protected void performDefaultAction(ClientUtils.SourceCodeSelection value) {\n                if (showSourceSupported()) showSource(value);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                SnapshotJDBCView.this.populatePopup(jdbcCallsView, popup, value, userValue);\n            }\n        };\n        jdbcCallsView.notifyOnFocus(new Runnable() {\n            public void run() { lastFocused = jdbcCallsView; }\n        });\n        \n        add(jdbcCallsView, BorderLayout.CENTER);\n        \n        ProfilerToolbar toolbar = ProfilerToolbar.create(true);\n        \n        if (saveAction != null) toolbar.add(saveAction);\n        \n        toolbar.add(ExportUtils.exportButton(this, JDBCView.EXPORT_TOOLTIP, getExportables(exportProvider)));\n        \n        if (compareAction != null) {\n            toolbar.addSpace(2);\n            toolbar.addSeparator();\n            toolbar.addSpace(2);\n        \n            Icon icon = (Icon)compareAction.getValue(Action.SMALL_ICON);\n            compareButton = new JToggleButton(icon) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    boolean sel = isSelected();\n                    if (sel) {\n                        compareAction.actionPerformed(e);\n                        if (refSnapshot == null) setSelected(false);\n                    } else {\n                        setRefSnapshot(null);\n                    }\n                    setToolTipText(isSelected() ? RESET_COMPARE_SNAPSHOTS :\n                                                  COMPARE_SNAPSHOTS);\n                }\n            };\n            compareButton.setToolTipText(COMPARE_SNAPSHOTS);\n            toolbar.add(compareButton);\n        }\n//        \n//        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n//        toolbar.addSpace(5);\n        \n//        GrayLabel aggregationL = new GrayLabel(TOOLBAR_AGGREGATION);\n//        toolbar.add(aggregationL);\n//        \n//        toolbar.addSpace(2);\n        \n//        Action aMethods = new AbstractAction() {\n//            { putValue(NAME, AGGREGATION_METHODS); }\n//            public void actionPerformed(ActionEvent e) { setAggregation(CPUResultsSnapshot.METHOD_LEVEL_VIEW); }\n//            \n//        };\n//        Action aClasses = new AbstractAction() {\n//            { putValue(NAME, AGGREGATION_CLASSES); }\n//            public void actionPerformed(ActionEvent e) { setAggregation(CPUResultsSnapshot.CLASS_LEVEL_VIEW); }\n//            \n//        };\n//        Action aPackages = new AbstractAction() {\n//            { putValue(NAME, AGGREGATION_PACKAGES); }\n//            public void actionPerformed(ActionEvent e) { setAggregation(CPUResultsSnapshot.PACKAGE_LEVEL_VIEW); }\n//            \n//        };\n//        \n//        ActionPopupButton aggregation = new ActionPopupButton(aMethods, aClasses, aPackages);\n//        toolbar.add(aggregation);\n//        \n        if (infoAction != null) {\n            toolbar.addFiller();\n            toolbar.add(infoAction);\n        }\n        \n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        \n//        // TODO: read last state?\n//        setView(true, false);\n    }\n    \n    private void registerActions() {\n        ActionMap map = getActionMap();\n        \n        map.put(FilterUtils.FILTER_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                DataView active = getLastFocused();\n                if (active != null) active.activateFilter();\n            }\n        });\n        \n        map.put(SearchUtils.FIND_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                DataView active = getLastFocused();\n                if (active != null) active.activateSearch();\n            }\n        });\n    }\n    \n    private DataView getLastFocused() {\n        if (lastFocused != null && !lastFocused.isShowing()) lastFocused = null;\n        \n        if (lastFocused == null) {\n            if (jdbcCallsView.isShowing()) lastFocused = jdbcCallsView;\n        }\n        \n        return lastFocused;\n    }\n    \n    private void showQueryImpl(PresoObjAllocCCTNode node) {\n        showSQLQuery(node.getNodeName(), ((JDBCTreeTableView.SQLQueryNode)node).htmlName);\n    }\n    \n    private void populatePopup(final DataView invoker, JPopupMenu popup, final Object value, final ClientUtils.SourceCodeSelection userValue) {\n        final PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)value;\n        if (JDBCTreeTableView.isSQL(node)) {\n            popup.add(new JMenuItem(JDBCView.ACTION_VIEWSQLQUERY) {\n                { setFont(getFont().deriveFont(Font.BOLD)); }\n                protected void fireActionPerformed(ActionEvent e) { showQueryImpl((JDBCTreeTableView.SQLQueryNode)value); }\n            });\n            popup.addSeparator();\n        } else if (showSourceSupported()) {\n            popup.add(new JMenuItem(JDBCView.ACTION_GOTOSOURCE) {\n                { setEnabled(userValue != null); setFont(getFont().deriveFont(Font.BOLD)); }\n                protected void fireActionPerformed(ActionEvent e) { showSource(userValue); }\n            });\n            popup.addSeparator();\n        }\n        \n        popup.add(new JMenuItem(JDBCView.ACTION_PROFILE_METHOD) {\n            { setEnabled(userValue != null && JDBCTreeTableView.isSelectable(node)); }\n            protected void fireActionPerformed(ActionEvent e) { profileMethod(userValue); }\n        });\n        \n        popup.add(new JMenuItem(JDBCView.ACTION_PROFILE_CLASS) {\n            { setEnabled(userValue != null); }\n            protected void fireActionPerformed(ActionEvent e) { profileClass(userValue); }\n        });\n        \n        customizeNodePopup(invoker, popup, value, userValue);\n        \n        popup.addSeparator();\n        \n        final ProfilerTreeTable ttable = (ProfilerTreeTable)jdbcCallsView.getResultsComponent();\n        JMenu expand = new JMenu(JDBCView.EXPAND_MENU);\n        popup.add(expand);\n\n        expand.add(new JMenuItem(JDBCView.EXPAND_PLAIN_ITEM) {\n            protected void fireActionPerformed(ActionEvent e) {\n                ttable.expandPlainPath(ttable.getSelectedRow(), 1);\n            }\n        });\n\n        expand.add(new JMenuItem(JDBCView.EXPAND_TOPMOST_ITEM) {\n            protected void fireActionPerformed(ActionEvent e) {\n                ttable.expandFirstPath(ttable.getSelectedRow());\n            }\n        });\n        \n        expand.addSeparator();\n            \n        expand.add(new JMenuItem(JDBCView.COLLAPSE_CHILDREN_ITEM) {\n            protected void fireActionPerformed(ActionEvent e) {\n                ttable.collapseChildren(ttable.getSelectedRow());\n            }\n        });\n\n        expand.add(new JMenuItem(JDBCView.COLLAPSE_ALL_ITEM) {\n            protected void fireActionPerformed(ActionEvent e) {\n                ttable.collapseAll();\n            }\n        });\n        \n        popup.addSeparator();\n        popup.add(invoker.createCopyMenuItem());\n        \n        popup.addSeparator();\n        popup.add(new JMenuItem(FilterUtils.ACTION_FILTER) {\n            protected void fireActionPerformed(ActionEvent e) { invoker.activateFilter(); }\n        });\n        popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {\n            protected void fireActionPerformed(ActionEvent e) { invoker.activateSearch(); }\n        });\n        \n    }\n    \n    protected void customizeNodePopup(DataView invoker, JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {}\n    \n    private void setData() {\n        getExecutor().submit(new Runnable() {\n            public void run() {\n                final JdbcResultsSnapshot _snapshot = refSnapshot == null ? snapshot :\n                                               snapshot.createDiff(refSnapshot);\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        boolean diff = _snapshot instanceof JdbcResultsDiff;\n                        jdbcCallsView.setData(_snapshot, null, -1, null, false, false, diff);\n                    }\n                });\n            }\n        });\n    }\n    \n    protected final void setSnapshot(JdbcResultsSnapshot snapshot) {\n        this.snapshot = snapshot;\n        setData();\n    }\n    \n    private ExportUtils.Exportable[] getExportables(final ExportUtils.Exportable snapshotExporter) {\n        return new ExportUtils.Exportable[] {\n            new ExportUtils.Exportable() {\n                public boolean isEnabled() {\n                    return refSnapshot == null && snapshotExporter.isEnabled();\n                }\n                public String getName() {\n                    return snapshotExporter.getName();\n                }\n                public ExportUtils.ExportProvider[] getProviders() {\n                    return snapshotExporter.getProviders();\n                }\n            },\n            new ExportUtils.Exportable() {\n                public boolean isEnabled() {\n                    return jdbcCallsView.isVisible();\n                }\n                public String getName() {\n                    return MessageFormat.format(JDBCView.EXPORT_LBL, JDBCView.EXPORT_QUERIES);\n                }\n                public ExportUtils.ExportProvider[] getProviders() {\n                    return jdbcCallsView.getExportProviders();\n                }\n            }\n        };\n    }\n    \n    private synchronized ExecutorService getExecutor() {\n        if (executor == null) executor = Executors.newSingleThreadExecutor();\n        return executor;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/jdbc/TablesSelector.java",
    "content": "/*\n * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.jdbc;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.ResourceBundle;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToolBar;\nimport javax.swing.RowFilter;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.lib.ui.swing.FilteringToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerPopup;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.SmallButton;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.CheckBoxRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class TablesSelector {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.jdbc.Bundle\"); // NOI18N\n    private static final String SELECT_TABLES = messages.getString(\"TablesSelector_SelectTables\"); // NOI18N\n    private static final String FILTER_TABLES = messages.getString(\"TablesSelector_FilterTables\"); // NOI18N\n    private static final String COLUMN_SELECTED = messages.getString(\"TablesSelector_ColumnSelected\"); // NOI18N\n    private static final String COLUMN_TABLE = messages.getString(\"TablesSelector_ColumnTable\"); // NOI18N\n    private static final String COLUMN_SELECTED_TOOLTIP = messages.getString(\"TablesSelector_ColumnSelectedToolTip\"); // NOI18N\n    private static final String COLUMN_TABLE_TOOLTIP = messages.getString(\"TablesSelector_ColumnTableToolTip\"); // NOI18N\n    private static final String ACT_SELECT_ALL = messages.getString(\"TablesSelector_ActSelectAll\"); // NOI18N\n    private static final String ACT_UNSELECT_ALL = messages.getString(\"TablesSelector_ActUnselectAll\"); // NOI18N\n    // -----\n    \n    \n    private final String[] tables;\n    private final Collection<String> selected;\n    \n    \n    TablesSelector(Collection<String> tables, Collection<String> selected) {\n        this.tables = tables.toArray(new String[0]);\n        this.selected = new HashSet<>(selected);\n    }\n    \n    \n    public void show(Component invoker) {\n        UI ui = new UI();\n        ui.show(invoker);\n    }\n    \n    \n    protected abstract void selectionChanged(Collection<String> selected);\n    \n    \n    private class UI {\n        \n        private JPanel panel;\n        private SmallButton selectAll;\n        private SmallButton unselectAll;\n        \n        UI() {\n            populatePopup();\n        }\n        \n        void show(Component invoker) {\n            int resizeMode = ProfilerPopup.RESIZE_TOP | ProfilerPopup.RESIZE_LEFT;\n            ProfilerPopup.createRelative(invoker, panel, SwingConstants.NORTH_EAST, resizeMode).show();\n        }\n        \n        private void populatePopup() {\n            JPanel content = new JPanel(new BorderLayout());\n            \n            JLabel hint = new JLabel(SELECT_TABLES, JLabel.LEADING);\n            hint.setBorder(BorderFactory.createEmptyBorder(0, 0, 6, 0));\n            content.add(hint, BorderLayout.NORTH);\n\n            final SelectedTablesModel tablesModel = new SelectedTablesModel();\n            final ProfilerTable tablesTable = new ProfilerTable(tablesModel, true, false, null);\n            tablesTable.setColumnToolTips(new String[] {\n                COLUMN_SELECTED_TOOLTIP,\n                COLUMN_TABLE_TOOLTIP });\n            tablesTable.setMainColumn(1);\n            tablesTable.setFitWidthColumn(1);\n            tablesTable.setDefaultSortOrder(1, SortOrder.ASCENDING);\n            tablesTable.setSortColumn(1);\n            tablesTable.setFixedColumnSelection(0); // #268298 - make sure SPACE always hits the Boolean column\n            tablesTable.setColumnRenderer(0, new CheckBoxRenderer());\n            LabelRenderer projectRenderer = new LabelRenderer();\n            tablesTable.setColumnRenderer(1, projectRenderer);\n            int w = new JLabel(tablesTable.getColumnName(0)).getPreferredSize().width;\n            tablesTable.setDefaultColumnWidth(0, w + 15);\n            int h = tablesTable.getRowHeight() * 8;\n            h += tablesTable.getTableHeader().getPreferredSize().height;\n            projectRenderer.setText(\"A LONGEST EXPECTED TABLE NAME A LONGEST EXPECTED TABLE NAME\"); // NOI18N\n            Dimension prefSize = new Dimension(w + projectRenderer.getPreferredSize().width, h);\n            tablesTable.setPreferredScrollableViewportSize(prefSize);\n            ProfilerTableContainer tableContainer = new ProfilerTableContainer(tablesTable, true, null);\n            JPanel tableContent = new JPanel(new BorderLayout());\n            tableContent.setBorder(BorderFactory.createEmptyBorder(0, 0, 4, 0));\n            tableContent.add(tableContainer, BorderLayout.CENTER);\n            content.add(tableContent, BorderLayout.CENTER);\n\n            JToolBar controls = new FilteringToolbar(FILTER_TABLES) {\n                protected void filterChanged() {\n                    if (isAll()) tablesTable.setRowFilter(null);\n                    else tablesTable.setRowFilter(new RowFilter() {\n                        public boolean include(RowFilter.Entry entry) {\n                            return passes(entry.getStringValue(1));\n                        }\n                    });\n                }\n            };\n            \n            controls.add(Box.createHorizontalStrut(2));\n            controls.addSeparator();\n            controls.add(Box.createHorizontalStrut(3));\n            \n            selectAll = new SmallButton(\" \" + ACT_SELECT_ALL + \" \") { // NOI18N\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            selected.clear();\n                            tablesModel.fireTableDataChanged();\n                            doSelectionChanged(selected);\n                        }\n                    });\n                }\n            };\n            controls.add(selectAll);\n            unselectAll = new SmallButton(\" \" + ACT_UNSELECT_ALL + \" \") { // NOI18N\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            selected.clear();\n                            selected.addAll(Arrays.asList(tables));\n                            tablesModel.fireTableDataChanged();\n                            doSelectionChanged(selected);\n                        }\n                    });\n                }\n            };\n            controls.add(unselectAll);\n\n            content.add(controls, BorderLayout.SOUTH);\n\n            panel = content;\n            \n            updateSelectionButtons();\n        }\n        \n        private void updateSelectionButtons() {\n            selectAll.setEnabled(!selected.isEmpty());\n            unselectAll.setEnabled(selected.size() < tables.length);\n        }\n        \n        private void doSelectionChanged(Collection<String> selected) {\n            updateSelectionButtons();\n            selectionChanged(selected);\n        }\n        \n        private class SelectedTablesModel extends AbstractTableModel {\n            \n            public String getColumnName(int columnIndex) {\n                if (columnIndex == 0) {\n                    return COLUMN_SELECTED;\n                } else if (columnIndex == 1) {\n                    return COLUMN_TABLE;\n                }\n                return null;\n            }\n\n            public Class<?> getColumnClass(int columnIndex) {\n                if (columnIndex == 0) {\n                    return Boolean.class;\n                } else if (columnIndex == 1) {\n                    return Lookup.Provider.class;\n                }\n                return null;\n            }\n\n            public int getRowCount() {\n                return tables.length;\n            }\n\n            public int getColumnCount() {\n                return 2;\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                if (columnIndex == 0) {\n                    return !selected.contains(tables[rowIndex]);\n                } else if (columnIndex == 1) {\n                    return tables[rowIndex];\n                }\n                return null;\n            }\n\n            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {\n                if (Boolean.TRUE.equals(aValue)) {\n                    if (selected.remove(tables[rowIndex])) doSelectionChanged(selected);\n                } else {\n                    if (selected.add(tables[rowIndex])) doSelectionChanged(selected);\n                }\n            }\n\n            public boolean isCellEditable(int rowIndex, int columnIndex) {\n                return columnIndex == 0;\n            }\n\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/locks/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLockContentionPanel_EnableLocksMonitoring=Lock contention monitoring is currently disabled. Press the button to enable it\\:\nLockContentionPanel_EnableLocksMonitoringToolTip=Press to enable lock contention monitoring for this profiling session.\nLockContentionPanel_NoProfiling=No profiling session currently in progress.\nLockContentionPanel_LocksThreadsColumnName=Locks and Threads\nLockContentionPanel_LocksThreadsColumnToolTip=Locks and Threads\nLockContentionPanel_TimeColumnName=Time [%]\nLockContentionPanel_TimeColumnToolTip=Waiting Time [%]\nLockContentionPanel_TimeRelColumnName=Time\nLockContentionPanel_TimeRelColumnToolTip=Waiting time\nLockContentionPanel_WaitsColumnName=Waits\nLockContentionPanel_WaitsColumnToolTip=Waits count\nLockContentionPanel_DisplayMode=View by:\nLockContentionPanel_ModeThreads=Threads\nLockContentionPanel_ModeMonitors=Monitors\nLockContentionPanel_SearchThreadsScope=Search Threads\nLockContentionPanel_SearchMonitorsScope=Search Monitors\nLockContentionPanel_SearchScopeTooltip=Search scope\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/locks/LiveLocksViewUpdater.java",
    "content": "/*\n * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.locks;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.locks.LockCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.locks.LockRuntimeCCTNode;\nimport org.openide.util.Lookup;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic class LiveLocksViewUpdater {\n\n    private static final int MIN_UPDATE_DIFF = 900;\n    private static final int MAX_UPDATE_DIFF = 1400;\n\n    private CCTHandler handler;\n\n    private final LockContentionPanel jdbcView;\n    private final ProfilerClient client;\n\n    private volatile boolean paused;\n    private volatile boolean forceRefresh;\n\n    public LiveLocksViewUpdater(LockContentionPanel jdbcView, ProfilerClient client) {\n        this.jdbcView = jdbcView;\n        this.client = client;\n    }\n\n    public void setPaused(boolean paused) {\n        this.paused = paused;\n    }\n\n    public void setForceRefresh(boolean forceRefresh) {\n        this.forceRefresh = forceRefresh;\n    }\n\n    public void update() throws ClientUtils.TargetAppOrVMTerminated {\n        if (handler == null) {\n            handler = CCTHandler.registerUpdater(this);\n        }\n\n        if (forceRefresh || (!paused && jdbcView.getLastUpdate() + MAX_UPDATE_DIFF < System.currentTimeMillis())) {\n            client.forceObtainedResultsDump(true);\n        }\n    }\n\n    public void cleanup() {\n        if (handler != null) {\n            handler.unregisterUpdater(this);\n        }\n        handler = null;\n    }\n\n    private void updateData(LockRuntimeCCTNode root) throws ClientUtils.TargetAppOrVMTerminated {\n        if (!forceRefresh && (paused || jdbcView.getLastUpdate() + MIN_UPDATE_DIFF > System.currentTimeMillis())) {\n            return;\n        }\n\n        jdbcView.setData(root);\n\n        forceRefresh = false;\n    }\n\n    private void resetData() {\n        jdbcView.resetData();\n    }\n\n    @ServiceProvider(service = LockCCTProvider.Listener.class)\n    public static class CCTHandler implements LockCCTProvider.Listener {\n\n        private final List<LiveLocksViewUpdater> updaters = new ArrayList<>();\n\n        public static CCTHandler registerUpdater(LiveLocksViewUpdater updater) {\n            CCTHandler handler = Lookup.getDefault().lookup(CCTHandler.class);\n\n            if (handler.updaters.isEmpty()) {\n                Collection<? extends LockCCTProvider> locksCCTProviders = Lookup.getDefault().lookupAll(LockCCTProvider.class);\n                assert !locksCCTProviders.isEmpty();\n                for (LockCCTProvider provider : locksCCTProviders) {\n                    provider.addListener(handler);\n                }\n            }\n\n            handler.updaters.add(updater);\n            return handler;\n        }\n\n        public void unregisterUpdater(LiveLocksViewUpdater updater) {\n            updaters.remove(updater);\n\n            if (updaters.isEmpty()) {\n                Collection<? extends LockCCTProvider> jdbcCCTProviders = Lookup.getDefault().lookupAll(LockCCTProvider.class);\n                assert !jdbcCCTProviders.isEmpty();\n                for (LockCCTProvider provider : jdbcCCTProviders) {\n                    provider.removeListener(this);\n                }\n            }\n        }\n\n        public final void cctEstablished(RuntimeCCTNode appRootNode, boolean empty) {\n            if (!empty) {\n                for (LiveLocksViewUpdater updater : updaters) {\n                    try {\n                        if (appRootNode instanceof LockRuntimeCCTNode) {\n                            updater.updateData((LockRuntimeCCTNode) appRootNode);\n                        }\n                    } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                        Logger.getLogger(LiveLocksViewUpdater.class.getName()).log(Level.FINE, null, ex);\n                    }\n                }\n            }\n        }\n\n        public final void cctReset() {\n            for (LiveLocksViewUpdater updater : updaters) {\n                updater.resetData();\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/locks/LockContentionPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.locks;\n\nimport java.awt.AWTKeyStroke;\nimport java.awt.BorderLayout;\nimport java.awt.CardLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.FlowLayout;\nimport java.awt.Insets;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyEvent;\nimport java.util.HashSet;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport javax.swing.AbstractAction;\nimport javax.swing.ActionMap;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.DefaultListCellRenderer;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToolBar;\nimport javax.swing.JTree;\nimport javax.swing.KeyStroke;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport javax.swing.border.Border;\nimport javax.swing.border.CompoundBorder;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.tree.TreeNode;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.locks.LockCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.locks.LockRuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.FlatToolBar;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelBracketTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.results.DataView;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.McsTimeRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class LockContentionPanel extends DataView {\n    \n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.locks.Bundle\"); // NOI18N\n    private static final String ENABLE_LOCKS_MONITORING = messages.getString(\"LockContentionPanel_EnableLocksMonitoring\"); // NOI18N\n    private static final String ENABLE_LOCKS_MONITORING_TOOLTIP = messages.getString(\"LockContentionPanel_EnableLocksMonitoringToolTip\"); // NOI18N\n    private static final String NO_PROFILING = messages.getString(\"LockContentionPanel_NoProfiling\"); // NOI18N\n    private static final String LOCKS_THREADS_COLUMN_NAME = messages.getString(\"LockContentionPanel_LocksThreadsColumnName\"); // NOI18N\n    private static final String LOCKS_THREADS_COLUMN_TOOLTIP = messages.getString(\"LockContentionPanel_LocksThreadsColumnToolTip\"); // NOI18N\n//    private static final String TIME_COLUMN_NAME = messages.getString(\"LockContentionPanel_TimeColumnName\"); // NOI18N\n//    private static final String TIME_COLUMN_TOOLTIP = messages.getString(\"LockContentionPanel_TimeColumnToolTip\"); // NOI18N\n    private static final String TIME_REL_COLUMN_NAME = messages.getString(\"LockContentionPanel_TimeRelColumnName\"); // NOI18N\n    private static final String TIME_REL_COLUMN_TOOLTIP = messages.getString(\"LockContentionPanel_TimeRelColumnToolTip\"); // NOI18N\n    private static final String WAITS_COLUMN_NAME = messages.getString(\"LockContentionPanel_WaitsColumnName\"); // NOI18N\n    private static final String WAITS_COLUMN_TOOLTIP = messages.getString(\"LockContentionPanel_WaitsColumnToolTip\"); // NOI18N\n    private static final String DISPLAY_MODE = messages.getString(\"LockContentionPanel_DisplayMode\"); // NOI18N\n    private static final String MODE_THREADS = messages.getString(\"LockContentionPanel_ModeThreads\"); // NOI18N\n    private static final String MODE_MONITORS = messages.getString(\"LockContentionPanel_ModeMonitors\"); // NOI18N\n    private static final String SEARCH_THREADS_SCOPE = messages.getString(\"LockContentionPanel_SearchThreadsScope\"); // NOI18N\n    private static final String SEARCH_MONITORS_SCOPE = messages.getString(\"LockContentionPanel_SearchMonitorsScope\"); // NOI18N\n    private static final String SEARCH_SCOPE_TOOLTIP = messages.getString(\"LockContentionPanel_SearchScopeTooltip\"); // NOI18N\n    // -----\n    private boolean refreshIsRunning;\n    \n    public static enum Aggregation { BY_THREADS, BY_MONITORS }\n    \n    private final ProfilerToolbar toolbar;\n    \n    private final LocksTreeTableModel treeTableModel;\n    private final ProfilerTreeTable treeTable;\n    private final ProfilerTableContainer treeTablePanel;\n    private final JComboBox modeCombo;\n    \n    private int columnCount;\n    \n    private String[] columnNames;\n    private TableCellRenderer[] columnRenderers;\n    private String[] columnToolTips;\n    private int[] columnWidths;\n    \n    private Aggregation aggregation = Aggregation.BY_THREADS;\n    \n    private final JPanel contentPanel;\n    private final JPanel notificationPanel;\n    private final JButton enableLockContentionButton;\n    private final JLabel enableLockContentionLabel1;\n    private final JLabel enableLockContentionLabel2;\n    \n    private LockRuntimeCCTNode root;\n    private long countsInMicrosec = 1;\n    \n    private final HideableBarRenderer hbrTime;\n    private final HideableBarRenderer hbrWaits;\n\n    private long lastupdate;\n    \n    private boolean searchThreads = true;\n    private boolean searchMonitors = true;\n    \n    \n    public LockContentionPanel() { \n    \n        toolbar = ProfilerToolbar.create(true);\n        \n        JLabel modeLabel = new JLabel(DISPLAY_MODE);\n        modeLabel.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 6));\n        toolbar.add(modeLabel);\n        \n        modeCombo = new JComboBox(new Object[] { MODE_THREADS, MODE_MONITORS }) {\n            protected void fireActionEvent() {\n                super.fireActionEvent();\n                treeTable.clearSelection();\n                prepareResults();\n            }\n            public Dimension getMaximumSize() {\n                Dimension dim = getPreferredSize();\n                dim.width += 20;\n                return dim;\n            }\n        };\n        modeCombo.setRenderer(new DefaultListCellRenderer() {\n            public Component getListCellRendererComponent(final JList list, final Object value, final int index,\n                                                          final boolean isSelected, final boolean cellHasFocus) {\n                DefaultListCellRenderer dlcr =\n                        (DefaultListCellRenderer)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);\n\n                if (MODE_THREADS.equals(value.toString())) {\n                    dlcr.setIcon(Icons.getIcon(ProfilerIcons.THREAD));\n                } else if (MODE_MONITORS.equals(value.toString())) {\n                    dlcr.setIcon(Icons.getIcon(ProfilerIcons.WINDOW_LOCKS));\n                }\n\n                return dlcr;\n            }\n        });\n        modeLabel.setLabelFor(modeCombo);\n        toolbar.add(modeCombo);\n        \n        initColumnsData();\n        \n        treeTableModel = new LocksTreeTableModel();\n        \n        treeTable = new ProfilerTreeTable(treeTableModel, true, true, new int[] { 0 }) {\n//            protected Object getValueForPopup(int row) {\n//                if (row == -1) return null;\n//                if (row >= getModel().getRowCount()) return null; // #239936\n//                return Integer.valueOf(convertRowIndexToModel(row));\n//            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                popup.add(createCopyMenuItem());\n                popup.addSeparator();\n                \n                popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {\n                    protected void fireActionPerformed(ActionEvent e) { activateSearch(); }\n                });\n            }\n        };\n        treeTable.setRootVisible(false);\n        treeTable.setShowsRootHandles(true);\n        \n        treeTable.providePopupMenu(true);\n        \n        treeTable.setMainColumn(0);\n        treeTable.setFitWidthColumn(0);\n        \n        treeTable.setSortColumn(1);\n        treeTable.setDefaultSortOrder(1, SortOrder.DESCENDING);\n        \n        LockContentionRenderer lcRenderer = new LockContentionRenderer();\n        treeTable.setTreeCellRenderer(lcRenderer);\n        \n        Number refTime = new Long(123456);\n        \n        NumberPercentRenderer npr = new NumberPercentRenderer(new McsTimeRenderer());\n//        npr.setValue(refTime, -1);\n        hbrTime = new HideableBarRenderer(npr);\n        hbrTime.setMaxValue(refTime.longValue());\n        treeTable.setColumnRenderer(1, hbrTime);\n        treeTable.setDefaultColumnWidth(1, hbrTime.getOptimalWidth());\n        \n        hbrWaits = new HideableBarRenderer(new NumberRenderer());\n        hbrWaits.setMaxValue(1234567);\n//        treeTable.setDefaultColumnWidth(3, hbrWaits.getOptimalWidth());\n        treeTable.setColumnRenderer(2, hbrWaits);\n        treeTable.setDefaultColumnWidth(2, hbrWaits.getMaxNoBarWidth());\n        \n        treeTable.setColumnToolTips(new String[] { LOCKS_THREADS_COLUMN_TOOLTIP,\n                                                   TIME_REL_COLUMN_TOOLTIP,\n                                                   WAITS_COLUMN_TOOLTIP });\n        \n//        NumberRenderer numberRenderer = new NumberRenderer();\n//        numberRenderer.setValue(refTime, -1);\n//        treeTable.setDefaultColumnWidth(3, numberRenderer.getPreferredSize().width);\n//        treeTable.setColumnRenderer(3, numberRenderer);\n\n        // Disable traversing table cells using TAB and Shift+TAB\n        Set<AWTKeyStroke> keys = new HashSet<>(treeTable.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));\n        keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));\n        treeTable.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys);\n\n        keys = new HashSet<>(treeTable.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));\n        keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));\n        treeTable.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys);\n        \n        treeTablePanel = new ProfilerTableContainer(treeTable, false, null);\n//        treeTablePanel.clearBorders();\n        \n        notificationPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 15));\n        notificationPanel.setBackground(treeTable.getBackground());\n        UIUtils.decorateProfilerPanel(notificationPanel);\n\n        Border myRolloverBorder = new CompoundBorder(new FlatToolBar.FlatRolloverButtonBorder(Color.GRAY, Color.LIGHT_GRAY),\n                                                     new FlatToolBar.FlatMarginBorder());\n\n        enableLockContentionLabel1 = new JLabel(ENABLE_LOCKS_MONITORING);\n        enableLockContentionLabel1.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 3));\n        enableLockContentionLabel1.setForeground(Color.DARK_GRAY);\n\n        enableLockContentionButton = new JButton(Icons.getIcon(ProfilerIcons.VIEW_LOCKS_32));\n        enableLockContentionButton.setToolTipText(ENABLE_LOCKS_MONITORING_TOOLTIP);\n        enableLockContentionButton.setContentAreaFilled(false);\n        enableLockContentionButton.setMargin(new Insets(3, 3, 3, 3));\n        enableLockContentionButton.setVerticalTextPosition(SwingConstants.BOTTOM);\n        enableLockContentionButton.setHorizontalTextPosition(SwingConstants.CENTER);\n        enableLockContentionButton.setRolloverEnabled(true);\n        enableLockContentionButton.setBorder(myRolloverBorder);\n        enableLockContentionButton.getAccessibleContext().setAccessibleName(ENABLE_LOCKS_MONITORING_TOOLTIP);\n\n        enableLockContentionLabel2 = new JLabel(NO_PROFILING);\n        enableLockContentionLabel2.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 0));\n        enableLockContentionLabel2.setForeground(Color.DARK_GRAY);\n        enableLockContentionLabel2.setVisible(false);\n\n        notificationPanel.add(enableLockContentionLabel1);\n        notificationPanel.add(enableLockContentionButton);\n        notificationPanel.add(enableLockContentionLabel2);\n        \n        contentPanel = new JPanel(new CardLayout());\n        contentPanel.add(notificationPanel, \"DISABLED\"); // NOI18N\n        contentPanel.add(treeTablePanel, \"ENABLED\"); // NOI18N\n        contentPanel.setOpaque(true);\n        contentPanel.setBackground(UIUtils.getProfilerResultsBackground());\n        \n        add(contentPanel, BorderLayout.CENTER);\n        \n        prepareResults(); // Disables combo\n        \n        registerActions();\n    }\n    \n    \n    protected abstract ProfilerClient getProfilerClient();\n    \n    \n    private void registerActions() {\n        ActionMap map = getActionMap();\n        \n//        map.put(FilterUtils.FILTER_ACTION_KEY, new AbstractAction() {\n//            public void actionPerformed(ActionEvent e) { activateFilter(); }\n//        });\n        \n        map.put(SearchUtils.FIND_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { activateSearch(); }\n        });\n    }\n    \n    protected SearchUtils.TreeHelper getSearchHelper() {\n        return new SearchUtils.TreeHelper() {\n            public int getNodeType(TreeNode tnode) {\n                LockCCTNode node = (LockCCTNode)tnode;\n                CCTNode parent = node.getParent();\n                if (parent == null) return SearchUtils.TreeHelper.NODE_SKIP_DOWN;\n                \n                if (node.isThreadLockNode()) {\n                    return searchThreads  ? SearchUtils.TreeHelper.NODE_SEARCH_DOWN :\n                                            SearchUtils.TreeHelper.NODE_SKIP_DOWN;\n                } else if (node.isMonitorNode()) {\n                    return searchMonitors ? SearchUtils.TreeHelper.NODE_SEARCH_DOWN :\n                                            SearchUtils.TreeHelper.NODE_SKIP_DOWN;\n                }\n                \n                return SearchUtils.TreeHelper.NODE_SKIP_DOWN;\n            }\n        };\n    }\n    \n    protected Component[] getSearchOptions() {\n        PopupButton pb = new PopupButton (Icons.getIcon(ProfilerIcons.TAB_CALL_TREE)) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new JCheckBoxMenuItem(SEARCH_THREADS_SCOPE, searchThreads) {\n                    {\n                        if (!searchMonitors) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        searchThreads = !searchThreads;\n                    }\n                });\n                popup.add(new JCheckBoxMenuItem(SEARCH_MONITORS_SCOPE, searchMonitors) {\n                    {\n                        if (!searchThreads) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        searchMonitors = !searchMonitors;\n                    }\n                });\n            }\n        };\n        pb.setToolTipText(SEARCH_SCOPE_TOOLTIP);\n        return new Component[] { Box.createHorizontalStrut(5), pb };\n    }\n    \n    protected ProfilerTable getResultsComponent() {\n        return treeTable;\n    }\n    \n    protected boolean hasBottomFilterFindMargin() {\n        return true;\n    }\n    \n    \n    public void setAggregation(Aggregation aggregation) {\n        this.aggregation = aggregation;\n        prepareResults();\n    }\n    \n    public Aggregation getAggregation() {\n        return aggregation;\n    }\n    \n    public boolean isRefreshing() {\n        return refreshIsRunning;\n    }\n\n    public long getLastUpdate() {\n        return lastupdate;\n    }\n\n    public void setData(final LockRuntimeCCTNode appRootNode) {\n        refreshIsRunning = true;\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                root = appRootNode;\n            }\n        });\n        prepareResults();\n//        forceRefresh = false;\n    }\n    \n    public void resetData() {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                root = null;\n                treeTableModel.setRoot(LockCCTNode.EMPTY);\n            }\n        });\n    }\n    \n    public void addSaveViewAction(AbstractAction saveViewAction) {\n        Component actionButton = toolbar.add(saveViewAction);\n        toolbar.remove(actionButton);\n        toolbar.add(actionButton, 0);\n        toolbar.add(new JToolBar.Separator(), 1);\n    }\n    \n    public void addExportAction(AbstractAction exportAction) {\n        Component actionButton = toolbar.add(exportAction);\n        toolbar.remove(actionButton);\n        toolbar.add(actionButton, 0);\n    }\n    \n    \n    public void prepareResults() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (root == null) {refreshIsRunning = false; return; }\n                \n                LockCCTNode newRoot = null;\n                switch (aggregation) {\n                    case BY_THREADS:\n                        newRoot = root.getThreads();\n                        break;\n                    case BY_MONITORS:\n                        newRoot = root.getMonitors();\n                        break;\n                }\n                \n//                newRoot.sortChildren(getSortBy(sortingColumn), sortingOrder);\n                hbrTime.setMaxValue(getTimeInMicroSec(newRoot));\n                hbrWaits.setMaxValue(newRoot.getWaits());\n                treeTableModel.setRoot(newRoot);\n                lastupdate = System.currentTimeMillis();\n                refreshIsRunning = false;\n            }\n        });\n    }\n    \n    public void lockContentionDisabled() {\n        ((CardLayout)(contentPanel.getLayout())).show(contentPanel, \"DISABLED\"); // NOI18N\n//        updateZoomButtonsEnabledState();\n//        threadsSelectionCombo.setEnabled(false);\n    }\n\n    public void lockContentionEnabled() {\n        ((CardLayout)(contentPanel.getLayout())).show(contentPanel, \"ENABLED\"); // NOI18N\n//        updateZoomButtonsEnabledState();\n//        threadsSelectionCombo.setEnabled(true);\n    }\n    \n    public void addLockContentionListener(ActionListener listener) {\n        enableLockContentionButton.addActionListener(listener);\n    }\n    \n    public void removeLockContentionListener(ActionListener listener) {\n        enableLockContentionButton.removeActionListener(listener);\n    }\n    \n    private long getTimeInMicroSec(LockCCTNode node) {\n        return node.getTime() / countsInMicrosec;\n    }\n\n    private String getTimeInMillis(LockCCTNode node) {\n        long microSec = getTimeInMicroSec(node);\n        return StringUtils.mcsTimeToString(microSec);\n    }\n    \n    private void initColumnsData() {\n        columnCount = 3;\n        \n        columnWidths = new int[columnCount - 1]; // Width of the first column fits to width\n        columnNames = new String[columnCount];\n        columnToolTips = new String[columnCount];\n        columnRenderers = new TableCellRenderer[columnCount];\n\n        columnNames[0] = LOCKS_THREADS_COLUMN_NAME;\n        columnToolTips[0] = LOCKS_THREADS_COLUMN_TOOLTIP;\n\n//        columnNames[1] = TIME_COLUMN_NAME;\n//        columnToolTips[1] = TIME_COLUMN_TOOLTIP;\n        \n        columnNames[1] = TIME_REL_COLUMN_NAME;\n        columnToolTips[1] = TIME_REL_COLUMN_TOOLTIP;\n        \n        columnNames[2] = WAITS_COLUMN_NAME;\n        columnToolTips[2] = WAITS_COLUMN_TOOLTIP;\n\n        int maxWidth = getFontMetrics(getFont()).charWidth('W') * 12; // NOI18N // initial width of data columns\n\n        columnRenderers[0] = null;\n\n//        columnWidths[1 - 1] = maxWidth;\n//        columnRenderers[1] = new CustomBarCellRenderer(0, 100);\n        \n        columnWidths[1 - 1] = maxWidth;\n        columnRenderers[1] = new LabelBracketTableCellRenderer(JLabel.TRAILING);\n\n        columnWidths[2 - 1] = maxWidth;\n        columnRenderers[2] = new LabelTableCellRenderer(JLabel.TRAILING);\n    }\n    \n    \n    public Component getToolbar() {\n        return toolbar.getComponent();\n    }\n    \n    \n    private class LocksTreeTableModel extends ProfilerTreeTableModel.Abstract {\n        \n        private LocksTreeTableModel() {\n            super(LockCCTNode.EMPTY);\n        }\n\n        public boolean isCellEditable(TreeNode node, int columnIndex) {\n            return false;\n        }\n\n        public Class<?> getColumnClass(int column) {\n            if (column == 0) {\n                return JTree.class;\n            } else if (column == 1) {\n                return Long.class;\n            } else if (column == 2) {\n                return Long.class;\n            }\n            return null;\n        }\n\n        public int getColumnCount() {\n            return columnCount;\n        }\n\n        public String getColumnName(int columnIndex) {\n            return columnNames[columnIndex];\n        }\n\n        public Object getValueAt(TreeNode node, int columnIndex) {\n            LockCCTNode lnode = (LockCCTNode)node;\n\n            switch (columnIndex) {\n                case 0:\n                    return lnode;\n                case 1:\n                    return getTimeInMicroSec(lnode);\n//                    return lnode;\n//                    return getTimeInMillis(lnode) + \" ms (\" // NOI18N\n//                    + percentFormat.format(lnode.getTimeInPerCent() / 100) + \")\"; // NOI18N\n                case 2:\n                    return lnode.getWaits();\n                    \n                default:\n                    return null;\n            }\n        }\n        \n        public void setValueAt(Object aValue, TreeNode node, int column) {}\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/locks/LockContentionRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.locks;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.lib.jfluid.results.locks.LockCCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.results.PackageColorer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NormalBoldGrayRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class LockContentionRenderer extends NormalBoldGrayRenderer {\n\n    private static final Icon THREAD_ICON = Icons.getIcon(ProfilerIcons.THREAD);\n    private static final Icon LOCK_ICON = Icons.getIcon(ProfilerIcons.WINDOW_LOCKS);\n\n    public void setValue(Object value, int row) {\n        if (value == null) {\n            setNormalValue(\"\"); // NOI18N\n            setBoldValue(\"\"); // NOI18N\n            setGrayValue(\"\"); // NOI18N\n            setIcon(null);\n        } else {\n            LockCCTNode node = (LockCCTNode)value;\n\n            boolean threadNode = node.isThreadLockNode();\n            boolean monitorNode = node.isMonitorNode();\n\n            String nodeName = node.getNodeName();\n            int bracketIndex = nodeName.indexOf('('); // NOI18N\n            int dotIndex = nodeName.lastIndexOf('.'); // NOI18N\n\n            String normalValue = getNormalValue(node, nodeName, bracketIndex, dotIndex, threadNode);\n            String boldValue = getBoldValue(node, nodeName, bracketIndex, dotIndex, threadNode);\n            String grayValue = getGrayValue(node, nodeName, bracketIndex, dotIndex, threadNode);\n\n            setNormalValue(normalValue);\n            setBoldValue(boldValue);\n            setGrayValue(grayValue);\n\n            Icon icon = null;\n            if (threadNode) icon = THREAD_ICON;\n            else if (monitorNode) icon = LOCK_ICON;\n\n            setIcon(icon);\n            \n            // TODO: optimize to not slow down sort/search/filter by resolving color!\n            setCustomForeground(monitorNode ? PackageColorer.getForeground(normalValue) : null);\n        }\n    }\n    \n    private String getNormalValue(LockCCTNode node, String nodeName, int bracketIndex,\n                                  int dotIndex, boolean threadNode) {\n        \n        if (threadNode) return node.getParent().getParent() == null ? \"\" : nodeName; // NOI18N\n        \n        if (dotIndex == -1 && bracketIndex == -1) return nodeName;\n\n        if (bracketIndex != -1) nodeName = nodeName.substring(0, bracketIndex);\n        return nodeName.substring(0, dotIndex + 1);\n    }\n    \n    private String getBoldValue(LockCCTNode node, String nodeName, int bracketIndex,\n                                int dotIndex, boolean threadNode) {\n        \n        if (threadNode) return node.getParent().getParent() == null ? nodeName : \"\"; // NOI18N\n        \n        if (dotIndex == -1 && bracketIndex == -1) return \"\"; // NOI18N\n\n        if (bracketIndex != -1) nodeName = nodeName.substring(0, bracketIndex);\n        return nodeName.substring(dotIndex + 1);\n    }\n    \n    private String getGrayValue(LockCCTNode node, String nodeName, int bracketIndex,\n                                int dotIndex, boolean threadNode) {\n        \n        if (threadNode) return \"\"; // NOI18N\n        \n        return bracketIndex != -1 ? \" \" + nodeName.substring(bracketIndex) : \"\"; // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/locks/LockContentionTreeCellRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.locks;\n\nimport java.awt.Component;\nimport javax.swing.Icon;\nimport javax.swing.JTree;\nimport org.graalvm.visualvm.lib.jfluid.results.locks.LockCCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.components.tree.EnhancedTreeCellRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class LockContentionTreeCellRenderer extends EnhancedTreeCellRenderer {\n\n    protected String getLabel1Text(Object node, String value) {\n        LockCCTNode n = (LockCCTNode)node;\n        String name = n.getNodeName();\n        if (n.isThreadLockNode()) return n.getParent().getParent() == null ? \"\" : name; // NOI18N\n\n        int bracketIndex = name.indexOf('('); // NOI18N\n        int dotIndex = name.lastIndexOf('.'); // NOI18N\n\n        if ((dotIndex == -1) && (bracketIndex == -1)) return name;\n\n        if (bracketIndex != -1) {\n            name = name.substring(0, bracketIndex);\n            dotIndex = name.lastIndexOf('.'); // NOI18N\n        }\n\n        return name.substring(0, dotIndex + 1);\n    }\n\n    protected String getLabel2Text(Object node, String value) {\n        LockCCTNode n = (LockCCTNode)node;\n        String name = n.getNodeName();\n        if (n.isThreadLockNode()) return n.getParent().getParent() == null ? name : \"\"; // NOI18N\n\n        int bracketIndex = name.indexOf('('); // NOI18N\n        int dotIndex = name.lastIndexOf('.'); // NOI18N\n\n        if ((dotIndex == -1) && (bracketIndex == -1)) return \"\"; // NOI18N\n\n        if (bracketIndex != -1) {\n            name = name.substring(0, bracketIndex);\n            dotIndex = name.lastIndexOf('.'); // NOI18N\n        }\n\n        return name.substring(dotIndex + 1);\n    }\n\n    protected String getLabel3Text(Object node, String value) {\n        LockCCTNode n = (LockCCTNode)node;\n        if (n.isThreadLockNode()) return \"\"; // NOI18N\n        \n        String name = n.getNodeName();\n        int bracketIndex = name.indexOf('('); // NOI18N\n        return bracketIndex != -1 ? \" \" + name.substring(bracketIndex) : \"\"; // NOI18N\n    }\n    \n    private Icon getIcon(Object node) {\n        LockCCTNode n = (LockCCTNode)node;\n        if (n.isThreadLockNode()) return Icons.getIcon(ProfilerIcons.THREAD);\n        else if (n.isMonitorNode()) return Icons.getIcon(ProfilerIcons.WINDOW_LOCKS);\n        return null;\n    }\n    \n    protected Icon getLeafIcon(Object value) {\n        return getIcon(value);\n    }\n\n    protected Icon getOpenIcon(Object value) {\n        return getIcon(value);\n    }\n    \n    protected Icon getClosedIcon(Object value) {\n        return getIcon(value);\n    }\n    \n    \n    public Component getTreeCellRendererComponentPersistent(JTree tree, Object value, boolean sel, boolean expanded,\n                                                            boolean leaf, int row, boolean hasFocus) {\n        LockContentionTreeCellRenderer renderer = new LockContentionTreeCellRenderer();\n//        renderer.setLeafIcon(leafIcon);\n//        renderer.setClosedIcon(closedIcon);\n//        renderer.setOpenIcon(openIcon);\n\n        return renderer.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/ActionsHandler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\n\n/**\n *\n * @author Emanuel Hucka\n */\npublic interface ActionsHandler {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void performAction(String actionName, Object[] arguments);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/AllocResultsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.AWTKeyStroke;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyEvent;\nimport java.util.HashSet;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport javax.swing.*;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedTable;\nimport org.graalvm.visualvm.lib.ui.components.table.ClassNameTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.ExtendedTableModel;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelBracketTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.SortableTableModel;\n\n\n/**\n * This class implements presentation frames for Object Allocation Profiling.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic abstract class AllocResultsPanel extends MemoryResultsPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String FILTER_MENU_ITEM_NAME = messages.getString(\"AllocResultsPanel_FilterMenuItemName\"); // NOI18N\n    private static final String CLASS_COLUMN_NAME = messages.getString(\"AllocResultsPanel_ClassColumnName\"); // NOI18N\n    private static final String BYTES_REL_COLUMN_NAME = messages.getString(\"AllocResultsPanel_BytesRelColumnName\"); // NOI18N\n    private static final String BYTES_COLUMN_NAME = messages.getString(\"AllocResultsPanel_BytesColumnName\"); // NOI18N\n    private static final String OBJECTS_COLUMN_NAME = messages.getString(\"AllocResultsPanel_ObjectsColumnName\"); // NOI18N\n    private static final String CLASS_COLUMN_TOOLTIP = messages.getString(\"AllocResultsPanel_ClassColumnToolTip\"); // NOI18N\n    private static final String BYTES_REL_COLUMN_TOOLTIP = messages.getString(\"AllocResultsPanel_BytesRelColumnToolTip\"); // NOI18N\n    private static final String BYTES_COLUMN_TOOLTIP = messages.getString(\"AllocResultsPanel_BytesColumnToolTip\"); // NOI18N\n    private static final String OBJECTS_COLUMN_TOOLTIP = messages.getString(\"AllocResultsPanel_ObjectsColumnToolTip\"); // NOI18N\n    private static final String TABLE_ACCESS_NAME = messages.getString(\"AllocResultsPanel_TableAccessName\"); // NOI18N\n                                                                                                             // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected int[] nTotalAllocObjects;\n    protected long[] totalAllocObjectsSize;\n    protected long nTotalBytes;\n    protected long nTotalClasses;\n    private int initialSortingColumn;\n    private int minNamesColumnWidth; // minimal width of classnames columns\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public AllocResultsPanel(MemoryResUserActionsHandler actionsHandler) {\n        super(actionsHandler);\n\n        setDefaultSorting();\n\n        initColumnsData();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    // NOTE: this method only sets sortBy and sortOrder, it doesn't refresh UI!\n    public void setDefaultSorting() {\n        setSorting(1, SortableTableModel.SORT_ORDER_DESC);\n    }\n\n    // NOTE: this method only sets sortBy and sortOrder, it doesn't refresh UI!\n    public void setSorting(int sColumn, boolean sOrder) {\n        if (sColumn == CommonConstants.SORTING_COLUMN_DEFAULT) {\n            setDefaultSorting();\n        } else {\n            initialSortingColumn = sColumn;\n            sortBy = getSortBy(initialSortingColumn);\n            sortOrder = sOrder;\n        }\n    }\n\n    public int getSortingColumn() {\n        if (resTableModel == null) {\n            return CommonConstants.SORTING_COLUMN_DEFAULT;\n        }\n\n        return resTableModel.getRealColumn(resTableModel.getSortingColumn());\n    }\n\n    public boolean getSortingOrder() {\n        if (resTableModel == null) {\n            return false;\n        }\n\n        return resTableModel.getSortingOrder();\n    }\n\n    protected abstract JPopupMenu getPopupMenu();\n\n    protected CustomBarCellRenderer getBarCellRenderer() {\n//        return new CustomBarCellRenderer(0, maxValue);\n        return new CustomBarCellRenderer(0, 100);\n    }\n\n    protected void getResultsSortedByAllocObjNumber() {\n        //\n        getResultsSortedByClassName(true); // Added because of lines toggling when switching between columns 1 and 2.\n                                           // At first items must be sorted by class names to get defined initial state for\n                                           // other sorting.\n\n        int visibleLines = nInfoLines; // Zero or unprofiled classes are filtered, sorting will be applied only to live\n                                       // data\n                                       //\n\n        nInfoLines = sortResults(nTotalAllocObjects, null, new long[][] { totalAllocObjectsSize }, null, 0, visibleLines, false);\n\n        totalAllocations = 0;\n\n        for (int i = 0; i < nInfoLines; i++) {\n            totalAllocations += nTotalAllocObjects[i];\n        }\n    }\n\n    protected void getResultsSortedByAllocObjSize() {\n        //\n        getResultsSortedByClassName(true); // Added because of lines toggling when switching between columns 1 and 2.\n                                           // At first items must be sorted by class names to get defined initial state\n                                           // for other sorting.\n\n        int visibleLines = nInfoLines; // Zero or unprofiled classes are filtered, sorting will be applied only to live\n                                       // data\n                                       //\n\n        nInfoLines = sortResults(totalAllocObjectsSize, new int[][] { nTotalAllocObjects }, null, null, 0, visibleLines, false);\n\n        totalAllocations = 0;\n\n        for (int i = 0; i < nInfoLines; i++) {\n            totalAllocations += nTotalAllocObjects[i];\n        }\n    }\n\n    protected void getResultsSortedByClassName(boolean presortOnly) {\n        nInfoLines = sortResultsByClassName(new int[][] { nTotalAllocObjects }, new long[][] { totalAllocObjectsSize }, null,\n                                            nTrackedItems, truncateZeroItems());\n\n        if (!presortOnly) {\n            totalAllocations = 0;\n\n            for (int i = 0; i < nInfoLines; i++) {\n                totalAllocations += nTotalAllocObjects[i];\n            }\n        }\n    }\n\n    protected JExtendedTable getResultsTable() {\n        sortResults();\n\n        if (resTable == null) {\n            resTableModel = new ExtendedTableModel(new SortableTableModel() {\n                    public String getColumnName(int col) {\n                        return columnNames[col];\n                    }\n\n                    public int getRowCount() {\n                        return nDisplayedItems;\n                    }\n\n                    public int getColumnCount() {\n                        return columnNames.length;\n                    }\n\n                    public Class<?> getColumnClass(int col) {\n                        return columnTypes[col];\n                    }\n\n                    public Object getValueAt(int row, int col) {\n                        return computeValueAt(row, col);\n                    }\n\n                    public String getColumnToolTipText(int col) {\n                        return columnToolTips[col];\n                    }\n\n                    public void sortByColumn(int column, boolean order) {\n                        sortBy = getSortBy(column);\n                        sortOrder = order;\n\n                        int selectedRow = resTable.getSelectedRow();\n                        String selectedRowContents = null;\n\n                        if (selectedRow != -1) {\n                            selectedRowContents = (String) resTable.getValueAt(selectedRow, 0);\n                        }\n\n                        prepareResults();\n\n                        if (selectedRowContents != null) {\n                            resTable.selectRowByContents(selectedRowContents, 0, true);\n                        }\n                    }\n\n                    /**\n                     * @param column The table column index\n                     * @return Initial sorting for the specified column - if true, ascending, if false descending\n                     */\n                    public boolean getInitialSorting(int column) {\n                        switch (column) {\n                            case 0:\n                                return true;\n                            default:\n                                return false;\n                        }\n                    }\n                });\n\n            resTable = new JExtendedTable(resTableModel) {\n                    public void doLayout() {\n                        int columnsWidthsSum = 0;\n                        int realFirstColumn = -1;\n\n                        int index;\n\n                        for (int i = 0; i < resTableModel.getColumnCount(); i++) {\n                            index = resTableModel.getRealColumn(i);\n\n                            if (index == 0) {\n                                realFirstColumn = i;\n                            } else {\n                                columnsWidthsSum += getColumnModel().getColumn(i).getPreferredWidth();\n                            }\n                        }\n\n                        if (realFirstColumn != -1) {\n                            getColumnModel().getColumn(realFirstColumn)\n                                .setPreferredWidth(Math.max(getWidth() - columnsWidthsSum, minNamesColumnWidth));\n                        }\n\n                        super.doLayout();\n                    }\n\n                };\n            resTable.getAccessibleContext().setAccessibleName(TABLE_ACCESS_NAME);\n\n            resTableModel.setTable(resTable);\n            resTableModel.setInitialSorting(initialSortingColumn, sortOrder);\n            resTable.setRowSelectionAllowed(true);\n            resTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n            resTable.setGridColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);\n            resTable.setSelectionBackground(UIConstants.TABLE_SELECTION_BACKGROUND_COLOR);\n            resTable.setSelectionForeground(UIConstants.TABLE_SELECTION_FOREGROUND_COLOR);\n            resTable.setShowHorizontalLines(UIConstants.SHOW_TABLE_HORIZONTAL_GRID);\n            resTable.setShowVerticalLines(UIConstants.SHOW_TABLE_VERTICAL_GRID);\n            resTable.setRowMargin(UIConstants.TABLE_ROW_MARGIN);\n            resTable.setRowHeight(UIUtils.getDefaultRowHeight() + 2);\n\n            // Disable traversing table cells using TAB and Shift+TAB\n            Set<AWTKeyStroke> keys = new HashSet<>(resTable.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));\n            keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));\n            resTable.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys);\n\n            keys = new HashSet<>(resTable.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));\n            keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));\n            resTable.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys);\n\n            setColumnsData();\n        }\n\n        return resTable;\n    }\n\n    protected Object computeValueAt(int row, int col) {\n        int index = ((Integer) filteredToFullIndexes.get(row)).intValue();\n\n        switch (col) {\n            case 0:\n                return sortedClassNames[index];\n            case 1:\n//                return new Long(totalAllocObjectsSize[index]);\n                return (nTotalBytes == 0) ? 0 : (double)totalAllocObjectsSize[index] / (double)nTotalBytes * 100;\n            case 2:\n                return intFormat.format(totalAllocObjectsSize[index]) + \" B (\" // NOI18N\n                       + ((nTotalBytes == 0) ? \"-%\"\n                                             : // NOI18N\n                percentFormat.format((double) totalAllocObjectsSize[index] / (double) nTotalBytes)) + \")\"; // NOI18N\n            case 3:\n                return intFormat.format(nTotalAllocObjects[index]) + \" (\" // NOI18N\n                       + ((nTotalClasses == 0) ? \"-%\"\n                                               : // NOI18N\n                percentFormat.format((double) nTotalAllocObjects[index] / (double) nTotalClasses)) + \")\"; // NOI18N\n            default:\n                return null;\n        }\n    }\n\n    protected void initColumnSelectorItems() {\n        headerPopup.removeAll();\n\n        JCheckBoxMenuItem menuItem;\n\n        for (int i = 0; i < columnNames.length; i++) {\n            menuItem = new JCheckBoxMenuItem(columnNames[i]);\n            menuItem.setActionCommand(Integer.toString(i));\n            addMenuItemListener(menuItem);\n\n            if (resTable != null) {\n                menuItem.setState(resTableModel.isRealColumnVisible(i));\n\n                if (i == 0) {\n                    menuItem.setEnabled(false);\n                }\n            } else {\n                menuItem.setState(true);\n            }\n\n            headerPopup.add(menuItem);\n        }\n\n        headerPopup.addSeparator();\n\n        JCheckBoxMenuItem filterMenuItem = new JCheckBoxMenuItem(FILTER_MENU_ITEM_NAME);\n        filterMenuItem.setActionCommand(\"Filter\"); // NOI18N\n        addMenuItemListener(filterMenuItem);\n\n        if (filterComponent == null) {\n            filterMenuItem.setState(true);\n        } else {\n            filterMenuItem.setState(filterComponent.getComponent().isVisible());\n        }\n\n        headerPopup.add(filterMenuItem);\n        headerPopup.pack();\n    }\n\n    protected void initColumnsData() {\n        int maxWidth = getFontMetrics(getFont()).charWidth('W') * 13; // NOI18N // initial width of data columns\n        minNamesColumnWidth = getFontMetrics(getFont()).charWidth('W') * 30; // NOI18N\n\n        ClassNameTableCellRenderer classNameTableCellRenderer = new ClassNameTableCellRenderer();\n        LabelBracketTableCellRenderer labelBracketTableCellRenderer = new LabelBracketTableCellRenderer(JLabel.TRAILING);\n\n        columnNames = new String[] { CLASS_COLUMN_NAME, BYTES_REL_COLUMN_NAME, BYTES_COLUMN_NAME, OBJECTS_COLUMN_NAME };\n        columnToolTips = new String[] { CLASS_COLUMN_TOOLTIP, BYTES_REL_COLUMN_TOOLTIP, BYTES_COLUMN_TOOLTIP, OBJECTS_COLUMN_TOOLTIP };\n        columnTypes = new Class[] { String.class, Number.class, String.class, String.class };\n        columnRenderers = new TableCellRenderer[] {\n                              classNameTableCellRenderer, null, labelBracketTableCellRenderer, labelBracketTableCellRenderer\n                          };\n        columnWidths = new int[] { maxWidth + 15, maxWidth, maxWidth };\n    }\n\n    protected boolean passesValueFilter(int i) {\n        return ((((double) totalAllocObjectsSize[i] / (double) nTotalBytes) * 100f) >= valueFilterValue);\n    }\n\n    protected void performDefaultAction(int classId) {\n        showSourceForClass(classId);\n    }\n\n    private void setColumnsData() {\n        barRenderer = getBarCellRenderer();\n\n        TableColumnModel colModel = resTable.getColumnModel();\n        colModel.getColumn(0).setPreferredWidth(minNamesColumnWidth);\n\n        int index;\n\n        for (int i = 0; i < colModel.getColumnCount(); i++) {\n            index = resTableModel.getRealColumn(i);\n\n            if (index == 0) {\n                colModel.getColumn(i).setPreferredWidth(minNamesColumnWidth);\n            } else {\n                colModel.getColumn(i).setPreferredWidth(columnWidths[index - 1]);\n            }\n\n            if (index == 1) {\n                colModel.getColumn(i).setCellRenderer(barRenderer);\n            } else {\n                colModel.getColumn(i).setCellRenderer(columnRenderers[index]);\n            }\n        }\n    }\n\n    private int getSortBy(int column) {\n        switch (column) {\n            case 0:\n                return PresoObjAllocCCTNode.SORT_BY_NAME;\n            case 1:\n                return PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_SIZE;\n            case 2:\n                return PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_SIZE;\n            case 3:\n                return PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_NUMBER;\n        }\n\n        return PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_SIZE;\n    }\n\n    private void addMenuItemListener(JCheckBoxMenuItem menuItem) {\n        menuItem.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    if (e.getActionCommand().equals(\"Filter\")) { // NOI18N\n                        filterComponent.getComponent().setVisible(!filterComponent.getComponent().isVisible());\n\n                        // TODO [ui-persistence]\n                        return;\n                    }\n\n                    saveColumnsData();\n\n                    boolean sortResults = false;\n                    int column = Integer.parseInt(e.getActionCommand());\n                    int sortingColumn = resTableModel.getSortingColumn();\n                    int realSortingColumn = resTableModel.getRealColumn(sortingColumn);\n                    boolean isColumnVisible = resTableModel.isRealColumnVisible(column);\n\n                    // Current sorting column is going to be hidden\n                    if ((isColumnVisible) && (column == realSortingColumn)) {\n                        // Try to set next column as a sortingColumn. If currentSortingColumn is the last column, set previous\n                        // column asa sorting Column (one column is always visible).\n                        sortingColumn = ((sortingColumn + 1) == resTableModel.getColumnCount()) ? (sortingColumn - 1)\n                                                                                                : (sortingColumn + 1);\n                        realSortingColumn = resTableModel.getRealColumn(sortingColumn);\n                        sortResults = true;\n                    }\n\n                    resTableModel.setRealColumnVisibility(column, !isColumnVisible);\n                    resTable.createDefaultColumnsFromModel();\n                    resTableModel.setTable(resTable);\n                    sortingColumn = resTableModel.getVirtualColumn(realSortingColumn);\n\n                    if (sortResults) {\n                        sortOrder = resTableModel.getInitialSorting(sortingColumn);\n                        sortBy = getSortBy(realSortingColumn);\n                        sortResults();\n                        resTable.repaint();\n                    }\n\n                    resTableModel.setInitialSorting(sortingColumn, sortOrder);\n                    resTable.getTableHeader().repaint();\n\n                    setColumnsData();\n\n                    // TODO [ui-persistence]\n                }\n            });\n    }\n\n    private void saveColumnsData() {\n        int index;\n        TableColumnModel colModel = resTable.getColumnModel();\n\n        for (int i = 0; i < resTableModel.getColumnCount(); i++) {\n            index = resTableModel.getRealColumn(i);\n\n            if (index != 0) {\n                columnWidths[index - 1] = colModel.getColumn(i).getPreferredWidth();\n            }\n        }\n    }\n\n    private void sortResults() {\n        // This will sort results and produce sortedClassNames and sortedClassIds\n        switch (sortBy) {\n            case PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_SIZE:\n                getResultsSortedByAllocObjSize();\n\n                break;\n            case PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_NUMBER:\n                getResultsSortedByAllocObjNumber();\n\n                break;\n            case PresoObjAllocCCTNode.SORT_BY_NAME:\n                getResultsSortedByClassName(false);\n\n                break;\n        }\n\n        createFilteredIndexes();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/AllocTableView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.BorderLayout;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.JLabel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.RowFilter;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.AllocMemoryResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.AllocMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.CheckBoxRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class AllocTableView extends MemoryView {\n\n    private MemoryTableModel tableModel;\n    private ProfilerTable table;\n\n    private int nTrackedItems;\n    private ClientUtils.SourceCodeSelection[] classNames;\n    private int[] nTotalAllocObjects;\n    private long[] totalAllocObjectsSize;\n\n    private final Set<ClientUtils.SourceCodeSelection> selection;\n\n    private boolean filterZeroItems = true;\n    \n    \n    AllocTableView(Set<ClientUtils.SourceCodeSelection> selection) {\n        this.selection = selection;\n        \n        initUI();\n    }\n    \n    \n    protected ProfilerTable getResultsComponent() { return table; }\n    \n    \n    private void setData(final int _nTrackedItems, final String[] _classNames,\n                 final int[] _nTotalAllocObjects, final long[] _totalAllocObjectsSize, final boolean diff) {\n        \n        // TODO: show classes with zero instances in live results!\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (tableModel != null) {\n                    nTrackedItems = _nTrackedItems;\n                    classNames = new ClientUtils.SourceCodeSelection[_classNames.length];\n                    for (int i = 0; i < classNames.length; i++)\n                        classNames[i] = new ClientUtils.SourceCodeSelection(_classNames[i], Wildcards.ALLWILDCARD, null);\n                    nTotalAllocObjects = _nTotalAllocObjects;\n                    totalAllocObjectsSize = _totalAllocObjectsSize;\n                    \n                    long totalObjects = 0;\n                    long _totalObjects = 0;\n                    long totalBytes = 0;\n                    long _totalBytes = 0;\n                    \n                    for (int i = 0; i < nTrackedItems; i++) {\n                        if (diff) {\n                            totalObjects = Math.max(totalObjects, nTotalAllocObjects[i]);\n                            _totalObjects = Math.min(_totalObjects, nTotalAllocObjects[i]);\n                            totalBytes = Math.max(totalBytes, totalAllocObjectsSize[i]);\n                            _totalBytes = Math.min(_totalBytes, totalAllocObjectsSize[i]);\n                        } else {\n                            totalObjects += nTotalAllocObjects[i];\n                            totalBytes += totalAllocObjectsSize[i];\n                        }\n                    }\n                    if (diff) {\n                        renderers[0].setMaxValue(Math.max(Math.abs(totalBytes), Math.abs(_totalBytes)));\n                        renderers[1].setMaxValue(Math.max(Math.abs(totalObjects), Math.abs(_totalObjects)));\n                    } else {\n                        renderers[0].setMaxValue(totalBytes);\n                        renderers[1].setMaxValue(totalObjects);\n                    }\n                    \n                    renderers[0].setDiffMode(diff);\n                    renderers[1].setDiffMode(diff);\n                    \n                    tableModel.fireTableDataChanged();\n                }\n            }\n        });\n    }\n    \n    public void setData(MemoryResultsSnapshot snapshot, GenericFilter filter, int aggregation) {\n        AllocMemoryResultsSnapshot _snapshot = (AllocMemoryResultsSnapshot)snapshot;\n        boolean diff = _snapshot instanceof AllocMemoryResultsDiff;\n        \n        String[] _classNames = _snapshot.getClassNames();\n        int[] _nTotalAllocObjects = _snapshot.getObjectsCounts();\n        long[] _totalAllocObjectsSize = _snapshot.getObjectsSizePerClass();\n        \n        int _nTrackedItems = Math.min(_snapshot.getNProfiledClasses(), _classNames.length);\n        _nTrackedItems = Math.min(_nTrackedItems, _nTotalAllocObjects.length);\n        \n        if (filter == null) { // old snapshot\n            filterZeroItems = !diff;\n            \n            setData(_nTrackedItems, _classNames, _nTotalAllocObjects, _totalAllocObjectsSize, diff);\n        } else { // new snapshot or live results\n            filterZeroItems = false;\n            \n            List<String> fClassNames = new ArrayList<>();\n            List<Integer> fTotalAllocObjects = new ArrayList<>();\n            List<Long> fTotalAllocObjectsSize = new ArrayList<>();\n            \n            for (int i = 0; i < _nTrackedItems; i++) {\n                if (filter.passes(_classNames[i].replace('.', '/'))) { // NOI18N\n                    fClassNames.add(_classNames[i]);\n                    fTotalAllocObjects.add(_nTotalAllocObjects[i]);\n                    fTotalAllocObjectsSize.add(_totalAllocObjectsSize[i]);\n                }\n            }\n            \n            int trackedItems = fClassNames.size();\n            String[] aClassNames = fClassNames.toArray(new String[0]);\n            \n            int[] aTotalAllocObjects = new int[trackedItems];\n            for (int i = 0; i < trackedItems; i++) aTotalAllocObjects[i] = fTotalAllocObjects.get(i);\n            \n            long[] aTotalAllocObjectsSize = new long[trackedItems];\n            for (int i = 0; i < trackedItems; i++) aTotalAllocObjectsSize[i] = fTotalAllocObjectsSize.get(i);\n            \n            setData(trackedItems, aClassNames, aTotalAllocObjects, aTotalAllocObjectsSize, diff);\n        }\n    }\n    \n    public void resetData() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                nTrackedItems = 0;\n                classNames = null;\n                nTotalAllocObjects = null;\n                totalAllocObjectsSize = null;\n                \n                renderers[0].setMaxValue(0);\n                renderers[1].setMaxValue(0);\n                renderers[0].setDiffMode(false);\n                renderers[1].setDiffMode(false);\n                \n                tableModel.fireTableDataChanged();\n            }\n        });\n    }\n    \n    \n    public void showSelectionColumn() {\n        table.setColumnVisibility(0, true);\n    }\n    \n    public void refreshSelection() {\n        tableModel.fireTableDataChanged();\n    }\n    \n    \n    public ExportUtils.ExportProvider[] getExportProviders() {\n        return table.getRowCount() == 0 ? null : new ExportUtils.ExportProvider[] {\n            new ExportUtils.CSVExportProvider(table),\n            new ExportUtils.HTMLExportProvider(table, EXPORT_ALLOCATED),\n            new ExportUtils.XMLExportProvider(table, EXPORT_ALLOCATED),\n            new ExportUtils.PNGExportProvider(table)\n        };\n    }\n    \n    \n    protected abstract void performDefaultAction(ClientUtils.SourceCodeSelection userValue);\n    \n    protected abstract void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue);\n    \n    protected void popupShowing() {}\n    \n    protected void popupHidden()  {}\n    \n    \n    private HideableBarRenderer[] renderers;\n    \n    HideableBarRenderer.BarDiffMode barDiffMode() {\n        return HideableBarRenderer.BarDiffMode.MODE_BAR_DIFF;\n    }\n    \n    private void initUI() {\n        final int offset = selection == null ? -1 : 0;\n        \n        tableModel = new MemoryTableModel();\n        \n        table = new ProfilerTable(tableModel, true, true, null) {\n            public ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n                return AllocTableView.this.getUserValueForRow(row);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                AllocTableView.this.populatePopup(popup, value, (ClientUtils.SourceCodeSelection)userValue);\n            }\n            protected void popupShowing() {\n                AllocTableView.this.popupShowing();\n            }\n            protected void popupHidden() {\n                AllocTableView.this.popupHidden();\n            }\n        };\n        \n        table.setColumnToolTips(selection == null ? new String[] {\n                                  NAME_COLUMN_TOOLTIP,\n                                  ALLOC_SIZE_COLUMN_TOOLTIP,\n                                  ALLOC_COUNT_COLUMN_TOOLTIP\n                                } : new String[] {\n                                  SELECTED_COLUMN_TOOLTIP,\n                                  NAME_COLUMN_TOOLTIP,\n                                  ALLOC_SIZE_COLUMN_TOOLTIP,\n                                  ALLOC_COUNT_COLUMN_TOOLTIP\n                                });\n        \n        table.providePopupMenu(true);\n        installDefaultAction();\n        \n        table.setMainColumn(1 + offset);\n        table.setFitWidthColumn(1 + offset);\n        \n        table.setSortColumn(2 + offset);\n        table.setDefaultSortOrder(1 + offset, SortOrder.ASCENDING);\n        \n        if (selection != null) table.setColumnVisibility(0, false);\n        \n        // Filter out classes with no instances\n        table.addRowFilter(new RowFilter() {\n            public boolean include(RowFilter.Entry entry) {\n                return !filterZeroItems || ((Number)entry.getValue(3 + offset)).intValue() > 0;\n            }\n        });\n        \n        renderers = new HideableBarRenderer[2];\n        \n        HideableBarRenderer.BarDiffMode barDiffMode = barDiffMode();\n        renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(Formatters.bytesFormat()));\n        renderers[0].setBarDiffMode(barDiffMode);\n        renderers[1] = new HideableBarRenderer(new NumberPercentRenderer());\n        renderers[1].setBarDiffMode(barDiffMode);\n        \n        renderers[0].setMaxValue(123456789);\n        renderers[1].setMaxValue(12345678);\n        \n        if (selection != null) table.setColumnRenderer(0, new CheckBoxRenderer());\n        table.setColumnRenderer(1 + offset, new JavaNameRenderer(Icons.getIcon(LanguageIcons.CLASS)));\n        table.setColumnRenderer(2 + offset, renderers[0]);\n        table.setColumnRenderer(3 + offset, renderers[1]);\n        \n        if (selection != null) {\n            int w = new JLabel(table.getColumnName(0)).getPreferredSize().width;\n            table.setDefaultColumnWidth(0, w + 15);\n        }\n        table.setDefaultColumnWidth(2 + offset, renderers[0].getOptimalWidth());\n        table.setDefaultColumnWidth(3 + offset, renderers[1].getMaxNoBarWidth());\n        \n        ProfilerTableContainer tableContainer = new ProfilerTableContainer(table, false, null);\n        \n        setLayout(new BorderLayout());\n        add(tableContainer, BorderLayout.CENTER);\n    }\n    \n    \n    protected ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n        if (nTrackedItems == 0 || row == -1) return null;\n        if (row >= tableModel.getRowCount()) return null; // #239936\n        return classNames[table.convertRowIndexToModel(row)];\n    }\n    \n    \n    private class MemoryTableModel extends AbstractTableModel {\n        \n        public String getColumnName(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return COLUMN_NAME;\n            } else if (columnIndex == 2) {\n                return COLUMN_ALLOCATED_BYTES;\n            } else if (columnIndex == 3) {\n                return COLUMN_ALLOCATED_OBJECTS;\n            } else if (columnIndex == 0) {\n                return COLUMN_SELECTED;\n            }\n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return String.class;\n            } else if (columnIndex == 2) {\n                return Long.class;\n            } else if (columnIndex == 3) {\n                return Integer.class;\n            } else if (columnIndex == 0) {\n                return Boolean.class;\n            }\n            return null;\n        }\n\n        public int getRowCount() {\n            return nTrackedItems;\n        }\n\n        public int getColumnCount() {\n            return selection == null ? 3 : 4;\n        }\n\n        public Object getValueAt(int rowIndex, int columnIndex) {\n            if (nTrackedItems == 0) return null;\n            \n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return classNames[rowIndex].getClassName();\n            } else if (columnIndex == 2) {\n                return totalAllocObjectsSize[rowIndex];\n            } else if (columnIndex == 3) {\n                return nTotalAllocObjects[rowIndex];\n            } else if (columnIndex == 0) {\n                if (selection.isEmpty()) return Boolean.FALSE;\n                return selection.contains(classNames[rowIndex]);\n            }\n\n            return null;\n        }\n\n        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 0) {\n                if (Boolean.FALSE.equals(aValue)) selection.remove(classNames[rowIndex]);\n                else selection.add(classNames[rowIndex]);\n            }\n        }\n\n        public boolean isCellEditable(int rowIndex, int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            return columnIndex == 0;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/AllocTreeTableView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Graphics;\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.swing.AbstractAction;\nimport javax.swing.Box;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JLabel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JTree;\nimport javax.swing.RowFilter;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.tree.TreeNode;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.AllocMemoryResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.AllocMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCCTManager;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.CheckBoxRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class AllocTreeTableView extends MemoryView {\n    \n    private AllocTreeTableModel treeTableModel;\n    private ProfilerTreeTable treeTable;\n    \n    private Map<TreeNode, ClientUtils.SourceCodeSelection> nodesMap;\n    private final Set<ClientUtils.SourceCodeSelection> selection;\n    \n    private boolean filterObjects = true;\n    private boolean filterAllocations = false;\n    private boolean searchObjects = true;\n    private boolean searchAllocations = false;\n    \n    \n    AllocTreeTableView(Set<ClientUtils.SourceCodeSelection> selection) {\n        this.selection = selection;\n        \n        initUI();\n    }\n    \n    \n    protected RowFilter getExcludesFilter() {\n        return new RowFilter() { // Do not filter first level nodes\n            public boolean include(RowFilter.Entry entry) {\n                PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)entry.getIdentifier();\n                CCTNode parent = node.getParent();\n                if (parent == null) return true;\n                if (parent.getParent() == null) return !filterObjects;\n                return !filterAllocations;\n            }\n        };\n    }\n    \n    protected Component[] getFilterOptions() {\n        PopupButton pb = new PopupButton (Icons.getIcon(ProfilerIcons.TAB_CALL_TREE)) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new JCheckBoxMenuItem(FILTER_CLASSES_SCOPE, filterObjects) {\n                    {\n                        if (!filterAllocations) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterObjects = !filterObjects;\n                        enableFilter();\n                    }\n                });\n                popup.add(new JCheckBoxMenuItem(FILTER_ALLOCATIONS_SCOPE, filterAllocations) {\n                    {\n                        if (!filterObjects) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterAllocations = !filterAllocations;\n                        enableFilter();\n                    }\n                });\n            }\n        };\n        pb.setToolTipText(FILTER_SCOPE_TOOLTIP);\n        return new Component[] { Box.createHorizontalStrut(5), pb };\n    }\n    \n    protected SearchUtils.TreeHelper getSearchHelper() {\n        return new SearchUtils.TreeHelper() {\n            public int getNodeType(TreeNode tnode) {\n                PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)tnode;\n                CCTNode parent = node.getParent();\n                if (parent == null) return SearchUtils.TreeHelper.NODE_SKIP_DOWN; // invisible root\n                \n                if (parent.getParent() == null) {\n                    if (searchObjects) {\n                        return searchAllocations ? SearchUtils.TreeHelper.NODE_SEARCH_DOWN :\n                                                   SearchUtils.TreeHelper.NODE_SEARCH_NEXT;\n                    } else {\n                        return searchAllocations ? SearchUtils.TreeHelper.NODE_SKIP_DOWN :\n                                                   SearchUtils.TreeHelper.NODE_SKIP_NEXT;\n                    }\n                }\n                \n                return searchAllocations ? SearchUtils.TreeHelper.NODE_SEARCH_DOWN :\n                                           SearchUtils.TreeHelper.NODE_SKIP_NEXT;\n            }\n        };\n    }\n    \n    protected Component[] getSearchOptions() {\n        PopupButton pb = new PopupButton (Icons.getIcon(ProfilerIcons.TAB_CALL_TREE)) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new JCheckBoxMenuItem(SEARCH_CLASSES_SCOPE, searchObjects) {\n                    {\n                        if (!searchAllocations) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        searchObjects = !searchObjects;\n                    }\n                });\n                popup.add(new JCheckBoxMenuItem(SEARCH_ALLOCATIONS_SCOPE, searchAllocations) {\n                    {\n                        if (!searchObjects) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        searchAllocations = !searchAllocations;\n                    }\n                });\n            }\n        };\n        pb.setToolTipText(SEARCH_SCOPE_TOOLTIP);\n        return new Component[] { Box.createHorizontalStrut(5), pb };\n    }\n    \n    protected ProfilerTable getResultsComponent() { return treeTable; }\n    \n    \n    public void setData(MemoryResultsSnapshot snapshot, GenericFilter filter, int aggregation) {\n        final boolean includeEmpty = filter != null;\n        final boolean diff = snapshot instanceof AllocMemoryResultsDiff;\n        final AllocMemoryResultsSnapshot _snapshot = (AllocMemoryResultsSnapshot)snapshot;\n        \n        String[] _classNames = _snapshot.getClassNames();\n        int[] _nTotalAllocObjects = _snapshot.getObjectsCounts();\n        long[] _totalAllocObjectsSize = _snapshot.getObjectsSizePerClass();\n        \n        int _nTrackedItems = Math.min(_snapshot.getNProfiledClasses(), _classNames.length);\n        _nTrackedItems = Math.min(_nTrackedItems, _nTotalAllocObjects.length);\n        \n        List<PresoObjAllocCCTNode> nodes = new ArrayList<>();\n        final Map<TreeNode, ClientUtils.SourceCodeSelection> _nodesMap = new HashMap<>();\n        \n        long totalObjects = 0;\n        long _totalObjects = 0;\n        long totalBytes = 0;\n        long _totalBytes = 0;\n        \n        for (int i = 0; i < _nTrackedItems; i++) {\n            if (diff) {\n                totalObjects = Math.max(totalObjects, _nTotalAllocObjects[i]);\n                _totalObjects = Math.min(_totalObjects, _nTotalAllocObjects[i]);\n                totalBytes = Math.max(totalBytes, _totalAllocObjectsSize[i]);\n                _totalBytes = Math.min(_totalBytes, _totalAllocObjectsSize[i]);\n            } else {\n                totalObjects += _nTotalAllocObjects[i];\n                totalBytes += _totalAllocObjectsSize[i];\n            }\n            \n            final int _i = i;\n            \n            class Node extends PresoObjAllocCCTNode {\n                Node(String className, int nTotalAllocObjects, long totalAllocObjectsSize) {\n                    super(className, nTotalAllocObjects, totalAllocObjectsSize);\n                }\n                public CCTNode[] getChildren() {\n                    if (children == null) {\n                        MemoryCCTManager callGraphManager = new MemoryCCTManager(_snapshot, _i, true);\n                        PresoObjAllocCCTNode root = callGraphManager.getRootNode();\n                        setChildren(root == null ? new PresoObjAllocCCTNode[0] :\n                                    (PresoObjAllocCCTNode[])root.getChildren());\n                    }\n                    return children;\n                }\n                public boolean isLeaf() {\n                    if (children == null) return includeEmpty && nCalls == 0;\n                    else return super.isLeaf();\n                }   \n                public int getChildCount() {\n                    if (children == null) getChildren();\n                    return super.getChildCount();\n                }\n            }\n            \n            if (!includeEmpty) { // old snapshot\n                if (_nTotalAllocObjects[i] > 0) {\n                    PresoObjAllocCCTNode node = new Node(_classNames[i], _nTotalAllocObjects[i], _totalAllocObjectsSize[i]);\n                    nodes.add(node);\n                    _nodesMap.put(node, new ClientUtils.SourceCodeSelection(_classNames[i], Wildcards.ALLWILDCARD, null));\n                }\n            } else if (filter.passes(_classNames[i].replace('.', '/'))) { // NOI18N\n                PresoObjAllocCCTNode node = new Node(_classNames[i], _nTotalAllocObjects[i], _totalAllocObjectsSize[i]);\n                nodes.add(node);\n                _nodesMap.put(node, new ClientUtils.SourceCodeSelection(_classNames[i], Wildcards.ALLWILDCARD, null));\n            }\n        }\n        \n        final long __totalBytes = !diff ? totalBytes :\n                Math.max(Math.abs(totalBytes), Math.abs(_totalBytes));\n        final long __totalObjects = !diff ? totalObjects :\n                Math.max(Math.abs(totalObjects), Math.abs(_totalObjects));\n        final PresoObjAllocCCTNode root = PresoObjAllocCCTNode.rootNode(nodes.toArray(new PresoObjAllocCCTNode[0]));\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                nodesMap = _nodesMap;\n                renderers[0].setMaxValue(__totalBytes);\n                renderers[1].setMaxValue(__totalObjects);\n                renderers[0].setDiffMode(diff);\n                renderers[1].setDiffMode(diff);\n                treeTableModel.setRoot(root);\n            }\n        });\n    }\n    \n    public void resetData() {\n        final PresoObjAllocCCTNode root = PresoObjAllocCCTNode.rootNode(new PresoObjAllocCCTNode[0]);\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                nodesMap = null;\n                \n                renderers[0].setMaxValue(0);\n                renderers[1].setMaxValue(0);\n                renderers[0].setDiffMode(false);\n                renderers[1].setDiffMode(false);\n                \n                treeTableModel.setRoot(root);\n            }\n        });\n    }\n    \n    \n    public void showSelectionColumn() {\n        treeTable.setColumnVisibility(0, true);\n    }\n    \n    public void refreshSelection() {\n        treeTableModel.dataChanged();\n    }\n    \n    \n    public ExportUtils.ExportProvider[] getExportProviders() {\n        return treeTable.getRowCount() == 0 ? null : new ExportUtils.ExportProvider[] {\n            new ExportUtils.CSVExportProvider(treeTable),\n            new ExportUtils.HTMLExportProvider(treeTable, EXPORT_ALLOCATED),\n            new ExportUtils.XMLExportProvider(treeTable, EXPORT_ALLOCATED),\n            new ExportUtils.PNGExportProvider(treeTable)\n        };\n    }\n    \n    \n    protected abstract void performDefaultAction(ClientUtils.SourceCodeSelection userValue);\n    \n    protected abstract void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue);\n    \n    protected void popupShowing() {}\n    \n    protected void popupHidden()  {}\n    \n    \n    private HideableBarRenderer[] renderers;\n    \n    HideableBarRenderer.BarDiffMode barDiffMode() {\n        return HideableBarRenderer.BarDiffMode.MODE_BAR_DIFF;\n    }\n    \n    private void initUI() {\n        final int offset = selection == null ? -1 : 0;\n        \n        treeTableModel = new AllocTreeTableModel(PrestimeCPUCCTNode.EMPTY);\n        \n        treeTable = new ProfilerTreeTable(treeTableModel, true, true, new int[] { 1 + offset }) {\n            public ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n                return AllocTreeTableView.this.getUserValueForRow(row);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                AllocTreeTableView.this.populatePopup(popup, value, (ClientUtils.SourceCodeSelection)userValue);\n            }\n            protected void popupShowing() {\n                AllocTreeTableView.this.popupShowing();\n            }\n            protected void popupHidden() {\n                AllocTreeTableView.this.popupHidden();\n            }\n        };\n        \n        treeTable.setColumnToolTips(selection == null ? new String[] {\n                                        NAME_COLUMN_TOOLTIP,\n                                        ALLOC_SIZE_COLUMN_TOOLTIP,\n                                        ALLOC_COUNT_COLUMN_TOOLTIP\n                                      } : new String[] {\n                                        SELECTED_COLUMN_TOOLTIP,\n                                        NAME_COLUMN_TOOLTIP,\n                                        ALLOC_SIZE_COLUMN_TOOLTIP,\n                                        ALLOC_COUNT_COLUMN_TOOLTIP\n                                      });\n        \n        treeTable.providePopupMenu(true);\n        treeTable.setDefaultAction(new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                int row = treeTable.getSelectedRow();\n                ClientUtils.SourceCodeSelection userValue = getUserValueForRow(row);\n                if (userValue != null) performDefaultAction(userValue);\n            }\n        });\n        \n        treeTable.setRootVisible(false);\n        treeTable.setShowsRootHandles(true);\n        treeTable.makeTreeAutoExpandable(2);\n        \n        treeTable.setMainColumn(1 + offset);\n        treeTable.setFitWidthColumn(1 + offset);\n        \n        treeTable.setSortColumn(2 + offset);\n        treeTable.setDefaultSortOrder(1 + offset, SortOrder.ASCENDING);\n        \n        if (selection != null) treeTable.setColumnVisibility(0, false);\n        \n        renderers = new HideableBarRenderer[2];\n        \n        HideableBarRenderer.BarDiffMode barDiffMode = barDiffMode();\n        renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(Formatters.bytesFormat()));\n        renderers[0].setBarDiffMode(barDiffMode);\n        renderers[1] = new HideableBarRenderer(new NumberPercentRenderer());\n        renderers[1].setBarDiffMode(barDiffMode);\n        \n        renderers[0].setMaxValue(123456789);\n        renderers[1].setMaxValue(12345678);\n        \n        if (selection != null) treeTable.setColumnRenderer(0, new CheckBoxRenderer() {\n            private boolean visible;\n            public void setValue(Object value, int row) {\n                TreePath path = treeTable.getPathForRow(row);\n                visible = nodesMap.containsKey((TreeNode)path.getLastPathComponent());\n                if (visible) super.setValue(value, row);\n            }\n            public void paint(Graphics g) {\n                if (visible) {\n                    super.paint(g);\n                } else {\n                    g.setColor(getBackground());\n                    g.fillRect(0, 0, size.width, size.height);\n                }\n            }\n        });\n        treeTable.setTreeCellRenderer(new MemoryJavaNameRenderer());\n        treeTable.setColumnRenderer(2 + offset, renderers[0]);\n        treeTable.setColumnRenderer(3 + offset, renderers[1]);\n        \n        if (selection != null) {\n            int w = new JLabel(treeTable.getColumnName(0)).getPreferredSize().width;\n            treeTable.setDefaultColumnWidth(0, w + 15);\n        }\n        treeTable.setDefaultColumnWidth(2 + offset, renderers[0].getOptimalWidth());\n        treeTable.setDefaultColumnWidth(3 + offset, renderers[1].getMaxNoBarWidth());\n        \n        ProfilerTableContainer tableContainer = new ProfilerTableContainer(treeTable, false, null);\n        \n        setLayout(new BorderLayout());\n        add(tableContainer, BorderLayout.CENTER);\n    }\n    \n    protected ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n        PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)treeTable.getValueForRow(row);\n        if (node == null || node.isFiltered()) return null;\n        String[] name = node.getMethodClassNameAndSig();\n        return new ClientUtils.SourceCodeSelection(name[0], name[1], name[2]);\n    }\n    \n    \n    private class AllocTreeTableModel extends ProfilerTreeTableModel.Abstract {\n        \n        AllocTreeTableModel(TreeNode root) {\n            super(root);\n        }\n        \n        public String getColumnName(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return COLUMN_NAME;\n            } else if (columnIndex == 2) {\n                return COLUMN_ALLOCATED_BYTES;\n            } else if (columnIndex == 3) {\n                return COLUMN_ALLOCATED_OBJECTS;\n            } else if (columnIndex == 0) {\n                return COLUMN_SELECTED;\n            }\n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return JTree.class;\n            } else if (columnIndex == 2) {\n                return Long.class;\n            } else if (columnIndex == 3) {\n                return Integer.class;\n            } else if (columnIndex == 0) {\n                return Boolean.class;\n            }\n            return null;\n        }\n\n        public int getColumnCount() {\n            return selection == null ? 3 : 4;\n        }\n\n        public Object getValueAt(TreeNode node, int columnIndex) {\n            PresoObjAllocCCTNode allocNode = (PresoObjAllocCCTNode)node;\n            \n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return allocNode.getNodeName();\n            } else if (columnIndex == 2) {\n                return allocNode.totalObjSize;\n            } else if (columnIndex == 3) {\n                return allocNode.nCalls;\n            } else if (columnIndex == 0) {\n                if (selection.isEmpty()) return Boolean.FALSE;\n                return selection.contains(nodesMap.get(node));\n            }\n\n            return null;\n        }\n        \n        public void setValueAt(Object aValue, TreeNode node, int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 0) {\n                if (Boolean.TRUE.equals(aValue)) selection.add(nodesMap.get(node));\n                else selection.remove(nodesMap.get(node));\n            }\n        }\n\n        public boolean isCellEditable(TreeNode node, int columnIndex) {\n            if (selection == null) columnIndex++;\n            if (columnIndex != 0) return false;\n            return (nodesMap.containsKey(node));\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nSampledResultsPanel_FilterMenuItemName=Filter\nSampledResultsPanel_GoSourcePopupItemName=Go To Source\nSampledResultsPanel_ClassColumnName=Class Name - Live Objects\nSampledResultsPanel_BytesRelColumnName=Live Bytes [%]\nSampledResultsPanel_BytesColumnName=Live Bytes\nSampledResultsPanel_ObjectsColumnName=Live Objects\nSampledResultsPanel_ClassColumnToolTip=Class Name - Live Objects\nSampledResultsPanel_BytesRelColumnToolTip=Memory size in bytes occupied by live instances of this class [%]\nSampledResultsPanel_BytesColumnToolTip=Memory size in bytes occupied by live instances of this class\nSampledResultsPanel_ObjectsColumnToolTip=Number of live instances of this class\nSampledResultsPanel_TableAccessName=Table with collected profiling results.\n\nAllocResultsPanel_FilterMenuItemName=Filter\nAllocResultsPanel_GoSourcePopupItemName=Go To Source\nAllocResultsPanel_ShowStackTracesPopupItemName=Show Allocation Stack Traces\nAllocResultsPanel_LiveShowStackTracesPopupItemName=Take Snapshot and Show Allocation Stack Traces\nAllocResultsPanel_ClassColumnName=Class Name - Allocated Objects\nAllocResultsPanel_BytesRelColumnName=Bytes Allocated [%]\nAllocResultsPanel_BytesColumnName=Bytes Allocated\nAllocResultsPanel_ObjectsColumnName=Objects Allocated\nAllocResultsPanel_ClassColumnToolTip=Class Name - Allocated Objects\nAllocResultsPanel_BytesRelColumnToolTip=Memory size in bytes occupied by instances of this class [%]\nAllocResultsPanel_BytesColumnToolTip=Memory size in bytes occupied by instances of this class\nAllocResultsPanel_ObjectsColumnToolTip=Number of instances of this class\nAllocResultsPanel_TableAccessName=Table with collected profiling results.\n\nLiveLivenessResultsPanel_GoSourcePopupItemName=Go To Source\nLiveLivenessResultsPanel_StopClassPopupItemName=Stop Profiling this Class\nLiveLivenessResultsPanel_StopBelowLinePopupItemName=Stop Profiling Classes below this Line\nLiveLivenessResultsPanel_StopClassSpecPopupItemName=Stop profiling class {0}\nLiveLivenessResultsPanel_StopBelowLineSpecPopupItemName=Stop profiling classes below class {0}\n\nLiveReverseMemCallGraphPanel_NoStacksMsg=No stack traces are available\nLiveReverseMemCallGraphPanel_TreeTableAccessName=Treetable with collected profiling results.\n\nLivenessResultsPanel_FilterMenuItemName=Filter\nLivenessResultsPanel_ClassColumnName=Class Name - Live Allocated Objects\nLivenessResultsPanel_LiveBytesRelColumnName=Live Bytes [%]\nLivenessResultsPanel_LiveBytesColumnName=Live Bytes\nLivenessResultsPanel_LiveObjectsColumnName=Live Objects\nLivenessResultsPanel_AllocObjectsColumnName=Allocated Objects\nLivenessResultsPanel_AvgAgeColumnName=Avg. Age\nLivenessResultsPanel_SurvGenColumnName=Generations\nLivenessResultsPanel_TotalAllocObjectsColumnName=Total Alloc. Obj.\nLivenessResultsPanel_ClassColumnToolTip=Class Name - Live Allocated Objects\nLivenessResultsPanel_LiveBytesRelColumnToolTip=Memory size in bytes currently occupied by live instances of this class [%]\nLivenessResultsPanel_LiveBytesColumnToolTip=Memory size in bytes currently occupied by live instances of this class\nLivenessResultsPanel_LiveObjectsColumnToolTip=Number of current live instances of this class\nLivenessResultsPanel_AllocObjectsColumnToolTip=Number of all instances of this class created since the Application start or last Results reset, allocated from this method\nLivenessResultsPanel_AvgAgeColumnToolTip=Average Age in generations of live instances of this class\nLivenessResultsPanel_SurvGenColumnToolTip=Number of different generations (garbage collections survived) of live instances of this class\nLivenessResultsPanel_TotalAllocObjectsColumnToolTip=Total number of allocated instances of this class\nLivenessResultsPanel_TableAccessName=Table with collected profiling results.\n\nMemoryResultsPanel_ClassNameFilterHint=Class Name Filter\nMemoryResultsPanel_MethodNameFilterHint=Method Name Filter\n\nMemoryResUserActionsHandler_CannotShowPrimitiveSrcMsg=Cannot show source for primitive array.\nMemoryResUserActionsHandler_CannotShowReflectionSrcMsg=Cannot show source for objects allocated by reflection.\n\nReverseMemCallGraphPanel_MethodColumnName=Method Name - Allocation Call Tree\nReverseMemCallGraphPanel_LiveBytesRelColumnName=Live Bytes [%]\nReverseMemCallGraphPanel_LiveBytesColumnName=Live Bytes\nReverseMemCallGraphPanel_LiveObjectsColumnName=Live Objects\nReverseMemCallGraphPanel_AllocObjectsColumnName=Allocated Objects\nReverseMemCallGraphPanel_AvgAgeColumnName=Avg. Age\nReverseMemCallGraphPanel_SurvGenColumnName=Generations\nReverseMemCallGraphPanel_MethodColumnToolTip=Method Name - Reverse allocation stack trace containing methods calls that lead to the object allocation\nReverseMemCallGraphPanel_LiveBytesRelColumnToolTip=Memory size in bytes currently occupied by live instances of this class allocated from this method [%]\nReverseMemCallGraphPanel_LiveBytesColumnToolTip=Memory size in bytes currently occupied by live instances of this class allocated from this method\nReverseMemCallGraphPanel_LiveObjectsColumnToolTip=Number of current live instances of this class allocated from this method\nReverseMemCallGraphPanel_AllocObjectsColumnToolTip=Number of all instances of this class created since the Application start or last Results reset, allocated from this method\nReverseMemCallGraphPanel_AvgAgeColumnToolTip=Average Age in generations of live instances of this class allocated from this method\nReverseMemCallGraphPanel_SurvGenColumnToolTip=Number of different generations (garbage collections survived) of live instances of this class allocated from this method\nReverseMemCallGraphPanel_BytesAllocRelColumnName=Bytes Allocated [%]\nReverseMemCallGraphPanel_BytesAllocColumnName=Bytes Allocated\nReverseMemCallGraphPanel_ObjectsAllocColumnName=Objects Allocated\nReverseMemCallGraphPanel_BytesAllocRelColumnToolTip=Memory size in bytes of instances of this class allocated from this method\nReverseMemCallGraphPanel_BytesAllocColumnToolTip=Memory size in bytes of instances of this class allocated from this method\nReverseMemCallGraphPanel_ObjectsAllocColumnToolTip=Number of instances of this class allocated from this method\nReverseMemCallGraphPanel_GoSourcePopupItem=Go To Source\n\nSnapshotLivenessResultsPanel_GoSourcePopupItem=Go To Source\nSnapshotLivenessResultsPanel_StackTracesPopupItem=Show Allocations Stack Traces\n\nSnapshotReverseMemCallGraphPanel_NoStackTracesMsg=Please select an item in Memory Results tab and choose \\\"Show Allocation Stack Traces\\\" in its context menu to show allocation stack traces. \nSnapshotReverseMemCallGraphPanel_TreeTableAccessName=Treetable with collected profiling results.\nSnapshotReverseMemCallGraphPanel_ExportAddedColumnName=Parent Node\n\nLiveResultsPanel_LogClassHistory=Log Class History\n\nMemoryView_ExportTooltip=Export data to file or image\nMemoryView_ExportObjects=Export Objects\nMemoryView_ExportLive=Live Objects\nMemoryView_ExportAllocated=Allocated Objects\nMemoryView_ExportAllocatedLive=Allocated and Live Objects\nMemoryView_ColumnName=Name\nMemoryView_ColumnAllocatedBytes=Allocated Bytes\nMemoryView_ColumnAllocatedObjects=Allocated Objects\nMemoryView_ColumnLiveBytes=Live Bytes\nMemoryView_ColumnLiveObjects=Live Objects\nMemoryView_ColumnTotalAllocatedObjects=Total Alloc. Obj.\nMemoryView_ColumnAvgAge=Avg. Age\nMemoryView_ColumnGenerations=Generations\nMemoryView_ColumnSelected=Selected\nMemoryView_ActionGoToSource=Go to Source\nMemoryView_ActionProfileMethod=Profile Method\nMemoryView_ActionProfileClass=Profile Class\nMemoryView_SelectedColumnTooltip=Selected for focused (instrumented) profiling\nMemoryView_NameColumnTooltip=Class name\nMemoryView_LiveSizeColumnTooltip=Size of live instances\nMemoryView_LiveCountColumnTooltip=Number of live instances\nMemoryView_AllocSizeColumnTooltip=Size of all allocated instances\nMemoryView_AllocCountColumnTooltip=Number of all allocated instances\nMemoryView_TotalAllocCountColumnTooltip=Total number of all allocated instances\nMemoryView_AvgAgeColumnTooltip=Average age in generations of live instances\nMemoryView_GenerationsColumnTooltip=Number of generations (garbage collections survived) of live instances\nMemoryView_FilterClassesScope=Filter Classes\nMemoryView_FilterAllocationsScope=Filter Allocations\nMemoryView_FilterScopeTooltip=Filter scope\nMemoryView_SearchClassesScope=Search Classes\nMemoryView_SearchAllocationsScope=Search Allocations\nMemoryView_SearchScopeTooltip=Search scope\nMemoryView_ExpandMenu=Expand / Collapse\nMemoryView_ExpandPlainItem=Expand Plain Path\nMemoryView_ExpandTopmostItem=Expand Topmost Path\nMemoryView_CollapseChildrenItem=Collapse Children\nMemoryView_CollapseAllItem=Collapse All\n\nSnapshotMemoryView_ToolbarAggregation=Aggregation\\:\nSnapshotMemoryView_AggregationClasses=Classes\nSnapshotMemoryView_AggregationPackages=Packages\nSnapshotMemoryView_CompareSnapshots=Compare with another snapshot...\nSnapshotMemoryView_ResetCompareSnapshots=Reset snapshots comparison\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/ClassHistoryActionsHandler.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\n/**\n * Handler for the Class History live results view.\n *\n * @author Jiri Sedlacek\n */\npublic interface ClassHistoryActionsHandler {\n\n    // The implementation notifies the user that previous history tracking\n    // will be reset and ensures that the history graph is visible.\n    public void showClassHistory(int classID, String className);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/ClassHistoryModels.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\nimport org.graalvm.visualvm.lib.jfluid.results.DataManagerListener;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.ClassHistoryDataManager;\nimport org.graalvm.visualvm.lib.ui.graphs.GraphsUI;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ClassHistoryModels {\n\n    // --- Instance variables --------------------------------------------------\n\n    private final ClassHistoryDataManager dataManager;\n\n    private final Timeline timeline;\n    private final SynchronousXYItemsModel allocationsItemsModel;\n    private final SynchronousXYItemsModel livenessItemsModel;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    public ClassHistoryModels(ClassHistoryDataManager dataManager) {\n        this.dataManager = dataManager;\n\n        timeline = createTimeline();\n        allocationsItemsModel = createAllocationsItemsModel(timeline);\n        livenessItemsModel = createLivenessItemsModel(timeline);\n\n        dataManager.addDataListener(new DataManagerListener() {\n            public void dataChanged() { dataChangedImpl(); }\n            public void dataReset() { dataResetImpl(); }\n        });\n    }\n\n\n    // --- Public interface ----------------------------------------------------\n\n    public ClassHistoryDataManager getDataManager() {\n        return dataManager;\n    }\n\n    public SynchronousXYItemsModel allocationsItemsModel() {\n        return allocationsItemsModel;\n    }\n\n    public SynchronousXYItemsModel livenessItemsModel() {\n        return livenessItemsModel;\n    }\n\n\n    // --- DataManagerListener implementation ----------------------------------\n\n    private void dataChangedImpl() {\n        allocationsItemsModel.valuesAdded();\n        livenessItemsModel.valuesAdded();\n    }\n\n    private void dataResetImpl() {\n        allocationsItemsModel.valuesReset();\n        livenessItemsModel.valuesReset();\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private Timeline createTimeline() {\n        return new Timeline() {\n            public int getTimestampsCount() { return dataManager.getItemCount(); }\n            public long getTimestamp(int index) { return dataManager.timeStamps[index]; }\n        };\n    }\n\n    private SynchronousXYItemsModel createAllocationsItemsModel(Timeline timeline) {\n        // Objects Allocated\n        SynchronousXYItem allocObjectsItem = new SynchronousXYItem(GraphsUI.A_ALLOC_OBJECTS_NAME, 0) {\n            public long getYValue(int index) {\n                return dataManager.nTotalAllocObjects[index];\n            }\n        };\n        allocObjectsItem.setInitialBounds(new LongRect(0, 0, 0, GraphsUI.A_ALLOC_OBJECTS_INITIAL_VALUE));\n\n        // Bytes Allocated\n        SynchronousXYItem allocBytesItem = new SynchronousXYItem(GraphsUI.A_ALLOC_BYTES_NAME, 0) {\n            public long getYValue(int index) {\n                return dataManager.totalAllocObjectsSize[index];\n            }\n        };\n        allocBytesItem.setInitialBounds(new LongRect(0, 0, 0, GraphsUI.A_ALLOC_BYTES_INITIAL_VALUE));\n\n        // Model\n        SynchronousXYItemsModel model = new SynchronousXYItemsModel(timeline,\n                           new SynchronousXYItem[] { allocObjectsItem, allocBytesItem });\n\n        return model;\n    }\n\n    private SynchronousXYItemsModel createLivenessItemsModel(Timeline timeline) {\n        // Live Objects\n        SynchronousXYItem liveObjectsItem = new SynchronousXYItem(GraphsUI.L_LIVE_OBJECTS_NAME, 0) {\n            public long getYValue(int index) {\n                return dataManager.nTrackedLiveObjects[index];\n            }\n        };\n        liveObjectsItem.setInitialBounds(new LongRect(0, 0, 0, GraphsUI.L_LIVE_OBJECTS_INITIAL_VALUE));\n\n        // Live Bytes\n        SynchronousXYItem liveBytesItem = new SynchronousXYItem(GraphsUI.L_LIVE_BYTES_NAME, 0) {\n            public long getYValue(int index) {\n                return dataManager.trackedLiveObjectsSize[index];\n            }\n        };\n        liveBytesItem.setInitialBounds(new LongRect(0, 0, 0, GraphsUI.L_LIVE_BYTES_INITIAL_VALUE));\n\n        // Objects Allocated\n        SynchronousXYItem allocObjectsItem = new SynchronousXYItem(GraphsUI.A_ALLOC_OBJECTS_NAME, 0) {\n            public long getYValue(int index) {\n                return dataManager.nTotalAllocObjects[index];\n            }\n        };\n        allocObjectsItem.setInitialBounds(new LongRect(0, 0, 0, GraphsUI.A_ALLOC_OBJECTS_INITIAL_VALUE));\n\n        // Model\n        SynchronousXYItemsModel model = new SynchronousXYItemsModel(timeline,\n                 new SynchronousXYItem[] { liveObjectsItem,\n                                        liveBytesItem,\n                                        allocObjectsItem});\n\n        return model;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/DiffAllocResultsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport javax.swing.table.TableCellRenderer;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.AllocMemoryResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.AllocMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.ui.components.table.ClassNameTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.DiffBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelTableCellRenderer;\n\n\n/**\n * This panel displays memory allocations diff.\n *\n * @author Jiri Sedlacek\n */\npublic class DiffAllocResultsPanel extends SnapshotAllocResultsPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String GO_SOURCE_POPUP_ITEM_NAME = messages.getString(\"AllocResultsPanel_GoSourcePopupItemName\"); // NOI18N\n                                                                                                                           // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private AllocMemoryResultsDiff diff;\n    private JMenuItem popupShowSource;\n    private JPopupMenu memoryResPopupMenu;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public DiffAllocResultsPanel(AllocMemoryResultsSnapshot snapshot, MemoryResUserActionsHandler actionsHandler) {\n        super(snapshot, actionsHandler);\n        diff = (AllocMemoryResultsDiff) snapshot;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void actionPerformed(ActionEvent e) {\n        if (e.getSource() == popupShowSource && popupShowSource != null) {\n            performDefaultAction(-1);\n        }\n    }\n\n    public void exportData(int typeOfFile, ExportDataDumper eDD, String viewName) {\n        switch (typeOfFile) {\n            case 1: exportCSV(\",\", eDD); break;  //NOI18N\n            case 2: exportCSV(\";\", eDD); break;  //NOI18N\n            case 3: exportXML(eDD, viewName); break;\n            case 4: exportHTML(eDD, viewName); break;\n        }\n    }\n\n    private void exportHTML(ExportDataDumper eDD, String viewName) {\n         // Header\n        StringBuffer result = new StringBuffer(\"<HTML><HEAD><meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" /><TITLE>\"+viewName+\"</TITLE></HEAD><BODY><TABLE border=\\\"1\\\"><tr>\"); // NOI18N\n        for (int i = 0; i < (columnNames.length); i++) {\n            if (!(columnRenderers[i]==null)) {\n                result.append(\"<th>\").append(columnNames[i]).append(\"</th>\"); //NOI18N\n            }\n        }\n        result.append(\"</tr>\"); //NOI18N\n        eDD.dumpData(result);\n\n        for (int i=0; i < nTrackedItems; i++) {\n\n            result = new StringBuffer(\"<tr><td>\"+replaceHTMLCharacters(sortedClassNames[i])+\"</td>\"); //NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(totalAllocObjectsSize[i]).append(\"</td>\"); //NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(nTotalAllocObjects[i]).append(\"</td></tr>\"); //NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TABLE></BODY></HTML>\")); //NOI18N\n    }\n\n    private void exportXML(ExportDataDumper eDD, String viewName) {\n         // Header\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"+newline); // NOI18N\n        result.append(\"<ExportedView Name=\\\"\").append(viewName).append(\"\\\">\").append(newline); //NOI18N\n        result.append(\" <TableData NumRows=\\\"\").append(nTrackedItems).append(\"\\\" NumColumns=\\\"3\\\">\").append(newline); //NOI18N\n        result.append(\"<TableHeader>\"); //NOI18N\n        for (int i = 0; i < (columnNames.length); i++) {\n            if (!(columnRenderers[i]==null)) {\n                result.append(\"  <TableColumn><![CDATA[\").append(columnNames[i]).append(\"]]></TableColumn>\").append(newline); //NOI18N\n            }\n        }\n        result.append(\"</TableHeader>\"); //NOI18N\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer(\"  <TableRow>\"+newline+\"   <TableColumn><![CDATA[\"+sortedClassNames[i]+\"]]></TableColumn>\"+newline); //NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(totalAllocObjectsSize[i]).append(\"]]></TableColumn>\").append(newline); //NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(nTotalAllocObjects[i]).append(\"]]></TableColumn>\").append(newline).append(\"  </TableRow>\").append(newline); //NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TableData>\"+newline+\"</ExportedView>\")); //NOI18N\n    }\n\n    private void exportCSV(String separator, ExportDataDumper eDD) {\n        // Header\n        StringBuffer result = new StringBuffer();\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n\n        for (int i = 0; i < columnNames.length; i++) {\n            if (!(columnRenderers[i]==null)) {\n                result.append(quote).append(columnNames[i]).append(quote).append(separator);\n            }\n        }\n        result.deleteCharAt(result.length()-1);\n        result.append(newLine);\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer();\n            result.append(quote).append(sortedClassNames[i]).append(quote).append(separator);\n            result.append(quote).append(totalAllocObjectsSize[i]).append(quote).append(separator);\n            result.append(quote).append(nTotalAllocObjects[i]).append(quote).append(newLine);\n            eDD.dumpData(result);\n        }\n        eDD.close();\n    }\n\n    private String replaceHTMLCharacters(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break; //NOI18N\n              case '>': sb.append(\"&gt;\"); break; //NOI18N\n              case '&': sb.append(\"&amp;\"); break; //NOI18N\n              case '\"': sb.append(\"&quot;\"); break; //NOI18N\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n\n    protected CustomBarCellRenderer getBarCellRenderer() {\n        return new DiffBarCellRenderer(diff.getMinObjectsSizePerClassDiff(), diff.getMaxObjectsSizePerClassDiff());\n    }\n\n    protected JPopupMenu getPopupMenu() {\n        if (memoryResPopupMenu == null) {\n            memoryResPopupMenu = new JPopupMenu();\n\n            if (GoToSource.isAvailable()) {\n                Font boldfont = memoryResPopupMenu.getFont().deriveFont(Font.BOLD);\n\n                popupShowSource = new JMenuItem();\n                popupShowSource.setFont(boldfont);\n                popupShowSource.setText(GO_SOURCE_POPUP_ITEM_NAME);\n                memoryResPopupMenu.add(popupShowSource);\n                popupShowSource.addActionListener(this);\n            }\n        }\n\n        return memoryResPopupMenu;\n    }\n\n    protected Object computeValueAt(int row, int col) {\n        int index = ((Integer) filteredToFullIndexes.get(row)).intValue();\n\n        switch (col) {\n            case 0:\n                return sortedClassNames[index];\n            case 1:\n                return new Long(totalAllocObjectsSize[index]);\n            case 2:\n                return ((totalAllocObjectsSize[index] > 0) ? \"+\" : \"\") + intFormat.format(totalAllocObjectsSize[index]) + \" B\"; // NOI18N\n            case 3:\n                return ((nTotalAllocObjects[index] > 0) ? \"+\" : \"\") + intFormat.format(nTotalAllocObjects[index]); // NOI18N\n            default:\n                return null;\n        }\n    }\n\n    protected void initColumnsData() {\n        super.initColumnsData();\n\n        ClassNameTableCellRenderer classNameTableCellRenderer = new ClassNameTableCellRenderer();\n        LabelTableCellRenderer labelTableCellRenderer = new LabelTableCellRenderer(JLabel.TRAILING);\n\n        columnRenderers = new TableCellRenderer[] { classNameTableCellRenderer, null, labelTableCellRenderer, labelTableCellRenderer };\n    }\n\n    protected void initDataUponResultsFetch() {\n        super.initDataUponResultsFetch();\n\n        if (barRenderer != null) {\n            barRenderer.setMinimum(diff.getMinObjectsSizePerClassDiff());\n            barRenderer.setMaximum(diff.getMaxObjectsSizePerClassDiff());\n        }\n    }\n\n    protected boolean passesValueFilter(int i) {\n        return true;\n    }\n\n    protected void performDefaultAction(int classId) {\n        String className = null;\n        int selectedRow = resTable.getSelectedRow();\n\n        if (selectedRow != -1) {\n            className = resTable.getValueAt(selectedRow, 0).toString().replace(\"[]\", \"\"); // NOI18N;\n        }\n\n        if (className != null) {\n            actionsHandler.showSourceForMethod(className, null, null);\n        }\n    }\n\n    protected boolean truncateZeroItems() {\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/DiffLivenessResultsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport javax.swing.table.TableCellRenderer;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.LivenessMemoryResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.LivenessMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.ui.components.table.ClassNameTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.DiffBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelTableCellRenderer;\n\n\n/**\n * This panel displays memory liveness diff.\n *\n * @author Jiri Sedlacek\n */\npublic class DiffLivenessResultsPanel extends SnapshotLivenessResultsPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String GO_SOURCE_POPUP_ITEM = messages.getString(\"SnapshotLivenessResultsPanel_GoSourcePopupItem\"); // NOI18N\n                                                                                                                             // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JMenuItem popupShowSource;\n    private JPopupMenu popup;\n    private LivenessMemoryResultsDiff diff;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public DiffLivenessResultsPanel(LivenessMemoryResultsSnapshot snapshot, MemoryResUserActionsHandler actionsHandler,\n                                    int allocTrackEvery) {\n        super(snapshot, actionsHandler, allocTrackEvery);\n        diff = (LivenessMemoryResultsDiff) snapshot;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void actionPerformed(ActionEvent e) {\n        if (e.getSource() == popupShowSource && popupShowSource != null) {\n            performDefaultAction(-1);\n        }\n    }\n\n    protected CustomBarCellRenderer getBarCellRenderer() {\n        return new DiffBarCellRenderer(diff.getMinTrackedLiveObjectsSizeDiff(), diff.getMaxTrackedLiveObjectsSizeDiff());\n    }\n\n    protected JPopupMenu getPopupMenu() {\n        if (popup == null) {\n            popup = new JPopupMenu();\n\n            if (GoToSource.isAvailable()) {\n                Font boldfont = popup.getFont().deriveFont(Font.BOLD);\n\n                popupShowSource = new JMenuItem();\n                popupShowSource.setText(GO_SOURCE_POPUP_ITEM);\n                popupShowSource.setFont(boldfont);\n                popup.add(popupShowSource);\n                popupShowSource.addActionListener(this);\n            }\n        }\n\n        return popup;\n    }\n\n    protected Object computeValueAt(int row, int col) {\n        int index = ((Integer) filteredToFullIndexes.get(row)).intValue();\n\n        switch (col) {\n            case 0:\n                return sortedClassNames[index];\n            case 1:\n                return new Long(trackedLiveObjectsSize[index]);\n            case 2:\n                return ((trackedLiveObjectsSize[index] > 0) ? \"+\" : \"\") + intFormat.format(trackedLiveObjectsSize[index]) + \" B\"; // NOI18N\n            case 3:\n                return ((nTrackedLiveObjects[index] > 0) ? \"+\" : \"\") + intFormat.format(nTrackedLiveObjects[index]); // NOI18N\n            case 4:\n                return ((nTrackedAllocObjects[index] > 0) ? \"+\" : \"\") + intFormat.format(nTrackedAllocObjects[index]); // NOI18N\n            case 5:\n                if (avgObjectAge[index] == 0) return \"0.0\"; // NOI18N\n                // NOTE: StringUtils.floatPerCentToString() doesn't handle correctly negative values!\n                else return ((avgObjectAge[index] > 0) ? \"+\" : \"-\") + StringUtils.floatPerCentToString(Math.abs(avgObjectAge[index])); // NOI18N\n            case 6:\n                return ((maxSurvGen[index] > 0) ? \"+\" : \"\") + intFormat.format(maxSurvGen[index]); // NOI18N\n            case 7:\n                return ((nTotalAllocObjects[index] > 0) ? \"+\" : \"\") + intFormat.format(nTotalAllocObjects[index]); // NOI18N\n            default:\n                return null;\n        }\n    }\n\n    protected void initColumnsData() {\n        super.initColumnsData();\n\n        ClassNameTableCellRenderer classNameTableCellRenderer = new ClassNameTableCellRenderer();\n        LabelTableCellRenderer labelTableCellRenderer = new LabelTableCellRenderer(JLabel.TRAILING);\n\n        columnRenderers = new TableCellRenderer[] {\n                              classNameTableCellRenderer, null, labelTableCellRenderer, labelTableCellRenderer,\n                              labelTableCellRenderer, labelTableCellRenderer, labelTableCellRenderer, labelTableCellRenderer\n                          };\n    }\n\n    protected void initDataUponResultsFetch() {\n        super.initDataUponResultsFetch();\n\n        if (barRenderer != null) {\n            barRenderer.setMinimum(diff.getMinTrackedLiveObjectsSizeDiff());\n            barRenderer.setMaximum(diff.getMaxTrackedLiveObjectsSizeDiff());\n        }\n    }\n\n    protected boolean passesValueFilter(int i) {\n        return true;\n    }\n\n    protected void performDefaultAction(int classId) {\n        String className = null;\n        int selectedRow = resTable.getSelectedRow();\n\n        if (selectedRow != -1) {\n            className = resTable.getValueAt(selectedRow, 0).toString().replace(\"[]\", \"\"); // NOI18N;\n        }\n\n        if (className != null) {\n            actionsHandler.showSourceForMethod(className, null, null);\n        }\n    }\n\n    protected boolean truncateZeroItems() {\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/DiffSampledResultsPanel.java",
    "content": "/*\n * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport javax.swing.table.TableCellRenderer;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.ui.components.table.ClassNameTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.DiffBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelTableCellRenderer;\n\n\n/**\n * This panel displays memory allocations diff.\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic class DiffSampledResultsPanel extends SnapshotSampledResultsPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String GO_SOURCE_POPUP_ITEM_NAME = messages.getString(\"AllocResultsPanel_GoSourcePopupItemName\"); // NOI18N\n                                                                                                                           // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private SampledMemoryResultsDiff diff;\n    private JMenuItem popupShowSource;\n    private JPopupMenu memoryResPopupMenu;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public DiffSampledResultsPanel(SampledMemoryResultsSnapshot snapshot, MemoryResUserActionsHandler actionsHandler) {\n        super(snapshot, actionsHandler);\n        diff = (SampledMemoryResultsDiff) snapshot;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void actionPerformed(ActionEvent e) {\n        if (e.getSource() == popupShowSource && popupShowSource != null) {\n            performDefaultAction(-1);\n        }\n    }\n\n    public void exportData(int typeOfFile, ExportDataDumper eDD, String viewName) {\n        switch (typeOfFile) {\n            case 1: exportCSV(\",\", eDD); break;  //NOI18N\n            case 2: exportCSV(\";\", eDD); break;  //NOI18N\n            case 3: exportXML(eDD, viewName); break;\n            case 4: exportHTML(eDD, viewName); break;\n        }\n    }\n\n    private void exportHTML(ExportDataDumper eDD, String viewName) {\n         // Header\n        StringBuffer result = new StringBuffer(\"<HTML><HEAD><meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" /><TITLE>\"+viewName+\"</TITLE></HEAD><BODY><TABLE border=\\\"1\\\"><tr>\"); // NOI18N\n        for (int i = 0; i < (columnNames.length); i++) {\n            if (!(columnRenderers[i]==null)) {\n                result.append(\"<th>\").append(columnNames[i]).append(\"</th>\"); //NOI18N\n            }\n        }\n        result.append(\"</tr>\"); //NOI18N\n        eDD.dumpData(result);\n\n        for (int i=0; i < nTrackedItems; i++) {\n\n            result = new StringBuffer(\"<tr><td>\"+replaceHTMLCharacters(sortedClassNames[i])+\"</td>\"); //NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(totalLiveObjectsSize[i]).append(\"</td>\"); //NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(nTotalLiveObjects[i]).append(\"</td></tr>\"); //NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TABLE></BODY></HTML>\")); //NOI18N\n    }\n\n    private void exportXML(ExportDataDumper eDD, String viewName) {\n         // Header\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"+newline); // NOI18N\n        result.append(\"<ExportedView Name=\\\"\").append(viewName).append(\"\\\">\").append(newline); //NOI18N\n        result.append(\" <TableData NumRows=\\\"\").append(nTrackedItems).append(\"\\\" NumColumns=\\\"3\\\">\").append(newline); //NOI18N\n        result.append(\"<TableHeader>\"); //NOI18N\n        for (int i = 0; i < (columnNames.length); i++) {\n            if (!(columnRenderers[i]==null)) {\n                result.append(\"  <TableColumn><![CDATA[\").append(columnNames[i]).append(\"]]></TableColumn>\").append(newline); //NOI18N\n            }\n        }\n        result.append(\"</TableHeader>\"); //NOI18N\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer(\"  <TableRow>\"+newline+\"   <TableColumn><![CDATA[\"+sortedClassNames[i]+\"]]></TableColumn>\"+newline); //NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(totalLiveObjectsSize[i]).append(\"]]></TableColumn>\").append(newline); //NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(nTotalLiveObjects[i]).append(\"]]></TableColumn>\").append(newline).append(\"  </TableRow>\").append(newline); //NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TableData>\"+newline+\"</ExportedView>\")); //NOI18N\n    }\n\n    private void exportCSV(String separator, ExportDataDumper eDD) {\n        // Header\n        StringBuffer result = new StringBuffer();\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n\n        for (int i = 0; i < columnNames.length; i++) {\n            if (!(columnRenderers[i]==null)) {\n                result.append(quote).append(columnNames[i]).append(quote).append(separator);\n            }\n        }\n        result.deleteCharAt(result.length()-1);\n        result.append(newLine);\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer();\n            result.append(quote).append(sortedClassNames[i]).append(quote).append(separator);\n            result.append(quote).append(totalLiveObjectsSize[i]).append(quote).append(separator);\n            result.append(quote).append(nTotalLiveObjects[i]).append(quote).append(newLine);\n            eDD.dumpData(result);\n        }\n        eDD.close();\n    }\n\n    private String replaceHTMLCharacters(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break; //NOI18N\n              case '>': sb.append(\"&gt;\"); break; //NOI18N\n              case '&': sb.append(\"&amp;\"); break; //NOI18N\n              case '\"': sb.append(\"&quot;\"); break; //NOI18N\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n\n    protected CustomBarCellRenderer getBarCellRenderer() {\n        return new DiffBarCellRenderer(diff.getMinObjectsSizePerClassDiff(), diff.getMaxObjectsSizePerClassDiff());\n    }\n\n    protected JPopupMenu getPopupMenu() {\n        if (memoryResPopupMenu == null) {\n            memoryResPopupMenu = new JPopupMenu();\n\n            if (GoToSource.isAvailable()) {\n                Font boldfont = memoryResPopupMenu.getFont().deriveFont(Font.BOLD);\n\n                popupShowSource = new JMenuItem();\n                popupShowSource.setFont(boldfont);\n                popupShowSource.setText(GO_SOURCE_POPUP_ITEM_NAME);\n                memoryResPopupMenu.add(popupShowSource);\n                popupShowSource.addActionListener(this);\n            }\n        }\n\n        return memoryResPopupMenu;\n    }\n\n    protected Object computeValueAt(int row, int col) {\n        int index = ((Integer) filteredToFullIndexes.get(row)).intValue();\n\n        switch (col) {\n            case 0:\n                return sortedClassNames[index];\n            case 1:\n                return new Long(totalLiveObjectsSize[index]);\n            case 2:\n                return ((totalLiveObjectsSize[index] > 0) ? \"+\" : \"\") + intFormat.format(totalLiveObjectsSize[index]) + \" B\"; // NOI18N\n            case 3:\n                return ((nTotalLiveObjects[index] > 0) ? \"+\" : \"\") + intFormat.format(nTotalLiveObjects[index]); // NOI18N\n            default:\n                return null;\n        }\n    }\n\n    protected void initColumnsData() {\n        super.initColumnsData();\n\n        ClassNameTableCellRenderer classNameTableCellRenderer = new ClassNameTableCellRenderer();\n        LabelTableCellRenderer labelTableCellRenderer = new LabelTableCellRenderer(JLabel.TRAILING);\n\n        columnRenderers = new TableCellRenderer[] { classNameTableCellRenderer, null, labelTableCellRenderer, labelTableCellRenderer };\n    }\n\n    protected void initDataUponResultsFetch() {\n        super.initDataUponResultsFetch();\n\n        if (barRenderer != null) {\n            barRenderer.setMinimum(diff.getMinObjectsSizePerClassDiff());\n            barRenderer.setMaximum(diff.getMaxObjectsSizePerClassDiff());\n        }\n    }\n\n    protected boolean passesValueFilter(int i) {\n        return true;\n    }\n\n    protected void performDefaultAction(int classId) {\n        String className = null;\n        int selectedRow = resTable.getSelectedRow();\n\n        if (selectedRow != -1) {\n            className = resTable.getValueAt(selectedRow, 0).toString().replace(\"[]\", \"\"); // NOI18N;\n        }\n\n        if (className != null) {\n            actionsHandler.showSourceForMethod(className, null, null);\n        }\n    }\n\n    protected boolean truncateZeroItems() {\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/LiveAllocResultsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.image.BufferedImage;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport javax.swing.event.PopupMenuEvent;\nimport javax.swing.event.PopupMenuListener;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.ClassHistoryDataManager;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.ui.LiveResultsPanel;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * This class implements presentation frames for Object Allocation Profiling.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic class LiveAllocResultsPanel extends AllocResultsPanel implements LiveResultsPanel, ActionListener {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String GO_SOURCE_POPUP_ITEM_NAME = messages.getString(\"AllocResultsPanel_GoSourcePopupItemName\"); // NOI18N\n    private static final String SHOW_STACK_TRACES_POPUP_ITEM_NAME = messages.getString(\"AllocResultsPanel_LiveShowStackTracesPopupItemName\"); // NOI18N\n    private static final String LOG_CLASS_HISTORY = messages.getString(\"LiveResultsPanel_LogClassHistory\"); // NOI18N\n                                                                                                            // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected TargetAppRunner runner;\n\n    private ClassHistoryActionsHandler historyActionsHandler;\n    private ClassHistoryDataManager classHistoryManager;\n    private JMenuItem popupShowSource;\n    private JMenuItem popupShowStacks;\n    private JMenuItem startHisto;\n    private JPopupMenu memoryResPopupMenu;\n    private ProfilingSessionStatus status;\n    private boolean updateResultsInProgress = false;\n    private boolean updateResultsPending = false;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public LiveAllocResultsPanel(TargetAppRunner runner,\n                                 MemoryResUserActionsHandler actionsHandler,\n                                 ClassHistoryActionsHandler historyActionsHandler,\n                                 ClassHistoryDataManager classHistoryManager) {\n        super(actionsHandler);\n        this.status = runner.getProfilerClient().getStatus();\n        this.runner = runner;\n        this.historyActionsHandler = historyActionsHandler;\n        this.classHistoryManager = classHistoryManager;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public BufferedImage getViewImage(boolean onlyVisibleArea) {\n        if (onlyVisibleArea) {\n            return UIUtils.createScreenshot(jScrollPane);\n        } else {\n            return UIUtils.createScreenshot(resTable);\n        }\n    }\n\n    public String getViewName() {\n        return \"memory-allocations-live\"; // NOI18N\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        if (e.getSource() == popupShowStacks) {\n            actionsHandler.showStacksForClass(selectedClassId, getSortingColumn(), getSortingOrder());\n        } else if (e.getSource() == popupShowSource && popupShowSource != null) {\n            showSourceForClass(selectedClassId);\n        } else if (e.getSource() == startHisto) {\n            String selectedClassName = StringUtils.userFormClassName(\n                                                getClassName(selectedClassId));\n            historyActionsHandler.showClassHistory(selectedClassId, selectedClassName);\n                \n        }\n    }\n\n    public void fetchResultsFromTargetApp() throws ClientUtils.TargetAppOrVMTerminated {\n        MemoryCCTProvider oacgb = runner.getProfilerClient().getMemoryCCTProvider();\n\n        if (oacgb == null) {\n            throw new ClientUtils.TargetAppOrVMTerminated(ClientUtils.TargetAppOrVMTerminated.VM);\n        } else {\n            totalAllocObjectsSize = oacgb.getAllocObjectNumbers();\n            nTotalAllocObjects = runner.getProfilerClient().getAllocatedObjectsCountResults();\n\n            // In some situations nInstrClasses can be already updated, but nTotalAllocObjects.length and/ort totalAllocObjectsSize - not yet.\n            // Take measures to avoid ArrayIndexOutOfBoundsException.\n            nTrackedItems = status.getNInstrClasses();\n\n            if (nTrackedItems > nTotalAllocObjects.length) {\n                nTrackedItems = nTotalAllocObjects.length;\n            }\n\n            if (nTrackedItems > totalAllocObjectsSize.length) {\n                nTrackedItems = totalAllocObjectsSize.length;\n            }\n\n            // Operations necessary for correct bar representation of results\n            maxValue = 0;\n            nTotalBytes = 0;\n            nTotalClasses = 0;\n\n            for (int i = 0; i < nTrackedItems; i++) {\n                if (maxValue < totalAllocObjectsSize[i]) {\n                    maxValue = totalAllocObjectsSize[i];\n                }\n\n                nTotalBytes += totalAllocObjectsSize[i];\n                nTotalClasses += nTotalAllocObjects[i];\n            }\n\n            if (classHistoryManager.isTrackingClass())\n                classHistoryManager.processData(nTotalAllocObjects,\n                                                totalAllocObjectsSize);\n\n//            if (handler != null) {\n//                handler.performAction(\"history update\", new Object[] { nTotalAllocObjects, totalAllocObjectsSize }); // NOI18N\n//            }\n\n            initDataUponResultsFetch();\n        }\n    }\n\n    public boolean fitsVisibleArea() {\n        return !jScrollPane.getVerticalScrollBar().isEnabled();\n    }\n\n    public void handleRemove() {\n    }\n\n    /**\n     * Called when auto refresh is on and profiling session will finish\n     * to give the panel chance to do some cleanup before asynchronous\n     * call to updateLiveResults() will happen.\n     *\n     * Currently it closes the context menu if open, which would otherwise\n     * block updating the results.\n     */\n    public void handleShutdown() {\n        // Profiling session will finish and context menu is opened, this would block last live results update -> menu will be closed\n        if ((memoryResPopupMenu != null) && memoryResPopupMenu.isVisible()) {\n            updateResultsPending = false; // clear the flag, updateLiveResults() will be called explicitly from outside\n            memoryResPopupMenu.setVisible(false); // close the context menu\n        }\n    }\n\n    // --- Save current View action support --------------------------------------\n    public boolean hasView() {\n        return resTable != null;\n    }\n\n    public boolean supports(int instrumentationType) {\n        return instrumentationType == CommonConstants.INSTR_OBJECT_ALLOCATIONS;\n    }\n\n    public void updateLiveResults() {\n        if ((memoryResPopupMenu != null) && memoryResPopupMenu.isVisible()) {\n            updateResultsPending = true;\n\n            return;\n        }\n\n        if (updateResultsInProgress) {\n            return;\n        }\n\n        updateResultsInProgress = true;\n\n        String selectedRowString = null;\n\n        if (resTable != null) {\n            int selectedRowIndex = resTable.getSelectedRow();\n\n            if (selectedRowIndex >= resTable.getRowCount()) {\n                selectedRowIndex = -1;\n                resTable.clearSelection();\n            }\n\n            if (selectedRowIndex != -1) {\n                selectedRowString = resTable.getValueAt(selectedRowIndex, 0).toString();\n            }\n        }\n\n        try {\n            if (runner.getProfilingSessionStatus().targetAppRunning) {\n                reset();\n                fetchResultsFromTargetApp();\n            }\n\n            prepareResults();\n\n            if (selectedRowString != null) {\n                resTable.selectRowByContents(selectedRowString, 0, false);\n            }\n\n            if ((resTable != null) && resTable.isFocusOwner()) {\n                resTable.requestFocusInWindow(); // prevents results table from losing focus\n            }\n        } catch (ClientUtils.TargetAppOrVMTerminated e) {\n            ProfilerDialogs.displayWarning(e.getMessage());\n            ProfilerLogger.log(e.getMessage());\n        }\n\n        updateResultsInProgress = false;\n    }\n\n    protected String getClassName(int classId) {\n        return status.getClassNames()[classId];\n    }\n\n    protected String[] getClassNames() {\n        return status.getClassNames();\n    }\n\n    protected JPopupMenu getPopupMenu() {\n        if (memoryResPopupMenu == null) {\n            memoryResPopupMenu = new JPopupMenu();\n\n            if (GoToSource.isAvailable()) {\n                Font boldfont = memoryResPopupMenu.getFont().deriveFont(Font.BOLD);\n\n                popupShowSource = new JMenuItem();\n                popupShowSource.setFont(boldfont);\n                popupShowSource.setText(GO_SOURCE_POPUP_ITEM_NAME);\n                memoryResPopupMenu.add(popupShowSource);\n\n                popupShowSource.addActionListener(this);\n                memoryResPopupMenu.addSeparator();\n            }\n\n            if (runner.getProfilerEngineSettings().getAllocStackTraceLimit() != 0) {\n                popupShowStacks = new JMenuItem();\n                popupShowStacks.setText(SHOW_STACK_TRACES_POPUP_ITEM_NAME);\n                memoryResPopupMenu.add(popupShowStacks);\n                popupShowStacks.addActionListener(this);\n                memoryResPopupMenu.addSeparator();\n            }\n\n            startHisto = new JMenuItem();\n            startHisto.setText(LOG_CLASS_HISTORY);\n            memoryResPopupMenu.add(startHisto);\n            startHisto.addActionListener(this);\n\n            memoryResPopupMenu.addPopupMenuListener(new PopupMenuListener() {\n                public void popupMenuCanceled(PopupMenuEvent e) {\n                }\n\n                public void popupMenuWillBecomeVisible(PopupMenuEvent e) {\n                }\n\n                public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                if (updateResultsPending) {\n                                    updateLiveResults();\n                                    updateResultsPending = false;\n                                }\n                            }\n                        });\n                }\n            });\n        }\n\n        // Only show these items when target JVM is alive\n        boolean jvmAlive = status.targetAppRunning;\n        if (popupShowStacks != null) popupShowStacks.setEnabled(jvmAlive);\n        startHisto.setEnabled(jvmAlive);\n\n        return memoryResPopupMenu;\n    }\n\n    public void exportData(int typeOfFile, ExportDataDumper eDD, String viewName) {\n        percentFormat.setMinimumFractionDigits(2);\n        percentFormat.setMaximumFractionDigits(2);\n        switch (typeOfFile) {\n            case 1: exportCSV(\",\", eDD); break; // normal CSV   // NOI18N\n            case 2: exportCSV(\";\", eDD); break; // Excel CSV  // NOI18N\n            case 3: exportXML(eDD, viewName); break;\n            case 4: exportHTML(eDD, viewName); break;\n        }\n        percentFormat.setMinimumFractionDigits(0);\n        percentFormat.setMaximumFractionDigits(1);\n    }\n\n    private void exportHTML(ExportDataDumper eDD, String viewName) {\n         // Header\n        StringBuffer result = new StringBuffer(\"<HTML><HEAD><meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" /><TITLE>\"+viewName+\"</TITLE></HEAD><BODY><TABLE border=\\\"1\\\"><tr>\"); // NOI18N\n        for (String columnName : columnNames) {\n            result.append(\"<th>\").append(columnName).append(\"</th>\");  // NOI18N\n        }\n        result.append(\"</tr>\");  // NOI18N\n        eDD.dumpData(result);\n\n        for (int i=0; i < nTrackedItems; i++) {\n\n            result = new StringBuffer(\"<tr><td>\"+replaceHTMLCharacters(sortedClassNames[i])+\"</td>\");  // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(percentFormat.format(((double) totalAllocObjectsSize[i])/nTotalBytes)).append(\"</td>\");  // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(totalAllocObjectsSize[i]).append(\" B</td>\");  // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(nTotalAllocObjects[i]).append(\"</td></tr>\");  // NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TABLE></BODY></HTML>\"));  // NOI18N\n    }\n\n    private void exportXML(ExportDataDumper eDD, String viewName) {\n         // Header\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"+newline+\"<ExportedView Name=\\\"\"+viewName+\"\\\">\"+newline); // NOI18N\n        result.append(\"<TableData NumRows=\\\"\").append(nTrackedItems).append(\"\\\" NumColumns=\\\"4\\\">\").append(newline).append(\"<TableHeader>\");  // NOI18N\n        for (String columnName : columnNames) {\n            result.append(\"  <TableColumn><![CDATA[\").append(columnName).append(\"]]></TableColumn>\").append(newline);  // NOI18N\n        }\n        result.append(\"</TableHeader>\");  // NOI18N\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer(\"  <TableRow>\"+newline+\"   <TableColumn><![CDATA[\"+sortedClassNames[i]+\"]]></TableColumn>\"+newline);  // NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(percentFormat.format(((double) totalAllocObjectsSize[i])/nTotalBytes)).append(\"]]></TableColumn>\").append(newline);  // NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(totalAllocObjectsSize[i]).append(\"]]></TableColumn>\").append(newline);  // NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(nTotalAllocObjects[i]).append(\"]]></TableColumn>\").append(newline).append(\"  </TableRow>\").append(newline);  // NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TableData>\"+newline+\"</ExportedView>\"));  // NOI18N\n    }\n\n    private void exportCSV(String separator, ExportDataDumper eDD) {\n        // Header\n        StringBuffer result = new StringBuffer();\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n\n        for (String columnName : columnNames) {\n            result.append(quote).append(columnName).append(quote).append(separator);\n        }\n        result.deleteCharAt(result.length()-1);\n        result.append(newLine);\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer();\n            result.append(quote).append(sortedClassNames[i]).append(quote).append(separator);\n            result.append(quote).append(percentFormat.format(((double) totalAllocObjectsSize[i])/nTotalBytes)).append(quote).append(separator);\n            result.append(quote).append(totalAllocObjectsSize[i]).append(quote).append(separator);\n            result.append(quote).append(nTotalAllocObjects[i]).append(quote).append(newLine);\n            eDD.dumpData(result);\n        }\n        eDD.close();\n    }\n\n    private String replaceHTMLCharacters(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break;  // NOI18N\n              case '>': sb.append(\"&gt;\"); break;  // NOI18N\n              case '&': sb.append(\"&amp;\"); break;  // NOI18N\n              case '\"': sb.append(\"&quot;\"); break;  // NOI18N\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/LiveLivenessResultsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.image.BufferedImage;\nimport java.text.MessageFormat;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport javax.swing.event.PopupMenuEvent;\nimport javax.swing.event.PopupMenuListener;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.InstrumentationException;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.ClassHistoryDataManager;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.ui.LiveResultsPanel;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * This class implements presentation frames for Object Liveness Profiling.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic class LiveLivenessResultsPanel extends LivenessResultsPanel implements LiveResultsPanel, ActionListener {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String GO_SOURCE_POPUP_ITEM_NAME = messages.getString(\"LiveLivenessResultsPanel_GoSourcePopupItemName\"); // NOI18N\n    private static final String SHOW_STACK_TRACES_POPUP_ITEM_NAME = messages.getString(\"AllocResultsPanel_LiveShowStackTracesPopupItemName\"); // NOI18N\n    private static final String STOP_CLASS_POPUP_ITEM_NAME = messages.getString(\"LiveLivenessResultsPanel_StopClassPopupItemName\"); // NOI18N\n    private static final String STOP_BELOW_LINE_POPUP_ITEM_NAME = messages.getString(\"LiveLivenessResultsPanel_StopBelowLinePopupItemName\"); // NOI18N\n    private static final String STOP_CLASS_SPEC_POPUP_ITEM_NAME = messages.getString(\"LiveLivenessResultsPanel_StopClassSpecPopupItemName\"); // NOI18N\n    private static final String STOP_BELOW_LINE_SPEC_POPUP_ITEM_NAME = messages.getString(\"LiveLivenessResultsPanel_StopBelowLineSpecPopupItemName\"); // NOI18N\n    private static final String LOG_CLASS_HISTORY = messages.getString(\"LiveResultsPanel_LogClassHistory\"); // NOI18N\n                                                                                                            // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected TargetAppRunner runner;\n\n    private ClassHistoryActionsHandler historyActionsHandler;\n    private ClassHistoryDataManager classHistoryManager;\n    private JMenuItem popupRemoveProfForClass;\n    private JMenuItem popupRemoveProfForClassesBelow;\n    private JMenuItem popupShowSource;\n    private JMenuItem popupShowStacks;\n    private JMenuItem startHisto;\n    private JPopupMenu popup;\n    private ProfilingSessionStatus status;\n    private boolean updateResultsInProgress = false;\n    private boolean updateResultsPending = false;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public LiveLivenessResultsPanel(TargetAppRunner runner,\n                                    MemoryResUserActionsHandler actionsHandler,\n                                    ClassHistoryActionsHandler historyActionsHandler,\n                                    ClassHistoryDataManager classHistoryManager) {\n        super(actionsHandler);\n        this.runner = runner;\n        this.status = runner.getProfilerClient().getStatus();\n        this.historyActionsHandler = historyActionsHandler;\n        this.classHistoryManager = classHistoryManager;\n        initColumnsData();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public BufferedImage getViewImage(boolean onlyVisibleArea) {\n        if (onlyVisibleArea) {\n            return UIUtils.createScreenshot(jScrollPane);\n        } else {\n            return UIUtils.createScreenshot(resTable);\n        }\n    }\n\n    public String getViewName() {\n        return \"memory-liveness-live\"; // NOI18N\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        Object source = e.getSource();\n\n        if (source == popupRemoveProfForClass) {\n            final int clickedLineLocal = clickedLine;\n            resTable.clearSelection();\n            new SwingWorker() {\n                @Override\n                protected Object doInBackground() throws Exception {\n                    MemoryCCTProvider olcgb = runner.getProfilerClient().getMemoryCCTProvider();\n                    boolean[] newlyUnprofiledClasses = new boolean[sortedClassIds.length];\n                    int line = ((Integer) filteredToFullIndexes.get(clickedLineLocal)).intValue();\n\n                    if (!olcgb.classMarkedUnprofiled(sortedClassIds[line])) {\n                        olcgb.markClassUnprofiled(sortedClassIds[line]);\n                        newlyUnprofiledClasses[sortedClassIds[line]] = true;\n\n                        if (line < nTrackedAllocObjects.length) { // The following arrays may actually be smaller\n                            nTrackedAllocObjects[line] = 0;\n                            nTrackedLiveObjects[line] = 0;\n                            trackedLiveObjectsSize[line] = 0;\n                            avgObjectAge[line] = 0;\n                            maxSurvGen[line] = 0;\n                        }\n\n                        nTotalAllocObjects[line] = 0;\n\n                        deinstrumentMemoryProfiledClasses(newlyUnprofiledClasses);\n                    }\n                    return null;\n                }\n\n                @Override\n                protected void done() {\n                    prepareResults();\n                    if (resTable.getSelectedRow() == -1) { // selection was not changed\n                        int selectedLine = clickedLineLocal;\n                        if (resTable.getRowCount() == clickedLineLocal) {\n                            selectedLine--;\n                        }\n                        if (selectedLine >= 0) {\n                            resTable.setRowSelectionInterval(selectedLine,selectedLine);\n                        }\n                    }\n                }\n            }.execute();\n        } else if (source == popupRemoveProfForClassesBelow) {\n            new SwingWorker() {\n\n                @Override\n                protected Object doInBackground() throws Exception {\n                    int line = clickedLine;\n                    MemoryCCTProvider olcgb = runner.getProfilerClient().getMemoryCCTProvider();\n                    boolean[] newlyUnprofiledClasses = new boolean[sortedClassIds.length];\n                    int nClasses = filteredToFullIndexes.size();\n\n                    for (int i = line + 1; i < nClasses; i++) {\n                        int index = ((Integer) filteredToFullIndexes.get(i)).intValue();\n\n                        if (!olcgb.classMarkedUnprofiled(sortedClassIds[index])) {\n                            olcgb.markClassUnprofiled(sortedClassIds[index]);\n                            newlyUnprofiledClasses[sortedClassIds[index]] = true;\n                            nTrackedAllocObjects[index] = 0;\n                            nTrackedLiveObjects[index] = 0;\n                            trackedLiveObjectsSize[index] = 0;\n                            avgObjectAge[index] = 0;\n                            maxSurvGen[index] = 0;\n                            nTotalAllocObjects[index] = 0;\n                        }\n                    }\n                    deinstrumentMemoryProfiledClasses(newlyUnprofiledClasses);\n                    \n                    return null;\n                }\n\n                @Override\n                protected void done() {\n                    prepareResults();\n                }\n            }.execute();\n        } else if (source == popupShowSource && popupShowSource != null) {\n            showSourceForClass(selectedClassId);\n        } else if (source == popupShowStacks) {\n            actionsHandler.showStacksForClass(selectedClassId, getSortingColumn(), getSortingOrder());\n        } else if (e.getSource() == startHisto) {\n            String selectedClassName = StringUtils.userFormClassName(\n                                                getClassName(selectedClassId));\n            historyActionsHandler.showClassHistory(selectedClassId, selectedClassName);\n        }\n    }\n\n    public void fetchResultsFromTargetApp() throws ClientUtils.TargetAppOrVMTerminated {\n        MemoryCCTProvider olcgb = runner.getProfilerClient().getMemoryCCTProvider();\n\n        if (olcgb == null) {\n            throw new ClientUtils.TargetAppOrVMTerminated(ClientUtils.TargetAppOrVMTerminated.VM);\n        } else {\n            MemoryCCTProvider.ObjectNumbersContainer onc = olcgb.getLivenessObjectNumbers();\n            nTrackedAllocObjects = onc.nTrackedAllocObjects;\n            nTrackedLiveObjects = onc.nTrackedLiveObjects;\n            trackedLiveObjectsSize = onc.trackedLiveObjectsSize;\n            avgObjectAge = onc.avgObjectAge;\n            maxSurvGen = onc.maxSurvGen;\n            nInstrClasses = onc.nInstrClasses;\n\n            if (((nTrackedLiveObjects == null) && (nTrackedAllocObjects == null)) || (avgObjectAge == null)\n                    || (maxSurvGen == null)) {\n                return;\n            }\n\n            // This returns the array containing the total number of allocated objects for each class.\n            nTotalAllocObjects = runner.getProfilerClient().getAllocatedObjectsCountResults();\n\n            // Below is a bit of \"defensive programming\". Normally the sizes of arrays here should be same\n            // except for nTotalAllocObjects, that is returned from the server, and may be shorter if some\n            // instrumented classes have not propagated to the server yet.\n            nTrackedItems = Math.min(nTrackedAllocObjects.length, nTrackedLiveObjects.length);\n            nTrackedItems = Math.min(nTrackedItems, trackedLiveObjectsSize.length);\n            nTrackedItems = Math.min(nTrackedItems, avgObjectAge.length);\n            nTrackedItems = Math.min(nTrackedItems, maxSurvGen.length);\n            nTrackedItems = Math.min(nTrackedItems, nInstrClasses);\n            nTrackedItems = Math.min(nTrackedItems, nTotalAllocObjects.length);\n\n            // Now if some classes are unprofiled, reflect that in nTotalAllocObjects\n            //for (int i = 0; i < nTrackedAllocObjects.length; i++) {\n            for (int i = 0; i < nTrackedItems; i++) {\n                if (nTrackedAllocObjects[i] == -1) {\n                    nTotalAllocObjects[i] = 0;\n                }\n            }\n\n            // Operations necessary for correct bar representation of results\n            maxValue = 0;\n            nTotalTrackedBytes = 0;\n            nTotalTracked = 0;\n\n            //for (int i = 0; i < trackedLiveObjectsSize.length; i++) {\n            for (int i = 0; i < nTrackedItems; i++) {\n                if (maxValue < trackedLiveObjectsSize[i]) {\n                    maxValue = trackedLiveObjectsSize[i];\n                }\n\n                nTotalTrackedBytes += trackedLiveObjectsSize[i];\n                nTotalTracked += nTrackedLiveObjects[i];\n            }\n\n            if (classHistoryManager.isTrackingClass())\n                classHistoryManager.processData(nTotalAllocObjects,\n                                                nTrackedLiveObjects,\n                                                trackedLiveObjectsSize);\n\n//            if (handler != null) {\n//                handler.performAction(\"history update\", new Object[] { nTrackedLiveObjects, nTotalAllocObjects }); // NOI18N\n//            }\n\n            initDataUponResultsFetch();\n        }\n    }\n\n    public boolean fitsVisibleArea() {\n        return !jScrollPane.getVerticalScrollBar().isEnabled();\n    }\n\n    public void handleRemove() {\n    }\n\n    /**\n     * Called when auto refresh is on and profiling session will finish\n     * to give the panel chance to do some cleanup before asynchronous\n     * call to updateLiveResults() will happen.\n     *\n     * Currently it closes the context menu if open, which would otherwise\n     * block updating the results.\n     */\n    public void handleShutdown() {\n        // Profiling session will finish and context menu is opened, this would block last live results update -> menu will be closed\n        if ((popup != null) && popup.isVisible()) {\n            updateResultsPending = false; // clear the flag, updateLiveResults() will be called explicitly from outside\n            popup.setVisible(false); // close the context menu\n        }\n    }\n\n    // --- Save current View action support --------------------------------------\n    public boolean hasView() {\n        return resTable != null;\n    }\n\n    public boolean supports(int instrumentationType) {\n        return instrumentationType == CommonConstants.INSTR_OBJECT_LIVENESS;\n    }\n\n    public void updateLiveResults() {\n        if ((popup != null) && popup.isVisible()) {\n            updateResultsPending = true;\n\n            return;\n        }\n\n        if (updateResultsInProgress) {\n            return;\n        }\n\n        updateResultsInProgress = true;\n\n        String selectedRowString = null;\n\n        if (resTable != null) {\n            int selectedRowIndex = resTable.getSelectedRow();\n\n            if (selectedRowIndex >= resTable.getRowCount()) {\n                selectedRowIndex = -1;\n                resTable.clearSelection();\n            }\n\n            if (selectedRowIndex != -1) {\n                selectedRowString = resTable.getValueAt(selectedRowIndex, 0).toString();\n            }\n        }\n\n        try {\n            if (runner.getProfilingSessionStatus().targetAppRunning) {\n                reset();\n                fetchResultsFromTargetApp();\n            }\n\n            prepareResults();\n\n            if (selectedRowString != null) {\n                resTable.selectRowByContents(selectedRowString, 0, false);\n            }\n\n            if ((resTable != null) && resTable.isFocusOwner()) {\n                resTable.requestFocusInWindow(); // prevents results table from losing focus\n            }\n        } catch (ClientUtils.TargetAppOrVMTerminated e) {\n            ProfilerDialogs.displayWarning(e.getMessage());\n            ProfilerLogger.log(e.getMessage());\n        }\n\n        updateResultsInProgress = false;\n    }\n\n    protected String getClassName(int classId) {\n        return status.getClassNames()[classId];\n    }\n\n    protected String[] getClassNames() {\n        return status.getClassNames();\n    }\n\n    protected int getPercentsTracked() {\n        return 100 / runner.getProfilerEngineSettings().getAllocTrackEvery();\n    }\n\n    protected JPopupMenu getPopupMenu() {\n        if (popup == null) {\n            popup = new JPopupMenu();\n\n            popupRemoveProfForClass = new JMenuItem();\n            popupRemoveProfForClassesBelow = new JMenuItem();\n            popupRemoveProfForClass.setText(STOP_CLASS_POPUP_ITEM_NAME);\n            popupRemoveProfForClassesBelow.setText(STOP_BELOW_LINE_POPUP_ITEM_NAME);\n\n            if (GoToSource.isAvailable()) {\n                Font boldfont = popup.getFont().deriveFont(Font.BOLD);\n\n                popupShowSource = new JMenuItem();\n                popupShowSource.setText(GO_SOURCE_POPUP_ITEM_NAME);\n                popupShowSource.setFont(boldfont);\n\n                popup.add(popupShowSource);\n                popup.addSeparator();\n            }\n\n            if (runner.getProfilerEngineSettings().getAllocStackTraceLimit() != 0) {\n                popupShowStacks = new JMenuItem();\n                popupShowStacks.setText(SHOW_STACK_TRACES_POPUP_ITEM_NAME);\n                popup.add(popupShowStacks);\n                popupShowStacks.addActionListener(this);\n                popup.addSeparator();\n            }\n\n            popup.add(popupRemoveProfForClass);\n            popup.add(popupRemoveProfForClassesBelow);\n\n            if (popupShowSource != null) popupShowSource.addActionListener(this);\n            popupRemoveProfForClass.addActionListener(this);\n            popupRemoveProfForClassesBelow.addActionListener(this);\n\n            popup.addSeparator();\n            startHisto = new JMenuItem();\n            startHisto.setText(LOG_CLASS_HISTORY);\n            popup.add(startHisto);\n            startHisto.addActionListener(this);\n\n            popup.addPopupMenuListener(new PopupMenuListener() {\n                public void popupMenuCanceled(PopupMenuEvent e) {\n                }\n\n                public void popupMenuWillBecomeVisible(PopupMenuEvent e) {\n                }\n\n                public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                if (updateResultsPending) {\n                                    updateLiveResults();\n                                    updateResultsPending = false;\n                                }\n                            }\n                        });\n                }\n            });\n        }\n        // Only show these items when target JVM is alive\n        boolean jvmAlive = status.targetAppRunning;\n        if (popupShowStacks != null) popupShowStacks.setEnabled(jvmAlive);\n        popupRemoveProfForClass.setEnabled(jvmAlive);\n        popupRemoveProfForClassesBelow.setEnabled(jvmAlive);\n        startHisto.setEnabled(jvmAlive);\n\n        return popup;\n    }\n\n    /**\n     * When the user invokes a popup menu, we need to adjust the name for the \"Stop profiling classes below this line\"\n     * item to include the concrete class name, so that the user knows exactly what they are going to remove.\n     */\n    protected void adjustFramePopupMenuTextIfNecessary() {\n        //String name = StringUtils.userFormClassName(sortedClassNames[clickedLine]);\n        String name = sortedClassNames[clickedLine];\n        popupRemoveProfForClass.setText(MessageFormat.format(STOP_CLASS_SPEC_POPUP_ITEM_NAME, name));\n        popupRemoveProfForClassesBelow.setText(MessageFormat.format(STOP_BELOW_LINE_SPEC_POPUP_ITEM_NAME, name));\n    }\n\n    protected void performDefaultAction(int classId) {\n        showSourceForClass(classId);\n    }\n\n    /**\n     * Disable memory profiling for classes with ids such that newlyUnprofiledClasses[id] = true\n     */\n    private void deinstrumentMemoryProfiledClasses(boolean[] newlyUnprofiledClasses) {\n        try {\n            runner.getProfilerClient().deinstrumentMemoryProfiledClasses(newlyUnprofiledClasses);\n        } catch (InstrumentationException ex1) {\n            runner.getAppStatusHandler().displayError(ex1.getMessage());\n        } catch (ClientUtils.TargetAppOrVMTerminated ex2) {\n            runner.getAppStatusHandler().displayWarning(ex2.getMessage());\n            ProfilerLogger.log(ex2.getMessage());\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/LiveMemoryView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.BorderLayout;\nimport java.awt.Font;\nimport java.awt.event.ActionEvent;\nimport java.util.Set;\nimport javax.swing.AbstractAction;\nimport javax.swing.ActionMap;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.AllocMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.LivenessMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.results.DataView;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class LiveMemoryView extends JPanel {\n\n    private MemoryView dataView;\n\n    private long lastupdate;\n    private volatile boolean refreshIsRunning;\n\n    private final Set<ClientUtils.SourceCodeSelection> selection;\n\n    private MemoryResultsSnapshot snapshot;\n    private MemoryResultsSnapshot refSnapshot;\n\n    private GenericFilter filter;\n\n\n\n\n    public LiveMemoryView(Set<ClientUtils.SourceCodeSelection> selection) {\n        this.selection = selection;\n        initUI();\n    }\n\n\n\n    public boolean isRefreshRunning() {\n        return refreshIsRunning;\n    }\n    \n    public long getLastUpdate() {\n        return lastupdate;\n    }\n    \n    public void setData(final MemoryResultsSnapshot snapshotData, final GenericFilter ifilter) {\n        if (refreshIsRunning) return;\n        refreshIsRunning = true;\n        \n        // class names in VM format\n//        MemoryView.userFormClassNames(snapshotData);\n        \n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                try {\n                    updateDataView(snapshotData);\n\n                    snapshot = snapshotData;\n                    filter = ifilter;\n\n                    if (dataView != null && snapshot != null) {\n                        if (refSnapshot == null) dataView.setData(snapshot, filter, CPUResultsSnapshot.CLASS_LEVEL_VIEW);\n                        else dataView.setData(refSnapshot.createDiff(snapshot), filter, CPUResultsSnapshot.CLASS_LEVEL_VIEW);\n                    }\n                } finally {\n                    refreshIsRunning = false;\n                    lastupdate = System.currentTimeMillis();\n                }\n            }\n        });\n    }\n    \n//    private void refreshData(RuntimeCCTNode appRootNode) throws ClientUtils.TargetAppOrVMTerminated {\n//        if ((lastupdate + MIN_UPDATE_DIFF > System.currentTimeMillis() || paused) && !forceRefresh) return;\n//        if (refreshIsRunning) return;\n//        refreshIsRunning = true;\n//        try {\n//            ProfilerClient client = getProfilerClient();\n//            final MemoryResultsSnapshot _snapshot = client.getMemoryProfilingResultsSnapshot(false);\n//\n//            // class names in VM format\n//            MemoryView.userFormClassNames(_snapshot);\n//\n//            // class names in VM format\n//            final GenericFilter ifilter = client.getSettings().getInstrumentationFilter();\n//            // --- TODO: rewrite down to all usages\n////            String[] _ifilter = ifilter == null ? null : ifilter.getUserFilterStrings();\n////            final Collection<String> _filter = _ifilter == null ? Collections.EMPTY_LIST :\n////                                               Arrays.asList(_ifilter);\n//            // ---\n////            final Collection<String> _filter = Arrays.asList(ifilter.getValues()); // Actually wrong, cuts trailing *\n//            \n//            \n////            if (_ifilter != null) for (String s : _ifilter)\n////                    _filter.add(StringUtils.userFormClassName(s));\n//\n//            SwingUtilities.invokeLater(new Runnable() {\n//                public void run() {\n//                    try {\n//                        refreshDataImpl(_snapshot, ifilter);\n//                    } finally {\n//                        refreshIsRunning = false;\n//                    }\n//                }\n//            });\n//        } catch (RuntimeException ex) {\n//            refreshIsRunning = false;\n//            throw ex;\n//        } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n//            refreshIsRunning = false;\n//            throw ex;            \n//        }\n//        \n//        lastupdate = System.currentTimeMillis();\n//        forceRefresh = false;\n//    }\n    \n//    private void refreshDataImpl(MemoryResultsSnapshot _snapshot, GenericFilter _filter) {\n//        assert SwingUtilities.isEventDispatchThread();\n//        \n//        updateDataView(_snapshot);\n//        \n//        snapshot = _snapshot;\n//        filter = _filter;\n//        \n//        if (dataView != null && snapshot != null) {\n//            if (refSnapshot == null) dataView.setData(snapshot, filter, CPUResultsSnapshot.CLASS_LEVEL_VIEW);\n//            else dataView.setData(refSnapshot.createDiff(snapshot), filter, CPUResultsSnapshot.CLASS_LEVEL_VIEW);\n//        }\n//    }\n    \n    public boolean setDiffView(boolean diff) {\n        if (snapshot == null) return false;\n        refSnapshot = diff ? snapshot : null;\n        setData(snapshot, filter);\n        return true;\n    }\n\n//    public void refreshData() throws ClientUtils.TargetAppOrVMTerminated {\n//        if (paused && !forceRefresh) return;\n//        \n//        ProfilerClient client = getProfilerClient();\n//        switch (client.getCurrentInstrType()) {\n//            case CommonConstants.INSTR_NONE_MEMORY_SAMPLING:\n//                refreshData(null);\n//                break;\n//            case CommonConstants.INSTR_OBJECT_LIVENESS:\n//            case CommonConstants.INSTR_OBJECT_ALLOCATIONS:\n//                if (lastupdate + MAX_UPDATE_DIFF < System.currentTimeMillis()) {\n//                    client.forceObtainedResultsDump(true);\n//                }\n//                break;\n//            default:\n//                throw new IllegalArgumentException(\"Invalid profiling instr. type: \" + client.getCurrentInstrType()); // NOI18N\n//        }\n//    }\n    \n    public void resetData() {\n        if (dataView != null) dataView.resetData();\n        snapshot = null;\n        refSnapshot = null;\n        filter = null;\n    }\n\n    \n    public void showSelectionColumn() {\n        if (dataView != null) dataView.showSelectionColumn();\n    }\n    \n    public void refreshSelection() {\n        if (dataView != null) dataView.showSelectionColumn();\n    }\n    \n    \n//    public void cleanup() {\n//        if (rm.view == this) rm.view = null;\n//    }\n    \n    \n//    protected abstract ProfilerClient getProfilerClient();\n    \n    protected boolean profileClassSupported() { return true; }\n    \n    \n    protected abstract boolean showSourceSupported();\n    \n    protected abstract void showSource(ClientUtils.SourceCodeSelection value);\n    \n    protected abstract void selectForProfiling(ClientUtils.SourceCodeSelection value);\n    \n    protected void popupShowing() {}\n    \n    protected void popupHidden() {}\n    \n    \n    private void updateDataView(MemoryResultsSnapshot snapshot) {\n        if (snapshot == null || snapshot instanceof SampledMemoryResultsSnapshot) {\n            if (dataView instanceof SampledTableView) return;\n            \n            dataView = new SampledTableView(selection) {\n                protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                    if (showSourceSupported()) showSource(userValue);\n                }\n                protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                    LiveMemoryView.this.populatePopup(dataView, popup, value, userValue);\n                }\n                protected void popupShowing() { LiveMemoryView.this.popupShowing(); }\n                protected void popupHidden()  { LiveMemoryView.this.popupHidden(); }\n                protected boolean hasBottomFilterFindMargin() { return true; }\n            };\n        } else if (snapshot instanceof AllocMemoryResultsSnapshot) {\n            if (snapshot.containsStacks()) {\n                if (dataView instanceof AllocTreeTableView) return;\n                \n                dataView = new AllocTreeTableView(selection) {\n                    protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                        if (showSourceSupported()) showSource(userValue);\n                    }\n                    protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                        LiveMemoryView.this.populatePopup(dataView, popup, value, userValue);\n                    }\n                    protected void popupShowing() { LiveMemoryView.this.popupShowing(); }\n                    protected void popupHidden()  { LiveMemoryView.this.popupHidden(); }\n                    protected boolean hasBottomFilterFindMargin() { return true; }\n                    HideableBarRenderer.BarDiffMode barDiffMode() { return HideableBarRenderer.BarDiffMode.MODE_BAR_NORMAL; }\n                };\n            } else {\n                if (dataView instanceof AllocTableView) return;\n                \n                dataView = new AllocTableView(selection) {\n                    protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                        if (showSourceSupported()) showSource(userValue);\n                    }\n                    protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                        LiveMemoryView.this.populatePopup(dataView, popup, value, userValue);\n                    }\n                    protected void popupShowing() { LiveMemoryView.this.popupShowing(); }\n                    protected void popupHidden()  { LiveMemoryView.this.popupHidden(); }\n                    protected boolean hasBottomFilterFindMargin() { return true; }\n                    HideableBarRenderer.BarDiffMode barDiffMode() { return HideableBarRenderer.BarDiffMode.MODE_BAR_NORMAL; }\n                };\n            }\n        } else if (snapshot instanceof LivenessMemoryResultsSnapshot) {\n            if (snapshot.containsStacks()) {\n                if (dataView instanceof LivenessTreeTableView) return;\n                \n                dataView = new LivenessTreeTableView(selection, false) {\n                    protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                        if (showSourceSupported()) showSource(userValue);\n                    }\n                    protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                        LiveMemoryView.this.populatePopup(dataView, popup, value, userValue);\n                    }\n                    protected void popupShowing() { LiveMemoryView.this.popupShowing(); }\n                    protected void popupHidden()  { LiveMemoryView.this.popupHidden(); }\n                    protected boolean hasBottomFilterFindMargin() { return true; }\n                };\n            } else {\n                if (dataView instanceof LivenessTableView) return;\n                \n                dataView = new LivenessTableView(selection, false) {\n                    protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                        if (showSourceSupported()) showSource(userValue);\n                    }\n                    protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                        LiveMemoryView.this.populatePopup(dataView, popup, value, userValue);\n                    }\n                    protected void popupShowing() { LiveMemoryView.this.popupShowing(); }\n                    protected void popupHidden()  { LiveMemoryView.this.popupHidden(); }\n                    protected boolean hasBottomFilterFindMargin() { return true; }\n                };\n            }\n        } else {\n            dataView = null;\n        }\n        \n        removeAll();\n        resetData();\n        if (dataView != null) add(dataView, BorderLayout.CENTER);\n        revalidate();\n        repaint();\n    }\n    \n    private void populatePopup(final DataView invoker, JPopupMenu popup, Object value, final ClientUtils.SourceCodeSelection userValue) {\n        if (showSourceSupported()) {\n            popup.add(new JMenuItem(MemoryView.ACTION_GOTOSOURCE) {\n                { setEnabled(userValue != null); setFont(getFont().deriveFont(Font.BOLD)); }\n                protected void fireActionPerformed(ActionEvent e) { showSource(userValue); }\n            });\n            popup.addSeparator();\n        }\n        \n        if (profileClassSupported()) {\n            popup.add(new JMenuItem(MemoryView.ACTION_PROFILE_CLASS) {\n                { setEnabled(userValue != null); }\n                protected void fireActionPerformed(ActionEvent e) { selectForProfiling(userValue); }\n            });\n        }\n        \n        if (profileClassSupported()) popup.addSeparator();\n        \n        JMenuItem[] customItems = invoker.createCustomMenuItems(this, value, userValue);\n        if (customItems != null) {\n            for (JMenuItem customItem : customItems) popup.add(customItem);\n            popup.addSeparator();\n        }\n        \n        customizeNodePopup(invoker, popup, value, userValue);\n        \n        if (snapshot.containsStacks()) {\n            final ProfilerTreeTable ttable = (ProfilerTreeTable)dataView.getResultsComponent();\n            JMenu expand = new JMenu(MemoryView.EXPAND_MENU);\n            popup.add(expand);\n\n            expand.add(new JMenuItem(MemoryView.EXPAND_PLAIN_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.expandPlainPath(ttable.getSelectedRow(), 1);\n                }\n            });\n\n            expand.add(new JMenuItem(MemoryView.EXPAND_TOPMOST_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.expandFirstPath(ttable.getSelectedRow());\n                }\n            });\n            \n            expand.addSeparator();\n            \n            expand.add(new JMenuItem(MemoryView.COLLAPSE_CHILDREN_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.collapseChildren(ttable.getSelectedRow());\n                }\n            });\n            \n            expand.add(new JMenuItem(MemoryView.COLLAPSE_ALL_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.collapseAll();\n                }\n            });\n            \n            popup.addSeparator();\n        }\n        \n        popup.add(invoker.createCopyMenuItem());\n        popup.addSeparator();\n        \n        popup.add(new JMenuItem(FilterUtils.ACTION_FILTER) {\n            protected void fireActionPerformed(ActionEvent e) { invoker.activateFilter(); }\n        });\n        popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {\n            protected void fireActionPerformed(ActionEvent e) { invoker.activateSearch(); }\n        });\n    }\n    \n    protected void customizeNodePopup(DataView invoker, JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {}\n    \n    \n    private void initUI() {\n        setLayout(new BorderLayout(0, 0));\n        \n        // TODO: read last state?\n        updateDataView(null);\n        \n        registerActions();\n    }\n    \n    private void registerActions() {\n        ActionMap map = getActionMap();\n        \n        map.put(FilterUtils.FILTER_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { dataView.activateFilter(); }\n        });\n        \n        map.put(SearchUtils.FIND_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { dataView.activateSearch(); }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/LiveMemoryViewUpdater.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryResultsSnapshot;\nimport org.openide.util.Lookup;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class LiveMemoryViewUpdater {\n\n    private static final int MIN_UPDATE_DIFF = 900;\n    private static final int MAX_UPDATE_DIFF = 1400;\n\n\n    private CCTHandler handler;\n\n    private final LiveMemoryView memoryView;\n    private final ProfilerClient client;\n\n    private volatile boolean paused;\n    private volatile boolean forceRefresh;\n\n\n    public LiveMemoryViewUpdater(LiveMemoryView memoryView, ProfilerClient client) {\n        this.memoryView = memoryView;\n        this.client = client;\n\n        handler = CCTHandler.registerUpdater(this);\n    }\n\n\n    public void setPaused(boolean paused) {\n        this.paused = paused;\n    }\n\n    public void setForceRefresh(boolean forceRefresh) {\n        this.forceRefresh = forceRefresh;\n    }\n\n    public void update() throws ClientUtils.TargetAppOrVMTerminated {\n        if (forceRefresh || (!paused && memoryView.getLastUpdate() + MAX_UPDATE_DIFF < System.currentTimeMillis()))\n            switch (client.getCurrentInstrType()) {\n                case CommonConstants.INSTR_NONE_MEMORY_SAMPLING:\n                    updateData();\n                    break;\n                case CommonConstants.INSTR_OBJECT_LIVENESS:\n                case CommonConstants.INSTR_OBJECT_ALLOCATIONS:\n                    if (memoryView.getLastUpdate() + MAX_UPDATE_DIFF < System.currentTimeMillis()) {\n                        client.forceObtainedResultsDump(true);\n                    }\n                    break;\n                default:\n                    throw new IllegalArgumentException(\"Invalid profiling instr. type: \" + client.getCurrentInstrType()); // NOI18N\n            }\n    }\n    \n    public void cleanup() {\n        handler.unregisterUpdater(this);\n        handler = null;\n    }\n    \n    \n    private void updateData() throws ClientUtils.TargetAppOrVMTerminated {\n        if (!forceRefresh && (paused || memoryView.getLastUpdate() + MIN_UPDATE_DIFF > System.currentTimeMillis())) return;\n        \n        MemoryResultsSnapshot snapshot = client.getMemoryProfilingResultsSnapshot(false);\n\n        // class names in VM format\n        MemoryView.userFormClassNames(snapshot);\n\n        // class names in VM format\n        GenericFilter filter = client.getSettings().getInstrumentationFilter();\n        \n        memoryView.setData(snapshot, filter);\n        \n        forceRefresh = false;\n    }\n    \n    private void resetData() {\n        memoryView.resetData();\n    }\n    \n    \n    @ServiceProvider(service=MemoryCCTProvider.Listener.class)\n    public static final class CCTHandler implements MemoryCCTProvider.Listener {\n\n        private final List<LiveMemoryViewUpdater> updaters = new ArrayList<>();\n        \n        \n        public static CCTHandler registerUpdater(LiveMemoryViewUpdater updater) {\n            CCTHandler handler = Lookup.getDefault().lookup(CCTHandler.class);\n            handler.updaters.add(updater);\n            return handler;\n        }\n        \n        public void unregisterUpdater(LiveMemoryViewUpdater updater) {\n            updaters.remove(updater);\n        }\n        \n        \n        public void cctEstablished(RuntimeCCTNode appRootNode, boolean empty) {\n            if (!empty) {\n                for (LiveMemoryViewUpdater updater : updaters) try {\n                    updater.updateData();\n                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n//                } catch (CPUResultsSnapshot.NoDataAvailableException ex) {\n                    Logger.getLogger(LiveMemoryView.class.getName()).log(Level.FINE, null, ex);\n                }\n            }\n        }\n\n        public void cctReset() {\n            for (LiveMemoryViewUpdater updater : updaters) updater.resetData();\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/LiveReverseMemCallGraphPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.*;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCCTManager;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjLivenessCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.JTreeTable;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.treetable.AbstractTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.ExtendedTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.JTreeTablePanel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.TreeTableModel;\n\n\n/**\n * A panel containing a reverse call graph for all allocations of instances of a given class\n *\n * No used at the moment!!!\n *\n * @author Misha Dmitriev\n * @author Jiri Sedlacek\n */\npublic class LiveReverseMemCallGraphPanel extends ReverseMemCallGraphPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String NO_STACKS_MSG = messages.getString(\"LiveReverseMemCallGraphPanel_NoStacksMsg\"); // NOI18N\n    private static final String TREETABLE_ACCESS_NAME = messages.getString(\"LiveReverseMemCallGraphPanel_TreeTableAccessName\"); // NOI18N\n                                                                                                                                // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected MemoryCCTManager callGraphManager;\n    protected ProfilingSessionStatus status;\n    protected int classId;\n    private AbstractTreeTableModel abstractTreeTableModel;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public LiveReverseMemCallGraphPanel(ProfilingSessionStatus status, MemoryResUserActionsHandler actionsHandler) {\n        super(actionsHandler, status.currentInstrType == ProfilerEngineSettings.INSTR_OBJECT_LIVENESS);\n        this.status = status;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setCallGraph(MemoryCCTManager callGraphManager, int classId) {\n        this.callGraphManager = callGraphManager;\n        this.classId = classId;\n\n        if (!callGraphManager.isEmpty()) {\n            customBarCellRenderer = new CustomBarCellRenderer(0, callGraphManager.getRootNode().totalObjSize);\n            columnRenderers[1] = customBarCellRenderer;\n        }\n    }\n\n    public void prepareResults() {\n        if (callGraphManager.isEmpty()) {\n            removeAll();\n            add(new JLabel(NO_STACKS_MSG), BorderLayout.CENTER);\n        } else {\n            abstractTreeTableModel = new AbstractTreeTableModel(callGraphManager.getRootNode(), 1, false) {\n                    public int getColumnCount() {\n                        return columnNames.length;\n                    }\n\n                    public String getColumnName(int column) {\n                        return columnNames[column];\n                    }\n\n                    public Class<?> getColumnClass(int column) {\n                        if (column == 0) {\n                            return TreeTableModel.class;\n                        } else {\n                            return Object.class;\n                        }\n                    }\n\n                    public Object getValueAt(Object node, int column) {\n                        long value;\n\n                        if (extendedResults) {\n                            PresoObjLivenessCCTNode pNode = (PresoObjLivenessCCTNode) node;\n\n                            switch (column) {\n                                case 0:\n                                    return pNode.toString();\n                                case 1:\n                                    return new Long(pNode.totalObjSize);\n                                case 2:\n                                    value = ((PresoObjLivenessCCTNode) root).totalObjSize;\n\n                                    return intFormat.format(pNode.totalObjSize) + \" B (\"\n                                           + ((value == 0) ? \"-%\" : percentFormat.format((float) pNode.totalObjSize / (float) value))\n                                           + \")\"; // NOI18N\n                                case 3:\n                                    value = ((PresoObjLivenessCCTNode) root).nLiveObjects;\n\n                                    return intFormat.format(pNode.nLiveObjects) + \" (\"\n                                           + ((value == 0) ? \"-%\" : percentFormat.format((float) pNode.nLiveObjects / (float) value))\n                                           + \")\"; // NOI18N\n                                case 4:\n                                    return intFormat.format(pNode.nCalls);\n                                case 5:\n                                    return StringUtils.floatPerCentToString(pNode.avgObjectAge);\n                                case 6:\n                                    return intFormat.format(pNode.survGen);\n                            }\n                        } else {\n                            PresoObjAllocCCTNode pNode = (PresoObjAllocCCTNode) node;\n\n                            switch (column) {\n                                case 0:\n                                    return pNode.getNodeName();\n                                case 1:\n                                    return new Long(pNode.totalObjSize);\n                                case 2:\n                                    value = ((PresoObjAllocCCTNode) root).totalObjSize;\n\n                                    return intFormat.format(pNode.totalObjSize) + \" B (\"\n                                           + ((value == 0) ? \"-%\" : percentFormat.format((float) pNode.totalObjSize / (float) value))\n                                           + \")\"; // NOI18N\n                                case 3:\n                                    value = ((PresoObjAllocCCTNode) root).nCalls;\n\n                                    return intFormat.format(pNode.nCalls) + \" (\"\n                                           + ((value == 0) ? \"-%\" : percentFormat.format((float) pNode.nCalls / (float) value))\n                                           + \")\"; // NOI18N\n                            }\n                        }\n\n                        return null;\n                    }\n\n                    public String getColumnToolTipText(int col) {\n                        return columnToolTips[col];\n                    }\n\n                    public void sortByColumn(int column, boolean order) {\n                        if (extendedResults) {\n                            PresoObjLivenessCCTNode pRoot = (PresoObjLivenessCCTNode) root;\n\n                            switch (column) {\n                                case 0:\n                                    pRoot.sortChildren(PresoObjLivenessCCTNode.SORT_BY_NAME, order);\n\n                                    break;\n                                case 1:\n                                case 2:\n                                    pRoot.sortChildren(PresoObjLivenessCCTNode.SORT_BY_LIVE_OBJ_SIZE, order);\n\n                                    break;\n                                case 3:\n                                    pRoot.sortChildren(PresoObjLivenessCCTNode.SORT_BY_LIVE_OBJ_NUMBER, order);\n\n                                    break;\n                                case 4:\n                                    pRoot.sortChildren(PresoObjLivenessCCTNode.SORT_BY_ALLOC_OBJ, order);\n\n                                    break;\n                                case 5:\n                                    pRoot.sortChildren(PresoObjLivenessCCTNode.SORT_BY_AVG_AGE, order);\n\n                                    break;\n                                case 6:\n                                    pRoot.sortChildren(PresoObjLivenessCCTNode.SORT_BY_SURV_GEN, order);\n\n                                    break;\n                            }\n                        } else {\n                            PresoObjAllocCCTNode pRoot = (PresoObjAllocCCTNode) root;\n\n                            switch (column) {\n                                case 0:\n                                    pRoot.sortChildren(PresoObjAllocCCTNode.SORT_BY_NAME, order);\n\n                                    break;\n                                case 1:\n                                case 2:\n                                    pRoot.sortChildren(PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_SIZE, order);\n\n                                    break;\n                                case 3:\n                                    pRoot.sortChildren(PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_NUMBER, order);\n\n                                    break;\n                            }\n                        }\n                    }\n\n                    public boolean getInitialSorting(int column) {\n                        switch (column) {\n                            case 0:\n                                return true;\n                            default:\n                                return false;\n                        }\n                    }\n                };\n\n            treeTableModel = new ExtendedTreeTableModel(abstractTreeTableModel);\n\n            treeTable = new JTreeTable(treeTableModel) {\n                    public void doLayout() {\n                        int columnsWidthsSum = 0;\n                        int realFirstColumn = -1;\n\n                        int index;\n                        TableColumnModel colModel = getColumnModel();\n\n                        for (int i = 0; i < treeTableModel.getColumnCount(); i++) {\n                            index = treeTableModel.getRealColumn(i);\n\n                            if (index == 0) {\n                                realFirstColumn = i;\n                            } else {\n                                columnsWidthsSum += colModel.getColumn(i).getPreferredWidth();\n                            }\n                        }\n\n                        if (realFirstColumn != -1) {\n                            colModel.getColumn(realFirstColumn)\n                                    .setPreferredWidth(Math.max(getWidth() - columnsWidthsSum, minNamesColumnWidth));\n                        }\n\n                        super.doLayout();\n                    }\n\n                };\n            treeTable.getAccessibleContext().setAccessibleName(TREETABLE_ACCESS_NAME);\n\n            treeTable.setRowSelectionAllowed(true);\n            treeTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n            treeTable.setGridColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);\n            treeTable.setSelectionBackground(UIConstants.TABLE_SELECTION_BACKGROUND_COLOR);\n            treeTable.setSelectionForeground(UIConstants.TABLE_SELECTION_FOREGROUND_COLOR);\n            treeTable.setShowHorizontalLines(UIConstants.SHOW_TABLE_HORIZONTAL_GRID);\n            treeTable.setShowVerticalLines(UIConstants.SHOW_TABLE_VERTICAL_GRID);\n            treeTable.setRowMargin(UIConstants.TABLE_ROW_MARGIN);\n            treeTable.setRowHeight(UIUtils.getDefaultRowHeight() + 2);\n\n            setColumnsData();\n\n            UIUtils.autoExpandRoot(treeTable.getTree());\n            UIUtils.makeTreeAutoExpandable(treeTable.getTree());\n\n            treeTable.addMouseListener(new MouseAdapter() {\n                    private void showPopupMenu(MouseEvent e) {\n                        treePath = treeTable.getTree().getPathForRow(treeTable.rowAtPoint(e.getPoint()));\n\n                        if (treePath == null) {\n                                treeTable.getTree().clearSelection();\n                        } else {\n                            treeTable.getTree().setSelectionPath(treePath);\n                            popupMenu.show(e.getComponent(), e.getX(), e.getY());\n                        }\n                    }\n                    public void mousePressed(MouseEvent e) {\n                        if (e.isPopupTrigger()) showPopupMenu(e);\n                    }\n\n                    public void mouseReleased(MouseEvent e) {\n                        if (e.isPopupTrigger()) showPopupMenu(e);\n                    }\n\n                    public void mouseClicked(MouseEvent e) {\n                        treePath = treeTable.getTree().getPathForRow(treeTable.rowAtPoint(e.getPoint()));\n\n                        if (treePath != null) {\n                            treeTable.getTree().setSelectionPath(treePath);\n                            if (SwingUtilities.isLeftMouseButton(e) && (e.getClickCount() == 2)) {\n                                if (treeTableModel.isLeaf(treePath.getPath()[treePath.getPath().length - 1])) {\n                                    performDefaultAction(treePath);\n                                }\n                            }\n                        }\n                    }\n                });\n\n            removeAll();\n            treeTablePanel = new JTreeTablePanel(treeTable);\n            treeTablePanel.setCorner(JScrollPane.UPPER_RIGHT_CORNER, cornerButton);\n            add(treeTablePanel, BorderLayout.CENTER);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/LiveSampledResultsPanel.java",
    "content": "/*\n * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.image.BufferedImage;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport javax.swing.event.PopupMenuEvent;\nimport javax.swing.event.PopupMenuListener;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.HeapHistogram;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.HeapHistogram.ClassInfo;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.ui.LiveResultsPanel;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * This class implements presentation frames for Memory sampling.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic class LiveSampledResultsPanel extends SampledResultsPanel implements LiveResultsPanel, ActionListener {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String GO_SOURCE_POPUP_ITEM_NAME = messages.getString(\"AllocResultsPanel_GoSourcePopupItemName\"); // NOI18N\n                                                                                                            // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected TargetAppRunner runner;\n\n    private String[] classNames;\n    private JMenuItem popupShowSource;\n    private JPopupMenu memoryResPopupMenu;\n    private ProfilingSessionStatus status;\n    private boolean updateResultsInProgress = false;\n    private boolean updateResultsPending = false;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public LiveSampledResultsPanel(TargetAppRunner runner,\n                                 MemoryResUserActionsHandler actionsHandler) {\n        super(actionsHandler);\n        this.status = runner.getProfilerClient().getStatus();\n        this.runner = runner;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public BufferedImage getViewImage(boolean onlyVisibleArea) {\n        if (onlyVisibleArea) {\n            return UIUtils.createScreenshot(jScrollPane);\n        } else {\n            return UIUtils.createScreenshot(resTable);\n        }\n    }\n\n    public String getViewName() {\n        return \"memory-sampled-live\"; // NOI18N\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        if (e.getSource() == popupShowSource && popupShowSource != null) {\n            showSourceForClass(selectedClassId);\n        }\n    }\n\n    public void fetchResultsFromTargetApp() throws ClientUtils.TargetAppOrVMTerminated {\n        HeapHistogram histogram = runner.getProfilerClient().getHeapHistogram();\n        ClassInfo[] classInfoArray = histogram.getHeapHistogram().toArray(new ClassInfo[0]);\n\n        classNames = new String[classInfoArray.length];\n        totalLiveObjectsSize = new long[classInfoArray.length];\n        nTotalLiveObjects = new int[classInfoArray.length];\n        \n        for (int i = 0; i<classInfoArray.length; i++) {\n            ClassInfo ci = classInfoArray[i];\n            classNames[i] = ci.getName();\n            totalLiveObjectsSize[i] = ci.getBytes();\n            nTotalLiveObjects[i] = (int)ci.getInstancesCount();\n        }\n\n        nTrackedItems = classInfoArray.length;\n\n        if (nTrackedItems > nTotalLiveObjects.length) {\n            nTrackedItems = nTotalLiveObjects.length;\n        }\n\n        if (nTrackedItems > totalLiveObjectsSize.length) {\n            nTrackedItems = totalLiveObjectsSize.length;\n        }\n\n        // Operations necessary for correct bar representation of results\n        maxValue = 0;\n        nTotalLiveBytes = 0;\n        nTotalClasses = 0;\n\n        for (int i = 0; i < nTrackedItems; i++) {\n            if (maxValue < totalLiveObjectsSize[i]) {\n                maxValue = totalLiveObjectsSize[i];\n            }\n\n            nTotalLiveBytes += totalLiveObjectsSize[i];\n            nTotalClasses += nTotalLiveObjects[i];\n        }\n\n        initDataUponResultsFetch();\n    }\n\n    public boolean fitsVisibleArea() {\n        return !jScrollPane.getVerticalScrollBar().isEnabled();\n    }\n\n    public void handleRemove() {\n    }\n\n    /**\n     * Called when auto refresh is on and profiling session will finish\n     * to give the panel chance to do some cleanup before asynchronous\n     * call to updateLiveResults() will happen.\n     *\n     * Currently it closes the context menu if open, which would otherwise\n     * block updating the results.\n     */\n    public void handleShutdown() {\n        // Profiling session will finish and context menu is opened, this would block last live results update -> menu will be closed\n        if ((memoryResPopupMenu != null) && memoryResPopupMenu.isVisible()) {\n            updateResultsPending = false; // clear the flag, updateLiveResults() will be called explicitly from outside\n            memoryResPopupMenu.setVisible(false); // close the context menu\n        }\n    }\n\n    // --- Save current View action support --------------------------------------\n    public boolean hasView() {\n        return resTable != null;\n    }\n\n    public boolean supports(int instrumentationType) {\n        return instrumentationType == CommonConstants.INSTR_NONE_MEMORY_SAMPLING;\n    }\n\n    public void updateLiveResults() {\n        if ((memoryResPopupMenu != null) && memoryResPopupMenu.isVisible()) {\n            updateResultsPending = true;\n\n            return;\n        }\n\n        if (updateResultsInProgress) {\n            return;\n        }\n\n        updateResultsInProgress = true;\n\n        String selectedRowString = null;\n\n        if (resTable != null) {\n            int selectedRowIndex = resTable.getSelectedRow();\n\n            if (selectedRowIndex >= resTable.getRowCount()) {\n                selectedRowIndex = -1;\n                resTable.clearSelection();\n            }\n\n            if (selectedRowIndex != -1) {\n                selectedRowString = resTable.getValueAt(selectedRowIndex, 0).toString();\n            }\n        }\n\n        try {\n            if (status.targetAppRunning) {\n                reset();\n                fetchResultsFromTargetApp();\n            }\n\n            prepareResults();\n\n            if (selectedRowString != null) {\n                resTable.selectRowByContents(selectedRowString, 0, false);\n            }\n\n            if ((resTable != null) && resTable.isFocusOwner()) {\n                resTable.requestFocusInWindow(); // prevents results table from losing focus\n            }\n        } catch (ClientUtils.TargetAppOrVMTerminated e) {\n            ProfilerDialogs.displayWarning(e.getMessage());\n            ProfilerLogger.log(e.getMessage());\n        }\n\n        updateResultsInProgress = false;\n    }\n\n    protected String getClassName(int classId) {\n        return classNames[classId];\n    }\n\n    protected String[] getClassNames() {\n        return classNames;\n    }\n\n    protected JPopupMenu getPopupMenu() {\n        if (memoryResPopupMenu == null) {\n            memoryResPopupMenu = new JPopupMenu();\n\n            if (GoToSource.isAvailable()) {\n                Font boldfont = memoryResPopupMenu.getFont().deriveFont(Font.BOLD);\n\n                popupShowSource = new JMenuItem();\n                popupShowSource.setFont(boldfont);\n                popupShowSource.setText(GO_SOURCE_POPUP_ITEM_NAME);\n                memoryResPopupMenu.add(popupShowSource);\n\n                popupShowSource.addActionListener(this);\n            }\n\n            memoryResPopupMenu.addPopupMenuListener(new PopupMenuListener() {\n                public void popupMenuCanceled(PopupMenuEvent e) {\n                }\n\n                public void popupMenuWillBecomeVisible(PopupMenuEvent e) {\n                }\n\n                public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                if (updateResultsPending) {\n                                    updateLiveResults();\n                                    updateResultsPending = false;\n                                }\n                            }\n                        });\n                }\n            });\n        }\n\n        return memoryResPopupMenu;\n    }\n\n    public void exportData(int typeOfFile, ExportDataDumper eDD, String viewName) {\n        percentFormat.setMinimumFractionDigits(2);\n        percentFormat.setMaximumFractionDigits(2);\n        switch (typeOfFile) {\n            case 1: exportCSV(\",\", eDD); break; // normal CSV   // NOI18N\n            case 2: exportCSV(\";\", eDD); break; // Excel CSV  // NOI18N\n            case 3: exportXML(eDD, viewName); break;\n            case 4: exportHTML(eDD, viewName); break;\n        }\n        percentFormat.setMinimumFractionDigits(0);\n        percentFormat.setMaximumFractionDigits(1);\n    }\n\n    private void exportHTML(ExportDataDumper eDD, String viewName) {\n         // Header\n        StringBuffer result = new StringBuffer(\"<HTML><HEAD><meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" /><TITLE>\"+viewName+\"</TITLE></HEAD><BODY><TABLE border=\\\"1\\\"><tr>\"); // NOI18N\n        for (String columnName : columnNames) {\n            result.append(\"<th>\").append(columnName).append(\"</th>\");  // NOI18N\n        }\n        result.append(\"</tr>\");  // NOI18N\n        eDD.dumpData(result);\n\n        for (int i=0; i < nTrackedItems; i++) {\n\n            result = new StringBuffer(\"<tr><td>\"+replaceHTMLCharacters(sortedClassNames[i])+\"</td>\");  // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(percentFormat.format(((double) totalLiveObjectsSize[i])/nTotalLiveBytes)).append(\"</td>\");  // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(totalLiveObjectsSize[i]).append(\" B</td>\");  // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(nTotalLiveObjects[i]).append(\"</td></tr>\");  // NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TABLE></BODY></HTML>\"));  // NOI18N\n    }\n\n    private void exportXML(ExportDataDumper eDD, String viewName) {\n         // Header\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"+newline+\"<ExportedView Name=\\\"\"+viewName+\"\\\">\"+newline); // NOI18N\n        result.append(\"<TableData NumRows=\\\"\").append(nTrackedItems).append(\"\\\" NumColumns=\\\"4\\\">\").append(newline).append(\"<TableHeader>\");  // NOI18N\n        for (String columnName : columnNames) {\n            result.append(\"  <TableColumn><![CDATA[\").append(columnName).append(\"]]></TableColumn>\").append(newline);  // NOI18N\n        }\n        result.append(\"</TableHeader>\");  // NOI18N\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer(\"  <TableRow>\"+newline+\"   <TableColumn><![CDATA[\"+sortedClassNames[i]+\"]]></TableColumn>\"+newline);  // NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(percentFormat.format(((double) totalLiveObjectsSize[i])/nTotalLiveBytes)).append(\"]]></TableColumn>\").append(newline);  // NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(totalLiveObjectsSize[i]).append(\"]]></TableColumn>\").append(newline);  // NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(nTotalLiveObjects[i]).append(\"]]></TableColumn>\").append(newline).append(\"  </TableRow>\").append(newline);  // NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TableData>\"+newline+\"</ExportedView>\"));  // NOI18N\n    }\n\n    private void exportCSV(String separator, ExportDataDumper eDD) {\n        // Header\n        StringBuffer result = new StringBuffer();\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n\n        for (String columnName : columnNames) {\n            result.append(quote).append(columnName).append(quote).append(separator);\n        }\n        result.deleteCharAt(result.length()-1);\n        result.append(newLine);\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer();\n            result.append(quote).append(sortedClassNames[i]).append(quote).append(separator);\n            result.append(quote).append(percentFormat.format(((double) totalLiveObjectsSize[i])/nTotalLiveBytes)).append(quote).append(separator);\n            result.append(quote).append(totalLiveObjectsSize[i]).append(quote).append(separator);\n            result.append(quote).append(nTotalLiveObjects[i]).append(quote).append(newLine);\n            eDD.dumpData(result);\n        }\n        eDD.close();\n    }\n\n    private String replaceHTMLCharacters(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break;  // NOI18N\n              case '>': sb.append(\"&gt;\"); break;  // NOI18N\n              case '&': sb.append(\"&amp;\"); break;  // NOI18N\n              case '\"': sb.append(\"&quot;\"); break;  // NOI18N\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/LivenessResultsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.AWTKeyStroke;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyEvent;\nimport java.util.HashSet;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport javax.swing.*;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjLivenessCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedTable;\nimport org.graalvm.visualvm.lib.ui.components.table.ClassNameTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.ExtendedTableModel;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelBracketTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.SortableTableModel;\n\n\n/**\n * This class implements presentation frames for Object Liveness Profiling.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic abstract class LivenessResultsPanel extends MemoryResultsPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String FILTER_MENU_ITEM_NAME = messages.getString(\"LivenessResultsPanel_FilterMenuItemName\"); // NOI18N\n    private static final String CLASS_COLUMN_NAME = messages.getString(\"LivenessResultsPanel_ClassColumnName\"); // NOI18N\n    private static final String LIVE_BYTES_REL_COLUMN_NAME = messages.getString(\"LivenessResultsPanel_LiveBytesRelColumnName\"); // NOI18N\n    private static final String LIVE_BYTES_COLUMN_NAME = messages.getString(\"LivenessResultsPanel_LiveBytesColumnName\"); // NOI18N\n    private static final String LIVE_OBJECTS_COLUMN_NAME = messages.getString(\"LivenessResultsPanel_LiveObjectsColumnName\"); // NOI18N\n    private static final String ALLOC_OBJECTS_COLUMN_NAME = messages.getString(\"LivenessResultsPanel_AllocObjectsColumnName\"); // NOI18N\n    private static final String AVG_AGE_COLUMN_NAME = messages.getString(\"LivenessResultsPanel_AvgAgeColumnName\"); // NOI18N\n    private static final String SURVGEN_COLUMN_NAME = messages.getString(\"LivenessResultsPanel_SurvGenColumnName\"); // NOI18N\n    private static final String TOTAL_ALLOC_OBJECTS_COLUMN_NAME = messages.getString(\"LivenessResultsPanel_TotalAllocObjectsColumnName\"); // NOI18N\n    private static final String CLASS_COLUMN_TOOLTIP = messages.getString(\"LivenessResultsPanel_ClassColumnToolTip\"); // NOI18N\n    private static final String LIVE_BYTES_REL_COLUMN_TOOLTIP = messages.getString(\"LivenessResultsPanel_LiveBytesRelColumnToolTip\"); // NOI18N\n    private static final String LIVE_BYTES_COLUMN_TOOLTIP = messages.getString(\"LivenessResultsPanel_LiveBytesColumnToolTip\"); // NOI18N\n    private static final String LIVE_OBJECTS_COLUMN_TOOLTIP = messages.getString(\"LivenessResultsPanel_LiveObjectsColumnToolTip\"); // NOI18N\n    private static final String ALLOC_OBJECTS_COLUMN_TOOLTIP = messages.getString(\"LivenessResultsPanel_AllocObjectsColumnToolTip\"); // NOI18N\n    private static final String AVG_AGE_COLUMN_TOOLTIP = messages.getString(\"LivenessResultsPanel_AvgAgeColumnToolTip\"); // NOI18N\n    private static final String SURVGEN_COLUMN_TOOLTIP = messages.getString(\"LivenessResultsPanel_SurvGenColumnToolTip\"); // NOI18N\n    private static final String TOTAL_ALLOC_OBJECTS_COLUMN_TOOLTIP = messages.getString(\"LivenessResultsPanel_TotalAllocObjectsColumnToolTip\"); // NOI18N\n    private static final String TABLE_ACCESS_NAME = messages.getString(\"LivenessResultsPanel_TableAccessName\"); // NOI18N    \n                                                                                                                // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected float[] avgObjectAge;\n    protected int[] maxSurvGen;\n    protected int[] nTotalAllocObjects; // # of allocated objects of each class\n    protected long[] nTrackedAllocObjects; // # of allocated objects of each class (just tracked)\n    protected int[] nTrackedLiveObjects; // # of live objects of each class\n    protected long[] trackedLiveObjectsSize; // Byte side of live objects of each class\n    protected int nInstrClasses;\n    protected long trackedAllocObjects;\n    protected long trackedLiveObjects;\n    protected long nTotalTracked;\n    protected long nTotalTrackedBytes;\n    private int initialSortingColumn;\n    private int minNamesColumnWidth; // minimal width of classnames columns\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public LivenessResultsPanel(MemoryResUserActionsHandler actionsHandler) {\n        super(actionsHandler);\n\n        setDefaultSorting();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /*\n     * @return value 1-100 of percentage of objects being tracked - to be used for column name rendering.\n     */\n\n    //  protected abstract int getPercentsTracked ();\n\n    // NOTE: this method only sets sortBy and sortOrder, it doesn't refresh UI!\n    public void setDefaultSorting() {\n        setSorting(1, SortableTableModel.SORT_ORDER_DESC);\n    }\n\n    // NOTE: this method only sets sortBy and sortOrder, it doesn't refresh UI!\n    public void setSorting(int sColumn, boolean sOrder) {\n        if (sColumn == CommonConstants.SORTING_COLUMN_DEFAULT) {\n            setDefaultSorting();\n        } else {\n            initialSortingColumn = sColumn;\n            sortBy = getSortBy(initialSortingColumn);\n            sortOrder = sOrder;\n        }\n    }\n\n    public int getSortingColumn() {\n        if (resTableModel == null) {\n            return CommonConstants.SORTING_COLUMN_DEFAULT;\n        }\n\n        return resTableModel.getRealColumn(resTableModel.getSortingColumn());\n    }\n\n    public boolean getSortingOrder() {\n        if (resTableModel == null) {\n            return false;\n        }\n\n        return resTableModel.getSortingOrder();\n    }\n\n    protected CustomBarCellRenderer getBarCellRenderer() {\n//        return new CustomBarCellRenderer(0, maxValue);\n        return new CustomBarCellRenderer(0, 100);\n    }\n\n    protected void getResultsSortedByAllocObj() {\n        getResultsSortedByClassName(true); // Added because of lines toggling when switching between columns 1 and 2.\n                                           // At first items must be sorted by class names to get defined initial state for\n                                           // other sorting.\n\n        int visibleLines = nInfoLines; // Zero or unprofiled classes are filtered, sorting will be applied only to live\n                                       // data\n\n        nInfoLines = sortResults(nTrackedAllocObjects, new int[][] { nTotalAllocObjects, nTrackedLiveObjects, maxSurvGen },\n                                 new long[][] { trackedLiveObjectsSize }, new float[][] { avgObjectAge }, 0, visibleLines, false);\n\n        totalAllocations = 0;\n        trackedLiveObjects = trackedAllocObjects = 0;\n\n        for (int i = 0; i < nInfoLines; i++) {\n            trackedLiveObjects += nTrackedLiveObjects[i];\n            trackedAllocObjects += nTrackedAllocObjects[i];\n            totalAllocations += nTotalAllocObjects[i];\n        }\n    }\n\n    protected void getResultsSortedByAvgAge() {\n        getResultsSortedByClassName(true); // Added because of lines toggling when switching between columns 1 and 2.\n                                           // At first items must be sorted by class names to get defined initial state for\n                                           // other sorting.\n\n        int visibleLines = nInfoLines; // Zero or unprofiled classes are filtered, sorting will be applied only to live\n                                       // data\n\n        nInfoLines = sortResults(avgObjectAge, new int[][] { nTotalAllocObjects, nTrackedLiveObjects, maxSurvGen },\n                                 new long[][] { trackedLiveObjectsSize, nTrackedAllocObjects }, 0, visibleLines, false);\n\n        totalAllocations = 0;\n        trackedLiveObjects = trackedAllocObjects = 0;\n\n        for (int i = 0; i < nInfoLines; i++) {\n            trackedLiveObjects += nTrackedLiveObjects[i];\n            trackedAllocObjects += nTrackedAllocObjects[i];\n            totalAllocations += nTotalAllocObjects[i];\n        }\n    }\n\n    protected void getResultsSortedByClassName(boolean presortOnly) {\n        // Sort classes by name, initially moving to the bottom elements that have zero allocated objects\n        nInfoLines = sortResultsByClassName(new int[][] { nTotalAllocObjects, nTrackedLiveObjects, maxSurvGen },\n                                            new long[][] { trackedLiveObjectsSize, nTrackedAllocObjects },\n                                            new float[][] { avgObjectAge }, //nInstrClasses, true);\n        nTrackedItems, truncateZeroItems());\n\n        if (!presortOnly) {\n            totalAllocations = 0;\n            trackedLiveObjects = trackedAllocObjects = 0;\n\n            for (int i = 0; i < nInfoLines; i++) {\n                trackedLiveObjects += nTrackedLiveObjects[i];\n                trackedAllocObjects += nTrackedAllocObjects[i];\n                totalAllocations += nTotalAllocObjects[i];\n            }\n        }\n    }\n\n    protected void getResultsSortedByLiveObjNumber() {\n        getResultsSortedByClassName(true); // Added because of lines toggling when switching between columns 1 and 2.\n                                           // At first items must be sorted by class names to get defined initial state for\n                                           // other sorting.\n\n        int visibleLines = nInfoLines; // Zero or unprofiled classes are filtered, sorting will be applied only to live\n                                       // data\n\n        // This will sort nTrackedLiveObjects, align with it the other arrays, and produce sortedClassNames and\n        // sortedClassIds\n        nInfoLines = sortResults(nTrackedLiveObjects, new int[][] { nTotalAllocObjects, maxSurvGen },\n                                 new long[][] { trackedLiveObjectsSize, nTrackedAllocObjects }, new float[][] { avgObjectAge },\n                                 0, visibleLines, false);\n\n        totalAllocations = 0;\n        trackedLiveObjects = trackedAllocObjects = 0;\n\n        for (int i = 0; i < nInfoLines; i++) {\n            trackedLiveObjects += nTrackedLiveObjects[i];\n            trackedAllocObjects += nTrackedAllocObjects[i];\n            totalAllocations += nTotalAllocObjects[i];\n        }\n    }\n\n    protected void getResultsSortedByLiveObjSize() {\n        getResultsSortedByClassName(true); // Added because of lines toggling when switching between columns 1 and 2.\n                                           // At first items must be sorted by class names to get defined initial state for\n                                           // other sorting.\n\n        int visibleLines = nInfoLines; // Zero or unprofiled classes are filtered, sorting will be applied only to live\n                                       // data\n\n        // This will sort trackedLiveObjectsSize, align with it nTrackedLiveObjects and nTotalAllocObjects, and produce\n        // sortedClassNames and sortedClassIds\n        nInfoLines = sortResults(trackedLiveObjectsSize, new int[][] { nTotalAllocObjects, nTrackedLiveObjects, maxSurvGen },\n                                 new long[][] { nTrackedAllocObjects }, new float[][] { avgObjectAge }, 0, visibleLines, false);\n\n        totalAllocations = 0;\n        trackedLiveObjects = trackedAllocObjects = 0;\n\n        for (int i = 0; i < nInfoLines; i++) {\n            trackedLiveObjects += nTrackedLiveObjects[i];\n            trackedAllocObjects += nTrackedAllocObjects[i];\n            totalAllocations += nTotalAllocObjects[i];\n        }\n    }\n\n    protected void getResultsSortedBySurvGen() {\n        getResultsSortedByClassName(true); // Added because of lines toggling when switching between columns 1 and 2.\n                                           // At first items must be sorted by class names to get defined initial state for\n                                           // other sorting.\n\n        int visibleLines = nInfoLines; // Zero or unprofiled classes are filtered, sorting will be applied only to live\n                                       // data\n\n        nInfoLines = sortResults(maxSurvGen, new int[][] { nTotalAllocObjects, nTrackedLiveObjects },\n                                 new long[][] { trackedLiveObjectsSize, nTrackedAllocObjects }, new float[][] { avgObjectAge },\n                                 0, visibleLines, false);\n\n        // Now sort each subgroup where the number of surviving generations is the same and > 0, by the total live obj size\n        int curSurvGen = maxSurvGen[0];\n        int top = 0;\n\n        while (curSurvGen > 0) {\n            int bottom = top;\n\n            while ((maxSurvGen[bottom] == curSurvGen) && (bottom < nInfoLines)) {\n                bottom++;\n            }\n\n            if (bottom > top) {\n                sortResults(trackedLiveObjectsSize, new int[][] { nTrackedLiveObjects, nTotalAllocObjects, maxSurvGen },\n                            new long[][] { nTrackedAllocObjects }, new float[][] { avgObjectAge }, top, bottom - top, false);\n                top = bottom;\n                curSurvGen = maxSurvGen[bottom];\n            }\n        }\n\n        totalAllocations = 0;\n        trackedLiveObjects = trackedAllocObjects = 0;\n\n        for (int i = 0; i < nInfoLines; i++) {\n            trackedLiveObjects += nTrackedLiveObjects[i];\n            trackedAllocObjects += nTrackedAllocObjects[i];\n            totalAllocations += nTotalAllocObjects[i];\n        }\n    }\n\n    protected void getResultsSortedByTotalAllocObj() {\n        getResultsSortedByClassName(true); // Added because of lines toggling when switching between columns 1 and 2.\n                                           // At first items must be sorted by class names to get defined initial state for\n                                           // other sorting.\n\n        int visibleLines = nInfoLines; // Zero or unprofiled classes are filtered, sorting will be applied only to live\n                                       // data\n\n        nInfoLines = sortResults(nTotalAllocObjects, new int[][] { nTrackedLiveObjects, maxSurvGen },\n                                 new long[][] { trackedLiveObjectsSize, nTrackedAllocObjects }, new float[][] { avgObjectAge },\n                                 0, visibleLines, false);\n\n        totalAllocations = 0;\n        trackedLiveObjects = trackedAllocObjects = 0;\n\n        for (int i = 0; i < nInfoLines; i++) {\n            trackedLiveObjects += nTrackedLiveObjects[i];\n            trackedAllocObjects += nTrackedAllocObjects[i];\n            totalAllocations += nTotalAllocObjects[i];\n        }\n    }\n\n    protected JExtendedTable getResultsTable() {\n        trackedLiveObjects = trackedAllocObjects = 0;\n        totalAllocations = 0;\n\n        sortResults();\n\n        if (resTable == null) {\n            resTableModel = new ExtendedTableModel(new SortableTableModel() {\n                    public String getColumnName(int col) {\n                        return columnNames[col];\n                    }\n\n                    public int getRowCount() {\n                        return nDisplayedItems;\n                    }\n\n                    public int getColumnCount() {\n                        return columnNames.length;\n                    }\n\n                    public Class<?> getColumnClass(int col) {\n                        // The main purpose of this method is to make numeric values aligned properly inside table cells\n                        return columnTypes[col];\n                    }\n\n                    public Object getValueAt(int row, int col) {\n                        return computeValueAt(row, col);\n                    }\n\n                    public String getColumnToolTipText(int col) {\n                        return columnToolTips[col];\n                    }\n\n                    public void sortByColumn(int column, boolean order) {\n                        sortBy = getSortBy(column);\n                        sortOrder = order;\n\n                        int selectedRow = resTable.getSelectedRow();\n                        String selectedRowContents = null;\n\n                        if (selectedRow != -1) {\n                            selectedRowContents = (String) resTable.getValueAt(selectedRow, 0);\n                        }\n\n                        prepareResults();\n\n                        if (selectedRowContents != null) {\n                            resTable.selectRowByContents(selectedRowContents, 0, true);\n                        }\n                    }\n\n                    /**\n                     * @param column The table column index\n                     * @return Initial sorting for the specified column - if true, ascending, if false descending\n                     */\n                    public boolean getInitialSorting(int column) {\n                        switch (column) {\n                            case 0:\n                                return true;\n                            default:\n                                return false;\n                        }\n                    }\n                });\n\n            resTableModel.setRealColumnVisibility(7, false);\n            resTableModel.setRealColumnVisibility(4, false);\n            resTableModel.setRealColumnVisibility(5, false);\n\n            resTable = new JExtendedTable(resTableModel) {\n                    public void doLayout() {\n                        int columnsWidthsSum = 0;\n                        int realFirstColumn = -1;\n\n                        int index;\n\n                        for (int i = 0; i < resTableModel.getColumnCount(); i++) {\n                            index = resTableModel.getRealColumn(i);\n\n                            if (index == 0) {\n                                realFirstColumn = i;\n                            } else {\n                                columnsWidthsSum += getColumnModel().getColumn(i).getPreferredWidth();\n                            }\n                        }\n\n                        if (realFirstColumn != -1) {\n                            getColumnModel().getColumn(realFirstColumn)\n                                .setPreferredWidth(Math.max(getWidth() - columnsWidthsSum, minNamesColumnWidth));\n                        }\n\n                        super.doLayout();\n                    }\n\n                };\n            resTable.getAccessibleContext().setAccessibleName(TABLE_ACCESS_NAME);\n\n            resTableModel.setTable(resTable);\n            resTableModel.setInitialSorting(initialSortingColumn, sortOrder);\n            resTable.setRowSelectionAllowed(true);\n            resTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n            resTable.setGridColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);\n            resTable.setSelectionBackground(UIConstants.TABLE_SELECTION_BACKGROUND_COLOR);\n            resTable.setSelectionForeground(UIConstants.TABLE_SELECTION_FOREGROUND_COLOR);\n            resTable.setShowHorizontalLines(UIConstants.SHOW_TABLE_HORIZONTAL_GRID);\n            resTable.setShowVerticalLines(UIConstants.SHOW_TABLE_VERTICAL_GRID);\n            resTable.setRowMargin(UIConstants.TABLE_ROW_MARGIN);\n            resTable.setRowHeight(UIUtils.getDefaultRowHeight() + 2);\n\n            // Disable traversing table cells using TAB and Shift+TAB\n            Set<AWTKeyStroke> keys = new HashSet<>(resTable.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));\n            keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));\n            resTable.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys);\n\n            keys = new HashSet<>(resTable.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));\n            keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));\n            resTable.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys);\n\n            setColumnsData();\n        }\n\n        return resTable;\n    }\n\n    protected Object computeValueAt(int row, int col) {\n        int index = ((Integer) filteredToFullIndexes.get(row)).intValue();\n\n        switch (col) {\n            case 0:\n                return sortedClassNames[index];\n            case 1:\n//                return new Long(trackedLiveObjectsSize[index]);\n                return (nTotalTrackedBytes == 0) ? 0 : (double)trackedLiveObjectsSize[index] / (double)nTotalTrackedBytes * 100;\n            case 2:\n                return intFormat.format(trackedLiveObjectsSize[index]) + \" B (\" // NOI18N\n                       + ((nTotalTrackedBytes == 0) ? \"-%\" //NOI18N\n                                                    : \n                percentFormat.format((float) trackedLiveObjectsSize[index] / (float) nTotalTrackedBytes)) + \")\"; // NOI18N\n            case 3:\n                return intFormat.format(nTrackedLiveObjects[index]) + \" (\" // NOI18N\n                       + ((nTotalTracked == 0) ? \"-%\"  //NOI18N\n                                               : \n                percentFormat.format((float) nTrackedLiveObjects[index] / (float) nTotalTracked)) + \")\"; // NOI18N\n            case 4:\n                return intFormat.format(nTrackedAllocObjects[index]);\n            case 5:\n                return StringUtils.floatPerCentToString(avgObjectAge[index]);\n            case 6:\n                return intFormat.format(maxSurvGen[index]);\n            case 7:\n                return intFormat.format(nTotalAllocObjects[index]);\n            default:\n                return null;\n        }\n    }\n\n    protected void initColumnSelectorItems() {\n        headerPopup.removeAll();\n\n        JCheckBoxMenuItem menuItem;\n\n        for (int i = 0; i < columnNames.length; i++) {\n            menuItem = new JCheckBoxMenuItem(columnNames[i]);\n            menuItem.setActionCommand(Integer.toString(i));\n            addMenuItemListener(menuItem);\n\n            if (resTable != null) {\n                menuItem.setState(resTableModel.isRealColumnVisible(i));\n\n                if (i == 0) {\n                    menuItem.setEnabled(false);\n                }\n            } else {\n                menuItem.setState(true);\n            }\n\n            headerPopup.add(menuItem);\n        }\n\n        headerPopup.addSeparator();\n\n        JCheckBoxMenuItem filterMenuItem = new JCheckBoxMenuItem(FILTER_MENU_ITEM_NAME);\n        filterMenuItem.setActionCommand(\"Filter\"); // NOI18N\n        addMenuItemListener(filterMenuItem);\n\n        if (filterComponent == null) {\n            filterMenuItem.setState(true);\n        } else {\n            filterMenuItem.setState(filterComponent.getComponent().isVisible());\n        }\n\n        headerPopup.add(filterMenuItem);\n\n        headerPopup.pack();\n    }\n\n    protected void initColumnsData() {\n        int maxWidth = getFontMetrics(getFont()).charWidth('W') * 10; // NOI18N // initial width of data columns\n        minNamesColumnWidth = getFontMetrics(getFont()).charWidth('W') * 30; // NOI18N\n\n        ClassNameTableCellRenderer classNameTableCellRenderer = new ClassNameTableCellRenderer();\n        LabelTableCellRenderer labelTableCellRenderer = new LabelTableCellRenderer(JLabel.TRAILING);\n        LabelBracketTableCellRenderer labelBracketTableCellRenderer = new LabelBracketTableCellRenderer(JLabel.TRAILING);\n\n        columnNames = new String[] {\n                          CLASS_COLUMN_NAME, // - \" + getPercentsTracked() + \"% Tracked\",\n        LIVE_BYTES_REL_COLUMN_NAME, LIVE_BYTES_COLUMN_NAME, LIVE_OBJECTS_COLUMN_NAME, ALLOC_OBJECTS_COLUMN_NAME,\n                          AVG_AGE_COLUMN_NAME, SURVGEN_COLUMN_NAME, TOTAL_ALLOC_OBJECTS_COLUMN_NAME\n                      };\n\n        columnToolTips = new String[] {\n                             CLASS_COLUMN_TOOLTIP, // - \"+getPercentsTracked()+\"% of all allocated objets are displayed\\\",\",\n        LIVE_BYTES_REL_COLUMN_TOOLTIP, // - \"+getPercentsTracked()+\"% Tracked\",\n        LIVE_BYTES_COLUMN_TOOLTIP, // - \"+getPercentsTracked()+\"% Tracked\",\n        LIVE_OBJECTS_COLUMN_TOOLTIP, // - \"+getPercentsTracked()+\"% Tracked\",\n        ALLOC_OBJECTS_COLUMN_TOOLTIP, // - \"+getPercentsTracked()+\"% Tracked\",\n        AVG_AGE_COLUMN_TOOLTIP, // - \"+getPercentsTracked()+\"% Tracked\",\n        SURVGEN_COLUMN_TOOLTIP, // - \"+ getPercentsTracked()+\"% Tracked\",\n        TOTAL_ALLOC_OBJECTS_COLUMN_TOOLTIP\n                         };\n        columnTypes = new Class[] {\n                          String.class, Number.class, String.class, String.class, String.class, Number.class, Number.class,\n                          String.class\n                      };\n        columnRenderers = new TableCellRenderer[] {\n                              classNameTableCellRenderer, null, labelBracketTableCellRenderer, labelBracketTableCellRenderer,\n                              labelTableCellRenderer, labelTableCellRenderer, labelTableCellRenderer, labelTableCellRenderer\n                          };\n        columnWidths = new int[] { maxWidth + 15, maxWidth, maxWidth, maxWidth, maxWidth, maxWidth, maxWidth, maxWidth };\n    }\n\n    protected boolean passesValueFilter(int i) {\n        return ((((double) trackedLiveObjectsSize[i] / (double) nTotalTrackedBytes) * 100f) >= valueFilterValue);\n    }\n\n    private void setColumnsData() {\n        barRenderer = getBarCellRenderer();\n\n        TableColumnModel colModel = resTable.getColumnModel();\n        colModel.getColumn(0).setPreferredWidth(minNamesColumnWidth);\n\n        int index;\n\n        for (int i = 0; i < colModel.getColumnCount(); i++) {\n            index = resTableModel.getRealColumn(i);\n\n            if (index == 0) {\n                colModel.getColumn(i).setPreferredWidth(minNamesColumnWidth);\n            } else {\n                colModel.getColumn(i).setPreferredWidth(columnWidths[index - 1]);\n            }\n\n            if (index == 1) {\n                colModel.getColumn(i).setCellRenderer(barRenderer);\n            } else {\n                colModel.getColumn(i).setCellRenderer(columnRenderers[index]);\n            }\n        }\n    }\n\n    private int getSortBy(int column) {\n        switch (column) {\n            case 0:\n                return PresoObjLivenessCCTNode.SORT_BY_NAME;\n            case 1:\n                return PresoObjLivenessCCTNode.SORT_BY_LIVE_OBJ_SIZE;\n            case 2:\n                return PresoObjLivenessCCTNode.SORT_BY_LIVE_OBJ_SIZE;\n            case 3:\n                return PresoObjLivenessCCTNode.SORT_BY_LIVE_OBJ_NUMBER;\n            case 4:\n                return PresoObjLivenessCCTNode.SORT_BY_ALLOC_OBJ;\n            case 5:\n                return PresoObjLivenessCCTNode.SORT_BY_AVG_AGE;\n            case 6:\n                return PresoObjLivenessCCTNode.SORT_BY_SURV_GEN;\n            case 7:\n                return PresoObjLivenessCCTNode.SORT_BY_TOTAL_ALLOC_OBJ;\n        }\n\n        return PresoObjLivenessCCTNode.SORT_BY_LIVE_OBJ_SIZE;\n    }\n\n    private void addMenuItemListener(JCheckBoxMenuItem menuItem) {\n        menuItem.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    if (e.getActionCommand().equals(\"Filter\")) { // NOI18N\n                        filterComponent.getComponent().setVisible(!filterComponent.getComponent().isVisible());\n\n                        // TODO [ui-persistence]\n                        return;\n                    }\n\n                    saveColumnsData();\n\n                    boolean sortResults = false;\n                    int column = Integer.parseInt(e.getActionCommand());\n                    int sortingColumn = resTableModel.getSortingColumn();\n                    int realSortingColumn = resTableModel.getRealColumn(sortingColumn);\n                    boolean isColumnVisible = resTableModel.isRealColumnVisible(column);\n\n                    // Current sorting column is going to be hidden\n                    if ((isColumnVisible) && (column == realSortingColumn)) {\n                        // Try to set next column as a sortingColumn. If currentSortingColumn is the last column, set previous\n                        // column as a sorting Column (one column is always visible).\n                        sortingColumn = ((sortingColumn + 1) == resTableModel.getColumnCount()) ? (sortingColumn - 1)\n                                                                                                : (sortingColumn + 1);\n                        realSortingColumn = resTableModel.getRealColumn(sortingColumn);\n                        sortResults = true;\n                    }\n\n                    resTableModel.setRealColumnVisibility(column, !isColumnVisible);\n                    resTable.createDefaultColumnsFromModel();\n                    resTableModel.setTable(resTable);\n                    sortingColumn = resTableModel.getVirtualColumn(realSortingColumn);\n\n                    if (sortResults) {\n                        sortOrder = resTableModel.getInitialSorting(sortingColumn);\n                        sortBy = getSortBy(realSortingColumn);\n                        sortResults();\n                        resTable.repaint();\n                    }\n\n                    resTableModel.setInitialSorting(sortingColumn, sortOrder);\n                    resTable.getTableHeader().repaint();\n\n                    setColumnsData();\n\n                    // TODO [ui-persistence]\n                }\n            });\n    }\n\n    private void saveColumnsData() {\n        int index;\n        TableColumnModel colModel = resTable.getColumnModel();\n\n        for (int i = 0; i < resTableModel.getColumnCount(); i++) {\n            index = resTableModel.getRealColumn(i);\n\n            if (index != 0) {\n                columnWidths[index - 1] = colModel.getColumn(i).getPreferredWidth();\n            }\n        }\n    }\n\n    private void sortResults() {\n        switch (sortBy) {\n            case PresoObjLivenessCCTNode.SORT_BY_NAME:\n                getResultsSortedByClassName(false);\n\n                break;\n            case PresoObjLivenessCCTNode.SORT_BY_LIVE_OBJ_SIZE:\n                getResultsSortedByLiveObjSize();\n\n                break;\n            case PresoObjLivenessCCTNode.SORT_BY_LIVE_OBJ_NUMBER:\n                getResultsSortedByLiveObjNumber();\n\n                break;\n            case PresoObjLivenessCCTNode.SORT_BY_ALLOC_OBJ:\n                getResultsSortedByAllocObj();\n\n                break;\n            case PresoObjLivenessCCTNode.SORT_BY_AVG_AGE:\n                getResultsSortedByAvgAge();\n\n                break;\n            case PresoObjLivenessCCTNode.SORT_BY_SURV_GEN:\n                getResultsSortedBySurvGen();\n\n                break;\n            case PresoObjLivenessCCTNode.SORT_BY_TOTAL_ALLOC_OBJ:\n                getResultsSortedByTotalAllocObj();\n\n                break;\n        }\n\n        createFilteredIndexes();\n    }\n\n    public void exportData(int typeOfFile, ExportDataDumper eDD, String viewName) {\n        intFormat.setMaximumFractionDigits(2);\n        intFormat.setMinimumFractionDigits(2);\n        switch (typeOfFile) {\n            case 1: exportCSV(\",\", eDD); break; // NOI18N\n            case 2: exportCSV(\";\", eDD); break; // NOI18N\n            case 3: exportXML(eDD, viewName); break;\n            case 4: exportHTML(eDD, viewName); break;\n        }\n        intFormat.setMaximumFractionDigits(1);\n        intFormat.setMinimumFractionDigits(0);\n    }\n\n    private void exportHTML(ExportDataDumper eDD, String viewName) {\n         // Header\n        StringBuffer result = new StringBuffer(\"<HTML><HEAD><meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" /><TITLE>\"+viewName+\"</TITLE></HEAD><BODY><TABLE border=\\\"1\\\"><tr>\"); // NOI18N\n        for (int i = 0; i < (columnNames.length-1); i++) {\n            if (!(columnRenderers[i]==null)) {\n                result.append(\"<th>\").append(columnNames[i]).append(\"</th>\"); // NOI18N\n            }\n        }\n        result.append(\"</tr>\"); // NOI18N\n        eDD.dumpData(result);\n\n        for (int i=0; i < nTrackedItems; i++) {\n\n            result = new StringBuffer(\"<tr><td>\"+replaceHTMLCharacters(sortedClassNames[i])+\"</td>\"); // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(trackedLiveObjectsSize[i]).append(\"</td>\"); // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(nTrackedLiveObjects[i]).append(\"</td>\"); // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(nTrackedAllocObjects[i]).append(\"</td>\"); // NOI18N\n            result.append(\"<td align=\\\"char\\\" char=\\\".\\\">\").append(intFormat.format(avgObjectAge[i])).append(\"</td>\"); // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(maxSurvGen[i]).append(\"</td></tr>\"); // NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TABLE></BODY></HTML>\")); // NOI18N\n    }\n\n    private void exportXML(ExportDataDumper eDD, String viewName) {\n         // Header\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"+newline+\"<ExportedView Name=\\\"\"+viewName+\"\\\">\"+newline); // NOI18N\n        result.append(\" <TableData NumRows=\\\"\").append(nTrackedItems).append(\"\\\" NumColumns=\\\"6\\\">\").append(newline); // NOI18N\n        result.append(\"<TableHeader>\"); // NOI18N\n        for (int i = 0; i < (columnNames.length-1); i++) {\n            if (!(columnRenderers[i]==null)) {\n                result.append(\"  <TableColumn><![CDATA[\").append(columnNames[i]).append(\"]]></TableColumn>\").append(newline); // NOI18N\n            }\n        }\n        result.append(\"</TableHeader>\"); // NOI18N\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer(\"  <TableRow>\"+newline);\n            result.append(\"   <TableColumn><![CDATA[\").append(sortedClassNames[i]).append(\"]]></TableColumn>\").append(newline);\n            result.append(\"   <TableColumn><![CDATA[\").append(trackedLiveObjectsSize[i]).append(\"]]></TableColumn>\").append(newline);\n            result.append(\"   <TableColumn><![CDATA[\").append(nTrackedLiveObjects[i]).append(\"]]></TableColumn>\").append(newline);\n            result.append(\"   <TableColumn><![CDATA[\").append(nTrackedAllocObjects[i]).append(\"]]></TableColumn>\").append(newline);\n            result.append(\"   <TableColumn><![CDATA[\").append(intFormat.format(avgObjectAge[i])).append(\"]]></TableColumn>\").append(newline);\n            result.append(\"   <TableColumn><![CDATA[\").append(maxSurvGen[i]).append(\"]]></TableColumn>\").append(newline).append(\"  </TableRow>\").append(newline);\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TableData>\"+newline+\"</ExportedView>\"));\n    }\n\n    private void exportCSV(String separator, ExportDataDumper eDD) {\n        // Header\n        StringBuffer result = new StringBuffer();\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n\n        for (int i = 0; i < (columnNames.length-1); i++) {\n            if (!(columnRenderers[i]==null)) {\n                result.append(quote).append(columnNames[i]).append(quote).append(separator);\n            }\n        }\n        result.deleteCharAt(result.length()-1);\n        result.append(newLine);\n        eDD.dumpData(result);\n\n        // Data\n        \n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer();\n            result.append(quote).append(sortedClassNames[i]).append(quote).append(separator);\n            result.append(quote).append(trackedLiveObjectsSize[i]).append(quote).append(separator);\n            result.append(quote).append(nTrackedLiveObjects[i]).append(quote).append(separator);\n            result.append(quote).append(nTrackedAllocObjects[i]).append(quote).append(separator);\n            result.append(quote).append(intFormat.format(avgObjectAge[i])).append(quote).append(separator);\n            result.append(quote).append(maxSurvGen[i]).append(quote).append(newLine);\n            eDD.dumpData(result);\n        }\n        eDD.close();\n    }\n\n    private String replaceHTMLCharacters(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break;\n              case '>': sb.append(\"&gt;\"); break;\n              case '&': sb.append(\"&amp;\"); break;\n              case '\"': sb.append(\"&quot;\"); break;\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/LivenessTableView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.BorderLayout;\nimport java.text.Format;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.JLabel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.RowFilter;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.LivenessMemoryResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.LivenessMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.CheckBoxRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class LivenessTableView extends MemoryView {\n\n    private MemoryTableModel tableModel;\n    private ProfilerTable table;\n\n    private int nTrackedItems;\n    private ClientUtils.SourceCodeSelection[] classNames;\n    private int[] nTrackedLiveObjects;\n    private long[] trackedLiveObjectsSize;\n    private long[] nTrackedAllocObjects;\n    private float[] avgObjectAge;\n    private int[] maxSurvGen;\n    private int[] nTotalAllocObjects;\n    \n    private final Set<ClientUtils.SourceCodeSelection> selection;\n    \n    private final boolean includeTotalAllocs;\n    \n    private boolean filterZeroItems = true;\n    \n    \n    LivenessTableView(Set<ClientUtils.SourceCodeSelection> selection, boolean includeTotalAllocs) {\n        this.selection = selection;\n        \n        this.includeTotalAllocs = includeTotalAllocs;\n        \n        initUI();\n    }\n    \n    \n    protected ProfilerTable getResultsComponent() { return table; }\n    \n    \n    private void setData(final int _nTrackedItems, final String[] _classNames,\n                 final int[] _nTrackedLiveObjects, final long[] _trackedLiveObjectsSize,\n                 final long[] _nTrackedAllocObjects, final float[] _avgObjectAge,\n                 final int[] _maxSurvGen, final int[] _nTotalAllocObjects, final boolean diff) {\n        \n        // TODO: show classes with zero instances in live results!\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (tableModel != null) {\n                    nTrackedItems = _nTrackedItems;\n                    classNames = new ClientUtils.SourceCodeSelection[_classNames.length];\n                    for (int i = 0; i < classNames.length; i++)\n                        classNames[i] = new ClientUtils.SourceCodeSelection(_classNames[i], Wildcards.ALLWILDCARD, null);\n                    nTrackedLiveObjects = _nTrackedLiveObjects;\n                    trackedLiveObjectsSize = _trackedLiveObjectsSize;\n                    nTrackedAllocObjects = _nTrackedAllocObjects;\n                    avgObjectAge = _avgObjectAge;\n                    maxSurvGen = _maxSurvGen;\n                    if (includeTotalAllocs) nTotalAllocObjects = _nTotalAllocObjects;\n                    \n                    long liveBytes = 0;\n                    long _liveBytes = 0;\n                    long liveObjects = 0;\n                    long _liveObjects = 0;\n                    long allocObjects = 0;\n                    long _allocObjects = 0;\n                    long totalAllocObjects = 0;\n                    long _totalAllocObjects = 0;\n                    for (int i = 0; i < nTrackedItems; i++) {\n                        if (diff) {\n                            liveBytes = Math.max(liveBytes, trackedLiveObjectsSize[i]);\n                            _liveBytes = Math.min(_liveBytes, trackedLiveObjectsSize[i]);\n                            liveObjects = Math.max(liveObjects, nTrackedLiveObjects[i]);\n                            _liveObjects = Math.min(_liveObjects, nTrackedLiveObjects[i]);\n                            allocObjects = Math.max(allocObjects, nTrackedAllocObjects[i]);\n                            _allocObjects = Math.min(_allocObjects, nTrackedAllocObjects[i]);\n                            if (includeTotalAllocs) {\n                                totalAllocObjects = Math.max(totalAllocObjects, nTotalAllocObjects[i]);\n                                _totalAllocObjects = Math.min(_totalAllocObjects, nTotalAllocObjects[i]);\n                            }\n                        } else {\n                            liveBytes += trackedLiveObjectsSize[i];\n                            liveObjects += nTrackedLiveObjects[i];\n                            allocObjects += nTrackedAllocObjects[i];\n                            if (includeTotalAllocs) totalAllocObjects += nTotalAllocObjects[i];\n                        }\n                    }\n                    if (diff) {\n                        renderers[0].setMaxValue(Math.max(Math.abs(liveBytes), Math.abs(_liveBytes)));\n                        renderers[1].setMaxValue(Math.max(Math.abs(liveObjects), Math.abs(_liveObjects)));\n                        renderers[2].setMaxValue(Math.max(Math.abs(allocObjects), Math.abs(_allocObjects)));\n                        if (includeTotalAllocs) renderers[3].setMaxValue(Math.max(Math.abs(totalAllocObjects), Math.abs(_totalAllocObjects)));\n                    } else {\n                        renderers[0].setMaxValue(liveBytes);\n                        renderers[1].setMaxValue(liveObjects);\n                        renderers[2].setMaxValue(allocObjects);\n                        if (includeTotalAllocs) renderers[3].setMaxValue(totalAllocObjects);\n                    }\n                    \n                    renderers[0].setDiffMode(diff);\n                    renderers[1].setDiffMode(diff);\n                    renderers[2].setDiffMode(diff);\n                    if (includeTotalAllocs) renderers[3].setDiffMode(diff);\n                    \n                    renderersEx[0].setDiffMode(diff);\n                    renderersEx[1].setDiffMode(diff);\n                    \n                    tableModel.fireTableDataChanged();\n                }\n            }\n        });\n    }\n    \n    public void setData(MemoryResultsSnapshot snapshot, GenericFilter filter, int aggregation) {\n        LivenessMemoryResultsSnapshot _snapshot = (LivenessMemoryResultsSnapshot)snapshot;\n        boolean diff = _snapshot instanceof LivenessMemoryResultsDiff;\n        \n        String[] _classNames = _snapshot.getClassNames();\n        int[] _nTrackedLiveObjects = _snapshot.getNTrackedLiveObjects();\n        long[] _trackedLiveObjectsSize = _snapshot.getTrackedLiveObjectsSize();\n        long[] _nTrackedAllocObjects = _snapshot.getNTrackedAllocObjects();\n        float[] _avgObjectAge = _snapshot.getAvgObjectAge();\n        int[] _maxSurvGen = _snapshot.getMaxSurvGen();\n        int[] _nTotalAllocObjects = _snapshot.getnTotalAllocObjects();\n        \n        int _nTrackedItems = Math.min(_snapshot.getNProfiledClasses(), _classNames.length);\n        _nTrackedItems = Math.min(_nTrackedItems, _nTotalAllocObjects.length);\n            \n        if (filter == null) { // old snapshot\n            filterZeroItems = !diff;\n            \n            setData(_nTrackedItems, _classNames, _nTrackedLiveObjects, _trackedLiveObjectsSize,\n                _nTrackedAllocObjects, _avgObjectAge, _maxSurvGen, _nTotalAllocObjects, diff);\n        } else { // new snapshot or live results\n            filterZeroItems = false;\n            \n            List<String> fClassNames = new ArrayList<>();\n            List<Integer> fTrackedLiveObjects = new ArrayList<>();\n            List<Long> fTrackedLiveObjectsSize = new ArrayList<>();\n            List<Long> fTrackedAllocObjects = new ArrayList<>();\n            List<Float> fAvgObjectAge = new ArrayList<>();\n            List<Integer> fMaxSurvGen = new ArrayList<>();\n//            List<Integer> fTotalAllocObjects = new ArrayList();\n\n            for (int i = 0; i < _nTrackedItems; i++) {\n                if (filter.passes(_classNames[i].replace('.', '/'))) { // NOI18N\n                    fClassNames.add(_classNames[i]);\n                    fTrackedLiveObjects.add(_nTrackedLiveObjects[i]);\n                    fTrackedLiveObjectsSize.add(_trackedLiveObjectsSize[i]);\n                    fTrackedAllocObjects.add(_nTrackedAllocObjects[i]);\n                    fAvgObjectAge.add(_avgObjectAge[i]);\n                    fMaxSurvGen.add(_maxSurvGen[i]);\n//                    fTotalAllocObjects.add(_nTotalAllocObjects[i]);\n                }\n            }\n            \n            int trackedItems = fClassNames.size();\n            String[] aClassNames = fClassNames.toArray(new String[0]);\n            \n            int[] aTrackedLiveObjects = new int[trackedItems];\n            for (int i = 0; i < trackedItems; i++) aTrackedLiveObjects[i] = fTrackedLiveObjects.get(i);\n            \n            long[] aTrackedLiveObjectsSize = new long[trackedItems];\n            for (int i = 0; i < trackedItems; i++) aTrackedLiveObjectsSize[i] = fTrackedLiveObjectsSize.get(i);\n            \n            long[] aTrackedAllocObjects = new long[trackedItems];\n            for (int i = 0; i < trackedItems; i++) aTrackedAllocObjects[i] = fTrackedAllocObjects.get(i);\n            \n            float[] aAvgObjectAge = new float[trackedItems];\n            for (int i = 0; i < trackedItems; i++) aAvgObjectAge[i] = fAvgObjectAge.get(i);\n            \n//            int[] aTotalAllocObjectsSize = new int[trackedItems];\n//            for (int i = 0; i < trackedItems; i++) aTotalAllocObjectsSize[i] = fTotalAllocObjects.get(i);\n            \n            int[] aMaxSurvGen = new int[trackedItems];\n            for (int i = 0; i < trackedItems; i++) aMaxSurvGen[i] = fMaxSurvGen.get(i);\n            \n            setData(trackedItems, aClassNames, aTrackedLiveObjects, aTrackedLiveObjectsSize,\n                aTrackedAllocObjects, aAvgObjectAge, aMaxSurvGen, /*aTotalAllocObjectsSize*/_nTotalAllocObjects, diff);\n        }\n    }\n    \n    public void resetData() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                nTrackedItems = 0;\n                classNames = null;\n                nTrackedLiveObjects = null;\n                trackedLiveObjectsSize = null;\n                nTrackedAllocObjects = null;\n                avgObjectAge = null;\n                maxSurvGen = null;\n                nTotalAllocObjects = null;\n                \n                renderers[0].setMaxValue(0);\n                renderers[1].setMaxValue(0);\n                renderers[2].setMaxValue(0);\n                if (includeTotalAllocs) renderers[3].setMaxValue(0);\n\n                renderers[0].setDiffMode(false);\n                renderers[1].setDiffMode(false);\n                renderers[2].setDiffMode(false);\n                if (includeTotalAllocs) renderers[3].setDiffMode(false);\n\n                renderersEx[0].setDiffMode(false);\n                renderersEx[1].setDiffMode(false);\n                \n                tableModel.fireTableDataChanged();\n            }\n        });\n    }\n    \n    \n    public void showSelectionColumn() {\n        table.setColumnVisibility(0, true);\n    }\n    \n    public void refreshSelection() {\n        tableModel.fireTableDataChanged();\n    }\n    \n    \n    public ExportUtils.ExportProvider[] getExportProviders() {\n        return table.getRowCount() == 0 ? null : new ExportUtils.ExportProvider[] {\n            new ExportUtils.CSVExportProvider(table),\n            new ExportUtils.HTMLExportProvider(table, EXPORT_ALLOCATED_LIVE),\n            new ExportUtils.XMLExportProvider(table, EXPORT_ALLOCATED_LIVE),\n            new ExportUtils.PNGExportProvider(table)\n        };\n    }\n    \n    \n    protected abstract void performDefaultAction(ClientUtils.SourceCodeSelection userValue);\n    \n    protected abstract void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue);\n    \n    protected void popupShowing() {}\n    \n    protected void popupHidden()  {}\n    \n    \n    private HideableBarRenderer[] renderers;\n    private NumberRenderer[] renderersEx;\n    \n    private void initUI() {\n        final int offset = selection == null ? -1 : 0;\n        \n        tableModel = new MemoryTableModel();\n        \n        table = new ProfilerTable(tableModel, true, true, null) {\n            public ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n                return LivenessTableView.this.getUserValueForRow(row);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                LivenessTableView.this.populatePopup(popup, value, (ClientUtils.SourceCodeSelection)userValue);\n            }\n            protected void popupShowing() {\n                LivenessTableView.this.popupShowing();\n            }\n            protected void popupHidden() {\n                LivenessTableView.this.popupHidden();\n            }\n        };\n        \n        table.setColumnToolTips(selection == null ? new String[] {\n                                  NAME_COLUMN_TOOLTIP,\n                                  LIVE_SIZE_COLUMN_TOOLTIP,\n                                  LIVE_COUNT_COLUMN_TOOLTIP,\n                                  ALLOC_COUNT_COLUMN_TOOLTIP,\n                                  AVG_AGE_COLUMN_TOOLTIP,\n                                  GENERATIONS_COLUMN_TOOLTIP,\n                                  TOTAL_ALLOC_COUNT_COLUMN_TOOLTIP\n                                } : new String[] {\n                                  SELECTED_COLUMN_TOOLTIP,\n                                  NAME_COLUMN_TOOLTIP,\n                                  LIVE_SIZE_COLUMN_TOOLTIP,\n                                  LIVE_COUNT_COLUMN_TOOLTIP,\n                                  ALLOC_COUNT_COLUMN_TOOLTIP,\n                                  AVG_AGE_COLUMN_TOOLTIP,\n                                  GENERATIONS_COLUMN_TOOLTIP,\n                                  TOTAL_ALLOC_COUNT_COLUMN_TOOLTIP\n                                });\n        \n        table.providePopupMenu(true);\n        installDefaultAction();\n        \n        table.setMainColumn(1 + offset);\n        table.setFitWidthColumn(1 + offset);\n        \n        table.setSortColumn(2 + offset);\n        table.setDefaultSortOrder(1 + offset, SortOrder.ASCENDING);\n        \n        if (selection != null) table.setColumnVisibility(0, false);\n        table.setColumnVisibility(5 + offset, false);\n        if (includeTotalAllocs) table.setColumnVisibility(7 + offset, false);\n        \n        // Filter out classes with no instances\n        table.addRowFilter(new RowFilter() {\n            public boolean include(RowFilter.Entry entry) {\n                return !filterZeroItems || ((Number)entry.getValue(/*5*/4 + offset)).intValue() > 0;\n            }\n        });\n        \n        renderers = new HideableBarRenderer[4];\n        renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(Formatters.bytesFormat()));\n        renderers[1] = new HideableBarRenderer(new NumberPercentRenderer());\n        renderers[2] = new HideableBarRenderer(new NumberPercentRenderer());\n        renderers[3] = new HideableBarRenderer(new NumberPercentRenderer());\n        \n        renderers[0].setMaxValue(123456789);\n        renderers[1].setMaxValue(12345678);\n        renderers[2].setMaxValue(12345678);\n        renderers[3].setMaxValue(12345678);\n        \n        renderersEx = new NumberRenderer[2];\n        renderersEx[0] = new NumberRenderer() {\n            protected String getValueString(Object value, int row, Format format) {\n                if (value == null) return \"-\"; // NOI18N\n                float _value = ((Float)value).floatValue();\n                String s = StringUtils.floatPerCentToString(_value);\n                if (renderingDiff && _value >= 0) s = '+' + s; // NOI18N\n                return s;\n            }\n        };\n        renderersEx[1] = new NumberRenderer();\n        \n        if (selection != null) table.setColumnRenderer(0, new CheckBoxRenderer());\n        table.setColumnRenderer(1 + offset, new JavaNameRenderer(Icons.getIcon(LanguageIcons.CLASS)));\n        table.setColumnRenderer(2 + offset, renderers[0]);\n        table.setColumnRenderer(3 + offset, renderers[1]);\n        table.setColumnRenderer(4 + offset, renderers[2]);\n        table.setColumnRenderer(5 + offset, renderersEx[0]);\n        table.setColumnRenderer(6 + offset, renderersEx[1]);\n        if (includeTotalAllocs) table.setColumnRenderer(7 + offset, renderers[3]);\n        \n        if (selection != null) {\n            int w = new JLabel(table.getColumnName(0)).getPreferredSize().width;\n            table.setDefaultColumnWidth(0, w + 15);\n        }\n        table.setDefaultColumnWidth(2 + offset, renderers[0].getOptimalWidth());\n        table.setDefaultColumnWidth(3 + offset, renderers[1].getMaxNoBarWidth());\n        table.setDefaultColumnWidth(4 + offset, renderers[2].getMaxNoBarWidth());\n        table.setDefaultColumnWidth(5 + offset, renderers[2].getNoBarWidth() - 25);\n        table.setDefaultColumnWidth(6 + offset, renderers[2].getNoBarWidth() - 25);\n        if (includeTotalAllocs) table.setDefaultColumnWidth(7 + offset, renderers[3].getMaxNoBarWidth());\n        \n        ProfilerTableContainer tableContainer = new ProfilerTableContainer(table, false, null);\n        \n        setLayout(new BorderLayout());\n        add(tableContainer, BorderLayout.CENTER);\n    }\n    \n    \n    protected ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n        if (nTrackedItems == 0 || row == -1) return null;\n        if (row >= tableModel.getRowCount()) return null; // #239936\n        return classNames[table.convertRowIndexToModel(row)];\n    }\n    \n    \n    private class MemoryTableModel extends AbstractTableModel {\n        \n        private final int columns = 6 +\n                (selection == null ? 0 : 1) +\n                (includeTotalAllocs ? 1 : 0);\n        \n        public String getColumnName(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return COLUMN_NAME;\n            } else if (columnIndex == 2) {\n                return COLUMN_LIVE_BYTES;\n            } else if (columnIndex == 3) {\n                return COLUMN_LIVE_OBJECTS;\n            } else if (columnIndex == 4) {\n                return COLUMN_ALLOCATED_OBJECTS;\n            } else if (columnIndex == 5) {\n                return COLUMN_AVG_AGE;\n            } else if (columnIndex == 6) {\n                return COLUMN_GENERATIONS;\n            } else if (columnIndex == 7) {\n                return COLUMN_TOTAL_ALLOCATED_OBJECTS;\n            } else if (columnIndex == 0) {\n                return COLUMN_SELECTED;\n            }\n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return String.class;\n            } else if (columnIndex == 2) {\n                return Long.class;\n            } else if (columnIndex == 3) {\n                return Integer.class;\n            } else if (columnIndex == 4) {\n                return Long.class;\n            } else if (columnIndex == 5) {\n                return Float.class;\n            } else if (columnIndex == 6) {\n                return Integer.class;\n            } else if (columnIndex == 7) {\n                return Integer.class;\n            } else if (columnIndex == 0) {\n                return Boolean.class;\n            }\n            return null;\n        }\n        \n        public int getRowCount() {\n            return nTrackedItems;\n        }\n\n        public int getColumnCount() {\n            return columns;\n        }\n\n        public Object getValueAt(int rowIndex, int columnIndex) {\n            if (nTrackedItems == 0) return null;\n            \n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return classNames[rowIndex].getClassName();\n            } else if (columnIndex == 2) {\n                return trackedLiveObjectsSize[rowIndex];\n            } else if (columnIndex == 3) {\n                return nTrackedLiveObjects[rowIndex];\n            } else if (columnIndex == 4) {\n                return nTrackedAllocObjects[rowIndex];\n            } else if (columnIndex == 5) {\n                return avgObjectAge[rowIndex];\n            } else if (columnIndex == 6) {\n                return maxSurvGen[rowIndex];\n            } else if (columnIndex == 7) {\n                return nTotalAllocObjects[rowIndex];\n            } else if (columnIndex == 0) {\n                if (selection.isEmpty()) return Boolean.FALSE;\n                return selection.contains(classNames[rowIndex]);\n            }\n\n            return null;\n        }\n\n        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 0) {\n                if (Boolean.FALSE.equals(aValue)) selection.remove(classNames[rowIndex]);\n                else selection.add(classNames[rowIndex]);\n            }\n        }\n\n        public boolean isCellEditable(int rowIndex, int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            return columnIndex == 0;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/LivenessTreeTableView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Graphics;\nimport java.awt.event.ActionEvent;\nimport java.text.Format;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.swing.AbstractAction;\nimport javax.swing.Box;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JLabel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JTree;\nimport javax.swing.RowFilter;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.tree.TreeNode;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.LivenessMemoryResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.LivenessMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCCTManager;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjLivenessCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.CheckBoxRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class LivenessTreeTableView extends MemoryView {\n    \n    private LivenessTreeTableModel treeTableModel;\n    private ProfilerTreeTable treeTable;\n    \n    private Map<TreeNode, ClientUtils.SourceCodeSelection> nodesMap;\n    private final Set<ClientUtils.SourceCodeSelection> selection;\n    \n    private final boolean includeTotalAllocs;\n    \n    private boolean filterObjects = true;\n    private boolean filterAllocations = false;\n    private boolean searchObjects = true;\n    private boolean searchAllocations = false;\n    \n    \n    LivenessTreeTableView(Set<ClientUtils.SourceCodeSelection> selection, boolean includeTotalAllocs) {\n        this.selection = selection;\n        \n        this.includeTotalAllocs = includeTotalAllocs;\n        \n        initUI();\n    }\n    \n    \n    protected RowFilter getExcludesFilter() {\n        return new RowFilter() { // Do not filter first level nodes\n            public boolean include(RowFilter.Entry entry) {\n                PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)entry.getIdentifier();\n                CCTNode parent = node.getParent();\n                if (parent == null) return true;\n                if (parent.getParent() == null) return !filterObjects;\n                return !filterAllocations;\n            }\n        };\n    }\n    \n    protected Component[] getFilterOptions() {\n        PopupButton pb = new PopupButton (Icons.getIcon(ProfilerIcons.TAB_CALL_TREE)) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new JCheckBoxMenuItem(SEARCH_CLASSES_SCOPE, filterObjects) {\n                    {\n                        if (!filterAllocations) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterObjects = !filterObjects;\n                        enableFilter();\n                    }\n                });\n                popup.add(new JCheckBoxMenuItem(FILTER_ALLOCATIONS_SCOPE, filterAllocations) {\n                    {\n                        if (!filterObjects) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterAllocations = !filterAllocations;\n                        enableFilter();\n                    }\n                });\n            }\n        };\n        pb.setToolTipText(FILTER_SCOPE_TOOLTIP);\n        return new Component[] { Box.createHorizontalStrut(5), pb };\n    }\n    \n    protected SearchUtils.TreeHelper getSearchHelper() {\n        return new SearchUtils.TreeHelper() {\n            public int getNodeType(TreeNode tnode) {\n                PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)tnode;\n                CCTNode parent = node.getParent();\n                if (parent == null) return SearchUtils.TreeHelper.NODE_SKIP_DOWN; // invisible root\n                \n                if (parent.getParent() == null) {\n                    if (searchObjects) {\n                        return searchAllocations ? SearchUtils.TreeHelper.NODE_SEARCH_DOWN :\n                                                   SearchUtils.TreeHelper.NODE_SEARCH_NEXT;\n                    } else {\n                        return searchAllocations ? SearchUtils.TreeHelper.NODE_SKIP_DOWN :\n                                                   SearchUtils.TreeHelper.NODE_SKIP_NEXT;\n                    }\n                }\n                \n                return searchAllocations ? SearchUtils.TreeHelper.NODE_SEARCH_DOWN :\n                                           SearchUtils.TreeHelper.NODE_SKIP_NEXT;\n            }\n        };\n    }\n    \n    protected Component[] getSearchOptions() {\n        PopupButton pb = new PopupButton (Icons.getIcon(ProfilerIcons.TAB_CALL_TREE)) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new JCheckBoxMenuItem(SEARCH_CLASSES_SCOPE, searchObjects) {\n                    {\n                        if (!searchAllocations) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        searchObjects = !searchObjects;\n                    }\n                });\n                popup.add(new JCheckBoxMenuItem(SEARCH_ALLOCATIONS_SCOPE, searchAllocations) {\n                    {\n                        if (!searchObjects) setEnabled(false);\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        searchAllocations = !searchAllocations;\n                    }\n                });\n            }\n        };\n        pb.setToolTipText(SEARCH_SCOPE_TOOLTIP);\n        return new Component[] { Box.createHorizontalStrut(5), pb };\n    }\n    \n    protected ProfilerTable getResultsComponent() { return treeTable; }\n    \n    \n    public void setData(MemoryResultsSnapshot snapshot, GenericFilter filter, int aggregation) {\n        final boolean includeEmpty = filter != null;\n//        final boolean includeEmpty = false;\n        final boolean diff = snapshot instanceof LivenessMemoryResultsDiff;\n        final LivenessMemoryResultsSnapshot _snapshot = (LivenessMemoryResultsSnapshot)snapshot;\n        \n        String[] _classNames = _snapshot.getClassNames();\n        long[] _nTrackedAllocObjects = _snapshot.getNTrackedAllocObjects();\n        long[] _objectsSizePerClass = _snapshot.getObjectsSizePerClass();\n        int[] _nTrackedLiveObjects = _snapshot.getNTrackedLiveObjects();\n        int[] _nTotalAllocObjects = _snapshot.getnTotalAllocObjects();\n        float[] _avgObjectAge = _snapshot.getAvgObjectAge();\n        int[] _maxSurvGen = _snapshot.getMaxSurvGen();\n        \n        int _nTrackedItems = Math.min(_snapshot.getNProfiledClasses(), _classNames.length);\n        _nTrackedItems = Math.min(_nTrackedItems, _nTotalAllocObjects.length);\n        \n        List<PresoObjLivenessCCTNode> nodes = new ArrayList<>();\n        final Map<TreeNode, ClientUtils.SourceCodeSelection> _nodesMap = new HashMap<>();\n        \n        long totalLiveBytes = 0;\n        long _totalLiveBytes = 0;\n        long totalLiveObjects = 0;\n        long _totalLiveObjects = 0;\n        long totalTrackedAlloc = 0;\n        long _totalTrackedAlloc = 0;\n        long totalTotalAlloc = 0;\n        long _totalTotalAlloc = 0;\n        \n        for (int i = 0; i < _nTrackedItems; i++) {\n            if (diff) {\n                totalLiveBytes = Math.max(totalLiveBytes, _objectsSizePerClass[i]);\n                _totalLiveBytes = Math.min(_totalLiveBytes, _objectsSizePerClass[i]);\n                totalLiveObjects = Math.max(totalLiveObjects, _nTrackedLiveObjects[i]);\n                _totalLiveObjects = Math.min(_totalLiveObjects, _nTrackedLiveObjects[i]);\n                totalTrackedAlloc = Math.max(totalTrackedAlloc, _nTrackedAllocObjects[i]);\n                _totalTrackedAlloc = Math.min(_totalTrackedAlloc, _nTrackedAllocObjects[i]);\n                if (includeTotalAllocs) {\n                    totalTotalAlloc = Math.max(totalTotalAlloc, _nTotalAllocObjects[i]);\n                    _totalTotalAlloc = Math.min(_totalTotalAlloc, _nTotalAllocObjects[i]);\n                }\n            } else {\n                totalLiveBytes += _objectsSizePerClass[i];\n                totalLiveObjects += _nTrackedLiveObjects[i];\n                totalTrackedAlloc += _nTrackedAllocObjects[i];\n                if (includeTotalAllocs) totalTotalAlloc += _nTotalAllocObjects[i];\n            }\n            \n            final int _i = i;\n            \n            class Node extends PresoObjLivenessCCTNode {\n                Node(String className, long nTrackedAllocObjects, long objectsSizePerClass, int nTrackedLiveObjects, int nTotalAllocObjects, float avgObjectAge, int maxSurvGen) {\n                    super(className, nTrackedAllocObjects, objectsSizePerClass, nTrackedLiveObjects, nTotalAllocObjects, avgObjectAge, maxSurvGen);\n                }\n                public CCTNode[] getChildren() {\n                    if (children == null) {\n                        MemoryCCTManager callGraphManager = new MemoryCCTManager(_snapshot, _i, true);\n                        PresoObjAllocCCTNode root = callGraphManager.getRootNode();\n                        setChildren(root == null ? new PresoObjAllocCCTNode[0] :\n                                    (PresoObjAllocCCTNode[])root.getChildren());\n                    }\n                    return children;\n                }\n                public boolean isLeaf() {\n                    if (children == null) return includeEmpty && nCalls == 0;\n                    else return super.isLeaf();\n                }   \n                public int getChildCount() {\n                    if (children == null) getChildren();\n                    return super.getChildCount();\n                }\n            }\n            \n            if (!includeEmpty) { // old snapshot\n                if (_nTrackedLiveObjects[i] > 0) {\n                    PresoObjLivenessCCTNode node = new Node(_classNames[i], _nTrackedAllocObjects[i], _objectsSizePerClass[i], _nTrackedLiveObjects[i], _nTotalAllocObjects[i], _avgObjectAge[i], _maxSurvGen[i]);\n                    nodes.add(node);\n                    _nodesMap.put(node, new ClientUtils.SourceCodeSelection(_classNames[i], Wildcards.ALLWILDCARD, null));\n                }\n            } else if (filter.passes(_classNames[i].replace('.', '/'))) { // NOI18N\n                PresoObjLivenessCCTNode node = new Node(_classNames[i], _nTrackedAllocObjects[i], _objectsSizePerClass[i], _nTrackedLiveObjects[i], _nTotalAllocObjects[i], _avgObjectAge[i], _maxSurvGen[i]);\n                nodes.add(node);\n                _nodesMap.put(node, new ClientUtils.SourceCodeSelection(_classNames[i], Wildcards.ALLWILDCARD, null));\n            }\n        }\n        \n        final long __totalLiveBytes = !diff ? totalLiveBytes :\n                Math.max(Math.abs(totalLiveBytes), Math.abs(_totalLiveBytes));\n        final long __totalLiveObjects = !diff ? totalLiveObjects :\n                Math.max(Math.abs(totalLiveObjects), Math.abs(_totalLiveObjects));\n        final long __totalTrackedAlloc = !diff ? totalTrackedAlloc :\n                Math.max(Math.abs(totalTrackedAlloc), Math.abs(_totalTrackedAlloc));\n        final long __totalTotalAlloc = !diff ? totalTotalAlloc :\n                Math.max(Math.abs(totalTotalAlloc), Math.abs(_totalTotalAlloc));\n        final PresoObjLivenessCCTNode root = PresoObjLivenessCCTNode.rootNode(nodes.toArray(new PresoObjLivenessCCTNode[0]));\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                nodesMap = _nodesMap;\n                renderers[0].setMaxValue(__totalLiveBytes);\n                renderers[1].setMaxValue(__totalLiveObjects);\n                renderers[2].setMaxValue(__totalTrackedAlloc);\n                if (includeTotalAllocs) renderers[3].setMaxValue(__totalTotalAlloc);\n                \n                renderers[0].setDiffMode(diff);\n                renderers[1].setDiffMode(diff);\n                renderers[2].setDiffMode(diff);\n                if (includeTotalAllocs) renderers[3].setDiffMode(diff);\n                \n                renderersEx[0].setDiffMode(diff);\n                renderersEx[1].setDiffMode(diff);\n                    \n                treeTableModel.setRoot(root);\n            }\n        });\n    }\n    \n    \n    public void resetData() {\n        final PresoObjLivenessCCTNode root = PresoObjLivenessCCTNode.rootNode(new PresoObjLivenessCCTNode[0]);\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                nodesMap = null;\n                \n                renderers[0].setMaxValue(0);\n                renderers[1].setMaxValue(0);\n                renderers[2].setMaxValue(0);\n                if (includeTotalAllocs) renderers[3].setMaxValue(0);\n\n                renderers[0].setDiffMode(false);\n                renderers[1].setDiffMode(false);\n                renderers[2].setDiffMode(false);\n                if (includeTotalAllocs) renderers[3].setDiffMode(false);\n\n                renderersEx[0].setDiffMode(false);\n                renderersEx[1].setDiffMode(false);\n                \n                treeTableModel.setRoot(root);\n            }\n        });\n    }\n    \n    \n    public void showSelectionColumn() {\n        treeTable.setColumnVisibility(0, true);\n    }\n    \n    public void refreshSelection() {\n        treeTableModel.dataChanged();\n    }\n    \n    \n    public ExportUtils.ExportProvider[] getExportProviders() {\n        return treeTable.getRowCount() == 0 ? null : new ExportUtils.ExportProvider[] {\n            new ExportUtils.CSVExportProvider(treeTable),\n            new ExportUtils.HTMLExportProvider(treeTable, EXPORT_ALLOCATED_LIVE),\n            new ExportUtils.XMLExportProvider(treeTable, EXPORT_ALLOCATED_LIVE),\n            new ExportUtils.PNGExportProvider(treeTable)\n        };\n    }\n    \n    \n    protected abstract void performDefaultAction(ClientUtils.SourceCodeSelection userValue);\n    \n    protected abstract void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue);\n    \n    protected void popupShowing() {}\n    \n    protected void popupHidden()  {}\n    \n    \n    private HideableBarRenderer[] renderers;\n    private NumberRenderer[] renderersEx;\n    \n    private void initUI() {\n        final int offset = selection == null ? -1 : 0;\n        \n        treeTableModel = new LivenessTreeTableModel(PrestimeCPUCCTNode.EMPTY);\n        \n        treeTable = new ProfilerTreeTable(treeTableModel, true, true, new int[] { 1 + offset }) {\n            public ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n                return LivenessTreeTableView.this.getUserValueForRow(row);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                LivenessTreeTableView.this.populatePopup(popup, value, (ClientUtils.SourceCodeSelection)userValue);\n            }\n            protected void popupShowing() {\n                LivenessTreeTableView.this.popupShowing();\n            }\n            protected void popupHidden() {\n                LivenessTreeTableView.this.popupHidden();\n            }\n        };\n        \n        treeTable.setColumnToolTips(selection == null ? new String[] {\n                                  NAME_COLUMN_TOOLTIP,\n                                  LIVE_SIZE_COLUMN_TOOLTIP,\n                                  LIVE_COUNT_COLUMN_TOOLTIP,\n                                  ALLOC_COUNT_COLUMN_TOOLTIP,\n                                  AVG_AGE_COLUMN_TOOLTIP,\n                                  GENERATIONS_COLUMN_TOOLTIP,\n                                  TOTAL_ALLOC_COUNT_COLUMN_TOOLTIP,\n                                } : new String[] {\n                                  SELECTED_COLUMN_TOOLTIP,\n                                  NAME_COLUMN_TOOLTIP,\n                                  LIVE_SIZE_COLUMN_TOOLTIP,\n                                  LIVE_COUNT_COLUMN_TOOLTIP,\n                                  ALLOC_COUNT_COLUMN_TOOLTIP,\n                                  AVG_AGE_COLUMN_TOOLTIP,\n                                  GENERATIONS_COLUMN_TOOLTIP,\n                                  TOTAL_ALLOC_COUNT_COLUMN_TOOLTIP,\n                                });\n        \n        treeTable.providePopupMenu(true);\n        treeTable.setDefaultAction(new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                int row = treeTable.getSelectedRow();\n                ClientUtils.SourceCodeSelection userValue = getUserValueForRow(row);\n                if (userValue != null) performDefaultAction(userValue);\n            }\n        });\n        \n        treeTable.setRootVisible(false);\n        treeTable.setShowsRootHandles(true);\n        treeTable.makeTreeAutoExpandable(2);\n        \n        treeTable.setMainColumn(1 + offset);\n        treeTable.setFitWidthColumn(1 + offset);\n        \n        treeTable.setSortColumn(2 + offset);\n        treeTable.setDefaultSortOrder(1 + offset, SortOrder.ASCENDING);\n        \n        if (selection != null) treeTable.setColumnVisibility(0, false);\n        treeTable.setColumnVisibility(5 + offset, false);\n        if (includeTotalAllocs) treeTable.setColumnVisibility(7 + offset, false);\n        \n        renderers = new HideableBarRenderer[4];\n        renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(Formatters.bytesFormat()));\n        renderers[1] = new HideableBarRenderer(new NumberPercentRenderer());\n        renderers[2] = new HideableBarRenderer(new NumberPercentRenderer());\n        renderers[3] = new HideableBarRenderer(new NumberPercentRenderer() {\n            public void setValue(Object value, int row) {\n                if (value == null || ((Number)value).longValue() == -1) {\n                    super.setValue(null, row);\n                } else {\n                    super.setValue(value, row);\n                }\n            }\n        });\n        \n        renderers[0].setMaxValue(123456789);\n        renderers[1].setMaxValue(12345678);\n        renderers[2].setMaxValue(12345678);\n        renderers[3].setMaxValue(12345678);\n        \n        renderersEx = new NumberRenderer[2];\n        renderersEx[0] = new NumberRenderer() {\n            protected String getValueString(Object value, int row, Format format) {\n                if (value == null) return \"-\"; // NOI18N\n                float _value = ((Float)value).floatValue();\n                String s = StringUtils.floatPerCentToString(_value);\n                if (renderingDiff && _value >= 0) s = '+' + s; // NOI18N\n                return s;\n            }\n        };\n        renderersEx[1] = new NumberRenderer();\n        \n        if (selection != null) treeTable.setColumnRenderer(0, new CheckBoxRenderer() {\n            private boolean visible;\n            public void setValue(Object value, int row) {\n                TreePath path = treeTable.getPathForRow(row);\n                visible = nodesMap.containsKey((TreeNode)path.getLastPathComponent());\n                if (visible) super.setValue(value, row);\n            }\n            public void paint(Graphics g) {\n                if (visible) {\n                    super.paint(g);\n                } else {\n                    g.setColor(getBackground());\n                    g.fillRect(0, 0, size.width, size.height);\n                }\n            }\n        });\n        treeTable.setTreeCellRenderer(new MemoryJavaNameRenderer());\n        treeTable.setColumnRenderer(2 + offset, renderers[0]);\n        treeTable.setColumnRenderer(3 + offset, renderers[1]);\n        treeTable.setColumnRenderer(4 + offset, renderers[2]);\n        treeTable.setColumnRenderer(5 + offset, renderersEx[0]);\n        treeTable.setColumnRenderer(6 + offset, renderersEx[1]);\n        if (includeTotalAllocs) treeTable.setColumnRenderer(7 + offset, renderers[3]);\n\n        if (selection != null) {\n            int w = new JLabel(treeTable.getColumnName(0)).getPreferredSize().width;\n            treeTable.setDefaultColumnWidth(0, w + 15);\n        }\n        treeTable.setDefaultColumnWidth(2 + offset, renderers[0].getOptimalWidth());\n        treeTable.setDefaultColumnWidth(3 + offset, renderers[1].getMaxNoBarWidth());\n        treeTable.setDefaultColumnWidth(4 + offset, renderers[2].getMaxNoBarWidth());\n        treeTable.setDefaultColumnWidth(5 + offset, renderers[2].getNoBarWidth() - 25);\n        if (includeTotalAllocs) treeTable.setDefaultColumnWidth(7 + offset, renderers[3].getMaxNoBarWidth());\n        \n        ProfilerTableContainer tableContainer = new ProfilerTableContainer(treeTable, false, null);\n        \n        setLayout(new BorderLayout());\n        add(tableContainer, BorderLayout.CENTER);\n    }\n    \n    protected ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n        PresoObjLivenessCCTNode node = (PresoObjLivenessCCTNode)treeTable.getValueForRow(row);\n        if (node == null || node.isFiltered()) return null;\n        String[] name = node.getMethodClassNameAndSig();\n        return new ClientUtils.SourceCodeSelection(name[0], name[1], name[2]);\n    }\n    \n    \n    private class LivenessTreeTableModel extends ProfilerTreeTableModel.Abstract {\n        \n        private final int columns = 6 +\n                (selection == null ? 0 : 1) +\n                (includeTotalAllocs ? 1 : 0);\n        \n        LivenessTreeTableModel(TreeNode root) {\n            super(root);\n        }\n        \n        public String getColumnName(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return COLUMN_NAME;\n            } else if (columnIndex == 2) {\n                return COLUMN_LIVE_BYTES;\n            } else if (columnIndex == 3) {\n                return COLUMN_LIVE_OBJECTS;\n            } else if (columnIndex == 4) {\n                return COLUMN_ALLOCATED_OBJECTS;\n            } else if (columnIndex == 5) {\n                return COLUMN_AVG_AGE;\n            } else if (columnIndex == 6) {\n                return COLUMN_GENERATIONS;\n            } else if (columnIndex == 7) {\n                return COLUMN_TOTAL_ALLOCATED_OBJECTS;\n            } else if (columnIndex == 0) {\n                return COLUMN_SELECTED;\n            }\n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return JTree.class;\n            } else if (columnIndex == 2) {\n                return Long.class;\n            } else if (columnIndex == 3) {\n                return Integer.class;\n            } else if (columnIndex == 4) {\n                return Long.class;\n            } else if (columnIndex == 5) {\n                return Float.class;\n            } else if (columnIndex == 6) {\n                return Integer.class;\n            } else if (columnIndex == 7) {\n                return Integer.class;\n            } else if (columnIndex == 0) {\n                return Boolean.class;\n            }\n            return null;\n        }\n\n        public int getColumnCount() {\n            return columns;\n        }\n\n        public Object getValueAt(TreeNode node, int columnIndex) {\n            PresoObjLivenessCCTNode livenessNode = (PresoObjLivenessCCTNode)node;\n            \n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return livenessNode.getNodeName();\n            } else if (columnIndex == 2) {\n                return livenessNode.totalObjSize;\n            } else if (columnIndex == 3) {\n                return livenessNode.nLiveObjects;\n            } else if (columnIndex == 4) {\n                return livenessNode.nCalls;\n            } else if (columnIndex == 5) {\n                return livenessNode.avgObjectAge;\n            } else if (columnIndex == 6) {\n                return livenessNode.survGen;\n            } else if (columnIndex == 7) {\n                return livenessNode.nTotalAllocObjects;\n            } else if (columnIndex == 0) {\n                if (selection.isEmpty()) return Boolean.FALSE;\n                return selection.contains(nodesMap.get(node));\n            }\n\n            return null;\n        }\n        \n        public void setValueAt(Object aValue, TreeNode node, int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 0) {\n                if (Boolean.TRUE.equals(aValue)) selection.add(nodesMap.get(node));\n                else selection.remove(nodesMap.get(node));\n            }\n        }\n\n        public boolean isCellEditable(TreeNode node, int columnIndex) {\n            if (selection == null) columnIndex++;\n            if (columnIndex != 0) return false;\n            return (nodesMap.containsKey(node));\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/MemoryCCTTreeModel.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport javax.swing.tree.*;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.*;\n\n\n/**\n * Implementation of TreeModel for Memory CCT Trees\n *\n * @author Misha Dmitriev\n * @author Jiri Sedlacek\n */\npublic class MemoryCCTTreeModel implements TreeModel {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private PresoObjAllocCCTNode root;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of MemoryCCTTreeModel */\n    public MemoryCCTTreeModel(PresoObjAllocCCTNode root) {\n        this.root = root;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Object getChild(Object obj, int index) {\n        if (obj == null) {\n            return null;\n        }\n\n        PresoObjAllocCCTNode node = (PresoObjAllocCCTNode) obj;\n\n        return node.getChild(index);\n    }\n\n    public int getChildCount(Object obj) {\n        if (obj == null) {\n            return -1;\n        }\n\n        PresoObjAllocCCTNode node = (PresoObjAllocCCTNode) obj;\n\n        return node.getNChildren();\n    }\n\n    public int getIndexOfChild(Object parentObj, Object childObj) {\n        if ((parentObj == null) || (childObj == null)) {\n            return -1;\n        }\n\n        PresoObjAllocCCTNode parent = (PresoObjAllocCCTNode) parentObj;\n        PresoObjAllocCCTNode child = (PresoObjAllocCCTNode) childObj;\n\n        return parent.getIndexOfChild(child);\n    }\n\n    public boolean isLeaf(Object obj) {\n        if (obj == null) {\n            return true;\n        }\n\n        PresoObjAllocCCTNode node = (PresoObjAllocCCTNode) obj;\n\n        return (node.getNChildren() == 0);\n    }\n\n    public Object getRoot() {\n        return root;\n    }\n\n    public void addTreeModelListener(javax.swing.event.TreeModelListener treeModelListener) {\n    }\n\n    public void removeTreeModelListener(javax.swing.event.TreeModelListener treeModelListener) {\n    }\n\n    // --------------------------------------------------------------  \n\n    // TreeModel interface methods that we don't implement\n    public void valueForPathChanged(javax.swing.tree.TreePath treePath, Object obj) {\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/MemoryJavaNameRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport javax.swing.Icon;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class MemoryJavaNameRenderer extends JavaNameRenderer {\n\n    private static final Icon CLASS_ICON = Icons.getIcon(LanguageIcons.CLASS);\n    private static final Icon REVERSE_ICON = Icons.getIcon(ProfilerIcons.NODE_REVERSE);\n    private static final Icon REVERSE_ICON_DISABLED = UIManager.getLookAndFeel().getDisabledIcon(null, REVERSE_ICON);\n\n    public void setValue(Object value, int row) {\n        if (value instanceof PresoObjAllocCCTNode) {\n            PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)value;\n\n            if (node.isFiltered()) {\n                setNormalValue(\"\"); // NOI18N\n                setBoldValue(\"\");\n                setGrayValue(node.getNodeName()); // NOI18N\n            } else {\n                super.setValue(value, row);\n            }\n\n            if (node.isFiltered()) setIcon(REVERSE_ICON_DISABLED);\n            else if (node.getMethodClassNameAndSig()[2] == null) setIcon(CLASS_ICON); // class name\n            else setIcon(REVERSE_ICON); // method name\n        } else {\n            super.setValue(value, row);\n        }\n\n//        // TODO: <clinit> methods should be displayed with \"()\" similar to <init>\n//        // PlainFormattableMethodName.getFullFormattedMethod()\n//\n//        if (getGrayValue().isEmpty()) System.err.println(\">> value: \" + ((PresoObjAllocCCTNode)value).getMethodClassNameAndSig()[2]);\n//        // TODO: also \"Objects allocated by reflection\" should be excluded to display icon\n//        if (getGrayValue().isEmpty()) setIcon(null); // class name\n//        else setIcon(Icons.getIcon(ProfilerIcons.NODE_REVERSE)); // method name\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/MemoryResUserActionsHandler.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.util.ResourceBundle;\n\n\n/**\n * This interface declares actions that the user may initiate when browsing memory profiling results.\n * For example, the user may move the cursor to some class and request the tool to show stack\n * traces for allocations of instances of this class.\n *\n * @author Misha Dmitriev\n */\npublic interface MemoryResUserActionsHandler {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    public static final String CANNOT_SHOW_PRIMITIVE_SRC_MSG = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\") // NOI18N\n                                                                             .getString(\"MemoryResUserActionsHandler_CannotShowPrimitiveSrcMsg\"); // NOI18N\n    public static final String CANNOT_SHOW_REFLECTION_SRC_MSG = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\") // NOI18N\n                                                                             .getString(\"MemoryResUserActionsHandler_CannotShowReflectionSrcMsg\"); // NOI18N\n    // -----\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void showSourceForMethod(String className, String methodName, String methodSig);\n\n    // if sorting is not defined, use showStacksForClass(selectedClassId, CommonConstants.SORTING_COLUMN_DEFAULT, false);\n    public void showStacksForClass(int selectedClassId, int sortingColumn, boolean sortingOrder);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/MemoryResultsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.awt.image.BufferedImage;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.TableCellRenderer;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.utils.*;\nimport org.graalvm.visualvm.lib.ui.ResultsPanel;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.FilterComponent;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedTable;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.ExtendedTableModel;\n\n\n/**\n * Base abstract class for panels containing memory profiling results in table form.\n * It consists of a JPanel with embedded JScrollPane, plus a popup menu that is not attached to\n * anything (that should be done by subclasses). The common functionality provided in it is:\n * - initialization and generation of displayable data\n * - reset\n * - showing results\n * - getting string title\n * - sorting results.\n *\n * @author Misha Dmitriev\n * @author Jiri Sedlacek\n * @author Ian Formanek\n */\npublic abstract class MemoryResultsPanel extends ResultsPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String CLASS_NAME_FILTER = messages.getString(\"MemoryResultsPanel_ClassNameFilterHint\"); // NOI18N\n                                                                                                                // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected List<Integer> filteredToFullIndexes;\n    protected CustomBarCellRenderer barRenderer;\n    protected ExtendedTableModel resTableModel;\n    protected FilterComponent filterComponent;\n    protected JButton cornerButton;\n    protected JExtendedTable resTable;\n    protected JPopupMenu headerPopup;\n    protected JScrollPane jScrollPane;\n    protected MemoryResUserActionsHandler actionsHandler;\n    protected String filterString = \"\"; // NOI18N\n    protected String[] columnNames;\n    protected TableCellRenderer[] columnRenderers;\n    protected String[] columnToolTips;\n    protected Class<?>[] columnTypes;\n    protected int[] columnWidths;\n    protected int[] sortedClassIds; // this maps row idx to classId (classId = original, before-sort, row index)\n    protected String[] sortedClassNames; // this is effectively a copy of the class names contained in profilingSessionStatus\n                                         // or MemoryResultsSnapshot, in user-level format and sorted according to current\n                                         // sorting criteria\n    protected boolean registeredMouseListenerWithResTable;\n    protected boolean sortOrder; // Defines the sorting order (ascending or descending)\n    protected double valueFilterValue = 0.0d;\n    protected int clickedLine;\n    protected int filterType = CommonConstants.FILTER_CONTAINS;\n    protected int nDisplayedItems;\n    protected int nInfoLines;\n    protected int nTrackedItems;\n    protected int selectedClassId;\n    protected int sortBy; // Defines sorting criteria (concrete values provided in subclasses)\n    protected long maxValue; // Used by the bar representation management code\n    protected long totalAllocations;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public MemoryResultsPanel(MemoryResUserActionsHandler actionsHandler) {\n        this.actionsHandler = actionsHandler;\n\n        filteredToFullIndexes = new ArrayList<>();\n\n        headerPopup = new JPopupMenu();\n        jScrollPane = createScrollPaneVerticalScrollBarAlways();\n        jScrollPane.setCorner(JScrollPane.UPPER_RIGHT_CORNER, createHeaderPopupCornerButton(headerPopup));\n        jScrollPane.setBorder(BorderFactory.createEmptyBorder());\n        jScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());\n\n        initFilterPanel();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public BufferedImage getCurrentViewScreenshot(boolean onlyVisibleArea) {\n        if (resTable == null) {\n            return null;\n        }\n\n        if (onlyVisibleArea) {\n            return UIUtils.createScreenshot(jScrollPane);\n        } else {\n            return UIUtils.createScreenshot(resTable);\n        }\n    }\n\n    // --- Find functionality stuff\n    public void setFindString(String findString) {\n        resTable.setFindParameters(findString, 0);\n    }\n\n    public String getFindString() {\n        return resTable.getFindString();\n    }\n\n    public boolean isFindStringDefined() {\n        return resTable.isFindStringDefined();\n    }\n\n    public boolean findFirst() {\n        return resTable.findFirst();\n    }\n\n    public boolean findNext() {\n        return resTable.findNext();\n    }\n\n    public boolean findPrevious() {\n        return resTable.findPrevious();\n    }\n\n    public boolean fitsVisibleArea() {\n        return !jScrollPane.getVerticalScrollBar().isEnabled();\n    }\n\n    public void prepareResults() {\n        final JExtendedTable table = getResultsTable();\n        resTable.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)\n                .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), \"DEFAULT_ACTION\"); // NOI18N\n        resTable.getActionMap().put(\"DEFAULT_ACTION\",\n                                    new AbstractAction() {\n                public void actionPerformed(ActionEvent e) {\n                    performDefaultAction(selectedClassId);\n                }\n            }); // NOI18N\n\n        jScrollPane.setViewportView(table);\n        jScrollPane.getViewport().setBackground(table.getBackground());\n\n        if (!registeredMouseListenerWithResTable) {\n            jScrollPane.addMouseWheelListener(table);\n\n            table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n                    public void valueChanged(ListSelectionEvent e) {\n                        int selectedRow = table.getSelectedRow();\n\n                        if (selectedRow == -1) {\n                            return;\n                        }\n\n                        selectedClassId = sortedClassIds[filteredToFullIndexes.get(selectedRow).intValue()];\n                    }\n                });\n\n            table.addKeyListener(new KeyAdapter() {\n                    public void keyPressed(KeyEvent e) {\n                        if ((e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU)\n                                || ((e.getKeyCode() == KeyEvent.VK_F10) && (e.getModifiers() == InputEvent.SHIFT_MASK))) {\n                            int selectedRow = table.getSelectedRow();\n\n                            if (selectedRow != -1) {\n                                selectedClassId = sortedClassIds[filteredToFullIndexes.get(selectedRow).intValue()];\n\n                                Rectangle cellRect = table.getCellRect(selectedRow, 0, false);\n                                JPopupMenu popup = getPopupMenu();\n\n                                if (popup != null) {\n                                    popup.show(e.getComponent(), ((cellRect.x + table.getSize().width) > 50) ? 50 : 5, cellRect.y);\n                                }\n                            }\n                        }\n                    }\n                });\n\n            table.addMouseListener(new MouseAdapter() {\n                    private void showPopupMenu(MouseEvent e) {\n                        clickedLine = table.rowAtPoint(e.getPoint());\n\n                        if (clickedLine != -1) {\n                            resTable.getSelectionModel().setSelectionInterval(clickedLine, clickedLine);\n                            //selectedClassId = sortedClassIds[clickedLine];\n                            selectedClassId = sortedClassIds[filteredToFullIndexes.get(clickedLine).intValue()];\n\n                            JPopupMenu popup = getPopupMenu();\n\n                            if (popup != null) {\n                                popup.show(e.getComponent(), e.getX(), e.getY());\n                            }\n                        }\n                    }\n\n                    public void mousePressed(MouseEvent e) {\n                        if (e.isPopupTrigger()) showPopupMenu(e);\n                    }\n\n                    public void mouseReleased(MouseEvent e) {\n                        if (e.isPopupTrigger()) showPopupMenu(e);\n                    }\n\n                    public void mouseClicked(MouseEvent e) {\n                        clickedLine = table.rowAtPoint(e.getPoint());\n\n                        if (clickedLine != -1) {\n                            resTable.getSelectionModel().setSelectionInterval(clickedLine, clickedLine);\n                            //selectedClassId = sortedClassIds[clickedLine];\n                            selectedClassId = sortedClassIds[filteredToFullIndexes.get(clickedLine).intValue()];\n\n                            if (SwingUtilities.isLeftMouseButton(e) && (e.getClickCount() == 2)) {\n                                performDefaultAction(selectedClassId);\n                            }\n                        }\n                    }\n                });\n            registeredMouseListenerWithResTable = true;\n        }\n    }\n\n    public void requestFocus() {\n        if (resTable != null) {\n            SwingUtilities.invokeLater(new Runnable() { // must be invoked lazily to override default focus of first component (top-right cornerButton)\n                    public void run() {\n                        resTable.requestFocus();\n                    }\n                });\n        }\n    }\n\n    public void reset() {\n        jScrollPane.setViewportView(null);\n    }\n\n    public void updateValueFilter(double value) {\n        valueFilterValue = value / 3f; // maximum 33.3%\n        createFilteredIndexes();\n        resTable.invalidate();\n        jScrollPane.revalidate();\n        resTable.repaint();\n    }\n\n    protected abstract String getClassName(int classid);\n\n    protected abstract String[] getClassNames();\n\n    protected abstract JPopupMenu getPopupMenu();\n\n    // ---------------------------------------------------------------------------\n    // Abstract methods that should be implemented by a concrete - data type frame\n    protected abstract JExtendedTable getResultsTable();\n\n    protected void createFilteredIndexes() {\n        filteredToFullIndexes.clear();\n\n        for (int i = 0; i < nInfoLines; i++) {\n            if (passesFilters(i) && passesValueFilter(i)) {\n                filteredToFullIndexes.add(Integer.valueOf(i));\n            }\n        }\n\n        nDisplayedItems = filteredToFullIndexes.size();\n    }\n\n    protected final void doCreateClassNamesFromScratch() {\n        String[] classNames = getClassNames();\n\n        if ((sortedClassNames == null) || (sortedClassNames.length < classNames.length)) {\n            sortedClassNames = new String[classNames.length];\n            sortedClassIds = new int[classNames.length];\n        }\n\n        for (int i = 0; i < classNames.length; i++) {\n            sortedClassNames[i] = StringUtils.userFormClassName(classNames[i]);\n            sortedClassIds[i] = i;\n        }\n    }\n\n    protected void initDataUponResultsFetch() {\n//        if (barRenderer != null) {\n//            barRenderer.setMaximum(maxValue); // updateState the bar renderer if already exists\n//        }\n\n        doCreateClassNamesFromScratch();\n    }\n\n    protected boolean passesValueFilter(int i) {\n        return true;\n    }\n\n    protected abstract void performDefaultAction(int selectedClassId);\n\n    protected void showSourceForClass(int classId) {\n        if (classId < 0) {\n            return;\n        }\n\n        String className = StringUtils.userFormClassName(getClassName(classId));\n\n        actionsHandler.showSourceForMethod(className, null, null);\n    }\n\n    //----------------------------------------------------------------------------\n    // Sorting results according to different criteria - used in subclasses\n\n    /**\n     * Sorts the results[] array, aligning secondaryData with it if it's present.\n     * Returns the number of non-zero elements, which may be smaller than the array size.\n     */\n    protected int sortResults(final int[] results, final int[][] secondaryIntData, final long[][] secondaryLongData,\n                              final float[][] secondaryFloatData, int off, int len, boolean truncateZeroItems) {\n        //if (createNamesFromScratch) doCreateClassNamesFromScratch();\n        final int nSecIDataArrays = (secondaryIntData != null) ? secondaryIntData.length : 0;\n        final int nSecLDataArrays = (secondaryLongData != null) ? secondaryLongData.length : 0;\n        final int nSecFDataArrays = (secondaryFloatData != null) ? secondaryFloatData.length : 0;\n\n        (new IntSorter(results, off, len) {\n                protected void swap(int a, int b) {\n                    if (results[a] != results[b]) {\n                        super.swap(a, b);\n\n                        String tmp = sortedClassNames[a];\n                        sortedClassNames[a] = sortedClassNames[b];\n                        sortedClassNames[b] = tmp;\n\n                        int tmpI = sortedClassIds[a];\n                        sortedClassIds[a] = sortedClassIds[b];\n                        sortedClassIds[b] = tmpI;\n\n                        for (int i = 0; i < nSecIDataArrays; i++) {\n                            tmpI = secondaryIntData[i][a];\n                            secondaryIntData[i][a] = secondaryIntData[i][b];\n                            secondaryIntData[i][b] = tmpI;\n                        }\n\n                        for (int i = 0; i < nSecLDataArrays; i++) {\n                            long tmpL = secondaryLongData[i][a];\n                            secondaryLongData[i][a] = secondaryLongData[i][b];\n                            secondaryLongData[i][b] = tmpL;\n                        }\n\n                        for (int i = 0; i < nSecFDataArrays; i++) {\n                            float tmpF = secondaryFloatData[i][a];\n                            secondaryFloatData[i][a] = secondaryFloatData[i][b];\n                            secondaryFloatData[i][b] = tmpF;\n                        }\n                    }\n                }\n            }).sort(sortOrder);\n\n        len = off + len; // Note that supplied len may be for a subset of the array, but what's ultimately needed is\n                         // the number of non-zero elements for the whole array\n                         //if (truncateZeroItems) {  // Deal with the fact that some items in the bottom may be just zero\n                         //  while (len > 0 && results[len - 1] == 0) len--;\n                         //}\n\n        return len;\n    }\n\n    /**\n     * Sorts the results[] array, aligning secondaryData with it if it's present.\n     * Returns the number of non-zero elements, which may be smaller than the array size.\n     */\n    protected int sortResults(final long[] results, final int[][] secondaryIntData, final long[][] secondaryLongData,\n                              final float[][] secondaryFloatData, int off, int len, boolean truncateZeroItems) {\n        //if (createNamesFromScratch) doCreateClassNamesFromScratch();\n        final int nSecIDataArrays = (secondaryIntData != null) ? secondaryIntData.length : 0;\n        final int nSecLDataArrays = (secondaryLongData != null) ? secondaryLongData.length : 0;\n        final int nSecFDataArrays = (secondaryFloatData != null) ? secondaryFloatData.length : 0;\n\n        (new LongSorter(results, off, len) {\n                protected void swap(int a, int b) {\n                    if (results[a] != results[b]) {\n                        super.swap(a, b);\n\n                        String tmp = sortedClassNames[a];\n                        sortedClassNames[a] = sortedClassNames[b];\n                        sortedClassNames[b] = tmp;\n\n                        int tmpI = sortedClassIds[a];\n                        sortedClassIds[a] = sortedClassIds[b];\n                        sortedClassIds[b] = tmpI;\n\n                        for (int i = 0; i < nSecIDataArrays; i++) {\n                            tmpI = secondaryIntData[i][a];\n                            secondaryIntData[i][a] = secondaryIntData[i][b];\n                            secondaryIntData[i][b] = tmpI;\n                        }\n\n                        for (int i = 0; i < nSecLDataArrays; i++) {\n                            long tmpL = secondaryLongData[i][a];\n                            secondaryLongData[i][a] = secondaryLongData[i][b];\n                            secondaryLongData[i][b] = tmpL;\n                        }\n\n                        for (int i = 0; i < nSecFDataArrays; i++) {\n                            float tmpF = secondaryFloatData[i][a];\n                            secondaryFloatData[i][a] = secondaryFloatData[i][b];\n                            secondaryFloatData[i][b] = tmpF;\n                        }\n                    }\n                }\n            }).sort(sortOrder);\n\n        len = off + len; // Note that supplied len may be for a subset of the array, but what's ultimately needed is\n                         // the number of non-zero elements for the whole array\n                         //if (truncateZeroItems) {  // Deal with the fact that some items in the bottom may be just zero\n                         //  while (len > 0 && results[len - 1] == 0) len--;\n                         //}\n\n        return len;\n    }\n\n    /**\n     * Sorts the results[] array, aligning secondaryData with it if it's present.\n     * Returns the number of non-zero elements, which may be smaller than the array size.\n     */\n    protected int sortResults(final float[] results, final int[][] secondaryIntData, final long[][] secondaryLongData, int off,\n                              int len, boolean truncateZeroItems) {\n        //if (createNamesFromScratch) doCreateClassNamesFromScratch();\n        final int nSecIDataArrays = (secondaryIntData != null) ? secondaryIntData.length : 0;\n        final int nSecLDataArrays = (secondaryLongData != null) ? secondaryLongData.length : 0;\n\n        (new FloatSorter(results, off, len) {\n                protected void swap(int a, int b) {\n                    if (results[a] != results[b]) {\n                        super.swap(a, b);\n\n                        String tmp = sortedClassNames[a];\n                        sortedClassNames[a] = sortedClassNames[b];\n                        sortedClassNames[b] = tmp;\n\n                        int tmpI = sortedClassIds[a];\n                        sortedClassIds[a] = sortedClassIds[b];\n                        sortedClassIds[b] = tmpI;\n\n                        for (int i = 0; i < nSecIDataArrays; i++) {\n                            tmpI = secondaryIntData[i][a];\n                            secondaryIntData[i][a] = secondaryIntData[i][b];\n                            secondaryIntData[i][b] = tmpI;\n                        }\n\n                        for (int i = 0; i < nSecLDataArrays; i++) {\n                            long tmpL = secondaryLongData[i][a];\n                            secondaryLongData[i][a] = secondaryLongData[i][b];\n                            secondaryLongData[i][b] = tmpL;\n                        }\n                    }\n                }\n            }).sort(sortOrder);\n\n        len = off + len; // Note that supplied len may be for a subset of the array, but what's ultimately needed is\n                         // the number of non-zero elements for the whole array\n                         //if (truncateZeroItems) {  // Deal with the fact that some items in the bottom may be just zero\n                         //  while (len > 0 && results[len - 1] == 0) len--;\n                         //}\n\n        return len;\n    }\n\n    /**\n     * Sorts the results by class name, aligning secondaryIntData and secondaryFloatData with it if it's present.\n     * Additionally, if truncateZeroItems is true, gets items for which secondaryIntData[0][i] is 0, to bottom.\n     * Returns the number of non-zero (as above) elements, which may be smaller than the array size.\n     */\n    protected int sortResultsByClassName(final int[][] secondaryIntData, final long[][] secondaryLongData,\n                                         final float[][] secondaryFloatData, int len, boolean truncateZeroItems) {\n        if (len == 0) {\n            return 0; // no processing for zero-length\n                      //if (createNamesFromScratch) doCreateClassNamesFromScratch();\n        }\n\n        final int nSecIDataArrays = (secondaryIntData != null) ? secondaryIntData.length : 0;\n        final int nSecLDataArrays = (secondaryLongData != null) ? secondaryLongData.length : 0;\n        final int nSecFDataArrays = (secondaryFloatData != null) ? secondaryFloatData.length : 0;\n\n        if (truncateZeroItems) { // Move zero items to the bottom\n\n            int head = 0;\n            int tail = len - 1;\n\n            while (head < tail) {\n                while ((secondaryIntData[0][tail] == 0) && (tail > head)) {\n                    tail--;\n                }\n\n                if (tail <= head) {\n                    break;\n                }\n\n                while ((secondaryIntData[0][head] != 0) && (head < tail)) {\n                    head++;\n                }\n\n                if (head >= tail) {\n                    break;\n                }\n\n                // Now data[headPos] == 0 and data[tailPos] != 0 - swap them\n                String tmpS = sortedClassNames[head];\n                sortedClassNames[head] = sortedClassNames[tail];\n                sortedClassNames[tail] = tmpS;\n\n                int tmpI = sortedClassIds[head];\n                sortedClassIds[head] = sortedClassIds[tail];\n                sortedClassIds[tail] = tmpI;\n\n                for (int i = 0; i < nSecIDataArrays; i++) {\n                    tmpI = secondaryIntData[i][head];\n                    secondaryIntData[i][head] = secondaryIntData[i][tail];\n                    secondaryIntData[i][tail] = tmpI;\n                }\n\n                for (int i = 0; i < nSecLDataArrays; i++) {\n                    long tmpL = secondaryLongData[i][head];\n                    secondaryLongData[i][head] = secondaryLongData[i][tail];\n                    secondaryLongData[i][tail] = tmpL;\n                }\n\n                for (int i = 0; i < nSecFDataArrays; i++) {\n                    float tmpF = secondaryFloatData[i][head];\n                    secondaryFloatData[i][head] = secondaryFloatData[i][tail];\n                    secondaryFloatData[i][tail] = tmpF;\n                }\n\n                head++;\n                tail--;\n            }\n\n            len = head;\n\n//            if ((secondaryIntData == null) || (secondaryIntData[0] == null) || (secondaryIntData.length == 0)\n//                    || (secondaryIntData[0].length == 0)) {\n//                System.out.println(\"break me\"); // NOI18N\n//            }\n\n            if (secondaryIntData[0][len] != 0) {\n                len++;\n            }\n        }\n\n        (new StringSorter(sortedClassNames, 0, len) {\n                protected void swap(int a, int b) {\n                    super.swap(a, b);\n\n                    int tmpI = sortedClassIds[a];\n                    sortedClassIds[a] = sortedClassIds[b];\n                    sortedClassIds[b] = tmpI;\n\n                    for (int i = 0; i < nSecIDataArrays; i++) {\n                        tmpI = secondaryIntData[i][a];\n                        secondaryIntData[i][a] = secondaryIntData[i][b];\n                        secondaryIntData[i][b] = tmpI;\n                    }\n\n                    for (int i = 0; i < nSecLDataArrays; i++) {\n                        long tmpL = secondaryLongData[i][a];\n                        secondaryLongData[i][a] = secondaryLongData[i][b];\n                        secondaryLongData[i][b] = tmpL;\n                    }\n\n                    for (int i = 0; i < nSecFDataArrays; i++) {\n                        float tmpF = secondaryFloatData[i][a];\n                        secondaryFloatData[i][a] = secondaryFloatData[i][b];\n                        secondaryFloatData[i][b] = tmpF;\n                    }\n                }\n            }).sort(sortOrder);\n\n        return len;\n    }\n\n    protected boolean truncateZeroItems() {\n        return true;\n    }\n\n    // ---\n    private void initFilterPanel() {\n        filterComponent = FilterComponent.create(true, true);\n        filterComponent.setHint(CLASS_NAME_FILTER);\n\n        filterComponent.setFilter(filterString, filterType);\n        filterComponent.addChangeListener(new ChangeListener() {\n                public void stateChanged(ChangeEvent e) {\n                    String selectedRowContents = null;\n                    int selectedRow = resTable.getSelectedRow();\n\n                    if (selectedRow != -1) {\n                        selectedRowContents = (String) resTable.getValueAt(selectedRow, 0);\n                    }\n\n                    filterString = filterComponent.getFilterValue();\n                    filterType = filterComponent.getFilterType();\n                    createFilteredIndexes();\n                    resTable.invalidate();\n                    jScrollPane.revalidate();\n                    resTable.repaint();\n\n                    if (selectedRowContents != null) {\n                        resTable.selectRowByContents(selectedRowContents, 0, true);\n                    }\n                }\n            });\n\n        add(filterComponent.getComponent(), BorderLayout.SOUTH);\n    }\n\n    private boolean passesFilter(int idx, String filter) {\n        String value = sortedClassNames[idx];\n\n        if (\"\".equals(filter)) {\n            return true; // NOI18N\n        }\n\n        // Case sensitive comparison:\n        /*switch (type) {\n           case CommonConstants.FILTER_STARTS_WITH:\n             return value.startsWith(filter);\n           case CommonConstants.FILTER_CONTAINS:\n             return value.indexOf(filter) != -1;\n           case CommonConstants.FILTER_ENDS_WITH:\n             return value.endsWith(filter);\n           case CommonConstants.FILTER_EQUALS:\n             return value.equals(filter);\n           case CommonConstants.FILTER_REGEXP:\n             return value.matches(filter);\n           }*/\n\n        // Case insensitive comparison (except regexp):\n        switch (filterType) {\n//            case CommonConstants.FILTER_STARTS_WITH:\n//                return value.regionMatches(true, 0, filter, 0, filter.length()); // case insensitive startsWith, optimized\n            case CommonConstants.FILTER_CONTAINS:\n                return value.toLowerCase().contains(filter); // case insensitive indexOf, NOT OPTIMIZED!!!\n            case CommonConstants.FILTER_NOT_CONTAINS:\n                return !value.toLowerCase().contains(filter);\n//            case CommonConstants.FILTER_ENDS_WITH:\n//                return value.regionMatches(true, value.length() - filter.length(), filter, 0, filter.length()); // case insensitive endsWith, optimized\n//            case CommonConstants.FILTER_EQUALS:\n//                return value.equalsIgnoreCase(filter); // case insensitive equals\n            case CommonConstants.FILTER_REGEXP:\n                try {\n                    return value.matches(filter); //  case sensitive!\n                } catch (java.util.regex.PatternSyntaxException e) {\n                    return false;\n                }\n        }\n\n        return false;\n    }\n\n    private boolean passesFilters(int idx) {\n        if (filterType == CommonConstants.FILTER_NONE) {\n            return true;\n        }\n\n        String[] filters = FilterComponent.getFilterValues(filterString);\n\n        if (filters == null) {\n            return true;\n        }\n\n        for (String filter : filters) {\n            if (passesFilter(idx, filter)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/MemoryView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.util.ResourceBundle;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.ui.results.DataView;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class MemoryView extends DataView {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    static final String EXPORT_TOOLTIP = messages.getString(\"MemoryView_ExportTooltip\"); // NOI18N\n    static final String EXPORT_OBJECTS = messages.getString(\"MemoryView_ExportObjects\"); // NOI18N\n    static final String EXPORT_LIVE = messages.getString(\"MemoryView_ExportLive\"); // NOI18N\n    static final String EXPORT_ALLOCATED = messages.getString(\"MemoryView_ExportAllocated\"); // NOI18N\n    static final String EXPORT_ALLOCATED_LIVE = messages.getString(\"MemoryView_ExportAllocatedLive\"); // NOI18N\n    static final String COLUMN_NAME = messages.getString(\"MemoryView_ColumnName\"); // NOI18N\n    static final String COLUMN_ALLOCATED_BYTES = messages.getString(\"MemoryView_ColumnAllocatedBytes\"); // NOI18N\n    static final String COLUMN_ALLOCATED_OBJECTS = messages.getString(\"MemoryView_ColumnAllocatedObjects\"); // NOI18N\n    static final String COLUMN_LIVE_BYTES = messages.getString(\"MemoryView_ColumnLiveBytes\"); // NOI18N\n    static final String COLUMN_LIVE_OBJECTS = messages.getString(\"MemoryView_ColumnLiveObjects\"); // NOI18N\n    static final String COLUMN_TOTAL_ALLOCATED_OBJECTS = messages.getString(\"MemoryView_ColumnTotalAllocatedObjects\"); // NOI18N\n    static final String COLUMN_AVG_AGE = messages.getString(\"MemoryView_ColumnAvgAge\"); // NOI18N\n    static final String COLUMN_GENERATIONS = messages.getString(\"MemoryView_ColumnGenerations\"); // NOI18N\n    static final String COLUMN_SELECTED = messages.getString(\"MemoryView_ColumnSelected\"); // NOI18N\n    static final String ACTION_GOTOSOURCE = messages.getString(\"MemoryView_ActionGoToSource\"); // NOI18N\n    static final String ACTION_PROFILE_METHOD = messages.getString(\"MemoryView_ActionProfileMethod\"); // NOI18N\n    static final String ACTION_PROFILE_CLASS = messages.getString(\"MemoryView_ActionProfileClass\"); // NOI18N\n    static final String SELECTED_COLUMN_TOOLTIP = messages.getString(\"MemoryView_SelectedColumnTooltip\"); // NOI18N\n    static final String NAME_COLUMN_TOOLTIP = messages.getString(\"MemoryView_NameColumnTooltip\"); // NOI18N\n    static final String LIVE_SIZE_COLUMN_TOOLTIP = messages.getString(\"MemoryView_LiveSizeColumnTooltip\"); // NOI18N\n    static final String LIVE_COUNT_COLUMN_TOOLTIP = messages.getString(\"MemoryView_LiveCountColumnTooltip\"); // NOI18N\n    static final String ALLOC_SIZE_COLUMN_TOOLTIP = messages.getString(\"MemoryView_AllocSizeColumnTooltip\"); // NOI18N\n    static final String ALLOC_COUNT_COLUMN_TOOLTIP = messages.getString(\"MemoryView_AllocCountColumnTooltip\"); // NOI18N\n    static final String TOTAL_ALLOC_COUNT_COLUMN_TOOLTIP = messages.getString(\"MemoryView_TotalAllocCountColumnTooltip\"); // NOI18N\n    static final String AVG_AGE_COLUMN_TOOLTIP = messages.getString(\"MemoryView_AvgAgeColumnTooltip\"); // NOI18N\n    static final String GENERATIONS_COLUMN_TOOLTIP = messages.getString(\"MemoryView_GenerationsColumnTooltip\"); // NOI18N\n    static final String FILTER_CLASSES_SCOPE = messages.getString(\"MemoryView_FilterClassesScope\"); // NOI18N\n    static final String FILTER_ALLOCATIONS_SCOPE = messages.getString(\"MemoryView_FilterAllocationsScope\"); // NOI18N\n    static final String FILTER_SCOPE_TOOLTIP = messages.getString(\"MemoryView_FilterScopeTooltip\"); // NOI18N\n    static final String SEARCH_CLASSES_SCOPE = messages.getString(\"MemoryView_SearchClassesScope\"); // NOI18N\n    static final String SEARCH_ALLOCATIONS_SCOPE = messages.getString(\"MemoryView_SearchAllocationsScope\"); // NOI18N\n    static final String SEARCH_SCOPE_TOOLTIP = messages.getString(\"MemoryView_SearchScopeTooltip\"); // NOI18N\n    static final String EXPAND_MENU = messages.getString(\"MemoryView_ExpandMenu\"); // NOI18N\n    static final String EXPAND_PLAIN_ITEM = messages.getString(\"MemoryView_ExpandPlainItem\"); // NOI18N\n    static final String EXPAND_TOPMOST_ITEM = messages.getString(\"MemoryView_ExpandTopmostItem\"); // NOI18N\n    static final String COLLAPSE_CHILDREN_ITEM = messages.getString(\"MemoryView_CollapseChildrenItem\"); // NOI18N\n    static final String COLLAPSE_ALL_ITEM = messages.getString(\"MemoryView_CollapseAllItem\"); // NOI18N\n    // -----_GenerationsCo\n    \n    \n    public abstract void setData(MemoryResultsSnapshot snapshot, GenericFilter filter, int aggregation);\n    \n    public abstract void resetData();\n    \n    \n    public abstract void showSelectionColumn();\n    \n    public abstract void refreshSelection();\n    \n    \n    public abstract ExportUtils.ExportProvider[] getExportProviders();\n    \n    \n    protected abstract ProfilerTable getResultsComponent();\n    \n    \n    static void userFormClassNames(MemoryResultsSnapshot snapshot) {\n        // class names in VM format\n        String[] classNames = snapshot == null ? null : snapshot.getClassNames();\n        if (classNames != null) for (int i = 0; i < classNames.length; i++)\n            classNames[i] = StringUtils.userFormClassName(classNames[i]);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/ReverseMemCallGraphPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.*;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumnModel;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.ResultsPanel;\nimport org.graalvm.visualvm.lib.ui.components.FilterComponent;\nimport org.graalvm.visualvm.lib.ui.components.JTreeTable;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelBracketTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.tree.EnhancedTreeCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.tree.MethodNameTreeCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.treetable.ExtendedTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.JTreeTablePanel;\n\n\n/**\n * A panel containing a reverse call graph for all allocations of instances of a given class\n *\n * @author Misha Dmitriev\n * @author Jiri Sedlacek\n */\npublic abstract class ReverseMemCallGraphPanel extends ResultsPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String METHOD_COLUMN_NAME = messages.getString(\"ReverseMemCallGraphPanel_MethodColumnName\"); // NOI18N\n    private static final String LIVE_BYTES_REL_COLUMN_NAME = messages.getString(\"ReverseMemCallGraphPanel_LiveBytesRelColumnName\"); // NOI18N\n    private static final String LIVE_BYTES_COLUMN_NAME = messages.getString(\"ReverseMemCallGraphPanel_LiveBytesColumnName\"); // NOI18N\n    private static final String LIVE_OBJECTS_COLUMN_NAME = messages.getString(\"ReverseMemCallGraphPanel_LiveObjectsColumnName\"); // NOI18N\n    private static final String ALLOC_OBJECTS_COLUMN_NAME = messages.getString(\"ReverseMemCallGraphPanel_AllocObjectsColumnName\"); // NOI18N\n    private static final String AVG_AGE_COLUMN_NAME = messages.getString(\"ReverseMemCallGraphPanel_AvgAgeColumnName\"); // NOI18N\n    private static final String SURVGEN_COLUMN_NAME = messages.getString(\"ReverseMemCallGraphPanel_SurvGenColumnName\"); // NOI18N\n    private static final String METHOD_COLUMN_TOOLTIP = messages.getString(\"ReverseMemCallGraphPanel_MethodColumnToolTip\"); // NOI18N\n    private static final String LIVE_BYTES_REL_COLUMN_TOOLTIP = messages.getString(\"ReverseMemCallGraphPanel_LiveBytesRelColumnToolTip\"); // NOI18N\n    private static final String LIVE_BYTES_COLUMN_TOOLTIP = messages.getString(\"ReverseMemCallGraphPanel_LiveBytesColumnToolTip\"); // NOI18N\n    private static final String LIVE_OBJECTS_COLUMN_TOOLTIP = messages.getString(\"ReverseMemCallGraphPanel_LiveObjectsColumnToolTip\"); // NOI18N\n    private static final String ALLOC_OBJECTS_COLUMN_TOOLTIP = messages.getString(\"ReverseMemCallGraphPanel_AllocObjectsColumnToolTip\"); // NOI18N\n    private static final String AVG_AGE_COLUMN_TOOLTIP = messages.getString(\"ReverseMemCallGraphPanel_AvgAgeColumnToolTip\"); // NOI18N\n    private static final String SURVGEN_COLUMN_TOOLTIP = messages.getString(\"ReverseMemCallGraphPanel_SurvGenColumnToolTip\"); // NOI18N\n    private static final String BYTES_ALLOC_REL_COLUMN_NAME = messages.getString(\"ReverseMemCallGraphPanel_BytesAllocRelColumnName\"); // NOI18N\n    private static final String BYTES_ALLOC_COLUMN_NAME = messages.getString(\"ReverseMemCallGraphPanel_BytesAllocColumnName\"); // NOI18N\n    private static final String OBJECTS_ALLOC_COLUMN_NAME = messages.getString(\"ReverseMemCallGraphPanel_ObjectsAllocColumnName\"); // NOI18N\n    private static final String BYTES_ALLOC_REL_COLUMN_TOOLTIP = messages.getString(\"ReverseMemCallGraphPanel_BytesAllocRelColumnToolTip\"); // NOI18N\n    private static final String BYTES_ALLOC_COLUMN_TOOLTIP = messages.getString(\"ReverseMemCallGraphPanel_BytesAllocColumnToolTip\"); // NOI18N\n    private static final String OBJECTS_ALLOC_COLUMN_TOOLTIP = messages.getString(\"ReverseMemCallGraphPanel_ObjectsAllocColumnToolTip\"); // NOI18N\n    private static final String GO_SOURCE_POPUP_ITEM = messages.getString(\"ReverseMemCallGraphPanel_GoSourcePopupItem\"); // NOI18N\n    private static final String FILTER_ITEM_NAME = messages.getString(\"AllocResultsPanel_FilterMenuItemName\"); // NOI18N\n                                                                                                                         // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected ExtendedTreeTableModel treeTableModel;\n    protected JButton cornerButton;\n    protected JPopupMenu headerPopup;\n    protected JPopupMenu popupMenu;\n    protected JTreeTable treeTable;\n    protected JTreeTablePanel treeTablePanel;\n    protected FilterComponent filterComponent;\n    protected JMenuItem popupShowSource;\n    protected MemoryResUserActionsHandler actionsHandler;\n    protected TreePath treePath;\n    protected String[] columnNames;\n    protected TableCellRenderer[] columnRenderers;\n    protected String[] columnToolTips;\n    protected int[] columnWidths;\n    protected boolean extendedResults; // determines Alloc./Liveness results\n    protected int columnCount = 0;\n    protected int minNamesColumnWidth; // minimal width of classnames columns\n    CustomBarCellRenderer customBarCellRenderer;\n    private EnhancedTreeCellRenderer enhancedTreeCellRenderer = new MethodNameTreeCellRenderer();\n    private Icon leafIcon = Icons.getIcon(ProfilerIcons.NODE_REVERSE);\n    private Icon nodeIcon = Icons.getIcon(ProfilerIcons.NODE_REVERSE);\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ReverseMemCallGraphPanel(MemoryResUserActionsHandler actionsHandler, boolean extendedResults) {\n        super();\n        this.extendedResults = extendedResults;\n        this.actionsHandler = actionsHandler;\n\n        enhancedTreeCellRenderer.setLeafIcon(leafIcon);\n        enhancedTreeCellRenderer.setClosedIcon(nodeIcon);\n        enhancedTreeCellRenderer.setOpenIcon(nodeIcon);\n\n        minNamesColumnWidth = getFontMetrics(getFont()).charWidth('W') * 30; // NOI18N\n\n        headerPopup = new JPopupMenu();\n        cornerButton = createHeaderPopupCornerButton(headerPopup);\n\n        popupMenu = initPopupMenu();\n\n        initColumnsData();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    // --- Find functionality stuff\n    public void setFindString(String findString) {\n        if (treeTable != null) {\n            treeTable.setFindParameters(findString, 0);\n        }\n    }\n\n    public String getFindString() {\n        if (treeTable == null) {\n            return null;\n        }\n\n        return treeTable.getFindString();\n    }\n\n    public boolean isFindStringDefined() {\n        if (treeTable == null) {\n            return false;\n        }\n\n        return treeTable.isFindStringDefined();\n    }\n\n    public boolean findFirst() {\n        if (treeTable == null) {\n            return false;\n        }\n\n        return treeTable.findFirst();\n    }\n\n    public boolean findNext() {\n        if (treeTable == null) {\n            return false;\n        }\n\n        return treeTable.findNext();\n    }\n\n    public boolean findPrevious() {\n        if (treeTable == null) {\n            return false;\n        }\n\n        return treeTable.findPrevious();\n    }\n\n    public void requestFocus() {\n        if (treeTable != null) {\n            SwingUtilities.invokeLater(new Runnable() { // must be invoked lazily to override default focus of first component (top-right cornerButton)\n                    public void run() {\n                        treeTable.requestFocus();\n                    }\n                });\n        }\n    }\n\n    protected void setColumnsData() {\n        int index;\n        TableColumnModel colModel = treeTable.getColumnModel();\n\n        treeTable.setTreeCellRenderer(enhancedTreeCellRenderer);\n        colModel.getColumn(0).setPreferredWidth(minNamesColumnWidth);\n\n        for (int i = 0; i < treeTableModel.getColumnCount(); i++) {\n            index = treeTableModel.getRealColumn(i);\n\n            if (index != 0) {\n                colModel.getColumn(i).setPreferredWidth(columnWidths[index - 1]);\n                colModel.getColumn(i).setCellRenderer(columnRenderers[index]);\n            }\n        }\n    }\n\n    protected void initColumnSelectorItems() {\n        headerPopup.removeAll();\n\n        JCheckBoxMenuItem menuItem;\n        boolean columnVisible;\n\n        for (int i = 0; i < columnCount; i++) {\n            menuItem = new JCheckBoxMenuItem(columnNames[i]);\n            menuItem.setActionCommand(Integer.toString(i));\n            addMenuItemListener(menuItem);\n\n            if (treeTable != null) {\n                columnVisible = treeTableModel.isRealColumnVisible(i);\n                menuItem.setState(treeTableModel.isRealColumnVisible(i));\n\n                if (i == 0) {\n                    menuItem.setEnabled(false);\n                }\n            } else {\n                menuItem.setState(true);\n            }\n\n            headerPopup.add(menuItem);\n        }\n        \n        headerPopup.addSeparator();\n\n        JCheckBoxMenuItem filterMenuItem = new JCheckBoxMenuItem(FILTER_ITEM_NAME);\n        filterMenuItem.setActionCommand(\"Filter\"); // NOI18N\n        addMenuItemListener(filterMenuItem);\n\n        if (filterComponent == null) {\n            filterMenuItem.setState(true);\n        } else {\n            filterMenuItem.setState(filterComponent.getComponent().isVisible());\n        }\n        \n        headerPopup.add(filterMenuItem);\n\n        headerPopup.pack();\n    }\n\n    protected JPopupMenu initPopupMenu() {\n        JPopupMenu popup = new JPopupMenu();\n        Font boldfont = popup.getFont().deriveFont(Font.BOLD);\n\n        if (GoToSource.isAvailable()) {\n            popupShowSource = new JMenuItem();\n            popupShowSource.setFont(boldfont);\n            popupShowSource.setText(GO_SOURCE_POPUP_ITEM);\n            popupShowSource.addActionListener(new java.awt.event.ActionListener() {\n                    public void actionPerformed(java.awt.event.ActionEvent evt) {\n                        if (treePath != null) {\n                            performDefaultAction(treePath);\n                        }\n                    }\n                });\n            popup.add(popupShowSource);\n        }\n\n        return popup;\n    }\n\n    void performDefaultAction(TreePath path) {\n        PresoObjAllocCCTNode node = (PresoObjAllocCCTNode) path.getLastPathComponent();\n        if (node.isFiltered()) return;\n        String[] classMethodAndSig = node.getMethodClassNameAndSig();\n        if (node.getParent() == null) showSourceForClass(classMethodAndSig[0]);\n        else actionsHandler.showSourceForMethod(classMethodAndSig[0], classMethodAndSig[1], classMethodAndSig[2]);\n    }\n    \n    private void showSourceForClass(String className) {\n        className = className.replace(\"[]\", \"\"); // NOI18N\n        actionsHandler.showSourceForMethod(className, null, null);\n    }\n\n    private void addMenuItemListener(JCheckBoxMenuItem menuItem) {\n        menuItem.addActionListener(new java.awt.event.ActionListener() {\n                public void actionPerformed(java.awt.event.ActionEvent e) {\n                    if (e.getActionCommand().equals(\"Filter\")) { // NOI18N\n                        filterComponent.getComponent().setVisible(!filterComponent.getComponent().isVisible());\n\n                        return;\n                    }\n                    \n                    boolean sortResults = false;\n                    int column = Integer.parseInt(e.getActionCommand());\n                    boolean sortOrder = treeTable.getSortingOrder();\n                    int sortingColumn = treeTable.getSortingColumn();\n                    int realSortingColumn = treeTableModel.getRealColumn(sortingColumn);\n                    boolean isColumnVisible = treeTableModel.isRealColumnVisible(column);\n\n                    // Current sorting column is going to be hidden\n                    if ((isColumnVisible) && (column == realSortingColumn)) {\n                        // Try to set next column as a sortingColumn. If currentSortingColumn is the last column, set previous\n                        // column as a sorting Column (one column is always visible).\n                        sortingColumn = ((sortingColumn + 1) == treeTableModel.getColumnCount()) ? (sortingColumn - 1)\n                                                                                                 : (sortingColumn + 1);\n                        realSortingColumn = treeTableModel.getRealColumn(sortingColumn);\n                        sortResults = true;\n                    }\n\n                    treeTableModel.setRealColumnVisibility(column, !isColumnVisible);\n                    treeTable.createDefaultColumnsFromModel();\n                    treeTable.updateTreeTableHeader();\n                    sortingColumn = treeTableModel.getVirtualColumn(realSortingColumn);\n\n                    if (sortResults) {\n                        sortOrder = treeTableModel.getInitialSorting(sortingColumn);\n                        treeTableModel.sortByColumn(sortingColumn, sortOrder);\n                        treeTable.updateTreeTable();\n                    }\n\n                    treeTable.setSortingColumn(sortingColumn);\n                    treeTable.setSortingOrder(sortOrder);\n                    treeTable.getTableHeader().repaint();\n                    setColumnsData();\n\n                    // TODO [ui-persistence]\n                }\n            });\n    }\n\n    private void initColumnsData() {\n        if (extendedResults) {\n            columnNames = new String[] {\n                              METHOD_COLUMN_NAME, LIVE_BYTES_REL_COLUMN_NAME, LIVE_BYTES_COLUMN_NAME, LIVE_OBJECTS_COLUMN_NAME,\n                              ALLOC_OBJECTS_COLUMN_NAME, AVG_AGE_COLUMN_NAME, SURVGEN_COLUMN_NAME\n                          };\n            columnToolTips = new String[] {\n                                 METHOD_COLUMN_TOOLTIP, LIVE_BYTES_REL_COLUMN_TOOLTIP, LIVE_BYTES_COLUMN_TOOLTIP,\n                                 LIVE_OBJECTS_COLUMN_TOOLTIP, ALLOC_OBJECTS_COLUMN_TOOLTIP, AVG_AGE_COLUMN_TOOLTIP,\n                                 SURVGEN_COLUMN_TOOLTIP,\n                             };\n        } else {\n            columnNames = new String[] {\n                              METHOD_COLUMN_NAME, BYTES_ALLOC_REL_COLUMN_NAME, BYTES_ALLOC_COLUMN_NAME, OBJECTS_ALLOC_COLUMN_NAME\n                          };\n            columnToolTips = new String[] {\n                                 METHOD_COLUMN_TOOLTIP, BYTES_ALLOC_REL_COLUMN_TOOLTIP, BYTES_ALLOC_COLUMN_TOOLTIP,\n                                 OBJECTS_ALLOC_COLUMN_TOOLTIP,\n                             };\n        }\n\n        columnCount = columnNames.length;\n\n        columnWidths = new int[columnCount - 1]; // Width of the first column fits to width\n        columnRenderers = new TableCellRenderer[columnCount];\n\n        LabelBracketTableCellRenderer labelBracketTableCellRenderer = new LabelBracketTableCellRenderer(JLabel.TRAILING);\n        LabelTableCellRenderer labelTableCellRenderer = new LabelTableCellRenderer(JLabel.TRAILING);\n\n        int maxWidth; // initial width of data columns\n\n        if (extendedResults) {\n            maxWidth = getFontMetrics(getFont()).charWidth('W') * 10; // NOI18N\n        } else {\n            maxWidth = getFontMetrics(getFont()).charWidth('W') * 13; // NOI18N\n        }\n\n        columnRenderers[0] = null;\n\n        columnWidths[1 - 1] = maxWidth;\n        columnRenderers[1] = null;\n\n        for (int i = 2; i < 4; i++) {\n            columnWidths[i - 1] = maxWidth;\n            columnRenderers[i] = labelBracketTableCellRenderer;\n        }\n\n        for (int i = 4; i < columnNames.length; i++) {\n            columnWidths[i - 1] = maxWidth;\n            columnRenderers[i] = labelTableCellRenderer;\n        }\n    }\n\n    private void saveColumnsData() {\n        int index;\n        TableColumnModel colModel = treeTable.getColumnModel();\n\n        for (int i = 0; i < treeTableModel.getColumnCount(); i++) {\n            index = treeTableModel.getRealColumn(i);\n\n            if (index != 0) {\n                columnWidths[index - 1] = colModel.getColumn(i).getPreferredWidth();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/SampledResultsPanel.java",
    "content": "/*\n * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.AWTKeyStroke;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyEvent;\nimport java.util.HashSet;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport javax.swing.*;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedTable;\nimport org.graalvm.visualvm.lib.ui.components.table.ClassNameTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.ExtendedTableModel;\nimport org.graalvm.visualvm.lib.ui.components.table.LabelBracketTableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.SortableTableModel;\n\n\n/**\n * This class implements presentation frames for Object Allocation Profiling.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic abstract class SampledResultsPanel extends MemoryResultsPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String FILTER_MENU_ITEM_NAME = messages.getString(\"SampledResultsPanel_FilterMenuItemName\"); // NOI18N\n    private static final String CLASS_COLUMN_NAME = messages.getString(\"SampledResultsPanel_ClassColumnName\"); // NOI18N\n    private static final String BYTES_REL_COLUMN_NAME = messages.getString(\"SampledResultsPanel_BytesRelColumnName\"); // NOI18N\n    private static final String BYTES_COLUMN_NAME = messages.getString(\"SampledResultsPanel_BytesColumnName\"); // NOI18N\n    private static final String OBJECTS_COLUMN_NAME = messages.getString(\"SampledResultsPanel_ObjectsColumnName\"); // NOI18N\n    private static final String CLASS_COLUMN_TOOLTIP = messages.getString(\"SampledResultsPanel_ClassColumnToolTip\"); // NOI18N\n    private static final String BYTES_REL_COLUMN_TOOLTIP = messages.getString(\"SampledResultsPanel_BytesRelColumnToolTip\"); // NOI18N\n    private static final String BYTES_COLUMN_TOOLTIP = messages.getString(\"SampledResultsPanel_BytesColumnToolTip\"); // NOI18N\n    private static final String OBJECTS_COLUMN_TOOLTIP = messages.getString(\"SampledResultsPanel_ObjectsColumnToolTip\"); // NOI18N\n    private static final String TABLE_ACCESS_NAME = messages.getString(\"SampledResultsPanel_TableAccessName\"); // NOI18N\n                                                                                                             // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected int[] nTotalLiveObjects;\n    protected long[] totalLiveObjectsSize;\n    protected long nTotalLiveBytes;\n    protected long nTotalClasses;\n    private int initialSortingColumn;\n    private int minNamesColumnWidth; // minimal width of classnames columns\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SampledResultsPanel(MemoryResUserActionsHandler actionsHandler) {\n        super(actionsHandler);\n\n        setDefaultSorting();\n\n        initColumnsData();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    // NOTE: this method only sets sortBy and sortOrder, it doesn't refresh UI!\n    public void setDefaultSorting() {\n        setSorting(1, SortableTableModel.SORT_ORDER_DESC);\n    }\n\n    // NOTE: this method only sets sortBy and sortOrder, it doesn't refresh UI!\n    public void setSorting(int sColumn, boolean sOrder) {\n        if (sColumn == CommonConstants.SORTING_COLUMN_DEFAULT) {\n            setDefaultSorting();\n        } else {\n            initialSortingColumn = sColumn;\n            sortBy = getSortBy(initialSortingColumn);\n            sortOrder = sOrder;\n        }\n    }\n\n    public int getSortingColumn() {\n        if (resTableModel == null) {\n            return CommonConstants.SORTING_COLUMN_DEFAULT;\n        }\n\n        return resTableModel.getRealColumn(resTableModel.getSortingColumn());\n    }\n\n    public boolean getSortingOrder() {\n        if (resTableModel == null) {\n            return false;\n        }\n\n        return resTableModel.getSortingOrder();\n    }\n\n    protected abstract JPopupMenu getPopupMenu();\n\n    protected CustomBarCellRenderer getBarCellRenderer() {\n//        return new CustomBarCellRenderer(0, maxValue);\n        return new CustomBarCellRenderer(0, 100);\n    }\n\n    protected void getResultsSortedByLiveObjNumber() {\n        //\n        getResultsSortedByClassName(true); // Added because of lines toggling when switching between columns 1 and 2.\n                                           // At first items must be sorted by class names to get defined initial state for\n                                           // other sorting.\n\n        int visibleLines = nInfoLines; // Zero or unprofiled classes are filtered, sorting will be applied only to live\n                                       // data\n                                       //\n\n        nInfoLines = sortResults(nTotalLiveObjects, null, new long[][] { totalLiveObjectsSize }, null, 0, visibleLines, false);\n\n        totalAllocations = 0;\n\n        for (int i = 0; i < nInfoLines; i++) {\n            totalAllocations += nTotalLiveObjects[i];\n        }\n    }\n\n    protected void getResultsSortedByLiveObjSize() {\n        //\n        getResultsSortedByClassName(true); // Added because of lines toggling when switching between columns 1 and 2.\n                                           // At first items must be sorted by class names to get defined initial state\n                                           // for other sorting.\n\n        int visibleLines = nInfoLines; // Zero or unprofiled classes are filtered, sorting will be applied only to live\n                                       // data\n                                       //\n\n        nInfoLines = sortResults(totalLiveObjectsSize, new int[][] { nTotalLiveObjects }, null, null, 0, visibleLines, false);\n\n        totalAllocations = 0;\n\n        for (int i = 0; i < nInfoLines; i++) {\n            totalAllocations += nTotalLiveObjects[i];\n        }\n    }\n\n    protected void getResultsSortedByClassName(boolean presortOnly) {\n        nInfoLines = sortResultsByClassName(new int[][] { nTotalLiveObjects }, new long[][] { totalLiveObjectsSize }, null,\n                                            nTrackedItems, truncateZeroItems());\n\n        if (!presortOnly) {\n            totalAllocations = 0;\n\n            for (int i = 0; i < nInfoLines; i++) {\n                totalAllocations += nTotalLiveObjects[i];\n            }\n        }\n    }\n\n    protected JExtendedTable getResultsTable() {\n        sortResults();\n\n        if (resTable == null) {\n            resTableModel = new ExtendedTableModel(new SortableTableModel() {\n                    public String getColumnName(int col) {\n                        return columnNames[col];\n                    }\n\n                    public int getRowCount() {\n                        return nDisplayedItems;\n                    }\n\n                    public int getColumnCount() {\n                        return columnNames.length;\n                    }\n\n                    public Class<?> getColumnClass(int col) {\n                        return columnTypes[col];\n                    }\n\n                    public Object getValueAt(int row, int col) {\n                        return computeValueAt(row, col);\n                    }\n\n                    public String getColumnToolTipText(int col) {\n                        return columnToolTips[col];\n                    }\n\n                    public void sortByColumn(int column, boolean order) {\n                        sortBy = getSortBy(column);\n                        sortOrder = order;\n\n                        int selectedRow = resTable.getSelectedRow();\n                        String selectedRowContents = null;\n\n                        if (selectedRow != -1) {\n                            selectedRowContents = (String) resTable.getValueAt(selectedRow, 0);\n                        }\n\n                        prepareResults();\n\n                        if (selectedRowContents != null) {\n                            resTable.selectRowByContents(selectedRowContents, 0, true);\n                        }\n                    }\n\n                    /**\n                     * @param column The table column index\n                     * @return Initial sorting for the specified column - if true, ascending, if false descending\n                     */\n                    public boolean getInitialSorting(int column) {\n                        switch (column) {\n                            case 0:\n                                return true;\n                            default:\n                                return false;\n                        }\n                    }\n                });\n\n            resTable = new JExtendedTable(resTableModel) {\n                    public void doLayout() {\n                        int columnsWidthsSum = 0;\n                        int realFirstColumn = -1;\n\n                        int index;\n\n                        for (int i = 0; i < resTableModel.getColumnCount(); i++) {\n                            index = resTableModel.getRealColumn(i);\n\n                            if (index == 0) {\n                                realFirstColumn = i;\n                            } else {\n                                columnsWidthsSum += getColumnModel().getColumn(i).getPreferredWidth();\n                            }\n                        }\n\n                        if (realFirstColumn != -1) {\n                            getColumnModel().getColumn(realFirstColumn)\n                                .setPreferredWidth(Math.max(getWidth() - columnsWidthsSum, minNamesColumnWidth));\n                        }\n\n                        super.doLayout();\n                    }\n\n                };\n            resTable.getAccessibleContext().setAccessibleName(TABLE_ACCESS_NAME);\n\n            resTableModel.setTable(resTable);\n            resTableModel.setInitialSorting(initialSortingColumn, sortOrder);\n            resTable.setRowSelectionAllowed(true);\n            resTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n            resTable.setGridColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);\n            resTable.setSelectionBackground(UIConstants.TABLE_SELECTION_BACKGROUND_COLOR);\n            resTable.setSelectionForeground(UIConstants.TABLE_SELECTION_FOREGROUND_COLOR);\n            resTable.setShowHorizontalLines(UIConstants.SHOW_TABLE_HORIZONTAL_GRID);\n            resTable.setShowVerticalLines(UIConstants.SHOW_TABLE_VERTICAL_GRID);\n            resTable.setRowMargin(UIConstants.TABLE_ROW_MARGIN);\n            resTable.setRowHeight(UIUtils.getDefaultRowHeight() + 2);\n\n            // Disable traversing table cells using TAB and Shift+TAB\n            Set<AWTKeyStroke> keys = new HashSet<>(resTable.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));\n            keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));\n            resTable.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys);\n\n            keys = new HashSet<>(resTable.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));\n            keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));\n            resTable.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys);\n\n            setColumnsData();\n        }\n\n        return resTable;\n    }\n\n    protected Object computeValueAt(int row, int col) {\n        int index = filteredToFullIndexes.get(row).intValue();\n\n        switch (col) {\n            case 0:\n                return sortedClassNames[index];\n            case 1:\n//                return new Long(totalAllocObjectsSize[index]);\n                return (nTotalLiveBytes == 0) ? 0 : (double)totalLiveObjectsSize[index] / (double)nTotalLiveBytes * 100;\n            case 2:\n                return intFormat.format(totalLiveObjectsSize[index]) + \" B (\" // NOI18N\n                       + ((nTotalLiveBytes == 0) ? \"-%\"\n                                             : // NOI18N\n                percentFormat.format((double) totalLiveObjectsSize[index] / (double) nTotalLiveBytes)) + \")\"; // NOI18N\n            case 3:\n                return intFormat.format(nTotalLiveObjects[index]) + \" (\" // NOI18N\n                       + ((nTotalClasses == 0) ? \"-%\"\n                                               : // NOI18N\n                percentFormat.format((double) nTotalLiveObjects[index] / (double) nTotalClasses)) + \")\"; // NOI18N\n            default:\n                return null;\n        }\n    }\n\n    protected void initColumnSelectorItems() {\n        headerPopup.removeAll();\n\n        JCheckBoxMenuItem menuItem;\n\n        for (int i = 0; i < columnNames.length; i++) {\n            menuItem = new JCheckBoxMenuItem(columnNames[i]);\n            menuItem.setActionCommand(Integer.toString(i));\n            addMenuItemListener(menuItem);\n\n            if (resTable != null) {\n                menuItem.setState(resTableModel.isRealColumnVisible(i));\n\n                if (i == 0) {\n                    menuItem.setEnabled(false);\n                }\n            } else {\n                menuItem.setState(true);\n            }\n\n            headerPopup.add(menuItem);\n        }\n\n        headerPopup.addSeparator();\n\n        JCheckBoxMenuItem filterMenuItem = new JCheckBoxMenuItem(FILTER_MENU_ITEM_NAME);\n        filterMenuItem.setActionCommand(\"Filter\"); // NOI18N\n        addMenuItemListener(filterMenuItem);\n\n        if (filterComponent == null) {\n            filterMenuItem.setState(true);\n        } else {\n            filterMenuItem.setState(filterComponent.getComponent().isVisible());\n        }\n\n        headerPopup.add(filterMenuItem);\n        headerPopup.pack();\n    }\n\n    protected void initColumnsData() {\n        int maxWidth = getFontMetrics(getFont()).charWidth('W') * 13; // NOI18N // initial width of data columns\n        minNamesColumnWidth = getFontMetrics(getFont()).charWidth('W') * 30; // NOI18N\n\n        ClassNameTableCellRenderer classNameTableCellRenderer = new ClassNameTableCellRenderer();\n        LabelBracketTableCellRenderer labelBracketTableCellRenderer = new LabelBracketTableCellRenderer(JLabel.TRAILING);\n\n        columnNames = new String[] { CLASS_COLUMN_NAME, BYTES_REL_COLUMN_NAME, BYTES_COLUMN_NAME, OBJECTS_COLUMN_NAME };\n        columnToolTips = new String[] { CLASS_COLUMN_TOOLTIP, BYTES_REL_COLUMN_TOOLTIP, BYTES_COLUMN_TOOLTIP, OBJECTS_COLUMN_TOOLTIP };\n        columnTypes = new Class[] { String.class, Number.class, String.class, String.class };\n        columnRenderers = new TableCellRenderer[] {\n                              classNameTableCellRenderer, null, labelBracketTableCellRenderer, labelBracketTableCellRenderer\n                          };\n        columnWidths = new int[] { maxWidth + 15, maxWidth, maxWidth };\n    }\n\n    protected boolean passesValueFilter(int i) {\n        return ((((double) totalLiveObjectsSize[i] / (double) nTotalLiveBytes) * 100f) >= valueFilterValue);\n    }\n\n    protected void performDefaultAction(int classId) {\n        showSourceForClass(classId);\n    }\n\n    private void setColumnsData() {\n        barRenderer = getBarCellRenderer();\n\n        TableColumnModel colModel = resTable.getColumnModel();\n        colModel.getColumn(0).setPreferredWidth(minNamesColumnWidth);\n\n        int index;\n\n        for (int i = 0; i < colModel.getColumnCount(); i++) {\n            index = resTableModel.getRealColumn(i);\n\n            if (index == 0) {\n                colModel.getColumn(i).setPreferredWidth(minNamesColumnWidth);\n            } else {\n                colModel.getColumn(i).setPreferredWidth(columnWidths[index - 1]);\n            }\n\n            if (index == 1) {\n                colModel.getColumn(i).setCellRenderer(barRenderer);\n            } else {\n                colModel.getColumn(i).setCellRenderer(columnRenderers[index]);\n            }\n        }\n    }\n\n    private int getSortBy(int column) {\n        switch (column) {\n            case 0:\n                return PresoObjAllocCCTNode.SORT_BY_NAME;\n            case 1:\n                return PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_SIZE;\n            case 2:\n                return PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_SIZE;\n            case 3:\n                return PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_NUMBER;\n        }\n\n        return PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_SIZE;\n    }\n\n    private void addMenuItemListener(JCheckBoxMenuItem menuItem) {\n        menuItem.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    if (e.getActionCommand().equals(\"Filter\")) { // NOI18N\n                        filterComponent.getComponent().setVisible(!filterComponent.getComponent().isVisible());\n\n                        // TODO [ui-persistence]\n                        return;\n                    }\n\n                    saveColumnsData();\n\n                    boolean sortResults = false;\n                    int column = Integer.parseInt(e.getActionCommand());\n                    int sortingColumn = resTableModel.getSortingColumn();\n                    int realSortingColumn = resTableModel.getRealColumn(sortingColumn);\n                    boolean isColumnVisible = resTableModel.isRealColumnVisible(column);\n\n                    // Current sorting column is going to be hidden\n                    if ((isColumnVisible) && (column == realSortingColumn)) {\n                        // Try to set next column as a sortingColumn. If currentSortingColumn is the last column, set previous\n                        // column asa sorting Column (one column is always visible).\n                        sortingColumn = ((sortingColumn + 1) == resTableModel.getColumnCount()) ? (sortingColumn - 1)\n                                                                                                : (sortingColumn + 1);\n                        realSortingColumn = resTableModel.getRealColumn(sortingColumn);\n                        sortResults = true;\n                    }\n\n                    resTableModel.setRealColumnVisibility(column, !isColumnVisible);\n                    resTable.createDefaultColumnsFromModel();\n                    resTableModel.setTable(resTable);\n                    sortingColumn = resTableModel.getVirtualColumn(realSortingColumn);\n\n                    if (sortResults) {\n                        sortOrder = resTableModel.getInitialSorting(sortingColumn);\n                        sortBy = getSortBy(realSortingColumn);\n                        sortResults();\n                        resTable.repaint();\n                    }\n\n                    resTableModel.setInitialSorting(sortingColumn, sortOrder);\n                    resTable.getTableHeader().repaint();\n\n                    setColumnsData();\n\n                    // TODO [ui-persistence]\n                }\n            });\n    }\n\n    private void saveColumnsData() {\n        int index;\n        TableColumnModel colModel = resTable.getColumnModel();\n\n        for (int i = 0; i < resTableModel.getColumnCount(); i++) {\n            index = resTableModel.getRealColumn(i);\n\n            if (index != 0) {\n                columnWidths[index - 1] = colModel.getColumn(i).getPreferredWidth();\n            }\n        }\n    }\n\n    private void sortResults() {\n        // This will sort results and produce sortedClassNames and sortedClassIds\n        switch (sortBy) {\n            case PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_SIZE:\n                getResultsSortedByLiveObjSize();\n\n                break;\n            case PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_NUMBER:\n                getResultsSortedByLiveObjNumber();\n\n                break;\n            case PresoObjAllocCCTNode.SORT_BY_NAME:\n                getResultsSortedByClassName(false);\n\n                break;\n        }\n\n        createFilteredIndexes();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/SampledTableView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.BorderLayout;\nimport java.util.Set;\nimport javax.swing.JLabel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.CheckBoxRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class SampledTableView extends MemoryView {\n\n    private MemoryTableModel tableModel;\n    private ProfilerTable table;\n\n    private String[] names;\n    private int[] instances;\n    private long[] bytes;\n    private ClientUtils.SourceCodeSelection[] classNames;\n\n    private final Set<ClientUtils.SourceCodeSelection> selection;\n\n\n    SampledTableView(Set<ClientUtils.SourceCodeSelection> selection) {\n        this.selection = selection;\n\n        initUI();\n    }\n    \n    \n    protected ProfilerTable getResultsComponent() { return table; }\n    \n    \n    public void setData(MemoryResultsSnapshot snapshot, GenericFilter filter, final int aggregation) {\n        final SampledMemoryResultsSnapshot _snapshot = (SampledMemoryResultsSnapshot)snapshot;\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                boolean diff = _snapshot instanceof SampledMemoryResultsDiff;\n                \n                long totalSize = 0;\n                long _totalSize = 0;\n                long totalInstances = 0;\n                long _totalInstances = 0;\n                \n                names = _snapshot.getClassNames();\n                instances = _snapshot.getObjectsCounts();\n                bytes = _snapshot.getObjectsSizePerClass();\n\n                classNames = new ClientUtils.SourceCodeSelection[names.length];\n\n                for (int i = 0; i < names.length; i++) {\n                    if (diff) {\n                        totalInstances = Math.max(totalInstances, instances[i]);\n                        _totalInstances = Math.min(_totalInstances, instances[i]);\n                        totalSize = Math.max(totalSize, bytes[i]);\n                        _totalSize = Math.min(_totalSize, bytes[i]);\n                    } else {\n                        totalInstances += instances[i];\n                        totalSize += bytes[i];\n                    }\n                    classNames[i] = new ClientUtils.SourceCodeSelection(names[i], Wildcards.ALLWILDCARD, null);\n                }\n                \n                if (diff) {\n                    renderers[0].setMaxValue(Math.max(Math.abs(totalSize), Math.abs(_totalSize)));\n                    renderers[1].setMaxValue(Math.max(Math.abs(totalInstances), Math.abs(_totalInstances)));\n                } else {\n                    renderers[0].setMaxValue(totalSize);\n                    renderers[1].setMaxValue(totalInstances);\n                }\n                \n                renderers[0].setDiffMode(diff);\n                renderers[1].setDiffMode(diff);\n\n                tableModel.fireTableDataChanged();\n            }\n        });\n    }\n    \n    public void resetData() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                names = null;\n                instances = null;\n                bytes = null;\n                classNames = null;\n                \n                renderers[0].setMaxValue(0);\n                renderers[1].setMaxValue(0);\n                renderers[0].setDiffMode(false);\n                renderers[1].setDiffMode(false);\n\n                tableModel.fireTableDataChanged();\n            }\n        });\n    }\n    \n    \n    public void showSelectionColumn() {\n        table.setColumnVisibility(0, true);\n    }\n    \n    public void refreshSelection() {\n        tableModel.fireTableDataChanged();\n    }\n    \n    \n    public ExportUtils.ExportProvider[] getExportProviders() {\n        return table.getRowCount() == 0 ? null : new ExportUtils.ExportProvider[] {\n            new ExportUtils.CSVExportProvider(table),\n            new ExportUtils.HTMLExportProvider(table, EXPORT_LIVE),\n            new ExportUtils.XMLExportProvider(table, EXPORT_LIVE),\n            new ExportUtils.PNGExportProvider(table)\n        };\n    }\n    \n    \n    protected abstract void performDefaultAction(ClientUtils.SourceCodeSelection userValue);\n    \n    protected abstract void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue);\n    \n    protected void popupShowing() {}\n    \n    protected void popupHidden()  {}\n    \n    \n    private HideableBarRenderer[] renderers;\n    \n    private void initUI() {\n        int offset = selection == null ? -1 : 0;\n        \n        tableModel = new MemoryTableModel();\n        \n        table = new ProfilerTable(tableModel, true, true, null) {\n            public ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n                return SampledTableView.this.getUserValueForRow(row);\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                SampledTableView.this.populatePopup(popup, value, (ClientUtils.SourceCodeSelection)userValue);\n            }\n            protected void popupShowing() {\n                SampledTableView.this.popupShowing();\n            }\n            protected void popupHidden() {\n                SampledTableView.this.popupHidden();\n            }\n        };\n        \n        table.setColumnToolTips(selection == null ? new String[] {\n                                  NAME_COLUMN_TOOLTIP,\n                                  LIVE_SIZE_COLUMN_TOOLTIP,\n                                  LIVE_COUNT_COLUMN_TOOLTIP\n                                } : new String[] {\n                                  SELECTED_COLUMN_TOOLTIP,\n                                  NAME_COLUMN_TOOLTIP,\n                                  LIVE_SIZE_COLUMN_TOOLTIP,\n                                  LIVE_COUNT_COLUMN_TOOLTIP\n                                });\n        \n        table.providePopupMenu(true);\n        installDefaultAction();\n        \n        table.setMainColumn(1 + offset);\n        table.setFitWidthColumn(1 + offset);\n        \n        table.setSortColumn(2 + offset);\n        table.setDefaultSortOrder(1 + offset, SortOrder.ASCENDING);\n        \n        if (selection != null) table.setColumnVisibility(0, false);\n        \n        renderers = new HideableBarRenderer[2];\n        renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(Formatters.bytesFormat()));\n        renderers[1] = new HideableBarRenderer(new NumberPercentRenderer());\n        \n        renderers[0].setMaxValue(123456789);\n        renderers[1].setMaxValue(12345678);\n        \n        if (selection != null) table.setColumnRenderer(0, new CheckBoxRenderer());\n        table.setColumnRenderer(1 + offset, new JavaNameRenderer(Icons.getIcon(LanguageIcons.CLASS)));\n        table.setColumnRenderer(2 + offset, renderers[0]);\n        table.setColumnRenderer(3 + offset, renderers[1]);\n        \n        if (selection != null) {\n            int w = new JLabel(table.getColumnName(0)).getPreferredSize().width;\n            table.setDefaultColumnWidth(0, w + 15);\n        }\n        table.setDefaultColumnWidth(2 + offset, renderers[0].getOptimalWidth());\n        table.setDefaultColumnWidth(3 + offset, renderers[1].getMaxNoBarWidth());\n        \n        ProfilerTableContainer tableContainer = new ProfilerTableContainer(table, false, null);\n        \n        setLayout(new BorderLayout());\n        add(tableContainer, BorderLayout.CENTER);\n    }\n    \n    \n    protected ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n        if (names == null || row == -1) return null;\n        if (row >= tableModel.getRowCount()) return null; // #239936\n        return classNames[table.convertRowIndexToModel(row)];\n    }\n    \n    \n    private class MemoryTableModel extends AbstractTableModel {\n        \n        public String getColumnName(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return COLUMN_NAME;\n            } else if (columnIndex == 2) {\n                return COLUMN_LIVE_BYTES;\n            } else if (columnIndex == 3) {\n                return COLUMN_LIVE_OBJECTS;\n            } else if (columnIndex == 0) {\n                return COLUMN_SELECTED;\n            }\n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return String.class;\n            } else if (columnIndex == 0) {\n                return Boolean.class;\n            } else {\n                return Long.class;\n            }\n        }\n\n        public int getRowCount() {\n            return names == null ? 0 : names.length;\n        }\n\n        public int getColumnCount() {\n            return selection == null ? 3 : 4;\n        }\n\n        public Object getValueAt(int rowIndex, int columnIndex) {\n            if (names == null) return null;\n            \n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 1) {\n                return names[rowIndex];\n            } else if (columnIndex == 2) {\n                return bytes[rowIndex];\n            } else if (columnIndex == 3) {\n                return instances[rowIndex];\n            } else if (columnIndex == 0) {\n                if (selection.isEmpty()) return Boolean.FALSE;\n                return selection.contains(classNames[rowIndex]);\n            }\n\n            return null;\n        }\n\n        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            if (columnIndex == 0) {\n                if (Boolean.FALSE.equals(aValue)) selection.remove(classNames[rowIndex]);\n                else selection.add(classNames[rowIndex]);\n            }\n        }\n\n        public boolean isCellEditable(int rowIndex, int columnIndex) {\n            if (selection == null) columnIndex++;\n            \n            return columnIndex == 0;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/SnapshotAllocResultsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.jfluid.results.ResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.AllocMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * This class implements presentation frames for Object Allocation Profiling.\n *\n * @author Ian Formanek\n */\npublic class SnapshotAllocResultsPanel extends AllocResultsPanel implements ActionListener {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String GO_SOURCE_POPUP_ITEM_NAME = messages.getString(\"AllocResultsPanel_GoSourcePopupItemName\"); // NOI18N\n    private static final String SHOW_STACK_TRACES_POPUP_ITEM_NAME = messages.getString(\"AllocResultsPanel_ShowStackTracesPopupItemName\"); // NOI18N\n                                                                                                                                          // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private AllocMemoryResultsSnapshot snapshot;\n    private JMenuItem popupShowSource;\n    private JMenuItem popupShowStacks;\n    private JPopupMenu memoryResPopupMenu;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SnapshotAllocResultsPanel(AllocMemoryResultsSnapshot snapshot, MemoryResUserActionsHandler actionsHandler) {\n        super(actionsHandler);\n        this.snapshot = snapshot;\n\n        fetchResultsFromSnapshot();\n\n        //prepareResults();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public ResultsSnapshot getSnapshot() {\n        return snapshot;\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        if (e.getSource() == popupShowStacks) {\n            actionsHandler.showStacksForClass(selectedClassId, getSortingColumn(), getSortingOrder());\n        } else if (e.getSource() == popupShowSource && popupShowSource != null) {\n            showSourceForClass(selectedClassId);\n        }\n    }\n\n    protected String getClassName(int classId) {\n        return snapshot.getClassName(classId);\n    }\n\n    protected String[] getClassNames() {\n        return snapshot.getClassNames();\n    }\n\n    protected JPopupMenu getPopupMenu() {\n        if (memoryResPopupMenu == null) {\n            memoryResPopupMenu = new JPopupMenu();\n\n            if (GoToSource.isAvailable()) {\n                Font boldfont = memoryResPopupMenu.getFont().deriveFont(Font.BOLD);\n\n                popupShowSource = new JMenuItem();\n                popupShowSource.setFont(boldfont);\n                popupShowSource.setText(GO_SOURCE_POPUP_ITEM_NAME);\n                memoryResPopupMenu.add(popupShowSource);\n                popupShowSource.addActionListener(this);\n            }\n\n            if (snapshot.containsStacks()) {\n                if (GoToSource.isAvailable()) memoryResPopupMenu.addSeparator();\n                popupShowStacks = new JMenuItem();\n                popupShowStacks.setText(SHOW_STACK_TRACES_POPUP_ITEM_NAME);\n                memoryResPopupMenu.add(popupShowStacks);\n                popupShowStacks.addActionListener(this);\n            }\n        }\n\n        return memoryResPopupMenu;\n    }\n\n    private void fetchResultsFromSnapshot() {\n        totalAllocObjectsSize = UIUtils.copyArray(snapshot.getObjectsSizePerClass());\n        nTotalAllocObjects = UIUtils.copyArray(snapshot.getObjectsCounts());\n\n        // In some situations nInstrClasses can be already updated, but nTotalAllocObjects.length and/ort totalAllocObjectsSize - not yet.\n        // Take measures to avoid ArrayIndexOutOfBoundsException.\n        nTrackedItems = snapshot.getNProfiledClasses();\n\n        if (nTrackedItems > nTotalAllocObjects.length) {\n            nTrackedItems = nTotalAllocObjects.length;\n        }\n\n        if (nTrackedItems > totalAllocObjectsSize.length) {\n            nTrackedItems = totalAllocObjectsSize.length;\n        }\n\n        // Operations necessary for correct bar representation of results\n        maxValue = 0;\n        nTotalBytes = 0;\n        nTotalClasses = 0;\n\n        for (int i = 0; i < nTrackedItems; i++) {\n            if (maxValue < totalAllocObjectsSize[i]) {\n                maxValue = totalAllocObjectsSize[i];\n            }\n\n            nTotalBytes += totalAllocObjectsSize[i];\n            nTotalClasses += nTotalAllocObjects[i];\n        }\n\n        initDataUponResultsFetch();\n    }\n\n    public void exportData(int typeOfFile, ExportDataDumper eDD, String viewName) {\n        percentFormat.setMinimumFractionDigits(2);\n        percentFormat.setMaximumFractionDigits(2);\n        switch (typeOfFile) {\n            case 1: exportCSV(\",\", eDD); break; // normal CSV   // NOI18N\n            case 2: exportCSV(\";\", eDD); break; // Excel CSV  // NOI18N\n            case 3: exportXML(eDD, viewName); break;\n            case 4: exportHTML(eDD, viewName); break;\n        }\n        percentFormat.setMaximumFractionDigits(1);\n        percentFormat.setMinimumFractionDigits(0);\n    }\n\n    private void exportHTML(ExportDataDumper eDD, String viewName) {\n         // Header\n       StringBuffer result = new StringBuffer(\"<HTML><HEAD><meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" /><TITLE>\"+viewName+\"</TITLE></HEAD><BODY><TABLE border=\\\"1\\\"><tr>\"); // NOI18N\n        for (String columnName : columnNames) {\n            result.append(\"<th>\").append(columnName).append(\"</th>\");  // NOI18N\n        }\n        result.append(\"</tr>\");  // NOI18N\n        eDD.dumpData(result);\n\n        for (int i=0; i < nTrackedItems; i++) {\n\n            result = new StringBuffer(\"<tr><td>\"+replaceHTMLCharacters(sortedClassNames[i])+\"</td>\");  // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(percentFormat.format(((double) totalAllocObjectsSize[i])/nTotalBytes)).append(\"</td>\");  // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(totalAllocObjectsSize[i]).append(\"</td>\");  // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(nTotalAllocObjects[i]).append(\"</td></tr>\");  // NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TABLE></BODY></HTML>\"));  // NOI18N\n    }\n\n    private void exportXML(ExportDataDumper eDD, String viewName) {\n         // Header\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"+newline+\"<ExportedView Name=\\\"\"+viewName+\"\\\">\"+newline); // NOI18N\n        result.append(\" <TableData NumRows=\\\"\").append(nTrackedItems).append(\"\\\" NumColumns=\\\"4\\\">\").append(newline).append(\"<TableHeader>\");  // NOI18N\n        for (String columnName : columnNames) {\n            result.append(\"  <TableColumn><![CDATA[\").append(columnName).append(\"]]></TableColumn>\").append(newline);  // NOI18N\n        }\n        result.append(\"</TableHeader>\");  // NOI18N\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer(\"  <TableRow>\"+newline+\"   <TableColumn><![CDATA[\"+sortedClassNames[i]+\"]]></TableColumn>\"+newline);  // NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(percentFormat.format(((double) totalAllocObjectsSize[i])/nTotalBytes)).append(\"]]></TableColumn>\").append(newline);  // NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(totalAllocObjectsSize[i]).append(\"]]></TableColumn>\").append(newline);  // NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(nTotalAllocObjects[i]).append(\"]]></TableColumn>\").append(newline).append(\"  </TableRow>\").append(newline);  // NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TableData>\"+newline+\"</ExportedView>\"));  // NOI18N\n    }\n\n    private void exportCSV(String separator, ExportDataDumper eDD) {\n        // Header\n        StringBuffer result = new StringBuffer();\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n\n        for (String columnName : columnNames) {\n            result.append(quote).append(columnName).append(quote).append(separator);\n        }\n        result.deleteCharAt(result.length()-1);\n        result.append(newLine);\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer();\n            result.append(quote).append(sortedClassNames[i]).append(quote).append(separator);\n            result.append(quote).append(percentFormat.format(((double) totalAllocObjectsSize[i])/nTotalBytes)).append(quote).append(separator);\n            result.append(quote).append(totalAllocObjectsSize[i]).append(quote).append(separator);\n            result.append(quote).append(nTotalAllocObjects[i]).append(quote).append(newLine);\n            eDD.dumpData(result);\n        }\n        eDD.close();\n    }\n\n    private String replaceHTMLCharacters(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break;  // NOI18N\n              case '>': sb.append(\"&gt;\"); break;  // NOI18N\n              case '&': sb.append(\"&amp;\"); break;  // NOI18N\n              case '\"': sb.append(\"&quot;\"); break;  // NOI18N\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/SnapshotLivenessResultsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.LivenessMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * This class implements presentation frames for Object Liveness Profiling.\n *\n * @author Misha Dmitriev\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\npublic class SnapshotLivenessResultsPanel extends LivenessResultsPanel implements ActionListener {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String GO_SOURCE_POPUP_ITEM = messages.getString(\"SnapshotLivenessResultsPanel_GoSourcePopupItem\"); // NOI18N\n    private static final String STACK_TRACES_POPUP_ITEM = messages.getString(\"SnapshotLivenessResultsPanel_StackTracesPopupItem\"); // NOI18N\n                                                                                                                                   // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JMenuItem popupShowSource;\n    private JMenuItem popupShowStacks;\n    private JPopupMenu popup;\n    private LivenessMemoryResultsSnapshot snapshot;\n    private int allocTrackEvery;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SnapshotLivenessResultsPanel(LivenessMemoryResultsSnapshot snapshot, MemoryResUserActionsHandler actionsHandler,\n                                        int allocTrackEvery) {\n        super(actionsHandler);\n        this.snapshot = snapshot;\n        this.allocTrackEvery = allocTrackEvery;\n\n        fetchResultsFromSnapshot();\n        //prepareResults();\n        initColumnsData();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void actionPerformed(ActionEvent e) {\n        Object source = e.getSource();\n\n        if (source == popupShowStacks) {\n            actionsHandler.showStacksForClass(selectedClassId, getSortingColumn(), getSortingOrder());\n        } else if (source == popupShowSource && popupShowSource != null) {\n            showSourceForClass(selectedClassId);\n        }\n    }\n\n    protected String getClassName(int classId) {\n        return snapshot.getClassName(classId);\n    }\n\n    protected String[] getClassNames() {\n        return snapshot.getClassNames();\n    }\n\n    protected int getPercentsTracked() {\n        return 100 / allocTrackEvery;\n    }\n\n    protected JPopupMenu getPopupMenu() {\n        if (popup == null) {\n            popup = new JPopupMenu();\n\n            if (GoToSource.isAvailable()) {\n                Font boldfont = popup.getFont().deriveFont(Font.BOLD);\n\n                popupShowSource = new JMenuItem();\n                popupShowSource.setText(GO_SOURCE_POPUP_ITEM);\n                popupShowSource.setFont(boldfont);\n                popup.add(popupShowSource);\n                popupShowSource.addActionListener(this);\n            }\n\n            if (snapshot.containsStacks()) {\n                if (GoToSource.isAvailable()) popup.addSeparator();\n                popupShowStacks = new JMenuItem();\n                popupShowStacks.setText(STACK_TRACES_POPUP_ITEM);\n                popup.add(popupShowStacks);\n                popupShowStacks.addActionListener(this);\n            }\n        }\n\n        return popup;\n    }\n\n    protected void performDefaultAction(int classId) {\n        showSourceForClass(classId);\n    }\n\n    private void fetchResultsFromSnapshot() {\n        nTrackedAllocObjects = UIUtils.copyArray(snapshot.getNTrackedAllocObjects());\n        nTrackedLiveObjects = UIUtils.copyArray(snapshot.getNTrackedLiveObjects());\n        trackedLiveObjectsSize = UIUtils.copyArray(snapshot.getTrackedLiveObjectsSize());\n        nTotalAllocObjects = UIUtils.copyArray(snapshot.getnTotalAllocObjects());\n        avgObjectAge = UIUtils.copyArray(snapshot.getAvgObjectAge());\n        maxSurvGen = UIUtils.copyArray(snapshot.getMaxSurvGen());\n        nInstrClasses = snapshot.getNInstrClasses();\n\n        nTrackedItems = snapshot.getNTrackedItems();\n        // Operations necessary for correct bar representation of results\n        maxValue = snapshot.getMaxValue();\n        nTotalTrackedBytes = snapshot.getNTotalTrackedBytes();\n        nTotalTracked = snapshot.getNTotalTracked();\n\n        initDataUponResultsFetch();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/SnapshotMemoryView.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.BorderLayout;\nimport java.awt.Font;\nimport java.awt.event.ActionEvent;\nimport java.util.ResourceBundle;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.Icon;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.AllocMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.LivenessMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.PresoObjAllocCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.results.DataView;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class SnapshotMemoryView extends JPanel {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String COMPARE_SNAPSHOTS = messages.getString(\"SnapshotMemoryView_CompareSnapshots\"); // NOI18N\n    private static final String RESET_COMPARE_SNAPSHOTS = messages.getString(\"SnapshotMemoryView_ResetCompareSnapshots\"); // NOI18N\n//    private static final String TOOLBAR_AGGREGATION = messages.getString(\"SnapshotMemoryView_ToolbarAggregation\"); // NOI18N\n//    private static final String AGGREGATION_CLASSES = messages.getString(\"SnapshotMemoryView_AggregationClasses\"); // NOI18N\n//    private static final String AGGREGATION_PACKAGES = messages.getString(\"SnapshotMemoryView_AggregationPackages\"); // NOI18N\n    // -----\n    \n    private final MemoryView dataView;\n    \n    private int aggregation;\n    private final GenericFilter filter;\n    private final MemoryResultsSnapshot snapshot;\n    private MemoryResultsSnapshot refSnapshot;\n    \n    private JToggleButton compareButton;\n    \n    \n    public SnapshotMemoryView(MemoryResultsSnapshot snapshot, GenericFilter filter, Action saveAction, final Action compareAction, Action infoAction, ExportUtils.Exportable exportProvider) {\n        this.filter = filter;\n        this.snapshot = snapshot;\n        \n        // class names in VM format\n        MemoryView.userFormClassNames(snapshot);\n        \n        setOpaque(false);\n        setLayout(new BorderLayout());\n        \n//        boolean supportsPackageAggregation = true;\n        \n        if (snapshot instanceof SampledMemoryResultsSnapshot) {\n            dataView = new SampledTableView(null) {\n                protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                    if (showSourceSupported()) showSource(userValue);\n                }\n                protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                    SnapshotMemoryView.this.populatePopup(this, popup, value, userValue);\n                }\n            };\n        } else if (snapshot instanceof AllocMemoryResultsSnapshot) {\n            if (snapshot.containsStacks()) {\n                dataView = new AllocTreeTableView(null) {\n                    protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                        if (showSourceSupported()) showSource(userValue);\n                    }\n                    protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                        SnapshotMemoryView.this.populatePopup(this, popup, value, userValue);\n                    }\n                };\n//                supportsPackageAggregation = false;\n            } else {\n                dataView = new AllocTableView(null) {\n                    protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                        if (showSourceSupported()) showSource(userValue);\n                    }\n                    protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                        SnapshotMemoryView.this.populatePopup(this, popup, value, userValue);\n                    }\n                };\n            }\n        } else if (snapshot instanceof LivenessMemoryResultsSnapshot) {\n            if (snapshot.containsStacks()) {\n                dataView = new LivenessTreeTableView(null, filter == null) {\n                    protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                        if (showSourceSupported()) showSource(userValue);\n                    }\n                    protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                        SnapshotMemoryView.this.populatePopup(this, popup, value, userValue);\n                    }\n                };\n//                supportsPackageAggregation = false;\n            } else {\n                dataView = new LivenessTableView(null, filter == null) {\n                    protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {\n                        if (showSourceSupported()) showSource(userValue);\n                    }\n                    protected void populatePopup(JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n                        SnapshotMemoryView.this.populatePopup(this, popup, value, userValue);\n                    }\n                };\n            }\n        } else {\n            dataView = null;\n        }\n        \n        ProfilerToolbar toolbar = ProfilerToolbar.create(true);\n        \n        if (saveAction != null) toolbar.add(saveAction);\n        \n        toolbar.add(ExportUtils.exportButton(this, MemoryView.EXPORT_TOOLTIP, getExportables(exportProvider)));\n        \n        if (compareAction != null) {\n            toolbar.addSpace(2);\n            toolbar.addSeparator();\n            toolbar.addSpace(2);\n        \n            Icon icon = (Icon)compareAction.getValue(Action.SMALL_ICON);\n            compareButton = new JToggleButton(icon) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    boolean sel = isSelected();\n                    if (sel) {\n                        compareAction.actionPerformed(e);\n                        if (refSnapshot == null) setSelected(false);\n                    } else {\n                        setRefSnapshot(null);\n                    }\n                    setToolTipText(isSelected() ? RESET_COMPARE_SNAPSHOTS :\n                                                  COMPARE_SNAPSHOTS);\n                }\n            };\n            compareButton.setToolTipText(COMPARE_SNAPSHOTS);\n            toolbar.add(compareButton);\n        }\n        \n//        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n//        toolbar.addSpace(5);\n        \n//        GrayLabel aggregationL = new GrayLabel(TOOLBAR_AGGREGATION);\n//        toolbar.add(aggregationL);\n//        \n//        toolbar.addSpace(2);\n//        \n//        Action aClasses = new AbstractAction() {\n//            { putValue(NAME, AGGREGATION_CLASSES); }\n//            public void actionPerformed(ActionEvent e) { setAggregation(CPUResultsSnapshot.CLASS_LEVEL_VIEW); }\n//            \n//        };\n//        Action aPackages = new AbstractAction() {\n//            { putValue(NAME, AGGREGATION_PACKAGES); }\n//            public void actionPerformed(ActionEvent e) { setAggregation(CPUResultsSnapshot.PACKAGE_LEVEL_VIEW); }\n//            \n//        };\n//        \n//        ActionPopupButton aggregation = new ActionPopupButton(0, aClasses, aPackages);\n//        aggregation.setEnabled(supportsPackageAggregation);\n//        toolbar.add(aggregation);\n        \n        if (infoAction != null) {\n            toolbar.addFiller();\n            toolbar.add(infoAction);\n        }\n        \n        if (dataView != null) add(dataView, BorderLayout.CENTER);\n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        \n        setAggregation(CPUResultsSnapshot.CLASS_LEVEL_VIEW);\n        \n        registerActions();\n    }\n    \n    private void registerActions() {\n        ActionMap map = getActionMap();\n        \n        map.put(FilterUtils.FILTER_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { dataView.activateFilter(); }\n        });\n        \n        map.put(SearchUtils.FIND_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { dataView.activateSearch(); }\n        });\n    }\n    \n    \n    public void setRefSnapshot(MemoryResultsSnapshot snapshot) {\n        // class names in VM format\n        MemoryView.userFormClassNames(snapshot);\n        \n        refSnapshot = snapshot;\n        if (compareButton != null && snapshot != null) {\n            compareButton.setSelected(true);\n            compareButton.setToolTipText(RESET_COMPARE_SNAPSHOTS);\n        }\n        \n        setAggregation(aggregation);\n    }\n    \n    \n    protected boolean profileMethodSupported() { return true; }\n    \n    protected boolean profileClassSupported() { return true; }\n    \n    \n    protected abstract boolean showSourceSupported();\n    \n    protected abstract void showSource(ClientUtils.SourceCodeSelection value);\n    \n    protected abstract void selectForProfiling(ClientUtils.SourceCodeSelection value);\n    \n    \n    private void profileMethod(ClientUtils.SourceCodeSelection value) {\n        selectForProfiling(value);\n    }\n    \n    private void profileClass(ClientUtils.SourceCodeSelection value) {\n        selectForProfiling(new ClientUtils.SourceCodeSelection(\n                           value.getClassName(), Wildcards.ALLWILDCARD, null));\n    }\n    \n    \n    // TODO: implement isSelectable()\n//    // Check if primitive type/array\n//    if ((methodName == null && methodSig == null) && (VMUtils.isVMPrimitiveType(className) ||\n//         VMUtils.isPrimitiveType(className))) ProfilerDialogs.displayWarning(CANNOT_SHOW_PRIMITIVE_SRC_MSG);\n    static boolean isSelectable(ClientUtils.SourceCodeSelection value, boolean method) {\n        String className = value.getClassName();\n        String methodName = value.getMethodName();\n        \n        if (method && methodName.endsWith(\"[native]\")) return false; // NOI18N\n        \n        if (PresoObjAllocCCTNode.VM_ALLOC_CLASS.equals(className) && PresoObjAllocCCTNode.VM_ALLOC_METHOD.equals(methodName)) return false;\n        \n        return true;\n    }\n    \n    private void populatePopup(final DataView invoker, JPopupMenu popup, Object value, final ClientUtils.SourceCodeSelection userValue) {\n        if (showSourceSupported()) {\n            popup.add(new JMenuItem(MemoryView.ACTION_GOTOSOURCE) {\n                { setEnabled(userValue != null && aggregation != CPUResultsSnapshot.PACKAGE_LEVEL_VIEW); setFont(getFont().deriveFont(Font.BOLD)); }\n                protected void fireActionPerformed(ActionEvent e) { showSource(userValue); }\n            });\n            popup.addSeparator();\n        }\n        \n        if (profileMethodSupported()) {\n            if (userValue == null || !Wildcards.ALLWILDCARD.equals(userValue.getMethodName())) {\n                popup.add(new JMenuItem(MemoryView.ACTION_PROFILE_METHOD) {\n                    { setEnabled(userValue != null && isSelectable(userValue, true)); }\n                    protected void fireActionPerformed(ActionEvent e) { profileMethod(userValue); }\n                });\n            }\n        }\n        \n        if (profileClassSupported()) popup.add(new JMenuItem(MemoryView.ACTION_PROFILE_CLASS) {\n            { setEnabled(userValue != null && aggregation != CPUResultsSnapshot.PACKAGE_LEVEL_VIEW && isSelectable(userValue, false)); }\n            protected void fireActionPerformed(ActionEvent e) { profileClass(userValue); }\n        });\n        \n        if (profileMethodSupported() || profileClassSupported()) popup.addSeparator();\n        \n        JMenuItem[] customItems = invoker.createCustomMenuItems(this, value, userValue);\n        if (customItems != null) {\n            for (JMenuItem customItem : customItems) popup.add(customItem);\n            popup.addSeparator();\n        }\n        \n        customizeNodePopup(invoker, popup, value, userValue);\n        \n        if (snapshot.containsStacks()) {\n            final ProfilerTreeTable ttable = (ProfilerTreeTable)dataView.getResultsComponent();\n            JMenu expand = new JMenu(MemoryView.EXPAND_MENU);\n            popup.add(expand);\n\n            expand.add(new JMenuItem(MemoryView.EXPAND_PLAIN_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.expandPlainPath(ttable.getSelectedRow(), 1);\n                }\n            });\n\n            expand.add(new JMenuItem(MemoryView.EXPAND_TOPMOST_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.expandFirstPath(ttable.getSelectedRow());\n                }\n            });\n            \n            expand.addSeparator();\n            \n            expand.add(new JMenuItem(MemoryView.COLLAPSE_CHILDREN_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.collapseChildren(ttable.getSelectedRow());\n                }\n            });\n            \n            expand.add(new JMenuItem(MemoryView.COLLAPSE_ALL_ITEM) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    ttable.collapseAll();\n                }\n            });\n            \n            popup.addSeparator();\n        }\n        \n        popup.add(invoker.createCopyMenuItem());\n        popup.addSeparator();\n        \n        popup.add(new JMenuItem(FilterUtils.ACTION_FILTER) {\n            protected void fireActionPerformed(ActionEvent e) { invoker.activateFilter(); }\n        });\n        popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {\n            protected void fireActionPerformed(ActionEvent e) { invoker.activateSearch(); }\n        });\n    }\n    \n    protected void customizeNodePopup(DataView invoker, JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {}\n    \n    private void setAggregation(int aggregation) {\n        this.aggregation = aggregation;\n        if (dataView != null) {\n            if (refSnapshot == null) dataView.setData(snapshot, filter, aggregation);\n            else dataView.setData(snapshot.createDiff(refSnapshot), filter, aggregation);\n        }\n    }\n    \n    private ExportUtils.Exportable[] getExportables(final ExportUtils.Exportable snapshotExporter) {\n        return new ExportUtils.Exportable[] {\n            new ExportUtils.Exportable() {\n                public boolean isEnabled() {\n                    return refSnapshot == null && snapshotExporter.isEnabled();\n                }\n                public String getName() {\n                    return snapshotExporter.getName();\n                }\n                public ExportUtils.ExportProvider[] getProviders() {\n                    return snapshotExporter.getProviders();\n                }\n            },\n            new ExportUtils.Exportable() {\n                public boolean isEnabled() {\n                    return true;\n                }\n                public String getName() {\n                    return MemoryView.EXPORT_OBJECTS;\n                }\n                public ExportUtils.ExportProvider[] getProviders() {\n                    return dataView.getExportProviders();\n                }\n            }\n        };\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/SnapshotReverseMemCallGraphPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyAdapter;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.image.BufferedImage;\nimport java.util.HashSet;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport javax.swing.*;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.*;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.FilterComponent;\nimport org.graalvm.visualvm.lib.ui.components.JTreeTable;\nimport org.graalvm.visualvm.lib.ui.components.table.CustomBarCellRenderer;\nimport org.graalvm.visualvm.lib.ui.components.table.SortableTableModel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.AbstractTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.ExtendedTreeTableModel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.JTreeTablePanel;\nimport org.graalvm.visualvm.lib.ui.components.treetable.TreeTableModel;\n\n\n/**\n * A panel containing a reverse call graph for all allocations of instances of a given class\n *\n * @author Misha Dmitriev\n * @author Jiri Sedlacek\n */\npublic class SnapshotReverseMemCallGraphPanel extends ReverseMemCallGraphPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String NO_STACK_TRACES_MSG = messages.getString(\"SnapshotReverseMemCallGraphPanel_NoStackTracesMsg\"); // NOI18N\n    private static final String TREETABLE_ACCESS_NAME = messages.getString(\"SnapshotReverseMemCallGraphPanel_TreeTableAccessName\"); // NOI18N\n    private static final String METHOD_NAME_FILTER = messages.getString(\"MemoryResultsPanel_MethodNameFilterHint\"); // NOI18N\n                                                                                                                                    // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected int classId;\n    private AbstractTreeTableModel abstractTreeTableModel;\n    private JPanel noContentPanel;\n    private MemoryCCTManager callGraphManager;\n    private MemoryResultsSnapshot snapshot;\n    private boolean initialSortingOrder;\n    private int initialSortingColumn;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SnapshotReverseMemCallGraphPanel(MemoryResultsSnapshot snapshot, MemoryResUserActionsHandler actionsHandler) {\n        super(actionsHandler, snapshot instanceof LivenessMemoryResultsSnapshot);\n        this.snapshot = snapshot;\n\n        noContentPanel = new JPanel();\n        noContentPanel.setLayout(new BorderLayout());\n        noContentPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));\n\n        JLabel noContentIcon = new JLabel(Icons.getIcon(ProfilerIcons.SNAPSHOT_MEMORY_32));\n        noContentIcon.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 5));\n        noContentIcon.setVerticalAlignment(SwingConstants.TOP);\n        noContentIcon.setEnabled(false);\n\n        JTextArea noContentText = new JTextArea(NO_STACK_TRACES_MSG);\n        noContentText.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));\n        noContentText.setFont(noContentText.getFont().deriveFont(14));\n        noContentText.setEditable(false);\n        noContentText.setEnabled(false);\n        noContentText.setWrapStyleWord(true);\n        noContentText.setLineWrap(true);\n        noContentText.setBackground(noContentPanel.getBackground());\n\n        JPanel containerPanel = new JPanel(new BorderLayout());\n        containerPanel.add(noContentIcon, BorderLayout.WEST);\n        containerPanel.add(noContentText, BorderLayout.CENTER);\n        noContentPanel.add(containerPanel, BorderLayout.NORTH);\n\n        setDefaultSorting();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setClassId(int classId) {\n        this.classId = classId;\n        callGraphManager = new MemoryCCTManager(snapshot, classId, true);\n\n        if (!callGraphManager.isEmpty()) {\n            customBarCellRenderer = new CustomBarCellRenderer(0, callGraphManager.getRootNode().totalObjSize);\n            columnRenderers[1] = customBarCellRenderer;\n        }\n    }\n\n    public BufferedImage getCurrentViewScreenshot(boolean onlyVisibleArea) {\n        if ((treeTablePanel == null) || (treeTable == null)) {\n            return null;\n        }\n\n        if (onlyVisibleArea) {\n            return UIUtils.createScreenshot(treeTablePanel.getScrollPane());\n        } else {\n            return UIUtils.createScreenshot(treeTable);\n        }\n    }\n\n    private StringBuffer getCSVHeader(String separator) {\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n        StringBuffer result = new StringBuffer(quote+columnNames[0]+quote+separator);\n        for (int i = 2; i < (columnNames.length); i++) {\n            result.append(quote).append(columnNames[i]).append(quote).append(separator);\n        }        \n        result.append(messages.getString(\"SnapshotReverseMemCallGraphPanel_ExportAddedColumnName\")).append(newLine);// NOI18N\n        return result;\n    }\n\n    public void exportData(int exportedFileType, ExportDataDumper eDD, String viewName) {\n        if (callGraphManager.getRootNode() instanceof PresoObjLivenessCCTNode) {\n            ((PresoObjLivenessCCTNode) callGraphManager.getRootNode()).setDecimalFormat();\n            switch (exportedFileType) {\n                case 1: eDD.dumpData(getCSVHeader(\",\")); //NOI18N\n                        callGraphManager.getRootNode().exportCSVData(\",\", 0, eDD); //NOI18N\n                        eDD.close();\n                        break;\n                case 2: eDD.dumpData(getCSVHeader(\";\")); //NOI18N\n                        callGraphManager.getRootNode().exportCSVData(\";\", 0, eDD); //NOI18N\n                        eDD.close();\n                        break;\n                case 3: eDD.dumpData(getXMLHeader(viewName));\n                        callGraphManager.getRootNode().exportXMLData(eDD, \" \"); //NOI18N\n                        eDD.dumpDataAndClose(getXMLFooter());\n                        break;\n                case 4: eDD.dumpData(getHTMLHeader(viewName));\n                        callGraphManager.getRootNode().exportHTMLData(eDD,0);\n                        eDD.dumpDataAndClose(getHTMLFooter());\n                        break;\n            }\n\n        } else {\n            switch (exportedFileType) {\n                case 1: eDD.dumpData(getCSVHeader(\",\")); //NOI18N\n                        callGraphManager.getRootNode().exportCSVData(\",\", 0, eDD); //NOI18N\n                        eDD.close();\n                        break;\n                case 2: eDD.dumpData(getCSVHeader(\";\")); //NOI18N\n                        callGraphManager.getRootNode().exportCSVData(\";\", 0, eDD); //NOI18N\n                        eDD.close();\n                        break;\n                case 3: eDD.dumpData(getXMLHeader(viewName));\n                        callGraphManager.getRootNode().exportXMLData(eDD, \" \"); //NOI18N\n                        eDD.dumpDataAndClose(getXMLFooter());\n                        break;\n                case 4: eDD.dumpData(getHTMLHeader(viewName));\n                        callGraphManager.getRootNode().exportHTMLData(eDD,0);\n                        eDD.dumpDataAndClose(getHTMLFooter());\n                        break;\n            }\n        }\n    }\n\n    private StringBuffer getHTMLHeader(String viewName) {\n        StringBuffer result = new StringBuffer(\"<HTML><HEAD><meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" /><TITLE>\"+viewName+\"</TITLE><style type=\\\"text/css\\\">pre.method{overflow:auto;width:600;height:30;vertical-align:baseline}pre.parent{overflow:auto;width:400;height:30;vertical-align:baseline}td.method{text-align:left;width:600}td.parent{text-align:left;width:400}td.right{text-align:right;white-space:nowrap}</style></HEAD><BODY><table border=\\\"1\\\"><tr><th>\"+columnNames[0]+\"</th>\"); // NOI18N\n        for (int i = 2; i < (columnNames.length); i++) {\n            result.append(\"<th>\").append(columnNames[i]).append(\"</th>\");\n        }\n        result.append(\"<th>\").append(messages.getString(\"SnapshotReverseMemCallGraphPanel_ExportAddedColumnName\")).append(\"</th></tr>\"); //NOI18N\n        return result;\n    }\n\n    private StringBuffer getHTMLFooter() {        \n        return new StringBuffer(\"</TABLE></BODY></HTML>\"); //NOI18N\n    }\n\n    private StringBuffer getXMLHeader(String viewName) {\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"+newline+\"<ExportedView Name=\\\"\"+viewName+\"\\\" type=\\\"tree\\\">\"+newline+\"<tree>\"+newline); // NOI18N\n        return result;\n    }\n\n    private StringBuffer getXMLFooter() {\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"</tree>\"+newline+\"</ExportedView>\"); // NOI18N\n        return result;\n    }\n    \n    // NOTE: this method only sets initialSortingColumn and initialSortingOrder, it doesn't refresh UI!\n    public void setDefaultSorting() {\n        setSorting(1, SortableTableModel.SORT_ORDER_DESC);\n    }\n\n    public boolean isEmpty() {\n        return (callGraphManager == null) || callGraphManager.isEmpty();\n    }\n\n    // NOTE: this method only sets initialSortingColumn and initialSortingOrder, it doesn't refresh UI!\n    public void setSorting(int sColumn, boolean sOrder) {\n        if (sColumn == CommonConstants.SORTING_COLUMN_DEFAULT) {\n            setDefaultSorting();\n        } else {\n            initialSortingColumn = sColumn;\n            initialSortingOrder = sOrder;\n        }\n    }\n\n    public boolean fitsVisibleArea() {\n        return !treeTablePanel.getScrollPane().getVerticalScrollBar().isEnabled();\n    }\n\n    public boolean hasView() {\n        return treeTable != null;\n    }\n\n    public void prepareResults() {\n        if ((callGraphManager == null) || callGraphManager.isEmpty()) {\n            removeAll();\n            add(noContentPanel, BorderLayout.CENTER);\n        } else {\n            abstractTreeTableModel = new AbstractTreeTableModel(callGraphManager.getRootNode(), initialSortingColumn,\n                                                                initialSortingOrder) {\n                    public int getColumnCount() {\n                        return columnNames.length;\n                    }\n\n                    public String getColumnName(int column) {\n                        return columnNames[column];\n                    }\n\n                    public Class<?> getColumnClass(int column) {\n                        if (column == 0) {\n                            return TreeTableModel.class;\n                        } else {\n                            return Object.class;\n                        }\n                    }\n\n                    public Object getValueAt(Object node, int column) {\n                        long value;\n\n                        if (extendedResults) {\n                            PresoObjLivenessCCTNode pNode = (PresoObjLivenessCCTNode) node;\n\n                            switch (column) {\n                                case 0:\n                                    return pNode;\n                                case 1:\n                                    return new Long(pNode.totalObjSize);\n                                case 2:\n                                    value = ((PresoObjLivenessCCTNode) root).totalObjSize;\n\n                                    return intFormat.format(pNode.totalObjSize) + \" B (\"  //NOI18N\n                                           + ((value == 0) ? \"-%\" : percentFormat.format((float) pNode.totalObjSize / (float) value)) //NOI18N\n                                           + \")\"; // NOI18N\n                                case 3:\n                                    value = ((PresoObjLivenessCCTNode) root).nLiveObjects;\n\n                                    return intFormat.format(pNode.nLiveObjects) + \" (\" //NOI18N\n                                           + ((value == 0) ? \"-%\" : percentFormat.format((float) pNode.nLiveObjects / (float) value)) //NOI18N\n                                           + \")\"; // NOI18N\n                                case 4:\n                                    return intFormat.format(pNode.nCalls);\n                                case 5:\n                                    return StringUtils.floatPerCentToString(pNode.avgObjectAge);\n                                case 6:\n                                    return intFormat.format(pNode.survGen);\n                            }\n                        } else {\n                            PresoObjAllocCCTNode pNode = (PresoObjAllocCCTNode) node;\n\n                            switch (column) {\n                                case 0:\n                                    return pNode;\n                                case 1:\n                                    return new Long(pNode.totalObjSize);\n                                case 2:\n                                    value = ((PresoObjAllocCCTNode) root).totalObjSize;\n\n                                    return intFormat.format(pNode.totalObjSize) + \" B (\" //NOI18N\n                                           + ((value == 0) ? \"-%\" : percentFormat.format((float) pNode.totalObjSize / (float) value)) //NOI18N\n                                           + \")\"; // NOI18N\n                                case 3:\n                                    value = ((PresoObjAllocCCTNode) root).nCalls;\n\n                                    return intFormat.format(pNode.nCalls) + \" (\" //NOI18N\n                                           + ((value == 0) ? \"-%\" : percentFormat.format((float) pNode.nCalls / (float) value)) //NOI18N\n                                           + \")\"; // NOI18N\n                            }\n                        }\n\n                        return null;\n                    }\n\n                    public String getColumnToolTipText(int col) {\n                        return columnToolTips[col];\n                    }\n\n                    public void sortByColumn(int column, boolean order) {\n                        if (extendedResults) {\n                            PresoObjLivenessCCTNode pRoot = (PresoObjLivenessCCTNode) root;\n\n                            switch (column) {\n                                case 0:\n                                    pRoot.sortChildren(PresoObjLivenessCCTNode.SORT_BY_NAME, order);\n\n                                    break;\n                                case 1:\n                                case 2:\n                                    pRoot.sortChildren(PresoObjLivenessCCTNode.SORT_BY_LIVE_OBJ_SIZE, order);\n\n                                    break;\n                                case 3:\n                                    pRoot.sortChildren(PresoObjLivenessCCTNode.SORT_BY_LIVE_OBJ_NUMBER, order);\n\n                                    break;\n                                case 4:\n                                    pRoot.sortChildren(PresoObjLivenessCCTNode.SORT_BY_ALLOC_OBJ, order);\n\n                                    break;\n                                case 5:\n                                    pRoot.sortChildren(PresoObjLivenessCCTNode.SORT_BY_AVG_AGE, order);\n\n                                    break;\n                                case 6:\n                                    pRoot.sortChildren(PresoObjLivenessCCTNode.SORT_BY_SURV_GEN, order);\n\n                                    break;\n                            }\n                        } else {\n                            PresoObjAllocCCTNode pRoot = (PresoObjAllocCCTNode) root;\n\n                            switch (column) {\n                                case 0:\n                                    pRoot.sortChildren(PresoObjAllocCCTNode.SORT_BY_NAME, order);\n\n                                    break;\n                                case 1:\n                                case 2:\n                                    pRoot.sortChildren(PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_SIZE, order);\n\n                                    break;\n                                case 3:\n                                    pRoot.sortChildren(PresoObjAllocCCTNode.SORT_BY_ALLOC_OBJ_NUMBER, order);\n\n                                    break;\n                            }\n                        }\n                    }\n\n                    public boolean getInitialSorting(int column) {\n                        switch (column) {\n                            case 0:\n                                return true;\n                            default:\n                                return false;\n                        }\n                    }\n                };\n            treeTableModel = new ExtendedTreeTableModel(abstractTreeTableModel);\n\n            treeTable = new JTreeTable(treeTableModel) {\n                    public void doLayout() {\n                        int columnsWidthsSum = 0;\n                        int realFirstColumn = -1;\n\n                        int index;\n                        TableColumnModel colModel = getColumnModel();\n\n                        for (int i = 0; i < treeTableModel.getColumnCount(); i++) {\n                            index = treeTableModel.getRealColumn(i);\n\n                            if (index == 0) {\n                                realFirstColumn = i;\n                            } else {\n                                columnsWidthsSum += colModel.getColumn(i).getPreferredWidth();\n                            }\n                        }\n\n                        if (realFirstColumn != -1) {\n                            colModel.getColumn(realFirstColumn)\n                                    .setPreferredWidth(Math.max(getWidth() - columnsWidthsSum, minNamesColumnWidth));\n                        }\n\n                        super.doLayout();\n                    }\n\n                };\n            treeTable.getAccessibleContext().setAccessibleName(TREETABLE_ACCESS_NAME);\n\n            treeTable.setRowSelectionAllowed(true);\n            treeTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n            treeTable.setGridColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);\n            treeTable.setSelectionBackground(UIConstants.TABLE_SELECTION_BACKGROUND_COLOR);\n            treeTable.setSelectionForeground(UIConstants.TABLE_SELECTION_FOREGROUND_COLOR);\n            treeTable.setShowHorizontalLines(UIConstants.SHOW_TABLE_HORIZONTAL_GRID);\n            treeTable.setShowVerticalLines(UIConstants.SHOW_TABLE_VERTICAL_GRID);\n            treeTable.setRowMargin(UIConstants.TABLE_ROW_MARGIN);\n            treeTable.setRowHeight(UIUtils.getDefaultRowHeight() + 2);\n            treeTable.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)\n                     .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), \"DEFAULT_ACTION\"); // NOI18N\n            treeTable.getActionMap().put(\"DEFAULT_ACTION\", new AbstractAction() { //NOI18N\n                    public void actionPerformed(ActionEvent e) {\n                        performDefaultAction(treePath);\n                    }\n                }); // NOI18N\n\n            // Disable traversing table cells using TAB and Shift+TAB\n            Set<AWTKeyStroke> keys = new HashSet<>(treeTable.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));\n            keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));\n            treeTable.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys);\n\n            keys = new HashSet<>(treeTable.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));\n            keys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));\n            treeTable.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys);\n\n            setColumnsData();\n\n            UIUtils.autoExpandRoot(treeTable.getTree());\n            UIUtils.makeTreeAutoExpandable(treeTable.getTree());\n\n            treeTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n                    public void valueChanged(ListSelectionEvent e) {\n                        int selectedRow = treeTable.getSelectedRow();\n\n                        if (selectedRow == -1) {\n                            return;\n                        }\n\n                        treePath = treeTable.getTree().getPathForRow(selectedRow);\n                    }\n                });\n\n            treeTable.addKeyListener(new KeyAdapter() {\n                    public void keyPressed(KeyEvent e) {\n                        if ((e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU)\n                                || ((e.getKeyCode() == KeyEvent.VK_F10) && (e.getModifiers() == InputEvent.SHIFT_MASK))) {\n                            int selectedRow = treeTable.getSelectedRow();\n\n                            if (selectedRow != -1) {\n                                treePath = treeTable.getTree().getPathForRow(selectedRow);\n                                \n                                PresoObjAllocCCTNode node = (PresoObjAllocCCTNode)treePath.getLastPathComponent();\n                                enableDisablePopup(node);\n\n                                Rectangle cellRect = treeTable.getCellRect(selectedRow, 0, false);\n                                popupMenu.show(e.getComponent(), ((cellRect.x + treeTable.getSize().width) > 50) ? 50 : 5,\n                                               cellRect.y);\n                            }\n                        }\n                    }\n                });\n\n            treeTable.addMouseListener(new MouseAdapter() {\n                    private void showPopupMenu(MouseEvent e) {\n                        treePath = treeTable.getTree().getPathForRow(treeTable.rowAtPoint(e.getPoint()));\n\n                        if (treePath == null) {\n                            treeTable.getTree().clearSelection();\n                        } else {\n                            treeTable.getTree().setSelectionPath(treePath);\n                            PresoObjAllocCCTNode node = (PresoObjAllocCCTNode) treePath.getLastPathComponent();\n                            enableDisablePopup(node);\n                            popupMenu.show(e.getComponent(), e.getX(), e.getY());\n                        }\n                    }\n\n                    public void mousePressed(MouseEvent e) {\n                        if (e.isPopupTrigger()) showPopupMenu(e);\n                    }\n\n                    public void mouseReleased(MouseEvent e) {\n                        if (e.isPopupTrigger()) showPopupMenu(e);\n                    }\n\n                    public void mouseClicked(MouseEvent e) {\n                        treePath = treeTable.getTree().getPathForRow(treeTable.rowAtPoint(e.getPoint()));\n\n                        if (treePath != null) {\n                            treeTable.getTree().setSelectionPath(treePath);\n                            if (SwingUtilities.isLeftMouseButton(e) && (e.getClickCount() == 2)) {\n                                if (treeTableModel.isLeaf(treePath.getPath()[treePath.getPath().length - 1])) {\n                                    performDefaultAction(treePath);\n                                }\n                            }\n                        }\n                    }\n                });\n\n            removeAll();\n            treeTablePanel = new JTreeTablePanel(treeTable);\n            treeTablePanel.clearBorders();\n            treeTablePanel.setCorner(JScrollPane.UPPER_RIGHT_CORNER, cornerButton);\n            add(treeTablePanel, BorderLayout.CENTER);\n            initFilterPanel();\n        }\n    }\n    \n    private void initFilterPanel() {\n        filterComponent = FilterComponent.create(true, true);\n\n        filterComponent.addChangeListener(new ChangeListener() {\n                public void stateChanged(ChangeEvent e) {\n                    String filterString = filterComponent.getFilterValue();\n                    int filterType = filterComponent.getFilterType();\n                    snapshot.filterReverse(filterString, filterType, treeTable.getSortingColumn(), treeTable.getSortingOrder(),\n                            (PresoObjAllocCCTNode)abstractTreeTableModel.getRoot(), classId, true);\n                    \n                    treeTable.updateTreeTable();\n                }\n            });\n        filterComponent.setHint(METHOD_NAME_FILTER);\n        add(filterComponent.getComponent(), BorderLayout.SOUTH);\n    }\n    \n    private void enableDisablePopup(PresoObjAllocCCTNode node) {\n        if (popupShowSource != null) popupShowSource.setEnabled(!node.isFiltered());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/memory/SnapshotSampledResultsPanel.java",
    "content": "/*\n * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.memory;\n\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.jfluid.results.ResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * This class implements presentation frames for Object Allocation Profiling.\n *\n * @author Ian Formanek\n * @author Tomas Hurka\n */\npublic class SnapshotSampledResultsPanel extends SampledResultsPanel implements ActionListener {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.memory.Bundle\"); // NOI18N\n    private static final String GO_SOURCE_POPUP_ITEM_NAME = messages.getString(\"AllocResultsPanel_GoSourcePopupItemName\"); // NOI18N\n    private static final String SHOW_STACK_TRACES_POPUP_ITEM_NAME = messages.getString(\"AllocResultsPanel_ShowStackTracesPopupItemName\"); // NOI18N\n                                                                                                                                          // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private SampledMemoryResultsSnapshot snapshot;\n    private JMenuItem popupShowSource;\n    private JMenuItem popupShowStacks;\n    private JPopupMenu memoryResPopupMenu;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SnapshotSampledResultsPanel(SampledMemoryResultsSnapshot snapshot, MemoryResUserActionsHandler actionsHandler) {\n        super(actionsHandler);\n        this.snapshot = snapshot;\n\n        fetchResultsFromSnapshot();\n\n        //prepareResults();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public ResultsSnapshot getSnapshot() {\n        return snapshot;\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        if (e.getSource() == popupShowStacks) {\n            actionsHandler.showStacksForClass(selectedClassId, getSortingColumn(), getSortingOrder());\n        } else if (e.getSource() == popupShowSource && popupShowSource != null) {\n            showSourceForClass(selectedClassId);\n        }\n    }\n\n    protected String getClassName(int classId) {\n        return snapshot.getClassName(classId);\n    }\n\n    protected String[] getClassNames() {\n        return snapshot.getClassNames();\n    }\n\n    protected JPopupMenu getPopupMenu() {\n        if (memoryResPopupMenu == null) {\n            memoryResPopupMenu = new JPopupMenu();\n\n            if (GoToSource.isAvailable()) {\n                Font boldfont = memoryResPopupMenu.getFont().deriveFont(Font.BOLD);\n\n                popupShowSource = new JMenuItem();\n                popupShowSource.setFont(boldfont);\n                popupShowSource.setText(GO_SOURCE_POPUP_ITEM_NAME);\n                memoryResPopupMenu.add(popupShowSource);\n                popupShowSource.addActionListener(this);\n            }\n\n            if (snapshot.containsStacks()) {\n                if (GoToSource.isAvailable()) memoryResPopupMenu.addSeparator();\n                popupShowStacks = new JMenuItem();\n                popupShowStacks.setText(SHOW_STACK_TRACES_POPUP_ITEM_NAME);\n                memoryResPopupMenu.add(popupShowStacks);\n                popupShowStacks.addActionListener(this);\n            }\n        }\n\n        return memoryResPopupMenu;\n    }\n\n    private void fetchResultsFromSnapshot() {\n        totalLiveObjectsSize = UIUtils.copyArray(snapshot.getObjectsSizePerClass());\n        nTotalLiveObjects = UIUtils.copyArray(snapshot.getObjectsCounts());\n\n        // In some situations nInstrClasses can be already updated, but nTotalAllocObjects.length and/ort totalAllocObjectsSize - not yet.\n        // Take measures to avoid ArrayIndexOutOfBoundsException.\n        nTrackedItems = snapshot.getNProfiledClasses();\n\n        if (nTrackedItems > nTotalLiveObjects.length) {\n            nTrackedItems = nTotalLiveObjects.length;\n        }\n\n        if (nTrackedItems > totalLiveObjectsSize.length) {\n            nTrackedItems = totalLiveObjectsSize.length;\n        }\n\n        // Operations necessary for correct bar representation of results\n        maxValue = 0;\n        nTotalLiveBytes = 0;\n        nTotalClasses = 0;\n\n        for (int i = 0; i < nTrackedItems; i++) {\n            if (maxValue < totalLiveObjectsSize[i]) {\n                maxValue = totalLiveObjectsSize[i];\n            }\n\n            nTotalLiveBytes += totalLiveObjectsSize[i];\n            nTotalClasses += nTotalLiveObjects[i];\n        }\n\n        initDataUponResultsFetch();\n    }\n\n    public void exportData(int typeOfFile, ExportDataDumper eDD, String viewName) {\n        percentFormat.setMinimumFractionDigits(2);\n        percentFormat.setMaximumFractionDigits(2);\n        switch (typeOfFile) {\n            case 1: exportCSV(\",\", eDD); break; // normal CSV   // NOI18N\n            case 2: exportCSV(\";\", eDD); break; // Excel CSV  // NOI18N\n            case 3: exportXML(eDD, viewName); break;\n            case 4: exportHTML(eDD, viewName); break;\n        }\n        percentFormat.setMaximumFractionDigits(1);\n        percentFormat.setMinimumFractionDigits(0);\n    }\n\n    private void exportHTML(ExportDataDumper eDD, String viewName) {\n         // Header\n       StringBuffer result = new StringBuffer(\"<HTML><HEAD><meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" /><TITLE>\"+viewName+\"</TITLE></HEAD><BODY><TABLE border=\\\"1\\\"><tr>\"); // NOI18N\n        for (String columnName : columnNames) {\n            result.append(\"<th>\").append(columnName).append(\"</th>\");  // NOI18N\n        }\n        result.append(\"</tr>\");  // NOI18N\n        eDD.dumpData(result);\n\n        for (int i=0; i < nTrackedItems; i++) {\n\n            result = new StringBuffer(\"<tr><td>\"+replaceHTMLCharacters(sortedClassNames[i])+\"</td>\");  // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(percentFormat.format(((double) totalLiveObjectsSize[i])/nTotalLiveBytes)).append(\"</td>\");  // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(totalLiveObjectsSize[i]).append(\"</td>\");  // NOI18N\n            result.append(\"<td align=\\\"right\\\">\").append(nTotalLiveObjects[i]).append(\"</td></tr>\");  // NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TABLE></BODY></HTML>\"));  // NOI18N\n    }\n\n    private void exportXML(ExportDataDumper eDD, String viewName) {\n         // Header\n        String newline = System.lineSeparator();\n        StringBuffer result = new StringBuffer(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"+newline+\"<ExportedView Name=\\\"\"+viewName+\"\\\">\"+newline); // NOI18N\n        result.append(\" <TableData NumRows=\\\"\").append(nTrackedItems).append(\"\\\" NumColumns=\\\"4\\\">\").append(newline).append(\"<TableHeader>\");  // NOI18N\n        for (String columnName : columnNames) {\n            result.append(\"  <TableColumn><![CDATA[\").append(columnName).append(\"]]></TableColumn>\").append(newline);  // NOI18N\n        }\n        result.append(\"</TableHeader>\");  // NOI18N\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer(\"  <TableRow>\"+newline+\"   <TableColumn><![CDATA[\"+sortedClassNames[i]+\"]]></TableColumn>\"+newline);  // NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(percentFormat.format(((double) totalLiveObjectsSize[i])/nTotalLiveBytes)).append(\"]]></TableColumn>\").append(newline);  // NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(totalLiveObjectsSize[i]).append(\"]]></TableColumn>\").append(newline);  // NOI18N\n            result.append(\"   <TableColumn><![CDATA[\").append(nTotalLiveObjects[i]).append(\"]]></TableColumn>\").append(newline).append(\"  </TableRow>\").append(newline);  // NOI18N\n            eDD.dumpData(result);\n        }\n        eDD.dumpDataAndClose(new StringBuffer(\" </TableData>\"+newline+\"</ExportedView>\"));  // NOI18N\n    }\n\n    private void exportCSV(String separator, ExportDataDumper eDD) {\n        // Header\n        StringBuffer result = new StringBuffer();\n        String newLine = \"\\r\\n\"; // NOI18N\n        String quote = \"\\\"\"; // NOI18N\n\n        for (String columnName : columnNames) {\n            result.append(quote).append(columnName).append(quote).append(separator);\n        }\n        result.deleteCharAt(result.length()-1);\n        result.append(newLine);\n        eDD.dumpData(result);\n\n        // Data\n        for (int i=0; i < nTrackedItems; i++) {\n            result = new StringBuffer();\n            result.append(quote).append(sortedClassNames[i]).append(quote).append(separator);\n            result.append(quote).append(percentFormat.format(((double) totalLiveObjectsSize[i])/nTotalLiveBytes)).append(quote).append(separator);\n            result.append(quote).append(totalLiveObjectsSize[i]).append(quote).append(separator);\n            result.append(quote).append(nTotalLiveObjects[i]).append(quote).append(newLine);\n            eDD.dumpData(result);\n        }\n        eDD.close();\n    }\n\n    private String replaceHTMLCharacters(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break;  // NOI18N\n              case '>': sb.append(\"&gt;\"); break;  // NOI18N\n              case '&': sb.append(\"&amp;\"); break;  // NOI18N\n              case '\"': sb.append(\"&quot;\"); break;  // NOI18N\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n}\n\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/monitor/MonitorView.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.monitor;\n\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.LayoutManager;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.jfluid.results.monitor.VMTelemetryDataManager;\nimport org.graalvm.visualvm.lib.ui.graphs.CPUGraphPanel;\nimport org.graalvm.visualvm.lib.ui.graphs.GraphPanel;\nimport org.graalvm.visualvm.lib.ui.graphs.MemoryGraphPanel;\nimport org.graalvm.visualvm.lib.ui.graphs.SurvivingGenerationsGraphPanel;\nimport org.graalvm.visualvm.lib.ui.graphs.ThreadsGraphPanel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class MonitorView extends JPanel {\n\n    private VMTelemetryModels models;\n\n    private GraphPanel cpuPanel;\n    private GraphPanel memoryPanel;\n    private GraphPanel gcPanel;\n    private GraphPanel threadsPanel;\n\n\n    public MonitorView(VMTelemetryDataManager dataManager) {\n        initUI(dataManager);\n    }\n\n\n    public void setupCPUView(boolean visible) {\n        cpuPanel.setVisible(visible);\n    }\n\n    public void setupMemoryView(boolean visible) {\n        memoryPanel.setVisible(visible);\n    }\n\n    public void setupGCView(boolean visible) {\n        gcPanel.setVisible(visible);\n    }\n\n    public void setupThreadsView(boolean visible) {\n        threadsPanel.setVisible(visible);\n    }\n\n\n    public void cleanup() {\n        cpuPanel.cleanup();\n        memoryPanel.cleanup();\n        gcPanel.cleanup();\n        threadsPanel.cleanup();\n\n        models.cleanup();\n    }\n\n\n    private void initUI(VMTelemetryDataManager dataManager) {\n        setLayout(new GraphsLayout());\n\n        models = new VMTelemetryModels(dataManager);\n\n        cpuPanel = CPUGraphPanel.createBigPanel(models);\n        add(cpuPanel);\n\n        memoryPanel = MemoryGraphPanel.createBigPanel(models);\n        add(memoryPanel);\n        \n        gcPanel = SurvivingGenerationsGraphPanel.createBigPanel(models);\n        add(gcPanel);\n        \n        threadsPanel = ThreadsGraphPanel.createBigPanel(models);\n        add(threadsPanel);\n    }\n    \n    \n    private class GraphsLayout implements LayoutManager {\n\n        public void addLayoutComponent(String name, Component comp) {}\n\n        public void removeLayoutComponent(Component comp) {}\n\n        public Dimension preferredLayoutSize(Container parent) { return new Dimension(); }\n\n        public Dimension minimumLayoutSize(Container parent) { return new Dimension(); }\n\n        public void layoutContainer(Container parent) {\n            int w = getWidth();\n            int h = getHeight();\n            \n            boolean c = cpuPanel.isVisible();\n            boolean m = memoryPanel.isVisible();\n            boolean g = gcPanel.isVisible();\n            boolean t = threadsPanel.isVisible();\n            \n            int h1 = c || m ? (g || t ? h / 2 : h) : 0;\n            int h2 = h - h1;\n            \n            if (h1 > 0) {\n                if (c && m) {\n                    int w1 = w / 2;\n                    int w2 = w - w1;\n                    cpuPanel.setBounds(0, 0, w1, h1);\n                    memoryPanel.setBounds(w1, 0, w2, h1);\n                } else if (c) {\n                    cpuPanel.setBounds(0, 0, w, h1);\n                } else {\n                    memoryPanel.setBounds(0, 0, w, h1);\n                }\n            }\n            \n            if (h2 > 0) {\n                if (g && t) {\n                    int w1 = w / 2;\n                    int w2 = w - w1;\n                    gcPanel.setBounds(0, h1, w1, h2);\n                    threadsPanel.setBounds(w1, h1, w2, h2);\n                } else if (g) {\n                    gcPanel.setBounds(0, h1, w, h2);\n                } else {\n                    threadsPanel.setBounds(0, h1, w, h2);\n                }\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/monitor/VMTelemetryModels.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.monitor;\n\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\nimport org.graalvm.visualvm.lib.jfluid.results.DataManagerListener;\nimport org.graalvm.visualvm.lib.jfluid.results.monitor.VMTelemetryDataManager;\nimport org.graalvm.visualvm.lib.ui.charts.xy.ProfilerGCXYItem;\nimport org.graalvm.visualvm.lib.ui.graphs.GraphsUI;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class VMTelemetryModels {\n\n    // --- Instance variables --------------------------------------------------\n\n    private final VMTelemetryDataManager dataManager;\n    private final DataManagerListener listener;\n\n    private final Timeline timeline;\n    private final SynchronousXYItemsModel cpuItemsModel;\n    private final SynchronousXYItemsModel memoryItemsModel;\n    private final SynchronousXYItemsModel generationsItemsModel;\n    private final SynchronousXYItemsModel threadsItemsModel;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    public VMTelemetryModels(VMTelemetryDataManager dataManager) {\n        this.dataManager = dataManager;\n\n        timeline = createTimeline();\n        cpuItemsModel = createCPUItemsModel(timeline);\n        memoryItemsModel = createMemoryItemsModel(timeline);\n        generationsItemsModel = createGenerationsItemsModel(timeline);\n        threadsItemsModel = createThreadsItemsModel(timeline);\n\n        listener = new DataManagerListener() {\n            public void dataChanged() { dataChangedImpl(); }\n            public void dataReset() { dataResetImpl(); }\n        };\n        dataManager.addDataListener(listener);\n    }\n\n\n    // --- Public interface ----------------------------------------------------\n\n    public VMTelemetryDataManager getDataManager() {\n        return dataManager;\n    }\n    \n    public SynchronousXYItemsModel cpuItemsModel() {\n        return cpuItemsModel;\n    }\n\n    public SynchronousXYItemsModel memoryItemsModel() {\n        return memoryItemsModel;\n    }\n\n    public SynchronousXYItemsModel generationsItemsModel() {\n        return generationsItemsModel;\n    }\n\n    public SynchronousXYItemsModel threadsItemsModel() {\n        return threadsItemsModel;\n    }\n    \n    \n    public void cleanup() {\n        dataManager.removeDataListener(listener);\n    }\n\n\n    // --- DataManagerListener implementation ----------------------------------\n\n    private void dataChangedImpl() {\n        cpuItemsModel.valuesAdded();\n        memoryItemsModel.valuesAdded();\n        generationsItemsModel.valuesAdded();\n        threadsItemsModel.valuesAdded();\n    }\n\n    private void dataResetImpl() {\n        cpuItemsModel.valuesReset();\n        memoryItemsModel.valuesReset();\n        generationsItemsModel.valuesReset();\n        threadsItemsModel.valuesReset();\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private Timeline createTimeline() {\n        return new Timeline() {\n            public int getTimestampsCount() { return dataManager.getItemCount(); }\n            public long getTimestamp(int index) { return dataManager.timeStamps[index]; }\n        };\n    }\n    \n    private SynchronousXYItemsModel createCPUItemsModel(Timeline timeline) {\n        // CPU\n        SynchronousXYItem cpuTimeItem = new SynchronousXYItem(\"CPU Time\", 0, 1000) {\n            public long getYValue(int index) {\n                return dataManager.processCPUTimeInPromile[index];\n            }\n        };\n        cpuTimeItem.setInitialBounds(new LongRect(0, 0, 0, 1000));\n        \n        // Relative time spent in GC\n        SynchronousXYItem gcTimeItem = new SynchronousXYItem(GraphsUI.GC_TIME_NAME, 0, 1000) {\n            public long getYValue(int index) {\n                return dataManager.relativeGCTimeInPerMil[index];\n            }\n        };\n        gcTimeItem.setInitialBounds(new LongRect(0, 0, 0, 1000));\n\n        // Model\n        SynchronousXYItemsModel model = new SynchronousXYItemsModel(timeline,\n                           new SynchronousXYItem[] { cpuTimeItem, gcTimeItem });\n\n        return model;\n    }\n\n    private SynchronousXYItemsModel createMemoryItemsModel(Timeline timeline) {\n        // Heap size\n        SynchronousXYItem heapSizeItem = new SynchronousXYItem(GraphsUI.HEAP_SIZE_NAME, 0) {\n            public long getYValue(int index) {\n                return dataManager.totalMemory[index];\n            }\n        };\n        heapSizeItem.setInitialBounds(new LongRect(0, 0, 0, GraphsUI.HEAP_SIZE_INITIAL_VALUE));\n\n        // Used heap\n        SynchronousXYItem usedHeapItem = new SynchronousXYItem(GraphsUI.USED_HEAP_NAME, 0) {\n            public long getYValue(int index) {\n                return dataManager.usedMemory[index];\n            }\n        };\n        usedHeapItem.setInitialBounds(new LongRect(0, 0, 0, GraphsUI.USED_HEAP_INITIAL_VALUE));\n\n        // Model\n        SynchronousXYItemsModel model = new SynchronousXYItemsModel(timeline,\n                           new SynchronousXYItem[] { heapSizeItem, usedHeapItem });\n\n        return model;\n    }\n\n    private SynchronousXYItemsModel createGenerationsItemsModel(Timeline timeline) {\n        // Surviving generations\n        SynchronousXYItem survivingGenerationsItem = new SynchronousXYItem(GraphsUI.SURVGEN_NAME, 0) {\n            public long getYValue(int index) {\n                return dataManager.nSurvivingGenerations[index];\n            }\n        };\n        survivingGenerationsItem.setInitialBounds(new LongRect(0, 0, 0, GraphsUI.SURVGEN_INITIAL_VALUE));\n\n//        // Relative time spent in GC\n//        SynchronousXYItem gcTimeItem = new SynchronousXYItem(GraphsUI.GC_TIME_NAME, 0, 1000) {\n//            public long getYValue(int index) {\n//                return dataManager.relativeGCTimeInPerMil[index];\n//            }\n//        };\n//        gcTimeItem.setInitialBounds(new LongRect(0, 0, 0, 1000));\n\n        // GC intervals\n        ProfilerGCXYItem gcIntervalsItem = new ProfilerGCXYItem(\"\") { // NOI18N\n\n            public long[] getGCStarts(int index) {\n                return dataManager.gcStarts[index];\n            }\n\n            public long[] getGCEnds(int index) {\n                return dataManager.gcFinishs[index];\n            }\n\n        };\n\n        // Model\n        SynchronousXYItemsModel model = new SynchronousXYItemsModel(timeline,\n                 new SynchronousXYItem[] { gcIntervalsItem,\n                                        survivingGenerationsItem });\n\n        return model;\n    }\n\n    private SynchronousXYItemsModel createThreadsItemsModel(Timeline timeline) {\n        // Threads\n        SynchronousXYItem threadsItem = new SynchronousXYItem(GraphsUI.THREADS_NAME, 0) {\n            public long getYValue(int index) {\n                return dataManager.nTotalThreads[index];\n            }\n        };\n        threadsItem.setInitialBounds(new LongRect(0, 0, 0, GraphsUI.THREADS_INITIAL_VALUE));\n\n        // Loaded classes\n        SynchronousXYItem loadedClassesItem = new SynchronousXYItem(GraphsUI.LOADED_CLASSES_NAME, 0) {\n            public long getYValue(int index) {\n                return dataManager.loadedClassesCount[index];\n            }\n        };\n        loadedClassesItem.setInitialBounds(new LongRect(0, 0, 0, GraphsUI.LOADED_CLASSES_INITIAL_VALUE));\n\n        // Model\n        SynchronousXYItemsModel model = new SynchronousXYItemsModel(timeline,\n                       new SynchronousXYItem[] { threadsItem, loadedClassesItem });\n\n        return model;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/results/Bundle.properties",
    "content": "# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nPackageColorer_FiltersReflection=Java Reflection\nPackageColorer_FiltersJpa=JPA\nPackageColorer_FiltersServers=Java EE Servers\nPackageColorer_FiltersJavaSe=Java SE\nPackageColorer_FiltersJavaEe=Java EE\n#PackageColorer_FiltersLiquibase=Liquibase\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/results/ColoredFilter.java",
    "content": "/*\n * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.results;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Graphics;\nimport java.util.Objects;\nimport java.util.Properties;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ColoredFilter extends GenericFilter {\n\n    private static final String PROP_COLOR = \"COLOR\"; // NOI18N\n\n    private Color color;\n    private transient Icon icon;\n\n\n    public ColoredFilter(ColoredFilter other) {\n        super(other);\n\n        this.color = other.color;\n    }\n\n    public ColoredFilter(String name, String value, Color color) {\n        super(name, value, TYPE_INCLUSIVE);\n\n        this.color = color;\n    }\n\n    public ColoredFilter(Properties properties, String id) {\n        super(properties, id);\n\n        color = loadColor(properties, id);\n    }\n\n\n    public void copyFrom(ColoredFilter other) {\n        super.copyFrom(other);\n\n        color = other.color;\n    }\n\n\n    public final void setColor(Color color) {\n        this.color = color;\n    }\n\n    public final Color getColor() {\n        return color;\n    }\n\n\n    public final Icon getIcon(int width, int height) {\n        if (icon == null || icon.getIconWidth() != width || icon.getIconHeight() != height) {\n            final int w = Math.max(16, width);\n            final int h = Math.max(16, height);\n            final int ww = width;\n            final int hh = height;\n            final int wo = ww >= 16 ? 0 : (16 - ww) / 2;\n            final int ho = hh >= 16 ? 0 : (16 - hh) / 2;\n            icon = new Icon() {\n                public void paintIcon(Component c, Graphics g, int x, int y) {\n                    if (color == null) {\n                        g.setColor(Color.BLACK);\n                        g.drawLine(x + wo, y + ho, x + wo + ww, y + ho + hh);\n                        g.drawLine(x + wo + ww, y + ho, x + wo, y + ho + hh);\n                        g.drawRect(x + wo, y + ho, ww, hh);\n                    } else {\n                        g.setColor(color);\n                        g.fillRect(x + wo, y + ho, ww, hh);\n                        g.setColor(Color.BLACK);\n                        g.drawRect(x + wo, y + ho, ww, hh);\n                    }\n                }\n                public int getIconWidth() {\n                    return w;\n                }\n                public int getIconHeight() {\n                    return h;\n                }\n            };\n        }\n        return icon;\n    }\n    \n    \n    protected String[] computeValues(String value) {\n        return super.computeValues(value.replace('*', ' ')); // NOI18N\n    }\n    \n    \n    public boolean passes(String string) {\n        if (simplePasses(string)) return true;\n\n        String[] values = getValues();\n        for (String value : values) {\n            if (string.startsWith(value)) {\n                return true;\n            }\n        }\n        \n        return false;\n    }\n    \n    \n    protected boolean valuesEquals(Object obj) {\n        if (!super.valuesEquals(obj)) return false;\n        \n        ColoredFilter other = (ColoredFilter)obj;\n        if (!Objects.equals(color, other.color)) return false;\n        \n        return true;\n    }\n    \n    protected int valuesHashCode(int hashBase) {\n        hashBase = super.valuesHashCode(hashBase);\n        \n        if (color != null) hashBase = 67 * hashBase + color.hashCode();\n        \n        return hashBase;\n    }\n    \n    \n    public void store(Properties properties, String id) {\n        super.store(properties, id);\n        if (color != null) properties.put(id + PROP_COLOR, Integer.toString(color.getRGB()));\n    }\n    \n    \n    private static Color loadColor(Properties properties, String id) {\n        String _color = properties.getProperty(id + PROP_COLOR);\n        if (_color == null) return null;\n        \n        try {\n            int _colorI = Integer.parseInt(_color);\n            return new Color(_colorI);\n        } catch (NumberFormatException e) {\n            throw new InvalidFilterIdException(\"Bad color code specified\", id); // NOI18N\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/results/DataView.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.results;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.LayoutManager;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.FocusAdapter;\nimport java.awt.event.FocusEvent;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.JComponent;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.RowFilter;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTreeTable;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class DataView extends JPanel {\n\n    protected DataView() {\n        super(new BorderLayout());\n\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { SearchUtils.enableSearchActions(getResultsComponent()); }\n        });\n    }\n\n\n    // --- View UI -------------------------------------------------------------\n\n    protected abstract ProfilerTable getResultsComponent();\n\n    public final JMenuItem createCopyMenuItem() {\n        return getResultsComponent().createCopyMenuItem();\n    }\n\n    public final JMenuItem[] createCustomMenuItems(JComponent invoker, Object value, ClientUtils.SourceCodeSelection userValue) {\n        Collection<? extends PopupCustomizer> customizers = Lookup.getDefault().lookupAll(PopupCustomizer.class);\n        if (customizers.isEmpty()) return null;\n        \n        List<JMenuItem> menuItems = new ArrayList<>(customizers.size());\n        for (PopupCustomizer customizer : customizers) {\n            JMenuItem[] items = customizer.getMenuItems(invoker, this, value, userValue);\n            if (items != null) Collections.addAll(menuItems, items);\n        }\n        \n        return menuItems.isEmpty() ? null : menuItems.toArray(new JMenuItem[0]);\n    }\n    \n    public void notifyOnFocus(final Runnable handler) {\n        getResultsComponent().addFocusListener(new FocusAdapter() {\n            public void focusGained(FocusEvent e) { handler.run(); }\n        });\n    }\n    \n    \n    // --- Default action ------------------------------------------------------\n    \n    protected void installDefaultAction() {\n        getResultsComponent().setDefaultAction(new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                int row = getResultsComponent().getSelectedRow();\n                ClientUtils.SourceCodeSelection userValue = getUserValueForRow(row);\n                if (userValue != null) performDefaultAction(userValue);\n            }\n        });\n    }\n    \n    protected void performDefaultAction(ClientUtils.SourceCodeSelection userValue) {}\n    \n    protected ClientUtils.SourceCodeSelection getUserValueForRow(int row) { return null; }\n    \n    \n    // --- Filter & Find support -----------------------------------------------\n    \n    private JComponent bottomPanel;\n    private JComponent filterPanel;\n    private JComponent searchPanel;\n    \n//    public boolean filterActive() {\n//        return filterPanel == null ? false : filterPanel.isVisible();\n//    }\n    \n    protected RowFilter getExcludesFilter() {\n        return null;\n    }\n    \n    protected Component[] getFilterOptions() {\n        return null;\n    }\n    \n    protected void enableFilter() {\n        if (filterPanel != null) {\n            Object a = filterPanel.getClientProperty(\"SET_FILTER_CHANGED\"); // NOI18N\n            if (a instanceof Action) ((Action)a).actionPerformed(null);\n        }\n    }\n    \n    public void activateFilter() {\n        JComponent panel = getBottomPanel();\n        \n        if (filterPanel == null) {\n            filterPanel = FilterUtils.createFilterPanel(getResultsComponent(), getExcludesFilter(), getFilterOptions());\n            panel.add(filterPanel);\n            Container parent = panel.getParent();\n            parent.invalidate();\n            parent.revalidate();\n            parent.repaint();\n        }\n        \n        panel.setVisible(true);\n        \n        filterPanel.setVisible(true);\n        filterPanel.requestFocusInWindow();\n    }\n    \n    \n//    public boolean searchActive() {\n//        return searchPanel == null ? false : searchPanel.isVisible();\n//    }\n    \n    protected SearchUtils.TreeHelper getSearchHelper() {\n        return null;\n    }\n    \n    protected Component[] getSearchOptions() {\n        return null;\n    }\n    \n    public void activateSearch() {\n        JComponent panel = getBottomPanel();\n        \n        if (searchPanel == null) {\n            SearchUtils.TreeHelper searchHelper = getSearchHelper();\n            if (searchHelper == null) searchPanel = SearchUtils.createSearchPanel(getResultsComponent(), getSearchOptions());\n            else searchPanel = SearchUtils.createSearchPanel((ProfilerTreeTable)getResultsComponent(), searchHelper, getSearchOptions());\n            panel.add(searchPanel);\n            Container parent = panel.getParent();\n            parent.invalidate();\n            parent.revalidate();\n            parent.repaint();\n        }\n        \n        panel.setVisible(true);\n        \n        searchPanel.setVisible(true);\n        searchPanel.requestFocusInWindow();\n    }\n    \n    \n    protected boolean hasBottomFilterFindMargin() {\n        return false;\n    }\n    \n    protected void addFilterFindPanel(JComponent comp) {\n        add(comp, BorderLayout.SOUTH);\n    }\n    \n    \n    private JComponent getBottomPanel() {\n        if (bottomPanel == null) {\n            bottomPanel = new JPanel(new FilterFindLayout());\n            bottomPanel.setOpaque(true);\n            bottomPanel.setBackground(UIManager.getColor(\"controlShadow\")); // NOI18N\n            addFilterFindPanel(bottomPanel);\n        }\n        return bottomPanel;\n    }\n    \n    \n    private final class FilterFindLayout implements LayoutManager {\n\n        public void addLayoutComponent(String name, Component comp) {}\n        public void removeLayoutComponent(Component comp) {}\n\n        public Dimension preferredLayoutSize(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            Dimension dim = new Dimension();\n            \n            if (filter != null && search != null) {\n                Dimension dim1 = filter.getPreferredSize();\n                Dimension dim2 = search.getPreferredSize();\n                dim.width = dim1.width + dim2.width + 1;\n                dim.height = Math.max(dim1.height, dim2.height);\n            } else if (filter != null) {\n                dim = filter.getPreferredSize();\n            } else if (search != null) {\n                dim = search.getPreferredSize();\n            }\n            \n            if ((filter != null || search != null) && hasBottomFilterFindMargin())\n                dim.height += 1;\n            \n            return dim;\n        }\n\n        public Dimension minimumLayoutSize(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            Dimension dim = new Dimension();\n            \n            if (filter != null && search != null) {\n                Dimension dim1 = filter.getMinimumSize();\n                Dimension dim2 = search.getMinimumSize();\n                dim.width = dim1.width + dim2.width + 1;\n                dim.height = Math.max(dim1.height, dim2.height);\n            } else if (filter != null) {\n                dim = filter.getMinimumSize();\n            } else if (search != null) {\n                dim = search.getMinimumSize();\n            }\n            \n            if ((filter != null || search != null) && hasBottomFilterFindMargin())\n                dim.height += 1;\n            \n            return dim;\n        }\n\n        public void layoutContainer(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            int bottomOffset = hasBottomFilterFindMargin() ? 1 : 0;\n            \n            if (filter != null && search != null) {\n                Dimension size = parent.getSize();\n                int w = (size.width - 1) / 2;\n                filter.setBounds(0, 0, w, size.height - bottomOffset);\n                search.setBounds(w + 1, 0, size.width - w - 1, size.height - bottomOffset);\n            } else if (filter != null) {\n                Dimension size = parent.getSize();\n                filter.setBounds(0, 0, size.width, size.height - bottomOffset);\n            } else if (search != null) {\n                Dimension size = parent.getSize();\n                search.setBounds(0, 0, size.width, size.height - bottomOffset);\n            }\n        }\n        \n    }\n    \n    \n    public static abstract class PopupCustomizer {\n        \n        public abstract JMenuItem[] getMenuItems(JComponent invoker, DataView source, Object value, ClientUtils.SourceCodeSelection userValue);\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/results/PackageColorer.java",
    "content": "/*\n * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.results;\n\nimport java.awt.Color;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Properties;\nimport java.util.ResourceBundle;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.SwingWorker;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerStorage;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class PackageColorer {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.results.Bundle\"); // NOI18N\n    private static final String FILTERS_REFLECTION = messages.getString(\"PackageColorer_FiltersReflection\"); // NOI18N\n    private static final String FILTERS_JPA = messages.getString(\"PackageColorer_FiltersJpa\"); // NOI18N\n    private static final String FILTERS_SERVERS = messages.getString(\"PackageColorer_FiltersServers\"); // NOI18N\n    private static final String FILTERS_JAVASE = messages.getString(\"PackageColorer_FiltersJavaSe\"); // NOI18N\n    private static final String FILTERS_JAVAEE = messages.getString(\"PackageColorer_FiltersJavaEe\"); // NOI18N\n//    private static final String FILTERS_LIQUIBASE = messages.getString(\"PackageColorer_FiltersLiquibase\"); // NOI18N\n    // -----\n\n\n    private static final String FILTERS_FILE = \"filters\"; // NOI18N\n\n    private static final List<ColoredFilter> COLORS = loadColors();\n\n\n    public static boolean registerColor(ColoredFilter color) {\n        if (COLORS.contains(color)) return false;\n        else return COLORS.add(color);\n    }\n\n    public static boolean unregisterColor(ColoredFilter color) {\n        return COLORS.remove(color);\n    }\n\n    public static boolean hasRegisteredColors() {\n        return !COLORS.isEmpty();\n    }\n    \n    public static List<ColoredFilter> getRegisteredColors() {\n        List<ColoredFilter> colors = new ArrayList<>();\n        for (ColoredFilter color : COLORS) colors.add(new ColoredFilter(color));\n        return colors;\n    }\n    \n    public static void setRegisteredColors(List<ColoredFilter> colors) {\n        if (!COLORS.equals(colors)) {\n            COLORS.clear();\n            COLORS.addAll(colors);\n        }\n    }\n    \n    \n    public static Color getForeground(String pkg) {\n        if (!ProfilerIDESettings.getInstance().isSourcesColoringEnabled()) return null;\n        \n        for (ColoredFilter color : COLORS)\n            if (color.passes(pkg))\n                return color.getColor();\n        \n        return null;\n    }\n    \n    \n    private static List<ColoredFilter> loadColors() {\n        List<ColoredFilter> colors = new ArrayList<ColoredFilter>() {\n            public boolean add(ColoredFilter e) {\n                boolean ret = super.add(e);\n                if (ret && COLORS != null) storeColors();\n                return ret;\n            }\n            public boolean addAll(Collection<? extends ColoredFilter> c) {\n                boolean ret = super.addAll(c);\n                if (ret && COLORS != null) storeColors();\n                return ret;\n            }\n            public boolean remove(Object o) {\n                boolean ret = super.remove(o);\n                if (ret && COLORS != null) storeColors();\n                return ret;\n            }\n        };\n        \n        // Load persisted filters to Properties\n        Properties properties = new Properties();\n        try {\n            ProfilerStorage.loadGlobalProperties(properties, FILTERS_FILE);\n        } catch (IOException e) {\n            Logger.getLogger(PackageColorer.class.getName()).log(Level.INFO, null, e);\n        }\n        \n        // Create filter instances from Properties\n        if (!properties.isEmpty()) {\n            int i = 0;\n            while (true) {\n                try { colors.add(new ColoredFilter(properties, Integer.toString(i++) + \"_\")); } // NOI18N\n                catch (GenericFilter.InvalidFilterIdException e) { break; }\n            }\n        }\n        \n        // Fallback to default filters if no persisted filters\n        if (colors.isEmpty()) createDefaultFilters(colors);\n        \n        return colors;\n    }\n    \n    private static void storeColors() {\n        final Properties properties = new Properties();\n        final List<ColoredFilter> colors = getRegisteredColors();\n        \n        new SwingWorker() {\n            protected Object doInBackground() throws Exception {\n                for (int i = 0; i < colors.size(); i++) try {\n                    colors.get(i).store(properties, Integer.toString(i) + \"_\"); // NOI18N\n                } catch (Throwable t) {\n                    Logger.getLogger(PackageColorer.class.getName()).log(Level.INFO, null, t);\n                }\n                \n                try {\n                    ProfilerStorage.saveGlobalProperties(properties, FILTERS_FILE);\n                } catch (IOException e) {\n                    Logger.getLogger(PackageColorer.class.getName()).log(Level.INFO, null, e);\n                }\n                \n                return null;\n            }\n        }.execute();\n    }\n    \n    private static void createDefaultFilters(List<ColoredFilter> colors) {\n//        String liquibase = new String(\"liquibase.\"); // NOI18N\n//        colors.add(new ColoredFilter(FILTERS_LIQUIBASE, liquibase, new Color(135, 135, 135)));\n        \n        String jpa = new String(\"org.eclipse.persistence., org.hibernate., org.apache.openjpa.\"); // NOI18N\n        colors.add(new ColoredFilter(FILTERS_JPA, jpa, new Color(135, 135, 135)));\n        \n        String javaee = new String(\"javax.servlet., com.sun.enterprise., com.sun.ejb., org.jboss.weld., org.jboss.logging., org.springframework.\"); // NOI18N\n        colors.add(new ColoredFilter(FILTERS_JAVAEE, javaee, new Color(135, 135, 135)));\n        \n        String servers = new String(\"org.glassfish., com.sun.appserv., com.sun.gjc., weblogic., com.oracle.weblogic., com.bea., org.apache.tomcat., org.apache.catalina., org.jboss.as., org.eclipse.jetty.\"); // NOI18N\n        colors.add(new ColoredFilter(FILTERS_SERVERS, servers, new Color(135, 135, 135)));\n        \n        String reflection = new String(\"java.lang.reflect., sun.reflect., com.sun.proxy.\"); // NOI18N\n        colors.add(new ColoredFilter(FILTERS_REFLECTION, reflection, new Color(180, 180, 180)));\n        \n        String javase = new String(\"apple.laf., apple.awt., com.apple., com.sun., java., javax., jdk., sun., sunw., org.omg.CORBA., org.omg.CosNaming., COM.rsa.\"); // NOI18N\n        colors.add(new ColoredFilter(FILTERS_JAVASE, javase, new Color(135, 135, 135)));\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/ActionPopupButton.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.Action;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JRadioButtonMenuItem;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ActionPopupButton extends PopupButton {\n\n    private Action action;\n    private final Action[] actions;\n\n//    private Dimension minSize;\n//    private Dimension prefSize;\n\n    public ActionPopupButton(Action... _actions) {\n        this(0, _actions);\n    }\n\n    public ActionPopupButton(int initial, Action... _actions) {\n        actions = _actions;\n        selectAction(initial);\n    }\n\n    public final Action[] getActions() {\n        return actions;\n    }\n\n    public final void selectAction(Action _action) {\n        action = _action;\n        setText(action == null ? \"\" : action.getValue(Action.NAME).toString()); // NOI18N\n        putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n    }\n\n    public final void selectAction(int index) {\n        selectAction(actions[index]);\n    }\n\n    public final Action getSelectedAction() {\n        return action;\n    }\n\n    public final int getSelectedIndex() {\n        for (int i = 0; i < actions.length; i++)\n            if (actions[i] == action) return i;\n        return -1;\n    }\n\n    protected void populatePopup(JPopupMenu popup) {\n        for (final Action _action : actions) {\n            if (_action != null) {\n                popup.add(new JRadioButtonMenuItem(_action.getValue(Action.NAME).toString(), _action == action) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        selectAction(_action);\n                        _action.actionPerformed(e);\n                    }\n                });\n            } else {\n                popup.addSeparator();\n            }\n        }\n    }\n    \n//    public Dimension getMinimumSize() {\n//        if (minSize == null) {\n//            Action orig = action;\n//            for (Action _action : actions) if (_action != null) {\n//                selectAction(_action);\n//                Dimension min = super.getMinimumSize();\n//                if (minSize == null) minSize = min;\n//                minSize.width = Math.max(minSize.width, min.width);\n//                minSize.height = Math.max(minSize.height, min.height);\n//            }\n//            selectAction(orig);\n//        }\n//        return minSize;\n//    }\n//    \n//    public Dimension getPreferredSize() {\n//        if (prefSize == null) {\n//            Action orig = action;\n//            for (Action _action : actions) if (_action != null) {\n//                selectAction(_action);\n//                Dimension pref = super.getPreferredSize();\n//                if (prefSize == null) prefSize = pref;\n//                prefSize.width = Math.max(prefSize.width, pref.width);\n//                prefSize.height = Math.max(prefSize.height, pref.height);\n//            }\n//            selectAction(orig);\n//        }\n//        return prefSize;\n//    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nExportUtils_ButtonExport=Export\nExportUtils_NpsFile=Profiler Snapshot File\nExportUtils_CsvFile=CSV File\nExportUtils_HtmlFile=HTML File\nExportUtils_XmlFile=XML File\nExportUtils_PngFile=PNG Image\n# File filter description in File Type combo, like 'CSV File (*.csv)'\nExportUtils_FileFilterDescr={0} (*{1})\nExportUtils_MsgCannotOverwriteSource=Cannot overwrite source file.\nExportUtils_MsgExportSnapshotFailed=Failed to export snapshot:\nExportUtils_MsgExportImageFailed=Failed to export image:\nExportUtils_MsgNoData=No data to export.\nExportUtils_TitleOverwriteFile=Overwrite Existing File\nExportUtils_MsgOverwriteFile=Overwrite existing file?\n\nFilterUtils_ActionFilter=Filter\nFilterUtils_SidebarCaption=Filter\\:\n#Tooltip, {0} stands for action accelerator\nFilterUtils_BtnFilterTooltip=Filter results ({0})\nFilterUtils_BtnMatchCaseTooltip=Match case\n#Tooltip, {0} stands for action accelerator\nFilterUtils_BtnCloseTooltip=Close Filter sidebar ({0})\nFilterUtils_MsgInvalidRegexp=Entered regular expression is invalid:\\n{0}\nFilterUtils_FilterContains=Contains\nFilterUtils_FilterNotContains=Does Not Contain\nFilterUtils_FilterRegexp=Regular Expression\nFilterUtils_FilterType=Filter type: {0}\nFilterUtils_InsertFilter=Insert Defined Filter\n\nSearchUtils_ActionFind=Find\nSearchUtils_MsgNoData=No data to search.\nSearchUtils_MsgNotFound=Searched string not found.\nSearchUtils_SidebarCaption=Find\\:\nSearchUtils_BtnPrevious=Previous\n#Tooltip, {0} stands for action accelerator\nSearchUtils_BtnPreviousTooltip=Find previous occurence ({0})\nSearchUtils_BtnNext=Next\n#Tooltip, {0} stands for action accelerator\nSearchUtils_BtnNextTooltip=Find next occurence ({0})\nSearchUtils_BtnMatchCaseTooltip=Match case\n#Tooltip, {0} stands for action accelerator\nSearchUtils_BtnCloseTooltip=Close Find sidebar ({0})\n\nProfilerTable_ShowHideColumns=Show or hide columns\nProfilerTable_CopyMenu=Copy\nProfilerTable_CopyRowItem=Copy Row\nProfilerTable_CopyColumnItem=Copy {0}\n\nTextArea_Cut=Cut\nTextArea_Copy=Copy\nTextArea_Paste=Paste\nTextArea_Delete=Delete\nTextArea_SelectAll=Select All\nTextArea_Resize=Resize\nTextArea_HorizPlus=Extend Horizontally\nTextArea_HorizMinus=Shrink Horizontally\nTextArea_VertPlus=Extend Vertically\nTextArea_VertMinus=Shrink Vertically\nTextArea_DefaultSize=Default Size\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/EditableHistoryCombo.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.JComboBox;\nimport javax.swing.JTextField;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.JTextComponent;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class EditableHistoryCombo extends JComboBox {\n\n    private Runnable onTextChange;\n\n    public EditableHistoryCombo() {\n        super(new ComboHistoryModel(10));\n\n        setEditable(true);\n//        putClientProperty(\"JComboBox.isTableCellEditor\", Boolean.TRUE); // NOI18N\n\n        setPrototypeDisplayValue(\"org.graalvm.visualvm.lib.ui.swing.XXXXX\"); // NOI18N\n        Dimension dim = getPreferredSize();\n        dim.height = !UIUtils.isNimbusLookAndFeel() ? getMinimumSize().height :\n                     new JTextField(\"X\").getPreferredSize().height; // NOI18N\n\n        setMinimumSize(dim);\n        setPreferredSize(dim);\n        setMaximumSize(dim);\n\n        JTextComponent comp = getTextComponent();\n        if (comp != null) comp.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e)  { onChange(); }\n            public void removeUpdate(DocumentEvent e)  { onChange(); }\n            public void changedUpdate(DocumentEvent e) { onChange(); }\n            private void onChange() { if (onTextChange != null) onTextChange.run(); }\n        });\n    }\n\n\n    public JTextComponent getTextComponent() {\n        Component comp = getEditor().getEditorComponent();\n        return comp instanceof JTextComponent ? (JTextComponent)comp : null;\n    }\n\n    public String getText() {\n        JTextComponent textC = getTextComponent();\n        return textC != null ? textC.getText() : getSelectedItem().toString();\n    }\n    \n    public void setOnTextChangeHandler(Runnable handler) {\n        onTextChange = handler;\n    }\n    \n    \n    private static class ComboHistoryModel extends DefaultComboBoxModel {\n        \n        private final int historySize;\n        \n        \n        ComboHistoryModel(int historySize) {\n            this.historySize = historySize;\n        }\n        \n        \n        public void addElement(Object item) {\n            insertElementAt(item, 0);\n        }\n        \n        public void insertElementAt(Object item, int index) {\n            int current = getIndexOf(item);\n            if (current == index) return;\n            \n            if (current != -1) removeElementAt(current);\n            super.insertElementAt(item, index);\n            \n            if (getSize() > historySize) removeElementAt(historySize);\n            \n            setSelectedItem(item);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/ExportUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Component;\nimport java.awt.event.ActionEvent;\nimport java.awt.image.BufferedImage;\nimport java.io.BufferedWriter;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStreamWriter;\nimport java.io.Writer;\nimport java.nio.charset.Charset;\nimport java.nio.charset.CharsetEncoder;\nimport java.nio.charset.StandardCharsets;\nimport java.text.MessageFormat;\nimport java.util.Locale;\nimport java.util.ResourceBundle;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ThreadFactory;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.imageio.ImageIO;\nimport javax.swing.AbstractButton;\nimport javax.swing.JFileChooser;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JTree;\nimport javax.swing.SwingUtilities;\nimport javax.swing.filechooser.FileFilter;\nimport javax.swing.tree.TreeNode;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ExportUtils {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.swing.Bundle\"); // NOI18N\n    private static final String BUTTON_EXPORT = messages.getString(\"ExportUtils_ButtonExport\"); // NOI18N\n    private static final String NPS_FILE = messages.getString(\"ExportUtils_NpsFile\"); // NOI18N\n    private static final String CSV_FILE = messages.getString(\"ExportUtils_CsvFile\"); // NOI18N\n    private static final String HTML_FILE = messages.getString(\"ExportUtils_HtmlFile\"); // NOI18N\n    private static final String XML_FILE = messages.getString(\"ExportUtils_XmlFile\"); // NOI18N\n    private static final String PNG_FILE = messages.getString(\"ExportUtils_PngFile\"); // NOI18N\n    private static final String FILE_FILTER_DESCR = messages.getString(\"ExportUtils_FileFilterDescr\"); // NOI18N\n    private static final String MSG_CANNOT_OVERWRITE_SOURCE = messages.getString(\"ExportUtils_MsgCannotOverwriteSource\"); // NOI18N\n    private static final String MSG_EXPORT_SNAPSHOT_FAILED = messages.getString(\"ExportUtils_MsgExportSnapshotFailed\"); // NOI18N\n    private static final String MSG_EXPORT_IMAGE_FAILED = messages.getString(\"ExportUtils_MsgExportImageFailed\"); // NOI18N\n//    private static final String MSG_NODATA = messages.getString(\"ExportUtils_MsgNoData\"); // NOI18N\n    private static final String TITLE_OVERWRITE_FILE = messages.getString(\"ExportUtils_TitleOverwriteFile\"); // NOI18N\n    private static final String MSG_OVERWRITE_FILE = messages.getString(\"ExportUtils_MsgOverwriteFile\"); // NOI18N\n    // -----\n    \n    private static final Logger LOGGER = Logger.getLogger(ExportUtils.class.getName());\n    \n    \n    public static class FormatFilter extends FileFilter {\n        \n        private final String name;\n        private final String extension;\n        \n        public FormatFilter(String name, String extension) {\n            this.name = name;\n            this.extension = extension.startsWith(\".\") ? extension : \".\" + extension; // NOI18N\n        }\n        \n        public boolean accept(File f) {\n            return f.isDirectory() || f.getName().toLowerCase(Locale.ENGLISH).endsWith(extension);\n        }\n        \n        public String getDescription() {\n            return MessageFormat.format(FILE_FILTER_DESCR, name, extension);\n        }\n        \n        public String getExtension() {\n            return extension;\n        }\n        \n    }\n    \n    public static final FormatFilter NPS_FILTER = new FormatFilter(NPS_FILE, \"nps\"); // NOI18N\n    public static final FormatFilter CSV_FILTER = new FormatFilter(CSV_FILE, \"csv\"); // NOI18N\n    public static final FormatFilter HTML_FILTER = new FormatFilter(HTML_FILE, \"html\"); // NOI18N\n    public static final FormatFilter XML_FILTER = new FormatFilter(XML_FILE, \"xml\"); // NOI18N\n    public static final FormatFilter PNG_FILTER = new FormatFilter(PNG_FILE, \"png\"); // NOI18N\n    \n    \n    public static abstract class Exportable {\n        \n        public abstract String getName();\n        \n        public abstract boolean isEnabled();\n        \n        public abstract ExportProvider[] getProviders();\n        \n    }\n    \n    public static abstract class ExportProvider {\n        \n        public abstract FormatFilter getFormatFilter();\n        \n        public abstract void export(File targetFile);\n        \n    }\n    \n    public static abstract class BaseExportProvider extends ExportProvider {\n        \n        private final FormatFilter formatFilter;\n        \n        protected BaseExportProvider(FormatFilter formatFilter) { this.formatFilter = formatFilter; }\n        \n        public FormatFilter getFormatFilter() { return formatFilter; }\n        \n    }\n    \n    \n    public static abstract class ProfilerTableExportProvider extends BaseExportProvider {\n        \n        private final ProfilerTable table;\n        \n        public ProfilerTableExportProvider(ProfilerTable table, FormatFilter formatFilter) {\n            super(formatFilter);\n            this.table = table;\n        }\n        \n        public void export(File targetFile) { export(table, targetFile); }\n        \n        protected abstract void export(ProfilerTable table, File targetFile);\n        \n    }\n    \n    public static abstract class AbstractNPSExportProvider extends BaseExportProvider {\n        \n        private final File sourceFile;\n        \n        public AbstractNPSExportProvider(File sourceFile) {\n            super(NPS_FILTER);\n            this.sourceFile = sourceFile;\n        }\n        \n        public void export(File targetFile) {\n            if (targetFile.isFile() && targetFile.equals(sourceFile)) {\n                ProfilerDialogs.displayError(MSG_CANNOT_OVERWRITE_SOURCE);\n            } else {\n                doExport(targetFile);\n            }\n        }\n        \n        protected abstract void doExport(File targetFile);\n        \n    }\n    \n    public static class CSVExportProvider extends ProfilerTableExportProvider {\n        \n        public CSVExportProvider(ProfilerTable table) {\n            super(table, CSV_FILTER);\n        }\n        \n        protected void export(ProfilerTable table, File targetFile) {\n            exportCSV(table, ',', targetFile); // NOI18N\n        }\n        \n    }\n    \n    public static class HTMLExportProvider extends ProfilerTableExportProvider {\n        \n        private final String name;\n        \n        public HTMLExportProvider(ProfilerTable table, String name) {\n            super(table, HTML_FILTER);\n            this.name = name;\n        }\n        \n        protected void export(ProfilerTable table, File targetFile) {\n            exportHTML(table, name, targetFile);\n        }\n        \n    }\n    \n    public static class XMLExportProvider extends ProfilerTableExportProvider {\n        \n        private final String name;\n        \n        public XMLExportProvider(ProfilerTable table, String name) {\n            super(table, XML_FILTER);\n            this.name = name;\n        }\n        \n        protected void export(ProfilerTable table, File targetFile) {\n            exportXML(table, name, targetFile);\n        }\n        \n    }\n    \n    public static class PNGExportProvider extends BaseExportProvider {\n        \n        private final Component component;\n        \n        public PNGExportProvider(Component component) {\n            super(PNG_FILTER);\n            this.component = component;\n        }\n        \n        public void export(final File targetFile) {\n            final BufferedImage image = UIUtils.createScreenshot(component);\n            createExecutor(targetFile.getName()).submit(new Runnable() {\n                public void run() {\n                    try {\n                        targetFile.toPath();\n                        ImageIO.write(image, \"PNG\", targetFile); // NOI18N\n                    } catch (Throwable t) {\n                        LOGGER.log(Level.INFO, t.getMessage(), t);\n                        String msg = t.getLocalizedMessage().replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\"); // NOI18N\n                        ProfilerDialogs.displayError(\"<html><b>\" + MSG_EXPORT_IMAGE_FAILED + \"</b><br><br>\" + msg + \"</html>\"); // NOI18N\n                    }\n                }\n            });\n        }\n        \n    }\n    \n    \n    public static AbstractButton exportButton(final Component parent, String tooltip, final Exportable... exportables) {\n        PopupButton exportPopup = new PopupButton(Icons.getIcon(GeneralIcons.SAVE_AS)) {\n            protected void populatePopup(JPopupMenu popup) {\n                for (final Exportable exportable : exportables) {\n                    if (exportable != null && exportable.isEnabled()) {\n                        popup.add(new JMenuItem(exportable.getName()) {\n                            protected void fireActionPerformed(ActionEvent e) {\n                                JFileChooser fileChooser = new JFileChooser();\n                                fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);\n                                fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);\n                                fileChooser.setMultiSelectionEnabled(false);\n                                fileChooser.setDialogTitle(exportable.getName());\n\n                                fileChooser.removeChoosableFileFilter(fileChooser.getAcceptAllFileFilter());\n\n                                ExportProvider[] providers = exportable.getProviders();\n                                for (ExportProvider provider : providers)\n                                    fileChooser.addChoosableFileFilter(provider.getFormatFilter());\n\n                                // returning true means exporting to .nps, don't export other views\n                                showExportDialog(fileChooser, parent, providers);\n                            }\n                        });\n                    }\n                }\n            }\n        };\n        exportPopup.setToolTipText(tooltip);\n        return exportPopup;\n    }\n    \n    private static void showExportDialog(final JFileChooser fileChooser, final Component parent, final ExportProvider[] providers) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (fileChooser.showDialog(parent, BUTTON_EXPORT) != JFileChooser.APPROVE_OPTION) return;\n\n                File targetFile = fileChooser.getSelectedFile();\n                FileFilter filter = fileChooser.getFileFilter();\n\n                for (ExportProvider provider : providers) {\n                    FormatFilter format = provider.getFormatFilter();\n                    if (filter.equals(format)) {\n                        targetFile = checkFileExtension(targetFile, format.getExtension());\n                        if (checkFileExists(targetFile)) provider.export(targetFile);\n                        else showExportDialog(fileChooser, parent, providers);\n                        break;\n                    }\n                }\n            }\n        });\n    }\n    \n    private static boolean checkFileExists(File file) {\n        return !file.isFile() || ProfilerDialogs.displayConfirmation(\n                MSG_OVERWRITE_FILE, TITLE_OVERWRITE_FILE);\n    }\n    \n    public static File checkFileExtension(File file, String extension) {\n        if (file.getName().endsWith(extension)) return file;\n        return new File(file.getPath() + extension);\n    }\n    \n    \n    public static boolean exportCSV(ProfilerTable table, char separator, File file) {\n        Exporter ex = new Exporter(file);\n        \n        char doubleQuote = '\"'; // NOI18N\n        int rowCount = table.getRowCount();\n        int columnCount = table.getColumnCount();\n        \n        try {            \n            for (int col = 0; col < columnCount; col++) {\n                ex.write(doubleQuote);\n                ex.write(table.getColumnName(col));\n                ex.write(doubleQuote);\n                if (col < columnCount - 1) ex.write(separator);\n                else ex.writeln();\n            }\n            \n            if (ex.failed()) return false;\n            \n            if (table instanceof ProfilerTreeTable) {\n                ProfilerTreeTable treeTable = (ProfilerTreeTable)table;\n                TreePath path = treeTable.getNextPath(treeTable.getRootPath());\n                TreeNode node = (TreeNode)path.getLastPathComponent();\n                int indent = path.getPathCount() - 2;\n                TreePath firstPath = path;\n                do {\n                    if (ex.failed()) return false;\n                    for (int col = 0; col < columnCount; col++) {\n                        ex.write(doubleQuote);\n                        if (table.getColumnClass(col) == JTree.class)\n                            for (int i = 0; i < indent; i++) ex.write(' '); // NOI18N\n                        ex.write  (treeTable.getStringValue(node, col));\n                        ex.write(doubleQuote);\n                        if (col < columnCount - 1) ex.write(separator);\n                        else ex.writeln();\n                    }\n                    path = treeTable.getNextPath(path);\n                    node = (TreeNode)path.getLastPathComponent();\n                    indent = path.getPathCount() - 2;\n                } while (!firstPath.equals(path));\n            } else {\n                for (int row = 0; row < rowCount; row++) {\n                    if (ex.failed()) return false;\n                    for (int col = 0; col < columnCount; col++) {\n                        ex.write(doubleQuote);\n                        ex.write(table.getStringValue(row, col));\n                        ex.write(doubleQuote);\n                        if (col < columnCount - 1) ex.write(separator);\n                        else ex.writeln();\n                    }\n                }\n            }\n        } finally {\n            ex.close();\n        }\n        \n        return true;\n    }\n    \n    public static boolean exportHTML(ProfilerTable table, String name, File file) {\n        Exporter ex = new Exporter(file);\n        \n        int columnCount = table.getColumnCount();\n        \n        try {\n            ex.writeln(\"<html>\"); // NOI18N\n            \n            if (ex.failed()) return false;\n            \n            ex.writeln(\" <head>\"); // NOI18N\n            ex.writeln(\"  <meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" />\"); // NOI18N\n            ex.write  (\"  <title>\"); // NOI18N\n            ex.write  (name);\n            ex.writeln(\"</title>\"); // NOI18N\n            ex.writeln(\" </head>\"); // NOI18N\n            \n            ex.writeln(\" <body>\"); // NOI18N\n            ex.writeln(\"  <table>\"); // NOI18N\n            \n            ex.writeln(\"   <tr>\"); // NOI18N\n            for (int col = 0; col < columnCount; col++) {\n                ex.write  (\"    <th>\"); // NOI18N\n                ex.write  (escapeHTML(table.getColumnName(col)));\n                ex.writeln(\"</th>\"); // NOI18N\n            }\n            ex.writeln(\"   </tr>\"); // NOI18N\n            \n            if (ex.failed()) return false;\n\n            if (table instanceof ProfilerTreeTable) {\n                ProfilerTreeTable treeTable = (ProfilerTreeTable)table;\n                TreePath path = treeTable.getNextPath(treeTable.getRootPath());\n                TreeNode node = (TreeNode)path.getLastPathComponent();\n                int indent = path.getPathCount() - 2;\n                TreePath firstPath = path;\n                do {\n                    if (ex.failed()) return false;\n                    ex.writeln(\"   <tr>\"); // NOI18N\n                    for (int col = 0; col < columnCount; col++) {\n                        ex.write  (\"    <td><pre>\"); // NOI18N\n                        if (table.getColumnClass(col) == JTree.class)\n                            for (int i = 0; i < indent; i++) ex.write('.'); // NOI18N\n                        ex.write  (escapeHTML(treeTable.getStringValue(node, col)));\n                        ex.writeln(\"</pre></td>\"); // NOI18N\n                    }\n                    ex.writeln(\"   </tr>\"); // NOI18N\n                    path = treeTable.getNextPath(path);\n                    node = (TreeNode)path.getLastPathComponent();\n                    indent = path.getPathCount() - 2;\n                } while (!firstPath.equals(path));\n            } else {\n                int rowCount = table.getRowCount();\n                for (int row = 0; row < rowCount; row++) {\n                    if (ex.failed()) return false;\n                    ex.writeln(\"   <tr>\"); // NOI18N\n                    for (int col = 0; col < columnCount; col++) {\n                        ex.write  (\"    <td><pre>\"); // NOI18N\n                        ex.write  (escapeHTML(table.getStringValue(row, col)));\n                        ex.writeln(\"</pre></td>\"); // NOI18N\n                    }\n                    ex.writeln(\"   </tr>\"); // NOI18N\n                }\n            }\n            \n            ex.writeln(\"  </table>\"); // NOI18N\n            ex.writeln(\" </body>\"); // NOI18N\n            ex.writeln(\"</html>\"); // NOI18N\n        } finally {\n            ex.close();\n        }\n        \n        return true;\n    }\n    \n    public static boolean exportXML(ProfilerTable table, String name, File file) {\n        Exporter ex = new Exporter(file);\n        \n        int columnCount = table.getColumnCount();\n        \n        try {\n            ex.writeln(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"); // NOI18N\n            \n            if (ex.failed()) return false;\n            \n            if (table instanceof ProfilerTreeTable) {\n                ProfilerTreeTable treeTable = (ProfilerTreeTable)table;\n                TreePath path = treeTable.getNextPath(treeTable.getRootPath());\n                TreeNode node = (TreeNode)path.getLastPathComponent();\n                int indent = path.getPathCount();\n                TreePath firstPath = path;\n                \n                ex.write  (\"<dataview name=\\\"\"); // NOI18N\n                ex.write  (name);\n                ex.writeln(\"\\\" type=\\\"tree\\\">\"); // NOI18N\n                ex.writeln(\" <tree>\"); // NOI18N\n                \n                do {\n                    if (ex.failed()) return false;\n                    ex.write  (indent(indent));\n                    ex.writeln(\"<node>\"); // NOI18N\n                    for (int col = 0; col < columnCount; col++) {\n                        ex.write  (indent(indent));\n                        ex.write  (\" <property name=\\\"\"); // NOI18N\n                        ex.write  (escapeXML(treeTable.getColumnName(col)));\n                        ex.write  (\"\\\" value=\\\"\"); // NOI18N\n                        ex.write  (escapeXML(treeTable.getStringValue(node, col)));\n                        ex.writeln(\"\\\" />\"); // NOI18N\n                    }\n                    \n                    path = treeTable.getNextPath(path);\n                    node = (TreeNode)path.getLastPathComponent();\n                    int oldIndent = indent;\n                    indent = path.getPathCount();\n                    for (int i = 0; i <= oldIndent - indent; i++) {\n                        ex.write  (indent(oldIndent - i));\n                        ex.writeln(\"</node>\"); // NOI18N\n                    }\n                } while (!firstPath.equals(path));\n                \n                ex.writeln(\" </tree>\"); // NOI18N\n                ex.writeln(\"</dataview>\"); // NOI18N\n            } else {\n                int rowCount = table.getRowCount();\n                \n                ex.write  (\"<dataview name=\\\"\"); // NOI18N\n                ex.write  (name);\n                ex.writeln(\"\\\" type=\\\"table\\\">\"); // NOI18N\n\n                ex.write  (\" <table rows=\\\"\"); // NOI18N\n                ex.write  (Integer.toString(rowCount));\n                ex.write  (\"\\\" columns=\\\"\"); // NOI18N\n                ex.write  (Integer.toString(columnCount));\n                ex.writeln(\"\\\">\"); // NOI18N\n\n                ex.writeln(\"  <thead>\"); // NOI18N\n                for (int col = 0; col < columnCount; col++) {\n                    ex.write  (\"   <th><![CDATA[\"); // NOI18N\n                    ex.write  (escapeXML(table.getColumnName(col)));\n                    ex.writeln(\"]]></th>\"); // NOI18N\n                }\n                ex.writeln(\"  </thead>\"); // NOI18N\n                \n                if (ex.failed()) return false;\n\n                ex.writeln(\"  <tbody>\"); // NOI18N\n                for (int row = 0; row < rowCount; row++) {\n                    if (ex.failed()) return false;\n                    ex.writeln(\"   <tr>\"); // NOI18N\n                    for (int col = 0; col < columnCount; col++) {\n                        ex.write  (\"    <td><![CDATA[\"); // NOI18N\n                        ex.write  (escapeXML(table.getStringValue(row, col)));\n                        ex.writeln(\"]]></td>\"); // NOI18N\n                    }\n                    ex.writeln(\"   </tr>\"); // NOI18N\n                }\n                ex.writeln(\"  </tbody>\"); // NOI18N\n\n                ex.writeln(\" </table>\"); // NOI18N\n                ex.writeln(\"</dataview>\"); // NOI18N\n            }\n        } finally {\n            ex.close();\n        }\n        \n        return true;\n    }\n    \n    private static int LAST_indent = Integer.MIN_VALUE;\n    private static String LAST_INDENT;\n    private static String indent(int indent) {\n        if (LAST_indent == indent) return LAST_INDENT;\n        \n        if (indent == 0) return \"\"; // NOI18N\n        if (indent == 1) return \" \"; // NOI18N\n        if (indent == 2) return \"  \"; // NOI18N\n        if (indent == 3) return \"   \"; // NOI18N\n        if (indent == 4) return \"    \"; // NOI18N\n        if (indent == 5) return \"     \"; // NOI18N\n        \n        StringBuilder sb = new StringBuilder();\n        for (int i = 0; i < indent; i++) sb.append(\" \"); // NOI18N\n        LAST_indent = indent;\n        LAST_INDENT = sb.toString();\n        \n        return LAST_INDENT;\n    }\n    \n    \n    private static String escapeHTML(String s) {\n        StringBuilder sb = new StringBuilder();\n        int len = s.length();\n        for (int i = 0; i < len; i++) {\n          char c = s.charAt(i);\n          switch (c) {\n              case '<': sb.append(\"&lt;\"); break; // NOI18N\n              case '>': sb.append(\"&gt;\"); break; // NOI18N\n              case '&': sb.append(\"&amp;\"); break; // NOI18N\n              case '\"': sb.append(\"&quot;\"); break; // NOI18N\n              default: sb.append(c); break;\n          }\n        }\n        return sb.toString();\n    }\n    \n    private static String escapeXML(String s) {\n        return s;\n    }\n    \n    private static ExecutorService createExecutor(final String file) {\n        return Executors.newSingleThreadExecutor(new ThreadFactory() {\n            public Thread newThread(Runnable r) {\n                return new Thread(r, \"Export thread for \" + file); // NOI18N\n            }\n        });\n    }\n    \n    \n    private static final class Exporter {\n        \n        private static final int WRT_BUF = 16384;\n        private static final int STR_BUF = WRT_BUF * 2 - 512;\n        \n        private volatile boolean failed = false;\n        \n        private final File file;\n        private StringBuilder buffer;\n        \n        private Writer writer; // created and accessed in Executor only\n        private ExecutorService executor; // created and accessed in EDT only\n        \n        \n        Exporter(File file) {\n            this.file = file;\n            buffer = new StringBuilder();\n        }\n        \n        \n        boolean failed() {\n            return failed;\n        }\n        \n        \n        void write(char ch) {\n            if (failed) return;\n            \n            buffer.append(ch);\n            checkAutoFlush();\n        }\n        \n        void writeln(char ch) {\n            if (failed) return;\n            \n            buffer.append(ch).append(System.lineSeparator());\n            checkAutoFlush();\n        }\n        \n        void write(String string) {\n            if (failed) return;\n            \n            buffer.append(string);\n            checkAutoFlush();\n        }\n        \n        void writeln(String string) {\n            if (failed) return;\n            \n            buffer.append(string).append(System.lineSeparator());\n            checkAutoFlush();\n        }\n        \n        void writeln() {\n            if (failed) return;\n            \n            buffer.append(System.lineSeparator());\n            checkAutoFlush();\n        }\n        \n        void flush() {\n            if (failed) return;\n            \n            if (buffer.length() == 0) return;\n            \n            final StringBuilder _buffer = buffer;\n            buffer = new StringBuilder();\n            \n            if (executor == null) executor = createExecutor(file.getName());\n            executor.submit(new Runnable() {\n                public void run() {\n                    try {\n                        if (writer == null) writer = createWriter(file);\n                        writer.append(_buffer);\n                    } catch (Throwable t) {\n                        failed(t);\n                    }\n                }\n            });\n        }\n        \n        void close() {\n            if (failed) return;\n            \n            flush();\n            \n            if (executor != null) executor.submit(new Runnable() {\n                public void run() {\n                    if (writer != null) try {\n                        writer.close();\n                    } catch (Throwable t) {\n                        failed(t);\n                    }\n                }\n            });\n        }\n        \n        \n        private void failed(Throwable t) {\n            failed = true;\n            LOGGER.log(Level.INFO, t.getMessage(), t);\n            String msg = t.getLocalizedMessage().replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\"); // NOI18N\n            ProfilerDialogs.displayError(\"<html><b>\" + MSG_EXPORT_SNAPSHOT_FAILED + \"</b><br><br>\" + msg + \"</html>\"); // NOI18N\n        }\n        \n        \n        private void checkAutoFlush() {\n            if (buffer.length() > STR_BUF) flush();\n        }\n        \n        private static Writer createWriter(File file) throws IOException {\n            file.toPath(); // will fail for invalid file\n            CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder();\n            FileOutputStream out = new FileOutputStream(file);\n            return new BufferedWriter(new OutputStreamWriter(out, encoder), WRT_BUF);\n        }\n        \n    }\n    \n    \n    // Do not create instances of this class\n    private ExportUtils() {}\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/FilterUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.KeyEvent;\nimport java.text.MessageFormat;\nimport java.util.ResourceBundle;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.Icon;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.JToolBar;\nimport javax.swing.KeyStroke;\nimport javax.swing.RowFilter;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.text.JTextComponent;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.filters.TextFilter;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.spi.ActionsSupportProvider;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.CloseButton;\nimport org.graalvm.visualvm.lib.ui.results.ColoredFilter;\nimport org.graalvm.visualvm.lib.ui.results.PackageColorer;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class FilterUtils {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.swing.Bundle\"); // NOI18N\n    public static final String ACTION_FILTER = messages.getString(\"FilterUtils_ActionFilter\"); // NOI18N\n    private static final String SIDEBAR_CAPTION = messages.getString(\"FilterUtils_SidebarCaption\"); // NOI18N\n    private static final String BTN_FILTER_TOOLTIP = messages.getString(\"FilterUtils_BtnFilterTooltip\"); // NOI18N\n    private static final String BTN_MATCH_CASE_TOOLTIP = messages.getString(\"FilterUtils_BtnMatchCaseTooltip\"); // NOI18N\n    private static final String BTN_CLOSE_TOOLTIP = messages.getString(\"FilterUtils_BtnCloseTooltip\"); // NOI18N\n    private static final String MSG_INVALID_REGEXP = messages.getString(\"FilterUtils_MsgInvalidRegexp\"); // NOI18N\n    private static final String FILTER_CONTAINS = messages.getString(\"FilterUtils_FilterContains\"); // NOI18N\n    private static final String FILTER_NOT_CONTAINS = messages.getString(\"FilterUtils_FilterNotContains\"); // NOI18N\n    private static final String FILTER_REGEXP = messages.getString(\"FilterUtils_FilterRegexp\"); // NOI18N\n    private static final String FILTER_TYPE = messages.getString(\"FilterUtils_FilterType\"); // NOI18N\n    private static final String INSERT_FILTER = messages.getString(\"FilterUtils_InsertFilter\"); // NOI18N\n    // -----\n    \n    public static final String FILTER_ACTION_KEY = \"filter-action-key\"; // NOI18N\n    \n    private static final String FILTER_CHANGED = \"filter-changed\"; // NOI18N\n    \n    \n    public static boolean filterContains(ProfilerTable table, String filter) {\n        return filterContains(table, filter, false, null);\n    }\n    \n    public static boolean filterContains(ProfilerTable table, String filter, boolean matchCase, RowFilter excludes) {\n        return filter(table, new TextFilter(filter, TextFilter.TYPE_INCLUSIVE, matchCase), excludes);\n    }\n    \n    public static boolean filterNotContains(ProfilerTable table, String filter, boolean matchCase, RowFilter excludes) {\n        return filter(table, new TextFilter(filter, TextFilter.TYPE_EXCLUSIVE, matchCase), excludes);\n    }\n    \n    public static boolean filterRegExp(ProfilerTable table, String filter, RowFilter excludes) {\n        return filter(table, new TextFilter(filter, TextFilter.TYPE_REGEXP, false), excludes);\n    }\n    \n    public static boolean filter(ProfilerTable table, final GenericFilter textFilter, final RowFilter excludesFilter) {\n        final int mainColumn = table.getMainColumn();\n        \n        Filter filter = new Filter() {\n            public boolean include(RowFilter.Entry entry) {\n                if (excludesFilter != null && excludesFilter.include(entry)) return true;\n                return textFilter.passes(entry.getValue(mainColumn).toString());\n            }\n        };\n        \n        if (!textFilter.isEmpty()) {\n            table.addRowFilter(filter);\n            return table.getRowCount() > 0;\n        } else {\n            table.removeRowFilter(filter);\n            return false;\n        }\n    }\n    \n    public static JComponent createFilterPanel(final ProfilerTable table) {\n        return createFilterPanel(table, null);\n    }\n    \n    public static JComponent createFilterPanel(final ProfilerTable table, final RowFilter excludesFilter) {\n        return createFilterPanel(table, excludesFilter, null);\n    }\n    \n    public static JComponent createFilterPanel(final ProfilerTable table, final RowFilter excludesFilter, Component[] options) {\n        JToolBar toolbar = new InvisibleToolbar();\n        if (UIUtils.isWindowsModernLookAndFeel())\n            toolbar.setBorder(BorderFactory.createEmptyBorder(2, 2, 1, 2));\n        else if (!UIUtils.isNimbusLookAndFeel() && !UIUtils.isAquaLookAndFeel())\n            toolbar.setBorder(BorderFactory.createEmptyBorder(1, 2, 1, 2));\n        \n        toolbar.add(Box.createHorizontalStrut(6));\n        toolbar.add(new JLabel(SIDEBAR_CAPTION));\n        toolbar.add(Box.createHorizontalStrut(3));\n        \n        final EditableHistoryCombo combo = new EditableHistoryCombo();        \n        final JTextComponent textC = combo.getTextComponent();\n        \n        JPanel comboContainer = new JPanel(new BorderLayout());\n        comboContainer.add(combo, BorderLayout.CENTER);\n        comboContainer.setMinimumSize(combo.getMinimumSize());\n        comboContainer.setPreferredSize(combo.getPreferredSize());\n        comboContainer.setMaximumSize(combo.getMaximumSize());\n        \n        toolbar.add(comboContainer);\n        \n        if (PackageColorer.hasRegisteredColors()) {\n            toolbar.add(new PopupButton() {\n                {\n                    setToolTipText(INSERT_FILTER);\n                }\n//                protected void displayPopup() {\n//                    JPopupMenu menu = new JPopupMenu();\n//                    populatePopup(menu);\n//                    if (menu.getComponentCount() > 0) {\n//                        Dimension size = menu.getPreferredSize();\n//                        size.width = Math.max(size.width, getWidth());\n//                        menu.setPreferredSize(size);\n//                        menu.show(this, 0, -size.height);\n//                    }\n//                }\n                protected void populatePopup(JPopupMenu popup) {\n                    for (final ColoredFilter color : PackageColorer.getRegisteredColors()) {\n                        if (color.getValue().trim().isEmpty()) continue;\n                        Icon icon = color.getColor() == null ? null : color.getIcon(12, 12);\n                        popup.add(new JMenuItem(color.getName(), icon) {\n                            protected void fireActionPerformed(ActionEvent event) {\n                                String current = getFilterString(combo);\n                                if (current == null) current = \"\"; // NOI18N\n                                if (!current.isEmpty()) current += \" \"; // NOI18N\n                                current += color.getValue();\n                                textC.setText(current);\n                                combo.requestFocusInWindow();\n                            }\n                        });\n                    }\n                }\n            });\n        }\n        \n        toolbar.add(Box.createHorizontalStrut(5));\n        \n        KeyStroke escKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);\n        KeyStroke filterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);\n        \n        final TextFilter activeFilter = new TextFilter() {\n            protected void handleInvalidFilter(final String invalidValue, RuntimeException e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        ProfilerDialogs.displayError(MessageFormat.format(MSG_INVALID_REGEXP, invalidValue));\n                    }\n                });\n            }\n        };\n        final TextFilter currentFilter = new TextFilter();\n        \n        final JButton filter = new JButton(ACTION_FILTER, Icons.getIcon(GeneralIcons.FILTER)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                final JButton _this = this;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        activeFilter.copyFrom(currentFilter);\n                        if (filter(table, activeFilter, excludesFilter))\n                            combo.addItem(activeFilter.getValue());\n                        putClientProperty(FILTER_CHANGED, null);\n                        updateFilterButton(_this, currentFilter, activeFilter);\n                    }\n                });\n            }\n        };\n        String filterAccelerator = ActionsSupport.keyAcceleratorString(filterKey);\n        filter.setToolTipText(MessageFormat.format(BTN_FILTER_TOOLTIP, filterAccelerator));\n        \n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(final ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        if (filter.isEnabled()) {\n                            filter.doClick();\n                            combo.requestFocusInWindow();\n                        }\n                    }\n                });\n            }\n        };\n        installAction(filter, filterAction, filterKey, FILTER_ACTION_KEY);\n        toolbar.add(filter);\n        \n        updateFilterButton(filter, currentFilter, activeFilter);\n        \n        toolbar.add(Box.createHorizontalStrut(2));\n        \n        toolbar.addSeparator();\n        \n        toolbar.add(Box.createHorizontalStrut(1));\n        \n        final JToggleButton matchCase = new JToggleButton(Icons.getIcon(GeneralIcons.MATCH_CASE)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                if (isEnabled()) SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        currentFilter.setCaseSensitive(isSelected());\n                        updateFilterButton(filter, currentFilter, activeFilter);\n                    }\n                });\n            }\n        };\n        matchCase.setToolTipText(BTN_MATCH_CASE_TOOLTIP);\n        installAction(matchCase, filterAction, filterKey, FILTER_ACTION_KEY);\n        \n        PopupButton filterType = new PopupButton(Icons.getIcon(GeneralIcons.FILTER_CONTAINS)) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new JMenuItem(FILTER_CONTAINS, Icons.getIcon(GeneralIcons.FILTER_CONTAINS)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(TextFilter.TYPE_INCLUSIVE, getIcon(), getText());\n                    }\n                });\n                popup.add(new JMenuItem(FILTER_NOT_CONTAINS, Icons.getIcon(GeneralIcons.FILTER_NOT_CONTAINS)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(TextFilter.TYPE_EXCLUSIVE, getIcon(), getText());\n                    }\n                });\n                popup.add(new JMenuItem(FILTER_REGEXP, Icons.getIcon(GeneralIcons.FILTER_REG_EXP)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        filterImpl(TextFilter.TYPE_REGEXP, getIcon(), getText());\n                    }\n                });\n            }\n            private void filterImpl(final int type, final Icon icon, final String name) {\n                if (type == TextFilter.TYPE_REGEXP) {\n                    matchCase.setEnabled(false);\n                    matchCase.setSelected(false);\n                } else {\n                    if (!matchCase.isEnabled()) {\n                        matchCase.setSelected(currentFilter.isCaseSensitive());\n                        matchCase.setEnabled(true);\n                    }\n                }\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setIcon(icon);\n                        setToolTipText(MessageFormat.format(FILTER_TYPE, name));\n                        currentFilter.setType(type);\n                        updateFilterButton(filter, currentFilter, activeFilter);\n                    }\n                });\n            }\n        };\n        filterType.setToolTipText(MessageFormat.format(FILTER_TYPE, FILTER_CONTAINS));\n        installAction(filterType, filterAction, filterKey, FILTER_ACTION_KEY);\n        toolbar.add(filterType);\n        \n        toolbar.add(matchCase);\n        \n        if (options != null) for (Component option : options) toolbar.add(option);\n        \n        toolbar.add(Box.createHorizontalStrut(2));\n        \n        combo.setOnTextChangeHandler(new Runnable() {\n            public void run() {\n                currentFilter.setValue(getFilterString(combo));\n                updateFilterButton(filter, currentFilter, activeFilter);\n            }\n        });\n        \n        final JPanel panel = new JPanel(new BorderLayout()) {\n            public void setVisible(boolean visible) {\n                super.setVisible(visible);\n                if (!visible) table.requestFocusInWindow();\n            }\n            public boolean requestFocusInWindow() {\n                if (textC != null) textC.selectAll();\n                return combo.requestFocusInWindow();\n            }\n        };\n        panel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UIManager.getColor(\"controlShadow\"))); // NOI18N\n        panel.add(toolbar, BorderLayout.CENTER);\n        \n        final Runnable hider = new Runnable() {\n            public void run() {\n                activeFilter.setValue(\"\"); // NOI18N\n                updateFilterButton(filter, currentFilter, activeFilter);\n                filter(table, activeFilter, excludesFilter);\n                panel.setVisible(false);\n            }\n        };\n        JButton closeButton = CloseButton.create(hider);\n        String escAccelerator = ActionsSupport.keyAcceleratorString(escKey);\n        closeButton.setToolTipText(MessageFormat.format(BTN_CLOSE_TOOLTIP, escAccelerator));\n        panel.add(closeButton, BorderLayout.EAST);\n        \n        String HIDE = \"hide-action\"; // NOI18N\n        InputMap map = panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        Action hiderAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { hider.run(); }\n        };\n        panel.getActionMap().put(HIDE, hiderAction);\n        map.put(escKey, HIDE);\n        \n        if (textC != null) {\n            map = textC.getInputMap();\n            Action _filterAction = new AbstractAction() {\n                public void actionPerformed(final ActionEvent e) {\n                    if (combo.isPopupVisible()) combo.hidePopup();\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { if (filter.isEnabled()) filter.doClick(); }\n                    });\n                }\n            };\n            textC.getActionMap().put(FILTER_ACTION_KEY, _filterAction);\n            map.put(filterKey, FILTER_ACTION_KEY);\n        }\n        \n        panel.putClientProperty(\"SET_FILTER_CHANGED\", new AbstractAction() { // NOI18N\n            public void actionPerformed(final ActionEvent e) {\n                filter.putClientProperty(FILTER_CHANGED, Boolean.TRUE);\n                updateFilterButton(filter, currentFilter, activeFilter);\n            }\n        });\n        \n        return panel;\n    }\n    \n    private static void installAction(JComponent comp, Action action, KeyStroke keyStroke, String actionKey) {\n        comp.getActionMap().put(actionKey, action);\n        comp.getInputMap().put(keyStroke, actionKey);\n    }\n    \n    private static String getFilterString(EditableHistoryCombo combo) {\n        String filter = combo.getText();\n        return filter == null ? null : filter.trim();\n    }\n    \n    private static void updateFilterButton(JButton button, TextFilter currentFilter, TextFilter activeFilter) {\n        if (Boolean.TRUE.equals(button.getClientProperty(FILTER_CHANGED))) button.setEnabled(true);\n        else button.setEnabled(!currentFilter.equals(activeFilter));\n    }\n    \n    private static abstract class Filter extends RowFilter {\n\n        public boolean equals(Object o) {\n            return o instanceof Filter;\n        }\n        \n        public int hashCode() {\n            return Integer.MAX_VALUE;\n        }\n    \n    }\n    \n    \n    // Do not create instances of this class\n    private FilterUtils() {}\n    \n    \n    // Default keybinding Ctrl+G for Filter action\n    private static interface Support { @ServiceProvider(service=ActionsSupportProvider.class, position=100)\n        public static final class FilterActionProvider extends ActionsSupportProvider {\n            public KeyStroke registerAction(String actionKey, Action action, ActionMap actionMap, InputMap inputMap) {\n                if (!FILTER_ACTION_KEY.equals(actionKey)) return null;\n                \n                KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());\n                actionMap.put(actionKey, action);\n                inputMap.put(ks, actionKey);\n\n                return ks;\n            }\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/FilteringToolbar.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Component;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.KeyAdapter;\nimport java.awt.event.KeyEvent;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.AbstractButton;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.JTextField;\nimport javax.swing.JToggleButton;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.filters.TextFilter;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class FilteringToolbar extends InvisibleToolbar {\n\n    private TextFilter filter;\n\n    private final List<Component> hiddenComponents = new ArrayList<>();\n    private final AbstractButton filterButton;\n\n    public FilteringToolbar(String name) {\n        if (!UIUtils.isNimbusLookAndFeel())\n            setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));\n\n        filterButton = new JToggleButton(Icons.getIcon(GeneralIcons.FILTER)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                if (isSelected()) showFilter(); else hideFilter();\n            }\n        };\n        filterButton.setToolTipText(name);\n        add(filterButton);\n    }\n\n\n    protected abstract void filterChanged();\n\n\n    public final boolean isAll() {\n        return filter == null;\n    }\n\n    public final boolean passes(String value) {\n        return filter == null || filter.passes(value);\n    }\n\n    public final GenericFilter getFilter() {\n        TextFilter copy = new TextFilter();\n        if (filter != null) copy.copyFrom(filter);\n        return copy;\n    }\n\n    \n    private void filterChanged(String value) {\n        if (value == null) {\n            filter = null;\n        } else {\n            if (filter == null) filter = new TextFilter();\n            filter.setValue(value);\n        }\n        filterChanged();\n    }\n\n    private void showFilter() {\n        filterButton.setSelected(true);\n\n        final JTextField f = new JTextField();\n        f.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e)  { changed(); }\n            public void removeUpdate(DocumentEvent e)  { changed(); }\n            public void changedUpdate(DocumentEvent e) { changed(); }\n            private void changed() { filterChanged(f.getText().trim()); }\n        });\n        f.addKeyListener(new KeyAdapter() {\n            public void keyPressed(KeyEvent e) { if (esc(e)) hideFilter(); }\n            public void keyReleased(KeyEvent e) { esc(e); }\n            private boolean esc(KeyEvent e) {\n                boolean esc = e.getKeyCode() == KeyEvent.VK_ESCAPE;\n                if (esc) e.consume();\n                return esc;\n            }\n        });\n\n        for (int i = 1; i < getComponentCount(); i++)\n            hiddenComponents.add(getComponent(i));\n\n        for (Component c : hiddenComponents) remove(c);\n\n        add(Box.createHorizontalStrut(3));\n        add(f);\n        f.requestFocusInWindow();\n\n        invalidate();\n        revalidate();\n        doLayout();\n        repaint();\n    }\n\n    private void hideFilter() {\n        filterChanged(null);\n\n        remove(2);\n        remove(1);\n        for (Component c : hiddenComponents) add(c);\n\n        filterButton.setSelected(false);\n        filterButton.requestFocusInWindow();\n\n        invalidate();\n        revalidate();\n        doLayout();\n        repaint();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/GenericToolbar.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport javax.swing.AbstractButton;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.ButtonModel;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JRadioButton;\nimport javax.swing.JSeparator;\nimport javax.swing.JTextField;\nimport javax.swing.JToggleButton;\nimport javax.swing.JToolBar;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.plaf.basic.BasicComboBoxEditor;\nimport javax.swing.plaf.basic.BasicComboBoxRenderer;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n * Common superclass for custom toolbar implementations.\n * Implements various OS/LaF specific tweaks.\n *\n * @author Jiri Sedlacek\n */\npublic class GenericToolbar extends JToolBar {\n\n    public GenericToolbar() { super(); tweak(); }\n\n    public GenericToolbar(int orientation) { super(orientation); tweak(); }\n\n    public GenericToolbar(String name) { super(name); tweak(); }\n\n    public GenericToolbar(String name, int orientation) { super(name, orientation); tweak(); }\n\n\n    private void tweak() {\n        if (UIUtils.isGTKLookAndFeel() || UIUtils.isNimbusLookAndFeel()) {\n            int axis = getOrientation() == VERTICAL ? BoxLayout.PAGE_AXIS :\n                                                      BoxLayout.LINE_AXIS;\n            setLayout(new BoxLayout(this, axis));\n        }\n\n        if (UIUtils.isNimbusLookAndFeel())\n            setBorder(BorderFactory.createEmptyBorder(-2, 0, -2, 0));\n        else if (UIUtils.isAquaLookAndFeel())\n            setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 1));\n        \n        if (UIUtils.isWindowsClassicLookAndFeel()) setRollover(true);\n    }\n    \n    \n    public void addSeparator() {\n        if (!UIUtils.isMetalLookAndFeel()) {\n            super.addSeparator();\n        } else {\n            final JSeparator separator = new JSeparator(JSeparator.VERTICAL);\n            final int WDTH = separator.getPreferredSize().width;\n            final Dimension SIZE = new Dimension(new JToolBar.Separator().getSeparatorSize().width, 12);\n            JPanel panel = new JPanel(null) {\n                public Dimension getPreferredSize() { return SIZE; }\n                public Dimension getMaximumSize() { return SIZE; }\n                public Dimension getMinimumSize() { return SIZE; }\n\n                public void doLayout() {\n                    int x = (getWidth() - WDTH) / 2;\n                    int y = (getHeight()- SIZE.height) / 2;\n                    separator.setBounds(x, y, WDTH, SIZE.height);\n                }\n            };\n            panel.setOpaque(false);\n            panel.add(separator);\n            super.add(panel);\n        }\n    }\n    \n    protected void addImpl(Component comp, Object constraints, int index) {\n        if (UIUtils.isMetalLookAndFeel()) {\n            if (comp instanceof AbstractButton && !(comp instanceof JCheckBox) && !(comp instanceof JRadioButton)) {\n                final AbstractButton ab = (AbstractButton)comp;\n                ab.setMargin(new Insets(1, 1, 1, 1));\n                if (ab.getClientProperty(\"MetalListener\") == null) { // NOI18N\n                    final ButtonModel bm = ab.getModel();\n                    ChangeListener cl = new ChangeListener() {\n                        public void stateChanged(ChangeEvent e) {\n                            ab.setBorderPainted(bm.isArmed() || bm.isPressed() || bm.isRollover() || bm.isSelected());\n                            ab.setContentAreaFilled(bm.isArmed() || bm.isPressed() || bm.isRollover() || bm.isSelected());\n                        }\n                    };\n                    cl.stateChanged(null); // initialize the appearance tweaks\n                    ab.getModel().addChangeListener(cl);\n                    ab.putClientProperty(\"MetalListener\", cl); // NOI18N\n                }\n            }\n        } else if (UIUtils.isNimbusLookAndFeel()) {\n            if (comp instanceof AbstractButton && !(comp instanceof JCheckBox) && !(comp instanceof JRadioButton)) {\n                AbstractButton ab = (AbstractButton)comp;\n                ab.setMargin(new Insets(2, 2, 2, 2));\n            }\n        } else if (UIUtils.isAquaLookAndFeel()) {\n            if (comp instanceof AbstractButton && !(comp instanceof JCheckBox) && !(comp instanceof JRadioButton)) {\n                AbstractButton ab = (AbstractButton)comp;\n                ab.putClientProperty(\"JButton.buttonType\", \"segmentedTextured\"); // NOI18N\n                if (ab.getClientProperty(\"JButton.segmentPosition\") == null) // NOI18N\n                    ab.putClientProperty(\"JButton.segmentPosition\", \"only\"); // NOI18N\n                ab.setMargin(new Insets(-1, -1, -2, -1));\n            }\n        } else if (UIUtils.isWindowsClassicLookAndFeel()) {\n            if (comp instanceof AbstractButton && !(comp instanceof JCheckBox) && !(comp instanceof JRadioButton)) {\n                AbstractButton ab = (AbstractButton)comp;\n                ab.setMargin(new Insets(1, 1, 1, 1));\n            }\n        }\n        \n        if (comp instanceof JButton) UIUtils.fixButtonUI((JButton) comp);\n        \n        super.addImpl(comp, constraints, index);\n    }\n    \n    \n    protected void paintComponent(Graphics g) {\n        if (UIUtils.isGTKLookAndFeel() && getClientProperty(\"Toolbar.noGTKBorder\") == Boolean.TRUE) return; // NOI18N\n        super.paintComponent(g);\n    }\n    \n    \n    private static int PREFERRED_HEIGHT = -1;\n    \n    public Dimension getPreferredSize() {\n        Dimension dim = super.getPreferredSize();\n        if (PREFERRED_HEIGHT == -1) {\n            GenericToolbar tb = new GenericToolbar();\n            tb.setBorder(getBorder());\n            tb.setBorderPainted(isBorderPainted());\n            tb.setRollover(isRollover());\n            tb.setFloatable(isFloatable());\n            Icon icon = Icons.getIcon(GeneralIcons.SAVE);\n            tb.add(new JButton(\"Button\", icon)); // NOI18N\n            tb.add(new JToggleButton(\"Button\", icon)); // NOI18N\n            tb.add(new JTextField(\"Text\")); // NOI18N\n            JComboBox c = new JComboBox();\n            c.setEditor(new BasicComboBoxEditor());\n            c.setRenderer(new BasicComboBoxRenderer());\n            tb.add(c);\n            tb.addSeparator();\n            PREFERRED_HEIGHT = tb.getSuperPreferredSize().height;\n        }\n        dim.height = getParent() instanceof JToolBar ? 1 :\n                     Math.max(dim.height, PREFERRED_HEIGHT);\n        return dim;\n    }\n    \n    private Dimension getSuperPreferredSize() {\n        return super.getPreferredSize();\n    }\n    \n    \n    public void doLayout() {\n        // #216443 - disabled/invisible/JLabel toolbar components\n        //           break left/right arrow focus traversal\n        for (Component component : getComponents())\n            component.setFocusable(isFocusableComponent(component));\n        super.doLayout();\n    }\n    \n    protected boolean isFocusableComponent(Component component) {\n        if (!component.isVisible()) return false;\n//            if (!component.isEnabled()) return false;\n        if (component instanceof JLabel) return false;\n        if (component instanceof JPanel) return false;\n        if (component instanceof JSeparator) return false;\n        if (component instanceof JToolBar) return false;\n        if (component instanceof Box.Filler) return false;\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/GrayLabel.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Color;\nimport javax.swing.Icon;\nimport javax.swing.JLabel;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class GrayLabel extends JLabel {\n\n    { setFocusable(false); }\n\n\n    public GrayLabel() { super(); }\n\n    public GrayLabel(Icon icon) { super(icon); }\n\n    public GrayLabel(String text) { super(text); }\n\n    public GrayLabel(Icon icon, int alignment) { super(icon, alignment); }\n\n    public GrayLabel(String text, int alignment) { super(text, alignment); }\n\n    public GrayLabel(String text, Icon icon, int alignment) { super(text, icon, alignment); }\n\n\n    public Color getForeground() {\n        return UIUtils.getDisabledLineColor();\n    }\n\n\n    public void setEnabled(boolean enabled) {\n        super.setEnabled(true); // To workaround the 3D look on some LaFs\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/HeaderComponent.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Graphics;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.CellRendererPane;\nimport javax.swing.JComponent;\nimport javax.swing.JTable;\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumn;\n\n/**\n * JComponent with TableHeader appearance.\n *\n * @author Jiri Sedlacek\n */\nclass HeaderComponent extends JComponent {\n\n    private boolean isPressed;\n    private boolean isSelected;\n\n    HeaderComponent(final ActionListener listener) {\n        if (listener != null) addMouseListener(new MouseAdapter() {\n            public void mousePressed(MouseEvent e) {\n                isPressed = true;\n                isSelected = true;\n                repaint();\n            }\n            public void mouseReleased(MouseEvent e) {\n                isPressed = false;\n                if (isSelected) {\n                    repaint();\n                    fireActionEvent(e);\n                }\n            }\n            public void mouseEntered(MouseEvent e) {\n                if (isPressed || !isButtonDown(e)) {\n                    isSelected = true;\n                    repaint();\n                }\n            }\n            public void mouseExited(MouseEvent e) {\n                if (isSelected) {\n                    isSelected = false;\n                    repaint();\n                }\n            }\n            private void fireActionEvent(MouseEvent e) {\n                ActionEvent ae = new ActionEvent(e.getSource(), e.getID(),\n                                                 e.paramString(), e.getWhen(),\n                                                 e.getModifiers());\n                listener.actionPerformed(ae);\n            }\n            private boolean isButtonDown(MouseEvent e) {\n                return SwingUtilities.isLeftMouseButton(e) ||\n                       SwingUtilities.isMiddleMouseButton(e) ||\n                       SwingUtilities.isRightMouseButton(e);\n            }\n        });\n    }\n    \n    protected void paintComponent(Graphics g) {\n        JTableHeader header = getHeader();\n        setupHeader(header);\n        TableCellRenderer renderer = header.getDefaultRenderer();\n        JComponent component = (JComponent)renderer.getTableCellRendererComponent(\n                               getTable(), \"\", isSelected && isPressed, isFocusOwner(), -1, 0); // NOI18N\n        \n        int height = header.getPreferredSize().height;\n        component.setBounds(0, 0, getWidth(), height);\n        component.setOpaque(false);\n        getPainter().paintComponent(g, component, null, 0, 0, getWidth(), height, false);\n    }\n    \n    private void setupHeader(JTableHeader h) {\n        h.setDraggedColumn(isSelected && isPressed ? getColumn() : null);\n        \n        MouseEvent e = isSelected && !isPressed ?\n                new MouseEvent(h, MouseEvent.MOUSE_ENTERED, 1, 0, 1, 1, 0, false) :\n                new MouseEvent(h, MouseEvent.MOUSE_EXITED, 1, 0, 0, 0, 0, false);\n        h.dispatchEvent(e);\n    }\n    \n    \n    private static CellRendererPane PAINTER;\n    private static CellRendererPane getPainter() {\n        if (PAINTER == null) PAINTER = new CellRendererPane();\n        return PAINTER;\n    }\n    \n    private static JTable REF_TABLE;\n    private static JTable getTable() {\n        if (REF_TABLE == null) REF_TABLE = new JTable(new Object[][] {{}},\n                                                      new Object[] { \" \" }) { // NOI18N\n            protected JTableHeader createDefaultTableHeader() {\n                return new JTableHeader(columnModel) {\n                    public boolean contains(int x, int y) { return x == 1 && y == 1; }\n                };\n            }\n        };\n        return REF_TABLE;\n    }\n    \n    private static JTableHeader getHeader() {\n        return getTable().getTableHeader();\n    }\n    \n    private static TableColumn getColumn() {\n        return getHeader().getColumnModel().getColumn(0);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/InvisibleToolbar.java",
    "content": "/*\n * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Insets;\nimport javax.swing.BorderFactory;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class InvisibleToolbar extends GenericToolbar {\n\n    public InvisibleToolbar() { super(); tweak(); }\n\n    public InvisibleToolbar(int orientation) { super(orientation); tweak(); }\n\n    public InvisibleToolbar(String name) { super(name); tweak(); }\n\n    public InvisibleToolbar(String name, int orientation) { super(name, orientation); tweak(); }\n\n\n    private void tweak() {\n        setBorder(BorderFactory.createEmptyBorder());\n        setBorderPainted(false);\n        setFloatable(false);\n        setRollover(true);\n        setOpaque(false);\n        setMargin(new Insets(0, 0, 0, 0));\n\n        putClientProperty(\"Toolbar.noGTKBorder\", Boolean.TRUE); // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/MultiButtonGroup.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.ButtonGroup;\nimport javax.swing.ButtonModel;\n\n/**\n * Button group with AT LEAST one button selected.\n *\n * @author Jiri Sedlacek\n */\npublic class MultiButtonGroup extends ButtonGroup {\n\n    private final Set<ButtonModel> selected = new HashSet<>();\n\n    public void setSelected(ButtonModel m, boolean b) {\n        if (!b) {\n            for (ButtonModel model : selected) {\n                if (model.isSelected() && model != m) {\n                    selected.remove(m);\n                    return;\n                }\n            }\n        } else {\n            selected.add(m);\n        }\n    }\n\n    public boolean isSelected(ButtonModel m) {\n        return selected.contains(m);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/PopupButton.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.event.ActionEvent;\nimport javax.swing.Action;\nimport javax.swing.Icon;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToolBar;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class PopupButton extends SmallButton {\n\n    private static final Icon DROPDOWN_ICON = Icons.getIcon(GeneralIcons.POPUP_ARROW);\n    private static final int DROPDOWN_ICON_WIDTH = DROPDOWN_ICON.getIconWidth();\n    private static final int DROPDOWN_ICON_HEIGHT = DROPDOWN_ICON.getIconHeight();\n\n    private int iconOffset;\n    private int popupAlign = SwingConstants.LEADING;\n\n\n    {\n        if (UIUtils.isMetalLookAndFeel()) iconOffset = 6;\n        else if (UIUtils.isNimbusLookAndFeel()) iconOffset = 8;\n        else iconOffset = 7;\n\n        setHorizontalAlignment(LEADING);\n    }\n\n\n    public PopupButton() { super(); }\n\n    public PopupButton(Icon icon) { super(icon); }\n\n    public PopupButton(String text) { super(text); }\n\n    public PopupButton(Action a) { super(a); }\n\n    public PopupButton(String text, Icon icon) { super(text, icon); }\n\n\n    public void setPopupAlign(int align) {\n        popupAlign = align;\n    }\n\n    public int getPopupAlign() {\n        return popupAlign;\n    }\n\n\n    protected void fireActionPerformed(ActionEvent e) {\n        super.fireActionPerformed(e);\n        displayPopup();\n    }\n\n    protected void displayPopup() {\n        JPopupMenu menu = new JPopupMenu();\n        populatePopup(menu);\n        if (menu.getComponentCount() > 0) {\n            Dimension size = menu.getPreferredSize();\n            size.width = Math.max(size.width, getWidth());\n            menu.setPreferredSize(size);\n            \n            int align = getPopupAlign();\n            \n            int x;\n            switch (align) {\n                case SwingConstants.EAST:\n                case SwingConstants.NORTH_EAST:\n                case SwingConstants.SOUTH_EAST:\n                    x = getWidth() - size.width;\n                    break;\n                default:\n                    x = 0;\n                    break;\n            }\n            \n            int y;\n            switch (align) {\n                case SwingConstants.NORTH:\n                case SwingConstants.NORTH_EAST:\n                case SwingConstants.NORTH_WEST:\n                    y = -size.height;\n                    break;\n                default:\n                    y = getHeight();\n                    break;\n            }\n            \n            menu.show(this, x, y);\n        }\n    }\n    \n    protected void populatePopup(JPopupMenu popup) {\n        // Implementation here\n    }\n    \n    \n    public Dimension getPreferredSize() {\n        Dimension size = super.getPreferredSize();\n        size.width += DROPDOWN_ICON_WIDTH + (isEmpty() ? 3 : 5);\n        return size;\n    }\n    \n    public Dimension getMinimumSize() {\n        return getPreferredSize();\n    }\n    \n    public Dimension getMaximumSize() {\n        return getPreferredSize();\n    }\n    \n    public void addNotify() {\n        super.addNotify();\n        if (UIUtils.isWindowsLookAndFeel() && getParent() instanceof JToolBar) {\n            if (getIcon() == NO_ICON) setIconTextGap(2);\n            iconOffset = 5;\n        }\n    }\n    \n    protected void paintComponent(Graphics g) {\n        super.paintComponent(g);\n        if (isEmpty()) {\n            DROPDOWN_ICON.paintIcon(this, g, (getWidth() - DROPDOWN_ICON_WIDTH) / 2,\n                                             (getHeight() - DROPDOWN_ICON_HEIGHT) / 2);\n        } else {\n            DROPDOWN_ICON.paintIcon(this, g, getWidth() - DROPDOWN_ICON_WIDTH - iconOffset,\n                                            (getHeight() - DROPDOWN_ICON_HEIGHT) / 2);\n        }\n    }\n    \n    \n    private boolean isEmpty() {\n        if (getIcon() != NO_ICON) return false;\n        String text = getText();\n        return text == null || text.isEmpty();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/ProfilerColumnModel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.Set;\nimport javax.swing.SortOrder;\nimport javax.swing.table.DefaultTableColumnModel;\nimport javax.swing.table.TableColumn;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ProfilerColumnModel extends DefaultTableColumnModel {\n\n    private static final String PROP_COLUMN_WIDTH = \"width\"; // NOI18N\n\n    // --- Package-private constructor -----------------------------------------\n\n    ProfilerColumnModel() {\n        super();\n    }\n\n    // --- Column width --------------------------------------------------------\n\n    private int fitWidthColumn = 0;\n\n    void setFitWidthColumn(int column) {\n        fitWidthColumn = column;\n    }\n\n    int getFitWidthColumn() {\n        return fitWidthColumn;\n    }\n\n    boolean hasFitWidthColumn() {\n        return fitWidthColumn != -1;\n    }\n\n    // --- Column resize -------------------------------------------------------\n\n    private int refWidth = -1;\n\n    void setResizingColumn(TableColumn column) {\n        refWidth = -1;\n    }\n\n    TableColumn createTableColumn(int columnIndex) {\n        return new TableColumn(columnIndex) {\n            public void setWidth(int width) {\n                if (getMaxWidth() == 0 && getWidth() == 0) {\n                    TableColumn c = getPreviousVisibleColumn(this);\n                    if (refWidth == -1) refWidth = c.getWidth();\n                    c.setWidth(refWidth + width);\n                } else {\n                    super.setWidth(width);\n                }\n            }                \n        };\n    }\n    \n    public void addColumn(final TableColumn column) {\n        super.addColumn(column);\n        \n        final int index = column.getModelIndex();\n        column.addPropertyChangeListener(new PropertyChangeListener() {\n            public void propertyChange(PropertyChangeEvent evt) {\n                if (PROP_COLUMN_WIDTH.equals(evt.getPropertyName())) {\n                    int oldWidth = ((Integer)evt.getOldValue()).intValue();\n                    int newWidth = ((Integer)evt.getNewValue()).intValue();\n                    fireColumnWidthChanged(index, oldWidth, newWidth);\n                }\n            }\n        });\n    }\n    \n    // --- Column offset & width -----------------------------------------------\n    \n    private Map<Integer, Integer> columnOffsets;\n    private Map<Integer, Integer> columnPreferredWidths;\n    \n    boolean setColumnOffset(int column, int offset) {\n        if (columnOffsets == null) columnOffsets = new HashMap<>();\n        Integer previousOffset = columnOffsets.put(column, offset);\n        int _previousOffset = previousOffset == null ? 0 : previousOffset.intValue();\n        boolean change = _previousOffset != offset;\n        if (change) fireColumnOffsetChanged(column, _previousOffset, offset);\n        return change;\n    }\n    \n    int getColumnOffset(int column) {\n        if (columnOffsets == null) return 0;\n        Integer offset = columnOffsets.get(column);\n        return offset == null ? 0 : offset.intValue();\n    }\n    \n    void clearColumnsPrefferedWidth() {\n        if (columnPreferredWidths != null) columnPreferredWidths.clear();\n    }\n    \n    boolean setColumnPreferredWidth(int column, int width) {\n        if (columnPreferredWidths == null) columnPreferredWidths = new HashMap<>();\n        Integer previousWidth = columnPreferredWidths.put(column, width);\n        int _previousWidth = previousWidth == null ? 0 : previousWidth.intValue();\n        boolean change = _previousWidth != width;\n        if (change) fireColumnPreferredWidthChanged(column, _previousWidth, width);\n        return change;\n    }\n    \n    int getColumnPreferredWidth(int column) {\n        if (columnPreferredWidths == null) return 0;\n        Integer width = columnPreferredWidths.get(column);\n        return width == null ? 0 : width.intValue();\n    }\n    \n    // --- Column visibility ---------------------------------------------------\n    \n    private int minColumnWidth = 20;\n    private int defaultColumnWidth = 60;\n    private Map<Integer, Integer> defaultColumnWidths;\n    private Map<Integer, Integer> hiddenColumnWidths = new HashMap<>();\n    \n    void setDefaultColumnWidth(int width) {\n        defaultColumnWidth = width;\n        Enumeration<TableColumn> columns = getColumns();\n        while (columns.hasMoreElements()) {\n            TableColumn column = columns.nextElement();\n            int index = column.getModelIndex();\n            if (defaultColumnWidths == null || defaultColumnWidths.get(index) == null)\n                if (index != fitWidthColumn) column.setWidth(width);\n        }\n    }\n    \n    void setDefaultColumnWidth(int column, int width) {\n        if (defaultColumnWidths == null) defaultColumnWidths = new HashMap<>();\n        defaultColumnWidths.put(column, width);\n        if (isColumnVisible(column)) {\n            TableColumn c = getModelColumn(column);\n            if (c != null) c.setWidth(width);\n        } else {\n            hiddenColumnWidths.put(column, width);\n        }\n    }\n    \n    int getDefaultColumnWidth(int column) {\n        Integer width = defaultColumnWidths == null ? null :\n                        defaultColumnWidths.get(column);\n        return width == null ? defaultColumnWidth : width.intValue();\n    }\n    \n    void setColumnVisibility(int column, boolean visible, ProfilerTable table) {\n        setColumnVisibility(getModelColumn(column), visible, table);\n    }\n    \n    void setColumnVisibility(TableColumn column, boolean visible, ProfilerTable table) {\n        if (visible) showColumn(column, table);\n        else hideColumn(column, table);\n    }\n    \n    boolean isColumnVisible(int column) {\n        return isColumnVisible(getModelColumn(column));\n    }\n    \n    boolean isColumnVisible(TableColumn column) {\n        return column.getMaxWidth() > 0;\n    }\n    \n    int getVisibleColumnCount() {\n        return getColumnCount() - hiddenColumnWidths.size();\n    }\n    \n    void showColumn(TableColumn column, ProfilerTable table) {\n        if (isColumnVisible(column)) return;\n        \n        column.setMaxWidth(Integer.MAX_VALUE);\n        Integer width = hiddenColumnWidths.remove(column.getModelIndex());\n        column.setWidth(width != null ? width.intValue() :\n                        getDefaultColumnWidth(column.getModelIndex()));\n        column.setMinWidth(minColumnWidth);\n        \n        int toResizeIndex = getFitWidthColumn();\n        if (column.getModelIndex() == toResizeIndex) {\n            Enumeration<TableColumn> columns = getColumns();\n            while (columns.hasMoreElements()) {\n                TableColumn col = columns.nextElement();\n                int index = col.getModelIndex();\n                if (col.getModelIndex() != toResizeIndex && isColumnVisible(col))\n                    col.setWidth(getDefaultColumnWidth(index));\n            }\n            table.doLayout();\n        }\n    }\n    \n    void hideColumn(TableColumn column, ProfilerTable table) {\n        if (!isColumnVisible(column)) return;\n        \n        hiddenColumnWidths.put(column.getModelIndex(), column.getWidth());\n        column.setMinWidth(0);\n        column.setMaxWidth(0);\n        \n        int selected = table.getSelectedColumn();\n        if (selected != -1 && getColumn(selected).equals(column)) {\n            int newSelected = getPreviousVisibleColumn(selected);\n            getSelectionModel().setSelectionInterval(newSelected, newSelected);\n        }\n                \n        if (table.isSortable()) {\n            ProfilerRowSorter sorter = table._getRowSorter();\n            int sortColumn = sorter.getSortColumn();\n            if (sortColumn == column.getModelIndex()) {\n                int newSortColumn = table.convertColumnIndexToView(sortColumn);\n                newSortColumn = getPreviousVisibleColumn(newSortColumn);\n                int modelIndex = getColumn(newSortColumn).getModelIndex();\n                if (!sorter.allowsThreeStateColumns()) sorter.setSortColumn(modelIndex);\n                else sorter.setSortColumn(modelIndex, SortOrder.UNSORTED);\n            }\n        }\n    }\n    \n    int getFirstVisibleColumn() {\n        int firstColumn = 0;\n        return isColumnVisible(getColumn(firstColumn)) ? firstColumn :\n               getNextVisibleColumn(firstColumn);\n    }\n    \n    int getLastVisibleColumn() {\n        int lastColumn = getColumnCount() - 1;\n        return isColumnVisible(getColumn(lastColumn)) ? lastColumn :\n               getPreviousVisibleColumn(lastColumn);\n    }\n    \n    TableColumn getNextVisibleColumn(TableColumn column) {\n        int columnIndex = tableColumns.indexOf(column);\n        int nextIndex = getNextVisibleColumn(columnIndex);\n        return getColumn(nextIndex);\n    }\n    \n    int getNextVisibleColumn(int column) {\n        do { column = getNextColumn(column); }\n        while (!isColumnVisible(getColumn(column)));\n        return column;\n    }\n    \n    TableColumn getPreviousVisibleColumn(TableColumn column) {\n        int columnIndex = tableColumns.indexOf(column);\n        int previousIndex = getPreviousVisibleColumn(columnIndex);\n        return getColumn(previousIndex);\n    }\n    \n    int getPreviousVisibleColumn(int column) {\n        do { column = getPreviousColumn(column); }\n        while (!isColumnVisible(getColumn(column)));\n        return column;\n    }\n    \n    private int getNextColumn(int column) {\n        return ++column == getColumnCount() ? 0 : column;\n    }\n    \n    private int getPreviousColumn(int column) {\n        return --column == -1 ? getColumnCount() - 1 : column;\n    }\n    \n    private TableColumn getModelColumn(int modelIndex) {\n        Enumeration<TableColumn> columns = getColumns();\n        while (columns.hasMoreElements()) {\n            TableColumn column = columns.nextElement();\n            if (column.getModelIndex() == modelIndex) return column;\n        }\n        return null;\n    }\n    \n    // --- Column tooltip ------------------------------------------------------\n    \n    private String[] toolTips;\n    \n    void setColumnToolTips(String[] toolTips) {\n        this.toolTips = Arrays.copyOf(toolTips, toolTips.length);\n    }\n    \n    String getColumnToolTip(int column) {\n        if (toolTips == null) return null;\n        return column < 0 || column >= toolTips.length ? null : toolTips[column];\n    }\n    \n    // --- Listener ------------------------------------------------------------\n    \n    private Set<Listener> columnListeners;\n    \n    void addColumnChangeListener(Listener listener) {\n        if (columnListeners == null) columnListeners = new HashSet<>();\n        columnListeners.add(listener);\n    }\n    \n    void removeColumnChangeListener(Listener listener) {\n        if (columnListeners == null) return;\n        columnListeners.remove(listener);\n        if (columnListeners.isEmpty()) columnListeners = null;\n    }\n    \n    private void fireColumnOffsetChanged(int column, int oldOffset, int newOffset) {\n        if (columnListeners == null) return;\n        for (Listener listener : columnListeners)\n            listener.columnOffsetChanged(column, oldOffset, newOffset);\n    }\n    \n    private void fireColumnWidthChanged(int column, int oldWidth, int newWidth) {\n        if (columnListeners == null) return;\n        for (Listener listener : columnListeners)\n            listener.columnWidthChanged(column, oldWidth, newWidth);\n    }\n    \n    private void fireColumnPreferredWidthChanged(int column, int oldWidth, int newWidth) {\n        if (columnListeners == null) return;\n        for (Listener listener : columnListeners)\n            listener.columnPreferredWidthChanged(column, oldWidth, newWidth);\n    }\n    \n    static interface Listener {\n        \n        public void columnOffsetChanged(int column, int oldOffset, int newOffset);\n        \n        public void columnWidthChanged(int column, int oldWidth, int newWidth);\n        \n        public void columnPreferredWidthChanged(int column, int oldWidth, int newWidth);\n        \n    }\n    \n    // --- Persistence ---------------------------------------------------------\n    \n    private static final String COLUMN_INDEX_KEY = \"ProfilerColumnModel.ColumnIndex\"; // NOI18N\n    private static final String COLUMN_WIDTH_KEY = \"ProfilerColumnModel.ColumnWidth\"; // NOI18N\n    \n    void loadFromStorage(Properties properties, ProfilerTable table) {\n        for (int i = 0; i < getColumnCount(); i++) {\n            String indexS = properties.getProperty(COLUMN_INDEX_KEY + \".\" + i); // NOI18N\n            if (indexS == null) continue;\n            try {\n                int index = Integer.parseInt(indexS);\n                int width = getDefaultColumnWidth(index);\n                String widthS = properties.getProperty(COLUMN_WIDTH_KEY + \".\" + i); // NOI18N\n                if (widthS != null) try {\n                    width = Integer.parseInt(widthS);\n                } catch (NumberFormatException e) {}\n                TableColumn column = getModelColumn(index);\n                column.setIdentifier(i);\n                if (index != getFitWidthColumn()) {\n                    if (width == 0) hideColumn(column, table);\n                    else column.setWidth(width);\n                }\n            } catch (NumberFormatException e) {}\n        }\n        tableColumns.sort(new Comparator<TableColumn>() {\n            public int compare(TableColumn c1, TableColumn c2) {\n                Integer index1 = (Integer) c1.getIdentifier();\n                Integer index2 = (Integer) c2.getIdentifier();\n                return index1.compareTo(index2);\n            }\n        });\n    }\n    \n    void saveToStorage(Properties properties, ProfilerTable table) {\n        for (int i = 0; i < getColumnCount(); i++) {\n            TableColumn column = getColumn(i);\n            properties.setProperty(COLUMN_INDEX_KEY + \".\" + i, Integer.toString(column.getModelIndex())); // NOI18N\n            properties.setProperty(COLUMN_WIDTH_KEY + \".\" + i, Integer.toString(column.getWidth())); // NOI18N\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/ProfilerPopup.java",
    "content": "/*\n * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Cursor;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.FocusTraversalPolicy;\nimport java.awt.Frame;\nimport java.awt.Graphics;\nimport java.awt.KeyEventDispatcher;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.Window;\nimport java.awt.event.ComponentEvent;\nimport java.awt.event.ComponentListener;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport java.awt.event.MouseMotionListener;\nimport java.awt.event.WindowAdapter;\nimport java.awt.event.WindowEvent;\nimport java.awt.event.WindowFocusListener;\nimport java.lang.ref.Reference;\nimport java.lang.ref.WeakReference;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.List;\nimport javax.swing.AbstractButton;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.ButtonGroup;\nimport javax.swing.ButtonModel;\nimport javax.swing.DefaultButtonModel;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JToolBar;\nimport javax.swing.JWindow;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport javax.swing.border.Border;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ProfilerPopup {\n\n    private static final boolean DEBUG = Boolean.getBoolean(\"ProfilerPopup.DebugWindows\"); // NOI18N\n\n    private static final int IGNORE_OWNER_TIMEOUT = Integer.getInteger(\"ProfilerPopup.OwnerTimeout\", 40); // NOI18N\n    private static final int RESIZE_STRIPE = Integer.getInteger(\"ProfilerPopup.ResizeStripe\", 10); // NOI18N\n\n    public static final int RESIZE_NONE    = 0;\n    public static final int RESIZE_TOP     = 1;\n    public static final int RESIZE_LEFT    = 2;\n    public static final int RESIZE_BOTTOM  = 4;\n    public static final int RESIZE_RIGHT   = 8;\n    \n//    private Reference<Component> focusRef;\n    private final Reference<Window> ownerRef;\n    \n    private final PopupPane content;\n    private final Rectangle location;\n    private final int popupAlign;\n    \n    private JWindow window;\n    private Window owner;\n    \n    private Point ownerLocation;\n    \n    private final Listener listener;\n    \n    private final int resizeMode;\n    \n    \n    public static ProfilerPopup create(Component invoker, Component content, int x, int y) {\n        return create(invoker, content, x, y, RESIZE_NONE);\n    }\n    \n    public static ProfilerPopup createRelative(Component invoker, Component content, int popupAlign) {\n        if (invoker == null) throw new IllegalArgumentException(\"Invoker cannot be null for relative popups\"); // NOI18N\n        return createRelative(invoker, content, popupAlign, RESIZE_NONE);\n    }\n    \n    public static ProfilerPopup create(Component invoker, Component content, int x, int y, int resizeMode) {\n        return create(invoker, content, x, y, resizeMode, null);\n    }\n    \n    public static ProfilerPopup createRelative(Component invoker, Component content, int popupAlign, int resizeMode) {\n        if (invoker == null) throw new IllegalArgumentException(\"Invoker cannot be null for relative popups\"); // NOI18N\n        return createRelative(invoker, content, popupAlign, resizeMode, null);\n    }\n    \n    public static ProfilerPopup create(Component invoker, Component content, int x, int y, int resizeMode, Listener listener) {\n        return create(invoker, content, x, y, -1, resizeMode, listener);\n    }\n    \n    public static ProfilerPopup createRelative(Component invoker, Component content, int popupAlign, int resizeMode, Listener listener) {\n        if (invoker == null) throw new IllegalArgumentException(\"Invoker cannot be null for relative popups\"); // NOI18N\n        return create(invoker, content, -1, -1, popupAlign, resizeMode, listener);\n    }\n    \n    private static ProfilerPopup create(Component invoker, Component content, int x, int y, int popupAlign, int resizeMode, Listener listener) {\n        Point location = new Point(x, y);\n        Dimension size = new Dimension();\n        Window owner = null;\n        \n        if (invoker != null) {\n            SwingUtilities.convertPointToScreen(location, invoker);\n            size.setSize(invoker.getSize());\n            owner = SwingUtilities.getWindowAncestor(invoker);\n        }\n        \n        return new ProfilerPopup(content, new Rectangle(location, size), popupAlign, owner, resizeMode, listener);\n    }\n    \n    \n    public void show() {\n//        Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();\n//        if (focusOwner != null) focusRef = new WeakReference(focusOwner);\n            \n        owner = ownerRef == null ? null : ownerRef.get();\n        ownerLocation = owner == null ? null : owner.getLocationOnScreen();\n        \n        window = new JWindow(owner);\n        window.setType(Window.Type.POPUP);\n        window.setAlwaysOnTop(false);\n        window.setFocusable(true);\n        window.setFocusableWindowState(true);\n        window.setAutoRequestFocus(true);\n        \n        window.getContentPane().add(content);\n        window.pack();\n        \n        if (popupAlign == -1) {\n            window.setLocation(location.getLocation());\n        } else {\n            Dimension size = content.getSize();\n            \n            int x;\n            switch (popupAlign) {\n                case SwingConstants.EAST:\n                case SwingConstants.NORTH_EAST:\n                case SwingConstants.SOUTH_EAST:\n                    x = location.x + location.width - size.width + 1;\n                    break;\n                default:\n                    x = location.x + 1;\n                    break;\n            }\n            \n            int y;\n            switch (popupAlign) {\n                case SwingConstants.NORTH:\n                case SwingConstants.NORTH_EAST:\n                case SwingConstants.NORTH_WEST:\n                    y = location.y - size.height + 1;\n                    break;\n                default:\n                    y = location.y + location.height + 1;\n                    break;\n            }\n            \n            window.setLocation(x, y);\n        }\n        \n        window.setVisible(true);\n        \n        Component defaultFocus = content.getFocusTraversalPolicy().getDefaultComponent(content);\n        if (defaultFocus != null) defaultFocus.requestFocusInWindow();\n        \n        content.installListeners();\n        \n        if (listener != null) listener.popupShown();\n    }\n    \n    public void hide() {\n        content.uninstallListeners();\n        \n        owner = null;\n        ownerLocation = null;\n\n        window.setVisible(false);\n        window.dispose();\n        window = null;\n        \n//        if (focusRef != null) {\n//            Component focusOwner = focusRef.get();\n//            focusRef.clear();\n//            focusRef = null;\n//            if (focusOwner != null) focusOwner.requestFocusInWindow();\n//        }\n        \n        if (listener != null) listener.popupHidden();\n    }\n    \n    \n    public static boolean isInPopup(Component component) {\n        Container parent = component.getParent();\n        while (parent != null)\n            if (parent instanceof PopupPane) return true;\n            else parent = parent.getParent();\n        return false;\n    }\n    \n    \n    private ProfilerPopup(Component component, Rectangle location, int popupAlign, Window owner, int resizeMode, Listener listener) {\n        this.content = new PopupPane(component, resizeMode != RESIZE_NONE);\n        this.location = location;\n        this.popupAlign = popupAlign;\n        this.ownerRef = owner == null ? null : new WeakReference<>(owner);\n        this.resizeMode = resizeMode;\n        this.listener = listener;\n    }\n    \n    \n    public static abstract class Listener {\n        \n        protected void popupShown() {}\n        \n        protected void popupHidden() {}\n        \n    }\n    \n    \n    private class PopupPane extends JPanel implements WindowFocusListener, ComponentListener, KeyEventDispatcher,\n                                                      MouseListener, MouseMotionListener {\n        \n        private boolean skippingEvents;\n        private long gainedFocusTime;\n        \n        \n        PopupPane(Component content, boolean resize) {\n            super(new BorderLayout());\n            add(content, BorderLayout.CENTER);\n            \n            setFocusCycleRoot(true);\n            setFocusTraversalPolicyProvider(true);\n            setFocusTraversalPolicy(new PopupFocusTraversalPolicy());\n            \n            if (UIUtils.isAquaLookAndFeel()) {\n                if (resize) {\n                    setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));\n                    addMouseListener(this);\n                    addMouseMotionListener(this);\n                }\n            } else {\n                Border border = BorderFactory.createLineBorder(UIUtils.getDisabledLineColor());\n                \n                if (resize) {\n                    setBorder(BorderFactory.createCompoundBorder(border,\n                              BorderFactory.createEmptyBorder(8, 8, 8, 8)));\n                    addMouseListener(this);\n                    addMouseMotionListener(this);\n                } else {\n                    setBorder(border);\n                }\n            }\n        }\n        \n        \n        // --- Resizing --------------------------------------------------------\n        \n        private boolean dragging;\n        private int currentResizing;\n        private int dragX, dragY = -1;\n        \n        public void mouseClicked(MouseEvent e) { }\n        \n        public void mousePressed(MouseEvent e) {\n            dragging = true;\n            dragX = e.getXOnScreen();\n            dragY = e.getYOnScreen();\n        }\n\n        public void mouseReleased(MouseEvent e) {\n            dragging = false;\n            dragX = -1;\n            dragY = -1;\n            updateResizing(e);\n        }\n\n        public void mouseEntered(MouseEvent e) {\n            if (!dragging) updateResizing(e);\n        }\n\n        public void mouseExited(MouseEvent e)  {\n            if (!dragging) {\n                currentResizing = RESIZE_NONE;\n                setCursor(Cursor.getDefaultCursor());\n            }\n        }\n        \n        public void mouseMoved(MouseEvent e) {\n            if (!dragging) updateResizing(e);\n        }\n        \n        public void mouseDragged(MouseEvent e) {\n            if (dragX >= 0 && dragY >= 0) {\n                int x = e.getXOnScreen();\n                int y = e.getYOnScreen();\n                \n                int dx = x - dragX;\n                int dy = y - dragY;\n                \n                int newX = window.getX();\n                int newY = window.getY();\n                int newW = window.getWidth();\n                int newH = window.getHeight();\n                \n                int xx = 0;\n                int yy = 0;\n                Dimension min = window.getMinimumSize();\n                \n                if (isResizeLeft(currentResizing)) {\n                    newX += dx;\n                    newW -= dx;\n                    if (newW < min.width) {\n                        xx = newW - min.width;\n                        newX += xx;\n                        newW = min.width;\n                    }\n                } else if (isResizeRight(currentResizing)) {\n                    newW += dx;\n                    if (newW < min.width) {\n                        xx = min.width - newW;\n                        newW = min.width;\n                    }\n                }\n                if (isResizeTop(currentResizing)) {\n                    newY += dy;\n                    newH -= dy;\n                    if (newH < min.height) {\n                        yy = newH - min.height;\n                        newY += yy;\n                        newH = min.height;\n                    }\n                } else if (isResizeBottom(currentResizing)) {\n                    newH += dy;\n                    if (newH < min.height) {\n                        yy = min.height - newH;\n                        newH = min.height;\n                    }\n                }\n                \n                window.setBounds(newX, newY, newW, newH);\n                content.setSize(newW, newH);\n                \n                dragX = x + xx;\n                dragY = y + yy;\n            }\n        }\n\n        private void updateResizing(MouseEvent e) {\n            int newResizing = RESIZE_NONE;\n            \n            int x = e.getX();\n            int y = e.getY();\n            \n            if (isResizeLeft(resizeMode) && x < 8 && x >= 0) {\n                newResizing |= RESIZE_LEFT;\n            } else if (isResizeRight(resizeMode) && x > getWidth() - RESIZE_STRIPE && x < getWidth()) {\n                newResizing |= RESIZE_RIGHT;\n            }\n            \n            if (isResizeTop(resizeMode)&& y < 8 && y >= 0) {\n                newResizing |= RESIZE_TOP;\n            } else if (isResizeBottom(resizeMode)&& y > getHeight() - RESIZE_STRIPE && y < getHeight()) {\n                newResizing |= RESIZE_BOTTOM;\n            }\n            \n            currentResizing = newResizing;\n            \n            switch (currentResizing) {\n                case RESIZE_NONE:\n                    setCursor(Cursor.getDefaultCursor());\n                    break;\n                case RESIZE_TOP:\n                    setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));\n                    break;\n                case RESIZE_LEFT:\n                    setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));\n                    break;\n                case RESIZE_BOTTOM:\n                    setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));\n                    break;\n                case RESIZE_RIGHT:\n                    setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));\n                    break;\n                case RESIZE_TOP | RESIZE_LEFT:\n                    setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));\n                    break;\n                case RESIZE_LEFT | RESIZE_BOTTOM:\n                    setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));\n                    break;\n                case RESIZE_BOTTOM | RESIZE_RIGHT:\n                    setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));\n                    break;\n                case RESIZE_RIGHT | RESIZE_TOP:\n                    setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));\n                    break;\n            }\n        }\n        \n        public void paint(Graphics g) {\n            super.paint(g);\n            \n            if (resizeMode > 0) {\n                g.setColor(UIUtils.getDisabledLineColor());\n                \n                switch (resizeMode) {\n                    case RESIZE_TOP | RESIZE_LEFT:\n                        g.drawLine(0, 5, 5, 0);\n                        g.drawLine(0, 9, 9, 0);\n                        break;\n                    case RESIZE_TOP | RESIZE_RIGHT:\n                        int w = getWidth();\n                        g.drawLine(w - 6, 0, w, 6);\n                        g.drawLine(w - 10, 0, w, 10);\n                        break;\n                    case RESIZE_BOTTOM | RESIZE_LEFT:\n                        int h = getHeight();\n                        g.drawLine(0, h - 6, 6, h);\n                        g.drawLine(0, h - 10, 10, h);\n                        break;\n                    default:\n                        w = getWidth();\n                        h = getHeight();\n                        g.drawLine(w, h - 7, w - 7, h);\n                        g.drawLine(w, h - 11, w - 11, h);\n                }\n            }\n        }\n        \n        boolean isResizeTop(int mode)    { return (mode & RESIZE_TOP) != 0; }\n        boolean isResizeLeft(int mode)   { return (mode & RESIZE_LEFT) != 0; }\n        boolean isResizeBottom(int mode) { return (mode & RESIZE_BOTTOM) != 0; }\n        boolean isResizeRight(int mode)  { return (mode & RESIZE_RIGHT) != 0; }\n        \n        \n        // --- Closing ---------------------------------------------------------\n        \n        void installListeners() {\n            window.addWindowFocusListener(this);\n            \n            if (owner != null) owner.addComponentListener(this);\n\n            KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this);\n        }\n        \n        void uninstallListeners() {\n            \n            window.removeWindowFocusListener(this);\n            \n            if (owner != null) owner.removeComponentListener(this);\n            \n            KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this);\n        }\n        \n        \n        // --- WindowFocusListener ---------------------------------------------\n        \n        public void windowGainedFocus(WindowEvent e) {\n            skippingEvents = false;\n            gainedFocusTime = System.currentTimeMillis();\n            if (DEBUG) System.err.println(\">>> Focus to popup gained\"); // NOI18N\n        }        \n\n        public void windowLostFocus(WindowEvent e) {\n            if (skippingEvents) return;\n            \n            if (e.getOppositeWindow() instanceof Dialog) {\n                final Dialog d = (Dialog)e.getOppositeWindow();\n                if (d != owner && d.isModal()) {\n                    // Do not close popup when a modal dialog is opened,\n                    // except of the owner\n                    skippingEvents = true;\n                    if (DEBUG) System.err.println(\">>> LOST TO DIALOG \" + getString(d) + \" owned by \" + getString(d.getOwner())); // NOI18N\n                    // NOTE: workaround for problem on macOS,\n                    //       closing the dialog opened from ProfilerPopup\n                    //       doesn't bring the focus back to the ProfilerPopup\n                    final Window win = window;\n                    final Component comp = window.getMostRecentFocusOwner();\n                    d.addWindowListener(new WindowAdapter() {\n                        public void windowClosed(WindowEvent e) {\n                            if (DEBUG) System.err.println(\">>> BLOCKING DIALOG CLOSED \" + getString(d)); // NOI18N\n                            win.requestFocus();\n                            if (comp != null) comp.requestFocus();\n                        }\n                    });\n                    return;\n                }\n            } else if (e.getOppositeWindow() == owner) {\n                // NOTE: workaround for bug on Linux,\n                //       closing the dialog opened from ProfilerPopup\n                //       sometimes also closes the ProfilerPopup,\n                //       passing the focus back to NB main window\n                long lostFocusTime = System.currentTimeMillis();\n                if (DEBUG) System.err.println(\">>> ### HIDDEN BY OWNER, gained focus before \" + (lostFocusTime - gainedFocusTime)); // NOI18N\n                if (lostFocusTime - gainedFocusTime < IGNORE_OWNER_TIMEOUT) {\n                    gainedFocusTime = 0;\n                    final Window win = window;\n                    final Component comp = window.getMostRecentFocusOwner();\n                    if (DEBUG) System.err.println(\">>>   Requesting focus again to \" + getString(comp)); // NOI18N\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            win.requestFocus();\n                            if (comp != null) comp.requestFocus();\n                            if (DEBUG) System.err.println(\">>>       REQUESTED lazily\"); // NOI18N\n                        }\n                    });\n                    return;\n                }\n            }\n            \n            ProfilerPopup.this.hide();\n            if (DEBUG) System.err.println(\">>> Focus to popup lost to \" + getString(e.getOppositeWindow()));\n        }\n        \n        private String getString(Component c) {\n            if (c instanceof Dialog) return \"[dialog] \" + ((Dialog)c).getTitle(); // NOI18N\n            else if (c instanceof Frame) return \"[frame] \" + ((Frame)c).getTitle(); // NOI18N\n            else return c == null ? \"null\" : c.getClass().getName(); // NOI18N\n        }\n        \n        \n        // --- ComponentListener -----------------------------------------------\n        \n        public void componentResized(ComponentEvent e) { if (DEBUG) System.err.println(\">>> Closed by componentResized\"); ProfilerPopup.this.hide(); }\n\n        public void componentMoved(ComponentEvent e)   {\n            Point newLocation = owner.getLocationOnScreen();\n            window.setLocation(window.getX() + (newLocation.x - ownerLocation.x),\n                               window.getY() + (newLocation.y - ownerLocation.y));\n            ownerLocation = newLocation;\n        }\n\n        public void componentShown(ComponentEvent e)   { }\n\n        public void componentHidden(ComponentEvent e)  { if (DEBUG) System.err.println(\">>> Closed by componentHidden\"); ProfilerPopup.this.hide(); }\n        \n        \n        // --- KeyEventDispatcher ----------------------------------------------\n        \n        public boolean dispatchKeyEvent(KeyEvent e) {\n            if (skippingEvents || e.isConsumed()) return false;\n            \n            if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == KeyEvent.VK_ESCAPE)\n                if (SwingUtilities.getRootPane(this) != e.getSource()) { // Closing JPopupMenu using the ESC key\n                    e.consume();\n                    if (DEBUG) System.err.println(\">>> Closed by ESC\"); // NOI18N\n                    ProfilerPopup.this.hide();\n                    return true;\n                }\n            \n            return false;\n        }\n        \n    }\n    \n    \n    private static class PopupFocusTraversalPolicy extends FocusTraversalPolicy {\n        \n        public Component getComponentAfter(Container aContainer, Component aComponent) {\n            List<Component> l = components(aContainer);\n            int i = l.indexOf(aComponent);\n            return i == -1 || i == l.size() - 1 ? null : l.get(i + 1);\n        }\n\n        public Component getComponentBefore(Container aContainer, Component aComponent) {\n            List<Component> l = components(aContainer);\n            int i = l.indexOf(aComponent);\n            return i == -1 || i == 0 ? null : l.get(i - 1);\n        }\n\n        public Component getFirstComponent(Container aContainer) {\n            List<Component> l = components(aContainer);\n            return l.isEmpty() ? null : l.get(0);\n        }\n\n        public Component getLastComponent(Container aContainer) {\n            List<Component> l = components(aContainer);\n            return l.isEmpty() ? null : l.get(l.size() - 1);\n        }\n\n        public Component getDefaultComponent(Container aContainer) {\n            Component c = getFirstComponent(aContainer);\n            \n            if (c instanceof AbstractButton) {\n                ButtonModel bm = ((AbstractButton)c).getModel();\n                if (bm instanceof DefaultButtonModel) {\n                    ButtonGroup bg = ((DefaultButtonModel)bm).getGroup();\n                    Enumeration<AbstractButton> en = bg == null ? null : bg.getElements();\n                    while (en != null && en.hasMoreElements()) {\n                        AbstractButton ab = en.nextElement();\n                        if (ab.isSelected()) return ab;\n                    }\n                }\n            }\n            \n            return c;\n        }\n\n        private static List<Component> components(Container aContainer) {\n            List<Component> l = new ArrayList<>();\n\n            for (int i = 0; i < aContainer.getComponentCount(); i++) {\n                Component c = aContainer.getComponent(i);\n                if (c instanceof JPanel || c instanceof JToolBar)\n                    l.addAll(components((Container)c));\n                else if (c instanceof JScrollPane)\n                    l.addAll(components(((JScrollPane)c).getViewport()));\n//                else if (c instanceof JRootPane)\n//                    l.addAll(components((Container)((JRootPane)c).getContentPane()));\n                else if (focusable(c)) l.add(c);\n            }\n\n            return l;\n        }\n        \n        private static boolean focusable(Component c) {\n            if (c instanceof JLabel || c instanceof Box.Filler) return false;\n            return c.isVisible() && c.isEnabled() && c.isFocusable();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/ProfilerPopupMenu.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Component;\nimport java.awt.Graphics;\nimport javax.swing.JComponent;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPopupMenu;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n * JPopupMenu which supports custom background color.\n *\n * @author Jiri Sedlacek\n */\npublic class ProfilerPopupMenu extends JPopupMenu {\n\n    private boolean forceBackground;\n\n\n    public ProfilerPopupMenu() {\n        super();\n    }\n\n    public ProfilerPopupMenu(String label) {\n        super(label);\n    }\n\n\n    // --- Tweaking UI ---------------------------------------------------------\n\n    public JMenuItem add(JMenuItem menuItem) {\n        if (forceBackground && !UIUtils.isOracleLookAndFeel()) menuItem.setOpaque(false);\n        if (forceBackground && !UIUtils.isNimbusLookAndFeel()) menuItem.setForeground(getForeground());\n        return super.add(menuItem);\n    }\n\n    public void add(Component comp, Object constraints) {\n        if (forceBackground && !UIUtils.isOracleLookAndFeel() && comp instanceof JComponent)\n            ((JComponent)comp).setOpaque(false);\n        if (forceBackground && !UIUtils.isNimbusLookAndFeel()) comp.setForeground(getForeground());\n        comp.setMinimumSize(comp.getPreferredSize());\n        super.add(comp, constraints);\n    }\n\n\n    public void setForceBackground(boolean force) {\n        if (!UIUtils.isNimbus() || !Boolean.TRUE.equals(UIManager.getBoolean(\"nb.dark.theme\"))) // NOI18N\n            this.forceBackground = force;\n    }\n\n    protected void paintComponent(Graphics g) {\n        super.paintComponent(g);\n\n        if (forceBackground) {\n            g.setColor(getBackground());\n            g.fillRect(1, 1, getWidth() - 2, getHeight() - 2);\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/ProfilerRowSorter.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Properties;\nimport javax.swing.RowFilter;\nimport javax.swing.RowSorter;\nimport javax.swing.SortOrder;\nimport javax.swing.table.TableModel;\nimport javax.swing.table.TableRowSorter;\n\n/**\n * TableRowSorter for single-column sorting with default SortOrders for each column.\n *\n * @author Jiri Sedlacek\n */\nclass ProfilerRowSorter extends TableRowSorter {\n\n    // --- Package-private constructor -----------------------------------------\n\n    ProfilerRowSorter(TableModel model) {\n        super(model);\n    }\n\n    // --- Sorting support -----------------------------------------------------\n\n    private SortOrder defaultSortOrder = SortOrder.ASCENDING;\n    private Map<Integer, SortOrder> defaultSortOrders;\n\n    private int secondarySortColumn = -1;\n\n    private boolean threeStateColumns;\n\n    public void setAllowsThreeStateColumns(boolean threeStateColumns) {\n        this.threeStateColumns = threeStateColumns;\n    }\n\n    public boolean allowsThreeStateColumns() {\n        return threeStateColumns;\n    }\n\n    public void toggleSortOrder(int column) {\n        // UNSORTED not allowed for sorting columns (default)\n        if (!allowsThreeStateColumns()) {\n            super.toggleSortOrder(column);\n            return;\n        }\n\n        // Switching from one column to another\n        if (getSortColumn() != column) {\n            super.toggleSortOrder(column);\n            return;\n        }\n\n        // Toggling from default sort order\n        SortOrder so = getSortOrder();\n        if (Objects.equals(getDefaultSortOrder(column), so)) {\n            super.toggleSortOrder(column);\n            return;\n        }\n        \n        // Resetting UNSORTED, use default sort order\n        if (Objects.equals(SortOrder.UNSORTED, so)) {\n            setSortColumn(column);\n            return;\n        }\n        \n        // Toggling from second sort order, switch to UNSORTED\n        setSortColumn(column, SortOrder.UNSORTED);\n    }\n    \n    public void setSortKeys(List newKeys) {\n        if (newKeys == null || newKeys.isEmpty()) {\n            setSortKeysImpl(newKeys);\n            return;\n        }\n        \n        RowSorter.SortKey oldKey = getSortKey();\n        RowSorter.SortKey newKey = (RowSorter.SortKey)newKeys.get(0);\n        \n        if (oldKey == null || oldKey.getColumn() != newKey.getColumn()) {\n            // Use defined initial SortOrder for a newly sorted column\n            setSortColumn(newKey.getColumn());\n        } else {\n            setSortKeysImpl(newKeys);\n        }\n    }\n    \n    protected void setSortKeysImpl(List newKeys) {\n        super.setSortKeys(newKeys);\n    }\n    \n    void setSortColumn(int column) {\n        setSortColumn(column, getDefaultSortOrder(column));\n    }\n    \n    void setSortColumn(int column, SortOrder order) {\n        setSortKey(new RowSorter.SortKey(column, order));\n    }\n    \n    void setSortKey(RowSorter.SortKey key) {\n        RowSorter.SortKey secondaryKey = secondarySortColumn == -1 ||\n                          secondarySortColumn == key.getColumn() ? null :\n                          new RowSorter.SortKey(secondarySortColumn,\n                          getDefaultSortOrder(secondarySortColumn));\n        setSortKeysImpl(secondaryKey == null ? Arrays.asList(key) :\n                          Arrays.asList(key, secondaryKey));\n    }\n    \n    int getSortColumn() {\n        RowSorter.SortKey key = getSortKey();\n        return key == null ? -1 : key.getColumn();\n    }\n    \n    SortOrder getSortOrder() {\n        RowSorter.SortKey key = getSortKey();\n        return key == null ? SortOrder.UNSORTED : key.getSortOrder();\n    }\n    \n    RowSorter.SortKey getSortKey() {\n        List<? extends RowSorter.SortKey> keys = getSortKeys();\n        return keys == null || keys.isEmpty() ? null : keys.get(0);\n    }\n    \n    \n    void setSecondarySortColumn(int column) {\n        secondarySortColumn = column;\n    }\n    \n    int getSecondarySortColumn() {\n        return secondarySortColumn;\n    }\n    \n    \n    void setDefaultSortOrder(SortOrder sortOrder) {\n        defaultSortOrder = sortOrder;\n    }\n    \n    void setDefaultSortOrder(int column, SortOrder sortOrder) {\n        if (defaultSortOrders == null) defaultSortOrders = new HashMap();\n        defaultSortOrders.put(column, sortOrder);\n    }\n    \n    SortOrder getDefaultSortOrder(int column) {\n        SortOrder order = defaultSortOrders == null ? null :\n                          defaultSortOrders.get(column);\n        return order == null ? defaultSortOrder : order;\n    }\n    \n    \n    // --- Filtering support ---------------------------------------------------\n    \n    private boolean filterMode = true; // AND filter by default\n    private Collection<RowFilter<Object, Object>> filters;\n    \n    // false = OR, true = AND\n    void setFiltersMode(boolean mode) {\n        this.filterMode = mode;\n        if (filters != null) refreshRowFilter();\n    }\n    \n    boolean getFiltersMode() {\n        return filterMode;\n    }\n    \n    void addRowFilter(RowFilter filter) {\n        if (filters == null) filters = new HashSet();\n        if (filters.contains(filter)) filters.remove(filter);\n        filters.add(filter);\n        refreshRowFilter();\n    }\n    \n    void removeRowFilter(RowFilter filter) {\n        if (filters == null) return;\n        filters.remove(filter);\n        refreshRowFilter();\n    }\n    \n    private void refreshRowFilter() {\n        if (filters == null || filters.isEmpty()) {\n            setRowFilter(null);\n        } else if (filters.size() == 1) {\n            setRowFilter(filters.iterator().next());\n        } else {\n            setRowFilter(filterMode ? RowFilter.andFilter(filters) :\n                                      RowFilter.orFilter(filters));\n        }\n    }\n    \n    // --- Persistence ---------------------------------------------------------\n    \n    private static final String SORT_COLUMN_KEY = \"ProfilerRowSorter.SortColumn\"; // NOI18N\n    private static final String SORT_ORDER_KEY = \"ProfilerRowSorter.SortOrder\"; // NOI18N\n    \n    void loadFromStorage(Properties properties, ProfilerTable table) {\n        String columnS = properties.getProperty(SORT_COLUMN_KEY);\n        String orderS = properties.getProperty(SORT_ORDER_KEY);\n        if (columnS != null) {\n            try {\n                int column = Integer.parseInt(columnS);\n                SortOrder order = getSortOrder(orderS);\n//                if (SortOrder.UNSORTED.equals(order)) order = getDefaultSortOrder(column);\n                setSortColumn(column, order);\n            } catch (NumberFormatException e) {\n                // Reset sorting? Set default column?\n            }\n        } else {\n            // Reset sorting? Set default column?\n        }\n    }\n    \n    void saveToStorage(Properties properties, ProfilerTable table) {\n        RowSorter.SortKey key = getSortKey();\n        if (key == null) {\n            properties.remove(SORT_COLUMN_KEY);\n            properties.remove(SORT_ORDER_KEY);\n        } else {\n            int column = key.getColumn();\n            SortOrder order = key.getSortOrder();\n            properties.setProperty(SORT_COLUMN_KEY, Integer.toString(column));\n            properties.setProperty(SORT_ORDER_KEY, order.toString());\n        }\n    }\n    \n    private SortOrder getSortOrder(String sortOrder) {\n        if (SortOrder.ASCENDING.toString().equals(sortOrder)) return SortOrder.ASCENDING;\n        else if (SortOrder.DESCENDING.toString().equals(sortOrder)) return SortOrder.DESCENDING;\n        else return SortOrder.UNSORTED;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/ProfilerTable.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.Toolkit;\nimport java.awt.datatransfer.StringSelection;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.AdjustmentEvent;\nimport java.awt.event.AdjustmentListener;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.FocusListener;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseEvent;\nimport java.text.MessageFormat;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Properties;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport javax.accessibility.AccessibleContext;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.DefaultListSelectionModel;\nimport javax.swing.Icon;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTable;\nimport javax.swing.JViewport;\nimport javax.swing.KeyStroke;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.RowFilter;\nimport javax.swing.RowSorter;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.event.RowSorterEvent;\nimport javax.swing.event.RowSorterListener;\nimport javax.swing.event.TableModelEvent;\nimport javax.swing.event.TableModelListener;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.table.TableCellEditor;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumn;\nimport javax.swing.table.TableColumnModel;\nimport javax.swing.table.TableModel;\nimport javax.swing.table.TableRowSorter;\nimport javax.swing.table.TableStringConverter;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.Movable;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ProfilerTable extends JTable {\n    \n    private static ResourceBundle BUNDLE() {\n        return ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.swing.Bundle\"); // NOI18N\n    }\n    \n    public static final String PROP_NO_HOVER = \"ProfilerTableHover_NoHover\"; // NOI18N\n    \n    public ProfilerTable(TableModel model, boolean sortable,\n                         boolean hideableColumns, int[] scrollableColumns) {\n        super(model);\n        \n        this.hideableColums = hideableColumns;\n        \n        setupModels(sortable);\n        setupAppearance();\n        \n        if (scrollableColumns != null && scrollableColumns.length > 0)\n            initScrollableColumns(scrollableColumns);\n        \n        tweak();\n    }\n    \n    \n    // --- Initialization ------------------------------------------------------\n    \n    protected void setupModels(boolean sortable) {\n        setAutoCreateRowSorter(false);\n        if (sortable) setRowSorter(createRowSorter());\n    }\n    \n    public void createDefaultColumnsFromModel() {\n        TableModel m = getModel();\n        if (m != null) {\n            // Remove any current columns\n            ProfilerColumnModel cm = _getColumnModel();\n            while (cm.getColumnCount() > 0)\n                cm.removeColumn(cm.getColumn(0));\n\n            // Create new columns from the data model info\n            for (int i = 0; i < m.getColumnCount(); i++)\n                addColumn(cm.createTableColumn(i));\n        }\n    }\n    \n    // --- UI tweaks -----------------------------------------------------------\n    \n    private void tweak() {\n        for (Tweaker tweaker : Lookup.getDefault().lookupAll(Tweaker.class))\n            tweaker.tweak(this);\n    }\n    \n    protected void setupAppearance() {\n        setAutoResizeMode(AUTO_RESIZE_NEXT_COLUMN);\n        setRowSelectionAllowed(true);\n        setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        setGridColor(UIConstants.TABLE_VERTICAL_GRID_COLOR);\n        setShowHorizontalLines(UIConstants.SHOW_TABLE_HORIZONTAL_GRID);\n        setShowVerticalLines(UIConstants.SHOW_TABLE_VERTICAL_GRID);\n        setRowMargin(UIConstants.TABLE_ROW_MARGIN);\n        setRowHeight(UIUtils.getDefaultRowHeight() + 2);\n        setBackground(UIUtils.getProfilerResultsBackground());\n        \n        if (UIUtils.isNimbusLookAndFeel() && Boolean.TRUE.equals(UIManager.getBoolean(\"nb.dark.theme\"))) // NOI18N\n            setForeground(UIManager.getColor(\"text\")); // NOI18N\n        \n        ProfilerTableActions.install(this);\n//        ProfilerTableHover.install(this);\n        ProfilerTableHovers.install(this);\n        \n        getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(\n                KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), \"DEFAULT_ACTION\"); // NOI18N\n        getActionMap().put(\"DEFAULT_ACTION\", new AbstractAction() { // NOI18N\n                    public void actionPerformed(ActionEvent e) { performDefaultAction(e); }\n                });\n        \n        addFocusListener(new FocusListener() {\n            public void focusGained(FocusEvent e) { ProfilerTable.this.focusGained(); }\n            public void focusLost(FocusEvent e)   { ProfilerTable.this.focusLost(); }\n        });\n    }\n    \n    public Color getBackground() {\n        return isEnabled() ? super.getBackground() :\n               UIManager.getColor(\"TextField.inactiveBackground\"); // NOI18N\n    }\n    \n    private void focusGained() {\n        repaint();\n    }\n    \n    private void focusLost() {\n        repaint();\n    }\n    \n    public void setDefaultRenderer(Class<?> columnClass, ProfilerRenderer renderer) {\n        super.setDefaultRenderer(columnClass, createTableCellRenderer(renderer));\n    }\n    \n    public void setColumnRenderer(int column, ProfilerRenderer renderer) {\n        int _column = convertColumnIndexToModel(column);\n        TableColumn tColumn = getColumnModel().getColumn(_column);\n        tColumn.setCellRenderer(createTableCellRenderer(renderer));\n    }\n    \n    public static TableCellRenderer createTableCellRenderer(ProfilerRenderer renderer) {\n        return new ProfilerRendererWrapper(renderer);\n    }\n    \n    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {\n        Component c = super.prepareRenderer(renderer, row, column);\n        \n        boolean cEnabled = c.isEnabled();\n        if (!cEnabled) c.setForeground(UIManager.getColor(\"TextField.inactiveForeground\")); // NOI18N\n        \n        boolean isSelected = isCellSelected(row, column);\n        \n        if (isSelected && isEnabled()) {\n            boolean focusOwner = !shadeUnfocusedSelection || super.isFocusOwner();\n            if (cEnabled) c.setForeground(focusOwner ? getSelectionForeground() : UIUtils.getUnfocusedSelectionForeground());\n            c.setBackground(focusOwner ? getSelectionBackground() : UIUtils.getUnfocusedSelectionBackground());\n        } else if (!isEnabled()) {\n            if (cEnabled) c.setForeground(UIManager.getColor(\"TextField.inactiveForeground\")); // NOI18N\n            c.setBackground(UIManager.getColor(\"TextField.inactiveBackground\")); // NOI18N\n        } else {\n            if (cEnabled) c.setForeground(getForeground());\n            c.setBackground(background(row, column));\n        }\n        \n        c.move(0, 0);\n        \n        int col = convertColumnIndexToModel(column);        \n        if (!isCustomRendering() && isScrollableColumn(col)) {\n            int prefWidth = getColumnPreferredWidth(col);\n            return getScrollableRenderer(c, col, prefWidth);\n        } else {\n            return c;\n        }\n    }\n    \n    private Color background(int row, int column) {\n        Color background = (row & 0x1) == 0 ? getBackground() : UIUtils.getDarker(getBackground());\n//        if (convertColumnIndexToModel(column) == getSortColumn()) return UIUtils.getDarker(background);\n        if (convertColumnIndexToModel(column) == getSortColumn() && !SortOrder.UNSORTED.equals(_getRowSorter().getSortOrder())) {\n            int r = background.getRed() - 4;\n            int g = background.getGreen() - 4;\n            int b = background.getBlue() + 6;\n            background = UIUtils.getSafeColor(r, g, b);\n        }\n        return background;\n    }\n    \n    public Component prepareEditor(TableCellEditor editor, int row, int column) {\n        Component c = super.prepareEditor(editor, row, column);\n        \n        c.setForeground(getSelectionForeground());\n        c.setBackground(getSelectionBackground());\n        \n        return c;\n    }\n    \n    private static class ProfilerRendererWrapper implements TableCellRenderer, ProfilerRenderer {\n        \n        private final ProfilerRenderer renderer;\n        \n        ProfilerRendererWrapper(ProfilerRenderer renderer) { this.renderer = renderer; }\n        \n        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {\n            setValue(value, row != -1 ? table.convertRowIndexToModel(row) : -1);\n            return getComponent();\n        }\n        \n        public void setValue(Object value, int row) { renderer.setValue(value, row); }\n    \n        public int getHorizontalAlignment() { return renderer.getHorizontalAlignment(); }\n\n        public JComponent getComponent() { return renderer.getComponent(); }\n        \n        public void move(int x, int y) { renderer.move(x, y); }\n        \n        public String toString() { return renderer.toString(); }\n\n        public AccessibleContext getAccessibleContext() { return renderer.getAccessibleContext(); }\n        \n    }\n    \n    private ScrollableRenderer _renderer;\n    private ScrollableRenderer getScrollableRenderer(Component renderer, int column, int width) {\n        if (_renderer == null) _renderer = new ScrollableRenderer();\n        _renderer.setRenderer(renderer, getColumnOffset(column), width);\n        return _renderer;\n    }\n    \n    private class ScrollableRenderer extends Component {\n        \n        private Component impl;\n        private Movable implM;\n        \n        private int offset;\n        private int prefWidth;\n        private int marginOffset;\n        \n        void setRenderer(Component c, int o, int w) {\n            impl = c;\n            offset = o;\n            prefWidth = w;\n            \n            marginOffset = isLeadingAlign(impl) ? 0 : \n                           getColumnModel().getColumnMargin();\n            \n            implM = c instanceof Movable ? (Movable)c : null;\n        }\n        \n        public void setBounds(int x, int y, int w, int h) {\n            super.setBounds(x, y, w, h);\n            if (prefWidth > w) offset += marginOffset;\n            impl.setSize(Math.max(w, prefWidth), h);\n        }\n        \n        public Dimension getPreferredSize() {\n            return impl.getPreferredSize();\n        }\n        \n        public void paint(Graphics g) {\n            if (implM != null) {\n                implM.move(-offset, 0);\n                impl.paint(g);\n            } else {\n                g.translate(-offset, 0);\n                impl.paint(g);\n            }\n        }\n        \n    }\n    \n    Component getRenderer(TableCellRenderer renderer, int row, int column, boolean sized) {\n        isCustomRendering = true;\n        try {\n            Component comp = prepareRenderer(renderer, row, column);\n//            comp.setSize(comp.getPreferredSize().width, getRowHeight());\n            if (sized) {\n                comp.setSize(comp.getPreferredSize().width, getRowHeight());\n                if (!isLeadingAlign(comp)) {\n                    TableColumnModel m = getColumnModel();\n                    int x = -comp.getWidth();\n                    int c = m.getColumn(column).getWidth();\n                    int _column = convertColumnIndexToModel(column);\n                    if (isScrollableColumn(_column)) {\n                        x += Math.max(c, getColumnPreferredWidth(_column));\n                    } else {\n                        x += c;\n                    }\n                    comp.move(x - m.getColumnMargin(), 0);\n                }\n            }\n            \n            return comp;\n        } finally {\n            isCustomRendering = false;\n        }\n    }\n    \n    public boolean isFocusOwner() {\n        return !isCustomRendering() && super.isFocusOwner();\n    }\n    \n    public void setVisibleRows(int rows) {\n        Dimension size = super.getPreferredScrollableViewportSize();\n        size.height = rows * getRowHeight();\n        setPreferredScrollableViewportSize(size);\n    }\n    \n    private boolean isCustomRendering;\n    \n    final boolean isCustomRendering() {\n        return isCustomRendering;\n    }\n    \n    // --- String value --------------------------------------------------------\n    \n    // row, column - view index\n    public String getStringValue(int row, int column) {\n        Object value = getValueAt(row, column);\n        TableCellRenderer renderer = getCellRenderer(row, column);\n        if (renderer instanceof ProfilerRenderer) {\n            ((ProfilerRenderer)renderer).setValue(value, convertRowIndexToModel(row));\n        } else {\n            renderer.getTableCellRendererComponent(this, value, false, false, row, column);\n        }\n        return renderer.toString();\n    }\n    \n    // row, column - model index\n    public String getModelStringValue(int row, int column) {\n        int c = convertColumnIndexToView(column);\n        Object value = getModel().getValueAt(row, column);\n        TableCellRenderer renderer = getCellRenderer(row, c);\n        if (renderer instanceof ProfilerRenderer) {\n            ((ProfilerRenderer)renderer).setValue(value, row);\n        } else {\n            renderer.getTableCellRendererComponent(this, value, false, false,\n                                                   convertRowIndexToView(row), c);\n        }\n        return renderer.toString();\n    }\n    \n    // --- Main column ---------------------------------------------------------\n    \n    private int mainColumn = 0;\n    \n    public final void setMainColumn(int column) {\n        mainColumn = column;\n    }\n    \n    public final int getMainColumn() {\n        return mainColumn;\n    }\n    \n    // --- Selection -----------------------------------------------------------\n    \n    private boolean shadeUnfocusedSelection = false;\n    private boolean selectionOnMiddlePress = false;\n    \n    boolean internal;\n    private Object selection;\n    private int fixedSelectionColumn = -1;\n    private ListSelectionListener selectionListener;\n    \n    public void setSelectionModel(ListSelectionModel newModel) {\n        ListSelectionModel oldModel = getSelectionModel();\n        if (oldModel != null && selectionListener != null)\n            oldModel.removeListSelectionListener(selectionListener);\n        \n        super.setSelectionModel(newModel);\n        \n        if (newModel != null) {\n            if (selectionListener == null) selectionListener = new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent e) { if (!internal) saveSelection(); }\n            };\n            newModel.addListSelectionListener(selectionListener);\n        }\n    }\n    \n    protected void saveSelection() {\n        int sel = getSelectionModel().getSelectionMode();\n        selection = sel == ListSelectionModel.SINGLE_SELECTION ?\n                getSelectedValue(mainColumn) : getSelectedValues(mainColumn).toArray();\n    }\n    \n    protected void restoreSelection() {\n        try {\n            if (!(selection instanceof Object[])) selection = selectValue(selection, mainColumn, false);\n            else selection = selectValues((Object[])selection, mainColumn, false);\n        } catch (Exception e) {\n            System.err.println(\">>> Exception in ProfilerTable.restoreSelection: \" + e.getMessage());\n            e.printStackTrace();\n        }\n    }\n    \n    public void selectRow(int row, boolean scrollToVisible) {\n        internal = true;\n        try { setRowSelectionInterval(row, row); saveSelection(); }\n        catch (Exception e) {\n            System.err.println(\">>> Exception in ProfilerTable.selectRow: \" + e.getMessage());\n            e.printStackTrace();\n        }\n        finally { internal = false; }\n        if (scrollToVisible) scrollRectToVisible(getCellRect(row, getSelectedColumn(), true));\n    }\n    \n    public void selectColumn(int column, boolean scrollToVisible) {\n        internal = true;\n        try { setColumnSelectionInterval(column, column); }\n        catch (Exception e) {\n            System.err.println(\">>> Exception in ProfilerTable.selectColumn: \" + e.getMessage());\n            e.printStackTrace();\n        }\n        finally { internal = false; }\n        if (scrollToVisible) scrollRectToVisible(getCellRect(getSelectedRow(), column, true));\n    }\n    \n    public void setFixedColumnSelection(final int column) {\n        if (fixedSelectionColumn == column) return;\n        \n        if (column == -1) {\n            getColumnModel().setSelectionModel(new DefaultListSelectionModel());\n        } else {\n            getColumnModel().setSelectionModel(new DefaultListSelectionModel() {\n                public void setSelectionInterval(int index0, int index1) {\n                    int index = convertColumnIndexToView(column);\n                    super.setSelectionInterval(index, index);\n                }\n            });\n        }\n        \n        fixedSelectionColumn = column;\n    }\n    \n    public Object selectValue(Object value, int column, boolean scrollToVisible) {\n        if (value == null) return null;\n        \n        int _column = convertColumnIndexToView(column);\n        for (int row = 0; row < getRowCount(); row++) {\n            Object _value = getValueAt(row, _column);\n            if (value.equals(_value)) {\n                selectRow(row, scrollToVisible);\n                return _value;\n            }\n        }\n        \n        return null;\n    }\n    \n    private Object[] selectValues(Object[] values, int column, boolean scrollToVisible) {\n        if (values == null || values.length == 0) return null;\n        \n        Set<Object> toSelect = new HashSet<>(Arrays.asList(values));\n        List<Object> selected = new ArrayList<>(toSelect.size());\n        \n        internal = true;\n        try {\n            int _column = convertColumnIndexToView(column);\n            for (int row = 0; row < getRowCount(); row++) {\n                Object _value = getValueAt(row, _column);\n                if (toSelect.remove(_value)) {\n                    if (selected.isEmpty()) {\n                        setRowSelectionInterval(row, row);\n                        if (scrollToVisible)\n                            scrollRectToVisible(getCellRect(row, _column, true));\n                    } else {\n                        addRowSelectionInterval(row, row);\n                    }\n                    selected.add(_value);\n                    if (toSelect.isEmpty()) break;\n                }\n            }\n        } finally { internal = false; }\n        \n        return selected.isEmpty() ? null : selected.toArray();\n    }\n    \n    public Object getSelectedValue(int column) {\n        int row = getSelectedRow();\n        if (row == -1) return null;\n        if (row >= getModel().getRowCount()) return null; // #239936\n        return getValueAt(row, convertColumnIndexToView(column));\n    }\n    \n    public List getSelectedValues(int column) {\n        List values = new ArrayList();\n        int col = convertColumnIndexToView(column);\n        int rowCount = getModel().getRowCount();\n        for (int row : getSelectedRows())\n            if (row < rowCount) // #239936\n                values.add(getValueAt(row, col));\n        return values;\n    }\n    \n    public void tableChanged(TableModelEvent e) {\n        internal = true;\n        try { super.tableChanged(e); }\n        finally { internal = false; }\n        restoreSelection();\n    }\n    \n    public final void setShadeUnfocusedSelection(boolean shade) {\n        shadeUnfocusedSelection = shade;\n    }\n    \n    public final boolean shadesUnfocusedSelection() {\n        return shadeUnfocusedSelection;\n    }\n    \n    public final void setSelectionOnMiddlePress(boolean select) {\n        selectionOnMiddlePress = select;\n    }\n    \n    public final boolean isSelectionOnMiddlePress() {\n        return selectionOnMiddlePress;\n    }\n    \n    // --- Traversing rows -----------------------------------------------------\n    \n    int getNextRow(int row) {\n        return ++row == getRowCount() ? 0 : row;\n    }\n    \n    int getPreviousRow(int row) {\n        return --row == -1 ? getRowCount() - 1 : row;\n    }\n    \n    // --- Column model --------------------------------------------------------\n    \n    private boolean columnWidthsValid;\n    private Set<Integer> scrollableColumns;\n    \n    ProfilerColumnModel _getColumnModel() {\n        return (ProfilerColumnModel)getColumnModel();\n    }\n    \n    protected TableColumnModel createDefaultColumnModel() {\n        return new ProfilerColumnModel();\n    }\n    \n    public void setFitWidthColumn(int column) {\n        _getColumnModel().setFitWidthColumn(column);\n    }\n    \n    public void setDefaultColumnWidth(int width) {\n        _getColumnModel().setDefaultColumnWidth(width);\n    }\n    \n    public void setDefaultColumnWidth(int column, int width) {\n        _getColumnModel().setDefaultColumnWidth(column, width);\n    }\n    \n    public void setColumnToolTips(String[] toolTips) {\n        _getColumnModel().setColumnToolTips(toolTips);\n    }\n    \n    public void setColumnVisibility(int column, boolean visible) {\n        _getColumnModel().setColumnVisibility(column, visible, this);\n    }\n    \n    public boolean isColumnVisible(int column) {\n        return _getColumnModel().isColumnVisible(column);\n    }\n    \n    public void setColumnOffset(int column, int offset) {\n        if (_getColumnModel().setColumnOffset(column, offset)) {\n            column = convertColumnIndexToView(column);\n            Rectangle rect = getCellRect(0, column, true);\n            repaint(rect.x, 0, rect.width, getHeight());\n        }\n    }\n    \n    public Set<Integer> getScrollableColumns() {\n        return scrollableColumns;\n    }\n    \n    public boolean isScrollableColumn(int column) {\n        return scrollableColumns != null && scrollableColumns.contains(column);\n    }\n    \n    public int getColumnOffset(int column) {\n        return _getColumnModel().getColumnOffset(column);\n    }\n    \n    protected void updateColumnsPreferredWidth() {\n        if (scrolling || scrollableColumns == null) return;\n        \n        ProfilerColumnModel cModel = _getColumnModel();\n        \n        int rowCount = getRowCount();\n        if (rowCount == 0) {\n            for (int column : scrollableColumns)\n                cModel.setColumnPreferredWidth(column, 0);\n            return;\n        }\n        \n        Rectangle visible = getVisibleRect();\n        if (visible.isEmpty()) return;\n        \n        Point visibleP = visible.getLocation();\n        int first = rowAtPoint(visibleP);\n        visibleP.translate(0, visible.height - 1);\n        int last = rowAtPoint(visibleP);\n        \n        if (last == -1) last = rowCount - 1; // last column above the visible rect boundary\n        \n        for (int column : scrollableColumns) {\n            int _column = convertColumnIndexToView(column);\n            int width = computeColumnPreferredWidth(column, _column, first, last);\n            cModel.setColumnPreferredWidth(column, width);\n        }\n        \n        columnWidthsValid = true;\n    }\n    \n    public void updateColumnPreferredWidth(int column) {\n        Rectangle visible = getVisibleRect();\n        if (visible.isEmpty()) return;\n        \n        Point visibleP = visible.getLocation();\n        int first = rowAtPoint(visible.getLocation());\n        visibleP.translate(0, visible.height - 1);\n        int last = rowAtPoint(visibleP);\n        \n        int _column = convertColumnIndexToView(column);\n        \n        int width = computeColumnPreferredWidth(column, _column, first, last);\n        _getColumnModel().setColumnPreferredWidth(column, width);\n    }\n    \n    protected int computeColumnPreferredWidth(int modelIndex, int viewIndex, int firstRow, int lastRow) {\n        int width = 0;\n        for (int row = firstRow; row <= lastRow; row++) {\n            TableCellRenderer renderer = getCellRenderer(row, viewIndex);\n            Component component = getRenderer(renderer, row, viewIndex, false);\n            width = Math.max(component.getPreferredSize().width, width);\n        }\n        return width;\n    }\n    \n    public int getColumnPreferredWidth(int column) {\n        if (!columnWidthsValid) updateColumnsPreferredWidth();\n        return _getColumnModel().getColumnPreferredWidth(column);\n    }\n    \n    private void initScrollableColumns(int[] columns) {\n        scrollableColumns = new HashSet<>(columns.length);\n        for (final int column : columns) scrollableColumns.add(column);\n        \n        columnWidthsValid = false;\n        \n        if (isSortable()) {\n            getRowSorter().addRowSorterListener(new RowSorterListener() {\n                public void sorterChanged(RowSorterEvent e) {\n                    if (RowSorterEvent.Type.SORTED.equals(e.getType()))\n                        updateColumnsPreferredWidth();\n                }\n            });\n        } else {\n            getModel().addTableModelListener(new TableModelListener() {\n                public void tableChanged(TableModelEvent e) {\n//                    // Must invoke later, JTree.getRowCount() not ready yet\n//                    SwingUtilities.invokeLater(new Runnable() {\n//                        public void run() { updateColumnsPreferredWidth(); }\n//                    });\n                    updateColumnsPreferredWidth();\n                }\n            }); \n        }\n    }\n    \n    boolean isLeadingAlign(int column) {\n        if (getRowCount() == 0) return true;\n        int _column = convertColumnIndexToView(column);\n        TableCellRenderer r = getCellRenderer(0, _column);\n        return isLeadingAlign(getRenderer(r, 0, _column, false));\n    }\n    \n    static boolean isLeadingAlign(Component component) {\n        int alignment;\n        \n        if (component instanceof ProfilerRenderer) {\n            alignment = ((ProfilerRenderer)component).getHorizontalAlignment();\n        } else if (component instanceof JLabel) {\n            alignment = ((JLabel)component).getHorizontalAlignment();\n        } else {\n            alignment = SwingConstants.LEADING;\n        }\n        \n        return alignment == SwingConstants.LEADING ||\n               alignment == SwingConstants.LEFT ||\n               alignment == SwingConstants.CENTER;\n    }\n    \n    \n    // --- Columns hiding & layout ---------------------------------------------\n    \n    private final boolean hideableColums;\n    private boolean scrolling;\n    \n    protected void configureEnclosingScrollPane() {\n        super.configureEnclosingScrollPane();\n\n        JScrollPane scrollPane = getEnclosingScrollPane();\n        if (scrollPane != null) {\n            boolean hideable = hideableColums && !UIUtils.isAquaLookAndFeel();\n            final ActionListener chooser = !hideable ? null : new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    chooseColumns((Component)e.getSource(), null);\n                }\n            };\n            HeaderComponent corner = !hideable ? new HeaderComponent(chooser) :\n                                                 new HeaderComponent(chooser) {\n                private final int offsetX = UIUtils.isWindowsClassicLookAndFeel() ? 0 : -1;\n                private final Icon icon = Icons.getIcon(GeneralIcons.POPUP_ARROW);\n                protected void paintComponent(Graphics g) {\n                    super.paintComponent(g);\n                    int x = (getWidth() - icon.getIconWidth()) / 2 + offsetX;\n                    int y = (getHeight() - icon.getIconHeight()) / 2;\n                    icon.paintIcon(this, g, x, y);\n                }\n            };\n            if (hideable) corner.setToolTipText(BUNDLE().getString(\"ProfilerTable_ShowHideColumns\")); // NOI18N\n            scrollPane.setCorner(JScrollPane.UPPER_RIGHT_CORNER, corner);\n            \n            if (scrollableColumns != null && !scrollableColumns.isEmpty())\n                scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {\n                    public void adjustmentValueChanged(AdjustmentEvent e) {\n                        scrolling = e.getValueIsAdjusting();\n                        updateColumnsPreferredWidth();\n                    }\n                });\n        }\n    }\n    \n    private JScrollPane getEnclosingScrollPane() {\n        Container parent = SwingUtilities.getUnwrappedParent(this);\n        if (!(parent instanceof JViewport)) return null;\n        Container scroll = ((JViewport)parent).getParent();\n        return scroll instanceof JScrollPane ? (JScrollPane)scroll : null;\n    }\n    \n    private void chooseColumns(Component source, Point p) {\n        final ProfilerColumnModel cModel = _getColumnModel();\n        List<TableColumn> columns = Collections.list(cModel.getColumns());\n        \n// --- NOTE: uncomment to sort column checkboxes by model index ----------------\n//        Collections.sort(columns, new Comparator<TableColumn>() {\n//            public int compare(TableColumn c1, TableColumn c2) {\n//                return Integer.compare(c1.getModelIndex(), c2.getModelIndex());\n//            }\n//        });\n        \n        JPopupMenu popup = new JPopupMenu();\n        for (final TableColumn c : columns)\n            popup.add(new JCheckBoxMenuItem(c.getHeaderValue().toString(), c.getWidth() > 0) {\n                {\n                    setEnabled(c.getModelIndex() != mainColumn);\n//                    setToolTipText(cModel.getColumnToolTip(c.getModelIndex()));\n                }\n                protected void fireActionPerformed(ActionEvent e) {\n                    cModel.setColumnVisibility(c, isSelected(), ProfilerTable.this);\n                }\n            });\n        \n        if (p == null) p = new Point(source.getSize().width -\n                                     popup.getPreferredSize().width - 1,\n                                     source.getHeight() - 1);\n        popup.show(source, p.x, p.y);\n    }\n    \n    public void doLayout() {\n        ProfilerColumnModel cModel = _getColumnModel();\n        JTableHeader header = getTableHeader();\n        TableColumn res = header == null ? null : header.getResizingColumn();\n        if (res != null) {\n            // Resizing column\n            int delta = getWidth() - cModel.getTotalColumnWidth();\n            TableColumn next = cModel.getNextVisibleColumn(res);\n            if (res == next) {\n                res.setWidth(res.getWidth() + delta);\n            } else {\n                next.setWidth(next.getWidth() + delta);\n            }\n        } else {\n            // Resizing table\n            int toResizeIndex = cModel.getFitWidthColumn();\n            if (toResizeIndex == -1) {\n                super.doLayout();\n            } else {\n                Enumeration<TableColumn> columns = cModel.getColumns();\n                TableColumn toResizeColumn = null;\n                int columnsWidth = 0;\n                while (columns.hasMoreElements()) {\n                    TableColumn column = columns.nextElement();\n                    if (column.getModelIndex() == toResizeIndex) {\n                        if (!cModel.isColumnVisible(column)) {\n                            super.doLayout();\n                            return;\n                        }\n                        toResizeColumn = column;\n                    } else {\n                        columnsWidth += column.getWidth();\n                    }\n                }\n                if (toResizeColumn != null) toResizeColumn.setWidth(getWidth() - columnsWidth);\n\n                // instead of super.doLayout()\n                layout();\n            }\n        }\n    }\n    \n    // --- Row sorter ----------------------------------------------------------\n    \n    boolean isSortable() {\n        return getRowSorter() != null;\n    }\n    \n    ProfilerRowSorter _getRowSorter() {\n        return (ProfilerRowSorter)getRowSorter();\n    }\n    \n    protected TableRowSorter createRowSorter() {\n        ProfilerRowSorter s = new ProfilerRowSorter(getModel());\n        s.setStringConverter(new TableStringConverter() {\n            public String toString(TableModel model, int row, int column) {\n                return getModelStringValue(row, column);\n            }\n        });\n        s.setDefaultSortOrder(SortOrder.DESCENDING);\n        s.setSortColumn(0);\n        return s;\n    }\n    \n    public void disableColumnSorting(int column) {\n        ProfilerRowSorter sorter = _getRowSorter();\n        if (sorter == null) return;\n        int _column = convertColumnIndexToView(column);\n        sorter.setSortable(_column, false);\n    }\n    \n    public void setSortColumn(int column) {\n        if (isSortable()) _getRowSorter().setSortColumn(column);\n    }\n    \n    public int getSortColumn() {\n        return isSortable() ? _getRowSorter().getSortColumn() : -1;\n    }\n    \n    public void setSorting(int column, SortOrder sortOrder) {\n        if (isSortable()) {\n            RowSorter.SortKey sortKey = new RowSorter.SortKey(column, sortOrder);\n            _getRowSorter().setSortKeysImpl(Collections.singletonList(sortKey));\n        }\n    }\n    \n    public void setSecondarySortColumn(int column) {\n        if (isSortable()) _getRowSorter().setSecondarySortColumn(column);\n    }\n    \n    public void setDefaultSortOrder(SortOrder sortOrder) {\n        if (isSortable()) _getRowSorter().setDefaultSortOrder(sortOrder);\n    }\n    \n    public void setDefaultSortOrder(int column, SortOrder sortOrder) {\n        if (isSortable()) _getRowSorter().setDefaultSortOrder(column, sortOrder);\n    }\n    \n    public void setAllowsThreeStateColumns(boolean threeStateColumns) {\n        _getRowSorter().setAllowsThreeStateColumns(threeStateColumns);\n    }\n    \n    public boolean allowsThreeStateColumns() {\n        return _getRowSorter().allowsThreeStateColumns();\n    }\n    \n    // --- Row filter ----------------------------------------------------------\n    \n    // false = OR, true = AND\n    public void setFiltersMode(boolean mode) {\n        _getRowSorter().setFiltersMode(mode);\n    }\n    \n    public boolean getFiltersMode() {\n        return _getRowSorter().getFiltersMode();\n    }\n    \n    public void addRowFilter(RowFilter filter) {\n        _getRowSorter().addRowFilter(filter);\n    }\n    \n    public void removeRowFilter(RowFilter filter) {\n        _getRowSorter().removeRowFilter(filter);\n    }\n    \n    public void setRowFilter(RowFilter filter) {\n        _getRowSorter().setRowFilter(filter);\n    }\n    \n    public RowFilter getRowFilter() {\n        return _getRowSorter().getRowFilter();\n    }\n    \n    // --- Default action ------------------------------------------------------\n    \n    private Action defaultAction;\n    \n    public void setDefaultAction(Action action) {\n        this.defaultAction = action;\n    }\n    \n    public void performDefaultAction(ActionEvent e) {\n        if (defaultAction != null) defaultAction.actionPerformed(null);\n    }\n    \n    // --- Popup menu ----------------------------------------------------------\n    \n    private long pressedWhen;\n    private Point pressedPoint;\n    private boolean providesPopupMenu;\n    \n    public final void providePopupMenu(boolean provide) {\n        providesPopupMenu = provide;\n    }\n    \n    public final boolean providesPopupMenu() {\n        return providesPopupMenu;\n    }\n    \n    protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n        // Implementation here\n    }\n    \n    public final JMenuItem createCopyMenuItem() {\n        final int row = getSelectedRow();\n        \n        JMenu copyItem = new JMenu(BUNDLE().getString(\"ProfilerTable_CopyMenu\")); // NOI118N\n        \n        JMenuItem copyRowItem = new JMenuItem(BUNDLE().getString(\"ProfilerTable_CopyRowItem\")) { // NOI118N\n            protected void fireActionPerformed(ActionEvent e) {\n                StringBuilder val = new StringBuilder();\n                List<TableColumn> columns = Collections.list(_getColumnModel().getColumns());\n                for (int col = 0; col < columns.size(); col++) if (columns.get(col).getWidth() > 0)\n                    val.append(\"\\t\").append(getStringValue(row, col)); // NOI118N\n                StringSelection s = new StringSelection(val.toString().trim());\n                Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s, s);\n            }\n        };\n        copyItem.add(copyRowItem);\n        \n        copyItem.addSeparator();\n        \n        String genericItemName = BUNDLE().getString(\"ProfilerTable_CopyColumnItem\"); // NOI118N\n        List<TableColumn> columns = Collections.list(_getColumnModel().getColumns());\n        for (int col = 0; col < columns.size(); col++) {\n            final int _col = col;\n            TableColumn column = columns.get(col);\n            if (column.getWidth() > 0) {\n                String columnName = column.getHeaderValue().toString();\n                if (columnName.toLowerCase(Locale.ENGLISH).startsWith(\"<html>\")) columnName = columnName.replaceAll(\"<[^>]*>\", \"\"); // NOI118N\n                copyItem.add(new JMenuItem(MessageFormat.format(genericItemName, columnName)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        StringSelection s = new StringSelection(getStringValue(row, _col));\n                        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s, s);\n                    }\n                });\n            }\n        }\n        \n        return copyItem;\n    }\n    \n    protected void popupShowing() {}\n    \n    protected void popupHidden() {}\n    \n    public Object getValueForRow(int row) {\n        if (row == -1) return null;\n        if (row >= getModel().getRowCount()) return null; // #239936\n        return getValueAt(row, convertColumnIndexToView(mainColumn));\n    }\n    \n    public Object getUserValueForRow(int row) {\n        return getValueForRow(row);\n    }\n    \n    protected void processMouseEvent(MouseEvent e) {\n        // --- Resolve CellTips/MouseEvent incompatibilities -------------------\n        //     TBD: doesn't work for heavyweight popups (RELEASED / CLICKED)\n        MouseEvent generatedClick = null;\n        if (e.getID() == MouseEvent.MOUSE_PRESSED) {\n            pressedWhen = e.getWhen();\n            pressedPoint = null;\n        } else if (e.getID() == MouseEvent.MOUSE_RELEASED) {\n            if (e.getWhen() - pressedWhen == 1) {\n                // #241878 dispatch MOUSE_RELEASED after forwarding MOUSE_PRESSED\n                pressedPoint = e.getPoint();\n                super.processMouseEvent(e);\n                return;\n            } else if (e.getPoint().equals(pressedPoint)) {\n                pressedPoint = null;\n                generatedClick = new MouseEvent(e.getComponent(), MouseEvent.MOUSE_CLICKED,\n                                                e.getWhen() + 1, e.getModifiers(),\n                                                e.getX(), e.getY(), e.getClickCount(),\n                                                e.isPopupTrigger(), e.getButton());\n            }\n            pressedWhen = 0;\n        }\n        // ---------------------------------------------------------------------\n        \n        boolean popupEvent = providesPopupMenu && e.isPopupTrigger();\n        boolean clickEvent = e.getID() == MouseEvent.MOUSE_CLICKED && SwingUtilities.isLeftMouseButton(e);\n        int row = rowAtPoint(e.getPoint());\n        \n        // Do not process doubleclick in editable cell (checkbox)\n        if (clickEvent && row != -1 && e.getClickCount() > 1) {\n            if (isCellEditable(row, columnAtPoint(e.getPoint())))\n                e = clearClicks(e);\n        }\n        \n        // Right-press selects row for popup\n        // Middle-press selects if enabled\n        if (e.getID() == MouseEvent.MOUSE_PRESSED && row != -1) {\n            if (popupEvent || (selectionOnMiddlePress && SwingUtilities.isMiddleMouseButton(e))) {\n                ListSelectionModel sel = getSelectionModel();\n                if (sel.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION || !sel.isSelectedIndex(row)) {\n                    selectRow(row, true);\n                    requestFocusInWindow();\n                }\n            }\n        }\n//        if (popupEvent && e.getID() == MouseEvent.MOUSE_PRESSED && row != -1) {\n//            ListSelectionModel sel = getSelectionModel();\n//            if (sel.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION ||\n//                !sel.isSelectedIndex(row)) selectRow(row, true);\n//        }\n        \n        super.processMouseEvent(e);\n        \n        // pop-up trigger selects row and opens popup\n        if (popupEvent && row != -1) {\n            ListSelectionModel sel = getSelectionModel();\n            if (sel.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION ||\n                !sel.isSelectedIndex(row)) selectRow(row, true);\n            final MouseEvent me = e;\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { showPopupMenu(me); }\n            });\n        }\n        \n        // Only perform default action if not already processed (expand tree)\n        if (!e.isConsumed() && clickEvent && e.getClickCount() == 2)\n            performDefaultAction(new ActionEvent(e.getSource(), e.getID(), \"default action\", e.getWhen(), e.getModifiers())); // NOI18N\n        \n        if (generatedClick != null) processMouseEvent(generatedClick);\n    }\n    \n    protected void processKeyEvent(KeyEvent e) {\n        int code = e.getKeyCode();\n        if (code == KeyEvent.VK_CONTEXT_MENU ||\n           (code == KeyEvent.VK_F10 && e.getModifiers() == InputEvent.SHIFT_MASK)) {\n            e.consume();\n            showPopupMenu(null);\n        }\n        \n        super.processKeyEvent(e);\n    }\n    \n    private void showPopupMenu(MouseEvent e) {\n        JPopupMenu popup = new JPopupMenu() {\n            public void setVisible(boolean visible) {\n                if (visible) popupShowing();\n                super.setVisible(visible);\n                if (!visible) popupHidden();\n            }\n        };\n        \n        int row = getSelectedRow();\n        Object value = getValueForRow(row);\n        Object userValue = getUserValueForRow(row);\n        populatePopup(popup, value, userValue);\n        \n        if (popup.getComponentCount() > 0) {\n            if (e == null) {\n                boolean b = row == -1;\n                int c = b ? -1 : convertColumnIndexToView(mainColumn);\n                Rectangle t = b ? getVisibleRect() : getCellRect(row, c, false);\n                Dimension s = popup.getPreferredSize();\n                int x = t.x + (t.width - s.width) / 2;\n                int y = t.y + (b ? (t.height - s.height) / 2 : getRowHeight() - 4);\n                popup.show(this, Math.max(x, 0), Math.max(y, 0));\n            } else {\n                popup.show(this, e.getX(), e.getY());\n            }\n        }\n    }\n    \n    // --- Persistence ---------------------------------------------------------\n    \n    public void loadColumns(Properties properties) {\n        _getColumnModel().loadFromStorage(properties, this);\n        if (isSortable()) _getRowSorter().loadFromStorage(properties, this);\n    }\n    \n    public void saveColumns(Properties properties) {\n        _getColumnModel().saveToStorage(properties, this);\n        if (isSortable()) _getRowSorter().saveToStorage(properties, this);\n    }\n    \n    // --- Header tweaks -------------------------------------------------------\n    \n    protected JTableHeader createDefaultTableHeader() {\n        return new JTableHeader(columnModel) {\n            public String getToolTipText(MouseEvent e) {\n                int index = columnAtPoint(e.getPoint());\n                if (index == -1) return null;\n                ProfilerColumnModel cModel = _getColumnModel();\n                TableColumn column = cModel.getColumn(index);\n                String toolTip = cModel.getColumnToolTip(column.getModelIndex());\n                return toolTip;\n            }\n            protected void processMouseEvent(MouseEvent e) {\n                if (hideableColums && UIUtils.isAquaLookAndFeel() && e.isPopupTrigger())\n                    chooseColumns((Component)e.getSource(), e.getPoint());\n                super.processMouseEvent(e.getClickCount() > 1 ? clearClicks(e) : e);\n            }\n            public void setResizingColumn(TableColumn aColumn) {\n                _getColumnModel().setResizingColumn(aColumn);\n                super.setResizingColumn(aColumn);\n            }\n        };\n    }\n    \n    protected static MouseEvent clearClicks(MouseEvent e) {\n        // Clear unwanted doubleclicks\n        return new MouseEvent((Component)e.getSource(), e.getID(), e.getWhen(),\n                              e.getModifiers(), e.getX(), e.getY(),\n                              1, e.isPopupTrigger(), e.getButton());\n    }\n    \n    \n    public static interface Tweaker {\n        \n        public void tweak(ProfilerTable table);\n        \n    } \n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/ProfilerTableActions.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ProfilerTableActions {\n\n    static void install(ProfilerTable table) {\n        new ProfilerTableActions(table).install();\n    }\n\n\n    private final ProfilerTable table;\n\n    private ProfilerTableActions(ProfilerTable table) { this.table = table; }\n\n    private void install() {\n        ActionMap map = table.getActionMap();\n\n        map.put(\"selectNextColumn\", selectNextColumnAction()); // NOI18N\n        map.put(\"selectPreviousColumn\", selectPreviousColumnAction()); // NOI18N\n        map.put(\"selectNextColumnCell\", createNextCellAction()); // NOI18N\n        map.put(\"selectPreviousColumnCell\", createPreviousCellAction()); // NOI18N\n        map.put(\"selectFirstColumn\", selectFirstColumnAction()); // NOI18N\n        map.put(\"selectLastColumn\", selectLastColumnAction()); // NOI18N\n        map.put(\"selectNextRowCell\", selectNextRowAction()); // NOI18N\n        map.put(\"selectPreviousRowCell\", selectPreviousRowAction()); // NOI18N\n\n        map.put(\"selectNextRowExtendSelection\", map.get(\"selectNextRow\")); // NOI18N\n        map.put(\"selectPreviousRowExtendSelection\", map.get(\"selectPreviousRow\")); // NOI18N\n        map.put(\"selectNextColumnExtendSelection\", map.get(\"selectNextColumn\")); // NOI18N\n        map.put(\"selectPreviousColumnExtendSelection\", map.get(\"selectPreviousColumn\")); // NOI18N\n        map.put(\"selectLastColumnExtendSelection\", map.get(\"selectLastColumn\")); // NOI18N\n        map.put(\"selectFirstColumnExtendSelection\", map.get(\"selectFirstColumn\")); // NOI18N\n    }\n\n    private Action selectNextRowAction() {\n        return new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                ProfilerColumnModel cModel = table._getColumnModel();\n                if (table.getRowCount() == 0 || cModel.getVisibleColumnCount() == 0) return;\n                \n                int row = table.getSelectedRow();\n                if (row == -1) {\n                    table.selectColumn(cModel.getFirstVisibleColumn(), false);\n                    table.selectRow(0, true);\n                } else {\n                    if (++row == table.getRowCount()) {\n                        row = 0;\n                        int column = table.getSelectedColumn();\n                        if (column == -1) column = cModel.getFirstVisibleColumn();\n                        column = cModel.getNextVisibleColumn(column);\n                        table.selectColumn(column, false);\n                    }\n                    table.selectRow(row, true);\n                }\n            }\n        };\n    }\n    \n    private Action selectPreviousRowAction() {\n        return new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                ProfilerColumnModel cModel = table._getColumnModel();\n                if (table.getRowCount() == 0 || cModel.getVisibleColumnCount() == 0) return;\n                \n                int row = table.getSelectedRow();\n                if (row == -1) {\n                    table.selectColumn(cModel.getLastVisibleColumn(), false);\n                    table.selectRow(table.getRowCount() - 1, true);\n                } else {\n                    if (--row == -1) {\n                        row = table.getRowCount() - 1;\n                        int column = table.getSelectedColumn();\n                        if (column == -1) column = cModel.getLastVisibleColumn();\n                        column = cModel.getPreviousVisibleColumn(column);\n                        table.selectColumn(column, false);\n                    }\n                    table.selectRow(row, true);\n                }\n            }\n        };\n    }\n    \n    private Action selectFirstColumnAction() {\n        return new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                ProfilerColumnModel cModel = table._getColumnModel();\n                if (table.getRowCount() == 0 || cModel.getVisibleColumnCount() == 0) return;\n                \n                int row = table.getSelectedRow();\n                table.selectColumn(cModel.getFirstVisibleColumn(), row != -1);\n                if (row == -1) table.selectRow(0, true);\n            }\n        };\n    }\n    \n    private Action selectLastColumnAction() {\n        return new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                ProfilerColumnModel cModel = table._getColumnModel();\n                if (table.getRowCount() == 0 || cModel.getVisibleColumnCount() == 0) return;\n                \n                int row = table.getSelectedRow();\n                table.selectColumn(cModel.getLastVisibleColumn(), row != -1);\n                if (row == -1) table.selectRow(0, true);\n            }\n        };\n    }\n    \n    private Action selectNextColumnAction() {\n        return new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                ProfilerColumnModel cModel = table._getColumnModel();\n                if (table.getRowCount() == 0 || cModel.getVisibleColumnCount() == 0) return;\n                \n                int column = table.getSelectedColumn();\n                if (column == -1) {\n                    table.selectColumn(cModel.getFirstVisibleColumn(), false);\n                    table.selectRow(0, true);\n                } else {\n                    int nextColumn = cModel.getNextVisibleColumn(column);\n                    if (nextColumn > column) table.selectColumn(nextColumn, true);\n                }\n            }\n        };\n    }\n    \n    private Action selectPreviousColumnAction() {\n        return new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                ProfilerColumnModel cModel = table._getColumnModel();\n                if (table.getRowCount() == 0 || cModel.getVisibleColumnCount() == 0) return;\n                \n                int column = table.getSelectedColumn();\n                if (column == -1) {\n                    table.selectColumn(cModel.getFirstVisibleColumn(), false);\n                    table.selectRow(0, true);\n                } else {\n                    int previousColumn = cModel.getPreviousVisibleColumn(column);\n                    if (previousColumn < column) table.selectColumn(previousColumn, true);\n                }\n            }\n        };\n    }\n    \n    private Action createNextCellAction() {\n        return new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                ProfilerColumnModel cModel = table._getColumnModel();\n                if (table.getRowCount() == 0 || cModel.getVisibleColumnCount() == 0) return;\n\n                int column = table.getSelectedColumn();\n                if (column == -1) {\n                    table.selectColumn(cModel.getFirstVisibleColumn(), false);\n                    table.selectRow(0, true);\n                } else {\n                    int nextColumn = cModel.getNextVisibleColumn(column);\n                    boolean differentRow = nextColumn <= column && table.getRowCount() > 1;\n                    if (nextColumn != column) table.selectColumn(nextColumn, !differentRow);\n                    if (differentRow) {\n                        int row = table.getSelectedRow();\n                        int newRow = getNextRow(row);\n                        if (row != newRow) table.selectRow(newRow, true);\n                    }\n                }\n            }\n        };\n    }\n    \n    private Action createPreviousCellAction() {\n        return new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                ProfilerColumnModel cModel = table._getColumnModel();\n                if (table.getRowCount() == 0 || cModel.getVisibleColumnCount() == 0) return;\n\n                int column = table.getSelectedColumn();\n                if (column == -1) {\n                    table.selectColumn(cModel.getFirstVisibleColumn(), false);\n                    table.selectRow(0, true);\n                } else {\n                    int previousColumn = cModel.getPreviousVisibleColumn(column);\n                    boolean differentRow = previousColumn >= column && table.getRowCount() > 1;\n                    if (previousColumn != column) table.selectColumn(previousColumn, !differentRow);\n                    if (differentRow) {\n                        int row = table.getSelectedRow();\n                        int newRow = getPreviousRow(row);\n                        if (row != newRow) table.selectRow(newRow, true);\n                    }\n                }\n            }\n        };\n    }\n    \n    private int getNextRow(int row) {\n        return ++row == table.getRowCount() ? 0 : row;\n    }\n    \n    private int getPreviousRow(int row) {\n        return --row == -1 ? table.getRowCount() - 1 : row;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/ProfilerTableContainer.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Rectangle;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseWheelEvent;\nimport java.awt.event.MouseWheelListener;\nimport java.awt.image.BufferedImage;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTable;\nimport javax.swing.JViewport;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.TableColumnModelEvent;\nimport javax.swing.event.TableColumnModelListener;\nimport javax.swing.table.JTableHeader;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ProfilerTableContainer extends JPanel {\n\n    private static final String PROP_COLUMN = \"column\"; // NOI18N\n\n    private ProfilerTable table;\n    private JScrollPane tableScroll;\n    private JPanel scrollersPanel;\n\n    public ProfilerTableContainer(final ProfilerTable table, boolean decorated,\n                                  ColumnChangeAdapter adapter) {\n        super(new BorderLayout());\n        setOpaque(true);\n        setBackground(new HTMLTextArea().getBackground());\n\n        this.table = table;\n\n        tableScroll = new JScrollPane(table) {\n            protected JViewport createViewport() {\n                if (getViewport() == null) return customViewport(table);\n                else return super.createViewport();\n            }\n        };\n        tableScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);\n        tableScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n        configureVerticalScrollBar(tableScroll.getVerticalScrollBar());\n        if (!decorated) {\n            tableScroll.setBorder(BorderFactory.createEmptyBorder());\n            tableScroll.setViewportBorder(BorderFactory.createEmptyBorder());\n        }\n        add(tableScroll, BorderLayout.CENTER);\n        \n        final ProfilerColumnModel cModel = table._getColumnModel();\n        \n        final Set<Integer> scrollableColumns = table.getScrollableColumns();\n        if (scrollableColumns != null && !scrollableColumns.isEmpty()) {\n            scrollersPanel = new JPanel(null) {\n                public void doLayout() {\n                    int height = getHeight();\n                    if (height > 0) for (Component component : getComponents()) {\n                        JScrollBar scroller = (JScrollBar)component;\n                        int column = table.convertColumnIndexToView(getColumn(scroller));\n                        Rectangle rect = table.getTableHeader().getHeaderRect(column);\n                        scroller.setBounds(rect.x, 0, rect.width, height);\n                        scroller.doLayout();\n                    }\n                }\n                public Dimension getPreferredSize() {\n                    Dimension d = super.getPreferredSize();\n                    d.height = 0;\n                    for (Component component : getComponents()) {\n                        JScrollBar scroller = (JScrollBar)component;\n                        if (cModel.isColumnVisible(getColumn(scroller)))\n                            d.height = Math.max(d.height, scroller.getPreferredSize().height);\n                    }\n                    return d;\n                }\n            };\n            scrollersPanel.setOpaque(true);\n            scrollersPanel.setBackground(UIUtils.getProfilerResultsBackground());\n\n            for (final Integer column : scrollableColumns) {\n                final JScrollBar scroller = new JScrollBar(JScrollBar.HORIZONTAL) {\n                    private boolean adjusting = false;\n                    {\n                        putClientProperty(PROP_COLUMN, column);\n                    }\n                    public void setValue(int value) {\n                        value = checkedValue(value);\n                        super.setValue(value);\n                        updateColumnOffset(value);\n                    }\n                    public void setValues(int value, int extent, int min, int max) {\n                        if (adjusting) return;\n                        value = checkedValue(value);\n                        setEnabled(extent < max);\n                        if (trackEnd()) value = max - extent;\n                        super.setValues(value, extent, min, max);\n                        updateColumnOffset(value);\n                    }\n                    public void setValueIsAdjusting(boolean b) {\n                        adjusting = b;\n                        super.setValueIsAdjusting(b);\n                        if (!adjusting) updateHorizontalScrollBars(table, column, false);\n                    }\n                    public int getUnitIncrement() {\n                        return 20;\n                    }\n                    public int getUnitIncrement(int direction) {\n                        return getUnitIncrement();\n                    }\n                    public int getBlockIncrement() {\n                        return (int)(getVisibleAmount() * 0.9f);\n                    }\n                    public int getBlockIncrement(int direction) {\n                        return getBlockIncrement();\n                    }\n                    private void updateColumnOffset(int value) {\n                        table.setColumnOffset(column, value);\n                    }\n                    private boolean trackEnd() {\n                        if (!isEnabled()) return false;\n                        int visible = getVisibleAmount();\n                        if (visible > 0) return getValue() + visible >= getMaximum();\n                        return !table.isLeadingAlign(column);\n                    }\n                    private int checkedValue(int value) {\n                        value = Math.max(0, value);\n                        value = Math.min(getMaximum() - getVisibleAmount(), value);\n                        return value;\n                    }\n                };\n                scroller.addMouseWheelListener(new MouseWheelListener() {\n                    public void mouseWheelMoved(MouseWheelEvent e) {\n                        scroll(scroller, e);\n                    }\n                });\n                scrollersPanel.add(scroller);\n            }\n            \n            MouseWheelListener[] listeners = tableScroll.getMouseWheelListeners();\n            if (listeners != null && listeners.length == 1) {\n                final MouseWheelListener listener = listeners[0];\n                tableScroll.removeMouseWheelListener(listener);\n                tableScroll.addMouseWheelListener(new MouseWheelListener() {\n                    public void mouseWheelMoved(MouseWheelEvent e) {\n                        if (onlyShift(e)) {\n                            int c = table.columnAtPoint(e.getPoint());\n                            int _c = c == -1 ? -1 : table.convertColumnIndexToModel(c);\n                            if (_c != -1 && table.isScrollableColumn(_c)) {\n                                JScrollBar scroller = getScroller(_c);\n                                if (scroller != null) scroll(scroller, e);\n                                return;\n                            }\n                        }\n                        listener.mouseWheelMoved(e);\n                    }\n                });\n            }\n            \n            cModel.addColumnChangeListener(new ColumnChangeAdapter() {\n                public void columnWidthChanged(int column, int oldWidth, int newWidth) {\n                    if (table.isScrollableColumn(column))\n                        updateHorizontalScrollBars(table, column, true);\n                }\n                public void columnPreferredWidthChanged(int column, int oldWidth, int newWidth) {\n                    if (table.isScrollableColumn(column))\n                        updateHorizontalScrollBars(table, column, false);\n                }\n            });\n            \n            cModel.addColumnModelListener(new TableColumnModelListener() {\n                public void columnAdded(TableColumnModelEvent e) {}\n                public void columnRemoved(TableColumnModelEvent e) {}\n                public void columnMoved(TableColumnModelEvent e) { moved(e); }\n                public void columnMarginChanged(ChangeEvent e) { margin(e); }\n                public void columnSelectionChanged(ListSelectionEvent e) {}\n                private void moved(TableColumnModelEvent e) {\n                    if (e.getFromIndex() != e.getToIndex())\n                        updateHorizontalScrollBars(table, -1, true);\n                }\n                private void margin(ChangeEvent e) {\n                    // Invoke later to let the columnWidthChanged perform first\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            for (Integer column : scrollableColumns) {\n                            int _column = table.convertColumnIndexToView(column);\n                                Rectangle rect = table.getTableHeader().getHeaderRect(_column);\n                                Rectangle scroll = getScroller(column).getBounds();\n                                // Column position changed without changing size\n                                if (rect.x != scroll.x || rect.width != scroll.width) {\n                                    updateHorizontalScrollBars(table, -1, true);\n                                    break;\n                                }\n                            }\n                        }\n                    });\n                }\n            });\n\n            add(scrollersPanel, BorderLayout.SOUTH);\n        }\n        \n        if (adapter != null) cModel.addColumnChangeListener(adapter);\n    }\n    \n    private static void scroll(JScrollBar scroller, MouseWheelEvent event) {\n        if (event.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {\n            int unitsToScroll = event.getUnitsToScroll();\n            if (unitsToScroll != 0) {\n                int direction = unitsToScroll < 0 ? -1 : 1;\n                int increment = scroller.getUnitIncrement(direction);\n                int amount = event.getScrollAmount();\n                int oldValue = scroller.getValue();\n                int newValue = oldValue + increment * amount * direction;\n                if (oldValue != newValue) scroller.setValue(newValue);\n            }\n            event.consume();\n        }\n    }\n    \n    private static boolean onlyShift(MouseEvent e) {\n        return e.isShiftDown() && !(e.isAltDown() || e.isAltGraphDown() ||\n                                    e.isControlDown() || e.isMetaDown());\n    }\n    \n    public boolean tableNeedsScrolling() {\n        return tableScroll.getVerticalScrollBar().isEnabled();\n    }\n    \n    public BufferedImage createTableScreenshot(boolean onlyVisibleArea) {\n        return onlyVisibleArea ? UIUtils.createScreenshot(tableScroll) :\n                                 UIUtils.createScreenshot(table);\n    }\n    \n    private int getColumn(JScrollBar scroller) {\n        return (Integer)scroller.getClientProperty(PROP_COLUMN);\n    }\n    \n    private JScrollBar getScroller(int column) {\n        for (Component component : scrollersPanel.getComponents()) {\n            JScrollBar scroller = (JScrollBar)component;\n            if (getColumn(scroller) == column) return scroller;\n        }\n        return null;\n    }\n    \n    private JViewport customViewport(final JTable table) {\n        return new JViewport() {\n            {\n                setBackground(table.getBackground());\n                table.addPropertyChangeListener(\"enabled\", new PropertyChangeListener() { // NOI18N\n                    public void propertyChange(PropertyChangeEvent evt) { setBackground(table.getBackground()); }\n                });\n            }\n            public void paint(Graphics g) {\n                super.paint(g);\n                \n                Component view = getView();\n                if (view == table) {\n                    if (!listening) hookColumns();\n                    \n                    int height = getHeight();\n                    int viewHeight = view.getHeight();\n                    if (height > viewHeight) {\n                        g.setColor(table.getGridColor());\n                        JTableHeader header = table.getTableHeader();\n                        if (header != null) {\n                            for (int i = 0; i < table.getColumnCount(); i++) {\n                                Rectangle rect = header.getHeaderRect(i);\n                                if (rect.width > 0) g.drawLine(rect.x + rect.width - 1, viewHeight,\n                                                               rect.x + rect.width - 1, height - 1);\n                            }\n                        } else if (table.getRowCount() > 0) {\n                            for (int i = 0; i < table.getColumnCount(); i++) {\n                                Rectangle rect = table.getCellRect(0, i, true);\n                                if (rect.width > 0) g.drawLine(rect.x + rect.width - 1, viewHeight,\n                                                               rect.x + rect.width - 1, height - 1);\n                            }\n                        }\n                    }\n                }\n            }\n            private boolean listening;\n            private void hookColumns() {\n                table.getColumnModel().addColumnModelListener(new TableColumnModelListener() {\n                    public void columnAdded(TableColumnModelEvent e) { repaint(); }\n                    public void columnRemoved(TableColumnModelEvent e) { repaint(); }\n                    public void columnMoved(TableColumnModelEvent e) { repaint(); }\n                    public void columnMarginChanged(ChangeEvent e) { repaint(); }\n                    public void columnSelectionChanged(ListSelectionEvent e) { repaint(); }\n                });\n                listening = true;\n            }\n        };\n    }\n    \n    private void configureVerticalScrollBar(final JScrollBar scrollBar) {\n        scrollBar.getModel().addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                scrollBar.setEnabled(ProfilerTableContainer.this.isEnabled() &&\n                          scrollBar.getVisibleAmount() < scrollBar.getMaximum());\n            }\n        });\n    }\n    \n    private void updateHorizontalScrollBars(ProfilerTable table, int column, boolean layout) {\n        if (column != -1) {\n            JScrollBar scroll = getScroller(column);\n            int offset = table.getColumnOffset(column);\n            int columnPref = table.getColumnPreferredWidth(column);\n            int _column = table.convertColumnIndexToView(column);\n            int columnAct = table.getTableHeader().getHeaderRect(_column).width;\n            if (columnPref > columnAct) {\n                int value = Math.min(offset, columnPref - columnAct);\n                scroll.setValues(value, columnAct, 0, columnPref);\n            } else {\n                scroll.setValues(0, 0, 0, 0);\n            }\n        }\n        \n        if (layout) {\n            doLayout();\n            scrollersPanel.doLayout();\n            repaint();\n        }\n    }\n    \n    \n    public static class ColumnChangeAdapter implements ProfilerColumnModel.Listener {\n        \n        public void columnOffsetChanged(int column, int oldOffset, int newOffset) {}\n        \n        public void columnWidthChanged(int column, int oldWidth, int newWidth) {}\n        \n        public void columnPreferredWidthChanged(int column, int oldWidth, int newWidth) {}\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/ProfilerTableHover.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.AWTEvent;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Graphics;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.Toolkit;\nimport java.awt.event.AWTEventListener;\nimport java.awt.event.ComponentEvent;\nimport java.awt.event.ComponentListener;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.FocusListener;\nimport java.awt.event.HierarchyBoundsListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.KeyListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseWheelEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport javax.swing.BorderFactory;\nimport javax.swing.CellRendererPane;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.Popup;\nimport javax.swing.PopupFactory;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.TableModelEvent;\nimport javax.swing.event.TableModelListener;\nimport javax.swing.table.TableCellRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ProfilerTableHover {\n\n    private static final boolean REPAINT_ON_HIDE =\n            !Boolean.getBoolean(\"ProfilerTableHover.noRepaintOnHide\"); // NOI18N\n\n\n    static void install(ProfilerTable table) {\n        new ProfilerTableHover(table).install();\n    }\n\n\n    private final ProfilerTable table;\n\n    private Popup popup;\n    private Point popupLocation; // topleft popup corner, table coords\n    private Rectangle popupRect; // visible cell rect, screen coords\n\n    private AWT awt;\n    private Mouse mouse;\n    private Paranoid paranoid;\n\n    private Point currentPoint;\n    private Point forwardPoint;\n    \n    \n    private ProfilerTableHover(ProfilerTable table) {\n        this.table = table;\n    }\n    \n    private void install() {\n        mouse = new Mouse();\n        mouse.install();\n    }\n    \n    private void showPopup(Painter p, Rectangle rect) {\n        mouse.deinstall();\n        \n        Point l = table.getLocationOnScreen();\n        \n        rect.translate(l.x, l.y);\n        popupRect = rect;\n        popupLocation = new Point(l.x + p.getX(), l.y + p.getY());\n        \n        PopupFactory popupFactory = PopupFactory.getSharedInstance();\n        popup = popupFactory.getPopup(table, p, popupLocation.x, popupLocation.y);\n        popup.show();\n        \n        paranoid = new Paranoid(p);\n        paranoid.install();\n        \n        awt = new AWT();\n        awt.install();\n    }\n    \n    private void hidePopup() {\n        if (awt != null) {\n            awt.deinstall();\n            awt = null;\n        }\n        \n        if (paranoid != null) {\n            paranoid.deinstall();\n            paranoid = null;\n        }\n        \n        popup.hide();\n        popupRect = null;\n        popupLocation = null;\n        popup = null;\n        \n        // Make sure lightweight popups are cleared correctly when mouse-wheeling\n        if (REPAINT_ON_HIDE) table.repaint();\n        \n        // Skip AWT noise after closing popup\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { mouse.install(); }\n        });\n    }\n    \n    private void checkPopup(int row, int column, Point point) {\n        if (row < 0 || row >= table.getRowCount()) return;\n        if (column < 0 || column >= table.getColumnCount()) return;\n        \n        if (point == null) point = currentPoint; else currentPoint = point;\n        if (point == null) return;\n        \n        Rectangle cellRect = table.getCellRect(row, column, true);\n        Rectangle rendererRect = getRendererRect(row, column);\n        if (rendererRect == null) return;\n        \n        rendererRect.translate(cellRect.x, cellRect.y);\n        if (cellRect.contains(rendererRect)) return; // Value fully visible\n        \n        Rectangle visibleRect = cellRect.intersection(rendererRect);\n        if (visibleRect.contains(point)) // Mouse over partially visible value\n            showPopup(new Painter(row, column, rendererRect), visibleRect);\n\n    }\n    \n    \n    private class AWT implements AWTEventListener {\n        \n        void install() {\n            Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK);\n            Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.MOUSE_MOTION_EVENT_MASK);\n            Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.MOUSE_WHEEL_EVENT_MASK);\n        }\n        \n        void deinstall() {\n            Toolkit.getDefaultToolkit().removeAWTEventListener(this);\n        }\n\n        public void eventDispatched(AWTEvent e) {\n            if (popup == null) return;\n            \n            // Not a mouse event\n            if (!(e instanceof MouseEvent)) return;\n            MouseEvent me = (MouseEvent)e;\n            \n            // Event not relevant\n            if (isIgnoreEvent(me)) return;\n            \n            // Mouse moved over popup\n            if (me.getID() == MouseEvent.MOUSE_MOVED && overPopup(me)) return;\n            \n            if (!overPopup(me)) {\n                // Mouse event outside of popup\n                hidePopup();\n            } else if (isForwardEvent(me)) {\n                // Mouse event on popup, to be forwarded to table\n                Point popupPoint = popupLocation;\n                hidePopup();\n                forwardEvent(me, popupPoint);\n            }\n        }\n        \n        private boolean overPopup(MouseEvent e) {\n            if (popupRect == null) return false;\n            // NOTE: e.getLocationOnScreen() doesn't work for MOUSE_WHEEL events\n            Point p = e.getPoint();\n            SwingUtilities.convertPointToScreen(p, e.getComponent());\n            return popupRect.contains(p);\n        }\n        \n        private boolean isIgnoreEvent(MouseEvent e) {\n            int eventID = e.getID();\n            return eventID == MouseEvent.MOUSE_ENTERED ||\n                   eventID == MouseEvent.MOUSE_EXITED;\n        }\n        \n        private boolean isForwardEvent(MouseEvent e) {\n            int eventID = e.getID();\n            return eventID == MouseEvent.MOUSE_PRESSED ||\n                   eventID == MouseEvent.MOUSE_RELEASED ||\n                   eventID == MouseEvent.MOUSE_WHEEL;\n        }\n        \n        private void forwardEvent(MouseEvent e, Point popupPoint) {\n            Point p = e.getPoint();\n            p.translate(popupPoint.x, popupPoint.y);\n            SwingUtilities.convertPointFromScreen(p, table);\n            forwardPoint = new Point(p.x - 1, p.y - 1);\n            \n            MouseWheelEvent we = e instanceof MouseWheelEvent ? (MouseWheelEvent)e : null;\n            MouseEvent ee = we != null ? new MouseWheelEvent(table, e.getID(), e.getWhen(),\n                                             e.getModifiers(), p.x, p.y, e.getClickCount(),\n                                             e.isPopupTrigger(), we.getScrollType(),\n                                             we.getScrollAmount(), we.getWheelRotation()) :\n                                         new MouseEvent(table, e.getID(), e.getWhen(),\n                                             e.getModifiers(), p.x, p.y, e.getClickCount(),\n                                             e.isPopupTrigger(), e.getButton());\n            \n            table.dispatchEvent(ee);\n            \n            // #241878 dispatch MOUSE_RELEASED after forwarding MOUSE_PRESSED\n            if (e.getID() == MouseEvent.MOUSE_PRESSED) {\n                ee = new MouseEvent(table, MouseEvent.MOUSE_RELEASED, e.getWhen() + 1,\n                                    e.getModifiers(), p.x, p.y, e.getClickCount(),\n                                    e.isPopupTrigger(), e.getButton());\n                table.dispatchEvent(ee);\n            }\n        }\n        \n    }\n    \n    private class Paranoid implements TableModelListener, KeyListener, ComponentListener,\n                                      HierarchyListener, HierarchyBoundsListener,\n                                      FocusListener, PropertyChangeListener {\n        private final Painter painter;\n        private Component focusOwner;\n        \n        Paranoid(Painter painter) {\n            this.painter = painter;\n        }\n        \n        void install() {\n            focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();\n            if (focusOwner != null) {\n                focusOwner.addKeyListener(this);\n                if (table.equals(focusOwner)) table.addFocusListener(this);\n            }\n            \n            table.getModel().addTableModelListener(this);\n            table.addComponentListener(this);\n            table.addHierarchyListener(this);\n            table.addHierarchyBoundsListener(this);\n        }\n        void deinstall() {\n            if (focusOwner != null) {\n                focusOwner.removeKeyListener(this);\n                if (table.equals(focusOwner)) table.removeFocusListener(this);\n                focusOwner = null;\n            }\n            \n            table.getModel().removeTableModelListener(this);\n            table.removeComponentListener(this);\n            table.removeHierarchyListener(this);\n            table.removeHierarchyBoundsListener(this);\n        }\n        \n        // TableModelListener\n        public void tableChanged(TableModelEvent e) {\n            if (painter.valueChanged()) {\n                final int row = painter.getRow();\n                final int column = painter.getColumn();\n                hidePopup();\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { checkPopup(row, column, null); }\n                });\n            }\n        }\n\n        // KeyListener\n        public void keyTyped(KeyEvent e) { hidePopup(); }\n        public void keyPressed(KeyEvent e) { hidePopup(); }\n        public void keyReleased(KeyEvent e) { hidePopup(); }\n        \n        // ComponentListener\n        public void componentResized(ComponentEvent e) { hidePopup(); }\n        public void componentMoved(ComponentEvent e) { hidePopup(); }\n        public void componentShown(ComponentEvent e) { hidePopup(); }\n        public void componentHidden(ComponentEvent e) { hidePopup(); }\n\n        // HierarchyListener\n        public void hierarchyChanged(HierarchyEvent e) { hidePopup(); }\n        \n        // HierarchyBoundsListener\n        public void ancestorMoved(HierarchyEvent e) { hidePopup(); }\n        public void ancestorResized(HierarchyEvent e) { hidePopup(); }\n        \n        // FocusListener\n        public void focusGained(FocusEvent e) {}\n        public void focusLost(FocusEvent e) { hidePopup(); }\n\n        // PropertyChangeListener\n        public void propertyChange(PropertyChangeEvent evt) { hidePopup(); }\n    }\n    \n    private class Mouse extends MouseAdapter {\n        void install() {\n            table.addMouseMotionListener(this);\n        }\n        void deinstall() {\n            table.removeMouseMotionListener(this);\n        }\n        public void mouseMoved(MouseEvent e) {\n            // Do not display popup when a modifier is pressed (can't read all keys)\n            if (e.getModifiers() != 0) return;\n                    \n            Point point = e.getPoint();\n            // Skip AWT noise after closing popup\n            if (point.equals(forwardPoint)) return;\n            \n            checkPopup(table.rowAtPoint(point), table.columnAtPoint(point), point);\n        }\n    }\n    \n    private class Painter extends JPanel {\n        \n        private final int row;\n        private final int column;\n        \n        private final Object value;\n        private final TableCellRenderer renderer;\n        \n        Painter(int row, int column, Rectangle bounds) {\n            super(null);\n            \n            this.row = row;\n            this.column = column;\n            \n            value = table.getValueAt(row, column);\n            renderer = table.getCellRenderer(row, column);\n            \n            setBorder(BorderFactory.createLineBorder(table.getGridColor()));\n            setBounds(bounds.x - 1, bounds.y - 1, bounds.width + 2, bounds.height + 2);\n            \n            setPreferredSize(getSize());\n        }\n        \n        protected void paintComponent(Graphics g) {\n            Component x = table.getRenderer(renderer, row, column, false);\n            getPainter().paintComponent(g, x, null, 1, 1, getWidth() - 2, getHeight() - 2, false);\n        }\n        \n        int getRow() {\n            return row;\n        }\n        \n        int getColumn() {\n            return column;\n        }\n        \n        boolean valueChanged() {\n            if (table.getRowCount() <= row) return true;\n            if (table.getColumnCount() <= column) return true;\n            Object v = table.getValueAt(row, column);\n            if (v == null && value == null) return false;\n            if (v != null && value != null) return !v.equals(value);\n            return true;\n        }\n        \n    }\n    \n    private Rectangle getRendererRect(int row, int column) {\n        Component component = getRenderer(row, column);\n        \n        if (component instanceof JComponent)\n            if (((JComponent)component).getClientProperty(ProfilerTable.PROP_NO_HOVER) != null)\n                return null;\n        \n        Rectangle bounds = component.getBounds();\n        bounds.x -= table.getColumnOffset(table.convertColumnIndexToModel(column));\n        \n        return bounds;\n    }\n    \n    private Component getRenderer(int row, int column) {\n        TableCellRenderer renderer = table.getCellRenderer(row, column);\n        return table.getRenderer(renderer, row, column, true);\n    }\n    \n    private static CellRendererPane PAINTER;\n    private static CellRendererPane getPainter() {\n        if (PAINTER == null) PAINTER = new CellRendererPane() {\n            public void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h, boolean shouldValidate) {\n                super.paintComponent(g, c, p, x, y, w, h, shouldValidate);\n                remove(c); // Prevent leaking ProfilerTreeTable.ProfilerTreeTableTree and transitively all the UI/models\n            }\n        };\n        return PAINTER;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/ProfilerTableHovers.java",
    "content": "/*\n * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Graphics;\nimport java.awt.GraphicsConfiguration;\nimport java.awt.Image;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.Window;\nimport java.awt.event.ComponentEvent;\nimport java.awt.event.ComponentListener;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.FocusListener;\nimport java.awt.event.HierarchyBoundsListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.KeyListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.image.BufferedImage;\nimport java.beans.PropertyChangeEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.CellRendererPane;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JWindow;\nimport javax.swing.MenuElement;\nimport javax.swing.MenuSelectionManager;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.event.TableModelEvent;\nimport javax.swing.event.TableModelListener;\nimport javax.swing.table.TableCellRenderer;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ProfilerTableHovers {\n\n    private static final int MAX_RENDERER_WIDTH = 5000;\n\n    private static final int POPUP_LEFT = 0;\n    private static final int POPUP_RIGHT = 1;\n\n\n    private final ProfilerTable table;\n\n    private Opener opener;\n    private Closer closer;\n\n    private CellRendererPane crp;\n\n    private int currentRow = -1;\n    private int currentColumn = -1;\n    private Point currentScreenPoint;\n\n    private final JWindow[] windows = new JWindow[2];\n\n\n    // --- Internal API --------------------------------------------------------\n    \n    static void install(ProfilerTable table) {\n        new ProfilerTableHovers(table).install();\n    }\n    \n    \n    // --- Implementation ------------------------------------------------------\n    \n    private ProfilerTableHovers(ProfilerTable table) {\n        this.table = table;\n    }\n    \n    private void install() {\n        opener = new Opener();\n        opener.install();\n    }\n    \n    \n    private void updatePopups(Point p, boolean repaint) {\n        if (currentScreenPoint == null) {\n            hidePopups();\n        } else {\n            if (p == null) {\n                p = new Point(currentScreenPoint);\n                SwingUtilities.convertPointFromScreen(p, table);\n            }\n            checkPopup(table.rowAtPoint(p), table.columnAtPoint(p), p, repaint);\n        }\n    }\n    \n    private void checkPopup(int row, int column, Point point, boolean repaint) {\n        if (!table.isShowing()) {\n            // Prevent \"IllegalComponentStateException: component must be showing on the screen...\"\n            hidePopups();\n            currentScreenPoint = null;\n            return;\n        }\n        \n        if (row < 0 || column < 0 || row >= table.getRowCount() ||\n            column >= table.getColumnCount()) { hidePopups(); return; }\n        \n        Component renderer = getRenderer(row, column);\n        Rectangle[] popups = computePopups(row, column, point, renderer);\n        \n        if (popups == null) {\n            hidePopups();\n        } else if (repaint || currentRow != row || currentColumn != column) {\n//            // If reusing the popup for a new cell hide the current popup\n//            // to honor window transitions (Linux) \n//            // !!! ACTUALLY NOT WORKING UNTIL Window.dispose() !!!\n//            if (!repaint) {\n//                if (windows[POPUP_LEFT] != null) windows[POPUP_LEFT].setVisible(false);\n//                if (windows[POPUP_RIGHT] != null) windows[POPUP_RIGHT].setVisible(false);\n//            }\n\n            if (!isInFocusedWindow(table) || isPopupOpen()) {\n                // Do not show value hovers when a lightweight popup is showing,\n                // might be drawn on top of it - overlap it.\n                hidePopups();\n            } else {\n                currentRow = row;\n                currentColumn = column;\n\n                showPopups(renderer, popups);\n            }\n        }\n    }\n    \n    private static boolean isInFocusedWindow(Component c) {\n        Window w = SwingUtilities.getWindowAncestor(c);\n        return w != null && w.isFocused();\n    }\n    \n    private static boolean isPopupOpen() {\n        MenuElement[] menuSel = MenuSelectionManager.defaultManager().getSelectedPath();\n        return menuSel != null && menuSel.length > 0;\n//        // Doesn't work reliably, hovering to a sliding window (Palette) changes the focus owner\n//        return KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() instanceof JRootPane;\n    }\n    \n//    private static boolean isLwPopupOpen(Component c) {\n//        Container cc = c.getParent();\n//        \n//        for (Container p = cc; p != null; p = p.getParent()) {\n//            if (p instanceof JRootPane) {\n//                if (p.getParent() instanceof JInternalFrame) continue;\n//                cc = ((JRootPane)p).getLayeredPane();\n//                if (cc instanceof JLayeredPane)\n//                    return ((JLayeredPane)cc).getComponentsInLayer(\n//                             JLayeredPane.POPUP_LAYER).length > 0;\n//            } else if (p instanceof Window) {\n//                break;\n//            } else if (p instanceof JApplet) {\n//                break;\n//            }\n//        }\n//        \n//        return false;\n//    }\n    \n    private void showPopups(Component renderer, Rectangle[] popups) {\n        Image img = createPopupImage(renderer);\n        Color border = table.getGridColor();\n        \n        if (popups[POPUP_LEFT] != null) openWindow(popups[POPUP_LEFT], img, POPUP_LEFT, border);\n        else if (windows[POPUP_LEFT] != null) closeWindow(POPUP_LEFT);\n        \n        if (popups[POPUP_RIGHT] != null) openWindow(popups[POPUP_RIGHT], img, POPUP_RIGHT, border);\n        else if (windows[POPUP_RIGHT] != null) closeWindow(POPUP_RIGHT);\n        \n        if (closer == null) {\n            closer = new Closer();\n            closer.install();\n        }\n    }\n    \n    private void hidePopups() {\n        if (windows[POPUP_LEFT] == null && windows[POPUP_RIGHT] == null) return;\n        \n        currentRow = -1;\n        currentColumn = -1;\n        \n        if (windows[POPUP_LEFT] != null) closeWindow(POPUP_LEFT);\n        if (windows[POPUP_RIGHT] != null) closeWindow(POPUP_RIGHT);\n        \n        if (closer != null) {\n            closer.deinstall();\n            closer = null;\n        }\n    }\n    \n    \n    private Image createPopupImage(Component renderer) {\n        int width = renderer.getWidth();\n        int height = renderer.getHeight();\n        \n        Image i = !Platform.isMac() ? table.createVolatileImage(width, height) :\n                  new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);\n        Graphics g = i.getGraphics();\n        \n        try {\n            g.setColor(table.getBackground());\n            g.fillRect(0, 0, width, height);\n            \n            // org.graalvm.visualvm.lib.ui.swing.renderer.Movable.move()\n            renderer.move(0, 0);\n            \n            if (crp == null) crp = new CellRendererPane() {\n                public void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h, boolean v) {\n                    super.paintComponent(g, c, p, x, y, w, h, v);\n                    remove(c); // Prevent leaking ProfilerTreeTable.ProfilerTreeTableTree and transitively all the UI/models\n                }\n            };\n            \n            crp.paintComponent(g, renderer, null, 0, 0, width, height, false);\n        } finally {\n            g.dispose();\n        }\n        \n        return i;\n    }\n    \n    private void openWindow(Rectangle popup, final Image img, int popupId, Color border) {\n        final boolean left = popupId == POPUP_LEFT;\n        \n        final int popupW = popup.width;\n        final int popupH = popup.height;\n        final int imageW = img.getWidth(null);\n        final int imageH = img.getHeight(null);\n        \n        JPanel l = new JPanel(null) {\n            protected void paintComponent(Graphics g) {\n                if (left) g.drawImage(img, 1, 1, 1 + popupW, 1 + popupH, 0, 0, popupW, popupH, null);\n                else      g.drawImage(img, 0, 1, 0 + popupW, 1 + popupH, imageW - popupW, 0, imageW, imageH, null);\n            }\n        };\n        if (left) l.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, border));\n        else      l.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, border));\n        l.setSize(popupW + 1, popupH + 2);\n        \n        JWindow win = windows[popupId];\n        if (win == null) {\n            win = new JWindow(SwingUtilities.getWindowAncestor(table));\n            win.setType(Window.Type.POPUP);\n            win.setFocusable(false);\n            win.setAutoRequestFocus(false);\n            win.setFocusableWindowState(false);\n            win.getContentPane().add(l);\n            \n            // Make sure there's no shadow behind the native window\n            safeSetBackground(win, new Color(255, 255, 255, 0)); // Linux // #269737\n            win.getRootPane().putClientProperty(\"Window.shadow\", Boolean.FALSE.toString()); // macOS // NOI18N\n            \n            win.setVisible(true);\n        } else {\n            win.getContentPane().removeAll();\n            win.getContentPane().add(l);\n            \n            if (win.isVisible()) win.repaint();\n            else win.setVisible(true);\n        }\n        \n        Point p = table.getLocationOnScreen();\n        win.setBounds(popup.x + p.x - (left ? 1 : 0), popup.y + p.y - 1, popupW + 1, popupH + 2);\n        \n        windows[popupId] = win;\n    }\n    \n    private void closeWindow(int index) {\n        windows[index].setVisible(false);\n        windows[index].dispose();\n        windows[index] = null;\n    }\n    \n    // See Window.setBackground() documentation\n    private static void safeSetBackground(JWindow window, Color background) {\n        GraphicsConfiguration gc = window.getGraphicsConfiguration();\n        \n//        if (!gc.isTranslucencyCapable()) return; // PERPIXEL_TRANSLUCENT not supported // doesn't work well with Ubuntu@VirtualBox, handled in catch below\n        if (gc.getDevice().getFullScreenWindow() == window) return; // fullscreen windows not supported\n        \n        // PERPIXEL_TRANSLUCENT not supported, safely ignore\n        try { window.setBackground(background); }\n        catch (UnsupportedOperationException e) {}\n    }\n    \n    \n    private Rectangle[] computePopups(int row, int column, Point point, Component renderer) {\n        Rectangle rendererRect = getRendererRect(column, renderer);\n        if (rendererRect == null) return null;\n        \n        Rectangle cellRect = table.getCellRect(row, column, true);\n        rendererRect.translate(cellRect.x, cellRect.y);\n        cellRect.width -= 1;\n        if (cellRect.contains(rendererRect)) return null; // Value fully visible\n        \n        Rectangle visibleRect = cellRect.intersection(rendererRect);\n        if (!visibleRect.contains(point)) return null; // Value fully invisible\n        \n        // Mouse over partially visible value\n        Rectangle[] ret = new Rectangle[2];\n        \n        if (rendererRect.x < visibleRect.x) {\n            Rectangle left = new Rectangle(rendererRect);\n            left.width = visibleRect.x - left.x;\n            ret[POPUP_LEFT] = left;\n        }\n\n        // rendererRect.x + rendererRect.width *- 1*: workaround for extra space for correctly right-aligned values\n        if (rendererRect.x + rendererRect.width - 1 > visibleRect.x + visibleRect.width) {\n            Rectangle right = new Rectangle(rendererRect);\n            right.x = visibleRect.x + visibleRect.width;\n            right.width = rendererRect.x + rendererRect.width - right.x;\n            ret[POPUP_RIGHT] = right;\n        }\n        \n        return ret;\n    }\n    \n    \n    private Rectangle getRendererRect(int column, Component renderer) {\n        int _column = table.convertColumnIndexToModel(column);\n        \n        // Do not show value hovers for standard renderers shortening values using '...'\n        if (!(renderer instanceof ProfilerRenderer) &&\n            !table.isScrollableColumn(_column))\n                return null;\n        \n        // Do not show value hovers when explicitly disabled\n        if (renderer instanceof JComponent)\n            if (((JComponent)renderer).getClientProperty(ProfilerTable.PROP_NO_HOVER) != null)\n                return null;\n        \n        Rectangle bounds = renderer.getBounds();\n        bounds.x -= table.getColumnOffset(_column);\n        \n        return bounds;\n    }\n    \n    private Component getRenderer(int row, int column) {\n        TableCellRenderer renderer = table.getCellRenderer(row, column);\n        Component _renderer = table.getRenderer(renderer, row, column, true);\n        _renderer.setSize(Math.min(_renderer.getWidth(), MAX_RENDERER_WIDTH), _renderer.getHeight());\n        return _renderer;\n    }\n    \n    \n    private class Opener extends MouseAdapter implements ComponentListener, TableModelListener {\n        \n        void install() {\n            table.addMouseListener(this);\n            table.addMouseMotionListener(this);\n            table.addComponentListener(this);\n            table.getModel().addTableModelListener(this);\n        }\n        void deinstall() {\n            hidePopups();\n            \n            table.removeMouseListener(this);\n            table.removeMouseMotionListener(this);\n            table.removeComponentListener(this);\n            table.getModel().removeTableModelListener(this);\n            \n            currentScreenPoint = null;\n        }\n        \n        // MouseAdapter\n        public void mouseMoved(MouseEvent e) {\n            // Do not display popup when a modifier is pressed (can't read all keys)\n//            if (e.getModifiers() != 0) return;\n            \n            currentScreenPoint = e.getLocationOnScreen();\n            \n            updatePopups(e.getPoint(), false);\n        }\n        \n        public void mouseDragged(MouseEvent e) {\n//            if (e.getModifiers() != 0) return;\n            \n            currentScreenPoint = e.getLocationOnScreen();\n            \n            updatePopups(e.getPoint(), false);\n        }\n        \n        public void mouseExited(MouseEvent e) {\n            hidePopups();\n            currentScreenPoint = null;\n        }\n        \n        // ComponentListener\n        public void componentResized(ComponentEvent e) {} // Lines added/removed to/from table\n        public void componentMoved(ComponentEvent e) { updatePopups(null, false); } // Table scrolled (mouse wheel, gesture)\n        public void componentShown(ComponentEvent e) {}\n        public void componentHidden(ComponentEvent e) {}\n        \n        // TableModelListener\n        public void tableChanged(TableModelEvent e) {\n            // Must invoke later, column widths not ready yet\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { updatePopups(null, true); }\n            });\n        }\n        \n    }\n    \n    private class Closer extends MouseAdapter implements /*TableModelListener,*/ KeyListener,\n                                                         ComponentListener, HierarchyListener,\n                                                         HierarchyBoundsListener, FocusListener,\n                                                         ListSelectionListener {\n        \n//        private Component focusOwner;\n                \n        void install() {\n            table.addMouseListener(this);\n            table.addMouseMotionListener(this);\n            \n//            focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();\n//            if (focusOwner != null) {\n//                focusOwner.addKeyListener(this);\n//                focusOwner.addFocusListener(this);\n//            }\n            \n//            table.getModel().addTableModelListener(this);\n            table.getSelectionModel().addListSelectionListener(this);\n            table.addComponentListener(this);\n            table.addHierarchyListener(this);\n            table.addHierarchyBoundsListener(this);\n        }\n        \n        void deinstall() {\n            table.removeMouseListener(this);\n            table.removeMouseMotionListener(this);\n            \n//            if (focusOwner != null) {\n//                focusOwner.removeKeyListener(this);\n//                focusOwner.removeFocusListener(this);\n//                focusOwner = null;\n//            }\n            \n//            table.getModel().removeTableModelListener(this);\n            table.getSelectionModel().removeListSelectionListener(this);\n            table.removeComponentListener(this);\n            table.removeHierarchyListener(this);\n            table.removeHierarchyBoundsListener(this);\n        }\n        \n        // MouseAdapter\n//        public void mouseExited(MouseEvent e) { hidePopups(); currentScreenPoint = null; }\n//        public void mouseDragged(MouseEvent e) { updatePopups(e.getPoint(), false); }\n//        public void mouseDragged(MouseEvent e) { hidePopups(); }\n//        public void mousePressed(MouseEvent e) { hidePopups(); }\n//        public void mouseReleased(MouseEvent e) { hidePopups(); }\n        public void mousePressed(MouseEvent e) { updatePopups(e.getPoint(), true); }\n        public void mouseReleased(MouseEvent e) { updatePopups(e.getPoint(), true); }\n        \n//        // TableModelListener\n//        public void tableChanged(TableModelEvent e) { updatePopups(null, true); }\n        \n        // ListSelectionListener\n        public void valueChanged(ListSelectionEvent e) { updatePopups(null, true); }\n\n        // KeyListener\n        public void keyTyped(KeyEvent e) { hidePopups(); }\n        public void keyPressed(KeyEvent e) { hidePopups(); }\n        public void keyReleased(KeyEvent e) { hidePopups(); }\n        \n        // ComponentListener\n        public void componentResized(ComponentEvent e) { /*hidePopups();*/ } // Lines added/removed to/from table\n        public void componentMoved(ComponentEvent e) { }  // Table scrolled (mouse wheel, gesture\n        public void componentShown(ComponentEvent e) { hidePopups(); }\n        public void componentHidden(ComponentEvent e) { hidePopups(); currentScreenPoint = null; }\n\n        // HierarchyListener\n        public void hierarchyChanged(HierarchyEvent e) { hidePopups(); }\n        \n        // HierarchyBoundsListener\n        public void ancestorMoved(HierarchyEvent e) { hidePopups(); }\n        public void ancestorResized(HierarchyEvent e) { hidePopups(); }\n        \n        // FocusListener\n        public void focusGained(FocusEvent e) {}\n        public void focusLost(FocusEvent e) { hidePopups(); currentScreenPoint = null; }\n\n        // PropertyChangeListener\n        public void propertyChange(PropertyChangeEvent evt) { hidePopups(); }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/ProfilerTreeTable.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.AWTEvent;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseEvent;\nimport java.awt.image.BufferedImage;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport javax.accessibility.Accessible;\nimport javax.accessibility.AccessibleContext;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JComponent;\nimport javax.swing.JTable;\nimport javax.swing.JTree;\nimport javax.swing.RowFilter;\nimport javax.swing.RowSorter;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.border.Border;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.event.TreeExpansionEvent;\nimport javax.swing.event.TreeExpansionListener;\nimport javax.swing.event.TreeModelEvent;\nimport javax.swing.event.TreeModelListener;\nimport javax.swing.event.TreeSelectionEvent;\nimport javax.swing.event.TreeSelectionListener;\nimport javax.swing.event.TreeWillExpandListener;\nimport javax.swing.plaf.TreeUI;\nimport javax.swing.plaf.basic.BasicTreeUI;\nimport javax.swing.plaf.synth.SynthTreeUI;\nimport javax.swing.table.AbstractTableModel;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumnModel;\nimport javax.swing.table.TableModel;\nimport javax.swing.table.TableRowSorter;\nimport javax.swing.tree.DefaultMutableTreeNode;\nimport javax.swing.tree.DefaultTreeCellRenderer;\nimport javax.swing.tree.DefaultTreeModel;\nimport javax.swing.tree.ExpandVetoException;\nimport javax.swing.tree.TreeCellRenderer;\nimport javax.swing.tree.TreeModel;\nimport javax.swing.tree.TreeNode;\nimport javax.swing.tree.TreePath;\nimport javax.swing.tree.TreeSelectionModel;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.ProfilerRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ProfilerTreeTable extends ProfilerTable {\n    \n    private static final boolean DISABLE_TREEUI_FIX = Boolean.getBoolean(\"ProfilerTreeTable.disableTreeUIFix\"); // NOI18N\n    \n    private final TableModelImpl model;\n    private final ProfilerTreeTableTree tree;\n    \n    \n    public ProfilerTreeTable(ProfilerTreeTableModel model, boolean sortable,\n                             boolean hideableColums, int[] scrollableColumns) {\n        super(new TableModelImpl(model), sortable, hideableColums, scrollableColumns);\n        \n        this.model = (TableModelImpl)getModel();\n        tree = this.model.getTree();\n        \n        Adapter adapter = new Adapter();\n        tree.addTreeSelectionListener(adapter);\n        tree.addTreeExpansionListener(adapter);\n        tree.addTreeWillExpandListener(adapter);\n        tree.getModel().addTreeModelListener(adapter);\n        getSelectionModel().addListSelectionListener(adapter);\n\n        tree.setRowHeight(rowHeight);\n        setDefaultRenderer(JTree.class, tree);\n    }\n    \n    \n    // --- Traversing nodes ---\n    \n    TreePath getRootPath() {\n        return new TreePath(model.treeModel.getRoot());\n    }\n    \n    TreePath getSelectionPath() {\n        return tree.getSelectionPath();\n    }\n    \n    TreePath getNextPath(TreePath path) {\n        return getNextPath(path, true);\n    }\n    \n    TreePath getNextPath(TreePath path, boolean down) {\n        TreeModel _model = model.treeModel;\n        TreeNode node = (TreeNode)path.getLastPathComponent();\n        if (down && _model.getChildCount(node) > 0)\n            return path.pathByAddingChild(_model.getChild(node, 0));\n\n        TreePath parentPath = path.getParentPath();\n        if (!down && parentPath == null)\n            return path.pathByAddingChild(_model.getChild(node, 0));\n        \n        TreeNode parent = (TreeNode)parentPath.getLastPathComponent();\n        int idx = _model.getIndexOfChild(parent, node) + 1;\n\n        if (_model.getChildCount(parent) > idx)\n            return parentPath.pathByAddingChild(_model.getChild(parent, idx));\n\n        if (!down && parentPath.getParentPath() == null) {\n            return parentPath.pathByAddingChild(_model.getChild(parent, 0));\n        } else {\n            return getNextPath(parentPath, false);\n        }\n    }\n    \n    TreePath getPreviousPath(TreePath path) {\n        return getPreviousPath(path, true);\n    }\n    \n    TreePath getPreviousPath(TreePath path, boolean down) { // TODO: optimize the algorithm to use 'down'\n        TreeModel _model = model.treeModel;\n        TreeNode node = (TreeNode)path.getLastPathComponent();\n        TreePath parentPath = path.getParentPath();\n        if (parentPath == null) parentPath = path;\n        TreeNode parent = (TreeNode)parentPath.getLastPathComponent();\n        int idx = parent == node ? parent.getChildCount() : _model.getIndexOfChild(parent, node);\n\n        if (idx == 0) {\n            if (parent != model.treeModel.getRoot()) return parentPath;\n            else idx = parent.getChildCount();\n        }\n        \n        node = (TreeNode)_model.getChild(parent, idx - 1);\n        path = parentPath.pathByAddingChild(node);\n\n        if (down) while (_model.getChildCount(node) != 0) {\n            node = (TreeNode)_model.getChild(node, _model.getChildCount(node) - 1);\n            path = path.pathByAddingChild(node);\n        }\n\n        return path;\n    }\n    \n    public void selectPath(TreePath path, boolean scrollToVisible) {\n        internal = true;\n        markExpansionTransaction();\n        try {\n//            tree.expandPath(path); // actually should not be needed, automatically expands the node further down\n            tree.setSelectionPath(path);\n            // Clear and select again to make sure the underlying tree is ready\n            tree.setSelectionPath(null);\n            tree.setSelectionPath(path);\n        } finally {\n            clearExpansionTransaction();\n            internal = false;\n        }\n        \n        if (scrollToVisible) {\n            Rectangle bounds = tree.getPathBounds(path);\n            if (bounds != null) scrollRectToVisible(bounds);\n        }\n    }\n    \n    // ---\n    \n    \n    public TreePath getPathForRow(int row) {\n        return tree.getPathForRow(row);\n    }\n    \n    public TreeNode getValueForRow(int row) {\n        if (row == -1) return null;\n        return model.nodeForRow(row);\n    }\n    \n    \n    public void setRowHeight(int rowHeight) {\n        super.setRowHeight(rowHeight);\n        if (tree != null) tree.setRowHeight(rowHeight);\n    }\n    \n    \n    public void setShowsRootHandles(boolean newValue) {\n        if (tree != null) tree.setShowsRootHandles(newValue);\n    }\n    \n    public boolean getShowsRootHandles() {\n        return tree != null && tree.getShowsRootHandles();\n    }\n    \n    public void setRootVisible(boolean rootVisible) {\n        if (tree != null) tree.setRootVisible(rootVisible);\n    }\n    \n    public boolean isRootVisible() {\n        return tree != null && tree.isRootVisible();\n    }\n    \n    \n    private void markExpansionTransaction() {\n        tree.putClientProperty(UIUtils.PROP_EXPANSION_TRANSACTION, Boolean.TRUE);\n    }\n    \n    private void clearExpansionTransaction() {\n        tree.putClientProperty(UIUtils.PROP_EXPANSION_TRANSACTION, null);\n        \n        TreePath[] selectedPaths = tree.getSelectionPaths();\n        model.fireTableDataChanged();\n        tree.setSelectionPaths(selectedPaths);\n    }\n    \n    public void collapseChildren(int row) {\n        if (tree != null) try {\n            markExpansionTransaction();\n            \n            TreePath tpath = tree.getPathForRow(row);\n            if (tpath == null || tree.isCollapsed(tpath)) return;\n            \n            TreeModel tmodel = tree.getModel();\n            Object selected = tpath.getLastPathComponent();\n            \n            int nchildren = tmodel.getChildCount(selected);\n            for (int i = 0; i < nchildren; i++)\n                tree.collapsePath(tpath.pathByAddingChild(tmodel.getChild(selected, i)));\n        \n        } finally {\n            clearExpansionTransaction();\n        }\n    }\n    \n    public void collapseChildren(TreePath tpath) {\n        if (tree != null) try {\n            markExpansionTransaction();\n            \n            if (tpath == null || tree.isCollapsed(tpath)) return;\n            \n            TreeModel tmodel = tree.getModel();\n            Object selected = tpath.getLastPathComponent();\n            \n            int nchildren = tmodel.getChildCount(selected);\n            for (int i = 0; i < nchildren; i++) {\n                TreePath tp = tpath.pathByAddingChild(tmodel.getChild(selected, i));\n                tree.collapsePath(tp);\n//                tree.resetExpandedState(tp);\n            }\n        \n        } finally {\n            clearExpansionTransaction();\n        }\n    }\n    \n    public void collapseAll() {\n        if (tree != null) try {\n            markExpansionTransaction();\n            \n            TreePath selected = tree.getSelectionPath();\n            if (selected != null && selected.getPathCount() > 2) {\n                tree.setSelectionPath(new TreePath(new Object[] {\n                    selected.getPathComponent(0), selected.getPathComponent(1)\n                }));\n            }\n            \n            TreeModel tmodel = tree.getModel();\n            Object root = tmodel.getRoot();\n            \n            int nchildren = tmodel.getChildCount(root);\n            for (int i = 0; i < nchildren; i++)\n                tree.collapsePath(new TreePath(new Object[] {\n                    root, tmodel.getChild(root, i)\n                }));\n            \n            tree.resetExpandedNodes();\n        \n        } finally {\n            clearExpansionTransaction();\n        }\n    }\n    \n    public void expandPlainPath(int row, int maxChildren) {\n        if (tree != null) try {\n            markExpansionTransaction();\n            \n            TreePath tpath = tree.getPathForRow(row);\n            if (tpath == null) return;\n            \n            TreeModel tmodel = tree.getModel();            \n            int childCount = tmodel.getChildCount(tpath.getLastPathComponent());\n        \n            while (childCount > 0 && childCount <= maxChildren) {\n                tpath = tpath.pathByAddingChild(tmodel.getChild(tpath.getLastPathComponent(), 0));\n                childCount = tmodel.getChildCount(tpath.getLastPathComponent());\n            }\n\n            tree.putClientProperty(UIUtils.PROP_AUTO_EXPANDING, Boolean.TRUE);\n            try { tree.expandPath(tpath); selectPath(tpath, true); }\n            finally { tree.putClientProperty(UIUtils.PROP_AUTO_EXPANDING, null); }\n            \n        } finally {\n            clearExpansionTransaction();\n        }\n    }\n    \n    public void expandFirstPath(int row) {\n        if (tree != null) try {\n            markExpansionTransaction();\n\n            TreePath tpath = tree.getPathForRow(row);\n            if (tpath == null) return;\n\n            TreeModel tmodel = tree.getModel();    \n\n            while (tmodel.getChildCount(tpath.getLastPathComponent()) > 0)\n                tpath = tpath.pathByAddingChild(tmodel.getChild(tpath.getLastPathComponent(), 0));\n\n            tree.putClientProperty(UIUtils.PROP_AUTO_EXPANDING, Boolean.TRUE);\n            try { selectPath(tpath, true); }\n            finally { tree.putClientProperty(UIUtils.PROP_AUTO_EXPANDING, null); }\n\n        } finally {\n            clearExpansionTransaction();\n        }\n    }\n    \n    public void expandPath(TreePath path) {\n        if (tree != null) try {\n            markExpansionTransaction();\n\n            tree.putClientProperty(UIUtils.PROP_AUTO_EXPANDING, Boolean.TRUE);\n            try { tree.expandPath(path); }\n            finally { tree.putClientProperty(UIUtils.PROP_AUTO_EXPANDING, null); }\n\n        } finally {\n            clearExpansionTransaction();\n        }\n    }\n    \n    public void expandRow(int row) {\n        if (tree != null) try {\n            markExpansionTransaction();\n\n            tree.putClientProperty(UIUtils.PROP_AUTO_EXPANDING, Boolean.TRUE);\n            try { tree.expandRow(row); }\n            finally { tree.putClientProperty(UIUtils.PROP_AUTO_EXPANDING, null); }\n\n        } finally {\n            clearExpansionTransaction();\n        }\n    }\n    \n    public void makeTreeAutoExpandable(int maxChildToExpand) {\n        if (tree != null) UIUtils.makeTreeAutoExpandable(tree, maxChildToExpand);\n    }\n    \n    protected void nodeExpanding(TreeNode node) {}\n    \n    protected void nodeExpanded(TreeNode node) {}\n    \n    protected void nodeCollapsing(TreeNode node) {}\n    \n    protected void nodeCollapsed(TreeNode node) {}\n    \n    public void setForgetPreviouslyExpanded(boolean ignorePreviouslyExpanded) {\n        tree.setForgetPreviouslyExpanded(ignorePreviouslyExpanded);\n    }\n    \n    public Enumeration<TreePath> getExpandedNodes() {\n        return tree == null ? null : tree.getExpandedDescendants(new TreePath(tree.getModel().getRoot()));\n    }\n    \n    public void clearExpandedNodes(Enumeration<TreePath> nodes) {\n        if (tree != null) {\n            tree.removeDescendantToggledPaths(nodes);\n            tree.updateUI();\n        }\n    }\n    \n    public void resetExpandedNodes() {\n        if (tree != null) tree.resetExpandedNodes();\n    }\n    \n    public void resetPath(TreePath path) {\n        if (tree != null) ((SortedFilteredTreeModel)tree.getModel()).clearPath(path);\n    }\n    \n    public DefaultTreeModel getTreeModel() {\n        return tree == null ? null : (DefaultTreeModel)tree.getModel();\n    }\n    \n//    public void resetTreeUI() {\n//        tree.updateUI();\n//    }\n    \n    public static abstract class NodeExpansionEvaluator {\n        \n        public abstract Boolean hasBeenExpanded(TreePath path);\n        \n    }\n    \n    public static interface DeleteNodes {}\n    \n    public void setCellRenderer(TreeCellRenderer renderer) {\n        if (tree != null) {\n            tree.setCellRenderer(renderer);\n            model.setRenderer(renderer);\n        }\n    }\n    \n    public void setTreeCellRenderer(ProfilerRenderer renderer) {\n        setCellRenderer(createTreeCellRenderer(renderer));\n    }\n    \n    public static TreeCellRenderer createTreeCellRenderer(final ProfilerRenderer renderer) {\n        return new ProfilerRendererWrapper(renderer);\n    }\n    \n    Component getRenderer(TableCellRenderer renderer, int row, int column, boolean sized) {\n        Component comp = super.getRenderer(renderer, row, column, sized);\n        \n        if (sized && JTree.class.equals(getColumnClass(column))) {\n            Rectangle bounds = tree.getRowBounds(row);\n            comp.setBounds(bounds.x, 0, bounds.width, comp.getHeight());\n        }\n        \n        return comp;\n    }\n    \n    \n    private static class ProfilerRendererWrapper implements TreeCellRenderer, ProfilerRenderer {\n        \n        private final ProfilerRenderer renderer;\n        \n        ProfilerRendererWrapper(ProfilerRenderer renderer) { this.renderer = renderer; }\n        \n        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {\n            setValue(value, row); // NOTE: should use table.convertRowIndexToModel(row)\n            JComponent comp = getComponent();\n            comp.setOpaque(false);\n            if (tree != null) {\n                comp.setForeground(tree.getForeground());\n                comp.setBackground(tree.getBackground());\n            }\n            return comp;\n        }\n        \n        public void setValue(Object value, int row) { renderer.setValue(value, row); }\n    \n        public int getHorizontalAlignment() { return renderer.getHorizontalAlignment(); }\n\n        public JComponent getComponent() { return renderer.getComponent(); }\n        \n        public void move(int x, int y) { renderer.move(x, y); }\n        \n        public String toString() { return renderer.toString(); }\n\n        public AccessibleContext getAccessibleContext() { return renderer.getAccessibleContext(); }\n        \n    }\n    \n    \n    protected void processKeyEvent(KeyEvent e) {\n        tree.dispatchEvent(e);\n        if (!e.isConsumed()) super.processKeyEvent(e);\n    }\n\n    protected void processMouseEvent(MouseEvent e) {\n        MouseEvent treeEvent = null;\n        \n        if (e != null) {\n            Point point = e.getPoint();\n            int column = columnAtPoint(point);\n            \n            if (column != -1 && getColumnClass(column) == JTree.class) {\n                int row = rowAtPoint(point);\n                Rectangle treeCellRect = tree.getRowBounds(row);\n                \n                if (treeCellRect != null) {\n                    Rectangle tableCellRect = getCellRect(row, column, true);\n                    int _column = convertColumnIndexToModel(column);\n                    int treeX = point.x - tableCellRect.x + getColumnOffset(_column);\n                    if (treeX > treeCellRect.x) treeX = treeCellRect.x + treeCellRect.width / 2;\n                    treeEvent = new MouseEvent(tree, e.getID(), e.getWhen(),\n                                               e.getModifiers(), treeX, e.getY(),\n                                               e.getClickCount(), e.isPopupTrigger());\n                    \n                    // Prevent invoking default action on expanding a node\n                    TreeNode value = getValueForRow(row);\n                    if (value != null && !value.isLeaf()) e = clearClicks(e);\n                }\n            }\n        }\n        \n        super.processMouseEvent(e);\n        if (treeEvent != null) tree.dispatchEvent(treeEvent);\n    }\n    \n    \n    public void addRowFilter(RowFilter filter) {\n        super.addRowFilter(filter);\n        refreshFilter();\n    }\n    \n    public void removeRowFilter(RowFilter filter) {\n        super.removeRowFilter(filter);\n        refreshFilter();\n    }\n    \n    public void setRowFilter(RowFilter filter) {\n        super.setRowFilter(filter);\n        refreshFilter();\n    }\n    \n    private void refreshFilter() {\n        model.filter(_getRowSorter().getRowFilter());\n    }\n    \n    \n    public Comparator getCurrentComparator() {\n        return model.getComparator();\n    }\n    \n    \n    // --- String value --------------------------------------------------------\n    \n    // column - view index\n    public String getStringValue(TreeNode node, int column) {\n        Object value = model.getValueAt(node, convertColumnIndexToModel(column));\n        if (getColumnClass(column) == JTree.class) {\n            TreeCellRenderer renderer = tree.getCellRenderer();\n            renderer.getTreeCellRendererComponent(tree, value, false, false, false, -1, false);\n            return renderer.toString();\n        } else {\n            TableCellRenderer renderer = getCellRenderer(-1, column);\n            if (renderer instanceof ProfilerRenderer) {\n                ((ProfilerRenderer)renderer).setValue(value, -1);\n            } else {\n                renderer.getTableCellRendererComponent(this, value, false, false, -1, column);\n            }\n            return renderer.toString();\n        }\n    }\n    \n    \n    protected TableRowSorter createRowSorter() {\n        ProfilerRowSorter s = new ProfilerTreeTableSorter(getModel()) {\n            public void allRowsChanged() {\n                // Must invoke later, JTree.getRowCount() not ready yet\n                SwingUtilities.invokeLater(ProfilerTreeTable.this::updateColumnsPreferredWidth);\n            }\n            protected void setSortKeysImpl(List newKeys) {\n                // TODO: Improve to not call createComparator(newKeys) here and from super\n                willBeSorted(Collections.unmodifiableList(newKeys));\n                super.setSortKeysImpl(newKeys);\n            }\n        };\n        s.setDefaultSortOrder(SortOrder.DESCENDING);\n        s.setDefaultSortOrder(0, SortOrder.ASCENDING);\n//        s.setSortColumn(0);\n        return s;\n    }\n    \n    protected void willBeSorted(List<? extends RowSorter.SortKey> sortKeys) {}\n    \n    private static class ProfilerTreeTableSorter extends ProfilerRowSorter {\n        \n        private final TableModelImpl model;\n        private List<RowSorter.SortKey> sortKeys;\n        \n        private boolean sorting;\n        \n        ProfilerTreeTableSorter(TableModel model) {\n            super(model);\n            this.model = (TableModelImpl)model;\n        }\n        \n        public int convertRowIndexToModel(int index) {\n            return index;\n        }\n        \n        public int convertRowIndexToView(int index) {\n            return index;\n        }\n        \n        public int getViewRowCount() {\n            return model.getRowCount();\n        }\n        \n        public int getModelRowCount() {\n            return model.getRowCount();\n        }\n        \n        public void sort() {\n            sorting = true;\n            super.sort();\n            sorting = false;\n        }\n        \n        public RowFilter getRowFilter() {\n            return sorting ? null : super.getRowFilter();\n        }\n        \n        protected void setSortKeysImpl(List newKeys) {\n            sortKeys = newKeys == null ? Collections.emptyList() :\n                       Collections.unmodifiableList(new ArrayList(newKeys));\n//            long start = System.currentTimeMillis();\n            model.sort(createComparator(newKeys));\n//            System.err.println(\">>> Sorted in \" + (System.currentTimeMillis() - start));\n//            Thread.dumpStack();\n        }\n        \n        public List<? extends RowSorter.SortKey> getSortKeys() {\n            return sortKeys;\n        }\n        \n        protected Comparator createComparator(List<RowSorter.SortKey> sortKeys) {\n            if (sortKeys == null || sortKeys.isEmpty()) return null;\n            \n            SortKey sortKey = sortKeys.get(0);\n            SortOrder sortOrder = sortKey.getSortOrder();\n            if (SortOrder.UNSORTED.equals(sortOrder)) return null;\n            \n            final boolean ascending = SortOrder.ASCENDING.equals(sortOrder);\n            final int sortColumn = sortKey.getColumn();\n            \n            Class<?> columnClass = model.getColumnClass(sortColumn);\n            final Comparator comp = JTree.class.equals(columnClass) ? null : \n                    (Comparable.class.isAssignableFrom(columnClass) ? new Comparator() {\n                        public int compare(Object o1, Object o2) {\n                            return ((Comparable)o1).compareTo(o2);\n                        }\n                    } : getComparator(sortColumn));\n            \n//            System.err.println(\">>> ascending: \" + ascending);\n//            System.err.println(\">>> sortColumn: \" + sortColumn);\n//            System.err.println(\">>> columnClass: \" + columnClass + \" - name: \" + model.getColumnName(sortColumn));\n            \n            return new Comparator() {\n                public int compare(Object o1, Object o2) {\n                    int result;\n                    \n                    if (o1 instanceof CCTNode.FixedPosition) {\n                        result = o1 instanceof CCTNode.AlwaysFirst ? -1 : 1;\n                        result = ascending ? result : -result;\n                    } else if (o2 instanceof CCTNode.FixedPosition) {\n                        result = o2 instanceof CCTNode.AlwaysFirst ? 1 : -1;\n                        result = ascending ? result : -result;\n                    } else if (comp == null) {\n                        result = o1.toString().compareTo(o2.toString());\n                    } else {\n                        Object v1 = model.getValueAt((TreeNode)o1, sortColumn);\n                        Object v2 = model.getValueAt((TreeNode)o2, sortColumn);\n                        \n                        if (v1 == v2) result = 0;\n                        else if (v1 == null) result = -1;\n                        else if (v2 == null) result = 1;\n                        else result = comp.compare(v1, v2);\n                    }\n                    \n                    return ascending ? result : result * -1;\n                }\n            };\n        }\n        \n//        private Comparator getComparator() {\n//            SortOrder sortOrder = getSortOrder();\n//            if (SortOrder.UNSORTED.equals(sortOrder)) return null;\n//            \n//            final boolean ascending = SortOrder.ASCENDING.equals(sortOrder);\n//            final int sortColumn = getSortColumn();\n//            Class columnClass = model.getColumnClass(sortColumn);\n//            final boolean sortingTree = JTree.class.equals(columnClass);\n//            final Comparator comparator = sortingTree ? null : \n//                    (Comparable.class.isAssignableFrom(columnClass) ? new Comparator() {\n//                        public int compare(Object o1, Object o2) {\n//                            return ((Comparable)o1).compareTo(o2);\n//                        }\n//                    } : getComparator(sortColumn));\n////            Class columnClass = model.getColumnClass(sortColumn);\n////            boolean sortingStrings = JTree.class.equals(columnClass) || String.class.equals(columnClass);\n////            final Comparator comparator = sortingStrings ? null : getComparator(sortColumn);\n//            \n//            return new Comparator() {\n//                public int compare(Object o1, Object o2) {\n//                    int result;\n//                    \n//                    if (sortingTree) {\n//                        result = o1.toString().compareTo(o2.toString());\n//                    } else {\n//                        Object v1 = model.getValueAt((TreeNode)o1, sortColumn);\n//                        Object v2 = model.getValueAt((TreeNode)o2, sortColumn);\n//                        \n//                        if (v1 == v2) result = 0;\n//                        else if (v1 == null) result = -1;\n//                        else if (v2 == null) result = 1;\n//                        else result = comparator.compare(v1, v2);\n//                    }\n//                    \n//                    return ascending ? result : result * -1;\n//                }\n//            };\n//        }\n        \n    }\n    \n    \n    private static class TableModelImpl extends AbstractTableModel {\n        \n        private final ProfilerTreeTableTree tree;\n        private SortedFilteredTreeModel treeModel;\n        private final ProfilerTreeTableModel treeTableModel;\n        \n        TableModelImpl(final ProfilerTreeTableModel model) {\n            this.treeTableModel = model;\n            \n            treeModel = treeModelImpl(model.getRoot(), null, null);\n            \n            model.addListener(new ProfilerTreeTableModel.Adapter() {\n                public void dataChanged() {\n                    fireTableDataChanged();\n                }\n                public void structureChanged() {\n                    treeModel.reload();\n//                    fireTableDataChanged();\n                }\n                public void childrenChanged(TreeNode node) {\n//                    System.err.println(\">>>      Firing nodeStructureChanged to the tree...\");\n                    treeModel.reload(node);\n//                    System.err.println(\">>>      Fired nodeStructureChanged to the tree.\");\n//                    fireTableDataChanged();\n                }\n                public void rootChanged(TreeNode oldRoot, TreeNode newRoot) {\n                    // NOTE: would be cleaner to change root of existing model,\n                    //       wasn't able to easily resolve all related problems.\n//                    treeModel.setRoot(newRoot);\n                    \n                    tree.setChangingModel(true);\n                    \n                    try {\n                        UIState uiState = getUIState(tree);\n\n                        Comparator comparator = treeModel != null ? treeModel.getComparator() : null;\n                        RowFilter filter = treeModel != null ? treeModel.getFilter() : null;\n                        treeModel = treeModelImpl(newRoot, comparator, filter);\n                        tree.setModel(treeModel);\n                        if (uiState != null) restoreExpandedNodes(tree, uiState);\n                        fireTableDataChanged(); // Clears selection\n                        if (uiState != null) restoreSelectedNodes(tree, uiState);\n                    } finally {\n                        tree.setChangingModel(false);\n                    }\n                }\n            });\n                    \n            tree = new ProfilerTreeTableTree(treeModel);\n        }\n        \n        private SortedFilteredTreeModel treeModelImpl(TreeNode root, Comparator comparator, RowFilter filter) {\n            return new SortedFilteredTreeModel(root, tree == null ? null : tree.getCellRenderer(), comparator, filter) {\n                protected void fireTreeStructureChanged(Object source, Object[] path,\n                                        int[] childIndices,\n                                        Object[] children) {\n                    UIState uiState = tree == null ? null : getUIState(tree);\n                    super.fireTreeStructureChanged(source, path, childIndices, children);\n                    if (uiState != null) restoreExpandedNodes(tree, uiState);\n                    fireTableDataChanged(); // Clears selection\n                    if (uiState != null) restoreSelectedNodes(tree, uiState);\n                }\n            };\n        }\n        \n        \n        void sort(Comparator comparator) {\n            treeModel.setComparator(comparator);\n        }\n        \n        Comparator getComparator() {\n            return treeModel.getComparator();\n        }\n        \n        void filter(RowFilter filter) {\n            treeModel.setFilter(filter);\n        }\n        \n        RowFilter getFilter() {\n            return treeModel.getFilter();\n        }\n        \n        void setRenderer(TreeCellRenderer renderer) {\n            treeModel.setRenderer(renderer);\n        }\n        \n        \n        ProfilerTreeTableTree getTree() {\n            return tree;\n        }\n        \n        TreeNode nodeForRow(int rowIndex) {\n            TreePath path = tree.getPathForRow(rowIndex);\n            return path == null ? null : (TreeNode)path.getLastPathComponent();\n        }\n        \n        public int getRowCount() {\n            return tree.getRowCount();\n        }\n\n        public int getColumnCount() {\n            return treeTableModel.getColumnCount();\n        }\n        \n        public String getColumnName(int columnIndex) {\n            return treeTableModel.getColumnName(columnIndex);\n        }\n        \n        public Class getColumnClass(int columnIndex) {\n            return treeTableModel.getColumnClass(columnIndex);\n        }\n        \n        public boolean isCellEditable(int rowIndex, int columnIndex) {\n            TreeNode node = nodeForRow(rowIndex);\n            return node == null ? false : treeTableModel.isCellEditable(node, columnIndex);\n        }\n\n        public Object getValueAt(int rowIndex, int columnIndex) {\n            TreeNode node = nodeForRow(rowIndex);\n            return node == null ? null : treeTableModel.getValueAt(node, columnIndex);\n        }\n        \n        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {\n            TreeNode node = nodeForRow(rowIndex);\n            if (node != null) treeTableModel.setValueAt(aValue, node, columnIndex);\n        }\n        \n        Object getValueAt(TreeNode node, int column) {\n            return treeTableModel.getValueAt(node, column);\n        }\n        \n    }\n    \n    \n    private static class FilteredTreeModel extends DefaultTreeModel {\n        \n        private TreeCellRenderer renderer;\n        \n        private RowFilter filter;\n        private Map<TreePathKey, List> cache;\n        \n        FilteredTreeModel(TreeNode root, TreeCellRenderer r, RowFilter f) {\n            super(root);\n            renderer = r;\n            filter = f;\n        }\n        \n        void setRenderer(TreeCellRenderer r) {\n            renderer = r;\n            reload();\n        }\n        \n        TreeCellRenderer getRenderer() {\n            return renderer;\n        }\n        \n        void setFilter(RowFilter f) {\n            filter = f;\n            reload();\n        }\n        \n        RowFilter getFilter() {\n            return filter;\n        }\n        \n        public Object getChild(Object parent, int index) {\n            if (renderer == null || filter == null) return super.getChild(parent, index);\n            return filteredChildren(parent).get(index);\n        }\n        \n        public int getIndexOfChild(Object parent, Object child) {\n            if (renderer == null || filter == null) return super.getIndexOfChild(parent, child);\n            return filteredChildren(parent).indexOf(child);\n        }\n        \n        public int getChildCount(Object parent) {\n            if (renderer == null || filter == null) return super.getChildCount(parent);\n            return filteredChildren(parent).size();\n        }\n        \n        \n        void clearPath(TreePath path) {\n            clearKey(null);\n//            clearKey(new TreePathKey(getPath(path)));\n        }\n        \n//        private TreeNode[] getPath(TreePath path) {\n//            int i = path.getPathCount();\n//            TreeNode[] result = new TreeNode[i--];\n//\n//            for(TreePath tp = path; tp != null; tp = tp.getParentPath())\n//                result[i--] = (TreeNode)tp.getLastPathComponent();\n//            \n//            return result;\n//        }\n        \n        protected void clearKey(TreePathKey key) {\n            cache = null;\n//            if (cache != null) cache.remove(key);\n        }\n        \n        \n        protected void fireTreeStructureChanged(Object source, Object[] path,\n                                                int[] childIndices,\n                                                Object[] children) {\n            cache = null;\n            super.fireTreeStructureChanged(source, path, childIndices, children);\n        }\n        \n        \n        private List filteredChildren(Object parent) {\n            if (cache == null) cache = new HashMap();\n            \n            boolean createFilteredNode = !(filter instanceof DeleteNodes);\n            TreeNode tParent = (TreeNode)parent;\n            TreePathKey parentKey = new TreePathKey(getPathToRoot(tParent));\n            List children = cache.get(parentKey);\n            \n            if (children == null) {\n                FilterEntry entry = null;\n                \n                children = new ArrayList(tParent.getChildCount());\n                CCTNode filtered = null;\n                Enumeration childrenE = tParent.children();\n                if (childrenE != null) while (childrenE.hasMoreElements()) {\n                    Object child = childrenE.nextElement();\n                    renderer.getTreeCellRendererComponent(null, child, false, false, false, -1, false);\n                    if (entry == null) entry = new FilterEntry(renderer.toString(), child);\n                    else entry.setContext(renderer.toString(), child);\n                    if (filter.include(entry)) {\n                        children.add(child);\n                    } else if (createFilteredNode && parent instanceof CCTNode) {\n                        if (filtered == null) filtered = ((CCTNode)child).createFilteredNode();\n                        else filtered.merge((CCTNode)child);\n                    }\n                }\n                \n                if (filtered != null) {\n                    List filteredChildren = filteredChildren(filtered);\n                    if (!((CCTNode)parent).isFiltered()) children.add(filtered);\n                    else if (!children.isEmpty()) children.add(filtered);\n                    else children.addAll(filteredChildren);\n                }\n                \n                cache.put(parentKey, children);\n            }\n            \n            return children;\n        }\n        \n        \n        // NOTE: use the alternative implementation if facing StackOverflows\n//        public TreeNode[] getPathToRoot(TreeNode node) {\n//            List<TreeNode> path = new ArrayList();\n//            while (node != null) {\n//                path.add(node);\n//                node = node.getParent();\n//            }\n//            return path.toArray(new TreeNode[0]);\n//        }\n        \n    }\n    \n    private static final class FilterEntry extends RowFilter.Entry {\n        private Object value; private Object identifier;\n        FilterEntry(Object _value, Object _identifier) { value = _value; identifier = _identifier; }\n        void setContext(Object _value, Object _identifier) { value = _value; identifier = _identifier; }\n        public Object getValue(int index) { return value; }\n        public Object getModel() { return null; }\n        public int getValueCount() { return 1; }\n        public Object getIdentifier() { return identifier; }\n    }\n    \n    \n    private static class SortedFilteredTreeModel extends FilteredTreeModel {\n        \n        private Comparator comparator;\n        private Map<TreePathKey, int[]> viewToModel;\n        \n        \n        SortedFilteredTreeModel(TreeNode root, TreeCellRenderer r, Comparator comp, RowFilter filter) {\n            super(root, r, filter);\n            comparator = comp;\n        }\n        \n        \n        void setComparator(Comparator comp) {\n            comparator = comp;\n            reload();\n        }\n        \n        Comparator getComparator() {\n            return comparator;\n        }\n        \n        \n        public Object getChild(Object parent, int index) {\n            if (comparator == null || parent instanceof CCTNode.DoNotSortChildren) return super.getChild(parent, index);\n            return super.getChild(parent, viewToModel(parent)[index]);\n        }\n        \n        public int getIndexOfChild(Object parent, Object child) {\n            if (comparator == null || parent instanceof CCTNode.DoNotSortChildren) return super.getIndexOfChild(parent, child);\n            \n            int index = super.getIndexOfChild(parent, child);\n            int[] indexes = viewToModel(parent);\n            for (int i = 0; i < indexes.length; i++)\n                if (indexes[i] == index) return i;\n            \n            return -1;\n        }\n        \n        \n        protected void clearKey(TreePathKey key) {\n            super.clearKey(key);\n            viewToModel = null;\n//            if (viewToModel != null) viewToModel.remove(key);\n        }\n        \n        \n        protected void fireTreeStructureChanged(Object source, Object[] path,\n                                                int[] childIndices,\n                                                Object[] children) {\n            viewToModel = null;\n//            System.err.println(\">>> CLEARING MODEL <<<\");\n            super.fireTreeStructureChanged(source, path, childIndices, children);\n        }\n        \n        \n        private int[] viewToModel(Object parent) {\n            if (viewToModel == null) viewToModel = new HashMap();\n            \n            TreePathKey parentKey = new TreePathKey(getPathToRoot((TreeNode)parent));\n            int[] indexes = viewToModel.get(parentKey);\n            \n            if (indexes == null) {\n                Object[] children = new Object[super.getChildCount(parent)];\n                for (int i = 0; i < children.length; i++)\n                    children[i] = super.getChild(parent, i);\n                Arrays.sort(children, comparator);\n                indexes = new int[children.length];\n                for (int i = 0; i < indexes.length; i++)\n                    indexes[i] = super.getIndexOfChild(parent, children[i]);\n                viewToModel.put(parentKey, indexes);\n            }\n            \n            return indexes;\n        }\n        \n    }\n    \n    private static final class TreePathKey {\n        \n        private final TreeNode[] pathToRoot;\n        private int hashCode;\n\n        TreePathKey(TreeNode[] _pathToRoot) {\n            pathToRoot = _pathToRoot;\n            \n            hashCode = 1;\n            for (TreeNode node : pathToRoot)\n                hashCode = 31 * hashCode + node.hashCode();\n            \n//            hashCode = Arrays.deepHashCode(pathToRoot);\n        }\n\n        public final int hashCode() {\n            return hashCode;\n        }\n        \n        public final boolean equals(Object o) {\n            if (o == this) return true;\n            if (!(o instanceof TreePathKey)) return false;\n            \n            TreeNode[] _pathToRoot = ((TreePathKey)o).pathToRoot;\n            if (pathToRoot.length != _pathToRoot.length) return false;\n            for (int i = pathToRoot.length - 1; i >= 0 ; i--)\n                if (!pathToRoot[i].equals(_pathToRoot[i])) return false;\n            \n            return true;\n        }\n\n    }\n    \n    \n    protected void saveSelection() {}\n    \n    protected void restoreSelection() {}\n    \n    static UIState getUIState(JTree tree) {\n        TreePath[] selectedPaths = tree.getSelectionPaths();\n        TreePath rootPath = new TreePath(tree.getModel().getRoot());\n        Enumeration<TreePath> expandedPaths = tree.getExpandedDescendants(rootPath);\n        return new UIState(selectedPaths, expandedPaths);\n    }\n    \n    static void restoreExpandedNodes(JTree tree, UIState uiState) {\n        try {\n            tree.putClientProperty(UIUtils.PROP_EXPANSION_TRANSACTION, Boolean.TRUE);\n            Enumeration<TreePath> paths = uiState.getExpandedPaths();\n            if (paths != null) while (paths.hasMoreElements()) {\n                TreePath tp = paths.nextElement();\n//                System.err.println(\">>> Restoring expanded \" + tp);\n                tree.expandPath(getSimilarPath(tp, tree.getModel()));\n            }\n        } catch (Exception e) {\n            System.err.println(\">>> Exception in ProfilerTreeTable.restoreExpandedNodes: \" + e.getMessage());\n            e.printStackTrace();\n        } finally {\n            tree.putClientProperty(UIUtils.PROP_EXPANSION_TRANSACTION, null);\n        }\n    }\n    \n    static void restoreSelectedNodes(JTree tree, UIState uiState) {\n        try {\n            TreePath[] sel = uiState.getSelectedPaths();\n\n            if (sel != null)\n                for (int i = 0; i < sel.length; i++)\n                    sel[i] = getSimilarPath(sel[i], tree.getModel());\n            tree.setSelectionPaths(sel);\n        } catch (Exception e) {\n            System.err.println(\">>> Exception in ProfilerTreeTable.restoreSelectedNodes: \" + e.getMessage());\n            e.printStackTrace();\n        }\n    }\n    \n    \n    protected UIState getUIState() {\n        return tree == null ? null : getUIState(tree);\n    }\n    \n    protected void restoreExpandedNodes(UIState uiState) {\n        if (tree != null) restoreExpandedNodes(tree, uiState);\n    }\n    \n    protected void restoreSelectedNodes(UIState uiState) {\n        if (tree != null) restoreSelectedNodes(tree, uiState);\n    }\n    \n    \n    private static TreePath getSimilarPath(TreePath oldPath, TreeModel currentModel) {\n        if (oldPath == null || oldPath.getPathCount() < 1) return null;\n\n//        TreeModel currentModel = getModel();\n        Object currentRoot = currentModel.getRoot();\n        if (!currentRoot.equals(oldPath.getPathComponent(0))) return null;\n\n        TreePath p = new TreePath(currentRoot);\n        Object[] op = oldPath.getPath();\n        Object n = currentRoot;\n\n        for (int i = 1; i < op.length; i++) {\n            Object nn = null;\n\n            for (int ii = 0; ii < currentModel.getChildCount(n); ii++) {\n                Object c = currentModel.getChild(n, ii);\n                if (c.equals(op[i])) {\n                    nn = c;\n                    break;\n                }\n            }\n\n            if (nn == null) return null;\n\n            n = nn;\n            p = p.pathByAddingChild(n);\n        }\n//        System.err.println(\">>> Similar path for \" + oldPath + \" is \" + p);\n        return p;\n    }\n    \n    \n    protected static class UIState {\n        \n        private final TreePath[] selectedPaths;\n        private final Enumeration<TreePath> expandedPaths;\n        \n        \n        UIState(TreePath[] selectedPaths, Enumeration<TreePath> expandedPaths) {\n            this.selectedPaths = selectedPaths;\n            this.expandedPaths = expandedPaths;\n        }\n        \n        \n        public TreePath[] getSelectedPaths() {\n            return selectedPaths;\n        }\n        \n        public Enumeration getExpandedPaths() {\n            return expandedPaths;\n        }\n        \n    }\n    \n    \n    private class Adapter implements TreeModelListener, TreeExpansionListener, TreeWillExpandListener,\n                                     TreeSelectionListener, ListSelectionListener {\n        \n        private boolean internal;\n        \n        public void treeExpanded(TreeExpansionEvent event) {\n            notifyTable();\n            Object expanded = event.getPath().getLastPathComponent();\n            if (expanded instanceof TreeNode) nodeExpanded((TreeNode)expanded);\n        }\n        public void treeCollapsed(final TreeExpansionEvent event) {\n            notifyTable();\n            Object collapsed = event.getPath().getLastPathComponent();\n            if (collapsed instanceof TreeNode) nodeCollapsed((TreeNode)collapsed);\n        }\n        \n        public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {\n            Object expanding = event.getPath().getLastPathComponent();\n            if (expanding instanceof TreeNode) nodeExpanding((TreeNode)expanding);\n        }\n        public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {\n            Object collapsing = event.getPath().getLastPathComponent();\n            if (collapsing instanceof TreeNode) nodeCollapsing((TreeNode)collapsing);\n        }\n\n        public void treeNodesChanged(TreeModelEvent e) { notifyTable(); }\n\n        public void treeNodesInserted(TreeModelEvent e) { notifyTable(); }\n\n        public void treeNodesRemoved(TreeModelEvent e) { notifyTable(); }\n\n        public void treeStructureChanged(TreeModelEvent e) {\n            tree.setChangingModel(true);\n            try { notifyTable(); }\n            finally { tree.setChangingModel(false); }\n        }\n        \n        private void notifyTable() {\n            if (tree.isChangingModel()) return;\n            if (tree.getClientProperty(UIUtils.PROP_EXPANSION_TRANSACTION) != null) return;\n            \n            TreePath[] selectedPaths = tree.getSelectionPaths();\n            model.fireTableDataChanged();\n            tree.setSelectionPaths(selectedPaths);\n        }\n\n        public void valueChanged(TreeSelectionEvent e) {\n            if (internal) return;\n            \n            TreePath selected = e.getPath();\n            \n            // NOTE: workaround to not break scrollRectToVisible() when there's\n            //       an expanded node above the selection.\n            //       Can be detected by e.getPath() != tree.getSelectionPath().\n            if (!Objects.equals(selected, tree.getSelectionPath())) return;\n            \n            int row = selected == null ? -1 : tree.getRowForPath(selected);\n            try {\n                internal = true;\n                if (row != -1) selectRow(row, !tree.isChangingModel());\n                else clearSelection();\n            } finally {\n                internal = false;\n            }\n        }\n\n        public void valueChanged(ListSelectionEvent e) {\n            if (internal) return;\n            \n            int row = getSelectedRow();\n            try {\n                internal = true;\n                if (row != -1) tree.setSelectionRow(row);\n                else tree.clearSelection();\n                repaint(); // TODO: optimize, do not repaint all\n            } finally {\n                internal = false;\n            }\n        }\n        \n    }\n    \n    \n    private static class ProfilerTreeTableTree extends JTree implements TableCellRenderer, Accessible {\n        \n        private int currentX;\n        private int currentWidth;\n        \n        private int currentRowOffset;\n        private boolean currentFirst;\n        private boolean currentFocused;\n        private boolean currentSelected;\n        \n        private boolean customRendering;\n        \n        private SynthLikeTreeUI synthLikeUI;\n        private boolean workaroundVerticalLines;\n        \n        private boolean forgetPreviouslyExpanded;\n\n        \n        ProfilerTreeTableTree(SortedFilteredTreeModel model) {\n            super((TreeModel)null);\n            \n            setOpaque(false);\n            setBorder(BorderFactory.createEmptyBorder());\n            getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);\n            \n            setCellRenderer(new ProfilerRendererWrapper(new LabelRenderer()));\n            \n            setLargeModel(true);\n            setModel(model);\n        }\n        \n        public boolean isFixedRowHeight() {\n            return true;\n        }\n        \n        public void setUI(TreeUI ui) {\n            if (ui instanceof SynthTreeUI) {\n//                if (synthLikeUI == null) {\n                    super.setUI(ui);\n                    SynthTreeUI synthUI = (SynthTreeUI)ui;\n                    int left = synthUI.getLeftChildIndent();\n                    int right = synthUI.getRightChildIndent();\n\n                    synthLikeUI = new SynthLikeTreeUI();\n                    super.setUI(synthLikeUI);\n\n                    boolean nimbus = UIUtils.isNimbusLookAndFeel();\n                    synthLikeUI.setLeftChildIndent(left + (nimbus ? 4 : 6));\n                    synthLikeUI.setRightChildIndent(right);\n//                } else {\n//                    super.setUI(synthLikeUI);\n//                }\n            } else {\n                synthLikeUI = null;\n                \n                super.setUI(ui);\n                \n                // #269500 - performance workaround for BasicTreeUI\n                if (!DISABLE_TREEUI_FIX && ui instanceof BasicTreeUI)\n                    workaroundVerticalLines = UIManager.getBoolean(\"Tree.paintLines\"); // NOI18N\n            }\n        }\n\n        \n        // Overridden for performance reasons.\n        public void validate() {}\n\n        // Overridden for performance reasons.\n        public void revalidate() {}\n        \n        public boolean hasFocus() {\n            return currentFocused;\n        }\n\n        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,\n                                                       int column) {\n            ProfilerTable ptable = (ProfilerTable)table;\n            \n            currentRowOffset = row * rowHeight;\n            currentFirst = column == 0 || isFirstColumn(table.getColumnModel(), column);\n            currentFocused = !ptable.shadesUnfocusedSelection() || hasFocus || table.hasFocus();\n            currentSelected = isSelected;\n            \n            Rectangle cellBounds = getRowBounds(row);\n            if (cellBounds == null) { // row may be -1\n                currentX = 0;\n                currentWidth = 0;\n            } else {\n                currentX = cellBounds.x;\n                currentWidth = cellBounds.width;\n            }\n            \n            customRendering = ptable.isCustomRendering();\n            if (synthLikeUI != null) synthLikeUI.setSelected(isSelected);\n            \n            return this;\n        }\n        \n        private final Dimension prefSize = new Dimension();\n        public Dimension getPreferredSize() {\n            prefSize.setSize(currentX + currentWidth, rowHeight);\n            return prefSize;\n        }\n        \n        public void paint(Graphics g) {\n            g.setColor(getBackground());\n            int rectX = currentSelected || customRendering || !currentFirst ? 0 : currentX;\n            g.fillRect(rectX, 0, getWidth() - rectX, rowHeight);\n            \n            g.translate(customRendering ? -currentX : 0, -currentRowOffset);\n\n            // #269500 - performance workaround for BasicTreeUI\n            if (workaroundVerticalLines && !rootVisible && currentRowOffset > 0) {\n                rootVisible = true;\n                super.paint(g);\n                rootVisible = false;\n            } else {\n                super.paint(g);\n            }\n        }\n        \n        private boolean isFirstColumn(TableColumnModel columns, int column) {\n            int x = 0;\n            for (int i = 0; i < column; i++) x += columns.getColumn(i).getWidth();\n            return x == 0;\n        }\n        \n        \n        public void setAnchorSelectionPath(TreePath newPath) {\n            // TODO: should only be disabled for forgetPreviouslyExpanded?\n        }\n        \n        void setForgetPreviouslyExpanded(boolean forgetPreviouslyExpanded) {\n            this.forgetPreviouslyExpanded = forgetPreviouslyExpanded;\n        }\n        \n        public boolean hasBeenExpanded(TreePath path) {\n            return !forgetPreviouslyExpanded && super.hasBeenExpanded(path);\n        }\n        \n        public void fireTreeCollapsed(TreePath path) {\n            super.fireTreeCollapsed(path);\n            if (forgetPreviouslyExpanded) {\n                super.removeDescendantToggledPaths(Collections.enumeration(Collections.singletonList(path)));\n                // NOTE: uncachePath() must be called for all DescendantToggledPaths once implemented!\n                ((SortedFilteredTreeModel)getModel()).clearPath(path);\n                SwingUtilities.invokeLater(this::updateUI);\n            }\n        }\n        \n        protected void removeDescendantToggledPaths(Enumeration<TreePath> toRemove) {\n//            System.err.println(\">>> REMOVING descendant toggled paths...\");\n//            Thread.dumpStack();\n            super.removeDescendantToggledPaths(toRemove);\n        }\n        \n        void resetExpandedNodes() {\n            clearToggledPaths();\n            updateUI();\n        }\n        \n        public Enumeration<TreePath> getExpandedDescendants(TreePath parent) {\n            return Boolean.TRUE.equals(getClientProperty(UIUtils.PROP_AUTO_EXPANDING)) ?\n                   null : super.getExpandedDescendants(parent);\n        }\n        \n        public void expandPath(TreePath path) {\n            if (changingModel) path = getSimilarPath(path);\n            super.expandPath(path);\n        }\n        \n        public void setSelectionPath(TreePath path) {\n            if (changingModel) path = getSimilarPath(path);\n            super.setSelectionPath(path);\n        }\n        \n        public void setSelectionPaths(TreePath[] paths) {\n            if (changingModel && paths != null) {\n                List<TreePath> similarPaths = new ArrayList<>();\n                for (TreePath path : paths) {\n                    TreePath similarPath = getSimilarPath(path);\n                    if (similarPath != null) similarPaths.add(similarPath);\n                }\n                super.setSelectionPaths(similarPaths.toArray(new TreePath[0]));\n            } else {\n                super.setSelectionPaths(paths);\n            }\n        }\n        \n        private TreePath getSimilarPath(TreePath oldPath) {\n            if (oldPath == null || oldPath.getPathCount() < 1) return null;\n\n            TreeModel currentModel = getModel();\n            Object currentRoot = currentModel.getRoot();\n            if (!currentRoot.equals(oldPath.getPathComponent(0))) return null;\n\n            TreePath p = new TreePath(currentRoot);\n            Object[] op = oldPath.getPath();\n            Object n = currentRoot;\n\n            for (int i = 1; i < op.length; i++) {\n                Object nn = null;\n\n                for (int ii = 0; ii < currentModel.getChildCount(n); ii++) {\n                    Object c = currentModel.getChild(n, ii);\n                    if (c.equals(op[i])) {\n                        nn = c;\n                        break;\n                    }\n                }\n\n                if (nn == null) return null;\n\n                n = nn;\n                p = p.pathByAddingChild(n);\n            }\n\n            return p;\n        }\n        \n        private boolean changingModel;\n        \n        private void setChangingModel(boolean changing) {\n            changingModel = changing;\n        }\n        \n        boolean isChangingModel() {\n            return changingModel;\n        }\n        \n        \n        // --- Handle supported/unsupported AWT Events for the JTree -----------\n        \n        protected void processEvent(AWTEvent e) {\n            if (e instanceof KeyEvent) {\n                if (supportsKeyEvent((KeyEvent)e)) super.processEvent(e);\n            } else if (e instanceof MouseEvent) {\n                if (supportsMouseEvent((MouseEvent)e)) super.processEvent(e);\n            }\n        }\n        \n        private boolean supportsKeyEvent(KeyEvent e) {            \n            switch (e.getKeyCode()) {\n                // Bugfix #GH-109\n                // Handled by the table\n                case KeyEvent.VK_PAGE_UP:\n                case KeyEvent.VK_PAGE_DOWN:\n                    return false;\n                    \n                default:\n                    return true;\n            }\n        }\n        \n        private boolean supportsMouseEvent(MouseEvent e) {\n            return true;\n        }\n        \n        // ---------------------------------------------------------------------\n        \n        \n        public String toString() {\n            return getCellRenderer().toString();\n        }\n        \n        public AccessibleContext getAccessibleContext() {\n            TreeCellRenderer renderer = getCellRenderer();\n            return renderer instanceof Accessible ?\n                   ((Accessible)renderer).getAccessibleContext() :\n                   new JComponent.AccessibleJComponent() {};\n        }\n        \n    }\n    \n    \n    private static class SynthLikeTreeUI extends BasicTreeUI {\n        \n        private static final Icon[] ICONS = new Icon[4];\n        \n        static {\n            \n            final BufferedImage[] image = new BufferedImage[1];\n            BufferedImage tmp = new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB);\n            \n            DefaultMutableTreeNode root = new DefaultMutableTreeNode();\n            root.add(new DefaultMutableTreeNode());\n            \n            JTree tree = new JTree(root);\n            tree.setRootVisible(true);\n            tree.setShowsRootHandles(true);\n            tree.setSize(50, 50);\n            \n            tree.setUI(new SynthTreeUI() {\n                protected void drawCentered(Component c, Graphics graphics, Icon icon,\n                                        int x, int y) {\n                    int w = icon.getIconWidth();\n                    int h = icon.getIconHeight();\n                    image[0] = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);\n                    super.drawCentered(c, image[0].getGraphics(), icon, w / 2, h / 2);\n                }\n            });\n            fixBorder(tree);\n            \n            // Expanded\n            tree.expandRow(0);\n            tree.clearSelection();\n            tree.paint(tmp.getGraphics());\n            ICONS[0] = new ImageIcon(image[0]);\n            \n            // Expanded selected\n            tree.expandRow(0);\n            tree.setSelectionRow(0);\n            tree.paint(tmp.getGraphics());\n            ICONS[1] = new ImageIcon(image[0]);\n            \n            // Collapsed\n            tree.collapseRow(0);\n            tree.clearSelection();\n            tree.paint(tmp.getGraphics());\n            ICONS[2] = new ImageIcon(image[0]);\n            \n            // Collapsed selected\n            tree.collapseRow(0);\n            tree.setSelectionRow(0);\n            tree.paint(tmp.getGraphics());\n            ICONS[3] = new ImageIcon(image[0]);\n            \n        }\n\n        private static void fixBorder(JTree tree) {\n            TreeCellRenderer cellRenderer = tree.getCellRenderer();\n            if (cellRenderer instanceof DefaultTreeCellRenderer) {\n                DefaultTreeCellRenderer defaultRenderer = (DefaultTreeCellRenderer) cellRenderer;\n                Border treeBorder = defaultRenderer.getBorder();\n                Insets i = treeBorder.getBorderInsets(defaultRenderer);\n                if (i.bottom + i.left + i.right + i.top == 0) {\n                    defaultRenderer.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));\n                }\n            }\n        }\n\n        private boolean isSelected;\n        \n        void setSelected(boolean selected) { isSelected = selected; }\n        \n        public Icon getExpandedIcon() { return isSelected ? ICONS[1] : ICONS[0]; }\n        \n        public Icon getCollapsedIcon() { return isSelected ? ICONS[3] : ICONS[2]; }\n        \n        protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds,\n                                        Insets insets, Rectangle bounds,\n                                        TreePath path, int row, boolean isExpanded,\n                                        boolean hasBeenExpanded, boolean isLeaf) {}\n\n        protected void paintVerticalPartOfLeg(Graphics g, Rectangle clipBounds,\n                                        Insets insets, TreePath path) {}\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/ProfilerTreeTableModel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.tree.TreeNode;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ProfilerTreeTableModel {\n\n    public TreeNode getRoot();\n\n    public int getColumnCount();\n\n    public Class<?> getColumnClass(int column);\n\n    public String getColumnName(int column);\n\n    public void setValueAt(Object aValue, TreeNode node, int column);\n\n    public Object getValueAt(TreeNode node, int column);\n\n    public boolean isCellEditable(TreeNode node, int column);\n\n    public void addListener(Listener listener);\n\n    public void removeListener(Listener listener);\n\n\n    public static abstract class Abstract implements ProfilerTreeTableModel {\n\n        private TreeNode root;\n\n        private Set<Listener> listeners;\n\n        public Abstract(TreeNode root) {\n            if (root == null) throw new NullPointerException(\"Root cannot be null\"); // NOI18N\n            this.root = root;\n        }\n\n        public void dataChanged() {\n            fireDataChanged();\n        }\n\n        public void structureChanged() {\n            fireStructureChanged();\n        }\n\n        public void childrenChanged(TreeNode node) {\n            fireChildrenChanged(node);\n        }\n\n        public void setRoot(TreeNode newRoot) {\n            TreeNode oldRoot = root;\n            root = newRoot;\n            fireRootChanged(oldRoot, newRoot);\n        }\n\n        public TreeNode getRoot() {\n            return root;\n        }\n\n        public void addListener(Listener listener) {\n            if (listeners == null) listeners = new HashSet<>();\n            listeners.add(listener);\n        }\n\n        public void removeListener(Listener listener) {\n            if (listeners != null) {\n                listeners.remove(listener);\n                if (listeners.isEmpty()) listeners = null;\n            }\n        }\n        \n        protected void fireDataChanged() {\n            if (listeners != null)\n                for (Listener listener : listeners)\n                    listener.dataChanged();\n        }\n        \n        protected void fireStructureChanged() {\n            if (listeners != null)\n                for (Listener listener : listeners)\n                    listener.structureChanged();\n        }\n        \n        protected void fireChildrenChanged(TreeNode node) {\n            if (listeners != null)\n                for (Listener listener : listeners)\n                    listener.childrenChanged(node);\n        }\n        \n        protected void fireRootChanged(TreeNode oldRoot, TreeNode newRoot) {\n            if (listeners != null)\n                for (Listener listener : listeners)\n                    listener.rootChanged(oldRoot, newRoot);\n        }\n        \n    }\n    \n    \n    public static interface Listener {\n        \n        public void dataChanged();\n        \n        public void structureChanged();\n        \n        public void childrenChanged(TreeNode node);\n        \n        public void rootChanged(TreeNode oldRoot, TreeNode newRoot);\n        \n    }\n    \n    public static class Adapter implements Listener {\n        \n        public void dataChanged() {}\n        \n        public void structureChanged() {}\n        \n        public void childrenChanged(TreeNode node) {}\n        \n        public void rootChanged(TreeNode oldRoot, TreeNode newRoot) {}\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/SearchUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyEvent;\nimport java.text.MessageFormat;\nimport java.util.ResourceBundle;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.JToolBar;\nimport javax.swing.KeyStroke;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.tree.TreeNode;\nimport javax.swing.tree.TreePath;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.spi.ActionsSupportProvider;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.CloseButton;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class SearchUtils {\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.swing.Bundle\"); // NOI18N\n    public static final String ACTION_FIND = messages.getString(\"SearchUtils_ActionFind\"); // NOI18N\n    private static final String MSG_NODATA = messages.getString(\"SearchUtils_MsgNoData\"); // NOI18N\n    private static final String MSG_NOTFOUND = messages.getString(\"SearchUtils_MsgNotFound\"); // NOI18N\n    private static final String SIDEBAR_CAPTION = messages.getString(\"SearchUtils_SidebarCaption\"); // NOI18N\n    private static final String BTN_PREVIOUS = messages.getString(\"SearchUtils_BtnPrevious\"); // NOI18N\n    private static final String BTN_PREVIOUS_TOOLTIP = messages.getString(\"SearchUtils_BtnPreviousTooltip\"); // NOI18N\n    private static final String BTN_NEXT = messages.getString(\"SearchUtils_BtnNext\"); // NOI18N\n    private static final String BTN_NEXT_TOOLTIP = messages.getString(\"SearchUtils_BtnNextTooltip\"); // NOI18N\n    private static final String BTN_MATCH_CASE_TOOLTIP = messages.getString(\"SearchUtils_BtnMatchCaseTooltip\"); // NOI18N\n    private static final String BTN_CLOSE_TOOLTIP = messages.getString(\"SearchUtils_BtnCloseTooltip\"); // NOI18N\n    // -----\n    \n    public static final String FIND_ACTION_KEY = \"find-action-key\"; // NOI18N\n    public static final String FIND_NEXT_ACTION_KEY = \"find-next-action-key\"; // NOI18N\n    public static final String FIND_PREV_ACTION_KEY = \"find-prev-action-key\"; // NOI18N\n    public static final String FIND_SEL_ACTION_KEY = \"find-sel-action-key\"; // NOI18N\n    \n    private static final String LAST_FIND_TEXT = \"last-find-text\"; // NOI18N\n    private static final String LAST_FIND_MATCH_CASE = \"last-find-match-case\"; // NOI18N\n    private static final String FIND_TREE_HELPER = \"find-tree-helper\"; // NOI18N\n    \n    \n    public static boolean findString(ProfilerTable table, String text) {\n        return findString(table, text, true, true);\n    }\n    \n    public static boolean findString(ProfilerTable table, String text, boolean matchCase, boolean next) {\n        int rowCount = table.getRowCount();\n        \n        ProfilerTreeTable treeTable = null;\n        \n        if (rowCount == 0) {\n            ProfilerDialogs.displayWarning(MSG_NODATA, ACTION_FIND, null);\n            return false;\n        } else if (rowCount == 1) {\n            if (!(table instanceof ProfilerTreeTable)) return false;\n            \n            treeTable = (ProfilerTreeTable)table;\n            TreeNode node = treeTable.getValueForRow(0);\n            if (node == null || node.isLeaf()) return false;\n        }\n        \n        if (treeTable != null || table instanceof ProfilerTreeTable) {\n            if (treeTable == null) treeTable = (ProfilerTreeTable)table;\n            return findString(treeTable, text, matchCase, next, null);\n        } else {\n            table.putClientProperty(LAST_FIND_TEXT, text);\n            table.putClientProperty(LAST_FIND_MATCH_CASE, matchCase);\n            \n            if (!matchCase) text = text.toLowerCase();\n            \n            int mainColumn = table.convertColumnIndexToView(table.getMainColumn());\n        \n            int selectedRow = table.getSelectedRow();\n            boolean fromSelection = selectedRow != -1;\n        \n            if (!fromSelection) selectedRow = next ? 0 : rowCount - 1;\n            else selectedRow = next ? table.getNextRow(selectedRow) :\n                                      table.getPreviousRow(selectedRow);\n        \n            int searchSteps = fromSelection ? rowCount - 1 : rowCount;\n            for (int i = 0; i < searchSteps; i++) {\n                String value = table.getStringValue(selectedRow, mainColumn);\n                if (!matchCase) value = value.toLowerCase();\n                if (value.contains(text)) {\n                    table.selectRow(selectedRow, true);\n                    return true;\n                }\n                selectedRow = next ? table.getNextRow(selectedRow) :\n                                     table.getPreviousRow(selectedRow);\n            }\n            \n            ProfilerDialogs.displayInfo(MSG_NOTFOUND, ACTION_FIND, null);\n            return false;\n        }\n    }\n    \n    public static boolean findString(ProfilerTreeTable treeTable, String text, boolean matchCase, boolean next, TreeHelper helper) {\n        treeTable.putClientProperty(LAST_FIND_TEXT, text);\n        treeTable.putClientProperty(LAST_FIND_MATCH_CASE, matchCase);\n        \n        if (!matchCase) text = text.toLowerCase();\n        \n        int mainColumn = treeTable.convertColumnIndexToView(treeTable.getMainColumn());\n        \n        TreePath selectedPath = treeTable.getSelectionPath();\n        if (selectedPath == null) selectedPath = treeTable.getRootPath();\n        boolean firstPath = true;\n        TreePath startPath = null;\n        \n        int nodeType = helper == null ? TreeHelper.NODE_SEARCH_DOWN : helper.getNodeType(selectedPath);\n        \n        do {\n            selectedPath = next ? treeTable.getNextPath(selectedPath, TreeHelper.isDown(nodeType)) :\n                                  treeTable.getPreviousPath(selectedPath, TreeHelper.isDown(nodeType));\n            TreeNode node = (TreeNode)selectedPath.getLastPathComponent();\n            \n            if (helper != null) nodeType = helper.getNodeType(node);\n            \n            if (TreeHelper.isSearch(nodeType)) {\n                String nodeValue = treeTable.getStringValue(node, mainColumn);\n                if (!matchCase) nodeValue = nodeValue.toLowerCase();\n                if (nodeValue.contains(text)) {\n                    treeTable.selectPath(selectedPath, true);\n                    return true;\n                }\n            }\n            \n            if (startPath == null) startPath = selectedPath;\n            else if (firstPath) firstPath = false;\n        } while (firstPath || !selectedPath.equals(startPath));\n        \n        ProfilerDialogs.displayInfo(MSG_NOTFOUND, ACTION_FIND, null);\n        return false;\n    }\n    \n    public static void enableSearchActions(final ProfilerTable table) {\n        ActionMap actionMap = table.getActionMap();\n        InputMap inputMap = table.getInputMap();\n        \n        Action nextAction = new AbstractAction() {\n            public void actionPerformed(final ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        Object text = table.getClientProperty(LAST_FIND_TEXT);\n                        Object matchCase = table.getClientProperty(LAST_FIND_MATCH_CASE);\n                        if (text != null && matchCase != null) {\n                            TreeHelper helper = (TreeHelper)table.getClientProperty(FIND_TREE_HELPER);\n                            if (helper == null) findString(table, text.toString(), Boolean.TRUE == matchCase, true);\n                            else findString((ProfilerTreeTable)table, text.toString(), Boolean.TRUE == matchCase, true, helper);\n                        }\n                    }\n                });\n            }\n        };\n        ActionsSupport.registerAction(FIND_NEXT_ACTION_KEY, nextAction, actionMap, inputMap);\n        \n        Action prevAction = new AbstractAction() {\n            public void actionPerformed(final ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        Object text = table.getClientProperty(LAST_FIND_TEXT);\n                        Object matchCase = table.getClientProperty(LAST_FIND_MATCH_CASE);\n                        if (text != null && matchCase != null) {\n                            TreeHelper helper = (TreeHelper)table.getClientProperty(FIND_TREE_HELPER);\n                            if (helper == null) findString(table, text.toString(), Boolean.TRUE == matchCase, false);\n                            else findString((ProfilerTreeTable)table, text.toString(), Boolean.TRUE == matchCase, false, helper);\n                        }\n                            \n                    }\n                });\n            }\n        };\n        ActionsSupport.registerAction(FIND_PREV_ACTION_KEY, prevAction, actionMap, inputMap);\n        \n        Action selAction = new AbstractAction() {\n            public void actionPerformed(final ActionEvent e) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        int selectedRow = table.getSelectedRow();\n                        if (selectedRow == -1) return;\n                        int mainColumn = table.convertColumnIndexToView(table.getMainColumn());\n                        TreeHelper helper = (TreeHelper)table.getClientProperty(FIND_TREE_HELPER);\n                        if (helper == null) findString(table, table.getStringValue(selectedRow, mainColumn), true, true);\n                        else findString((ProfilerTreeTable)table, table.getStringValue(selectedRow, mainColumn), true, true, helper);\n                    }\n                });\n            }\n        };\n        ActionsSupport.registerAction(FIND_SEL_ACTION_KEY, selAction, actionMap, inputMap);\n    }\n    \n    \n    public static JComponent createSearchPanel(final ProfilerTable table) {\n        return createSearchPanel(table, null);\n    }\n    \n    public static JComponent createSearchPanel(final ProfilerTable table, Component[] options) {\n        return createSearchPanelImpl(table, null, options);\n    }\n    \n    public static JComponent createSearchPanel(final ProfilerTreeTable table, final TreeHelper helper, Component[] options) {\n        return createSearchPanelImpl(table, helper, options);\n    }\n    \n    private static JComponent createSearchPanelImpl(final ProfilerTable table, final TreeHelper helper, Component[] options) {\n        JToolBar toolbar = new InvisibleToolbar();\n        if (UIUtils.isWindowsModernLookAndFeel())\n            toolbar.setBorder(BorderFactory.createEmptyBorder(2, 2, 1, 2));\n        else if (!UIUtils.isNimbusLookAndFeel() && !UIUtils.isAquaLookAndFeel())\n            toolbar.setBorder(BorderFactory.createEmptyBorder(1, 2, 1, 2));\n        \n        toolbar.add(Box.createHorizontalStrut(6));\n        toolbar.add(new JLabel(SIDEBAR_CAPTION));\n        toolbar.add(Box.createHorizontalStrut(3));\n        \n        final EditableHistoryCombo combo = new EditableHistoryCombo();        \n        final JTextComponent textC = combo.getTextComponent();\n        \n        JPanel comboContainer = new JPanel(new BorderLayout());\n        comboContainer.add(combo, BorderLayout.CENTER);\n        comboContainer.setMinimumSize(combo.getMinimumSize());\n        comboContainer.setPreferredSize(combo.getPreferredSize());\n        comboContainer.setMaximumSize(combo.getMaximumSize());\n        \n        toolbar.add(comboContainer);\n        \n        toolbar.add(Box.createHorizontalStrut(5));\n        \n        KeyStroke escKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);\n        KeyStroke prevKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_MASK);\n        KeyStroke nextKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);\n        \n        final JToggleButton matchCase = new JToggleButton(Icons.getIcon(GeneralIcons.MATCH_CASE));\n        matchCase.setToolTipText(BTN_MATCH_CASE_TOOLTIP);\n        // NOTE: added below\n        \n        final JButton prev = new JButton(BTN_PREVIOUS, Icons.getIcon(GeneralIcons.FIND_PREVIOUS)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        String search = getSearchString(combo);\n                        if (search == null || search.isEmpty()) return;\n                        if (helper == null) {\n                            if (findString(table, search, matchCase.isSelected(), false)) combo.addItem(search);\n                        } else {\n                            if (findString((ProfilerTreeTable)table, search, matchCase.isSelected(), false, helper))\n                                combo.addItem(search);\n                        }\n                    }\n                });\n            }\n        };\n        prev.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        prev.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        String prevAccelerator = ActionsSupport.keyAcceleratorString(prevKey);\n        prev.setToolTipText(MessageFormat.format(BTN_PREVIOUS_TOOLTIP, prevAccelerator));\n        prev.setEnabled(false);\n        toolbar.add(prev);\n        \n        if (!UIUtils.isAquaLookAndFeel()) toolbar.add(Box.createHorizontalStrut(2));\n        \n        final JButton next = new JButton(BTN_NEXT, Icons.getIcon(GeneralIcons.FIND_NEXT)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        String search = getSearchString(combo);\n                        if (search == null || search.isEmpty()) return;\n                        if (helper == null) {\n                            if (findString(table, search, matchCase.isSelected(), true)) combo.addItem(search);\n                        } else {\n                            if (findString((ProfilerTreeTable)table, search, matchCase.isSelected(), true, helper))\n                                combo.addItem(search);\n                        }\n                    }\n                });\n            }\n        };\n        next.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        next.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n        String nextAccelerator = ActionsSupport.keyAcceleratorString(nextKey);\n        next.setToolTipText(MessageFormat.format(BTN_NEXT_TOOLTIP, nextAccelerator));\n        next.setEnabled(false);\n        toolbar.add(next);\n        \n        toolbar.add(Box.createHorizontalStrut(2));\n        \n        toolbar.addSeparator();\n        \n        toolbar.add(Box.createHorizontalStrut(1));\n        \n        toolbar.add(matchCase);\n        \n        if (options != null) for (Component option : options) toolbar.add(option);\n        \n        toolbar.add(Box.createHorizontalStrut(2));\n        \n        combo.setOnTextChangeHandler(new Runnable() {\n            public void run() {\n                boolean enable = !combo.getText().trim().isEmpty();\n                prev.setEnabled(enable);\n                next.setEnabled(enable);\n            }\n        });\n        \n        final JPanel panel = new JPanel(new BorderLayout()) {\n            public void setVisible(boolean visible) {\n                super.setVisible(visible);\n                if (!visible) table.requestFocusInWindow();\n            }\n            public boolean requestFocusInWindow() {\n                if (textC != null) textC.selectAll();\n                return combo.requestFocusInWindow();\n            }\n        };\n        panel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UIManager.getColor(\"controlShadow\"))); // NOI18N\n        panel.add(toolbar, BorderLayout.CENTER);\n        \n        final Runnable hider = new Runnable() { public void run() { panel.setVisible(false); } };\n        JButton closeButton = CloseButton.create(hider);\n        String escAccelerator = ActionsSupport.keyAcceleratorString(escKey);\n        closeButton.setToolTipText(MessageFormat.format(BTN_CLOSE_TOOLTIP, escAccelerator));\n        panel.add(closeButton, BorderLayout.EAST);\n        \n        String HIDE = \"hide-action\"; // NOI18N\n        InputMap inputMap = panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        Action hiderAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { hider.run(); }\n        };\n        panel.getActionMap().put(HIDE, hiderAction);\n        inputMap.put(escKey, HIDE);\n        \n        if (textC != null) {\n            inputMap = textC.getInputMap();\n            ActionMap actionMap = textC.getActionMap();\n            \n            String NEXT = \"search-next-action\"; // NOI18N\n            Action nextAction = new AbstractAction() {\n                public void actionPerformed(final ActionEvent e) {\n                    if (combo.isPopupVisible()) combo.hidePopup();\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { if (next.isEnabled()) next.doClick(); }\n                    });\n                }\n            };\n            actionMap.put(NEXT, nextAction);\n            inputMap.put(nextKey, NEXT);\n            \n            KeyStroke nextKey2 = ActionsSupport.registerAction(FIND_NEXT_ACTION_KEY, nextAction, actionMap, inputMap);\n            String nextAccelerator2 = ActionsSupport.keyAcceleratorString(nextKey2);\n            if (nextAccelerator2 != null) next.setToolTipText(MessageFormat.format(BTN_NEXT_TOOLTIP,\n                                                         nextAccelerator + \", \" + nextAccelerator2)); // NOI18N\n\n            String PREV = \"search-prev-action\"; // NOI18N\n            Action prevAction = new AbstractAction() {\n                public void actionPerformed(final ActionEvent e) {\n                    if (combo.isPopupVisible()) combo.hidePopup();\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { if (next.isEnabled()) prev.doClick(); }\n                    });\n                }\n            };\n            actionMap.put(PREV, prevAction);\n            inputMap.put(prevKey, PREV);\n            \n            KeyStroke prevKey2 = ActionsSupport.registerAction(FIND_PREV_ACTION_KEY, prevAction, actionMap, inputMap);\n            String prevAccelerator2 = ActionsSupport.keyAcceleratorString(prevKey2);\n            if (prevAccelerator2 != null) prev.setToolTipText(MessageFormat.format(BTN_PREVIOUS_TOOLTIP,\n                                                         prevAccelerator + \", \" + prevAccelerator2)); // NOI18N\n        }\n        \n        if (helper != null) table.putClientProperty(FIND_TREE_HELPER, helper);\n        \n        return panel;\n    }\n    \n    private static String getSearchString(EditableHistoryCombo combo) {\n        String search = combo.getText();\n        return search == null ? null : search.trim();\n    }\n    \n    \n    // Do not create instances of this class\n    private SearchUtils() {}\n    \n    \n    public static abstract class TreeHelper {\n        \n        public static final int NODE_SEARCH_DOWN =  10; // Node to be searched, search its children\n        public static final int NODE_SEARCH_NEXT =  11; // Node to be searched, do not search its children\n        public static final int NODE_SKIP_DOWN   = 100; // Node not to be searched, search its children\n        public static final int NODE_SKIP_NEXT   = 101; // Node not to be searched, do not search its children\n        \n        public abstract int getNodeType(TreeNode node);\n        \n        int getNodeType(TreePath path) { return getNodeType((TreeNode)path.getLastPathComponent()); }\n        \n        static boolean isSearch(int type) { return type < 100; }\n        \n        static boolean isDown(int type) { return (type & 1) == 0; }\n        \n    }\n    \n    \n    // Default keybinding Ctrl+F and F3 variants for Find action\n    private static interface Support { @ServiceProvider(service=ActionsSupportProvider.class, position=100)\n        public static final class SearchActionProvider extends ActionsSupportProvider {\n            public KeyStroke registerAction(String actionKey, Action action, ActionMap actionMap, InputMap inputMap) {\n                KeyStroke ks = null;\n                \n                if (FIND_ACTION_KEY.equals(actionKey)) {\n                    ks = KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());\n                } else if (FIND_NEXT_ACTION_KEY.equals(actionKey)) {\n                    ks = KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0);\n                } else if (FIND_PREV_ACTION_KEY.equals(actionKey)) {\n                    ks = KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.SHIFT_MASK);\n                } else if (FIND_SEL_ACTION_KEY.equals(actionKey)) {\n                    ks = KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.CTRL_MASK);\n                }\n                \n                if (ks != null) {\n                    actionMap.put(actionKey, action);\n                    inputMap.put(ks, actionKey);\n                }\n\n                return ks;\n            }\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/SmallButton.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Component;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport javax.swing.Action;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JToolBar;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class SmallButton extends JButton {\n\n    protected static final Icon NO_ICON = new Icon() {\n        public int getIconWidth() { return 0; }\n        public int getIconHeight() { return 16; }\n        public void paintIcon(Component c, Graphics g, int x, int y) {}\n    };\n\n\n    {\n        setDefaultCapable(false);\n        if (UIUtils.isWindowsLookAndFeel()) setOpaque(false);\n    }\n\n\n    public SmallButton() { this(null, null);  }\n\n    public SmallButton(Icon icon) { this(null, icon); }\n\n    public SmallButton(String text) { this(text, null); }\n\n    public SmallButton(Action a) { super(a); }\n\n    public SmallButton(String text, Icon icon) { setText(text); setIcon(icon); }\n\n\n    public void setIcon(Icon defaultIcon) {\n        boolean noIcon = defaultIcon == null;\n        if (defaultIcon == null) {\n            defaultIcon = NO_ICON;\n            setIconTextGap(0);\n        }\n        super.setIcon(defaultIcon);\n        if (!noIcon) putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n    }\n\n    public Insets getMargin() {\n        Insets margin = super.getMargin();\n        if (margin != null) {\n            if (getParent() instanceof JToolBar) {\n                if (UIUtils.isNimbus()) {\n                    margin.left = margin.top + 3;\n                    margin.right = margin.top + 3;\n                }\n            } else {\n                if (UIUtils.isNimbus()) {\n                    margin.left = margin.top - 6;\n                    margin.right = margin.top - 6;\n                } else {\n                    margin.left = margin.top + 3;\n                    margin.right = margin.top + 3;\n                }\n            }\n        }\n        return margin;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/StayOpenPopupMenu.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Component;\nimport java.awt.EventQueue;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseEvent;\nimport javax.swing.Action;\nimport javax.swing.Icon;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JMenuItem;\nimport javax.swing.JRadioButtonMenuItem;\nimport javax.swing.JToggleButton;\nimport javax.swing.KeyStroke;\nimport javax.swing.MenuElement;\nimport javax.swing.MenuSelectionManager;\n\n/**\n * A JPopupMenu implementation optionally allowing to interact with JMenuItems\n * without immediately closing the menu.\n *\n * Optionally supports to set a custom background color (some LaF implementations\n * may not support it) to visually present the difference from a standard popup.\n *\n * @author Jiri Sedlacek\n */\npublic class StayOpenPopupMenu extends ProfilerPopupMenu {\n\n\n    public StayOpenPopupMenu() {\n        super();\n    }\n\n    public StayOpenPopupMenu(String label) {\n        super(label);\n    }\n\n\n    // --- Handling keyboard events --------------------------------------------\n\n    private static boolean isReturnAction(KeyEvent e) {\n        int keyCode = e.getKeyCode();\n        return keyCode == KeyEvent.VK_ENTER || keyCode == KeyEvent.VK_SPACE;\n    }\n\n    private static KeyStroke mnemonic(JMenuItem item) {\n        return KeyStroke.getKeyStroke(item.getMnemonic(), KeyEvent.ALT_DOWN_MASK);\n    }\n\n    public void processKeyEvent(KeyEvent e, MenuElement[] path, MenuSelectionManager manager) {\n        if (isReturnAction(e)) { // Handle SPACE and ENTER\n            MenuElement[] p = manager.getSelectedPath();\n            MenuElement m = p != null && p.length > 0 ? p[p.length - 1] : null;\n            if (m instanceof StayOpen) {\n                e.consume();\n                if (e.getID() == KeyEvent.KEY_PRESSED)\n                    performAction((StayOpen)m, e.getModifiers());\n                return;\n            }\n        } else for (Component component : getComponents()) { // Handle mnemonics and accelerators\n            if (component instanceof StayOpen) {\n                StayOpen item = (StayOpen)component;\n                JMenuItem i = item.getItem();\n                KeyStroke k = KeyStroke.getKeyStrokeForEvent(e);\n                if (k.equals(mnemonic(i)) || k.equals(i.getAccelerator())) {\n                    e.consume();\n                    manager.setSelectedPath(new MenuElement[] { this, i });\n                    performAction(item, e.getModifiers());\n                    return;\n                }\n            }\n        }\n        \n        super.processKeyEvent(e, path, manager);\n    }\n    \n    \n    // --- Actions implementation ----------------------------------------------\n    \n    private static void performAction(StayOpen item, int modifiers) {\n        JMenuItem i = item.getItem();\n        \n        // Skip disabled items\n        if (!item.getItem().isEnabled()) return;\n        \n        // Handle toggle items\n        if (i.getModel() instanceof JToggleButton.ToggleButtonModel)\n            i.setSelected(!i.isSelected());\n        \n        // Invoke item action\n        item.actionPerformed(new ActionEvent(item, ActionEvent.ACTION_PERFORMED,\n                             item.getItem().getActionCommand(),\n                             EventQueue.getMostRecentEventTime(), modifiers));\n    }\n    \n    private static void performAction(StayOpen item, MouseEvent e) {\n        if (e.getID() == MouseEvent.MOUSE_RELEASED) {\n            if (item.getItem().contains(e.getPoint()))\n                performAction(item, e.getModifiers());\n            e.consume();\n        }\n    }\n    \n    \n    // --- StayOpen items ------------------------------------------------------\n    \n    private static interface StayOpen extends ActionListener {\n        \n        JMenuItem getItem();\n        \n    }\n    \n    /**\n     * JMenuItem implementation not closing the owner StayOpenPopupMenu when invoked.\n     */\n    public static class Item extends JMenuItem implements StayOpen {\n        \n        public Item() { super(); }\n\n        public Item(Icon icon) { super(icon); }\n\n        public Item(String text) { super(text); }\n\n        public Item(Action a) { super(a); }\n\n        public Item(String text, Icon icon) { super(text, icon); }\n\n        public Item(String text, int mnemonic) { super(text, mnemonic); }\n        \n        \n        public JMenuItem getItem() {\n            return this;\n        }\n        \n        public void actionPerformed(ActionEvent event) {\n            fireActionPerformed(event);\n        }\n        \n        \n        protected void processMouseEvent(MouseEvent e) {\n            performAction(this, e);\n            if (!e.isConsumed()) super.processMouseEvent(e);\n        }\n        \n    }\n    \n    /**\n     * JCheckBoxMenuItem implementation not closing the owner StayOpenPopupMenu when invoked.\n     */\n    public static class CheckBoxItem extends JCheckBoxMenuItem implements StayOpen {\n        \n        public CheckBoxItem() { super(); }\n\n        public CheckBoxItem(Icon icon) { super(icon); }\n\n        public CheckBoxItem(String text) { super(text); }\n\n        public CheckBoxItem(Action a) { super(a); }\n\n        public CheckBoxItem(String text, Icon icon) { super(text, icon); }\n\n        public CheckBoxItem(String text, boolean b) { super(text, b); }\n\n        public CheckBoxItem(String text, Icon icon, boolean b) { super(text, icon, b); }\n        \n        \n        public JMenuItem getItem() {\n            return this;\n        }\n        \n        public void actionPerformed(ActionEvent event) {\n            super.fireActionPerformed(event);\n        }\n        \n        \n        protected void processMouseEvent(MouseEvent e) {\n            performAction(this, e);\n            if (!e.isConsumed()) super.processMouseEvent(e);\n        }\n        \n    }\n    \n    /**\n     * JRadioButtonMenuItem implementation not closing the owner StayOpenPopupMenu when invoked.\n     */\n    public static class RadioButtonItem extends JRadioButtonMenuItem implements StayOpen {\n        \n        public RadioButtonItem() { super(); }\n\n        public RadioButtonItem(Icon icon) { super(icon); }\n\n        public RadioButtonItem(String text) { super(text); }\n\n        public RadioButtonItem(Action a) { super(a); }\n\n        public RadioButtonItem(String text, Icon icon) { super(text, icon); }\n\n        public RadioButtonItem(String text, boolean b) { super(text, b); }\n\n        public RadioButtonItem(String text, Icon icon, boolean b) { super(text, icon, b); }\n        \n        \n        public JMenuItem getItem() {\n            return this;\n        }\n        \n        public void actionPerformed(ActionEvent event) {\n            super.fireActionPerformed(event);\n        }\n        \n        \n        protected void processMouseEvent(MouseEvent e) {\n            performAction(this, e);\n            if (!e.isConsumed()) super.processMouseEvent(e);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/TextArea.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing;\n\nimport java.awt.Color;\nimport java.awt.Toolkit;\nimport java.awt.datatransfer.DataFlavor;\nimport java.awt.datatransfer.Transferable;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseEvent;\nimport java.util.Objects;\nimport java.util.ResourceBundle;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JTextArea;\nimport javax.swing.KeyStroke;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.text.Document;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class TextArea extends JTextArea {\n\n    private static ResourceBundle BUNDLE() {\n        return ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.swing.Bundle\"); // NOI18N\n    }\n\n    private String hint;\n    private Color hintFg;\n    private boolean showsHint;\n\n\n    public TextArea() {\n        super();\n    }\n\n    public TextArea(String text) {\n        super(text);\n    }\n\n    public TextArea(int rows, int columns) {\n        super(rows, columns);\n    }\n\n    public TextArea(String text, int rows, int columns) {\n        super(text, rows, columns);\n    }\n\n    public TextArea(Document doc) {\n        super(doc);\n    }\n\n    public TextArea(Document doc, String text, int rows, int columns) {\n        super(doc, text, rows, columns);\n    }\n\n\n    // --- Change support ------------------------------------------------------\n\n    private boolean changeListener;\n\n    public void setText(String t) {\n        if (showsHint() && !Objects.equals(t, hint)) hideHint();\n\n        if (!changeListener) {\n            changeListener = true;\n            getDocument().addDocumentListener(new DocumentListener() {\n                public void insertUpdate(DocumentEvent e) { updated(); }\n                public void removeUpdate(DocumentEvent e) { updated(); }\n                public void changedUpdate(DocumentEvent e) { updated(); }\n                private void updated() { if (!showsHint()) changed(); }\n            });\n        }\n        \n        super.setText(t);\n    }\n    \n    protected void changed() {}\n    \n    \n    // --- Hint support --------------------------------------------------------\n    \n    public void setHint(String hint) {\n        hideHint();\n        this.hint = hint;\n        if (!isFocusOwner()) showHint();\n    }\n    \n    public String getHint() {\n        return hint;\n    }\n    \n    public boolean showsHint() {\n        return showsHint;\n    }\n    \n    \n    protected void processFocusEvent(FocusEvent e) {\n        if (isFocusOwner()) hideHint(); else showHint();\n        super.processFocusEvent(e);\n    }\n    \n    \n    private void showHint() {\n        if (hint != null && getText().isEmpty()) {\n            showsHint = true;\n            setText(hint);\n            hintFg = getForeground();\n            setForeground(getDisabledTextColor());\n        }\n    }\n    \n    private void hideHint() {\n        if (showsHint) {\n            showsHint = false;\n            setForeground(hintFg);\n            if (Objects.equals(getText(), hint)) setText(\"\"); // NOI18N\n        }\n    }\n    \n    \n    // --- Popup menu support --------------------------------------------------\n    \n    protected void processMouseEvent(MouseEvent e) {\n        super.processMouseEvent(e);\n        if (e.isPopupTrigger() && isEnabled()) showPopup(e);\n    }\n    \n    \n    private void showPopup(MouseEvent e) {\n        boolean editable = isEditable();\n        boolean selectedText = getSelectedText() != null;\n        \n        JPopupMenu popup = new JPopupMenu();\n        \n        JMenuItem miCut = new JMenuItem(BUNDLE().getString(\"TextArea_Cut\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent ae) {\n                super.fireActionPerformed(ae);\n                cut();\n                requestFocusInWindow();\n            }\n        };\n        miCut.setEnabled(editable && selectedText);\n        popup.add(miCut);\n        \n        JMenuItem miCopy = new JMenuItem(BUNDLE().getString(\"TextArea_Copy\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent ae) {\n                super.fireActionPerformed(ae);\n                copy();\n                requestFocusInWindow();\n            }\n        };\n        miCopy.setEnabled(selectedText);\n        popup.add(miCopy);\n        \n        JMenuItem miPaste = new JMenuItem(BUNDLE().getString(\"TextArea_Paste\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent ae) {\n                super.fireActionPerformed(ae);\n                hideHint();\n                try {\n                    replaceSelection(Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this).\n                                     getTransferData(DataFlavor.stringFlavor).toString());\n                    requestFocusInWindow();\n                } catch (Exception ex) {}\n                showHint();\n            }\n        };\n        try {\n            Transferable clipboardContent = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this);\n            miPaste.setEnabled(editable && clipboardContent != null && clipboardContent.isDataFlavorSupported(\n                                                                       DataFlavor.stringFlavor));\n            requestFocusInWindow();\n        } catch (Exception ex) {\n            miPaste.setEnabled(false);\n        }\n        popup.add(miPaste);\n        \n        if (editable) {\n            JMenuItem miDelete = new JMenuItem(BUNDLE().getString(\"TextArea_Delete\")) { // NOI18N\n                protected void fireActionPerformed(ActionEvent ae) {\n                    super.fireActionPerformed(ae);\n                    try {\n                        int selStart = getSelectionStart();\n                        getDocument().remove(selStart, getSelectionEnd() - selStart);\n                        requestFocusInWindow();\n                    } catch (Exception ex) {}\n                }\n            };\n            miDelete.setEnabled(selectedText);\n            popup.add(miDelete);\n        }\n        \n        popup.addSeparator();\n        \n        JMenuItem miSelect = new JMenuItem(BUNDLE().getString(\"TextArea_SelectAll\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent ae) {\n                super.fireActionPerformed(ae);\n                selectAll();\n                requestFocusInWindow();\n            }\n        };\n        miSelect.setEnabled(!showsHint() && !getText().isEmpty());\n        popup.add(miSelect);\n        \n        customizePopup(popup);\n        \n        popup.show(this, e.getX(), e.getY());\n    }\n    \n    protected void customizePopup(JPopupMenu popup) {}\n    \n    \n    // --- Resize support ------------------------------------------------------\n    \n    protected void processKeyEvent(KeyEvent e) {\n        if (e.isControlDown() && e.getID() == KeyEvent.KEY_RELEASED) {\n            int keyCode = e.getKeyCode();\n            if (keyCode == KeyEvent.VK_EQUALS || keyCode == KeyEvent.VK_PLUS) {\n                if (changeSize(e.isShiftDown(), true)) e.consume();\n            } else if (keyCode == KeyEvent.VK_MINUS) {\n                if (changeSize(e.isShiftDown(), false)) e.consume();\n            } else if (keyCode == KeyEvent.VK_0) {\n                if (resetSize()) e.consume();\n            }\n        }\n        \n        if (!e.isConsumed()) super.processKeyEvent(e);\n    }\n    \n    protected boolean changeSize(boolean vertical, boolean direction) { return false; }\n    \n    protected boolean resetSize() { return false; }\n    \n    protected final JMenu createResizeMenu() {\n        JMenu menu = new JMenu(BUNDLE().getString(\"TextArea_Resize\")); // NOI18N\n                        \n        JMenuItem horizPlus = new JMenuItem(BUNDLE().getString(\"TextArea_HorizPlus\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent e) { changeSize(false, true); }\n        };\n        horizPlus.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, KeyEvent.CTRL_MASK));\n        menu.add(horizPlus);\n        JMenuItem horizMinus = new JMenuItem(BUNDLE().getString(\"TextArea_HorizMinus\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent e) { changeSize(false, false); }\n        };\n        horizMinus.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, KeyEvent.CTRL_MASK));\n        menu.add(horizMinus);\n        JMenuItem vertPlus = new JMenuItem(BUNDLE().getString(\"TextArea_VertPlus\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent e) { changeSize(true, true); }\n        };\n        vertPlus.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK));\n        menu.add(vertPlus);\n        JMenuItem vertMinus = new JMenuItem(BUNDLE().getString(\"TextArea_VertMinus\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent e) { changeSize(true, false); }\n        };\n        vertMinus.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK));\n        menu.add(vertMinus);\n\n        menu.addSeparator();\n\n        JMenuItem reset = new JMenuItem(BUNDLE().getString(\"TextArea_DefaultSize\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent e) { resetSize(); }\n        };\n        reset.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_0, KeyEvent.CTRL_MASK));\n        menu.add(reset);\n        \n        return menu;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/BarRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Rectangle;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class BarRenderer extends BaseRenderer implements RelativeRenderer {\n\n    private static final Color COLOR_POS = new Color(225, 130, 130);\n    private static final Color COLOR_NEG = new Color(130, 225, 130);\n\n    private static final int X_MARGIN = 2;\n    private static final int Y_MARGIN = 3;\n\n    private static final Rectangle BAR_RECT = new Rectangle();\n\n    private long maxValue;\n    private float value;\n\n    protected boolean renderingDiff;\n\n\n    public BarRenderer() {\n        maxValue = 100;\n        value = 0;\n\n        setOpaque(true);\n        putClientProperty(ProfilerTable.PROP_NO_HOVER, this);\n    }\n\n\n    public void setMaxValue(long maxValue) {\n        this.maxValue = maxValue;\n    }\n\n    public long getMaxValue() {\n        return maxValue;\n    }\n\n    public void setValue(Object value, int row) {\n        if (value == null) this.value = 0;\n        else this.value = maxValue == 0 ? 0 : ((Number)value).floatValue() / maxValue;\n    }\n\n\n    public void setDiffMode(boolean diffMode) {\n        renderingDiff = diffMode;\n    }\n\n    public boolean isDiffMode() {\n        return renderingDiff;\n    }\n\n\n    public void paint(Graphics g) {\n        super.paint(g);\n\n        BAR_RECT.x = location.x + X_MARGIN;\n        BAR_RECT.y = location.y + Y_MARGIN;\n        BAR_RECT.height = size.height - Y_MARGIN * 2;\n\n        int width = size.width - X_MARGIN * 2;\n\n        if (renderingDiff) {\n            Color color = value < 0 ? COLOR_NEG : COLOR_POS;\n            int width2 = width / 2;\n            \n            if (value <= -1) {\n                g.setColor(color);\n                g.fillRect(BAR_RECT.x, BAR_RECT.y, width2, BAR_RECT.height);\n                \n                g.setColor(alternate(color));\n                g.fillRect(BAR_RECT.x + width2, BAR_RECT.y, width - width2, BAR_RECT.height);\n            } else if (value >= 1) {\n                g.setColor(alternate(color));\n                g.fillRect(BAR_RECT.x, BAR_RECT.y, width2, BAR_RECT.height);\n                \n                g.setColor(color);\n                g.fillRect(BAR_RECT.x + width2, BAR_RECT.y, width - width2, BAR_RECT.height);\n            } else {\n                g.setColor(alternate(color));\n                g.fillRect(BAR_RECT.x, BAR_RECT.y, width, BAR_RECT.height);\n\n                BAR_RECT.width = (int)(width2 * Math.min(Math.abs(value), 1));\n                if (BAR_RECT.width > 0) {\n                    g.setColor(color);\n                    if (value < 0) {\n                        g.fillRect(BAR_RECT.x + width2 - BAR_RECT.width, BAR_RECT.y, BAR_RECT.width, BAR_RECT.height);\n                    } else {\n                        g.fillRect(BAR_RECT.x + width2, BAR_RECT.y, BAR_RECT.width, BAR_RECT.height);\n                    }\n                }\n            }\n        } else {\n            BAR_RECT.width = (int)(width * Math.min(value, 1));\n            if (BAR_RECT.width > 0) {\n                g.setColor(COLOR_POS);\n                g.fillRect(BAR_RECT.x, BAR_RECT.y, BAR_RECT.width, BAR_RECT.height);\n            }\n\n            if (BAR_RECT.width < width) {\n                BAR_RECT.x += BAR_RECT.width;\n                BAR_RECT.width = width - BAR_RECT.width;\n                g.setColor(alternate(COLOR_POS));\n                g.fillRect(BAR_RECT.x, BAR_RECT.y, BAR_RECT.width, BAR_RECT.height);\n            }\n        }\n    }\n    \n    private static final double FACTOR = 0.55d;\n//    private static final double FACTOR = 0.20d;\n    \n    private static Color alternate(Color c) {\n        return !UIUtils.isDarkResultsBackground() ? brighter(c) : darker(c);\n    }\n    \n    private static Color brighter(Color c) {\n        int r = c.getRed();\n        int g = c.getGreen();\n        int b = c.getBlue();\n\n        int i = (int)(1.0/(1.0-FACTOR));\n        if ( r > 0 && r < i ) r = i;\n        if ( g > 0 && g < i ) g = i;\n        if ( b > 0 && b < i ) b = i;\n\n        return new Color(Math.min((int)(r/FACTOR), 255),\n                         Math.min((int)(g/FACTOR), 255),\n                         Math.min((int)(b/FACTOR), 255));\n    }\n    \n    private static Color darker(Color c) {\n        return new Color(Math.max((int)(c.getRed()  *FACTOR), 0),\n                         Math.max((int)(c.getGreen()*FACTOR), 0),\n                         Math.max((int)(c.getBlue() *FACTOR), 0));\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/BaseRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport javax.accessibility.AccessibleContext;\nimport javax.accessibility.AccessibleRole;\nimport javax.swing.JComponent;\n\n/**\n * Base class for custom Table/Tree/List renderers optimized for performance.\n * To create a label-based renderer, use LabelRenderer instead.\n *\n * @author Jiri Sedlacek\n */\npublic class BaseRenderer extends JComponent implements ProfilerRenderer {\n\n    // --- Constructor ---------------------------------------------------------\n\n    public BaseRenderer() {\n        setOpaque(false);\n    }\n\n    // --- Renderer ------------------------------------------------------------\n\n    private int alignment;\n\n    public void setValue(Object value, int row) {}\n\n    public void setHorizontalAlignment(int alignment) {\n        this.alignment = alignment;\n    }\n\n    public int getHorizontalAlignment() {\n        return alignment;\n    }\n\n    public JComponent getComponent() {\n        return this;\n    }\n\n    // --- Tools ---------------------------------------------------------------\n\n    private Point sharedPoint;\n    private Dimension sharedDimension;\n    private Rectangle sharedRectangle;\n\n    protected final Point sharedPoint(int x, int y) {\n        if (sharedPoint == null) sharedPoint = new Point();\n        sharedPoint.x = x;\n        sharedPoint.y = y;\n        return sharedPoint;\n    }\n\n    protected final Point sharedPoint(Point point) {\n        return sharedPoint(point.x, point.y);\n    }\n\n    protected final Dimension sharedDimension(int width, int height) {\n        if (sharedDimension == null) sharedDimension = new Dimension();\n        sharedDimension.width = width;\n        sharedDimension.height = height;\n        return sharedDimension;\n    }\n    \n    protected final Dimension sharedDimension(Dimension dimension) {\n        return sharedDimension(dimension.width, dimension.height);\n    }\n    \n    protected final Rectangle sharedRectangle(int x, int y, int width, int height) {\n        if (sharedRectangle == null) sharedRectangle = new Rectangle();\n        sharedRectangle.x = x;\n        sharedRectangle.y = y;\n        sharedRectangle.width = width;\n        sharedRectangle.height = height;\n        return sharedRectangle;\n    }\n    \n    protected final Rectangle sharedRectangle(Rectangle rectangle) {\n        return sharedRectangle(rectangle.x, rectangle.y, rectangle.width, rectangle.height);\n    }\n    \n    // --- Geometry ------------------------------------------------------------\n    \n    protected final Point location = new Point();\n    protected final Dimension size = new Dimension();\n    \n    public void move(int x, int y) {\n        location.x = x;\n        location.y = y;\n    }\n    \n    public Point getLocation() {\n        return sharedPoint(location);\n    }\n    \n    public int getX() {\n        return location.x;\n    }\n    \n    public int getY() {\n        return location.y;\n    }\n    \n    public void setSize(int w, int h) {\n        size.width = w;\n        size.height = h;\n    }\n    \n    public Dimension getSize() {\n        return sharedDimension(size);\n    }\n    \n    public int getWidth() {\n        return size.width;\n    }\n    \n    public int getHeight() {\n        return size.height;\n    }\n    \n    public Rectangle getBounds() {\n        return sharedRectangle(location.x, location.y, size.width, size.height);\n    }\n    \n    public void reshape(int x, int y, int w, int h) {\n        // ignore x, y: used only for move(x, y)\n//        location.x = x;\n//        location.y = y;\n        size.width = w;\n        size.height = h;\n    }\n    \n    // --- Margins / Borders ---------------------------------------------------\n    \n    private final Insets insets = new Insets(0, 0, 0, 0);\n    \n    public Insets getInsets() {\n        return insets;\n    }\n\n    public Insets getInsets(Insets insets) {\n        return this.insets;\n    }\n    \n    // --- Appearance ----------------------------------------------------------\n    \n    private boolean visible = true;\n    private boolean enabled = true;\n    private Color foreground;\n    private Color background;\n    \n    public void setVisible(boolean visible) {\n        this.visible = visible;\n    }\n\n    public boolean isVisible() {\n        return visible;\n    }\n    \n    public void setEnabled(boolean enabled) {\n        this.enabled = enabled;\n    }\n\n    public boolean isEnabled() {\n        return enabled;\n    }\n    \n    public void setForeground(Color foreground) {\n        this.foreground = foreground;\n    }\n\n    public Color getForeground() {\n        return foreground;\n    }\n    \n    public void setBackground(Color background) {\n        this.background = background;\n    }\n\n    public Color getBackground() {\n        return background;\n    }\n    \n    // --- Painting / Layout ---------------------------------------------------\n    \n    public void paint(Graphics g) {\n        if (isOpaque()) {\n            g.setColor(background);\n            g.fillRect(location.x, location.y, size.width, size.height);\n        }\n    }\n    \n    public void validate() {}\n\n    public void revalidate() {}\n\n    public void repaint(long tm, int x, int y, int width, int height) {}\n\n    public void repaint(Rectangle r) {}\n\n    public void repaint() {}\n    \n    // --- Events --------------------------------------------------------------\n\n    public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {}\n\n    public void firePropertyChange(String propertyName, char oldValue, char newValue) {}\n\n    public void firePropertyChange(String propertyName, short oldValue, short newValue) {}\n\n    public void firePropertyChange(String propertyName, int oldValue, int newValue) {}\n\n    public void firePropertyChange(String propertyName, long oldValue, long newValue) {}\n\n    public void firePropertyChange(String propertyName, float oldValue, float newValue) {}\n\n    public void firePropertyChange(String propertyName, double oldValue, double newValue) {}\n\n    public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}\n\n    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}\n    \n    // --- Accessibility -------------------------------------------------------\n    \n    private AccessibleContext accessibleContext;\n    \n    protected AccessibleContext createAccessibleContext() {\n        return new JComponent.AccessibleJComponent() {\n            public AccessibleRole getAccessibleRole() {\n                return AccessibleRole.LABEL;\n            }\n            public String getAccessibleName() {\n                return BaseRenderer.this.toString();\n            }\n        };\n    }\n    \n    public AccessibleContext getAccessibleContext() {\n        if (accessibleContext == null) accessibleContext = createAccessibleContext();\n        return accessibleContext;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/CheckBoxRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComponent;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class CheckBoxRenderer extends JCheckBox implements ProfilerRenderer {\n\n    // --- Constructor ---------------------------------------------------------\n\n    public CheckBoxRenderer() {\n        setOpaque(true);\n        setHorizontalAlignment(CENTER);\n    }\n\n    // --- Renderer ------------------------------------------------------------\n\n    public void setValue(Object value, int row) {\n        if (value == null) setSelected(false);\n        else setSelected(((Boolean)value).booleanValue());\n    }\n\n    public JComponent getComponent() {\n        return this;\n    }\n\n    public String toString() {\n        return Boolean.toString(isSelected());\n    }\n\n    // --- Tools ---------------------------------------------------------------\n\n    private Point sharedPoint;\n    private Dimension sharedDimension;\n    private Rectangle sharedRectangle;\n\n    protected final Point sharedPoint(int x, int y) {\n        if (sharedPoint == null) sharedPoint = new Point();\n        sharedPoint.x = x;\n        sharedPoint.y = y;\n        return sharedPoint;\n    }\n\n    protected final Point sharedPoint(Point point) {\n        return sharedPoint(point.x, point.y);\n    }\n\n    protected final Dimension sharedDimension(int width, int height) {\n        if (sharedDimension == null) sharedDimension = new Dimension();\n        sharedDimension.width = width;\n        sharedDimension.height = height;\n        return sharedDimension;\n    }\n\n    protected final Dimension sharedDimension(Dimension dimension) {\n        return sharedDimension(dimension.width, dimension.height);\n    }\n    \n    protected final Rectangle sharedRectangle(int x, int y, int width, int height) {\n        if (sharedRectangle == null) sharedRectangle = new Rectangle();\n        sharedRectangle.x = x;\n        sharedRectangle.y = y;\n        sharedRectangle.width = width;\n        sharedRectangle.height = height;\n        return sharedRectangle;\n    }\n    \n    protected final Rectangle sharedRectangle(Rectangle rectangle) {\n        return sharedRectangle(rectangle.x, rectangle.y, rectangle.width, rectangle.height);\n    }\n    \n    // --- Geometry ------------------------------------------------------------\n    \n    protected final Point location = new Point();\n    protected final Dimension size = new Dimension();\n    \n    public void move(int x, int y) {\n        location.x = x;\n        location.y = y;\n    }\n    \n    public Point getLocation() {\n        return sharedPoint(location);\n    }\n    \n    public int getX() {\n        return location.x;\n    }\n    \n    public int getY() {\n        return location.y;\n    }\n    \n    public void setSize(int w, int h) {\n        size.width = w;\n        size.height = h;\n    }\n    \n    public Dimension getSize() {\n        return sharedDimension(size);\n    }\n    \n    public int getWidth() {\n        return size.width;\n    }\n    \n    public int getHeight() {\n        return size.height;\n    }\n    \n    public Rectangle getBounds() {\n        return sharedRectangle(location.x, location.y, size.width, size.height);\n    }\n    \n    public void reshape(int x, int y, int w, int h) {\n        // ignore x, y: used only for move(x, y)\n//        location.x = x;\n//        location.y = y;\n        size.width = w;\n        size.height = h;\n    }\n\n    // --- Insets --------------------------------------------------------------\n    \n    private final Insets insets = new Insets(0, 0, 0, 0);\n    \n    public Insets getInsets() {\n        return insets;\n    }\n\n    public Insets getInsets(Insets insets) {\n        return this.insets;\n    }\n\n    // --- Other performance tweaks ---------------------------------------------\n    \n    private Color foreground;\n    private Color background;\n    private boolean enabled = true;\n\n    public void setForeground(Color foreground) {\n        this.foreground = foreground;\n    }\n\n    public Color getForeground() {\n        return foreground;\n    }\n    \n    public void setBackground(Color background) {\n        this.background = background;\n    }\n\n    public Color getBackground() {\n        return background;\n    }\n\n    public void setEnabled(boolean enabled) {\n        this.enabled = enabled;\n    }\n\n    public boolean isEnabled() {\n        return enabled;\n    }\n    \n    // --- Painting / Layout ---------------------------------------------------\n\n    public void validate() {}\n\n    public void revalidate() {}\n\n    public void repaint(long tm, int x, int y, int width, int height) {}\n\n    public void repaint(Rectangle r) {}\n\n    public void repaint() {}\n\n    public void setDisplayedMnemonicIndex(int index) {}\n    \n    // --- Events --------------------------------------------------------------\n\n    public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {}\n\n    public void firePropertyChange(String propertyName, char oldValue, char newValue) {}\n\n    public void firePropertyChange(String propertyName, short oldValue, short newValue) {}\n\n    public void firePropertyChange(String propertyName, int oldValue, int newValue) {}\n\n    public void firePropertyChange(String propertyName, long oldValue, long newValue) {}\n\n    public void firePropertyChange(String propertyName, float oldValue, float newValue) {}\n\n    public void firePropertyChange(String propertyName, double oldValue, double newValue) {}\n\n    public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}\n\n    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/FormattedLabelRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport java.text.Format;\nimport java.text.MessageFormat;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class FormattedLabelRenderer extends LabelRenderer {\n\n    private final Format format;\n\n    public FormattedLabelRenderer(Format format) {\n        this.format = format;\n    }\n\n    public void setValue(Object value, int row) {\n        super.setValue(getValueString(value, row, format), row);\n    }\n\n    protected String getValueString(Object value, int row, Format format) {\n        if (format != null) return formatImpl(format, value);\n        else return value == null ? \"null\" : value.toString(); // NOI18N\n    }\n\n    protected static String formatImpl(Format format, Object value) {\n        if (format instanceof MessageFormat)\n            if (!(value instanceof Object[]))\n                value = new Object[] { value };\n        return format.format(value);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/HideableBarRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport javax.swing.JComponent;\nimport javax.swing.SwingConstants;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class HideableBarRenderer extends MultiRenderer {\n\n    private static final int BAR_MARGIN = 20;\n    private static final int MIN_BAR_WIDTH = 20;\n    private static final int MAX_BAR_WIDTH = 100;\n    private static final int OPT_BAR_WIDTH = 50;\n\n\n    public static enum BarDiffMode {\n        MODE_BAR_DIFF,      // divided bar with green/red sections\n        MODE_BAR_NORMAL,    // single bar as if diff was not in effect\n        MODE_BAR_NONE       // no bar (hidden) in diff mode\n    }\n\n\n    private BarDiffMode barDiffMode = BarDiffMode.MODE_BAR_DIFF;\n\n    private int maxRendererWidth;\n\n    private final BarRenderer barRenderer;\n    private final ProfilerRenderer mainRenderer;\n    private final NumberPercentRenderer numberPercentRenderer;\n\n    private final ProfilerRenderer[] valueRenderers;\n\n\n    public HideableBarRenderer(ProfilerRenderer renderer) {\n        this(renderer, renderer.getComponent().getPreferredSize().width);\n    }\n\n    public HideableBarRenderer(ProfilerRenderer renderer, int maxWidth) {\n        maxRendererWidth = maxWidth;\n\n        barRenderer = new BarRenderer();\n        mainRenderer = renderer;\n        numberPercentRenderer = renderer instanceof NumberPercentRenderer ?\n                                (NumberPercentRenderer)renderer : null;\n\n        valueRenderers = new ProfilerRenderer[] { barRenderer, mainRenderer };\n\n        setOpaque(true);\n        setHorizontalAlignment(SwingConstants.TRAILING);\n    }\n\n\n    public void setBarDiffMode(BarDiffMode barDiffMode) {\n        this.barDiffMode = barDiffMode;\n    }\n    \n    public BarDiffMode getBarDiffMode() {\n        return barDiffMode;\n    }\n    \n    \n    public void setDiffMode(boolean diffMode) {\n        super.setDiffMode(diffMode);\n        \n        if (!diffMode || BarDiffMode.MODE_BAR_NORMAL.equals(barDiffMode)) {\n            barRenderer.setVisible(true);\n            barRenderer.setDiffMode(false);\n        } else {\n            if (BarDiffMode.MODE_BAR_NONE.equals(barDiffMode)) barRenderer.setVisible(false);\n            else if (BarDiffMode.MODE_BAR_DIFF.equals(barDiffMode)) barRenderer.setDiffMode(true);\n        }\n    }\n    \n    \n    public void setMaxValue(long maxValue) {\n        int oldDigits = Long.toString(barRenderer.getMaxValue()).length();\n        int newDigits = Long.toString(maxValue).length();\n        \n        barRenderer.setMaxValue(maxValue);\n        if (numberPercentRenderer != null) numberPercentRenderer.setMaxValue(maxValue);\n        \n        if (oldDigits < newDigits) {\n            // Number of the same pow10 created using only digit '9'\n//            int ref = (int)Math.pow(10, Math.ceil(Math.log10(maxValue + 1))) - 1;\n            mainRenderer.setValue((long)Math.pow(10, newDigits) - 1, -1);\n            int mainWidth = mainRenderer.getComponent().getPreferredSize().width;\n            maxRendererWidth = Math.max(maxRendererWidth, mainWidth);\n        }\n    }\n    \n    public void setValue(Object value, int row) {\n        barRenderer.setValue(value, row);\n        mainRenderer.setValue(value, row);\n    }\n    \n\n    protected ProfilerRenderer[] valueRenderers() {\n        return valueRenderers;\n    }\n    \n    protected int renderersGap() {\n        return BAR_MARGIN;\n    }\n    \n    \n    public Dimension getPreferredSize() {\n        return mainRenderer.getComponent().getPreferredSize();\n    }\n    \n    public int getOptimalWidth() {\n        return maxRendererWidth + renderersGap() + OPT_BAR_WIDTH;\n    }\n    \n    public int getMaxNoBarWidth() {\n        return maxRendererWidth + renderersGap() + MIN_BAR_WIDTH - 1;\n    }\n    \n    public int getNoBarWidth() {\n        return maxRendererWidth;\n    }\n    \n    public void paint(Graphics g) {\n        g.setColor(getBackground());\n        g.fillRect(location.x, location.y, size.width, size.height);\n        \n        JComponent component = mainRenderer.getComponent();\n        int componentWidth = component.getPreferredSize().width;\n        int componentX = size.width - componentWidth;\n        \n        mainRenderer.move(location.x + componentX, location.y);\n        component.setSize(componentWidth, size.height);\n        component.paint(g);\n        \n        if (barRenderer.isVisible()) {\n            int freeWidth = size.width - maxRendererWidth - renderersGap();\n            if (freeWidth >= MIN_BAR_WIDTH) {\n                barRenderer.setSize(Math.min(freeWidth, MAX_BAR_WIDTH), size.height);\n                barRenderer.move(location.x, location.y);\n                barRenderer.paint(g);\n            }\n        }\n    }\n    \n    public String toString() {\n        return mainRenderer.toString();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/JavaNameRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.lib.ui.results.PackageColorer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class JavaNameRenderer extends NormalBoldGrayRenderer {\n\n    private final Icon icon;\n\n    public JavaNameRenderer() {\n        this(null);\n    }\n\n    public JavaNameRenderer(Icon icon) {\n        this.icon = icon;\n    }\n\n    public void setValue(Object value, int row) {\n        if (value == null) {\n            setNormalValue(\"\"); // NOI18N\n            setBoldValue(\"\"); // NOI18N\n            setGrayValue(\"\"); // NOI18N\n        } else {\n            String name = value.toString();\n            String gray = \"\"; // NOI18N\n\n            int bracketIndex = name.indexOf('('); // NOI18N\n            if (bracketIndex != -1) {\n                gray = \" \" + name.substring(bracketIndex); // NOI18N\n                name = name.substring(0, bracketIndex);\n            }\n\n            int dotIndex = name.lastIndexOf('.'); // NOI18N\n            setNormalValue(name.substring(0, dotIndex + 1));\n            setBoldValue(name.substring(dotIndex + 1));\n            setGrayValue(gray);\n        }\n        setIcon(icon);\n    }\n\n\n    // TODO: optimize to not slow down sort/search/filter by resolving color!\n    protected void setNormalValue(String value) {\n        super.setNormalValue(value);\n        setCustomForeground(PackageColorer.getForeground(value));\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/LabelRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.FontMetrics;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.plaf.LabelUI;\nimport javax.swing.plaf.basic.BasicLabelUI;\n\n/**\n * JLabel subclass to be used as a high-performance Table/Tree/List renderer.\n * Make sure you call setOpaque(true) for painting background.\n * For custom non-label Table/Tree/List renderer extend BaseRenderer.\n *\n * @author Jiri Sedlacek\n */\npublic class LabelRenderer extends JLabel implements ProfilerRenderer {\n\n    // --- Constructor ---------------------------------------------------------\n\n    public LabelRenderer() {\n        this(false);\n    }\n\n    public LabelRenderer(boolean plain) {\n        setHorizontalAlignment(LEADING);\n        setVerticalAlignment(TOP);\n        setSize(Integer.MAX_VALUE, Integer.MAX_VALUE);\n\n        if (plain) {\n            setOpaque(false);\n        } else {\n            setOpaque(true);\n            setMargin(3, 3, 3, 3);\n        }\n\n        iconTextGap = super.getIconTextGap();\n    }\n\n    // --- Renderer ------------------------------------------------------------\n\n    public void setValue(Object value, int row) {\n        if (value == null) setText(\"\"); // NOI18N\n        else setText(value.toString());\n    }\n\n    public JComponent getComponent() {\n        return this;\n    }\n\n    public String toString() {\n        return getText();\n    }\n\n    // --- Appearance ----------------------------------------------------------\n\n    private static final LabelRendererUI UI = new LabelRendererUI();\n    private static final int DIRTY = Integer.MIN_VALUE;\n    \n    private Dimension preferredSize;\n    \n    private int iconWidth;\n    private int iconHeight;\n    private int iconTextGap;\n    private int textWidth;\n    private int fontAscent;\n    \n    public void setUI(LabelUI ui) {\n        super.setUI(UI);\n    }\n    \n    public Dimension getPreferredSize() {\n        return sharedDimension(getPreferredSizeImpl());\n    }\n    \n    public Dimension getPreferredSizeImpl() {\n        if (preferredSize == null) preferredSize = new Dimension(DIRTY, DIRTY);\n        \n        if (preferredSize.width == DIRTY) {\n            textWidth = text == null || text.isEmpty() ? 0 : fontMetrics.stringWidth(text);\n            preferredSize.width = iconWidth + textWidth;\n            preferredSize.width += margin.left + margin.right;\n            if (iconWidth > 0 && textWidth > 0) preferredSize.width += iconTextGap;\n        }\n\n        if (preferredSize.height == DIRTY) {\n            fontAscent = fontMetrics.getAscent();\n            preferredSize.height = fontAscent + fontMetrics.getDescent();\n            preferredSize.height += margin.top + margin.bottom;\n        }\n    \n        return preferredSize;\n    }\n\n    private void resetPreferredSize(boolean width, boolean height) {\n        if (preferredSize == null) return;\n        if (width) preferredSize.width = DIRTY;\n        if (height) preferredSize.height = DIRTY;\n    }\n\n    public void paint(Graphics g) {\n        int xx = location.x;\n        int h = size.height;\n        int hh = getPreferredSizeImpl().height; // lazily computes dirty metrics\n        \n        if (background != null && isOpaque()) {\n            g.setColor(background);\n            g.fillRect(xx, location.y, size.width, h);\n        }\n        \n        g.setFont(getFont());\n        \n        int hAlign = getHorizontalAlignment();\n        if (hAlign == LEADING) {\n            xx += margin.left;\n        } else if (hAlign == CENTER) {\n            int w = size.width - textWidth - iconWidth;\n            if (textWidth > 0 && iconWidth > 0 ) w -= iconTextGap;\n            xx += Math.max(margin.left, w / 2);\n        } else {\n            xx += size.width - margin.right - textWidth;\n            if (iconWidth > 0 ) xx += - iconWidth - iconTextGap;\n        }\n        \n        if (iconWidth > 0) {\n            int yy = (h - iconHeight) / 2;\n            icon.paintIcon(this, g, xx, location.y + yy);\n            xx += iconWidth + iconTextGap;\n        }\n        \n        if (textWidth > 0) {\n            int yy = (h - hh - fontSizeDiff) / 2 + margin.top;\n            UI.paintEnabledText(this, g, text, xx, location.y + yy + fontAscent);\n        }\n    }\n\n    // --- Tools ---------------------------------------------------------------\n    \n    private Point sharedPoint;\n    private Dimension sharedDimension;\n    private Rectangle sharedRectangle;\n    \n    protected final Point sharedPoint(int x, int y) {\n        if (sharedPoint == null) sharedPoint = new Point();\n        sharedPoint.x = x;\n        sharedPoint.y = y;\n        return sharedPoint;\n    }\n    \n    protected final Point sharedPoint(Point point) {\n        return sharedPoint(point.x, point.y);\n    }\n    \n    protected final Dimension sharedDimension(int width, int height) {\n        if (sharedDimension == null) sharedDimension = new Dimension();\n        sharedDimension.width = width;\n        sharedDimension.height = height;\n        return sharedDimension;\n    }\n    \n    protected final Dimension sharedDimension(Dimension dimension) {\n        return sharedDimension(dimension.width, dimension.height);\n    }\n    \n    protected final Rectangle sharedRectangle(int x, int y, int width, int height) {\n        if (sharedRectangle == null) sharedRectangle = new Rectangle();\n        sharedRectangle.x = x;\n        sharedRectangle.y = y;\n        sharedRectangle.width = width;\n        sharedRectangle.height = height;\n        return sharedRectangle;\n    }\n    \n    protected final Rectangle sharedRectangle(Rectangle rectangle) {\n        return sharedRectangle(rectangle.x, rectangle.y, rectangle.width, rectangle.height);\n    }\n    \n    // --- Geometry ------------------------------------------------------------\n    \n    protected final Point location = new Point();\n    protected final Dimension size = new Dimension();\n    \n    public void move(int x, int y) {\n        location.x = x;\n        location.y = y;\n    }\n    \n    public Point getLocation() {\n        return sharedPoint(location);\n    }\n    \n    public int getX() {\n        return location.x;\n    }\n    \n    public int getY() {\n        return location.y;\n    }\n    \n    public void setSize(int w, int h) {\n        size.width = w;\n        size.height = h;\n    }\n    \n    public Dimension getSize() {\n        return sharedDimension(size);\n    }\n    \n    public int getWidth() {\n        return size.width;\n    }\n    \n    public int getHeight() {\n        return size.height;\n    }\n    \n    public Rectangle getBounds() {\n        return sharedRectangle(location.x, location.y, size.width, size.height);\n    }\n    \n    public void reshape(int x, int y, int w, int h) {\n        // ignore x, y: used only for move(x, y)\n//        location.x = x;\n//        location.y = y;\n        size.width = w;\n        size.height = h;\n    }\n\n    // --- Margins -------------------------------------------------------------\n    \n    private final Insets insets = new Insets(0, 0, 0, 0);\n    private final Insets margin = new Insets(0, 0, 0, 0);\n    \n    public Insets getInsets() {\n        return insets;\n    }\n\n    public Insets getInsets(Insets insets) {\n        return this.insets;\n    }\n    \n    public void setMargin(int top, int left, int bottom, int right) {\n        margin.top = top;\n        margin.left = left;\n        margin.bottom = bottom;\n        margin.right = right;\n        resetPreferredSize(true, true);\n    }\n    \n    public Insets getMargin() {\n        return margin;\n    }\n\n    // --- Other performance tweaks ---------------------------------------------\n    \n    private FontMetrics fontMetrics;\n    private int fontSizeDiff;\n    private String text;\n    private Icon icon;\n    private Color foreground;\n    private Color background;\n    private boolean enabled = true;\n\n    public void setText(String text) {\n        this.text = text;\n        resetPreferredSize(true, false);\n    }\n\n    public String getText() {\n        return text;\n    }\n\n    public void setIcon(Icon icon) {\n        this.icon = icon;\n        iconWidth = icon == null ? 0 : icon.getIconWidth();\n        iconHeight = icon == null ? 0 : icon.getIconHeight();\n        resetPreferredSize(true, false); // Icon likely won't change height\n    }\n\n    public Icon getIcon() {\n        return icon;\n    }\n\n    public void setForeground(Color foreground) {\n        this.foreground = foreground;\n    }\n\n    public Color getForeground() {\n        return foreground;\n    }\n    \n    public void setBackground(Color background) {\n        this.background = background;\n    }\n\n    public Color getBackground() {\n        return background;\n    }\n\n    public void setEnabled(boolean enabled) {\n        this.enabled = enabled;\n    }\n\n    public boolean isEnabled() {\n        return enabled;\n    }\n\n    public int getDisplayedMnemonicIndex() {\n        return -1;\n    }\n\n    public FontMetrics getFontMetrics(Font font) {\n        return fontMetrics;\n    }\n\n    public void setFont(Font font) {\n        super.setFont(font);\n        fontMetrics = super.getFontMetrics(font);\n        resetPreferredSize(true, true);\n    }\n    \n    // Use to keep the baseline for various font-sized instances\n    public void changeFontSize(int diff) {\n        fontSizeDiff = diff;\n        Font font = getFont();\n        setFont(font.deriveFont(font.getSize2D() + diff));\n    }\n\n    public int getIconTextGap() {\n        return iconTextGap;\n    }\n\n\n    public void setIconTextGap(int iconTextGap) {\n        this.iconTextGap = iconTextGap;\n        resetPreferredSize(true, false);\n    }\n    \n    // --- Painting / Layout ---------------------------------------------------\n\n    public void validate() {}\n\n    public void revalidate() {}\n\n    public void repaint(long tm, int x, int y, int width, int height) {}\n\n    public void repaint(Rectangle r) {}\n\n    public void repaint() {}\n\n    public void setDisplayedMnemonic(int key) {}\n\n    public void setDisplayedMnemonic(char aChar) {}\n\n    public void setDisplayedMnemonicIndex(int index) {}\n    \n    // --- Events --------------------------------------------------------------\n\n    public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {}\n\n    public void firePropertyChange(String propertyName, char oldValue, char newValue) {}\n\n    public void firePropertyChange(String propertyName, short oldValue, short newValue) {}\n\n    public void firePropertyChange(String propertyName, int oldValue, int newValue) {}\n\n    public void firePropertyChange(String propertyName, long oldValue, long newValue) {}\n\n    public void firePropertyChange(String propertyName, float oldValue, float newValue) {}\n\n    public void firePropertyChange(String propertyName, double oldValue, double newValue) {}\n\n    public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}\n\n    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}\n\n\n    private static final class LabelRendererUI extends BasicLabelUI {\n        protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) {\n            super.paintEnabledText(l, g, s, textX, textY);\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/McsTimeRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.ui.Formatters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class McsTimeRenderer extends FormattedLabelRenderer implements RelativeRenderer {\n\n    protected boolean renderingDiff;\n\n    public McsTimeRenderer() {\n        super(Formatters.millisecondsFormat());\n        setHorizontalAlignment(SwingConstants.TRAILING);\n    }\n\n    public void setDiffMode(boolean diffMode) {\n        renderingDiff = diffMode;\n    }\n\n    public boolean isDiffMode() {\n        return renderingDiff;\n    }\n\n    public void setValue(Object value, int row) {\n        long lvalue = value == null ? 0 : ((Number)value).longValue();\n        String s = StringUtils.mcsTimeToString(lvalue);\n        if (renderingDiff && lvalue >= 0) s = '+' + s; // NOI18N\n        super.setValue(s, row);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/Movable.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\n/**\n * Marker interface for Components painting their UI with respect to [x, y]\n * coordinates.\n *\n * @author Jiri Sedlacek\n */\npublic interface Movable {\n\n    public void move(int x, int y);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/MultiRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport javax.swing.JComponent;\nimport javax.swing.SwingConstants;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class MultiRenderer extends BaseRenderer implements RelativeRenderer {\n\n    private Dimension preferredSize;\n\n\n    protected int renderersGap() { return 0; }\n\n    protected abstract ProfilerRenderer[] valueRenderers();\n\n\n    public void setDiffMode(boolean diffMode) {\n        ProfilerRenderer[] valueRenderers = valueRenderers();\n        if (valueRenderers == null) return;\n\n        for (ProfilerRenderer renderer : valueRenderers)\n            if (renderer instanceof RelativeRenderer)\n                ((RelativeRenderer)renderer).setDiffMode(diffMode);\n    }\n\n    public boolean isDiffMode() {\n        ProfilerRenderer[] valueRenderers = valueRenderers();\n        if (valueRenderers == null) return false;\n\n        for (ProfilerRenderer renderer : valueRenderers)\n            if (renderer instanceof RelativeRenderer)\n                return ((RelativeRenderer)renderer).isDiffMode();\n\n        return false;\n    }\n\n\n    public void setOpaque(boolean isOpaque) {\n        super.setOpaque(isOpaque);\n\n        ProfilerRenderer[] valueRenderers = valueRenderers();\n        if (valueRenderers == null) return;\n\n        for (ProfilerRenderer renderer : valueRenderers)\n            renderer.getComponent().setOpaque(isOpaque);\n    }\n\n    public void setForeground(Color foreground) {\n        super.setForeground(foreground);\n\n        ProfilerRenderer[] valueRenderers = valueRenderers();\n        if (valueRenderers == null) return;\n\n        for (ProfilerRenderer renderer : valueRenderers)\n            renderer.getComponent().setForeground(foreground);\n    }\n    \n    public void setBackground(Color background) {\n        super.setBackground(background);\n        \n        ProfilerRenderer[] valueRenderers = valueRenderers();\n        if (valueRenderers == null) return;\n        \n        for (ProfilerRenderer renderer : valueRenderers)\n            renderer.getComponent().setBackground(background);\n    }\n    \n    public Dimension getPreferredSize() {\n        if (preferredSize == null) preferredSize = new Dimension();\n        else preferredSize.setSize(0, 0);\n        \n        ProfilerRenderer[] valueRenderers = valueRenderers();\n        if (valueRenderers != null) {\n            int visible = 0;\n            for (ProfilerRenderer renderer : valueRenderers) {\n                JComponent component = renderer.getComponent();\n                if (component.isVisible()) {\n                    Dimension rendererSize = component.getPreferredSize();\n                    preferredSize.width += rendererSize.width;\n                    preferredSize.height = Math.max(preferredSize.height, rendererSize.height);\n                    visible++;\n                }\n            }\n            preferredSize.width += renderersGap() * (visible - 1);\n        }\n        \n        return sharedDimension(preferredSize);\n    }\n    \n    \n    public void paint(Graphics g) {\n        super.paint(g);\n        \n        int alignment = getHorizontalAlignment();\n        int renderersGap = renderersGap();\n        \n        if (alignment == SwingConstants.LEADING || alignment == SwingConstants.LEFT) {\n            \n            int xx = location.x;\n            \n            for (ProfilerRenderer renderer : valueRenderers()) {\n                JComponent component = renderer.getComponent();\n                if (component.isVisible()) {\n                    int componentWidth = component.getPreferredSize().width;\n                    component.setSize(componentWidth, size.height);\n                    renderer.move(xx, location.y);\n                    component.paint(g);\n                    xx += componentWidth + renderersGap;\n                }\n            }\n            \n        } else {\n            \n            int xx = location.x + size.width;\n            \n            ProfilerRenderer[] valueRenderers = valueRenderers();\n            for (int i = valueRenderers.length - 1; i >= 0; i--) {\n                ProfilerRenderer renderer = valueRenderers[i];\n                JComponent component = renderer.getComponent();\n                if (component.isVisible()) {\n                    int componentWidth = component.getPreferredSize().width;\n                    component.setSize(componentWidth, size.height);\n                    xx -= componentWidth;\n                    renderer.move(xx, location.y);\n                    component.paint(g);\n                    xx -= renderersGap;\n                }\n            }\n            \n        }\n    }\n    \n    public String toString() {\n        StringBuilder sb = new StringBuilder();\n        ProfilerRenderer[] renderers = valueRenderers();\n        if (renderers != null)\n            for (ProfilerRenderer renderer : renderers)\n                if (renderer.getComponent().isVisible())\n                    sb.append(renderer.toString());\n        return sb.toString();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/NormalBoldGrayRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.util.Objects;\nimport javax.swing.Icon;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class NormalBoldGrayRenderer extends MultiRenderer {\n\n    private final LabelRenderer normalRenderer;\n    private final LabelRenderer boldRenderer;\n    private final LabelRenderer grayRenderer;\n\n    private final ProfilerRenderer[] renderers;\n\n    private Color customForeground;\n    private Color replaceableForeground = UIUtils.getDefaultTableForeground();\n\n\n    public NormalBoldGrayRenderer() {\n        normalRenderer = new LabelRenderer(true) {\n            public void setForeground(Color foreground) {\n                if (customForeground != null && Objects.equals(foreground, replaceableForeground)) foreground = customForeground;\n                super.setForeground(foreground);\n            }\n        };\n        normalRenderer.setMargin(3, 3, 3, 0);\n\n        boldRenderer = new LabelRenderer(true) {\n            public void setForeground(Color foreground) {\n                if (customForeground != null && Objects.equals(foreground, replaceableForeground)) foreground = customForeground;\n                super.setForeground(foreground);\n            }\n        };\n        boldRenderer.setMargin(3, 0, 3, 0);\n        Font font = boldRenderer.getFont();\n        boldRenderer.setFont(font.deriveFont(Font.BOLD));\n\n        grayRenderer = new LabelRenderer(true) {\n            public void setForeground(Color foreground) {\n                if (Objects.equals(foreground, replaceableForeground)) {\n                    if (customForeground != null && supportsCustomGrayForeground()) super.setForeground(customForeground);\n                    else super.setForeground(UIUtils.getDisabledForeground(foreground == null ? Color.BLACK : foreground));\n                } else {\n                    super.setForeground(foreground);\n                }\n            }\n        };\n        grayRenderer.setMargin(3, 0, 3, 3);\n        \n        renderers = new ProfilerRenderer[] { normalRenderer, boldRenderer, grayRenderer };\n        \n        setOpaque(true);\n        setHorizontalAlignment(SwingConstants.LEADING);\n    }\n    \n    \n    protected void setCustomForeground(Color foreground) {\n        customForeground = foreground;\n    }\n    \n    public void setReplaceableForeground(Color foreground) {\n        replaceableForeground = foreground;\n    }\n    \n    protected boolean supportsCustomGrayForeground() {\n        return true;\n    }\n\n    \n    protected ProfilerRenderer[] valueRenderers() {\n        return renderers;\n    }\n    \n    \n    protected void setNormalValue(String value) {\n        normalRenderer.setText(value);\n    }\n    \n    public final String getNormalValue() {\n        return normalRenderer.getText();\n    }\n    \n    protected void setBoldValue(String value) {\n        boldRenderer.setText(value);\n    }\n    \n    public final String getBoldValue() {\n        return boldRenderer.getText();\n    }\n    \n    protected void setGrayValue(String value) {\n        grayRenderer.setText(value);\n    }\n    \n    public final String getGrayValue() {\n        return grayRenderer.getText();\n    }\n    \n    // Invoke after values are set!\n    protected void setIcon(Icon icon) {\n        String text = normalRenderer.getText();\n        if (text == null || text.isEmpty()) {\n            normalRenderer.setIcon(null);\n            text = boldRenderer.getText();\n            if (text == null || text.isEmpty()) {\n                boldRenderer.setIcon(null);\n                grayRenderer.setIcon(icon);\n            } else {\n                boldRenderer.setIcon(icon);\n                grayRenderer.setIcon(null);\n            }\n        } else {\n            normalRenderer.setIcon(icon);\n            boldRenderer.setIcon(null);\n            grayRenderer.setIcon(null);\n        }\n    }\n    \n    public Icon getIcon() {\n        Icon icon = normalRenderer.getIcon();\n        if (icon == null) icon = boldRenderer.getIcon();\n        if (icon == null) icon = grayRenderer.getIcon();\n        return icon;\n    }\n    \n    // Invoke after values are set!\n    protected void setIconTextGap(int gap) {\n        String text = normalRenderer.getText();\n        if (text == null || text.isEmpty()) {\n//            normalRenderer.setIcon(null);\n            text = boldRenderer.getText();\n            if (text == null || text.isEmpty()) {\n//                boldRenderer.setIcon(null);\n                grayRenderer.setIconTextGap(gap);\n            } else {\n                boldRenderer.setIconTextGap(gap);\n//                grayRenderer.setIcon(null);\n            }\n        } else {\n            normalRenderer.setIconTextGap(gap);\n//            boldRenderer.setIcon(null);\n//            grayRenderer.setIcon(null);\n        }\n    }\n        \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/NumberPercentRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.text.Format;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class NumberPercentRenderer extends MultiRenderer {\n\n    private final ProfilerRenderer valueRenderer;\n    private final PercentRenderer percentRenderer;\n\n    private final ProfilerRenderer[] renderers;\n\n    private Dimension percentSize;\n\n\n    public NumberPercentRenderer() {\n        this((Format)null);\n    }\n\n    public NumberPercentRenderer(Format customFormat) {\n        this(createNumberRenderer(customFormat));\n    }\n\n    public NumberPercentRenderer(ProfilerRenderer renderer) {\n        valueRenderer = renderer;\n\n        percentRenderer = new PercentRenderer() {\n            public void setForeground(Color foreground) {\n                if (foreground == null) foreground = Color.BLACK;\n                super.setForeground(UIUtils.getDisabledForeground(foreground));\n            }\n            public Dimension getPreferredSize() {\n                if (percentSize == null) percentSize = super.getPreferredSize();\n                return percentSize;\n            }\n        };\n        percentRenderer.changeFontSize(-1);\n        percentRenderer.setMargin(3, 0, 3, 3);\n        percentRenderer.setHorizontalAlignment(SwingConstants.TRAILING);\n\n        percentRenderer.setMaxValue(100);\n        percentRenderer.setValue(9999, -1);\n        int fixedWidth = percentRenderer.getPreferredSize().width;\n        percentSize.width = fixedWidth;\n\n        renderers = new ProfilerRenderer[] { valueRenderer, percentRenderer };\n\n        setOpaque(true);\n        setHorizontalAlignment(SwingConstants.TRAILING);\n    }\n\n\n    protected ProfilerRenderer[] valueRenderers() {\n        return renderers;\n    }\n    \n    \n    public void setMaxValue(long maxValue) {\n        percentRenderer.setMaxValue(maxValue);\n    }\n    \n    public void setValue(Object value, int row) {\n        valueRenderer.setValue(value, row);\n        percentRenderer.setValue(value, row);\n    }\n    \n    \n    public void setDiffMode(boolean diffMode) {\n        percentRenderer.setVisible(!diffMode);\n        super.setDiffMode(diffMode);\n    }\n    \n    \n    public Dimension getPreferredSize() {\n        Dimension dim = valueRenderer.getComponent().getPreferredSize();\n        if (percentRenderer.isVisible()) dim.width += percentRenderer.getPreferredSize().width;\n        return sharedDimension(dim);\n    }\n    \n    \n    private static ProfilerRenderer createNumberRenderer(Format customFormat) {\n        NumberRenderer numberRenderer = new NumberRenderer(customFormat);\n        numberRenderer.setMargin(3, 3, 3, 3);\n        return numberRenderer;\n    }\n    \n    \n    public String toString() {\n        if (!percentRenderer.isVisible()) return valueRenderer.toString();\n        else return valueRenderer.toString() + \" \" + percentRenderer.toString(); // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/NumberRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport java.text.Format;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.ui.Formatters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class NumberRenderer extends FormattedLabelRenderer implements RelativeRenderer {\n\n    private final Format outputFormat;\n\n    protected boolean renderingDiff;\n\n    public NumberRenderer() {\n        this(null);\n    }\n\n    public NumberRenderer(Format outputFormat) {\n        super(Formatters.numberFormat());\n\n        this.outputFormat = outputFormat;\n\n        setHorizontalAlignment(SwingConstants.TRAILING);\n    }\n\n    public void setDiffMode(boolean diffMode) {\n        renderingDiff = diffMode;\n    }\n\n    public boolean isDiffMode() {\n        return renderingDiff;\n    }\n\n    protected String getValueString(Object value, int row, Format format) {\n        if (value == null) return \"-\"; // NOI18N\n        String s = super.getValueString(value, row, format);\n        s = outputFormat == null ? s : formatImpl(outputFormat, s);\n        if (renderingDiff && value instanceof Number)\n            if (((Number)value).doubleValue() >= 0) s = '+' + s; // NOI18N\n        return s;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/PercentRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport java.text.Format;\nimport org.graalvm.visualvm.lib.ui.Formatters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class PercentRenderer extends FormattedLabelRenderer implements RelativeRenderer {\n\n    private static final String NUL = Formatters.percentFormat().format(0);\n    private static final String NAN = NUL.replace('0', '-');  // NOI18N\n\n    private long maxValue = 100;\n\n    protected boolean renderingDiff;\n\n\n    public PercentRenderer() {\n        super(Formatters.percentFormat());\n    }\n\n\n    public void setMaxValue(long maxValue) {\n        this.maxValue = maxValue;\n    }\n\n    public long getMaxValue() {\n        return maxValue;\n    }\n\n\n    public void setDiffMode(boolean diffMode) {\n        renderingDiff = diffMode;\n    }\n\n    public boolean isDiffMode() {\n        return renderingDiff;\n    }\n\n\n    protected String getValueString(Object value, int row, Format format) {\n        if (value == null) return \"-\"; // NOI18N\n\n        StringBuilder s = new StringBuilder();\n        s.append(\"(\"); // NOI18N\n\n        if (maxValue == 0) {\n            s.append(NAN);\n        } else {\n            double number = ((Number)value).doubleValue();\n            if (number == 0) {\n                if (renderingDiff) s.append('+'); // NOI18N\n                s.append(NUL);\n            } else {\n                number = number / maxValue;\n                if (renderingDiff && number > 0) s.append('+'); // NOI18N\n                s.append(format.format(number));\n            }\n        }\n\n        s.append(\")\"); // NOI18N\n        return s.toString();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/ProfilerRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\nimport javax.accessibility.Accessible;\nimport javax.swing.JComponent;\n\n/**\n * Interface to be implemented by each custom renderer.\n *\n * @author Jiri Sedlacek\n */\npublic interface ProfilerRenderer extends Movable, Accessible {\n\n    public void setValue(Object value, int row);\n\n    public int getHorizontalAlignment();\n\n    public JComponent getComponent();\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/swing/renderer/RelativeRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui.swing.renderer;\n\n/**\n * Interface to be implemented by renderers supporting relative (diff) values.\n *\n * @author Jiri Sedlacek\n */\npublic interface RelativeRenderer {\n\n    public void setDiffMode(boolean diffMode);\n\n    public boolean isDiffMode();\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/threads/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nACT_ZoomIn=Zoom in\nACT_ZoomOut=Zoom out\nACT_ScaleToFit=Scale to fit\n\nCOL_Selected=Selected\nCOL_Name=Name\nCOL_Timeline=Timeline\nCOL_Total=Total\nDESC_Selected=Thread selection\nDESC_Name=Thread name\nDESC_Timeline=Thread states timeline\nDESC_Running=Time spent in Running state\nDESC_Sleeping=Time spent in Sleeping state\nDESC_Wait=Time spent in Wait state\nDESC_Park=Time spent in Park state\nDESC_Monitor=Time spent in Monitor state\nDESC_Total=Total thread time\nLBL_View=View:\nOPT_AllThreads=All threads\nOPT_LiveThreads=Live threads\nOPT_FinishedThreads=Finished threads\nMSG_NoProfiling=No profiling session currently in progress.\nMSG_ThreadsDisabled=Threads monitoring is currently disabled. Press the button to enable it:\nDESC_ThreadsDisabled=Press to enable threads monitoring for this profiling session.\nACT_SelectThread=Select thread\nACT_UnselectThread=Unselect thread\n\nTimelineRenderer_ThreadStateRunning=running\nTimelineRenderer_ThreadStateSleeping=sleeping\nTimelineRenderer_ThreadStateMonitor=monitor\nTimelineRenderer_ThreadStateWait=wait\nTimelineRenderer_ThreadStatePark=park\nTimelineRenderer_ThreadStateFinished=finished\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/threads/NameStateRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.threads;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadData;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class NameStateRenderer extends LabelRenderer {\n\n    public NameStateRenderer() {\n        setOpaque(true);\n        setMargin(3, 4, 3, 4);\n    }\n\n    public void setValue(Object value, int row) {\n        if (value == null) {\n            setText(\"\"); // NOI18N\n            setIcon(null);\n        } else {\n            ThreadData data = (ThreadData)value;\n            setText(data.getName());\n            setIcon(getIcon(data.getLastState()));\n        }\n    }\n\n    private static final int THREAD_ICON_SIZE = 9;\n    private static final Map<Byte, Icon> STATE_ICONS_CACHE = new HashMap<>();\n    private static Icon getIcon(byte state) {\n        Icon icon = STATE_ICONS_CACHE.get(state);\n\n        if (icon == null) {\n            icon = new ThreadStateIcon(state, THREAD_ICON_SIZE, THREAD_ICON_SIZE);\n            STATE_ICONS_CACHE.put(state, icon);\n        }\n\n        return icon;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/threads/ThreadStateIcon.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.threads;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Graphics;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadData;\n\n\n/**\n * @author Jiri Sedlacek\n */\npublic class ThreadStateIcon implements Icon {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final int ICON_NONE = -100;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected Color threadStateColor;\n    protected int height;\n    protected int width;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ThreadStateIcon(int threadState, int width, int height) {\n        this.threadStateColor = getThreadStateColor(threadState);\n        this.width = width;\n        this.height = height;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getIconHeight() {\n        return height;\n    }\n\n    public int getIconWidth() {\n        return width;\n    }\n\n    public void paintIcon(Component c, Graphics g, int x, int y) {\n        if (threadStateColor != null) {\n            g.setColor(threadStateColor);\n            g.fillRect(x + 1, y + 1, width - 1, height - 1);\n        }\n        g.setColor(Color.BLACK);\n        g.drawRect(x, y, width - 1, height - 1);\n    }\n\n    protected Color getThreadStateColor(int threadState) {\n        if (threadState == ICON_NONE) return null;\n        return ThreadData.getThreadStateColor(threadState);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/threads/ThreadTimeRelRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.threads;\n\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadsDataManager;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ThreadTimeRelRenderer extends HideableBarRenderer {\n\n    private final ThreadsDataManager manager;\n\n    public ThreadTimeRelRenderer(ThreadsDataManager manager) {\n        super(new NumberPercentRenderer(Formatters.millisecondsFormat()));\n        this.manager = manager;\n    }\n\n    public void setValue(Object value, int row) {\n        if (row > -1) setMaxValue(manager.getThreadData(row).getTotalTime(manager.getEndTime()));\n        super.setValue(value, row);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/threads/ThreadsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.threads;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.FlowLayout;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.image.BufferedImage;\nimport java.util.HashSet;\nimport java.util.ResourceBundle;\nimport java.util.Set;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.RowFilter;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingConstants;\nimport javax.swing.table.AbstractTableModel;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumn;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.DataManagerListener;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadData;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadsDataManager;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.results.DataView;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.CheckBoxRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ThreadsPanel extends DataView {\n    \n    private static ResourceBundle BUNDLE() {\n        return ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.threads.Bundle\"); // NOI18N\n    }\n    \n    public static enum Filter { ALL, LIVE, FINISHED, SELECTED }\n    \n    private final ThreadsDataManager dataManager;\n    private final ViewManager viewManager;\n    \n    private DataManagerListener listener;\n    \n    private ProfilerTable threadsTable;\n    private ProfilerTableContainer threadsTableContainer;\n    private JPanel bottomPanel;\n    private JPanel legendPanel;\n    \n    private Filter filter = Filter.ALL;\n    \n    private final Set<Integer> selected = new HashSet<>();\n    private final Set<Integer> selectedApplied = new HashSet<>();\n    \n    private Component zoomInAction;\n    private Component zoomOutAction;\n    private Component fitAction;\n    \n    private ThreadTimeRelRenderer timeRelRenderer;\n    \n    private long lastTimestamp;\n    \n    \n    public ThreadsPanel(ThreadsDataManager dataManager, Action saveView) {\n        this.dataManager = dataManager;\n        lastTimestamp = dataManager.getEndTime();\n        viewManager = new ViewManager(2, dataManager) {\n            public void columnWidthChanged(int column, int oldW, int newW) {\n                if (column == 2 && isFit()) threadsTable.updateColumnPreferredWidth(2);\n                super.columnWidthChanged(column, oldW, newW);\n            }\n            public void columnOffsetChanged(int column, int oldO, int newO) {\n                super.columnOffsetChanged(column, oldO, newO);\n                if (column == 2) repaintTimeline();\n            }\n            public void zoomChanged(double oldZoom, double newZoom) {\n                super.zoomChanged(oldZoom, newZoom);\n                repaintTimeline();\n            }\n        };\n        \n        initUI(saveView);\n    }\n    \n    \n    public void setFilter(Filter filter) {\n        selectedApplied.clear();\n        if (Filter.SELECTED.equals(filter)) selectedApplied.addAll(selected);\n        \n        this.filter = filter;\n        threadsTable.addRowFilter(new ThreadsFilter());\n        \n        filterSelected(filter);\n    }\n    \n    public Filter getFilter() {\n        return filter;\n    }\n    \n    protected void filterSelected(Filter filter) {}\n    \n    public boolean hasSelectedThreads() {\n        return !selected.isEmpty();\n    }\n    \n    public void showSelectedColumn() {\n        threadsTable.setColumnVisibility(0, true);\n    }\n    \n    \n    public void cleanup() {\n        dataManager.removeDataListener(listener);\n    }\n    \n    \n    private void initUI(Action saveView) {\n        setOpaque(true);\n        setBackground(new HTMLTextArea().getBackground());\n        \n        final AbstractTableModel threadsTableModel = new AbstractTableModel() {\n            public String getColumnName(int columnIndex) {\n                if (columnIndex == 0) {\n                    return BUNDLE().getString(\"COL_Selected\"); // NOI18N\n                } else if (columnIndex == 1) {\n                    return BUNDLE().getString(\"COL_Name\"); // NOI18N\n                } else if (columnIndex == 2) {\n                    return BUNDLE().getString(\"COL_Timeline\"); // NOI18N\n                } else if (columnIndex == 3) {\n                    return CommonConstants.THREAD_STATUS_RUNNING_STRING;\n                } else if (columnIndex == 4) {\n                    return CommonConstants.THREAD_STATUS_SLEEPING_STRING;\n                } else if (columnIndex == 5) {\n                    return CommonConstants.THREAD_STATUS_WAIT_STRING;\n                } else if (columnIndex == 6) {\n                    return CommonConstants.THREAD_STATUS_PARK_STRING;\n                } else if (columnIndex == 7) {\n                    return CommonConstants.THREAD_STATUS_MONITOR_STRING;\n                } else if (columnIndex == 8) {\n                    return BUNDLE().getString(\"COL_Total\"); // NOI18N\n                }\n                return null;\n            }\n            \n            public Class<?> getColumnClass(int columnIndex) {\n                if (columnIndex == 0) {\n                    return Boolean.class;\n                } else if (columnIndex == 1) {\n                    return ThreadData.class;\n                } else if (columnIndex == 2) {\n                    return ViewManager.RowView.class;\n                } else {\n                    return Long.class;\n                }\n            }\n\n            public int getRowCount() {\n                return dataManager.getThreadsCount();\n            }\n\n            public int getColumnCount() {\n                return 9;\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                if (columnIndex == 0) {\n                    return selected.contains(rowIndex);\n                } else if (columnIndex == 1) {\n                    return getData(rowIndex);\n                } else if (columnIndex == 2) {\n                    return viewManager.getRowView(rowIndex);\n                } else if (columnIndex == 3) {\n                    return getData(rowIndex).getRunningTime(lastTimestamp);\n                } else if (columnIndex == 4) {\n                    return getData(rowIndex).getSleepingTime(lastTimestamp);\n                } else if (columnIndex == 5) {\n                    return getData(rowIndex).getWaitTime(lastTimestamp);\n                } else if (columnIndex == 6) {\n                    return getData(rowIndex).getParkTime(lastTimestamp);\n                } else if (columnIndex == 7) {\n                    return getData(rowIndex).getMonitorTime(lastTimestamp);\n                } else if (columnIndex == 8) {\n                    return getData(rowIndex).getTotalTime(lastTimestamp);\n                }\n                \n                return null;\n            }\n            \n            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {\n                if (columnIndex == 0) {\n                    if (Boolean.FALSE.equals(aValue)) selected.remove(rowIndex);\n                    else selected.add(rowIndex);\n                }\n            }\n            \n            public boolean isCellEditable(int rowIndex, int columnIndex) {\n                return columnIndex == 0;\n            }\n            \n            private ThreadData getData(int rowIndex) {\n                return dataManager.getThreadData(rowIndex);\n            }\n        \n        };\n        \n        threadsTable = new ProfilerTable(threadsTableModel, true, true, new int[] { 2 }) {\n            protected int computeColumnPreferredWidth(int modelIndex, int viewIndex, int firstRow, int lastRow) {\n                if (modelIndex != 2) return super.computeColumnPreferredWidth(modelIndex, viewIndex, firstRow, lastRow);\n                \n                viewManager.update();\n                \n                if (viewManager.isFit()) {\n                    return getTableHeader().getHeaderRect(viewIndex).width;\n                } else {\n                    return viewManager.getViewWidth();\n                }\n            }\n            public Object getUserValueForRow(int row) {\n                if (row == -1) return null;\n                if (row >= getModel().getRowCount()) return null; // #239936\n                return Integer.valueOf(convertRowIndexToModel(row));\n            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                if (userValue != null) {\n                    final int row = ((Integer)userValue).intValue();\n                    final boolean sel = selected.contains(row);\n                    popup.add(new JMenuItem(sel ? BUNDLE().getString(\"ACT_UnselectThread\") :\n                                                  BUNDLE().getString(\"ACT_SelectThread\")) { // NOI18N\n                        protected void fireActionPerformed(ActionEvent e) {\n                            if (sel) selected.remove(row);\n                            else selected.add(row);\n                            threadsTableModel.fireTableDataChanged();\n                            if (!sel) showSelectedColumn();\n                        }\n                    });\n\n                    popup.addSeparator();\n                }\n                \n                popup.add(createCopyMenuItem());\n                popup.addSeparator();\n                \n                popup.add(new JMenuItem(FilterUtils.ACTION_FILTER) {\n                    protected void fireActionPerformed(ActionEvent e) { activateFilter(); }\n                });\n                popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {\n                    protected void fireActionPerformed(ActionEvent e) { activateSearch(); }\n                });\n            }\n        };\n        threadsTable.setColumnVisibility(0, false);\n        threadsTable.setMainColumn(1);\n        threadsTable.setColumnToolTips(new String[] { BUNDLE().getString(\"DESC_Selected\"), // NOI18N\n                                                      BUNDLE().getString(\"DESC_Name\"), // NOI18N\n                                                      BUNDLE().getString(\"DESC_Timeline\"), // NOI18N\n                                                      BUNDLE().getString(\"DESC_Running\"), // NOI18N\n                                                      BUNDLE().getString(\"DESC_Sleeping\"), // NOI18N\n                                                      BUNDLE().getString(\"DESC_Wait\"), // NOI18N\n                                                      BUNDLE().getString(\"DESC_Park\"), // NOI18N\n                                                      BUNDLE().getString(\"DESC_Monitor\"), // NOI18N\n                                                      BUNDLE().getString(\"DESC_Total\") }); // NOI18N\n        threadsTable.setDefaultSortOrder(1, SortOrder.ASCENDING);\n        threadsTable.setDefaultSortOrder(2, SortOrder.ASCENDING);\n        threadsTable.setSecondarySortColumn(1); // Simple way for stable sorting, should use threadID\n        threadsTable.setSortColumn(2);\n        threadsTable.setFitWidthColumn(2);\n        NameStateRenderer nameStateRenderer = new NameStateRenderer();\n        nameStateRenderer.setText(\"THREADnameTOsetupCOLUMNwidth\"); // NOI18N\n        threadsTable.setColumnRenderer(0, new CheckBoxRenderer());\n        threadsTable.setDefaultRenderer(ThreadData.class, nameStateRenderer);\n        threadsTable.setDefaultRenderer(ViewManager.RowView.class, new TimelineRenderer(viewManager));\n        int w = new JLabel(threadsTable.getColumnName(0)).getPreferredSize().width;\n        threadsTable.setDefaultColumnWidth(0, w + 15);\n        threadsTable.setDefaultColumnWidth(1, nameStateRenderer.getPreferredSize().width);\n        \n        final JTableHeader header = threadsTable.getTableHeader();\n        TableCellRenderer headerRenderer = header.getDefaultRenderer();\n        header.setDefaultRenderer(new TimelineHeaderRenderer(headerRenderer, 2, viewManager));\n        \n        Number refTime = new Long(1234567);\n        \n        timeRelRenderer = new ThreadTimeRelRenderer(dataManager);\n        timeRelRenderer.setMaxValue(refTime.longValue());\n        threadsTable.setDefaultColumnWidth(timeRelRenderer.getNoBarWidth());\n        threadsTable.setDefaultRenderer(Long.class, timeRelRenderer);\n        \n        NumberRenderer numberRenderer = new NumberRenderer(Formatters.millisecondsFormat());\n        numberRenderer.setValue(refTime, -1);\n        threadsTable.setDefaultColumnWidth(8, numberRenderer.getPreferredSize().width);\n        threadsTable.setColumnRenderer(8, numberRenderer);\n        \n        threadsTable.setColumnVisibility(4, false);\n        threadsTable.setColumnVisibility(5, false);\n        threadsTable.setColumnVisibility(6, false);\n        threadsTable.setColumnVisibility(7, false);\n        \n        threadsTable.providePopupMenu(true);\n        \n        threadsTableContainer = new ProfilerTableContainer(threadsTable, false, viewManager);\n        \n        legendPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING, 7, 8));\n        legendPanel.setOpaque(false);\n        \n        ThreadStateIcon runningIcon = new ThreadStateIcon(CommonConstants.THREAD_STATUS_RUNNING, 18, 9);\n        JLabel runningLegend = new JLabel(CommonConstants.THREAD_STATUS_RUNNING_STRING, runningIcon, SwingConstants.LEADING);\n        runningLegend.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n        legendPanel.add(runningLegend);\n        ThreadStateIcon sleepingIcon = new ThreadStateIcon(CommonConstants.THREAD_STATUS_SLEEPING, 18, 9);\n        JLabel sleepingLegend = new JLabel(CommonConstants.THREAD_STATUS_SLEEPING_STRING, sleepingIcon, SwingConstants.LEADING);\n        sleepingLegend.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n        legendPanel.add(sleepingLegend);\n        ThreadStateIcon waitIcon = new ThreadStateIcon(CommonConstants.THREAD_STATUS_WAIT, 18, 9);\n        JLabel waitLegend = new JLabel(CommonConstants.THREAD_STATUS_WAIT_STRING, waitIcon, SwingConstants.LEADING);\n        waitLegend.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n        legendPanel.add(waitLegend);\n        ThreadStateIcon parkIcon = new ThreadStateIcon(CommonConstants.THREAD_STATUS_PARK, 18, 9);\n        JLabel parkLegend = new JLabel(CommonConstants.THREAD_STATUS_PARK_STRING, parkIcon, SwingConstants.LEADING);\n        parkLegend.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n        legendPanel.add(parkLegend);\n        ThreadStateIcon monitorIcon = new ThreadStateIcon(CommonConstants.THREAD_STATUS_MONITOR, 18, 9);\n        JLabel monitorLegend = new JLabel(CommonConstants.THREAD_STATUS_MONITOR_STRING, monitorIcon, SwingConstants.LEADING);\n        monitorLegend.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));\n        legendPanel.add(monitorLegend);\n        \n        final Action zoomIn = viewManager.zoomInAction();\n        zoomInAction = new JButton(zoomIn) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                Object newOffset = zoomIn.getValue(ViewManager.PROP_NEW_OFFSET);\n                if (newOffset != null) {\n                    int _newOffset = ((Integer)newOffset).intValue();\n                    threadsTable.setColumnOffset(2, _newOffset);\n                }\n                threadsTableModel.fireTableDataChanged();\n            }\n            public boolean isEnabled() {\n                return threadsTable.isShowing() && super.isEnabled();\n            }\n        };\n        \n        final Action zoomOut = viewManager.zoomOutAction();\n        zoomOutAction = new JButton(zoomOut) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                Object newOffset = zoomOut.getValue(ViewManager.PROP_NEW_OFFSET);\n                if (newOffset != null) {\n                    int _newOffset = ((Integer)newOffset).intValue();\n                    threadsTable.setColumnOffset(2, _newOffset);\n                }\n                threadsTableModel.fireTableDataChanged();\n            }\n            public boolean isEnabled() {\n                return threadsTable.isShowing() && super.isEnabled();\n            }\n        };\n        \n        fitAction = new JToggleButton(viewManager.fitAction()) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                threadsTableModel.fireTableDataChanged();\n            }\n        };\n        fitAction.setEnabled(false);\n        \n        bottomPanel = new JPanel(new BorderLayout());\n        bottomPanel.setOpaque(false);\n        bottomPanel.add(legendPanel, BorderLayout.SOUTH);\n        \n        setOpaque(true);\n        setBackground(UIUtils.getProfilerResultsBackground());\n        setLayout(new BorderLayout());\n        add(threadsTableContainer, BorderLayout.CENTER);\n        add(bottomPanel, BorderLayout.SOUTH);\n        \n        listener = new DataManagerListener() {\n            private boolean firstChange = true;\n            public void dataChanged() {\n                lastTimestamp = dataManager.getEndTime();\n                if (firstChange) {\n                    firstChange = false;\n                    repaintTimeline();\n                }\n                threadsTableModel.fireTableDataChanged();\n            }\n            public void dataReset() {\n                viewManager.reset();\n                firstChange = true;\n                timeRelRenderer.setMaxValue(0);\n                threadsTableModel.fireTableDataChanged();\n            }\n        };\n        dataManager.addDataListener(listener);\n        \n        registerActions();\n    }\n    \n    private void registerActions() {\n        ActionMap map = getActionMap();\n        \n        map.put(FilterUtils.FILTER_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { activateFilter(); }\n        });\n        \n        map.put(SearchUtils.FIND_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { activateSearch(); }\n        });\n    }\n    \n    protected ProfilerTable getResultsComponent() {\n        return threadsTable;\n    }\n    \n    protected boolean hasBottomFilterFindMargin() {\n        return true;\n    }\n    \n    protected void addFilterFindPanel(JComponent comp) {\n        bottomPanel.add(comp, BorderLayout.NORTH);\n    }\n    \n    private void repaintTimeline() {\n        JTableHeader header = threadsTable.getTableHeader();\n        TableColumn draggedColumn = header.getDraggedColumn();\n        if (draggedColumn != null && draggedColumn.getModelIndex() == 2) {\n            header.repaint();\n        } else {\n            int _column = threadsTable.convertColumnIndexToView(2);\n            header.repaint(header.getHeaderRect(_column));\n        }\n    }\n    \n    public Component getToolbar() {\n        return null;\n    }\n    \n    public Component getZoomIn() {\n        return zoomInAction;\n    }\n    \n    public Component getZoomOut() {\n        return zoomOutAction;\n    }\n    \n    public Component getFitWidth() {\n        return fitAction;\n    }\n    \n    public BufferedImage getCurrentViewScreenshot(boolean onlyVisibleArea) {\n        return threadsTableContainer.createTableScreenshot(onlyVisibleArea);\n    }\n    \n    public boolean fitsVisibleArea() {\n        return !threadsTableContainer.tableNeedsScrolling();\n    }\n\n    public boolean hasView() {\n        return threadsTableContainer.isShowing();\n    }\n    \n    public void threadsMonitoringDisabled() {\n        fitAction.setEnabled(false);\n    }\n\n    public void threadsMonitoringEnabled() {\n        fitAction.setEnabled(true);\n    }\n    \n    public void profilingSessionStarted() {\n        selected.clear();\n        if (!selectedApplied.isEmpty()) setFilter(Filter.LIVE);\n    }\n    \n    public void profilingSessionFinished() {\n    }\n    \n    public void addThreadsMonitoringActionListener(ActionListener listener) {\n    }\n    \n    \n    private final class ThreadsFilter extends RowFilter {\n        \n        public boolean include(RowFilter.Entry entry) {\n            ThreadData data = (ThreadData)entry.getValue(1);\n            switch (filter) {\n                case LIVE: return ThreadData.isAliveState(data.getLastState());\n                case FINISHED: return !ThreadData.isAliveState(data.getLastState());\n                case SELECTED: return selectedApplied.contains(entry.getIdentifier());\n                default: return true;\n            }\n        }\n        \n        public boolean equals(Object o) {\n            return o instanceof ThreadsFilter;\n        }\n        \n        public int hashCode() {\n            return Integer.MAX_VALUE - 11;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/threads/TimelineHeaderRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.threads;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport javax.swing.JTable;\nimport javax.swing.UIManager;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumn;\nimport org.graalvm.visualvm.lib.charts.axis.TimeAxisUtils;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.BaseRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class TimelineHeaderRenderer extends BaseRenderer implements TableCellRenderer {\n\n    private final TableCellRenderer impl;\n    private final int column;\n\n    private final ViewManager view;\n\n\n    public TimelineHeaderRenderer(TableCellRenderer impl, int column, ViewManager view) {\n        this.impl = impl;\n        this.column = column;\n        this.view = view;\n    }\n\n\n    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {\n        boolean timelineColumn = column == table.convertColumnIndexToModel(col);\n        setVisible(timelineColumn);\n\n        Component c = impl.getTableCellRendererComponent(table, timelineColumn ?\n                      \" \" : value, isSelected, hasFocus, row, col); // NOI18N\n        if (timelineColumn) {\n            if (getParent() == null && c instanceof Container) ((Container)c).add(this);\n\n            JTableHeader header = table.getTableHeader();\n            if (painter == null) initStaticUI(c, header);\n\n            TableColumn _column = header.getColumnModel().getColumn(col);\n\n            setSize(_column.getWidth(), header.getSize().height);\n        }\n        \n        return c;\n    }\n    \n    public void paint(Graphics g) {        \n        long time = view.getFirstTimeMark(true);\n        long step = view.getTimeMarksStep();\n        String format = view.getTimeMarksFormat();\n        \n        int w = getWidth();\n        int h = getHeight();\n        int x = view.getTimePosition(time, true);\n        \n        g.setColor(painter.getForeground());\n        int oldX = x;\n        while (x < w) {\n            paintTimeMark(x, TimeAxisUtils.formatTime(time, format), h, g);\n            time += step;\n            x = view.getTimePosition(time, true);\n            \n            // Workaround to prevent endless loop until fixed\n            if (x <= oldX) break;\n            else oldX = x;\n        }\n    }\n    \n    private void paintTimeMark(int x, String time, int h, Graphics g) {\n        painter.setText(time);\n        \n        Dimension d = painter.getPreferredSize();\n        painter.setSize(d);\n        painter.move(x - d.width / 2, (h - d.height) / 2 + Y_LAF_OFFSET);\n        painter.paint(g);\n    }\n    \n    private static LabelRenderer painter;\n    private static int Y_LAF_OFFSET;\n    private static void initStaticUI(Component c, JTableHeader header) {\n        painter = new LabelRenderer(true);\n        \n        Color color = c.getForeground();\n        if (color == null) color = header.getForeground();\n        if (color == null) color = UIManager.getColor(\"TableHeader.foreground\"); // NOI18N\n        if (color != null) painter.setForeground(color);\n        Font font = c.getFont();\n        if (font == null) font = header.getFont();\n        if (font == null) font = UIManager.getFont(\"TableHeader.font\"); // NOI18N\n        if (font != null) painter.setFont(font);\n        \n        if (UIUtils.isWindowsXPLookAndFeel()) Y_LAF_OFFSET = 1;\n        else if (UIUtils.isNimbusLookAndFeel()) Y_LAF_OFFSET = -1;\n        else Y_LAF_OFFSET = 0;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/threads/TimelineRenderer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.threads;\n\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.util.ResourceBundle;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadData;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.BaseRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class TimelineRenderer extends BaseRenderer {\n\n    private static ResourceBundle BUNDLE() {\n        return ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.threads.Bundle\"); // NOI18N\n    }\n\n    private static final Color TICK_COLOR = new Color(200, 200, 200);\n\n    private static final int BAR_MARGIN = 3;\n    private static final int BAR_MARGIN_X2 = BAR_MARGIN * 2;\n\n    private final ViewManager view;\n    private ViewManager.RowView rowView;\n\n\n    public TimelineRenderer(ViewManager view) {\n        this.view = view;\n\n        setOpaque(true);\n        setHorizontalAlignment(SwingConstants.TRAILING); // #269252\n\n        putClientProperty(ProfilerTable.PROP_NO_HOVER, this);\n    }\n\n    public void setValue(Object value, int row) {\n        rowView = (ViewManager.RowView)value; // NOTE: rowView can be set to null here!\n    }\n\n    public String toString() {\n        int lastIndex = rowView == null ? -1 : rowView.getLastIndex();\n        return getStateName(lastIndex == -1 ? -1 : rowView.getState(lastIndex));\n    }\n\n    public void paint(Graphics g) {\n        super.paint(g);\n\n        int w = size.width;\n        int h = size.height;\n\n        long time = view.getFirstTimeMark(false);\n        long step = view.getTimeMarksStep();\n\n        g.setColor(TICK_COLOR);\n\n        int x = view.getTimePosition(time, false);\n        int oldX = x;\n        while (x < w) {\n            g.drawLine(x + location.x, location.y, x + location.x, h - 1 + location.y);\n            time += step;\n            x = view.getTimePosition(time, false);\n            // Workaround to prevent endless loop until fixed\n            if (x <= oldX) break;\n            else oldX = x;\n        }\n        \n        if (rowView == null) return;\n        \n        int i = rowView.getLastIndex();\n        if (i == -1) return;\n        \n        int xx = (i == rowView.getMaxIndex() ? rowView.getMaxPosition() :\n                  rowView.getPosition(rowView.getTime(i + 1))) + location.x;\n        \n        while (i >= 0 && xx >= 0) {\n            x = Math.max(0, rowView.getPosition(rowView.getTime(i))) + location.x;\n            int ww = xx - x;\n            if (ww > 0) {\n                Color c = ThreadData.getThreadStateColor(rowView.getState(i));\n                if (c != null) {\n                    g.setColor(c);\n                    g.fillRect(x, BAR_MARGIN + location.y, ww, h - BAR_MARGIN_X2);\n                }\n                \n                xx = x;\n            }\n            i--;\n        }\n    }\n    \n    private static String getStateName(int state) {\n        switch (state) {\n//            case 0: return \"finished\";\n            case 1: return BUNDLE().getString(\"TimelineRenderer_ThreadStateRunning\");\n            case 2: return BUNDLE().getString(\"TimelineRenderer_ThreadStateSleeping\");\n            case 3: return BUNDLE().getString(\"TimelineRenderer_ThreadStateMonitor\");\n            case 4: return BUNDLE().getString(\"TimelineRenderer_ThreadStateWait\");\n            case 5: return BUNDLE().getString(\"TimelineRenderer_ThreadStatePark\");\n//            default: return \"unknown\";\n            default: return BUNDLE().getString(\"TimelineRenderer_ThreadStateFinished\");\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/src/org/graalvm/visualvm/lib/ui/threads/ViewManager.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.ui.threads;\n\nimport java.awt.event.ActionEvent;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.ResourceBundle;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.JToggleButton;\nimport org.graalvm.visualvm.lib.charts.axis.TimeAxisUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadData;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadsDataManager;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ViewManager extends ProfilerTableContainer.ColumnChangeAdapter {\n\n    private static ResourceBundle BUNDLE() {\n        return ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.threads.Bundle\"); // NOI18N\n    }\n\n    private static final int MIN_TIMEMARK_STEP = 120; // The minimal distance between two time marks\n    public static final String PROP_NEW_OFFSET = \"newOffset\"; // NOI18N\n\n    // Zoom value maximum\n    private static final int MAX_ZOOM = 5;\n    // Minimum part of view covered by data (1/MIN_VIEW)\n    private static final int MIN_VIEW = 3;\n\n    private final int column;\n\n    private final ThreadsDataManager data;\n    private final Map<Integer, RowView> rowViews;\n\n    private int offset;\n    private int width;\n    private int prefWidth;\n\n    private boolean fit = false;\n    private double zoom = 0.03f;\n    private double lastZoom = zoom;\n\n    private Action zoomInAction;\n    private Action zoomOutAction;\n    private Action fitAction;\n\n\n    public ViewManager(int column, ThreadsDataManager data) {\n        this.column = column;\n        this.data = data;\n\n        updateTimeMarks(true);\n        \n        rowViews = new HashMap<>();\n    }\n    \n    \n    public int zoomIn() {\n        return setZoom(zoom * 1.2d);\n    }\n    \n    public int zoomOut() {\n        return setZoom(zoom * 0.8d);\n    }\n    \n    public int setZoom(double zoom) {\n        int newOffset = offset;\n        if (this.zoom != zoom) {\n            double oldZoom = this.zoom;\n            zoomChanged(this.zoom, zoom);\n            if (!isFit()) {\n                double tt = (offset + width / 2) / oldZoom;\n                newOffset = Math.max((int)(tt * zoom - width / 2), 0);\n            }\n            updateActions();\n        }\n        return newOffset;\n    }\n    \n    public double getZoom() {\n        return zoom;\n    }\n    \n    public Action zoomInAction() {\n        if (zoomInAction == null) zoomInAction = new AbstractAction(null, Icons.getIcon(GeneralIcons.ZOOM_IN)) {\n            {\n                putValue(Action.SHORT_DESCRIPTION, BUNDLE().getString(\"ACT_ZoomIn\")); // NOI18N\n            }\n            public void actionPerformed(ActionEvent e) {\n                int newOffset = zoomIn();\n                Integer _newOffset = newOffset == offset ? null : newOffset;\n                zoomInAction.putValue(PROP_NEW_OFFSET, _newOffset);\n            }\n        };\n        return zoomInAction;\n    }\n    \n    public Action zoomOutAction() {\n        if (zoomOutAction == null) zoomOutAction = new AbstractAction(null, Icons.getIcon(GeneralIcons.ZOOM_OUT)) {\n            {\n                putValue(Action.SHORT_DESCRIPTION, BUNDLE().getString(\"ACT_ZoomOut\")); // NOI18N\n            }\n            public void actionPerformed(ActionEvent e) {\n                int newOffset = zoomOut();\n                Integer _newOffset = newOffset == offset ? null : newOffset;\n                zoomOutAction.putValue(PROP_NEW_OFFSET, _newOffset);\n            }\n        };\n        return zoomOutAction;\n    }\n    \n    public Action fitAction() {\n        if (fitAction == null) fitAction = new AbstractAction(null, Icons.getIcon(GeneralIcons.SCALE_TO_FIT)) {\n            {\n                putValue(Action.SHORT_DESCRIPTION, BUNDLE().getString(\"ACT_ScaleToFit\")); // NOI18N\n            }\n            public void actionPerformed(ActionEvent e) {\n                Object source = e.getSource();\n                if (source instanceof JToggleButton) {\n                    fit = ((JToggleButton)source).isSelected();\n                    if (fit) lastZoom = zoom;\n                    else zoom = lastZoom;\n                    updateTimeMarks(true);\n                    updateActions();\n                }\n            }\n        };\n        return fitAction;\n    }\n    \n    private void updateActions() {\n        if (zoomInAction != null) {\n            zoomInAction.setEnabled(!isFit() && getViewWidth() > 0 && zoom <= MAX_ZOOM);\n        }\n        if (zoomOutAction != null) {\n            zoomOutAction.setEnabled(!isFit() && prefWidth >= width / MIN_VIEW);\n        }\n    }\n    \n    \n    private long getFirstTime() {\n        return data.getStartTime();\n    }\n    \n    public int getViewWidth() {\n        return (int)(getDataWidth() * zoom);\n    }\n    \n    private int getDataWidth() {\n        return (int)(data.getEndTime() - data.getStartTime());\n    }\n    \n    \n    public long getFirstTimeMark(boolean _offset) {\n        return _offset ? _firstTimeMark : firstTimeMark;\n    }\n    \n    public long getTimeMarksStep() {\n        return timeMarksStep;\n    }\n    \n    public String getTimeMarksFormat() {\n        return format;\n    }\n    \n    public int getTimePosition(long time, boolean _offset) {\n        return !_offset || isFit() ? (int)((time - data.getStartTime()) * zoom) :\n                                     (int)((time - data.getStartTime()) * zoom) - offset;\n    }\n    \n    private long firstTimeMark;\n    private long _firstTimeMark;\n    private long timeMarksStep;\n    private String format;\n    private void updateTimeMarks(boolean updateStep) {\n        if (updateStep) timeMarksStep = TimeAxisUtils.getTimeUnits(zoom, MIN_TIMEMARK_STEP);\n        \n        long first = data.getStartTime();\n        long _first = first + (long)(offset / zoom);\n        firstTimeMark = first / timeMarksStep * timeMarksStep + timeMarksStep;\n        _firstTimeMark = _first / timeMarksStep * timeMarksStep + timeMarksStep;\n        \n        long last = first + (long)(width / zoom);\n        format = TimeAxisUtils.getFormatString(timeMarksStep, first, last);\n    }\n    \n    \n    public RowView getRowView(int row) {\n        RowView rowView = rowViews.get(row);\n        if (rowView == null) {\n            rowView = new RowView(data.getThreadData(row));\n            rowViews.put(row, rowView);\n        }\n        return rowView;\n    }\n    \n    \n    public void update() {\n        if (isFit()) zoomChanged(zoom, width / (double)getDataWidth());\n    }\n    \n    public void reset() {\n        zoom = 0.03f;\n        lastZoom = zoom;\n        rowViews.clear();\n        updateTimeMarks(true);\n    }\n    \n    public void columnOffsetChanged(int column, int oldO, int newO) {\n        if (this.column != column) return;\n        offset = newO;\n        updateTimeMarks(false);\n        for (RowView view : rowViews.values()) view.offsetChanged(oldO, newO);\n    }\n    \n    public void columnWidthChanged(int column, int oldW, int newW) {\n        if (this.column != column) return;\n        width = newW;\n        if (!isFit()) for (RowView view : rowViews.values()) view.widthChanged(oldW, newW);\n        updateActions();\n    }\n    \n    public void columnPreferredWidthChanged(int column, int oldW, int newW) {\n        if (this.column != column) return;\n        prefWidth = newW;\n        updateTimeMarks(false);\n        if (!isFit()) for (RowView view : rowViews.values()) view.preferredWidthChanged(oldW, newW);\n        updateActions();\n    }\n    \n    public void zoomChanged(double oldZoom, double newZoom) {\n        zoom = newZoom;\n        updateTimeMarks(true);\n        for (RowView view : rowViews.values()) view.zoomChanged(oldZoom, newZoom);\n    }\n    \n    \n    public void setFit(boolean f) {\n        fit = f;\n    }\n    \n    public boolean isFit() {\n        return fit;\n    }\n    \n    private boolean isTrackingEnd() {\n        return offset + width >= prefWidth;\n    }\n    \n    \n    public class RowView implements Comparable<RowView> {\n        \n        private final ThreadData data;\n        \n        private int i = -1;\n        \n        \n        RowView(ThreadData data) {\n            this.data = data;\n            if (getMaxIndex() >= 0) i = findLastIndex();\n        }\n        \n        \n        public int getLastIndex() {\n            return i == Integer.MIN_VALUE || i == Integer.MAX_VALUE ? -1 : i;\n        }\n        \n        public int getMaxIndex() {\n            return data.size() - 1;\n        }\n        \n        public long getTime(int index) {\n            return data.getTimeStampAt(index);\n        }\n        \n        public int getState(int index) {\n            return data.getStateAt(index);\n        }\n        \n        public int getPosition(long time) {\n            return (int)((time - getFirstTime()) * zoom);\n        }\n        \n        // TODO: should return end of last alive state for dead threads\n        public int getMaxPosition() {\n            return getViewWidth();\n        }\n        \n        \n        // TODO: optimize based on current offset / visible area\n        private int findLastIndex() {\n//            if (data.getThreadRecordsCount(row) == 0) return -1;\n            \n            if (isTrackingEnd() || isFit()) return getMaxIndex();\n            \n            i = Integer.MIN_VALUE;\n            return findLastIndexLeft();\n        }\n        \n        private int findLastIndexLeft() {\n            // All indexes already on right\n            if (i == Integer.MAX_VALUE) return i;\n            \n            int maxIndex = getMaxIndex();\n            int newIndex = i == Integer.MIN_VALUE ? maxIndex : i;\n            Position position = getIndexPosition(newIndex);\n            while (newIndex > 0 && Position.RIGHT.equals(position))\n                position = getIndexPosition(--newIndex);\n            \n            // All indexes on right\n            if (Position.RIGHT.equals(position)) return Integer.MAX_VALUE;\n            \n            // All indexes on left\n            if (Position.LEFT.equals(position) && newIndex == maxIndex &&\n                getMaxPosition() - offset < 0) return Integer.MIN_VALUE;\n            \n            // Last visible index\n            return newIndex;\n        }\n        \n        private int findLastIndexRight() {\n            // All indexes already on right\n            if (i == Integer.MIN_VALUE) return i;\n            \n            int maxIndex = getMaxIndex();\n            int newIndex = i == Integer.MAX_VALUE ? 0 : i;\n            Position position = getIndexPosition(newIndex);\n            while (newIndex < maxIndex && !Position.RIGHT.equals(position))\n                position = getIndexPosition(++newIndex);\n            \n            // First invisible index or all indexes on right\n            if (Position.RIGHT.equals(position))\n                return newIndex == 0 ? Integer.MAX_VALUE : newIndex - 1;\n            \n            // All indexes on left\n            if (Position.LEFT.equals(position) && newIndex == maxIndex &&\n                getMaxPosition() - offset < 0) return Integer.MIN_VALUE;\n            \n            // Last visible index\n            return newIndex;\n        }\n        \n        private Position getIndexPosition(int index) {\n            int position = getPosition(getTime(index)) - offset;\n            if (position < 0) return Position.LEFT;\n            else if (position >= width) return Position.RIGHT;\n            else return Position.WITHIN;\n        }\n        \n        \n        private void offsetChanged(int oldOffset, int newOffset) {\n            int maxIndex = getMaxIndex();\n            if (maxIndex == -1) return;\n            \n            if (isTrackingEnd()) {\n                i = maxIndex;\n            } else {\n                if (newOffset > oldOffset) {\n                    i = i == -1 ? findLastIndex() : findLastIndexRight();\n                } else {\n                    i = i == -1 ? findLastIndex() : findLastIndexLeft();\n                }\n            }\n        }\n        \n        private void widthChanged(int oldWidth, int newWidth) {\n            int maxIndex = getMaxIndex();\n            if (maxIndex == -1) return;\n            \n            if (isTrackingEnd() || isFit()) {\n                i = maxIndex;\n            } else {\n                if (newWidth > oldWidth) {\n                    i = i == -1 ? findLastIndex() : findLastIndexRight();\n                } else {\n                    i = i == -1 ? findLastIndex() : findLastIndexLeft();\n                }\n            }\n        }\n        \n        private boolean lastMaxIn = true;\n        private void preferredWidthChanged(int oldWidth, int newWidth) {\n            int maxIndex = getMaxIndex();\n            if (maxIndex == -1) return;\n            \n            int currPos = getMaxPosition() - offset;\n            if (currPos >= 0 && currPos < width) { // TODO: verify\n                i = maxIndex;\n                lastMaxIn = true;\n            } else {\n                if (lastMaxIn && currPos >= width) {\n                    // preferred width increases with new data\n                    i = maxIndex;\n                    findLastIndexLeft();\n                }\n                lastMaxIn = false;\n            }\n        }\n        \n        private void zoomChanged(double oldZoom, double newZoom) {\n            int maxIndex = getMaxIndex();\n            if (maxIndex == -1) return;\n            \n            if (isTrackingEnd() || isFit()) {\n                i = maxIndex;\n            } else {\n                i = findLastIndex();\n            }\n        }\n\n        public int compareTo(RowView view) {\n            return Long.compare(data.getFirstTimeStamp(), view.data.getFirstTimeStamp());\n        }\n        \n        public String toString() {\n            return BUNDLE().getString(\"COL_Timeline\"); // NOI18N\n        }\n        \n    }\n    \n    private static enum Position { LEFT, WITHIN, RIGHT }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/lib.profiler.ui/test/unit/src/org/graalvm/visualvm/lib/ui/SwingWorkerTest.java",
    "content": "/*\n * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.ui;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.Semaphore;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport static org.junit.Assert.*;\n\n/**\n *\n * @author Jaroslav Bachorik <jaroslav.bachorik@oracle.com>\n */\npublic class SwingWorkerTest {\n\n    public SwingWorkerTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() {\n    }\n\n    @AfterClass\n    public static void tearDownClass() {\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    /**\n     * Test of execute method, of class SwingWorker.\n     */\n    @Test\n    public void testExecute() throws Exception {\n        System.out.println(\"execute\");\n        final boolean[] executed = new boolean[]{false};\n        final CountDownLatch latch = new CountDownLatch(1);\n        SwingWorker instance = new SwingWorkerImpl(0, true, null, new Runnable() {\n            @Override\n            public void run() {\n                executed[0] = true;\n            }\n        }, new Runnable() {\n\n            @Override\n            public void run() {\n                latch.countDown();\n            }\n        }, null, null);\n        instance.execute();\n        latch.await(1, TimeUnit.SECONDS);\n        assertTrue(executed[0]);\n    }\n\n    /**\n     * Test of cancel method, of class SwingWorker.\n     */\n    @Test\n    public void testCancel() throws Exception {\n        System.out.println(\"cancel\");\n        final boolean[] canceled = new boolean[]{false};\n        final boolean[] done = new boolean[]{false};\n        final CountDownLatch latch = new CountDownLatch(1);\n        SwingWorker instance = new SwingWorkerImpl(6000, true, null, new Runnable() {\n            @Override\n            public void run() {\n                try {\n                    Thread.sleep(2000);\n                } catch (InterruptedException e) {\n                }\n            }\n        }, new Runnable() {\n\n            @Override\n            public void run() {\n                done[0] = true;\n            }\n        }, new Runnable() {\n\n            @Override\n            public void run() {\n                canceled[0] = true;\n                latch.countDown();\n            }\n        }, null);\n        instance.execute();\n        try {\n            Thread.sleep(500);\n        } catch (InterruptedException e) {\n        }\n        instance.cancel();\n        latch.await(5, TimeUnit.SECONDS);\n        assertTrue(canceled[0]);\n        assertFalse(done[0]);\n    }\n\n    /**\n     * Test of nonResponding method, of class SwingWorker.\n     */\n    @Test\n    public void testNonResponding() throws Exception {\n        System.out.println(\"nonResponding\");\n        final boolean[] waiting = new boolean[]{false};\n        final CountDownLatch latch = new CountDownLatch(1);\n        SwingWorker instance = new SwingWorkerImpl(500, true, null, new Runnable() {\n            @Override\n            public void run() {\n                try {\n                    Thread.sleep(2000);\n                } catch (InterruptedException e) {\n                }\n            }\n        }, new Runnable() {\n\n            @Override\n            public void run() {\n                latch.countDown();\n            }\n        }, null, \n        new Runnable() {\n\n            @Override\n            public void run() {\n                waiting[0] = true;\n            }\n        });\n        instance.execute();\n        latch.await(4, TimeUnit.SECONDS);\n        \n        assertTrue(waiting[0]);\n    }\n    \n    @Test\n    public void testSharedSemaphore() throws Exception  {\n        System.out.println(\"sharedSemaphore\");\n        Semaphore s = new Semaphore(1);\n        final AtomicInteger counter = new AtomicInteger(0);\n        final CountDownLatch latch = new CountDownLatch(2);\n        \n        final SwingWorker sw1 = new SwingWorkerImpl(0, true, s, new Runnable() {\n\n            @Override\n            public void run() {\n                counter.incrementAndGet();\n                try {\n                    Thread.sleep(312);\n                } catch (InterruptedException e) {\n                }\n                counter.decrementAndGet();\n            }\n        }, new Runnable() {\n\n            @Override\n            public void run() {\n                latch.countDown();\n            }\n        }, null, null);\n        SwingWorker sw2 = new SwingWorkerImpl(0, true, s, new Runnable() {\n\n            @Override\n            public void run() {\n                counter.incrementAndGet();\n                sw1.execute();                \n                try {\n                    Thread.sleep(500);\n                } catch (InterruptedException e) {\n                }\n                counter.decrementAndGet();\n            }\n        }, new Runnable() {\n\n            @Override\n            public void run() {\n                latch.countDown();\n            }\n        }, null, null);\n        \n        sw2.execute();\n        \n        latch.await(3, TimeUnit.SECONDS);\n        \n        assertEquals(0, counter.get());\n    }\n\n    public class SwingWorkerImpl extends SwingWorker {\n        final private Runnable task, onDone, onCancel, waiting;\n        \n        final private int warmup;\n\n        public SwingWorkerImpl(int warmup, boolean forceEQ, Semaphore throughputSemaphore, Runnable task, Runnable onDone, Runnable onCancel, Runnable waiting) {\n            super(forceEQ, throughputSemaphore);\n            this.warmup = warmup;\n            this.task = task;\n            this.onDone = onDone;\n            this.onCancel = onCancel;\n            this.waiting = waiting;\n        }\n        \n        public void doInBackground() {\n            if (task != null) {\n                task.run();\n            }\n        }\n\n        @Override\n        protected int getWarmup() {\n            return warmup;\n        }\n\n        @Override\n        protected void done() {\n            if (onDone != null) {\n                onDone.run();\n            }\n        }\n\n        @Override\n        protected void cancelled() {\n            if (onCancel != null) {\n                onCancel.run();\n            }\n        }\n\n        @Override\n        protected void nonResponding() {\n            if (waiting != null) {\n                waiting.run();\n            }\n        }\n        \n        \n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project basedir=\".\" default=\"netbeans\" name=\"profiler\">\n    <description>Builds, tests, and runs the project org.yourorghere.main</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n    <property name=\"test.run.args\" value=\"-Dnetbeans.keyring.no.master=true -Dnetbeans.full.hack=true  -client -Xss4m -Xms64m -Xmx512m -XX:PermSize=64m -XX:MaxPermSize=300m -Dsun.java2d.noddraw=true\"/>\n\n  <target name=\"netbeans-extra-ml\" depends=\"release-ml\" if=\"locales\"/>\n\n  <target name=\"check-run-mlbuild\" depends=\"basic-init\">\n    <property name=\"translated.src.dir\" value=\"${nb_all}/translatedfiles/src/${module.name}/src\"/>\n    <condition property=\"locjar.locales\" value=\"${locales}\">\n      <and>\n        <isset property=\"locales\" />\n        <not>\n          <isset property=\"locjar.locales\"/>\n        </not>\n      </and>\n    </condition>\n    <available file=\"${nb_all}/translatedfiles/src/${module.name}\" type=\"dir\" property=\"translated.src.dir.exist\"/>\n    <condition property=\"run.ml.build\" value=\"true\">\n      <and>\n        <isset property=\"translated.src.dir.exist\"/>\n        <isset property=\"locjar.locales\"/>\n        <length string=\"${locjar.locales}\" when=\"greater\" length=\"0\"/>\n      </and>\n    </condition>\n  </target>\n\n  <target name=\"release-ml\" depends=\"basic-init,check-run-mlbuild\" if=\"run.ml.build\">\n      <taskdef name=\"repeat\" classname=\"org.netbeans.nbbuild.Repeat\"\n               classpath=\"${nbantext.jar}\"/>\n      <repeat target=\"release-one-locale\" name=\"locale\" values=\"${locales}\"/>\n  </target>\n\n  <target name=\"release-one-locale\" if=\"locale\">\n      <copy todir=\"${cluster}\">\n          <fileset dir=\"${nb_all}/translatedfiles/src/${module.name}/release\">\n              <include name=\"**/oqlqueries-default_${locale}.xml\"/>\n          </fileset>\n      </copy>\n  </target>\n\n\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/l10n.list",
    "content": "# profiler/modules/main \nread global\n${l10n-module}/src/org/graalvm/visualvm/lib/profiler/heapwalk/oqlqueries-default.xml\n\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.lib.profiler/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/lib/profiler/mf-layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/lib/profiler/Bundle.properties\nOpenIDE-Module-Install: org/graalvm/visualvm/lib/profiler/ProfilerModule.class\nOpenIDE-Module-Requires: org.openide.windows.WindowManager\nOpenIDE-Module-Package-Dependencies: com.sun.tools.attach[VirtualMachine]\nOpenIDE-Module-Specification-Version: 2.4\n\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.lib.profiler-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/nbproject/genfiles.properties",
    "content": "# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=05d8af55\nnbproject/build-impl.xml.script.CRC32=a56246ef\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/nbproject/project.properties",
    "content": "# Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nis.autoload=true\n\ncp.extra=${tools.jar}\n\njavac.source=1.8\ntest-qa-functional-sys-prop.BrokenReferencesSupport.suppressBrokenRefAlert=true\ntest.config.uicommit.includes=\\\n    org/netbeans/test/profiler/ProfilerValidationTest.class\ntest.config.stableBTD.includes=**/*Test.class\ntest.config.stableBTD.excludes=org/netbeans/test/**/*\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.lib.profiler</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.charts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.common</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.14</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.attach</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.utilities</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.45</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.23</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.actions</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.6</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.11</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems.nb</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.loaders</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.61</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.nodes</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.2</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.16</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <test-dependencies>\n                <test-type>\n                    <name>qa-functional</name>\n                    <test-dependency>\n                        <code-name-base>org.graalvm.visualvm.lib.common</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.libs.junit4</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.modules.jellytools.ide</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.modules.jellytools.java</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.modules.jellytools.platform</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.modules.jemmy</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.modules.nbjunit</code-name-base>\n                        <recursive/>\n                        <compile-dependency/>\n                    </test-dependency>\n                </test-type>\n                <test-type>\n                    <name>unit</name>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.libs.junit4</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.modules.nbjunit</code-name-base>\n                        <recursive/>\n                        <compile-dependency/>\n                    </test-dependency>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.modules.sampler</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                </test-type>\n            </test-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.core</friend>\n                <friend>org.graalvm.visualvm.heapdump</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.heapwalker</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.snaptracer</friend>\n                <friend>org.graalvm.visualvm.profiler</friend>\n                <friend>org.graalvm.visualvm.profiling</friend>\n                <friend>org.graalvm.visualvm.sampler</friend>\n                <friend>org.graalvm.visualvm.sampler.truffle</friend>\n                <package>org.graalvm.visualvm.lib.profiler</package>\n                <package>org.graalvm.visualvm.lib.profiler.actions</package>\n                <package>org.graalvm.visualvm.lib.profiler.ui</package>\n                <package>org.graalvm.visualvm.lib.profiler.utils</package>\n                <package>org.graalvm.visualvm.lib.profiler.v2</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/../..\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n## Resource bundle for package org.graalvm.visualvm.lib.profiler\n#Mon May 03 18:59:38 CEST 2004\nOpenIDE-Module-Display-Category=Java SE\nOpenIDE-Module-Name=Java Profiler Core\nOpenIDE-Module-Long-Description=NetBeans Profiler is a full-featured Java profiler adding CPU, Memory and Thread profiling functionality to the NetBeans IDE.\n\nNpsResolver=Nps Files\nHprofResolver=Dummy Hprof Files\n\nSnapshotDataLoader_DisplayName=Profiler Snapshot Loader\n\n#ResultsWindow_UpdateResultsAutomaticallyTooltip=Update Results Automatically\n#ResultsWindow_CloseTabMenuItem=Close\n#ResultsWindow_NoResultsToExportMessage=No results available to save.\n#ResultsWindow_ErrorOpeningFileMessage=Error opening file {0}\\:\\n{1}\n#ResultsWindow_ErrorWritingToFileMessage=Error writing to file {0}\\:\\n{1}\n#ResultsWindow_NoProfilingResultsLabelText=No profiling results available yet\n#ResultsWindow_NoResultsTabName=No Results\n#ResultsWindow_ResultsTimestampTooltip=Obtained {0}\n#ResultsWindow_ObjectAllocationsTabName=Object Allocations\n#ResultsWindow_LiveObjectsTabName=Live Objects\n#ResultsWindow_CPUCallTreeTabName=CPU Call Tree\n#ResultsWindow_CodeRegionTabName=Code Region\n#ResultsWindow_NoNewResultsMessage=No new results to display\\n{0}\n#ResultsWindow_MemoryProfilingInactiveMessage=Memory profiling inactive. Cannot display call graphs now.\n#ResultsWindow_NoLiveObjectsExistMessage=No live objects for this class exist - nothing to display\n\nHistoryPanel_ToolTipClass=Class\nHistoryPanel_ToolTipObjects=Objects\nHistoryPanel_ToolTipSize=Size\nHistoryPanel_ToolTipCursor=Cursor:\nHistoryPanel_ToolTipTime=Time\nHistoryPanel_ToolTipLive=Live\nHistoryPanel_ToolTipAllocated=Allocated\n\nMarkerMethodBuilder_ProjectRootCategory=Project\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/DummyHprofResolver.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n\n<!DOCTYPE MIME-resolver PUBLIC \"-//NetBeans//DTD MIME Resolver 1.0//EN\" \"http://www.netbeans.org/dtds/mime-resolver-1_0.dtd\">\n<MIME-resolver>\n    <file>\n        <ext name=\"hprof\"/>\n        <resolver mime=\"application/x-netbeans-profiler-hprof\"/>\n    </file>\n    <file>\n        <magic hex=\"4a4156412050524f46494c4520312e30\"\n              mask=\"ffffffffffffffffffffffffffffffff\"/>\n        <resolver mime=\"application/x-netbeans-profiler-hprof\"/>\n    </file>\n</MIME-resolver>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/HeapDumpWatch.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\nimport org.openide.filesystems.FileChangeAdapter;\nimport org.openide.filesystems.FileEvent;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.NbBundle;\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerStorage;\nimport org.graalvm.visualvm.lib.profiler.spi.SessionListener;\nimport org.graalvm.visualvm.lib.profiler.v2.SnapshotsWindow;\nimport org.openide.util.Lookup;\nimport org.openide.util.Lookup.Provider;\nimport org.openide.util.lookup.ServiceProvider;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\n@NbBundle.Messages({\n    \"HeapDumpWatch_OOME_PROTECTION_OPEN_HEAPDUMP=Profiled application crashed and generated heap dump.\\nDo you wish to open it in heapwalker?\",\n    \"HeapDumpWatch_OOME_PROTECTION_REMOVE_HEAPDUMP=You chose not to open the generated heap dump.\\nThe heap dump can take a significant amount of disk space.\\nShould it be deleted?\"\n})\n@ServiceProvider(service=SessionListener.class)\npublic class HeapDumpWatch extends SessionListener.Adapter {\n    private static final Logger LOG = Logger.getLogger(HeapDumpWatch.class.getName());\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private  class HeapDumpFolderListener extends FileChangeAdapter {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void fileDataCreated(FileEvent fileEvent) {\n            captureHeapDump(fileEvent.getFile());\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private FileObject monitoredPath;\n    private HeapDumpFolderListener listener;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of HeapDumpWatch */\n    public HeapDumpWatch() {\n        listener = new HeapDumpFolderListener();\n    }\n\n    public static String getHeapDumpPath(Lookup.Provider project) {\n        ProfilerIDESettings gps = ProfilerIDESettings.getInstance();\n        if (!gps.isOOMDetectionEnabled()) return null;\n        \n        int oomeDetectionMode = gps.getOOMDetectionMode();\n\n        switch (oomeDetectionMode) {\n            case ProfilerIDESettings.OOME_DETECTION_TEMPDIR:\n                return System.getProperty(\"java.io.tmpdir\"); // NOI18N\n            case ProfilerIDESettings.OOME_DETECTION_PROJECTDIR:\n\n                try {\n                    return FileUtil.toFile(ProfilerStorage.getProjectFolder(project, true)).getAbsolutePath();\n                } catch (IOException e) {\n                    LOG.log(Level.WARNING, \"Cannot resolve project settings directory:\\n\" + e.getMessage(), e);\n                    \n                    return null;\n                }\n            case ProfilerIDESettings.OOME_DETECTION_CUSTOMDIR:\n                return gps.getCustomHeapdumpPath();\n        }\n\n        return null;\n    }\n    \n    @Override\n    public void onShutdown() {\n        release();\n    }\n\n    @Override\n    public void onStartup(ProfilingSettings ps, Provider p) {\n        if (ProfilerIDESettings.getInstance().isOOMDetectionEnabled()) {\n            String oomePath = getHeapDumpPath(p);\n            if (oomePath != null) {\n                monitor(oomePath);\n            }\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    private void monitor(String path) throws IllegalArgumentException {\n        if ((path == null) || path.isEmpty()) {\n            throw new IllegalArgumentException(\"The path \\\"\" + path + \"\\\" can't be null.\"); // NOI18N\n        }\n\n        FileObject fo = FileUtil.toFileObject(FileUtil.normalizeFile(new File(path)));\n\n        if (fo != null) {\n            if (!fo.isFolder()) {\n                throw new IllegalArgumentException(\"The given path \\\"\" + path + \"\\\" is invalid. It must be a folder\"); // NOI18N\n            }\n\n            fo.getChildren();\n            fo.addFileChangeListener(listener);\n            monitoredPath = fo;\n        }\n    }\n    \n    private void captureHeapDump(FileObject heapDump) {\n        if (!heapDump.getExt().equals(ResultsManager.HEAPDUMP_EXTENSION)) {\n            return; // NOI18N\n        }\n\n        if (heapDump.getName().startsWith(ResultsManager.HEAPDUMP_PREFIX)) {\n            return; // custom heapdump\n        }\n\n        SnapshotsWindow.instance().refreshFolder(heapDump.getParent(), true);\n//        if (ProfilerControlPanel2.hasDefault())\n//            ProfilerControlPanel2.getDefault().refreshSnapshotsList(); // refresh list of snapshots\n\n        try {\n            if (ProfilerDialogs.displayConfirmation(Bundle.HeapDumpWatch_OOME_PROTECTION_OPEN_HEAPDUMP())) {\n                ResultsManager.getDefault().openSnapshot(heapDump);\n            } else if (ProfilerDialogs.displayConfirmation(Bundle.HeapDumpWatch_OOME_PROTECTION_REMOVE_HEAPDUMP())) {\n                heapDump.delete();\n                SnapshotsWindow.instance().refreshFolder(heapDump.getParent(), true);\n//                if (ProfilerControlPanel2.hasDefault())\n//                    ProfilerControlPanel2.getDefault().refreshSnapshotsList();\n            }\n        } catch (FileNotFoundException ex) {\n            ex.printStackTrace();\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        } finally {\n            release();\n        }\n    }\n\n    private void release() {\n        if (monitoredPath != null) {\n            monitoredPath.removeFileChangeListener(listener);\n            monitoredPath = null;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/LoadedSnapshot.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.results.ResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.coderegion.CodeRegionResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot.NoDataAvailableException;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.AllocMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.LivenessMemoryResultsSnapshot;\nimport org.openide.util.NbBundle;\nimport java.io.*;\nimport java.lang.management.ThreadInfo;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.zip.Deflater;\nimport java.util.zip.GZIPInputStream;\nimport java.util.zip.InflaterInputStream;\nimport javax.management.openmbean.CompositeData;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.common.ProfilingSettingsPresets;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.StackTraceSnapshotBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProjectUtilities;\nimport org.openide.util.Lookup;\n\n@NbBundle.Messages({\n    \"LoadedSnapshot_IllegalSnapshotDataMsg=Illegal snapshot data\",\n    \"LoadedSnapshot_InvalidSnapshotFileMsg=Not a valid NetBeans Profiler snapshot file\",\n    \"LoadedSnapshot_UnsupportedSnapshotVersionMsg=Unsupported file version\",\n    \"LoadedSnapshot_WrongSnapshotTypeMsg=Incorrect snapshot type\",\n    \"LoadedSnapshot_CannotReadSnapshotDataMsg=Cannot read snapshot data\",\n    \"LoadedSnapshot_CannotReadSettingsDataMsg=Cannot read settings data\",\n    \"LoadedSnapshot_UnrecognizedSnapshotTypeMsg=Unrecognized snapshot type\",\n    \"LoadedSnapshot_SnapshotDataCorruptedMsg=Snapshot data corrupted\",\n    \"LoadedSnapshot_SnapshotFileShortMsg=File too short\",\n    \"LoadedSnapshot_SnapshotFileCorrupted=Snapshot file corrupted\",\n    \"LoadedSnapshot_SnapshotFileCorruptedReason=Snapshot file is corrupted: {0}\",\n    \"LoadedSnapshot_OutOfMemoryLoadingMsg=Not enough memory to load snapshot.\\n\\nTo avoid this error please increase the -Xmx value\\nin the etc/visualvm.conf file in VisualVM directory.\"\n})\npublic class LoadedSnapshot {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Logger LOGGER = Logger.getLogger(LoadedSnapshot.class.getName());\n\n    //  private static final boolean DEBUG = true; //System.getProperty(\"org.graalvm.visualvm.lib.profiler.LoadedSnapshot\") != null; // TODO [m7] : change to property\n    public static final int SNAPSHOT_TYPE_UNKNOWN = 0;\n    public static final int SNAPSHOT_TYPE_CPU = 1;\n    public static final int SNAPSHOT_TYPE_CODEFRAGMENT = 2;\n    public static final int SNAPSHOT_TYPE_MEMORY_ALLOCATIONS = 4;\n    public static final int SNAPSHOT_TYPE_MEMORY_LIVENESS = 8;\n    public static final int SNAPSHOT_TYPE_MEMORY_SAMPLED = 16;\n    public static final int SNAPSHOT_TYPE_CPU_JDBC = 32;\n    public static final int SNAPSHOT_TYPE_MEMORY = SNAPSHOT_TYPE_MEMORY_ALLOCATIONS | SNAPSHOT_TYPE_MEMORY_LIVENESS | SNAPSHOT_TYPE_MEMORY_SAMPLED;\n    public static final String PROFILER_FILE_MAGIC_STRING = \"nBpRoFiLeR\"; // NOI18N\n    private static final byte SNAPSHOT_FILE_VERSION_MAJOR = 1;\n    private static final byte SNAPSHOT_FILE_VERSION_MINOR = 2;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private File file;\n    private ProfilingSettings settings;\n    private Lookup.Provider project = null;\n    private ResultsSnapshot snapshot;\n    private String userComments = \"\"; // NOI18N\n    private boolean saved = false;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates a new LoadedSnapshot.\n     *\n     * @param snapshot The actual snapshot results data\n     * @param settings ProfilingSettings used to obtain this snapshot\n     * @param file     The FileObject in which this snapshot is saved or null if it is not yet saved (in-memory only)\n     */\n    public LoadedSnapshot(ResultsSnapshot snapshot, ProfilingSettings settings, File file, Lookup.Provider project) {\n        if (snapshot == null) {\n            throw new IllegalArgumentException();\n        }\n\n        if (settings == null) {\n            throw new IllegalArgumentException();\n        }\n\n        this.snapshot = snapshot;\n        this.settings = settings;\n        this.file = file;\n        this.project = project;\n    }\n\n    private LoadedSnapshot() {\n        // for persistence only\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setFile(File file) {\n        this.file = file;\n        saved = true;\n        SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    if (SnapshotResultsWindow.hasSnapshotWindow(LoadedSnapshot.this))\n                        SnapshotResultsWindow.get(LoadedSnapshot.this).refreshTabName();\n                }\n            });\n    }\n\n    /**\n     * @return The File in which this snapshot is saved or null if it is not yet saved (in-memory only)\n     */\n    public File getFile() {\n        return file;\n    }\n\n    public Lookup.Provider getProject() {\n        return project;\n    }\n\n    public void setSaved(boolean saved) {\n        this.saved = saved;\n    }\n\n    public boolean isSaved() {\n        return saved;\n    }\n    \n    public void setUserComments(String userComments) {\n        if (!this.userComments.equals(userComments)) {\n            this.userComments = userComments;\n            setSaved(false);\n        }\n    }\n    \n    public String getUserComments() {\n        return userComments;\n    }\n\n    /**\n     * @return ProfilingSettings used to obtain this snapshot\n     */\n    public ProfilingSettings getSettings() {\n        return settings;\n    }\n\n    /**\n     * @return The actual snapshot results data\n     */\n    public ResultsSnapshot getSnapshot() {\n        return snapshot;\n    }\n\n    public int getType() {\n        if (snapshot instanceof CPUResultsSnapshot) {\n            return SNAPSHOT_TYPE_CPU;\n        } else if (snapshot instanceof CodeRegionResultsSnapshot) {\n            return SNAPSHOT_TYPE_CODEFRAGMENT;\n        } else if (snapshot instanceof LivenessMemoryResultsSnapshot) {\n            return SNAPSHOT_TYPE_MEMORY_LIVENESS;\n        } else if (snapshot instanceof AllocMemoryResultsSnapshot) {\n            return SNAPSHOT_TYPE_MEMORY_ALLOCATIONS;\n        } else if (snapshot instanceof SampledMemoryResultsSnapshot) {\n            return SNAPSHOT_TYPE_MEMORY_SAMPLED;\n        } else if (snapshot instanceof JdbcResultsSnapshot) {\n            return SNAPSHOT_TYPE_CPU_JDBC;\n        } else {\n            throw new IllegalStateException(Bundle.LoadedSnapshot_IllegalSnapshotDataMsg());\n        }\n    }\n\n    /**\n     * Will load a snapshot into memory from the provided stream and return the snapshot representation.\n     *\n     * @param dis Stream to read from, typically data from file.\n     * @return The loaded snapshot or null if failed to load (has already been reported to the user)\n     * @throws IOException If unexpected error occurred while loading (should be reported to the user)\n     */\n    public static LoadedSnapshot loadSnapshot(DataInputStream dis)\n                                       throws IOException {\n        dis.mark(100);\n        try {\n            LoadedSnapshot ls = new LoadedSnapshot();\n\n            if (ls.load(dis)) {\n                return ls;\n            } else {\n                return null;\n            }\n        } catch (IOException ex) {\n            if (Bundle.LoadedSnapshot_InvalidSnapshotFileMsg().equals(ex.getMessage())) {\n                dis.reset();\n                return loadSnapshotFromStackTraces(dis);\n            }\n            throw ex;\n        }\n    }\n\n    private static LoadedSnapshot loadSnapshotFromStackTraces(DataInputStream dis) throws IOException {\n        SamplesInputStream is = new SamplesInputStream(dis);\n        StackTraceSnapshotBuilder builder = new StackTraceSnapshotBuilder();\n        ThreadsSample sample = is.readSample();\n        // start time in milliseconds\n        long startTime = sample.getTime() / 1000000;\n\n        for ( ;sample != null; sample = is.readSample()) {\n            builder.addStacktrace(sample.getTinfos(),sample.getTime());\n            \n        }\n        is.close();\n        is = null;\n        CPUResultsSnapshot snapshot;\n        try {\n            snapshot = builder.createSnapshot(startTime);\n        } catch (NoDataAvailableException ex) {\n            throw new IOException(ex);\n        }\n        return new LoadedSnapshot(snapshot, ProfilingSettingsPresets.createCPUPreset(), null, null);\n    }\n\n    public void setProject(Lookup.Provider project) {\n        this.project = project;\n    }\n\n    public void save(DataOutputStream dos) throws IOException, OutOfMemoryError {\n        // todo [performance] profile memory use during the save operation\n        // there is ~80MB bytes used for byte[], for the length of uncompressed data ~20MB\n        Properties props = new Properties();\n        settings.store(props);\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"save properties: --------------------------------------------------------------\"); // NOI18N\n            LOGGER.finest(settings.debug());\n            LOGGER.finest(\"-------------------------------------------------------------------------------\"); // NOI18N\n        }\n\n        ByteArrayOutputStream baos = new ByteArrayOutputStream(1000000); // ~1MB pre-allocated\n        DataOutputStream snapshotDataStream = new DataOutputStream(baos);\n\n        ByteArrayOutputStream baos2 = new ByteArrayOutputStream(10000); // ~10kB pre-allocated\n        DataOutputStream settingsDataStream = new DataOutputStream(baos2);\n\n        try {\n            snapshot.writeToStream(snapshotDataStream);\n            snapshotDataStream.flush();\n            props.store(settingsDataStream, \"\"); //NOI18N\n            settingsDataStream.flush();\n\n            byte[] snapshotBytes = baos.toByteArray();\n            byte[] compressedBytes = new byte[snapshotBytes.length];\n\n            Deflater d = new Deflater();\n            d.setInput(snapshotBytes);\n            d.finish();\n\n            int compressedLen = d.deflate(compressedBytes);\n            int uncompressedLen = snapshotBytes.length;\n\n            // binary file format:\n            // 1. magic number: \"nbprofiler\"\n            // 2. int type\n            // 3. int length of snapshot data size\n            // 4. snapshot data bytes\n            // 5. int length of settings data size\n            // 6. settings data bytes (.properties plain text file format)\n            // 7. String (UTF) custom comments\n            if (LOGGER.isLoggable(Level.FINEST)) {\n                LOGGER.finest(\"save version:\" + SNAPSHOT_FILE_VERSION_MAJOR //NOI18N\n                              + \".\" + SNAPSHOT_FILE_VERSION_MINOR); // NOI18N\n                LOGGER.finest(\"save type:\" + getType()); // NOI18N\n                LOGGER.finest(\"length of uncompressed snapshot data:\" + uncompressedLen); // NOI18N\n                LOGGER.finest(\"save length of snapshot data:\" + compressedLen); // NOI18N\n                LOGGER.finest(\"length of settings data:\" + baos2.size()); // NOI18N\n            }\n\n            dos.writeBytes(PROFILER_FILE_MAGIC_STRING); // 1. magic number: \"nbprofiler\"\n            dos.writeByte(SNAPSHOT_FILE_VERSION_MAJOR); // 2. file version\n            dos.writeByte(SNAPSHOT_FILE_VERSION_MINOR); // 3. file version\n            dos.writeInt(getType()); // 4. int type\n            dos.writeInt(compressedLen); // 5. int length of compressed snapshot data size\n            dos.writeInt(uncompressedLen); // 5. int length of uncompressed snapshot data size\n            dos.write(compressedBytes, 0, compressedLen); // 6. compressed snapshot data bytes\n            dos.writeInt(baos2.size()); // 7. int length of settings data size\n            dos.write(baos2.toByteArray()); // 8. settings data bytes (.properties plain text file format)\n            dos.writeUTF(userComments);\n        } catch (OutOfMemoryError e) {\n            baos = null;\n            snapshotDataStream = null;\n            baos2 = null;\n            settingsDataStream = null;\n\n            throw e;\n        } finally {\n            if (snapshotDataStream != null) {\n                snapshotDataStream.close();\n            }\n\n            if (settingsDataStream != null) {\n                settingsDataStream.close();\n            }\n        }\n    }\n\n    public String toString() {\n        String snapshotString = \"snapshot = \" + snapshot.toString(); // NOI18N\n        String fileString = \"file = \" + ((file == null) ? \"null\" : file.toString()); // NOI18N\n        String projectString = \"project = \"\n                               + ((project == null) ? \"null\" : ProjectUtilities.getDisplayName(project)); // NOI18N\n\n        return \"Loaded Results Snapshot, \" + snapshotString + \", \" + projectString + \", \" + fileString; // NOI18N\n    }\n\n    private static String getCorruptedMessage(IOException e) {\n        String message = e.getMessage();\n\n        if (message == null) {\n            if (e instanceof EOFException) {\n                return Bundle.LoadedSnapshot_SnapshotFileCorruptedReason(Bundle.LoadedSnapshot_SnapshotFileShortMsg());\n            } else {\n                return Bundle.LoadedSnapshot_SnapshotFileCorrupted();\n            }\n        } else {\n            return Bundle.LoadedSnapshot_SnapshotFileCorruptedReason(message);\n        }\n    }\n\n    private boolean load(DataInputStream dis) throws IOException {\n        try {\n            Properties props = new Properties();\n            settings = new ProfilingSettings();\n\n            // binary file format:\n            // 1. magic number: \"nbprofiler\"\n            // 2. byte major, minor version\n            // 3. int type\n            // 4. int length of snapshot data size\n            // 5. snapshot data bytes\n            // 6. int length of settings data size\n            // 7. settings data bytes (.properties plain text file format)\n            // 8. String (UTF) custom comments\n\n            // 1. magic number: \"nbprofiler\"\n            byte[] magicArray = new byte[PROFILER_FILE_MAGIC_STRING.length()];\n            int len = dis.read(magicArray);\n\n            if ((len != PROFILER_FILE_MAGIC_STRING.length()) || !PROFILER_FILE_MAGIC_STRING.equals(new String(magicArray))) {\n                throw new IOException(Bundle.LoadedSnapshot_InvalidSnapshotFileMsg());\n            }\n\n            // 2. byte major, minor version\n            byte majorVersion = dis.readByte();\n            byte minorVersion = dis.readByte();\n\n            if (majorVersion > SNAPSHOT_FILE_VERSION_MAJOR) {\n                throw new IOException(Bundle.LoadedSnapshot_SnapshotFileCorruptedReason(Bundle.LoadedSnapshot_UnsupportedSnapshotVersionMsg()));\n            }\n\n            // 3. int type\n            int type = dis.readInt();\n\n            if (type == -1) {\n                throw new IOException(Bundle.LoadedSnapshot_SnapshotFileCorruptedReason(Bundle.LoadedSnapshot_WrongSnapshotTypeMsg()));\n            }\n\n            // 4. int length of snapshot data size\n            int compressedDataLen = dis.readInt();\n            int uncompressedDataLen = dis.readInt();\n\n            // 5. snapshot data bytes\n            InputStream subStream = new SubInputStream(dis,compressedDataLen);\n            InputStream zipStream = new InflaterInputStream(subStream);\n            \n            switch (type) {\n                case SNAPSHOT_TYPE_CPU:\n                    snapshot = new CPUResultsSnapshot();\n\n                    break;\n                case SNAPSHOT_TYPE_CODEFRAGMENT:\n                    snapshot = new CodeRegionResultsSnapshot();\n\n                    break;\n                case SNAPSHOT_TYPE_MEMORY_ALLOCATIONS:\n                    snapshot = new AllocMemoryResultsSnapshot();\n\n                    break;\n                case SNAPSHOT_TYPE_MEMORY_LIVENESS:\n                    snapshot = new LivenessMemoryResultsSnapshot();\n\n                    break;\n                case SNAPSHOT_TYPE_MEMORY_SAMPLED:\n                    snapshot = new SampledMemoryResultsSnapshot();\n                    \n                    break;\n                case SNAPSHOT_TYPE_CPU_JDBC:\n                    snapshot = new JdbcResultsSnapshot();\n                    \n                    break;\n                default:\n                    throw new IOException(Bundle.LoadedSnapshot_SnapshotFileCorruptedReason(Bundle.LoadedSnapshot_UnrecognizedSnapshotTypeMsg())); // not supported\n            }\n\n            BufferedInputStream bufBais = new BufferedInputStream(zipStream);\n            DataInputStream dataDis = new DataInputStream(bufBais);\n\n            try {\n                snapshot.readFromStream(dataDis);\n                ensureZipStreamEOF(dataDis, subStream);\n            } catch (IOException e) {\n                throw new IOException(getCorruptedMessage(e));\n            }\n\n            // 6. int length of settings data size\n            int settingsLen = dis.readInt();\n            byte[] settingsBytes = new byte[settingsLen];\n\n            // 7. settings data bytes (.properties plain text file format)\n            int readLen2 = dis.read(settingsBytes);\n\n            if (settingsLen != readLen2) {\n                throw new IOException(Bundle.LoadedSnapshot_SnapshotFileCorruptedReason(Bundle.LoadedSnapshot_CannotReadSettingsDataMsg()));\n            }\n            \n            // 8. String (UTF) custom comments\n            if (minorVersion >= SNAPSHOT_FILE_VERSION_MINOR) {\n                userComments = dis.readUTF();\n            }\n\n            // Process read data:\n            if (LOGGER.isLoggable(Level.FINEST)) {\n                LOGGER.finest(\"load version:\" + majorVersion + \".\" + minorVersion); // NOI18N\n                LOGGER.finest(\"load type:\" + type); // NOI18N\n                LOGGER.finest(\"load length of snapshot data:\" + compressedDataLen); // NOI18N\n                LOGGER.finest(\"uncompressed length of snapshot data:\" + uncompressedDataLen); // NOI18N\n                LOGGER.finest(\"load length of settings data:\" + settingsLen); // NOI18N\n            }\n\n            ByteArrayInputStream bais2 = new ByteArrayInputStream(settingsBytes);\n            try (DataInputStream settingsDis = new DataInputStream(bais2)) {\n                props.load(settingsDis);\n            } catch (IOException e) {\n                throw new IOException(getCorruptedMessage(e));\n            }\n\n            settings.load(props);\n\n            if (LOGGER.isLoggable(Level.FINEST)) {\n                LOGGER.finest(\"load properties: --------------------------------------------------------------\"); // NOI18N\n                LOGGER.finest(settings.debug());\n                LOGGER.finest(\"-------------------------------------------------------------------------------\"); // NOI18N\n            }\n        } catch (OutOfMemoryError e) {\n            ProfilerDialogs.displayError(Bundle.LoadedSnapshot_OutOfMemoryLoadingMsg());\n\n            return false;\n        }\n        ProfilerEngineSettings pes = new ProfilerEngineSettings();\n        settings.applySettings(pes);\n        snapshot.setProfilerSettings(pes);\n\n        return true;\n    }\n\n    // make sure both streams are at the end (both should return EOF aka -1)\n    private void ensureZipStreamEOF(InputStream dataDis, InputStream sub) throws IOException {\n        if (dataDis.read() != -1) {\n            throw new IOException(\"Compressed stream longer than expected\");     // NOI18N\n        }\n        if (sub.read() != -1) {\n            throw new IOException(\"Compressed stream ended too early\");     // NOI18N\n        }\n    }\n\n    private static class SubInputStream extends FilterInputStream {\n        private int limit;\n        \n        private SubInputStream(InputStream is, int l) {\n            super(is);\n            limit = l;\n        }\n\n        @Override\n        public int available() throws IOException {\n            int avail = super.available();\n            return Math.min(avail, limit);\n        }\n\n        @Override\n        public int read() throws IOException {\n            if (limit == 0) {\n                return -1;\n            }\n            limit--;\n            return super.read();\n        }\n\n        @Override\n        public int read(byte[] b, int off, int len) throws IOException {\n            if (limit == 0) {\n                return -1;\n            }\n            int realLen = Math.min(len, limit);\n            int readBytes = super.read(b, off, realLen);\n            limit -= readBytes;\n            return readBytes;\n        }\n\n        @Override\n        public long skip(long n) throws IOException {\n            long skip = Math.min(n, limit);\n            long skipped = super.skip(skip);\n            limit -= skipped;\n            return skipped;\n        }\n\n        @Override\n        public boolean markSupported() {\n            return false;\n        }\n    }\n    \n    static class SamplesInputStream {\n        static final String ID = \"NPSS\"; // NetBeans Profiler samples stream, it must match org.netbeans.modules.sampler.SamplesOutputStream.ID\n        static final int MAX_SUPPORTED_VERSION = 2;\n\n        int version;\n        int samples;\n        long lastTimestamp;\n        ObjectInputStream in;\n        Map<Long,ThreadInfo> threads;\n        \n        SamplesInputStream(File file) throws IOException {\n            this(new FileInputStream(file));\n        }\n\n        SamplesInputStream(InputStream is) throws IOException {\n            readHeader(is);\n            in = new ObjectInputStream(new GZIPInputStream(is));\n            if (version > 1) {\n                samples = in.readInt();\n                lastTimestamp = in.readLong();\n            }\n            threads = new HashMap(128);\n        }\n\n        int getSamples() {\n            return samples;\n        }\n\n        long getLastTimestamp() {\n            return lastTimestamp;\n        }\n        \n        ThreadsSample readSample() throws IOException {\n            long time;\n            ThreadInfo infos[];\n            int sameThreads;\n            Map<Long,ThreadInfo> newThreads;\n            \n            try {\n                time = in.readLong();\n            } catch (EOFException ex) {\n                return null;\n            }\n            newThreads = new HashMap(threads.size());\n            sameThreads = in.readInt();\n            for (int i=0;i<sameThreads;i++) {\n                Long tid = Long.valueOf(in.readLong());\n                ThreadInfo oldThread = threads.get(tid);\n                assert oldThread != null;\n                newThreads.put(tid,oldThread);\n            }\n            infos = new ThreadInfo[in.readInt()];\n            for (ThreadInfo info : infos) {\n                CompositeData infoData;\n                ThreadInfo thread;\n                \n                try {\n                    infoData = (CompositeData) in.readObject();\n                } catch (ClassNotFoundException ex) {\n                    throw new RuntimeException(ex);\n                }\n                thread = ThreadInfo.from(infoData);\n                newThreads.put(Long.valueOf(thread.getThreadId()),thread);\n            }\n            threads = newThreads;\n            return new ThreadsSample(time,threads.values());\n        }\n\n        void close() throws IOException {\n            in.close();\n        }\n\n        @NbBundle.Messages({\n            \"MSG_NotNPSSSnapshot=Not a NPSS snapshot.\",\n            \"MSG_UnsupportedSnapshotVersion=Unsupported snapshot version.\"\n        })\n        private void readHeader(InputStream is) throws IOException {\n            String id;\n            byte[] idarr = new byte[ID.length()];\n\n            is.read(idarr);\n            id = new String(idarr);\n            if (!ID.equals(id)) {\n                throw new IOException(\"Invalid header \"+id) { // NOI18N\n                    public String getLocalizedMessage() {\n                        return Bundle.MSG_NotNPSSSnapshot();\n                    }\n                };\n            }\n            version = is.read();\n            if (version > MAX_SUPPORTED_VERSION) {\n                throw new IOException(\"NPSS file version \"+version+\" is not supported\") { // NOI18N\n                    public String getLocalizedMessage() {\n                        return Bundle.MSG_UnsupportedSnapshotVersion();\n                    }\n                };\n            }\n        }\n    }\n\n    static final class ThreadsSample {\n        private final long time;\n        private final ThreadInfo[] tinfos;\n\n        ThreadsSample(long t, Collection<ThreadInfo> tis) {\n            time = t;\n            tinfos = tis.toArray(new ThreadInfo[0]);\n        }\n\n        long getTime() {\n            return time;\n        }\n\n        ThreadInfo[] getTinfos() {\n            return tinfos;\n        }\n    }\n}\n/* Code to do persist into a ZIP file\n   public void save (ZipOutputStream zos) throws IOException {\n     Properties props = new Properties ();\n     settings.store(props);\n     Properties versionProps = new Properties ();\n     versionProps.put(\"major\", \"\"+SNAPSHOT_FILE_VERSION_MAJOR);\n     versionProps.put(\"minor\", \"\"+SNAPSHOT_FILE_VERSION_MINOR);\n     ByteArrayOutputStream baos = new ByteArrayOutputStream(1000000); // ~1MB pre-allocated\n     BufferedOutputStream bufBaos = new BufferedOutputStream(baos);\n     DataOutputStream snapshotDataStream = new DataOutputStream(bufBaos);\n     try {\n       snapshot.writeToStream(snapshotDataStream);\n       snapshotDataStream.flush();\n       // binary file format is ZIP file with the following content:\n       // 1. version properties stored in file <type>.properties\n       // 2. snapshot data in file \"data\"\n       // 3. settings properties in file \"settings.properties\"\n       if (DEBUG) {\n         System.err.println(\"LoadedSnapshot.DEBUG: save version:\" + SNAPSHOT_FILE_VERSION_MAJOR + \".\" + SNAPSHOT_FILE_VERSION_MINOR);\n         System.err.println(\"LoadedSnapshot.DEBUG: save type:\" + getType());\n         System.err.println(\"LoadedSnapshot.DEBUG: save length of snapshot data:\" + baos.size());\n       }\n       // 1. store version data, in the form of properties file named by type of results\n       switch (getType ()) {\n         case SNAPSHOT_TYPE_CPU: zos.putNextEntry(new ZipEntry(\"cpu.properties\")); break;\n         case SNAPSHOT_TYPE_CODEFRAGMENT: zos.putNextEntry(new ZipEntry(\"fragment.properties\")); break;\n         case SNAPSHOT_TYPE_MEMORY_ALLOCATIONS: zos.putNextEntry(new ZipEntry(\"allocations.properties\")); break;\n         case SNAPSHOT_TYPE_MEMORY_LIVENESS: zos.putNextEntry(new ZipEntry(\"liveness.properties\")); break;\n         default: throw new IllegalStateException();\n       }\n       versionProps.store(zos, \"\");\n       zos.flush();\n       zos.closeEntry();\n       // 2. store data into file \"data\"\n       zos.putNextEntry(new ZipEntry(\"data\"));\n       writeBytes (zos, baos.toByteArray());\n       zos.flush();\n       zos.closeEntry();\n       // 3. store properties as \"settings.properties\"\n       zos.putNextEntry(new ZipEntry(\"settings.properties\"));\n       props.store(zos, \"\");\n       zos.flush();\n       zos.closeEntry();\n     } finally {\n       snapshotDataStream.close ();\n     }\n   }\n   public void load (ZipInputStream zis) throws IOException {\n     Properties settingsProps = null;\n     Properties versionProps = null;\n     int type = SNAPSHOT_TYPE_UNKNOWN;\n     byte[] dataBytes = null;\n     ZipEntry ze = zis.getNextEntry();\n     while (ze != null) {\n       if (ze.isDirectory()) continue;\n       String name = ze.getName();\n       if (name.equals (\"data\")) {\n         dataBytes = readBytes (zis);\n       } else if (name.equals (\"settings.properties\")) {\n         settingsProps = new Properties ();\n         settingsProps.load(zis);\n       } else if (type == SNAPSHOT_TYPE_UNKNOWN && name.endsWith(\".properties\")) {\n         if (name.equals (\"cpu.properties\")) type = SNAPSHOT_TYPE_CPU;\n         else if (name.equals (\"fragment.properties\")) type = SNAPSHOT_TYPE_CODEFRAGMENT;\n         else if (name.equals (\"allocations.properties\")) type = SNAPSHOT_TYPE_MEMORY_ALLOCATIONS;\n         else if (name.equals (\"liveness.properties\")) type = SNAPSHOT_TYPE_MEMORY_LIVENESS;\n         if (type != SNAPSHOT_TYPE_UNKNOWN) {\n           versionProps = new Properties ();\n           versionProps.load(zis);\n         }\n       }\n       ze = zis.getNextEntry();\n     }\n     if (dataBytes == null) throw new IOException (\"The file is not a valid NetBeans Profiler Snapshot file: missing results data\");\n     if (settingsProps == null) throw new IOException (\"The file is not a valid NetBeans Profiler Snapshot file: missing settings data\");\n     if (versionProps == null) throw new IOException (\"The file is not a valid NetBeans Profiler Snapshot file: missing type and version data\");\n     // binary file format is ZIP file with the following content:\n     // 1. version properties stored in file <type>.properties\n     // 2. snapshot data in file \"data\"\n     // 3. settings properties in file \"settings.properties\"\n     // 2. int type\n   /*    byte majorVersion = zis.readByte();\n       byte minorVersion = zis.readByte();\n       if (majorVersion > SNAPSHOT_FILE_VERSION_MAJOR) throw new IOException(\"Snapshot file is corrupted: unsupported file version\");\n * /\n   /*    // 5. snapshot data bytes\n       int readLen1 = zis.read(dataBytes);\n       if (lenData1 != readLen1) throw new IOException(\"Snapshot file is corrupted: cannot read snapshot data\");\n       // 6. int length of settings data size\n       int lenData2 = zis.readInt();\n       byte[] settingsBytes = new byte [lenData2];\n       // 7. settings data bytes (.properties plain text file format)\n       int readLen2 = zis.read(settingsBytes);\n       if (lenData2 != readLen2) throw new IOException(\"Snapshot file is corrupted: cannot read settings data\");\n * /\n       // Process read data:\n   /*\n       if (DEBUG) {\n         System.err.println(\"LoadedSnapshot.DEBUG: load version:\" + majorVersion + \".\"+minorVersion);\n         System.err.println(\"LoadedSnapshot.DEBUG: load type:\" + type);\n         System.err.println(\"LoadedSnapshot.DEBUG: load length of snapshot data:\" + lenData1);\n         System.err.println(\"LoadedSnapshot.DEBUG: load length of settings data:\" + lenData2);\n       }\n * /\n       switch (type) {\n         case SNAPSHOT_TYPE_CPU: snapshot = new CPUResultsSnapshot (); break;\n         case SNAPSHOT_TYPE_CODEFRAGMENT: snapshot = new CodeRegionResultsSnapshot (); break;\n         case SNAPSHOT_TYPE_MEMORY_ALLOCATIONS: snapshot = new AllocMemoryResultsSnapshot(); break;\n         case SNAPSHOT_TYPE_MEMORY_LIVENESS: snapshot = new LivenessMemoryResultsSnapshot(); break;\n         default: throw new IOException (\"Snapshot file is corrupted: unrecognized snapshot type\"); // not supported\n       }\n       ByteArrayInputStream bais = new ByteArrayInputStream(dataBytes);\n       BufferedInputStream bufBais = new BufferedInputStream(bais);\n       DataInputStream dataDis = new DataInputStream(bufBais);\n       try {\n         snapshot.readFromStream(dataDis);\n       } catch (IOException e) {\n         ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);\n         throw new IOException (getCorruptedMessage(e));\n       } finally {\n         dataDis.close ();\n       }\n       settings = new ProfilingSettings();\n       settings.load(settingsProps);\n     }\n     private byte[] readBytes(ZipInputStream zis) throws IOException {\n       int ch1 = zis.read();\n       int ch2 = zis.read();\n       int ch3 = zis.read();\n       int ch4 = zis.read();\n       if ((ch1 | ch2 | ch3 | ch4) < 0) throw new EOFException();\n       int length = ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));\n       System.err.println(\"Loading length:\"+length);\n       if (length < 0) throw new IOException(\"Wrong data size: \"+length);\n       // TODO: if length is too large by error, we should not crash by allocating too much memory, but what is too much?\n       byte[] bytes = new byte[length];\n       zis.read(bytes, 0, length);\n       for (int i = 0; i < 10; i++) {\n         System.err.println(\"byte[\"+i+\"]=\"+bytes[i]);\n       }\n       for (int i = bytes.length-10; i < bytes.length; i++) {\n         System.err.println(\"byte[\"+i+\"]=\"+bytes[i]);\n       }\n       return bytes;\n     }\n     private void writeBytes(ZipOutputStream zos, byte[] bytes) throws IOException {\n       int v = bytes.length;\n       System.err.println(\"Storing length:\"+v);\n       for (int i = 0; i < 10; i++) {\n         System.err.println(\"byte[\"+i+\"]=\"+bytes[i]);\n       }\n       for (int i = bytes.length-10; i < bytes.length; i++) {\n         System.err.println(\"byte[\"+i+\"]=\"+bytes[i]);\n       }\n       zos.write((v >>> 24) & 0xFF);\n       zos.write((v >>> 16) & 0xFF);\n       zos.write((v >>>  8) & 0xFF);\n       zos.write((v >>>  0) & 0xFF);\n       zos.write(bytes);\n     }\n     private static String getCorruptedMessage (IOException e) {\n       String message = e.getMessage();\n       if (message == null) {\n         if (e instanceof EOFException) return \"Snapshot file is corrupted: file too short\";\n         else return \"Snapshot file is corrupted\";\n       }\n       else return \"Snapshot file is corrupted: \" + message;\n     }\n     public static LoadedSnapshot loadSnapshot (ZipInputStream zis) throws IOException {\n       LoadedSnapshot ls = new LoadedSnapshot ();\n       ls.load (zis);\n       return ls;\n     }\n */\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/NetBeansProfiler.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\nimport com.sun.tools.attach.AgentInitializationException;\nimport com.sun.tools.attach.AgentLoadException;\nimport com.sun.tools.attach.AttachNotSupportedException;\nimport com.sun.tools.attach.VirtualMachine;\nimport java.awt.BorderLayout;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.Frame;\nimport java.awt.Window;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.io.BufferedInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectOutputStream;\nimport java.net.Socket;\nimport java.net.SocketTimeoutException;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.Properties;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.JButton;\nimport javax.swing.JDialog;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JProgressBar;\nimport javax.swing.SwingUtilities;\nimport javax.swing.border.EmptyBorder;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.ProfilingEventListener;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassRepository;\nimport org.graalvm.visualvm.lib.jfluid.client.AppStatusHandler;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.client.ProfilingPointsProcessor;\nimport org.graalvm.visualvm.lib.common.*;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CalibrationDataFileIO;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.BadLocationException;\nimport org.graalvm.visualvm.lib.jfluid.instrumentation.InstrumentationException;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.ProfilingResultsDispatcher;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUProfilingResultListener;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.CCTResultsFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.TimeCollector;\nimport org.graalvm.visualvm.lib.jfluid.results.locks.LockProfilingResultListener;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryProfilingResultsListener;\nimport org.graalvm.visualvm.lib.jfluid.results.monitor.VMTelemetryDataManager;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadsDataManager;\nimport org.graalvm.visualvm.lib.ui.SwingWorker;\nimport org.graalvm.visualvm.lib.ui.monitor.VMTelemetryModels;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.Command;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.Response;\nimport org.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO;\nimport org.graalvm.visualvm.lib.profiler.api.JavaPlatform;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.api.ProgressDisplayer;\nimport org.graalvm.visualvm.lib.profiler.spi.SessionListener;\nimport org.graalvm.visualvm.lib.profiler.ui.ProfilerProgressDisplayer;\nimport org.graalvm.visualvm.lib.profiler.utilities.ProfilerUtils;\nimport org.openide.awt.Mnemonics;\nimport org.openide.awt.StatusDisplayer;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.windows.WindowManager;\n\n\n/**\n * The main class representing profiler integrated in the IDE\n * <p>\n * List of properties that can be used to influence the profiler behavior:\n * \\\"org.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO\\\" - set to true to enable wire i/o debugging on profiler side\n * \\\"org.graalvm.visualvm.lib.jfluid.wireprotocol.WireIO.agent\\\" - set to true to enable wire i/o debugging on profiled app side\n *\n * @author Tomas Hurka\n * @author Ian Formanek\n * @author Misha Dmitriev\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"NetBeansProfiler_ProgressDialogCaption=Progress...\",\n    \"NetBeansProfiler_EntireApplicationProfilingWarning=In the Entire Application profiling mode,\\nprofiling data collection will not start\\nuntil your application starts a new Thread,\\nand will be done only for new Threads.\\n\\nConsider switching to \\\"Part of Application\\\" mode\\nif you want to profile already running threads.\",\n    \"NetBeansProfiler_DirectoryDoesNotExistMessage=The directory does not exist.\",\n    \"NetBeansProfiler_DirectoryIsWriteProtectedMessage=The directory is write-protected.\\nPlease make it writeable.\",\n    \"NetBeansProfiler_ErrorLoadingProfilingSettingsMessage=Error encountered while loading profiling settings: {0}\",\n    \"NetBeansProfiler_ErrorSavingProfilingSettingsMessage=Error encountered while saving global filters: {0}\",\n    \"NetBeansProfiler_ErrorSavingFilterSetsMessage=Error encountered while saving defined filter sets: {0}\",\n    \"NetBeansProfiler_ErrorSavingGlobalSettingsMessage=Error encountered while saving global settings: {0}\",\n    \"NetBeansProfiler_ErrorSavingAttachSettingsMessage=Error encountered while saving attach settings: {0}\",\n    \"NetBeansProfiler_CannotFindLibsMsg=Cannot find profiler libs directory\",\n    \"NetBeansProfiler_EngineInitFailedMsg=Failed to initialize the Profiler engine: {0}\",\n    \"NetBeansProfiler_InitialCalibrationMsg=Profiler will now perform an initial calibration of your machine and target JVM.\\n\\nThis calibration needs to be performed the first time you run the profiler to\\nensure that timing results are accurate when profiling your application. To\\nensure the calibration data is accurate, please make sure that other\\napplications are not placing a noticeable load on your machine at this time.\\n\\nYou can run the calibration again using\\n\\\"Tools | Options | Profiling | Manage calibration data\\\"\\n\\nWarning: If your computer uses dynamic CPU frequency switching, please\\ndisable it and do not use it when profiling.\",\n    \"NetBeansProfiler_MustCalibrateFirstMsg=Profiling will STOP now because the calibration data is missing or is corrupt.\\n\\nIf this is the first time you are using the profiler or target JVM on this machine,\\nyou first need to run the calibration for your target JVM.\\nThe obtained calibration data will be saved and re-used\\non subsequent runs, so you will not see this message again.\\n\\nTo perform calibration, use\\n\\\"Tools | Options | Profiling | Manage calibration data\\\".\\n\\n\",\n    \"NetBeansProfiler_MustCalibrateFirstShortMsg=<html><b>Calibration data missing.</b><br><br>Profiling cannot be started on this JDK. Please perform<br>profiler calibration first and start the profiling session again.</html>\",\n    \"NetBeansProfiler_TerminateVMOnExitMsg=<b>The profiled application has finished execution.</b>\\n Press OK to terminate the VM.\",\n    \"NetBeansProfiler_TakeSnapshotOnExitMsg=<b>The profiled application has finished execution.</b>\\nDo you want to take a snapshot of the collected results?\",\n    \"NetBeansProfiler_TakeSnapshotOnExitDialogTitle=Application Finished\",\n    \"NetBeansProfiler_TargetAppNotRespondingMsg=The profiled application does not respond.\\n Do you want to close the connection and stop profiling?\",\n    \"NetBeansProfiler_TargetAppNotRespondingDialogTitle=Question\",\n    \"NetBeansProfiler_ModifyingInstrumentationMsg=Modifying instrumentation...\",\n    \"NetBeansProfiler_StartingSession=Starting profiling session...\",\n    \"NetBeansProfiler_CancelBtn=&Cancel\",\n    \"NetBeansProfiler_AgentFailed=Make sure the process is not already being profiled.\",\n    \"NetBeansProfiler_MemorySamplingJava5=<html><b>Memory sampling is not supported for Java 5.</b><br><br>Please run the profiled application using Java 6+ or use memory instrumentation.</html>\"\n})\npublic abstract class NetBeansProfiler extends Profiler {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n    \n    public static final class ProgressPanel implements AppStatusHandler.AsyncDialog {\n        \n        private static final int MINIMUM_WIDTH = 350;\n        \n        private volatile boolean opened;\n        private volatile boolean closed;\n        private JDialog dialog;\n        \n        private final String message;\n        private final boolean showProgress;\n        private final Runnable cancelHandler;\n        \n        \n        private ProgressPanel(String message, boolean showProgress, Runnable cancelHandler) {\n            this.message = message;\n            this.showProgress = showProgress;\n            this.cancelHandler = cancelHandler;\n        }\n\n        @Override\n        public void close() {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    if (!opened) closed = true;\n                    else closeImpl();\n                }\n            });\n        }\n\n        @Override\n        public void display() {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    initUI();\n//                    RequestProcessor.getDefault().post(new Runnable() {\n//                        public void run() {\n                            if (!closed) dialog.setVisible(true);\n//                        }\n//                    });\n                }\n            });\n        }\n        \n        private void initUI() {\n            Frame mainWindow = WindowManager.getDefault().getMainWindow();\n            dialog = new JDialog(mainWindow, Bundle.NetBeansProfiler_ProgressDialogCaption(), true);\n            \n            JPanel panel = new JPanel(new BorderLayout(5, 5));\n            panel.setBorder(new EmptyBorder(15, 15, 15, 10));\n            panel.add(new JLabel(message), BorderLayout.NORTH);\n\n            if (showProgress) {\n                JProgressBar progress = new JProgressBar();\n                progress.setIndeterminate(true);\n                panel.add(progress, BorderLayout.SOUTH);\n            }\n            \n            if (cancelHandler != null) {\n                JButton cancelButton = new JButton() {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        close();\n                        cancelHandler.run();\n                    }\n                };\n                Mnemonics.setLocalizedText(cancelButton, Bundle.NetBeansProfiler_CancelBtn());\n                JPanel buttonPanel = new JPanel(new BorderLayout(0, 0));\n                buttonPanel.setBorder(new EmptyBorder(5, 15, 10, 10));\n                buttonPanel.add(cancelButton, BorderLayout.EAST);\n                \n                dialog.add(panel, BorderLayout.NORTH);\n                dialog.add(buttonPanel, BorderLayout.SOUTH);\n            } else {\n                dialog.add(panel, BorderLayout.NORTH);\n            }\n            \n            Dimension ps = panel.getPreferredSize();\n            panel.setPreferredSize(new Dimension(Math.max(ps.width, MINIMUM_WIDTH), ps.height));\n            dialog.pack();\n            dialog.setLocationRelativeTo(mainWindow);\n            \n            dialog.addHierarchyListener(new HierarchyListener() {\n                public void hierarchyChanged(HierarchyEvent e) {\n                    if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && dialog.isShowing()) {\n                        dialog.removeHierarchyListener(this);\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                opened = true;\n                                if (closed) closeImpl();\n                            }\n                        });\n                    }\n                }\n            });\n            dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);\n        }\n        \n        private void closeImpl() {\n            dialog.setVisible(false);\n            dialog.dispose();\n        }\n        \n    }\n    \n    // -- NetBeansProfiler-only callback classes ---------------------------------------------------------------------------\n    private final class IDEAppStatusHandler implements AppStatusHandler {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n        public AppStatusHandler.AsyncDialog getAsyncDialogInstance(String message, boolean showProgress, Runnable cancelHandler) {\n            return new ProgressPanel(message, showProgress, cancelHandler);\n        }\n\n        public boolean confirmWaitForConnectionReply() {\n            // FIXXX: should display a NotifyDescriptor.WARNING_MESSAGE confirmation!\n            return (!ProfilerDialogs.displayConfirmation(\n                    Bundle.NetBeansProfiler_TargetAppNotRespondingMsg(),\n                    Bundle.NetBeansProfiler_TargetAppNotRespondingDialogTitle()));\n        }\n\n        // The following methods should display messages asynchronously, i.e. they shouldn't block the current\n        // thread waiting for the user pressing OK.\n        public void displayError(final String msg) {\n            LOGGER.log(Level.WARNING, \"IDEAppStatusHandler - error: {0}\", msg); //NOI18N\n            ProfilerDialogs.displayError(msg);\n        }\n\n        // These method SHOULD wait for the user to press ok, since they may be used in a sequence of displayed\n        // panels, and the next one shouldn't be displayed before the previous one is read and understood.\n        public void displayErrorAndWaitForConfirm(final String msg) {\n            LOGGER.log(Level.WARNING, \"IDEAppStatusHandler - errorAndWaitForConfirm: {0}\", msg); //NOI18N\n            ProfilerDialogs.displayError(msg);\n        }\n\n        public void displayErrorWithDetailsAndWaitForConfirm(String shortMsg, String detailsMsg) {\n            ProfilerDialogs.displayError(shortMsg, null, detailsMsg);\n        }\n\n        public void displayNotification(final String msg) {\n            StatusDisplayer.getDefault().setStatusText(msg);\n        }\n\n        public void displayNotificationAndWaitForConfirm(final String msg) {\n            ProfilerDialogs.displayInfo(msg);\n        }\n\n        public void displayNotificationWithDetailsAndWaitForConfirm(String shortMsg, String detailsMsg) {\n            ProfilerDialogs.displayInfo(shortMsg, null, detailsMsg);\n        }\n\n        public void displayWarning(final String msg) {\n            LOGGER.log(Level.WARNING, \"IDEAppStatusHandler - warning: {0}\" ,msg); //NOI18N\n            ProfilerDialogs.displayWarning(msg);\n        }\n\n        public void displayWarningAndWaitForConfirm(final String msg) {\n            LOGGER.log(Level.WARNING, \"IDEAppStatusHandler - warningAndWaitForConfirm: {0}\", msg); //NOI18N\n            ProfilerDialogs.displayWarning(msg);\n        }\n\n        public void handleShutdown() {\n            //      IDEUtils.runInEventDispatchThreadAndWait( // According to Issue 74914 this cannot run in AWT-EventQueue\n            //          new Runnable() {\n            //            public void run() {\n\n            // Asynchronously update live results if autorefresh is on\n//            if (LiveResultsWindow.hasDefault()) {\n//                LiveResultsWindow.getDefault().handleShutdown();\n//            }\n\n            if ((getTargetAppRunner().getProfilerClient().getCurrentInstrType() == CommonConstants.INSTR_NONE)\n                    || !ResultsManager.getDefault().resultsAvailable()) {\n                ProfilerDialogs.displayInfoDNSA(Bundle.NetBeansProfiler_TerminateVMOnExitMsg(), null, null, \"NetBeansProfiler.handleShutdown.noResults\", false); //NOI18N\n            } else if (ProfilerDialogs.displayConfirmationDNSA(Bundle.NetBeansProfiler_TakeSnapshotOnExitMsg(), Bundle.NetBeansProfiler_TakeSnapshotOnExitDialogTitle(), null, \"NetBeansProfiler.handleShutdown\", false)) { //NOI18N\n                ResultsManager.getDefault().takeSnapshot();\n            }\n\n            //            }\n            //          }\n            //      );\n        }\n\n        public void pauseLiveUpdates() {\n//            LiveResultsWindow.setPaused(true);\n        }\n\n        public void resultsAvailable() {\n            ProfilingSettings ps = getLastProfilingSettings();\n            if (ps != null && ps.getProfilingType() == ProfilingSettings.PROFILE_CPU_SAMPLING) {\n                return;\n            }\n            ResultsManager.getDefault().resultsBecameAvailable();\n        }\n\n        public void resumeLiveUpdates() {\n//            LiveResultsWindow.setPaused(false);\n        }\n\n        public void takeSnapshot() {\n            ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                    public void run() {\n                        ResultsManager.getDefault().takeSnapshot();\n                    }\n                });\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Logger LOGGER = Logger.getLogger(NetBeansProfiler.class.getName());\n\n//    private static final String GLOBAL_FILTERS_FILENAME = \"filters\"; //NOI18N\n//    private static final String DEFINED_FILTERSETS_FILENAME = \"filtersets\"; //NOI18N\n//    private static final String DEFAULT_FILE_SUFFIX = \"-default\"; //NOI18N\n    private static boolean initialized = false;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    //--- Modifying instrumentation progress -------------------------------------\n    boolean shouldDisplayDialog = true;\n\n    // TODO [release] set to obtain from property\n    //  static boolean DEBUG = true; // System.getProperty(\"org.graalvm.visualvm.lib.profiler.NetBeansProfiler\") != null;\n    private final ProfilerIDESettings ideSettings = ProfilerIDESettings.getInstance();\n    \n    private ProfilingMonitor monitor = null;\n    private TargetAppRunner targetAppRunner;\n    private FileObject profiledSingleFile;\n    final private ProfilerEngineSettings sharedSettings;\n    \n    private final Object setupLock = new Object();\n    private ProfilingSettings lastProfilingSettings;\n    private Lookup.Provider profiledProject = null;\n    private SessionSettings lastSessionSettings;\n    private StringBuilder logMsgs = new StringBuilder();\n    private ThreadsDataManager threadsManager;\n    private VMTelemetryDataManager vmTelemetryManager;\n    private VMTelemetryModels vmTelemetryModels;\n    private boolean calibrating = false;\n\n    // ---------------------------------------------------------------------------\n    // Temporary workaround to refresh profiling points when LiveResultsWindow is not refreshing\n    // TODO: implement better approach for refreshing profiling points and remove this code\n//    private boolean processesProfilingPoints;\n    private boolean threadsMonitoringEnabled = false;\n    private boolean lockContentionMonitoringEnabled = false;\n    private boolean waitDialogOpen = false;\n    private int lastMode = MODE_PROFILE;\n    private int profilingMode = MODE_PROFILE;\n    private int profilingState = PROFILING_INACTIVE;\n    \n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n    \n    public NetBeansProfiler() {\n        boolean initFailed = false;\n\n        sharedSettings = new ProfilerEngineSettings();\n\n        try {\n            String libsDir = getLibsDir();\n\n            if (libsDir == null) {\n                throw new IOException(Bundle.NetBeansProfiler_CannotFindLibsMsg());\n            }\n\n            sharedSettings.initialize(libsDir);\n            sharedSettings.setSeparateConsole(System.getProperty(\"org.netbeans.profiler.separateConsole\") != null //NOI18N\n                                              ); // change to true if something misbehaves and the TA VM does not start\n            sharedSettings.setTargetWindowRemains(System.getProperty(\"org.netbeans.profiler.targetWindowRemains\") != null //NOI18N\n                                                  ); // use for testing when something misbehaves\n        } catch (RuntimeException e) {\n            ProfilerLogger.log(e);\n            ProfilerDialogs.displayError(e.getMessage());\n            initFailed = true;\n        } catch (IOException e) {\n            // #216809 - likely an unsupported system, just silently log the problem\n            LOGGER.log(Level.WARNING, Bundle.NetBeansProfiler_EngineInitFailedMsg(e.getLocalizedMessage()));\n            initFailed = true;\n        }\n\n        \n        if (!initFailed) {\n            initialized = true;\n            new ServerStateMonitor(this);\n        }\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    public static NetBeansProfiler getDefaultNB() {\n        return (NetBeansProfiler) getDefault();\n    }\n\n    // ---------------------------------------------------------------------------\n    public static boolean isInitialized() {\n        // make sure that the profiler is initialized\n        getDefaultNB();\n        return initialized;\n    }\n\n    public int getAgentState(String host, int port, int agentId) {\n        if (profilingState /*!= PROFILING_INACTIVE*/ == PROFILING_RUNNING) {\n            // profiling currently in progress, check port and id\n            if (port == getTargetAppRunner().getProfilerEngineSettings().getPortNo()) {\n                if (getTargetAppRunner().getProfilerClient().getCurrentAgentId() == agentId) {\n                    return CommonConstants.AGENT_STATE_CONNECTED;\n                } else {\n                    return CommonConstants.AGENT_STATE_DIFFERENT_ID;\n                }\n            }\n        }\n\n        Properties agentProps = getAgentProperties(port);\n\n        if (agentProps == null) {\n            return CommonConstants.AGENT_STATE_NOT_RUNNING;\n        } else {\n            try {\n                int id = Integer.parseInt(agentProps.getProperty(\"agent.id\")); //NOI18N\n\n                if (id == agentId) {\n                    String dynamic = agentProps.getProperty(\"dynamic\"); //NOI18N\n\n                    if ((dynamic == null) || \"false\".equals(dynamic)) { //NOI18N\n\n                        return CommonConstants.AGENT_STATE_READY_DIRECT;\n                    } else {\n                        return CommonConstants.AGENT_STATE_READY_DYNAMIC;\n                    }\n                } else {\n                    return CommonConstants.AGENT_STATE_DIFFERENT_ID;\n                }\n            } catch (NumberFormatException e) {\n                return CommonConstants.AGENT_STATE_NOT_RUNNING;\n            }\n        }\n    }\n\n    public SessionSettings getCurrentSessionSettings() {\n        return lastSessionSettings;\n    }\n\n    public GlobalProfilingSettings getGlobalProfilingSettings() {\n        return ideSettings;\n    }\n\n    public ProfilingSettings getLastProfilingSettings() {\n        return lastProfilingSettings;\n    }\n\n    public abstract String getLibsDir();\n\n    public int getPlatformArchitecture(String platformName) {\n        JavaPlatform platform = JavaPlatform.getJavaPlatformById(platformName);\n\n        return platform.getPlatformArchitecture();\n    }\n\n    public String getPlatformJDKVersion(String platformName) {\n        JavaPlatform platform = JavaPlatform.getJavaPlatformById(platformName);\n\n        return platform.getPlatformJDKVersion();\n    }\n\n    public String getPlatformJavaFile(String platformName) {\n        JavaPlatform platform = JavaPlatform.getJavaPlatformById(platformName);\n\n        return platform.getPlatformJavaFile();\n    }\n\n    public int getProfilingMode() {\n        return profilingMode;\n    }\n\n    public int getProfilingState() {\n        return profilingState;\n    }\n\n    @Override\n    public int getServerState() {\n        if (monitor != null) {\n            return monitor.getServerState();\n        }\n        return CommonConstants.SERVER_RUNNING;\n    }\n    \n    @Override\n    public int getServerProgress() {\n        if (monitor != null) {\n            return monitor.getServerProgress();\n        }\n        return CommonConstants.SERVER_PROGRESS_INDETERMINATE;\n    }\n\n    public synchronized TargetAppRunner getTargetAppRunner() {\n        if (initialized) {\n            if (targetAppRunner == null) {\n                // Initialize shared TargetAppRunner instance\n                targetAppRunner = new TargetAppRunner(sharedSettings, new IDEAppStatusHandler(), getProfilingPointsManager());\n                targetAppRunner.addProfilingEventListener(new ProfilingEventListener() {\n                    @Override\n                    public void targetAppStarted() {\n                        if (calibrating) {\n                            return;\n                        }\n\n                        changeStateTo(PROFILING_RUNNING);\n                    }\n\n                    @Override\n                    public void targetAppStopped() {\n                        if (calibrating) {\n                            return;\n                        }\n\n                        changeStateTo(PROFILING_STOPPED);\n                    }\n\n                    @Override\n                    public void targetAppSuspended() {\n                        if (calibrating) {\n                            return;\n                        }\n\n                        changeStateTo(PROFILING_PAUSED);\n                    }\n\n                    @Override\n                    public void targetAppResumed() {\n                        if (calibrating) {\n                            return;\n                        }\n\n                        changeStateTo(PROFILING_RUNNING);\n                    }\n\n                    @Override\n                    public void attachedToTarget() {\n                        if (calibrating) {\n                            return;\n                        }\n\n                        changeStateTo(PROFILING_RUNNING);\n                    }\n\n                    @Override\n                    public void detachedFromTarget() {\n                        if (calibrating) {\n                            return;\n                        }\n\n                        getMonitor().stopDisplayingVM();\n                        changeStateTo(PROFILING_INACTIVE);\n                    }\n\n                    @Override\n                    public void targetVMTerminated() {\n                        if (calibrating) {\n                            return;\n                        }\n\n                        getMonitor().stopDisplayingVM();\n                        changeStateTo(PROFILING_INACTIVE);\n                    }\n                });\n            }\n            return targetAppRunner;\n        }\n        return null;\n    }\n\n    public synchronized ThreadsDataManager getThreadsManager() {\n        if (threadsManager == null) {\n            threadsManager = new ThreadsDataManager();\n        }\n\n        return threadsManager;\n    }\n\n    public void setThreadsMonitoringEnabled(final boolean enabled) {\n        getThreadsManager().setThreadsMonitoringEnabled(enabled);\n\n        if (threadsMonitoringEnabled == enabled) {\n            return;\n        }\n\n        threadsMonitoringEnabled = enabled;\n        fireThreadsMonitoringChange();\n    }\n\n    public boolean getThreadsMonitoringEnabled() {\n        return threadsMonitoringEnabled;\n    }\n    \n    public void setLockContentionMonitoringEnabled(final boolean enabled) {\n        if (lockContentionMonitoringEnabled == enabled) {\n            return;\n        }\n\n        if (getProfilingState() == PROFILING_RUNNING) {\n            final TargetAppRunner runner = getTargetAppRunner();\n            final ProfilerEngineSettings settings = runner.getProfilerEngineSettings();\n            \n            if (settings.isLockContentionMonitoringEnabled() != enabled && runner.targetJVMIsAlive()) {\n                settings.setLockContentionMonitoringEnabled(enabled);\n                try {\n                    runner.getProfilerClient().sendSetInstrumentationParamsCmd(true);\n                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                   settings.setLockContentionMonitoringEnabled(!enabled);\n                   ProfilerDialogs.displayError(ex.getMessage());\n                    return;\n                }\n            }\n        }\n        lockContentionMonitoringEnabled = enabled;\n        fireLockContentionMonitoringChange();\n    }\n\n    public boolean getLockContentionMonitoringEnabled() {\n        return lockContentionMonitoringEnabled;\n    }\n\n    public synchronized VMTelemetryModels getVMTelemetryModels() {\n        if (vmTelemetryModels == null) {\n            vmTelemetryModels = new VMTelemetryModels(getVMTelemetryManager());\n        }\n\n        return vmTelemetryModels;\n    }\n\n    public synchronized VMTelemetryDataManager getVMTelemetryManager() {\n        if (vmTelemetryManager == null) {\n            vmTelemetryManager = new VMTelemetryDataManager();\n        }\n\n        return vmTelemetryManager;\n    }\n\n    /**\n     * Attaches to a running application using provided settings\n     *\n     * @param profilingSettings Settings to use for profiling\n     * @param attachSettings    AttachSettings to use\n     * @return true if successfully attached, false otherwise\n     */\n    public boolean attachToApp(final ProfilingSettings profilingSettings, final AttachSettings attachSettings) {\n        profilingMode = MODE_ATTACH;\n\n        ProgressHandle ph = ProgressHandle.createHandle(Bundle.NetBeansProfiler_StartingSession());\n        ph.setInitialDelay(500);\n        \n        ph.start();\n        \n        try {\n            if (getProfilingState() != PROFILING_INACTIVE) {\n                if (lastMode == MODE_ATTACH) {\n                    detachFromApp(); // if attached, detach\n                } else if (getTargetAppRunner().targetJVMIsAlive()) {\n                    getTargetAppRunner().terminateTargetJVM(); // otherwise kill current app if running\n                }\n            }\n\n            // remember profiling settings\n            lastProfilingSettings = profilingSettings;\n            lastSessionSettings = null;\n            lastMode = MODE_ATTACH;\n            \n            final ProfilerEngineSettings sSettings = getTargetAppRunner().getProfilerEngineSettings();\n            profilingSettings.applySettings(sSettings); // can override the session settings\n            attachSettings.applySettings(sSettings);\n\n            //getThreadsManager().setSupportsSleepingStateMonitoring(\n            // Platform.supportsThreadSleepingStateMonitoring(sharedSettings.getTargetJDKVersionString()));\n            logActionConfig(\"attachToApp\", profilingSettings, null, attachSettings, sSettings.getInstrumentationFilter()); // NOI18N\n            \n            changeStateTo(PROFILING_STARTED);\n            \n            cleanupBeforeProfiling(sSettings);\n            \n            setThreadsMonitoringEnabled(profilingSettings.getThreadsMonitoringEnabled());\n            setLockContentionMonitoringEnabled(profilingSettings.getLockContentionMonitoringEnabled());\n            \n            if (shouldOpenWindowsOnProfilingStart()) {\n                CommonUtils.runInEventDispatchThread(new Runnable() {\n                    public void run() {\n                        openWindowsOnProfilingStart();\n                    }\n                });\n            }\n            \n            if (attachSettings.isDirect()) { // Previously known as \"attach on startup\"\n                // The VM is already started with all necessary options and waiting for us to connect.\n                // Remote profiling case fits here too - it's distinguished in ProfilerClient using attachSettings.isRemote()\n                // perform the selected instrumentation - it will really start right after the target app starts\n\n                boolean success = false;\n                \n                if (prepareInstrumentation(profilingSettings)) {\n                    success = getTargetAppRunner().initiateSession(1, false) && getTargetAppRunner().attachToTargetVMOnStartup();\n                }\n                \n                if (!success) {\n                    changeStateTo(PROFILING_INACTIVE);\n                    // change state back to inactive and fire, return false\n\n                    return false;\n                }\n            } else if (attachSettings.isDynamic16()) {\n                String jar = getLibsDir() + \"/jfluid-server-15.jar\"; // NOI18N\n                String pid = String.valueOf(attachSettings.getPid());\n                String options = String.valueOf(attachSettings.getPort());\n                boolean success = false;\n                \n                try {\n                    loadAgentIntoTargetJVM(jar, options, pid);\n                    \n                    if (prepareInstrumentation(profilingSettings)) {\n                        success = getTargetAppRunner().initiateSession(2, false) && getTargetAppRunner().attachToTargetVM();\n                    }\n                } catch (AgentInitializationException ex) {\n                    ProfilerDialogs.displayError(ex.getMessage()+\"\\n\"+Bundle.NetBeansProfiler_AgentFailed());   // NOI18N\n                    ProfilerLogger.log(ex);                    \n                } catch (Exception ex) {\n                    ProfilerDialogs.displayError(ex.getMessage());\n                    ProfilerLogger.log(ex);\n                }\n                \n                if (!success) {\n                    changeStateTo(PROFILING_INACTIVE);\n                    // change state back to inactive and fire, return false\n\n                    return false;\n                }\n            } else {\n                throw new IllegalArgumentException(\"Invalid settings \" + attachSettings); // NOI18N\n            }\n            \n            return connectToApp();\n        } finally {\n            ph.finish();\n        }\n    }\n    \n    private static void loadAgentIntoTargetJVM(final String jar, final String options, final String pid)\n                                            throws AttachNotSupportedException, IOException, AgentLoadException, AgentInitializationException  {\n        VirtualMachine virtualMachine = VirtualMachine.attach(pid);\n        try {\n            virtualMachine.loadAgent(jar,options);\n        } catch (AgentLoadException ex) {\n            if (\"0\".equals(ex.getMessage())) {\n                // JDK 10 -> JDK 9 mismatch\n                return;\n            }\n            throw ex;\n        } catch (IOException ex) {\n           if (\"readInt\".equals(ex.getStackTrace()[0].getMethodName())) {\n                // JDK 9 -> JDK 10 mismatch\n                return;\n            }\n            throw ex;\n        }\n    }\n\n    // -- NetBeansProfiler-only public methods -----------------------------------------------------------------------------\n    public void checkAndUpdateState() {\n        // TODO: check & refactor to remove this\n        final boolean targetVMAlive = getTargetAppRunner().targetJVMIsAlive();\n\n        if (!targetVMAlive) {\n            changeStateTo(PROFILING_INACTIVE);\n\n            return;\n        }\n\n        final boolean running = getTargetAppRunner().targetAppIsRunning();\n\n        if (!running) {\n            changeStateTo(PROFILING_STOPPED);\n\n            return;\n        }\n\n        final boolean suspended = getTargetAppRunner().targetAppSuspended();\n\n        if (suspended) {\n            changeStateTo(PROFILING_PAUSED);\n        }\n    }\n\n    // used before starting a server for profiling, kills any agent which would cause collision on port and removes agent file\n    // does nothing if the agent is already profiling (port is used, covers both profiling from current or other IDE)\n    public boolean cleanForProfilingOnPort(int port) {\n        // profiling session communicating over the port currently in progress, nothing to do (will cause collision)\n        if (isProfilingRunningOnPort(port)) {\n            ProfilerLogger.severe(\">>> Profiling session already running on port \" + port\n                                  + \", will cause collision when starting another agent on the same port.\"); // NOI18N\n\n            return false;\n        }\n\n        // there is an agent alive currently using the port, most likely profiling from within another IDE (will cause collision)\n        if (!shutdownAgent(\"localhost\", port)) { // NOI18N\n            ProfilerLogger.severe(\">>> Profiler agent already profiling on port \" + port\n                                  + \" (communicating with another IDE?), will cause collision when starting another agent on the same port.\"); // NOI18N\n\n            return false;\n        }\n\n        File agentFile = getInfoFile(port);\n\n        // agent file exists, agent is still shutting down or in undefined state (hanging?)\n        if (agentFile.exists()) {\n            // returns true if agent file successfuly deleted, false otherwise (will cause server startup failure because initial STATE_INACTIVE)\n            boolean fileDeleted = waitForDeleteAgentFile(agentFile);\n\n            if (!fileDeleted) {\n                ProfilerLogger.severe(\">>> Profiler agent identification file cannot be deleted for port \" + port\n                                      + \", will cause failure starting a server for profiling on the same port.\"); // NOI18N\n            }\n\n            return fileDeleted;\n        }\n\n        // agent file doesn't exist, there should be no collision starting new profiling session on port\n        return true;\n    }\n\n    /**\n     * Connects to an application started using the specified sessionSettings, and will start its profiling\n     * with the provided profilingSettings.\n     *\n     * @param profilingSettings Settings to use for profiling\n     * @param sessionSettings   Session settings for profiling\n     * @return true if connected successfully, false otherwise\n     */\n    @Override\n    public boolean connectToStartedApp(final ProfilingSettings profilingSettings, final SessionSettings sessionSettings) {\n        return connectToStartedApp(profilingSettings, sessionSettings, new AtomicBoolean());\n    }\n    \n    /**\n     * Connects to an application started using the specified sessionSettings, and will start its profiling\n     * with the provided profilingSettings.\n     *\n     * @param profilingSettings Settings to use for profiling\n     * @param sessionSettings   Session settings for profiling\n     * @param cancel shared cancel flag\n     * @return true if connected successfully, false otherwise\n     */\n    public boolean connectToStartedApp(final ProfilingSettings profilingSettings, final SessionSettings sessionSettings, final AtomicBoolean cancel) {\n        profilingMode = MODE_PROFILE;\n\n        lastProfilingSettings = profilingSettings;\n        lastSessionSettings = sessionSettings;\n        lastMode = MODE_PROFILE;\n\n        ProgressHandle ph = ProgressHandle.createHandle(Bundle.NetBeansProfiler_StartingSession());\n        try {\n            ph.setInitialDelay(500);\n            ph.start();\n            \n            if (getTargetAppRunner().targetJVMIsAlive()) {\n                getTargetAppRunner().terminateTargetJVM();\n            }\n            \n            final ProfilerEngineSettings sSettings = getTargetAppRunner().getProfilerEngineSettings();\n            \n            sessionSettings.applySettings(sSettings);\n            profilingSettings.applySettings(sSettings); // can override the session settings\n            sSettings.setInstrumentObjectInit(false); // clear instrument object.<init>\n            //sSettings.setRemoteHost(\"\"); // NOI18N // clear remote profiling host\n\n            //getThreadsManager().setSupportsSleepingStateMonitoring(\n            // Platform.supportsThreadSleepingStateMonitoring(sharedSettings.getTargetJDKVersionString()));\n            logActionConfig(\"connectToStartedApp\", profilingSettings, sessionSettings, null, sSettings.getInstrumentationFilter()); // NOI18N\n            \n            if (prepareProfilingSession(profilingSettings, sessionSettings)) {\n                RequestProcessor.getDefault().post(new Runnable() {\n                    \n                    @Override\n                    public void run() {\n                        // should propagate the result of the following operation somehow; current workflow doesn't allow it\n                        if (tryInitiateSession(sessionSettings, cancel)) {\n                            connectToApp();\n                        }\n                    }\n                });\n                \n                return true;\n            }\n            \n            return false;\n        } finally {\n            ph.finish();\n        }\n    }\n\n    private boolean prepareProfilingSession(ProfilingSettings profilingSettings, SessionSettings sessionSettings) {\n        changeStateTo(PROFILING_STARTED);\n\n        cleanupBeforeProfiling(getTargetAppRunner().getProfilerEngineSettings());\n\n        setThreadsMonitoringEnabled(profilingSettings.getThreadsMonitoringEnabled());\n        setLockContentionMonitoringEnabled(profilingSettings.getLockContentionMonitoringEnabled());\n\n        if (shouldOpenWindowsOnProfilingStart()) {\n            CommonUtils.runInEventDispatchThread(new Runnable() {\n                public void run() {\n                    openWindowsOnProfilingStart();\n                }\n            });\n        }\n        if (sessionSettings.getRemoteHost().isEmpty() && !CalibrationDataFileIO.validateCalibrationInput(\n                sessionSettings.getJavaVersionString(),sessionSettings.getJavaExecutable())) {\n            ProfilerDialogs.displayError(Bundle.NetBeansProfiler_MustCalibrateFirstShortMsg(), null, Bundle.NetBeansProfiler_MustCalibrateFirstMsg());\n            changeStateTo(PROFILING_INACTIVE);\n\n            return false; // failed, cannot proceed\n        }\n\n        // perform the selected instrumentation\n        if (!prepareInstrumentation(profilingSettings)) {\n            return false; // failed, cannot proceed\n        }\n        \n        return true;\n    }\n    \n    private boolean tryInitiateSession(SessionSettings sessionSettings, AtomicBoolean cancel) {\n        if (!targetAppRunner.initiateSession(sessionSettings.getRemoteHost().isEmpty() ? 0 : 1, false, cancel) || !targetAppRunner.connectToStartedVMAndStartTA()) {\n            changeStateTo(PROFILING_INACTIVE);\n            return false; // failed, cannot proceed\n        }\n        return true;\n    }\n    \n    private boolean connectToApp() {\n        if (getTargetAppRunner().targetAppIsRunning()) {\n            getThreadsManager()\n                .setSupportsSleepingStateMonitoring(Platform.supportsThreadSleepingStateMonitoring(getTargetAppRunner().getProfilerEngineSettings().getTargetJDKVersionString()));\n            CommonUtils.runInEventDispatchThread(new Runnable() {\n                    public void run() {\n                        getMonitor().monitorVM(getTargetAppRunner());\n                    }\n                });\n\n            return true;\n        } else {\n            // TODO: notify the user???\n            changeStateTo(PROFILING_INACTIVE);\n\n            return false; // failed, cannot proceed\n        }\n    }\n    \n    public void detachFromApp() {\n        TargetAppRunner runner = getTargetAppRunner();\n        if (runner == null || !runner.targetJVMIsAlive()) return;\n        \n        changeStateTo(PROFILING_IN_TRANSITION);\n\n        runner.prepareDetachFromTargetJVM();\n\n        if (runner.getProfilingSessionStatus().currentInstrType != CommonConstants.INSTR_NONE) {\n            //      if (LiveResultsWindow.hasDefault()) LiveResultsWindow.getDefault().reset(); // see issue http://www.netbeans.org/issues/show_bug.cgi?id=68213\n            try {\n                runner.getProfilerClient().removeAllInstrumentation(false); // remove only the server side instrumentation\n            } catch (InstrumentationException e) {\n                ProfilerDialogs.displayError(e.getMessage());\n            }\n        }\n\n        runner.detachFromTargetJVM();\n\n        //    targetAppRunner.getProfilerClient().resetClientData();\n        // TODO reset all profilingresultslisteners\n        //    CPUCallGraphBuilder.resetCollectors();\n        //    ResultsManager.getDefault().reset();\n    }\n\n    public void instrumentSelectedRoots(ClientUtils.SourceCodeSelection[] rootMethods)\n                                 throws ClassNotFoundException, InstrumentationException, BadLocationException, IOException,\n                                        ClassFormatError, ClientUtils.TargetAppOrVMTerminated {\n        final ProfilerClient client = getTargetAppRunner().getProfilerClient();\n\n        if (rootMethods.length == 0) {\n            ClientUtils.SourceCodeSelection selection = new ClientUtils.SourceCodeSelection(1); // spawned threads recursively\n            rootMethods = new ClientUtils.SourceCodeSelection[] { selection };\n        }\n\n        // Start the recursive code instrumentation\n        client.initiateRecursiveCPUProfInstrumentation(rootMethods);\n    }\n\n    public void log(int severity, final String message) {\n        switch (severity) {\n            case Profiler.INFORMATIONAL:\n                LOGGER.log(Level.INFO, message);\n\n                break;\n            case Profiler.WARNING:\n                LOGGER.log(Level.WARNING, message);\n\n                break;\n            case Profiler.EXCEPTION:\n            case Profiler.ERROR:\n                LOGGER.log(Level.SEVERE, message);\n\n                break;\n            default:\n                LOGGER.log(Level.FINEST, message);\n\n                break;\n        }\n    }\n\n    // ---------------------------------------------------------------------------\n    public void modifyCurrentProfiling(final ProfilingSettings profilingSettings) {\n        lastProfilingSettings = profilingSettings;\n\n        if (!targetAppRunner.targetJVMIsAlive()) {\n            return;\n        }\n\n        final ProfilerEngineSettings sharedSettings = getTargetAppRunner().getProfilerEngineSettings();\n        profilingSettings.applySettings(sharedSettings);\n        sharedSettings.setInstrumentObjectInit(true);\n\n        logActionConfig(\"modifyCurrentProfiling\", profilingSettings, null, null, sharedSettings.getInstrumentationFilter()); //NOI18N\n\n        setThreadsMonitoringEnabled(profilingSettings.getThreadsMonitoringEnabled());\n        setLockContentionMonitoringEnabled(profilingSettings.getLockContentionMonitoringEnabled());\n\n//        SwingUtilities.invokeLater(new Runnable() {\n//            @Override\n//            public void run() {\n//                if (LiveResultsWindow.hasDefault())\n//                    LiveResultsWindow.getDefault().handleCleanupBeforeProfiling();\n//            }\n//        });\n\n        ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                @Override\n                public void run() {\n                    changeStateTo(PROFILING_IN_TRANSITION);\n                    getTargetAppRunner().getAppStatusHandler().pauseLiveUpdates();\n                    ResultsManager.getDefault().reset();\n\n                    try {\n                        Thread.sleep(100);\n                    } catch (InterruptedException e) {\n                    }\n\n                    AppStatusHandler.AsyncDialog waitDialog = getTargetAppRunner().getAppStatusHandler()\n                                                .getAsyncDialogInstance(Bundle.NetBeansProfiler_ModifyingInstrumentationMsg(), true, null);\n                    waitDialog.display();\n\n                    try {\n                        prepareInstrumentation(profilingSettings);\n                        changeStateTo(PROFILING_RUNNING);\n                    } finally {\n                        waitDialog.close();\n\n                        getTargetAppRunner().getAppStatusHandler().resumeLiveUpdates();\n                    }\n                }\n            });\n    }\n\n    public void notifyException(final int severity, final Exception e) {\n        switch (severity) {\n            case Profiler.INFORMATIONAL:\n                LOGGER.log(Level.INFO, null, e);\n\n                break;\n            case Profiler.WARNING:\n                LOGGER.log(Level.WARNING, null, e);\n\n                break;\n            default:\n                LOGGER.log(Level.SEVERE, null, e);\n\n                break;\n        }\n    }\n\n    public void openJavaSource(String className, String methodName, String methodSig) {\n//        openJavaSource(getProfiledProject(), className, methodName, methodSig);\n    }\n    \n    public boolean processesProfilingPoints() {\n        ProfilingPointsProcessor ppp = getProfilingPointsManager();\n        if (ppp != null) {\n            return ppp.getSupportedProfilingPoints().length > 0;\n        }\n        return false;\n    }\n\n    /**\n     * Starts the TA described via sessionSettings, using profiling mode specified in profilingSettings.\n     *\n     * @param profilingSettings Settings to use for profiling\n     * @param sessionSettings   Session settings for profiling\n     * @return true if target app successfully started, false otherwise\n     */\n    public boolean profileClass(final ProfilingSettings profilingSettings, final SessionSettings sessionSettings) {\n        //final long time = System.currentTimeMillis();\n        profilingMode = MODE_PROFILE;\n\n        lastProfilingSettings = profilingSettings;\n        lastSessionSettings = sessionSettings;\n        lastMode = MODE_PROFILE;\n\n        if (getTargetAppRunner().targetJVMIsAlive()) {\n            getTargetAppRunner().terminateTargetJVM();\n        }\n\n        final ProfilerEngineSettings sSettings = getTargetAppRunner().getProfilerEngineSettings();\n\n        sessionSettings.applySettings(sSettings);\n        profilingSettings.applySettings(sSettings); // can override the session settings\n        sSettings.setRemoteHost(\"\"); // NOI18N // clear remote profiling host\n        sSettings.setInstrumentObjectInit(false); // clear instrument object.<init>\n\n        //getThreadsManager().setSupportsSleepingStateMonitoring(\n        // Platform.supportsThreadSleepingStateMonitoring(sharedSettings.getTargetJDKVersionString()));\n        logActionConfig(\"profileClass\", profilingSettings, sessionSettings, null, sSettings.getInstrumentationFilter()); //NOI18N\n\n        changeStateTo(PROFILING_STARTED);\n\n        //    System.err.println(\"--------------------------------------------- 2: \"+ (System.currentTimeMillis() - time));\n        cleanupBeforeProfiling(sSettings);\n\n        setThreadsMonitoringEnabled(profilingSettings.getThreadsMonitoringEnabled());\n        setLockContentionMonitoringEnabled(profilingSettings.getLockContentionMonitoringEnabled());\n        //    System.err.println(\"------------------------------------------ 3: \"+ (System.currentTimeMillis() - time));\n        if (shouldOpenWindowsOnProfilingStart()) {\n            openWindowsOnProfilingStart();\n        }\n\n        //    System.err.println(\"------------------------------------- 4: \"+ (System.currentTimeMillis() - time));\n        final Window mainWindow = WindowManager.getDefault().getMainWindow();\n\n        // This call reduces the speedup for class instrumentation on the 2nd and further runs that we could otherwise\n        // have, but guarantees that if any classes have been recompiled in between runs, their most up-to-date copies will\n        // be used.\n        ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                public void run() {\n                    final Cursor cursor = mainWindow.getCursor();\n                    mainWindow.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));\n\n                    try {\n                        if (!runCalibration(true, sessionSettings.getJavaExecutable(), sessionSettings.getJavaVersionString(),\n                                                sessionSettings.getSystemArchitecture())) {\n                            ProfilerDialogs.displayError(Bundle.ProfilerModule_CalibrationFailedMessage());\n                            changeStateTo(PROFILING_INACTIVE);\n\n                            return; // failed, cannot proceed\n                        }\n\n                        // System.err.println(\"-----------------------------------5: \"+ (System.currentTimeMillis() - time));\n                        // perform the selected instrumentation\n                        boolean success = prepareInstrumentation(profilingSettings);\n\n                        // and run the target application\n                        //        System.err.println(\"---------------------------- 6: \"+ (System.currentTimeMillis() - time));\n                        success = success && getTargetAppRunner().startTargetVM() && getTargetAppRunner().initiateSession(0, false)\n                                  && getTargetAppRunner().connectToStartedVMAndStartTA();\n\n                        if (!success) {\n                            changeStateTo(PROFILING_INACTIVE);\n\n                            return;\n                        }\n\n                        // System.err.println(\"---------------------------- 7: \"+ (System.currentTimeMillis() - time));\n                        if (getTargetAppRunner().targetAppIsRunning()) {\n                            getThreadsManager()\n                                .setSupportsSleepingStateMonitoring(Platform.supportsThreadSleepingStateMonitoring(sSettings.getTargetJDKVersionString()));\n                            CommonUtils.runInEventDispatchThread(new Runnable() {\n                                    public void run() {\n                                        // System.err.println(\"------------ 8: \"+ (System.currentTimeMillis() - time));\n                                        getMonitor().monitorVM(getTargetAppRunner());\n\n                                        // System.err.println(\"------------------------ 9: \"+ (System.currentTimeMillis() - time));\n                                        // System.err.println(\"------------------------ 11: \"+ (System.currentTimeMillis() - time));\n                                    }\n                                });\n                        } else {\n                            // TODO: notify the user???\n                            changeStateTo(PROFILING_INACTIVE);\n                        }\n                    } finally {\n                        mainWindow.setCursor(cursor);\n                    }\n                }\n            });\n\n        //    Syst---------------------------------------------------- Final: \"+ (System.currentTimeMillis() - time));\n        return true;\n    }\n\n    protected boolean shouldOpenWindowsOnProfilingStart() {\n        return true;\n    }\n\n    // NOTE: used from org.graalvm.visualvm.profiler.ProfilerSupport.calibrateJVM(),\n    //       requires targetAppRunner to be configured correctly. Most likely you want to use\n    //       runCalibration(boolean checkForSaved, String jvmExecutable, String jdkString, int architecture) !!!\n    public boolean runConfiguredCalibration() {\n        calibrating = true;\n        boolean result = targetAppRunner.calibrateInstrumentationCode();\n        calibrating = false;\n\n        return result;\n    }\n\n    public boolean runCalibration(boolean checkForSaved, String jvmExecutable, String jdkString, int architecture) {\n        calibrating = true;\n\n        ProfilerEngineSettings pes = getTargetAppRunner().getProfilerEngineSettings();\n\n        int savedPort = pes.getPortNo();\n        GenericFilter savedInstrFilter = pes.getInstrumentationFilter();\n        String savedJVMExeFile = pes.getTargetJVMExeFile();\n        String savedJDKVersionString = pes.getTargetJDKVersionString();\n        int savedArch = pes.getSystemArchitecture();\n        String savedCP = pes.getMainClassPath();\n\n        if (jvmExecutable != null) {\n            pes.setTargetJVMExeFile(jvmExecutable);\n            pes.setTargetJDKVersionString(jdkString);\n            pes.setSystemArchitecture(architecture);\n        }\n\n        pes.setPortNo(ideSettings.getCalibrationPortNo());\n        pes.setInstrumentationFilter(new GenericFilter());\n        pes.setMainClassPath(\"\"); //NOI18N\n\n        boolean result = false;\n\n        if (checkForSaved) {\n            result = getTargetAppRunner().readSavedCalibrationData();\n\n            if (!result) {\n                ProfilerDialogs.displayInfo(Bundle.NetBeansProfiler_InitialCalibrationMsg());\n                result = getTargetAppRunner().calibrateInstrumentationCode();\n            }\n            \n            // NOTE: use -Dprofiler.disableFTSRecalibration=true to skip fast\n            //       timestamp recalibration for each profiling session on old\n            //       linux kernels not supporting Time Stamp Counter.\n            if (!Boolean.getBoolean(\"profiler.disableFTSRecalibration\")) { // NOI18N\n                boolean shouldCalibrate = false;\n                getTargetAppRunner().getProfilingSessionStatus().beginTrans(false);\n                try {\n                    // the calibration was executed without the usage of \"-XX:+UseLinuxPosixThreadCPUClocks\" flag\n                    // ---> recalibrate <---\n                    shouldCalibrate = Platform.isLinux() &&\n                                      Platform.JDK_16_STRING.equals(pes.getTargetJDKVersionString()) &&\n                                      getTargetAppRunner().getProfilingSessionStatus().methodEntryExitCallTime[1] > 20000; // 20us\n                } finally {\n                    getTargetAppRunner().getProfilingSessionStatus().endTrans();\n                }\n                if (shouldCalibrate) {\n                    result = getTargetAppRunner().calibrateInstrumentationCode();\n                }\n            }\n        } else {\n            result = getTargetAppRunner().calibrateInstrumentationCode();\n        }\n\n        calibrating = false;\n\n        // restore original values\n        pes.setPortNo(savedPort);\n        pes.setInstrumentationFilter(savedInstrFilter);\n        pes.setTargetJDKVersionString(savedJDKVersionString);\n        pes.setSystemArchitecture(savedArch);\n        pes.setTargetJVMExeFile(savedJVMExeFile);\n        pes.setMainClassPath(savedCP);\n\n        return result;\n    }\n\n    public void setProfiledProject(Lookup.Provider project, FileObject singleFile) {\n        profiledProject = project;\n        profiledSingleFile = singleFile;\n//        SwingUtilities.invokeLater(new Runnable() {\n//            @Override\n//            public void run() {\n//                if (ProfilerControlPanel2.hasDefault())\n//                    ProfilerControlPanel2.getDefault().setProfiledProject(profiledProject);\n//            }\n//        });\n    }\n\n    public Lookup.Provider getProfiledProject() {\n        return profiledProject;\n    }\n\n    public FileObject getProfiledSingleFile() {\n        return profiledSingleFile;\n    }\n\n    @Override\n    public boolean prepareInstrumentation(ProfilingSettings profilingSettings) {\n        teardownDispatcher();\n        setupDispatcher(profilingSettings);\n        \n//        ClientUtils.SourceCodeSelection[] marks = MarkingEngine.getDefault().getMarkerMethods();\n//        profilingSettings.setInstrumentationMarkerMethods(marks);\n        profilingSettings.setInstrumentationMarkerMethods(new ClientUtils.SourceCodeSelection[0]);\n\n        return prepareInstrumentationImpl(profilingSettings);\n    }\n    \n    private synchronized ProfilingMonitor getMonitor() {\n        if (monitor == null) {\n            monitor = new ProfilingMonitor();\n            monitor.addPropertyChangeListener(new PropertyChangeListener() {\n                        @Override\n                        public void propertyChange(PropertyChangeEvent evt) {\n                            if (evt.getPropertyName().equals(ProfilingMonitor.PROPERTY_SERVER_STATE)\n                                || evt.getPropertyName().equals(ProfilingMonitor.PROPERTY_SERVER_PROGRESS)) {\n                                fireServerStateChanged(((ProfilingMonitor)evt.getSource()).getServerState(),\n                                                       ((ProfilingMonitor)evt.getSource()).getServerProgress());\n                            }\n                        }\n                    });            \n        }\n        return monitor;\n    }\n    \n    private boolean prepareInstrumentationImpl(ProfilingSettings profilingSettings) {\n        try {\n            return super.prepareInstrumentation(profilingSettings);\n        } catch (ClientUtils.TargetAppOrVMTerminated e) {\n            ProfilerDialogs.displayWarning(e.getMessage());\n            e.printStackTrace(System.err);\n        } catch (InstrumentationException e) {\n            ProfilerDialogs.displayError(e.getMessage());\n            e.printStackTrace(System.err);\n        } catch (BadLocationException e) {\n            ProfilerDialogs.displayError(e.getMessage());\n            e.printStackTrace(System.err);\n        } catch (ClassNotFoundException e) {\n            ProfilerDialogs.displayError(e.getMessage());\n            e.printStackTrace(System.err);\n        } catch (IOException e) {\n            ProfilerDialogs.displayError(e.getMessage());\n        } catch (ClassFormatError e) {\n            ProfilerDialogs.displayError(e.getMessage());\n        }\n\n        return false;\n    }\n\n//    // TODO [ian] - perform saving of global settings differently\n//    public void saveFilters() {\n//        // 1. save global filters\n//        FileLock lock = null;\n//\n//        try {\n//            Properties globalFiltersProps = new Properties();\n//            globalFilters.store(globalFiltersProps);\n//            ProfilerStorage.saveGlobalProperties(globalFiltersProps, GLOBAL_FILTERS_FILENAME);\n//        } catch (Exception e) {\n//            ProfilerLogger.log(e);\n//            ProfilerDialogs.displayError(\n//                Bundle.NetBeansProfiler_ErrorSavingProfilingSettingsMessage(e.getMessage()));\n//        } finally {\n//            if (lock != null) {\n//                lock.releaseLock();\n//            }\n//        }\n//\n//        // 2. save defined Filter Sets\n//        lock = null;\n//\n//        try {\n//            Properties definedFilterSetsProps = new Properties();\n//            definedFilterSets.store(definedFilterSetsProps);\n//            ProfilerStorage.saveGlobalProperties(definedFilterSetsProps, DEFINED_FILTERSETS_FILENAME);\n//        } catch (Exception e) {\n//            ProfilerLogger.log(e);\n//            ProfilerDialogs.displayError(\n//                Bundle.NetBeansProfiler_ErrorSavingFilterSetsMessage(e.getMessage()));\n//        } finally {\n//            if (lock != null) {\n//                lock.releaseLock();\n//            }\n//        }\n//    }\n\n    public void shutdown() {\n        getMonitor().stopUpdateThread();\n    }\n\n    // (synchronous - blocking) Used for stopping a server from a blocking state ready for direct attach (org.netbeans.modules.j2ee.deployment.profiler.spi.Profiler.shutdown())\n    // returns true if the agent was correctly finished from blocked state, false otherwise\n    public boolean shutdownBlockedAgent(String host, int port, int agentId) {\n        int state = getAgentState(host, port, agentId);\n\n        if (state == CommonConstants.AGENT_STATE_READY_DIRECT) {\n            Socket clientSocket = null;\n            ObjectOutputStream socketOut = null;\n            ObjectInputStream socketIn = null;\n\n            try {\n                clientSocket = new Socket(host, port);\n                clientSocket.setSoTimeout(100);\n                clientSocket.setTcpNoDelay(true); // Necessary at least on Solaris to avoid delays in e.g. readInt() etc.\n                socketOut = new ObjectOutputStream(clientSocket.getOutputStream());\n                socketIn = new ObjectInputStream(clientSocket.getInputStream());\n\n                WireIO wio = new WireIO(socketOut, socketIn);\n                wio.sendSimpleCommand(Command.TERMINATE_TARGET_JVM);\n\n                Object o = wio.receiveCommandOrResponse();\n\n                if (o instanceof Response && ((Response) o).isOK()) {\n                    return true;\n                } else {\n                    return false;\n                }\n            } catch (IOException e) {\n                return false;\n            } finally {\n                try {\n                    if (socketIn != null) {\n                        socketIn.close();\n                    }\n\n                    if (socketOut != null) {\n                        socketOut.close();\n                    }\n\n                    if (clientSocket != null) {\n                        clientSocket.close();\n                    }\n                } catch (IOException e) {\n                    ProfilerLogger.log(e);\n                }\n            }\n        } else {\n            return false;\n        }\n    }\n\n    public void stopApp() {\n        TargetAppRunner runner = getTargetAppRunner();\n        if (runner == null || !runner.targetJVMIsAlive()) return;\n        \n        changeStateTo(PROFILING_IN_TRANSITION);\n        runner.terminateTargetJVM();\n    }\n\n    private Properties getAgentProperties(int port) {\n        File f = getInfoFile(port);\n\n        if (!f.exists()) {\n            return null; // No agent is running\n        }\n\n        BufferedInputStream bis = null;\n\n        try {\n            Properties props = new Properties();\n            FileInputStream fis = new FileInputStream(f);\n            bis = new BufferedInputStream(fis);\n\n            props.load(bis);\n\n            bis.close();\n\n            return props;\n        } catch (IOException e) {\n            // commented out, the file is sometimes deleted before creating FileInputStream,\n            // which results in FileNotFoundException. This actually means that the file doesn't exist\n            // and that the Profiler is connected, so silently returning null is correct.\n            //e.printStackTrace();\n            return null;\n        } finally {\n            if (bis != null) {\n                try {\n                    bis.close();\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n            }\n        }\n    }\n\n    private static File getInfoFile(int port) {\n        String homeDir = System.getProperty(\"user.home\"); // NOI18N\n\n        return new File(homeDir + File.separator + \".nbprofiler\" + File.separator + port); // NOI18N\n    }\n\n    // checks if there is a profiling session currently in progress communicating over specified port\n    private boolean isProfilingRunningOnPort(int port) {\n        return (profilingState == PROFILING_RUNNING) && (port == getTargetAppRunner().getProfilerEngineSettings().getPortNo());\n    }\n\n    private void changeStateTo(int newState) {\n        if (profilingState == newState) {\n            return;\n        }\n\n        final int oldProfilingState = profilingState;\n        profilingState = newState;\n        fireProfilingStateChange(oldProfilingState, profilingState);\n\n        if ((newState == PROFILING_INACTIVE) || (newState == PROFILING_STOPPED)) {\n            cleanupAfterProfiling();\n        }\n        \n        if (newState == PROFILING_RUNNING && CommonConstants.JDK_15_STRING.\n                equals(getTargetAppRunner().getProfilerEngineSettings().getTargetJDKVersionString())) {\n            if (lastProfilingSettings.getProfilingType() == ProfilingSettings.PROFILE_MEMORY_SAMPLING)\n                SwingUtilities.invokeLater(new Runnable() { // Let the underlying dialogs close first\n                    public void run() {\n                        ProfilerDialogs.displayWarning(Bundle.NetBeansProfiler_MemorySamplingJava5());\n                    }\n                });                    \n        }\n    }\n\n    protected void cleanupAfterProfiling() {\n        teardownDispatcher();\n//        MarkingEngine.getDefault().deconfigure();\n        ClassRepository repo = targetAppRunner.getProfilerClient().getClassRepository();\n        repo.cleanup();\n    }\n\n    private void cleanupBeforeProfiling(ProfilerEngineSettings sharedSettings) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                NetBeansProfiler.this.getThreadsManager().reset();\n                NetBeansProfiler.this.getVMTelemetryManager().reset();\n//                if (LiveResultsWindow.hasDefault())\n//                    LiveResultsWindow.getDefault().handleCleanupBeforeProfiling();\n            }\n        });\n        ResultsManager.getDefault().reset();\n\n        ClassRepository repo = targetAppRunner.getProfilerClient().getClassRepository();\n        repo.clearCache();\n        repo.initClassPaths(sharedSettings.getWorkingDir(), sharedSettings.getVMClassPaths());\n    }\n\n//    private void displayWarningAboutEntireAppProfiling() {\n//        ProfilerDialogs.displayWarning(Bundle.NetBeansProfiler_EntireApplicationProfilingWarning());\n//    }\n//\n//    // -- Package-Private stuff --------------------------------------------------------------------------------------------\n//    private void loadGlobalFilters() {\n//        try {\n//            Properties globalFiltersProps = new Properties();\n//            ProfilerStorage.loadGlobalProperties(globalFiltersProps, GLOBAL_FILTERS_FILENAME);\n//            globalFilters = new GlobalFilters();\n//            globalFilters.load(globalFiltersProps);\n//            \n//            Properties definedFilterSetsProps = new Properties();\n//            ProfilerStorage.loadGlobalProperties(definedFilterSetsProps, DEFINED_FILTERSETS_FILENAME);\n//            definedFilterSets = new DefinedFilterSets();\n//            definedFilterSets.load(definedFilterSetsProps);\n//        } catch (Exception e) {\n//            ProfilerLogger.log(e);\n//            ProfilerDialogs.displayError(\n//                Bundle.NetBeansProfiler_ErrorLoadingProfilingSettingsMessage(e.getMessage()));\n//        }\n//    }\n\n    // -- Private implementation -------------------------------------------------------------------------------------------\n    private void openWindowsOnProfilingStart() {\n//        int telemetryBehavior = ideSettings.getTelemetryOverviewBehavior();\n//        int threadsBehavior = ideSettings.getThreadsViewBehavior();\n//        int locksBehavior = ideSettings.getLockContentionViewBehavior();\n//\n//        boolean threadsEnabled = lastProfilingSettings.getThreadsMonitoringEnabled();\n//        boolean lockContentionEnabled = lastProfilingSettings.getLockContentionMonitoringEnabled();\n//        int type = lastProfilingSettings.getProfilingType();\n//\n//        // 1. Telemetry Overview\n//        if ((telemetryBehavior == ProfilerIDESettings.OPEN_ALWAYS)\n//                || ((telemetryBehavior == ProfilerIDESettings.OPEN_MONITORING) && (type == ProfilingSettings.PROFILE_MONITOR))) {\n//            TelemetryOverviewPanel.getDefault().open();\n//            TelemetryOverviewPanel.getDefault().requestVisible();\n//        }\n//\n//        // 2. Threads view\n//        if (threadsEnabled) {\n//            if ((threadsBehavior == ProfilerIDESettings.OPEN_ALWAYS)\n//                    || ((threadsBehavior == ProfilerIDESettings.OPEN_MONITORING) && (type == ProfilingSettings.PROFILE_MONITOR))) {\n//                ThreadsWindow.getDefault().open();\n//                ThreadsWindow.getDefault().requestVisible();\n//            }\n//        }\n//        \n//        // 3. Lock Contention view\n//        if (lockContentionEnabled) {\n//            if ((locksBehavior == ProfilerIDESettings.OPEN_ALWAYS)\n//                    || ((locksBehavior == ProfilerIDESettings.OPEN_MONITORING) && (type == ProfilingSettings.PROFILE_MONITOR))) {\n//                LockContentionWindow.getDefault().showView();\n//            }\n//        }\n//\n//        // 4. Live Results\n//        if ((ideSettings.getDisplayLiveResultsCPU()\n//                && ((type == ProfilingSettings.PROFILE_CPU_ENTIRE) || (type == ProfilingSettings.PROFILE_CPU_PART)\n//                    || (type == ProfilingSettings.PROFILE_CPU_SAMPLING)))\n//                || (ideSettings.getDisplayLiveResultsFragment() && (type == ProfilingSettings.PROFILE_CPU_STOPWATCH))\n//                || (ideSettings.getDisplayLiveResultsMemory()\n//                       && ((type == ProfilingSettings.PROFILE_MEMORY_ALLOCATIONS)\n//                           || (type == ProfilingSettings.PROFILE_MEMORY_LIVENESS)\n//                           || (type == ProfilingSettings.PROFILE_MEMORY_SAMPLING)))) {\n//            LiveResultsWindow.getDefault().open();\n//            LiveResultsWindow.getDefault().requestVisible();\n//        }\n//\n//        // 5. Control Panel displayed always, and getting focus\n//        final ProfilerControlPanel2 controlPanel2 = ProfilerControlPanel2.getDefault();\n//        controlPanel2.open();\n//        controlPanel2.requestActive();\n    }\n\n    @NbBundle.Messages({\n        \"MSG_StartingProfilerClient=Starting Profiler Client\"\n    })\n    public boolean startEx(final ProfilingSettings profilingSettings, final SessionSettings sessionSettings, final AtomicBoolean cancel) {\n        final boolean[] rslt = new boolean[1];\n        final CountDownLatch latch = new CountDownLatch(1);\n        \n        if (sessionSettings.getRemoteHost().isEmpty()&&(!CalibrationDataFileIO.validateCalibrationInput(sessionSettings.getJavaVersionString(), sessionSettings.getJavaExecutable())\n        || !runCalibration(true, sessionSettings.getJavaExecutable(), sessionSettings.getJavaVersionString(),sessionSettings.getSystemArchitecture()))) {\n            ProfilerDialogs.displayError(Bundle.ProfilerModule_CalibrationFailedMessage());\n            return false;\n        }\n                \n        new SwingWorker(false) {\n            volatile private ProgressDisplayer pd;\n            @Override\n            protected void doInBackground() {\n                if (isCancelled()) return;\n                \n                connectToStartedApp(profilingSettings, sessionSettings, cancel);\n            }\n\n            @Override\n            protected void done() {\n                if (pd != null) {\n                    pd.close();\n                    pd = null;\n                }\n                rslt[0] = true;\n                latch.countDown();\n            }\n\n            @Override\n            protected void nonResponding() {\n                final SwingWorker thiz = this;\n                pd = ProfilerProgressDisplayer.getDefault().showProgress(Bundle.MSG_StartingProfilerClient(), new ProgressDisplayer.ProgressController() {\n                    @Override\n                    public boolean cancel() {\n                        thiz.cancel();\n                        return true;\n                    }\n                });\n            }\n\n            @Override\n            protected void cancelled() {\n                if (pd != null) {\n                    pd.close();\n                    pd = null;\n                }\n                rslt[0] = false;\n                cancel.set(true);\n                latch.countDown();\n            }\n\n            @Override\n            protected int getWarmup() {\n                return 1500;\n            }\n        }.execute();\n        \n        try {\n            latch.await();\n            return rslt[0];\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n        }\n        return false;\n    }\n    \n    public void setupDispatcher(ProfilingSettings profilingSettings) {\n        lastProfilingSettings = profilingSettings;\n        synchronized (setupLock) {\n            final Lookup.Provider project = getProfiledProject();\n\n            // configure call-context-tree dispatching infrastructure\n            CCTProvider cctProvider = null;\n            Collection<?extends CCTProvider.Listener> cctListeners = null;\n\n            switch (profilingSettings.getProfilingType()) {\n                case ProfilingSettings.PROFILE_CPU_ENTIRE:\n                case ProfilingSettings.PROFILE_CPU_PART:\n                case ProfilingSettings.PROFILE_CPU_JDBC:\n                case ProfilingSettings.PROFILE_CPU_SAMPLING:\n                case ProfilingSettings.PROFILE_CPU_STOPWATCH: {\n                    cctProvider = Lookup.getDefault().lookup(CPUCCTProvider.class);\n                    cctListeners = Lookup.getDefault().lookupAll(CPUCCTProvider.Listener.class);\n\n                    break;\n                }\n                case ProfilingSettings.PROFILE_MEMORY_ALLOCATIONS:\n                case ProfilingSettings.PROFILE_MEMORY_LIVENESS: {\n                    cctProvider = Lookup.getDefault().lookup(MemoryCCTProvider.class);\n                    cctListeners = Lookup.getDefault().lookupAll(MemoryCCTProvider.Listener.class);\n\n                    break;\n                }\n            }\n\n            if ((cctProvider != null) && (cctListeners != null) && (!cctListeners.isEmpty())) {\n                for (CCTProvider.Listener cctListener : cctListeners) {\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.log(Level.FINEST, \"Adding listener {0} to the provider {1}\", new Object[]{cctListener.getClass().getName(), cctProvider.getClass().getName()});\n                    }\n\n                    cctProvider.addListener(cctListener);\n                }\n            } else {\n                if (LOGGER.isLoggable(Level.WARNING)) {\n                    if (cctProvider == null) {\n                        LOGGER.warning(\"Could not find a CCT provider in lookup!\");\n                    } else if ((cctListeners == null) || (cctListeners.isEmpty())) {\n                        LOGGER.warning(\"Could not find listeners in lookup!\");\n                    }\n                }\n            }\n\n            for(SessionListener sl : Lookup.getDefault().lookupAll(SessionListener.class)) {\n                sl.onStartup(profilingSettings, project);\n            }\n\n            ProfilerClient client = getTargetAppRunner().getProfilerClient();\n\n            CCTResultsFilter filter = Lookup.getDefault().lookup(CCTResultsFilter.class);\n\n            if (filter != null) {\n                filter.reset(); // clean up the filter before reusing it\n                filter.setEvaluators(Lookup.getDefault().lookupAll(CCTResultsFilter.EvaluatorProvider.class));\n            }\n\n            // init context aware instances\n            FlatProfileBuilder fpb = Lookup.getDefault().lookup(FlatProfileBuilder.class);\n            TimeCollector tc = Lookup.getDefault().lookup(TimeCollector.class);\n            fpb.setContext(client, tc, filter);\n\n            Collection listeners = null;\n            switch (profilingSettings.getProfilingType()) {\n                case ProfilingSettings.PROFILE_CPU_PART:\n                case ProfilingSettings.PROFILE_CPU_JDBC:\n                case ProfilingSettings.PROFILE_CPU_ENTIRE:\n                case ProfilingSettings.PROFILE_CPU_SAMPLING: {\n                    listeners = Lookup.getDefault().lookupAll(CPUProfilingResultListener.class);\n\n                    for (Iterator iter = listeners.iterator(); iter.hasNext();) {\n                        CPUProfilingResultListener listener = (CPUProfilingResultListener) iter.next();\n                        ProfilingResultsDispatcher.getDefault().addListener(listener);\n                        listener.startup(getTargetAppRunner().getProfilerClient());\n                    }\n                    break;\n                }\n                case ProfilingSettings.PROFILE_MEMORY_ALLOCATIONS:\n                case ProfilingSettings.PROFILE_MEMORY_LIVENESS: {\n                    listeners = Lookup.getDefault().lookupAll(MemoryProfilingResultsListener.class);\n\n                    for (Iterator iter = listeners.iterator(); iter.hasNext();) {\n                        MemoryProfilingResultsListener listener = (MemoryProfilingResultsListener) iter.next();\n                        ProfilingResultsDispatcher.getDefault().addListener(listener);\n                        listener.startup(getTargetAppRunner().getProfilerClient());\n                    }\n                    break;\n                }\n                default: {\n                    listeners = Lookup.getDefault().lookupAll(LockProfilingResultListener.class);\n\n                    for (Iterator iter = listeners.iterator(); iter.hasNext();) {\n                        LockProfilingResultListener listener = (LockProfilingResultListener) iter.next();\n                        ProfilingResultsDispatcher.getDefault().addListener(listener);\n                        listener.startup(getTargetAppRunner().getProfilerClient());\n                    }\n                    \n                }\n            }\n            \n            ProfilingPointsProcessor ppp = getProfilingPointsManager();\n            if (ppp != null) ppp.init(getProfiledProject());\n\n            ProfilingResultsDispatcher.getDefault().startup(client);\n        }\n    }\n\n    // Used for killing an agent which could cause a collision on port\n    // Returns true if TERMINATE_TARGET_JVM was invoked on agent (not necessarily killed!), false if the agent is already profiling (port is used)\n    private boolean shutdownAgent(String host, int port) {\n        if (port == -1) return false; // invalid port\n        \n        Socket clientSocket = null;\n        ObjectOutputStream socketOut = null;\n        ObjectInputStream socketIn = null;\n\n        try {\n            clientSocket = new Socket(host, port);\n            clientSocket.setSoTimeout(100);\n            clientSocket.setTcpNoDelay(true); // Necessary at least on Solaris to avoid delays in e.g. readInt() etc.\n            socketOut = new ObjectOutputStream(clientSocket.getOutputStream());\n            socketIn = new ObjectInputStream(clientSocket.getInputStream());\n\n            WireIO wio = new WireIO(socketOut, socketIn);\n            wio.sendSimpleCommand(Command.TERMINATE_TARGET_JVM);\n\n            try {\n                Object o = wio.receiveCommandOrResponse();\n            } catch (Exception e) {\n            } // Throws SocketTimeoutException!\n\n            ProfilerLogger.warning(\">>> An existing Profiler agent listening on port \" + port\n                                   + \" was terminated to allow starting new profiling session on the same port.\"); // NOI18N\n\n            return true;\n        } catch (SocketTimeoutException e) { // port already in use\n\n            return false;\n        } catch (IOException e) {\n            return true;\n        } finally {\n            try {\n                if (socketIn != null) {\n                    socketIn.close();\n                }\n\n                if (socketOut != null) {\n                    socketOut.close();\n                }\n\n                if (clientSocket != null) {\n                    clientSocket.close();\n                }\n            } catch (IOException e) {\n                //        e.printStackTrace(System.err);\n            }\n        }\n    }\n\n    private void teardownDispatcher() {\n        synchronized (setupLock) {\n            ProfilingResultsDispatcher.getDefault().shutdown();\n\n            //      Collection<? extends CCTProvider> cctProviders = Lookup.getDefault().lookupAll(CCTProvider.class);\n            //      for(CCTProvider cctProvider : cctProviders) {\n            //        cctProvider.removeAllListeners();\n            //      }\n//            StatisticalModuleContainer statModulesContainer = Lookup.getDefault().lookup(StatisticalModuleContainer.class);\n//\n//            if (statModulesContainer != null) {\n//                statModulesContainer.removeAllModules();\n//            }\n\n            // deconfigure the profiler client\n            ProfilerClient client = getTargetAppRunner().getProfilerClient();\n            client.registerFlatProfileProvider(null);\n\n//            // deconfigure the marking engine\n//            MarkingEngine.getDefault().deconfigure();\n            for(SessionListener sl : Lookup.getDefault().lookupAll(SessionListener.class)) {\n                sl.onShutdown();\n            }\n            FlatProfileBuilder fpb = Lookup.getDefault().lookup(FlatProfileBuilder.class);\n            fpb.setContext(null, null, null);\n        }\n    }\n\n    private ProfilingPointsProcessor getProfilingPointsManager() {\n        return Lookup.getDefault().lookup(ProfilingPointsProcessor.class);\n    }\n    \n    private boolean waitForDeleteAgentFile(File agentFile) {\n        if (agentFile.delete()) {\n            return true;\n        }\n\n        for (int i = 0; i < 5; i++) {\n            if (agentFile.delete()) {\n                return true;\n            }\n\n            try {\n                Thread.sleep(50);\n            } catch (InterruptedException ex) {\n            }\n        }\n\n        return false;\n    }\n    \n    private static void logActionConfig(String actionTitle, ProfilingSettings ps, SessionSettings ss, AttachSettings as, GenericFilter f) {\n        assert actionTitle != null;\n        assert ps != null;\n        assert f != null;\n        \n        LOGGER.log(Level.CONFIG, \n            \"*** Profiler Action = {0}\\n\" + //NOI18N\n            \">>> Profiling Settings = \\n\" + // NOI18N\n            \"{1}\\n\" +// NOI18N\n            \">>> {2} Settings = \\n\" + // NOI18N\n            \"{3}\\n\" + // NOI18N\n            \">>> Instrumentation Filter = \\n\" + //NOI18N\n            \"{4}\", // NOI18N\n            new Object[]{\n                actionTitle,\n                ps.debug(),\n                (ss != null ? \"Session\" : (as != null ? \"Attach\" : null)),  // NOI18N\n                (ss != null ? ss.debug() : (as != null ? as.debug() : null)),                    \n                f.toString()\n            }\n        );\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/NpsResolver.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n\n<!DOCTYPE MIME-resolver PUBLIC \"-//NetBeans//DTD MIME Resolver 1.0//EN\" \"http://www.netbeans.org/dtds/mime-resolver-1_0.dtd\">\n<MIME-resolver>\n    <file>\n        <ext name=\"nps\"/>\n        <resolver mime=\"application/x-netbeans-profiler\"/>\n    </file>\n    <file>\n        <magic hex=\"6e4270526f46694c6552\"\n              mask=\"ffffffffffffffffffff\"/>\n        <resolver mime=\"application/x-netbeans-profiler\"/>\n    </file>\n\n    <file>\n        <ext name=\"npss\"/>\n        <resolver mime=\"application/x-netbeans-profiler\"/>\n    </file>\n    <file>\n        <magic hex=\"4e505353\"\n              mask=\"ffffffff\"/>\n        <resolver mime=\"application/x-netbeans-profiler\"/>\n    </file>\n</MIME-resolver>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/ProfilerModule.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport org.graalvm.visualvm.lib.profiler.actions.ResetResultsAction;\nimport org.openide.modules.ModuleInstall;\nimport org.openide.util.NbBundle;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\n\n\n/**\n * @author Tomas Hurka\n * @author Ian Formanek\n */\n@NbBundle.Messages({\n    \"ProfilerModule_CalibrationFailedMessage=Calibration failed.\\nPlease check your setup and run the calibration again.\",\n    \"ProfilerModule_ExitingFromProfileMessage=Profiling session is currently in progress\\nDo you want to stop the current session and exit the IDE?\",\n    \"ProfilerModule_QuestionDialogCaption=Question\",\n    \"ProfilerModule_ExitingFromAttachMessage=Profiling session is currently in progress\\nDo you want to detach from the target application and exit the IDE?\"\n})\npublic final class ProfilerModule extends ModuleInstall {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final String LIBS_DIR = \"lib\"; //NOI18N\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Called when the IDE is about to exit. The default implementation returns <code>true</code>.\n     * The module may cancel the exit if it is not prepared to be shut down.\n     *\n     * @return <code>true</code> if it is ok to exit the IDE\n     */\n    public boolean closing() {\n        if (!NetBeansProfiler.isInitialized()) return true;\n        final int state = Profiler.getDefault().getProfilingState();\n        final int mode = Profiler.getDefault().getProfilingMode();\n\n        if ((state == Profiler.PROFILING_PAUSED) || (state == Profiler.PROFILING_RUNNING)) {\n            if (mode == Profiler.MODE_PROFILE) {\n                if (!ProfilerDialogs.displayConfirmation(\n                        Bundle.ProfilerModule_ExitingFromProfileMessage(), \n                        Bundle.ProfilerModule_QuestionDialogCaption())) {\n                    return false;\n                }\n\n                Profiler.getDefault().stopApp();\n            } else {\n                if (!ProfilerDialogs.displayConfirmation(\n                        Bundle.ProfilerModule_ExitingFromAttachMessage(), \n                        Bundle.ProfilerModule_QuestionDialogCaption())) {\n                    return false;\n                }\n\n                Profiler.getDefault().detachFromApp();\n            }\n        }\n\n        // cleanup before exiting the IDE, always returns true\n//        if (LiveResultsWindow.hasDefault()) {\n//            LiveResultsWindow.getDefault().ideClosing();\n//        }\n\n        return true;\n    }\n\n    /**\n     * Called when an already-installed module is restored (during IDE startup).\n     * Should perform whatever initializations are required.\n     * <p>Note that it is possible for module code to be run before this method\n     * is called, and that code must be ready nonetheless. For example, data loaders\n     * might be asked to recognize a file before the module is \"restored\". For this\n     * reason, but more importantly for general performance reasons, modules should\n     * avoid doing anything here that is not strictly necessary - often by moving\n     * initialization code into the place where the initialization is actually first\n     * required (if ever). This method should serve as a place for tasks that must\n     * be run once during every startup, and that cannot reasonably be put elsewhere.\n     * <p>Basic programmatic services are available to the module at this stage -\n     * for example, its class loader is ready for general use, any objects registered\n     * declaratively to lookup (e.g. system options or services) are ready to be\n     * queried, and so on.\n     */\n    public void restored() {\n        super.restored();\n        MiscUtils.setVerbosePrint(); // for EA, we want as many details in the log file as possible to be able to resolve user problems\n                                     // Settings have to be load on startup at least for the following calibration (saved calibration data loading) stuff\n                                     // to run correctly - it needs to know the saved JVM executable file/version to run.\n\n        MiscUtils.deleteHeapTempFiles();\n    }\n\n    /**\n     * Called when the module is uninstalled (from a running IDE).\n     * Should remove whatever functionality from the IDE that it had registered.\n     */\n    public void uninstalled() {\n        try {\n            SwingUtilities.invokeAndWait(new Runnable() {\n                    public void run() {\n                        // stop or detach from any profiling in progress\n                        final int state = Profiler.getDefault().getProfilingState();\n                        final int mode = Profiler.getDefault().getProfilingMode();\n\n                        if ((state == Profiler.PROFILING_PAUSED) || (state == Profiler.PROFILING_RUNNING)) {\n                            if (mode == Profiler.MODE_PROFILE) {\n                                Profiler.getDefault().stopApp();\n                            } else {\n                                Profiler.getDefault().detachFromApp();\n                            }\n                        }\n\n// NB is performing IDE reset after uninstall anyway; no need to close the windows explicitly\n//                        // force closing of all windows\n//                        ProfilerControlPanel2.closeIfOpened();\n//                        TelemetryOverviewPanel.closeIfOpened();\n//                        LiveResultsWindow.closeIfOpened();\n//                        TelemetryWindow.closeIfOpened();\n//                        ThreadsWindow.closeIfOpened();\n//                        SnapshotResultsWindow.closeAllWindows();\n//                        ProfilingPointsWindow.closeIfOpened();\n\n                        // perform any shutdown\n                        ((NetBeansProfiler) Profiler.getDefault()).shutdown();\n\n                        ResetResultsAction.getInstance().actionPerformed(null); // cleanup client data\n                    }\n                });\n        } catch (Exception e) {\n            ProfilerLogger.log(e);\n        }\n\n        // proceed with uninstall\n        super.uninstalled();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/ProfilerTopComponent.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.KeyboardFocusManager;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.ui.UIConstants;\nimport org.openide.windows.TopComponent;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ProfilerTopComponent extends TopComponent {\n\n    public static final String RECENT_FILE_KEY = \"nb.recent.file.path\"; // NOI18N\n\n    private Component lastFocusOwner;\n\n    private final PropertyChangeListener focusListener = new PropertyChangeListener() {\n        public void propertyChange(PropertyChangeEvent evt) {\n            Component c = evt.getNewValue() instanceof Component ?\n                    (Component)evt.getNewValue() : null;\n            processFocusedComponent(c);\n        }\n        private void processFocusedComponent(Component c) {\n            Component cc = c;\n            while (c != null) {\n                if (c == ProfilerTopComponent.this) {\n                    lastFocusOwner = cc;\n                    return;\n                }\n                c = c.getParent();\n            }\n        }\n    };\n\n    protected void componentActivated() {\n        super.componentActivated();\n        if (lastFocusOwner != null) {\n            lastFocusOwner.requestFocus();\n        } else {\n            Component defaultFocusOwner = defaultFocusOwner();\n            if (defaultFocusOwner != null) defaultFocusOwner.requestFocus();\n        }\n        KeyboardFocusManager.getCurrentKeyboardFocusManager().\n                addPropertyChangeListener(\"focusOwner\", focusListener); // NOI18N\n    }\n\n    protected void componentDeactivated() {\n        KeyboardFocusManager.getCurrentKeyboardFocusManager().\n                removePropertyChangeListener(\"focusOwner\", focusListener); // NOI18N\n        super.componentDeactivated();\n    }\n    \n    protected Component defaultFocusOwner() {\n        return null;\n    }\n    \n    public Dimension getMinimumSize() {\n        return new Dimension(0, 0);\n    }\n    \n    public void paintComponent(Graphics g) {\n        Color background = UIManager.getColor(UIConstants.PROFILER_PANELS_BACKGROUND);\n        if (background != null) {\n            g.setColor(background);\n            Insets i = getInsets();\n            g.fillRect(i.left, i.top, getWidth() - i.left - i.right, getHeight() - i.top - i.bottom);\n        } else {\n            super.paintComponent(g);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/ProfilingMonitor.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.client.MonitoredData;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.monitor.VMTelemetryDataManager;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadsDataManager;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.openide.util.NbBundle;\n\n\n/**\n * This class provides thread for periodically processing monitoring data from profiled application (feeding them to\n * telemetry and threads data managers) as well as I/O redirection.\n *\n * @author Tomas Hurka\n * @author Ian Formanek\n */\npublic final class ProfilingMonitor {\n\n    @NbBundle.Messages({\n        \"ProfilingMonitor_OomeMsg=<html><b>Not enough memory to store profiling data.</b><br><br>To avoid this error please increase the -Xmx value<br>in the etc/visualvm.conf file in VisualVM directory.</html>\"\n    })\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    final class UpdateThread extends Thread {\n        //~ Static fields/initializers -------------------------------------------------------------------------------------------\n\n        private static final int UPDATE_INTERVAL = 1200;\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private TargetAppRunner runner;\n        private ThreadsDataManager threadsDataManager;\n        private VMTelemetryDataManager vmTelemetryManager;\n//        private boolean doUpdateLiveResults;\n        private boolean keepRunning = true;\n        private volatile boolean oomeNotified;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        UpdateThread() {\n            super(\"Profiler Monitor\"); // NOI18N\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void monitor(final TargetAppRunner runner) {\n            oomeNotified = false;\n            this.runner = runner;\n            this.threadsDataManager = Profiler.getDefault().getThreadsManager();\n            this.vmTelemetryManager = Profiler.getDefault().getVMTelemetryManager();\n\n            if (runner != null) {\n                this.vmTelemetryManager.maxHeapSize = runner.getProfilingSessionStatus().maxHeapSize;\n            }\n        }\n\n        public void run() {\n            while (keepRunning) { // Main loop\n\n                try {\n                    if (runner != null) {\n//                        ProfilerControlPanel2.getDefault().updateStatus(); // TODO: move elsewhere\n\n                        final MonitoredData md = runner.getProfilerClient().getMonitoredData();\n\n                        if (md != null) {\n                            SwingUtilities.invokeAndWait(new Runnable() {\n                                    public void run() {\n                                        try {\n                                            setServerState(md.getServerState());\n                                            setServerProgress(md.getServerProgress());\n                                            \n                                            threadsDataManager.processData(md);\n                                            vmTelemetryManager.processData(md);\n\n                                            // ---------------------------------------------------------\n                                            // Temporary workaround to refresh profiling points when LiveResultsWindow is not refreshing\n                                            // TODO: move this code to a separate class performing the update if necessary\n//                                            final Profiler profiler = Profiler.getDefault();\n//                                            final ProfilerClient client = profiler.getTargetAppRunner().getProfilerClient();\n//                                            final int instrType = client.getCurrentInstrType();\n//                                            if ((NetBeansProfiler.getDefaultNB().processesProfilingPoints())\n//                                                && (!doUpdateLiveResults /*|| !LiveResultsWindow.hasDefault()*/)) {\n//                                                ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n//                                                        public void run() {\n//                                                            try {\n//                                                                if (instrType != ProfilerEngineSettings.INSTR_CODE_REGION) {\n//                                                                    client.forceObtainedResultsDump(true);\n//                                                                }\n//                                                            } catch (Exception e /*ClientUtils.TargetAppOrVMTerminated targetAppOrVMTerminated*/) {\n//                                                            }\n//                                                        }\n//                                                    });\n//\n//                                            }\n//\n//                                            // ---------------------------------------------------------\n//\n//                                            // Let results updating happen every other cycle (i.e. every ~2.5 sec) to allow the user to understand something before it disappears :-)\n////                                            if (doUpdateLiveResults && LiveResultsWindow.hasDefault()) {\n////                                                LiveResultsWindow.getDefault().refreshLiveResults();\n////                                            }\n//\n//                                            doUpdateLiveResults = !doUpdateLiveResults;\n                                        } catch (Exception e) {\n                                            Profiler.getDefault().notifyException(Profiler.EXCEPTION, e);\n                                        } catch (OutOfMemoryError e) {\n                                            if (!oomeNotified) {\n                                                oomeNotified = true;\n                                                ProfilerDialogs.displayError(Bundle.ProfilingMonitor_OomeMsg());\n                                            }\n                                        }\n                                    }\n                                });\n                        } else {\n                            NetBeansProfiler.getDefaultNB().checkAndUpdateState();\n                            runner = null; // stop monitoring, the TA must have terminated\n                        }\n                    }\n                } catch (Throwable t) {\n                    // prevent thread from dying on exceptions from JFluid engine\n                    if (t instanceof ThreadDeath) {\n                        throw (ThreadDeath) t;\n                    }\n                }\n\n                try {\n                    sleep(UPDATE_INTERVAL);\n                } catch (InterruptedException e) {\n                    break;\n                }\n            }\n        }\n\n        private void stopThread() {\n            keepRunning = false;\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n    static final String PROPERTY_SERVER_STATE = \"serverState\";\n    static final String PROPERTY_SERVER_PROGRESS = \"serverProgress\";\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private UpdateThread monitorThread;\n    private boolean updateThreadStarted = false;\n    private int serverState = CommonConstants.SERVER_RUNNING;\n    private int serverProgress = CommonConstants.SERVER_PROGRESS_INDETERMINATE;\n    private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Initializes the Form\n     */\n    public ProfilingMonitor() {\n        monitorThread = new UpdateThread();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void monitorVM(final TargetAppRunner runner) {\n        //set server state before first MONITORED_NUMBERS response arrives\n        setServerState(CommonConstants.SERVER_INITIALIZING);\n        setServerProgress(CommonConstants.SERVER_PROGRESS_INDETERMINATE);\n        if (!updateThreadStarted) {\n            updateThreadStarted = true;\n            monitorThread.start();\n        }\n\n        monitorThread.monitor(runner);\n    }\n\n    public void stopDisplayingVM() {\n        if (monitorThread != null) {\n            monitorThread.monitor(null);\n        }\n    }\n\n    public void stopUpdateThread() {\n        if (monitorThread != null) {\n            monitorThread.stopThread();\n            monitorThread = null;\n        }\n    }\n\n    private void setServerState(int serverState) {\n        if(this.serverState != serverState) {\n            int oldValue = this.serverState;\n            this.serverState = serverState;\n            propertyChangeSupport.firePropertyChange(PROPERTY_SERVER_STATE, oldValue, serverState);\n        }\n    }\n\n    int getServerState() {\n        return serverState;\n    }\n\n    private void setServerProgress(int serverProgress) {\n        if(this.serverProgress != serverProgress)\n        {\n            int oldValue = this.serverProgress;\n            this.serverProgress = serverProgress;\n            propertyChangeSupport.firePropertyChange(PROPERTY_SERVER_PROGRESS, oldValue, serverProgress);\n        }\n    }\n\n    int getServerProgress() {\n        return serverProgress;\n    }\n\n    void addPropertyChangeListener(PropertyChangeListener listener) {\n        propertyChangeSupport.addPropertyChangeListener(listener);\n    }\n\n    void removePropertyChangeListener(PropertyChangeListener listener) {\n        propertyChangeSupport.addPropertyChangeListener(listener);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/ResultsListener.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\n\n/** A listener for results manager changes\n *\n * @author Tomas Hurka\n * @author Ian Formanek\n */\npublic interface ResultsListener {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /** Called each time profiling results will become available for the first time using current instrumentation */\n    public void resultsAvailable();\n\n    /** Called when collected results buffer has been reset */\n    public void resultsReset();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/ResultsManager.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\nimport java.awt.Cursor;\nimport java.awt.Window;\nimport java.io.*;\nimport java.nio.file.Files;\nimport java.nio.file.StandardCopyOption;\nimport java.util.*;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.JFileChooser;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.CommonUtils;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.ProfilingResultsDispatcher;\nimport org.graalvm.visualvm.lib.jfluid.results.ResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.AllocMemoryResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.AllocMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.LivenessMemoryResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.LivenessMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryCCTProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsDiff;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerStorage;\nimport org.graalvm.visualvm.lib.profiler.utilities.ProfilerUtils;\nimport org.openide.cookies.OpenCookie;\nimport org.openide.filesystems.FileLock;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.loaders.DataObject;\nimport org.openide.loaders.DataObjectNotFoundException;\nimport org.openide.util.Exceptions;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.util.lookup.ServiceProviders;\nimport org.openide.windows.WindowManager;\n\n\n/** An manager for management/notifications about obtainer profiling results.\n *\n * @author Tomas Hurka\n * @author Ian Formanek\n */\n@NbBundle.Messages({\n    \"ResultsManager_SnapshotSaveFailedMsg=Failed to save snapshot: {0}\",\n    \"ResultsManager_SnapshotCreateFailedMsg=Failed to create snapshot file: {0}\",\n    \"ResultsManager_ProfiledAppTerminatedMsg=Failed to obtain results snapshot. The profiled application terminated.\",\n    \"ResultsManager_DataNotAvailableMsg=Failed to obtain results snapshot. Data is not available yet.\",\n    \"ResultsManager_OutOfMemoryMsg=Too much data collected - the profiler ran out of memory.\\n\\nCollected profiling data has been deleted and profiling resumed.\\nTo avoid this error please increase the -Xmx value\\nin the etc/visualvm.conf file in VisualVM directory\\nor decrease the amount of detail in profiling settings.\",\n    \"ResultsManager_SnapshotDeleteFailedMsg=Failed to delete the snapshot file: {0}\",\n    \"ResultsManager_CantFindSnapshotLocationMsg=Cannot find default location for snapshot in project: {0}\",\n    \"ResultsManager_SnapshotCreateInProjectFailedMsg=Failed to create snapshot file in project: {0}\",\n    \"ResultsManager_SnapshotLoadFailed=Error while loading snapshot: {0}\",\n    \"ResultsManager_SnapshotsLoadFailedMsg=Loading snapshots failed.\",\n    \"ResultsManager_ObtainSavedSnapshotsFailedMsg=Failed to obtain list of saved snaphshots for project: {0}\",\n    \"ResultsManager_SelectDirDialogCaption=Select Target Directory\",\n    \"ResultsManager_SaveButtonName=Save\",\n    \"ResultsManager_OverwriteFileDialogCaption=Overwrite Existing File?\",\n    \"ResultsManager_OverwriteFileDialogMsg=The target folder already contains file {0}\\n Do you want to overwrite this file?\",\n    \"ResultsManager_FileDeleteFailedMsg=Cannot delete the existing file: {0}\",\n    \"ResultsManager_SnapshotExportFailedMsg=<html><b>Failed to export snapshot:</b><br><br>{0}</html>\",\n    \"ResultsManager_ExportSnapshotData=Export Snapshot Data\",\n    \"ResultsManager_SelectFileOrDirDialogCaption=Select File or Directory\",\n    \"ResultsManager_ProfilerSnapshotFileFilter=Profiler Snapshot File (*.{0})\",\n    \"ResultsManager_ProfilerHeapdumpFileFilter=Heap Dump File (*.{0})\",\n    \"ResultsManager_OutOfMemorySavingMsg=<html><b>Not enough memory to save the snapshot.</b><br><br>To avoid this error please increase the -Xmx value<br>in the etc/visualvm.conf file in VisualVM directory.</html>\",\n    \"ResultsManager_CannotCompareSnapshotsMsg=<html><b>Cannot compare snapshots:</b><br><br>  {0}<br>  {1}<br><br>Make sure that both snaphots are the same type.</html>\",\n    \"ResultsManager_DirectoryDoesntExistCaption=Selected Directory Does Not Exist\",\n    \"ResultsManager_DirectoryDoesntExistMsg=The directory you have selected does not exist.\\nDo you want to create the directory?\",\n    \"ResultsManager_SnapshotLoadFailedMsg=<html><b>Snapshot {0} failed to load.</b><br><br>{1}</html>\",\n    \"ResultsManager_CannotOpenSnapshotMsg=<html><b>Cannot open profiler snapshot.</b><br><br>Attempting to open null snapshot.<br>Check the logfile for details.</html>\",\n    \"ResultsManager_CpuSnapshotDisplayName=cpu: {0}\",\n    \"ResultsManager_MemorySnapshotDisplayName=mem: {0}\",\n    \"ResultsManager_HeapSnapshotDisplayName=heap: {0}\",\n    \"MSG_SavingSnapshots=Saving Snapshots\",\n    \"MSG_SavingSnapshot=Saving Snapshot\",\n    \"ResultsManager_CaptionWarning=Warning\",\n    \"ResultsManager_DifferentObjectSize=<html><b>Object sizes are different.</b><br><br>Size of the same objects differ for each snapshot and their comparison is invalid.<br>The snapshots have likely been taken on different architectures (32bit vs. 64bit).</html>\"\n})\npublic final class ResultsManager {\n    final private static Logger LOGGER = Logger.getLogger(ResultsManager.class.getName());\n    \n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    //  /**\n    //   * Resets collected results (either memory or CPU, depending on current mode).\n    //   */\n    //  public void resetCollectors() {\n    //    reset();\n    //    int instr = Profiler.getDefault().getTargetAppRunner().getProfilerClient().getCurrentInstrType();\n    //    ProfilingResultsDispatcher.getDefault().reset();\n    //    if (instr == CommonConstants.INSTR_RECURSIVE_FULL || instr == CommonConstants.INSTR_RECURSIVE_SAMPLED) {\n    //      // TODO reset cpu profiling results collectors\n    ////      CPUCallGraphBuilder.resetCollectors();\n    //    } else if (instr == CommonConstants.INSTR_OBJECT_ALLOCATIONS || instr == CommonConstants.INSTR_OBJECT_LIVENESS) {\n    //      MemoryCallGraphBuilder mcgb = Profiler.getDefault().getTargetAppRunner().getProfilerClient().getMemoryCallGraphBuilder();\n    //      mcgb.resetCollectors();\n    //    }\n    //    fireResultsReset();\n    //  }\n    static class SelectedFile {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        FileObject folder;\n        String fileExt;\n        String fileName;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        SelectedFile(FileObject folder, String fileName, String fileExt) {\n            this.folder = folder;\n            this.fileName = fileName;\n            this.fileExt = fileExt;\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n    public static final String SNAPSHOT_EXTENSION = \"nps\"; // NOI18N\n    public static final String HEAPDUMP_EXTENSION = \"hprof\"; // NOI18N\n    /* see  org.netbeans.modules.sampler.SampleOutputStream.FILE_EXT */ \n    public static final String STACKTRACES_SNAPSHOT_EXTENSION = \"npss\"; // NOI18N \n\n    static final String HEAPDUMP_PREFIX = \"heapdump-\";  // NOI18N // should differ from generated OOME heapdumps not to be detected as OOME\n    private static final String SNAPSHOT_PREFIX = \"snapshot-\";  // NOI18N\n    private static final long MINIMAL_TIMESTAMP = 946684800000L; // Sat, 01 Jan 2000 00:00:00 GMT in milliseconds since 01 Jan 1970\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ArrayList<LoadedSnapshot> loadedSnapshots = new ArrayList<>();\n    private File exportDir;\n    private HashMap<FileObject, ProfilingSettings> settingsCache = new HashMap<>();\n    private HashMap<FileObject, Integer> typeCache = new HashMap<>();\n    private Window mainWindow;\n    private boolean resultsAvailable = false;\n    \n    private Lookup.Result<SnapshotsListener> snapshotListeners;\n    private Lookup.Result<ResultsListener> resultsListeners;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n    private ResultsManager() {\n        Lookup l = Lookup.getDefault();\n        snapshotListeners = l.lookupResult(SnapshotsListener.class);\n        resultsListeners = l.lookupResult(ResultsListener.class);\n    }\n\n    private static class Singleton {\n        final private static ResultsManager INSTANCE = new ResultsManager();\n    }\n    \n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static ResultsManager getDefault() {\n        return Singleton.INSTANCE;\n    }\n\n    public String getDefaultSnapshotFileName(LoadedSnapshot ls) {\n        return SNAPSHOT_PREFIX + ls.getSnapshot().getTimeTaken();\n    }\n    \n    public String getSnapshotDisplayName(LoadedSnapshot ls) {\n        String name = ls.getFile() == null ? null : ls.getFile().getName();\n        if (name == null) {\n            name = getDefaultSnapshotFileName(ls);\n        } else {\n            int dotIndex = name.lastIndexOf('.'); // NOI18N\n            if (dotIndex > 0 && dotIndex <= name.length() - 2)\n                name = name.substring(0, dotIndex);\n        }\n        return getSnapshotDisplayName(name, ls.getType());\n    }\n        \n    public String getSnapshotDisplayName(String fileName, int snapshotType) {\n        String displayName;\n        if (fileName.startsWith(SNAPSHOT_PREFIX)) {\n            String time = fileName.substring(SNAPSHOT_PREFIX.length(), fileName.length());\n            try {\n                long timeStamp = Long.parseLong(time);\n                if (timeStamp > MINIMAL_TIMESTAMP) {\n                    displayName = StringUtils.formatUserDate(new Date(timeStamp));\n                } else {\n                    // file name is probably customized\n                    displayName = fileName;                    \n                }\n            } catch (NumberFormatException e) {\n                // file name is probably customized\n                displayName = fileName;\n            }\n        } else {\n            displayName = fileName;\n        }\n//        switch (snapshotType) {\n//            case LoadedSnapshot.SNAPSHOT_TYPE_CPU:\n//                return Bundle.ResultsManager_CpuSnapshotDisplayName(displayName);\n//            case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_ALLOCATIONS:\n//            case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_LIVENESS:\n//            case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_SAMPLED:\n//                return Bundle.ResultsManager_MemorySnapshotDisplayName(displayName);\n//            default:\n//                return displayName;\n//        }\n        return displayName;\n    }\n    \n    public String getDefaultHeapDumpFileName(long time) {\n        return HEAPDUMP_PREFIX + time;\n    }\n\n    public String getHeapDumpDisplayName(String fileName) {\n        String displayName;\n        if (fileName.startsWith(HEAPDUMP_PREFIX)) {\n            String time = fileName.substring(HEAPDUMP_PREFIX.length(), fileName.length());\n            try {\n                long timeStamp = Long.parseLong(time);\n                if (timeStamp > MINIMAL_TIMESTAMP) {\n                    displayName = StringUtils.formatUserDate(new Date(timeStamp));\n                } else {\n                    // file name is probably customized\n                    displayName = fileName;                    \n                }\n            } catch (NumberFormatException e) {\n                // file name is probably customized\n                displayName = fileName;\n            }\n        } else {\n            displayName = fileName;\n        }\n        \n        return displayName;\n//        return Bundle.ResultsManager_HeapSnapshotDisplayName(displayName);\n    }\n\n    public LoadedSnapshot[] getLoadedSnapshots() {\n        return loadedSnapshots.toArray(new LoadedSnapshot[0]);\n    }\n\n    public LoadedSnapshot getSnapshotFromFileObject(FileObject fo) {\n        LoadedSnapshot ls = findAlreadyLoadedSnapshot(fo);\n\n        if (ls != null) {\n            return ls;\n        }\n\n        try {\n            return loadSnapshotFromFileObject(fo);\n        } catch (IOException e) {\n            LOGGER.log(Level.SEVERE, null, e);\n\n            return null;\n        }\n    }\n\n    public ProfilingSettings getSnapshotSettings(FileObject fo) {\n        ProfilingSettings settings = settingsCache.get(fo);\n\n        if ((settings == null) && !settingsCache.containsKey(fo)) {\n            settings = readSettingsFromFile(fo);\n            settingsCache.put(fo, settings);\n        }\n\n        return settings;\n    }\n\n    public int getSnapshotType(FileObject fo) {\n        Integer type = typeCache.get(fo);\n\n        if (type == null) {\n            type = Integer.valueOf(readTypeFromFile(fo));\n            typeCache.put(fo, type);\n        }\n\n        return type.intValue();\n    }\n\n    @ServiceProviders({@ServiceProvider(service=CPUCCTProvider.Listener.class), @ServiceProvider(service=MemoryCCTProvider.Listener.class)})\n    public static final class ResultsMonitor implements CPUCCTProvider.Listener, MemoryCCTProvider.Listener {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void cctEstablished(RuntimeCCTNode runtimeCCTNode, boolean empty) {\n            if (!empty) {\n                ResultsManager rm = getDefault();\n                if (!rm.resultsAvailable() && !isSomeResultsAvailable()) {\n                    return;\n                }\n                rm.resultsBecameAvailable();\n            }\n        }\n\n        public void cctReset() {\n            getDefault().resultsReset();\n        }\n        \n        private boolean isSomeResultsAvailable() {\n            // check that we have data for snapshot, CPU profiling can have non-empty\n            // batch, but this batch can contain only marker methods\n            Profiler profiler = Profiler.getDefault();\n            ProfilerClient client = profiler.getTargetAppRunner().getProfilerClient();\n            int profilingType = profiler.getLastProfilingSettings().getProfilingType();\n\n            if (profilingType == ProfilingSettings.PROFILE_CPU_ENTIRE ||\n                profilingType == ProfilingSettings.PROFILE_CPU_PART) {\n                try {\n                    // construct snapshot and check that it has some data\n                    client.getCPUProfilingResultsSnapshot(false);\n                } catch (CPUResultsSnapshot.NoDataAvailableException ex) {\n                    // we don't have data for snapshot\n                    return false;\n                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                    // target VM is down\n                    return false;\n                }\n            }\n            return true;\n        }\n    }\n\n    public void closeSnapshot(LoadedSnapshot ls) {\n        if (ls != null) {\n            loadedSnapshots.remove(ls);\n            fireSnapshotRemoved(ls);\n        }\n    }\n\n    public void compareSnapshots(FileObject snapshot1FO, FileObject snapshot2FO) {\n        LoadedSnapshot s1 = null;\n        LoadedSnapshot s2 = null;\n        \n        FileObject snapshotFO = snapshot1FO;\n\n        try {\n            s1 = findAlreadyLoadedSnapshot(snapshot1FO);\n\n            if (s1 == null) {\n                s1 = loadSnapshotImpl(snapshot1FO);\n            }\n            \n            snapshotFO = snapshot2FO;\n\n            s2 = findAlreadyLoadedSnapshot(snapshot2FO);\n\n            if (s2 == null) {\n                s2 = loadSnapshotFromFileObject(snapshot2FO);\n            }\n        } catch (Exception e) {\n            LOGGER.log(Level.INFO, Bundle.ResultsManager_SnapshotLoadFailed(snapshotFO.getPath()), e);\n            ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotLoadFailedMsg(snapshotFO.getNameExt(), e.getMessage()));\n\n            return;\n        }\n\n        if ((s1 != null) && (s2 != null)) {\n            compareSnapshots(s1, s2);\n        } else {\n            ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotsLoadFailedMsg());\n        }\n    }\n    \n    public ResultsSnapshot createDiffSnapshot(LoadedSnapshot s1, LoadedSnapshot s2) {\n        ResultsSnapshot snap1 = s1.getSnapshot();\n        ResultsSnapshot snap2 = s2.getSnapshot();\n        ResultsSnapshot diff = null;\n\n        if (snap1 instanceof SampledMemoryResultsSnapshot && snap2 instanceof SampledMemoryResultsSnapshot) {\n            SampledMemoryResultsSnapshot sn1 = (SampledMemoryResultsSnapshot)snap1;\n            SampledMemoryResultsSnapshot sn2 = (SampledMemoryResultsSnapshot)snap2;\n            checkObjectSizes(sn1.getClassNames(), sn1.getObjectsCounts(), sn1.getObjectsSizePerClass(), 1,\n                             sn2.getClassNames(), sn2.getObjectsCounts(), sn2.getObjectsSizePerClass(), 1);\n            diff = new SampledMemoryResultsDiff((SampledMemoryResultsSnapshot)snap1,\n                                                (SampledMemoryResultsSnapshot)snap2);\n        } else if (snap1 instanceof AllocMemoryResultsSnapshot && snap2 instanceof AllocMemoryResultsSnapshot) {\n            AllocMemoryResultsSnapshot sn1 = (AllocMemoryResultsSnapshot)snap1;\n            AllocMemoryResultsSnapshot sn2 = (AllocMemoryResultsSnapshot)snap2;\n// Note: instrumented allocations not compared because of #236363\n//            ProfilingSettings sn1s = s1.getSettings();\n//            ProfilingSettings sn2s = s2.getSettings();\n//            checkObjectSizes(sn1.getClassNames(), sn1.getObjectsCounts(), sn1.getObjectsSizePerClass(), sn1s.getAllocTrackEvery(),\n//                             sn2.getClassNames(), sn2.getObjectsCounts(), sn2.getObjectsSizePerClass(), sn2s.getAllocTrackEvery());\n            checkObjectSizes(sn1.getClassNames(), sn1.getObjectsCounts(), sn1.getObjectsSizePerClass(), Integer.MAX_VALUE,\n                             sn2.getClassNames(), sn2.getObjectsCounts(), sn2.getObjectsSizePerClass(), Integer.MAX_VALUE);\n            diff = new AllocMemoryResultsDiff((AllocMemoryResultsSnapshot)snap1,\n                                              (AllocMemoryResultsSnapshot)snap2);\n        } else if (snap1 instanceof LivenessMemoryResultsSnapshot && snap2 instanceof LivenessMemoryResultsSnapshot) {\n            LivenessMemoryResultsSnapshot sn1 = (LivenessMemoryResultsSnapshot)snap1;\n            LivenessMemoryResultsSnapshot sn2 = (LivenessMemoryResultsSnapshot)snap2;\n// Note: using track each 1 object to prevent unnecessary division, the data are always correct for liveness results\n//            ProfilingSettings sn1s = s1.getSettings();\n//            ProfilingSettings sn2s = s2.getSettings();\n//            checkObjectSizes(sn1.getClassNames(), sn1.getNTrackedLiveObjects(), sn1.getTrackedLiveObjectsSize(), sn1s.getAllocTrackEvery(),\n//                             sn2.getClassNames(), sn2.getNTrackedLiveObjects(), sn2.getTrackedLiveObjectsSize(), sn2s.getAllocTrackEvery());\n            checkObjectSizes(sn1.getClassNames(), sn1.getNTrackedLiveObjects(), sn1.getTrackedLiveObjectsSize(), 1,\n                             sn2.getClassNames(), sn2.getNTrackedLiveObjects(), sn2.getTrackedLiveObjectsSize(), 1);\n            diff = new LivenessMemoryResultsDiff((LivenessMemoryResultsSnapshot)snap1,\n                                                 (LivenessMemoryResultsSnapshot)snap2);\n        } else if (snap1 instanceof CPUResultsSnapshot && snap2 instanceof CPUResultsSnapshot) {\n            diff = new CPUResultsDiff((CPUResultsSnapshot)snap1, (CPUResultsSnapshot)snap2);\n        } else if (snap1 instanceof JdbcResultsSnapshot && snap2 instanceof JdbcResultsSnapshot) {\n            diff = new JdbcResultsDiff((JdbcResultsSnapshot)snap1, (JdbcResultsSnapshot)snap2);\n        }\n        \n        return diff;\n    }\n\n    public void compareSnapshots(final LoadedSnapshot s1, final LoadedSnapshot s2) {\n        CommonUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                SnapshotResultsWindow srw = SnapshotResultsWindow.get(s1, 0, false);\n                if (!srw.setRefSnapshot(s2)) {\n                    ProfilerDialogs.displayError(Bundle.ResultsManager_CannotCompareSnapshotsMsg(\n                                                 s1.getFile().getName(), s2.getFile().getName()));\n                } else {\n                    srw.open();\n                    srw.requestActive();\n                }\n            }\n        });\n    }\n    \n    static void checkObjectSizes(String[] names1, int[] counts1, long[] sizes1, int n1,\n                                 String[] names2, int[] counts2, long[] sizes2, int n2) {\n        String obj1 = \"java.lang.Object\"; // NOI18N // Sampled snapshots\n        String obj2 = \"java/lang/Object\"; // NOI18N // Instrumented snapshots\n        \n        int idx1 = -1;\n        for (int i = 0; i < names1.length; i++)\n            if (obj1.equals(names1[i]) || obj2.equals(names1[i])) {\n                idx1 = i;\n                break;\n            }\n        if (idx1 == -1 || counts1[idx1] == 0) return; // Should not happen\n        \n        int idx2 = -1;\n        for (int i = 0; i < names2.length; i++)\n            if (obj1.equals(names2[i]) || obj2.equals(names2[i])) {\n                idx2 = i;\n                break;\n            }\n        if (idx2 == -1 || counts2[idx2] == 0) return; // Should not happen\n        \n        // Note: instrumented allocations not compared because of #236363\n        long objsize1 = n1 == 1 ? sizes1[idx1] / counts1[idx1] : 0;\n        long objsize2 = n2 == 1 ? sizes2[idx2] / counts2[idx2] : 0;\n        \n        if (objsize1 != objsize2)\n            ProfilerDialogs.displayWarningDNSA(Bundle.ResultsManager_DifferentObjectSize(),\n                                               Bundle.ResultsManager_CaptionWarning(), null,\n                                               \"ResultsManager.checkObjectSizes\", false); // NOI18N\n    }\n\n    public void deleteSnapshot(FileObject snapshotFile) {\n        LoadedSnapshot ls = findLoadedSnapshot(FileUtil.toFile(snapshotFile));\n\n        try {\n            snapshotFile.delete();\n        } catch (IOException e) {\n            LOGGER.log(Level.SEVERE, Bundle.ResultsManager_SnapshotDeleteFailedMsg(e.getMessage()), e);\n\n            return; // do not proceed with removing the snapshot from internal structures\n        }\n\n        if (ls != null) { // if the snapshot has been loaded, remove the internal structures as well\n            loadedSnapshots.remove(ls);\n            fireSnapshotRemoved(ls);\n        }\n    }\n\n    public void exportSnapshots(final FileObject[] selectedSnapshots) {\n        assert (selectedSnapshots != null);\n        assert (selectedSnapshots.length > 0);\n\n        final String[] fileName = new String[1], fileExt = new String[1];\n        final FileObject[] dir = new FileObject[1];\n        if (selectedSnapshots.length == 1) {\n            SelectedFile sf = selectSnapshotTargetFile(selectedSnapshots[0].getName(),\n                                selectedSnapshots[0].getExt().equals(HEAPDUMP_EXTENSION));\n\n            if ((sf != null) && checkFileExists(sf)) {\n                fileName[0] = sf.fileName;\n                fileExt[0] = sf.fileExt;\n                dir[0] = sf.folder;\n            } else { // dialog cancelled by the user\n                return;\n            }\n        } else {\n            JFileChooser chooser = new JFileChooser();\n\n            if (exportDir != null) {\n                chooser.setCurrentDirectory(exportDir);\n            }\n\n            chooser.setDialogTitle(Bundle.ResultsManager_SelectDirDialogCaption());\n            chooser.setApproveButtonText(Bundle.ResultsManager_SaveButtonName());\n            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\n            chooser.setMultiSelectionEnabled(false);\n\n            if (chooser.showSaveDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) {\n                File file = chooser.getSelectedFile();\n\n                if (!file.exists()) {\n                    if (!ProfilerDialogs.displayConfirmation(\n                            Bundle.ResultsManager_DirectoryDoesntExistMsg(), \n                            Bundle.ResultsManager_DirectoryDoesntExistCaption())) {\n                        return; // cancelled by the user\n                    }\n\n                    file.mkdir();\n                }\n\n                exportDir = file;\n\n                dir[0] = FileUtil.toFileObject(FileUtil.normalizeFile(file));\n            } else { // dialog cancelled\n                return;\n            }\n        }\n        final ProgressHandle ph = ProgressHandle.createHandle(Bundle.MSG_SavingSnapshots());\n        ph.setInitialDelay(500);\n        ph.start();\n        ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n            @Override\n            public void run() {\n                try {\n                    for (FileObject selectedSnapshot : selectedSnapshots) {\n                        exportSnapshot(selectedSnapshot, dir[0], fileName[0] != null ? fileName[0] : selectedSnapshot.getName(), fileExt[0] != null ? fileExt[0] : selectedSnapshot.getExt());\n                    }\n                } finally {\n                    ph.finish();\n                }\n            }\n        });\n    }\n\n    public LoadedSnapshot findLoadedSnapshot(ResultsSnapshot snapshot) {\n        for (LoadedSnapshot ls : loadedSnapshots) {\n            if (ls.getSnapshot() == snapshot) {\n                return ls;\n            }\n        }\n\n        return null;\n    }\n\n    public LoadedSnapshot findLoadedSnapshot(File snapshotFile) {\n        for (LoadedSnapshot ls : loadedSnapshots) {\n            if ((ls.getFile() != null) && ls.getFile().equals(snapshotFile)) {\n                return ls;\n            }\n        }\n\n        return null;\n    }\n    \n    private static final String HPROF_HEADER = \"JAVA PROFILE 1.0\"; // NOI18H\n    private static final long MIN_HPROF_SIZE = 1024*1024L;\n    public static boolean checkHprofFile(File file) {\n        try {\n            if (file.isFile() && file.canRead() && file.length()>MIN_HPROF_SIZE) { // heap dump must be 1M and bigger\n                byte[] prefix = new byte[HPROF_HEADER.length()+4];\n                try (RandomAccessFile raf = new RandomAccessFile(file,\"r\")) {   // NOI18N\n                    raf.readFully(prefix);\n                }\n                if (new String(prefix).startsWith(HPROF_HEADER)) {\n                    return true;\n                }\n            }\n        } catch (FileNotFoundException ex) {\n            return false;\n        } catch (IOException ex) {\n            return false;\n        }\n        return false;\n    }\n\n    public FileObject[] listSavedHeapdumps(Lookup.Provider project, File directory) {\n        try {\n            FileObject snapshotsFolder = null;\n                    \n            if (project == null && directory != null) {\n                snapshotsFolder = FileUtil.toFileObject(directory);\n            } else {\n                snapshotsFolder = ProfilerStorage.getProjectFolder(project, false);\n            }\n\n            if (snapshotsFolder == null) {\n                return new FileObject[0];\n            }\n\n            snapshotsFolder.refresh();\n\n            FileObject[] children = snapshotsFolder.getChildren();\n\n            ArrayList /*<FileObject>*/ files = new ArrayList /*<FileObject>*/();\n\n            for (FileObject child : children) {\n                if (checkHprofFile(FileUtil.toFile(child))) {\n                    files.add(child);\n                }\n            }\n\n            Collections.sort(files,\n                             new Comparator() {\n                    public int compare(Object o1, Object o2) {\n                        FileObject f1 = (FileObject) o1;\n                        FileObject f2 = (FileObject) o2;\n\n                        return f1.getName().compareTo(f2.getName());\n                    }\n                });\n\n            return (FileObject[])files.toArray(new FileObject[0]);\n        } catch (IOException e) {\n            LOGGER.log(Level.SEVERE, Bundle.ResultsManager_ObtainSavedSnapshotsFailedMsg(e.getMessage()), e);\n\n            return new FileObject[0];\n        }\n    }\n\n    public FileObject[] listSavedSnapshots(Lookup.Provider project, File directory) {\n        try {\n            FileObject snapshotsFolder = null;\n                    \n            if (project == null && directory != null) {\n                snapshotsFolder = FileUtil.toFileObject(directory);\n            } else {\n                snapshotsFolder = ProfilerStorage.getProjectFolder(project, false);\n            }\n\n            if (snapshotsFolder == null) {\n                return new FileObject[0];\n            }\n\n            snapshotsFolder.refresh();\n\n            FileObject[] children = snapshotsFolder.getChildren();\n\n            ArrayList /*<FileObject>*/ files = new ArrayList /*<FileObject>*/();\n\n            for (FileObject child : children) {\n                if (child.getExt().equalsIgnoreCase(SNAPSHOT_EXTENSION)) {\n                    files.add(child);\n                }\n            }\n\n            Collections.sort(files,\n                             new Comparator() {\n                    public int compare(Object o1, Object o2) {\n                        FileObject f1 = (FileObject) o1;\n                        FileObject f2 = (FileObject) o2;\n\n                        return f1.getName().compareTo(f2.getName());\n                    }\n                });\n\n            return (FileObject[])files.toArray(new FileObject[0]);\n        } catch (IOException e) {\n            LOGGER.log(Level.SEVERE, Bundle.ResultsManager_ObtainSavedSnapshotsFailedMsg(e.getMessage()), e);\n\n            return new FileObject[0];\n        }\n    }\n\n    public boolean hasSnapshotsFor(Lookup.Provider project) {\n        try {\n            FileObject snapshotsFolder = ProfilerStorage.getProjectFolder(project, false);\n            FileObject[] children;\n            \n            if (snapshotsFolder == null) {\n                return false;\n            }\n            snapshotsFolder.refresh();\n            children = snapshotsFolder.getChildren();\n            for (FileObject child : children) {\n                if (child.getExt().equalsIgnoreCase(SNAPSHOT_EXTENSION)) return true;\n                if (checkHprofFile(FileUtil.toFile(child))) return true;\n            }\n        } catch (IOException e) {\n            LOGGER.log(Level.SEVERE, Bundle.ResultsManager_ObtainSavedSnapshotsFailedMsg(e.getMessage()), e);            \n        }\n        return false;\n    }\n    \n    public int getSnapshotsCountFor(Lookup.Provider project) {\n        int count = 0;\n        try {\n            FileObject snapshotsFolder = ProfilerStorage.getProjectFolder(project, false);\n            FileObject[] children;\n            \n            if (snapshotsFolder == null) {\n                return count;\n            }\n            snapshotsFolder.refresh();\n            children = snapshotsFolder.getChildren();\n            for (FileObject child : children) {\n                if (child.getExt().equalsIgnoreCase(SNAPSHOT_EXTENSION) ||\n                    checkHprofFile(FileUtil.toFile(child))) count++;\n            }\n        } catch (IOException e) {\n            LOGGER.log(Level.SEVERE, Bundle.ResultsManager_ObtainSavedSnapshotsFailedMsg(e.getMessage()), e);            \n        }\n        return count;\n    }\n    \n    public LoadedSnapshot loadSnapshot(FileObject selectedFile) {\n        try {\n            return loadSnapshotImpl(selectedFile);\n        } catch (IOException e) {\n            LOGGER.log(Level.INFO, Bundle.ResultsManager_SnapshotLoadFailed(selectedFile.getPath()), e);\n            ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotLoadFailedMsg(selectedFile.getNameExt(), e.getMessage()));\n\n            return null;\n        }\n    }\n\n    public LoadedSnapshot[] loadSnapshots(FileObject[] selectedFiles) {\n        LoadedSnapshot[] ret = new LoadedSnapshot[selectedFiles.length];\n\n        for (int i = 0; i < selectedFiles.length; i++) {\n            try {\n                if (selectedFiles[i] != null) {\n                    ret[i] = loadSnapshotImpl(selectedFiles[i]);\n                }\n            } catch (IOException e) {\n                LOGGER.log(Level.INFO, Bundle.ResultsManager_SnapshotLoadFailed(selectedFiles[i].getPath()), e);\n                ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotLoadFailedMsg(selectedFiles[i].getNameExt(), e.getMessage()));\n            }\n        }\n\n        return ret;\n    }\n    \n    public void openSnapshot(File snapshot) {\n        File sf = FileUtil.normalizeFile(snapshot);\n        FileObject snapshotFo = FileUtil.toFileObject(sf);\n        openSnapshot(snapshotFo);\n    }\n    \n    public void openSnapshot(FileObject snapshotFo) {\n        try {\n            DataObject snapshotDo = DataObject.find(snapshotFo);\n            OpenCookie open = snapshotDo.getCookie(OpenCookie.class);\n            if (open != null) {\n                open.open();\n            }\n        } catch (DataObjectNotFoundException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n    }\n\n    public void openSnapshot(LoadedSnapshot ls) {\n        openSnapshot(ls, CommonConstants.SORTING_COLUMN_DEFAULT, false); // target component decides which column will be used for sorting\n    }\n\n    public void openSnapshot(final LoadedSnapshot ls, final int sortingColumn, final boolean sortingOrder) {\n        if (ls == null) ProfilerDialogs.displayError(Bundle.ResultsManager_CannotOpenSnapshotMsg());\n        else CommonUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                SnapshotResultsWindow srw = SnapshotResultsWindow.get(ls, sortingColumn, sortingOrder);\n                srw.open();\n                srw.requestActive();\n            }\n        });\n    }\n\n    public void openSnapshots(LoadedSnapshot[] loaded) {\n        LoadedSnapshot loadedSnapshot = null;\n\n        try {\n            SnapshotResultsWindow srw = null;\n\n            for (LoadedSnapshot loaded1 : loaded) {\n                loadedSnapshot = loaded1;\n                if (loaded1 != null) {\n                    srw = SnapshotResultsWindow.get(loadedSnapshot);\n                    srw.open();\n                }\n            }\n\n            if (srw != null) {\n                srw.requestActive(); // activate the last one\n            }\n        } catch (Exception e) {\n            LOGGER.log(Level.INFO, Bundle.ResultsManager_SnapshotLoadFailed(loadedSnapshot.getFile().getAbsoluteFile()), e);\n            ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotLoadFailedMsg(loadedSnapshot.getFile().getName(), e.getMessage()));\n        }\n    }\n\n    public LoadedSnapshot prepareSnapshot() {\n        return prepareSnapshot(true);\n    }\n\n    public LoadedSnapshot prepareSnapshot(boolean reqeustData) {\n        ResultsSnapshot snapshot = null;\n\n        if (!resultsAvailable()) {\n            return null;\n        }\n\n        try {\n            final Profiler profiler = Profiler.getDefault();\n            final TargetAppRunner runner = profiler.getTargetAppRunner();\n            final ProfilerClient client = runner.getProfilerClient();\n            final int currentProfilingType = profiler.getLastProfilingSettings().getProfilingType();\n\n            try {\n                switch (currentProfilingType) {\n                    case ProfilingSettings.PROFILE_MEMORY_ALLOCATIONS:\n                    case ProfilingSettings.PROFILE_MEMORY_LIVENESS:\n                    case ProfilingSettings.PROFILE_MEMORY_SAMPLING:\n                        snapshot = client.getMemoryProfilingResultsSnapshot(reqeustData);\n\n                        break;\n                    case ProfilingSettings.PROFILE_CPU_ENTIRE:\n                    case ProfilingSettings.PROFILE_CPU_PART:\n                    case ProfilingSettings.PROFILE_CPU_SAMPLING:\n                        snapshot = client.getCPUProfilingResultsSnapshot(reqeustData);\n\n                        break;\n                    case ProfilingSettings.PROFILE_CPU_STOPWATCH:\n                        snapshot = client.getCodeRegionProfilingResultsSnapshot();\n\n                        break;\n                    case ProfilingSettings.PROFILE_CPU_JDBC:\n                        snapshot = client.getJdbcProfilingResultsSnapshot(reqeustData);\n\n                        break;\n                }\n            } catch (ClientUtils.TargetAppOrVMTerminated e1) {\n                ProfilerDialogs.displayWarning(Bundle.ResultsManager_ProfiledAppTerminatedMsg());\n                ProfilerLogger.log(e1.getMessage());\n            } catch (CPUResultsSnapshot.NoDataAvailableException e2) {\n                LOGGER.log(Level.SEVERE, Bundle.ResultsManager_DataNotAvailableMsg(), e2);\n            } catch (OutOfMemoryError e) {\n                try {\n                    reset(); // reset the client data\n                    runner.resetTimers(); // reset the server data\n                } catch (ClientUtils.TargetAppOrVMTerminated targetAppOrVMTerminated) {\n                    // the target app has died; clean up all client data\n                    client.resetClientData();\n                }\n\n                LOGGER.log(Level.SEVERE, Bundle.ResultsManager_OutOfMemoryMsg(), e);\n            }\n        } finally {\n            if (snapshot != null) {\n                ProfilingSettings settings = new ProfilingSettings();\n                Profiler.getDefault().getLastProfilingSettings().copySettingsInto(settings);\n                settings.setSettingsName(Profiler.getDefault().getLastProfilingSettings().getSettingsName());\n\n                Lookup.Provider profiledProject = NetBeansProfiler.getDefaultNB().getProfiledProject();\n\n                return new LoadedSnapshot(snapshot, settings, null, profiledProject);\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * This should be called when the app is restarted or \"Reset Collected Results\" is invoked (because once this happened,\n     * there are all sorts of data that's going to be deleted/changed, and an attempt to do something with old results displayed\n     * here can cause big problems). It should also set the results panel invisible (or is it already happening?) etc.\n     */\n    public void reset() {\n        ProfilingResultsDispatcher.getDefault().reset();\n        resultsReset();\n    }\n\n    public boolean resultsAvailable() {\n        return resultsAvailable;\n    }\n    \n    \n    public static interface SnapshotHandle {\n        public LoadedSnapshot getSnapshot();\n    }\n    \n    public ExportUtils.Exportable createSnapshotExporter(final LoadedSnapshot snapshot) {\n        return createSnapshotExporter(new SnapshotHandle() {\n            public LoadedSnapshot getSnapshot() { return snapshot; }\n        });\n    }\n    \n    public ExportUtils.Exportable createSnapshotExporter(final SnapshotHandle handle) {\n        return new ExportUtils.Exportable() {\n            public String getName() {\n                return Bundle.ResultsManager_ExportSnapshotData();\n            }\n\n            public boolean isEnabled() {\n                return true;\n            }\n\n            public ExportUtils.ExportProvider[] getProviders() {\n                final LoadedSnapshot snapshot = handle.getSnapshot();\n                return new ExportUtils.ExportProvider[] {\n                    new ExportUtils.AbstractNPSExportProvider(snapshot.getFile()) {\n                        protected void doExport(File targetFile) {\n                            exportSnapshot(snapshot, targetFile);\n                        }\n                    }\n                };\n            }\n        };\n    }\n    \n    private boolean exportSnapshot(LoadedSnapshot snapshot, File targetFile) {\n        File sourceFile = snapshot.getFile();\n        if (sourceFile != null) {\n            try {\n                Files.copy(sourceFile.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING,\n                                                                     StandardCopyOption.COPY_ATTRIBUTES);\n                return true;\n            } catch (Throwable t) {\n                LOGGER.log(Level.INFO, t.getMessage(), t);\n                String msg = t.getLocalizedMessage().replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\"); // NOI18N\n                ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotExportFailedMsg(msg));\n                return false;\n            }\n        } else {\n            FileLock lock = null;\n            FileObject target = null;\n            DataOutputStream dos = null;\n            \n            try {\n                targetFile = FileUtil.normalizeFile(targetFile);\n                target = targetFile.isFile() ? FileUtil.toFileObject(targetFile) :\n                                               FileUtil.createData(targetFile);\n            \n                lock = target.lock();\n\n                OutputStream os = target.getOutputStream(lock);\n                BufferedOutputStream bos = new BufferedOutputStream(os);\n                dos = new DataOutputStream(bos);\n                //      System.out.println(\"Saving snapshot [\" + snapshot.getSnapshot().getTimeTaken() + \"]\");\n                snapshot.save(dos);\n                dos.close();\n            } catch (IOException e) {\n                try {\n                    if (dos != null) dos.close();\n                    if (lock != null) target.delete(lock);\n                } catch (Exception e2) {}\n\n                ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotSaveFailedMsg(e.getMessage()));\n\n                return false; // failure => we wont continue with firing the event\n            } catch (OutOfMemoryError e) {\n                try {\n                    if (dos != null) dos.close();\n                    if (lock != null) target.delete(lock);\n                } catch (Exception e2) {}\n\n                ProfilerDialogs.displayError(Bundle.ResultsManager_OutOfMemorySavingMsg());\n\n                return false; // failure => we wont continue with firing the event\n            } finally {\n                if (lock != null) lock.releaseLock();\n            }\n\n            return true;\n        }\n    }\n\n    public boolean saveSnapshot(LoadedSnapshot snapshot, FileObject profFile) {\n        FileLock lock = null;\n        DataOutputStream dos = null;\n        \n        boolean isSaved = snapshot.isSaved();\n        snapshot.setSaved(true); // Set the file as saved in advance to prevent saving it again\n        try {\n            lock = profFile.lock();\n\n            OutputStream os = profFile.getOutputStream(lock);\n            BufferedOutputStream bos = new BufferedOutputStream(os);\n            dos = new DataOutputStream(bos);\n            //      System.out.println(\"Saving snapshot [\" + snapshot.getSnapshot().getTimeTaken() + \"]\");\n            snapshot.save(dos);\n            dos.close();\n            snapshot.setFile(FileUtil.toFile(profFile));\n            snapshot.setSaved(true);\n            fireSnapshotSaved(snapshot);\n        } catch (IOException e) {\n            snapshot.setSaved(isSaved);\n            try {\n                if (dos != null) {\n                    dos.close();\n                }\n\n                if (lock != null) {\n                    profFile.delete(lock);\n                }\n            } catch (Exception e2) {\n            }\n\n            ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotSaveFailedMsg(e.getMessage()));\n            \n            return false; // failure => we wont continue with firing the event\n        } catch (OutOfMemoryError e) {\n            snapshot.setSaved(isSaved);\n            try {\n                if (dos != null) {\n                    dos.close();\n                }\n\n                if (lock != null) {\n                    profFile.delete(lock);\n                }\n            } catch (Exception e2) {\n            }\n\n            ProfilerDialogs.displayError(Bundle.ResultsManager_OutOfMemorySavingMsg());\n\n            return false; // failure => we wont continue with firing the event\n        } finally {\n            if (lock != null) {\n                lock.releaseLock();\n            }\n        }\n\n        return true;\n    }\n\n    public boolean saveSnapshot(LoadedSnapshot ls) {\n        FileObject profFile = null;\n\n        Lookup.Provider p = ls.getProject();\n        FileObject saveDir = null;\n\n        try {\n            saveDir = ProfilerStorage.getProjectFolder(p, true);\n        } catch (IOException e) {\n            LOGGER.log(Level.SEVERE, Bundle.ResultsManager_CantFindSnapshotLocationMsg(e.getMessage()), e);\n\n            return false;\n        }\n\n        try {\n            profFile = saveDir.createData(getDefaultSnapshotFileName(ls), SNAPSHOT_EXTENSION);\n        } catch (IOException e) {\n            LOGGER.log(Level.SEVERE, Bundle.ResultsManager_SnapshotCreateInProjectFailedMsg(e.getMessage()), e);\n\n            return false;\n        }\n\n        return saveSnapshot(ls, profFile);\n    }\n\n    public LoadedSnapshot takeSnapshot() {\n        CommonUtils.runInEventDispatchThreadAndWait(new Runnable() {\n                public void run() {\n                    mainWindow = WindowManager.getDefault().getMainWindow();\n                }\n            });\n\n        final Cursor cursor = mainWindow.getCursor();\n        mainWindow.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));\n\n        try {\n            LoadedSnapshot snapshot = prepareSnapshot();\n\n            if (snapshot != null) {\n                loadedSnapshots.add(snapshot);\n                fireSnapshotTaken(snapshot);\n\n                return snapshot;\n            }\n        } finally {\n            mainWindow.setCursor(cursor);\n        }\n\n        return null;\n    }\n\n    protected void fireResultsAvailable() {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"fireResultsAvailable\", new Exception());\n        }\n        if (resultsListeners.allClasses().isEmpty()) {\n            return;\n        }\n\n        CommonUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                for(ResultsListener rl : resultsListeners.allInstances()) {\n                    rl.resultsAvailable();\n                }\n            }\n        });\n    }\n\n    protected void fireResultsReset() {\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.log(Level.FINEST, \"fireResultsReset\", new Exception());\n        }\n        if (resultsListeners.allClasses().isEmpty()) {\n            return;\n        }\n\n        CommonUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                for(ResultsListener rl : resultsListeners.allInstances()) {\n                    rl.resultsReset();\n                }\n            }\n        });\n    }\n\n    protected void fireSnapshotLoaded(final LoadedSnapshot snapshot) {\n        if (snapshotListeners.allClasses().isEmpty()) {\n            return;\n        }\n\n        CommonUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                for(SnapshotsListener sl : snapshotListeners.allInstances()) {\n                    sl.snapshotLoaded(snapshot);\n                }\n            }\n        });\n    }\n\n    protected void fireSnapshotRemoved(final LoadedSnapshot snapshot) {\n        if (snapshotListeners.allClasses().isEmpty()) {\n            return;\n        }\n\n        CommonUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                for(SnapshotsListener sl : snapshotListeners.allInstances()) {\n                    sl.snapshotRemoved(snapshot);\n                }\n            }\n        });\n    }\n\n    protected void fireSnapshotSaved(final LoadedSnapshot snapshot) {\n        if (snapshotListeners.allClasses().isEmpty()) {\n            return;\n        }\n\n        CommonUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                for(SnapshotsListener sl : snapshotListeners.allInstances()) {\n                    sl.snapshotSaved(snapshot);\n                }\n            }\n        });\n    }\n\n    protected void fireSnapshotTaken(final LoadedSnapshot snapshot) {\n        if (snapshotListeners.allClasses().isEmpty()) {\n            return;\n        }\n\n        CommonUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                for(SnapshotsListener sl : snapshotListeners.allInstances()) {\n                    sl.snapshotTaken(snapshot);\n                }\n            }\n        });\n    }\n\n    void resultsBecameAvailable() {\n        if (Profiler.getDefault().getProfilingState() == Profiler.PROFILING_INACTIVE) return; // Calibration, ignore\n        resultsAvailable = true;\n        fireResultsAvailable();\n    }\n\n    void resultsReset() {\n        // NOTE: originally left as true for memory profiling due to Issue 60432, now seems to work correctly\n        resultsAvailable = false;\n        fireResultsReset();\n    }\n\n    // heapdump == true means selecting heapdump (*.hprof)\n    SelectedFile selectSnapshotTargetFile(final String defaultName, final boolean heapdump) {\n        String targetName;\n        FileObject targetDir;\n\n        // 1. let the user choose file or directory\n        JFileChooser chooser = new JFileChooser();\n\n        if (exportDir != null) {\n            chooser.setCurrentDirectory(exportDir);\n        }\n\n        chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);\n        chooser.setMultiSelectionEnabled(false);\n        chooser.setDialogTitle(Bundle.ResultsManager_SelectFileOrDirDialogCaption());\n        chooser.setApproveButtonText(Bundle.ResultsManager_SaveButtonName());\n        chooser.setAcceptAllFileFilterUsed(false);\n        chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {\n                public boolean accept(File f) {\n                    return f.isDirectory() || f.getName().endsWith(\".\" + (heapdump ? HEAPDUMP_EXTENSION : SNAPSHOT_EXTENSION)); //NOI18N\n                }\n\n                public String getDescription() {\n                    if (heapdump) {\n                        return Bundle.ResultsManager_ProfilerHeapdumpFileFilter(HEAPDUMP_EXTENSION);\n                    }\n                    return Bundle.ResultsManager_ProfilerSnapshotFileFilter(SNAPSHOT_EXTENSION);\n                }\n            });\n\n        if (chooser.showSaveDialog(WindowManager.getDefault().getMainWindow()) != JFileChooser.APPROVE_OPTION) {\n            return null; // cancelled by the user\n        }\n\n        // 2. process both cases and extract file name and extension to use\n        File file = chooser.getSelectedFile();\n        String targetExt = heapdump ? HEAPDUMP_EXTENSION : SNAPSHOT_EXTENSION;\n\n        if (file.isDirectory()) { // save to selected directory under default name\n            exportDir = chooser.getCurrentDirectory();\n            targetDir = FileUtil.toFileObject(FileUtil.normalizeFile(file));\n            targetName = defaultName;\n        } else { // save to selected file\n            exportDir = chooser.getCurrentDirectory();\n\n            targetDir = FileUtil.toFileObject(FileUtil.normalizeFile(exportDir));\n\n            String fName = file.getName();\n\n            // divide the file name into name and extension\n            int idx = fName.lastIndexOf('.'); // NOI18N\n\n            if (idx == -1) { // no extension\n                targetName = fName;\n\n                // extension will be used from source file\n            } else { // extension exists\n                if (heapdump || fName.endsWith(\".\" + targetExt)) { // NOI18N\n                    targetName = fName.substring(0, idx);\n                    targetExt = fName.substring(idx + 1);\n                } else {\n                    targetName = fName;\n                }\n            }\n        }\n\n        // 3. return a newly created FileObject\n        return new SelectedFile(targetDir, targetName, targetExt);\n    }\n\n    private boolean checkFileExists(SelectedFile sf) {\n        // check if the file already exists and if so prompt the user\n        FileObject existingFile = sf.folder.getFileObject(sf.fileName, sf.fileExt);\n\n        if (existingFile != null) {\n            if (!ProfilerDialogs.displayConfirmation(Bundle.ResultsManager_OverwriteFileDialogMsg(\n                                                        sf.fileName + \".\" //NOI18N\n                                                        + sf.fileExt), \n                                                     Bundle.ResultsManager_OverwriteFileDialogCaption())) {\n                return false; // cancelled by the user\n            }\n\n            try {\n                existingFile.delete();\n            } catch (IOException e) {\n                LOGGER.log(Level.SEVERE, Bundle.ResultsManager_FileDeleteFailedMsg(e.getMessage()), e);\n\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    private void exportSnapshot(FileObject selectedSnapshot, FileObject targetFolder, String fileName, String fileExt) {\n        if (checkFileExists(new SelectedFile(targetFolder, fileName, fileExt))) {\n            try {\n                FileUtil.copyFile(selectedSnapshot, targetFolder, fileName, fileExt);\n            } catch (Throwable t) {\n                LOGGER.log(Level.INFO, t.getMessage(), t);\n                String msg = t.getLocalizedMessage().replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\"); // NOI18N\n                ProfilerDialogs.displayError(Bundle.ResultsManager_SnapshotExportFailedMsg(msg));\n            }\n        }\n    }\n\n    private LoadedSnapshot findAlreadyLoadedSnapshot(FileObject selectedFile) {\n        File f = FileUtil.toFile(selectedFile);\n\n        if (f == null) {\n            return null;\n        }\n\n        for (LoadedSnapshot ls : loadedSnapshots) {\n            if (Objects.equals(ls.getFile(), f)) {\n                return ls;\n            }\n        }\n\n        return null;\n    }\n\n    private Lookup.Provider findProjectForSnapshot(FileObject selectedFile) {\n        return ProfilerStorage.getProjectFromFolder(selectedFile.getParent());\n    }\n\n    private LoadedSnapshot loadSnapshotFromFileObject(FileObject selectedFile)\n                                               throws IOException {\n        try (\n            InputStream is = selectedFile.getInputStream();\n            BufferedInputStream bis = new BufferedInputStream(is);\n            DataInputStream dis = new DataInputStream(bis);\n        ) {\n            LoadedSnapshot ls = LoadedSnapshot.loadSnapshot(dis);\n\n            if (ls != null) {\n                ls.setFile(FileUtil.toFile(selectedFile));\n                ls.setProject(findProjectForSnapshot(selectedFile));\n            }\n            return ls;\n        }\n    }\n\n    private LoadedSnapshot loadSnapshotImpl(FileObject selectedFile)\n                                     throws IOException {\n        LoadedSnapshot ls = findAlreadyLoadedSnapshot(selectedFile);\n\n        if (ls != null) {\n            return ls;\n        }\n\n        ls = loadSnapshotFromFileObject(selectedFile);\n\n        if (ls != null) {\n            loadedSnapshots.add(ls);\n            fireSnapshotLoaded(ls);\n        }\n\n        return ls;\n    }\n\n    private ProfilingSettings readSettingsFromFile(FileObject fo) {\n        LoadedSnapshot ls = findAlreadyLoadedSnapshot(fo);\n\n        if (ls != null) {\n            return ls.getSettings();\n        }\n\n        DataInputStream dis = null;\n\n        try {\n            InputStream is = fo.getInputStream();\n            BufferedInputStream bis = new BufferedInputStream(is);\n            dis = new DataInputStream(bis);\n\n            // data before settings\n            byte[] magicArray = new byte[LoadedSnapshot.PROFILER_FILE_MAGIC_STRING.length()];\n            int len = dis.read(magicArray);\n\n            if ((len != LoadedSnapshot.PROFILER_FILE_MAGIC_STRING.length())\n                    || !LoadedSnapshot.PROFILER_FILE_MAGIC_STRING.equals(new String(magicArray))) {\n                return null;\n            }\n\n            byte majorVersion = dis.readByte();\n            byte minorVersion = dis.readByte();\n            int type = dis.readInt();\n            int compressedDataLen = dis.readInt();\n            int uncompressedDataLen = dis.readInt();\n\n            if (dis.skipBytes(compressedDataLen) != compressedDataLen) {\n                return null;\n            }\n\n            // settings data\n            int settingsLen = dis.readInt();\n            byte[] settingsBytes = new byte[settingsLen];\n\n            if (dis.read(settingsBytes) != settingsLen) {\n                return null;\n            }\n\n            // create settings\n            Properties props = new Properties();\n            ProfilingSettings settings = new ProfilingSettings();\n            ByteArrayInputStream bais2 = new ByteArrayInputStream(settingsBytes);\n            BufferedInputStream bufBais2 = new BufferedInputStream(bais2);\n            try (DataInputStream settingsDis = new DataInputStream(bufBais2)) {\n                props.load(settingsDis);\n            } catch (IOException e) {\n                ProfilerLogger.log(e);\n\n                return null;\n            }\n\n            settings.load(props);\n\n            return settings;\n        } catch (Exception e) {\n            ProfilerLogger.log(e);\n\n            return null;\n        } finally {\n            try {\n                if (dis != null) {\n                    dis.close();\n                }\n            } catch (IOException e) {\n                ProfilerLogger.log(e);\n            }\n        }\n    }\n\n    private int readTypeFromFile(FileObject fo) {\n        LoadedSnapshot ls = findAlreadyLoadedSnapshot(fo);\n\n        if (ls != null) {\n            return ls.getType();\n        }\n\n        DataInputStream dis = null;\n\n        try {\n            InputStream is = fo.getInputStream();\n            BufferedInputStream bis = new BufferedInputStream(is);\n            dis = new DataInputStream(bis);\n\n            byte[] magicArray = new byte[LoadedSnapshot.PROFILER_FILE_MAGIC_STRING.length()];\n            int len = dis.read(magicArray);\n\n            if ((len != LoadedSnapshot.PROFILER_FILE_MAGIC_STRING.length())\n                    || !LoadedSnapshot.PROFILER_FILE_MAGIC_STRING.equals(new String(magicArray))) {\n                return LoadedSnapshot.SNAPSHOT_TYPE_UNKNOWN;\n            }\n\n            byte majorVersion = dis.readByte();\n            byte minorVersion = dis.readByte();\n            int type = dis.readInt();\n\n            return type;\n        } catch (Exception e) {\n            return LoadedSnapshot.SNAPSHOT_TYPE_UNKNOWN;\n        } finally {\n            try {\n                if (dis != null) {\n                    dis.close();\n                }\n            } catch (IOException e) {\n                e.printStackTrace(System.err);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/SampledCPUSnapshot.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\nimport java.io.IOException;\nimport java.lang.management.LockInfo;\nimport java.lang.management.MonitorInfo;\nimport java.lang.management.ThreadInfo;\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.graalvm.visualvm.lib.common.ProfilingSettingsPresets;\nimport org.graalvm.visualvm.lib.jfluid.results.CCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot.NoDataAvailableException;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.StackTraceSnapshotBuilder;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot.SamplesInputStream;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot.ThreadsSample;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.openide.filesystems.FileObject;\n\n/** SampledCPUSnapshot provides access to NPSS file\n *\n * @author Tomas Hurka\n */\npublic final class SampledCPUSnapshot {\n    public static final String OPEN_THREADS_URL = \"file:/stackframe/\";     // NOI18N\n\n    private FileObject npssFile;\n    private SamplesInputStream samplesStream;\n    private long lastTimestamp;\n    private int samples;\n    private int currentIndex;\n    private ThreadsSample sample;\n    private StackTraceSnapshotBuilder builder;\n    private long startTime;\n\n    public SampledCPUSnapshot(FileObject file) throws IOException {\n        samplesStream = new SamplesInputStream(file.getInputStream());\n        npssFile = file;\n        samples = samplesStream.getSamples();\n        lastTimestamp = samplesStream.getLastTimestamp();\n        if (samples == 0) {\n            initSamples();\n        }\n        currentIndex = -1;\n    }\n\n    public int getSamplesCount() {\n        return samples;\n    }\n\n    /**\n     * Returns start time\n     * @return start time in nanoseconds\n     */\n    public long getStartTime() {\n        return startTime;\n    }\n    \n    public long getTimestamp(int sampleIndex) throws IOException {\n        long timestamp;\n\n        if (sampleIndex == getSamplesCount()-1) {\n            return lastTimestamp;\n        }\n        getSample(sampleIndex);\n        timestamp = sample.getTime();\n        if (startTime == 0) {\n            startTime = timestamp;\n            builder = new StackTraceSnapshotBuilder();\n        }\n        builder.addStacktrace(sample.getTinfos(),timestamp);\n        return timestamp;\n    }\n\n    public long getValue(int sampleIndex, int valIndex) throws IOException {\n        getSample(sampleIndex);\n        long ret = 0;\n        for (ThreadInfo info : sample.getTinfos()) {\n            if (info.getThreadState().equals(Thread.State.RUNNABLE)) {\n                ret += info.getStackTrace().length;\n            }\n        }\n        return ret;\n    }\n\n    public List<Integer> getIntervals(int startIndex, int endIndex,PrestimeCPUCCTNode node) throws IOException {\n        List<Integer> intervals = new ArrayList();\n        SamplesInputStream stream = seek(startIndex);\n        CCTNode n = node;\n        List<String[]> stack = new ArrayList();\n        final String NATIVE_ID = \"[native]\"; // NOI18N \n        boolean match = false;\n        do {\n            if (n instanceof PrestimeCPUCCTNode) {\n                PrestimeCPUCCTNode cctNode = (PrestimeCPUCCTNode) n;\n                if (isRegular(cctNode)) {\n                    String[] mid = cctNode.getMethodClassNameAndSig();\n                    \n                    if (mid[1].endsWith(NATIVE_ID)) {\n                        mid[1] = mid[1].substring(0,mid[1].length()-NATIVE_ID.length());\n                    }\n                    stack.add(0,mid);\n                }\n            }\n            n = n.getParent();\n        } while (n != null);\n\n        for (int i = startIndex; i <= endIndex; i++) {\n            LoadedSnapshot.ThreadsSample _sample = stream.readSample();\n            ThreadInfo[] threads = _sample.getTinfos();\n            if (findStack(stack, threads)) {// match found\n                if (!match) {\n                    intervals.add(i);\n                }\n                match = true;\n            } else {\n                if (match) {\n                    intervals.add(i-1);\n                }\n                match = false;\n            }\n        }\n        if (match) {\n            intervals.add(endIndex);\n        }\n        stream.close();\n        stream = null;\n        return intervals;\n    }\n\n    private boolean findStack(final List<String[]> stack, final ThreadInfo[] threads) {      \n        for (ThreadInfo t : threads) {\n            StackTraceElement[] els = t.getStackTrace();\n            \n            if (els == null || els.length < stack.size()) {\n                continue;\n            }\n            int j=0;\n            for (; j<stack.size(); j++) {\n                StackTraceElement el = els[els.length - j - 1];\n                String[] method = stack.get(j);\n                \n                if (!el.getClassName().equals(method[0]) || !el.getMethodName().equals(method[1])) {\n                    break;  // try next thread\n                }\n            }\n            if (j == stack.size()) { // match\n                return true;\n            }\n        }\n        return false;\n    }\n    \n    public String getThreadDump(int sampleIndex) throws IOException {\n        StringBuilder sb = new StringBuilder(4096);\n        SamplesInputStream stream = seek(sampleIndex);\n        ThreadsSample _sample = stream.readSample();\n        ThreadInfo[] threads = _sample.getTinfos();\n\n        stream.close();\n        stream = null;\n        printThreads(sb, threads);\n        return sb.toString();\n    }\n\n    public LoadedSnapshot getCPUSnapshot(int startIndex, int endIndex) throws IOException {\n        LoadedSnapshot snapshot;\n\n        if (builder != null && samplesStream == null &&\n            startIndex == 0 && endIndex == getSamplesCount()-1) { // full snapshot prepared in advance\n            snapshot = createSnapshot(startTime/1000000,builder);\n            builder = null;\n        } else {\n            SamplesInputStream stream = seek(startIndex);\n            StackTraceSnapshotBuilder _builder = new StackTraceSnapshotBuilder();\n            long _startTime = 0;  // in milliseconds\n\n            for (int i = startIndex; i <= endIndex; i++) {\n                LoadedSnapshot.ThreadsSample _sample = stream.readSample();\n                if (_startTime == 0) {\n                    _startTime = _sample.getTime() / 1000000;\n                }\n                _builder.addStacktrace(_sample.getTinfos(),_sample.getTime());\n            }\n            stream.close();\n            stream = null;\n            snapshot = createSnapshot(_startTime, _builder);\n        }\n        return snapshot;\n    }\n\n    /**\n     * \n     * @param startTime start time in milliseconds\n     * @param builder StackTraceSnapshotBuilder\n     * @return snapshot\n     * @throws IOException \n     */\n    private LoadedSnapshot createSnapshot(final long startTime, final StackTraceSnapshotBuilder builder) throws IOException {\n        CPUResultsSnapshot snapshot;\n        try {\n            snapshot = builder.createSnapshot(startTime);\n        } catch (NoDataAvailableException ex) {\n            throw new IOException(ex);\n        }\n        LoadedSnapshot ls = new LoadedSnapshot(snapshot, ProfilingSettingsPresets.createCPUPreset(), null, null);\n        ls.setSaved(true);\n        return ls;\n    }\n\n    private SamplesInputStream seek(final int sampleIndex) throws IOException {\n        SamplesInputStream stream = new SamplesInputStream(npssFile.getInputStream());\n//        ThreadsSample sample;\n\n        for (int i = 0; i < sampleIndex; i++) {\n            stream.readSample();\n        }\n        return stream;\n    }\n\n    private void getSample(final int sampleIndex) throws IllegalArgumentException, IOException {\n        if (currentIndex > sampleIndex || currentIndex+1 < sampleIndex ) {\n            throw new IllegalArgumentException(\"current sample \"+currentIndex+\" requested sample \"+sampleIndex); // NOI18N\n        }\n        if (currentIndex+1 == sampleIndex) {\n            currentIndex++;\n            sample = samplesStream.readSample();\n            if (sampleIndex == getSamplesCount()-1) {\n                samplesStream.close();\n                samplesStream = null;\n            }\n        }\n    }\n\n    private void printThreads(final StringBuilder sb, ThreadInfo[] threads) {\n        boolean goToSourceAvailable = GoToSource.isAvailable();\n        sb.append(\"<pre>\"); // NOI18N\n        for (ThreadInfo thread : threads) {\n            if (thread != null) {\n                print16Thread(sb, thread, goToSourceAvailable);\n            }\n        }\n        sb.append(\"</pre>\"); // NOI18N\n    }\n\n    private void print16Thread(final StringBuilder sb, final ThreadInfo thread, boolean goToSourceAvailable) {\n        MonitorInfo[] monitors = thread.getLockedMonitors();\n        sb.append(\"&nbsp;<b>\");   // NOI18N\n        sb.append(\"\\\"\").append(thread.getThreadName()).append(\"\\\" - Thread t@\").append(thread.getThreadId()).append(\"<br>\");    // NOI18N\n        sb.append(\"    java.lang.Thread.State: \").append(thread.getThreadState()); // NOI18N\n        sb.append(\"</b><br>\");   // NOI18N\n        int index = 0;\n        for (StackTraceElement st : thread.getStackTrace()) {\n            LockInfo lock = thread.getLockInfo();\n            String stackElementText = htmlize(st.toString());\n            String lockOwner = thread.getLockOwnerName();\n            String className = st.getClassName();\n            String method = st.getMethodName();\n            int lineNo = st.getLineNumber();\n            \n            String stackEl = stackElementText;\n            if (goToSourceAvailable) {\n                String stackUrl = OPEN_THREADS_URL+className+\"|\"+method+\"|\"+lineNo; // NOI18N\n                stackEl = \"<a href=\\\"\"+stackUrl+\"\\\">\"+stackElementText+\"</a>\";    // NOI18N\n            }\n\n            sb.append(\"\\tat \").append(stackEl).append(\"<br>\");    // NOI18N\n            if (index == 0) {\n                if (\"java.lang.Object\".equals(st.getClassName()) &&     // NOI18N\n                        \"wait\".equals(st.getMethodName())) {                // NOI18N\n                    if (lock != null) {\n                        sb.append(\"\\t- waiting on \");    // NOI18N\n                        printLock(sb,lock);\n                        sb.append(\"<br>\");    // NOI18N\n                    }\n                } else if (lock != null) {\n                    if (lockOwner == null) {\n                        sb.append(\"\\t- parking to wait for \");      // NOI18N\n                        printLock(sb,lock);\n                        sb.append(\"<br>\");            // NOI18N\n                    } else {\n                        sb.append(\"\\t- waiting to lock \");      // NOI18N\n                        printLock(sb,lock);\n                        sb.append(\" owned by \\\"\").append(lockOwner).append(\"\\\" t@\").append(thread.getLockOwnerId()).append(\"<br>\");   // NOI18N\n                    }\n                }\n            }\n            printMonitors(sb, monitors, index);\n            index++;\n        }\n        StringBuilder jnisb = new StringBuilder();\n        printMonitors(jnisb, monitors, -1);\n        if (jnisb.length() > 0) {\n            sb.append(\"   JNI locked monitors:<br>\");\n            sb.append(jnisb);\n        }\n        LockInfo[] synchronizers = thread.getLockedSynchronizers();\n        if (synchronizers != null) {\n            sb.append(\"<br>   Locked ownable synchronizers:\");    // NOI18N\n            if (synchronizers.length == 0) {\n                sb.append(\"<br>\\t- None\\n\");  // NOI18N\n            } else {\n                for (LockInfo li : synchronizers) {\n                    sb.append(\"<br>\\t- locked \");         // NOI18N\n                    printLock(sb,li);\n                    sb.append(\"<br>\");  // NOI18N\n                }\n            }\n        }\n        sb.append(\"<br>\");\n    }\n\n    private void printMonitors(final StringBuilder sb, final MonitorInfo[] monitors, final int index) {\n        if (monitors != null) {\n            for (MonitorInfo mi : monitors) {\n                if (mi.getLockedStackDepth() == index) {\n                    sb.append(\"\\t- locked \");   // NOI18N\n                    printLock(sb,mi);\n                    sb.append(\"<br>\");    // NOI18N\n                }\n            }\n        }\n    }\n\n    private void printLock(StringBuilder sb,LockInfo lock) {\n        String id = Integer.toHexString(lock.getIdentityHashCode());\n        String className = lock.getClassName();\n\n        sb.append(\"&lt;\").append(id).append(\"&gt; (a \").append(className).append(\")\");       // NOI18N\n    }\n    \n    private static String htmlize(String value) {\n            return value.replace(\">\", \"&gt;\").replace(\"<\", \"&lt;\");     // NOI18N\n    }\n\n    private boolean isRegular(PrestimeCPUCCTNode n) {\n        return !n.isThreadNode() && !n.isFiltered();\n    }\n\n    private void initSamples() throws IOException {\n        SamplesInputStream stream = new SamplesInputStream(npssFile.getInputStream());\n        int samplesGuess = (int)(npssFile.getSize()/130);\n        ProgressHandle ph = ProgressHandle.createSystemHandle(\"Computing snapshot samples\", null);\n        ph.start(samplesGuess);\n        \n        for(ThreadsSample s = stream.readSample(); s != null; s = stream.readSample()) {\n            samples++;\n            lastTimestamp = s.getTime();\n            if (samples < samplesGuess) {\n                ph.progress(samples);\n            }\n        }\n        ph.finish();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/SaveSnapshotAction.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\nimport org.openide.util.NbBundle;\nimport java.awt.event.ActionEvent;\nimport javax.swing.*;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.ui.NBSwingWorker;\n\n@NbBundle.Messages({\n    \"SaveSnapshotAction_ActionName=Save Snapshot\",\n    \"SaveSnapshotAction_ActionDescr=Save Snapshot to Project\"\n})\nclass SaveSnapshotAction extends AbstractAction {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final LoadedSnapshot snapshot;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    SaveSnapshotAction(LoadedSnapshot snapshot) {\n        putValue(Action.NAME, Bundle.SaveSnapshotAction_ActionName());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.SaveSnapshotAction_ActionDescr());\n        putValue(Action.SMALL_ICON, Icons.getIcon(GeneralIcons.SAVE));\n        putValue(\"iconBase\", Icons.getResource(GeneralIcons.SAVE)); // NOI18N\n        this.snapshot = snapshot;\n        updateState();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void actionPerformed(ActionEvent e) {\n        new NBSwingWorker() {\n            final private ProgressHandle ph = ProgressHandle.createHandle(Bundle.MSG_SavingSnapshot());\n            @Override\n            protected void doInBackground() {\n                ph.setInitialDelay(500);\n                ph.start();\n                ResultsManager.getDefault().saveSnapshot(snapshot);\n            }\n\n            @Override\n            protected void done() {\n                ph.finish();\n                updateState();\n            }\n        }.execute();\n    }\n\n    public void updateState() {\n        setEnabled(!snapshot.isSaved());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/ServerStateMonitor.java",
    "content": "/*\n * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler;\n\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.event.SimpleProfilingStateAdapter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.openide.util.NbBundle;\n\n/**\n * Monitor of the profiler state which displays status of the server in the main window status bar.\n *\n * @author Jan Taus\n */\n@NbBundle.Messages({\n    \"ServerStateMonitor_ProfilerBusy=Profiler Busy\",\n    \"ServerStateMonitor_ServerInitializing=Initializing...\",\n    \"ServerStateMonitor_ServerPreparing=Preparing data...\",\n    \"ServerStateMonitor_ServerInstrumenting=Instrumenting...\"\n})\nclass ServerStateMonitor {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final Profiler profiler;\n    private ProgressHandle progressHandle = null;\n    private int activeServerState = -1;\n    private int activeServerProgress = -1;\n    private int activeServerProgressValue = -1;\n\n    //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n    ServerStateMonitor(Profiler profiler) {\n        this.profiler = profiler;\n        updateProgress();\n        profiler.addProfilingStateListener(new SimpleProfilingStateAdapter() {\n            @Override\n            protected void update() {\n                updateProgress();\n            }\n        });\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    private void updateProgress() {\n        boolean display = profiler.getProfilingState() != Profiler.PROFILING_INACTIVE &&\n                          profiler.getServerState() != CommonConstants.SERVER_RUNNING;\n        if (display) {\n            int serverProgress = profiler.getServerProgress();\n            int serverState = profiler.getServerState();\n            if (progressHandle == null) {\n                progressHandle = ProgressHandle.createHandle(Bundle.ServerStateMonitor_ProfilerBusy());\n                if (serverProgress == CommonConstants.SERVER_PROGRESS_INDETERMINATE) {\n                    progressHandle.start();\n                } else {\n                    progressHandle.start(CommonConstants.SERVER_PROGRESS_WORKUNITS);\n                }\n                activeServerState = -1;\n                activeServerProgress = serverProgress;\n            }\n            if (serverProgress != activeServerProgress) {\n                if (activeServerProgress == CommonConstants.SERVER_PROGRESS_INDETERMINATE) {\n                    progressHandle.switchToDeterminate(CommonConstants.SERVER_PROGRESS_WORKUNITS);\n                    progressHandle.progress(serverProgress);\n                    activeServerProgressValue = serverProgress;\n                } else if (serverProgress == CommonConstants.SERVER_PROGRESS_INDETERMINATE) {\n                    progressHandle.switchToIndeterminate();\n                } else {\n                    if (serverProgress > activeServerProgressValue) {\n                        progressHandle.progress(serverProgress);\n                        activeServerProgressValue = serverProgress;\n                    }\n                }\n                activeServerProgress = serverProgress;\n            }\n\n            if (serverState != activeServerState) {\n                activeServerState = serverState;\n                switch (activeServerState) {\n                    case CommonConstants.SERVER_INITIALIZING:\n                        progressHandle.progress(Bundle.ServerStateMonitor_ServerInitializing());\n                        break;\n                    case CommonConstants.SERVER_INSTRUMENTING:\n                        progressHandle.progress(Bundle.ServerStateMonitor_ServerInstrumenting());\n                        break;\n                    case CommonConstants.SERVER_PREPARING:\n                        progressHandle.progress(Bundle.ServerStateMonitor_ServerPreparing());\n                        break;\n                    default:\n                        progressHandle.progress(\"\"); // NOI18N\n                        break;\n                }\n            }\n        } else {\n            closeProgress();\n        }\n    }\n\n    private void closeProgress() {\n        if (progressHandle != null) {\n            progressHandle.finish();\n            progressHandle = null;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/SnapshotInfoAction.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\nimport org.openide.util.NbBundle;\nimport java.awt.event.ActionEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.util.HelpCtx;\n\n@NbBundle.Messages({\n    \"SnapshotInfoAction_ActionName=Snapshot information\",\n    \"SnapshotInfoAction_ActionDescr=Display snapshot information\",\n    \"SnapshotInfoAction_WindowCaption=Snapshot Information\"\n})\nclass SnapshotInfoAction extends AbstractAction {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final LoadedSnapshot snapshot;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    SnapshotInfoAction(LoadedSnapshot snapshot) {\n        putValue(Action.NAME, Bundle.SnapshotInfoAction_ActionName());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.SnapshotInfoAction_ActionDescr());\n        putValue(Action.SMALL_ICON, Icons.getIcon(GeneralIcons.INFO));\n        putValue(\"iconBase\", Icons.getResource(GeneralIcons.INFO)); // NOI18N\n        this.snapshot = snapshot;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void actionPerformed(ActionEvent e) {\n        HelpCtx helpCtx = new HelpCtx(\"SnapshotInfo.HelpCtx\"); // NOI18N\n        DialogDescriptor dd = new DialogDescriptor(new SnapshotInfoPanel(snapshot),\n                              Bundle.SnapshotInfoAction_WindowCaption(), true,\n                              new Object[] { DialogDescriptor.OK_OPTION }, \n                              DialogDescriptor.OK_OPTION, DialogDescriptor.DEFAULT_ALIGN,\n                              helpCtx, null);\n        DialogDisplayer.getDefault().createDialog(dd).setVisible(true);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/SnapshotInfoPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatterFactory;\nimport org.openide.util.NbBundle;\nimport java.awt.*;\nimport java.awt.image.BufferedImage;\nimport java.io.File;\nimport java.net.URL;\nimport java.text.NumberFormat;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Date;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.awt.Mnemonics;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.RequestProcessor;\n\n@NbBundle.Messages({\n    \"SnapshotInfoPanel_DataCollectedFromString=Data collected from:\",\n    \"SnapshotInfoPanel_SnapshotTakenAtString=Snapshot taken at:\",\n    \"SnapshotInfoPanel_FileString=File:\",\n    \"SnapshotInfoPanel_NotSavedString=Not Saved\",\n    \"SnapshotInfoPanel_FileSizeString=File Size:\",\n    \"SnapshotInfoPanel_SettingsString=Settings:\",\n    \"SnapshotInfoPanel_SettingsNameString=Settings Name:\",\n    \"SnapshotInfoPanel_ProfilingTypeString=Profiling Type:\",\n    \"SnapshotInfoPanel_CodeRegionString=Code Region\",\n    \"SnapshotInfoPanel_ProfiledCodeRegionString=Profiled Code Region:\",\n    \"SnapshotInfoPanel_ExcludeSleepWaitString=Exclude time spent in Thread.sleep() and Object.wait():\",\n    \"SnapshotInfoPanel_BufferSizeString=Buffer Size:\",\n    \"SnapshotInfoPanel_LimitProfiledThreadsString=Limit number of profiled threads:\",\n    \"SnapshotInfoPanel_StackDepthLimitString=Stack depth limit:\",\n    \"SnapshotInfoPanel_UnlimitedString=Unlimited\",\n    \"SnapshotInfoPanel_CpuSamplingString=CPU Profiling (Sampling Application)\",\n    \"SnapshotInfoPanel_CpuEntireString=CPU Profiling (Entire Application)\",\n    \"SnapshotInfoPanel_CpuPartString=CPU Profiling (Part of Application)\",\n    \"SnapshotInfoPanel_MemorySamplingString=Memory (Sampling)\",\n    \"SnapshotInfoPanel_MemoryAllocString=Memory (Allocations Only)\",\n    \"SnapshotInfoPanel_MemoryLivenessString=Memory (Liveness)\",\n    \"SnapshotInfoPanel_TrackingAllInstancesString=Tracking All Instances\",\n    \"SnapshotInfoPanel_TrackEveryString=Track Every:\",\n    \"SnapshotInfoPanel_RecordStackTracesString=Record Stack Traces:\",\n    \"SnapshotInfoPanel_LimitStackDepthString=Limit Stack Depth:\",\n    \"SnapshotInfoPanel_RunGcString=Run Garbage Collection When Getting Results:\",\n    \"SnapshotInfoPanel_RootMethodsString=Root Methods:\",\n    \"SnapshotInfoPanel_CpuProfilingTypeString=CPU Profiling Type:\",\n    \"SnapshotInfoPanel_SamplingPeriodString=Sampling Period:\",\n    \"SnapshotInfoPanel_CpuTimerString=CPU Timer:\",\n    \"SnapshotInfoPanel_InstrumentationFilterString=Instrumentation Filter:\",\n    \"SnapshotInfoPanel_InstrumentationSchemeString=Instrumentation Scheme:\",\n    \"SnapshotInfoPanel_InstrumentMethodInvokeString=Instrument Method Invoke:\",\n    \"SnapshotInfoPanel_InstrumentNewThreadsString=Instrument New Threads:\",\n    \"SnapshotInfoPanel_InstrumentGettersSettersString=Instrument Getters and Setters:\",\n    \"SnapshotInfoPanel_InstrumentEmptyMethodsString=Instrument Empty Methods:\",\n    \"SnapshotInfoPanel_OverridenGlobalPropertiesString=Overridden Global Properties:\",\n    \"SnapshotInfoPanel_WorkingDirectoryString=Working Directory:\",\n    \"SnapshotInfoPanel_ProjectPlatformNameString=<project>\",\n    \"SnapshotInfoPanel_JavaPlatformString=Java Platform:\",\n    \"SnapshotInfoPanel_JvmArgumentsString=JVM Arguments:\",\n    \"SnapshotInfoPanel_CommPortString=Communication Port:\",\n    \"SnapshotInfoPanel_YesString=Yes\",\n    \"SnapshotInfoPanel_NoString=No\",\n    \"SnapshotInfoPanel_OnString=On\",\n    \"SnapshotInfoPanel_OffString=Off\",\n    \"SnapshotInfoPanel_InvalidString=<Invalid>\",\n    \"SnapshotInfoPanel_NoMethodsString=No methods, main(String[] args) method of first loaded class becomes root method\",\n    \"SnapshotInfoPanel_LinesDefString={0}, lines: {1} to {2}\",\n    \"SnapshotInfoPanel_InstrumentationProfTypeString=Instrumentation\",\n    \"SnapshotInfoPanel_SampledInstrProfTypeString=Sampled Instrumentation\",\n    \"SnapshotInfoPanel_SampledProfTypeString=Sampled\",\n    \"SnapshotInfoPanel_TotalProfSchemeString=Total\",\n    \"SnapshotInfoPanel_EagerProfSchemeString=Eager\",\n    \"SnapshotInfoPanel_LazyProfSchemeString=Lazy\",\n    \"SnapshotInfoPanel_InstancesCountString={0} instances\",\n    \"SnapshotInfoPanel_InfoAreaAccessName=Snapshot properties.\",\n    \"SnapshotInfoPanel_UserCommentsLbl=&User comments:\",\n    \"SnapshotInfoPanel_UserCommentsCaption=Edit User Comments\",\n    \"SnapshotInfoPanel_SummaryString=Summary:\",\n    \"SnapshotInfoPanel_CommentsString=User comments:\",\n    \"SnapshotInfoPanel_EditCommentsLink=edit...\",\n    \"SnapshotInfoPanel_NoCommentsString=none\",\n    \"SnapshotInfoPanel_ProfilingMode=Profiling Mode:\",\n    \"SnapshotInfoPanel_MethodsAllClasses=Methods - All Classes\",\n    \"SnapshotInfoPanel_MethodsProjectClasses=Methods - Project Classes\",\n    \"SnapshotInfoPanel_MethodsSelectedClasses=Methods - Selected Classes\",\n    \"SnapshotInfoPanel_MethodsSelectedMethods=Methods - Selected Methods\",\n    \"SnapshotInfoPanel_MethodsDefinedClasses=Methods - Defined Classes\",\n    \"SnapshotInfoPanel_ObjectsAllClasses=Objects - All Classes\",\n    \"SnapshotInfoPanel_ObjectsProjectClasses=Objects - Project Classes\",\n    \"SnapshotInfoPanel_ObjectsSelectedClasses=Objects - Selected Classes\",\n    \"SnapshotInfoPanel_ProfilingTypeSampling=Sampling\",\n    \"SnapshotInfoPanel_ProfilingTypeInstrumentation=Instrumentation\",\n    \"SnapshotInfoPanel_ProjectClasses=Project Classes:\",\n    \"SnapshotInfoPanel_SelectedClasses=Selected Classes:\",\n    \"SnapshotInfoPanel_SelectedMethods=Selected Methods:\",\n    \"SnapshotInfoPanel_RecordLifecycle=Track only live objects:\",\n    \"SnapshotInfoPanel_RecordAllocations=Record allocations:\",\n    \"SnapshotInfoPanel_LimitAllocations=Limit allocation calls:\",\n    \"SnapshotInfoPanel_SqlAllQueries=SQL Queries - All Queries\",\n    \"SnapshotInfoPanel_SqlDefinedQueries=SQL Queries - Defined Queries\",\n    \"SnapshotInfoPanel_DefinedQueries=Defined Queries:\"\n})\npublic class SnapshotInfoPanel extends JPanel {\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private static class UserCommentsPanel extends JPanel\n    {\n        //~ Instance fields ----------------------------------------------------------------------------------------------------\n\n        private JTextArea textArea;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        UserCommentsPanel() {\n            initComponents();\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        String getInputText() {\n            return textArea.getText();\n        }\n\n        void setInputText(final String text) {\n            textArea.setText(text);\n            textArea.selectAll();\n        }\n\n        private void initComponents() {\n            setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));\n            setLayout(new BorderLayout(0, 5));\n\n            JLabel textLabel = new JLabel();\n            Mnemonics.setLocalizedText(textLabel, Bundle.SnapshotInfoPanel_UserCommentsLbl());\n\n            textArea = new JTextArea();\n            textLabel.setLabelFor(textArea);\n\n            textArea.requestFocus();\n\n            JScrollPane textAreaScroll = new JScrollPane(textArea);\n            textAreaScroll.setPreferredSize(new Dimension(350, 150));\n            add(textAreaScroll, BorderLayout.CENTER);\n            add(textLabel, BorderLayout.NORTH);\n\n            getAccessibleContext().setAccessibleDescription(\n                    NbBundle.getMessage(NotifyDescriptor.class, \"ACSD_InputPanel\") // NOI18N\n                    );\n            textArea.getAccessibleContext().setAccessibleDescription(\n                    NbBundle.getMessage(NotifyDescriptor.class, \"ACSD_InputField\") // NOI18N\n                    );\n        }\n    };\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final HelpCtx HELP_CTX = new HelpCtx(\"EditUserComments.HelpCtx\"); // NOI18N\n    \n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private HTMLTextArea infoArea;\n    private JScrollPane infoAreaScrollPane;\n    private LoadedSnapshot loadedSnapshot;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public SnapshotInfoPanel(LoadedSnapshot snapshot) {\n        setLayout(new BorderLayout());\n        infoArea = new HTMLTextArea() {\n            protected void showURL(URL url) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        String userComments = loadedSnapshot.getUserComments();\n                        UserCommentsPanel panel = new UserCommentsPanel();\n                        DialogDescriptor dd = new DialogDescriptor(panel, Bundle.SnapshotInfoPanel_UserCommentsCaption(),\n                                true, new Object[] { DialogDescriptor.OK_OPTION, DialogDescriptor.CANCEL_OPTION },\n                                    DialogDescriptor.OK_OPTION,\n                                    0, HELP_CTX, null);\n                        panel.setInputText(userComments);\n                        Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n                        d.setVisible(true);\n                        if (dd.getValue() == DialogDescriptor.OK_OPTION) {\n                            setUserComments(panel.getInputText());\n                        }\n                    }\n                });\n            }\n            public void scrollRectToVisible(Rectangle aRect) {\n                if (isShowing()) super.scrollRectToVisible(aRect);\n            }\n        };\n        infoArea.getAccessibleContext().setAccessibleName(Bundle.SnapshotInfoPanel_InfoAreaAccessName());\n        infoArea.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));\n        infoAreaScrollPane = new JScrollPane(infoArea);\n        infoAreaScrollPane.setBorder(BorderFactory.createEmptyBorder());\n        infoAreaScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());\n        add(infoAreaScrollPane, BorderLayout.CENTER);\n        this.loadedSnapshot = snapshot;\n        updateInfo();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public BufferedImage getCurrentViewScreenshot(boolean onlyVisibleArea) {\n        if (onlyVisibleArea) {\n            return UIUtils.createScreenshot(infoAreaScrollPane);\n        } else {\n            return UIUtils.createScreenshot(infoArea);\n        }\n    }\n\n    public boolean fitsVisibleArea() {\n        return !infoAreaScrollPane.getVerticalScrollBar().isVisible();\n    }\n    \n    public void setUserComments(String userComments) {\n        loadedSnapshot.setUserComments(userComments);\n        if (!loadedSnapshot.isSaved()) {\n            updateInfo();\n            final File snapshotFile = loadedSnapshot.getFile();\n            if (snapshotFile != null)\n                RequestProcessor.getDefault().post(new Runnable() {\n                    public void run() {\n                        ResultsManager.getDefault().saveSnapshot(loadedSnapshot,\n                                FileUtil.toFileObject(snapshotFile));\n                    }\n                });\n        }\n    }\n\n    public void updateInfo() {\n        ProfilingSettings ps = loadedSnapshot.getSettings();\n\n        StringBuffer htmlText = new StringBuffer(1000);\n\n        String infoRes = Icons.getResource(GeneralIcons.INFO);\n        String summaryStr = Bundle.SnapshotInfoPanel_SummaryString();\n        htmlText.append(\"<b><img border='0' align='bottom' src='nbresloc:/\").append(infoRes).append(\"'>&nbsp;&nbsp;\").append(summaryStr).append(\"</b><br><hr>\"); // NOI18N\n        htmlText.append(\"<div style='margin-left: 10px;'>\"); // NOI18N\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_DataCollectedFromString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(StringUtils.formatFullDate(new Date(loadedSnapshot.getSnapshot().getBeginTime())));\n        htmlText.append(\"<br>\"); // NOI18N\n\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_SnapshotTakenAtString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(StringUtils.formatFullDate(new Date(loadedSnapshot.getSnapshot().getTimeTaken())));\n        htmlText.append(\"<br>\"); // NOI18N\n\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_FileString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n\n        File f = loadedSnapshot.getFile();\n\n        if (f == null) {\n            htmlText.append(Bundle.SnapshotInfoPanel_NotSavedString());\n        } else {\n            htmlText.append(f.getAbsolutePath());\n            htmlText.append(\"<br>\"); // NOI18N\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_FileSizeString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n\n            NumberFormat format = NumberFormat.getIntegerInstance();\n            format.setGroupingUsed(true);\n            htmlText.append(format.format(f.length())).append(\" B\"); // NOI18N\n        }\n        htmlText.append(\"</div>\"); // NOI18N\n        \n        String commentsRes = Icons.getResource(GeneralIcons.INFO);\n        String commentsStr = Bundle.SnapshotInfoPanel_CommentsString();\n        String commentsLink = Bundle.SnapshotInfoPanel_EditCommentsLink();\n        String noCommentsStr = Bundle.SnapshotInfoPanel_NoCommentsString();\n        htmlText.append(\"<br>\"); // NOI18N\n        htmlText.append(\"<br>\"); // NOI18N\n        htmlText.append(\"<b><img border='0' align='bottom' src='nbresloc:/\").append(commentsRes).append(\"'>&nbsp;&nbsp;\").append(commentsStr).append(\"&nbsp;&nbsp;\" + \"</b><a href='#'>\").append(commentsLink).append(\"</a><br><hr>\"); // NOI18N\n        htmlText.append(\"<div style='margin-left: 10px;'>\"); // NOI18N\n        String comments = loadedSnapshot.getUserComments();\n        comments = comments.replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\"); // NOI18N\n        htmlText.append(comments.isEmpty() ? \"&lt;\" + noCommentsStr + \"&gt;\" : comments); // NOI18N\n        htmlText.append(\"</div>\"); // NOI18N\n\n        htmlText.append(\"<br>\"); // NOI18N\n        htmlText.append(\"<br>\"); // NOI18N\n        String settingsRes = Icons.getResource(GeneralIcons.INFO);\n        htmlText.append(\"<b><img border='0' align='bottom' src='nbresloc:/\").append(settingsRes).append(\"'>&nbsp;&nbsp;\").append(Bundle.SnapshotInfoPanel_SettingsString()).append(\"</b><br><hr>\"); // NOI18N\n        htmlText.append(\"<div style='margin-left: 10px;'>\"); // NOI18N\n        \n        switch (ps.getProfilingType()) {\n            case ProfilingSettings.PROFILE_CPU_STOPWATCH:\n                htmlText.append(\"<strong>\"); // NOI18N\n                htmlText.append(Bundle.SnapshotInfoPanel_SettingsNameString()).append(\" \"); // NOI18N\n                htmlText.append(\"</strong>\"); // NOI18N\n                htmlText.append(ps.getSettingsName());\n                htmlText.append(\"<br>\"); // NOI18N\n                htmlText.append(\"<strong>\"); // NOI18N\n                htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                htmlText.append(\"</strong>\"); // NOI18N\n                htmlText.append(Bundle.SnapshotInfoPanel_CodeRegionString());\n                htmlText.append(\"<br>\"); // NOI18N\n                htmlText.append(\"<br>\"); // NOI18N\n                htmlText.append(\"<strong>\"); // NOI18N\n                htmlText.append(Bundle.SnapshotInfoPanel_ProfiledCodeRegionString()).append(\" \"); // NOI18N\n                htmlText.append(\"</strong>\"); // NOI18N\n                htmlText.append(formatRootMethod(ps.getCodeFragmentSelection()));\n                htmlText.append(\"<br>\"); // NOI18N\n                htmlText.append(\"<strong>\"); // NOI18N\n                htmlText.append(Bundle.SnapshotInfoPanel_ExcludeSleepWaitString()).append(\" \"); // NOI18N\n                htmlText.append(\"</strong>\"); // NOI18N\n                htmlText.append(getYesNo(ps.getExcludeWaitTime()));\n                htmlText.append(\"<br>\"); // NOI18N\n                htmlText.append(\"<strong>\"); // NOI18N\n                htmlText.append(Bundle.SnapshotInfoPanel_BufferSizeString()).append(\" \"); // NOI18N\n                htmlText.append(\"</strong>\"); // NOI18N\n                htmlText.append(ps.getCodeRegionCPUResBufSize());\n                htmlText.append(\"<br>\"); // NOI18N\n                htmlText.append(\"<strong>\"); // NOI18N\n                htmlText.append(Bundle.SnapshotInfoPanel_LimitProfiledThreadsString()).append(\" \"); // NOI18N\n                htmlText.append(\"</strong>\"); // NOI18N\n\n                if (ps.getNProfiledThreadsLimit() < 0) {\n                    htmlText.append(Bundle.SnapshotInfoPanel_UnlimitedString());\n                } else {\n                    htmlText.append(ps.getNProfiledThreadsLimit());\n                }\n\n                htmlText.append(\"<br>\"); // NOI18N\n\n                break;\n            case ProfilingSettings.PROFILE_CPU_SAMPLING:\n                GenericFilter filter = ps.getInstrumentationFilter();\n                int filterType = filter.getType();\n                if (filterType == GenericFilter.TYPE_NONE && filter.getName() == null) {\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingMode()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_MethodsAllClasses());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeSampling());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    appendSampledCPUText(htmlText, false, ps);\n                } else if (filterType == GenericFilter.TYPE_INCLUSIVE && filter.getName() == null) {\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingMode()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_MethodsProjectClasses());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeSampling());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    appendSampledCPUText(htmlText, true, ps);\n                } else {\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_SettingsNameString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(ps.getSettingsName());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    \n                    htmlText.append(Bundle.SnapshotInfoPanel_CpuSamplingString());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    appendCPUText(htmlText, ps);\n                }\n\n                break;\n            case ProfilingSettings.PROFILE_CPU_ENTIRE:\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_SettingsNameString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(ps.getSettingsName());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    \n                    htmlText.append(Bundle.SnapshotInfoPanel_CpuEntireString());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    appendCPUText(htmlText, ps);\n\n                break;\n            case ProfilingSettings.PROFILE_CPU_PART:\n                ClientUtils.SourceCodeSelection[] roots = ps.getInstrumentationRootMethods();\n                if (ps.getInstrumentationFilter().getName() == null && roots != null && roots.length > 0) {\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingMode()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    boolean classes;\n                     // NOTE: currently not possible to detect Defined Clases\n                    if (Wildcards.ALLWILDCARD.equals(roots[0].getMethodName())) {\n                        htmlText.append(Bundle.SnapshotInfoPanel_MethodsSelectedClasses());\n                        classes = true;\n                    } else {\n                        htmlText.append(Bundle.SnapshotInfoPanel_MethodsSelectedMethods());\n                        classes = false;\n                    }\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeInstrumentation());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    appendInstrumentedCPUText(htmlText, classes, ps);\n                } else {\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_SettingsNameString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(ps.getSettingsName());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    \n                    htmlText.append(Bundle.SnapshotInfoPanel_CpuPartString());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    appendCPUText(htmlText, ps);\n                }\n\n                break;\n            case ProfilingSettings.PROFILE_CPU_JDBC:\n                filter = ps.getInstrumentationFilter();\n                \n                htmlText.append(\"<strong>\"); // NOI18N\n                htmlText.append(Bundle.SnapshotInfoPanel_ProfilingMode()).append(\" \"); // NOI18N\n                htmlText.append(\"</strong>\"); // NOI18N\n                htmlText.append(filter.isAll() ? Bundle.SnapshotInfoPanel_SqlAllQueries() :\n                                                 Bundle.SnapshotInfoPanel_SqlDefinedQueries());\n                \n                if (!filter.isAll()) {\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    formattedRow(htmlText, Bundle.SnapshotInfoPanel_DefinedQueries(), filter.getValue());\n                }\n                \n                break;\n            case ProfilingSettings.PROFILE_MEMORY_SAMPLING:\n                filter = ps.getInstrumentationFilter();\n                filterType = filter.getType();\n                if (filterType == GenericFilter.TYPE_NONE && filter.getName() == null) {\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingMode()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ObjectsAllClasses());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeSampling());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    appendSampledMemoryText(htmlText, false, ps);\n                } else if (filterType == GenericFilter.TYPE_INCLUSIVE && filter.getName() == null) {\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingMode()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ObjectsProjectClasses());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeSampling());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    appendSampledMemoryText(htmlText, true, ps);\n                } else {\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_SettingsNameString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(ps.getSettingsName());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_MemorySamplingString());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    appendMemoryText(htmlText, ps);\n                }\n\n                break;\n            case ProfilingSettings.PROFILE_MEMORY_ALLOCATIONS:\n                filter = ps.getInstrumentationFilter();\n                filterType = filter.getType();\n                if (filterType == GenericFilter.TYPE_INCLUSIVE && filter.getName() == null) {\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingMode()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ObjectsSelectedClasses()); // NOTE: currently not possible to detect Defined Clases\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeInstrumentation());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    appendInstrumentedMemoryText(htmlText, ps);\n                } else {\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_SettingsNameString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(ps.getSettingsName());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n\n                    htmlText.append(Bundle.SnapshotInfoPanel_MemoryAllocString());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    appendMemoryText(htmlText, ps);\n                }\n\n                break;\n            case ProfilingSettings.PROFILE_MEMORY_LIVENESS:\n                filter = ps.getInstrumentationFilter();\n                filterType = filter.getType();\n                if (filterType == GenericFilter.TYPE_INCLUSIVE && filter.getName() == null) {\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingMode()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ObjectsSelectedClasses()); // NOTE: currently not possible to detect Defined Clases\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeInstrumentation());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    appendInstrumentedMemoryText(htmlText, ps);\n                } else {\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_SettingsNameString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n                    htmlText.append(ps.getSettingsName());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<strong>\"); // NOI18N\n                    htmlText.append(Bundle.SnapshotInfoPanel_ProfilingTypeString()).append(\" \"); // NOI18N\n                    htmlText.append(\"</strong>\"); // NOI18N\n\n                    htmlText.append(Bundle.SnapshotInfoPanel_MemoryLivenessString());\n                    htmlText.append(\"<br>\"); // NOI18N\n                    htmlText.append(\"<br>\"); // NOI18N\n                    appendMemoryText(htmlText, ps);\n                }\n\n                break;\n        }\n\n        appendOverridenGlobalProperties(htmlText, ps);\n\n        htmlText.append(\"</div>\"); // NOI18N\n        htmlText.append(\"<br>\"); // NOI18N\n\n        infoArea.setText(htmlText.toString());\n        infoArea.setCaretPosition(0);\n    }\n\n    private static String getOnOff(boolean b) {\n        return b ? Bundle.SnapshotInfoPanel_OnString() : Bundle.SnapshotInfoPanel_OffString();\n    }\n\n    private static String getYesNo(boolean b) {\n        return b ? Bundle.SnapshotInfoPanel_YesString() : Bundle.SnapshotInfoPanel_NoString();\n    }\n\n    private String getCPUProfilingScheme(int type) {\n        switch (type) {\n            case CommonConstants.INSTRSCHEME_TOTAL:\n                return Bundle.SnapshotInfoPanel_TotalProfSchemeString();\n            case CommonConstants.INSTRSCHEME_EAGER:\n                return Bundle.SnapshotInfoPanel_EagerProfSchemeString();\n            case CommonConstants.INSTRSCHEME_LAZY:\n                return Bundle.SnapshotInfoPanel_LazyProfSchemeString();\n            default:\n                return Bundle.SnapshotInfoPanel_InvalidString();\n        }\n    }\n\n    private String getCPUProfilingType(int type) {\n        switch (type) {\n            case CommonConstants.CPU_INSTR_FULL:\n                return Bundle.SnapshotInfoPanel_InstrumentationProfTypeString();\n            case CommonConstants.CPU_INSTR_SAMPLED:\n                return Bundle.SnapshotInfoPanel_SampledInstrProfTypeString();\n            case CommonConstants.CPU_SAMPLED:\n                return Bundle.SnapshotInfoPanel_SampledProfTypeString();\n            default:\n                return Bundle.SnapshotInfoPanel_InvalidString();\n        }\n    }\n    \n    private static void formattedRow(StringBuffer htmlText, String caption, String text) {\n        htmlText.append(\"<table cellspacing='0' cellpadding='0'>\"); // NOI18N\n        \n        htmlText.append(\"<tr>\"); // NOI18N\n        \n        htmlText.append(\"<td valign='top' align='left'><nobr><b>\"); // NOI18N\n        htmlText.append(caption);\n        htmlText.append(\"</b>&nbsp;&nbsp;</nobr></td>\"); // NOI18N\n        \n        htmlText.append(\"<td valign='top' align='left' width='500'>\"); // NOI18N\n        htmlText.append(text);\n        htmlText.append(\"</td>\"); // NOI18N\n        \n        htmlText.append(\"</tr>\"); // NOI18N\n        \n        htmlText.append(\"</table>\"); // NOI18N\n    }\n    \n    private void appendSampledCPUText(StringBuffer htmlText, boolean project, ProfilingSettings ps) {\n        if (project) {\n            String filter = ps.getInstrumentationFilter().getValue();\n            formattedRow(htmlText, Bundle.SnapshotInfoPanel_ProjectClasses(), filter);\n            htmlText.append(\"<br>\"); // NOI18N\n        }\n        \n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_SamplingPeriodString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(ps.getSamplingFrequency());\n        htmlText.append(\" ms<br>\"); // NOI18N\n    }\n    \n    private void appendInstrumentedCPUText(StringBuffer htmlText, boolean classes, ProfilingSettings ps) {\n        String roots = formatRootMethods(ps.getInstrumentationRootMethods());\n        formattedRow(htmlText, classes ? Bundle.SnapshotInfoPanel_SelectedClasses() :\n                                         Bundle.SnapshotInfoPanel_SelectedMethods(), roots);\n        htmlText.append(\"<br>\"); // NOI18N // TODO: formatting\n        \n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_CpuTimerString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(getOnOff(ps.getThreadCPUTimerOn()));\n        htmlText.append(\"<br>\"); // NOI18N\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_ExcludeSleepWaitString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(getYesNo(ps.getExcludeWaitTime()));\n        htmlText.append(\"<br>\"); // NOI18N\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_LimitProfiledThreadsString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n\n        if (ps.getNProfiledThreadsLimit() < 0) {\n            htmlText.append(Bundle.SnapshotInfoPanel_UnlimitedString());\n        } else {\n            htmlText.append(ps.getNProfiledThreadsLimit());\n        }\n\n        htmlText.append(\"<br>\"); // NOI18N\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_StackDepthLimitString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        if (ps.getStackDepthLimit() == Integer.MAX_VALUE) {\n            htmlText.append(Bundle.SnapshotInfoPanel_UnlimitedString());\n        } else {\n            htmlText.append(ps.getStackDepthLimit());\n        }\n\n        htmlText.append(\"<br>\"); // NOI18N\n        \n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_InstrumentationSchemeString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(getCPUProfilingScheme(ps.getInstrScheme()));\n        htmlText.append(\"<br>\"); // NOI18N\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_InstrumentMethodInvokeString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(getYesNo(ps.getInstrumentMethodInvoke()));\n        htmlText.append(\"<br>\"); //NOI18N\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_InstrumentNewThreadsString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(getYesNo(ps.getInstrumentSpawnedThreads()));\n        htmlText.append(\"<br>\"); // NOI18N\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_InstrumentGettersSettersString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(getYesNo(ps.getInstrumentGetterSetterMethods()));\n        htmlText.append(\"<br>\"); // NOI18N\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_InstrumentEmptyMethodsString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(getYesNo(ps.getInstrumentEmptyMethods()));\n        htmlText.append(\"<br>\"); // NOI18N\n    }\n\n    private void appendCPUText(StringBuffer htmlText, ProfilingSettings ps) {\n        boolean sampling = ps.getProfilingType() == ProfilingSettings.PROFILE_CPU_SAMPLING;\n        \n        if (!sampling) {\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_RootMethodsString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(formatRootMethods(ps.getInstrumentationRootMethods()));\n            htmlText.append(\"<br>\"); // NOI18N // TODO: formatting\n        }\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_CpuProfilingTypeString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(getCPUProfilingType(ps.getCPUProfilingType()));\n        htmlText.append(\"<br>\"); // NOI18N\n\n        if (sampling) {\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_SamplingPeriodString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(ps.getSamplingFrequency());\n            htmlText.append(\" ms<br>\"); // NOI18N\n        } else {\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_CpuTimerString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(getOnOff(ps.getThreadCPUTimerOn()));\n            htmlText.append(\"<br>\"); // NOI18N\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_ExcludeSleepWaitString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(getYesNo(ps.getExcludeWaitTime()));\n            htmlText.append(\"<br>\"); // NOI18N\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_LimitProfiledThreadsString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n\n            if (ps.getNProfiledThreadsLimit() < 0) {\n                htmlText.append(Bundle.SnapshotInfoPanel_UnlimitedString());\n            } else {\n                htmlText.append(ps.getNProfiledThreadsLimit());\n            }\n\n            htmlText.append(\"<br>\"); // NOI18N\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_StackDepthLimitString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            if (ps.getStackDepthLimit() == Integer.MAX_VALUE) {\n                htmlText.append(Bundle.SnapshotInfoPanel_UnlimitedString());\n            } else {\n                htmlText.append(ps.getStackDepthLimit());\n            }\n\n            htmlText.append(\"<br>\"); // NOI18N\n        }\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_InstrumentationFilterString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(ps.getInstrumentationFilter().getValue());\n        htmlText.append(\"<br>\"); // NOI18N // TODO: text\n        if (!sampling) {\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_InstrumentationSchemeString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(getCPUProfilingScheme(ps.getInstrScheme()));\n            htmlText.append(\"<br>\"); // NOI18N\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_InstrumentMethodInvokeString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(getYesNo(ps.getInstrumentMethodInvoke()));\n            htmlText.append(\"<br>\"); //NOI18N\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_InstrumentNewThreadsString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(getYesNo(ps.getInstrumentSpawnedThreads()));\n            htmlText.append(\"<br>\"); // NOI18N\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_InstrumentGettersSettersString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(getYesNo(ps.getInstrumentGetterSetterMethods()));\n            htmlText.append(\"<br>\"); // NOI18N\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_InstrumentEmptyMethodsString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(getYesNo(ps.getInstrumentEmptyMethods()));\n            htmlText.append(\"<br>\"); // NOI18N\n        }\n    }\n    \n    private void appendSampledMemoryText(StringBuffer htmlText, boolean project, ProfilingSettings ps) {\n        if (project) {\n            String filter = ps.getInstrumentationFilter().getValue();\n            formattedRow(htmlText, Bundle.SnapshotInfoPanel_ProjectClasses(), filter);\n            htmlText.append(\"<br>\"); // NOI18N\n        }\n        \n//        htmlText.append(\"<strong>\"); // NOI18N\n//        htmlText.append(Bundle.SnapshotInfoPanel_SamplingPeriodString()).append(\" \"); // NOI18N\n//        htmlText.append(\"</strong>\"); // NOI18N\n//        htmlText.append(ps.getSamplingInterval());\n//        htmlText.append(\" ms<br>\"); // NOI18N\n    }\n    \n    private void appendInstrumentedMemoryText(StringBuffer htmlText, ProfilingSettings ps) {\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_RecordLifecycle()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(getYesNo(ps.getProfilingType() == ProfilingSettings.PROFILE_MEMORY_LIVENESS));\n        htmlText.append(\"<br>\"); //NOI18N\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_RecordAllocations()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        int allocLimit = ps.getAllocStackTraceLimit();\n        htmlText.append(getYesNo(allocLimit != 0));\n        htmlText.append(\"<br>\"); //NOI18N\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_LimitAllocations()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(allocLimit < 0 ? \"No\" : allocLimit);\n        htmlText.append(\"<br>\"); //NOI18N\n        htmlText.append(\"<br>\"); //NOI18N\n        \n        String filter = ps.getInstrumentationFilter().getValue();\n        formattedRow(htmlText, Bundle.SnapshotInfoPanel_SelectedClasses(), filter);\n        htmlText.append(\"<br>\"); // NOI18N\n        \n        if (ps.getAllocTrackEvery() == 1) {\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_TrackingAllInstancesString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n        } else {\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_TrackEveryString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_InstancesCountString(\"\" + ps.getAllocTrackEvery())); // NOI18N\n        }\n        htmlText.append(\"<br>\"); //NOI18N\n\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_RunGcString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(getYesNo(ps.getRunGCOnGetResultsInMemoryProfiling()));\n        htmlText.append(\"<br>\"); // NOI18N\n    }\n\n    private void appendMemoryText(StringBuffer htmlText, ProfilingSettings ps) {\n        if (ps.getProfilingType() != ProfilingSettings.PROFILE_MEMORY_SAMPLING) {\n            if (ps.getAllocTrackEvery() == 1) {\n                htmlText.append(\"<strong>\"); // NOI18N\n                htmlText.append(Bundle.SnapshotInfoPanel_TrackingAllInstancesString()).append(\" \"); // NOI18N\n                htmlText.append(\"</strong>\"); // NOI18N\n            } else {\n                htmlText.append(\"<strong>\"); // NOI18N\n                htmlText.append(Bundle.SnapshotInfoPanel_TrackEveryString()).append(\" \"); // NOI18N\n                htmlText.append(\"</strong>\"); // NOI18N\n                htmlText.append(Bundle.SnapshotInfoPanel_InstancesCountString(\"\" + ps.getAllocTrackEvery())); // NOI18N\n            }\n\n            htmlText.append(\"<br>\"); // NOI18N\n\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_RecordStackTracesString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(getYesNo(ps.getAllocStackTraceLimit() != 0));\n            htmlText.append(\"<br>\"); // NOI18N\n\n            if (ps.getAllocStackTraceLimit() != 0) {\n                htmlText.append(\"<strong>\"); // NOI18N\n                htmlText.append(Bundle.SnapshotInfoPanel_LimitStackDepthString()).append(\" \"); // NOI18N\n                htmlText.append(\"</strong>\"); // NOI18N\n\n                if (ps.getAllocStackTraceLimit() < 0) {\n                    htmlText.append(Bundle.SnapshotInfoPanel_UnlimitedString());\n                } else {\n                    htmlText.append(ps.getAllocStackTraceLimit());\n                }\n\n                htmlText.append(\"<br>\"); // NOI18N\n            }\n        }\n\n        htmlText.append(\"<strong>\"); // NOI18N\n        htmlText.append(Bundle.SnapshotInfoPanel_RunGcString()).append(\" \"); // NOI18N\n        htmlText.append(\"</strong>\"); // NOI18N\n        htmlText.append(getYesNo(ps.getRunGCOnGetResultsInMemoryProfiling()));\n        htmlText.append(\"<br>\"); // NOI18N\n    }\n\n    private void appendOverridenGlobalProperties(StringBuffer htmlText, ProfilingSettings ps) {\n        // Done\n        if (ps.getOverrideGlobalSettings()) {\n            htmlText.append(\"<br>\"); // NOI18N\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_OverridenGlobalPropertiesString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(\"<br>\"); // NOI18N\n            htmlText.append(\"<div style='margin-left: 10px;'>\"); // NOI18N\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_WorkingDirectoryString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(ps.getWorkingDir());\n            htmlText.append(\"<br>\"); // NOI18N\n\n            String platformName = ps.getJavaPlatformName();\n\n            if (platformName == null) {\n                platformName = Bundle.SnapshotInfoPanel_ProjectPlatformNameString();\n            }\n\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_JavaPlatformString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(platformName);\n            htmlText.append(\"<br>\"); // NOI18N\n            htmlText.append(\"<strong>\"); // NOI18N\n            htmlText.append(Bundle.SnapshotInfoPanel_JvmArgumentsString()).append(\" \"); // NOI18N\n            htmlText.append(\"</strong>\"); // NOI18N\n            htmlText.append(ps.getJVMArgs());\n            htmlText.append(\"</div>\"); // NOI18N\n            htmlText.append(\"<br>\"); // NOI18N\n        }\n    }\n\n    private String formatRootMethod(ClientUtils.SourceCodeSelection method) {\n        String ret;\n\n        if (method.definedViaMethodName()) {\n            //      ret =\n            //      new MethodNameFormatter(\n            //          method.getClassName(), method.getMethodName(), method.getMethodSignature()\n            //      ).getFormattedClassAndMethod();\n            ret = MethodNameFormatterFactory.getDefault().getFormatter().formatMethodName(method).toFormatted();\n            ret = ret.replace(\"<\", \"&lt;\"); // NOI18N\n            ret = ret.replace(\">\", \"&gt;\"); // NOI18N\n        } else {\n            ret = Bundle.SnapshotInfoPanel_LinesDefString(\n                    method.getClassName(), \n                    \"\" + method.getStartLine(), \n                    \"\" + method.getEndLine()\n            );\n        }\n\n        return ret;\n    }\n\n    private String formatRootMethods(ClientUtils.SourceCodeSelection[] methods) {\n        if ((methods == null) || (methods.length == 0)) {\n            return Bundle.SnapshotInfoPanel_NoMethodsString();\n        } else if (methods.length == 1) {\n            return formatRootMethod(methods[0]);\n        } else {\n            StringBuilder ret = new StringBuilder();\n\n            java.util.List<String> rootNames = new ArrayList<>();\n            for (ClientUtils.SourceCodeSelection method : methods) {\n                rootNames.add(formatRootMethod(method));\n            }\n            Collections.sort(rootNames);\n            for (String rootName : rootNames) ret.append(rootName).append(\"<br>\"); // NOI18N\n\n            return ret.toString();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/SnapshotResultsWindow.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.openide.util.NbBundle;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.ObjectInput;\nimport java.io.ObjectOutput;\nimport java.net.URI;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.ResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.MemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.cpu.SnapshotCPUView;\nimport org.graalvm.visualvm.lib.ui.jdbc.SnapshotJDBCView;\nimport org.graalvm.visualvm.lib.ui.memory.SnapshotMemoryView;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.actions.CompareSnapshotsAction;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerFeature;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.netbeans.spi.actions.AbstractSavable;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.Exceptions;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.Utilities;\nimport org.openide.util.lookup.AbstractLookup;\nimport org.openide.util.lookup.InstanceContent;\nimport org.openide.util.lookup.Lookups;\nimport org.openide.util.lookup.ServiceProvider;\n\n\n/**\n * An IDE TopComponent to display a snapshot of profiling results.\n *\n * @author Tomas Hurka\n * @author Ian Formanek\n */\n@NbBundle.Messages({\n    \"SnapshotResultsWindow_LoadingProgress=Loading profiler snapshot...\",\n    \"SnapshotResultsWindow_SaveSnapshotDialogMsg=The results snapshot is not saved. Do you want to save it?\",\n    \"SnapshotResultsWindow_CpuSnapshotAccessDescr=Profiler snapshot with CPU results\",\n    \"SnapshotResultsWindow_FragmentSnapshotAccessDescr=Profiler snapshot with code fragment results\",\n    \"SnapshotResultsWindow_MemorySnapshotAccessDescr=Profiler snapshot with memory results\",\n    \"SnapshotResultsWindow_ProfileClass=Profile Class\",\n    \"SnapshotResultsWindow_ProfileMethod=Profile Method\",\n    \"SnapshotResultsWindow_SqlQueryCaption=SQL Query Viewer\",\n    \"SnapshotResultsWindow_SqlQueryLabel=SQL Query:\"\n})\npublic final class SnapshotResultsWindow extends ProfilerTopComponent {\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n    \n    /* \n     * The following code is an externalization of various listeners registered\n     * in the global lookup and needing access to an enclosing instance of\n     * SnapshotResultsWindow. \n     */\n    @ServiceProvider(service=SnapshotsListener.class)   \n    public static class SnapshotListener implements SnapshotsListener {\n        \n        java.util.List<SnapshotResultsWindow> registeredWindows;\n        \n        void registerSnapshotResultsWindow(SnapshotResultsWindow w) {\n            assert SwingUtilities.isEventDispatchThread();\n            if (registeredWindows == null) {\n                registeredWindows = new ArrayList();\n            }\n            registeredWindows.add(w);\n        }\n\n        void unregisterSnapshotResultsWindow(SnapshotResultsWindow w) {\n            assert SwingUtilities.isEventDispatchThread();\n            if (registeredWindows != null) {\n                registeredWindows.remove(w);\n            }\n        }\n        \n        @Override\n        public void snapshotLoaded(LoadedSnapshot snapshot) {\n            // ignore\n        }\n\n        @Override\n        public void snapshotRemoved(LoadedSnapshot snapshot) {\n            // ignore\n        }\n\n        @Override\n        public void snapshotSaved(LoadedSnapshot snapshot) {\n            assert SwingUtilities.isEventDispatchThread();\n            if (registeredWindows != null) {\n                for (SnapshotResultsWindow w : registeredWindows) {\n                    if (w.snapshot == snapshot) {\n                        w.updateSaveState();\n                    }\n                }\n            }\n        }\n\n        @Override\n        public void snapshotTaken(LoadedSnapshot snapshot) {\n            // ignore\n        }\n    }\n    \n    public static interface FindPerformer {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void performFind();\n\n        public void performFindNext();\n\n        public void performFindPrevious();\n    }\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private class SavePerformer extends AbstractSavable {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        private void add() {\n            register();\n            ic.add(this);\n        }\n        \n        private void remove() {\n             unregister();\n             ic.remove(this);\n        }\n        \n        @Override\n        protected String findDisplayName() {\n            return tabName;\n        }\n\n        @Override\n        protected void handleSave() {\n            LoadedSnapshot toSave = snapshot;\n            if (toSave == null) return; // #218565 snapshot already closed\n            \n            ResultsManager.getDefault().saveSnapshot(toSave);\n            ic.remove(this);\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            return this == obj;\n        }\n\n        @Override\n        public int hashCode() {\n            return System.identityHashCode(this);\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n    \n    private static final byte PERSISTENCE_VERSION_MAJOR = 8;\n    private static final byte PERSISTENCE_VERSION_MINOR = 1;\n    \n    private static final String HELP_CTX_KEY_CPU = \"CpuSnapshot.HelpCtx\"; // NOI18N\n    private static final String HELP_CTX_KEY_MEM = \"MemorySnapshot.HelpCtx\"; // NOI18N\n    \n    private static final Image WINDOW_ICON_CPU = Icons.getImage(ProfilerIcons.CPU);\n    private static final Image WINDOW_ICON_FRAGMENT = Icons.getImage(ProfilerIcons.FRAGMENT);\n    private static final Image WINDOW_ICON_MEMORY = Icons.getImage(ProfilerIcons.MEMORY);\n    private static final Image WINDOW_ICON_JDBC = Icons.getImage(ProfilerIcons.WINDOW_SQL);\n    private static final HashMap /*<ResultsSnapshot, SnapshotResultsWindow>*/ windowsList = new HashMap();\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private LoadedSnapshot snapshot;\n    private InstanceContent ic = new InstanceContent();\n    private SavePerformer savePerformer = new SavePerformer();\n    private JPanel displayedPanel;\n    private String tabName = \"\"; // NOI18N // default\n    private SnapshotListener listener;\n    private boolean forcedClose = false;\n    private HelpCtx helpCtx = HelpCtx.DEFAULT_HELP;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Default constructor, used when restoring persisted snapshots.\n     */\n    public SnapshotResultsWindow() {\n        associateLookup(new AbstractLookup(ic));\n        ic.add(getActionMap());\n        setLayout(new BorderLayout());\n    }\n\n    /**\n     * Creates a new SnapshotResultsWindow for provided snapshot. The content of this window will vary depending on\n     * the type of snapshot provided.\n     *\n     * @param ls The results snapshot to display\n     */\n    public SnapshotResultsWindow(LoadedSnapshot ls, int sortingColumn, boolean sortingOrder) {\n        this();\n        initImpl(ls);\n    }\n    \n    private void initImpl(LoadedSnapshot ls) {\n        this.snapshot = ls;\n        updateSaveState();\n\n        setOpaque(false);\n        setFocusable(true);\n        setRequestFocusEnabled(true);\n        \n        refreshTabName();\n\n        switch (snapshot.getType()) {\n            case LoadedSnapshot.SNAPSHOT_TYPE_CPU:\n                setIcon(WINDOW_ICON_CPU);\n                helpCtx = new HelpCtx(HELP_CTX_KEY_CPU);\n                getAccessibleContext().setAccessibleDescription(Bundle.SnapshotResultsWindow_CpuSnapshotAccessDescr());\n                setupCPUResultsView();\n\n                break;\n//            case LoadedSnapshot.SNAPSHOT_TYPE_CODEFRAGMENT:\n//                getAccessibleContext().setAccessibleDescription(Bundle.SnapshotResultsWindow_FragmentSnapshotAccessDescr());\n//                displayCodeRegionResults(ls);\n//\n//                break;\n            case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_ALLOCATIONS:\n            case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_LIVENESS:\n            case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_SAMPLED:\n                setIcon(WINDOW_ICON_MEMORY);\n                helpCtx = new HelpCtx(HELP_CTX_KEY_MEM);\n                getAccessibleContext().setAccessibleDescription(Bundle.SnapshotResultsWindow_MemorySnapshotAccessDescr());\n                setupMemoryResultsView();\n\n                break;\n                \n            case LoadedSnapshot.SNAPSHOT_TYPE_CPU_JDBC:\n                setIcon(WINDOW_ICON_JDBC);\n                helpCtx = new HelpCtx(HELP_CTX_KEY_CPU);\n                getAccessibleContext().setAccessibleDescription(Bundle.SnapshotResultsWindow_CpuSnapshotAccessDescr());\n                setupJDBCResultsView();\n\n                break;\n        }\n        \n        if (displayedPanel != null) {\n            add(displayedPanel, BorderLayout.CENTER);\n            invalidate();\n            doLayout();\n            repaint();\n        }\n        \n        listener = Lookup.getDefault().lookup(SnapshotListener.class);\n        listener.registerSnapshotResultsWindow(this);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    public static synchronized void closeAllWindows() {\n        Collection windows = windowsList.values();\n\n        if (!windows.isEmpty()) {\n            SnapshotResultsWindow[] toClose = (SnapshotResultsWindow[])windows.toArray(new SnapshotResultsWindow[0]);\n\n            for (SnapshotResultsWindow snapshotResultsWindow : toClose) {\n                snapshotResultsWindow.forcedClose();\n            }\n        }\n    }\n\n    public static synchronized void closeWindow(LoadedSnapshot snapshot) {\n        SnapshotResultsWindow win = (SnapshotResultsWindow) windowsList.get(snapshot);\n\n        if (win != null) {\n            win.forcedClose();\n        }\n    }\n\n    public static synchronized SnapshotResultsWindow get(LoadedSnapshot ls) {\n        // target component decides which column will be used for sorting\n        return SnapshotResultsWindow.get(ls, CommonConstants.SORTING_COLUMN_DEFAULT, false);\n    }\n\n    public static synchronized SnapshotResultsWindow get(LoadedSnapshot ls, int sortingColumn, boolean sortingOrder) {\n        SnapshotResultsWindow win = (SnapshotResultsWindow) windowsList.get(ls);\n\n        if (win == null) {\n            win = new SnapshotResultsWindow(ls, sortingColumn, sortingOrder);\n            windowsList.put(ls, win);\n        }\n\n        return win;\n    }\n\n    public static synchronized boolean hasSnapshotWindow(LoadedSnapshot ls) {\n        return windowsList.get(ls) != null;\n    }\n    \n    public void writeExternal(ObjectOutput out) throws IOException {\n        super.writeExternal(out);\n        \n        out.writeByte(PERSISTENCE_VERSION_MAJOR);\n        out.writeByte(PERSISTENCE_VERSION_MINOR);\n        \n        out.writeUTF(Utilities.toURI(snapshot.getFile()).toString());\n    }\n    \n    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {\n        try {\n            add(new JLabel(Bundle.SnapshotResultsWindow_LoadingProgress(), JLabel.CENTER), BorderLayout.CENTER);\n            invalidate();\n            doLayout();\n            repaint();\n            \n            super.readExternal(in);\n            \n            in.readByte(); // PERSISTENCE_VERSION_MAJOR\n            in.readByte(); // PERSISTENCE_VERSION_MINOR\n            \n            URI uri = new URI(in.readUTF());\n            final File file = Utilities.toFile(uri);\n            \n            new RequestProcessor(\"NPS loader for \" + getName()).post(new Runnable() { // NOI18N\n                public void run() {\n                    try {\n                        FileObject fileo = FileUtil.toFileObject(file);\n                        final LoadedSnapshot ls = ResultsManager.getDefault().loadSnapshot(fileo);\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                removeAll();\n                                initImpl(ls);\n                            }\n                        });\n                    } catch (Throwable t) { handleReadThrowable(t); }\n                }\n            });\n        } catch (Throwable t) { handleReadThrowable(t); }\n    }\n    \n    private void handleReadThrowable(Throwable t) {\n        ProfilerLogger.info(\"Restoring profiler snapshot failed: \" + t.getMessage()); // NOI18N\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { close(); }\n        });\n    }\n\n    public int getPersistenceType() {\n        return ProfilerIDESettings.getInstance().getReopenSnapshots() ?\n               PERSISTENCE_ONLY_OPENED : PERSISTENCE_NEVER;\n    }\n    \n    public HelpCtx getHelpCtx() {\n        return helpCtx;\n    }\n\n    public boolean canClose() {\n        if (snapshot == null) return true; // Close window when persistence fails\n        \n        // #221709, add saved snapshot to Open Recent File list\n        // Not supported for new snapshots to be saved on close\n        File file = snapshot.getFile();\n        if (file != null) putClientProperty(RECENT_FILE_KEY, file);\n            \n        if (forcedClose) {\n            savePerformer.remove();\n            return true;\n        }\n\n        if (snapshot.isSaved()) {\n            return true; // already saved\n        }\n\n        Boolean ret = ProfilerDialogs.displayCancellableConfirmationDNSA(Bundle.SnapshotResultsWindow_SaveSnapshotDialogMsg(),\n                null, null, \"org.graalvm.visualvm.lib.profiler.SnapshotResultsWindow.canClose\", false); // NOI18N\n\n        if (Boolean.TRUE.equals(ret)) {\n            try {\n                savePerformer.save();\n            } catch (IOException ex) {\n                Exceptions.printStackTrace(ex);\n            }\n            return true;\n        } else if (Boolean.FALSE.equals(ret)) {\n            // clean up to avoid being held in memory\n            savePerformer.remove();\n            return true;\n        } else {\n            return false;\n        }\n    }\n    \n    protected Component defaultFocusOwner() {\n        return displayedPanel == null ? this : displayedPanel;\n    }\n    \n    public void refreshTabName() {\n        tabName = ResultsManager.getDefault().getSnapshotDisplayName(snapshot);\n        File snapshotFile = snapshot.getFile();\n        if (snapshotFile != null) setToolTipText(snapshotFile.getAbsolutePath());\n        updateTitle();\n    }\n\n    public void updateTitle() {\n        if (snapshot.isSaved()) {\n            setName(tabName);\n        } else {\n            // XXX consider using DataEditorSupport.annotateName\n            setName(tabName + \" *\"); // NOI18N\n        }\n        // Called when snapshot is saved, update also tooltip\n        if (snapshot.getFile() != null)\n            setToolTipText(snapshot.getFile().getAbsolutePath());\n    }\n\n    protected void componentClosed() {\n        if (snapshot == null) return; // Window closed after persistence failure\n        \n        synchronized (SnapshotResultsWindow.class) {\n            windowsList.remove(snapshot);\n        }\n\n        ResultsManager.getDefault().closeSnapshot(snapshot);\n        snapshot = null;\n        listener.unregisterSnapshotResultsWindow(this);\n    }\n\n    protected String preferredID() {\n        return this.getClass().getName();\n    }\n    // -------------------------------------------------------------------------\n    \n    \n    // --- Internal \"API\" ------------------------------------------------------\n    \n    boolean setRefSnapshot(LoadedSnapshot ls) {\n        ResultsSnapshot s = ls == null ? null : ls.getSnapshot();\n        \n        if (displayedPanel instanceof SnapshotCPUView && s instanceof CPUResultsSnapshot) {\n            ((SnapshotCPUView)displayedPanel).setRefSnapshot((CPUResultsSnapshot)s);\n            return true;\n        } else if (displayedPanel instanceof SnapshotMemoryView && s instanceof MemoryResultsSnapshot) {\n            ((SnapshotMemoryView)displayedPanel).setRefSnapshot((MemoryResultsSnapshot)s);\n            return true;\n        } else if (displayedPanel instanceof SnapshotJDBCView && s instanceof JdbcResultsSnapshot) {\n            ((SnapshotJDBCView)displayedPanel).setRefSnapshot((JdbcResultsSnapshot)s);\n            return true;\n        }\n        \n        return false;\n    }\n\n    \n    // -- Private methods --------------------------------------------------------------------------------------------------\n\n    private void setupCPUResultsView() {\n        ResultsSnapshot _snapshot = snapshot.getSnapshot();\n        if (_snapshot instanceof CPUResultsSnapshot) {\n            CPUResultsSnapshot s = (CPUResultsSnapshot)_snapshot;\n            boolean sampling = snapshot.getSettings().getCPUProfilingType() == CommonConstants.CPU_SAMPLED;\n            \n            SaveSnapshotAction aSave = new SaveSnapshotAction(snapshot);\n            CompareSnapshotsAction aCompare = new CompareSnapshotsAction(snapshot);\n            SnapshotInfoAction aInfo = new SnapshotInfoAction(snapshot);\n            ExportUtils.Exportable exporter = ResultsManager.getDefault().createSnapshotExporter(snapshot);\n            \n            final SnapshotCPUView _cpuSnapshot = new SnapshotCPUView(s, sampling, aSave, aCompare, aInfo, exporter) {\n                protected boolean showSourceSupported() {\n                    return GoToSource.isAvailable();\n                }\n                protected boolean profileMethodSupported() {\n                    return ProfilerFeature.Registry.hasProviders();\n                }\n                protected boolean profileClassSupported() {\n                    return ProfilerFeature.Registry.hasProviders();\n                }\n                protected void showSource(ClientUtils.SourceCodeSelection value) {\n                    Lookup.Provider project = snapshot.getProject();\n                    String className = value.getClassName();\n                    String methodName = value.getMethodName();\n                    String methodSig = value.getMethodSignature();\n                    GoToSource.openSource(project, className, methodName, methodSig);\n                }\n                protected void selectForProfiling(final ClientUtils.SourceCodeSelection value) {\n                    RequestProcessor.getDefault().post(new Runnable() {\n                        public void run() {\n                            Lookup.Provider project = snapshot.getProject();\n                            String name = Wildcards.ALLWILDCARD.equals(value.getMethodName()) ?\n                                          Bundle.SnapshotResultsWindow_ProfileClass() :\n                                          Bundle.SnapshotResultsWindow_ProfileMethod();\n                            ProfilerSession.findAndConfigure(Lookups.fixed(value), project, name);\n                        }\n                    });\n                }\n            };\n            \n            aCompare.setPerformer(new CompareSnapshotsAction.Performer() {\n                public void compare(LoadedSnapshot snapshot) {\n                    _cpuSnapshot.setRefSnapshot((CPUResultsSnapshot)snapshot.getSnapshot());\n                }\n            });\n            \n            registerActions(_cpuSnapshot);\n            displayedPanel = _cpuSnapshot;\n        }\n    }\n\n//    private void displayCodeRegionResults(LoadedSnapshot ls) {\n//        FragmentSnapshotPanel codeRegionPanel = new FragmentSnapshotPanel(ls);\n//        displayedPanel = codeRegionPanel;\n//        add(codeRegionPanel, BorderLayout.CENTER);\n//        setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));\n//        setIcon(WINDOWS_ICON_FRAGMENT);\n//    }\n\n    private void setupMemoryResultsView() {\n        ResultsSnapshot _snapshot = snapshot.getSnapshot();\n        if (_snapshot instanceof MemoryResultsSnapshot) {\n            GenericFilter filter = snapshot.getSettings().getInstrumentationFilter();\n            if (filter != null && filter.isEmpty()) filter = null;\n            \n            MemoryResultsSnapshot s = (MemoryResultsSnapshot)_snapshot;\n            \n            SaveSnapshotAction aSave = new SaveSnapshotAction(snapshot);\n            CompareSnapshotsAction aCompare = new CompareSnapshotsAction(snapshot);\n            SnapshotInfoAction aInfo = new SnapshotInfoAction(snapshot);\n            ExportUtils.Exportable exporter = ResultsManager.getDefault().createSnapshotExporter(snapshot);\n            \n            final SnapshotMemoryView _memorySnapshot = new SnapshotMemoryView(s, filter, aSave, aCompare, aInfo, exporter) {\n                protected boolean showSourceSupported() {\n                    return GoToSource.isAvailable();\n                }\n                protected boolean profileMethodSupported() {\n                    return ProfilerFeature.Registry.hasProviders();\n                }\n                protected boolean profileClassSupported() {\n                    return ProfilerFeature.Registry.hasProviders();\n                }\n                protected void showSource(ClientUtils.SourceCodeSelection value) {\n                    Lookup.Provider project = snapshot.getProject();\n                    String className = value.getClassName();\n                    String methodName = value.getMethodName();\n                    String methodSig = value.getMethodSignature();\n                    GoToSource.openSource(project, className, methodName, methodSig);\n                }\n                protected void selectForProfiling(final ClientUtils.SourceCodeSelection value) {\n                    RequestProcessor.getDefault().post(new Runnable() {\n                        public void run() {\n                            Lookup.Provider project = snapshot.getProject();\n                            ProfilerSession.findAndConfigure(Lookups.fixed(value), project, Bundle.SnapshotResultsWindow_ProfileClass());\n                        }\n                    });\n                }\n            };\n            \n            aCompare.setPerformer(new CompareSnapshotsAction.Performer() {\n                public void compare(LoadedSnapshot snapshot) {\n                    _memorySnapshot.setRefSnapshot((MemoryResultsSnapshot)snapshot.getSnapshot());\n                }\n            });\n            \n            registerActions(_memorySnapshot);\n            displayedPanel = _memorySnapshot;\n        }\n    }\n    \n    private void setupJDBCResultsView() {\n        ResultsSnapshot _snapshot = snapshot.getSnapshot();\n        if (_snapshot instanceof JdbcResultsSnapshot) {\n            JdbcResultsSnapshot s = (JdbcResultsSnapshot)_snapshot;\n            \n            SaveSnapshotAction aSave = new SaveSnapshotAction(snapshot);\n            CompareSnapshotsAction aCompare = new CompareSnapshotsAction(snapshot);\n            SnapshotInfoAction aInfo = new SnapshotInfoAction(snapshot);\n            ExportUtils.Exportable exporter = ResultsManager.getDefault().createSnapshotExporter(snapshot);\n            \n            final SnapshotJDBCView _jdbcSnapshot = new SnapshotJDBCView(s, aSave, aCompare, aInfo, exporter) {\n                protected boolean showSourceSupported() {\n                    return GoToSource.isAvailable();\n                }\n                protected void showSource(ClientUtils.SourceCodeSelection value) {\n                    Lookup.Provider project = snapshot.getProject();\n                    String className = value.getClassName();\n                    String methodName = value.getMethodName();\n                    String methodSig = value.getMethodSignature();\n                    GoToSource.openSource(project, className, methodName, methodSig);\n                }\n                protected void showSQLQuery(String query, String htmlQuery) {\n                    HTMLTextArea area = new HTMLTextArea(htmlQuery);\n                    JScrollPane areaScroll = new JScrollPane(area);\n                    areaScroll.setPreferredSize(new Dimension(500, 250));\n                    JLabel label = new JLabel(Bundle.SnapshotResultsWindow_SqlQueryLabel(), JLabel.LEADING);\n                    label.setBorder(BorderFactory.createEmptyBorder(0, 0, 3, 0));\n                    label.setLabelFor(area);\n                    JPanel panel = new JPanel(new BorderLayout());\n                    panel.add(label, BorderLayout.NORTH);\n                    panel.add(areaScroll, BorderLayout.CENTER);\n                    panel.setBorder(BorderFactory.createEmptyBorder(12, 10, 0, 10));\n                    HelpCtx help = new HelpCtx(\"SqlQueryViewer.HelpCtx\"); // NOI18N\n                    DialogDisplayer.getDefault().notify(new DialogDescriptor(panel,\n                            Bundle.SnapshotResultsWindow_SqlQueryCaption(), false,\n                            new Object[] { DialogDescriptor.CLOSED_OPTION },\n                            DialogDescriptor.CLOSED_OPTION, DialogDescriptor.BOTTOM_ALIGN, help, null));\n                }\n                protected void selectForProfiling(final ClientUtils.SourceCodeSelection value) {\n                    RequestProcessor.getDefault().post(new Runnable() {\n                        public void run() {\n                            Lookup.Provider project = snapshot.getProject();\n                            String name = Wildcards.ALLWILDCARD.equals(value.getMethodName()) ?\n                                          Bundle.SnapshotResultsWindow_ProfileClass() :\n                                          Bundle.SnapshotResultsWindow_ProfileMethod();\n                            ProfilerSession.findAndConfigure(Lookups.fixed(value), project, name);\n                        }\n                    });\n                }\n            };\n            \n            aCompare.setPerformer(new CompareSnapshotsAction.Performer() {\n                public void compare(LoadedSnapshot snapshot) {\n                    _jdbcSnapshot.setRefSnapshot((JdbcResultsSnapshot)snapshot.getSnapshot());\n                }\n            });\n            \n            registerActions(_jdbcSnapshot);\n            displayedPanel = _jdbcSnapshot;\n        }\n    }\n\n    private void forcedClose() {\n        forcedClose = true;\n        close();\n    }\n    \n    private void registerActions(final JComponent view) {\n        InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        ActionMap actionMap = getActionMap();\n        \n        final String filterKey = FilterUtils.FILTER_ACTION_KEY;\n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                Action action = view.getActionMap().get(filterKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);\n        \n        final String findKey = SearchUtils.FIND_ACTION_KEY;\n        Action findAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                Action action = view.getActionMap().get(findKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(findKey, findAction, actionMap, inputMap);\n    }\n\n    private void updateSaveState() {\n        if (snapshot != null) { // snapshot == null means the window has been closed (#202992)\n            if (snapshot.isSaved()) {\n                savePerformer.remove();\n            } else {\n                savePerformer.add();\n            }\n\n//            if (displayedPanel != null) {\n//                displayedPanel.updateSavedState();\n//            }\n        } else {\n            // just to be sure\n            savePerformer.remove();\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/SnapshotsListener.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler;\n\n\n/** A listener for results manager changes\n *\n * @author Tomas Hurka\n * @author Ian Formanek\n */\npublic interface SnapshotsListener {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /** Called when a snapshot has been loaded. */\n    public void snapshotLoaded(LoadedSnapshot snapshot);\n\n    /** Called when a snapshot has been removed/deleted. */\n    public void snapshotRemoved(LoadedSnapshot snapshot);\n\n    /** Called when a snapshot has been saved. */\n    public void snapshotSaved(LoadedSnapshot snapshot);\n\n    /** Called when a new snapshot has been taken */\n    public void snapshotTaken(LoadedSnapshot snapshot);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/ThreadDumpWindow.java",
    "content": "/*\n * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.lang.management.LockInfo;\nimport java.lang.management.MonitorInfo;\nimport java.lang.management.ThreadInfo;\nimport java.net.URL;\nimport java.text.SimpleDateFormat;\nimport java.util.Arrays;\nimport javax.swing.BorderFactory;\nimport javax.swing.JScrollPane;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.Document;\nimport javax.swing.text.Segment;\nimport javax.swing.text.html.HTMLDocument;\nimport javax.swing.text.html.HTMLEditorKit;\nimport javax.swing.text.html.StyleSheet;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadDump;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.jfluid.utils.StringUtils;\nimport static org.graalvm.visualvm.lib.profiler.SampledCPUSnapshot.OPEN_THREADS_URL;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.TopComponent;\n\n/**\n * IDE topcomponent to display thread dump.\n *\n * @author Tomas Hurka\n */\n@NbBundle.Messages({\n    \"ThreadDumpWindow_Caption=Thread dump {0}\",})\npublic class ThreadDumpWindow extends ProfilerTopComponent {\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n    private static final String HELP_CTX_KEY = \"ThreadDumpWindow.HelpCtx\"; // NOI18N\n    private static final HelpCtx HELP_CTX = new HelpCtx(HELP_CTX_KEY);\n\n\n    private HTMLTextArea a;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n    /**\n     * This constructor cannot be called, instances of this window cannot be\n     * persisted.\n     */\n    public ThreadDumpWindow() {\n        throw new InternalError(\"This constructor should never be called\"); // NOI18N\n    }\n\n    public ThreadDumpWindow(ThreadDump td) {\n        setLayout(new BorderLayout());\n        setFocusable(true);\n        setRequestFocusEnabled(true);\n        setName(Bundle.ThreadDumpWindow_Caption(StringUtils.formatUserDate(td.getTime())));\n        setIcon(Icons.getImage(ProfilerIcons.THREAD));\n\n        StringBuilder text = new StringBuilder();\n        printThreads(text, td);\n        a = new HTMLTextArea() {\n            protected void showURL(URL url) {\n                if (url == null) {\n                    return;\n                }\n                String urls = url.toString();\n                ThreadDumpWindow.this.showURL(urls);\n            }\n        };\n        a.setEditorKit(new CustomHtmlEditorKit());\n        a.setText(text.toString());\n        a.setCaretPosition(0);\n        JScrollPane sp = new JScrollPane(a);\n        sp.setBorder(BorderFactory.createEmptyBorder());\n        sp.setViewportBorder(BorderFactory.createEmptyBorder());\n        add(sp, BorderLayout.CENTER);\n    }\n    \n    protected Component defaultFocusOwner() {\n        return a;\n    }\n\n    public int getPersistenceType() {\n        return TopComponent.PERSISTENCE_NEVER;\n    }\n\n    public HelpCtx getHelpCtx() {\n        return HELP_CTX;\n    }\n\n    protected String preferredID() {\n        return this.getClass().getName();\n    }\n\n    private void printThreads(final StringBuilder sb, ThreadDump td) {\n        ThreadInfo[] threads = td.getThreads();\n        boolean goToSourceAvailable = GoToSource.isAvailable();\n        boolean jdk15 = td.isJDK15();\n\n        sb.append(\"<pre>\"); // NOI18N\n        sb.append(\" <b>Full thread dump: \"); // NOI18N\n        SimpleDateFormat df = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");  // NOI18N\n        sb.append(df.format(td.getTime()) + \"</b><br><br>\");\n        for (ThreadInfo thread : threads) {\n            if (thread != null) {\n                if (jdk15) {\n                    print15Thread(sb, thread, goToSourceAvailable);\n                } else {\n                    print16Thread(sb, thread, goToSourceAvailable);\n                }\n            }\n        }\n        sb.append(\"</pre>\"); // NOI18N\n    }\n\n    private void print15Thread(final StringBuilder sb, final ThreadInfo thread, boolean goToSourceAvailable) {\n        sb.append(\"<br>\\\"\" + thread.getThreadName() + // NOI18N\n                \"\\\" - Thread t@\" + thread.getThreadId() + \"<br>\");    // NOI18N\n        sb.append(\"   java.lang.Thread.State: \" + thread.getThreadState()); // NOI18N\n        if (thread.getLockName() != null) {\n            sb.append(\" on \" + thread.getLockName());   // NOI18N\n            if (thread.getLockOwnerName() != null) {\n                sb.append(\" owned by: \" + thread.getLockOwnerName());   // NOI18N\n            }\n        }\n        sb.append(\"<br>\");    // NOI18N\n        for (StackTraceElement st : thread.getStackTrace()) {\n            String stackElementText = htmlize(st.toString());\n            String stackEl = stackElementText;\n            if (goToSourceAvailable) {\n                String className = st.getClassName();\n                String method = st.getMethodName();\n                int lineNo = st.getLineNumber();\n                String stackUrl = OPEN_THREADS_URL + className + \"|\" + method + \"|\" + lineNo; // NOI18N\n                stackEl = \"<a href=\\\"\" + stackUrl + \"\\\">\" + stackElementText + \"</a>\";    // NOI18N\n            }\n            sb.append(\"        at \").append(stackEl).append(\"<br>\");    // NOI18N\n        }\n    }\n\n    private void print16Thread(final StringBuilder sb, final ThreadInfo thread, boolean goToSourceAvailable) {\n        MonitorInfo[] monitors = thread.getLockedMonitors();\n        sb.append(\"&nbsp;<b>\");   // NOI18N\n        sb.append(\"\\\"\").append(thread.getThreadName()).append(\"\\\" - Thread t@\").append(thread.getThreadId()).append(\"<br>\");    // NOI18N\n        sb.append(\"    java.lang.Thread.State: \").append(thread.getThreadState()); // NOI18N\n        sb.append(\"</b><br>\");   // NOI18N\n        int index = 0;\n        for (StackTraceElement st : thread.getStackTrace()) {\n            LockInfo lock = thread.getLockInfo();\n            String stackElementText = htmlize(st.toString());\n            String lockOwner = thread.getLockOwnerName();\n\n            String stackEl = stackElementText;\n            if (goToSourceAvailable) {\n                String className = st.getClassName();\n                String method = st.getMethodName();\n                int lineNo = st.getLineNumber();\n                String stackUrl = OPEN_THREADS_URL + className + \"|\" + method + \"|\" + lineNo; // NOI18N\n                stackEl = \"<a href=\\\"\" + stackUrl + \"\\\">\" + stackElementText + \"</a>\";    // NOI18N\n            }\n\n            sb.append(\"    at \").append(stackEl).append(\"<br>\");    // NOI18N\n            if (index == 0) {\n                if (\"java.lang.Object\".equals(st.getClassName()) && // NOI18N\n                        \"wait\".equals(st.getMethodName())) {                // NOI18N\n                    if (lock != null) {\n                        sb.append(\"    - waiting on \");    // NOI18N\n                        printLock(sb, lock);\n                        sb.append(\"<br>\");    // NOI18N\n                    }\n                } else if (lock != null) {\n                    if (lockOwner == null) {\n                        sb.append(\"    - parking to wait for \");      // NOI18N\n                        printLock(sb, lock);\n                        sb.append(\"<br>\");            // NOI18N\n                    } else {\n                        sb.append(\"    - waiting to lock \");      // NOI18N\n                        printLock(sb, lock);\n                        sb.append(\" owned by \\\"\").append(lockOwner).append(\"\\\" t@\").append(thread.getLockOwnerId()).append(\"<br>\");   // NOI18N\n                    }\n                }\n            }\n            printMonitors(sb, monitors, index);\n            index++;\n        }\n        StringBuilder jnisb = new StringBuilder();\n        printMonitors(jnisb, monitors, -1);\n        if (jnisb.length() > 0) {\n            sb.append(\"   JNI locked monitors:<br>\");\n            sb.append(jnisb);\n        }\n        LockInfo[] synchronizers = thread.getLockedSynchronizers();\n        if (synchronizers != null) {\n            sb.append(\"<br>   Locked ownable synchronizers:\");    // NOI18N\n            if (synchronizers.length == 0) {\n                sb.append(\"<br>    - None\\n\");  // NOI18N\n            } else {\n                for (LockInfo li : synchronizers) {\n                    sb.append(\"<br>    - locked \");         // NOI18N\n                    printLock(sb, li);\n                    sb.append(\"<br>\");  // NOI18N\n                }\n            }\n        }\n        sb.append(\"<br>\");\n    }\n\n    private void printMonitors(final StringBuilder sb, final MonitorInfo[] monitors, final int index) {\n        if (monitors != null) {\n            for (MonitorInfo mi : monitors) {\n                if (mi.getLockedStackDepth() == index) {\n                    sb.append(\"    - locked \");   // NOI18N\n                    printLock(sb, mi);\n                    sb.append(\"<br>\");    // NOI18N\n                }\n            }\n        }\n    }\n\n    private void printLock(StringBuilder sb, LockInfo lock) {\n        String id = Integer.toHexString(lock.getIdentityHashCode());\n        String className = lock.getClassName();\n\n        sb.append(\"&lt;\").append(id).append(\"&gt; (a \").append(className).append(\")\");       // NOI18N\n    }\n\n    private static String htmlize(String value) {\n        return value.replace(\">\", \"&gt;\").replace(\"<\", \"&lt;\");     // NOI18N\n    }\n\n    private void showURL(String urls) {\n        if (urls.startsWith(SampledCPUSnapshot.OPEN_THREADS_URL)) {\n            urls = urls.substring(SampledCPUSnapshot.OPEN_THREADS_URL.length());\n            String parts[] = urls.split(\"\\\\|\"); // NOI18N\n            String className = parts[0];\n            String method = parts[1];\n            int linenumber = Integer.parseInt(parts[2]);\n            GoToSource.openSource(null, className, method, linenumber);\n        }\n    }\n\n    private static class CustomHtmlEditorKit extends HTMLEditorKit {\n\n        @Override\n        public Document createDefaultDocument() {\n            StyleSheet styles = getStyleSheet();\n            StyleSheet ss = new StyleSheet();\n\n            ss.addStyleSheet(styles);\n\n            HTMLDocument doc = new CustomHTMLDocument(ss);\n            doc.setParser(getParser());\n            doc.setAsynchronousLoadPriority(4);\n            doc.setTokenThreshold(100);\n            return doc;\n        }\n    }\n\n    private static class CustomHTMLDocument extends HTMLDocument {\n\n        private static final int CACHE_BOUNDARY = 1000;\n        private char[] segArray;\n        private int segOffset;\n        private int segCount;\n        private boolean segPartialReturn;\n        private int lastOffset;\n        private int lastLength;\n\n        private CustomHTMLDocument(StyleSheet ss) {\n            super(ss);\n            lastOffset = -1;\n            lastLength = -1;\n            putProperty(\"multiByte\", Boolean.TRUE);      // NOI18N\n        }\n\n        @Override\n        public void getText(int offset, int length, Segment txt) throws BadLocationException {\n            if (lastOffset == offset && lastLength == length) {\n                txt.array = segArray;\n                txt.offset = segOffset;\n                txt.count = segCount;\n                txt.setPartialReturn(segPartialReturn);\n                return;\n            }\n            super.getText(offset, length, txt);\n            if (length > CACHE_BOUNDARY || lastLength <= CACHE_BOUNDARY) {\n                segArray = Arrays.copyOf(txt.array, txt.array.length);\n                segOffset = txt.offset;\n                segCount = txt.count;\n                segPartialReturn = txt.isPartialReturn();\n                lastOffset = offset;\n                lastLength = length;\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/AttachAction.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n\n/**\n * Action to start profiler attach\n *\n * @author Ian Formanek\n */\n@NbBundle.Messages({\n    \"LBL_AttachAction=Attach to &External Process\",\n    \"HINT_AttachAction=Attach to External Process\"\n})\npublic final class AttachAction extends AbstractAction {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    final private static class Singleton {\n        final private static AttachAction INSTANCE = new AttachAction();\n    }\n\n    private AttachAction() {\n        putValue(Action.NAME, Bundle.LBL_AttachAction());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.HINT_AttachAction());\n    }\n\n    public static AttachAction getInstance() {\n        return Singleton.INSTANCE;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Invoked when an action occurs.\n     */\n    public void actionPerformed(final ActionEvent e) {\n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() {\n                ProfilerSession session = ProfilerSession.forContext(Lookup.EMPTY);\n                if (session != null) {\n                    session.setAttach(true);\n                    session.open();\n                }\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n## Resource bundle for package org.graalvm.visualvm.lib.profiler.actions\n#Mon May 03 18:59:38 CEST 2004\n\nAdvancedOption_DisplayName=EntityBean Profiler Settings\nAdvancedOption_Tooltip=Customize the profiling settings\n\n# {0} - # of selected projects (0 if disabled), or -1 if main project\n# {1} - project name, if exactly one project\nLBL_ProfileMainProjectAction=&Profile {0,choice,-1#Main Project|0#Project|1#Project ({1})|1<{0} Projects}\nHINT_ProfileMainProjectAction=Profile (Main) Project\nLBL_AttachProjectAction=Attach Profiler Using Project {0,choice,0#|1#\"{1}\"|1<}\n\nLBL_ProfileAction=Profile...\nHINT_ProfileAction=Profile...\nLBL_ProfileAction_40=Profile File...\nHINT_ProfileAction_40=Profile File...\nLBL_ProfileSingleAction40=Pro&file {0,choice,0#File|1#\"{1}\"|1<File}\nLBL_ProfileSingleAction40_General=Profile File\nLBL_ProfileSingleActionPopup=Profile File\n# new\nLBL_EnableProfilingPopup=Enable Profiling\n# end\nLBL_ProfileTestAction=Profile {0,choice,0#&Test for File|1#&Test for \"{1}\"|1<&Test for Files}\nLBL_ProfileTestAction_General=Profile Test for File\nLBL_ProfileProjectAction40=Profile &Project {0,choice,0#|1#\"{1}\"|1<}\nLBL_ProfileProjectAction40_General=Profile Project\nLBL_ProfileProjectActionPopup=Profile\n\nMenu/Profile=&Profile\nMenu/Profile/View=&View\nMenu/Profile/Advanced=A&dvanced Commands\nMenu/Profile/Help=&Help\nMenu/Window/Profile=Profilin&g\nMenu/Profile/Help/profiler-website.url=Profiler Project &Website...\nMenu/Profile/Help/nb-log-file.url=NetBeans Lo&g File\nToolbars/Profile=Profile\nActions/Profile/profiler-website.url=Profiler Project Website\nActions/Profile=Profile\nEditors/text/x-java/Popup/Profile=Profile\n\nMSG_NoMainMethod=Cannot start profiling.\\nSelected class does not contain the \"main\" method.\nMSG_CannotFindHelp=Cannot find Profiler help\nMSG_CannotFindHelpFile=Cannot find Profiler help file\\:\\n{0}\nMSG_CannotFindWhatsNew=Cannot find What's New file\\:\\n{0}\nMSG_CannotAddAbstractNativeCodeFragment=Cannot add code fragment from an abstract or native method.\nMSG_NoClassToProfile=No class to profile\n\nMSG_ProblemSelectingRootMethods=Cannot get list of methods for selected item. This can happen for items placed in directory other than project sources directory (typically /src and /web). If so, please select appropriate item in project sources directory.\nMSG_ProblemAddingCodeFragment=Cannot add selected method as a code fragment. This can happen for items placed in directory other than project sources directory (typically /src and /web). If so, please select appropriate item in project sources directory.\nMSG_StartingProfiler=Starting Profiler\nMSG_CollectingCategories=Collecting categories. Please wait.\n\nSelfSamplerAction_ActionNameStart=Start sampling IDE\nSelfSamplerAction_ActionNameStop=Stop sampling and take snapshot\nSelfSamplerAction_ActionDescription=Will take a snapshot based on the thread dump\nSelfSamplerAction_ThreadName=IDE Self Sampler\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/CompareSnapshotsAction.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.profiler.*;\nimport org.openide.DialogDescriptor;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.NbBundle;\nimport java.awt.*;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.ItemListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.io.File;\nimport javax.swing.*;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.filechooser.FileFilter;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.ui.NBSwingWorker;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.ActionID;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\nimport org.openide.windows.WindowManager;\n\n@NbBundle.Messages({\n    \"CompareSnapshotsAction_ActionName=&Compare Snapshots...\",\n    \"CompareSnapshotsAction_ActionDescr=Computes the difference between two comparable snapshots\",\n    \"CompareSnapshotsAction_SelectSnapshotDialogCaption=Select Snapshot to Compare\",\n    \"CompareSnapshotsAction_SelectSnapshotsDialogCaption=Select Snapshots to Compare\",\n    \"CompareSnapshotsAction_OpenChooserCaption=Open Snapshot\",\n    \"CompareSnapshotsAction_OpenChooserFilter=Profiler Snapshot File (*.{0})\",\n    \"CompareSnapshotsAction_NoComparableSnapshotsFoundMsg=<No comparable snapshots found>\",\n    \"CompareSnapshotsAction_ComparingSameSnapshotsMsg=The snapshot cannot be compared to itself.\",\n    \"CompareSnapshotsAction_DifferentSnapshotsTypeMsg=Snapshots must be of same type.\",\n    \"CompareSnapshotsAction_OnlyMemorySnapshotsMsg=Only memory snapshots can be compared!\",\n    \"CompareSnapshotsAction_DifferentObjectsCountsMsg=\\\"Track every N object allocations\\\" values don't match!\",\n    \"CompareSnapshotsAction_InvalidFileMsg=Invalid snapshot file\",\n    \"CompareSnapshotsAction_InvalidFilesMsg=Invalid snapshot file(s)\",\n    \"CompareSnapshotsAction_EnterFileMsg=Enter snapshot file\",\n    \"CompareSnapshotsAction_OkButtonText=OK\",\n    \"CompareSnapshotsAction_SelectSnapshotString=<html><b><nobr>Select snapshot to compare:</nobr></b></html>\",\n    \"CompareSnapshotsAction_SelectSnapshotsString=Specify snapshots you want to compare\",\n    \"CompareSnapshotsAction_FromProjectRadioText=From &project:\",\n    \"CompareSnapshotsAction_OnlyComparableListedString=Note: only comparable snapshots are listed\",\n    \"CompareSnapshotsAction_FromFileRadioText=From &file:\",\n    \"CompareSnapshotsAction_FromCurrentLocationRadioText=From &current location:\",\n    \"CompareSnapshotsAction_BrowseButtonText=&Browse...\",\n    \"CompareSnapshotsAction_Browse2ButtonText=B&rowse...\",\n    \"CompareSnapshotsAction_BrowseButtonAccessDescr=Select snapshot file\",\n    \"CompareSnapshotsAction_Snapshot1String=Snapshot &1:\",\n    \"CompareSnapshotsAction_Snapshot2String=Snapshot &2:\",\n    \"CompareSnapshotsAction_SnapshotAccessDescr=Selected snapshot file\",\n    \"CompareSnapshotsAction_SnapshotsListAccessDescr=List of comparable snapshots in current project\"\n})\n@ActionID(id = \"org.graalvm.visualvm.lib.profiler.actions.CompareSnapshotsAction\", category = \"Profile\")\n//@ActionRegistration(iconInMenu = true, displayName = \"#CompareSnapshotsAction_ActionName\", iconBase = \"org/graalvm/visualvm/lib/profiler/impl/icons/compareSnapshots.png\")\n//@ActionReference(path = \"Menu/Profile\", position = 1600, separatorAfter=1700)\npublic class CompareSnapshotsAction extends AbstractAction {\n    //~ Static fields/initializers -------------------------------------------------------------------------------------------\n        private static final HelpCtx EXTERNAL_SNAPSHOT_HELP_CTX = new HelpCtx(\"SelectExternalSnapshotsPanel.HelpCtx\"); // NOI18N\n        private static final HelpCtx SECOND_SNAPSHOT_HELP_CTX = new HelpCtx(\"SelectSecondSnapshotPanel.HelpCtx\"); // NOI18N\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private static class SelectExternalSnapshotsPanel extends JPanel implements HelpCtx.Provider {\n            \n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private JButton okButton;\n        private JButton snapshot1Button;\n        private JButton snapshot2Button;\n        private JLabel hintLabel;\n        private JLabel snapshot1Label;\n        private JLabel snapshot2Label;\n        private JTextField snapshot1Field;\n        private JTextField snapshot2Field;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        SelectExternalSnapshotsPanel() {\n            initComponents();\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        @Override\n        public HelpCtx getHelpCtx() {\n            return EXTERNAL_SNAPSHOT_HELP_CTX;\n        }        \n        \n        public JButton getOKButton() {\n            return okButton;\n        }\n\n        public String getSnapshot1Filename() {\n            return snapshot1Field.getText();\n        }\n\n        public String getSnapshot2Filename() {\n            return snapshot2Field.getText();\n        }\n\n        private void initComponents() {\n            okButton = new JButton(Bundle.CompareSnapshotsAction_OkButtonText());\n\n            setLayout(new GridBagLayout());\n\n            GridBagConstraints c;\n\n            snapshot1Label = new JLabel();\n            org.openide.awt.Mnemonics.setLocalizedText(snapshot1Label, Bundle.CompareSnapshotsAction_Snapshot1String());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 0;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(15, 10, 5, 5);\n            add(snapshot1Label, c);\n\n            snapshot1Field = new JTextField();\n            snapshot1Field.setPreferredSize(new Dimension(250, snapshot1Field.getPreferredSize().height));\n            snapshot1Label.setLabelFor(snapshot1Field);\n            snapshot1Field.getAccessibleContext().setAccessibleDescription(Bundle.CompareSnapshotsAction_SnapshotAccessDescr());\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = 0;\n            c.weightx = 1.0d;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(15, 5, 5, 5);\n            add(snapshot1Field, c);\n\n            snapshot1Button = new JButton();\n            org.openide.awt.Mnemonics.setLocalizedText(snapshot1Button, Bundle.CompareSnapshotsAction_BrowseButtonText());\n            snapshot1Button.getAccessibleContext().setAccessibleDescription(Bundle.CompareSnapshotsAction_BrowseButtonAccessDescr());\n            c = new GridBagConstraints();\n            c.gridx = 2;\n            c.gridy = 0;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(15, 5, 5, 10);\n            add(snapshot1Button, c);\n\n            snapshot2Label = new JLabel();\n            org.openide.awt.Mnemonics.setLocalizedText(snapshot2Label, Bundle.CompareSnapshotsAction_Snapshot2String());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 1;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(5, 10, 5, 5);\n            add(snapshot2Label, c);\n\n            snapshot2Field = new JTextField();\n            snapshot2Field.setPreferredSize(new Dimension(250, snapshot2Field.getPreferredSize().height));\n            snapshot2Label.setLabelFor(snapshot2Field);\n            snapshot2Field.getAccessibleContext().setAccessibleDescription(Bundle.CompareSnapshotsAction_SnapshotAccessDescr());\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = 1;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(5, 5, 5, 5);\n            add(snapshot2Field, c);\n\n            snapshot2Button = new JButton();\n            org.openide.awt.Mnemonics.setLocalizedText(snapshot2Button, Bundle.CompareSnapshotsAction_Browse2ButtonText());\n            snapshot2Button.getAccessibleContext().setAccessibleDescription(Bundle.CompareSnapshotsAction_BrowseButtonAccessDescr());\n            c = new GridBagConstraints();\n            c.gridx = 2;\n            c.gridy = 1;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(5, 5, 5, 10);\n            add(snapshot2Button, c);\n\n            hintLabel = new JLabel(\" \"); // NOI18N\n            hintLabel.setForeground(Color.darkGray);\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = 2;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(5, 5, 5, 10);\n            add(hintLabel, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 3;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.weighty = 1.0d;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.fill = GridBagConstraints.BOTH;\n            add(new JPanel(new FlowLayout(0, 0, FlowLayout.LEADING)), c);\n\n            DocumentListener documentListener = new DocumentListener() {\n                public void insertUpdate(DocumentEvent e) {\n                    updateOKButton();\n                }\n\n                public void removeUpdate(DocumentEvent e) {\n                    updateOKButton();\n                }\n\n                public void changedUpdate(DocumentEvent e) {\n                    updateOKButton();\n                }\n            };\n\n            snapshot1Field.getDocument().addDocumentListener(documentListener);\n            snapshot2Field.getDocument().addDocumentListener(documentListener);\n\n            snapshot1Button.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        JFileChooser snapshotChooser = CompareSnapshotsAction.getSnapshotFileChooser();\n                        snapshotChooser.setCurrentDirectory(new File(getSnapshot1Filename()));\n\n                        if (snapshotChooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == 0) {\n                            File file = snapshotChooser.getSelectedFile();\n\n                            if (file != null) {\n                                snapshot1Field.setText(file.getAbsolutePath());\n                            }\n                        }\n                    }\n                });\n\n            snapshot2Button.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        JFileChooser snapshotChooser = CompareSnapshotsAction.getSnapshotFileChooser();\n                        snapshotChooser.setCurrentDirectory(new File(getSnapshot2Filename().isEmpty()\n                                                                     ? getSnapshot1Filename() : getSnapshot2Filename()));\n\n                        if (snapshotChooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == 0) {\n                            File file = snapshotChooser.getSelectedFile();\n\n                            if (file != null) {\n                                snapshot2Field.setText(file.getAbsolutePath());\n                            }\n                        }\n                    }\n                });\n\n            updateOKButton();\n        }\n\n        private void updateOKButton() {\n            String s1f = getSnapshot1Filename();\n            String s2f = getSnapshot2Filename();\n\n            if (!s1f.isEmpty() && !s2f.isEmpty()) {\n                // filenames not empty string\n                final File s1 = new File(s1f);\n                final File s2 = new File(s2f);\n\n                if (s1.exists() && s1.isFile() && s2.exists() && s2.isFile()) {\n                    // files exist\n                    if (s1.equals(s2)) {\n                        // comparing the same snapshot\n                        hintLabel.setText(Bundle.CompareSnapshotsAction_ComparingSameSnapshotsMsg());\n                        okButton.setEnabled(false);\n                    } else {\n                        // comparing different snapshots\n                        new NBSwingWorker(true) {\n                            private String hintStr;\n                            private boolean enabledOk;\n                            \n                            @Override\n                            protected void doInBackground() {\n                                ResultsManager rm = ResultsManager.getDefault();\n                                FileObject s1fo = FileUtil.toFileObject(s1);\n                                FileObject s2fo = FileUtil.toFileObject(s2);\n                                int s1t = rm.getSnapshotType(s1fo);\n                                int s2t = rm.getSnapshotType(s2fo);\n\n                                if (s1t == LoadedSnapshot.SNAPSHOT_TYPE_UNKNOWN ||\n                                    s2t == LoadedSnapshot.SNAPSHOT_TYPE_UNKNOWN) {\n                                    // Unknown snapshot types or not .nps snapshots\n                                    hintStr = Bundle.CompareSnapshotsAction_InvalidFilesMsg();\n                                    okButton.setEnabled(false);\n                                } else if (s1t != s2t) {\n                                    // snapshot types don't match\n                                    hintStr = Bundle.CompareSnapshotsAction_DifferentSnapshotsTypeMsg();\n                                    enabledOk = false;\n//                                } else if ((s1t != LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_ALLOCATIONS)\n//                                       && (s1t != LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_LIVENESS)) {\n//                                    // not a memory snapshot\n//                                    hintStr = Bundle.CompareSnapshotsAction_OnlyMemorySnapshotsMsg();\n//                                    enabledOk = false;\n                                } else {\n                                    ProfilingSettings s1s = rm.getSnapshotSettings(s1fo);\n                                    ProfilingSettings s2s = rm.getSnapshotSettings(s2fo);\n                                    if (s1s == null || s2s == null) {\n                                        // Snapshot settings not available (should not happen)\n                                        hintStr = Bundle.CompareSnapshotsAction_InvalidFilesMsg();\n                                        okButton.setEnabled(false);\n                                    } else if (s1s.getAllocTrackEvery() != s2s.getAllocTrackEvery()) {\n                                        // memory snapshots have different track every N objects\n                                        // TODO: is this branch OK for CPU snapshots? Seems to work fine.\n                                        hintStr = Bundle.CompareSnapshotsAction_DifferentObjectsCountsMsg();\n                                        enabledOk = false;\n                                    } else {\n                                        // comparable snapshots (from the hint point of view!)\n                                        hintStr = \" \"; // NOI18N\n                                        enabledOk = areComparableSnapshots(s1fo, s2fo);\n                                    }\n                                }\n                            }\n\n                            @Override\n                            protected void done() {\n                                hintLabel.setText(hintStr);\n                                okButton.setEnabled(enabledOk);\n                            }\n                        }.execute();\n                    }\n                } else {\n                    // files don't exist\n                    hintLabel.setText(Bundle.CompareSnapshotsAction_InvalidFilesMsg());\n                    okButton.setEnabled(false);\n                }\n            } else {\n                // filenames are empty string\n                hintLabel.setText(Bundle.CompareSnapshotsAction_SelectSnapshotsString());\n                okButton.setEnabled(false);\n            }\n        }\n    }\n\n    private class SelectSecondSnapshotPanel extends JPanel implements HelpCtx.Provider {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private JButton externalFileButton;\n        private JButton okButton;\n        private JLabel externalFileHintLabel;\n        private JLabel projectSnapshotsHintLabel;\n        private JLabel selectSnapshotLabel;\n        private JList projectSnapshotsList;\n        private JRadioButton fromFileRadio;\n        private JRadioButton fromProjectRadio;\n        private JTextField externalFileField;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        SelectSecondSnapshotPanel() {\n            initComponents();\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        @Override\n        public HelpCtx getHelpCtx() {\n            return SECOND_SNAPSHOT_HELP_CTX;\n        }        \n\n        public JButton getOKButton() {\n            return okButton;\n        }\n\n        public Object getSnapshot() {\n            if (fromProjectRadio.isSelected()) {\n                Object selectedItem = projectSnapshotsList.getSelectedValue();\n\n                if ((selectedItem == null) || selectedItem instanceof String) {\n                    return null;\n                }\n\n                return selectedItem;\n            } else if (fromFileRadio.isSelected()) {\n                String sf = externalFileField.getText();\n\n                if (!sf.isEmpty()) {\n                    File s = new File(sf);\n\n                    if (s.exists() && s.isFile()) {\n                        return FileUtil.toFileObject(s);\n                    }\n                }\n\n                return null;\n            } else {\n                return null;\n            }\n        }\n\n        public void populateSnapshotsList() {\n            // Get list model\n            DefaultListModel listModel = (DefaultListModel) projectSnapshotsList.getModel();\n\n            // Clear the list\n            listModel.removeAllElements();\n\n            // Add opened but not-yet-saved snapshots\n            // TODO: check that this works correctly in VisualVM!\n            LoadedSnapshot[] loadedSnapshots = ResultsManager.getDefault().getLoadedSnapshots();\n\n            for (LoadedSnapshot loadedSnapshot : loadedSnapshots) {\n                if ((loadedSnapshot != snapshot) && (loadedSnapshot.getFile() == null) && areComparableSnapshots(snapshot, loadedSnapshot)) {\n                    listModel.addElement(loadedSnapshot);\n                }\n            }\n\n            // Add saved snapshots\n            final Lookup.Provider project = snapshot.getProject();\n            File snapFile = snapshot.getFile();\n            final File snapshotDir = snapFile != null ? snapFile.getParentFile() : null;\n            FileObject[] snapshotsOnDisk = ResultsManager.getDefault().listSavedSnapshots(project, snapshotDir);\n            FileObject snapshotFile = (snapFile != null) ? FileUtil.toFileObject(snapFile) : null;\n            \n            for (FileObject snapshotsOnDisk1 : snapshotsOnDisk) {\n                if (((snapshotFile == null) || !snapshotsOnDisk1.equals(snapshotFile)) && areComparableSnapshots(snapshot, snapshotsOnDisk1)) {\n                    listModel.addElement(snapshotsOnDisk1);\n                }\n            }\n\n            if (listModel.getSize() == 0) {\n                listModel.addElement(Bundle.CompareSnapshotsAction_NoComparableSnapshotsFoundMsg());\n                fromFileRadio.setSelected(true);\n                externalFileField.addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && externalFileField.isShowing()) {\n                            externalFileField.removeHierarchyListener(this);\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    externalFileField.requestFocusInWindow();\n                                }\n                            });\n                        }\n                    }\n                });\n            } else {\n                projectSnapshotsList.setSelectedIndex(0);\n                projectSnapshotsList.addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && externalFileField.isShowing()) {\n                            projectSnapshotsList.removeHierarchyListener(this);\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    projectSnapshotsList.requestFocusInWindow();\n                                }\n                            });\n                        }\n                    }\n                });\n            }\n            \n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    if (project != null) {\n                        org.openide.awt.Mnemonics.setLocalizedText(fromProjectRadio, Bundle.CompareSnapshotsAction_FromProjectRadioText());\n                        fromProjectRadio.setToolTipText(null);\n                    } else {\n                        org.openide.awt.Mnemonics.setLocalizedText(fromProjectRadio, Bundle.CompareSnapshotsAction_FromCurrentLocationRadioText());\n                        fromProjectRadio.setToolTipText(snapshotDir != null ?\n                                snapshotDir.getAbsolutePath() : null);\n                    }\n                }\n            });\n        }\n\n        private void initComponents() {\n            okButton = new JButton(Bundle.CompareSnapshotsAction_OkButtonText());\n\n            setLayout(new GridBagLayout());\n\n            GridBagConstraints c;\n            ButtonGroup group = new ButtonGroup();\n\n            selectSnapshotLabel = new JLabel(Bundle.CompareSnapshotsAction_SelectSnapshotString());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 0;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(15, 10, 8, 10);\n            add(selectSnapshotLabel, c);\n\n            fromProjectRadio = new JRadioButton();\n            org.openide.awt.Mnemonics.setLocalizedText(fromProjectRadio, Bundle.CompareSnapshotsAction_FromProjectRadioText());\n            group.add(fromProjectRadio);\n            fromProjectRadio.getAccessibleContext().setAccessibleDescription(\n                Bundle.CompareSnapshotsAction_SelectSnapshotString() + \n                Bundle.CompareSnapshotsAction_FromProjectRadioText());\n            fromProjectRadio.setSelected(true);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 1;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(0, 15, 0, 10);\n            add(fromProjectRadio, c);\n\n            projectSnapshotsList = new JList(new DefaultListModel());\n            projectSnapshotsList.getAccessibleContext().setAccessibleName(Bundle.CompareSnapshotsAction_SnapshotsListAccessDescr());\n            projectSnapshotsList.setVisibleRowCount(5);\n            projectSnapshotsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n\n            JScrollPane projectSnapshotsListScroll = new JScrollPane(projectSnapshotsList,\n                                                                     JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                                                                     JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n            projectSnapshotsListScroll.setPreferredSize(new Dimension(1, projectSnapshotsListScroll.getPreferredSize().height));\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 2;\n            c.weighty = 1d;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.fill = GridBagConstraints.BOTH;\n            c.insets = new Insets(0, 15 + new JRadioButton(\"\").getPreferredSize().width, 5, 10); // NOI18N\n            add(projectSnapshotsListScroll, c);\n\n            projectSnapshotsHintLabel = new JLabel(Bundle.CompareSnapshotsAction_OnlyComparableListedString());\n            projectSnapshotsHintLabel.setForeground(Color.darkGray);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 3;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(0, 15 + new JRadioButton(\"\").getPreferredSize().width, 5, 10); // NOI18N\n            add(projectSnapshotsHintLabel, c);\n\n            fromFileRadio = new JRadioButton(Bundle.CompareSnapshotsAction_FromFileRadioText());\n            org.openide.awt.Mnemonics.setLocalizedText(fromFileRadio, Bundle.CompareSnapshotsAction_FromFileRadioText());\n            group.add(fromFileRadio);\n            fromProjectRadio.getAccessibleContext().setAccessibleDescription(\n                Bundle.CompareSnapshotsAction_SelectSnapshotString() + \n                Bundle.CompareSnapshotsAction_FromFileRadioText());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 4;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(5, 15, 0, 10);\n            add(fromFileRadio, c);\n\n            externalFileField = new JTextField();\n            externalFileField.setPreferredSize(new Dimension(250, externalFileField.getPreferredSize().height));\n            externalFileField.setEnabled(false);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 5;\n            c.weightx = 1d;\n            c.gridwidth = 2;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, 15 + new JRadioButton(\"\").getPreferredSize().width, 5, 5); // NOI18N\n            add(externalFileField, c);\n\n            externalFileButton = new JButton();\n            org.openide.awt.Mnemonics.setLocalizedText(externalFileButton, Bundle.CompareSnapshotsAction_BrowseButtonText());\n            externalFileButton.getAccessibleContext().setAccessibleDescription(Bundle.CompareSnapshotsAction_BrowseButtonAccessDescr());\n            externalFileButton.setEnabled(false);\n            c = new GridBagConstraints();\n            c.gridx = 2;\n            c.gridy = 5;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(0, 5, 5, 10);\n            add(externalFileButton, c);\n\n            externalFileHintLabel = new JLabel(\" \"); // NOI18N\n            externalFileHintLabel.setForeground(Color.darkGray);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 6;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(0, 15 + new JRadioButton(\"\").getPreferredSize().width, 5, 10); // NOI18N\n            add(externalFileHintLabel, c);\n\n            projectSnapshotsList.setCellRenderer(new DefaultListCellRenderer() {\n                    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,\n                                                                  boolean cellHasFocus) {\n                        JLabel c = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);\n\n                        ResultsManager rm = ResultsManager.getDefault();\n                        if (value instanceof LoadedSnapshot) {\n                            LoadedSnapshot ls = (LoadedSnapshot) value;\n                            c.setFont(c.getFont().deriveFont(Font.BOLD));\n                            c.setText(rm.getSnapshotDisplayName(ls));\n\n                            switch (ls.getType()) {\n                                case LoadedSnapshot.SNAPSHOT_TYPE_CPU:\n                                case LoadedSnapshot.SNAPSHOT_TYPE_CPU_JDBC:\n                                    c.setIcon(cpuIcon);\n\n                                    break;\n                                case LoadedSnapshot.SNAPSHOT_TYPE_CODEFRAGMENT:\n                                    c.setIcon(fragmentIcon);\n\n                                    break;\n                                case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_ALLOCATIONS:\n                                case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_LIVENESS:\n                                case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_SAMPLED:\n                                    c.setIcon(memoryIcon);\n\n                                    break;\n                            }\n                        } else if (value instanceof FileObject) {\n                            FileObject fo = (FileObject) value;\n                            LoadedSnapshot ls = rm.findLoadedSnapshot(FileUtil.toFile(fo));\n\n                            if (ls != null) {\n                                c.setFont(c.getFont().deriveFont(Font.BOLD));\n                                c.setText(rm.getSnapshotDisplayName(ls));\n\n                                switch (ls.getType()) {\n                                    case LoadedSnapshot.SNAPSHOT_TYPE_CPU:\n                                    case LoadedSnapshot.SNAPSHOT_TYPE_CPU_JDBC:\n                                        c.setIcon(cpuIcon);\n\n                                        break;\n                                    case LoadedSnapshot.SNAPSHOT_TYPE_CODEFRAGMENT:\n                                        c.setIcon(fragmentIcon);\n\n                                        break;\n                                    case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_ALLOCATIONS:\n                                    case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_LIVENESS:\n                                    case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_SAMPLED:\n                                        c.setIcon(memoryIcon);\n\n                                        break;\n                                }\n                            } else {\n                                int type = rm.getSnapshotType(fo);\n                                c.setText(rm.getSnapshotDisplayName(fo.getName(), type));\n                                switch (type) {\n                                    case LoadedSnapshot.SNAPSHOT_TYPE_CPU:\n                                    case LoadedSnapshot.SNAPSHOT_TYPE_CPU_JDBC:\n                                        c.setIcon(cpuIcon);\n\n                                        break;\n                                    case LoadedSnapshot.SNAPSHOT_TYPE_CODEFRAGMENT:\n                                        c.setIcon(fragmentIcon);\n\n                                        break;\n                                    case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_ALLOCATIONS:\n                                    case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_LIVENESS:\n                                    case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_SAMPLED:\n                                        c.setIcon(memoryIcon);\n\n                                        break;\n                                }\n                            }\n                        }\n\n                        return c;\n                    }\n                });\n\n            projectSnapshotsList.addListSelectionListener(new ListSelectionListener() {\n                    public void valueChanged(ListSelectionEvent e) {\n                        updateOKButton();\n                    }\n                });\n\n            projectSnapshotsList.addMouseListener(new MouseAdapter() {\n                    public void mousePressed(MouseEvent e) {\n                        if ((e.getButton() == MouseEvent.BUTTON1) && (e.getClickCount() == 2)\n                                && (projectSnapshotsList.getSelectedValue() != null)) {\n                            SwingUtilities.invokeLater(new Runnable() {\n                                    public void run() {\n                                        okButton.doClick();\n                                    }\n                                });\n                        }\n                    }\n                });\n\n            fromProjectRadio.addItemListener(new ItemListener() {\n                    public void itemStateChanged(ItemEvent e) {\n                        projectSnapshotsList.setEnabled(fromProjectRadio.isSelected());\n                        projectSnapshotsHintLabel.setText(fromProjectRadio.isSelected() ? Bundle.CompareSnapshotsAction_OnlyComparableListedString() : \" \"); // NOI18N\n                        updateOKButton();\n                    }\n                });\n\n            fromFileRadio.addItemListener(new ItemListener() {\n                    public void itemStateChanged(ItemEvent e) {\n                        externalFileField.setEnabled(fromFileRadio.isSelected());\n                        externalFileButton.setEnabled(fromFileRadio.isSelected());\n\n                        if (!fromFileRadio.isSelected()) {\n                            externalFileHintLabel.setText(\" \"); // NOI18N\n                        }\n\n                        updateOKButton();\n                    }\n                });\n\n            DocumentListener documentListener = new DocumentListener() {\n                public void insertUpdate(DocumentEvent e) {\n                    updateOKButton();\n                }\n\n                public void removeUpdate(DocumentEvent e) {\n                    updateOKButton();\n                }\n\n                public void changedUpdate(DocumentEvent e) {\n                    updateOKButton();\n                }\n            };\n\n            externalFileField.getDocument().addDocumentListener(documentListener);\n\n            externalFileButton.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        JFileChooser snapshotChooser = CompareSnapshotsAction.getSnapshotFileChooser();\n                        snapshotChooser.setCurrentDirectory(new File(externalFileField.getText()));\n\n                        if (snapshotChooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == 0) {\n                            File file = snapshotChooser.getSelectedFile();\n\n                            if (file != null) {\n                                externalFileField.setText(file.getAbsolutePath());\n                            }\n                        }\n                    }\n                });\n\n            updateOKButton();\n        }\n\n        private void updateOKButton() {\n            if (fromProjectRadio.isSelected()) {\n                // Snapshot from project\n                Object selectedItem = projectSnapshotsList.getSelectedValue();\n                okButton.setEnabled((selectedItem != null) && !(selectedItem instanceof String));\n            } else if (fromFileRadio.isSelected()) {\n                // Snapshot from file\n                String sf = externalFileField.getText();\n\n                if (!sf.isEmpty()) {\n                    // filename not empty string\n                    File s = new File(sf);\n\n                    if (s.exists() && s.isFile()) {\n                        // file exists\n                        if (s.equals(snapshot.getFile())) {\n                            // comparing snapshot with itself\n                            externalFileHintLabel.setText(Bundle.CompareSnapshotsAction_ComparingSameSnapshotsMsg());\n                            okButton.setEnabled(false);\n                        } else {\n                            // comparing different snapshots\n                            FileObject snapshot2f = FileUtil.toFileObject(s);\n\n                            if (snapshot.getType() != ResultsManager.getDefault().getSnapshotType(snapshot2f)) {\n                                // snapshot types doesn't match\n                                externalFileHintLabel.setText(Bundle.CompareSnapshotsAction_DifferentSnapshotsTypeMsg());\n//                            } else if ((snapshot.getType() != LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_ALLOCATIONS)\n//                                           && (snapshot.getType() != LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_LIVENESS)) {\n//                                // TODO: remove after Compare CPU snapshots is implemented\n//                                // not a memory snapshot\n//                                externalFileHintLabel.setText(Bundle.CompareSnapshotsAction_OnlyMemorySnapshotsMsg());\n//                                okButton.setEnabled(false);\n//\n//                                return;\n                            } else if (snapshot.getSettings().getAllocTrackEvery() != ResultsManager.getDefault()\n                                                                                                        .getSnapshotSettings(snapshot2f)\n                                                                                                        .getAllocTrackEvery()) {\n                                // memory snapshots have different track every N objects\n                                externalFileHintLabel.setText(Bundle.CompareSnapshotsAction_DifferentObjectsCountsMsg());\n                            } else {\n                                // comparable snapshots (from the hint point of view!)\n                                externalFileHintLabel.setText(\" \"); // NOI18N\n                            }\n\n                            okButton.setEnabled(areComparableSnapshots(snapshot, snapshot2f));\n                        }\n                    } else {\n                        // file doesn't exist\n                        externalFileHintLabel.setText(Bundle.CompareSnapshotsAction_InvalidFileMsg());\n                        okButton.setEnabled(false);\n                    }\n                } else {\n                    // filename is empty string\n                    externalFileHintLabel.setText(Bundle.CompareSnapshotsAction_EnterFileMsg());\n                    okButton.setEnabled(false);\n                }\n            } else {\n                okButton.setEnabled(false);\n            }\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Icon cpuIcon = Icons.getIcon(ProfilerIcons.CPU);\n    private static final Icon fragmentIcon = Icons.getIcon(ProfilerIcons.FRAGMENT);\n    private static final Icon memoryIcon = Icons.getIcon(ProfilerIcons.MEMORY);\n    private static JFileChooser snapshotFileChooser;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private LoadedSnapshot snapshot;\n    private SelectExternalSnapshotsPanel externalSnapshotsSelector;\n    private SelectSecondSnapshotPanel secondSnapshotSelector;\n    \n    private Performer performer;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CompareSnapshotsAction() {\n        this(null);\n    }\n\n    public CompareSnapshotsAction(LoadedSnapshot snapshot) {\n        putValue(Action.NAME, Bundle.CompareSnapshotsAction_ActionName());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.CompareSnapshotsAction_ActionDescr());\n        putValue(Action.SMALL_ICON, Icons.getIcon(ProfilerIcons.SNAPSHOTS_COMPARE));\n        \n        this.snapshot = snapshot;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    public void setPerformer(Performer _performer) {\n        performer = _performer;\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        if (snapshot != null) {\n            assert performer != null;\n            compareDefinedSnapshot();\n        } else {\n            compareExternalSnapshots();\n        }\n    }\n\n    public static boolean areComparableSnapshots(LoadedSnapshot s1, LoadedSnapshot s2) {\n        // compare snapshot types\n        if (s1.getType() != s2.getType()) {\n            return false;\n        }\n\n        // for memory snapshots compare track every n allocations\n        if ((s1.getType() == LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_ALLOCATIONS)\n                || (s1.getType() == LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_LIVENESS)) {\n            if (s1.getSettings().getAllocTrackEvery() != s2.getSettings().getAllocTrackEvery()) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    public static boolean areComparableSnapshots(LoadedSnapshot s1, FileObject s2f) {\n        // try to find already loaded snapshot\n        LoadedSnapshot s2 = ResultsManager.getDefault().findLoadedSnapshot(FileUtil.toFile(s2f));\n\n        // compare loaded snapshots\n        if (s2 != null) {\n            return areComparableSnapshots(s1, s2);\n        }\n\n        // compare snapshot types\n        if (s1.getType() != ResultsManager.getDefault().getSnapshotType(s2f)) {\n            return false;\n        }\n\n        // for memory snapshots compare track every n allocations\n        if ((s1.getType() == LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_ALLOCATIONS)\n                || (s1.getType() == LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_LIVENESS)) {\n            ProfilingSettings s2settings = ResultsManager.getDefault().getSnapshotSettings(s2f);\n\n            if (s2settings == null) {\n                return false;\n            }\n\n            if (s1.getSettings().getAllocTrackEvery() != s2settings.getAllocTrackEvery()) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    public static boolean areComparableSnapshots(FileObject s1f, FileObject s2f) {\n        // try to find already loaded snapshots\n        LoadedSnapshot s1 = ResultsManager.getDefault().findLoadedSnapshot(FileUtil.toFile(s1f));\n        LoadedSnapshot s2 = ResultsManager.getDefault().findLoadedSnapshot(FileUtil.toFile(s2f));\n\n        // compare loaded snapshots\n        if (s1 != null) {\n            if (s2 != null) {\n                return areComparableSnapshots(s1, s2);\n            } else {\n                return areComparableSnapshots(s1, s2f);\n            }\n        }\n\n        // compare snapshot types\n        int s1t = ResultsManager.getDefault().getSnapshotType(s1f);\n\n        if (s1t != ResultsManager.getDefault().getSnapshotType(s2f)) {\n            return false;\n        }\n\n        // for memory snapshots compare track every n allocations\n        if ((s1t == LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_ALLOCATIONS) || (s1t == LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_LIVENESS)) {\n            ProfilingSettings s1s = ResultsManager.getDefault().getSnapshotSettings(s1f);\n            ProfilingSettings s2s = ResultsManager.getDefault().getSnapshotSettings(s2f);\n\n            if ((s1s == null) || (s2s == null)) {\n                return false;\n            }\n\n            if (s1s.getAllocTrackEvery() != s2s.getAllocTrackEvery()) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    private static JFileChooser getSnapshotFileChooser() {\n        if (snapshotFileChooser == null) {\n            snapshotFileChooser = new JFileChooser();\n            snapshotFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);\n            snapshotFileChooser.setMultiSelectionEnabled(false);\n            snapshotFileChooser.setDialogType(JFileChooser.OPEN_DIALOG);\n            snapshotFileChooser.setDialogTitle(Bundle.CompareSnapshotsAction_OpenChooserCaption());\n            snapshotFileChooser.setFileFilter(new FileFilter() {\n                    public boolean accept(File f) {\n                        return f.isDirectory() || f.getName().endsWith(\".nps\"); // NOI18N\n                    }\n\n                    public String getDescription() {\n                        return Bundle.CompareSnapshotsAction_OpenChooserFilter(\"nps\"); // NOI18N\n                    }\n                });\n            snapshotFileChooser.setAcceptAllFileFilterUsed(false);\n        }\n\n        return snapshotFileChooser;\n    }\n\n    private SelectExternalSnapshotsPanel getExternalSnapshotsSelector() {\n        if (externalSnapshotsSelector == null) {\n            externalSnapshotsSelector = new SelectExternalSnapshotsPanel();\n        }\n\n        return externalSnapshotsSelector;\n    }\n\n    private SelectSecondSnapshotPanel getSecondSnapshotSelector() {\n        if (secondSnapshotSelector == null) {\n            secondSnapshotSelector = new SelectSecondSnapshotPanel();\n        }\n\n        return secondSnapshotSelector;\n    }\n\n    private void compareDefinedSnapshot() {\n        getSecondSnapshotSelector().populateSnapshotsList();\n\n        DialogDescriptor desc = new DialogDescriptor(getSecondSnapshotSelector(), Bundle.CompareSnapshotsAction_SelectSnapshotDialogCaption(), true,\n                                                     new Object[] {\n                                                         getSecondSnapshotSelector().getOKButton(), DialogDescriptor.CANCEL_OPTION\n                                                     }, DialogDescriptor.OK_OPTION, 0, SECOND_SNAPSHOT_HELP_CTX, null);\n        Object res = DialogDisplayer.getDefault().notify(desc);\n\n        if (res.equals(getSecondSnapshotSelector().getOKButton())) {\n            Object selectedSnapshot = getSecondSnapshotSelector().getSnapshot();\n\n            if (selectedSnapshot instanceof LoadedSnapshot) {\n                performer.compare((LoadedSnapshot)selectedSnapshot);\n//                ResultsManager.getDefault().compareSnapshots(snapshot, (LoadedSnapshot) selectedSnapshot);\n            } else if (selectedSnapshot instanceof FileObject) {\n                // TODO: seems to eventually load the snapshot in EDT\n                LoadedSnapshot snapshot2 = ResultsManager.getDefault().\n                        getSnapshotFromFileObject((FileObject)selectedSnapshot);\n                if (snapshot2 != null) performer.compare(snapshot2);\n//                if (snapshot.getFile() == null) {\n//                    LoadedSnapshot snapshot2 = ResultsManager.getDefault().getSnapshotFromFileObject((FileObject) selectedSnapshot);\n//\n//                    if (snapshot2 != null) {\n//                        ResultsManager.getDefault().compareSnapshots(snapshot, snapshot2);\n//                    }\n//                } else {\n//                    ResultsManager.getDefault()\n//                                  .compareSnapshots(FileUtil.toFileObject(snapshot.getFile()), (FileObject) selectedSnapshot);\n//                }\n            }\n        }\n    }\n\n    private void compareExternalSnapshots() {\n        DialogDescriptor desc = new DialogDescriptor(getExternalSnapshotsSelector(), Bundle.CompareSnapshotsAction_SelectSnapshotsDialogCaption(), true,\n                                                     new Object[] {\n                                                         getExternalSnapshotsSelector().getOKButton(),\n                                                         DialogDescriptor.CANCEL_OPTION\n                                                     }, DialogDescriptor.OK_OPTION, 0, EXTERNAL_SNAPSHOT_HELP_CTX, null);\n        Object res = DialogDisplayer.getDefault().notify(desc);\n\n        if (res.equals(getExternalSnapshotsSelector().getOKButton())) {\n            ResultsManager.getDefault()\n                          .compareSnapshots(FileUtil.toFileObject(new File(getExternalSnapshotsSelector().getSnapshot1Filename())),\n                                            FileUtil.toFileObject(new File(getExternalSnapshotsSelector().getSnapshot2Filename())));\n        }\n    }\n    \n    \n    public static interface Performer {\n        \n        void compare(LoadedSnapshot snapshot);\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/GetCmdLineArgumentsAction.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.openide.DialogDescriptor;\nimport org.openide.util.NbBundle;\nimport java.awt.*;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.ActionID;\nimport org.openide.util.HelpCtx;\n\n\n/**\n * An action to print command-line arguments from target app.\n *\n * @author Ian Formanek\n */\n@NbBundle.Messages({\n    \"GetCmdLineArgumentsAction_TargetJvmInactiveMsg=Target JVM is inactive\",\n    \"GetCmdLineArgumentsAction_JvmArgumentsString=JVM arguments:\",\n    \"GetCmdLineArgumentsAction_MainClassAndArgsString=Main class (JAR) and its arguments:\",\n    \"LBL_GetCmdLineArgumentsAction=&View Command-line Arguments\",\n    \"HINT_GetCmdLineArgumentsAction=View Command-line Arguments\",\n    \"CAPTION_JVMandMainClassCommandLineArguments=JVM and Main Class Command-line Arguments\",\n    \"MSG_NotAvailableNow=Not available at this time: {0}\"\n})\n@ActionID(category=\"Profile\", id=\"org.graalvm.visualvm.lib.profiler.actions.GetCmdLineArgumentsAction\")\n//@ActionRegistration(displayName=\"#LBL_GetCmdLineArgumentsAction\")\n//@ActionReference(path=\"Menu/Profile/Advanced\", position=200)\npublic final class GetCmdLineArgumentsAction extends ProfilingAwareAction {\n    final private static int[] enabledStates = new int[]{Profiler.PROFILING_RUNNING};\n    \n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public GetCmdLineArgumentsAction() {\n        putValue(Action.NAME, Bundle.LBL_GetCmdLineArgumentsAction());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.HINT_GetCmdLineArgumentsAction());\n        putValue(\"noIconInMenu\", Boolean.TRUE); //NOI18N\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Invoked when an action occurs.\n     */\n    public void performAction() {\n        try {\n            final TargetAppRunner runner = Profiler.getDefault().getTargetAppRunner();\n            final ProfilerClient profilerClient = runner.getProfilerClient();\n            final ProfilingSessionStatus status = runner.getProfilingSessionStatus();\n            final ProfilerEngineSettings settings = runner.getProfilerEngineSettings();\n\n            if (!profilerClient.targetJVMIsAlive()) {\n                throw new ClientUtils.TargetAppOrVMTerminated(1, Bundle.GetCmdLineArgumentsAction_TargetJvmInactiveMsg());\n            }\n\n            final String jvmArgs;\n            final String javaCommand;\n\n            if (status.runningInAttachedMode) {\n                jvmArgs = status.jvmArguments;\n                javaCommand = status.javaCommand;\n            } else {\n                jvmArgs = settings.getJVMArgsAsSingleString();\n                javaCommand = settings.getMainClassName() + \" \" + settings.getMainArgsAsSingleString(); // NOI18N\n            }\n\n            final StringBuffer s = new StringBuffer();\n            s.append(\"<b>\"); // NOI18N\n            s.append(Bundle.GetCmdLineArgumentsAction_JvmArgumentsString());\n            s.append(\"</b><br>\"); // NOI18N\n            s.append(jvmArgs);\n            s.append(\"<br><br>\"); // NOI18N\n            s.append(\"<b>\"); // NOI18N\n            s.append(Bundle.GetCmdLineArgumentsAction_MainClassAndArgsString());\n            s.append(\"</b><br>\"); // NOI18N\n            s.append(javaCommand);\n\n            final HTMLTextArea textArea = new HTMLTextArea(s.toString());\n            textArea.getAccessibleContext()\n                    .setAccessibleName(Bundle.CAPTION_JVMandMainClassCommandLineArguments());\n\n            final JPanel p = new JPanel();\n            p.setLayout(new BorderLayout());\n            p.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));\n            p.add(new JScrollPane(textArea), BorderLayout.CENTER);\n            p.setPreferredSize(new Dimension(600, 200));\n\n            DialogDisplayer.getDefault().createDialog(new DialogDescriptor(p,\n                                                              Bundle.CAPTION_JVMandMainClassCommandLineArguments(),\n                                                              true, new Object[] { DialogDescriptor.CLOSED_OPTION },\n                                                              DialogDescriptor.CLOSED_OPTION, DialogDescriptor.BOTTOM_ALIGN,\n                                                              null, null)).setVisible(true);\n        } catch (ClientUtils.TargetAppOrVMTerminated e) {\n            ProfilerDialogs.displayWarning(Bundle.MSG_NotAvailableNow(e.getMessage()));\n            ProfilerLogger.log(e.getMessage());\n        }\n    }\n\n    @Override\n    protected int[] enabledStates() {\n        return enabledStates;\n    }\n\n    @Override\n    public HelpCtx getHelpCtx() {\n        return null;\n    }\n\n    @Override\n    public String getName() {\n        return Bundle.LBL_GetCmdLineArgumentsAction();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/HeapDumpAction.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport java.awt.Dimension;\nimport java.awt.FlowLayout;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.ItemListener;\nimport java.io.File;\nimport java.io.IOException;\nimport javax.swing.*;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.profiler.NetBeansProfiler;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerStorage;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.utilities.ProfilerUtils;\nimport org.graalvm.visualvm.lib.profiler.v2.SnapshotsWindow;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.ActionID;\nimport org.openide.awt.ActionReference;\nimport org.openide.awt.ActionRegistration;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n\n/**\n * Save heap dump of profiled application to file\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"HeapDumpAction_ActionName=Take &Heap Dump...\",\n    \"HeapDumpAction_RequiredJdkMsg=The profiled application must be run on JDK 1.6, 1.7 or 1.5.0_12 to take a heap dump\",\n    \"HeapDumpAction_RemoteUnsupportedMsg=Taking heap dump on a remote machine not supported.\",\n    \"HeapDumpAction_WrongDestinationMsg=Dumping heap failed, cannot resolve destination file.\",\n    \"HeapDumpAction_DumpingHeapText=Dumping heap...\",\n    \"HeapDumpAction_SavedDialogCaption=Heap Dump Saved\",\n    \"HeapDumpAction_SavedDialogText=<html><b>The heap has been successfuly saved to a file.</b><br>Do you want to open it in HeapWalker?</html>\",\n    \"HeapDumpAction_DumpingFailedMsg=Taking heap dump failed. See NetBeans logfile for details.\",\n    \"HeapDumpAction_DestinationDialogCaption=Choose Heap Dump Destination\",\n    \"HeapDumpAction_LocationProjectString=Profiled project\",\n    \"HeapDumpAction_LocationGlobalString=Default storage for external processes\",\n    \"HeapDumpAction_DirectoryDialogCaption=Choose Directory\",\n    \"HeapDumpAction_OkButtonText=OK\",\n    \"HeapDumpAction_DestinationLabelText=<html><b><nobr>Choose heap dump destination:</nobr></b></html>\",\n    \"HeapDumpAction_DefaultLocationRadioText=Default location\",\n    \"HeapDumpAction_CustomLocationRadioText=Custom directory:\",\n    \"HeapDumpAction_BrowseButtonText=Browse\",\n    \"HeapDumpAction_ToolTip=Take heap dump from the profiled process\",\n    \"HeapDumpAction_ToolTipNoRemote=Take heap dump from the profiled application (not supported for remote profiling)\"\n})\npublic final class HeapDumpAction extends ProfilingAwareAction {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n    final private static class Singleton {\n        final private static HeapDumpAction INSTANCE = new HeapDumpAction();\n    }\n    \n    private static class ChooseHeapdumpTargetPanel extends JPanel implements HelpCtx.Provider {\n        //~ Static fields/initializers -------------------------------------------------------------------------------------------\n\n        private static final String HELP_CTX_KEY = \"ChooseHeapdumpTargetPanel.HelpCtx\";  // NOI18N\n        private static final HelpCtx HELP_CTX = new HelpCtx(HELP_CTX_KEY);\n        public static final int DESTINATION_DEFAULT = 0;\n        public static final int DESTINATION_CUSTOM = 1;\n\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private JButton customLocationButton;\n        private JButton okButton;\n        private JLabel chooseDestinationLabel;\n        private JRadioButton customLocationRadio;\n        private JRadioButton defaultLocationRadio;\n        private JTextField customLocationField;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ChooseHeapdumpTargetPanel() {\n            initComponents();\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        @Override\n        public HelpCtx getHelpCtx() {\n            return HELP_CTX;\n        }\n        \n        public String getCustomDirectory() {\n            return customLocationField.getText();\n        }\n        \n        public void setCustomDirectory(String directory) {\n            customLocationField.setText(directory);\n        }\n\n        public int getDestinationType() {\n            if (defaultLocationRadio.isSelected()) {\n                return DESTINATION_DEFAULT;\n            } else {\n                return DESTINATION_CUSTOM;\n            }\n        }\n        \n        public void setDestinationType(int type) {\n            defaultLocationRadio.setSelected(type == DESTINATION_DEFAULT);\n        }\n\n        public JButton getOKButton() {\n            return okButton;\n        }\n\n        public void updateDefaultLocation(String location) {\n            defaultLocationRadio.setText(location);\n        }\n\n        private void initComponents() {\n            okButton = new JButton(Bundle.HeapDumpAction_OkButtonText());\n\n            setLayout(new GridBagLayout());\n\n            GridBagConstraints c;\n            ButtonGroup group = new ButtonGroup();\n\n            chooseDestinationLabel = new JLabel(Bundle.HeapDumpAction_DestinationLabelText());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 0;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(15, 10, 8, 5);\n            add(chooseDestinationLabel, c);\n\n            defaultLocationRadio = new JRadioButton(Bundle.HeapDumpAction_DefaultLocationRadioText());\n            group.add(defaultLocationRadio);\n            defaultLocationRadio.setSelected(true);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 1;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(0, 15, 0, 5);\n            add(defaultLocationRadio, c);\n\n            customLocationRadio = new JRadioButton(Bundle.HeapDumpAction_CustomLocationRadioText());\n            group.add(customLocationRadio);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 2;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(0, 15, 0, 5);\n            add(customLocationRadio, c);\n\n            String tempDir = System.getProperty(\"java.io.tmpdir\"); // NOI18N\n\n            if (tempDir.endsWith(File.separator)) {\n                tempDir = tempDir.substring(0, tempDir.length() - File.separator.length());\n            }\n\n            customLocationField = new JTextField();\n            customLocationField.setText(tempDir);\n            customLocationField.setPreferredSize(new Dimension(210, customLocationField.getPreferredSize().height));\n            customLocationField.setEnabled(false);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 3;\n            c.gridwidth = 2;\n            c.weightx = 1.0d;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, 15 + new JRadioButton(\"\").getPreferredSize().width, 5, 5); // NOI18N\n            add(customLocationField, c);\n\n            customLocationButton = new JButton(Bundle.HeapDumpAction_BrowseButtonText());\n            customLocationButton.setEnabled(false);\n            c = new GridBagConstraints();\n            c.gridx = 2;\n            c.gridy = 3;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(0, 5, 5, 10);\n            add(customLocationButton, c);\n\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 4;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.weighty = 1.0d;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.fill = GridBagConstraints.BOTH;\n            add(new JPanel(new FlowLayout(0, 0, FlowLayout.LEADING)), c);\n\n            DocumentListener documentListener = new DocumentListener() {\n                public void insertUpdate(DocumentEvent e) {\n                    updateOKButton();\n                }\n\n                public void removeUpdate(DocumentEvent e) {\n                    updateOKButton();\n                }\n\n                public void changedUpdate(DocumentEvent e) {\n                    updateOKButton();\n                }\n            };\n\n            customLocationField.getDocument().addDocumentListener(documentListener);\n\n            defaultLocationRadio.addItemListener(new ItemListener() {\n                    public void itemStateChanged(ItemEvent e) {\n                        updateOKButton();\n                    }\n                });\n\n            customLocationRadio.addItemListener(new ItemListener() {\n                    public void itemStateChanged(ItemEvent e) {\n                        customLocationField.setEnabled(customLocationRadio.isSelected());\n                        customLocationButton.setEnabled(customLocationRadio.isSelected());\n                        updateOKButton();\n                    }\n                });\n\n            customLocationButton.addActionListener(new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        JFileChooser directoryChooser = HeapDumpAction.getSnapshotDirectoryChooser();\n                        directoryChooser.setCurrentDirectory(new File(getCustomDirectory()));\n\n                        if (directoryChooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == 0) {\n                            File file = directoryChooser.getSelectedFile();\n\n                            if (file != null) {\n                                customLocationField.setText(directoryChooser.getSelectedFile().getAbsolutePath());\n                            }\n                        }\n                    }\n                });\n\n            updateOKButton();\n        }\n\n        private void updateOKButton() {\n            if (defaultLocationRadio.isSelected()) {\n                okButton.setEnabled(true);\n            } else if (customLocationRadio.isSelected()) {\n                File file = new File(getCustomDirectory());\n                okButton.setEnabled(file.exists() && file.isDirectory());\n            } else {\n                okButton.setEnabled(false);\n            }\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    private static final String SELECTING_TARGET_CANCELLED = \"&*$?CANCELLED?$*&\"; // NOI18N\n    private static final int[] ENABLED_STATES = new int[] { Profiler.PROFILING_RUNNING };\n    private static JFileChooser snapshotDirectoryChooser;\n\n    @ActionID(id = \"org.graalvm.visualvm.lib.profiler.actions.HeapDumpAction\", category = \"Profile\")\n    @ActionRegistration(displayName = \"#HeapDumpAction_ActionName\", lazy=false)\n    @ActionReference(path = \"Menu/Profile\", position = 600)\n    public static HeapDumpAction getInstance() {\n        return Singleton.INSTANCE;\n    }\n    \n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ChooseHeapdumpTargetPanel heapdumpTargetSelector;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    public HeapDumpAction() {\n        setIcon(Icons.getIcon(ProfilerIcons.SNAPSHOT_HEAP));\n        putValue(\"iconBase\", Icons.getResource(ProfilerIcons.SNAPSHOT_HEAP)); // NOI18N\n    }\n\n    public HelpCtx getHelpCtx() {\n        return HelpCtx.DEFAULT_HELP;\n\n        // If you will provide context help then use:\n        // return new HelpCtx(MyAction.class);\n    }\n\n    public String getName() {\n        return Bundle.HeapDumpAction_ActionName();\n    }\n\n    // dumps to project and opens in HeapWalker if automatic snapshot opening is set\n    public void dumpToProject() {\n        takeHeapDump(false);\n    }\n\n    // asks for heap dump destination first\n    public void performAction() {\n        takeHeapDump(true);\n    }\n\n    protected int[] enabledStates() {\n        return ENABLED_STATES;\n    }\n\n    private String getCurrentHeapDumpFilename(String targetFolder) {\n        try {\n            String fileName = ResultsManager.getDefault().getDefaultHeapDumpFileName(System.currentTimeMillis());\n            FileObject folder = (targetFolder == null)\n                                ? ProfilerStorage.getProjectFolder(NetBeansProfiler.getDefaultNB().getProfiledProject(), true)\n                                : FileUtil.toFileObject(FileUtil.normalizeFile(new File(targetFolder)));\n\n            return FileUtil.toFile(folder).getAbsolutePath() + File.separator\n                   + FileUtil.findFreeFileName(folder, fileName, ResultsManager.HEAPDUMP_EXTENSION) + \".\"\n                   + ResultsManager.HEAPDUMP_EXTENSION; // NOI18N\n        } catch (IOException e) {\n            return null;\n        }\n    }\n    \n    protected void updateAction() {\n        boolean remote = false;\n        boolean enabled = shouldBeEnabled(Profiler.getDefault());\n        if (enabled) {\n            String remoteHost = Profiler.getDefault().getTargetAppRunner().\n                    getProfilerEngineSettings().getRemoteHost();\n            if (remoteHost != null && !remoteHost.isEmpty())\n                remote = true; // Not supported for remote attach\n        }\n        setEnabled(!remote && enabled);\n        setToolTipText(remote ? Bundle.HeapDumpAction_ToolTipNoRemote() :\n                                Bundle.HeapDumpAction_ToolTip());\n    }\n    \n    private void setToolTipText(String text) {\n        Object oldText = getProperty(SHORT_DESCRIPTION);\n        putProperty(SHORT_DESCRIPTION, text);\n        firePropertyChange(SHORT_DESCRIPTION, oldText, text);\n    }\n\n    private static JFileChooser getSnapshotDirectoryChooser() {\n        if (snapshotDirectoryChooser == null) {\n            snapshotDirectoryChooser = new JFileChooser();\n            snapshotDirectoryChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\n            snapshotDirectoryChooser.setMultiSelectionEnabled(false);\n            snapshotDirectoryChooser.setDialogType(JFileChooser.OPEN_DIALOG);\n            snapshotDirectoryChooser.setDialogTitle(Bundle.HeapDumpAction_DirectoryDialogCaption());\n        }\n\n        return snapshotDirectoryChooser;\n    }\n\n    private ChooseHeapdumpTargetPanel getHeapdumpTargetSelector() {\n        if (heapdumpTargetSelector == null) {\n            heapdumpTargetSelector = new ChooseHeapdumpTargetPanel();\n        }\n\n        return heapdumpTargetSelector;\n    }\n\n    private String selectTargetDirectory() {\n        // Choose heapdump destination\n        ChooseHeapdumpTargetPanel targetSelector = getHeapdumpTargetSelector();\n        targetSelector.updateDefaultLocation((NetBeansProfiler.getDefaultNB().getProfiledProject() != null)\n                                             ? Bundle.HeapDumpAction_LocationProjectString() : \n                                               Bundle.HeapDumpAction_LocationGlobalString());\n\n        int previousType = targetSelector.getDestinationType();\n        String previousDirectory = targetSelector.getCustomDirectory();\n        \n        DialogDescriptor desc = new DialogDescriptor(targetSelector, Bundle.HeapDumpAction_DestinationDialogCaption(), true,\n                                                     new Object[] { targetSelector.getOKButton(), DialogDescriptor.CANCEL_OPTION },\n                                                     DialogDescriptor.OK_OPTION, 0, null, null);\n        Object res = DialogDisplayer.getDefault().notify(desc);\n\n        if (!res.equals(targetSelector.getOKButton())) {\n            targetSelector.setDestinationType(previousType);\n            targetSelector.setCustomDirectory(previousDirectory);\n            return SELECTING_TARGET_CANCELLED;\n        }\n\n        // Resolve destination file\n        int destinationType = targetSelector.getDestinationType();\n\n        if (destinationType == ChooseHeapdumpTargetPanel.DESTINATION_DEFAULT) {\n            targetSelector.setCustomDirectory(previousDirectory);\n            return getCurrentHeapDumpFilename(null);\n        } else if (destinationType == ChooseHeapdumpTargetPanel.DESTINATION_CUSTOM) {\n            return getCurrentHeapDumpFilename(targetSelector.getCustomDirectory());\n        }\n\n        return null;\n    }\n\n    // askForDestination == false ? dump to project : ask for destination (project vs. external file)\n    private void takeHeapDump(final boolean askForDestination) {\n        ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                public void run() {\n                    TargetAppRunner targetApp = Profiler.getDefault().getTargetAppRunner();\n\n                    // not supported for JDK other than 1.6 & 1.7 & 1.5.0_12 and up\n                    if (!targetApp.hasSupportedJDKForHeapDump()) {\n                        ProfilerDialogs.displayWarning(Bundle.HeapDumpAction_RequiredJdkMsg());\n\n                        return;\n                    }\n\n                    // not supported for remote attach\n                    if (targetApp.getProfilingSessionStatus().remoteProfiling) {\n                        ProfilerDialogs.displayWarning(Bundle.HeapDumpAction_RemoteUnsupportedMsg());\n\n                        return;\n                    }\n\n                    try {\n                        // Resolve destination file\n                        String dumpFileName = askForDestination ? selectTargetDirectory() : getCurrentHeapDumpFilename(null);\n\n                        // Selecting destination cancelled by the user\n                        if (dumpFileName == SELECTING_TARGET_CANCELLED) {\n                            return;\n                        }\n\n                        // Cannot resolve destination file\n                        if (dumpFileName == null) {\n                            ProfilerDialogs.displayError(Bundle.HeapDumpAction_WrongDestinationMsg());\n\n                            return;\n                        }\n\n                        // Take heapdump\n                        boolean heapdumpTaken = false;\n                        ProgressHandle pHandle = null;\n\n                        try {\n                            pHandle = ProgressHandle.createHandle(Bundle.HeapDumpAction_DumpingHeapText());\n                            pHandle.setInitialDelay(0);\n                            pHandle.start();\n                            heapdumpTaken = targetApp.getProfilerClient().takeHeapDump(dumpFileName);\n                        } finally {\n                            if (pHandle != null) {\n                                pHandle.finish();\n                            }\n                        }\n\n                        if (heapdumpTaken) {\n                            // Refresh list of snapshots\n                            File file = new File(dumpFileName);\n                            FileObject folder = FileUtil.toFileObject(file.getParentFile());\n                            SnapshotsWindow.instance().refreshFolder(folder, true);\n//                            if (ProfilerControlPanel2.hasDefault())\n//                                ProfilerControlPanel2.getDefault().refreshSnapshotsList();\n\n                            if (askForDestination) {\n                                // Heapdump saved, open in HeapWalker?\n                                if (ProfilerDialogs.displayConfirmationDNSA(Bundle.HeapDumpAction_SavedDialogText(),\n                                        Bundle.HeapDumpAction_SavedDialogCaption(), null, \"HeapDumpAction.heapdumpSaved\", false)) { //NOI18N\n                                    ResultsManager.getDefault().openSnapshot(file);\n                                }\n                            } else {\n                                if (ProfilerIDESettings.getInstance().getAutoOpenSnapshot()) {\n                                    ResultsManager.getDefault().openSnapshot(file);\n                                }\n                            }\n                        } else {\n                            // Saving heapdump failed\n                            ProfilerDialogs.displayError(Bundle.HeapDumpAction_DumpingFailedMsg());\n                        }\n                    } catch (Exception e) {\n                        ProfilerDialogs.displayError(e.getMessage());\n                        ProfilerLogger.log(e);\n                    }\n                }\n            });\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/InternalStatsAction.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.openide.DialogDescriptor;\nimport org.openide.util.NbBundle;\nimport java.awt.*;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.ActionID;\nimport org.openide.util.HelpCtx;\n\n\n/**\n * Provisionary action to display internal profiler stats.\n *\n * @author Ian Formanek\n */\n@NbBundle.Messages({\n    \"LBL_InternalStatsAction=&Display Internal Statistics\",\n    \"HINT_InternalStatsAction=Display Internal Statistics\",\n    \"CAPTION_InternalStatisticsInstrHotswap=Internal Statistics of Instrumentation and Hotswapping Operations\"\n})\n@ActionID(category=\"Profile\", id=\"org.graalvm.visualvm.lib.profiler.actions.InternalStatsAction\")\n//@ActionRegistration(displayName=\"#LBL_InternalStatsAction\")\n//@ActionReference(path=\"Menu/Profile/Advanced\", position=300, separatorAfter=400)\npublic final class InternalStatsAction extends ProfilingAwareAction {\n    final private static int[] enabledStates = new int[]{Profiler.PROFILING_RUNNING};\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public InternalStatsAction() {\n        putValue(Action.NAME, Bundle.LBL_InternalStatsAction());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.HINT_InternalStatsAction());\n        putValue(\"noIconInMenu\", Boolean.TRUE); //NOI18N\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Invoked when an action occurs.\n     */\n    @Override\n    public void performAction() {\n        String stats;\n\n        try {\n            stats = Profiler.getDefault().getTargetAppRunner().getInternalStats();\n\n            final HTMLTextArea textArea = new HTMLTextArea(stats);\n            textArea.getAccessibleContext()\n                    .setAccessibleName(Bundle.CAPTION_InternalStatisticsInstrHotswap());\n\n            final JPanel p = new JPanel();\n            p.setLayout(new BorderLayout());\n            p.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));\n            p.add(new JScrollPane(textArea), BorderLayout.CENTER);\n\n            DialogDisplayer.getDefault().createDialog(new DialogDescriptor(p,\n                                                              Bundle.CAPTION_InternalStatisticsInstrHotswap(),\n                                                              true, new Object[] { DialogDescriptor.CLOSED_OPTION },\n                                                              DialogDescriptor.CLOSED_OPTION, DialogDescriptor.BOTTOM_ALIGN,\n                                                              null, null)).setVisible(true);\n        } catch (ClientUtils.TargetAppOrVMTerminated e) {\n             ProfilerDialogs.displayWarning(Bundle.MSG_NotAvailableNow(e.getMessage()));\n             ProfilerLogger.log(e.getMessage());\n        }\n    }\n\n    @Override\n    protected int[] enabledStates() {\n        return enabledStates;\n    }\n\n    @Override\n    public HelpCtx getHelpCtx() {\n        return null;\n    }\n\n    @Override\n    public String getName() {\n        return Bundle.LBL_InternalStatsAction();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/JavaPlatformSelector.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.openide.DialogDescriptor;\nimport org.openide.util.NbBundle;\nimport java.awt.*;\nimport javax.swing.*;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport org.graalvm.visualvm.lib.profiler.api.JavaPlatform;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.openide.DialogDisplayer;\nimport org.openide.util.HelpCtx;\n\n\n/**\n * A panel to select Java Platform for profiling\n *\n * @author Ian Formanek\n */\n@NbBundle.Messages({\n    \"JavaPlatformSelector_OkButtonName=OK\",\n    \"JavaPlatformSelector_UseSelPlatformChckBoxName=Always use the selected platform for profiling\",\n    \"JavaPlatformSelector_NoSupportedPlatformMsg=None of the installed Java Platforms can be used for profiling.\\nNetBeans Profiler requires JDK 5.0 Update 4 and newer.\\n\\nPlease install a suitable Java Platform and run calibration again.\",\n    \"JavaPlatformSelector_SelectPlatformCalibrateMsg=Select Java Platform to calibrate:\",\n    \"JavaPlatformSelector_SelectPlatformCalibrateDialogCaption=Select Java Platform to calibrate\",\n    \"JavaPlatformSelector_SelectPlatformProfileMsg=Please select Java Platform to use:\",\n    \"JavaPlatformSelector_SelectPlatformProfileDialogCaption=Select Java Platform for Profiling\",\n    \"JavaPlatformSelector_CannotUsePlatform=The Java Platform this project runs on cannot be used for profiling.\",\n    \"JavaPlatformSelector_ListAccessName=List of Java Platforms available for profiling\"\n})\npublic final class JavaPlatformSelector extends JPanel implements ListSelectionListener, HelpCtx.Provider {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static class JPListModel extends AbstractListModel {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private java.util.List<JavaPlatform> platforms;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        private JPListModel(java.util.List platforms) {\n            this.platforms = platforms;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public Object getElementAt(int index) {\n            return platforms.get(index).getDisplayName();\n        }\n\n        public int getSize() {\n            return platforms.size();\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n    private static final String HELP_CTX_KEY = \"JavaPlatformSelector.HelpCtx\";\n    private static final HelpCtx HELP_CTX = new HelpCtx(HELP_CTX_KEY);\n    private static JavaPlatformSelector defaultPlatform;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JLabel noteLabel;\n    private JButton okButton = new JButton(Bundle.JavaPlatformSelector_OkButtonName());\n    private JCheckBox alwaysCheckBox;\n    private JList list;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private JavaPlatformSelector() {\n        setLayout(new BorderLayout());\n        setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));\n        list = new JList();\n        list.setVisibleRowCount(6);\n        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        list.addListSelectionListener(this);\n        list.getAccessibleContext().setAccessibleName(Bundle.JavaPlatformSelector_ListAccessName());\n        noteLabel = new JLabel();\n        noteLabel.setLabelFor(list);\n        noteLabel.setFocusable(false);        \n        alwaysCheckBox = new JCheckBox(Bundle.JavaPlatformSelector_UseSelPlatformChckBoxName(), false);\n        add(new JScrollPane(list) {\n            public Dimension getPreferredSize() {\n                Dimension d = super.getPreferredSize();\n                d.width = Math.max(d.width, 400);\n                return d;\n            }\n        }, BorderLayout.CENTER);\n        add(noteLabel, BorderLayout.NORTH);\n        add(alwaysCheckBox, BorderLayout.SOUTH);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    public HelpCtx getHelpCtx() {\n        return HELP_CTX;\n    }\n\n    public static synchronized JavaPlatformSelector getDefault() {\n        if (defaultPlatform == null) {\n            defaultPlatform = new JavaPlatformSelector();\n        }\n\n        return defaultPlatform;\n    }\n\n    public JavaPlatform selectPlatformForCalibration() {\n        java.util.List<JavaPlatform> platforms = JavaPlatform.getPlatforms();\n\n        if (platforms.isEmpty()) {\n            ProfilerDialogs.displayError(Bundle.JavaPlatformSelector_NoSupportedPlatformMsg());\n            JavaPlatform.showCustomizer();\n\n            return null;\n        }\n\n        noteLabel.setText(Bundle.JavaPlatformSelector_SelectPlatformCalibrateMsg());\n        noteLabel.getAccessibleContext().setAccessibleName(Bundle.JavaPlatformSelector_SelectPlatformCalibrateMsg());\n        list.getAccessibleContext().setAccessibleDescription(Bundle.JavaPlatformSelector_SelectPlatformCalibrateMsg());\n        list.setModel(new JPListModel(platforms));\n        alwaysCheckBox.setVisible(false);\n\n        DialogDescriptor dd = new DialogDescriptor(this, Bundle.JavaPlatformSelector_SelectPlatformCalibrateDialogCaption(), true,\n                                                   new Object[] { okButton, DialogDescriptor.CANCEL_OPTION }, okButton,\n                                                   DialogDescriptor.BOTTOM_ALIGN, null, null);\n        list.setSelectedIndex(0);\n        validateOKButton();\n        Dialog selectDialog = DialogDisplayer.getDefault().createDialog(dd);\n        selectDialog.getAccessibleContext().setAccessibleDescription(Bundle.JavaPlatformSelector_SelectPlatformCalibrateDialogCaption());\n        selectDialog.setVisible(true);\n\n        if (dd.getValue() == okButton) {\n            int idx = list.getSelectedIndex();\n\n            return (JavaPlatform) platforms.get(idx);\n        }\n\n        return null;\n    }\n\n    public JavaPlatform selectPlatformToUse() {\n        java.util.List platforms = JavaPlatform.getPlatforms();\n\n        if (platforms.isEmpty()) {\n            ProfilerDialogs.displayError(Bundle.JavaPlatformSelector_NoSupportedPlatformMsg());\n            JavaPlatform.showCustomizer();\n\n            return null;\n        }\n\n        noteLabel.setText(\"<html>\"+Bundle.JavaPlatformSelector_CannotUsePlatform() + \"<br>\" // NOI18N\n                          + Bundle.JavaPlatformSelector_SelectPlatformProfileMsg()+\"</html>\"); // NOI18N\n        noteLabel.getAccessibleContext().setAccessibleName(\n            Bundle.JavaPlatformSelector_CannotUsePlatform() + \n            Bundle.JavaPlatformSelector_SelectPlatformProfileMsg());\n        list.getAccessibleContext().setAccessibleDescription(\n            Bundle.JavaPlatformSelector_CannotUsePlatform() + Bundle.JavaPlatformSelector_SelectPlatformCalibrateMsg());\n        list.setModel(new JPListModel(platforms));\n        alwaysCheckBox.setSelected(false);\n        alwaysCheckBox.setVisible(true);\n\n        DialogDescriptor dd = new DialogDescriptor(this, Bundle.JavaPlatformSelector_SelectPlatformProfileDialogCaption(), true,\n                                                   new Object[] { okButton, DialogDescriptor.CANCEL_OPTION }, okButton,\n                                                   DialogDescriptor.BOTTOM_ALIGN, null, null);\n        list.setSelectedIndex(0);\n        validateOKButton();\n        DialogDisplayer.getDefault().createDialog(dd).setVisible(true);\n\n        if (dd.getValue() == okButton) {\n            int idx = list.getSelectedIndex();\n            JavaPlatform plat = (JavaPlatform) platforms.get(idx);\n\n            if (alwaysCheckBox.isSelected()) {\n                // in this case store the selected platform as global platform to use\n                Profiler.getDefault().getGlobalProfilingSettings()\n                        .setJavaPlatformForProfiling((plat == null) ? null : plat.getDisplayName());\n            }\n\n            return plat;\n        }\n\n        return null;\n    }\n\n    public void valueChanged(ListSelectionEvent e) {\n        validateOKButton();\n    }\n\n    private void validateOKButton() {\n        okButton.setEnabled(list.getSelectedIndex() != -1);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/LoadSnapshotAction.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport java.awt.event.ActionEvent;\nimport java.io.File;\nimport java.lang.ref.Reference;\nimport java.lang.ref.WeakReference;\nimport java.util.ArrayList;\nimport javax.swing.*;\nimport javax.swing.filechooser.FileFilter;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.openide.awt.ActionID;\nimport org.openide.windows.WindowManager;\n\n\n/**\n * An action to prompt to select file and load/open snapshot from it.\n *\n * @author Ian Formanek\n */\n@NbBundle.Messages({\n    \"LoadSnapshotAction_ActionName=&Load Snapshot...\",\n    \"LoadSnapshotAction_ActionDescr=Load profiling results snapshot from disk\",\n    \"LoadSnapshotAction_OpenSnapshotDialogCaption=Open Snapshot File\",\n    \"LoadSnapshotAction_ProfilerSnapshotFileFilter=Profiler Snapshot Files (*.{0})\",\n    \"LoadSnapshotAction_OpenSnapshotHeapdumpDialogCaption=Open Snapshot or Heap Dump\",\n    \"LoadSnapshotAction_ProfilerSnapshotHeapdumpFileFilter=Profiler Snapshot or Heap Dump Files (*.{0} | *.{1})\",\n    \"LoadSnapshotAction_No_Snapshot_Selected=Not a .nps snapshot file\"\n})\n@ActionID(id = \"org.graalvm.visualvm.lib.profiler.actions.LoadSnapshotAction\", category = \"Profile\")\n//@ActionRegistration(iconInMenu = true, displayName = \"#LoadSnapshotAction_ActionName\", iconBase = \"org/graalvm/visualvm/lib/profiler/impl/icons/openSnapshot.png\")\n//@ActionReference(path = \"Menu/Profile\", position = 1400)\npublic final class LoadSnapshotAction extends AbstractAction {\n    //~ Static fields/initializers ----------------------------------------------------------------------------------------------- \n    private static File importDir;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public LoadSnapshotAction() {\n        putValue(Action.SHORT_DESCRIPTION, Bundle.LoadSnapshotAction_ActionDescr());\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    /**\n     * Invoked when an action occurs.\n     */\n    public void actionPerformed(final ActionEvent e) {\n        loadSnapshot(false);\n    }\n\n    public void loadSnapshotOrHeapdump() {\n        loadSnapshot(true);\n    }\n\n    // NOTE: supports also loading HeapDumps to simplify implementation of Load button in Control Panel\n    private void loadSnapshot(final boolean handleHeapdumps) {\n        JFileChooser chooser = new JFileChooser();\n\n        if (importDir != null) {\n            chooser.setCurrentDirectory(importDir);\n        }\n\n        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);\n        chooser.setMultiSelectionEnabled(true);\n        chooser.setDialogType(JFileChooser.OPEN_DIALOG);\n        chooser.setDialogTitle(handleHeapdumps ? \n            Bundle.LoadSnapshotAction_OpenSnapshotHeapdumpDialogCaption() : \n            Bundle.LoadSnapshotAction_OpenSnapshotDialogCaption());\n        chooser.setFileFilter(new FileFilter() {\n                public boolean accept(File f) {\n                    if (f.isDirectory()) return true;\n                    String fname = f.getName();\n                    if (fname.endsWith(\".\" + ResultsManager.SNAPSHOT_EXTENSION)) return true; // NOI18N\n                    if (fname.endsWith(\".\" + ResultsManager.STACKTRACES_SNAPSHOT_EXTENSION)) return true; // NOI18N\n                    if (handleHeapdumps && fname.endsWith(\".\" + ResultsManager.HEAPDUMP_EXTENSION)) return true; // NOI18N\n                    return false;\n                }\n\n                public String getDescription() {\n                    return handleHeapdumps\n                           ? Bundle.LoadSnapshotAction_ProfilerSnapshotHeapdumpFileFilter(\n                                ResultsManager.SNAPSHOT_EXTENSION, \n                                ResultsManager.HEAPDUMP_EXTENSION)\n                           : Bundle.LoadSnapshotAction_ProfilerSnapshotFileFilter(\n                                ResultsManager.SNAPSHOT_EXTENSION);\n                }\n            });\n\n        if (chooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) {\n            final File[] files = chooser.getSelectedFiles();\n            final ArrayList<FileObject> snapshotsFOArr = new ArrayList();\n            final ArrayList<File> heapdumpsFArr = new ArrayList();\n\n            for (File file : files) {\n                String fname = file.getName();\n\n                if (fname.endsWith(\".\" + ResultsManager.SNAPSHOT_EXTENSION) || fname.endsWith(\".\" + ResultsManager.STACKTRACES_SNAPSHOT_EXTENSION)) { // NOI18N\n                    snapshotsFOArr.add(FileUtil.toFileObject(FileUtil.normalizeFile(file)));\n                } else if (fname.endsWith(\".\" + ResultsManager.HEAPDUMP_EXTENSION)) { // NOI18N\n                    heapdumpsFArr.add(file);\n                }\n            }\n\n            if (!snapshotsFOArr.isEmpty()) {\n                processor().post(new Runnable() {\n                    public void run() {\n                        final LoadedSnapshot[] imported = ResultsManager.getDefault().loadSnapshots(\n                                snapshotsFOArr.toArray(new FileObject[0]));\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                ResultsManager.getDefault().openSnapshots(imported);\n                            }\n                        });\n                    }\n                });\n            } else if (!handleHeapdumps) {\n                ProfilerDialogs.displayError(Bundle.LoadSnapshotAction_No_Snapshot_Selected());\n\n            }\n\n            if (!heapdumpsFArr.isEmpty()) {\n                processor().post(new Runnable() {\n                    public void run() {\n                        for (File heapDump : heapdumpsFArr) {\n                            ResultsManager.getDefault().openSnapshot(heapDump);\n                        }\n                    }\n                });\n            }\n\n            importDir = chooser.getCurrentDirectory();\n        }\n    }\n    \n    private static Reference<RequestProcessor> PROCESSOR_REF;\n    private static synchronized RequestProcessor processor() {\n        RequestProcessor processor = PROCESSOR_REF == null ? null : PROCESSOR_REF.get();\n        if (processor == null) {\n            processor = new RequestProcessor(\"Profiler Snapshot Loader\", 3); // NOI18N\n            PROCESSOR_REF = new WeakReference(processor);\n        }\n        return processor;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/ProfilingAwareAction.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.event.SimpleProfilingStateAdapter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.openide.util.actions.CallableSystemAction;\n\n\n/**\n * @author Ian Formanek\n */\npublic abstract class ProfilingAwareAction extends CallableSystemAction {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    boolean enabledSet = false;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    protected ProfilingAwareAction() {\n        Profiler.getDefault().addProfilingStateListener(new SimpleProfilingStateAdapter() {\n\n            @Override\n            protected void update() {\n                updateAction();\n            }\n        });\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    public final boolean isEnabled() {\n        if(enabledSet) {\n            return super.isEnabled();\n        } else {\n            return shouldBeEnabled(Profiler.getDefault());\n        }\n    }\n\n    @Override\n    public final void setEnabled(boolean value) {\n        enabledSet = true;\n        super.setEnabled(value);\n    }\n\n    /** Called whenever state of the Profiler has changed.\n     *  By default this method use {@link #shouldBeEnabled(org.graalvm.visualvm.lib.common.Profiler)} to update the\n     *  enabled property of the action.\n     */\n    protected void updateAction()\n    {\n        setEnabled(shouldBeEnabled(Profiler.getDefault()));\n    }\n\n    /** Compute if the action is enabled based on the state of the Profiler.\n     *  Default implementation uses array returned by the {@link #enabledStates() } to determine the state.\n     */\n    protected boolean shouldBeEnabled(Profiler profiler) {\n        boolean shouldBeEnabled = false;\n        int lastProfilingState = profiler.getProfilingState();\n        int lastInstrumentation = lastProfilingState != Profiler.PROFILING_INACTIVE ?\n                                profiler.getTargetAppRunner().getProfilerClient().getCurrentInstrType() :\n                                 CommonConstants.INSTR_NONE;\n\n        final int[] enabledStates = enabledStates();\n\n        for (int i = 0; i < enabledStates.length; i++) {\n            if (lastProfilingState == enabledStates[i]) {\n                shouldBeEnabled = true;\n\n                break;\n            }\n        }\n\n        if (shouldBeEnabled && requiresInstrumentation()) {\n            shouldBeEnabled = (lastInstrumentation != CommonConstants.INSTR_NONE);\n        }\n\n        return shouldBeEnabled;\n    }    \n\n    /** Used by the default implementation of the {@link #shouldBeEnabled(Profiler) } to determine the enabled\n     *  state of the action. */\n    protected abstract int[] enabledStates();\n\n    @Override\n    protected final boolean asynchronous() {\n        return false;\n    }\n\n    protected boolean requiresInstrumentation() {\n        return false;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/ProfilingSupport.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport org.openide.util.NbBundle;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.utilities.ProfilerUtils;\n\n\n/**\n * A supporting class for the IDE profiling actions.\n * It centralizes all the code that has to do with figuring out context\n * from the IDE and interface it to the actual profiling.\n *\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"CAPTION_Question=Question\",\n    \"ProfilingSupport_StopStartProfileSessionMessage=Profiling session is currently in progress.\\nDo you want to stop the current session and start a new one?\",\n    \"ProfilingSupport_StopStartAttachSessionMessage=Profiling session is currently in progress\\nDo you want to detach from the target application and start a new profiling session?\",\n    \"ProfilingSupport_FailedLoadSettingsMsg=Failed to load attach settings: {0}\"\n})\npublic final class ProfilingSupport {\n\n    public static boolean checkProfilingInProgress() {\n        final Profiler profiler = Profiler.getDefault();\n        final int state = profiler.getProfilingState();\n        final int mode = profiler.getProfilingMode();\n\n        if ((state == Profiler.PROFILING_PAUSED) || (state == Profiler.PROFILING_RUNNING)) {\n            if (mode == Profiler.MODE_PROFILE) {\n                if (!ProfilerDialogs.displayConfirmation(\n                    Bundle.ProfilingSupport_StopStartProfileSessionMessage(),\n                    Bundle.CAPTION_Question())) {\n                    return true;\n                }\n                // TODO remove the condition when the method is only called in awt or only in RP\n                if (SwingUtilities.isEventDispatchThread()) {\n                    StopAction.getInstance().setEnabled(false);\n                    ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                        @Override\n                        public void run() {\n                            profiler.stopApp();\n                        }\n                    });\n                } else {\n                    profiler.stopApp();\n                }\n                \n            } else {\n                if (!ProfilerDialogs.displayConfirmation(\n                    Bundle.ProfilingSupport_StopStartAttachSessionMessage(), \n                    Bundle.CAPTION_Question())) {\n                    return true;\n                }\n\n                profiler.detachFromApp();\n            }\n        }\n\n        return false;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/ResetResultsAction.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport javax.swing.Action;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.profiler.utilities.Delegate;\nimport org.graalvm.visualvm.lib.profiler.ResultsListener;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.utilities.ProfilerUtils;\nimport org.openide.awt.ActionID;\nimport org.openide.awt.ActionReference;\nimport org.openide.awt.ActionReferences;\nimport org.openide.awt.ActionRegistration;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.actions.CallableSystemAction;\nimport org.openide.util.lookup.ServiceProvider;\n\n\n/**\n * Reset Collected Results for the profiled application (= Reset Collectors)\n *\n * @author Ian Formanek\n */\n@NbBundle.Messages({\n    \"LBL_ResetResultsAction=R&eset Collected Results\",\n    \"HINT_ResetResultsAction=Reset collected results\"\n})\npublic final class ResetResultsAction extends CallableSystemAction {\n\n    Listener resultListener;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /*\n     * The following code is an externalization of various listeners registered\n     * in the global lookup and needing access to an enclosing instance of\n     * ResetResultsAction.\n     * The enclosing instance will use the FQN registration to obtain the shared instance\n     * of the listener implementation and inject itself as a delegate into the listener.\n     */\n    @ServiceProvider(service=ResultsListener.class)\n    public static final class Listener extends Delegate<ResetResultsAction> implements ResultsListener {\n        @Override\n        public void resultsAvailable() {\n            if (getDelegate() != null) getDelegate().updateEnabledState();\n        }\n\n        @Override\n        public void resultsReset() { \n            if (getDelegate() != null) getDelegate().updateEnabledState();\n        }\n    }\n    \n    final private static class Singleton {\n        final private static ResetResultsAction INSTANCE = new ResetResultsAction();\n    }\n    \n    private ResetResultsAction() {\n        putValue(Action.NAME, Bundle.LBL_ResetResultsAction());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.HINT_ResetResultsAction());\n        putValue(Action.SMALL_ICON, Icons.getIcon(ProfilerIcons.RESET_RESULTS));\n        putValue(\"iconBase\", Icons.getResource(ProfilerIcons.RESET_RESULTS)); // NOI18N\n        \n        resultListener = Lookup.getDefault().lookup(Listener.class);\n        resultListener.setDelegate(this);\n        updateEnabledState();\n    }\n    \n    @ActionID(category=\"Profile\", id=\"org.graalvm.visualvm.lib.profiler.actions.ResetResultsAction\")\n    @ActionRegistration(displayName=\"#LBL_ResetResultsAction\", lazy=false)\n    @ActionReferences({\n        @ActionReference(path=\"Menu/Profile\", position=1000, separatorAfter=1100),\n        @ActionReference(path = \"Shortcuts\", name = \"AS-F2\")\n    })\n    public static ResetResultsAction getInstance() {\n        return Singleton.INSTANCE;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    /**\n     * Invoked when an action occurs.\n     */\n    @Override\n    public void performAction() {\n        \n        ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n            @Override\n            public void run() {\n                ResultsManager.getDefault().reset();\n        \n                try {\n                    TargetAppRunner runner = Profiler.getDefault().getTargetAppRunner();\n\n                    if (runner.targetJVMIsAlive()) {\n                        runner.resetTimers();\n                    } else {\n                        runner.getProfilerClient().resetClientData();\n\n                        // TODO \n                        //        CPUCallGraphBuilder.resetCollectors();\n                    }\n                } catch (ClientUtils.TargetAppOrVMTerminated targetAppOrVMTerminated) {} // ignore\n            }\n        });\n    }\n    \n    @Override\n    protected boolean asynchronous() {\n        return false;\n    }\n    \n    @Override\n    public HelpCtx getHelpCtx() {\n        return null;\n    }\n\n    @Override\n    public String getName() {\n        return Bundle.LBL_ResetResultsAction();\n    }\n\n    @Override\n    protected String iconResource() {\n        return Icons.getResource(ProfilerIcons.RESET_RESULTS);\n    }\n    \n    private void updateEnabledState() {\n        setEnabled(ResultsManager.getDefault().resultsAvailable());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/RunCalibrationAction.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.FlowLayout;\nimport org.openide.util.NbBundle;\nimport java.awt.event.ActionEvent;\nimport java.io.File;\nimport java.text.DateFormat;\nimport java.util.Arrays;\nimport java.util.Calendar;\nimport java.util.Date;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.Vector;\nimport java.util.logging.Level;\nimport javax.swing.*;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.DefaultTableCellRenderer;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.jfluid.global.CalibrationDataFileIO;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.profiler.api.JavaPlatform;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.spi.JavaPlatformManagerProvider;\nimport org.graalvm.visualvm.lib.profiler.spi.JavaPlatformProvider;\nimport org.graalvm.visualvm.lib.profiler.utilities.ProfilerUtils;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.ActionID;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\nimport org.openide.util.RequestProcessor;\n\n\n/**\n * Provisionary action to explicitely run Profiler calibration.\n *\n * @author Ian Formanek\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"LBL_RunCalibrationAction=&Manage Calibration Data\",\n    \"HINT_RunCalibrationAction=Manage Calibration Data\",\n    \"HINT_CalibrateDisabled=Calibration is done Automatically for remote platforms\",\n    \"LBL_JavaPlatform=Java Platform\",\n    \"LBL_LastCalibrated=Last Calibrated\",\n    \"LBL_NotCalibrated=Not calibrated\",\n    \"LBL_JavaPlatformsForProfiling=&Java platforms available for profiling:\",\n    \"LBL_Calibrate=&Calibrate\",\n    \"LBL_JavaPlatforms=Java &Platforms...\",\n    \"MSG_CalibrationOnProfile=Profiling session is currently in progress.\\nDo you want to stop the current session and perform the calibration?\",\n    \"MSG_CalibrationOnAttach=Profiling session is currently in progress\\nDo you want to detach from the target application and perform the calibration?\",\n    \"MSG_CalibrationFailed=Calibration failed.\\nPlease check your setup and run the calibration again.\",\n    \"TTP_PlatformName=Java platform name\",\n    \"TTP_CalibrationDate=Date of last calibration\"\n})\n@ActionID(category=\"Profile\", id=\"org.graalvm.visualvm.lib.profiler.actions.RunCalibrationAction\")\n//@ActionRegistration(displayName=\"#LBL_RunCalibrationAction\")\n//@ActionReference(path=\"Menu/Profile/Advanced\", position=100)\npublic final class RunCalibrationAction extends AbstractAction {\n    \n    private static final HelpCtx HELP_CTX = new HelpCtx(\"ManageCalibration.HelpCtx\"); // NOI18N\n    \n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public RunCalibrationAction() {\n        putValue(Action.NAME, Bundle.LBL_RunCalibrationAction());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.HINT_RunCalibrationAction());\n        putValue(\"noIconInMenu\", Boolean.TRUE); // NOI18N\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    /**\n     * Invoked when an action occurs.\n     */\n    public void actionPerformed(final ActionEvent e) {\n        List<JavaPlatform> platforms = JavaPlatform.getPlatforms();\n        String[] columnNames = new String[] { Bundle.LBL_JavaPlatform(),\n                                              Bundle.LBL_LastCalibrated() };\n        Object[][] columnData = new Object[platforms.size()][2];\n        for (int i = 0; i < platforms.size(); i++)\n            columnData[i] = new Object[] { platforms.get(i), null };\n        final TableModel model = new DefaultTableModel(columnData, columnNames) {\n            public boolean isCellEditable(int row, int column) { return false; }\n        };\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { displayUI(model); }\n        });\n        \n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() { refreshTimes(model); }\n        });\n    }\n    \n    private void displayUI(final TableModel model) {\n        final ProfilerTable table = new ProfilerTable(model, false, true, null);\n        table.getColumnModel().getColumn(1).setCellRenderer(new CalibrationDateCellRenderer());\n        table.setDefaultColumnWidth(getColumnWidth());\n        table.setSortColumn(0);\n        table.setPreferredScrollableViewportSize(new Dimension(400, 10));\n        table.setVisibleRows(6);\n        table.setColumnToolTips(new String[] { Bundle.TTP_PlatformName(),\n                                               Bundle.TTP_CalibrationDate() });\n        \n        ProfilerTableContainer container = new ProfilerTableContainer(table, true, null);\n        container.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));\n        \n        JLabel label = new JLabel();\n        Mnemonics.setLocalizedText(label, Bundle.LBL_JavaPlatformsForProfiling());\n        label.setLabelFor(table);\n        label.setBorder(BorderFactory.createEmptyBorder(15, 10, 5, 10));\n        \n        final JButton calibrate = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) { calibrate(table); }\n        };\n        Mnemonics.setLocalizedText(calibrate, Bundle.LBL_Calibrate());\n        JButton platforms = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                JavaPlatform.showCustomizer();\n                refreshModel(table);\n            }\n        };\n        Mnemonics.setLocalizedText(platforms, Bundle.LBL_JavaPlatforms());\n        JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEADING, 10, 10));\n        buttons.add(calibrate);\n        buttons.add(platforms);\n        \n        table.setDefaultAction(new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { calibrate(table); }\n        });\n        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n            public void valueChanged(ListSelectionEvent e) {\n                if (table.getSelectedRow() != -1) {\n                    boolean remote = isRemotePlatform((JavaPlatform)table.getValueAt(table.getSelectedRow(), table.convertColumnIndexToView(0)));\n                    if (remote) {\n                        calibrate.setToolTipText(Bundle.HINT_CalibrateDisabled());\n                    } else {\n                        calibrate.setToolTipText(\"\"); //NOI18N\n                    }\n                    calibrate.setEnabled(!remote);\n                }\n            }\n        });\n        calibrate.setEnabled(false);\n        table.clearSelection();\n        \n        JPanel panel = new JPanel(new BorderLayout());\n        panel.add(label, BorderLayout.NORTH);\n        panel.add(container, BorderLayout.CENTER);\n        panel.add(buttons, BorderLayout.SOUTH);\n        \n        DialogDescriptor dd = new DialogDescriptor(panel,\n                Bundle.HINT_RunCalibrationAction(), true,\n                new Object[] { DialogDescriptor.CLOSED_OPTION },\n                DialogDescriptor.CLOSED_OPTION, 0, HELP_CTX, null);\n        DialogDisplayer.getDefault().createDialog(dd).setVisible(true);\n    }\n    \n    private int getColumnWidth() {\n        int width = new JLabel(Bundle.LBL_LastCalibrated() + \"XXX\") // NOI18N\n                    .getPreferredSize().width;\n        width = Math.max(width, new JLabel(Bundle.LBL_NotCalibrated() + \"XXX\") // NOI18N\n                    .getPreferredSize().width);\n        width = Math.max(width, new JLabel(DateFormat.getDateInstance()\n                    .format(new Date()) + \"XXX\").getPreferredSize().width); // NOI18N\n        width = Math.max(width, new JLabel(DateFormat.getTimeInstance()\n                    .format(new Date()) + \"XXX\").getPreferredSize().width); // NOI18N\n        return width;\n    }\n    \n    private void refreshTimes(final TableModel model) {\n        for (int i = 0; i < model.getRowCount(); i++) {\n            JavaPlatform platform = (JavaPlatform)model.getValueAt(i, 0);\n            boolean remote = isRemotePlatform(platform);\n            String version = platform.getPlatformJDKVersion();\n            Long modified = null;\n            if (remote) {\n                try {\n                    File f = new File(CalibrationDataFileIO.getCalibrationDataFileName(version)+\".\"+platform.getProperties().get(\"platform.host\")); //NOI18N\n                    if (f.isFile()) modified = Long.valueOf(f.lastModified());\n                } catch (Exception e) {}\n            } else {\n                try {\n                    File f = new File(CalibrationDataFileIO.getCalibrationDataFileName(version));\n                    if (f.isFile()) modified = Long.valueOf(f.lastModified());\n                } catch (Exception e) {}\n            }\n            final int index = i;\n            final Long _modified = modified;\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { model.setValueAt(_modified, index, 1); }\n            });\n        }\n    }\n    \n    private void refreshModel(final ProfilerTable table) {\n        Object selected = null;\n        Set original = new HashSet();\n        int selrow = table.getSelectedRow();\n        int column = table.convertColumnIndexToView(0);\n        for (int row = 0; row < table.getRowCount(); row++) {\n            Object value = table.getValueAt(row, column);\n            original.add(value);\n            if (row == selrow) selected = value;\n        }\n        \n        final DefaultTableModel model = (DefaultTableModel)table.getModel();\n        Vector data = model.getDataVector();\n        data.clear();\n        \n        for (JavaPlatform platform : JavaPlatform.getPlatforms()) {\n            data.add(new Vector(Arrays.asList(platform, null)));\n            if (!original.contains(platform)) selected = platform;\n        }\n        \n        table.clearSelection();\n        model.fireTableDataChanged();\n        \n        if (selected != null) table.selectValue(selected, column, true);\n        \n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() { refreshTimes(model); }\n        });\n    }\n    \n    \n    private void calibrate(ProfilerTable table) {\n        int row = table.getSelectedRow();\n        if (row == -1) return;\n\n        int col = table.convertColumnIndexToView(0);\n        final JavaPlatform platform = (JavaPlatform)table.getValueAt(row, col);\n        final DefaultTableModel model = (DefaultTableModel)table.getModel();\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { calibrate(platform, model); }\n        });\n    }\n    \n    \n    private static boolean isRemotePlatform(final JavaPlatform platform) {\n        JavaPlatformManagerProvider impl = Lookup.getDefault().lookup(JavaPlatformManagerProvider.class);\n        if (impl == null) {\n            ProfilerUtils.getProfilerErrorManager().log(Level.WARNING.intValue(), \"No instance of JavaPlatformManagerProvider found in Lookup\");  //NOI18N\n            return false;\n        }\n        for (JavaPlatformProvider jpp : impl.getPlatforms()) {\n            if ( (platform.getPlatformId() != null) && (platform.getPlatformId().equals(jpp.getPlatformId())) && (platform.getProperties().containsKey(\"platform.host\")) ) {//NOI18N\n                return true;\n                \n            }\n        }\n        return false;\n    }\n    \n    private void calibrate(final JavaPlatform platform, final TableModel model) {\n        final int state = Profiler.getDefault().getProfilingState();\n        final int mode = Profiler.getDefault().getProfilingMode();\n        boolean terminate = false;\n        boolean detach = false;\n\n        if ((state == Profiler.PROFILING_PAUSED) || (state == Profiler.PROFILING_RUNNING)) {\n            if (mode == Profiler.MODE_PROFILE) {\n                if (!ProfilerDialogs.displayConfirmation(\n                    Bundle.MSG_CalibrationOnProfile(), \n                    Bundle.CAPTION_Question())) {\n                    return;\n                }\n                terminate = true;\n            } else {\n                if (!ProfilerDialogs.displayConfirmation(\n                    Bundle.MSG_CalibrationOnAttach(), \n                    Bundle.CAPTION_Question())) { \n                    return;\n                }\n                detach = true;\n            }\n        }\n\n        final boolean doDetach = detach;\n        final boolean doStop = terminate;\n\n        ProfilerUtils.getProfilerRequestProcessor().post(new Runnable() {\n            public void run() {\n                if (doDetach) {\n                    Profiler.getDefault().detachFromApp();\n                } else if (doStop) {\n                    Profiler.getDefault().stopApp();\n                }\n                boolean calibrated = Profiler.getDefault().runCalibration(false,\n                                              platform.getPlatformJavaFile(),\n                                              platform.getPlatformJDKVersion(),\n                                              platform.getPlatformArchitecture());\n                refreshTimes(model);\n                if (!calibrated) ProfilerDialogs.displayError(Bundle.MSG_CalibrationFailed());\n            }\n        }, 0, Thread.MAX_PRIORITY);\n    }\n    \n    \n    private static class CalibrationDateCellRenderer extends DefaultTableCellRenderer {\n    \n        private static Calendar CALENDAR;\n        private static int REF_DAY_OF_YEAR = -1;\n        private static int DAY_OF_YEAR = -1;\n        private static int YEAR = -1;\n        private static int ERA = -1;\n\n        private static Date DATE;\n        private static DateFormat FORMAT_TIME;\n        private static DateFormat FORMAT_DATE;\n        \n        CalibrationDateCellRenderer() {\n            setHorizontalAlignment(TRAILING);\n        }\n\n        protected void setValue(Object value) {\n            if (value == null) {\n                setText(Bundle.LBL_NotCalibrated());\n            } else {\n                long time = ((Long)value).longValue();\n                setValue(time, isToday(time));\n            }\n        }\n\n        private void setValue(long time, boolean today) {\n            DateFormat format;\n            if (today) {\n                if (FORMAT_TIME == null) FORMAT_TIME = DateFormat.getTimeInstance();\n                format = FORMAT_TIME;\n            } else {\n                if (FORMAT_DATE == null) FORMAT_DATE = DateFormat.getDateInstance();\n                format = FORMAT_DATE;\n            }\n\n            if (DATE == null) DATE = new Date();\n            DATE.setTime(time);\n\n            setText(format.format(DATE));\n        }\n\n        private static boolean isToday(long time) {\n            if (REF_DAY_OF_YEAR != -1 && CALENDAR.get(Calendar.DAY_OF_YEAR)\n                != REF_DAY_OF_YEAR) CALENDAR = null;\n\n            if (CALENDAR == null) initializeCalendar();\n            CALENDAR.setTimeInMillis(time);\n\n            return DAY_OF_YEAR == CALENDAR.get(Calendar.DAY_OF_YEAR) &&\n                   YEAR == CALENDAR.get(Calendar.YEAR) &&\n                   ERA == CALENDAR.get(Calendar.ERA);\n        }\n\n        private static void initializeCalendar() {\n            CALENDAR = Calendar.getInstance();\n            DAY_OF_YEAR = CALENDAR.get(Calendar.DAY_OF_YEAR);\n            YEAR = CALENDAR.get(Calendar.YEAR);\n            ERA = CALENDAR.get(Calendar.ERA);\n            if (REF_DAY_OF_YEAR == -1) REF_DAY_OF_YEAR = DAY_OF_YEAR;\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/RunGCAction.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport javax.swing.Action;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.utilities.ProfilerUtils;\nimport org.openide.awt.ActionID;\nimport org.openide.awt.ActionReference;\nimport org.openide.awt.ActionRegistration;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\n\n\n/**\n * Run Garbage Collection in the target application VM\n *\n * @author Ian Formanek\n */\n@NbBundle.Messages({\n    \"LBL_RunGCAction=Run &GC\",\n    \"HINT_RunGCAction=Request garbage collection in the profiled process\"\n})\npublic final class RunGCAction extends ProfilingAwareAction {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final int[] ENABLED_STATES = new int[] { Profiler.PROFILING_RUNNING };\n\n    final private static class Singleton {\n        final private static RunGCAction INSTANCE = new RunGCAction();\n    }\n\n    @ActionID(id = \"org.graalvm.visualvm.lib.profiler.actions.RunGCAction\", category = \"Profile\")\n    @ActionRegistration(displayName = \"#LBL_RunGCAction\", lazy=false)\n    @ActionReference(path = \"Menu/Profile\", position = 700, separatorAfter=800)\n    public static RunGCAction getInstance() {\n        return Singleton.INSTANCE;\n    }\n\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    protected RunGCAction() {\n        super();\n        setIcon(Icons.getIcon(ProfilerIcons.RUN_GC));\n        putValue(\"iconBase\", Icons.getResource(ProfilerIcons.RUN_GC)); // NOI18N\n        putProperty(Action.SHORT_DESCRIPTION, Bundle.HINT_RunGCAction());\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public HelpCtx getHelpCtx() {\n        return HelpCtx.DEFAULT_HELP;\n\n        // If you will provide context help then use:\n        // return new HelpCtx(MyAction.class);\n    }\n\n    public String getName() {\n        return Bundle.LBL_RunGCAction();\n    }\n\n    public void performAction() {\n        ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n            public void run() {\n                try {\n                    Profiler.getDefault().getTargetAppRunner().runGC();\n                } catch (final ClientUtils.TargetAppOrVMTerminated e) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { ProfilerDialogs.displayWarning(e.getMessage()); }\n                    });\n                    ProfilerLogger.log(e.getMessage());\n                }\n            }\n        });\n    }\n\n    protected int[] enabledStates() {\n        return ENABLED_STATES;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/SnapshotsWindowAction.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport org.openide.util.NbBundle;\nimport java.awt.event.ActionEvent;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.v2.SnapshotsWindow;\nimport org.openide.awt.ActionID;\nimport org.openide.awt.ActionReference;\nimport org.openide.awt.ActionRegistration;\n\n\n/**\n * Action to display the Snapshots window.\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"LBL_SnapshotsWindowAction=&Snapshots\",\n    \"HINT_SnapshotsWindowAction=Show Profiler Snapshots Window\"\n})\n@ActionID(category=\"Profile\", id=\"org.netbeans.modules.profiles.actions.SnapshotsWindowAction\")\n@ActionRegistration(displayName=\"#LBL_SnapshotsWindowAction\", iconBase=\"org/graalvm/visualvm/lib/profiler/impl/icons/takeSnapshot.png\")\n@ActionReference(path=\"Menu/Window/Profile\", position=99)\npublic final class SnapshotsWindowAction extends AbstractAction {\n\n    public SnapshotsWindowAction() {\n        putValue(Action.NAME, Bundle.LBL_SnapshotsWindowAction());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.HINT_SnapshotsWindowAction());\n        putValue(Action.SMALL_ICON, Icons.getIcon(ProfilerIcons.SNAPSHOT_TAKE));\n        putValue(\"iconBase\", Icons.getResource(ProfilerIcons.SNAPSHOT_TAKE));\n    }\n\n\n    public void actionPerformed(final ActionEvent e) {\n        SnapshotsWindow.instance().showStandalone();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/StopAction.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.openide.util.NbBundle;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.utilities.ProfilerUtils;\nimport org.openide.util.HelpCtx;\n\n\n/**\n * Stop/Finish the currently profiled target application\n *\n * @author Ian Formanek\n */\n@NbBundle.Messages({\n    \"StopAction_DoYouWantToTerminateCap=Detach Profiler\",\n    \"StopAction_DoYouWantToTerminateMsg=Do you want to terminate the profiled application upon detach?\",\n    \"LBL_StopAction=&Stop Profiling Session\",\n    \"HINT_StopAction=Stop (Terminate) the Profiled Application\",\n    \"LBL_DetachAction=Detach...\",\n    \"HINT_DetachAction=Detach from the Profiled Application\"\n})\npublic final class StopAction extends ProfilingAwareAction {\n    final private static int[] enabledStates = new int[]{Profiler.PROFILING_PAUSED, Profiler.PROFILING_RUNNING, Profiler.PROFILING_STARTED};\n\n    final private static class Singleton {\n        final private static StopAction INSTANCE = new StopAction();\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private boolean taskPosted = false;\n    private int mode = -1; // not determined yet\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private StopAction() {\n        updateAction();\n    }\n\n//    @ActionID(category=\"Profile\", id=\"org.graalvm.visualvm.lib.profiler.actions.StopAction\")\n//    @ActionRegistration(displayName=\"#LBL_StopAction\")\n//    @ActionReferences({\n//        @ActionReference(path=\"Menu/Profile\", position=300, separatorAfter=400),\n//        @ActionReference(path=\"Shortcuts\", name=\"S-F2\")\n//    })\n    public static StopAction getInstance() {\n        return Singleton.INSTANCE;\n    }\n    \n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Invoked when an action occurs.\n     */\n    public void performAction() {\n        if (taskPosted) { // TODO this doesn't prevent from multiple stop tasks being posted!!!\n\n            return; // already performing\n        }\n\n        Runnable task = null;\n\n        if (mode == Profiler.MODE_ATTACH) {\n            Boolean ret = ProfilerDialogs.displayCancellableConfirmationDNSA(\n                Bundle.StopAction_DoYouWantToTerminateMsg(), Bundle.StopAction_DoYouWantToTerminateCap(),\n                null, StopAction.class.getName(), false);\n\n            if (Boolean.TRUE.equals(ret)) {\n                task = new Runnable() {\n                        public void run() {\n                            Profiler.getDefault().stopApp();\n                            taskPosted = false;\n                        }\n                    };\n            } else if (Boolean.FALSE.equals(ret)) {\n                task = new Runnable() {\n                        public void run() {\n                            Profiler.getDefault().detachFromApp();\n                            taskPosted = false;\n                        }\n                    };\n            }\n        } else {\n            task = new Runnable() {\n                    public void run() {\n                        Profiler.getDefault().stopApp();\n                        taskPosted = false;\n                    }\n                };\n        }\n\n        if (task != null) {\n            taskPosted = true;\n            updateAction();\n            ProfilerUtils.runInProfilerRequestProcessor(task);\n        }\n    }\n\n    @Override\n    protected int[] enabledStates() {\n        return enabledStates;\n    }\n\n    @Override\n    public HelpCtx getHelpCtx() {\n        return new HelpCtx(StopAction.class);\n    }\n\n    @Override\n    public String getName() {\n        return (mode == Profiler.MODE_PROFILE) ? Bundle.LBL_StopAction() : Bundle.LBL_DetachAction();\n    }\n\n    @Override\n    protected void updateAction() {\n        super.updateAction();\n        mode = Profiler.getDefault().getProfilingMode();\n\n        if (mode == Profiler.MODE_PROFILE) {\n            setToStop(); \n        } else if (mode == Profiler.MODE_ATTACH) {\n            setToDetach(); \n        }\n        \n        firePropertyChange(SMALL_ICON, null, null);\n    }\n\n    @Override\n    protected boolean shouldBeEnabled(Profiler profiler) {\n        return super.shouldBeEnabled(profiler) && (profiler.getProfilingState() == Profiler.PROFILING_INACTIVE\n                || profiler.getServerState() == CommonConstants.SERVER_RUNNING);\n    }\n    \n    private void setToDetach() {\n        putValue(Action.NAME, Bundle.LBL_DetachAction());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.HINT_DetachAction());\n        putValue(Action.SMALL_ICON, Icons.getIcon(GeneralIcons.DETACH));\n        putValue(\"iconBase\", Icons.getResource(GeneralIcons.DETACH)); // NOI18N\n        setIcon(Icons.getIcon(GeneralIcons.DETACH));\n    }\n\n    private void setToStop() {\n        putValue(Action.NAME, Bundle.LBL_StopAction());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.HINT_StopAction());\n        putValue(Action.SMALL_ICON, Icons.getIcon(GeneralIcons.STOP));\n        putValue(\"iconBase\", Icons.getResource(GeneralIcons.STOP)); // NOI18N\n        setIcon(Icons.getIcon(GeneralIcons.STOP));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/TakeSnapshotAction.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport javax.swing.Action;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.profiler.ResultsListener;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.utilities.Delegate;\nimport org.graalvm.visualvm.lib.profiler.utilities.ProfilerUtils;\nimport org.openide.awt.ActionID;\nimport org.openide.awt.ActionReference;\nimport org.openide.awt.ActionReferences;\nimport org.openide.awt.ActionRegistration;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n\n/**\n * Action to take snapshot of results.\n *\n * @author Ian Formanek\n */\n@NbBundle.Messages({\n    \"LBL_TakeSnapshotAction=&Take Snapshot of Collected Results\",\n    \"HINT_TakeSnapshotAction=Take snapshot of collected results\"\n})\npublic final class TakeSnapshotAction extends ProfilingAwareAction {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final int[] ENABLED_STATES = new int[] {\n                                                    Profiler.PROFILING_RUNNING, Profiler.PROFILING_PAUSED,\n                                                    Profiler.PROFILING_STOPPED\n                                                };\n\n    private Listener listener;\n\n    /*\n     * The following code is an externalization of various listeners registered\n     * in the global lookup and needing access to an enclosing instance of\n     * TakeSnapshotAction.\n     * The enclosing instance will use the FQN registration to obtain the shared instance\n     * of the listener implementation and inject itself as a delegate into the listener.\n     */\n    @ServiceProvider(service=ResultsListener.class)\n    public static final class Listener extends Delegate<TakeSnapshotAction> implements ResultsListener {\n\n        @Override\n        public void resultsAvailable() {\n            if (getDelegate() != null) getDelegate().updateAction();\n        }\n\n        @Override\n        public void resultsReset() {\n            if (getDelegate() != null) getDelegate().updateAction();\n        }\n        \n    }\n    \n    private static final class Singleton {\n        final private static TakeSnapshotAction INSTANCE = new TakeSnapshotAction();\n    }\n    \n    @ActionID(id = \"org.graalvm.visualvm.lib.profiler.actions.TakeSnapshotAction\", category = \"Profile\")\n    @ActionRegistration(displayName = \"#LBL_TakeSnapshotAction\")\n    @ActionReferences(value = {\n        @ActionReference(path = \"Shortcuts\", name = \"A-F2\"),\n        @ActionReference(path = \"Menu/Profile\", position = 900)})\n    public static TakeSnapshotAction getInstance() {\n        return Singleton.INSTANCE;\n    }\n    \n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n    public TakeSnapshotAction() {\n        listener = Lookup.getDefault().lookup(Listener.class);\n        listener.setDelegate(this);\n        setIcon(Icons.getIcon(ProfilerIcons.SNAPSHOT_TAKE));\n        putValue(Action.SHORT_DESCRIPTION, Bundle.HINT_TakeSnapshotAction());\n        putValue(\"iconBase\", Icons.getResource(ProfilerIcons.SNAPSHOT_TAKE)); // NOI18N\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    protected boolean shouldBeEnabled(Profiler profiler) {\n        return super.shouldBeEnabled(profiler) && ResultsManager.getDefault().resultsAvailable();\n    }\n\n    public HelpCtx getHelpCtx() {\n        return HelpCtx.DEFAULT_HELP;\n\n        // If you will provide context help then use:\n        // return new HelpCtx(MyAction.class);\n    }\n\n    public String getName() {\n        return Bundle.LBL_TakeSnapshotAction();\n    }\n\n    @Override\n    public void performAction() {\n        ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                public void run() {\n                    ResultsManager.getDefault().takeSnapshot();\n                }\n            });\n    }\n\n    @Override\n    protected int[] enabledStates() {\n        return ENABLED_STATES;\n    }\n\n    protected boolean requiresInstrumentation() {\n        return true;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/actions/TakeThreadDumpAction.java",
    "content": "/*\n * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport java.util.concurrent.ExecutionException;\nimport javax.swing.Action;\nimport javax.swing.SwingWorker;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.jfluid.results.threads.ThreadDump;\nimport org.graalvm.visualvm.lib.profiler.ThreadDumpWindow;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.awt.ActionID;\nimport org.openide.awt.ActionReference;\nimport org.openide.awt.ActionReferences;\nimport org.openide.awt.ActionRegistration;\nimport org.openide.util.Exceptions;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\n@NbBundle.Messages({\n    \"LBL_TakeThreadDumpAction=&Take Thread Dump\",\n    \"HINT_TakeThreadDumpAction=Take thread dump from the profiled process\"\n})\npublic class TakeThreadDumpAction extends ProfilingAwareAction {\n\n    private static final int[] ENABLED_STATES = new int[]{Profiler.PROFILING_RUNNING};\n\n    private static final class Singleton {\n\n        final private static TakeThreadDumpAction INSTANCE = new TakeThreadDumpAction();\n    }\n\n    @ActionID(id = \"org.graalvm.visualvm.lib.profiler.actions.TakeThreadDumpAction\", category = \"Profile\")\n    @ActionRegistration(displayName = \"#LBL_TakeThreadDumpAction\")\n    @ActionReferences(value = {\n        //        @ActionReference(path = \"Shortcuts\", name = \"C-F3\"),\n        @ActionReference(path = \"Menu/Profile\", position = 500)})\n    public static TakeThreadDumpAction getInstance() {\n        return Singleton.INSTANCE;\n    }\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n    public TakeThreadDumpAction() {\n        setIcon(Icons.getIcon(ProfilerIcons.SNAPSHOT_THREADS));\n        putValue(\"iconBase\", Icons.getResource(ProfilerIcons.SNAPSHOT_THREADS)); // NOI18N\n        putProperty(Action.SHORT_DESCRIPTION, Bundle.HINT_TakeThreadDumpAction());\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    public HelpCtx getHelpCtx() {\n        return HelpCtx.DEFAULT_HELP;\n\n        // If you will provide context help then use:\n        // return new HelpCtx(MyAction.class);\n    }\n\n    public String getName() {\n        return Bundle.LBL_TakeThreadDumpAction();\n    }\n\n    @Override\n    protected int[] enabledStates() {\n        return ENABLED_STATES;\n    }\n\n    @Override\n    public void performAction() {\n        new SwingWorker<ThreadDump, Object>() {\n\n            @Override\n            protected ThreadDump doInBackground()throws Exception {\n                try {\n                    ProfilerClient client = Profiler.getDefault().getTargetAppRunner().getProfilerClient();\n                    return client.takeThreadDump();\n\n                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                    ProfilerLogger.log(ex.getMessage());\n                }\n                return null;\n            }\n\n            @Override\n            protected void done() {\n                try {\n                    ThreadDump threadDump = get();\n                    if (threadDump != null) {\n                        ThreadDumpWindow win = new ThreadDumpWindow(threadDump);\n                        win.open();\n                        win.requestActive();\n                    }\n                } catch (InterruptedException ex) {\n                    Exceptions.printStackTrace(ex);\n                } catch (ExecutionException ex) {\n                    Exceptions.printStackTrace(ex);\n                }\n            }\n            \n        }.execute();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/impl/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/impl/CloseButtonProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.impl;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport javax.swing.JButton;\nimport org.graalvm.visualvm.lib.ui.components.CloseButton;\nimport org.openide.awt.CloseButtonFactory;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service = CloseButton.Provider.class)\npublic class CloseButtonProvider extends CloseButton.Provider {\n\n    @Override\n    public JButton create(final Runnable onClose) {\n        JButton close = CloseButtonFactory.createBigCloseButton();\n        if (onClose != null) close.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { onClose.run(); }\n        });\n        return close;\n    }\n\n    @Override\n    public JButton createSmall(final Runnable onClose) {\n        JButton close = CloseButtonFactory.createCloseButton();\n        if (onClose != null) close.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { onClose.run(); }\n        });\n        return close;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/impl/ProfilerDialogs.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.impl;\n\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\nimport java.awt.*;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.ui.NBHTMLLabel;\n\n@NbBundle.Messages({\n    \"ProfilerDialogs_DontShowAgainMsg=Do not show this message again\",\n    \"ProfilerDialogs_ShowDetailsButtonText=Show Details\"\n})\nfinal class ProfilerDialogs {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    public static final class DNSAConfirmation extends NotifyDescriptor.Confirmation {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private final String dnsaKey;\n        private String dnsaMessage = Bundle.ProfilerDialogs_DontShowAgainMsg();\n        private boolean dnsaDefault = true;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        /**\n         * Create a yes/no/cancel question with default title.\n         *\n         * @param message the message object\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAConfirmation(final String key, final Object message) {\n            super(message);\n            this.dnsaKey = key;\n        }\n\n        /**\n         * Create a yes/no/cancel question.\n         *\n         * @param message the message object\n         * @param title   the dialog title\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAConfirmation(final String key, final Object message, final String title) {\n            super(message, title);\n            this.dnsaKey = key;\n        }\n\n        /**\n         * Create a question with default title.\n         *\n         * @param message    the message object\n         * @param optionType the type of options to display to the user\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAConfirmation(final String key, final Object message, final int optionType) {\n            super(message, optionType);\n            this.dnsaKey = key;\n        }\n\n        /**\n         * Create a question.\n         *\n         * @param message    the message object\n         * @param title      the dialog title\n         * @param optionType the type of options to display to the user\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAConfirmation(final String key, final Object message, final String title, final int optionType) {\n            super(message, title, optionType);\n            this.dnsaKey = key;\n        }\n\n        /**\n         * Create a confirmation with default title.\n         *\n         * @param message     the message object\n         * @param optionType  the type of options to display to the user\n         * @param messageType the type of message to use\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAConfirmation(final String key, final Object message, final int optionType, final int messageType) {\n            super(message, optionType, messageType);\n            this.dnsaKey = key;\n        }\n\n        /**\n         * Create a confirmation.\n         *\n         * @param message     the message object\n         * @param title       the dialog title\n         * @param optionType  the type of options to display to the user\n         * @param messageType the type of message to use\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAConfirmation(final String key, final Object message, final String title, final int optionType,\n                                final int messageType) {\n            super(message, title, optionType, messageType);\n            this.dnsaKey = key;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void setDNSADefault(boolean value) {\n            this.dnsaDefault = value;\n        }\n\n        public boolean getDNSADefault() {\n            return dnsaDefault;\n        }\n\n        public String getDNSAKey() {\n            return dnsaKey;\n        }\n\n        public void setDNSAMessage(String value) {\n            this.dnsaMessage = value;\n        }\n\n        public String getDNSAMessage() {\n            return dnsaMessage;\n        }\n    }\n\n    // If No is selected the Don't show again is reset\n    public static final class DNSAConfirmationChecked extends NotifyDescriptor.Confirmation {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private final String dnsaKey;\n        private String dnsaMessage = Bundle.ProfilerDialogs_DontShowAgainMsg();\n        private boolean dnsaDefault = false;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        /**\n         * Create a yes/no/cancel question with default title.\n         *\n         * @param message the message object\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAConfirmationChecked(final String key, final Object message) {\n            super(message);\n            this.dnsaKey = key;\n        }\n\n        /**\n         * Create a yes/no/cancel question.\n         *\n         * @param message the message object\n         * @param title   the dialog title\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAConfirmationChecked(final String key, final Object message, final String title) {\n            super(message, title);\n            this.dnsaKey = key;\n        }\n\n        /**\n         * Create a question with default title.\n         *\n         * @param message    the message object\n         * @param optionType the type of options to display to the user\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAConfirmationChecked(final String key, final Object message, final int optionType) {\n            super(message, optionType);\n            this.dnsaKey = key;\n        }\n\n        /**\n         * Create a question.\n         *\n         * @param message    the message object\n         * @param title      the dialog title\n         * @param optionType the type of options to display to the user\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAConfirmationChecked(final String key, final Object message, final String title, final int optionType) {\n            super(message, title, optionType);\n            this.dnsaKey = key;\n        }\n\n        /**\n         * Create a confirmation with default title.\n         *\n         * @param message     the message object\n         * @param optionType  the type of options to display to the user\n         * @param messageType the type of message to use\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAConfirmationChecked(final String key, final Object message, final int optionType, final int messageType) {\n            super(message, optionType, messageType);\n            this.dnsaKey = key;\n        }\n\n        /**\n         * Create a confirmation.\n         *\n         * @param message     the message object\n         * @param title       the dialog title\n         * @param optionType  the type of options to display to the user\n         * @param messageType the type of message to use\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAConfirmationChecked(final String key, final Object message, final String title, final int optionType,\n                                       final int messageType) {\n            super(message, title, optionType, messageType);\n            this.dnsaKey = key;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void setDNSADefault(boolean value) {\n            this.dnsaDefault = value;\n        }\n\n        public boolean getDNSADefault() {\n            return dnsaDefault;\n        }\n\n        public String getDNSAKey() {\n            return dnsaKey;\n        }\n\n        public void setDNSAMessage(String value) {\n            this.dnsaMessage = value;\n        }\n\n        public String getDNSAMessage() {\n            return dnsaMessage;\n        }\n    }\n\n    public static final class DNSAMessage extends NotifyDescriptor.Message {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private final String dnsaKey;\n        private String dnsaMessage = Bundle.ProfilerDialogs_DontShowAgainMsg();\n        private boolean dnsaDefault = true;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        /**\n         * Create an informational report about the results of a command.\n         *\n         * @param message the message object\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAMessage(final String key, final Object message) {\n            super(message);\n            this.dnsaKey = key;\n        }\n\n        /**\n         * Create a report about the results of a command.\n         *\n         * @param message     the message object\n         * @param messageType the type of message to be displayed\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public DNSAMessage(final String dnsaKey, final Object message, final int messageType) {\n            super(message, messageType);\n            this.dnsaKey = dnsaKey;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void setDNSADefault(boolean value) {\n            this.dnsaDefault = value;\n        }\n\n        public boolean getDNSADefault() {\n            return dnsaDefault;\n        }\n\n        public String getDNSAKey() {\n            return dnsaKey;\n        }\n\n        public void setDNSAMessage(String value) {\n            this.dnsaMessage = value;\n        }\n\n        public String getDNSAMessage() {\n            return dnsaMessage;\n        }\n    }\n\n    public static final class MessageWithDetails extends DialogDescriptor {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private JButton showDetailsButton = new JButton(Bundle.ProfilerDialogs_ShowDetailsButtonText());\n        private Object detailsMsg;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        /**\n         * Create an informational report about the results of a command.\n         *\n         * @param shortMsg the short message object\n         * @param detailsMsg the details message object\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public MessageWithDetails(final Object shortMsg, final Object detailsMsg, final boolean respectParent) {\n            super(shortMsg, NotifyDescriptor.getTitleForType(NotifyDescriptor.INFORMATION_MESSAGE));\n            this.detailsMsg = detailsMsg;\n            showDetailsButton.setDefaultCapable(false);\n            setOptions(new Object[] { OK_OPTION });\n            setAdditionalOptions(new Object[] { showDetailsButton });\n            setLeaf(!respectParent);\n        }\n\n        /**\n         * Create a report about the results of a command.\n         *\n         * @param shortMsg     the message object\n         * @param detailsMsg the details message object\n         * @param messageType the type of message to be displayed\n         * @see org.openide.NotifyDescriptor#NotifyDescriptor\n         */\n        public MessageWithDetails(final Object shortMsg, final Object detailsMsg, final int messageType,\n                                  final boolean respectParent) {\n            super(shortMsg, NotifyDescriptor.getTitleForType(messageType));\n            this.setMessageType(messageType);\n            this.detailsMsg = detailsMsg;\n            showDetailsButton.setDefaultCapable(false);\n            setOptions(new Object[] { OK_OPTION });\n            setAdditionalOptions(new Object[] { showDetailsButton });\n            setLeaf(!respectParent);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public Object getDetailsMessage() {\n            return detailsMsg;\n        }\n\n        public Object getShortMessage() {\n            return this.getMessage();\n        }\n\n        public JButton getShowDetailsButton() {\n            return showDetailsButton;\n        }\n    }\n\n    private static final class DNSAPanel extends JPanel {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private final JCheckBox check;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        DNSAPanel(final Object message, final boolean defaultSel, final String dnsaMessage) {\n            Component messageComponent = null;\n\n            if (message instanceof Component) {\n                messageComponent = (Component) message;\n            } else if (message instanceof String) {\n                messageComponent = new NBHTMLLabel((String) message);\n                messageComponent.setFocusable(false);\n            }\n\n            setLayout(new BorderLayout(0, 10));\n            check = new JCheckBox(dnsaMessage, defaultSel);\n\n            if (messageComponent != null) {\n                add(messageComponent, BorderLayout.CENTER);\n            }\n\n            add(check, BorderLayout.SOUTH);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public boolean isAutoChecked() {\n            return check.isSelected();\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Logger LOGGER = Logger.getLogger(ProfilerDialogs.class.getName());\n\n    private static boolean DEBUG = System.getProperty(\"org.graalvm.visualvm.lib.profiler.ui.ProfilerDialogs\") != null; //NOI18N\n    private static final DialogDisplayer standard = DialogDisplayer.getDefault();\n    private static boolean silent = false;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private ProfilerDialogs() {\n    } // avoid direct instance creation\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static void setSilent(boolean value) {\n        silent = value;\n    }\n\n    public static Dialog createDialog(final DialogDescriptor descriptor) {\n        descriptor.setLeaf(true);\n\n        return standard.createDialog(descriptor);\n    }\n\n    public static Object notify(final NotifyDescriptor descriptor) {\n        if (silent) {\n            if (LOGGER.isLoggable(Level.FINEST)) {\n                LOGGER.finest(\"Silently closed message: \" + descriptor.getMessage()); //NOI18N\n            }\n\n            return NotifyDescriptor.CLOSED_OPTION;\n        }\n\n        if (LOGGER.isLoggable(Level.FINEST)) {\n            LOGGER.finest(\"notify: \" + descriptor.getClass().getName()); //NOI18N\n        }\n\n        if (descriptor instanceof DNSAMessage) {\n            final DNSAMessage dm = (DNSAMessage) descriptor;\n            Object autoAccept = stringToNDOption(ProfilerIDESettings.getInstance().getDoNotShowAgain(dm.getDNSAKey()));\n\n            if (LOGGER.isLoggable(Level.FINEST)) {\n                LOGGER.finest(\"DNSAMessage key: \" + dm.getDNSAKey() + \", autoAccept: \" + autoAccept); //NOI18N\n            }\n\n            if (autoAccept != null) {\n                return autoAccept;\n            }\n\n            final DNSAPanel dp = new DNSAPanel(dm.getMessage(), dm.getDNSADefault(), dm.getDNSAMessage());\n            dm.setMessage(dp);\n\n            final Object ret = standard.notify(descriptor);\n\n            if ((ret != DialogDescriptor.CANCEL_OPTION) && (ret != DialogDescriptor.CLOSED_OPTION)) {\n                if (dp.isAutoChecked()) {\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"DNSAMessage key: \" + dm.getDNSAKey() + \", setting autoAccept: \" + autoAccept); //NOI18N\n                    }\n\n                    ProfilerIDESettings.getInstance().setDoNotShowAgain(dm.getDNSAKey(), ndOptionToString(ret));\n                }\n            }\n\n            return ret;\n        } else if (descriptor instanceof DNSAConfirmation) {\n            final DNSAConfirmation dm = (DNSAConfirmation) descriptor;\n            Object autoAccept = stringToNDOption(ProfilerIDESettings.getInstance().getDoNotShowAgain(dm.getDNSAKey()));\n\n            if (LOGGER.isLoggable(Level.FINEST)) {\n                LOGGER.finest(\"DNSAConfirmation key: \" + dm.getDNSAKey() + \", autoAccept: \" + autoAccept); //NOI18N\n            }\n\n            if (autoAccept != null) {\n                return autoAccept;\n            }\n\n            final DNSAPanel dp = new DNSAPanel(dm.getMessage(), dm.getDNSADefault(), dm.getDNSAMessage());\n            dm.setMessage(dp);\n\n            final Object ret = standard.notify(descriptor);\n\n            if ((ret != DialogDescriptor.CANCEL_OPTION) && (ret != DialogDescriptor.CLOSED_OPTION)) {\n                if (dp.isAutoChecked()) {\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"ProfilerDialogs: DNSAConfirmation key: \" + dm.getDNSAKey() + \", setting autoAccept: \"\n                                      + autoAccept); //NOI18N\n                    }\n\n                    ProfilerIDESettings.getInstance().setDoNotShowAgain(dm.getDNSAKey(), ndOptionToString(ret));\n                }\n            }\n\n            return ret;\n        } else if (descriptor instanceof DNSAConfirmationChecked) {\n            final DNSAConfirmationChecked dm = (DNSAConfirmationChecked) descriptor;\n            Object autoAccept = stringToNDOption(ProfilerIDESettings.getInstance().getDoNotShowAgain(dm.getDNSAKey()));\n\n            if (LOGGER.isLoggable(Level.FINEST)) {\n                LOGGER.finest(\"DNSAConfirmationChecked key: \" + dm.getDNSAKey() + \", autoAccept: \" + autoAccept); //NOI18N\n            }\n\n            if (autoAccept != null) {\n                return autoAccept;\n            }\n\n            final DNSAPanel dp = new DNSAPanel(dm.getMessage(), dm.getDNSADefault(), dm.getDNSAMessage());\n            dm.setMessage(dp);\n\n            final Object ret = standard.notify(descriptor);\n\n            if ((ret != DialogDescriptor.CANCEL_OPTION) && (ret != DialogDescriptor.CLOSED_OPTION)) {\n                if (dp.isAutoChecked() && (ret != DialogDescriptor.NO_OPTION)) {\n                    if (LOGGER.isLoggable(Level.FINEST)) {\n                        LOGGER.finest(\"ProfilerDialogs: DNSAConfirmationChecked key: \" + dm.getDNSAKey()\n                                      + \", setting autoAccept: \" + autoAccept); //NOI18N\n                    }\n\n                    ProfilerIDESettings.getInstance().setDoNotShowAgain(dm.getDNSAKey(), ndOptionToString(ret));\n                }\n            }\n\n            return ret;\n        } else if (descriptor instanceof MessageWithDetails) {\n            if (LOGGER.isLoggable(Level.FINEST)) {\n                LOGGER.finest(\"MessageWithDetails message:\" + ((MessageWithDetails) descriptor).getDetailsMessage()); //NOI18N\n            }\n\n            final MessageWithDetails dm = (MessageWithDetails) descriptor;\n            Object returnObj = standard.notify(dm);\n\n            if (returnObj == dm.getShowDetailsButton()) {\n                returnObj = standard.notify(new NotifyDescriptor.Message(dm.getDetailsMessage(), dm.getMessageType()));\n            }\n\n            return returnObj;\n        } else {\n            return standard.notify(descriptor);\n        }\n    }\n\n    // Maps org.openide.NotifyDescriptor option to String\n    private static String ndOptionToString(Object option) {\n        if (option == NotifyDescriptor.CANCEL_OPTION) {\n            return \"CANCEL_OPTION\"; // NOI18N\n        } else if (option == NotifyDescriptor.CLOSED_OPTION) {\n            return \"CLOSED_OPTION\"; // NOI18N\n        } else if (option == NotifyDescriptor.NO_OPTION) {\n            return \"NO_OPTION\"; // NOI18N\n        } else if (option == NotifyDescriptor.OK_OPTION) {\n            return \"OK_OPTION\"; // NOI18N\n        } else if (option == NotifyDescriptor.YES_OPTION) {\n            return \"YES_OPTION\"; // NOI18N\n        }\n\n        return null;\n    }\n\n    // Maps String to org.openide.NotifyDescriptor option\n    private static Object stringToNDOption(String string) {\n        if (string == null) {\n            return null;\n        }\n\n        if (string.equals(\"CANCEL_OPTION\")) { //NOI18N\n\n            return NotifyDescriptor.CANCEL_OPTION;\n        } else if (string.equals(\"CLOSED_OPTION\")) { //NOI18N\n\n            return NotifyDescriptor.CLOSED_OPTION;\n        } else if (string.equals(\"NO_OPTION\")) { //NOI18N\n\n            return NotifyDescriptor.NO_OPTION;\n        } else if (string.equals(\"OK_OPTION\")) { //NOI18N\n\n            return NotifyDescriptor.OK_OPTION;\n        } else if (string.equals(\"YES_OPTION\")) { //NOI18N\n\n            return NotifyDescriptor.YES_OPTION;\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/impl/ProfilerDialogsProviderImpl.java",
    "content": "/*\n * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.impl;\n\nimport org.graalvm.visualvm.lib.profiler.spi.ProfilerDialogsProvider;\nimport org.graalvm.visualvm.lib.profiler.ui.NBHTMLLabel;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=ProfilerDialogsProvider.class)\npublic final class ProfilerDialogsProviderImpl extends ProfilerDialogsProvider {\n\n    @Override\n    public void displayInfo(String message, String caption, String details) {\n        displayMessage(message, caption, details, NotifyDescriptor.INFORMATION_MESSAGE);\n    }\n\n    @Override\n    public void displayInfoDNSA(String message, String caption, String dnsaMessage, String key, boolean dnsaDefault) {\n        displayDNSAMessage(message, caption, dnsaMessage, key, dnsaDefault, NotifyDescriptor.INFORMATION_MESSAGE);\n    }\n\n    @Override\n    public void displayWarning(String message, String caption, String details) {\n        displayMessage(message, caption, details, NotifyDescriptor.WARNING_MESSAGE);\n    }\n\n    @Override\n    public void displayWarningDNSA(String message, String caption, String dnsaMessage, String key, boolean dnsaDefault) {\n        displayDNSAMessage(message, caption, dnsaMessage, key, dnsaDefault, NotifyDescriptor.WARNING_MESSAGE);\n    }\n\n    @Override\n    public void displayError(String message, String caption, String details) {\n        displayMessage(message, caption, details, NotifyDescriptor.ERROR_MESSAGE);\n    }\n\n    @Override\n    public Boolean displayConfirmation(String message, String caption, boolean cancellable) {\n        NotifyDescriptor nd = new NotifyDescriptor.Confirmation(message,\n                cancellable ? NotifyDescriptor.YES_NO_CANCEL_OPTION : NotifyDescriptor.YES_NO_OPTION);\n        if (caption != null) nd.setTitle(caption);\n        Object ret = DialogDisplayer.getDefault().notify(nd);\n        if (ret == NotifyDescriptor.YES_OPTION) return Boolean.TRUE;\n        if (ret == NotifyDescriptor.NO_OPTION) return Boolean.FALSE;\n        return null;\n    }\n\n    @Override\n    public Boolean displayConfirmationDNSA(String message, String caption, String dnsaMessage, boolean cancellable, String key, boolean dnsaDefault) {\n        ProfilerDialogs.DNSAConfirmation dnsa = new ProfilerDialogs.DNSAConfirmation(\n                key, message, cancellable ? NotifyDescriptor.YES_NO_CANCEL_OPTION : NotifyDescriptor.YES_NO_OPTION);\n        if (caption != null) dnsa.setTitle(caption);\n        if (dnsaMessage != null) dnsa.setDNSAMessage(dnsaMessage);\n        dnsa.setDNSADefault(dnsaDefault);\n        Object ret = ProfilerDialogs.notify(dnsa);\n        if (ret == NotifyDescriptor.YES_OPTION) return Boolean.TRUE;\n        if (ret == NotifyDescriptor.NO_OPTION) return Boolean.FALSE;\n        return null;\n    }\n    \n    private void displayMessage(String message, String caption, String details, int type) {\n        Object msg = message;\n        Object det = details;\n        if (isHtmlString(message)) msg = new NBHTMLLabel(message);\n        if (isHtmlString(details)) det = new NBHTMLLabel(message);\n        NotifyDescriptor nd = det == null ? new NotifyDescriptor.Message(msg, type) :\n                        new ProfilerDialogs.MessageWithDetails(msg, det, type, false);\n        if (caption != null) nd.setTitle(caption);\n        ProfilerDialogs.notify(nd);\n    }\n    \n    private void displayDNSAMessage(String message, String caption, String dnsaMessage, String key, boolean dnsaDefault, int type) {\n        ProfilerDialogs.DNSAMessage dnsa = new ProfilerDialogs.DNSAMessage(key, message, type);\n        if (caption != null) dnsa.setTitle(caption);\n        if (dnsaMessage != null) dnsa.setDNSAMessage(dnsaMessage);\n        dnsa.setDNSADefault(dnsaDefault);\n        ProfilerDialogs.notify(dnsa);\n    }\n    \n    private static boolean isHtmlString(String string) {\n        if (string == null) return false;\n        // Simple heuristics, seems to work fine\n        return string.contains(\"<\") && string.contains(\">\"); // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/impl/icons/IconsProviderImpl.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.impl.icons;\n\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.spi.IconsProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=IconsProvider.class)\npublic final class IconsProviderImpl extends IconsProvider.Basic {\n\n    @Override\n    protected final void initStaticImages(Map<String, String> cache) {\n        cache.put(GeneralIcons.FILTER, \"filter.png\");\n        cache.put(GeneralIcons.FILTER_HIGHL, \"filterHighl.png\");\n        cache.put(GeneralIcons.SET_FILTER, \"setFilter.png\");\n        cache.put(GeneralIcons.SET_FILTER_HIGHL, \"setFilterHighl.png\");\n        cache.put(GeneralIcons.CLEAR_FILTER, \"clearFilter.png\");\n        cache.put(GeneralIcons.CLEAR_FILTER_HIGHL, \"clearFilterHighl.png\");\n        cache.put(GeneralIcons.CLOSE_PANEL, \"closePanel.png\");\n        cache.put(GeneralIcons.FILTER_CONTAINS, \"filterContains.png\");\n        cache.put(GeneralIcons.FILTER_NOT_CONTAINS, \"filterNotContains.png\");\n        cache.put(GeneralIcons.FILTER_ENDS_WITH, \"filterEndsWith.png\");\n        cache.put(GeneralIcons.FILTER_REG_EXP, \"filterRegExp.png\");\n        cache.put(GeneralIcons.FILTER_STARTS_WITH, \"filterStartsWith.png\");\n        cache.put(GeneralIcons.COLLAPSED_SNIPPET, \"collapsedSnippet.png\");\n        cache.put(GeneralIcons.EXPANDED_SNIPPET, \"expandedSnippet.png\");\n        cache.put(GeneralIcons.HIDE_COLUMN, \"hideColumn.png\");\n        cache.put(GeneralIcons.MAXIMIZE_PANEL, \"maximizePanel.png\");\n        cache.put(GeneralIcons.MINIMIZE_PANEL, \"minimizePanel.png\");\n        cache.put(GeneralIcons.RESTORE_PANEL, \"restorePanel.png\");\n        cache.put(GeneralIcons.SORT_ASCENDING, \"sortAsc.png\");\n        cache.put(GeneralIcons.SORT_DESCENDING, \"sortDesc.png\");\n        cache.put(GeneralIcons.POPUP_ARROW, \"popupArrow.png\");\n        cache.put(GeneralIcons.ZOOM, \"zoom.png\");\n        cache.put(GeneralIcons.ZOOM_IN, \"zoomIn.png\");\n        cache.put(GeneralIcons.ZOOM_OUT, \"zoomOut.png\");\n        cache.put(GeneralIcons.SCALE_TO_FIT, \"scaleToFit.png\");\n        cache.put(GeneralIcons.INFO, \"infoIcon.png\");\n        cache.put(GeneralIcons.FIND_NEXT, \"findNext.png\");\n        cache.put(GeneralIcons.FIND_PREVIOUS, \"findPrevious.png\");\n        cache.put(GeneralIcons.SAVE, \"save.png\");\n        cache.put(GeneralIcons.SAVE_AS, \"saveAs.png\");\n        cache.put(GeneralIcons.SAVE_VIEW, \"saveView.png\");\n        cache.put(GeneralIcons.EXPORT, \"saveAs.png\");\n        cache.put(GeneralIcons.DETACH, \"detach.png\");\n        cache.put(GeneralIcons.START, \"start.png\");\n        cache.put(GeneralIcons.PAUSE, \"pause.png\");\n        cache.put(GeneralIcons.RERUN, \"rerun.png\");\n        cache.put(GeneralIcons.RESUME, \"resume.png\");\n        cache.put(GeneralIcons.STOP, \"stop.png\");\n        cache.put(GeneralIcons.EMPTY, \"empty.gif\");\n        cache.put(GeneralIcons.ERROR, \"error.png\");\n        cache.put(GeneralIcons.FIND, \"find.gif\");\n        cache.put(GeneralIcons.SLAVE_DOWN, \"slaveDown.png\");\n        cache.put(GeneralIcons.SLAVE_UP, \"slaveUp.png\");\n        cache.put(GeneralIcons.UPDATE_AUTO, \"autoRefresh.png\");\n        cache.put(GeneralIcons.PIE, \"pie.png\");\n        cache.put(GeneralIcons.UPDATE_NOW, \"updateNow.png\");\n        cache.put(GeneralIcons.BUTTON_ATTACH, \"attachButton.gif\");\n        cache.put(GeneralIcons.BUTTON_RUN, \"runButton.gif\");\n        cache.put(GeneralIcons.UP, \"up.png\");\n        cache.put(GeneralIcons.DOWN, \"down.png\");\n        cache.put(GeneralIcons.FORWARD, \"forward.png\");\n        cache.put(GeneralIcons.BACK, \"back.png\");\n        cache.put(GeneralIcons.SETTINGS, \"settings.png\");\n        cache.put(GeneralIcons.JAVA_PROCESS, \"javaProcess.png\");\n        cache.put(GeneralIcons.FOLDER, \"folder.png\");\n        cache.put(GeneralIcons.BADGE_ADD, \"badgeAdd.png\");\n        cache.put(GeneralIcons.BADGE_REMOVE, \"badgeRemove.png\");\n        cache.put(GeneralIcons.RENAME, \"rename.png\");\n        cache.put(GeneralIcons.MATCH_CASE, \"matchCase.png\");\n        cache.put(GeneralIcons.ADD, \"add.png\");\n        cache.put(GeneralIcons.EDIT, \"edit.png\");\n        cache.put(GeneralIcons.REMOVE, \"remove.png\");\n        cache.put(GeneralIcons.HIGHLIGHT_RESULTS, \"highlightResults.png\");\n        \n        cache.put(ProfilerIcons.NODE_FORWARD, \"forwardNode.png\");\n        cache.put(ProfilerIcons.NODE_REVERSE, \"reverseNode.png\");\n        cache.put(ProfilerIcons.NODE_LEAF, \"leafNode.png\");\n        cache.put(ProfilerIcons.SNAPSHOT_MEMORY_32, \"memorySnapshot32.png\");\n        cache.put(ProfilerIcons.THREAD, \"thread.png\");\n        cache.put(ProfilerIcons.ALL_THREADS, \"allThreads.png\");\n        cache.put(ProfilerIcons.SQL_QUERY, \"sqlQuery.png\");\n        cache.put(ProfilerIcons.ATTACH, \"attach.png\");\n        cache.put(ProfilerIcons.ATTACH_24, \"attach24.png\");\n        cache.put(ProfilerIcons.SNAPSHOTS_COMPARE, \"compareSnapshots.png\");\n        cache.put(ProfilerIcons.SNAPSHOT_OPEN, \"openSnapshot.png\");\n        cache.put(ProfilerIcons.SNAPSHOT_TAKE, \"takeSnapshot.png\");\n        cache.put(ProfilerIcons.PROFILE, \"profile.png\");\n        cache.put(ProfilerIcons.PROFILE_24, \"profile24.png\");\n        cache.put(ProfilerIcons.PROFILE_INACTIVE, \"profileInactive.png\");\n        cache.put(ProfilerIcons.PROFILE_RUNNING, \"profileRunning.png\");\n        cache.put(ProfilerIcons.RESET_RESULTS, \"resetResults.png\");\n        cache.put(ProfilerIcons.RUN_GC, \"runGC.png\");\n        cache.put(ProfilerIcons.SNAPSHOT_THREADS, \"threadsSnapshot.png\");\n        cache.put(ProfilerIcons.SNAPSHOT_HEAP, \"heapSnapshot.png\");\n        cache.put(ProfilerIcons.CONTROL_PANEL, \"controlPanel.gif\");\n        cache.put(ProfilerIcons.LIVE_RESULTS, \"liveResults.png\");\n        cache.put(ProfilerIcons.MODIFY_PROFILING, \"modifyProfiling.png\");\n        cache.put(ProfilerIcons.SHOW_GRAPHS, \"showGraphs.png\");\n        cache.put(ProfilerIcons.SNAPSHOT_DO, \"snapshotDataObject.png\");\n        cache.put(ProfilerIcons.SNAPSHOT_DO_32, \"snapshotDataObject32.png\");\n        cache.put(ProfilerIcons.SNAPSHOT_CPU_DO, \"snapshotDataObjectCPU.gif\");\n        cache.put(ProfilerIcons.SNAPSHOT_CPU_DO_32, \"snapshotDataObjectCPU32.gif\");\n        cache.put(ProfilerIcons.SNAPSHOT_MEMORY_DO, \"snapshotDataObjectMemory.gif\");\n        cache.put(ProfilerIcons.SNAPSHOT_MEMORY_DO_32, \"snapshotDataObjectMemory32.gif\");\n        cache.put(ProfilerIcons.SNAPSHOT_FRAGMENT_DO, \"snapshotDataObjectFragment.gif\");\n        cache.put(ProfilerIcons.SNAPSHOT_FRAGMENT_DO_32, \"snapshotDataObjectFragment32.gif\");\n        cache.put(ProfilerIcons.TAKE_SNAPSHOT_CPU_32, \"takeSnapshotCPU32.png\");\n        cache.put(ProfilerIcons.TAKE_SNAPSHOT_FRAGMENT_32, \"takeSnapshotFragment32.png\");\n        cache.put(ProfilerIcons.TAKE_SNAPSHOT_MEMORY_32, \"takeSnapshotMem32.png\");\n        cache.put(ProfilerIcons.TAKE_HEAP_DUMP_32, \"takeSnapshotMem32.png\");\n        cache.put(ProfilerIcons.TAB_BACK_TRACES, \"backTracesTab.png\");\n        cache.put(ProfilerIcons.TAB_CALL_TREE, \"callTreeTab.png\");\n        cache.put(ProfilerIcons.TAB_COMBINED, \"combinedTab.png\");\n        cache.put(ProfilerIcons.TAB_HOTSPOTS, \"hotspotsTab.png\");\n        cache.put(ProfilerIcons.TAB_INFO, \"infoTab.png\");\n        cache.put(ProfilerIcons.TAB_MEMORY_RESULTS, \"memoryResultsTab.png\");\n        cache.put(ProfilerIcons.TAB_STACK_TRACES, \"stackTracesTab.png\");\n        cache.put(ProfilerIcons.TAB_SUBTREE, \"subtreeTab.png\");\n        cache.put(ProfilerIcons.WINDOW_CONTROL_PANEL, \"controlPanelWindow.gif\");\n        cache.put(ProfilerIcons.WINDOW_LIVE_RESULTS, \"liveResultsWindow.png\");\n        cache.put(ProfilerIcons.WINDOW_TELEMETRY, \"telemetryWindow.png\");\n        cache.put(ProfilerIcons.WINDOW_TELEMETRY_OVERVIEW, \"telemetryOverviewWindow.png\");\n        cache.put(ProfilerIcons.WINDOW_THREADS, \"threadsWindow.png\");\n        cache.put(ProfilerIcons.WINDOW_LOCKS, \"locksWindow.png\");\n        cache.put(ProfilerIcons.WINDOW_SQL, \"sqlWindow.png\");\n        cache.put(ProfilerIcons.VIEW_LIVE_RESULTS_CPU_32, \"liveResultsCPUView32.png\");\n        cache.put(ProfilerIcons.VIEW_LIVE_RESULTS_FRAGMENT_32, \"liveResultsFragmentView32.png\");\n        cache.put(ProfilerIcons.VIEW_LIVE_RESULTS_MEMORY_32, \"liveResultsMemView32.png\");\n        cache.put(ProfilerIcons.VIEW_THREADS_32, \"threadsView32.png\");\n        cache.put(ProfilerIcons.VIEW_TELEMETRY_32, \"telemetryView32.png\");\n        cache.put(ProfilerIcons.VIEW_LOCKS_32, \"locksView32.png\");\n        cache.put(ProfilerIcons.CPU, \"cpu.png\");\n        cache.put(ProfilerIcons.CPU_32, \"cpu32.png\");\n        cache.put(ProfilerIcons.FRAGMENT, \"fragment.png\");\n        cache.put(ProfilerIcons.MEMORY, \"memory.png\");\n        cache.put(ProfilerIcons.MEMORY_32, \"memory32.png\");\n        cache.put(ProfilerIcons.HEAP_DUMP, \"memoryResultsTab.png\");\n        cache.put(ProfilerIcons.CUSTOM_32, \"custom32.png\");\n        cache.put(ProfilerIcons.MONITORING, \"monitoring.png\");\n        cache.put(ProfilerIcons.MONITORING_32, \"monitoring32.png\");\n        cache.put(ProfilerIcons.STARTUP_32, \"startup32.png\");\n        cache.put(ProfilerIcons.DELTA_RESULTS, \"deltaValues.png\");\n        \n        cache.put(LanguageIcons.CLASS, \"class.png\");\n        cache.put(LanguageIcons.CLASS_ANONYMOUS, \"classAnonymous.png\");\n        cache.put(LanguageIcons.CONSTRUCTOR_PACKAGE, \"constructorPackage.png\");\n        cache.put(LanguageIcons.CONSTRUCTOR_PRIVATE, \"constructorPrivate.png\");\n        cache.put(LanguageIcons.CONSTRUCTOR_PROTECTED, \"constructorProtected.png\");\n        cache.put(LanguageIcons.CONSTRUCTOR_PUBLIC, \"constructorPublic.png\");\n        cache.put(LanguageIcons.CONSTRUCTORS, \"constructors.png\");\n        cache.put(LanguageIcons.INITIALIZER, \"initializer.png\");\n        cache.put(LanguageIcons.INITIALIZER_STATIC, \"initializerSt.png\");\n        cache.put(LanguageIcons.INTERFACE, \"interface.png\");\n        cache.put(LanguageIcons.LIBRARIES, \"libraries.png\");\n        cache.put(LanguageIcons.METHOD_PACKAGE, \"methodPackage.png\");\n        cache.put(LanguageIcons.METHOD_PRIVATE, \"methodPrivate.png\");\n        cache.put(LanguageIcons.METHOD_PROTECTED, \"methodProtected.png\");\n        cache.put(LanguageIcons.METHOD_PUBLIC, \"methodPublic.png\");\n        cache.put(LanguageIcons.METHOD_PACKAGE_STATIC, \"methodStPackage.png\");\n        cache.put(LanguageIcons.METHOD_PRIVATE_STATIC, \"methodStPrivate.png\");\n        cache.put(LanguageIcons.METHOD_PROTECTED_STATIC, \"methodStProtected.png\");\n        cache.put(LanguageIcons.METHOD_PUBLIC_STATIC, \"methodStPublic.png\");\n        cache.put(LanguageIcons.METHOD_INHERITED, \"methodInherited.png\");\n        cache.put(LanguageIcons.METHODS, \"methods.png\");\n        cache.put(LanguageIcons.METHOD, \"method.png\");\n        cache.put(LanguageIcons.PACKAGE, \"package.png\");\n        cache.put(LanguageIcons.VARIABLE_PACKAGE, \"variablePackage.png\");\n        cache.put(LanguageIcons.VARIABLE_PRIVATE, \"variablePrivate.gif\");\n        cache.put(LanguageIcons.VARIABLE_PROTECTED, \"variableProtected.png\");\n        cache.put(LanguageIcons.VARIABLE_PUBLIC, \"variablePublic.png\");\n        cache.put(LanguageIcons.VARIABLE_PACKAGE_STATIC, \"variableStPackage.png\");\n        cache.put(LanguageIcons.VARIABLE_PRIVATE_STATIC, \"variableStPrivate.png\");\n        cache.put(LanguageIcons.VARIABLE_PROTECTED_STATIC, \"variableStProtected.png\");\n        cache.put(LanguageIcons.VARIABLE_PUBLIC_STATIC, \"variableStPublic.png\");\n        cache.put(LanguageIcons.VARIABLES, \"variables.png\");\n        cache.put(LanguageIcons.ARRAY, \"array.png\");\n        cache.put(LanguageIcons.INSTANCE, \"instance.png\");\n        cache.put(LanguageIcons.PRIMITIVE, \"primitive.png\");\n        cache.put(LanguageIcons.JAR, \"jar.png\");\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/mf-layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.2//EN\" \"http://www.netbeans.org/dtds/filesystem-1_2.dtd\">\n<filesystem>\n    <folder name=\"Menu\">\n        <folder name=\"Window\">\n            <folder name=\"Profile\">\n                <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.actions.Bundle#Menu/Window/Profile\"/>\n                <attr name=\"iconBase\" stringvalue=\"org/graalvm/visualvm/lib/profiler/impl/icons/empty.gif\"/>\n                <attr name=\"position\" intvalue=\"1100\"/>\n            </folder>\n        </folder>\n\n\n\n        <folder name=\"Profile\">\n            <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.actions.Bundle#Menu/Profile\"/>\n            <attr name=\"position\" intvalue=\"850\"/>\n\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-AttachAction.shadow\">\n               <attr name=\"originalFile\" stringvalue=\"Actions/Profile/org-graalvm-visualvm-lib-profiler-actions-AttachAction.instance\"/>\n               <attr name=\"position\" intvalue=\"200\"/>\n               <attr name=\"ergonomics\" boolvalue=\"true\"/>\n            </file>\n        </folder>\n    </folder>\n\n    <folder name=\"Actions\">\n        <folder name=\"Profile\">\n            <attr name=\"SystemFileSystem.localizingBundle\" stringvalue=\"org.graalvm.visualvm.lib.profiler.actions.Bundle\"/>\n            <file name=\"org-graalvm-visualvm-lib-profiler-actions-AttachAction.instance\"> <!-- cannot yet use @ActionRegistration due to ergonomics=true on shadow -->\n                <attr name=\"delegate\" methodvalue=\"org.graalvm.visualvm.lib.profiler.actions.AttachAction.getInstance\"/>\n                <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.actions.Bundle#LBL_AttachAction\"/>\n                <attr name=\"iconBase\" stringvalue=\"org/graalvm/visualvm/lib/profiler/impl/icons/attach.png\"/>\n                <attr name=\"instanceCreate\" methodvalue=\"org.openide.awt.Actions.alwaysEnabled\"/>\n                <attr name=\"noIconInMenu\" boolvalue=\"false\"/>\n            </file>\n        </folder>\n    </folder>\n\n    <folder name=\"Editors\">\n        <folder name=\"text\">\n            <folder name=\"x-java\">\n                <folder name=\"Popup\">\n                    <folder name=\"Profile\">\n                        <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.actions.Bundle#Editors/text/x-java/Popup/Profile\"/>\n                        <attr name=\"position\" intvalue=\"1920\"/>\n                    </folder>\n                </folder>\n            </folder>\n        </folder>\n    </folder>\n\n</filesystem>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/ui/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n# Sample ResourceBundle properties file\n\nLBL_ProfilerFiles=Profiler Files\nLBL_Nps_loader_name=Nps Files\n\nMethodSelect_SelectMethodsDialogCaption=Select Methods\nMethodSelect_OKButtonText=OK\nMethodSelect_InvalidClassListItem=<invalid class>\nMethodSelect_ClassNameLabelText=Class Name\\:\nMethodSelect_SelectClassButtonText=Select...\nMethodSelect_MethodsLabelText=Methods\\:\nMethodSelect_GettingMethodsListItem=Getting list of class methods...\nMethodSelect_ClassNameComboAccessName=Selected class.\nMethodSelect_ClassNameButtonAccessDescr=Selects a class from opened projects.\nMethodSelect_MethodsListAccessName=List of methods defined in selected class.\nMethodSelect_MethodsListAccessDescr=Select root methods from this list.\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/ui/HprofDataObject.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.ui;\n\nimport java.io.IOException;\nimport org.openide.cookies.OpenCookie;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.MIMEResolver;\nimport org.openide.loaders.DataNode;\nimport org.openide.loaders.DataObject;\nimport org.openide.loaders.DataObjectExistsException;\nimport org.openide.loaders.MultiDataObject;\nimport org.openide.loaders.MultiFileLoader;\nimport org.openide.nodes.Node;\nimport org.openide.nodes.Children;\nimport org.openide.util.Lookup;\n\n/**\n * HPROF heapdump DataObject\n *\n * @author Tomas Hurka\n */\n@MIMEResolver.Registration(\n    displayName=\"org.graalvm.visualvm.lib.profiler.Bundle#HprofResolver\",\n    position=99900,\n    resource=\"../DummyHprofResolver.xml\",\n    showInFileChooser = { \"#LBL_ProfilerFiles\" }\n)\n@DataObject.Registration(\n    iconBase = \"org/graalvm/visualvm/lib/profiler/impl/icons/snapshotDataObject.png\",\n    mimeType = \"application/x-netbeans-profiler-hprof\",\n    position=1000\n)\npublic class HprofDataObject extends MultiDataObject implements OpenCookie {\n\n    public HprofDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {\n        super(pf, loader);\n\n    }\n\n    @Override\n    protected Node createNodeDelegate() {\n        return new DataNode(this, Children.LEAF, getLookup());\n    }\n\n    @Override\n    public Lookup getLookup() {\n        return getCookieSet().getLookup();\n    }\n\n    public void open() {\n        // display dialog, no viewer available\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/ui/NBHTMLLabel.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.ui;\n\nimport org.graalvm.visualvm.lib.ui.components.HTMLLabel;\nimport org.openide.awt.HtmlBrowser;\nimport java.net.URL;\nimport javax.swing.BorderFactory;\n\n\npublic final class NBHTMLLabel extends HTMLLabel {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public NBHTMLLabel(final String text) {\n        super(text);\n        setBorder(BorderFactory.createEmptyBorder(5, 3, 3, 5));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    protected void showURL(final URL url) {\n        HtmlBrowser.URLDisplayer.getDefault().showURL(url);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/ui/NBSwingWorker.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.ui;\n\nimport org.graalvm.visualvm.lib.ui.SwingWorker;\nimport org.openide.util.RequestProcessor;\n\n\n/**\n * Overrides the default behaviour of the SwingWorker to use RequestProcessor\n * @author Jaroslav Bachorik\n */\npublic abstract class NBSwingWorker extends SwingWorker {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static RequestProcessor rp = null;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public NBSwingWorker(boolean forceEQ) {\n        super(forceEQ);\n    }\n\n    public NBSwingWorker() {\n        super();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    protected void postRunnable(Runnable runnable) {\n        getRequestProcessor().post(runnable);\n    }\n\n    private static synchronized RequestProcessor getRequestProcessor() {\n        if (rp == null) {\n            rp = new RequestProcessor(\"NBSwingWorker - RequestProcessor\", 1); // NOI18N\n        }\n\n        return rp;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/ui/NpsDataObject.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.ui;\n\nimport java.io.IOException;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.openide.cookies.OpenCookie;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.MIMEResolver;\nimport org.openide.loaders.DataNode;\nimport org.openide.loaders.DataObject;\nimport org.openide.loaders.DataObjectExistsException;\nimport org.openide.loaders.MultiDataObject;\nimport org.openide.loaders.MultiFileLoader;\nimport org.openide.nodes.Children;\nimport org.openide.nodes.Node;\nimport org.openide.util.Lookup;\n\n@MIMEResolver.Registration(\n    displayName=\"org.graalvm.visualvm.lib.profiler.Bundle#NpsResolver\",\n    position=99500,\n    resource=\"../NpsResolver.xml\",\n    showInFileChooser = { \"#LBL_ProfilerFiles\" }\n)\n@DataObject.Registration(\n    iconBase = \"org/graalvm/visualvm/lib/profiler/impl/icons/snapshotDataObject.png\",\n    mimeType = \"application/x-netbeans-profiler\"\n)\npublic class NpsDataObject extends MultiDataObject implements OpenCookie {\n\n    public NpsDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {\n        super(pf, loader);\n\n    }\n\n    @Override\n    protected Node createNodeDelegate() {\n        return new DataNode(this, Children.LEAF, getLookup());\n    }\n\n    @Override\n    public Lookup getLookup() {\n        return getCookieSet().getLookup();\n    }\n\n    public void open() {\n        LoadedSnapshot imported = ResultsManager.getDefault().loadSnapshot(getPrimaryFile());\n        if (imported != null) ResultsManager.getDefault().openSnapshot(imported);\n    }\n\n    @Override\n    protected void handleDelete() throws IOException {\n        ResultsManager.getDefault().deleteSnapshot(getPrimaryFile());\n    }\n\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/ui/ProfilerProgressDisplayer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.ui;\n\nimport org.openide.DialogDescriptor;\nimport org.openide.util.NbBundle;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport javax.swing.JButton;\nimport javax.swing.JDialog;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JProgressBar;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.profiler.api.ProgressDisplayer;\nimport org.openide.DialogDisplayer;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ProgressDisplayer_ProgressString=Progress...\",\n    \"ProgressDisplayer_CancelButtonText=Cancel\"\n})\npublic class ProfilerProgressDisplayer extends JPanel implements ProgressDisplayer {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    protected static final String PROGRESS_STRING = Bundle.ProgressDisplayer_ProgressString();\n    protected static final String CANCEL_BUTTON_TEXT = Bundle.ProgressDisplayer_CancelButtonText();\n    // -----\n\n    // --- Private implementation ------------------------------------------------\n    private static ProfilerProgressDisplayer defaultInstance;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Dialog owner;\n    private JButton cancelButton;\n\n    // --- UI components declaration ---------------------------------------------\n    private JLabel progressLabel;\n    private JProgressBar progressBar;\n\n    // --- Instance variables declaration ----------------------------------------\n    private ProgressController controller;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private ProfilerProgressDisplayer() {}\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    // --- Public interface ------------------------------------------------------\n    \n    @Override\n    public ProgressDisplayer showProgress(String message) {\n        return showProgress(message, null);\n    }\n\n    @Override\n    public ProgressDisplayer showProgress(String message, ProgressController controller) {\n        return showProgress(PROGRESS_STRING, message, controller);\n    }\n    \n    \n    @Override\n    public ProgressDisplayer showProgress(final String caption, final String message, final ProgressController controller) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (progressLabel == null) initComponents();\n                \n                DialogDescriptor dd = createDialogDescriptor(caption, message, controller);\n                Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n                d.pack();\n\n                owner = d;\n                if (owner instanceof JDialog) {\n                    ((JDialog)owner).setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);\n                }\n                \n                d.setVisible(true);\n            }\n        });\n        return this;\n    }\n\n    public void close() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (owner != null) {\n                    owner.setVisible(false);\n                    owner.dispose();\n                }\n\n                cleanup();\n            }\n        });\n    }\n\n    public static ProfilerProgressDisplayer getDefault() {\n        if (defaultInstance == null) {\n            defaultInstance = new ProfilerProgressDisplayer();\n        }\n\n        return defaultInstance;\n    }\n\n    private void cleanup() {\n        if (progressBar != null) {\n            progressBar.setIndeterminate(false);\n        }\n\n        controller = null;\n        owner = null;\n    }\n\n    private DialogDescriptor createDialogDescriptor(String caption, String message, ProgressController controller) {\n        this.controller = controller;\n\n        progressLabel.setText(message);\n        progressBar.setIndeterminate(true);\n\n        DialogDescriptor dd = controller == null ?\n            new DialogDescriptor(this, caption, true, new Object[0], null, 0, null, null) :\n            new DialogDescriptor(this, caption, true, new Object[] { cancelButton }, null, 0, null, null);\n\n        dd.setClosingOptions(new Object[0]);\n        return dd;\n    }\n\n    // --- UI definition ---------------------------------------------------------\n    private void initComponents() {\n        setLayout(new GridBagLayout());\n\n        GridBagConstraints constraints;\n\n        // progressLabel\n        progressLabel = new JLabel();\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 0;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(15, 8, 0, 8);\n        add(progressLabel, constraints);\n\n        // progressBar\n        progressBar = new JProgressBar(SwingConstants.HORIZONTAL);\n        progressBar.setPreferredSize(new Dimension(300, progressBar.getPreferredSize().height));\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.HORIZONTAL;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(10, 8, 15, 8);\n        add(progressBar, constraints);\n\n        // fillerPanel\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 2;\n        constraints.weightx = 1;\n        constraints.weighty = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.insets = new Insets(0, 0, 0, 0);\n        add(UIUtils.createFillerPanel(), constraints);\n\n        // cancelButton\n        cancelButton = new JButton(CANCEL_BUTTON_TEXT);\n        cancelButton.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    if (controller != null) {\n                        controller.cancel();\n                    }\n                }\n            });\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/utils/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n#ResourceBundle properties file for package org.graalvm.visualvm.lib.profiler.utils\n\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/utils/MainClassChooser.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.utils;\n\nimport org.openide.awt.Mnemonics;\nimport org.openide.awt.MouseUtils;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport javax.swing.JPanel;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport org.graalvm.visualvm.lib.profiler.api.java.ProfilerTypeUtils;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceClassInfo;\nimport org.openide.util.Lookup;\n\n\n/**\n * Browses and allows to choose a project's main class.\n *\n * @author Tomas Hurka\n * @author Jiri Rechtacek\n */\n@NbBundle.Messages({\n    \"CTL_SelectAvaialableMainClasses=&Select the main class for profiling:\",\n    \"CTL_AvaialableMainClasses=&Main classes:\",\n    \"AD_jMainClassList=N/A\",\n    \"AD_MainClassChooser=N/A\",\n    \"LBL_ChooseMainClass_NO_CLASSES_NODE=<No main classes found>\",\n    \"LBL_ChooseMainClass_WARMUP_MESSAGE=Initializing view, please wait ...\"\n})\npublic class MainClassChooser extends JPanel {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // Used only from unit tests to suppress check of main method. If value\n    // is different from null it will be returned instead.\n    public static Boolean unitTestingSupport_hasMainMethodResult = null;\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private javax.swing.JLabel jLabel1;\n    private javax.swing.JList jMainClassList;\n    private javax.swing.JScrollPane jScrollPane1;\n    private ChangeListener changeListener;\n    private Collection<String> possibleMainClasses;\n    private String dialogSubtitle = null;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates new form MainClassChooser\n     */\n    public MainClassChooser(Lookup.Provider project) {\n        this(project, null);\n    }\n\n    public MainClassChooser(Lookup.Provider project, String subtitle) {\n        dialogSubtitle = subtitle;\n        initComponents();\n        initClassesView(project);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns the selected main class.\n     *\n     * @return name of class or null if no class with the main method is selected\n     */\n    public String getSelectedMainClass() {\n        if (isValidMainClassName(jMainClassList.getSelectedValue())) {\n            return (String) jMainClassList.getSelectedValue();\n        } else {\n            return null;\n        }\n    }\n\n    public void addChangeListener(ChangeListener l) {\n        changeListener = l;\n    }\n\n    /**\n     * Checks if given file object contains the main method.\n     *\n     * @param classFO file object represents java\n     * @return false if parameter is null or doesn't contain SourceCookie\n     *         or SourceCookie doesn't contain the main method\n     */\n    public static boolean hasMainMethod(FileObject classFO) {\n        //    return MDRUtils.hasMainMethod(classFO);\n        return false;\n    }\n\n    public void removeChangeListener(ChangeListener l) {\n        changeListener = null;\n    }\n\n    private boolean isValidMainClassName(Object value) {\n        return (possibleMainClasses != null) && (possibleMainClasses.contains(value));\n    }\n\n    private Object[] getWarmupList() {\n        return new Object[] { Bundle.LBL_ChooseMainClass_WARMUP_MESSAGE() };\n    }\n\n    private void initClassesView(final Lookup.Provider project) {\n        possibleMainClasses = new ArrayList<>();\n        jMainClassList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        jMainClassList.setListData(getWarmupList());\n        RequestProcessor.getDefault().post(new Runnable() {\n                public void run() {\n                    for(SourceClassInfo sci : ProfilerTypeUtils.getMainClasses(project)) {\n                        possibleMainClasses.add(sci.getQualifiedName());\n                    }\n\n                    if (possibleMainClasses.isEmpty()) {\n                        jMainClassList.setListData(new String[] {\n                                                       Bundle.LBL_ChooseMainClass_NO_CLASSES_NODE()\n                                                   });\n                    } else {\n                        Object[] arr = possibleMainClasses.toArray();\n                        // #46861, sort name of classes\n                        Arrays.sort(arr);\n                        jMainClassList.setListData(arr);\n                        jMainClassList.setSelectedIndex(0);\n                    }\n                }\n            });\n        jMainClassList.addListSelectionListener(new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent evt) {\n                    if (changeListener != null) {\n                        changeListener.stateChanged(new ChangeEvent(evt));\n                    }\n                }\n            });\n        // support for double click to finish dialog with selected class\n        jMainClassList.addMouseListener(new MouseListener() {\n                public void mouseClicked(MouseEvent e) {\n                    if (MouseUtils.isDoubleClick(e)) {\n                        if (getSelectedMainClass() != null) {\n                            if (changeListener != null) {\n                                changeListener.stateChanged(new ChangeEvent(e));\n                            }\n                        }\n                    }\n                }\n\n                public void mousePressed(MouseEvent e) {\n                }\n\n                public void mouseReleased(MouseEvent e) {\n                }\n\n                public void mouseEntered(MouseEvent e) {\n                }\n\n                public void mouseExited(MouseEvent e) {\n                }\n            });\n\n        if (dialogSubtitle != null) {\n            Mnemonics.setLocalizedText(jLabel1, dialogSubtitle);\n        }\n    }\n\n    private void initComponents() {\n        java.awt.GridBagConstraints gridBagConstraints;\n\n        jLabel1 = new javax.swing.JLabel();\n        jScrollPane1 = new javax.swing.JScrollPane();\n        jMainClassList = new javax.swing.JList();\n\n        setLayout(new java.awt.GridBagLayout());\n\n        setPreferredSize(new java.awt.Dimension(380, 300));\n        getAccessibleContext()\n            .setAccessibleDescription(Bundle.AD_MainClassChooser());\n        jLabel1.setLabelFor(jMainClassList);\n        Mnemonics.setLocalizedText(jLabel1, Bundle.CTL_AvaialableMainClasses());\n        gridBagConstraints = new java.awt.GridBagConstraints();\n        gridBagConstraints.gridx = 0;\n        gridBagConstraints.gridy = 0;\n        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;\n        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;\n        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;\n        gridBagConstraints.weightx = 1.0;\n        gridBagConstraints.insets = new java.awt.Insets(12, 12, 2, 12);\n        add(jLabel1, gridBagConstraints);\n\n        jScrollPane1.setMinimumSize(new java.awt.Dimension(100, 200));\n        jScrollPane1.setViewportView(jMainClassList);\n        jMainClassList.getAccessibleContext()\n                      .setAccessibleDescription(Bundle.AD_jMainClassList());\n\n        gridBagConstraints = new java.awt.GridBagConstraints();\n        gridBagConstraints.gridx = 0;\n        gridBagConstraints.gridy = 1;\n        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;\n        gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;\n        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;\n        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;\n        gridBagConstraints.weightx = 1.0;\n        gridBagConstraints.weighty = 1.0;\n        gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 12);\n        add(jScrollPane1, gridBagConstraints);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/utils/MainClassWarning.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.utils;\n\nimport javax.swing.JPanel;\nimport javax.swing.event.ChangeListener;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n\n/**\n * Shows a warning that no main class is set and allows choose a main class.\n *\n * @author Tomas Hurka\n * @author Jiri Rechtacek\n */\n@NbBundle.Messages({\n    \"AD_MainClassWarning=N/A\"\n})\npublic class MainClassWarning extends JPanel {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private javax.swing.JLabel jLabel1;\n    private javax.swing.JScrollPane jScrollPane1;\n    private JPanel jPanel1;\n    private String message;\n    private Lookup.Provider project;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Creates new form LibrariesChooser\n     */\n    public MainClassWarning(String message, Lookup.Provider project) {\n        this.project = project;\n        this.message = message;\n        initComponents();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns the selected main class.\n     *\n     * @return name of class or null if no class with the main method is selected\n     */\n    public String getSelectedMainClass() {\n        return ((MainClassChooser) jPanel1).getSelectedMainClass();\n    }\n\n    public void addChangeListener(ChangeListener l) {\n        ((MainClassChooser) jPanel1).addChangeListener(l);\n    }\n\n    public void removeChangeListener(ChangeListener l) {\n        ((MainClassChooser) jPanel1).removeChangeListener(l);\n    }\n\n    private void initComponents() {\n        java.awt.GridBagConstraints gridBagConstraints;\n\n        jLabel1 = new javax.swing.JLabel();\n        jScrollPane1 = new javax.swing.JScrollPane();\n        jPanel1 = new MainClassChooser(project, Bundle.CTL_SelectAvaialableMainClasses());\n\n        setLayout(new java.awt.GridBagLayout());\n\n        getAccessibleContext()\n            .setAccessibleDescription(Bundle.AD_MainClassWarning());\n        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, this.message);\n        gridBagConstraints = new java.awt.GridBagConstraints();\n        gridBagConstraints.gridx = 0;\n        gridBagConstraints.gridy = 0;\n        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;\n        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;\n        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;\n        gridBagConstraints.weightx = 1.0;\n        gridBagConstraints.insets = new java.awt.Insets(12, 12, 6, 12);\n        add(jLabel1, gridBagConstraints);\n\n        jScrollPane1.setBorder(null);\n        jScrollPane1.setViewportView(jPanel1);\n\n        gridBagConstraints = new java.awt.GridBagConstraints();\n        gridBagConstraints.gridx = 1;\n        gridBagConstraints.gridy = 1;\n        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;\n        gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;\n        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;\n        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;\n        gridBagConstraints.weightx = 1.0;\n        gridBagConstraints.weighty = 1.0;\n        add(jScrollPane1, gridBagConstraints);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/ProfilerFeature.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2;\n\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.Icon;\nimport javax.swing.JPanel;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.common.event.ProfilingStateEvent;\nimport org.graalvm.visualvm.lib.common.event.ProfilingStateListener;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerFeature {\n\n    public abstract Icon getIcon();\n\n    public abstract String getName();\n\n    public abstract String getDescription();\n\n    public abstract int getPosition();\n\n\n    // To be called in EDT\n    public abstract JPanel getResultsUI();\n\n    // To be called in EDT\n    public abstract JPanel getSettingsUI();\n\n    // To be called in EDT\n    public abstract ProfilerToolbar getToolbar();\n\n\n    public abstract boolean supportsSettings(ProfilingSettings settings);\n\n    // To be called in EDT\n    public abstract void configureSettings(ProfilingSettings settings);\n\n    // To be called in EDT\n    public abstract boolean currentSettingsValid();\n\n\n    public abstract boolean supportsConfiguration(Lookup configuration);\n\n    // To be called in EDT\n    public abstract void configure(Lookup configuration);\n\n\n    protected void activatedInSession() {}\n\n    protected void deactivatedInSession() {}\n\n\n    public abstract void addChangeListener(ChangeListener listener);\n\n    public abstract void removeChangeListener(ChangeListener listener);\n    \n    \n    public static abstract class Basic extends ProfilerFeature {\n        \n        private Set<ChangeListener> listeners;\n        \n        private final Icon icon;\n        private final String name;\n        private final String description;\n        private final int position;\n        \n        private final ProfilerSession session;\n        \n        private volatile boolean isActive;\n        \n        \n        public Basic(Icon icon, String name, String description, int position, ProfilerSession session) {\n            this.icon = icon;\n            this.name = name;\n            this.description = description;\n            this.position = position;\n            \n            this.session = session;\n        }\n        \n        public final Icon getIcon() { return icon; }\n        \n        public final String getName() { return name; }\n    \n        public final String getDescription() { return description; }\n        \n        public final int getPosition() { return position; }\n        \n        \n        protected final ProfilerSession getSession() { return session; }\n        \n        \n        public JPanel getSettingsUI() { return null; }\n        \n        public boolean supportsSettings(ProfilingSettings settings) { return true; }\n        \n        public boolean currentSettingsValid() { return true; }\n        \n        \n        public ProfilerToolbar getToolbar() { return null; }\n        \n        \n        public boolean supportsConfiguration(Lookup configuration) { return false; }\n    \n        public void configure(Lookup configuration) {}\n        \n        \n        protected void notifyActivated() {}\n        \n        protected void notifyDeactivated() {}\n        \n        protected final boolean isActivated() { return isActive; }\n        \n        \n        protected final void activatedInSession() {\n            isActive = true;\n            \n            notifyActivated();\n            \n            session.addListener(getListener());\n            \n            final int state = session.getState();\n            Runnable notifier = new Runnable() {\n                public void run() { profilingStateChanged(-1, state); }\n            };\n            UIUtils.runInEventDispatchThread(notifier);\n        }\n    \n        protected final void deactivatedInSession() {\n            isActive = false;\n            \n            notifyDeactivated();\n            \n            session.removeListener(getListener());\n            listener = null;\n            \n            final int state = Profiler.PROFILING_INACTIVE;\n            Runnable notifier = new Runnable() {\n                public void run() { profilingStateChanged(-1, state); }\n            };\n            UIUtils.runInEventDispatchThread(notifier);\n        }\n        \n        protected final int getSessionState() {\n            return isActive ? session.getState() : Profiler.PROFILING_INACTIVE;\n        }\n        \n        \n        protected final String readFlag(String flag, String defaultValue) {\n            String id = getClass().getName();\n            return session.getStorage().readFlag(id + \"_\" + flag, defaultValue); // NOI18N\n        }\n        \n        protected final void storeFlag(String flag, String value) {\n            String id = getClass().getName();\n            session.getStorage().storeFlag(id + \"_\" + flag, value); // NOI18N\n        }\n        \n        \n        private ProfilingStateListener listener;\n        private ProfilingStateListener getListener() {\n            if (listener == null) listener = new ProfilingStateListener() {\n                public void serverStateChanged(int serverState, int serverProgress) {\n                    if (!isActive) return;\n                    Basic.this.serverStateChanged(serverState, serverProgress);\n                }\n                public void instrumentationChanged(int oldType, int newType) {\n                    if (!isActive) return;\n                    Basic.this.instrumentationChanged(oldType, newType);\n                }\n                public void profilingStateChanged(ProfilingStateEvent e) {\n                    if (!isActive) return;\n                    Basic.this.profilingStateChanged(e.getOldState(), e.getNewState());\n                }\n                public void threadsMonitoringChanged() {\n                    if (!isActive) return;\n                    Basic.this.threadsMonitoringChanged();\n                }\n                public void lockContentionMonitoringChanged() {\n                    if (!isActive) return;\n                    Basic.this.lockContentionMonitoringChanged();\n                }\n            };\n            return listener;\n        }\n        \n        protected void serverStateChanged(int serverState, int serverProgress) {}\n        \n        protected void instrumentationChanged(int oldType, int newType) {}\n\n        protected void profilingStateChanged(int oldState, int newState) {}\n\n        protected void threadsMonitoringChanged() {}\n\n        protected void lockContentionMonitoringChanged() {}\n        \n        \n        public synchronized final void addChangeListener(ChangeListener listener) {\n            if (listeners == null) listeners = new HashSet();\n            listeners.add(listener);\n        }\n    \n        public synchronized final void removeChangeListener(ChangeListener listener) {\n            if (listeners != null) listeners.remove(listener);\n        }\n        \n        protected synchronized final void fireChange() {\n            if (listeners == null) return;\n            ChangeEvent e = new ChangeEvent(this);\n            for (ChangeListener listener : listeners) listener.stateChanged(e);\n        }\n        \n    }\n    \n    \n    // --- Provider ------------------------------------------------------------\n    \n    public static abstract class Provider {\n        \n        public abstract ProfilerFeature getFeature(ProfilerSession session);\n        \n    }\n    \n    \n    // --- Registry ------------------------------------------------------------\n    \n    public static final class Registry {\n        \n        private static boolean HAS_PROVIDERS;\n        \n        private Registry() {}\n        \n        public static boolean hasProviders() {\n            return HAS_PROVIDERS;\n        }\n        \n        static Collection<? extends Provider> getProviders() {\n            Collection<? extends Provider> providers = Lookup.getDefault().lookupAll(Provider.class);\n            HAS_PROVIDERS = !providers.isEmpty();\n            return providers;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/ProfilerFeatures.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2;\n\nimport java.util.Comparator;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Set;\nimport java.util.TreeSet;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.openide.util.Lookup;\nimport org.openide.util.RequestProcessor;\n\n/**\n * Note: all methods excluding constructor and getAvailable() to be called in EDT.\n *\n * @author Jiri Sedlacek\n */\nfinal class ProfilerFeatures {\n\n    private static final String FLAG_SINGLE_FEATURE = \"SINGLE_FEATURE\"; // NOI18N\n    private static final String FLAG_ACTIVATED_FEATURES = \"ACTIVATED_FEATURES\"; // NOI18N\n    private static final String FLAG_PROFILING_POINTS = \"PROFILING_POINTS\"; // NOI18N\n\n    private static final Boolean SINGLE_FEATURE_DEFAULT = Boolean.TRUE;\n    private static final Boolean PROFILING_POINTS_DEFAULT = Boolean.TRUE;\n\n    private static final Comparator<ProfilerFeature> FEATURES_COMPARATOR =\n        new Comparator<ProfilerFeature>() {\n            public int compare(ProfilerFeature f1, ProfilerFeature f2) {\n                return Integer.compare(f1.getPosition(), f2.getPosition());\n            }\n        };\n\n    private final ProfilerSession session;\n\n    private final Set<ProfilerFeature> features;\n    private final Set<ProfilerFeature> activated;\n\n    private final Set<Listener> listeners;\n    private final ChangeListener listener = new ChangeListener() {\n        public void stateChanged(ChangeEvent e) { fireSettingsChanged(); }\n    };\n\n    private boolean singleFeatured;\n    private boolean ppoints;\n\n\n    ProfilerFeatures(ProfilerSession session) {\n        this.session = session;\n        \n        SessionStorage storage = session.getStorage();\n        singleFeatured = Boolean.parseBoolean(storage.readFlag(FLAG_SINGLE_FEATURE, SINGLE_FEATURE_DEFAULT.toString()));\n        ppoints = Boolean.parseBoolean(storage.readFlag(FLAG_PROFILING_POINTS, PROFILING_POINTS_DEFAULT.toString()));\n        \n        features = new TreeSet(FEATURES_COMPARATOR);\n        activated = new TreeSet(FEATURES_COMPARATOR);\n        \n        listeners = new HashSet();\n        \n        // Populates SessionStorage, can be accessed in EDT from now\n        for (ProfilerFeature.Provider provider : ProfilerFeature.Registry.getProviders()) {\n            ProfilerFeature feature = provider.getFeature(session);\n            if (feature != null) features.add(feature);\n//            features.add(provider.getFeature(session));\n        }\n        \n        loadActivatedFeatures();\n    }\n    \n    \n    Set<ProfilerFeature> getAvailable() {\n        return features;\n    }\n    \n    Set<ProfilerFeature> getActivated() {\n        assert SwingUtilities.isEventDispatchThread();\n        \n        return activated;\n    }\n    \n    static Set<ProfilerFeature> getCompatible(Set<ProfilerFeature> f, Lookup c) {\n        Set<ProfilerFeature> s = new TreeSet(FEATURES_COMPARATOR);\n        for (ProfilerFeature p : f) if (p.supportsConfiguration(c)) s.add(p);\n        return s;\n    }\n    \n    void activateFeature(ProfilerFeature feature) {\n        assert SwingUtilities.isEventDispatchThread();\n        \n        if (singleFeatured) {\n            if (activated.size() == 1 && activated.contains(feature)) return;\n            for (ProfilerFeature f : activated) {\n                f.deactivatedInSession();\n                f.removeChangeListener(listener);\n            }\n            activated.clear();\n            activated.add(feature);\n            feature.addChangeListener(listener);\n            feature.activatedInSession();\n            fireFeaturesChanged(feature);\n            saveActivatedFeatures();\n        } else {\n            if (activated.add(feature)) {\n                ProfilingSettings ps = ProfilerIDESettings.getInstance().createDefaultProfilingSettings();\n                feature.configureSettings(ps);\n                \n                Iterator<ProfilerFeature> it = activated.iterator();\n                while (it.hasNext()) {\n                    ProfilerFeature f = it.next();\n                    if (f != feature && !f.supportsSettings(ps)) {\n                        it.remove();\n                        f.deactivatedInSession();\n                        f.removeChangeListener(listener);\n                    }\n                }\n                \n                feature.addChangeListener(listener);\n                feature.activatedInSession();\n                fireFeaturesChanged(feature);\n                saveActivatedFeatures();\n            }\n        }\n    }\n    \n    void deactivateFeature(ProfilerFeature feature) {\n        assert SwingUtilities.isEventDispatchThread();\n        \n        if (activated.size() == 1 && activated.contains(feature) && session.inProgress()) return;\n        if (activated.remove(feature)) {\n            feature.deactivatedInSession();\n            feature.removeChangeListener(listener);\n            fireFeaturesChanged(feature);\n            saveActivatedFeatures();\n        }\n    }\n    \n    void toggleActivated(ProfilerFeature feature) {\n        if (activated.contains(feature)) deactivateFeature(feature);\n        else activateFeature(feature);\n    }\n    \n    \n    private volatile boolean loading;\n    \n    private void loadActivatedFeatures() {\n        loading = true;\n        final String _activated = session.getStorage().readFlag(FLAG_ACTIVATED_FEATURES, \"\"); // NOI18N\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                for (ProfilerFeature feature : features)\n                    if (_activated.contains(getFeatureID(feature)))\n                        activateFeature(feature);\n                loading = false;\n            }\n        });\n    }\n    \n    private void saveActivatedFeatures() {\n        if (loading) return;\n        final Set<ProfilerFeature> _activated = new HashSet(activated);\n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() {\n                SessionStorage storage = session.getStorage();\n                if (_activated.isEmpty()) {\n                    storage.storeFlag(FLAG_ACTIVATED_FEATURES, null);\n                } else {\n                    StringBuilder b = new StringBuilder();\n                    for (ProfilerFeature feature : _activated)\n                        b.append(getFeatureID(feature));\n                    storage.storeFlag(FLAG_ACTIVATED_FEATURES, b.toString());\n                }\n            }\n        });\n    }\n    \n    private static String getFeatureID(ProfilerFeature feature) {\n        return \"#\" + feature.getClass().getName() + \"@\"; // NOI18N\n    }\n    \n    \n    void setSingleFeatured(boolean single) {\n        assert SwingUtilities.isEventDispatchThread();\n        \n        singleFeatured = single;\n        \n        if (singleFeatured && !activated.isEmpty())\n            activateFeature(activated.iterator().next());\n        \n        session.getStorage().storeFlag(FLAG_SINGLE_FEATURE, SINGLE_FEATURE_DEFAULT.equals(single) ?\n                                       null : Boolean.toString(singleFeatured));\n    }\n    \n    boolean isSingleFeatured() {\n        assert SwingUtilities.isEventDispatchThread();\n        \n        return singleFeatured;\n    }\n    \n    \n    void setUseProfilingPoints(boolean use) {\n        assert SwingUtilities.isEventDispatchThread();\n        \n        ppoints = use;\n        \n        session.getStorage().storeFlag(FLAG_PROFILING_POINTS, PROFILING_POINTS_DEFAULT.equals(use) ?\n                                       null : Boolean.toString(use));\n    }\n    \n    boolean getUseProfilingPoints() {\n        assert SwingUtilities.isEventDispatchThread();\n        \n        return ppoints;\n    }\n    \n    \n    boolean settingsValid() {\n        assert SwingUtilities.isEventDispatchThread();\n        \n        if (activated.isEmpty()) return false;\n        \n        for (ProfilerFeature f : activated) if (!f.currentSettingsValid()) return false;\n        \n        return true;\n    }\n    \n    ProfilingSettings getSettings() {\n        assert SwingUtilities.isEventDispatchThread();\n        \n        session.persistStorage(false);\n        \n        if (activated.isEmpty()) return null;\n        \n        ProfilingSettings settings = ProfilerIDESettings.getInstance().createDefaultProfilingSettings();\n        for (ProfilerFeature f : activated) f.configureSettings(settings);\n        \n        settings.setUseProfilingPoints(ppoints);\n        \n        return settings;\n    }\n    \n    \n    void sessionFinished() {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                for (ProfilerFeature activated : getActivated())\n                    activated.deactivatedInSession();\n            }\n        });\n    }\n    \n    \n    void addListener(Listener listener) {\n        assert SwingUtilities.isEventDispatchThread();\n        \n        listeners.add(listener);\n    }\n    \n    void removeListener(Listener listener) {\n        assert SwingUtilities.isEventDispatchThread();\n        \n        listeners.remove(listener);\n    }\n    \n    private void fireFeaturesChanged(ProfilerFeature changed) {\n        boolean valid = settingsValid();\n        for (Listener l : listeners) {\n            l.featuresChanged(changed);\n            l.settingsChanged(valid); // Not necessarily, but ProfilingSettings don't provide equals() to decide\n        }\n    }\n    \n    private void fireSettingsChanged() {\n        boolean valid = settingsValid();\n        for (Listener l : listeners) {\n            l.settingsChanged(valid);\n        }\n    }\n    \n    \n    static abstract class Listener {\n        \n        abstract void featuresChanged(ProfilerFeature changed);\n        \n        abstract void settingsChanged(boolean valid);\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/ProfilerPlugin.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.v2;\n\nimport javax.swing.JMenu;\nimport org.openide.util.Lookup;\n\n/**\n * Common superclass for simple addons integrating into the Profile menu and\n * getting notifications about state of the profiler session.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerPlugin {\n\n    private final String name;\n\n\n    public ProfilerPlugin(String name) {\n        if (name == null) throw new IllegalArgumentException(\"Plugin name cannot be null\"); // NOI18N\n        this.name = name;\n    }\n\n\n    public final String getName() {\n        return name;\n    }\n\n\n    public abstract void createMenu(JMenu menu);\n\n\n    protected void sessionStarting() {}\n\n    protected void sessionStarted()  {}\n\n    protected void sessionStopping() {}\n\n    protected void sessionStopped()  {}\n\n\n    // --- Provider ------------------------------------------------------------\n\n    public static abstract class Provider {\n\n        public abstract ProfilerPlugin createPlugin(Lookup.Provider project, SessionStorage storage);\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/ProfilerPlugins.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.v2;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuItem;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.event.ProfilingStateAdapter;\nimport org.graalvm.visualvm.lib.common.event.ProfilingStateEvent;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ProfilerPlugins_PluginNotInitialized=<html><b>Profiler plugin failed to initialize:</b><br><br>{0}</html>\",\n    \"ProfilerPlugins_PluginFailed=<html><b>Plugin {0} failed:</b><br><br>{1}</html>\"\n})\nfinal class ProfilerPlugins {\n\n    private final List<ProfilerPlugin> plugins;\n\n\n    ProfilerPlugins(ProfilerSession session) {\n        Collection<? extends ProfilerPlugin.Provider> providers =\n                Lookup.getDefault().lookupAll(ProfilerPlugin.Provider.class);\n\n        if (providers.isEmpty()) {\n            plugins = null;\n        } else {\n            List<ProfilerPlugin> _plugins = new ArrayList();\n            Lookup.Provider project = session.getProject();\n            SessionStorage storage = session.getStorage();\n            for (ProfilerPlugin.Provider provider : providers) {\n                ProfilerPlugin plugin = null;\n                try { plugin = provider.createPlugin(project, storage); }\n                catch (Throwable t) { handleThrowable(plugin, t); }\n                if (plugin != null) _plugins.add(plugin);\n            }\n\n            if (_plugins.isEmpty()) {\n                plugins = null;\n            } else {\n                session.addListener(new ProfilingStateAdapter() {\n                    public void profilingStateChanged(ProfilingStateEvent e) {\n                        int state = e.getNewState();\n                        if (state == Profiler.PROFILING_STARTED) notifyStarted();\n                        else if (state == Profiler.PROFILING_INACTIVE) notifyStopped();\n                    }\n                });\n                plugins = _plugins;\n            }\n        }\n    }\n    \n    \n    boolean hasPlugins() {\n        return plugins != null;\n    }\n    \n    List<JMenuItem> menuItems() {\n        List<JMenuItem> menus = new ArrayList();\n        \n        if (plugins != null) for (ProfilerPlugin plugin : plugins) {\n            try {\n                JMenu menu = new JMenu(plugin.getName());\n                plugin.createMenu(menu);\n                if (menu.getItemCount() > 0) menus.add(menu);\n            } catch (Throwable t) {\n                handleThrowable(plugin, t);\n            }\n        }\n        \n        return menus;\n    }\n    \n    \n    void notifyStarting() {\n        if (plugins != null) for (ProfilerPlugin plugin : plugins)\n            try {\n                plugin.sessionStarting();\n            } catch (Throwable t) {\n                handleThrowable(plugin, t);\n            }\n    }\n    \n    void notifyStarted() {\n        if (plugins != null) for (ProfilerPlugin plugin : plugins)\n            try {\n                plugin.sessionStarted();\n            } catch (Throwable t) {\n                handleThrowable(plugin, t);\n            }\n    }\n    \n    void notifyStopping() {\n        if (plugins != null) for (ProfilerPlugin plugin : plugins)\n            try {\n                plugin.sessionStopping();\n            } catch (Throwable t) {\n                handleThrowable(plugin, t);\n            }\n    }\n    \n    void notifyStopped() {\n        if (plugins != null) for (ProfilerPlugin plugin : plugins)\n            try {\n                plugin.sessionStopped();\n            } catch (Throwable t) {\n                handleThrowable(plugin, t);\n            }\n    }\n    \n    private void handleThrowable(final ProfilerPlugin p, final Throwable t) {\n        t.printStackTrace(System.err);\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                String log = t.getLocalizedMessage();\n                String msg = p == null ? Bundle.ProfilerPlugins_PluginNotInitialized(log) :\n                                  Bundle.ProfilerPlugins_PluginFailed(p.getName(), log);\n                ProfilerDialogs.displayError(msg);\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/ProfilerSession.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.common.AttachSettings;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.common.event.ProfilingStateListener;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.profiler.actions.ResetResultsAction;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.utilities.ProfilerUtils;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerSession {\n\n    // --- Static access -------------------------------------------------------\n\n    private static ProfilerSession CURRENT_SESSION;\n    private static final Object CURRENT_SESSION_LOCK = new Object();\n\n\n    public static ProfilerSession currentSession() {\n        synchronized(CURRENT_SESSION_LOCK) {\n            return CURRENT_SESSION;\n        }\n    }\n\n    public static ProfilerSession forContext(Lookup context) {\n        synchronized(CURRENT_SESSION_LOCK) {\n            if (CURRENT_SESSION != null) {\n                if (CURRENT_SESSION.isCompatibleContext(context)) {\n                    // Reuse the compatible active session\n                    CURRENT_SESSION.setContext(context);\n                    return CURRENT_SESSION;\n                } else {\n                    // Close the incompatible active session\n                    if (!CURRENT_SESSION.close()) return null;\n                }\n            }\n        }\n\n        if (!ProfilerSessions.waitForProfiler()) return null;\n\n        // Create a new session, will eliminate another session when showing UI\n        Provider provider = Lookup.getDefault().lookup(Provider.class);\n        ProfilerSession session = provider == null ? null : provider.createSession(context);\n\n        synchronized (CURRENT_SESSION_LOCK) { CURRENT_SESSION = session; }\n            \n        notifyStopAction();\n\n        return session;\n        \n    };\n    \n    \n    public static void findAndConfigure(Lookup context, Lookup.Provider project, String actionName) {\n        ProfilerSession current = currentSession();\n        if (current != null) ProfilerSessions.configure(current, context, actionName);\n        else ProfilerSessions.createAndConfigure(context, project, actionName);\n    }\n    \n    \n    // --- Constructor ---------------------------------------------------------\n    \n    protected ProfilerSession(Profiler _profiler, Lookup context) {\n        if (_profiler == null) throw new IllegalArgumentException(\"Profiler cannot be null\"); // NOI18N\n        \n        profiler = _profiler;\n        setContext(context);\n    }\n    \n    \n    // --- Context -------------------------------------------------------------\n    \n    private Lookup context;\n    \n    \n    protected synchronized final Lookup getContext() { return context; }\n    \n    private final void setContext(Lookup _context) {\n        synchronized(this) { context = _context; }\n        notifyWindow();\n    }\n    \n    \n    // --- SPI -----------------------------------------------------------------\n    \n    // Called in EDT, return false for start failure\n    protected abstract boolean start();\n    \n    // Called in EDT, return false for modify failure\n    protected abstract boolean modify();\n    \n    // Called in EDT, return false for termination failure\n    protected abstract boolean stop();\n    \n    \n    public abstract Lookup.Provider getProject();\n    \n    public abstract FileObject getFile();\n    \n    \n    protected abstract boolean isCompatibleContext(Lookup context);\n    \n    \n    // --- API -----------------------------------------------------------------\n    \n    private final Profiler profiler;\n    private ProfilerWindow window;\n    \n    private ProfilingSettings profilingSettings;\n    private AttachSettings attachSettings;\n    \n    private boolean isAttach;\n    \n    private SessionStorage storage;\n    \n    \n    public final void setAttach(final boolean attach) {\n        synchronized (this) { if (attach == isAttach) return; }\n        \n        boolean sessionInProgress = inProgress();\n        if (sessionInProgress && !confirmedStop()) return;\n        \n        Runnable updater = new Runnable() {\n            public void run() {\n                synchronized (ProfilerSession.this) { isAttach = attach; }\n                notifyStopAction();\n                notifyWindow();\n            }\n        };\n        \n        if (!sessionInProgress) updater.run();\n        else ProfilerUtils.runInProfilerRequestProcessor(updater);\n    }\n    \n    // Set when configuring profiling session, not a persistent storage!\n    public synchronized final boolean isAttach() { return isAttach; }\n    \n    \n    public final Profiler getProfiler() { return profiler; }    \n    \n    // Set when starting/modifying profiling session, not a persistent storage!\n    public final ProfilingSettings getProfilingSettings() { return profilingSettings; }\n    \n    // Set when starting profiling session, not a persistent storage!\n    public final AttachSettings getAttachSettings() { return attachSettings; }\n    \n    public final synchronized SessionStorage getStorage() {\n        if (storage == null) storage = new SessionStorage(getProject());\n        return storage;\n    }\n    \n    \n    public final void open() {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                ProfilerWindow w = getWindow();\n                w.open();\n                w.requestActive();\n            }\n        });\n    };\n    \n    \n    // --- Profiler API bridge -------------------------------------------------\n    \n    private final Set<ProfilingStateListener> profilingStateListeners = new HashSet();\n    \n    \n    public final int getState() {\n        return profiler.getProfilingState();\n    }\n    \n    public final boolean inProgress() {\n        return getState() != Profiler.PROFILING_INACTIVE;\n    }\n    \n    public final void addListener(ProfilingStateListener listener) {\n        synchronized (profiler) {\n            profiler.addProfilingStateListener(listener);\n            profilingStateListeners.add(listener);\n        }\n    }\n    \n    public final void removeListener(ProfilingStateListener listener) {\n        synchronized (profiler) {\n            profiler.removeProfilingStateListener(listener);\n            profilingStateListeners.remove(listener);\n        }\n    }\n    \n    \n    private final void cleanupAllListeners() {\n        synchronized (profiler) {\n            for (ProfilingStateListener listener : profilingStateListeners)\n                profiler.removeProfilingStateListener(listener);\n        }\n    }\n    \n    // --- Internal API --------------------------------------------------------\n    \n    private ProfilerFeatures features;\n    private ProfilerPlugins plugins;\n    \n    final boolean doStart(ProfilingSettings pSettings, AttachSettings aSettings) {\n        profilingSettings = pSettings;\n        attachSettings = aSettings;\n        plugins.notifyStarting();\n        return start();\n    }\n    \n    final boolean doModify(ProfilingSettings pSettings) {\n        profilingSettings = pSettings;\n        return modify();\n    }\n    \n    final boolean doStop() {\n        plugins.notifyStopping();\n        return stop();\n    }\n    \n    private final boolean confirmedStop() {\n        if (inProgress()) {\n            if (!ProfilerDialogs.displayConfirmation(Bundle.ProfilerWindow_terminateMsg(),\n                                                Bundle.ProfilerWindow_terminateCaption()))\n                return false;\n            if (!doStop()) return false;\n        }\n        \n        return true;\n    }\n    \n    final boolean close() {\n        if (!confirmedStop()) return false;\n        \n        synchronized (CURRENT_SESSION_LOCK) {\n            if (CURRENT_SESSION == this) CURRENT_SESSION = null;\n        }\n        \n        notifyStopAction();\n        \n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                if (window != null) {\n                    if (!window.closing && window.isOpened()) {\n                        window.closing = true;\n                        window.close(); // calls session.cleanup()\n                    }\n                } else {\n                    cleanup();\n                }\n            }\n        });\n        \n        return true;\n    }\n    \n    final ProfilerFeatures getFeatures() {\n        assert !SwingUtilities.isEventDispatchThread();\n        \n        synchronized(this) { if (features == null) features = new ProfilerFeatures(this); }\n        \n        return features;\n    }\n    \n    final void selectFeature(final ProfilerFeature feature) {\n        Runnable task = new Runnable() {\n            public void run() { getWindow().selectFeature(feature); }\n        };\n        UIUtils.runInEventDispatchThread(task);\n    }\n    \n    final ProfilerPlugins getPlugins() {\n        assert !SwingUtilities.isEventDispatchThread();\n        \n        synchronized(this) { if (plugins == null) plugins = new ProfilerPlugins(this); }\n        \n        return plugins;\n    }\n    \n    final synchronized void persistStorage(boolean immediately) {\n        if (storage != null) storage.persist(immediately);\n    }\n    \n    \n    // --- Implementation ------------------------------------------------------\n    \n    private ProfilerWindow getWindow() {\n        assert SwingUtilities.isEventDispatchThread();\n        \n        if (window == null) {\n            window = new ProfilerWindow(ProfilerSession.this) {\n                protected void componentClosed() {\n                    super.componentClosed();\n                    window = null;\n                    cleanup();\n                }\n            };\n        }\n        return window;\n    }\n    \n    private void notifyWindow() {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() { if (window != null) window.updateSession(); }\n        });\n    }\n    \n    private void cleanup() {\n        synchronized(this) { if (features != null) features.sessionFinished(); }\n        \n        cleanupAllListeners();\n        \n        // Note: should call profiler.resetAllResults() once implemented\n        ResetResultsAction.getInstance().performAction();\n        \n        persistStorage(false);\n    }\n    \n    private static void notifyStopAction() {\n        final ProfilerSession CURRENT_SESSION_F;\n        synchronized (CURRENT_SESSION_LOCK) { CURRENT_SESSION_F = CURRENT_SESSION; }\n        \n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() { ProfilerSessions.StopAction.getInstance().setSession(CURRENT_SESSION_F); }\n        });\n    }\n    \n    \n    // --- Provider ------------------------------------------------------------\n    \n    public static abstract class Provider {\n        \n        public abstract ProfilerSession createSession(Lookup context);\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/ProfilerSessions.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ItemEvent;\nimport java.util.Set;\nimport javax.swing.AbstractAction;\nimport javax.swing.ButtonGroup;\nimport javax.swing.JButton;\nimport javax.swing.JDialog;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JProgressBar;\nimport javax.swing.JRadioButton;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport javax.swing.border.EmptyBorder;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.event.ProfilingStateAdapter;\nimport org.graalvm.visualvm.lib.common.event.ProfilingStateEvent;\nimport org.graalvm.visualvm.lib.common.event.ProfilingStateListener;\nimport org.graalvm.visualvm.lib.common.event.SimpleProfilingStateAdapter;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedRadioButton;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProjectUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.v2.ui.ProjectSelector;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.ActionID;\nimport org.openide.awt.ActionReference;\nimport org.openide.awt.ActionReferences;\nimport org.openide.awt.ActionRegistration;\nimport org.openide.awt.Mnemonics;\nimport org.openide.modules.OnStop;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.lookup.Lookups;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ProfilerSessions_actionNotSupported=Action not supported by the current profiling session.\",\n    \"ProfilerSessions_loadingFeatures=Loading profiler modes...\",\n    \"ProfilerSessions_noFeature=<no compatible mode available>\",\n    \"ProfilerSessions_selectProject=&Select the project to profile:\",\n    \"ProfilerSessions_selectFeature=Select Profiler Mode\",\n    \"ProfilerSessions_selectHandlingFeature=S&elect profiler mode to handle the action:\",\n    \"ProfilerSessions_selectProjectAndFeature=Select Project and Profiler Mode\",\n    \"ProfilerSessions_finishingSession=Finishing previous session...\",\n    \"ProfilerSessions_finishSessionCaption=Profile\",\n    \"ProfilerSessions_cancel=Cancel\",\n    \"ProfilerSessions_profileProject=&Profile project\",\n    \"ProfilerSessions_attachProject=&Attach to project\"\n})\nfinal class ProfilerSessions {\n    \n    // --- Find and configure session ------------------------------------------\n    \n    static void configure(final ProfilerSession session, final Lookup context, final String actionName) {\n        final ProfilerFeatures _features = session.getFeatures();\n        final Set<ProfilerFeature> compatA = ProfilerFeatures.getCompatible(\n                                             _features.getAvailable(), context);\n        if (compatA.isEmpty()) {\n            // TODO: might offer creating a new profiling session if the current is not in progress\n            ProfilerDialogs.displayInfo(Bundle.ProfilerSessions_actionNotSupported());\n        } else {\n            // Resolving selected features in only supported in EDT\n            UIUtils.runInEventDispatchThread(new Runnable() {\n                public void run() {\n                    Set<ProfilerFeature> compatS = ProfilerFeatures.getCompatible(\n                                                   _features.getActivated(), context);\n\n                    ProfilerFeature feature;\n                    if (compatS.size() == 1) {\n                        // Exactly one selected feature handles the action\n                        feature = compatS.iterator().next();\n                    } else if (!compatS.isEmpty()) {\n                        // Multiple selected features handle the action\n                        feature = selectFeature(compatS, actionName);\n                    } else if (compatA.size() == 1) {\n                        // Exactly one available feature handles the action\n                        feature = compatA.iterator().next();\n                    } else {\n                        // Multiple available features handle the action\n                        feature = selectFeature(compatA, actionName);\n                    }\n\n                    if (feature != null) {\n                        _features.activateFeature(feature);\n                        feature.configure(context);\n                        session.selectFeature(feature);\n                        session.open();\n                    }\n                }\n            });\n        }\n    }\n    \n    static void createAndConfigure(final Lookup context, Lookup.Provider project, final String actionName) {\n        if (project == null) project = ProjectUtilities.getMainProject();\n        final Lookup.Provider _project = project;\n        \n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                UI ui = UI.createAndConfigure(context, _project);\n\n                HelpCtx helpCtx = new HelpCtx(\"SelectFeatureDialog.HelpCtx\"); // NOI18N\n                String caption = actionName == null ? Bundle.ProfilerSessions_selectProjectAndFeature() : actionName;\n                DialogDescriptor dd = new DialogDescriptor(ui, caption, true, new Object[]\n                                                         { DialogDescriptor.OK_OPTION, DialogDescriptor.CANCEL_OPTION },\n                                                           DialogDescriptor.OK_OPTION, DialogDescriptor.BOTTOM_ALIGN,\n                                                           helpCtx, null);\n                Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n                d.setVisible(true);\n                \n                final ProfilerSession session = ui.selectedSession();\n\n                if (dd.getValue() == DialogDescriptor.OK_OPTION) {\n                    final ProfilerFeature feature = ui.selectedFeature();\n\n                    RequestProcessor.getDefault().post(new Runnable() {\n                        public void run() {\n                            final ProfilerFeatures features = session.getFeatures();\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    features.activateFeature(feature);\n                                    feature.configure(context);\n                                    session.selectFeature(feature);\n                                    session.open();\n                                }\n                            });\n                        }\n                    });\n                } else {\n                    if (session != null) session.close();\n                }\n                \n                dd.setMessage(null); // Do not leak because of WindowsPopupMenuUI.mnemonicListener\n                \n            }\n        });\n    }\n    \n    private static ProfilerFeature selectFeature(Set<ProfilerFeature> features, String actionName) {\n        UI ui = UI.selectFeature(features);\n\n        HelpCtx helpCtx = new HelpCtx(\"SelectFeatureDialog.HelpCtx\"); // NOI18N // TODO: should have a special one?\n        String caption = actionName == null ? Bundle.ProfilerSessions_selectFeature() : actionName;\n        DialogDescriptor dd = new DialogDescriptor(ui, caption, true, new Object[]\n                                                 { DialogDescriptor.OK_OPTION, DialogDescriptor.CANCEL_OPTION },\n                                                   DialogDescriptor.OK_OPTION, DialogDescriptor.BOTTOM_ALIGN,\n                                                   helpCtx, null);\n        Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n        d.setVisible(true);\n        \n        ProfilerFeature ret = dd.getValue() == DialogDescriptor.OK_OPTION ? ui.selectedFeature() : null;\n        \n        dd.setMessage(null); // Do not leak because of WindowsPopupMenuUI.mnemonicListener\n        \n        return ret;\n    }\n    \n    \n    private static class UI extends JPanel {\n        \n        private ProfilerFeature selectedFeature;\n        private ProfilerSession selectedSession;\n        \n        static UI selectFeature(Set<ProfilerFeature> features) {\n            return new UI(features);\n        }\n        \n        static UI createAndConfigure(Lookup context, Lookup.Provider project) {\n            return new UI(context, project);\n        }\n        \n        \n        ProfilerFeature selectedFeature() {\n            return selectedFeature;\n        }\n        \n        ProfilerSession selectedSession() {\n            if (selectedSession != null)\n                selectedSession.setAttach(attachProject.isSelected());\n            return selectedSession;\n        }\n        \n            \n        UI(Set<ProfilerFeature> features) {\n            super(new GridBagLayout());\n            \n            int y = 0;\n            GridBagConstraints c;\n            \n            selectModeLabel = new JLabel();\n            Mnemonics.setLocalizedText(selectModeLabel, Bundle.ProfilerSessions_selectHandlingFeature());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(10, 10, 10, 10);\n            add(selectModeLabel, c);\n            \n            ButtonGroup rbg = new ButtonGroup();\n            for (final ProfilerFeature f : features) {\n                JRadioButton rb = new JExtendedRadioButton(f.getName(), f.getIcon()) {\n                    protected void fireItemStateChanged(ItemEvent e) {\n                        if (e.getStateChange() == ItemEvent.SELECTED)\n                            selectedFeature = f;\n                    }\n                };\n                rbg.add(rb);\n                if (rbg.getSelection() == null) rb.setSelected(true);\n                c = new GridBagConstraints();\n                c.gridx = 0;\n                c.gridy = y++;\n                c.anchor = GridBagConstraints.WEST;\n                c.insets = new Insets(0, 20, 0, 10);\n                add(rb, c);\n                if (selectModeLabel.getLabelFor() == null) selectModeLabel.setLabelFor(rb);\n            }\n            \n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.weightx = 1;\n            c.weighty = 1;\n            c.fill = GridBagConstraints.BOTH;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.insets = new Insets(15, 0, 0, 300);\n            add(UIUtils.createFillerPanel(), c);\n        }\n        \n        private JPanel contents;\n        private JRadioButton profileProject;\n        private JRadioButton attachProject;\n        private JLabel selectModeLabel;\n        \n        private void repaintContents() {\n            contents.invalidate();\n            contents.revalidate();\n            contents.repaint();\n        }\n        \n        UI(final Lookup context, final Lookup.Provider project) {\n            super(new GridBagLayout());\n            \n            int y = 0;\n            GridBagConstraints c;\n            \n            JLabel l = new JLabel();\n            Mnemonics.setLocalizedText(l, Bundle.ProfilerSessions_selectProject());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(10, 10, 10, 10);\n            add(l, c);\n            \n            contents = new JPanel(new GridBagLayout());\n            \n            ProjectSelector.Populator populator = new ProjectSelector.Populator() {\n                protected Lookup.Provider initialProject() { return project; }\n            };\n            ProjectSelector selector = new ProjectSelector(populator) {\n                protected void selectionChanged() {\n                    Lookup.Provider project = getProject();\n                    refreshProfileAttach(project);\n                    refreshFeatures(context, project);\n                }\n            };\n            l.setLabelFor(selector);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, 20, 4, 10);\n            add(selector, c);\n            \n            ButtonGroup bg = new ButtonGroup();\n            \n            profileProject = new JRadioButton();\n            bg.add(profileProject);\n            profileProject.setSelected(true);\n            Mnemonics.setLocalizedText(profileProject, Bundle.ProfilerSessions_profileProject());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y;\n            c.weightx = 0;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(0, 20, 10, 5);\n            add(profileProject, c);\n            \n            attachProject = new JRadioButton();\n            bg.add(attachProject);\n            Mnemonics.setLocalizedText(attachProject, Bundle.ProfilerSessions_attachProject());\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = y;\n            c.weightx = 0;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(0, 0, 10, 10);\n            add(attachProject, c);\n            \n            c = new GridBagConstraints();\n            c.gridx = 2;\n            c.gridy = y++;\n            c.weightx = 1;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, 0, 10, 0);\n            add(UIUtils.createFillerPanel(), c);\n            \n            selectModeLabel = new JLabel();\n            Mnemonics.setLocalizedText(selectModeLabel, Bundle.ProfilerSessions_selectHandlingFeature());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(10, 10, 10, 10);\n            add(selectModeLabel, c);\n            \n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(0, 0, 0, 0);\n            add(contents, c);\n            \n            JRadioButton ref = new JExtendedRadioButton(\"XXX\"); // NOI18N\n            final int refHeight = ref.getPreferredSize().height;\n            JPanel filler = new JPanel(null) {\n                public Dimension getPreferredSize() {\n                    return new Dimension(300, refHeight * 2);\n                }\n            };\n            filler.setOpaque(false);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.weightx = 1;\n            c.weighty = 1;\n            c.fill = GridBagConstraints.BOTH;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.insets = new Insets(15, 0, 0, 0);\n            add(filler, c);\n            \n            Lookup.Provider _project = selector.getProject();\n            refreshProfileAttach(_project);\n            refreshFeatures(context, _project);\n        }\n        \n        private void refreshProfileAttach(Lookup.Provider project) {\n            boolean fromExternal = !profileProject.isEnabled();\n            profileProject.setEnabled(project != null);\n            if (project == null) attachProject.setSelected(true);\n            else if (fromExternal) profileProject.setSelected(true);\n        }\n        \n        private void refreshFeatures(final Lookup context, final Lookup.Provider project) {\n            contents.removeAll();\n            \n            final JLabel l = new JLabel(Bundle.ProfilerSessions_loadingFeatures(), JLabel.CENTER);\n            GridBagConstraints c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 0;\n            c.weightx = 1;\n            c.weighty = 1;\n            c.fill = GridBagConstraints.BOTH;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.insets = new Insets(0, 20, 0, 10);\n            contents.add(l, c);\n            \n            repaintContents();\n            \n            RequestProcessor.getDefault().post(new Runnable() {\n                public void run() {\n                    \n                    if (selectedSession != null) selectedSession.close();\n                    \n                    Lookup projectContext = project == null ? Lookup.EMPTY :\n                                            Lookups.fixed(project);\n                    selectedSession = ProfilerSession.forContext(projectContext);\n                    final ProfilerFeatures features = selectedSession == null ? null :\n                                                      selectedSession.getFeatures();\n                    \n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            \n                            if (features == null || features.getAvailable().isEmpty()) {\n                                l.setText(Bundle.ProfilerSessions_noFeature());\n                            } else {                            \n                                contents.removeAll();\n                                selectModeLabel.setLabelFor(null);\n\n                                int y = 0;\n                                GridBagConstraints c;\n\n                                ButtonGroup rbg = new ButtonGroup();\n                                for (final ProfilerFeature f : features.getAvailable()) {\n                                    if (f.supportsConfiguration(context)) {\n                                        JRadioButton rb = new JExtendedRadioButton(f.getName(), f.getIcon()) {\n                                            protected void fireItemStateChanged(ItemEvent e) {\n                                                if (e.getStateChange() == ItemEvent.SELECTED)\n                                                    selectedFeature = f;\n                                            }\n                                        };\n                                        rbg.add(rb);\n                                        if (rbg.getSelection() == null) rb.setSelected(true);\n                                        c = new GridBagConstraints();\n                                        c.gridx = 0;\n                                        c.gridy = y++;\n                                        c.anchor = GridBagConstraints.WEST;\n                                        c.insets = new Insets(0, 20, 0, 10);\n                                        contents.add(rb, c);\n                                        if (selectModeLabel.getLabelFor() == null) selectModeLabel.setLabelFor(rb);\n                                    }\n                                }\n\n                                repaintContents();\n                            }\n                        }\n                    });\n                    \n                }\n            });\n        }\n        \n    }\n    \n    \n    // --- Wait for profiler ---------------------------------------------------\n    \n    private static final int MIN_WAIT_WIDTH = 350;\n    private static final int ENABLE_CANCEL_MS = 5000;\n    private static volatile boolean waitingCancelled;\n    \n    \n    static boolean waitForProfiler() {\n        final Profiler profiler = Profiler.getDefault();\n        if (profiler.getProfilingState() == Profiler.PROFILING_INACTIVE) return true;\n        \n        if (SwingUtilities.isEventDispatchThread()) {\n            waitingCancelled = blockingWaitDialog(profiler, null);\n        } else {\n            final Object lock = new Object();\n            synchronized(lock) { \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { waitingCancelled = blockingWaitDialog(profiler, lock); }\n                });\n                try { lock.wait(); }\n                catch (InterruptedException ex) {}\n            }\n        }\n        \n        return !waitingCancelled;\n    }\n    \n    private static boolean blockingWaitDialog(Profiler profiler, Object lock) {\n        try {\n            if (profiler.getProfilingState() == Profiler.PROFILING_INACTIVE) return false;\n            \n            JPanel panel = new JPanel(new BorderLayout(5, 5));\n            panel.setBorder(new EmptyBorder(15, 15, 15, 10));\n            panel.add(new JLabel(Bundle.ProfilerSessions_finishingSession()), BorderLayout.NORTH);\n\n            JProgressBar progress = new JProgressBar();\n            progress.setIndeterminate(true);\n            panel.add(progress, BorderLayout.SOUTH);\n            \n            Dimension ps = panel.getPreferredSize();\n            panel.setPreferredSize(new Dimension(Math.max(ps.width, MIN_WAIT_WIDTH), ps.height));\n            \n            final JButton cancel = new JButton(Bundle.ProfilerSessions_cancel());\n            cancel.setVisible(false);\n\n            DialogDescriptor dd = new DialogDescriptor(panel, Bundle.ProfilerSessions_finishSessionCaption(),\n                                      true, new Object[] { cancel }, null,\n                                      DialogDescriptor.DEFAULT_ALIGN, null, null);\n            final Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n            final JDialog jd = d instanceof JDialog ? (JDialog)d : null;\n\n            final ProfilingStateListener listener = new ProfilingStateAdapter() {\n                public void profilingStateChanged(ProfilingStateEvent e) {\n                    if (e.getNewState() == Profiler.PROFILING_INACTIVE) { d.setVisible(false); }\n                }\n            };\n            profiler.addProfilingStateListener(listener);\n            \n            int closeOp = -1;\n            if (jd != null) {\n                closeOp = jd.getDefaultCloseOperation();\n                jd.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);\n            }\n            \n            final int _closeOp = closeOp;\n            Timer timer = new Timer(ENABLE_CANCEL_MS, new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    if (jd != null) jd.setDefaultCloseOperation(_closeOp);\n                    cancel.addActionListener(new ActionListener() {\n                        public void actionPerformed(ActionEvent e) { d.setVisible(false); }\n                    });\n                    cancel.setVisible(true);\n                    d.pack();\n                }\n            });\n            timer.setRepeats(false);\n            timer.start();\n            \n            d.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());\n            d.setVisible(true);\n            \n            profiler.removeProfilingStateListener(listener);\n            \n            return dd.getValue() != null;\n        } finally {\n            if (lock != null) synchronized(lock) { lock.notifyAll(); }\n        }\n    }\n    \n    \n    // --- Stop action ---------------------------------------------------------\n    \n    @NbBundle.Messages({\n        \"LBL_StopAction=Fini&sh Profiler Session\",\n        \"HINT_StopAction=Finish profiler session (terminate profiled application)\",\n        \"HINT_DetachAction=Finish profiler session (detach from profiled application)\"\n    })\n    public static final class StopAction extends AbstractAction {\n        \n        // --- Singleton -------------------------------------------------------\n        \n        private static final class Singleton {\n            final private static StopAction INSTANCE = new StopAction();\n        }\n        @ActionID(category=\"Profile\", id=\"org.graalvm.visualvm.lib.profiler.v2.ProfilerSessions.StopAction\") // NOI18N\n        @ActionRegistration(displayName=\"#LBL_StopAction\", lazy=false) // NOI18N\n        @ActionReferences({\n            @ActionReference(path=\"Menu/Profile\", position=300, separatorAfter=400), // NOI18N\n            @ActionReference(path=\"Shortcuts\", name=\"S-F2\") // NOI18N\n        })\n        public static StopAction getInstance() { return Singleton.INSTANCE; }\n        \n        \n        // --- Implementation --------------------------------------------------\n        \n        private ProfilerSession session;\n        \n        private final ProfilingStateListener listener = new SimpleProfilingStateAdapter() {\n            protected void update() { updateState(); }\n        };\n        \n        public void actionPerformed(ActionEvent e) {\n            if (session != null) {\n                setEnabled(false);\n                final ProfilerSession sessionF = session;\n        \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { if (!sessionF.doStop()) setEnabled(true); }\n                });\n            }\n        }\n        \n        \n        void setSession(final ProfilerSession _session) {\n            if (session != null) session.removeListener(listener);\n            session = _session;\n            if (session != null) session.addListener(listener);\n\n            putValue(SHORT_DESCRIPTION, session != null && session.isAttach() ?\n                     Bundle.HINT_DetachAction() : Bundle.HINT_StopAction());\n            updateState();\n        }\n        \n        private void updateState() {\n            setEnabled(session != null && session.getState() == Profiler.PROFILING_RUNNING);\n        }\n\n        private StopAction() {\n            putValue(NAME, Bundle.LBL_StopAction());\n            putValue(SHORT_DESCRIPTION, Bundle.HINT_StopAction());\n            putValue(SMALL_ICON, Icons.getIcon(GeneralIcons.STOP));\n            putValue(\"iconBase\", Icons.getResource(GeneralIcons.STOP)); // NOI18N\n            \n            updateState();\n        }\n        \n    }\n    \n    \n    // --- Persist session -----------------------------------------------------\n    \n    @OnStop\n    public static final class ExitHandler implements Runnable {\n        \n        public void run() {\n            ProfilerSession current = ProfilerSession.currentSession();\n            if (current != null) current.persistStorage(true);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/ProfilerWindow.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ComponentEvent;\nimport java.awt.event.ComponentListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.ItemEvent;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Properties;\nimport java.util.Set;\nimport javax.accessibility.AccessibleContext;\nimport javax.accessibility.AccessibleRole;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.BorderFactory;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.common.AttachSettings;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.common.event.SimpleProfilingStateAdapter;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerPopup;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.StayOpenPopupMenu;\nimport org.graalvm.visualvm.lib.profiler.ProfilerTopComponent;\nimport org.graalvm.visualvm.lib.profiler.actions.HeapDumpAction;\nimport org.graalvm.visualvm.lib.profiler.actions.RunGCAction;\nimport org.graalvm.visualvm.lib.profiler.actions.TakeThreadDumpAction;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerStorage;\nimport org.graalvm.visualvm.lib.profiler.api.ProjectUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.attach.AttachWizard;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.FeaturesView;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.ProfilerStatus;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.WelcomePanel;\nimport org.graalvm.visualvm.lib.profiler.v2.ui.DropdownButton;\nimport org.graalvm.visualvm.lib.profiler.v2.ui.ToggleButtonMenuItem;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Exceptions;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.windows.Mode;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ProfilerWindow_captionProject={0}\",\n    \"ProfilerWindow_captionFile={0} | {1}\",\n    \"ProfilerWindow_captionExternal=Profile External Process\",\n    \"ProfilerWindow_configure=Configure Session\",\n    \"ProfilerWindow_profile=Profile\",\n    \"ProfilerWindow_attach=Attach\",\n    \"ProfilerWindow_profileTooltip=Start profiling session\",\n    \"ProfilerWindow_profileRunningTooltip=Start profiling session (already running)\",\n    \"ProfilerWindow_configureTooltip=Configure profiling session\",\n    \"ProfilerWindow_terminateCaption=Terminate Profiling Session\",\n    \"ProfilerWindow_terminateMsg=Terminate profiling session?\",\n    \"ProfilerWindow_loadingSession=Creating session...\",\n    \"ProfilerWindow_settings=Settings\",\n    \"ProfilerWindow_application=Process:\",\n    \"ProfilerWindow_threadDump=Thread Dump\",\n    \"ProfilerWindow_heapDump=Heap Dump\",\n    \"ProfilerWindow_gc=GC\",\n    \"ProfilerWindow_setupAttachProject=Setup Attach to Project...\",\n    \"ProfilerWindow_setupAttachProcess=Setup Attach to Process...\",\n    \"ProfilerWindow_multipleFeatures=Enable Multiple Modes\",\n    \"ProfilerWindow_usePPoints=Use Defined Profiling Points\",\n    \"ProfilerWindow_targetSection=Target:\",\n    \"ProfilerWindow_profileSection=Profile:\",\n    \"ProfilerWindow_settingsSection=Settings:\",\n    \"ProfilerWindow_pluginsSection=Plugins:\",\n    \"#NOI18N\",\n    \"ProfilerWindow_mode=editor\",\n    \"ProfilerWindow_noFeature=<html><b>No profiling feature selected.</b><br><br>Please select at least one profiling feature for the session.</html>\",\n    \"ProfilerWindow_accessName=Profiler Window for {0}\"\n})\nclass ProfilerWindow extends ProfilerTopComponent {    \n    \n    // --- Constructor ---------------------------------------------------------\n    \n    private final ProfilerSession session;\n    \n    ProfilerWindow(ProfilerSession session) {\n        this.session = session;\n        \n        updateWindowName();\n        updateWindowIcon();\n        \n        createUI();\n    }\n    \n    // --- API -----------------------------------------------------------------\n    \n    void updateSession() {\n        updateWindowName();\n        \n        if (start != null) start.setText(session.isAttach() ? Bundle.ProfilerWindow_attach() :\n                                                              Bundle.ProfilerWindow_profile());\n    }\n    \n    void selectFeature(ProfilerFeature feature) {\n        if (featuresView != null) featuresView.selectFeature(feature);\n    }\n    \n    // --- Implementation ------------------------------------------------------\n    \n    private ProfilerFeatures features;\n    private ProfilerPlugins plugins;\n    \n    private ProfilerToolbar toolbar;\n    private ProfilerToolbar featureToolbar;\n    private ProfilerToolbar applicationToolbar;\n//    private ProfilerToolbar statusBar;\n    private JPanel container;\n    private FeaturesView featuresView;\n    \n    private PopupButton configure;\n    private DropdownButton start;\n    private JButton stop;\n    private SettingsPresenter settingsButton;\n    \n    private AttachSettings attachSettings;\n    \n    private ProfilerStatus status;\n//    private String preselectItem;\n    \n    \n    private void createUI() {\n        setLayout(new BorderLayout(0, 0));\n        setFocusable(false);\n        \n        toolbar = ProfilerToolbar.create(true);\n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        \n        final JLabel loading = new JLabel(Bundle.ProfilerWindow_loadingSession());\n        loading.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));\n        toolbar.add(loading);\n        \n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() {\n                loadSessionSettings();\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        toolbar.remove(loading);\n                        popupulateUI();\n                    }\n                });\n            }\n        });\n    }\n    \n    private void loadSessionSettings() {\n        features = session.getFeatures();\n        plugins = session.getPlugins();\n        \n        Properties p = new Properties();\n        try {\n            ProfilerStorage.loadProjectProperties(p, session.getProject(), \"attach\"); // NOI18N\n        } catch (IOException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n        if (!p.isEmpty()) {\n            attachSettings = new AttachSettings();\n            attachSettings.load(p);\n        }\n    }\n    \n    private void popupulateUI() {  \n        configure = new PopupButton(Bundle.ProfilerWindow_configure()) {\n            protected void displayPopup() { displayPopupImpl(); }\n        };\n        configure.setToolTipText(Bundle.ProfilerWindow_configureTooltip());\n        if (UIUtils.isAquaLookAndFeel())\n            configure.putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n        toolbar.add(configure);\n        \n        String command = session.isAttach() ? Bundle.ProfilerWindow_attach() :\n                                              Bundle.ProfilerWindow_profile();\n        start = new DropdownButton(command, Icons.getIcon(GeneralIcons.START), true) {\n            public void displayPopup() { displayPopupImpl(); }\n            protected void performAction() { performStartImpl(); }\n        };\n        start.setToolTipText(Bundle.ProfilerWindow_profileTooltip());\n        start.setPushedToolTipText(Bundle.ProfilerWindow_profileRunningTooltip());\n        start.setPopupToolTipText(Bundle.ProfilerWindow_configureTooltip());\n        toolbar.add(start);\n        \n        stop = new JButton(ProfilerSessions.StopAction.getInstance());\n        stop.setHideActionText(true);\n        toolbar.add(stop);\n        \n//        statusBar = new ProfilerStatus(session).getToolbar();\n//        statusBar.getComponent().setVisible(false); // TODO: read last state\n//        toolbar.add(statusBar);\n        \n        toolbar.addFiller();\n        \n        settingsButton = new SettingsPresenter();\n        toolbar.add(settingsButton);\n        \n        container = new JPanel(new BorderLayout(0, 0));\n        add(container, BorderLayout.CENTER);\n        \n        JPanel welcomePanel = new WelcomePanel(configure.getText(), start.getText(), features.getAvailable()) {\n            public void highlightItem(final String text) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { configure.doClick(85); }\n                });\n            }\n        };\n        \n        boolean showHint = ProfilerIDESettings.getInstance().getShowNoDataHint();\n        featuresView = new FeaturesView(welcomePanel, showHint ? command : null);\n        container.add(featuresView, BorderLayout.CENTER);\n        \n        features.addListener(new ProfilerFeatures.Listener() {\n            void featuresChanged(ProfilerFeature changed) { updateFeatures(changed); }\n            void settingsChanged(boolean valid) { updateSettings(valid); }\n        });\n        updateFeatures(null);\n        updateSettings(features.settingsValid());\n        \n        featuresView.addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                updateFeatureToolbar();\n            }\n        });\n        updateFeatureToolbar();\n        \n        session.addListener(new SimpleProfilingStateAdapter() {\n            public void update() {\n                updateWindowIcon();\n                updateButtons();\n            }\n        });\n        updateButtons();\n        \n        registerActions();\n        \n        status = ProfilerStatus.forSession(session);\n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (isShowing()) status.startSessionLogging();\n                    else status.stopSessionLogging();\n                }\n            }\n        });\n        if (isShowing()) status.startSessionLogging();\n    }\n    \n    private void registerActions() {\n        InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        ActionMap actionMap = getActionMap();\n        \n        final String filterKey = FilterUtils.FILTER_ACTION_KEY;\n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                ProfilerFeature feature = featuresView.getSelectedFeature();\n                JPanel resultsUI = feature == null ? null : feature.getResultsUI();\n                if (resultsUI == null) return;\n                \n                Action action = resultsUI.getActionMap().get(filterKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);\n        \n        final String findKey = SearchUtils.FIND_ACTION_KEY;\n        Action findAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                ProfilerFeature feature = featuresView.getSelectedFeature();\n                JPanel resultsUI = feature == null ? null : feature.getResultsUI();\n                if (resultsUI == null) return;\n                \n                Action action = resultsUI.getActionMap().get(findKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(findKey, findAction, actionMap, inputMap);\n    }\n    \n    \n    private void updateWindowName() {\n       Lookup.Provider project = session.getProject();\n        if (project == null) {\n            setDisplayName(Bundle.ProfilerWindow_captionExternal());\n        } else {\n            String projectN = ProjectUtilities.getDisplayName(project);\n            FileObject file = session.getFile();\n            setDisplayName(file == null ? Bundle.ProfilerWindow_captionProject(projectN) :\n                                          Bundle.ProfilerWindow_captionFile(projectN, file.getNameExt()));\n        } \n    }\n    \n    private void updateWindowIcon() {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() {\n                if (session.inProgress()) setIcon(Icons.getImage(ProfilerIcons.PROFILE_RUNNING));\n                else setIcon(Icons.getImage(ProfilerIcons.PROFILE_INACTIVE));\n            }\n        });\n    }\n    \n    private void updateButtons() {\n        int state = session.getState();\n        start.setPushed(state != Profiler.PROFILING_INACTIVE);\n        start.setPopupEnabled(state != Profiler.PROFILING_IN_TRANSITION);\n    }\n    \n    \n    private void updateFeatures(ProfilerFeature changed) {\n        // TODO: optimize!\n        // TODO: restore focused component if possible\n        ProfilerFeature restore = featuresView.getSelectedFeature();\n        featuresView.removeFeatures();\n        Set<ProfilerFeature> selected = features.getActivated();\n        for (ProfilerFeature feature : selected) featuresView.addFeature(feature);\n        if (changed != null && selected.contains(changed)) featuresView.selectFeature(changed);\n        else featuresView.selectFeature(restore);\n        featuresView.repaint();\n    }\n    \n    private void updateSettings(boolean valid) {\n        start.setEnabled(valid);\n        \n        boolean _configure = features.getActivated().isEmpty();\n        start.setVisible(!_configure);\n        stop.setVisible(!_configure);\n        configure.setVisible(_configure);\n        \n        new Timer(0, null) {\n            {\n                setRepeats(false);\n                setInitialDelay(50);\n            }\n            protected void fireActionPerformed(ActionEvent e) {\n                updateFocus();\n            }\n        }.start();\n        \n        if (session.inProgress()) session.doModify(features.getSettings());\n    }\n    \n    private void updateFocus() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                Component focused = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();\n\n                // Do not change focus for these special cases:\n                if (focused != null) {\n                    if (profilePopupVisible) return; // focus in the Profile popup\n                    if (ProfilerPopup.isInPopup(focused)) return; // focus in a profiler popup\n                    if (ProfilerWindow.this.isAncestorOf(focused)) return; // focus inside the ProfilerWindow\n                }\n\n                final Component foc = configure.isVisible() ? configure : start;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { foc.requestFocusInWindow(); }\n                });\n            }\n        });\n    }\n    \n    private void updateFeatureToolbar() {\n        if (featureToolbar != null) toolbar.remove(featureToolbar);\n        if (applicationToolbar != null) toolbar.remove(applicationToolbar);\n        \n        ProfilerFeature selected = featuresView.getSelectedFeature();\n        featureToolbar = selected == null ? null : selected.getToolbar();\n        if (featureToolbar != null) toolbar.add(featureToolbar, toolbar.getComponentCount() - 2); // add before filler & settingsButton\n        settingsButton.setFeature(selected);\n        \n        if (selected != null) toolbar.add(getApplicationToolbar(), toolbar.getComponentCount() - 2); // add before filler & settingsButton\n        else applicationToolbar = null;\n        \n        doLayout();\n        repaint();\n    }\n    \n    private ProfilerToolbar getApplicationToolbar() {\n        if (applicationToolbar == null) {\n            applicationToolbar = ProfilerToolbar.create(true);\n\n            applicationToolbar.addSpace(2);\n            applicationToolbar.addSeparator();\n            applicationToolbar.addSpace(5);\n\n            JLabel apLabel = new GrayLabel(Bundle.ProfilerWindow_application());\n            applicationToolbar.add(apLabel);\n            \n            applicationToolbar.addSpace(2);\n            \n            JButton apThreadDumpButton = new JButton(TakeThreadDumpAction.getInstance());\n            apThreadDumpButton.setHideActionText(true);\n//            apThreadDumpButton.setText(Bundle.ProfilerWindow_threadDump());\n            applicationToolbar.add(apThreadDumpButton);\n            \n            applicationToolbar.addSpace(3);\n            \n            JButton apHeapDumpButton = new JButton(HeapDumpAction.getInstance());\n            apHeapDumpButton.setHideActionText(true);\n//            apHeapDumpButton.setText(Bundle.ProfilerWindow_heapDump());\n            applicationToolbar.add(apHeapDumpButton);\n            \n            applicationToolbar.addSpace(3);\n            \n            JButton apGCButton = new JButton(RunGCAction.getInstance());\n            apGCButton.setHideActionText(true);\n//            apGCButton.setText(Bundle.ProfilerWindow_gc());\n            applicationToolbar.add(apGCButton);\n        }\n        return applicationToolbar;\n    }\n    \n    private boolean configureAttachSettings(boolean partially) {\n        AttachSettings settings = AttachWizard.getDefault().configure(attachSettings, partially);\n        if (settings == null) return false; // cancelled by the user\n        \n        attachSettings = settings;\n        final AttachSettings as = new AttachSettings();\n        attachSettings.copyInto(as);\n        final Lookup.Provider lp = session.getProject();\n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() {\n                Properties p = new Properties();\n                as.store(p);\n                try {\n                    ProfilerStorage.saveProjectProperties(p, lp, \"attach\"); // NOI18N\n                } catch (IOException ex) {\n                    Exceptions.printStackTrace(ex);\n                }\n            }\n        });\n            \n        return true;\n    }\n    \n    private void performStartImpl() {\n        featuresView.resetNoDataHint();\n        \n        start.setPushed(true);\n        \n        final ProfilingSettings _profilingSettings = features.getSettings();\n        if (_profilingSettings == null) { // #250237 ?\n            ProfilerDialogs.displayError(Bundle.ProfilerWindow_noFeature());\n            start.setPushed(false);\n            return;\n        }\n        \n        if (session.isAttach()) {\n            RequestProcessor.getDefault().post(new Runnable() {\n                public void run() {\n                    if (AttachWizard.getDefault().configured(attachSettings)) {\n                        performDoStartImpl(_profilingSettings, attachSettings);\n                    } else {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                if (!configureAttachSettings(false)) start.setPushed(false);\n                                else performDoStartImpl(_profilingSettings, attachSettings);\n                            }\n                        });\n                    }\n                }\n            });\n        } else {\n            performDoStartImpl(_profilingSettings, null);\n        }\n    }\n    \n    private void performDoStartImpl(final ProfilingSettings ps, final AttachSettings as) {\n        UIUtils.runInEventDispatchThread(new Runnable() {\n            public void run() { if (!session.doStart(ps, as)) start.setPushed(false); }\n        });\n    }\n    \n    \n    // --- Profile/Attach popup ------------------------------------------------\n    \n    private boolean profilePopupVisible;\n    \n    private void displayPopupImpl() {\n        final Set<ProfilerFeature> _features = features.getAvailable();\n        final Set<ProfilerFeature> _selected = features.getActivated();\n        final List<ToggleButtonMenuItem> _items = new ArrayList();\n        \n        // --- Features listener ---\n        final ProfilerFeatures.Listener listener = new ProfilerFeatures.Listener() {\n            void featuresChanged(ProfilerFeature changed) {\n                int index = 0;\n                for (ProfilerFeature feature : _features) {\n                    ToggleButtonMenuItem item = _items.get(index++);\n                    if (item == null) item = _items.get(index++);\n                    item.setPressed(_selected.contains(feature));\n                }\n            }\n            void settingsChanged(boolean valid) {}\n        };\n        \n        // --- Popup menu ---\n        final StayOpenPopupMenu popup = new StayOpenPopupMenu() {\n            public void setVisible(boolean visible) {\n                if (visible) features.addListener(listener);\n                else features.removeListener(listener);\n                super.setVisible(visible);\n                profilePopupVisible = visible;\n                if (!visible) updateFocus();\n            }\n        };\n        popup.setLayout(new GridBagLayout());\n        if (!UIUtils.isAquaLookAndFeel()) {\n            popup.setForceBackground(true);\n            Color background = UIUtils.getProfilerResultsBackground();\n            popup.setBackground(new Color(background.getRGB())); // JPopupMenu doesn't seem to follow ColorUIResource\n        }\n        \n        // --- Feature items ---\n        int lastPosition = -1;\n        for (final ProfilerFeature feature : _features) {\n            int currentPosition = feature.getPosition();\n            if (lastPosition == -1) lastPosition = currentPosition;\n            if (currentPosition - lastPosition > 1) _items.add(null);\n            lastPosition = currentPosition;\n            \n            _items.add(new ToggleButtonMenuItem(feature.getName(), feature.getIcon()) {\n                {\n                    setPressed(_selected.contains(feature));\n                }\n                protected void fireActionPerformed(ActionEvent e) {\n                    features.toggleActivated(feature);\n                    if (features.isSingleFeatured() && isPressed())\n                        /*if (session.inProgress())*/ popup.setVisible(false);\n                }\n            });\n        }\n        \n        // --- Other controls ---\n        final boolean _project = session.getProject() != null;\n//        final boolean _file = session.getFile() != null;\n        final boolean _attach = session.isAttach();\n//        \n        JMenuItem attachProject = null;\n        if (_attach) {\n            String nameA = _project ? Bundle.ProfilerWindow_setupAttachProject() :\n                                      Bundle.ProfilerWindow_setupAttachProcess();\n            attachProject = new JMenuItem(nameA) {\n                {\n                    setEnabled(!session.inProgress());\n                }\n                protected void fireActionPerformed(ActionEvent event) {\n                    configureAttachSettings(true);\n                }\n            };\n        }\n        \n        JCheckBoxMenuItem singleFeature = new StayOpenPopupMenu.CheckBoxItem(Bundle.ProfilerWindow_multipleFeatures()) {\n            { setSelected(!features.isSingleFeatured()); }\n            protected void fireItemStateChanged(ItemEvent event) {\n                features.setSingleFeatured(!isSelected());\n            }\n        };\n        \n        JCheckBoxMenuItem usePPoints = new StayOpenPopupMenu.CheckBoxItem(Bundle.ProfilerWindow_usePPoints()) {\n            {\n                setSelected(features.getUseProfilingPoints());\n                setEnabled(!session.inProgress());\n            }\n            protected void fireItemStateChanged(ItemEvent event) {\n                features.setUseProfilingPoints(isSelected());\n            }\n        };\n        \n        // --- Popup crowding ---\n        int left = 12;\n        int labl = 5;\n        int y = 0;\n        GridBagConstraints c;\n        \n        if (_attach) {\n            JLabel projectL = new JLabel(Bundle.ProfilerWindow_targetSection(), JLabel.LEADING);\n            projectL.setFont(popup.getFont().deriveFont(Font.BOLD));\n            c = new GridBagConstraints();\n            c.gridy = y++;\n            c.insets = new Insets(5, labl, 5, 5);\n            c.fill = GridBagConstraints.HORIZONTAL;\n            popup.add(projectL, c);\n\n            c = new GridBagConstraints();\n            c.gridy = y++;\n            c.gridx = 0;\n            c.insets = new Insets(0, left, 0, 5);\n            c.gridwidth = 1;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            popup.add(attachProject, c);\n        }\n                \n        JLabel profileL = new JLabel(Bundle.ProfilerWindow_profileSection(), JLabel.LEADING);\n        profileL.setFont(popup.getFont().deriveFont(Font.BOLD));\n        c = new GridBagConstraints();\n        c.gridy = y++;\n        c.insets = new Insets(_attach ? 8 : 5, labl, 5, 5);\n        c.fill = GridBagConstraints.HORIZONTAL;\n        popup.add(profileL, c);\n        \n        for (ToggleButtonMenuItem item : _items) {\n            if (item == null) {\n                JPanel p = new JPanel(null);\n                p.setOpaque(false);\n                c = new GridBagConstraints();\n                c.gridy = y++;\n                c.insets = new Insets(5, 0, 5, 0);\n                c.fill = GridBagConstraints.HORIZONTAL;\n                popup.add(p, c);\n            } else {\n                c = new GridBagConstraints();\n                c.gridy = y++;\n                c.insets = new Insets(0, left, 0, 5);\n                c.fill = GridBagConstraints.HORIZONTAL;\n                popup.add(item, c);\n            }\n        }\n\n        JLabel settingsL = new JLabel(Bundle.ProfilerWindow_settingsSection(), JLabel.LEADING);\n        settingsL.setFont(popup.getFont().deriveFont(Font.BOLD));\n        c = new GridBagConstraints();\n        c.gridy = y++;\n        c.insets = new Insets(8, labl, 5, 5);\n        c.fill = GridBagConstraints.HORIZONTAL;\n        popup.add(settingsL, c);\n\n        c = new GridBagConstraints();\n        c.gridy = y++;\n        c.insets = new Insets(0, left, 0, 5);\n        c.fill = GridBagConstraints.HORIZONTAL;\n        popup.add(singleFeature, c);\n\n        if (_project) {\n            c = new GridBagConstraints();\n            c.gridy = y++;\n            c.insets = new Insets(0, left, 0, 5);\n            c.fill = GridBagConstraints.HORIZONTAL;\n            popup.add(usePPoints, c);\n        }\n        \n        if (plugins.hasPlugins()) {\n            JLabel pluginsL = new JLabel(Bundle.ProfilerWindow_pluginsSection(), JLabel.LEADING);\n            pluginsL.setFont(popup.getFont().deriveFont(Font.BOLD));\n            c = new GridBagConstraints();\n            c.gridy = y++;\n            c.insets = new Insets(8, labl, 5, 5);\n            c.fill = GridBagConstraints.HORIZONTAL;\n            popup.add(pluginsL, c);\n            \n            for (JMenuItem menu : plugins.menuItems()) {\n                c = new GridBagConstraints();\n                c.gridy = y++;\n                c.insets = new Insets(0, left, 0, 5);\n                c.fill = GridBagConstraints.HORIZONTAL;\n                popup.add(menu, c);\n            }\n        }\n\n        JPanel footer = new JPanel(null);\n        footer.setOpaque(false);\n        c = new GridBagConstraints();\n        c.gridy = y++;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.insets = new Insets(3, 0, 0, 0);\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        popup.add(footer, c);\n        \n//        MenuElement preselect = null;\n//        if (preselectItem != null) {\n//            for (Component comp : popup.getComponents()) {\n//                if (comp instanceof JMenuItem) {\n//                    JMenuItem mi = (JMenuItem)comp;\n//                    if (mi.getText().contains(preselectItem)) {\n//                        preselect = mi;\n//                        break;\n//                    }\n//                }\n//            }\n//            preselectItem = null;\n//        }\n//        \n//        if (preselect instanceof JRadioButtonMenuItem)\n//            ((JRadioButtonMenuItem)preselect).setSelected(true);\n        \n        JComponent button = start.isVisible() ? start : configure;\n        popup.show(button, 0, button.getHeight());\n        \n//        if (preselect != null) MenuSelectionManager.defaultManager().setSelectedPath(\n//                               new MenuElement[] { popup, preselect });\n    }\n    \n    \n    // --- ProfilerTopComponent ------------------------------------------------\n    \n    protected Component defaultFocusOwner() {\n        if (configure != null && configure.isVisible()) return configure;\n        else if (start != null) return start;\n        else return null;\n    }\n    \n    \n    // --- TopComponent --------------------------------------------------------\n    \n    private final String ID = \"ProfilerWindow\"; // NOI18N\n    \n    boolean closing = false;\n    \n    public boolean canClose() {\n        if (closing) return true;\n        if (!super.canClose()) return false;\n        closing = true;\n        closing = session.close();\n        return closing;\n    }\n    \n    public void open() {\n        WindowManager windowManager = WindowManager.getDefault();\n        if (windowManager.findMode(this) == null) { // needs docking\n            Mode mode = windowManager.findMode(Bundle.ProfilerWindow_mode());\n            if (mode != null) mode.dockInto(this);\n        }\n        super.open();\n    }\n    \n    protected void componentOpened() {\n        super.componentOpened();\n        SnapshotsWindow.instance().sessionOpened(session);\n    }\n    \n    protected void componentShowing() {\n        super.componentShowing();\n        SnapshotsWindow.instance().sessionActivated(session);\n    }\n    \n    protected void componentHidden() {\n        super.componentHidden();\n        SnapshotsWindow.instance().sessionDeactivated(session);\n    }\n    \n    protected void componentClosed() {\n        super.componentOpened();\n        SnapshotsWindow.instance().sessionClosed(session);\n    }\n    \n    protected void componentActivated() {\n        super.componentActivated();\n        if (status != null) status.startSessionLogging();\n    }\n    \n    public int getPersistenceType() {\n        return PERSISTENCE_NEVER;\n    }\n    \n    protected String preferredID() {\n        return ID;\n    }\n    \n    public HelpCtx getHelpCtx() {\n        ProfilerFeature selected = featuresView == null ? null :\n                                   featuresView.getSelectedFeature();\n        \n        JPanel selectedUI = selected == null ? null : selected.getResultsUI();\n        if (selectedUI == null && selected != null) selectedUI = selected.getSettingsUI();\n        \n        String helpCtx = selectedUI == null ? null :\n                         (String)selectedUI.getClientProperty(\"HelpCtx.Key\"); // NOI18N\n        if (helpCtx == null) helpCtx = \"ProfileWindow.HelpCtx\"; // NOI18N\n        \n        return new HelpCtx(helpCtx);\n    }\n    \n    \n    // --- Accessibility -------------------------------------------------------\n    \n    private AccessibleContext accessibleContext;\n    \n    public AccessibleContext getAccessibleContext() {\n        if (accessibleContext == null) {\n            accessibleContext = new JComponent.AccessibleJComponent() {\n                public AccessibleRole getAccessibleRole() {\n                    return AccessibleRole.PANEL;\n                }\n\n                public String getAccessibleName() {\n                    return Bundle.ProfilerWindow_accessName(getDisplayName());\n                }\n\n                public String getAccessibleDescription() {\n                    ProfilerFeature selected = featuresView == null ? null :\n                                    featuresView.getSelectedFeature();\n                    return selected == null ? WelcomePanel.CAPTION :\n                           (selected.getName() + \" \" + selected.getDescription()); // NOI18N\n                }\n            };\n        }\n        return accessibleContext;\n    }\n    \n    \n    // --- Private classes -----------------------------------------------------\n    \n    private static final class SettingsPresenter extends JToggleButton\n                                                 implements ComponentListener {\n        \n        private JPanel settings;\n        \n        SettingsPresenter() {\n            super(Icons.getIcon(GeneralIcons.SETTINGS));\n            setToolTipText(Bundle.ProfilerWindow_settings());\n            updateVisibility(false);\n        }\n        \n        void setFeature(ProfilerFeature feature) {\n            if (settings != null) settings.removeComponentListener(this);\n            settings = feature == null ? null : feature.getSettingsUI();\n            updateVisibility(false);\n            if (settings != null) settings.addComponentListener(this);\n        }\n        \n        protected void fireActionPerformed(ActionEvent e) {\n            if (settings != null) {\n                settings.setVisible(isSelected());\n                settings.getParent().setVisible(isSelected());\n            }\n        }\n        \n        void cleanup() {\n            settings.removeComponentListener(this);\n        }\n        \n        private void updateVisibility(boolean parent) {\n            setVisible(settings != null);\n            setSelected(settings != null && settings.isVisible());\n            if (parent) settings.getParent().setVisible(settings.isVisible());\n        }\n        \n        public void componentShown(ComponentEvent e) { updateVisibility(true); }\n\n        public void componentHidden(ComponentEvent e) { updateVisibility(true); }\n        \n        public void componentResized(ComponentEvent e) {}\n        \n        public void componentMoved(ComponentEvent e) {}\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/SessionStorage.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2;\n\nimport java.util.Properties;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerStorage;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.WeakProcessor;\nimport org.openide.ErrorManager;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class SessionStorage {\n\n    private static final String SETTINGS_FILENAME = \"settings\"; // NOI18N\n\n    private static final WeakProcessor PROCESSOR = new WeakProcessor(\"Profiler Storage Processor\"); // NOI18N\n\n    private boolean dirty;\n    private Properties properties;\n    private final Lookup.Provider project;\n\n\n    SessionStorage(Lookup.Provider project) {\n        this.project = project;\n    }\n\n\n    public synchronized void storeFlag(String flag, String value) {\n        if (properties == null) loadProperties();\n\n        boolean _dirty;\n        if (value != null) _dirty = !value.equals(properties.put(flag, value));\n        else _dirty = properties.remove(flag) != null;\n\n        dirty |= _dirty;\n    }\n\n    public synchronized String readFlag(String flag, String defaultValue) {\n        if (properties == null) loadProperties();\n\n        return properties.getProperty(flag, defaultValue);\n    }\n\n\n    synchronized void persist(boolean immediately) {\n        if (dirty) {\n            if (immediately) {\n                synchronized(PROCESSOR) { saveProperties(properties); }\n            } else {\n                final Properties _properties = new Properties();\n                for (String key : properties.stringPropertyNames())\n                    _properties.setProperty(key, properties.getProperty(key));\n                PROCESSOR.post(new Runnable() {\n                    public void run() { synchronized(PROCESSOR) { saveProperties(_properties); } }\n                });\n            }\n            dirty = false;\n        }\n    }\n    \n    \n    private void loadProperties() {\n        properties = new Properties();\n\n        assert !SwingUtilities.isEventDispatchThread();\n        try {\n            ProfilerStorage.loadProjectProperties(properties, project, SETTINGS_FILENAME);\n        } catch (Exception e) {\n            ErrorManager.getDefault().log(ErrorManager.ERROR, e.getMessage());\n            e.printStackTrace();\n        }\n    }\n    \n    private void saveProperties(Properties _properties) {\n        assert !SwingUtilities.isEventDispatchThread();\n        try {\n            ProfilerStorage.saveProjectProperties(_properties, project, SETTINGS_FILENAME);\n        } catch (Exception e) {\n            ErrorManager.getDefault().log(ErrorManager.ERROR, e.getMessage());\n            e.printStackTrace();\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/SnapshotsWindow.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2;\n\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.Objects;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.SnapshotsListener;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.SnapshotsWindowHelper;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.SnapshotsWindowUI;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\nimport org.openide.windows.TopComponent;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n public final class SnapshotsWindow {\n\n    // --- Singleton -----------------------------------------------------------\n\n    private static SnapshotsWindow INSTANCE;\n\n    private final SnapshotsListener snapshotsListener;\n\n    public static synchronized SnapshotsWindow instance() {\n        if (INSTANCE == null) INSTANCE = new SnapshotsWindow();\n        return INSTANCE;\n    }\n\n    private SnapshotsWindow() {\n        snapshotsListener = Lookup.getDefault().lookup(SnapshotsWindowHelper.class);\n\n        TopComponent.getRegistry().addPropertyChangeListener(new PropertyChangeListener() {\n            public void propertyChange(PropertyChangeEvent evt) {\n                if (TopComponent.Registry.PROP_TC_CLOSED.equals(evt.getPropertyName()))\n                    if (ui != null && evt.getNewValue() == ui) ui = null;\n            }\n        });\n    }\n\n    // --- API -----------------------------------------------------------------\n\n    public void showStandalone() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                SnapshotsWindowUI ui = getUI(true);\n                ui.open();\n                ui.requestActive();\n            }\n        });\n    }\n    \n    public void sessionOpened(final ProfilerSession session) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                SnapshotsWindowUI ui = getUI(false);\n                if (ui == null && ProfilerIDESettings.getInstance().getSnapshotWindowOpenPolicy() == ProfilerIDESettings.SNAPSHOT_WINDOW_OPEN_PROFILER) {\n                    ui = getUI(true);\n                    ui.setProject(session.getProject());\n                    ui.open();\n                } else if (ui != null) ui.setProject(session.getProject());\n            }\n        });\n    }\n    \n    public void sessionActivated(final ProfilerSession session) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                SnapshotsWindowUI ui = getUI(false);\n                if (ui == null && ProfilerIDESettings.getInstance().getSnapshotWindowOpenPolicy() == ProfilerIDESettings.SNAPSHOT_WINDOW_SHOW_PROFILER) {\n                    ui = getUI(true);\n                    ui.setProject(session.getProject());\n                    ui.open();\n                } else if (ui != null) ui.setProject(session.getProject());\n            }\n        });\n    }\n    \n    public void sessionDeactivated(final ProfilerSession session) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                SnapshotsWindowUI ui = getUI(false);\n                if (ui != null) {\n                    if (ProfilerIDESettings.getInstance().getSnapshotWindowClosePolicy() == ProfilerIDESettings.SNAPSHOT_WINDOW_HIDE_PROFILER)\n                        ui.close();\n                    ui.resetProject(session.getProject());\n                }\n            }\n        });\n    }\n    \n    public void sessionClosed(final ProfilerSession session) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                SnapshotsWindowUI ui = getUI(false);\n                if (ui != null) {\n                    if (ProfilerIDESettings.getInstance().getSnapshotWindowClosePolicy() == ProfilerIDESettings.SNAPSHOT_WINDOW_CLOSE_PROFILER)\n                        ui.close();\n                    ui.resetProject(session.getProject());\n                }\n            }\n        });\n    }\n    \n    public void snapshotSaved(final LoadedSnapshot snapshot) {\n        assert !SwingUtilities.isEventDispatchThread();\n        \n        int policy = ProfilerIDESettings.getInstance().getSnapshotWindowOpenPolicy();\n        if ((policy == ProfilerIDESettings.SNAPSHOT_WINDOW_OPEN_FIRST &&\n             ResultsManager.getDefault().getSnapshotsCountFor(snapshot.getProject()) == 1) ||\n             policy == ProfilerIDESettings.SNAPSHOT_WINDOW_OPEN_EACH) {\n            final Lookup.Provider project = snapshot.getProject();\n            ProfilerSession session = ProfilerSession.currentSession();\n            if (session != null && Objects.equals(session.getProject(), project))\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        SnapshotsWindowUI ui = getUI(false);\n                        if (ui == null) {\n                            ui = getUI(true);\n                            ui.setProject(project);\n                            ui.open();\n                        }\n                    }\n                });\n        }\n    }\n    \n    public void refreshFolder(final FileObject folder, final boolean fullRefresh) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                SnapshotsWindowUI ui = getUI(false);\n                if (ui != null) ui.refreshFolder(folder, fullRefresh);\n            }\n        });\n    }\n    \n    \n    // --- UI ------------------------------------------------------------------\n    \n    private SnapshotsWindowUI ui;\n    \n    private SnapshotsWindowUI getUI(boolean create) {\n        if (ui == null) {\n            WindowManager wm = WindowManager.getDefault();\n            \n            for (TopComponent tc : TopComponent.getRegistry().getOpened())\n                if (tc.getClientProperty(SnapshotsWindowUI.ID) != null)\n                    ui = (SnapshotsWindowUI)tc;\n            \n            if (ui == null && create)\n                ui = (SnapshotsWindowUI)wm.findTopComponent(SnapshotsWindowUI.ID);\n            \n            if (ui == null && create)\n                ui = new SnapshotsWindowUI();\n        }\n        \n        return ui;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/FeatureMode.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport java.util.Collection;\nimport java.util.HashSet;\nimport javax.swing.JComponent;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class FeatureMode {\n\n    // --- API -----------------------------------------------------------------\n\n    abstract String getID();\n\n    abstract String getName();\n\n    abstract void configureSettings(ProfilingSettings settings);\n\n    abstract void confirmSettings();\n\n    abstract boolean pendingChanges();\n\n    abstract boolean currentSettingsValid();\n\n    abstract JComponent getUI();\n\n\n    // --- External implementation ---------------------------------------------\n\n    abstract void settingsChanged();\n\n    abstract String readFlag(String flag, String defaultValue);\n\n    abstract void storeFlag(String flag, String value);\n\n\n    // --- Roots Set -----------------------------------------------------------\n\n    // To be only accessed in EDT\n    static class Selection extends HashSet<ClientUtils.SourceCodeSelection> {\n\n        private boolean trans;\n        private boolean dirty;\n        private boolean events;\n        private boolean changing;\n\n        final void beginTrans() {\n            assert SwingUtilities.isEventDispatchThread();\n            trans = true;\n        }\n\n        final void endTrans() {\n            assert SwingUtilities.isEventDispatchThread();\n            trans = false;\n            if (dirty) _changed();\n        }\n\n        final void enableEvents() {\n            assert SwingUtilities.isEventDispatchThread();\n            events = true;\n        }\n\n        final void disableEvents() {\n            assert SwingUtilities.isEventDispatchThread();\n            events = false;\n        }\n        \n        public final boolean add(ClientUtils.SourceCodeSelection selection) {\n            assert SwingUtilities.isEventDispatchThread();\n            _changing();\n            if (super.add(selection)) return _changed();\n            else return false;\n        }\n        \n        public final boolean addAll(Collection<? extends ClientUtils.SourceCodeSelection> selections) {\n            boolean _trans = trans;\n            beginTrans();\n            \n            boolean addAll = super.addAll(selections);\n            \n            endTrans();\n            trans = _trans;\n            \n            return addAll;\n        }\n        \n        public final boolean remove(Object selection) {\n            assert SwingUtilities.isEventDispatchThread();\n            _changing();\n            if (super.remove(selection)) return _changed();\n            else return false;\n        }\n        \n        public final boolean removeAll(Collection<?> selections) {\n            boolean _trans = trans;\n            beginTrans();\n            \n            _changing();\n            boolean removeAll = super.removeAll(selections);\n            if (removeAll) _changed();\n            \n            endTrans();\n            trans = _trans;\n            \n            return removeAll;\n        }\n        \n        public final boolean retainAll(Collection<?> selections) {\n            boolean _trans = trans;\n            beginTrans();\n            \n            _changing();\n            boolean retainAll = super.retainAll(selections);\n            if (retainAll) _changed();\n            \n            endTrans();\n            trans = _trans;\n            \n            return retainAll;\n        }\n        \n        public final void clear() {\n            assert SwingUtilities.isEventDispatchThread();\n            _changing();\n            super.clear();\n            _changed();\n        }\n        \n        private void _changing() {\n            if (trans) {\n                if (!changing) changing = true;\n                else return;\n            }\n            if (events) changing();\n        }\n        \n        protected void changing() {}\n        \n        private boolean _changed() {\n            changing = false;\n            if (!trans) {\n                if (events) changed();\n                dirty = false;\n            } else {\n                dirty = true;\n            }\n            return true;\n        }\n        \n        protected void changed() {}\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/FeatureUI.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class FeatureUI {\n\n    // --- API -----------------------------------------------------------------\n\n    abstract ProfilerToolbar getToolbar();\n\n    abstract JPanel getResultsUI();\n\n    abstract void sessionStateChanged(int sessionState);\n\n\n    // --- External implementation ---------------------------------------------\n\n    abstract int getSessionState();\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/LocksFeature.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.profiler.api.ProjectUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerFeature;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.WeakProcessor;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"LocksFeature_name=Locks\",\n    \"LocksFeature_description=Collect lock contention statistics\",\n    \"LocksFeature_show=View by:\",\n    \"LocksFeature_aggregationByThreads=Threads\",\n    \"LocksFeature_aggregationByMonitors=Monitors\",\n    \"LocksFeature_application=Application:\",\n    \"LocksFeature_threadDump=Thread Dump\"\n})\nfinal class LocksFeature extends ProfilerFeature.Basic {\n\n    private final WeakProcessor processor;\n\n    private LocksFeature(ProfilerSession session) {\n        super(Icons.getIcon(ProfilerIcons.WINDOW_LOCKS), Bundle.LocksFeature_name(),\n              Bundle.LocksFeature_description(), 16, session);\n\n        assert !SwingUtilities.isEventDispatchThread();\n\n        Lookup.Provider project = session.getProject();\n        String projectName = project == null ? \"External Process\" : // NOI18N\n                             ProjectUtilities.getDisplayName(project);\n        processor = new WeakProcessor(\"MethodsFeature Processor for \" + projectName); // NOI18N\n    }\n    \n    \n    // --- Settings ------------------------------------------------------------\n    \n    public void configureSettings(ProfilingSettings settings) {\n        settings.setLockContentionMonitoringEnabled(true);\n    }\n    \n    \n    // --- Toolbar & Results UI ------------------------------------------------\n    \n    private LocksFeatureUI ui;\n    \n    public JPanel getResultsUI() {\n        return getUI().getResultsUI();\n    }\n    \n    public ProfilerToolbar getToolbar() {\n        return getUI().getToolbar();\n    }\n    \n    private LocksFeatureUI getUI() {\n        if (ui == null) ui = new LocksFeatureUI() {\n            int getSessionState() {\n                return LocksFeature.this.getSessionState();\n            }\n            ProfilerClient getProfilerClient() {\n                Profiler profiler = LocksFeature.this.getSession().getProfiler();\n                return profiler.getTargetAppRunner().getProfilerClient();\n            }\n            void refreshResults() {\n                LocksFeature.this.refreshResults();\n            }\n        };\n        return ui;\n    }\n\n    // --- Live results --------------------------------------------------------\n    \n    private Runnable refresher;\n    private volatile boolean running;\n    \n    \n    private void startResults() {\n        if (running) return;\n        running = true;\n        \n        refresher = new Runnable() {\n            public void run() {\n                if (running) {\n                    refreshView();\n                    refreshResults(1500);\n                }\n            }\n        };\n        \n        refreshResults(1000);\n    }\n\n    private void refreshView() {\n        if (ui != null /* && ResultsManager.getDefault().resultsAvailable()*/) {\n            try {\n                ProfilingSettings settings = getSession().getProfilingSettings();\n                if (ProfilingSettings.isCPUSettings(settings)\n                   || ProfilingSettings.isJDBCSettings(settings)\n                   || ProfilingSettings.isMemorySettings(settings)) {\n                    // CPU or memory profiling will do refresh for us,\n                    // it will call ProfilerClient.forceObtainedResultsDump()\n                    return;\n                }\n                ui.refreshData();\n            } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                stopResults();\n            }\n        }\n    }\n    \n    private void refreshResults() {\n        if (running) processor.post(new Runnable() {\n            public void run() {\n                if (ui != null) ui.setForceRefresh();\n                refreshView();\n            }\n        });\n    }\n    \n    private void refreshResults(int delay) {\n        if (running && refresher != null) processor.post(refresher, delay);\n    }\n    \n    private void resetResults() {\n        if (ui != null) ui.resetData();\n    }\n\n    private void stopResults() {\n        if (refresher != null) {\n            running = false;\n            refresher = null;\n        }\n    }\n    \n    private void unpauseResults() {\n        if (ui != null) ui.resetPause();\n    }\n     \n    // --- Session lifecycle ---------------------------------------------------\n    \n    public void notifyActivated() {\n        resetResults();\n    }\n    \n    public void notifyDeactivated() {\n        resetResults();\n    }\n    \n    \n    protected void profilingStateChanged(int oldState, int newState) {\n        if (newState == Profiler.PROFILING_INACTIVE || newState == Profiler.PROFILING_IN_TRANSITION) {\n            stopResults();\n        } else if (isActivated() && newState == Profiler.PROFILING_RUNNING) {\n            startResults();\n        } else if (newState == Profiler.PROFILING_STARTED) {\n            resetResults();\n            unpauseResults();\n        }\n        \n        if (ui != null) ui.sessionStateChanged(getSessionState());\n    }\n    \n    \n    // --- Provider ------------------------------------------------------------\n    \n    @ServiceProvider(service=ProfilerFeature.Provider.class)\n    public static final class Provider extends ProfilerFeature.Provider {\n        public ProfilerFeature getFeature(ProfilerSession session) {\n            return new LocksFeature(session);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/LocksFeatureUI.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.locks.LiveLocksViewUpdater;\nimport org.graalvm.visualvm.lib.ui.locks.LockContentionPanel;\nimport org.graalvm.visualvm.lib.ui.swing.ActionPopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"LocksFeatureUI_show=View by:\",\n    \"LocksFeatureUI_aggregationByThreads=Threads\",\n    \"LocksFeatureUI_aggregationByMonitors=Monitors\",\n    \"LocksFeatureUI_aggregationHint=Results aggregation\"\n})\nabstract class LocksFeatureUI extends FeatureUI {\n\n    private ProfilerToolbar toolbar;\n    private LockContentionPanel locksView;\n    private LiveLocksViewUpdater updater;\n\n    // --- External implementation ---------------------------------------------\n\n    abstract ProfilerClient getProfilerClient();\n\n    abstract void refreshResults();\n\n\n    // --- API implementation --------------------------------------------------\n\n    ProfilerToolbar getToolbar() {\n        if (toolbar == null) initUI();\n        return toolbar;\n    }\n\n    JPanel getResultsUI() {\n        if (locksView == null) initUI();\n        return locksView;\n    }\n\n\n    void sessionStateChanged(int sessionState) {\n        refreshToolbar(sessionState);\n    }\n\n    void resetPause() {\n//        if (lrPauseButton != null) lrPauseButton.setSelected(false);\n    }\n\n    void setForceRefresh() {\n        if (updater != null) updater.setForceRefresh(true);\n    }\n    \n    void refreshData() throws ClientUtils.TargetAppOrVMTerminated {\n        if (updater != null) updater.update();\n    }\n        \n    void resetData() {\n        if (locksView != null) locksView.resetData();\n    }\n    \n    \n    // --- UI ------------------------------------------------------------------\n    \n    private JLabel shLabel;\n    private ActionPopupButton shAggregation;\n    \n    \n    private void initUI() {\n        \n        assert SwingUtilities.isEventDispatchThread();\n        \n        // --- Results ---------------------------------------------------------\n\n        locksView = new LockContentionPanel() {\n            protected ProfilerClient getProfilerClient() {\n                return LocksFeatureUI.this.getProfilerClient();\n            }\n        };\n        locksView.lockContentionEnabled();\n        \n        locksView.putClientProperty(\"HelpCtx.Key\", \"ProfileLocks.HelpCtx\"); // NOI18N\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        shLabel = new GrayLabel(Bundle.LocksFeatureUI_show());\n        \n        Action aThreads = new AbstractAction() {\n            { putValue(NAME, Bundle.LocksFeatureUI_aggregationByThreads()); }\n            public void actionPerformed(ActionEvent e) { setAggregation(LockContentionPanel.Aggregation.BY_THREADS); }\n            \n        };\n        Action aMonitors = new AbstractAction() {\n            { putValue(NAME, Bundle.LocksFeatureUI_aggregationByMonitors()); }\n            public void actionPerformed(ActionEvent e) { setAggregation(LockContentionPanel.Aggregation.BY_MONITORS); }\n            \n        };\n        shAggregation = new ActionPopupButton(aThreads, aMonitors);\n        shAggregation.setToolTipText(Bundle.LocksFeatureUI_aggregationHint());\n\n        toolbar = ProfilerToolbar.create(true);\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(shLabel);\n        toolbar.addSpace(2);\n        toolbar.add(shAggregation);\n\n\n        // --- Sync UI ---------------------------------------------------------\n        \n        setAggregation(LockContentionPanel.Aggregation.BY_THREADS);\n        sessionStateChanged(getSessionState());\n\n    }\n    \n    private void refreshToolbar(final int state) {\n//        if (toolbar != null) SwingUtilities.invokeLater(new Runnable() {\n//            public void run() {\n//            }\n//        });\n    }\n    \n    private void setAggregation(LockContentionPanel.Aggregation aggregation) {\n        locksView.setAggregation(aggregation);\n        shAggregation.selectAction(aggregation.ordinal());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/MethodsFeature.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.util.Collection;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JRadioButtonMenuItem;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.SmallButton;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.ResultsListener;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.api.ProjectUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceClassInfo;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceMethodInfo;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerFeature;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.WeakProcessor;\nimport org.graalvm.visualvm.lib.profiler.v2.ui.SettingsPanel;\nimport org.graalvm.visualvm.lib.profiler.v2.ui.TitledMenuSeparator;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"MethodsFeature_name=Methods\",\n    \"MethodsFeature_description=Profile method execution times and invocation counts, including call trees\",\n    \"MethodsFeature_modeReset=<html><b>Current mode ''{0}'' is not configured properly.</b><br><br>Default ''{1}'' mode has been selected and applied instead.<br><br></html>\"\n})\nfinal class MethodsFeature extends ProfilerFeature.Basic {\n    \n    private final WeakProcessor processor;\n    \n    private FeatureMode currentMode;\n    private FeatureMode appliedMode;\n    \n    private MethodsFeatureModes.AllClassesMode allClassesMode;\n    private MethodsFeatureModes.ProjectClassesMode projectClassesMode;\n    private MethodsFeatureModes.SelectedClassesMode selectedClassesMode;\n    private MethodsFeatureModes.SelectedMethodsMode selectedMethodsMode;\n    private MethodsFeatureModes.CustomClassesMode definedClassesMode;\n    \n    \n    private MethodsFeature(ProfilerSession session) {\n        super(Icons.getIcon(ProfilerIcons.CPU), Bundle.MethodsFeature_name(),\n              Bundle.MethodsFeature_description(), 12, session);\n        \n        assert !SwingUtilities.isEventDispatchThread();\n        \n        Lookup.Provider project = session.getProject();\n        String projectName = project == null ? \"External Process\" : // NOI18N\n                             ProjectUtilities.getDisplayName(project);\n        processor = new WeakProcessor(\"MethodsFeature Processor for \" + projectName); // NOI18N\n\n        initModes();\n    }\n    \n    \n    // --- Configuration -------------------------------------------------------\n    \n    public boolean supportsConfiguration(Lookup configuration) {\n        return configuration.lookup(SourceMethodInfo.class) != null ||\n               configuration.lookup(SourceClassInfo.class) != null ||\n               configuration.lookup(ClientUtils.SourceCodeSelection.class) != null;\n    }\n    \n    public void configure(Lookup configuration) {\n        // Handle Profile Method action from editor\n        SourceMethodInfo methodInfo = configuration.lookup(SourceMethodInfo.class);\n        if (methodInfo != null) selectMethodForProfiling(methodInfo);\n        \n        // Handle Profile Class action from editor\n        SourceClassInfo classInfo = configuration.lookup(SourceClassInfo.class);\n        if (classInfo != null) selectClassForProfiling(classInfo);\n        \n        // Handle Profile Class/Method action from snapshot\n        ClientUtils.SourceCodeSelection sel = configuration.lookup(ClientUtils.SourceCodeSelection.class);\n        if (sel != null) selectForProfiling(sel);\n    }\n    \n    \n    private void selectMethodForProfiling(SourceMethodInfo methodInfo) {\n        selectForProfiling(new ClientUtils.SourceCodeSelection(methodInfo.getClassName(),\n                           methodInfo.getName(), methodInfo.getSignature()));\n    }\n    \n    private void selectClassForProfiling(SourceClassInfo classInfo) {\n        selectForProfiling(new ClientUtils.SourceCodeSelection(classInfo.getQualifiedName(),\n                           Wildcards.ALLWILDCARD, null));\n    }\n    \n    private void selectForProfiling(ClientUtils.SourceCodeSelection sel) {\n        if (Wildcards.ALLWILDCARD.equals(sel.getMethodName())) {\n            selectedClassesMode.getSelection().add(sel);\n        } else {\n            selectedMethodsMode.getSelection().add(sel);\n        }\n    }\n    \n    \n    // --- Mode ----------------------------------------------------------------\n    \n    private static final String MODE_FLAG = \"MODE_FLAG\"; // NOI18N\n    \n    private void initModes() {\n        allClassesMode = new MethodsFeatureModes.AllClassesMode() {\n            String readFlag(String flag, String defaultValue) {\n                return MethodsFeature.this.readFlag(getID() + \"_\" + flag, defaultValue); // NOI18N\n            }\n            void storeFlag(String flag, String value) {\n                MethodsFeature.this.storeFlag(getID() + \"_\" + flag, value); // NOI18N\n            }\n            void settingsChanged() {\n                MethodsFeature.this.settingsChanged();\n            }\n        };\n        allClassesMode.initialize();\n        \n        if (getSession().getProject() != null) projectClassesMode = new MethodsFeatureModes.ProjectClassesMode() {\n            String readFlag(String flag, String defaultValue) {\n                return MethodsFeature.this.readFlag(getID() + \"_\" + flag, defaultValue); // NOI18N\n            }\n            void storeFlag(String flag, String value) {\n                MethodsFeature.this.storeFlag(getID() + \"_\" + flag, value); // NOI18N\n            }\n            void settingsChanged() {\n                MethodsFeature.this.settingsChanged();\n            }\n            Lookup.Provider getProject() {\n                return MethodsFeature.this.getSession().getProject();\n            }\n        };\n        if (projectClassesMode != null) projectClassesMode.initialize();\n        \n        selectedClassesMode = new MethodsFeatureModes.SelectedClassesMode() {\n            String readFlag(String flag, String defaultValue) {\n                return MethodsFeature.this.readFlag(getID() + \"_\" + flag, defaultValue); // NOI18N\n            }\n            void storeFlag(String flag, String value) {\n                MethodsFeature.this.storeFlag(getID() + \"_\" + flag, value); // NOI18N\n            }\n            ProfilerSession getSession() {\n                return MethodsFeature.this.getSession();\n            }\n            void selectForProfiling(Collection<SourceClassInfo> classInfos) {\n                for (SourceClassInfo classInfo : classInfos)\n                    MethodsFeature.this.selectClassForProfiling(classInfo);\n            }\n            void settingsChanged() {\n                MethodsFeature.this.settingsChanged();\n            }\n            void selectionChanging() {\n                MethodsFeature.this.setMode(this);\n                MethodsFeature.this.getSettingsUI().setVisible(true);\n            }\n            void selectionChanged() {\n                MethodsFeature.this.selectionChanged();\n            }\n        };\n        selectedClassesMode.initialize();\n        \n        selectedMethodsMode = new MethodsFeatureModes.SelectedMethodsMode() {\n            String readFlag(String flag, String defaultValue) {\n                return MethodsFeature.this.readFlag(getID() + \"_\" + flag, defaultValue); // NOI18N\n            }\n            void storeFlag(String flag, String value) {\n                MethodsFeature.this.storeFlag(getID() + \"_\" + flag, value); // NOI18N\n            }\n            ProfilerSession getSession() {\n                return MethodsFeature.this.getSession();\n            }\n            void selectForProfiling(Collection<SourceMethodInfo> methodInfos) {\n                for (SourceMethodInfo methodInfo : methodInfos)\n                    MethodsFeature.this.selectMethodForProfiling(methodInfo);\n            }\n            void settingsChanged() {\n                MethodsFeature.this.settingsChanged();\n            }\n            void selectionChanging() {\n                MethodsFeature.this.setMode(this);\n                MethodsFeature.this.getSettingsUI().setVisible(true);\n            }\n            void selectionChanged() {\n                MethodsFeature.this.selectionChanged();\n                if (MethodsFeature.this.ui != null && MethodsFeature.this.ui.hasResultsUI())\n                    MethodsFeature.this.ui.getResultsUI().repaint();\n            }\n        };\n        selectedMethodsMode.initialize();\n        \n        if (ProfilerIDESettings.getInstance().getEnableExpertSettings()) {\n            definedClassesMode = new MethodsFeatureModes.CustomClassesMode() {\n                String readFlag(String flag, String defaultValue) {\n                    return MethodsFeature.this.readFlag(getID() + \"_\" + flag, defaultValue); // NOI18N\n                }\n                void storeFlag(String flag, String value) {\n                    MethodsFeature.this.storeFlag(getID() + \"_\" + flag, value); // NOI18N\n                }\n                void settingsChanged() {\n                    MethodsFeature.this.settingsChanged();\n                }\n            };\n        }\n        if (definedClassesMode != null) definedClassesMode.initialize();\n        \n//        currentMode = allClassesMode;\n        String _currentMode = readFlag(MODE_FLAG, allClassesMode.getID());\n        if (projectClassesMode != null && _currentMode.equals(projectClassesMode.getID())) currentMode = projectClassesMode;\n        else if (_currentMode.equals(selectedClassesMode.getID())) currentMode = selectedClassesMode;\n        else if (_currentMode.equals(selectedMethodsMode.getID())) currentMode = selectedMethodsMode;\n        else if (definedClassesMode != null && _currentMode.equals(definedClassesMode.getID())) currentMode = definedClassesMode;\n        else currentMode = allClassesMode;\n        \n        appliedMode = currentMode;\n    }\n    \n    private void saveMode() {\n        storeFlag(MODE_FLAG, currentMode.getID());\n    }\n    \n    private void setMode(FeatureMode newMode) {\n        if (currentMode == newMode) return;\n        currentMode = newMode;\n        modeChanged();\n    }\n    \n    private void confirmMode() {\n        appliedMode = currentMode;\n    }\n    \n    private void modeChanged() {\n        updateModeName();\n        updateModeUI();\n        configurationChanged();\n        saveMode();\n    }\n    \n    \n    // --- Settings ------------------------------------------------------------\n    \n    public boolean supportsSettings(ProfilingSettings psettings) {\n        return !ProfilingSettings.isMemorySettings(psettings) &&\n               !ProfilingSettings.isJDBCSettings(psettings);\n    }\n\n    public void configureSettings(ProfilingSettings psettings) {\n        currentMode.configureSettings(psettings);\n    }\n    \n    public boolean currentSettingsValid() {\n        return currentMode.currentSettingsValid();\n    }\n    \n    private void submitChanges() {\n        confirmMode();\n        confirmSettings();\n        fireChange();\n    }\n    \n    // Changes to current settings are pending\n    private boolean pendingChanges() {\n        if (appliedMode != currentMode) return true;\n        return currentMode.pendingChanges();\n    }\n    \n    // Profiling settings defined by this feature have changed\n    private void configurationChanged() {\n        assert isActivated();\n        \n        ProfilerSession session = getSession();\n        \n        if (!session.inProgress()) submitChanges();\n        else updateApplyButton(session.getState());\n    }\n    \n    private void confirmSettings() {\n        currentMode.confirmSettings();\n    }\n    \n    private void confirmAllSettings() {\n        if (allClassesMode != null) allClassesMode.confirmSettings();\n        if (projectClassesMode != null) projectClassesMode.confirmSettings();\n        if (selectedClassesMode != null) selectedClassesMode.confirmSettings();\n        if (selectedMethodsMode != null) selectedMethodsMode.confirmSettings();\n        if (definedClassesMode != null) definedClassesMode.confirmSettings();\n    }\n    \n    private void settingsChanged() {\n        configurationChanged();\n    }\n    \n    private void selectionChanged() {\n        configurationChanged();\n    }\n    \n    \n    // --- Settings UI ---------------------------------------------------------\n    \n    private static final String SETTINGS_FLAG = \"SETTINGS_FLAG\"; // NOI18N\n    \n    private JPanel settingsUI;\n    private JButton modeButton;\n    private JPanel settingsContainer;\n    private JButton applyButton;\n    \n    public JPanel getSettingsUI() {\n        if (settingsUI == null) {\n            settingsUI = new JPanel(new GridBagLayout()) {\n                public void setVisible(boolean visible) {\n                    if (visible && getComponentCount() == 0) populateSettingsUI();\n                    super.setVisible(visible);\n                    storeFlag(SETTINGS_FLAG, visible ? Boolean.TRUE.toString() : null);\n                }\n                public Dimension getPreferredSize() {\n                    if (getComponentCount() == 0) return new Dimension();\n                    else return super.getPreferredSize();\n                }\n            };\n            \n            String _vis = readFlag(SETTINGS_FLAG, null);\n            boolean vis = _vis == null ? false : Boolean.parseBoolean(_vis);\n            settingsUI.setVisible(vis || currentMode != allClassesMode);\n//            settingsUI.setVisible(false);\n        }\n        return settingsUI;\n    }\n    \n    private void populateSettingsUI() {\n        settingsUI.setOpaque(false);\n        settingsUI.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n        \n        GridBagConstraints c;\n        \n        JPanel profilePanel = new SettingsPanel();\n        profilePanel.add(new JLabel(Bundle.ObjectsFeature_profileMode()));\n        profilePanel.add(Box.createHorizontalStrut(5));\n        \n        // Mode button\n        modeButton = new PopupButton(currentMode.getName()) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new TitledMenuSeparator(Bundle.ObjectsFeature_samplingModes()));\n                popup.add(new JRadioButtonMenuItem(allClassesMode.getName(), currentMode == allClassesMode) {\n                    protected void fireActionPerformed(ActionEvent e) { setMode(allClassesMode); }\n                });\n                if (projectClassesMode != null) popup.add(new JRadioButtonMenuItem(projectClassesMode.getName(), currentMode == projectClassesMode) {\n                    protected void fireActionPerformed(ActionEvent e) { setMode(projectClassesMode); }\n                });\n\n                popup.add(new TitledMenuSeparator(Bundle.ObjectsFeature_instrModes()));\n                popup.add(new JRadioButtonMenuItem(selectedClassesMode.getName(), currentMode == selectedClassesMode) {\n                    protected void fireActionPerformed(ActionEvent e) { setMode(selectedClassesMode); }\n                });\n                popup.add(new JRadioButtonMenuItem(selectedMethodsMode.getName(), currentMode == selectedMethodsMode) {\n                    protected void fireActionPerformed(ActionEvent e) { setMode(selectedMethodsMode); }\n                });\n                \n                if (definedClassesMode != null) popup.add(new JRadioButtonMenuItem(definedClassesMode.getName(), currentMode == definedClassesMode) {\n                    protected void fireActionPerformed(ActionEvent e) { setMode(definedClassesMode); }\n                });\n            }\n        };\n        profilePanel.add(modeButton);\n        \n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(0, 0, 0, 0);\n        c.anchor = GridBagConstraints.NORTHWEST;\n        settingsUI.add(profilePanel, c);\n        \n        // Settings container\n        settingsContainer = new JPanel(new BorderLayout());\n        settingsContainer.setOpaque(false);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.fill = GridBagConstraints.VERTICAL;\n        c.insets = new Insets(0, 10, 0, 0);\n        c.anchor = GridBagConstraints.NORTHWEST;\n        settingsUI.add(settingsContainer, c);\n        \n        JPanel buttonsPanel = new SettingsPanel();\n        \n        final Component space = Box.createHorizontalStrut(10);\n        buttonsPanel.add(space);\n        \n        // Apply button\n        applyButton = new SmallButton(Bundle.ObjectsFeature_applyButton()) {\n            protected void fireActionPerformed(ActionEvent e) {\n                stopResults();\n                resetResults();\n                submitChanges();\n                unpauseResults();\n            }\n            public void setVisible(boolean visible) {\n                super.setVisible(visible);\n                space.setVisible(visible);\n            }\n        };\n        buttonsPanel.add(applyButton);\n        \n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 0;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(0, 0, 0, 0);\n        c.anchor = GridBagConstraints.NORTHEAST;\n        settingsUI.add(buttonsPanel, c);\n        \n        updateModeUI();\n        updateApplyButton(getSession().getState());\n    }\n    \n    private void updateModeName() {\n        if (modeButton != null) modeButton.setText(currentMode.getName());\n    }\n    \n    private void updateModeUI() {\n        if (settingsContainer != null) {\n            settingsContainer.removeAll();\n\n            JComponent modeUI = currentMode.getUI();\n            if (modeUI != null) settingsContainer.add(modeUI);\n            settingsContainer.doLayout();\n            settingsContainer.repaint();\n        }\n    }\n    \n    private void updateApplyButton(int state) {\n        if (applyButton != null) {\n            boolean visible = state != Profiler.PROFILING_INACTIVE;\n            applyButton.setVisible(visible);\n            if (visible) applyButton.setEnabled(currentSettingsValid() && pendingChanges());\n        }\n    }\n    \n    \n    // --- Toolbar & Results UI ------------------------------------------------\n    \n    private MethodsFeatureUI ui;\n    \n    public JPanel getResultsUI() {\n        return getUI().getResultsUI();\n    }\n    \n    public ProfilerToolbar getToolbar() {\n        return getUI().getToolbar();\n    }\n    \n    private MethodsFeatureUI getUI() {\n        if (ui == null) ui = new MethodsFeatureUI() {\n            Set<ClientUtils.SourceCodeSelection> getClassesSelection() {\n                return selectedClassesMode.getSelection();\n            }\n            Set<ClientUtils.SourceCodeSelection> getMethodsSelection() {\n                return selectedMethodsMode.getSelection();\n            }\n            void selectForProfiling(ClientUtils.SourceCodeSelection value) {\n                MethodsFeature.this.selectForProfiling(value);\n            }\n            Lookup.Provider getProject() {\n                return MethodsFeature.this.getSession().getProject();\n            }\n            ProfilerClient getProfilerClient() {\n                Profiler profiler = MethodsFeature.this.getSession().getProfiler();\n                return profiler.getTargetAppRunner().getProfilerClient();\n            }\n            int getSessionState() {\n                return MethodsFeature.this.getSessionState();\n            }\n            void refreshResults() {\n                MethodsFeature.this.refreshResults();\n            }\n        };\n        return ui;\n    }\n    \n    \n    // --- Live results --------------------------------------------------------\n    \n    private Runnable refresher;\n    private volatile boolean running;\n    \n    \n    private void startResults() {\n        if (running) return;\n        running = true;\n        \n        refresher = new Runnable() {\n            public void run() {\n                if (running) {\n                    refreshView();\n                    refreshResults(1500);\n                }\n            }\n        };\n        \n        refreshResults(1000);\n    }\n\n    private void refreshView() {\n        if (ui != null && ResultsManager.getDefault().resultsAvailable()\n            || getSession().getProfilingSettings().getCPUProfilingType() == CommonConstants.CPU_SAMPLED) {\n            try {\n                ui.refreshData();\n            } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                stopResults();\n            }\n        }\n    }\n    \n    private void refreshResults() {\n        if (running) processor.post(new Runnable() {\n            public void run() {\n                if (ui != null) ui.setForceRefresh();\n                refreshView();\n            }\n        });\n    }\n    \n    private void refreshResults(int delay) {\n        if (running && refresher != null) processor.post(refresher, delay);\n    }\n    \n    private void resetResults() {\n        if (ui != null) ui.resetData();\n    }\n    \n    private void stopResults() {\n        if (refresher != null) {\n            running = false;\n            refresher = null;\n        }\n    }\n    \n    private void unpauseResults() {\n        if (ui != null) ui.resetPause();\n    }\n    \n    \n    // --- Session lifecycle ---------------------------------------------------\n    \n    private MethodsResetter resetter;\n    \n    public void notifyActivated() {\n        resetResults();\n        \n        resetter = Lookup.getDefault().lookup(MethodsResetter.class);\n        resetter.controller = this;\n        \n        if (getSession().inProgress() && !currentMode.currentSettingsValid()) {\n            final String oldMode = currentMode.getName();\n            final String newMode = allClassesMode.getName();\n            setMode(allClassesMode);\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    ProfilerDialogs.displayInfo(Bundle.MethodsFeature_modeReset(\n                                                oldMode, newMode));\n                }\n            });\n        }\n    }\n    \n    public void notifyDeactivated() {\n        resetResults();\n        \n        if (resetter != null) {\n            resetter.controller = null;\n            resetter = null;\n        }\n        \n        if (ui != null) {\n            ui.cleanup();\n            ui = null;\n        }\n        \n        settingsUI = null;\n    }\n    \n    \n    protected void profilingStateChanged(int oldState, int newState) {\n        if (newState == Profiler.PROFILING_INACTIVE || newState == Profiler.PROFILING_IN_TRANSITION) {\n            stopResults();\n            confirmAllSettings();\n        } else if (isActivated() && newState == Profiler.PROFILING_RUNNING) {\n            startResults();\n        } else if (newState == Profiler.PROFILING_STARTED) {\n            resetResults();\n            unpauseResults();\n        }\n        \n        if (ui != null) ui.sessionStateChanged(getSessionState());\n        \n        updateApplyButton(newState);\n    }\n    \n    \n    @ServiceProvider(service=ResultsListener.class)\n    public static final class MethodsResetter implements ResultsListener {\n        private MethodsFeature controller;\n        public void resultsAvailable() { /*if (controller != null) controller.refreshView();*/ }\n        public void resultsReset() { if (controller != null && controller.ui != null) controller.ui.resetData(); }\n    }\n    \n    \n    // --- Provider ------------------------------------------------------------\n    \n    @ServiceProvider(service=ProfilerFeature.Provider.class)\n    public static final class Provider extends ProfilerFeature.Provider {\n        public ProfilerFeature getFeature(ProfilerSession session) {\n            return new MethodsFeature(session);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/MethodsFeatureModes.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Image;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseEvent;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.ButtonGroup;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JRadioButton;\nimport javax.swing.JScrollPane;\nimport javax.swing.JSpinner;\nimport javax.swing.SpinnerNumberModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.border.Border;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.filters.JavaTypeFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedSpinner;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.SmallButton;\nimport org.graalvm.visualvm.lib.ui.swing.TextArea;\nimport org.graalvm.visualvm.lib.profiler.api.ProjectUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceClassInfo;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceMethodInfo;\nimport org.graalvm.visualvm.lib.profiler.api.project.ProjectContentsSupport;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.ClassMethodList;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.ClassMethodSelector;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.FilterSelector;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.ProjectsSelector;\nimport org.graalvm.visualvm.lib.profiler.v2.ui.SettingsPanel;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"MethodsFeatureModes_allClasses=All classes\",\n    \"MethodsFeatureModes_projectClasses=Project classes\",\n    \"MethodsFeatureModes_selectedClasses=Selected classes\",\n    \"MethodsFeatureModes_selectedMethods=Selected methods\",\n    \"MethodsFeatureModes_editLink=<html><a href='#'>{0}, edit</a></html>\",\n    \"MethodsFeatureModes_selectedProject=Selected {0}\",\n    \"MethodsFeatureModes_selectedProjects=Selected {0} projects\",\n    \"MethodsFeatureModes_outgoingCalls=Limit outgoing calls:\",\n    \"MethodsFeatureModes_unlimitedCalls=unlimited\",\n    \"MethodsFeatureModes_filterOutgoingCalls=Filter outgoing calls:\",\n    \"MethodsFeatureModes_filterOutgoingTooltip=Filter calls from the selected classes or methods\",\n    \"MethodsFeatureModes_noFilter=no filter\",\n    \"MethodsFeatureModes_noClassSelected=No classes selected, use Profile Class action in editor or results or click the Add button:\",\n    \"MethodsFeatureModes_oneClassSelected=Selected 1 class\",\n    \"MethodsFeatureModes_multipleClassesSelected=Selected {0} classes\",\n    \"MethodsFeatureModes_noMethodSelected=No methods selected, use Profile Method action in editor or results or click the Add button:\",\n    \"MethodsFeatureModes_oneMethodSelected=Selected 1 method\",\n    \"MethodsFeatureModes_multipleMethodsSelected=Selected {0} methods\",\n    \"MethodsFeatureModes_addMethod=Select method\",\n    \"MethodsFeatureModes_addClass=Select class\",\n    \"MethodsFeatureModes_limitCallTreeToolTip=Limit depth of calls from the selected classes or methods\",\n    \"MethodsFeatureModes_doNotProfileCoreJavaToolTip=Do not profile core Java classes (java.*, sun.*, com.sun.*, etc.)\",\n    \"MethodsFeatureModes_definedClasses=Defined classes\",\n    \"MethodsFeatureModes_classesLbl=Classes:\",\n    \"MethodsFeatureModes_includeCalls=Include outgoing calls:\",\n    \"MethodsFeatureModes_includeTooltip=Profile only outgoing calls of the defined classes or packages\",\n    \"MethodsFeatureModes_excludeCalls=Exclude outgoing calls:\",\n    \"MethodsFeatureModes_excludeTooltip=Do not profile outgoing calls of the defined classes or packages\",\n    \"MethodsFeatureModes_classesHint=org.mypackage.**\\norg.mypackage.*\\norg.mypackage.MyClass\",\n    \"MethodsFeatureModes_filterHint=org.mypackage.**\\norg.mypackage.*\\norg.mypackage.MyClass\",\n    \"MethodsFeatureModes_classesTooltip=<html>Profile methods of these classes or packages:<br><br>\"\n            + \"<code>&nbsp;org.mypackage.**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package and subpackages<br>\"\n            + \"<code>&nbsp;org.mypackage.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package<br>\"\n            + \"<code>&nbsp;org.mypackage.MyClass&nbsp;&nbsp;</code>single class<br></html>\",\n    \"MethodsFeatureModes_filterTooltip=<html>Include/exclude profiling outgoing calls from these classes or packages:<br><br>\"\n            + \"<code>&nbsp;org.mypackage.**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package and subpackages<br>\"\n            + \"<code>&nbsp;org.mypackage.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package<br>\"\n            + \"<code>&nbsp;org.mypackage.MyClass&nbsp;&nbsp;</code>single class<br><br>\"\n            + \"Special case:<br><br>\"\n            + \"<code>&nbsp;&lt;empty&gt;</code> or <code>*&nbsp;&nbsp;</code>include all classes<br></html>\"\n})\nfinal class MethodsFeatureModes {\n    \n    private static abstract class MethodsMode extends FeatureMode {\n        \n        void initialize() {}\n        \n        void configureSettings(ProfilingSettings settings) {}\n        \n    }\n    \n    private static abstract class SampledMethodsMode extends MethodsMode {\n        \n        void configureSettings(ProfilingSettings settings) {\n            super.configureSettings(settings);\n            \n            settings.setProfilingType(ProfilingSettings.PROFILE_CPU_SAMPLING);\n            settings.setCPUProfilingType(CommonConstants.CPU_SAMPLED);\n        }\n        \n        void confirmSettings() {}\n        \n        boolean pendingChanges() { return false; }\n\n        boolean currentSettingsValid() { return true; }\n        \n        JComponent getUI() { return null; }\n        \n    }\n    \n    static abstract class AllClassesMode extends SampledMethodsMode {\n        \n        String getID() {\n            return \"AllClassesMode\"; // NOI18N\n        }\n\n        String getName() {\n            return Bundle.MethodsFeatureModes_allClasses();\n        }\n\n        void configureSettings(ProfilingSettings settings) {\n            super.configureSettings(settings);\n            \n            settings.setInstrumentationFilter(new JavaTypeFilter());\n        }\n        \n    }\n    \n    static abstract class ProjectClassesMode extends SampledMethodsMode {\n        \n        private final Collection<Lookup.Provider> selectedProjects;\n        \n        // --- External implementation -----------------------------------------\n        \n        abstract Lookup.Provider getProject();\n        \n        \n        // --- API implementation ----------------------------------------------\n        \n        private static final String PROJECTS_FLAG = \"PROJECTS_FLAG\"; // NOI18N\n        \n        ProjectClassesMode() {\n            selectedProjects = new HashSet();\n            \n            Collection<File> files = createFilesFromStorage();\n            if (files.isEmpty()) {\n                selectedProjects.add(getProject());\n            } else {\n                for (File file : files) if (file.exists()) {\n                    FileObject fo = FileUtil.toFileObject(FileUtil.normalizeFile(file));\n                    Lookup.Provider project = fo == null ? null : ProjectUtilities.getProject(fo);\n                    if (fo != null) selectedProjects.add(project);\n                }\n                verifySelectedProjects(false);\n            }\n        }\n        \n        String getID() {\n            return \"ProjectClassesMode\"; // NOI18N\n        }\n\n        String getName() {\n            return Bundle.MethodsFeatureModes_projectClasses();\n        }\n\n        void configureSettings(ProfilingSettings settings) {\n            super.configureSettings(settings);\n            \n            StringBuilder filter = new StringBuilder();\n            \n            for (Lookup.Provider project : selectedProjects) {\n                ProjectContentsSupport pcs = ProjectContentsSupport.get(project);\n                filter.append(pcs.getInstrumentationFilter(false));\n                filter.append(\" \"); // NOI18N\n                pcs.reset();\n            }\n            \n            String s  = filter.toString().replace(\". \", \".* \").replace(\".,\", \".*,\").trim(); // NOI18N\n            JavaTypeFilter f = new JavaTypeFilter(s, JavaTypeFilter.TYPE_INCLUSIVE);\n            settings.setInstrumentationFilter(f);\n        }\n        \n        void confirmSettings() {\n            if (ui != null) {\n                assert SwingUtilities.isEventDispatchThread();\n                                \n                saveSelection();\n            }\n        }\n        \n        boolean pendingChanges() {\n            if (ui != null) {\n                assert SwingUtilities.isEventDispatchThread();\n                \n                if (!filesEquals(createFilesFromSelection(), createFilesFromStorage())) return true;\n            }\n            return false;\n        }\n        \n        boolean currentSettingsValid() {\n            assert SwingUtilities.isEventDispatchThread();\n            \n            if (selectedProjects.isEmpty()) return false;\n            \n            return true;\n        }\n        \n        \n        private void saveSelection() {\n            Collection<File> files = createFilesFromSelection();\n            if (files.isEmpty()) {\n                storeFlag(PROJECTS_FLAG, null);\n            } else {\n                StringBuilder sb = new StringBuilder();\n                for (File file : files) {\n                    try {\n                        sb.append(file.getCanonicalPath());\n                    } catch (IOException ex) {\n                        sb.append(file.getAbsolutePath());\n                    }\n                    sb.append(File.pathSeparatorChar);\n                }\n                storeFlag(PROJECTS_FLAG, sb.toString());\n            }\n        }\n        \n        private Collection<File> createFilesFromStorage() {\n            Set<File> files = new HashSet();\n            \n            String s = readFlag(PROJECTS_FLAG, null);\n            if (s != null) {\n                String[] sa = s.split(File.pathSeparator);\n                for (String _s : sa) files.add(new File(_s));\n            }\n            \n            return files;\n        }\n        \n        private Collection<File> createFilesFromSelection() {\n            Set<File> files = new HashSet();\n            \n            if (selectedProjects.size() > 1 || !selectedProjects.contains(getProject()))\n                for (Lookup.Provider project : selectedProjects)\n                    files.add(FileUtil.toFile(ProjectUtilities.getProjectDirectory(project)));\n            \n            return files;\n        }\n        \n        private boolean filesEquals(Collection<File> files1, Collection<File> files2) {\n            if (files1.size() != files2.size()) return false;\n            for (File file1 : files1) if (!files2.contains(file1)) return false;\n            return true;\n        }\n        \n        // NOTE: must be executed in EDT except of calling from constructor (populating selectedProjects)\n        private void verifySelectedProjects(boolean refreshLink) {\n            if (selectedProjects.size() == 1 && selectedProjects.contains(getProject())) return;\n            \n            List<Lookup.Provider> projects = Arrays.asList(ProjectUtilities.getOpenedProjects());\n            Iterator<Lookup.Provider> iterator = selectedProjects.iterator();\n            while (iterator.hasNext()) if (!projects.contains(iterator.next())) iterator.remove();\n            \n            if (selectedProjects.isEmpty()) selectedProjects.add(getProject());\n            \n            if (refreshLink) refreshProjectsLink();\n        }\n        \n        \n        JComponent getUI() {\n            if (ui == null) {\n                final ChangeListener projectsListener = new ChangeListener() {\n                    public void stateChanged(ChangeEvent e) {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() { verifySelectedProjects(true); }\n                        });\n                    }\n                };\n                ui = new SettingsPanel() {\n                    public void addNotify() {\n                        super.addNotify();\n                        ProjectUtilities.addOpenProjectsListener(projectsListener);\n                    }\n                    public void removeNotify() {\n                        ProjectUtilities.removeOpenProjectsListener(projectsListener);\n                        super.removeNotify();\n                    }\n                };\n                \n                editProjectLink = new JButton() {\n                    public void setText(String text) {\n                        super.setText(Bundle.MethodsFeatureModes_editLink(text));\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        performEditProject();\n                    }\n                    public Dimension getMinimumSize() {\n                        return getPreferredSize();\n                    }\n                    public Dimension getMaximumSize() {\n                        return getPreferredSize();\n                    }\n                };\n                editProjectLink.setContentAreaFilled(false);\n                editProjectLink.setBorderPainted(true);\n                editProjectLink.setMargin(new Insets(0, 0, 0, 0));\n                editProjectLink.setBorder(BorderFactory.createEmptyBorder());\n                editProjectLink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n                refreshProjectsLink();\n                ui.add(editProjectLink);\n            }\n            return ui;\n        }\n        \n        \n        private void performEditProject() {\n            new ProjectsSelector(selectedProjects) {\n                protected void selectionChanged(Collection<Lookup.Provider> selected) {\n                    selectedProjects.clear();\n                    selectedProjects.addAll(selected);\n                    refreshProjectsLink();\n                    settingsChanged();\n                }\n            }.show(ui);\n        }\n        \n        private void refreshProjectsLink() {\n            if (editProjectLink == null) return;\n            if (selectedProjects.size() == 1)\n                editProjectLink.setText(Bundle.MethodsFeatureModes_selectedProject(\n                                        ProjectUtilities.getDisplayName(selectedProjects.\n                                        iterator().next())));\n            else editProjectLink.setText(Bundle.MethodsFeatureModes_selectedProjects(\n                                        selectedProjects.size()));\n        }\n        \n        \n        private JComponent ui;\n        private JButton editProjectLink;\n        \n    }\n    \n    private static abstract class InstrMethodsMode extends MethodsMode {\n        \n        // --- External implementation -----------------------------------------\n        \n        abstract void selectionChanging();\n        \n        abstract void selectionChanged();\n        \n        abstract ProfilerSession getSession();\n        \n        \n        // --- API implementation ----------------------------------------------\n        private static final String CORE_JAVA_FILTER = \"apple.laf.**, apple.awt.**, com.apple.**, com.sun.**, java.**, javax.**, jdk.**, sun.**, sunw.**, org.omg.CORBA.**, org.omg.CosNaming.**, COM.rsa.**\"; // NOI18N\n        \n        private static final String OUTGOING_CALLS_ENABLED_FLAG = \"OUTGOING_CALLS_ENABLED_FLAG\"; // NOI18N\n        private static final String OUTGOING_CALLS_FLAG = \"OUTGOING_CALLS_FLAG\"; // NOI18N\n        private static final String SKIP_JAVA_FLAG = \"SKIP_JAVA_FLAG\"; // NOI18N // Note: used in 8.1\n        private static final String FILTER_CALLS_FLAG = \"FILTER_CALLS_FLAG\"; // NOI18N\n        private static final String FILTER_CALLS_VALUE_FLAG = \"FILTER_CALLS_VALUE_FLAG\"; // NOI18N\n        private static final String SELECTION_FLAG = \"SELECTION_FLAG\"; // NOI18N\n        \n        private static final Integer OUTGOING_CALLS_DEFAULT = 5;\n        \n        private FeatureMode.Selection selection;\n        private FilterSelector.FilterName filterName;\n        private String filterValue;\n        \n        private boolean lastOutgoingSelected;\n        \n        \n        void initialize() {\n            // Migrate 8.1 settings\n            String excludeJava = readFlag(SKIP_JAVA_FLAG, null);\n            if (excludeJava != null) {\n                boolean _excludeJava = Boolean.TRUE.toString().equals(excludeJava) ?\n                                       true : false;\n                \n                // remove deprecated flag\n                storeFlag(SKIP_JAVA_FLAG, null);\n                \n                if (_excludeJava) {\n                    // default value, no need to set anything\n                } else {\n                    // no filtering, set the appropriate flag\n                    storeFlag(FILTER_CALLS_FLAG, FilterSelector.FilterName.NO_FILTER.name());\n                }\n            }\n            \n            // Initialize selected filter\n            String filter = readFlag(FILTER_CALLS_FLAG, null);\n            if (filter != null) filterName = FilterSelector.FilterName.valueOf(filter);\n            if (filterName == null) filterName = FilterSelector.FilterName.EXCLUDE_JAVA_FILTER;\n            \n            // Initialize custom filter\n            filterValue = readFlag(FILTER_CALLS_VALUE_FLAG, \"\"); // NOI18N\n        }\n        \n\n        void configureSettings(ProfilingSettings settings) {\n            assert SwingUtilities.isEventDispatchThread();\n            \n            super.configureSettings(settings);            \n            \n            settings.setProfilingType(ProfilingSettings.PROFILE_CPU_PART);\n            settings.setCPUProfilingType(settings.getSamplingInterval() <= 0 ?\n                                         CommonConstants.CPU_INSTR_FULL :\n                                         CommonConstants.CPU_INSTR_SAMPLED);\n            \n            String filterType = readFlag(FILTER_CALLS_FLAG, FilterSelector.FilterName.EXCLUDE_JAVA_FILTER.name());\n            if (FilterSelector.FilterName.NO_FILTER.name().equals(filterType)) {\n                settings.setInstrumentationFilter(new JavaTypeFilter());\n            } else if (FilterSelector.FilterName.EXCLUDE_JAVA_FILTER.name().equals(filterType)) {\n                settings.setInstrumentationFilter(new JavaTypeFilter(CORE_JAVA_FILTER, JavaTypeFilter.TYPE_EXCLUSIVE));\n            } else {\n                 String filterStrings = readFlag(FILTER_CALLS_VALUE_FLAG, CORE_JAVA_FILTER);\n                 if (filterStrings.isEmpty() || \"*\".equals(filterStrings) || \"**\".equals(filterStrings)) { // NOI18N\n                     settings.setInstrumentationFilter(new JavaTypeFilter());\n                 } else {\n                     filterStrings = getFlatValues(filterStrings.split(\"\\\\n\")); // NOI18N\n                     if (FilterSelector.FilterName.EXCLUDE_CUSTOM_FILTER.name().equals(filterType)) {\n                         settings.setInstrumentationFilter(new JavaTypeFilter(filterStrings, JavaTypeFilter.TYPE_EXCLUSIVE));\n                     } else if (FilterSelector.FilterName.INCLUDE_CUSTOM_FILTER.name().equals(filterType)) {\n                         settings.setInstrumentationFilter(new JavaTypeFilter(filterStrings, JavaTypeFilter.TYPE_INCLUSIVE)); // NOI18N\n                     }\n                 }\n            }\n            \n            HashSet<ClientUtils.SourceCodeSelection> _sel = getSelection();\n            ClientUtils.SourceCodeSelection[] classes = _sel.toArray(new ClientUtils.SourceCodeSelection[0]);\n            settings.addRootMethods(classes);\n            \n            if (Boolean.parseBoolean(readFlag(OUTGOING_CALLS_ENABLED_FLAG, Boolean.TRUE.toString())))\n                settings.setStackDepthLimit(Integer.parseInt(readFlag(OUTGOING_CALLS_FLAG, OUTGOING_CALLS_DEFAULT.toString())));\n            else settings.setStackDepthLimit(Integer.MAX_VALUE);\n        }\n        \n        void confirmSettings() {\n            if (ui != null) {\n                assert SwingUtilities.isEventDispatchThread();\n                \n                storeFlag(OUTGOING_CALLS_ENABLED_FLAG, lastOutgoingSelected ? null : Boolean.FALSE.toString());\n                \n                String outgoingCalls = outgoingSpinner.getValue().toString();\n                storeFlag(OUTGOING_CALLS_FLAG, OUTGOING_CALLS_DEFAULT.toString().equals(outgoingCalls) ? null : outgoingCalls);\n                \n                String filter = FilterSelector.FilterName.EXCLUDE_JAVA_FILTER.equals(filterName) ? null : filterName.name();\n                storeFlag(FILTER_CALLS_FLAG, filter);\n                \n                storeFlag(FILTER_CALLS_VALUE_FLAG, filterValue.isEmpty() ? null : filterValue);\n                \n                saveSelection();\n            }\n        }\n        \n        boolean pendingChanges() {\n            if (ui != null) {\n                assert SwingUtilities.isEventDispatchThread();\n                \n                if (Boolean.parseBoolean(readFlag(OUTGOING_CALLS_ENABLED_FLAG, Boolean.TRUE.toString())) != lastOutgoingSelected)\n                    return true;\n                \n                if (!outgoingSpinner.getValue().toString().equals(readFlag(OUTGOING_CALLS_FLAG, OUTGOING_CALLS_DEFAULT.toString())))\n                    return true;\n                \n                String filter = readFlag(FILTER_CALLS_FLAG, FilterSelector.FilterName.EXCLUDE_JAVA_FILTER.name());\n                if (!filter.equals(filterName.name())) return true;\n                \n                if (!readFlag(FILTER_CALLS_VALUE_FLAG, \"\").equals(filterValue)) return true; // NOI18N\n                \n                if (!initSelection(false).equals(getSelection())) return true;\n            }\n            return false;\n        }\n        \n        boolean currentSettingsValid() {\n            assert SwingUtilities.isEventDispatchThread();\n            \n            if (ui != null) {\n                if (FilterSelector.FilterName.EXCLUDE_CUSTOM_FILTER.equals(filterName) ||\n                    FilterSelector.FilterName.INCLUDE_CUSTOM_FILTER.equals(filterName))\n                    if (filterValue.isEmpty()) return false;\n            } else {\n                String filter = readFlag(FILTER_CALLS_FLAG, FilterSelector.FilterName.EXCLUDE_JAVA_FILTER.name());\n                if (FilterSelector.FilterName.EXCLUDE_CUSTOM_FILTER.name().equals(filter) ||\n                    FilterSelector.FilterName.INCLUDE_CUSTOM_FILTER.name().equals(filter))\n                    if (readFlag(FILTER_CALLS_VALUE_FLAG, \"\").isEmpty()) return false; // NOI18N\n            }\n            \n            if (getSelection().isEmpty()) return false;\n\n            return true;\n        }\n        \n        HashSet<ClientUtils.SourceCodeSelection> getSelection() {\n            if (selection == null) selection = initSelection(true);\n            return selection;\n        }\n        \n        private FeatureMode.Selection initSelection(final boolean events) {\n            FeatureMode.Selection sel = new FeatureMode.Selection() {\n                protected void changing() { selectionChanging(); }\n                protected void changed() { selectionChanged(); updateSelectionCustomizer(); }\n            };\n            \n            sel.disableEvents();\n            \n            String _sel = readFlag(SELECTION_FLAG, null);\n            if (_sel != null)\n                for (String s : _sel.split(\" \")) // NOI18N\n                    sel.add(ClientUtils.stringToSelection(s));\n            \n            if (events) sel.enableEvents();\n            \n            return sel;\n        }\n        \n        private void saveSelection() {\n            if (selection != null) {\n                StringBuilder b = new StringBuilder();\n                for (ClientUtils.SourceCodeSelection sel : selection) {\n                    b.append(ClientUtils.selectionToString(sel));\n                    b.append(\" \"); // NOI18N\n                }\n                String sel = b.toString();\n                storeFlag(SELECTION_FLAG, sel.isEmpty() ? null : sel);\n            }\n        }\n        \n        \n        // --- UI --------------------------------------------------------------\n        \n        private JComponent ui;\n        private JPanel selectionContent;\n        private JPanel noSelectionContent;\n        private JLabel outgoingLabel;\n        private JCheckBox outgoingChoice;\n        private JLabel outgoingHint;\n        private JSpinner outgoingSpinner;\n        private JButton addSelectionButton;\n        private JButton editSelectionLink;\n        private JButton filterLink;\n        \n        \n        protected abstract int getOutgoingCallsMaximum();\n        \n        protected abstract String noSelectionString();\n        \n        protected abstract String oneSelectionString();\n        \n        protected abstract String multipleSelectionsString(int count);\n        \n        protected abstract Icon getAddIcon();\n        \n        protected abstract String getAddTooltip();\n        \n        protected abstract void performAddSelection();\n        \n        protected abstract void performEditSelection(Component invoker);\n        \n        \n        JComponent getUI() {\n            if (ui == null) {\n                ui = new SettingsPanel();\n                \n                selectionContent = new SettingsPanel();\n\n                editSelectionLink = new JButton() {\n                    public void setText(String text) {\n                        super.setText(Bundle.MethodsFeatureModes_editLink(text));\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        performEditSelection(InstrMethodsMode.this.ui);\n                    }\n                    public Dimension getMinimumSize() {\n                        return getPreferredSize();\n                    }\n                    public Dimension getMaximumSize() {\n                        return getPreferredSize();\n                    }\n                };\n                editSelectionLink.setContentAreaFilled(false);\n                editSelectionLink.setBorderPainted(true);\n                editSelectionLink.setMargin(new Insets(0, 0, 0, 0));\n                editSelectionLink.setBorder(BorderFactory.createEmptyBorder());\n                editSelectionLink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n                selectionContent.add(editSelectionLink);\n\n                selectionContent.add(Box.createHorizontalStrut(8));\n\n                Component separator = Box.createHorizontalStrut(1);\n                separator.setBackground(Color.GRAY);\n                if (separator instanceof JComponent) ((JComponent)separator).setOpaque(true);\n                Dimension d = separator.getMaximumSize();\n                d.height = 20;\n                separator.setMaximumSize(d);\n                selectionContent.add(separator);\n                \n                outgoingLabel = new JLabel(Bundle.MethodsFeatureModes_outgoingCalls());\n\n                lastOutgoingSelected = Boolean.parseBoolean(readFlag(OUTGOING_CALLS_ENABLED_FLAG, Boolean.TRUE.toString()));\n                outgoingChoice = new JCheckBox(Bundle.MethodsFeatureModes_outgoingCalls(), lastOutgoingSelected) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        lastOutgoingSelected = isSelected();\n                        updateControls();\n                        settingsChanged();\n                    }\n                };\n                outgoingChoice.setToolTipText(Bundle.MethodsFeatureModes_limitCallTreeToolTip());\n                outgoingChoice.setOpaque(false);\n                selectionContent.add(createStrut(outgoingChoice, 8, true));\n                selectionContent.add(outgoingLabel);\n                selectionContent.add(outgoingChoice);\n                \n                Insets i = outgoingChoice.getBorder().getBorderInsets(outgoingChoice);\n                outgoingLabel.setBorder(BorderFactory.createEmptyBorder(0, i.left, 0, i.right));\n\n                selectionContent.add(createStrut(outgoingChoice, 5, false));\n\n                outgoingHint = new GrayLabel(Bundle.MethodsFeatureModes_unlimitedCalls());\n                outgoingHint.setEnabled(false);\n                outgoingHint.setVisible(!outgoingChoice.isSelected());\n                selectionContent.add(outgoingHint);\n\n                int outgoingCalls = Integer.parseInt(readFlag(OUTGOING_CALLS_FLAG, OUTGOING_CALLS_DEFAULT.toString()));\n                outgoingSpinner = new JExtendedSpinner(new SpinnerNumberModel(outgoingCalls, 1, getOutgoingCallsMaximum(), 1)) {\n                    public Dimension getPreferredSize() { return getMinimumSize(); }\n                    public Dimension getMaximumSize() { return getMinimumSize(); }\n                    protected void fireStateChanged() { settingsChanged(); super.fireStateChanged(); }\n                };\n                outgoingSpinner.setToolTipText(Bundle.MethodsFeatureModes_limitCallTreeToolTip());\n                outgoingSpinner.setVisible(outgoingChoice.isSelected());\n                selectionContent.add(outgoingSpinner);\n                \n                selectionContent.add(Box.createHorizontalStrut(10));\n                if (UIUtils.isOracleLookAndFeel()) selectionContent.add(Box.createHorizontalStrut(4));\n\n                JLabel filterLabel = new JLabel(Bundle.MethodsFeatureModes_filterOutgoingCalls());\n                filterLabel.setToolTipText(Bundle.MethodsFeatureModes_filterOutgoingTooltip());\n                selectionContent.add(filterLabel);\n                \n                selectionContent.add(createStrut(filterLabel, 5, false));\n\n                filterLink = new JButton() {\n                    public void setText(String text) {\n                        super.setText(Bundle.MethodsFeatureModes_editLink(text));\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        performEditFilter(this);\n                    }\n                    public Dimension getMinimumSize() {\n                        return getPreferredSize();\n                    }\n                    public Dimension getMaximumSize() {\n                        return getPreferredSize();\n                    }\n                };\n                filterLink.setContentAreaFilled(false);\n                filterLink.setBorderPainted(true);\n                filterLink.setMargin(new Insets(0, 0, 0, 0));\n                filterLink.setBorder(BorderFactory.createEmptyBorder());\n                filterLink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n                selectionContent.add(filterLink);\n                updateControls();\n\n                noSelectionContent = new SettingsPanel();\n\n                GrayLabel noSelectionHint = new GrayLabel(noSelectionString());\n                noSelectionHint.setEnabled(false);\n                noSelectionContent.add(noSelectionHint);\n\n                noSelectionContent.add(Box.createHorizontalStrut(5));\n\n                addSelectionButton = new SmallButton(getAddIcon()) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        performAddSelection();\n                    }\n                    public Dimension getMinimumSize() {\n                        return getPreferredSize();\n                    }\n                    public Dimension getMaximumSize() {\n                        return getPreferredSize();\n                    }\n                };\n                addSelectionButton.setToolTipText(getAddTooltip());\n                noSelectionContent.add(addSelectionButton);\n                updateSelectionCustomizer();\n            }\n            return ui;\n        }\n        \n        private void updateSelectionCustomizer() {\n            if (ui != null) {\n                int count = getSelection().size();\n                \n                JPanel content = count == 0 ? noSelectionContent : selectionContent;\n                if (ui.getComponentCount() > 0 && content == ui.getComponent(0)) content = null;\n                \n                if (count > 0) editSelectionLink.setText(count == 1 ? oneSelectionString() :\n                                                         multipleSelectionsString(count));\n                \n                if (content != null) {\n                    ui.removeAll();\n                    ui.add(content);\n                    ui.doLayout();\n                    ui.repaint();\n                }\n            }\n        }\n        \n        private void updateControls() {\n            boolean outgoingRequired = FilterSelector.FilterName.NO_FILTER.equals(filterName) ||\n                                       FilterSelector.FilterName.EXCLUDE_JAVA_FILTER.equals(filterName);\n            outgoingLabel.setVisible(outgoingRequired);\n            outgoingChoice.setVisible(!outgoingRequired);\n            \n            if (outgoingRequired) outgoingChoice.setSelected(true);\n            else outgoingChoice.setSelected(lastOutgoingSelected);\n            \n            boolean outgoingDefined = outgoingChoice.isSelected();\n            outgoingSpinner.setVisible(outgoingDefined);\n            outgoingHint.setVisible(!outgoingDefined);\n            \n            filterLink.setText(filterName.toString());\n        }\n        \n        private void performEditFilter(Component invoker) {\n            new FilterSelector() {\n                protected void filterChanged(FilterSelector.FilterName filterName, String filterValue) {\n                    InstrMethodsMode.this.filterName = filterName;\n                    InstrMethodsMode.this.filterValue = filterValue;\n                    updateControls();\n                    settingsChanged();\n                }\n            }.show(invoker.getParent(), filterName, filterValue);\n        }\n        \n    }\n    \n    static abstract class SelectedClassesMode extends InstrMethodsMode {\n        \n        abstract void selectForProfiling(Collection<SourceClassInfo> classInfos);\n        \n        \n        String getID() {\n            return \"SelectedClassesMode\"; // NOI18N\n        }\n\n        String getName() {\n            return Bundle.MethodsFeatureModes_selectedClasses();\n        }\n        \n        \n        protected int getOutgoingCallsMaximum() {\n            return 10;\n        }\n        \n        protected String noSelectionString() {\n            return Bundle.MethodsFeatureModes_noClassSelected();\n        }\n        \n        protected String oneSelectionString() {\n            return Bundle.MethodsFeatureModes_oneClassSelected();\n        }\n        \n        protected String multipleSelectionsString(int count) {\n            return Bundle.MethodsFeatureModes_multipleClassesSelected(count);\n        }\n        \n        \n        protected Icon getAddIcon() {\n            String iconMask = LanguageIcons.CLASS;\n            Image baseIcon = Icons.getImage(iconMask);\n            Image addBadge = Icons.getImage(GeneralIcons.BADGE_ADD);\n            Image addImage = ImageUtilities.mergeImages(baseIcon, addBadge, 0, 0);\n            return ImageUtilities.image2Icon(addImage);\n        }\n        \n        protected String getAddTooltip() {\n            return Bundle.MethodsFeatureModes_addClass();\n        }\n        \n        \n        protected void performAddSelection() {\n            selectForProfiling(ClassMethodSelector.selectClasses(getSession()));\n        }\n        \n        protected void performEditSelection(Component invoker) {\n            ClassMethodList.showClasses(getSession(), getSelection(), invoker);\n        }\n        \n    }\n    \n    static abstract class SelectedMethodsMode extends InstrMethodsMode {\n        \n        abstract void selectForProfiling(Collection<SourceMethodInfo> methodInfos);\n        \n        \n        String getID() {\n            return \"SelectedMethodsMode\"; // NOI18N\n        }\n\n        String getName() {\n            return Bundle.MethodsFeatureModes_selectedMethods();\n        }\n        \n        \n        protected int getOutgoingCallsMaximum() {\n            return 99;\n        }\n        \n        protected String noSelectionString() {\n            return Bundle.MethodsFeatureModes_noMethodSelected();\n        }\n        \n        protected String oneSelectionString() {\n            return Bundle.MethodsFeatureModes_oneMethodSelected();\n        }\n        \n        protected String multipleSelectionsString(int count) {\n            return Bundle.MethodsFeatureModes_multipleMethodsSelected(count);\n        }\n        \n        \n        protected Icon getAddIcon() {\n            String iconMask = LanguageIcons.METHOD;\n            Image baseIcon = Icons.getImage(iconMask);\n            Image addBadge = Icons.getImage(GeneralIcons.BADGE_ADD);\n            Image addImage = ImageUtilities.mergeImages(baseIcon, addBadge, 0, 0);\n            return ImageUtilities.image2Icon(addImage);\n        }\n        \n        protected String getAddTooltip() {\n            return Bundle.MethodsFeatureModes_addMethod();\n        }\n        \n        \n        protected void performAddSelection() {\n            selectForProfiling(ClassMethodSelector.selectMethods(getSession()));\n        }\n        \n        protected void performEditSelection(Component invoker) {\n            ClassMethodList.showMethods(getSession(), getSelection(), invoker);\n        }\n        \n    }\n    \n    \n    static abstract class CustomClassesMode extends MethodsMode {\n        \n        private static final String CLASSES_FLAG = \"CLASSES_FLAG\"; // NOI18N\n        private static final String FILTER_FLAG = \"FILTER_FLAG\"; // NOI18N\n        private static final String FILTER_MODE_FLAG = \"FILTER_MODE_FLAG\"; // NOI18N\n        \n        private static final int MIN_ROWS = 2;\n        private static final int MAX_ROWS = 15;\n        private static final int DEFAULT_ROWS = 3;\n        private static final int MIN_COLUMNS = 10;\n        private static final int MAX_COLUMNS = 100;\n        private static final int DEFAULT_COLUMNS = 40;\n        \n        private JComponent ui;\n        private TextArea classesArea;\n        private TextArea filterArea;\n        private JRadioButton includeChoice;\n        private JRadioButton excludeChoice;\n        \n\n        String getID() {\n            return \"CustomMethodsMode\"; // NOI18N\n        }\n\n        String getName() {\n            return Bundle.MethodsFeatureModes_definedClasses();\n        }\n        \n        void configureSettings(ProfilingSettings settings) {\n            assert SwingUtilities.isEventDispatchThread();\n            \n            super.configureSettings(settings);            \n            \n            settings.setProfilingType(ProfilingSettings.PROFILE_CPU_PART);\n            settings.setCPUProfilingType(settings.getSamplingInterval() <= 0 ?\n                                         CommonConstants.CPU_INSTR_FULL :\n                                         CommonConstants.CPU_INSTR_SAMPLED);\n            \n            String[] rootsLines = readFlag(CLASSES_FLAG, \"\").split(\"\\\\n\"); // NOI18N\n            String[] rootsValues = GenericFilter.values(getFlatValues(rootsLines));\n            ClientUtils.SourceCodeSelection[] roots = (rootsValues.length == 1 && rootsValues[0].isEmpty()) ?\n                new ClientUtils.SourceCodeSelection[0] :\n                new ClientUtils.SourceCodeSelection[rootsValues.length];\n            for (int i = 0; i < roots.length; i++)\n                roots[i] = new ClientUtils.SourceCodeSelection(rootsValues[i], \"*\", null); // NOI18N\n            settings.addRootMethods(roots);\n            \n            String filter = readFlag(FILTER_FLAG, \"\"); // NOI18N\n            if (filter.isEmpty() || \"*\".equals(filter) || \"**\".equals(filter)) { // NOI18N\n                settings.setInstrumentationFilter(new JavaTypeFilter());\n            } else {\n                int filterType = Boolean.parseBoolean(readFlag(FILTER_MODE_FLAG, Boolean.TRUE.toString())) == true ?\n                                 JavaTypeFilter.TYPE_INCLUSIVE : JavaTypeFilter.TYPE_EXCLUSIVE;\n                String filterValue = getFlatValues(filter.split(\"\\\\n\")); // NOI18N\n                settings.setInstrumentationFilter(new JavaTypeFilter(filterValue, filterType));\n            }\n            \n            settings.setStackDepthLimit(Integer.MAX_VALUE);\n        }\n\n        void confirmSettings() {\n            if (ui != null) {\n                assert SwingUtilities.isEventDispatchThread();\n                \n                String classes = classesArea.showsHint() ? \"\" : // NOI18N\n                                 classesArea.getText().trim();\n                storeFlag(CLASSES_FLAG, classes.isEmpty() ? null : classes);\n                \n                String filter = filterArea.showsHint() ? \"\" : // NOI18N\n                                filterArea.getText().trim();\n                storeFlag(FILTER_FLAG, filter.isEmpty() ? null : filter);\n                \n                boolean filterMode = includeChoice.isSelected();\n                storeFlag(FILTER_MODE_FLAG, filterMode == true ? null : Boolean.FALSE.toString());\n            }\n        }\n\n        boolean pendingChanges() {\n            if (ui != null) {\n                assert SwingUtilities.isEventDispatchThread();\n                \n                String classes = classesArea.showsHint() ? \"\" : // NOI18N\n                                 classesArea.getText().trim();\n                if (!classes.equals(readFlag(CLASSES_FLAG, \"\"))) return true; // NOI18N\n                \n                String filter = filterArea.showsHint() ? \"\" : // NOI18N\n                                filterArea.getText().trim();\n                if (!filter.equals(readFlag(FILTER_FLAG, \"\"))) return true; // NOI18N\n                \n                if (Boolean.parseBoolean(readFlag(FILTER_MODE_FLAG, Boolean.TRUE.toString())) != includeChoice.isSelected())\n                    return true;\n            }\n            return false;\n        }\n\n        boolean currentSettingsValid() {\n            assert SwingUtilities.isEventDispatchThread();\n            \n            if (ui != null) {\n                if (classesArea.showsHint() || classesArea.getText().trim().isEmpty()) return false;\n            } else {\n                if (readFlag(CLASSES_FLAG, \"\").isEmpty()) return false; // NOI18N\n            }\n            \n            return true;\n        }\n\n        JComponent getUI() {\n            if (ui == null) {\n                JPanel p = new JPanel(new GridBagLayout());\n                p.setOpaque(false);\n                \n                GridBagConstraints c;\n        \n                JPanel classesPanel = new SettingsPanel();\n                classesPanel.add(new JLabel(Bundle.MethodsFeatureModes_classesLbl()));\n                c = new GridBagConstraints();\n                c.gridx = 0;\n                c.gridy = 0;\n                c.fill = GridBagConstraints.NONE;\n                c.insets = new Insets(0, 0, 0, 5);\n                c.anchor = GridBagConstraints.NORTHWEST;\n                p.add(classesPanel, c);\n                \n                class Resizer {\n                    \n                    private TextArea area1, area2;\n                    private JComponent container1, container2;\n                    \n                    void setContext(TextArea area1, TextArea area2, JComponent container1, JComponent container2) {\n                        this.area1 = area1; this.area2 = area2;\n                        this.container1 = container1; this.container2 = container2;\n                    }\n                    \n                    void resize() {\n                        area1.setColumns(readColumns1());\n                        area2.setColumns(readColumns2());\n                        \n                        int rows = readRows();\n                        area1.setRows(rows);\n                        area2.setRows(rows);\n                        \n                        area1.invalidate();\n                        area2.invalidate();\n                        \n                        container1.setPreferredSize(null);\n                        container1.setPreferredSize(container1.getPreferredSize());\n                        container1.setMinimumSize(container1.getPreferredSize());\n                        \n                        container2.setPreferredSize(null);\n                        container2.setPreferredSize(container2.getPreferredSize());\n                        container2.setMinimumSize(container2.getPreferredSize());\n                        \n                        JComponent root = SwingUtilities.getRootPane(container1);\n                        root.doLayout();\n                        root.repaint();\n                        \n                        area1.setColumns(0);\n                        area2.setColumns(0);\n                    }\n                    \n                }\n                final Resizer resizer = new Resizer();\n                \n                classesArea = new TextArea(readFlag(CLASSES_FLAG, \"\")) { // NOI18N\n                    protected void changed() {\n                        settingsChanged();\n                    }\n                    protected boolean changeSize(boolean vertical, boolean direction) {\n                        if (vertical) {\n                            int rows = readRows();\n                            if (direction) rows = Math.min(rows + 1, MAX_ROWS);\n                            else rows = Math.max(rows - 1, MIN_ROWS);\n                            storeRows(rows);\n                        } else {\n                            int cols = readColumns1();\n                            if (direction) cols = Math.min(cols + 3, MAX_COLUMNS);\n                            else cols = Math.max(cols - 3, MIN_COLUMNS);\n                            storeColumns1(cols);\n                        }\n                        \n                        resizer.resize();\n                        return true;\n                    }\n                    protected boolean resetSize() {\n                        storeRows(DEFAULT_ROWS);\n                        storeColumns1(DEFAULT_COLUMNS);\n                \n                        resizer.resize();\n                        return true;\n                    }\n                    protected void customizePopup(JPopupMenu popup) {\n                        popup.addSeparator();\n                        popup.add(createResizeMenu());\n                    }\n                    public Point getToolTipLocation(MouseEvent event) {\n                        Component scroll = getParent().getParent();\n                        return SwingUtilities.convertPoint(scroll, 0, scroll.getHeight(), this);\n                    }\n                };\n                classesArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, classesArea.getFont().getSize()));\n                classesArea.setRows(readRows());\n                classesArea.setColumns(readColumns1());\n                JScrollPane classesScroll = new JScrollPane(classesArea);\n                classesScroll.setPreferredSize(classesScroll.getPreferredSize());\n                classesScroll.setMinimumSize(classesScroll.getPreferredSize());\n                classesArea.setColumns(0);\n                classesArea.setHint(Bundle.MethodsFeatureModes_classesHint());\n                classesArea.setToolTipText(Bundle.MethodsFeatureModes_classesTooltip());\n                c = new GridBagConstraints();\n                c.gridx = 1;\n                c.gridy = 0;\n                c.gridheight = GridBagConstraints.REMAINDER;\n                c.weightx = 0.5;\n                c.weighty = 1;\n                c.fill = GridBagConstraints.VERTICAL;\n                c.insets = new Insets(0, 0, 0, 10);\n                c.anchor = GridBagConstraints.NORTHWEST;\n                p.add(classesScroll, c);\n                \n                boolean filterMode = Boolean.TRUE.toString().equals(readFlag(FILTER_MODE_FLAG, Boolean.TRUE.toString()));\n                ButtonGroup bg = new ButtonGroup();\n                JPanel filterPanel = new SettingsPanel();\n                includeChoice = new JRadioButton(Bundle.MethodsFeatureModes_includeCalls()) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        settingsChanged();\n                    }\n                };\n                includeChoice.setToolTipText(Bundle.MethodsFeatureModes_includeTooltip());\n                Border b = includeChoice.getBorder();\n                Insets i = b != null ? b.getBorderInsets(includeChoice) : null;\n                includeChoice.setOpaque(false);\n                bg.add(includeChoice);\n                includeChoice.setSelected(filterMode);\n                filterPanel.add(includeChoice);\n                c = new GridBagConstraints();\n                c.gridx = 2;\n                c.gridy = 0;\n                c.fill = GridBagConstraints.NONE;\n                c.insets = i == null ? new Insets(0, 0, 0, 0) :\n                           new Insets(0, 1 - i.left, 0, 1 - i.right);\n                c.anchor = GridBagConstraints.NORTHWEST;\n                p.add(filterPanel, c);\n                \n                excludeChoice = new JRadioButton(Bundle.MethodsFeatureModes_excludeCalls()) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        settingsChanged();\n                    }\n                };\n                excludeChoice.setToolTipText(Bundle.MethodsFeatureModes_excludeTooltip());\n                b = excludeChoice.getBorder();\n                i = b != null ? b.getBorderInsets(excludeChoice) : null;\n                excludeChoice.setOpaque(false);\n                bg.add(excludeChoice);\n                excludeChoice.setSelected(!filterMode);\n                c = new GridBagConstraints();\n                c.gridx = 2;\n                c.gridy = 1;\n                c.fill = GridBagConstraints.NONE;\n                c.insets = i == null ? new Insets(0, 0, 0, 0) :\n                           new Insets(1 - i.top, 1 - i.left, 0, 1 - i.right);\n                c.anchor = GridBagConstraints.NORTHWEST;\n                p.add(excludeChoice, c);\n                \n                filterArea = new TextArea(readFlag(FILTER_FLAG, \"\")) { // NOI18N\n                    protected void changed() {\n                        settingsChanged();\n                    }\n                    protected boolean changeSize(boolean vertical, boolean direction) {\n                        if (vertical) {\n                            int rows = readRows();\n                            if (direction) rows = Math.min(rows + 1, MAX_ROWS);\n                            else rows = Math.max(rows - 1, MIN_ROWS);\n                            storeRows(rows);\n                        } else {\n                            int cols = readColumns2();\n                            if (direction) cols = Math.min(cols + 3, MAX_COLUMNS);\n                            else cols = Math.max(cols - 3, MIN_COLUMNS);\n                            storeColumns2(cols);\n                        }\n                        \n                        resizer.resize();               \n                        return true;\n                    }\n                    protected boolean resetSize() {\n                        storeRows(DEFAULT_ROWS);\n                        storeColumns2(DEFAULT_COLUMNS);\n                \n                        resizer.resize();\n                        return true;\n                    }\n                    protected void customizePopup(JPopupMenu popup) {\n                        popup.addSeparator();\n                        popup.add(createResizeMenu());\n                    }\n                    public Point getToolTipLocation(MouseEvent event) {\n                        Component scroll = getParent().getParent();\n                        return SwingUtilities.convertPoint(scroll, 0, scroll.getHeight(), this);\n                    }\n                };\n                filterArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, classesArea.getFont().getSize()));\n                filterArea.setRows(readRows());\n                filterArea.setColumns(readColumns2());\n                JScrollPane filterScroll = new JScrollPane(filterArea);\n                filterScroll.setPreferredSize(filterScroll.getPreferredSize());\n                filterScroll.setMinimumSize(filterScroll.getPreferredSize());\n                filterArea.setColumns(0);\n                filterArea.setHint(Bundle.MethodsFeatureModes_filterHint());\n                filterArea.setToolTipText(Bundle.MethodsFeatureModes_filterTooltip());\n                c = new GridBagConstraints();\n                c.gridx = 3;\n                c.gridy = 0;\n                c.gridheight = GridBagConstraints.REMAINDER;\n                c.weightx = 0.5;\n                c.weighty = 1;\n                c.fill = GridBagConstraints.VERTICAL;\n                c.insets = new Insets(0, 4, 0, 1);\n                c.anchor = GridBagConstraints.NORTHWEST;\n                p.add(filterScroll, c);\n                \n                resizer.setContext(classesArea, filterArea, classesScroll, filterScroll);\n                \n                ui = p;\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { settingsChanged(); }\n                });\n            }\n            return ui;\n        }\n        \n        private int readRows() {\n            return NbPreferences.forModule(MethodsFeatureModes.class).getInt(\"MethodsFeatureModes.rows\", DEFAULT_ROWS); // NOI18N\n        }\n        \n        private void storeRows(int rows) {\n            NbPreferences.forModule(MethodsFeatureModes.class).putInt(\"MethodsFeatureModes.rows\", rows); // NOI18N\n        }\n        \n        private int readColumns1() {\n            return NbPreferences.forModule(MethodsFeatureModes.class).getInt(\"MethodsFeatureModes.columns1\", DEFAULT_COLUMNS); // NOI18N\n        }\n        \n        private void storeColumns1(int columns) {\n            NbPreferences.forModule(MethodsFeatureModes.class).putInt(\"MethodsFeatureModes.columns1\", columns); // NOI18N\n        }\n        \n        private int readColumns2() {\n            return NbPreferences.forModule(MethodsFeatureModes.class).getInt(\"MethodsFeatureModes.columns2\", DEFAULT_COLUMNS); // NOI18N\n        }\n        \n        private void storeColumns2(int columns) {\n            NbPreferences.forModule(MethodsFeatureModes.class).putInt(\"MethodsFeatureModes.columns2\", columns); // NOI18N\n        }\n        \n    }\n    \n    private static String getFlatValues(String[] values) {\n        StringBuilder convertedValue = new StringBuilder();\n\n        for (int i = 0; i < values.length; i++) {\n            String filterValue = values[i].trim();\n            if ((i != (values.length - 1)) && !filterValue.endsWith(\",\")) // NOI18N\n                filterValue = filterValue + \",\"; // NOI18N\n            convertedValue.append(filterValue);\n        }\n\n        return convertedValue.toString();\n    }\n    \n    private static Component createStrut(JComponent c, int width, boolean before) {\n        Border b = c.getBorder();\n        Insets i = b != null ? b.getBorderInsets(c) : null;\n        int w = i == null ? width : Math.max(width - (before ? i.left : i.right), 0);\n        return Box.createHorizontalStrut(w);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/MethodsFeatureUI.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport java.util.Set;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.cpu.LiveCPUView;\nimport org.graalvm.visualvm.lib.ui.cpu.LiveCPUViewUpdater;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.MultiButtonGroup;\nimport org.graalvm.visualvm.lib.profiler.actions.ResetResultsAction;\nimport org.graalvm.visualvm.lib.profiler.actions.TakeSnapshotAction;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n//    \"MethodsFeatureUI_viewHotSpots=Hot spots\",\n//    \"MethodsFeatureUI_viewCallTree=Call tree\",\n//    \"MethodsFeatureUI_viewCombined=Combined\",\n    \"MethodsFeatureUI_selectedMethods=Selected methods\",\n    \"MethodsFeatureUI_liveResults=Results:\",\n    \"MethodsFeatureUI_pauseResults=Pause live results\",\n    \"MethodsFeatureUI_updateResults=Update live results\",\n    \"MethodsFeatureUI_view=View:\",\n    \"MethodsFeatureUI_viewForward=Forward calls\",\n    \"MethodsFeatureUI_viewHotSpots=Hot spots\",\n    \"MethodsFeatureUI_viewReverse=Reverse calls\",\n    \"MethodsFeatureUI_resultsMode=Results mode\",\n    \"MethodsFeatureUI_profilingData=Collected data:\",\n    \"MethodsFeatureUI_snapshot=Snapshot\",\n    \"MethodsFeatureUI_showAbsolute=Show absolute values\",\n    \"MethodsFeatureUI_showDeltas=Show delta values\"\n})\nabstract class MethodsFeatureUI extends FeatureUI {\n    \n    private ProfilerToolbar toolbar;\n    private LiveCPUView cpuView;\n    private LiveCPUViewUpdater updater;\n\n    \n    // --- External implementation ---------------------------------------------\n    \n    abstract Set<ClientUtils.SourceCodeSelection> getClassesSelection();\n    \n    abstract Set<ClientUtils.SourceCodeSelection> getMethodsSelection();\n    \n    abstract void selectForProfiling(ClientUtils.SourceCodeSelection value);\n    \n    abstract Lookup.Provider getProject();\n    \n    abstract ProfilerClient getProfilerClient();\n    \n    abstract void refreshResults();\n    \n    \n    // --- API implementation --------------------------------------------------\n    \n    ProfilerToolbar getToolbar() {\n        if (toolbar == null) initUI();\n        return toolbar;\n    }\n\n    JPanel getResultsUI() {\n        if (cpuView == null) initUI();\n        return cpuView;\n    }\n    \n    boolean hasResultsUI() {\n        return cpuView != null;\n    }\n    \n    void sessionStateChanged(int sessionState) {\n        refreshToolbar(sessionState);\n    }\n    \n    \n    void resetPause() {\n        if (lrPauseButton != null) lrPauseButton.setSelected(false);\n    }\n    \n    void setForceRefresh() {\n        if (updater != null) updater.setForceRefresh(true);\n    }\n    \n    void refreshData() throws ClientUtils.TargetAppOrVMTerminated {\n        if (updater != null) updater.update();\n    }\n    \n    void resetData() {\n        if (lrDeltasButton != null) {\n            lrDeltasButton.setSelected(false);\n            lrDeltasButton.setToolTipText(Bundle.MethodsFeatureUI_showDeltas());\n        }\n        if (cpuView != null) {\n            cpuView.resetData();\n            cpuView.setDiffView(false);\n        }\n    }\n    \n    \n    void cleanup() {\n        if (updater != null) updater.cleanup();\n    }\n    \n    \n    // --- UI ------------------------------------------------------------------\n    \n//    private static enum View { CALL_TREE, HOT_SPOTS, COMBINED }\n    \n    private JLabel lrLabel;\n    private JToggleButton lrPauseButton;\n    private JButton lrRefreshButton;\n    private JToggleButton lrDeltasButton;\n//    private ActionPopupButton lrView;\n    \n    private JLabel pdLabel;\n    private JButton pdSnapshotButton;\n    private JButton pdResetResultsButton;\n    \n    private boolean popupPause;\n    private JToggleButton[] toggles;\n    \n    \n    private void initUI() {\n        \n        assert SwingUtilities.isEventDispatchThread();\n        \n        // --- Results ---------------------------------------------------------\n        \n        cpuView = new LiveCPUView(getMethodsSelection()) {\n//            protected ProfilerClient getProfilerClient() {\n//                return MethodsFeatureUI.this.getProfilerClient();\n//            }\n////            protected boolean isSampling() {\n////                return MethodsFeatureUI.this.getProfilerClient().getCurrentInstrType() == ProfilerClient.INSTR_NONE_SAMPLING;\n////            }\n////            protected void requestResults() throws ClientUtils.TargetAppOrVMTerminated {\n////                MethodsFeatureUI.this.getProfilerClient().forceObtainedResultsDump(true);\n////            }\n////            protected CPUResultsSnapshot getResults() throws ClientUtils.TargetAppOrVMTerminated, CPUResultsSnapshot.NoDataAvailableException {\n////                ProfilerClient client = MethodsFeatureUI.this.getProfilerClient();\n////                return client.getStatus().getInstrMethodClasses() == null ?\n////                       null : client.getCPUProfilingResultsSnapshot(false);\n////            }\n            protected boolean showSourceSupported() {\n                return GoToSource.isAvailable();\n            }\n            protected void showSource(ClientUtils.SourceCodeSelection value) {\n                Lookup.Provider project = getProject();\n                String className = value.getClassName();\n                String methodName = value.getMethodName();\n                String methodSig = value.getMethodSignature();\n                GoToSource.openSource(project, className, methodName, methodSig);\n            }\n            protected void selectForProfiling(ClientUtils.SourceCodeSelection value) {\n                MethodsFeatureUI.this.selectForProfiling(value);\n            }\n            protected void popupShowing() {\n                if (lrPauseButton.isEnabled() && !lrRefreshButton.isEnabled()) {\n                    popupPause = true;\n                    lrPauseButton.setSelected(true);\n                }\n            }\n            protected void popupHidden() {\n                if (lrPauseButton.isEnabled() && popupPause) {\n                    popupPause = false;\n                    lrPauseButton.setSelected(false);\n                }\n            }\n            protected void foundInForwardCalls() {\n                super.foundInForwardCalls();\n                toggles[0].setSelected(true);\n            }\n            protected void foundInHotSpots() {\n                super.foundInHotSpots();\n                toggles[1].setSelected(true);\n            }\n            protected void foundInReverseCalls() {\n                super.foundInReverseCalls();\n                toggles[2].setSelected(true);\n            }\n        };\n        \n        cpuView.putClientProperty(\"HelpCtx.Key\", \"ProfileMethods.HelpCtx\"); // NOI18N\n        \n        updater = new LiveCPUViewUpdater(cpuView, getProfilerClient());\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        lrLabel = new GrayLabel(Bundle.MethodsFeatureUI_liveResults());\n            \n        lrPauseButton = new JToggleButton(Icons.getIcon(GeneralIcons.PAUSE)) {\n            protected void fireItemStateChanged(ItemEvent event) {\n                boolean paused = isSelected();\n                updater.setPaused(paused);\n                if (!paused) refreshResults();\n                refreshToolbar(getSessionState());\n            }\n        };\n        lrPauseButton.setToolTipText(Bundle.MethodsFeatureUI_pauseResults());\n        lrPauseButton.setEnabled(false);\n\n        lrRefreshButton = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                refreshResults();\n            }\n        };\n        lrRefreshButton.setToolTipText(Bundle.MethodsFeatureUI_updateResults());\n        \n        Icon icon = Icons.getIcon(ProfilerIcons.DELTA_RESULTS);\n        lrDeltasButton = new JToggleButton(icon) {\n            protected void fireActionPerformed(ActionEvent e) {\n                if (!cpuView.setDiffView(isSelected())) setSelected(false);\n                setToolTipText(isSelected() ? Bundle.MethodsFeatureUI_showAbsolute() :\n                                              Bundle.MethodsFeatureUI_showDeltas());\n            }\n        };\n        lrDeltasButton.setToolTipText(Bundle.MethodsFeatureUI_showDeltas());\n        \n        MultiButtonGroup group = new MultiButtonGroup();\n        toggles = new JToggleButton[3];\n        \n        JToggleButton forwardCalls = new JToggleButton(Icons.getIcon(ProfilerIcons.NODE_FORWARD)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                cpuView.setView(isSelected(), toggles[1].isSelected(), toggles[2].isSelected());\n                refreshResults();\n            }\n        };\n        forwardCalls.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        forwardCalls.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        forwardCalls.setToolTipText(Bundle.MethodsFeatureUI_viewForward());\n        group.add(forwardCalls);\n        toggles[0] = forwardCalls;\n//        toolbar.add(forwardCalls);\n        forwardCalls.setSelected(true);\n        \n        JToggleButton hotSpots = new JToggleButton(Icons.getIcon(ProfilerIcons.TAB_HOTSPOTS)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                cpuView.setView(toggles[0].isSelected(), isSelected(), toggles[2].isSelected());\n                refreshResults();\n            }\n        };\n        hotSpots.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        hotSpots.putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n        hotSpots.setToolTipText(Bundle.MethodsFeatureUI_viewHotSpots());\n        group.add(hotSpots);\n        toggles[1] = hotSpots;\n//        toolbar.add(hotSpots);\n        hotSpots.setSelected(false);\n        \n        JToggleButton reverseCalls = new JToggleButton(Icons.getIcon(ProfilerIcons.NODE_REVERSE)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                cpuView.setView(toggles[0].isSelected(), toggles[1].isSelected(), isSelected());\n                refreshResults();\n            }\n        };\n        reverseCalls.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        reverseCalls.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n        reverseCalls.setToolTipText(Bundle.MethodsFeatureUI_viewReverse());\n        group.add(reverseCalls);\n        toggles[2] = reverseCalls;\n//        toolbar.add(reverseCalls);\n        reverseCalls.setSelected(false);\n        \n//        Action aCallTree = new AbstractAction() {\n//            { putValue(NAME, Bundle.MethodsFeatureUI_viewCallTree()); }\n//            public void actionPerformed(ActionEvent e) { setView(View.CALL_TREE); }\n//            \n//        };\n//        Action aHotSpots = new AbstractAction() {\n//            { putValue(NAME, Bundle.MethodsFeatureUI_viewHotSpots()); }\n//            public void actionPerformed(ActionEvent e) { setView(View.HOT_SPOTS); }\n//            \n//        };\n//        Action aCombined = new AbstractAction() {\n//            { putValue(NAME, Bundle.MethodsFeatureUI_viewCombined()); }\n//            public void actionPerformed(ActionEvent e) { setView(View.COMBINED); }\n//            \n//        };\n//        lrView = new ActionPopupButton(aCallTree, aHotSpots, aCombined);\n//        lrView.setToolTipText(Bundle.MethodsFeatureUI_resultsMode());\n\n        pdLabel = new GrayLabel(Bundle.MethodsFeatureUI_profilingData());\n\n        pdSnapshotButton = new JButton(TakeSnapshotAction.getInstance());\n        pdSnapshotButton.setHideActionText(true);\n//        pdSnapshotButton.setText(Bundle.MethodsFeatureUI_snapshot());\n\n        pdResetResultsButton = new JButton(ResetResultsAction.getInstance());\n        pdResetResultsButton.setHideActionText(true);\n\n        toolbar = ProfilerToolbar.create(true);\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(lrLabel);\n        toolbar.addSpace(2);\n        toolbar.add(lrPauseButton);\n        toolbar.add(lrRefreshButton);\n        \n        toolbar.addSpace(5);\n        toolbar.add(lrDeltasButton);\n        \n        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n        toolbar.addSpace(5);\n        \n        toolbar.add(new GrayLabel(Bundle.MethodsFeatureUI_view()));\n        toolbar.addSpace(2);\n        toolbar.add(forwardCalls);\n        toolbar.add(hotSpots);\n        toolbar.add(reverseCalls);\n        \n        toolbar.addSpace(5);\n        toolbar.add(cpuView.createThreadSelector());\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(pdLabel);\n        toolbar.addSpace(2);\n        toolbar.add(pdSnapshotButton);\n        toolbar.addSpace(3);\n        toolbar.add(pdResetResultsButton);\n        \n        \n        // --- Sync UI ---------------------------------------------------------\n        \n//        setView(View.HOT_SPOTS);\n        cpuView.setView(true, false, false);\n        sessionStateChanged(getSessionState());\n        \n    }\n    \n    private void refreshToolbar(final int state) {\n        if (toolbar != null) SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n//                boolean running = isRunning(state);\n                boolean running = state == Profiler.PROFILING_RUNNING;\n                lrPauseButton.setEnabled(running);\n                lrRefreshButton.setEnabled(!popupPause && running && lrPauseButton.isSelected());\n                lrDeltasButton.setEnabled(running);\n            }\n        });\n    }\n\n//    private void setView(View view) {\n//        lrView.selectAction(view.ordinal());\n//        \n//        switch (view) {\n//            case HOT_SPOTS:\n//                cpuView.setView(false, true);\n//                break;\n//            case CALL_TREE:\n//                cpuView.setView(true, false);\n//                break;\n//            case COMBINED:\n//                cpuView.setView(true, true);\n//                break;\n//        }\n//        \n//        refreshResults();\n//    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/MonitorFeature.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerFeature;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"MonitorFeature_name=Telemetry\",\n    \"MonitorFeature_description=Monitor CPU and Memory usage, number of threads and loaded classes\"\n})\nfinal class MonitorFeature extends ProfilerFeature.Basic {\n\n    private MonitorFeature(ProfilerSession session) {\n        super(Icons.getIcon(ProfilerIcons.MONITORING), Bundle.MonitorFeature_name(),\n              Bundle.MonitorFeature_description(), 10, session);\n    }\n\n\n    // --- Settings ------------------------------------------------------------\n\n    public void configureSettings(ProfilingSettings settings) {}\n\n\n    // --- Toolbar & Results UI ------------------------------------------------\n\n    private MonitorFeatureUI ui;\n\n    public JPanel getResultsUI() {\n        return getUI().getResultsUI();\n    }\n\n    public ProfilerToolbar getToolbar() {\n        return getUI().getToolbar();\n    }\n\n    private MonitorFeatureUI getUI() {\n        if (ui == null) ui = new MonitorFeatureUI() {\n            int getSessionState() {\n                return MonitorFeature.this.getSessionState();\n            }\n            Profiler getProfiler() {\n                return MonitorFeature.this.getSession().getProfiler();\n            }\n\n            String readFlag(String flag, String defaultValue) {\n                return MonitorFeature.this.readFlag(\"UI_\" + flag, defaultValue); // NOI18N\n            }\n\n            void storeFlag(String flag, String value) {\n                MonitorFeature.this.storeFlag(\"UI_\" + flag, value); // NOI18N\n            }\n        };\n        return ui;\n    }\n    \n    \n    // --- Session lifecycle ---------------------------------------------------\n    \n    public void notifyActivated() {\n        getSession().getProfiler().getVMTelemetryManager().reset();\n    }\n    \n    public void notifyDeactivated() {\n        getSession().getProfiler().getVMTelemetryManager().reset();\n        \n        if (ui != null) {\n            ui.cleanup();\n            ui = null;\n        }\n    }\n    \n    \n    protected void profilingStateChanged(int oldState, int newState) {\n        if (newState == Profiler.PROFILING_STARTED)\n            getSession().getProfiler().getVMTelemetryManager().reset();\n        \n        if (ui != null) ui.sessionStateChanged(getSessionState());\n    }\n    \n    \n    // --- Provider ------------------------------------------------------------\n    \n    @ServiceProvider(service=ProfilerFeature.Provider.class)\n    public static final class Provider extends ProfilerFeature.Provider {\n        public ProfilerFeature getFeature(ProfilerSession session) {\n            return new MonitorFeature(session);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/MonitorFeatureUI.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.monitor.MonitorView;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.MultiButtonGroup;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"MonitorFeatureUI_graphs=View:\",\n    \"MonitorFeatureUI_cpuGraph=CPU and GC\",\n    \"MonitorFeatureUI_memoryGraph=Memory\",\n    \"MonitorFeatureUI_gcGraph=Garbage Collection\",\n    \"MonitorFeatureUI_threadsGraph=Threads and Classes\"\n})\nabstract class MonitorFeatureUI extends FeatureUI {\n\n    private static final String CPU_GRAPH_FLAG = \"CPU_GRAPH_FLAG\"; // NOI18N\n    private static final String MEM_GRAPH_FLAG = \"MEM_GRAPH_FLAG\"; // NOI18N\n    private static final String GC_GRAPH_FLAG = \"GC_GRAPH_FLAG\"; // NOI18N\n    private static final String THCL_GRAPH_FLAG = \"THCL_GRAPH_FLAG\"; // NOI18N\n\n    private ProfilerToolbar toolbar;\n    private MonitorView monitorView;\n\n\n    // --- External implementation ---------------------------------------------\n\n    abstract Profiler getProfiler();\n\n    abstract String readFlag(String flag, String defaultValue);\n\n    abstract void storeFlag(String flag, String value);\n\n\n    // --- API implementation --------------------------------------------------\n\n    ProfilerToolbar getToolbar() {\n        if (toolbar == null) initUI();\n        return toolbar;\n    }\n\n    JPanel getResultsUI() {\n        if (monitorView == null) initUI();\n        return monitorView;\n    }\n    \n    \n    void cleanup() {\n        if (monitorView != null) monitorView.cleanup();\n    }\n    \n    \n    void sessionStateChanged(int sessionState) {\n        refreshToolbar(sessionState);\n    }\n    \n    \n    // --- UI ------------------------------------------------------------------\n    \n    private JLabel grLabel;\n    \n    \n    private void initUI() {\n        \n        assert SwingUtilities.isEventDispatchThread();\n        \n        // --- Results ---------------------------------------------------------\n        \n        monitorView = new MonitorView(getProfiler().getVMTelemetryManager());\n        \n        monitorView.putClientProperty(\"HelpCtx.Key\", \"ProfileTelemetry.HelpCtx\"); // NOI18N\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        MultiButtonGroup group = new MultiButtonGroup();\n\n        toolbar = ProfilerToolbar.create(true);\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        grLabel = new GrayLabel(Bundle.MonitorFeatureUI_graphs());\n        toolbar.add(grLabel);\n        \n        toolbar.addSpace(2);\n        \n        JToggleButton cpuView = new JToggleButton(Icons.getIcon(ProfilerIcons.CPU)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                monitorView.setupCPUView(isSelected());\n            }\n            protected void fireItemStateChanged(ItemEvent event) {\n                super.fireItemStateChanged(event);\n                storeFlag(CPU_GRAPH_FLAG, isSelected() ? null : Boolean.FALSE.toString());\n            }\n        };\n        cpuView.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        cpuView.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        cpuView.setToolTipText(Bundle.MonitorFeatureUI_cpuGraph());\n        group.add(cpuView);\n        boolean cpuGraphVisible = Boolean.parseBoolean(readFlag(CPU_GRAPH_FLAG, Boolean.TRUE.toString()));\n        monitorView.setupCPUView(cpuGraphVisible);\n        cpuView.setSelected(cpuGraphVisible);\n        toolbar.add(cpuView);\n        \n        JToggleButton memoryView = new JToggleButton(Icons.getIcon(ProfilerIcons.MEMORY)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                monitorView.setupMemoryView(isSelected());\n            }\n            protected void fireItemStateChanged(ItemEvent event) {\n                super.fireItemStateChanged(event);\n                storeFlag(MEM_GRAPH_FLAG, isSelected() ? null : Boolean.FALSE.toString());\n            }\n        };\n        memoryView.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        memoryView.putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n        memoryView.setToolTipText(Bundle.MonitorFeatureUI_memoryGraph());\n        group.add(memoryView);\n        boolean memGraphVisible = Boolean.parseBoolean(readFlag(MEM_GRAPH_FLAG, Boolean.TRUE.toString()));\n        monitorView.setupMemoryView(memGraphVisible);\n        memoryView.setSelected(memGraphVisible);\n        toolbar.add(memoryView);\n        \n        JToggleButton gcView = new JToggleButton(Icons.getIcon(ProfilerIcons.RUN_GC)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                monitorView.setupGCView(isSelected());\n            }\n            protected void fireItemStateChanged(ItemEvent event) {\n                super.fireItemStateChanged(event);\n                storeFlag(GC_GRAPH_FLAG, isSelected() ? null : Boolean.FALSE.toString());\n            }\n        };\n        gcView.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        gcView.putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n        gcView.setToolTipText(Bundle.MonitorFeatureUI_gcGraph());\n        group.add(gcView);\n        boolean gcGraphVisible = Boolean.parseBoolean(readFlag(GC_GRAPH_FLAG, Boolean.TRUE.toString()));\n        monitorView.setupGCView(gcGraphVisible);\n        gcView.setSelected(gcGraphVisible);\n        toolbar.add(gcView);\n        \n        JToggleButton threadsView = new JToggleButton(Icons.getIcon(ProfilerIcons.WINDOW_THREADS)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                monitorView.setupThreadsView(isSelected());\n            }\n            protected void fireItemStateChanged(ItemEvent event) {\n                super.fireItemStateChanged(event);\n                storeFlag(THCL_GRAPH_FLAG, isSelected() ? null : Boolean.FALSE.toString());\n            }\n        };\n        threadsView.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        threadsView.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n        threadsView.setToolTipText(Bundle.MonitorFeatureUI_threadsGraph());\n        group.add(threadsView);\n        boolean thclGraphVisible = Boolean.parseBoolean(readFlag(THCL_GRAPH_FLAG, Boolean.TRUE.toString()));\n        monitorView.setupThreadsView(thclGraphVisible);\n        threadsView.setSelected(thclGraphVisible);\n        toolbar.add(threadsView);\n        \n        \n        // --- Sync UI ---------------------------------------------------------\n        \n        sessionStateChanged(getSessionState());\n        \n    }\n    \n    private void refreshToolbar(final int state) {\n//        if (toolbar != null) SwingUtilities.invokeLater(new Runnable() {\n//            public void run() {\n//            }\n//        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/ObjectsFeature.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JRadioButtonMenuItem;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.SmallButton;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.ResultsListener;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.api.ProjectUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceClassInfo;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerFeature;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.WeakProcessor;\nimport org.graalvm.visualvm.lib.profiler.v2.ui.SettingsPanel;\nimport org.graalvm.visualvm.lib.profiler.v2.ui.TitledMenuSeparator;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ObjectsFeature_name=Objects\",\n    \"ObjectsFeature_description=Profile size and count of allocated objects, including allocation paths\",\n    \"ObjectsFeature_profileMode=Profile:\",\n    \"ObjectsFeature_samplingModes=General (sampled)\",\n    \"ObjectsFeature_instrModes=Focused (instrumented)\",\n    \"ObjectsFeature_applyButton=Apply\",\n    \"ObjectsFeature_arrayWarningCaption=Selected Array Warning\",\n    \"#HTML-formatted, line breaks using <br> to make the displaying dialog not too wide\",\n    \"ObjectsFeature_arrayWarningMsg=<html><b>Array object selected for profiling.</b><br><br>Configuring the target application for profiling arrays can<br>take a long time when attaching to a running process or<br>changing the settings during profiling.<br><br></html>\",\n    \"ObjectsFeature_modeReset=<html><b>Current mode ''{0}'' is not configured properly.</b><br><br>Default ''{1}'' mode has been selected and applied instead.<br><br></html>\"\n})\nfinal class ObjectsFeature extends ProfilerFeature.Basic {\n    \n    private final WeakProcessor processor;\n    \n    private FeatureMode currentMode;\n    private FeatureMode appliedMode;\n    \n    private ObjectsFeatureModes.AllClassesMode allClassesMode;\n    private ObjectsFeatureModes.ProjectClassesMode projectClassesMode;\n    private ObjectsFeatureModes.SelectedClassesMode selectedClassesMode;\n    private ObjectsFeatureModes.CustomClassesMode definedClassesMode;\n    \n    \n    private ObjectsFeature(ProfilerSession session) {\n        super(Icons.getIcon(ProfilerIcons.MEMORY), Bundle.ObjectsFeature_name(),\n              Bundle.ObjectsFeature_description(), 13, session);\n        \n        assert !SwingUtilities.isEventDispatchThread();\n        \n        Lookup.Provider project = session.getProject();\n        String projectName = project == null ? \"External Process\" : // NOI18N\n                             ProjectUtilities.getDisplayName(project);\n        processor = new WeakProcessor(\"ObjectsFeature Processor for \" + projectName); // NOI18N\n\n        initModes();\n    }\n    \n    \n    // --- Configuration -------------------------------------------------------\n    \n    public boolean supportsConfiguration(Lookup configuration) {\n        if (configuration.lookup(SourceClassInfo.class) != null) return true;\n        \n        ClientUtils.SourceCodeSelection sel = configuration.lookup(ClientUtils.SourceCodeSelection.class);\n        return sel != null && Wildcards.ALLWILDCARD.equals(sel.getMethodName());\n    }\n    \n    public void configure(Lookup configuration) {\n        // Handle Profile Class action from editor\n        SourceClassInfo classInfo = configuration.lookup(SourceClassInfo.class);\n        if (classInfo != null) selectClassForProfiling(classInfo);\n        \n        // Handle Profile Class action from snapshot\n        ClientUtils.SourceCodeSelection sel = configuration.lookup(ClientUtils.SourceCodeSelection.class);\n        if (sel != null && Wildcards.ALLWILDCARD.equals(sel.getMethodName())) selectForProfiling(sel);\n    }\n    \n    \n    private void selectClassForProfiling(SourceClassInfo classInfo) {\n        selectForProfiling(new ClientUtils.SourceCodeSelection(classInfo.getQualifiedName(),\n                                                               Wildcards.ALLWILDCARD, null));\n    }\n    \n    private void selectForProfiling(ClientUtils.SourceCodeSelection sel) {\n        selectedClassesMode.getSelection().add(sel);\n    }\n    \n    \n    // --- Mode ----------------------------------------------------------------\n    \n    private static final String MODE_FLAG = \"MODE_FLAG\"; // NOI18N\n    \n    private void initModes() {\n        allClassesMode = new ObjectsFeatureModes.AllClassesMode() {\n            String readFlag(String flag, String defaultValue) {\n                return ObjectsFeature.this.readFlag(getID() + \"_\" + flag, defaultValue); // NOI18N\n            }\n            void storeFlag(String flag, String value) {\n                ObjectsFeature.this.storeFlag(getID() + \"_\" + flag, value); // NOI18N\n            }\n            void settingsChanged() {\n                ObjectsFeature.this.settingsChanged();\n            }\n        };\n        \n        if (getSession().getProject() != null) projectClassesMode = new ObjectsFeatureModes.ProjectClassesMode() {\n            String readFlag(String flag, String defaultValue) {\n                return ObjectsFeature.this.readFlag(getID() + \"_\" + flag, defaultValue); // NOI18N\n            }\n            void storeFlag(String flag, String value) {\n                ObjectsFeature.this.storeFlag(getID() + \"_\" + flag, value); // NOI18N\n            }\n            void settingsChanged() {\n                ObjectsFeature.this.settingsChanged();\n            }\n            Lookup.Provider getProject() {\n                return ObjectsFeature.this.getSession().getProject();\n            }\n        };\n        \n        selectedClassesMode = new ObjectsFeatureModes.SelectedClassesMode() {\n            String readFlag(String flag, String defaultValue) {\n                return ObjectsFeature.this.readFlag(getID() + \"_\" + flag, defaultValue); // NOI18N\n            }\n            void storeFlag(String flag, String value) {\n                ObjectsFeature.this.storeFlag(getID() + \"_\" + flag, value); // NOI18N\n            }\n            ProfilerSession getSession() {\n                return ObjectsFeature.this.getSession();\n            }\n            void selectForProfiling(Collection<SourceClassInfo> classInfos) {\n                for (SourceClassInfo classInfo : classInfos)\n                    ObjectsFeature.this.selectClassForProfiling(classInfo);\n            }\n            void settingsChanged() {\n                ObjectsFeature.this.settingsChanged();\n            }\n            void selectionChanging() {\n                ObjectsFeature.this.setMode(this);\n                ObjectsFeature.this.getSettingsUI().setVisible(true);\n            }\n            void selectionChanged() {\n                ObjectsFeature.this.selectionChanged();\n                if (ObjectsFeature.this.ui != null && ObjectsFeature.this.ui.hasResultsUI())\n                    ObjectsFeature.this.ui.getResultsUI().repaint();\n            }\n        };\n        \n        if (ProfilerIDESettings.getInstance().getEnableExpertSettings()) {\n            definedClassesMode = new ObjectsFeatureModes.CustomClassesMode() {\n                String readFlag(String flag, String defaultValue) {\n                    return ObjectsFeature.this.readFlag(getID() + \"_\" + flag, defaultValue); // NOI18N\n                }\n                void storeFlag(String flag, String value) {\n                    ObjectsFeature.this.storeFlag(getID() + \"_\" + flag, value); // NOI18N\n                }\n                void settingsChanged() {\n                    ObjectsFeature.this.settingsChanged();\n                }\n            };\n        }\n        \n//        currentMode = allClassesMode;\n        String _currentMode = readFlag(MODE_FLAG, allClassesMode.getID());\n        if (projectClassesMode != null && _currentMode.equals(projectClassesMode.getID())) currentMode = projectClassesMode;\n        else if (_currentMode.equals(selectedClassesMode.getID())) currentMode = selectedClassesMode;\n        else if (definedClassesMode != null && _currentMode.equals(definedClassesMode.getID())) currentMode = definedClassesMode;\n        else currentMode = allClassesMode;\n        \n        appliedMode = currentMode;\n    }\n    \n    private void saveMode() {\n        storeFlag(MODE_FLAG, currentMode.getID());\n    }\n    \n    private void setMode(FeatureMode newMode) {\n        if (currentMode == newMode) return;\n        currentMode = newMode;\n        modeChanged();\n    }\n    \n    private void confirmMode() {\n        appliedMode = currentMode;\n    }\n    \n    private void modeChanged() {\n        updateModeName();\n        updateModeUI();\n        configurationChanged();\n        saveMode();\n    }\n    \n    \n    // --- Settings ------------------------------------------------------------\n    \n    public boolean supportsSettings(ProfilingSettings psettings) {\n        return !ProfilingSettings.isCPUSettings(psettings) &&\n               !ProfilingSettings.isJDBCSettings(psettings);\n    }\n\n    public void configureSettings(ProfilingSettings psettings) {\n        currentMode.configureSettings(psettings);\n    }\n    \n    public boolean currentSettingsValid() {\n        return currentMode.currentSettingsValid();\n    }\n    \n    private void submitChanges() {\n        confirmMode();\n        confirmSettings();\n        fireChange();\n    }\n    \n    // Changes to current settings are pending\n    private boolean pendingChanges() {\n        if (appliedMode != currentMode) return true;\n        return currentMode.pendingChanges();\n    }\n    \n    // Profiling settings defined by this feature have changed\n    private void configurationChanged() {\n        assert isActivated();\n        \n        ProfilerSession session = getSession();\n        \n        if (!session.inProgress()) submitChanges();\n        else updateApplyButton(session.getState());\n    }\n    \n    private void confirmSettings() {\n        currentMode.confirmSettings();\n    }\n    \n    private void confirmAllSettings() {\n        if (allClassesMode != null) allClassesMode.confirmSettings();\n        if (projectClassesMode != null) projectClassesMode.confirmSettings();\n        if (selectedClassesMode != null) selectedClassesMode.confirmSettings();\n        if (definedClassesMode != null) definedClassesMode.confirmSettings();\n    }\n    \n    private void settingsChanged() {\n        configurationChanged();\n    }\n    \n    private void selectionChanged() {\n        configurationChanged();\n        \n        if (getSession().inProgress() || getSession().isAttach()) checkArrays();\n    }\n    \n    private void checkArrays() {\n        HashSet<ClientUtils.SourceCodeSelection> sel = selectedClassesMode.getSelection();\n        for (ClientUtils.SourceCodeSelection s : sel)\n            if (s.getClassName().endsWith(\"[]\")) { // NOI18N\n                ProfilerDialogs.displayWarningDNSA(Bundle.ObjectsFeature_arrayWarningMsg(),\n                                                   Bundle.ObjectsFeature_arrayWarningCaption(),\n                                                   null, \"ObjectsFeature.arraysDNSA\", true); // NOI18N\n                break;\n            }\n    }\n    \n    \n    // --- Settings UI ---------------------------------------------------------\n    \n    private static final String SETTINGS_FLAG = \"SETTINGS_FLAG\"; // NOI18N\n    \n    private JPanel settingsUI;\n    private JButton modeButton;\n    private JPanel settingsContainer;\n    private JButton applyButton;\n    \n    public JPanel getSettingsUI() {\n        if (settingsUI == null) {\n            settingsUI = new JPanel(new GridBagLayout()) {\n                public void setVisible(boolean visible) {\n                    if (visible && getComponentCount() == 0) populateSettingsUI();\n                    super.setVisible(visible);\n                    storeFlag(SETTINGS_FLAG, visible ? Boolean.TRUE.toString() : null);\n                }\n                public Dimension getPreferredSize() {\n                    if (getComponentCount() == 0) return new Dimension();\n                    else return super.getPreferredSize();\n                }\n            };\n            \n            String _vis = readFlag(SETTINGS_FLAG, null);\n            boolean vis = _vis == null ? false : Boolean.parseBoolean(_vis);\n            settingsUI.setVisible(vis || currentMode != allClassesMode);\n//            settingsUI.setVisible(false);\n        }\n        return settingsUI;\n    }\n    \n    private void populateSettingsUI() {\n        settingsUI.setOpaque(false);\n        settingsUI.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n        \n        GridBagConstraints c;\n        \n        JPanel profilePanel = new SettingsPanel();\n        profilePanel.add(new JLabel(Bundle.ObjectsFeature_profileMode()));\n        profilePanel.add(Box.createHorizontalStrut(5));\n        \n        // Mode button\n        modeButton = new PopupButton(currentMode.getName()) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new TitledMenuSeparator(Bundle.ObjectsFeature_samplingModes()));\n                popup.add(new JRadioButtonMenuItem(allClassesMode.getName(), currentMode == allClassesMode) {\n                    protected void fireActionPerformed(ActionEvent e) { setMode(allClassesMode); }\n                });\n                if (projectClassesMode != null) popup.add(new JRadioButtonMenuItem(projectClassesMode.getName(), currentMode == projectClassesMode) {\n                    protected void fireActionPerformed(ActionEvent e) { setMode(projectClassesMode); }\n                });\n\n                popup.add(new TitledMenuSeparator(Bundle.ObjectsFeature_instrModes()));\n                popup.add(new JRadioButtonMenuItem(selectedClassesMode.getName(), currentMode == selectedClassesMode) {\n                    protected void fireActionPerformed(ActionEvent e) { setMode(selectedClassesMode); }\n                });\n                \n                if (definedClassesMode != null) popup.add(new JRadioButtonMenuItem(definedClassesMode.getName(), currentMode == definedClassesMode) {\n                    protected void fireActionPerformed(ActionEvent e) { setMode(definedClassesMode); }\n                });\n            }\n        };\n        profilePanel.add(modeButton);\n        \n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(0, 0, 0, 0);\n        c.anchor = GridBagConstraints.NORTHWEST;\n        settingsUI.add(profilePanel, c);\n        \n        // Settings container\n        settingsContainer = new JPanel(new BorderLayout());\n        settingsContainer.setOpaque(false);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.fill = GridBagConstraints.VERTICAL;\n        c.insets = new Insets(0, 10, 0, 0);\n        c.anchor = GridBagConstraints.NORTHWEST;\n        settingsUI.add(settingsContainer, c);\n        \n        JPanel buttonsPanel = new SettingsPanel();\n        \n        final Component space = Box.createHorizontalStrut(10);\n        buttonsPanel.add(space);\n        \n        // Apply button\n        applyButton = new SmallButton(Bundle.ObjectsFeature_applyButton()) {\n            protected void fireActionPerformed(ActionEvent e) {\n                stopResults();\n                resetResults();\n                submitChanges();\n                unpauseResults();\n            }\n            public void setVisible(boolean visible) {\n                super.setVisible(visible);\n                space.setVisible(visible);\n            }\n        };\n        buttonsPanel.add(applyButton);\n        \n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 0;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(0, 0, 0, 0);\n        c.anchor = GridBagConstraints.NORTHEAST;\n        settingsUI.add(buttonsPanel, c);\n        \n        updateModeUI();\n        updateApplyButton(getSession().getState());\n    }\n    \n    private void updateModeName() {\n        if (modeButton != null) modeButton.setText(currentMode.getName());\n    }\n    \n    private void updateModeUI() {\n        if (settingsContainer != null) {\n            settingsContainer.removeAll();\n\n            JComponent modeUI = currentMode.getUI();\n            if (modeUI != null) settingsContainer.add(modeUI);\n            settingsContainer.doLayout();\n            settingsContainer.repaint();\n        }\n    }\n    \n    private void updateApplyButton(int state) {\n        if (applyButton != null) {\n            boolean visible = state != Profiler.PROFILING_INACTIVE;\n            applyButton.setVisible(visible);\n            if (visible) applyButton.setEnabled(currentSettingsValid() && pendingChanges());\n        }\n    }\n    \n    \n    // --- Toolbar & Results UI ------------------------------------------------\n    \n    private ObjectsFeatureUI ui;\n    \n    public JPanel getResultsUI() {\n        return getUI().getResultsUI();\n    }\n    \n    public ProfilerToolbar getToolbar() {\n        return getUI().getToolbar();\n    }\n    \n    private ObjectsFeatureUI getUI() {\n        if (ui == null) ui = new ObjectsFeatureUI() {\n            Set<ClientUtils.SourceCodeSelection> getSelection() {\n                return selectedClassesMode.getSelection();\n            }\n            void selectForProfiling(ClientUtils.SourceCodeSelection value) {\n                ObjectsFeature.this.selectForProfiling(value);\n            }\n            Lookup.Provider getProject() {\n                return ObjectsFeature.this.getSession().getProject();\n            }\n            ProfilerClient getProfilerClient() {\n                Profiler profiler = ObjectsFeature.this.getSession().getProfiler();\n                return profiler.getTargetAppRunner().getProfilerClient();\n            }\n            int getSessionState() {\n                return ObjectsFeature.this.getSessionState();\n            }\n            void refreshResults() {\n                ObjectsFeature.this.refreshResults();\n            }\n        };\n        return ui;\n    }\n    \n    \n    // --- Live results --------------------------------------------------------\n    \n    private Runnable refresher;\n    private volatile boolean running;\n    \n    \n    private void startResults() {\n        if (running) return;\n        running = true;\n        \n        refresher = new Runnable() {\n            public void run() {\n                if (running) {\n                    refreshView();\n                    refreshResults(1500);\n                }\n            }\n        };\n        \n        refreshResults(1000);\n    }\n\n    private void refreshView() {\n        if (ui != null && ResultsManager.getDefault().resultsAvailable()) try {\n            // NOTE: might check ProfilerClient.getCurrentInstrType() here if #247827 still occurs\n            ui.refreshData();\n        } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n            stopResults();\n        }\n    }\n    \n    private void refreshResults() {\n        if (running) processor.post(new Runnable() {\n            public void run() {\n                if (ui != null) ui.setForceRefresh();\n                refreshView();\n            }\n        });\n    }\n    \n    private void refreshResults(int delay) {\n        if (running && refresher != null) processor.post(refresher, delay);\n    }\n    \n    private void resetResults() {\n        if (ui != null) ui.resetData();\n    }\n    \n    private void stopResults() {\n        if (refresher != null) {\n            running = false;\n            refresher = null;\n        }\n    }\n    \n    private void unpauseResults() {\n        if (ui != null) ui.resetPause();\n    }\n    \n    \n    // --- Session lifecycle ---------------------------------------------------\n    \n    private ObjectsResetter resetter;\n    \n    public void notifyActivated() {\n        resetResults();\n        \n        resetter = Lookup.getDefault().lookup(ObjectsResetter.class);\n        resetter.controller = this;\n        \n        if (getSession().inProgress() && !currentMode.currentSettingsValid()) {\n            final String oldMode = currentMode.getName();\n            final String newMode = allClassesMode.getName();\n            setMode(allClassesMode);\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    ProfilerDialogs.displayInfo(Bundle.MethodsFeature_modeReset(\n                                                oldMode, newMode));\n                }\n            });\n        }\n    }\n    \n    public void notifyDeactivated() {\n        resetResults();\n        \n        if (resetter != null) {\n            resetter.controller = null;\n            resetter = null;\n        }\n        \n        if (ui != null) {\n            ui.cleanup();\n            ui = null;\n        }\n        \n        settingsUI = null;\n    }\n    \n    \n    protected void profilingStateChanged(int oldState, int newState) {\n        if (newState == Profiler.PROFILING_INACTIVE || newState == Profiler.PROFILING_IN_TRANSITION) {\n            stopResults();\n            confirmAllSettings();\n        } else if (isActivated() && newState == Profiler.PROFILING_RUNNING) {\n            startResults();\n        } else if (newState == Profiler.PROFILING_STARTED) {\n            resetResults();\n            unpauseResults();\n        }\n        \n        if (ui != null) ui.sessionStateChanged(getSessionState());\n        \n        updateApplyButton(newState);\n    }\n    \n    \n    @ServiceProvider(service=ResultsListener.class)\n    public static final class ObjectsResetter implements ResultsListener {\n        private ObjectsFeature controller;\n        public void resultsAvailable() { /*if (controller != null) controller.refreshView();*/ }\n        public void resultsReset() { if (controller != null && controller.ui != null) controller.ui.resetData(); }\n    }\n    \n    \n    // --- Provider ------------------------------------------------------------\n    \n    @ServiceProvider(service=ProfilerFeature.Provider.class)\n    public static final class Provider extends ProfilerFeature.Provider {\n        public ProfilerFeature getFeature(ProfilerSession session) {\n            return new ObjectsFeature(session);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/ObjectsFeatureModes.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Image;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseEvent;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JScrollPane;\nimport javax.swing.JSpinner;\nimport javax.swing.JTextField;\nimport javax.swing.SpinnerNumberModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.border.Border;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.filters.JavaTypeFilter;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedSpinner;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.SmallButton;\nimport org.graalvm.visualvm.lib.ui.swing.TextArea;\nimport org.graalvm.visualvm.lib.profiler.api.ProjectUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceClassInfo;\nimport org.graalvm.visualvm.lib.profiler.api.project.ProjectContentsSupport;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.ClassMethodList;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.ClassMethodSelector;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.ProjectsSelector;\nimport org.graalvm.visualvm.lib.profiler.v2.ui.SettingsPanel;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ObjectsFeatureModes_allClasses=All classes\",\n    \"ObjectsFeatureModes_projectClasses=Project classes\",\n    \"ObjectsFeatureModes_selectedClasses=Selected classes\",\n    \"ObjectsFeatureModes_editLink=<html><a href='#'>{0}, edit</a></html>\",\n    \"ObjectsFeatureModes_selectedProject=Selected {0}\",\n    \"ObjectsFeatureModes_selectedProjects=Selected {0} projects\",\n    \"ObjectsFeatureModes_recordLifecycle=Track only live objects\",\n    \"ObjectsFeatureModes_recordAllocations=Record allocations\",\n    \"ObjectsFeatureModes_limitAllocations=Limit allocations depth:\",\n    \"ObjectsFeatureModes_noClassSelected=No classes selected, use Profile Class action in editor or results or click the Add button:\",\n    \"ObjectsFeatureModes_oneClassSelected=Selected 1 class\",\n    \"ObjectsFeatureModes_multipleClassesSelected=Selected {0} classes\",\n    \"ObjectsFeatureModes_addClass=Select class\",\n    \"ObjectsFeatureModes_lblUnlimited=unlimited\",\n    \"ObjectsFeatureModes_lblNoAllocations=(no allocation calls)\",\n    \"ObjectsFeatureModes_profileAllObjectsToolTip=Unselect to profile all created objects (including already released)\",\n    \"ObjectsFeatureModes_collectFullStacksToolTip=Unselect to collect full depth allocations call tree\",\n    \"ObjectsFeatureModes_limitAllocationsDepthToolTip=Limit depth of allocations call tree (select 0 for no allocation calls)\",\n    \"ObjectsFeatureModes_definedClasses=Defined classes\",\n    \"ObjectsFeatureModes_classesLbl=Classes:\",\n    \"ObjectsFeatureModes_classesHint=org.mypackage.**\\norg.mypackage.*\\norg.mypackage.MyClass\",\n    \"ObjectsFeatureModes_classesTooltip=<html>Define the classes to be profiled:<br><br>\"\n            + \"<code>&nbsp;org.mypackage.**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package and subpackages<br>\"\n            + \"<code>&nbsp;org.mypackage.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package<br>\"\n            + \"<code>&nbsp;org.mypackage.MyClass&nbsp;&nbsp;</code>single class<br><br>\"\n            + \"Special cases:<br><br>\"\n            + \"<code>&nbsp;char[]&nbsp;&nbsp;</code>primitive array<br>\"\n            + \"<code>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes<br>\"\n            + \"<code>&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>(on a separate line) include arrays matching the filter<br></html>\"\n})\nfinal class ObjectsFeatureModes {\n    \n    private static abstract class MemoryMode extends FeatureMode {\n        \n        void configureSettings(ProfilingSettings settings) {\n        }\n        \n    }\n    \n    private static abstract class SampledMemoryMode extends MemoryMode {\n        \n        void configureSettings(ProfilingSettings settings) {\n            super.configureSettings(settings);\n            \n            settings.setProfilingType(ProfilingSettings.PROFILE_MEMORY_SAMPLING);\n        }\n        \n        void confirmSettings() {}\n        \n        boolean pendingChanges() { return false; }\n\n        boolean currentSettingsValid() { return true; }\n        \n        JComponent getUI() { return null; }\n        \n    }\n    \n    static abstract class AllClassesMode extends SampledMemoryMode {\n        \n        String getID() {\n            return \"AllClassesMode\"; // NOI18N\n        }\n\n        String getName() {\n            return Bundle.ObjectsFeatureModes_allClasses();\n        }\n\n        void configureSettings(ProfilingSettings settings) {\n            super.configureSettings(settings);\n            \n            settings.setInstrumentationFilter(new JavaTypeFilter());\n        }\n        \n    }\n    \n    static abstract class ProjectClassesMode extends SampledMemoryMode {\n        \n        private final Collection<Lookup.Provider> selectedProjects;\n        \n        // --- External implementation -----------------------------------------\n        \n        abstract Lookup.Provider getProject();\n        \n        \n        // --- API implementation ----------------------------------------------\n        \n        private static final String PROJECTS_FLAG = \"PROJECTS_FLAG\"; // NOI18N\n        \n        ProjectClassesMode() {\n            selectedProjects = new HashSet();\n            \n            Collection<File> files = createFilesFromStorage();\n            if (files.isEmpty()) {\n                selectedProjects.add(getProject());\n            } else {\n                for (File file : files) if (file.exists()) {\n                    FileObject fo = FileUtil.toFileObject(FileUtil.normalizeFile(file));\n                    Lookup.Provider project = fo == null ? null : ProjectUtilities.getProject(fo);\n                    if (fo != null) selectedProjects.add(project);\n                }\n                verifySelectedProjects(false);\n            }\n        }\n        \n        String getID() {\n            return \"ProjectClassesMode\"; // NOI18N\n        }\n\n        String getName() {\n            return Bundle.ObjectsFeatureModes_projectClasses();\n        }\n        \n        void configureSettings(ProfilingSettings settings) {\n            super.configureSettings(settings);\n            \n            StringBuilder filter = new StringBuilder();\n            \n            for (Lookup.Provider project : selectedProjects) {\n                ProjectContentsSupport pcs = ProjectContentsSupport.get(project);\n                filter.append(pcs.getInstrumentationFilter(false));\n                filter.append(\" \"); // NOI18N\n                pcs.reset();\n            }\n            \n            String s  = filter.toString().replace(\". \", \".* \").replace(\".,\", \".*,\").trim(); // NOI18N\n            JavaTypeFilter f = new JavaTypeFilter(s, JavaTypeFilter.TYPE_INCLUSIVE);\n            settings.setInstrumentationFilter(f);\n        }\n        \n        void confirmSettings() {\n            if (ui != null) {\n                assert SwingUtilities.isEventDispatchThread();\n                                \n                saveSelection();\n            }\n        }\n        \n        boolean pendingChanges() {\n            if (ui != null) {\n                assert SwingUtilities.isEventDispatchThread();\n                \n                if (!filesEquals(createFilesFromSelection(), createFilesFromStorage())) return true;\n            }\n            return false;\n        }\n        \n        boolean currentSettingsValid() {\n            assert SwingUtilities.isEventDispatchThread();\n            \n            if (selectedProjects.isEmpty()) return false;\n            \n            return true;\n        }\n        \n        \n        private void saveSelection() {\n            Collection<File> files = createFilesFromSelection();\n            if (files.isEmpty()) {\n                storeFlag(PROJECTS_FLAG, null);\n            } else {\n                StringBuilder sb = new StringBuilder();\n                for (File file : files) {\n                    try {\n                        sb.append(file.getCanonicalPath());\n                    } catch (IOException ex) {\n                        sb.append(file.getAbsolutePath());\n                    }\n                    sb.append(File.pathSeparatorChar);\n                }\n                storeFlag(PROJECTS_FLAG, sb.toString());\n            }\n        }\n        \n        private Collection<File> createFilesFromStorage() {\n            Set<File> files = new HashSet();\n            \n            String s = readFlag(PROJECTS_FLAG, null);\n            if (s != null) {\n                String[] sa = s.split(File.pathSeparator);\n                for (String _s : sa) files.add(new File(_s));\n            }\n            \n            return files;\n        }\n        \n        private Collection<File> createFilesFromSelection() {\n            Set<File> files = new HashSet();\n            \n            if (selectedProjects.size() > 1 || !selectedProjects.contains(getProject()))\n                for (Lookup.Provider project : selectedProjects)\n                    files.add(FileUtil.toFile(ProjectUtilities.getProjectDirectory(project)));\n            \n            return files;\n        }\n        \n        private boolean filesEquals(Collection<File> files1, Collection<File> files2) {\n            if (files1.size() != files2.size()) return false;\n            for (File file1 : files1) if (!files2.contains(file1)) return false;\n            return true;\n        }\n        \n        // NOTE: must be executed in EDT except of calling from constructor (populating selectedProjects)\n        private void verifySelectedProjects(boolean refreshLink) {\n            if (selectedProjects.size() == 1 && selectedProjects.contains(getProject())) return;\n            \n            List<Lookup.Provider> projects = Arrays.asList(ProjectUtilities.getOpenedProjects());\n            Iterator<Lookup.Provider> iterator = selectedProjects.iterator();\n            while (iterator.hasNext()) if (!projects.contains(iterator.next())) iterator.remove();\n            \n            if (selectedProjects.isEmpty()) selectedProjects.add(getProject());\n            \n            if (refreshLink) refreshProjectsLink();\n        }\n        \n        \n        JComponent getUI() {\n            if (ui == null) {\n                final ChangeListener projectsListener = new ChangeListener() {\n                    public void stateChanged(ChangeEvent e) {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() { verifySelectedProjects(true); }\n                        });\n                    }\n                };\n                ui = new SettingsPanel() {\n                    public void addNotify() {\n                        super.addNotify();\n                        ProjectUtilities.addOpenProjectsListener(projectsListener);\n                    }\n                    public void removeNotify() {\n                        ProjectUtilities.removeOpenProjectsListener(projectsListener);\n                        super.removeNotify();\n                    }\n                };\n                \n                editProjectLink = new JButton() {\n                    public void setText(String text) {\n                        super.setText(Bundle.MethodsFeatureModes_editLink(text));\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        performEditProject();\n                    }\n                    public Dimension getMinimumSize() {\n                        return getPreferredSize();\n                    }\n                    public Dimension getMaximumSize() {\n                        return getPreferredSize();\n                    }\n                };\n                editProjectLink.setContentAreaFilled(false);\n                editProjectLink.setBorderPainted(true);\n                editProjectLink.setMargin(new Insets(0, 0, 0, 0));\n                editProjectLink.setBorder(BorderFactory.createEmptyBorder());\n                editProjectLink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n                refreshProjectsLink();\n                ui.add(editProjectLink);\n            }\n            return ui;\n        }\n        \n        \n        private void performEditProject() {\n            new ProjectsSelector(selectedProjects) {\n                protected void selectionChanged(Collection<Lookup.Provider> selected) {\n                    selectedProjects.clear();\n                    selectedProjects.addAll(selected);\n                    refreshProjectsLink();\n                    settingsChanged();\n                }\n            }.show(ui);\n        }\n        \n        private void refreshProjectsLink() {\n            if (editProjectLink == null) return;\n            if (selectedProjects.size() == 1)\n                editProjectLink.setText(Bundle.MethodsFeatureModes_selectedProject(\n                                        ProjectUtilities.getDisplayName(selectedProjects.\n                                        iterator().next())));\n            else editProjectLink.setText(Bundle.MethodsFeatureModes_selectedProjects(\n                                        selectedProjects.size()));\n        }\n        \n        \n        private JComponent ui;\n        private JButton editProjectLink;\n        \n    }\n    \n    static abstract class SelectedClassesMode extends MemoryMode {\n        \n        // --- External implementation -----------------------------------------\n        \n        abstract void selectionChanging();\n        \n        abstract void selectionChanged();\n        \n        abstract ProfilerSession getSession();\n        \n        abstract void selectForProfiling(Collection<SourceClassInfo> classInfos);\n        \n        \n        // --- API implementation ----------------------------------------------\n        \n        private static final String LIFECYCLE_FLAG = \"LIFECYCLE_FLAG\"; // NOI18N\n        private static final String ALLOCATIONS_FLAG = \"ALLOCATIONS_FLAG\"; // NOI18N\n        private static final String LIMIT_ALLOCATIONS_FLAG = \"LIMIT_ALLOCATIONS_FLAG\"; // NOI18N\n        private static final String SELECTION_FLAG = \"SELECTION_FLAG\"; // NOI18N\n        \n        private static final Integer LIMIT_ALLOCATIONS_DEFAULT = 10;\n        \n        private Selection selection;\n        \n        \n        String getID() {\n            return \"SelectedClassesMode\"; // NOI18N\n        }\n\n        String getName() {\n            return Bundle.ObjectsFeatureModes_selectedClasses();\n        }\n\n        void configureSettings(ProfilingSettings settings) {\n            assert SwingUtilities.isEventDispatchThread();\n            \n            super.configureSettings(settings);\n            \n            boolean lifecycle = Boolean.parseBoolean(readFlag(LIFECYCLE_FLAG, Boolean.TRUE.toString()));\n            settings.setProfilingType(lifecycle ? ProfilingSettings.PROFILE_MEMORY_LIVENESS :\n                                                  ProfilingSettings.PROFILE_MEMORY_ALLOCATIONS);\n\n            boolean alloc = Boolean.parseBoolean(readFlag(ALLOCATIONS_FLAG, Boolean.TRUE.toString()));\n            int limit = Integer.parseInt(readFlag(LIMIT_ALLOCATIONS_FLAG, LIMIT_ALLOCATIONS_DEFAULT.toString()));\n            settings.setAllocStackTraceLimit(!alloc ? -10 : limit); // TODO: should follow limit from Options\n\n            StringBuilder b = new StringBuilder();\n            HashSet<ClientUtils.SourceCodeSelection> _sel = getSelection();\n            ClientUtils.SourceCodeSelection[] classes = _sel.toArray(new ClientUtils.SourceCodeSelection[0]);\n            for (int i = 0; i < classes.length; i++) {\n                b.append(classes[i].getClassName());\n                if (i < classes.length - 1) b.append(\", \"); // NOI18N\n            }\n\n            JavaTypeFilter ff = new JavaTypeFilter(b.toString(), JavaTypeFilter.TYPE_INCLUSIVE);\n            settings.setInstrumentationFilter(ff);\n        }\n        \n        void confirmSettings() {\n            if (ui != null) {\n                assert SwingUtilities.isEventDispatchThread();\n                \n                storeFlag(LIFECYCLE_FLAG,   lifecycleCheckbox.isSelected() ?\n                                            null : Boolean.FALSE.toString());\n                storeFlag(ALLOCATIONS_FLAG, outgoingCheckbox.isSelected() ?\n                                            null : Boolean.FALSE.toString());\n                Integer limit = ((Integer)outgoingSpinner.getValue());\n                boolean deflimit = LIMIT_ALLOCATIONS_DEFAULT.equals(limit);\n                storeFlag(LIMIT_ALLOCATIONS_FLAG, deflimit ? null : limit.toString());\n                saveSelection();\n            }\n        }\n        \n        boolean pendingChanges() {\n            if (ui != null) {\n                assert SwingUtilities.isEventDispatchThread();\n                \n                boolean lifecycle = lifecycleCheckbox.isSelected();\n                boolean _lifecycle = Boolean.parseBoolean(readFlag(LIFECYCLE_FLAG, Boolean.TRUE.toString()));\n                if (lifecycle != _lifecycle) return true;\n                \n                boolean alloc = outgoingCheckbox.isSelected();\n                boolean _alloc = Boolean.parseBoolean(readFlag(ALLOCATIONS_FLAG, Boolean.TRUE.toString()));\n                if (alloc != _alloc) return true;\n                \n                int limit = Integer.parseInt(readFlag(LIMIT_ALLOCATIONS_FLAG, LIMIT_ALLOCATIONS_DEFAULT.toString()));\n                int _limit = (Integer)outgoingSpinner.getValue();\n                if (limit != _limit) return true;\n                \n                if (!initSelection(false).equals(getSelection())) return true;\n            }\n            return false;\n        }\n\n        boolean currentSettingsValid() {\n            assert SwingUtilities.isEventDispatchThread();\n            \n            if (getSelection().isEmpty()) return false;\n            \n            return true;\n        }\n        \n        HashSet<ClientUtils.SourceCodeSelection> getSelection() {\n            if (selection == null) selection = initSelection(true);\n            return selection;\n        }\n        \n        private Selection initSelection(final boolean events) {\n            Selection sel = new Selection() {\n                protected void changing() { selectionChanging(); }\n                protected void changed() { selectionChanged(); updateSelectionCustomizer(); }\n            };\n            \n            sel.disableEvents();\n            \n            String _sel = readFlag(SELECTION_FLAG, null);\n            if (_sel != null)\n                for (String s : _sel.split(\" \")) // NOI18N\n                    sel.add(ClientUtils.stringToSelection(s));\n            \n            if (events) sel.enableEvents();\n            \n            return sel;\n        }\n        \n        private void saveSelection() {\n            if (selection != null) {\n                StringBuilder b = new StringBuilder();\n                for (ClientUtils.SourceCodeSelection sel : selection) {\n                    b.append(ClientUtils.selectionToString(sel));\n                    b.append(\" \"); // NOI18N\n                }\n                String sel = b.toString();\n                storeFlag(SELECTION_FLAG, sel.isEmpty() ? null : sel);\n            }\n        }\n        \n        \n        // --- UI --------------------------------------------------------------\n        \n        private JComponent ui;\n        private JPanel selectionContent;\n        private JPanel noSelectionContent;\n        private JCheckBox lifecycleCheckbox;\n        private JButton addSelectionButton;\n        private JButton editSelectionLink;\n        private JCheckBox outgoingCheckbox;\n        private JSpinner outgoingSpinner;\n        \n        JComponent getUI() {\n            if (ui == null) {\n                ui = new SettingsPanel();\n\n                selectionContent = new SettingsPanel();\n\n                editSelectionLink = new JButton() {\n                    public void setText(String text) {\n                        super.setText(Bundle.ObjectsFeatureModes_editLink(text));\n                    }\n                    protected void fireActionPerformed(ActionEvent e) {\n                        ClassMethodList.showClasses(getSession(), selection, SelectedClassesMode.this.ui);\n                    }\n                    public Dimension getMinimumSize() {\n                        return getPreferredSize();\n                    }\n                    public Dimension getMaximumSize() {\n                        return getPreferredSize();\n                    }\n                };\n                editSelectionLink.setContentAreaFilled(false);\n                editSelectionLink.setBorderPainted(true);\n                editSelectionLink.setMargin(new Insets(0, 0, 0, 0));\n                editSelectionLink.setBorder(BorderFactory.createEmptyBorder());\n                editSelectionLink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n                selectionContent.add(editSelectionLink);\n\n                selectionContent.add(Box.createHorizontalStrut(8));\n\n                Component separator = Box.createHorizontalStrut(1);\n                separator.setBackground(Color.GRAY);\n                if (separator instanceof JComponent) ((JComponent)separator).setOpaque(true);\n                Dimension d = separator.getMaximumSize();\n                d.height = 20;\n                separator.setMaximumSize(d);\n                selectionContent.add(separator);\n\n                boolean lifecycle = Boolean.parseBoolean(readFlag(LIFECYCLE_FLAG, Boolean.TRUE.toString()));\n                lifecycleCheckbox = new JCheckBox(Bundle.ObjectsFeatureModes_recordLifecycle(), lifecycle) {\n                    protected void fireActionPerformed(ActionEvent e) { super.fireActionPerformed(e); settingsChanged(); }\n                };\n                lifecycleCheckbox.setToolTipText(Bundle.ObjectsFeatureModes_profileAllObjectsToolTip());\n                lifecycleCheckbox.setOpaque(false);\n                selectionContent.add(createStrut(lifecycleCheckbox, 8, true));\n                selectionContent.add(lifecycleCheckbox);\n                \n                selectionContent.add(createStrut(lifecycleCheckbox, 5, false));\n                if (UIUtils.isOracleLookAndFeel()) selectionContent.add(Box.createHorizontalStrut(4));\n                \n                final JLabel unlimited = new GrayLabel(Bundle.ObjectsFeatureModes_lblUnlimited());\n                final JLabel noAllocs = new GrayLabel(Bundle.ObjectsFeatureModes_lblNoAllocations());\n                \n                boolean alloc = Boolean.parseBoolean(readFlag(ALLOCATIONS_FLAG, Boolean.TRUE.toString()));\n                outgoingCheckbox = new JCheckBox(Bundle.ObjectsFeatureModes_limitAllocations(), alloc) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        boolean selected = isSelected();\n                        unlimited.setVisible(!selected);\n                        outgoingSpinner.setVisible(selected);\n                        noAllocs.setVisible(selected && (Integer)outgoingSpinner.getValue() == 0);\n                        settingsChanged();\n                    }\n                };\n                outgoingCheckbox.setToolTipText(Bundle.ObjectsFeatureModes_collectFullStacksToolTip());\n                outgoingCheckbox.setOpaque(false);\n                selectionContent.add(outgoingCheckbox);\n                \n                selectionContent.add(createStrut(outgoingCheckbox, 5, false));\n                if (UIUtils.isOracleLookAndFeel()) selectionContent.add(Box.createHorizontalStrut(4));\n                \n                unlimited.setVisible(!outgoingCheckbox.isSelected());\n                selectionContent.add(unlimited);\n                \n                int limit = Integer.parseInt(readFlag(LIMIT_ALLOCATIONS_FLAG, LIMIT_ALLOCATIONS_DEFAULT.toString()));\n                outgoingSpinner = new JExtendedSpinner(new SpinnerNumberModel(Math.abs(limit), 0, 99, 1)) {\n                    public Dimension getPreferredSize() { return getMinimumSize(); }\n                    public Dimension getMaximumSize() { return getMinimumSize(); }\n                    protected void fireStateChanged() { settingsChanged(); super.fireStateChanged(); }\n                };\n                outgoingSpinner.setToolTipText(Bundle.ObjectsFeatureModes_limitAllocationsDepthToolTip());\n                JComponent editor = outgoingSpinner.getEditor();\n                JTextField field = editor instanceof JSpinner.DefaultEditor ?\n                        ((JSpinner.DefaultEditor)editor).getTextField() : null;\n                if (field != null) field.getDocument().addDocumentListener(new DocumentListener() {\n                    public void insertUpdate(DocumentEvent e) { change(); }\n                    public void removeUpdate(DocumentEvent e) { change(); }\n                    public void changedUpdate(DocumentEvent e) { change(); }\n                    private void change() {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                noAllocs.setVisible(outgoingSpinner.isVisible() &&\n                                                    (Integer)outgoingSpinner.getValue() == 0);\n                            }\n                        });\n//                            settingsChanged();\n                    }\n                });\n                outgoingSpinner.setVisible(outgoingCheckbox.isSelected());\n                selectionContent.add(outgoingSpinner);\n                \n                selectionContent.add(Box.createHorizontalStrut(5));\n                \n                noAllocs.setVisible(outgoingSpinner.isVisible() && (Integer)outgoingSpinner.getValue() == 0);\n                selectionContent.add(noAllocs);\n\n                noSelectionContent = new SettingsPanel();\n\n                GrayLabel noSelectionHint = new GrayLabel(Bundle.ObjectsFeatureModes_noClassSelected());\n                noSelectionHint.setEnabled(false);\n                noSelectionContent.add(noSelectionHint);\n\n                noSelectionContent.add(Box.createHorizontalStrut(5));\n\n                String iconMask = LanguageIcons.CLASS;\n                Image baseIcon = Icons.getImage(iconMask);\n                Image addBadge = Icons.getImage(GeneralIcons.BADGE_ADD);\n                Image addImage = ImageUtilities.mergeImages(baseIcon, addBadge, 0, 0);\n                addSelectionButton = new SmallButton(ImageUtilities.image2Icon(addImage)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        selectForProfiling(ClassMethodSelector.selectClasses(getSession()));\n                    }\n                    public Dimension getMinimumSize() {\n                        return getPreferredSize();\n                    }\n                    public Dimension getMaximumSize() {\n                        return getPreferredSize();\n                    }\n                };\n                addSelectionButton.setToolTipText(Bundle.ObjectsFeatureModes_addClass());\n                noSelectionContent.add(addSelectionButton);\n                updateSelectionCustomizer();\n            }\n            return ui;\n        }\n        \n        private void updateSelectionCustomizer() {\n            if (ui != null) {\n                int count = getSelection().size();\n                \n                JPanel content = count == 0 ? noSelectionContent : selectionContent;\n                if (ui.getComponentCount() > 0 && content == ui.getComponent(0)) content = null;\n                \n                if (count > 0) editSelectionLink.setText(count == 1 ? Bundle.ObjectsFeatureModes_oneClassSelected() :\n                                                         Bundle.ObjectsFeatureModes_multipleClassesSelected(count));\n                \n                if (content != null) {\n                    ui.removeAll();\n                    ui.add(content);\n                    ui.doLayout();\n                    ui.repaint();\n                }\n            }\n        }\n        \n    }\n    \n    \n    static abstract class CustomClassesMode extends MemoryMode {\n        \n        private static final String LIFECYCLE_FLAG = \"LIFECYCLE_FLAG\"; // NOI18N\n        private static final String ALLOCATIONS_FLAG = \"ALLOCATIONS_FLAG\"; // NOI18N\n        private static final String LIMIT_ALLOCATIONS_FLAG = \"LIMIT_ALLOCATIONS_FLAG\"; // NOI18N\n        private static final String CLASSES_FLAG = \"SELECTION_FLAG\"; // NOI18N\n        \n        private static final int MIN_ROWS = 1;\n        private static final int MAX_ROWS = 15;\n        private static final int DEFAULT_ROWS = 3;\n        private static final int MIN_COLUMNS = 10;\n        private static final int MAX_COLUMNS = 100;\n        private static final int DEFAULT_COLUMNS = 40;\n        \n        private static final Integer LIMIT_ALLOCATIONS_DEFAULT = 10;        \n        \n        private JComponent ui;\n        private TextArea classesArea;\n        private JCheckBox lifecycleCheckbox;\n        private JCheckBox outgoingCheckbox;\n        private JSpinner outgoingSpinner;\n        \n\n        String getID() {\n            return \"CustomMethodsMode\"; // NOI18N\n        }\n\n        String getName() {\n            return Bundle.ObjectsFeatureModes_definedClasses();\n        }\n        \n        void configureSettings(ProfilingSettings settings) {\n            assert SwingUtilities.isEventDispatchThread();\n            \n            super.configureSettings(settings);\n            \n            String filterValue = getFlatValues(readFlag(CLASSES_FLAG, \"\").split(\"\\\\n\")); // NOI18N\n            settings.setInstrumentationFilter(new JavaTypeFilter(filterValue, JavaTypeFilter.TYPE_INCLUSIVE));\n            \n            boolean lifecycle = Boolean.parseBoolean(readFlag(LIFECYCLE_FLAG, Boolean.TRUE.toString()));\n            settings.setProfilingType(lifecycle ? ProfilingSettings.PROFILE_MEMORY_LIVENESS :\n                                                  ProfilingSettings.PROFILE_MEMORY_ALLOCATIONS);\n\n            boolean alloc = Boolean.parseBoolean(readFlag(ALLOCATIONS_FLAG, Boolean.TRUE.toString()));\n            int limit = Integer.parseInt(readFlag(LIMIT_ALLOCATIONS_FLAG, LIMIT_ALLOCATIONS_DEFAULT.toString()));\n            settings.setAllocStackTraceLimit(!alloc ? -10 : limit); // TODO: should follow limit from Options\n        }\n        \n        void confirmSettings() {\n            if (ui != null && classesArea != null) { // filter out notifications from initialization\n                assert SwingUtilities.isEventDispatchThread();\n                \n                String classes = classesArea.showsHint() ? \"\" : // NOI18N\n                                 classesArea.getText().trim();\n                storeFlag(CLASSES_FLAG, classes.isEmpty() ? null : classes);\n                \n                storeFlag(LIFECYCLE_FLAG,   lifecycleCheckbox.isSelected() ?\n                                            null : Boolean.FALSE.toString());\n                storeFlag(ALLOCATIONS_FLAG, outgoingCheckbox.isSelected() ?\n                                            null : Boolean.FALSE.toString());\n                Integer limit = ((Integer)outgoingSpinner.getValue());\n                boolean deflimit = LIMIT_ALLOCATIONS_DEFAULT.equals(limit);\n                storeFlag(LIMIT_ALLOCATIONS_FLAG, deflimit ? null : limit.toString());\n            }\n        }\n        \n        boolean pendingChanges() {\n            if (ui != null) {\n                assert SwingUtilities.isEventDispatchThread();\n                \n                String classes = classesArea.showsHint() ? \"\" : // NOI18N\n                                 classesArea.getText().trim();\n                if (!classes.equals(readFlag(CLASSES_FLAG, \"\"))) return true; // NOI18N\n                \n                boolean lifecycle = lifecycleCheckbox.isSelected();\n                boolean _lifecycle = Boolean.parseBoolean(readFlag(LIFECYCLE_FLAG, Boolean.TRUE.toString()));\n                if (lifecycle != _lifecycle) return true;\n                \n                boolean alloc = outgoingCheckbox.isSelected();\n                boolean _alloc = Boolean.parseBoolean(readFlag(ALLOCATIONS_FLAG, Boolean.TRUE.toString()));\n                if (alloc != _alloc) return true;\n                \n                int limit = Integer.parseInt(readFlag(LIMIT_ALLOCATIONS_FLAG, LIMIT_ALLOCATIONS_DEFAULT.toString()));\n                int _limit = (Integer)outgoingSpinner.getValue();\n                if (limit != _limit) return true;\n            }\n            return false;\n        }\n\n        boolean currentSettingsValid() {\n            assert SwingUtilities.isEventDispatchThread();\n            \n            if (ui != null) {\n                if (classesArea.showsHint() || classesArea.getText().trim().isEmpty()) return false;\n            } else {\n                if (readFlag(CLASSES_FLAG, \"\").isEmpty()) return false; // NOI18N\n            }\n            \n            return true;\n        }\n        \n        private static String getFlatValues(String[] values) {\n            StringBuilder convertedValue = new StringBuilder();\n\n            for (int i = 0; i < values.length; i++) {\n                String filterValue = values[i].trim();\n                if ((i != (values.length - 1)) && !filterValue.endsWith(\",\")) // NOI18N\n                    filterValue = filterValue + \",\"; // NOI18N\n                convertedValue.append(filterValue);\n            }\n\n            return convertedValue.toString();\n        }\n\n        JComponent getUI() {\n            if (ui == null) {\n                JPanel p = new JPanel(new GridBagLayout());\n                p.setOpaque(false);\n                \n                GridBagConstraints c;\n        \n                JPanel classesPanel = new SettingsPanel();\n                classesPanel.add(new JLabel(Bundle.ObjectsFeatureModes_classesLbl()));\n                c = new GridBagConstraints();\n                c.gridx = 0;\n                c.gridy = 0;\n                c.fill = GridBagConstraints.NONE;\n                c.insets = new Insets(0, 0, 0, 5);\n                c.anchor = GridBagConstraints.NORTHWEST;\n                p.add(classesPanel, c);\n                \n                final JScrollPane[] container = new JScrollPane[1];\n                classesArea = new TextArea(readFlag(CLASSES_FLAG, \"\")) { // NOI18N\n                    protected void changed() {\n                        settingsChanged();\n                    }\n                    protected boolean changeSize(boolean vertical, boolean direction) {\n                        if (vertical) {\n                            int rows = readRows();\n                            if (direction) rows = Math.min(rows + 1, MAX_ROWS);\n                            else rows = Math.max(rows - 1, MIN_ROWS);\n                            storeRows(rows);\n                        } else {\n                            int cols = readColumns();\n                            if (direction) cols = Math.min(cols + 3, MAX_COLUMNS);\n                            else cols = Math.max(cols - 3, MIN_COLUMNS);\n                            storeColumns(cols);\n                        }\n                        \n                        layoutImpl();                        \n                        return true;\n                    }\n                    protected boolean resetSize() {\n                        storeRows(DEFAULT_ROWS);\n                        storeColumns(DEFAULT_COLUMNS);\n                \n                        layoutImpl();\n                        return true;\n                    }\n                    private void layoutImpl() {\n                        setRows(readRows());\n                        setColumns(readColumns());\n                        container[0].setPreferredSize(null);\n                        container[0].setPreferredSize(container[0].getPreferredSize());\n                        container[0].setMinimumSize(container[0].getPreferredSize());\n                        JComponent root = SwingUtilities.getRootPane(container[0]);\n                        root.doLayout();\n                        root.repaint();\n                        setColumns(0);\n                    }\n                    protected void customizePopup(JPopupMenu popup) {\n                        popup.addSeparator();\n                        popup.add(createResizeMenu());\n                    }\n                    public Point getToolTipLocation(MouseEvent event) {\n                        Component scroll = getParent().getParent();\n                        return SwingUtilities.convertPoint(scroll, 0, scroll.getHeight(), this);\n                    }\n                };\n                classesArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, classesArea.getFont().getSize()));\n                classesArea.setRows(readRows());\n                classesArea.setColumns(readColumns());\n                container[0] = new JScrollPane(classesArea);\n                container[0].setPreferredSize(container[0].getPreferredSize());\n                container[0].setMinimumSize(container[0].getPreferredSize());\n                classesArea.setColumns(0);\n                classesArea.setHint(Bundle.ObjectsFeatureModes_classesHint());\n                classesArea.setToolTipText(Bundle.ObjectsFeatureModes_classesTooltip());\n                c = new GridBagConstraints();\n                c.gridx = 1;\n                c.gridy = 0;\n                c.weightx = 1;\n                c.weighty = 1;\n                c.fill = GridBagConstraints.VERTICAL;\n                c.insets = new Insets(0, 0, 0, 5);\n                c.anchor = GridBagConstraints.NORTHWEST;\n                p.add(container[0], c);\n                \n                JPanel settingsPanel = new SettingsPanel();\n                \n                settingsPanel.add(Box.createHorizontalStrut(4));\n\n                Component separator = Box.createHorizontalStrut(1);\n                separator.setBackground(Color.GRAY);\n                if (separator instanceof JComponent) ((JComponent)separator).setOpaque(true);\n                Dimension d = separator.getMaximumSize();\n                d.height = 20;\n                separator.setMaximumSize(d);\n                settingsPanel.add(separator);\n\n                boolean lifecycle = Boolean.parseBoolean(readFlag(LIFECYCLE_FLAG, Boolean.TRUE.toString()));\n                lifecycleCheckbox = new JCheckBox(Bundle.ObjectsFeatureModes_recordLifecycle(), lifecycle) {\n                    protected void fireActionPerformed(ActionEvent e) { super.fireActionPerformed(e); settingsChanged(); }\n                };\n                lifecycleCheckbox.setToolTipText(Bundle.ObjectsFeatureModes_profileAllObjectsToolTip());\n                lifecycleCheckbox.setOpaque(false);\n                settingsPanel.add(createStrut(lifecycleCheckbox, 8, true));\n                settingsPanel.add(lifecycleCheckbox);\n                \n                settingsPanel.add(createStrut(lifecycleCheckbox, 5, false));\n                if (UIUtils.isOracleLookAndFeel()) p.add(Box.createHorizontalStrut(4));\n                \n                final JLabel unlimited = new GrayLabel(Bundle.ObjectsFeatureModes_lblUnlimited());\n                final JLabel noAllocs = new GrayLabel(Bundle.ObjectsFeatureModes_lblNoAllocations());\n                \n                boolean alloc = Boolean.parseBoolean(readFlag(ALLOCATIONS_FLAG, Boolean.TRUE.toString()));\n                outgoingCheckbox = new JCheckBox(Bundle.ObjectsFeatureModes_limitAllocations(), alloc) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        boolean selected = isSelected();\n                        unlimited.setVisible(!selected);\n                        outgoingSpinner.setVisible(selected);\n                        noAllocs.setVisible(selected && (Integer)outgoingSpinner.getValue() == 0);\n                        settingsChanged();\n                    }\n                };\n                outgoingCheckbox.setToolTipText(Bundle.ObjectsFeatureModes_collectFullStacksToolTip());\n                outgoingCheckbox.setOpaque(false);\n                settingsPanel.add(outgoingCheckbox);\n                \n                settingsPanel.add(createStrut(outgoingCheckbox, 5, false));\n                if (UIUtils.isOracleLookAndFeel()) settingsPanel.add(Box.createHorizontalStrut(4));\n                \n                unlimited.setVisible(!outgoingCheckbox.isSelected());\n                settingsPanel.add(unlimited);\n                \n                int limit = Integer.parseInt(readFlag(LIMIT_ALLOCATIONS_FLAG, LIMIT_ALLOCATIONS_DEFAULT.toString()));\n                outgoingSpinner = new JExtendedSpinner(new SpinnerNumberModel(Math.abs(limit), 0, 99, 1)) {\n                    public Dimension getPreferredSize() { return getMinimumSize(); }\n                    public Dimension getMaximumSize() { return getMinimumSize(); }\n                    protected void fireStateChanged() { settingsChanged(); super.fireStateChanged(); }\n                };\n                outgoingSpinner.setToolTipText(Bundle.ObjectsFeatureModes_limitAllocationsDepthToolTip());\n                JComponent editor = outgoingSpinner.getEditor();\n                JTextField field = editor instanceof JSpinner.DefaultEditor ?\n                        ((JSpinner.DefaultEditor)editor).getTextField() : null;\n                if (field != null) field.getDocument().addDocumentListener(new DocumentListener() {\n                    public void insertUpdate(DocumentEvent e) { change(); }\n                    public void removeUpdate(DocumentEvent e) { change(); }\n                    public void changedUpdate(DocumentEvent e) { change(); }\n                    private void change() {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                noAllocs.setVisible(outgoingSpinner.isVisible() &&\n                                                    (Integer)outgoingSpinner.getValue() == 0);\n                            }\n                        });\n//                            settingsChanged();\n                    }\n                });\n                outgoingSpinner.setVisible(outgoingCheckbox.isSelected());\n                settingsPanel.add(outgoingSpinner);\n                \n                settingsPanel.add(Box.createHorizontalStrut(5));\n                \n                noAllocs.setVisible(outgoingSpinner.isVisible() && (Integer)outgoingSpinner.getValue() == 0);\n                settingsPanel.add(noAllocs);\n                \n                c = new GridBagConstraints();\n                c.gridx = 2;\n                c.gridy = 0;\n                c.fill = GridBagConstraints.NONE;\n                c.insets = new Insets(0, 0, 0, 0);\n                c.anchor = GridBagConstraints.NORTHWEST;\n                p.add(settingsPanel, c);\n                \n                ui = p;\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { settingsChanged(); }\n                });\n            }\n            return ui;\n        }\n        \n        private int readRows() {\n            return NbPreferences.forModule(ObjectsFeatureModes.class).getInt(\"ObjectsFeatureModes.rows\", DEFAULT_ROWS); // NOI18N\n        }\n        \n        private void storeRows(int rows) {\n            NbPreferences.forModule(ObjectsFeatureModes.class).putInt(\"ObjectsFeatureModes.rows\", rows); // NOI18N\n        }\n        \n        private int readColumns() {\n            return NbPreferences.forModule(ObjectsFeatureModes.class).getInt(\"ObjectsFeatureModes.columns\", DEFAULT_COLUMNS); // NOI18N\n        }\n        \n        private void storeColumns(int columns) {\n            NbPreferences.forModule(ObjectsFeatureModes.class).putInt(\"ObjectsFeatureModes.columns\", columns); // NOI18N\n        }\n        \n    }\n    \n    \n    private static Component createStrut(JComponent c, int width, boolean before) {\n        Border b = c.getBorder();\n        Insets i = b != null ? b.getBorderInsets(c) : null;\n        int w = i == null ? width : Math.max(width - (before ? i.left : i.right), 0);\n        return Box.createHorizontalStrut(w);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/ObjectsFeatureUI.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport java.util.Set;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.memory.LiveMemoryView;\nimport org.graalvm.visualvm.lib.ui.memory.LiveMemoryViewUpdater;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.profiler.actions.ResetResultsAction;\nimport org.graalvm.visualvm.lib.profiler.actions.TakeSnapshotAction;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ObjectsFeatureUI_liveResults=Results:\",\n    \"ObjectsFeatureUI_pauseResults=Pause live results\",\n    \"ObjectsFeatureUI_updateResults=Update live results\",\n    \"ObjectsFeatureUI_profilingData=Collected data:\",\n    \"ObjectsFeatureUI_snapshot=Snapshot\",\n    \"ObjectsFeatureUI_showAbsolute=Show absolute values\",\n    \"ObjectsFeatureUI_showDeltas=Show delta values\"\n})\nabstract class ObjectsFeatureUI extends FeatureUI {\n\n    private ProfilerToolbar toolbar;\n    private LiveMemoryView memoryView;\n    private LiveMemoryViewUpdater updater;\n\n\n    // --- External implementation ---------------------------------------------\n    \n    abstract Set<ClientUtils.SourceCodeSelection> getSelection();\n    \n    abstract void selectForProfiling(ClientUtils.SourceCodeSelection value);\n    \n    abstract Lookup.Provider getProject();\n    \n    abstract ProfilerClient getProfilerClient();\n    \n    abstract void refreshResults();\n    \n    \n    // --- API implementation --------------------------------------------------\n    \n    ProfilerToolbar getToolbar() {\n        if (toolbar == null) initUI();\n        return toolbar;\n    }\n\n    JPanel getResultsUI() {\n        if (memoryView == null) initUI();\n        return memoryView;\n    }\n    \n    boolean hasResultsUI() {\n        return memoryView != null;\n    }\n    \n    void sessionStateChanged(int sessionState) {\n        refreshToolbar(sessionState);\n    }\n    \n    \n    void resetPause() {\n        if (lrPauseButton != null) lrPauseButton.setSelected(false);\n    }\n    \n    void setForceRefresh() {\n        if (updater != null) updater.setForceRefresh(true);\n    }\n    \n    void refreshData() throws ClientUtils.TargetAppOrVMTerminated {\n        if (updater != null) updater.update();\n    }\n    \n    void resetData() {\n        if (lrDeltasButton != null) {\n            lrDeltasButton.setSelected(false);\n            lrDeltasButton.setToolTipText(Bundle.ObjectsFeatureUI_showDeltas());\n        }\n        if (memoryView != null) {\n            memoryView.resetData();\n            memoryView.setDiffView(false);\n        }\n    }\n    \n    \n    void cleanup() {\n        if (updater != null) updater.cleanup();\n    }\n    \n    \n    // --- UI ------------------------------------------------------------------\n    \n    private JLabel lrLabel;\n    private JToggleButton lrPauseButton;\n    private JButton lrRefreshButton;\n    private JToggleButton lrDeltasButton;\n    \n    private JLabel pdLabel;\n    private JButton pdSnapshotButton;\n    private JButton pdResetResultsButton;\n    \n    private boolean popupPause;\n    \n    \n    private void initUI() {\n        \n        assert SwingUtilities.isEventDispatchThread();\n        \n        // --- Results ---------------------------------------------------------\n        \n        memoryView = new LiveMemoryView(getSelection()) {\n            protected ProfilerClient getProfilerClient() {\n                return ObjectsFeatureUI.this.getProfilerClient();\n            }\n            protected boolean showSourceSupported() {\n                return GoToSource.isAvailable();\n            }\n            protected void showSource(ClientUtils.SourceCodeSelection value) {\n                String className = value.getClassName();\n                String methodName = value.getMethodName();\n                String methodSig = value.getMethodSignature();\n                GoToSource.openSource(getProject(), className, methodName, methodSig);\n            }\n            protected void selectForProfiling(ClientUtils.SourceCodeSelection value) {\n                ObjectsFeatureUI.this.selectForProfiling(value);\n            }\n            protected void popupShowing() {\n                if (lrPauseButton.isEnabled() && !lrRefreshButton.isEnabled()) {\n                    popupPause = true;\n                    lrPauseButton.setSelected(true);\n                }\n            }\n            protected void popupHidden() {\n                if (lrPauseButton.isEnabled() && popupPause) {\n                    popupPause = false;\n                    lrPauseButton.setSelected(false);\n                }\n            }\n        };\n        \n        memoryView.putClientProperty(\"HelpCtx.Key\", \"ProfileObjects.HelpCtx\"); // NOI18N\n        \n        updater = new LiveMemoryViewUpdater(memoryView, getProfilerClient());\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        lrLabel = new GrayLabel(Bundle.ObjectsFeatureUI_liveResults());\n\n        lrPauseButton = new JToggleButton(Icons.getIcon(GeneralIcons.PAUSE)) {\n            protected void fireItemStateChanged(ItemEvent event) {\n                boolean paused = isSelected();\n                updater.setPaused(paused);\n                if (!paused) refreshResults();\n                refreshToolbar(getSessionState());\n            }\n        };\n        lrPauseButton.setToolTipText(Bundle.ObjectsFeatureUI_pauseResults());\n        lrPauseButton.setEnabled(false);\n\n        lrRefreshButton = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                refreshResults();\n            }\n        };\n        lrRefreshButton.setToolTipText(Bundle.ObjectsFeatureUI_updateResults());\n        \n        Icon icon = Icons.getIcon(ProfilerIcons.DELTA_RESULTS);\n        lrDeltasButton = new JToggleButton(icon) {\n            protected void fireActionPerformed(ActionEvent e) {\n                if (!memoryView.setDiffView(isSelected())) setSelected(false);\n                setToolTipText(isSelected() ? Bundle.ObjectsFeatureUI_showAbsolute() :\n                                              Bundle.ObjectsFeatureUI_showDeltas());\n            }\n        };\n        lrDeltasButton.setToolTipText(Bundle.ObjectsFeatureUI_showDeltas());\n\n        pdLabel = new GrayLabel(Bundle.ObjectsFeatureUI_profilingData());\n\n        pdSnapshotButton = new JButton(TakeSnapshotAction.getInstance());\n        pdSnapshotButton.setHideActionText(true);\n//        pdSnapshotButton.setText(Bundle.ObjectsFeatureUI_snapshot());\n\n        pdResetResultsButton = new JButton(ResetResultsAction.getInstance());\n        pdResetResultsButton.setHideActionText(true);\n\n        toolbar = ProfilerToolbar.create(true);\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(lrLabel);\n        toolbar.addSpace(2);\n        toolbar.add(lrPauseButton);\n        toolbar.add(lrRefreshButton);\n        toolbar.addSpace(5);\n        toolbar.add(lrDeltasButton);\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(pdLabel);\n        toolbar.addSpace(2);\n        toolbar.add(pdSnapshotButton);\n        toolbar.addSpace(3);\n        toolbar.add(pdResetResultsButton);\n        \n        \n        // --- Sync UI ---------------------------------------------------------\n        \n        sessionStateChanged(getSessionState());\n        \n    }\n    \n    private void refreshToolbar(final int state) {\n        if (toolbar != null) SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n//                boolean running = isRunning(state);\n                boolean running = state == Profiler.PROFILING_RUNNING;\n                lrPauseButton.setEnabled(running);\n                lrRefreshButton.setEnabled(!popupPause && running && lrPauseButton.isSelected());\n                lrDeltasButton.setEnabled(running);\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/SQLFeature.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JRadioButtonMenuItem;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.SmallButton;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.ResultsListener;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.api.ProjectUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerFeature;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.graalvm.visualvm.lib.profiler.v2.impl.WeakProcessor;\nimport org.graalvm.visualvm.lib.profiler.v2.ui.SettingsPanel;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.lookup.Lookups;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"SQLFeature_name=SQL Queries\",\n    \"SQLFeature_description=Display executed SQL queries, their duration and invocation paths\",\n    \"SQLFeature_profileMethod=Profile Method\",\n    \"SQLFeature_profileClass=Profile Class\"\n})\nfinal class SQLFeature extends ProfilerFeature.Basic {\n    \n    private final WeakProcessor processor;\n    \n    private FeatureMode currentMode;\n    private FeatureMode appliedMode;\n    \n    private SQLFeatureModes.AllQueriesMode allQueriesMode;\n    private SQLFeatureModes.FilteredQueriesMode filteredQueriesMode;\n    \n    \n    private SQLFeature(ProfilerSession session) {\n        super(Icons.getIcon(ProfilerIcons.WINDOW_SQL), Bundle.SQLFeature_name(),\n              Bundle.SQLFeature_description(), 20, session);\n        \n        Lookup.Provider project = session.getProject();\n        String projectName = project == null ? \"External Process\" : // NOI18N\n                             ProjectUtilities.getDisplayName(project);\n        processor = new WeakProcessor(\"SQLFeature Processor for \" + projectName); // NOI18N\n        \n        initModes();\n    }\n    \n    \n    // --- Mode ----------------------------------------------------------------\n    \n    private static final String MODE_FLAG = \"MODE_FLAG\"; // NOI18N\n    \n    private void initModes() {\n        allQueriesMode = new SQLFeatureModes.AllQueriesMode() {\n            String readFlag(String flag, String defaultValue) {\n                return SQLFeature.this.readFlag(getID() + \"_\" + flag, defaultValue); // NOI18N\n            }\n            void storeFlag(String flag, String value) {\n                SQLFeature.this.storeFlag(getID() + \"_\" + flag, value); // NOI18N\n            }\n            void settingsChanged() {\n                SQLFeature.this.settingsChanged();\n            }\n        };\n        \n        filteredQueriesMode = new SQLFeatureModes.FilteredQueriesMode() {\n            String readFlag(String flag, String defaultValue) {\n                return SQLFeature.this.readFlag(getID() + \"_\" + flag, defaultValue); // NOI18N\n            }\n            void storeFlag(String flag, String value) {\n                SQLFeature.this.storeFlag(getID() + \"_\" + flag, value); // NOI18N\n            }\n            void settingsChanged() {\n                SQLFeature.this.settingsChanged();\n            }\n        };\n        \n        String _currentMode = readFlag(MODE_FLAG, allQueriesMode.getID());\n        if (_currentMode.equals(filteredQueriesMode.getID())) currentMode = filteredQueriesMode;\n        else currentMode = allQueriesMode;\n        \n        appliedMode = currentMode;\n    }\n    \n    private void saveMode() {\n        storeFlag(MODE_FLAG, currentMode.getID());\n    }\n    \n    private void setMode(FeatureMode newMode) {\n        if (currentMode == newMode) return;\n        currentMode = newMode;\n        modeChanged();\n    }\n    \n    private void confirmMode() {\n        appliedMode = currentMode;\n    }\n    \n    private void modeChanged() {\n        updateModeName();\n        updateModeUI();\n        configurationChanged();\n        saveMode();\n    }\n    \n    \n    // --- Settings ------------------------------------------------------------\n    \n    public boolean supportsSettings(ProfilingSettings psettings) {\n        return !ProfilingSettings.isCPUSettings(psettings) &&\n               !ProfilingSettings.isMemorySettings(psettings);\n    }\n\n    public void configureSettings(ProfilingSettings psettings) {\n        currentMode.configureSettings(psettings);\n    }\n    \n    public boolean currentSettingsValid() {\n        return currentMode.currentSettingsValid();\n    }\n    \n    private void submitChanges() {\n        confirmMode();\n        confirmSettings();\n        fireChange();\n    }\n    \n    // Changes to current settings are pending\n    private boolean pendingChanges() {\n        if (appliedMode != currentMode) return true;\n        return currentMode.pendingChanges();\n    }\n    \n    // Profiling settings defined by this feature have changed\n    private void configurationChanged() {\n        assert isActivated();\n        \n        ProfilerSession session = getSession();\n        \n        if (!session.inProgress()) submitChanges();\n        else updateApplyButton(session.getState());\n    }\n    \n    private void confirmSettings() {\n        currentMode.confirmSettings();\n    }\n    \n    private void confirmAllSettings() {\n        if (allQueriesMode != null) allQueriesMode.confirmSettings();\n        if (filteredQueriesMode != null) filteredQueriesMode.confirmSettings();\n    }\n    \n    private void settingsChanged() {\n        configurationChanged();\n    }\n    \n    private void selectionChanged() {\n        configurationChanged();\n    }\n    \n    \n    // --- Settings UI ---------------------------------------------------------\n    \n    private static final String SETTINGS_FLAG = \"SETTINGS_FLAG\"; // NOI18N\n    \n    private JPanel settingsUI;\n    private JButton modeButton;\n    private JPanel settingsContainer;\n    private JButton applyButton;\n    \n    public JPanel getSettingsUI() {\n        if (settingsUI == null) {\n            settingsUI = new JPanel(new GridBagLayout()) {\n                public void setVisible(boolean visible) {\n                    if (visible && getComponentCount() == 0) populateSettingsUI();\n                    super.setVisible(visible);\n                    storeFlag(SETTINGS_FLAG, visible ? Boolean.TRUE.toString() : null);\n                }\n                public Dimension getPreferredSize() {\n                    if (getComponentCount() == 0) return new Dimension();\n                    else return super.getPreferredSize();\n                }\n            };\n            \n            String _vis = readFlag(SETTINGS_FLAG, null);\n            boolean vis = _vis == null ? false : Boolean.parseBoolean(_vis);\n            settingsUI.setVisible(vis || currentMode != allQueriesMode);\n        }\n        return settingsUI;\n    }\n    \n    private void populateSettingsUI() {\n        settingsUI.setOpaque(false);\n        settingsUI.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n        \n        GridBagConstraints c;\n        \n        JPanel profilePanel = new SettingsPanel();\n        profilePanel.add(new JLabel(Bundle.ObjectsFeature_profileMode()));\n        profilePanel.add(Box.createHorizontalStrut(5));\n        \n        // Mode button\n        modeButton = new PopupButton(currentMode.getName()) {\n            protected void populatePopup(JPopupMenu popup) {\n                popup.add(new JRadioButtonMenuItem(allQueriesMode.getName(), currentMode == allQueriesMode) {\n                    protected void fireActionPerformed(ActionEvent e) { setMode(allQueriesMode); }\n                });\n                popup.add(new JRadioButtonMenuItem(filteredQueriesMode.getName(), currentMode == filteredQueriesMode) {\n                    protected void fireActionPerformed(ActionEvent e) { setMode(filteredQueriesMode); }\n                });\n            }\n        };\n        profilePanel.add(modeButton);\n        \n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(0, 0, 0, 0);\n        c.anchor = GridBagConstraints.NORTHWEST;\n        settingsUI.add(profilePanel, c);\n        \n        // Settings container\n        settingsContainer = new JPanel(new BorderLayout());\n        settingsContainer.setOpaque(false);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.fill = GridBagConstraints.VERTICAL;\n        c.insets = new Insets(0, 10, 0, 0);\n        c.anchor = GridBagConstraints.NORTHWEST;\n        settingsUI.add(settingsContainer, c);\n        \n        JPanel buttonsPanel = new SettingsPanel();\n        \n        final Component space = Box.createHorizontalStrut(10);\n        buttonsPanel.add(space);\n        \n        // Apply button\n        applyButton = new SmallButton(Bundle.ObjectsFeature_applyButton()) {\n            protected void fireActionPerformed(ActionEvent e) {\n                stopResults();\n                resetResults();\n                submitChanges();\n                unpauseResults();\n            }\n            public void setVisible(boolean visible) {\n                super.setVisible(visible);\n                space.setVisible(visible);\n            }\n        };\n        buttonsPanel.add(applyButton);\n        \n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 0;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(0, 0, 0, 0);\n        c.anchor = GridBagConstraints.NORTHEAST;\n        settingsUI.add(buttonsPanel, c);\n        \n        updateModeUI();\n        updateApplyButton(getSession().getState());\n    }\n    \n    private void updateModeName() {\n        if (modeButton != null) modeButton.setText(currentMode.getName());\n    }\n    \n    private void updateModeUI() {\n        if (settingsContainer != null) {\n            settingsContainer.removeAll();\n\n            JComponent modeUI = currentMode.getUI();\n            if (modeUI != null) settingsContainer.add(modeUI);\n            settingsContainer.doLayout();\n            settingsContainer.repaint();\n        }\n    }\n    \n    private void updateApplyButton(int state) {\n        if (applyButton != null) {\n            boolean visible = state != Profiler.PROFILING_INACTIVE;\n            applyButton.setVisible(visible);\n            if (visible) applyButton.setEnabled(currentSettingsValid() && pendingChanges());\n        }\n    }\n    \n    \n    // --- Toolbar & Results UI ------------------------------------------------\n    \n    private SQLFeatureUI ui;\n    \n    public JPanel getResultsUI() {\n        return getUI().getResultsUI();\n    }\n    \n    public ProfilerToolbar getToolbar() {\n        return getUI().getToolbar();\n    }\n    \n    private SQLFeatureUI getUI() {\n        if (ui == null) ui = new SQLFeatureUI() {\n            void selectForProfiling(final ClientUtils.SourceCodeSelection value) {\n                RequestProcessor.getDefault().post(new Runnable() {\n                    public void run() {\n                        String name = Wildcards.ALLWILDCARD.equals(value.getMethodName()) ?\n                                      Bundle.SQLFeature_profileClass() :\n                                      Bundle.SQLFeature_profileMethod();\n                        ProfilerSession.findAndConfigure(Lookups.fixed(value), getProject(), name);\n                    }\n                });\n            }\n            Lookup.Provider getProject() {\n                return SQLFeature.this.getSession().getProject();\n            }\n            ProfilerClient getProfilerClient() {\n                Profiler profiler = SQLFeature.this.getSession().getProfiler();\n                return profiler.getTargetAppRunner().getProfilerClient();\n            }\n            int getSessionState() {\n                return SQLFeature.this.getSessionState();\n            }\n            void refreshResults() {\n                SQLFeature.this.refreshResults();\n            }\n        };\n        return ui;\n    }\n    \n    \n    // --- Live results --------------------------------------------------------\n    \n    private Runnable refresher;\n    private volatile boolean running;\n    \n    \n    private void startResults() {\n        if (running) return;\n        running = true;\n        \n        refresher = new Runnable() {\n            public void run() {\n                if (running) {\n                    refreshView();\n                    refreshResults(1500);\n                }\n            }\n        };\n        \n        refreshResults(1000);\n    }\n\n    private void refreshView() {\n        if (ui != null && ResultsManager.getDefault().resultsAvailable()) {\n            try {\n                ui.refreshData();\n            } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                stopResults();\n            }\n        }\n    }\n    \n    private void refreshResults() {\n        if (running) processor.post(new Runnable() {\n            public void run() {\n                if (ui != null) ui.setForceRefresh();\n                refreshView();\n            }\n        });\n    }\n    \n    private void refreshResults(int delay) {\n        if (running && refresher != null) processor.post(refresher, delay);\n    }\n    \n    private void resetResults() {\n        if (ui != null) ui.resetData();\n    }\n    \n    private void stopResults() {\n        if (refresher != null) {\n            running = false;\n            refresher = null;\n        }\n    }\n    \n    private void unpauseResults() {\n        if (ui != null) ui.resetPause();\n    }\n    \n    \n    // --- Session lifecycle ---------------------------------------------------\n    \n    private SQLResetter resetter;\n    \n    public void notifyActivated() {\n        resetResults();\n        \n        resetter = Lookup.getDefault().lookup(SQLResetter.class);\n        resetter.controller = this;\n    }\n    \n    public void notifyDeactivated() {\n        resetResults();\n        \n        if (resetter != null) {\n            resetter.controller = null;\n            resetter = null;\n        }\n        \n        if (ui != null) {\n            ui.cleanup();\n            ui = null;\n        }\n    }\n    \n    \n    protected void profilingStateChanged(int oldState, int newState) {\n        if (newState == Profiler.PROFILING_INACTIVE || newState == Profiler.PROFILING_IN_TRANSITION) {\n            stopResults();\n            confirmAllSettings();\n        } else if (isActivated() && newState == Profiler.PROFILING_RUNNING) {\n            startResults();\n        } else if (newState == Profiler.PROFILING_STARTED) {\n            resetResults();\n            unpauseResults();\n        }\n        \n        if (ui != null) ui.sessionStateChanged(getSessionState());\n        \n        updateApplyButton(newState);\n    }\n    \n    \n    @ServiceProvider(service=ResultsListener.class)\n    public static final class SQLResetter implements ResultsListener {\n        private SQLFeature controller;\n        public void resultsAvailable() { /*if (controller != null) controller.refreshView();*/ }\n        public void resultsReset() { if (controller != null && controller.ui != null) controller.ui.resetData(); }\n    }\n    \n    \n    // --- Provider ------------------------------------------------------------\n    \n    @ServiceProvider(service=ProfilerFeature.Provider.class)\n    public static final class Provider extends ProfilerFeature.Provider {\n        public ProfilerFeature getFeature(ProfilerSession session) {\n            //return Boolean.getBoolean(\"org.graalvm.visualvm.lib.profiler.features.enableSQL\") ? new SQLFeature(session) : null; // NOI18N\n            return new SQLFeature(session);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/SQLFeatureModes.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport java.awt.Component;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.event.MouseEvent;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JScrollPane;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.filters.TextFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcCCTProvider;\nimport org.graalvm.visualvm.lib.ui.swing.TextArea;\nimport org.graalvm.visualvm.lib.profiler.v2.ui.SettingsPanel;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"SQLFeatureModes_allQueries=All queries\",\n    \"SQLFeatureModes_filteredQueries=Defined queries\",\n    \"SQLFeatureModes_queryContains=Query contains:\",\n    \"SQLFeatureModes_filterHint=case-insensitive query substring(s)\"\n})\nclass SQLFeatureModes {\n\n    private static abstract class SQLMode extends FeatureMode {\n\n        private static final String[] JDBC_MARKER_CLASSES = {\n            JdbcCCTProvider.DRIVER_INTERFACE,\n            JdbcCCTProvider.CONNECTION_INTERFACE,\n            JdbcCCTProvider.STATEMENT_INTERFACE,\n            JdbcCCTProvider.PREPARED_STATEMENT_INTERFACE,\n            JdbcCCTProvider.CALLABLE_STATEMENT_INTERFACE\n        };\n\n        void configureSettings(ProfilingSettings settings) {\n            settings.setProfilingType(ProfilingSettings.PROFILE_CPU_JDBC);\n            settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);\n\n            ClientUtils.SourceCodeSelection[] roots = new ClientUtils.SourceCodeSelection[JDBC_MARKER_CLASSES.length];\n            for (int i = 0; i < JDBC_MARKER_CLASSES.length; i++) {\n                roots[i] = new ClientUtils.SourceCodeSelection(JDBC_MARKER_CLASSES[i], \"*\", null); // NOI18N\n                roots[i].setMarkerMethod(true);\n            }\n            settings.addRootMethods(roots);\n        }\n        \n    }\n    \n    static abstract class AllQueriesMode extends SQLMode {\n        \n        String getID() {\n            return \"AllQueriesMode\"; // NOI18N\n        }\n\n        String getName() {\n            return Bundle.SQLFeatureModes_allQueries();\n        }\n        \n        void configureSettings(ProfilingSettings settings) {\n            super.configureSettings(settings);\n            settings.setInstrumentationFilter(new TextFilter());\n        }\n        \n        void confirmSettings() {}\n        \n        boolean pendingChanges() { return false; }\n\n        boolean currentSettingsValid() { return true; }\n        \n        JComponent getUI() { return null; }\n        \n    }\n    \n    static abstract class FilteredQueriesMode extends SQLMode {\n        \n        private static final String QUERIES_FILTER_FLAG = \"QUERIES_FILTER_FLAG\"; // NOI18N\n        \n        private static final int MIN_ROWS = 1;\n        private static final int MAX_ROWS = 15;\n        private static final int DEFAULT_ROWS = 3;\n        private static final int MIN_COLUMNS = 10;\n        private static final int MAX_COLUMNS = 100;\n        private static final int DEFAULT_COLUMNS = 50;\n        \n        String getID() {\n            return \"FilteredQueriesMode\"; // NOI18N\n        }\n\n        String getName() {\n            return Bundle.SQLFeatureModes_filteredQueries();\n        }\n        \n        void configureSettings(ProfilingSettings settings) {\n            super.configureSettings(settings);\n            \n            String filter = getFlatValues(readFlag(QUERIES_FILTER_FLAG, \"\").split(\"\\\\n\")); // NOI18N\n            settings.setInstrumentationFilter(new TextFilter(filter, TextFilter.TYPE_INCLUSIVE, false));\n        }\n        \n        void confirmSettings() {\n            if (ui != null && filterArea != null) { // filter out notifications from initialization\n                assert SwingUtilities.isEventDispatchThread();\n                \n                String filter = filterArea.showsHint() ? \"\" : // NOI18N\n                                filterArea.getText().trim();\n                storeFlag(QUERIES_FILTER_FLAG, filter.isEmpty() ? null : filter);\n            }\n        }\n        \n        boolean pendingChanges() {\n            if (ui != null) {\n                assert SwingUtilities.isEventDispatchThread();\n                \n                String filter = filterArea.showsHint() ? \"\" : // NOI18N\n                                filterArea.getText().trim();\n                if (!filter.equals(readFlag(QUERIES_FILTER_FLAG, \"\"))) return true; // NOI18N\n            }\n            return false;\n        }\n\n        boolean currentSettingsValid() {\n            assert SwingUtilities.isEventDispatchThread();\n            \n            if (ui != null) {\n                if (filterArea.showsHint() || filterArea.getText().trim().isEmpty()) return false;\n            } else {\n                if (readFlag(QUERIES_FILTER_FLAG, \"\").isEmpty()) return false; // NOI18N\n            }\n            \n            return true;\n        }\n        \n        private static String getFlatValues(String[] values) {\n            StringBuilder convertedValue = new StringBuilder();\n\n            for (int i = 0; i < values.length; i++) {\n                String filterValue = values[i].trim();\n                if ((i != (values.length - 1)) && !filterValue.endsWith(\",\")) // NOI18N\n                    filterValue = filterValue + \",\"; // NOI18N\n                convertedValue.append(filterValue);\n            }\n\n            return convertedValue.toString();\n        }\n        \n        JComponent getUI() {\n            if (ui == null) {\n                JPanel p = new JPanel(new GridBagLayout());\n                p.setOpaque(false);\n                \n                GridBagConstraints c;\n        \n                JPanel classesPanel = new SettingsPanel();\n                classesPanel.add(new JLabel(Bundle.SQLFeatureModes_queryContains()));\n                c = new GridBagConstraints();\n                c.gridx = 0;\n                c.gridy = 0;\n                c.fill = GridBagConstraints.NONE;\n                c.insets = new Insets(0, 0, 0, 5);\n                c.anchor = GridBagConstraints.NORTHWEST;\n                p.add(classesPanel, c);\n\n                final JScrollPane[] container = new JScrollPane[1];\n                filterArea = new TextArea(readFlag(QUERIES_FILTER_FLAG, \"\")) { // NOI18N\n                    protected void changed() {\n                        settingsChanged();\n                    }\n                    protected boolean changeSize(boolean vertical, boolean direction) {\n                        if (vertical) {\n                            int rows = readRows();\n                            if (direction) rows = Math.min(rows + 1, MAX_ROWS);\n                            else rows = Math.max(rows - 1, MIN_ROWS);\n                            storeRows(rows);\n                        } else {\n                            int cols = readColumns();\n                            if (direction) cols = Math.min(cols + 3, MAX_COLUMNS);\n                            else cols = Math.max(cols - 3, MIN_COLUMNS);\n                            storeColumns(cols);\n                        }\n                        \n                        layoutImpl();                        \n                        return true;\n                    }\n                    protected boolean resetSize() {\n                        storeRows(DEFAULT_ROWS);\n                        storeColumns(DEFAULT_COLUMNS);\n                \n                        layoutImpl();\n                        return true;\n                    }\n                    private void layoutImpl() {\n                        setRows(readRows());\n                        setColumns(readColumns());\n                        container[0].setPreferredSize(null);\n                        container[0].setPreferredSize(container[0].getPreferredSize());\n                        container[0].setMinimumSize(container[0].getPreferredSize());\n                        JComponent root = SwingUtilities.getRootPane(container[0]);\n                        root.doLayout();\n                        root.repaint();\n                        setColumns(0);\n                    }\n                    protected void customizePopup(JPopupMenu popup) {\n                        popup.addSeparator();\n                        popup.add(createResizeMenu());\n                    }\n                    public Point getToolTipLocation(MouseEvent event) {\n                        Component scroll = getParent().getParent();\n                        return SwingUtilities.convertPoint(scroll, 0, scroll.getHeight(), this);\n                    }\n                };\n                filterArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, filterArea.getFont().getSize()));\n                filterArea.setRows(readRows());\n                filterArea.setColumns(readColumns());\n                container[0] = new JScrollPane(filterArea);\n                container[0].setPreferredSize(container[0].getPreferredSize());\n                container[0].setMinimumSize(container[0].getPreferredSize());\n                filterArea.setColumns(0);\n                filterArea.setHint(Bundle.SQLFeatureModes_filterHint());\n                c = new GridBagConstraints();\n                c.gridx = 1;\n                c.gridy = 0;\n                c.weightx = 1;\n                c.weighty = 1;\n                c.fill = GridBagConstraints.VERTICAL;\n                c.insets = new Insets(0, 0, 0, 5);\n                c.anchor = GridBagConstraints.NORTHWEST;\n                p.add(container[0], c);\n                \n                ui = p;\n                \n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() { settingsChanged(); }\n                });\n            }\n            return ui;\n        }\n        \n        private int readRows() {\n            return NbPreferences.forModule(SQLFeatureModes.class).getInt(\"SQLFeatureModes.rows\", DEFAULT_ROWS); // NOI18N\n        }\n        \n        private void storeRows(int rows) {\n            NbPreferences.forModule(SQLFeatureModes.class).putInt(\"SQLFeatureModes.rows\", rows); // NOI18N\n        }\n        \n        private int readColumns() {\n            return NbPreferences.forModule(SQLFeatureModes.class).getInt(\"SQLFeatureModes.columns\", DEFAULT_COLUMNS); // NOI18N\n        }\n        \n        private void storeColumns(int columns) {\n            NbPreferences.forModule(SQLFeatureModes.class).putInt(\"SQLFeatureModes.columns\", columns); // NOI18N\n        }\n        \n        private JComponent ui;\n        private TextArea filterArea;\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/SQLFeatureUI.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.jdbc.LiveJDBCView;\nimport org.graalvm.visualvm.lib.ui.jdbc.LiveJDBCViewUpdater;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.profiler.actions.ResetResultsAction;\nimport org.graalvm.visualvm.lib.profiler.actions.TakeSnapshotAction;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"LocksFeatureUI_SqlQueryCaption=SQL Query Viewer\",\n    \"LocksFeatureUI_SqlQueryLabel=SQL Query:\"\n})\nabstract class SQLFeatureUI extends FeatureUI {\n\n    private ProfilerToolbar toolbar;\n    private LiveJDBCView jdbcView;\n    private LiveJDBCViewUpdater updater;\n\n\n    // --- External implementation ---------------------------------------------\n        \n    abstract void selectForProfiling(ClientUtils.SourceCodeSelection value);\n    \n    abstract Lookup.Provider getProject();\n    \n    abstract ProfilerClient getProfilerClient();\n    \n    abstract void refreshResults();\n    \n   \n    // --- API implementation --------------------------------------------------\n    \n    ProfilerToolbar getToolbar() {\n        if (toolbar == null) initUI();\n        return toolbar;\n    }\n\n    JPanel getResultsUI() {\n        if (jdbcView == null) initUI();\n        return jdbcView;\n    }\n    \n    \n    void sessionStateChanged(int sessionState) {\n        refreshToolbar(sessionState);\n        \n//        if (sessionState == Profiler.PROFILING_INACTIVE || sessionState == Profiler.PROFILING_IN_TRANSITION) {\n//            if (jdbcView != null) jdbcView.profilingSessionFinished();\n//        } else if (sessionState == Profiler.PROFILING_RUNNING) {\n//            if (jdbcView != null) jdbcView.profilingSessionStarted();\n//        }\n    }\n\n    void resetPause() {\n        if (lrPauseButton != null) lrPauseButton.setSelected(false);\n    }\n    \n    void setForceRefresh() {\n        if (updater != null) updater.setForceRefresh(true);\n    }\n    \n    void refreshData() throws ClientUtils.TargetAppOrVMTerminated {\n        if (updater != null) updater.update();\n    }\n        \n    void resetData() {\n        if (lrDeltasButton != null) {\n            lrDeltasButton.setSelected(false);\n            lrDeltasButton.setToolTipText(Bundle.MethodsFeatureUI_showDeltas());\n        }\n        if (jdbcView != null) {\n            jdbcView.resetData();\n            jdbcView.setDiffView(false);\n        }\n    }\n    \n    void cleanup() {\n        if (jdbcView != null) jdbcView.cleanup();\n    }\n    \n    \n    // --- UI ------------------------------------------------------------------    \n    \n    private JLabel lrLabel;\n    private JToggleButton lrPauseButton;\n    private JButton lrRefreshButton;\n    private JToggleButton lrDeltasButton;\n    \n    private JLabel pdLabel;\n    private JButton pdSnapshotButton;\n    private JButton pdResetResultsButton;\n    \n    private boolean popupPause;\n    \n    \n    private void initUI() {\n        \n        assert SwingUtilities.isEventDispatchThread();\n        \n        // --- Results ---------------------------------------------------------\n\n        jdbcView = new LiveJDBCView(null) {\n            protected ProfilerClient getProfilerClient() {\n                return SQLFeatureUI.this.getProfilerClient();\n            }\n            protected boolean showSourceSupported() {\n                return GoToSource.isAvailable();\n            }\n            protected void showSource(ClientUtils.SourceCodeSelection value) {\n                Lookup.Provider project = getProject();\n                String className = value.getClassName();\n                String methodName = value.getMethodName();\n                String methodSig = value.getMethodSignature();\n                GoToSource.openSource(project, className, methodName, methodSig);\n            }\n            protected void showSQLQuery(String query, String htmlQuery) {\n                    HTMLTextArea area = new HTMLTextArea(htmlQuery);\n                    JScrollPane areaScroll = new JScrollPane(area);\n                    areaScroll.setPreferredSize(new Dimension(500, 250));\n                    JLabel label = new JLabel(Bundle.LocksFeatureUI_SqlQueryLabel(), JLabel.LEADING);\n                    label.setBorder(BorderFactory.createEmptyBorder(0, 0, 3, 0));\n                    label.setLabelFor(area);\n                    JPanel panel = new JPanel(new BorderLayout());\n                    panel.add(label, BorderLayout.NORTH);\n                    panel.add(areaScroll, BorderLayout.CENTER);\n                    panel.setBorder(BorderFactory.createEmptyBorder(12, 10, 0, 10));\n                    HelpCtx help = new HelpCtx(\"SqlQueryViewer.HelpCtx\"); // NOI18N\n                    DialogDisplayer.getDefault().notify(new DialogDescriptor(panel,\n                            Bundle.LocksFeatureUI_SqlQueryCaption(), false,\n                            new Object[] { DialogDescriptor.CLOSED_OPTION },\n                            DialogDescriptor.CLOSED_OPTION, DialogDescriptor.BOTTOM_ALIGN, help, null));\n                }\n            protected void selectForProfiling(ClientUtils.SourceCodeSelection value) {\n                SQLFeatureUI.this.selectForProfiling(value);\n            }\n            protected void popupShowing() {\n                if (lrPauseButton.isEnabled() && !lrRefreshButton.isEnabled()) {\n                    popupPause = true;\n                    lrPauseButton.setSelected(true);\n                }\n            }\n            protected void popupHidden() {\n                if (lrPauseButton.isEnabled() && popupPause) {\n                    popupPause = false;\n                    lrPauseButton.setSelected(false);\n                }\n            }\n        };\n        \n        jdbcView.putClientProperty(\"HelpCtx.Key\", \"ProfileSQL.HelpCtx\"); // NOI18N\n        \n        updater = new LiveJDBCViewUpdater(jdbcView, getProfilerClient());\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        lrLabel = new GrayLabel(Bundle.MethodsFeatureUI_liveResults());\n            \n        lrPauseButton = new JToggleButton(Icons.getIcon(GeneralIcons.PAUSE)) {\n            protected void fireItemStateChanged(ItemEvent event) {\n                boolean paused = isSelected();\n                updater.setPaused(paused);\n                if (!paused) refreshResults();\n                refreshToolbar(getSessionState());\n            }\n        };\n        lrPauseButton.setToolTipText(Bundle.MethodsFeatureUI_pauseResults());\n        lrPauseButton.setEnabled(false);\n\n        lrRefreshButton = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                refreshResults();\n            }\n        };\n        lrRefreshButton.setToolTipText(Bundle.MethodsFeatureUI_updateResults());\n        \n        Icon icon = Icons.getIcon(ProfilerIcons.DELTA_RESULTS);\n        lrDeltasButton = new JToggleButton(icon) {\n            protected void fireActionPerformed(ActionEvent e) {\n                if (!jdbcView.setDiffView(isSelected())) setSelected(false);\n                setToolTipText(isSelected() ? Bundle.MethodsFeatureUI_showAbsolute() :\n                                              Bundle.MethodsFeatureUI_showDeltas());\n            }\n        };\n        lrDeltasButton.setToolTipText(Bundle.MethodsFeatureUI_showDeltas());\n        \n        pdLabel = new GrayLabel(Bundle.MethodsFeatureUI_profilingData());\n\n        pdSnapshotButton = new JButton(TakeSnapshotAction.getInstance());\n        pdSnapshotButton.setHideActionText(true);\n\n        pdResetResultsButton = new JButton(ResetResultsAction.getInstance());\n        pdResetResultsButton.setHideActionText(true);\n\n        toolbar = ProfilerToolbar.create(true);\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(lrLabel);\n        toolbar.addSpace(2);\n        toolbar.add(lrPauseButton);\n        toolbar.add(lrRefreshButton);\n        \n        toolbar.addSpace(5);\n        toolbar.add(lrDeltasButton);\n        \n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(pdLabel);\n        toolbar.addSpace(2);\n        toolbar.add(pdSnapshotButton);\n        toolbar.addSpace(3);\n        toolbar.add(pdResetResultsButton);\n\n\n        // --- Sync UI ---------------------------------------------------------\n        \n        sessionStateChanged(getSessionState());\n\n    }\n    \n    private void refreshToolbar(final int state) {\n        if (toolbar != null) SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n//                boolean running = isRunning(state);\n                boolean running = state == Profiler.PROFILING_RUNNING;\n                lrPauseButton.setEnabled(running);\n                lrRefreshButton.setEnabled(!popupPause && running && lrPauseButton.isSelected());\n                lrDeltasButton.setEnabled(running);\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/ThreadsFeature.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerFeature;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ThreadsFeature_name=Threads\",\n    \"ThreadsFeature_description=Monitor thread states and times\"\n})\nfinal class ThreadsFeature extends ProfilerFeature.Basic {\n\n    private ThreadsFeature(ProfilerSession session) {\n        super(Icons.getIcon(ProfilerIcons.WINDOW_THREADS), Bundle.ThreadsFeature_name(),\n              Bundle.ThreadsFeature_description(), 15, session);\n    }\n\n\n    // --- Settings ------------------------------------------------------------\n\n    public void configureSettings(ProfilingSettings settings) {\n        settings.setThreadsMonitoringEnabled(true);\n    }\n\n\n    // --- Toolbar & Results UI ------------------------------------------------\n\n    private ThreadsFeatureUI ui;\n\n    public JPanel getResultsUI() {\n        return getUI().getResultsUI();\n    }\n\n    public ProfilerToolbar getToolbar() {\n        return getUI().getToolbar();\n    }\n\n    private ThreadsFeatureUI getUI() {\n        if (ui == null) ui = new ThreadsFeatureUI() {\n            int getSessionState() {\n                return ThreadsFeature.this.getSessionState();\n            }\n            Profiler getProfiler() {\n                return ThreadsFeature.this.getSession().getProfiler();\n            }\n        };\n        return ui;\n    }\n    \n    \n    // --- Session lifecycle ---------------------------------------------------\n    \n    public void notifyActivated() {\n        getSession().getProfiler().getThreadsManager().resetStates();\n    }\n    \n    public void notifyDeactivated() {\n        getSession().getProfiler().getThreadsManager().resetStates();\n        \n        if (ui != null) {\n            ui.cleanup();\n            ui = null;\n        }\n    }\n    \n    \n    protected void profilingStateChanged(int oldState, int newState) {\n        if (newState == Profiler.PROFILING_STARTED)\n            getSession().getProfiler().getThreadsManager().reset();\n        \n        if (ui != null) ui.sessionStateChanged(getSessionState());\n    }\n    \n    \n    // --- Provider ------------------------------------------------------------\n    \n    @ServiceProvider(service=ProfilerFeature.Provider.class)\n    public static final class Provider extends ProfilerFeature.Provider {\n        public ProfilerFeature getFeature(ProfilerSession session) {\n            return new ThreadsFeature(session);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/features/ThreadsFeatureUI.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.features;\n\nimport java.awt.event.ActionEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.ActionPopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.threads.ThreadsPanel;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ThreadsFeatureUI_show=Show:\",\n    \"ThreadsFeatureUI_filterAll=All threads\",\n    \"ThreadsFeatureUI_filterLive=Live threads\",\n    \"ThreadsFeatureUI_filterFinished=Finished threads\",\n    \"ThreadsFeatureUI_filterSelected=Selected threads\",\n    \"ThreadsFeatureUI_timeline=Timeline:\",\n    \"ThreadsFeatureUI_threadsFilter=Threads filter\",\n    \"# HTML formatted:\",\n    \"ThreadsFeatureUI_noThreadsMsg=<html><b>No threads are currently selected.</b><br><br>Use the Selected column or invoke Select thread action to select threads.</html>\"\n})\nabstract class ThreadsFeatureUI extends FeatureUI {\n\n    private ProfilerToolbar toolbar;\n    private ThreadsPanel threadsView;\n\n\n    // --- External implementation ---------------------------------------------\n\n    abstract Profiler getProfiler();\n\n\n    // --- API implementation --------------------------------------------------\n\n    ProfilerToolbar getToolbar() {\n        if (toolbar == null) initUI();\n        return toolbar;\n    }\n\n    JPanel getResultsUI() {\n        if (threadsView == null) initUI();\n        return threadsView;\n    }\n\n\n    void cleanup() {\n        if (threadsView != null) threadsView.cleanup();\n    }\n    \n    \n    void sessionStateChanged(int sessionState) {\n        refreshToolbar(sessionState);\n        \n        if (sessionState == Profiler.PROFILING_INACTIVE || sessionState == Profiler.PROFILING_IN_TRANSITION) {\n            if (threadsView != null) threadsView.profilingSessionFinished();\n        } else if (sessionState == Profiler.PROFILING_RUNNING) {\n            if (threadsView != null) threadsView.profilingSessionStarted();\n        }\n    }\n    \n    \n    // --- UI ------------------------------------------------------------------\n    \n    private JLabel shLabel;\n    private ActionPopupButton shFilter;\n    \n    private JLabel tlLabel;\n    private JComponent tlZoomInButton;\n    private JComponent tlZoomOutButton;\n    private JComponent tlFitWidthButton;\n    \n    \n    private void initUI() {\n        \n        assert SwingUtilities.isEventDispatchThread();\n        \n        // --- Results ---------------------------------------------------------\n        \n        threadsView = new ThreadsPanel(getProfiler().getThreadsManager(), null) {\n            protected void filterSelected(ThreadsPanel.Filter filter) {\n                super.filterSelected(filter);\n                shFilter.selectAction(filter.ordinal());\n            }\n        };\n        threadsView.threadsMonitoringEnabled();\n        \n        threadsView.putClientProperty(\"HelpCtx.Key\", \"ProfileThreads.HelpCtx\"); // NOI18N\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        shLabel = new GrayLabel(Bundle.ThreadsFeatureUI_show());\n\n        Action aAll = new AbstractAction() {\n            { putValue(NAME, Bundle.ThreadsFeatureUI_filterAll()); }\n            public void actionPerformed(ActionEvent e) { setFilter(ThreadsPanel.Filter.ALL); }\n            \n        };\n        Action aLive = new AbstractAction() {\n            { putValue(NAME, Bundle.ThreadsFeatureUI_filterLive()); }\n            public void actionPerformed(ActionEvent e) { setFilter(ThreadsPanel.Filter.LIVE); }\n            \n        };\n        Action aFinished = new AbstractAction() {\n            { putValue(NAME, Bundle.ThreadsFeatureUI_filterFinished()); }\n            public void actionPerformed(ActionEvent e) { setFilter(ThreadsPanel.Filter.FINISHED); }\n            \n        };\n        Action aSelected = new AbstractAction() {\n            { putValue(NAME, Bundle.ThreadsFeatureUI_filterSelected()); }\n            public void actionPerformed(ActionEvent e) { setSelectedFilter(); }\n            \n        };\n        shFilter = new ActionPopupButton(aAll, aLive, aFinished, aSelected);\n        shFilter.setToolTipText(Bundle.ThreadsFeatureUI_threadsFilter());\n\n        tlLabel = new GrayLabel(Bundle.ThreadsFeatureUI_timeline());\n\n\n        tlZoomInButton = (JComponent)threadsView.getZoomIn();\n        tlZoomInButton.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        tlZoomInButton.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        tlZoomOutButton = (JComponent)threadsView.getZoomOut();\n        tlZoomOutButton.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        tlZoomOutButton.putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n        tlFitWidthButton = (JComponent)threadsView.getFitWidth();\n        tlFitWidthButton.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        tlFitWidthButton.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n\n        toolbar = ProfilerToolbar.create(true);\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(shLabel);\n        toolbar.addSpace(2);\n        toolbar.add(shFilter);\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(tlLabel);\n        toolbar.addSpace(2);\n        toolbar.add(tlZoomInButton);\n        toolbar.add(tlZoomOutButton);\n        toolbar.add(tlFitWidthButton);\n        \n        \n        // --- Sync UI ---------------------------------------------------------\n\n        setFilter(ThreadsPanel.Filter.LIVE);\n        sessionStateChanged(getSessionState());\n        \n    }\n    \n    private void refreshToolbar(final int state) {\n//        if (toolbar != null) SwingUtilities.invokeLater(new Runnable() {\n//            public void run() {\n//            }\n//        });\n    }\n    \n    private void setSelectedFilter() {\n        if (threadsView.hasSelectedThreads()) {\n            setFilter(ThreadsPanel.Filter.SELECTED);\n        } else {\n            threadsView.showSelectedColumn();\n            shFilter.selectAction(threadsView.getFilter().ordinal());\n            ProfilerDialogs.displayWarning(Bundle.ThreadsFeatureUI_noThreadsMsg());\n        }\n    }\n\n    private void setFilter(ThreadsPanel.Filter filter) {\n        threadsView.setFilter(filter);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/impl/ClassMethodList.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Image;\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.AbstractListModel;\nimport javax.swing.BorderFactory;\nimport javax.swing.BoxLayout;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.ListCellRenderer;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.SwingConstants;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerPopup;\nimport org.graalvm.visualvm.lib.ui.swing.SmallButton;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatter;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.DefaultMethodNameFormatter;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceClassInfo;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceMethodInfo;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ClassMethodList_addMethod=Add method\",\n    \"ClassMethodList_removeMethods=Remove selected methods\",\n    \"ClassMethodList_addClass=Add class\",\n    \"ClassMethodList_removeClasses=Remove selected classes\",\n    \"ClassMethodList_selectedMethods=Selected methods:\",\n    \"ClassMethodList_selectedClasses=Selected classes:\"\n})\npublic final class ClassMethodList {\n    \n    public static void showClasses(ProfilerSession session, Set<ClientUtils.SourceCodeSelection> selection, Component invoker) {\n        UI.forClasses(session, selection).show(invoker);\n    }\n    \n    public static void showMethods(ProfilerSession session, Set<ClientUtils.SourceCodeSelection> selection, Component invoker) {\n        UI.forMethods(session, selection).show(invoker);\n    }\n    \n    \n    private ClassMethodList() {}\n    \n    private static class UI {\n        \n        private JPanel panel;\n        \n        static UI forClasses(ProfilerSession session, Set<ClientUtils.SourceCodeSelection> selection) {\n            return new UI(session, selection, false);\n        }\n        \n        static UI forMethods(ProfilerSession session, Set<ClientUtils.SourceCodeSelection> selection) {\n            return new UI(session, selection, true);\n        }\n        \n        \n        void show(Component invoker) {\n            int resizeMode = ProfilerPopup.RESIZE_BOTTOM | ProfilerPopup.RESIZE_RIGHT;\n            ProfilerPopup.createRelative(invoker, panel, SwingConstants.SOUTH_WEST, resizeMode).show();\n        }\n        \n        \n        private UI(final ProfilerSession session, final Set<ClientUtils.SourceCodeSelection> selection, final boolean methods) {\n            \n            JPanel content = new JPanel(new BorderLayout());\n            \n            JLabel hint = new JLabel(methods ? Bundle.ClassMethodList_selectedMethods() :\n                                                  Bundle.ClassMethodList_selectedClasses(), JLabel.LEADING);\n            hint.setBorder(BorderFactory.createEmptyBorder(0, 0, 6, 0));\n            content.add(hint, BorderLayout.NORTH);\n            \n            class XListModel extends AbstractListModel<ClientUtils.SourceCodeSelection> {\n                public int getSize() {\n                    return selection.size();\n                }\n                public ClientUtils.SourceCodeSelection getElementAt(int index) {\n                    return (ClientUtils.SourceCodeSelection)new ArrayList(selection).get(index);\n                }\n                public void refresh() {\n                    super.fireContentsChanged(this, 0, getSize());\n                }\n            }\n            \n            final XListModel xmodel = new XListModel();\n            final JList list = new JList(xmodel) {\n                public Dimension getPreferredScrollableViewportSize() {\n                    Dimension dim = super.getPreferredScrollableViewportSize();\n                    dim.width = 420;\n                    return dim;\n                }\n            };\n            list.setBackground(UIUtils.getProfilerResultsBackground());\n            int format = methods ? DefaultMethodNameFormatter.VERBOSITY_CLASSMETHOD :\n                                   DefaultMethodNameFormatter.VERBOSITY_CLASS;\n            final MethodNameFormatter formatter = new DefaultMethodNameFormatter(format);\n            final JavaNameRenderer renderer = new JavaNameRenderer();\n            list.setCellRenderer(new ListCellRenderer() {\n                public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {\n                    renderer.setValue(formatter.formatMethodName((ClientUtils.SourceCodeSelection)value).toFormatted(), index);\n                    JComponent c = renderer.getComponent();\n                    if (isSelected) {\n                        c.setForeground(list.getSelectionForeground());\n                        c.setBackground(list.getSelectionBackground());\n                    } else {\n                        c.setForeground(list.getForeground());\n                        c.setBackground((index & 0x1) == 0 ? list.getBackground() :\n                                         UIUtils.getDarker(list.getBackground()));\n                    }\n                    return c;\n                }\n            });\n            \n            String iconMask = methods ? LanguageIcons.METHOD : LanguageIcons.CLASS;\n            Image baseIcon = Icons.getImage(iconMask);\n            Image addBadge = Icons.getImage(GeneralIcons.BADGE_ADD);\n            Image addImage = ImageUtilities.mergeImages(baseIcon, addBadge, 0, 0);\n            final JButton addB = new SmallButton(ImageUtilities.image2Icon(addImage)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    Collection<ClientUtils.SourceCodeSelection> sel = null;\n                    \n                    if (methods) {\n                        Collection<SourceMethodInfo> mtd = ClassMethodSelector.selectMethods(session);\n                        if (!mtd.isEmpty()) {\n                            sel = new HashSet();\n                            for (SourceMethodInfo smi : mtd) sel.add(\n                                    new ClientUtils.SourceCodeSelection(smi.getClassName(),\n                                                                        smi.getName(), smi.getSignature()));\n                        }\n                    } else {\n                        Collection<SourceClassInfo> cls = ClassMethodSelector.selectClasses(session);\n                        if (!cls.isEmpty()) {\n                            sel = new HashSet();\n                            for (SourceClassInfo sci : cls) sel.add(new ClientUtils.SourceCodeSelection(\n                                    sci.getQualifiedName(), Wildcards.ALLWILDCARD, null));\n                        }\n                    }\n                    \n                    if (sel != null) {\n                        selection.addAll(sel);\n                        xmodel.refresh();\n                    }\n                }   \n            };\n            addB.setToolTipText(methods ? Bundle.ClassMethodList_addMethod() :\n                                          Bundle.ClassMethodList_addClass());\n            \n            Image removeBadge = Icons.getImage(GeneralIcons.BADGE_REMOVE);\n            Image removeImage = ImageUtilities.mergeImages(baseIcon, removeBadge, 0, 0);\n            final JButton removeB = new SmallButton(ImageUtilities.image2Icon(removeImage)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    selection.removeAll(list.getSelectedValuesList());\n                    xmodel.refresh();\n                    list.clearSelection();\n                    setEnabled(false);\n                }\n            };\n            removeB.setToolTipText(methods ? Bundle.ClassMethodList_removeMethods() :\n                                             Bundle.ClassMethodList_removeClasses());\n            removeB.setEnabled(false);\n            \n            \n            list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);\n            list.addListSelectionListener(new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent e) {\n                    if (e.getValueIsAdjusting()) return;\n                    removeB.setEnabled(list.getSelectedValue() != null);\n                }\n            });\n            \n            JScrollPane scroll = new JScrollPane(list);\n            hint.setLabelFor(scroll);\n            content.add(scroll, BorderLayout.CENTER);\n            \n            JPanel buttons = new JPanel(null);\n            buttons.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0));\n            buttons.setLayout(new BoxLayout(buttons, BoxLayout.Y_AXIS));\n            buttons.add(addB);\n            buttons.add(removeB);\n            content.add(buttons, BorderLayout.EAST);\n            \n            panel = content;            \n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/impl/ClassMethodSelector.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.GridLayout;\nimport java.awt.Image;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.io.File;\nimport java.lang.reflect.Modifier;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.Enumeration;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.TreeSet;\nimport java.util.prefs.Preferences;\nimport javax.swing.AbstractButton;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.DefaultListCellRenderer;\nimport javax.swing.DefaultListModel;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTabbedPane;\nimport javax.swing.JToggleButton;\nimport javax.swing.JToolBar;\nimport javax.swing.ListModel;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.event.ListDataEvent;\nimport javax.swing.event.ListDataListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.filechooser.FileFilter;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.FilteringToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.DefaultMethodNameFormatter;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.Formattable;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatter;\nimport org.graalvm.visualvm.lib.profiler.api.ProjectUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.java.ExternalPackages;\nimport org.graalvm.visualvm.lib.profiler.api.java.ProfilerTypeUtils;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceClassInfo;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceMethodInfo;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourcePackageInfo;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.graalvm.visualvm.lib.profiler.v2.SessionStorage;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.filesystems.FileChooserBuilder;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ClassMethodSelector_selectClass=Select Class\",\n    \"ClassMethodSelector_selectMethod=Select Method\",\n    \"ClassMethodSelector_btnOk=OK\",\n    \"ClassMethodSelector_capFromProject=From Project\",\n    \"ClassMethodSelector_capFromJarFolder=From JAR/Folder\",\n    \"ClassMethodSelector_capFiles=Files:\",\n    \"ClassMethodSelector_jarsFoldersFilterDescr=.jar files/.class folders\",\n    \"ClassMethodSelector_selectJarOrFolder=Select JAR File or Class Folder\",\n    \"ClassMethodSelector_addFileOrFolder=Add file or folder\",\n    \"ClassMethodSelector_removeSelectedItem=Remove selected item\",\n    \"ClassMethodSelector_capProjects=Projects:\",\n    \"ClassMethodSelector_capPackages=Packages:\",\n    \"ClassMethodSelector_showProjectPackages=Show project packages\",\n    \"ClassMethodSelector_showDependenciesPackages=Show dependencies packages\",\n    \"ClassMethodSelector_capClasses=Classes:\",\n    \"ClassMethodSelector_showInnerClasses=Show inner classes\",\n    \"ClassMethodSelector_showAnonymousClasses=Show anonymous classes\",\n    \"ClassMethodSelector_capMethods=Methods:\",\n    \"ClassMethodSelector_showInheritedMethods=Show inherited methods\",\n    \"ClassMethodSelector_showNonPublicMethods=Show non-public methods\",\n    \"ClassMethodSelector_showStaticMethods=Show static methods\",\n    \"ClassMethodSelector_lblComputing=Computing...\",\n    \"ClassMethodSelector_lblNoItems=No items\",\n    \"ClassMethodSelector_lblNoSelection=No selection\",\n    \"ClassMethodSelector_lblFilterItems=Filter items\"\n})\npublic final class ClassMethodSelector {\n    \n    private static final WeakProcessor PROCESSOR = new WeakProcessor(\"Profiler ClassMethodSelector Processor\"); // NOI18N\n    private static final MethodNameFormatter METHOD_FORMATTER = new DefaultMethodNameFormatter(DefaultMethodNameFormatter.VERBOSITY_METHOD);\n    \n    public static List<SourceClassInfo> selectClasses(ProfilerSession session) {\n        // TODO: wait for finished scan\n        \n        UI ui = UI.forSession(session, false);\n\n        HelpCtx helpCtx = new HelpCtx(\"SelectClassDialog.HelpCtx\"); // NOI18N\n        DialogDescriptor dd = new DialogDescriptor(ui, Bundle.ClassMethodSelector_selectClass(), true,\n                                                   new Object[] { ui.getOKButton(), DialogDescriptor.CANCEL_OPTION },\n                                                   ui.getOKButton(), DialogDescriptor.BOTTOM_ALIGN, helpCtx, null);\n        Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n        d.setVisible(true);\n        \n        return dd.getValue() == ui.getOKButton() ? ui.selectedClasses() : Collections.EMPTY_LIST;\n    }\n    \n    public static List<SourceMethodInfo> selectMethods(ProfilerSession session) {\n        // TODO: wait for finished scan\n        \n        UI ui = UI.forSession(session, true);\n\n        HelpCtx helpCtx = new HelpCtx(\"SelectMethodDialog.HelpCtx\"); // NOI18N\n        DialogDescriptor dd = new DialogDescriptor(ui, Bundle.ClassMethodSelector_selectMethod(), true,\n                                                   new Object[] { ui.getOKButton(), DialogDescriptor.CANCEL_OPTION },\n                                                   ui.getOKButton(), DialogDescriptor.BOTTOM_ALIGN, helpCtx, null);\n        Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n        d.setVisible(true);\n        \n        return dd.getValue() == ui.getOKButton() ? ui.selectedMethods() : Collections.EMPTY_LIST;\n    }\n    \n    \n    private ClassMethodSelector() {}\n    \n    \n    // --- UI ------------------------------------------------------------------\n    \n    private static final int LIST_WIDTH = 200;\n    private static final Preferences PREF = NbPreferences.forModule(ClassMethodSelector.class);\n    \n    private static class UI extends JPanel {\n        \n        private final JButton okButton;\n        \n        private final JPanel p_selectors;\n        private final MethodSelector p_methodSelector;\n        private final ClassSelector p_classSelector;\n        private final PackageSelector p_packageSelector;\n        private final ProjectSelector p_projectSelector;\n        \n        private final JPanel f_selectors;\n        private final MethodSelector f_methodSelector;\n        private final ClassSelector f_classSelector;\n        private final PackageSelector f_packageSelector;\n        private final FileSelector f_fileSelector;\n        \n        private JComponent selected;\n        \n        \n        static UI forSession(ProfilerSession session, boolean method) {\n            return new UI(session, method);\n        }\n        \n        JButton getOKButton() {\n            return okButton;\n        }\n        \n        List<SourceClassInfo> selectedClasses() {\n            if (p_selectors == selected && p_classSelector != null) {\n                return p_classSelector.getAllSelected();\n            } else if (f_selectors == selected && f_classSelector != null) {\n                return f_classSelector.getAllSelected();\n            }\n            return null;\n        }\n        \n        List<SourceMethodInfo> selectedMethods() {\n            if (p_selectors == selected && p_methodSelector != null) {\n                return p_methodSelector.getAllSelected();\n            } else if (f_selectors == selected && f_methodSelector != null) {\n                return f_methodSelector.getAllSelected();\n            }\n            return null;\n        }\n        \n        \n        private UI(final ProfilerSession session, final boolean method) {\n            okButton = new JButton(Bundle.ClassMethodSelector_btnOk());\n            okButton.setEnabled(false);\n            \n            // --- From Project ------------------------------------------------\n            final boolean[] p_init = new boolean[1];\n            if (session.getProject() != null) {\n                if (method) {\n                    p_methodSelector = new MethodSelector() {\n                        void methodSelected() {\n                            okButton.setEnabled(getSelected() != null);\n                        }\n                        void reload() {\n                            init(p_classSelector.getSelected());\n                        }\n                    };\n                } else {\n                    p_methodSelector = null;\n                }\n\n                p_classSelector = new ClassSelector(method) {\n                    void classSelected() {\n                        if (!method) okButton.setEnabled(getSelected() != null);\n                        else p_methodSelector.init(getSelected());\n                    }\n                    void reload() {\n                        init(p_packageSelector.getSelected());\n                    }\n                };\n\n                p_packageSelector = new PackageSelector(true) {\n                    void packageSelected() {\n                        p_classSelector.init(getSelected());\n                    }\n                    void reload() {\n                        init(p_projectSelector.getSelected());\n                    }\n                };\n\n                p_projectSelector = new ProjectSelector() {\n                    void projectSelected() {\n                        p_packageSelector.init(getSelected());\n                    }\n                };\n\n                p_selectors = new JPanel(new GridLayout(1, method ? 4 : 3, 10, 10));\n                p_selectors.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));\n                p_selectors.add(p_projectSelector);\n                p_selectors.add(p_packageSelector);\n                p_selectors.add(p_classSelector);\n                if (method) p_selectors.add(p_methodSelector);\n            } else {\n                p_selectors = null;\n                p_methodSelector = null;\n                p_classSelector = null;\n                p_packageSelector = null;\n                p_projectSelector = null;\n            }\n            \n            // --- From File ---------------------------------------------------\n            final boolean[] f_init = new boolean[1];\n            if (method) {\n                f_methodSelector = new MethodSelector() {\n                    void methodSelected() {\n                        okButton.setEnabled(getSelected() != null);\n                    }\n                    void reload() {\n                        init(f_classSelector.getSelected());\n                    }\n                };\n            } else {\n                f_methodSelector = null;\n            }\n            \n            f_classSelector = new ClassSelector(method) {\n                void classSelected() {\n                    if (!method) okButton.setEnabled(getSelected() != null);\n                    else f_methodSelector.init(getSelected());\n                }\n                void reload() {\n                    init(f_packageSelector.getSelected());\n                }\n            };\n            \n            f_packageSelector = new PackageSelector(false) {\n                void packageSelected() {\n                    f_classSelector.init(getSelected());\n                }\n                void reload() {\n                    init(f_fileSelector.getSelected());\n                }\n            };\n            \n            f_fileSelector = new FileSelector() {\n                void fileSelected() {\n                    f_packageSelector.init(getSelected());\n                }\n                SessionStorage getStorage() {\n                    return session.getStorage();\n                }\n            };\n            \n            f_selectors = new JPanel(new GridLayout(1, method ? 4 : 3, 10, 10));\n            f_selectors.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));\n            f_selectors.add(f_fileSelector);\n            f_selectors.add(f_packageSelector);\n            f_selectors.add(f_classSelector);\n            if (method) f_selectors.add(f_methodSelector);\n            \n            // --- Views -------------------------------------------------------\n            \n            JTabbedPane p = new JTabbedPane() {\n                protected void fireStateChanged() {\n                    super.fireStateChanged();\n                    \n                    Component sel = getSelectedComponent();\n                    if (sel == p_selectors) {\n                        // Mark selected\n                        selected = p_selectors;\n                        // Init projects\n                        if (!p_init[0]) {\n                            p_projectSelector.init(session.getProject());\n                            p_init[0] = true;\n                        }\n                        // Update OK button\n                        if (p_methodSelector != null) p_methodSelector.methodSelected();\n                        else p_classSelector.classSelected();\n                    } else if (sel == f_selectors) {\n                        // Mark selected\n                        selected = f_selectors;\n                        // Init files\n                        if (!f_init[0]) {\n                            f_fileSelector.init();\n                            f_init[0] = true;\n                        }\n                        // Update OK button\n                        if (f_methodSelector != null) f_methodSelector.methodSelected();\n                        else f_classSelector.classSelected();\n                    }\n                }\n            };\n            if (UIUtils.isAquaLookAndFeel()) {\n                p.setBorder(BorderFactory.createEmptyBorder(0, -11, -13, -10));\n            } else {\n                Insets i = UIManager.getInsets(\"TabbedPane.contentBorderInsets\"); // NOI18N\n                if (i == null) p.setBorder(BorderFactory.createEmptyBorder());\n                else p.setBorder(BorderFactory.createEmptyBorder(0, -i.left, -i.bottom, -i.right));\n            }\n            if (p_selectors != null) p.addTab(Bundle.ClassMethodSelector_capFromProject(), null, p_selectors, null);\n            if (f_selectors != null) p.addTab(Bundle.ClassMethodSelector_capFromJarFolder(), null, f_selectors, null);\n            \n            setLayout(new BorderLayout());\n            setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n            add(p, BorderLayout.CENTER);\n        }\n        \n    }\n    \n    \n    private static abstract class FileSelector extends JPanel {\n        \n        abstract void fileSelected();\n        \n        abstract SessionStorage getStorage();\n        \n        FileObject getSelected() {\n            return fileList.getSelectedValue();\n        }\n        \n        void init() {\n            isInitialized = true;\n            \n            fileListModel.clear();\n            fileList.setEnabled(!isInitialized);\n            \n            if (isInitialized) {\n                PROCESSOR.post(new Runnable() {\n                    public void run() {\n                        SessionStorage _storage = getStorage();\n                        final Collection<FileObject> files = getFiles(_storage);\n                        \n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                fileList.setEnabled(true);\n                                for (FileObject fo : files) fileListModel.addElement(fo);\n                            }\n                        });\n                    }\n                });\n            }\n        }\n        \n        private static Collection<FileObject> getFiles(SessionStorage _storage) {\n            List<FileObject> files = new ArrayList();\n            String _files = _storage.readFlag(\"CMS.files\", \"\"); // NOI18N\n\n            if (!_files.isEmpty()) for (String file : _files.split(\"#\")) { // NOI18N\n                File f = new File(file);\n                FileObject fo = f.exists() ? FileUtil.toFileObject(\n                                FileUtil.normalizeFile(f)) : null;\n                if (fo != null) files.add(fo);\n            }\n            \n            return files;\n        }\n        \n        private void persist() {\n            StringBuilder sb = new StringBuilder();\n            Enumeration<FileObject> files = fileListModel.elements();\n            while (files.hasMoreElements()) {\n                FileObject file = files.nextElement();\n                sb.append(FileUtil.toFile(file).getAbsolutePath());\n                if (files.hasMoreElements()) sb.append(\"#\"); // NOI18N\n            }\n            if (sb.length() == 0) getStorage().storeFlag(\"CMS.files\", null); // NOI18N\n            else getStorage().storeFlag(\"CMS.files\", sb.toString()); // NOI18N\n        }\n        \n        \n        private final JList<FileObject> fileList;\n        private final DefaultListModel<FileObject> fileListModel;\n        private final AbstractButton addFileB;\n        private final AbstractButton removeFileB;\n        \n        private boolean isInitialized;\n        \n        FileSelector() {\n            fileListModel = new DefaultListModel();\n            final FilteredListModel<FileObject> filteredFiles = new FilteredListModel<FileObject>(fileListModel) {\n                protected boolean matchesFilter(FileObject file, GenericFilter filter) {\n                    return filter.passes(file.getNameExt());\n                }\n            };\n            final HintRenderer hintRenderer = new HintRenderer();\n            fileList = new JList(filteredFiles) {\n                public Dimension getPreferredScrollableViewportSize() {\n                    Dimension dim = super.getPreferredScrollableViewportSize();\n                    dim.width = LIST_WIDTH;\n                    return dim;\n                }\n                protected void paintComponent(Graphics g) {\n                    super.paintComponent(g);\n                    \n                    if (getModel().getSize() == 0) {\n                        hintRenderer.setup(true, getSize());\n                        hintRenderer.paint(g);\n                    }\n                }\n            };\n            fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n            filteredFiles.setSelectionModel(fileList.getSelectionModel());\n            fileList.setCellRenderer(new DefaultListCellRenderer() {\n                public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {\n                    DefaultListCellRenderer c = (DefaultListCellRenderer)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);\n                    FileObject file = (FileObject)value;\n                    c.setText(file.getNameExt());\n                    c.setIcon(Icons.getIcon(file.isFolder() ? LanguageIcons.LIBRARIES : LanguageIcons.JAR));\n                    return c;\n                }\n            });\n            fileList.addListSelectionListener(new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent e) {\n                    if (!e.getValueIsAdjusting()) {\n                        fileSelected();\n                        removeFileB.setEnabled(fileList.getSelectedValue() != null);\n                    }\n                }\n            });\n            \n            JLabel projectsLabel = new JLabel(Bundle.ClassMethodSelector_capFiles(), JLabel.LEADING);\n            projectsLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));\n            JToolBar fileTools = new FilteringToolbar(Bundle.ClassMethodSelector_lblFilterItems()) {\n                protected void filterChanged() {\n                    filteredFiles.setFilter(getFilter());\n                }\n            };\n            String iconMask = GeneralIcons.FOLDER;\n            Image baseIcon = Icons.getImage(iconMask);\n            Image addBadge = Icons.getImage(GeneralIcons.BADGE_ADD);\n            Image addImage = ImageUtilities.mergeImages(baseIcon, addBadge, 0, 0);\n            addFileB = new JButton(ImageUtilities.image2Icon(addImage)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    FileChooserBuilder b = new FileChooserBuilder(ClassMethodSelector.class);\n                    b.setAcceptAllFileFilterUsed(false);\n                    final File file = b.setFileFilter(new FileFilter() {\n                        public boolean accept(File f) {\n                            if (f.isDirectory()) {\n                                return true;\n                            }\n                            String ext = null;\n                            String n = f.getName();\n                            int index = n.lastIndexOf('.'); // NOI18N\n                            if (index > -1) {\n                                ext = n.substring(index + 1);\n                            }\n                            return ext != null && ext.equalsIgnoreCase(\"jar\"); // NOI18N\n                        }\n                        public String getDescription() {\n                            return Bundle.ClassMethodSelector_jarsFoldersFilterDescr();\n                        }\n                    }).setTitle(Bundle.ClassMethodSelector_selectJarOrFolder()).showOpenDialog();\n                    if (file != null) {\n                        FileObject f = FileUtil.toFileObject(FileUtil.normalizeFile(file));\n                        if (f != null) {\n                            fileListModel.addElement(f);\n                            persist();\n                        }\n                    }\n                }\n            };\n            addFileB.setToolTipText(Bundle.ClassMethodSelector_addFileOrFolder());\n            Image removeBadge = Icons.getImage(GeneralIcons.BADGE_REMOVE);\n            Image removeImage = ImageUtilities.mergeImages(baseIcon, removeBadge, 0, 0);\n            removeFileB = new JButton(ImageUtilities.image2Icon(removeImage)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    List<FileObject> files = fileList.getSelectedValuesList();\n                    if (!files.isEmpty()) {\n                        for (FileObject file : files) fileListModel.removeElement(file);\n                        persist();\n                    }\n                }\n            };\n            removeFileB.setToolTipText(Bundle.ClassMethodSelector_removeSelectedItem());\n            removeFileB.setEnabled(fileList.getSelectedValue() != null);\n            fileTools.add(Box.createHorizontalStrut(2));\n            fileTools.addSeparator();\n            fileTools.add(Box.createHorizontalStrut(2));\n            fileTools.add(addFileB);\n            fileTools.add(Box.createHorizontalStrut(2));\n            fileTools.add(removeFileB);\n            \n            setOpaque(false);\n            setLayout(new BorderLayout());\n            add(projectsLabel, BorderLayout.NORTH);\n            add(new JScrollPane(fileList), BorderLayout.CENTER);\n            add(fileTools, BorderLayout.SOUTH);\n        }\n        \n    }\n    \n    private static abstract class ProjectSelector extends JPanel {\n        \n        abstract void projectSelected();\n        \n        Lookup.Provider getSelected() {\n            return projectList.getSelectedValue();\n        }\n        \n        void init(final Lookup.Provider _project) {\n            isInitialized = true;\n            \n            projectListModel.clear();\n            projectList.setEnabled(!isInitialized);\n            \n            if (isInitialized) {\n                PROCESSOR.post(new Runnable() {\n                    public void run() {\n                        final Lookup.Provider[] projects = getProjects();\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                projectList.setEnabled(true);\n                                for (Lookup.Provider prj : projects) projectListModel.addElement(prj);\n                                if (_project != null) projectList.setSelectedValue(_project, true);\n                            }\n                        });\n                    }\n                });\n            }\n        }\n        \n        private static Lookup.Provider[] getProjects() {\n            return ProjectUtilities.getSortedProjects(ProjectUtilities.getOpenedProjects());\n        }\n        \n        \n        private final JList<Lookup.Provider> projectList;\n        private final DefaultListModel<Lookup.Provider> projectListModel;\n        \n        private boolean isInitialized;\n        \n        ProjectSelector() {\n            projectListModel = new DefaultListModel();\n            final FilteredListModel<Lookup.Provider> filteredProjects = new FilteredListModel<Lookup.Provider>(projectListModel) {\n                protected boolean matchesFilter(Lookup.Provider proj, GenericFilter filter) {\n                    return filter.passes(ProjectUtilities.getDisplayName(proj));\n                }\n            };\n            final HintRenderer hintRenderer = new HintRenderer();\n            projectList = new JList(filteredProjects) {\n                public Dimension getPreferredScrollableViewportSize() {\n                    Dimension dim = super.getPreferredScrollableViewportSize();\n                    dim.width = LIST_WIDTH;\n                    return dim;\n                }\n                protected void paintComponent(Graphics g) {\n                    super.paintComponent(g);\n                    \n                    if (getModel().getSize() == 0) {\n                        hintRenderer.setup(true, getSize());\n                        hintRenderer.paint(g);\n                    }\n                }\n            };\n            projectList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n            filteredProjects.setSelectionModel(projectList.getSelectionModel());\n            projectList.setCellRenderer(new DefaultListCellRenderer() {\n                public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {\n                    DefaultListCellRenderer c = (DefaultListCellRenderer)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);\n                    Lookup.Provider val = (Lookup.Provider)value;\n                    c.setText(ProjectUtilities.getDisplayName(val));\n                    c.setIcon(ProjectUtilities.getIcon(val));\n                    return c;\n                }\n            });\n            projectList.addListSelectionListener(new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent e) {\n                    if (!e.getValueIsAdjusting()) projectSelected();\n                }\n            });\n            \n            JLabel projectsLabel = new JLabel(Bundle.ClassMethodSelector_capProjects(), JLabel.LEADING);\n            projectsLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));\n            JToolBar projectsTools = new FilteringToolbar(Bundle.ClassMethodSelector_lblFilterItems()) {\n                protected void filterChanged() {\n                    filteredProjects.setFilter(getFilter());\n                }\n            };\n            \n            setOpaque(false);\n            setLayout(new BorderLayout());\n            add(projectsLabel, BorderLayout.NORTH);\n            add(new JScrollPane(projectList), BorderLayout.CENTER);\n            add(projectsTools, BorderLayout.SOUTH);\n        }\n        \n    }\n    \n    private static abstract class PackageSelector extends JPanel {\n        \n        abstract void packageSelected();\n        \n        abstract void reload();\n        \n        SourcePackageInfo getSelected() {\n            return packageList.getSelectedValue();\n        }\n        \n        void init(final Lookup.Provider _project) {\n            isInitialized = _project != null;\n            \n            packageListModel.clear();\n            packageList.setEnabled(!isInitialized);\n            \n            if (isInitialized) {\n                final boolean sources = packagesSourcesB.isSelected();\n                final boolean dependencies = packagesDependenciesB.isSelected();\n                \n                PROCESSOR.post(new Runnable() {\n                    public void run() {\n                        final Collection<SourcePackageInfo> packages = getProjectPackages(_project, sources, dependencies);\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                packageList.setEnabled(true);\n                                for (SourcePackageInfo pkg : packages)\n                                   packageListModel.addElement(pkg); \n                            }\n                        });\n                    }\n                });\n            }\n        }\n        \n        void init(final FileObject _file) {\n            isInitialized = _file != null;\n            \n            packageListModel.clear();\n            packageList.setEnabled(!isInitialized);\n            \n            if (isInitialized) {\n                PROCESSOR.post(new Runnable() {\n                    public void run() {\n                        final Collection<SourcePackageInfo> packages = getFilePackages(_file);\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                packageList.setEnabled(true);\n                                for (SourcePackageInfo pkg : packages)\n                                   packageListModel.addElement(pkg); \n                            }\n                        });\n                    }\n                });\n            }\n        }\n        \n        private static Collection<SourcePackageInfo> getProjectPackages(Lookup.Provider project, boolean sources, boolean dependencies) {\n            Set<SourcePackageInfo> packages = new HashSet();\n            if (sources) packages.addAll(ProfilerTypeUtils.getPackages(false, SourcePackageInfo.Scope.SOURCE, project));\n            if (dependencies) packages.addAll(ProfilerTypeUtils.getPackages(false, SourcePackageInfo.Scope.DEPENDENCIES, project));\n\n            Set<SourcePackageInfo> sortedPackages = new TreeSet<>(\n                new Comparator<SourcePackageInfo>() {\n                    public int compare(SourcePackageInfo p1, SourcePackageInfo p2) {\n                        return p1.getBinaryName().compareTo(p2.getBinaryName());\n                    }\n                }\n            );\n            sortedPackages.addAll(packages);\n            return sortedPackages;\n        }\n        \n        private static Collection<SourcePackageInfo> getFilePackages(FileObject file) {\n            Set<SourcePackageInfo> packages = new HashSet(ExternalPackages.forPath(file, true));\n\n            Set<SourcePackageInfo> sortedPackages = new TreeSet<>(\n                new Comparator<SourcePackageInfo>() {\n                    public int compare(SourcePackageInfo p1, SourcePackageInfo p2) {\n                        return p1.getBinaryName().compareTo(p2.getBinaryName());\n                    }\n                }\n            );\n            sortedPackages.addAll(packages);\n            return sortedPackages;\n        }\n        \n        \n        private final JList<SourcePackageInfo> packageList;\n        private final DefaultListModel<SourcePackageInfo> packageListModel;\n        private final AbstractButton packagesSourcesB;\n        private final AbstractButton packagesDependenciesB;\n        \n        private boolean isInitialized;\n        \n        PackageSelector(boolean fromProject) {\n            packageListModel = new DefaultListModel();\n            final FilteredListModel<SourcePackageInfo> filteredPackages = new FilteredListModel<SourcePackageInfo>(packageListModel) {\n                protected boolean matchesFilter(SourcePackageInfo pkg, GenericFilter filter) {\n                    return filter.passes(pkg.getBinaryName());\n                }\n            };\n            final HintRenderer hintRenderer = new HintRenderer();\n            packageList = new JList(filteredPackages) {\n                public Dimension getPreferredScrollableViewportSize() {\n                    Dimension dim = super.getPreferredScrollableViewportSize();\n                    dim.width = LIST_WIDTH;\n                    return dim;\n                }\n                protected void paintComponent(Graphics g) {\n                    super.paintComponent(g);\n                    \n                    if (getModel().getSize() == 0) {\n                        if (!isEnabled()) hintRenderer.setup(false, getSize());\n                        else if (isInitialized) hintRenderer.setup(true, getSize());\n                        else hintRenderer.setup(null, getSize());\n                        hintRenderer.paint(g);\n                    }\n                }\n            };\n            packageList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n            filteredPackages.setSelectionModel(packageList.getSelectionModel());\n            packageList.setCellRenderer(new DefaultListCellRenderer() {\n                public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {\n                    DefaultListCellRenderer c = (DefaultListCellRenderer)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);\n                    SourcePackageInfo val = (SourcePackageInfo)value;\n                    c.setText(val.getBinaryName());\n                    c.setIcon(Icons.getIcon(LanguageIcons.PACKAGE));\n                    return c;\n                }\n            });\n            packageList.addListSelectionListener(new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent e) {\n                    if (!e.getValueIsAdjusting()) packageSelected();\n                }\n            });\n            \n            JLabel packagesLabel = new JLabel(Bundle.ClassMethodSelector_capPackages(), JLabel.LEADING);\n            packagesLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));\n            JToolBar packagesTools = new FilteringToolbar(Bundle.ClassMethodSelector_lblFilterItems()) {\n                protected void filterChanged() {\n                    filteredPackages.setFilter(getFilter());\n                }\n            };\n            if (fromProject) {\n                packagesSourcesB = new JToggleButton(Icons.getIcon(LanguageIcons.CONSTRUCTORS)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        reload();\n                        PREF.putBoolean(\"Profiler.CMS.packagesSourcesB\", packagesSourcesB.isSelected()); // NOI18N\n                    }\n                };\n                packagesSourcesB.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n                packagesSourcesB.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n                packagesSourcesB.setToolTipText(Bundle.ClassMethodSelector_showProjectPackages());\n                packagesSourcesB.setSelected(PREF.getBoolean(\"Profiler.CMS.packagesSourcesB\", true)); // NOI18N\n                packagesDependenciesB = new JToggleButton(Icons.getIcon(LanguageIcons.JAR)) {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        super.fireActionPerformed(e);\n                        reload();\n                        PREF.putBoolean(\"Profiler.CMS.packagesDependenciesB\", packagesDependenciesB.isSelected()); // NOI18N\n                    }\n                };\n                packagesDependenciesB.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n                packagesDependenciesB.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n                packagesDependenciesB.setToolTipText(Bundle.ClassMethodSelector_showDependenciesPackages());\n                packagesDependenciesB.setSelected(PREF.getBoolean(\"Profiler.CMS.packagesDependenciesB\", false)); // NOI18N\n                \n                packagesTools.add(Box.createHorizontalStrut(2));\n                packagesTools.addSeparator();\n                packagesTools.add(Box.createHorizontalStrut(2));\n                packagesTools.add(packagesSourcesB);\n                packagesTools.add(Box.createHorizontalStrut(2));\n                packagesTools.add(packagesDependenciesB);\n            } else {\n                packagesSourcesB = null;\n                packagesDependenciesB = null;\n            }\n            \n            setOpaque(false);\n            setLayout(new BorderLayout());\n            add(packagesLabel, BorderLayout.NORTH);\n            add(new JScrollPane(packageList), BorderLayout.CENTER);\n            add(packagesTools, BorderLayout.SOUTH);\n        }\n        \n    }\n    \n    private static abstract class ClassSelector extends JPanel {\n        \n        abstract void classSelected();\n        \n        abstract void reload();\n        \n        SourceClassInfo getSelected() {\n            return classesList.getSelectedValue();\n        }\n        \n        List<SourceClassInfo> getAllSelected() {\n            return classesList.getSelectedValuesList();\n        }\n        \n        void init(final SourcePackageInfo _package) {\n            isInitialized = _package != null;\n            \n            classesListModel.clear();\n            classesList.setEnabled(!isInitialized);\n            \n            if (isInitialized) {\n                final boolean inner = classesInnerB.isSelected();\n                final boolean anonymous = classesAnonymousB.isSelected();\n                \n                PROCESSOR.post(new Runnable() {\n                    public void run() {\n                        final Collection<SourceClassInfo> classes = getClasses(_package, inner, anonymous);\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                classesList.setEnabled(true);\n                                for (SourceClassInfo clss : classes)\n                                   classesListModel.addElement(clss); \n                            }\n                        });\n                    }\n                });\n            }\n        }\n        \n        private static Collection<SourceClassInfo> getClasses(SourcePackageInfo pkg, boolean inner, boolean anonymous) {\n            Collection<SourceClassInfo> classes = pkg.getClasses();\n\n            if (inner) {\n                Set<SourceClassInfo> _classes = new HashSet();\n                while (!classes.isEmpty()) {\n                    SourceClassInfo cls = classes.iterator().next();\n                    classes.remove(cls);\n                    if (anonymous || !cls.isAnonymous()) _classes.add(cls);\n                    classes.addAll(cls.getInnerClases());\n                }\n                classes = _classes;\n            }\n\n            Set<SourceClassInfo> sortedClasses = new TreeSet<>(\n                new Comparator<SourceClassInfo>() {\n                    public int compare(SourceClassInfo c1, SourceClassInfo c2) {\n                        return c1.getSimpleName().compareTo(c2.getSimpleName());\n                    }\n                }\n            );\n\n            sortedClasses.addAll(classes);\n            return sortedClasses;\n        }\n        \n        \n        private final JList<SourceClassInfo> classesList;\n        private final DefaultListModel<SourceClassInfo> classesListModel;\n        private final AbstractButton classesInnerB;\n        private final AbstractButton classesAnonymousB;\n        \n        private boolean isInitialized;\n        \n        ClassSelector(boolean singleSelection) {\n            classesListModel = new DefaultListModel();\n            final FilteredListModel<SourceClassInfo> filteredClasses = new FilteredListModel<SourceClassInfo>(classesListModel) {\n                protected boolean matchesFilter(SourceClassInfo cls, GenericFilter filter) {\n                    return filter.passes(cls.getSimpleName());\n                }\n            };\n            final HintRenderer hintRenderer = new HintRenderer();\n            classesList = new JList(filteredClasses) {\n                public Dimension getPreferredScrollableViewportSize() {\n                    Dimension dim = super.getPreferredScrollableViewportSize();\n                    dim.width = LIST_WIDTH;\n                    return dim;\n                }\n                protected void paintComponent(Graphics g) {\n                    super.paintComponent(g);\n                    \n                    if (getModel().getSize() == 0) {\n                        if (!isEnabled()) hintRenderer.setup(false, getSize());\n                        else if (isInitialized) hintRenderer.setup(true, getSize());\n                        else hintRenderer.setup(null, getSize());\n                        hintRenderer.paint(g);\n                    }\n                }\n            };\n            classesList.setSelectionMode(singleSelection ? ListSelectionModel.SINGLE_SELECTION :\n                                         ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);\n            filteredClasses.setSelectionModel(classesList.getSelectionModel());\n            classesList.setCellRenderer(new DefaultListCellRenderer() {\n                public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {\n                    DefaultListCellRenderer c = (DefaultListCellRenderer)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);\n                    SourceClassInfo val = (SourceClassInfo)value;\n                    c.setText(val.getSimpleName());\n                    c.setIcon(Icons.getIcon(LanguageIcons.CLASS));\n                    return c;\n                }\n            });\n            classesList.addListSelectionListener(new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent e) {\n                    if (!e.getValueIsAdjusting()) classSelected();\n                }\n            });\n            \n            JLabel classesLabel = new JLabel(Bundle.ClassMethodSelector_capClasses(), JLabel.LEADING);\n            classesLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));\n            classesInnerB = new JToggleButton(Icons.getIcon(LanguageIcons.CLASS)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    reload();\n                    classesAnonymousB.setEnabled(isSelected());\n                    PREF.putBoolean(\"Profiler.CMS.classesInnerB\", classesInnerB.isSelected()); // NOI18N\n                }\n            };\n            classesInnerB.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            classesInnerB.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n            classesInnerB.setToolTipText(Bundle.ClassMethodSelector_showInnerClasses());\n            classesInnerB.setSelected(PREF.getBoolean(\"Profiler.CMS.classesInnerB\", true)); // NOI18N\n            classesAnonymousB = new JToggleButton(Icons.getIcon(LanguageIcons.CLASS_ANONYMOUS)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    reload();\n                    PREF.putBoolean(\"Profiler.CMS.classesAnonymousB\", classesAnonymousB.isSelected()); // NOI18N\n                }\n                public void setEnabled(boolean enabled) {\n                    super.setEnabled(enabled);\n                    if (!isEnabled()) setSelected(false);\n                }\n            };\n            classesAnonymousB.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            classesAnonymousB.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n            classesAnonymousB.setToolTipText(Bundle.ClassMethodSelector_showAnonymousClasses());\n            classesAnonymousB.setSelected(PREF.getBoolean(\"Profiler.CMS.classesAnonymousB\", false)); // NOI18N\n            JToolBar classesTools = new FilteringToolbar(Bundle.ClassMethodSelector_lblFilterItems()) {\n                protected void filterChanged() {\n                    filteredClasses.setFilter(getFilter());\n                }\n            };\n            classesTools.add(Box.createHorizontalStrut(2));\n            classesTools.addSeparator();\n            classesTools.add(Box.createHorizontalStrut(2));\n            classesTools.add(classesInnerB);\n            classesTools.add(Box.createHorizontalStrut(2));\n            classesTools.add(classesAnonymousB);\n            \n            setOpaque(false);\n            setLayout(new BorderLayout());\n            add(classesLabel, BorderLayout.NORTH);\n            add(new JScrollPane(classesList), BorderLayout.CENTER);\n            add(classesTools, BorderLayout.SOUTH);\n        }\n        \n    }\n    \n    private static abstract class MethodSelector extends JPanel {\n        \n        abstract void methodSelected();\n        \n        abstract void reload();\n        \n        SourceMethodInfo getSelected() {\n            return methodsList.getSelectedValue();\n        }\n        \n        List<SourceMethodInfo> getAllSelected() {\n            return methodsList.getSelectedValuesList();\n        }\n        \n        void init(final SourceClassInfo _class) {\n            isInitialized = _class != null;\n            \n            methodsListModel.clear();\n            methodsList.setEnabled(!isInitialized);\n\n            if (isInitialized) {\n                final boolean inherited = methodsInheritedB.isSelected();\n                final boolean nonpublic = methodsNonPublicB.isSelected();\n                final boolean staticc   = methodsStaticB.isSelected();\n\n                PROCESSOR.post(new Runnable() {\n                    public void run() {\n                        final Collection<SourceMethodInfo> methods = getMethods(_class, inherited, nonpublic, staticc);\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                methodsList.setEnabled(true);\n                                for (SourceMethodInfo mthd : methods)\n                                   methodsListModel.addElement(mthd); \n                            }\n                        });\n                    }\n                });\n            }\n        }\n        \n        private static Collection<SourceMethodInfo> getMethods(SourceClassInfo cls, boolean inherited, boolean nonpublic, boolean staticc) {\n            Set<SourceMethodInfo> sortedMethods = new TreeSet<>(\n                new Comparator<SourceMethodInfo>() {\n                    public int compare(SourceMethodInfo m1, SourceMethodInfo m2) {\n                        Formattable f1 = METHOD_FORMATTER.formatMethodName(\"\", m1.getName(), m1.getSignature()); // NOI18N\n                        Formattable f2 = METHOD_FORMATTER.formatMethodName(\"\", m2.getName(), m2.getSignature()); // NOI18N\n                        return f1.toFormatted().compareTo(f2.toFormatted());\n                    }\n                }\n            );\n\n            Set<SourceMethodInfo> methods = new HashSet(cls.getConstructors());\n            methods.addAll(cls.getMethods(inherited));\n            for (SourceMethodInfo method : methods) {\n                int modifiers = method.getModifiers();\n                if ((nonpublic || Modifier.isPublic(modifiers)) &&\n                    (staticc || !Modifier.isStatic(modifiers)))\n                    sortedMethods.add(method);\n            }\n\n            return sortedMethods;\n        }\n        \n        \n        private final JList<SourceMethodInfo> methodsList;\n        private final DefaultListModel<SourceMethodInfo> methodsListModel;\n        private final AbstractButton methodsInheritedB;\n        private final AbstractButton methodsNonPublicB;\n        private final AbstractButton methodsStaticB;\n        \n        private boolean isInitialized;\n            \n        MethodSelector() {\n            methodsListModel = new DefaultListModel();\n            final FilteredListModel<SourceMethodInfo> filteredMethods = new FilteredListModel<SourceMethodInfo>(methodsListModel) {\n                protected boolean matchesFilter(SourceMethodInfo mtd, GenericFilter filter) {\n                    return filter.passes(mtd.getName());\n                }\n            };\n            final HintRenderer hintRenderer = new HintRenderer();\n            methodsList = new JList(filteredMethods) {\n                public Dimension getPreferredScrollableViewportSize() {\n                    Dimension dim = super.getPreferredScrollableViewportSize();\n                    dim.width = LIST_WIDTH;\n                    return dim;\n                }\n                protected void paintComponent(Graphics g) {\n                    super.paintComponent(g);\n\n                    if (getModel().getSize() == 0) {\n                        if (!isEnabled()) hintRenderer.setup(false, getSize());\n                        else if (isInitialized) hintRenderer.setup(true, getSize());\n                        else hintRenderer.setup(null, getSize());\n                        hintRenderer.paint(g);\n                    }\n                }\n            };\n            methodsList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);\n            filteredMethods.setSelectionModel(methodsList.getSelectionModel());\n            methodsList.setCellRenderer(new DefaultListCellRenderer() {\n                public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {\n                    DefaultListCellRenderer c = (DefaultListCellRenderer)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);\n                    SourceMethodInfo val = (SourceMethodInfo)value;\n                    c.setText(METHOD_FORMATTER.formatMethodName(\"\", val.getName(), val.getSignature()).toFormatted()); // NOI18N\n                    c.setIcon(Icons.getIcon(LanguageIcons.METHOD_PUBLIC));\n                    return c;\n                }\n            });\n            methodsList.addListSelectionListener(new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent e) {\n                    if (!e.getValueIsAdjusting()) methodSelected();\n                }\n            });\n\n            JLabel methodsLabel = new JLabel(Bundle.ClassMethodSelector_capMethods(), JLabel.LEADING);\n            methodsLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));\n            methodsInheritedB = new JToggleButton(Icons.getIcon(LanguageIcons.METHOD_INHERITED)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    reload();\n                    PREF.putBoolean(\"Profiler.CMS.methodsInheritedB\", methodsInheritedB.isSelected()); // NOI18N\n                }\n            };\n            methodsInheritedB.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            methodsInheritedB.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n            methodsInheritedB.setToolTipText(Bundle.ClassMethodSelector_showInheritedMethods());\n            methodsInheritedB.setSelected(PREF.getBoolean(\"Profiler.CMS.methodsInheritedB\", false));\n            methodsNonPublicB = new JToggleButton(Icons.getIcon(LanguageIcons.METHOD_PRIVATE)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    reload();\n                    PREF.putBoolean(\"Profiler.CMS.methodsNonPublicB\", methodsNonPublicB.isSelected()); // NOI18N\n                }\n            };\n            methodsNonPublicB.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            methodsNonPublicB.putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n            methodsNonPublicB.setToolTipText(Bundle.ClassMethodSelector_showNonPublicMethods());\n            methodsNonPublicB.setSelected(PREF.getBoolean(\"Profiler.CMS.methodsNonPublicB\", true));\n            methodsStaticB = new JToggleButton(Icons.getIcon(LanguageIcons.METHOD_PUBLIC_STATIC)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    reload();\n                    PREF.putBoolean(\"Profiler.CMS.methodsStaticB\", methodsStaticB.isSelected()); // NOI18N\n                }\n            };\n            methodsStaticB.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n            methodsStaticB.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n            methodsStaticB.setToolTipText(Bundle.ClassMethodSelector_showStaticMethods());\n            methodsStaticB.setSelected(PREF.getBoolean(\"Profiler.CMS.methodsStaticB\", true));\n            JToolBar methodsTools = new FilteringToolbar(Bundle.ClassMethodSelector_lblFilterItems()) {\n                protected void filterChanged() {\n                    filteredMethods.setFilter(getFilter());\n                }\n            };\n            methodsTools.add(Box.createHorizontalStrut(2));\n            methodsTools.addSeparator();\n            methodsTools.add(Box.createHorizontalStrut(2));\n            methodsTools.add(methodsInheritedB);\n            methodsTools.add(Box.createHorizontalStrut(2));\n            methodsTools.add(methodsStaticB);\n            methodsTools.add(Box.createHorizontalStrut(2));\n            methodsTools.add(methodsNonPublicB);\n            \n            setOpaque(false);\n            setLayout(new BorderLayout());\n            add(methodsLabel, BorderLayout.NORTH);\n            add(new JScrollPane(methodsList), BorderLayout.CENTER);\n            add(methodsTools, BorderLayout.SOUTH);\n        }\n        \n    }\n    \n    \n    private static class HintRenderer extends LabelRenderer {\n                \n        HintRenderer() {\n            super(true);\n            setHorizontalAlignment(CENTER);\n            setForeground(UIUtils.getDisabledLineColor());\n        }\n\n        void setup(Boolean mode, Dimension size) {\n            if (Boolean.FALSE.equals(mode)) setText(Bundle.ClassMethodSelector_lblComputing());\n            else if (Boolean.TRUE.equals(mode)) setText(Bundle.ClassMethodSelector_lblNoItems());\n            else setText(Bundle.ClassMethodSelector_lblNoSelection());\n            setSize(size);\n        }\n\n    }\n    \n    \n    private static abstract class FilteredListModel<E> implements ListModel<E> {\n        \n        private final Collection<ListDataListener> listeners;\n        \n        private final ListModel<E> data;\n        \n        private ListSelectionModel selection;\n        private E selected;\n        \n        private GenericFilter filter;\n        private final List<Integer> indices;\n        \n        FilteredListModel(ListModel data) {\n            this.data = data;\n            \n            listeners = new HashSet();\n            \n            indices = new ArrayList();\n            doFilter();\n            \n            this.data.addListDataListener(new ListDataListener() {\n                public void intervalAdded(ListDataEvent e)   { doFilter(); }\n                public void intervalRemoved(ListDataEvent e) { doFilter(); }\n                public void contentsChanged(ListDataEvent e) { doFilter(); }\n            });\n        }\n        \n        \n        protected abstract boolean matchesFilter(E item, GenericFilter filter);\n        \n        \n        public void setSelectionModel(final ListSelectionModel selection) {\n            this.selection = selection;\n            selection.addListSelectionListener(new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent e) {\n                    if (!e.getValueIsAdjusting()) {\n                        int index = selection.getMinSelectionIndex();\n                        selected = index == -1 ? null : getElementAt(index);\n                    }\n                }\n            });\n        }\n        \n        \n        public void setFilter(GenericFilter filter) {\n            this.filter = filter.isAll() ? null : filter;\n            doFilter();\n        }\n        \n        public GenericFilter getFilter() {\n            return filter;\n        }\n        \n\n        public int getSize() {\n            return filter == null ? data.getSize() : indices.size();\n        }\n\n        public E getElementAt(int index) {\n            return data.getElementAt(filter == null ? index : indices.get(index));\n        }\n\n        public void addListDataListener(ListDataListener listener) {\n            listeners.add(listener);\n        }\n\n        public void removeListDataListener(ListDataListener listener) {\n            listeners.remove(listener);\n        }\n        \n        \n        private void doFilter() {\n            indices.clear();\n            \n            int _selected = -1;\n            \n            if (filter != null) {\n                for (int i = 0; i < data.getSize(); i++) {\n                    E element = data.getElementAt(i);\n                    if (matchesFilter(element, filter)) {\n                        if (selection != null && element.equals(selected)) _selected = indices.size();\n                        indices.add(i);\n                    }\n                }\n            } else if (selection != null) {\n                for (int i = 0; i < data.getSize(); i++) {\n                    E element = data.getElementAt(i);\n                    if (element.equals(selected)) _selected = i;\n                }\n            }\n            \n            if (!listeners.isEmpty()) {\n                // TODO: should only fire events if data really changed\n                ListDataEvent event = new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, 0, indices.size());\n                for (ListDataListener listener : listeners) listener.contentsChanged(event);\n            }\n            \n            if (selection != null) {\n                if (_selected == -1) selection.clearSelection();\n                else selection.setSelectionInterval(_selected, _selected);\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/impl/FeaturesView.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.v2.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.AbstractAction;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JSeparator;\nimport javax.swing.JTabbedPane;\nimport javax.swing.JToolTip;\nimport javax.swing.UIManager;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerFeature;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"FeaturesView_noData=No data collected yet. Click the {0} button in toolbar to start profiling.\"\n})\npublic class FeaturesView extends JPanel {\n\n    private JTabbedPane tabs;\n    private final Component defaultView;\n\n    private JLabel hintLabel;\n    private final Color hintColor;\n\n    private final Set<ChangeListener> listeners = new HashSet();\n\n\n    public FeaturesView(Component defaultView, String buttonString) {\n        if (UIUtils.isOracleLookAndFeel()) {\n            setOpaque(true);\n            setBackground(UIUtils.getProfilerResultsBackground());\n        } else {\n            setOpaque(false);\n        }\n        setBorder(BorderFactory.createEmptyBorder());\n        setLayout(new BorderLayout(0, 0));\n\n        if (defaultView != null) {\n            JScrollPane sp = new JScrollPane(defaultView, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER) {\n                public Dimension getMinimumSize() { return getPreferredSize(); }\n            };\n            sp.getVerticalScrollBar().setUnitIncrement(20);\n            sp.setBorder(null);\n            sp.setViewportBorder(null);\n\n            this.defaultView = sp;\n            add(this.defaultView, BorderLayout.CENTER);\n        } else {\n            this.defaultView = null;\n        }\n        \n        if (buttonString != null) {\n            hintLabel = new JLabel();\n            hintLabel.setIcon(Icons.getIcon(GeneralIcons.INFO));\n            hintLabel.setIconTextGap(hintLabel.getIconTextGap() + 1);\n            hintLabel.setOpaque(false);\n            \n            Font font = new JToolTip().getFont();\n            \n            Color f = hintLabel.getForeground();\n            int r = f.getRed() + 70;\n            if (r > 255) r = f.getRed() - 70; else r = Math.min(r, 70);\n            int g = f.getGreen() + 70;\n            if (g > 255) g = f.getRed() - 70; else g = Math.min(g, 70);\n            int b = f.getBlue() + 70;\n            if (b > 255) b = f.getRed() - 70; else b = Math.min(b, 70);\n            hintLabel.setText(\"<html><body text=\\\"rgb(\" + r + \", \" + g + \", \" + b + \")\\\" style=\\\"font-size: \" + //NOI18N\n                              (font.getSize()) + \"pt; font-family: \" + font.getName() + \";\\\">\" + //NOI18N\n                              Bundle.FeaturesView_noData(\"<b>\" + buttonString + \"</b>\") + \"</body></html>\"); //NOI18N\n            \n            hintLabel.setSize(hintLabel.getPreferredSize());\n            \n            Color c = UIUtils.getProfilerResultsBackground();\n            hintColor = Utils.checkedColor(new Color(c.getRed(), c.getGreen(), c.getBlue(), 245));\n        } else {\n            hintColor = null;\n        }\n    }\n    \n    \n    public final void resetNoDataHint() {\n        hintLabel = null;\n        repaint();\n    }\n    \n    \n    public final void addFeature(ProfilerFeature feature) {\n        if (tabs == null) {\n            if (defaultView != null) remove(defaultView);\n            tabs = createTabs();\n            add(tabs, BorderLayout.CENTER);\n        }\n        \n        JPanel container = createContainer(feature);\n        tabs.addTab(feature.getName(), feature.getIcon(), container, null);\n        \n        doLayout();\n        repaint();\n        fireViewOrIndexChanged();\n    }\n    \n    private static final int XMAR = 40;\n    private static final int YMAR = 40;\n    \n    private JPanel createContainer(ProfilerFeature feature) {\n        JPanel container = new JPanel(new BorderLayout(0, 0));\n        container.putClientProperty(ProfilerFeature.class, feature);\n        \n        JPanel results = feature.getResultsUI();\n        JPanel xresults = new JPanel(new BorderLayout()) {\n            public void paint(Graphics g) {\n                super.paint(g);\n                if (hintLabel != null) {\n                    Dimension dim = hintLabel.getSize();\n                    int x = (getWidth() - dim.width) / 2;\n                    int y = (getHeight() - dim.height) / 2;\n                    \n                    g.setColor(hintColor);\n                    g.fillRect(x - XMAR, y - YMAR, dim.width + XMAR * 2, dim.height + YMAR * 2);\n                    g.setColor(Color.LIGHT_GRAY);\n                    g.drawRect(x - XMAR, y - YMAR, dim.width + XMAR * 2, dim.height + YMAR * 2);\n                    \n                    g.translate(x, y);\n                    hintLabel.paint(g);\n                    g.translate(-x, -y);\n                }\n            }\n        };\n        xresults.add(results, BorderLayout.CENTER);\n        container.add(xresults, BorderLayout.CENTER);\n        \n        JPanel settings = feature.getSettingsUI();\n        if (settings != null) {\n            JPanel pan = new JPanel(new BorderLayout(0, 0)) {\n                public void setVisible(boolean visible) {\n                    super.setVisible(visible);\n                    for (Component c : getComponents()) c.setVisible(visible);\n                }\n            };\n            pan.setOpaque(true);\n            pan.setBackground(UIUtils.getProfilerResultsBackground());\n            pan.add(settings, BorderLayout.CENTER);\n            JSeparator sep = UIUtils.createHorizontalLine(pan.getBackground());\n            pan.add(sep, BorderLayout.SOUTH);\n            pan.setVisible(settings.isVisible());\n            container.add(pan, BorderLayout.NORTH);\n        }\n        \n        return container;\n    }\n    \n    public final void removeFeature(ProfilerFeature feature) {\n        if (tabs != null) {\n            tabs.remove(feature.getResultsUI());\n            doLayout();\n            repaint();\n            if (tabs.getTabCount() == 0) removeFeatures();\n            else fireViewOrIndexChanged();\n        }\n    }\n    \n    public final void removeFeatures() {\n        removeAll();\n        tabs = null;\n        if (defaultView != null) add(defaultView, BorderLayout.CENTER);\n        doLayout();\n        repaint();\n        fireViewOrIndexChanged();\n    }\n    \n    \n    public final ProfilerFeature getSelectedFeature() {\n        if (tabs == null) return null;\n        JPanel container = (JPanel)tabs.getSelectedComponent();\n        return (ProfilerFeature)container.getClientProperty(ProfilerFeature.class);\n    }\n    \n    public final void selectFeature(ProfilerFeature feature) {\n        if (tabs == null) return;\n        for (Component c : tabs.getComponents())\n            if (((JComponent)c).getClientProperty(ProfilerFeature.class) == feature)\n                tabs.setSelectedComponent(c);\n    }\n    \n    public final void selectFeature(int index) {\n        if (tabs == null) return;\n        tabs.setSelectedIndex(index);\n    }\n    \n    public final void selectPreviousFeature() {\n        if (tabs == null) return;\n        int index = UIUtils.getPreviousSubTabIndex(tabs, tabs.getSelectedIndex());\n        tabs.setSelectedIndex(index);\n    }\n    \n    public final void selectNextFeature() {\n        if (tabs == null) return;\n        int index = UIUtils.getNextSubTabIndex(tabs, tabs.getSelectedIndex());\n        tabs.setSelectedIndex(index);\n    }\n    \n    \n    public final void addChangeListener(ChangeListener listener) {\n        listeners.add(listener);\n    }\n    \n    public final void removeChangeListener(ChangeListener listener) {\n        listeners.remove(listener);\n    }\n    \n    public final void fireViewOrIndexChanged() {\n        if (listeners.isEmpty()) return;\n        ChangeEvent event = new ChangeEvent(this);\n        for (ChangeListener listener : listeners)\n            listener.stateChanged(event);\n    }\n    \n    \n    private JTabbedPane createTabs() {\n        JTabbedPane tp = new JTabbedPane(JTabbedPane.BOTTOM) {\n            protected final void fireStateChanged() {\n                super.fireStateChanged();\n                fireViewOrIndexChanged();\n            }\n        };\n        tp.setOpaque(false);\n        if (UIUtils.isAquaLookAndFeel()) {\n            tp.setBorder(BorderFactory.createEmptyBorder(-13, -11, 0, -10));\n        } else {\n            tp.setBorder(BorderFactory.createEmptyBorder());\n            Insets i = UIManager.getInsets(\"TabbedPane.contentBorderInsets\"); // NOI18N\n            int bottomOffset = 0;\n            if (UIUtils.isMetalLookAndFeel()) {\n                bottomOffset = -i.bottom + 1;\n            } else if (UIUtils.isWindowsLookAndFeel()) {\n                bottomOffset = -i.bottom;\n            }\n            if (i != null) tp.setBorder(BorderFactory.createEmptyBorder(-i.top, -i.left, bottomOffset, -i.right));\n        }\n        \n        // Fix for Issue 115062 (CTRL-PageUp/PageDown should move between snapshot tabs)\n        tp.getActionMap().getParent().remove(\"navigatePageUp\"); // NOI18N\n        tp.getActionMap().getParent().remove(\"navigatePageDown\"); // NOI18N\n        \n        // support for traversing subtabs using Ctrl-Alt-PgDn/PgUp\n        getActionMap().put(\"PreviousViewAction\", new AbstractAction() { // NOI18N\n            public void actionPerformed(ActionEvent e) { selectPreviousFeature(); }\n        });\n        getActionMap().put(\"NextViewAction\", new AbstractAction() { // NOI18N\n            public void actionPerformed(ActionEvent e) { selectNextFeature(); }\n        });\n        \n        return tp;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/impl/FilterSelector.java",
    "content": "/*\n * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.v2.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.GridLayout;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.ButtonGroup;\nimport javax.swing.ButtonModel;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JRadioButton;\nimport javax.swing.JScrollPane;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport javax.swing.border.Border;\nimport org.graalvm.visualvm.lib.ui.results.ColoredFilter;\nimport org.graalvm.visualvm.lib.ui.results.PackageColorer;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerPopup;\nimport org.graalvm.visualvm.lib.ui.swing.TextArea;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"FilterSelector_outgoingCalls=Outgoing calls filter:\",\n    \"FilterSelector_noFilter=No filter\",\n    \"FilterSelector_excludeCoreJava=Exclude core Java classes\",\n    \"FilterSelector_excludeCustom=Exclude defined classes\",\n    \"FilterSelector_includeCustom=Include defined classes\",\n    \"FilterSelector_excludeCustomEx=Exclude defined classes:\",\n    \"FilterSelector_includeCustomEx=Include defined classes:\",\n    \"FilterSelector_filterHint=org.mypackage.**\\norg.mypackage.*\\norg.mypackage.MyClass\",\n    \"FilterSelector_filterTooltip=<html>Include/exclude profiling outgoing calls from these classes or packages:<br><br>\"\n            + \"<code>&nbsp;org.mypackage.**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package and subpackages<br>\"\n            + \"<code>&nbsp;org.mypackage.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package<br>\"\n            + \"<code>&nbsp;org.mypackage.MyClass&nbsp;&nbsp;</code>single class<br></html>\",\n    \"FilterSelector_insertFilter=Insert Defined Filter\"\n})\npublic abstract class FilterSelector {\n    \n    public static enum FilterName {\n        NO_FILTER,\n        EXCLUDE_JAVA_FILTER,\n        EXCLUDE_CUSTOM_FILTER,\n        INCLUDE_CUSTOM_FILTER;\n        \n        public String toString() {\n            switch(this) {\n                case NO_FILTER:             return Bundle.FilterSelector_noFilter();\n                case EXCLUDE_JAVA_FILTER:   return Bundle.FilterSelector_excludeCoreJava();\n                case EXCLUDE_CUSTOM_FILTER: return Bundle.FilterSelector_excludeCustom();\n                case INCLUDE_CUSTOM_FILTER: return Bundle.FilterSelector_includeCustom();\n                default:                    throw new IllegalArgumentException();\n            }\n        }\n    }\n    \n    \n    public void show(Component invoker, FilterName filterName, String filterValue) {\n        UI ui = new UI(filterName, filterValue);\n        ui.show(invoker);\n    }\n    \n    \n    protected abstract void filterChanged(FilterName filterName, String filterValue);\n    \n    \n    private class UI {\n        \n        private JRadioButton noFilterChoice;\n        private JRadioButton javaClassesChoice;\n        private JRadioButton excludeCustomChoice;\n        private JRadioButton includeCustomChoice;\n        private TextArea customClasses;\n        private PopupButton insertFilter;\n        \n        private JPanel panel;\n        \n        UI(FilterName filterName, String filterValue) {\n            populatePopup(filterName, filterValue);\n        }\n        \n        void show(Component invoker) {\n            int resizeMode = ProfilerPopup.RESIZE_LEFT | ProfilerPopup.RESIZE_BOTTOM;\n            ProfilerPopup.createRelative(invoker, panel, SwingConstants.SOUTH_EAST, resizeMode).show();\n        }\n        \n        private void populatePopup(FilterName filterName, String filterValue) {\n            JPanel content = new JPanel(new BorderLayout());\n            \n            JLabel hint = new JLabel(Bundle.FilterSelector_outgoingCalls(), JLabel.LEADING);\n            hint.setBorder(BorderFactory.createEmptyBorder(0, 0, 7, 0));\n            content.add(hint, BorderLayout.NORTH);\n            \n            ButtonGroup bg = new ButtonGroup() {\n                public void setSelected(ButtonModel m, boolean b) {\n                    super.setSelected(m, b);\n                    if (b && m.isSelected()) filterChanged(true);\n                }\n            };\n            \n            JPanel filters = new JPanel(new GridLayout(3, 1));\n            \n            noFilterChoice = new JRadioButton(Bundle.FilterSelector_noFilter(),\n                                FilterName.NO_FILTER.equals(filterName));\n            bg.add(noFilterChoice);\n            JPanel noFilter = new JPanel(null);\n            noFilter.setLayout(new BoxLayout(noFilter, BoxLayout.LINE_AXIS));\n            noFilter.add(noFilterChoice);\n            filters.add(noFilter);\n            \n            javaClassesChoice = new JRadioButton(Bundle.FilterSelector_excludeCoreJava(),\n                                FilterName.EXCLUDE_JAVA_FILTER.equals(filterName));\n            bg.add(javaClassesChoice);\n            \n            JLabel javaClassesHint = new JLabel(\"(java.*, javax.*, sun.*, com.sun.*, etc.)\", JLabel.LEADING);\n            javaClassesHint.setFont(javaClassesHint.getFont().deriveFont(javaClassesHint.getFont().getSize2D() - 1));\n            javaClassesHint.setEnabled(false);\n            \n            JPanel javaFilters = new JPanel(null);\n            javaFilters.setLayout(new BoxLayout(javaFilters, BoxLayout.LINE_AXIS));\n            javaFilters.add(javaClassesChoice);\n            javaFilters.add(createStrut(javaClassesChoice, 5, false));\n            javaFilters.add(javaClassesHint);\n            filters.add(javaFilters);\n            \n            excludeCustomChoice = new JRadioButton(Bundle.FilterSelector_excludeCustomEx(),\n                                  FilterName.EXCLUDE_CUSTOM_FILTER.equals(filterName));\n            bg.add(excludeCustomChoice);\n            \n            includeCustomChoice = new JRadioButton(Bundle.FilterSelector_includeCustomEx(),\n                                  FilterName.INCLUDE_CUSTOM_FILTER.equals(filterName));\n            bg.add(includeCustomChoice);\n            \n            JPanel customFilters = new JPanel(null);\n            customFilters.setLayout(new BoxLayout(customFilters, BoxLayout.LINE_AXIS));\n            customFilters.add(excludeCustomChoice);\n            customFilters.add(createStrut(excludeCustomChoice, 8, false));\n            customFilters.add(includeCustomChoice);\n            filters.add(customFilters);\n            \n            if (PackageColorer.hasRegisteredColors()) {\n                insertFilter = new PopupButton(Icons.getIcon(GeneralIcons.FILTER)) {\n                    {\n                        setToolTipText(Bundle.FilterSelector_insertFilter());\n                    }\n                    protected void populatePopup(JPopupMenu popup) {\n                        for (final ColoredFilter color : PackageColorer.getRegisteredColors()) {\n                            if (color.getValue().trim().isEmpty()) continue;\n                            Icon icon = color.getColor() == null ? null : color.getIcon(12, 12);\n                            popup.add(new JMenuItem(color.getName(), icon) {\n                                protected void fireActionPerformed(ActionEvent event) {\n                                    StringBuilder added = new StringBuilder();\n                                    for (String f : color.getValues()) {\n                                        if (added.length() > 0) added.append(\", \"); // NOI18N\n                                        added.append(f);\n                                        if (f.endsWith(\".\")) added.append(\"**\"); // NOI18N\n                                    }\n                                    \n                                    String current = customClasses.showsHint() ? \"\" : customClasses.getText(); // NOI18N\n                                    if (!current.isEmpty()) current += \"\\n\"; // NOI18N\n                                    current += added.toString();\n                                    \n                                    customClasses.requestFocusInWindow();\n                                    customClasses.setText(current);\n                                }\n                            });\n                        }\n                    }\n                    public Dimension getPreferredSize() {\n                        Dimension dim = super.getPreferredSize();\n                        dim.width -= 2;\n                        dim.height -= 2;\n                        return dim;\n                    }\n                };\n                customFilters.add(Box.createHorizontalGlue());\n                customFilters.add(insertFilter);\n            }\n            \n            JPanel filtersOut = new JPanel(new GridBagLayout());\n            GridBagConstraints c;\n            int y = 0;\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(3, 0, 0, 0);\n            filtersOut.add(filters, c);\n            \n            customClasses = new TextArea() {\n                protected void changed() {\n                    filterChanged(true);\n                }\n                public Point getToolTipLocation(MouseEvent event) {\n                    Component scroll = getParent().getParent();\n                    return SwingUtilities.convertPoint(scroll, 0, scroll.getHeight(), this);\n                }\n                public void setEnabled(boolean enabled) {\n                    super.setEnabled(enabled);\n                    if (insertFilter != null) insertFilter.setEnabled(enabled);\n                }\n            };\n            customClasses.setFont(new Font(Font.MONOSPACED, Font.PLAIN, customClasses.getFont().getSize()));\n            customClasses.setRows(0);\n            customClasses.setColumns(0);\n            JScrollPane customClassesScroll = new JScrollPane(customClasses);\n            Dimension d = customClassesScroll.getPreferredSize();\n            customClasses.setRows(3);\n            customClasses.setColumns(56);\n            Dimension _d = customClasses.getPreferredScrollableViewportSize();\n            d.width += _d.width;\n            d.height += _d.height;\n            customClassesScroll.setPreferredSize(d);\n            customClassesScroll.setMinimumSize(d);\n            customClasses.setText(filterValue);\n            customClasses.setHint(Bundle.FilterSelector_filterHint());\n            customClasses.setToolTipText(Bundle.FilterSelector_filterTooltip());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.weightx = 1;\n            c.weighty = 1;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.fill = GridBagConstraints.BOTH;\n            c.insets = new Insets(3, 20, 0, 0);\n            filtersOut.add(customClassesScroll, c);\n            \n            filterChanged(false);\n            \n            content.add(filtersOut, BorderLayout.CENTER);\n            \n            panel = content;\n        }\n        \n        private void filterChanged(boolean fire) {\n            customClasses.setEnabled(excludeCustomChoice.isSelected() ||\n                                     includeCustomChoice.isSelected());\n            \n            if (!fire) return;\n            \n            String filterValue = customClasses.showsHint() ? \"\" : customClasses.getText().trim(); // NOI18N\n            \n            if (noFilterChoice.isSelected()) {\n                FilterSelector.this.filterChanged(FilterName.NO_FILTER, filterValue);\n            } else if (javaClassesChoice.isSelected()) {\n                FilterSelector.this.filterChanged(FilterName.EXCLUDE_JAVA_FILTER, filterValue);\n            } else if (excludeCustomChoice.isSelected()) {\n                FilterSelector.this.filterChanged(FilterName.EXCLUDE_CUSTOM_FILTER, filterValue);\n            } else if (includeCustomChoice.isSelected()) {\n                FilterSelector.this.filterChanged(FilterName.INCLUDE_CUSTOM_FILTER, filterValue);\n            }\n        }\n        \n    }\n    \n    \n    private static Component createStrut(JComponent c, int width, boolean before) {\n        Border b = c.getBorder();\n        Insets i = b != null ? b.getBorderInsets(c) : null;\n        int w = i == null ? width : Math.max(width - (before ? i.left : i.right), 0);\n        return Box.createHorizontalStrut(w);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/impl/ProfilerStatus.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.impl;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.lang.ref.Reference;\nimport java.lang.ref.WeakReference;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.event.SimpleProfilingStateAdapter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.openide.awt.StatusDisplayer;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ProfilerStatus_profilerStopped=Profiler stopped\",\n    \"ProfilerStatus_profilerStarting=Profiler starting\",\n    \"ProfilerStatus_profilerRunning=Profiler running\",\n    \"ProfilerStatus_profilerRunningMethods=Profiler running, {0} methods instrumented\",\n    \"ProfilerStatus_profilerRunningClasses=Profiler running, {0} classes instrumented\"\n})\npublic final class ProfilerStatus {\n\n    private static final int STATUS_TIMEOUT = Integer.getInteger(\"org.openide.awt.StatusDisplayer.DISPLAY_TIME\", 5000); // NOI18N\n    private static final int STATUS_REFRESH = Math.min(STATUS_TIMEOUT - 250, 1500); // NOI18N\n\n    private final ProfilerSession session;\n\n    private volatile boolean logging;\n    private final Timer refreshTimer;\n\n    private int progressDots;\n    private boolean wasRunning;\n\n    private Reference<StatusDisplayer.Message> lastMessage;\n\n\n    public static ProfilerStatus forSession(ProfilerSession session) {\n        return new ProfilerStatus(session);\n    }\n\n    \n    public void startSessionLogging() {\n//        if (logging == false) {\n            logging = true;\n            updateStatus();\n//        }\n    }\n    \n    public void stopSessionLogging() {\n        logging = false;\n        clearStatus();\n    }\n    \n    public void log(final String text) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                StatusDisplayer.Message message = StatusDisplayer.getDefault().setStatusText(text, 1000);\n                message.clear(STATUS_TIMEOUT);\n                lastMessage = new WeakReference(message);\n            }\n        });\n    }\n    \n    \n    private ProfilerStatus(ProfilerSession session) {\n        this.session = session;\n        \n        refreshTimer = new Timer(STATUS_REFRESH, new ActionListener() {\n            public void actionPerformed(ActionEvent e) { updateStatus(); }\n        });\n        refreshTimer.setRepeats(false);\n        \n        session.addListener(new SimpleProfilingStateAdapter() {\n            public void update() { updateStatus(); }\n        });\n    }\n    \n    \n    private void updateStatus() {\n        if (!logging) return;\n        if (!ProfilerIDESettings.getInstance().getLogProfilerStatus()) {\n            clearStatus();\n            return;\n        }\n        \n        switch (session.getState()) {\n            case Profiler.PROFILING_INACTIVE:\n                if (wasRunning) {\n                    log(Bundle.ProfilerStatus_profilerStopped());\n                    wasRunning = false;\n                }\n                break;\n            case Profiler.PROFILING_PAUSED:\n//                log(\"Profiler paused\");\n                break;\n            case Profiler.PROFILING_STARTED:\n                log(Bundle.ProfilerStatus_profilerStarting());\n                progressDots = 0;\n                wasRunning = true;\n                break;\n            case Profiler.PROFILING_STOPPED:\n//                log(\"Profiler stopped\");\n                break;\n            case Profiler.PROFILING_IN_TRANSITION:\n//                log(\"Profiler changing state\");\n                progressDots = 0;\n                break;\n            case Profiler.PROFILING_RUNNING:\n                TargetAppRunner taRunner = session.getProfiler().getTargetAppRunner();\n                ProfilingSessionStatus pss = taRunner.getProfilingSessionStatus();\n                StringBuilder sb = new StringBuilder();\n                switch (pss.currentInstrType) {\n                    case CommonConstants.INSTR_RECURSIVE_FULL:\n                    case CommonConstants.INSTR_RECURSIVE_SAMPLED:\n                        sb.append(Bundle.ProfilerStatus_profilerRunningMethods(pss.getNInstrMethods()));\n                        break;\n                    case CommonConstants.INSTR_OBJECT_ALLOCATIONS:\n                    case CommonConstants.INSTR_OBJECT_LIVENESS:\n                        sb.append(Bundle.ProfilerStatus_profilerRunningClasses(pss.getNInstrClasses()));\n                        break;\n                    default:\n                        sb.append(Bundle.ProfilerStatus_profilerRunning());\n                }\n                \n                for (int i = 0; i < progressDots; i++) sb.append('.'); // NOI18N\n                log(sb.toString());\n                if (++progressDots > 3) progressDots = 0;\n                \n                refreshTimer.start();\n                \n                break;\n        }\n    }\n    \n    private void clearStatus() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                StatusDisplayer.Message message = lastMessage == null ? null :\n                                                  lastMessage.get();\n                if (message != null) message.clear(0);\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/impl/ProjectsSelector.java",
    "content": "/*\n * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.v2.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Objects;\nimport javax.swing.BorderFactory;\nimport javax.swing.GrayFilter;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToolBar;\nimport javax.swing.RowFilter;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingConstants;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.lib.ui.swing.FilteringToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerPopup;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.CheckBoxRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.profiler.api.ProjectUtilities;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ProjectsSelector_selectProjects=Select projects:\",\n    \"ProjectsSelector_filterProjects=Filter projects\",\n    \"ProjectsSelector_columnSelected=Selected\",\n    \"ProjectsSelector_columnProject=Project\",\n    \"ProjectsSelector_columnSelectedToolTip=Selected for profiling\",\n    \"ProjectsSelector_columnProjectToolTip=Project name\"\n})\npublic abstract class ProjectsSelector {\n\n    private final Collection<Lookup.Provider> selected;\n\n    public ProjectsSelector(Collection<Lookup.Provider> selected) {\n        this.selected = new HashSet(selected);\n    }\n\n\n    public void show(Component invoker) {\n        UI ui = new UI(selected);\n        ui.show(invoker);\n    }\n\n\n    protected abstract void selectionChanged(Collection<Lookup.Provider> selected);\n\n\n    private class UI {\n\n        private JPanel panel;\n        \n        UI(Collection<Lookup.Provider> selected) {\n            populatePopup();\n        }\n        \n        void show(Component invoker) {\n            int resizeMode = ProfilerPopup.RESIZE_BOTTOM | ProfilerPopup.RESIZE_RIGHT;\n            ProfilerPopup.createRelative(invoker, panel, SwingConstants.SOUTH_WEST, resizeMode).show();\n        }\n        \n        private void populatePopup() {\n            JPanel content = new JPanel(new BorderLayout());\n            \n            JLabel hint = new JLabel(Bundle.ProjectsSelector_selectProjects(), JLabel.LEADING);\n            hint.setBorder(BorderFactory.createEmptyBorder(0, 0, 6, 0));\n            content.add(hint, BorderLayout.NORTH);\n\n            final SelectedProjectsModel projectsModel = new SelectedProjectsModel();\n            final ProfilerTable projectsTable = new ProfilerTable(projectsModel, true, false, null);\n            projectsTable.setColumnToolTips(new String[] {\n                Bundle.ProjectsSelector_columnSelectedToolTip(),\n                Bundle.ProjectsSelector_columnProjectToolTip() });\n            projectsTable.setMainColumn(1);\n            projectsTable.setFitWidthColumn(1);\n            projectsTable.setDefaultSortOrder(1, SortOrder.ASCENDING);\n            projectsTable.setSortColumn(1);\n            projectsTable.setFixedColumnSelection(0); // #268298 - make sure SPACE always hits the Boolean column\n            projectsTable.setColumnRenderer(0, new CheckBoxRenderer());\n            LabelRenderer projectRenderer = new ProjectRenderer();\n            projectsTable.setColumnRenderer(1, projectRenderer);\n            int w = new JLabel(projectsTable.getColumnName(0)).getPreferredSize().width;\n            projectsTable.setDefaultColumnWidth(0, w + 15);\n            int h = projectsTable.getRowHeight() * 8;\n            h += projectsTable.getTableHeader().getPreferredSize().height;\n            projectRenderer.setText(\"A longest expected project name A longest expected project name\"); // NOI18N\n            Dimension prefSize = new Dimension(w + projectRenderer.getPreferredSize().width, h);\n            projectsTable.setPreferredScrollableViewportSize(prefSize);\n            ProfilerTableContainer tableContainer = new ProfilerTableContainer(projectsTable, true, null);\n            JPanel tableContent = new JPanel(new BorderLayout());\n            tableContent.setBorder(BorderFactory.createEmptyBorder(0, 0, 4, 0));\n            tableContent.add(tableContainer, BorderLayout.CENTER);\n            content.add(tableContent, BorderLayout.CENTER);\n\n            JToolBar controls = new FilteringToolbar(Bundle.ProjectsSelector_filterProjects()) {\n                protected void filterChanged() {\n                    if (isAll()) projectsTable.setRowFilter(null);\n                    else projectsTable.setRowFilter(new RowFilter() {\n                        public boolean include(RowFilter.Entry entry) {\n                            return passes(entry.getStringValue(1));\n                        }\n                    });\n                }\n            };\n\n            content.add(controls, BorderLayout.SOUTH);\n\n            panel = content;\n        }\n        \n        private class SelectedProjectsModel extends AbstractTableModel {\n            \n            Lookup.Provider[] projects = ProjectUtilities.getOpenedProjects(); \n            \n            SelectedProjectsModel() {\n                ProjectUtilities.getOpenedProjects();\n            }\n        \n            public String getColumnName(int columnIndex) {\n                if (columnIndex == 0) {\n                    return Bundle.ProjectsSelector_columnSelected();\n                } else if (columnIndex == 1) {\n                    return Bundle.ProjectsSelector_columnProject();\n                }\n                return null;\n            }\n\n            public Class<?> getColumnClass(int columnIndex) {\n                if (columnIndex == 0) {\n                    return Boolean.class;\n                } else if (columnIndex == 1) {\n                    return Lookup.Provider.class;\n                }\n                return null;\n            }\n\n            public int getRowCount() {\n                return projects.length;\n            }\n\n            public int getColumnCount() {\n                return 2;\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                if (columnIndex == 0) {\n                    return selected.contains(projects[rowIndex]);\n                } else if (columnIndex == 1) {\n                    return projects[rowIndex];\n                }\n                return null;\n            }\n\n            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {\n                if (Boolean.TRUE.equals(aValue)) {\n                    if (selected.add(projects[rowIndex])) selectionChanged(selected);\n                } else if (selected.size() > 1) {\n                    if (selected.remove(projects[rowIndex])) selectionChanged(selected);\n                }\n            }\n\n            public boolean isCellEditable(int rowIndex, int columnIndex) {\n                return columnIndex == 0;\n            }\n\n        }\n        \n    }\n    \n    private static class ProjectRenderer extends LabelRenderer {\n        \n        private final Font font;\n        private final Lookup.Provider main;\n        \n\n        ProjectRenderer() {\n            font = getFont();\n            main = ProjectUtilities.getMainProject();\n        }\n\n        public void setValue(Object value, int row) {\n            if (value == null) {\n                setText(\"\"); // NOI18N\n                setIcon(null);\n            } else {\n                Lookup.Provider project = (Lookup.Provider)value;\n                setText(ProjectUtilities.getDisplayName(project));\n                Icon icon = ProjectUtilities.getIcon(project);\n                setIcon(isEnabled() ? icon : disabledIcon(icon));\n                setFont(Objects.equals(main, value) ? font.deriveFont(Font.BOLD) : font);\n            }\n        }\n        \n        private static Icon disabledIcon(Icon icon) {\n            return new ImageIcon(GrayFilter.createDisabledImage(((ImageIcon)icon).getImage()));\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/impl/SnapshotsWindowHelper.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.impl;\n\nimport java.io.File;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.SnapshotResultsWindow;\nimport org.graalvm.visualvm.lib.profiler.SnapshotsListener;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.v2.SnapshotsWindow;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=SnapshotsListener.class)\npublic final class SnapshotsWindowHelper implements SnapshotsListener {\n\n    static final WeakProcessor PROCESSOR = new WeakProcessor(\"Snapshots Window Processor\"); // NOI18N\n\n    public void snapshotTaken(LoadedSnapshot snapshot) {\n        if (ProfilerIDESettings.getInstance().getAutoOpenSnapshot()) {\n//            int sortingColumn = LiveResultsWindow.hasDefault() ? LiveResultsWindow.getDefault().getSortingColumn()\n//                                                               : CommonConstants.SORTING_COLUMN_DEFAULT;\n//            boolean sortingOrder = LiveResultsWindow.hasDefault() ? LiveResultsWindow.getDefault().getSortingOrder() : false;\n//            ResultsManager.getDefault().openSnapshot(ls, sortingColumn, sortingOrder);\n\n            ResultsManager.getDefault().openSnapshot(snapshot);\n        }\n\n        if (ProfilerIDESettings.getInstance().getAutoSaveSnapshot()) {\n            ResultsManager.getDefault().saveSnapshot(snapshot);\n            if (!ProfilerIDESettings.getInstance().getAutoOpenSnapshot())\n                ResultsManager.getDefault().closeSnapshot(snapshot);\n        }\n    }\n\n    public void snapshotLoaded(LoadedSnapshot snapshot) {}\n\n    public void snapshotSaved(final LoadedSnapshot snapshot) {\n        refreshSnapshots(snapshot);\n        PROCESSOR.post(new Runnable() {\n            public void run() { SnapshotsWindow.instance().snapshotSaved(snapshot); }\n        });\n    }\n\n    public void snapshotRemoved(LoadedSnapshot snapshot) {\n        SnapshotResultsWindow.closeWindow(snapshot);\n        refreshSnapshots(snapshot);\n    }\n\n    private void refreshSnapshots(final LoadedSnapshot snapshot) {\n        PROCESSOR.post(new Runnable() {\n            public void run() {\n                File f = snapshot.getFile();\n                File p = f == null ? null : f.getParentFile();\n                FileObject fo = p == null ? null : FileUtil.toFileObject(p);\n                if (fo != null) SnapshotsWindow.instance().refreshFolder(fo, true);\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/impl/SnapshotsWindowUI.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.LayoutManager;\nimport java.awt.event.ActionEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.io.File;\nimport java.io.IOException;\nimport java.text.Collator;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.Set;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JTextField;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.ProfilerTopComponent;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.actions.CompareSnapshotsAction;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerStorage;\nimport org.graalvm.visualvm.lib.profiler.api.ProjectUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.graalvm.visualvm.lib.profiler.v2.ui.ProjectSelector;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.awt.Mnemonics;\nimport org.openide.filesystems.FileLock;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.loaders.DataObject;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.Mode;\nimport org.openide.windows.TopComponent;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"SnapshotsWindowUI_name=Snapshots\",\n    \"#NOI18N\",\n    \"SnapshotsWindowUI_mode=properties\",\n    \"SnapshotsWindowUI_colType=Type\",\n    \"SnapshotsWindowUI_colName=Name\",\n    \"SnapshotsWindowUI_lblProject=Project:\",\n    \"SnapshotsWindowUI_lblSnapshots=Snapshots:\",\n    \"SnapshotsWindowUI_actOpenSnapshots=Open\",\n    \"SnapshotsWindowUI_actExportSnapshot=Export...\",\n    \"SnapshotsWindowUI_actCompareSnapshots=Compare\",\n    \"SnapshotsWindowUI_actRenameSnapshot=Rename...\",\n    \"SnapshotsWindowUI_actDeleteSnapshots=Delete\",\n    \"SnapshotsWindowUI_descOpenSnapshots=Open selected snapshots\",\n    \"SnapshotsWindowUI_descExportSnapshot=Export selected snapshots...\",\n    \"SnapshotsWindowUI_descCompareSnapshots=Compare selected snapshots\",\n    \"SnapshotsWindowUI_descRenameSnapshot=Rename selected snapshot...\",\n    \"SnapshotsWindowUI_descDeleteSnapshots=Delete selected snapshots\",\n    \"SnapshotsWindowUI_msgCannotCompareSnapshots=Selected snapshots cannot be compared.\",\n    \"SnapshotsWindowUI_capRenameSnapshot=Rename Snapshot\",\n    \"SnapshotsWindowUI_msgNameEmpty=Snapshot name cannot be empty.\",\n    \"SnapshotsWindowUI_msgRenameFailed=Failed to rename {0}\",\n    \"SnapshotsWindowUI_capDeleteSnapshots=Confirm Delete\",\n    \"SnapshotsWindowUI_msgDeleteSnapshots=Delete selected snapshots?\",\n    \"SnapshotsWindowUI_msgDeleteFailed=Failed to delete {0}\",\n    \"SnapshotsWindowUI_lblNewFile=&New file name:\",\n    \"SnapshotsWindowUI_ttpSnapshotType=Snapshot type\",\n    \"SnapshotsWindowUI_ttpSnapshotName=Snapshot name\",\n    \"SnapshotsWindowUI_accessDescr=List of saved profiler snapshots\"\n})\npublic final class SnapshotsWindowUI extends ProfilerTopComponent {\n    \n    public static final String ID = \"SnapshotsWindowUI\"; // NOI18N\n    private static final HelpCtx HELP_CTX = new HelpCtx(\"SnapshotsWindow.HelpCtx\"); // NOI18N\n    \n    \n    // --- Instance ------------------------------------------------------------\n    \n    public SnapshotsWindowUI() {\n        setName(Bundle.SnapshotsWindowUI_name());\n        setIcon(Icons.getImage(ProfilerIcons.SNAPSHOT_TAKE));\n        \n        getAccessibleContext().setAccessibleDescription(Bundle.SnapshotsWindowUI_accessDescr());\n        \n        putClientProperty(ID, ID);\n        \n        initUI();\n    }\n    \n    \n    // --- Internal API --------------------------------------------------------\n    \n    public void refreshFolder(FileObject folder, boolean fullRefresh) {\n        // Converting to Files as comparing FileObjects doesn't work for global storage\n        File f1 = folder == null ? null : FileUtil.toFile(folder);\n        File f2 = currentFolder == null ? null : FileUtil.toFile(currentFolder);\n        if (Objects.equals(f1, f2)) {\n            if (fullRefresh) refreshSnapshots();\n            else snapshotsTableModel.fireTableDataChanged();\n        }\n    }\n    \n    public void setProject(Lookup.Provider project) {\n        selector.setProject(project);\n    }\n    \n    public void resetProject(Lookup.Provider project) {\n        selector.resetProject(project);\n    }\n    \n    \n    // --- Implementation ------------------------------------------------------\n    \n    private ProfilerTable snapshotsTable;\n    \n    private ProjectSelector selector;\n    private ChangeListener openProjectsListener;\n    \n    private FileObject currentFolder;\n    private final List<Snapshot> snapshots = new ArrayList();\n    \n    private Action openA;\n    private Action exportA;\n    private Action compareA;\n    private Action renameA;\n    private Action deleteA;\n\n    private final AbstractTableModel snapshotsTableModel = new AbstractTableModel() {\n        public String getColumnName(int columnIndex) {\n            if (columnIndex == 0) {\n                return Bundle.SnapshotsWindowUI_colType();\n            } else if (columnIndex == 1) {\n                return Bundle.SnapshotsWindowUI_colName();\n            }\n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (columnIndex == 0) {\n                return Integer.class;\n            } else if (columnIndex == 1) {\n                return Snapshot.class;\n            }\n            return null;\n        }\n\n        public int getRowCount() {\n            return snapshots.size();\n        }\n\n        public int getColumnCount() {\n            return 2;\n        }\n\n        public Object getValueAt(int rowIndex, int columnIndex) {\n            if (columnIndex == 0) {\n                return snapshots.get(rowIndex).getSnapshotType();\n            } else if (columnIndex == 1) {\n                return snapshots.get(rowIndex);\n            }\n            return null;\n        }\n\n        public boolean isCellEditable(int rowIndex, int columnIndex) {\n            return false;\n        }\n\n    };\n    \n    \n    void refreshSnapshots() {\n        final Lookup.Provider project = selector.getProject();\n        SnapshotsWindowHelper.PROCESSOR.post(new Runnable() {\n            public void run() {\n                ResultsManager rm = ResultsManager.getDefault();\n                final List<Snapshot> _snapshots = new ArrayList();\n                for (FileObject fo : rm.listSavedSnapshots(project, null))\n                    _snapshots.add(new Snapshot(fo) {\n                        boolean alternativeSorting() {\n                            return snapshotsTable.getSortColumn() == 0;\n                        }\n                    });\n                for (FileObject fo : rm.listSavedHeapdumps(project, null))\n                    _snapshots.add(new Snapshot(fo) {\n                        boolean alternativeSorting() {\n                            return snapshotsTable.getSortColumn() == 0;\n                        }\n                    });\n                FileObject __currentFolder = null;\n                try {\n                    __currentFolder = ProfilerStorage.getProjectFolder(project, false);\n                } catch (IOException e) {}\n                final FileObject _currentFolder = __currentFolder;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        currentFolder = _currentFolder;\n                        snapshots.clear();\n                        snapshots.addAll(_snapshots);\n                        snapshotsTableModel.fireTableDataChanged();\n                    }\n                });\n            }\n        });\n    }\n    \n    \n    // --- UI ------------------------------------------------------------------\n    \n    private void initUI() {\n        JPanel contents = new JPanel(new GridBagLayout());\n        contents.setOpaque(true);\n        contents.setBackground(UIUtils.getProfilerResultsBackground());\n        \n        GridBagConstraints c;\n        int y = 0;\n        \n        JLabel projectSelectL = new JLabel(Bundle.SnapshotsWindowUI_lblProject(), JLabel.LEADING);\n        c = new GridBagConstraints();\n        c.gridy = y++;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(10, 10, 0, 10);\n        contents.add(projectSelectL, c);\n        \n        ProjectSelector.Populator populator = new ProjectSelector.Populator() {\n            protected Lookup.Provider initialProject() {\n                ProfilerSession ps = ProfilerSession.currentSession();\n                return ps == null ? ProjectUtilities.getMainProject() : ps.getProject();\n            }\n            protected Collection<Lookup.Provider> additionalProjects() {\n                ProfilerSession ps = ProfilerSession.currentSession();\n                Lookup.Provider cp = ps == null ? null : ps.getProject();\n                if (cp != null) return Collections.singleton(cp);\n                else return super.additionalProjects();\n            }\n        };\n        \n        selector = new ProjectSelector(populator) {\n            protected void selectionChanged() { refreshSnapshots(); }\n        };\n        \n        c = new GridBagConstraints();\n        c.gridy = y++;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 10, 0, 10);\n        contents.add(selector, c);\n        \n        JLabel snapshotsListL = new JLabel(Bundle.SnapshotsWindowUI_lblSnapshots(), JLabel.LEADING);\n        c = new GridBagConstraints();\n        c.gridy = y++;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(15, 10, 0, 10);\n        contents.add(snapshotsListL, c);\n        \n        openA = new AbstractAction(Bundle.SnapshotsWindowUI_actOpenSnapshots()) {\n            {\n                putValue(\"BTN_TOOLTIP\", Bundle.SnapshotsWindowUI_descOpenSnapshots()); // NOI18N\n            }\n            public void actionPerformed(ActionEvent e) {\n                openSnapshots(snapshotsTable.getSelectedValues(1));\n            }\n        };\n        \n        exportA = new AbstractAction(Bundle.SnapshotsWindowUI_actExportSnapshot()) {\n            {\n                putValue(\"BTN_TOOLTIP\", Bundle.SnapshotsWindowUI_descExportSnapshot()); // NOI18N\n            }\n            public void actionPerformed(ActionEvent e) {\n                exportSnapshots(snapshotsTable.getSelectedValues(1));\n            }\n        };\n        \n        compareA = new AbstractAction(Bundle.SnapshotsWindowUI_actCompareSnapshots()) {\n            {\n                putValue(\"BTN_TOOLTIP\", Bundle.SnapshotsWindowUI_descCompareSnapshots()); // NOI18N\n            }\n            public void actionPerformed(ActionEvent e) {\n                List<Snapshot> snapshots = snapshotsTable.getSelectedValues(1);\n                compareSnapshots(snapshots.get(0), snapshots.get(1));\n            }\n        };\n        \n        renameA = new AbstractAction(Bundle.SnapshotsWindowUI_actRenameSnapshot()) {\n            {\n                putValue(\"BTN_TOOLTIP\", Bundle.SnapshotsWindowUI_descRenameSnapshot()); // NOI18N\n            }\n            public void actionPerformed(ActionEvent e) {\n                Snapshot s = (Snapshot)snapshotsTable.getSelectedValue(1);\n                renameSnapshot(s, snapshotsTableModel);\n            }\n        };\n        \n        deleteA = new AbstractAction(Bundle.SnapshotsWindowUI_actDeleteSnapshots()) {\n            {\n                putValue(\"BTN_TOOLTIP\", Bundle.SnapshotsWindowUI_descDeleteSnapshots()); // NOI18N\n            }\n            public void actionPerformed(ActionEvent e) {\n                deleteSnapshots(snapshotsTable.getSelectedValues(1));\n            }\n        };\n        \n        snapshotsTable = new ProfilerTable(snapshotsTableModel, true, true, null) {\n            protected void populatePopup(final JPopupMenu popup, Object value, Object userValue) {\n                popup.add(new JMenuItem(openA) {\n                    { setFont(popup.getFont().deriveFont(Font.BOLD)); }\n                });\n                popup.add(new JMenuItem(exportA));\n                popup.add(new JMenuItem(compareA));\n                popup.add(new JMenuItem(renameA));\n                popup.add(new JMenuItem(deleteA));\n            }\n        };\n        snapshotsTable.providePopupMenu(true);\n        snapshotsTable.setMainColumn(1);\n        snapshotsTable.setDefaultSortOrder(SortOrder.ASCENDING);\n        snapshotsTable.setSecondarySortColumn(1);\n        snapshotsTable.setSortColumn(0);\n        snapshotsTable.setFitWidthColumn(1);\n        snapshotsTable.setDefaultColumnWidth(0, new JLabel(Bundle.SnapshotsWindowUI_colType()).getPreferredSize().width + 30);      \n        snapshotsTable.setColumnRenderer(0, new LabelRenderer() {\n            {\n                setHorizontalAlignment(CENTER);\n            }\n            public void setValue(Object value, int row) {\n                if (value == null) setIcon(null);\n                else setIcon(Icons.getIcon(Snapshot.getIconName((Integer)value)));\n            }\n        });\n        snapshotsTable.setColumnRenderer(1, new LabelRenderer() {\n            private final Font plain;\n            private final Font bold;\n            {\n                plain = getFont().deriveFont(Font.PLAIN);\n                bold = plain.deriveFont(Font.BOLD);\n            }\n            public void setValue(Object value, int row) {\n                if (value == null) {\n                    setText(\"\"); // NOI18N\n                } else {\n                    Snapshot s = (Snapshot)value;\n                    setText(s.getDisplayName());\n                    if (isOpen(s)) setFont(bold); else setFont(plain);\n                }\n            }\n        });\n        snapshotsTable.setColumnToolTips(new String[] { Bundle.SnapshotsWindowUI_ttpSnapshotType(),\n                                                        Bundle.SnapshotsWindowUI_ttpSnapshotName() });\n        snapshotsTable.setDefaultAction(openA);\n        snapshotsTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);\n        snapshotsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n            public void valueChanged(ListSelectionEvent e) {\n                updateButtons(snapshotsTable.getSelectedValues(1));\n            }\n        });\n        \n        c = new GridBagConstraints();\n        c.gridy = y++;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(3, 10, 10, 10);\n        contents.add(new ProfilerTableContainer(snapshotsTable, true, null), c);\n        \n        setLayout(new BorderLayout());\n        add(contents, BorderLayout.CENTER);\n        \n        class ThinButton extends JButton {\n            ThinButton(Action action, Icon icon) {\n                super(action);\n                setText(null);\n                setIcon(icon);\n                setToolTipText(action.getValue(\"BTN_TOOLTIP\").toString()); // NOI18N\n                if (!UIUtils.isOracleLookAndFeel()) setOpaque(false);\n            }\n            public Dimension getMinimumSize() {\n                Dimension d = super.getMinimumSize();\n                d.width = 5;\n                return d;\n            }\n        }\n        \n        JPanel actions = new JPanel(new ButtonsLayout());\n        actions.setOpaque(true);\n        actions.setBackground(UIUtils.getProfilerResultsBackground());\n        actions.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));\n        actions.add(new ThinButton(openA, Icons.getIcon(ProfilerIcons.SNAPSHOT_OPEN)));\n        actions.add(new ThinButton(exportA, Icons.getIcon(GeneralIcons.EXPORT)));\n        actions.add(new ThinButton(compareA, Icons.getIcon(ProfilerIcons.SNAPSHOTS_COMPARE)));\n        actions.add(new ThinButton(renameA, Icons.getIcon(GeneralIcons.RENAME)));\n        actions.add(new ThinButton(deleteA, Icons.getIcon(ProfilerIcons.RUN_GC)));\n        add(actions, BorderLayout.SOUTH);\n        \n        updateButtons(Collections.EMPTY_LIST);\n    }\n    \n    private void updateButtons(List<Snapshot> selectedSnapshots) {\n        int selected = selectedSnapshots.size();\n        openA.setEnabled(selected > 0);\n        exportA.setEnabled(selected > 0);\n        compareA.setEnabled(selected == 2 && !selectedSnapshots.get(0).isHeapDump()\n                                          && !selectedSnapshots.get(1).isHeapDump());\n        renameA.setEnabled(selected == 1);\n        deleteA.setEnabled(selected > 0);\n        \n    }\n    \n    private static boolean hasSnapshots(ProfilerSession session) {\n//        ResultsManager rm = ResultsManager.getDefault();\n//        Lookup.Provider project = session.getProject();\n//        return rm.hasSnapshotsFor(project);\n        \n        return true;\n    }\n    \n    private static boolean isOpen(Snapshot s) {\n        File f = FileUtil.toFile(s.getFile());\n        if (f == null) return false; // #236480\n\n        if (s.isHeapDump()) {\n            Set<TopComponent> tcs = WindowManager.getDefault().getRegistry().getOpened();\n            for (TopComponent tc : tcs) {\n                if (f.equals(tc.getClientProperty(ProfilerTopComponent.RECENT_FILE_KEY)))\n                    return true;\n            }\n        } else {\n            LoadedSnapshot ls = ResultsManager.getDefault().findLoadedSnapshot(f);\n            if (ls != null) return true;\n        }\n        return false;\n    }\n    \n    \n    private static void openSnapshots(final Collection<Snapshot> snapshots) {\n        SnapshotsWindowHelper.PROCESSOR.post(new Runnable() {\n            public void run() {\n                for (Snapshot snapshot : snapshots)\n                    ResultsManager.getDefault().openSnapshot(snapshot.getFile());\n            }\n        });\n    }\n    \n    private static void exportSnapshots(final Collection<Snapshot> snapshots) {\n        FileObject[] files = new FileObject[snapshots.size()];\n        int idx = 0;\n        for (Snapshot snapshot : snapshots) files[idx++] = snapshot.getFile();\n        ResultsManager.getDefault().exportSnapshots(files);\n    }\n    \n    private static void compareSnapshots(final Snapshot snapshot1, final Snapshot snapshot2) {\n        SnapshotsWindowHelper.PROCESSOR.post(new Runnable() {\n            public void run() {\n                final FileObject file1 = snapshot1.getFile();\n                final FileObject file2 = snapshot2.getFile();\n                if (CompareSnapshotsAction.areComparableSnapshots(file1, file2)) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { ResultsManager.getDefault().compareSnapshots(file1, file2); }\n                    });\n                } else {\n                    ProfilerDialogs.displayError(Bundle.SnapshotsWindowUI_msgCannotCompareSnapshots());\n                }   \n            }\n        });\n    }\n    \n    private static void renameSnapshot(final Snapshot snapshot, final AbstractTableModel model) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                final FileObject file = snapshot.getFile();\n                String origName = file.getName();\n                RenameSnapshotPanel panel = new RenameSnapshotPanel();\n                panel.setSnapshotName(origName);\n                DialogDescriptor dd = new DialogDescriptor(panel, Bundle.SnapshotsWindowUI_capRenameSnapshot(),\n                            true, new Object[] { DialogDescriptor.OK_OPTION, DialogDescriptor.CANCEL_OPTION },\n                            DialogDescriptor.OK_OPTION, 0, null, null);\n                Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n                d.setVisible(true);\n                \n                if (dd.getValue() != DialogDescriptor.OK_OPTION) return;\n                \n                final String newName = panel.getSnapshotName();\n                if (!origName.equals(newName)) {\n                    if (newName.isEmpty()) {\n                        ProfilerDialogs.displayError(Bundle.SnapshotsWindowUI_msgNameEmpty());\n                        renameSnapshot(snapshot, model);\n                    } else {\n                        SnapshotsWindowHelper.PROCESSOR.post(new Runnable() {\n                            public void run() {\n                                FileLock lock = null;\n                                try {\n                                    lock = file.lock();\n                                    final LoadedSnapshot ls = ResultsManager.getDefault().findLoadedSnapshot(\n                                            FileUtil.toFile(file));\n                                    file.rename(lock, newName, file.getExt());\n                                    if (ls != null) ls.setFile(FileUtil.toFile(file));\n                                    snapshot.loadDetails();\n                                    SwingUtilities.invokeLater(new Runnable() {\n                                        public void run() { model.fireTableDataChanged(); }\n                                    });\n                                } catch (IOException e) {\n                                    ProfilerDialogs.displayError(Bundle.SnapshotsWindowUI_msgRenameFailed(snapshot.getDisplayName()));\n                                    e.printStackTrace();\n                                    renameSnapshot(snapshot, model);\n                                } finally {\n                                    if (lock != null) lock.releaseLock();\n                                }\n                            }\n                        });\n                    }\n                }\n            }\n        });\n    }\n    \n    private void deleteSnapshots(final Collection<Snapshot> snapshots) {\n        SnapshotsWindowHelper.PROCESSOR.post(new Runnable() {\n            public void run() {\n                if (ProfilerDialogs.displayConfirmation(Bundle.SnapshotsWindowUI_msgDeleteSnapshots(), Bundle.SnapshotsWindowUI_capDeleteSnapshots())) {\n                    ResultsManager rm = null;\n                    for (Snapshot snapshot : snapshots) try {\n                        if (!snapshot.isHeapDump()) {\n                            if (rm == null) rm = ResultsManager.getDefault();\n                            LoadedSnapshot ls = rm.findLoadedSnapshot(FileUtil.toFile(snapshot.getFile()));\n                            if (ls != null) rm.closeSnapshot(ls);\n                        }\n                        DataObject.find(snapshot.getFile()).delete();\n                    } catch (Throwable t) {\n                        ProfilerDialogs.displayError(Bundle.SnapshotsWindowUI_msgDeleteFailed(snapshot.getDisplayName()));\n                        t.printStackTrace();\n                    }\n                    refreshSnapshots();\n                }\n            }\n        });\n    }\n    \n    \n    // --- TopComponent --------------------------------------------------------\n    \n    public void open() {\n        WindowManager wmanager = WindowManager.getDefault();\n        if (wmanager.findMode(this) == null) { // needs docking\n            Mode _mode = wmanager.findMode(Bundle.SnapshotsWindowUI_mode());\n            if (_mode != null) _mode.dockInto(this);\n        }\n        super.open();\n    }\n    \n    protected void componentOpened() {\n        super.componentOpened();\n        \n        refreshSnapshots();\n        \n        final boolean[] firstMainProject = new boolean[1];\n        \n        openProjectsListener = new ChangeListener() {\n            public void stateChanged(ChangeEvent e) {\n                if (!firstMainProject[0] && selector.getProject() == null && e.getSource() instanceof PropertyChangeEvent) {\n                    PropertyChangeEvent event = (PropertyChangeEvent)e.getSource();\n                    if (\"MainProject\".equals(event.getPropertyName())) { // NOI18N // OpenProjects.PROPERTY_MAIN_PROJECT\n                        if (event.getOldValue() == null && event.getNewValue() instanceof Lookup.Provider) {\n                            firstMainProject[0] = true;\n                            selector.setProject((Lookup.Provider)event.getNewValue());\n                            return;\n                        }\n                    }\n                }\n                \n                selector.resetModel();\n                selector.repaint();\n            }\n        };\n        ProjectUtilities.addOpenProjectsListener(openProjectsListener);\n    }\n    \n    protected void componentClosed() {\n        ProjectUtilities.removeOpenProjectsListener(openProjectsListener);\n        \n        super.componentClosed();\n    }\n    \n    public int getPersistenceType() {\n        return PERSISTENCE_ALWAYS;\n    }\n    \n    protected String preferredID() {\n        return ID;\n    }\n    \n    public HelpCtx getHelpCtx() {\n        return HELP_CTX;\n    }\n    \n    \n    // --- ProfilerTopComponent ------------------------------------------------\n    \n    protected Component defaultFocusOwner() {\n        return snapshotsTable;\n    }\n    \n    \n    // --- Snapshot wrapper  ---------------------------------------------------\n    \n    private static abstract class Snapshot implements Comparable {\n        \n        private final FileObject fo;\n        private String displayName;\n        private boolean customName;\n        private long timestamp;\n        private int snapshotType;\n        private boolean isHeapDump;\n\n        Snapshot(FileObject fo) {\n            this.fo = fo;\n            loadDetails();\n        }\n        \n        abstract boolean alternativeSorting();\n        \n        public String getDisplayName() {\n            return displayName;\n        }\n        \n        // Snapshot types (internal):\n        // 1: CPU snapshot\n        // 2: Memory snapshot\n        // 3: Thread dump\n        // 4: Heap dump\n        // 5: JDBC snapshot\n        \n        public int getSnapshotType() {\n            return snapshotType;\n        }\n\n        public static String getIconName(int type) {\n            switch (type) {\n                case 1: return ProfilerIcons.CPU;\n                case 2: return ProfilerIcons.MEMORY;\n                case 3: return ProfilerIcons.SNAPSHOT_THREADS;\n                case 4: return ProfilerIcons.HEAP_DUMP;\n                case 5: return ProfilerIcons.WINDOW_SQL;\n                default: return null;\n            }\n        }\n\n        public FileObject getFile() {\n            return fo;\n        }\n\n        public boolean isHeapDump() {\n            return isHeapDump;\n        }\n\n        void loadDetails() {\n            String fileName = fo.getName();\n            if (fo.getExt().equalsIgnoreCase(ResultsManager.HEAPDUMP_EXTENSION)) {\n                // Heap Dump\n                snapshotType = 4;\n                displayName = ResultsManager.getDefault().getHeapDumpDisplayName(fileName);\n                isHeapDump = true;\n//            } else if (fo.getExt().equalsIgnoreCase(ResultsManager.THREADDUMP_EXTENSION)) {\n//                // Thread Dump\n////                this.icon = Icons.getIcon(ProfilerIcons.HEAP_DUMP);\n////                this.icon =  ProfilerIcons.SNAPSHOT_THREADS;\n//                this.snapshotType = 4;\n//                this.displayName = ResultsManager.getDefault().getHeapDumpDisplayName(fo.getName());\n//                this.isHeapDump = false;\n            } else {\n                int type = ResultsManager.getDefault().getSnapshotType(fo);\n                if (type == LoadedSnapshot.SNAPSHOT_TYPE_CPU) snapshotType = 1; // CPU snapshot\n                else if (type == LoadedSnapshot.SNAPSHOT_TYPE_CPU_JDBC) snapshotType = 5; // JDBC snapshot\n                else snapshotType = 2; // Memory snapshot\n                displayName = ResultsManager.getDefault().getSnapshotDisplayName(fileName, type);\n                isHeapDump = false;\n            }\n            customName = fileName.equals(displayName);\n            if (!customName) {\n                String _timestamp = fileName.substring(fileName.lastIndexOf('-')); // NOI18N\n                try { timestamp = Long.parseLong(_timestamp); } catch (NumberFormatException e) {}\n            }\n        }\n\n        public boolean equals(Object o) {\n            return fo.equals(((Snapshot)o).fo);\n        }\n\n        public int hashCode() {\n            return fo.hashCode();\n        }\n\n        public int compareTo(Object o) {\n            Snapshot s = (Snapshot)o;\n            // Alternative sorting: when sorting by snapshot type, the secondary\n            // sorting sorts custom-named snapshots alphabetically and default-named\n            // snapshots by timestamp, newest first. Custom-named snapshots display\n            // above the default-named snapshots.\n            if (alternativeSorting()) {\n                if (customName) {\n                    if (!s.customName) return -1;\n                    else return Collator.getInstance().compare(getDisplayName(), s.getDisplayName());\n                } else {\n                    if (s.customName) return 1;\n                    else return Long.compare(timestamp, s.timestamp);\n                }\n            } else {\n                return Collator.getInstance().compare(getDisplayName(), s.getDisplayName());\n            }\n        }\n    }\n    \n    \n    // --- Rename panel --------------------------------------------------------\n    \n    private static final class RenameSnapshotPanel extends JPanel {\n        //~ Instance fields ----------------------------------------------------------------------------------------------------\n\n        private JTextField textField;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        RenameSnapshotPanel() {\n            initComponents();\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        String getSnapshotName() {\n            return textField.getText().trim();\n        }\n\n        void setSnapshotName(final String text) {\n            textField.setText(text);\n            textField.selectAll();\n        }\n\n        private void initComponents() {\n            GridBagConstraints gridBagConstraints;\n            \n            JLabel textLabel = new JLabel();\n            Mnemonics.setLocalizedText(textLabel, Bundle.SnapshotsWindowUI_lblNewFile());\n            textLabel.setAlignmentX(JLabel.LEFT_ALIGNMENT);\n\n            textField = new JTextField();\n            textLabel.setLabelFor(textField);\n            textField.setPreferredSize(new Dimension(350, textField.getPreferredSize().height));\n            textField.requestFocus();            \n            textField.setAlignmentX(JLabel.LEFT_ALIGNMENT);\n\n            setLayout(new GridBagLayout());\n            \n            gridBagConstraints = new GridBagConstraints();\n            gridBagConstraints.gridx = 0;\n            gridBagConstraints.gridy = 0;\n            gridBagConstraints.weightx = 1.0;\n            gridBagConstraints.insets = new java.awt.Insets(15, 10, 5, 10);\n            gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;\n            add(textLabel, gridBagConstraints);\n\n            gridBagConstraints = new GridBagConstraints();\n            gridBagConstraints.gridx = 0;\n            gridBagConstraints.gridy = 1;\n            gridBagConstraints.weightx = 1.0;\n            gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;\n            gridBagConstraints.insets = new java.awt.Insets(0, 10, 15, 10);\n            gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;\n            add(textField, gridBagConstraints);\n\n            gridBagConstraints = new GridBagConstraints();\n            gridBagConstraints.gridx = 0;\n            gridBagConstraints.gridy = 2;\n            gridBagConstraints.weightx = 1.0;\n            gridBagConstraints.weighty = 1.0;            \n            add(new JPanel(), gridBagConstraints);\n            \n            getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(\n                    NotifyDescriptor.class, \"ACSD_InputPanel\")); // NOI18N\n            textField.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(\n                    NotifyDescriptor.class, \"ACSD_InputField\")); // NOI18N\n                    \n        }\n    };\n    \n    \n    // --- Buttons Layout ------------------------------------------------------\n    \n    private static final class ButtonsLayout implements LayoutManager {\n        \n        private static final int HGAP = 2;\n        private static final float MAX_WIDTH_FACTOR = 1.8f;\n        \n        public void layoutContainer(Container parent) {\n            int c = parent.getComponentCount();\n            \n            Insets insets = parent.getInsets();\n            Dimension size = parent.getSize();\n            size.width = Math.min(size.width, maximumLayoutSize(parent).width);\n            \n            int x = insets.left;\n            int y = insets.top;\n            int w = size.width - x - insets.right - HGAP * (c - 1);\n            int h = size.height - y - insets.bottom;\n            \n            int m = w % c;\n            w /= c;\n\n            for (int i = 0; i < c; i++) {\n                int o = i < m ? 1 : 0;\n                parent.getComponent(i).setBounds(x, y, w + o, h);\n                x += w + o + HGAP;\n            }\n        }\n\n        public Dimension preferredLayoutSize(Container parent) {\n            int prefw = 0;\n            int prefh = 0;\n            for (Component c : parent.getComponents()) {\n                Dimension pref = c.getPreferredSize();\n                prefw += pref.width;\n                prefh = Math.max(prefh, pref.height);\n            }\n            prefw += HGAP * (parent.getComponentCount() - 1);\n            \n            Insets i = parent.getInsets();\n            prefw += i.left + i.right;\n            prefh += i.top + i.bottom;\n            \n            return new Dimension(prefw, prefh);\n        }\n\n        public Dimension minimumLayoutSize(Container parent) {\n            int minw = 0;\n            int minh = 0;\n            for (Component c : parent.getComponents()) {\n                Dimension min = c.getMinimumSize();\n                minw += min.width;\n                minh = Math.max(minh, min.height);\n            }\n            minw += HGAP * (parent.getComponentCount() - 1);\n            return new Dimension(minw, minh);\n        }\n        \n        private Dimension maximumLayoutSize(Container parent) {\n            int maxw = 0;\n            int maxh = 0;\n            for (Component c : parent.getComponents()) {\n                Dimension pref = c.getPreferredSize();\n                maxw += pref.height * MAX_WIDTH_FACTOR;\n                maxh = Math.max(maxh, pref.height);\n            }\n            maxw += HGAP * (parent.getComponentCount() - 1);\n            \n            Insets i = parent.getInsets();\n            maxw += i.left + i.right;\n            maxh += i.top + i.bottom;\n            \n            return new Dimension(maxw, maxh);\n        }\n        \n        public void addLayoutComponent(String name, Component comp) {}\n\n        public void removeLayoutComponent(Component comp) {}\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/impl/WeakProcessor.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.impl;\n\nimport java.lang.ref.Reference;\nimport java.lang.ref.WeakReference;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class WeakProcessor {\n\n    private Reference<RequestProcessor> processor;\n\n    private final String name;\n    private final int throughput;\n\n    public WeakProcessor(String name) {\n        this(name, 1);\n    }\n\n    public WeakProcessor(String name, int throughput) {\n        this.name = name;\n        this.throughput = throughput;\n    }\n\n    public void post(Runnable task) {\n        processor().post(task);\n    }\n\n    public void post(Runnable task, int delay) {\n        processor().post(task, delay);\n    }\n\n    private synchronized RequestProcessor processor() {\n        RequestProcessor p = processor != null ? processor.get() : null;\n\n        if (p == null) {\n            p = new RequestProcessor(name, throughput);\n            processor = new WeakReference(p);\n        }\n\n        return p;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/impl/WelcomePanel.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.impl;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.net.URL;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToolTip;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.NoCaret;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerFeature;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"WelcomePanel_howtoCaption=Configure and Start Profiling\",\n    \"WelcomePanel_clickForSetings=Click the {0} button in toolbar and select the desired profiling mode:\",\n    \"WelcomePanel_startProfiling=Click the {0} button in toolbar once the session is configured to start profiling.\",\n    \"WelcomePanel_modifyProfiling=Use the {0} <b>dropdown arrow</b> to change profiling settings for the session.\"\n})\npublic abstract class WelcomePanel extends JPanel {\n\n    public static final String CAPTION = Bundle.WelcomePanel_howtoCaption();\n\n    public WelcomePanel(String configureButton, String profileButton, Set<ProfilerFeature> features) {\n\n        Color background = UIUtils.getProfilerResultsBackground();\n\n        JPanel pp = new JPanel(new GridBagLayout());\n        pp.setOpaque(true);\n        pp.setBackground(background);\n\n        int y = 0;\n\n        Paragraph header = new Paragraph(null, CAPTION, 3, background);\n        header.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, header.getForeground()));\n        if (UIUtils.isNimbus()) header.setOpaque(false);\n        GridBagConstraints c = new GridBagConstraints();\n        c.gridy = y++;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(4, 20, 4, 20);\n        pp.add(header, c);\n        \n        int counter = 0;\n        \n        Paragraph hint1 = new Paragraph(Bundle.WelcomePanel_clickForSetings(\"<b><a href='#'>\" + configureButton + \"</a></b>\"), Integer.toString(++counter), 1, background) { // NOI18N\n            protected void showURL(URL url) { highlightItem(null); }\n        };\n        c = new GridBagConstraints();\n        c.gridy = y++;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(4, 28, 0, 20);\n        pp.add(hint1, c);\n        \n        for (ProfilerFeature feature : features) {\n        \n            JLabel l1 = new JLabel(feature.getName(), feature.getIcon(), JLabel.LEADING);\n            l1.setFont(new JToolTip().getFont());\n            l1.setIconTextGap(l1.getIconTextGap() + 2);\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = y;\n            c.gridwidth = 1;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.insets = new Insets(3, 60, 3, 10);\n            pp.add(l1, c);\n\n            JLabel l2 = new JLabel(feature.getDescription());\n            l2.setFont(l1.getFont());\n            l2.setEnabled(false);\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = y++;\n            c.gridwidth = 1;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(3, 0, 3, 20);\n            pp.add(l2, c);\n        \n        }\n        \n        Paragraph hint2 = new Paragraph(Bundle.WelcomePanel_startProfiling(\"<b>\" + profileButton + \"</b>\"), Integer.toString(++counter), 1, background); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = y++;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(6, 28, 0, 20);\n        pp.add(hint2, c);\n        \n        Paragraph hint3 = new Paragraph(Bundle.WelcomePanel_modifyProfiling(profileButton), Integer.toString(++counter), 1, background); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = y++;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(0, 28, 0, 20);\n        pp.add(hint3, c);\n        \n        int w = pp.getMinimumSize().width;\n        \n        header.setSize(w, Integer.MAX_VALUE);\n        header.setPreferredSize(new Dimension(w, header.getPreferredSize().height));\n        \n        hint1.setSize(w, Integer.MAX_VALUE);\n        hint1.setPreferredSize(new Dimension(w, hint1.getPreferredSize().height));\n        \n        hint2.setSize(w, Integer.MAX_VALUE);\n        hint2.setPreferredSize(new Dimension(w, hint2.getPreferredSize().height));\n        \n        hint3.setSize(w, Integer.MAX_VALUE);\n        hint3.setPreferredSize(new Dimension(w, hint2.getPreferredSize().height));\n        \n        setLayout(new GridBagLayout());\n        setOpaque(true);\n        setBackground(UIUtils.getProfilerResultsBackground());\n        GridBagConstraints x = new GridBagConstraints();\n        x.gridx = 0;\n        x.gridy = 0;\n        x.weightx = 1;\n        x.weighty = 1;\n        x.fill = GridBagConstraints.NONE;\n        add(pp, x);\n        \n    }\n    \n    public abstract void highlightItem(String text);\n    \n    \n    private static class Paragraph extends HTMLTextArea {\n        \n        Paragraph(String text, String caption, int captionSizeDiff, Color background) {\n            setCaret(new NoCaret());\n            setShowPopup(false);\n            setBackground(background);\n            if (UIUtils.isNimbus()) setOpaque(false);\n            \n            setFocusable(false);\n            \n            setFont(new JToolTip().getFont());\n            setText(setupText(text, caption, captionSizeDiff));\n        }\n        \n        private String setupText(String text, String caption, int captionSizeDiff) {\n            int fsize = getFont().getSize() + captionSizeDiff;\n            return caption == null ? text : \"<span style='font-size:\" + fsize + \"px;'>\" + caption + // NOI18N\n                                            \"</span>\" + (text == null ? \"\" : \". \" + text); // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/ui/DropdownButton.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.ui;\n\nimport java.awt.AWTEvent;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseEvent;\nimport java.util.Objects;\nimport javax.swing.AbstractAction;\nimport javax.swing.DefaultButtonModel;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToolBar;\nimport javax.swing.KeyStroke;\nimport javax.swing.ToolTipManager;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.GenericToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.SmallButton;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class DropdownButton extends JPanel {\n\n    private static final Icon DROPDOWN_ICON = Icons.getIcon(GeneralIcons.POPUP_ARROW);\n    private static final int DROPDOWN_ICON_WIDTH = DROPDOWN_ICON.getIconWidth();\n    private static final int DROPDOWN_ICON_HEIGHT = DROPDOWN_ICON.getIconHeight();\n\n    private static final String NO_ACTION = \"none\"; // NOI18N\n    private static final String POPUP_ACTION = \"displayPopup\"; // NOI18N\n\n    private static final int POPUP_EXTENT;\n    private static final int POPUP_OFFSET;\n    private static final int POPUP_XWIDTH;\n    private static final int POPUP_MARGIN;\n\n    static {\n        if (UIUtils.isWindowsClassicLookAndFeel()) {\n            POPUP_EXTENT = 18;\n            POPUP_OFFSET = 6;\n            POPUP_XWIDTH = -1;\n            POPUP_MARGIN = 6;\n        } else if (UIUtils.isWindowsLookAndFeel()) {\n            POPUP_EXTENT = 15;\n            POPUP_OFFSET = 4;\n            POPUP_XWIDTH = -1;\n            POPUP_MARGIN = 6;\n        } else if (UIUtils.isNimbus()) {\n            POPUP_EXTENT = 17;\n            POPUP_OFFSET = 6;\n            POPUP_XWIDTH = -1;\n            POPUP_MARGIN = 6;\n        } else if (UIUtils.isMetalLookAndFeel()) {\n            POPUP_EXTENT = 16;\n            POPUP_OFFSET = 5;\n            POPUP_XWIDTH = -2;\n            POPUP_MARGIN = 6;\n        } else if (UIUtils.isAquaLookAndFeel()) {\n            POPUP_EXTENT = 19;\n            POPUP_OFFSET = 7;\n            POPUP_XWIDTH = -8;\n            POPUP_MARGIN = 6;\n        } else {\n            POPUP_EXTENT = 16;\n            POPUP_OFFSET = 5;\n            POPUP_XWIDTH = -2;\n            POPUP_MARGIN = 6;\n        }\n    }\n    \n    \n    private final JComponent container;\n    private final Button button;\n    private final Popup popup;\n    \n    private boolean pushed;\n    \n    \n    public DropdownButton(String text, Icon icon, boolean toolbar) {\n        setOpaque(false);\n        \n        if (toolbar) {\n            JToolBar tb = new GenericToolbar() {\n                public void doLayout() {\n                    for (Component c : getComponents())\n                        c.setBounds(0, 0, getWidth(), getHeight());\n                }\n                public void paint(Graphics g) {\n                    paintChildren(g);\n                }\n            };\n            tb.setFloatable(false);\n            tb.setFocusable(false);\n            container = tb;\n            add(container);\n        } else {\n            container = this;\n        }\n        \n        button = new Button(text, icon);\n        container.add(button);\n        \n        popup = new Popup();\n        container.add(popup);\n        \n        KeyStroke down = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);\n        container.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(down, POPUP_ACTION);\n        container.getActionMap().put(POPUP_ACTION, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) { displayPopup(); }\n        });\n    }\n    \n    public boolean requestFocusInWindow() {\n        return popup.isFocusable() ? popup.requestFocusInWindow() :\n                                     button.requestFocusInWindow();\n    }\n    \n    public void setEnabled(boolean enabled) {\n        if (button != null) {\n            button.setEnabled(enabled);\n            if (enabled) exposeButton();\n            else exposePopup();\n        }\n    }\n    \n    public boolean isEnabled() {\n        return button == null ? false : button.isEnabled();\n    }\n    \n    public void setPopupEnabled(boolean enabled) {\n        if (popup != null) popup.setEnabled(enabled);\n    }\n    \n    public boolean isPopupEnabled() {\n        return popup == null ? false : popup.isEnabled();\n    }\n    \n    public void setPushed(boolean p) {\n        pushed = p;\n        repaint();\n    }\n    \n    public boolean isPushed() {\n        return pushed;\n    }\n    \n    \n    public void setToolTipText(String text) {\n        button.setToolTipText(text);\n    }\n    \n    public void setPushedToolTipText(String text) {\n        button.putClientProperty(\"PUSHED_TOOLTIP\", text); // NOI18N\n    }\n    \n    public void setPopupToolTipText(String text) {\n        popup.setToolTipText(text);\n    }\n    \n    \n    public void setText(String text) {\n        if (button != null) {\n            String _text = button.getText();\n            button.setText(text);\n            \n            Component parent = getParent();\n            if (!Objects.equals(text, _text) && parent != null) {\n                parent.invalidate();\n                parent.revalidate();\n                parent.repaint();\n            }\n        }\n    }\n    \n    public String getText() {\n        return button == null ? null : button.getText();\n    }\n    \n    public void setIcon(Icon icon) {\n        if (button != null) {\n            Icon _icon = button.getIcon();\n            button.setIcon(icon);\n            \n            Component parent = getParent();\n            if (!Objects.equals(icon, _icon) && parent != null) {\n                parent.invalidate();\n                parent.revalidate();\n                parent.repaint();\n            }\n        }\n    }\n    \n    public Icon getIcon() {\n        return button == null ? null : button.getIcon();\n    }\n    \n    \n    public void clickPopup() {\n        if (popup != null) popup.doClick();\n    }\n    \n    public void displayPopup() {\n        JPopupMenu menu = new JPopupMenu();\n        populatePopup(menu);\n        if (menu.getComponentCount() > 0) {\n            Dimension size = menu.getPreferredSize();\n            size.width = Math.max(size.width, getWidth());\n            menu.setPreferredSize(size);\n            menu.show(this, 0, getHeight());\n        }\n    }\n    \n    protected void populatePopup(JPopupMenu menu) {\n        // Implementation here\n    }\n    \n    protected void performAction() {\n        // Implementation here\n    }\n    \n    \n    public void paint(Graphics g) {\n        paintChildren(g);\n    }\n    \n    protected void paintChildren(Graphics g) {\n        super.paintChildren(g);\n        \n        DROPDOWN_ICON.paintIcon(this, g, getWidth() - DROPDOWN_ICON_WIDTH - POPUP_OFFSET,\n                                        (getHeight() - DROPDOWN_ICON_HEIGHT) / 2);\n        \n        if (pushed || !button.isEnabled() || container.getComponent(0) == popup || button.getModel().isRollover() || button.isFocusOwner()) {\n            g.setColor(Color.GRAY);\n            g.drawLine(getWidth() - POPUP_EXTENT, POPUP_MARGIN,\n                       getWidth() - POPUP_EXTENT, getHeight() - POPUP_MARGIN);\n        }\n    }\n    \n    private boolean wasIn;\n    private void processChildMouseEvent(MouseEvent e) {\n        boolean isIn = contains(e.getX(), e.getY());\n        boolean isPopupSide = e.getX() >= getWidth() - POPUP_EXTENT;\n        \n        switch (e.getID()) {\n            case MouseEvent.MOUSE_ENTERED:\n                if (!wasIn) {\n                    button.processEventImpl(fromEvent((MouseEvent)e, button, MouseEvent.MOUSE_ENTERED));\n                    popup.processEventImpl(fromEvent((MouseEvent)e, popup, MouseEvent.MOUSE_ENTERED));\n                }\n                break;\n            case MouseEvent.MOUSE_EXITED:\n                if (!isIn) {\n                    popup.processEventImpl(fromEvent((MouseEvent)e, popup, MouseEvent.MOUSE_EXITED));\n                    button.processEventImpl(fromEvent((MouseEvent)e, button, MouseEvent.MOUSE_EXITED));\n                    exposeButton();\n                }\n                break;\n            case MouseEvent.MOUSE_MOVED:\n                if (isPopupSide) {\n                    exposePopup();\n                    MouseEvent ee = fromEvent((MouseEvent)e, popup, MouseEvent.MOUSE_MOVED);\n                    popup.processEventImpl(ee);\n                    ToolTipManager.sharedInstance().mouseMoved(ee);\n                } else {\n                    exposeButton();\n                    MouseEvent ee = fromEvent((MouseEvent)e, button, MouseEvent.MOUSE_MOVED);\n                    button.processEventImpl(ee);\n                    ToolTipManager.sharedInstance().mouseMoved(ee);\n                }\n                break;\n            default:\n                if (isPopupSide) {\n                    popup.processEventImpl(e);\n                } else {\n                    button.processEventImpl(e);\n                }\n        }\n        \n        wasIn = isIn;\n    }\n    \n    private static MouseEvent fromEvent(MouseEvent e, Component source, int id) {\n        return new MouseEvent(source, id, e.getWhen(), e.getModifiers(), e.getX(),\n                              e.getY(), e.getClickCount(), e.isPopupTrigger());\n    }\n    \n    private boolean exposeButton() {\n        if (container.getComponent(0) == button) return false;\n        container.setComponentZOrder(button, 0);\n        repaint();\n        return true;\n    }\n    \n    private boolean exposePopup() {\n        if (container.getComponent(0) == popup) return false;\n        container.setComponentZOrder(popup, 0);\n        repaint();\n        return true;\n    }\n    \n    \n    public Dimension getPreferredSize() {\n        Dimension d = button.getPreferredSize();\n        d.width += POPUP_EXTENT + POPUP_XWIDTH;\n        return d;\n    }\n    \n    public Dimension getMinimumSize() {\n        return getPreferredSize();\n    }\n    \n    public Dimension getMaximumSize() {\n        return getPreferredSize();\n    }\n    \n    public void doLayout() {\n        for (Component c : getComponents())\n            c.setBounds(0, 0, getWidth(), getHeight());\n    }\n    \n    \n    private class Button extends SmallButton {\n        \n        Button(String text, Icon icon) {\n            super(text, icon);\n            \n            // See GenericToolbar.addImpl()\n            putClientProperty(\"MetalListener\", new Object()); // NOI18N\n            \n            if (UIUtils.isAquaLookAndFeel())\n                putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n            \n            setModel(new DefaultButtonModel() {\n                public boolean isRollover() {\n                    return super.isRollover() || (isEnabled() && (popup != null && popup.getModel().isRollover()));\n                }\n                public boolean isPressed() {\n                    return pushed || super.isPressed();\n                }\n                public boolean isArmed() {\n                    return pushed || super.isArmed();\n                }\n            });\n            \n            setHorizontalAlignment(LEADING);\n            setDefaultCapable(false);\n        }\n        \n        public String getToolTipText() {\n            if (pushed) {\n                Object pushedTT = getClientProperty(\"PUSHED_TOOLTIP\"); // NOI18N\n                if (pushedTT != null) return pushedTT.toString();\n            }\n            return super.getToolTipText();\n        }\n        \n        protected void fireActionPerformed(ActionEvent e) {\n            super.fireActionPerformed(e);\n            performAction();\n        }\n        \n        protected void processEvent(AWTEvent e) {\n            if (!(e instanceof MouseEvent)) processEventImpl(e);\n            else processChildMouseEvent((MouseEvent)e);\n        }\n        \n        private void processEventImpl(AWTEvent e) {\n            super.processEvent(e);\n        }\n        \n        public boolean hasFocus() {\n            return isEnabled() ? super.hasFocus() : popup.hasFocus();\n        }\n        \n        public void paint(Graphics g) {\n            Rectangle c = g.getClipBounds();\n            if (pushed || !isEnabled() || container.getComponent(0) != this)\n                g.setClip(0, 0, getWidth() - POPUP_EXTENT, getHeight());\n            super.paint(g);\n            g.setClip(c);\n        }\n        \n        public void repaint() {\n            DropdownButton.this.repaint();\n        }\n        \n        public Insets getMargin() {\n            Insets i = super.getMargin();\n            if (UIUtils.isWindowsClassicLookAndFeel()) {\n                if (i == null) {\n                    i = new Insets(1, 1, 1, 1);\n                } else {\n                    i.top = 1;\n                    i.left = 1;\n                    i.bottom = 1;\n                    i.right = 1;\n                }\n            } else if (UIUtils.isNimbusLookAndFeel()) {\n                if (i == null) {\n                    i = new Insets(0, 2, 0, 2);\n                } else {\n                    i.left = 2;\n                    i.right = 2;\n                }\n            } else if (UIUtils.isAquaLookAndFeel()) {\n                if (i == null) {\n                    i = new Insets(0, -6, 0, 0);\n                } else {\n                    i.left = -6;\n                    i.right = 0;\n                }\n            }\n            return i;\n        }\n        \n    }\n    \n    private class Popup extends JButton {\n        \n        Popup() {\n            super(\" \"); // NOI18N\n            \n            // See GenericToolbar.addImpl()\n            putClientProperty(\"MetalListener\", new Object()); // NOI18N\n            \n            setModel(new DefaultButtonModel() {\n                public boolean isRollover() {\n                    return super.isRollover() || pushed;\n                }\n            });\n            \n            setHorizontalAlignment(LEADING);\n            setDefaultCapable(false);\n            \n            getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), NO_ACTION);\n            getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true), NO_ACTION);\n        }\n        \n        protected void fireActionPerformed(ActionEvent e) {\n            super.fireActionPerformed(e);\n            displayPopup();\n        }\n        \n        protected void processEvent(AWTEvent e) {\n            if (!(e instanceof MouseEvent)) processEventImpl(e);\n            else processChildMouseEvent((MouseEvent)e);\n        }\n        \n        private void processEventImpl(AWTEvent e) {\n            super.processEvent(e);\n            if (e.getID() == MouseEvent.MOUSE_PRESSED) {\n                if (isFocusable()) requestFocus();\n                else button.requestFocus();\n            }\n        }\n        \n        public boolean hasFocus() {\n            return isFocusable() ? super.hasFocus() : button.hasFocus();\n            \n        }\n        \n        public boolean isFocusable() {\n            return !button.isEnabled();\n        }\n        \n        public void paint(Graphics g) {\n            if (pushed || !button.isEnabled() || container.getComponent(0) == this) {\n                Rectangle c = g.getClipBounds();\n                g.setClip(getWidth() - POPUP_EXTENT, 0, POPUP_EXTENT, getHeight());\n                super.paint(g);\n                g.setClip(c);\n            }\n        }\n        \n        public void repaint() {\n            DropdownButton.this.repaint();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/ui/ProjectSelector.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.ui;\n\nimport org.graalvm.visualvm.lib.ui.components.LazyComboBox;\nimport java.awt.Component;\nimport java.awt.Font;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.DefaultListCellRenderer;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport org.graalvm.visualvm.lib.profiler.api.ProjectUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ProjectSelector_ExternalProcess=External process\"\n})\npublic class ProjectSelector extends LazyComboBox<Lookup.Provider> {\n\n    public static final Lookup.Provider EXTERNAL_PROCESS = new Lookup.Provider() {\n        public Lookup getLookup() { return Lookup.EMPTY; }\n    };\n\n\n    public ProjectSelector(Populator populator) {\n        super(populator);\n        setRenderer(new ProjectNameRenderer());\n    }\n\n\n    public final Lookup.Provider getProject() {\n        Lookup.Provider project = (Lookup.Provider)getSelectedItem();\n        return project == EXTERNAL_PROCESS ? null : project;\n    }\n\n    public final void setProject(Lookup.Provider project) {\n        setSelectedItem(project == null ? EXTERNAL_PROCESS : project);\n    }\n\n    public void resetProject(Lookup.Provider project) {\n        if (getProject() == project) resetModel();\n    }\n\n\n    // --- Projects populator --------------------------------------------------\n\n    public static class Populator extends LazyComboBox.Populator<Lookup.Provider> {\n\n        protected Lookup.Provider initialProject() {\n            return null;\n        }\n\n        protected Collection<Lookup.Provider> additionalProjects() {\n            return Collections.EMPTY_SET;\n        }\n        \n        protected final Lookup.Provider initial() {\n            Lookup.Provider initial = initialProject();\n            return initial == null ? EXTERNAL_PROCESS : initial;\n        }\n        \n        protected final Lookup.Provider[] populate() {\n            Set<Lookup.Provider> s = new HashSet();\n            s.addAll(Arrays.asList(ProjectUtilities.getOpenedProjects()));\n            s.addAll(additionalProjects());\n\n            List<Lookup.Provider> l = new ArrayList();\n            Lookup.Provider[] pa = s.toArray(new Lookup.Provider[0]);\n            l.add(EXTERNAL_PROCESS);\n            l.addAll(Arrays.asList(ProjectUtilities.getSortedProjects(pa)));\n            return l.toArray(new Lookup.Provider[0]);\n        }\n    }\n    \n    \n    // --- Project renderer ----------------------------------------------------\n    \n    private static final class ProjectNameRenderer extends DefaultListCellRenderer {\n        \n        private Font _plainFont;\n        private Font _boldFont;\n        \n        private Renderer _renderer;\n\n        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,\n                                                      boolean cellHasFocus) {\n            JLabel renderer = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);\n            \n            if (_renderer == null) _renderer = new Renderer();\n            _renderer.setComponentOrientation(renderer.getComponentOrientation());\n            _renderer.setOpaque(renderer.isOpaque());\n            _renderer.setForeground(renderer.getForeground());\n            _renderer.setBackground(renderer.getBackground());\n            _renderer.setEnabled(renderer.isEnabled());\n            _renderer.setBorder(renderer.getBorder());\n            \n            if (value != EXTERNAL_PROCESS) {\n                Lookup.Provider p = (Lookup.Provider)value;\n                _renderer.setText(ProjectUtilities.getDisplayName(p));\n                _renderer.setIcon(ProjectUtilities.getIcon(p));\n                boolean main = ProjectUtilities.getMainProject() == value;\n                _renderer.setFontEx(main ? boldFont(renderer) : plainFont(renderer));\n            } else {\n                _renderer.setText(Bundle.ProjectSelector_ExternalProcess());\n                _renderer.setIcon(Icons.getIcon(GeneralIcons.JAVA_PROCESS));\n                _renderer.setFontEx(plainFont(renderer));\n            }\n\n            return _renderer;\n        }\n        \n        private Font plainFont(JLabel renderer) {\n            if (_plainFont == null) _plainFont = renderer.getFont().deriveFont(Font.PLAIN);\n            return _plainFont;\n        }\n        \n        private Font boldFont(JLabel renderer) {\n            if (_boldFont == null) _boldFont = renderer.getFont().deriveFont(Font.BOLD);\n            return _boldFont;\n        }\n        \n        // Default renderer doesn't follow font settings in combo (not popup)\n        private static class Renderer extends DefaultListCellRenderer {\n            public void setFont(Font font) {}\n            public void setFontEx(Font font) { super.setFont(font); }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/ui/SettingsPanel.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.v2.ui;\n\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JRadioButton;\nimport javax.swing.JTextField;\nimport javax.swing.SpinnerNumberModel;\nimport org.graalvm.visualvm.lib.ui.components.JExtendedSpinner;\nimport org.graalvm.visualvm.lib.ui.swing.PopupButton;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class SettingsPanel extends JPanel {\n\n    public SettingsPanel() {\n        super(null);\n\n        setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));\n        setOpaque(false);\n\n        add(Box.createVerticalStrut(defaultHeight()));\n    }\n\n\n    public void removeAll() {\n        super.removeAll();\n        add(Box.createVerticalStrut(defaultHeight()));\n    }\n\n\n    private static int DEFAULT_HEIGHT = -1;\n\n    private static int defaultHeight() {\n        if (DEFAULT_HEIGHT == -1) {\n            JPanel ref = new JPanel(null);\n            ref.setLayout(new BoxLayout(ref, BoxLayout.LINE_AXIS));\n            ref.setOpaque(false);\n\n            ref.add(new JLabel(\"XXX\")); // NOI18N\n\n            ref.add(new JButton(\"XXX\")); // NOI18N\n            ref.add(new PopupButton(\"XXX\")); // NOI18N\n\n            ref.add(new JCheckBox(\"XXX\")); // NOI18N\n            ref.add(new JRadioButton(\"XXX\")); // NOI18N\n\n            ref.add(new JTextField(\"XXX\")); // NOI18N\n\n            ref.add(new JExtendedSpinner(new SpinnerNumberModel(1, 1, 655535, 1)));\n\n            Component separator = Box.createHorizontalStrut(1);\n            Dimension d = separator.getMaximumSize(); d.height = 20;\n            separator.setMaximumSize(d);\n            ref.add(separator);\n            \n            DEFAULT_HEIGHT = ref.getPreferredSize().height;\n        }\n        return DEFAULT_HEIGHT;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/ui/TitledMenuSeparator.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Rectangle;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class TitledMenuSeparator extends JPanel {\n\n    public TitledMenuSeparator(String text) {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n\n        JLabel l = new JLabel(text);\n        l.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));\n        if (UIUtils.isWindowsLookAndFeel()) l.setOpaque(true);\n        l.setFont(l.getFont().deriveFont(Font.BOLD, l.getFont().getSize2D() - 1));\n        if (UIUtils.isWindowsLookAndFeel()) l.setForeground(UIUtils.getDisabledLineColor());\n\n        add(l, BorderLayout.WEST);\n\n        if (UIUtils.isGTKLookAndFeel()) {\n            add(UIUtils.createHorizontalSeparator(), BorderLayout.CENTER);\n        } else {\n            JComponent sep = new JPopupMenu.Separator();\n            add(sep, BorderLayout.CENTER);\n\n            if (UIUtils.isOracleLookAndFeel()) {\n                setOpaque(true);\n                setBackground(sep.getBackground());\n                l.setForeground(sep.getForeground());\n            }\n        }\n    }\n\n    public void doLayout() {\n        super.doLayout();\n        Component c = getComponent(1);\n\n        int h = c.getPreferredSize().height;\n        Rectangle b = c.getBounds();\n\n        b.y = (b.height - h) / 2;\n        b.height = h;\n        c.setBounds(b);\n    }\n\n    public Dimension getPreferredSize() {\n        Dimension d = getComponent(0).getPreferredSize();\n        d.width += 25;\n        return d;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/src/org/graalvm/visualvm/lib/profiler/v2/ui/ToggleButtonMenuItem.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.v2.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.image.BufferedImage;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JToggleButton;\nimport javax.swing.JToolBar;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.swing.StayOpenPopupMenu;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ToggleButtonMenuItem extends StayOpenPopupMenu.Item {\n\n    private final JLabel label;\n    private final Icon selectedIcon;\n    private final Icon unselectedIcon;\n\n    private boolean pressed;\n\n\n    public ToggleButtonMenuItem(String text, Icon icon) {\n        super(sizeText(text));\n        setLayout(null);\n\n        selectedIcon = createSelectedIcon(icon);\n        unselectedIcon = createUnselectedIcon(icon);\n\n        label = new JLabel(unselectedIcon, JLabel.LEADING);\n        add(label, BorderLayout.WEST);\n    }\n\n\n    public void setPressed(boolean pressed) {\n        if (this.pressed == pressed) return;\n\n        this.pressed = pressed;\n        label.setIcon(pressed ? selectedIcon : unselectedIcon);\n        repaint();\n    }\n\n    public boolean isPressed() {\n        return pressed;\n    }\n\n\n    public Dimension getPreferredSize() {\n        Dimension dim = super.getPreferredSize();\n        dim.height = Math.max(dim.height, getComponent(0).getPreferredSize().height);\n        return dim;\n    }\n\n    public void doLayout() {\n        getComponent(0).setBounds(0, 0, getWidth(), getHeight());\n    }\n\n\n    private static Icon createSelectedIcon(Icon icon) {\n        JComponent c = new JToggleButton() {\n            {\n                setSelected(true);\n                if (UIUtils.isAquaLookAndFeel())\n                    putClientProperty(\"JButton.buttonType\", \"textured\"); // NOI18N\n            }\n            protected void paintComponent(Graphics g) {\n                super.paintComponent(g);\n                if (UIUtils.isOracleLookAndFeel()) {\n                    Color c = UIManager.getColor(\"List.selectionBackground\"); // NOI18N\n                    g.setColor(new Color(c.getRed(), c.getGreen(), c.getBlue(), 140));\n                    g.fillRect(1, 1, getWidth() - 3, getHeight() - 2);\n                }\n            }\n        };\n\n        if (UIUtils.isWindowsLookAndFeel() || UIUtils.isMetalLookAndFeel() || UIUtils.isOracleLookAndFeel()) {\n            JToolBar t = new JToolBar() {\n                {\n                    setLayout(null);\n                    setOpaque(false);\n                    setRollover(true);\n                    setFloatable(false);\n                    setBorderPainted(false);\n                }\n                public void setSize(int w, int h) {\n                    super.setSize(w, h);\n                    if (getComponentCount() > 0) getComponent(0).setBounds(0, 0, w, h);\n                }\n            };\n            t.removeAll();\n            t.add(c);\n            c = t;\n        }\n\n        return createMenuIcon(icon, c);\n    }\n    \n    private static Icon createUnselectedIcon(Icon icon) {\n        return createMenuIcon(icon, null);\n    }\n\n    private static Icon createMenuIcon(Icon icon, Component decorator) {\n        int h = menuIconSize();\n        int w = UIUtils.isAquaLookAndFeel() ? h + 4 : h;\n\n        BufferedImage i = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);\n        Graphics g = i.getGraphics();\n\n        if (decorator != null) {\n            decorator.setSize(w, h);\n            decorator.paint(g);\n        }\n\n        icon.paintIcon(null, g, (w - icon.getIconWidth()) / 2, (h - icon.getIconHeight()) / 2);\n        g.dispose();\n\n        return new ImageIcon(i);\n    }\n\n    private static int menuIconSize() {\n        if (UIUtils.isMetalLookAndFeel()) return 23;\n        if (UIUtils.isAquaLookAndFeel()) return 26;\n        if (UIUtils.isGTKLookAndFeel()) return 24;\n        if (UIUtils.isNimbus()) return 25;\n        if (UIUtils.isOracleLookAndFeel()) return 21;\n        return 22;\n    }\n\n    private static String sizeText(String text) {\n        if (UIUtils.isMetalLookAndFeel()) return \"  \" + text; // NOI18N\n        if (UIUtils.isAquaLookAndFeel()) return \"   \" + text; // NOI18N\n        if (UIUtils.isGTKLookAndFeel()) return \" \" + text; // NOI18N\n        if (UIUtils.isWindowsClassicLookAndFeel()) return \"  \" + text; // NOI18N\n        return text;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/test/qa-functional/src/org/netbeans/test/profiler/ProfilerValidationTest.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.netbeans.test.profiler;\n\nimport java.awt.Component;\nimport java.awt.event.KeyEvent;\nimport java.util.logging.Level;\nimport javax.swing.JComboBox;\nimport javax.swing.JComponent;\nimport javax.swing.JSpinner;\nimport junit.framework.Test;\nimport org.netbeans.jellytools.Bundle;\nimport org.netbeans.jellytools.EditorOperator;\nimport org.netbeans.jellytools.JavaProjectsTabOperator;\nimport org.netbeans.jellytools.JellyTestCase;\nimport org.netbeans.jellytools.MainWindowOperator;\nimport org.netbeans.jellytools.NbDialogOperator;\nimport org.netbeans.jellytools.NewJavaProjectNameLocationStepOperator;\nimport org.netbeans.jellytools.NewProjectWizardOperator;\nimport org.netbeans.jellytools.OptionsOperator;\nimport org.netbeans.jellytools.OutputTabOperator;\nimport org.netbeans.jellytools.TopComponentOperator;\nimport org.netbeans.jellytools.actions.Action;\nimport org.netbeans.jellytools.actions.EditAction;\nimport org.netbeans.jellytools.nodes.JavaProjectRootNode;\nimport org.netbeans.jellytools.nodes.Node;\nimport org.netbeans.jellytools.nodes.SourcePackagesNode;\nimport org.netbeans.jemmy.ComponentChooser;\nimport org.netbeans.jemmy.EventTool;\nimport org.netbeans.jemmy.JemmyException;\nimport org.netbeans.jemmy.Waitable;\nimport org.netbeans.jemmy.Waiter;\nimport org.netbeans.jemmy.operators.ContainerOperator;\nimport org.netbeans.jemmy.operators.JButtonOperator;\nimport org.netbeans.jemmy.operators.JComboBoxOperator;\nimport org.netbeans.jemmy.operators.JLabelOperator;\nimport org.netbeans.jemmy.operators.JListOperator;\nimport org.netbeans.jemmy.operators.JPopupMenuOperator;\nimport org.netbeans.jemmy.operators.JSpinnerOperator;\nimport org.netbeans.jemmy.operators.JTabbedPaneOperator;\nimport org.netbeans.jemmy.operators.JTableOperator;\nimport org.graalvm.visualvm.lib.common.Profiler;\n\n/**\n * Validation test of profiler.\n *\n * @author Alexandr Scherbatiy, Jiri Skrivanek\n */\npublic class ProfilerValidationTest extends JellyTestCase {\n\n    //private static final String SAMPLE_PROJECT_NAME = \"AnagramGame\";\n    private static final String VISIBLE_TOKEN = \"VISIBLE\";\n\n    /**\n     * Default constructor.\n     *\n     * @param name test case name\n     */\n    public ProfilerValidationTest(String name) {\n        super(name);\n    }\n\n    /**\n     * Define order of test cases.\n     *\n     * @return NbTestSuite instance\n     */\n    public static Test suite() {\n        return emptyConfiguration().failOnException(Level.SEVERE).failOnMessage(Level.SEVERE)\n                .addTest(ProfilerValidationTest.class,\n                        \"testCreateProject\",\n                        \"testMenus\",\n                        \"testOptions\",\n                        \"testProfiler\")\n                .suite();\n    }\n\n    /**\n     * Setup before every test case.\n     */\n    @Override\n    public void setUp() {\n        System.out.println(\"########  \" + getName() + \"  #######\");\n    }\n\n    /**\n     * Test create sample project to be profiled\n     */\n    public void testCreateProject() {\n        // create sample Anagram Game Java project\n        NewProjectWizardOperator npwo = NewProjectWizardOperator.invoke();\n        String samplesLbl = Bundle.getStringTrimmed(\"org.netbeans.modules.project.ui.Bundle\", \"Templates/Project/Samples\"); // \"Samples\"\n        String javaLbl = Bundle.getStringTrimmed(\"org.netbeans.modules.java.examples.Bundle\", \"Templates/Project/Samples/Standard\"); // \"Java\"\n        npwo.selectCategory(samplesLbl + \"|\" + javaLbl);\n        npwo.selectProject(Bundle.getStringTrimmed(\"org.netbeans.modules.java.examples.Bundle\",\n                \"Templates/Project/Samples/Standard/anagrams.zip\")); //\"Anagram Game\"\n        npwo.next();\n        NewJavaProjectNameLocationStepOperator npnlso = new NewJavaProjectNameLocationStepOperator();\n        String anagramGamePrName = npnlso.txtProjectName().getText();\n        npnlso.txtProjectLocation().setText(System.getProperty(\"netbeans.user\")); // NOI18N\n        npnlso.btFinish().pushNoBlock();\n        npnlso.getTimeouts().setTimeout(\"ComponentOperator.WaitStateTimeout\", 120000);\n        npnlso.waitClosed();\n        // wait project appear in projects view\n        JavaProjectRootNode projectNode = new JavaProjectsTabOperator().getJavaProjectRootNode(anagramGamePrName);\n        // add log message to application to \n        Node anagramsNode = new Node(new SourcePackagesNode(projectNode), \"ui|Anagrams.java\");\n        new EditAction().perform(anagramsNode);\n        EditorOperator eo = new EditorOperator(\"Anagrams.java\");\n        eo.replace(\"setVisible(true);\", \"setVisible(true);\\nSystem.out.println(\\\"\" + VISIBLE_TOKEN + \"\\\");\");\n        // build project\n        projectNode.buildProject();\n        MainWindowOperator.getDefault().waitStatusText(Bundle.getStringTrimmed(\"org.apache.tools.ant.module.run.Bundle\", \"FMT_finished_target_status\")); // \"Finished Building\"\n        eo.closeDiscard();\n        waitScanFinished();\n    }\n\n    /**\n     * Test Profiler Menus.\n     */\n    public void testMenus() {\n        String item = \"Profile|Profile Project\";\n        assertTrue(\"Menu item in incorrect state: \" + item, new Action(item, null).isEnabled());\n        item = \"Profile|Attach to External Process\";\n        assertTrue(\"Menu item in incorrect state: \" + item, new Action(item, null).isEnabled());\n        item = \"Profile|Take Snapshot of Collected Results\";\n        assertFalse(\"Menu item in incorrect state: \" + item, new Action(item, null).isEnabled());\n        item = \"Profile|Finish Profiler Session\";\n        assertFalse(\"Menu item in incorrect state: \" + item, new Action(item, null).isEnabled());\n        MainWindowOperator.getDefault().pushKey(KeyEvent.VK_ESCAPE);\n    }\n\n    /**\n     * Test Profiler options.\n     */\n    public void testOptions() {\n        OptionsOperator options = OptionsOperator.invoke();\n        options.selectJava();\n        JTabbedPaneOperator tabbedPane = new JTabbedPaneOperator(options);\n        tabbedPane.selectPage(\"Profiler\");\n        JListOperator categoriesOper = new JListOperator(options);\n        // General category\n        assertEquals(\"Wrong profiling port.\", 5140, new JSpinnerOperator(options).getValue());\n        // manage calibration data\n        new JButtonOperator(options, \"Manage\").pushNoBlock();\n        NbDialogOperator manageOper = new NbDialogOperator(\"Manage Calibration data\");\n        JTableOperator platformsOper = new JTableOperator(manageOper);\n        platformsOper.selectCell(0, 0);\n        new JButtonOperator(manageOper, \"Calibrate\").pushNoBlock();\n        new NbDialogOperator(\"Information\").ok();\n        manageOper.closeByButton();\n        // reset\n        new JButtonOperator(options, \"Reset\").push();\n        // Snapshots category\n        categoriesOper.selectItem(\"Snapshots\");\n        JLabelOperator lblSnapshotOper = new JLabelOperator(options, \"When taking snapshot:\");\n        assertEquals(\"Wrong value for \" + lblSnapshotOper.getText(), \"Open snapshot\", new JComboBoxOperator((JComboBox) lblSnapshotOper.getLabelFor()).getSelectedItem());\n        JLabelOperator lblOpenOper = new JLabelOperator(options, \"Open automatically:\");\n        assertEquals(\"Wrong value for \" + lblOpenOper.getText(), \"On first saved snapshot\", new JComboBoxOperator((JComboBox) lblOpenOper.getLabelFor()).getSelectedItem());\n        // Engine category\n        categoriesOper.selectItem(\"Engine\");\n        JLabelOperator lblSamplingOper = new JLabelOperator(options, \"Sampling frequency\");\n        assertEquals(\"Wrong value for \" + lblSamplingOper.getText(), 10, new JSpinnerOperator((JSpinner) lblSamplingOper.getLabelFor()).getValue());\n        options.cancel();\n    }\n\n    /**\n     * Test profiler<br>\n     * - call Profile|Profile Project<br>\n     * - click arrow button in opened profiling TopComponent<br>\n     * - in opened popup click Methods<br>\n     * - click Profile button to start profiling<br>\n     * - wait until text token appears in output window<br>\n     * - click \"Snapshot\" button in tool bar<br>\n     * - wait for snapshot TopComponent<br>\n     * - save snapshot<br>\n     * - call \"Profile|Finish Profiler Session\"<br>\n     */\n    public void testProfiler() {\n        new Action(\"Profile|Profile Project\", null).perform();\n        TopComponentOperator tcProfiler = new TopComponentOperator(\"AnagramGame\");\n        JButtonOperator btnArrow = new JButtonOperator(tcProfiler, new ComponentChooser() {\n\n            @Override\n            public boolean checkComponent(Component comp) {\n                return comp.getClass().getName().endsWith(\"Popup\");\n            }\n\n            @Override\n            public String getDescription() {\n                return \"org.graalvm.visualvm.lib.profiler.v2.ui.DropdownButton$Popup\";\n            }\n        });\n        //using doClick because btnArrow is unstandard component and btnArrow.push(); sometimes fails\n        btnArrow.doClick();\n        new JPopupMenuOperator().pushMenu(\"Methods\");\n        new JButtonOperator(tcProfiler, \"Profile\").push();\n        // wait for application visible\n        OutputTabOperator oto = new OutputTabOperator(\"profile\");\n        oto.getTimeouts().setTimeout(\"ComponentOperator.WaitStateTimeout\", 120000);\n        oto.waitText(VISIBLE_TOKEN);\n        new EventTool().waitNoEvent(1000);\n        // create snapshot\n        new JButtonOperator(tcProfiler, new ComponentChooser() {\n\n            private final String TOOLTIP = \"Take snapshot of collected results\";\n\n            @Override\n            public boolean checkComponent(Component comp) {\n                return TOOLTIP.equals(((JComponent) comp).getToolTipText());\n            }\n\n            @Override\n            public String getDescription() {\n                return \"tooltip is \" + TOOLTIP;\n            }\n        }).push();\n        TopComponentOperator tcSnapshot = new TopComponentOperator(new ContainerOperator(MainWindowOperator.getDefault(), new ComponentChooser() {\n\n            @Override\n            public boolean checkComponent(Component comp) {\n                return comp.getClass().getName().endsWith(\"SnapshotResultsWindow\");\n            }\n\n            @Override\n            public String getDescription() {\n                return \"org.graalvm.visualvm.lib.profiler.SnapshotResultsWindow\";\n            }\n        }));\n        tcSnapshot.save();\n        // stop profiler\n        new Action(\"Profile|Finish Profiler Session\", null).perform();\n        waitProfilerStopped();\n    }\n\n    /**\n     * Waits until profiler is not stopped.\n     */\n    private void waitProfilerStopped() {\n        try {\n            new Waiter(new Waitable() {\n                @Override\n                public Object actionProduced(Object object) {\n                    final int state = Profiler.getDefault().getProfilingState();\n                    final int mode = Profiler.getDefault().getProfilingMode();\n                    if ((state == Profiler.PROFILING_PAUSED) || (state == Profiler.PROFILING_RUNNING)) {\n                        if (mode == Profiler.MODE_PROFILE) {\n                            return null;\n                        }\n                    }\n                    return Boolean.TRUE;\n                }\n\n                @Override\n                public String getDescription() {\n                    return (\"Wait profiler stopped.\"); // NOI18N\n                }\n            }).waitAction(null);\n        } catch (InterruptedException ex) {\n            throw new JemmyException(\"Waiting for profiler stopped failed.\", ex);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler/test/unit/src/org/graalvm/visualvm/lib/profiler/actions/SelfSamplerActionTest.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.actions;\n\nimport java.io.DataOutputStream;\nimport java.io.OutputStream;\nimport java.util.logging.Level;\nimport org.junit.Test;\nimport org.netbeans.junit.Log;\nimport org.graalvm.visualvm.lib.profiler.ui.NpsDataObject;\nimport org.openide.cookies.OpenCookie;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.loaders.DataObject;\nimport static org.junit.Assert.*;\nimport org.netbeans.modules.sampler.Sampler;\n\n/** Shows how o.n.core uses the SelfSamplerAction to start and stop self profiling.\n *\n * @author Jaroslav Tulach <jtulach@netbeans.org>\n * @author Tomas Hurka\n */\npublic class SelfSamplerActionTest {\n\n    public SelfSamplerActionTest() {\n    }\n\n    @Test\n    public void testSelfProfileToStream() throws Exception {\n        Sampler sampler = Sampler.createManualSampler(\"testprofile\");\n        assertTrue(\"sampler instance\", sampler != null);\n\n        sampler.start();\n        Thread.sleep(1000);\n        assertSamplerThread(\"sampler-testprofile shall be there\", true);\n\n        FileObject fo = FileUtil.createMemoryFileSystem().getRoot().createData(\"slow.nps\");\n        OutputStream os = fo.getOutputStream();\n        DataOutputStream dos = new DataOutputStream(os);\n        sampler.stopAndWriteTo(dos);\n        dos.close();\n\n        if (fo.getSize() < 100) {\n            fail(\"The file shall have real content: \" + fo.getSize());\n        }\n\n        DataObject dataObject = DataObject.find(fo);\n        assertEquals(\"Nps DataObject\", NpsDataObject.class, dataObject.getClass());\n        OpenCookie oc = dataObject.getLookup().lookup(OpenCookie.class);\n        assertNotNull(\"Open cookie exists\", oc);\n\n        CharSequence log = Log.enable(\"\", Level.WARNING);\n        oc.open();\n\n        if (log.length() > 0) {\n            fail(\"There shall be no warnings:\\n\" + log);\n        }\n\n        assertSamplerThread(\"no sampler- thread shall be there\", false);\n    }\n\n    @Test\n    public void testSelfProfileCancel() throws Exception {\n        Sampler sampler = Sampler.createManualSampler(\"testprofile\");\n        assertTrue(\"sampler instance\", sampler != null);\n\n        sampler.start();\n        Thread.sleep(1000);\n        assertSamplerThread(\"sampler-testprofile shall be there\", true);\n\n        sampler.cancel();\n        Thread.sleep(1000);\n\n        assertSamplerThread(\"no sampler- thread shall be there\", false);\n    }\n\n    private void assertSamplerThread(String msg, boolean exist) {\n        for (Thread t : Thread.getAllStackTraces().keySet()) {\n            if (t.getName().startsWith(\"sampler-\")) {\n                assertTrue(msg + \" There is \" + t.getName() + \" thread\", exist);\n                return;\n            }\n        }\n        assertFalse(msg + \" There is no sampler- thread\", exist);\n    }\n\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project basedir=\".\" default=\"netbeans\" name=\"profiler.api\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.lib.profiler.api</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.lib.profiler.api/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/lib/profiler/api/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.2\nNetigso-Export-Package: org.graalvm.visualvm.lib.profiler.spi\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.lib.profiler.api-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/nbproject/genfiles.properties",
    "content": "# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=9d48cf2d\nnbproject/build-impl.xml.script.CRC32=78461761\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/nbproject/project.properties",
    "content": "# Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nis.autoload=true\njavac.source=1.8\nrequires.nb.javac=true\n\ntest-unit-sys-prop.java.awt.headless=true\n\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.common</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.16</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.45</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.23</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.32</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.3</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.application.views</friend>\n                <friend>org.graalvm.visualvm.charts</friend>\n                <friend>org.graalvm.visualvm.core</friend>\n                <friend>org.graalvm.visualvm.heapdump</friend>\n                <friend>org.graalvm.visualvm.heapviewer</friend>\n                <friend>org.graalvm.visualvm.heapviewer.console</friend>\n                <friend>org.graalvm.visualvm.heapviewer.truffle</friend>\n                <friend>org.graalvm.visualvm.jfr</friend>\n                <friend>org.graalvm.visualvm.lib.profiler</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.attach</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.heapwalker</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.oql</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.snaptracer</friend>\n                <friend>org.graalvm.visualvm.lib.ui</friend>\n                <friend>org.graalvm.visualvm.modules.appui</friend>\n                <friend>org.graalvm.visualvm.profiler</friend>\n                <friend>org.graalvm.visualvm.profiling</friend>\n                <friend>org.graalvm.visualvm.sampler</friend>\n                <friend>org.graalvm.visualvm.sampler.truffle</friend>\n                <friend>org.graalvm.visualvm.gotosource</friend>\n                <package>org.graalvm.visualvm.lib.profiler.api</package>\n                <package>org.graalvm.visualvm.lib.profiler.api.icons</package>\n                <package>org.graalvm.visualvm.lib.profiler.api.java</package>\n                <package>org.graalvm.visualvm.lib.profiler.api.project</package>\n                <package>org.graalvm.visualvm.lib.profiler.spi</package>\n                <package>org.graalvm.visualvm.lib.profiler.spi.java</package>\n                <package>org.graalvm.visualvm.lib.profiler.spi.project</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/../..\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/ActionsSupport.java",
    "content": "/*\n * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api;\n\nimport java.awt.event.KeyEvent;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.InputMap;\nimport javax.swing.KeyStroke;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.profiler.spi.ActionsSupportProvider;\nimport org.openide.util.Lookup;\n\n/**\n * Allows to customize key bindings for profiler actions.\n *\n * @author Jiri Sedlacek\n */\npublic final class ActionsSupport {\n\n    public static final KeyStroke NO_KEYSTROKE = KeyStroke.getKeyStroke(KeyEvent.VK_UNDEFINED, 0);\n\n    private static String ACC_DELIMITER;\n    public static String keyAcceleratorString(KeyStroke keyStroke) {\n        if (keyStroke == null || NO_KEYSTROKE.equals(keyStroke)) return null;\n\n        String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode());\n\n        int modifiers = keyStroke.getModifiers();\n        if (modifiers == 0) return keyText;\n\n        if (ACC_DELIMITER == null) {\n            ACC_DELIMITER = UIManager.getString(\"MenuItem.acceleratorDelimiter\"); // NOI18N\n            if (ACC_DELIMITER == null) ACC_DELIMITER = \"+\"; // NOI18N // Note: NetBeans default, Swing uses '-' by default\n        }\n\n        return KeyEvent.getKeyModifiersText(modifiers) + ACC_DELIMITER + keyText;\n    }\n\n    public static KeyStroke registerAction(String actionKey, Action action, ActionMap actionMap, InputMap inputMap) {\n        for (ActionsSupportProvider provider : Lookup.getDefault().lookupAll(ActionsSupportProvider.class)) {\n            KeyStroke ks = provider.registerAction(actionKey, action, actionMap, inputMap);\n            if (ks != null) return ks;\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Name=Java Profiler (API & SPI)\nOpenIDE-Module-Long-Description=\\\n    API and SPI module for Java Profiler\n\n# Gestures\nUSG_PROFILER_ATTACH=Profiler Attach\n#NOI18N\nUSG_PROFILER_ATTACH_ICON_BASE=org/graalvm/visualvm/lib/profiler/impl/icons/attach.png\nUSG_PROFILER_CONFIG=Profiler Settings\n#NOI18N\nUSG_PROFILER_CONFIG_ICON_BASE=org/graalvm/visualvm/lib/profiler/impl/icons/modifyProfiling.png\nUSG_PROFILER_PROFILE_APP=Profile Application\n#NOI18N\nUSG_PROFILER_PROFILE_APP_ICON_BASE=org/graalvm/visualvm/lib/profiler/impl/icons/profile.png\nUSG_PROFILER_PROFILE_CLASS=Profile Single Class\n#NOI18N\nUSG_PROFILER_PROFILE_PROFILE_CLASS_ICON_BASE=org/graalvm/visualvm/lib/profiler/impl/icons/profile.png\nUSG_PROFILER_RMS_SEARCH=Search in Root Method Selector\n#NOI18N\nUSG_PROFILER_RMS_SEARCH_ICON_BASE=org/graalvm/visualvm/lib/profiler/impl/icons/profile.png\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/EditorContext.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api;\n\nimport javax.swing.text.Document;\nimport javax.swing.text.JTextComponent;\nimport org.openide.filesystems.FileObject;\n\n/**\n * Editor context encapsulating document, project and (Swing) text component.\n *\n * @author Jiri Sedlacek\n */\npublic final class EditorContext {\n\n    private Document document;\n    private FileObject fileObject;\n    private JTextComponent textComponent;\n\n\n    public EditorContext(JTextComponent textComponent, Document document, FileObject fileObject) {\n        this.textComponent = textComponent;\n        this.document = document;\n        this.fileObject = fileObject;\n    }\n\n\n    public Document getDocument() {\n        return document;\n    }\n\n    public FileObject getFileObject() {\n        return fileObject;\n    }\n\n    public JTextComponent getTextComponent() {\n        return textComponent;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/EditorSupport.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api;\n\nimport org.graalvm.visualvm.lib.profiler.spi.EditorSupportProvider;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\n\n/**\n * Decouples the profiler implementation from the underlying source code\n * editor. Provides support for finding out eg. the currently edited file,\n * the offset within that file etc.\n *\n * @author Jiri Sedlacek\n * @author Jaroslav Bachorik\n */\nfinal public class EditorSupport {\n\n    private static EditorSupportProvider getSupport() {\n        EditorSupportProvider support = Lookup.getDefault().lookup(EditorSupportProvider.class);\n        return support != null ? support : EditorSupportProvider.NULL;\n    }\n\n    /**\n     * Returns true if currently focused IDE component is Java editor.\n     *\n     * @return true if currently focused IDE component is Java editor, false otherwise\n     */\n    public static boolean currentlyInJavaEditor() {\n        return getSupport().currentlyInJavaEditor();\n    }\n\n    /**\n     * Returns editor context of the most active Java editor.\n     *\n     * @return editor context of the most active Java editor or null if not available\n     */\n    public static EditorContext getMostActiveJavaEditorContext() {\n        return getSupport().getMostActiveJavaEditorContext();\n    }\n\n    /**\n     * Returns the FileObject of the most active editor document\n     * @return A FileObject or null\n     */\n    public static FileObject getCurrentFile() {\n        return getSupport().getCurrentFile();\n    }\n\n    /**\n     * Returns the caret position within the active editor document\n     * converted into line number\n     * @return The line number or -1\n     */\n    public static int getCurrentLine() {\n        return getLineForOffset(getCurrentFile(), getCurrentOffset());\n    }\n\n    /**\n     * Returns the caret position within the active editor document\n     * @return The caret offset or -1\n     */\n    public static int getCurrentOffset() {\n        return getSupport().getCurrentOffset();\n    }\n\n    /**\n     * Validates the current offset\n     * @return Returns TRUE if the current offset is valid within the bounds of the current file\n     */\n    public static boolean isCurrentOffsetValid() {\n        return isOffsetValid(getCurrentFile(), getCurrentOffset());\n    }\n    \n    /**\n     * Validates an offset within a particular file\n     * @param file The file to check\n     * @param offset The offset within the file\n     * @return Returns TRUE if the given offset is valid\n     */\n    public static boolean isOffsetValid(FileObject file, int offset) {\n        return getSupport().isOffsetValid(file, offset);\n    }\n    \n    /**\n     * Calculates the line number for a given offset\n     * @return Returns the line number within the active editor document or -1\n     */\n    public static int getLineForOffset(FileObject file, int offset) {\n        return getSupport().getLineForOffset(file, offset);\n    }\n    \n    /**\n     * Calculates the offset for a given line number\n     * @return Returns the offset for the provided file and line number or -1\n     */\n    public static int getOffsetForLine(FileObject file, int line) {\n        return getSupport().getOffsetForLine(file, line);\n    }\n    \n    /**\n     * Returns the tuple of start/end selection offset in the currently activated editor\n     * @return Tuple [startOffset, endOffset] or [-1, -1] if there is no selection\n     */\n    public static int[] getSelectionOffsets() {\n        return getSupport().getSelectionOffsets();\n    }\n\n    /**\n     * Returns the project the currently activated document belongs to\n     * @return The most active project or null\n     */\n    public static Lookup.Provider getCurrentProject() {\n        return getSupport().getCurrentProject();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/GestureSubmitter.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.api;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.LogRecord;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.common.AttachSettings;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n\n/**\n * A utility class for submitting UI Gestures Collector records\n * @author Jaroslav Bachorik\n * @author Jiri Sedlacek\n */\npublic class GestureSubmitter {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Logger USG_LOGGER = Logger.getLogger(\"org.netbeans.ui.metrics.profiler\"); // NOI18N\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n//    public static void logConfig(ProfilingSettings settings, InstrumentationFilter filter) {\n//        List<Object> paramList = new ArrayList<Object>();\n//\n//        fillParamsForProfiling(settings, paramList);\n//\n//        logUsage(\"CONFIG\", paramList); // NOI18N\n//    }\n\n    public static void logProfileApp(Lookup.Provider p, ProfilingSettings ps) {\n        List<Object> paramList = new ArrayList<>();\n\n        fillProjectParam(p, paramList);\n        fillParamsForProfiling(ps, paramList);\n\n        logUsage(\"PROFILE_APP\", paramList); // NOI18N\n    }\n\n    public static void logAttachApp(Lookup.Provider p, ProfilingSettings ps, AttachSettings as) {\n        List<Object> paramList = new ArrayList<>();\n\n        fillProjectParam(p, paramList);\n        fillParamsForProfiling(ps, paramList);\n        fillParamsForAttach(as, paramList);\n\n        logUsage(\"ATTACH_APP\", paramList); // NOI18N\n    }\n    \n    public static void logAttachExternal(ProfilingSettings ps, AttachSettings as) {\n        List<Object> paramList = new ArrayList<>();\n\n        fillParamsForProfiling(ps, paramList);\n        fillParamsForAttach(as, paramList);\n\n        logUsage(\"ATTACH_EXT\", paramList); // NOI18N\n    }\n\n//    public static void logProfileClass(Lookup.Provider profiledProject, SessionSettings session) {\n//        List<Object> paramList = new ArrayList<Object>();\n//\n//        fillProjectParam(profiledProject, paramList);\n//        fillParamsForSession(session, paramList);\n//\n//        logUsage(\"PROFILE_CLASS\", paramList); // NOI18N\n//    }\n\n//    public static void logAttach(Lookup.Provider profiledProject, AttachSettings attach) {\n//        List<Object> paramList = new ArrayList<Object>();\n//\n//        fillProjectParam(profiledProject, paramList);\n//        fillParamsForAttach(attach, paramList);\n//\n//        logUsage(\"ATTACH\", paramList); // NOI18N\n//    }\n    \n//    public static void logRMSSearch(String pattern) {\n//        logUsage(\"RMS_SEARCH\", Arrays.asList(new Object[]{pattern}));\n//    }\n\n    private static void fillProjectParam(Lookup.Provider profiledProject, List<Object> paramList) {\n        String param = \"\"; // NOI18N\n        if (profiledProject != null) {\n            param = profiledProject.getClass().getName();\n        }\n        paramList.add(0, param);\n    }\n    \n    private static void fillParamsForAttach(AttachSettings as, List<Object> paramList) {\n//        paramList.add(\"OS_\" + as.getHostOS());\n        paramList.add(as.isDirect() ? \"ATTACH_DIRECT\" : \"ATTACH_DYNAMIC\"); // NOI18N\n        paramList.add(as.isRemote() ? \"ATTACH_REMOTE\" : \"ATTACH_LOCAL\"); // NOI18N\n    }\n    \n    private static void fillParamsForProfiling(ProfilingSettings ps, List<Object> paramList) {\n        switch (ps.getProfilingType()) {\n            case ProfilingSettings.PROFILE_CPU_ENTIRE:\n                paramList.add(\"TYPE_CPU_ENTIRE\"); // NOI18N\n\n                break;\n            case ProfilingSettings.PROFILE_CPU_PART:\n                paramList.add(\"TYPE_CPU_PART\"); // NOI18N\n\n                break;\n            case ProfilingSettings.PROFILE_CPU_JDBC:\n                paramList.add(\"TYPE_CPU_JDBC\"); // NOI18N\n\n                break;\n            case ProfilingSettings.PROFILE_CPU_SAMPLING:\n                paramList.add(\"TYPE_CPU_SAMPLING\"); // NOI18N\n\n                break;\n            case ProfilingSettings.PROFILE_CPU_STOPWATCH:\n                paramList.add(\"TYPE_CPU_STOPWATCH\"); // NOI18N\n\n                break;\n            case ProfilingSettings.PROFILE_MEMORY_ALLOCATIONS:\n                paramList.add(\"TYPE_MEM_ALLOC\"); // NOI18N\n\n                break;\n            case ProfilingSettings.PROFILE_MEMORY_LIVENESS:\n                paramList.add(\"TYPE_MEM_LIVENESS\"); // NOI18N\n\n                break;\n            case ProfilingSettings.PROFILE_MEMORY_SAMPLING:\n                paramList.add(\"TYPE_MEM_SAMPLING\"); // NOI18N\n\n                break;\n            case ProfilingSettings.PROFILE_MONITOR:\n                paramList.add(\"TYPE_MONITOR\"); // NOI18N\n\n                break;\n        }\n        \n        if (ps.getThreadsMonitoringEnabled()) paramList.add(\"TYPE_THREADS\"); // NOI18N\n        \n        if (ps.getLockContentionMonitoringEnabled()) paramList.add(\"TYPE_LOCKS\"); // NOI18N\n    }\n\n//    private static void fillParamsForProfiling(ProfilingSettings ps, List<Object> paramList) {\n//        switch (ps.getProfilingType()) {\n//            case ProfilingSettings.PROFILE_CPU_ENTIRE:\n//                paramList.add(\"TYPE_CPU_ENTIRE\"); // NOI18N\n//\n//                break;\n//            case ProfilingSettings.PROFILE_CPU_PART:\n//                paramList.add(\"TYPE_CPU_PART\"); // NOI18N\n//\n//                break;\n//            case ProfilingSettings.PROFILE_CPU_SAMPLING:\n//                paramList.add(\"TYPE_CPU_SAMPLING\"); // NOI18N\n//\n//                break;\n//            case ProfilingSettings.PROFILE_CPU_STOPWATCH:\n//                paramList.add(\"TYPE_CPU_STOPWATCH\"); // NOI18N\n//\n//                break;\n//            case ProfilingSettings.PROFILE_MEMORY_ALLOCATIONS:\n//                paramList.add(\"TYPE_MEM_ALLOC\"); // NOI18N\n//\n//                break;\n//            case ProfilingSettings.PROFILE_MEMORY_LIVENESS:\n//                paramList.add(\"TYPE_MEM_LIVENESS\"); // NOI18N\n//\n//                break;\n//            case ProfilingSettings.PROFILE_MEMORY_SAMPLING:\n//                paramList.add(\"TYPE_MEM_SAMPLING\"); // NOI18N\n//\n//                break;\n//            case ProfilingSettings.PROFILE_MONITOR:\n//                paramList.add(\"TYPE_MONITOR\"); // NOI18N\n//\n//                break;\n//        }\n//\n//        switch (ps.getInstrScheme()) {\n//            case CommonConstants.INSTRSCHEME_EAGER:\n//                paramList.add(\"INSTR_EAGER\"); // NOI18N\n//\n//                break;\n//            case CommonConstants.INSTRSCHEME_LAZY:\n//                paramList.add(\"INSTR_LAZY\"); // NOI18N\n//\n//                break;\n//            case CommonConstants.INSTRSCHEME_TOTAL:\n//                paramList.add(\"INSTR_TOTAL\"); // NOI18N\n//\n//                break;\n//        }\n//\n//        paramList.add(ps.getProfileUnderlyingFramework() ? \"FRAMEWORK_YES\" : \"FRAMEWORK_NO\");\n//        paramList.add(ps.getExcludeWaitTime() ? \"WAIT_EXCLUDE\" : \"WAIT_INCLUDE\"); // NOI18N\n//        paramList.add(ps.getInstrumentMethodInvoke() ? \"REFL_INVOKE_YES\" : \"REFL_INVOKE_NO\"); // NOI18N\n//        paramList.add(ps.getInstrumentSpawnedThreads() ? \"SPAWNED_THREADS_YES\" : \"SPAWNED_THREADS_NO\"); // NOI18N\n//        paramList.add(ps.getThreadCPUTimerOn() ? \"THREAD_CPU_YES\" : \"THREAD_CPU_NO\"); // NOI18N\n//        paramList.add(ps.useProfilingPoints() ? \"PPOINTS_YES\" : \"PPOINTS_NO\"); //NOI18N\n//    }\n\n//    private static void fillParamsForSession(SessionSettings ss, List<Object> paramList) {\n//        paramList.add(\"JAVA_\" + ss.getJavaVersionString()); // NOI18N\n//    }\n\n    private static void logUsage(String startType, List<Object> params) {\n        LogRecord record = new LogRecord(Level.INFO, \"USG_PROFILER_\" + startType); // NOI18N\n        record.setResourceBundle(NbBundle.getBundle(GestureSubmitter.class));\n        record.setResourceBundleName(GestureSubmitter.class.getPackage().getName() + \".Bundle\"); // NOI18N\n        record.setLoggerName(USG_LOGGER.getName());\n        record.setParameters(params.toArray(new Object[0]));\n\n        USG_LOGGER.log(record);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/GoToSource.java",
    "content": "/*\n * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.api;\n\nimport java.util.Collection;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.profiler.spi.java.GoToSourceProvider;\nimport org.openide.awt.StatusDisplayer;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n * GoToSource class allows to open source file at specified line number or method.\n *\n * @author Jaroslav Bachorik\n * @author Tomas Hurka\n */\nfinal public class GoToSource {\n\n    private static final RequestProcessor srcOpenerRP = new RequestProcessor(\"Profiler Source Opener\"); // NOI18N\n\n    /**\n     * Returns true if at least one provider of GoToSource is available. This still\n     * doesn't mean that opening a concrete source is supported, the provider(s)\n     * may not support the source type.\n     *\n     * @return true if at least one provider of GoToSource is available, false otherwise\n     */\n    public static boolean isAvailable() {\n        return Lookup.getDefault().lookup(GoToSourceProvider.class) != null;\n    }\n\n    /**\n     * Open a source code file on a given position.\n     * @param srcFile The source file to be opened\n     * @param offset The position to open the file at\n     */\n    public static void openFile(final FileObject srcFile, final int offset) {\n        srcOpenerRP.post(new Runnable() {\n\n            @Override\n            public void run() {\n                openFileImpl(srcFile, offset);\n            }\n        });\n    }\n\n    /**\n     * Open a source specified by parameters.\n     * @param project The associated project\n     * @param className The class name\n     * @param methodName The method name or NULL\n     * @param methodSig The signature or NULL\n     */\n    public static void openSource(Lookup.Provider project, String className, String methodName, String methodSig) {\n        openSource(project, className, methodName, methodSig, -1);\n    }\n\n    /**\n     * Open a source specified by parameters.\n     * @param project The associated project\n     * @param className The class name\n     * @param methodName The method name or NULL\n     * @param line The line number or {@linkplain Integer#MIN_VALUE}\n     */\n    public static void openSource(Lookup.Provider project, String className, String methodName, int line) {\n        openSource(project, className, methodName, null, line);\n    }\n\n    private static void openSource(final Lookup.Provider project, final String className, final String methodName, final String signature, final int line) {\n        srcOpenerRP.post(new Runnable() {\n            \n            @Override\n            public void run() {\n                openSourceImpl(project, className, methodName, signature, line);\n            }\n        });\n    }\n    \n    @NbBundle.Messages({\n        \"# {0} - class name\",\n        \"OpeningSourceMsg=Opening source for class {0}\",\n        \"# {0} - class name\",\n        \"NoSourceFoundMessage=No source found for class {0}\"\n    })\n    private static void openSourceImpl(Lookup.Provider project, String className, String methodName, String signature, int line) {\n        int idx = methodName == null ? -1 : methodName.indexOf(\"[native]\"); // NOI18N\n        if (idx > -1) methodName = methodName.substring(0, idx);\n        \n        // *** logging stuff ***\n        ProfilerLogger.debug(\"Open Source: Project: \" + project); // NOI18N\n        ProfilerLogger.debug(\"Open Source: Class name: \" + className); // NOI18N\n        ProfilerLogger.debug(\"Open Source: Method name: \" + methodName); // NOI18N\n        ProfilerLogger.debug(\"Open Source: Method sig: \" + signature); // NOI18N\n        \n        Collection<? extends GoToSourceProvider> implementations = Lookup.getDefault().lookupAll(GoToSourceProvider.class);\n        \n        String st = Bundle.OpeningSourceMsg(className);\n        final String finalStatusText = st + \" ...\"; // NOI18N\n        StatusDisplayer.getDefault().setStatusText(finalStatusText);\n        \n        for(GoToSourceProvider impl : implementations) {\n            try {\n                if (impl.openSource(project, className, methodName, signature, line)) return;\n            } catch (Exception e) {\n                ProfilerLogger.log(e);\n            }\n        }\n        \n        ProfilerDialogs.displayError(Bundle.NoSourceFoundMessage(className));\n    }\n    \n    @NbBundle.Messages({\n        \"OpeningFileMsg=Opening source file {0}\",\n        \"OpenFileFailsMessage=File \\\"{0}\\\" does not exist or the offset \\\"{1}\\\" is out of range\"\n    })\n    private static void openFileImpl(FileObject srcFile, int offset) {\n        // *** logging stuff ***\n        ProfilerLogger.debug(\"Open Source: FileObject: \" + srcFile); // NOI18N\n        ProfilerLogger.debug(\"Open Source: Offset: \" + offset); // NOI18N\n        \n        Collection<? extends GoToSourceProvider> implementations = Lookup.getDefault().lookupAll(GoToSourceProvider.class);\n        \n        String st = Bundle.OpeningFileMsg(srcFile.getName());\n        final String finalStatusText = st + \" ...\"; // NOI18N\n        StatusDisplayer.getDefault().setStatusText(finalStatusText);\n        \n        for(GoToSourceProvider impl : implementations) {\n            try {\n                if (impl.openFile(srcFile, offset)) return;\n            } catch (Exception e) {\n                ProfilerLogger.log(e);\n            }\n        }\n        \n        ProfilerDialogs.displayError(Bundle.OpenFileFailsMessage(srcFile.getName(), offset));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/JavaPlatform.java",
    "content": "/*\n * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.utils.MiscUtils;\nimport org.graalvm.visualvm.lib.profiler.spi.JavaPlatformManagerProvider;\nimport org.graalvm.visualvm.lib.profiler.spi.JavaPlatformProvider;\nimport org.openide.util.Lookup;\n\n/**\n * JavaPlatform describes a java platform in a way that the profiler tools may utilize. It may serve as\n * description of the platform a profiler targets, or it may provide access to tools from the\n * particular SDK installation. It also provides information about individual platforms, for example\n * the Java platform version implemented, vendor name or implementation version.\n *\n * @author Tomas Hurka\n */\n\npublic final class JavaPlatform {\n\n    private final JavaPlatformProvider provider;\n\n    /**\n     * finds platform with specified platform id.\n     * @param platformId unique id of the platform\n     * @return platform which has plarformId as unique id\n     * or <code>null</code> if the is no such platform\n     */\n    public static JavaPlatform getJavaPlatformById(String platformId) {\n        if (platformId != null) {\n            List<JavaPlatform> platforms = getPlatforms();\n\n            for (JavaPlatform platform : platforms) {\n                if (platformId.equals(platform.getPlatformId())) {\n                    return platform;\n                }\n            }\n        }\n        return null;\n    }\n\n    /** Gets an list of JavaPlatfrom objects suitable for profiling.\n     * @return the array of java platform definitions.\n     */\n    public static List<JavaPlatform> getPlatforms() {\n        List<JavaPlatformProvider> platformProviders = provider().getPlatforms();\n        List<JavaPlatform> platforms = new ArrayList(platformProviders.size());\n        \n        for (JavaPlatformProvider p : platformProviders) {\n            if (p.getPlatformJavaFile() != null &&\n                MiscUtils.isSupportedJVM(p.getSystemProperties())) {\n                platforms.add(new JavaPlatform(p));\n            }\n        }\n        return Collections.unmodifiableList(platforms);\n    }\n\n    /**\n     * Get the \"default platform\", meaning the JDK on which profiler itself is running.\n     * @return the default platform, if it can be found, or null\n     */\n    public static JavaPlatform getDefaultPlatform() {\n        return new JavaPlatform(provider().getDefaultPlatform());        \n    }\n    \n    /**\n     * Shows java platforms customizer\n     */\n    public static void showCustomizer() {\n        provider().showCustomizer();                \n    }\n    \n    private static JavaPlatformManagerProvider provider() {\n        return Lookup.getDefault().lookup(JavaPlatformManagerProvider.class);\n    }\n    \n    JavaPlatform(JavaPlatformProvider p) {\n        provider = p;\n    }\n    \n    /**\n     * @return  a descriptive, human-readable name of the platform\n     */\n    public String getDisplayName() {\n        return provider.getDisplayName();\n    }\n\n    /**\n     * @return  a unique name of the platform\n     */\n    public String getPlatformId() {\n        return provider.getPlatformId();\n    }\n    \n    /**\n     * Returns the minor version of the Java SDK\n     * @return String\n     */\n    public int getPlatformJDKMinor() {\n        return Platform.getJDKMinorNumber(getVersion());\n    }\n    \n    /** Gets a version for JavaPlatform.\n     *\n     * @return Java version string\n     * @see CommonConstants#JDK_15_STRING\n     * @see CommonConstants#JDK_16_STRING\n     * @see CommonConstants#JDK_17_STRING\n     * @see CommonConstants#JDK_18_STRING\n     * @see CommonConstants#JDK_19_STRING\n     * @see CommonConstants#JDK_100_STRING\n     * @see CommonConstants#JDK_110_STRING\n     */\n    public String getPlatformJDKVersion() {\n        String ver = getVersion();\n\n        if (ver == null) {\n            return null;\n        }\n\n        return Platform.getJDKVersionString(ver);\n    }\n\n    /** Gets a path to java executable for specified platform.\n     * Errors when obtaining the java executable will be reported to the user and null will be returned.\n     *\n     * @return A path to java executable or null if not found\n     */\n    public String getPlatformJavaFile() {\n        return provider.getPlatformJavaFile();\n    }\n    \n    /** Gets the java platform system properties.\n     * @return the java platform system properties\n     */\n    public Map<String,String> getSystemProperties() {\n        return provider.getSystemProperties();\n    }\n    \n    /** Gets the java platform properties.\n     * @return the java platform system properties\n     */\n    public Map<String,String> getProperties() {\n        return provider.getProperties();\n    }\n\n    /** Gets the java platform architecture.\n     * @return the java platform architecture - 32 or 64\n     */\n    public int getPlatformArchitecture() {\n        String arch = getSystemProperties().get(\"sun.arch.data.model\"); // NOI18N\n\n        if (arch == null) {\n            return 32;\n        }\n        return Integer.parseInt(arch);\n    }\n    \n    /**\n     * Returns the version of the Java SDK\n     * @return String\n     */\n    public String getVersion() {\n        return getSystemProperties().get(\"java.version\");\n    }\n    \n    @Override\n    public String toString() {\n        return getDisplayName();\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj instanceof JavaPlatform) {\n            return getPlatformId().equals(((JavaPlatform)obj).getPlatformId());\n        }\n        return false;\n    }\n\n    @Override\n    public int hashCode() {\n        return getPlatformId().hashCode();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/ProfilerDialogs.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api;\n\nimport org.graalvm.visualvm.lib.profiler.spi.ProfilerDialogsProvider;\nimport org.openide.util.Lookup;\n\n/**\n * Support for displaying dialogs by the profiler.\n *\n * @author Jiri Sedlacek\n */\npublic final class ProfilerDialogs {\n\n    /**\n     * Displays a user-level info message. Can be run from any thread.\n     * @param message The info message to display\n     */\n    public static void displayInfo(String message) {\n        displayInfo(message, null, null);\n    }\n\n    /**\n     * Displays a user-level info message. Can be run from any thread.\n     * @param message The info message to display\n     * @param caption The caption of the dialog, null for default\n     * @param details Optional message with detailed information, null for no details\n     */\n    public static void displayInfo(String message, String caption, String details) {\n        ProfilerDialogsProvider p = provider();\n        if (p != null) p.displayInfo(message, caption, details);\n    }\n\n    /**\n     * Displays a user-level info message with a checkbox. Can be run from any thread.\n     * @param message The info message to display\n     * @param caption The caption of the dialog, null for default\n     * @param dnsaMessage The dnsa checkbox label, null for default\n     * @param key dialog ID, must be unique for each DNSA dialog\n     * @param dnsaDefault true if the dnsa checkbox should be selected by default, false otherwise\n     */\n    public static void displayInfoDNSA(String message, String caption, String dnsaMessage, String key, boolean dnsaDefault) {\n        ProfilerDialogsProvider p = provider();\n        if (p != null) p.displayInfoDNSA(message, caption, dnsaMessage, key, dnsaDefault);\n    }\n\n    /** Displays a user-level warning message. Can be run from any thread.\n     * @param message The warning message to display\n     */\n    public static void displayWarning(String message) {\n        displayWarning(message, null, null);\n    }\n    \n    /** Displays a user-level warning message. Can be run from any thread.\n     * @param message The warning message to display\n     * @param caption The caption of the dialog, null for default\n     * @param details Optional message with detailed information, null for no details\n     */\n    public static void displayWarning(String message, String caption, String details) {\n        ProfilerDialogsProvider p = provider();\n        if (p != null) p.displayWarning(message, caption, details);\n    }\n    \n    /**\n     * Displays a user-level warning message with a checkbox. Can be run from any thread.\n     * @param message The warning message to display\n     * @param caption The caption of the dialog, null for default\n     * @param dnsaMessage The dnsa checkbox label, null for default\n     * @param key dialog ID, must be unique for each DNSA dialog\n     * @param dnsaDefault true if the dnsa checkbox should be selected by default, false otherwise\n     */\n    public static void displayWarningDNSA(String message, String caption, String dnsaMessage, String key, boolean dnsaDefault) {\n        ProfilerDialogsProvider p = provider();\n        if (p != null) p.displayWarningDNSA(message, caption, dnsaMessage, key, dnsaDefault);\n    }\n    \n    /** Displays a user-level error message. Can be run from any thread.\n     * @param message The error message to display\n     */\n    public static void displayError(String message) {\n        displayError(message, null, null);\n    }\n    \n    /** Displays a user-level error message. Can be run from any thread.\n     * @param message The error message to display\n     * @param caption The caption of the dialog, null for default\n     * @param details Optional message with detailed information, null for no details\n     */\n    public static void displayError(String message, String caption, String details) {\n        ProfilerDialogsProvider p = provider();\n        if (p != null) p.displayError(message, caption, details);\n    }\n    \n    /**\n     * Displays a user-level confirmation message. Can be run from any thread.\n     * @param message The confirmation message to display\n     * @return true if the user has confirmed the dialog, false otherwise\n     */\n    public static boolean displayConfirmation(String message) {\n        return displayConfirmation(message, null);\n    }\n    \n    /**\n     * Displays a user-level confirmation message. Can be run from any thread.\n     * @param message The confirmation message to display\n     * @param caption The caption of the dialog, null for default\n     * @return true if the user has confirmed the dialog, false otherwise\n     */\n    public static boolean displayConfirmation(String message, String caption) {\n        ProfilerDialogsProvider p = provider();\n        if (p != null) return Boolean.TRUE.equals(p.displayConfirmation(message, caption, false));\n        else return false;\n    }\n    \n    /**\n     * Displays a user-level cancellable confirmation message. Can be run from any thread.\n     * @param message The confirmation message to display\n     * @param caption The caption of the dialog, null for default\n     * @return Boolean.TRUE if the user has confirmed the dialog, Boolean.FALSE if the user has rejected the dialog, null if the dialog has been cancelled\n     */\n    public static Boolean displayCancellableConfirmation(String message, String caption) {\n        ProfilerDialogsProvider p = provider();\n        if (p != null) return p.displayConfirmation(message, caption, true);\n        else return false;\n    }\n    \n    /**\n     * Displays a user-level confirmation message with a checkbox. Can be run from any thread.\n     * @param message The confirmation message to display\n     * @param caption The caption of the dialog, null for default\n     * @param dnsaMessage The dnsa checkbox label, null for default\n     * @param key dialog ID, must be unique for each DNSA dialog\n     * @param dnsaDefault true if the dnsa checkbox should be selected by default, false otherwise\n     * @return true if the user has confirmed the dialog, false otherwise\n     */\n    public static boolean displayConfirmationDNSA(String message, String caption, String dnsaMessage, String key, boolean dnsaDefault) {\n        ProfilerDialogsProvider p = provider();\n        if (p != null) return Boolean.TRUE.equals(p.displayConfirmationDNSA(message, caption, dnsaMessage, false, key, dnsaDefault));\n        else return false;\n    }\n    \n    /**\n     * Displays a user-level cancellable confirmation message with a checkbox. Can be run from any thread.\n     * @param message The confirmation message to display\n     * @param caption The caption of the dialog, null for default\n     * @param dnsaMessage The dnsa checkbox label, null for default\n     * @param key dialog ID, must be unique for each DNSA dialog\n     * @param dnsaDefault true if the dnsa checkbox should be selected by default, false otherwise\n     * @return Boolean.TRUE if the user has confirmed the dialog, Boolean.FALSE if the user has rejected the dialog, null if the dialog has been cancelled\n     */\n    public static Boolean displayCancellableConfirmationDNSA(String message, String caption, String dnsaMessage, String key, boolean dnsaDefault) {\n        ProfilerDialogsProvider p = provider();\n        if (p != null) return p.displayConfirmationDNSA(message, caption, dnsaMessage, true, key, dnsaDefault);\n        else return false;\n    }\n    \n    private static ProfilerDialogsProvider provider() {\n        return Lookup.getDefault().lookup(ProfilerDialogsProvider.class);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/ProfilerIDESettings.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.api;\n\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.Map;\nimport java.util.prefs.Preferences;\nimport org.graalvm.visualvm.lib.common.GlobalProfilingSettings;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\n\n\n/**\n * SystemOption to store UI settings for profiler\n */\npublic final class ProfilerIDESettings implements GlobalProfilingSettings {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    public static final String DO_NOT_SHOW_ATTACH_SETTINGS = \"dns-attach-settings\"; // NOI18N\n    public static final String DO_NOT_SHOW_JDK_DIALOG = \"dns-jdk-dialog\"; // NOI18N\n    public static final String DO_NOT_SHOW_PID_WINDOWS = \"dns-pid-windows4\"; // NOI18N\n    public static final int CPU_ENTIRE_APP = 0;\n    public static final int CPU_PART_APP = 1;\n    public static final int CPU_STARTUP = 2;\n    public static final int CPU_PROFILING_POINTS = 3;\n    public static final int OOME_DETECTION_NONE = 0;\n    public static final int OOME_DETECTION_PROJECTDIR = 1;\n    public static final int OOME_DETECTION_TEMPDIR = 2;\n    public static final int OOME_DETECTION_CUSTOMDIR = 3;\n    public static final int SNAPSHOT_WINDOW_OPEN_NEVER = 0;\n    public static final int SNAPSHOT_WINDOW_OPEN_PROFILER = 1;\n    public static final int SNAPSHOT_WINDOW_SHOW_PROFILER = 2;\n    public static final int SNAPSHOT_WINDOW_OPEN_FIRST = 3;\n    public static final int SNAPSHOT_WINDOW_OPEN_EACH = 4;\n    public static final int SNAPSHOT_WINDOW_CLOSE_NEVER = 0;\n    public static final int SNAPSHOT_WINDOW_CLOSE_PROFILER = 1;\n    public static final int SNAPSHOT_WINDOW_HIDE_PROFILER = 2;\n\n    /** The Window automatically opens always when profiling starts */\n    public static final int OPEN_ALWAYS = 1;\n\n    /** The Window automatically opens when profiling starts using only Monitoring */\n    public static final int OPEN_MONITORING = 2;\n\n    /** The Windows does not automatically open */\n    public static final int OPEN_NEVER = 3;\n\n    // --- Singleton pattern ---\n    private static final ProfilerIDESettings defaultInstance = new ProfilerIDESettings();\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Map<String, String> dnsaMap;\n    \n    // Keys for tracked properties\n    private final String AUTO_OPEN_SNAPSHOT_KEY_55 = \"autoOpenSnapshot\"; // NOI18N\n    private final String AUTO_SAVE_SNAPSHOT_KEY_55 = \"autoSaveSnapshot\"; // NOI18N\n    private final String CALIBRATION_PORT_NO_KEY_55 = \"calibrationPortNo\"; // NOI18N\n    private final String CPU_TASK_KEY_55 = \"cpuTaskDefault\"; // NOI18N\n    private final String LIVE_CPU_KEY_55 = \"displayLiveResultsCPU\"; // NOI18N\n    private final String LIVE_FRAGMENT_KEY_55 = \"displayLiveResultsFragment\"; // NOI18N\n    private final String LIVE_MEMORY_KEY_55 = \"displayLiveResultsMemory\"; // NOI18N\n    private final String MEMORY_TASK_ALLOCATIONS_KEY_55 = \"memoryTaskAllocationsDefault\"; // NOI18N\n    private final String PLATFORM_NAME_KEY_55 = \"javaPlatformForProfiling\"; // NOI18N\n    private final String PORT_NO_KEY_55 = \"portNo\"; // NOI18N\n    private final String RECORD_STACK_TRACES_KEY_55 = \"recordStackTracesDefault\"; // NOI18N\n    private final String THREADS_MONITORING_KEY_55 = \"threadsMonitoringDefault\"; // NOI18N\n    private final String TO_BEHAVIOR_KEY_55 = \"telemetryOverviewBehavior\"; // NOI18N\n    private final String TRACK_EVERY_KEY_55 = \"trackEveryDefault\"; // NOI18N\n    private final String TV_BEHAVIOR_KEY_55 = \"threadsViewBehavior\"; // NOI18N\n\n    // Keys for tracked properties\n    private final String AUTO_OPEN_SNAPSHOT_KEY = \"AUTO_OPEN_SNAPSHOT\"; // NOI18N\n    private final String AUTO_SAVE_SNAPSHOT_KEY = \"AUTO_SAVE_SNAPSHOT\"; // NOI18N\n    private final String CALIBRATION_PORT_NO_KEY = \"CALIBRATION_PORT_NO\"; // NOI18N\n    private final String CPU_TASK_KEY = \"CPU_TASK\"; // NOI18N\n    private final String CUSTOM_HEAPDUMP_PATH_KEY = \"CUSTOM_HEAPDUMP_PATH\"; // NOI18N\n    private final String DNSA_SETTINGS_KEY = \"DNSA_SETTINGS\"; // NOI18N\n    private final String HEAPWALKER_ANALYSIS_ENABLED_KEY = \"HEAPWALKER_ANALYSIS_ENABLED\"; // NOI18N\n    private final String INSTR_FILTER_KEY = \"INSTR_FILTER\"; // NOI18N\n    private final String LIVE_CPU_KEY = \"LIVE_CPU\"; // NOI18N\n    private final String LIVE_FRAGMENT_KEY = \"LIVE_FRAGMENT\"; // NOI18N\n    private final String LIVE_MEMORY_KEY = \"LIVE_MEMORY\"; // NOI18N\n    private final String MEMORY_TASK_ALLOCATIONS_KEY = \"MEMORY_TASK_ALLOCATIONS\"; // NOI18N\n    private final String OOME_DETECTION_MODE_KEY = \"OOME_DETECTION_MODE\"; // NOI18N\n    private final String PLATFORM_NAME_KEY = \"PLATFORM_NAME\"; // NOI18N\n    private final String PORT_NO_KEY = \"PORT_NO\"; // NOI18N\n    private final String PPOINTS_DEPENDENCIES_INCLUDE_KEY = \"PPOINTS_DEPENDENCIES_INCLUDE\"; // NOI18N\n    private final String RECORD_STACK_TRACES_KEY = \"RECORD_STACK_TRACES\"; // NOI18N\n    private final String THREADS_MONITORING_KEY = \"THREADS_MONITORING\"; // NOI18N\n    private final String TO_BEHAVIOR_KEY = \"TO_BEHAVIOR\"; // NOI18N\n    private final String TRACK_EVERY_KEY = \"TRACK_EVERY\"; // NOI18N\n    private final String TV_BEHAVIOR_KEY = \"TV_BEHAVIOR\"; // NOI18N\n    private final String LCV_BEHAVIOR_KEY = \"LCV_BEHAVIOR\"; // NOI18N\n    private final String NO_DATA_HINT_KEY = \"NO_DATA_HINT\"; // NOI18N\n    private final String SNAPSHOT_WINDOW_OPEN_POLICY_KEY = \"SNAPSHOT_WINDOW_OPEN_POLICY\"; // NOI18N\n    private final String SNAPSHOT_WINDOW_CLOSE_POLICY_KEY = \"SNAPSHOT_WINDOW_CLOSE_POLICY\"; // NOI18N\n    private final String ENABLE_EXPERT_SETTINGS_KEY = \"ENABLE_EXPERT_SETTINGS\"; // NOI18N\n    private final String LOG_PROFILER_STATUS_KEY = \"LOG_PROFILER_STATUS\"; // NOI18N\n    private final String REOPEN_SNAPSHOTS_KEY = \"REOPEN_SNAPSHOTS_KEY\"; // NOI18N\n    private final String REOPEN_HDUMPS_KEY = \"REOPEN_HDUMPS_KEY\"; // NOI18N\n    private final String SOURCES_COLORING_KEY = \"SOURCES_COLORING_KEY\"; // NOI18N\n    \n    // Defaults for tracked properties\n    private final String CUSTOM_HEAPDUMP_PATH_DEFAULT = \"\"; // NOI18N\n    private final String PLATFORM_NAME_DEFAULT = \"PLATFORM_NAME_DEFAULT\"; // NOI18N // replaces original null, means platform defined by project\n    private final String INSTR_FILTER_DEFAULT = \"###\"; // NOI18N // Shouldn't be matched, this is intention (logic for default is in CPUPerformanceConfigPanelLarge)\n    private final boolean AUTO_OPEN_SNAPSHOT_DEFAULT = true;\n    private final boolean AUTO_SAVE_SNAPSHOT_DEFAULT = false;\n    private final boolean HEAPWALKER_ANALYSIS_ENABLED_DEFAULT = false;\n    private final boolean LIVE_CPU_DEFAULT = false;\n    private final boolean LIVE_FRAGMENT_DEFAULT = false;\n    private final boolean LIVE_MEMORY_DEFAULT = false;\n    private final boolean MEMORY_TASK_ALLOCATIONS_DEFAULT = true;\n    private final boolean PPOINTS_DEPENDENCIES_INCLUDE_DEFAULT = true;\n    private final boolean RECORD_STACK_TRACES_DEFAULT = false;\n    private final boolean THREADS_MONITORING_DEFAULT = true;\n    private final int CALIBRATION_PORT_NO_DEFAULT = -1;\n    private final int CPU_TASK_DEFAULT = CPU_ENTIRE_APP;\n    private final int OOME_DETECTION_MODE_DEFAULT = OOME_DETECTION_PROJECTDIR;\n    private final int PORT_NO_DEFAULT = 5140;\n    private final int TO_BEHAVIOR_DEFAULT = OPEN_MONITORING;\n    private final int TRACK_EVERY_DEFAULT = 10;\n    private final int TV_BEHAVIOR_DEFAULT = OPEN_ALWAYS;\n    private final int LCV_BEHAVIOR_DEFAULT = OPEN_ALWAYS;\n    private final boolean NO_DATA_HINT_DEFAULT = true;\n    private final int SNAPSHOT_WINDOW_OPEN_DEFAULT = SNAPSHOT_WINDOW_OPEN_FIRST;\n    private final int SNAPSHOT_WINDOW_CLOSE_DEFAULT = SNAPSHOT_WINDOW_CLOSE_NEVER;\n    private final boolean ENABLE_EXPERT_SETTINGS_DEFAULT = false;\n    private final boolean LOG_PROFILER_STATUS_DEFAULT = false;\n    private final boolean REOPEN_SNAPSHOTS_DEFAULT = false;\n    private final boolean REOPEN_HDUMPS_DEFAULT = false;\n    private final boolean SOURCES_COLORING_DEFAULT = false;\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static ProfilerIDESettings getInstance() {\n        return defaultInstance;\n    }\n    \n    private ProfilerIDESettings() {}\n    \n    \n    // ProfilingSettings -------------------------------------------------------------------------------------------------\n    \n    private ProfilingSettings pSettings;\n    \n    public ProfilingSettings getDefaultProfilingSettings() {\n        if (pSettings == null) pSettings = loadProfilingSettings();\n        return pSettings;\n    }\n    \n    public void saveDefaultProfilingSettings() {\n        if (pSettings != null) storeProfilingSettings(pSettings);\n    }\n    \n    public ProfilingSettings createDefaultProfilingSettings() {\n        ProfilingSettings defaultSettings = new ProfilingSettings();\n        getDefaultProfilingSettings().copySettingsInto(defaultSettings);\n        return defaultSettings;\n    }\n    \n    private ProfilingSettings loadProfilingSettings() {\n        Preferences pref = getPreferences();\n        ProfilingSettings settings = new ProfilingSettings();\n        \n        settings.setSamplingFrequency(pref.getInt(ProfilingSettings.PROP_SAMPLING_FREQUENCY, 10));\n        settings.setCPUProfilingType(pref.getInt(ProfilingSettings.PROP_CPU_PROFILING_TYPE, CommonConstants.CPU_INSTR_FULL));\n        settings.setSamplingInterval(pref.getInt(ProfilingSettings.PROP_SAMPLING_INTERVAL, -10));\n        settings.setExcludeWaitTime(pref.getBoolean(ProfilingSettings.PROP_EXCLUDE_WAIT_TIME, true));\n        settings.setInstrumentSpawnedThreads(pref.getBoolean(ProfilingSettings.PROP_INSTRUMENT_SPAWNED_THREADS, false));\n        settings.setNProfiledThreadsLimit(pref.getInt(ProfilingSettings.PROP_N_PROFILED_THREADS_LIMIT, 128));\n        settings.setMaxStringLength(pref.getInt(ProfilingSettings.PROP_MAX_STRING_LENGTH, CommonConstants.MAX_STRING_LENGTH_DEFAULT));\n        settings.setInstrScheme(pref.getInt(ProfilingSettings.PROP_INSTR_SCHEME, CommonConstants.INSTRSCHEME_LAZY));\n        settings.setInstrumentMethodInvoke(pref.getBoolean(ProfilingSettings.PROP_INSTRUMENT_METHOD_INVOKE, true));\n        settings.setInstrumentGetterSetterMethods(pref.getBoolean(ProfilingSettings.PROP_INSTRUMENT_GETTER_SETTER_METHODS, false));\n        settings.setInstrumentEmptyMethods(pref.getBoolean(ProfilingSettings.PROP_INSTRUMENT_EMPTY_METHODS, false));\n        \n        settings.setAllocTrackEvery(pref.getInt(ProfilingSettings.PROP_OBJ_ALLOC_STACK_SAMPLING_INTERVAL, 1));\n        settings.setRunGCOnGetResultsInMemoryProfiling(pref.getBoolean(ProfilingSettings.PROP_RUN_GC_ON_GET_RESULTS_IN_MEMORY_PROFILING, false));\n        \n        settings.setThreadsSamplingEnabled(pref.getBoolean(ProfilingSettings.PROP_THREADS_SAMPLING_ENABLED, false));\n        \n        return settings;\n    }\n    \n    private void storeProfilingSettings(ProfilingSettings settings) {\n        Preferences pref = getPreferences();\n        \n        pref.putInt(ProfilingSettings.PROP_SAMPLING_FREQUENCY, settings.getSamplingFrequency());\n        pref.putInt(ProfilingSettings.PROP_CPU_PROFILING_TYPE, settings.getCPUProfilingType());\n        pref.putInt(ProfilingSettings.PROP_SAMPLING_INTERVAL, settings.getSamplingInterval());\n        pref.putBoolean(ProfilingSettings.PROP_EXCLUDE_WAIT_TIME, settings.getExcludeWaitTime());\n        pref.putBoolean(ProfilingSettings.PROP_INSTRUMENT_SPAWNED_THREADS, settings.getInstrumentSpawnedThreads());\n        pref.putInt(ProfilingSettings.PROP_N_PROFILED_THREADS_LIMIT, settings.getNProfiledThreadsLimit());\n        pref.putInt(ProfilingSettings.PROP_MAX_STRING_LENGTH, settings.getMaxStringLength());\n        pref.putInt(ProfilingSettings.PROP_INSTR_SCHEME, settings.getInstrScheme());\n        pref.putBoolean(ProfilingSettings.PROP_INSTRUMENT_METHOD_INVOKE, settings.getInstrumentMethodInvoke());\n        pref.putBoolean(ProfilingSettings.PROP_INSTRUMENT_GETTER_SETTER_METHODS, settings.getInstrumentGetterSetterMethods());\n        pref.putBoolean(ProfilingSettings.PROP_INSTRUMENT_EMPTY_METHODS, settings.getInstrumentEmptyMethods());\n        \n        pref.putInt(ProfilingSettings.PROP_OBJ_ALLOC_STACK_SAMPLING_INTERVAL, settings.getAllocTrackEvery());\n        pref.putBoolean(ProfilingSettings.PROP_RUN_GC_ON_GET_RESULTS_IN_MEMORY_PROFILING, settings.getRunGCOnGetResultsInMemoryProfiling());\n        \n        pref.putBoolean(ProfilingSettings.PROP_THREADS_SAMPLING_ENABLED, settings.getThreadsSamplingEnabled());\n    }\n    \n    // Properties --------------------------------------------------------------------------------------------------------\n    \n    /** Determines whether snapshots are automatically opened.\n     * @param value true if snapshot should be automatically opened after taking it, false otherwise\n     */\n    public void setAutoOpenSnapshot(final boolean value) {\n        getPreferences().putBoolean(AUTO_OPEN_SNAPSHOT_KEY, value);\n    }\n\n    /** Determines whether snapshots are automatically opened.\n     * @return true if snapshot should be automatically opened after taking it, false otherwise\n     */\n    public boolean getAutoOpenSnapshot() {\n        return getPreferences().getBoolean(AUTO_OPEN_SNAPSHOT_KEY, AUTO_OPEN_SNAPSHOT_DEFAULT);\n    }\n\n    /** Determines whether snapshots are automatically saved.\n     * @param value true if snapshot should be automatically saved after taking it, false otherwise\n     */\n    public void setAutoSaveSnapshot(final boolean value) {\n        getPreferences().putBoolean(AUTO_SAVE_SNAPSHOT_KEY, value);\n    }\n\n    /** Determines whether snapshots are automatically saved.\n     *\n     * @return true if snapshot should be automatically saved after taking it, false otherwise\n     */\n    public boolean getAutoSaveSnapshot() {\n        return getPreferences().getBoolean(AUTO_SAVE_SNAPSHOT_KEY, AUTO_SAVE_SNAPSHOT_DEFAULT);\n    }\n\n    public void setCalibrationPortNo(final int value) {\n        getPreferences().putInt(CALIBRATION_PORT_NO_KEY, value);\n    }\n\n    public int getCalibrationPortNo() {\n        int calibrationPort = getPreferences().getInt(CALIBRATION_PORT_NO_KEY, CALIBRATION_PORT_NO_DEFAULT);\n\n        if (calibrationPort == -1) {\n            return getPortNo() + 1;\n        } else {\n            return calibrationPort;\n        }\n    }\n\n    public void setCpuTaskDefault(int value) {\n        getPreferences().putInt(CPU_TASK_KEY, value);\n    }\n\n    public int getCpuTaskDefault() {\n        return getPreferences().getInt(CPU_TASK_KEY, CPU_TASK_DEFAULT);\n    }\n\n    /**\n     * The custom path to a heapdump generated by -XX:+HeapDumpOnOutOfMemoryError option\n     */\n    public void setCustomHeapdumpPath(String heapDumpCustomDir) {\n        getPreferences().put(CUSTOM_HEAPDUMP_PATH_KEY, heapDumpCustomDir);\n    }\n\n    /**\n     * The custom path to a heapdump generated by -XX:+HeapDumpOnOutOfMemoryError option\n     */\n    public String getCustomHeapdumpPath() {\n        return getPreferences().get(CUSTOM_HEAPDUMP_PATH_KEY, CUSTOM_HEAPDUMP_PATH_DEFAULT);\n    }\n\n    public void setDisplayLiveResultsCPU(final boolean value) {\n        getPreferences().putBoolean(LIVE_CPU_KEY, value);\n    }\n\n    public boolean getDisplayLiveResultsCPU() {\n        return getPreferences().getBoolean(LIVE_CPU_KEY, LIVE_CPU_DEFAULT);\n    }\n\n    public void setDisplayLiveResultsFragment(final boolean value) {\n        getPreferences().putBoolean(LIVE_FRAGMENT_KEY, value);\n    }\n\n    public boolean getDisplayLiveResultsFragment() {\n        return getPreferences().getBoolean(LIVE_FRAGMENT_KEY, LIVE_FRAGMENT_DEFAULT);\n    }\n\n    public void setDisplayLiveResultsMemory(final boolean value) {\n        getPreferences().putBoolean(LIVE_MEMORY_KEY, value);\n    }\n\n    public boolean getDisplayLiveResultsMemory() {\n        return getPreferences().getBoolean(LIVE_MEMORY_KEY, LIVE_MEMORY_DEFAULT);\n    }\n    \n    public void setShowNoDataHint(boolean value) {\n        getPreferences().putBoolean(NO_DATA_HINT_KEY, value);\n    }\n    \n    public boolean getShowNoDataHint() {\n        return getPreferences().getBoolean(NO_DATA_HINT_KEY, NO_DATA_HINT_DEFAULT);\n    }\n    \n    public void setSnapshotWindowOpenPolicy(int policy) {\n        getPreferences().putInt(SNAPSHOT_WINDOW_OPEN_POLICY_KEY, policy);\n    }\n    \n    public int getSnapshotWindowOpenPolicy() {\n        return getPreferences().getInt(SNAPSHOT_WINDOW_OPEN_POLICY_KEY, SNAPSHOT_WINDOW_OPEN_DEFAULT);\n    }\n    \n    public void setSnapshotWindowClosePolicy(int policy) {\n        getPreferences().putInt(SNAPSHOT_WINDOW_CLOSE_POLICY_KEY, policy);\n    }\n    \n    public int getSnapshotWindowClosePolicy() {\n        return getPreferences().getInt(SNAPSHOT_WINDOW_CLOSE_POLICY_KEY, SNAPSHOT_WINDOW_CLOSE_DEFAULT);\n    }\n    \n    public void setEnableExpertSettings(boolean value) {\n        getPreferences().putBoolean(ENABLE_EXPERT_SETTINGS_KEY, true);\n//        getPreferences().putBoolean(ENABLE_EXPERT_SETTINGS_KEY, value);\n    }\n    \n    public boolean getEnableExpertSettings() {\n        return true;\n//        return getPreferences().getBoolean(ENABLE_EXPERT_SETTINGS_KEY, ENABLE_EXPERT_SETTINGS_DEFAULT);\n    }\n    \n    public void setLogProfilerStatus(boolean value) {\n        getPreferences().putBoolean(LOG_PROFILER_STATUS_KEY, value);\n    }\n    \n    public boolean getLogProfilerStatus() {\n        return getPreferences().getBoolean(LOG_PROFILER_STATUS_KEY, LOG_PROFILER_STATUS_DEFAULT);\n    }\n    \n    public void setReopenSnapshots(boolean value) {\n        getPreferences().putBoolean(REOPEN_SNAPSHOTS_KEY, value);\n    }\n    \n    public boolean getReopenSnapshots() {\n        return getPreferences().getBoolean(REOPEN_SNAPSHOTS_KEY, REOPEN_SNAPSHOTS_DEFAULT);\n    }\n    \n    public void setReopenHeapDumps(boolean value) {\n        getPreferences().putBoolean(REOPEN_HDUMPS_KEY, value);\n    }\n    \n    public boolean getReopenHeapDumps() {\n        return getPreferences().getBoolean(REOPEN_HDUMPS_KEY, REOPEN_HDUMPS_DEFAULT);\n    }\n    \n    private Boolean sourcesColoringEnabled; // needs to be as fast as possible for rendering tables\n    public void setSourcesColoringEnabled(boolean value) {\n        getPreferences().putBoolean(SOURCES_COLORING_KEY, value);\n        sourcesColoringEnabled = value;\n    }\n    \n    public boolean isSourcesColoringEnabled() {\n        if (sourcesColoringEnabled == null) sourcesColoringEnabled =\n                getPreferences().getBoolean(SOURCES_COLORING_KEY, SOURCES_COLORING_DEFAULT);\n        return sourcesColoringEnabled;\n    }\n\n    /**\n     * Used by the DNSAConfirmation.\n     *\n     * Allows to set or clear persistent do not show again value associated with given notification identified by the\n     * provided key.\n     *\n     * @param key A key that uniquely identifies the notification\n     * @param value The value that should be used without displaying the notification or null to cleat the Do not show\n     *              again (i.e. start displaying the notifications again.\n     *\n     * @see org.graalvm.visualvm.lib.profiler.impl.ProfilerDialogs.DNSAConfirmation\n     * @see org.graalvm.visualvm.lib.profiler.impl.ProfilerDialogs.DNSAMessage\n     */\n    public void setDoNotShowAgain(final String key, final String value) {\n        if (value != null) {\n            getDNSAMap().put(key, value);\n        } else {\n            getDNSAMap().remove(key);\n        }\n\n        storeDNSAMap();\n    }\n\n    /**\n     * Used by the DNSAConfirmation.\n     *\n     * Allows to get persistent do not show again value associated with given notification identified by the provided key.\n     *\n     * @param  key A key that uniquely identifies the notification\n     * @return The value that should be used without displaying the notification or null if the notification should\n     *         be displayed\n     *\n     * @see org.graalvm.visualvm.lib.profiler.impl.ProfilerDialogs.DNSAConfirmation\n     * @see org.graalvm.visualvm.lib.profiler.impl.ProfilerDialogs.DNSAMessage\n     */\n    public String getDoNotShowAgain(final String key) {\n        return getDNSAMap().get(key);\n    }\n\n    public void setHeapWalkerAnalysisEnabled(boolean value) {\n        getPreferences().putBoolean(HEAPWALKER_ANALYSIS_ENABLED_KEY, value);\n    }\n\n    public boolean getHeapWalkerAnalysisEnabled() {\n        return getPreferences().getBoolean(HEAPWALKER_ANALYSIS_ENABLED_KEY, HEAPWALKER_ANALYSIS_ENABLED_DEFAULT);\n    }\n\n    public void setIncludeProfilingPointsDependencies(boolean value) {\n        getPreferences().putBoolean(PPOINTS_DEPENDENCIES_INCLUDE_KEY, value);\n    }\n\n    public boolean getIncludeProfilingPointsDependencies() {\n        return getPreferences().getBoolean(PPOINTS_DEPENDENCIES_INCLUDE_KEY, PPOINTS_DEPENDENCIES_INCLUDE_DEFAULT);\n    }\n\n    public void setInstrFilterDefault(String value) {\n        getPreferences().put(INSTR_FILTER_KEY, value);\n    }\n\n    public String getInstrFilterDefault() {\n        return getPreferences().get(INSTR_FILTER_KEY, INSTR_FILTER_DEFAULT);\n    }\n\n    /**\n     * @param value Name of Java platform to use for profiling. Null value indicates no global platform is selected\n     */\n    public void setJavaPlatformForProfiling(String value) {\n        getPreferences().put(PLATFORM_NAME_KEY, (value == null) ? PLATFORM_NAME_DEFAULT : value);\n    }\n\n    /** @return Name of Java platform to use for profiling. Null value indicates no global platform is selected */\n    public String getJavaPlatformForProfiling() {\n        String platformName = getPreferences().get(PLATFORM_NAME_KEY, PLATFORM_NAME_DEFAULT);\n\n        return PLATFORM_NAME_DEFAULT.equals(platformName) ? null : platformName;\n    }\n\n    public void setMemoryTaskAllocationsDefault(boolean value) {\n        getPreferences().putBoolean(MEMORY_TASK_ALLOCATIONS_KEY, value);\n    }\n\n    public boolean getMemoryTaskAllocationsDefault() {\n        return getPreferences().getBoolean(MEMORY_TASK_ALLOCATIONS_KEY, MEMORY_TASK_ALLOCATIONS_DEFAULT);\n    }\n\n    /**\n     * The flag specifying whether all profiled applications should be started with -XX:+HeapDumpOnOutOfMemoryError option\n     */\n    public boolean isOOMDetectionEnabled() {\n        return getOOMDetectionMode() != OOME_DETECTION_NONE;\n    }\n\n    /**\n     * The flag specifying whether all profiled applications should be started with -XX:+HeapDumpOnOutOfMemoryError option\n     */\n    public void setOOMDetectionMode(int oomeDetectionMode) {\n        getPreferences().putInt(OOME_DETECTION_MODE_KEY, oomeDetectionMode);\n    }\n\n    /**\n     * The flag specifying whether all profiled applications should be started with -XX:+HeapDumpOnOutOfMemoryError option\n     */\n    public int getOOMDetectionMode() {\n        return getPreferences().getInt(OOME_DETECTION_MODE_KEY, OOME_DETECTION_MODE_DEFAULT);\n    }\n\n    public void setPortNo(final int value) {\n        getPreferences().putInt(PORT_NO_KEY, value);\n    }\n\n    public int getPortNo() {\n        return getPreferences().getInt(PORT_NO_KEY, PORT_NO_DEFAULT);\n    }\n\n    public void setRecordStackTracesDefault(boolean value) {\n        getPreferences().putBoolean(RECORD_STACK_TRACES_KEY, value);\n    }\n\n    public boolean getRecordStackTracesDefault() {\n        return getPreferences().getBoolean(RECORD_STACK_TRACES_KEY, RECORD_STACK_TRACES_DEFAULT);\n    }\n\n    public void setTelemetryOverviewBehavior(final int value) {\n        getPreferences().putInt(TO_BEHAVIOR_KEY, value);\n    }\n\n    public int getTelemetryOverviewBehavior() {\n        return getPreferences().getInt(TO_BEHAVIOR_KEY, TO_BEHAVIOR_DEFAULT);\n    }\n\n    public void setThreadsMonitoringDefault(boolean value) {\n        getPreferences().putBoolean(THREADS_MONITORING_KEY, value);\n    }\n\n    // SelectTaskPanel\n    public boolean getThreadsMonitoringDefault() {\n        return getPreferences().getBoolean(THREADS_MONITORING_KEY, THREADS_MONITORING_DEFAULT);\n    }\n\n    public void setThreadsViewBehavior(final int value) {\n        getPreferences().putInt(TV_BEHAVIOR_KEY, value);\n    }\n\n    public int getThreadsViewBehavior() {\n        return getPreferences().getInt(TV_BEHAVIOR_KEY, TV_BEHAVIOR_DEFAULT);\n    }\n    \n    public void setLockContentionViewBehavior(final int value) {\n        getPreferences().putInt(LCV_BEHAVIOR_KEY, value);\n    }\n\n    public int getLockContentionViewBehavior() {\n        return getPreferences().getInt(LCV_BEHAVIOR_KEY, LCV_BEHAVIOR_DEFAULT);\n    }\n\n    public void setTrackEveryDefault(int value) {\n        getPreferences().putInt(TRACK_EVERY_KEY, value);\n    }\n\n    public int getTrackEveryDefault() {\n        return getPreferences().getInt(TRACK_EVERY_KEY, TRACK_EVERY_DEFAULT);\n    }\n\n    /**\n     * Used by the DNSAConfirmation.\n     *\n     * Clears the Do not show again, so that all confirmations are displayed again.\n     *\n     * @see org.graalvm.visualvm.lib.profiler.impl.ProfilerDialogs.DNSAConfirmation\n     * @see org.graalvm.visualvm.lib.profiler.impl.ProfilerDialogs.DNSAMessage\n     */\n    public void clearDoNotShowAgainMap() {\n        getDNSAMap().clear();\n        storeDNSAMap();\n    }\n\n    // -------------------------\n    @NbBundle.Messages({\n        \"ProfilerIDESettings_Name=Profiler Settings\"\n    })\n    public String displayName() {\n        return Bundle.ProfilerIDESettings_Name();\n    }\n\n    private Map<String, String> getDNSAMap() {\n        if (dnsaMap != null) {\n            return dnsaMap;\n        }\n\n        dnsaMap = new HashMap();\n\n        String allPairs = getPreferences().get(DNSA_SETTINGS_KEY, null);\n\n        if (allPairs != null) {\n            String[] pairs = allPairs.split(\":\"); //NOI18N\n            for (String pair : pairs) {\n                String[] elems = pair.split(\",\"); //NOI18N\n                assert elems.length == 2;\n                dnsaMap.put(elems[0], elems[1]);\n            }\n        }\n\n        return dnsaMap;\n    }\n\n    // --- Private stuff ---------------------------------------------------------\n    private Preferences getPreferences() {\n        return NbPreferences.forModule(ProfilerIDESettings.class);\n    }\n\n    private void storeDNSAMap() {\n        StringBuilder sb = new StringBuilder();\n\n        for (Iterator it = getDNSAMap().entrySet().iterator(); it.hasNext();) {\n            Map.Entry e = (Map.Entry) it.next();\n            sb.append(e.getKey()).append(\",\").append(e.getValue()); //NOI18N\n\n            if (it.hasNext()) {\n                sb.append(\":\"); //NOI18N\n            }\n        }\n\n        String toStore = sb.toString();\n\n        if (toStore.isEmpty()) {\n            getPreferences().remove(DNSA_SETTINGS_KEY);\n        } else {\n            getPreferences().put(DNSA_SETTINGS_KEY, toStore);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/ProfilerProject.java",
    "content": "/*\n * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api;\n\nimport org.openide.util.Lookup;\nimport org.openide.util.lookup.Lookups;\nimport org.openide.util.lookup.ProxyLookup;\n\n/**\n * IDE agnostic project definition wrapper.<br>\n * Basically, a simple {@linkplain Lookup.Provider} which contains, as a part \n * of its lookup, the real project implementation.\n *\n * @author Jaroslav Bachorik\n */\nabstract public class ProfilerProject implements Lookup.Provider {\n    final private Object lkpLock = new Object();\n    // @GuardedBy lkpLock\n    private Lookup lkp;\n    private Lookup.Provider provider;\n\n    protected ProfilerProject(Lookup.Provider project) {\n        this.provider = project;\n    }\n\n    @Override\n    public Lookup getLookup() {\n        synchronized(lkpLock) {\n            if (lkp == null) {\n                lkp = new ProxyLookup(provider.getLookup(), Lookups.fixed(provider, this), additionalLookup());\n            }\n            return lkp;\n        }\n    }\n\n    abstract protected Lookup additionalLookup();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/ProfilerSource.java",
    "content": "/*\n * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api;\n\nimport org.netbeans.api.editor.mimelookup.MimeLookup;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\n\n/**\n * IDE agnostic source file wrapper<br>\n * A simple {@linkplain Lookup.Provider} derived from the appropriate {@linkplain MimeLookup} registrations.\n * @author Jaroslav Bachorik\n */\nabstract public class ProfilerSource implements Lookup.Provider {\n    private FileObject file;\n\n    protected ProfilerSource(FileObject file) {\n        this.file = file;\n    }\n\n    /**\n     * The wrapped file\n     * @return Returns the {@linkplain FileObject} representing a particular {@linkplain ProfilerSource}\n     */\n    final public FileObject getFile() {\n        return file;\n    }\n\n    @Override\n    final public Lookup getLookup() {\n        return MimeLookup.getLookup(file.getMIMEType());\n    }\n\n    /**\n     * Indicates whether a source can be run by the IDE or not\n     * @return Returns <b>TRUE</b> if the source can be run by the IDE (eg. main class, test etc.), <b>FALSE</b> otherwise\n     */\n    abstract public boolean isRunnable();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/ProfilerStorage.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api;\n\nimport java.io.IOException;\nimport java.util.Properties;\nimport org.graalvm.visualvm.lib.profiler.spi.ProfilerStorageProvider;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ProfilerStorage {\n\n    // --- Global storage ------------------------------------------------------\n\n    /**\n     * Returns FileObject which can be used as a general settings storage.\n     * @param create If <code>true</code> the folder will be created if it doesn't exist yet\n     * @return FileObject which can be used as a general settings storage\n     * @throws IOException\n     */\n    public static FileObject getGlobalFolder(boolean create) throws IOException {\n        ProfilerStorageProvider p = provider();\n        if (p != null) return p.getGlobalFolder(create);\n        else return null;\n    }\n\n    /**\n     * Loads the provided Properties from a global storage directory.\n     * @param properties Properties instance to load\n     * @param filename name of the file containing the persisted properties\n     * @throws IOException\n     */\n    public static void loadGlobalProperties(Properties properties, String filename) throws IOException {\n        ProfilerStorageProvider p = provider();\n        if (p != null) p.loadGlobalProperties(properties, filename);\n    }\n\n    /**\n     * Saves the provided Properties to a global storage directory.\n     * @param properties Properties instance to save\n     * @param filename name of the file containing the persisted properties\n     * @throws IOException\n     */\n    public static void saveGlobalProperties(Properties properties, String filename) throws IOException {\n        ProfilerStorageProvider p = provider();\n        if (p != null) p.saveGlobalProperties(properties, filename);\n    }\n    \n    public static void deleteGlobalProperties(String filename) throws IOException {\n        ProfilerStorageProvider p = provider();\n        if (p != null) p.deleteGlobalProperties(filename);\n    }\n    \n    // --- Project storage -----------------------------------------------------\n    \n    /**\n     * Returns FileObject which can be used as a settings storage for the provided project, or global storage for null project.\n     * \n     * @param project project context\n     * @param create if <code>true</code> the storage will be created if not already available\n     * @return FileObject which can be used as a settings storage for the provided project or null if not available\n     * @throws IOException \n     */\n    public static FileObject getProjectFolder(Lookup.Provider project, boolean create)\n            throws IOException {\n        if (project == null) return getGlobalFolder(create);\n        ProfilerStorageProvider p = provider();\n        if (p != null) return p.getProjectFolder(project, create);\n        else return null;\n    }\n    \n    /**\n     * Returns project context for the provided settings storage FileObject or null if not resolvable.\n     * \n     * @param settingsFolder settings storage\n     * @return  project context for the provided settings storage FileObject or null if not resolvable\n     */\n    public static Lookup.Provider getProjectFromFolder(FileObject settingsFolder) {\n        ProfilerStorageProvider p = provider();\n        if (p != null) return p.getProjectFromFolder(settingsFolder);\n        else return null;\n    }\n    \n    /**\n     * Loads the provided Properties from the project (or global for null project) storage directory.\n     * @param properties Properties instance to load\n     * @param project project context\n     * @param filename name of the file containing the persisted properties\n     * @throws IOException \n     */\n    public static void loadProjectProperties(Properties properties, Lookup.Provider project, String filename) throws IOException {\n        if (project == null) {\n            loadGlobalProperties(properties, filename);\n        } else {\n            ProfilerStorageProvider p = provider();\n            if (p != null) p.loadProjectProperties(properties, project, filename);\n        }\n    }\n    \n    /**\n     * Saves the provided Properties to the project (or global for null project) storage directory.\n     * @param properties Properties instance to save\n     * @param project project context\n     * @param filename name of the file containing the persisted properties\n     * @throws IOException \n     */\n    public static void saveProjectProperties(Properties properties, Lookup.Provider project, String filename) throws IOException {\n        if (project == null) {\n            saveGlobalProperties(properties, filename);\n        } else {\n            ProfilerStorageProvider p = provider();\n            if (p != null) p.saveProjectProperties(properties, project, filename);\n        }\n    }\n    \n    public static void deleteProjectProperties(Lookup.Provider project, String filename) throws IOException {\n        if (project == null) {\n            deleteGlobalProperties(filename);\n        } else {\n            ProfilerStorageProvider p = provider();\n            if (p != null) p.deleteProjectProperties(project, filename);\n        }\n    }\n    \n    // --- Implementation ------------------------------------------------------\n    \n    private static ProfilerStorageProvider provider() {\n        return Lookup.getDefault().lookup(ProfilerStorageProvider.class);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/ProgressDisplayer.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.api;\n\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.util.Cancellable;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface ProgressDisplayer {\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    public static interface ProgressController extends Cancellable {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void close();\n\n    public ProgressDisplayer showProgress(String message);\n\n    public ProgressDisplayer showProgress(String message, ProgressController controller);\n\n    public ProgressDisplayer showProgress(String caption, String message, ProgressController controller);\n\n    public static final ProgressDisplayer DEFAULT = new ProgressDisplayer() {\n        ProgressHandle ph = null;\n\n        public synchronized ProgressDisplayer showProgress(String message) {\n            ph = ProgressHandle.createHandle(message);\n            ph.start();\n            return DEFAULT;\n        }\n\n        public synchronized ProgressDisplayer showProgress(String message, ProgressController controller) {\n            ph = ProgressHandle.createHandle(message, controller);\n            ph.start();\n            return DEFAULT;\n        }\n\n        public synchronized ProgressDisplayer showProgress(String caption, String message, ProgressController controller) {\n            ph = ProgressHandle.createHandle(message, controller);\n            ph.start();\n            return DEFAULT;\n        }\n\n        public synchronized void close() {\n            if (ph != null) {\n                ph.finish();\n                ph = null;\n            }\n        }\n    };\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/ProjectUtilities.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api;\n\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.Icon;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.profiler.spi.ProjectUtilitiesProvider;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\nimport org.openide.util.Lookup.Provider;\n\n/**\n * ProjectUtilities provides profiler with necessary functionality work accessing\n * project oriented data.\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic final class ProjectUtilities {\n\n    /**Retrieves the current main project set in the IDE.\n     *\n     * @return the current main project or null if none\n     */\n    public static Provider getMainProject() {\n        return provider().getMainProject();\n    }\n\n    /**\n     * Gets a list of currently open projects.\n     *\n     * @return list of projects currently opened in the IDE's GUI; order not specified\n     */\n    public static Provider[] getOpenedProjects() {\n        return provider().getOpenedProjects();\n    }\n\n    /**\n     * Get a human-readable display name for the project.\n     * May contain spaces, international characters, etc.\n     * @param project project\n     * @return a display name for the project\n     */\n    public static String getDisplayName(Lookup.Provider project) {\n        return provider().getDisplayName(project);\n    }\n\n    /**\n     * Gets an associated directory where the project metadata and possibly sources live.\n     * In the case of a typical Ant project, this is the top directory, not the\n     * project metadata subdirectory.\n     * @return a directory\n     */\n    public static FileObject getProjectDirectory(Lookup.Provider project) {\n        return provider().getProjectDirectory(project);\n    }\n\n    /**\n     * Gets icon for given project.\n     * Usually determined by the project type.\n     * @param project project\n     * @return icon of the project.\n     */\n    public static Icon getIcon(Provider project) {\n        return provider().getIcon(project);\n    }\n    \n    /**\n     * Returns true if the provided project has sub-projects.\n     * \n     * @param project a project\n     * @return true if the provided project has sub-projects, false otherwise\n     */\n    public static boolean hasSubprojects(Provider project) {\n        return provider().hasSubprojects(project);\n    }\n\n    /**\n     * Computes set of sub-projects of a project\n     * @param project a project\n     * @param subprojects map of sub-projects\n     */\n    public static void fetchSubprojects(Provider project, Set<Provider> subprojects) {\n        provider().fetchSubprojects(project, subprojects);\n    }\n    \n    /**\n     * Find the project, if any, which \"owns\" the given file.\n     * @param fobj the file (generally on disk)\n     * @return a project which contains it, or null if there is no known project containing it\n     */\n    public static Provider getProject(FileObject fobj) {\n        return provider().getProject(fobj);\n    }\n    /**\n     * Adds a listener to be notified when set of open projects changes.\n     * @param listener listener to be added\n     */\n    public static void addOpenProjectsListener(ChangeListener listener) {\n        provider().addOpenProjectsListener(listener);\n    }\n    \n    /**\n     * Removes a listener to be notified when set of open projects changes.\n     * @param listener listener to be removed\n     */\n    public static void removeOpenProjectsListener(ChangeListener listener) {\n        provider().removeOpenProjectsListener(listener);\n    }\n\n    /**\n     * Sorts projects by display name\n     * @param projects\n     * @return arrays of projects sorted by display name\n     */\n    public static Provider[] getSortedProjects(Provider[] projects) {\n        List<Provider> projectsArray = Arrays.asList(projects);\n\n        Collections.sort(projectsArray,\n                new Comparator() {\n\n                    @Override\n                    public int compare(Object o1, Object o2) {\n                        Provider p1 = (Provider) o1;\n                        Provider p2 = (Provider) o2;\n\n                        return getDisplayName(p1).toLowerCase().compareTo(getDisplayName(p2).toLowerCase());\n                    }\n                });\n        projectsArray.toArray(projects);\n\n        return projects;\n    }\n    \n    private static ProjectUtilitiesProvider provider() {\n        return Lookup.getDefault().lookup(ProjectUtilitiesProvider.class);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/icons/GeneralIcons.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api.icons;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface GeneralIcons extends Icons.Keys {\n\n    public static final String FILTER = \"GeneralIcons.Filter\"; // NOI18N\n    public static final String FILTER_HIGHL = \"GeneralIcons.FilterHighl\"; // NOI18N\n    public static final String SET_FILTER = \"GeneralIcons.SetFilter\"; // NOI18N\n    public static final String SET_FILTER_HIGHL = \"GeneralIcons.SetFilterHighl\"; // NOI18N\n    public static final String CLEAR_FILTER = \"GeneralIcons.ClearFilter\"; // NOI18N\n    public static final String CLEAR_FILTER_HIGHL = \"GeneralIcons.ClearFilterHighl\"; // NOI18N\n    public static final String CLOSE_PANEL = \"GeneralIcons.ClosePanel\"; // NOI18N\n    public static final String FILTER_CONTAINS = \"GeneralIcons.FilterContains\"; // NOI18N\n    public static final String FILTER_NOT_CONTAINS = \"GeneralIcons.FilterNotContains\"; // NOI18N\n    public static final String FILTER_ENDS_WITH = \"GeneralIcons.FilterEndsWith\"; // NOI18N\n    public static final String FILTER_REG_EXP = \"GeneralIcons.FilterRegExp\"; // NOI18N\n    public static final String FILTER_STARTS_WITH = \"GeneralIcons.FilterStartsWith\"; // NOI18N\n    public static final String COLLAPSED_SNIPPET = \"GeneralIcons.CollapsedSnippet\"; // NOI18N\n    public static final String EXPANDED_SNIPPET = \"GeneralIcons.ExpandedSnippet\"; // NOI18N\n    public static final String HIDE_COLUMN = \"GeneralIcons.HideColumn\"; // NOI18N\n    public static final String MAXIMIZE_PANEL = \"GeneralIcons.MaximizePanel\"; // NOI18N\n    public static final String MINIMIZE_PANEL = \"GeneralIcons.MinimizePanel\"; // NOI18N\n    public static final String RESTORE_PANEL = \"GeneralIcons.RestorePanel\"; // NOI18N\n    public static final String SORT_ASCENDING = \"GeneralIcons.SortAscending\"; // NOI18N\n    public static final String SORT_DESCENDING = \"GeneralIcons.SortDescending\"; // NOI18N\n    public static final String POPUP_ARROW = \"GeneralIcons.PopupArrow\"; // NOI18N\n    public static final String ZOOM = \"GeneralIcons.Zoom\"; // NOI18N\n    public static final String ZOOM_IN = \"GeneralIcons.ZoomIn\"; // NOI18N\n    public static final String ZOOM_OUT = \"GeneralIcons.ZoomOut\"; // NOI18N\n    public static final String SCALE_TO_FIT = \"GeneralIcons.ScaleToFit\"; // NOI18N\n    public static final String INFO = \"GeneralIcons.Info\"; // NOI18N\n    public static final String FIND_NEXT = \"GeneralIcons.FindNext\"; // NOI18N\n    public static final String FIND_PREVIOUS = \"GeneralIcons.FindPrevious\"; // NOI18N\n    public static final String SAVE = \"GeneralIcons.Save\"; // NOI18N\n    public static final String SAVE_AS = \"GeneralIcons.SaveAs\"; // NOI18N\n    public static final String SAVE_VIEW = \"GeneralIcons.SaveView\"; // NOI18N\n    public static final String EXPORT = \"GeneralIcons.Export\"; // NOI18N\n    public static final String DETACH = \"GeneralIcons.Detach\"; // NOI18N\n    public static final String START = \"GeneralIcons.Start\"; // NOI18N\n    public static final String PAUSE = \"GeneralIcons.Pause\"; // NOI18N\n    public static final String RERUN = \"GeneralIcons.Rerun\"; // NOI18N\n    public static final String RESUME = \"GeneralIcons.Resume\"; // NOI18N\n    public static final String STOP = \"GeneralIcons.Stop\"; // NOI18N\n    public static final String EMPTY = \"GeneralIcons.Empty\"; // NOI18N\n    public static final String ERROR = \"GeneralIcons.Error\"; // NOI18N\n    public static final String FIND = \"GeneralIcons.Find\"; // NOI18N\n    public static final String SLAVE_DOWN = \"GeneralIcons.SlaveDown\"; // NOI18N\n    public static final String SLAVE_UP = \"GeneralIcons.SlaveUp\"; // NOI18N\n    public static final String UPDATE_AUTO = \"GeneralIcons.UpdateAuto\"; // NOI18N\n    public static final String PIE = \"GeneralIcons.Pie\"; // NOI18N\n    public static final String UPDATE_NOW = \"GeneralIcons.UpdateNow\"; // NOI18N\n    public static final String BUTTON_ATTACH = \"GeneralIcons.ButtonAttach\"; // NOI18N\n    public static final String BUTTON_RUN = \"GeneralIcons.ButtonRun\"; // NOI18N\n    public static final String UP = \"GeneralIcons.Up\"; // NOI18N\n    public static final String DOWN = \"GeneralIcons.Down\"; // NOI18N\n    public static final String FORWARD = \"GeneralIcons.Forward\"; // NOI18N\n    public static final String BACK = \"GeneralIcons.Back\"; // NOI18N\n    public static final String SETTINGS = \"GeneralIcons.Settings\"; // NOI18N\n    public static final String JAVA_PROCESS = \"GeneralIcons.JavaProcess\"; // NOI18N\n    public static final String FOLDER = \"GeneralIcons.Folder\"; // NOI18N\n    public static final String BADGE_ADD = \"GeneralIcons.BadgeAdd\"; // NOI18N\n    public static final String BADGE_REMOVE = \"GeneralIcons.BadgeRemove\"; // NOI18N\n    public static final String RENAME = \"GeneralIcons.Rename\"; // NOI18N\n    public static final String MATCH_CASE = \"GeneralIcons.MatchCase\"; // NOI18N\n    public static final String ADD = \"GeneralIcons.Add\"; // NOI18N\n    public static final String EDIT = \"GeneralIcons.Edit\"; // NOI18N\n    public static final String REMOVE = \"GeneralIcons.Remove\"; // NOI18N\n    public static final String HIGHLIGHT_RESULTS = \"GeneralIcons.HighlightResults\"; // NOI18N\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/icons/Icons.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api.icons;\n\nimport java.awt.Image;\nimport java.util.Collection;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.lib.profiler.spi.IconsProvider;\nimport org.openide.util.Lookup;\n\n/**\n * Support for predefined icons and images.\n *\n * @author Jiri Sedlacek\n */\npublic final class Icons {\n\n    /**\n     * Returns an Icon instance according to the provided key.\n     *\n     * @param key icon key\n     * @return Icon instance according to the provided key\n     */\n    public static Icon getIcon(String key) {\n        return getImageIcon(key);\n    }\n\n    /**\n     * Returns an ImageIcon instance according to the provided key.\n     *\n     * @param key icon key\n     * @return ImageIcon instance according to the provided key\n     */\n    public static ImageIcon getImageIcon(String key) {\n        Image image = getImage(key);\n        if (image == null) return null;\n        else return new ImageIcon(image);\n    }\n\n    /**\n     * Returns an Image instance according to the provided key.\n     *\n     * @param key image key\n     * @return Image instance according to the provided key\n     */\n    public static Image getImage(String key) {\n        Collection<? extends IconsProvider> ps = providers();\n        for (IconsProvider p : ps) {\n            Image image = p.getImage(key);\n            if (image != null) return image;\n        }\n        return null;\n    }\n\n    /**\n     * Returns path to image resource without leading slash according to the provided key.\n     *\n     * @param key image key\n     * @return path to image resource without leading slash according to the provided key\n     */\n    public static String getResource(String key) {\n        Collection<? extends IconsProvider> ps = providers();\n        for (IconsProvider p : ps) {\n            String resource = p.getResource(key);\n            if (resource != null) return resource;\n        }\n        return null;\n    }\n    \n    private static Collection<? extends IconsProvider> providers() {\n        return Lookup.getDefault().lookupAll(IconsProvider.class);\n    }\n    \n    \n    public static interface Keys {}\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/icons/LanguageIcons.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api.icons;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface LanguageIcons extends Icons.Keys {\n\n    public static final String CLASS = \"LanguageIcons.Class\"; // NOI18N\n    public static final String CLASS_ANONYMOUS = \"LanguageIcons.ClassAnonymous\"; // NOI18N\n    public static final String CONSTRUCTOR_PACKAGE = \"LanguageIcons.ConstructorPackage\"; // NOI18N\n    public static final String CONSTRUCTOR_PRIVATE = \"LanguageIcons.ConstructorPrivate\"; // NOI18N\n    public static final String CONSTRUCTOR_PROTECTED = \"LanguageIcons.ConstructorProtected\"; // NOI18N\n    public static final String CONSTRUCTOR_PUBLIC = \"LanguageIcons.ConstructorPublic\"; // NOI18N\n    public static final String CONSTRUCTORS = \"LanguageIcons.Constructors\"; // NOI18N\n    public static final String INITIALIZER = \"LanguageIcons.Initializer\"; // NOI18N\n    public static final String INITIALIZER_STATIC = \"LanguageIcons.InitializerStatic\"; // NOI18N\n    public static final String INTERFACE = \"LanguageIcons.Interface\"; // NOI18N\n    public static final String LIBRARIES = \"LanguageIcons.Libraries\"; // NOI18N\n    public static final String METHOD_PACKAGE = \"LanguageIcons.MethodPackage\"; // NOI18N\n    public static final String METHOD_PRIVATE = \"LanguageIcons.MethodPrivate\"; // NOI18N\n    public static final String METHOD_PROTECTED = \"LanguageIcons.MethodProtected\"; // NOI18N\n    public static final String METHOD_PUBLIC = \"LanguageIcons.MethodPublic\"; // NOI18N\n    public static final String METHOD_PACKAGE_STATIC = \"LanguageIcons.MethodPackageStatic\"; // NOI18N\n    public static final String METHOD_PRIVATE_STATIC = \"LanguageIcons.MethodPrivateStatic\"; // NOI18N\n    public static final String METHOD_PROTECTED_STATIC = \"LanguageIcons.MethodProtectedStatic\"; // NOI18N\n    public static final String METHOD_PUBLIC_STATIC = \"LanguageIcons.MethodPublicStatic\"; // NOI18N\n    public static final String METHOD_INHERITED = \"LanguageIcons.MethodInheritedStatic\"; // NOI18N\n    public static final String METHODS = \"LanguageIcons.Methods\"; // NOI18N\n    public static final String METHOD = \"LanguageIcons.Method\"; // NOI18N\n    public static final String PACKAGE = \"LanguageIcons.Package\"; // NOI18N\n    public static final String VARIABLE_PACKAGE = \"LanguageIcons.VariablePackage\"; // NOI18N\n    public static final String VARIABLE_PRIVATE = \"LanguageIcons.VariablePrivate\"; // NOI18N\n    public static final String VARIABLE_PROTECTED = \"LanguageIcons.VariableProtected\"; // NOI18N\n    public static final String VARIABLE_PUBLIC = \"LanguageIcons.VariablePublic\"; // NOI18N\n    public static final String VARIABLE_PACKAGE_STATIC = \"LanguageIcons.VariablePackageStatic\"; // NOI18N\n    public static final String VARIABLE_PRIVATE_STATIC = \"LanguageIcons.VariablePrivateStatic\"; // NOI18N\n    public static final String VARIABLE_PROTECTED_STATIC = \"LanguageIcons.VariableProtectedStatic\"; // NOI18N\n    public static final String VARIABLE_PUBLIC_STATIC = \"LanguageIcons.VariablePublicStatic\"; // NOI18N\n    public static final String VARIABLES = \"LanguageIcons.Variables\"; // NOI18N\n    public static final String ARRAY = \"LanguageIcons.Array\"; // NOI18N\n    public static final String INSTANCE = \"LanguageIcons.Instance\"; // NOI18N\n    public static final String PRIMITIVE = \"LanguageIcons.Primitive\"; // NOI18N\n    public static final String JAR = \"LanguangeIcons.Jar\"; // NOI18N\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/icons/ProfilerIcons.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api.icons;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface ProfilerIcons extends Icons.Keys {\n\n    public static final String NODE_FORWARD = \"ProfilerIcons.NodeForward\"; // NOI18N\n    public static final String NODE_REVERSE = \"ProfilerIcons.NodeReverse\"; // NOI18N\n    public static final String NODE_LEAF = \"ProfilerIcons.NodeLeaf\"; // NOI18N\n    public static final String SNAPSHOT_MEMORY_32 = \"ProfilerIcons.SnapshotMemory32\"; // NOI18N\n    public static final String THREAD = \"ProfilerIcons.Thread\"; // NOI18N\n    public static final String ALL_THREADS = \"ProfilerIcons.AllThreads\"; // NOI18N\n    public static final String SQL_QUERY = \"ProfilerIcons.SqlQuery\"; // NOI18N\n\n    public static final String ATTACH = \"ProfilerIcons.Attach\"; // NOI18N\n    public static final String ATTACH_24 = \"ProfilerIcons.Attach24\"; // NOI18N\n    public static final String SNAPSHOTS_COMPARE = \"ProfilerIcons.SnapshotsCompare\"; // NOI18N\n    public static final String SNAPSHOT_OPEN = \"ProfilerIcons.SnapshotOpen\"; // NOI18N\n    public static final String SNAPSHOT_TAKE = \"ProfilerIcons.SnapshotTake\"; // NOI18N\n    public static final String PROFILE = \"ProfilerIcons.Profile\"; // NOI18N\n    public static final String PROFILE_24 = \"ProfilerIcons.Profile24\"; // NOI18N\n    public static final String PROFILE_INACTIVE = \"ProfilerIcons.ProfileInactive\"; // NOI18N\n    public static final String PROFILE_RUNNING = \"ProfilerIcons.ProfileRunning\"; // NOI18N\n    public static final String RESET_RESULTS = \"ProfilerIcons.ResetResults\"; // NOI18N\n    public static final String RUN_GC = \"ProfilerIcons.RunGC\"; // NOI18N\n    public static final String SNAPSHOT_THREADS = \"ProfilerIcons.SnapshotThreads\"; // NOI18N\n    public static final String SNAPSHOT_HEAP = \"ProfilerIcons.SnapshotHeap\"; // NOI18N\n    public static final String CONTROL_PANEL = \"ProfilerIcons.ControlPanel\"; // NOI18N\n    public static final String LIVE_RESULTS = \"ProfilerIcons.LiveResults\"; // NOI18N\n    public static final String MODIFY_PROFILING = \"ProfilerIcons.ModifyProfiling\"; // NOI18N\n    public static final String SHOW_GRAPHS = \"ProfilerIcons.ShowGraphs\"; // NOI18N\n    \n    public static final String SNAPSHOT_DO = \"ProfilerIcons.SnapshotDO\"; // NOI18N\n    public static final String SNAPSHOT_DO_32 = \"ProfilerIcons.SnapshotDO32\"; // NOI18N\n    public static final String SNAPSHOT_CPU_DO = \"ProfilerIcons.SnapshotCpuDO\"; // NOI18N\n    public static final String SNAPSHOT_CPU_DO_32 = \"ProfilerIcons.SnapshotCpuDO32\"; // NOI18N\n    public static final String SNAPSHOT_MEMORY_DO = \"ProfilerIcons.SnapshotMemoryDO\"; // NOI18N\n    public static final String SNAPSHOT_MEMORY_DO_32 = \"ProfilerIcons.SnapshotMemoryDO32\"; // NOI18N\n    public static final String SNAPSHOT_FRAGMENT_DO = \"ProfilerIcons.SnapshotFragmentDO\"; // NOI18N\n    public static final String SNAPSHOT_FRAGMENT_DO_32 = \"ProfilerIcons.SnapshotFragmentDO32\"; // NOI18N\n    public static final String TAKE_SNAPSHOT_CPU_32 = \"ProfilerIcons.TakeSnapshotCpu32\"; // NOI18N\n    public static final String TAKE_SNAPSHOT_FRAGMENT_32 = \"ProfilerIcons.TakeSnapshotFragment32\"; // NOI18N\n    public static final String TAKE_SNAPSHOT_MEMORY_32 = \"ProfilerIcons.TakeSnapshotMemory32\"; // NOI18N\n    public static final String TAKE_HEAP_DUMP_32 = \"ProfilerIcons.TakeHeapDump32\"; // NOI18N\n    \n    public static final String TAB_BACK_TRACES = \"ProfilerIcons.TabBackTraces\"; // NOI18N\n    public static final String TAB_CALL_TREE = \"ProfilerIcons.TabCallTree\"; // NOI18N\n    public static final String TAB_COMBINED = \"ProfilerIcons.TabCombined\"; // NOI18N\n    public static final String TAB_HOTSPOTS = \"ProfilerIcons.TabHotSpots\"; // NOI18N\n    public static final String TAB_INFO = \"ProfilerIcons.TabInfo\"; // NOI18N\n    public static final String TAB_MEMORY_RESULTS = \"ProfilerIcons.TabMemoryResults\"; // NOI18N\n    public static final String TAB_STACK_TRACES = \"ProfilerIcons.TabStackTraces\"; // NOI18N\n    public static final String TAB_SUBTREE = \"ProfilerIcons.TabSubtree\"; // NOI18N\n    \n    public static final String WINDOW_CONTROL_PANEL = \"ProfilerIcons.WindowControlPanel\"; // NOI18N\n    public static final String WINDOW_LIVE_RESULTS = \"ProfilerIcons.WindowLiveResults\"; // NOI18N\n    public static final String WINDOW_TELEMETRY_OVERVIEW = \"ProfilerIcons.WindowTelemetryOverview\"; // NOI18N\n    public static final String WINDOW_TELEMETRY = \"ProfilerIcons.WindowTelemetry\"; // NOI18N\n    public static final String WINDOW_THREADS = \"ProfilerIcons.WindowThreads\"; // NOI18N\n    public static final String WINDOW_LOCKS = \"ProfilerIcons.WindowLocks\"; // NOI18N\n    public static final String WINDOW_SQL = \"ProfilerIcons.WindowSql\"; // NOI18N\n    \n    public static final String VIEW_LIVE_RESULTS_CPU_32 = \"ProfilerIcons.ViewLiveResultsCpu32\"; // NOI18N\n    public static final String VIEW_LIVE_RESULTS_FRAGMENT_32 = \"ProfilerIcons.ViewLiveResultsFragment32\"; // NOI18N\n    public static final String VIEW_LIVE_RESULTS_MEMORY_32 = \"ProfilerIcons.ViewLiveResultsMemory32\"; // NOI18N\n    public static final String VIEW_THREADS_32 = \"ProfilerIcons.ViewThreads32\"; // NOI18N\n    public static final String VIEW_TELEMETRY_32 = \"ProfilerIcons.ViewTelemetry32\"; // NOI18N\n    public static final String VIEW_LOCKS_32 = \"ProfilerIcons.ViewLocks32\"; // NOI18N\n    \n    public static final String CPU = \"ProfilerIcons.Cpu\"; // NOI18N\n    public static final String CPU_32 = \"ProfilerIcons.Cpu32\"; // NOI18N\n    public static final String FRAGMENT = \"ProfilerIcons.Fragment\"; // NOI18N\n    public static final String MEMORY = \"ProfilerIcons.Memory\"; // NOI18N\n    public static final String MEMORY_32 = \"ProfilerIcons.Memory32\"; // NOI18N\n    public static final String HEAP_DUMP = \"ProfilerIcons.HeapDump\"; // NOI18N\n    \n    public static final String CUSTOM_32 = \"ProfilerIcons.Custom32\"; // NOI18N\n    public static final String MONITORING = \"ProfilerIcons.Monitoring\"; // NOI18N\n    public static final String MONITORING_32 = \"ProfilerIcons.Monitoring32\"; // NOI18N\n    public static final String STARTUP_32 = \"ProfilerIcons.Startup32\"; // NOI18N\n    \n    public static final String DELTA_RESULTS = \"ProfilerIcons.DeltaResults\"; // NOI18N\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/java/ExternalPackages.java",
    "content": "/*\n * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api.java;\n\nimport java.io.IOException;\nimport java.lang.reflect.Modifier;\nimport java.util.*;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassFileParser;\nimport org.graalvm.visualvm.lib.jfluid.classfile.ClassInfo;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\n\n/**\n *\n * @author Jaroslv Bachorik\n */\nfinal public class ExternalPackages {\n    private static final Comparator<FileObject> pathComparator = new Comparator<FileObject>() {\n        @Override\n        public int compare(FileObject o1, FileObject o2) {\n            return o1.getPath().compareTo(o2.getPath());\n        }\n    };\n\n    private static class FilePackageInfo extends SourcePackageInfo {\n        private FileObject root;\n        private FileObject pkg;\n        private Set<String> pkgsContent;\n\n        FilePackageInfo(FileObject root, FileObject pkg, Set<String> pkgsContent) {\n            super(FileUtil.getRelativePath(root, pkg), FileUtil.getRelativePath(root, pkg).replace('/', '.'), SourcePackageInfo.Scope.SOURCE); // NOI18N\n            this.pkg = pkg;\n            this.root = root;\n            this.pkgsContent = pkgsContent;\n        }\n\n        @Override\n        public Collection<SourceClassInfo> getClasses() {\n            Set<FileObject> clzs = new TreeSet(pathComparator);\n            Enumeration<? extends FileObject> e = pkg.getData(false);\n            while (e.hasMoreElements()) {\n                FileObject clz = e.nextElement();\n                if (clz.getExt().equalsIgnoreCase(\"class\")) { // NOI18N\n                    clzs.add(clz);\n                }\n            }\n            ClassFileParser cfp = new ClassFileParser();\n            Collection<SourceClassInfo> rslt = new ArrayList<>();\n            for(final FileObject p : clzs) {\n                if (p.getName().contains(\"$\")) { // NOI18N\n                    continue; // skipping inner classes\n                }\n                \n                ClassInfo ci = new ClassInfo(p.getName(), 0) {\n                    @Override\n                    protected byte[] getClassFileBytes() throws IOException, ClassNotFoundException {\n                        return p.asBytes();\n                    }\n                };\n                try {\n                    cfp.parseClassFile(p.asBytes(), ci);\n                    rslt.add(new FileClassInfo(ci, root, p));\n                } catch (IOException ex) {\n                } catch (ClassFileParser.ClassFileReadException ex) {\n                }\n            }\n            return rslt;\n        }\n        \n        boolean hasClasses() {\n            Enumeration<? extends FileObject> e = pkg.getData(false);\n            while (e.hasMoreElements())\n                if (e.nextElement().getExt().equalsIgnoreCase(\"class\")) // NOI18N\n                    return true;\n            return false;\n        }\n\n        @Override\n        public Collection<SourcePackageInfo> getSubpackages() {\n            Set<FileObject> pkgs = new TreeSet(pathComparator);\n            Enumeration<? extends FileObject> e = pkg.getFolders(false);\n            while (e.hasMoreElements()) {\n                pkgs.add(e.nextElement());\n            }\n            Collection<SourcePackageInfo> rslt = new ArrayList<>();\n            for(FileObject p : pkgs) {\n                if (pkgsContent.contains(p.getPath())) {\n                    rslt.add(new FilePackageInfo(root, p, pkgsContent));\n                }\n            }\n            return rslt;\n        }   \n    }\n    \n    private static class FileClassInfo extends SourceClassInfo {\n        private FileObject root, clazz;\n        private ClassInfo ci;\n        \n        FileClassInfo(ClassInfo ci, FileObject root, FileObject clazz) {\n            super(clazz.getName(), FileUtil.getRelativePath(root, clazz).replace('/', '.').replace(\".class\", \"\"), FileUtil.getRelativePath(root, clazz).replace(\".class\", \"\")); // NOI18N\n            this.ci = ci;\n            this.clazz = clazz;\n            this.root = root;\n        }\n\n        @Override\n        public Set<SourceMethodInfo> getConstructors() {\n            String[] names = ci.getMethodNames();\n            Set<SourceMethodInfo> cts = new HashSet<>();\n            if (names != null) {\n                for(int i=0;i<names.length;i++) {\n                    if (names[i].equals(\"<init>\")) { // NOI18N\n                        cts.add(new FileMethodInfo(ci, i));\n                    }\n                }\n            }\n            return cts;\n        }\n\n        @Override\n        public FileObject getFile() {\n            return clazz;\n        }\n\n        @Override\n        public Set<SourceClassInfo> getInnerClases() {\n            Set<SourceClassInfo> rslt = new HashSet<>();\n            ClassFileParser cfp = new ClassFileParser();\n            Enumeration<? extends FileObject> siblings = clazz.getParent().getData(false);\n            while (siblings.hasMoreElements()) {\n                final FileObject sibling = siblings.nextElement();\n                if (sibling.getName().contains(\"$\") && sibling.getName().startsWith(clazz.getName()) && !sibling.getName().equals(clazz.getName())) { // NOI18N\n                    ClassInfo ci = new ClassInfo(sibling.getName(), 0) {\n                        @Override\n                        protected byte[] getClassFileBytes() throws IOException, ClassNotFoundException {\n                            return sibling.asBytes();\n                        }\n                    };\n                    try {\n                        cfp.parseClassFile(sibling.asBytes(), ci);\n                        rslt.add(new FileClassInfo(ci, root, sibling));\n                    } catch (IOException ex) {\n                    } catch (ClassFileParser.ClassFileReadException ex) {\n                    }\n                }\n            }\n            return rslt;\n        }\n\n        @Override\n        public Set<SourceClassInfo> getInterfaces() {\n            Set<SourceClassInfo> ifcs = new HashSet<>();\n            String[] iNames = ci.getInterfaceNames();\n            if (iNames != null) {\n                for(String name : iNames) {\n                    ifcs.add(new PlainClassInfo(name));\n                }\n            }\n            return ifcs;\n        }\n\n        @Override\n        public Set<SourceMethodInfo> getMethods(boolean all) {\n            String[] names = ci.getMethodNames();\n            Set<SourceMethodInfo> cts = new HashSet<>();\n            if (names != null) {\n                for(int i=0;i<names.length;i++) {\n                    if (!names[i].equals(\"<init>\")) { // NOI18N\n                        cts.add(new FileMethodInfo(ci, i));\n                    }\n                }\n            }\n            return cts;\n        }\n\n        @Override\n        public Set<SourceClassInfo> getSubclasses() {\n            return Collections.EMPTY_SET;\n        }\n\n        @Override\n        public SourceClassInfo getSuperType() {\n            String superC = ci.getSuperclassName();\n            if (superC == null) {\n                superC = Object.class.getName();\n            }\n            return new PlainClassInfo(superC);\n        }\n        \n    }\n    \n    private static class PlainClassInfo extends SourceClassInfo {\n        PlainClassInfo(String className) {\n            super(className, className, className);\n        }\n        @Override\n        public FileObject getFile() {\n            return null;\n        }\n\n        @Override\n        public Set<SourceMethodInfo> getMethods(boolean all) {\n            return Collections.EMPTY_SET;\n        }\n\n        @Override\n        public Set<SourceClassInfo> getSubclasses() {\n            return Collections.EMPTY_SET;\n        }\n\n        @Override\n        public Set<SourceClassInfo> getInnerClases() {\n            return Collections.EMPTY_SET;\n        }\n\n        @Override\n        public Set<SourceMethodInfo> getConstructors() {\n            return Collections.EMPTY_SET;\n        }\n\n        @Override\n        public SourceClassInfo getSuperType() {\n            return new PlainClassInfo(\"\");\n        }\n\n        @Override\n        public Set<SourceClassInfo> getInterfaces() {\n            return Collections.EMPTY_SET;\n        }\n    }\n    \n    private static class FileMethodInfo extends SourceMethodInfo {\n        private static int getModifiers(ClassInfo ci, int mIndex) {\n            int modifiers = 0;\n            if (ci.isMethodAbstract(mIndex)) {\n                modifiers += Modifier.ABSTRACT;\n            }\n            if (ci.isMethodPrivate(mIndex)) {\n                modifiers += Modifier.PRIVATE;\n            }\n            if (ci.isMethodProtected(mIndex)) {\n                modifiers += Modifier.PROTECTED;\n            }\n            if (ci.isMethodPublic(mIndex)) {\n                modifiers += Modifier.PUBLIC;\n            }\n            if (ci.isMethodFinal(mIndex)) {\n                modifiers += Modifier.FINAL;\n            }\n            if (ci.isMethodStatic(mIndex)) {\n                modifiers += Modifier.STATIC;\n            }\n            if (ci.isMethodNative(mIndex)) {\n                modifiers += Modifier.NATIVE;\n            }\n            return modifiers;\n        }\n        FileMethodInfo(ClassInfo ci, int mIndex) {\n            super(ci.getName().replace('/', '.'), ci.getMethodName(mIndex), ci.getMethodSignature(mIndex), ci.getMethodName(mIndex), false, getModifiers(ci, mIndex)); // NOI18N\n        }\n    }\n    \n    public static List<SourcePackageInfo> forPath(FileObject fo, boolean rec) {\n        FileObject root = null;\n        if (fo.getExt().equalsIgnoreCase(\"jar\")) { // NOI18N\n            if (FileUtil.isArchiveFile(fo)) {\n                root = FileUtil.getArchiveRoot(fo);\n            }\n        } else if (fo.isFolder()) {\n            root = fo;\n        }\n        if (root != null) {\n            Queue<FileObject> stack = new ArrayDeque<>();\n            Set<FileObject> packages = new TreeSet<>(pathComparator);\n            Set<String> pkgsContent = new HashSet<>();\n\n            stack.offer(root);\n            while (!stack.isEmpty()) {\n                FileObject f = stack.poll();\n                if (f != null) {\n                    if (f.isData() && f.getExt().equalsIgnoreCase(\"class\")) { // NOI18N\n                        String path = f.getParent().getPath();\n                        int i = path.lastIndexOf('/'); // NOI18N\n                        while (i > -1) {\n                            pkgsContent.add(path);\n                            path = path.substring(0, i);\n                            i = path.lastIndexOf('/'); // NOI18N\n                        }\n                        pkgsContent.add(path);\n                    } else {\n                        stack.addAll(Arrays.asList(f.getChildren()));\n                    }\n                }\n            }\n                    \n            Enumeration<? extends FileObject> ePkgs = root.getFolders(false);\n            while (ePkgs.hasMoreElements()) {\n                FileObject pkg = ePkgs.nextElement();\n                if (pkgsContent.contains(pkg.getPath())) {\n                    packages.add(pkg);\n                }\n            }\n\n            List<SourcePackageInfo> pkgis = new ArrayList<>(packages.size());\n            for (FileObject pkg : packages) {\n                pkgis.add(new FilePackageInfo(root, pkg, pkgsContent));\n            }\n            \n            if (rec) {\n                Queue<SourcePackageInfo> _packages = new ArrayDeque(pkgis);\n                pkgis.clear();\n                while (!_packages.isEmpty()) {\n                    FilePackageInfo pkg = (FilePackageInfo)_packages.poll();\n                    if (pkg.hasClasses()) pkgis.add(pkg);\n                    _packages.addAll(pkg.getSubpackages());\n                }\n            }\n\n            return pkgis;\n        }\n        \n        return Collections.EMPTY_LIST;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/java/JavaProfilerSource.java",
    "content": "/*\n * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api.java;\n\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerSource;\nimport org.graalvm.visualvm.lib.profiler.spi.java.AbstractJavaProfilerSource;\nimport org.netbeans.api.editor.mimelookup.MimeLookup;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\n\n/**\n * Java source file representation\n *\n * @author Jaroslav Bachorik\n */\nfinal public class JavaProfilerSource extends ProfilerSource {\n    final private AbstractJavaProfilerSource impl;\n\n    /**\n     * Factory method for obtaining a {@linkplain JavaProfilerSource} from a file or NULL\n     * @return Returns a {@linkplain JavaProfilerSource} instance or NULL\n     */\n    public static JavaProfilerSource createFrom(FileObject fo) {\n        if (fo == null || !fo.isValid()) return null;\n\n        Lookup lkp = MimeLookup.getLookup(fo.getMIMEType());\n        AbstractJavaProfilerSource impl = lkp.lookup(AbstractJavaProfilerSource.class);\n        if (impl == null && fo.isData() && fo.hasExt(\"java\")) // NOI18N\n            impl = Lookup.getDefault().lookup(AbstractJavaProfilerSource.class);\n        if (impl == null) {\n            return null;\n        }\n        return new JavaProfilerSource(fo, impl);\n    }\n\n    private JavaProfilerSource(FileObject file, AbstractJavaProfilerSource impl) {\n        super(file);\n        this.impl = impl;\n    }\n\n    /**\n     *\n     * @return Returns true if the source represents a junit tet\n     */\n    public boolean isTest() {\n        return impl.isTest(getFile());\n    }\n\n    /**\n     *\n     * @return Returns true if the source is a java applet\n     */\n    public boolean isApplet() {\n        return impl.isApplet(getFile());\n    }\n\n    /**\n     * \n     * @return Returns {@linkplain SourceClassInfo} of a top level class\n     */\n    public SourceClassInfo getTopLevelClass() {\n        return impl.getTopLevelClass(getFile());\n    }\n\n    /**\n     * List all top level classes contained in the source\n     * @return Returns a set of {@linkplain SourceClassInfo} instances from a source\n     */\n    public Set<SourceClassInfo> getClasses() {\n        return impl.getClasses(getFile());\n    }\n    \n    /**\n     * Lists all main classes contained in the source\n     * @return Returns a set of {@linkplain SourceClassInfo} instances from a source\n     */\n    public Set<SourceClassInfo> getMainClasses() {\n        return impl.getMainClasses(getFile());\n    }\n    \n    /**\n     * Lists all constructors contained in the source\n     * @return Returns a set of {@linkplain SourceMethodInfo} instances from the source\n     */\n    public Set<SourceMethodInfo> getConstructors() {\n        return impl.getConstructors(getFile());\n    }\n    \n    /**\n     * Finds a class present on the given position in the source\n     * @param position The position in the source\n     * @return Returns a {@linkplain SourceClassInfo} for the class present on the given position\n     */\n    public SourceClassInfo getEnclosingClass(final int position) {\n        return impl.getEnclosingClass(getFile(), position);\n    }\n    \n    /**\n     * Finds a method present on the given position in the source\n     * @param position The position in the source\n     * @return Returns a {@linkplain SourceMethodInfo} for the method present on the given position\n     */\n    public SourceMethodInfo getEnclosingMethod(final int position) {\n        return impl.getEnclosingMethod(getFile(), position);\n    }\n    \n    /**\n     * Checks whether the source represents any or all of the provided superclasses/interfaces\n     * @param classNames A list of required superclasses/interfaces\n     * @param allRequired Require all(TRUE)/any(FALSE) provided superclasses/interfaces to match\n     * @return Returns TRUE if the source represents any or all of the provided classes/interfaces\n     */\n    public boolean isInstanceOf(String[] classNames, boolean allRequired) {\n        return impl.isInstanceOf(getFile(), classNames, allRequired);\n    }\n    \n    /**\n     * Checks whether the source represents the provided superclass/interface\n     * @param className The required superclass/interface\n     * @return Returns TRUE if the source represents the provided superclass/interface\n     */\n    public boolean isInstanceOf(String className) {\n        return impl.isInstanceOf(getFile(), className);\n    }\n    \n    /**\n     * Checks whether the source contains any/all provided annotations\n     * @param annotationNames A list of required annotations\n     * @param allRequired Require all(TRUE)/any(FALSE) provided annotations to match\n     * @return Returns TRUE if the source contains any or all of the provided annotations\n     */\n    public boolean hasAnnotation(String[] annotationNames, boolean allRequired) {\n        return impl.hasAnnotation(getFile(), annotationNames, allRequired);\n    }\n    \n    /**\n     * Checks whether the source contains the provided annotation\n     * @param annotation The required annotation\n     * @return Returns TRUE if the source contains the provided annotation\n     */\n    public boolean hasAnnotation(String annotation) {\n        return impl.hasAnnotation(getFile(), annotation);\n    }\n    \n    /**\n     * Is the given offset valid within a particular source\n     * @param offset The offset to check\n     * @return Returns TRUE if the offset is valid for the source\n     */\n    public boolean isOffsetValid(int offset) {\n        return impl.isOffsetValid(getFile(), offset);\n    }\n    \n    /**\n     * Resolves a method at the given position<br>\n     * In order to resolve the method there must be the method definition or invocation\n     * at the given position.\n     * @param position The position to check for method definition or invocation\n     * @return Returns the {@linkplain SourceMethodInfo} for the method definition or invocation at the given position or NULL if there is none\n     */\n    public SourceMethodInfo resolveMethodAtPosition(int position) {\n        return impl.resolveMethodAtPosition(getFile(), position);\n    }\n\n    /**\n     * Resolves a class at the given position<br>\n     * In order to resolve the class there must be the class definition or reference\n     * at the given position.\n     * @param position The position to check for class definition or reference\n     * @param resolveField Should the class be resolved from a variable type too?\n     * @return Returns the {@linkplain SourceClassInfo} for the class definition or reference at the given position or NULL if there is none\n     */\n    public SourceClassInfo resolveClassAtPosition(int position, boolean resolveField) {\n        return impl.resolveClassAtPosition(getFile(), position, resolveField);\n    }\n\n    @Override\n    public boolean isRunnable() {\n        return isApplet() || isTest() || !getMainClasses().isEmpty();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/java/ProfilerTypeUtils.java",
    "content": "/*\n * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api.java;\n\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.profiler.spi.java.ProfilerTypeUtilsProvider;\nimport org.openide.util.Lookup;\n\n/**\n * Java types related profiler utility methods\n *\n * @author Jaroslav Bachorik\n */\nfinal public class ProfilerTypeUtils {\n    private static ProfilerTypeUtilsProvider getProvider(Lookup.Provider project) {\n        return project != null ? project.getLookup().lookup(ProfilerTypeUtilsProvider.class) : Lookup.getDefault().lookup(ProfilerTypeUtilsProvider.class);\n    }\n\n    /**\n     * Resolves a class given its FQN\n     * @param className The class FQN\n     * @param project A project to resolve the class in\n     * @return Returns a resolved {@linkplain SourceClassInfo} or null\n     */\n    public static SourceClassInfo resolveClass(String className, Lookup.Provider project) {\n        ProfilerTypeUtilsProvider p = getProvider(project);\n        return p != null ? p.resolveClass(className) : null;\n    }\n\n    /**\n     * @param project A project to get the main classes for\n     * @return Returns a list of all main classes present in the project\n     */\n    public static Collection<SourceClassInfo> getMainClasses(Lookup.Provider project) {\n        ProfilerTypeUtilsProvider p = getProvider(project);\n\n        return p != null ? p.getMainClasses() : Collections.EMPTY_LIST;\n    }\n\n    /**\n     * Retrieves project's packages\n     * @param subprojects Flag indicating whether subprojects should be taken into account\n     * @param scope A {@linkplain SourcePackageInfo.Scope} - SOURCE or DEPENDENCIES\n     * @param project A project to get the packages for\n     * @return Returns a list of project's packages\n     */\n    public static Collection<SourcePackageInfo> getPackages(boolean subprojects, SourcePackageInfo.Scope scope, Lookup.Provider project) {\n        ProfilerTypeUtilsProvider p = getProvider(project);\n        \n        return p != null ? p.getPackages(subprojects, scope) : Collections.EMPTY_LIST;\n    }\n    \n    /**\n     * Case insensitive regexp class search\n     * @param pattern Class pattern as a regular expression\n     * @param scope A {@linkplain SourcePackageInfo.Scope} - SOURCE or DEPENDENCIES\n     * @param project A project to get the packages for\n     * @return Returns a collection of classes matching the given pattern\n     */\n    public static Collection<SourceClassInfo> findClasses(String pattern, Set<SourcePackageInfo.Scope> scope, Lookup.Provider project) {\n        ProfilerTypeUtilsProvider p = getProvider(project);\n        \n        return p != null ? p.findClasses(pattern, scope) : Collections.EMPTY_LIST;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/java/SourceClassInfo.java",
    "content": "/*\n * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api.java;\n\nimport java.util.Comparator;\nimport java.util.Objects;\nimport java.util.Set;\nimport java.util.regex.Pattern;\nimport org.openide.filesystems.FileObject;\n\n/**\n * A simplified java class descriptor\n */\n/**\n *\n * @author Jaroslav Bachorik\n */\nabstract public class SourceClassInfo {\n    final public static Comparator<SourceClassInfo> COMPARATOR = new Comparator<SourceClassInfo>() {\n        @Override\n        public int compare(SourceClassInfo o1, SourceClassInfo o2) {\n            return o1.getVMName().compareTo(o2.getVMName());\n        }\n    };\n\n    final private static Pattern anonymousInnerClassPattern = Pattern.compile(\".*?\\\\$[0-9]*$\");\n\n    private String simpleName, qualName, vmName;\n\n    public SourceClassInfo(String name, String fqn, String vmName) {\n        this.simpleName = name;\n        this.qualName = fqn;\n        this.vmName = vmName;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj == null) {\n            return false;\n        }\n        if (getClass() != obj.getClass()) {\n            return false;\n        }\n        final SourceClassInfo other = (SourceClassInfo) obj;\n        if (!Objects.equals(vmName, other.vmName)) {\n            return false;\n        }\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int hash = 5;\n        hash = 53 * hash + (this.vmName != null ? this.vmName.hashCode() : 0);\n        return hash;\n    }\n\n    /**\n     *\n     * @return Returns the class simple name (the last part of the FQN)\n     */\n    final public String getSimpleName() {\n        return simpleName;\n    }\n\n    /**\n     *\n     * @return Returns the class FQN\n     */\n    final public String getQualifiedName() {\n        return qualName;\n    }\n\n    /**\n     *\n     * @return Returns the VM internal class name\n     */\n    final public String getVMName() {\n        return vmName;\n    }\n\n    /**\n     *\n     * @return Returns true if the class is an anonymous inner class, false otherwise\n     */\n    public boolean isAnonymous() {\n        return isAnonymous(qualName);\n    }\n    \n    abstract public FileObject getFile();\n    abstract public Set<SourceMethodInfo> getMethods(boolean all);\n    abstract public Set<SourceClassInfo> getSubclasses();\n    abstract public Set<SourceClassInfo> getInnerClases();\n    abstract public Set<SourceMethodInfo> getConstructors();\n    abstract public SourceClassInfo getSuperType();\n    abstract public Set<SourceClassInfo> getInterfaces();\n    \n    final protected boolean isAnonymous(String className) {\n        return anonymousInnerClassPattern.matcher(className).matches();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/java/SourceMethodInfo.java",
    "content": "/*\n * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api.java;\n\nimport java.lang.reflect.Modifier;\nimport java.util.Objects;\n\n/**\n * A simplified java method descriptor\n */\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class SourceMethodInfo {\n    private String className, name, signature, vmName;\n    private boolean execFlag;\n    final private int modifiers;\n\n    public SourceMethodInfo(String className, String name, String signature, String vmName, boolean execFlag, int modifiers) {\n        this.className = className;\n        this.name = name;\n        this.signature = signature;\n        this.vmName = vmName;\n        this.execFlag = execFlag;\n        this.modifiers = modifiers;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj == null) {\n            return false;\n        }\n        if (getClass() != obj.getClass()) {\n            return false;\n        }\n        final SourceMethodInfo other = (SourceMethodInfo) obj;\n        if (!Objects.equals(className, other.className)) {\n            return false;\n        }\n        if (!Objects.equals(name, other.name)) {\n            return false;\n        }\n        if (!Objects.equals(signature, other.signature)) {\n            return false;\n        }\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int hash = 7;\n        hash = 73 * hash + (this.className != null ? this.className.hashCode() : 0);\n        hash = 73 * hash + (this.name != null ? this.name.hashCode() : 0);\n        hash = 73 * hash + (this.signature != null ? this.signature.hashCode() : 0);\n        return hash;\n    }\n\n    /**\n     *\n     * @return Returns the containing class FQN\n     */\n    final public String getClassName() {\n        return className;\n    }\n\n    /**\n     *\n     * @return Returns the method name\n     */\n    final public String getName() {\n        return name;\n    }\n\n    /**\n     *\n     * @return Returns the method signature\n     */\n    final public String getSignature() {\n        return signature;\n    }\n\n    /**\n     *\n     * @return Returns the VM internal method name\n     */\n    final public String getVMName() {\n        return vmName;\n    }\n\n    /**\n     *\n     * @return Returns TRUE if the method is executable (eg. main(String[]) or JSP main method)\n     */\n    final public boolean isExecutable() {\n        return execFlag;\n    }\n    \n    /**\n     * \n     * @return Returns method's modifiers in the {@linkplain Modifier} format\n     */\n    final public int getModifiers() {\n        return modifiers;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/java/SourcePackageInfo.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api.java;\n\nimport java.util.Collection;\n\n/**\n * A java package wrapper\n * @author Jaroslav Bachorik\n */\nabstract public class SourcePackageInfo {\n    public static enum Scope {\n        SOURCE, DEPENDENCIES\n    }\n\n    private String simpleName;\n    private String fqn;\n    private Scope scope;\n\n    public SourcePackageInfo(String simpleName, String fqn, Scope scope) {\n        this.simpleName = simpleName;\n        this.fqn = fqn;\n        this.scope = scope;\n    }\n\n    public String getBinaryName() {\n        return fqn;\n    }\n\n    public String getSimpleName() {\n        return simpleName;\n    }\n\n    public Scope getScope() {\n        return scope;\n    }\n\n    abstract public Collection<SourcePackageInfo> getSubpackages();\n    abstract public Collection<SourceClassInfo> getClasses();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/project/ProjectContentsSupport.java",
    "content": "/*\n * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api.project;\n\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.profiler.spi.project.ProjectContentsSupportProvider;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\n\n/**\n * Support for configuring profiling roots and instrumentation filter from a project.\n *\n * @author Jiri Sedlacek\n */\npublic final class ProjectContentsSupport {\n\n    private static final ClientUtils.SourceCodeSelection[] EMPTY_SELECTION = new ClientUtils.SourceCodeSelection[0];\n    private static ProjectContentsSupport DEFAULT;\n\n    private final Collection<? extends ProjectContentsSupportProvider> providers;\n\n\n    /**\n     * Returns array of profiling roots for the defined context.\n     *\n     * @param profiledClassFile profiled file or null for profiling the entire project\n     * @param profileSubprojects true if profiling also project's subprojects, false for profiling just the project\n     * @return array of profiling roots for the defined context\n     */\n    public ClientUtils.SourceCodeSelection[] getProfilingRoots(FileObject profiledClassFile,\n                                                               boolean profileSubprojects) {\n        if (providers == null) {\n            return EMPTY_SELECTION;\n        } else {\n            Set<ClientUtils.SourceCodeSelection> allRoots = new HashSet<>();\n            for (ProjectContentsSupportProvider provider : providers) {\n                ClientUtils.SourceCodeSelection[] roots = provider.getProfilingRoots(profiledClassFile, profileSubprojects);\n                if (roots != null && roots.length > 0) allRoots.addAll(Arrays.asList(roots));\n            }\n            return allRoots.toArray(new ClientUtils.SourceCodeSelection[0]);\n        }\n    }\n\n    /**\n     * Returns instrumentation filter for the defined context.\n     * \n     * @param profileSubprojects true if profiling also project's subprojects, false for profiling just the project\n     * @return instrumentation filter for the defined context\n     */\n    public String getInstrumentationFilter(boolean profileSubprojects) {\n        if (providers == null) {\n            return \"\"; // NOI18N\n        } else {\n            StringBuilder buffer = new StringBuilder();\n            for( ProjectContentsSupportProvider provider : providers) {\n                String filter = provider.getInstrumentationFilter(profileSubprojects);\n                if (filter != null && !filter.isEmpty()) {\n                    buffer.append(filter).append(\" \"); // NOI18N\n                }\n            }\n            return buffer.toString().trim();\n        }\n    }\n    \n    /**\n     * Resets the ProjectContentsSupport instance after submitting or cancelling the Select Profiling Task dialog.\n     */\n    public void reset() {\n        if (providers != null)\n            for (ProjectContentsSupportProvider provider : providers) \n                provider.reset();\n    }\n    \n    \n    private ProjectContentsSupport(Collection<? extends ProjectContentsSupportProvider> providers) {\n        this.providers = providers;\n    }\n    \n    private static synchronized ProjectContentsSupport defaultImpl() {\n        if (DEFAULT == null)\n            DEFAULT = new ProjectContentsSupport(null);\n        return DEFAULT;\n    }\n    \n\n    /**\n     * Returns ProjectContentsSupport instance for the provided project.\n     * \n     * @param project project\n     * @return ProjectContentsSupport instance for the provided project\n     */\n    public static ProjectContentsSupport get(Lookup.Provider project) {\n        Collection<? extends ProjectContentsSupportProvider> providers =\n                project != null ? project.getLookup().lookupAll(ProjectContentsSupportProvider.class) : null;\n        if (providers == null || providers.isEmpty()) return defaultImpl();\n        else return new ProjectContentsSupport(providers);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/api/project/ProjectProfilingSupport.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.api.project;\n\nimport org.graalvm.visualvm.lib.common.SessionSettings;\nimport org.graalvm.visualvm.lib.profiler.api.JavaPlatform;\nimport org.graalvm.visualvm.lib.profiler.spi.project.ProjectProfilingSupportProvider;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\n\n/**\n * Support for profiling projects.\n *\n * @author Jiri Sedlacek\n */\npublic final class ProjectProfilingSupport {\n\n    private static ProjectProfilingSupport DEFAULT;\n\n    private final ProjectProfilingSupportProvider provider;\n\n\n    /**\n     * Returns true if profiling a project is supported.\n     *\n     * @return true if profiling a project is supported, false otherwise\n     */\n    public boolean isProfilingSupported() {\n        return provider.isProfilingSupported();\n    }\n\n    /**\n     * Returns true if attaching to a running project is supported.\n     *\n     * @return true if attaching to a running project is supported, false otherwise.\n     */\n    public boolean isAttachSupported() {\n        return provider.isAttachSupported();\n    }\n\n    /**\n     * Returns true if profiling the provided file is supported.\n     *\n     * @param fo file\n     * @return true if profiling the provided file is supported, false otherwise\n     */\n    public boolean isFileObjectSupported(FileObject fo) {\n        return provider.isFileObjectSupported(fo);\n    }\n\n    /**\n     * Returns true if Profiling Points can be processed by this project.\n     *\n     * @return true if Profiling Points can be processed by this project, false otherwise.\n     */\n    public boolean areProfilingPointsSupported() {\n        return provider.areProfilingPointsSupported();\n    }\n\n    /**\n     * Returns the Java platform configured for running the project.\n     *\n     * @return Java platform configured for running the project\n     */\n    public JavaPlatform getProjectJavaPlatform() {\n        return provider.getProjectJavaPlatform();\n    }\n    \n    /**\n     * Returns true if the project is configured and properly set up to be profiled (e.g. profiler is integrated with the project, main class has a main method etc.).\n     * \n     * @param profiledClassFile profiled file or null for profiling the entire project\n     * @return true if the project is configured and properly set up to be profiled, false otherwise\n     */\n    public boolean checkProjectCanBeProfiled(FileObject profiledClassFile) {\n        return provider.checkProjectCanBeProfiled(profiledClassFile);\n    }\n    \n    /**\n     * Configures project-specific session settings.\n     * \n     * @param ss session settings\n     */\n    public void setupProjectSessionSettings(SessionSettings ss) {\n        provider.setupProjectSessionSettings(ss);\n    }\n    \n    /**\n     * Allows to start a profiling session directly by the ProjectProfilingSupport instance.\n     * \n     * @param profiledClassFile profiled file\n     * @param isTest true if profiledClassFile is a test, false otherwise\n     * @return true if the ProjectProfilingSupport instance started a profiling session, false otherwise\n     */\n    public boolean startProfilingSession(FileObject profiledClassFile, boolean isTest) {\n        return provider.startProfilingSession(profiledClassFile, isTest);\n    }\n    \n    \n    private ProjectProfilingSupport(ProjectProfilingSupportProvider provider) {\n        this.provider = provider;\n    }\n    \n    private static synchronized ProjectProfilingSupport defaultImpl() {\n        if (DEFAULT == null)\n            DEFAULT = new ProjectProfilingSupport(new ProjectProfilingSupportProvider.Basic());\n        return DEFAULT;\n    }\n    \n    \n    /**\n     * Returns ProjectProfilingSupport instance for the provided project.\n     * \n     * @param project project\n     * @return ProjectProfilingSupport instance for the provided project\n     */\n    public static ProjectProfilingSupport get(Lookup.Provider project) {\n        ProjectProfilingSupportProvider provider =\n                project != null ? project.getLookup().lookup(ProjectProfilingSupportProvider.class) : null;\n        if (provider == null) return defaultImpl();\n        else return new ProjectProfilingSupport(provider);\n    }\n    \n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/ActionsSupportProvider.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.spi;\n\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.InputMap;\nimport javax.swing.KeyStroke;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ActionsSupportProvider {\n\n    public abstract KeyStroke registerAction(String actionKey, Action action, ActionMap actionMap, InputMap inputMap);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/EditorSupportProvider.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.spi;\n\nimport org.graalvm.visualvm.lib.profiler.api.EditorContext;\nimport org.graalvm.visualvm.lib.profiler.api.EditorSupport;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerProject;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\n\n/**\n * An SPI interface for {@linkplain EditorSupport} functionality\n * @author Jaroslav Bachorik\n */\npublic abstract class EditorSupportProvider {\n    public static EditorSupportProvider NULL = new EditorSupportProvider() {\n\n        @Override\n        public boolean currentlyInJavaEditor() {\n            return false;\n        }\n\n        @Override\n        public EditorContext getMostActiveJavaEditorContext() {\n            return null;\n        }\n\n        @Override\n        public FileObject getCurrentFile() {\n            return null;\n        }\n\n        @Override\n        public int getCurrentOffset() {\n            return -1;\n        }\n\n        @Override\n        public boolean isOffsetValid(FileObject file, int offset) {\n            return false;\n        }\n\n        @Override\n        public int getLineForOffset(FileObject file, int offset) {\n            return -1;\n        }\n\n        @Override\n        public int getOffsetForLine(FileObject file, int line) {\n            return -1;\n        }\n\n        @Override\n        public ProfilerProject getCurrentProject() {\n            return null;\n        }\n\n        @Override\n        public int[] getSelectionOffsets() {\n            return new int[]{-1, -1};\n        }\n    };\n\n    /**\n     * Returns true if currently focused IDE component is Java editor.\n     *\n     * @return true if currently focused IDE component is Java editor, false otherwise\n     */\n    public abstract boolean currentlyInJavaEditor();\n    /**\n     * Returns editor context of the most active Java editor.\n     *\n     * @return editor context of the most active Java editor or null if not available\n     */\n    public abstract EditorContext getMostActiveJavaEditorContext();\n    /**\n     * Returns the FileObject of the most active editor document\n     * @return A FileObject or null\n     */\n    public abstract FileObject getCurrentFile();\n    /**\n     * Returns the caret position within the active editor document\n     * @return The caret offset or -1\n     */\n    public abstract int getCurrentOffset();\n    /**\n     * Validates an offset within a particular file\n     * @param file The file to check\n     * @param offset The offset within the file\n     * @return Returns TRUE if the given offset is valid\n     */\n    public abstract boolean isOffsetValid(FileObject file, int offset);\n    /**\n     * Calculates the line number for a given offset\n     * @return Returns the line number within the active editor document or -1\n     */\n    public abstract int getLineForOffset(FileObject file, int offset);\n    /**\n     * Calculates the offset for a given line number\n     * @return Returns the offset for the provided file and line number or -1\n     */\n    public abstract int getOffsetForLine(FileObject file, int line);\n    /**\n     * Returns the project the currently activated document belongs to\n     * @return The most active project or null\n     */\n    public abstract Lookup.Provider getCurrentProject();\n    /**\n     * Returns the tuple of start/end selection offset in the currently activated editor\n     * @return Tuple [startOffset, endOffset] or [-1, -1] if there is no selection\n     */\n    public abstract int[] getSelectionOffsets();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/IconsProvider.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.spi;\n\nimport java.awt.Image;\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.openide.util.ImageUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class IconsProvider {\n\n    /**\n     * Returns an Image instance according to the provided key.\n     *\n     * @param key image key\n     * @return Image instance according to the provided key or null if no image is provided for the key by this provider\n     */\n    public abstract Image getImage(String key);\n\n    /**\n     * Returns path to image resource without leading slash according to the provided key.\n     *\n     * @param key image key\n     * @return path to image resource without leading slash according to the provided key or null if no image is provided for the key by this provider\n     */\n    public abstract String getResource(String key);\n\n\n    /**\n     * Basic implementation of a simple IconsProvider supporting statically defined and dynamically generated images.\n     */\n    public static abstract class Basic extends IconsProvider {\n\n        private Map<String, String> images;\n\n        @Override\n        public final Image getImage(String key) {\n            String resource = getResource(key);\n            if (resource == null) return getDynamicImage(key);\n            else return ImageUtilities.loadImage(resource, true);\n        }\n\n        @Override\n        public final String getResource(String key) {\n            return getImageCache().get(key);\n        }\n\n        private Map<String, String> getImageCache() {\n            synchronized (this) {\n                if (images == null) {\n                    images = new HashMap<String, String>() {\n                        public String put(String key, String value) {\n                            return super.put(key, getImagePath(value));\n                        }\n                    };\n                    initStaticImages(images);\n                }\n            }\n            return images;\n        }\n        \n        protected String getImagePath(String imageFile) {\n            String packagePrefix = getClass().getPackage().getName().\n                                   replace('.', '/') + \"/\"; // NOI18N\n            return packagePrefix + imageFile;\n        }\n\n        protected void initStaticImages(Map<String, String> cache) {}\n\n        protected Image getDynamicImage(String key) { return null; }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/JavaPlatformManagerProvider.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.spi;\n\nimport java.util.List;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic abstract class JavaPlatformManagerProvider {\n\n    /** Gets an list of JavaPlatformProvider objects registered in the IDE.\n     * @return the array of java platform definitions.\n     */\n    public abstract List<JavaPlatformProvider> getPlatforms();\n\n    /**\n     * Get the \"default platform\", meaning the JDK on which profiler itself is running.\n     * @return the default platform, if it can be found, or null\n     */\n    public abstract JavaPlatformProvider getDefaultPlatform();\n\n    /**\n     * Shows java platforms customizer\n     */\n    public abstract void showCustomizer();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/JavaPlatformProvider.java",
    "content": "/*\n * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.spi;\n\nimport java.util.Map;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic abstract class JavaPlatformProvider {\n\n    /**\n     * @return  a descriptive, human-readable name of the platform\n     */\n    public abstract String getDisplayName();\n\n    /** Gets the java platform system properties.\n     * @return the java platform system properties\n     */\n    public abstract Map<String,String> getSystemProperties();\n\n    /** Gets the java platform properties.\n     * @return the java platform properties\n     */\n    public abstract Map<String,String> getProperties();\n\n\n    /** Gets a path to java executable for specified platform.\n     * Errors when obtaining the java executable will be reported to the user and null will be returned.\n     *\n     * @return A path to java executable or null if not found\n     */\n    public abstract String getPlatformJavaFile();\n\n    /**\n     * @return  a unique name of the platform\n     */\n    public abstract String getPlatformId();\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/LoadGenPlugin.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.spi;\n\nimport java.util.Collection;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.profiler.spi.LoadGenPlugin.Result;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\n\n\n/**\n * Defines an interface for accessing Load Generator features from the profiler UI\n * @author Jaroslav Bachorik\n */\npublic interface LoadGenPlugin {\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    public static interface Callback {\n        //~ Static fields/initializers -------------------------------------------------------------------------------------------\n\n        /**\n         * Null-object implementation\n         */\n        public static final Callback NULL = new Callback() {\n            public void afterStart(Result result) {\n                // do nothing\n            }\n\n            public void afterStop(Result result) {\n                // do nothing\n            }\n        };\n\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        /**\n         * Called after the start() method has been finished\n         * @param result Holds the result of the start() method\n         */\n        void afterStart(Result result);\n\n        /**\n         * Called after the stop() method has been finished\n         * @param result Holds the result of the stop() method\n         */\n        void afterStop(Result result);\n    }\n\n    //~ Enumerations -------------------------------------------------------------------------------------------------------------\n\n    public static enum Result {//~ Enumeration constant initializers ------------------------------------------------------------------------------------\n\n        FAIL, SUCCESS, TIMEOUT;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns the load generator status\n     */\n    boolean isRunning();\n\n    /**\n     * Retrieves the set of all supported file extensions; depends on the loadgenerator implementations installed in the system\n     */\n    Set<String> getSupportedExtensions();\n\n    /**\n     * Lists all supported loadgen scripts contained in the given project\n     * @param project The project to search for scripts\n     * @return Returns a list of FileObject instances representing loadgen scripts\n     */\n    Collection<FileObject> listScripts(Lookup.Provider project);\n\n    /**\n     * Runs a given loadgen script\n     * @param scriptPath The path to the script to be run\n     * @param callback Callback to be called upon finishing the start method; must not be null - us <code>Callback.NULL</code> instead\n     */\n    void start(String scriptPath, Callback callback);\n\n    /**\n     * Stops the last successfuly started load generator process\n     */\n    void stop();\n\n    /**\n     * Stops a load generator process givent the script path that started it\n     * @param scriptPath The path to the loadgen script\n     */\n    void stop(String scriptPath);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/ProfilerDialogsProvider.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.spi;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerDialogsProvider {\n\n    /**\n     * Displays a user-level info message. Can be run from any thread.\n     * @param message The info message to display\n     * @param caption The caption of the dialog, null for default\n     * @param details Optional message with detailed information, null for no details\n     */\n    public abstract void displayInfo(String message, String caption, String details);\n\n    /**\n     * Displays a user-level info message with a checkbox. Can be run from any thread.\n     * @param message The info message to display\n     * @param caption The caption of the dialog, null for default\n     * @param dnsaMessage The dnsa checkbox label, null for default\n     * @param key dialog ID, must be unique for each DNSA dialog\n     * @param dnsaDefault true if the dnsa checkbox should be selected by default, false otherwise\n     */\n    public abstract void displayInfoDNSA(String message, String caption, String dnsaMessage, String key, boolean dnsaDefault);\n\n    /** Displays a user-level warning message. Can be run from any thread.\n     * @param message The warning message to display\n     * @param caption The caption of the dialog, null for default\n     * @param details Optional message with detailed information, null for no details\n     */\n    public abstract void displayWarning(String message, String caption, String details);\n\n    /**\n     * Displays a user-level warning message with a checkbox. Can be run from any thread.\n     * @param message The warning message to display\n     * @param caption The caption of the dialog, null for default\n     * @param dnsaMessage The dnsa checkbox label, null for default\n     * @param key dialog ID, must be unique for each DNSA dialog\n     * @param dnsaDefault true if the dnsa checkbox should be selected by default, false otherwise\n     */\n    public abstract void displayWarningDNSA(String message, String caption, String dnsaMessage, String key, boolean dnsaDefault);\n    \n    /** Displays a user-level error message. Can be run from any thread.\n     * @param message The error message to display\n     * @param caption The caption of the dialog, null for default\n     * @param details Optional message with detailed information, null for no details\n     */\n    public abstract void displayError(String message, String caption, String details);\n    \n    /**\n     * Displays a user-level confirmation message. Can be run from any thread.\n     * @param message The confirmation message to display\n     * @param caption The caption of the dialog, null for default\n     * @param cancellable true if the dialog should display Cancel option, false otherwise\n     * @return Boolean.TRUE if the user has confirmed the dialog, Boolean.FALSE if the user has rejected the dialog, null if the dialog has been cancelled\n     */\n    public abstract Boolean displayConfirmation(String message, String caption, boolean cancellable);\n    \n    /**\n     * Displays a user-level confirmation message with a checkbox. Can be run from any thread.\n     * @param message The confirmation message to display\n     * @param caption The caption of the dialog, null for default\n     * @param dnsaMessage The dnsa checkbox label, null for default\n     * @param cancellable true if the dialog should display Cancel option, false otherwise\n     * @param key dialog ID, must be unique for each DNSA dialog\n     * @param dnsaDefault true if the dnsa checkbox should be selected by default, false otherwise\n     * @return Boolean.TRUE if the user has confirmed the dialog, Boolean.FALSE if the user has rejected the dialog, null if the dialog has been cancelled\n     */\n    public abstract Boolean displayConfirmationDNSA(String message, String caption, String dnsaMessage, boolean cancellable, String key, boolean dnsaDefault);\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/ProfilerStorageProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.spi;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.Properties;\nimport org.openide.filesystems.FileLock;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerStorageProvider {\n\n    // --- Global storage ------------------------------------------------------\n\n    /**\n     * Returns FileObject which can be used as a general settings storage.\n     * @param create If <code>true</code> the folder will be created if it doesn't exist yet\n     * @return FileObject which can be used as a general settings storage\n     * @throws IOException\n     */\n    public abstract FileObject getGlobalFolder(boolean create) throws IOException;\n\n    /**\n     * Loads the provided Properties from a global storage directory.\n     * @param properties Properties instance to load\n     * @param filename name of the file containing the persisted properties\n     * @throws IOException\n     */\n    public abstract void loadGlobalProperties(Properties properties, String filename) throws IOException;\n\n    /**\n     * Saves the provided Properties to a global storage directory.\n     * @param properties Properties instance to save\n     * @param filename name of the file containing the persisted properties\n     * @throws IOException\n     */\n    public abstract void saveGlobalProperties(Properties properties, String filename) throws IOException;\n\n    public abstract void deleteGlobalProperties(String filename) throws IOException;\n\n    // --- Project storage -----------------------------------------------------\n\n    /**\n     * Returns FileObject which can be used as a settings storage for the provided project or null if not available.\n     * \n     * @param project project context, for null GlobalStorage.getSettingsFolder(create) will be called\n     * @param create if <code>true</code> the storage will be created if not already available\n     * @return FileObject which can be used as a settings storage for the provided project or null if not available\n     * @throws IOException \n     */\n    public abstract FileObject getProjectFolder(Lookup.Provider project, boolean create) throws IOException;\n    \n    /**\n     * Returns project context for the provided settings storage FileObject or null if not resolvable.\n     * \n     * @param settingsFolder settings storage\n     * @return  project context for the provided settings storage FileObject or null if not resolvable\n     */\n    public abstract Lookup.Provider getProjectFromFolder(FileObject settingsFolder);\n    \n    /**\n     * Loads the provided Properties from the project storage directory.\n     * @param properties Properties instance to load\n     * @param filename name of the file containing the persisted properties\n     * @throws IOException \n     */\n    public abstract void loadProjectProperties(Properties properties, Lookup.Provider project, String filename) throws IOException;\n    \n    /**\n     * Saves the provided Properties to the project storage directory.\n     * @param properties Properties instance to save\n     * @param filename name of the file containing the persisted properties\n     * @throws IOException \n     */\n    public abstract void saveProjectProperties(Properties properties, Lookup.Provider project, String filename) throws IOException;\n    \n    public abstract void deleteProjectProperties(Lookup.Provider project, String filename) throws IOException;\n    \n    \n    // --- Base implementation -------------------------------------------------\n    \n    public static abstract class Abstract extends ProfilerStorageProvider {\n        \n        protected String EXT = \"xml\"; // NOI18N\n        \n        // --- Global storage --------------------------------------------------\n        \n        @Override\n        public void loadGlobalProperties(Properties properties, String filename) throws IOException {\n            FileObject folder = getGlobalFolder(false);\n            if (folder == null) return;\n\n            FileObject fo = folder.getFileObject(filename, EXT);\n            if (fo == null) return;\n\n            loadProperties(properties, fo);\n        }\n\n        @Override\n        public void saveGlobalProperties(Properties properties, String filename) throws IOException {\n            FileObject folder = getGlobalFolder(true);\n            FileObject fo = folder.getFileObject(filename, EXT);\n            if (fo == null) fo = folder.createData(filename, EXT);\n\n            saveProperties(properties, fo);\n        }\n\n        @Override\n        public void deleteGlobalProperties(String filename) throws IOException {\n            FileObject folder = getGlobalFolder(false);\n            FileObject fo = folder == null ? null : folder.getFileObject(filename, EXT);\n            if (fo != null) deleteProperties(fo);\n        }\n        \n        // --- Project storage -------------------------------------------------\n        \n        @Override\n        public void loadProjectProperties(Properties properties, Lookup.Provider project, String filename) throws IOException {\n            FileObject folder = getProjectFolder(project, false);\n            if (folder == null) return;\n\n            FileObject fo = folder.getFileObject(filename, EXT);\n            if (fo == null) {\n                // Convert PP storage .pp to .xml\n                fo = folder.getFileObject(filename, \"pp\"); // NOI18N\n                if (fo != null) {\n                    FileLock fol = fo.lock();\n                    try { fo.rename(fol, filename, EXT); }\n                    finally { fol.releaseLock(); }\n                }\n            }\n            if (fo == null) return;\n\n            loadProperties(properties, fo);\n        }\n\n        @Override\n        public void saveProjectProperties(Properties properties, Lookup.Provider project, String filename) throws IOException {\n            FileObject folder = getProjectFolder(project, true);\n            FileObject fo = folder.getFileObject(filename, EXT);\n            if (fo == null) fo = folder.createData(filename, EXT);\n\n            saveProperties(properties, fo);\n        }\n\n        @Override\n        public void deleteProjectProperties(Lookup.Provider project, String filename) throws IOException {\n            FileObject folder = getProjectFolder(project, false);\n            FileObject fo = folder == null ? null : folder.getFileObject(filename, EXT);\n            if (fo != null) deleteProperties(fo);\n        }\n        \n        // --- Implementation --------------------------------------------------\n    \n        protected void loadProperties(Properties properties, FileObject storage) throws IOException {\n            synchronized (this) {\n                InputStream is = storage.getInputStream();\n                try (BufferedInputStream bis = new BufferedInputStream(is)) {\n                    properties.loadFromXML(bis);\n                }\n            }\n        }\n\n        protected void saveProperties(Properties properties, FileObject storage) throws IOException {\n            synchronized (this) {\n                try (OutputStream os = storage.getOutputStream();\n                     BufferedOutputStream bos = new BufferedOutputStream(os)) {\n                    properties.storeToXML(bos, \"\"); // NOI18N\n                }\n            }\n        }\n\n        protected void deleteProperties(FileObject storage) throws IOException {\n            synchronized (this) {\n                storage.delete();\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/ProjectUtilitiesProvider.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.spi;\n\nimport java.util.Set;\nimport javax.swing.Icon;\nimport javax.swing.event.ChangeListener;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup.Provider;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic abstract class ProjectUtilitiesProvider {\n\n     /**\n     * Gets icon for given project.\n     * Usually determined by the project type.\n     * @param project project\n     * @return icon of the project.\n     */\n   public abstract Icon getIcon(Provider project);\n\n\n    /**Retrieves the current main project set in the IDE.\n     *\n     * @return the current main project or null if none\n     */\n    public abstract Provider getMainProject();\n\n    /**\n     * Get a human-readable display name for the project.\n     * May contain spaces, international characters, etc.\n     * @param project project\n     * @return a display name for the project\n     */\n    public abstract String getDisplayName(Provider project);\n\n    /**\n     * Gets an associated directory where the project metadata and possibly sources live.\n     * In the case of a typical Ant project, this is the top directory, not the\n     * project metadata subdirectory.\n     * @return a directory\n     */\n    public abstract FileObject getProjectDirectory(Provider project);\n\n    /**\n     * Gets a list of currently open projects.\n     *\n     * @return list of projects currently opened in the IDE's GUI; order not specified\n     */\n    public abstract Provider[] getOpenedProjects();\n\n    /**\n     * Returns true if the provided project has sub-projects.\n     *\n     * @param project a project\n     * @return true if the provided project has sub-projects, false otherwise\n     */\n    public abstract boolean hasSubprojects(Provider project);\n\n    /**\n     * Computes set of sub-projects of a project\n     * @param project a project\n     * @param subprojects map of sub-projects\n     */\n    public abstract void fetchSubprojects(Provider project, Set<Provider> subprojects);\n\n    /**\n     * Find the project, if any, which \"owns\" the given file.\n     * @param fobj the file (generally on disk)\n     * @return a project which contains it, or null if there is no known project containing it\n     */\n    public abstract Provider getProject(FileObject fobj);\n    \n    /**\n     * Adds a listener to be notified when set of open projects changes.\n     * @param listener listener to be added\n     */\n    public abstract void addOpenProjectsListener(ChangeListener listener);\n    \n    /**\n     * Removes a listener to be notified when set of open projects changes.\n     * @param listener listener to be removed\n     */\n    public abstract void removeOpenProjectsListener(ChangeListener listener);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/SessionListener.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.spi;\n\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.openide.util.Lookup;\n\n/**\n * A helper SPI interface for plugging in to the profiling session lifecycle\n *\n * @author Jaroslav Bachorik\n */\npublic interface SessionListener {\n    /**\n     * Default No-op implementation of {@linkplain SessionListener}\n     */\n    public static abstract class Adapter implements SessionListener {\n\n        @Override\n        public void onShutdown() {\n        }\n\n        @Override\n        public void onStartup(ProfilingSettings ps, Lookup.Provider p) {\n        }\n    }\n\n    /**\n     * Called on the profiling session startup\n     * @param ps The {@linkplain ProfilingSettings} used to start the session\n     * @param p The associated project\n     */\n    void onStartup(ProfilingSettings ps, Lookup.Provider p);\n\n    /**\n     * Called on the profiling session shutdown\n     */\n    void onShutdown();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/java/AbstractJavaProfilerSource.java",
    "content": "/*\n * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.spi.java;\n\nimport java.util.Collections;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceClassInfo;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceMethodInfo;\nimport org.openide.filesystems.FileObject;\n\n/**\n * An SPI for {@linkplain org.graalvm.visualvm.lib.profiler.api.java.JavaProfilerSource} functionality providers\n * @author Jaroslav Bachorik\n */\npublic interface AbstractJavaProfilerSource {\n    final public static AbstractJavaProfilerSource NULL = new AbstractJavaProfilerSource() {\n\n        @Override\n        public boolean isTest(FileObject fo) {\n            return false;\n        }\n\n        @Override\n        public boolean isApplet(FileObject fo) {\n            return false;\n        }\n\n        @Override\n        public SourceClassInfo getTopLevelClass(FileObject fo) {\n            return null;\n        }\n\n        @Override\n        public Set<SourceClassInfo> getClasses(FileObject fo) {\n            return Collections.EMPTY_SET;\n        }\n\n        @Override\n        public Set<SourceClassInfo> getMainClasses(FileObject fo) {\n            return Collections.EMPTY_SET;\n        }\n\n        @Override\n        public Set<SourceMethodInfo> getConstructors(FileObject fo) {\n            return Collections.EMPTY_SET;\n        }\n\n        @Override\n        public SourceClassInfo getEnclosingClass(FileObject fo, int position) {\n            return null;\n        }\n\n        @Override\n        public SourceMethodInfo getEnclosingMethod(FileObject fo, int position) {\n            return null;\n        }\n\n        @Override\n        public boolean isInstanceOf(FileObject fo, String[] classNames, boolean allRequired) {\n            return false;\n        }\n\n        @Override\n        public boolean isInstanceOf(FileObject fo, String className) {\n            return false;\n        }\n\n        @Override\n        public boolean hasAnnotation(FileObject fo, String[] annotationNames, boolean allRequired) {\n            return false;\n        }\n\n        @Override\n        public boolean hasAnnotation(FileObject fo, String annotation) {\n            return false;\n        }\n\n        @Override\n        public boolean isOffsetValid(FileObject fo, int offset) {\n            return false;\n        }\n\n        @Override\n        public SourceMethodInfo resolveMethodAtPosition(FileObject fo, int position) {\n            return null;\n        }\n\n        @Override\n        public SourceClassInfo resolveClassAtPosition(FileObject fo, int position, boolean resolveField) {\n            return null;\n        }\n    };\n    \n    /**\n     * @param fo The source file. Must not be NULL\n     * @return Returns true if the source represents a junit tet\n     */\n    boolean isTest(FileObject fo);\n\n    /**\n     * @param fo The source file. Must not be NULL\n     * @return Returns true if the source is a java applet\n     */\n    boolean isApplet(FileObject fo);\n\n    /**\n     * @param fo The source file. Must not be NULL\n     * @return Returns {@linkplain SourceClassInfo} of a top level class\n     */\n    SourceClassInfo getTopLevelClass(FileObject fo);\n    \n    /**\n     * Lists all top level classes contained in the source\n     * @param fo The source file. Must not be NULL\n     * @return Returns a set of {@linkplain SourceClassInfo} instances from a source\n     */\n    Set<SourceClassInfo> getClasses(FileObject fo);\n\n    /**\n     * Lists all main classes contained in the source\n     * @param fo The source file. Must not be NULL\n     * @return Returns a set of {@linkplain SourceClassInfo} instances from a source\n     */\n    Set<SourceClassInfo> getMainClasses(FileObject fo);\n    \n    /**\n     * Lists all constructors contained in the source\n     * @param fo The source file. Must not be NULL\n     * @return Returns a set of {@linkplain SourceMethodInfo} instances from the source\n     */\n    Set<SourceMethodInfo> getConstructors(FileObject fo);\n\n    /**\n     * Finds a class present on the given position in the source\n     * @param fo The source file. Must not be NULL\n     * @param position The position in the source\n     * @return Returns a {@linkplain SourceClassInfo} for the class present on the given position\n     */\n    SourceClassInfo getEnclosingClass(FileObject fo, final int position);\n\n    /**\n     * Finds a method present on the given position in the source\n     * @param fo The source file. Must not be NULL\n     * @param position The position in the source\n     * @return Returns a {@linkplain SourceMethodInfo} for the method present on the given position\n     */\n    SourceMethodInfo getEnclosingMethod(FileObject fo, final int position);\n\n    /**\n     * Checks whether the source represents any or all of the provided superclasses/interfaces\n     * @param fo The source file. Must not be NULL\n     * @param classNames A list of required superclasses/interfaces\n     * @param allRequired Require all(TRUE)/any(FALSE) provided superclasses/interfaces to match\n     * @return Returns TRUE if the source represents any or all of the provided classes/interfaces\n     */\n    boolean isInstanceOf(FileObject fo, String[] classNames, boolean allRequired);\n\n    /**\n     * Checks whether the source represents the provided superclass/interface\n     * @param fo The source file. Must not be NULL\n     * @param className The required superclass/interface\n     * @return Returns TRUE if the source represents the provided superclass/interface\n     */\n    boolean isInstanceOf(FileObject fo, String className);\n\n    /**\n     * Checks whether the source contains any/all provided annotations\n     * @param fo The source file. Must not be NULL\n     * @param annotationNames A list of required annotations\n     * @param allRequired Require all(TRUE)/any(FALSE) provided annotations to match\n     * @return Returns TRUE if the source contains any or all of the provided annotations\n     */\n    boolean hasAnnotation(FileObject fo, String[] annotationNames, boolean allRequired);\n\n    /**\n     * Checks whether the source contains the provided annotation\n     * @param fo The source file. Must not be NULL\n     * @param annotation The required annotation\n     * @return Returns TRUE if the source contains the provided annotation\n     */\n    boolean hasAnnotation(FileObject fo, String annotation);\n\n    /**\n     * Is the given offset valid within a particular source\n     * @param fo The source file. Must not be NULL\n     * @param offset The offset to check\n     * @return Returns TRUE if the offset is valid for the source\n     */\n    boolean isOffsetValid(FileObject fo, int offset);\n    \n    /**\n     * Resolves a method at the given position<br>\n     * In order to resolve the method there must be the method definition or invocation\n     * at the given position.\n     * @param fo The source file. Must not be NULL\n     * @param position The position to check for method definition or invocation\n     * @return Returns the {@linkplain SourceMethodInfo} for the method definition or invocation at the given position or NULL if there is none\n     */\n    SourceMethodInfo resolveMethodAtPosition(FileObject fo, int position);\n    \n    /**\n     * Resolves a class at the given position<br>\n     * In order to resolve the class there must be the class definition or reference\n     * at the given position.\n     * @param fo The source file. Must not be NULL\n     * @param position The position to check for class definition or reference\n     * @param resolveField Should the class be resolved from a variable type too?\n     * @return Returns the {@linkplain SourceClassInfo} for the class definition or reference at the given position or NULL if there is none\n     */\n    SourceClassInfo resolveClassAtPosition(FileObject fo, int position, boolean resolveField);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/java/GoToSourceProvider.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.spi.java;\n\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic abstract class GoToSourceProvider {\n    /**\n     * Implementors will provide a specific functionality to open a source code\n     * @param project The associated project\n     * @param className The class name\n     * @param methodName The method name or NULL\n     * @param signature The signature or NULL\n     * @param line The line number or {@linkplain Integer#MIN_VALUE}\n     * @return Returns TRUE if the infrastructure was able to open the source code, FALSE otherwise\n     */\n    public abstract boolean openSource(Lookup.Provider project, String className, String methodName, String signature, int line);\n\n    /**\n     * Implementors will provide a specific functionality to open a source code file on a given position\n     * @param srcFile The source file to be opened\n     * @param offset The position to open the file at\n     * @return  Returns TRUE if such file exists and the offset is valid\n     */\n    public abstract boolean openFile(FileObject srcFile, int offset);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/java/ProfilerTypeUtilsProvider.java",
    "content": "/*\n * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.spi.java;\n\nimport java.util.Collection;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.profiler.api.java.ProfilerTypeUtils;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourceClassInfo;\nimport org.graalvm.visualvm.lib.profiler.api.java.SourcePackageInfo;\n\n/**\n * An SPI for {@linkplain ProfilerTypeUtils} functionality\n * @author Jaroslav Bachorik\n */\npublic abstract class ProfilerTypeUtilsProvider {\n    /**\n     *\n     * @param className A fully qualified class name\n     * @return Returns a resolved class or NULL\n     */\n    abstract public SourceClassInfo resolveClass(String className);\n\n    /**\n     * @return Returns a list of all main classes present in the project\n     */\n    abstract public Collection<SourceClassInfo> getMainClasses();\n\n    /**\n     *\n     * @param subprojects A flag indicating whether subprojects should be taken into account\n     * @param scope A {@linkplain SourcePackageInfo.Scope} - SOURCE or DEPENDENCIES\n     * @return Returns a list of project's packages\n     */\n    abstract public Collection<SourcePackageInfo> getPackages(boolean subprojects, SourcePackageInfo.Scope scope);\n\n    /**\n     * Case insensitive regexp class search\n     * @param pattern Class pattern as a regular expression\n     * @param scope A {@linkplain SourcePackageInfo.Scope} - SOURCE or DEPENDENCIES\n     * @return Returns a collection of classes matching the given pattern\n     */\n    public Collection<SourceClassInfo> findClasses(String pattern, Set<SourcePackageInfo.Scope> scope) {\n        throw new UnsupportedOperationException();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/project/Bundle.properties",
    "content": "# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/project/ProjectContentsSupportProvider.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.spi.project;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.openide.filesystems.FileObject;\n\n/**\n * Provider of support for configuring profiling roots and instrumentation filter from a project.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProjectContentsSupportProvider {\n\n    /**\n     * Returns array of profiling roots for the defined context.\n     *\n     * @param profiledClassFile profiled file or null for profiling the entire project\n     * @param profileSubprojects true if profiling also project's subprojects, false for profiling just the project\n     * @return array of profiling roots for the defined context\n     */\n    public abstract ClientUtils.SourceCodeSelection[] getProfilingRoots(FileObject profiledClassFile, boolean profileSubprojects);\n\n    /**\n     * Returns instrumentation filter for the defined context.\n     *\n     * @param profileSubprojects true if profiling also project's subprojects, false for profiling just the project\n     * @return instrumentation filter for the defined context\n     */\n    public abstract String getInstrumentationFilter(boolean profileSubprojects);\n\n    /**\n     * Resets the ProjectContentsSupport instance after submitting or cancelling the Select Profiling Task dialog.\n     */\n    public abstract void reset();\n\n\n//    public static class Basic extends ProjectContentsSupportProvider {\n//\n//        private static final SourceCodeSelection[] EMPTY_SELECTION = new ClientUtils.SourceCodeSelection[0];\n//\n//        @Override\n//        public SourceCodeSelection[] getProfilingRoots(FileObject profiledClassFile, boolean profileSubprojects) {\n//            return EMPTY_SELECTION;\n//        }\n//\n//        @Override\n//        public SimpleFilter getInstrumentationFilter(boolean profileSubprojects) {\n//            return SimpleFilter.NO_FILTER;\n//        }\n//\n//    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.api/src/org/graalvm/visualvm/lib/profiler/spi/project/ProjectProfilingSupportProvider.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.spi.project;\n\nimport org.graalvm.visualvm.lib.common.SessionSettings;\nimport org.graalvm.visualvm.lib.profiler.api.JavaPlatform;\nimport org.openide.filesystems.FileObject;\n\n/**\n * Provider of support for profiling projects.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProjectProfilingSupportProvider {\n\n    /**\n     * Returns true if profiling a project is supported.\n     *\n     * @return true if profiling a project is supported, false otherwise\n     */\n    public abstract boolean isProfilingSupported();\n\n    /**\n     * Returns true if attaching to a running project is supported.\n     *\n     * @return true if attaching to a running project is supported, false otherwise.\n     */\n    public abstract boolean isAttachSupported();\n\n    /**\n     * Returns true if profiling the provided file is supported.\n     *\n     * @param fo file\n     * @return true if profiling the provided file is supported, false otherwise\n     */\n    public abstract boolean isFileObjectSupported(FileObject fo);\n\n    /**\n     * Returns true if Profiling Points can be processed by this project.\n     *\n     * @return true if Profiling Points can be processed by this project, false otherwise.\n     */\n    public abstract boolean areProfilingPointsSupported();\n\n    /**\n     * Returns the Java platform configured for running the project.\n     *\n     * @return Java platform configured for running the project\n     */\n    public abstract JavaPlatform getProjectJavaPlatform();\n\n    /**\n     * Returns true if the project is configured and properly set up to be profiled (e.g. main class has a main method etc.).\n     *\n     * @param profiledClassFile profiled file or null for profiling the entire project\n     * @return true if the project is configured and properly set up to be profiled, false otherwise\n     */\n    public abstract boolean checkProjectCanBeProfiled(FileObject profiledClassFile);\n\n    /**\n     * Configures project-specific session settings.\n     * \n     * @param ss session settings\n     */\n    public abstract void setupProjectSessionSettings(SessionSettings ss);\n    \n    /**\n     * Allows to start a profiling session directly by the ProjectProfilingSupport instance.\n     * \n     * @param profiledClassFile profiled file\n     * @param isTest true if profiledClassFile is a test, false otherwise\n     * @return true if the ProjectProfilingSupport instance started a profiling session, false otherwise\n     */\n    public abstract boolean startProfilingSession(FileObject profiledClassFile, boolean isTest);\n    \n    \n    public static class Basic extends ProjectProfilingSupportProvider {\n\n        @Override\n        public boolean isProfilingSupported() {\n            return false;\n        }\n\n        @Override\n        public boolean isAttachSupported() {\n            return false;\n        }\n\n        @Override\n        public boolean isFileObjectSupported(FileObject fo) {\n            return false;\n        }\n        \n        @Override\n        public boolean areProfilingPointsSupported() {\n            return false;\n        }\n\n        @Override\n        public JavaPlatform getProjectJavaPlatform() {\n            return null;\n        }\n\n        @Override\n        public boolean checkProjectCanBeProfiled(FileObject profiledClassFile) {\n            return true;\n        }\n\n        @Override\n        public void setupProjectSessionSettings(SessionSettings ss) {\n        }\n\n        @Override\n        public boolean startProfilingSession(FileObject profiledClassFile, boolean isTest) {\n            return false;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project basedir=\".\" default=\"netbeans\" name=\"profiler.attach\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.lib.profiler.attach</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.lib.profiler.attach/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/lib/profiler/attach/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.5\n\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.lib.profiler.attach-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/nbproject/genfiles.properties",
    "content": "# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=e5853d0f\nnbproject/build-impl.xml.script.CRC32=414d89dc\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/nbproject/project.properties",
    "content": "# Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\nis.autoload=true\njavac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.lib.profiler.attach</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.common</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.13</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.15</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.45</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.11</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.3</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.lib.profiler</friend>\n                <package>org.graalvm.visualvm.lib.profiler.attach</package>\n                <package>org.graalvm.visualvm.lib.profiler.attach.providers</package>\n                <package>org.graalvm.visualvm.lib.profiler.attach.spi</package>\n                <package>org.graalvm.visualvm.lib.profiler.attach.steps</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/../..\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/src/org/graalvm/visualvm/lib/profiler/attach/AttachWizard.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.attach;\n\nimport org.graalvm.visualvm.lib.common.AttachSettings;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic abstract class AttachWizard {\n    public static AttachWizard getDefault() {\n        return Lookup.getDefault().lookup(AttachWizard.class);\n    }\n\n    public static boolean isAvailable() {\n        return getDefault() != null;\n    }\n\n    public abstract boolean configured(AttachSettings initialSettings);\n\n    public abstract AttachSettings configure(AttachSettings initialSettings, boolean partially);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/src/org/graalvm/visualvm/lib/profiler/attach/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Name=Java Profiler (Attach Support)\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/src/org/graalvm/visualvm/lib/profiler/attach/dialog/AttachDialog.java",
    "content": "/*\n * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.attach.dialog;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.MouseEvent;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextField;\nimport javax.swing.RowFilter;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.event.TableModelEvent;\nimport javax.swing.event.TableModelListener;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.lib.common.AttachSettings;\nimport org.graalvm.visualvm.lib.common.integration.IntegrationUtils;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.jps.JpsProxy;\nimport org.graalvm.visualvm.lib.jfluid.jps.RunningVM;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.swing.ActionPopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.FilteringToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.attach.AttachWizard;\nimport org.graalvm.visualvm.lib.profiler.attach.spi.AttachStepsProvider;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"AttachDialog_JavaApplication=Java application\", // NOI18N\n    \"AttachDialog_Caption=Attach Settings\", // NOI18N\n    \"AttachDialog_NoSteps=No steps available.\", // NOI18N\n    \"AttachDialog_SelectProcess=&Select the process for profiling:\", // NOI18N\n    \"AttachDialog_SelectProcessReload=&Select the process for profiling (reloading...):\", // NOI18N\n    \"AttachDialog_ReloadProcesses=Reload processes\", // NOI18N\n    \"AttachDialog_ShowDetails=Show process details\", // NOI18N\n    \"AttachDialog_ConnectToSelected=&Always connect to selected process\", // NOI18N\n    \"# {0} - process name\",   // NOI18N\n    \"AttachDialog_ConnectToProcess=&Always connect to \\\"{0}\\\"\", // NOI18N\n    \"AttachDialog_FilterProcesses=Filter processes\", // NOI18N\n    \"AttachDialog_Profile=&Profile:\", // NOI18N\n    \"AttachDialog_Hostname=Host&name:\", // NOI18N\n    \"AttachDialog_OsJvm=&OS & JVM:\", // NOI18N\n    \"AttachDialog_LocalRunningProcess=Already running local Java process\", // NOI18N\n    \"AttachDialog_LocalStartedProcess=Manually started local Java process\", // NOI18N\n    \"AttachDialog_RemoteStartedProcess=Manually started remote Java process\", // NOI18N\n    \"AttachDialog_UnknownProcess=Java process\", // NOI18N\n    \"AttachDialog_ColumnName=Name\", // NOI18N\n    \"AttachDialog_ColumnPid=PID\", // NOI18N\n    \"AttachDialog_RowPid=PID:\", // NOI18N\n    \"AttachDialog_RowMainClass=Main class:\", // NOI18N\n    \"AttachDialog_RowArguments=Arguments:\", // NOI18N\n    \"AttachDialog_RowJvmArguments=JVM Arguments:\", // NOI18N\n    \"AttachDialog_RowJvmFlags=JVM Flags:\", // NOI18N\n    \"AttachDialog_DetailsUnknown=unknown\", // NOI18N\n    \"AttachDialog_DetailsNone=none\", // NOI18N\n    \"AttachDialog_BtnClose=Close\", // NOI18N\n    \"# {0} - process name\",   // NOI18N\n    \"AttachDialog_DetailsCaption=Details of {0}\", // NOI18N\n    \"AttachDialog_Steps=P&erform the following steps to start profiling:\", // NOI18N\n    \"AttachDialog_ProcessNameTtp=Process name\", // NOI18N\n    \"AttachDialog_ProcessIdTtp=Process identifier\" // NOI18N\n})\n@ServiceProvider(service = AttachWizard.class)\npublic class AttachDialog extends AttachWizard {\n    \n    private AttachStepsProvider currentProvider;\n    private Panel panel;\n    \n    \n    @Override\n    public boolean configured(AttachSettings settings) {\n        if (settings == null) return false; // no settings provided\n        \n        if (settings.isRemote()) {\n            String host = settings.getHost();\n            return host != null && !host.trim().isEmpty(); // remote settings valid if host provided\n        } else {\n            if (settings.isDirect()) return true; // local direct settings always valid\n            \n            int pid = settings.getPid();\n            String name = settings.getProcessName();\n            \n            if (pid == -1 || name == null) return false; // no preselected process for dynamic attach\n            \n            assert !SwingUtilities.isEventDispatchThread();\n            \n            RunningVM[] vms = JpsProxy.getRunningVMs();\n            if (vms == null || vms.length == 0) return false; // no locally running processes for dynamic attach\n            \n            List<RunningVM> targets = new ArrayList<>();\n            for (RunningVM vm : vms)\n                if (getProcessName(vm.getMainClass()).equals(name))\n                    targets.add(vm); // all processes with the preferred process name ready for profiling\n            \n            if (targets.isEmpty()) return false; // no locally running process with the preselected process name\n            \n            if (settings.isAutoSelectProcess() && targets.size() == 1) {\n                settings.setPid(targets.get(0).getPid());\n                return true; // exactly one preferred process found for dynamic attach\n            }\n            \n            for (RunningVM vm : targets) if (vm.getPid() == pid) return true; // preselected process found\n        }\n        \n        return false;\n    }\n\n    @Override\n    public AttachSettings configure(AttachSettings settings, boolean partially) {\n        if (settings == null)\n            settings = new AttachSettings();\n        \n        // Configure default settings\n        if (settings.getTargetType().isEmpty()) {\n            settings.setDirect(false);\n            settings.setDynamic16(true);\n            settings.setRemote(false);\n        }\n        \n        // Configure implicit settings\n        settings.setTargetType(Bundle.AttachDialog_JavaApplication());\n        settings.setServerType(Bundle.AttachDialog_JavaApplication());\n                \n//        // Workaround for remote OS\n//        if (settings.isRemote()) settings.setHostOS(null);\n        \n        panel = new Panel();\n        panel.setup(settings);\n        DialogDescriptor dd = new DialogDescriptor(panel, Bundle.AttachDialog_Caption());\n        if (!partially) {\n            dd.setValid(false);\n            panel.setDisplayer(dd);\n        }\n        Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n        d.setVisible(true);\n        AttachSettings result = dd.getValue() == DialogDescriptor.OK_OPTION ?\n                                panel.getSettings() : null;\n        if (currentProvider != null) currentProvider.removeChangeListener(panel);\n        currentProvider = null;\n        panel = null;\n        return result;\n    }\n    \n    private String steps(AttachSettings settings) {\n        Collection<? extends AttachStepsProvider> providers =\n                Lookup.getDefault().lookupAll(AttachStepsProvider.class);\n        \n        if (currentProvider != null) currentProvider.removeChangeListener(panel);\n        \n        for (AttachStepsProvider provider : providers) {\n            String steps = provider.getSteps(settings);\n            if (steps != null) {\n                currentProvider = provider;\n                currentProvider.addChangeListener(panel);\n                return steps;\n            }\n        }\n        \n        currentProvider = null;\n        \n        return Bundle.AttachDialog_NoSteps();\n    }\n    \n    \n    private static final String ATTACH_WIZARD_HELPCTX = \"AttachDialog.HelpCtx\"; // NOI18N\n    private static final HelpCtx HELP_CTX = new HelpCtx(ATTACH_WIZARD_HELPCTX);\n    \n    private class Panel extends JPanel implements HelpCtx.Provider, ChangeListener {\n        \n        private static final int VISIBLE_ROWS = 9;\n        \n        private ActionPopupButton modeButton;\n        private JTextField hostname;\n        private ActionPopupButton os;\n        private HTMLTextArea steps;\n        private JCheckBox autoSelect;\n        \n        private DialogDescriptor displayer;\n        private AttachSettings as;\n        \n        private String selectedName;\n        private int selectedPid = -1;\n        \n        private boolean updatingUI = false;\n        \n        \n        Panel() {\n            initComponents();\n        }\n        \n        void setDisplayer(DialogDescriptor displayer) {\n            this.displayer = displayer;\n        }\n        \n        void setup(AttachSettings as) {\n            this.as = new AttachSettings();\n            as.copyInto(this.as);\n            \n            updatingUI = true;\n            \n            if (as.isRemote()) modeButton.selectAction(3);\n            else if (as.isDirect()) modeButton.selectAction(2);\n            else modeButton.selectAction(0);\n            modeButton.getSelectedAction().actionPerformed(null);\n            \n            hostname.setText(as.getHost());\n            String hostOS = as.getHostOS();\n            for (Action action : os.getActions())\n                if (action != null && action.getValue(Action.NAME).equals(hostOS)) {\n                    os.selectAction(action);\n                    break;\n                }\n\n            selectedName = as.getProcessName();\n            selectedPid = as.getPid();\n            autoSelect.setSelected(as.isAutoSelectProcess());\n            updateAutoSelect();\n            \n            updatingUI = false;\n            \n            updateSteps();\n        }\n        \n        AttachSettings getSettings() {\n            int mode = modeButton.getSelectedIndex();\n            as.setRemote(mode == 3);\n            if (as.isRemote()) {\n                as.setDirect(true);\n                as.setDynamic16(false);\n                as.setHost(hostname.getText().trim());\n                as.setHostOS(os.getSelectedAction().getValue(Action.NAME).toString());\n            } else {\n                as.setDirect(mode == 2);\n                as.setDynamic16(mode == 0);\n                as.setHost(\"\"); // NOI18N\n                as.setHostOS(null);\n                as.setProcessName(selectedName);\n                as.setPid(selectedPid);\n                as.setAutoSelectProcess(autoSelect.isSelected());\n            }\n            return as;\n        }\n        \n        private void initComponents() {\n            \n            final JLabel processesHint = new JLabel(\"\", JLabel.LEADING); // NOI18N\n            Mnemonics.setLocalizedText(processesHint, Bundle.AttachDialog_SelectProcess());\n            processesHint.setBorder(BorderFactory.createEmptyBorder(0, 0, 3, 0));\n            \n            final ProcessesModel processesModel = new ProcessesModel();\n            \n            final ProfilerTable processes = new ProfilerTable(processesModel, true, true, null){\n                public String getToolTipText(MouseEvent event) {\n                    int row = rowAtPoint(event.getPoint());\n                    if (row == -1) return null;\n                    \n                    row = convertRowIndexToModel(row);\n                    return \"<html>\" + getDetails((RunningVM)processesModel.getValueAt(row, -1)) + \"</html>\"; // NOI18N\n                }\n                public Point getToolTipLocation(MouseEvent event) {\n                    int row = rowAtPoint(event.getPoint());\n                    if (row == -1) return null;\n                    \n                    Rectangle rect = getCellRect(row, 0, false);\n                    return new Point(event.getX() + 15, rect.y + rect.height + 2);\n                }\n            };\n            processesHint.setLabelFor(processes);\n            processes.setMainColumn(0);\n            processes.setFitWidthColumn(0);\n            processes.setDefaultSortOrder(SortOrder.ASCENDING);\n            processes.setSortColumn(0);\n            processes.setColumnToolTips(new String[] { Bundle.AttachDialog_ProcessNameTtp(),\n                                                       Bundle.AttachDialog_ProcessIdTtp() });\n            LabelRenderer processRenderer = new LabelRenderer();\n            processes.setColumnRenderer(0, processRenderer);\n            LabelRenderer pidRenderer = new LabelRenderer();\n            pidRenderer.setHorizontalAlignment(LabelRenderer.TRAILING);\n            processes.setColumnRenderer(1, pidRenderer);\n            pidRenderer.setValue(processes.getColumnName(1), -1);\n            int w = pidRenderer.getPreferredSize().width;\n            pidRenderer.setValue(\"9999999\", -1); // NOI18N\n            w = Math.max(w, pidRenderer.getPreferredSize().width);\n            processes.setDefaultColumnWidth(1, w + 10);\n            Dimension prefSize = processes.getPreferredSize();\n            prefSize.height = processes.getRowHeight() * VISIBLE_ROWS;\n            prefSize.height += processes.getTableHeader().getPreferredSize().height;\n            processes.setPreferredScrollableViewportSize(prefSize);\n            ProfilerTableContainer processesContainer = new ProfilerTableContainer(processes, true, null);\n            \n            final JButton refresh = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    processesModel.refresh();\n                }\n            };\n            refresh.setToolTipText(Bundle.AttachDialog_ReloadProcesses());\n            \n            processesModel.addTableModelListener(new TableModelListener() {\n                public void tableChanged(TableModelEvent e) {\n                    boolean enabled = !processesModel.isRefreshing();\n                    processes.setEnabled(enabled);\n                    refresh.setEnabled(enabled);\n                    Mnemonics.setLocalizedText(processesHint, enabled ?\n                                Bundle.AttachDialog_SelectProcess() :\n                                Bundle.AttachDialog_SelectProcessReload());\n                    if (processesModel.isFirstRefresh() && selectedName != null) {\n                        SwingUtilities.invokeLater(new Runnable() { // wait for the table to refresh its model\n                            public void run() {\n                                int _nameC = processes.convertColumnIndexToView(0);\n                                int _pidC = processes.convertColumnIndexToView(1);\n                                for (int row = 0; row < processes.getRowCount(); row++) {\n                                    if (selectedName.equals(processes.getValueAt(row, _nameC)) &&\n                                        selectedPid == (Integer)processes.getValueAt(row, _pidC)) {\n                                        processes.selectRow(row, true);\n                                        return;\n                                    }\n                                }\n                                if (!autoSelect.isSelected()) selectedName = null;\n                                selectedPid = -1;\n                                updateAutoSelect();\n                            }\n                        });\n                    }\n                }\n            });\n            \n            final JButton details = new JButton(Icons.getIcon(GeneralIcons.INFO)) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    super.fireActionPerformed(e);\n                    showDetails((RunningVM)processes.getSelectedValue(-1));\n                }\n            };\n            details.setToolTipText(Bundle.AttachDialog_ShowDetails());\n            \n            autoSelect = new JCheckBox() {\n                private final RowFilter rowFilter = new RowFilter() {\n                    public boolean include(RowFilter.Entry entry) {\n                        return selectedName == null || selectedName.equals(entry.getValue(0));\n                    }\n                };\n                protected void fireItemStateChanged(ItemEvent event) {\n                    super.fireItemStateChanged(event);\n                    if (isSelected()) processes.addRowFilter(rowFilter);\n                    else processes.removeRowFilter(rowFilter);\n                    updateAutoSelect();\n                }\n            };\n            Mnemonics.setLocalizedText(autoSelect, Bundle.AttachDialog_ConnectToSelected());\n            autoSelect.setEnabled(false);\n            \n            processes.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n                public void valueChanged(ListSelectionEvent e) {\n                    if (processes.getSelectedRow() == -1) {\n                        selectedPid = -1;\n                    } else {\n                        selectedPid = (Integer)processes.getSelectedValue(1);\n                        selectedName = getProcessName(processes.getSelectedValue(0).toString());\n                    }\n                    updateDetails(details);\n                    updateAutoSelect();\n                    updateDisplayer();\n                }\n            });\n            \n            FilteringToolbar toolbar = new FilteringToolbar(Bundle.AttachDialog_FilterProcesses()) {\n                private GenericFilter _filter;\n                private final RowFilter rowFilter = new RowFilter() {\n                    public boolean include(RowFilter.Entry entry) {\n                        return _filter.passes(entry.getValue(0).toString());\n                    }\n                };\n                protected void filterChanged() {\n                    _filter = isAll() ? null : getFilter();\n                    if (_filter != null) processes.addRowFilter(rowFilter);\n                    else processes.removeRowFilter(rowFilter);\n                }\n            };\n            toolbar.add(Box.createHorizontalStrut(2));\n            toolbar.addSeparator();\n            toolbar.add(Box.createHorizontalStrut(1));\n            toolbar.add(refresh);\n            toolbar.add(Box.createHorizontalStrut(2));\n            toolbar.add(details);\n            toolbar.add(Box.createHorizontalStrut(3));\n            toolbar.add(autoSelect);\n            \n            final JPanel dynamicContent = new JPanel(new BorderLayout());\n            dynamicContent.add(processesHint, BorderLayout.NORTH);\n            dynamicContent.add(processesContainer, BorderLayout.CENTER);\n            dynamicContent.add(toolbar, BorderLayout.SOUTH);\n            \n            \n            \n            JLabel stepsHint = new JLabel(\"\", JLabel.LEADING); // NOI18N\n            Mnemonics.setLocalizedText(stepsHint, Bundle.AttachDialog_Steps());\n            \n            steps = new HTMLTextArea() {\n                protected void showURL(URL url) {\n                    if (currentProvider != null) {\n                        final String action = url.toString();\n                        final AttachSettings settings = new AttachSettings();\n                        getSettings().copyInto(settings);\n                        RequestProcessor.getDefault().post(new Runnable() {\n                            public void run() {\n                                currentProvider.handleAction(action, settings);\n                            }\n                        });\n                    }\n                }\n            };\n            stepsHint.setLabelFor(steps);\n            JScrollPane stepsScroll = new JScrollPane(steps);\n            \n            final JPanel directContent = new JPanel(new BorderLayout(3, 3));\n            directContent.add(stepsHint, BorderLayout.NORTH);\n            directContent.add(stepsScroll, BorderLayout.CENTER);\n            \n            final JPanel remoteSettings = new JPanel(new GridBagLayout());\n            GridBagConstraints c;\n            \n            final JPanel content = new JPanel(new BorderLayout());\n            content.add(dynamicContent, BorderLayout.CENTER);\n            \n            setLayout(new GridBagLayout());\n            \n            JLabel profile = new JLabel();\n            Mnemonics.setLocalizedText(profile, Bundle.AttachDialog_Profile());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 0;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(10, 10, 0, 0);\n            add(profile, c);\n            \n            class ModeAction extends AbstractAction {\n                private final boolean remote;\n                private final boolean hasSteps;\n                ModeAction(String name, boolean remote, boolean hasSteps) {\n                    super(name);\n                    this.remote = remote;\n                    this.hasSteps = hasSteps;\n                }\n                public void actionPerformed(ActionEvent e) {\n                    content.removeAll();\n                    remoteSettings.setVisible(remote);\n                    if (hasSteps) updateSteps();\n                    content.add(hasSteps ? directContent : dynamicContent, BorderLayout.CENTER);\n                    content.invalidate();\n                    content.revalidate();\n                    content.repaint();\n                    updateDisplayer();\n                }\n            }\n            modeButton = new ActionPopupButton(new ModeAction(Bundle.AttachDialog_LocalRunningProcess(), false, false),\n                                               null,\n                                               new ModeAction(Bundle.AttachDialog_LocalStartedProcess(), false, true),\n                                               new ModeAction(Bundle.AttachDialog_RemoteStartedProcess(), true, true));\n            modeButton.setPopupAlign(SwingConstants.EAST);\n            profile.setLabelFor(modeButton);\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = 0;\n            c.weightx = 1;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.insets = new Insets(10, 5, 0, 10);\n            add(modeButton, c);\n            \n            \n            \n            JLabel hostnameLabel = new JLabel();\n            Mnemonics.setLocalizedText(hostnameLabel, Bundle.AttachDialog_Hostname());\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 0;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(0, 0, 0, 0);\n            remoteSettings.add(hostnameLabel, c);\n            \n            hostname = new JTextField();\n            hostnameLabel.setLabelFor(hostname);\n            hostname.setText(\"https://netbeans.org/features/index.html\"); // NOI18N\n            c = new GridBagConstraints();\n            c.gridx = 1;\n            c.gridy = 0;\n            c.weightx = 1;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, 5, 0, 20);\n            remoteSettings.add(hostname, c);\n            \n            JLabel osJvmLabel = new JLabel();\n            Mnemonics.setLocalizedText(osJvmLabel, Bundle.AttachDialog_OsJvm());\n            c = new GridBagConstraints();\n            c.gridx = 2;\n            c.gridy = 0;\n            c.anchor = GridBagConstraints.WEST;\n            c.insets = new Insets(0, 0, 0, 0);\n            remoteSettings.add(osJvmLabel, c);\n            \n            class OsAction extends AbstractAction {\n                OsAction(String name) { super(name); }\n                public void actionPerformed(ActionEvent e) { updateSteps(); }\n            }\n            os = new ActionPopupButton(new OsAction(IntegrationUtils.PLATFORM_WINDOWS_OS),\n                                       new OsAction(IntegrationUtils.PLATFORM_WINDOWS_AMD64_OS),\n                                       new OsAction(IntegrationUtils.PLATFORM_WINDOWS_CVM),\n                                       null,\n                                       new OsAction(IntegrationUtils.PLATFORM_LINUX_OS),\n                                       new OsAction(IntegrationUtils.PLATFORM_LINUX_AMD64_OS),\n                                       new OsAction(IntegrationUtils.PLATFORM_LINUX_ARM_OS),\n                                       new OsAction(IntegrationUtils.PLATFORM_LINUX_ARM_VFP_HFLT_OS),\n                                       new OsAction(IntegrationUtils.PLATFORM_LINUX_ARM_AARCH64_OS),\n                                       new OsAction(IntegrationUtils.PLATFORM_LINUX_CVM),\n                                       null,\n                                       new OsAction(IntegrationUtils.PLATFORM_MAC_OS),\n                                       null,\n                                       new OsAction(IntegrationUtils.PLATFORM_SOLARIS_SPARC_OS),\n                                       new OsAction(IntegrationUtils.PLATFORM_SOLARIS_SPARC64_OS),\n                                       new OsAction(IntegrationUtils.PLATFORM_SOLARIS_INTEL_OS),\n                                       new OsAction(IntegrationUtils.PLATFORM_SOLARIS_AMD64_OS));\n            osJvmLabel.setLabelFor(os);\n            os.setPopupAlign(SwingConstants.EAST);\n            c = new GridBagConstraints();\n            c.gridx = 3;\n            c.gridy = 0;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(0, 5, 0, 0);\n            remoteSettings.add(os, c);\n            \n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 1;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.insets = new Insets(5, 10, 0, 10);\n            add(remoteSettings, c);\n            \n            \n            \n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 10;\n            c.weighty = 1;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.fill = GridBagConstraints.BOTH;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.insets = new Insets(20, 10, 10, 10);\n            add(content, c);\n            \n            setPreferredSize(getPreferredSize());\n            hostname.setText(\"\"); // NOI18N\n            \n            processesModel.refresh();\n            updateDetails(details);\n            updateAutoSelect();\n        }\n        \n        private void updateSteps() {\n            if (updatingUI) return;\n            steps.setText(steps(getSettings()));\n            // Make sure the first step is visible\n            steps.setCaretPosition(0);\n            // Really make sure the first step is visible\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { steps.setCaretPosition(0); }\n            });\n        }\n\n        @Override\n        public HelpCtx getHelpCtx() {\n            return HELP_CTX;\n        }\n\n        @Override\n        public void stateChanged(ChangeEvent e) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { updateSteps(); }\n            });\n        }\n        \n        private void updateDetails(JButton info) {\n            info.setEnabled(selectedPid != -1);\n        }\n        \n        private void updateAutoSelect() {\n            if (!autoSelect.isSelected() && selectedPid == -1) selectedName = null;\n            autoSelect.setEnabled(autoSelect.isSelected() || selectedPid != -1);\n            Mnemonics.setLocalizedText(autoSelect, selectedName == null ? Bundle.AttachDialog_ConnectToSelected() :\n                                                   Bundle.AttachDialog_ConnectToProcess(selectedName));\n        }\n        \n        private void updateDisplayer() {\n            if (displayer == null) return;\n            \n            if (modeButton.getSelectedIndex() != 0) {\n                displayer.setValid(true);\n                return;\n            }\n            \n            displayer.setValid(selectedPid != -1);\n        }\n        \n    }\n    \n    \n    private static String getProcessName(String name) {\n        name = name == null ? null : name.trim();\n        return name == null || name.isEmpty() ? Bundle.AttachDialog_UnknownProcess() : name;\n    }\n    \n    private static String escapedText(String text, String replace) {\n        if (text != null) text = text.trim();\n        if (text == null || text.isEmpty()) return \"&lt;\" + replace + \"&gt;\"; // NOI18N\n        return text;\n    }\n    \n    private static void configureScrollBar(final JScrollBar s) {\n        s.getModel().addChangeListener(new ChangeListener() {\n            public void stateChanged(ChangeEvent e) { s.setEnabled(s.getVisibleAmount() < s.getMaximum()); }\n        });\n    }\n    \n    private static void showDetails(RunningVM vm) {\n        HTMLTextArea area = new HTMLTextArea();\n        JScrollPane areaScroll = new JScrollPane(area, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,\n                                                       JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);\n        areaScroll.setBorder(BorderFactory.createEmptyBorder());\n        areaScroll.setViewportBorder(BorderFactory.createEmptyBorder());\n        areaScroll.setPreferredSize(new Dimension(500, 260));\n        configureScrollBar(areaScroll.getVerticalScrollBar());\n        configureScrollBar(areaScroll.getHorizontalScrollBar());\n        \n        area.setText(getDetails(vm));\n        area.setCaretPosition(0);\n        \n        HelpCtx helpCtx = new HelpCtx(\"ProcessDetails.HelpCtx\"); //NOI18N\n        JButton close = new JButton(Bundle.AttachDialog_BtnClose());\n        close.setDefaultCapable(true);\n        DialogDescriptor dd = new DialogDescriptor(areaScroll, Bundle.AttachDialog_DetailsCaption(getProcessName(vm.getMainClass())),\n                              true, new Object[] { close }, close, DialogDescriptor.DEFAULT_ALIGN, helpCtx, null);\n        Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n        d.pack();\n        d.setVisible(true);\n    }\n    \n    private static String getDetails(RunningVM vm) {\n        StringBuilder buffer = new StringBuilder();\n        \n        buffer.append(\"<table cellspacing=\\\"3\\\" cellpadding=\\\"0\\\" width=\\\"400\\\">\"); //NOI18N\n        \n        // --- PID -------------------------------------------------------------\n        buffer.append(\"<tr>\"); //NOI18N\n        \n        buffer.append(\"<td valign='top'><nobr><b>\"); //NOI18N\n        buffer.append(Bundle.AttachDialog_RowPid());\n        buffer.append(\"</b>&nbsp;&nbsp;&nbsp;</nobr></td>\"); //NOI18N\n        \n        buffer.append(\"<td width=\\\"100%\\\">\"); //NOI18N\n        buffer.append(vm.getPid());\n        buffer.append(\"</td>\"); //NOI18N\n        \n        buffer.append(\"</tr>\"); //NOI18N\n        \n        // --- Main Class ------------------------------------------------------\n        \n        buffer.append(\"<tr>\"); //NOI18N\n        \n        buffer.append(\"<td valign='top'><nobr><b>\"); //NOI18N\n        buffer.append(Bundle.AttachDialog_RowMainClass());\n        buffer.append(\"</b>&nbsp;&nbsp;&nbsp;</nobr></td>\"); //NOI18N\n        \n        buffer.append(\"<td width=\\\"100%\\\">\"); //NOI18N\n        buffer.append(escapedText(vm.getMainClass(), Bundle.AttachDialog_DetailsUnknown()));\n        buffer.append(\"</td>\"); //NOI18N\n        \n        buffer.append(\"</tr>\"); //NOI18N\n        \n        // --- Arguments -------------------------------------------------------\n        \n        buffer.append(\"<tr>\"); //NOI18N\n        \n        buffer.append(\"<td valign='top'><nobr><b>\"); //NOI18N\n        buffer.append(Bundle.AttachDialog_RowArguments());\n        buffer.append(\"</b>&nbsp;&nbsp;&nbsp;</nobr></td>\"); //NOI18N\n        \n        buffer.append(\"<td width=\\\"100%\\\">\"); //NOI18N\n        buffer.append(escapedText(vm.getMainArgs(), Bundle.AttachDialog_DetailsNone()));\n        buffer.append(\"</td>\"); //NOI18N\n        \n        buffer.append(\"</tr>\"); //NOI18N\n        \n        // --- VM Arguments ----------------------------------------------------\n        \n        buffer.append(\"<tr>\"); //NOI18N\n        \n        buffer.append(\"<td valign='top'><nobr><b>\"); //NOI18N\n        buffer.append(Bundle.AttachDialog_RowJvmArguments());\n        buffer.append(\"</b>&nbsp;&nbsp;&nbsp;</nobr></td>\"); //NOI18N\n        \n        buffer.append(\"<td width=\\\"100%\\\">\"); //NOI18N\n        buffer.append(escapedText(vm.getVMArgs(), Bundle.AttachDialog_DetailsNone()));\n        buffer.append(\"</td>\"); //NOI18N\n        \n        buffer.append(\"</tr>\"); //NOI18N\n        \n        // --- VM Flags --------------------------------------------------------\n        \n        buffer.append(\"<tr>\"); //NOI18N\n        \n        buffer.append(\"<td valign='top'><nobr><b>\"); //NOI18N\n        buffer.append(Bundle.AttachDialog_RowJvmFlags());\n        buffer.append(\"</b>&nbsp;&nbsp;&nbsp;</nobr></td>\"); //NOI18N\n        \n        buffer.append(\"<td width=\\\"100%\\\">\"); //NOI18N\n        buffer.append(escapedText(vm.getVMFlags(), Bundle.AttachDialog_DetailsNone()));\n        buffer.append(\"</td>\"); //NOI18N\n        \n        buffer.append(\"</tr>\"); //NOI18N\n        \n        buffer.append(\"</table>\"); //NOI18N\n        \n        return buffer.toString();\n    }\n    \n    \n    private static class ProcessesModel extends AbstractTableModel {\n        \n        private RunningVM[] vms;\n        private boolean refreshing;\n        private boolean firstRefresh = true;\n        \n        void refresh() {\n            refreshing = true;\n            fireTableDataChanged();\n            new RequestProcessor(\"Processes refresher\").post(new Runnable() { // NOI18N\n                public void run() {\n                    final RunningVM[] _vms = JpsProxy.getRunningVMs();\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            vms = _vms;\n                            refreshing = false;\n                            fireTableDataChanged();\n                            firstRefresh = false;\n                        }\n                    });\n                }\n            }, 500);\n        }\n        \n        boolean isRefreshing() {\n            return refreshing;\n        }\n        \n        boolean isFirstRefresh() {\n            return !refreshing && firstRefresh;\n        }\n        \n        public String getColumnName(int columnIndex) {\n            if (columnIndex == 0) {\n                return Bundle.AttachDialog_ColumnName();\n            } else if (columnIndex == 1) {\n                return Bundle.AttachDialog_ColumnPid();\n            }\n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (columnIndex == 0) {\n                return String.class;\n            } else if (columnIndex == 1) {\n                return Integer.class;\n            }\n            return null;\n        }\n\n        public int getRowCount() {\n            return vms == null ? 0 : vms.length;\n        }\n\n        public int getColumnCount() {\n            return 2;\n        }\n\n        public Object getValueAt(int rowIndex, int columnIndex) {\n            if (columnIndex == 0) {\n                return getProcessName(vms[rowIndex].getMainClass());\n            } else if (columnIndex == 1) {\n                return vms[rowIndex].getPid();\n            } else if (columnIndex == -1) {\n                return vms[rowIndex];\n            }\n            return null;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/src/org/graalvm/visualvm/lib/profiler/attach/providers/RemotePackExporter.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.attach.providers;\n\nimport java.io.IOException;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.graalvm.visualvm.lib.profiler.attach.spi.AbstractRemotePackExporter;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\n@NbBundle.Messages({\n    \"RemotePackExporter_GeneratingRemotePack=Generating Remote Pack to {0}\" // NOI18N\n})\nfinal public class RemotePackExporter {\n\n    private static final class Singleton {\n\n        private static final RemotePackExporter INSTANCE = new RemotePackExporter();\n    }\n\n    public static RemotePackExporter getInstance() {\n        return Singleton.INSTANCE;\n    }\n\n    private AbstractRemotePackExporter impl = null;\n\n    private RemotePackExporter() {\n        impl = Lookup.getDefault().lookup(AbstractRemotePackExporter.class);\n    }\n\n    public String export(final String exportPath, final String hostOS, final String jvm) throws IOException {\n        if (impl == null) {\n            throw new IOException();\n        }\n\n        ProgressHandle ph = ProgressHandle.createHandle(\n                Bundle.RemotePackExporter_GeneratingRemotePack(impl.getRemotePackPath(exportPath, hostOS)));\n        ph.setInitialDelay(500);\n        ph.start();\n        try {\n            return impl.export(exportPath, hostOS, jvm);\n        } finally {\n            ph.finish();\n        }\n    }\n\n    public void export(String hostOS, final String jvm) throws IOException {\n        export(null, hostOS, jvm);\n    }\n\n    public boolean isAvailable() {\n        return impl != null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/src/org/graalvm/visualvm/lib/profiler/attach/providers/TargetPlatformEnum.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.attach.providers;\n\nimport org.graalvm.visualvm.lib.common.integration.IntegrationUtils;\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class TargetPlatformEnum {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final String[] jvmNames = new String[] {\n                                                 IntegrationUtils.PLATFORM_JAVA_50, IntegrationUtils.PLATFORM_JAVA_60,\n                                                 IntegrationUtils.PLATFORM_JAVA_70, IntegrationUtils.PLATFORM_JAVA_80,\n                                                 IntegrationUtils.PLATFORM_JAVA_90, IntegrationUtils.PLATFORM_JAVA_100,\n                                                 IntegrationUtils.PLATFORM_JAVA_110,IntegrationUtils.PLATFORM_JAVA_120,\n                                                 IntegrationUtils.PLATFORM_JAVA_130,IntegrationUtils.PLATFORM_JAVA_140,\n                                                 IntegrationUtils.PLATFORM_JAVA_150,IntegrationUtils.PLATFORM_JAVA_160,\n                                                 IntegrationUtils.PLATFORM_JAVA_170,IntegrationUtils.PLATFORM_JAVA_180,\n                                                 IntegrationUtils.PLATFORM_JAVA_190,IntegrationUtils.PLATFORM_JAVA_200,\n                                                 IntegrationUtils.PLATFORM_JAVA_210,IntegrationUtils.PLATFORM_JAVA_220,\n                                                 IntegrationUtils.PLATFORM_JAVA_230,IntegrationUtils.PLATFORM_JAVA_240,\n                                                 IntegrationUtils.PLATFORM_JAVA_250,IntegrationUtils.PLATFORM_JAVA_CVM,\n                                             };\n    public static final TargetPlatformEnum JDK5 = new TargetPlatformEnum(0);\n    public static final TargetPlatformEnum JDK6 = new TargetPlatformEnum(1);\n    public static final TargetPlatformEnum JDK7 = new TargetPlatformEnum(2);\n    public static final TargetPlatformEnum JDK8 = new TargetPlatformEnum(3);\n    public static final TargetPlatformEnum JDK9 = new TargetPlatformEnum(4);\n    public static final TargetPlatformEnum JDK10 = new TargetPlatformEnum(5);\n    public static final TargetPlatformEnum JDK11 = new TargetPlatformEnum(6);\n    public static final TargetPlatformEnum JDK12 = new TargetPlatformEnum(7);\n    public static final TargetPlatformEnum JDK13 = new TargetPlatformEnum(8);\n    public static final TargetPlatformEnum JDK14 = new TargetPlatformEnum(9);\n    public static final TargetPlatformEnum JDK15 = new TargetPlatformEnum(10);\n    public static final TargetPlatformEnum JDK16 = new TargetPlatformEnum(11);\n    public static final TargetPlatformEnum JDK17 = new TargetPlatformEnum(12);\n    public static final TargetPlatformEnum JDK18 = new TargetPlatformEnum(13);\n    public static final TargetPlatformEnum JDK19 = new TargetPlatformEnum(14);\n    public static final TargetPlatformEnum JDK20 = new TargetPlatformEnum(15);\n    public static final TargetPlatformEnum JDK21 = new TargetPlatformEnum(16);\n    public static final TargetPlatformEnum JDK22 = new TargetPlatformEnum(17);\n    public static final TargetPlatformEnum JDK23 = new TargetPlatformEnum(18);\n    public static final TargetPlatformEnum JDK24 = new TargetPlatformEnum(19);\n    public static final TargetPlatformEnum JDK25 = new TargetPlatformEnum(20);\n    public static final TargetPlatformEnum JDK_CVM = new TargetPlatformEnum(21);\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private int jvmIndex = 0;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private TargetPlatformEnum(int index) {\n        this.jvmIndex = index;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public boolean equals(Object obj) {\n        if ((obj == null) || !(obj instanceof TargetPlatformEnum)) {\n            return false;\n        }\n\n        return ((TargetPlatformEnum) obj).jvmIndex == this.jvmIndex;\n    }\n\n    @Override\n    public int hashCode() {\n        return jvmIndex;\n    }\n\n    public static Iterator<TargetPlatformEnum> iterator() {\n        List<TargetPlatformEnum> jvmList = new ArrayList<>(22);\n        jvmList.add(JDK5);\n        jvmList.add(JDK6);\n        jvmList.add(JDK7);\n        jvmList.add(JDK8);\n        jvmList.add(JDK9);\n        jvmList.add(JDK10);\n        jvmList.add(JDK11);\n        jvmList.add(JDK12);\n        jvmList.add(JDK13);\n        jvmList.add(JDK14);\n        jvmList.add(JDK15);\n        jvmList.add(JDK16);\n        jvmList.add(JDK17);\n        jvmList.add(JDK18);\n        jvmList.add(JDK19);\n        jvmList.add(JDK20);\n        jvmList.add(JDK21);\n        jvmList.add(JDK22);\n        jvmList.add(JDK23);\n        jvmList.add(JDK24);\n        jvmList.add(JDK25);\n        jvmList.add(JDK_CVM);\n\n        return jvmList.listIterator();\n    }\n\n    public String toString() {\n        return jvmNames[this.jvmIndex];\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/src/org/graalvm/visualvm/lib/profiler/attach/spi/AbstractRemotePackExporter.java",
    "content": "/*\n * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.attach.spi;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.common.integration.IntegrationUtils;\nimport org.graalvm.visualvm.lib.profiler.attach.providers.TargetPlatformEnum;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\nabstract public class AbstractRemotePackExporter {\n    private static final Map<String, String> scriptMapper = new HashMap<String, String>() {\n        {\n            put(IntegrationUtils.PLATFORM_LINUX_AMD64_OS, \"linuxamd64\"); //NOI18N\n            put(IntegrationUtils.PLATFORM_LINUX_OS, \"linux\"); //NOI18N\n            put(IntegrationUtils.PLATFORM_LINUX_ARM_OS, \"linuxarm\"); //NOI18N\n            put(IntegrationUtils.PLATFORM_LINUX_ARM_VFP_HFLT_OS, \"linuxarmvfphflt\"); //NOI18N\n            put(IntegrationUtils.PLATFORM_LINUX_ARM_AARCH64_OS, \"linuxaarch64\"); //NOI18N\n            put(IntegrationUtils.PLATFORM_MAC_OS, \"mac\"); //NOI18N\n            put(IntegrationUtils.PLATFORM_SOLARIS_AMD64_OS, \"solamd64\"); //NOI18N\n            put(IntegrationUtils.PLATFORM_SOLARIS_INTEL_OS, \"solx86\"); //NOI18N\n            put(IntegrationUtils.PLATFORM_SOLARIS_SPARC_OS, \"solsparc\"); //NOI18N\n            put(IntegrationUtils.PLATFORM_SOLARIS_SPARC64_OS, \"solsparcv9\"); //NOI18N\n            put(IntegrationUtils.PLATFORM_WINDOWS_AMD64_OS, \"winamd64\"); //NOI18N\n            put(IntegrationUtils.PLATFORM_WINDOWS_OS, \"win\"); //NOI18N\n        }\n    };\n    private static final Map<String, String> jdkMapper = new HashMap<String, String>() {\n        {\n            // NOTE: 15 is used to only generate Ant task name which always ends with '-15'\n            put(TargetPlatformEnum.JDK5.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK6.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK7.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK8.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK9.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK10.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK11.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK12.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK13.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK14.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK15.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK16.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK17.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK18.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK19.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK20.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK21.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK22.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK23.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK24.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK25.toString(), \"15\"); //NOI18N\n            put(TargetPlatformEnum.JDK_CVM.toString(), \"cvm\"); //NOI18N\n        }\n    };\n    \n    final protected String getPlatformShort(String hostOS) {\n        return scriptMapper.get(hostOS);\n    }\n    \n    final protected String getJVMShort(String jvm) {\n        return jdkMapper.get(jvm);\n    }\n    \n    abstract public String export(String exportPath, String hostOS, String jvm) throws IOException;\n    abstract public String getRemotePackPath(String exportPath, String hostOS);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/src/org/graalvm/visualvm/lib/profiler/attach/spi/AttachStepsProvider.java",
    "content": "/*\n * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.attach.spi;\n\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.common.AttachSettings;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class AttachStepsProvider {\n\n    public String getSteps(AttachSettings settings) { return null; }\n\n    public void handleAction(String action, AttachSettings settings) {}\n\n    public void addChangeListener(ChangeListener listener) {}\n\n    public void removeChangeListener(ChangeListener listener) {}\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.attach/src/org/graalvm/visualvm/lib/profiler/attach/steps/BasicAttachStepsProvider.java",
    "content": "/*\n * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.attach.steps;\n\nimport java.awt.Toolkit;\nimport java.awt.datatransfer.StringSelection;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport javax.swing.JFileChooser;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.common.AttachSettings;\nimport org.graalvm.visualvm.lib.common.integration.IntegrationUtils;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.attach.providers.RemotePackExporter;\nimport org.graalvm.visualvm.lib.profiler.attach.spi.AttachStepsProvider;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"AttachDialog_CopiedToClipboard=Profiler parameter(s) copied to clipboard\", // NOI18N\n    \"AttachDialog_RemotePackDialogCaption=Choose Target Folder\", // NOI18N\n    \"AttachDialog_RemotePackSaved=Remote profiling pack saved to {0}\", // NOI18N\n    \"AttachDialog_Steps_Step=Step {0}:\", // NOI18N\n    \"AttachDialog_Steps_CopyToClipboard=copy to clipboard\", // NOI18N\n    \"AttachDialog_Steps_MakeSureStarted=Make sure the target application has been started by user {0} and is running using Java 6+.\", // NOI18N\n    \"AttachDialog_Steps_SubmitSelectProcess=Submit this dialog and click the Attach button to select the target application process.\", // NOI18N\n    \"AttachDialog_Steps_EnsureCorrectJava=Make sure the target application is configured to run using {0}.\", // NOI18N\n    \"AttachDialog_Steps_Java6=Java 6+\", // NOI18N\n    \"AttachDialog_Steps_Java6_32b=Java 6+, 32bit\", // NOI18N\n    \"AttachDialog_Steps_Java6_64b=Java 6+, 64bit\", // NOI18N\n    \"AttachDialog_Steps_Java5=Java 5\", // NOI18N\n    \"AttachDialog_Steps_Java5_32b=Java 5, 32bit\", // NOI18N\n    \"AttachDialog_Steps_Java5_64b=Java 5, 64bit\", // NOI18N\n    \"AttachDialog_Steps_JavaCvm=CVM\", // NOI18N\n    \"AttachDialog_Steps_JavaSeEmbedded=Java SE Embedded\", // NOI18N\n    \"#{0}, {1} provide begin/end of HTML link\",\n    \"AttachDialog_Steps_SwitchToJava6Up={0}Click{1} to update steps for profiling JDK 6+ applications.\", // NOI18N\n    \"#{0}, {1} provide begin/end of HTML link\",\n    \"AttachDialog_Steps_SwitchToJava5={0}Click{1} to update steps for profiling JDK 5 applications.\", // NOI18N\n    \"#{0}, {1} provide begin/end of HTML link\",\n    \"AttachDialog_Steps_SwitchTo32BitArch={0}Click{1} to update steps for profiling 32bit applications.\", // NOI18N\n    \"#{0}, {1} provide begin/end of HTML link\",\n    \"AttachDialog_Steps_SwitchTo64BitArch={0}Click{1} to update steps for profiling 64bit applications.\", // NOI18N\n    \"AttachDialog_Steps_StartApplication=Start the target application. The process will wait for the profiler to connect.\", // NOI18N\n    \"AttachDialog_Steps_SubmitUnblock=Submit this dialog and click the Attach button to connect to the target application and resume its execution.\", // NOI18N\n    \"AttachDialog_Steps_AddParameters=Add the following parameter(s) to the application startup script\", // NOI18N\n    \"AttachDialog_Steps_RunCalibrateScript=If you have not run profiling on the remote system yet, run the {0} script first to calibrate the profiler.\", // NOI18N\n    \"AttachDialog_Steps_CreateRemotePack=If you have not done it before <a href={0}>create a Remote profiling pack</a> for the selected OS & JVM and upload it to the remote system. Remote profiling pack root directory will be referred to as {1}.\" // NOI18N\n})\n@ServiceProvider(service = AttachStepsProvider.class)\npublic class BasicAttachStepsProvider extends AttachStepsProvider {\n    \n    protected static final String LINK_CLIPBOARD = \"file:/clipboard\"; // NOI18N\n    protected static final String LINK_REMOTEPACK = \"file:/remotepack\"; // NOI18N\n    protected static final String LINK_JDK5 = \"file:/jdk5\"; // NOI18N\n    protected static final String LINK_JDK6UP = \"file:/jdk6up\"; // NOI18N\n    protected static final String LINK_32ARCH = \"file:/32arch\"; // NOI18N\n    protected static final String LINK_64ARCH = \"file:/64arch\"; // NOI18N\n    \n    protected String currentJDK = LINK_JDK6UP;\n    protected String currentARCH = LINK_64ARCH;\n    \n    \n    private final Set<ChangeListener> listeners = new HashSet<>();\n    \n    public synchronized final void addChangeListener(ChangeListener listener) {\n        listeners.add(listener);\n    }\n    \n    public synchronized final void removeChangeListener(ChangeListener listener) {\n        listeners.remove(listener);\n    }\n    \n    protected synchronized final void fireChange(ChangeEvent e) {\n        if (e == null) e = new ChangeEvent(this);\n        for (ChangeListener listener : listeners) listener.stateChanged(e);\n    }\n    \n    \n    public String getSteps(AttachSettings settings) {\n        if (settings.isRemote()) return remoteDirectSteps(settings);\n        else if (settings.isDirect()) return localDirectSteps(settings);\n        else return localDynamicSteps(settings);\n    }\n    \n    public void handleAction(String action, AttachSettings settings) {\n        if (LINK_CLIPBOARD.equals(action)) copyParameters(settings);\n        else if (LINK_REMOTEPACK.equals(action)) createRemotePack(settings);\n        else if (LINK_JDK5.equals(action)) switchToJDK5();\n        else if (LINK_JDK6UP.equals(action)) switchToJDK6Up();\n        else if (LINK_32ARCH.equals(action)) switchTo32ARCH();\n        else if (LINK_64ARCH.equals(action)) switchTo64ARCH();\n    }\n    \n    \n    protected void switchToJDK5() {\n        currentJDK = LINK_JDK5;\n        fireChange(null);\n    }\n    \n    protected void switchToJDK6Up() {\n        currentJDK = LINK_JDK6UP;\n        fireChange(null);\n    }\n    \n    protected void switchTo32ARCH() {\n        currentARCH = LINK_32ARCH;\n        fireChange(null);\n    }\n    \n    protected void switchTo64ARCH() {\n        currentARCH = LINK_64ARCH;\n        fireChange(null);\n    }\n    \n    \n    protected String localDynamicSteps(AttachSettings settings) {\n        StringBuilder b = new StringBuilder();\n        b.append(\"<div>\"); // NOI18N\n        b.append(\"<b>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_Step(1));\n        b.append(\"</b> \"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_MakeSureStarted(System.getProperty(\"user.name\"))); // NOI18N\n        b.append(\"</div>\"); // NOI18N\n        b.append(\"<br/>\"); // NOI18N\n        b.append(\"<div>\"); // NOI18N\n        b.append(\"<b>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_Step(2));\n        b.append(\"</b> \"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_SubmitSelectProcess());\n        b.append(\"</div>\"); // NOI18N\n        return b.toString();\n    }\n    \n    protected String localDirectSteps(AttachSettings settings) {\n        StringBuilder b = new StringBuilder();\n        b.append(\"<div>\"); // NOI18N\n        b.append(\"<b>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_Step(1));\n        b.append(\"</b> \"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_EnsureCorrectJava(\n                getCorrectJavaMsg(currentJDK, currentARCH)));\n        String linkStart = \" <a href='\"; // NOI18N\n        linkStart += LINK_JDK6UP.equals(currentJDK) ? LINK_JDK5 : LINK_JDK6UP;\n        linkStart += \"'>\"; // NOI18N\n        String linkEnd = \"</a> \"; // NOI18N\n        b.append(LINK_JDK6UP.equals(currentJDK) ?\n                Bundle.AttachDialog_Steps_SwitchToJava5(linkStart, linkEnd) :\n                Bundle.AttachDialog_Steps_SwitchToJava6Up(linkStart, linkEnd));\n        if (!IntegrationUtils.PLATFORM_MAC_OS.equals(IntegrationUtils.getLocalPlatform(-1))) {\n            linkStart = \" <a href='\"; // NOI18N\n            linkStart += LINK_64ARCH.equals(currentARCH) ? LINK_32ARCH : LINK_64ARCH;\n            linkStart += \"'>\"; // NOI18N\n            b.append(LINK_64ARCH.equals(currentARCH) ?\n                    Bundle.AttachDialog_Steps_SwitchTo32BitArch(linkStart, linkEnd) :\n                    Bundle.AttachDialog_Steps_SwitchTo64BitArch(linkStart, linkEnd));\n        }\n        b.append(\"</div>\"); // NOI18N\n        b.append(\"<br/>\"); // NOI18N\n        b.append(\"<div>\"); // NOI18N\n        b.append(\"<b>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_Step(2));\n        b.append(\"</b> \"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_AddParameters());\n        b.append(\" (<a href='\"); // NOI18N\n        b.append(LINK_CLIPBOARD);\n        b.append(\"'>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_CopyToClipboard());\n        b.append(\"</a>):\"); // NOI18N\n        b.append(\"</div>\"); // NOI18N\n        b.append(\"<pre>\"); // NOI18N\n        b.append(parameters(settings));\n        b.append(\"</pre>\"); // NOI18N\n        b.append(\"<br/>\"); // NOI18N\n        b.append(\"<div>\"); // NOI18N\n        b.append(\"<b>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_Step(3));\n        b.append(\"</b> \"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_StartApplication());\n        b.append(\"</div>\"); // NOI18N\n        b.append(\"<br/>\"); // NOI18N\n        b.append(\"<div>\"); // NOI18N\n        b.append(\"<b>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_Step(4));\n        b.append(\"</b> \"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_SubmitUnblock());\n        b.append(\"</div>\"); // NOI18N\n        return b.toString();\n    }\n    \n    protected String remoteDirectSteps(AttachSettings settings) {\n        StringBuilder b = new StringBuilder();\n        b.append(\"<div>\"); // NOI18N\n        b.append(\"<b>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_Step(1));\n        b.append(\"</b> \"); // NOI18N\n        if (isCVMJVM(settings)) {\n            b.append(Bundle.AttachDialog_Steps_EnsureCorrectJava(\n                    Bundle.AttachDialog_Steps_JavaCvm()));\n        } else if (isARMJVM(settings)) {\n            b.append(Bundle.AttachDialog_Steps_EnsureCorrectJava(\n                    Bundle.AttachDialog_Steps_JavaSeEmbedded()));\n        } else {\n            b.append(LINK_JDK6UP.equals(currentJDK) ?\n                    Bundle.AttachDialog_Steps_EnsureCorrectJava(\n                    Bundle.AttachDialog_Steps_Java6()) :\n                    Bundle.AttachDialog_Steps_EnsureCorrectJava(\n                    Bundle.AttachDialog_Steps_Java5()));\n            String linkStart = \" <a href='\"; // NOI18N\n            linkStart += LINK_JDK6UP.equals(currentJDK) ? LINK_JDK5 : LINK_JDK6UP;\n            linkStart += \"'>\"; // NOI18N\n            String linkEnd = \"</a> \"; // NOI18N\n            b.append(LINK_JDK6UP.equals(currentJDK) ?\n                    Bundle.AttachDialog_Steps_SwitchToJava5(linkStart, linkEnd) :\n                    Bundle.AttachDialog_Steps_SwitchToJava6Up(linkStart, linkEnd));\n        }\n        b.append(\"</div>\"); // NOI18N\n        b.append(\"<br/>\"); // NOI18N\n        b.append(\"<div>\"); // NOI18N\n        b.append(\"<b>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_Step(2));\n        b.append(\"</b> \"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_CreateRemotePack(\"'\" + LINK_REMOTEPACK + \"'\", \"<code>&lt;remote&gt;</code>\")); // NOI18N\n        b.append(\"</div>\"); // NOI18N\n        b.append(\"<br/>\"); // NOI18N\n        b.append(\"<div>\"); // NOI18N\n        b.append(\"<b>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_Step(3));\n        b.append(\"</b> \"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_RunCalibrateScript(\"<code>\" + IntegrationUtils.getRemoteCalibrateCommandString(settings.getHostOS(), getPlatform(settings, currentJDK)) + \"</code>\")); // NOI18N\n        b.append(\"</div>\"); // NOI18N\n        b.append(\"<br/>\"); // NOI18N\n        b.append(\"<div>\"); // NOI18N\n        b.append(\"<b>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_Step(4));\n        b.append(\"</b> \"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_AddParameters());\n        b.append(\" (<a href='\"); // NOI18N\n        b.append(LINK_CLIPBOARD);\n        b.append(\"'>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_CopyToClipboard());\n        b.append(\"</a>):\"); // NOI18N\n        b.append(\"</div>\"); // NOI18N\n        b.append(\"<pre>\"); // NOI18N\n        b.append(parameters(settings));\n        b.append(\"</pre>\"); // NOI18N\n        b.append(\"<br/>\"); // NOI18N\n        b.append(\"<div>\"); // NOI18N\n        b.append(\"<b>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_Step(5));\n        b.append(\"</b> \"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_StartApplication());\n        b.append(\"</div>\"); // NOI18N\n        b.append(\"<br/>\"); // NOI18N\n        b.append(\"<div>\"); // NOI18N\n        b.append(\"<b>\"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_Step(6));\n        b.append(\"</b> \"); // NOI18N\n        b.append(Bundle.AttachDialog_Steps_SubmitUnblock());\n        b.append(\"</div>\"); // NOI18N\n        return b.toString();\n    }\n    \n    protected String parameters(AttachSettings settings) {\n        return IntegrationUtils.getProfilerAgentCommandLineArgs(getOS(settings, currentARCH),\n                getPlatform(settings, currentJDK), settings.isRemote(), settings.getPort());\n    }\n    \n    protected void copyParameters(AttachSettings settings) {\n        String parameters = parameters(settings);\n        parameters = parameters.replace(\"&lt;\", \"<\").replace(\"&gt;\", \">\"); // NOI18N\n        StringSelection s = new StringSelection(parameters);\n        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s, s);\n        ProfilerDialogs.displayInfo(Bundle.AttachDialog_CopiedToClipboard());\n    }\n    \n    protected void createRemotePack(final AttachSettings settings) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                JFileChooser chooser = new JFileChooser();\n                File tmpDir = new File(System.getProperty(\"java.io.tmpdir\")); // NOI18N\n                chooser.setDialogTitle(Bundle.AttachDialog_RemotePackDialogCaption());\n                chooser.setAcceptAllFileFilterUsed(false);\n                chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\n                chooser.setSelectedFile(tmpDir);\n                chooser.setCurrentDirectory(tmpDir);\n                chooser.setMultiSelectionEnabled(false);\n                if ((JFileChooser.CANCEL_OPTION & chooser.showSaveDialog(chooser)) == 0) {\n                    final String path = chooser.getSelectedFile().getAbsolutePath();\n                    final String jdkF = currentJDK;\n                    RequestProcessor.getDefault().post(new Runnable() {\n                        public void run() {\n                            try {\n                                String packPath = exportRemotePack(path, settings, jdkF);\n                                ProfilerDialogs.displayInfo(Bundle.AttachDialog_RemotePackSaved(packPath));\n                            } catch (IOException ex) {\n                                System.err.println(\"Exception creating remote pack: \" + ex); // NOI18N\n                            }\n                        }\n                    });\n                }\n            }\n        });\n    }\n    \n    private static final AtomicBoolean exportRunning = new AtomicBoolean(false);\n    protected static String exportRemotePack(String path, AttachSettings settings, String jdk) throws IOException {\n        if (exportRunning.compareAndSet(false, true)) {\n            try {\n                if (path != null && path.endsWith(File.separator))\n                    path = path.substring(0, path.length() - 1);\n                return RemotePackExporter.getInstance().export(\n                        path, getOS(settings, null), getPlatform(settings, jdk));\n            } finally {\n                exportRunning.compareAndSet(true, false);\n            }\n        } else {\n            throw new IOException();\n        }\n    }\n    \n    protected static String getOS(AttachSettings settings, String arch) {\n//        if (!settings.isRemote()) return settings.getHostOS();\n        if (!settings.isRemote()) {\n            return IntegrationUtils.getLocalPlatform(arch == LINK_64ARCH ? 64 : 32);\n        } else {\n            String hostOS = settings.getHostOS();\n            if (IntegrationUtils.PLATFORM_WINDOWS_CVM.equals(hostOS))\n                return IntegrationUtils.PLATFORM_WINDOWS_OS;\n            if (IntegrationUtils.PLATFORM_LINUX_CVM.equals(hostOS))\n                return IntegrationUtils.PLATFORM_LINUX_OS;\n            else return settings.getHostOS();\n        }\n    }\n    \n    protected static String getPlatform(AttachSettings settings, String jdk) {\n        if (settings.isRemote() && isCVMJVM(settings))\n            return IntegrationUtils.PLATFORM_JAVA_CVM;\n        else if (LINK_JDK5.equals(jdk))\n            return IntegrationUtils.PLATFORM_JAVA_50;\n        else\n            return IntegrationUtils.PLATFORM_JAVA_60;\n    }\n    \n    protected static boolean isCVMJVM(AttachSettings settings) {\n        String hostOS = settings.getHostOS();\n        return IntegrationUtils.PLATFORM_WINDOWS_CVM.equals(hostOS) ||\n               IntegrationUtils.PLATFORM_LINUX_CVM.equals(hostOS);\n    }\n    \n    protected static boolean isARMJVM(AttachSettings settings) {\n        String hostOS = settings.getHostOS();\n        return IntegrationUtils.PLATFORM_LINUX_ARM_OS.equals(hostOS);\n    }\n    \n    protected static String getCorrectJavaMsg(String currentJDK, String currentARCH) {\n        if (IntegrationUtils.PLATFORM_MAC_OS.equals(IntegrationUtils.getLocalPlatform(-1))) {\n            return LINK_JDK6UP.equals(currentJDK) ?\n                    Bundle.AttachDialog_Steps_Java6() :\n                    Bundle.AttachDialog_Steps_Java5();\n        } else {\n            if (LINK_64ARCH.equals(currentARCH)) {\n                return LINK_JDK6UP.equals(currentJDK) ?\n                    Bundle.AttachDialog_Steps_Java6_64b() :\n                    Bundle.AttachDialog_Steps_Java5_64b();\n            } else {\n                return LINK_JDK6UP.equals(currentJDK) ?\n                    Bundle.AttachDialog_Steps_Java6_32b() :\n                    Bundle.AttachDialog_Steps_Java5_32b();\n            }\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project basedir=\".\" default=\"netbeans\" name=\"profiler.heapwalker\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.lib.profiler.heapwalker</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nOpenIDE-Module: org.graalvm.visualvm.lib.profiler.heapwalker/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/lib/profiler/heapwalker/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.2\n\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.lib.profiler.heapwalker-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/nbproject/genfiles.properties",
    "content": "# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=08e08606\nnbproject/build-impl.xml.script.CRC32=4530e23b\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/nbproject/project.properties",
    "content": "# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\njavac.source=1.8\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.lib.profiler.heapwalker</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid.heap</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.oql</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.45</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.40</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.heapdump</friend>\n                <friend>org.graalvm.visualvm.heapviewer</friend>\n                <friend>org.graalvm.visualvm.heapviewer.truffle</friend>\n                <package>org.graalvm.visualvm.lib.profiler.heapwalk</package>\n                <package>org.graalvm.visualvm.lib.profiler.heapwalk.details.api</package>\n                <package>org.graalvm.visualvm.lib.profiler.heapwalk.details.spi</package>\n                <package>org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/../..\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/api/DetailsSupport.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.api;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.openide.util.Lookup;\nimport org.openide.util.LookupEvent;\nimport org.openide.util.LookupListener;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class DetailsSupport {\n\n    public static String getDetailsString(Instance instance) {\n        // TODO [Tomas]: cache computed string per heap\n        Collection<ProviderClassPair> pairs = getCompatibleProviders(instance.getJavaClass());\n        for (ProviderClassPair pair : pairs) {\n            String classKey = pair.classKey;\n            if (pair.subclasses) classKey += \"+\";                               // NOI18N\n            String string = pair.provider.getDetailsString(classKey, instance);\n            if (string != null) return string;\n        }\n        return null;\n    }\n\n    public static DetailsProvider.View getDetailsView(Instance instance) {\n        Collection<ProviderClassPair> pairs = getCompatibleProviders(instance.getJavaClass());\n        for (ProviderClassPair pair : pairs) {\n            String classKey = pair.classKey;\n            if (pair.subclasses) classKey += \"+\";                               // NOI18N\n            DetailsProvider.View view = pair.provider.getDetailsView(classKey, instance);\n            if (view != null) return view;\n        }\n        return null;\n    }\n\n\n    private static final LinkedHashMap<Long, List<ProviderClassPair>> PROVIDERS_CACHE =\n            new LinkedHashMap<Long, List<ProviderClassPair>>(10000) {\n                protected boolean removeEldestEntry(Map.Entry eldest) {\n                    return size() > 5000;\n                }\n            };\n    \n    private static Lookup.Result<DetailsProvider> PROVIDERS;\n    private static Collection<? extends DetailsProvider> getProviders() {\n        if (PROVIDERS == null) {\n            PROVIDERS = Lookup.getDefault().lookupResult(DetailsProvider.class);\n            PROVIDERS.addLookupListener(new LookupListener() {\n                public void resultChanged(LookupEvent ev) { PROVIDERS_CACHE.clear(); }\n            });\n        }\n        return PROVIDERS.allInstances();\n    }\n    \n    private static List<ProviderClassPair> getCompatibleProviders(JavaClass cls) {\n        Long classId = cls.getJavaClassId();\n\n        // Query the cache for already computed DetailsProviders\n        List<ProviderClassPair> cachedPairs = PROVIDERS_CACHE.get(classId);\n        if (cachedPairs != null) return cachedPairs;\n        \n        // All registered className|DetailsProvider pairs\n        List<ProviderClassPair> allPairs = new ArrayList<>();\n        List<ProviderClassPair> simplePairs = new ArrayList<>();\n        Collection<? extends DetailsProvider> providers = getProviders();\n        for (DetailsProvider provider : providers) {\n            String[] classes = provider.getSupportedClasses();\n            if (classes != null && classes.length > 0)\n                for (String classs : classes)\n                    allPairs.add(new ProviderClassPair(provider, classs));\n            else simplePairs.add(new ProviderClassPair(provider, null));\n        }\n        \n        List<ProviderClassPair> pairs = new ArrayList<>();\n        \n        // Only compatible className|DetailsProvider pairs\n        if (!allPairs.isEmpty()) {\n            boolean superClass = false;\n            while (cls != null) {\n                String clsName = cls.getName();\n                for (ProviderClassPair pair : allPairs)\n                    if ((pair.subclasses || !superClass) &&\n                        clsName.equals(pair.classKey))\n                        pairs.add(pair);\n                cls = cls.getSuperClass();\n                superClass = true;\n            }\n        }\n        \n        // DetailsProviders without className definitions\n        pairs.addAll(simplePairs);\n        \n        // Cache the computed DetailsProviders\n        PROVIDERS_CACHE.put(classId, pairs);\n        \n        return pairs;\n    }\n    \n    \n    private static class ProviderClassPair {\n        \n        final DetailsProvider provider;\n        final String classKey;\n        final boolean subclasses;\n        \n        ProviderClassPair(DetailsProvider provider, String classKey) {\n            subclasses = classKey != null && classKey.endsWith(\"+\");            // NOI18N\n            this.provider = provider;\n            this.classKey = !subclasses ? classKey :\n                            classKey.substring(0, classKey.length() - 1);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/api/ExportAction.java",
    "content": "/*\n * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.api;\n\nimport java.awt.event.ActionEvent;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.Locale;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.Icon;\nimport javax.swing.JFileChooser;\nimport javax.swing.filechooser.FileFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.ui.NBSwingWorker;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Petr Cyhelsky\n */\n\n\n@NbBundle.Messages({\n    \"ExportAction_BasicExportActionName=Export to...\",\n    \"ExportAction_BasicExportActionDescr=Export to...\",\n    \"ExportAction_ExportDialogTitle=Select File or Directory\",\n    \"ExportAction_ExportDialogButton=Export\",\n    \"ExportAction_OverwriteFileCaption=Overwrite Existing File\",\n    \"ExportAction_OverwriteFileMsg=<html><b>File {0} already exists.</b><br><br>Do you want to replace it?</html>\",\n    \"ExportAction_ExportDialogCSVFilter=CSV File (*.csv)\",\n    \"ExportAction_ExportDialogTXTFilter=Text File (*.txt)\",\n    \"ExportAction_ExportDialogBINFilter=Binary File (*.bin)\",\n    \"ExportAction_ExportingViewMsg=Exporting...\",\n    \"ExportAction_NoViewMsg=No view to export.\",\n    \"ExportAction_OomeExportingMsg=<html><b>Not enough memory to save the file.</b><br><br>To avoid this error please increase the -Xmx value<br>in the etc/visualvm.conf file in VisualVM directory.</html>\",\n    \"ExportAction_IOException_Exporting_Msg=<html>IOException occurred during export, see IDE log for details</html>\",\n    \"ExportAction_CannotWriteFileMsg=Failed to export File. Reason: {0}.\"})\npublic final class ExportAction extends AbstractAction {\n    private static final Logger LOGGER = Logger.getLogger(ExportAction.class.getName());\n\n//~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    public static interface ExportProvider {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void exportData(int exportedFileType, ExportDataDumper eDD);\n\n        public String getViewName();\n\n        public boolean isExportable();\n\n        public boolean hasRawData();\n        \n        public boolean hasBinaryData();\n\n        public boolean hasText();\n\n    }\n\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n\n    private static class SelectedFile {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        File folder;\n        String fileExt;\n        String fileName;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        SelectedFile(File folder, String fileName, String fileExt) {\n            this.folder = folder;\n            this.fileName = fileName;\n            this.fileExt = fileExt;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        File getSelectedFile() {\n            String folderPath=folder.getAbsolutePath();\n            if (folderPath.endsWith(File.separator)) {\n                folderPath=folderPath.substring(0, folderPath.length()-1);\n            }\n            return new File(folderPath + File.separator + fileName+ \".\" + fileExt);\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final Icon ICON = Icons.getIcon(GeneralIcons.EXPORT);\n    private static final String FILE_EXTENSION_CSV = \"csv\"; // NOI18N\n    private static final String FILE_EXTENSION_TXT = \"txt\"; // NOI18N\n    private static final String FILE_EXTENSION_BIN = \"bin\"; // NOI18N\n    public static final int MODE_CSV = 1;\n    public static final int MODE_TXT = 2;\n    public static final int MODE_BIN = 3;\n    private static File exportDir;\n\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JFileChooser fileChooser;\n    private final ExportProvider exportProvider;\n    private int exportedFileType;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public ExportAction(ExportProvider exportProvider) {\n        putValue(Action.NAME, Bundle.ExportAction_BasicExportActionName());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.ExportAction_BasicExportActionDescr());\n        putValue(Action.SMALL_ICON, ICON);\n        putValue(\"iconBase\", Icons.getResource(GeneralIcons.EXPORT)); // NOI18N\n        this.exportProvider = exportProvider;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    private void setFilters() {\n        fileChooser.removeChoosableFileFilter(fileChooser.getAcceptAllFileFilter());\n        if (exportProvider.hasRawData()) {\n            fileChooser.addChoosableFileFilter(new FileFilterImpl(FILE_EXTENSION_CSV));\n        }\n        if (exportProvider.hasText()) {\n            fileChooser.addChoosableFileFilter(new FileFilterImpl(FILE_EXTENSION_TXT));\n        }\n        if (exportProvider.hasBinaryData()) {\n            fileChooser.addChoosableFileFilter(new FileFilterImpl(FILE_EXTENSION_BIN));\n        }\n    }\n\n\n    private JFileChooser getFileChooser() {\n        if (fileChooser == null) {\n            // File chooser\n            fileChooser = new JFileChooser();\n            fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);\n            fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);\n            fileChooser.setMultiSelectionEnabled(false);\n            fileChooser.setDialogTitle(Bundle.ExportAction_ExportDialogTitle());\n            fileChooser.setApproveButtonText(Bundle.ExportAction_ExportDialogButton());\n        }\n        fileChooser.resetChoosableFileFilters();\n        setFilters();\n        return fileChooser;\n    }\n\n    private boolean checkFileExists(File target) {\n        if (target.exists()) {\n            if (!ProfilerDialogs.displayConfirmation(\n                    Bundle.ExportAction_OverwriteFileMsg(target.getName()),\n                    Bundle.ExportAction_OverwriteFileCaption())) {  // choose whether to overwrite\n                  return false; // user chose not to overwrite\n              }\n          }\n          return true;\n      }\n\n    private SelectedFile selectExportTargetFile(final ExportProvider exportProvider) {\n        File targetDir;\n        String targetName;\n        String defaultName = exportProvider.getViewName();\n\n        // 1. let the user choose file or directory\n        final JFileChooser chooser = getFileChooser();\n        if (exportDir != null) {\n            chooser.setCurrentDirectory(exportDir);\n        }\n        int result = chooser.showSaveDialog(WindowManager.getDefault().getRegistry().getActivated());\n        if (result != JFileChooser.APPROVE_OPTION) {\n            return null; // cancelled by the user\n        }\n\n        // 2. process both cases and extract file name and extension to use and set exported file type\n        File file = chooser.getSelectedFile();\n        String targetExt = null;\n        FileFilter selectedFileFilter = chooser.getFileFilter();\n        if (selectedFileFilter==null  // workaround for #227659\n                ||  selectedFileFilter.getDescription().equals(Bundle.ExportAction_ExportDialogCSVFilter())) {\n            targetExt=FILE_EXTENSION_CSV;\n            exportedFileType=MODE_CSV;\n        } else if (selectedFileFilter.getDescription().equals(Bundle.ExportAction_ExportDialogTXTFilter())) {\n            targetExt=FILE_EXTENSION_TXT;\n            exportedFileType=MODE_TXT;\n        } else if (selectedFileFilter.getDescription().equals(Bundle.ExportAction_ExportDialogBINFilter())) {\n            targetExt=FILE_EXTENSION_BIN;\n            exportedFileType=MODE_BIN;\n        }\n\n        if (file.isDirectory()) { // save to selected directory under default name\n            exportDir = file;\n            targetDir = file;\n            targetName = defaultName;\n        } else { // save to selected file\n            targetDir = fileChooser.getCurrentDirectory();\n            String fName = file.getName();\n\n            // divide the file name into name and extension\n            if (fName.endsWith(\".\"+targetExt)) {  // NOI18N\n                int idx = fName.lastIndexOf('.'); // NOI18N\n                targetName = fName.substring(0, idx);\n            } else {            // no extension\n                targetName=fName;\n            }\n        }\n\n        // 3. set type of exported file and return a newly created FileObject\n\n        return new ExportAction.SelectedFile(targetDir, targetName, targetExt);\n    }\n\n    @Override\n    public void actionPerformed(ActionEvent evt) {\n        if (!exportProvider.hasRawData() && !exportProvider.hasText()) { // nothing to export\n            ProfilerDialogs.displayError(Bundle.ExportAction_NoViewMsg());\n            return;\n        }\n\n        SelectedFile saveFile = selectExportTargetFile(exportProvider);\n\n        if (saveFile == null) return; // cancelled\n\n        final File file = saveFile.getSelectedFile();\n        if (!checkFileExists(file)) return; // user doesn't want to overwrite existing file or it can't be overwritten\n\n        new NBSwingWorker(true) {\n            final private ProgressHandle ph = ProgressHandle.createHandle(Bundle.ExportAction_ExportingViewMsg());\n            @Override\n            protected void doInBackground() {\n                ph.setInitialDelay(500);\n                ph.start();\n\n                try {\n                    FileOutputStream fo;\n                    fo = new FileOutputStream(file);\n                    ExportDataDumper eDD = new ExportDataDumper(fo);\n                    exportProvider.exportData(exportedFileType, eDD);\n                    if (eDD.getCaughtException()!=null) {\n                        ProfilerDialogs.displayError(eDD.getNumExceptions()+Bundle.ExportAction_IOException_Exporting_Msg());\n                    }\n                } catch (OutOfMemoryError e) {\n                    ProfilerDialogs.displayError(Bundle.ExportAction_OomeExportingMsg()+e.getMessage());\n                } catch (IOException e1) {\n                    ProfilerDialogs.displayError(Bundle.ExportAction_CannotWriteFileMsg(e1.getLocalizedMessage()));\n                    LOGGER.log(Level.WARNING, e1.toString());\n                }\n            }\n\n            @Override\n            protected void done() {\n                ph.finish();\n            }\n        }.execute();\n    }\n\n    private static class FileFilterImpl extends FileFilter {\n        \n        private final String extension;\n\n        FileFilterImpl(String ext) {\n            extension = ext;\n        }\n\n        @Override\n        public boolean accept(File f) {\n            return f.isDirectory() || f.getName().toLowerCase(Locale.US).endsWith(\".\"+extension); //NOI18N\n        }\n\n        @Override\n        public String getDescription() {\n            if (FILE_EXTENSION_CSV.equals(extension)) {\n                return Bundle.ExportAction_ExportDialogCSVFilter();\n            } else if (FILE_EXTENSION_TXT.equals(extension)) {\n                return Bundle.ExportAction_ExportDialogTXTFilter();\n            } else if (FILE_EXTENSION_BIN.equals(extension)) {\n                return Bundle.ExportAction_ExportDialogBINFilter();\n            } else {\n                return null;\n            }\n            \n        }\n    }\n}\n\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/api/StringDecoder.java",
    "content": "/*\n * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.api;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.WeakHashMap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic final class StringDecoder {\n\n    private static final Map<Heap,int[]> CACHE = new WeakHashMap<>();\n\n    private final byte coder;\n    private final List<String> values;\n    private int HI_BYTE_SHIFT;\n    private int LO_BYTE_SHIFT;\n\n    public StringDecoder(Heap heap, byte c, List<String> val) {\n        coder = c;\n        values = val;\n        if (coder == 1) {\n            int[] shiftBytes = CACHE.get(heap);\n\n            if (shiftBytes == null) {\n                JavaClass utf16Class = heap.getJavaClassByName(\"java.lang.StringUTF16\"); // NOI18N\n                Integer hiShift = (Integer) utf16Class.getValueOfStaticField(\"HI_BYTE_SHIFT\"); // NOI18N\n                Integer loShift = (Integer) utf16Class.getValueOfStaticField(\"LO_BYTE_SHIFT\"); // NOI18N\n\n                if (hiShift != null && loShift != null) {\n                    shiftBytes = new int[] {hiShift.intValue(), loShift.intValue()};\n                } else {\n                    // use default\n                    shiftBytes = new int[] {0,8};\n                }\n                CACHE.put(heap, shiftBytes);\n            }\n            HI_BYTE_SHIFT = shiftBytes[0];\n            LO_BYTE_SHIFT = shiftBytes[1];\n        }\n    }\n\n    public int getStringLength() {\n        int size = values.size();\n        switch (coder) {\n            case -1:\n                return size;\n            case 0:\n                return size;\n            case 1:\n                return size / 2;\n            default:\n                return size;\n        }\n    }\n\n    public String getValueAt(int index) {\n        switch (coder) {\n            case -1:\n                return values.get(index);\n            case 0: {\n                char ch = (char) (Byte.valueOf(values.get(index)) & 0xff);\n                return String.valueOf(ch);\n            }\n            case 1: {\n                index *= 2;\n                byte hiByte = Byte.valueOf(values.get(index));\n                byte lowByte = Byte.valueOf(values.get(index + 1));\n                char ch = (char) (((hiByte & 0xff) << HI_BYTE_SHIFT) |\n                                 ((lowByte & 0xff) << LO_BYTE_SHIFT));\n                return String.valueOf(ch);\n            }\n            default:\n                return \"?\"; // NOI18N\n        }\n    }  \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/basic/ArrayDetailsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.basic;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ArrayDetailsProvider_OneItemString=1 item\",                                // NOI18N\n    \"# {0} - number of items\",                                                  // NOI18N\n    \"ArrayDetailsProvider_ItemsNumberString={0} items\"                          // NOI18N\n})\n@ServiceProvider(service=DetailsProvider.class)\npublic final class ArrayDetailsProvider extends DetailsProvider {\n\n    public String getDetailsString(String className, Instance instance) {\n        if (instance instanceof PrimitiveArrayInstance) {\n            if (\"char[]\".equals(instance.getJavaClass().getName())) {           // NOI18N\n                return DetailsUtils.getPrimitiveArrayString(\n                        instance, 0, -1, null, \"...\");                          // NOI18N\n            } else {\n                return getItemsString(((PrimitiveArrayInstance)instance).getLength());\n            }\n        } else if (instance instanceof ObjectArrayInstance) {\n            return getItemsString(((ObjectArrayInstance)instance).getLength());\n        }\n        return null;\n    }\n\n    public View getDetailsView(String className, Instance instance) {\n        if (instance instanceof PrimitiveArrayInstance)\n            return new ArrayValueView(className, instance);\n        else return null;\n    }\n\n    private static String getItemsString(int length) {\n        return length == 1 ? Bundle.ArrayDetailsProvider_OneItemString() :\n                             Bundle.ArrayDetailsProvider_ItemsNumberString(length);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/basic/ArrayValueView.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.basic;\n\nimport java.awt.BorderLayout;\nimport java.awt.Container;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.regex.Pattern;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextArea;\nimport javax.swing.JViewport;\nimport javax.swing.Scrollable;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.results.ExportDataDumper;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.ExportAction;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.StringDecoder;\nimport static org.graalvm.visualvm.lib.profiler.heapwalk.details.basic.ArrayValueView.Type.*;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.model.BrowserUtils;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ArrayValueView_Truncated=... <truncated>\",                                     // NOI18N\n    \"ArrayValueView_Value=Value:\",                                                  // NOI18N\n    \"ArrayValueView_Items=Array items:\",                                            // NOI18N\n    \"ArrayValueView_All=Show All\",                                                  // NOI18N\n    \"ArrayValueView_Save=Save to File\",                                             // NOI18N\n    \"ArrayValueView_OutOfMemory=Out of memory - value too long.\"                    // NOI18N\n})\nfinal class ArrayValueView extends DetailsProvider.View implements Scrollable, ExportAction.ExportProvider {\n    \n    private static final int MAX_PREVIEW_LENGTH = 256;\n    private static final int MAX_ARRAY_ITEMS = 1000;\n    private static final int MAX_CHARARRAY_ITEMS = 500000;\n    private static final String TRUNCATED = Bundle.ArrayValueView_Truncated();\n    enum Type {STRING, STRING_BUILDER, PRIMITIVE_ARRAY};\n    \n    private final String className;\n    \n    private JTextArea view;\n    private JButton all;\n    \n    private String caption;\n    private Heap heap;\n    private List<String> values;\n    private byte coder = -1;\n    private String separator;\n    private int offset;\n    private int count;\n    private boolean truncated;\n    private boolean chararray;\n    private boolean bytearray;\n    private String instanceIdentifier;\n    private Type type;\n    \n    protected ArrayValueView(String className, Instance instance) {\n        super(instance);\n        this.className = className;\n    }\n\n    protected void computeView(Instance instance) {\n        JavaClass javaClass = instance.getJavaClass();\n        String clsName = javaClass.getName();\n        heap = javaClass.getHeap();\n        if (StringDetailsProvider.STRING_MASK.equals(className)) {                  // String\n            separator = \"\";                                                         // NOI18N\n            offset = DetailsUtils.getIntFieldValue(instance, \"offset\", 0);          // NOI18N\n            count = DetailsUtils.getIntFieldValue(instance, \"count\", -1);           // NOI18N\n            coder = DetailsUtils.getByteFieldValue(instance, \"coder\", (byte) -1);   // NOI18N\n            values = DetailsUtils.getPrimitiveArrayFieldValues(instance, \"value\");  // NOI18N\n            caption = Bundle.ArrayValueView_Value();\n            type = STRING;\n        } else if (StringDetailsProvider.BUILDERS_MASK.equals(className)) {         // AbstractStringBuilder+\n            separator = \"\";                                                         // NOI18N\n            offset = 0;\n            count = DetailsUtils.getIntFieldValue(instance, \"count\", -1);           // NOI18N\n            coder = DetailsUtils.getByteFieldValue(instance, \"coder\", (byte) -1);   // NOI18N\n            values = DetailsUtils.getPrimitiveArrayFieldValues(instance, \"value\");  // NOI18N\n            caption = Bundle.ArrayValueView_Value();\n            type = STRING_BUILDER;\n        } else if (instance instanceof PrimitiveArrayInstance) {                    // Primitive array\n            chararray = \"char[]\".equals(clsName);                       // NOI18N\n            bytearray = \"byte[]\".equals(clsName);                       // NOI18N\n            separator = chararray ? \"\" : \", \";                                      // NOI18N\n            offset = 0;\n            values = DetailsUtils.getPrimitiveArrayValues(instance);\n            count = values == null ? 0 : values.size();\n            caption = Bundle.ArrayValueView_Items();\n            type = PRIMITIVE_ARRAY;\n        }\n        instanceIdentifier=clsName+\"#\"+instance.getInstanceNumber(); // NOI18N\n        final String preview = getString(true);\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));\n                setBackground(UIUtils.getProfilerResultsBackground());\n                setOpaque(true);\n                \n                removeAll();\n                \n                JLabel l = new JLabel(caption, JLabel.LEADING);\n                l.setBorder(BorderFactory.createEmptyBorder(0, 0, 3, 0));\n                add(l, BorderLayout.NORTH);\n                \n                view = new JTextArea();\n                if (bytearray) {\n                    Font defaultFont = view.getFont();\n                    view.setFont(new Font(Font.MONOSPACED, Font.PLAIN, defaultFont.getSize()));\n                }\n                l.setLabelFor(view);\n                view.setEditable(false);\n                view.setLineWrap(true);\n                view.setWrapStyleWord(true);\n                view.setText(preview);\n                try { view.setCaretPosition(0); } catch (IllegalArgumentException e) {}\n                \n                JScrollPane viewScroll = new JScrollPane(view,\n                        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                        JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n                add(viewScroll, BorderLayout.CENTER);\n                \n                JPanel p = new JPanel(new GridBagLayout());\n                p.setOpaque(false);\n                \n                all = htmlButton(Bundle.ArrayValueView_All(), truncated && count < (chararray ? MAX_CHARARRAY_ITEMS : MAX_ARRAY_ITEMS), new Runnable() {\n                    public void run() { showAll(); }\n                });\n                GridBagConstraints c = new GridBagConstraints();\n                c.gridx = 0;\n                c.insets = new Insets(3, 0, 0, 5);\n                p.add(all, c);\n                \n                JButton save = htmlButton(Bundle.ArrayValueView_Save(), !preview.isEmpty(), new Runnable() {\n                    public void run() {\n                        new ExportAction(ArrayValueView.this).actionPerformed(null);\n                    }\n                });\n                c = new GridBagConstraints();\n                c.gridx = 1;\n                c.insets = new Insets(3, 0, 0, 0);\n                p.add(save, c);\n                \n                JPanel f = new JPanel(null);\n                f.setOpaque(false);\n                c = new GridBagConstraints();\n                c.gridx = 2;\n                c.weightx = 1;\n                c.fill = GridBagConstraints.HORIZONTAL;\n                p.add(f, c);\n                \n                add(p, BorderLayout.SOUTH);\n                \n                revalidate();\n                doLayout();\n                repaint();\n            }\n        });\n    }\n    \n    private void showAll() {\n        all.setEnabled(false);\n        view.setEnabled(false);\n        BrowserUtils.performTask(new Runnable() {\n            public void run() {\n                String _preview = null;\n                try {\n                    _preview = getString(false);\n                } catch (OutOfMemoryError e) {\n                    ProfilerDialogs.displayError(Bundle.ArrayValueView_OutOfMemory());\n                    return;\n                }\n                \n                final String preview = _preview;\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        try {\n                            view.setText(preview);\n                            try { view.setCaretPosition(0); } catch (IllegalArgumentException e) {}\n                            view.setEnabled(true);\n                        } catch (OutOfMemoryError e) {\n                            ProfilerDialogs.displayError(Bundle.ArrayValueView_OutOfMemory());\n                        }\n                    }\n                });\n            }\n        });\n    }\n    \n    \n    private String getString(boolean preview) {\n        if (values == null) return \"\";                                              // NOI18N\n        if (bytearray) return getHexDump(preview);\n        StringDecoder decoder = new StringDecoder(heap, coder, values);\n        int valuesCount = count < 0 ? decoder.getStringLength() - offset : count;            \n        int separatorLength = separator == null ? 0 : separator.length();\n        int estimatedSize = (int)Math.min((long)valuesCount * (2 + separatorLength), MAX_PREVIEW_LENGTH + TRUNCATED.length());\n        StringBuilder value = new StringBuilder(estimatedSize);\n        int lastValue = offset + valuesCount - 1;\n        for (int i = offset; i <= lastValue; i++) {\n            value.append(decoder.getValueAt(i));\n            if (preview && value.length() >= MAX_PREVIEW_LENGTH) {\n                value.append(TRUNCATED);\n                truncated = true;\n                break;\n            }\n            if (separator != null && i < lastValue) value.append(separator);\n        }\n        return value.toString();\n    }\n    \n    private static final int LINE_LEN = 0x10;\n\n    private String getHexDump(boolean preview) {\n        StringBuilder value = new StringBuilder();\n        StringBuilder chars = new StringBuilder();\n        int lastValue = count - 1;\n        for (int i = 0; i <= lastValue; i++) {\n            if (i%LINE_LEN == 0) {\n                if (i != 0) {\n                    value.append(getPrintableChars(chars));\n                    value.append(\"\\n\");\n                    chars = new StringBuilder();\n                }\n                if (preview && i >= MAX_PREVIEW_LENGTH) {\n                    truncated = true;\n                    break;\n                }\n                value.append(String.format(\"%04X  \", i));\n            }\n            byte val = Byte.parseByte(values.get(i));\n            value.append(String.format(\"%02X \", val));\n            chars.append((char)val);\n        }\n        if (chars.length() > 0) {\n            char[] spaces = new char[(LINE_LEN-chars.length())*3];\n            Arrays.fill(spaces, ' ');\n            value.append(spaces);\n            value.append(getPrintableChars(chars));\n        }\n        return value.toString();\n    }\n\n    private static final Pattern REGEXP = Pattern.compile(\"\\\\P{Print}\");\n\n    private String getPrintableChars(StringBuilder chars) {\n        StringBuilder val = new StringBuilder();\n        val.append(\"   |\");\n        val.append(REGEXP.matcher(chars.toString()).replaceAll(\".\"));\n        val.append(\"|\");\n        return val.toString();\n    }\n\n    public Dimension getPreferredScrollableViewportSize() {\n        return null;\n    }\n\n    public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {\n        // Scroll almost one screen\n        Container parent = getParent();\n        if ((parent == null) || !(parent instanceof JViewport)) return 50;\n        return (int)(((JViewport)parent).getHeight() * 0.95f);\n    }\n\n    public boolean getScrollableTracksViewportHeight() {\n        // Allow dynamic vertical enlarging of the panel but request the vertical scrollbar when needed\n        Container parent = getParent();\n        if ((parent == null) || !(parent instanceof JViewport)) return false;\n        return getMinimumSize().height < ((JViewport)parent).getHeight();\n    }\n\n    public boolean getScrollableTracksViewportWidth() {\n        // Allow dynamic horizontal enlarging of the panel but request the vertical scrollbar when needed\n        Container parent = getParent();\n        if ((parent == null) || !(parent instanceof JViewport)) return false;\n        return getMinimumSize().width < ((JViewport)parent).getWidth();\n    }\n\n    public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {\n        return 20;\n    }\n    \n    \n    private static JButton htmlButton(final String text, final boolean enabled, final Runnable handler) {\n        JButton b = new JButton() {\n            public void setEnabled(boolean b) {\n                setText(!b ? text : \"<html><nobr><a href='#'>\" + text + \"</a></nobr></html>\"); // NOI18N\n                setCursor(!b ? Cursor.getDefaultCursor() : Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n                super.setEnabled(b);\n            }\n        };\n        b.setOpaque(false);\n        b.setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 1));\n        b.setBorderPainted(false);\n        b.setContentAreaFilled(false);\n        b.setEnabled(enabled);\n        b.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { handler.run(); }\n        });\n        return b;\n    }\n\n    @Override\n    public void exportData(int exportedFileType, ExportDataDumper eDD) {\n        String comma = \",\"; // NOI18N\n        if (values != null) {\n            StringDecoder decoder = new StringDecoder(heap, coder, values);\n            int valuesCount = count < 0 ? decoder.getStringLength() - offset : count;            \n            int lastValue = offset + valuesCount - 1;\n            for (int i = offset; i <= lastValue; i++) {\n                String value = decoder.getValueAt(i);\n                \n                switch (exportedFileType) {\n                    case ExportAction.MODE_CSV:\n                        eDD.dumpData(value);\n                        eDD.dumpData(comma);\n                        break;\n                    case ExportAction.MODE_TXT:\n                        eDD.dumpData(value);\n                        break;\n                    case ExportAction.MODE_BIN:\n                        byte b = Byte.valueOf(value);\n                        eDD.dumpByte(b);\n                        break;\n                    default:\n                        throw new IllegalArgumentException(); //Illegal export type\n                }\n            }\n        }\n        eDD.close();\n    }\n\n    @Override\n    public String getViewName() {\n        return instanceIdentifier;\n    }\n\n    @Override\n    public boolean hasRawData() {\n        return type.equals(PRIMITIVE_ARRAY);\n    }\n\n    @Override\n    public boolean hasBinaryData() {\n        return bytearray;\n    }\n\n    @Override\n    public boolean hasText() {\n        switch (type) {\n            case STRING:\n            case STRING_BUILDER:\n                return true;\n            case PRIMITIVE_ARRAY:\n                return chararray;\n        }\n        throw new IllegalArgumentException(type.toString());\n    }\n\n    @Override\n    public boolean isExportable() {\n        return hasText() || hasBinaryData() || hasRawData();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/basic/PrimitiveDetailsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.basic;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic final class PrimitiveDetailsProvider extends DetailsProvider.Basic {\n\n    public PrimitiveDetailsProvider() {\n        super(Boolean.class.getName(), Byte.class.getName(),\n              Character.class.getName(), Double.class.getName(),\n              Float.class.getName(), Integer.class.getName(),\n              Long.class.getName(), Short.class.getName());\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        Object value = instance.getValueOfField(\"value\");                       // NOI18N\n        return value != null ? value.toString() : null;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/basic/StringDetailsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.basic;\n\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.StringDecoder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic final class StringDetailsProvider extends DetailsProvider.Basic {\n\n    static final String STRING_MASK = \"java.lang.String\";                           // NOI18N\n    static final String BUILDERS_MASK = \"java.lang.AbstractStringBuilder+\";         // NOI18N\n\n    public StringDetailsProvider() {\n        super(STRING_MASK, BUILDERS_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        if (STRING_MASK.equals(className)) {                                        // String\n            byte coder = DetailsUtils.getByteFieldValue(instance, \"coder\", (byte) -1);     // NOI18N\n            if (coder == -1) {\n                int offset = DetailsUtils.getIntFieldValue(instance, \"offset\", 0);      // NOI18N\n                int count = DetailsUtils.getIntFieldValue(instance, \"count\", -1);       // NOI18N\n                return DetailsUtils.getPrimitiveArrayFieldString(instance, \"value\",     // NOI18N\n                        offset, count, null,\n                        \"...\");                // NOI18N\n            } else {\n                return getJDK9String(instance, \"value\", coder, null, \"...\");          // NOI18N\n            }\n        } else if (BUILDERS_MASK.equals(className)) {                               // AbstractStringBuilder+\n            byte coder = DetailsUtils.getByteFieldValue(instance, \"coder\", (byte) -1);  // NOI18N\n            if (coder == -1) {\n                int count = DetailsUtils.getIntFieldValue(instance, \"count\", -1);       // NOI18N\n                return DetailsUtils.getPrimitiveArrayFieldString(instance, \"value\",     // NOI18N\n                        0, count, null,\n                        \"...\");                // NOI18N\n            } else {\n                return getJDK9String(instance, \"value\", coder, null, \"...\");          // NOI18N\n            }\n        }\n        return null;\n    }\n    \n    public View getDetailsView(String className, Instance instance) {\n        return new ArrayValueView(className, instance);\n    }\n    \n    private String getJDK9String(Instance instance, String field, byte coder, String separator, String trailer) {\n        Object byteArray = instance.getValueOfField(field);\n        if (byteArray instanceof PrimitiveArrayInstance) {\n            List<String> values = ((PrimitiveArrayInstance) byteArray).getValues();\n            if (values != null) {\n                Heap heap = instance.getJavaClass().getHeap();\n                StringDecoder decoder = new StringDecoder(heap, coder, values);\n                int valuesCount = decoder.getStringLength();\n                int separatorLength = separator == null ? 0 : separator.length();\n                int trailerLength = trailer == null ? 0 : trailer.length();\n                int estimatedSize = Math.min(valuesCount * (1 + separatorLength), DetailsUtils.MAX_ARRAY_LENGTH + trailerLength);\n                StringBuilder value = new StringBuilder(estimatedSize);\n                int lastValue = valuesCount - 1;\n                for (int i = 0; i <= lastValue; i++) {\n                    if (value.length() >= DetailsUtils.MAX_ARRAY_LENGTH) {\n                        if (trailerLength > 0) {\n                            value.append(trailer);\n                        }\n                        break;\n                    }\n                    value.append(decoder.getValueAt(i));\n                    if (separator != null && i < lastValue) {\n                        value.append(separator);\n                    }\n                }\n                return value.toString();\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/AtomicDetailsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.model.BrowserUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic final class AtomicDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String BOOLEAN_MASK = \"java.util.concurrent.atomic.AtomicBoolean+\";    // NOI18N\n    private static final String INTEGER_MASK = \"java.util.concurrent.atomic.AtomicInteger+\";    // NOI18N\n    private static final String LONG_MASK = \"java.util.concurrent.atomic.AtomicLong+\";          // NOI18N\n    private static final String REFERENCE_MASK = \"java.util.concurrent.atomic.AtomicReference+\";// NOI18N\n\n    public AtomicDetailsProvider() {\n        super(BOOLEAN_MASK, INTEGER_MASK, LONG_MASK, REFERENCE_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case BOOLEAN_MASK: {\n                int value = DetailsUtils.getIntFieldValue(instance, \"value\", 0);                    // NOI18N\n                return Boolean.toString(value != 0);\n            }\n            case INTEGER_MASK: {\n                int value = DetailsUtils.getIntFieldValue(instance, \"value\", 0);                    // NOI18N\n                return Integer.toString(value);\n            }\n            case LONG_MASK: {\n                long value = DetailsUtils.getLongFieldValue(instance, \"value\", 0);                  // NOI18N\n                return Long.toString(value);\n            }\n            case REFERENCE_MASK: {\n                Object value = instance.getValueOfField(\"value\");                                   // NOI18N\n                if (value instanceof Instance) {\n                    Instance i = (Instance)value;\n                    String s = DetailsUtils.getInstanceString(i);\n                    s = s == null ? \"#\" + i.getInstanceNumber() : \": \" + s;                         // NOI18N\n                    return BrowserUtils.getSimpleType(i.getJavaClass().getName()) + s;\n                }\n                break;\n            }\n            default:\n                break;\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/IoDetailsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.WeakHashMap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic final class IoDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String FILE_MASK = \"java.io.File+\";                    // NOI18N\n    private static final String ZIPFILE_MASK = \"java.util.zip.ZipFile+\";        // NOI18N\n    private static final String RAF_MASK = \"java.io.RandomAccessFile\";          // NOI18N\n    private static final String FIS_MASK = \"java.io.FileInputStream\";           // NOI18N\n    private static final String FOS_MASK = \"java.io.FileOutputStream\";          // NOI18N\n    private static final String FD_MASK = \"java.io.FileDescriptor\";             // NOI18N\n    private static final String FD_RAF_CLASS = \"java.io.RandomAccessFile\";      // NOI18N\n    private static final String FD_FIS_CLASS = \"java.io.FileInputStream\";       // NOI18N\n    private static final String FD_FOS_CLASS = \"java.io.FileOutputStream\";      // NOI18N\n\n    private static final Object CACHE_LOCK = new Object();\n    private static WeakHashMap<Heap,Map<Long,String>> CACHE;\n\n    public IoDetailsProvider() {\n        super(FILE_MASK, ZIPFILE_MASK, RAF_MASK, FIS_MASK, FOS_MASK, FD_MASK);\n    }\n    \n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case FILE_MASK: // File+\n                return DetailsUtils.getInstanceFieldString(instance, \"path\"); // NOI18N\n            case ZIPFILE_MASK: // ZipFile+\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            case RAF_MASK: // RandomAccessFile\n                return DetailsUtils.getInstanceFieldString(instance, \"path\"); // NOI18N\n            case FIS_MASK: // FileInputStrea\n                return DetailsUtils.getInstanceFieldString(instance, \"path\"); // NOI18N\n            case FOS_MASK: // FileOutputStream\n                return DetailsUtils.getInstanceFieldString(instance, \"path\"); // NOI18N\n            case FD_MASK: // FileDescriptor\n                synchronized (CACHE_LOCK) {\n                    if (CACHE == null) {\n                        CACHE = new WeakHashMap<>();\n                    }\n                    Heap heap = instance.getJavaClass().getHeap();\n                    Map<Long,String> heapCache = CACHE.get(heap);\n                    if (heapCache == null) {\n                        heapCache = computeFDCache(heap, instance.getJavaClass());\n                        CACHE.put(heap, heapCache);\n                    }\n                    return heapCache.get(instance.getInstanceId());\n                }\n            default:\n                break;\n        }\n        \n        return null;\n    }\n\n    private Map<Long, String> computeFDCache(Heap heap, JavaClass fdClass) {\n        Map<Long, String> cache = new HashMap<>();\n        computeFDCacheForClass(heap, FD_RAF_CLASS, \"fd\", cache);                // NOI18N\n        computeFDCacheForClass(heap, FD_FIS_CLASS, \"fd\", cache);                // NOi18N\n        computeFDCacheForClass(heap, FD_FOS_CLASS, \"fd\", cache);                // NOI18N\n        computeStdDescriptor(fdClass, \"in\", \"Standard Input\", cache);           // NOI18N\n        computeStdDescriptor(fdClass, \"out\", \"Standard Output\", cache);         // NOi18N\n        computeStdDescriptor(fdClass, \"err\", \"Standard Error\", cache);          // NOi18N\n        return cache;\n    }\n\n    private void computeFDCacheForClass(Heap heap, String className, String fieldName, Map<Long, String> cache) {\n        JavaClass rafClass = heap.getJavaClassByName(className);\n        if (rafClass != null) {\n            for (Instance raf : rafClass.getInstances()) {\n                Instance fd = (Instance)raf.getValueOfField(fieldName);\n                if (fd != null) {\n                    String details = getDetailsString(className,raf);\n                    if (details != null) {\n                        cache.put(fd.getInstanceId(), details);\n                    }\n                }\n            }\n        }\n    }\n\n    private void computeStdDescriptor(JavaClass fdClass, String field, String text, Map<Long, String> cache) {\n        Instance stdFd = (Instance) fdClass.getValueOfStaticField(field);\n        \n        if (stdFd != null) {\n            cache.put(stdFd.getInstanceId(), text);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/JmxDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic class JmxDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String OBJECT_NAME_MASK = \"javax.management.ObjectName\";    // NOI18N\n\n    public JmxDetailsProvider() {\n        super(OBJECT_NAME_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        if (OBJECT_NAME_MASK.equals(className)) {\n            return DetailsUtils.getInstanceFieldString(instance, \"_canonicalName\");     // NOI18N\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/LangDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic class LangDetailsProvider extends DetailsProvider.Basic {\n    private static final String ENUM_MASK = \"java.lang.Enum+\";                    // NOI18N\n    private static final String STACKTRACE_MASK = \"java.lang.StackTraceElement\";    // NOI18N\n\n    public LangDetailsProvider() {\n        super(ENUM_MASK, STACKTRACE_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case ENUM_MASK: { // Enum+\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n                int ordinal = DetailsUtils.getIntFieldValue(instance, \"ordinal\", -1); // NOI18N\n                if (name != null) {\n                    if (ordinal != -1) {\n                        return name+\" (\"+ordinal+\")\";       // NOI18N\n                    }\n                    return name;\n                }\n                break;\n            }\n            case STACKTRACE_MASK: { // StackTraceElement\n                String declaringClass = DetailsUtils.getInstanceFieldString(instance, \"declaringClass\"); // NOI18N\n                if (declaringClass != null) {\n                    String methodName = DetailsUtils.getInstanceFieldString(instance, \"methodName\"); // NOI18N\n                    String fileName = DetailsUtils.getInstanceFieldString(instance, \"fileName\"); // NOI18N\n                    int lineNumber = DetailsUtils.getIntFieldValue(instance, \"lineNumber\", -1); // NOi18N\n                    if (methodName == null) methodName = \"Unknown method\";   // NOI18N\n                    StackTraceElement ste = new StackTraceElement(declaringClass, methodName, fileName, lineNumber);\n                    return ste.toString();\n                }\n                break;\n            }\n            default:\n                break;\n        }\n        \n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/MathDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport java.math.BigDecimal;\nimport java.math.BigInteger;\nimport java.nio.ByteBuffer;\nimport java.nio.IntBuffer;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic final class MathDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String BIG_INTEGRER_MASK = \"java.math.BigInteger\"; // NOI18N\n    private static final String BIG_DECIMAL_MASK = \"java.math.BigDecimal\";  // NOI18N\n    private static final String FD_BIG_INTEGRER_MASK = \"jdk.internal.math.FDBigInteger\";  // NOI18N\n\n    public MathDetailsProvider() {\n        super(BIG_INTEGRER_MASK,BIG_DECIMAL_MASK, FD_BIG_INTEGRER_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case BIG_INTEGRER_MASK: {\n                BigInteger bint = getBigInteger(instance);\n                if (bint != null) {\n                    return bint.toString();\n                }\n                break;\n            }\n            case BIG_DECIMAL_MASK: {\n                String val = DetailsUtils.getInstanceFieldString(instance, \"stringCache\");   // NOI18N\n                if (val == null) {\n                    int scale = DetailsUtils.getIntFieldValue(instance, \"scale\", 0);    // NOI18N\n                    long intCompact = DetailsUtils.getLongFieldValue(instance, \"intCompact\", Long.MIN_VALUE);   // NOI18N\n\n                    if (intCompact != Long.MIN_VALUE) {\n                        return BigDecimal.valueOf(intCompact, scale).toString();\n                    } else {\n                        Object bintInstace = instance.getValueOfField(\"intVal\");    // NOI18N\n                        if (bintInstace instanceof Instance) {\n                            BigInteger bint = getBigInteger((Instance)bintInstace);\n\n                            if (bint != null) {\n                                return new BigDecimal(bint, scale).toString();\n                            }\n                        }\n                    }\n                } else {\n                    return val;\n                }\n                break;\n            }\n            case FD_BIG_INTEGRER_MASK: {\n                Integer nWords = (Integer) instance.getValueOfField(\"nWords\");      // NOI18N\n                Integer offset = (Integer) instance.getValueOfField(\"offset\");      // NOI18N\n                int[] data = DetailsUtils.getIntArray(DetailsUtils.getPrimitiveArrayFieldValues(instance, \"data\"));   // NOI18N\n                if (nWords != null && offset != null && data != null) {\n                    byte[] magnitude = new byte[nWords * 4 + 1];\n                    for (int i = 0; i < nWords; i++) {\n                        int w = data[i];\n                        magnitude[magnitude.length - 4 * i - 1] = (byte) w;\n                        magnitude[magnitude.length - 4 * i - 2] = (byte) (w >> 8);\n                        magnitude[magnitude.length - 4 * i - 3] = (byte) (w >> 16);\n                        magnitude[magnitude.length - 4 * i - 4] = (byte) (w >> 24);\n                    }\n                    return new BigInteger(magnitude).shiftLeft(offset * 32).toString();\n                }\n                break;\n            }\n            default:\n                break;\n        }\n        return null;\n    }\n\n    private BigInteger getBigInteger(final Instance instance) {\n        int sig = DetailsUtils.getIntFieldValue(instance, \"signum\", Integer.MAX_VALUE);     // NOI18N\n        int[] mag = DetailsUtils.getIntArray(DetailsUtils.getPrimitiveArrayFieldValues(instance, \"mag\"));   // NOI18N\n        if (mag != null && sig != Integer.MAX_VALUE) {\n            ByteBuffer buffer = ByteBuffer.allocate(mag.length * 4);\n            IntBuffer intBuffer = buffer.asIntBuffer();\n            intBuffer.put(mag);\n            \n            return new BigInteger(sig, buffer.array());\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ModuleDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service = DetailsProvider.class)\npublic final class ModuleDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String MODULE_MASK = \"java.lang.Module\";        // NOI18N\n    private static final String MODULE_DESCR_MASK = \"java.lang.module.ModuleDescriptor\";        // NOI18N\n    private static final String MODULE_VERSION_MASK = \"java.lang.module.ModuleDescriptor$Version\";  // NOI18N\n    private static final String MODULE_REF_MASK = \"java.lang.module.ModuleReference+\";  // NOI18N\n    private static final String RES_MODULE_MASK = \"java.lang.module.ResolvedModule\";  // NOI18N\n\n    public ModuleDetailsProvider() {\n        super(MODULE_MASK, MODULE_DESCR_MASK, MODULE_VERSION_MASK,\n                MODULE_REF_MASK, RES_MODULE_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case MODULE_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"descriptor\");   // NOI18N\n                if (name == null) {\n                    return \"unnamed module #\" + instance.getInstanceNumber();   // NOI18N\n                }\n                return name;\n            }\n            case MODULE_DESCR_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\");   // NOI18N\n                String version = DetailsUtils.getInstanceFieldString(instance, \"version\");   // NOI18N\n\n                if (version == null) {\n                    return name;\n                }\n                return name + \"@\" + version;\n            }\n            case MODULE_VERSION_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"version\");   // NOI18N\n            case RES_MODULE_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"mref\");   // NOI18N\n            case MODULE_REF_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"descriptor\");   // NOI18N\n                String loc = DetailsUtils.getInstanceFieldString(instance, \"location\");   // NOI18N\n                boolean patcher = instance.getValueOfField(\"patcher\") != null;\n                String patched = patcher ? \" (patched)\" : \"\";\n\n                if (loc == null) {\n                    return String.valueOf(name) + patched;            // NOI18N\n                }\n                return String.valueOf(name) + \", \" + loc + patched;  // NOI18N\n            }\n            default:\n                break;\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/NetDetailsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic final class NetDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String URL_MASK = \"java.net.URL\";                          // NOI18N\n    private static final String INET4_ADDRESS_MASK = \"java.net.Inet4Address\";       // NOI18N\n    private static final String INET6_ADDRESS_MASK = \"java.net.Inet6Address\";       // NOI18N\n    private static final String NETWORK_IF_MASK = \"java.net.NetworkInterface\";      // NOI18N\n    private static final String IF_ADDRESS_MASK = \"java.net.InterfaceAddress+\";     // NOI18N\n    private static final String URL_CONN_MASK = \"java.net.URLConnection+\";          // NOI18N\n    private static final String URI_MASK = \"java.net.URI\";                          // NOI18N\n    private static final String HTTP_COOKIE_MASK = \"java.net.HttpCookie\";           // NOI18N\n    private static final String INET_SOCKET_ADDRERSS_MASK = \"java.net.InetSocketAddress+\"; // NOI18N           // NOI18N\n    private static final String INET_SOCKET_ADDR_HOLDER_MASK = \"java.net.InetSocketAddress$InetSocketAddressHolder\"; // NOI18N\n\n    public NetDetailsProvider() {\n        super(URL_MASK, INET4_ADDRESS_MASK, INET6_ADDRESS_MASK, NETWORK_IF_MASK,\n              IF_ADDRESS_MASK, URL_CONN_MASK, URI_MASK, HTTP_COOKIE_MASK,\n              INET_SOCKET_ADDRERSS_MASK, INET_SOCKET_ADDR_HOLDER_MASK);\n    }\n    \n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case URL_MASK: {                 // URL\n                String file = DetailsUtils.getInstanceFieldString(instance, \"file\"); // NOI18N\n                String host = DetailsUtils.getInstanceFieldString(instance, \"host\");  // NOI18N\n                String protocol = DetailsUtils.getInstanceFieldString(instance, \"protocol\");  // NOI18N\n                int port = DetailsUtils.getIntFieldValue(instance, \"port\", -1); // NOI18N\n                if (file != null && protocol != null) {\n                    try {\n                        return new URL(protocol,host,port,file).toExternalForm();\n                    } catch (MalformedURLException ex) {\n\n                    }\n                }\n                // fallback\n                return DetailsUtils.getInstanceFieldString(instance, \"path\"); // NOI18N;\n            }\n            case INET4_ADDRESS_MASK:   // Inet4Address\n            case INET6_ADDRESS_MASK: { // Inet6Address\n                String host;\n                Instance holder = (Instance)instance.getValueOfField(\"holder\");                     // NOI18N\n                if (holder != null) {\n                    // JDK-8015743, variant with holder (6u65, 7u45, 8)\n                    host = DetailsUtils.getInstanceFieldString(holder, \"hostName\");                               // NOI18N\n                    if (INET4_ADDRESS_MASK.equals(className)) {\n                        instance = holder;\n                    } else {\n                        instance = (Instance) instance.getValueOfField(\"holder6\");\n                    }\n                } else {\n                    host = DetailsUtils.getInstanceFieldString(instance, \"hostName\");                               // NOI18N\n                }\n                String addr = null;\n                if (!\"0.0.0.0\".equals(host)) {                                           // NOI18N\n                    if (INET4_ADDRESS_MASK.equals(className)) {\n                        int address = DetailsUtils.getIntFieldValue(\n                                instance, \"address\", 0);                          // NOI18N\n                        addr = getHostInet4Address(address);\n                    } else {\n                        List<String> items = DetailsUtils.getPrimitiveArrayFieldValues(\n                                instance, \"ipaddress\");                  // NOI18N\n                        byte[] ipaddress = DetailsUtils.getByteArray(items);\n                        boolean scope_ifname_set = DetailsUtils.getBooleanFieldValue\n                                                   (instance, \"scope_ifname_set\", false);   // NOI18N\n                        String scope_ifname = null;\n                        if (scope_ifname_set) {\n                            // java.net.NetworkInterface\n                            Object ifname = instance.getValueOfField(\"scope_ifname\");   // NOI18N\n                            if (ifname instanceof Instance) {\n                                // java.net.NetworkInterface.name [java.lang.String]\n                                scope_ifname = DetailsUtils.getInstanceFieldString(instance, \"name\");                 // NOI18N\n                            }\n                        }\n                        boolean scope_id_set = DetailsUtils.getBooleanFieldValue\n                                                   (instance, \"scope_id_set\", false);       // NOI18N\n                        int scope_id = DetailsUtils.getIntFieldValue\n                                                   (instance, \"scope_id\", 0);               // NOI18N\n                        addr = getHostInet6Address(ipaddress, scope_ifname_set,\n                                scope_ifname, scope_id_set, scope_id);\n                    }\n                }\n                if (host == null) {\n                    return addr;\n                }\n                if (addr == null) {\n                    return host;\n                }\n                return host+\" [\"+addr+\"]\";                                              // NOI18N\n            }\n            case NETWORK_IF_MASK: {      // NetworkInterface\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\");                 // NOI18N\n                if (name == null) name = new String();\n                String displayName = DetailsUtils.getInstanceFieldString(instance, \"displayName\");          // NOI18N\n                if (displayName == null) displayName = new String();\n                if (!name.isEmpty() && !displayName.isEmpty()) name += \" - \";           // NOI18N\n                return name + displayName;\n            }\n            case IF_ADDRESS_MASK: { // InterfaceAddress+\n                String address = DetailsUtils.getInstanceFieldString(instance, \"address\");              // NOI18N\n                if (address == null) address = \"\";\n                String broadcast = DetailsUtils.getInstanceFieldString(instance, \"broadcast\");            // NOI18N\n                if (broadcast == null) broadcast = new String();\n                short maskLength = DetailsUtils.getShortFieldValue(\n                        instance, \"maskLength\", (short)0);       // NOI18N\n                return address + \"/\" + maskLength + \" [\" + broadcast + \"]\";                             // NOI18N\n            }\n            case URL_CONN_MASK: {    // URLConnection+\n                String url = DetailsUtils.getInstanceFieldString(instance, \"url\");                  // NOI18N\n                if (url == null) url = \"\";\n                return /*instance.getJavaClass().getName() + \":\" +*/ url;               // NOI18N\n            }\n            case URI_MASK: {                                    // URI\n                String name = DetailsUtils.getInstanceFieldString(instance, \"string\");                 // NOI18N\n                if (name != null) return name;\n                String scheme = DetailsUtils.getInstanceFieldString(instance, \"scheme\");               // NOI18N\n                String path = DetailsUtils.getInstanceFieldString(instance, \"path\");                 // NOI18N\n                String schemeSpecificPart = DetailsUtils.getInstanceFieldString(instance, \"schemeSpecificPart\");   // NOI18N\n                String host = DetailsUtils.getInstanceFieldString(instance, \"host\");                 // NOI18N\n                String userInfo = DetailsUtils.getInstanceFieldString(instance, \"userInfo\");             // NOI18N\n                int port = DetailsUtils.getIntFieldValue(\n                        instance, \"name\", -1);                   // NOI18N\n                String authority = DetailsUtils.getInstanceFieldString(instance, \"authority\");            // NOI18N\n                String query = DetailsUtils.getInstanceFieldString(instance, \"query\");                // NOI18N\n                String fragment = DetailsUtils.getInstanceFieldString(instance, \"fragment\");             // NOI18N\n                return defineURIString(scheme, path, schemeSpecificPart, host,\n                        userInfo, port, authority, query, fragment);\n            }\n            case HTTP_COOKIE_MASK: {                            // HttpCookie\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\");                 // NOI18N\n                String value = DetailsUtils.getInstanceFieldString(instance, \"value\");                // NOI18N\n                return name + \"=\" + value;                                              // NOI18N\n            }\n            case INET_SOCKET_ADDRERSS_MASK: {\n                String holder = DetailsUtils.getInstanceFieldString(instance, \"holder\");  // NOI18N\n                if (holder != null) return holder;\n                return getInetSocketAddress(instance);\n            }\n            case INET_SOCKET_ADDR_HOLDER_MASK:\n                return getInetSocketAddress(instance);\n            default:\n                break;\n        }\n        return null;\n    }\n\n    private String getInetSocketAddress(Instance instance) {\n        String host = DetailsUtils.getInstanceFieldString(instance, \"hostname\");  // NOI18N\n        String address = DetailsUtils.getInstanceFieldString(instance, \"addr\"); // NOI18N\n        int port = DetailsUtils.getIntFieldValue(instance, \"port\", -1); // NOI18N\n        StringBuilder str = new StringBuilder();\n        if (host != null) {\n            str.append(host);\n        }\n        if (address != null) {\n            if (host != null) {\n                str.append(\"[\").append(address).append(\"]\");    // NOI18N\n            } else {\n                str.append(address);\n            }\n        }\n        str.append(\":\").append(port);       // NOI18N\n        return str.toString();\n    }\n    \n    \n    // --- Inet4Address.getHostAddress() ---------------------------------------\n    \n    private static String getHostInet4Address(int address) {\n        return numericToTextFormatInet4(getInet4Address(address));\n    }\n    \n    private static byte[] getInet4Address(int address) {\n        byte[] addr = new byte[4];\n\n        addr[0] = (byte) ((address >>> 24) & 0xFF);\n        addr[1] = (byte) ((address >>> 16) & 0xFF);\n        addr[2] = (byte) ((address >>> 8) & 0xFF);\n        addr[3] = (byte) (address & 0xFF);\n        return addr;\n    }\n    \n    private static String numericToTextFormatInet4(byte[] src) {\n        return (src[0] & 0xff) + \".\" + (src[1] & 0xff) + \".\" +                      // NOI18N\n               (src[2] & 0xff) + \".\" + (src[3] & 0xff);                             // NOI18N\n    }\n    \n    \n    // --- Inet6Address.getHostAddress() ---------------------------------------\n    \n    public String getHostInet6Address(byte[] ipaddress, boolean scope_ifname_set,\n                                      String scope_ifname, boolean scope_id_set,\n                                      int scope_id) {\n        String s = numericToTextFormatInet6(ipaddress);\n        if (scope_ifname_set) { /* must check this first */\n            s = s + \"%\" + scope_ifname;                                             // NOI18N\n        } else if (scope_id_set) {\n            s = s + \"%\" + scope_id;                                                 // NOI18N\n        }\n        return s;\n    }\n    \n    private static String numericToTextFormatInet6(byte[] src) {\n        StringBuilder sb = new StringBuilder(39);\n        for (int i = 0; i < 8; i++) {\n            sb.append(Integer.toHexString(((src[i<<1]<<8) & 0xff00)\n                                          | (src[(i<<1)+1] & 0xff)));\n            if (i < 7) {\n               sb.append(\":\");                                                      // NOI18N\n            }\n        }\n        return sb.toString();\n    }\n    \n    \n    // --- URI.defineString() --------------------------------------------------\n    \n    private String defineURIString(String scheme, String path,\n            String schemeSpecificPart, String host, String userInfo, int port,\n            String authority, String query, String fragment) {\n        StringBuilder sb = new StringBuilder();\n        if (scheme != null) {\n            sb.append(scheme);\n            sb.append(':');                                                         // NOI18N\n        }\n        if (path == null) {\n            sb.append(schemeSpecificPart);\n        } else {\n            if (host != null) {\n                sb.append(\"//\");                                                    // NOI18N\n                if (userInfo != null) {\n                    sb.append(userInfo);\n                    sb.append('@');                                                 // NOI18N\n                }\n                boolean needBrackets = ((host.indexOf(':') >= 0)                    // NOI18N\n                                    && !host.startsWith(\"[\")                        // NOI18N\n                                    && !host.endsWith(\"]\"));                        // NOI18N\n                if (needBrackets) sb.append('[');                                   // NOI18N\n                sb.append(host);\n                if (needBrackets) sb.append(']');                                   // NOI18N\n                if (port != -1) {\n                    sb.append(':');                                                 // NOI18N\n                    sb.append(port);\n                }\n            } else if (authority != null) {\n                sb.append(\"//\");                                                    // NOI18N\n                sb.append(authority);\n            }\n            if (path != null)\n                sb.append(path);\n            if (query != null) {\n                sb.append('?');                                                     // NOI18N\n                sb.append(query);\n            }\n        }\n        if (fragment != null) {\n            sb.append('#');                                                         // NOI18N\n            sb.append(fragment);\n        }\n        return sb.toString();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/NioDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport java.nio.charset.Charset;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service = DetailsProvider.class)\npublic final class NioDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String UNIXPATH_MASK = \"sun.nio.fs.UnixPath\"; // NOI18N\n    private static final String WINDOWSPATH_MASK = \"sun.nio.fs.WindowsPath+\"; // NOI18N\n    private static final String FCI_MASK = \"sun.nio.ch.FileChannelImpl\";        // NOI18N\n    private static final String BUFFER_MASK = \"java.nio.Buffer+\";               // NOI18N\n    private static final String HEAPCHARBUFFER_MASK = \"java.nio.HeapCharBuffer\";// NOI18N\n\n    private long lastHeapId;\n    private Charset lastJnuEncoding;\n\n    public NioDetailsProvider() {\n        super(UNIXPATH_MASK, WINDOWSPATH_MASK, FCI_MASK, BUFFER_MASK, HEAPCHARBUFFER_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case UNIXPATH_MASK: {\n                String path = DetailsUtils.getInstanceFieldString(instance, \"stringValue\");   // NOI18N\n                if (path != null) {\n                    return path;\n                }   Charset encoding = getJnuEncoding(instance.getJavaClass().getHeap());\n                List<String> pathItems = DetailsUtils.getPrimitiveArrayFieldValues(instance, \"path\");                  // NOI18N\n                byte[] pathArr = DetailsUtils.getByteArray(pathItems);\n                if (pathArr != null) {\n                    return new String(pathArr, encoding);\n                }\n                break;\n            }\n            case WINDOWSPATH_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"path\");   // NOI18N\n            case FCI_MASK: // FileChannelImpl\n                return DetailsUtils.getInstanceFieldString(instance, \"path\"); // NOI18N\n            case BUFFER_MASK: {\n                int position = DetailsUtils.getIntFieldValue(instance, \"position\", -1); // NOI18N\n                int limit = DetailsUtils.getIntFieldValue(instance, \"limit\", -1);       // NOI18N\n                int capacity = DetailsUtils.getIntFieldValue(instance, \"capacity\", -1);       // NOI18N\n                return String.format(\"[pos=%d lim=%d cap=%d]\", position, limit, capacity); // NOI18N\n            }\n            case HEAPCHARBUFFER_MASK: {\n                int position = DetailsUtils.getIntFieldValue(instance, \"position\", -1); // NOI18N\n                int limit = DetailsUtils.getIntFieldValue(instance, \"limit\", -1);       // NOI18N\n                int offset = DetailsUtils.getIntFieldValue(instance, \"offset\", -1);       // NOI18N\n                return DetailsUtils.getPrimitiveArrayFieldString(instance, \"hb\", position + offset, limit - position, null, \"...\"); // NOI18N\n            }\n            default:\n                break;\n        }\n        return null;\n    }\n\n    private Charset getJnuEncoding(Heap heap) {\n        if (lastHeapId != System.identityHashCode(heap)) {\n            String encoding = heap.getSystemProperties().getProperty(\"sun.jnu.encoding\", \"UTF-8\"); // NOI18N\n            lastJnuEncoding = Charset.forName(encoding);\n            lastHeapId = System.identityHashCode(heap);\n        }\n        return lastJnuEncoding;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ReferenceDetailsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport java.lang.ref.Reference;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.model.BrowserUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic final class ReferenceDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String FEEBLE_REF_MASK = \"com.oracle.svm.core.heap.FeebleReference+\";  // NOI18N\n\n    public ReferenceDetailsProvider() {\n        super(Reference.class.getName() + \"+\", FEEBLE_REF_MASK);                // NOI18N\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        if (FEEBLE_REF_MASK.equals(className)) {\n            Object value = instance.getValueOfField(\"rawReferent\");             // NOI18N\n            if (value instanceof Instance) {\n                return getRefDetail(value);\n            }\n        } else {\n            Object value = instance.getValueOfField(\"referent\");                // NOI18N\n            if (value instanceof Instance) {\n                return getRefDetail(value);\n            }\n            value = instance.getValueOfField(\"feeble\");                         // NOI18N\n            if (value instanceof Instance) {\n                return DetailsUtils.getInstanceString((Instance) value);\n            }\n            value = instance.getValueOfField(\"bootImageStrongValue\");           // NOI18N\n            if (value instanceof Instance) {\n                return getRefDetail(value);\n            }\n        }\n        return null;\n    }\n\n    private String getRefDetail(Object value) {\n        Instance i = (Instance)value;\n        // TODO: can create cycle?\n        String s = DetailsUtils.getInstanceString(i);\n        s = s == null ? \"#\" + i.getInstanceNumber() : \": \" + s;                 // NOI18N\n        return BrowserUtils.getSimpleType(i.getJavaClass().getName()) + s;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ReflectionDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport java.lang.reflect.Modifier;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.model.BrowserUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic class ReflectionDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String CLASS_MASK = \"java.lang.Class\";                     // NOI18N\n    private static final String CONSTRUCTOR_MASK = \"java.lang.reflect.Constructor\"; // NOI18N\n    private static final String METHOD_MASK = \"java.lang.reflect.Method\";           // NOI18N\n    private static final String FIELD_MASK = \"java.lang.reflect.Field\";             // NOI18N\n    private static final String PARAMETER_MASK = \"java.lang.reflect.Parameter\";     // NOI18N\n\n    public ReflectionDetailsProvider() {\n        super(CLASS_MASK,CONSTRUCTOR_MASK, METHOD_MASK, FIELD_MASK, PARAMETER_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case CLASS_MASK: {                                     // Class\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n                if (name == null && CLASS_MASK.equals(instance.getJavaClass().getName())) {\n                    Heap heap = instance.getJavaClass().getHeap();\n                    JavaClass jclass = heap.getJavaClassByID(instance.getInstanceId());\n                    if (jclass != null) name = BrowserUtils.getSimpleType(jclass.getName());\n//                if (jclass != null) name = jclass.getName();\n                }\n                return name;\n            }\n            case CONSTRUCTOR_MASK: {   // Constructor\n                Object value = instance.getValueOfField(\"clazz\");                   // NOI18N\n                if (value instanceof Instance) return getDetailsString(\"java.lang.Class\", (Instance)value); // NOI18N\n                break;\n            }\n            case METHOD_MASK:          // Method\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            case FIELD_MASK: {         // Field\n                int mod = DetailsUtils.getIntFieldValue(instance, \"modifiers\", 0);\n                String type = DetailsUtils.getInstanceFieldString(instance, \"type\"); // NOI18N\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n                String clazz = DetailsUtils.getInstanceFieldString(instance, \"clazz\"); // NOI18N\n\n                return (((mod == 0) ? \"\" : (Modifier.toString(mod) + \" \"))\n                        + type + \" \" + clazz + \".\" + name);\n            }\n            case PARAMETER_MASK:        // Parameter\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            default:\n                break;\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/SecurityDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service = DetailsProvider.class)\npublic class SecurityDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String CODE_MASK = \"java.security.CodeSource\";         // NOI18N\n\n    public SecurityDetailsProvider() {\n        super(CODE_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case CODE_MASK: { // CodeSource\n                return DetailsUtils.getInstanceFieldString(instance, \"location\"); // NOI18N\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ThreadDetailsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport java.util.Locale;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic final class ThreadDetailsProvider extends DetailsProvider.Basic {\n    private static final String VIRTUAL_THREAD_MASK = \"java.lang.VirtualThread\";                    // NOI18N\n\n    public ThreadDetailsProvider() {\n        super(Thread.class.getName() + \"+\", ThreadGroup.class.getName() + \"+\",\n                VIRTUAL_THREAD_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case VIRTUAL_THREAD_MASK:\n                StringBuilder sb = new StringBuilder(\"[#\");                     // NOI18N\n                sb.append(instance.getValueOfField(\"tid\"));                     // NOI18N\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n                if (!name.isEmpty()) {\n                    sb.append(\",\");                                             // NOI18N\n                    sb.append(name);\n                }\n                sb.append(\"]/\");                                                // NOI18N\n                Instance carrier = (Instance) instance.getValueOfField(\"carrierThread\");  // NOI18N\n                if (carrier != null) {\n                    // include the carrier thread state and name when mounted\n                    Instance holder = (Instance) carrier.getValueOfField(\"holder\"); // NOI18N\n                    Integer threadStatus = (Integer)holder.getValueOfField(\"threadStatus\"); // NOI18N\n                    String stateAsString = toThreadState(threadStatus.intValue()).toString();\n                    sb.append(stateAsString.toLowerCase(Locale.ROOT));\n                    sb.append('@');\n                    sb.append(DetailsUtils.getInstanceString(carrier));\n                }\n                // include virtual thread state when not mounted\n                if (carrier == null) {\n                    String stateAsString = getThreadState(instance);\n                    sb.append(stateAsString.toLowerCase(Locale.ROOT));\n                }\n                return sb.toString();\n            default:\n                return DetailsUtils.getInstanceFieldString(instance, \"name\");   // NOI18N\n        }\n    }\n\n    /** taken from sun.misc.VM\n     *\n     * Returns Thread.State for the given threadStatus\n     */\n    public static Thread.State toThreadState(int threadStatus) {\n        if ((threadStatus & JVMTI_THREAD_STATE_RUNNABLE) != 0) {\n            return Thread.State.RUNNABLE;\n        } else if ((threadStatus & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) != 0) {\n            return Thread.State.BLOCKED;\n        } else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) != 0) {\n            return Thread.State.WAITING;\n        } else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) != 0) {\n            return Thread.State.TIMED_WAITING;\n        } else if ((threadStatus & JVMTI_THREAD_STATE_TERMINATED) != 0) {\n            return Thread.State.TERMINATED;\n        } else if ((threadStatus & JVMTI_THREAD_STATE_ALIVE) == 0) {\n            return Thread.State.NEW;\n        } else {\n            return Thread.State.RUNNABLE;\n        }\n    }\n\n     /* The threadStatus field is set by the VM at state transition\n     * in the hotspot implementation. Its value is set according to\n     * the JVM TI specification GetThreadState function.\n     */\n    private final static int JVMTI_THREAD_STATE_ALIVE = 0x0001;\n    private final static int JVMTI_THREAD_STATE_TERMINATED = 0x0002;\n    private final static int JVMTI_THREAD_STATE_RUNNABLE = 0x0004;\n    private final static int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400;\n    private final static int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010;\n    private final static int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;\n\n    private String getThreadState(Instance virtualThread) {\n        Integer state = (Integer)virtualThread.getValueOfField(\"state\");\n        switch (state) {\n            case NEW: return \"new\"; // NOI18N\n            case STARTED: return \"started\"; //NOI18N\n            case RUNNABLE: return \"runnable\";     // runnable-unmounted\n            case RUNNING: return \"running\";     // runnable-mounted\n            case PARKING: return \"parking\";\n            case PARKED: return \"parked\";     // unmounted\n            case PINNED: return \"pinned\";     // mounted\n            case YIELDING: return \"yelding\";     // Thread.yield\n            case TERMINATED: return \"terminated\";  // final state\n            default: return \"unknown\";   // NOI18N\n        }\n    }\n\n    /*\n     * Virtual thread state and transitions:\n     *\n     *      NEW -> STARTED         // Thread.start\n     *  STARTED -> TERMINATED      // failed to start\n     *  STARTED -> RUNNING         // first run\n     *\n     *  RUNNING -> PARKING         // Thread attempts to park\n     *  PARKING -> PARKED          // cont.yield successful, thread is parked\n     *  PARKING -> PINNED          // cont.yield failed, thread is pinned\n     *\n     *   PARKED -> RUNNABLE        // unpark or interrupted\n     *   PINNED -> RUNNABLE        // unpark or interrupted\n     *\n     * RUNNABLE -> RUNNING         // continue execution\n     *\n     *  RUNNING -> YIELDING        // Thread.yield\n     * YIELDING -> RUNNABLE        // yield successful\n     * YIELDING -> RUNNING         // yield failed\n     *\n     *  RUNNING -> TERMINATED      // done\n     */\n    private static final int NEW      = 0;\n    private static final int STARTED  = 1;\n    private static final int RUNNABLE = 2;     // runnable-unmounted\n    private static final int RUNNING  = 3;     // runnable-mounted\n    private static final int PARKING  = 4;\n    private static final int PARKED   = 5;     // unmounted\n    private static final int PINNED   = 6;     // mounted\n    private static final int YIELDING = 7;     // Thread.yield\n    private static final int TERMINATED = 99;  // final state\n\n    // can be suspended from scheduling when unmounted\n    private static final int SUSPENDED = 1 << 8;\n    private static final int RUNNABLE_SUSPENDED = (RUNNABLE | SUSPENDED);\n    private static final int PARKED_SUSPENDED   = (PARKED | SUSPENDED);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/TimeDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport java.time.Instant;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic final class TimeDetailsProvider extends DetailsProvider.Basic {\n    private static final String INSTANT_MASK = \"java.time.Instant\"; // NOI18N\n\n    public TimeDetailsProvider() {\n        super(INSTANT_MASK);\n    }\n\n    public String getDetailsString(String className, Instance instance) {\n        if (INSTANT_MASK.equals(className)) {\n            Instant instant = getInstant(instance);\n            if (instant != null) return instant.toString();\n        }\n        return null;\n    }\n\n    static Instant getInstant(Object instant) {\n        if (instant instanceof Instance) {\n            Instance instantObj = (Instance) instant;\n            long seconds = DetailsUtils.getLongFieldValue(instantObj, \"seconds\", -1);     // NOI18N\n            int nanos = DetailsUtils.getIntFieldValue(instantObj, \"nanos\", -1);      // NOI18N\n\n            if (seconds != -1 && nanos != -1) {\n                return Instant.ofEpochSecond(seconds, nanos);\n            }\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/UtilDetailsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk;\n\nimport java.time.Instant;\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.List;\nimport java.util.UUID;\nimport java.util.logging.Formatter;\nimport java.util.logging.Level;\nimport java.util.logging.LogRecord;\nimport java.util.logging.SimpleFormatter;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic final class UtilDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String LOGGER_MASK = \"java.util.logging.Logger+\";      // NOI18N\n    private static final String LEVEL_MASK = \"java.util.logging.Level+\";        // NOI18N\n    private static final String LOCALE_MASK = \"java.util.Locale\";               // NOI18N\n    private static final String DATE_MASK = \"java.util.Date+\";                  // NOI18N\n    private static final String TIMEZONE_MASK = \"java.util.TimeZone+\";          // NOI18N\n    private static final String PATTERN_MASK = \"java.util.regex.Pattern\";       // NOI18N\n    private static final String CURRENCY_MASK = \"java.util.Currency\";           // NOI18N\n    private static final String ZIPENTRY_MASK = \"java.util.zip.ZipEntry+\";      // NOI18N\n    private static final String LOGRECORD_MASK = \"java.util.logging.LogRecord\"; // NOI18N\n    private static final String ATTR_NAME_MASK = \"java.util.jar.Attributes$Name\";    // NOI18N\n    private static final String COLLECTION_MASK = \"java.util.AbstractCollection+\";   // NOI18N\n    private static final String MAP_MASK = \"java.util.AbstractMap+\";            // NOI18N\n    private static final String A_SET_MASK = \"java.util.AbstractSet+\";          // NOI18N\n    private static final String VECTOR_MASK = \"java.util.Vector+\";              // NOI18N\n    private static final String SET_MASK = \"java.util.HashSet+\";                 // NOI18N\n    private static final String TREESET_MASK = \"java.util.TreeSet\";             // NOI18N\n    private static final String HASHTABLE_MASK = \"java.util.Hashtable+\";        // NOI18N\n    private static final String PROP_MASK = \"java.util.Properties+\";            // NOI18N\n    private static final String UUID_MASK = \"java.util.UUID\";                   // NOI18N\n    private static final String UNMOD_COLLECTION_MASK = \"java.util.Collections$UnmodifiableCollection+\";    // NOI18N\n    private static final String UNMOD_MAP_MASK = \"java.util.Collections$UnmodifiableMap+\";    // NOI18N\n    private static final String ARRAYS_LIST_MASK = \"java.util.Arrays$ArrayList\";       // NOI18N\n    private static final String EMPTY_LIST_MASK = \"java.util.Collections$EmptyList\";   // NOI18N\n    private static final String EMPTY_SET_MASK = \"java.util.Collections$EmptySet\";   // NOI18N\n    private static final String EMPTY_MAP_MASK = \"java.util.Collections$EmptyMap\";   // NOI18N\n    private static final String SINGLETON_LIST_MASK = \"java.util.Collections$SingletonList\";   // NOI18N\n    private static final String SINGLETON_SET_MASK = \"java.util.Collections$SingletonSet\";   // NOI18N\n    private static final String SINGLETON_MAP_MASK = \"java.util.Collections$SingletonMap\";   // NOI18N\n    private static final String SYN_COLLECTION_MASK = \"java.util.Collections$SynchronizedCollection+\";   // NOI18N\n    private static final String SYN_MAP_MASK = \"java.util.Collections$SynchronizedMap+\";   // NOI18N\n    private static final String DEQUE_MASK = \"java.util.ArrayDeque+\";           // NOI18N\n    private static final String ENUM_SET_MASK = \"java.util.RegularEnumSet\";     // NOI18N\n    private static final String CONCURRENT_MAP_MASK = \"java.util.concurrent.ConcurrentHashMap\";     // NOI18N\n    private static final String SET12_MASK = \"java.util.ImmutableCollections$Set12\"; //NOI18N\n    private static final String LIST12_MASK = \"java.util.ImmutableCollections$List12\"; //NOI18N\n    private static final String LISTN_MASK = \"java.util.ImmutableCollections$ListN\"; // NOI18N\n    private static final String MAP1_MASK = \"java.util.ImmutableCollections$Map1\"; // NOI18N\n    \n    private Formatter formatter = new SimpleFormatter();\n\n    public UtilDetailsProvider() {\n        super(LOGGER_MASK, LEVEL_MASK, LOCALE_MASK, DATE_MASK, TIMEZONE_MASK,\n              PATTERN_MASK, CURRENCY_MASK, ZIPENTRY_MASK, LOGRECORD_MASK,\n              ATTR_NAME_MASK, COLLECTION_MASK, MAP_MASK, A_SET_MASK, VECTOR_MASK,\n              SET_MASK, TREESET_MASK, HASHTABLE_MASK, PROP_MASK, UUID_MASK,\n              UNMOD_COLLECTION_MASK, UNMOD_MAP_MASK, ARRAYS_LIST_MASK,\n              EMPTY_LIST_MASK, EMPTY_MAP_MASK, EMPTY_SET_MASK,\n              SINGLETON_LIST_MASK, SINGLETON_MAP_MASK, SINGLETON_SET_MASK,\n              SYN_COLLECTION_MASK, SYN_MAP_MASK, DEQUE_MASK, ENUM_SET_MASK,\n              CONCURRENT_MAP_MASK, SET12_MASK, LIST12_MASK, LISTN_MASK,\n              MAP1_MASK);\n    }\n    \n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case LOGGER_MASK:\n            case LEVEL_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            case LOCALE_MASK: {\n                String language = DetailsUtils.getInstanceFieldString(instance, \"language\");                                // NOI18N\n                if (language == null) language = \"\";                                // NOI18N\n                String country = DetailsUtils.getInstanceFieldString(instance, \"country\");                                 // NOI18N\n                if (country == null) country = \"\";                                  // NOI18N\n                if (!language.isEmpty() || !country.isEmpty()) {\n                    if (language.isEmpty() || country.isEmpty())\n                        return language + country;\n                    else\n                        return language + \"_\" + country;                            // NOI18N\n                }\n                break;\n            }\n            case DATE_MASK: {\n                long fastTime = DetailsUtils.getLongFieldValue(\n                        instance, \"fastTime\", -1);                                  // NOI18N\n                return new Date(fastTime).toString();\n            }\n            case TIMEZONE_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"ID\");                                      // NOI18N\n            case PATTERN_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"pattern\");                                 // NOI18N\n            case CURRENCY_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"currencyCode\");                            // NOI18N\n            case ZIPENTRY_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\");                                    // NOI18N\n                long size = DetailsUtils.getLongFieldValue(\n                        instance, \"size\", -1);                                      // NOI18N\n                if (name != null && size != -1) {\n                    return String.format(\"%s, size=%d\", name, size);                // NOI18N\n                }\n                return name;\n            }\n            case LOGRECORD_MASK:\n                return formatter.format(new DetailsLogRecord(instance));\n            case ATTR_NAME_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n            case COLLECTION_MASK:\n            case MAP_MASK: {\n                int size = DetailsUtils.getIntFieldValue(instance, \"size\", -1);  // NOI18N\n                if (size != -1) {\n                    return getElementsString(size);\n                }\n                break;\n            }\n            case VECTOR_MASK: {\n                int elements = DetailsUtils.getIntFieldValue(instance, \"elementCount\", -1); // NOI18N\n                if (elements != -1) {\n                    return getElementsString(elements);\n                }\n                break;\n            }\n            case SET_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"map\"); // NOI18N\n            case A_SET_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"this$0\"); // NOI18N\n            case TREESET_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"m\");    // NOI18N\n            case HASHTABLE_MASK: {\n                int elements = DetailsUtils.getIntFieldValue(instance, \"count\", -1);     // NOI18N\n                if (elements != -1) {\n                    return getElementsString(elements);\n                }\n                break;\n            }\n            case PROP_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"map\");    // NOI18N\n            case UUID_MASK: {\n                long mostSigBits = DetailsUtils.getLongFieldValue(instance, \"mostSigBits\", -1);  // NOI18N\n                long leastSigBits = DetailsUtils.getLongFieldValue(instance, \"leastSigBits\", -1);// NOI18N\n                if (mostSigBits != -1 && leastSigBits != -1) {\n                    return new UUID(mostSigBits, leastSigBits).toString();\n                }\n                break;\n            }\n            case UNMOD_COLLECTION_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"c\");    // NOI18N\n            case UNMOD_MAP_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"m\");    // NOI18N\n            case ARRAYS_LIST_MASK:{\n                ObjectArrayInstance arr = (ObjectArrayInstance) instance.getValueOfField(\"a\");  // NOI18N\n                if (arr != null) {\n                    return getElementsString(arr.getLength());\n                }\n                break;\n            }\n            case EMPTY_LIST_MASK:\n            case EMPTY_MAP_MASK:\n            case EMPTY_SET_MASK:\n                return getElementsString(0);\n            case SINGLETON_LIST_MASK:\n            case SINGLETON_MAP_MASK:\n            case SINGLETON_SET_MASK:\n                return getElementsString(1);\n            case DEQUE_MASK: {\n                int head = DetailsUtils.getIntFieldValue(instance, \"head\", -1); // NOI18N\n                int tail = DetailsUtils.getIntFieldValue(instance, \"tail\", -1); // NOI18N\n                ObjectArrayInstance arr = (ObjectArrayInstance) instance.getValueOfField(\"elements\");   // NOI18N\n                if (head != -1 && tail != -1 && arr != null) {\n                    int size = (tail - head) & (arr.getLength() - 1);\n                    return getElementsString(size);\n                }\n                break;\n            }\n            case SYN_COLLECTION_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"c\");    // NOI18N\n            case SYN_MAP_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"m\");    // NOI18N\n            case ENUM_SET_MASK: {\n                Object elements = instance.getValueOfField(\"elements\");             // NOI18N\n                if (elements instanceof Long) {\n                    return getElementsString(Long.bitCount((Long)elements));\n                }\n                break;\n            }\n            case CONCURRENT_MAP_MASK: {\n                long baseCount = DetailsUtils.getLongFieldValue(instance, \"baseCount\", -1);     // NOI18N\n                ObjectArrayInstance counterCells = (ObjectArrayInstance)instance.getValueOfField(\"counterCells\");  // NOI18N\n                if (baseCount != -1) {\n                    return getElementsString(getConcurrentMapSize(baseCount, counterCells));\n                }\n                break;\n            }\n            case SET12_MASK:\n            case LIST12_MASK: {\n                Object e1 = instance.getValueOfField(\"e1\");     // NOI18N\n                return getElementsString(e1 != null ? 2 : 1);\n            }\n            case LISTN_MASK: {\n                Object elements = instance.getValueOfField(\"elements\"); // NOI18N\n                if (elements instanceof ObjectArrayInstance) {\n                    return getElementsString(((ObjectArrayInstance)elements).getLength());\n                }\n                break;\n            }\n            case MAP1_MASK: {\n                return getElementsString(1);\n            }\n            default:\n                break;\n        }\n        return null;\n    }\n    \n    @NbBundle.Messages({\n        \"UtilDetailsProvider_OneItemString=1 element\",                          // NOI18N\n        \"# {0} - number of elements\",                                           // NOI18N\n        \"UtilDetailsProvider_ItemsNumberString={0} elements\"                    // NOI18N\n    })\n    private static String getElementsString(int length) {\n        return length == 1 ? Bundle.UtilDetailsProvider_OneItemString() :\n                             Bundle.UtilDetailsProvider_ItemsNumberString(length);\n    }\n\n    private int getConcurrentMapSize(long baseCount, ObjectArrayInstance counterCells) {\n        long n = getConcurrentMapSumCount(baseCount, counterCells);\n        return ((n < 0L) ? 0 :\n                (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE :\n                (int)n);\n    }\n\n    private long getConcurrentMapSumCount(long baseCount, ObjectArrayInstance counterCells) {\n        long sum = baseCount;\n\n        if (counterCells != null) {\n            List<Instance> as = counterCells.getValues();\n            Instance a;\n\n            for (int i = 0; i < as.size(); ++i) {\n                if ((a = as.get(i)) != null)\n                    sum += DetailsUtils.getLongFieldValue(a, \"value\", 0);   // NOI18N\n            }\n        }\n        return sum;\n    }\n\n    private static class DetailsLogRecord extends LogRecord {\n        private final Instance record;\n\n        private DetailsLogRecord(Instance rec) {\n            super(Level.ALL, null);\n            record = rec;\n        }\n\n        @Override\n        public long getMillis() {\n            return getInstant().toEpochMilli();\n        }\n\n        @Override\n        public String getSourceClassName() {\n            return DetailsUtils.getInstanceFieldString(record, \"sourceClassName\");    // NOI18N\n        }\n\n        @Override\n        public String getSourceMethodName() {\n            return DetailsUtils.getInstanceFieldString(record, \"sourceMethodName\");   // NOI18N\n        }\n\n        @Override\n        public String getLoggerName() {\n            return DetailsUtils.getInstanceFieldString(record, \"loggerName\"); // NOI18N\n        }\n\n        @Override\n        public String getMessage() {\n            return DetailsUtils.getInstanceFieldString(record, \"message\");    // NOI18N\n        }\n\n        // @Override since JDK 9\n        public Instant getInstant() {\n            Object instant = record.getValueOfField(\"instant\");     // NOI18N\n            if (instant instanceof Instance) {\n                return TimeDetailsProvider.getInstant(instant);\n            }\n            Object time = record.getValueOfField(\"millis\");\n            if (time instanceof Number) {\n                return Instant.ofEpochMilli(((Number)time).longValue());\n            }\n            return Instant.EPOCH;\n        }\n\n        @Override\n        public Object[] getParameters() {\n            Object pars = record.getValueOfField(\"parameters\");\n            if (pars instanceof ObjectArrayInstance) {\n                List<String> parameters = new ArrayList<>();\n\n                for (Instance o : ((ObjectArrayInstance)pars).getValues()) {\n                    String par = null;\n                    if (o != null) {\n                        par = DetailsUtils.getInstanceString(o);\n                    }\n                    if (par == null) par = \"\";\n                    parameters.add(par);\n                }\n                return parameters.toArray();\n            }\n            return null;\n        }\n\n        @Override\n        public Level getLevel() {\n            String level = DetailsUtils.getInstanceFieldString(record, \"level\");  // NOI18N\n            try {\n                return Level.parse(level);\n            } catch (RuntimeException ex) {\n                // custom level, construct level directly\n                Instance levelObj = (Instance)record.getValueOfField(\"level\");  // NOI18N\n                Integer value = (Integer)levelObj.getValueOfField(\"value\");     // NOI18N\n                if (level == null) level = \"NULL\";        // NOI18N\n                return new CustomLevel(level, value);     // NOI18N\n            }\n        }\n    }\n\n    private static class CustomLevel extends Level {\n        private CustomLevel(String name, int value) {\n            super(name, value);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/image/FieldAccessor.java",
    "content": "/*\n * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.image;\n\nimport java.lang.reflect.Array;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n * Utilities to access fields of heap dump instances.\n *\n * @author Jan Taus\n */\npublic class FieldAccessor {\n\n    private final InstanceBuilderRegistry registry;\n\n    public FieldAccessor() {\n        this(new InstanceBuilderRegistry());\n    }\n\n    FieldAccessor(InstanceBuilderRegistry registry) {\n        this.registry = registry;\n    }\n\n    // Utils -----------------------------------------------------------------------------\n    public static String getClassMask(Class<?> type, boolean subtypes) {\n        if (subtypes) {\n            return type.getName() + \"+\"; // NOI18N\n        }\n        return type.getName();\n    }\n\n    public static boolean matchClassMask(Instance instance, String mask) {\n        if (mask.endsWith(\"+\")) {\n            return DetailsUtils.isSubclassOf(instance, mask.substring(0, mask.length() - 1));\n        }\n        return DetailsUtils.isInstanceOf(instance, mask);\n    }\n\n    public static boolean isInstanceOf(Instance instance, Class<?> type) {\n        if (instance == null) {\n            return false;\n        }\n        return instance.getJavaClass().getName().equals(type.getName());\n    }\n\n    /**\n     * Exception thrown by the field accessors if the field doesn't exists or has unexpected value.\n     */\n    public static class InvalidFieldException extends Exception {\n\n        public InvalidFieldException() {\n            super();\n        }\n\n        public InvalidFieldException(String message, Object... args) {\n            super(String.format(message, args));\n        }\n\n        public InvalidFieldException(Instance instance, String field, String message) {\n            this(instance, field, \"%s\", message);\n        }\n\n        public InvalidFieldException(Instance instance, String field, String message, Object... args) {\n            this(\"%s#%d->%s: %s\", // NOI18N\n                    instance == null ? \"null\" : instance.getJavaClass().getName(), // NOI18N\n                    instance == null ? -1: instance.getInstanceNumber(), // NOI18N\n                    field, String.format(message, args));\n        }\n\n        public InvalidFieldException(String message) {\n            super(message);\n        }\n\n        @Override\n        public synchronized InvalidFieldException initCause(Throwable cause) {\n            super.initCause(cause);\n            return this;\n        }\n    }\n\n    public static <T> T notNull(T value) throws InvalidFieldException {\n        return notNullCheck(value, false);\n    }\n\n    public static <T> T notNullCheck(T value, boolean allowNull) throws InvalidFieldException {\n        if (!allowNull && value == null) {\n            throw new InvalidFieldException(\"Unexpected null value\"); // NOI18N\n        }\n        return value;\n    }\n\n    public static <T> T castValue(Object value, Class<T> type) throws InvalidFieldException {\n        if (value == null) {\n            return null;\n        }\n        if (!type.isInstance(value)) {\n            throw new InvalidFieldException(\"Value is %s but %s is expected\", // NOI18N\n                    value.getClass().getName(),\n                    type.getName());\n        }\n        return type.cast(value);\n    }\n\n    // Checked field accessor   --------------------------------------------\n    /**\n     * Return value of the field casted to the specific object (primitive type object or instance subclass).\n     *\n     * @param allowNull if false then null is never returned and call fails with exception\n     */\n    public <T> T get(Instance instance, String field, Class<T> type, boolean allowNull) throws InvalidFieldException {\n        Object value = instance.getValueOfField(field);\n        if (value == null) {\n            if (allowNull) {\n                return null;\n            }\n            throw new InvalidFieldException(instance, field, \"Empty or missing field\");  // NOI18N\n        }\n        try {\n            return castValue(value, type);\n        } catch (InvalidFieldException ex) {\n            throw new InvalidFieldException(instance, field, ex.getMessage()).initCause(ex);\n        }\n    }\n    // Instance accessors  --------------------------------------------\n\n    /**\n     * Return value of the field casted as {@link Instance}.\n     *\n     * @see #get(org.graalvm.visualvm.lib.jfluid.heap.Instance, java.lang.String, java.lang.Class, boolean)\n     */\n    public Instance getInstance(Instance instance, String field, boolean allowNull)\n            throws InvalidFieldException {\n        return get(instance, field, Instance.class, allowNull);\n    }\n\n    /**\n     * Return value of the field casted as {@link Instance}. Check if the instance java class correspond to the supplied\n     * class. Simplifies call to {@link #getInstance(Instance, String, String) getInstance(instance, field, className)\n     * } if the class object is available.\n     *\n     * @param type source of class name used in Instance type checking\n     * @param subclasses match also subclasses of the <code>type<code>\n     * @return never null\n     */\n    public Instance getInstance(Instance instance, String field, Class<?> type, boolean subclasses) throws InvalidFieldException {\n        return getInstance(instance, field, getClassMask(type, subclasses));\n    }\n\n    /**\n     * Return value of the field casted as {@link Instance}. Check the java class name of the returned instance.\n     *\n     * @param clsName name of the expected class, allow subclasses if the name end with '+'\n     * @return never null\n     */\n    public Instance getInstance(Instance instance, String field, String clsName) throws InvalidFieldException {\n        Instance value = getInstance(instance, field, false);\n        if (clsName.endsWith(\"+\")) {\n            clsName = clsName.substring(0, clsName.length() - 1);\n            if (!DetailsUtils.isSubclassOf(value, clsName)) {\n                throw new InvalidFieldException(instance, field, \"Instance is %s but subclass of %s is expected\", //NOI18N\n                        value.getJavaClass().getName(),\n                        clsName);\n            }\n        } else {\n            if (!DetailsUtils.isInstanceOf(value, clsName)) {\n                throw new InvalidFieldException(instance, field, \"Instance is %s but %s is expected\", //NOI18N\n                        value.getJavaClass().getName(),\n                        clsName);\n            }\n        }\n        return value;\n    }\n\n    <T> T build(Instance instance, String field, InstanceBuilder<T> builder, boolean allowNull)\n            throws InvalidFieldException {\n        return builder.convert(this, get(instance, field, Instance.class, allowNull));\n    }\n\n    /**\n     * Builds using registry\n     */\n    public <T> T build(Instance instance, String field, Class<T> type, boolean allowNull)\n            throws InvalidFieldException {\n        Instance value = get(instance, field, Instance.class, allowNull);\n        if (value == null) {\n            return null;\n        }\n        InstanceBuilder<? extends T> builder = registry.getBuilder(value, type);\n        if (builder == null) {\n            if (allowNull) {\n                return null;\n            }\n            throw new InvalidFieldException(instance, field, \"No builder for %s returning %s registered\", //NOI18N\n                    value.getJavaClass().getName(), type.getName());\n        }\n        return builder.convert(this, value);\n    }\n\n    /**\n     * Convert filed of the instance to the array of represented objects. Use builder registry to get builder for each\n     * item in the array.\n     *\n     * @param instance parent instance of the array\n     * @param field name of the field containing the array\n     * @param type base type of returned array\n     * @param allowNull never return null, throw exception instead\n     * @param allowNullValues returned array can contain nulls\n     */\n    public <T> T[] buildArray(Instance instance, String field, Class<T> type,\n            boolean allowNull, boolean allowNullValues) throws InvalidFieldException {\n        return buildArray(instance, field, type, null, allowNull, allowNullValues);\n    }\n\n    /**\n     * Convert filed of the instance to the array of represented objects. Use given builder to convert the array items.\n     *\n     * @param instance parent instance of the array\n     * @param field name of the field containing the array\n     * @param builder builder used to convert items in the array\n     * @param allowNull never return null, throw exception instead\n     * @param allowNullValues returned array can contain nulls\n     */\n    <T> T[] buildArray(Instance instance, String field, InstanceBuilder<T> builder,\n            boolean allowNull, boolean allowNullValues) throws InvalidFieldException {\n        return buildArray(instance, field, builder.getType(), builder, allowNull, allowNullValues);\n    }\n\n    private <T> T[] buildArray(Instance instance, String field, Class<T> type, InstanceBuilder<? extends T> builder,\n            boolean allowNull, boolean allowNullValues) throws InvalidFieldException {\n\n        ObjectArrayInstance array = get(instance, field, ObjectArrayInstance.class, allowNull);\n        if (array == null) {\n            return null;\n        }\n        List<Instance> list = array.getValues();\n        T[] result = (T[]) Array.newInstance(builder.getType(), list.size());\n        for (int i = 0; i < result.length; i++) {\n            try {\n                InstanceBuilder<? extends T> itemBuilder = builder == null ? registry.getBuilder(instance, type) : builder;\n                result[i] = itemBuilder.convert(this, castValue(notNullCheck(list.get(i), allowNullValues), Instance.class));\n            } catch (InvalidFieldException ex) {\n                throw new InvalidFieldException(instance, field, \"Invalid value at index %d: %s\", i, ex.getMessage()).initCause(ex);\n            }\n        }\n        return result;\n    }\n\n    // Builder functions -----------------------------------------------------------------\n    public String toString(Instance instance) {\n        if (instance == null) {\n            return null;\n        }\n        return DetailsSupport.getDetailsString(instance);\n    }\n\n    // Predefined type accessors ---------------------------------------------------------\n    public int getInt(Instance instance, String field) throws InvalidFieldException {\n        return get(instance, field, Number.class, false).intValue();\n    }\n\n    public boolean getBoolean(Instance instance, String field) throws InvalidFieldException {\n        return get(instance, field, Boolean.class, false).booleanValue();\n    }\n\n    public String getString(Instance instance, String field, boolean allowNull) throws InvalidFieldException {\n        return build(instance, field, InstanceBuilder.STRING_BUILDER, allowNull);\n    }\n\n    public int[] getIntArray(Instance instance, String field, boolean allowNull) throws InvalidFieldException {\n        return build(instance, field, InstanceBuilder.INT_ARRAY_BUILDER, allowNull);\n    }\n\n    public byte[] getByteArray(Instance instance, String field, boolean allowNull) throws InvalidFieldException {\n        return build(instance, field, InstanceBuilder.BYTE_ARRAY_BUILDER, allowNull);\n    }\n\n    public int[][] getIntArray2(Instance instance, String field, boolean allowNull) throws InvalidFieldException {\n        return buildArray(instance, field, InstanceBuilder.INT_ARRAY_BUILDER, allowNull, false);\n    }\n\n    public byte[][] getByteArray2(Instance instance, String field, boolean allowNull) throws InvalidFieldException {\n        return buildArray(instance, field, InstanceBuilder.BYTE_ARRAY_BUILDER, allowNull, false);\n    }\n\n    public short[][] getShortArray2(Instance instance, String field, boolean allowNull) throws InvalidFieldException {\n        return buildArray(instance, field, InstanceBuilder.SHORT_ARRAY_BUILDER, allowNull, false);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/image/ImageBuilder.java",
    "content": "/*\n * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.image;\n\nimport java.awt.Image;\nimport java.awt.Point;\nimport java.awt.color.ColorSpace;\nimport java.awt.image.BandedSampleModel;\nimport java.awt.image.BufferedImage;\nimport java.awt.image.ColorModel;\nimport java.awt.image.ComponentColorModel;\nimport java.awt.image.DataBuffer;\nimport java.awt.image.DataBufferByte;\nimport java.awt.image.DataBufferInt;\nimport java.awt.image.DataBufferUShort;\nimport java.awt.image.DirectColorModel;\nimport java.awt.image.IndexColorModel;\nimport java.awt.image.MultiPixelPackedSampleModel;\nimport java.awt.image.PixelInterleavedSampleModel;\nimport java.awt.image.Raster;\nimport java.awt.image.SampleModel;\nimport java.awt.image.SinglePixelPackedSampleModel;\nimport java.awt.image.WritableRaster;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n * Functions to reconstruct image from the heap dump.\n *\n * @author Jan Taus\n */\npublic class ImageBuilder {\n\n    /** Logger used to log messages related to the image building process. */\n    static final Logger LOGGER = Logger.getLogger(ImageDetailProvider.class.getName());\n\n\n    /**\n     * Create image from heap instance.\n     *\n     * @return <code>null</code> if the image cannot be reconstructed from the heap.\n     */\n    public static Image buildImage(Instance instance) {\n        try {\n            return buildImageInternal(instance);\n        } catch (FieldAccessor.InvalidFieldException ex) {\n            LOGGER.log(Level.FINE, \"Unable to create image for instance, error: {0}\", ex.getMessage());\n            return null;\n        }\n    }\n\n    static Image buildImageInternal(Instance instance) throws FieldAccessor.InvalidFieldException {\n        InstanceBuilder<? extends Image> builder = BUILDERS.getBuilder(instance, Image.class);\n        if (builder == null) {\n            throw new FieldAccessor.InvalidFieldException(\"Unable to get Image builder for {0}#{1}\", instance.getJavaClass().getName(), instance.getInstanceNumber()); //NOI18N\n        }\n        return builder.convert(new FieldAccessor(BUILDERS), instance);\n    }\n\n    private static final InstanceBuilder<String> TOOKIT_IMAGE_STRING_BUILDER =\n            new InstanceBuilder.ReferringInstanceBuilder<>(String.class, \"imagerep\", \"bimage\");\n    private static final InstanceBuilder<Image> TOOKIT_IMAGE_IMAGE_BUILDER =\n            new InstanceBuilder.ReferringInstanceBuilder<>(Image.class, \"imagerep\", \"bimage\");\n    private static final InstanceBuilder<String> IMAGE_ICON_STRING_BUILDER =\n            new InstanceBuilder.ReferringInstanceBuilder<>(String.class, \"image\");\n    private static final InstanceBuilder<Image> IMAGE_ICON_IMAGE_BUILDER =\n            new InstanceBuilder.ReferringInstanceBuilder<>(Image.class, \"image\");\n    private static final InstanceBuilder<String> BUFFERED_IMAGE_STRING_BUILDER = new InstanceBuilder<String>(String.class) {\n        @Override\n        public String convert(FieldAccessor fa, Instance instance) throws FieldAccessor.InvalidFieldException {\n            Instance raster = fa.getInstance(instance, \"raster\", WritableRaster.class, true);   // NOI18N\n            int width = fa.getInt(raster, \"width\");   // NOI18N\n            int height = fa.getInt(raster, \"height\");   // NOI18N\n            Instance colorModel = fa.getInstance(instance, \"colorModel\", ColorModel.class, true);\n\n            int color_count = 0;\n            if (FieldAccessor.isInstanceOf(colorModel, IndexColorModel.class)) {\n                color_count = DetailsUtils.getIntFieldValue(colorModel, \"map_size\", 0); // NOI18N\n            }\n            if (color_count > 0) {\n                return Bundle.ImageDetailProvider_ImageDescrColors(width, height, color_count);\n            } else {\n                return Bundle.ImageDetailProvider_ImageDescr(width, height);\n            }\n        }\n    };\n    private static final InstanceBuilder<Image> BUFFERED_IMAGE_IMAGE_BUILDER = new InstanceBuilder<Image>(Image.class) {\n        @Override\n        public Image convert(FieldAccessor fa, Instance instance) throws FieldAccessor.InvalidFieldException {\n            try {\n                int imageType = fa.getInt(instance, \"imageType\"); // NOI18N\n                WritableRaster raster = fa.build(instance, \"raster\", WritableRaster.class, false);\n                ColorModel cm = fa.build(instance, \"colorModel\", ColorModel.class, false);\n                BufferedImage result = new BufferedImage(cm, raster, cm.isAlphaPremultiplied(), null);\n                result.setData(raster);\n                return result;\n            } catch (FieldAccessor.InvalidFieldException ex) {\n                throw ex;\n            } catch (Throwable ex) {\n                throw new FieldAccessor.InvalidFieldException(\"unable to recreate raster: {0}\", ex.getMessage()).initCause(ex); // NOI18N\n            }\n        }\n    };\n    private static final InstanceBuilder<ColorModel> INDEX_COLOR_MODEL_BUILDER = new InstanceBuilder<ColorModel>(ColorModel.class) {\n        @Override\n        public ColorModel convert(FieldAccessor fa, Instance instance) throws FieldAccessor.InvalidFieldException {\n            int bits = fa.getInt(instance, \"pixel_bits\"); // NOI18N\n            int[] cmap = fa.getIntArray(instance, \"rgb\", false);// NOI18N\n            int size = fa.getInt(instance, \"map_size\"); // NOI18N\n            int trans = fa.getInt(instance, \"transparent_index\"); // NOI18N\n            int transferType = fa.getInt(instance, \"transferType\"); // NOI18N\n            return new IndexColorModel(bits, size, cmap, 0, true, trans, transferType);\n        }\n    };\n    private static final InstanceBuilder<ColorModel> DIRECT_COLOR_MODEL_BUILDER = new InstanceBuilder<ColorModel>(ColorModel.class) {\n        @Override\n        public ColorModel convert(FieldAccessor fa, Instance instance) throws FieldAccessor.InvalidFieldException {\n            int bits = fa.getInt(instance, \"pixel_bits\"); // NOI18N\n            int rmask = fa.getInt(instance, \"red_mask\"); // NOI18N\n            int gmask = fa.getInt(instance, \"green_mask\"); // NOI18N\n            int bmask = fa.getInt(instance, \"blue_mask\"); // NOI18N\n            int amask = fa.getInt(instance, \"alpha_mask\"); // NOI18N\n            boolean ap = fa.getBoolean(instance, \"isAlphaPremultiplied\"); // NOI18N\n            int transferType = fa.getInt(instance, \"transferType\"); // NOI18N\n            return new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), bits, rmask, gmask, bmask, amask, ap, transferType);\n        }\n    };\n    private static final InstanceBuilder<ColorModel> COMPONENT_COLOR_MODEL_BUILDER = new InstanceBuilder<ColorModel>(ColorModel.class) {\n        @Override\n        public ColorModel convert(FieldAccessor fa, Instance instance) throws FieldAccessor.InvalidFieldException {\n            int[] bits = fa.getIntArray(instance, \"nBits\", false);// NOI18N\n            int transparency = fa.getInt(instance, \"transparency\"); // NOI18N\n            boolean hasAlpha = fa.getBoolean(instance, \"supportsAlpha\"); // NOI18N\n            boolean ap = fa.getBoolean(instance, \"isAlphaPremultiplied\"); // NOI18N\n            int transferType = fa.getInt(instance, \"transferType\"); // NOI18N\n            return new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), bits, hasAlpha, ap, transparency, transferType);\n        }\n    };\n    private static final InstanceBuilder<ColorSpace> DEFAULT_COLOR_SPACE_BUILDER = new InstanceBuilder<ColorSpace>(ColorSpace.class) {\n        @Override\n        public ColorSpace convert(FieldAccessor accessor, Instance instance) throws FieldAccessor.InvalidFieldException {\n            return ColorSpace.getInstance(ColorSpace.CS_sRGB);\n        }\n    };\n    private static final InstanceBuilder<WritableRaster> WRITABLE_RASTER_BUILDER = new InstanceBuilder<WritableRaster>(WritableRaster.class) {\n        @Override\n        public WritableRaster convert(FieldAccessor accessor, Instance instance) throws FieldAccessor.InvalidFieldException {\n            WritableRaster parent = accessor.build(instance, \"parent\", WritableRaster.class, true);\n            if (parent == null) {\n                DataBuffer dataBuffer = accessor.build(instance, \"dataBuffer\", DataBuffer.class, false);\n                SampleModel sampleModel = accessor.build(instance, \"sampleModel\", SampleModel.class, false); // NOI18N\n                int tx = accessor.getInt(instance, \"sampleModelTranslateX\");\n                int ty = accessor.getInt(instance, \"sampleModelTranslateY\");\n                return Raster.createWritableRaster(sampleModel, dataBuffer, new Point(tx, ty));\n            }\n            int width = accessor.getInt(instance, \"width\");\n            int height = accessor.getInt(instance, \"height\");\n            int minX = accessor.getInt(instance, \"minX\");\n            int minY = accessor.getInt(instance, \"minY\");\n            int tx = accessor.getInt(instance, \"sampleModelTranslateX\");\n            int ty = accessor.getInt(instance, \"sampleModelTranslateY\");\n            int px = parent.getSampleModelTranslateX();\n            int py = parent.getSampleModelTranslateY();\n            return parent.createWritableChild(minX, minY, width, height, tx - px + minX, ty - py + minY, null);\n        }\n    };\n    private static final InstanceBuilder<SampleModel> SPP_SAMPLE_MODEL_BUILDER = new InstanceBuilder<SampleModel>(SampleModel.class) {\n        @Override\n        public SampleModel convert(FieldAccessor fa, Instance instance) throws FieldAccessor.InvalidFieldException {\n            int width = fa.getInt(instance, \"width\");          // NOI18N\n            int height = fa.getInt(instance, \"height\");  // NOI18N\n            int dataType = fa.getInt(instance, \"dataType\");   // NOI18N\n            int scanlineStride = fa.getInt(instance, \"scanlineStride\");  // NOI18N\n            int[] bitMasks = fa.getIntArray(instance, \"bitMasks\", false);  // NOI18N\n            return new SinglePixelPackedSampleModel(dataType, width, height, scanlineStride, bitMasks);\n        }\n    };\n    private static final InstanceBuilder<SampleModel> PI_SAMPLE_MODEL_BUILDER = new InstanceBuilder<SampleModel>(SampleModel.class) {\n        @Override\n        public SampleModel convert(FieldAccessor fa, Instance instance) throws FieldAccessor.InvalidFieldException {\n            int width = fa.getInt(instance, \"width\");          // NOI18N\n            int height = fa.getInt(instance, \"height\");  // NOI18N\n            int dataType = fa.getInt(instance, \"dataType\");   // NOI18N\n            int pixelStride = fa.getInt(instance, \"pixelStride\");  // NOI18N\n            int scanlineStride = fa.getInt(instance, \"scanlineStride\");  // NOI18N\n            int[] bandOffsets = fa.getIntArray(instance, \"bandOffsets\", false);  // NOI18N\n            return new PixelInterleavedSampleModel(dataType, width, height, pixelStride, scanlineStride, bandOffsets);\n        }\n    };\n    private static final InstanceBuilder<SampleModel> B_SAMPLE_MODEL_BUILDER = new InstanceBuilder<SampleModel>(SampleModel.class) {\n        @Override\n        public SampleModel convert(FieldAccessor fa, Instance instance) throws FieldAccessor.InvalidFieldException {\n            int width = fa.getInt(instance, \"width\");          // NOI18N\n            int height = fa.getInt(instance, \"height\");  // NOI18N\n            int dataType = fa.getInt(instance, \"dataType\");   // NOI18N\n            int scanlineStride = fa.getInt(instance, \"scanlineStride\");  // NOI18N\n            int[] bankIndices = fa.getIntArray(instance, \"bankIndices\", false);  // NOI18N\n            int[] bandOffsets = fa.getIntArray(instance, \"bandOffsets\", false);  // NOI18N\n            return new BandedSampleModel(dataType, width, height, scanlineStride, bankIndices, bandOffsets);\n        }\n    };\n    private static final InstanceBuilder<SampleModel> MPP_SAMPLE_MODEL_BUILDER = new InstanceBuilder<SampleModel>(SampleModel.class) {\n        @Override\n        public SampleModel convert(FieldAccessor fa, Instance instance) throws FieldAccessor.InvalidFieldException {\n            int width = fa.getInt(instance, \"width\");          // NOI18N\n            int height = fa.getInt(instance, \"height\");  // NOI18N\n            int dataType = fa.getInt(instance, \"dataType\");   // NOI18N\n            int scanlineStride = fa.getInt(instance, \"scanlineStride\");  // NOI18N\n            int numberOfBits = fa.getInt(instance, \"numberOfBits\");  // NOI18N\n            int dataBitOffset = fa.getInt(instance, \"dataBitOffset\");  // NOI18N\n            return new MultiPixelPackedSampleModel(dataType, width, height, numberOfBits, scanlineStride, dataBitOffset);\n        }\n    };\n    private static final InstanceBuilder<DataBuffer> INT_DATA_BUFFER_BUILDER = new InstanceBuilder<DataBuffer>(DataBuffer.class) {\n        @Override\n        public DataBuffer convert(FieldAccessor fa, Instance instance) throws FieldAccessor.InvalidFieldException {\n            int size = fa.getInt(instance, \"size\");                        // NOI18N\n            int[] offsets = fa.getIntArray(instance, \"offsets\", false);      // NOI18N\n            //int[] data = fa.getIntArray(instance, \"data\", false);     // NOI18N\n            int[][] bankdata = fa.getIntArray2(instance, \"bankdata\", false); // NOI18N\n            return new DataBufferInt(bankdata, size, offsets);\n        }\n    };\n    private static final InstanceBuilder<DataBuffer> BYTE_DATA_BUFFER_BUILDER = new InstanceBuilder<DataBuffer>(DataBuffer.class) {\n        @Override\n        public DataBuffer convert(FieldAccessor fa, Instance instance) throws FieldAccessor.InvalidFieldException {\n            int size = fa.getInt(instance, \"size\");                        // NOI18N\n            int[] offsets = fa.getIntArray(instance, \"offsets\", false);      // NOI18N\n            byte[][] bankdata = fa.getByteArray2(instance, \"bankdata\", false); // NOI18N\n            return new DataBufferByte(bankdata, size, offsets);\n        }\n    };\n    private static final InstanceBuilder<DataBuffer> USHORT_DATA_BUFFER_BUILDER = new InstanceBuilder<DataBuffer>(DataBuffer.class) {\n        @Override\n        public DataBuffer convert(FieldAccessor fa, Instance instance) throws FieldAccessor.InvalidFieldException {\n            int size = fa.getInt(instance, \"size\");                        // NOI18N\n            int[] offsets = fa.getIntArray(instance, \"offsets\", false);      // NOI18N\n            short[][] bankdata = fa.getShortArray2(instance, \"bankdata\", false); // NOI18N\n            return new DataBufferUShort(bankdata, size, offsets);\n        }\n    };\n\n    static final InstanceBuilderRegistry BUILDERS = new InstanceBuilderRegistry();\n    static {\n        BUILDERS.register(ColorSpace.class, true, DEFAULT_COLOR_SPACE_BUILDER);\n        BUILDERS.register(IndexColorModel.class, true, INDEX_COLOR_MODEL_BUILDER);\n        BUILDERS.register(ComponentColorModel.class, true, COMPONENT_COLOR_MODEL_BUILDER);\n        BUILDERS.register(DirectColorModel.class, true, DIRECT_COLOR_MODEL_BUILDER);\n        BUILDERS.register(SinglePixelPackedSampleModel.class, false, SPP_SAMPLE_MODEL_BUILDER);\n        BUILDERS.register(PixelInterleavedSampleModel.class, false, PI_SAMPLE_MODEL_BUILDER);\n        BUILDERS.register(BandedSampleModel.class, false, B_SAMPLE_MODEL_BUILDER);\n        BUILDERS.register(MultiPixelPackedSampleModel.class, false, MPP_SAMPLE_MODEL_BUILDER);\n        BUILDERS.register(DataBufferInt.class, false, INT_DATA_BUFFER_BUILDER);\n        BUILDERS.register(DataBufferByte.class, false, BYTE_DATA_BUFFER_BUILDER);\n        BUILDERS.register(DataBufferUShort.class, false, USHORT_DATA_BUFFER_BUILDER);\n        BUILDERS.register(WritableRaster.class, true, WRITABLE_RASTER_BUILDER);\n        BUILDERS.register(\"sun.awt.image.ToolkitImage+\", TOOKIT_IMAGE_STRING_BUILDER);\n        BUILDERS.register(\"sun.awt.image.ToolkitImage+\", TOOKIT_IMAGE_IMAGE_BUILDER);\n        BUILDERS.register(ImageIcon.class, true, IMAGE_ICON_STRING_BUILDER);\n        BUILDERS.register(ImageIcon.class, true, IMAGE_ICON_IMAGE_BUILDER);\n        BUILDERS.register(BufferedImage.class, true, BUFFERED_IMAGE_STRING_BUILDER);\n        BUILDERS.register(BufferedImage.class, true, BUFFERED_IMAGE_IMAGE_BUILDER);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/image/ImageDetailProvider.java",
    "content": "/*\n * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.image;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.awt.Image;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.image.BufferedImage;\nimport java.util.logging.Level;\nimport javax.swing.ImageIcon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JScrollPane;\nimport javax.swing.JToolBar;\nimport javax.swing.Scrollable;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.ProfilerTopComponent;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.image.FieldAccessor.InvalidFieldException;\nimport static org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.image.ImageBuilder.BUILDERS;\nimport static org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.image.ImageBuilder.LOGGER;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.model.BrowserUtils;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.windows.TopComponent;\n\n/**\n *\n * @author Jan Taus\n */\n@NbBundle.Messages({\n    \"ImageDetailProvider_ImageDescr={0}x{1}\", // NOI18N\n    \"ImageDetailProvider_ImageDescrColors=size={0}x{1}, {2} colors\", // NOI18N\n    \"ImageDetailProvider_NotSupported=Unsupported image\", // NOI18N\n    \"ImageDetailProvider_Zoom=Zoom: 1/{0}\", // NOI18N\n    \"ImageDetailProvider_Dimension=Dimension: {0}x{1}\", // NOI18N\n    \"ImageDetailProvider_Action_Show=Open in window\", // NOI18N\n    \"ImageDetailProvider_Action_Export=Export image\", // NOI18N\n    \"ImageDetailProvider_Toolbar=Export toolbar\" // NOI18N\n})\n@ServiceProvider(service = DetailsProvider.class)\npublic class ImageDetailProvider extends DetailsProvider.Basic {\n\n    private static final int CHECKER_SIZE = 8;\n    private static final int PREVIEW_BORDER = 4;\n    private static final Color CHECKER_BG = Color.LIGHT_GRAY;\n    private static final Color CHECKER_FG = Color.DARK_GRAY;\n\n    private static void drawChecker(Graphics g, int x, int y, int width, int height) {\n        g.setColor(CHECKER_BG);\n        g.fillRect(x, y, width, height);\n        g.setColor(CHECKER_FG);\n        for (int i = 0; i < width; i += CHECKER_SIZE) {\n            for (int j = 0; j < height; j += CHECKER_SIZE) {\n                if ((i / CHECKER_SIZE + j / CHECKER_SIZE) % 2 == 0) {\n                    g.fillRect(x + i, y + j, Math.min(CHECKER_SIZE, width - i), Math.min(CHECKER_SIZE, height - j));\n                }\n            }\n        }\n    }\n\n    public ImageDetailProvider() {\n        super(ImageBuilder.BUILDERS.getMasks(Image.class, String.class));\n    }\n\n    @Override\n    public String getDetailsString(String className, Instance instance) {\n        try {\n            InstanceBuilder<? extends String> builder = BUILDERS.getBuilder(instance, String.class);\n            if (builder == null) {\n                LOGGER.log(Level.FINE, \"Unable to get String builder for {0}\", className); //NOI18N\n            } else {\n                return builder.convert(new FieldAccessor(BUILDERS), instance);\n            }\n        } catch (InvalidFieldException ex) {\n            LOGGER.log(Level.FINE, \"Unable to get text for instance, error: {0}\", ex.getMessage()); //NOI18N\n        }\n        return null;\n    }\n\n    @Override\n    public View getDetailsView(String className, Instance instance) {\n        return new ImageView(instance);\n    }\n\n    private static class ImageView extends DetailsProvider.View implements Scrollable {\n\n        private final String instanceName;\n        private final int instanceNumber;\n        private Image instanceImage = null;\n\n        private JLabel paintLabel;\n\n\n        ImageView(Instance instance) {\n            super(instance);\n            this.instanceName = instance.getJavaClass().getName();\n            this.instanceNumber = instance.getInstanceNumber();\n            addMouseListener(new MouseHandler());\n        }\n\n        @Override\n        protected void computeView(Instance instance) {\n            Image image = null;\n            JLabel label = null;\n            try {\n                image = ImageBuilder.buildImageInternal(instance);\n            } catch (InvalidFieldException ex) {\n                LOGGER.log(Level.FINE, \"Unable to get image for instance, error: {0}\", ex.getMessage());\n                label = new JLabel(Bundle.ImageDetailProvider_NotSupported(), JLabel.CENTER);\n                label.setEnabled(false);\n            }\n\n            final JComponent component = label;\n            final Image im = image;\n            SwingUtilities.invokeLater(new Runnable() {\n                @Override\n                public void run() {\n                    removeAll();\n                    if (component != null) {\n                        add(component, BorderLayout.CENTER);\n                    }\n                    revalidate();\n                    doLayout();\n                    repaint();\n                    instanceImage = im;\n                }\n            });\n        }\n\n        @Override\n        protected void paintComponent(Graphics g) {\n            super.paintComponent(g);\n\n            if (instanceImage == null) {\n                return;\n            }\n\n            int lineHeight = g.getFontMetrics().getHeight();\n            int viewWidth = getWidth() - 2 * PREVIEW_BORDER;\n            int viewHeight = getHeight() - 3 * PREVIEW_BORDER - 2 * lineHeight;\n            if (viewWidth < 1 || viewHeight < 1) {\n                return;\n            }\n\n            int imgWidth = instanceImage.getWidth(null);\n            int imgHeight = instanceImage.getHeight(null);\n            if (imgWidth < 1 || imgHeight < 1) {\n                return;\n            }\n\n            int width = imgWidth;\n            int height = imgHeight;\n            int scale = 1;\n            int scaleX = (int) Math.ceil((float) imgWidth / viewWidth);\n            int scaleY = (int) Math.ceil((float) imgHeight / viewHeight);\n            if (scaleX > 1 || scaleY > 1) {\n                scale = Math.max(scaleX, scaleY);\n                width = (int) ((float) imgWidth / scale);\n                height = (int) ((float) imgHeight / scale);\n            }\n            int x = PREVIEW_BORDER + (viewWidth - width) / 2;\n            int y = PREVIEW_BORDER + (viewHeight - height) / 2;\n\n            drawChecker(g, x, y, width, height);\n            g.drawImage(instanceImage, x, y, x + width, y + height, 0, 0, imgWidth, imgHeight, null);\n\n            g.setColor(getForeground());\n            int nextY = getHeight() - drawText(g, PREVIEW_BORDER, getHeight(), Bundle.ImageDetailProvider_Dimension(imgWidth, imgHeight));\n            if (scale != 1) {\n                drawText(g, PREVIEW_BORDER, nextY, Bundle.ImageDetailProvider_Zoom(scale));\n            }\n        }\n\n        private int drawText(Graphics g, int x, int y, String text) {\n            if(paintLabel == null) {\n                paintLabel = new JLabel();\n            }\n            paintLabel.setFont(g.getFont());\n            paintLabel.setText(text);\n            paintLabel.setSize(paintLabel.getPreferredSize());\n            g.translate(x, y - paintLabel.getHeight());\n            paintLabel.paint(g);\n            g.translate(-x, paintLabel.getHeight() - y);\n            return paintLabel.getHeight();\n        }\n\n        private class MouseHandler extends MouseAdapter {\n\n            public void mousePressed(final MouseEvent e) {\n                if (e.isPopupTrigger()) {\n                    showPopup(e);\n                }\n            }\n\n            public void mouseReleased(MouseEvent e) {\n                if (e.isPopupTrigger()) {\n                    showPopup(e);\n                }\n            }\n\n            @Override\n            public void mouseClicked(MouseEvent e) {\n                if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {\n                    openNewWindow();\n                }\n            }\n        }\n\n        private void showPopup(MouseEvent e) {\n            if (instanceImage == null) {\n                return;\n            }\n            JMenuItem showItem = new JMenuItem(Bundle.ImageDetailProvider_Action_Show()) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    openNewWindow();\n                }\n            };\n            showItem.setFont(showItem.getFont().deriveFont(Font.BOLD));\n            JPopupMenu popup = new JPopupMenu();\n            popup.add(showItem);\n            popup.add(new ImageExportAction(instanceImage));\n            popup.show(e.getComponent(), e.getX(), e.getY());\n        }\n\n        private void openNewWindow() {\n            if (instanceImage == null) {\n                return;\n            }\n            ImageTopComponent itc = new ImageTopComponent(instanceImage, instanceName, instanceNumber);\n            itc.open();\n            itc.requestActive();\n        }\n\n        @Override\n        public Dimension getPreferredScrollableViewportSize() {\n            return null;\n        }\n\n        @Override\n        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {\n            return 20;\n        }\n\n        @Override\n        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {\n            return 50;\n        }\n\n        @Override\n        public boolean getScrollableTracksViewportWidth() {\n            return true;\n        }\n\n        @Override\n        public boolean getScrollableTracksViewportHeight() {\n            return true;\n        }\n    }\n\n    private static class ImageTopComponent extends ProfilerTopComponent {\n\n        private static final String HELP_CTX_KEY = \"HeapWalker.ImagePreview.HelpCtx\"; // NOI18N\n        private static final HelpCtx HELP_CTX = new HelpCtx(HELP_CTX_KEY);\n\n        ImageTopComponent(Image image, String className, int instanceNumber) {\n            setName(BrowserUtils.getSimpleType(className) + \"#\" + instanceNumber);\n            setToolTipText(\"Preview of \" + className + \"#\" + instanceNumber);\n            setLayout(new BorderLayout());\n\n            int width = image.getWidth(null);\n            int height = image.getHeight(null);\n            BufferedImage displayedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);\n            Graphics g = displayedImage.createGraphics();\n            drawChecker(g, 0, 0, width, height);\n            g.drawImage(image, 0, 0, null);\n\n            JComponent c = new JScrollPane(new JLabel(new ImageIcon(displayedImage)));\n            add(c, BorderLayout.CENTER);\n\n\n            JToolBar toolBar = new JToolBar();\n            toolBar.putClientProperty(\"JToolBar.isRollover\", Boolean.TRUE); //NOI18N\n            toolBar.setFloatable(false);\n            toolBar.setName(Bundle.ImageDetailProvider_Toolbar());\n\n            //JButton button = new JButton();\n            //button.setText(\"\");\n            toolBar.add(new ImageExportAction(image));\n            add(toolBar, BorderLayout.NORTH);\n        }\n\n        @Override\n        public int getPersistenceType() {\n            return TopComponent.PERSISTENCE_NEVER;\n        }\n\n        @Override\n        protected String preferredID() {\n            return this.getClass().getName();\n        }\n\n        @Override\n        public HelpCtx getHelpCtx() {\n            return HELP_CTX;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/image/ImageExportAction.java",
    "content": "/*\n * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.image;\n\nimport java.awt.Image;\nimport java.awt.event.ActionEvent;\nimport java.awt.image.BufferedImage;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.util.Locale;\nimport javax.imageio.ImageIO;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.JFileChooser;\nimport javax.swing.filechooser.FileFilter;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n * Action used to export images.\n *\n * @author Jan Taus\n */\n@NbBundle.Messages({\n    \"ImageExportAction_Title=Export Image\", // NOI18N\n    \"ImageExportAction_Ok=Export\", // NOI18N\n    \"ImageExportAction_PNG=Portable Network Graphics (*.png)\", // NOI18N\n    \"ImageExportAction_OverwriteFileCaption=Overwrite Existing File\", // NOI18N\n    \"ImageExportAction_OverwriteFileMsg=<html><b>File {0} already exists.</b><br><br>Do you want to replace it?</html>\", // NOI18N\n    \"ImageExportAction_WrongFormat=File type {0} is not supported.\", // NOI18N\n    \"ImageExportAction_InvalidLoc=Invalid location for file.\", // NOI18N\n    \"ImageExportAction_Failed=<html>Failed to export File.<br>Reason: {0}</html>\" // NOI18N\n})\nclass ImageExportAction extends AbstractAction {\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static final String DEFAULT_EXPORT_TYPE = \"png\"; //NOI18N\n    private static File exportDir;\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n    private JFileChooser fileChooser;\n    private final Image image;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n    ImageExportAction(Image image) {\n        super();\n        putValue(Action.NAME, Bundle.ImageDetailProvider_Action_Export());\n        putValue(Action.SMALL_ICON, Icons.getIcon(GeneralIcons.EXPORT));\n        putValue(Action.SHORT_DESCRIPTION, Bundle.ImageDetailProvider_Action_Export());\n        putValue(\"iconBase\", Icons.getResource(GeneralIcons.EXPORT)); // NOI18N\n        this.image = image;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    @Override\n    public void actionPerformed(ActionEvent e) {\n        if (fileChooser == null) {\n            fileChooser = new JFileChooser();\n            fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);\n            fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);\n            fileChooser.setMultiSelectionEnabled(false);\n            fileChooser.setDialogTitle(Bundle.ImageExportAction_Title());\n            fileChooser.setApproveButtonText(Bundle.ImageExportAction_Ok());\n            fileChooser.addChoosableFileFilter(new FileFilter() {\n                @Override\n                public boolean accept(File f) {\n                    return f.isDirectory() || f.getName().toLowerCase(Locale.ENGLISH).endsWith(\".\" + DEFAULT_EXPORT_TYPE);\n                }\n\n                @Override\n                public String getDescription() {\n                    return Bundle.ImageExportAction_PNG();\n                }\n            });\n        }\n        if (exportDir != null) {\n            fileChooser.setCurrentDirectory(exportDir);\n        }\n        int result = fileChooser.showSaveDialog(WindowManager.getDefault().getRegistry().getActivated());\n        if (result == JFileChooser.APPROVE_OPTION) {\n            exportDir = fileChooser.getCurrentDirectory();\n            File target = fileChooser.getSelectedFile();\n            if (target.exists()) {\n                if (!ProfilerDialogs.displayConfirmation(\n                        Bundle.ImageExportAction_OverwriteFileMsg(target.getName()),\n                        Bundle.ImageExportAction_OverwriteFileCaption())) {\n                    return;\n                }\n            }\n\n            try {\n                writeImage(fileChooser.getSelectedFile());\n            } catch (IOException ex) {\n                ProfilerDialogs.displayError(Bundle.ImageExportAction_Failed(ex.getMessage()));\n            }\n        }\n    }\n\n    private void writeImage(File file) throws IOException {\n        String type;\n        int idx = file.getName().lastIndexOf('.');\n        if (idx == -1) {\n            file = new File(file.getPath() + '.' + DEFAULT_EXPORT_TYPE);\n            type = DEFAULT_EXPORT_TYPE;\n        } else {\n            type = file.getName().substring(idx + 1);\n        }\n        BufferedImage bi;\n        if (image instanceof BufferedImage) {\n            bi = (BufferedImage) image;\n        } else {\n            bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);\n            bi.createGraphics().drawImage(image, 0, 0, null);\n        }\n        FileObject fo = FileUtil.createData(file);\n        if (fo == null) {\n            throw new IOException(Bundle.ImageExportAction_InvalidLoc());\n        }\n        try (OutputStream output = fo.getOutputStream()) {\n            if (!ImageIO.write(bi, type, output)) {\n                throw new IOException(Bundle.ImageExportAction_WrongFormat(type));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/image/InstanceBuilder.java",
    "content": "/*\n * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.image;\n\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.image.FieldAccessor.InvalidFieldException;\n\n// Convertors of instance values --------------------------------------------\n/**\n * Reconstruct object from the heap instance.\n * @author Jan Taus\n */\nabstract class InstanceBuilder<T> {\n\n    public static final InstanceBuilder<String> STRING_BUILDER = new InstanceBuilder<String>(String.class) {\n        @Override\n        public String convert(FieldAccessor accessor, Instance instance) throws InvalidFieldException {\n            return accessor.toString(instance);\n        }\n    };\n    /**\n     * Builds\n     * <code>int[]</code> from {@link PrimitiveArrayInstance}\n     */\n    public static final InstanceBuilder<int[]> INT_ARRAY_BUILDER = new InstanceBuilder<int[]>(int[].class) {\n        @Override\n        public int[] convert(FieldAccessor accessor, Instance instance) throws InvalidFieldException {\n            if (instance == null) {\n                return null;\n            }\n            PrimitiveArrayInstance array = FieldAccessor.castValue(instance, PrimitiveArrayInstance.class);\n            List<String> list = array.getValues();\n            int[] result = new int[list.size()];\n            for (int i = 0; i < result.length; i++) {\n                try {\n                    result[i] = Integer.parseInt(list.get(i));\n                } catch (NumberFormatException e) {\n                    throw new InvalidFieldException(\"invalid format of int at index %d: %s\", i, list.get(i));\n                }\n            }\n            return result;\n        }\n    };\n    /**\n     * Builds\n     * <code>byte[]</code> from {@link PrimitiveArrayInstance}\n     */\n    public static final InstanceBuilder<byte[]> BYTE_ARRAY_BUILDER = new InstanceBuilder<byte[]>(byte[].class) {\n        @Override\n        public byte[] convert(FieldAccessor accessor, Instance instance) throws InvalidFieldException {\n            if (instance == null) {\n                return null;\n            }\n            PrimitiveArrayInstance array = FieldAccessor.castValue(instance, PrimitiveArrayInstance.class);\n            List<String> list = array.getValues();\n            byte[] result = new byte[list.size()];\n            for (int i = 0; i < result.length; i++) {\n                try {\n                    result[i] = Byte.parseByte(list.get(i));\n                } catch (NumberFormatException e) {\n                    throw new InvalidFieldException(\"invalid format of byte at index %d: %s\", i, list.get(i));\n                }\n            }\n            return result;\n        }\n    };\n    /**\n     * Builds\n     * <code>short[]</code> from {@link PrimitiveArrayInstance}\n     */\n    public static final InstanceBuilder<short[]> SHORT_ARRAY_BUILDER = new InstanceBuilder<short[]>(short[].class) {\n        @Override\n        public short[] convert(FieldAccessor accessor, Instance instance) throws InvalidFieldException {\n            if (instance == null) {\n                return null;\n            }\n            PrimitiveArrayInstance array = FieldAccessor.castValue(instance, PrimitiveArrayInstance.class);\n            List<String> list = array.getValues();\n            short[] result = new short[list.size()];\n            for (int i = 0; i < result.length; i++) {\n                try {\n                    result[i] = Short.parseShort(list.get(i));\n                } catch (NumberFormatException e) {\n                    throw new InvalidFieldException(\"invalid format of short at index %d: %s\", i, list.get(i));\n                }\n            }\n            return result;\n        }\n    };\n    /**\n     * Builder which returns original instance.\n     */\n    public static final InstanceBuilder<Instance> IDENTITY_BUILDER = new InstanceBuilder<Instance>(Instance.class) {\n        @Override\n        public Instance convert(FieldAccessor accessor, Instance instance) throws InvalidFieldException {\n            return instance;\n        }\n    };\n\n    /**\n     * Builds object in the field of the instance.\n     */\n    public static class ReferringInstanceBuilder<T> extends InstanceBuilder<T> {\n\n        private final String[] path;\n\n        public ReferringInstanceBuilder(Class<T> type, String... path) {\n            super(type);\n            this.path = path;\n        }\n\n        @Override\n        public T convert(FieldAccessor fa, Instance instance) throws InvalidFieldException {\n            for (int i = 0; i < path.length - 1 && instance != null; i++) {\n                instance = fa.getInstance(instance, path[i], false);\n            }\n            if (instance == null) {\n                return null;\n            }\n            return fa.build(instance, path[path.length - 1], getType(), false);\n        }\n    }\n    private final Class<T> type;\n\n    InstanceBuilder(Class<T> type) {\n        this.type = type;\n    }\n\n    /**\n     * Return type of the created objects. Function used to access class from generic context (e.g. allocating arrays).\n     */\n    Class<T> getType() {\n        return type;\n    }\n\n    /**\n     * Reconstruct object from the instance.\n     *\n     * @throws InvalidFieldException if the reconstructions failed\n     */\n    public abstract T convert(FieldAccessor accessor, Instance instance) throws FieldAccessor.InvalidFieldException;\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/image/InstanceBuilderRegistry.java",
    "content": "/*\n * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.image;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\n\n/**\n * Support for automatic selection of {@link InstanceBuilder} for an instance.\n *\n * @author Jan Taus\n */\nclass InstanceBuilderRegistry {\n\n    private static class RegisteredBuilder {\n\n        private final String mask;\n        private final InstanceBuilder<?> builder;\n\n        RegisteredBuilder(String mask, InstanceBuilder<?> builder) {\n            this.mask = mask;\n            this.builder = builder;\n        }\n    }\n    private final List<RegisteredBuilder> builders;\n\n    InstanceBuilderRegistry() {\n        this.builders = new ArrayList<>();\n    }\n\n    public void register(String mask, InstanceBuilder<?> builder) {\n        builders.add(new RegisteredBuilder(mask, builder));\n    }\n\n    public void register(Class<?> type, boolean subtypes, InstanceBuilder<?> builder) {\n        register(FieldAccessor.getClassMask(type, subtypes), builder);\n    }\n\n    /**\n     * Returns builder which creates object of given\n     * <code>type</code>. First registered builder matching given type and registered for given instance is returned. No\n     * <em>best match</em> is performed.\n     *\n     * @return builder or <code>null</code>.\n     */\n    public <T> InstanceBuilder<? extends T> getBuilder(Instance instance, Class<T> type) {\n        for (RegisteredBuilder builder : builders) {\n            if (FieldAccessor.matchClassMask(instance, builder.mask)) {\n                if (type.isAssignableFrom(builder.builder.getType())) {\n                    return (InstanceBuilder<? extends T>) builder.builder;\n                }\n            }\n        }\n        return null;\n    }\n\n    public String[] getMasks(Class<?>... types) {\n        Set<String> masks = new HashSet<>();\n        for (RegisteredBuilder builder : builders) {\n            for (Class<?> type : types) {\n                if (type.isAssignableFrom(builder.builder.getType())) {\n                    masks.add(builder.mask);\n                }\n            }\n        }\n        return masks.toArray(new String[0]);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ui/AwtDetailsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.ColorBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.DimensionBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.FontBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.InsetsBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.PointBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.RectangleBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic final class AwtDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String FONT_MASK = \"java.awt.Font+\";                   // NOI18N\n    private static final String COLOR_MASK = \"java.awt.Color+\";                 // NOI18N\n    private static final String POINT_MASK = \"java.awt.Point+\";                 // NOI18N\n    private static final String DIMENSION_MASK = \"java.awt.Dimension+\";         // NOI18N\n    private static final String RECTANGLE_MASK = \"java.awt.Rectangle+\";         // NOI18N\n    private static final String INSETS_MASK = \"java.awt.Insets+\";               // NOI18N\n    private static final String TEXTATTRIBUTE_MASK = \"java.text.AttributedCharacterIterator$Attribute+\"; // NOI18N\n    private static final String CURSOR_MASK = \"java.awt.Cursor+\";               // NOI18N\n    \n    public AwtDetailsProvider() {\n        super(FONT_MASK, COLOR_MASK, POINT_MASK, DIMENSION_MASK,\n              RECTANGLE_MASK, INSETS_MASK, TEXTATTRIBUTE_MASK, CURSOR_MASK);\n    }\n    \n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case FONT_MASK: { // Font+\n                String name = Utils.getFontName(instance);\n                if (name == null) name = \"Default\";                                 // NOI18N\n                int size = DetailsUtils.getIntFieldValue(instance, \"size\", 10);     // NOI18N // TODO: should use default font size\n                name += \", \" + size + \"pt\";                                         // NOI18N\n                int style = DetailsUtils.getIntFieldValue(instance, \"style\", 0);    // NOI18N\n                if ((style & 1) != 0) name += \", bold\";                             // NOI18N\n                if ((style & 2) != 0) name += \", italic\";                           // NOI18N\n                return name;\n            }\n            case COLOR_MASK: { // Color+\n                Color color = new ColorBuilder(instance).createInstance();\n                return color.getRed() + \", \" + color.getGreen() +                   // NOI18N\n                        \", \" + color.getBlue() + \", \" + color.getAlpha();           // NOI18N\n            }\n            case POINT_MASK: { // Point+\n                Point point = new PointBuilder(instance).createInstance();\n                return point.x + \", \" + point.y;                                    // NOI18N\n            }\n            case DIMENSION_MASK: { // Dimension+\n                Dimension dimension = new DimensionBuilder(instance).createInstance();\n                return dimension.width + \", \" + dimension.height;                   // NOI18N\n            }\n            case RECTANGLE_MASK: { // Rectangle+\n                Rectangle rectangle = new RectangleBuilder(instance).createInstance();\n                return rectangle.x + \", \" + rectangle.y +                           // NOI18N\n                        \", \" + rectangle.width + \", \" + rectangle.height;           // NOI18N\n            }\n            case INSETS_MASK:{ // Insets+\n                Insets insets = new InsetsBuilder(instance).createInstance();\n                return insets.top + \", \" + insets.left +                            // NOI18N\n                        \", \" + insets.bottom + \", \" + insets.right;                 // NOI18N\n            }\n            case TEXTATTRIBUTE_MASK: // AttributedCharacterIterator$Attribute+\n            case CURSOR_MASK: // Cursor+\n                return DetailsUtils.getInstanceFieldString(instance, \"name\");                                    // NOI18N\n            default:\n                break;\n        }\n        return null;\n    }\n    \n    public View getDetailsView(String className, Instance instance) {\n        if (FONT_MASK.equals(className)) {                                      // Font+\n            return new FontView(instance);\n        } else if (COLOR_MASK.equals(className)) {                              // Color+\n            return new ColorView(instance);\n        }\n        return null;\n    }\n    \n    @NbBundle.Messages({\n        \"FontView_Preview=ABCabc123\"\n    })\n    private static class FontView extends Utils.View<FontBuilder> {\n        \n        FontView(Instance instance) {\n            super(0, false, true, instance);\n        }\n        \n        protected FontBuilder getBuilder(Instance instance) {\n            return new FontBuilder(instance);\n        }\n        \n        protected Component getComponent(FontBuilder builder) {\n            JLabel label = new JLabel();\n            label.setHorizontalAlignment(JLabel.CENTER);\n            label.setFont(builder.createInstance());\n            label.setText(Bundle.FontView_Preview());\n            return label;\n        }\n        \n    }\n    \n    private static class ColorView extends Utils.View<ColorBuilder> {\n        \n        ColorView(Instance instance) {\n            super(0, true, true, instance);\n        }\n        \n        protected ColorBuilder getBuilder(Instance instance) {\n            return new ColorBuilder(instance);\n        }\n        \n        protected Component getComponent(ColorBuilder builder) {\n            final Color color = builder.createInstance();\n            JPanel panel = new JPanel(null) {\n                public void paint(Graphics g) {\n                    g.setColor(color);\n                    g.fillRect(0, 0, getWidth(), getHeight());\n                }\n            };\n            panel.setOpaque(false);\n            return panel;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ui/BaseBuilders.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Image;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.image.ImageBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.Utils.InstanceBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.Utils.PlaceholderIcon;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class BaseBuilders {\n\n    static final class PointBuilder extends InstanceBuilder<Point> {\n\n        private final int x;\n        private final int y;\n\n        PointBuilder(Instance instance) {\n            super(instance);\n            x = DetailsUtils.getIntFieldValue(instance, \"x\", 0);\n            y = DetailsUtils.getIntFieldValue(instance, \"y\", 0);\n        }\n\n        static PointBuilder fromField(Instance instance, String field) {\n            Object point = instance.getValueOfField(field);\n            if (!(point instanceof Instance)) return null;\n            return new PointBuilder((Instance)point);\n        }\n\n        protected Point createInstanceImpl() {\n            return new Point(x, y);\n        }\n\n    }\n\n    static final class DimensionBuilder extends InstanceBuilder<Dimension> {\n\n        private final int width;\n        private final int height;\n\n        DimensionBuilder(Instance instance) {\n            super(instance);\n            width = DetailsUtils.getIntFieldValue(instance, \"width\", 0);\n            height = DetailsUtils.getIntFieldValue(instance, \"height\", 0);\n        }\n        \n        static DimensionBuilder fromField(Instance instance, String field) {\n            Object dimension = instance.getValueOfField(field);\n            if (!(dimension instanceof Instance)) return null;\n            return new DimensionBuilder((Instance)dimension);\n        }\n        \n        protected Dimension createInstanceImpl() {\n            return new Dimension(width, height);\n        }\n        \n    }\n    \n    static final class RectangleBuilder extends InstanceBuilder<Rectangle> {\n        \n        private final PointBuilder point;\n        private final DimensionBuilder dimension;\n        \n        RectangleBuilder(Instance instance) {\n            super(instance);\n            point = new PointBuilder(instance);\n            dimension = new DimensionBuilder(instance);\n        }\n        \n        static RectangleBuilder fromField(Instance instance, String field) {\n            Object rectangle = instance.getValueOfField(field);\n            if (!(rectangle instanceof Instance)) return null;\n            return new RectangleBuilder((Instance)rectangle);\n        }\n        \n        protected Rectangle createInstanceImpl() {\n            return new Rectangle(point.createInstance(), dimension.createInstance());\n        }\n        \n    }\n    \n    static final class InsetsBuilder extends InstanceBuilder<Insets> {\n        \n        private final int top;\n        private final int left;\n        private final int bottom;\n        private final int right;\n        \n        InsetsBuilder(Instance instance) {\n            super(instance);\n            top = DetailsUtils.getIntFieldValue(instance, \"top\", 0);\n            left = DetailsUtils.getIntFieldValue(instance, \"left\", 0);\n            bottom = DetailsUtils.getIntFieldValue(instance, \"bottom\", 0);\n            right = DetailsUtils.getIntFieldValue(instance, \"right\", 0);\n        }\n        \n        static InsetsBuilder fromField(Instance instance, String field) {\n            Object insets = instance.getValueOfField(field);\n            if (!(insets instanceof Instance)) return null;\n            return new InsetsBuilder((Instance)insets);\n        }\n        \n        protected Insets createInstanceImpl() {\n            return new Insets(top, left, bottom, right);\n        }\n        \n    }\n    \n    static final class FontBuilder extends InstanceBuilder<Font> {\n        \n        private final String name;\n        private final int style;\n        private final int size;\n        private final boolean isUIResource;\n        \n        FontBuilder(Instance instance) {\n            super(instance);\n            name = Utils.getFontName(instance);\n            style = DetailsUtils.getIntFieldValue(instance, \"style\", 0);\n            size = DetailsUtils.getIntFieldValue(instance, \"size\", 10);\n            isUIResource = DetailsUtils.isSubclassOf(instance, \"javax.swing.plaf.FontUIResource\");\n        }\n        \n        boolean isUIResource() {\n            return isUIResource;\n        }\n        \n        static FontBuilder fromField(Instance instance, String field) {\n            Object font = instance.getValueOfField(field);\n            if (!(font instanceof Instance)) return null;\n            return new FontBuilder((Instance)font);\n        }\n        \n        protected Font createInstanceImpl() {\n            return new Font(name, style, size);\n        }\n        \n    }\n    \n    static final class ColorBuilder extends InstanceBuilder<Color> {\n        \n        private final int value;\n        private final boolean isUIResource;\n        \n        ColorBuilder(Instance instance) {\n            super(instance);\n            value = DetailsUtils.getIntFieldValue(instance, \"value\", 0);\n            isUIResource = DetailsUtils.isSubclassOf(instance, \"javax.swing.plaf.ColorUIResource\") ||\n                           DetailsUtils.isSubclassOf(instance, \"javax.swing.plaf.nimbus.DerivedColor$UIResource\");\n        }\n        \n        boolean isUIResource() {\n            return isUIResource;\n        }\n        \n        static ColorBuilder fromField(Instance instance, String field) {\n            Object color = instance.getValueOfField(field);\n            if (!(color instanceof Instance)) return null;            \n            return new ColorBuilder((Instance)color);\n        }\n        \n        protected Color createInstanceImpl() {\n            return new Color(value);\n        }\n        \n    }\n    \n    static final class IconBuilder extends InstanceBuilder<Icon> {\n        \n        private final int width;\n        private final int height;\n        private final Image image;\n        \n        IconBuilder(Instance instance) {\n            super(instance);\n            width = DetailsUtils.getIntFieldValue(instance, \"width\", 0);\n            height = DetailsUtils.getIntFieldValue(instance, \"height\", 0);\n            image = ImageBuilder.buildImage(instance);\n        }\n        \n        static IconBuilder fromField(Instance instance, String field) {\n            Object icon = instance.getValueOfField(field);\n            if (!(icon instanceof Instance)) return null;\n            if (!DetailsUtils.isSubclassOf((Instance)icon, ImageIcon.class.getName())) return null;\n            return new IconBuilder((Instance)icon);\n        }\n        \n        protected Icon createInstanceImpl() {\n            if(image == null) {\n                    return new PlaceholderIcon(width, height);\n            }\n            return new ImageIcon(image);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ui/BorderBuilders.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui;\n\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.awt.Insets;\nimport javax.swing.BorderFactory;\nimport javax.swing.border.BevelBorder;\nimport javax.swing.border.Border;\nimport javax.swing.border.CompoundBorder;\nimport javax.swing.border.EmptyBorder;\nimport javax.swing.border.EtchedBorder;\nimport javax.swing.border.LineBorder;\nimport javax.swing.border.MatteBorder;\nimport javax.swing.border.TitledBorder;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.ColorBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.FontBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.IconBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.InsetsBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.Utils.InstanceBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class BorderBuilders {\n\n    static BorderBuilder fromField(Instance instance, String field, boolean uiresource) {\n        Object _border = instance.getValueOfField(field);\n        if (!(_border instanceof Instance)) return null;\n\n        Instance border = (Instance)_border;\n\n        // Make sure subclasses are listed before base class if using isSubclassOf\n        if (DetailsUtils.isSubclassOf(border, BevelBorder.class.getName())) {\n            return new BevelBorderBuilder(border);\n        } else if (DetailsUtils.isSubclassOf(border, MatteBorder.class.getName())) { // Must be before EmptyBorder (extends EmptyBorder)\n            return new EmptyBorderBuilder(border);\n        } else if (DetailsUtils.isSubclassOf(border, EmptyBorder.class.getName())) {\n            return new MatteBorderBuilder(border);\n        } else if (DetailsUtils.isSubclassOf(border, EtchedBorder.class.getName())) {\n            return new EtchedBorderBuilder(border);\n        } else if (DetailsUtils.isSubclassOf(border, LineBorder.class.getName())) {\n            return new LineBorderBuilder(border);\n        } else if (DetailsUtils.isSubclassOf(border, TitledBorder.class.getName())) {\n            return new TitledBorderBuilder(border);\n        } else if (DetailsUtils.isSubclassOf(border, CompoundBorder.class.getName())) {\n            return new CompoundBorderBuilder(border);\n        }\n\n        return null;\n    }\n    \n    static abstract class BorderBuilder extends InstanceBuilder<Border> {\n        private final boolean isUIResource;\n        BorderBuilder(Instance instance) {\n            super(instance);\n            this.isUIResource = instance.getJavaClass().getName().\n                    startsWith(\"javax.swing.plaf.BorderUIResource$\");\n        }\n        boolean isUIResource() {\n            return isUIResource;\n        }\n    }\n    \n    private static class BevelBorderBuilder extends BorderBuilder {\n        \n        private final int bevelType;\n        private final ColorBuilder highlightOuter;\n        private final ColorBuilder highlightInner;\n        private final ColorBuilder shadowInner;\n        private final ColorBuilder shadowOuter;\n        \n        BevelBorderBuilder(Instance instance) {\n            super(instance);\n            \n            bevelType = DetailsUtils.getIntFieldValue(instance, \"bevelType\", BevelBorder.LOWERED);\n            highlightOuter = ColorBuilder.fromField(instance, \"highlightOuter\");\n            highlightInner = ColorBuilder.fromField(instance, \"highlightInner\");\n            shadowInner = ColorBuilder.fromField(instance, \"shadowInner\");\n            shadowOuter = ColorBuilder.fromField(instance, \"shadowOuter\");\n        }\n        \n        protected Border createInstanceImpl() {\n            if (highlightOuter == null && shadowInner == null) {\n                if (highlightInner == null && shadowOuter == null) {\n                    return BorderFactory.createBevelBorder(bevelType);\n                } else {\n                    return BorderFactory.createBevelBorder(bevelType,\n                            highlightInner.createInstance(), shadowOuter.createInstance());\n                }\n            } else {\n                return BorderFactory.createBevelBorder(bevelType,\n                        highlightOuter.createInstance(), highlightInner.createInstance(),\n                        shadowOuter.createInstance(), shadowInner.createInstance());\n            }\n        }\n        \n    }\n    \n    private static class EmptyBorderBuilder extends BorderBuilder {\n        \n        private final InsetsBuilder insets;\n        \n        EmptyBorderBuilder(Instance instance) {\n            super(instance);\n            \n            insets = new InsetsBuilder(instance);\n        }\n        \n        protected Border createInstanceImpl() {\n            Insets i = insets.createInstance();\n            if (i.top == 0 && i.left == 0 && i.bottom == 0 && i.right == 0) {\n                return BorderFactory.createEmptyBorder();\n            } else {\n                return BorderFactory.createEmptyBorder(i.top, i.left, i.bottom, i.right);\n            }\n        }\n        \n    }\n    \n    private static class MatteBorderBuilder extends BorderBuilder {\n        \n        private final InsetsBuilder insets;\n        private final ColorBuilder color;\n        private final IconBuilder tileIcon;\n        \n        MatteBorderBuilder(Instance instance) {\n            super(instance);\n            \n            insets = new InsetsBuilder(instance);\n            color = ColorBuilder.fromField(instance, \"color\");\n            tileIcon = IconBuilder.fromField(instance, \"tileIcon\");\n        }\n        \n        protected Border createInstanceImpl() {\n            Insets i = insets.createInstance();\n            if (color == null) {\n                return BorderFactory.createMatteBorder(i.top, i.left, i.bottom,\n                        i.right, tileIcon == null ? null : tileIcon.createInstance());\n            } else {\n                return BorderFactory.createMatteBorder(i.top, i.left, i.bottom,\n                        i.right, color.createInstance());\n            }\n        }\n        \n    }\n    \n    private static class EtchedBorderBuilder extends BorderBuilder {\n        \n        private final int etchType;\n        private final ColorBuilder highlight;\n        private final ColorBuilder shadow;\n        \n        EtchedBorderBuilder(Instance instance) {\n            super(instance);\n            \n            etchType = DetailsUtils.getIntFieldValue(instance, \"etchType\", EtchedBorder.LOWERED);\n            highlight = ColorBuilder.fromField(instance, \"highlight\");\n            shadow = ColorBuilder.fromField(instance, \"shadow\");\n        }\n        \n        protected Border createInstanceImpl() {\n            if (highlight == null && shadow == null) {\n                return BorderFactory.createEtchedBorder(etchType);\n            } else {\n                return BorderFactory.createEtchedBorder(etchType,\n                        highlight == null ? null : highlight.createInstance(),\n                        shadow == null ? null : shadow.createInstance());\n            }\n        }\n        \n    }\n    \n    private static class LineBorderBuilder extends BorderBuilder {\n        \n        private final int thickness;\n        private final ColorBuilder lineColor;\n        private final boolean roundedCorners;\n        \n        LineBorderBuilder(Instance instance) {\n            super(instance);\n            \n            thickness = DetailsUtils.getIntFieldValue(instance, \"thickness\", 1);\n            lineColor = ColorBuilder.fromField(instance, \"lineColor\");\n            roundedCorners = DetailsUtils.getBooleanFieldValue(instance, \"roundedCorners\", false);\n        }\n        \n        protected Border createInstanceImpl() {\n            Color c = lineColor == null ? null : lineColor.createInstance();\n            if (c == null) c = Color.BLACK;\n            if (roundedCorners) {\n                return new LineBorder(c, thickness, roundedCorners);\n            } else if (thickness == 1) {\n                return BorderFactory.createLineBorder(c);\n            } else {\n                return BorderFactory.createLineBorder(c, thickness);\n            }\n        }\n        \n    }\n    \n    private static class TitledBorderBuilder extends BorderBuilder {\n        \n        private final String title;\n        private final BorderBuilder border;\n        private final int titlePosition;\n        private final int titleJustification;\n        private final FontBuilder titleFont;\n        private final ColorBuilder titleColor;\n        \n        TitledBorderBuilder(Instance instance) {\n            super(instance);\n            \n            title = Utils.getFieldString(instance, \"title\");\n            border = fromField(instance, \"border\", false);\n            titlePosition = DetailsUtils.getIntFieldValue(instance, \"titlePosition\", TitledBorder.DEFAULT_POSITION);\n            titleJustification = DetailsUtils.getIntFieldValue(instance, \"titleJustification\", TitledBorder.LEADING);\n            titleFont = FontBuilder.fromField(instance, \"titleFont\");\n            titleColor = ColorBuilder.fromField(instance, \"titleColor\");\n        }\n        \n        protected Border createInstanceImpl() {\n            Font font = titleFont == null || titleFont.isUIResource() ?\n                        null : titleFont.createInstance();\n            Color color = titleColor == null || titleColor.isUIResource() ?\n                        null : titleColor.createInstance();\n            \n            return new TitledBorder(border == null ? null : border.createInstance(),\n                    title, titleJustification, titlePosition, font, color);\n        }\n        \n    }\n    \n    private static class CompoundBorderBuilder extends BorderBuilder {\n        \n        private final BorderBuilder outsideBorder;\n        private final BorderBuilder insideBorder;\n        \n        CompoundBorderBuilder(Instance instance) {\n            super(instance);\n            \n            outsideBorder = fromField(instance, \"outsideBorder\", true);\n            insideBorder = fromField(instance, \"insideBorder\", true);\n        }\n        \n        protected Border createInstanceImpl() {\n            Border outside = outsideBorder == null || outsideBorder.isUIResource() ?\n                             null : outsideBorder.createInstance();\n            Border inside = insideBorder == null || insideBorder.isUIResource() ?\n                             null : insideBorder.createInstance();\n            if (outside == null && inside == null) {\n                return BorderFactory.createEmptyBorder();\n            } else if (outside == null || inside == null) {\n                if (outside == null) return inside;\n                else return outside;\n            } else {\n                return BorderFactory.createCompoundBorder(outside, inside);\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ui/ButtonBuilders.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui;\n\nimport java.awt.Component;\nimport javax.swing.AbstractButton;\nimport javax.swing.DefaultButtonModel;\nimport javax.swing.JButton;\nimport javax.swing.JCheckBox;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuBar;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JRadioButton;\nimport javax.swing.JRadioButtonMenuItem;\nimport javax.swing.JToggleButton;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.IconBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.InsetsBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.ComponentBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.JComponentBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.Utils.InstanceBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.Utils.JPopupMenuImpl;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ButtonBuilders {\n\n    // Make sure subclasses are listed before base class if using isSubclassOf\n    static ComponentBuilder<? extends JComponent> getBuilder(Instance instance) {\n        if (DetailsUtils.isSubclassOf(instance, JButton.class.getName())) {\n            return new JButtonBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JCheckBox.class.getName())) {\n            return new JCheckBoxBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JRadioButton.class.getName())) {\n            return new JRadioButtonBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JToggleButton.class.getName())) {\n            return new JToggleButtonBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JCheckBoxMenuItem.class.getName())) {\n            return new JCheckBoxMenuItemBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JRadioButtonMenuItem.class.getName())) {\n            return new JRadioButtonMenuItemBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JMenu.class.getName())) {\n            return new JMenuBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JMenuBar.class.getName())) {\n            return new JMenuBarBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JMenuItem.class.getName())) {\n            return new JMenuItemBuilder(instance);\n        }\n        return null;\n    }\n    \n    \n    private static final class DefaultButtonModelBuilder extends InstanceBuilder<DefaultButtonModel> {\n        \n        private final int stateMask;\n        \n        DefaultButtonModelBuilder(Instance instance) {\n            super(instance);\n            \n            stateMask = DetailsUtils.getIntFieldValue(instance, \"stateMask\", 0);\n        }\n        \n        static DefaultButtonModelBuilder fromField(Instance instance, String field) {\n            Object model = instance.getValueOfField(field);\n            if (!(model instanceof Instance)) return null;\n            if (!DetailsUtils.isSubclassOf((Instance)model, DefaultButtonModel.class.getName())) return null;\n            return new DefaultButtonModelBuilder((Instance)model);\n        }\n        \n        protected void setupInstance(DefaultButtonModel instance) {\n            super.setupInstance(instance);\n            \n            instance.setArmed((stateMask & DefaultButtonModel.ARMED) != 0);\n            instance.setSelected((stateMask & DefaultButtonModel.SELECTED) != 0);\n            instance.setEnabled((stateMask & DefaultButtonModel.ENABLED) != 0);\n            instance.setPressed((stateMask & DefaultButtonModel.PRESSED) != 0);\n            instance.setRollover((stateMask & DefaultButtonModel.ROLLOVER) != 0);\n        }\n        \n        protected DefaultButtonModel createInstanceImpl() {\n            return new DefaultButtonModel();\n        }\n        \n    }\n    \n    private static abstract class AbstractButtonBuilder<T extends AbstractButton> extends JComponentBuilder<T> {\n        \n        private final DefaultButtonModelBuilder model;\n        private final String text;\n        private final InsetsBuilder margin;\n        private final IconBuilder defaultIcon;\n        private final int verticalAlignment;\n        private final boolean borderPaintedSet;\n        private final boolean paintBorder;\n        private final boolean contentAreaFilledSet;\n        private final boolean contentAreaFilled;\n        private final int horizontalAlignment;\n        private final int verticalTextPosition;\n        private final int horizontalTextPosition;\n        private final int iconTextGap;\n        \n        AbstractButtonBuilder(Instance instance) {\n            this(instance, false);\n        }\n        \n        AbstractButtonBuilder(Instance instance, boolean trackChildren) {\n            super(instance, false);\n            \n            model = DefaultButtonModelBuilder.fromField(instance, \"model\");\n            \n            text = Utils.getFieldString(instance, \"text\");\n            \n            margin = InsetsBuilder.fromField(instance, \"margin\");\n            \n            defaultIcon = IconBuilder.fromField(instance, \"defaultIcon\");\n            \n            borderPaintedSet = DetailsUtils.getBooleanFieldValue(instance, \"borderPaintedSet\", false);\n            paintBorder = DetailsUtils.getBooleanFieldValue(instance, \"paintBorder\", true);\n            contentAreaFilledSet = DetailsUtils.getBooleanFieldValue(instance, \"contentAreaFilledSet\", false);\n            contentAreaFilled = DetailsUtils.getBooleanFieldValue(instance, \"contentAreaFilled\", true);\n            \n            verticalAlignment = DetailsUtils.getIntFieldValue(instance, \"verticalAlignment\", JLabel.CENTER);\n            horizontalAlignment = DetailsUtils.getIntFieldValue(instance, \"horizontalAlignment\", JLabel.LEADING);\n            verticalTextPosition = DetailsUtils.getIntFieldValue(instance, \"verticalTextPosition\", JLabel.CENTER);\n            horizontalTextPosition = DetailsUtils.getIntFieldValue(instance, \"horizontalTextPosition\", JLabel.TRAILING);\n            iconTextGap = DetailsUtils.getIntFieldValue(instance, \"iconTextGap\", 4);\n        }\n        \n        protected void setupInstance(T instance) {\n            super.setupInstance(instance);\n            \n            if (model != null) instance.setModel(model.createInstance());\n            \n            instance.setText(text);\n            \n            if (margin != null) instance.setMargin(margin.createInstance());\n            \n            if (defaultIcon != null) instance.setIcon(defaultIcon.createInstance());\n            \n            if (borderPaintedSet) instance.setBorderPainted(paintBorder);\n            if (contentAreaFilledSet) instance.setContentAreaFilled(contentAreaFilled);\n            \n            instance.setVerticalAlignment(verticalAlignment);\n            instance.setHorizontalAlignment(horizontalAlignment);\n            instance.setVerticalTextPosition(verticalTextPosition);\n            instance.setHorizontalTextPosition(horizontalTextPosition);\n            instance.setIconTextGap(iconTextGap);\n        }\n        \n    }\n    \n    private static final class JButtonBuilder extends AbstractButtonBuilder<JButton> {\n        \n        JButtonBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JButton createInstanceImpl() {\n            return new JButton();\n        }\n        \n    }\n    \n    private static class JToggleButtonBuilder extends AbstractButtonBuilder<JToggleButton> {\n        \n        JToggleButtonBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JToggleButton createInstanceImpl() {\n            return new JToggleButton();\n        }\n        \n    }\n    \n    private static class JCheckBoxBuilder extends JToggleButtonBuilder {\n        \n        private final boolean flat;\n        \n        JCheckBoxBuilder(Instance instance) {\n            super(instance);\n            \n            flat = DetailsUtils.getBooleanFieldValue(instance, \"flat\", false);\n        }\n        \n        protected JToggleButton createInstanceImpl() {\n            JCheckBox checkBox = new JCheckBox();\n            checkBox.setBorderPaintedFlat(flat);\n            return checkBox;\n        }\n        \n    }\n    \n    private static class JRadioButtonBuilder extends JToggleButtonBuilder {\n        \n        JRadioButtonBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JToggleButton createInstanceImpl() {\n            return new JRadioButton();\n        }\n        \n    }\n    \n    private static class JMenuItemBuilder extends AbstractButtonBuilder<JMenuItem> {\n        \n        JMenuItemBuilder(Instance instance) {\n            super(instance, true);\n        }\n        \n        protected JMenuItem createInstanceImpl() {\n            return new JMenuItem();\n        }\n        \n        protected Component createPresenterImpl(JMenuItem instance) {\n            JPopupMenu popupMenu = new JPopupMenuImpl();\n            popupMenu.add(instance);\n            return popupMenu;\n        }\n        \n    }\n    \n    private static class JCheckBoxMenuItemBuilder extends JMenuItemBuilder {\n        \n        JCheckBoxMenuItemBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JMenuItem createInstanceImpl() {\n            return new JCheckBoxMenuItem();\n        }\n        \n    }\n    \n    private static class JRadioButtonMenuItemBuilder extends JMenuItemBuilder {\n        \n        JRadioButtonMenuItemBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JMenuItem createInstanceImpl() {\n            return new JRadioButtonMenuItem();\n        }\n        \n    }\n    \n    private static class JMenuBuilder extends JMenuItemBuilder {\n        \n        JMenuBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JMenuItem createInstanceImpl() {\n            return new JMenu();\n        }\n        \n        protected Component createPresenterImpl(JMenuItem instance) {\n            JMenuBar menuBar = new JMenuBar();\n            menuBar.add(instance);\n            return menuBar;\n        }\n        \n    }\n    \n    private static class JMenuBarBuilder extends JComponentBuilder<JMenuBar> {\n        \n        private final boolean paintBorder;\n        private final InsetsBuilder margin;\n        \n        JMenuBarBuilder(Instance instance) {\n            super(instance);\n            \n            paintBorder = DetailsUtils.getBooleanFieldValue(instance, \"paintBorder\", true);\n            margin = InsetsBuilder.fromField(instance, \"margin\");\n        }\n        \n        protected void setupInstance(JMenuBar instance) {\n            super.setupInstance(instance);\n            \n            instance.setBorderPainted(paintBorder);\n            if (margin != null) instance.setMargin(margin.createInstance());\n        }\n        \n        protected JMenuBar createInstanceImpl() {\n            return new JMenuBar();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ui/ComponentBuilders.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui;\n\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Rectangle;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.JComponent;\nimport javax.swing.border.Border;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.ColorBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.FontBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.RectangleBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BorderBuilders.BorderBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.Utils.InstanceBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.Utils.PlaceholderPanel;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ComponentBuilders {\n\n    // Make sure subclasses are listed before base class if using isSubclassOf\n    static ComponentBuilder getBuilder(Instance instance) {\n\n        if (Thread.interrupted()) return null;\n\n        ComponentBuilder jcomponent = JComponentBuilders.getBuilder(instance);\n        if (jcomponent != null) return jcomponent;\n\n        ComponentBuilder button = ButtonBuilders.getBuilder(instance);\n        if (button != null) return button;\n\n        ComponentBuilder textComponent = TextComponentBuilders.getBuilder(instance);\n        if (textComponent != null) return textComponent;\n\n        ComponentBuilder pane = PaneBuilders.getBuilder(instance);\n        if (pane != null) return pane;\n\n        ComponentBuilder dataView = DataViewBuilders.getBuilder(instance);\n        if (dataView != null) return dataView;\n        \n        ComponentBuilder window = WindowBuilders.getBuilder(instance);\n        if (window != null) return window;\n        \n        \n        // Always at the end - support for unrecognized components\n        if (DetailsUtils.isSubclassOf(instance, JComponent.class.getName())) {\n            return new JComponentBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, Container.class.getName())) {\n            return new ContainerBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, Component.class.getName())) {\n            return new ComponentBuilder(instance);\n        }\n        return null;\n    }\n    \n    \n    private static final class ChildrenBuilder extends InstanceBuilder<Component[]> {\n        \n        private final List<InstanceBuilder<Component>> component;\n        \n        ChildrenBuilder(Instance instance) {\n            super(instance);\n            \n            component = new ArrayList<>();\n            \n            if (instance instanceof ObjectArrayInstance) {                      // Component[] (JDK 5-)\n                List<Instance> components = ((ObjectArrayInstance)instance).getValues();\n                for (Instance c : components) {\n                    if (c != null) {\n                        ComponentBuilder builder = getBuilder(c);\n                        if (builder != null) component.add(builder);\n                    }\n                }\n            } else {                                                            // ArrayList<Component> (JDK 6+)\n                int size = DetailsUtils.getIntFieldValue(instance, \"size\", 0);\n                if (size > 0) {\n                    Object elementData = instance.getValueOfField(\"elementData\");\n                    if (elementData instanceof ObjectArrayInstance) {\n                        List<Instance> components = ((ObjectArrayInstance)elementData).getValues();\n                        for (Instance c : components) {\n                            if (c != null) {\n                                ComponentBuilder builder = getBuilder(c);\n                                if (builder != null) component.add(builder);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        static ChildrenBuilder fromField(Instance instance, String field) {\n            Object children = instance.getValueOfField(field);\n            if (!(children instanceof Instance)) return null;\n            return new ChildrenBuilder((Instance)children);\n        }\n        \n        protected Component[] createInstanceImpl() {\n            Component[] components = new Component[component.size()];\n            for (int i = 0; i < components.length; i++)\n                components[i] = component.get(i).createInstance();\n            return components;\n        }\n        \n    }\n    \n    static class ComponentBuilder<T extends Component> extends InstanceBuilder<T> {\n        \n        private final static int MAX_WIDTH = 10000;\n        private final static int MAX_HEIGHT = 10000;\n        \n        protected final String className;\n        \n        private final RectangleBuilder bounds;\n        private final ColorBuilder foreground;\n        private final ColorBuilder background;\n        private final FontBuilder font;\n        private final boolean visible;\n        private final boolean enabled;\n        \n        private boolean isPlaceholder = false;\n        \n        ComponentBuilder(Instance instance) {\n            super(instance);\n            \n            className = instance.getJavaClass().getName()+\"#\"+instance.getInstanceNumber();\n            \n            bounds = new RectangleBuilder(instance);\n            \n            foreground = ColorBuilder.fromField(instance, \"foreground\");\n            background = ColorBuilder.fromField(instance, \"background\");\n            \n            font = FontBuilder.fromField(instance, \"font\");\n            \n            visible = DetailsUtils.getBooleanFieldValue(instance, \"visible\", true);\n            enabled = DetailsUtils.getBooleanFieldValue(instance, \"enabled\", true);\n        }\n        \n        protected void setupInstance(T instance) {\n            super.setupInstance(instance);\n            \n            // #250485 - large components may cause OOME when previewing\n            Rectangle rect = bounds.createInstance();\n            if (rect != null) {\n                rect.width = Math.min(rect.width, MAX_WIDTH);\n                rect.height = Math.min(rect.height, MAX_HEIGHT);\n                instance.setBounds(rect);\n            }\n            \n//            if (foreground != null) instance.setForeground(foreground.createInstance());\n//            if (background != null) instance.setBackground(background.createInstance());\n            \n            if (foreground != null && (isPlaceholder || !foreground.isUIResource()))\n                    instance.setForeground(foreground.createInstance());\n            if (background != null && (isPlaceholder || !background.isUIResource()))\n                    instance.setBackground(background.createInstance());\n            \n            if (font != null && (isPlaceholder || !font.isUIResource()))\n                instance.setFont(font.createInstance());\n            \n            instance.setVisible(visible);\n            instance.setEnabled(enabled);\n        }\n        \n        protected final boolean isVisible() {\n            return visible;\n        }\n        \n        protected final void setPlaceholder() {\n            isPlaceholder = true;\n        }\n        \n        protected final boolean isPlaceholder() {\n            return isPlaceholder;\n        }\n        \n        protected T createInstanceImpl() {\n            setPlaceholder();\n            return (T)new PlaceholderPanel(className);\n        }\n        \n        protected Component createPresenterImpl(T instance) { return instance; }\n        \n        final Component createPresenter() {\n            T instance = createInstance();\n            return instance != null ? createPresenterImpl(instance) : null;\n        }\n        \n    }\n    \n    static class ContainerBuilder<T extends Container> extends ComponentBuilder<T> {\n        \n        private final boolean trackChildren;\n        private final ChildrenBuilder component;\n        \n        ContainerBuilder(Instance instance) {\n            this(instance, true);\n        }\n        \n        protected ContainerBuilder(Instance instance, boolean trackChildren) {\n            super(instance);\n            \n            this.trackChildren = trackChildren;\n            component = isVisible() && trackChildren ?\n                    ChildrenBuilder.fromField(instance, \"component\") : null;\n        }\n        \n        protected void setupInstance(T instance) {\n            super.setupInstance(instance);\n            \n            if (trackChildren) {\n                instance.setLayout(null);\n                instance.removeAll();\n                if (component != null) {\n                    Component[] components = component.createInstance();\n                    for (Component c : components) instance.add(c);\n                }\n            }\n        }\n        \n        protected T createInstanceImpl() {\n            setPlaceholder();\n            return (T)new PlaceholderPanel(className);\n        }\n        \n    }\n    \n    static class JComponentBuilder<T extends JComponent> extends ContainerBuilder<T> {\n        \n        private final boolean isAlignmentXSet;\n        private final float alignmentX;\n        private final boolean isAlignmentYSet;\n        private final float alignmentY;\n        private final BorderBuilder border;\n        private final int flags;\n        \n        JComponentBuilder(Instance instance) {\n            this(instance, true);\n        }\n        \n        protected JComponentBuilder(Instance instance, boolean trackChildren) {\n            super(instance, trackChildren);\n            \n            isAlignmentXSet = DetailsUtils.getBooleanFieldValue(instance, \"isAlignmentXSet\", false);\n            alignmentX = DetailsUtils.getFloatFieldValue(instance, \"alignmentX\", 0);\n            isAlignmentYSet = DetailsUtils.getBooleanFieldValue(instance, \"isAlignmentYSet\", false);\n            alignmentY = DetailsUtils.getFloatFieldValue(instance, \"alignmentY\", 0);\n            \n            border = BorderBuilders.fromField(instance, \"border\", false);\n            \n            flags = DetailsUtils.getIntFieldValue(instance, \"flags\", 0);\n        }\n        \n        protected void setupInstance(T instance) {\n            super.setupInstance(instance);\n            \n            instance.putClientProperty(\"className\", className);\n            \n            if (isAlignmentXSet) instance.setAlignmentX(alignmentX);\n            if (isAlignmentYSet) instance.setAlignmentY(alignmentY);\n            \n            if (border != null && (isPlaceholder() || !border.isUIResource())) {\n                Border b = border.createInstance();\n                if (b != null) instance.setBorder(b);\n            }\n            \n            int opaque_mask = (1 << 3);\n            boolean opaque = (flags & opaque_mask) == opaque_mask;\n            instance.setOpaque(opaque);\n        }\n        \n        protected T createInstanceImpl() {\n            setPlaceholder();\n            return (T)new PlaceholderPanel(className);\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ui/ComponentDetailsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Graphics;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.JComponent;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JScrollPane;\nimport javax.swing.SwingUtilities;\nimport javax.swing.ToolTipManager;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.ProfilerTopComponent;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.ComponentBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.model.BrowserUtils;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.windows.TopComponent;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ComponentDetailsProvider_NewWindow=Analyze in new window\",\n    \"ComponentDetailsProvider_InvisibleComponentPrefix=[invisible]\"\n})\n@ServiceProvider(service=DetailsProvider.class)\npublic final class ComponentDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String JLABEL_MASK = \"javax.swing.JLabel+\";                // NOI18N\n    private static final String ABSTRACTBUTTON_MASK = \"javax.swing.AbstractButton+\";// NOI18N\n    private static final String JTOOLTIP_MASK = \"javax.swing.JToolTip+\";            // NOI18N\n    private static final String JFILECHOOSER_MASK = \"javax.swing.JFileChooser+\";    // NOI18N\n    private static final String TABLECOLUMN_MASK = \"javax.swing.table.TableColumn+\";// NOI18N\n    private static final String JPANEL_MASK = \"javax.swing.JPanel+\";                // NOI18N\n    private static final String JPROGRESSBAR_MASK = \"javax.swing.JProgressBar+\";    // NOI18N\n    \n    private static final String JINTERNALFRAME_MASK = \"javax.swing.JInternalFrame+\";// NOI18N\n    private static final String FRAME_MASK = \"java.awt.Frame+\";                     // NOI18N\n    private static final String DIALOG_MASK = \"java.awt.Dialog+\";                   // NOI18N\n    \n    private static final String COMPONENT_MASK = \"java.awt.Component+\";             // NOI18N\n    \n    public ComponentDetailsProvider() {\n        super(JLABEL_MASK, ABSTRACTBUTTON_MASK, JTOOLTIP_MASK, JFILECHOOSER_MASK,\n              JINTERNALFRAME_MASK, TABLECOLUMN_MASK, JPANEL_MASK, JPROGRESSBAR_MASK,\n              FRAME_MASK, DIALOG_MASK, COMPONENT_MASK);\n    }\n    \n    public String getDetailsString(String className, Instance instance) {\n        String string = null;\n        \n        switch (className) {\n            case JLABEL_MASK: // JLabel+\n            case ABSTRACTBUTTON_MASK: // AbstractButton+\n                string = DetailsUtils.getInstanceFieldString(instance, \"text\");                                        // NOI18N\n                break;\n            case JTOOLTIP_MASK: // JToolTip+\n                string = DetailsUtils.getInstanceFieldString(instance, \"tipText\");                                     // NOI18N\n                break;\n            case JFILECHOOSER_MASK: // JFileChooser+\n                string = DetailsUtils.getInstanceFieldString(instance, \"dialogTitle\");                                 // NOI18N\n                break;\n            case JINTERNALFRAME_MASK: // JInternalFrame+\n            case FRAME_MASK: // Frame+\n            case DIALOG_MASK: // Dialog+\n                string = DetailsUtils.getInstanceFieldString(instance, \"title\");                                       // NOI18N\n                break;\n            case TABLECOLUMN_MASK: // TableColumn+\n                string = DetailsUtils.getInstanceFieldString(instance, \"headerValue\");                                 // NOI18N\n                break;\n            case JPROGRESSBAR_MASK: // JProgressBar+\n                boolean b = DetailsUtils.getBooleanFieldValue(\n                        instance, \"paintString\", false);                                // NOI18N\n                if (b) string = DetailsUtils.getInstanceFieldString(instance, \"progressString\");                              // NOI18N\n                break;\n            default:\n                break;\n        }\n        \n        if (string == null) {\n            // Value for a generic Component\n            string = getStringField(instance, \"displayName\");\n            if (string == null) string = getStringField(instance, \"label\");\n            if (string == null) string = getStringField(instance, \"name\");\n            // TODO: check tooltip\n\n            if (string != null && string.trim().isEmpty()) string = null;\n        }\n        \n        if (string != null) {\n            // Mark invisible components\n            boolean b = DetailsUtils.getBooleanFieldValue(\n                    instance, \"visible\", false);                                    // NOI18N\n            if (!b) string = Bundle.ComponentDetailsProvider_InvisibleComponentPrefix() + \" \" + string; // NOI18N\n        }\n        \n        return string;\n    }\n    \n    public View getDetailsView(String className, Instance instance) {\n        return new ComponentView(instance);\n    }\n    \n    \n    private static String getStringField(Instance instance, String field) {\n        Object string = instance.getValueOfField(field);\n        if (string instanceof Instance &&\n            String.class.getName().equals(((Instance)string).getJavaClass().getName()))\n            return DetailsUtils.getInstanceString((Instance)string);\n        return null;\n    }\n    \n    \n    private static class ComponentView extends Utils.View<ComponentBuilder> {\n        \n        private ComponentBuilder builder;\n        private Component component;\n        private Component hover;\n        private final MouseHandler mouse;\n        \n        private JComponent glassPane;\n        \n        private final String className;\n        private final int instanceNumber;\n        \n        private final boolean enableNewWindow;\n        private final boolean enableInteraction;\n        \n        ComponentView(Instance instance) {\n            this(instance, null, true, false);\n        }\n        \n        private ComponentView(Instance instance, ComponentBuilder builder, boolean enableNewWindow, boolean enableInteraction) {\n            super(instance);\n            \n            this.builder = builder;\n            this.enableNewWindow = enableNewWindow;\n            this.enableInteraction = enableInteraction;\n            \n            if (enableNewWindow || enableInteraction) {\n                mouse = new MouseHandler();\n                addMouseListener(mouse);\n            } else {\n                mouse = null;\n            }\n            \n            if (enableNewWindow) {\n                className = instance.getJavaClass().getName();\n                instanceNumber = instance.getInstanceNumber();\n            } else {\n                className = null;\n                instanceNumber = -1;\n            }\n        }\n        \n        protected ComponentBuilder getBuilder(Instance instance) {\n            if (builder == null)\n                builder = ComponentBuilders.getBuilder(instance);\n            return builder;\n        }\n        \n        protected Component getComponent(ComponentBuilder builder) {\n            component = builder.createPresenter();\n            if (component != null) component.setVisible(true);\n            return component;\n        }\n        \n        protected void setupGlassPane(JPanel glassPane) {\n            this.glassPane = glassPane;\n            if (mouse != null) {\n                glassPane.addMouseListener(mouse);\n                if (enableInteraction) {\n                    glassPane.addMouseMotionListener(mouse);\n                }\n            }\n        }\n        \n        private class MouseHandler extends MouseAdapter {\n            \n            public void mousePressed(final MouseEvent e) {\n                if (e.isPopupTrigger()) showPopup(e);\n            }\n\n            public void mouseReleased(MouseEvent e) {\n                if (e.isPopupTrigger()) showPopup(e);\n            }\n            \n            public void mouseMoved(MouseEvent e) {\n                Component at = e == null ? null :\n                        componentAt(component, e.getX(), e.getY());\n                if (hover == at) return;\n                hover = at;\n                hoverChanged();\n            }\n            \n            public void mouseExited(MouseEvent e) {\n                if (!enableInteraction) return;\n                mouseMoved(null);\n            }\n            \n        }\n        \n        \n        private void hoverChanged() {\n            String toolTipText;\n            if (hover != null) {                \n                JComponent jc = hover instanceof JComponent ? (JComponent)hover : null;\n                Object cn = jc == null ? null : jc.getClientProperty(\"className\");\n                String name = cn == null ? \"\" : cn.toString();\n                \n                toolTipText = name.isEmpty() ? null : name;\n            } else {\n                toolTipText = null;\n            }\n            // ToolTipManager doesn't like changing the tooltip from mouseMoved().\n            // This is a workaround to hide the tip when needed and prevent NPEs.\n            if (toolTipText == null) ToolTipManager.sharedInstance().mousePressed(null);\n            glassPane.setToolTipText(toolTipText);\n            repaint();\n        }\n        \n        public void paint(Graphics g) {\n            super.paint(g);\n            \n            if (hover != null) {\n                Rectangle b = SwingUtilities.convertRectangle(\n                        hover.getParent(), hover.getBounds(), this);\n                g.setColor(Color.RED);\n                g.drawRect(b.x, b.y, b.width, b.height);\n            }\n        }\n        \n        static Component componentAt(Component comp, int x, int y) {\n            if (!comp.contains(x, y)) return null;\n            \n            if (comp instanceof Container) {\n                for (Component c : ((Container)comp).getComponents()) {\n                    if (c != null && c.isVisible()) {\n                        Component at = componentAt(c, x - c.getX(), y - c.getY());\n                        if (at != null) return at;\n                    }\n                }\n            }\n                \n            return comp;\n        }\n        \n        private void showPopup(MouseEvent e) {\n            if (!enableNewWindow || builder == null || component == null) return;\n            \n            JMenuItem test = new JMenuItem(Bundle.ComponentDetailsProvider_NewWindow()) {\n                protected void fireActionPerformed(ActionEvent e) {\n                    openNewWindow();\n                }\n            };\n            \n            JPopupMenu popup = new JPopupMenu();\n            popup.add(test);\n            popup.show(e.getComponent(), e.getX(), e.getY());\n        }\n        \n        private void openNewWindow() {\n            Component c = new ComponentView(null, builder, false, true);\n            ComponentTopComponent ctc =\n                    new ComponentTopComponent(c, className, instanceNumber);\n            ctc.open();\n            ctc.requestActive();\n        }\n        \n    }\n    \n    private static class ComponentTopComponent extends ProfilerTopComponent {\n        \n        private static final String HELP_CTX_KEY = \"HeapWalker.ComponentPreview.HelpCtx\"; // NOI18N\n        private static final HelpCtx HELP_CTX = new HelpCtx(HELP_CTX_KEY);\n        \n        ComponentTopComponent(Component c, String className, int instanceNumber) {\n            setName(BrowserUtils.getSimpleType(className) + \" #\" + instanceNumber);\n//            setIcon(Icons.getImage(ProfilerIcons.HEAP_DUMP));\n            setToolTipText(\"Preview of \" + className + \" #\" + instanceNumber);\n//            getAccessibleContext().setAccessibleDescription(org.graalvm.visualvm.lib.profiler.heapwalk.ui.Bundle.HeapWalkerUI_ComponentDescr());\n            \n            setLayout(new BorderLayout());\n            add(new JScrollPane(c), BorderLayout.CENTER);\n        }\n        \n        public int getPersistenceType() {\n            return TopComponent.PERSISTENCE_NEVER;\n        }\n        \n        protected String preferredID() {\n            return this.getClass().getName();\n        }\n        \n        public HelpCtx getHelpCtx() {\n            return HELP_CTX;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ui/DataViewBuilders.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui;\n\nimport java.awt.Component;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.DefaultListModel;\nimport javax.swing.JComboBox;\nimport javax.swing.JComponent;\nimport javax.swing.JList;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTable;\nimport javax.swing.JTree;\nimport javax.swing.ListModel;\nimport javax.swing.table.DefaultTableColumnModel;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.table.TableColumn;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.ComponentBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.JComponentBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.Utils.InstanceBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.model.BrowserUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class DataViewBuilders {\n\n    // Make sure subclasses are listed before base class if using isSubclassOf\n    static ComponentBuilder<? extends JComponent> getBuilder(Instance instance) {\n        if (DetailsUtils.isSubclassOf(instance, JComboBox.class.getName())) {\n            return new JComboBoxBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JList.class.getName())) {\n            return new JListBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JTree.class.getName())) {\n            return new JTreeBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JTable.class.getName())) {\n            return new JTableBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JTableHeader.class.getName())) {\n            return new JTableHeaderBuilder(instance);\n        }\n        return null;\n    }\n    \n    \n    private static class JComboBoxBuilder extends JComponentBuilder<JComboBox<String>> {\n        \n        private final boolean isEditable;\n        private final String selectedObject;\n        \n        JComboBoxBuilder(Instance instance) {\n            super(instance, false);\n            \n            isEditable = DetailsUtils.getBooleanFieldValue(instance, \"isEditable\", false);\n            \n            String _selectedObject = null;\n            Object _dataModel = instance.getValueOfField(\"dataModel\");\n            if (_dataModel instanceof Instance) {\n                Instance dataModel = (Instance)_dataModel;\n                if (DetailsUtils.isSubclassOf(dataModel, DefaultComboBoxModel.class.getName())) {\n                    Object _selected = dataModel.getValueOfField(\"selectedObject\");\n                    if (_selected instanceof Instance) {\n                        Instance selected = (Instance)_selected;\n                        _selectedObject = DetailsUtils.getInstanceString(selected);\n                        if (_selectedObject == null)\n                            _selectedObject = BrowserUtils.getSimpleType(selected.getJavaClass().getName()) +\n                                             \" #\" + selected.getInstanceNumber();\n                    }\n                }\n            }\n            selectedObject = _selectedObject;\n        }\n        \n        protected void setupInstance(JComboBox<String> instance) {\n            super.setupInstance(instance);\n            \n            instance.setEditable(isEditable);\n            if (selectedObject != null) instance.addItem(selectedObject);\n        }\n        \n        protected JComboBox<String> createInstanceImpl() {\n            return new JComboBox<>();\n        }\n        \n    }\n    \n    private static class DefaultListModelBuilder extends InstanceBuilder<DefaultListModel<String>> {\n        \n        private final List<String> model;\n        \n        DefaultListModelBuilder(Instance instance) {\n            super(instance);\n            \n            model = new ArrayList<>();\n            \n            Object _delegate = instance.getValueOfField(\"delegate\");\n            if (_delegate instanceof Instance) {\n                Instance delegate = (Instance)_delegate;\n                Object _elementData = delegate.getValueOfField(\"elementData\");\n                if (_elementData instanceof ObjectArrayInstance) {\n                    int size = DetailsUtils.getIntFieldValue(delegate, \"elementCount\", 0);\n                    if (size > 0) { // TODO: should read up to 'size' elements\n                        ObjectArrayInstance elementData = (ObjectArrayInstance)_elementData;\n                        for (Instance item : elementData.getValues()) {\n                            if (item != null) {\n                                String ytem = DetailsUtils.getInstanceString(item);\n                                if (ytem == null)\n                                    ytem = BrowserUtils.getSimpleType(item.getJavaClass().getName()) +\n                                           \" #\" + item.getInstanceNumber();\n                                model.add(ytem);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        static DefaultListModelBuilder fromField(Instance instance, String field) {\n            Object model = instance.getValueOfField(field);\n            if (!(model instanceof Instance)) return null;\n            if (!DetailsUtils.isSubclassOf((Instance)model, DefaultListModel.class.getName())) return null;\n            return new DefaultListModelBuilder((Instance)model);\n        }\n        \n        protected void setupInstance(DefaultListModel<String> instance) {\n            super.setupInstance(instance);\n            \n            for (String item : model) instance.addElement(item);\n        }\n        \n        protected DefaultListModel<String> createInstanceImpl() {\n            return new DefaultListModel<>();\n        }\n        \n    }\n    \n    private static class JListBuilder extends JComponentBuilder<JList<String>> {\n        \n        private final DefaultListModelBuilder dataModel;\n        \n        JListBuilder(Instance instance) {\n            super(instance, false);\n            \n            dataModel = DefaultListModelBuilder.fromField(instance, \"dataModel\");\n        }\n        \n        protected void setupInstance(JList<String> instance) {\n            super.setupInstance(instance);\n            \n            ListModel<String> model = dataModel == null ? null : dataModel.createInstance();\n            if (model != null) instance.setModel(model);\n        }\n        \n        protected JList<String> createInstanceImpl() {\n            return new JList<>();\n        }\n        \n    }\n    \n    private static class JTreeBuilder extends JComponentBuilder<JTree> {\n        \n        private final boolean editable;\n        \n        JTreeBuilder(Instance instance) {\n            super(instance, false);\n            \n            editable = DetailsUtils.getBooleanFieldValue(instance, \"editable\", false);\n        }\n        \n        protected void setupInstance(JTree instance) {\n            super.setupInstance(instance);\n            \n            instance.setEditable(editable);\n        }\n        \n        protected JTree createInstanceImpl() {\n            return new JTree(new Object[0]);\n        }\n        \n    }\n    \n    private static class TableColumnBuilder extends InstanceBuilder<TableColumn> {\n        private final int modelIndex;\n        private final int width;\n        private final String headerValue;\n        \n        TableColumnBuilder(Instance instance) {\n            super(instance);\n            \n            modelIndex = DetailsUtils.getIntFieldValue(instance, \"modelIndex\", 0);\n            width = DetailsUtils.getIntFieldValue(instance, \"width\", 75);\n            \n            String _headerValue = Utils.getFieldString(instance, \"headerValue\");\n            headerValue = _headerValue != null ? _headerValue : \"Col \" + (modelIndex + 1);\n        }\n        \n        protected void setupInstance(TableColumn instance) {\n            super.setupInstance(instance);\n            \n            instance.setHeaderValue(headerValue);\n        }\n        \n        protected TableColumn createInstanceImpl() {\n            return new TableColumn(modelIndex, width, null, null);\n        }\n    }\n    \n    private static class TableColumnModelBuilder extends InstanceBuilder<DefaultTableColumnModel> {\n        \n        private final List<TableColumnBuilder> tableColumns;\n        private final int columnMargin;\n        \n        TableColumnModelBuilder(Instance instance) {\n            super(instance);\n            \n            tableColumns = new ArrayList<>();\n            columnMargin = DetailsUtils.getIntFieldValue(instance, \"columnMargin\", 1);\n            \n            Object _columns = instance.getValueOfField(\"tableColumns\");\n            if (_columns instanceof Instance) {\n                Instance columns = (Instance)_columns;\n                Object _elementData = columns.getValueOfField(\"elementData\");\n                if (_elementData instanceof ObjectArrayInstance) {\n                    int size = DetailsUtils.getIntFieldValue(columns, \"elementCount\", 0);\n                    if (size > 0) { // TODO: should read up to 'size' elements\n                        ObjectArrayInstance elementData = (ObjectArrayInstance)_elementData;\n                        for (Instance column : elementData.getValues()) {\n                            if (column != null)\n                                tableColumns.add(new TableColumnBuilder(column));\n                        }\n                    }\n                }\n            }\n        }\n        \n        static TableColumnModelBuilder fromField(Instance instance, String field) {\n            Object model = instance.getValueOfField(field);\n            if (!(model instanceof Instance)) return null;\n            if (!DetailsUtils.isSubclassOf((Instance)model, DefaultTableColumnModel.class.getName())) return null;\n            return new TableColumnModelBuilder((Instance)model);\n        }\n        \n        protected void setupInstance(DefaultTableColumnModel instance) {\n            super.setupInstance(instance);\n            \n            for (TableColumnBuilder builder : tableColumns)\n                instance.addColumn(builder.createInstance());\n            instance.setColumnMargin(columnMargin); \n        }\n        \n        protected DefaultTableColumnModel createInstanceImpl() {\n            return new DefaultTableColumnModel();\n        }\n        \n    }\n    \n    private static class JTableBuilder extends JComponentBuilder<JTable> {\n        \n        private final TableColumnModelBuilder columnModel;\n        \n        JTableBuilder(Instance instance) {\n            super(instance, false);\n            \n            columnModel = TableColumnModelBuilder.fromField(instance, \"columnModel\");\n        }\n        \n        protected JTable createInstanceImpl() {\n            return new JTable();\n        }\n        \n        protected Component createPresenterImpl(JTable instance) {\n            TableColumnModel _columnModel = columnModel == null ? null : columnModel.createInstance();\n            if (_columnModel == null || _columnModel.getColumnCount() == 0) {\n                TableColumn column = new TableColumn(0, instance.getWidth());\n                column.setHeaderValue(\"Table\");\n                _columnModel = new DefaultTableColumnModel();\n                _columnModel.addColumn(column);\n            }\n            instance.setColumnModel(_columnModel);\n            instance.setPreferredScrollableViewportSize(instance.getSize());\n            \n            return new JScrollPane(instance);\n        }\n        \n    }\n    \n    private static class JTableHeaderBuilder extends JComponentBuilder<JTableHeader> {\n        \n        private final TableColumnModelBuilder columnModel;\n        \n        JTableHeaderBuilder(Instance instance) {\n            super(instance, false);\n            \n            columnModel = TableColumnModelBuilder.fromField(instance, \"columnModel\");\n        }\n        \n        protected void setupInstance(JTableHeader instance) {\n            super.setupInstance(instance);\n            \n            TableColumnModel _columnModel = columnModel == null ? null : columnModel.createInstance();\n            if (_columnModel == null || _columnModel.getColumnCount() == 0) {\n                TableColumn column = new TableColumn(0, instance.getWidth());\n                column.setHeaderValue(\"Table\");\n                _columnModel = new DefaultTableColumnModel();\n                _columnModel.addColumn(column);\n            }\n            instance.setColumnModel(_columnModel);\n        }\n        \n        protected JTableHeader createInstanceImpl() {\n            return new JTableHeader();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ui/JComponentBuilders.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui;\n\nimport java.awt.LayoutManager;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.DefaultBoundedRangeModel;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JProgressBar;\nimport javax.swing.JScrollBar;\nimport javax.swing.JSeparator;\nimport javax.swing.JSlider;\nimport javax.swing.JSpinner;\nimport javax.swing.JToolBar;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.DimensionBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.IconBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.InsetsBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.ComponentBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.JComponentBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.Utils.InstanceBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JComponentBuilders {\n\n    // Make sure subclasses are listed before base class if using isSubclassOf\n    static ComponentBuilder<? extends JComponent> getBuilder(Instance instance) {\n        if (DetailsUtils.isSubclassOf(instance, JLabel.class.getName())) {\n            return new JLabelBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JPanel.class.getName())) {\n            return new JPanelBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JToolBar.class.getName())) {\n            return new JToolBarBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, Box.Filler.class.getName())) {\n            return new BoxFillerBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, Box.class.getName())) {\n            return new BoxBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JScrollBar.class.getName())) {\n            return new JScrollBarBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JToolBar.Separator.class.getName())) {\n            return new JToolBarSeparatorBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JPopupMenu.Separator.class.getName())) {\n            return new JPopupMenuSeparatorBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JSeparator.class.getName())) {\n            return new JSeparatorBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JProgressBar.class.getName())) {\n            return new JProgressBarBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JSlider.class.getName())) {\n            return new JSliderBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JSpinner.class.getName())) {\n            return new JSpinnerBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JPopupMenu.class.getName())) {\n            return new JPopupMenuBuilder(instance);\n        }\n        return null;\n    }\n    \n    \n    private static final class JLabelBuilder extends JComponentBuilder<JLabel> {\n        \n        private final String text;\n        private final IconBuilder defaultIcon;\n        private final int verticalAlignment;\n        private final int horizontalAlignment;\n        private final int verticalTextPosition;\n        private final int horizontalTextPosition;\n        private final int iconTextGap;\n        \n        JLabelBuilder(Instance instance) {\n            super(instance, false);\n            \n            text = Utils.getFieldString(instance, \"text\");\n            \n            defaultIcon = IconBuilder.fromField(instance, \"defaultIcon\");\n            \n            verticalAlignment = DetailsUtils.getIntFieldValue(instance, \"verticalAlignment\", JLabel.CENTER);\n            horizontalAlignment = DetailsUtils.getIntFieldValue(instance, \"horizontalAlignment\", JLabel.LEADING);\n            verticalTextPosition = DetailsUtils.getIntFieldValue(instance, \"verticalTextPosition\", JLabel.CENTER);\n            horizontalTextPosition = DetailsUtils.getIntFieldValue(instance, \"horizontalTextPosition\", JLabel.TRAILING);\n            iconTextGap = DetailsUtils.getIntFieldValue(instance, \"iconTextGap\", 4);\n        }\n        \n        protected void setupInstance(JLabel instance) {\n            super.setupInstance(instance);\n            \n            instance.setText(text);\n            \n            if (defaultIcon != null) instance.setIcon(defaultIcon.createInstance());\n            \n            instance.setVerticalAlignment(verticalAlignment);\n            instance.setHorizontalAlignment(horizontalAlignment);\n            instance.setVerticalTextPosition(verticalTextPosition);\n            instance.setHorizontalTextPosition(horizontalTextPosition);\n            instance.setIconTextGap(iconTextGap);\n        }\n        \n        protected JLabel createInstanceImpl() {\n            return new JLabel();\n        }\n        \n    }\n    \n    private static class JPanelBuilder extends JComponentBuilder<JPanel> {\n        \n        JPanelBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JPanel createInstanceImpl() {\n            return new JPanel(null);\n        }\n        \n    }\n    \n    private static class JToolBarBuilder extends JComponentBuilder<JToolBar> {\n        \n        private final boolean paintBorder;\n        private final InsetsBuilder margin;\n        private final boolean floatable;\n        private final int orientation;\n        \n        JToolBarBuilder(Instance instance) {\n            super(instance);\n            \n            paintBorder = DetailsUtils.getBooleanFieldValue(instance, \"paintBorder\", true);\n            \n            margin = InsetsBuilder.fromField(instance, \"margin\");\n            \n            floatable = DetailsUtils.getBooleanFieldValue(instance, \"floatable\", true);\n            orientation = DetailsUtils.getIntFieldValue(instance, \"orientation\", JToolBar.HORIZONTAL);\n        }\n        \n        protected void setupInstance(JToolBar instance) {\n            super.setupInstance(instance);\n            \n            instance.setBorderPainted(paintBorder);\n            \n            if (margin != null) instance.setMargin(margin.createInstance());\n            \n            instance.setFloatable(floatable);\n            instance.setOrientation(orientation);\n        }\n        \n        protected JToolBar createInstanceImpl() {\n            return new JToolBar();\n        }\n        \n    }\n    \n    private static class BoxBuilder extends JComponentBuilder<Box> {\n        \n        BoxBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected Box createInstanceImpl() {\n            return new Box(BoxLayout.X_AXIS) {\n                public void layout() {}\n                public void setLayout(LayoutManager l) {}\n            };\n        }\n        \n    }\n    \n    private static class BoxFillerBuilder extends JComponentBuilder<Box.Filler> {\n        \n        BoxFillerBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected Box.Filler createInstanceImpl() {\n            return new Box.Filler(null, null, null);\n        }\n        \n    }\n    \n    private static class DefaultBoundedRangeModelBuilder extends InstanceBuilder<DefaultBoundedRangeModel> {\n        \n        private final int value;\n        private final int extent;\n        private final int min;\n        private final int max;\n        \n        DefaultBoundedRangeModelBuilder(Instance instance) {\n            super(instance);\n            \n            value = DetailsUtils.getIntFieldValue(instance, \"value\", 0);\n            extent = DetailsUtils.getIntFieldValue(instance, \"extent\", 0);\n            min = DetailsUtils.getIntFieldValue(instance, \"min\", 0);\n            max = DetailsUtils.getIntFieldValue(instance, \"max\", 100);\n        }\n        \n        static DefaultBoundedRangeModelBuilder fromField(Instance instance, String field) {\n            Object model = instance.getValueOfField(field);\n            if (!(model instanceof Instance)) return null;\n            if (!DetailsUtils.isSubclassOf((Instance)model, DefaultBoundedRangeModel.class.getName())) return null;\n            return new DefaultBoundedRangeModelBuilder((Instance)model);\n        }\n        \n        protected DefaultBoundedRangeModel createInstanceImpl() {\n            return new DefaultBoundedRangeModel(value, extent, min, max);\n        }\n        \n    }\n    \n    private static class JScrollBarBuilder extends JComponentBuilder<JScrollBar> {\n        \n        private final DefaultBoundedRangeModelBuilder model;\n        private final int orientation;\n        \n        JScrollBarBuilder(Instance instance) {\n            super(instance, false);\n            \n            model = DefaultBoundedRangeModelBuilder.fromField(instance, \"model\");\n            orientation = DetailsUtils.getIntFieldValue(instance, \"orientation\", JScrollBar.VERTICAL);\n        }\n        \n        static JScrollBarBuilder fromField(Instance instance, String field) {\n            Object insets = instance.getValueOfField(field);\n            if (!(insets instanceof Instance)) return null;\n            return new JScrollBarBuilder((Instance)insets);\n        }\n        \n        protected void setupInstance(JScrollBar instance) {\n            super.setupInstance(instance);\n            \n            if (model != null) instance.setModel(model.createInstance());\n        }\n        \n        protected JScrollBar createInstanceImpl() {\n            return new JScrollBar(orientation);\n        }\n        \n    }\n    \n    private static class JSeparatorBuilder extends JComponentBuilder<JSeparator> {\n        \n        private final int orientation;\n        \n        JSeparatorBuilder(Instance instance) {\n            super(instance, false);\n            \n            orientation = DetailsUtils.getIntFieldValue(instance, \"orientation\", JSeparator.HORIZONTAL);\n        }\n        \n        protected JSeparator createInstanceImpl() {\n            return new JSeparator(orientation);\n        }\n        \n    }\n    \n    private static class JToolBarSeparatorBuilder extends JSeparatorBuilder {\n        \n        private final DimensionBuilder separatorSize;\n        \n        JToolBarSeparatorBuilder(Instance instance) {\n            super(instance);\n            \n            separatorSize = DimensionBuilder.fromField(instance, \"separatorSize\");\n        }\n        \n        protected JSeparator createInstanceImpl() {\n            return separatorSize == null ? new JToolBar.Separator() :\n                    new JToolBar.Separator(separatorSize.createInstance());\n        }\n        \n    }\n    \n    private static class JPopupMenuSeparatorBuilder extends JSeparatorBuilder {\n        \n        JPopupMenuSeparatorBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JSeparator createInstanceImpl() {\n            return new JPopupMenu.Separator();\n        }\n        \n    }\n    \n    private static class JProgressBarBuilder extends JComponentBuilder<JProgressBar> {\n        \n        private final int orientation;\n        private final boolean paintBorder;\n        private final DefaultBoundedRangeModelBuilder model;\n        private final String progressString;\n        private final boolean paintString;\n        private final boolean indeterminate;\n        \n        JProgressBarBuilder(Instance instance) {\n            super(instance, false);\n            \n            orientation = DetailsUtils.getIntFieldValue(instance, \"orientation\", JProgressBar.HORIZONTAL);\n            paintBorder = DetailsUtils.getBooleanFieldValue(instance, \"paintBorder\", true);\n            model = DefaultBoundedRangeModelBuilder.fromField(instance, \"model\");\n            progressString = Utils.getFieldString(instance, \"progressString\");\n            paintString = DetailsUtils.getBooleanFieldValue(instance, \"paintString\", false);\n            indeterminate = DetailsUtils.getBooleanFieldValue(instance, \"indeterminate\", false);\n        }\n        \n        protected void setupInstance(JProgressBar instance) {\n            super.setupInstance(instance);\n            \n            instance.setBorderPainted(paintBorder);\n            if (model != null) instance.setModel(model.createInstance());\n            if (progressString != null) instance.setString(progressString);\n            instance.setStringPainted(paintString);\n            instance.setIndeterminate(indeterminate);\n        }\n        \n        protected JProgressBar createInstanceImpl() {\n            return new JProgressBar(orientation);\n        }\n        \n    }\n    \n    private static class JSliderBuilder extends JComponentBuilder<JSlider> {\n        \n        private final boolean paintTicks;\n        private final boolean paintTrack;\n        private final boolean paintLabels;\n        private final boolean isInverted;\n        private final DefaultBoundedRangeModelBuilder sliderModel;\n        private final int majorTickSpacing;\n        private final int minorTickSpacing;\n        private final boolean snapToTicks;\n        private final int orientation;\n        \n        JSliderBuilder(Instance instance) {\n            super(instance, false);\n            \n            paintTicks = DetailsUtils.getBooleanFieldValue(instance, \"paintTicks\", false);\n            paintTrack = DetailsUtils.getBooleanFieldValue(instance, \"paintTrack\", true);\n            paintLabels = DetailsUtils.getBooleanFieldValue(instance, \"paintLabels\", false);\n            isInverted = DetailsUtils.getBooleanFieldValue(instance, \"isInverted\", false);\n            sliderModel = DefaultBoundedRangeModelBuilder.fromField(instance, \"sliderModel\");\n            majorTickSpacing = DetailsUtils.getIntFieldValue(instance, \"majorTickSpacing\", 0);\n            minorTickSpacing = DetailsUtils.getIntFieldValue(instance, \"minorTickSpacing\", 0);\n            snapToTicks = DetailsUtils.getBooleanFieldValue(instance, \"snapToTicks\", false);\n            orientation = DetailsUtils.getIntFieldValue(instance, \"orientation\", JProgressBar.HORIZONTAL);\n        }\n        \n        protected void setupInstance(JSlider instance) {\n            super.setupInstance(instance);\n            \n            instance.setPaintTicks(paintTicks);\n            instance.setPaintTrack(paintTrack);\n            instance.setPaintLabels(paintLabels);\n            instance.setInverted(isInverted);\n            if (sliderModel != null) instance.setModel(sliderModel.createInstance());\n            instance.setMajorTickSpacing(majorTickSpacing);\n            instance.setMinorTickSpacing(minorTickSpacing);\n            instance.setSnapToTicks(snapToTicks);\n        }\n        \n        protected JSlider createInstanceImpl() {\n            return new JSlider(orientation);\n        }\n        \n    }\n    \n    private static Number getNumber(Instance number) {\n        if (!DetailsUtils.isSubclassOf(number, Number.class.getName())) return null;\n        String _number = DetailsUtils.getInstanceString(number);\n        if (_number == null || _number.isEmpty()) return null;\n        \n        try {\n            if (DetailsUtils.isSubclassOf(number, Integer.class.getName()))\n                return Integer.valueOf(_number);\n            else if (DetailsUtils.isSubclassOf(number, Byte.class.getName()))\n                return Byte.valueOf(_number);\n            else if (DetailsUtils.isSubclassOf(number, Short.class.getName()))\n                return Short.valueOf(_number);\n            else if (DetailsUtils.isSubclassOf(number, Long.class.getName()))\n                return Long.valueOf(_number);\n            else if (DetailsUtils.isSubclassOf(number, Float.class.getName()))\n                return Float.valueOf(_number);\n            else if (DetailsUtils.isSubclassOf(number, Double.class.getName()))\n                return Double.valueOf(_number);\n        } catch (NumberFormatException e) {}\n        \n        return null;\n    }\n    \n    private static class JSpinnerBuilder extends JComponentBuilder<JSpinner> {\n        \n        private Number value;\n        \n        JSpinnerBuilder(Instance instance) {\n            super(instance, false);\n            \n            Number val = null;\n            Object model = instance.getValueOfField(\"model\");\n            if (model instanceof Instance) {\n                Object _value = ((Instance)model).getValueOfField(\"value\");\n                if (_value instanceof Instance) val = getNumber((Instance)_value);\n            }\n            value = val;\n        }\n        \n        protected void setupInstance(JSpinner instance) {\n            super.setupInstance(instance);\n            \n            if (value != null) instance.setValue(value);\n        }\n        \n        protected JSpinner createInstanceImpl() {\n            return new JSpinner();\n        }\n        \n    }\n    \n    private static class JPopupMenuBuilder extends JComponentBuilder<JPopupMenu> {\n        \n        private final String label;\n        private final boolean paintBorder;\n        \n        JPopupMenuBuilder(Instance instance) {\n            super(instance);\n            \n            label = Utils.getFieldString(instance, \"label\");\n            paintBorder = DetailsUtils.getBooleanFieldValue(instance, \"paintBorder\", true);\n        }\n        \n        protected void setupInstance(JPopupMenu instance) {\n            super.setupInstance(instance);\n            \n            if (label != null) instance.setLabel(label);\n            instance.setBorderPainted(paintBorder);\n        }\n        \n        protected JPopupMenu createInstanceImpl() {\n            return new Utils.JPopupMenuImpl();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ui/PaneBuilders.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.JScrollPane;\nimport javax.swing.JSplitPane;\nimport javax.swing.JTabbedPane;\nimport javax.swing.JViewport;\nimport javax.swing.border.Border;\nimport javax.swing.plaf.basic.BasicSplitPaneDivider;\nimport javax.swing.plaf.basic.BasicSplitPaneUI;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.ColorBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.IconBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BorderBuilders.BorderBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.ComponentBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.ContainerBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.JComponentBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.Utils.InstanceBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class PaneBuilders {\n\n    // Make sure subclasses are listed before base class if using isSubclassOf\n    static ComponentBuilder<? extends Container> getBuilder(Instance instance) {\n        if (DetailsUtils.isSubclassOf(instance, JViewport.class.getName())) {\n            return new JViewportBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JScrollPane.class.getName())) {\n            return new JScrollPaneBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JSplitPane.class.getName())) {\n            return new JSplitPaneBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, BasicSplitPaneDivider.class.getName())) {\n            return new BasicSplitPaneDividerBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JTabbedPane.class.getName())) {\n            return new JTabbedPaneBuilder(instance);\n        }\n        return null;\n    }\n    \n    \n    private static class JViewportBuilder extends JComponentBuilder<JViewport> {\n        \n        JViewportBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JViewport createInstanceImpl() {\n            return new JViewport();\n        }\n        \n    }\n    \n    private static class JScrollPaneBuilder extends JComponentBuilder<JScrollPane> {\n        \n        private final BorderBuilder viewportBorder;\n        \n        JScrollPaneBuilder(Instance instance) {\n            super(instance);\n            \n            viewportBorder = BorderBuilders.fromField(instance, \"viewportBorder\", false);\n\n        }\n        \n        protected void setupInstance(JScrollPane instance) {\n            super.setupInstance(instance);\n            \n            if (viewportBorder != null) {\n                Border b = viewportBorder.createInstance();\n                if (b != null) instance.setViewportBorder(b);\n            }\n        }\n        \n        protected JScrollPane createInstanceImpl() {\n            return new JScrollPane();\n        }\n        \n    }\n    \n    private static class JSplitPaneBuilder extends JComponentBuilder<JSplitPane> {\n        \n        private final int orientation;\n        \n        JSplitPaneBuilder(Instance instance) {\n            super(instance);\n            \n            orientation = DetailsUtils.getIntFieldValue(instance, \"orientation\", JSplitPane.HORIZONTAL_SPLIT);\n\n        }\n        \n        protected JSplitPane createInstanceImpl() {\n            return new JSplitPane(orientation);\n        }\n        \n    }\n    \n    private static class BasicSplitPaneDividerBuilder extends ContainerBuilder<BasicSplitPaneDivider> {\n        \n        private final int orientation;\n//        private final int dividerSize;\n        private final BorderBuilder border;\n        \n        BasicSplitPaneDividerBuilder(Instance instance) {\n            super(instance, false);\n            \n            orientation = DetailsUtils.getIntFieldValue(instance, \"orientation\", JSplitPane.HORIZONTAL_SPLIT);\n//            dividerSize = DetailsUtils.getIntFieldValue(instance, \"dividerSize\", 0);\n            border = BorderBuilders.fromField(instance, \"border\", false);\n        }\n        \n        protected void setupInstance(BasicSplitPaneDivider instance) {\n            super.setupInstance(instance);\n            \n//            instance.setDividerSize(dividerSize);\n            if (border != null) {\n                Border b = border.createInstance();\n                if (b != null) instance.setBorder(b);\n            }\n        }\n        \n        protected BasicSplitPaneDivider createInstanceImpl() {\n            final JSplitPane split = new JSplitPane(orientation);\n            BasicSplitPaneUI ui = split.getUI() instanceof BasicSplitPaneUI ?\n                    (BasicSplitPaneUI)split.getUI() : new BasicSplitPaneUI() {\n                        { installUI(split); }\n                    };\n            return new BasicSplitPaneDivider(ui);\n        }\n        \n    }\n    \n    \n    private static class PageImpl {\n        final String title;\n        final ColorBuilder background;\n        final ColorBuilder foreground;\n        final IconBuilder icon;\n        final long component;\n        final boolean enabled;\n        \n        PageImpl(String title, ColorBuilder background, ColorBuilder foreground,\n                 IconBuilder icon, long component, boolean enabled) {\n            this.title = title;\n            this.background = background;\n            this.foreground = foreground;\n            this.icon = icon;\n            this.component = component;\n            this.enabled = enabled;\n        }\n    }\n    \n    private static class PageImplBuilder extends InstanceBuilder<List<PageImpl>> {\n        \n        private final List<PageImpl> pages;\n        \n        PageImplBuilder(Instance instance) {\n            super(instance);\n            \n            pages = new ArrayList<>(1);\n            \n            Object _elementData = instance.getValueOfField(\"elementData\");\n            if (_elementData instanceof ObjectArrayInstance) {\n                int size = DetailsUtils.getIntFieldValue(instance, \"size\", Integer.MIN_VALUE); // ArrayList, JDK 7+\n                if (size == Integer.MIN_VALUE) size = DetailsUtils.getIntFieldValue(instance, \"elementCount\", 0); // Vector, JDK 6-\n                \n                if (size > 0) { // TODO: should read up to 'size' elements\n                    ObjectArrayInstance elementData = (ObjectArrayInstance)_elementData;\n                    for (Instance page : elementData.getValues()) {\n                        if (page != null) {\n                            Object comp = page.getValueOfField(\"component\");\n                            pages.add(new PageImpl(\n                                            Utils.getFieldString(page, \"title\"),\n                                            ColorBuilder.fromField(page, \"background\"),\n                                            ColorBuilder.fromField(page, \"foreground\"),\n                                            IconBuilder.fromField(page, \"icon\"),\n                                            comp instanceof Instance ? ((Instance)comp).getInstanceId() : -1,\n                                            DetailsUtils.getBooleanFieldValue(page, \"enabled\", true)\n                                      ));\n                        }\n                    }\n                }\n            }\n        }\n        \n        static PageImplBuilder fromField(Instance instance, String field) {\n            Object pages = instance.getValueOfField(field);\n            if (!(pages instanceof Instance)) return null;\n            return new PageImplBuilder((Instance)pages);\n        }\n        \n        protected List<PageImpl> createInstanceImpl() {\n            return pages;\n        }\n        \n    }\n    \n    private static class JTabbedPaneBuilder extends JComponentBuilder<JTabbedPane> {\n        \n        private final int tabPlacement;\n        private final int tabLayoutPolicy;\n        private final PageImplBuilder pages;\n        private final long visCompId;\n        private final InstanceBuilder<Component> visComp;\n        private int selComp = -1;\n        \n        JTabbedPaneBuilder(Instance instance) {\n            super(instance, false);\n            \n            tabPlacement = DetailsUtils.getIntFieldValue(instance, \"tabPlacement\", JTabbedPane.TOP);\n            tabLayoutPolicy = DetailsUtils.getIntFieldValue(instance, \"tabLayoutPolicy\", JTabbedPane.WRAP_TAB_LAYOUT);\n            pages = PageImplBuilder.fromField(instance, \"pages\");\n            \n            Object _visComp = instance.getValueOfField(\"visComp\");\n            if (_visComp instanceof Instance) {\n                Instance visCompI = (Instance)_visComp;\n                visCompId = visCompI.getInstanceId();\n                visComp = ComponentBuilders.getBuilder(visCompI);\n            } else {\n                visCompId = Long.MIN_VALUE;\n                visComp = null;\n            }\n        }\n        \n        protected void setupInstance(JTabbedPane instance) {\n            super.setupInstance(instance);\n            \n            if (pages != null) {\n                List<PageImpl> pageImpls = pages.createInstance();\n                for (PageImpl page : pageImpls) {\n                    int index = instance.getTabCount();\n                    Component comp = null;\n                    if (selComp == -1 && visComp != null && visCompId == page.component) {\n//                        comp = new JPanel(null) { public boolean isOpaque() { return false; } };\n                        comp = visComp.createInstance();\n                        selComp = index;\n                    }\n                    instance.addTab(page.title, page.icon == null ? null : page.icon.createInstance(), comp);\n                    if (page.background != null) {\n                        Color background = page.background.createInstance();\n                        if (background != null) instance.setBackgroundAt(index, background);\n                    }\n                    if (page.foreground != null) {\n                        Color foreground = page.foreground.createInstance();\n                        if (foreground != null) instance.setForegroundAt(index, foreground);\n                    }\n                    instance.setEnabledAt(index, page.enabled);\n                }\n            }\n            \n            if (selComp != -1) {\n                instance.setSelectedIndex(selComp);\n//                instance.add(visComp.createInstance());\n                selComp = -1; // Cleanup for eventual Builder reuse\n            }\n        }\n        \n        protected JTabbedPane createInstanceImpl() {\n            return new JTabbedPane(tabPlacement, tabLayoutPolicy) {\n//                public Component add(Component component) {\n//                    addImpl(component, null, getComponentCount());\n//                    return component;\n//                }\n//                protected void processContainerEvent(ContainerEvent e) {}\n            };\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ui/TextComponentBuilders.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui;\n\nimport java.util.List;\nimport javax.swing.JEditorPane;\nimport javax.swing.JTextArea;\nimport javax.swing.JTextField;\nimport javax.swing.text.GapContent;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.PlainDocument;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.InsetsBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.JComponentBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.Utils.InstanceBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TextComponentBuilders {\n\n    // Make sure subclasses are listed before base class if using isSubclassOf\n    static ComponentBuilders.ComponentBuilder<? extends JTextComponent> getBuilder(Instance instance) {\n        if (DetailsUtils.isSubclassOf(instance, JTextField.class.getName())) {\n            return new JTextFieldBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JTextArea.class.getName())) {\n            return new JTextAreaBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JEditorPane.class.getName())) {\n            return new JEditorPaneBuilder(instance);\n        }\n        return null;\n    }\n\n\n    private static class ContentTextBuilder extends InstanceBuilder<String> {\n\n        private final char[] array;\n\n        ContentTextBuilder(Instance instance) {\n            super(instance);\n\n            List<String> values = DetailsUtils.getPrimitiveArrayFieldValues(instance, \"array\");\n            array = values != null ? DetailsUtils.getCharArray(values) : null;\n        }\n\n        static ContentTextBuilder fromField(Instance instance, String field) {\n            Object model = instance.getValueOfField(field);\n            if (!(model instanceof Instance)) return null;\n            if (!DetailsUtils.isSubclassOf((Instance)model, GapContent.class.getName())) return null;\n            return new ContentTextBuilder((Instance)model);\n        }\n        \n        protected String createInstanceImpl() {\n            return array != null ? new String(array).trim() : \"\";\n        }\n        \n    }\n    \n    private static class DocumentTextBuilder extends InstanceBuilder<String> {\n        \n        private final ContentTextBuilder data;\n        \n        DocumentTextBuilder(Instance instance) {\n            super(instance);\n            \n            data = ContentTextBuilder.fromField(instance, \"data\");\n        }\n        \n        static DocumentTextBuilder fromField(Instance instance, String field) {\n            Object model = instance.getValueOfField(field);\n            if (!(model instanceof Instance)) return null;\n            if (!DetailsUtils.isSubclassOf((Instance)model, PlainDocument.class.getName())) return null;\n            return new DocumentTextBuilder((Instance)model);\n        }\n        \n        protected String createInstanceImpl() {\n            return data != null ? data.createInstance() : \"\";\n        }\n        \n    }\n    \n    private static abstract class JTextComponentBuilder<T extends JTextComponent> extends JComponentBuilder<T> {\n        \n        private final DocumentTextBuilder model;\n        private final boolean isEditable;\n        private final InsetsBuilder margin;\n        \n        JTextComponentBuilder(Instance instance) {\n            super(instance, false);\n            \n            model = DocumentTextBuilder.fromField(instance, \"model\");\n            \n            isEditable = DetailsUtils.getBooleanFieldValue(instance, \"editable\", false);\n            \n            margin = InsetsBuilder.fromField(instance, \"margin\");\n        }\n        \n        protected void setupInstance(T instance) {\n            super.setupInstance(instance);\n            \n            if (model != null) instance.setText(model.createInstance());\n            \n            instance.setEditable(isEditable);\n            \n            if (margin != null) instance.setMargin(margin.createInstance());\n        }\n        \n    }\n    \n    private static class JTextFieldBuilder extends JTextComponentBuilder<JTextField> {\n        \n        JTextFieldBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JTextField createInstanceImpl() {\n            return new JTextField();\n        }\n        \n    }\n    \n    private static class JTextAreaBuilder extends JTextComponentBuilder<JTextArea> {\n        \n        JTextAreaBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JTextArea createInstanceImpl() {\n            return new JTextArea();\n        }\n        \n    }\n    \n    private static class JEditorPaneBuilder extends JTextComponentBuilder<JEditorPane> {\n        \n        JEditorPaneBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JEditorPane createInstanceImpl() {\n            return new JEditorPane();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ui/Utils.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.KeyAdapter;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseMotionAdapter;\nimport java.lang.reflect.Method;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JViewport;\nimport javax.swing.Scrollable;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.model.BrowserUtils;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"Utils_NoDetails=<No details>\"\n})\nfinal class Utils {\n\n    static String getFontName(Instance instance) {\n        String name = getFieldString(instance, \"name\");                         // NOI18N\n        if (name == null) {\n            Instance font2DHandle = (Instance)instance.getValueOfField(\n                    \"font2DHandle\");                                            // NOI18N\n            if (font2DHandle != null) {\n                Instance font2D = (Instance)font2DHandle.getValueOfField(\n                        \"font2D\");                                              // NOI18N\n                if (font2D != null) {\n                    name = getFieldString(instance, \"fullName\");                // NOI18N\n                    if (name == null)\n                        name = getFieldString(instance, \"nativeFontName\");      // NOI18N\n                }\n            }\n        }\n        return name;\n    }\n    \n    static String getFieldString(Instance instance, String field) {\n        Object _s = instance.getValueOfField(field);\n        if (_s instanceof Instance) {\n            try {\n                Class<?> proxy = Class.forName(\"org.graalvm.visualvm.lib.jfluid.heap.HprofProxy\"); // NOI18N\n                Method method = proxy.getDeclaredMethod(\"getString\", Instance.class); // NOI18N\n                method.setAccessible(true);\n                return (String) method.invoke(proxy, _s);\n            } catch (Exception ex) {\n                Exceptions.printStackTrace(ex);\n            }\n        }\n        return null;\n    }\n    \n    static final class PlaceholderIcon implements Icon {\n        \n        private final int width;\n        private final int height;\n        \n        PlaceholderIcon(int width, int height) {\n            this.width = width;\n            this.height = height;\n        }\n        \n        public int getIconWidth() {\n            return width;\n        }\n\n        public int getIconHeight() {\n            return height;\n        }\n\n        public void paintIcon(Component c, Graphics g, int x, int y) {\n            g.setColor(Color.WHITE);\n            g.fillRect(x, y, width, height);\n            g.setColor(Color.BLACK);\n            g.drawLine(x, y, x + width - 1, y + height - 1);\n            g.drawLine(x, y + height - 1, x + width - 1, y);\n        }\n        \n    }\n    \n    static final class PlaceholderPanel extends JPanel {\n        \n        private static final Color LINE =\n                          UIManager.getLookAndFeel().getID().equals(\"Metal\") ?  // NOI18N\n                          UIManager.getColor(\"Button.darkShadow\") :             // NOI18N\n                          UIManager.getColor(\"Button.shadow\");                  // NOI18N\n        \n        private final JLabel label;\n        \n        PlaceholderPanel(String className) {\n            super(null);\n            \n            putClientProperty(\"className\", className);\n            \n            setOpaque(true);\n            setBorder(BorderFactory.createLineBorder(LINE));\n            \n            label = new JLabel(BrowserUtils.getSimpleType(className), JLabel.CENTER);\n            label.setOpaque(true);\n        }\n        \n        public void doLayout() {\n            Dimension s = getSize();\n            Dimension p = label.getPreferredSize();\n            \n            int x = (s.width - p.width) / 2;\n            int y = (s.height - p.height) / 2;\n            \n            label.setBounds(x, y, p.width, p.height);\n        }\n        \n        protected void paintComponent(Graphics g) {\n            super.paintComponent(g);\n            g.setColor(LINE);\n            g.drawLine(0, 0, getWidth() - 1, getHeight() - 1);\n            g.drawLine(0, getHeight() - 1, getWidth() - 1, 0);\n            \n            Point p = label.getLocation();\n            g.translate(p.x, p.y);\n            label.paint(g);\n            g.translate(-p.x, -p.y);\n        }\n        \n    }\n    \n    static final class JPopupMenuImpl extends JPopupMenu {\n        \n        public void setVisible(boolean visible) {}\n        public boolean isVisible() { return true; }\n\n        // Workarounds for best apperance of JPopupMenu preview\n        public Component add(Component comp) {\n            if (comp instanceof JComponent)\n                ((JComponent)comp).setOpaque(false);\n            return super.add(comp);\n        }\n        public void addNotify() {\n            super.addNotify();\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { repaint(); }\n            });\n        }\n        \n    }\n    \n    static abstract class InstanceBuilder<T> {\n\n        InstanceBuilder(Instance instance) {}\n\n        protected void setupInstance(T instance) {}\n\n        protected T createInstanceImpl() { return null; }\n        \n        final T createInstance() {\n            T instance = createInstanceImpl();\n            if (instance != null) try { setupInstance(instance); } catch (Throwable t) {} // #GH-110: setting up the instance may fail at any time\n            return instance;\n        }\n\n    }\n    \n    static abstract class View<T extends InstanceBuilder> extends DetailsProvider.View implements Scrollable {\n        \n        private static final int DASH_SIZE = 20;\n        \n        private final int margin;\n        private final boolean pattern;\n        private final boolean stretch;\n        \n        private Component component;\n        private JPanel glassPane;\n        \n        View(Instance instance) {\n            this(10, true, false, instance);\n        }\n        \n        View(int margin, boolean pattern, boolean stretch, Instance instance) {\n            super(instance);\n            this.margin = margin;\n            this.pattern = pattern;\n            this.stretch = stretch;\n        }\n        \n        protected T getBuilder(Instance instance) {\n            return null;\n        }\n        \n        protected Component getComponent(T builder) {\n            return null;\n        }\n        \n        protected void setupGlassPane(JPanel glassPane) {}\n        \n        protected final void computeView(Instance instance) {\n            final T builder = getBuilder(instance);\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    removeAll();\n                    component = builder == null ? null : getComponent(builder);\n                    if (component != null) {\n                        component.setVisible(true);\n                        if (stretch) {\n                            add(component, BorderLayout.CENTER);\n                        } else {\n                            glassPane = new JPanel(null) {\n                                public Point getToolTipLocation(MouseEvent event) {\n                                    Point p = event.getPoint();\n                                    p.translate(15, 15);\n                                    return p;\n                                }\n                            };\n                            glassPane.setOpaque(false);\n                            glassPane.addMouseListener(new MouseAdapter() {});\n                            glassPane.addMouseMotionListener(new MouseMotionAdapter() {});\n                            glassPane.addKeyListener(new KeyAdapter() {});\n                            setupGlassPane(glassPane);\n                            add(glassPane);\n                            \n                            setLayout(null);\n                            add(component);\n                        }\n                        if (component.getWidth() == 0 || component.getHeight() == 0)\n                            component.setSize(component.getPreferredSize());\n                        Dimension d = component.getSize();\n                        d.width += margin;\n                        d.height += margin;\n                        setPreferredSize(d);\n                        setBackground(UIUtils.getProfilerResultsBackground());\n                        setForeground(UIUtils.getDarker(getBackground()));\n                    } else {\n                        component = new JLabel(Bundle.Utils_NoDetails(), JLabel.CENTER);\n                        component.setEnabled(false);\n                        add(component, BorderLayout.CENTER);\n                    }\n                    revalidate();\n                    doLayout();\n                    repaint();\n                }\n            });\n        }\n        \n        public void doLayout() {\n            if (getLayout() != null) {\n                super.doLayout();\n            } else {\n                Dimension size = getSize();\n                Dimension comp = component.getSize();\n                \n                int x = comp.width >= size.width ? 0 :\n                        (size.width - comp.width) / 2;\n                int y = comp.height >= size.height ? 0 :\n                        (size.height - comp.height) / 2;\n                \n                component.move(x, y); // required to correctly setup JPopupMenu\n                \n                glassPane.setBounds(component.getBounds());\n            }\n        }\n        \n        protected void paintComponent(Graphics g) {\n            if (!pattern || component == null) {\n                super.paintComponent(g);\n            } else {\n                int x = 0;\n                int y = 0;\n                int w = getWidth();\n                int h = getHeight();\n                \n                while (y <= h) {\n                    boolean flag = (y / DASH_SIZE) % 2 == 0;\n                    while (x <= w) {\n                        g.setColor(flag ? getBackground() : getForeground());\n                        g.fillRect(x, y, DASH_SIZE, DASH_SIZE);\n                        x += DASH_SIZE;\n                        flag = !flag;\n                    }\n                    x = 0;\n                    y += DASH_SIZE;\n                }\n            }\n        }\n        \n        public Dimension getPreferredScrollableViewportSize() {\n            return null;\n        }\n\n        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {\n            // Scroll almost one screen\n            Container parent = getParent();\n            if ((parent == null) || !(parent instanceof JViewport)) return 50;\n            return (int)(((JViewport)parent).getHeight() * 0.95f);\n        }\n\n        public boolean getScrollableTracksViewportHeight() {\n            // Allow dynamic vertical enlarging of the panel but request the vertical scrollbar when needed\n            Container parent = getParent();\n            if ((parent == null) || !(parent instanceof JViewport)) return false;\n            return getPreferredSize().height < ((JViewport)parent).getHeight();\n        }\n\n        public boolean getScrollableTracksViewportWidth() {\n            // Allow dynamic horizontal enlarging of the panel but request the vertical scrollbar when needed\n            Container parent = getParent();\n            if ((parent == null) || !(parent instanceof JViewport)) return false;\n            return getPreferredSize().width < ((JViewport)parent).getWidth();\n        }\n\n        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {\n            return 20;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/jdk/ui/WindowBuilders.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui;\n\nimport java.awt.Component;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.Frame;\nimport java.awt.Image;\nimport java.beans.PropertyVetoException;\nimport java.util.List;\nimport javax.swing.ImageIcon;\nimport javax.swing.JDesktopPane;\nimport javax.swing.JDialog;\nimport javax.swing.JFrame;\nimport javax.swing.JInternalFrame;\nimport javax.swing.JLayeredPane;\nimport javax.swing.JPanel;\nimport javax.swing.JRootPane;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.image.ImageBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.BaseBuilders.IconBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.ComponentBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.ContainerBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.jdk.ui.ComponentBuilders.JComponentBuilder;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class WindowBuilders {\n\n    // Make sure subclasses are listed before base class if using isSubclassOf\n    static ComponentBuilder<? extends Component> getBuilder(Instance instance) {\n        if (DetailsUtils.isSubclassOf(instance, JRootPane.class.getName())) {\n            return new JRootPaneBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JDesktopPane.class.getName())) {\n            return new JDesktopPaneBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JLayeredPane.class.getName())) {\n            return new JLayeredPaneBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, Frame.class.getName())) {\n            return new FrameBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, Dialog.class.getName())) {\n            return new DialogBuilder(instance);\n        } else if (DetailsUtils.isSubclassOf(instance, JInternalFrame.class.getName())) {\n            return new JInternalFrameBuilder(instance);\n        }\n        return null;\n    }\n    \n    \n    private static class JRootPaneBuilder extends JComponentBuilder<JRootPane> {\n        \n        private final int windowDecorationStyle;\n        \n        JRootPaneBuilder(Instance instance) {\n            super(instance);\n            \n            windowDecorationStyle = DetailsUtils.getIntFieldValue(instance, \"windowDecorationStyle\", 0);\n        }\n        \n        static JRootPaneBuilder fromField(Instance instance, String field) {\n            Object insets = instance.getValueOfField(field);\n            if (!(insets instanceof Instance)) return null;\n            return new JRootPaneBuilder((Instance)insets);\n        }\n        \n        protected void setupInstance(JRootPane instance) {\n            super.setupInstance(instance);\n            \n            instance.setWindowDecorationStyle(windowDecorationStyle);\n//            instance.setPreferredSize(instance.getSize());\n        }\n        \n        protected JRootPane createInstanceImpl() {\n            return new JRootPane();\n        }\n        \n    }\n    \n    private static class JLayeredPaneBuilder extends JComponentBuilder<JLayeredPane> {\n        \n        JLayeredPaneBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JLayeredPane createInstanceImpl() {\n            return new JLayeredPane();\n        }\n        \n    }\n    \n    private static class JDesktopPaneBuilder extends JLayeredPaneBuilder {\n        \n        JDesktopPaneBuilder(Instance instance) {\n            super(instance);\n        }\n        \n        protected JLayeredPane createInstanceImpl() {\n            return new JDesktopPane();\n        }\n        \n    }\n    \n    private static class FrameBuilder extends ContainerBuilder<Frame> {\n        \n        private final String title;\n        private final boolean undecorated;\n        private final Image image;\n        \n        FrameBuilder(Instance instance) {\n            super(instance);\n            \n            title = Utils.getFieldString(instance, \"title\");\n            undecorated = DetailsUtils.getBooleanFieldValue(instance, \"undecorated\", false);\n            \n            Image _image = null;\n            Object icons = instance.getValueOfField(\"icons\");\n            if (icons instanceof Instance) {\n                Instance i = (Instance)icons;\n                if (DetailsUtils.getIntFieldValue(i, \"size\", 0) > 0) {\n                    Object elementData = i.getValueOfField(\"elementData\");\n                    if (elementData instanceof ObjectArrayInstance) {\n                        Instance o = ((ObjectArrayInstance)elementData).getValues().get(0);\n                        _image = o != null ? ImageBuilder.buildImage(o) : null;\n                    }\n                }\n            }\n            image = _image;\n        }\n        \n        protected void setupInstance(Frame instance) {\n            super.setupInstance(instance);\n            \n            instance.setUndecorated(undecorated);\n            if (image != null) instance.setIconImage(image);\n        }\n        \n        protected Frame createInstanceImpl() {\n            return new JFrame(title) {\n                protected void frameInit() {}\n                public void addNotify() {}\n                public void remove(Component comp) {}\n                public void setVisible(boolean b) {}\n            };\n        }\n        \n        protected Component createPresenterImpl(Frame instance) {\n            if (instance.isUndecorated()) {\n                JPanel presenter = new JPanel(null);\n                presenter.setOpaque(true);\n                Dimension dim = null;\n                for (Component c : instance.getComponents()) {\n                    presenter.add(c);\n                    Dimension s = c.getSize();\n                    if (dim == null) {\n                        dim = s;\n                    } else {\n                        dim.width = Math.max(dim.width, s.width);\n                        dim.height = Math.max(dim.height, s.height);\n                    }\n                }\n                if (dim != null) presenter.setSize(dim);\n                return presenter;\n            } else {\n                JInternalFrame presenter = new JInternalFrame(instance.getTitle());\n                Image img = instance.getIconImage();\n                if (img != null) presenter.setFrameIcon(new ImageIcon(img));\n                for (Component c : instance.getComponents()) presenter.add(c);\n                presenter.pack();\n                return presenter;\n            }\n        }\n        \n    }\n    \n    private static class DialogBuilder extends ContainerBuilder<Dialog> {\n        \n        private final String title;\n        private final boolean undecorated;\n        private final Image image;\n        \n        DialogBuilder(Instance instance) {\n            super(instance);\n            \n            title = Utils.getFieldString(instance, \"title\");\n            undecorated = DetailsUtils.getBooleanFieldValue(instance, \"undecorated\", false);\n            \n            Image _image = null;\n            Object icons = instance.getValueOfField(\"icons\");\n            if (icons == null) {\n                Object parent = instance.getValueOfField(\"parent\");\n                while (parent instanceof Instance) {\n                    icons = ((Instance)parent).getValueOfField(\"icons\");\n                    if (icons instanceof Instance) break;\n                    parent = ((Instance)parent).getValueOfField(\"parent\");\n                }\n            }\n            if (icons instanceof Instance) {\n                Instance i = (Instance)icons;\n                if (DetailsUtils.getIntFieldValue(i, \"size\", 0) > 0) {\n                    Object elementData = i.getValueOfField(\"elementData\");\n                    if (elementData instanceof ObjectArrayInstance) {\n                        Instance o = ((ObjectArrayInstance)elementData).getValues().get(0);\n                        _image = o != null ? ImageBuilder.buildImage(o) : null;\n                    }\n                }\n            }\n            image = _image;\n        }\n        \n        protected void setupInstance(Dialog instance) {\n            super.setupInstance(instance);\n            \n            instance.setUndecorated(undecorated);\n            if (image != null) instance.setIconImage(image);\n        }\n        \n        protected Dialog createInstanceImpl() {\n            return new JDialog((Frame)null, title) {\n                protected void dialogInit() {}\n                public void addNotify() {}\n                public void remove(Component comp) {}\n                public void setVisible(boolean b) {}\n            };\n        }\n        \n        protected Component createPresenterImpl(Dialog instance) {\n            if (instance.isUndecorated()) {\n                JPanel presenter = new JPanel(null);\n                presenter.setOpaque(true);\n                Dimension dim = null;\n                for (Component c : instance.getComponents()) {\n                    presenter.add(c);\n                    Dimension s = c.getSize();\n                    if (dim == null) {\n                        dim = s;\n                    } else {\n                        dim.width = Math.max(dim.width, s.width);\n                        dim.height = Math.max(dim.height, s.height);\n                    }\n                }\n                if (dim != null) presenter.setSize(dim);\n                return presenter;\n            } else {\n                JInternalFrame presenter = new JInternalFrame(instance.getTitle());\n                List<Image> images = instance.getIconImages();\n                Image img = images.isEmpty() ? null : images.get(0);\n                if (img != null) presenter.setFrameIcon(new ImageIcon(img));\n                for (Component c : instance.getComponents()) presenter.add(c);\n                presenter.pack();\n                return presenter;\n            }\n        }\n        \n    }\n    \n    private static class JInternalFrameBuilder extends JComponentBuilder<JInternalFrame> {\n        \n        private final JRootPaneBuilder _rootPane;\n        private final boolean closable;\n        private final boolean _isClosed;\n        private final boolean maximizable;\n        private final boolean _isMaximum;\n        private final boolean iconable;\n        private final boolean _isIcon;\n        private final boolean resizable;\n        private final boolean _isSelected;\n        private final IconBuilder frameIcon;\n        private final String  title;\n        \n        JInternalFrameBuilder(Instance instance) {\n            super(instance, false);\n            \n            _rootPane = JRootPaneBuilder.fromField(instance, \"rootPane\");\n            closable = DetailsUtils.getBooleanFieldValue(instance, \"closable\", false);\n            _isClosed = DetailsUtils.getBooleanFieldValue(instance, \"isClosed\", false);\n            maximizable = DetailsUtils.getBooleanFieldValue(instance, \"maximizable\", false);\n            _isMaximum = DetailsUtils.getBooleanFieldValue(instance, \"isMaximum\", false);\n            iconable = DetailsUtils.getBooleanFieldValue(instance, \"iconable\", false);\n            _isIcon = DetailsUtils.getBooleanFieldValue(instance, \"isIcon\", false);\n            resizable = DetailsUtils.getBooleanFieldValue(instance, \"resizable\", false);\n            _isSelected = DetailsUtils.getBooleanFieldValue(instance, \"isSelected\", false);\n            frameIcon = IconBuilder.fromField(instance, \"frameIcon\");\n            title = Utils.getFieldString(instance, \"title\");\n        }\n        \n        protected void setupInstance(JInternalFrame instance) {\n            super.setupInstance(instance);\n            \n            if (frameIcon != null) instance.setFrameIcon(frameIcon.createInstance());\n        }\n        \n        protected JInternalFrame createInstanceImpl() {\n            JInternalFrame frame = new JInternalFrame(title, resizable, closable, maximizable, iconable) {\n                protected JRootPane createRootPane() {\n                    return _rootPane == null ? null : _rootPane.createInstance();\n                }\n                public void addNotify() {\n                    try {\n                        // Doesn't seem to work correctly\n                        setClosed(_isClosed);\n                        setMaximum(_isMaximum);\n                        setIcon(_isIcon);\n                        setSelected(_isSelected);\n                    } catch (PropertyVetoException ex) {}\n                }\n            };\n            return frame;\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/netbeans/EditorDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.netbeans;\n\nimport java.util.AbstractList;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.Value;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic class EditorDetailsProvider  extends DetailsProvider.Basic {\n    private static final String CHAR_CONTENT = \"org.netbeans.modules.editor.lib2.document.CharContent\"; // NOI18N\n\n    public EditorDetailsProvider() {\n        super(CHAR_CONTENT);\n    }\n\n    @Override\n    public String getDetailsString(String className, Instance instance) {\n        if (CHAR_CONTENT.equals(className)) {\n            int gapStart = DetailsUtils.getIntFieldValue(instance, \"gapStart\", -1);     // NOI18N\n            int gapLength = DetailsUtils.getIntFieldValue(instance, \"gapLength\", -1);       // NOI18N\n            PrimitiveArrayInstance buffer = (PrimitiveArrayInstance)instance.getValueOfField(\"buffer\"); // NOI18N\n\n            if (gapStart >= 0 && gapLength >= 0 && buffer != null) {\n                CharArrayWithGap array = new CharArrayWithGap(buffer, gapStart, gapLength);\n\n                return DetailsUtils.getPrimitiveArrayString(array, 0, array.getLength(), \"\", \"...\");    // NOI18N\n            }\n        }\n        return null;\n    }\n\n\n    private static class CharArrayWithGap implements PrimitiveArrayInstance {\n\n        PrimitiveArrayInstance buffer;\n        int gapStart;\n        int gapLength;\n\n        private CharArrayWithGap(PrimitiveArrayInstance buf, int start, int length) {\n            buffer = buf;\n            gapStart = start;\n            gapLength = length;\n        }\n\n        @Override\n        public int getLength() {\n            return buffer.getLength() - gapLength;\n        }\n\n        @Override\n        public List<String> getValues() {\n            final List<String> origValues = buffer.getValues();\n\n            return new AbstractList<String>() {\n\n                @Override\n                public String get(int index) {\n                    return origValues.get(rawOffset(index));\n                }\n\n                @Override\n                public int size() {\n                    return getLength();\n                }\n            };\n        }\n\n        private int rawOffset(int index) {\n            return (index < gapStart) ? index : (index + gapLength);\n        }\n\n        @Override\n        public List<FieldValue> getFieldValues() {\n            throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n        }\n\n        @Override\n        public boolean isGCRoot() {\n                throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n        }\n\n        @Override\n        public long getInstanceId() {\n            throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n        }\n\n        @Override\n        public int getInstanceNumber() {\n            throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n        }\n\n        @Override\n        public JavaClass getJavaClass() {\n            throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n        }\n\n        @Override\n        public Instance getNearestGCRootPointer() {\n            throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n        }\n\n        @Override\n        public long getReachableSize() {\n            throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n        }\n\n        @Override\n        public List<Value> getReferences() {\n            throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n        }\n\n        @Override\n        public long getRetainedSize() {\n            throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n        }\n\n        @Override\n        public long getSize() {\n            throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n        }\n\n        @Override\n        public List<FieldValue> getStaticFieldValues() {\n            throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n        }\n\n        @Override\n        public Object getValueOfField(String name) {\n            throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/netbeans/JavaDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.netbeans;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic class JavaDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String FO_INDEXABLE = \"org.netbeans.modules.parsing.impl.indexing.FileObjectIndexable\"; // NOI18N\n    private static final String INDEXABLE = \"org.netbeans.modules.parsing.spi.indexing.Indexable\"; // NOI18N\n    private static final String CLASSPATH_ENTRY = \"org.netbeans.api.java.classpath.ClassPath$Entry\";    // NOI18N\n\n    private long lastHeapId;\n    private String lastSeparator;\n\n    public JavaDetailsProvider() {\n        super(FO_INDEXABLE,INDEXABLE,CLASSPATH_ENTRY);\n    }\n\n    @Override\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case FO_INDEXABLE: {\n                String root = DetailsUtils.getInstanceFieldString(instance, \"root\"); // NOI18N\n                String relpath = DetailsUtils.getInstanceFieldString(instance, \"relativePath\"); // NOI18N\n                if (root != null && relpath != null) {\n                    Heap heap = instance.getJavaClass().getHeap();\n                    return root.concat(getFileSeparator(heap)).concat(relpath);\n                }\n                break;\n            }\n            case INDEXABLE:\n                return DetailsUtils.getInstanceFieldString(instance, \"delegate\"); // NOI18N\n            case CLASSPATH_ENTRY:\n                return DetailsUtils.getInstanceFieldString(instance, \"url\");  // NOI18N\n            default:\n                break;\n        }\n        return null;\n    }\n\n    private String getFileSeparator(Heap heap) {\n        if (lastHeapId != System.identityHashCode(heap)) {\n            lastSeparator = heap.getSystemProperties().getProperty(\"file.separator\",\"/\"); // NOI18N\n            lastHeapId = System.identityHashCode(heap);\n        }\n        return lastSeparator;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/netbeans/JavacDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.netbeans;\n\nimport java.io.UnsupportedEncodingException;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.Exceptions;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic class JavacDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String SHAREDNAMETABLE_NAMEIMPL_MASK = \"com.sun.tools.javac.util.SharedNameTable$NameImpl\";                // NOI18N\n    private static final String NAME_MASK = \"com.sun.tools.javac.util.Name\";    // NOI18N\n    private static final String SYMBOL_MASK = \"com.sun.tools.javac.code.Symbol+\"; // NOI18N\n    private static final String CLASS_SYM_MASK = \"com.sun.tools.javac.code.Symbol$ClassSymbol\"; // NOI18N\n    private static final String PACKAGE_SYM_MASK = \"com.sun.tools.javac.code.Symbol$PackageSymbol\"; // NOI18N\n\n    public JavacDetailsProvider() {\n        super(SHAREDNAMETABLE_NAMEIMPL_MASK, NAME_MASK, SYMBOL_MASK, CLASS_SYM_MASK, PACKAGE_SYM_MASK);\n    }\n\n    @Override\n    public String getDetailsString(String className, Instance instance) {\n        switch (className) {\n            case SHAREDNAMETABLE_NAMEIMPL_MASK:\n                return getName(instance, \"length\", \"index\", \"table\", \"bytes\");      // NOI18N\n            case NAME_MASK:\n                return getName(instance, \"len\", \"index\", \"table\", \"names\");         // NOI18N\n            case SYMBOL_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"name\");  // NI18N\n            case CLASS_SYM_MASK: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\");  // NI18N\n\n                if (name == null || name.isEmpty()) {\n                    return DetailsUtils.getInstanceFieldString(instance, \"flatname\");  // NI18N\n                } else {\n                    return DetailsUtils.getInstanceFieldString(instance, \"fullname\");  // NI18N\n                }\n            }\n            case PACKAGE_SYM_MASK:\n                return DetailsUtils.getInstanceFieldString(instance, \"fullname\");  // NI18N\n            default:\n                break;\n        }\n        return null;\n    }\n\n    private String getName(Instance instance, String lenField, String indexField, String tableField, String bytesField) {\n        Integer length = (Integer) instance.getValueOfField(lenField);\n        Integer index = (Integer) instance.getValueOfField(indexField);\n        Instance table = (Instance) instance.getValueOfField(tableField);\n        if (length != null && index != null && table != null) {\n            PrimitiveArrayInstance bytes = (PrimitiveArrayInstance) table.getValueOfField(bytesField);\n            List<String> elements = bytes.getValues();\n            byte[] data = new byte[length];\n            for (int i = 0; i < length; i++) {\n                String el = elements.get(index+i);\n                data[i] = Byte.parseByte(el);\n            }\n            try {\n                return new String(data, \"UTF-8\"); // NOI18N\n            } catch (UnsupportedEncodingException ex) {\n                Exceptions.printStackTrace(ex);\n            }\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/netbeans/PlatformDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.netbeans;\n\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic class PlatformDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String STANDARD_MODULE = \"org.netbeans.Module+\"; // NOI18N\n    private static final String MODULE_DATA = \"org.netbeans.ModuleData+\"; // NOI18N\n    private static final String DEPENDENCY = \"org.openide.modules.Dependency\"; // NOI18N\n    private static final String SPECIFICATION_VERSION = \"org.openide.modules.SpecificationVersion\"; // NOI18N\n    private static final String ABSTRACT_NODE = \"org.openide.nodes.AbstractNode+\"; // NOI18N\n    private static final String MULTI_FILE_ENTRY = \"org.openide.loaders.MultiDataObject$Entry+\"; // NOI18N\n    private static final String DATA_OBJECT = \"org.openide.loaders.DataObject+\"; // NOI18N\n    private static final String JAR_FILESYSTEM = \"org.openide.filesystems.JarFileSystem+\"; // NOI18N\n    private static final String FILE_OBJ = \"org.netbeans.modules.masterfs.filebasedfs.fileobjects.FileObj+\"; // NOI18N\n    private static final String FOLDER_OBJ = \"org.netbeans.modules.masterfs.filebasedfs.fileobjects.FolderObj+\"; // NOI18N\n    private static final String FILE_NAME = \"org.netbeans.modules.masterfs.filebasedfs.naming.FileName+\"; // NOI18N\n    private static final String FOLDER_NAME = \"org.netbeans.modules.masterfs.filebasedfs.naming.FolderName+\"; // NOI18N\n    private static final String ABSTRACT_FOLDER = \"org.openide.filesystems.AbstractFolder+\"; // NOI18N\n    private static final String BFS_BASE = \"org.netbeans.core.startup.layers.BinaryFS$BFSBase+\"; // NOI18N\n    private static final String FIXED_0_7 = \"org.openide.util.CharSequences$Fixed_0_7\"; // NOI18N\n    private static final String FIXED_8_15 = \"org.openide.util.CharSequences$Fixed_8_15\"; // NOI18N\n    private static final String FIXED_16_23 = \"org.openide.util.CharSequences$Fixed_16_23\"; // NOI18N\n    private static final String FIXED_1_10 = \"org.openide.util.CharSequences$Fixed6Bit_1_10\"; // NOI18N\n    private static final String FIXED_11_20 = \"org.openide.util.CharSequences$Fixed6Bit_11_20\"; // NOI18N\n    private static final String FIXED_21_30 = \"org.openide.util.CharSequences$Fixed6Bit_21_30\"; // NOI18N\n    private static final String BYTE_BASED_SEQUENCE = \"org.openide.util.CharSequences$ByteBasedSequence\"; // NOI18N\n    private static final String CHAR_BASED_SEQUENCE = \"org.openide.util.CharSequences$CharBasedSequence\"; // NOI18N\n    private static final String REQUEST_PROCESSOR = \"org.openide.util.RequestProcessor\";     // NOI18N\n    \n    LinkedHashMap<Long, String> cache = new LinkedHashMap<Long, String>(10000) {\n\n        @Override\n        protected boolean removeEldestEntry(Map.Entry<Long, String> eldest) {\n            return size() > 10000;\n        }\n    };\n    \n    public PlatformDetailsProvider() {\n        super(STANDARD_MODULE,MODULE_DATA,DEPENDENCY,SPECIFICATION_VERSION,\n              ABSTRACT_NODE,MULTI_FILE_ENTRY,DATA_OBJECT,JAR_FILESYSTEM,\n              FILE_OBJ,FOLDER_OBJ, FILE_NAME,FOLDER_NAME,ABSTRACT_FOLDER,\n              BFS_BASE,\n              FIXED_0_7,FIXED_8_15,FIXED_16_23,FIXED_1_10,FIXED_11_20,\n              FIXED_21_30,BYTE_BASED_SEQUENCE,CHAR_BASED_SEQUENCE,\n              REQUEST_PROCESSOR);\n    }\n\n    @Override\n    public String getDetailsString(String className, Instance instance) {\n        Long id = getUniqueInstanceId(instance);\n        String s = cache.get(id);\n        if (s != null) {\n            return s;\n        }\n        s = getDetailsStringImpl(className, instance);\n        cache.put(id, s);\n        return s;\n    }\n\n    private String getDetailsStringImpl(String className, Instance instance) {\n        switch (className) {\n            case STANDARD_MODULE: {\n                String codeName = DetailsUtils.getInstanceFieldString(instance, \"codeName\");     // NOI18N\n                if (codeName != null) {\n                    return codeName;\n                }\n                return DetailsUtils.getInstanceFieldString(instance, \"data\");     // NOI18N\n            }\n            case DEPENDENCY: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"name\");     // NOI18N\n                String version = DetailsUtils.getInstanceFieldString(instance, \"version\");     // NOI18N\n                int type = DetailsUtils.getIntFieldValue(instance, \"type\", -1); // NOI18N\n                int comparison = DetailsUtils.getIntFieldValue(instance, \"comparison\", -1); // NOI18N\n                return DependencyResolver.toString(name, version, type, comparison);\n            }\n            case SPECIFICATION_VERSION: {\n                PrimitiveArrayInstance digits = (PrimitiveArrayInstance) instance.getValueOfField(\"digits\"); // NOI18N\n                if (digits != null) {\n                    StringBuilder specVersion = new StringBuilder();\n\n                    for (Object d : digits.getValues()) {\n                        specVersion.append(d);\n                        specVersion.append('.');\n                    }\n                    return specVersion.substring(0, specVersion.length()-1);\n                }\n                break;\n            }\n            case MODULE_DATA: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"codeName\");     // NOI18N\n                String version = DetailsUtils.getInstanceFieldString(instance, \"specVers\");     // NOI18N\n                String implVer = DetailsUtils.getInstanceFieldString(instance, \"implVersion\");       // NOI18N\n                return String.format(\"%s [%s %s]\", name, version, implVer);\n            }\n            case ABSTRACT_NODE: {\n                String name = DetailsUtils.getInstanceFieldString(instance, \"displayName\"); // NOI18N\n\n                if (name == null) {\n                    name = DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n                }\n                if (name == null || name.isEmpty()) {\n                    name = DetailsUtils.getInstanceFieldString(instance, \"shortDescription\"); // NOI18N\n                }\n                return name;\n            }\n            case JAR_FILESYSTEM:\n                return DetailsUtils.getInstanceFieldString(instance, \"foRoot\"); // NOI18N\n            case MULTI_FILE_ENTRY:\n                return DetailsUtils.getInstanceFieldString(instance, \"file\"); // NOI18N\n            case DATA_OBJECT:\n                return DetailsUtils.getInstanceFieldString(instance, \"primary\"); // NOI18N\n            case FILE_OBJ:\n                return DetailsUtils.getInstanceFieldString(instance, \"fileName\"); // NOI18N\n            case FOLDER_OBJ:\n                return DetailsUtils.getInstanceFieldString(instance, \"fileName\"); // NOI18N\n            case FILE_NAME:\n            case FOLDER_NAME:\n            case ABSTRACT_FOLDER:\n            case BFS_BASE: {\n                String nameString = DetailsUtils.getInstanceFieldString(instance, \"name\"); // NOI18N\n\n                if (nameString != null) {\n                    String parentDetail = DetailsUtils.getInstanceFieldString(instance, \"parent\"); // NOI18N\n                    if (parentDetail != null) {\n                        String sep;\n\n                        if (FILE_NAME.equals(className) || FOLDER_NAME.equals(className)) {\n                            // FileObject on the disk - find correct file seperator\n                            Heap heap = instance.getJavaClass().getHeap();\n                            sep = getFileSeparator(heap);\n                            if (parentDetail.endsWith(sep)) {\n                                // do not duplicate separator\n                                sep = \"\";\n                            }\n                        } else {\n                            sep = \"/\";\n                        }\n                        nameString = parentDetail.concat(sep).concat(nameString);\n                    }\n                }\n                return nameString;\n            }\n            case FIXED_0_7: {\n                Integer i1 = (Integer) instance.getValueOfField(\"i1\"); // NOI18N\n                Integer i2 = (Integer) instance.getValueOfField(\"i2\"); // NOI18N\n                if (i1 != null && i2 != null) {\n                    return new Fixed_0_7(i1, i2).toString();\n                }\n                break;\n            }\n            case FIXED_8_15: {\n                Integer i1 = (Integer) instance.getValueOfField(\"i1\"); // NOI18N\n                Integer i2 = (Integer) instance.getValueOfField(\"i2\"); // NOI18N\n                Integer i3 = (Integer) instance.getValueOfField(\"i3\"); // NOI18N\n                Integer i4 = (Integer) instance.getValueOfField(\"i4\"); // NOI18N\n                if (i1 != null && i2 != null && i3 != null && i4 != null) {\n                    return new Fixed_8_15(i1, i2, i3, i4).toString();\n                }\n                break;\n            }\n            case FIXED_16_23: {\n                Long i1 = (Long) instance.getValueOfField(\"i1\"); // NOI18N\n                Long i2 = (Long) instance.getValueOfField(\"i2\"); // NOI18N\n                Long i3 = (Long) instance.getValueOfField(\"i3\"); // NOI18N\n                if (i1 != null && i2 != null && i3 != null) {\n                    return new Fixed_16_23(i1, i2, i3).toString();\n                }\n                break;\n            }\n            case FIXED_1_10:{\n                Long i1 = (Long) instance.getValueOfField(\"i\"); // NOI18N\n                if (i1 != null) {\n                    return new Fixed6Bit_1_10(i1).toString();\n                }\n                break;\n            }\n            case FIXED_11_20:{\n                Long i1 = (Long) instance.getValueOfField(\"i1\"); // NOI18N\n                Long i2 = (Long) instance.getValueOfField(\"i2\"); // NOI18N\n                if (i1 != null && i2 != null) {\n                    return new Fixed6Bit_11_20(i1, i2).toString();\n                }\n                break;\n            }\n            case FIXED_21_30:{\n                Long i1 = (Long) instance.getValueOfField(\"i1\"); // NOI18N\n                Long i2 = (Long) instance.getValueOfField(\"i2\"); // NOI18N\n                Long i3 = (Long) instance.getValueOfField(\"i3\"); // NOI18N\n                if (i1 != null && i2 != null && i3 != null) {\n                    return new Fixed6Bit_21_30(i1, i2, i3).toString();\n                }\n                break;\n            }\n            case BYTE_BASED_SEQUENCE: {\n                Object value = instance.getValueOfField(\"value\");  // NOI18N\n                if (value instanceof PrimitiveArrayInstance) {\n                    PrimitiveArrayInstance bytesArr = (PrimitiveArrayInstance) value;\n                    byte[] bytes = new byte[bytesArr.getLength()];\n                    int i = 0;\n\n                    for (String b : bytesArr.getValues()) {\n                        bytes[i++] = Byte.valueOf(b);\n                    }\n                    return new String(bytes);\n                }\n                break;\n            }\n            case CHAR_BASED_SEQUENCE:\n                return DetailsUtils.getInstanceFieldString(instance, \"value\");    // NOI18N\n            case REQUEST_PROCESSOR:\n                return DetailsUtils.getInstanceFieldString(instance, \"name\");     // NOI18N\n            default:\n                break;\n        }\n        return null;\n    }\n    \n    private Long getUniqueInstanceId(Instance instance) {\n        Heap heap = instance.getJavaClass().getHeap();\n        long id = instance.getInstanceId()^System.identityHashCode(heap);\n        \n        return new Long(id);\n    }\n\n    private String getFileSeparator(Heap heap) {\n        Long id = new Long(System.identityHashCode(heap));\n        String sep = cache.get(id);\n        if (sep == null) {\n            sep = heap.getSystemProperties().getProperty(\"file.separator\",\"/\"); // NOI18N\n            cache.put(id,sep);\n        }\n        return sep;\n    }\n\n    //<editor-fold defaultstate=\"collapsed\" desc=\"Private Classes\">\n\n    /**\n     * compact char sequence implementation for strings in range 0-7 characters\n     * 8 + 2*4 = 16 bytes for all strings vs String impl occupying\n     */\n    private static final class Fixed_0_7 implements CompactCharSequence, Comparable<CharSequence> {\n\n        private final int i1;\n        private final int i2;\n\n        private Fixed_0_7(int a1, int a2) {\n            i1 = a1;\n            i2 = a2;\n        }\n\n        @SuppressWarnings(\"fallthrough\")\n        private Fixed_0_7(byte[] b, int n) {\n            int a1 = n;\n            int a2 = 0;\n            switch (n) {\n                case 7:\n                    a2 += (b[6] & 0xFF) << 24;\n                case 6:\n                    a2 += (b[5] & 0xFF) << 16;\n                case 5:\n                    a2 += (b[4] & 0xFF) << 8;\n                case 4:\n                    a2 += b[3] & 0xFF;\n                case 3:\n                    a1 += (b[2] & 0xFF) << 24;\n                case 2:\n                    a1 += (b[1] & 0xFF) << 16;\n                case 1:\n                    a1 += (b[0] & 0xFF) << 8;\n                case 0:\n                    break;\n                default:\n                    throw new IllegalArgumentException();\n            }\n            i1 = a1;\n            i2 = a2;\n        }\n\n        @Override\n        public int length() {\n            return i1 & 0xFF;\n        }\n\n        @Override\n        public char charAt(int index) {\n            int r = 0;\n            switch (index) {\n                case 0:\n                    r = (i1 & 0xFF00) >> 8;\n                    break;\n                case 1:\n                    r = (i1 & 0xFF0000) >> 16;\n                    break;\n                case 2:\n                    r = (i1 >> 24) & 0xFF;\n                    break;\n                case 3:\n                    r = i2 & 0xFF;\n                    break;\n                case 4:\n                    r = (i2 & 0xFF00) >> 8;\n                    break;\n                case 5:\n                    r = (i2 & 0xFF0000) >> 16;\n                    break;\n                case 6:\n                    r = (i2 >> 24) & 0xFF;\n                    break;\n            }\n            return (char) r;\n        }\n\n        @Override\n        public String toString() {\n            int n = length();\n            char[] r = new char[n];\n            for (int i = 0; i < n; i++) {\n                r[i] = charAt(i);\n            }\n            return new String(r);\n        }\n\n        @Override\n        public boolean equals(Object object) {\n            if (this == object) {\n                return true;\n            }\n            if (object instanceof Fixed_0_7) {\n                Fixed_0_7 otherString = (Fixed_0_7) object;\n                return i1 == otherString.i1 && i2 == otherString.i2;\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            int hash = 0;\n            for (int i = 0; i < length(); i++) {\n                hash = 31 * hash + charAt(i);\n            }\n            return hash;\n            //            return (i1 >> 4) + (i1 >> 8) + (i2 << 5) - i2;\n        }\n\n        @Override\n        public CharSequence subSequence(int start, int end) {\n            return CharSequences.create(toString().substring(start, end));\n        }\n\n        @Override\n        public int compareTo(CharSequence o) {\n            return Comparator.compare(this, o);\n        }\n    }\n\n    private static final long[] encodeTable = new long[] {\n           -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n           -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n           -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1,\n            0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,\n           -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\n           25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, 63,\n           -1, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,\n           51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1\n    };\n\n    private static final char[] decodeTable = new char[] {\n          '0','1','2','3','4','5','6','7','8','9',\n              'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',\n          'P','Q','R','S','T','U','V','W','X','Y','Z',\n              'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',\n          'p','q','r','s','t','u','v','w','x','y','z',\n                                                                  '.',     // for 'file.ext' names\n                                                                      '_'\n    };\n\n    private static boolean is6BitChar(int d) {\n        return d < 128 && encodeTable[d] >= 0;\n    }\n\n    private static long encode6BitChar(int d) {\n        return encodeTable[d];\n    }\n\n    private static char decode6BitChar(int d) {\n        return decodeTable[d];\n    }\n\n    private static final class Fixed6Bit_1_10 implements CompactCharSequence, Comparable<CharSequence> {\n\n        // Length is in lower 4bits\n        // then 6bits per symbol\n        private final long i;\n\n        private Fixed6Bit_1_10(long a1) {\n            i = a1;\n        }\n\n        @SuppressWarnings(\"fallthrough\")\n        private Fixed6Bit_1_10(byte[] b, int n) {\n            long a = n;\n            switch (n) {\n                case 10:\n                    a |= encode6BitChar(b[9]) << 58;\n                case 9:\n                    a |= encode6BitChar(b[8]) << 52;\n                case 8:\n                    a |= encode6BitChar(b[7]) << 46;\n                case 7:\n                    a |= encode6BitChar(b[6]) << 40;\n                case 6:\n                    a |= encode6BitChar(b[5]) << 34;\n                case 5:\n                    a |= encode6BitChar(b[4]) << 28;\n                case 4:\n                    a |= encode6BitChar(b[3]) << 22;\n                case 3:\n                    a |= encode6BitChar(b[2]) << 16;\n                case 2:\n                    a |= encode6BitChar(b[1]) << 10;\n                case 1:\n                    a |= encode6BitChar(b[0]) << 4;\n                    break;\n                case 0:\n                default:\n                    throw new IllegalArgumentException();\n            }\n            i = a;\n        }\n\n        @Override\n        public int length() {\n            return (int) (i & 0x0FL);\n        }\n\n        @Override\n        public char charAt(int index) {\n            int r = 0;\n            switch (index) {\n                case 0:\n                    r = (int) ((i >> 4) & 0x3FL);\n                    break;\n                case 1:\n                    r = (int) ((i >> 10) & 0x3FL);\n                    break;\n                case 2:\n                    r = (int) ((i >> 16) & 0x3FL);\n                    break;\n                case 3:\n                    r = (int) ((i >> 22) & 0x3FL);\n                    break;\n                case 4:\n                    r = (int) ((i >> 28) & 0x3FL);\n                    break;\n                case 5:\n                    r = (int) ((i >> 34) & 0x3FL);\n                    break;\n                case 6:\n                    r = (int) ((i >> 40) & 0x3FL);\n                    break;\n                case 7:\n                    r = (int) ((i >> 46) & 0x3FL);\n                    break;\n                case 8:\n                    r = (int) ((i >> 52) & 0x3FL);\n                    break;\n                case 9:\n                    r = (int) ((i >> 58) & 0x3FL);\n                    break;\n            }\n            return decode6BitChar(r);\n        }\n\n        @Override\n        public String toString() {\n            int n = length();\n            char[] r = new char[n];\n            for (int j = 0; j < n; j++) {\n                r[j] = charAt(j);\n            }\n            return new String(r);\n        }\n\n        @Override\n        public boolean equals(Object object) {\n            if (this == object) {\n                return true;\n            }\n            if (object instanceof Fixed6Bit_1_10) {\n                Fixed6Bit_1_10 otherString = (Fixed6Bit_1_10) object;\n                return i == otherString.i;\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            int hash = 0;\n            for (int j = 0; j < length(); j++) {\n                hash = 31 * hash + charAt(j);\n            }\n            return hash;\n        }\n\n        @Override\n        public CharSequence subSequence(int start, int end) {\n            return CharSequences.create(toString().substring(start, end));\n        }\n\n        @Override\n        public int compareTo(CharSequence o) {\n            return Comparator.compare(this, o);\n        }\n    }\n\n    private static final class Fixed6Bit_11_20 implements CompactCharSequence, Comparable<CharSequence> {\n\n        // Length is in lower 4bits of i1 and l2\n        // then 6 bits per character\n        private final long i1;\n        private final long i2;\n\n        private Fixed6Bit_11_20(long a1, long a2) {\n            i1 = a1;\n            i2 = a2;\n        }\n\n        @SuppressWarnings(\"fallthrough\")\n        private Fixed6Bit_11_20(byte[] b, int n) {\n            long a1 = n & 0x0F;\n            long a2 = (n >> 4) & 0x0F;\n            switch (n) {\n                case 20:\n                    a2 |= encode6BitChar(b[19]) << 58;\n                case 19:\n                    a2 |= encode6BitChar(b[18]) << 52;\n                case 18:\n                    a2 |= encode6BitChar(b[17]) << 46;\n                case 17:\n                    a2 |= encode6BitChar(b[16]) << 40;\n                case 16:\n                    a2 |= encode6BitChar(b[15]) << 34;\n                case 15:\n                    a2 |= encode6BitChar(b[14]) << 28;\n                case 14:\n                    a2 |= encode6BitChar(b[13]) << 22;\n                case 13:\n                    a2 |= encode6BitChar(b[12]) << 16;\n                case 12:\n                    a2 |= encode6BitChar(b[11]) << 10;\n                case 11:\n                    a2 |= encode6BitChar(b[10]) << 4;\n                case 10:\n                    a1 |= encode6BitChar(b[9]) << 58;\n                case 9:\n                    a1 |= encode6BitChar(b[8]) << 52;\n                case 8:\n                    a1 |= encode6BitChar(b[7]) << 46;\n                case 7:\n                    a1 |= encode6BitChar(b[6]) << 40;\n                case 6:\n                    a1 |= encode6BitChar(b[5]) << 34;\n                case 5:\n                    a1 |= encode6BitChar(b[4]) << 28;\n                case 4:\n                    a1 |= encode6BitChar(b[3]) << 22;\n                case 3:\n                    a1 |= encode6BitChar(b[2]) << 16;\n                case 2:\n                    a1 |= encode6BitChar(b[1]) << 10;\n                case 1:\n                    a1 |= encode6BitChar(b[0]) << 4;\n                    break;\n                case 0:\n                default:\n                    throw new IllegalArgumentException();\n            }\n            i1 = a1;\n            i2 = a2;\n        }\n\n        @Override\n        public int length() {\n            return (int) ((i1 & 0x0FL) + ((i2 & 0x0FL) << 4));\n        }\n\n        @Override\n        public char charAt(int index) {\n            int r = 0;\n            switch (index) {\n                case 0:\n                    r = (int) ((i1 >> 4) & 0x3FL);\n                    break;\n                case 1:\n                    r = (int) ((i1 >> 10) & 0x3FL);\n                    break;\n                case 2:\n                    r = (int) ((i1 >> 16) & 0x3FL);\n                    break;\n                case 3:\n                    r = (int) ((i1 >> 22) & 0x3FL);\n                    break;\n                case 4:\n                    r = (int) ((i1 >> 28) & 0x3FL);\n                    break;\n                case 5:\n                    r = (int) ((i1 >> 34) & 0x3FL);\n                    break;\n                case 6:\n                    r = (int) ((i1 >> 40) & 0x3FL);\n                    break;\n                case 7:\n                    r = (int) ((i1 >> 46) & 0x3FL);\n                    break;\n                case 8:\n                    r = (int) ((i1 >> 52) & 0x3FL);\n                    break;\n                case 9:\n                    r = (int) ((i1 >> 58) & 0x3FL);\n                    break;\n                case 10:\n                    r = (int) ((i2 >> 4) & 0x3FL);\n                    break;\n                case 11:\n                    r = (int) ((i2 >> 10) & 0x3FL);\n                    break;\n                case 12:\n                    r = (int) ((i2 >> 16) & 0x3FL);\n                    break;\n                case 13:\n                    r = (int) ((i2 >> 22) & 0x3FL);\n                    break;\n                case 14:\n                    r = (int) ((i2 >> 28) & 0x3FL);\n                    break;\n                case 15:\n                    r = (int) ((i2 >> 34) & 0x3FL);\n                    break;\n                case 16:\n                    r = (int) ((i2 >> 40) & 0x3FL);\n                    break;\n                case 17:\n                    r = (int) ((i2 >> 46) & 0x3FL);\n                    break;\n                case 18:\n                    r = (int) ((i2 >> 52) & 0x3FL);\n                    break;\n                case 19:\n                    r = (int) ((i2 >> 58) & 0x3FL);\n                    break;\n            }\n            return decode6BitChar(r);\n        }\n\n        @Override\n        public String toString() {\n            int n = length();\n            char[] r = new char[n];\n            for (int j = 0; j < n; j++) {\n                r[j] = charAt(j);\n            }\n            return new String(r);\n        }\n\n        @Override\n        public boolean equals(Object object) {\n            if (this == object) {\n                return true;\n            }\n            if (object instanceof Fixed6Bit_11_20) {\n                Fixed6Bit_11_20 otherString = (Fixed6Bit_11_20) object;\n                return i1 == otherString.i1 && i2 == otherString.i2;\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            long res = i1 + 31 * i2;\n            res = (res + (res >> 32)) & 0xFFFFFFFFL;\n            return (int) res;\n        }\n\n        @Override\n        public CharSequence subSequence(int start, int end) {\n            return CharSequences.create(toString().substring(start, end));\n        }\n\n        @Override\n        public int compareTo(CharSequence o) {\n            return Comparator.compare(this, o);\n        }\n    }\n\n    private static final class Fixed6Bit_21_30 implements CompactCharSequence, Comparable<CharSequence> {\n\n        // Length is in lower 4bits of i1 and l2\n        // then 6 bits per character in i1, i2 and i3\n        private final long i1;\n        private final long i2;\n        private final long i3;\n\n        private Fixed6Bit_21_30(long a1, long a2, long a3) {\n            i1 = a1;\n            i2 = a2;\n            i3 = a3;\n        }\n\n        @SuppressWarnings(\"fallthrough\")\n        private Fixed6Bit_21_30(byte[] b, int n) {\n            long a1 = n & 0x0F;\n            long a2 = (n >> 4) & 0x0F;\n            long a3 = 0;\n            switch (n) {\n                case 30:\n                    a3 |= encode6BitChar(b[29]) << 58;\n                case 29:\n                    a3 |= encode6BitChar(b[28]) << 52;\n                case 28:\n                    a3 |= encode6BitChar(b[27]) << 46;\n                case 27:\n                    a3 |= encode6BitChar(b[26]) << 40;\n                case 26:\n                    a3 |= encode6BitChar(b[25]) << 34;\n                case 25:\n                    a3 |= encode6BitChar(b[24]) << 28;\n                case 24:\n                    a3 |= encode6BitChar(b[23]) << 22;\n                case 23:\n                    a3 |= encode6BitChar(b[22]) << 16;\n                case 22:\n                    a3 |= encode6BitChar(b[21]) << 10;\n                case 21:\n                    a3 |= encode6BitChar(b[20]) << 4;\n                case 20:\n                    a2 |= encode6BitChar(b[19]) << 58;\n                case 19:\n                    a2 |= encode6BitChar(b[18]) << 52;\n                case 18:\n                    a2 |= encode6BitChar(b[17]) << 46;\n                case 17:\n                    a2 |= encode6BitChar(b[16]) << 40;\n                case 16:\n                    a2 |= encode6BitChar(b[15]) << 34;\n                case 15:\n                    a2 |= encode6BitChar(b[14]) << 28;\n                case 14:\n                    a2 |= encode6BitChar(b[13]) << 22;\n                case 13:\n                    a2 |= encode6BitChar(b[12]) << 16;\n                case 12:\n                    a2 |= encode6BitChar(b[11]) << 10;\n                case 11:\n                    a2 |= encode6BitChar(b[10]) << 4;\n                case 10:\n                    a1 |= encode6BitChar(b[9]) << 58;\n                case 9:\n                    a1 |= encode6BitChar(b[8]) << 52;\n                case 8:\n                    a1 |= encode6BitChar(b[7]) << 46;\n                case 7:\n                    a1 |= encode6BitChar(b[6]) << 40;\n                case 6:\n                    a1 |= encode6BitChar(b[5]) << 34;\n                case 5:\n                    a1 |= encode6BitChar(b[4]) << 28;\n                case 4:\n                    a1 |= encode6BitChar(b[3]) << 22;\n                case 3:\n                    a1 |= encode6BitChar(b[2]) << 16;\n                case 2:\n                    a1 |= encode6BitChar(b[1]) << 10;\n                case 1:\n                    a1 |= encode6BitChar(b[0]) << 4;\n                    break;\n                case 0:\n                default:\n                    throw new IllegalArgumentException();\n            }\n            i1 = a1;\n            i2 = a2;\n            i3 = a3;\n        }\n\n        @Override\n        public int length() {\n            return (int) ((i1 & 0x0FL) + ((i2 & 0x0FL) << 4));\n        }\n\n        @Override\n        public char charAt(int index) {\n            int r = 0;\n            switch (index) {\n                case 0:\n                    r = (int) ((i1 >> 4) & 0x3FL);\n                    break;\n                case 1:\n                    r = (int) ((i1 >> 10) & 0x3FL);\n                    break;\n                case 2:\n                    r = (int) ((i1 >> 16) & 0x3FL);\n                    break;\n                case 3:\n                    r = (int) ((i1 >> 22) & 0x3FL);\n                    break;\n                case 4:\n                    r = (int) ((i1 >> 28) & 0x3FL);\n                    break;\n                case 5:\n                    r = (int) ((i1 >> 34) & 0x3FL);\n                    break;\n                case 6:\n                    r = (int) ((i1 >> 40) & 0x3FL);\n                    break;\n                case 7:\n                    r = (int) ((i1 >> 46) & 0x3FL);\n                    break;\n                case 8:\n                    r = (int) ((i1 >> 52) & 0x3FL);\n                    break;\n                case 9:\n                    r = (int) ((i1 >> 58) & 0x3FL);\n                    break;\n                case 10:\n                    r = (int) ((i2 >> 4) & 0x3FL);\n                    break;\n                case 11:\n                    r = (int) ((i2 >> 10) & 0x3FL);\n                    break;\n                case 12:\n                    r = (int) ((i2 >> 16) & 0x3FL);\n                    break;\n                case 13:\n                    r = (int) ((i2 >> 22) & 0x3FL);\n                    break;\n                case 14:\n                    r = (int) ((i2 >> 28) & 0x3FL);\n                    break;\n                case 15:\n                    r = (int) ((i2 >> 34) & 0x3FL);\n                    break;\n                case 16:\n                    r = (int) ((i2 >> 40) & 0x3FL);\n                    break;\n                case 17:\n                    r = (int) ((i2 >> 46) & 0x3FL);\n                    break;\n                case 18:\n                    r = (int) ((i2 >> 52) & 0x3FL);\n                    break;\n                case 19:\n                    r = (int) ((i2 >> 58) & 0x3FL);\n                    break;\n                case 20:\n                    r = (int) ((i3 >> 4) & 0x3FL);\n                    break;\n                case 21:\n                    r = (int) ((i3 >> 10) & 0x3FL);\n                    break;\n                case 22:\n                    r = (int) ((i3 >> 16) & 0x3FL);\n                    break;\n                case 23:\n                    r = (int) ((i3 >> 22) & 0x3FL);\n                    break;\n                case 24:\n                    r = (int) ((i3 >> 28) & 0x3FL);\n                    break;\n                case 25:\n                    r = (int) ((i3 >> 34) & 0x3FL);\n                    break;\n                case 26:\n                    r = (int) ((i3 >> 40) & 0x3FL);\n                    break;\n                case 27:\n                    r = (int) ((i3 >> 46) & 0x3FL);\n                    break;\n                case 28:\n                    r = (int) ((i3 >> 52) & 0x3FL);\n                    break;\n                case 29:\n                    r = (int) ((i3 >> 58) & 0x3FL);\n                    break;\n            }\n            return decode6BitChar(r);\n        }\n\n        @Override\n        public String toString() {\n            int n = length();\n            char[] r = new char[n];\n            for (int j = 0; j < n; j++) {\n                r[j] = charAt(j);\n            }\n            return new String(r);\n        }\n\n        @Override\n        public boolean equals(Object object) {\n            if (this == object) {\n                return true;\n            }\n            if (object instanceof Fixed6Bit_21_30) {\n                Fixed6Bit_21_30 otherString = (Fixed6Bit_21_30) object;\n                return i1 == otherString.i1 && i2 == otherString.i2 && i3 == otherString.i3;\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            long res = i1 + 31 * (i2 + i3 * 31);\n            res = (res + (res >> 32)) & 0xFFFFFFFFL;\n            return (int) res;\n        }\n\n        @Override\n        public CharSequence subSequence(int start, int end) {\n            return CharSequences.create(toString().substring(start, end));\n        }\n\n        @Override\n        public int compareTo(CharSequence o) {\n            return Comparator.compare(this, o);\n        }\n    }\n\n    /**\n     * compact char sequence implementation for strings in range 8-15 characters\n     * size: 8 + 4*4 = 24 bytes for all strings vs String impl occupying\n     */\n    private static final class Fixed_8_15 implements CompactCharSequence, Comparable<CharSequence> {\n\n        private final int i1;\n        private final int i2;\n        private final int i3;\n        private final int i4;\n\n        private Fixed_8_15(int a1, int a2, int a3, int a4) {\n            i1 = a1;\n            i2 = a2;\n            i3 = a3;\n            i4 = a4;\n        }\n\n        @SuppressWarnings(\"fallthrough\")\n        private Fixed_8_15(byte[] b, int n) {\n            int a1 = n;\n            int a2 = 0;\n            int a3 = 0;\n            int a4 = 0;\n            switch (n) {\n                case 15:\n                    a4 += (b[14] & 0xFF) << 24;\n                case 14:\n                    a4 += (b[13] & 0xFF) << 16;\n                case 13:\n                    a4 += (b[12] & 0xFF) << 8;\n                case 12:\n                    a4 += b[11] & 0xFF;\n                case 11:\n                    a3 += (b[10] & 0xFF) << 24;\n                case 10:\n                    a3 += (b[9] & 0xFF) << 16;\n                case 9:\n                    a3 += (b[8] & 0xFF) << 8;\n                case 8:\n                    a3 += b[7] & 0xFF;\n                case 7:\n                    a2 += (b[6] & 0xFF) << 24;\n                case 6:\n                    a2 += (b[5] & 0xFF) << 16;\n                case 5:\n                    a2 += (b[4] & 0xFF) << 8;\n                case 4:\n                    a2 += b[3] & 0xFF;\n                case 3:\n                    a1 += (b[2] & 0xFF) << 24;\n                case 2:\n                    a1 += (b[1] & 0xFF) << 16;\n                case 1:\n                    a1 += (b[0] & 0xFF) << 8;\n                case 0:\n                    break;\n                default:\n                    throw new IllegalArgumentException();\n            }\n            i1 = a1;\n            i2 = a2;\n            i3 = a3;\n            i4 = a4;\n        }\n\n        @Override\n        public int length() {\n            return i1 & 0xFF;\n        }\n\n        @Override\n        public char charAt(int index) {\n            int r = 0;\n            switch (index) {\n                case 0:\n                    r = (i1 & 0xFF00) >> 8;\n                    break;\n                case 1:\n                    r = (i1 & 0xFF0000) >> 16;\n                    break;\n                case 2:\n                    r = (i1 >> 24) & 0xFF;\n                    break;\n                case 3:\n                    r = i2 & 0xFF;\n                    break;\n                case 4:\n                    r = (i2 & 0xFF00) >> 8;\n                    break;\n                case 5:\n                    r = (i2 & 0xFF0000) >> 16;\n                    break;\n                case 6:\n                    r = (i2 >> 24) & 0xFF;\n                    break;\n                case 7:\n                    r = i3 & 0xFF;\n                    break;\n                case 8:\n                    r = (i3 & 0xFF00) >> 8;\n                    break;\n                case 9:\n                    r = (i3 & 0xFF0000) >> 16;\n                    break;\n                case 10:\n                    r = (i3 >> 24) & 0xFF;\n                    break;\n                case 11:\n                    r = i4 & 0xFF;\n                    break;\n                case 12:\n                    r = (i4 & 0xFF00) >> 8;\n                    break;\n                case 13:\n                    r = (i4 & 0xFF0000) >> 16;\n                    break;\n                case 14:\n                    r = (i4 >> 24) & 0xFF;\n                    break;\n            }\n            return (char) r;\n        }\n\n        @Override\n        public String toString() {\n            int n = length();\n            char[] r = new char[n];\n            for (int i = 0; i < n; i++) {\n                r[i] = charAt(i);\n            }\n            return new String(r);\n        }\n\n        @Override\n        public boolean equals(Object object) {\n            if (this == object) {\n                return true;\n            }\n            if (object instanceof Fixed_8_15) {\n                Fixed_8_15 otherString = (Fixed_8_15) object;\n                return i1 == otherString.i1 && i2 == otherString.i2 && i3 == otherString.i3 && i4 == otherString.i4;\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            return i1 + 31 * (i2 + 31 * (i3 + 31 * i4));\n        }\n\n        @Override\n        public CharSequence subSequence(int start, int end) {\n            return CharSequences.create(toString().substring(start, end));\n        }\n\n        @Override\n        public int compareTo(CharSequence o) {\n            return Comparator.compare(this, o);\n        }\n    }\n\n    /**\n     * compact char sequence implementation for strings in range 16-23 characters\n     * size: 8 + 3*8 = 32 bytes for all strings vs String impl occupying\n     */\n    private static final class Fixed_16_23 implements CompactCharSequence, Comparable<CharSequence> {\n\n        private final long i1;\n        private final long i2;\n        private final long i3;\n\n        private Fixed_16_23(long a1, long a2, long a3) {\n            i1 = a1;\n            i2 = a2;\n            i3 = a3;\n        }\n\n        @SuppressWarnings(\"fallthrough\")\n        private Fixed_16_23(byte[] b, int n) {\n            long a1 = 0;\n            long a2 = 0;\n            long a3 = 0;\n            switch (n) {\n                case 23:\n                    a3 += (b[22] & 0xFFL) << 24;\n                case 22:\n                    a3 += (b[21] & 0xFF) << 16;\n                case 21:\n                    a3 += (b[20] & 0xFF) << 8;\n                case 20:\n                    a3 += (b[19] & 0xFF);\n                    a3 <<= 32;\n                case 19:\n                    a3 += (b[18] & 0xFFL) << 24;\n                case 18:\n                    a3 += (b[17] & 0xFF) << 16;\n                case 17:\n                    a3 += (b[16] & 0xFF) << 8;\n                case 16:\n                    a3 += b[15] & 0xFF;\n                case 15:\n                    a2 += (b[14] & 0xFFL) << 24;\n                case 14:\n                    a2 += (b[13] & 0xFF) << 16;\n                case 13:\n                    a2 += (b[12] & 0xFF) << 8;\n                case 12:\n                    a2 += (b[11] & 0xFF);\n                    a2 <<= 32;\n                case 11:\n                    a2 += (b[10] & 0xFFL) << 24;\n                case 10:\n                    a2 += (b[9] & 0xFF) << 16;\n                case 9:\n                    a2 += (b[8] & 0xFF) << 8;\n                case 8:\n                    a2 += b[7] & 0xFF;\n                case 7:\n                    a1 += (b[6] & 0xFFL) << 24;\n                case 6:\n                    a1 += (b[5] & 0xFF) << 16;\n                case 5:\n                    a1 += (b[4] & 0xFF) << 8;\n                case 4:\n                    a1 += (b[3] & 0xFF);\n                    a1 <<= 32;\n                case 3:\n                    a1 += (b[2] & 0xFFL) << 24;\n                case 2:\n                    a1 += (b[1] & 0xFF) << 16;\n                case 1:\n                    a1 += (b[0] & 0xFF) << 8;\n                case 0:\n                    a1 += n;\n                    break;\n                default:\n                    throw new IllegalArgumentException();\n            }\n            i1 = a1;\n            i2 = a2;\n            i3 = a3;\n        }\n\n        @Override\n        public int length() {\n            return (int) (i1 & 0xFF);\n        }\n\n        @Override\n        public char charAt(int index) {\n            int r = 0;\n            switch (index) {\n                case 0:\n                    r = (int) ((i1 >> 8) & 0xFFL);\n                    break;\n                case 1:\n                    r = (int) ((i1 >> 16) & 0xFFL);\n                    break;\n                case 2:\n                    r = (int) ((i1 >> 24) & 0xFFL);\n                    break;\n                case 3:\n                    r = (int) ((i1 >> 32) & 0xFFL);\n                    break;\n                case 4:\n                    r = (int) ((i1 >> 40) & 0xFFL);\n                    break;\n                case 5:\n                    r = (int) ((i1 >> 48) & 0xFFL);\n                    break;\n                case 6:\n                    r = (int) ((i1 >> 56) & 0xFFL);\n                    break;\n                case 7:\n                    r = (int) (i2 & 0xFFL);\n                    break;\n                case 8:\n                    r = (int) ((i2 >> 8) & 0xFFL);\n                    break;\n                case 9:\n                    r = (int) ((i2 >> 16) & 0xFFL);\n                    break;\n                case 10:\n                    r = (int) ((i2 >> 24) & 0xFFL);\n                    break;\n                case 11:\n                    r = (int) ((i2 >> 32) & 0xFFL);\n                    break;\n                case 12:\n                    r = (int) ((i2 >> 40) & 0xFFL);\n                    break;\n                case 13:\n                    r = (int) ((i2 >> 48) & 0xFFL);\n                    break;\n                case 14:\n                    r = (int) ((i2 >> 56) & 0xFFL);\n                    break;\n                case 15:\n                    r = (int) (i3 & 0xFFL);\n                    break;\n                case 16:\n                    r = (int) ((i3 >> 8) & 0xFFL);\n                    break;\n                case 17:\n                    r = (int) ((i3 >> 16) & 0xFFL);\n                    break;\n                case 18:\n                    r = (int) ((i3 >> 24) & 0xFFL);\n                    break;\n                case 19:\n                    r = (int) ((i3 >> 32) & 0xFFL);\n                    break;\n                case 20:\n                    r = (int) ((i3 >> 40) & 0xFFL);\n                    break;\n                case 21:\n                    r = (int) ((i3 >> 48) & 0xFFL);\n                    break;\n                case 22:\n                    r = (int) ((i3 >> 56) & 0xFFL);\n                    break;\n            }\n            return (char) r;\n        }\n\n        @Override\n        public String toString() {\n            int n = length();\n            char[] r = new char[n];\n            for (int i = 0; i < n; i++) {\n                r[i] = charAt(i);\n            }\n            return new String(r);\n        }\n\n        @Override\n        public boolean equals(Object object) {\n            if (this == object) {\n                return true;\n            }\n            if (object instanceof Fixed_16_23) {\n                Fixed_16_23 otherString = (Fixed_16_23) object;\n                return i1 == otherString.i1 && i2 == otherString.i2 && i3 == otherString.i3;\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            long res = i1 + 31 * (i2 + 31 * i3);\n            res = (res + (res >> 32)) & 0xFFFFFFFFL;\n            return (int) res;\n        }\n\n        @Override\n        public CharSequence subSequence(int start, int end) {\n            return CharSequences.create(toString().substring(start, end));\n        }\n\n        @Override\n        public int compareTo(CharSequence o) {\n            return Comparator.compare(this, o);\n        }\n    }\n\n    /**\n     * compact char sequence implementation based on char[] array\n     * size: 8 + 4 + 4 (= 16 bytes) + sizeof ('value')\n     * it is still more effective than String, because string stores length in field\n     * and it costs 20 bytes aligned into 24\n     */\n    private final static class CharBasedSequence implements CompactCharSequence, Comparable<CharSequence> {\n\n        private final char[] value;\n        private int hash;\n\n        private CharBasedSequence(char[] v) {\n            value = v;\n        }\n\n        @Override\n        public int length() {\n            return value.length;\n        }\n\n        @Override\n        public char charAt(int index) {\n            return value[index];\n        }\n\n        @Override\n        public boolean equals(Object object) {\n            if (this == object) {\n                return true;\n            }\n            if (object instanceof CharBasedSequence) {\n                CharBasedSequence otherString = (CharBasedSequence) object;\n                if (hash != 0 && otherString.hash != 0) {\n                    if (hash != otherString.hash) {\n                        return false;\n                    }\n                }\n                return Arrays.equals(value, otherString.value);\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            int h = hash;\n            if (h == 0) {\n                int n = value.length;\n                for (int i = 0; i < n; i++) {\n                    h = 31 * h + value[i];\n                }\n                hash = h;\n            }\n            return h;\n        }\n\n        @Override\n        public CharSequence subSequence(int beginIndex, int endIndex) {\n            return CharSequences.create(value, beginIndex, endIndex-beginIndex);\n        }\n\n        @Override\n        public String toString() {\n            return new String(value);\n        }\n\n        @Override\n        public int compareTo(CharSequence o) {\n            return CharSequenceComparator.compareCharBasedWithOther(this, o);\n        }\n    }\n\n    /**\n     * compact char sequence implementation based on byte[]\n     * size: 8 + 4 + 4 (= 16 bytes) + sizeof ('value')\n     */\n    private final static class ByteBasedSequence implements CompactCharSequence, Comparable<CharSequence> {\n\n        private final byte[] value;\n        private int hash;\n\n        private ByteBasedSequence(byte[] b) {\n            value = b;\n        }\n\n        @Override\n        public int length() {\n            return value.length;\n        }\n\n        @Override\n        public char charAt(int index) {\n            int r = value[index] & 0xFF;\n            return (char) r;\n        }\n\n        @Override\n        public boolean equals(Object object) {\n            if (this == object) {\n                return true;\n            }\n            if (object instanceof ByteBasedSequence) {\n                ByteBasedSequence otherString = (ByteBasedSequence) object;\n                if (hash != 0 && otherString.hash != 0) {\n                    if (hash != otherString.hash) {\n                        return false;\n                    }\n                }\n                return Arrays.equals(value, otherString.value);\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            int h = hash;\n            if (h == 0) {\n                int n = value.length;\n                for (int i = 0; i < n; i++) {\n                    h = 31 * h + value[i];\n                }\n                hash = h;\n            }\n            return h;\n        }\n\n        @Override\n        public CharSequence subSequence(int beginIndex, int endIndex) {\n            return CharSequences.create(toChars(), beginIndex, endIndex-beginIndex);\n        }\n\n        @Override\n        public String toString() {\n            char[] r = toChars();\n            return new String(r);\n        }\n\n        private char[] toChars() {\n            int n = value.length;\n            char[] r = new char[n];\n            for (int i = 0; i < n; i++) {\n                int c = value[i] & 0xFF;\n                r[i] = (char) c;\n            }\n            return r;\n        }\n\n        @Override\n        public int compareTo(CharSequence o) {\n            return CharSequenceComparator.compareByteBasedWithOther(this, o);\n        }\n    }\n\n    private static final CompactCharSequence EMPTY = new Fixed_0_7(new byte[0], 0);\n    private static final CharSequenceComparator Comparator = new CharSequenceComparator();\n\n    /**\n     * performance tuned comparator to prevent charAt calls when possible\n     */\n    private static class CharSequenceComparator implements Comparator<CharSequence> {\n\n        @Override\n        public int compare(CharSequence o1, CharSequence o2) {\n            if (o1 instanceof ByteBasedSequence) {\n                return compareByteBasedWithOther((ByteBasedSequence)o1, o2);\n            } else if (o2 instanceof ByteBasedSequence) {\n                return -compareByteBasedWithOther((ByteBasedSequence) o2, o1);\n            } else if (o1 instanceof CharBasedSequence) {\n                return compareCharBasedWithOther((CharBasedSequence)o1, o2);\n            } else if (o2 instanceof CharBasedSequence) {\n                return -compareCharBasedWithOther((CharBasedSequence)o2, o1);\n            }\n            int len1 = o1.length();\n            int len2 = o2.length();\n            int n = Math.min(len1, len2);\n            int k = 0;\n            while (k < n) {\n                char c1 = o1.charAt(k);\n                char c2 = o2.charAt(k);\n                if (c1 != c2) {\n                    return c1 - c2;\n                }\n                k++;\n            }\n            return len1 - len2;\n        }\n\n        //<editor-fold defaultstate=\"collapsed\" desc=\"Private methods\">\n        private static int compareByteBased(ByteBasedSequence bbs1, ByteBasedSequence bbs2) {\n            int len1 = bbs1.value.length;\n            int len2 = bbs2.value.length;\n            int n = Math.min(len1, len2);\n            int k = 0;\n            while (k < n) {\n                if (bbs1.value[k] != bbs2.value[k]) {\n                    return (bbs1.value[k] & 0xFF) - (bbs2.value[k] & 0xFF);\n                }\n                k++;\n            }\n            return len1 - len2;\n        }\n\n        private static int compareCharBased(CharBasedSequence cbs1, CharBasedSequence cbs2) {\n            int len1 = cbs1.value.length;\n            int len2 = cbs2.value.length;\n            int n = Math.min(len1, len2);\n            int k = 0;\n            while (k < n) {\n                if (cbs1.value[k] != cbs2.value[k]) {\n                    return cbs1.value[k] - cbs2.value[k];\n                }\n                k++;\n            }\n            return len1 - len2;\n        }\n\n        private static int compareByteBasedWithCharBased(ByteBasedSequence bbs1, CharBasedSequence cbs2) {\n            int len1 = bbs1.value.length;\n            int len2 = cbs2.value.length;\n            int n = Math.min(len1, len2);\n            int k = 0;\n            while (k < n) {\n                int c1 = bbs1.value[k] & 0xFF;\n                int c2 = cbs2.value[k];\n                if (c1 != c2) {\n                    return c1 - c2;\n                }\n                k++;\n            }\n            return len1 - len2;\n        }\n\n        private static int compareByteBasedWithOther(ByteBasedSequence bbs1, CharSequence o2) {\n            if (o2 instanceof ByteBasedSequence) {\n                return compareByteBased(bbs1, (ByteBasedSequence) o2);\n            } else if (o2 instanceof CharBasedSequence) {\n                return compareByteBasedWithCharBased(bbs1, (CharBasedSequence) o2);\n            }\n            int len1 = bbs1.value.length;\n            int len2 = o2.length();\n            int n = Math.min(len1, len2);\n            int k = 0;\n            int c1, c2;\n            while (k < n) {\n                c1 = bbs1.value[k] & 0xFF;\n                c2 = o2.charAt(k);\n                if (c1 != c2) {\n                    return c1 - c2;\n                }\n                k++;\n            }\n            return len1 - len2;\n        }\n\n        private static int compareCharBasedWithOther(CharBasedSequence cbs1, CharSequence o2) {\n            if (o2 instanceof CharBasedSequence) {\n                return compareCharBased(cbs1, (CharBasedSequence) o2);\n            } else if (o2 instanceof ByteBasedSequence) {\n                return -compareByteBasedWithCharBased((ByteBasedSequence) o2, cbs1);\n            }\n            int len1 = cbs1.value.length;\n            int len2 = o2.length();\n            int n = Math.min(len1, len2);\n            int k = 0;\n            int c1, c2;\n            while (k < n) {\n                c1 = cbs1.value[k];\n                c2 = o2.charAt(k);\n                if (c1 != c2) {\n                    return c1 - c2;\n                }\n                k++;\n            }\n            return len1 - len2;\n        }\n        //</editor-fold>\n    }\n\n    private static class CharSequences {\n\n        private static CharSequence create(String substring) {\n            throw new UnsupportedOperationException(\"Not supported yet.\"); //To change body of generated methods, choose Tools | Templates.\n        }\n\n        private static CharSequence create(char[] value, int beginIndex, int i) {\n            throw new UnsupportedOperationException(\"Not supported yet.\"); //To change body of generated methods, choose Tools | Templates.\n        }\n\n        CharSequences() {\n        }\n    }\n\n    /**\n     * marker interface for compact char sequence implementations\n     */\n    private interface CompactCharSequence extends CharSequence {\n    }\n    \n    \n    private static class DependencyResolver {\n        \n        private final static int TYPE_MODULE = 1;\n        private final static int TYPE_PACKAGE = 2;\n        private final static int TYPE_JAVA = 3;\n        private final static int TYPE_IDE = 4;\n        private final static int TYPE_REQUIRES = 5;\n        private final static int TYPE_NEEDS = 6;\n        private final static int TYPE_RECOMMENDS = 7;\n        private final static int COMPARE_SPEC = 1;\n        private final static int COMPARE_IMPL = 2;\n        private final static int COMPARE_ANY = 3;\n        \n        static String toString(String name, String version, int type, int comparison) {\n            StringBuilder buf = new StringBuilder(100);\n\n            if (type == TYPE_MODULE) {\n                buf.append(\"module \"); // NOI18N\n            } else if (type == TYPE_PACKAGE) {\n                buf.append(\"package \"); // NOI18N\n            } else if (type == TYPE_REQUIRES) {\n                buf.append(\"requires \"); // NOI18N\n            } else if (type == TYPE_NEEDS) {\n                buf.append(\"needs \"); // NOI18N\n            } else if (type == TYPE_RECOMMENDS) {\n                buf.append(\"recommends \"); // NOI18N\n            }\n\n            buf.append(name);\n\n            if (comparison == COMPARE_IMPL) {\n                buf.append(\" = \"); // NOI18N\n                buf.append(version);\n            } else if (comparison == COMPARE_SPEC) {\n                buf.append(\" > \"); // NOI18N\n                buf.append(version);\n            }\n\n            return buf.toString();\n        }\n        \n    }\n\n    //</editor-fold>\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/netbeans/VCSDetailsProvider.java",
    "content": "/*\n * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.netbeans;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsProvider;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.spi.DetailsUtils;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=DetailsProvider.class)\npublic class VCSDetailsProvider extends DetailsProvider.Basic {\n\n    private static final String GIT_STATUS = \"org.netbeans.libs.git.GitStatus\"; // NOI18N\n\n    public VCSDetailsProvider() {\n        super(GIT_STATUS);\n    }\n\n    @Override\n    public String getDetailsString(String className, Instance instance) {\n        if (GIT_STATUS.equals(className))  {\n            String relpath = DetailsUtils.getInstanceFieldString(instance, \"relativePath\"); // NOI18N\n            String status = DetailsUtils.getInstanceFieldString(instance, \"statusHeadWC\"); // NOI18N\n            if (status != null && relpath != null) {\n                return status + \" \" + relpath;      // NOI18N\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/spi/DetailsProvider.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.spi;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.model.BrowserUtils;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"BrowserUtils_Loading=<loading content...>\"                                   // NOI18N\n})\npublic abstract class DetailsProvider {\n\n    // [Event Dispatch Thread / Worker Thread] List of supported classes, null for all\n    public String[] getSupportedClasses() {\n        return null;\n    }\n\n    // [Worker Thread] Short string representing the instance\n    public String getDetailsString(String className, Instance instance) {\n        return null;\n    }\n\n    // [Event Dispatch Thread] UI to visualize the selected instance\n    public View getDetailsView(String className, Instance instance) {\n        return null;\n    }\n\n\n    public static abstract class Basic extends DetailsProvider {\n\n        private final String[] supportedClasses;\n\n        // Use to register for all classes\n        public Basic() {\n            this((String[])null);\n        }\n\n        // Use to register for defined classes\n        protected Basic(String... supportedClasses) {\n            this.supportedClasses = supportedClasses;\n        }\n\n        public final String[] getSupportedClasses() {\n            return supportedClasses;\n        }\n\n    }\n\n\n    public static abstract class View extends JPanel {\n\n        private RequestProcessor.Task workerTask;\n        private Instance instance;\n        \n        // [Event Dispatch Thread] Constructor for default initial UI (\"<loading content...>\")\n        protected View(Instance instance) {\n            this(instance, initialView());\n        }\n        \n        private static JComponent initialView() {\n            JLabel loading = new JLabel(Bundle.BrowserUtils_Loading(), JLabel.CENTER);\n            loading.setEnabled(false);\n            \n            JPanel loadingContainer = new JPanel(new BorderLayout());\n            loadingContainer.setOpaque(true);\n            loadingContainer.setBackground(UIUtils.getProfilerResultsBackground());\n            loadingContainer.setEnabled(false);\n            loadingContainer.add(loading, BorderLayout.CENTER);\n            \n            return loadingContainer;\n        }\n        \n        // [Event Dispatch Thread] Constructor for custom initial UI\n        protected View(Instance instance, Component initialView) {\n            super(new BorderLayout());\n            add(initialView, BorderLayout.CENTER);\n            \n            this.instance = instance;\n        }\n        \n        // [Worker Thread] Compute the view here, check Thread.interrupted(),\n        // use SwingUtilities.invokeLater() to display the result\n        protected abstract void computeView(Instance instance);\n        \n        public final void addNotify() {\n            super.addNotify();\n            \n            // #241316, this can't be called from constructor!\n            workerTask = BrowserUtils.performTask(new Runnable() {\n                public void run() {\n                    if (!Thread.interrupted()) computeView(instance);\n                }\n            });\n        }\n        \n        // [Event Dispatch Thread] Do any cleanup here if needed\n        protected void removed() {}\n        \n        public final void removeNotify() {\n            workerTask.cancel();\n            super.removeNotify();\n            removed();\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/spi/DetailsUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.details.spi;\n\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.details.api.DetailsSupport;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class DetailsUtils {\n\n    public static final int MAX_ARRAY_LENGTH = 160;\n\n\n    // --- Check types ---------------------------------------------------------\n\n    public static boolean isInstanceOf(Instance instance, String clsName) {\n        if (instance == null) return false;\n        return instance.getJavaClass().getName().equals(clsName);\n    }\n\n    public static boolean isSubclassOf(Instance instance, String clsName) {\n        if (instance == null) return false;\n        JavaClass cls = instance.getJavaClass();\n\n        // NOTE: currently optimized for Builders, two-dimensional cache would be more general\n        if (!cls.getName().equals(LAST_SUBCLASS_INSTANCE)) {\n            SUBCLASS_CACHE.clear();\n        } else {\n            Boolean subclass = SUBCLASS_CACHE.get(clsName);\n            if (subclass != null) return subclass.booleanValue();\n        }\n\n        LAST_SUBCLASS_INSTANCE = cls.getName();\n\n        boolean result = false;\n        while (cls != null) {\n            if (cls.getName().equals(clsName)) {\n                result = true;\n                break;\n            }\n            cls = cls.getSuperClass();\n        }\n\n        SUBCLASS_CACHE.put(clsName, Boolean.valueOf(result));\n\n        return result;\n    }\n\n    private static String LAST_SUBCLASS_INSTANCE;\n    private static final LinkedHashMap<String, Boolean> SUBCLASS_CACHE =\n            new LinkedHashMap<String, Boolean>(100) {\n                protected boolean removeEldestEntry(Map.Entry eldest) {\n                    return size() > 5000;\n                }\n            };\n    \n    \n    // --- Primitive types -----------------------------------------------------\n    \n    public static boolean getBooleanFieldValue(Instance instance, String field, boolean def) {\n        Object value = instance.getValueOfField(field);\n        return value instanceof Boolean ? ((Boolean)value).booleanValue() : def;\n    }\n    \n    public static byte getByteFieldValue(Instance instance, String field, byte def) {\n        Object value = instance.getValueOfField(field);\n        return value instanceof Byte ? ((Byte)value).byteValue() : def;\n    }\n    \n    public static char getCharFieldValue(Instance instance, String field, char def) {\n        Object value = instance.getValueOfField(field);\n        return value instanceof Character ? ((Character)value).charValue() : def;\n    }\n    \n    public static double getDoubleFieldValue(Instance instance, String field, double def) {\n        Object value = instance.getValueOfField(field);\n        return value instanceof Double ? ((Double)value).doubleValue() : def;\n    }\n    \n    public static float getFloatFieldValue(Instance instance, String field, float def) {\n        Object value = instance.getValueOfField(field);\n        return value instanceof Float ? ((Float)value).floatValue() : def;\n    }\n    \n    public static int getIntFieldValue(Instance instance, String field, int def) {\n        Object value = instance.getValueOfField(field);\n        return value instanceof Integer ? ((Integer)value).intValue() : def;\n    }\n    \n    public static long getLongFieldValue(Instance instance, String field, long def) {\n        Object value = instance.getValueOfField(field);\n        return value instanceof Long ? ((Long)value).longValue() : def;\n    }\n    \n    public static short getShortFieldValue(Instance instance, String field, short def) {\n        Object value = instance.getValueOfField(field);\n        return value instanceof Short ? ((Short)value).shortValue() : def;\n    }\n    \n    \n    // --- Primitive arrays ----------------------------------------------------\n    \n    public static String getPrimitiveArrayFieldString(Instance instance, String field, int offset, int count, String separator, String trailer) {\n        Object value = instance.getValueOfField(field);\n        return value instanceof Instance ? getPrimitiveArrayString((Instance)value,\n                                           offset, count, separator, trailer) : null;\n    }\n    \n    public static String getPrimitiveArrayString(Instance instance, int offset, int count, String separator, String trailer) {\n        List<String> values = getPrimitiveArrayValues(instance);\n        if (values != null) {\n            int valuesCount = count < 0 ? values.size() - offset :\n                              Math.min(count, values.size() - offset);            \n            int separatorLength = separator == null ? 0 : separator.length();\n            int trailerLength = trailer == null ? 0 : trailer.length();\n            int estimatedSize = Math.min(valuesCount * (1 + separatorLength), MAX_ARRAY_LENGTH + trailerLength);\n            StringBuilder value = new StringBuilder(estimatedSize);\n            int lastValue = offset + valuesCount - 1;\n            for (int i = offset; i <= lastValue; i++) {\n                if (value.length() >= MAX_ARRAY_LENGTH) {\n                    if (trailerLength > 0) value.append(trailer);\n                    break;\n                }\n                value.append(values.get(i));\n                if (separator != null && i < lastValue) value.append(separator);\n            }\n            return value.toString();\n        }\n        return null;\n    }\n    \n    public static List<String> getPrimitiveArrayFieldValues(Instance instance, String field) {\n        Object value = instance.getValueOfField(field);\n        if (value instanceof Instance) return getPrimitiveArrayValues((Instance)value);\n        return null;\n    }\n    \n    public static List<String> getPrimitiveArrayValues(Instance instance) {\n        if (instance instanceof PrimitiveArrayInstance) {\n            PrimitiveArrayInstance array = (PrimitiveArrayInstance)instance;\n            return array.getValues();\n        }\n        return null;\n    }\n    \n    \n    // --- Object types --------------------------------------------------------\n    \n    public static String getInstanceFieldString(Instance instance, String field) {\n        Object value = instance.getValueOfField(field);\n        return value instanceof Instance ? getInstanceString((Instance)value) : null;\n    }\n    \n    public static String getInstanceString(Instance instance) {\n        return instance != null ? DetailsSupport.getDetailsString(instance) : null;\n    }\n    \n    \n    // --- Create arrays -------------------------------------------------------\n    \n    public static boolean[] getBooleanArray(List<String> valuesList) {\n        if (valuesList == null) return null;\n        int valuesCount = valuesList.size();\n        try {\n            boolean[] values = new boolean[valuesCount];\n            for (int i = 0; i < valuesCount; i++)\n                values[i] = Boolean.parseBoolean(valuesList.get(i));\n            return values;\n        } catch (OutOfMemoryError e) {\n            return new boolean[0];\n        }\n    }\n    \n    public static byte[] getByteArray(List<String> valuesList) {\n        if (valuesList == null) return null;\n        int valuesCount = valuesList.size();\n        try {\n            byte[] values = new byte[valuesCount];\n            for (int i = 0; i < valuesCount; i++)\n                values[i] = Byte.parseByte(valuesList.get(i));\n            return values;\n        } catch (NumberFormatException e) { // Byte.parseByte(String)\n            return new byte[0];\n        } catch (OutOfMemoryError e) {\n            return new byte[0];\n        }\n    }\n    \n    public static char[] getCharArray(List<String> valuesList) {\n        if (valuesList == null) return null;\n        int valuesCount = valuesList.size();\n        try {\n            char[] values = new char[valuesCount];\n            for (int i = 0; i < valuesCount; i++)\n                values[i] = valuesList.get(i).charAt(0);\n            return values;\n        } catch (IndexOutOfBoundsException e) { // String.charAt(0)\n            return new char[0];\n        } catch (OutOfMemoryError e) {\n            return new char[0];\n        }\n    }\n    \n    public static double[] getDoubleArray(List<String> valuesList) {\n        if (valuesList == null) return null;\n        int valuesCount = valuesList.size();\n        try {\n            double[] values = new double[valuesCount];\n            for (int i = 0; i < valuesCount; i++)\n                values[i] = Double.parseDouble(valuesList.get(i));\n            return values;\n        } catch (NumberFormatException e) { // Double.parseDouble(String)\n            return new double[0];\n        } catch (OutOfMemoryError e) {\n            return new double[0];\n        }\n    }\n    \n    public static float[] getFloatArray(List<String> valuesList) {\n        if (valuesList == null) return null;\n        int valuesCount = valuesList.size();\n        try {\n            float[] values = new float[valuesCount];\n            for (int i = 0; i < valuesCount; i++)\n                values[i] = Float.parseFloat(valuesList.get(i));\n            return values;\n        } catch (NumberFormatException e) { // Float.parseFloat(String)\n            return new float[0];\n        } catch (OutOfMemoryError e) {\n            return new float[0];\n        }\n    }\n    \n    public static int[] getIntArray(List<String> valuesList) {\n        if (valuesList == null) return null;\n        int valuesCount = valuesList.size();\n        try {\n            int[] values = new int[valuesCount];\n            for (int i = 0; i < valuesCount; i++)\n                values[i] = Integer.parseInt(valuesList.get(i));\n            return values;\n        } catch (NumberFormatException e) { // Integer.parseInt(String)\n            return new int[0];\n        } catch (OutOfMemoryError e) {\n            return new int[0];\n        }\n    }\n    \n    public static long[] getLongArray(List<String> valuesList) {\n        if (valuesList == null) return null;\n        int valuesCount = valuesList.size();\n        try {\n            long[] values = new long[valuesCount];\n            for (int i = 0; i < valuesCount; i++)\n                values[i] = Long.parseLong(valuesList.get(i));\n            return values;\n        } catch (NumberFormatException e) { // Long.parseLong(String)\n            return new long[0];\n        } catch (OutOfMemoryError e) {\n            return new long[0];\n        }\n    }\n    \n    public static short[] getShortArray(List<String> valuesList) {\n        if (valuesList == null) return null;\n        int valuesCount = valuesList.size();\n        try {\n            short[] values = new short[valuesCount];\n            for (int i = 0; i < valuesCount; i++)\n                values[i] = Short.parseShort(valuesList.get(i));\n            return values;\n        } catch (NumberFormatException e) { // Short.parseShort(String)\n            return new short[0];\n        } catch (OutOfMemoryError e) {\n            return new short[0];\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nFMT_DistEntry={0} objects ({1}B):\\n\nFMT_HistogramSum=Total instance count: {0}, size: {1}<br>\nLBL_UnknownClass=unknown class\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/Distribution.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint;\n\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.openide.util.NbBundle;\n\n\n/**\n * An object collector that classifies the objects according to their type.\n * For each logged type, it counts the number of instances and sums their total\n * size.\n *\n * @param T the entry type, which can add additional properties\n * @author nenik\n */\npublic final class Distribution {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    /**\n     *\n     */\n    public static class Entry {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private JavaClass type;\n        private int count;\n        private int size;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        /**\n         * Creates an entry with given size and count=1\n         * @param size the size this entry represent.\n         */\n        private Entry(JavaClass cls) {\n            this.type = cls;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public final int getCount() {\n            return count;\n        }\n\n        public final int getSize() {\n            return size;\n        }\n\n        @Override\n        public String toString() {\n            return Utils.printClass(null, type.getName()) + \": \" + getCount() + \"/\" + getSize() + \"B\"; // NOI18N\n        }\n\n        private void count(Instance in) {\n            assert ((type == null) || type.equals(in.getJavaClass()));\n            count++;\n            size += in.getSize();\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Entry allEntry = new Entry(null);\n    private HashMap<JavaClass, Entry> map = new HashMap<>();\n    private Set<Instance> counted = new HashSet<>();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     *\n     */\n    public Distribution() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Set<JavaClass> getClasses() {\n        return Collections.unmodifiableSet(map.keySet());\n    }\n\n    public boolean isCounted(Instance in) {\n        return counted.contains(in);\n    }\n\n    public Entry getResults(JavaClass cls) {\n        return map.get(cls);\n    }\n\n    public void add(Instance in) {\n        if (!counted.add(in)) {\n            return;\n        }\n\n        JavaClass cls = in.getJavaClass();\n        Entry en = map.get(cls);\n\n        if (en == null) {\n            map.put(cls, en = new Entry(cls));\n        }\n\n        en.count(in);\n        allEntry.count(in);\n    }\n\n    @Override\n    public String toString() {\n        StringBuilder result = new StringBuilder();\n\n        result.append(NbBundle.getMessage(Distribution.class, \"FMT_DistEntry\",\n                allEntry.getCount(),\n                allEntry.getSize()));\n\n        for (JavaClass key : getClasses()) {\n            result.append(\"  \").append(getResults(key)).append(\"\\n\"); // NOI18N\n        }\n\n        return result.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/FieldAccess.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint;\n\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\n\n\n/**\n *\n * @author nenik\n */\npublic class FieldAccess {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    Field fld;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of Field */\n    public FieldAccess(JavaClass jc, String name) {\n        List<Field> fields = jc.getFields();\n\n        for (Field f : fields) {\n            if (f.getName().equals(name)) {\n                fld = f;\n\n                break;\n            }\n        }\n        assert (fld != null);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public int getIntValue(Instance in) {\n        @SuppressWarnings(\"unchecked\")\n        List<FieldValue> values = in.getFieldValues();\n\n        for (FieldValue fv : values) {\n            if (fv.getField().equals(fld)) {\n                try {\n                    return Integer.parseInt(fv.getValue());\n                } catch (NumberFormatException nfe) {\n                }\n            }\n        }\n        assert false; // shouldn't reach\n\n        return -1;\n    }\n\n    public Instance getRefValue(Instance in) {\n        assert fld.getType().getName().equals(\"object\");\n\n        @SuppressWarnings(\"unchecked\")\n        List<FieldValue> values = in.getFieldValues();\n\n        for (FieldValue fv : values) {\n            if (fv.getField().equals(fld)) {\n                return ((ObjectFieldValue) fv).getInstance();\n            }\n        }\n        assert false; // shouldn't reach\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/Histogram.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint;\n\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.SortedMap;\nimport java.util.TreeMap;\nimport org.openide.util.NbBundle;\n\n\n/**\n *\n * @param T the entry type, which can add additional properties\n * @author nenik\n */\npublic final class Histogram<T extends Histogram.Entry> {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    /**\n     *\n     */\n    public static class Entry<T extends Entry> {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private int count;\n        private long size;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        /**\n         * Creates an entry with given size and count=1\n         * @param size the size this entry represent.\n         */\n        public Entry(long size) {\n            this.count = 1;\n            this.size = size;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public final int getCount() {\n            return count;\n        }\n\n        public final long getSize() {\n            return size;\n        }\n\n        @Override\n        public String toString() {\n            return \"#:\" + getCount() + \"/\" + getSize() + \"B\\n\"; // NOI18N\n        }\n\n        /**\n         * A callback for subclasses that should add the additional properties\n         * from given source to this entry. The infrastructure takes care of\n         * adding base properties. There's no need to call super.add().\n         *\n         * @param source The Entry to add to this\n         */\n        protected void add(T source) {\n        }\n\n        private void doAdd(T entry) {\n            count += ((Entry)entry).count;\n            size += ((Entry)entry).size;\n            add(entry);\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private HashMap<String, T> map = new HashMap<>();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     *\n     */\n    public Histogram() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static final Comparator<Entry> sortByCount() {\n        return new Comparator<Entry>() {\n                public int compare(Entry o1, Entry o2) {\n                    return o2.count - o1.count;\n                }\n            };\n    }\n\n    public static final Comparator<Entry> sortBySize() {\n        return new Comparator<Entry>() {\n                public int compare(Entry o1, Entry o2) {\n                    return Long.compare(o2.size,o1.size);\n                }\n            };\n    }\n\n    public SortedMap<String, T> getResults(final Comparator<Entry> comparator) {\n        SortedMap<String, T> sm = new TreeMap<>(new Comparator<String>() {\n                public int compare(String o1, String o2) {\n                    T t1 = map.get(o1);\n                    T t2 = map.get(o2);\n                    int delta = comparator.compare(t1, t2);\n\n                    if (delta == 0) {\n                        delta = o1.compareTo(o2);\n                    }\n\n                    return delta;\n                }\n            });\n        sm.putAll(map);\n\n        return sm;\n    }\n\n    public void add(String key, T entry) {\n        T current = map.get(key);\n\n        if (current != null) {\n            ((Entry)current).doAdd(entry);\n        } else {\n            map.put(key, entry);\n        }\n    }\n\n    public String toString(int treshold) {\n        StringBuilder result = new StringBuilder();\n        long totalSize = 0;\n        int totalCount = 0;\n        SortedMap<String, T> bySize = getResults(sortBySize());\n\n        for (Map.Entry<String, T> entry : bySize.entrySet()) {\n            long size = entry.getValue().getSize();\n\n            if (size > treshold) {\n                result.append(entry.getKey()).append(\": \").append(entry.getValue()).append(\"<br>\"); // NOI18N\n            }\n\n            totalSize += size;\n            totalCount += entry.getValue().getCount();\n        }\n\n        result.append(NbBundle.getMessage(Histogram.class, \"FMT_HistogramSum\", totalCount, totalSize));\n\n        return result.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/IteratingRule.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.regex.Pattern;\nimport javax.swing.BoundedRangeModel;\nimport javax.swing.JComponent;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\n\n\n/**\n * An iterating rule is a rule that iterates through all instances of single\n * class and does some analysis over each instance. When such a Rule is based\n * on this helper class, the infrastructure can independently monitor\n * the progress and also paralelize the task among available CPUs.\n *\n * Rules can override {@link #prepareRule(MemoryLint)} and {@link #summary()}\n * for preparation and finalization work, and must implement\n * {@link #perform(Instance)} for actual, per-instance analysis.\n *\n * @author nenik\n */\npublic abstract class IteratingRule extends Rule {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private MemoryLint context;\n    private Pattern classNamePattern;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public IteratingRule(String name, String desc, String classNamePattern) {\n        super(name, desc);\n        setClassNamePattern(classNamePattern);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public final void perform() {\n        Heap heap = context.getHeap();\n        @SuppressWarnings(\"unchecked\")\n        List<JavaClass> classes = heap.getAllClasses();\n        List<JavaClass> matching = new ArrayList<>();\n        int count = 0;\n\n        for (JavaClass cls : classes) {\n            if (classNamePattern.matcher(cls.getName()).matches()) {\n                matching.add(cls);\n                count += cls.getInstancesCount();\n            }\n\n            if (context.isInterruped()) {\n                return;\n            }\n        }\n\n        BoundedRangeModel progress = context.getProgress();\n        progress.setMaximum((count != 0) ? count : 1);\n\n        for (JavaClass actCls : matching) {\n            @SuppressWarnings(\"unchecked\")\n            List<Instance> instances = actCls.getInstances();\n\n            for (Instance inst : instances) {\n                Logger.getLogger(IteratingRule.class.getName()).log(Level.FINE, \"Executing rule on {0} instance\", inst); // NOI18N\n                perform(inst);\n                progress.setValue(progress.getValue() + 1);\n\n                if (context.isInterruped()) {\n                    return;\n                }\n            }\n        }\n\n        if (count == 0) {\n            progress.setValue(1);\n        }\n\n        summary();\n    }\n\n    public final void prepare(MemoryLint context) {\n        this.context = context;\n        prepareRule(context);\n    }\n\n    /** Configures the rule to be applied on all instances of classes\n     * matching to given pattern.\n     */\n    protected final void setClassNamePattern(String classNamePattern) {\n        this.classNamePattern = Pattern.compile(classNamePattern);\n    }\n\n    protected abstract void perform(Instance inst);\n\n    protected final MemoryLint getContext() {\n        return context;\n    }\n\n    /** Default implementation returns <code>null</code>\n     * (no customizer for the rule).\n     */\n    protected JComponent createCustomizer() {\n        return null;\n    }\n\n    protected void prepareRule(MemoryLint context) {\n    }\n\n    protected void summary() {\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/MemoryLint.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint;\n\nimport java.util.Collection;\nimport java.util.List;\nimport javax.swing.BoundedRangeModel;\nimport javax.swing.DefaultBoundedRangeModel;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\n\n\n/**\n * This is the MemoryLint engine. It manages the heap dump, available rules,\n * processing and results gathering.\n * Generally, it has no UI, but provides hooks for progress bar and results\n * visualization.\n *\n * @author nenik\n */\npublic class MemoryLint {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private static class HierarchicalModel extends DefaultBoundedRangeModel implements ChangeListener {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        BoundedRangeModel delegate = new DefaultBoundedRangeModel(0, 0, 0, 1);\n        int each;\n        int step = -1;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        HierarchicalModel(int steps, int each) {\n            super(0, 0, 0, steps * each);\n            this.each = each;\n            delegate.addChangeListener(this);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void setSteps(int steps) {\n            setRangeProperties(0, 0, 0, steps * each, false);\n        }\n\n        public void stateChanged(ChangeEvent e) {\n            updateValue();\n        }\n\n        BoundedRangeModel getNextDelegate() {\n            step++;\n            delegate.setRangeProperties(0, 0, 0, 1, false);\n            updateValue();\n\n            return delegate;\n        }\n\n        private void updateValue() {\n            int val = getValue();\n            setValue((step * each) + ((each * delegate.getValue()) / delegate.getMaximum()));\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private BoundedRangeModel progress;\n    private Heap heap;\n    private HierarchicalModel globalProgress;\n    private StringBuffer results = new StringBuffer();\n    private StringHelper stringHelper;\n    private volatile boolean interrupted;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public MemoryLint(Heap heap) {\n        this.heap = heap;\n        globalProgress = new HierarchicalModel(1, 1000);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public BoundedRangeModel getGlobalProgress() {\n        return globalProgress;\n    }\n\n    public Heap getHeap() {\n        return heap;\n    }\n\n    public boolean isInterruped() {\n        return interrupted;\n    }\n\n    public String getResults() {\n        return results.toString();\n    }\n\n    /** Perform BFS of incomming references and find shortest one not from SDK\n     */\n    public String getRootIncommingString(Instance in) {\n        String temp = null;\n\n        for (;;) {\n            Instance from = in.getNearestGCRootPointer();\n\n            if (from == null) {\n                break;\n            }\n\n            String rName = getFullName(in, from);\n\n            if (temp == null) {\n                temp = \"<< \" + rName; // there is at least some incoming ref\n            }\n\n            if (!rName.startsWith(\"java.\") && !rName.startsWith(\"javax.\")) {\n                return rName;\n            }\n\n            if (from.isGCRoot()) {\n                break;\n            }\n\n            in = from;\n        }\n\n        return (temp == null) ? \"unknown\" : temp;\n    }\n\n    public StringHelper getStringHelper() {\n        if (stringHelper == null) {\n            stringHelper = new StringHelper(heap);\n        }\n\n        return stringHelper;\n    }\n\n    public void appendResults(String s) {\n        results.append(s).append('\\n');\n    }\n\n    public static Collection<Rule> createRules() {\n        return RuleRegistry.getRegisteredRules();\n    }\n\n    public void interrupt() {\n        interrupted = true;\n    }\n\n    public void process(Collection<Rule> rules) {\n        int count = rules.size();\n        globalProgress.setSteps(count);\n\n        for (Rule r : rules) {\n            r.prepare(this);\n            progress = globalProgress.getNextDelegate();\n            results.append(r.resultsHeader());\n            r.perform();\n            results.append(\"<hr>\");\n\n            if (isInterruped()) {\n                break;\n            }\n        }\n    }\n\n    BoundedRangeModel getProgress() {\n        return progress;\n    }\n\n    private String getFullName(Instance to, Instance from) {\n        ObjectFieldValue fv = getInField(to, from);\n\n        if (fv == null) {\n            return from.getJavaClass().getName();\n        }\n\n        if (fv.getField().isStatic()) {\n            return fv.getField().getDeclaringClass().getName() + \";\" + fv.getField().getName();\n        } else {\n            return from.getJavaClass().getName() + \":\" + fv.getField().getName();\n        }\n    }\n\n    private ObjectFieldValue getInField(Instance to, Instance from) {\n        List<FieldValue> vals = from.getFieldValues();\n\n        for (FieldValue fv : vals) {\n            if (fv instanceof ObjectFieldValue) {\n                if (to.equals(((ObjectFieldValue) fv).getInstance())) {\n                    return (ObjectFieldValue) fv;\n                }\n            }\n        }\n\n        if (from.getJavaClass().getName().equals(\"java.lang.Class\")) {\n            JavaClass cls = heap.getJavaClassByID(from.getInstanceId());\n            vals = cls.getStaticFieldValues();\n\n            for (FieldValue fv : vals) {\n                if (fv instanceof ObjectFieldValue) {\n                    if (to.equals(((ObjectFieldValue) fv).getInstance())) {\n                        return (ObjectFieldValue) fv;\n                    }\n                }\n            }\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/Rule.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint;\n\nimport javax.swing.JComponent;\n\n\n/**\n *\n * @author nenik\n */\npublic abstract class Rule {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private JComponent customizer;\n    private String description;\n    private String displayName;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    protected Rule(String name, String desc) {\n        displayName = name;\n        description = desc;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public final String getDescription() {\n        return description;\n    }\n\n    public final String getDisplayName() {\n        return displayName;\n    }\n\n    /**\n     * The rule can provide a long description in the form of HTML page.\n     * This method should directly return the HTML page content.\n     * If there are any relative URLs in the html code (images, style sheet),\n     * they are interpretted as relative to the Rule's class file.\n     *\n     * @return the HTML description code or null if the rule has no\n     * HTML description.\n     */\n    public String getHTMLDescription() {\n        return null;\n    }\n\n    public abstract void perform();\n\n    public abstract void prepare(MemoryLint context);\n\n    public JComponent getCustomizer() {\n        if (customizer == null) {\n            customizer = createCustomizer();\n        }\n\n        return customizer;\n    }\n\n    /** Factory method to create customizer for adjusting\n     * rule parameters.\n     * @return UI component or <code>null</code>\n     */\n    protected abstract JComponent createCustomizer();\n\n    protected String resultsHeader() {\n        return \"<h2>\" + getDisplayName() + \"</h2>\"; // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/RuleRegistry.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author nenik\n */\nfinal class RuleRegistry {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private RuleRegistry() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static Collection<Rule> getRegisteredRules() {\n        List<Rule> al = instantiateRules();\n        Collections.sort(al,\n                         new Comparator<Rule>() {\n                public int compare(Rule o1, Rule o2) {\n                    return o1.getDisplayName().compareTo(o2.getDisplayName());\n                }\n            });\n\n        return al;\n    }\n\n    private static List<Rule> instantiateRules() {\n        return new ArrayList<>(Lookup.getDefault().lookupAll(Rule.class));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/StringHelper.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint;\n\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\n\n\n/**\n *\n * @author nenik\n */\npublic class StringHelper {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private FieldAccess fldCount;\n    private FieldAccess fldOffset;\n    private FieldAccess fldValue;\n    private Heap heap;\n    private JavaClass clsString;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    StringHelper(Heap heap) {\n        this.heap = heap;\n        clsString = heap.getJavaClassByName(\"java.lang.String\"); // NOI18N\n        fldOffset = new FieldAccess(clsString, \"offset\"); // NOI18N\n        fldCount = new FieldAccess(clsString, \"count\"); // NOI18N\n        fldValue = new FieldAccess(clsString, \"value\"); // NOI18N\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String decodeString(Instance in) {\n        if (in == null) {\n            return \"null\"; // NOI18N\n        }\n\n        if (!\"java.lang.String\".equals(in.getJavaClass().getName())) { // NOI18N\n            return \"<<\" + in.getJavaClass().getName() + \">>\"; // NOI18N\n        }\n\n        int off = fldOffset.getIntValue(in);\n        int cnt = fldCount.getIntValue(in);\n        PrimitiveArrayInstance arrValue = (PrimitiveArrayInstance) fldValue.getRefValue(in);\n\n        if (arrValue == null) {\n            return \"\"; // NOI18N\n        }\n\n        char[] data = getCharArray(arrValue);\n\n        return new String(data, off, cnt);\n    }\n\n    private char[] getCharArray(PrimitiveArrayInstance in) {\n        @SuppressWarnings(\"unchecked\")\n        List<String> vals = in.getValues();\n        char[] ret = new char[in.getLength()];\n        assert (ret.length == vals.size());\n\n        int i = 0;\n\n        for (String v : vals) {\n            ret[i++] = v.charAt(0);\n        }\n\n        return ret;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/Utils.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint;\n\nimport java.util.ArrayDeque;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Deque;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.heap.ArrayItemValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.GCRoot;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Value;\nimport org.openide.util.NbBundle;\n\n\n/**\n *\n * @author nenik\n */\npublic class Utils {\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    /** Performs a check whether target object is strongly referenced from source.\n     * @param source object to search path from\n     * @return true is target is held by source\n     */\n    public static boolean isReachableFrom(Instance source, Instance target) {\n        if ((source == null) || (target == null)) {\n            return false;\n        }\n\n        Logger.getLogger(Utils.class.getName()).log(Level.FINE, \"Utils.isReachableFrom {0}, {1}\", new Object[] { source, target });\n\n        Set<Instance> processed = new HashSet<>();\n        Deque<Instance> fifo = new ArrayDeque<>();\n        fifo.add(source);\n\n        while (!fifo.isEmpty()) {\n            if (fifo.size() > 200) {\n                Logger.getLogger(Utils.class.getName()).log(Level.FINE, \"overflow in isReachableFrom {0}, {1}\", new Object[] { source, target });\n\n                break;\n            }\n\n            Instance act = fifo.removeFirst();\n\n            if (act.equals(target)) {\n                return true;\n            }\n\n            //System.err.println(\"  processing iof \" + act.getJavaClass().getName() ); \n            @SuppressWarnings(\"unchecked\")\n            List<FieldValue> outgoing = act.getFieldValues();\n\n            for (FieldValue v : outgoing) {\n                Instance neu = null;\n\n                if (v instanceof ObjectFieldValue) {\n                    Field fld = ((ObjectFieldValue) v).getField();\n\n                    if (\"referent\".equals(fld.getName()) && \"java.lang.ref.Reference\".equals(fld.getDeclaringClass().getName())) { // NOI18N\n                        continue;\n                    }\n\n                    neu = ((ObjectFieldValue) v).getInstance();\n                }\n\n                if (v instanceof ArrayItemValue) {\n                    neu = ((ArrayItemValue) v).getInstance();\n                }\n\n                if (neu == null) {\n                    continue;\n                }\n\n                if (processed.add(neu)) {\n                    fifo.add(neu);\n                }\n            }\n        }\n\n        return false;\n    }\n\n    /*\n       private static void printObject(Instance in, Heap heap) {\n           System.err.println(in.getJavaClass().getName() + \"@\" + Long.toHexString(in.getInstanceId()));\n           List<FieldValue> lfv = in.getFieldValues();\n           for (FieldValue fv : lfv) {\n               if (\"object\".equals(fv.getField().getType().getName()) &&\n                       \"char[]\".equals(((ObjectFieldValue)fv).getInstance().getJavaClass().getName())) { // char[], special printout\n                   ObjectFieldValue ofv = (ObjectFieldValue)fv;\n                   PrimitiveArrayInstance carr = (PrimitiveArrayInstance)ofv.getInstance();\n                   List<String> vals = carr.getValues();\n                       StringBuilder val = new StringBuilder(\"'\");\n                   for (String v : vals) val.append(v);\n                   val.append(\"'\");\n                   System.err.println(\"  \" + fv.getField().getName() + \":\" + val.toString());\n               } else {\n                   System.err.println(\"  \" + fv.getField().getName() + \"(\" + fv.getField().getType().getName() + \"):\" + fv.getValue());\n               }\n           }\n           printPath(in, heap);\n           System.err.println(\"\");\n       }\n    \n       private static void printPath(Instance in, Heap heap) {\n           String prefix = \" \";\n           while (in != null) {\n               if (in.isGCRoot()) {\n                   GCRoot root = heap.getGCRoot(in);\n                   System.err.println(prefix + \"<-\" + in.getJavaClass().getName() + \"@\" + Long.toHexString(in.getInstanceId()) + \" is ROOT: \" + root.getKind());\n                   break;\n               }\n    \n               System.err.println(prefix + \"<-\" + in.getJavaClass().getName() + \"@\" + Long.toHexString(in.getInstanceId()));\n               prefix += \" \";\n               in = in.getNearestGCRootPointer();\n           }\n       }\n     */\n\n    /** Computes object set retained by some objects.\n     */\n    public static Set<Instance> getRetainedSet(Collection<Instance> objSet, Heap heap) {\n        Field ref = null;\n        JavaClass reference = heap.getJavaClassByName(\"java.lang.ref.Reference\"); // NOI18N\n\n        for (Field f : reference.getFields()) {\n\n            if (\"referent\".equals(f.getName())) { // NOI18N\n                ref = f;\n\n                break;\n            }\n        }\n\n        Set<Instance> results = new HashSet<>();\n        @SuppressWarnings(\"unchecked\")\n        Collection<GCRoot> roots = heap.getGCRoots();\n        Set<Instance> marked = new HashSet<>();\n        Deque<Instance> fifo = new ArrayDeque<>();\n\n        for (GCRoot r : roots) {\n            Instance curr = r.getInstance();\n\n            if (!objSet.contains(curr)) {\n                fifo.add(curr);\n            }\n        }\n\n        while (!fifo.isEmpty()) {\n            Instance curr = fifo.removeFirst();\n\n            if (!marked.add(curr)) {\n                continue;\n            }\n\n            for (FieldValue fv : curr.getFieldValues()) {\n\n                // skip weak references\n                if (fv.getField().equals(ref)) {\n                    continue;\n                }\n\n                // \n                if (fv instanceof ObjectFieldValue) {\n                    Instance neu = ((ObjectFieldValue) fv).getInstance();\n\n                    if ((neu != null) && !objSet.contains(neu)) {\n                        fifo.add(neu);\n                    }\n                }\n            }\n\n            if (curr instanceof ObjectArrayInstance) {\n                for (Instance neu : ((ObjectArrayInstance) curr).getValues()) {\n                    if ((neu != null) && !objSet.contains(neu)) {\n                        fifo.add(neu);\n                    }\n                }\n            }\n        }\n\n        // now find what we can reach from 'in'\n        fifo.addAll(objSet);\n        results.addAll(objSet);\n\n        while (!fifo.isEmpty()) {\n            Instance curr = fifo.removeFirst();\n\n            for (FieldValue fv : curr.getFieldValues()) {\n\n                // skip weak references\n                if (fv.getField().equals(ref)) {\n                    continue;\n                }\n\n                // \n                if (fv instanceof ObjectFieldValue) {\n                    Instance neu = ((ObjectFieldValue) fv).getInstance();\n\n                    if ((neu != null) && !marked.contains(neu)) {\n                        if (results.add(neu)) {\n                            fifo.add(neu);\n                        }\n                    }\n                }\n            }\n        }\n\n        return results;\n    }\n\n    /** Computes object set retained by some object.\n     */\n    public static Set<Instance> getRetainedSet(Instance in, Heap heap) {\n        return getRetainedSet(Collections.singleton(in), heap);\n    }\n\n    /** Perform BFS of incomming references and find shortest one not from SDK\n     */\n    public static String getRootIncommingString(Instance in) {\n        String temp = null;\n\n        for (;;) {\n            in = in.getNearestGCRootPointer();\n\n            if (in == null) {\n                break;\n            }\n\n            String rName = in.getJavaClass().getName();\n\n            if (temp == null) {\n                temp = \"<< \" + rName; // there is at least some incoming ref\n            }\n\n            if (!rName.startsWith(\"java.\") && !rName.startsWith(\"javax.\")) {\n                return rName;\n            }\n\n            if (in.isGCRoot()) {\n                break;\n            }\n        }\n\n        return (temp == null) ? \"unknown\" : temp;\n    }\n\n    // Perform BFS of incomming references and find shortest one not from SDK\n    public static String getSignificantIncommingString(Instance in) {\n        Set<Instance> processed = new HashSet<>();\n        String temp = null;\n        Deque<Instance> fifo = new ArrayDeque<>();\n        fifo.add(in);\n\n        while (!fifo.isEmpty()) {\n            if (fifo.size() > 10) {\n                Logger.getLogger(Utils.class.getName()).log(Level.FINE, \"overflow in getSignificantIncommingString({0})\", new Object[] { in });\n\n                break;\n            }\n\n            Instance act = fifo.removeFirst();\n            @SuppressWarnings(\"unchecked\")\n            List<Value> incoming = act.getReferences();\n\n            for (Value v : incoming) {\n                String rName = v.getDefiningInstance().getJavaClass().getName();\n\n                if (temp == null) {\n                    temp = \"<< \" + rName; // there is at least some incoming ref\n                }\n\n                if (rName.startsWith(\"java.\") || rName.startsWith(\"javax.\")) { // NOI18N\n                    Instance i = v.getDefiningInstance();\n\n                    if (processed.add(i)) {\n                        fifo.add(i);\n                    }\n                } else { // Bingo!\n\n                    return rName;\n                }\n            }\n        }\n\n        return (temp == null) ? \"unknown\" : temp; // NOI18N\n    }\n\n    public static String printClass(MemoryLint context, String cls) {\n        if (cls.startsWith(\"<< \")) { // NOI18N\n            cls = cls.substring(\"<< \".length()); // NOI18N\n        }\n\n        if (\"unknown\".equals(cls)) { // NOI18N\n            return NbBundle.getMessage(Utils.class, \"LBL_UnknownClass\");\n        }\n\n        String fullName = cls;\n        String dispName = cls;\n        String field = \"\"; // NOI18N\n\n        // now you can wrap it with a/href to given class\n        int dotIdx = cls.lastIndexOf('.');\n        int colonIdx = cls.lastIndexOf(':');\n\n        if (colonIdx == -1) {\n            colonIdx = cls.lastIndexOf(';');\n        }\n\n        if (colonIdx > 0) {\n            fullName = cls.substring(0, colonIdx);\n            field = \".\" + cls.substring(colonIdx + 1);\n        }\n\n        dispName = fullName.substring(dotIdx + 1);\n\n        return \"<a href='file://class/\" + fullName + \"'>\" + dispName + \"</a>\" + field; // NOI18N\n    }\n\n    public static String printInstance(Instance in) {\n        String className = in.getJavaClass().getName();\n        return \"<a href='file://instance/\" + className + \"/\" + in.getInstanceNumber() + \"'>\" + className + '#' + in.getInstanceNumber() + \"</a>\"; // NOI18N\n//        return in.getJavaClass().getName() + '@' + Long.toHexString(in.getInstanceId()) + '#' + in.getInstanceNumber();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/Walker.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint;\n\nimport java.util.ArrayDeque;\nimport java.util.List;\nimport java.util.Queue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Type;\n\n\n/**\n * An utility class capable of walking the object graph and counting all\n * found objects.\n *\n * @param T the entry type, which can add additional properties\n * @author nenik\n */\npublic final class Walker {\n    //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------\n\n    private static final Type OBJECT = new Type() {\n        public String getName() { return \"object\"; }\n    };\n\n    private static class ArrayEntryValue implements ObjectFieldValue, Field {\n        int idx;\n        private Instance src;\n        private Instance target;\n\n        ArrayEntryValue(int idx, Instance src, Instance target) {\n            this.idx = idx;\n            this.src = src;\n            this.target = target;\n        }\n\n        public Instance getInstance() {\n            return target;\n        }\n\n        public Field getField() {\n            return this;\n        }\n\n        public String getValue() {\n            return \"Instance #\" + target.getInstanceId();\n        }\n\n        public Instance getDefiningInstance() {\n            return src;\n        }\n\n        public JavaClass getDeclaringClass() {\n            return src.getJavaClass(); // XXX\n        }\n\n        public String getName() {\n            return \"[\" + idx + \"]\";\n        }\n\n        public boolean isStatic() {\n            return false;\n        }\n\n        public Type getType() {\n            return OBJECT;\n        }\n        \n    }\n    \n    public static interface Filter {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public boolean accept(ObjectFieldValue val);\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Distribution log = new Distribution();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public Walker() {\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public Distribution getResults() {\n        return log;\n    }\n\n    public void walk(Instance in) {\n        walk(in, null);\n    }\n\n    public void walk(Instance in, Filter f) {\n        Queue<Instance> q = new ArrayDeque<>();\n        q.add(in);\n\n        log.add(in);\n\n        while (!q.isEmpty()) {\n            Instance act = q.poll();\n            \n            if (act instanceof ObjectArrayInstance) {\n                List<Instance> out = ((ObjectArrayInstance)act).getValues();\n                int i = 0;\n                for (Instance target : out) {\n                    if (target != null) {\n                        if ((f == null || f.accept(new ArrayEntryValue(i, act, target))) && !log.isCounted(target)) {\n                            log.add(target);\n                            q.add(target);\n                        }\n                    }\n                    i++;\n                }\n            }\n\n            List<FieldValue> out = act.getFieldValues();\n\n            for (FieldValue fv : out) {\n                if (fv instanceof ObjectFieldValue) {\n                    ObjectFieldValue ofv = (ObjectFieldValue) fv;\n\n                    if ((f != null) && !f.accept(ofv)) {\n                        continue;\n                    }\n\n                    Instance target = ofv.getInstance();\n\n                    if ((target != null) && !log.isCounted(target)) {\n                        log.add(target);\n                        q.add(target);\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/rules/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n# Shared entry\nLBL_ClassName=Class name:\n\n\nLBL_DS_Name=Reachable size\nLBL_DS_Desc=Computes deep size of all instances of given class\nLBL_DS_LongDesc=<html><body>Computes reachable (deep) size of all instances of given class.</body></html>\nLBL_DS_ResHeader=<h2>Reachable size (all instances of {0})</h2>\n\nLBL_DupStr_Name=Duplicated Strings\nLBL_DupStr_Desc=Find String duplicates and measure their cost\nLBL_DupStr_LongDesc=<html><body>Computes total memory wasted by duplicated \\\n<code>String</code>s and tries to identify their referrers.</body></html>\nFMT_DupStr_Result=<b>Total waste: {0}B</b>, distributed by domain source:<br>\n\nLBL_HMH_Name=HashMap histograms\nLBL_HMH_Desc=Scans all HashMap instances and prints statistics of their usage\nLBL_HMH_LongDesc=<html><body>Computes memory used by <code>HashMap</code> \\\nstructures and <code>String</code>s referenced from the <code>HashMap</code>s.</body></html>\n\nLBL_OverStr_Name=Overallocated Strings\nLBL_OverStr_Desc=Covers long living results of String.substring(), computes amount of wasted memory\nLBL_OverStr_LongDesc=<html><body>Computes overhead of <code>String</code>s that \\\nhave their backing <code>char[]</code> larger than necessary (for example \\\nresult of <code>String.substring()</code>).</body></html>\nFMT_OverStr_Result=<b>Wasted {0}B</b> on overallocated Strings<br>\n\nLBL_RSBC_Name=Retained sets by class histograms\nLBL_RSBC_Desc=Prints histogram of retained set held by every class\nLBL_RSBC_LongDesc=<html><body><b>Warning!</b><br><br>This rule takes a long \\\ntime to compute and can use a big amout of memory on large heaps!</body></html>\n\nLBL_RSBI_Name=Histograms of retained sets\nLBL_RSBI_Desc=Prints histogram of retained set held by instances of class\nLBL_RSBI_LongDesc=<html><body>Computes retained set for each instance of given class.</body></html>\n\nLBL_TMB_Name=Too many Booleans\nLBL_TMB_Desc=Checks instances of Boolean other than Boolean.TRUE and Boolean.FALSE\nLBL_TMB_LongDesc=<html><body>Checks if there are more than two instances of \\\n<code>Boolean</code> on the heap (only <code>Boolean.TRUE</code> and \\\n<code>Boolean.FALSE</code> are necessary).</body></html>\nFMT_TMB_Result=There are {0} Boolean instances wasting {1}B<br>\nFMT_TMB_ResultOK=There are not more than two Boolean instances: OK\n\n\nLBL_WWHM_Name=Leaking WeakHashMap\nLBL_WWHM_Desc=WeakHashMap with values strong referencing the keys\nLBL_WWHM_LongDesc=<html><body>Identifies improperly used <code>WeakHashMap</code>s \\\nwhere a value strongly references its key.</body></html>\nFMT_WWHM_Entry={0}: {1} is wrong: key {2} is reachable from value {3}<br>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/rules/CollapsedHashMap.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.rules;\n\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.*;\nimport org.openide.util.NbBundle;\n\n@NbBundle.Messages({\n    \"LBL_CHM_Name=Collapsed (Weak)HashMaps\",\n    \"LBL_CHM_Desc=HashMaps populated by entries with poorly distributed hashcode\",\n    \"LBL_CHM_LongDesc=<html><body>This rule checks for (<code>Weak</code>)<code>\" +\n    \"HashMap</code>s that have bad distribution of entries among allocated buckets,\" +\n    \"like in the illustration: <br><img src='res/wrongmap.png'><br> This can be \" +\n    \"caused by bad implementation of <code>hashcode()</code> or \" +\n    \"<code>equals()</code> methods of the objects used as map keys</body></html>\",\n    \"FMT_CHM_Record={0}: {1} {2,number} entries are allocated to \" +\n    \"{3,choice,1#'<b>one bucket</b>'|2#{3,number,integer} buckets}\"\n})\n//@org.openide.util.lookup.ServiceProvider(service=org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.Rule.class)\npublic class CollapsedHashMap extends IteratingRule {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private class HMRecord {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private Instance hm;\n        private int size;\n        private int slots;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        HMRecord(Instance hm, int size, int slots) {\n            this.hm = hm;\n            this.size = size;\n            this.slots = slots;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        @Override\n        public String toString() {\n            boolean reallyBad = slots == 1;\n            return Bundle.FMT_CHM_Record(\n                        Utils.printClass(getContext(), getContext().getRootIncommingString(hm)),\n                        Utils.printInstance(hm),\n                        size,\n                        slots\n                    );\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private FieldAccess fldHMSize;\n    private FieldAccess fldHMTable;\n    private FieldAccess fldWHMSize;\n    private FieldAccess fldWHMTable;\n    private JavaClass clsHM;\n    private JavaClass clsWHM;\n    private Set<HMRecord> poorHM = new HashSet<>();\n\n    /** Threshold for count of chained entries to raise the warning */\n    private float ratio = 1.5f;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public CollapsedHashMap() {\n        super(Bundle.LBL_CHM_Name(),\n                Bundle.LBL_CHM_Desc(),\n                \"java.util.HashMap|java.util.WeakHashMap\"); // NOI18N\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    public String getHTMLDescription() {\n        return Bundle.LBL_CHM_LongDesc();\n    }\n\n    public void setRatio(float ratio) {\n        this.ratio = ratio;\n    }\n\n    @Override\n    protected void perform(Instance hm) {\n        if (clsHM.equals(hm.getJavaClass())) {\n            scanHashmap(hm, fldHMSize, fldHMTable);\n        } else {\n            scanHashmap(hm, fldWHMSize, fldWHMTable);\n        }\n    }\n\n    @Override\n    protected void prepareRule(MemoryLint context) {\n        Heap heap = context.getHeap();\n        clsHM = heap.getJavaClassByName(\"java.util.HashMap\"); // NOI18N\n        fldHMTable = new FieldAccess(clsHM, \"table\"); // NOI18N\n        fldHMSize = new FieldAccess(clsHM, \"size\"); // NOI18N\n        clsWHM = heap.getJavaClassByName(\"java.util.WeakHashMap\"); // NOI18N\n        fldWHMTable = new FieldAccess(clsWHM, \"table\"); // NOI18N\n        fldWHMSize = new FieldAccess(clsWHM, \"size\"); // NOI18N\n    }\n\n    @Override\n    protected void summary() {\n        for (HMRecord hm : poorHM) {\n            getContext().appendResults(hm.toString() + \"<br>\"); // NOI18N\n        }\n    }\n\n    private void scanHashmap(Instance hm, FieldAccess sizeAccess, FieldAccess tableAccess) {\n        int size = sizeAccess.getIntValue(hm);\n\n        if (size < 5) {\n            return; // not really significant\n        }\n\n        ObjectArrayInstance table = (ObjectArrayInstance) tableAccess.getRefValue(hm);\n\n        if (table != null) {\n            int slots = 0;\n            @SuppressWarnings(\"unchecked\")\n            List<Instance> tval = table.getValues();\n\n            for (Instance entry : tval) {\n                if (entry != null) {\n                    slots++;\n                }\n            }\n\n            if (slots > 0 && (size / slots) > ratio) {\n                poorHM.add(new HMRecord(hm, size, slots));\n            }\n        }\n\n        return;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/rules/DeepSize.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.rules;\n\nimport javax.swing.BorderFactory;\nimport javax.swing.BoxLayout;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTextField;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.*;\nimport org.openide.util.NbBundle;\n\n\n//@org.openide.util.lookup.ServiceProvider(service=org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.Rule.class)\npublic class DeepSize extends IteratingRule {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private class Customizer extends JPanel {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        JTextField txtFld;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        Customizer() {\n            setOpaque(false);\n            setLayout(new BoxLayout(this, BoxLayout.X_AXIS));\n            JLabel caption = new JLabel(NbBundle.getMessage(DeepSize.class, \"LBL_ClassName\"));\n            caption.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));\n            add(caption);\n            txtFld = new JTextField(className, 15);\n            txtFld.getDocument().addDocumentListener(new DocumentListener() {\n                    public void changedUpdate(DocumentEvent e) {\n                        className = txtFld.getText();\n                    }\n\n                    public void insertUpdate(DocumentEvent e) {\n                        className = txtFld.getText();\n                    }\n\n                    public void removeUpdate(DocumentEvent e) {\n                        className = txtFld.getText();\n                    }\n                });\n            add(txtFld);\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    Walker walker;\n    private static String className = \"java.io.File\"; // NOI18N\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public DeepSize() {\n        super(NbBundle.getMessage(DeepSize.class, \"LBL_DS_Name\"),\n                NbBundle.getMessage(DeepSize.class, \"LBL_DS_Desc\"),\n                \"\"); // NOI18N\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    @Override\n    public String getHTMLDescription() {\n        return NbBundle.getMessage(DeepSize.class, \"LBL_DS_LongDesc\");\n    }\n\n    @Override\n    protected JComponent createCustomizer() {\n        return new Customizer();\n    }\n\n    protected void perform(Instance hm) {\n        walker.walk(hm);\n    }\n\n    protected @Override void prepareRule(MemoryLint context) {\n        setClassNamePattern(className);\n        walker = new Walker();\n    }\n\n    @Override\n    protected String resultsHeader() {\n        return NbBundle.getMessage(DeepSize.class, \"LBL_DS_ResHeader\", Utils.printClass(getContext(), className));\n    }\n\n    protected @Override void summary() {\n        Distribution res = walker.getResults();\n        String str = res.toString();\n        str = str.replace(\"\\n\", \"<br>\"); // NOI18N\n        str = str.replace(\"  \", \"&nbsp;&nbsp;\"); // NOI18N\n        getContext().appendResults(str);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/rules/DuplicatedString.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.rules;\n\nimport java.util.HashMap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.*;\nimport org.openide.util.NbBundle;\n\n\n//@org.openide.util.lookup.ServiceProvider(service=org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.Rule.class)\npublic class DuplicatedString extends IteratingRule {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private FieldAccess fldValue;\n    private HashMap<String, Integer> map = new HashMap<>();\n    private Histogram<Histogram.Entry> dupSources = new Histogram<>();\n    private StringHelper helper;\n    private int total;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public DuplicatedString() {\n        super(NbBundle.getMessage(DuplicatedString.class, \"LBL_DupStr_Name\"),\n                NbBundle.getMessage(DuplicatedString.class, \"LBL_DupStr_Desc\"),\n                \"java.lang.String\"); // NOI18N\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    public String getHTMLDescription() {\n        return NbBundle.getMessage(DuplicatedString.class, \"LBL_DupStr_LongDesc\");\n    }\n\n    protected void perform(Instance in) {\n        String str = helper.decodeString(in);\n        Integer val = map.get(str);\n\n        if (val != null) { // already known, histogram the rest.\n\n            long strSize = in.getSize();\n            Instance arr = fldValue.getRefValue(in);\n\n            if (arr != null) {\n                strSize += ((str.length() * 2) + 14); // XXX aproximation\n            }\n\n            String incomming = getContext().getRootIncommingString(in);\n            incomming = Utils.printClass(getContext(), incomming);\n            dupSources.add(incomming, new Histogram.Entry(strSize));\n            total += strSize;\n        }\n\n        val = (val == null) ? 1 : (val + 1);\n        map.put(str, val);\n    }\n\n    protected @Override void prepareRule(MemoryLint context) {\n        Heap heap = context.getHeap();\n        helper = context.getStringHelper();\n\n        JavaClass clsString = heap.getJavaClassByName(\"java.lang.String\"); // NOI18N\n        fldValue = new FieldAccess(clsString, \"value\"); // NOI18N\n    }\n\n    protected @Override void summary() {\n        getContext().appendResults(NbBundle.getMessage(DuplicatedString.class, \"FMT_DupStr_Result\", total));\n        getContext().appendResults(dupSources.toString(50000));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/rules/HashMapHistogram.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.rules;\n\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.*;\nimport org.openide.util.NbBundle;\n\n\n//@org.openide.util.lookup.ServiceProvider(service=org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.Rule.class)\npublic class HashMapHistogram extends IteratingRule {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private static class HashmapEntry extends Histogram.Entry<HashmapEntry> {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        int hmeCount;\n        int strCount;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        HashmapEntry(long size, int hmeCount, int strCount) {\n            super(size);\n            this.hmeCount = hmeCount;\n            this.strCount = strCount;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        @Override\n        public String toString() {\n            return \"#:\" + getCount() + \"/\" + getSize() + \"B, \" + hmeCount + \" HMEs, \" + strCount + \" Strings<br>\"; // NOI18N\n        }\n\n        @Override\n        protected void add(HashmapEntry source) {\n            hmeCount += source.hmeCount;\n            strCount += source.strCount;\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private FieldAccess fldHMEKey;\n    private FieldAccess fldHMENext;\n    private FieldAccess fldHMEValue;\n    private FieldAccess fldHMTable;\n    private FieldAccess fldSValue;\n    private Histogram<HashmapEntry> byIncomming;\n    private JavaClass clsHM;\n    private JavaClass clsHME;\n    private JavaClass clsString;\n    private Set<Instance> known = new HashSet<>();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public HashMapHistogram() {\n        super(NbBundle.getMessage(HashMapHistogram.class, \"LBL_HMH_Name\"),\n                NbBundle.getMessage(HashMapHistogram.class, \"LBL_HMH_Desc\"),\n                \"java.util.HashMap\"); // NOI18N\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    @Override\n    public String getHTMLDescription() {\n        return NbBundle.getMessage(HashMapHistogram.class, \"LBL_HMH_LongDesc\");\n    }\n\n    protected void perform(Instance hm) {\n        HashmapEntry he = sizeOfHashmap(hm);\n        String incomming = getContext().getRootIncommingString(hm);\n        incomming = Utils.printClass(getContext(), incomming);\n        byIncomming.add(incomming, he);\n    }\n\n    protected @Override void prepareRule(MemoryLint context) {\n        Heap heap = context.getHeap();\n        clsString = heap.getJavaClassByName(\"java.lang.String\"); // NOI18N\n        clsHM = heap.getJavaClassByName(\"java.util.HashMap\"); // NOI18N\n        clsHME = heap.getJavaClassByName(\"java.util.HashMap$Entry\"); // NOI18N\n        fldSValue = new FieldAccess(clsString, \"value\"); // NOI18N\n        fldHMTable = new FieldAccess(clsHM, \"table\"); // NOI18N\n        fldHMEKey = new FieldAccess(clsHME, \"key\"); // NOI18N\n        fldHMEValue = new FieldAccess(clsHME, \"value\"); // NOI18N\n        fldHMENext = new FieldAccess(clsHME, \"next\"); // NOI18N\n        byIncomming = new Histogram<>();\n    }\n\n    protected @Override void summary() {\n        getContext().appendResults(byIncomming.toString(50000));\n    }\n\n    private boolean add(Instance inst) {\n        if (known.contains(inst)) {\n            return false;\n        }\n\n        known.add(inst);\n\n        return true;\n    }\n\n    private long sizeIfNewString(Instance obj) {\n        if (obj == null) {\n            return 0;\n        }\n\n        if (\"java.lang.String\".equals(obj.getJavaClass().getName())) { // NOI18N\n            if (add(obj)) {\n                long sz = obj.getSize();\n                Instance arr = fldSValue.getRefValue(obj);\n\n                if ((arr != null) && add(arr)) {\n                    sz += arr.getSize();\n                }\n\n                return sz;\n            }\n        }\n\n        return 0;\n    }\n\n    private HashmapEntry sizeOfHashmap(Instance hm) {\n        ObjectArrayInstance table = (ObjectArrayInstance) fldHMTable.getRefValue(hm);\n        long sum = hm.getSize() + table.getSize();\n        int hmeCount = 0;\n        int strCount = 0;\n\n        List<Instance> tval = table.getValues();\n\n        for (Instance entry : tval) {\n            while (entry != null) {\n                hmeCount++;\n                sum += entry.getSize(); // size of entry\n\n                long sz = sizeIfNewString(fldHMEKey.getRefValue(entry));\n\n                if (sz != 0) {\n                    strCount++;\n                }\n\n                sum += sz;\n                sz = sizeIfNewString(fldHMEValue.getRefValue(entry));\n\n                if (sz != 0) {\n                    strCount++;\n                }\n\n                sum += sz;\n                entry = fldHMENext.getRefValue(entry);\n            }\n        }\n\n        HashmapEntry hme = new HashmapEntry(sum, hmeCount, strCount);\n\n        return hme;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/rules/OverallocatedString.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.rules;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.*;\nimport org.openide.util.NbBundle;\n\n\n//@org.openide.util.lookup.ServiceProvider(service=org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.Rule.class)\npublic class OverallocatedString extends IteratingRule {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private FieldAccess fldCount;\n    private FieldAccess fldOffset;\n    private FieldAccess fldValue;\n    private JavaClass clsString;\n    private Map<Instance, Integer> covered = new HashMap<>();\n    private int total;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public OverallocatedString() {\n        super(NbBundle.getMessage(OverallocatedString.class, \"LBL_OverStr_Name\"),\n                NbBundle.getMessage(OverallocatedString.class, \"LBL_OverStr_Desc\"),\n                \"java.lang.String\"); // NOI18N\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    public String getHTMLDescription() {\n        return NbBundle.getMessage(OverallocatedString.class, \"LBL_OverStr_LongDesc\");\n    }\n\n    protected void perform(Instance in) {\n        int off = fldOffset.getIntValue(in);\n        int cnt = fldCount.getIntValue(in);\n        PrimitiveArrayInstance arrValue = (PrimitiveArrayInstance) fldValue.getRefValue(in);\n\n        if (arrValue == null) {\n            return; // empty\n        }\n\n        if ((off > 0) || (arrValue.getLength() > cnt)) {\n            if (covered.containsKey(arrValue)) {\n                // simplification - don't track shared char arrays\n                total -= covered.remove(arrValue);\n            } else {\n                int waste = (2 * off) + (2 * (arrValue.getLength() - (cnt + off)));\n                covered.put(arrValue, waste);\n                total += waste;\n            }\n        }\n    }\n\n    protected void prepareRule(MemoryLint context) {\n        Heap heap = context.getHeap();\n        clsString = heap.getJavaClassByName(\"java.lang.String\"); // NOI18N\n        fldOffset = new FieldAccess(clsString, \"offset\"); // NOI18N\n        fldCount = new FieldAccess(clsString, \"count\"); // NOI18N\n        fldValue = new FieldAccess(clsString, \"value\"); // NOI18N\n    }\n\n    @Override\n    protected void summary() {\n        getContext().appendResults(NbBundle.getMessage(OverallocatedString.class, \"FMT_OverStr_Result\", total));\n\n        Histogram<Histogram.Entry> h = new Histogram<>();\n\n        for (Map.Entry<Instance, Integer> e : covered.entrySet()) {\n            String incomming = getContext().getRootIncommingString(e.getKey());\n            incomming = Utils.printClass(getContext(), incomming);\n            h.add(incomming, new Histogram.Entry(e.getValue()));\n        }\n\n        getContext().appendResults(h.toString(5000));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/rules/RetainedSetByClass.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.rules;\n\nimport java.util.List;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.JComponent;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.*;\nimport org.openide.util.NbBundle;\n\n\npublic class RetainedSetByClass extends Rule {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private MemoryLint context;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public RetainedSetByClass() {\n        super(NbBundle.getMessage(RetainedSetByClass.class, \"LBL_RSBC_Name\"),\n                NbBundle.getMessage(RetainedSetByClass.class, \"LBL_RSBC_Desc\"));\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    public String getHTMLDescription() {\n        return NbBundle.getMessage(RetainedSetByClass.class, \"LBL_RSBC_LongDesc\");\n    }\n\n    public void perform() {\n        Heap heap = context.getHeap();\n        @SuppressWarnings(\"unchecked\")\n        List<JavaClass> classes = heap.getAllClasses();\n\n        // TODO access to progress\n        //        BoundedRangeModel progress = context.getProgress();\n        //        progress.setMaximum(classes.size());\n        Histogram<Histogram.Entry> hist = new Histogram<>();\n\n        for (JavaClass cls : classes) {\n            Logger.getLogger(RetainedSetByClass.class.getName()).log(Level.FINE, \"Executing rule on class {0}.\", cls); // NOI18N\n            performClass(cls, hist);\n\n            if (context.isInterruped()) {\n                return;\n            }\n\n            // TODO access to progress\n            //            progress.setValue(progress.getValue()+1);\n        }\n\n        summary(hist);\n    }\n\n    @Override\n    public void prepare(MemoryLint context) {\n        this.context = context;\n    }\n\n    @Override\n    protected JComponent createCustomizer() {\n        return null;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private void performClass(JavaClass clz, Histogram<Histogram.Entry> hist) {\n        Set<Instance> retained = Utils.getRetainedSet(clz.getInstances(), context.getHeap());\n        String name = clz.getName();\n        name = Utils.printClass(context, name);\n\n        for (Instance i : retained) {\n            hist.add(name, new Histogram.Entry<>(i.getSize()));\n        }\n    }\n\n    private void summary(Histogram h) {\n//        context.appendResults(\"<hr>Histogram of retained size:<br>\");\n        context.appendResults(h.toString(0));\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/rules/RetainedSetByInstance.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.rules;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.BoxLayout;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTextField;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.*;\nimport org.openide.util.NbBundle;\n\n\n//@org.openide.util.lookup.ServiceProvider(service=org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.Rule.class)\npublic class RetainedSetByInstance extends IteratingRule {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private class Customizer extends JPanel {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        JTextField txtFld;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        Customizer() {\n            setLayout(new BoxLayout(this, BoxLayout.X_AXIS));\n            JLabel caption = new JLabel(NbBundle.getMessage(RetainedSetByInstance.class, \"LBL_ClassName\"));\n            caption.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));\n            add(caption);\n            txtFld = new JTextField(CLASSNAME, 15);\n            txtFld.getDocument().addDocumentListener(new DocumentListener() {\n                    public void changedUpdate(DocumentEvent e) {\n                        RetainedSetByInstance.this.updateClassName(txtFld.getText());\n                    }\n\n                    public void insertUpdate(DocumentEvent e) {\n                        RetainedSetByInstance.this.updateClassName(txtFld.getText());\n                    }\n\n                    public void removeUpdate(DocumentEvent e) {\n                        RetainedSetByInstance.this.updateClassName(txtFld.getText());\n                    }\n                });\n            add(txtFld);\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    private static String CLASSNAME = \"java.io.File\";  // NOI18N\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private Heap heap;\n    private Set<Histogram> allDocs = new HashSet<>();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public RetainedSetByInstance() {\n        super(NbBundle.getMessage(RetainedSetByInstance.class, \"LBL_RSBI_Name\"),\n                NbBundle.getMessage(RetainedSetByInstance.class, \"LBL_RSBI_Desc\"),\n                CLASSNAME);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    @Override\n    public String getHTMLDescription() {\n        return NbBundle.getMessage(RetainedSetByInstance.class, \"LBL_RSBI_LongDesc\");\n    }\n\n    public void perform(Instance hm) {\n        Set<Instance> retained = Utils.getRetainedSet(hm, heap);\n        Histogram<Histogram.Entry> hist = new Histogram<>();\n\n        for (Instance i : retained) {\n            String key = Utils.printClass(getContext(), i.getJavaClass().getName());\n            hist.add(key, new Histogram.Entry(i.getSize()));\n        }\n\n        allDocs.add(hist);\n    }\n\n    @Override\n    protected JComponent createCustomizer() {\n        return new Customizer();\n    }\n\n    @Override\n    protected void prepareRule(MemoryLint context) {\n        heap = context.getHeap();\n    }\n    \n    @Override\n    protected String resultsHeader() {\n        return \"<h2>\" + getDisplayName() + \" (\" + Utils.printClass(getContext(), CLASSNAME) + \")</h2>\"; // NOI18N\n    }\n\n    @Override\n    protected void summary() {\n        for (Histogram h : allDocs) {\n//            getContext().appendResults(\"<hr>Histogram of retained size:<br>\");\n            getContext().appendResults(h.toString(0));\n        }\n    }\n\n    void updateClassName(String className) {\n        CLASSNAME = className;\n        setClassNamePattern(className);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/rules/TooManyBooleans.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.rules;\n\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.*;\nimport org.openide.util.NbBundle;\n\n\n//@org.openide.util.lookup.ServiceProvider(service=org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.Rule.class)\npublic class TooManyBooleans extends IteratingRule {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    Histogram<Histogram.Entry> booleans = new Histogram<>();\n    private Heap heap;\n    private Instance FALSE;\n    private Instance TRUE;\n    private StringHelper helper;\n    private int count;\n    private int total;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public TooManyBooleans() {\n        super(NbBundle.getMessage(TooManyBooleans.class, \"LBL_TMB_Name\"),\n                NbBundle.getMessage(TooManyBooleans.class, \"LBL_TMB_Desc\"),\n                \"java.lang.Boolean\"); // NOI18N\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    @Override\n    public String getHTMLDescription() {\n        return NbBundle.getMessage(TooManyBooleans.class, \"LBL_TMB_LongDesc\");\n    }\n\n    protected void perform(Instance in) {\n        if (in.equals(TRUE) || in.equals(FALSE)) {\n            return;\n        }\n\n        count++;\n        booleans.add(Utils.printClass(getContext(), getContext().getRootIncommingString(in)), new Histogram.Entry(in.getSize()));\n    }\n\n    protected @Override void prepareRule(MemoryLint context) {\n        heap = context.getHeap();\n        helper = context.getStringHelper();\n\n        JavaClass booleanClass = heap.getJavaClassByName(\"java.lang.Boolean\"); // NOI18N\n        TRUE = (Instance) booleanClass.getValueOfStaticField(\"TRUE\"); // NOI18N\n        FALSE = (Instance) booleanClass.getValueOfStaticField(\"FALSE\"); // NOI18N\n    }\n\n    protected @Override void summary() {\n        if (count > 0) {\n            getContext().appendResults(\n                    NbBundle.getMessage(TooManyBooleans.class, \"FMT_TMB_Result\", count+2, (count * TRUE.getSize())));\n            getContext().appendResults(booleans.toString(0));\n        } else {\n            getContext().appendResults(NbBundle.getMessage(TooManyBooleans.class, \"FMT_TMB_ResultOK\"));\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/memorylint/rules/WrongWeakHashMap.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.rules;\n\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.*;\nimport org.openide.util.NbBundle;\n\n\n//@org.openide.util.lookup.ServiceProvider(service=org.graalvm.visualvm.lib.profiler.heapwalk.memorylint.Rule.class)\npublic class WrongWeakHashMap extends IteratingRule {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    private class WHMRecord {\n        //~ Instance fields ------------------------------------------------------------------------------------------------------\n\n        private Instance hm;\n        private Instance key;\n        private Instance value;\n\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        WHMRecord(Instance hm, Instance key, Instance value) {\n            this.hm = hm;\n            this.key = key;\n            this.value = value;\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        @Override\n        public String toString() {\n            return NbBundle.getMessage(WrongWeakHashMap.class, \"FMT_WWHM_Entry\",\n                    new Object[] {\n                        Utils.printClass(getContext(), getContext().getRootIncommingString(hm)),\n                        Utils.printInstance(hm),\n                        Utils.printInstance(key),\n                        Utils.printInstance(value)\n                    }\n            );\n        }\n    }\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private FieldAccess fldHMEKey;\n    private FieldAccess fldHMENext;\n    private FieldAccess fldHMEValue;\n    private FieldAccess fldHMTable;\n    private JavaClass clsHM;\n    private JavaClass clsHME;\n    private Set<WHMRecord> poorWHM = new HashSet<>();\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public WrongWeakHashMap() {\n        super(NbBundle.getMessage(WrongWeakHashMap.class, \"LBL_WWHM_Name\"),\n                NbBundle.getMessage(WrongWeakHashMap.class, \"LBL_WWHM_Desc\"),\n                \"java.util.WeakHashMap\");\n        \n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    @Override\n    public String getHTMLDescription() {\n        return NbBundle.getMessage(WrongWeakHashMap.class, \"LBL_WWHM_LongDesc\");\n    }\n\n    protected void perform(Instance hm) {\n        scanWeakHashmap(hm);\n    }\n\n    @Override\n    protected void prepareRule(MemoryLint context) {\n        // TODO WeakHashMap might not be present in the dump\n        Heap heap = context.getHeap();\n        clsHM = heap.getJavaClassByName(\"java.util.WeakHashMap\"); // NOI18N\n        clsHME = heap.getJavaClassByName(\"java.util.WeakHashMap$Entry\"); // NOI18N\n        fldHMTable = new FieldAccess(clsHM, \"table\"); // NOI18N\n\n        JavaClass ref = heap.getJavaClassByName(\"java.lang.ref.Reference\"); // NOI18N\n        fldHMEKey = new FieldAccess(ref, \"referent\"); // NOI18N\n        fldHMEValue = new FieldAccess(clsHME, \"value\"); // NOI18N\n        fldHMENext = new FieldAccess(clsHME, \"next\"); // NOI18N\n    }\n\n    @Override\n    protected void summary() {\n        for (WHMRecord whm : poorWHM) {\n            getContext().appendResults(whm.toString());\n        }\n    }\n\n    private void scanWeakHashmap(Instance hm) {\n        ObjectArrayInstance table = (ObjectArrayInstance) fldHMTable.getRefValue(hm);\n\n        if (table == null) { // ? \n\n            return;\n        }\n\n        @SuppressWarnings(\"unchecked\")\n        List<Instance> tval = table.getValues();\n\n        for (Instance entry : tval) {\n            while (entry != null) {\n                Instance key = fldHMEKey.getRefValue(entry);\n\n                if (key != null) { // XXX can also scan for weak HM pending cleanup\n\n                    Instance value = fldHMEValue.getRefValue(entry);\n\n                    if (Utils.isReachableFrom(value, key)) {\n                        poorWHM.add(new WHMRecord(hm, key, value));\n\n                        return;\n                    }\n                }\n\n                entry = fldHMENext.getRefValue(entry);\n            }\n        }\n\n        return;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/model/BrowserUtils.java",
    "content": "/*\n * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.heapwalk.model;\n\nimport org.openide.util.RequestProcessor;\n\n\n/**\n * Constants and utilities for Fields Browser\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\npublic class BrowserUtils {\n\n    private static final RequestProcessor REQUEST_PROCESSOR = new RequestProcessor(\"HeapWalker Processor\", 5, true); // NOI18N\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public static String getSimpleType(String fullType) {\n        int simpleTypeIdx = fullType.lastIndexOf('.'); // NOI18N\n\n        if (simpleTypeIdx == -1) {\n            return fullType;\n        } else {\n            if (fullType.startsWith(\"<\")) { // NOI18N\n\n                return \"<\" + fullType.substring(simpleTypeIdx + 1); // NOI18N\n            } else {\n                return fullType.substring(simpleTypeIdx + 1);\n            }\n        }\n    }\n\n    public static RequestProcessor.Task performTask(Runnable task) {\n        return REQUEST_PROCESSOR.post(task);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/ui/icons/HeapWalkerIcons.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons;\n\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface HeapWalkerIcons extends Icons.Keys {\n\n    public static final String CLASSES = \"HeapWalkerIcons.Classes\"; // NOI18N\n    public static final String DATA = \"HeapWalkerIcons.Data\"; // NOI18N\n    public static final String GC_ROOT = \"HeapWalkerIcons.GcRoot\"; // NOI18N\n    public static final String GC_ROOTS = \"HeapWalkerIcons.GcRoots\"; // NOI18N\n    public static final String INCOMING_REFERENCES = \"HeapWalkerIcons.IncomingReferences\"; // NOI18N\n    public static final String INSTANCES = \"HeapWalkerIcons.Instances\"; // NOI18N\n    public static final String LOOP = \"HeapWalkerIcons.Loop\"; // NOI18N\n    public static final String MEMORY_LINT = \"HeapWalkerIcons.MemoryLint\"; // NOI18N\n    public static final String PROGRESS = \"HeapWalkerIcons.Progress\"; // NOI18N\n    public static final String PROPERTIES = \"HeapWalkerIcons.Properties\"; // NOI18N\n    public static final String RULES = \"HeapWalkerIcons.Rules\"; // NOI18N\n    public static final String SAVED_OQL_QUERIES = \"HeapWalkerIcons.SavedOqlQueries\"; // NOI18N\n    public static final String STATIC = \"HeapWalkerIcons.Static\"; // NOI18N\n    public static final String SYSTEM_INFO = \"HeapWalkerIcons.SystemInfo\"; // NOI18N\n    public static final String WINDOW = \"HeapWalkerIcons.Window\"; // NOI18N\n    public static final String BIGGEST_OBJECTS = \"HeapWalkerIcons.BiggestObjects\"; // NOI18N\n    public static final String OQL_CONSOLE = \"HeapWalkerIcons.OQLConsole\"; // NOI18N\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/ui/icons/impl/HeapWalkerIconsProviderImpl.java",
    "content": "/*\n * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.impl;\n\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.profiler.heapwalk.ui.icons.HeapWalkerIcons;\nimport org.graalvm.visualvm.lib.profiler.spi.IconsProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=IconsProvider.class)\npublic final class HeapWalkerIconsProviderImpl extends IconsProvider.Basic {\n\n    @Override\n    protected final void initStaticImages(Map<String, String> cache) {\n        cache.put(HeapWalkerIcons.CLASSES, \"classes.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.DATA, \"data.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.GC_ROOT, \"gcRoot.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.GC_ROOTS, \"gcRoots.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.INCOMING_REFERENCES, \"incomingRef.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.INSTANCES, \"instances.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.LOOP, \"loop.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.MEMORY_LINT, \"memoryLint.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.PROGRESS, \"progress.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.PROPERTIES, \"properties.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.RULES, \"rules.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.SAVED_OQL_QUERIES, \"savedOQL.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.STATIC, \"static.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.SYSTEM_INFO, \"sysinfo.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.WINDOW, \"window.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.BIGGEST_OBJECTS, \"biggestObjects.png\"); // NOI18N\n        cache.put(HeapWalkerIcons.OQL_CONSOLE, \"oqlConsole.png\"); // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalker/Bundle.properties",
    "content": "# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Name=Java Profiler (HeapWalker)\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project basedir=\".\" default=\"netbeans\" name=\"profiler.oql\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.lib.profiler.oql</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nOpenIDE-Module: org.graalvm.visualvm.lib.profiler.oql/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/lib/profiler/oql/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/lib/profiler/oql/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.lib.profiler.oql-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/nbproject/genfiles.properties",
    "content": "# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=a244f046\nnbproject/build-impl.xml.script.CRC32=7264ed56\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/nbproject/project.properties",
    "content": "# Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\nauxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=8\nauxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=80\nauxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=default\nis.autoload=true\njavac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\n\ntest.config.stableBTD.includes=**/*Test.class\ntest.config.stableBTD.excludes=**/OQLEngineTest.class\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.lib.profiler.oql</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid.heap</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.annotations.common</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.9</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <test-dependencies>\n                <test-type>\n                    <name>unit</name>\n                    <test-dependency>\n                        <code-name-base>org.netbeans.libs.junit4</code-name-base>\n                        <compile-dependency/>\n                    </test-dependency>\n                </test-type>\n            </test-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.heapviewer</friend>\n                <friend>org.graalvm.visualvm.modules.oqlsyntax</friend>\n                <friend>org.graalvm.visualvm.lib.profiler.heapwalker</friend>\n                <package>org.graalvm.visualvm.lib.profiler.oql.engine.api</package>\n                <package>org.graalvm.visualvm.lib.profiler.oql.icons</package>\n                <package>org.graalvm.visualvm.lib.profiler.oql.repository.api</package>\n                <package>org.graalvm.visualvm.lib.profiler.oql.spi</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/../..\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Name=Java Profiler (OQL)\n\nServices/MIMEResolver/text-x-oql-mime-resolver.xml=OQL query language\ntext/x-oql=OQL\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/engine/api/OQLEngine.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.oql.engine.api;\n\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.impl.OQLEngineImpl;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.impl.Snapshot;\n\n/**\n * This is Object Query Language Interpreter\n *\n * @author J. Bachorik\n */\nfinal public class OQLEngine {\n    final private static Logger LOGGER = Logger.getLogger(OQLEngine.class.getName());\n    final private OQLEngineImpl delegate;\n    final private Heap heap;\n\n    /**\n     * This represents a parsed OQL query\n     *\n     * @author A. Sundararajan\n     */\n    public static abstract class OQLQuery {\n\n    }\n\n    /**\n     * This visitor is supplied to OQLEngine.executeQuery\n     * to receive result set objects one by one.\n     *\n     * @author A. Sundararajan\n     * @author J. Bachorik\n     */\n    public static interface ObjectVisitor {\n        // return true to terminate the result set callback earlier\n        public boolean visit(Object o);\n\n        public static final ObjectVisitor DEFAULT = new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                if (o != null && LOGGER.isLoggable(Level.FINEST)) LOGGER.finest(o.toString());\n\n                return true; // prevent calling \"visit\" for the rest of the result set\n            }\n        };\n    }\n\n    // check OQL is supported or not before creating OQLEngine\n    public static boolean isOQLSupported() {\n        return OQLEngineImpl.isOQLSupported();\n    }\n\n    public OQLEngine(Heap heap) {\n        delegate = new OQLEngineImpl(new Snapshot(heap, this));\n        this.heap = heap;\n    }\n\n    public Heap getHeap() {\n        return heap;\n    }\n\n    /**\n    Query is of the form\n\n    select &lt;java script code to select&gt;\n    [ from [instanceof] &lt;class name&gt; [&lt;identifier&gt;]\n    [ where &lt;java script boolean expression&gt; ]\n    ]\n     */\n    public void executeQuery(String query, ObjectVisitor visitor)\n            throws OQLException {\n        delegate.executeQuery(query, visitor);\n    }\n\n    public OQLQuery parseQuery(String query) throws OQLException {\n        return delegate.parseQuery(query);\n    }\n\n    public void cancelQuery() throws OQLException {\n        delegate.cancelQuery();\n    }\n\n    public Object unwrapJavaObject(Object object) {\n        return delegate.unwrapJavaObject(object);\n    }\n\n    public Object unwrapJavaObject(Object object, boolean tryAssociativeArray) {\n        return delegate.unwrapJavaObject(object, tryAssociativeArray);\n    }\n\n    public boolean isCancelled() {\n        return delegate.isCancelled();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/engine/api/OQLException.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.oql.engine.api;\n\n/**\n * OQLException is thrown if OQL execution results in error\n *\n */\nfinal public class OQLException extends Exception {\n    public OQLException(String msg) {\n        super(msg);\n    }\n\n    public OQLException(String msg, Throwable cause) {\n        super(msg, cause);\n    }\n\n    public OQLException(Throwable cause) {\n        super(cause);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/engine/api/ReferenceChain.java",
    "content": "/*\n * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.oql.engine.api;\n\nimport java.lang.ref.WeakReference;\nimport java.util.Objects;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\n\n/**\n * Represents a chain of references to some target object\n *\n * @author      Bill Foote\n */\nfinal public class ReferenceChain {\n    private WeakReference<Object> obj;\t// Object referred to\n    ReferenceChain next;\t// Next in chain\n    private Heap heap;\n    private long id;\n    private char type;\n\n    private static final char TYPE_INSTANCE = 0;\n    private static final char TYPE_CLASS = 1;\n\n    public ReferenceChain(Heap heap, Object obj, ReferenceChain next) {\n        this.obj = new WeakReference<>(obj);\n        this.next = next;\n        this.heap = heap;\n\n        if (obj instanceof Instance) {\n            type = TYPE_INSTANCE;\n            id = ((Instance)obj).getInstanceId();\n        } else if (obj instanceof JavaClass) {\n            type = TYPE_CLASS;\n            id = ((JavaClass)obj).getJavaClassId();\n        }\n    }\n\n    public Object getObj() {\n        Object o = obj.get();\n        if (o == null) {\n            if (type == TYPE_INSTANCE) {\n                o = heap.getInstanceByID(id);\n            } else if (type == TYPE_CLASS) {\n                o = heap.getJavaClassByID(id);\n            }\n            obj = new WeakReference<>(o);\n        }\n        return o;\n    }\n\n    public ReferenceChain getNext() {\n        return next;\n    }\n\n    public boolean contains(Object obj) {\n        ReferenceChain tmp = this;\n        while (tmp != null) {\n            if (tmp.getObj().equals(obj)) return true;\n            tmp = tmp.next;\n        }\n        return false;\n    }\n\n    public int getDepth() {\n        int count = 1;\n        ReferenceChain tmp = next;\n        while (tmp != null) {\n            count++;\n            tmp = tmp.next;\n        }\n        return count;\n    }\n\n    public String toString() {\n        StringBuilder sb = new StringBuilder();\n        if (obj instanceof Instance) {\n            Instance inst = (Instance)obj;\n            sb.append(inst.getJavaClass().getName()).append(\"#\").append(inst.getInstanceNumber());\n        } else if (obj instanceof JavaClass) {\n            sb.append(\"class of \").append(((JavaClass)obj).getName());\n        }\n        sb.append(next != null ? (\"->\" + next.toString()) : \"\");\n        return sb.toString();\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj == null) {\n            return false;\n        }\n        if (getClass() != obj.getClass()) {\n            return false;\n        }\n        final ReferenceChain other = (ReferenceChain) obj;\n        if (!Objects.equals(obj, other.obj)) {\n            return false;\n        }\n        if (!Objects.equals(next, other.next)) {\n            return false;\n        }\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int hash = 3;\n        hash = 79 * hash + (this.obj != null ? this.obj.hashCode() : 0);\n        hash = 79 * hash + (this.next != null ? this.next.hashCode() : 0);\n        return hash;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/engine/api/impl/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/engine/api/impl/OQLEngineImpl.java",
    "content": "/*\n * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.oql.engine.api.impl;\n\nimport java.io.*;\nimport java.util.*;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.script.Bindings;\nimport javax.script.Compilable;\nimport javax.script.CompiledScript;\nimport javax.script.Invocable;\nimport javax.script.ScriptContext;\nimport javax.script.ScriptEngine;\nimport javax.script.ScriptEngineManager;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.OQLEngine.OQLQuery;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.OQLEngine.ObjectVisitor;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.OQLException;\nimport org.openide.util.NbBundle;\n\n/**\n * This is Object Query Language Interpreter\n *\n * @author A. Sundararajan\n * @author J. Bachorik\n */\npublic class OQLEngineImpl {\n    final private static Logger LOGGER = Logger.getLogger(OQLEngineImpl.class.getName());\n\n    private static boolean oqlSupported;\n\n    static {\n        try {\n            // Do we have JavaScript engine?\n            ScriptEngineManager manager = new ScriptEngineManager();\n            Object engine = manager.getEngineByName(\"JavaScript\"); // NOI18N\n\n            oqlSupported = engine != null;\n        } catch (Throwable ex) {\n            LOGGER.log(Level.INFO,\"OQLEngine init\",ex); // NOI18N\n            oqlSupported = false;\n        }\n    }\n\n    // check OQL is supported or not before creating OQLEngine\n    public static boolean isOQLSupported() {\n        return oqlSupported;\n    }\n\n    private ScriptEngine engine;\n    private Snapshot snapshot;\n\n    public OQLEngineImpl(Snapshot snapshot) {\n        if (!isOQLSupported()) {\n            throw new UnsupportedOperationException(\"OQL not supported\"); // NOI18N\n        }\n        init(snapshot);\n    }\n\n    public Snapshot getHeapHelper() {\n        return snapshot;\n    }\n\n    /**\n    Query is of the form\n\n    select &lt;java script code to select&gt;\n    [ from [instanceof] &lt;class name&gt; [&lt;identifier&gt;]\n    [ where &lt;java script boolean expression&gt; ]\n    ]\n     */\n    public synchronized void executeQuery(String query, ObjectVisitor visitor)\n            throws OQLException {\n        LOGGER.log(Level.FINE, query);\n\n        OQLQuery parsedQuery = parseQuery(query);\n        if (parsedQuery == null) {\n            // Query does not start with 'select' keyword.\n            // Just treat it as plain JavaScript and eval it.\n            try {\n                Object res = evalScript(query);\n                dispatchValue(res, visitor);\n            } catch (Exception e) {\n                throw new OQLException(e);\n            }\n            return;\n        }\n\n        executeQuery((OQLQueryImpl)parsedQuery, visitor);\n    }\n\n    @NbBundle.Messages({\n        \"ERROR_NO_SELECT_CLAUSE=query syntax error: no 'select' clause\",\n        \"ERROR_EMPTY_SELECT=query syntax error: 'select' expression can not be empty\",\n        \"ERROR_INSTANCEOF_NO_CLASSNAME=no class name after 'instanceof'\",\n        \"ERROR_FROM_NO_CLASSNAME=query syntax error: class name must follow 'from'\",\n        \"ERROR_NO_IDENTIFIER=query syntax error: identifier should follow class name\",\n        \"ERROR_EXPECTING_WHERE=query syntax error: 'where' clause expected after 'from' clause\",\n        \"ERROR_EMPTY_WHERE=query syntax error: 'where' clause cannot have empty expression\"\n    })\n    public OQLQuery parseQuery(String query) throws OQLException {\n        StringTokenizer st = new StringTokenizer(query);\n        if (st.hasMoreTokens()) {\n            String first = st.nextToken();\n            if (!first.equals(\"select\")) { // NOI18N\n                // Query does not start with 'select' keyword.\n                // Just treat it as plain JavaScript and eval it.\n                return null;\n            }\n        } else {\n            throw new OQLException(Bundle.ERROR_NO_SELECT_CLAUSE());\n        }\n\n        String selectExpr = \"\"; // NOI18N\n        boolean seenFrom = false;\n        while (st.hasMoreTokens()) {\n            String tok = st.nextToken();\n            if (tok.equals(\"from\")) { // NOI18N\n                seenFrom = true;\n                break;\n            }\n            selectExpr += \" \" + tok; // NOI18N\n        }\n\n        if (selectExpr.isEmpty()) { // NOI18N\n            throw new OQLException(Bundle.ERROR_EMPTY_SELECT());\n        }\n\n        String className = null;\n        boolean isInstanceOf = false;\n        String whereExpr = null;\n        String identifier = null;\n\n        if (seenFrom) {\n            if (st.hasMoreTokens()) {\n                String tmp = st.nextToken();\n                if (tmp.equals(\"instanceof\")) { // NOI18N\n                    isInstanceOf = true;\n                    if (!st.hasMoreTokens()) {\n                        throw new OQLException(Bundle.ERROR_INSTANCEOF_NO_CLASSNAME());\n                    }\n                    className = st.nextToken();\n                } else {\n                    className = tmp;\n                }\n            } else {\n                throw new OQLException(Bundle.ERROR_FROM_NO_CLASSNAME());\n            }\n\n            if (st.hasMoreTokens()) {\n                identifier = st.nextToken();\n                if (identifier.equals(\"where\")) { // NOI18N\n                    throw new OQLException(Bundle.ERROR_NO_IDENTIFIER());\n                }\n                if (st.hasMoreTokens()) {\n                    String tmp = st.nextToken();\n                    if (!tmp.equals(\"where\")) { // NOI18N\n                        throw new OQLException(Bundle.ERROR_EXPECTING_WHERE());\n                    }\n\n                    whereExpr = \"\";  // NOI18N\n                    while (st.hasMoreTokens()) {\n                        whereExpr += \" \" + st.nextToken(); // NOI18N\n                    }\n                    if (whereExpr.isEmpty()) { // NOI18N\n                        throw new OQLException(Bundle.ERROR_EMPTY_WHERE());\n                    }\n                }\n            } else {\n                throw new OQLException(Bundle.ERROR_NO_IDENTIFIER());\n            }\n        }\n        return new OQLQueryImpl(selectExpr, isInstanceOf, className, identifier, whereExpr);\n    }\n\n    public void cancelQuery() throws OQLException {\n        cancelled.set(true);\n    }\n    \n    public boolean isCancelled() {\n        return cancelled.get();\n    }\n\n    private void executeQuery(OQLQueryImpl q, ObjectVisitor visitor)\n            throws OQLException {\n\n        cancelled.set(false);\n        visitor = visitor != null ? visitor : ObjectVisitor.DEFAULT;\n\n        JavaClass clazz = null;\n        if (q.className != null) {\n            String className = q.className;\n\n            clazz = snapshot.findClass(className);\n            if (clazz == null) {\n                throw new OQLException(className + \" was not found!\"); // NOI18N\n            }\n        }\n\n        StringBuilder buf = new StringBuilder();\n        buf.append(\"function __select__(\"); // NOI18N\n        if (q.identifier != null) {\n            buf.append(q.identifier);\n        }\n        buf.append(\") { return \"); // NOI18N\n        buf.append(q.selectExpr.replace('\\n', ' ')); // NOI18N\n        buf.append(\"; }\\n\"); // NOI18N\n        buf.append(\"__select__(\").append(q.identifier).append(\")\"); // NOI18N\n\n        String selectCode = buf.toString();\n\n        // compile select expression and where condition \n        try {\n            Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);\n\n            CompiledScript whereCs = null;\n            CompiledScript selectCs = ((Compilable)engine).compile(selectCode);\n            \n            if (q.whereExpr != null) {\n                whereCs = ((Compilable)engine).compile(q.whereExpr.replace('\\n', ' ')); // NOI18N\n            }\n\n            if (q.className != null) {\n                Stack<JavaClass> toInspect = new Stack<>();\n                Set<JavaClass> inspected = new HashSet<>();\n\n                toInspect.push(clazz);\n\n                while(!toInspect.isEmpty()) {\n                    JavaClass inspecting = toInspect.pop();\n                    inspected.add(inspecting);\n                    if (q.isInstanceOf) {\n                        for(JavaClass subclass : inspecting.getSubClasses()) {\n                            if (!inspected.contains(subclass) && !toInspect.contains(subclass)) {\n                                toInspect.push(subclass);\n                            }\n                        }\n                    }\n                    Iterator<Instance> objectsIt = inspecting.getInstancesIterator();\n\n                    while (objectsIt.hasNext()) {\n                        Object wrapped = wrapJavaObject(objectsIt.next());\n                        boolean b = (whereCs == null);\n                        if (!b) {\n                            bindings.put(q.identifier, wrapped);\n                            Object res = whereCs.eval(bindings);\n                            if (res instanceof Boolean) {\n                                b = ((Boolean) res).booleanValue();\n                            } else if (res instanceof Number) {\n                                b = ((Number) res).intValue() != 0;\n                            } else {\n                                b = (res != null);\n                            }\n                        }\n\n                        if (b) {\n                            bindings.put(q.identifier, wrapped);\n                            Object select = selectCs.eval(bindings);\n                            if (dispatchValue(select, visitor)) {\n                                return;\n                            }\n                        }\n                    }\n                }\n            } else {\n                // simple \"select <expr>\" query\n                Object select = selectCs.eval();\n                if (dispatchValue(select, visitor)) {\n                    return;\n                }\n            }\n        } catch (Exception e) {\n            throw new OQLException(e);\n        }\n    }\n\n    private boolean dispatchValue(Object jsObject, ObjectVisitor visitor) {\n        if (jsObject == null) {\n            return false;\n        }\n\n        if (jsObject instanceof Iterator) {\n            Iterator<?> iter = (Iterator) jsObject;\n            while (iter.hasNext()) {\n                if (dispatchValue(iter.next(), visitor)) return true;\n            }\n            return false;\n        } else if (jsObject instanceof Enumeration) {\n            Enumeration<?> enm = (Enumeration) jsObject;\n            while (enm.hasMoreElements()) {\n                Object elem = enm.nextElement();\n                if (dispatchValue(elem, visitor)) return true;\n            }\n            return false;\n        } else {\n            Object object = unwrapJavaObject(jsObject, true);\n            if (object instanceof Object[]) {\n                for (Object obj1 : (Object[]) object) {\n                    if (dispatchValue(obj1, visitor)) return true;\n                }\n                return false;\n            }\n            if (visitor.visit(object)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public Object evalScript(String script) throws Exception {\n        cancelled.set(false);\n        CompiledScript cs = ((Compilable)engine).compile(script);\n        return cs.eval();\n    }\n\n    public Object wrapJavaObject(Instance obj) throws Exception {\n        return call(\"wrapJavaObject\", new Object[]{obj}); // NOI18N\n    }\n\n    public Object toHtml(Object obj) throws Exception {\n        return call(\"toHtml\", new Object[]{obj}); // NOI18N\n    }\n\n    public Object call(String func, Object[] args) throws Exception {\n\n        return ((Invocable)engine).invokeFunction(func, args);\n    }\n\n    public Object unwrapJavaObject(Object object) {\n        return unwrapJavaObject(object, false);\n    }\n\n    public Object unwrapJavaObject(Object object, boolean tryAssociativeArray) {\n        if (object == null) return null;\n        String className = object.getClass().getName();\n        boolean isNativeJS = className.startsWith(\"com.oracle.truffle.object.\") // NOI18N\n                          || className.equals(\"org.graalvm.polyglot.Value\"); // NOI18N\n\n        try {\n            Object ret = ((Invocable)engine).invokeFunction(\"unwrapJavaObjectRes\", object); // NOI18N\n            if (isNativeJS && ret == null && tryAssociativeArray) {\n                ret = ((Invocable)engine).invokeFunction(\"unwrapMap\", object); // NOI18N\n            }\n            return ret == null ? object : ret;\n        } catch (Exception ex) {\n            LOGGER.log(Level.WARNING, \"Error unwrapping JS object\", ex); // NOI18N\n        }\n        return null;\n    }\n\n    final private AtomicBoolean cancelled = new AtomicBoolean(false);\n    private void init(Snapshot snapshot) throws RuntimeException {\n        this.snapshot = snapshot;\n        try {\n            ScriptEngineManager manager = new ScriptEngineManager();\n            engine = manager.getEngineByName(\"JavaScript\"); // NOI18N\n            InputStream strm = getInitStream();\n            CompiledScript cs = ((Compilable)engine).compile(new InputStreamReader(strm));\n            cs.eval();\n            Object heap = ((Invocable)engine).invokeFunction(\"wrapHeapSnapshot\", snapshot); // NOI18N\n            engine.put(\"heap\", heap); // NOI18N\n            engine.put(\"cancelled\", cancelled); // NOI18N\n        } catch (Exception ex) {\n            LOGGER.log(Level.INFO, \"Error initializing snapshot\", ex); // NOI18N\n            throw new RuntimeException(ex);\n        }\n    }\n\n    private InputStream getInitStream() {\n        return getClass().getResourceAsStream(\"/org/graalvm/visualvm/lib/profiler/oql/engine/api/impl/hat.js\"); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/engine/api/impl/OQLQueryImpl.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.oql.engine.api.impl;\n\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.OQLEngine.OQLQuery;\n\n/**\n * This represents a parsed OQL query\n *\n * @author A. Sundararajan\n */\npublic class OQLQueryImpl extends OQLQuery {\n    OQLQueryImpl(String selectExpr, boolean isInstanceOf,\n             String className, String identifier, String whereExpr) {\n        this.selectExpr = selectExpr;\n        this.isInstanceOf = isInstanceOf;\n        this.className = className;\n        this.identifier = identifier;\n        this.whereExpr = whereExpr;\n    }\n\n    String   selectExpr;\n    boolean  isInstanceOf;\n    String   className;\n    String   identifier;\n    String   whereExpr;\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/engine/api/impl/ReachableExcludes.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.oql.engine.api.impl;\n\n\n/**\n * This represents a set of data members that should be excluded from the\n * reachable objects query. This is useful to exclude observers from the\n * transitive closure of objects reachable from a given object, allowing\n * some kind of real determination of the \"size\" of that object.\n *\n * @author    A. Sundararajan\n */\n\npublic interface ReachableExcludes {\n    /**\n     * @return true if the given field is on the hitlist of excluded\n     * \t\tfields.\n     */\n    public boolean isExcluded(String fieldName);\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/engine/api/impl/ReachableObjects.java",
    "content": "/*\n * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.oql.engine.api.impl;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.FieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class ReachableObjects {\n    private ReachableExcludes excludes;\n    private Instance root;\n    private Set<Instance> alreadyReached;\n\n    public ReachableObjects(Instance root, final ReachableExcludes excludes) {\n        this.root = root;\n        this.excludes = excludes;\n        alreadyReached = new HashSet<>();\n    }\n\n    public Instance getRoot() {\n        return root;\n    }\n\n    public Iterator<Instance> getReachables() {\n        return new TreeIterator<Instance, Instance>(root) {\n\n            @Override\n            protected Iterator<Instance> getSameLevelIterator(Instance popped) {\n                Collection<Instance> instances = new ArrayList<>();\n                for(Object fv : popped.getFieldValues()) {\n                    if (fv instanceof ObjectFieldValue) {\n                        if (excludes == null || !excludes.isExcluded(getFQFieldName(((FieldValue)fv).getField()))) {\n                            Instance i = ((ObjectFieldValue)fv).getInstance();\n                            if (i != null && !alreadyReached.contains(i)) {\n                                instances.add(i);\n                                alreadyReached.add(i);\n                            }\n                        }\n                    }\n                }\n                if (popped instanceof ObjectArrayInstance) {\n                    for(Instance i : ((ObjectArrayInstance)popped).getValues()) {\n                        if (i != null && !alreadyReached.contains(i)) {\n                            instances.add(i);\n                            alreadyReached.add(i);\n                        }\n                    }\n                }\n                return instances.iterator();\n            }\n\n            @Override\n            protected Iterator<Instance> getTraversingIterator(Instance popped) {\n                Collection<Instance> instances = new ArrayList<>();\n                for(Object fv : popped.getFieldValues()) {\n                    if (fv instanceof ObjectFieldValue) {\n                        if (excludes == null || !excludes.isExcluded(getFQFieldName(((FieldValue)fv).getField()))) {\n                            Instance i = ((ObjectFieldValue)fv).getInstance();\n                            if (i != null) {\n                                instances.add(i);\n                            }\n                        }\n                    }\n                }\n                if (popped instanceof ObjectArrayInstance) {\n                    for(Instance el : ((ObjectArrayInstance)popped).getValues()) {\n                        if (el != null) {\n                            instances.add(el);\n                        }\n                    }\n                }\n                return instances.iterator();\n            }\n        };\n    }\n\n    public long getTotalSize() {\n        return -1;\n    }\n\n    private String getFQFieldName(Field fld) {\n        return fld.getDeclaringClass().getName() + \".\" + fld.getName();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/engine/api/impl/Snapshot.java",
    "content": "/*\n * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.oql.engine.api.impl;\n\nimport java.lang.reflect.Method;\nimport java.util.*;\nimport java.util.concurrent.atomic.AtomicLong;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.lib.jfluid.heap.Field;\nimport org.graalvm.visualvm.lib.jfluid.heap.GCRoot;\nimport org.graalvm.visualvm.lib.jfluid.heap.Heap;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.ObjectFieldValue;\nimport org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance;\nimport org.graalvm.visualvm.lib.jfluid.heap.Value;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.OQLEngine;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.ReferenceChain;\nimport org.openide.util.Enumerations;\n\n/**\n * A helper class for OQL engine allowing easy access to the underlying\n * heapwalker model\n * \n * @author      Jaroslav Bachorik\n */\npublic final class Snapshot {\n\n    private static final String BOOLEAN_CODE = \"Z\"; // NOI18N\n    private static final String CHAR_CODE = \"C\"; // NOI18N\n    private static final String BYTE_CODE = \"B\"; // NOI18N\n    private static final String SHORT_CODE = \"S\"; // NOI18N\n    private static final String INT_CODE = \"I\"; // NOI18N\n    private static final String LONG_CODE = \"J\"; // NOI18N\n    private static final String FLOAT_CODE = \"F\"; // NOI18N\n    private static final String DOUBLE_CODE = \"D\"; // NOI18N\n    private static final String VOID_CODE = \"V\"; // NOI18N\n    private static final char REFERENCE = 'L'; // NOI18N\n\n    private final Heap delegate;\n    private JavaClass weakReferenceClass;\n    private int referentFieldIndex;\n    private ReachableExcludes reachableExcludes;\n    final private OQLEngine engine;\n\n    public Snapshot(Heap heap, OQLEngine engine) {\n        this.delegate = heap;\n        this.engine = engine;\n        init();\n    }\n\n    private void init() {\n        weakReferenceClass = findClass(\"java.lang.ref.Reference\"); // NOI18N\n        if (weakReferenceClass == null) {\t// JDK 1.1.x\n            weakReferenceClass = findClass(\"sun.misc.Ref\"); // NOI18N\n            referentFieldIndex = 0;\n        } else {\n            List<Field> flds = weakReferenceClass.getFields();\n            int fldsCount = flds.size();\n\n            for (int i = 0; i < fldsCount; i++) {\n                if (\"referent\".equals(flds.get(i).getName())) { // NOI18N\n                    referentFieldIndex = i;\n                    break;\n                }\n            }\n        }\n    }\n\n    public JavaClass findClass(String name) {\n        try {\n            long classId;\n            if (name.startsWith(\"0x\")) {\n                classId = Long.parseLong(name.substring(2), 16);\n            } else {\n                classId = Long.parseLong(name);\n            }\n            return delegate.getJavaClassByID(classId);\n        } catch (NumberFormatException e) {}\n        return delegate.getJavaClassByName(preprocessClassName(name));\n    }\n\n    private String preprocessClassName(String className) {\n        int arrDim = 0;\n        if (className.startsWith(\"[\")) { // NOI18N\n            arrDim = className.lastIndexOf('[') + 1; // NOI18N\n\n            className = className.substring(arrDim);\n        }\n        if (className.length() == 1) {\n            if (className.equals(INT_CODE)) {\n                className = int.class.toString();\n            } else if (className.equals(LONG_CODE)) {\n                className = long.class.toString();\n            } else if (className.equals(DOUBLE_CODE)) {\n                className = double.class.toString();\n            } else if (className.equals(FLOAT_CODE)) {\n                className = float.class.toString();\n            } else if (className.equals(BYTE_CODE)) {\n                className = byte.class.toString();\n            } else if (className.equals(SHORT_CODE)) {\n                className = short.class.toString();\n            } else if (className.equals(CHAR_CODE)) {\n                className = char.class.toString();\n            } else if (className.equals(BOOLEAN_CODE)) {\n                className = boolean.class.toString();\n            }\n        }\n        if (arrDim > 0 && className.charAt(0) == REFERENCE) {   // class name\n            className = className.substring(1);\n        }\n        StringBuilder sb = new StringBuilder(className);\n        for (int i = 0; i < arrDim; i++) {\n            sb.append(\"[]\"); // NOI18N\n        }\n\n        return sb.toString();\n    }\n\n    public Instance findThing(long objectId) {\n        return delegate.getInstanceByID(objectId);\n    }\n\n    public GCRoot findRoot(Instance object) {\n        Instance gcInstance = object;\n        do {\n            gcInstance = gcInstance.getNearestGCRootPointer();\n        } while (gcInstance != null && !gcInstance.isGCRoot());\n        if (gcInstance != null) {\n            Collection<GCRoot> roots = delegate.getGCRoots(gcInstance);\n            if (!roots.isEmpty()) {\n                // TODO getGCRoot() now returns Collection\n                return roots.iterator().next();\n            }\n        }\n        return null;\n    }\n\n    public int distanceToGCRoot(Instance object) {\n        Instance gcInstance = object;\n        int distance = 0;\n        do {\n            gcInstance = gcInstance.getNearestGCRootPointer();\n            if (gcInstance == null) {\n                return 0;\n            }\n            distance++;\n        } while (!gcInstance.isGCRoot());\n        return distance;\n    }\n\n    public <T> Enumeration<T> concat(Enumeration<? extends T> en1, Enumeration<? extends T> en2) {\n        return Enumerations.concat(en1, en2);\n    }\n\n    /**\n     * Return an Iterator of all of the classes in this snapshot.\n     **/\n    public Iterator<JavaClass> getClasses() {\n        return delegate.getAllClasses().iterator();\n    }\n\n    public Iterator<String> getClassNames(String regex)  {\n        final Iterator<JavaClass> delegated = delegate.getJavaClassesByRegExp(regex).iterator();\n        return new Iterator<String>() {\n\n            public boolean hasNext() {\n                return delegated.hasNext();\n            }\n\n            public String next() {\n                return delegated.next().getName();\n            }\n\n            public void remove() {\n                delegated.remove();\n            }\n        };\n\n    }\n\n    public Iterator<Instance> getInstances(final JavaClass clazz, final boolean includeSubclasses) {\n        // special case for all subclasses of java.lang.Object\n        if (includeSubclasses && clazz.getSuperClass() == null) {\n            return delegate.getAllInstancesIterator();\n        }\n        return new TreeIterator<Instance, JavaClass>(clazz) {\n\n            @Override\n            protected Iterator<Instance> getSameLevelIterator(JavaClass popped) {\n                return popped.getInstancesIterator();\n            }\n\n            @Override\n            protected Iterator<JavaClass> getTraversingIterator(JavaClass popped) {\n                return includeSubclasses ? popped.getSubClasses().iterator() : Collections.emptyIterator();\n            }\n        };\n    }\n\n    public Iterator<Object> getReferrers(Object obj, boolean includeWeak) {\n        List<Object> instances = new ArrayList<>();\n        List<Object> references = new ArrayList<>();\n        \n        if (obj instanceof Instance) {\n            references.addAll(((Instance)obj).getReferences());\n        } else if (obj instanceof JavaClass) {\n            references.addAll(((JavaClass)obj).getInstances());\n            references.add(((JavaClass)obj).getClassLoader());\n        }\n        if (!references.isEmpty()) {\n            for (Object o : references) {\n                if (o instanceof Value) {\n                    Value val = (Value) o;\n                    Instance inst = val.getDefiningInstance();\n                    if (includeWeak || !isWeakRef(inst)) {\n                        instances.add(inst);\n                    }\n                } else if (o instanceof Instance) {\n                    if (includeWeak || !isWeakRef((Instance)o)) {\n                        instances.add(o);\n                    }\n                }\n            }\n        }\n        return instances.iterator();\n    }\n\n    public Iterator<Object> getReferees(Object obj, boolean includeWeak) {\n        List<Object> instances = new ArrayList<>();\n        List<Object> values = new ArrayList<>();\n        \n        if (obj instanceof Instance) {\n            Instance o = (Instance)obj;\n            values.addAll(o.getFieldValues());\n        }\n        if (obj instanceof JavaClass) {\n            values.addAll(((JavaClass)obj).getStaticFieldValues());\n        }\n        if (obj instanceof ObjectArrayInstance) {\n            ObjectArrayInstance oarr = (ObjectArrayInstance)obj;\n            values.addAll(oarr.getValues());\n        }\n        if (!values.isEmpty()) {\n            for (Object value : values) {\n                if (value instanceof ObjectFieldValue && ((ObjectFieldValue) value).getInstance() != null) {\n                    Instance inst = ((ObjectFieldValue) value).getInstance();\n                    if (includeWeak || !isWeakRef(inst)) {\n                        if (inst.getJavaClass().getName().equals(\"java.lang.Class\")) {\n                            JavaClass jc = delegate.getJavaClassByID(inst.getInstanceId());\n                            if (jc != null) {\n                                instances.add(jc);\n                            } else {\n                                instances.add(inst);\n                            }\n                        } else {\n                            instances.add(inst);\n                        }\n                    }\n                } else if (value instanceof Instance) {\n                    if (includeWeak || !isWeakRef((Instance)value)) {\n                        instances.add(value);\n                    }\n                }\n            }\n        }\n        return instances.iterator();\n    }\n\n    public Iterator<Instance> getFinalizerObjects() {\n        JavaClass clazz = findClass(\"java.lang.ref.Finalizer\"); // NOI18N\n        Instance queue = (Instance) clazz.getValueOfStaticField(\"queue\"); // NOI18N\n        Instance head = (Instance) queue.getValueOfField(\"head\"); // NOI18N\n\n        List<Instance> finalizables = new ArrayList<>();\n        if (head != null) {\n            while (true) {\n                Instance referent = (Instance) head.getValueOfField(\"referent\"); // NOI18N\n                Instance next = (Instance) head.getValueOfField(\"next\"); // NOI18N\n\n                finalizables.add(referent);\n                if (next == null || next.equals(head)) {\n                    break;\n                }\n                head = next;\n            }\n        }\n        return finalizables.iterator();\n    }\n\n    public Iterator<GCRoot> getRoots() {\n        return delegate.getGCRoots().iterator();\n    }\n    \n    private Set<Object> getRootsInstances() {\n        Set<Object> roots = new HashSet<>();\n        for(GCRoot root : delegate.getGCRoots()) {\n            Instance inst = root.getInstance();\n            if (inst.getJavaClass().getName().equals(\"java.lang.Class\")) {\n                JavaClass jc = delegate.getJavaClassByID(inst.getInstanceId());\n                if (jc != null) {\n                    roots.add(jc);\n                } else {\n                    roots.add(inst);\n                }\n            } else {\n                roots.add(inst);\n            }\n        }\n        return roots;\n    }\n\n    public GCRoot[] getRootsArray() {\n        Collection<GCRoot> rootList = delegate.getGCRoots();\n        return rootList.toArray(new GCRoot[0]);\n    }\n   \n    public ReferenceChain[] rootsetReferencesTo(Instance target, boolean includeWeak) {\n        class State {\n            private Iterator<Object> iterator;\n            private ReferenceChain path;\n            private AtomicLong hits = new AtomicLong(0);\n\n            State(ReferenceChain path, Iterator<Object> iterator) {\n                this.iterator = iterator;\n                this.path = path;\n            }\n        }\n        Deque<State> stack = new ArrayDeque<>();\n        Set<Object> ignored = new HashSet<>();\n        \n        List<ReferenceChain> result = new ArrayList<>();\n        \n        Iterator<Object> toInspect = getRootsInstances().iterator();\n        ReferenceChain path = null;\n        State s = new State(path, toInspect);\n        \n        do {\n            if (path != null && path.getObj().equals(target)) {\n                result.add(path);\n                s.hits.incrementAndGet();\n            } else {\n                while(!engine.isCancelled() && toInspect.hasNext()) {\n                    Object node = toInspect.next();\n                    if (path != null && path.contains(node)) continue;\n                    if (ignored.contains(node)) continue;\n\n                    stack.push(s);\n                    path = new ReferenceChain(delegate, node, path);\n                    toInspect = getReferees(node, includeWeak);\n                    s = new State(path, toInspect);\n                }\n                if (path != null && path.getObj().equals(target)) {\n                    result.add(path);\n                    s.hits.incrementAndGet();\n                }\n            }\n            State s1 = stack.poll();\n            if (s1 == null) break;\n            s1.hits.addAndGet(s.hits.get());\n            if (s.hits.get() == 0L && path != null) {\n                ignored.add(path.getObj());\n            }\n            s = s1;\n            path = s.path;\n            toInspect = s.iterator;\n        } while (!engine.isCancelled());\n\n        return result.toArray(new ReferenceChain[0]);\n    }\n\n    private boolean isAssignable(JavaClass from, JavaClass to) {\n        if (from == to) {\n            return true;\n        } else if (from == null) {\n            return false;\n        } else {\n            return isAssignable(from.getSuperClass(), to);\n        // Trivial tail recursion:  I have faith in javac.\n        }\n    }\n    \n    private boolean isWeakRef(Instance inst) {\n        return weakReferenceClass != null && isAssignable(inst.getJavaClass(), weakReferenceClass);\n    }\n\n    public JavaClass getWeakReferenceClass() {\n        return weakReferenceClass;\n    }\n\n    public int getReferentFieldIndex() {\n        return referentFieldIndex;\n    }\n\n    public void setReachableExcludes(ReachableExcludes e) {\n        reachableExcludes = e;\n    }\n\n    public ReachableExcludes getReachableExcludes() {\n        return reachableExcludes;\n    }\n\n    public String valueString(Instance instance) {\n        if (instance == null) return null;\n        try {\n            if (instance.getJavaClass().getName().equals(String.class.getName())) {\n                Class<?> proxy = Class.forName(\"org.graalvm.visualvm.lib.jfluid.heap.HprofProxy\"); // NOI18N\n                Method method = proxy.getDeclaredMethod(\"getString\", Instance.class); // NOI18N\n                method.setAccessible(true);\n                return (String) method.invoke(proxy, instance);\n            } else if (instance.getJavaClass().getName().equals(\"char[]\")) { // NOI18N\n                Method method = instance.getClass().getDeclaredMethod(\"getChars\", int.class, int.class);\n                method.setAccessible(true);\n                char[] chars = (char[])method.invoke(instance, 0, ((PrimitiveArrayInstance)instance).getLength());\n                if (chars != null) {\n                    return new String(chars);\n                } else {\n                    return \"*null*\"; // NOI18N\n                }\n            }\n        } catch (Exception ex) {\n            Logger.getLogger(Snapshot.class.getName()).log(Level.WARNING, \"Error getting toString() value of an instance dump\", ex); // NO18N\n        }\n        return instance.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/engine/api/impl/TreeIterator.java",
    "content": "/*\n * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.oql.engine.api.impl;\n\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\nimport java.util.Set;\nimport java.util.Stack;\n\n/**\n * Provides an iterator over instances of <I> using instances of <T> for traversal\n * @author Jaroslav Bachorik\n */\nabstract public class TreeIterator<I, T> implements Iterator<I> {\n    private Stack<T> toInspect = new Stack<>();\n    private Set<T> inspected = new HashSet<>();\n\n    private T popped = null;\n    private Iterator<I> inspecting = null;\n\n    public TreeIterator(T root) {\n        toInspect.push(root);\n        inspected.add(root);\n    }\n\n    public boolean hasNext() {\n        setupIterator();\n        return inspecting != null && inspecting.hasNext();\n    }\n\n    public I next() {\n        setupIterator();\n\n        if (inspecting == null || !inspecting.hasNext()) {\n            throw new NoSuchElementException();\n        }\n\n        I retVal = inspecting.next();\n        return retVal;\n    }\n\n    public void remove() {\n        throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n    }\n\n    abstract protected Iterator<I> getSameLevelIterator(T popped);\n    abstract protected Iterator<T> getTraversingIterator(T popped);\n\n    private void setupIterator() {\n        while (!toInspect.isEmpty() && (inspecting == null || !inspecting.hasNext())) {\n            popped = toInspect.pop();\n            if (popped != null) {\n                inspecting = getSameLevelIterator(popped);\n                Iterator<T> recurseIter = getTraversingIterator(popped);\n                while (recurseIter.hasNext()) {\n                    T inspectNext = recurseIter.next();\n                    if (inspectNext == null) continue;\n                    if (!inspected.contains(inspectNext)) {\n                        toInspect.push(inspectNext);\n                        inspected.add(inspectNext);\n                    }\n                }\n            } else {\n                inspecting = null;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/engine/api/impl/hat.js",
    "content": "/*\n * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\nvar ReachableExcludes = Java.type(\"org.graalvm.visualvm.lib.profiler.oql.engine.api.impl.ReachableExcludes\");\nvar ReachableObjects = Java.type(\"org.graalvm.visualvm.lib.profiler.oql.engine.api.impl.ReachableObjects\");\n\nvar JavaClass = Java.type(\"org.graalvm.visualvm.lib.jfluid.heap.JavaClass\");\nvar Instance = Java.type(\"org.graalvm.visualvm.lib.jfluid.heap.Instance\");\nvar ObjectArrayInstance = Java.type(\"org.graalvm.visualvm.lib.jfluid.heap.ObjectArrayInstance\");\nvar PrimitiveArrayInstance = Java.type(\"org.graalvm.visualvm.lib.jfluid.heap.PrimitiveArrayInstance\");\nvar Field = Java.type(\"org.graalvm.visualvm.lib.jfluid.heap.Field\");\nvar FieldValue = Java.type(\"org.graalvm.visualvm.lib.jfluid.heap.FieldValue\");\nvar GCRoot = Java.type(\"org.graalvm.visualvm.lib.jfluid.heap.GCRoot\");\n\nvar snapshot;\nvar classWrapperCache;\n\n/**\n * This is JavaScript interface for heap analysis using HAT\n * (Heap Analysis Tool). HAT classes are refered from\n * this file. In particular, refer to classes in hat.model\n * package.\n *\n * HAT model objects are wrapped as convenient script objects so that\n * fields may be accessed in natural syntax. For eg. Java fields can be\n * accessed with obj.field_name syntax and array elements can be accessed\n * with array[index] syntax.\n */\n\n// returns an enumeration that wraps elements of\n// the input enumeration elements.\nfunction wrapperEnumeration(e) {\n    return new java.util.Enumeration() {\n        hasMoreElements: function() {\n            return e.hasMoreElements();\n        },\n        nextElement: function() {\n            return wrapJavaValue(e.nextElement());\n        }\n    };\n}\n\n// returns an enumeration that filters out elements\n// of input enumeration using the filter function.\nfunction filterEnumeration(e, func, wrap) {\n    var next = undefined;\n    var index = 0;\n\n    function findNext() {\n        var tmp;\n        while (e.hasMoreElements() && !cancelled.get()) {\n            tmp = e.nextElement();\n            index++;\n            if (wrap) {\n                tmp = wrapJavaObject(tmp);\n            }\n            if (func(tmp, index, e)) {\n                next = tmp;\n                return;\n            }\n        }\n    }\n\n    return new java.util.Iterator() {\n        hasNext: function() {\n            findNext();\n            return next !== undefined;\n        },\n\n        next: function() {\n            if (next === undefined) {\n                // user may not have called hasMoreElements?\n                findNext();\n            }\n            if (next === undefined) {\n                throw \"NoSuchElementException\";\n            }\n            var res = next;\n            next = undefined;\n            return res;\n        },\n        \n        remove: function() {\n            throw \"NotSupportedOperation\";\n        }\n\n    };\n}\n\nfunction filterIterator(e, func, wrap) {\n    var next = undefined;\n    var index = 0;\n\n    function findNext() {\n        var tmp;\n        while (e.hasNext() && !cancelled.get()) {\n            tmp = e.next();\n            index++;\n            if (wrap) {\n                tmp = wrapJavaObject(tmp);\n            }\n            if (func(tmp, index, e)) {\n                next = tmp;\n                return;\n            }\n        }\n    }\n\n    return new java.util.Iterator() {\n        hasNext: function() {\n            findNext();\n            return next !== undefined;\n        },\n\n        next: function() {\n            if (next === undefined) {\n                // user may not have called hasMoreElements?\n                findNext();\n            }\n            if (next === undefined) {\n                throw \"NoSuchElementException\";\n            }\n            var res = next;\n            next = undefined;\n            return res;\n        },\n\n        remove: function() {\n            throw \"NotSupportedOperation\";\n        }\n\n    };\n}\n\n// enumeration that has no elements ..\nvar emptyEnumeration = new java.util.Enumeration() {\n    hasMoreElements: function() {\n        return false;\n    },\n    nextElement: function() {\n        throw \"NoSuchElementException\";\n    }\n};\n\nfunction wrapRoot(root) {\n    if (root) {\n        return {\n            get id() { return i = root.instance; return (i) ? i.getInstanceId() : 0; },\n            description: \"Reference \" + root.kind,\n            get referrer() { return wrapJavaValue(root.instance); },\n            type: root.kind,\n            wrapped: root\n        };\n    } else {\n        return null;\n    }\n}\n\nfunction wrapField(javaField) {\n    if (javaField) {\n        return {\n            name: javaField.name,\n            signature: javaField.type.name,\n            wrapped: javaField\n        };\n    } else {\n        return null;\n    }\n}\n\nfunction JavaClassProto() {    \n    function jclass(obj) {\n        return obj['wrapped-object'];\n    }\n\n    // return whether given class is subclass of this class or not\n    this.isSubclassOf = function(other) {\n        var tmp = jclass(this);\n        var otherid = objectid(other);\n        while (tmp != null) {\n            if (otherid.equals(String(tmp.javaClassId))) {\n                return true;\n            }\n            tmp = tmp.superClass;\n        }\n        return false;\n    }\n\n    // return whether given class is superclass of this class or not\n    this.isSuperclassOf = function(other) {\n        return other.isSubclassOf(this); \n    }\n\n    // includes direct and indirect superclasses\n    this.superclasses = function() {\n        var res = new Array();\n        var tmp = this.superclass;\n        while (tmp != null) {\n            res[res.length] = tmp;\n            tmp = tmp.superclass;\n        }\n        return res;\n    }\n\n    /**\n     * Returns an array containing subclasses of this class.\n     *\n     * @param indirect should include indirect subclasses or not.\n     *                 default is true.\n     */\n    this.subclasses = function(indirect) {\n        if (indirect === undefined) indirect = true;\n        var classes = wrapIterator(jclass(this).subClasses.iterator(), true);\n        var res = new Array();\n        while (classes.hasMoreElements()) {\n            var subclass = classes.nextElement();\n            res[res.length] = subclass;\n            if (indirect) {\n                res = res.concat(subclass.subclasses());\n            }\n        }\n        return res;\n    }\n\n    this.instances = function() {\n        return wrapIterator(jclass(this).instances.iterator(), true)\n    }\n\n    this.toString = function() { \n        return jclass(this).toString();\n    }\n}\n\nvar theJavaClassProto = new JavaClassProto();\n\n// Script wrapper for HAT model objects, values.\n// wraps a Java value as appropriate for script object\nfunction wrapJavaValue(thing) {\n    if (thing === null || thing === undefined) {\n        return null;\n    }\n\n    //    printStackTrace();\n    //    print(thing);\n\n    if (thing instanceof FieldValue) {\n        var type = thing.field.type;\n\n        // map primitive values to closest JavaScript primitives\n        if (type.name === \"boolean\") {\n            return thing.value === \"true\";\n        } else if (type.name === \"char\") {\n            return thing.value + '';\n        } else if (type.name === \"float\" ||\n            type.name === \"double\" ||\n            type.name === \"byte\" ||\n            type.name === \"short\" ||\n            type.name === \"int\" ||\n            type.name === \"long\"){\n            return java.lang.Double.parseDouble(thing.value);\n        } else {\n            // wrap Java object as script object\n            return wrapJavaObject(thing.instance);\n        }\n    } else if (thing instanceof GCRoot) {\n        return wrapRoot(thing);\n    } else if (thing instanceof Field) {\n        return wrapField(thing);\n    } else {\n        return wrapJavaObject(thing);\n    }\n}\n\n// HAT Java model object wrapper. Handles all cases \n// (instance, object/primitive array and Class objects)\t\nfunction javaObject(jobject) {\n    //        print(jobject.getClass());\n    if (jobject instanceof JavaClass) {\n        //            print(\"wrapping as Class\");\n        var classId = jobject.getJavaClassId();\n        if (classWrapperCache[classId] === undefined) {\n            classWrapperCache[classId] = new JavaClassWrapper(jobject);\n        }\n        return classWrapperCache[classId];\n    } else if (jobject instanceof ObjectArrayInstance) {\n        //            print(\"wrapping as ObjectArray\");\n        return new JavaObjectArrayWrapper(jobject);\n    } else if (jobject instanceof PrimitiveArrayInstance) {\n        // print(\"wrapping as ValueArray\");\n        return new JavaValueArrayWrapper(jobject);\n    } else if (jobject instanceof Instance) {\n        //            print(\"wrapping as Instance\");\n        return new JavaObjectWrapper(jobject);\n    } else {\n        //            print(\"unknown heap object type: \" + jobject.getClass());\n        return jobject;\n    }\n}\n\n// returns wrapper for Java instances\nfunction JavaObjectWrapper(instance) {\n    var things;\n    var fldValueCache = new Array();\n\n    // instance fields can be accessed in natural syntax\n    return new JSAdapter() {\n        __getIds__ : function() {\n            if (things === undefined) {\n                things = instance.getJavaClass().getFields();\n            }\n            var res = new Array(things.size());\n            for(var j=0;j<things.size();j++) {\n                res[j] = things.get(j).getName();\n            }\n            return res;\n        },\n        __has__ : function(name) {\n            if  (name === 'clazz' || name === 'toString' ||\n            name === 'id' || name === 'wrapped-object' || name === 'statics') {\n                return true;\n            }\n            if (things === undefined) {\n                things = instance.getJavaClass().getFields();\n            }\n            for (var i=0;i<things.size();i++) {\n                if (name == things.get(i).getName()) return true;\n            }\n            return false;\n        },\n        __get__ : function(name) {\n            if (name === 'clazz') {\n                if (fldValueCache[name] === undefined) {\n                    fldValueCache[name] = wrapJavaObject(instance.getJavaClass());\n                }\n                return fldValueCache[name];\n            } else if (name === 'statics') {\n                if (fldValueCache[name] === undefined) {\n                    var clz = wrapJavaObject(instance.getJavaClass());\n                    if (clz !== undefined) {\n                        fldValueCache[name] = clz.statics;\n                    } else {\n                        fldValueCache[name] = null;\n                    }\n                }\n                return fldValueCache[name];\n            } else if (name === 'id') {\n                if (fldValueCache[name] === undefined) {\n                    fldValueCache[name] = instance.getInstanceId();\n                }\n                return fldValueCache[name];\n            } else if (name === 'wrapped-object') {\n                return instance;\n            } else {\n                if (fldValueCache[\"_$\"+name] === undefined) {\n                    fldValueCache[\"_$\"+name] = wrapJavaObject(instance.getValueOfField(name));\n                }\n                return fldValueCache[\"_$\"+name];\n            }\n        },\n        __call__: function(name) {\n            if (name === 'toString') {\n                if (instance.getJavaClass().getName() === \"java.lang.String\") {\n                    return snapshot.valueString(instance);\n                }\n                return instance.toString();\n            } else {\n                return undefined;\n            }\n        }\n    }\t\t\t\t\n}\n\n// return wrapper for Java Class objects\nfunction JavaClassWrapper(jclass) {\n    var static_fields = jclass.staticFieldValues;\n    var fldValueCache = new Array();\n\n    // to access static fields of given Class cl, use \n    // cl.statics.<static-field-name> syntax\n    this.statics = new JSAdapter() {\n        __getIds__ : function() {\n            var res = new Array(static_fields.size());\n            for (var i=0;i<static_fields.size();i++) {\n                res[i] = static_fields.get(i).field.name;\n            }\n\n            return res;\n        },\n        __has__ : function(name) {\n            for (var i=0;i<static_fields.size();i++) {\n                if (name === static_fields.get(i).field.name) {\n                    return true;\n                }\t\t\t\t\t\n            }\n        },\n        __get__ : function(name) {\n            if (fldValueCache[\"_$\"+name] === undefined) {\n                var result;\n                result = wrapJavaObject(jclass.getValueOfStaticField(name));\n                fldValueCache[\"_$\"+name] = result;\n            }\n            return fldValueCache[\"_$\"+name];\n        },\n        __call__: function(name) {\n            if (name === 'toString') {\n                return jclass.toString();\n            } else {\n                return undefined;\n            }\n        }\n    }\n\n    if (jclass.superClass != null) {\n        this.superclass = wrapJavaValue(jclass.superClass);\n    } else {\n        this.superclass = null;\n    }\n\n    this.loader = wrapJavaObject(jclass.classLoader);\n    this.signers = wrapJavaValue(jclass.getSigners());\n    this.protectionDomain = wrapJavaValue(jclass.getProtectionDomain());\n    Object.defineProperty(this, \"fields\", {\n        get:function() { return wrapIterator(jclass.fields.iterator(), true); }\n    });\n    this.instanceSize = jclass.instanceSize;\n    this.name = jclass.name;\n    this.id = jclass.javaClassId;\n    this['wrapped-object'] = jclass;\n}\n\nfor (var i in theJavaClassProto) {\n    if (typeof theJavaClassProto[i] === 'function') {\n       JavaClassWrapper.prototype[i] = theJavaClassProto[i];\n    }\n}\n\n// returns wrapper for Java object arrays\nfunction JavaObjectArrayWrapper(array) {\n    var elements = array.values;\n    var fldValueCache = new Array();\n    // array elements can be accessed in natural syntax\n    // also, 'length' property is supported.\n    return new JSAdapter() {\n        __getIds__ : function() {\n            var res = new Array(elements.size());\n            for (var i = 0; i < elements.size(); i++) {\n                res[i] = String(i);\n            }\n            return res;\n        },\n        __has__: function(name) {\n            return (name >= 0 && name < elements.size())  ||\n            name === 'length' || name === 'clazz' ||\n            name === 'toString' || name === 'wrapped-object';\n        },\n        __get__ : function(name) {\n            if (name >= 0 && name < elements.size()) {\n                return wrapJavaValue(elements.get(name));\n            } else if (name === 'id') {\n                if (fldValueCache[name] === undefined) {\n                    fldValueCache[name] = array.instanceId;\n                }\n                return fldValueCache[name];\n            } else if (name === 'length') {\n                if (fldValueCache[\"len\"] === undefined) {\n                    fldValueCache[\"len\"] = elements.size();\n                }\n                return fldValueCache[\"len\"];\n            } else if (name === 'clazz') {\n                if (fldValueCache[name] === undefined) {\n                    fldValueCache[name] = wrapJavaObject(array.javaClass);\n                }\n                return fldValueCache[name];\n            } else if (name === 'wrapped-object') {\n                return array;\n            } else {\n                return undefined;\n            }\t\t\t\t\n        },\n        __call__: function(name) {\n            if (name === 'toString') {\n                return array.toString();\n            } else {\n                return undefined;\n            }\n        }\n    }\t\t\n}\n\n// returns wrapper for Java primitive arrays\nfunction JavaValueArrayWrapper(array) {\n    var elements = array.values;\n    var fldValueCache = new Array();\n    // array elements can be accessed in natural syntax\n    // also, 'length' property is supported.\n    return new JSAdapter() {\n        __getIds__ : function() {\n            var r = new Array(elements.size());\n            for (var i = 0; i < elements.size(); i++) {\n                r[i] = String(i);\n            }\n            return r;\n        },\n        __has__: function(name) {\n            return (name >= 0 && name < elements.size()) ||\n            name === 'length' || name === 'clazz' ||\n            name === 'toString' || name === 'wrapped-object';\n        },\n        __get__: function(name) {\n            if (name >= 0 && name < elements.size()) {\n                return elements.get(name);\n            }\n\n            if (name === 'length') {\n                if (fldValueCache[\"len\"] === undefined) {\n                    fldValueCache[\"len\"] = elements.size();\n                }\n                return fldValueCache[\"len\"];\n            } else if (name === 'wrapped-object') {\n                return array;\n            } else if (name === 'clazz') {\n                if (fldValueCache[name] === undefined) {\n                    fldValueCache[name] = wrapJavaObject(array.javaClass);\n                }\n                return fldValueCache[name];\n            } else {\n                return undefined;\n            }\n        },\n        __call__: function(name) {\n            if (name === 'toString') {\n                if (array.javaClass.name === 'char[]') {\n                        return snapshot.valueString(array);\n                    }\n                return array.toString();\n            } else {\n                return undefined;\n            }\n        }\n    }\n}\n\n// wrap Java object with appropriate script object\nfunction wrapJavaObject(thing) {\n    if (thing === null) return null;\n    \n    return javaObject(thing);\n}\n\n// unwrap a script object to corresponding HAT object\nfunction unwrapJavaObject(jobject) {\n    //    print(\"Unwrapping object\");\n    //    print(typeof(jobject));\n    \n    if (!(jobject instanceof Instance)) {\n        if (jobject instanceof Array) {\n            //            print(\"Object is array\");\n            var arr = new java.util.ArrayList(jobject.length);\n\n            for (var index in jobject) {\n                arr.add(jobject[index]);\n            }\n            return arr.toArray();\n        }\n        \n        try {\n            //            print(typeof(jobject));\n            var orig = jobject;\n            jobject = orig[\"wrapped-object\"];\n            if (jobject === undefined) {\n                jobject = orig.wrapped;\n            }\n            if (jobject === undefined) {\n                jobject = orig;\n            }\n        } catch (e) {\n            //print(\"unwrapJavaObject: \" + jobject + \", \" + e);\n            jobject = undefined;\n        }\n    }\n    return jobject;\n}\n\nfunction unwrapMap(jobject) {\n    var map = new java.util.HashMap();\n    for(var prop in jobject) {\n        //        print(\"adding \" + prop + \" = \" + unwrapJavaObject(jobject[prop]));\n        map.put(prop, unwrapJavaObject(jobject[prop]));\n    }\n    return map;\n}\n\nfunction unwrapArray(jsobject) {\n    var array = new Object[jsobject.length];\n\n    for(var i=0;i<jsobject.lenght;i++) {\n        array[i] = jsobject[i];\n    }\n\n    return array;\n}\n\nfunction unwrapJavaObjectRes(jobject) {\n    var ret = unwrapJavaObject(jobject);\n\n    if (ret === jobject) {\n        return null;\n    }\n    return ret;\n}\n\n/**\n * The result object supports the following methods:\n * \n *  forEachClass  -- calls a callback for each Java Class\n *  forEachObject -- calls a callback for each Java object\n *  findClass -- finds Java Class of given name\n *  findObject -- finds object from given object id\n *  objects -- returns all objects of given class as an enumeration\n *  classes -- returns all classes in the heap as an enumeration\n *  reachables -- returns all objects reachable from a given object\n *  livepaths -- returns an array of live paths because of which an\n *               object alive.\n *  describeRef -- returns description for a reference from a 'from' \n *              object to a 'to' object.\n */\nfunction wrapHeapSnapshot(heap) {\n    function getClazz(clazz) {\n        if (clazz === undefined) clazz = \"java.lang.Object\";\n        var type = typeof(clazz);\n        if (type === \"string\") {\n            clazz = heap.findClass(clazz);\n        } else if (type === \"object\") {\n            clazz = unwrapJavaObject(clazz);\n        } else {\n            throw \"class expected\";;\n        }\n        return clazz;\n    }\n\n    snapshot = heap;\n    classWrapperCache = new Array();\n\n    // return heap as a script object with useful methods.\n    return {\n        snapshot: heap,\n\n        /**\n         * Class iteration: Calls callback function for each\n         * Java Class in the heap. Default callback function \n         * is 'print'. If callback returns true, the iteration \n         * is stopped.\n         *\n         * @param callback function to be called.\n         */\n        forEachClass: function(callback) {\n            if (callback === undefined) callback = print;\n            var classes = this.snapshot.classes;\n            while (classes.hasNext() && !cancelled.get()) {\n                var wrapped = wrapJavaObject(classes.next());\n\n                if (wrapped != null && callback(wrapped))\n                    return;\n            }\n        },\n\n        /**\n         * Returns an Enumeration of all roots.\n         */\n        roots: function() {\n            return wrapIterator(this.snapshot.roots, true);\n        },\n\n        /**\n         * Returns an Enumeration for all Java classes.\n         */\n        classes: function() {\n            return wrapIterator(this.snapshot.classes, true);\n        },\n\n        /**\n         * Object iteration: Calls callback function for each\n         * Java Object in the heap. Default callback function \n         * is 'print'.If callback returns true, the iteration \n         * is stopped.\n         *\n         * @param callback function to be called. \n         * @param clazz Class whose objects are retrieved.\n         *        Optional, default is 'java.lang.Object'\n         * @param includeSubtypes flag to tell if objects of subtypes\n         *        are included or not. optional, default is true.\n         */\n        forEachObject: function(callback, clazz, includeSubtypes) {\n            if (includeSubtypes === undefined) includeSubtypes = true;\n            if (callback === undefined) callback = print;\n            clazz = getClazz(clazz);\n\n            if (clazz) {\n                //                var instances = clazz.getInstances(includeSubtypes); // TODO\n                var instances = snapshot.getInstances(clazz, includeSubtypes);\n                while (instances.hasNext() && !cancelled.get()) {\n                    if (callback(wrapJavaObject(instances.next())))\n                        return;\n                }\n            }\n        },\n\n        /** \n         * Returns an enumeration of Java objects in the heap.\n         * \n         * @param clazz Class whose objects are retrieved.\n         *        Optional, default is 'java.lang.Object'\n         * @param includeSubtypes flag to tell if objects of subtypes\n         *        are included or not. optional, default is true.\n         * @param where (optional) filter expression or function to\n         *        filter the objects. The expression has to return true\n         *        to include object passed to it in the result array. \n         *        Built-in variable 'it' refers to the current object in \n         *        filter expression.\n         */\n        objects: function(clazz, includeSubtypes, where) {\n            if (includeSubtypes === undefined) includeSubtypes = true;\n            if (where) {\n                if (typeof(where) === 'string') {\n                    where = new Function(\"it\", \"return \" + where);\n                }\n            }\n            clazz = getClazz(clazz);\n            if (clazz) {\n                if (where) {\n                    return filterIterator(snapshot.getInstances(clazz, includeSubtypes), where, true);\n                } else {\n                    return wrapIterator(snapshot.getInstances(clazz, includeSubtypes), true);\n                }\n            } else {\n                return emptyEnumeration;\n            }\n        },\n\n        /**\n         * Find Java Class of given name.\n         * \n         * @param name class name\n         */\n        findClass: function(name) {\n            var clazz = this.snapshot.findClass(name + '');\n            return wrapJavaObject(clazz);\n        },\n\n        /**\n         * Find Java Object from given object id\n         *\n         * @param id object id as string\n         */\n        findObject: function(id) {\n            return wrapJavaValue(this.snapshot.findThing(id));\n        },\n\n        /**\n         * Returns an enumeration of objects in the finalizer\n         * queue waiting to be finalized.\n         */\n        finalizables: function() {\n            var tmp = this.snapshot.getFinalizerObjects();\n            return wrapIterator(tmp);\n        },\n \n        /**\n         * Returns an array that contains objects referred from the\n         * given Java object directly or indirectly (i.e., all \n         * transitively referred objects are returned).\n         *\n         * @param jobject Java object whose reachables are returned.\n         */\n        reachables: function (jobject) {\n            return reachables(jobject, this.snapshot.reachableExcludes);\n        },\n\n        /**\n         * Returns array of paths of references by which the given \n         * Java object is live. Each path itself is an array of\n         * objects in the chain of references. Each path supports\n         * toHtml method that returns html description of the path.\n         *\n         * @param jobject Java object whose live paths are returned\n         * @param weak flag to indicate whether to include paths with\n         *             weak references or not. default is false.\n         */\n        livepaths: function (jobject, weak) {\n            if (weak === undefined) {\n                weak = false;\n            }\n\n            function wrapRefChain(refChain) {\n                var path = new Array();\n\n                // compute path array from refChain\n                var tmp = refChain;\n                while (tmp != null) {\n                    var obj = tmp.obj;\n                    path[path.length] = wrapJavaValue(obj);\n                    tmp = tmp.next;\n                }\n\n                function computeDescription(html) {\n                    var root = refChain.obj.root;\n                    var desc = root.description;\n                    if (root.referer) {\n                        var ref = root.referer;\n                        desc += \" (from \" + \n                        (html? toHtml(ref) : ref.toString()) + ')';\n                    }\n                    desc += '->';\n                    var tmp = refChain;\n                    while (tmp != null) {\n                        var next = tmp.next;\n                        var obj = tmp.obj;\n                        desc += html? toHtml(obj) : obj.toString();\n                        if (next != null) {\n                            desc += \" (\" + \n                            obj.describeReferenceTo(next.obj, heap)  +\n                            \") ->\";\n                        }\n                        tmp = next;\n                    }\n                    return desc;\n                }\n\n                return new JSAdapter() {\n                    __getIds__ : function() {\n                        var res = new Array(path.length);\n                        for (var i = 0; i < path.length; i++) {\n                            res[i] = String(i);\n                        }\n                        return res;\n                    },\n                    __has__ : function (name) {\n                        return (name >= 0 && name < path.length) ||\n                        name === 'length' || name === 'toHtml' ||\n                        name === 'toString' || name === 'wrapped-object';\n                    },\n                    __get__ : function(name) {\n                        if (name >= 0 && name < path.length) {\n                            return path[name];\n                        } else if (name === 'length') {\n                            return path.length;\n                        } else if (name === 'wrapped-object') {\n                            return refChain;\n                        } else {\n                            return undefined;\n                        }\n                    },\n                    __call__: function(name) {\n                        if (name === 'toString') {\n                            return computeDescription(false);\n                        } else if (name === 'toHtml') {\n                            return computeDescription(true);\n                        }else {\n                            return undefined;\n                        }\n                    }\n                };\n            }\n\n            jobject = unwrapJavaObject(jobject);\n            var refChains = this.snapshot.rootsetReferencesTo(jobject, weak);\n\n            var paths = new java.util.Enumeration() {\n                counter: 0,\n                hasMoreElements: function() {\n                    return this.counter < refChains.length\n                },\n                nextElement: function() {\n                    return wrapRefChain(refChains[this.counter++])\n                }\n            }\n            return paths;\n        },\n\n        /**\n         * Return description string for reference from 'from' object\n         * to 'to' Java object.\n         *\n         * @param from source Java object\n         * @param to destination Java object\n         */\n        describeRef: function (from, to) {\n            from = unwrapJavaObject(from);\n            to = unwrapJavaObject(to);\n            return from.describeReferenceTo(to, this.snapshot);\n        }\n\n    };\n}\n\n// per-object functions\n\n/**\n * Returns allocation site trace (if available) of a Java object\n *\n * @param jobject object whose allocation site trace is returned\n */\nfunction allocTrace(jobject) {\n    try {\n        jobject = unwrapJavaObject(jobject);\t\t\t\n        var trace = jobject.allocatedFrom;\n        return (trace != null) ? trace.frames : null;\n    } catch (e) {\n        print(\"allocTrace: \" + jobject + \", \" + e);\n        return null;\n    }\n}\n\n/**\n * Returns Class object for given Java object\n *\n * @param jobject object whose Class object is returned\n */\nfunction classof(jobject) {\n    jobject = unwrapJavaObject(jobject);\n    return wrapJavaValue(jobject.javaClass);\n}\n\n/**\n * Find referers (a.k.a in-coming references). Calls callback\n * for each referrer of the given Java object. If the callback \n * returns true, the iteration is stopped.\n *\n * @param callback function to call for each referer\n * @param jobject object whose referers are retrieved\n */\nfunction forEachReferrer(callback, jobject) {\n    //    jobject = unwrapJavaObject(jobject);\n    var refs = referrers(jobject);\n    while (refs.hasMoreElements() && !cancelled.get()) {\n        var referrer = refs.nextElement();\n        if (callback(wrapJavaValue(referrer))) {\n            return;\n        }\n    }\n}\n\nfunction forEachReferee(callback, jobject) {\n    var refs = referees(jobject);\n    while (refs.hasMoreElements() && !cancelled.get()) {\n        var referrer = refs.nextElement();\n        if (callback(wrapJavaValue(referrer))) {\n            return;\n        }\n    }\n}\n\n/**\n * Compares two Java objects for object identity.\n *\n * @param o1, o2 objects to compare for identity\n */\nfunction identical(o1, o2) {\n    return objectid(o1) === objectid(o2);\n}\n\n/**\n * Returns Java object id as string\n *\n * @param jobject object whose id is returned\n */\nfunction objectid(jobject) {\n    try {\n        jobject = unwrapJavaObject(jobject);\n        if (jobject instanceof Instance) {\n            return String(jobject.instanceId);\n        } else if (jobject instanceof JavaClass) {\n            return String(jobject.javaClassId);\n        }\n    } catch (e) {\n        print(\"objectid: \" + jobject + \", \" + e);\n        return null;\n    }\n}\n\n/**\n * Prints allocation site trace of given object\n *\n * @param jobject object whose allocation site trace is returned\n */\nfunction printAllocTrace(jobject) {\n    var frames = this.allocTrace(jobject);\n    if (frames === null || frames.length === 0) {\n        print(\"allocation site trace unavailable for \" + \n            objectid(jobject));\n        return;\n    }    \n    print(objectid(jobject) + \" was allocated at ..\");\n    for (var i in frames) {\n        var frame = frames[i];\n        var src = frame.sourceFileName;\n        if (src === null) src = '<unknown source>';\n        print('\\t' + frame.className + \".\" +\n            frame.methodName + '(' + frame.methodSignature + ') [' +\n            src + ':' + frame.lineNumber + ']');\n    }\n}\n\n/**\n * Returns an enumeration of referrers of the given Java object.\n *\n * @param jobject Java object whose referrers are returned.\n * @param weak Boolean flag indicating whether to include weak references\n */\nfunction referrers(jobject, weak) {\n    try {\n        if (weak === undefined) {\n            weak = false\n        }\n        jobject = unwrapJavaObject(jobject);\n        return wrapIterator(this.snapshot.getReferrers(jobject, weak));\n    } catch (e) {\n        print(\"referrers: \" + jobject + \", \" + e);\n        return emptyEnumeration;\n    }\n}\n\n/**\n * Returns an array that contains objects referred from the\n * given Java object.\n *\n * @param jobject Java object whose referees are returned.\n * @param weak Boolean flag indicating whether to include weak references\n */\nfunction referees(jobject, weak) {\n    try {\n        if (weak === undefined) {\n            weak = false;\n        }\n        jobject = unwrapJavaObject(jobject);\n        return wrapIterator(this.snapshot.getReferees(jobject, weak));\n    } catch (e) {\n        print(\"referees: \" + jobject + \", \" + e);\n        return emptyEnumeration;\n    }\n}\n\n/**\n * Returns an array that contains objects referred from the\n * given Java object directly or indirectly (i.e., all \n * transitively referred objects are returned).\n *\n * @param jobject Java object whose reachables are returned.\n * @param excludes optional comma separated list of fields to be \n *                 removed in reachables computation. Fields are\n *                 written as class_name.field_name form.\n */\nfunction reachables(jobject, excludes) {\n    if (excludes === undefined) {\n        excludes = null;\n    } else if (typeof(excludes) === 'string') {\n        var st = new java.util.StringTokenizer(excludes, \",\");\n        var excludedFields = new Array();\n        while (st.hasMoreTokens() && !cancelled.get()) {\n            excludedFields[excludedFields.length] = st.nextToken().trim();\n        }\n        if (excludedFields.length > 0) { \n            excludes = new ReachableExcludes() {\n                isExcluded: function (field) {\n                    for (var index in excludedFields) {\n                        if (field.equals(excludedFields[index])) {\n                            return true;\n                        }\n                    }\n                    return false;\n                }\n            };\n        } else {\n            // nothing to filter...\n            excludes = null;\n        }\n    } else if (! (excludes instanceof ReachableExcludes)) {\n        excludes = null;\n    }\n\n    jobject = unwrapJavaObject(jobject);\n    var ro = new ReachableObjects(jobject, excludes);\n    return wrapIterator(ro.reachables, true);\n}\n\n\n/**\n * Returns whether 'from' object refers to 'to' object or not.\n *\n * @param from Java object that is source of the reference.\n * @param to Java object that is destination of the reference.\n */\nfunction refers(from, to) {\n    try {\n        var tmp = unwrapJavaObject(from);\n        if (tmp instanceof JavaClass) {\n            from = from.statics;\n        } else if (tmp instanceof PrimitiveArrayInstance) {\n            return false;\n        }\n        for (var i in from) {\n            if (identical(from[i], to)) {\n                return true;\n            }\n        }\n    } catch (e) {\n        print(\"refers: \" + from + \", \" + e);\n    }\n    return false;\n}\n\n/**\n * If rootset includes given jobject, return Root\n * object explanining the reason why it is a root.\n *\n * @param jobject object whose Root is returned\n */\nfunction root(jobject) {\n    try {\n        jobject = unwrapJavaObject(jobject);\n        var root = wrapRoot(snapshot.findRoot(jobject));\n        return root;\n    } catch (e) {\n        return null;\n    }\n}\n\n/**\n * If given jobject has a path to GC root, return distance\n * to nearest GC root.\n *\n * @param jobject object whose distance to the nearest GC root is returned\n */\nfunction rootDistance(jobject) {\n    try {\n        jobject = unwrapJavaObject(jobject);\n        return snapshot.distanceToGCRoot(jobject);\n    } catch (e) {\n        return 0;\n    }\n}\n\n/**\n * Returns size of the given Java object\n *\n * @param jobject object whose size is returned\n */\nfunction sizeof(jobject) {\n    try {\n        jobject = unwrapJavaObject(jobject);\n        return jobject.size;\n    } catch (e) {\n        print(\"sizeof: \" + jobject + \", \" + e);\n        return null;\n    }\n}\n\nfunction rsizeof(jobject) {\n    try {\n        jobject = unwrapJavaObject(jobject);\n        return jobject.retainedSize;\n    } catch (e) {\n        print(\"rsizeof: \" + jobject + \", \" + e);\n        return null;\n    }\n}\n\n/**\n * Returns HTML string for the given object.\n *\n * @param obj object for which HTML string is returned.\n */\nfunction toHtml(obj) {\n    if (obj === null) {\n        return \"null\";\n    } \n\n    if (obj === undefined) {\n        return \"undefined\";\n    } \n    //print(\"tohtml \"+typeof(obj));\n    var tmp = unwrapJavaObject(obj);\n    if (tmp !== undefined) {\n        //print(\"1\");\n        if (tmp instanceof JavaClass) {\n            //print(\"2\");\n            // must use the same format as defined in org.graalvm.visualvm.lib.profiler.heapwalker.v2.utils.HeapUtils.classToHtml()\n            var id = tmp.javaClassId;\n            var name = tmp.name;\n            return \"<a href='file://class/\" + id + \"' name='\" + id + \"'>class \" + name + \"</a>\";\n        }else if (tmp instanceof Instance) {\n            //print(\"3\");\n            // must use the same format as defined in org.graalvm.visualvm.lib.profiler.heapwalker.v2.utils.HeapUtils.instanceToHtml()\n            var id = tmp.instanceId;\n            var number = tmp.instanceNumber;\n            var name = tmp.javaClass.name;\n            return \"<a href='file://instance/\" + id + \"' name='\" + id + \"'>\" + name + \"#\" + number + \"</a>\";\n        }\n        //print(\"31 \"+typeof(tmp));\n    }\n    if (obj instanceof Object) {\n        //print(\"4\");\n        if (Array.isArray(obj)) {\n            //print(\"5\");\n            // script array\n            var res = \"[ \";\n            for (var i in obj) {\n                res += toHtml(obj[i]);\n                if (i != obj.length - 1) {\n                    res += \", \";\n                }\n                if (cancelled.get()) break;\n            } \n            res += \" ]\";\n            return res;\n        } else {\n            //print(\"6\");\n            // if the object has a toHtml function property\n            // just use that...\n            if (typeof(obj.toHtml) === 'function') {\n                //print(\"7\");\n                return obj.toHtml();\n            } else {\n                //print(\"8\");\n                // script object\n                var res = \"{ \";\n                for (var i in obj) {\n                    res +=  i + \":\" + toHtml(obj[i]) + \", \";\n                }\n                res += \"}\";\n                return res;\n            }\n        }\n    } else {\n        //print(\"9\");\n        // script wrapped Java object\n        obj = wrapIterator(obj);\n        // special case for enumeration\n        if (obj instanceof java.util.Enumeration) {\n            //print(\"A\");\n            var res = \"[ \";\n            while (obj.hasMoreElements() && !cancelled.get()) {\n                res += toHtml(obj.nextElement()) + \", \";\n            }\n            res += \"]\";\n            return res; \n        } else {\n            //print(\"B\");\n            return obj.toString().replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\");\n        }\n    }\n}\n\n/*\n * Generic array/iterator/enumeration [or even object!] manipulation \n * functions. These functions accept an array/iteration/enumeration\n * and expression String or function. These functions iterate each \n * element of array and apply the expression/function on each element.\n */\n\n// private function to wrap an Iterator as an Enumeration\nfunction wrapIterator(itr, wrap) {\n    if (isJsArray(itr)) {\n        return itr;\n    } else if (itr instanceof java.util.Iterator) {\n        return new java.util.Enumeration() {\n            hasMoreElements: function() {\n                return itr.hasNext() && !cancelled.get();\n            },\n            nextElement: function() {\n                return wrap? wrapJavaValue(itr.next()) : itr.next();\n            },\n            wrapped: itr\n        };\n    } else if (itr instanceof java.util.Enumeration) {\n        return itr; // already wrapped\n    } else if (itr instanceof ObjectArrayInstance) {\n        return wrapJavaObject(itr);\n    } else if (itr instanceof PrimitiveArrayInstance) {\n        return wrapJavaObject(itr);\n    } else if (itr.constructor === JavaClassProto && !(itr instanceof JSAdapter)) {\n        var arr = new Array();\n        arr[0] = itr;\n        return arr;\n    } else {\n        return itr;\n    }\n}\n\n/**\n * Converts an enumeration/iterator/object into an array\n *\n * @param obj enumeration/iterator/object\n * @return array that contains values of enumeration/iterator/object\n */\nfunction toArray(obj) {\t\n    obj = wrapIterator(obj);\n    if (obj instanceof java.util.Enumeration) {\n        var res = new Array();\n        while (obj.hasMoreElements() && !cancelled.get()) {\n            res[res.length] = obj.nextElement();\n        }\n        return res;\n    } else if (obj instanceof Array) {\n        return obj;\n    } else {\n        var res = new Array();\n        for (var index in obj) {\n            res[res.length] = obj[index];\n            if (cancelled.get()) break;\n        }\n        return res;\n    }\n}\n\nfunction top(array, code, num) {\n    if (array === undefined) {\n        return array;\n    }\n    var func;\n    if (code === undefined) {\n        func = function(lhs, rhs) {\n            return 1; // first-come order\n        }\n    } else if (typeof(code) === 'string') {\n        func = new Function(\"lhs\", \"rhs\", \"return \" + code);\n    } else {\n        func = code;\n    }\n\n    if (num === undefined) {\n        num = 10;\n    }\n    array = wrapIterator(array, true);\n\n    if (array instanceof java.util.Enumeration) {\n        var sorted = new Array();\n\n        while(array.hasMoreElements() && !cancelled.get()) {\n            var element = array.nextElement();\n            if (sorted.length > 0) {\n                if (sorted.length >= num && func(element, sorted[num -1]) >=0 ) continue;\n            }\n\n            var index = search(sorted, element, true, func);\n            for(var counter=Math.min(sorted.length, num - 1);counter > index;counter--) {\n                sorted[counter] = sorted[counter - 1];\n            }\n            sorted[index] = element;\n        }\n        sorted.length = Math.min(sorted.length, num);\n        return sorted;\n    } else if (array instanceof Array) {\n        var result = array.sort(func);\n        result.length = Math.min(result.length, num);\n        return result;\n    }\n    return array;\n}\n\n/**\n * Returns whether the given array/iterator/enumeration contains \n * an element that satisfies the given boolean expression specified \n * in code. \n *\n * @param array input array/iterator/enumeration that is iterated\n * @param code  expression string or function \n * @return boolean result\n *\n * The code evaluated can refer to the following built-in variables. \n *\n * 'it' -> currently visited element\n * 'index' -> index of the current element\n * 'array' -> array that is being iterated\n */\nfunction contains(array, code) {\n    array = wrapIterator(array);\n    var func = code;\n    if (typeof(func) != 'function') {\n        func = new Function(\"it\", \"index\", \"array\",  \"return \" + code);\n    }\n\n    if (array instanceof java.util.Enumeration) {\n        var index = 0;\n        while (array.hasMoreElements()) {\n            var it = array.nextElement();\n            if (func(it, index, array)) {\n                return true;\n            }\n            index++;\n        }\n    } else {\n        for (var index in array) {\n            var it = array[index];\n            if (func(it, index, array)) {\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\n/**\n * concatenates two arrays/iterators/enumerators.\n *\n * @param array1 array/iterator/enumeration\n * @param array2 array/iterator/enumeration\n *\n * @return concatenated array or composite enumeration\n */\nfunction concat(array1, array2) {\n    array1 = wrapIterator(array1);\n    array2 = wrapIterator(array2);\n    if (array1 instanceof Array && array2 instanceof Array) {\n        return array1.concat(array2);\n    } else if (array1 instanceof java.util.Enumeration &&\n        array2 instanceof java.util.Enumeration) {\n        return this.snapshot.concat(array1, array2);\n    } else {\n        return undefined;\n    }\n}\n\n/**\n * Returns the number of array/iterator/enumeration elements \n * that satisfy the given boolean expression specified in code. \n * The code evaluated can refer to the following built-in variables. \n *\n * @param array input array/iterator/enumeration that is iterated\n * @param code  expression string or function \n * @return number of elements\n *\n * 'it' -> currently visited element\n * 'index' -> index of the current element\n * 'array' -> array that is being iterated\n */\nfunction count(array, code) {\n    if (code === undefined) {\n        return length(array);\n    }\n    array = wrapIterator(array);\n    var func = code;\n    if (typeof(func) != 'function') {\n        func = new Function(\"it\", \"index\", \"array\",  \"return \" + code);\n    }\n\n    var result = 0;\n    if (array instanceof java.util.Enumeration) {\n        var index = 0;\n        while (array.hasMoreElements()) {\n            var it = array.nextElement();\n            if (func(it, index, array)) {\n                result++;\n            }\n            index++;\n        }\n    } else {\n        for (var index in array) {\n            var it = array[index];\n            if (func(it, index, array)) {\n                result++;\n            }\n        }\n    }\n    return result;\n}\n\n/**\n * filter function returns an array/enumeration that contains \n * elements of the input array/iterator/enumeration that satisfy \n * the given boolean expression. The boolean expression code can \n * refer to the following built-in variables. \n *\n * @param array input array/iterator/enumeration that is iterated\n * @param code  expression string or function \n * @return array/enumeration that contains the filtered elements\n *\n * 'it' -> currently visited element\n * 'index' -> index of the current element\n * 'array' -> array that is being iterated\n * 'result' -> result array\n */\nfunction filter(array, code) {\n    array = wrapIterator(array);\n    var func = code;\n    if (typeof(code) != 'function') {\n        func = new Function(\"it\", \"index\", \"array\", \"result\", \"return \" + code);\n    }\n    if (array instanceof java.util.Enumeration) {\n        return filterEnumeration(array, func, true);\n    } else if (array instanceof java.util.Iterator) {\n        return filterIterator(array, func, true);\n    } else {\n        var result = new Array();\n        for (var index in array) {\n            var it = array[index];\n            if (func(wrapJavaObject(it), index, array, result)) {\n                result[result.length] = it;\n            }\n            if (cancelled.get()) break;\n        }\n        return result;\n    }\n}\n\n/**\n * Returns the number of elements of array/iterator/enumeration.\n *\n * @param array input array/iterator/enumeration that is iterated\n */\nfunction length(array) {\n    array = wrapIterator(array);\n    var length = array.length;\n\n    if (length !== undefined) return length;\n    \n    if (array instanceof java.util.Enumeration) {\n        var cnt = 0;\n        while (array.hasMoreElements()) {\n            array.nextElement(); \n            cnt++;\n        }\n        return cnt;\n    } else {\n        var cnt = 0;\n        for (var index in array) {\n            cnt++;\n        }\n        return cnt;\n    }\n}\n\n/**\n * Transforms the given object or array by evaluating given code\n * on each element of the object or array. The code evaluated\n * can refer to the following built-in variables. \n *\n * @param array input array/iterator/enumeration that is iterated\n * @param code  expression string or function \n * @return array/enumeration that contains mapped values\n *\n * 'it' -> currently visited element\n * 'index' -> index of the current element\n * 'array' -> array that is being iterated\n * 'result' -> result array\n *\n * map function returns an array/enumeration of values created \n * by repeatedly calling code on each element of the input\n * array/iterator/enumeration.\n */\nfunction map(array, code) {\n    array = wrapIterator(array);\n    var func = code;\n    if(typeof(code) != 'function') {\n        func = new Function(\"it\", \"index\", \"array\", \"result\", \"return \" + code);\n    }\n\n    if (array instanceof java.util.Enumeration) {\n        var index = 0;\n        var result = new java.util.Enumeration() {\n            hasMoreElements: function() {\n                return array.hasMoreElements();\n            },\n            nextElement: function() {\n                return func(wrapJavaObject(array.nextElement()), index++, array, result);\n            }\n        };\n        return result;\n    } else {\n        var result = new Array();\n        for (var index in array) {\n            var it = array[index];\n            if (it instanceof java.util.Enumeration) {\n                var counter = 0;\n                while(it.hasMoreElements() && !cancelled.get()) {\n                    result[result.length] = func(wrapJavaObject(it.nextElement()), counter++, it, result);\n                }\n            } else {\n                result[result.length] = func(wrapJavaObject(it), index, array, result);\n            }\n            if (cancelled.get()) break;\n        }\n        return result;\n    }\n}\n\n// private function used by min, max functions\nfunction minmax(array, code) {\n    if (typeof(code) === 'string') {\n        code = new Function(\"lhs\", \"rhs\", \"return \" + code);\n    }\n    array = wrapIterator(array);\n    if (array instanceof java.util.Enumeration) {\n        if (! array.hasMoreElements()) {\n            return undefined;\n        }\n        var res = array.nextElement();\n        while (array.hasMoreElements() && !cancelled.get()) {\n            var next = array.nextElement();\n            if (code(next, res)) {\n                res = next;\n            }\n        }\n        return res;\n    } else {\n        if (array.length === 0) {\n            return undefined;\n        }\n        var res = array[0];\n        for (var index = 1; index < array.length; index++) {\n            if (code(array[index], res)) {\n                res = array[index];\n            }\n            if (cancelled.get()) break;\n        } \n        return res;\n    }\n}\n\n/**\n * Returns the maximum element of the array/iterator/enumeration\n *\n * @param array input array/iterator/enumeration that is iterated\n * @param code (optional) comparision expression or function\n *        by default numerical maximum is computed.\n */\nfunction max(array, code) {\n    if (code === undefined) {\n        code = function (lhs, rhs) { \n            return lhs > rhs;\n        }\n    }\n    return minmax(array, code);\n}\n\n/**\n * Returns the minimum element of the array/iterator/enumeration\n *\n * @param array input array/iterator/enumeration that is iterated\n * @param code (optional) comparision expression or function\n *        by default numerical minimum is computed.\n */\nfunction min(array, code) {\n    if (code === undefined) {\n        code = function (lhs, rhs) { \n            return lhs < rhs;\n        }\n    } \n    return minmax(array, code);\n}\n\n/**\n * sort function sorts the input array. optionally accepts\n * code to compare the elements. If code is not supplied,\n * numerical sort is done.\n *\n * @param array input array/iterator/enumeration that is sorted\n * @param code  expression string or function \n * @return sorted array \n *\n * The comparison expression can refer to the following\n * built-in variables:\n *\n * 'lhs' -> 'left side' element\n * 'rhs' -> 'right side' element\n */\nfunction sort(array, code) {\n    // we need an array to sort, so convert non-arrays\n    array = toArray(array);\n    \n    // by default use numerical comparison\n    var func = code;\n    if (code === undefined) {\n        func = function(lhs, rhs) { \n            return lhs - rhs;\n        };\n    } else if (typeof(code) === 'string') {\n        func = new Function(\"lhs\", \"rhs\", \"return \" + code);\n    }\n    return array.sort(func);\n}\n\n/**\n * Returns the sum of the elements of the array\n *\n * @param array input array that is summed.\n * @param code optional expression used to map\n *        input elements before sum.\n */\nfunction sum(array, code) {\n    array = wrapIterator(array);\n    if (code !== undefined) {\n        array = map(array, code);\n    }\n    var result = 0;\n    if (array instanceof java.util.Enumeration) {\n        while (array.hasMoreElements() && !cancelled.get()) {\n            result += Number(array.nextElement());\n        }\n    } else {\n        for (var index in array) {\n            result += Number(array[index]);\n            if (cancelled.get()) break;\n        }\n    }\n    return result;\n}\n\n/**\n * Returns array of unique elements from the given input \n * array/iterator/enumeration.\n *\n * @param array from which unique elements are returned.\n * @param code optional expression (or function) giving unique\n *             attribute/property for each element.\n *             by default, objectid is used for uniqueness.\n */\nfunction unique(array, code) {\n    array = wrapIterator(array);\n    if (code === undefined) {\n        code = new Function(\"it\", \"var id = objectid(it);return id !== undefined ? id : it;\");\n    } else if (typeof(code) === 'string') {\n        code = new Function(\"it\", \"return \" + code);\n    }\n    var tmp = new Object();\n    if (array instanceof java.util.Enumeration) {\n        while (array.hasMoreElements() && !cancelled.get()) {\n            var it = array.nextElement();\n            tmp[code(it)] = it;\n        }\n    } else {\n        for (var index in array) {\n            var it = array[index];\n            tmp[code(it)] = it;\n            if (cancelled.get()) break;\n        }\n    }\n    var res = new Array();\n    for (var index in tmp) {\n        res[res.length] = tmp[index];\n        if (cancelled.get()) break;\n    }\n    return res;\n}\n\nfunction printStackTrace() {\n    try {\n        var c = undefined;\n        c.toString();\n    } catch (e) {\n        e.rhinoException.printStackTrace();\n    }\n}\n\nfunction isJsArray(obj) {\n    if (obj.constructor === undefined) {\n        return false;\n    }\n    return obj.constructor === Array;\n}\n\nfunction search(a, v, i, func){\n    var h = a.length, l = -1, m;\n    while(h - l > 1) {\n        if(func(a[m = h + l >> 1], v) < 0) l = m;\n        else h = m;\n        if (cancelled.get()) return -1;\n    }\n    return a[h] != v ? i ? h : -1 : h;\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/icons/OQLIcons.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.oql.icons;\n\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface OQLIcons extends Icons.Keys {\n\n    public static final String OQL = \"OQLIcons.OQL\"; // NOI18N\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/icons/impl/OQLIconsProviderImpl.java",
    "content": "/*\n * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.oql.icons.impl;\n\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.profiler.oql.icons.OQLIcons;\nimport org.graalvm.visualvm.lib.profiler.spi.IconsProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=IconsProvider.class)\npublic final class OQLIconsProviderImpl extends IconsProvider.Basic {\n\n    @Override\n    protected final void initStaticImages(Map<String, String> cache) {\n        cache.put(OQLIcons.OQL, \"oql.png\"); // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.2//EN\" \"http://www.netbeans.org/dtds/filesystem-1_2.dtd\">\n<filesystem>\n    <folder name=\"NBProfiler\">\n        <folder name=\"Config\">\n            <folder name=\"OQL\">\n                <folder name=\"samples\">\n                    <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.resources.Bundle#NBProfiler/Config/OQL/samplesName\"/>\n                    <attr name=\"desc\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.resources.Bundle#NBProfiler/Config/OQL/samplesDescr\"/>\n                    <attr name=\"position\" intvalue=\"100\"/>\n                    <file name=\"AllFiles.oql\" url=\"repository/resources/AllFiles.oql\">\n                        <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.resources.Bundle#AllFiles.name\"/>\n                        <attr name=\"desc\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.resources.Bundle#AllFiles.desc\"/>\n                        <attr name=\"position\" intvalue=\"10\"/>\n                    </file>\n                    <file name=\"OverallocatedStrings.oql\" url=\"repository/resources/OverallocatedStrings.oql\">\n                        <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.resources.Bundle#OverallocatedStrings.name\"/>\n                        <attr name=\"desc\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.resources.Bundle#OverallocatedStrings.desc\"/>\n                        <attr name=\"position\" intvalue=\"20\"/>\n                    </file>\n                    <file name=\"OverallocatedStringsJS.oql\" url=\"repository/resources/OverallocatedStringsJS.oql\">\n                        <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.resources.Bundle#OverallocatedStringsJS.name\"/>\n                        <attr name=\"desc\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.resources.Bundle#OverallocatedStringsJS.desc\"/>\n                        <attr name=\"position\" intvalue=\"30\"/>\n                    </file>\n                    <file name=\"TooManyBooleans.oql\" url=\"repository/resources/TooManyBooleans.oql\">\n                        <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.resources.Bundle#TooManyBooleans.name\"/>\n                        <attr name=\"desc\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.resources.Bundle#TooManyBooleans.desc\"/>\n                        <attr name=\"position\" intvalue=\"40\"/>\n                    </file>\n                </folder>\n                <folder name=\"permgen\">\n                    <attr name=\"position\" intvalue=\"200\"/>\n                    <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#NBProfiler/Config/OQL/permgen\"/>\n                    <file name=\"BootstrapCount.oql\" url=\"repository/permgen/resources/BootstrapCount.oql\">\n                        <attr name=\"desc\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#BootstrapCount.desc\"/>\n                        <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#NBProfiler/Config/OQL/permgen/BootstrapCount.oql\"/>\n                        <attr name=\"position\" intvalue=\"100\"/>\n                    </file>\n                    <file name=\"CLHisto.oql\" url=\"repository/permgen/resources/CLHisto.oql\">\n                        <attr name=\"desc\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#CLHisto.desc\"/>\n                        <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#NBProfiler/Config/OQL/permgen/CLHisto.oql\"/>\n                        <attr name=\"position\" intvalue=\"250\"/>\n                    </file>\n                    <file name=\"CLChildParent.oql\" url=\"repository/permgen/resources/CLChildParent.oql\">\n                        <attr name=\"desc\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#CLChildParent.desc\"/>\n                        <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#NBProfiler/Config/OQL/permgen/CLChildParent.oql\"/>\n                        <attr name=\"position\" intvalue=\"300\"/>\n                    </file>\n                    <file name=\"CLLoadedClasses.oql\" url=\"repository/permgen/resources/CLLoadedClasses.oql\">\n                        <attr name=\"desc\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#CLLoadedClasses.desc\"/>\n                        <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#NBProfiler/Config/OQL/permgen/CLLoadedClasses.oql\"/>\n                        <attr name=\"position\" intvalue=\"200\"/>\n                    </file>\n                    <file name=\"CLTypes.oql\" url=\"repository/permgen/resources/CLTypes.oql\">\n                        <attr name=\"desc\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#CLTypes.desc\"/>\n                        <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#NBProfiler/Config/OQL/permgen/CLTypes.oql\"/>\n                        <attr name=\"position\" intvalue=\"0\"/>\n                    </file>\n                    <file name=\"CLReflection.oql\" url=\"repository/permgen/resources/CLReflection.oql\">\n                        <attr name=\"desc\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#CLReflection.desc\"/>\n                        <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#NBProfiler/Config/OQL/permgen/CLReflection.oql\"/>\n                        <attr name=\"position\" intvalue=\"600\"/>\n                    </file>\n                    <file name=\"CLLiveness.oql\" url=\"repository/permgen/resources/CLLiveness.oql\">\n                        <attr name=\"desc\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#CLLiveness.desc\"/>\n                        <attr name=\"displayName\" bundlevalue=\"org.graalvm.visualvm.lib.profiler.oql.repository.permgen.resources.Bundle#NBProfiler/Config/OQL/permgen/CLLiveness.oql\"/>\n                        <attr name=\"position\" intvalue=\"500\"/>\n                    </file>\n                </folder>\n            </folder>\n        </folder>\n    </folder>\n</filesystem>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/api/OQLQueryCategory.java",
    "content": "/*\n * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.oql.repository.api;\n\nimport java.util.List;\nimport org.netbeans.api.annotations.common.NonNull;\n\n/**\n * Value object for an OQL query category<br>\n * Use {@linkplain OQLQueryRepository#listCategories()} or its variants\n * to obtain this class instances.\n * @author Jaroslav Bachorik\n */\nfinal public class OQLQueryCategory {\n    private final String id;\n    private final String name;\n    private final String description;\n    private final OQLQueryRepository repository;\n\n    OQLQueryCategory(@NonNull OQLQueryRepository repository, @NonNull String id,\n                     @NonNull String name, String description) {\n        this.id = id;\n        this.name = name;\n        this.description = description;\n        this.repository = repository;\n    }\n\n    @NonNull\n    public String getName() {\n        return name;\n    }\n\n    public String getDescription() {\n        return description;\n    }\n\n    @NonNull\n    String getID() {\n        return id;\n    }\n\n    @NonNull\n    public List<? extends OQLQueryDefinition> listQueries() {\n        return repository.listQueries(this);\n    }\n\n    @NonNull\n    public List<? extends OQLQueryDefinition> listQueries(@NonNull String pattern) {\n        return repository.listQueries(this, pattern);\n    }\n\n    @Override\n    public String toString() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/api/OQLQueryDefinition.java",
    "content": "/*\n * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.oql.repository.api;\n\nimport org.netbeans.api.annotations.common.NonNull;\n\n/**\n * Value object for OQL query definition<br>\n * @author Jaroslav Bachorik\n */\nfinal public class OQLQueryDefinition {\n    private final String name;\n    private final String description;\n    private final String content;\n\n    /**\n     * The constructor taking all necessary information\n     * @param name The query name - as being displayed by a browser\n     * @param description The query description\n     * @param content The query content\n     */\n    public OQLQueryDefinition(@NonNull String name, String description, @NonNull String content) {\n        this.name = name;\n        this.description = description;\n        this.content = content;\n    }\n\n    @NonNull\n    public String getContent() {\n        return content;\n    }\n\n    public String getDescription() {\n        return description;\n    }\n\n    @NonNull\n    public String getName() {\n        return name;\n    }\n\n    @Override\n    public String toString() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/api/OQLQueryRepository.java",
    "content": "/*\n * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.oql.repository.api;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.regex.Pattern;\nimport org.netbeans.api.annotations.common.NonNull;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\n\n/** \n * This class provides an API to the OQL queries stored in the system<br>\n * Currently, the API is read only\n * @author Jaroslav Bachorik\n * @version 0.1\n */\nfinal public class OQLQueryRepository {\n    final private static class Singleton {\n        final private static OQLQueryRepository INSTANCE = new OQLQueryRepository();\n    }\n\n    final private static String MATCH_ALL = \".*\"; // NOI18N\n    final private static Logger LOGGER = Logger.getLogger(OQLQueryRepository.class.getName());\n\n    private OQLQueryRepository() {}\n\n    public static OQLQueryRepository getInstance() {\n        return Singleton.INSTANCE;\n    }\n\n    @NonNull\n    private FileObject getRepositoryRoot() {\n        FileObject root = FileUtil.getConfigFile(\"NBProfiler/Config/OQL\"); // NOI18N\n        if (root == null) {\n            throw new IllegalStateException(\"can not find OQL queries repository\"); // NOI18N\n        }\n        return root;\n    }\n\n    @NonNull\n    private String getDisplayName(@NonNull FileObject fo) {\n        String dName = (String)fo.getAttribute(\"displayName\"); // NOI18N\n        return dName != null ? dName : fo.getName();\n    }\n\n    private String getDescription(FileObject fo) {\n        return (String)fo.getAttribute(\"desc\"); // NOI18N\n    }\n\n    @NonNull\n    private List<? extends OQLQueryDefinition> getQueries(FileObject categoryFO, String pattern) {\n        List<OQLQueryDefinition> defs = new ArrayList<>();\n        try {\n            Pattern p = Pattern.compile(pattern);\n            List<FileObject> queries = sortedFOs(categoryFO.getData(false));\n            for (FileObject query : queries) {\n                String displayName = getDisplayName(query);\n                if (p.matcher(displayName).matches()) {\n                    defs.add(new OQLQueryDefinition(displayName, getDescription(query), query.asText())); // NOI18N\n                }\n            }\n        } catch (IOException iOException) {\n            LOGGER.log(Level.SEVERE, \"error while retrieving query definitions\", iOException); // NOI18N\n        }\n        return defs;\n    }\n\n    /**\n     * Retrieves the list of all query categories registered in the system\n     * @return Return the system of all query categories registered in the system\n     */\n    @NonNull\n    public List<? extends OQLQueryCategory> listCategories() {\n        return listCategories(MATCH_ALL);\n    }\n\n    @NonNull\n    public List<? extends OQLQueryCategory> listCategories(@NonNull String pattern) {\n        FileObject root = getRepositoryRoot();\n        Pattern p = Pattern.compile(pattern);\n        List<OQLQueryCategory> catList = new ArrayList<>();\n        List<FileObject> categories = sortedFOs(root.getFolders(false));\n        for (FileObject categoryFO : categories) {\n            String displayName = getDisplayName(categoryFO);\n            if(p.matcher(displayName).matches()) {\n                catList.add(new OQLQueryCategory(this, categoryFO.getName(),\n                                                 displayName, getDescription(categoryFO)));\n            }\n        }\n        \n        return catList;\n    }\n\n    @NonNull\n    public List<? extends OQLQueryDefinition> listQueries() {\n        return listQueries(MATCH_ALL);\n    }\n\n    @NonNull\n    public List<? extends OQLQueryDefinition> listQueries(@NonNull String pattern) {\n        FileObject root = getRepositoryRoot();\n        List<OQLQueryDefinition> qdefs = new ArrayList<>();\n        for(OQLQueryCategory cat : listCategories()) {\n            FileObject catFO = root.getFileObject(cat.getID());\n            qdefs.addAll(getQueries(catFO, pattern));\n        }\n        return qdefs;\n    }\n\n    @NonNull\n    public List<? extends OQLQueryDefinition> listQueries(@NonNull OQLQueryCategory category) {\n        return listQueries(category, MATCH_ALL);\n    }\n\n    @NonNull\n    public List<? extends OQLQueryDefinition> listQueries(@NonNull OQLQueryCategory category, @NonNull String pattern) {\n        FileObject root = getRepositoryRoot();\n        FileObject catFO = root.getFileObject(category.getID());\n\n        return getQueries(catFO, pattern);\n    }\n\n    private static List<FileObject> sortedFOs(Enumeration<? extends FileObject> fos) {\n        List<FileObject> list = new ArrayList<>();\n        while(fos.hasMoreElements()) list.add(fos.nextElement());\n        return FileUtil.getOrder(list, false);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/permgen/resources/BootstrapCount.oql",
    "content": "select count(heap.classes(), 'it.loader == null')"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/permgen/resources/Bundle.properties",
    "content": "# Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nBootstrapCount.desc=The count of bootstrap classes (i.e., Java platform classes loaded by JVM without using any java.lang.ClassLoader instance)\nCLHisto.desc=Lists class loaders and shows the number of classes loaded by each of them\nCLChildParent.desc=Shows entire child-parent chain for each class loader\nCLLoadedClasses.desc=Shows each class loader and classes loaded by it\nCLTypes.desc=Shows different types of class loaders in the system\nCLReflection.desc=Shows the number of synthetic speed up classes for reflection access.\nCLLiveness.desc=Shows liveness paths for each class loader. !!! Can take a long time to finish !!!\n\nNBProfiler/Config/OQL/permgen=PermGen Analysis\nNBProfiler/Config/OQL/permgen/BootstrapCount.oql=Bootstrap Count\nNBProfiler/Config/OQL/permgen/CLChildParent.oql=ClassLoader Child-Parent Chain\nNBProfiler/Config/OQL/permgen/CLHisto.oql=ClassLoader Loaded Classes Histo\nNBProfiler/Config/OQL/permgen/CLLiveness.oql=ClassLoader Liveness\nNBProfiler/Config/OQL/permgen/CLLoadedClasses.oql=ClassLoader Loaded Classes\nNBProfiler/Config/OQL/permgen/CLReflection.oql=Reflection Speedup Classes Count\nNBProfiler/Config/OQL/permgen/CLTypes.oql=ClassLoader Types\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/permgen/resources/CLChildParent.oql",
    "content": "select map(heap.objects('java.lang.ClassLoader'),\n        function(it) {\n            var res='';\n            while (it != null) {\n                res += toHtml(it) + \"->\";\n                it = it.parent;\n            }\n            res += \"null\";\n            return res + \"<br>\";\n       })"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/permgen/resources/CLHisto.oql",
    "content": "select map(sort(map(heap.objects('java.lang.ClassLoader'),\n   '{loader: it, count: it.classes.elementCount }'), 'rhs.count - lhs.count'),\n   'toHtml(it) + \"<br>\"')"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/permgen/resources/CLLiveness.oql",
    "content": "select { loader: cl, liveness: heap.livepaths(cl) }\n    from instanceof java.lang.ClassLoader cl"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/permgen/resources/CLLoadedClasses.oql",
    "content": "select { loader: cl,\n             classes: filter(map(cl.classes.elementData, 'it'), 'it != null') }\n    from instanceof java.lang.ClassLoader cl"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/permgen/resources/CLReflection.oql",
    "content": "select count(heap.objects('sun.reflect.DelegatingClassLoader'))"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/permgen/resources/CLTypes.oql",
    "content": "select unique(map(heap.objects('java.lang.ClassLoader'), 'classof(it)'))"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/resources/AllFiles.oql",
    "content": "select x from java.io.File x"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/resources/Bundle.properties",
    "content": "# Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\nNBProfiler/Config/OQL/samplesName=Samples\nNBProfiler/Config/OQL/samplesDescr=Sample OQL queries.\nAllFiles.name=List java.io.File instances\nAllFiles.desc=Sample OQL query to list all instances of java.io.File allocated on the heap.\nOverallocatedStrings.name=Overallocated Strings\nOverallocatedStrings.desc=Computes overhead of Strings that have their backing char[] larger than necessary (for example result of String.substring()).\nOverallocatedStringsJS.name=Overallocated Strings (JS)\nOverallocatedStringsJS.desc=Computes overhead of Strings that have their backing char[] larger than necessary (for example result of String.substring()). This time it uses JavaScript functions.\nTooManyBooleans.name=Too many Booleans\nTooManyBooleans.desc=Checks if there are more than two instances of Boolean on the heap (only Boolean.TRUE and Boolean.FALSE are necessary).\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/resources/OverallocatedStrings.oql",
    "content": "select map(\n    top(heap.objects(\"java.lang.String\", false, '(2 * it.offset) + (2 * (it.value.length - (1*it.count + 1*it.offset))) > 0'),\n        '((2 * rhs.offset) + (2 * (rhs.value.length - (1*rhs.count + 1*rhs.offset)))) - ((2 * lhs.offset) + (2 * (lhs.value.length - (1*lhs.count + 1*lhs.offset))))'),\n    'toHtml(it) + \" wasting \" + ((2 * it.offset) + (2 * (it.value.length - (1*it.count + 1*it.offset)))) + \"b\"')"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/resources/OverallocatedStringsJS.oql",
    "content": "function overallocation(it) {\n    return (2 * it.offset) + (2 * (it.value.length - (1*it.count + 1*it.offset)));\n}\n\nfunction showOAinfo(it) {\n    return toHtml(it) + \" wasting \" + overallocation(it) + \"b\";\n}\n\nfunction overallocationdiff(lhs, rhs) {\n    return overallocation(rhs) - overallocation(lhs);\n}\n\nmap(top(heap.objects(\"java.lang.String\", false, 'overallocation(it) > 0'), overallocationdiff), showOAinfo);"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/repository/resources/TooManyBooleans.oql",
    "content": "select toHtml(a) + \" = \" + a.value from java.lang.Boolean a\n    where objectid(a.clazz.statics.TRUE) != objectid(a) &&\n          objectid(a.clazz.statics.FALSE) != objectid(a)"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/src/org/graalvm/visualvm/lib/profiler/oql/spi/OQLEditorImpl.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.oql.spi;\n\nimport javax.swing.JEditorPane;\nimport javax.swing.text.Document;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.OQLEngine;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\nabstract public class OQLEditorImpl {\n    public final static String VALIDITY_PROPERTY = \"document#valid\";\n    public static interface ValidationCallback {\n        void callback(boolean lexingResult);\n    }\n\n    final static protected ValidationCallback getValidationCallback(Document document) {\n        return (ValidationCallback)document.getProperty(ValidationCallback.class);\n    }\n\n    final static protected OQLEngine getEngine(Document document) {\n        return (OQLEngine)document.getProperty(OQLEngine.class);\n    }\n\n    public abstract JEditorPane getEditorPane();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/test/unit/src/org/graalvm/visualvm/lib/profiler/oql/engine/api/impl/OQLEngineTest.java",
    "content": "/*\n * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.oql.engine.api.impl;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.URISyntaxException;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport org.graalvm.visualvm.lib.jfluid.heap.HeapFactory;\nimport org.graalvm.visualvm.lib.jfluid.heap.Instance;\nimport org.graalvm.visualvm.lib.jfluid.heap.JavaClass;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.OQLEngine;\nimport org.graalvm.visualvm.lib.profiler.oql.engine.api.OQLEngine.ObjectVisitor;\nimport static org.junit.Assert.*;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class OQLEngineTest {\n    private OQLEngine instance;\n\n    public OQLEngineTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n    }\n\n    @Before\n    public void setUp() throws IOException, URISyntaxException {\n        URL url = getClass().getResource(\"small_heap.bin\");\n        instance = new OQLEngine(HeapFactory.createHeap(new File(url.toURI())));\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    @Test\n    public void testAltTypeNames() throws Exception {\n        instance.executeQuery(\"select a from [I a\", null);\n        instance.executeQuery(\"select a from [B a\", null);\n        instance.executeQuery(\"select a from [C a\", null);\n        instance.executeQuery(\"select a from [S a\", null);\n        instance.executeQuery(\"select a from [J a\", null);\n        instance.executeQuery(\"select a from [F a\", null);\n        instance.executeQuery(\"select a from [Z a\", null);\n\n        instance.executeQuery(\"select a from [java.lang.String a\", null);\n\n//        try {\n//            instance.executeQuery(\"select a from [[I a\", null);\n//            fail();\n//        } catch (Exception e) {}\n//\n//        instance.executeQuery(\"select a from [[B a\", null);\n//        instance.executeQuery(\"select a from [[C a\", null);\n//        instance.executeQuery(\"select a from [[S a\", null);\n//        instance.executeQuery(\"select a from [[J a\", null);\n//        instance.executeQuery(\"select a from [[F a\", null);\n//        instance.executeQuery(\"select a from [[Z a\", null);\n//\n//        instance.executeQuery(\"select a from [[java.lang.String a\", null);\n    }\n\n    @Test\n    public void testIntResult() throws Exception {\n        final boolean[] rslt = new boolean[]{true};\n        instance.executeQuery(\"select a.count from java.lang.String a\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                if (!(o instanceof Integer)) {\n                    rslt[0] = false;\n                    return true;\n                }\n                return false;\n            }\n        });\n        assertTrue(rslt[0]);\n    }\n\n    @Test\n    public void testClassFields() throws Exception {\n        System.out.println(\"test class fields\");\n\n        final String[] values = new String[] {\"\", \"prefixLength = int\"};\n\n        instance.executeQuery(\"select map(heap.findClass(\\\"java.io.File\\\").fields, 'toHtml(it.name) + \\\" = \\\" + toHtml(it.signature)')\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                values[0] = o.toString();\n                return true;\n            }\n        });\n\n        assertEquals(values[1], values[0]);\n    }\n\n    @Test\n    public void testObjectClass() throws Exception {\n        System.out.println(\"test object class accessor\");\n\n        instance.executeQuery(\"select map(a.clazz.statics, 'toHtml(it)') from java.lang.String a\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                return true;\n            }\n        });\n    }\n\n    @Test\n    public void testHeapForEachClass() throws Exception {\n        System.out.println(\"heap.forEachClass\");\n        String query = \"select heap.forEachClass(function(xxx) { print(xxx.name); print(\\\"\\\\n\\\");})\";\n\n        instance.executeQuery(query, null);\n    }\n\n    @Test\n    public void testHeapForEachObject() throws Exception {\n        System.out.println(\"heap.forEachObject\");\n        String query = \"select heap.forEachObject(function(xxx) { print(xxx.id); print(\\\"\\\\n\\\");}, \\\"java.io.File\\\")\";\n\n        instance.executeQuery(query, null);\n    }\n\n    @Test\n    public void testHeapFindObject() throws Exception {\n        System.out.println(\"heap.findObject\");\n        final int[] counter = new int[1];\n        String query = \"select heap.findObject(1684166976)\";\n\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                counter[0]++;\n                return true;\n            }\n        });\n        assertTrue(counter[0] > 0);\n    }\n\n    @Test\n    public void testHeapRoots() throws Exception {\n        System.out.println(\"heap.roots\");\n        final int[] counter = new int[1];\n\n        String query = \"select heap.roots()\";\n\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                counter[0]++;\n                return false;\n            }\n        });\n        assertTrue(counter[0] == 491);\n    }\n\n    @Test\n    public void testHeapClasses() throws Exception {\n        System.out.println(\"heap.classes\");\n        final int[] counter = new int[1];\n\n        String query = \"select heap.classes()\";\n\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                counter[0]++;\n                return false;\n            }\n        });\n        assertTrue(counter[0] == 443);\n    }\n\n    @Test\n    public void testHeapFinalizables() throws Exception {\n        System.out.println(\"heap.finalizables\");\n        final int[] counter = new int[1];\n\n        String query = \"select heap.finalizables()\";\n\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                counter[0]++;\n                return false;\n            }\n        });\n        assertTrue(counter[0] == 0);\n    }\n\n    @Test\n    public void testHeapLivePaths() throws Exception {\n        System.out.println(\"heap.livepaths\");\n        final int[] counter = new int[1];\n\n        String query = \"select heap.livepaths(s) from java.lang.String s\";\n\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                if (o != null) {\n                    counter[0]++;\n                    return true;\n                } else {\n                    return false;\n                }\n            }\n        });\n        assertTrue(counter[0] > 0);\n    }\n\n    @Test\n    public void testHeapObjects() throws Exception {\n        System.out.println(\"heap.objects\");\n\n        final int[] count = new int[]{0,0};\n\n        instance.executeQuery(\"select heap.objects(\\\"java.io.InputStream\\\", true)\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                count[0]++;\n                return false;\n            }\n        });\n        instance.executeQuery(\"select heap.objects(\\\"java.io.InputStream\\\", false)\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                count[1]++;\n                return false;\n            }\n        });\n\n        assertNotSame(count[0], count[1]);\n\n        assertEquals(4, count[0]);\n        assertEquals(0, count[1]);\n    }\n\n    @Test\n    public void testSubclasses() throws Exception {\n        System.out.println(\"subclasses\");\n        final int[] counter = new int[1];\n\n        String query = \"select heap.findClass(\\\"java.io.InputStream\\\").subclasses()\";\n\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                System.out.println(((JavaClass)o).getName());\n                counter[0]++;\n                return false;\n            }\n        });\n        assertTrue(counter[0] > 0);\n    }\n\n    @Test\n    public void testSuperlasses() throws Exception {\n        System.out.println(\"superclasses\");\n        final int[] counter = new int[1];\n\n        String query = \"select heap.findClass(\\\"java.io.DataInputStream\\\").superclasses()\";\n\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                System.out.println(((JavaClass)o).getName());\n                counter[0]++;\n                return true;\n            }\n        });\n        assertTrue(counter[0] > 0);\n    }\n\n    @Test\n    public void testforEachReferrer() throws Exception {\n        System.out.println(\"forEachReferrer\");\n\n        String query = \"select forEachReferrer(function(xxx) { print(\\\"referrer: \\\" + xxx.id); print(\\\"\\\\n\\\");}, heap.findObject(1684166976))\";\n\n        instance.executeQuery(query, null);\n    }\n\n    @Test\n    public void testforEachReferee() throws Exception {\n        System.out.println(\"forEachReferee\");\n\n        String query = \"select forEachReferee(function(xxx) { print(\\\"referee: \\\" + xxx.id); print(\\\"\\\\n\\\");}, heap.findObject(1684166976))\";\n\n        instance.executeQuery(query, null);\n    }\n\n    @Test\n    public void testReferrersInstance() throws Exception {\n        System.out.println(\"referrers-instance\");\n\n        String query = \"select referrers(heap.findObject(1684166976))\";\n        long[] referrersTest = new long[] {1684166952};\n        final List<Long> referrers = new ArrayList<>();\n\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                referrers.add(((Instance)o).getInstanceId());\n                return false;\n            }\n        });\n\n        assertEquals(referrersTest.length, referrers.size());\n        for(long referee : referrersTest) {\n            if (!referrers.contains(referee)) fail();\n        }\n    }\n\n    @Test\n    public void testRefereesInstance() throws Exception {\n        System.out.println(\"referees-instance\");\n\n        String query = \"select referees(heap.findObject(1684166976))\";\n        long[] refereesTest = new long[] {1684166992};\n        final List<Long> referees = new ArrayList<>();\n\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                referees.add(((Instance)o).getInstanceId());\n                return false;\n            }\n        });\n\n        assertEquals(refereesTest.length, referees.size());\n        for(long referee : refereesTest) {\n            if (!referees.contains(referee)) fail();\n        }\n    }\n\n    @Test\n    public void testRefereesClass() throws Exception {\n        System.out.println(\"referees-class\");\n\n        String query = \"select referees(heap.findClass(\\\"java.io.File\\\"))\";\n        long[] refereesTest = new long[] {1684106928, 1684106888, 1684106848, 1684106408};\n        final List<Long> referees = new ArrayList<>();\n\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                referees.add(((Instance)o).getInstanceId());\n                return false;\n            }\n        });\n\n        assertEquals(refereesTest.length, referees.size());\n        for(long referee : refereesTest) {\n            if (!referees.contains(referee)) fail();\n        }\n    }\n\n    @Test\n    public void testRefers() throws Exception  {\n        System.out.println(\"refers\");\n\n        String query = \"select refers(heap.findObject(1684166976), heap.findObject(1684166992))\";\n\n        final boolean[] result = new boolean[1];\n\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                result[0] = (Boolean)o;\n                return true;\n            }\n        });\n        assertTrue(result[0]);\n\n        query = \"select refers(heap.findObject(1684166992), heap.findObject(1684166976))\";\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                result[0] = (Boolean)o;\n                return true;\n            }\n        });\n        assertFalse(result[0]);\n    }\n\n    @Test\n    public void testReachables() throws Exception {\n        System.out.println(\"reachables\");\n        final int count[] = new int[1];\n\n        String query = \"select reachables(p) from java.util.Properties p\";\n\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                count[0]++;\n                return false;\n            }\n        });\n        assertEquals(352, count[0]);\n    }\n\n    @Test\n    public void testInstanceOf() throws Exception {\n        System.out.println(\"instanceof\");\n\n        String query = \"select classof(cl).name from instanceof java.lang.ClassLoader cl\";\n        final int[] counter = new int[1];\n\n        instance.executeQuery(query, new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                System.out.println(o);\n                counter[0]++;\n                return false;\n            }\n        });\n        assertEquals(2, counter[0]); // although there is 8 subclasses of ClassLoader only 2 of them have instances\n    }\n\n    @Test\n    public void testSizeOf() throws Exception {\n        System.out.println(\"sizeof\");\n        final int[] counter = new int[1];\n\n        instance.executeQuery(\"select sizeof(o) from [I o\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                if (o instanceof Number) counter[0]++;\n                return false;\n            }\n        });\n\n        assertTrue(counter[0] > 0);\n    }\n\n    @Test\n    public void testRoot() throws Exception {\n        System.out.println(\"root\");\n\n        final int[] count = new int[1];\n\n        instance.executeQuery(\"select root(heap.findObject(1684166976))\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                count[0]++;\n                return false;\n            }\n        });\n\n        assertTrue(count[0] > 0);\n    }\n\n    @Test\n    public void testContains() throws Exception {\n        System.out.println(\"contains\");\n\n        final int[] count = new int[1];\n\n        instance.executeQuery(\"select s from java.lang.String s where contains(referrers(s), \\\"classof(it).name == 'java.lang.Class'\\\")\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                count[0]++;\n                return false;\n            }\n        });\n\n        assertTrue(count[0] > 0);\n    }\n\n    @Test\n    public void testMap() throws Exception {\n        System.out.println(\"map\");\n\n        final String[] output = new String[] {\"\", \"$assertionsDisabled=true\\nserialVersionUID=301077366599181567\\ntmpdir=null\\ncounter=-1\\ntmpFileLock=<a href='file://instance/1684106928' name='1684106928'>java.lang.Object#6</a>\\npathSeparator=<a href='file://instance/1684106888' name='1684106888'>java.lang.String#101</a>\\npathSeparatorChar=:\\nseparator=<a href='file://instance/1684106848' name='1684106848'>java.lang.String#100</a>\\nseparatorChar=/\\nfs=<a href='file://instance/1684106408' name='1684106408'>java.io.UnixFileSystem#1</a>\\n<classLoader>=null\\n\"};\n\n        instance.executeQuery(\"select map(heap.findClass(\\\"java.io.File\\\").statics, \\\"index + '=' + toHtml(it)\\\")\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                output[0] += o.toString() + \"\\n\";\n                return false;\n            }\n        });\n        assertEquals(output[1], output[0]);\n    }\n\n    @Test\n    public void testFilter() throws Exception {\n        System.out.println(\"filter\");\n\n        final int[] size = new int[]{0};\n        final boolean sorted[] = new boolean[] {true};\n\n\n        instance.executeQuery(\"select map(sort(filter(heap.objects('[C'), 'it.length > 0'), 'sizeof(lhs) - sizeof(rhs)'), \\\"sizeof(it)\\\")\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                int aSize = ((Number)o).intValue();\n                if (aSize < size[0]) {\n                    sorted[0] = false;\n                    return true;\n                }\n                size[0] = aSize;\n                return false;\n            }\n        });\n\n        assertTrue(sorted[0]);\n    }\n\n    @Test\n    public void testSort() throws Exception {\n        System.out.println(\"sort\");\n\n        final int[] size = new int[]{0};\n        final boolean sorted[] = new boolean[] {true};\n\n\n        instance.executeQuery(\"select map(sort(heap.objects('[C'), 'sizeof(lhs) - sizeof(rhs)'), \\\"sizeof(it)\\\")\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                int aSize = ((Number)o).intValue();\n                if (aSize < size[0]) {\n                    sorted[0] = false;\n                    return true;\n                }\n                size[0] = aSize;\n                return false;\n            }\n        });\n\n        assertTrue(sorted[0]);\n    }\n\n    @Test\n    public void testLength() throws Exception {\n        System.out.println(\"length\");\n\n        final Class<?>[] rsltClass = new Class<?>[1];\n//        final boolean sorted[] = new boolean[] {true};\n\n\n        instance.executeQuery(\"select length(a.value) from java.lang.String a\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                rsltClass[0] = o.getClass();\n                return true;\n            }\n        });\n\n        assertTrue(Number.class.isAssignableFrom(rsltClass[0]));\n    }\n\n    @Test\n    public void testCountNoClosure() throws Exception {\n        System.out.println(\"count - no closure\");\n\n        final Class<?>[] rsltClass = new Class<?>[1];\n//        final boolean sorted[] = new boolean[] {true};\n\n\n        instance.executeQuery(\"select count(a.value) from java.lang.String a\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                rsltClass[0] = o.getClass();\n                return true;\n            }\n        });\n\n        assertTrue(Number.class.isAssignableFrom(rsltClass[0]));\n    }\n\n    @Test\n    public void testCount() throws Exception {\n        System.out.println(\"count\");\n\n        final Class<?>[] rsltClass = new Class<?>[1];\n//        final boolean sorted[] = new boolean[] {true};\n\n\n        instance.executeQuery(\"select count(a.value, 'true') from java.lang.String a\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                rsltClass[0] = o.getClass();\n                return true;\n            }\n        });\n\n        assertTrue(Number.class.isAssignableFrom(rsltClass[0]));\n    }\n\n    @Test\n    public void testMultivalue() throws Exception {\n        System.out.println(\"multi-value\");\n\n        final Class<?>[] rsltClass = new Class<?>[1];\n//        final boolean sorted[] = new boolean[] {true};\n\n\n        instance.executeQuery(\"select { name: t.name? t.name.toString() : \\\"null\\\", thread: t }  from instanceof java.lang.Thread t\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                rsltClass[0] = o.getClass();\n                return true;\n            }\n        });\n\n        assertTrue(Map.class.isAssignableFrom(rsltClass[0]));\n    }\n\n    @Test\n    public void testComplexStatement1() throws Exception {\n        System.out.println(\"complex statement 1\");\n\n        final String[] rslt = new String[1];\n\n        instance.executeQuery(\n            \"select map(filter(heap.findClass('java.lang.System').statics.props.table, 'it != null && it.key != null && it.value != null'),  \" +\n                \"function (it) { \" +\n                    \"return 'MapEntry{' + it.key.toString() + ' = ' + it.value.toString() + '}' ;\" +\n                \"}\" +\n            \")\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                System.out.println(o);\n                rslt[0] = o.toString();\n                return true;\n            }\n        });\n\n        assertEquals(\"MapEntry{sun.cpu.isalist = }\", rslt[0]);\n    }\n\n    @Test\n    public void testComplexStatement2() throws Exception {\n        System.out.println(\"complex statement 2\");\n\n        final String[] rslt = new String[1];\n\n        instance.executeQuery(\n            \"select map(filter(heap.findClass('java.lang.System').statics.props.table, 'it != null && it.key != null && it.value != null'), \" +\n            \"'{ key: it.key.toString(), value: it.value.toString() }')\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                System.out.println(o);\n                rslt[0] = dump(o);\n                return true;\n            }\n        });\n        assertEquals(\"{key=sun.cpu.isalist, value=}\", rslt[0]);\n    }\n\n    @Test\n    public void testMapWrapping() throws Exception {\n        System.out.println(\"map wrapping\");\n\n        final String[] result = new String[] {\"\", \"<a href='file://class/1746081976' name='1746081976'>class java.util.HashMap$Entry[]</a>\"};\n\n        instance.executeQuery(\"select unique(map(filter(reachables(a), 'it != null'), 'toHtml(it.clazz)')) from instanceof java.util.HashMap a\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                result[0] = o.toString();\n                return true;\n            }\n        });\n\n        assertEquals(result[1], result[0]);\n    }\n\n    @Test\n    public void testUnwrapIterator() throws Exception {\n        System.out.println(\"unwrap iterator\");\n\n        instance.executeQuery(\"select map(filter(a.table, 'it != null'), 'reachables(it)') from instanceof java.util.HashMap a\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                System.out.println(o);\n                return true;\n            }\n        });\n    }\n\n    @Test\n    public void testUnwrapIteratorComplex() throws Exception {\n        System.out.println(\"unwrap iterator complex\");\n\n        instance.executeQuery(\"select map(map(filter(a.table, 'it != null'), 'reachables(it)'), 'it.clazz.statics') from instanceof java.util.HashMap a\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                System.out.println(o);\n                return true;\n            }\n        });\n    }\n\n    @Test\n    public void testTop() throws Exception {\n        System.out.println(\"top 5\");\n\n        instance.executeQuery(\"select top(heap.objects('java.lang.String', false, '(2 * it.offset) + (2 * (it.value.length - (1*it.count + 1*it.offset))) > 0'), '((2 * rhs.offset) + (2 * (rhs.value.length - (1*rhs.count + 1*rhs.offset)))) - ((2 * lhs.offset) + (2 * (lhs.value.length - (1*lhs.count + 1*lhs.offset))))')\", new ObjectVisitor() {\n\n            public boolean visit(Object o) {\n                System.out.println(o);\n                return false;\n            }\n        });\n    }\n\n    private String dump(Object o) {\n        if (o instanceof Map) {\n            List<String> els = new ArrayList<>();\n            Map<?,?> m = (Map) o;\n            for (Map.Entry<?,?> e : m.entrySet()) {\n                els.add(e.getKey()+\"=\"+e.getValue());\n            }\n            els.sort(null);\n            return \"{\"+String.join(\", \", els)+\"}\";\n        }\n        return o.toString();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.oql/test/unit/src/org/graalvm/visualvm/lib/profiler/oql/repository/api/OQLQueryRepositoryTest.java",
    "content": "/*\n * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.oql.repository.api;\n\nimport java.util.List;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport static org.junit.Assert.*;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class OQLQueryRepositoryTest {\n    private OQLQueryRepository instance;\n\n    public OQLQueryRepositoryTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n    }\n\n    @Before\n    public void setUp() {\n        instance = OQLQueryRepository.getInstance();\n    }\n\n    @After\n    public void tearDown() {\n        instance = null;\n    }\n\n    /**\n     * Test of listCategories() method, of class OQLQueryBrowser.\n     * Matching for any category\n     */\n    @Test\n    public void testListAllCategories() {\n        System.out.println(\"listAllCategories\");\n\n        List<?> result = instance.listCategories();\n        assertTrue(!result.isEmpty());\n    }\n\n    /**\n     * Test of listCategories(pattern) method, of class OQLQueryBrowser.\n     * Matching for an existing pattern\n     */\n    @Test\n    public void testListMatchingCategories() {\n        System.out.println(\"listMatchingCategories\");\n        String pattern = \"Sam.*\";\n        List<?> result = instance.listCategories(pattern);\n        assertEquals(1, result.size());\n    }\n\n    /**\n     * Test of listCategories(pattern) method, of class OQLQueryBrowser.\n     * Matching for a nonexisting pattern\n     */\n    @Test\n    public void testListNonMatchingCategories() {\n        System.out.println(\"listNonMatchingCategories\");\n        String pattern = \"[0-9]+\";\n        List<?> result = instance.listCategories(pattern);\n        assertEquals(0, result.size());\n    }\n\n    /**\n     * Test of listQueries() method, of class OQLQueryBrowser\n     * Listing all queries available\n     */\n    @Test\n    public void testListAllQueries() {\n        System.out.println(\"listAllQueries\");\n        List<?> result = instance.listQueries();\n        assertEquals(11, result.size());\n    }\n\n    /**\n     * Test of listQueries(OQLQueryCategory) method, of class OQLQueryBrowser\n     * Listing all queries available for certain category\n     */\n    @Test\n    public void testListAllCategoryQueries() {\n        System.out.println(\"listAllCategoryQueries\");\n        OQLQueryCategory category = instance.listCategories().get(0);\n        List<?> result = instance.listQueries(category);\n        assertEquals(4, result.size());\n    }\n\n    /**\n     * Test of listQueries(String) method, of class OQLQueryBrowser\n     * Listing all queries available matching the given pattern\n     */\n    @Test\n    public void testListAllMatchingQueries() {\n        System.out.println(\"listAllMatchingQueries\");\n        List<?> result = instance.listQueries(\".+?allocated.*\");\n        assertEquals(2, result.size());\n    }\n\n    /**\n     * Test of listQueries(OQLQueryCategory, String) method, of class OQLQueryBrowser\n     * Listing all queries available for certain category matching the given pattern\n     */\n    @Test\n    public void testListMatchingCategoryQueries() {\n        System.out.println(\"listMatchingCategoryQueries\");\n        OQLQueryCategory category = instance.listCategories().get(0);\n        List<?> result = instance.listQueries(category, \".+?allocated.*\");\n        assertEquals(2, result.size());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project basedir=\".\" default=\"netbeans\" name=\"profiler.snaptracer\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.lib.profiler.snaptracer</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nOpenIDE-Module: org.graalvm.visualvm.lib.profiler.snaptracer/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/lib/profiler/snaptracer/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.lib.profiler.snaptracer-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/nbproject/genfiles.properties",
    "content": "# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=2641f976\nnbproject/build-impl.xml.script.CRC32=aaa3e780\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/nbproject/project.properties",
    "content": "# Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\njavac.source=1.8\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.lib.profiler.snaptracer</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.charts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.45</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.options.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.19</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.actions</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.37</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.25</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.16</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.loaders</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.61</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.nodes</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.18</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.34</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.profiling</friend>\n                <package>org.graalvm.visualvm.lib.profiler.snaptracer.impl</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/../..\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Name=Java Profiler (Snapshots Tracer)\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/ClassNameComparator.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n\nimport java.util.Comparator;\n\n/**\n * Comparator based on class names.\n *\n * @author Jiri Sedlacek\n */\nfinal class ClassNameComparator implements Comparator {\n\n    /**\n     * Shared instance of ClassNameComparator.\n     */\n    public static final ClassNameComparator INSTANCE = new ClassNameComparator();\n\n    public int compare(Object o1, Object o2) {\n        return o1.getClass().getName().compareTo(o2.getClass().getName());\n    }\n\n    private ClassNameComparator() {}\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/ItemValueFormatter.java",
    "content": "/*\n * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n\nimport java.text.NumberFormat;\n\n/**\n * This class is responsible for formatting item values in the UI. In the current\n * version it formats values for chart tooltips, chart units (min/max values) and\n * details table.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ItemValueFormatter {\n\n    /**\n     * Code for tooltip formatting.\n     */\n    public static final int FORMAT_TOOLTIP = 0;\n    /**\n     * Code for units (min/max values) formatting.\n     */\n    public static final int FORMAT_UNITS = 1;\n    /**\n     * Code for details table formatting.\n     */\n    public static final int FORMAT_DETAILS = 2;\n    /**\n     * Code for exported data formatting.\n     */\n    public static final int FORMAT_EXPORT = 3;\n\n    /**\n     * Predefined formatter providing simple numeric values.\n     * Uses Number.getInstance().toString().\n     */\n    public static final ItemValueFormatter SIMPLE = new ItemValueFormatter() {\n        public String formatValue(long value, int format) {\n            return Long.toString(value);\n        }\n        public String getUnits(int format) {\n            return null;\n        }\n    };\n\n    /**\n     * Predefined formatter for decimal values with custom units.\n     * Uses Number.getInstance().toString().\n     */\n    public static final ItemValueFormatter DEFAULT_DECIMAL = new Decimal();\n    /**\n     * Predefined formatter for memory values. Uses B (Bytes) for tooltip,\n     * details table and export, uses MB for units (min/max values).\n     * Uses Number.getInstance().toString().\n     */\n    public static final ItemValueFormatter DEFAULT_BYTES = new Bytes();\n    /**\n     * Predefined formatter for percent values with custom factor.\n     * Uses Number.getPercentInstance().toString().\n     */\n    public static final ItemValueFormatter DEFAULT_PERCENT = new Percent();\n\n\n    /**\n     * Returns value formatted in the requested format.\n     *\n     * @param value value to be formatted\n     * @param format format to be used\n     * @return value formatted in the requested format\n     */\n    public abstract String formatValue(long value, int format);\n\n    /**\n     * Returns value units for the requested format.\n     *\n     * @param format format to be used\n     * @return value units for the requested format or null for no units\n     */\n    public abstract String getUnits(int format);\n\n\n    /**\n     * Predefined formatter for decimal values with custom factor and units.\n     * Uses Number.getInstance().toString().\n     */\n    public static final class Decimal extends ItemValueFormatter {\n        \n        private static final NumberFormat FORMAT = NumberFormat.getInstance();\n\n        private final int factor;\n        private final String units;\n\n\n        Decimal() {\n            this(1, null);\n        }\n\n        /**\n         * Creates new instance of Decimal formatter with the defined units.\n         * The values are computed as value / factor.\n         *\n         * @param factor factor for computing values\n         * @param units units\n         */\n        public Decimal(int factor, String units) {\n            this.factor = factor;\n            this.units = units;\n        }\n\n\n        public String formatValue(long value, int format) {\n            return FORMAT.format(value / factor);\n        }\n        \n        public String getUnits(int format) {\n            return units;\n        }\n        \n    }\n\n\n    /**\n     * Predefined formatter for memory values. Uses B (Bytes) for tooltip,\n     * details table and export, uses MB for units (min/max values).\n     * Uses Number.getInstance().toString().\n     */\n    private static final class Bytes extends ItemValueFormatter {\n\n        private static final NumberFormat FORMAT = NumberFormat.getInstance();\n\n\n        Bytes() {}\n\n\n        public String formatValue(long value, int format) {\n            switch (format) {\n                case FORMAT_TOOLTIP:\n                case FORMAT_DETAILS:\n                case FORMAT_EXPORT:\n                    return FORMAT.format(value);\n                case FORMAT_UNITS:\n                    String est = value == 0 ? \"\" : \"~\";\n                    return est + FORMAT.format(Math.round((double)value / 1024 / 1024));\n                default:\n                    return null;\n            }\n        }\n        \n        public String getUnits(int format) {\n            switch (format) {\n                case FORMAT_TOOLTIP:\n                case FORMAT_DETAILS:\n                case FORMAT_EXPORT:\n                    return \"B\";\n                case FORMAT_UNITS:\n                    return \"MB\";\n                default:\n                    return null;\n            }\n        }\n        \n    }\n\n\n    /**\n     * Predefined formatter for percent values with custom factor.\n     * Uses Number.getPercentInstance().toString().\n     */\n    public static final class Percent extends ItemValueFormatter {\n\n        private static final NumberFormat PERCENT_FORMAT;\n        private static final NumberFormat NUMBER_FORMAT;\n\n        static {\n            PERCENT_FORMAT = NumberFormat.getPercentInstance();\n            PERCENT_FORMAT.setMinimumFractionDigits(1);\n            PERCENT_FORMAT.setMaximumIntegerDigits(3);\n            NUMBER_FORMAT = NumberFormat.getInstance();\n            NUMBER_FORMAT.setMinimumFractionDigits(1);\n            NUMBER_FORMAT.setMaximumIntegerDigits(3);\n        }\n        \n        private double factor;\n\n\n        Percent() {\n            this(3);\n        }\n\n        /**\n         * Creates new instance of Percent formatter with the defined decimal\n         * exponent. The values are computed as value / Math.pow(10, decexp).\n         *\n         * @param decexp decimal exponent for computing values\n         */\n        public Percent(int decexp) {\n            factor = Math.pow(10, decexp);\n        }\n\n\n        public String formatValue(long value, int format) {\n            switch (format) {\n                case FORMAT_TOOLTIP:\n                case FORMAT_UNITS:\n                    return PERCENT_FORMAT.format(value / factor);\n                case FORMAT_DETAILS:\n                case FORMAT_EXPORT:\n                    return NUMBER_FORMAT.format(value * 100 / factor);\n                default:\n                    return null;\n            }\n        }\n        \n        public String getUnits(int format) {\n            switch (format) {\n                case FORMAT_TOOLTIP:\n                case FORMAT_UNITS:\n                    return null; // '%' provided by NumberFormat.getPercentInstance()\n                case FORMAT_DETAILS:\n                case FORMAT_EXPORT:\n                    return \"%\"; // '%' is part of column header\n                default:\n                    return null;\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/PackageStateHandler.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.IdeSnapshot;\n\n\n/**\n * PackageStateHandler interface allows an implementing TracerPackage to be\n * notified about Tracer session state. See TracerPackage.getStateHandler().\n *\n * @author Jiri Sedlacek\n */\npublic interface PackageStateHandler {\n\n    /**\n     * Invoked when a probe is added into the Timeline view.\n     *\n     * @param probe added probe\n     * @param snapshot profiler snapshot\n     */\n    public void probeAdded(TracerProbe probe, IdeSnapshot snapshot);\n\n    /**\n     * Invoked when a probe is removed from the Timeline view.\n     *\n     * @param probe removed probe\n     * @param snapshot profiler snapshot\n     */\n    public void probeRemoved(TracerProbe probe, IdeSnapshot snapshot);\n\n\n    /**\n     * Invoked when setting up a new Tracer session. This method allows a\n     * Package to notify the user about initialization progress. The actual\n     * initialization (and updating the TracerProgressObject) should be\n     * performed in the sessionStarting() method. Useful for example for\n     * messaging a delay during instrumentation of classes in target application.\n     *\n     * @param probes probes defined for the Tracer session\n     * @param snapshot profiler snapshot\n     * @param refresh session refresh rate in milliseconds\n     * @return TracerProgressObject to track initialization progress\n     */\n    public TracerProgressObject sessionInitializing(TracerProbe[] probes,\n            IdeSnapshot snapshot, int refresh);\n\n    /**\n     * Invoked when starting a new Tracer session. Any package/probes\n     * initialization should be performed in this method. If provided by the\n     * sessionInitializing method, a TracerProgressObject should be updated to\n     * reflect the initialization progress. This method may throw a\n     * SessionInitializationException in case of initialization failure. Any\n     * packages/probes initialized so far will be correctly finished, however the\n     * package throwing the SessionInitializationException is responsible for\n     * cleaning up any used resources and restoring its state without any\n     * following events.\n     *\n     * @param probes probes defined for the Tracer session\n     * @param snapshot profiler snapshot\n     * @throws SessionInitializationException in case of initialization failure\n     */\n    public void sessionStarting(TracerProbe[] probes, IdeSnapshot snapshot)\n            throws SessionInitializationException;\n\n    /**\n     * Invoked when all packages/probes have been started and the Tracer session\n     * is running and collecting data.\n     *\n     * @param probes probes defined for the Tracer session\n     * @param snapshot profiler snapshot\n     */\n    public void sessionRunning(TracerProbe[] probes, IdeSnapshot snapshot);\n\n    /**\n     * Invoked when stopping the Tracer session. Any package/probes cleanup\n     * should be performed in this method. Any long-running cleanup code should\n     * preferably be invoked in a separate worker thread to allow the Tracer\n     * session to finish as fast as possible. Be sure to check/wait for the\n     * cleanup thread when starting a new Tracer session in sessionStarting().\n     * \n     * @param probes probes defined for the Tracer session\n     * @param snapshot profiler snapshot\n     */\n    public void sessionStopping(TracerProbe[] probes, IdeSnapshot snapshot);\n\n    /**\n     * Invoked when the Tracer session has finished.\n     *\n     * @param probes probes defined for the Tracer session\n     * @param snapshot profiler snapshot\n     */\n    public void sessionFinished(TracerProbe[] probes, IdeSnapshot snapshot);\n\n    /**\n     * Invoked when refresh rate of the Tracer session has been changed.\n     *\n     * @param probes probes defined for the Tracer session\n     * @param snapshot profiler snapshot\n     * @param refresh session refresh rate in milliseconds\n     */\n    public void refreshRateChanged(TracerProbe[] probes, IdeSnapshot snapshot, int refresh);\n\n\n    /**\n     * An abstract adapter class for receiving Tracer session state notifications.\n     */\n    public abstract class Adapter implements PackageStateHandler {\n\n        public void probeAdded(TracerProbe probe, IdeSnapshot snapshot) {}\n\n        public void probeRemoved(TracerProbe probe, IdeSnapshot snapshot) {}\n\n        /**\n         * Invoked when setting up a new Tracer session. This method allows a\n         * Package to notify the user about initialization progress. The actual\n         * initialization (and updating the TracerProgressObject) should be\n         * performed in the sessionStarting() method. Useful for example for\n         * messaging a delay during instrumentation of classes in target application.\n         *\n         * @param probes probes defined for the Tracer session\n         * @param snapshot profiler snapshot\n         * @param refresh session refresh rate in milliseconds\n         * @return TracerProgressObject null in default implementation\n         */\n        public TracerProgressObject sessionInitializing(TracerProbe[] probes,\n                IdeSnapshot snapshot, int refresh) { return null; }\n\n        public void sessionStarting(TracerProbe[] probes, IdeSnapshot snapshot)\n                throws SessionInitializationException {}\n\n        public void sessionRunning(TracerProbe[] probes, IdeSnapshot snapshot) {}\n\n        public void sessionStopping(TracerProbe[] probes, IdeSnapshot snapshot) {}\n\n        public void sessionFinished(TracerProbe[] probes, IdeSnapshot snapshot) {}\n\n        public void refreshRateChanged(TracerProbe[] probes, IdeSnapshot snapshot,\n                int refresh) {}\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/Positionable.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n\nimport java.io.Serializable;\nimport java.util.Comparator;\n\n/**\n * Common interface for entities that can specify their position within other entities.\n *\n * @author Jiri Sedlacek\n */\npublic interface Positionable {\n\n    /**\n     * Entity will be placed before first entity with POSITION_LAST position or at the current last position if there's no entity with POSITION_LAST position.\n     */\n    public static final int POSITION_AT_THE_END = Integer.MAX_VALUE - 1;\n\n    /**\n     * Entity will be placed at the current last position.\n     */\n    public static final int POSITION_LAST = Integer.MAX_VALUE;\n\n    /**\n     * Comparator based on <code>getPreferredPosition()</code> value.\n     * <code>COMPARATOR.compare(Positionable p1, Positionable p2)</code> returns\n     * <code>0</code> only if <code>p1.getPreferredPosition() == p2.getPreferredPosition</code>,\n     * not to be used as a comparator for <code>TreeSet</code> or <code>TreeMap</code>.\n     */\n    public static final Comparator COMPARATOR = new PositionableComparator();\n\n    /**\n     * Comparator based on <code>getPreferredPosition()</code> value.\n     * <code>COMPARATOR.compare(Positionable p1, Positionable p2)</code> returns\n     * <code>0</code> only if <code>p1.equals(p2)</code>, safe to be used as a\n     * comparator for <code>TreeSet</code> or <code>TreeMap</code>.\n     */\n    public static final Comparator STRONG_COMPARATOR = new StrongPositionableComparator();\n\n    /**\n     * Returns preferred position of this entity within other entities.\n     *\n     * @return preferred position of this entity within other entities.\n     */\n    public int getPreferredPosition();\n\n    /**\n     * Implementation of Comparator based on <code>getPreferredPosition()</code> value.\n     * <code>PositionableComparator.compare(Positionable p1, Positionable p2)</code> returns\n     * <code>0</code> only if <code>p1.getPreferredPosition() == p2.getPreferredPosition</code>,\n     * not to be used as a comparator for <code>TreeSet</code> or <code>TreeMap</code>.\n     */\n    static final class PositionableComparator implements Comparator, Serializable {\n        \n        public int compare(Object o1, Object o2) {\n            Positionable p1 = (Positionable)o1;\n            Positionable p2 = (Positionable)o2;\n            \n            int position1 = p1.getPreferredPosition();\n            int position2 = p2.getPreferredPosition();\n\n            return Integer.compare(position1, position2);\n        }\n        \n    }\n    \n    /**\n     * Implementation of Comparator based on <code>getPreferredPosition()</code> value.\n     * <code>StrongPositionableComparator.compare(Positionable p1, Positionable p2)</code>\n     * returns <code>0</code> only if <code>p1.equals(p2)</code>, safe to be used\n     * as a comparator for <code>TreeSet</code> or <code>TreeMap</code>.\n     */\n    static final class StrongPositionableComparator implements Comparator, Serializable {\n        \n        public int compare(Object o1, Object o2) {\n            Positionable p1 = (Positionable)o1;\n            Positionable p2 = (Positionable)o2;\n            \n            int position1 = p1.getPreferredPosition();\n            int position2 = p2.getPreferredPosition();\n            \n            // Compare using getPreferredPosition()\n            if (position1 > position2) return 1;\n            else if (position1 < position2) return -1;\n            \n            // Make sure to return 0 for o1.equals(o2)\n            if (o1.equals(o2)) return 0;\n            \n            // Compare using classname\n            int result = ClassNameComparator.INSTANCE.compare(o1, o2);\n            if (result != 0) return result;\n            \n            // Compare using System.identityHashCode(o)\n            result = Integer.valueOf(System.identityHashCode(o1)).compareTo(\n                     Integer.valueOf(System.identityHashCode(o2)));\n            if (result != 0) return result;\n            \n            // Compare using o.hashCode()\n            result = Integer.valueOf(o1.hashCode()).compareTo(\n                     Integer.valueOf(o2.hashCode()));\n            if (result != 0) return result;\n            \n            // Give up, pretend that second number is greater\n            return -1;\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/ProbeItemDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n\nimport java.awt.Color;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items.ContinuousXYItemDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items.DiscreteXYItemDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items.IconItemDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items.ValueItemDescriptor;\n\n/**\n * ProbeItemDescriptor describes a TracerProbe item appearance in the UI.\n * <p>\n *\n * Current version supports two general types of items: continuous and discrete.\n * Continuous items consist of non-rectangular polyline or polygon segments\n * connecting the values. The values define vertices of the segments.\n * <p>\n *\n * Discrete items consist of rectangular segments either connected together or\n * divided into bar segments. The values are located in the middle of the segments.\n * <p>\n *\n * Each descriptor requires a common set of mandatory options:\n * <ul>\n * <li><code>name</code>: item name\n * <li><code>description</code>: item description, may be <code>null</code>\n * <li><code>formatter</code>: ItemValueFormatter instance which defines how the item values are presented in UI\n * </ul>\n * <p>\n *\n * The other options which may be set are:\n * <ul>\n * <li><code>dataFactor</code>: a multiplication factor for item values, useful when displaying multiple items in one graph\n * <li<code>minValue</code>: minimum (initial) item value, typically set for zero-based metrics (heap size)\n * <li><code>maxValue</code>: maximum (initial) item value, may be used for the initial graph scale\n * </ul>\n * <p>\n *\n * There's no need to define line width and/or line/fill colors, the framework\n * guarantees that each item in a graph will be displayed by a different color.\n * If needed, line width and/or line/fill colors may be customized by setting\n * these options:\n * <ul>\n * <li><code>lineWidth</code>: width of the line, default is <code>2f</code>\n * <li><code>lineColor</code>: color of the line, may be <code>null</code>\n * <li><code>fillColor</code>: color of the filled area, may be <code>null</code>\n * </ul>\n * <p>\n *\n * <b>Note:</b> Use the predefined static methods to create instances of ProbeItemDescriptor.\n * Custom instances of ProbeItemDescriptor are not supported and will cause a\n * <code>RuntimeException</code>.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProbeItemDescriptor {\n\n    // --- Public predefined constants -----------------------------------------\n\n    /**\n     * Minimum item value is undefined.\n     */\n    public static final long MIN_VALUE_UNDEFINED = Long.MAX_VALUE;\n    /**\n     * Maximum item value is undefined.\n     */\n    public static final long MAX_VALUE_UNDEFINED = Long.MIN_VALUE;\n    /**\n     * Value is undefined. For minimum/maximum value use MIN_VALUE_UNDEFINED or\n     * MAX_VALUE_UNDEFINED.\n     */\n    public static final long VALUE_UNDEFINED = Long.MIN_VALUE - 1;\n\n    /**\n     * Default color.\n     */\n    public static final Color DEFAULT_COLOR = new Color(0, 0, 0); // use == to identify this instance!\n\n    /**\n     * Default line width.\n     */\n    public static final float DEFAULT_LINE_WIDTH = -1.0F;\n\n\n    // --- Private instance variables ------------------------------------------\n\n    private final String name;\n    private final String description;\n\n\n    // --- Protected constructor -----------------------------------------------\n\n    protected ProbeItemDescriptor(String name, String description) {\n        if (name == null)\n            throw new IllegalArgumentException(\"name cannot be null\"); // NOI18N\n\n        // Custom ProbeItemDescriptor subclasses are currently not supported.\n        // May be supported in future versions together with custom Painters.\n        if (!(this instanceof ValueItemDescriptor))\n            throw new UnsupportedOperationException(\"Custom descriptor not supported. Use the predefined descriptors.\"); // NOI18N\n\n        this.name = name;\n        this.description = description;\n    }\n\n\n    // --- Common implementation -----------------------------------------------\n\n    /**\n     * Returns name of the item.\n     * @return name of the item\n     */\n    public final String getName() { return name; }\n\n    /**\n     * Returns description of the item.\n     * @return description of the item\n     */\n    public final String getDescription() { return description; }\n\n\n    // === Public factory methods ==============================================\n\n    // --- Icon items ----------------------------------------------------------\n\n    public static ProbeItemDescriptor iconItem(String name, String description,\n                                               ItemValueFormatter formatter) {\n        return new IconItemDescriptor(name, description, formatter, DEFAULT_COLOR);\n    }\n\n\n    // --- Continuous items ----------------------------------------------------\n\n    /**\n     * Creates descriptor for a continuous item created by line segments.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @return descriptor for a continuous item created by line segments\n     */\n    public static ProbeItemDescriptor continuousLineItem(String name, String description,\n                                                         ItemValueFormatter formatter) {\n\n        return continuousItem(name, description, formatter, 1d, 0, MAX_VALUE_UNDEFINED,\n                              DEFAULT_LINE_WIDTH, DEFAULT_COLOR, null);\n    }\n\n    /**\n     * Creates descriptor for a continuous item created by line segments with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @return descriptor for a continuous item created by line segments\n     */\n    public static ProbeItemDescriptor continuousLineItem(String name, String description,\n                                                         ItemValueFormatter formatter,\n                                                         double dataFactor,\n                                                         long minValue, long maxValue) {\n\n        return continuousItem(name, description, formatter, dataFactor, minValue,\n                              maxValue, DEFAULT_LINE_WIDTH, DEFAULT_COLOR, null);\n    }\n\n    /**\n     * Creates descriptor for a continuous item created by filled segments.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @return descriptor for a continuous item created by filled segments\n     */\n    public static ProbeItemDescriptor continuousFillItem(String name, String description,\n                                                         ItemValueFormatter formatter) {\n\n        return continuousItem(name, description, formatter, 1d, 0, MAX_VALUE_UNDEFINED,\n                              DEFAULT_LINE_WIDTH, null, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a continuous item created by filled segments with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @return descriptor for a continuous item created by filled segments\n     */\n    public static ProbeItemDescriptor continuousFillItem(String name, String description,\n                                                         ItemValueFormatter formatter,\n                                                         double dataFactor,\n                                                         long minValue, long maxValue) {\n\n        return continuousItem(name, description, formatter, dataFactor, minValue,\n                              maxValue, DEFAULT_LINE_WIDTH, null, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a continuous item created by line and filled segments.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @return descriptor for a continuous item created by line and filled segments\n     */\n    public static ProbeItemDescriptor continuousLineFillItem(String name, String description,\n                                                             ItemValueFormatter formatter) {\n\n        return continuousItem(name, description, formatter, 1d, 0, MAX_VALUE_UNDEFINED,\n                              DEFAULT_LINE_WIDTH, DEFAULT_COLOR, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a continuous item created by line and filled segments with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @return descriptor for a continuous item created by line and filled segments\n     */\n    public static ProbeItemDescriptor continuousLineFillItem(String name, String description,\n                                                             ItemValueFormatter formatter,\n                                                             double dataFactor,\n                                                             long minValue, long maxValue) {\n\n        return continuousItem(name, description, formatter, dataFactor, minValue,\n                              maxValue, DEFAULT_LINE_WIDTH, DEFAULT_COLOR, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a general continuous item with custom dataFactor ad min/max values, and custom line width and line/fill colors.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @param lineWidth line width\n     * @param lineColor line color or null\n     * @param fillColor fill color or null\n     * @return descriptor for a general continuous item\n     */\n    public static ProbeItemDescriptor continuousItem(String name, String description,\n                                                     ItemValueFormatter formatter,\n                                                     double dataFactor, long minValue,\n                                                     long maxValue, float lineWidth,\n                                                     Color lineColor, Color fillColor) {\n        \n        if (lineColor == null && fillColor == null)\n            throw new IllegalArgumentException(\"Either lineColor or fillColor must be defined\"); // NOI18N\n\n        return new ContinuousXYItemDescriptor(name, description, formatter, dataFactor,\n                                              minValue, maxValue, lineWidth, lineColor,\n                                              fillColor);\n    }\n\n\n    // --- Discrete items ------------------------------------------------------\n\n    /**\n     * Creates descriptor for a discrete item created by line segments representing the outline.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @return descriptor for a discrete item created by line segments representing the outline\n     */\n    public static ProbeItemDescriptor discreteLineItem(String name, String description,\n                                                       ItemValueFormatter formatter) {\n\n        return discreteOutlineItem(name, description, formatter, 1d, 0, MAX_VALUE_UNDEFINED,\n                                   DEFAULT_LINE_WIDTH, DEFAULT_COLOR, null);\n    }\n\n    /**\n     * Creates descriptor for a discrete item created by line segments representing the outline with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @return descriptor for a discrete item created by line segments representing the outline\n     */\n    public static ProbeItemDescriptor discreteLineItem(String name, String description,\n                                                       ItemValueFormatter formatter,\n                                                       double dataFactor,\n                                                       long minValue, long maxValue) {\n\n        return discreteOutlineItem(name, description, formatter, dataFactor, minValue,\n                                   maxValue, DEFAULT_LINE_WIDTH, DEFAULT_COLOR, null);\n    }\n\n    /**\n     * Creates descriptor of a discrete item created by filled segments.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @return descriptor of a discrete item created by filled segments\n     */\n    public static ProbeItemDescriptor discreteFillItem(String name, String description,\n                                                       ItemValueFormatter formatter) {\n\n        return discreteOutlineItem(name, description, formatter, 1d, 0, MAX_VALUE_UNDEFINED,\n                                   DEFAULT_LINE_WIDTH, null, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor of a discrete item created by filled segments with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @return descriptor of a discrete item created by filled segments\n     */\n    public static ProbeItemDescriptor discreteFillItem(String name, String description,\n                                                       ItemValueFormatter formatter,\n                                                       double dataFactor,\n                                                       long minValue, long maxValue) {\n\n        return discreteOutlineItem(name, description, formatter, dataFactor, minValue,\n                                   maxValue, DEFAULT_LINE_WIDTH, null, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a discrete item created by line segments representing the outline and filled segments.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @return descriptor for a discrete item created by line segments representing the outline and filled segments\n     */\n    public static ProbeItemDescriptor discreteLineFillItem(String name, String description,\n                                                           ItemValueFormatter formatter) {\n\n        return discreteOutlineItem(name, description, formatter, 1d, 0, MAX_VALUE_UNDEFINED,\n                                  DEFAULT_LINE_WIDTH, DEFAULT_COLOR, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a discrete item created by line segments representing the outline and filled segments with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @return descriptor for a discrete item created by line segments representing the outline and filled segments\n     */\n    public static ProbeItemDescriptor discreteLineFillItem(String name, String description,\n                                                           ItemValueFormatter formatter,\n                                                           double dataFactor,\n                                                           long minValue, long maxValue) {\n        \n        return discreteOutlineItem(name, description, formatter, dataFactor, minValue,\n                                   maxValue, DEFAULT_LINE_WIDTH, DEFAULT_COLOR, DEFAULT_COLOR);\n    }\n\n    /**\n     * Creates descriptor for a general discrete outlined item with custom dataFactor ad min/max values, and custom line width and line/fill colors.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @param lineWidth line width\n     * @param lineColor line color or null\n     * @param fillColor fill color or null\n     * @return descriptor for a general discrete outlined item\n     */\n    public static ProbeItemDescriptor discreteOutlineItem(String name, String description,\n                                                          ItemValueFormatter formatter,\n                                                          double dataFactor, long minValue,\n                                                          long maxValue, float lineWidth,\n                                                          Color lineColor, Color fillColor) {\n        \n        if (lineColor == null && fillColor == null)\n            throw new IllegalArgumentException(\"Either lineColor or fillColor must be defined\"); // NOI18N\n\n        return discreteItem(name, description, formatter, dataFactor, minValue, maxValue,\n                            lineWidth, lineColor, fillColor, 0, false, false, true);\n    }\n\n    /**\n     * Creates descriptor for a discrete item represented by a horizontal line segment, optionally filled, with custom dataFactor ad min/max values.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @param filled true if the segments are filled\n     * @param width width of/between the segments\n     * @param fixedWidth true if width defines segment width, false if width defines segments spacing\n     * @return descriptor for a discrete item represented by a horizontal line segment, optionally filled\n     */\n    public static ProbeItemDescriptor discreteToplineItem(String name, String description,\n                                                          ItemValueFormatter formatter,\n                                                          double dataFactor, long minValue,\n                                                          long maxValue, boolean filled,\n                                                          int width, boolean fixedWidth) {\n\n        return discreteItem(name, description, formatter, dataFactor, minValue, maxValue,\n                            DEFAULT_LINE_WIDTH, DEFAULT_COLOR, filled ? DEFAULT_COLOR : null,\n                            width, fixedWidth, true, false);\n    }\n\n    /**\n     * Creates descriptor for a discrete item represented by a horizontal line segment, optionally filled, with custom dataFactor ad min/max values, and custom line width and line/fill colors.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @param lineWidth line width\n     * @param lineColor line color or null\n     * @param fillColor fill color or null\n     * @param width width width of/between the segments\n     * @param fixedWidth fixedWidth true if width defines segment width, false if width defines segments spacing\n     * @return descriptor for a discrete item represented by a horizontal line segment, optionally filled\n     */\n    public static ProbeItemDescriptor discreteToplineItem(String name, String description,\n                                                          ItemValueFormatter formatter,\n                                                          double dataFactor, long minValue,\n                                                          long maxValue, float lineWidth,\n                                                          Color lineColor, Color fillColor,\n                                                          int width, boolean fixedWidth) {\n        \n        if (lineColor == null && fillColor == null)\n            throw new IllegalArgumentException(\"Either lineColor or fillColor must be defined\"); // NOI18N\n\n        return discreteItem(name, description, formatter, dataFactor, minValue, maxValue,\n                            lineWidth, lineColor, fillColor, width, fixedWidth, true, false);\n    }\n\n    /**\n     * Creates descriptor for a discrete item represented by vertical bars, with custom dataFactor ad min/max values\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @param outlined true if the bars are outlined\n     * @param filled true if the bars are filled\n     * @param width width width of/between the bars\n     * @param fixedWidth fixedWidth true if width defines bar width, false if width defines bars spacing\n     * @return descriptor for a discrete item represented by vertical bars\n     */\n    public static ProbeItemDescriptor discreteBarItem(String name, String description,\n                                                      ItemValueFormatter formatter,\n                                                      double dataFactor, long minValue,\n                                                      long maxValue, boolean outlined,\n                                                      boolean filled, int width,\n                                                      boolean fixedWidth) {\n\n        if (!outlined && !filled)\n            throw new IllegalArgumentException(\"Either outlined or filled must be set\"); // NOI18N\n\n        return discreteItem(name, description, formatter, dataFactor, minValue, maxValue,\n                            DEFAULT_LINE_WIDTH, outlined ? DEFAULT_COLOR : null,\n                            filled ? DEFAULT_COLOR : null, width, fixedWidth, false, !filled);\n    }\n\n    /**\n     * Creates descriptor for a discrete item represented by vertical bars, with custom dataFactor ad min/max values, and custom line width and line/fill colors.\n     *\n     * @param name item name\n     * @param description item description or null\n     * @param formatter item formatter\n     * @param dataFactor multiplication factor\n     * @param minValue minimum (initial) item value\n     * @param maxValue maximum (initial) item value\n     * @param lineWidth line width\n     * @param lineColor line color or null\n     * @param fillColor fill color or null\n     * @param width width width of/between the bars\n     * @param fixedWidth fixedWidth true if width defines bar width, false if width defines bars spacing\n     * @return descriptor for a discrete item represented by vertical bars\n     */\n    public static ProbeItemDescriptor discreteBarItem(String name, String description,\n                                                      ItemValueFormatter formatter,\n                                                      double dataFactor, long minValue,\n                                                      long maxValue, float lineWidth,\n                                                      Color lineColor, Color fillColor,\n                                                      int width, boolean fixedWidth) {\n        \n        if (lineColor == null && fillColor == null)\n            throw new IllegalArgumentException(\"Either lineColor or fillColor must be defined\"); // NOI18N\n\n        return discreteItem(name, description, formatter, dataFactor, minValue, maxValue,\n                            lineWidth, lineColor, fillColor, width, fixedWidth, false, fillColor == null);\n    }\n\n    private static ProbeItemDescriptor discreteItem(String name, String description,\n                                                    ItemValueFormatter formatter,\n                                                    double dataFactor, long minValue,\n                                                    long maxValue, float lineWidth,\n                                                    Color lineColor, Color fillColor,\n                                                    int width, boolean fixedWidth,\n                                                    boolean topLineOnly,\n                                                    boolean outlineOnly) {\n\n        return new DiscreteXYItemDescriptor(name, description, formatter, dataFactor,\n                                            minValue, maxValue, lineWidth, lineColor,\n                                            fillColor, width, fixedWidth, topLineOnly,\n                                            outlineOnly);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/ProbeStateHandler.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.IdeSnapshot;\n\n\n/**\n * ProbeStateHandler interface allows an implementing TracerProbe to be\n * notified about Tracer session state. See TracerProbe.getStateHandler().\n *\n * @author Jiri Sedlacek\n */\npublic interface ProbeStateHandler {\n\n    /**\n     * Invoked when the is added into the Timeline view.\n     *\n     * @param snapshot profiler snapshot\n     */\n    public void probeAdded(IdeSnapshot snapshot);\n\n    /**\n     * Invoked when the probe is removed from the Timeline view.\n     *\n     * @param snapshot profiler snapshot\n     */\n    public void probeRemoved(IdeSnapshot snapshot);\n\n\n    /**\n     * Invoked when setting up a new Tracer session. This method allows a\n     * Probe to notify the user about initialization progress. The actual\n     * initialization (and updating the TracerProgressObject) should be\n     * performed in the sessionStarting() method. Useful for example for\n     * messaging a delay during instrumentation of classes in target application.\n     *\n     * @param snapshot profiler snapshot\n     * @param refresh session refresh rate in milliseconds\n     * @return TracerProgressObject to track initialization progress\n     */\n    public TracerProgressObject sessionInitializing(IdeSnapshot snapshot, int refresh);\n\n    /**\n     * Invoked when starting a new Tracer session. Any probe initialization\n     * should be performed in this method. If provided by the\n     * sessionInitializing method, a TracerProgressObject should be updated to\n     * reflect the initialization progress. This method may throw a\n     * SessionInitializationException in case of initialization failure. Any\n     * packages/probes initialized so far will be correctly finished, however the\n     * probe throwing the SessionInitializationException is responsible for\n     * cleaning up any used resources and restoring its state without any\n     * following events.\n     *\n     * @param snapshot profiler snapshot\n     * @throws SessionInitializationException in case of initialization failure\n     */\n    public void sessionStarting(IdeSnapshot snapshot)\n            throws SessionInitializationException;\n\n    /**\n     * Invoked when all packages/probes have been started and the Tracer session\n     * is running and collecting data.\n     *\n     * @param snapshot profiler snapshot\n     */\n    public void sessionRunning(IdeSnapshot snapshot);\n\n    /**\n     * Invoked when stopping the Tracer session. Any probe cleanup should be\n     * performed in this method. Any long-running cleanup code should preferably\n     * be invoked in a separate worker thread to allow the Tracer session to\n     * finish as fast as possible. Be sure to check/wait for the cleanup thread\n     * when starting a new Tracer session in sessionStarting().\n     *\n     * @param snapshot profiler snapshot\n     */\n    public void sessionStopping(IdeSnapshot snapshot);\n\n    /**\n     * Invoked when the Tracer session has finished.\n     *\n     * @param snapshot profiler snapshot\n     */\n    public void sessionFinished(IdeSnapshot snapshot);\n\n    /**\n     * Invoked when refresh rate of the Tracer session has been changed.\n     *\n     * @param snapshot profiler snapshot\n     * @param refresh session refresh rate in milliseconds\n     */\n    public void refreshRateChanged(IdeSnapshot snapshot, int refresh);\n\n\n    /**\n     * An abstract adapter class for receiving Tracer session state notifications.\n     */\n    public abstract class Adapter implements ProbeStateHandler {\n\n        public void probeAdded(IdeSnapshot snapshot) {}\n\n        public void probeRemoved(IdeSnapshot snapshot) {}\n\n        /**\n         * Invoked when setting up a new Tracer session. This method allows a\n         * Probe to notify the user about initialization progress. The actual\n         * initialization (and updating the TracerProgressObject) should be\n         * performed in the sessionStarting() method. Useful for example for\n         * messaging a delay during instrumentation of classes in target application.\n         *\n         * @param snapshot profiler snapshot\n         * @param refresh session refresh rate in milliseconds\n         * @return TracerProgressObject null in default implementation\n         */\n        public TracerProgressObject sessionInitializing(IdeSnapshot snapshot, int refresh) {\n            return null;\n        }\n\n        public void sessionStarting(IdeSnapshot snapshot)\n                throws SessionInitializationException {}\n\n        public void sessionRunning(IdeSnapshot snapshot) {}\n\n        public void sessionStopping(IdeSnapshot snapshot) {}\n\n        public void sessionFinished(IdeSnapshot snapshot) {}\n\n        public void refreshRateChanged(IdeSnapshot snapshot, int refresh) {}\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/SessionInitializationException.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n\n/**\n * Signals that a TracerPackage/TracerProbe failed to initialize for a new\n * Tracer session. Preferably provides a message to notify the user about\n * the failure.\n *\n * @author Jiri Sedlacek\n */\npublic final class SessionInitializationException extends Exception {\n\n    private final String userMessage;\n\n\n    /**\n     * Creates a new instance of SessionInitializationException with defined\n     * log message and default user message.\n     *\n     * @param logMessage log message\n     */\n    public SessionInitializationException(String logMessage) {\n        this(null, logMessage);\n    }\n\n    /**\n     * Creates a new instance of SessionInitializationException with defined\n     * log message and cause and default user message.\n     *\n     * @param logMessage log message\n     * @param cause exception cause\n     */\n    public SessionInitializationException(String logMessage,\n                                          Throwable cause) {\n        this(null, logMessage, cause);\n    }\n\n    /**\n     * Creates a new instance of SessionInitializationException with defined\n     * user message and log message.\n     *\n     * @param userMessage user message\n     * @param logMessage log message\n     */\n    public SessionInitializationException(String userMessage,\n                                          String logMessage) {\n        super(logMessage);\n        this.userMessage = userMessage;\n    }\n\n    /**\n     * Creates a new instance of SessionInitializationException with defined\n     * user message, log message and cause.\n     *\n     * @param userMessage user message\n     * @param logMessage log message\n     * @param cause exception cause\n     */\n    public SessionInitializationException(String userMessage,\n                                          String logMessage,\n                                          Throwable cause) {\n        super(logMessage, cause);\n        this.userMessage = userMessage;\n    }\n\n\n    /**\n     * Returns an user message to be displayed in Tracer UI. The message should\n     * be short, for example \"Probe XYZ failed to initialize\" or \"Probe XYZ\n     * failed to connect to target application.\"\n     *\n     * @return user message to be displayed in Tracer UI\n     */\n    public String getUserMessage() {\n        return userMessage;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/TracerPackage.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.IdeSnapshot;\n\n/**\n * TracerPackage is a container for a set of TracerProbes distributed as a single\n * package (plugin). The probes in a package are typically designed to monitor\n * the same functional unit on the target - for example disk I/O, network I/O,\n * memory subsystem etc.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class TracerPackage implements Positionable {\n\n    private final String name;\n    private final String description;\n    private final Icon icon;\n    private final int preferredPosition;\n\n\n    /**\n     * Creates new instance of TracerPackage.\n     *\n     * @param name name of the package\n     * @param description description of the package\n     * @param icon icon of the package\n     * @param preferredPosition preferred position of the package in UI\n     */\n    public TracerPackage(String name, String description, Icon icon,\n                         int preferredPosition) {\n        this.name = name;\n        this.description = description;\n        this.icon = icon;\n        this.preferredPosition = preferredPosition;\n    }\n\n\n    /**\n     * Returns name of the package.\n     *\n     * @return name of the package\n     */\n    public final String getName() { return name; }\n\n    /**\n     * Returns description of the package.\n     *\n     * @return description of the package\n     */\n    public final String getDescription() { return description; }\n\n    /**\n     * Returns icon of the package.\n     *\n     * @return icon of the package\n     */\n    public final Icon getIcon() { return icon; }\n\n    /**\n     * Returns preferred position of the package in UI.\n     *\n     * @return preferred position of the package in UI\n     */\n    public final int getPreferredPosition() { return preferredPosition; }\n\n\n    /**\n     * Returns array of TracerProbeDescriptors to present the package probes in UI.\n     * Should always return descriptors for all probes provided by the provider\n     * for each DataSource. If a probe is not available for the DataSource its\n     * descriptor should be disabled - TracerProbeDescriptor.isProbeAvailable()\n     * returns false.\n     *\n     * @return array of TracerProbeDescriptors to present the package probes in UI\n     */\n    public abstract TracerProbeDescriptor[] getProbeDescriptors();\n\n    /**\n     * Returns the probe to be used in Tracer session. The probe to return\n     * is defined by its TracerProbeDescriptor created by getProbeDescriptors()\n     * method and selected by the user.\n     *\n     * @param descriptor TracerProbeDescriptor selecting the probe\n     * @return the probe to be used in Tracer session\n     */\n    public abstract TracerProbe getProbe(TracerProbeDescriptor descriptor);\n\n    \n    /**\n     * Optionally returns PackageStateHandler instance which obtains notifications\n     * about the Tracer session status in context of TracerProbes provided by this\n     * TracerPackage. Default implementation returns null. You may use StateAware\n     * subclass instead of implementing this method to obtain the notifications.\n     *\n     * @return PackageStateHandler instance which obtains status notifications,\n     * default implementation returns null\n     */\n    public PackageStateHandler getStateHandler() { return null; }\n\n\n    /**\n     * An abstract adapter class for receiving Tracer session state notifications.\n     * See PackageStateHandler for details.\n     *\n     */\n    public static abstract class SessionAware extends TracerPackage {\n\n        private PackageStateHandler stateHandler;\n\n\n        /**\n         * Creates new instance of TracerPackage.SessionAware.\n         *\n         * @param name name of the package\n         * @param description description of the package\n         * @param icon icon of the package\n         * @param preferredPosition preferred position of the package in UI\n         */\n        public SessionAware(String name, String description,\n                          Icon icon, int preferredPosition) {\n            super(name, description, icon, preferredPosition);\n        }\n\n\n        /**\n         * Returns a predefined PackageStateHandler which obtains notifications\n         * about the Tracer session state in context of TracerProbes provided by this\n         * TracerPackage.\n         *\n         * @return predefined PackageStateHandler which obtains status notifications\n         */\n        public synchronized final PackageStateHandler getStateHandler() {\n            if (stateHandler == null) stateHandler = new PackageStateHandler() {\n                public void probeAdded(TracerProbe probe, IdeSnapshot snapshot) {\n                    SessionAware.this.probeAdded(probe, snapshot);\n                }\n                public void probeRemoved(TracerProbe probe, IdeSnapshot snapshot) {\n                    SessionAware.this.probeRemoved(probe, snapshot);\n                }\n                public TracerProgressObject sessionInitializing(TracerProbe[] probes,\n                    IdeSnapshot snapshot, int refresh) {\n                    return SessionAware.this.sessionInitializing(probes, snapshot, refresh);\n                }\n                public void sessionStarting(TracerProbe[] probes, IdeSnapshot snapshot)\n                        throws SessionInitializationException {\n                    SessionAware.this.sessionStarting(probes, snapshot);\n                }\n                public void sessionRunning(TracerProbe[] probes, IdeSnapshot snapshot) {\n                    SessionAware.this.sessionRunning(probes, snapshot);\n                }\n                public void sessionStopping(TracerProbe[] probes, IdeSnapshot snapshot) {\n                    SessionAware.this.sessionStopping(probes, snapshot);\n                }\n                public void sessionFinished(TracerProbe[] probes, IdeSnapshot snapshot) {\n                    SessionAware.this.sessionFinished(probes, snapshot);\n                }\n                public void refreshRateChanged(TracerProbe[] probes, IdeSnapshot snapshot,\n                        int refresh) {\n                    SessionAware.this.refreshRateChanged(probes, snapshot, refresh);\n                }\n            };\n            return stateHandler;\n        }\n\n\n        /**\n         * Invoked when a probe is added into the Timeline view.\n         *\n         * @param probe added probe\n         * @param snapshot profiler snapshot\n         */\n        protected void probeAdded(TracerProbe probe, IdeSnapshot snapshot) {}\n\n        /**\n         * Invoked when a probe is removed from the Timeline view.\n         *\n         * @param probe removed probe\n         * @param snapshot profiler snapshot\n         */\n        protected void probeRemoved(TracerProbe probe, IdeSnapshot snapshot) {}\n\n\n        /**\n         * Invoked when setting up a new Tracer session. This method allows a\n         * Package to notify the user about initialization progress. The actual\n         * initialization (and updating the TracerProgressObject) should be\n         * performed in the sessionStarting() method. Useful for example for\n         * messaging a delay during instrumentation of classes in target application.\n         *\n         * @param probes probes defined for the Tracer session\n         * @param snapshot profiler snapshot\n         * @param refresh session refresh rate in milliseconds\n         * @return TracerProgressObject to track initialization progress\n         */\n        protected TracerProgressObject sessionInitializing(TracerProbe[] probes,\n                IdeSnapshot snapshot, int refresh) { return null; }\n\n        /**\n         * Invoked when starting a new Tracer session. Any package/probes\n         * initialization should be performed in this method. If provided by the\n         * sessionInitializing method, a TracerProgressObject should be updated to\n         * reflect the initialization progress. This method may throw a\n         * SessionInitializationException in case of initialization failure. Any\n         * packages/probes initialized so far will be correctly finished, however the\n         * package throwing the SessionInitializationException is responsible for\n         * cleaning up any used resources and restoring its state without any\n         * following events.\n         *\n         * @param probes probes defined for the Tracer session\n         * @param snapshot profiler snapshot\n         * @throws SessionInitializationException in case of initialization failure\n         */\n        protected void sessionStarting(TracerProbe[] probes, IdeSnapshot snapshot)\n                throws SessionInitializationException {}\n\n        /**\n         * Invoked when all packages/probes have been started and the Tracer session\n         * is running and collecting data.\n         *\n         * @param probes probes defined for the Tracer session\n         * @param snapshot profiler snapshot\n         */\n        protected void sessionRunning(TracerProbe[] probes, IdeSnapshot snapshot) {}\n\n        /**\n         * Invoked when stopping the Tracer session. Any package/probes cleanup\n         * should be performed in this method. Any long-running cleanup code should\n         * preferably be invoked in a separate worker thread to allow the Tracer\n         * session to finish as fast as possible. Be sure to check/wait for the\n         * cleanup thread when starting a new Tracer session in sessionStarting().\n         *\n         * @param probes probes defined for the Tracer session\n         * @param snapshot profiler snapshot\n         */\n        protected void sessionStopping(TracerProbe[] probes, IdeSnapshot snapshot) {}\n\n        /**\n         * Invoked when the Tracer session has finished.\n         *\n         * @param probes probes defined for the Tracer session\n         * @param snapshot profiler snapshot\n         */\n        protected void sessionFinished(TracerProbe[] probes, IdeSnapshot snapshot) {}\n\n        /**\n         * Invoked when refresh rate of the Tracer session has been changed.\n         *\n         * @param probes probes defined for the Tracer session\n         * @param snapshot profiler snapshot\n         * @param refresh session refresh rate in milliseconds\n         */\n        protected void refreshRateChanged(TracerProbe[] probes, IdeSnapshot snapshot,\n                int refresh) {}\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/TracerPackageProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.IdeSnapshot;\n\n\n/**\n * Provider of TracerPackage(s) for a DataSource type.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class TracerPackageProvider {\n\n    private final Class scope;\n\n\n    /**\n     * Creates new instance of TracerPackageProvider with defined scope.\n     *\n     * @param scope scope of the provider\n     */\n    public TracerPackageProvider(Class scope) { this.scope = scope; }\n\n\n    /**\n     * Returns scope of the provider.\n     *\n     * @return scope of the provider\n     */\n    public final Class getScope() { return scope; }\n\n\n    /**\n     * Returns TracerPackages for the provided target.\n     *\n     * @return TracerPackages for the provided target\n     */\n    public abstract TracerPackage[] getPackages(IdeSnapshot snapshot);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/TracerProbe.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.IdeSnapshot;\n\n\n/**\n * Tracer probe represents one monitored unit in the Timeline chart. The probe\n * may provide one or several values displayed in the chart, for example several\n * numeric values of an MBean.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class TracerProbe {\n\n    private final ProbeItemDescriptor[] itemDescriptors;\n\n\n    /**\n     * Creates new instance of TracerProbe.\n     *\n     * @param itemDescriptors descriptors of UI appearance of items provided by the probe\n     */\n    public TracerProbe(ProbeItemDescriptor[] itemDescriptors) {\n        if (itemDescriptors == null || itemDescriptors.length == 0)\n            throw new IllegalArgumentException(\"Invalid ProbeItemDescriptors\"); // NOI18N\n        this.itemDescriptors = itemDescriptors;\n    }\n\n\n    /**\n     * Returns descriptors of UI appearance of items provided by the probe.\n     *\n     * @return descriptors of UI appearance of items provided by the probe\n     */\n    public final ProbeItemDescriptor[] getItemDescriptors() { return itemDescriptors; }\n\n\n    /**\n     * Returns number of items provided by the probe.\n     *\n     * @return number of items provided by the probe\n     */\n    public int getItemsCount() { return itemDescriptors.length; }\n\n    /**\n     * Returns values of items provided by the probe at the defined time. It's up\n     * to the probe implementation whether the values will be read in this method\n     * or retrieved from a private data model prefetching the values asynchronously.\n     * The timestamp is the same for a single data-read event for all selected\n     * probes of the actual Tracer session.\n     * <br><br>\n     * <b>Note: current Tracer version doesn't support negative values. Negative\n     * values returned by the probes will be treated as '0' and the user will be\n     * notified by a warning dialog.</b>\n     *\n     * @param sampleIndex index of the data-read event\n     * @return values of items provided by the probe\n     */\n    public abstract long[] getItemValues(int sampleIndex);\n\n\n    /**\n     * Optionally returns ProbeStateHandler instance which obtains notifications\n     * about the Tracer session status. Default implementation returns null.\n     * You may use StateAware subclass instead of implementing this method to\n     * obtain the notifications.\n     *\n     * @return ProbeStateHandler instance which obtains status notifications,\n     * default implementation returns null\n     */\n    public ProbeStateHandler getStateHandler() { return null; }\n\n\n    /**\n     * An abstract adapter class for receiving Tracer session state notifications.\n     * See ProbeStateHandler for details.\n     */\n    public static abstract class SessionAware extends TracerProbe {\n\n        private ProbeStateHandler stateHandler;\n\n        /**\n         * Creates new instance of TracerProbe.SessionAware.\n         *\n         * @param itemDescriptors descriptors of UI appearance of items provided by the probe\n         */\n        public SessionAware(ProbeItemDescriptor[] itemDescriptors) {\n            super(itemDescriptors);\n        }\n\n\n        /**\n         * Returns a predefined ProbeStateHandler which obtains notifications\n         * about the Tracer session state.\n         *\n         * @return predefined ProbeStateHandler which obtains status notifications\n         */\n        public synchronized final ProbeStateHandler getStateHandler() {\n            if (stateHandler == null) stateHandler = new ProbeStateHandler() {\n                public void probeAdded(IdeSnapshot snapshot) {\n                    SessionAware.this.probeAdded(snapshot);\n                }\n                public void probeRemoved(IdeSnapshot snapshot) {\n                    SessionAware.this.probeRemoved(snapshot);\n                }\n                public TracerProgressObject sessionInitializing(IdeSnapshot snapshot, int refresh) {\n                    return SessionAware.this.sessionInitializing(snapshot, refresh);\n                }\n                public void sessionStarting(IdeSnapshot snapshot)\n                        throws SessionInitializationException {\n                    SessionAware.this.sessionStarting(snapshot);\n                }\n                public void sessionRunning(IdeSnapshot snapshot) {\n                    SessionAware.this.sessionRunning(snapshot);\n                }\n                public void sessionStopping(IdeSnapshot snapshot) {\n                    SessionAware.this.sessionStopping(snapshot);\n                }\n                public void sessionFinished(IdeSnapshot snapshot) {\n                    SessionAware.this.sessionFinished(snapshot);\n                }\n                public void refreshRateChanged(IdeSnapshot snapshot, int refresh) {\n                    SessionAware.this.refreshRateChanged(snapshot, refresh);\n                }\n            };\n            return stateHandler;\n        }\n\n\n        /**\n         * Invoked when the is added into the Timeline view.\n         *\n         * @param snapshot profiler snapshot\n         */\n        protected void probeAdded(IdeSnapshot snapshot) {}\n\n        /**\n         * Invoked when the probe is removed from the Timeline view.\n         *\n         * @param snapshot profiler snapshot\n         */\n        protected void probeRemoved(IdeSnapshot snapshot) {}\n\n\n        /**\n         * Invoked when setting up a new Tracer session. This method allows a\n         * Probe to notify the user about initialization progress. The actual\n         * initialization (and updating the TracerProgressObject) should be\n         * performed in the sessionStarting() method. Useful for example for\n         * messaging a delay during instrumentation of classes in target application.\n         *\n         * @param snapshot profiler snapshot\n         * @param refresh session refresh rate in milliseconds\n         * @return TracerProgressObject to track initialization progress\n         */\n        protected TracerProgressObject sessionInitializing(IdeSnapshot snapshot, int refresh) {\n            return null;\n        }\n\n        /**\n         * Invoked when starting a new Tracer session. Any probe initialization\n         * should be performed in this method. If provided by the\n         * sessionInitializing method, a TracerProgressObject should be updated to\n         * reflect the initialization progress. This method may throw a\n         * SessionInitializationException in case of initialization failure. Any\n         * packages/probes initialized so far will be correctly finished, however the\n         * probe throwing the SessionInitializationException is responsible for\n         * cleaning up any used resources and restoring its state without any\n         * following events.\n         *\n         * @param snapshot profiler snapshot\n         * @throws SessionInitializationException in case of initialization failure\n         */\n        protected void sessionStarting(IdeSnapshot snapshot)\n                throws SessionInitializationException {}\n\n        /**\n         * Invoked when all packages/probes have been started and the Tracer session\n         * is running and collecting data.\n         *\n         * @param snapshot profiler snapshot\n         */\n        protected void sessionRunning(IdeSnapshot snapshot) {}\n\n        /**\n         * Invoked when stopping the Tracer session. Any probe cleanup should be\n         * performed in this method. Any long-running cleanup code should preferably\n         * be invoked in a separate worker thread to allow the Tracer session to\n         * finish as fast as possible. Be sure to check/wait for the cleanup thread\n         * when starting a new Tracer session in sessionStarting().\n         *\n         * @param snapshot profiler snapshot\n         */\n        protected void sessionStopping(IdeSnapshot snapshot) {}\n\n        /**\n         * Invoked when the Tracer session has finished.\n         *\n         * @param snapshot profiler snapshot\n         */\n        protected void sessionFinished(IdeSnapshot snapshot) {}\n\n        /**\n         * Invoked when refresh rate of the Tracer session has been changed.\n         *\n         * @param snapshot profiler snapshot\n         * @param refresh session refresh rate in milliseconds\n         */\n        protected void refreshRateChanged(IdeSnapshot snapshot, int refresh) {}\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/TracerProbeDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.icons.TracerIcons;\n\n/**\n * TracerProbeDescriptor defines how a TracerProbe appears in the Tracer UI.\n *\n * @author Jiri Sedlacek\n */\npublic final class TracerProbeDescriptor implements Positionable {\n\n    private final String name;\n    private final String description;\n    private final Icon icon;\n    private final int preferredPosition;\n    private final boolean available;\n\n\n    /**\n     * Creates new instance of TracerProbeDescriptor.\n     *\n     * @param name probe name\n     * @param description probe description\n     * @param icon probe icon\n     * @param preferredPosition preferred position of the probe in UI\n     * @param available availability of the probe in actual context\n     */\n    public TracerProbeDescriptor(String name, String description, Icon icon,\n                                 int preferredPosition, boolean available) {\n        this.name = name;\n        this.description = description;\n        this.icon = icon != null ? icon : Icons.getIcon(TracerIcons.PROBE);\n        this.preferredPosition = preferredPosition;\n        this.available = available;\n    }\n\n\n    /**\n     * Returns probe name.\n     *\n     * @return probe name\n     */\n    public String getProbeName() { return name; }\n\n    /**\n     * Returns probe description.\n     *\n     * @return probe description\n     */\n    public String getProbeDescription() { return description; }\n\n    /**\n     * Returns probe icon.\n     *\n     * @return probe icon\n     */\n    public Icon getProbeIcon() { return icon; }\n\n    /**\n     * Returns preferred position of the probe in UI.\n     *\n     * @return preferred position of the probe in UI\n     */\n    public int getPreferredPosition() { return preferredPosition; }\n\n    /**\n     * Returns true if the probe is available in current context, false otherwise.\n     *\n     * @return true if the probe is available in current context, false otherwise\n     */\n    public boolean isProbeAvailable() { return available; }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/TracerProgressObject.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.SwingUtilities;\n\n/**\n * TracerProgressObject describes progress of the TracerPackage/TracerProbe\n * initialization when starting a Tracer session.\n *\n * @author Jiri Sedlacek\n */\npublic final class TracerProgressObject {\n\n    private final int steps;\n    private String text;\n    private int currentStep;\n    private int lastStep;\n\n    private final Set<Listener> listeners;\n\n\n    /**\n     * Creates new instance of TracerProgressObject with a defined number of\n     * steps.\n     *\n     * @param steps number of steps to finish the initialization\n     */\n    public TracerProgressObject(int steps) {\n        this(steps, null);\n    }\n\n    /**\n     * Creates new instance of TracerProgressObject with a defined number of\n     * steps and text describing the initial state.\n     *\n     * @param steps number of steps to finish the initialization\n     * @param text text describing the initial state\n     */\n    public TracerProgressObject(int steps, String text) {\n        if (steps < 1)\n            throw new IllegalArgumentException(\"steps value must be >= 1: \" + steps); // NOI18N\n\n        this.steps = steps;\n        this.text = text;\n        currentStep = 0;\n        lastStep = 0;\n        listeners = new HashSet<>();\n    }\n\n\n    /**\n     * Returns number of steps to finish the initialization.\n     *\n     * @return number of steps to finish the initialization\n     */\n    public synchronized int getSteps() { return steps; }\n\n    /**\n     * Returns current step of the initialization progress.\n     *\n     * @return current step of the initialization progress\n     */\n    public synchronized int getCurrentStep() { return currentStep; }\n\n    /**\n     * Returns text describing the current state or null.\n     *\n     * @return text describing the current state or null\n     */\n    public synchronized String getText() { return text; }\n\n\n    /**\n     * Adds a single step to the current initialization progress.\n     */\n    public void addStep() { addSteps(1); }\n\n    /**\n     * Adds a single step to the current initialization progress and changes\n     * the text describing the current state.\n     *\n     * @param text text describing the current state\n     */\n    public void addStep(String text)  { addSteps(1, text); }\n\n    /**\n     * Adds a number of steps to the current initialization progress.\n     *\n     * @param steps number of steps to be added to the current initialization progress\n     */\n    public void addSteps(int steps) { addSteps(steps, text); }\n\n    /**\n     * Adds a number of steps to the current initialization progress and changes\n     * the text describing the current state.\n     *\n     * @param steps number of steps to be added to the current initialization progress\n     * @param text text describing the current state\n     */\n    public synchronized void addSteps(int steps, String text) {\n        if (steps < 0)\n            throw new IllegalArgumentException(\"steps value must be >= 0: \" + steps); // NOI18N\n        if (currentStep + steps > this.steps)\n            throw new IllegalArgumentException(\"Total steps exceeded: \" + // NOI18N\n                                               (currentStep + steps) + \">\" + this.steps); // NOI18N\n\n        currentStep += steps;\n        this.text = text;\n        fireChange();\n    }\n\n    /**\n     * Updates text describing the current state without adding any steps to the\n     * current initialization progress.\n     *\n     * @param text text describing the current state\n     */\n    public synchronized void setText(String text) {\n        this.text = text;\n        fireChange();\n    }\n\n    /**\n     * Adds all remaining steps to finish the initialization progress.\n     */\n    public synchronized void finish() {\n        if (isFinished()) return;\n        currentStep = steps;\n        fireChange();\n    }\n\n    /**\n     * Returns true for a finished TracerProgressObject, false otherwise.\n     *\n     * @return true for a finished TracerProgressObject, false otherwise.\n     */\n    public synchronized boolean isFinished() {\n        return currentStep == steps;\n    }\n\n\n    /**\n     * Adds a listener to receive progress notifications.\n     *\n     * @param l listener to be added\n     */\n    public synchronized void addListener(Listener l) { listeners.add(l); }\n\n    /**\n     * Removes a listener receiving progress notifications.\n     *\n     * @param l listener to be removed.\n     */\n    public synchronized void removeListener(Listener l) { listeners.remove(l); }\n\n    private void fireChange() {\n        final int currentStepF = currentStep;\n        final int addedStepsF = currentStep - lastStep;\n        final String textF = text;\n        final Set<Listener> toNotify = new HashSet<>(listeners);\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                for (Listener listener : toNotify)\n                    listener.progressChanged(addedStepsF, currentStepF, textF);\n            }\n        });\n        lastStep = currentStep;\n    }\n\n\n    /**\n     * Listener to receive notifications about the initialization progress.\n     */\n    public static interface Listener {\n\n        /**\n         * Invoked when the progress and/or text describing the current state\n         * changes.\n         *\n         * @param addedSteps new steps added by the change\n         * @param currentStep current step of the initialization progress\n         * @param text text describing the current state\n         */\n        public void progressChanged(int addedSteps, int currentStep, String text);\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/TracerSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.TracerSupportImpl;\n\n/**\n * Entrypoint to the Tracer. Use this class to register and unregister\n * TracerPackageProvider implementations.\n *\n * @author Jiri Sedlacek\n */\npublic final class TracerSupport {\n\n    private static TracerSupport INSTANCE;\n\n\n    /**\n     * Returns singleton instance of TracerSupport.\n     *\n     * @return singleton instance of TracerSupport\n     */\n    public static synchronized TracerSupport getInstance() {\n        if (INSTANCE == null) INSTANCE = new TracerSupport();\n        return INSTANCE;\n    }\n\n\n    /**\n     * Registers TracerPackageProvider.\n     *\n     * @param provider TracerPackageProvider\n     */\n    public void registerPackageProvider(TracerPackageProvider provider) {\n        TracerSupportImpl.getInstance().registerPackageProvider(provider);\n    }\n\n    /**\n     * Unregisters TracerPackageProvider.\n     *\n     * @param provider TracerPackageProvider\n     */\n    public void unregisterPackageProvider(TracerPackageProvider provider) {\n        TracerSupportImpl.getInstance().unregisterPackageProvider(provider);\n    }\n\n\n    private TracerSupport() {}\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Tracer\nOpenIDE-Module-Long-Description=\\\n    Tracer-Framework module is a framework and graphical user interface for visual tracing of applications or other data sources using Tracer probes.\\n\\\n    <BR>\\n<BR>\\nNote: the public API of this module is not stable, incompatible changes may happen at any time!\nOpenIDE-Module-Name=Tracer-Framework\nOpenIDE-Module-Short-Description=Tracer framework and GUI\n\nACTION_IdeSnapshot_name=L&oad IDE Snapshot...\n\nNpssResolver=Npss Files\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/DetailsView.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl;\n\nimport javax.swing.JComponent;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.details.DetailsPanel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.VisibilityHandler;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.TimelineSupport;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class DetailsView {\n\n    private final TimelineSupport timelineSupport;\n    private DetailsPanel panel;\n\n    private boolean hasData;\n\n    private VisibilityHandler viewHandler;\n\n    // --- Constructor ---------------------------------------------------------\n\n    DetailsView(TracerModel model) {\n        timelineSupport = model.getTimelineSupport();\n    }\n\n\n    // --- Internal interface --------------------------------------------------\n\n    void registerViewListener(VisibilityHandler viewHandler) {\n        if (panel != null) {\n            viewHandler.handle(panel);\n        } else {\n            this.viewHandler = viewHandler;\n        }\n\n    }\n\n    boolean isShowing() {\n        return panel != null && panel.isShowing();\n    }\n\n    boolean hasData() {\n        return hasData;\n    }\n\n\n    // --- UI implementation ---------------------------------------------------\n\n    JComponent getView() {\n        panel = new DetailsPanel(timelineSupport);\n\n        timelineSupport.addSelectionListener(new TimelineSupport.SelectionListener() {\n            public void intervalsSelectionChanged() {}\n            public void indexSelectionChanged() {}\n            public void timeSelectionChanged(boolean timestampsSelected, boolean justHovering) {}\n        });\n\n        if (viewHandler != null) {\n            viewHandler.handle(panel);\n            viewHandler = null;\n        }\n\n        return panel;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/ExportSnapshotAction.java",
    "content": "/*\n * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl;\n\nimport java.awt.Component;\nimport java.awt.event.ActionEvent;\nimport java.io.File;\nimport java.util.Locale;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.JFileChooser;\nimport javax.swing.SwingUtilities;\nimport javax.swing.filechooser.FileFilter;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerLogger;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ExportSnapshotAction_ActionName=Export IDE snapshot...\",\n    \"ExportSnapshotAction_ActionDescr=Export IDE snapshot...\",\n    \"ExportSnapshotAction_ProgressMsg=Exporting snapshot...\",\n    \"ExportSnapshotAction_CannotReplaceMsg=File {0} cannot be replaced.\\nCheck file permissions.\",\n    \"ExportSnapshotAction_ExportFailedMsg=Exporting snapshot failed:\",\n    \"ExportSnapshotAction_FileChooserCaption=Select File or Directory\",\n    \"ExportSnapshotAction_ExportButtonText=Export\",\n    \"ExportSnapshotAction_NpssFileFilter=IDE Snapshots (*{0})\",\n    \"ExportSnapshotAction_ExportToItselfMsg=Exporting the snapshot to itself.\",\n    \"ExportSnapshotAction_OverwriteFileCaption=Overwrite Existing File\",\n    \"ExportSnapshotAction_OverwriteFileMsg=File {0} already exists.\\nDo you want to replace it?\"\n})\nfinal class ExportSnapshotAction extends AbstractAction {\n\n    private static final String NPSS_EXT = \".\"+ResultsManager.STACKTRACES_SNAPSHOT_EXTENSION; // NOI18N\n    private static String LAST_DIRECTORY;\n\n    private final FileObject snapshotFileObject;\n    \n    \n    ExportSnapshotAction(FileObject snapshot) {\n        snapshotFileObject = snapshot;\n        \n        putValue(Action.NAME, Bundle.ExportSnapshotAction_ActionName());\n        putValue(Action.SHORT_DESCRIPTION, Bundle.ExportSnapshotAction_ActionDescr());\n        putValue(Action.SMALL_ICON, Icons.getIcon(GeneralIcons.EXPORT));\n        putValue(\"iconBase\", Icons.getResource(GeneralIcons.EXPORT)); // NOI18N\n    }\n\n    @Override\n    public void actionPerformed(final ActionEvent e) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                JFileChooser chooser = createFileChooser();\n                String filename = snapshotFileObject.getName();\n                File lastDir = LAST_DIRECTORY != null ? new File(LAST_DIRECTORY) :\n                                                        chooser.getCurrentDirectory();\n                chooser.setSelectedFile(new File(lastDir, filename));\n                Component parent = WindowManager.getDefault().getRegistry().getActivated();\n                if (parent == null) parent = WindowManager.getDefault().getMainWindow();\n                if (chooser.showDialog(parent, null) != JFileChooser.APPROVE_OPTION) return;\n                File selected = chooser.getSelectedFile();\n                if (selected.isDirectory()) {\n                    LAST_DIRECTORY = selected.getAbsolutePath();\n                    selected = new File(selected, filename);\n                } else {\n                    LAST_DIRECTORY = selected.getParent();\n                }\n                filename = selected.getName();\n                if (!filename.toLowerCase(Locale.ENGLISH).endsWith(NPSS_EXT)) {\n                    filename+=NPSS_EXT;\n                    selected = new File(selected.getParentFile(), filename);\n                }\n                if (!checkItselfOrOverwrite(snapshotFileObject, selected)) actionPerformed(e);\n                else export(snapshotFileObject, selected);\n            }\n        });\n    }\n    \n    // TODO: export also UI gestures file if available, preferably based on user option\n    private static void export(final FileObject sourceFO, final File targetFile) {\n        final ProgressHandle progress = ProgressHandle.createHandle(\n                Bundle.ExportSnapshotAction_ProgressMsg());\n        progress.setInitialDelay(500);\n        RequestProcessor.getDefault().post(new Runnable() {\n            public void run() {\n                progress.start();\n                try {\n                    if (targetFile.exists() && !targetFile.delete()) {\n                        ProfilerDialogs.displayError(\n                                Bundle.ExportSnapshotAction_CannotReplaceMsg(targetFile.getName()));\n                    } else {\n                        targetFile.toPath();\n                        File targetParent = FileUtil.normalizeFile(targetFile.getParentFile());\n                        FileObject targetFO = FileUtil.toFileObject(targetParent);\n                        String targetName = targetFile.getName();\n                        FileUtil.copyFile(sourceFO, targetFO, targetName, null);\n                    }\n                } catch (Throwable t) {\n                    ProfilerLogger.log(\"Failed to export NPSS snapshot: \" + t.getMessage()); // NOI18N\n                    String msg = t.getLocalizedMessage().replace(\"<\", \"&lt;\").replace(\">\", \"&gt;\"); // NOI18N\n                    ProfilerDialogs.displayError(\"<html><b>\" + Bundle.ExportSnapshotAction_ExportFailedMsg() + // NOI18N\n                                                               \"</b><br><br>\" + msg + \"</html>\"); // NOI18N\n                } finally {\n                    progress.finish();\n                }\n            }\n        });\n    }\n    \n    private static JFileChooser createFileChooser() {\n        JFileChooser fileChooser = new JFileChooser();\n        fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);\n        fileChooser.setMultiSelectionEnabled(false);\n        fileChooser.setDialogTitle(Bundle.ExportSnapshotAction_FileChooserCaption());\n        fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);\n        fileChooser.setApproveButtonText(Bundle.ExportSnapshotAction_ExportButtonText());\n        fileChooser.removeChoosableFileFilter(fileChooser.getAcceptAllFileFilter());\n        fileChooser.addChoosableFileFilter(new FileFilter() {\n            public boolean accept(File f) {\n                return f.isDirectory() || f.getName().toLowerCase(Locale.ENGLISH).endsWith(NPSS_EXT);\n            }\n            public String getDescription() {\n                return Bundle.ExportSnapshotAction_NpssFileFilter(NPSS_EXT);\n            }\n        });\n        return fileChooser;\n    }\n    \n    private static boolean checkItselfOrOverwrite(FileObject sourceFO, File target) {\n        if (!target.exists()) {\n            return true;\n        }\n        File source = FileUtil.toFile(sourceFO);\n        if (source == null) {   // sourceFO is in memory\n            return true;\n        }\n        if (source.equals(target)) {\n            ProfilerDialogs.displayError(Bundle.ExportSnapshotAction_ExportToItselfMsg());\n            return false;\n        } else {\n            return ProfilerDialogs.displayConfirmation(\n                    Bundle.ExportSnapshotAction_OverwriteFileMsg(target.getName()),\n                    Bundle.ExportSnapshotAction_OverwriteFileCaption());\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/IdeSnapshot.java",
    "content": "/*\n * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.logging.LogRecord;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.SampledCPUSnapshot;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.logs.LogReader;\nimport org.openide.filesystems.FileObject;\n\n/** Reads xml log and npss snapshot from file.\n *\n * @author Tomas Hurka\n */\npublic final class IdeSnapshot {\n\n    private final SampledCPUSnapshot cpuSnapshot;\n    private LogReader xmlLogs;\n    private LogRecord lastRecord;\n    private Map<Integer, LogRecord> recordsMap;\n    private Map<Integer, LogRecordInfo> infosMap;\n    private final FileObject npssFileObject;\n\n    public IdeSnapshot(FileObject npssFO, FileObject uigestureFO) throws IOException {\n        cpuSnapshot = new SampledCPUSnapshot(npssFO);\n        npssFileObject = npssFO;\n        if (uigestureFO != null) {\n            xmlLogs = new LogReader(uigestureFO);\n            xmlLogs.load();\n            recordsMap = new HashMap<>();\n            infosMap = new HashMap<>();\n        }\n    }\n\n    int getSamplesCount() {\n        return cpuSnapshot.getSamplesCount();\n    }\n\n    long getTimestamp(int sampleIndex) throws IOException {\n        return cpuSnapshot.getTimestamp(sampleIndex);\n    }\n\n    FileObject getNpssFileObject() {\n        return npssFileObject;\n    }\n\n    public boolean hasUiGestures() {\n        return xmlLogs != null;\n    }\n\n    LoadedSnapshot getCPUSnapshot(int startIndex, int endIndex) throws IOException {\n        return cpuSnapshot.getCPUSnapshot(startIndex, endIndex);\n    }\n\n    public long getValue(int sampleIndex, int valIndex) throws IOException {\n        if (valIndex == 0) {\n            return cpuSnapshot.getValue(sampleIndex, valIndex);\n        } else if (xmlLogs != null) {\n            Integer val = getLogRecordValue(sampleIndex);\n            if (val != null) {\n                return val.intValue();\n            }\n        }\n        return 0;\n    }\n\n    public LogRecordInfo getLogInfoForValue(long loggerValue) {\n        if (xmlLogs == null || loggerValue == 0) {\n            return null;\n        }\n        Integer index = new Integer((int) loggerValue);\n        LogRecordInfo info = infosMap.get(index);\n\n        if (info == null) {\n            LogRecord rec = recordsMap.get(index);\n\n            assert rec != null : \"Null record for value \"+index;        // NOI18N\n            info = new LogRecordInfo(rec);\n            infosMap.put(index, info);\n        }\n        return info;\n    }\n\n    private Integer getLogRecordValue(int sampleIndex) throws IOException {\n        long timestamp = getTimestamp(sampleIndex);\n        LogRecord rec = xmlLogs.getRecordFor(timestamp / 1000000);\n        if (rec != null) {\n            long startTime = cpuSnapshot.getStartTime();\n            long endTime = getTimestamp(getSamplesCount() - 1);\n            long recTime = rec.getMillis() * 1000000;\n            if (recTime > startTime && recTime < endTime) {\n                if (rec != lastRecord) {\n                    Integer index = new Integer(sampleIndex+1);\n                    lastRecord = rec;\n                    recordsMap.put(index, rec);\n                    return index;\n                }\n            }\n        }\n        return null;\n    }\n\n    String getThreadDump(int sampleIndex) throws IOException {\n        return cpuSnapshot.getThreadDump(sampleIndex);\n    }\n\n    List<Integer> getIntervals(int start, int end, PrestimeCPUCCTNode node) throws IOException {\n        return cpuSnapshot.getIntervals(start,end,node);\n    }\n\n    public static final class LogRecordInfo {\n        private static final int MAX_DISPLAY_NAME = 40;\n        \n        private String name;\n        private String displayName;\n        private String toolTip;\n        private Icon icon;\n        private LogRecord record;\n\n        LogRecordInfo(LogRecord rec) {\n            record = rec;\n        }\n\n        void setName(String name) {\n            this.name = name;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        void setDisplayName(String displayName) {\n            this.displayName = displayName;\n        }\n\n        public String getDisplayName() {\n            if (displayName == null) {\n                String message = record.getMessage();\n                \n                if (message != null && !message.isEmpty()) {\n                    StringBuilder sb = new StringBuilder(message);\n                    Object[] arr = record.getParameters();\n                    \n                    if (arr != null && arr.length > 0) {\n                        String sep = \" (\";  // NOI18N\n                        \n                        for (Object par : arr) {\n                            sb.append(sep);\n                            sb.append(par);\n                            sep = \", \";     // NOI18N\n                            if (sb.length() > MAX_DISPLAY_NAME) {\n                                return sb.substring(0,MAX_DISPLAY_NAME).concat(\" ...\"); // NOI18N\n                            }\n                        }\n                        sb.append(\")\");     // NOI18N\n                    }\n                    return sb.toString();\n                }\n            }\n            return displayName;\n        }\n\n        void setToolTip(String toolTip) {\n            this.toolTip = toolTip;\n        }\n\n        public String getToolTip() {\n            return toolTip;\n        }\n\n        void setIcon(Icon icon) {\n            this.icon = icon;\n        }\n\n        public Icon getIcon() {\n            return icon;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/IdeSnapshotAction.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Frame;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.File;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.InputMap;\nimport javax.swing.JComponent;\nimport javax.swing.JFileChooser;\nimport javax.swing.SwingUtilities;\nimport javax.swing.filechooser.FileFilter;\nimport org.graalvm.visualvm.lib.profiler.ProfilerTopComponent;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.TopComponent;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class IdeSnapshotAction implements ActionListener {\n\n    private File lastDirectory;\n\n    public void actionPerformed(ActionEvent e) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                final File file = snapshotFile();\n                if (file == null) return;\n                openSnapshot(FileUtil.toFileObject(file));\n            }\n        });\n    }\n\n    @NbBundle.Messages(\"MSG_SnapshotLoadFailedMsg=Error while loading snapshot {0}:\\n{1}\")\n    static void openSnapshot(final FileObject primary) {\n        TracerSupportImpl.getInstance().perform(new Runnable() {\n            public void run() {\n                try {\n                    FileObject uigestureFO = primary.getParent().getFileObject(primary.getName(), \"log\"); // NOI18N\n                    IdeSnapshot snapshot = new IdeSnapshot(primary, uigestureFO);\n                    openSnapshotImpl(snapshot);\n                } catch (Throwable t) {\n                    ProfilerDialogs.displayError(Bundle.MSG_SnapshotLoadFailedMsg(\n                                                 primary.getNameExt(), t.getLocalizedMessage()));\n                }\n            }\n        });\n    }\n\n    private static void openSnapshotImpl(final IdeSnapshot snapshot) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                TracerModel model = new TracerModel(snapshot);\n                TracerController controller = new TracerController(model);\n                TopComponent ui = ui(model, controller, snapshot.getNpssFileObject());\n                ui.open();\n                ui.requestActive();\n            }\n        });\n    }\n\n    private static TopComponent ui(TracerModel model, TracerController controller, FileObject snapshotFo) {\n        String npssFileName = snapshotFo.getName();\n        TopComponent tc = new IdeSnapshotComponent(npssFileName, FileUtil.toFile(snapshotFo));\n        final JComponent tracer = new TracerView(model, controller).createComponent();\n        tc.add(tracer, BorderLayout.CENTER);\n        \n        InputMap inputMap = tc.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        ActionMap actionMap = tc.getActionMap();\n        \n        final String filterKey = FilterUtils.FILTER_ACTION_KEY;\n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                Action action = tracer.getActionMap().get(filterKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);\n        \n        final String findKey = SearchUtils.FIND_ACTION_KEY;\n        Action findAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                Action action = tracer.getActionMap().get(findKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(findKey, findAction, actionMap, inputMap);\n        \n        return tc;\n    }\n\n    private File snapshotFile() {\n        JFileChooser chooser = createFileChooser(lastDirectory);\n        Frame mainWindow = WindowManager.getDefault().getMainWindow();\n        if (chooser.showOpenDialog(mainWindow) == JFileChooser.APPROVE_OPTION) {\n            lastDirectory = chooser.getCurrentDirectory();\n            return chooser.getSelectedFile();\n        } else {\n            return null;\n        }\n    }\n\n    @NbBundle.Messages({\n        \"ACTION_IdeSnapshot_dialog=Load IDE Snapshot\",\n        \"ACTION_IdeSnapshot_filter=IDE Snapshots\"\n    })\n    private static JFileChooser createFileChooser(File directory) {\n        JFileChooser chooser = new JFileChooser();\n\n        chooser.setDialogTitle(Bundle.ACTION_IdeSnapshot_dialog());\n        chooser.setDialogType(JFileChooser.OPEN_DIALOG);\n        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);\n\n        chooser.setAcceptAllFileFilterUsed(false);\n        if (directory != null) {\n            chooser.setCurrentDirectory(directory);\n        }\n        \n        String descr = Bundle.ACTION_IdeSnapshot_filter();\n        String ext = \".\"+ResultsManager.STACKTRACES_SNAPSHOT_EXTENSION; // NOI18N\n        Filter filter = Filter.create(descr, ext);\n        chooser.addChoosableFileFilter(filter);\n\n        return chooser;\n    }\n\n    private static class IdeSnapshotComponent extends ProfilerTopComponent {\n\n        IdeSnapshotComponent(String displayName, File npssFile) {\n            setDisplayName(displayName);\n            if (npssFile != null) {\n                putClientProperty(ProfilerTopComponent.RECENT_FILE_KEY, npssFile);\n                setToolTipText(npssFile.getAbsolutePath());\n            }\n            setLayout(new BorderLayout());\n        }\n\n        public int getPersistenceType() { return PERSISTENCE_NEVER; }\n\n    }\n\n    private static abstract class Filter extends FileFilter {\n\n        abstract String getExt();\n\n        static Filter create(final String descr, final String ext) {\n            return new Filter() {\n                public boolean accept(File f) {\n                    return f.isDirectory() || getFileExt(f.getName()).equals(ext);\n                }\n                public String getExt() {\n                    return ext;\n                }\n                public String getDescription() {\n                    return descr + \" (*\" + ext + \")\";  // NOI18N\n                }\n            };\n        }\n\n        private static String getFileExt(String fileName) {\n            int extIndex = fileName.lastIndexOf('.'); // NOI18N\n            if (extIndex == -1) return \"\"; // NOI18N\n            return fileName.substring(extIndex);\n        }\n\n        private Filter() {}\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/NpssDataObject.java",
    "content": "/*\n * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl;\n\nimport java.io.IOException;\nimport org.openide.cookies.OpenCookie;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.MIMEResolver;\nimport org.openide.loaders.DataNode;\nimport org.openide.loaders.DataObject;\nimport org.openide.loaders.DataObjectExistsException;\nimport org.openide.loaders.MultiDataObject;\nimport org.openide.loaders.MultiFileLoader;\nimport org.openide.nodes.Children;\nimport org.openide.nodes.Node;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Tomas Hurka\n */\n@MIMEResolver.Registration(displayName=\"#NpssResolver\", position=2033, resource=\"../impl/resources/NpssResolver.xml\")\n@DataObject.Registration(\n    iconBase = \"org/graalvm/visualvm/lib/profiler/snaptracer/impl/icons/snapshotDataObjectCPU.png\",\n    mimeType = \"application/x-netbeans-profiler-npss\"\n)\npublic class NpssDataObject extends MultiDataObject implements OpenCookie {\n\n    public NpssDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {\n        super(pf, loader);\n\n    }\n\n    @Override\n    protected Node createNodeDelegate() {\n        return new DataNode(this, Children.LEAF, getLookup());\n    }\n\n    @Override\n    public Lookup getLookup() {\n        return getCookieSet().getLookup();\n    }\n\n    @Override\n    public void open() {\n        IdeSnapshotAction.openSnapshot(getPrimaryFile());\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/TimelineView.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.ActionEvent;\nimport java.text.Format;\nimport java.text.SimpleDateFormat;\nimport javax.swing.AbstractButton;\nimport javax.swing.Action;\nimport javax.swing.ButtonGroup;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.axis.TimeAxisUtils;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.icons.TracerIcons;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.VisibilityHandler;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.TimelinePanel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.TimelineSupport;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineView {\n\n    private final TracerModel model;\n    private TimelinePanel panel;\n\n    private JButton selectAllButton;\n    private JButton clearTimestampSelectionButton;\n    private JLabel selectionLabel;\n\n    private VisibilityHandler viewHandler;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    TimelineView(TracerModel model) {\n        this.model = model;\n    }\n\n\n    // --- Internal interface --------------------------------------------------\n\n    void reset() {\n        if (panel != null) panel.reset();\n    }\n\n    void resetSelection() {\n        if (panel != null) panel.resetSelection();\n    }\n\n    void updateActions() {\n        if (panel != null) panel.updateActions();\n    }\n\n    Action zoomInAction() {\n        if (panel != null) return panel.zoomInAction();\n        return null;\n    }\n\n    Action zoomOutAction() {\n        if (panel != null) return panel.zoomOutAction();\n        return null;\n    }\n\n    Action toggleViewAction() {\n        if (panel != null) return panel.toggleViewAction();\n        return null;\n    }\n\n    AbstractButton mouseZoom() {\n        if (panel != null) return panel.mouseZoom();\n        return null;\n    }\n\n    AbstractButton mouseHScroll() {\n        if (panel != null) return panel.mouseHScroll();\n        return null;\n    }\n\n    AbstractButton mouseVScroll() {\n        if (panel != null) return panel.mouseVScroll();\n        return null;\n    }\n\n\n    void registerViewListener(VisibilityHandler viewHandler) {\n        if (panel != null) {\n            viewHandler.handle(panel);\n        } else {\n            this.viewHandler = viewHandler;\n        }\n\n    }\n\n    boolean isShowing() {\n        return panel != null && panel.isShowing();\n    }\n\n    // --- UI implementation ---------------------------------------------------\n\n    @NbBundle.Messages({\n        \"TOOLTIP_SelectAll=Select all\",\n        \"TOOLTIP_ClearMarks=Clear marks\"\n    })\n    JComponent getView() {\n        final TimelineSupport support = model.getTimelineSupport();\n        panel = new TimelinePanel(support);\n\n        if (viewHandler != null) {\n            viewHandler.handle(panel);\n            viewHandler = null;\n        }\n        \n        ProfilerToolbar toolbar = ProfilerToolbar.create(true);\n        FileObject npssFo = model.getSnapshot().getNpssFileObject();\n        toolbar.add(new ExportSnapshotAction(npssFo));\n        toolbar.addSeparator();\n        \n        toolbar.add(panel.zoomInAction());\n        toolbar.add(panel.zoomOutAction());\n        toolbar.add(panel.toggleViewAction());\n        toolbar.addSeparator();\n\n        ButtonGroup bg = new ButtonGroup();\n        AbstractButton mz = panel.mouseZoom();\n        bg.add(mz);\n        toolbar.add(mz);\n        AbstractButton mh = panel.mouseHScroll();\n        bg.add(mh);\n        toolbar.add(mh);\n        toolbar.addSeparator();\n\n        selectAllButton = new JButton(Icons.getIcon(TracerIcons.SELECT_ALL)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(support::selectAll);\n            }\n        };\n        selectAllButton.setToolTipText(Bundle.TOOLTIP_SelectAll());\n        toolbar.add(selectAllButton);\n        \n        clearTimestampSelectionButton = new JButton(Icons.getIcon(TracerIcons.MARK_CLEAR)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                SwingUtilities.invokeLater(support::resetSelectedTimestamps);\n            }\n        };\n        clearTimestampSelectionButton.setToolTipText(Bundle.TOOLTIP_ClearMarks());\n        toolbar.add(clearTimestampSelectionButton);\n\n        toolbar.addSeparator();\n        selectionLabel = new JLabel();\n        toolbar.add(selectionLabel);\n\n        JPanel container = new JPanel(new BorderLayout());\n        container.setOpaque(false);\n\n        container.add(toolbar.getComponent(), BorderLayout.NORTH);\n        container.add(panel, BorderLayout.CENTER);\n\n        support.addSelectionListener( new TimelineSupport.SelectionListener() {\n            public void intervalsSelectionChanged() {\n                updateSelectionToolbar();\n            }\n            public void indexSelectionChanged() {\n                updateSelectionToolbar();\n            }\n            public void timeSelectionChanged(boolean timestampsSelected, boolean justHovering) {\n                updateSelectionToolbar();\n            }\n        });\n\n        updateSelectionToolbar();\n\n        return container;\n    }\n\n    private static final Format df = new SimpleDateFormat(TimeAxisUtils.TIME_MSEC);\n\n    @NbBundle.Messages({\n        \"LBL_Selection=Selection:\",\n        \"LBL_None=<none>\",\n        \"LBL_SingleSample=sample #{0}\",\n        \"LBL_TwoSamples=samples #{0} to #{1}\",\n        \"LBL_TwoTimes={0} to {1}\",\n        \"LBL_EntireSnapshot=entire snapshot\"\n    })\n    private void updateSelectionToolbar() {\n        TimelineSupport support = model.getTimelineSupport();\n        selectAllButton.setEnabled(!support.isSelectAll());\n        clearTimestampSelectionButton.setEnabled(support.isTimestampSelection(false));\n        \n        int startIndex = support.getStartIndex();\n        int endIndex = support.getEndIndex();\n        String selection = \" \" + Bundle.LBL_Selection() + \" \";\n        if (startIndex == -1) {\n            selection += Bundle.LBL_None();\n        }  else if (startIndex == endIndex) {\n            selection += df.format(support.getTimestamp(startIndex)) + \", \" + // NOI18N\n                    Bundle.LBL_SingleSample(startIndex);\n        }  else {\n            long startTime = support.getTimestamp(startIndex);\n            long endTime = support.getTimestamp(endIndex);\n            selection += Bundle.LBL_TwoTimes(df.format(startTime), df.format(endTime));\n            selection += \" (\" + (endTime - startTime) + \" ms)\";\n            selection += \", \" + Bundle.LBL_TwoSamples(startIndex, endIndex);\n        }\n\n        if (support.isSelectAll())\n            selection += \", \" + Bundle.LBL_EntireSnapshot();\n        selectionLabel.setText(selection);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/TracerController.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl;\n\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.PackageStateHandler;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ProbeStateHandler;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.SessionInitializationException;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerPackage;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProbe;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProgressObject;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n        \"Warning_NegativeValue=<html><b>One or more probes \"\n        + \"returned negative value.</b><br><br>Currently this is \"\n        + \"not supported in Tracer,<br>all negative values will be\"\n        + \" displayed as 0.</html>\"\n    })\npublic final class TracerController  {\n\n    private static final Logger LOGGER = Logger.getLogger(TracerController.class.getName());\n\n    private static final String PROPERTY_STATE = \"state\"; // NOI18N\n    static final int STATE_SESSION_INACTIVE = 0;\n    static final int STATE_SESSION_RUNNING = 1;\n    static final int STATE_SESSION_IMPOSSIBLE = -1;\n    static final int STATE_SESSION_STARTING = Integer.MAX_VALUE;\n    static final int STATE_SESSION_STOPPING = Integer.MIN_VALUE;\n\n    private final TracerModel model;\n\n    private final PropertyChangeSupport changeSupport;\n    private int state;\n\n    private TracerProgressObject progress;\n    private String error;\n    private boolean wasNegativeValue;\n\n    private RequestProcessor processor;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    public TracerController(TracerModel model) {\n        this.model = model;\n\n        changeSupport = new PropertyChangeSupport(this);\n        state = STATE_SESSION_INACTIVE;\n    }\n\n\n    // --- Session & probes state ----------------------------------------------\n\n    private void setState(final int state) {\n        Runnable stateSetter = new Runnable() {\n            public void run() {\n                if (TracerController.this.state == STATE_SESSION_IMPOSSIBLE) return;\n                int oldState = TracerController.this.state;\n                TracerController.this.state = state;\n                changeSupport.firePropertyChange(PROPERTY_STATE, oldState, state);\n            }\n        };\n        if (SwingUtilities.isEventDispatchThread()) stateSetter.run();\n        else SwingUtilities.invokeLater(stateSetter);\n    }\n\n    int getState() {\n        return state;\n    }\n\n    TracerProgressObject getProgress() {\n        return progress;\n    }\n\n    String getErrorMessage() {\n        return error;\n    }\n\n    void addListener(PropertyChangeListener listener) {\n        if (changeSupport != null && state != STATE_SESSION_IMPOSSIBLE)\n            changeSupport.addPropertyChangeListener(PROPERTY_STATE, listener);\n    }\n\n    void removeListener(PropertyChangeListener listener) {\n        if (changeSupport != null)\n            changeSupport.removePropertyChangeListener(PROPERTY_STATE, listener);\n    }\n\n\n    // --- Session control -----------------------------------------------------\n    \n    void performSession() {\n        startSession();\n        doPerformSession();\n        stopSession();\n    }\n\n    void performAfterSession(Runnable task) {\n        getProcessor().post(task);\n    }\n\n    private void startSession() {\n        if (!model.areProbesDefined()) return;\n        if (doStartSession()) setState(STATE_SESSION_RUNNING);\n        else setState(STATE_SESSION_INACTIVE);\n    }\n\n    private void stopSession() {\n        if (state == STATE_SESSION_RUNNING) setState(STATE_SESSION_STOPPING);\n        doStopSession();\n        setState(STATE_SESSION_INACTIVE);\n    }\n\n    private boolean doStartSession() {\n        wasNegativeValue = false;\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { model.getTimelineSupport().resetValues(); }\n        });\n        Set<Map.Entry<TracerPackage, List<TracerProbe>>> toNotify =\n                model.getDefinedProbeSets();\n        notifySessionInitializing(toNotify);\n        setState(STATE_SESSION_STARTING);\n        if (!notifySessionStarting(toNotify)) return false;\n        notifySessionRunning(toNotify);\n        return true;\n    }\n    \n    private void doPerformSession() {\n        int samples = model.getSamplesCount();\n        for (int i = 0; i < samples; i++) fetchData(i);\n    }\n\n    private void doStopSession() {\n        Set<Map.Entry<TracerPackage, List<TracerProbe>>> toNotify =\n                model.getDefinedProbeSets();\n        notifySessionStopping(toNotify);\n        notifySessionFinished(toNotify);\n    }\n\n    private void notifySessionInitializing(Set<Map.Entry<TracerPackage, List<TracerProbe>>> items) {\n        List<TracerProgressObject> progresses = new ArrayList<>();\n        int steps = 0;\n        for (Map.Entry<TracerPackage, List<TracerProbe>> item : items) {\n            List<TracerProbe> probes = item.getValue();\n            TracerProbe[] probesArr = probes.toArray(new TracerProbe[0]);\n\n            PackageStateHandler ph = item.getKey().getStateHandler();\n            if (ph != null) try {\n                TracerProgressObject c = ph.sessionInitializing(probesArr, null, -1);\n                if (c != null) {\n                    steps += c.getSteps();\n                    progresses.add(c);\n                }\n            } catch (Throwable t) {\n                LOGGER.log(Level.INFO, \"Package exception in sessionInitializing\", t); // NOI18N\n            }\n\n            for (TracerProbe probe : probes) {\n                ProbeStateHandler rh = probe.getStateHandler();\n                if (rh != null) try {\n                    TracerProgressObject c = rh.sessionInitializing(null, -1);\n                    if (c != null) {\n                        steps += c.getSteps();\n                        progresses.add(c);\n                    }\n                } catch (Throwable t) {\n                    LOGGER.log(Level.INFO, \"Probe exception in sessionInitializing\", t); // NOI18N\n                }\n            }\n        }\n        if (steps == 0) {\n            progress = null;\n        } else {\n            progress = new TracerProgressObject(steps, \"Starting session...\");\n            TracerProgressObject.Listener l = new TracerProgressObject.Listener() {\n                public void progressChanged(int addedSteps, int currentStep, String text) {\n                    progress.addSteps(addedSteps, text);\n                }\n            };\n            for (TracerProgressObject o : progresses) o.addListener(l);\n        }\n        error = null;\n    }\n\n    private boolean notifySessionStarting(Set<Map.Entry<TracerPackage, List<TracerProbe>>> items) {\n        Iterator<Map.Entry<TracerPackage, List<TracerProbe>>> itemsI = items.iterator();\n        Map<TracerPackage, List<TracerProbe>> notifiedItems = new HashMap<>();\n        String notifiedName = null;\n        try {\n            while (itemsI.hasNext()) {\n                Map.Entry<TracerPackage, List<TracerProbe>> item = itemsI.next();\n                TracerPackage pkg = item.getKey();\n                notifiedName = pkg.getName();\n                List<TracerProbe> probes = item.getValue();\n                TracerProbe[] probesArr = probes.toArray(new TracerProbe[0]);\n\n                PackageStateHandler ph = pkg.getStateHandler();\n                if (ph != null) ph.sessionStarting(probesArr, null);\n                List<TracerProbe> notifiedList = new ArrayList<>();\n                notifiedItems.put(pkg, notifiedList);\n\n                for (TracerProbe probe : probes) {\n                    notifiedName = model.getDescriptor(probe).getProbeName();\n                    ProbeStateHandler rh = probe.getStateHandler();\n                    if (rh != null) rh.sessionStarting(null);\n                    notifiedList.add(probe);\n                }\n            }\n            return true;\n        } catch (SessionInitializationException sie) {\n            // TODO: update UI\n            LOGGER.log(Level.INFO, \"Package or probe failed to start Tracer session\", sie); // NOI18N\n            error = sie.getUserMessage();\n            if (error == null) error = notifiedName + \" failed to start\";\n\n            Set<Map.Entry<TracerPackage, List<TracerProbe>>> notifiedItemsE =\n                    notifiedItems.entrySet();\n            notifySessionStopping(notifiedItemsE);\n            setState(STATE_SESSION_STOPPING);\n            notifySessionFinished(notifiedItemsE);\n\n            return false;\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Package or probe exception in sessionStarting\", t); // NOI18N\n            return true;\n            // TODO: ignore or terminate the session as for the SessionInitializationException?\n        }\n    }\n\n    private void notifySessionRunning(Set<Map.Entry<TracerPackage, List<TracerProbe>>> items) {\n        for (Map.Entry<TracerPackage, List<TracerProbe>> item : items) {\n            List<TracerProbe> probes = item.getValue();\n            TracerProbe[] probesArr = probes.toArray(new TracerProbe[0]);\n\n            PackageStateHandler ph = item.getKey().getStateHandler();\n            if (ph != null) try {\n                ph.sessionRunning(probesArr, null);\n            } catch (Throwable t) {\n                LOGGER.log(Level.INFO, \"Package exception in sessionRunning\", t); // NOI18N\n            }\n\n            for (TracerProbe probe : probes) {\n                ProbeStateHandler rh = probe.getStateHandler();\n                if (rh != null) try {\n                    rh.sessionRunning(null);\n                } catch (Throwable t) {\n                    LOGGER.log(Level.INFO, \"Probe exception in sessionRunning\", t); // NOI18N\n                }\n            }\n        }\n    }\n\n    private void notifySessionStopping(Set<Map.Entry<TracerPackage, List<TracerProbe>>> items) {\n        for (Map.Entry<TracerPackage, List<TracerProbe>> item : items) {\n            List<TracerProbe> probes = item.getValue();\n            TracerProbe[] probesArr = probes.toArray(new TracerProbe[0]);\n\n            PackageStateHandler ph = item.getKey().getStateHandler();\n            if (ph != null) try {\n                ph.sessionStopping(probesArr, null);\n            } catch (Throwable t) {\n                LOGGER.log(Level.INFO, \"Package exception in sessionStopping\", t); // NOI18N\n            }\n\n            for (TracerProbe probe : probes) {\n                ProbeStateHandler rh = probe.getStateHandler();\n                if (rh != null) try {\n                    rh.sessionStopping(null);\n                } catch (Throwable t) {\n                    LOGGER.log(Level.INFO, \"Probe exception in sessionStopping\", t); // NOI18N\n                }\n            }\n        }\n    }\n\n    private void notifySessionFinished(Set<Map.Entry<TracerPackage, List<TracerProbe>>> items) {\n        for (Map.Entry<TracerPackage, List<TracerProbe>> item : items) {\n            List<TracerProbe> probes = item.getValue();\n            TracerProbe[] probesArr = probes.toArray(new TracerProbe[0]);\n\n            PackageStateHandler ph = item.getKey().getStateHandler();\n            if (ph != null) try {\n                ph.sessionFinished(probesArr, null);\n            } catch (Throwable t) {\n                LOGGER.log(Level.INFO, \"Package exception in sessionFinished\", t); // NOI18N\n            }\n\n            for (TracerProbe probe : probes) {\n                ProbeStateHandler rh = probe.getStateHandler();\n                if (rh != null) try {\n                    rh.sessionFinished(null);\n                } catch (Throwable t) {\n                    LOGGER.log(Level.INFO, \"Probe exception in sessionFinished\", t); // NOI18N\n                }\n            }\n        }\n    }\n\n    private void notifyRefreshRateChanged(Set<Map.Entry<TracerPackage, List<TracerProbe>>> items) {\n        for (Map.Entry<TracerPackage, List<TracerProbe>> item : items) {\n            List<TracerProbe> probes = item.getValue();\n            TracerProbe[] probesArr = probes.toArray(new TracerProbe[0]);\n\n            PackageStateHandler ph = item.getKey().getStateHandler();\n            if (ph != null) try {\n                ph.refreshRateChanged(probesArr, null, -1);\n            } catch (Throwable t) {\n                LOGGER.log(Level.INFO, \"Package exception in refreshRateChanged\", t); // NOI18N\n            }\n\n            for (TracerProbe probe : probes) {\n                ProbeStateHandler rh = probe.getStateHandler();\n                if (rh != null) try {\n                    rh.refreshRateChanged(null, -1);\n                } catch (Throwable t) {\n                    LOGGER.log(Level.INFO, \"Probe exception in refreshRateChanged\", t); // NOI18N\n                }\n            }\n        }\n    }\n\n\n    // --- Session runtime -----------------------------------------------------\n\n    private synchronized RequestProcessor getProcessor() {\n        if (processor == null)\n            processor = new RequestProcessor(\"Tracer Processor for \" + model.getSnapshot().toString()); // NOI18N\n        return processor;\n    }\n    \n    private void fetchData(final int sampleIndex) {\n        \n        final List<TracerProbe> probes = model.getDefinedProbes();\n        if (probes.isEmpty()) return;\n        \n        final int itemsCount = model.getTimelineSupport().getItemsCount();\n        getProcessor().post(new Runnable() {\n            public void run() { fetchDataImpl(probes, itemsCount, sampleIndex); }\n        });\n    }\n\n    private void fetchDataImpl(List<TracerProbe> probes, int itemsCount, int sampleIndex) {\n\n        final long[] values = new long[itemsCount];\n        int currentIndex = 0;\n\n        final long timestamp = model.getTimestamp(sampleIndex);\n        \n        for (TracerProbe probe : probes) {\n            long[] itemValues;\n            try {\n                itemValues = probe.getItemValues(sampleIndex);\n            } catch (Throwable t) {\n                itemValues = new long[probe.getItemsCount()];\n                Arrays.fill(itemValues, ProbeItemDescriptor.VALUE_UNDEFINED);\n                LOGGER.log(Level.INFO, \"Probe exception in getItemValues\", t); // NOI18N\n            }\n            for (long value : itemValues) {\n                if (value < 0) {\n                    if (!wasNegativeValue) {\n                        ProfilerDialogs.displayWarning(Bundle.Warning_NegativeValue());\n                        LOGGER.info(\"Probe \" + model.getDescriptor(probe).getProbeName() + // NOI18N\n                                \" returned negative value: \" + value); // NOI18N\n                        wasNegativeValue = true;\n                    }\n                    value = 0;\n                }\n                values[currentIndex++] = value;\n            }\n        }\n\n\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                \n                model.getTimelineSupport().addValues(timestamp, values);\n            }\n        });\n\n    }\n\n\n    // --- DataSource & DataSourceView lifecycle -------------------------------\n\n    void viewRemoved() {\n        stopSession();\n        setState(STATE_SESSION_IMPOSSIBLE);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/TracerModel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.Set;\nimport java.util.TreeSet;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.PackageStateHandler;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.Positionable;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ProbeStateHandler;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerPackage;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProbe;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.TimelineSupport;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class TracerModel {\n\n    private static final Logger LOGGER = Logger.getLogger(TracerController.class.getName());\n\n    private final IdeSnapshot snapshot;\n\n    private final Map<TracerPackage, List<TracerProbe>> probesCache = new HashMap<>();\n    private final Map<TracerProbe, TracerProbeDescriptor> descriptorsCache = new HashMap<>();\n\n    private final Set<Listener> listeners = new HashSet<>();\n\n    private final TimelineSupport timelineSupport;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    public TracerModel(IdeSnapshot snapshot) {\n        this.snapshot = snapshot;\n        timelineSupport = new TimelineSupport(TracerModel.this::getDescriptor, snapshot);\n    }\n\n\n    // --- DataSource ----------------------------------------------------------\n\n    IdeSnapshot getSnapshot() {\n        return snapshot;\n    }\n    \n    int getSamplesCount() {\n        return snapshot.getSamplesCount();\n    }\n\n    long firstTimestamp() {\n        return getTimestamp(0);\n    }\n\n    long lastTimestamp() {\n        return getTimestamp(getSamplesCount() - 1);\n    }\n\n    long getTimestamp(int sampleIndex) {\n        try {\n            return snapshot.getTimestamp(sampleIndex) / 1000000;\n        } catch (IOException ex) {\n            Exceptions.printStackTrace(ex);\n            return -1;\n        }\n    }\n\n\n    // --- Packages ------------------------------------------------------------\n\n    List<TracerPackage> getPackages() {\n        try {\n            return TracerSupportImpl.getInstance().getPackages(snapshot);\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Package exception in getPackages\", t); // NOI18N\n            return null;\n        }\n    }\n\n\n    // --- Probes --------------------------------------------------------------\n\n    void addDescriptor(final TracerPackage p,\n                       final TracerProbeDescriptor d) {\n        TracerSupportImpl.getInstance().perform(new Runnable() {\n            public void run() { addProbe(p, d); }\n        });\n    }\n\n    void removeDescriptor(final TracerPackage p,\n                          final TracerProbeDescriptor d) {\n        TracerSupportImpl.getInstance().perform(new Runnable() {\n            public void run() { removeProbe(p, d); }\n        });\n    }\n    \n    void addDescriptors(final TracerPackage p,\n                       final TracerProbeDescriptor[] da) {\n        for (TracerProbeDescriptor d : da) addProbe(p, d);\n    }\n\n    void removeDescriptors(final TracerPackage p,\n                          final TracerProbeDescriptor[] da) {\n        for (TracerProbeDescriptor d : da) removeProbe(p, d);\n    }\n\n    TracerProbeDescriptor getDescriptor(TracerProbe p) {\n        synchronized(descriptorsCache) {\n            return descriptorsCache.get(p);\n        }\n    }\n\n    // Must be called in EDT\n    List<TracerProbe> getDefinedProbes() {\n        List<TracerProbe> probes = new ArrayList<>();\n        probes.addAll(timelineSupport.getProbes());\n        return probes;\n    }\n\n    Set<Map.Entry<TracerPackage, List<TracerProbe>>> getDefinedProbeSets() {\n        Comparator<Map.Entry<TracerPackage, List<TracerProbe>>> comp =\n                new Comparator<Map.Entry<TracerPackage, List<TracerProbe>>>() {\n            public int compare(Entry<TracerPackage, List<TracerProbe>> o1,\n                               Entry<TracerPackage, List<TracerProbe>> o2) {\n                return Positionable.STRONG_COMPARATOR.compare(o1.getKey(), o2.getKey());\n            }\n        };\n        Set<Map.Entry<TracerPackage, List<TracerProbe>>> probes = new TreeSet<>(comp);\n        synchronized(probesCache) { probes.addAll(probesCache.entrySet()); }\n        return probes;\n    }\n\n    boolean areProbesDefined() {\n        synchronized(probesCache) { return !probesCache.isEmpty(); }\n    }\n\n\n    private void addProbe(TracerPackage p, TracerProbeDescriptor d) {\n        TracerProbe r = p.getProbe(d);\n        synchronized(descriptorsCache) {\n            descriptorsCache.put(r, d);\n        }\n        synchronized(probesCache) {\n            List<TracerProbe> probes = probesCache.computeIfAbsent(p, k -> new ArrayList<>());\n            probes.add(r);\n        }\n\n        timelineSupport.addProbe(r);\n\n        notifyProbeAdded(p, r);\n        fireProbeAdded(r);\n    }\n\n    private void removeProbe(TracerPackage p, TracerProbeDescriptor d) {\n        TracerProbe probe = null;\n        boolean probesDefined = true;\n\n        synchronized(descriptorsCache) {\n            for (Map.Entry<TracerProbe, TracerProbeDescriptor> entry : descriptorsCache.entrySet()) {\n                if (entry.getValue() == d) {\n                    probe = entry.getKey();\n                    break;\n                }\n            }\n            descriptorsCache.remove(probe);\n        }\n        synchronized(probesCache) {\n            List<TracerProbe> probes = probesCache.get(p);\n            probes.remove(probe);\n            if (probes.isEmpty()) {\n                probesCache.remove(p);\n                probesDefined = !probesCache.isEmpty();\n            }\n        }\n\n        timelineSupport.removeProbe(probe);\n\n        notifyProbeRemoved(p, probe);\n        fireProbeRemoved(probe, probesDefined);\n    }\n\n    private void notifyProbeAdded(TracerPackage p, TracerProbe r) {\n        PackageStateHandler ph = p.getStateHandler();\n        if (ph != null) try {\n            ph.probeAdded(r, snapshot);\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Package exception in probeAdded\", t); // NOI18N\n        }\n\n        ProbeStateHandler rh = r.getStateHandler();\n        if (rh != null) try {\n            rh.probeAdded(snapshot);\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Probe exception in probeAdded\", t); // NOI18N\n        }\n    }\n\n    private void notifyProbeRemoved(TracerPackage p, TracerProbe r) {\n        PackageStateHandler ph = p.getStateHandler();\n        if (ph != null) try {\n            ph.probeRemoved(r, snapshot);\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Package exception in probeRemoved\", t); // NOI18N\n        }\n\n        ProbeStateHandler rh = r.getStateHandler();\n        if (rh != null) try {\n            rh.probeRemoved(snapshot);\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"Probe exception in probeRemoved\", t); // NOI18N\n        }\n    }\n\n\n    // --- Events support ------------------------------------------------------\n\n    void addListener(Listener listener) {\n        synchronized(listeners) { listeners.add(listener); }\n    }\n\n    void removeListener(Listener listener) {\n        synchronized(listeners) { listeners.remove(listener); }\n    }\n\n    private void fireProbeAdded(final TracerProbe probe) {\n        final Set<Listener> toNotify = new HashSet<>();\n        synchronized(listeners) { toNotify.addAll(listeners); }\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                for (Listener listener : toNotify)\n                    listener.probeAdded(probe);\n            }\n        });\n        \n    }\n\n    private void fireProbeRemoved(final TracerProbe probe, final boolean probesDefined) {\n        final Set<Listener> toNotify = new HashSet<>();\n        synchronized(listeners) { toNotify.addAll(listeners); }\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                for (Listener listener : toNotify)\n                    listener.probeRemoved(probe, probesDefined);\n            }\n        });\n    }\n\n    static interface Listener {\n\n        public void probeAdded(TracerProbe probe);\n\n        public void probeRemoved(TracerProbe probe, boolean probesDefined);\n\n    }\n\n\n    // --- Timeline ------------------------------------------------------------\n\n    TimelineSupport getTimelineSupport() {\n        return timelineSupport;\n    }\n\n    List<Integer> getIntervals(PrestimeCPUCCTNode node) throws IOException {\n        TimelineSupport support = getTimelineSupport();\n        final int startIndex = Math.min(support.getStartIndex(), support.getEndIndex());\n        final int endIndex = Math.max(support.getStartIndex(), support.getEndIndex());\n        \n        return getSnapshot().getIntervals(startIndex,endIndex,node);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/TracerSupportImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.Positionable;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerPackage;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerPackageProvider;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.packages.TestPackageProvider;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class TracerSupportImpl {\n\n    private static TracerSupportImpl INSTANCE;\n    private static RequestProcessor PROCESSOR;\n\n    private final Set<TracerPackageProvider> providers;\n\n\n    public static synchronized TracerSupportImpl getInstance() {\n        if (INSTANCE == null) {\n            INSTANCE = new TracerSupportImpl();\n            PROCESSOR = new RequestProcessor(\"Tracer Processor\", 5); // NOI18N\n        }\n        return INSTANCE;\n    }\n\n\n    public synchronized void registerPackageProvider(TracerPackageProvider provider) {\n        providers.add(provider);\n    }\n\n    public synchronized void unregisterPackageProvider(TracerPackageProvider provider) {\n        providers.remove(provider);\n    }\n\n\n    public synchronized boolean hasPackages(Object target) {\n        for (TracerPackageProvider provider : providers)\n            if (provider.getScope().isInstance(target))\n                return true;\n        return false;\n    }\n\n    public synchronized List<TracerPackage> getPackages(IdeSnapshot snapshot) {\n        List<TracerPackage> packages = new ArrayList<>();\n        for (TracerPackageProvider provider : providers)\n            packages.addAll(Arrays.asList(provider.getPackages(snapshot)));\n        packages.sort(Positionable.COMPARATOR);\n        return packages;\n    }\n    \n    \n    public void perform(Runnable task) {\n        PROCESSOR.post(task);\n    }\n\n\n    private TracerSupportImpl() {\n        providers = new HashSet<>();\n        registerPackageProvider(new TestPackageProvider());\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/TracerView.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.KeyAdapter;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseMotionAdapter;\nimport java.io.IOException;\nimport java.net.URL;\nimport java.util.Iterator;\nimport java.util.List;\nimport javax.swing.*;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.PrestimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.SampledCPUSnapshot;\nimport org.graalvm.visualvm.lib.profiler.actions.CompareSnapshotsAction;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerPackage;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.TimelineSupport;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerFeature;\nimport org.graalvm.visualvm.lib.profiler.v2.ProfilerSession;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextAreaSearchUtils;\nimport org.graalvm.visualvm.lib.ui.cpu.SnapshotCPUView;\nimport org.graalvm.visualvm.lib.ui.results.DataView;\nimport org.graalvm.visualvm.lib.ui.swing.ExportUtils;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.lookup.Lookups;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic final class TracerView {\n    \n    private final TracerModel model;\n    private final TracerController controller;\n    private LoadedSnapshot lsF;\n    private TimelineView timelineView;\n    private SnapshotView snapshotView;\n    \n    public TracerView(TracerModel model, TracerController controller) {\n        this.model = model;\n        this.controller = controller;\n    }\n\n    public JComponent createComponent() {\n        \n        final JPanel component = new JPanel(new BorderLayout());\n        component.setOpaque(false);\n\n        // create timeline support\n        timelineView = new TimelineView(model);\n        JPanel timelinePanel = new JPanel(new BorderLayout());\n        timelinePanel.setOpaque(false);\n        timelinePanel.add(timelineView.getView(), BorderLayout.CENTER);\n        timelinePanel.add(new JSeparator(), BorderLayout.SOUTH);\n        \n        // add the timeline component to the UI\n        final JPanel container = new JPanel(null) {\n            public void doLayout() {\n                Component[] components = getComponents();\n                for (Component component : components)\n                    component.setBounds(0, 0, getWidth(), getHeight());\n            }\n            public Dimension getPreferredSize() {\n                return getComponent(getComponentCount() - 1).getPreferredSize();\n            }\n            public Dimension getMinimumSize() {\n                return getComponent(getComponentCount() - 1).getMinimumSize();\n            }\n            public Dimension getMaximumSize() {\n                return getComponent(getComponentCount() - 1).getMaximumSize();\n            }\n            public boolean isOptimizedDrawingEnabled() {\n                return false;\n            }\n        };\n        JPanel glass = new JPanel(null);\n        glass.setOpaque(false);\n        glass.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));\n        glass.addMouseListener(new MouseAdapter() {});\n        glass.addMouseMotionListener(new MouseMotionAdapter() {});\n        glass.addKeyListener(new KeyAdapter() {});\n        container.add(glass); // Consumes event\n        container.add(timelinePanel);\n        \n        component.add(container, BorderLayout.NORTH);\n\n        TracerSupportImpl.getInstance().perform(new Runnable() {\n            public void run() {\n                // add all registered probes to the timeline\n                initProbes();\n                // setup the timeline - zoom according to snapshot data\n                initTimeline();\n                // load the probes data\n                initData(component, container);\n                // init required listeners - timeline selection\n                initListeners(component);\n            }\n        });\n        \n        ActionMap map = component.getActionMap();\n        \n        map.put(FilterUtils.FILTER_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                if (snapshotView != null && snapshotView.isShowing())\n                    snapshotView.getActionMap().get(FilterUtils.FILTER_ACTION_KEY).actionPerformed(e);\n            }\n        });\n        \n        map.put(SearchUtils.FIND_ACTION_KEY, new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                if (snapshotView != null && snapshotView.isShowing())\n                    snapshotView.getActionMap().get(SearchUtils.FIND_ACTION_KEY).actionPerformed(e);\n            }\n        });\n\n        return component;\n    }\n    \n    private void initProbes() {\n        List<TracerPackage> packages =\n            TracerSupportImpl.getInstance().getPackages(model.getSnapshot());\n        for (TracerPackage p : packages)\n            model.addDescriptors(p, p.getProbeDescriptors());\n    }\n\n    private void initTimeline() {\n        TimelineSupport support = model.getTimelineSupport();\n        long start = model.firstTimestamp();\n        if (start == -1) return;\n        long end = model.lastTimestamp();\n        if (end == -1) return;\n        support.dataLoadingStarted(end - start);\n    }\n\n    @NbBundle.Messages(\"MSG_LoadingSnapshot=Loading snapshot...\")\n    private void initData(final JPanel component, final JPanel container) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                JLabel progress = new JLabel(Bundle.MSG_LoadingSnapshot(), JLabel.CENTER);\n                progress.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));\n                addContents(component, progress);\n\n                TracerSupportImpl.getInstance().perform(new Runnable() {\n                    public void run() {\n                        controller.performSession();\n                        controller.performAfterSession(new Runnable() {\n                            public void run() {\n                                TimelineSupport support = model.getTimelineSupport();\n                                support.dataLoadingFinished();\n                                support.selectAll();\n\n                                SwingUtilities.invokeLater(new Runnable() {\n                                    public void run() {\n                                        timelineView.updateActions();\n                                    }\n                                });\n\n                                 // Enable events for timeline\n                                component.remove(container);\n                                component.add(container.getComponent(1), BorderLayout.NORTH);\n                                component.revalidate();\n                                component.repaint();\n                            }\n                        });\n                    }\n                });\n            }\n        });\n    }\n\n    @NbBundle.Messages(\"MSG_ProcessingSelection=Processing selection...\")\n    private void initListeners(final JPanel component) {\n        final TimelineSupport support = model.getTimelineSupport();\n        support.addSelectionListener(\n                new TimelineSupport.SelectionListener() {\n            public void intervalsSelectionChanged() {}\n            public void indexSelectionChanged() {\n                final int startIndex = Math.min(support.getStartIndex(), support.getEndIndex());\n                final int endIndex = Math.max(support.getStartIndex(), support.getEndIndex());\n                JLabel progress = new JLabel(Bundle.MSG_ProcessingSelection(), JLabel.CENTER); // NOI18N\n                addContents(component, progress);\n\n                controller.performAfterSession(new Runnable() {\n                    public void run() {\n                        if (startIndex == endIndex) displayThreadDump(component, startIndex);\n                        else displaySnapshot(component, startIndex, endIndex);\n                    }\n                });\n            }\n\n            public void timeSelectionChanged(boolean timestampsSelected,\n                                             boolean justHovering) {}\n        });\n    }\n    \n    private void displaySnapshot(final JPanel p, final int s1, final int s2) {\n        LoadedSnapshot ls = null;\n        try {\n            ls = model.getSnapshot().getCPUSnapshot(s1, s2);\n        } catch (IOException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n\n        lsF = ls;\n\n        if (lsF != null) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    CPUResultsSnapshot s = (CPUResultsSnapshot)lsF.getSnapshot();\n                    if (snapshotView == null) {\n                        CompareSnapshotsAction aCompare = new CompareSnapshotsAction(lsF);\n                        ResultsManager.SnapshotHandle handle = new ResultsManager.SnapshotHandle() {\n                            public LoadedSnapshot getSnapshot() { return lsF; }\n                        };\n                        ExportUtils.Exportable exporter = ResultsManager.getDefault().createSnapshotExporter(handle);\n                        snapshotView = new SnapshotView(s, aCompare, exporter);\n                        aCompare.setPerformer(new CompareSnapshotsAction.Performer() {\n                            public void compare(LoadedSnapshot snapshot) {\n                                snapshotView.setRefSnapshot((CPUResultsSnapshot)snapshot.getSnapshot());\n                            }\n                        });\n                    } else {\n                        snapshotView.setData(s);\n                    }\n                    addContents(p, snapshotView);\n                }\n            });\n        }\n    }\n\n    private void displayThreadDump(final JPanel p, final int s) {\n        String td = null;\n        try {\n            td = model.getSnapshot().getThreadDump(s);\n        } catch (IOException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n\n        final String tdF = td;\n\n        if (tdF != null) {\n            lsF = null;\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    HTMLTextArea a = new HTMLTextArea(tdF) {\n                        protected void showURL(URL url) {\n                            if (url == null) return;\n                            String urls = url.toString();\n                            TracerView.this.showURL(urls);\n                        }\n                    };\n                    a.setCaretPosition(0);\n                    JScrollPane sp = new JScrollPane(a);\n                    sp.setBorder(BorderFactory.createEmptyBorder());\n                    sp.setViewportBorder(BorderFactory.createEmptyBorder());\n                    JPanel pp = new JPanel(new BorderLayout());\n                    pp.add(sp, BorderLayout.CENTER);\n                    pp.add(HTMLTextAreaSearchUtils.createSearchPanel(a), BorderLayout.SOUTH);\n                    addContents(p, pp);\n                }\n            });\n        }\n    }\n\n    private void addContents(JComponent container, JComponent contents) {\n        BorderLayout layout = (BorderLayout)container.getLayout();\n        Component oldContents = layout.getLayoutComponent(BorderLayout.CENTER);\n        if (oldContents != contents) {\n            if (oldContents != null) container.remove(oldContents);\n            container.add(contents, BorderLayout.CENTER);\n            contents.requestFocusInWindow();\n            container.revalidate();\n            container.repaint();\n        }\n    }\n\n    void showURL(String urls) {\n        if (urls.startsWith(SampledCPUSnapshot.OPEN_THREADS_URL)) {\n            urls = urls.substring(SampledCPUSnapshot.OPEN_THREADS_URL.length());\n            String parts[] = urls.split(\"\\\\|\"); // NOI18N\n            String className = parts[0];\n            String method = parts[1];\n            int linenumber = Integer.parseInt(parts[2]);\n            GoToSource.openSource(null, className, method, linenumber);\n        }\n    }\n    \n    private final class SnapshotView extends SnapshotCPUView {\n        \n        SnapshotView(CPUResultsSnapshot snapshot, Action compare, ExportUtils.Exportable exporter) {\n            super(snapshot, true, null, compare, null, exporter);\n        }\n        \n        void setData(CPUResultsSnapshot snapshot) {\n            super.setSnapshot(snapshot, true);\n        }\n        \n        protected boolean profileMethodEnabled() {\n            return false;\n        }\n        \n        protected boolean profileMethodSupported() {\n            return ProfilerFeature.Registry.hasProviders();\n        }\n    \n        protected boolean profileClassSupported() {\n            return ProfilerFeature.Registry.hasProviders();\n        }\n\n        protected boolean showSourceSupported() {\n            return GoToSource.isAvailable();\n        }\n        \n        protected void showSource(ClientUtils.SourceCodeSelection value) {\n            String className = value.getClassName();\n            String methodName = value.getMethodName();\n            String methodSig = value.getMethodSignature();\n            GoToSource.openSource(null, className, methodName, methodSig);\n        }\n        \n        @NbBundle.Messages({\n            \"LBL_ProfileClass=Profile Class\",\n            \"LBL_ProfileMethod=Profile Method\"                \n        })\n        protected void selectForProfiling(final ClientUtils.SourceCodeSelection value) {\n            RequestProcessor.getDefault().post(new Runnable() {\n                public void run() {\n                    String name = Wildcards.ALLWILDCARD.equals(value.getMethodName()) ?\n                                  Bundle.LBL_ProfileClass() : Bundle.LBL_ProfileMethod();\n                    ProfilerSession.findAndConfigure(Lookups.fixed(value), null, name);\n                }\n            });\n        }\n        \n        protected void customizeNodePopup(DataView invoker, JPopupMenu popup, Object value, ClientUtils.SourceCodeSelection userValue) {\n            if (value instanceof PrestimeCPUCCTNode) {\n                popup.add(new FindMethodAction((PrestimeCPUCCTNode)value));\n                popup.addSeparator();\n            }\n        }\n        \n    }\n    \n    private class FindMethodAction extends AbstractAction {\n        \n        private final PrestimeCPUCCTNode node;\n        \n        @NbBundle.Messages(\"LBL_FindMethod=Select Intervals\")\n        private FindMethodAction(PrestimeCPUCCTNode node) {\n            super(Bundle.LBL_FindMethod());\n            this.node = node;\n            setEnabled(isRegular(node));\n        }\n        \n        @NbBundle.Messages(\"LBL_SelectingIntervals=Selecting method intervals...\")\n        @Override\n        public void actionPerformed(ActionEvent actionEvent) {\n            RequestProcessor.getDefault().post(new Runnable() {\n                public void run() {\n                    ProgressHandle pHandle = null;\n                    try {\n                        pHandle = ProgressHandle.createHandle(Bundle.LBL_SelectingIntervals());\n                        pHandle.setInitialDelay(0);\n                        pHandle.start();\n                        \n                        List<Integer> ints = model.getIntervals(node);\n                        assert ints.size() % 2 == 0;\n                        final Iterator<Integer> iter = ints.iterator();\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                TimelineSupport support = model.getTimelineSupport();\n                                support.resetSelectedIntervals();\n                                while (iter.hasNext()) {\n                                    int start = iter.next();\n                                    int stop  = iter.next();\n                                    support.selectInterval(start, stop);\n                                }\n                                support.selectedIntervalsChanged();\n                            }\n                        });\n                    } catch (IOException ex) {\n                        Exceptions.printStackTrace(ex);\n                    } finally {\n                        if (pHandle != null) pHandle.finish();\n                    }\n                }\n            });\n        }\n\n        private boolean isRegular(PrestimeCPUCCTNode n) {\n            return n.getThreadId() != -1 && n.getMethodId() != 0 && !n.isFiltered();\n        }\n\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/details/DetailsPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.details;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Rectangle;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.KeyListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.JScrollPane;\nimport javax.swing.JViewport;\nimport javax.swing.KeyStroke;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.Scrollable;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.event.TableColumnModelEvent;\nimport javax.swing.event.TableColumnModelListener;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.TableColumnModel;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.HeaderPanel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.ScrollBar;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.TimelineSupport;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class DetailsPanel extends JPanel {\n\n    private JPanel noDataContainer;\n    private JComponent dataContainer;\n\n    private JScrollBar scrollBar;\n\n    private DetailsTable table;\n    private final TimelineSupport support;\n\n    private boolean selectionAdjusting;\n    private KeyStroke tableKeyStroke;\n\n\n    public DetailsPanel(TimelineSupport support) {\n        this.support = support;\n        initComponents();\n        initListeners();\n    }\n\n\n    public void setTableModel(TableModel model) {\n        if (model == null) {\n            table.clearSelection();\n            table.setModel(new DefaultTableModel());\n            removeAll();\n            add(noDataContainer, BorderLayout.CENTER);\n        } else {\n            int selectedRow = getSelectedRow();\n            table.setModel(model);\n            if (selectedRow != -1)\n                table.getSelectionModel().setSelectionInterval(selectedRow,\n                                                               selectedRow);\n            removeAll();\n            add(dataContainer, BorderLayout.CENTER);\n        }\n        \n        validate();\n        repaint();\n    }\n\n\n    private void initListeners() {\n        TableListener tableListener = new TableListener();\n        table.getSelectionModel().addListSelectionListener(tableListener);\n        table.addKeyListener(tableListener);\n        table.addMouseListener(tableListener);\n    }\n\n    private int getSelectedRow() {\n        int selectedRow = table.getSelectedRow();\n        return selectedRow == -1 ? -1 : table.convertRowIndexToModel(selectedRow);\n    }\n\n    private boolean isTrackingEnd() {\n        if (scrollBar == null) return false;\n        return scrollBar.getValue() + scrollBar.getVisibleAmount() >= scrollBar.getMaximum();\n    }\n\n    private boolean isSelectionChanging() {\n        if (selectionAdjusting) return true;\n        if (tableKeyStroke == null) return false;\n        return table.getActionForKeyStroke(tableKeyStroke) != null;\n    }\n\n    private void initComponents() {        \n        table = new DetailsTable();\n        table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n\n        JViewport viewport = new Viewport(table);\n\n        final JScrollPane tableScroll = new JScrollPane(\n                                            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,\n                                            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n        tableScroll.setViewport(viewport);\n        tableScroll.setBorder(BorderFactory.createEmptyBorder());\n        tableScroll.setViewportBorder(BorderFactory.createEmptyBorder());\n        tableScroll.setCorner(JScrollPane.UPPER_RIGHT_CORNER, new HeaderPanel());\n        \n        scrollBar = new ScrollBar(JScrollBar.VERTICAL) {\n            public int getUnitIncrement(int direction) {\n                JViewport vp = tableScroll.getViewport();\n                Scrollable view = (Scrollable)(vp.getView());\n                Rectangle vr = vp.getViewRect();\n                return view.getScrollableUnitIncrement(vr, getOrientation(), direction);\n            }\n            public int getBlockIncrement(int direction) {\n                JViewport vp = tableScroll.getViewport();\n                Scrollable view = (Scrollable)(vp.getView());\n                Rectangle vr = vp.getViewRect();\n                return view.getScrollableBlockIncrement(vr, getOrientation(), direction);\n            }\n            public void setValues(int newValue, int newExtent, int newMin, int newMax) {\n                setEnabled(newExtent < newMax);\n                if (isEnabled() && !isSelectionChanging() && isTrackingEnd())\n                    newValue = newMax - newExtent;\n                super.setValues(newValue, newExtent, newMin, newMax);\n            }\n        };\n        tableScroll.setVerticalScrollBar(scrollBar);\n        dataContainer = tableScroll;\n\n        JLabel noDataLabel = new JLabel(\"<No probe selected>\", JLabel.CENTER);\n        noDataLabel.setEnabled(false);\n        noDataContainer = new JPanel(new BorderLayout());\n        noDataContainer.setOpaque(false);\n        noDataContainer.add(noDataLabel, BorderLayout.CENTER);\n\n        setOpaque(false);\n        setLayout(new BorderLayout());\n        add(noDataContainer, BorderLayout.CENTER);\n    }\n\n\n    private class TableListener extends MouseAdapter implements\n                                ListSelectionListener, KeyListener {\n        public void valueChanged(ListSelectionEvent e) {\n            selectionAdjusting = e.getValueIsAdjusting();\n        }\n        public void keyPressed(KeyEvent e) {\n            tableKeyStroke = KeyStroke.getKeyStrokeForEvent(e);\n        }\n        public void keyReleased(KeyEvent e) {\n            tableKeyStroke = null;\n            if (e.getKeyCode() == KeyEvent.VK_SPACE)\n                support.scrollChartToIndex(getSelectedRow());\n        }\n        public void keyTyped(KeyEvent e) {}\n        public void mouseClicked(MouseEvent e) {\n            if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2)\n                support.scrollChartToIndex(getSelectedRow());\n        }\n    }\n\n\n    private static class Viewport extends JViewport {\n        \n        private final DetailsTable view;\n        private final Color background;\n\n        Viewport(DetailsTable view) {\n            super();\n\n            setView(view);\n            this.view = view;\n            \n            setOpaque(true);\n            background = view.getBackground();\n            setBackground(background);\n\n            view.getColumnModel().addColumnModelListener(new TableColumnModelListener() {\n                public void columnAdded(TableColumnModelEvent e) { repaint(); }\n                public void columnMoved(TableColumnModelEvent e) { repaint(); }\n                public void columnRemoved(TableColumnModelEvent e) { repaint(); }\n                public void columnMarginChanged(ChangeEvent e) { repaint(); }\n                public void columnSelectionChanged(ListSelectionEvent e) {}\n            });\n        }\n\n        protected void paintComponent(Graphics g) {\n            super.paintComponent(g);\n            paintVerticalLines(g);\n        }\n\n        private void paintVerticalLines(Graphics g) {\n            int height = getHeight();\n            int viewHeight = view.getHeight();\n            if (viewHeight >= height) return;\n\n            g.setColor(background);\n            g.fillRect(0, viewHeight, getWidth(), getHeight() - viewHeight);\n\n            int cellX = 0;\n            int cellWidth;\n            TableColumnModel model = view.getColumnModel();\n            int columnCount = model.getColumnCount();\n            \n            g.setColor(DetailsTable.DEFAULT_GRID_COLOR);\n            for (int i = 0; i < columnCount; i++) {\n                cellWidth = model.getColumn(i).getWidth();\n                cellX += cellWidth;\n                g.drawLine(cellX - 1, viewHeight, cellX - 1, height);\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/details/DetailsTable.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.details;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.event.MouseEvent;\nimport javax.swing.JLabel;\nimport javax.swing.JTable;\nimport javax.swing.event.TableModelEvent;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumn;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.HeaderLabel;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class DetailsTable extends JTable {\n\n    private static final int DEFAULT_ROW_HEIGHT = defaultRowHeight();\n    static final Color DEFAULT_GRID_COLOR = new Color(240, 240, 240);\n\n    private TableCellRenderer markRenderer;\n    private TimestampRenderer timestampRenderer;\n\n\n    DetailsTable() {\n        setOpaque(true);\n        setBackground(UIUtils.getProfilerResultsBackground());\n        setRowHeight(DEFAULT_ROW_HEIGHT);\n        setRowMargin(0);\n        setAutoCreateRowSorter(true);\n        setShowHorizontalLines(false);\n        setShowVerticalLines(true);\n        setGridColor(DEFAULT_GRID_COLOR);\n        getTableHeader().setPreferredSize(new Dimension(1, HeaderLabel.DEFAULT_HEIGHT));\n        getColumnModel().setColumnMargin(1);\n        initRenderers();\n    }\n\n\n    public void addColumn(TableColumn aColumn) {\n        super.addColumn(aColumn);\n        if (aColumn.getModelIndex() == 0 || aColumn.getModelIndex() == 1)\n            updateColumns(true);\n    }\n\n    public void tableChanged(TableModelEvent e) {\n        super.tableChanged(e);\n        if (e.getType() == TableModelEvent.INSERT) updateColumns(false);\n    }\n\n    protected JTableHeader createDefaultTableHeader() {\n        return new JTableHeader(columnModel) {\n            public String getToolTipText(MouseEvent e) {\n                int index = columnModel.getColumnIndexAtX(e.getPoint().x);\n                int realIndex = columnModel.getColumn(index).getModelIndex();\n                return ((DetailsTableModel)dataModel).getColumnTooltip(realIndex);\n            }\n        };\n    }\n\n\n    private void initRenderers() {\n        markRenderer = getDefaultRenderer(Boolean.class);\n        TableCellRenderer dateRenderer = getDefaultRenderer(String.class);\n        timestampRenderer = new TimestampRenderer(dateRenderer);\n        TableCellRenderer numberRenderer = getDefaultRenderer(Long.class);\n        setDefaultRenderer(Boolean.class, new MarkRenderer(markRenderer));\n        setDefaultRenderer(DetailsPanel.class, timestampRenderer);\n        setDefaultRenderer(Long.class, new ItemValueRenderer(numberRenderer));\n    }\n\n    private void updateColumns(boolean initialUpdate) {\n        if (timestampRenderer == null) return;\n\n        if (initialUpdate) {\n            Component boolRenderer = markRenderer.getTableCellRendererComponent(\n                                     DetailsTable.this, Boolean.FALSE, false,\n                                     false, 0, 0);\n            int width = boolRenderer.getPreferredSize().width;\n            TableColumn column = columnModel.getColumn(0);\n            TableCellRenderer headerRenderer = getTableHeader().getDefaultRenderer();\n            Component renderer = headerRenderer.getTableCellRendererComponent(\n                                 DetailsTable.this, column.getHeaderValue(), false,\n                                 false, 0, 0);\n            width = Math.max(width, renderer.getPreferredSize().width);\n            width += 16;\n            column.setPreferredWidth(width);\n            column.setMaxWidth(width);\n        }\n\n        if (columnModel.getColumnCount() > 1) {\n            if (!timestampRenderer.updateFormat(dataModel) && !initialUpdate) return;\n            Component renderer = timestampRenderer.getTableCellRendererComponent(\n                                 DetailsTable.this, TimestampRenderer.\n                                 REFERENCE_TIMESTAMP, false, false, 0, 1);\n            TableColumn column = columnModel.getColumn(1);\n            int width = renderer.getPreferredSize().width + 5;\n            if (initialUpdate || column.getMaxWidth() < width) {\n                column.setPreferredWidth(width);\n                column.setMaxWidth(width);\n                if (!initialUpdate) repaint();\n            }\n        }\n    }\n\n    private static int defaultRowHeight() {\n        return new JLabel(\"X\").getPreferredSize().height + 4; // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/details/DetailsTableCellRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.details;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport javax.swing.JComponent;\nimport javax.swing.JTable;\nimport javax.swing.table.TableCellRenderer;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass DetailsTableCellRenderer implements TableCellRenderer {\n\n    private static final Color BACKGROUND;\n    private static final Color DARKER_BACKGROUND;\n\n    static {\n        BACKGROUND = UIUtils.getProfilerResultsBackground();\n\n        int darkerR = BACKGROUND.getRed() - 11;\n        if (darkerR < 0) darkerR += 26;\n        int darkerG = BACKGROUND.getGreen() - 11;\n        if (darkerG < 0) darkerG += 26;\n        int darkerB = BACKGROUND.getBlue() - 11;\n        if (darkerB < 0) darkerB += 26;\n        DARKER_BACKGROUND = new Color(darkerR, darkerG, darkerB);\n    }\n\n    private TableCellRenderer impl;\n\n\n    DetailsTableCellRenderer(TableCellRenderer impl) {\n        this.impl = impl;\n    }\n\n\n    protected Object formatValue(JTable table, Object value, boolean isSelected,\n                                 boolean hasFocus, int row, int column) {\n        return value;\n    }\n\n    protected void updateRenderer(Component c, JTable table, Object value,\n                                  boolean isSelected, boolean hasFocus, int row,\n                                  int column) {\n        if (!isSelected) {\n            c.setBackground(row % 2 == 0 ? DARKER_BACKGROUND : BACKGROUND);\n            // Make sure the renderer paints its background (Nimbus)\n            if (c instanceof JComponent) ((JComponent)c).setOpaque(true);\n        }\n    }\n\n    public Component getTableCellRendererComponent(JTable table, Object value,\n                                                   boolean isSelected, boolean hasFocus,\n                                                   int row, int column) {\n\n        if (impl == null) impl = table.getDefaultRenderer(table.getColumnClass(column));\n        \n        value = formatValue(table, value, isSelected, hasFocus, row, column);\n        Component c = impl.getTableCellRendererComponent(table, value, isSelected,\n                                                         hasFocus, row, column);\n        updateRenderer(c, table, value, isSelected, hasFocus, row, column);\n\n        return c;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/details/DetailsTableModel.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.details;\n\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items.ValueItemDescriptor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class DetailsTableModel extends AbstractTableModel {\n\n    public abstract String getColumnTooltip(int columnIndex);\n\n    public abstract ValueItemDescriptor getDescriptor(int columnIndex);\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/details/ItemValueRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.details;\n\nimport javax.swing.JTable;\nimport javax.swing.table.TableCellRenderer;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ItemValueFormatter;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items.ValueItemDescriptor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ItemValueRenderer extends DetailsTableCellRenderer {\n\n    ItemValueRenderer(TableCellRenderer renderer) {\n        super(renderer);\n    }\n\n    protected Object formatValue(JTable table, Object value, boolean isSelected,\n                                 boolean hasFocus, int row, int column) {\n\n        DetailsTableModel model = (DetailsTableModel)table.getModel();\n        int columnIndex = table.convertColumnIndexToModel(column);\n        ValueItemDescriptor descriptor = model.getDescriptor(columnIndex);\n\n        String valueString = descriptor.getValueString((Long)value,\n                             ItemValueFormatter.FORMAT_DETAILS);\n        // Improve spacing of the text\n        return \" \" + valueString + \" \"; // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/details/MarkRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.details;\n\nimport java.awt.Component;\nimport javax.swing.JTable;\nimport javax.swing.table.TableCellRenderer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class MarkRenderer extends DetailsTableCellRenderer {\n\n    MarkRenderer(TableCellRenderer renderer) {\n        super(renderer);\n    }\n\n    public Component getTableCellRendererComponent(JTable table, Object value,\n                                                   boolean isSelected, boolean hasFocus,\n                                                   int row, int column) {\n\n        // Workaround strange selection behavior for newly selected checkbox\n        isSelected = isSelected || hasFocus;\n\n        return super.getTableCellRendererComponent(table, value, isSelected,\n                                                   hasFocus, row, column);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/details/TimestampRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.details;\n\nimport java.awt.Component;\nimport java.text.Format;\nimport java.text.SimpleDateFormat;\nimport javax.swing.JLabel;\nimport javax.swing.JTable;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.lib.charts.axis.TimeAxisUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimestampRenderer extends DetailsTableCellRenderer {\n\n    // Fri Mar 19 11:59:59.999 AM 2010\n    static final long REFERENCE_TIMESTAMP = 1268996399999l;\n\n    private String formatString;\n    private Format format;\n\n    TimestampRenderer(TableCellRenderer renderer) {\n        super(renderer);\n    }\n\n    protected Object formatValue(JTable table, Object value, boolean isSelected,\n                                 boolean hasFocus, int row, int column) {\n        String valueString = format.format(value);\n        // Improve spacing of the text\n        return \" \" + valueString + \" \"; // NOI18N\n    }\n\n    protected void updateRenderer(Component c, JTable table, Object value,\n                                  boolean isSelected, boolean hasFocus, int row,\n                                  int column) {\n        super.updateRenderer(c, table, value, isSelected, hasFocus, row, column);\n        if (c instanceof JLabel) ((JLabel)c).setHorizontalAlignment(JLabel.TRAILING);\n    }\n\n    boolean updateFormat(TableModel model) {\n        int rowCount = model.getRowCount();\n\n        long first = rowCount > 0 ? (Long)model.getValueAt(0, 1) : REFERENCE_TIMESTAMP;\n        long last  = rowCount > 0 ? (Long)model.getValueAt(rowCount - 1, 1) :\n                                    REFERENCE_TIMESTAMP + 1;\n\n        String newFormatString = TimeAxisUtils.getFormatString(1, first, last);\n        if (!newFormatString.equals(formatString)) {\n            formatString = newFormatString;\n            format = new SimpleDateFormat(formatString);\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/export/CSVExporter.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.export;\n\nimport java.io.IOException;\nimport java.io.Writer;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProgressObject;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class CSVExporter extends Exporter {\n\n    private static final String DELIMITER = \",\"; // NOI18N\n\n    private float step = 1;\n    private int lastStep = 0;\n\n\n    protected int getSteps(TableModel model) {\n        int steps = model.getRowCount();\n        if (steps > MAX_STEPS) {\n            step = MAX_STEPS / (float)steps;\n            steps = MAX_STEPS;\n        }\n        return steps;\n    }\n\n    protected void writeData(TableModel model, String title, Writer writer,\n                             TracerProgressObject progress) throws IOException {\n        int columnsCount = model.getColumnCount();\n        int rowsCount = model.getRowCount();\n\n        for (int c = 0; c < columnsCount; c++) {\n            write(writer, \"\\\"\" + model.getColumnName(c) + \"\\\"\"); // NOI18N\n            if (c < columnsCount - 1) write(writer, DELIMITER);\n        }\n        writeLine(writer);\n\n        for (int r = 0; r < rowsCount; r++) {\n            for (int c = 0; c < columnsCount; c++) {\n                write(writer, \"\\\"\" + model.getValueAt(r, c) + \"\\\"\"); // NOI18N\n                if (c < columnsCount - 1) write(writer, DELIMITER);\n            }\n            writeLine(writer);\n\n            if (progress.isFinished()) break;\n\n            if (step == 1) {\n                progress.addStep();\n            } else {\n                int currentStep = (int)(r * step);\n                if (currentStep > lastStep) {\n                    progress.addStep();\n                    lastStep = currentStep;\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/export/DataExport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.export;\n\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.OutputStreamWriter;\nimport java.io.Writer;\nimport java.nio.charset.StandardCharsets;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JDialog;\nimport javax.swing.JFileChooser;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JProgressBar;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport javax.swing.filechooser.FileFilter;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProgressObject;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.TracerSupportImpl;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.VerticalLayout;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class DataExport {\n\n    private static final Logger LOGGER = Logger.getLogger(DataExport.class.getName());\n\n    private static final int INDETERMINATE_PROGRESS_THRESHOLD =\n                Integer.getInteger(\"visualvm.tracer.indeterminateProgressThreshold\", 2500); // NOI18N\n\n    private static final Filter CSV_FILTER  = Filter.create(\"CSV Files\", \".csv\");\n    private static final Filter HTML_FILTER = Filter.create(\"HTML Files\", \".html\");\n    private static final Filter XML_FILTER  = Filter.create(\"XML Files\", \".xml\");\n\n    private static JFileChooser fileChooser;\n    private static File lastDirectory;\n    private static Filter lastFilter = CSV_FILTER;\n\n\n    public static void exportData(final TableModel model, final String title) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                JFileChooser chooser = getFileChooser();\n                if (chooser.showSaveDialog(WindowManager.getDefault().getRegistry().\n                        getActivated()) == JFileChooser.APPROVE_OPTION) {\n                    File file = chooser.getSelectedFile();\n                    Filter filter = (Filter)chooser.getFileFilter();\n                    doExportData(model, title, file, filter);\n                }\n                lastDirectory = chooser.getCurrentDirectory();\n                lastFilter = (Filter)chooser.getFileFilter();\n            }\n        });\n    }\n\n\n    private static void doExportData(final TableModel model, final String title,\n                                     final File file, final Filter filter) {\n        \n        TracerSupportImpl.getInstance().perform(new Runnable() {\n            public void run() {\n                TracerProgressObject progress = null;\n                try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)) {\n                    ExportBatch batch = null;\n\n                    if (filter == XML_FILTER)\n                        batch = new XMLExporter().createBatch(model, title, writer);\n                    else if (filter == HTML_FILTER)\n                        batch = new HTMLExporter().createBatch(model, title, writer);\n                    else if (filter == CSV_FILTER)\n                        batch = new CSVExporter().createBatch(model, title, writer);\n\n                    if (batch != null) {\n                        progress = batch.getProgress();\n                        final TracerProgressObject progressF = progress;\n                        SwingUtilities.invokeAndWait(new Runnable() {\n                            public void run() { showProgressDialog(progressF); }\n                        });\n                        batch.getWorker().run();\n                    }\n                } catch (Throwable t) {\n                    if (progress != null) {\n                        progress.setText(\"Exporting data failed\");\n                        progress.finish();\n                    }\n                    LOGGER.log(Level.INFO, \"Exporting data failed\", t); // NOI18N\n                }\n            }\n        });\n    }\n\n    private static void showProgressDialog(final TracerProgressObject progress) {\n        final JLabel l = new JLabel();\n        l.setBorder(BorderFactory.createEmptyBorder(0, 0, 7, 0));\n\n        final JProgressBar p = new JProgressBar(0, progress.getSteps()) {\n            public Dimension getPreferredSize() {\n                Dimension d = super.getPreferredSize();\n                d.width = Exporter.MAX_STEPS;\n                d.height += 2;\n                return d;\n            }\n        };\n        p.setBorder(BorderFactory.createEmptyBorder());\n        final Timer t = new Timer(INDETERMINATE_PROGRESS_THRESHOLD, null);\n        t.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                p.setIndeterminate(true);\n                t.stop();\n            }\n        });\n\n        final JButton b = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                SwingUtilities.getWindowAncestor(this).setVisible(false);\n            }\n        };\n\n        progress.addListener(new TracerProgressObject.Listener() {\n            public void progressChanged(int addedSteps, int currentStep, String text) {\n                t.stop();\n                p.setIndeterminate(false);\n                p.setValue(currentStep);\n                l.setText(text == null ? \"\" : text); // NOI18N\n                if (!progress.isFinished()) t.start();\n                else b.setText(\"Close\");\n            }\n        });\n        l.setText(progress.getText());\n        p.setValue(progress.getCurrentStep());\n        b.setText(progress.isFinished() ? \"Close\" : \"Cancel\");\n\n        JPanel c = new JPanel(new VerticalLayout(false));\n        c.setBorder(BorderFactory.createEmptyBorder(20, 10, 15, 10));\n        c.add(l);\n        c.add(p);\n\n        final DialogDescriptor dd = new DialogDescriptor(c, \"Export Tracer Data\",\n                                                        true, new Object[] { b },\n                                                        b, DialogDescriptor.BOTTOM_ALIGN,\n                                                        null, null);\n\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n                openDialog(d);\n                progress.finish();\n            }\n        });\n    }\n    \n\n    private static JFileChooser getFileChooser() {\n        if (fileChooser == null)   fileChooser = createFileChooser();\n        if (lastDirectory != null) fileChooser.setCurrentDirectory(lastDirectory);\n        if (lastFilter != null)    fileChooser.setFileFilter(lastFilter);\n        return fileChooser;\n    }\n\n    private static JFileChooser createFileChooser() {\n        JFileChooser chooser = new JFileChooser() {\n            public void approveSelection() {\n                File file = getSelectedFile();\n                Filter filter = (Filter)getFileFilter();\n\n                if (!file.getName().endsWith(filter.getExt())) {\n                    file = new File(file.getPath() + filter.getExt());\n                    setSelectedFile(file);\n                }\n\n                if (!file.isFile()) {\n                    super.approveSelection();\n                    return;\n                }\n                \n                final boolean[] ret = new boolean[1];\n                JButton yesB = new JButton(\"Yes\") {\n                    protected void fireActionPerformed(ActionEvent e) {\n                        ret[0] = true;\n                        super.fireActionPerformed(e);\n                    }\n                };\n                DialogDescriptor desc = new DialogDescriptor(\n                    \"File \\\"\" + file.getName() + \"\\\" already exists.\\n\" +\n                    \"Do you want to replace it?\", \"Replace Existing File\",\n                    true, new Object[] { yesB, new JButton(\"No\") }, yesB,\n                    DialogDescriptor.BOTTOM_ALIGN, null, null);\n                desc.setMessageType(NotifyDescriptor.QUESTION_MESSAGE);\n                Dialog d = DialogDisplayer.getDefault().createDialog(desc);\n                openDialog(d);\n                if (ret[0] == true) super.approveSelection();\n            }\n        };\n\n        chooser.setDialogTitle(\"Export Tracer Data\");\n        chooser.setDialogType(JFileChooser.SAVE_DIALOG);\n        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);\n\n        chooser.setAcceptAllFileFilterUsed(false);\n\n        chooser.addChoosableFileFilter(CSV_FILTER);\n        chooser.addChoosableFileFilter(HTML_FILTER);\n        chooser.addChoosableFileFilter(XML_FILTER);\n\n        return chooser;\n    }\n\n    private static void openDialog(Dialog d) {\n        if (d instanceof JDialog) d.setLocationRelativeTo(\n                WindowManager.getDefault().getRegistry().getActivated());\n        d.setVisible(true);\n    }\n\n    \n    private static abstract class Filter extends FileFilter {\n\n        abstract String getExt();\n\n        static Filter create(final String descr, final String ext) {\n            return new Filter() {\n                public boolean accept(File f) {\n                    return f.isDirectory() || getFileExt(f.getName()).equals(ext);\n                }\n                public String getExt() {\n                    return ext;\n                }\n                public String getDescription() {\n                    return descr + \" (*\" + ext + \")\";\n                }\n            };\n        }\n        \n        private static String getFileExt(String fileName) {\n            int extIndex = fileName.lastIndexOf('.'); // NOI18N\n            if (extIndex == -1) return \"\"; // NOI18N\n            return fileName.substring(extIndex);\n        }\n\n        private Filter() {}\n\n    }\n\n\n    private DataExport() {}\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/export/ExportBatch.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.export;\n\nimport java.io.IOException;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProgressObject;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ExportBatch {\n\n    private final TracerProgressObject progress;\n    private final BatchRunnable worker;\n\n    protected ExportBatch(TracerProgressObject progress, BatchRunnable worker) {\n        this.progress = progress;\n        this.worker = worker;\n    }\n\n    TracerProgressObject getProgress() { return progress; }\n    BatchRunnable getWorker() { return worker; }\n\n    static interface BatchRunnable {\n        public void run() throws IOException;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/export/Exporter.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.export;\n\nimport java.io.IOException;\nimport java.io.Writer;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProgressObject;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class Exporter {\n\n    protected static final int MAX_STEPS = 300; // Defines also JProgressBar width\n\n\n    protected abstract int getSteps(TableModel model);\n\n    protected void writeHeader(TableModel model, String title, Writer writer,\n                               TracerProgressObject progress) throws IOException {}\n\n    protected void writeData(TableModel model, String title, Writer writer,\n                             TracerProgressObject progress) throws IOException {}\n\n    protected void writeFooter(TableModel model, String title, Writer writer,\n                               TracerProgressObject progress) throws IOException {}\n\n\n    protected static void writeLine(Writer writer) throws IOException {\n        writer.write(\"\\n\"); // NOI18N\n    }\n\n    protected static void writeLine(Writer writer, String line) throws IOException {\n        writer.write(line + \"\\n\"); // NOI18N\n    }\n\n    protected static void write(Writer writer, String text) throws IOException {\n        writer.write(text);\n    }\n\n\n    final ExportBatch createBatch(final TableModel model, final String title,\n                                  final Writer writer) {\n\n        final TracerProgressObject progress = new TracerProgressObject(getSteps(model) + 2);\n\n        ExportBatch.BatchRunnable worker = new ExportBatch.BatchRunnable() {\n            public void run() throws IOException {\n                doExport(model, title, writer, progress);\n            }\n        };\n\n        return new ExportBatch(progress, worker);\n    }\n\n    private void doExport(TableModel model, String title, Writer writer,\n                          TracerProgressObject progress) throws IOException {\n        progress.setText(\"Initializing export...\");\n        writeHeader(model, title, writer, progress);\n\n        if (progress.isFinished()) return;\n\n        progress.addStep(\"Exporting data...\");\n        writeData(model, title, writer, progress);\n\n        if (progress.isFinished()) return;\n\n        progress.setText(\"Finishing export...\");\n        writeFooter(model, title, writer, progress);\n\n        if (progress.isFinished()) return;\n\n        progress.setText(\"Data exported\");\n        progress.finish();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/export/HTMLExporter.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.export;\n\nimport java.io.IOException;\nimport java.io.Writer;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProgressObject;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class HTMLExporter extends Exporter {\n\n    private float step = 1;\n    private int lastStep = 0;\n\n\n    protected int getSteps(TableModel model) {\n        int steps = model.getRowCount();\n        if (steps > MAX_STEPS) {\n            step = MAX_STEPS / (float)steps;\n            steps = MAX_STEPS;\n        }\n        return steps;\n    }\n\n    protected void writeHeader(TableModel model, String title, Writer writer,\n                               TracerProgressObject progress) throws IOException {\n        writeLine(writer, \"<!DOCTYPE HTML PUBLIC \\\"-//W3C//DTD HTML 4.01 Transitional//EN\\\" \\\"http://www.w3.org/TR/html4/loose.dtd\\\">\"); // NOI18N\n        writeLine(writer);\n\n        writeLine(writer, \"<html>\"); // NOI18N\n        writeLine(writer, \"<head>\"); // NOI18N\n        writeLine(writer, \"  <title>\"); // NOI18N\n        writeLine(writer, \"    \" + title); // NOI18N\n        writeLine(writer, \"  </title>\"); // NOI18N\n        writeLine(writer, \"</head>\"); // NOI18N\n        writeLine(writer);\n\n        writeLine(writer, \"<body>\"); // NOI18N\n    }\n\n    protected void writeData(TableModel model, String title, Writer writer,\n                             TracerProgressObject progress) throws IOException {\n        int columnsCount = model.getColumnCount();\n        int rowsCount = model.getRowCount();\n\n        writeLine(writer, \"  <table border=\\\"1\\\" summary=\\\"\" + title + \"\\\">\"); // NOI18N\n\n        writeLine(writer, \"    <thead>\"); // NOI18N\n        writeLine(writer, \"      <tr>\"); // NOI18N\n        for (int c = 0; c < columnsCount; c++)\n            writeLine(writer, \"        <td>\" + model.getColumnName(c) + \"</td>\"); // NOI18N\n        writeLine(writer, \"      </tr>\"); // NOI18N\n        writeLine(writer, \"    </thead>\"); // NOI18N\n\n        writeLine(writer, \"    <tbody>\"); // NOI18N\n        for (int r = 0; r < rowsCount; r++) {\n            writeLine(writer, \"      <tr>\"); // NOI18N\n            for (int c = 0; c < columnsCount; c++)\n                writeLine(writer, \"        <td>\" + model.getValueAt(r, c) + \"</td>\"); // NOI18N\n            writeLine(writer, \"      </tr>\"); // NOI18N\n            \n            if (progress.isFinished()) break;\n\n            if (step == 1) {\n                progress.addStep();\n            } else {\n                int currentStep = (int)(r * step);\n                if (currentStep > lastStep) {\n                    progress.addStep();\n                    lastStep = currentStep;\n                }\n            }\n        }\n        writeLine(writer, \"    </tbody>\"); // NOI18N\n\n        writeLine(writer, \"  </table>\"); // NOI18N\n    }\n\n    protected void writeFooter(TableModel model, String title, Writer writer,\n                               TracerProgressObject progress) throws IOException {\n        writeLine(writer, \"</body>\"); // NOI18N\n        writeLine(writer, \"</html>\"); // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/export/XMLExporter.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.export;\n\nimport java.io.IOException;\nimport java.io.Writer;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProgressObject;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class XMLExporter extends Exporter {\n\n    private float step = 1;\n    private int lastStep = 0;\n\n\n    protected int getSteps(TableModel model) {\n        int steps = model.getRowCount();\n        if (steps > MAX_STEPS) {\n            step = MAX_STEPS / (float)steps;\n            steps = MAX_STEPS;\n        }\n        return steps;\n    }\n\n    protected void writeHeader(TableModel model, String title, Writer writer,\n                               TracerProgressObject progress) throws IOException {\n        writeLine(writer, \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"); // NOI18N\n        writeLine(writer, \"<ExportedView Name=\\\"\" + title + \"\\\">\"); // NOI18N\n    }\n\n    protected void writeData(TableModel model, String title, Writer writer,\n                             TracerProgressObject progress) throws IOException {\n        int columnsCount = model.getColumnCount();\n        int rowsCount = model.getRowCount();\n\n        writeLine(writer, \"  <TableData NumRows=\\\"\" + rowsCount + // NOI18N\n                             \"\\\" NumColumns=\\\"\" + columnsCount + \"\\\">\"); // NOI18N\n\n        writeLine(writer, \"    <TableHeader>\"); // NOI18N\n        for (int c = 0; c < columnsCount; c++)\n            writeLine(writer, \"      <TableColumn>\" + model.getColumnName(c) + \"</TableColumn>\"); // NOI18N\n        writeLine(writer, \"    </TableHeader>\"); // NOI18N\n\n        writeLine(writer, \"    <TableBody>\"); // NOI18N\n        for (int r = 0; r < rowsCount; r++) {\n            writeLine(writer, \"      <TableRow>\"); // NOI18N\n            for (int c = 0; c < columnsCount; c++)\n                writeLine(writer, \"        <TableColumn>\" + model.getValueAt(r, c) + \"</TableColumn>\"); // NOI18N\n            writeLine(writer, \"      </TableRow>\"); // NOI18N\n            \n            if (progress.isFinished()) break;\n\n            if (step == 1) {\n                progress.addStep();\n            } else {\n                int currentStep = (int)(r * step);\n                if (currentStep > lastStep) {\n                    progress.addStep();\n                    lastStep = currentStep;\n                }\n            }\n        }\n        writeLine(writer, \"    </TableBody>\"); // NOI18N\n\n        writeLine(writer, \"  </TableData>\"); // NOI18N\n    }\n\n    protected void writeFooter(TableModel model, String title, Writer writer,\n                               TracerProgressObject progress) throws IOException {\n        writeLine(writer, \"</ExportedView>\"); // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/icons/TracerIcons.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.icons;\n\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic interface TracerIcons extends Icons.Keys {\n\n    public static final String INCREMENT = \"TracerIcons.Increment\"; // NOI18N\n    public static final String DECREMENT = \"TracerIcons.Decrement\"; // NOI18N\n    public static final String RESET = \"TracerIcons.Reset\"; // NOI18N\n    public static final String GENERIC_ACTION = \"TracerIcons.GenericAction\"; // NOI18N\n    public static final String MOUSE_WHEEL_HORIZONTAL = \"TracerIcons.MouseWheelHorizontal\"; // NOI18N\n    public static final String MOUSE_WHEEL_VERTICAL = \"TracerIcons.MouseWheelVertical\"; // NOI18N\n    public static final String MOUSE_WHEEL_ZOOM = \"TracerIcons.MouseWheelZoom\"; // NOI18N\n    public static final String MARK = \"TracerIcons.Mark\"; // NOI18N\n    public static final String MARK_CLEAR = \"TracerIcons.MarkClear\"; // NOI18N\n    public static final String MARK_HIGHLIGHT = \"TracerIcons.MarkHiglight\"; // NOI18N\n    public static final String SELECT_ALL = \"TracerIcons.SelectAll\"; // NOI18N\n    public static final String PROBE = \"TracerIcons.Probe\"; // NOI18N\n    public static final String TRACER = \"TracerIcons.Tracer\"; // NOI18N\n    public static final String TRACER_32 = \"TracerIcons.Tracer32\"; // NOI18N\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/icons/TracerIconsProviderImpl.java",
    "content": "/*\n * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.icons;\n\nimport java.util.Map;\nimport org.graalvm.visualvm.lib.profiler.spi.IconsProvider;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=IconsProvider.class)\npublic final class TracerIconsProviderImpl extends IconsProvider.Basic {\n\n    @Override\n    protected final void initStaticImages(Map<String, String> cache) {\n        cache.put(TracerIcons.INCREMENT, \"increment.png\"); // NOI18N\n        cache.put(TracerIcons.DECREMENT, \"decrement.png\"); // NOI18N\n        cache.put(TracerIcons.RESET, \"reset.png\"); // NOI18N\n        cache.put(TracerIcons.GENERIC_ACTION, \"genericAction.png\"); // NOI18N\n        cache.put(TracerIcons.MOUSE_WHEEL_HORIZONTAL, \"hmwheel.png\"); // NOI18N\n        cache.put(TracerIcons.MOUSE_WHEEL_VERTICAL, \"vmwheel.png\"); // NOI18N\n        cache.put(TracerIcons.MOUSE_WHEEL_ZOOM, \"zmwheel.png\"); // NOI18N\n        cache.put(TracerIcons.MARK, \"mark.png\"); // NOI18N\n        cache.put(TracerIcons.MARK_CLEAR, \"markClear.png\"); // NOI18N\n        cache.put(TracerIcons.MARK_HIGHLIGHT, \"markHighl.png\"); // NOI18N\n        cache.put(TracerIcons.SELECT_ALL, \"selectAll.png\"); // NOI18N\n        cache.put(TracerIcons.PROBE, \"probe.png\"); // NOI18N\n        cache.put(TracerIcons.TRACER, \"tracer.png\"); // NOI18N\n        cache.put(TracerIcons.TRACER_32, \"tracer32.png\"); // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/options/TracerOptions.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.options;\n\nimport java.util.prefs.Preferences;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class TracerOptions {\n\n    private static final String PROP_PROBES_APP = \"TracerOptions.probesApp\"; // NOI18N\n    public static final int KEY_PROBES_FIRSTEXP = 0;\n    public static final int KEY_PROBES_ALLEXP = 1;\n    public static final int KEY_PROBES_ALLCOLL = 2;\n    private static final int PROBES_APP_DEFAULT = KEY_PROBES_FIRSTEXP;\n\n    private static final String PROP_REFRESH_RATE = \"TracerOptions.refreshRate\"; // NOI18N\n    private static final String PROP_REFRESH_CUSTOMIZABLE = \"TracerOptions.refreshCustomizable\"; // NOI18N\n\n    private static final String PROP_SHOW_VALUES = \"TracerOptions.showValues\"; // NOI18N\n    private static final String PROP_SHOW_LEGEND = \"TracerOptions.showLegend\"; // NOI18N\n    private static final String PROP_ROWS_DECORATION = \"TracerOptions.rowsDecoration\"; // NOI18N\n    private static final String PROP_ROWS_SELECTION = \"TracerOptions.rowsSelection\"; // NOI18N\n\n    private static final String PROP_INITIALLY_OPEN = \"TracerOptions.initiallyOpen\"; // NOI18N\n    private static final String PROP_PROBE_ADDED = \"TracerOptions.probeAdded\"; // NOI18N\n    private static final String PROP_PROBE_ADDED2 = \"TracerOptions.probeAdded2\"; // NOI18N\n    private static final String PROP_SESSION_STARTED = \"TracerOptions.sessionStarted\"; // NOI18N\n    private static final String PROP_ROW_SELECTED = \"TracerOptions.rowSelected\"; // NOI18N\n    private static final String PROP_ROW_SELECTED2 = \"TracerOptions.rowSelected2\"; // NOI18N\n    public static final String VIEWS_UNCHANGED = \"\"; // NOI18N\n    public static final String VIEW_PROBES = \"KEY_probes\"; // NOI18N\n    public static final String VIEW_TIMELINE = \"KEY_timeline\"; // NOI18N\n    public static final String VIEW_SETTINGS = \"KEY_settings\"; // NOI18N\n    public static final String VIEW_DETAILS = \"KEY_details\"; // NOI18N\n    static final String INITIALLY_OPEN_DEFAULT = VIEW_PROBES;\n    static final String PROBE_ADDED_DEFAULT = INITIALLY_OPEN_DEFAULT + \",\" + VIEW_TIMELINE; // NOI18N\n    static final String PROBE_ADDED_DEFAULT2 = INITIALLY_OPEN_DEFAULT;\n    static final String SESSION_STARTED_DEFAULT = VIEW_TIMELINE;\n    static final String ROW_SELECTED_DEFAULT = SESSION_STARTED_DEFAULT + \",\" + VIEW_DETAILS; // NOI18N\n    static final String ROW_SELECTED_DEFAULT2 = SESSION_STARTED_DEFAULT;\n\n    private static final String PROP_CLEAR_SELECTION = \"TracerOptions.clearSelection\"; // NOI18N\n\n    private static final String PROP_ZOOM_MODE = \"TracerOptions.zoomMode\"; // NOI18N\n    private static final String KEY_FIXED_SCALE = \"KEY_fixedScale\"; // NOI18N\n    private static final String KEY_SCALE_TO_FIT = \"KEY_scaleToFit\"; // NOI18N\n    public static final String FIXED_SCALE = \"fixed scale\";\n    public static final String SCALE_TO_FIT = \"scale to fit\";\n\n    private static final String PROP_MOUSE_WHEEL_ACTION = \"TracerOptions.mouseWheelAction\"; // NOI18N\n    private static final String KEY_MOUSE_WHEEL_ZOOMS = \"KEY_mouseWheelZooms\"; // NOI18N\n    private static final String KEY_MOUSE_WHEEL_HSCROLLS = \"KEY_mouseWheelHScrolls\"; // NOI18N\n    private static final String KEY_MOUSE_WHEEL_VSCROLLS = \"KEY_mouseWheelVScrolls\"; // NOI18N\n    public static final String MOUSE_WHEEL_ZOOMS = \"zoom\";\n    public static final String MOUSE_WHEEL_HSCROLLS = \"horizontal scroll\";\n    public static final String MOUSE_WHEEL_VSCROLLS = \"vertical scroll\";\n\n    private static final String PROP_TIMELINE_TOOLBAR = \"TracerOptions.timelineToolbar\"; // NOI18N\n    private static final String PROP_SELECTION_TOOLBAR = \"TracerOptions.selectionToolbar\"; // NOI18N\n    private static final String PROP_EXTRA_TOOLBAR = \"TracerOptions.extraToolbar\"; // NOI18N\n    public static final int SHOW_ALWAYS = 0;\n    public static final int SHOW_AS_NEEDED = 1;\n    public static final int SHOW_NEVER = 2;\n    private static final int TIMELINE_TOOLBAR_DEFAULT = SHOW_AS_NEEDED;\n    private static final int SELECTION_TOOLBAR_DEFAULT = SHOW_AS_NEEDED;\n    private static final int EXTRA_TOOLBAR_DEFAULT = SHOW_AS_NEEDED;\n\n\n\n    private static TracerOptions INSTANCE;\n\n    private final Preferences prefs;\n\n\n    public static synchronized TracerOptions getInstance() {\n        if (INSTANCE == null) INSTANCE = new TracerOptions();\n        return INSTANCE;\n    }\n\n\n    void setProbesApp(int probesApp) {\n        prefs.putInt(PROP_PROBES_APP, probesApp);\n    }\n\n    public int getProbesApp() {\n        return prefs.getInt(PROP_PROBES_APP, PROBES_APP_DEFAULT);\n    }\n\n    void setRefresh(int refreshRate) {\n        prefs.putInt(PROP_REFRESH_RATE, refreshRate);\n    }\n\n    int getRefresh() {\n        return prefs.getInt(PROP_REFRESH_RATE, -1);\n    }\n\n    public int getRefreshRate() {\n        int refresh = getRefresh();\n        return refresh != -1 ? refresh : 1000;\n    }\n\n    void setRefreshCustomizable(boolean customizable) {\n        prefs.putBoolean(PROP_REFRESH_CUSTOMIZABLE, customizable);\n    }\n\n    public boolean isRefreshCustomizable() {\n        return prefs.getBoolean(PROP_REFRESH_CUSTOMIZABLE, false);\n    }\n\n    void setShowValuesEnabled(boolean showValuesEnabled) {\n        prefs.putBoolean(PROP_SHOW_VALUES, showValuesEnabled);\n    }\n\n    public boolean isShowValuesEnabled() {\n        return prefs.getBoolean(PROP_SHOW_VALUES, true);\n    }\n\n    void setShowLegendEnabled(boolean showLegendEnabled) {\n        prefs.putBoolean(PROP_SHOW_LEGEND, showLegendEnabled);\n    }\n\n    public boolean isShowLegendEnabled() {\n        return prefs.getBoolean(PROP_SHOW_LEGEND, true); // Default 'false' might be better\n    }\n\n    void setRowsDecorationEnabled(boolean rowsDecorationEnabled) {\n        if (Utils.forceSpeed()) return;\n        prefs.putBoolean(PROP_ROWS_DECORATION, rowsDecorationEnabled);\n    }\n\n    public boolean isRowsDecorationEnabled() {\n        if (Utils.forceSpeed()) return false;\n        return prefs.getBoolean(PROP_ROWS_DECORATION, !Utils.forceSpeed());\n    }\n\n    void setRowsSelectionEnabled(boolean rowsSelectionEnabled) {\n        prefs.putBoolean(PROP_ROWS_SELECTION, rowsSelectionEnabled);\n    }\n\n    public boolean isRowsSelectionEnabled() {\n        return prefs.getBoolean(PROP_ROWS_SELECTION, !Utils.forceSpeed());\n    }\n\n    void setInitiallyOpened(String opened) {\n        prefs.put(PROP_INITIALLY_OPEN, opened);\n    }\n\n    public String getInitiallyOpened() {\n        return prefs.get(PROP_INITIALLY_OPEN, INITIALLY_OPEN_DEFAULT);\n    }\n\n    void setOnProbeAdded(String opened) {\n        prefs.put(PROP_PROBE_ADDED, opened);\n    }\n\n    public String getOnProbeAdded() {\n        return prefs.get(PROP_PROBE_ADDED, PROBE_ADDED_DEFAULT);\n    }\n\n    void setOnProbeAdded2(String opened) {\n        prefs.put(PROP_PROBE_ADDED2, opened);\n    }\n\n    public String getOnProbeAdded2() {\n        return prefs.get(PROP_PROBE_ADDED2, PROBE_ADDED_DEFAULT2);\n    }\n\n    void setOnSessionStart(String opened) {\n        prefs.put(PROP_SESSION_STARTED, opened);\n    }\n\n    public String getOnSessionStart() {\n        return prefs.get(PROP_SESSION_STARTED, SESSION_STARTED_DEFAULT);\n    }\n\n     void setOnRowSelected(String opened) {\n        prefs.put(PROP_ROW_SELECTED, opened);\n    }\n\n    public String getOnRowSelected() {\n        return prefs.get(PROP_ROW_SELECTED, ROW_SELECTED_DEFAULT);\n    }\n\n    void setOnRowSelected2(String opened) {\n        prefs.put(PROP_ROW_SELECTED2, opened);\n    }\n\n    public String getOnRowSelected2() {\n        return prefs.get(PROP_ROW_SELECTED2, ROW_SELECTED_DEFAULT2);\n    }\n\n    void setZoomMode(String zoomMode) {\n        if (SCALE_TO_FIT.equals(zoomMode))\n            prefs.put(PROP_ZOOM_MODE, KEY_SCALE_TO_FIT);\n        else\n            prefs.put(PROP_ZOOM_MODE, KEY_FIXED_SCALE);\n    }\n\n    public String getZoomMode() {\n        String zoomMode = prefs.get(PROP_ZOOM_MODE, KEY_FIXED_SCALE);\n        if (KEY_SCALE_TO_FIT.equals(zoomMode)) return SCALE_TO_FIT;\n        return FIXED_SCALE;\n    }\n\n    void setMouseWheelAction(String mouseWheelAction) {\n        if (MOUSE_WHEEL_HSCROLLS.equals(mouseWheelAction))\n            prefs.put(PROP_MOUSE_WHEEL_ACTION, KEY_MOUSE_WHEEL_HSCROLLS);\n        else if (MOUSE_WHEEL_VSCROLLS.equals(mouseWheelAction))\n            prefs.put(PROP_MOUSE_WHEEL_ACTION, KEY_MOUSE_WHEEL_VSCROLLS);\n        else\n            prefs.put(PROP_MOUSE_WHEEL_ACTION, KEY_MOUSE_WHEEL_ZOOMS);\n    }\n\n    public String getMouseWheelAction() {\n        String mouseWheelAction = prefs.get(PROP_MOUSE_WHEEL_ACTION, KEY_MOUSE_WHEEL_ZOOMS);\n        if (KEY_MOUSE_WHEEL_HSCROLLS.equals(mouseWheelAction)) return MOUSE_WHEEL_HSCROLLS;\n        else if (KEY_MOUSE_WHEEL_VSCROLLS.equals(mouseWheelAction)) return MOUSE_WHEEL_VSCROLLS;\n        return MOUSE_WHEEL_ZOOMS;\n    }\n\n    void setTimelineToolbar(int visible) {\n        prefs.putInt(PROP_TIMELINE_TOOLBAR, visible);\n    }\n\n    public int getTimelineToolbar() {\n        return prefs.getInt(PROP_TIMELINE_TOOLBAR, TIMELINE_TOOLBAR_DEFAULT);\n    }\n\n    void setSelectionToolbar(int visible) {\n        prefs.putInt(PROP_SELECTION_TOOLBAR, visible);\n    }\n\n    public int getSelectionToolbar() {\n        return prefs.getInt(PROP_SELECTION_TOOLBAR, SELECTION_TOOLBAR_DEFAULT);\n    }\n\n    void setExtraToolbar(int visible) {\n        prefs.putInt(PROP_EXTRA_TOOLBAR, visible);\n    }\n\n    public int getExtraToolbar() {\n        return prefs.getInt(PROP_EXTRA_TOOLBAR, EXTRA_TOOLBAR_DEFAULT);\n    }\n\n    void setClearSelection(boolean clear) {\n        prefs.putBoolean(PROP_CLEAR_SELECTION, clear);\n    }\n\n    public boolean isClearSelection() {\n        return prefs.getBoolean(PROP_CLEAR_SELECTION, true);\n    }\n\n\n    private TracerOptions() {\n        prefs = NbPreferences.forModule(TracerOptions.class);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/options/TracerOptionsCategory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.options;\n\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.icons.TracerIcons;\nimport org.netbeans.spi.options.OptionsCategory;\nimport org.netbeans.spi.options.OptionsPanelController;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TracerOptionsCategory extends OptionsCategory {\n\n    private static TracerOptionsCategory INSTANCE;\n\n\n    public static synchronized TracerOptionsCategory instance() {\n        if (INSTANCE == null) INSTANCE = new TracerOptionsCategory();\n        return INSTANCE;\n    }\n\n    public Icon getIcon() {\n        return Icons.getIcon(TracerIcons.TRACER_32);\n    }\n\n    public String getCategoryName() {\n        return \"Tracer\";\n    }\n\n    public String getTitle() {\n        return \"Tracer\";\n    }\n\n    public OptionsPanelController create() {\n        return new TracerOptionsPanelController();\n    }\n\n    private TracerOptionsCategory() {}\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/options/TracerOptionsPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.options;\n\nimport java.awt.BorderLayout;\nimport java.awt.CardLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.GridLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.AbstractButton;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultListModel;\nimport javax.swing.DefaultListSelectionModel;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComboBox;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.ListCellRenderer;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.border.Border;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.CustomComboRenderer;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.SectionSeparator;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.Spacer;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.VerticalLayout;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TracerOptionsPanel extends JPanel {\n\n    private final TracerOptionsPanelController controller;\n    private boolean internalChange;\n\n\n    TracerOptionsPanel(TracerOptionsPanelController controller) {\n        this.controller = controller;\n        initComponents();\n    }\n\n\n    boolean dataValid() {\n        return true;\n    }\n\n\n    void setProbesApp(int probesApp) {\n        internalChange = true;\n        probesDefaultsCombo.setSelectedIndex(probesApp);\n        internalChange = false;\n    }\n\n    int getProbesApp() {\n        return probesDefaultsCombo.getSelectedIndex();\n    }\n\n    void setRefresh(int refresh) {\n        internalChange = true;\n        refreshCombo.setSelectedItem(refresh);\n        internalChange = false;\n    }\n\n    int getRefresh() {\n        return (Integer)refreshCombo.getSelectedItem();\n    }\n\n    void setRefreshCustomizable(boolean customizable) {\n        refreshCheckBox.setSelected(customizable);\n    }\n\n    boolean isRefreshCustomizable() {\n        return refreshCheckBox.isSelected();\n    }\n\n    void setShowValuesEnabled(boolean showValuesEnabled) {\n        internalChange = true;\n        minMaxValsCombo.setSelectedItem(showValuesEnabled);\n        internalChange = false;\n    }\n\n    boolean isShowValuesEnabled() {\n        return (Boolean)minMaxValsCombo.getSelectedItem();\n    }\n\n    void setShowLegendEnabled(boolean showLegendEnabled) {\n        internalChange = true;\n        rowLegendCombo.setSelectedItem(showLegendEnabled);\n        internalChange = false;\n    }\n\n    boolean isShowLegendEnabled() {\n        return (Boolean)rowLegendCombo.getSelectedItem();\n    }\n\n    void setRowsDecorationEnabled(boolean rowsDecorationEnabled) {\n        internalChange = true;\n        rowsDecorationCombo.setSelectedItem(rowsDecorationEnabled);\n        internalChange = false;\n    }\n\n    boolean isRowsDecorationEnabled() {\n        return (Boolean)rowsDecorationCombo.getSelectedItem();\n    }\n\n    void setRowsSelectionEnabled(boolean rowsSelectionEnabled) {\n        internalChange = true;\n        rowsSelectionCombo.setSelectedIndex(rowsSelectionEnabled ? 0 : 1);\n        internalChange = false;\n    }\n\n    boolean isRowsSelectionEnabled() {\n        return rowsSelectionCombo.getSelectedIndex() == 0;\n    }\n\n    void setTimelineToolbar(int visible) {\n        internalChange = true;\n        timelineToolbarCombo.setSelectedIndex(visible);\n        internalChange = false;\n    }\n\n    int getTimelineToolbar() {\n        return timelineToolbarCombo.getSelectedIndex();\n    }\n\n    void setSelectionToolbar(int visible) {\n        internalChange = true;\n        selectionToolbarCombo.setSelectedIndex(visible);\n        internalChange = false;\n    }\n\n    int getSelectionToolbar() {\n        return selectionToolbarCombo.getSelectedIndex();\n    }\n\n    void setExtraToolbar(int visible) {\n        internalChange = true;\n        extraToolbarCombo.setSelectedIndex(visible);\n        internalChange = false;\n    }\n\n    int getExtraToolbar() {\n        return extraToolbarCombo.getSelectedIndex();\n    }\n\n    void setInitiallyOpened(String opened) {\n        internalChange = true;\n        initialProbesCheckBox.setSelected(\n                opened.contains(TracerOptions.VIEW_PROBES));\n        initialTimelineCheckBox.setSelected(\n                opened.contains(TracerOptions.VIEW_TIMELINE));\n        initialDetailsCheckBox.setSelected(\n                opened.contains(TracerOptions.VIEW_DETAILS));\n        internalChange = false;\n    }\n\n    String getInitiallyOpened() {\n        String result = TracerOptions.VIEWS_UNCHANGED;\n        result = append(result, TracerOptions.VIEW_PROBES,\n               initialProbesCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_TIMELINE,\n               initialTimelineCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_DETAILS,\n               initialDetailsCheckBox.isSelected());\n        return result;\n    }\n\n    void setOnProbeAdded(String opened) {\n        internalChange = true;\n        if (TracerOptions.VIEWS_UNCHANGED.equals(opened)) {\n            onProbeAddedProbesCheckBox.setSelected(false);\n            onProbeAddedTimelineCheckBox.setSelected(false);\n            onProbeAddedDetailsCheckBox.setSelected(false);\n            onProbeAddedNothingCheckBox.setSelected(true);\n        } else {\n            onProbeAddedProbesCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_PROBES));\n            onProbeAddedTimelineCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_TIMELINE));\n            onProbeAddedDetailsCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_DETAILS));\n            onProbeAddedNothingCheckBox.setSelected(false);\n        }\n        internalChange = false;\n    }\n\n    String getOnProbeAdded() {\n        String result = TracerOptions.VIEWS_UNCHANGED;\n        result = append(result, TracerOptions.VIEW_PROBES,\n               onProbeAddedProbesCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_TIMELINE,\n               onProbeAddedTimelineCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_DETAILS,\n               onProbeAddedDetailsCheckBox.isSelected());\n        return result;\n    }\n\n    void setOnProbeAdded2(String opened) {\n        internalChange = true;\n        if (TracerOptions.VIEWS_UNCHANGED.equals(opened)) {\n            onProbeAddedProbesCheckBox2.setSelected(false);\n            onProbeAddedTimelineCheckBox2.setSelected(false);\n            onProbeAddedDetailsCheckBox2.setSelected(false);\n            onProbeAddedNothingCheckBox2.setSelected(true);\n        } else {\n            onProbeAddedProbesCheckBox2.setSelected(\n                    opened.contains(TracerOptions.VIEW_PROBES));\n            onProbeAddedTimelineCheckBox2.setSelected(\n                    opened.contains(TracerOptions.VIEW_TIMELINE));\n            onProbeAddedDetailsCheckBox2.setSelected(\n                    opened.contains(TracerOptions.VIEW_DETAILS));\n            onProbeAddedNothingCheckBox2.setSelected(false);\n        }\n        internalChange = false;\n    }\n\n    String getOnProbeAdded2() {\n        String result = TracerOptions.VIEWS_UNCHANGED;\n        result = append(result, TracerOptions.VIEW_PROBES,\n               onProbeAddedProbesCheckBox2.isSelected());\n        result = append(result, TracerOptions.VIEW_TIMELINE,\n               onProbeAddedTimelineCheckBox2.isSelected());\n        result = append(result, TracerOptions.VIEW_DETAILS,\n               onProbeAddedDetailsCheckBox2.isSelected());\n        return result;\n    }\n\n    void setOnSessionStart(String opened) {\n        internalChange = true;\n        if (TracerOptions.VIEWS_UNCHANGED.equals(opened)) {\n            onStartProbesCheckBox.setSelected(false);\n            onStartTimelineCheckBox.setSelected(false);\n            onStartDetailsCheckBox.setSelected(false);\n            onStartNothingCheckBox.setSelected(true);\n        } else {\n            onStartProbesCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_PROBES));\n            onStartTimelineCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_TIMELINE));\n            onStartDetailsCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_DETAILS));\n            onStartNothingCheckBox.setSelected(false);\n        }\n        internalChange = false;\n    }\n\n    String getOnSessionStart() {\n        String result = TracerOptions.VIEWS_UNCHANGED;\n        result = append(result, TracerOptions.VIEW_PROBES,\n               onStartProbesCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_TIMELINE,\n               onStartTimelineCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_DETAILS,\n               onStartDetailsCheckBox.isSelected());\n        return result;\n    }\n\n    void setOnRowSelected(String opened) {\n        internalChange = true;\n        if (TracerOptions.VIEWS_UNCHANGED.equals(opened)) {\n            onRowSelectedProbesCheckBox.setSelected(false);\n            onRowSelectedTimelineCheckBox.setSelected(false);\n            onRowSelectedDetailsCheckBox.setSelected(false);\n            onRowSelectedNothingCheckBox.setSelected(true);\n        } else {\n            onRowSelectedProbesCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_PROBES));\n            onRowSelectedTimelineCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_TIMELINE));\n            onRowSelectedDetailsCheckBox.setSelected(\n                    opened.contains(TracerOptions.VIEW_DETAILS));\n            onRowSelectedNothingCheckBox.setSelected(false);\n        }\n        internalChange = false;\n    }\n\n    String getOnRowSelected() {\n        String result = TracerOptions.VIEWS_UNCHANGED;\n        result = append(result, TracerOptions.VIEW_PROBES,\n               onRowSelectedProbesCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_TIMELINE,\n               onRowSelectedTimelineCheckBox.isSelected());\n        result = append(result, TracerOptions.VIEW_DETAILS,\n               onRowSelectedDetailsCheckBox.isSelected());\n        return result;\n    }\n\n    void setOnRowSelected2(String opened) {\n        internalChange = true;\n        if (TracerOptions.VIEWS_UNCHANGED.equals(opened)) {\n            onRowSelectedProbesCheckBox2.setSelected(false);\n            onRowSelectedTimelineCheckBox2.setSelected(false);\n            onRowSelectedDetailsCheckBox2.setSelected(false);\n            onRowSelectedNothingCheckBox2.setSelected(true);\n        } else {\n            onRowSelectedProbesCheckBox2.setSelected(\n                    opened.contains(TracerOptions.VIEW_PROBES));\n            onRowSelectedTimelineCheckBox2.setSelected(\n                    opened.contains(TracerOptions.VIEW_TIMELINE));\n            onRowSelectedDetailsCheckBox2.setSelected(\n                    opened.contains(TracerOptions.VIEW_DETAILS));\n            onRowSelectedNothingCheckBox2.setSelected(false);\n        }\n        internalChange = false;\n    }\n\n    String getOnRowSelected2() {\n        String result = TracerOptions.VIEWS_UNCHANGED;\n        result = append(result, TracerOptions.VIEW_PROBES,\n               onRowSelectedProbesCheckBox2.isSelected());\n        result = append(result, TracerOptions.VIEW_TIMELINE,\n               onRowSelectedTimelineCheckBox2.isSelected());\n        result = append(result, TracerOptions.VIEW_DETAILS,\n               onRowSelectedDetailsCheckBox2.isSelected());\n        return result;\n    }\n\n    void setZoomMode(String zoomMode) {\n        internalChange = true;\n        zoomModeCombo.setSelectedIndex(0); // fallback for invalid zoomMode\n        zoomModeCombo.setSelectedItem(zoomMode);\n        internalChange = false;\n    }\n\n    String getZoomMode() {\n        return zoomModeCombo.getSelectedItem().toString();\n    }\n\n    void setMouseWheelAction(String action) {\n        internalChange = true;\n        mouseWheelCombo.setSelectedIndex(0); // fallback for invalid action\n        mouseWheelCombo.setSelectedItem(action);\n        internalChange = false;\n    }\n\n    String getMouseWheelAction() {\n        return mouseWheelCombo.getSelectedItem().toString();\n    }\n    \n    void setClearSelection(boolean clear) {\n        clearSelectionsCheckBox.setSelected(clear);\n    }\n\n    boolean isClearSelection() {\n        return clearSelectionsCheckBox.isSelected();\n    }\n\n\n    private String append(String result, String item, boolean append) {\n        if (!append) return result;\n        if (result.isEmpty()) return item;\n        else return result += \",\" + item; // NOI18N\n    }\n\n    void update() {\n        if (internalChange) return;\n\n        // --- refreshInterval -------------------------------------------------\n        if (refreshCombo.getSelectedIndex() == 0) {\n            refreshCheckBox.setSelected(false);\n            refreshCheckBox.setEnabled(false);\n        } else {\n            refreshCheckBox.setEnabled(true);\n        }\n\n        // --- rowsDecoration --------------------------------------------------\n        if (Utils.forceSpeed()) {\n            rowsDecorationCombo.setSelectedItem(Boolean.FALSE);\n            rowsDecorationCombo.setEnabled(false);\n        }\n\n        // --- initiallyOpened -------------------------------------------------\n        List<AbstractButton> selected = getSelected(initiallyOpenedPanel);\n\n        if (selected.isEmpty()) {\n            // Fallback to defaults\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    setInitiallyOpened(TracerOptions.INITIALLY_OPEN_DEFAULT);\n                    update();\n                }\n            });\n        } else {\n            initialProbesCheckBox.setEnabled(selected.size() > 1 ||\n                    !selected.contains(initialProbesCheckBox));\n            initialTimelineCheckBox.setEnabled(selected.size() > 1 ||\n                    !selected.contains(initialTimelineCheckBox));\n            initialDetailsCheckBox.setEnabled(selected.size() > 1 ||\n                    !selected.contains(initialDetailsCheckBox));\n        }\n\n        // --- onProbeAdded ----------------------------------------------------\n        if (onProbeAddedNothingCheckBox.isSelected()) {\n            onProbeAddedProbesCheckBox.setSelected(false);\n            onProbeAddedProbesCheckBox.setEnabled(false);\n            onProbeAddedTimelineCheckBox.setSelected(false);\n            onProbeAddedTimelineCheckBox.setEnabled(false);\n            onProbeAddedDetailsCheckBox.setSelected(false);\n            onProbeAddedDetailsCheckBox.setEnabled(false);\n        } else {\n            selected = getSelected(onProbeAddedPanel);\n\n            if (selected.isEmpty()) {\n                // Fallback to defaults\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setOnProbeAdded(TracerOptions.PROBE_ADDED_DEFAULT);\n                        update();\n                    }\n                });\n            } else {\n                onProbeAddedProbesCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onProbeAddedProbesCheckBox));\n                onProbeAddedTimelineCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onProbeAddedTimelineCheckBox));\n                onProbeAddedDetailsCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onProbeAddedDetailsCheckBox));\n            }\n        }\n\n        if (onProbeAddedNothingCheckBox2.isSelected()) {\n            onProbeAddedProbesCheckBox2.setSelected(false);\n            onProbeAddedProbesCheckBox2.setEnabled(false);\n            onProbeAddedTimelineCheckBox2.setSelected(false);\n            onProbeAddedTimelineCheckBox2.setEnabled(false);\n            onProbeAddedDetailsCheckBox2.setSelected(false);\n            onProbeAddedDetailsCheckBox2.setEnabled(false);\n        } else {\n            selected = getSelected(onProbeAddedPanel2);\n\n            if (selected.isEmpty()) {\n                // Fallback to defaults\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setOnProbeAdded2(TracerOptions.PROBE_ADDED_DEFAULT2);\n                        update();\n                    }\n                });\n            } else {\n                onProbeAddedProbesCheckBox2.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onProbeAddedProbesCheckBox2));\n                onProbeAddedTimelineCheckBox2.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onProbeAddedTimelineCheckBox2));\n                onProbeAddedDetailsCheckBox2.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onProbeAddedDetailsCheckBox2));\n            }\n        }\n\n        // --- onStart ---------------------------------------------------------\n        if (onStartNothingCheckBox.isSelected()) {\n            onStartProbesCheckBox.setSelected(false);\n            onStartProbesCheckBox.setEnabled(false);\n            onStartTimelineCheckBox.setSelected(false);\n            onStartTimelineCheckBox.setEnabled(false);\n            onStartDetailsCheckBox.setSelected(false);\n            onStartDetailsCheckBox.setEnabled(false);\n        } else {\n            selected = getSelected(onStartOpenedPanel);\n\n            if (selected.isEmpty()) {\n                // Fallback to defaults\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setOnSessionStart(TracerOptions.SESSION_STARTED_DEFAULT);\n                        update();\n                    }\n                });\n            } else {\n                onStartProbesCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onStartProbesCheckBox));\n                onStartTimelineCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onStartTimelineCheckBox));\n                onStartDetailsCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onStartDetailsCheckBox));\n            }\n        }\n\n        // --- onRowSelected ---------------------------------------------------\n        if (onRowSelectedNothingCheckBox.isSelected()) {\n            onRowSelectedProbesCheckBox.setSelected(false);\n            onRowSelectedProbesCheckBox.setEnabled(false);\n            onRowSelectedTimelineCheckBox.setSelected(false);\n            onRowSelectedTimelineCheckBox.setEnabled(false);\n            onRowSelectedDetailsCheckBox.setSelected(false);\n            onRowSelectedDetailsCheckBox.setEnabled(false);\n        } else {\n            selected = getSelected(onRowSelectedPanel);\n\n            if (selected.isEmpty()) {\n                // Fallback to defaults\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setOnRowSelected(TracerOptions.ROW_SELECTED_DEFAULT);\n                        update();\n                    }\n                });\n            } else {\n                onRowSelectedProbesCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onRowSelectedProbesCheckBox));\n                onRowSelectedTimelineCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onRowSelectedTimelineCheckBox));\n                onRowSelectedDetailsCheckBox.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onRowSelectedDetailsCheckBox));\n            }\n        }\n\n        if (onRowSelectedNothingCheckBox2.isSelected()) {\n            onRowSelectedProbesCheckBox2.setSelected(false);\n            onRowSelectedProbesCheckBox2.setEnabled(false);\n            onRowSelectedTimelineCheckBox2.setSelected(false);\n            onRowSelectedTimelineCheckBox2.setEnabled(false);\n            onRowSelectedDetailsCheckBox2.setSelected(false);\n            onRowSelectedDetailsCheckBox2.setEnabled(false);\n        } else {\n            selected = getSelected(onRowSelectedPanel2);\n\n            if (selected.isEmpty()) {\n                // Fallback to defaults\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setOnRowSelected2(TracerOptions.ROW_SELECTED_DEFAULT2);\n                        update();\n                    }\n                });\n            } else {\n                onRowSelectedProbesCheckBox2.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onRowSelectedProbesCheckBox2));\n                onRowSelectedTimelineCheckBox2.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onRowSelectedTimelineCheckBox2));\n                onRowSelectedDetailsCheckBox2.setEnabled(selected.size() > 1 ||\n                        !selected.contains(onRowSelectedDetailsCheckBox2));\n            }\n        }\n\n        controller.changed();\n    }\n\n    private List<AbstractButton> getSelected(JPanel container) {\n        List<AbstractButton> selected = new ArrayList<>();\n        for (Component c : container.getComponents())\n            if (c instanceof AbstractButton && ((AbstractButton)c).isSelected())\n                selected.add((AbstractButton)c);\n        return selected;\n    }\n\n\n    private void initComponents() {\n        setLayout(new GridBagLayout());\n\n        GridBagConstraints c;\n\n        // probesDefaultsSeparator\n        SectionSeparator probesDefaultsSeparator =\n                new SectionSeparator(\"Probes Settings\"); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 0;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 5, 0);\n        add(probesDefaultsSeparator, c);\n\n        JLabel probesDefaultsLabel = new JLabel(\"Initial appearance:\");\n        c.gridx = 0;\n        c.gridy = 1;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(probesDefaultsLabel, c);\n\n        // probesDefaultsCombo\n        probesDefaultsCombo = new JComboBox(new String[] { \"first expanded\",\n                                                           \"all expanded\",\n                                                           \"all collapsed\" }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        probesDefaultsLabel.setLabelFor(probesDefaultsCombo);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 1;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(probesDefaultsCombo, c);\n\n        // timelineDefaultsSeparator\n        SectionSeparator timelineDefaultsSeparator =\n                new SectionSeparator(\"Timeline Settings\"); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 2;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(15, 0, 5, 0);\n        add(timelineDefaultsSeparator, c);\n\n        JLabel refreshRateLabel = new JLabel(\"Sampling frequency:\");\n        c.gridx = 0;\n        c.gridy = 3;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(refreshRateLabel, c);\n\n        Integer[] refreshRates = new Integer[] { -1, 100, 200, 500, 1000, 2000, 5000, 10000 };\n        refreshCombo = new JComboBox(refreshRates)  {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        refreshRateLabel.setLabelFor(refreshCombo);\n        refreshCombo.setRenderer(new CustomComboRenderer.Number(refreshCombo, \"ms\", true));\n        refreshCombo.setEditable(false);\n        c.gridx = 1;\n        c.gridy = 3;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(refreshCombo, c);\n\n        refreshCheckBox = new JCheckBox(\"Customizable in Tracer tab\") {\n            public Dimension getPreferredSize() {\n                Dimension d = super.getPreferredSize();\n                d.height = Math.min(d.height, refreshCombo.getPreferredSize().height);\n                return d;\n            }\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n        c.gridx = 2;\n        c.gridy = 3;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(refreshCheckBox, c);\n\n        // zoomModeLabel\n        JLabel zoomModeLabel = new JLabel(\"Zoom mode:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 4;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(zoomModeLabel, c);\n\n        // zoomModeCombo\n        zoomModeCombo = new JComboBox(new String[] {\n                                          TracerOptions.FIXED_SCALE,\n                                          TracerOptions.SCALE_TO_FIT }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        zoomModeLabel.setLabelFor(zoomModeCombo);\n        zoomModeCombo.setRenderer(new CustomComboRenderer.String(zoomModeCombo));\n        zoomModeCombo.setEditable(false);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 4;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(zoomModeCombo, c);\n\n        // customizableZoomModeLabel\n        JLabel customizableZoomModeLabel = new JLabel(\"Customizable in Tracer tab\");\n        customizableZoomModeLabel.setEnabled(false);\n        c.gridx = 2;\n        c.gridy = 4;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 9, 3, 0);\n        add(customizableZoomModeLabel, c);\n\n        // mouseWheelLabel\n        JLabel mouseWheelLabel = new JLabel(\"Mouse wheel action:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 5;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(mouseWheelLabel, c);\n\n        // mouseWheelCombo\n        mouseWheelCombo = new JComboBox(new String[] {\n                                          TracerOptions.MOUSE_WHEEL_ZOOMS,\n                                          TracerOptions.MOUSE_WHEEL_HSCROLLS,\n                                          TracerOptions.MOUSE_WHEEL_VSCROLLS }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        mouseWheelLabel.setLabelFor(mouseWheelCombo);\n        mouseWheelCombo.setRenderer(new CustomComboRenderer.String(mouseWheelCombo));\n        mouseWheelCombo.setEditable(false);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 5;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(mouseWheelCombo, c);\n\n        // customizableMouseWheelLabel\n        JLabel customizableMouseWheelLabel = new JLabel(\"Customizable in Tracer tab\");\n        customizableMouseWheelLabel.setEnabled(false);\n        c.gridx = 2;\n        c.gridy = 5;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 9, 3, 0);\n        add(customizableMouseWheelLabel, c);\n\n\n        // timelineAppearanceSeparator\n        SectionSeparator timelineAppearanceSeparator =\n                new SectionSeparator(\"Timeline Appearance\"); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 6;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(15, 0, 5, 0);\n        add(timelineAppearanceSeparator, c);\n\n        // minMaxValsLabel\n        JLabel minMaxValsLabel = new JLabel(\"Show min/max values:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 7;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(minMaxValsLabel, c);\n\n        // minMaxValsCombo\n        minMaxValsCombo = new JComboBox(new Boolean[] { Boolean.TRUE,\n                                                        Boolean.FALSE }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n        minMaxValsLabel.setLabelFor(minMaxValsCombo);\n        minMaxValsCombo.setRenderer(new CustomComboRenderer.Boolean(minMaxValsCombo));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 7;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(minMaxValsCombo, c);\n\n        // customizableMinMaxValsLabel\n        JLabel customizableMinMaxValsLabel = new JLabel(\"Customizable in Tracer tab\");\n        customizableMinMaxValsLabel.setEnabled(false);\n        c.gridx = 2;\n        c.gridy = 7;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 9, 3, 0);\n        add(customizableMinMaxValsLabel, c);\n\n        // rowLegendLabel\n        JLabel rowLegendLabel = new JLabel(\"Show row legend:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 8;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(rowLegendLabel, c);\n\n        // rowLegendCombo\n        rowLegendCombo = new JComboBox(new Boolean[] { Boolean.TRUE,\n                                                       Boolean.FALSE }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n        rowLegendLabel.setLabelFor(rowLegendCombo);\n        rowLegendCombo.setRenderer(new CustomComboRenderer.Boolean(rowLegendCombo));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 8;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(rowLegendCombo, c);\n\n        // customizableRowLegendLabel\n        JLabel customizableRowLegendLabel = new JLabel(\"Customizable in Tracer tab\");\n        customizableRowLegendLabel.setEnabled(false);\n        c.gridx = 2;\n        c.gridy = 8;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 9, 3, 0);\n        add(customizableRowLegendLabel, c);\n\n        // rowsDecorationLabel\n        JLabel rowsDecorationLabel = new JLabel(\"Rows decoration:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 9;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(rowsDecorationLabel, c);\n\n        // rowsDecorationCombo\n        rowsDecorationCombo = new JComboBox(new Boolean[] { Boolean.TRUE,\n                                                            Boolean.FALSE }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n        rowsDecorationLabel.setLabelFor(rowsDecorationCombo);\n        rowsDecorationCombo.setRenderer(new CustomComboRenderer.Boolean(rowsDecorationCombo));\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 9;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(rowsDecorationCombo, c);\n\n        // rowsSelectionLabel\n        JLabel rowsSelectionLabel = new JLabel(\"Rows selection:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 10;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(rowsSelectionLabel, c);\n\n        // rowsSelectionCombo\n        rowsSelectionCombo = new JComboBox(new String[] { \"panel and chart\",\n                                                          \"panel only\" }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n        rowsSelectionLabel.setLabelFor(rowsSelectionCombo);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 10;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(rowsSelectionCombo, c);\n\n\n        // toolbarsBehaviorSeparator\n        SectionSeparator toolbarsBehaviorSeparator =\n                new SectionSeparator(\"Toolbars Behavior\"); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 11;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(15, 0, 5, 0);\n        add(toolbarsBehaviorSeparator, c);\n\n        // minMaxValsLabel\n        JLabel timelineToolbarLabel = new JLabel(\"Timeline toolbar:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 12;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(timelineToolbarLabel, c);\n\n        // timelineToolbarCombo\n        timelineToolbarCombo = new JComboBox(new String[] { \"always visible\",\n                                                            \"show with timeline\" }) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        timelineToolbarLabel.setLabelFor(timelineToolbarCombo);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 12;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(timelineToolbarCombo, c);\n\n        // selectionToolbarLabel\n        JLabel selectionToolbarLabel = new JLabel(\"Selection toolbar:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 13;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(selectionToolbarLabel, c);\n\n        // rowLegendCombo\n        selectionToolbarCombo = new JComboBox(new String[] { \"always visible\",\n                                                             \"show on selection\",\n                                                             \"always hidden\"}) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        selectionToolbarLabel.setLabelFor(selectionToolbarCombo);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 13;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(selectionToolbarCombo, c);\n\n        // extraToolbarLabel\n        JLabel extraToolbarLabel = new JLabel(\"Export toolbar:\");\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 14;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.NONE;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(extraToolbarLabel, c);\n\n        // extraToolbarCombo\n        extraToolbarCombo = new JComboBox(new String[] { \"always visible\",\n                                                          \"show on data\",\n                                                          \"always hidden\"}) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void selectedItemChanged() {\n                TracerOptionsPanel.this.update();\n                super.selectedItemChanged();\n            }\n        };\n        extraToolbarLabel.setLabelFor(extraToolbarCombo);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 14;\n        c.gridwidth = 1;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.anchor = GridBagConstraints.WEST;\n        c.insets = new Insets(3, 5, 3, 0);\n        add(extraToolbarCombo, c);\n\n\n        // viewsBehaviorSeparator\n        SectionSeparator viewsBehaviorSeparator =\n                new SectionSeparator(\"Views Behavior\"); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 15;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(15, 0, 5, 0);\n        add(viewsBehaviorSeparator, c);\n\n        // viewsBehaviorPanel\n        JPanel viewsBehaviorPanel = new JPanel(new BorderLayout(0, 0));\n        viewsBehaviorPanel.setOpaque(false);\n        c = new GridBagConstraints();\n        c.gridy = 16;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(8, 15, 0, 0);\n        add(viewsBehaviorPanel, c);\n\n        final CardLayout viewsSettingsLayout = new CardLayout();\n        final JPanel viewsSettingsContainer = new JPanel(viewsSettingsLayout);\n        final String INITIALLY_OPEN = \"Initial appearance\";\n        final String OPEN_PROBE_ADDED = \"Probe added or removed\";\n        final String OPEN_SESSION_STARTS = \"Session started\";\n        final String OPEN_ROW_SELECTED = \"Row selected or unselected\";\n\n        final DefaultListModel connectionTypeListModel = new DefaultListModel();\n        connectionTypeListModel.addElement(INITIALLY_OPEN);\n        connectionTypeListModel.addElement(OPEN_PROBE_ADDED);\n        connectionTypeListModel.addElement(OPEN_SESSION_STARTS);\n        connectionTypeListModel.addElement(OPEN_ROW_SELECTED);\n\n        JList connectionTypeList = new JList(connectionTypeListModel);\n        connectionTypeList.setVisibleRowCount(connectionTypeListModel.getSize());\n\n        connectionTypeList.setSelectionModel(new DefaultListSelectionModel() {\n            public void setSelectionInterval(int index0, int index1) {\n                super.setSelectionInterval(index0, index1);\n                viewsSettingsLayout.show(viewsSettingsContainer, connectionTypeListModel.get(getMinSelectionIndex()).toString());\n            }\n            public void removeSelectionInterval(int i1, int i2) {}\n        });\n        connectionTypeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        connectionTypeList.setSelectedIndex(0);\n        final ListCellRenderer defaultRenderer = connectionTypeList.getCellRenderer();\n        Component rc = defaultRenderer.getListCellRendererComponent(connectionTypeList, \"X\", 0, false, false); // NOI18N\n        connectionTypeList.setFixedCellHeight(rc.getPreferredSize().height + 2);\n        connectionTypeList.setCellRenderer(new ListCellRenderer() {\n            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {\n                return defaultRenderer.getListCellRendererComponent(list, \" \" + value + \" \", index, isSelected, cellHasFocus); // NOI18N\n            }\n        });\n        JScrollPane connectionTypeScroll = new JScrollPane(connectionTypeList,\n                                    JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                                    JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) {\n            public Dimension getMinimumSize() { return getPreferredSize(); }\n        };\n        createBorder(connectionTypeScroll, BorderFactory.createEmptyBorder(0, 0, 0, 10));\n        viewsBehaviorPanel.add(connectionTypeScroll, BorderLayout.WEST);\n        viewsBehaviorPanel.add(viewsSettingsContainer, BorderLayout.CENTER);\n\n\n        // initiallyOpenedPanel\n        initiallyOpenedPanel = new JPanel(new VerticalLayout(false));\n        initiallyOpenedPanel.setBorder(titledBorder(\"Select the views to open:\"));\n        initiallyOpenedPanel.setOpaque(false);\n        // initialProbesCheckBox\n        initialProbesCheckBox = new JCheckBox(\"Probes\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        initiallyOpenedPanel.add(initialProbesCheckBox);\n        // initialTimelineCheckBox\n        initialTimelineCheckBox = new JCheckBox(\"Timeline\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        initiallyOpenedPanel.add(initialTimelineCheckBox);\n        // initialDetailsCheckBox\n        initialDetailsCheckBox = new JCheckBox(\"Details\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        initiallyOpenedPanel.add(initialDetailsCheckBox);\n        viewsSettingsContainer.add(initiallyOpenedPanel, INITIALLY_OPEN);\n\n        // onProbeAddedPanel\n        onProbeAddedPanel = new JPanel(new VerticalLayout(false));\n        onProbeAddedPanel.setBorder(titledBorder(\"Open for selected probes:\"));\n        onProbeAddedPanel.setOpaque(false);\n        // initialProbesCheckBox\n        onProbeAddedProbesCheckBox = new JCheckBox(\"Probes\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel.add(onProbeAddedProbesCheckBox);\n        // initialTimelineCheckBox\n        onProbeAddedTimelineCheckBox = new JCheckBox(\"Timeline\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel.add(onProbeAddedTimelineCheckBox);\n        // initialDetailsCheckBox\n        onProbeAddedDetailsCheckBox = new JCheckBox(\"Details\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel.add(onProbeAddedDetailsCheckBox);\n        // onStartNothingCheckBox\n        onProbeAddedNothingCheckBox = new JCheckBox(\"No change\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel.add(onProbeAddedNothingCheckBox);\n\n\n        // onProbeAddedPanel2\n        onProbeAddedPanel2 = new JPanel(new VerticalLayout(false));\n        onProbeAddedPanel2.setBorder(titledBorder(\"Open for no selection:\"));\n        onProbeAddedPanel2.setOpaque(false);\n        // initialProbesCheckBox2\n        onProbeAddedProbesCheckBox2 = new JCheckBox(\"Probes\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel2.add(onProbeAddedProbesCheckBox2);\n        // initialTimelineCheckBox2\n        onProbeAddedTimelineCheckBox2 = new JCheckBox(\"Timeline\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel2.add(onProbeAddedTimelineCheckBox2);\n        // onProbeAddedDetailsCheckBox2\n        onProbeAddedDetailsCheckBox2 = new JCheckBox(\"Details\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel2.add(onProbeAddedDetailsCheckBox2);\n        // onProbeAddedNothingCheckBox2\n        onProbeAddedNothingCheckBox2 = new JCheckBox(\"No change\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onProbeAddedPanel2.add(onProbeAddedNothingCheckBox2);\n\n        JPanel onProbeAddedContainer = new JPanel(new GridLayout(1, 2));\n        onProbeAddedContainer.add(onProbeAddedPanel);\n        onProbeAddedContainer.add(onProbeAddedPanel2);\n        viewsSettingsContainer.add(onProbeAddedContainer, OPEN_PROBE_ADDED);\n\n        // onStartOpenedPanel\n        onStartOpenedPanel = new JPanel(new VerticalLayout(false));\n        onStartOpenedPanel.setBorder(titledBorder(\"Select the views to open:\"));\n        onStartOpenedPanel.setOpaque(false);\n        // initialProbesCheckBox\n        onStartProbesCheckBox = new JCheckBox(\"Probes\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onStartOpenedPanel.add(onStartProbesCheckBox);\n        // initialTimelineCheckBox\n        onStartTimelineCheckBox = new JCheckBox(\"Timeline\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onStartOpenedPanel.add(onStartTimelineCheckBox);\n        // initialDetailsCheckBox\n        onStartDetailsCheckBox = new JCheckBox(\"Details\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onStartOpenedPanel.add(onStartDetailsCheckBox);\n        // onStartNothingCheckBox\n        onStartNothingCheckBox = new JCheckBox(\"No change\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onStartOpenedPanel.add(onStartNothingCheckBox);\n        viewsSettingsContainer.add(onStartOpenedPanel, OPEN_SESSION_STARTS);\n\n        // onRowSelectedPanel\n        onRowSelectedPanel = new JPanel(new VerticalLayout(false));\n        onRowSelectedPanel.setBorder(titledBorder(\"Open for selected rows:\"));\n        onRowSelectedPanel.setOpaque(false);\n        // initialProbesCheckBox\n        onRowSelectedProbesCheckBox = new JCheckBox(\"Probes\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel.add(onRowSelectedProbesCheckBox);\n        // initialTimelineCheckBox\n        onRowSelectedTimelineCheckBox = new JCheckBox(\"Timeline\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel.add(onRowSelectedTimelineCheckBox);\n        // initialDetailsCheckBox\n        onRowSelectedDetailsCheckBox = new JCheckBox(\"Details\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel.add(onRowSelectedDetailsCheckBox);\n        // onStartNothingCheckBox\n        onRowSelectedNothingCheckBox = new JCheckBox(\"No change\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel.add(onRowSelectedNothingCheckBox);\n\n\n        // onRowSelectedPanel2\n        onRowSelectedPanel2 = new JPanel(new VerticalLayout(false));\n        onRowSelectedPanel2.setBorder(titledBorder(\"Open for no selection:\"));\n        onRowSelectedPanel2.setOpaque(false);\n        // initialProbesCheckBox2\n        onRowSelectedProbesCheckBox2 = new JCheckBox(\"Probes\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel2.add(onRowSelectedProbesCheckBox2);\n        // initialTimelineCheckBox2\n        onRowSelectedTimelineCheckBox2 = new JCheckBox(\"Timeline\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel2.add(onRowSelectedTimelineCheckBox2);\n        // onProbeAddedDetailsCheckBox2\n        onRowSelectedDetailsCheckBox2 = new JCheckBox(\"Details\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel2.add(onRowSelectedDetailsCheckBox2);\n        // onProbeAddedNothingCheckBox2\n        onRowSelectedNothingCheckBox2 = new JCheckBox(\"No change\") {\n            protected void fireActionPerformed(ActionEvent e) {\n                TracerOptionsPanel.this.update();\n            }\n        };\n        onRowSelectedPanel2.add(onRowSelectedNothingCheckBox2);\n\n        JPanel onRowSelectedContainer = new JPanel(new GridLayout(1, 2));\n        onRowSelectedContainer.add(onRowSelectedPanel);\n        onRowSelectedContainer.add(onRowSelectedPanel2);\n        viewsSettingsContainer.add(onRowSelectedContainer, OPEN_ROW_SELECTED);\n\n        // clearSelectionsCheckBox\n        clearSelectionsCheckBox = new JCheckBox(\"Clear selected rows when closing Details view\") {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n        };\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 17;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.insets = new Insets(8, 15, 0, 0);\n        add(clearSelectionsCheckBox, c);\n\n\n        // bottomFiller\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 100;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        add(Spacer.create(), c);\n    }\n\n\n    private JComboBox probesDefaultsCombo;\n    private JComboBox refreshCombo;\n    private JCheckBox refreshCheckBox;\n    private JComboBox minMaxValsCombo;\n    private JComboBox rowLegendCombo;\n    private JComboBox rowsDecorationCombo;\n    private JComboBox rowsSelectionCombo;\n    private JComboBox timelineToolbarCombo;\n    private JComboBox selectionToolbarCombo;\n    private JComboBox extraToolbarCombo;\n    private JPanel initiallyOpenedPanel;\n    private JCheckBox initialProbesCheckBox;\n    private JCheckBox initialTimelineCheckBox;\n    private JCheckBox initialDetailsCheckBox;\n    private JPanel onProbeAddedPanel;\n    private JCheckBox onProbeAddedProbesCheckBox;\n    private JCheckBox onProbeAddedTimelineCheckBox;\n    private JCheckBox onProbeAddedDetailsCheckBox;\n    private JCheckBox onProbeAddedNothingCheckBox;\n    private JPanel onProbeAddedPanel2;\n    private JCheckBox onProbeAddedProbesCheckBox2;\n    private JCheckBox onProbeAddedTimelineCheckBox2;\n    private JCheckBox onProbeAddedDetailsCheckBox2;\n    private JCheckBox onProbeAddedNothingCheckBox2;\n    private JPanel onStartOpenedPanel;\n    private JCheckBox onStartProbesCheckBox;\n    private JCheckBox onStartTimelineCheckBox;\n    private JCheckBox onStartDetailsCheckBox;\n    private JCheckBox onStartNothingCheckBox;\n    private JPanel onRowSelectedPanel;\n    private JCheckBox onRowSelectedProbesCheckBox;\n    private JCheckBox onRowSelectedTimelineCheckBox;\n    private JCheckBox onRowSelectedDetailsCheckBox;\n    private JCheckBox onRowSelectedNothingCheckBox;\n    private JPanel onRowSelectedPanel2;\n    private JCheckBox onRowSelectedProbesCheckBox2;\n    private JCheckBox onRowSelectedTimelineCheckBox2;\n    private JCheckBox onRowSelectedDetailsCheckBox2;\n    private JCheckBox onRowSelectedNothingCheckBox2;\n    private JCheckBox clearSelectionsCheckBox;\n\n    private JComboBox zoomModeCombo;\n    private JComboBox mouseWheelCombo;\n\n\n    private static Border titledBorder(String title) {\n        String titleBorder = UIUtils.isWindowsLookAndFeel() ? \" \" : \"\"; //NOI18N\n        Border inner = BorderFactory.createEmptyBorder(0, 12, 3, 3);\n        Border outer = BorderFactory.createTitledBorder(titleBorder + title);\n        return BorderFactory.createCompoundBorder(outer, inner);\n    }\n\n    private static void createBorder(JComponent component, Border border) {\n        Border cBorder = component.getBorder();\n        if (cBorder == null) component.setBorder(border);\n        else component.setBorder(BorderFactory.createCompoundBorder(border, cBorder));\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/options/TracerOptionsPanelController.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.options;\n\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JScrollPane;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.ScrollableContainer;\nimport org.netbeans.spi.options.OptionsPanelController;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TracerOptionsPanelController extends OptionsPanelController {\n\n    private TracerOptions options = TracerOptions.getInstance();\n    private TracerOptionsPanel panel;\n    private JComponent component;\n    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);\n    private boolean changed;\n\n\n    public void update() {\n        TracerOptionsPanel p = getPanel();\n\n        p.setProbesApp(options.getProbesApp());\n\n        p.setRefresh(options.getRefresh());\n        p.setRefreshCustomizable(options.isRefreshCustomizable());\n\n        p.setShowValuesEnabled(options.isShowValuesEnabled());\n        p.setShowLegendEnabled(options.isShowLegendEnabled());\n        p.setRowsDecorationEnabled(options.isRowsDecorationEnabled());\n        p.setRowsSelectionEnabled(options.isRowsSelectionEnabled());\n\n        p.setInitiallyOpened(options.getInitiallyOpened());\n        p.setOnProbeAdded(options.getOnProbeAdded());\n        p.setOnProbeAdded2(options.getOnProbeAdded2());\n        p.setOnSessionStart(options.getOnSessionStart());\n        p.setOnRowSelected(options.getOnRowSelected());\n        p.setOnRowSelected2(options.getOnRowSelected2());\n\n        p.setZoomMode(options.getZoomMode());\n        p.setMouseWheelAction(options.getMouseWheelAction());\n\n        p.setTimelineToolbar(options.getTimelineToolbar());\n        p.setSelectionToolbar(options.getSelectionToolbar());\n        p.setExtraToolbar(options.getExtraToolbar());\n\n        p.setClearSelection(options.isClearSelection());\n\n        p.update();\n    }\n\n    public void applyChanges() {\n        TracerOptionsPanel p = getPanel();\n\n        options.setProbesApp(p.getProbesApp());\n\n        options.setRefresh(p.getRefresh());\n        options.setRefreshCustomizable(p.isRefreshCustomizable());\n\n        options.setShowValuesEnabled(p.isShowValuesEnabled());\n        options.setShowLegendEnabled(p.isShowLegendEnabled());\n        options.setRowsDecorationEnabled(p.isRowsDecorationEnabled());\n        options.setRowsSelectionEnabled(p.isRowsSelectionEnabled());\n\n        options.setInitiallyOpened(p.getInitiallyOpened());\n        options.setOnProbeAdded(p.getOnProbeAdded());\n        options.setOnProbeAdded2(p.getOnProbeAdded2());\n        options.setOnSessionStart(p.getOnSessionStart());\n        options.setOnRowSelected(p.getOnRowSelected());\n        options.setOnRowSelected2(p.getOnRowSelected2());\n\n        options.setZoomMode(p.getZoomMode());\n        options.setMouseWheelAction(p.getMouseWheelAction());\n\n        options.setTimelineToolbar(p.getTimelineToolbar());\n        options.setSelectionToolbar(p.getSelectionToolbar());\n        options.setExtraToolbar(p.getExtraToolbar());\n\n        options.setClearSelection(p.isClearSelection());\n    }\n\n    public void cancel() {}\n\n    public boolean isValid() {\n        return getPanel().dataValid();\n    }\n\n    public boolean isChanged() {\n        TracerOptionsPanel p = getPanel();\n\n        if (options.getProbesApp() != p.getProbesApp()) return true;\n\n        if (options.getRefresh() != p.getRefresh()) return true;\n        if (options.isRefreshCustomizable() != p.isRefreshCustomizable()) return true;\n\n        if (options.isShowValuesEnabled() != p.isShowValuesEnabled()) return true;\n        if (options.isShowLegendEnabled() != p.isShowLegendEnabled()) return true;\n        if (options.isRowsDecorationEnabled() != p.isRowsDecorationEnabled()) return true;\n        if (options.isRowsSelectionEnabled() != p.isRowsSelectionEnabled()) return true;\n\n        if (!options.getInitiallyOpened().equals(p.getInitiallyOpened())) return true;\n        if (!options.getOnProbeAdded().equals(p.getOnProbeAdded())) return true;\n        if (!options.getOnProbeAdded2().equals(p.getOnProbeAdded2())) return true;\n        if (!options.getOnSessionStart().equals(p.getOnSessionStart())) return true;\n        if (!options.getOnRowSelected().equals(p.getOnRowSelected())) return true;\n        if (!options.getOnRowSelected2().equals(p.getOnRowSelected2())) return true;\n\n        if (!options.getZoomMode().equals(p.getZoomMode())) return true;\n        if (!options.getMouseWheelAction().equals(p.getMouseWheelAction())) return true;\n\n        if (options.getTimelineToolbar() != p.getTimelineToolbar()) return true;\n        if (options.getSelectionToolbar() != p.getSelectionToolbar()) return true;\n        if (options.getExtraToolbar() != p.getExtraToolbar()) return true;\n\n        if (options.isClearSelection() != p.isClearSelection()) return true;\n\n        return false;\n    }\n\n\n    public HelpCtx getHelpCtx() {\n        return null;\n\n    }\n\n\n    public JComponent getComponent(Lookup masterLookup) {\n        return getComponent();\n    }\n\n    public void addPropertyChangeListener(PropertyChangeListener l) {\n        pcs.addPropertyChangeListener(l);\n    }\n\n    public void removePropertyChangeListener(PropertyChangeListener l) {\n        pcs.removePropertyChangeListener(l);\n    }\n\n\n    private TracerOptionsPanel getPanel() {\n        if (panel == null) panel = new TracerOptionsPanel(this);\n        return panel;\n    }\n\n    private JComponent getComponent() {\n        if (component == null) {\n            ScrollableContainer container = new ScrollableContainer(getPanel(),\n                                        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                                        JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);\n            container.setViewportBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));\n            container.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 5));\n            component = container;\n        }\n        return component;\n    }\n\n    void changed() {\n        if (!changed) {\n            changed = true;\n            pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);\n        }\n        pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/packages/TestPackage.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.packages;\n\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerPackage;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProbe;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.IdeSnapshot;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass TestPackage extends TracerPackage {\n\n    private TracerProbeDescriptor descriptor1;\n    private TracerProbeDescriptor descriptor2;\n    private TracerProbe probe1;\n    private TracerProbe probe2;\n\n    private IdeSnapshot snapshot;\n\n\n    TestPackage(IdeSnapshot snapshot) {\n        super(\"Test Package\", \"Package for testing purposes\", null, 1);\n        this.snapshot = snapshot;\n    }\n\n\n    public TracerProbeDescriptor[] getProbeDescriptors() {\n        if (snapshot.hasUiGestures()) {\n            descriptor1 = new TracerProbeDescriptor(\"UI Actions\", \"Shows UI actions performed by the user in the IDE\", null, 1, true);\n            descriptor2 = new TracerProbeDescriptor(\"Stack depth\", \"Reports the cumulative depth of all running threads\", null, 2, true);\n            return new TracerProbeDescriptor[] { descriptor1, descriptor2, };\n        } else {\n            descriptor2 = new TracerProbeDescriptor(\"Stack depth\", \"Reports the cumulative depth of all running threads\", null, 2, true);\n            return new TracerProbeDescriptor[] { descriptor2, };\n        }\n    }\n\n    public TracerProbe getProbe(TracerProbeDescriptor descriptor) {\n        if (descriptor == descriptor1) {\n            if (probe1 == null) probe1 = new UiGesturesProbe(snapshot);\n            return probe1;\n        } else if (descriptor == descriptor2) {\n            if (probe2 == null) probe2 = new TestProbe(snapshot);\n            return probe2;\n        } else {\n            return null;\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/packages/TestPackageProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.packages;\n\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerPackage;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerPackageProvider;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.IdeSnapshot;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class TestPackageProvider extends TracerPackageProvider {\n\n    public TestPackageProvider() {\n        super(Object.class);\n    }\n\n    public TracerPackage[] getPackages(IdeSnapshot snapshot) {\n        return new TestPackage[] { new TestPackage(snapshot) };\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/packages/TestProbe.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.packages;\n\nimport java.io.IOException;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ItemValueFormatter;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProbe;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.IdeSnapshot;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass TestProbe extends TracerProbe {\n\n//    private int items;\n    private IdeSnapshot snapshot;\n\n\n    TestProbe(IdeSnapshot snapshot) {\n        super(descriptors(1));\n        this.snapshot = snapshot;\n//        this.items = items;\n    }\n\n    public long[] getItemValues(int sampleIndex) {\n        return values(sampleIndex);\n    }\n\n\n    private static ProbeItemDescriptor[] descriptors(int items) {\n        ProbeItemDescriptor[] descriptors = new ProbeItemDescriptor[items];\n        descriptors[0] = ProbeItemDescriptor.continuousLineItem(\"Cumulative stack depth\",\n                             \"Reports the cumulative depth of all running threads\", ItemValueFormatter.DEFAULT_DECIMAL);\n//        for (int i = 0; i < descriptors.length; i++)\n//            descriptors[i] = ProbeItemDescriptor.continuousLineItem(\"Item \" + i,\n//                             \"Description \" + i, ItemValueFormatter.SIMPLE);\n        return descriptors;\n    }\n\n    private long[] values(int sampleIndex) {\n        long[] values = new long[1];\n        try {\n            values[0] = snapshot.getValue(sampleIndex, 0);\n        } catch (IOException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n//        for (int i = 0; i < values.length; i++)\n//            values[i] = (long)(Math.random() * 10000);\n        return values;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/packages/UiGesturesProbe.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.packages;\n\nimport java.io.IOException;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ItemValueFormatter;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProbe;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.IdeSnapshot;\nimport org.openide.util.Exceptions;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass UiGesturesProbe extends TracerProbe {\n\n    private IdeSnapshot snapshot;\n\n\n    UiGesturesProbe(IdeSnapshot snapshot) {\n        super(descriptors(1, snapshot));\n        this.snapshot = snapshot;\n    }\n\n    public long[] getItemValues(int sampleIndex) {\n        return values(sampleIndex);\n    }\n\n\n    private static ProbeItemDescriptor[] descriptors(int items, IdeSnapshot snapshot) {\n        ProbeItemDescriptor[] descriptors = new ProbeItemDescriptor[items];\n        descriptors[0] = ProbeItemDescriptor.iconItem(\"UI Gesture\",\n                             \"Shows UI actions performed by the user in the IDE\",\n                             new UiGesturesFormatter(snapshot));\n        return descriptors;\n    }\n\n    private long[] values(int sampleIndex) {\n        long[] values = new long[1];\n        try {\n            values[0] = snapshot.getValue(sampleIndex, 1);\n        } catch (IOException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n        return values;\n    }\n\n\n    private static class UiGesturesFormatter extends ItemValueFormatter {\n\n        private IdeSnapshot snapshot;\n\n        UiGesturesFormatter(IdeSnapshot snapshot) {\n            this.snapshot = snapshot;\n        }\n\n        public String formatValue(long value, int format) {\n            switch (format) {\n                case FORMAT_TOOLTIP:\n                case FORMAT_DETAILS:\n                case FORMAT_EXPORT:\n                    IdeSnapshot.LogRecordInfo info = snapshot.getLogInfoForValue(value);\n                    String message = null;\n                    if (info != null) {\n                        message = info.getDisplayName();\n                        if (message == null) message = info.getName();\n                        if (message == null) message = \"<unknown>\";\n                    }\n                    return message != null ? message : \"<none>\";\n                case FORMAT_UNITS:\n                    return \"\";\n                default:\n                    return null;\n            }\n        }\n\n        public String getUnits(int format) {\n            return \"\";\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/probes/ProbeDescriptorComponent.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.probes;\n\nimport java.awt.Component;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport javax.swing.Icon;\nimport javax.swing.JCheckBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerPackage;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProbeDescriptor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ProbeDescriptorComponent extends JPanel {\n\n    public ProbeDescriptorComponent(final TracerProbeDescriptor descriptor,\n                                    final TracerPackage p,\n                                    final SelectionHandler handler) {\n        setOpaque(false);\n        setLayout(new GridBagLayout());\n        GridBagConstraints c;\n\n        JCheckBox checkBox = new JCheckBox() {\n            protected void fireActionPerformed(ActionEvent event) {\n                if (isSelected()) handler.descriptorSelected(p, descriptor);\n                else handler.descriptorUnselected(p, descriptor);\n            }\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled && descriptor.isProbeAvailable());\n            }\n        };\n        checkBox.setOpaque(false);\n        checkBox.setEnabled(descriptor.isProbeAvailable());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.gridheight = 2;\n        c.anchor = GridBagConstraints.CENTER;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(3, 15, 3, 5);\n        add(checkBox, c);\n\n        JLabel icon = new JLabel() {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled && descriptor.isProbeAvailable());\n            }\n        };\n        Icon ic = descriptor.getProbeIcon();\n        icon.setIcon(ic);\n        icon.setEnabled(descriptor.isProbeAvailable());\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.gridheight = 2;\n        c.anchor = GridBagConstraints.CENTER;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 5, 3, 5);\n        add(icon, c);\n\n        JLabel name = new JLabel(descriptor.getProbeName()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled && descriptor.isProbeAvailable());\n            }\n        };\n        name.setFont(name.getFont().deriveFont(Font.BOLD));\n        name.setEnabled(descriptor.isProbeAvailable());\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.gridheight = 1;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 10, 0, 5);\n        add(name, c);\n\n        JLabel descr = new JLabel(descriptor.getProbeDescription()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled && descriptor.isProbeAvailable());\n            }\n        };\n        descr.setFont(descr.getFont().deriveFont(Font.PLAIN));\n        descr.setEnabled(descriptor.isProbeAvailable());\n        c = new GridBagConstraints();\n        c.gridx = 2;\n        c.gridy = 1;\n        c.gridwidth = 1;\n        c.gridheight = 1;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 10, 3, 5);\n        add(descr, c);\n    }\n\n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        Component[] components = getComponents();\n        for (Component c : components) c.setEnabled(enabled);\n    }\n\n\n    public static interface SelectionHandler {\n\n        public void descriptorSelected(TracerPackage p, TracerProbeDescriptor d);\n\n        public void descriptorUnselected(TracerPackage p, TracerProbeDescriptor d);\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/probes/ProbePresenter.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.probes;\n\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.LinearGradientPaint;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProbe;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ProbePresenter extends JLabel {\n\n    private static final Color SELECTED_FILTER = new Color(0, 0, 200, 40);\n    private static final float[] FRACTIONS = new float[] { 0.0f, 0.49f, 0.51f, 1.0f };\n    private static final Color[] COLORS = !UIUtils.isDarkResultsBackground() ?\n        new Color[] { new Color(250, 251, 252, 120),\n                      new Color(237, 240, 242, 120),\n                      new Color(229, 233, 236, 125),\n                      new Color(215, 221, 226, 130) } :\n        new Color[] { new Color(50, 51, 52, 220),\n                      new Color(37, 40, 42, 220),\n                      new Color(29, 33, 36, 225),\n                      new Color(15, 21, 26, 230) };\n\n    private static final Color BACKGROUND = !UIUtils.isDarkResultsBackground() ?\n            UIManager.getColor(\"Panel.background\") : new Color(30, 30, 30); // NOI18N\n\n    private LinearGradientPaint gradientPaint;\n\n    private static final boolean GRADIENT = !Utils.forceSpeed();\n    private boolean isSelected = false;\n\n    public ProbePresenter(TracerProbe p, TracerProbeDescriptor d) {\n        super(d.getProbeName(), d.getProbeIcon(), JLabel.LEADING);\n\n        // --- ToolTips support\n        // Let's store the tooltip in client property and resolve it from parent\n        putClientProperty(\"ToolTipHelper\", d.getProbeDescription()); // NOI18N\n        // ---\n        \n        setIconTextGap(7);\n        setBorder(BorderFactory.createCompoundBorder(\n                    BorderFactory.createMatteBorder(0, 0, 1, 1, Color.LIGHT_GRAY),\n                    BorderFactory.createEmptyBorder(5, 10, 5, 10)\n                ));\n    }\n    \n\n    public void setSelected(boolean selected) {\n        if (isSelected == selected) return;\n        isSelected = selected;\n        repaint();\n    }\n    \n    public boolean isSelected() {\n        return isSelected;\n    }\n\n\n    public void reshape(int x, int y, int w, int h) {\n        if (GRADIENT) gradientPaint = new LinearGradientPaint(0, 0, 0, h - 1,\n                                                              FRACTIONS, COLORS);\n        super.reshape(x, y, w, h);\n    }\n\n\n    protected void paintComponent(Graphics g) {\n        int y = getHeight() - 1;\n\n        ((Graphics2D)g).setPaint(GRADIENT ? gradientPaint : BACKGROUND);\n        g.fillRect(0, 0, getWidth(), y);\n        \n        if (isSelected) {\n            g.setColor(SELECTED_FILTER);\n            g.fillRect(0, 0, getWidth(), y);\n        }\n\n        super.paintComponent(g);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/resources/NpssResolver.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n\n<!DOCTYPE MIME-resolver PUBLIC \"-//NetBeans//DTD MIME Resolver 1.0//EN\" \"http://www.netbeans.org/dtds/mime-resolver-1_0.dtd\">\n<MIME-resolver>\n    <file>\n        <ext name=\"npss\"/>\n        <resolver mime=\"application/x-netbeans-profiler-npss\"/>\n    </file>\n    <file>\n        <magic hex=\"4e505353\"\n              mask=\"ffffffff\"/>\n        <resolver mime=\"application/x-netbeans-profiler-npss\"/>\n    </file>\n</MIME-resolver>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/ColorIcon.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Color;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ColorIcon implements javax.swing.Icon {\n\n    private static int WIDTH = 8;\n    private static int HEIGHT = 8;\n    private static Color BACKGROUND_COLOR = Color.WHITE;\n    private static Color FOREGROUND_COLOR = Color.BLACK;\n\n    public static final ColorIcon BOTTOM_SHADOW = new ColorIcon(null, true);\n\n    private final boolean shadow;\n    private final Color color;\n\n    private static final Map<Color, ColorIcon> icons = new HashMap<>();\n\n\n    private ColorIcon(Color color) {\n        this(color, false);\n    }\n\n    private ColorIcon(Color color, boolean shadow) {\n        this.color = color;\n        this.shadow = shadow;\n    }\n\n\n    public static void setup(int width, int height, Color foreground, Color background) {\n        WIDTH = width;\n        HEIGHT = height;\n        BACKGROUND_COLOR = background;\n        FOREGROUND_COLOR = foreground;\n        icons.clear();\n    }\n\n    public static ColorIcon fromColor(Color color) {\n        return icons.computeIfAbsent(color, ColorIcon::new);\n    }\n\n\n    public int getIconWidth() {\n        return WIDTH;\n    }\n\n    public int getIconHeight() {\n        return HEIGHT;\n    }\n\n    public void paintIcon(java.awt.Component c, java.awt.Graphics g, int x, int y) {\n        if (shadow) {\n            g.setColor(BACKGROUND_COLOR);\n            g.drawLine(x, y + HEIGHT + 1, x + WIDTH - 1, y + HEIGHT + 1);\n        } else {\n            g.setColor(color);\n            g.fillRect(x, y, WIDTH, HEIGHT);\n            g.setColor(FOREGROUND_COLOR);\n            g.drawRect(x, y, WIDTH - 1, HEIGHT - 1);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/CustomComboRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Component;\nimport java.text.NumberFormat;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.ListCellRenderer;\nimport javax.swing.SwingConstants;\nimport javax.swing.event.PopupMenuEvent;\nimport javax.swing.event.PopupMenuListener;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class CustomComboRenderer implements ListCellRenderer {\n\n    private final JComboBox combo;\n    private final ListCellRenderer renderer;\n    private final JLabel rendererL;\n\n\n    private CustomComboRenderer(JComboBox combo) {\n        this.combo = combo;\n        renderer = combo.getRenderer();\n        if (renderer instanceof JLabel) rendererL = (JLabel)renderer;\n        else rendererL = null;\n\n        this.combo.addPopupMenuListener(new PopupMenuListener() {\n            public void popupMenuWillBecomeVisible(PopupMenuEvent e)   { repaint(); }\n            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { repaint(); }\n            public void popupMenuCanceled(PopupMenuEvent e)            { repaint(); }\n            private void repaint() { CustomComboRenderer.this.combo.repaint(); }\n        });\n    }\n\n\n    protected void setupRenderer(ListCellRenderer renderer, boolean popupVisible) {}\n\n    protected void setupRenderer(JLabel renderer, boolean popupVisible) {}\n\n    public abstract java.lang.String value(Object value);\n\n\n    public Component getListCellRendererComponent(JList list, Object value,\n                                                  int index, boolean isSelected,\n                                                  boolean cellHasFocus) {\n\n        if (rendererL != null) setupRenderer(rendererL, combo.isPopupVisible());\n        else setupRenderer(renderer, combo.isPopupVisible());\n        \n        return renderer.getListCellRendererComponent(list, value(value), index,\n                                                     isSelected, cellHasFocus);\n    }\n\n\n    public static final class String extends CustomComboRenderer {\n\n        public String(JComboBox combo) {\n            super(combo);\n        }\n\n        public java.lang.String value(Object value) {\n            return value == null ? \"null\" : value.toString(); // NOI18N\n        }\n\n    }\n\n\n    public static final class Boolean extends CustomComboRenderer {\n\n        public Boolean(JComboBox combo) {\n            super(combo);\n        }\n\n        public java.lang.String value(Object value) {\n            if (java.lang.Boolean.TRUE.equals(value)) return \"enabled\";\n            if (java.lang.Boolean.FALSE.equals(value)) return \"disabled\";\n            return \"default\";\n        }\n\n    }\n\n\n    public static final class Number extends CustomComboRenderer {\n\n        private final java.lang.String units;\n        private final boolean lAlign;\n\n        public Number(JComboBox combo, java.lang.String units, boolean lAlign) {\n            super(combo);\n            this.units = units;\n            this.lAlign = lAlign;\n        }\n\n        protected void setupRenderer(JLabel renderer, boolean popupVisible) {\n            if (popupVisible || !lAlign) renderer.setHorizontalAlignment(SwingConstants.TRAILING);\n            else renderer.setHorizontalAlignment(SwingConstants.LEADING);\n        }\n\n        public java.lang.String value(Object value) {\n            java.lang.String sunits = units == null ? \"\" : \" \" + units;\n            return Integer.valueOf(-1).equals(value) ? \"default\" :\n                   NumberFormat.getInstance().format(value) + sunits;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/DropdownButton.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.event.ActionEvent;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.Action;\nimport javax.swing.Icon;\nimport javax.swing.JCheckBoxMenuItem;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.event.PopupMenuEvent;\nimport javax.swing.event.PopupMenuListener;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class DropdownButton extends JToggleButton {\n\n    public static final String KEY_CLASS = \"KEY_CLASS\"; // NOI18N\n    public static final String KEY_BOOLVALUE = \"KEY_BOOLVALUE\"; // NOI18N\n\n    private final List<Action> actions = new ArrayList<>();\n\n\n    public DropdownButton(Icon icon) {\n        super(icon);\n    }\n\n\n    public void addAction(Action action) {\n        actions.add(action);\n    }\n\n    public void addSeparator() {\n        actions.add(null);\n    }\n\n\n    protected void fireActionPerformed(ActionEvent event) {\n        JPopupMenu popup = new JPopupMenu();\n        for (Action action : actions) addAction(popup, action);\n        popup.addPopupMenuListener(new PopupMenuListener() {\n            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {\n                setSelected(true);\n            }\n            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {\n                setSelected(false);\n            }\n            public void popupMenuCanceled(PopupMenuEvent e) {}\n        });\n        popup.show(this, getWidth() - popup.getPreferredSize().width, getHeight());\n    }\n\n    private void addAction(JPopupMenu popup, Action action) {\n        if (action == null) {\n            popup.addSeparator();\n        } else {\n            Object cls = action.getValue(KEY_CLASS);\n            if (Boolean.class.equals(cls)) {\n                Boolean boolvalue = (Boolean)action.getValue(KEY_BOOLVALUE);\n                JCheckBoxMenuItem item = new JCheckBoxMenuItem(action);\n                item.setSelected(boolvalue);\n                popup.add(item);\n            } else {\n                popup.add(action);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/EnhancedLabelRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport javax.swing.border.Border;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class EnhancedLabelRenderer extends LabelRenderer {\n\n    private static final EnhancedInsets EMPTY_INSETS = new EnhancedInsets();\n\n    private EnhancedInsets marginInsets;\n    private EnhancedInsets borderInsets;\n    private Border border;\n    private Color background;\n\n\n    public void setMargin(Insets marginInsets) {\n        if (marginInsets == null) this.marginInsets = EMPTY_INSETS;\n        else this.marginInsets = new EnhancedInsets(marginInsets);\n    }\n\n    // Overridden for performance reasons.\n    public void setBorder(Border border) {\n        this.border = border;\n        if (border == null) borderInsets = EMPTY_INSETS;\n        else borderInsets = new EnhancedInsets(border.getBorderInsets(this));\n    }\n\n    // Overridden for performance reasons.\n    public Border getBorder() {\n        return border;\n    }\n\n    // Overridden for performance reasons.\n    public void setBackground(Color background) {\n        this.background = background;\n    }\n\n    // Overridden for performance reasons.\n    public Color getBackground() {\n        return background;\n    }\n\n    private EnhancedInsets getMarginInsets() {\n        if (marginInsets == null) marginInsets = EMPTY_INSETS;\n        return marginInsets;\n    }\n\n    private EnhancedInsets getBorderInsets() {\n        if (borderInsets == null) borderInsets = EMPTY_INSETS;\n        return borderInsets;\n    }\n\n\n    protected void prePaint(Graphics g, int x, int y) {\n        if (background != null) {\n            g.setColor(background);\n            EnhancedInsets margin = getMarginInsets();\n            Dimension size = getPreferredSize();\n            g.fillRect(x - margin.left,\n                       y - margin.top,\n                       size.width + margin.width(),\n                       size.height + margin.height());\n        }\n    }\n\n    protected void postPaint(Graphics g, int x, int y) {\n        if (border != null) {\n            EnhancedInsets bi = getBorderInsets();\n            EnhancedInsets margin = getMarginInsets();\n            Dimension size = getPreferredSize();\n            border.paintBorder(this, g,\n                               x - margin.left - bi.left,\n                               y - margin.top - bi.top,\n                               size.width + margin.width() + bi.width(),\n                               size.height + margin.height() + bi.height());\n        }\n    }\n\n\n    private static class EnhancedInsets extends Insets {\n\n        EnhancedInsets() {\n            this(0, 0, 0, 0);\n        }\n        \n        EnhancedInsets(Insets insets) {\n            this(insets.top, insets.left, insets.bottom, insets.right);\n        }\n\n        EnhancedInsets(int top, int left, int bottom, int right) {\n            super(top, left, bottom, right);\n        }\n\n\n        public int width() {\n            return left + right;\n        }\n\n        public int height() {\n            return top + bottom;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/HeaderButton.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.BasicStroke;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseEvent;\nimport javax.swing.AbstractButton;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JPanel;\nimport javax.swing.plaf.ButtonUI;\nimport javax.swing.plaf.basic.BasicButtonUI;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class HeaderButton extends HeaderPanel {\n\n    private static final HeaderButtonUI UI = new HeaderButtonUI();\n\n    private final JButton button;\n\n\n    public HeaderButton(String text, Icon icon) {\n        JPanel panel = super.getClientContainer();\n        panel.setLayout(new BorderLayout());\n        button = new JButton(text, icon) {\n            protected void processMouseEvent(MouseEvent e) {\n                super.processMouseEvent(e);\n                if (!isEnabled()) return;\n                HeaderButton.this.processMouseEvent(e);\n            }\n            protected void fireActionPerformed(ActionEvent e) {\n                performAction(e);\n            }\n        };\n        panel.add(button, BorderLayout.CENTER);\n\n        button.setOpaque(false);\n        button.setBorderPainted(false);\n        button.setMargin(new Insets(0, 0, 0, 0));\n        button.setUI(UI);\n    }\n\n    public void setToolTipText(String text) {\n        button.setToolTipText(text);\n    }\n\n    public void setEnabled(boolean enabled) {\n        button.setEnabled(enabled);\n        super.setEnabled(enabled);\n    }\n\n    public void reset() {\n        processMouseEvent(new MouseEvent(this, MouseEvent.MOUSE_EXITED,\n                          System.currentTimeMillis(), 0, -1, -1, 0, false));\n    }\n\n    protected boolean processMouseEvents() { return true; }\n\n    protected void performAction(ActionEvent e) {}\n    \n    public void setUI(ButtonUI ui) { if (ui == UI) super.setUI(ui); }\n\n\n    private static class HeaderButtonUI extends BasicButtonUI {\n\n        private static final Color FOCUS_COLOR = Color.BLACK;\n        private static final Stroke FOCUS_STROKE =\n                new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL,\n                                0, new float[] {0, 2}, 0);\n        private static final Color PRESSED_FOREGROUND =\n                Utils.checkedColor(new Color(100, 100, 100, 70));\n\n        protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect,\n                                  Rectangle textRect, Rectangle iconRect) {\n            Graphics2D g2 = (Graphics2D)g;\n            g2.setStroke(FOCUS_STROKE);\n            g2.setColor(FOCUS_COLOR);\n            g2.drawRect(2, 2, b.getWidth() - 5, b.getHeight() - 5);\n        }\n\n        protected void paintButtonPressed(Graphics g, AbstractButton b) {\n            g.setColor(PRESSED_FOREGROUND);\n            g.fillRect(0, 0, b.getWidth(), b.getHeight());\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/HeaderLabel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport javax.swing.JLabel;\nimport javax.swing.SwingConstants;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class HeaderLabel extends HeaderPanel {\n\n    public static final int DEFAULT_HEIGHT = computeHeight();\n\n\n    private String text;\n    private int hAlign = SwingConstants.CENTER;\n\n\n    public HeaderLabel() {\n        this(\"\"); // NOI18N\n    }\n\n    public HeaderLabel(String text) {\n        this.text = text;\n    }\n\n\n    public final void setText(String text) {\n        this.text = text;\n        repaint();\n    }\n\n    public final String getText() {\n        return text;\n    }\n\n    public final void setHorizontalAlignment(int align) {\n        hAlign = align;\n        repaint();\n    }\n\n    public final int getHorizontalAlignment() {\n        return hAlign;\n    }\n\n\n    protected Object getRendererValue() {\n        return getText();\n    }\n\n\n    protected void setupRenderer(Component renderer) {\n        if (renderer instanceof JLabel) {\n            JLabel label = (JLabel)renderer;\n            label.setHorizontalAlignment(hAlign);\n        }\n    }\n\n\n    public Dimension getPreferredSize() {\n        Dimension dim = getPreferredSizeSuper();\n        dim.height = DEFAULT_HEIGHT;\n        return dim;\n    }\n\n    private Dimension getPreferredSizeSuper() {\n        return super.getPreferredSize();\n    }\n\n\n    private static int computeHeight() {\n        int height = new HeaderLabel(\"X\").getPreferredSizeSuper().height; // NOI18N\n        if (UIUtils.isMetalLookAndFeel()) height += 4;\n//        else if (UISupport.isAquaLookAndFeel()) height += 6;\n        return height;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/HeaderPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.event.MouseEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTable;\nimport javax.swing.OverlayLayout;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.JTableHeader;\nimport javax.swing.table.TableCellRenderer;\nimport javax.swing.table.TableColumn;\nimport javax.swing.table.TableColumnModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class HeaderPanel extends JPanel {\n\n    private JPanel clientContainer;\n    private Header header;\n\n    public HeaderPanel() {\n        initComponents();\n    }\n\n\n    protected Object getRendererValue() { return null; }\n\n    protected void setupRenderer(Component renderer) {}\n\n    protected boolean isSelected() { return false; }\n\n    protected boolean processMouseEvents() { return false; }\n\n\n    public JPanel getClientContainer() {\n        if (clientContainer == null) {\n            clientContainer = Spacer.create();\n            add(clientContainer, 0);\n        }\n        return clientContainer;\n    }\n\n    public boolean isOptimizedDrawingEnabled() {\n        return clientContainer == null;\n    }\n\n    protected void processMouseEvent(MouseEvent e) {\n        if (processMouseEvents()) header.processMouseEvent(e);\n        if (!e.isConsumed()) super.processMouseEvent(e);\n    }\n\n    private void initComponents() {\n        JTable impl = new JTable(new DefaultTableModel(new Object[] { \"\" }, 0)); // NOI18N\n        TableColumnModel colMod = impl.getColumnModel();\n        final TableColumn col = colMod.getColumn(0);\n        impl.setFocusable(false);\n        header = new Header(colMod);\n        impl.setTableHeader(header);\n        header.setResizingAllowed(false);\n        header.setReorderingAllowed(false);\n\n        final TableCellRenderer renderer = header.getDefaultRenderer();\n        header.setDefaultRenderer(new TableCellRenderer() {\n            public Component getTableCellRendererComponent(\n                    JTable table, Object value, boolean isSelected, boolean hasFocus,\n                    int row, int column) {\n\n                Component component = renderer.getTableCellRendererComponent(\n                        table, getRendererValue(), isSelected(),\n                        isSelected(), row, processMouseEvents() ? 0 : 1);\n\n                setupRenderer(component);\n\n                col.setWidth(header.getWidth());\n                return component;\n            }\n        });\n\n        JScrollPane scroll = new JScrollPane(impl, JScrollPane.VERTICAL_SCROLLBAR_NEVER,\n                                                   JScrollPane.HORIZONTAL_SCROLLBAR_NEVER) {\n            public Dimension getPreferredSize() { return header.getPreferredSize(); }\n            public void reshape(int x, int y, int width, int height) {\n                header.setPreferredSize(new Dimension(width, height));\n                super.reshape(x, y, width, height);\n            }\n        };\n        scroll.setBorder(BorderFactory.createEmptyBorder());\n        scroll.setViewportBorder(BorderFactory.createEmptyBorder());\n\n        setLayout(new OverlayLayout(this));\n        add(scroll);\n    }\n\n    private static class Header extends JTableHeader {\n        Header(TableColumnModel model) { super(model); }\n        public void processMouseEvent(MouseEvent e) { super.processMouseEvent(e); }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/HorizontalLayout.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Insets;\nimport java.awt.LayoutManager;\nimport javax.swing.Box;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class HorizontalLayout implements LayoutManager {\n\n    private final boolean proportionalHeight;\n    private final int hGap;\n\n\n    public HorizontalLayout(boolean proportionalHeight) {\n        this(proportionalHeight, 0);\n    }\n\n    public HorizontalLayout(boolean proportionalHeight, int hGap) {\n        this.proportionalHeight = proportionalHeight;\n        this.hGap = hGap;\n    }\n\n\n    public void layoutContainer(final Container parent) {\n        final Insets insets = parent.getInsets();\n        int posX = insets.left;\n        final int posY = insets.top;\n        final int height = parent.getHeight() - insets.top - insets.bottom;\n\n        for (Component comp : parent.getComponents()) {\n            if (comp.isVisible()) {\n                Dimension pref = comp.getPreferredSize();\n                if (proportionalHeight) {\n                    int h = Math.min(pref.height, height);\n                    int o = (height - h) / 2;\n                    comp.setBounds(posX, posY + o, pref.width, h);\n                } else {\n                    comp.setBounds(posX, posY, pref.width, height);\n                }\n                posX += hGap;\n                posX += pref.width;\n            }\n        }\n    }\n\n    public Dimension minimumLayoutSize(final Container parent) {\n        final Insets insets = parent.getInsets();\n        final Dimension d = new Dimension(insets.left + insets.right,\n                                          insets.top + insets.bottom);\n        int maxHeight = 0;\n        int visibleCount = 0;\n\n        for (Component comp : parent.getComponents()) {\n            if (comp.isVisible() && !(comp instanceof Box.Filler)) {\n                final Dimension size = comp.getPreferredSize();\n                maxHeight = Math.max(maxHeight, size.height);\n                d.width += size.width;\n                visibleCount++;\n            }\n        }\n\n        d.width += (visibleCount - 1) * hGap;\n        d.height += maxHeight;\n\n        return d;\n    }\n\n    public Dimension preferredLayoutSize(final Container parent) {\n        final Insets insets = parent.getInsets();\n        final Dimension d = new Dimension(insets.left + insets.right,\n                                          insets.top + insets.bottom);\n        int maxHeight = 0;\n        int visibleCount = 0;\n\n        for (Component comp : parent.getComponents()) {\n            if (comp.isVisible()) {\n                final Dimension size = comp.getPreferredSize();\n                maxHeight = Math.max(maxHeight, size.height);\n                d.width += size.width;\n                visibleCount++;\n            }\n        }\n\n        d.width += (visibleCount - 1) * hGap;\n        d.height += maxHeight;\n\n        return d;\n    }\n\n\n    public void addLayoutComponent(final String name, final Component comp) {}\n\n    public void removeLayoutComponent(final Component comp) {}\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/LabelRenderer.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.FontMetrics;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport javax.swing.Icon;\nimport javax.swing.JLabel;\nimport javax.swing.plaf.LabelUI;\nimport javax.swing.plaf.basic.BasicLabelUI;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class LabelRenderer extends JLabel {\n\n    private static final LabelRendererUI UI = new LabelRendererUI();\n    private static final int DIRTY = Integer.MIN_VALUE;\n\n    private int x;\n    private int y;\n    private Insets insets = new Insets(0, 0, 0, 0);\n    private Dimension preferredSize;\n\n    private FontMetrics fontMetrics;\n    private String text;\n    private Icon icon;\n    private Color foreground;\n    private boolean enabled;\n\n    private int iconWidth;\n    private int iconHeight;\n    private int iconTextGap;\n    private int textWidth;\n    private int fontAscent;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    public LabelRenderer() {\n        setHorizontalAlignment(LEFT);\n        setVerticalAlignment(TOP);\n        setSize(Integer.MAX_VALUE, Integer.MAX_VALUE);\n\n        setOpaque(false);\n        setEnabled(true);\n\n        iconTextGap = super.getIconTextGap();\n    }\n\n\n    // --- Implementation ------------------------------------------------------\n\n    public Insets getInsets() {\n        return insets;\n    }\n\n    public Insets getInsets(Insets insets) {\n        return this.insets;\n    }\n\n    public void setLocation(int x, int y) {\n        this.x = x;\n        this.y = y;\n    }\n\n    public Dimension getPreferredSize() {\n        if (preferredSize == null) preferredSize = new Dimension(DIRTY, DIRTY);\n\n        if (preferredSize.width == DIRTY) {\n            textWidth = text == null || text.isEmpty() ? 0 : fontMetrics.stringWidth(text);\n            preferredSize.width = iconWidth + textWidth;\n            if (iconWidth > 0 && textWidth > 0) preferredSize.width += iconTextGap;\n        }\n\n        if (preferredSize.height == DIRTY) {\n            fontAscent = fontMetrics.getAscent();\n            preferredSize.height = fontAscent + fontMetrics.getDescent();\n        }\n\n        return preferredSize;\n    }\n\n    public void setUI(LabelUI ui) {\n        super.setUI(UI);\n    }\n\n    private void resetPreferredSize(boolean width, boolean height) {\n        if (preferredSize == null) return;\n        if (width) preferredSize.width = DIRTY;\n        if (height) preferredSize.height = DIRTY;\n    }\n\n    protected void prePaint(Graphics g, int x, int y) {}\n    protected void postPaint(Graphics g, int x, int y) {}\n\n    public void paint(Graphics g) {\n        Graphics cg = getComponentGraphics(g);\n\n        prePaint(cg, x, y);\n\n        int xx = x;\n        if (iconWidth > 0) {\n            int yy = (preferredSize.height - iconHeight) / 2;\n            icon.paintIcon(this, cg, xx, y + yy);\n            xx += iconWidth + iconTextGap;\n        }\n        if (textWidth > 0)\n            UI.paintEnabledText(this, cg, text, xx, y + fontAscent);\n\n        postPaint(cg, x, y);\n    }\n\n\n    // --- Performance tweaks ---------------------------------------------------\n\n    // Overridden for performance reasons.\n    public void setText(String text) {\n        this.text = text;\n        resetPreferredSize(true, false);\n    }\n\n    // Overridden for performance reasons.\n    public String getText() {\n        return text;\n    }\n\n    // Overridden for performance reasons.\n    public void setIcon(Icon icon) {\n        int oldIconWidth = iconWidth;\n        iconWidth = icon == null ? 0 : icon.getIconWidth();\n        iconHeight = icon == null ? 0 : icon.getIconHeight();\n        this.icon = icon;\n        if (oldIconWidth != iconWidth) resetPreferredSize(true, false);\n    }\n\n    // Overridden for performance reasons.\n    public Icon getIcon() {\n        return icon;\n    }\n\n    // Overridden for performance reasons.\n    public void setForeground(Color foreground) {\n        this.foreground = foreground;\n    }\n\n    // Overridden for performance reasons.\n    public Color getForeground() {\n        return foreground;\n    }\n\n    // Overridden for performance reasons.\n    public void setEnabled(boolean enabled) {\n        this.enabled = enabled;\n    }\n\n    // Overridden for performance reasons.\n    public boolean isEnabled() {\n        return enabled;\n    }\n\n    // Overridden for performance reasons.\n    public int getDisplayedMnemonicIndex() {\n        return -1;\n    }\n\n    // Overridden for performance reasons.\n    public FontMetrics getFontMetrics(Font font) {\n        return fontMetrics;\n    }\n\n    // Overridden for performance reasons.\n    public void setFont(Font font) {\n        super.setFont(font);\n        fontMetrics = super.getFontMetrics(font);\n        resetPreferredSize(true, true);\n    }\n\n    // Overridden for performance reasons.\n    public int getIconTextGap() {\n        return iconTextGap;\n    }\n\n\n    // Overridden for performance reasons.\n    public void setIconTextGap(int iconTextGap) {\n        this.iconTextGap = iconTextGap;\n        resetPreferredSize(true, false);\n    }\n\n    // Overridden for performance reasons.\n    public void validate() {}\n\n    // Overridden for performance reasons.\n    public void revalidate() {}\n\n    // Overridden for performance reasons.\n    public void repaint(long tm, int x, int y, int width, int height) {}\n\n    // Overridden for performance reasons.\n    public void repaint(Rectangle r) {}\n\n    // Overridden for performance reasons.\n    public void repaint() {}\n\n    // Overridden for performance reasons.\n    public void setDisplayedMnemonic(int key) {}\n\n    // Overridden for performance reasons.\n    public void setDisplayedMnemonic(char aChar) {}\n\n    // Overridden for performance reasons.\n    public void setDisplayedMnemonicIndex(int index) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, char oldValue, char newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, short oldValue, short newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, int oldValue, int newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, long oldValue, long newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, float oldValue, float newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, double oldValue, double newValue) {}\n\n    // Overridden for performance reasons.\n    public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}\n\n    // Overridden for performance reasons.\n    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}\n\n\n    private static class LabelRendererUI extends BasicLabelUI {\n        protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) {\n            super.paintEnabledText(l, g, s, textX, textY);\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/LegendFont.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Color;\nimport java.awt.Font;\nimport javax.swing.JLabel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class LegendFont extends Font {\n\n    public static final Color FOREGROUND_COLOR = new Color(100, 100, 100);\n    public static final Color BACKGROUND_COLOR = new Color(255, 255, 255);\n\n    private static final Font baseFont = baseFont();\n\n\n    public LegendFont() {\n        super(baseFont);\n    }\n\n\n    private static Font baseFont() {\n        Font font = new JLabel().getFont();\n        return font.deriveFont((float)font.getSize() - 2);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/ScrollBar.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Insets;\nimport javax.swing.BorderFactory;\nimport javax.swing.JScrollBar;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n * Use only for creating ScrollBars which mimic insets of JScrollPane's SBs.\n *\n * @author Jiri Sedlacek\n */\npublic class ScrollBar extends JScrollBar {\n\n    public ScrollBar(int orientation) {\n        super(orientation);\n\n        if (UIUtils.isGTKLookAndFeel()) {\n            Insets insets = getBorder().getBorderInsets(this);\n            // Typically the insets are 2 for GTK themes except for Nimbus theme\n            // which uses 3 and requires 1 (other themes seem to require 0). Lets\n            // lower the insets to mimic JScrollBars used in JScrollPanes.\n            setBorder(BorderFactory.createEmptyBorder(Math.max(insets.top - 2, 0),\n                                                    Math.max(insets.left - 2, 0),\n                                                    Math.max(insets.bottom - 2, 0),\n                                                    Math.max(insets.right - 2, 0)\n                                                   ));\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/ScrollableContainer.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.BorderLayout;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Rectangle;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JViewport;\nimport javax.swing.Scrollable;\n\n/**\n * Predefined JScrollPane to be used in VisualVM, for example in details views.\n * Use UISupport.createScrollableContainer() method instead of instantiating\n * this class directly if creating scrollable container for the Options panel.\n *\n * @author Jiri Sedlacek\n */\npublic final class ScrollableContainer extends JScrollPane {\n\n    /**\n     * Creates new instance of ScrollableContainer.\n     *\n     * @param view component to be displayed\n     */\n    public ScrollableContainer(JComponent view) {\n        this(view, VERTICAL_SCROLLBAR_AS_NEEDED,\n             HORIZONTAL_SCROLLBAR_AS_NEEDED);\n    }\n\n    /**\n     * Creates new instance of ScrollableContainer.\n     *\n     * @param view component to be displayed\n     * @param vsbPolicy policy flag for the vertical scrollbar\n     * @param hsbPolicy policy flag for the horizontal scrollbar\n     */\n    public ScrollableContainer(JComponent view, int vsbPolicy, int hsbPolicy) {\n        setViewportView(new ScrollableContents(view));\n\n        setVerticalScrollBarPolicy(vsbPolicy);\n        setHorizontalScrollBarPolicy(hsbPolicy);\n\n        setBorder(BorderFactory.createEmptyBorder());\n        setViewportBorder(BorderFactory.createEmptyBorder());\n\n        getViewport().setOpaque(false);\n        setOpaque(false);\n    }\n\n\n    // --- Scrollable container ------------------------------------------------\n\n    private class ScrollableContents extends JPanel implements Scrollable {\n\n        ScrollableContents(JComponent contents) {\n            super(new BorderLayout());\n            setOpaque(false);\n            add(contents, BorderLayout.CENTER);\n        }\n\n        public Dimension getPreferredScrollableViewportSize() {\n            return getPreferredSize();\n        }\n\n        public int getScrollableUnitIncrement(Rectangle visibleRect,\n                                              int orientation, int direction) {\n            return 20;\n        }\n\n        public int getScrollableBlockIncrement(Rectangle visibleRect,\n                                               int orientation, int direction) {\n            return (int)(visibleRect.height * 0.9d);\n        }\n\n        public boolean getScrollableTracksViewportWidth() {\n            if (getHorizontalScrollBarPolicy() == HORIZONTAL_SCROLLBAR_NEVER)\n                return true;\n\n            Container parent = getParent();\n            if (!(parent instanceof JViewport)) return false;\n            return getMinimumSize().width < parent.getWidth();\n        }\n\n        public boolean getScrollableTracksViewportHeight() {\n            if (getVerticalScrollBarPolicy() == VERTICAL_SCROLLBAR_NEVER)\n                return true;\n\n            Container parent = getParent();\n            if (!(parent instanceof JViewport)) return false;\n            return getMinimumSize().height < parent.getHeight();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/SectionSeparator.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Color;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\n\n/**\n * Separator-like component to be used instead of TitledBorder to keep the UI\n * lightweight. Use UISupport.createSectionSeparator() method instead of instantiating\n * this class directly if creating sections for the Options panel.\n *\n * @author Jiri Sedlacek\n */\npublic final class SectionSeparator extends JPanel {\n\n    /**\n     * Creates new instance of SectionSeparator. Uses bold font by default.\n     *\n     * @param text separator text\n     */\n    public SectionSeparator(String text) {\n        this(text, null);\n    }\n\n    /**\n     * Creates new instance of SectionSeparator. Uses the provided font or default\n     * font if no font is provided.\n     *\n     * @param text separator text\n     * @param font font for the caption text or null for default font\n     */\n    public SectionSeparator(String text, Font font) {\n        if (text == null) throw new IllegalArgumentException(\"Text cannot be null\"); // NOI18N\n        initComponents(text, font);\n    }\n\n    public void setForeground(Color foreground) {\n        if (label == null) super.setForeground(foreground);\n        else label.setForeground(foreground);\n    }\n\n    public Color getForeground() {\n        if (label == null) return super.getForeground();\n        else return label.getForeground();\n    }\n\n    public void setFont(Font font) {\n        if (label == null) super.setFont(font);\n        else label.setFont(font);\n    }\n\n    public Font getFont() {\n        if (label == null) return super.getFont();\n        else return label.getFont();\n    }\n\n    private void initComponents(String text, Font font) {\n        setBorder(BorderFactory.createEmptyBorder());\n        setLayout(new GridBagLayout());\n        setOpaque(false);\n\n        label = new JLabel(text);\n        label.setForeground(getForeground());\n        if (font != null) label.setFont(font);\n        else label.setFont(label.getFont().deriveFont(Font.BOLD));\n        GridBagConstraints c1 = new GridBagConstraints();\n        c1.weighty = 1d;\n        add(label, c1);\n\n        GridBagConstraints c2 = new GridBagConstraints();\n        c2.weightx = 1d;\n        c2.fill = GridBagConstraints.HORIZONTAL;\n        c2.insets = new Insets(0, 4, 0, 0);\n        add(new Separator(), c2);\n    }\n\n    private JLabel label;\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/Separator.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Dimension;\nimport java.lang.reflect.Method;\nimport javax.swing.JComponent;\nimport javax.swing.JSeparator;\nimport javax.swing.UIManager;\nimport javax.swing.plaf.SeparatorUI;\n\n/**\n * JSeparator applying a workaround for bad separator appearance on macOS\n * broken by the NetBeans Platform.\n *\n * @author Jiri Sedlacek\n */\nfinal class Separator extends JSeparator {\n\n    private static final String SEPARATOR_UI = \"SeparatorUI\"; // NOI18N\n    private static final String MAC_OS_X_SEPARATOR_UI =\n            \"com.apple.laf.AquaPopupMenuSeparatorUI\"; // NOI18N\n    private static final String MAC_OS_X_SEPARATOR_UI_NB =\n            \"org.netbeans.swing.plaf.aqua.AquaSeparatorUI\"; // NOI18N\n    private static Class<SeparatorUI> MAC_OS_X_SEPARATOR_UI_CLASS;\n    private static final String MAC_OS_X_SEPARATOR_COLOR_KEY =\n            \"InternalFrame.inactiveTitleForeground\"; // NOI18N\n\n    private boolean separatorUIInitialized = false;\n    private SeparatorUI macOsXSeparatorUI;\n\n\n    static {\n        if (MAC_OS_X_SEPARATOR_UI_NB.\n                equals(UIManager.getDefaults().get(SEPARATOR_UI))) {\n            try {\n                MAC_OS_X_SEPARATOR_UI_CLASS =\n                        (Class<SeparatorUI>)Class.forName(MAC_OS_X_SEPARATOR_UI);\n            } catch (Throwable e) {\n                MAC_OS_X_SEPARATOR_UI_CLASS = null;\n            }\n        }\n    }\n\n\n    Separator() {\n        super();\n    }\n\n    Separator(int orientation) {\n        super(orientation);\n    }\n\n\n    public void setUI(SeparatorUI ui) {\n        synchronized(this) {\n            if (!separatorUIInitialized) {\n                macOsXSeparatorUI = createCustomUI(this);\n                separatorUIInitialized = true;\n            }\n        }\n\n        if (macOsXSeparatorUI == null) {\n            super.setUI(ui);\n        } else {\n            super.setUI(macOsXSeparatorUI);\n            setForeground(UIManager.getColor(MAC_OS_X_SEPARATOR_COLOR_KEY));\n        }\n    }\n\n    public Dimension getMinimumSize() {\n        return getPreferredSize();\n    }\n\n\n    private static SeparatorUI createCustomUI(JComponent separator) {\n        if (MAC_OS_X_SEPARATOR_UI_CLASS != null) {\n            try {\n                Method m = MAC_OS_X_SEPARATOR_UI_CLASS.getDeclaredMethod(\n                           \"createUI\", JComponent.class); // NOI18N\n                return (SeparatorUI)m.invoke(null, separator);\n            } catch (Throwable e) {\n                return null;\n            }\n        } else {\n            return null;\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/SimpleSeparator.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport javax.swing.JPanel;\nimport javax.swing.SwingConstants;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class SimpleSeparator extends JPanel implements SwingConstants {\n\n    private final int orientation;\n    private final Dimension preferredSize = new Dimension(1, 1);\n\n\n    public SimpleSeparator() {\n        this(HORIZONTAL);\n    }\n\n    public SimpleSeparator(int orientation) {\n        super(null);\n        this.orientation = orientation;\n    }\n\n\n    public void setPreferredSize(Dimension preferredSize) {\n        this.preferredSize.width = preferredSize.width;\n        this.preferredSize.height = preferredSize.height;\n    }\n\n\n    public Dimension getMinimumSize() {\n        Insets insets = getInsets();\n        if (orientation == HORIZONTAL)\n            return new Dimension(insets.left + insets.right,\n                                 insets.top + insets.bottom + 1);\n        else\n            return new Dimension(insets.left + insets.right + 1,\n                                 insets.top + insets.bottom);\n    }\n\n    public Dimension getMaximumSize() {\n        Insets insets = getInsets();\n        if (orientation == HORIZONTAL)\n            return new Dimension(Integer.MAX_VALUE,\n                                 insets.top + insets.bottom + 1);\n        else\n            return new Dimension(insets.left + insets.right + 1,\n                                 Integer.MAX_VALUE);\n    }\n\n    public Dimension getPreferredSize() {\n        Insets insets = getInsets();\n        if (orientation == HORIZONTAL)\n            return new Dimension(Math.max(insets.left + insets.right, preferredSize.width),\n                                 insets.top + insets.bottom + 1);\n        else\n            return new Dimension(insets.left + insets.right + 1,\n                                 Math.max(insets.top + insets.bottom, preferredSize.height));\n    }\n\n\n    public void paint(Graphics g) {\n        g.setColor(new Color(192, 192, 192));\n        Insets insets = getInsets();\n        if (orientation == HORIZONTAL)\n            g.drawLine(insets.left, insets.top, getWidth() - insets.right, insets.top);\n        else\n            g.drawLine(insets.left, insets.top, insets.left, getHeight() - insets.bottom);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/Spacer.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Dimension;\nimport javax.swing.JPanel;\n\n/**\n * Subclass of a JPanel to be used as a spacer in GridBagLayout. Creates a\n * non-opaque JPanel with null Layout and zero preferred size.\n *\n * @author Jiri Sedlacek\n */\npublic final class Spacer extends JPanel {\n\n    private static final Dimension DIMENSION_ZERO = new Dimension(0, 0);\n\n\n    /**\n     * Creates new instance of Spacer.\n     *\n     * @return new instance of Spacer\n     */\n    public static Spacer create() { return new Spacer(); }\n\n\n    public Dimension getPreferredSize() { return DIMENSION_ZERO; }\n\n    private Spacer() {\n        super(null);\n        setOpaque(false);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/TimelineMarksPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Component;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMark;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMarksPainter;\nimport org.graalvm.visualvm.lib.charts.axis.TimeAxisUtils;\nimport org.graalvm.visualvm.lib.charts.axis.TimeMark;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class TimelineMarksPainter extends LabelRenderer implements AxisMarksPainter {\n\n    public TimelineMarksPainter() {\n        super();\n        setFont(new LegendFont());\n    }\n\n    public Component getPainter(AxisMark mark) {\n        setText(TimeAxisUtils.formatTime((TimeMark)mark));\n        return this;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/TransparentToolBar.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.FocusListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.AbstractButton;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JToolBar;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class TransparentToolBar extends JPanel {\n\n    private static Boolean NEEDS_PANEL;\n    private static Boolean CUSTOM_FILLER;\n\n    private final JToolBar toolbar;\n    private final ItemListener listener = new ItemListener();\n\n\n    public TransparentToolBar() {\n        toolbar = needsPanel() ? null : new JToolBar();\n        setOpaque(false);\n        if (toolbar == null) {\n            // Toolbar is a JPanel (GTK)\n            setLayout(new HorizontalLayout(false));\n        } else {\n            // Toolbar is a JToolBar (default)\n            toolbar.setBorderPainted(false);\n            toolbar.setFloatable(false);\n            toolbar.setRollover(true);\n            toolbar.setOpaque(false);\n            toolbar.setBorder(BorderFactory.createEmptyBorder());\n            setLayout(new BorderLayout());\n            add(toolbar, BorderLayout.CENTER);\n        }\n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (isShowing()) {\n                        removeHierarchyListener(this);\n                        for (Component c : getComponents()) {\n                            if (c instanceof AbstractButton) {\n                                listener.refresh((AbstractButton)c);\n                            }\n                        }\n                    }\n                }\n            }\n        });\n    }\n\n    public void addItem(JComponent c) {\n        c.setOpaque(false);\n\n        if (c instanceof JButton)\n            ((JButton)c).setDefaultCapable(false);\n\n        if (toolbar != null) {\n            toolbar.add(c);\n        } else {\n            add(c);\n            if (c instanceof AbstractButton) {\n                AbstractButton b = (AbstractButton) c;\n                b.addMouseListener(listener);\n                b.addChangeListener(listener);\n                b.addFocusListener(listener);\n                b.setRolloverEnabled(true);\n            }\n        }\n    }\n\n    public void removeItem(JComponent c) {\n        if (toolbar != null) {\n            toolbar.remove(c);\n        } else {\n            if (c instanceof AbstractButton) {\n                c.removeMouseListener(listener);\n                ((AbstractButton) c).removeChangeListener(listener);\n                c.removeFocusListener(listener);\n            }\n            remove(c);\n        }\n    }\n    \n    public void addSeparator() {\n        JToolBar.Separator separator = new JToolBar.Separator();\n        separator.setOrientation(JToolBar.Separator.VERTICAL);\n        addItem(separator);\n    }\n    \n    public void addFiller() {\n        Dimension minDim = new Dimension(0, 0);\n        Dimension maxDim = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);\n        final boolean customFiller = customFiller();\n        Box.Filler filler = new Box.Filler(minDim, minDim, maxDim) {\n            public Dimension getPreferredSize() {\n                if (customFiller) {\n                    int currentWidth = TransparentToolBar.this.getSize().width;\n                    int minimumWidth = TransparentToolBar.this.getMinimumSize().width;\n                    int extraWidth = currentWidth - minimumWidth;\n                    return new Dimension(Math.max(extraWidth, 0), 0);\n                } else {\n                    return super.getPreferredSize();\n                }\n            }\n            protected void paintComponent(Graphics g) {}\n        };\n        addItem(filler);\n    }\n    \n\n    private static boolean needsPanel() {\n        if (NEEDS_PANEL == null) NEEDS_PANEL = UIUtils.isGTKLookAndFeel();\n        return NEEDS_PANEL;\n    }\n    \n    private static boolean customFiller() {\n        if (CUSTOM_FILLER == null) CUSTOM_FILLER = UIUtils.isGTKLookAndFeel() ||\n                                                  UIUtils.isNimbusLookAndFeel();\n        return CUSTOM_FILLER;\n    }\n\n            \n    private static final class ItemListener extends MouseAdapter implements ChangeListener, FocusListener {\n\n        private static final String PROP_HOVERED = \"BUTTON_HOVERED\"; // NOI18N\n\n        public void mouseEntered(MouseEvent e) {\n            AbstractButton b = (AbstractButton) e.getSource();\n            b.putClientProperty(PROP_HOVERED, Boolean.TRUE);\n            refresh(b);\n        }\n\n        public void mouseExited(MouseEvent e) {\n            AbstractButton b = (AbstractButton) e.getSource();\n            b.putClientProperty(PROP_HOVERED, Boolean.FALSE);\n            refresh(b);\n        }\n\n        public void stateChanged(ChangeEvent e) {\n            refresh((AbstractButton) e.getSource());\n        }\n\n        public void focusGained(FocusEvent e) {\n            refresh((AbstractButton) e.getSource());\n        }\n\n        public void focusLost(FocusEvent e) {\n            refresh((AbstractButton) e.getSource());\n        }\n\n        private void refresh(final AbstractButton b) {\n            b.setBackground(UIUtils.getProfilerResultsBackground());\n            boolean hovered = Boolean.TRUE.equals(b.getClientProperty(PROP_HOVERED));\n            boolean filled = b.isEnabled() && (hovered || b.isSelected() || b.isFocusOwner());\n            b.setOpaque(filled);\n            b.setContentAreaFilled(filled);\n            b.repaint();\n        }\n        \n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/VerticalLayout.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Insets;\nimport java.awt.LayoutManager;\nimport javax.swing.Box;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class VerticalLayout implements LayoutManager {\n\n    private final boolean proportionalWidth;\n    private final int vGap;\n\n\n    public VerticalLayout(boolean proportionalWidth) {\n        this(proportionalWidth, 0);\n    }\n\n    public VerticalLayout(boolean proportionalWidth, int vGap) {\n        this.proportionalWidth = proportionalWidth;\n        this.vGap = vGap;\n    }\n\n\n    public void layoutContainer(final Container parent) {\n        final Insets insets = parent.getInsets();\n        final int posX = insets.left;\n        int posY = insets.top;\n        final int width = parent.getWidth() - insets.left - insets.right;\n\n        for (Component comp : parent.getComponents()) {\n            if (comp.isVisible()) {\n                Dimension pref = comp.getPreferredSize();\n                if (proportionalWidth) {\n                    int w = Math.min(pref.width, width);\n                    int o = (width - w) / 2;\n                    comp.setBounds(posX, posY + o, w, pref.height);\n                } else {\n                    comp.setBounds(posX, posY, width, pref.height);\n                }\n                pref.height += vGap;\n                posY += pref.height;\n            }\n        }\n    }\n\n    public Dimension minimumLayoutSize(final Container parent) {\n        final Insets insets = parent.getInsets();\n        final Dimension d = new Dimension(insets.left + insets.right,\n                                          insets.top + insets.bottom);\n        int maxWidth = 0;\n        int visibleCount = 0;\n\n        for (Component comp : parent.getComponents()) {\n            if (comp.isVisible() && !(comp instanceof Box.Filler)) {\n                final Dimension size = comp.getPreferredSize();\n                maxWidth = Math.max(maxWidth, size.width);\n                d.height += size.height;\n                visibleCount++;\n            }\n        }\n\n        d.height += (visibleCount - 1) * vGap;\n        d.width += maxWidth;\n\n        return d;\n    }\n\n    public Dimension preferredLayoutSize(final Container parent) {\n        final Insets insets = parent.getInsets();\n        final Dimension d = new Dimension(insets.left + insets.right,\n                                          insets.top + insets.bottom);\n        int maxWidth = 0;\n        int visibleCount = 0;\n\n        for (Component comp : parent.getComponents()) {\n            if (comp.isVisible()) {\n                final Dimension size = comp.getPreferredSize();\n                maxWidth = Math.max(maxWidth, size.width);\n                d.height += size.height;\n                visibleCount++;\n            }\n        }\n\n        d.height += (visibleCount - 1) * vGap;\n        d.width += maxWidth;\n\n        return d;\n    }\n\n\n    public void addLayoutComponent(final String name, final Component comp) {}\n\n    public void removeLayoutComponent(final Component comp) {}\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/swing/VisibilityHandler.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing;\n\nimport java.awt.Component;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class VisibilityHandler {\n\n    private Component component;\n    private boolean wasVisible;\n\n    private HierarchyListener listener;\n\n\n    public VisibilityHandler() {}\n\n    public abstract void shown();\n    public abstract void hidden();\n\n\n    public final void handle(Component component) {\n        if (component == null)\n            throw new NullPointerException(\"component cannot be null\"); // NOI18N\n\n        if (listener != null && component != null)\n            component.removeHierarchyListener(listener);\n\n        this.component = component;\n        wasVisible = component.isVisible();\n\n        if (listener == null) listener = createListener();\n        component.addHierarchyListener(listener);\n    }\n\n\n    private HierarchyListener createListener() {\n        return new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    boolean visible = component.isShowing();\n                    if (wasVisible == visible) return;\n\n                    wasVisible = visible;\n\n                    if (visible) shown();\n                    else hidden();\n                }\n            }\n        };\n    }\n\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/ChartPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.AdjustmentEvent;\nimport java.awt.event.AdjustmentListener;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseWheelEvent;\nimport java.awt.event.MouseWheelListener;\nimport javax.swing.AbstractAction;\nimport javax.swing.AbstractButton;\nimport javax.swing.Action;\nimport javax.swing.Icon;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.icons.TracerIcons;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.options.TracerOptions;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.ScrollBar;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ACTION_ZoomIn_name=Zoom in\",\n    \"ACTION_ZoomOut_name=Zoom out\",\n    \"ACTION_FixedScale_name=Fixed scale\",\n    \"ACTION_ScaleToFit_name=Scale to fit\",\n    \"ACTION_WheelZooms_name=Mouse wheel zooms\",\n    \"ACTION_WheelHScrolls_name=Mouse wheel scrolls horizontally\",\n    \"ACTION_WheelVScrolls_name=Mouse wheel scrolls vertically\"\n})\nfinal class ChartPanel extends JPanel {\n\n    private static final Icon ZOOM_IN_ICON = Icons.getIcon(GeneralIcons.ZOOM_IN);\n    private static final Icon ZOOM_OUT_ICON = Icons.getIcon(GeneralIcons.ZOOM_OUT);\n    private static final Icon FIXED_SCALE_ICON = Icons.getIcon(GeneralIcons.ZOOM);\n    private static final Icon SCALE_TO_FIT_ICON = Icons.getIcon(GeneralIcons.SCALE_TO_FIT);\n    private static final Icon ZMWHEEL_ICON = Icons.getIcon(TracerIcons.MOUSE_WHEEL_ZOOM);\n    private static final Icon HMWHEEL_ICON = Icons.getIcon(TracerIcons.MOUSE_WHEEL_HORIZONTAL);\n    private static final Icon VMWHEEL_ICON = Icons.getIcon(TracerIcons.MOUSE_WHEEL_VERTICAL);\n\n\n    private final TimelineChart chart;\n\n    private ZoomInAction zoomInAction;\n    private ZoomOutAction zoomOutAction;\n    private ToggleViewAction toggleViewAction;\n\n    private final JScrollBar hScrollBar;\n    private final JScrollBar vScrollBar;\n    private final MouseWheelListener defaultWheelHandler;\n    private AbstractButton mouseZoom;\n    private AbstractButton mouseHScroll;\n    private AbstractButton mouseVScroll;\n\n\n    ChartPanel(TimelineChart chart, TimelineSupport support) {\n        this.chart = chart;\n\n        boolean speed = Utils.forceSpeed();\n\n        chart.setBackground(!UIUtils.isDarkResultsBackground() ? Color.WHITE : new Color(70, 70, 70));\n        if (speed && TracerOptions.getInstance().isRowsSelectionEnabled())\n            chart.addPreDecorator(new RowBackgroundDecorator(chart));\n        chart.addPreDecorator(new RowBoundsDecorator(chart));\n        chart.addPostDecorator(new RowForegroundDecorator(chart,\n                TracerOptions.getInstance().isRowsDecorationEnabled(),\n                !speed && TracerOptions.getInstance().isRowsSelectionEnabled()));\n\n        TimelineSelectionOverlay selectionOverlay = new TimelineSelectionOverlay();\n        chart.addOverlayComponent(selectionOverlay);\n        selectionOverlay.registerChart(support);\n\n        XChartSelectionOverlay xOverlay = new XChartSelectionOverlay(support);\n        xOverlay.setLineMode(false, false, false, false);\n        chart.addOverlayComponent(xOverlay);\n        xOverlay.registerChart(chart);\n\n        ChartSelectionModel selectionModel = chart.getSelectionModel();\n        if (selectionModel != null) {\n            selectionModel.setHoverMode(ChartSelectionModel.HOVER_EACH_NEAREST);\n            selectionModel.setMoveMode(ChartSelectionModel.SELECTION_LINE_V);\n            selectionModel.setDragMode(ChartSelectionModel.SELECTION_RECT);\n        }\n        \n        TimelineAxis axis = new TimelineAxis(chart, support);\n        \n        hScrollBar = new ScrollBar(JScrollBar.HORIZONTAL);\n        hScrollBar.addAdjustmentListener(new AdjustmentListener() {\n            public void adjustmentValueChanged(AdjustmentEvent e) {\n                if (hScrollBar.getValueIsAdjusting())\n                    ChartPanel.this.chart.updateSelection(false, hScrollBar);\n                else\n                    ChartPanel.this.chart.updateSelection(true, hScrollBar);\n            }\n        });\n        chart.attachHorizontalScrollBar(hScrollBar);\n\n        vScrollBar = new ScrollBar(JScrollBar.VERTICAL) {\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.height = 1;\n                return dim;\n            }\n        };\n        vScrollBar.addAdjustmentListener(new AdjustmentListener() {\n            public void adjustmentValueChanged(AdjustmentEvent e) {\n                if (vScrollBar.getValueIsAdjusting())\n                    ChartPanel.this.chart.updateSelection(false, vScrollBar);\n                else\n                    ChartPanel.this.chart.updateSelection(true, vScrollBar);\n            }\n        });\n        chart.attachVerticalScrollBar(vScrollBar);\n        \n        defaultWheelHandler = chart.getMouseWheelListeners()[0];\n\n        chart.addConfigurationListener(new VisibleBoundsListener());\n\n        setOpaque(false);\n        setLayout(new BorderLayout());\n        add(axis, BorderLayout.NORTH);\n        add(chart, BorderLayout.CENTER);\n        add(vScrollBar, BorderLayout.EAST);\n        add(hScrollBar, BorderLayout.SOUTH);\n\n        resetChart();\n    }\n\n\n    // --- Internal interface --------------------------------------------------\n\n    void resetChart() {\n        chart.setScale(0.02, 1);\n        chart.setOffset(0, 0);\n    }\n\n    boolean resetSelection() {\n        chart.getSelectionModel().setSelectionBounds(null);\n        return false;\n    }\n\n\n    void updateActions() {\n        if (zoomInAction != null) zoomInAction.updateAction();\n        if (zoomOutAction != null) zoomOutAction.updateAction();\n        if (toggleViewAction != null) toggleViewAction.updateAction();\n    }\n\n    Action zoomInAction() {\n        if (zoomInAction == null) zoomInAction = new ZoomInAction();\n        return zoomInAction;\n    }\n\n    Action zoomOutAction() {\n        if (zoomOutAction == null) zoomOutAction = new ZoomOutAction();\n        return zoomOutAction;\n    }\n\n    Action toggleViewAction() {\n        if (toggleViewAction == null) {\n            toggleViewAction = new ToggleViewAction();\n            if (TracerOptions.getInstance().getZoomMode().equals(TracerOptions.\n                    SCALE_TO_FIT)) toggleViewAction.actionPerformed(null);\n        }\n        return toggleViewAction;\n    }\n\n\n    AbstractButton mouseZoom() {\n        if (mouseZoom == null) {\n            mouseZoom = new OneWayToggleButton(ZMWHEEL_ICON, Bundle.ACTION_WheelZooms_name()) {\n                protected void performAction() { mouseZoomImpl(); }\n            };\n            if (TracerOptions.getInstance().getMouseWheelAction().equals(\n                    TracerOptions.MOUSE_WHEEL_ZOOMS)) {\n                mouseZoom.setSelected(true);\n                mouseZoomImpl();\n            }\n        }\n        return mouseZoom;\n    }\n\n    AbstractButton mouseHScroll() {\n        if (mouseHScroll == null) {\n            mouseHScroll = new OneWayToggleButton(HMWHEEL_ICON, Bundle.ACTION_WheelHScrolls_name()) {\n                protected void performAction() { mouseHScrollImpl(); }\n            };\n            if (TracerOptions.getInstance().getMouseWheelAction().equals(\n                    TracerOptions.MOUSE_WHEEL_HSCROLLS)) {\n                mouseHScroll.setSelected(true);\n                mouseHScrollImpl();\n            }\n        }\n        return mouseHScroll;\n    }\n\n    AbstractButton mouseVScroll() {\n        if (mouseVScroll == null) {\n            mouseVScroll = new OneWayToggleButton(VMWHEEL_ICON, Bundle.ACTION_WheelVScrolls_name()) {\n                protected void performAction() { mouseVScrollImpl(); }\n            };\n            if (TracerOptions.getInstance().getMouseWheelAction().equals(\n                    TracerOptions.MOUSE_WHEEL_VSCROLLS)) {\n                mouseVScroll.setSelected(true);\n                mouseVScrollImpl();\n            }\n        }\n        return mouseVScroll;\n    }\n\n\n    // --- Mouse wheel handling ------------------------------------------------\n\n    void vScroll(MouseWheelEvent e) {\n        scroll(vScrollBar, e);\n    }\n\n    private void mouseZoomImpl() {\n        clearWheelHandlers();\n        chart.setMouseZoomingEnabled(true);\n        chart.addMouseWheelListener(defaultWheelHandler);\n    }\n\n    private void mouseHScrollImpl() {\n        chart.setMouseZoomingEnabled(false);\n        clearWheelHandlers();\n        setWheelScrollHandler(hScrollBar);\n    }\n\n    private void mouseVScrollImpl() {\n        chart.setMouseZoomingEnabled(false);\n        clearWheelHandlers();\n        setWheelScrollHandler(vScrollBar);\n    }\n\n    private void clearWheelHandlers() {\n        MouseWheelListener[] handlers = chart.getMouseWheelListeners();\n        for (MouseWheelListener handler : handlers)\n            chart.removeMouseWheelListener(handler);\n    }\n\n    private void setWheelScrollHandler(final JScrollBar scrollBar) {\n        chart.addMouseWheelListener(new MouseWheelListener() {\n            public void mouseWheelMoved(MouseWheelEvent e) {\n                scroll(scrollBar, e);\n            }\n        });\n    }\n\n    private static void scroll(JScrollBar scrollBar, MouseWheelEvent e) {\n        if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {\n            int unitsToScroll = e.getUnitsToScroll();\n            if (unitsToScroll != 0) {\n                int direction = unitsToScroll < 0 ? -1 : 1;\n                int increment = scrollBar.getUnitIncrement(direction);\n                int oldValue = scrollBar.getValue();\n                int newValue = oldValue + increment * unitsToScroll;\n                newValue = Math.max(Math.min(newValue, scrollBar.getMaximum() -\n                        scrollBar.getVisibleAmount()), scrollBar.getMinimum());\n                if (oldValue != newValue) scrollBar.setValue(newValue);\n            }\n        }\n    }\n\n\n    // --- Actions support -----------------------------------------------------\n\n    private class ZoomInAction extends AbstractAction {\n\n        private static final int ONE_SECOND_WIDTH_THRESHOLD = 200;\n\n        ZoomInAction() {\n            super();\n\n            putValue(SHORT_DESCRIPTION, Bundle.ACTION_ZoomIn_name());\n            putValue(SMALL_ICON, ZOOM_IN_ICON);\n\n            updateAction();\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            boolean followsWidth = chart.currentlyFollowingDataWidth();\n            chart.zoom(getWidth() / 2, getHeight() / 2, 2d);\n            if (followsWidth) chart.setOffset(chart.maxOffsetX(), chart.getOffsetY());\n\n            chart.repaintDirty();\n        }\n\n        private void updateAction() {\n            Timeline timeline = ((SynchronousXYItemsModel)chart.getItemsModel()).getTimeline();\n            setEnabled(timeline.getTimestampsCount() > 1 && !chart.fitsWidth() &&\n                       chart.viewWidth(1000) < ONE_SECOND_WIDTH_THRESHOLD);\n        }\n\n    }\n\n    private class ZoomOutAction extends AbstractAction {\n\n        private static final float USED_CHART_WIDTH_THRESHOLD = 0.33f;\n\n        ZoomOutAction() {\n            super();\n\n            putValue(SHORT_DESCRIPTION, Bundle.ACTION_ZoomOut_name());\n            putValue(SMALL_ICON, ZOOM_OUT_ICON);\n\n            updateAction();\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            boolean followsWidth = chart.currentlyFollowingDataWidth();\n            chart.zoom(getWidth() / 2, getHeight() / 2, 0.5d);\n            if (followsWidth) chart.setOffset(chart.maxOffsetX(), chart.getOffsetY());\n\n            chart.repaintDirty();\n        }\n\n        private void updateAction() {\n            Timeline timeline = ((SynchronousXYItemsModel)chart.getItemsModel()).getTimeline();\n            setEnabled(timeline.getTimestampsCount() > 0 && !chart.fitsWidth() &&\n                       chart.getContentsWidth() > getWidth() * USED_CHART_WIDTH_THRESHOLD);\n        }\n\n    }\n\n    private class ToggleViewAction extends AbstractAction {\n\n        private long origOffsetX  = -1;\n        private double origScaleX = -1;\n\n        ToggleViewAction() {\n            super();\n            updateAction();\n            addMouseListener(new MouseAdapter() {\n                public void mouseClicked(MouseEvent e) {\n                    if (SwingUtilities.isMiddleMouseButton(e))\n                        actionPerformed(null);\n                }\n            });\n        }\n\n        public void actionPerformed(ActionEvent e) {\n            boolean fitsWidth = chart.fitsWidth();\n\n            if (!fitsWidth) {\n                origOffsetX = chart.getOffsetX();\n                if (chart.tracksDataWidth() && origOffsetX == chart.maxOffsetX())\n                    origOffsetX = Long.MAX_VALUE;\n                origScaleX  = chart.getScaleX();\n            }\n\n            chart.setFitsWidth(!fitsWidth);\n\n            if (fitsWidth && origOffsetX != -1 && origScaleX != -1) {\n                chart.setScale(origScaleX, chart.getScaleY());\n                chart.setOffset(origOffsetX, chart.getOffsetY());\n            }\n\n            updateAction();\n            if (zoomInAction != null) zoomInAction.updateAction();\n            if (zoomOutAction != null) zoomOutAction.updateAction();\n\n            chart.repaintDirty();\n\n        }\n\n        private void updateAction() {\n            boolean fitsWidth = chart.fitsWidth();\n            Icon icon = fitsWidth ? FIXED_SCALE_ICON : SCALE_TO_FIT_ICON;\n            String name = fitsWidth ? Bundle.ACTION_FixedScale_name() : Bundle.ACTION_ScaleToFit_name();\n            putValue(SHORT_DESCRIPTION, name);\n            putValue(SMALL_ICON, icon);\n        }\n\n    }\n\n\n    private static abstract class OneWayToggleButton extends JToggleButton {\n\n        private boolean action;\n\n\n        OneWayToggleButton(Icon icon, String toolTip) {\n            super(icon);\n            setToolTipText(toolTip);\n        }\n\n        protected void processMouseEvent(MouseEvent e) {\n            if (isSelected()) {\n                e.consume();\n                action = false;\n            } else {\n                action = true;\n            }\n            super.processMouseEvent(e);\n        }\n\n        protected void processKeyEvent(KeyEvent e) {\n            if (isSelected()) {\n                e.consume();\n                action = false;\n            } else {\n                action = true;\n            }\n            super.processKeyEvent(e);\n        }\n\n        protected final void fireActionPerformed(ActionEvent e) {\n            if (action) performAction();\n        }\n\n        protected abstract void performAction();\n\n    }\n\n\n    // --- ChartConfigurationListener implementation ---------------------------\n\n    private class VisibleBoundsListener extends ChartConfigurationListener.Adapter {\n\n        public void dataBoundsChanged(long dataOffsetX, long dataOffsetY,\n                                      long dataWidth, long dataHeight,\n                                      long oldDataOffsetX, long oldDataOffsetY,\n                                      long oldDataWidth, long oldDataHeight) {\n\n            if (zoomInAction != null) zoomInAction.updateAction();\n            if (zoomOutAction != null) zoomOutAction.updateAction();\n        }\n\n        public void scaleChanged(double oldScaleX, double oldScaleY,\n                                 double newScaleX, double newScaleY) {\n\n            if (zoomInAction != null) zoomInAction.updateAction();\n            if (zoomOutAction != null) zoomOutAction.updateAction();\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/ContinuousXYPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Polygon;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ContinuousXYPainter extends TimelineXYPainter {\n\n    private static final Polygon POLYGON = new Polygon();\n\n    protected final int lineWidth;\n    protected final Color lineColor;\n    protected final Color fillColor;\n    protected final Color definingColor;\n\n    protected final Stroke lineStroke;\n\n    private final PointsComputer computer;\n\n\n    ContinuousXYPainter(float lineWidth, Color lineColor, Color fillColor,\n                        double dataFactor, PointsComputer computer) {\n\n        super((int)Math.ceil(lineWidth), fillColor != null, dataFactor);\n\n        if (lineColor == null && fillColor == null)\n            throw new IllegalArgumentException(\"lineColor or fillColor must not be null\"); // NOI18N\n\n        this.lineWidth = (int)Math.ceil(lineWidth);\n        this.lineColor = Utils.checkedColor(lineColor);\n        this.fillColor = Utils.checkedColor(fillColor);\n\n        definingColor = lineColor != null ? lineColor : fillColor;\n\n        this.lineStroke = new BasicStroke(lineWidth, BasicStroke.CAP_ROUND,\n                                          BasicStroke.JOIN_ROUND);\n\n        this.computer = computer;\n    }\n\n\n    protected Color getDefiningColor() {\n        return definingColor;\n    }\n\n    protected void paint(XYItem item, List<ItemSelection> highlighted,\n                         List<ItemSelection> selected, Graphics2D g,\n                         Rectangle dirtyArea, SynchronousXYChartContext context) {\n\n        int valuesCount = item.getValuesCount();\n        int extraTrailing = fillColor != null ? 2 : 0;\n\n        Rectangle dirtyExtended = new Rectangle(dirtyArea);\n        dirtyExtended.x -= lineWidth;\n        dirtyExtended.width += lineWidth * 2;\n        int[][] idxs = computer.getVisible(dirtyExtended, valuesCount, context, 1,\n                                           extraTrailing);\n        if (idxs == null) return;\n        int[] visibleIndexes = idxs[0];\n        int npoints = idxs[1][0];\n        int[][] points = computer.createPoints(visibleIndexes, npoints, item,\n                                               dataFactor, context);\n\n        if (fillColor != null) {\n            points[0][npoints - 2] = points[0][npoints - 3];\n            points[1][npoints - 2] = computer.getZeroY(context);\n            points[0][npoints - 1] = points[0][0];\n            points[1][npoints - 1] = points[1][npoints - 2];\n\n            POLYGON.xpoints = points[0];\n            POLYGON.ypoints = points[1];\n            POLYGON.npoints = npoints;\n\n            g.setPaint(fillColor);\n            g.fill(POLYGON);\n        }\n\n        if (lineColor != null) {\n            g.setPaint(lineColor);\n            g.setStroke(lineStroke);\n            g.drawPolyline(points[0], points[1], npoints - extraTrailing);\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/DiscreteXYPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Polygon;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class DiscreteXYPainter extends TimelineXYPainter {\n\n    private static final Polygon POLYGON = new Polygon();\n\n    private static final int[] x3arr = new int[3];\n    private static final int[] y3arr = new int[3];\n    private static final int[] x4arr = new int[4];\n    private static final int[] y4arr = new int[4];\n\n    protected final int lineWidth;\n    protected final Color lineColor;\n    protected final Color fillColor;\n    protected final Color definingColor;\n\n    protected final Stroke lineStroke;\n\n    protected final int width;\n    protected final boolean fixedWidth;\n    protected final boolean topLineOnly;\n    protected final boolean outlineOnly;\n\n    private final PointsComputer computer;\n\n\n    DiscreteXYPainter(float lineWidth, Color lineColor, Color fillColor,\n                      int width, boolean fixedWidth, boolean topLineOnly,\n                      boolean outlineOnly, double dataFactor, PointsComputer computer) {\n\n        super((int)Math.ceil(lineWidth), fillColor != null ||\n              (!topLineOnly && !outlineOnly), dataFactor);\n\n        if (lineColor == null && fillColor == null)\n            throw new IllegalArgumentException(\"lineColor or fillColor must not be null\"); // NOI18N\n\n        this.lineWidth = (int)Math.ceil(lineWidth);\n        this.lineColor = Utils.checkedColor(lineColor);\n        this.fillColor = Utils.checkedColor(fillColor);\n\n        definingColor = lineColor != null ? lineColor : fillColor;\n\n        this.lineStroke = new BasicStroke(lineWidth, BasicStroke.CAP_ROUND,\n                                          BasicStroke.JOIN_ROUND);\n\n        this.width = width;\n        this.fixedWidth = fixedWidth;\n        this.topLineOnly = topLineOnly;\n        this.outlineOnly = outlineOnly;\n\n        this.computer = computer;\n    }\n\n    \n    protected Color getDefiningColor() {\n        return definingColor;\n    }\n\n    protected void paint(XYItem item, List<ItemSelection> highlighted,\n                         List<ItemSelection> selected, Graphics2D g,\n                         Rectangle dirtyArea, SynchronousXYChartContext context) {\n\n        int zeroY = 0;\n        int zeroYLimit = 0;\n        if (fillColor != null || !topLineOnly) {\n            zeroY = Utils.checkedInt(context.getViewY(context.getDataOffsetY()));\n            zeroY = Math.max(Utils.checkedInt(context.getViewportOffsetY()), zeroY);\n            zeroY = Math.min(Utils.checkedInt(context.getViewportOffsetY() +\n                                              context.getViewportHeight()), zeroY);\n            zeroYLimit = zeroY - lineWidth + 1;\n        }\n\n        int outlineWidth = lineColor == null || topLineOnly || outlineOnly ? 0 :\n                           Math.max(1, (width > 0 ? 2 : 1) * lineWidth - 1);\n        int valuesCount = item.getValuesCount();\n\n        if (width > 0 || lineColor == null || topLineOnly) {\n\n            int[][] idxs = computer.getVisible(dirtyArea, valuesCount, context,\n                                               1, 0);\n            if (idxs == null) return;\n            int[] visibleIndexes = idxs[0];\n            int npoints = idxs[1][0];\n            int[][] points = computer.createPoints(visibleIndexes, npoints, item,\n                                                   dataFactor, context);\n            int[] xpoints = points[0];\n            int[] ypoints = points[1];\n            \n\n            int startX = xpoints[0];\n            int stopX;\n            int currentX = startX;\n            int nextX = 0;\n            int itemsOffset = fixedWidth ? 0 : width;\n            \n            for (int i = 0; i < npoints; i++) {\n                int height = zeroY - ypoints[i];\n\n                if (fixedWidth) {\n                    startX = Math.max(startX, currentX - width / 2);\n                    nextX = i == npoints - 1 ? xpoints[i] : xpoints[i + 1];\n                    stopX = currentX + Math.min(width / 2, (nextX - currentX) / 2);\n                } else {\n                    nextX = i == npoints - 1 ? xpoints[i] : xpoints[i + 1];\n                    int diff = nextX - currentX;\n                    itemsOffset = Math.min(diff, width + 1);\n                    stopX = currentX + (diff - itemsOffset) / 2;\n                }\n\n                int segmentWidth = stopX - startX;\n\n                if (fillColor != null && segmentWidth >= outlineWidth) {\n                    g.setColor(fillColor);\n                    g.fillRect(startX, zeroY - height, segmentWidth + 1, height);\n                }\n                if (lineColor != null) {\n                    g.setColor(lineColor);\n                    g.setStroke(lineStroke);\n\n                    if (topLineOnly) {\n                        g.drawLine(startX, zeroY - height, Math.max(startX + 1, stopX), zeroY - height);\n                    } else if (segmentWidth + 1 <= lineWidth) {\n                        g.drawLine(startX, zeroY - height, startX, zeroYLimit);\n                    } else {\n                        int[] xx;\n                        int[] yy;\n\n                        if (i == 0) {\n                            xx = xArr(startX, stopX, stopX);\n                            yy = yArr(zeroY - height, zeroY - height, zeroYLimit);\n                        } else if (i == npoints - 1) {\n                            xx = xArr(startX, startX, stopX);\n                            yy = yArr(zeroYLimit, zeroY - height, zeroY - height);\n                        } else {\n                            xx = xArr(startX, startX, stopX, stopX);\n                            yy = yArr(zeroYLimit, zeroY - height, zeroY - height, zeroYLimit);\n                        }\n\n                        g.drawPolyline(xx, yy, xx.length);\n                    }\n                }\n                \n                currentX = nextX;\n                startX = stopX + itemsOffset;\n            }\n\n        } else {\n\n            int extraPoints = fillColor != null ? 2 : 0;\n            int[][] idxs = computer.getVisible(dirtyArea, valuesCount, context,\n                                               2, extraPoints);\n            if (idxs == null) return;\n            int[] visibleIndexes = idxs[0];\n            int npoints = idxs[1][0];\n            int[][] points = computer.createPoints(visibleIndexes, npoints, item,\n                                                   dataFactor, context);\n            int[] xpoints = points[0];\n            int[] ypoints = points[1];\n            int npointse = npoints;\n            npoints -= extraPoints;\n            \n            int index = 1;\n            int lastX = xpoints[0];\n\n            while (index < npoints - 2) {\n                int currentX = xpoints[index + 1];\n                currentX -= (currentX - lastX) / 2;\n                xpoints[index] = currentX;\n                lastX = xpoints[index + 1];\n                xpoints[index + 1] = currentX;\n                index += 2;\n            }\n\n            if (fillColor != null) {\n                xpoints[npointse - 2] = xpoints[npointse - 3];\n                ypoints[npointse - 2] = zeroY;\n                xpoints[npointse - 1] = xpoints[0];\n                ypoints[npointse - 1] = ypoints[npointse - 2];\n\n                POLYGON.xpoints = xpoints;\n                POLYGON.ypoints = ypoints;\n                POLYGON.npoints = npointse;\n\n                g.setPaint(fillColor);\n                g.fill(POLYGON);\n            }\n\n            g.setColor(lineColor);\n            g.setStroke(lineStroke);\n            g.drawPolyline(xpoints, ypoints, npoints);\n\n            if (!outlineOnly) {\n                g.setColor(lineColor);\n                g.setStroke(lineStroke);\n\n                int i = 1;\n                while (i < npoints - 1) {\n                    int y = ypoints[i] + lineWidth / 2;\n                    if (y < zeroYLimit) g.drawLine(xpoints[i], y, xpoints[i], zeroYLimit);\n                    i += 3;\n                    if (i >= npoints - 1) break;\n                    y = ypoints[i] + lineWidth / 2;\n                    if (y < zeroYLimit) g.drawLine(xpoints[i], y, xpoints[i], zeroYLimit);\n                    i++;\n                }\n            }\n\n        }\n    }\n    \n    private static int[] xArr(int... vals) {\n        if (vals.length == 3) {\n            x3arr[0] = vals[0];\n            x3arr[1] = vals[1];\n            x3arr[2] = vals[2];\n            return x3arr;\n        } else {\n            x4arr[0] = vals[0];\n            x4arr[1] = vals[1];\n            x4arr[2] = vals[2];\n            x4arr[3] = vals[3];\n            return x4arr;\n        }\n    }\n\n    private static int[] yArr(int... vals) {\n        if (vals.length == 3) {\n            y3arr[0] = vals[0];\n            y3arr[1] = vals[1];\n            y3arr[2] = vals[2];\n            return y3arr;\n        } else {\n            y4arr[0] = vals[0];\n            y4arr[1] = vals[1];\n            y4arr[2] = vals[2];\n            y4arr[3] = vals[3];\n            return y4arr;\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/PointsComputer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Rectangle;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class PointsComputer {\n\n    private static final int INDEXES_STEP = 1000;\n\n    private int[] arr1;\n    private int[] arr2;\n    private final int[] count = new int[1];\n    private final int[][] ret = new int[2][];\n\n\n    PointsComputer() {}\n\n\n    void reset() {\n        arr1 = null;\n        arr2 = null;\n    }\n\n    private int[] arr1(int size) {\n        if (arr1 == null || arr1.length < size)\n            arr1 = newArr(size + INDEXES_STEP, true);\n        return arr1;\n    }\n\n    private int[] arr2(int size) {\n        if (arr2 == null || arr2.length < size)\n            arr2 = newArr(size + INDEXES_STEP, false);\n        return arr2;\n    }\n\n    private int[] newArr(int size, boolean arr1) {\n        int[] arr = new int[size];\n        if (arr1) ret[0] = arr;\n        return arr;\n    }\n\n\n    int[][] getVisible(Rectangle dirtyArea, int valuesCount,\n                       SynchronousXYChartContext context,\n                       int extraFactor, int extraTrailing) {\n\n        if (context.getViewWidth() == 0) return null;\n\n        int[][] visibleBounds = context.getVisibleBounds(dirtyArea);\n\n        int firstFirst = visibleBounds[0][0];\n        int firstIndex = firstFirst;\n        if (firstIndex == -1) firstIndex = visibleBounds[0][1];\n        if (firstIndex == -1) return null;\n        // firstIndex - 2: workaround for polyline joins\n        if (firstFirst != -1) firstIndex = Math.max(firstIndex - 2, 0);\n\n        int lastFirst = visibleBounds[1][0];\n        int lastIndex = lastFirst;\n        if (lastIndex == -1) lastIndex = visibleBounds[1][1];\n        if (lastIndex == -1) lastIndex = valuesCount - 1;\n        // lastIndex + 2: workaround for polyline joins\n        if (lastFirst != -1) lastIndex = Math.min(lastIndex + 2, valuesCount - 1);\n\n        int itemsStep = (int)Math.ceil(valuesCount / context.getViewWidth());\n        if (itemsStep == 0) itemsStep = 1;\n\n        int visibleCount = lastIndex - firstIndex + 1;\n\n        if (itemsStep > 1) {\n            int firstMod = firstIndex % itemsStep;\n            firstIndex -= firstMod;\n            int lastMod = lastIndex % itemsStep;\n            lastIndex = lastIndex - lastMod + itemsStep;\n            visibleCount = (lastIndex - firstIndex) / itemsStep + 1;\n            lastIndex = Math.min(lastIndex, valuesCount - 1);\n        }\n\n        int visibleCountEx = extraFactor == 1 ? visibleCount :\n                            (visibleCount - 1) * extraFactor + 2;\n\n        count[0] = visibleCountEx + extraTrailing;\n        int[] visibleIndexes = arr1(count[0]);\n\n        for (int i = 0; i < visibleCountEx; i++) {\n            int index = firstIndex + (i / extraFactor) * itemsStep;\n            if (index > lastIndex) index = lastIndex;\n            visibleIndexes[i] = index;\n        }\n        \n        for (int i = visibleCountEx; i < visibleIndexes.length; i++)\n            visibleIndexes[i] = -1;\n\n        ret[1] = count;\n        return ret;\n    }\n\n    int getZeroY(SynchronousXYChartContext context) {\n        int zeroY = Utils.checkedInt(context.getViewY(context.getDataOffsetY()));\n        zeroY = Math.max(Utils.checkedInt(context.getViewportOffsetY()), zeroY);\n        zeroY = Math.min(Utils.checkedInt(context.getViewportOffsetY() +\n                                          context.getViewportHeight()), zeroY);\n        return zeroY;\n    }\n\n    int[][] createPoints(int[] indexes, int itemsCount, XYItem item,\n                         double dataFactor, SynchronousXYChartContext context) {\n\n        int[] xPoints = indexes;\n        int[] yPoints = arr2(itemsCount);\n\n        for (int i = 0; i < itemsCount; i++) {\n            int dataIndex = xPoints[i];\n            if (dataIndex != -1) {\n                xPoints[i] = Utils.checkedInt(Math.ceil(\n                             context.getViewX(item.getXValue(dataIndex))));\n                yPoints[i] = Utils.checkedInt(Math.ceil(\n                             context.getViewY(item.getYValue(dataIndex) *\n                             dataFactor)));\n            }\n        }\n\n        ret[1] = yPoints;\n        return ret;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/ProbesPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.GridLayout;\nimport java.awt.LayoutManager;\nimport java.awt.Point;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseEvent;\nimport java.util.List;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollBar;\nimport javax.swing.JViewport;\nimport javax.swing.SwingUtilities;\nimport javax.swing.ToolTipManager;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProbe;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.icons.TracerIcons;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.probes.ProbePresenter;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.HeaderButton;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.HeaderLabel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.ScrollBar;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ProbesPanel extends JPanel {\n\n    private final ListPanel listPanel;\n    private final JViewport viewport;\n    private final HeaderButton increaseB;\n    private final HeaderButton decreaseB;\n    private final HeaderButton resetB;\n\n    @NbBundle.Messages({\n        \"TOOLTIP_IncreaseRowsHeight=Increase rows height\",\n        \"TOOLTIP_DecreaseRowsHeight=Decrease rows height\",\n        \"TOOLTIP_ResetRowsHeight=Reset rows height\",\n        \"LBL_Probes=Probes\"\n    })\n    ProbesPanel(final TimelineSupport support) {\n        final TimelineChart chart = support.getChart();\n\n        listPanel = new ListPanel(new VerticalTimelineLayout(chart)) {\n            public Dimension getPreferredSize() {\n                Dimension d = super.getPreferredSize();\n                d.height = Utils.checkedInt(chart.getChartContext().getViewHeight());\n                return d;\n            }\n            protected void updateSelection() {\n                int count = getComponentCount();\n                for (int i = 0; i < count; i++)\n                    ((ProbePresenter)getComponent(i)).setSelected(\n                            chart.isRowSelected(chart.getRow(i)));\n            }\n        };\n\n        viewport = new JViewport() {\n            public String getToolTipText(MouseEvent event) {\n                Point p = event.getPoint();\n                p.y += getViewPosition().y;\n                return listPanel.getToolTipText(p);\n            }\n        };\n        ToolTipManager.sharedInstance().registerComponent(viewport);\n        viewport.setOpaque(true);\n        viewport.setBackground(new Color(247, 247, 247));\n        viewport.setView(listPanel);\n        viewport.setViewPosition(new Point(0, 0));\n        final ViewportUpdater updater = new ViewportUpdater(viewport);\n        chart.addConfigurationListener(new ChartConfigurationListener.Adapter() {\n            public void contentsWillBeUpdated(long offsetX, final long offsetY,\n                                              double scaleX, double scaleY,\n                                              long lastOffsetX, final long lastOffsetY,\n                                              double lastScaleX, double lastScaleY) {\n                if (lastOffsetY != offsetY)\n                    SwingUtilities.invokeLater(updater.forPoint(new Point(\n                            0, Utils.checkedInt(offsetY))));\n            }\n        });\n        final JPanel bottomPanel = new JPanel(new GridLayout(1, 3));\n        bottomPanel.setPreferredSize(new Dimension(100, new ScrollBar(JScrollBar.\n                                     HORIZONTAL).getPreferredSize().height));\n        bottomPanel.setOpaque(false);\n\n        increaseB = new HeaderButton(null, Icons.getIcon(TracerIcons.INCREMENT)) {\n            protected void performAction(ActionEvent e) {\n                chart.increaseRowHeights((e.getModifiers() & Toolkit.getDefaultToolkit().\n                                         getMenuShortcutKeyMask()) == 0);\n            }\n        };\n        increaseB.setToolTipText(Bundle.TOOLTIP_IncreaseRowsHeight());\n        bottomPanel.add(increaseB);\n\n        decreaseB = new HeaderButton(null, Icons.getIcon(TracerIcons.DECREMENT)) {\n            protected void performAction(ActionEvent e) {\n                chart.decreaseRowHeights((e.getModifiers() & Toolkit.getDefaultToolkit().\n                                         getMenuShortcutKeyMask()) == 0);\n            }\n        };\n        decreaseB.setToolTipText(Bundle.TOOLTIP_DecreaseRowsHeight());\n        bottomPanel.add(decreaseB);\n\n        resetB = new HeaderButton(null, Icons.getIcon(TracerIcons.RESET)) {\n            protected void performAction(ActionEvent e) {\n                chart.resetRowHeights();\n            }\n        };\n        resetB.setToolTipText(Bundle.TOOLTIP_ResetRowsHeight());\n        bottomPanel.add(resetB);\n        \n        setOpaque(false);\n        setLayout(new BorderLayout());\n        add(new HeaderLabel(Bundle.LBL_Probes()), BorderLayout.NORTH);\n        add(viewport, BorderLayout.CENTER);\n        add(bottomPanel, BorderLayout.SOUTH);\n\n        chart.addRowListener(new TimelineChart.RowListener() {\n            public void rowsAdded(List<TimelineChart.Row> rows) {\n                for (TimelineChart.Row row : rows) {\n                    TracerProbe probe = support.getProbe(row);\n                    listPanel.add(new ProbePresenter(probe, support.\n                                  getDescriptor(probe)), row.getIndex());\n                }\n                listPanel.sync();\n                revalidate();\n                repaint();\n                refreshButtons(true);\n            }\n\n            public void rowsRemoved(List<TimelineChart.Row> rows) {\n                for (TimelineChart.Row row : rows)\n                    listPanel.remove(row.getIndex());\n                listPanel.sync();\n                revalidate();\n                repaint();\n                refreshButtons(chart.hasRows());\n            }\n\n            public void rowsResized(List<TimelineChart.Row> rows) {\n                listPanel.sync();\n                revalidate();\n                repaint();\n            }\n        });\n\n        refreshButtons(chart.hasRows());\n    }\n\n    \n    public void setCursor(Cursor cursor) {\n        viewport.setCursor(cursor);\n    }\n\n    Component getMouseTarget() {\n        return viewport;\n    }\n\n    void updateSelection() {\n        listPanel.updateSelection();\n    }\n\n\n    private void refreshButtons(boolean enabled) {\n        increaseB.setEnabled(enabled);\n        decreaseB.setEnabled(enabled);\n        resetB.setEnabled(enabled);\n    }\n\n\n    private static class ViewportUpdater implements Runnable {\n\n        private final JViewport viewport;\n        private Point point;\n\n        ViewportUpdater(JViewport viewport) { this.viewport = viewport; }\n\n        Runnable forPoint(Point point) { this.point = point; return this; }\n\n        public void run() { viewport.setViewPosition(point); }\n\n    }\n\n\n    private static class ListPanel extends JPanel {\n\n        ListPanel(LayoutManager layout) {\n            super(layout);\n            setOpaque(false);\n        }\n\n        protected void updateSelection() {\n        }\n        \n        String getToolTipText(Point p) {\n            String tooltip = null;\n            Component c = getComponentAt(p);\n            if (c instanceof JComponent)\n                tooltip = (String)((JComponent)c).getClientProperty(\"ToolTipHelper\"); // NOI18N\n            return tooltip;\n        }\n\n        private void sync() {\n            doLayout();\n            repaint();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/RowBackgroundDecorator.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartDecorator;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class RowBackgroundDecorator implements ChartDecorator {\n\n    private static final Color BACKGROUND = new Color(228, 228, 248);\n\n    private final TimelineChart chart;\n\n\n    RowBackgroundDecorator(TimelineChart chart) {\n        this.chart = chart;\n    }\n\n\n    public void paint(Graphics2D g, Rectangle dirtyArea, ChartContext context) {\n        int rowsCount = chart.getRowsCount();\n        for (int i = 0; i < rowsCount; i++) {\n            TimelineChart.Row row = chart.getRow(i);\n            ChartContext rowContext = row.getContext();\n\n            int y = Utils.checkedInt(rowContext.getViewportOffsetY());\n            int h = Utils.checkedInt(rowContext.getViewportHeight() - 1);\n\n            if (chart.isRowSelected(row)) {\n                    g.setColor(BACKGROUND);\n                    g.fillRect(0, y, chart.getWidth(), h);\n                }\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/RowBoundsDecorator.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartDecorator;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class RowBoundsDecorator implements ChartDecorator {\n\n    private static final Color BORDER_COLOR = Color.LIGHT_GRAY;\n\n    private final TimelineChart chart;\n\n\n    RowBoundsDecorator(TimelineChart chart) {\n        this.chart = chart;\n    }\n\n\n    public void paint(Graphics2D g, Rectangle dirtyArea, ChartContext context) {\n        int rowsCount = chart.getRowsCount();\n        for (int i = 0; i < rowsCount; i++) {\n            TimelineChart.Row row = chart.getRow(i);\n            ChartContext rowContext = row.getContext();\n\n            int y = Utils.checkedInt(rowContext.getViewportOffsetY()) +\n                    rowContext.getViewportHeight() - 1;\n            int w = chart.getWidth();\n\n            g.setColor(BORDER_COLOR);\n            g.drawLine(0, y, w, y);\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/RowForegroundDecorator.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.LinearGradientPaint;\nimport java.awt.Rectangle;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartDecorator;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class RowForegroundDecorator implements ChartDecorator {\n\n    private static final Color SELECTED_FILTER = new Color(0, 0, 200, 25);\n    private static final float[] FRACTIONS = new float[] { 0.0f, 0.49f, 0.51f, 1.0f };\n    private static final Color[] COLORS = !UIUtils.isDarkResultsBackground() ?\n        new Color[] { new Color(250, 251, 252, 120),\n                      new Color(237, 240, 242, 120),\n                      new Color(229, 233, 236, 125),\n                      new Color(215, 221, 226, 130) } :\n        new Color[] { new Color(50, 51, 52, 110),\n                      new Color(37, 40, 42, 110),\n                      new Color(29, 33, 36, 115),\n                      new Color(15, 21, 26, 120) };\n\n    private final TimelineChart chart;\n    private final boolean gradient;\n    private final boolean selection;\n\n\n    RowForegroundDecorator(TimelineChart chart, boolean gradient, boolean selection) {\n        this.chart = chart;\n        this.gradient = gradient;\n        this.selection = selection;\n    }\n\n\n    public void paint(Graphics2D g, Rectangle dirtyArea, ChartContext context) {\n        if (gradient || selection) {\n            int rowsCount = chart.getRowsCount();\n            for (int i = 0; i < rowsCount; i++) {\n                TimelineChart.Row row = chart.getRow(i);\n                ChartContext rowContext = row.getContext();\n\n                int y = Utils.checkedInt(rowContext.getViewportOffsetY());\n                int h = Utils.checkedInt(rowContext.getViewportHeight() - 1);\n\n                if (gradient) {\n                    g.setPaint(new LinearGradientPaint(0, y, 0, y + h, FRACTIONS, COLORS));\n                    g.fillRect(0, y, chart.getWidth(), h);\n                }\n\n                if (selection && chart.isRowSelected(row)) {\n                    g.setColor(SELECTED_FILTER);\n                    g.fillRect(0, y, chart.getWidth(), h);\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineAxis.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Cursor;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Image;\nimport java.awt.Insets;\nimport java.awt.Paint;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseMotionListener;\nimport java.awt.event.MouseWheelEvent;\nimport java.awt.event.MouseWheelListener;\nimport java.awt.image.BufferedImage;\nimport java.text.Format;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.axis.AxisComponent;\nimport org.graalvm.visualvm.lib.charts.axis.AxisMark;\nimport org.graalvm.visualvm.lib.charts.axis.TimeAxisUtils;\nimport org.graalvm.visualvm.lib.charts.axis.TimelineMarksComputer;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.icons.TracerIcons;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.EnhancedLabelRenderer;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.HeaderLabel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.HeaderPanel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.LegendFont;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.TimelineMarksPainter;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineAxis extends JPanel {\n\n    private final HeaderRenderer painter;\n    private final AxisComponent axis;\n    private final MarksComponent marks;\n\n    private int preferredHeight;\n    \n    private int pointerX;\n\n\n    TimelineAxis(final TimelineChart chart, TimelineSupport support) {\n\n        super(null);\n\n        painter = new HeaderRenderer();\n        \n        Timeline timeline = ((SynchronousXYItemsModel)chart.getItemsModel()).getTimeline();\n        axis = new Axis(chart, new MarksComputer(timeline, chart.getChartContext()));\n\n        marks = new MarksComponent(support);\n\n        preferredHeight = HeaderLabel.DEFAULT_HEIGHT;\n\n        add(marks);\n        add(axis);\n        add(painter);\n\n        chart.addConfigurationListener(new ChartConfigurationListener.Adapter() {\n\n            private final Runnable updater = new Runnable() {\n                public void run() {\n                    if (!axis.isVisible()) {\n                        marks.setupTicks();\n                        marks.refreshHoverMark(pointerX);\n                        marks.repaint();\n                    }\n                }\n            };\n\n            public void contentsUpdated(long offsetX, long offsetY,\n                                        double scaleX, double scaleY,\n                                        long lastOffsetX, long lastOffsetY,\n                                        double lastScaleX, double lastScaleY,\n                                        int shiftX, int shiftY) {\n                \n                if (lastOffsetX != offsetX || lastScaleX != scaleX)\n                    marks.refreshMarks();\n                SwingUtilities.invokeLater(updater);\n            }\n\n        });\n\n        support.addSelectionListener(new TimelineSupport.SelectionListener() {\n            \n            public void intervalsSelectionChanged() {\n                marks.refreshMarks();\n                marks.repaint();\n            }\n\n            public void indexSelectionChanged() {}\n\n            public void timeSelectionChanged(boolean timestampsSelected, boolean justHovering) {\n                marks.refreshMarks();\n                marks.repaint();\n            }\n        });\n\n        marks.addMouseListener(new MouseAdapter() {\n            public void mouseEntered(MouseEvent e) {\n                pointerX = e.getX();\n                marks.setupTicks();\n                marks.refreshHoverMark(pointerX);\n                axis.setVisible(false);\n            }\n\n            public void mouseExited(MouseEvent e) {\n                axis.setVisible(true);\n                marks.clearTicks();\n                marks.refreshHoverMark(-10);\n            }\n\n            public void mouseClicked(MouseEvent e) {\n                marks.handleAction();\n                marks.repaint();\n            }\n        });\n\n        marks.addMouseMotionListener(new MouseMotionListener() {\n            public void mouseDragged(MouseEvent e) {\n                pointerX = e.getX();\n            }\n\n            public void mouseMoved(MouseEvent e) {\n                pointerX = e.getX();\n                if (!axis.isVisible()) marks.refreshHoverMark(pointerX);\n            }\n        });\n\n        marks.addMouseWheelListener(new MouseWheelListener() {\n            public void mouseWheelMoved(MouseWheelEvent e) {\n                e.setSource(chart);\n                chart.processMouseWheelEvent(e);\n            }\n        });\n\n    }\n\n\n    public boolean isOptimizedDrawingEnabled() {\n        return false;\n    }\n\n    public Dimension getPreferredSize() {\n        Dimension size = super.getPreferredSize();\n        size.height = preferredHeight;\n        return size;\n    }\n\n\n    public void validate() {}\n    public void doLayout() {}\n\n    public void reshape(int x, int y, int width, int height) {\n        super.reshape(x, y, width, height);\n        painter.reshape(0, 0, width, height);\n        axis.reshape(1, 1, width - 2, height - 2);\n        marks.reshape(0, 0, width, height);\n    }\n\n\n    private static class HeaderRenderer extends HeaderPanel {\n\n        private Image offscreen;\n\n        public void reshape(int x, int y, int width, int height) {\n            if (getWidth() != width || getHeight() != height) offscreen = null;\n            super.reshape(x, y, width, height);\n        }\n\n        long total = 0;\n        int count = 0;\n\n        public void validate() {}\n\n        public void paint(Graphics g) {\n            if (offscreen == null) {\n                offscreen = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);\n                super.paint(offscreen.getGraphics());\n            }\n            g.drawImage(offscreen, 0, 0, null);\n        }\n\n    }\n\n\n    private static class MarksComponent extends JComponent {\n\n        private static final Image MARK = Icons.getImage(TracerIcons.MARK);\n        private static final Image MARK_HIGHL = Icons.getImage(TracerIcons.MARK_HIGHLIGHT);\n        private static final int MARK_EXTENT = MARK.getWidth(null) / 2;\n        private static final int MARK_HEIGHT = MARK.getHeight(null);\n\n        private final TimelineSupport support;\n        private final Timeline timeline;\n        private final SynchronousXYChartContext context;\n\n        private final EnhancedLabelRenderer timeRenderer;\n        private final Format timeFormat;\n\n        private int[] ticks;\n        private int hoverIndex = -1;\n        private int hoverX = -10;\n        private boolean wasSelected;\n        private long hoverTime;\n\n        private final List<Integer> selections = new ArrayList<>();\n        private final List<Integer> intervals = new ArrayList<>();\n        private final int markExtent = 2;\n\n\n        MarksComponent(TimelineSupport support) {\n            this.support = support;\n\n            TimelineChart chart = support.getChart();\n            SynchronousXYItemsModel model = (SynchronousXYItemsModel)chart.getItemsModel();\n            context = (SynchronousXYChartContext)chart.getChartContext();\n            timeline = model.getTimeline();\n\n            timeRenderer = new EnhancedLabelRenderer();\n            if (UIUtils.isAquaLookAndFeel()) {\n                Font f = new LegendFont();\n                timeRenderer.setFont(f.deriveFont(f.getSize2D() - 1));\n                timeRenderer.setMargin(new Insets(0, 2, 0, 2));\n            } else {\n                timeRenderer.setFont(new LegendFont());\n                timeRenderer.setMargin(new Insets(1, 2, 1, 2));\n            }\n            timeRenderer.setBackground(Color.WHITE);\n            timeRenderer.setBorder(BorderFactory.createLineBorder(Color.BLACK));\n            timeFormat = new SimpleDateFormat(TimeAxisUtils.getFormatString(1, 1, 1));\n\n            setOpaque(false);\n        }\n        \n        public void validate() {}\n        public void doLayout() {}\n\n\n        void refreshMarks() {\n            Set<Integer> selectedIndexes = support.getSelectedTimestamps();\n            if (!selectedIndexes.isEmpty() || !selections.isEmpty()) {\n                selections.clear();\n\n                for (int selectedIndex : selectedIndexes) {\n                    long time = timeline.getTimestamp(selectedIndex);\n                    int x = Utils.checkedInt(context.getViewX(time));\n                    if (x > -markExtent && x < getWidth() + markExtent)\n                        selections.add(x + 1);\n                }\n            }\n         \n            \n            List<Integer> selectedIntervals = support.getSelectedIntervals();\n            if (!selectedIntervals.isEmpty() || !intervals.isEmpty()) {\n                intervals.clear();\n                \n                Iterator<Integer> iter = selectedIntervals.iterator();\n                while (iter.hasNext()) {\n                    int start = iter.next();\n                    long time = timeline.getTimestamp(start);\n                    int startX = Utils.checkedInt(context.getViewX(time)) + 1;\n                    \n                    int stop  = iter.hasNext() ? iter.next() : getWidth();\n                    time = timeline.getTimestamp(stop);\n                    int stopX = Utils.checkedInt(context.getViewX(time)) + 1;\n                    \n                    if (startX < getWidth() && stopX > 0) {\n                        intervals.add(startX);\n                        intervals.add(stopX);\n                    }\n                }\n            }\n        }\n\n        void setupTicks() {\n            int[][] idxs = support.getPointsComputer().getVisible(getBounds(),\n                           timeline.getTimestampsCount(), context, 1, 0);\n            ticks = idxs == null ? null : idxs[0];\n            if (ticks != null) for (int i = 0; i < idxs[1][0]; i++)\n                    ticks[i] = Utils.checkedInt(context.getViewX(timeline.\n                                                getTimestamp(ticks[i]))) + 1;\n        }\n\n        void refreshHoverMark(int pointerX) {\n            int lastHoverIndex = hoverIndex;\n\n            hoverIndex = context.getNearestTimestampIndex(pointerX - 1, 0);\n            hoverX = hoverIndex == -1 ? -10 : Utils.checkedInt(context.getViewX(\n                                        timeline.getTimestamp(hoverIndex))) + 1;\n            if (Math.abs(hoverX - pointerX + 1) > MARK_EXTENT) {\n                hoverIndex = -1;\n                hoverX = -10;\n            }\n\n            if (lastHoverIndex != hoverIndex) {\n                if (!wasSelected) support.unselectTimestamp(lastHoverIndex);\n                wasSelected = hoverIndex != -1 && support.isTimestampSelected(hoverIndex);\n                support.setTimestampHovering(hoverIndex != -1, wasSelected);\n                if (hoverIndex != -1) {\n                    support.selectTimestamp(hoverIndex, false);\n                    hoverTime = timeline.getTimestamp(hoverIndex);\n                    if (wasSelected) repaint();\n                } else {\n                    if (!wasSelected) repaint();\n                }\n                if (hoverIndex == -1) setCursor(Cursor.getDefaultCursor());\n                else setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n            }\n\n        }\n\n        void clearTicks() {\n            ticks = null;\n        }\n\n        void handleAction() {\n            wasSelected = !wasSelected;\n            support.setTimestampHovering(hoverIndex != -1, wasSelected);\n        }\n\n        private final Color systemSelection = Utils.getSystemSelection();\n        private final Color selection = new Color(systemSelection.getRed(),\n                               systemSelection.getGreen(),\n                               systemSelection.getBlue(), 150);\n\n        public void paint(Graphics g) {\n            int height = getHeight();\n            int width = getWidth();\n            int top = height / 2 - 1;\n            int bottom = top + 2;\n            \n            g.setColor(selection);\n            if (intervals != null && !intervals.isEmpty()) {\n                Iterator<Integer> iter = intervals.iterator();\n                while (iter.hasNext()) {\n                    int start = iter.next();\n                    int wdth = iter.next() - start + 1;\n                    g.fillRect(start, height - 6, Math.min(wdth, width - start - 3), 3);\n                }\n            }\n            \n            g.setColor(getForeground());\n            if (ticks != null)\n                for (int tick : ticks) g.drawLine(tick, top, tick, bottom);\n\n            if (selections != null && !selections.isEmpty()) {\n                int y = height - 5 - MARK_HEIGHT;\n                for (int x : selections)\n                    g.drawImage((x == hoverX && wasSelected) ? MARK_HIGHL :\n                                MARK, x - MARK_EXTENT + 1, y, null);\n\n                if (hoverIndex != -1) {\n                    timeRenderer.setText(timeFormat.format(hoverTime));\n                    Dimension timeSize = timeRenderer.getPreferredSize();\n                    int timeWidth = timeSize.width;\n                    int extraWidth = MARK_EXTENT + TimelineTooltipOverlay.TOOLTIP_OFFSET;\n                    int timeX = hoverX + extraWidth;\n                    if (timeX > width - timeWidth - TimelineTooltipOverlay.TOOLTIP_MARGIN)\n                        timeX = hoverX - timeWidth - extraWidth;\n                    timeRenderer.setLocation(timeX, top - timeSize.height / 2);\n                    timeRenderer.paint(g);\n                }\n            }\n            \n        }\n\n    }\n\n\n    private static class MarksComputer extends TimelineMarksComputer {\n\n        MarksComputer(Timeline timeline, ChartContext context) {\n            super(timeline, context, SwingConstants.HORIZONTAL);\n        }\n\n        void refresh() {\n            refreshConfiguration();\n        }\n\n    }\n\n\n    private static class Axis extends AxisComponent {\n\n        private static final int LAF_OFFSET = resolveOffset();\n\n        private final Paint meshPaint = Utils.checkedColor(new Color(180, 180, 180, 50));\n        private final Stroke meshStroke = new BasicStroke(1);\n\n        private final TimelineChart chart;\n        private final MarksComputer marksComputer;\n        private final TimelineMarksPainter marksPainter;\n        private boolean hadTicks = false;\n\n        private final Runnable repainter;\n\n\n        Axis(TimelineChart chart, MarksComputer marksComputer) {\n\n            super(chart, marksComputer, null, SwingConstants.NORTH,\n                  AxisComponent.MESH_FOREGROUND);\n\n            this.chart = chart;\n            this.marksComputer = marksComputer;\n            this.marksPainter = new TimelineMarksPainter();\n\n            repainter = Axis.this.chart::invalidateRepaint;\n        }\n\n\n        public void validate() {}\n        public void doLayout() {}\n\n\n        public void paint(Graphics g) {\n            Rectangle clip = g.getClipBounds();\n            if (clip == null) clip = new Rectangle(0, 0, getWidth(), getHeight());\n\n            marksComputer.refresh();\n\n            paintHorizontalAxis(g, clip);\n        }\n\n        protected void paintHorizontalMesh(Graphics2D g, Rectangle clip, Rectangle chartMask) {\n            Iterator<AxisMark> marks =\n                    marksComputer.marksIterator(chartMask.x, chartMask.x + chartMask.width);\n\n            boolean hasTicks = false;\n\n            while (marks.hasNext()) {\n                hasTicks = true;\n\n                AxisMark mark = marks.next();\n                int x = mark.getPosition();\n\n                g.setPaint(meshPaint);\n                g.setStroke(meshStroke);\n                g.drawLine(x, chartMask.y, x, chartMask.y + chartMask.height);\n            }\n\n            if (!hadTicks && hasTicks) SwingUtilities.invokeLater(repainter);\n            hadTicks = hasTicks;\n        }\n\n        protected void paintHorizontalAxis(Graphics g, Rectangle clip) {\n            int viewStart = -1; // -1: extra 1px for axis\n            int viewEnd = viewStart + chart.getWidth() + 2; // +2 extra 1px + 1px for axis\n\n            Iterator<AxisMark> marks = marksComputer.marksIterator(viewStart, viewEnd);\n\n            int lZeroOffset = chart.isRightBased() ? 0 : 1;\n            int rZeroOffset = chart.isRightBased() ? 1 : 0;\n\n            while (marks.hasNext()) {\n                AxisMark mark = marks.next();\n\n                int x = mark.getPosition() - 1;\n\n                if (x < -1 - lZeroOffset ||\n                    x >= -1 + chart.getWidth() + rZeroOffset) continue;\n\n                TimelineMarksPainter painter =\n                        (TimelineMarksPainter)marksPainter.getPainter(mark);\n                Dimension painterSize = painter.getPreferredSize();\n                int markOffsetX = painterSize.width / 2;\n\n                if (x + markOffsetX < clip.x ||\n                    x - markOffsetX >= clip.x + clip.width) continue;\n\n                g.setColor(getForeground());\n                g.drawLine(x, 1, x, 3);\n                \n                int markOffsetY = (getHeight() - painterSize.height) / 2 + LAF_OFFSET;\n                painter.setLocation(x - markOffsetX, markOffsetY);\n                painter.paint(g);\n            }\n        }\n\n        private static int resolveOffset() {\n            if (UIUtils.isWindowsLookAndFeel() ||\n                UIUtils.isMetalLookAndFeel() ||\n                UIUtils.isGTKLookAndFeel()) return 1;\n            return 0;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineChart.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Rectangle;\nimport java.awt.event.MouseWheelEvent;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.TreeSet;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartItemChange;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemPainter;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChart;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineChart extends SynchronousXYChart {\n\n    static final int MIN_ROW_HEIGHT = 20;\n    static final int MAX_ROW_HEIGHT = 500;\n    static final int DEF_ROW_HEIGHT = 40;\n    static final int ROW_RESIZE_STEP = MIN_ROW_HEIGHT;\n\n    private static final int ROW_MARGIN_TOP = 3;\n    private static final int ROW_MARGIN_BOTTOM = 3;\n\n    private int currentRowHeight = DEF_ROW_HEIGHT;\n\n    private final List<Row> rows;\n    private final Map<ChartItem, Row> itemsToRows;\n\n    private final Set selectedRows = new TreeSet(new RowComparator());\n    private final Set selectionBlockers = new HashSet();\n    private int lastHoverMode;\n    private int lastMoveMode;\n\n    private final Set<RowListener> rowListeners = new HashSet<>();\n\n\n    // --- Constructors --------------------------------------------------------\n\n    TimelineChart(SynchronousXYItemsModel itemsModel) {\n        super(itemsModel, new PaintersModel.Default());\n\n        rows = new ArrayList<>();\n        itemsToRows = new HashMap<>();\n\n        setBottomBased(false);\n\n        setZoomMode(ZOOM_X);\n        setMouseZoomingEnabled(false);\n        setMousePanningEnabled(false);\n\n        setAccelerationPriority(1f);\n    }\n\n\n    // --- Rows management -----------------------------------------------------\n\n    Row addRow() {\n        Row row = new Row();\n        int rowIndex = rows.size();\n        row.setIndex(rowIndex);\n        rows.add(row);\n        row.setHeight(currentRowHeight, true);\n        row.updateOffset();\n        updateChart();\n        notifyRowsAdded(Collections.singletonList(row));\n        return row;\n    }\n\n    Row addRow(int rowIndex) {\n        Row row = new Row();\n        row.setIndex(rowIndex);\n        rows.add(rowIndex, row);\n        row.setHeight(currentRowHeight, true);\n        updateRowOffsets(rowIndex);\n        updateRowIndexes(rowIndex + 1);\n        updateChart();\n        notifyRowsAdded(Collections.singletonList(row));\n        return row;\n    }\n\n    Row removeRow(int rowIndex) {\n        return removeRow(rows.get(rowIndex));\n    }\n\n    Row removeRow(Row row) {\n        row.clearItems();\n        rows.remove(row);\n        int rowIndex = row.getIndex();\n        updateRowIndexes(rowIndex);\n        updateRowOffsets(rowIndex);\n        updateChart();\n        notifyRowsRemoved(Collections.singletonList(row));\n        return row;\n    }\n\n\n    // --- Rows access ---------------------------------------------------------\n\n    boolean hasRows() {\n        return !rows.isEmpty();\n    }\n\n    int getRowsCount() {\n        return rows.size();\n    }\n\n    Row getRow(int rowIndex) {\n        return rows.get(rowIndex);\n    }\n\n    Row getRow(ChartItem item) {\n        return itemsToRows.get(item);\n    }\n\n\n    // --- Row appearance ------------------------------------------------------\n\n    void setRowHeight(int rowIndex, int rowHeight) {\n        setRowHeight(rowIndex, rowHeight, true);\n    }\n\n    void setRowHeight(int rowIndex, int rowHeight, boolean checkStep) {\n        Row row = rows.get(rowIndex);\n        boolean changed = row.setHeight(rowHeight, checkStep);\n        updateRowOffsets(rowIndex + 1);\n        if (changed) notifyRowsResized(Collections.singletonList(row));\n        updateChart(); // TODO: update only affected rows!\n    }\n\n    int getRowHeight(int rowIndex) {\n        return rows.get(rowIndex).getHeight();\n    }\n\n    void increaseRowHeights(boolean step) {\n        if (rows.isEmpty()) return;\n        int incr = step ? ROW_RESIZE_STEP : 1;\n        List<Row> resized = new ArrayList<>(rows.size());\n        for (Row row : rows)\n            if (row.setHeight(row.getHeight() + incr, step))\n                resized.add(row);\n        updateRowOffsets(0);\n        if (!resized.isEmpty()) notifyRowsResized(resized);\n        updateChart(); // TODO: update only affected rows!\n        currentRowHeight += incr;\n    }\n\n    void decreaseRowHeights(boolean step) {\n        if (rows.isEmpty()) return;\n        int decr = step ? ROW_RESIZE_STEP : 1;\n        List<Row> resized = new ArrayList<>(rows.size());\n        for (Row row : rows)\n            if (row.setHeight(row.getHeight() - decr, step))\n                resized.add(row);\n        updateRowOffsets(0);\n        if (!resized.isEmpty()) notifyRowsResized(resized);\n        updateChart(); // TODO: update only affected rows!\n        currentRowHeight = Math.max(currentRowHeight - decr, MIN_ROW_HEIGHT);\n    }\n\n    void resetRowHeights() {\n        if (rows.isEmpty()) return;\n        List<Row> resized = new ArrayList<>(rows.size());\n        for (Row row : rows)\n            if (row.setHeight(DEF_ROW_HEIGHT, true))\n                resized.add(row);\n        updateRowOffsets(0);\n        if (!resized.isEmpty()) notifyRowsResized(new ArrayList<>(rows));\n        updateChart(); // TODO: update only affected rows!\n        currentRowHeight = DEF_ROW_HEIGHT;\n    }\n\n    Row getRowAt(int ypos) {\n        ypos += getOffsetY();\n        for (Row row : rows) {\n            int pos = row.getOffset();\n            if (ypos < pos) return null;\n            pos += row.getHeight();\n            if (ypos <= pos) return row;\n        }\n        return null;\n    }\n\n    Row getNearestRow(int ypos, int range, boolean noFirst) {\n        if (rows.isEmpty()) return null;\n        \n        ypos += getOffsetY();\n\n        if (noFirst) {\n            Row row = rows.get(0);\n            int pos = row.getOffset() + row.getHeight();\n            if (ypos < pos - range) return null;\n        }\n\n        for (Row row : rows) {\n            int pos = row.getOffset();\n            if (ypos < pos - range) return null;\n            if (ypos <= pos + range) return row;\n            pos += row.getHeight();\n            if (ypos < pos - range) return null;\n            if (ypos <= pos + range) return row;\n        }\n        return null;\n    }\n\n    private void updateRowOffsets(int rowIndex) {\n        int rowsCount = rows.size();\n        if (rowIndex >= rowsCount) return;\n        for (int i = rowIndex; i < rowsCount; i++)\n            rows.get(i).updateOffset();\n    }\n\n\n    // --- Row events ----------------------------------------------------------\n\n    void addRowListener(RowListener listener) {\n        rowListeners.add(listener);\n    }\n\n    void removeRowListener(RowListener listener) {\n        rowListeners.remove(listener);\n    }\n\n\n    private void notifyRowsAdded(final List<Row> rows) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                for (RowListener listener : rowListeners)\n                    listener.rowsAdded(rows);\n            }\n        });\n    }\n\n    private void notifyRowsRemoved(final List<Row> rows) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                for (RowListener listener : rowListeners)\n                    listener.rowsRemoved(rows);\n            }\n        });\n    }\n\n    private void notifyRowsResized(final List<Row> rows) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                for (RowListener listener : rowListeners)\n                    listener.rowsResized(rows);\n            }\n        });\n    }\n\n\n    // --- Selection support ---------------------------------------------------\n\n    boolean selectRow(Row row) {\n        if (!selectedRows.add(row)) return false;\n        repaintRows();\n        return true;\n    }\n\n    boolean unselectRow(Row row) {\n        if (!selectedRows.remove(row)) return false;\n        repaintRows();\n        return true;\n    }\n\n    boolean setSelectedRow(Row row) {\n        if (row == null) {\n            return clearRowsSelection();\n        } else {\n            if (selectedRows.size() == 1 && selectedRows.contains(row)) return false;\n            selectedRows.clear();\n            selectedRows.add(row);\n            repaintRows();\n            return true;\n        }\n    }\n\n    boolean toggleRowSelection(Row row) {\n        if (selectedRows.contains(row)) return unselectRow(row);\n        else return selectRow(row);\n    }\n\n    boolean clearRowsSelection() {\n        if (selectedRows.isEmpty()) return false;\n        selectedRows.clear();\n        repaintRows();\n        return true;\n    }\n\n    boolean isRowSelected(Row row) {\n        return selectedRows.contains(row);\n    }\n\n    boolean isRowSelection() {\n        return !selectedRows.isEmpty();\n    }\n\n    List<Row> getSelectedRows() {\n        return new ArrayList<>(selectedRows);\n    }\n    \n\n    void updateSelection(boolean enable, Object source) {\n        int blockersSize = selectionBlockers.size();\n        if (enable) selectionBlockers.remove(source);\n        else selectionBlockers.add(source);\n        if (selectionBlockers.size() == blockersSize) return;\n\n        ChartSelectionModel selectionModel = getSelectionModel();\n        if (selectionModel == null) return;\n\n        if (selectionBlockers.isEmpty()) {\n            selectionModel.setHoverMode(lastHoverMode);\n        } else {\n            lastHoverMode = selectionModel.getHoverMode();\n            lastMoveMode = selectionModel.getMoveMode();\n            selectionModel.setHoverMode(ChartSelectionModel.HOVER_NONE);\n        }\n    }\n\n\n    // --- Internal API to access protected methods ----------------------------\n\n    long maxOffsetX() {\n        return super.getMaxOffsetX();\n    }\n\n    double viewWidth(double d) {\n        return super.getViewWidth(d);\n    }\n\n    protected void processMouseWheelEvent(MouseWheelEvent e) {\n        super.processMouseWheelEvent(e);\n    }\n\n\n    // --- Protected implementation --------------------------------------------\n\n    protected ChartContext getChartContext(ChartItem item) {\n        if (item == null) return super.getChartContext(null);\n        else return itemsToRows.get(item).getContext();\n    }\n\n    protected void computeDataBounds() {\n        LongRect.clear(dataBounds);\n\n        if (rows == null) return;\n\n        for (Row row : rows) {\n            RowContext context = (RowContext)row.getContext();\n            if (LongRect.isClear(dataBounds)) LongRect.set(dataBounds, context.bounds);\n            else LongRect.add(dataBounds, context.bounds);\n        }\n\n        dataBounds.y = 0;\n        Row lastRow = rows.isEmpty() ? null : rows.get(rows.size() - 1);\n        dataBounds.height = lastRow != null ? lastRow.getOffset() + lastRow.getHeight() : 0;\n    }\n\n    protected void updateChart() {\n        updateRowBounds();\n        super.updateChart();\n    }\n\n\n    protected void itemsAdded(List<ChartItem> addedItems) {\n        updateRowBounds();\n        super.itemsAdded(addedItems);\n    }\n\n    protected void itemsRemoved(List<ChartItem> removedItems) {\n        updateRowBounds();\n        super.itemsRemoved(removedItems);\n    }\n\n    protected void itemsChanged(List<ChartItemChange> itemChanges) {\n        updateRowBounds(); // NOTE: should be computed from itemChanges!!!\n        super.itemsChanged(itemChanges);\n    }\n\n    protected void paintersChanged(List<ItemPainter> changedPainters) {\n        updateRowBounds();\n        super.paintersChanged(changedPainters);\n    }\n\n\n    // --- Internal implementation ---------------------------------------------\n\n    void addItemsImpl(SynchronousXYItem[] addedItems, ItemPainter[] addedPainters, Row row) {\n        for (SynchronousXYItem item : addedItems) itemsToRows.put(item, row);\n        paintersModel().addPainters(addedItems, addedPainters);\n        itemsModel().addItems(addedItems);\n    }\n\n    void removeItemsImpl(SynchronousXYItem[] removedItems) {\n        itemsModel().removeItems(removedItems);\n        paintersModel().removePainters(removedItems);\n        for (SynchronousXYItem item : removedItems) itemsToRows.remove(item);\n    }\n\n\n    void invalidateRepaint() {\n        invalidateImage();\n        repaintDirty();\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private SynchronousXYItemsModel itemsModel() {\n        return (SynchronousXYItemsModel)getItemsModel();\n    }\n\n    private PaintersModel.Default paintersModel() {\n        return (PaintersModel.Default)getPaintersModel();\n    }\n\n    private void updateRowIndexes(int startIndex) {\n        for (int i = startIndex; i < rows.size(); i++)\n            rows.get(i).setIndex(i);\n    }\n\n    private void repaintRows() {\n        invalidateImage();\n        repaintDirty();\n    }\n\n    private void repaintRows(final int startIndex) {\n        for (int i = startIndex; i < rows.size(); i++) {\n            ChartContext rowContext = rows.get(i).getContext();\n            invalidateImage(new Rectangle(0, Utils.checkedInt(rowContext.\n                           getViewportOffsetY()), getWidth(), rowContext.\n                           getViewportHeight()));\n        }\n        repaintDirty();\n    }\n\n    private void updateRowBounds() {\n        if (rows == null) return; // Happens when called from constructor\n        for (Row row : rows) ((RowContext)row.getContext()).updateBounds();\n    }\n\n\n    // --- Row definition ------------------------------------------------------\n\n    class Row {\n\n        private int rowIndex;\n        private int rowOffset;\n        private int rowHeight;\n        private final List<SynchronousXYItem> items;\n        private final RowContext context;\n\n\n        // --- Constructors ----------------------------------------------------\n\n        Row() {\n            items = new ArrayList<>();\n            context = new RowContext(this);\n        }\n\n\n        // --- Row telemetry ---------------------------------------------------\n\n        int getIndex() {\n            return rowIndex;\n        }\n\n        private void updateOffset() {\n            if (rowIndex != 0) {\n                Row previousRow = rows.get(rowIndex - 1);\n                rowOffset = previousRow.rowOffset + previousRow.rowHeight;\n            } else {\n                rowOffset = 0;\n            }\n        }\n\n        int getOffset() {\n            return rowOffset;\n        }\n\n        private boolean setHeight(int height, boolean checkStep) {\n            height = Math.max(MIN_ROW_HEIGHT, height);\n            height = Math.min(MAX_ROW_HEIGHT, height);\n            if (checkStep) height = height / ROW_RESIZE_STEP * ROW_RESIZE_STEP;\n            boolean changed = rowHeight != height;\n            rowHeight = height;\n            return changed;\n        }\n\n        int getHeight() {\n            return rowHeight;\n        }\n\n\n        // --- Items management ------------------------------------------------\n\n        void addItems(SynchronousXYItemsModel addedItems, PaintersModel addedPainters) {\n            int itemsCount = addedItems.getItemsCount();\n\n            SynchronousXYItem[] addedItemsArr = new SynchronousXYItem[itemsCount];\n            for (int i = 0; i < itemsCount; i++)\n                addedItemsArr[i] = addedItems.getItem(i);\n\n            ItemPainter[] addedPaintersArr = new ItemPainter[itemsCount];\n            for (int i = 0; i < itemsCount; i++)\n                addedPaintersArr[i] = addedPainters.getPainter(addedItemsArr[i]);\n\n            addItems(addedItemsArr, addedPaintersArr);\n        }\n\n        void addItems(SynchronousXYItem[] addedItems, ItemPainter[] addedPainters) {\n            for (SynchronousXYItem item : addedItems) items.add(item);\n            addItemsImpl(addedItems, addedPainters, this);\n        }\n\n        void removeItems(SynchronousXYItemsModel removedItems) {\n            int itemsCount = removedItems.getItemsCount();\n\n            SynchronousXYItem[] removedItemsArr = new SynchronousXYItem[itemsCount];\n            for (int i = 0; i < itemsCount; i++)\n                removedItemsArr[i] = removedItems.getItem(i);\n\n            removeItems(removedItemsArr);\n        }\n\n        void removeItems(SynchronousXYItem[] removedItems) {\n            removeItemsImpl(removedItems);\n            for (SynchronousXYItem item : removedItems) items.remove(item);\n        }\n\n\n        // --- Items access ----------------------------------------------------\n\n        int getItemsCount() {\n            return items.size();\n        }\n\n        ChartItem getItem(int itemIndex) {\n            return items.get(itemIndex);\n        }\n\n        SynchronousXYItem[] getItems() {\n            return items.toArray(new SynchronousXYItem[0]);\n        }\n\n        @SuppressWarnings(\"element-type-mismatch\")\n        boolean containsItem(ChartItem item) {\n            return items.contains(item);\n        }\n\n\n        // --- Row context -----------------------------------------------------\n\n        ChartContext getContext() {\n            return context;\n        }\n\n\n        // --- Internal interface ----------------------------------------------\n\n        private void setIndex(int rowIndex) {\n            this.rowIndex = rowIndex;\n        }\n\n        private void clearItems() {\n            if (items.isEmpty()) return;\n            removeItemsImpl(getItems());\n        }\n\n    }\n\n\n    // --- RowContext implementation -------------------------------------------\n\n    private class RowContext extends SynchronousXYChart.Context {\n\n        private final Row row;\n\n        private final LongRect bounds;\n        private double scaleY;\n\n        private int marginTop;\n        private int marginBottom;\n\n\n        RowContext(Row row) {\n            super(TimelineChart.this);\n            this.row = row;\n\n            marginTop = ROW_MARGIN_TOP;\n            marginBottom = ROW_MARGIN_BOTTOM;\n\n            bounds = new LongRect();\n        }\n\n\n        protected void updateBounds() {\n            LongRect.clear(bounds);\n\n            PaintersModel painters = paintersModel();\n            int itemsCount = row.getItemsCount();\n\n            for (int i = 0; i < itemsCount; i++) {\n                ChartItem item = row.getItem(i);\n                ItemPainter painter = painters.getPainter(item);\n                LongRect itemBounds = painter.getItemBounds(item);\n                if (LongRect.isClear(bounds)) {\n                    LongRect.set(bounds, itemBounds);\n                } else if (LongRect.isEmpty(itemBounds)) { // Zero height (constant value)\n                    LongRect.add(bounds, itemBounds.x, itemBounds.height);\n                } else {\n                    LongRect.add(bounds, itemBounds);\n                }\n            }\n\n            double oldScaleY = scaleY;\n            scaleY = (double)(row.getHeight() - marginTop - marginBottom) /\n                     (double)(bounds.height == 0 ? 1 : bounds.height);\n\n            if (scaleY != oldScaleY) invalidateImage(Utils.checkedRectangle(\n                                                     getViewRect(bounds)));\n        }\n\n\n        public boolean isBottomBased() { return true; }\n\n        public boolean fitsHeight() { return true; }\n\n        public long getDataOffsetY() { return bounds.y; }\n\n        public long getDataHeight() { return bounds.height; }\n\n        public long getViewHeight() { return row.getHeight(); }\n\n        public long getViewportOffsetY() { return row.getOffset() - getOffsetY(); }\n\n        public int getViewportHeight() { return row.getHeight(); }\n\n        public double getViewY(double dataY) { return getViewY(dataY, false); }\n\n        public double getReversedViewY(double dataY) { return getViewY(dataY, true); }\n\n        public double getViewHeight(double dataHeight) { return dataHeight * scaleY; }\n\n        public double getDataY(double viewY) { return getDataY(viewY, false); }\n\n        public double getReversedDataY(double viewY) { return getDataY(viewY, true); }\n\n        public double getDataHeight(double viewHeight) { return viewHeight / scaleY; }\n\n\n        private double getViewY(double dataY, boolean reverse) {\n            if (isBottomBased() && !reverse || !isBottomBased() && reverse) {\n                return row.getHeight() - (dataY - bounds.y) * scaleY - getOffsetY() +\n                       getViewInsets().top - marginBottom + row.getOffset();\n            } else {\n                return (dataY - bounds.y) * scaleY - getOffsetY() +\n                       getViewInsets().top + marginTop + row.getOffset();\n            }\n        }\n\n        private double getDataY(double viewY, boolean reverse) {\n            if ((isBottomBased() && !reverse) || (!isBottomBased() && reverse)) {\n                return bounds.y - (viewY + getViewInsets().bottom - marginBottom -\n                       getOffsetY() - getHeight()) / scaleY;\n            } else {\n                return (viewY + getOffsetY() - getViewInsets().top - marginTop) /\n                       scaleY + bounds.y;\n            }\n        }\n\n    }\n\n\n    private static class RowComparator implements Comparator<Row> {\n\n        public int compare(Row r1, Row r2) {\n            int r1i = r1.getIndex();\n            int r2i = r2.getIndex();\n            return (Integer.compare(r1i, r2i));\n        }\n\n    }\n\n\n    public static interface RowListener {\n\n        public void rowsAdded(List<Row> rows);\n\n        public void rowsRemoved(List<Row> rows);\n\n        public void rowsResized(List<Row> rows);\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineColorFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Color;\n\n/**\n * Utility class to access colors predefined for VisualVM.\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineColorFactory {\n\n    private static final Color[] PREDEFINED_COLORS = new Color[] {\n                                                new Color(241, 154,  42),\n                                                new Color( 32, 171, 217),\n                                                new Color(144,  97, 207),\n                                                new Color(158, 156,   0)\n    };\n\n    private static final Color[][] PREDEFINED_GRADIENTS = new Color[][] {\n        new Color[] { new Color(245, 204, 152), new Color(255, 243, 226) },\n        new Color[] { new Color(151, 223, 246), new Color(227, 248, 255) },\n        new Color[] { new Color(200, 163, 248), new Color(242, 232, 255) },\n        new Color[] { new Color(212, 211, 131), new Color(244, 243, 217) }\n    };\n\n\n    /**\n     * Returns a color predefined for VisualVM charts.\n     *\n     * @param index index of the predefined color\n     * @return color predefined for VisualVM charts\n     */\n    private static Color getPredefinedColor(int index) {\n        return PREDEFINED_COLORS[index];\n    }\n\n    static Color getColor(int index) {\n        Color color;\n\n        if (index >= PREDEFINED_COLORS.length) {\n            color = getPredefinedColor(index % PREDEFINED_COLORS.length);\n            int darkerFactor = index / PREDEFINED_COLORS.length;\n            while (darkerFactor-- > 0) color = color.darker();\n        } else {\n            color = getPredefinedColor(index);\n        }\n\n        return color;\n    }\n\n\n    /**\n     * Returns a color pair predefined for VisualVM charts gradients.\n     *\n     * @param index index of the predefined color pair\n     * @return color pair predefined for VisualVM charts gradients\n     */\n    private static Color[] getPredefinedGradient(int index) {\n        return PREDEFINED_GRADIENTS[index];\n    }\n\n    static Color[] getGradient(int index) {\n        Color[] colors = null;\n\n        if (index >= PREDEFINED_GRADIENTS.length) {\n            colors = getPredefinedGradient(index % PREDEFINED_GRADIENTS.length);\n            int darkerFactor = index / PREDEFINED_GRADIENTS.length;\n            while (darkerFactor-- > 0) {\n                colors[0] = colors[0].darker();\n                colors[1] = colors[1].darker();\n            }\n        } else {\n            colors = getPredefinedGradient(index);\n        }\n\n        return colors;\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineIconPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport java.util.List;\nimport javax.swing.Icon;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartItemChange;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemChange;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.IdeSnapshot;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.icons.TracerIcons;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass TimelineIconPainter extends TimelineXYPainter {\n\n    private static final Icon ICON = Icons.getIcon(TracerIcons.GENERIC_ACTION);\n\n    private static final int ICON_EXTENT = 8;\n\n    protected final Color color;\n    protected final IdeSnapshot snapshot;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    TimelineIconPainter(Color color, IdeSnapshot snapshot) {\n        super(ICON_EXTENT, true, 1);\n        this.color = color;\n        this.snapshot = snapshot;\n    }\n\n\n    // --- Abstract interface --------------------------------------------------\n\n    protected void paint(XYItem item, List<ItemSelection> highlighted,\n                         List<ItemSelection> selected, Graphics2D g,\n                         Rectangle dirtyArea, SynchronousXYChartContext\n                         context) {\n\n        if (context.getViewWidth() == 0) return;\n        \n        int[][] visibleBounds = context.getVisibleBounds(dirtyArea);\n\n        int firstFirst = visibleBounds[0][0];\n        int firstIndex = firstFirst;\n        if (firstIndex == -1) firstIndex = visibleBounds[0][1];\n        if (firstIndex == -1) return;\n\n        int minX = dirtyArea.x - ICON_EXTENT;\n        while (context.getViewX(item.getXValue(firstIndex)) > minX && firstIndex > 0) firstIndex--;\n\n        int endIndex = item.getValuesCount() - 1;\n        int lastFirst = visibleBounds[1][0];\n        int lastIndex = lastFirst;\n        if (lastIndex == -1) lastIndex = visibleBounds[1][1];\n        if (lastIndex == -1) lastIndex = endIndex;\n\n        int maxX = dirtyArea.x + dirtyArea.width + ICON_EXTENT;\n        while (context.getViewX(item.getXValue(lastIndex)) < maxX && lastIndex < endIndex) lastIndex++;\n\n        g.setColor(color);\n\n        for (int index = firstIndex; index <= lastIndex; index++) {\n            long dataY = item.getYValue(index);\n            if (dataY == 0) continue;\n\n            long dataX = item.getXValue(index);\n            int  viewX = Utils.checkedInt(context.getViewX(dataX));\n            Icon icon = snapshot.getLogInfoForValue(dataY).getIcon();\n            if (icon == null) icon = ICON;\n            int iconWidth = icon.getIconWidth();\n            int iconHeight = icon.getIconHeight();\n            icon.paintIcon(null, g, viewX - iconWidth / 2, (context.getViewportHeight() - iconHeight) / 2);\n        }\n    }\n\n    protected Color getDefiningColor() { return color; }\n    \n\n    // --- ItemPainter implementation ------------------------------------------\n\n    public LongRect getItemBounds(ChartItem item) {\n        XYItem xyItem = (XYItem)item;\n        return getDataBounds(xyItem.getBounds());\n    }\n\n    public LongRect getItemBounds(ChartItem item, ChartContext context) {\n        XYItem xyItem = (XYItem)item;\n        return getViewBounds(xyItem.getBounds(), context);\n    }\n\n\n    public boolean isBoundsChange(ChartItemChange itemChange) {\n        XYItemChange change = (XYItemChange)itemChange;\n        return !LongRect.equals(change.getOldValuesBounds(),\n                                change.getNewValuesBounds());\n    }\n\n    public boolean isAppearanceChange(ChartItemChange itemChange) {\n        XYItemChange change = (XYItemChange)itemChange;\n        LongRect dirtyBounds = change.getDirtyValuesBounds();\n        return dirtyBounds.width != 0 && dirtyBounds.height != 0;\n    }\n\n    public LongRect getDirtyBounds(ChartItemChange itemChange, ChartContext context) {\n        XYItemChange change = (XYItemChange)itemChange;\n        return getViewBounds(change.getDirtyValuesBounds(), context);\n    }\n\n\n    public boolean supportsHovering(ChartItem item) {\n        return true;\n    }\n\n    public boolean supportsSelecting(ChartItem item) {\n        return true;\n    }\n\n    public LongRect getSelectionBounds(ItemSelection selection, ChartContext context) {\n\n        XYItemSelection sel = (XYItemSelection)selection;\n        XYItem item  = sel.getItem();\n        int selectedValueIndex = sel.getValueIndex();\n\n        if (selectedValueIndex == -1 ||\n            selectedValueIndex >= item.getValuesCount())\n            // This happens on reset - bounds of the selection are unknown, let's clear whole area\n            return new LongRect(0, 0, context.getViewportWidth(),\n                                context.getViewportHeight());\n        else\n            return getViewBounds(item, selectedValueIndex, context);\n    }\n\n    public XYItemSelection getClosestSelection(ChartItem item, int viewX,\n                                               int viewY, ChartContext context) {\n\n        SynchronousXYChartContext contx = (SynchronousXYChartContext)context;\n        SynchronousXYItem xyItem = (SynchronousXYItem)item;\n\n        int nearestTimestampIndex = contx.getNearestTimestampIndex(viewX, viewY);\n        if (nearestTimestampIndex == -1) return new XYItemSelection.Default(xyItem,\n                nearestTimestampIndex, ItemSelection.DISTANCE_UNKNOWN);\n\n        int minX = viewX - ICON_EXTENT;\n        int maxX = viewX + ICON_EXTENT;\n        int itemX = Utils.checkedInt(contx.getViewX(xyItem.getXValue(nearestTimestampIndex)));\n        if (itemX > maxX || itemX < minX) return new XYItemSelection.Default(xyItem,\n                nearestTimestampIndex, ItemSelection.DISTANCE_UNKNOWN);\n\n        int closest = -1;\n        int index = nearestTimestampIndex;\n        while (index < xyItem.getValuesCount()) {\n            if (Utils.checkedInt(contx.getViewX(xyItem.getXValue(index))) > maxX) break;\n            if (xyItem.getYValue(index) != 0) closest = index;\n            index++;\n        }\n\n        if (closest != -1) return new XYItemSelection.Default(xyItem, closest,\n                ItemSelection.DISTANCE_UNKNOWN);\n\n        index = nearestTimestampIndex - 1;\n        while (index >= 0) {\n            if (Utils.checkedInt(contx.getViewX(xyItem.getXValue(index))) < minX) break;\n            if (xyItem.getYValue(index) != 0) closest = index;\n            index--;\n        }\n\n        if (closest != -1) return new XYItemSelection.Default(xyItem, closest,\n                ItemSelection.DISTANCE_UNKNOWN);\n\n        return new XYItemSelection.Default(xyItem, nearestTimestampIndex,\n                ItemSelection.DISTANCE_UNKNOWN);\n    }\n\n\n    // --- XYItemPainter implementation ----------------------------------------\n\n    public double getItemView(double dataY, XYItem item, ChartContext context) {\n        return -1;\n    }\n\n    public double getItemValue(double viewY, XYItem item, ChartContext context) {\n        return -1;\n    }\n\n    public double getItemValueScale(XYItem item, ChartContext context) {\n        return -1;\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private LongRect getDataBounds(LongRect itemBounds) {\n\n        LongRect bounds = new LongRect(itemBounds);\n        bounds.y = 0;\n        bounds.height = 1000;\n        return bounds;\n    }\n\n    private LongRect getViewBounds(LongRect itemBounds, ChartContext context) {\n\n        boolean isData = itemBounds.height != 0;\n\n        LongRect viewBounds = context.getViewRect(itemBounds);\n\n        if (isData) {\n            viewBounds.y = Utils.checkedInt(context.getViewY(context.getDataHeight() / 2));\n            viewBounds.height = 0;\n            LongRect.addBorder(viewBounds, ICON_EXTENT);\n        } else {\n            LongRect.clear(viewBounds);\n        }\n        \n        return viewBounds;\n    }\n\n    private LongRect getViewBounds(XYItem item, int valueIndex, ChartContext context) {\n        long xValue = item.getXValue(valueIndex);\n        LongRect viewBounds = new LongRect(Utils.checkedInt(context.getViewX(xValue)),\n                                           Utils.checkedInt(context.getViewY(context.\n                                           getDataHeight() / 2)), 0, 0);\n\n        if (item.getYValue(valueIndex) != 0) LongRect.addBorder(viewBounds, ICON_EXTENT);\n\n        return viewBounds;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineLegendOverlay.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartOverlay;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.ColorIcon;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.LabelRenderer;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.LegendFont;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineLegendOverlay extends ChartOverlay {\n\n    private final TimelineChart chart;\n    private final LabelRenderer painter;\n\n\n    TimelineLegendOverlay(TimelineChart chart) {\n        this.chart = chart;\n\n        painter = new LabelRenderer();\n        painter.setFont(new LegendFont());\n\n        int size = painter.getFont().getSize() - 3;\n        ColorIcon.setup(size, size,\n                LegendFont.FOREGROUND_COLOR, LegendFont.BACKGROUND_COLOR);\n    }\n\n\n    private void setupPainter(String text, Color color) {\n        painter.setText(text);\n        painter.setIcon(ColorIcon.fromColor(color));\n    }\n\n\n    public void paint(Graphics g) {\n        int rowsCount = chart.getRowsCount();\n        for (int i = 0; i < rowsCount; i++) {\n            TimelineChart.Row row = chart.getRow(i);\n            ChartContext rowContext = row.getContext();\n            SynchronousXYItem[] rowItems = row.getItems();\n\n            int x = 3;\n            int y = -1;\n\n            for (SynchronousXYItem rowItem : rowItems) {\n                TimelineXYPainter itemPainter =\n                        (TimelineXYPainter)chart.getPaintersModel().getPainter(rowItem);\n                if (itemPainter.isPainting()) {\n                    setupPainter(rowItem.getName(), itemPainter.getDefiningColor());\n                    Dimension pd = painter.getPreferredSize();\n                    if (y == -1)\n                        y = Utils.checkedInt(rowContext.getViewportOffsetY()) +\n                            rowContext.getViewportHeight() - pd.height - 1;\n                    paint(g, x, y);\n                    x += pd.width + 10;\n                }\n            }\n        }\n    }\n\n    private void paint(Graphics g, int x, int y) {\n        painter.setLocation(x, y + 1);\n        painter.setForeground(LegendFont.BACKGROUND_COLOR);\n        painter.paint(g);\n\n        painter.setLocation(x, y);\n        painter.setForeground(LegendFont.FOREGROUND_COLOR);\n        painter.setIcon(ColorIcon.BOTTOM_SHADOW);\n        painter.paint(g);\n    }\n\n    // --- Performance tweaks ---------------------------------------------------\n\n    public void invalidate() {}\n\n    public void update(Graphics g) {}\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineModel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items.ValueItemDescriptor;\n\n/**\n * All methods must be invoked from the EDT.\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineModel implements Timeline {\n\n    private static final int STORAGE_BUFFER_STEP = 50;\n\n    private int bufferStep;\n\n    private int valuesCount;\n    private long[] timestamps;\n    private long[][] values;\n\n    private final List<TimelineXYItem> items = new ArrayList<>();\n\n\n    TimelineModel() {\n        this(STORAGE_BUFFER_STEP);\n    }\n\n    private TimelineModel(int bufferStep) {\n        this.bufferStep = bufferStep;\n        reset();\n    }\n\n\n    int getItemsCount() {\n        return items.size();\n    }\n\n\n    TimelineXYItem[] createItems(ProbeItemDescriptor[] itemDescriptors) {\n        int itemsCount = values == null ? 0 : values.length;\n        int addedItemsCount = itemDescriptors.length;\n        TimelineXYItem[] itemsArr = new TimelineXYItem[addedItemsCount];\n\n        for (int i = 0; i < addedItemsCount; i++) {\n            if (itemDescriptors[i] instanceof ValueItemDescriptor) {\n                ValueItemDescriptor d = (ValueItemDescriptor)itemDescriptors[i];\n                itemsArr[i] = new TimelineXYItem(d.getName(), d.getMinValue(),\n                                                 d.getMaxValue(), itemsCount + i) {\n                    public long getYValue(int valueIndex) {\n                        return values[getIndex()][valueIndex];\n                    }\n                };\n            } else {\n                // Reserved for non-value items\n            }\n            items.add(itemsArr[i]);\n        }\n\n        addItemsImpl(addedItemsCount);\n\n        return itemsArr;\n    }\n\n    void removeItems(SynchronousXYItem[] removed) {\n        removeItemsImpl(removed.length);\n\n        int firstRemovedIndex = ((TimelineXYItem)removed[0]).getIndex();\n        for (SynchronousXYItem item : removed)\n            items.remove(firstRemovedIndex);\n        for (int i = firstRemovedIndex; i < items.size(); i++)\n            items.get(i).setIndex(i);\n    }\n\n\n    void addValues(long timestamp, long[] newValues) {\n        updateStorage();\n        \n        // Check last timestamp whether greater than the new one\n        long lastTimestamp = valuesCount == 0 ? -1 : timestamps[valuesCount - 1];\n        // Silently increase timestamp, JVM was busy - timer out of sync\n        if (lastTimestamp >= timestamp) timestamp = lastTimestamp + 1;\n\n        timestamps[valuesCount] = timestamp;\n        for (int i = 0; i < values.length; i++)\n            values[i][valuesCount] = newValues[i];\n\n        valuesCount++;\n    }\n    \n\n    void reset() {\n        valuesCount = 0;\n\n        timestamps = null;\n        if (values != null) {\n            if (values.length == 0) {\n                values = null;\n            } else {\n                Arrays.fill(values, new long[0]);\n            }\n        }\n    }\n\n\n    private void addItemsImpl(int addedItemsCount) {\n        int newItemsCount = (values == null ? 0 : values.length) + addedItemsCount;\n        values = new long[newItemsCount][];\n        reset();\n    }\n\n    private void removeItemsImpl(int removedItemsCount) {\n        values = new long[values.length - removedItemsCount][];\n        reset();\n    }\n\n\n    public int getTimestampsCount() {\n        return valuesCount;\n    }\n\n    public long getTimestamp(int index) {\n        return timestamps[index];\n    }\n\n\n    private void updateStorage() {\n        if (timestamps == null) {\n            timestamps = new long[bufferStep];\n            for (int i = 0; i < values.length; i++)\n                values[i] = new long[bufferStep];\n        } else if (valuesCount == timestamps.length) {\n            timestamps = extendArray(timestamps, bufferStep);\n            for (int i = 0; i < values.length; i++)\n                values[i] = extendArray(values[i], bufferStep);\n        }\n    }\n\n    private static long[] extendArray(long[] array, int extraLength) {\n        int originalLength = array.length;\n        long[] newArray = new long[originalLength + extraLength];\n        System.arraycopy(array, 0, newArray, 0, originalLength);\n        return newArray;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelinePaintersFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Color;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.IdeSnapshot;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items.ContinuousXYItemDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items.DiscreteXYItemDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items.IconItemDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items.ValueItemDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items.XYItemDescriptor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelinePaintersFactory {\n\n    static TimelineXYPainter createPainter(ProbeItemDescriptor descriptor,\n                                           int itemIndex, PointsComputer c,\n                                           IdeSnapshot snapshot) {\n\n        // --- ValueItem -------------------------------------------------------\n        if (descriptor instanceof ValueItemDescriptor)\n            return createValuePainter((ValueItemDescriptor)descriptor, itemIndex, c, snapshot);\n\n        return null;\n    }\n\n    private static TimelineXYPainter createValuePainter(\n            ValueItemDescriptor descriptor, int itemIndex, PointsComputer c,\n            IdeSnapshot snapshot) {\n\n        // --- XYItem ----------------------------------------------------------\n        if (descriptor instanceof ContinuousXYItemDescriptor)\n            return createContinuousPainter((ContinuousXYItemDescriptor)descriptor, itemIndex, c);\n\n        // --- BarItem ---------------------------------------------------------\n        if (descriptor instanceof DiscreteXYItemDescriptor)\n            return createDiscretePainter((DiscreteXYItemDescriptor)descriptor, itemIndex, c);\n\n        // --- IconItem --------------------------------------------------------\n        if (descriptor instanceof IconItemDescriptor)\n            return createIconPainter((IconItemDescriptor)descriptor, itemIndex, snapshot);\n\n        return null;\n    }\n\n    private static TimelineXYPainter createContinuousPainter(\n            XYItemDescriptor descriptor, int itemIndex, PointsComputer c) {\n\n        double dataFactor = descriptor.getDataFactor();\n\n        float lineWidth = descriptor.getLineWidth();\n        if (lineWidth == ProbeItemDescriptor.DEFAULT_LINE_WIDTH)\n            lineWidth = 2f;\n\n        Color lineColor = descriptor.getLineColor();\n        if (lineColor == ProbeItemDescriptor.DEFAULT_COLOR)\n            lineColor = TimelineColorFactory.getColor(itemIndex);\n\n        Color fillColor = descriptor.getFillColor();\n        if (fillColor == ProbeItemDescriptor.DEFAULT_COLOR) {\n            if (lineColor == null)\n                fillColor = TimelineColorFactory.getColor(itemIndex);\n            else\n                fillColor = TimelineColorFactory.getGradient(itemIndex)[0];\n        }\n\n        return new ContinuousXYPainter(lineWidth, lineColor, fillColor, dataFactor, c);\n    }\n\n    private static DiscreteXYPainter createDiscretePainter(\n            DiscreteXYItemDescriptor descriptor, int itemIndex, PointsComputer c) {\n\n        double dataFactor = descriptor.getDataFactor();\n\n        float lineWidth = descriptor.getLineWidth();\n        if (lineWidth == ProbeItemDescriptor.DEFAULT_LINE_WIDTH)\n            lineWidth = 2f;\n\n        Color lineColor = descriptor.getLineColor();\n        if (lineColor == ProbeItemDescriptor.DEFAULT_COLOR)\n            lineColor = TimelineColorFactory.getColor(itemIndex);\n\n        Color fillColor = descriptor.getFillColor();\n        if (fillColor == ProbeItemDescriptor.DEFAULT_COLOR) {\n            if (lineColor == null)\n                fillColor = TimelineColorFactory.getColor(itemIndex);\n            else\n                fillColor = TimelineColorFactory.getGradient(itemIndex)[0];\n        }\n\n        return new DiscreteXYPainter(lineWidth, lineColor, fillColor, descriptor.getWidth(),\n                                     descriptor.isFixedWidth(), descriptor.isTopLineOnly(),\n                                     descriptor.isOutlineOnly(), dataFactor, c);\n    }\n\n    private static TimelineIconPainter createIconPainter(\n            IconItemDescriptor descriptor, int itemIndex, IdeSnapshot snapshot) {\n\n        Color color = descriptor.getColor();\n        if (color == ProbeItemDescriptor.DEFAULT_COLOR)\n            color = TimelineColorFactory.getColor(itemIndex);\n\n        return new TimelineIconPainter(color, snapshot);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelinePanel.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.BorderLayout;\nimport java.awt.Cursor;\nimport java.awt.Toolkit;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseWheelEvent;\nimport java.awt.event.MouseWheelListener;\nimport javax.swing.AbstractButton;\nimport javax.swing.Action;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class TimelinePanel extends JPanel {\n\n    private final ChartPanel chartPanel;\n    private final RowMouseHandler mouseHandler;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    public TimelinePanel(TimelineSupport support) {\n        super(new BorderLayout());\n        setOpaque(false);\n\n        ProbesPanel probesPanel = new ProbesPanel(support);\n        chartPanel = new ChartPanel(support.getChart(), support);\n\n        add(probesPanel, BorderLayout.WEST);\n        add(chartPanel, BorderLayout.CENTER);\n\n        new ProbesWheelHandler(chartPanel, probesPanel).register();\n        mouseHandler = new RowMouseHandler(support, probesPanel);\n        mouseHandler.register();\n    }\n\n\n    // --- Public interface ----------------------------------------------------\n\n    public void reset() {\n        chartPanel.resetChart();\n        resetSelection();\n    }\n\n    public void resetSelection() {\n        chartPanel.resetSelection();\n    }\n\n    public void updateActions() {\n        chartPanel.updateActions();\n    }\n\n    public Action zoomInAction() {\n        return chartPanel.zoomInAction();\n    }\n\n    public Action zoomOutAction() {\n        return chartPanel.zoomOutAction();\n    }\n\n    public Action toggleViewAction() {\n        return chartPanel.toggleViewAction();\n    }\n\n    public AbstractButton mouseZoom() {\n        return chartPanel.mouseZoom();\n    }\n\n    public AbstractButton mouseHScroll() {\n        return chartPanel.mouseHScroll();\n    }\n\n    public AbstractButton mouseVScroll() {\n        return chartPanel.mouseVScroll();\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private static class ProbesWheelHandler implements MouseWheelListener {\n\n        private final ChartPanel chartPanel;\n        private final ProbesPanel probesPanel;\n\n        ProbesWheelHandler(ChartPanel chartPanel, ProbesPanel probesPanel) {\n            this.chartPanel = chartPanel;\n            this.probesPanel = probesPanel;\n        }\n\n        void register() {\n            probesPanel.addMouseWheelListener(this);\n        }\n\n        public void mouseWheelMoved(MouseWheelEvent e) {\n            chartPanel.vScroll(e);\n        }\n\n    }\n\n    private static class RowMouseHandler extends MouseAdapter {\n\n        private static final int RESIZE_RANGE = 3;\n\n        private final TimelineSupport support;\n        private final TimelineChart chart;\n        private TimelineSelectionManager selection;\n        private final ProbesPanel probesPanel;\n\n        private int baseY;\n        private int baseHeight;\n        private TimelineChart.Row draggingRow;\n\n\n        RowMouseHandler(TimelineSupport support, ProbesPanel probesPanel) {\n            this.support = support;\n            this.chart = support.getChart();\n            this.selection = (TimelineSelectionManager)chart.getSelectionModel();\n            this.probesPanel = probesPanel;\n        }\n\n\n        void register() {\n            chart.addMouseListener(this);\n            chart.addMouseMotionListener(this);\n            probesPanel.getMouseTarget().addMouseListener(this);\n            probesPanel.getMouseTarget().addMouseMotionListener(this);\n        }\n\n\n        public void mousePressed(MouseEvent e) {\n            if (!SwingUtilities.isLeftMouseButton(e)) return;\n            updateRowState(e, SwingUtilities.isLeftMouseButton(e));\n            chart.updateSelection(false, this);\n            selection.setEnabled(draggingRow == null);\n            updateCursor();\n        }\n\n        public void mouseReleased(MouseEvent e) {\n            if (!SwingUtilities.isLeftMouseButton(e)) return;\n            chart.updateSelection(true, this);\n\n            if (draggingRow == null && e.getSource() == chart)\n                support.indexSelectionChanged(selection.getStartIndex(),\n                                              selection.getEndIndex());\n            \n            updateRowState(e, false);\n            updateCursor();\n\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    selection.setEnabled(true);\n                }\n            });\n        }\n\n        public void mouseMoved(MouseEvent e) {\n            updateRowState(e, false);\n            updateCursor();\n        }\n\n        public void mouseDragged(MouseEvent e){\n            if (!SwingUtilities.isLeftMouseButton(e)) return;\n            if (draggingRow != null) {\n                boolean checkStep = (e.getModifiers() & Toolkit.getDefaultToolkit().\n                                     getMenuShortcutKeyMask()) == 0;\n                chart.setRowHeight(draggingRow.getIndex(), baseHeight + e.getY() - baseY, checkStep);\n            }\n        }\n\n\n        private void updateRowState(MouseEvent e, boolean updateSelection) {\n            baseY = e.getY();\n            draggingRow = chart.getNearestRow(baseY, RESIZE_RANGE, true);\n            if (draggingRow != null) {\n                baseHeight = draggingRow.getHeight();\n            }\n        }\n\n        private void updateCursor() {\n            if (draggingRow != null) {\n                Cursor resizeCursor = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);\n                chart.setCursor(resizeCursor);\n                probesPanel.setCursor(resizeCursor);\n            } else {\n                Cursor defaultCursor = Cursor.getDefaultCursor();\n                chart.setCursor(defaultCursor);\n                probesPanel.setCursor(defaultCursor);\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineSelectionManager.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseMotionListener;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartComponent;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionListener;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemPainter;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.ItemsModel;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass TimelineSelectionManager implements ChartSelectionModel {\n\n    private ChartComponent chart;\n\n    private ChartListener chartListener;\n    private MouseListener mouseListener;\n\n    private int selectionMode;\n    private int moveMode;\n    private int dragMode;\n\n    private int hoverMode;\n    private int hoverDistanceLimit;\n\n    private int mouseX;\n    private int mouseY;\n    private boolean inChart;\n\n    private Rectangle selectionBounds;\n\n    private List<ItemSelection> highlightedSelection;\n    private List<ItemSelection> selectedSelection;\n\n    private boolean mousePanningBackup;\n\n    private boolean enabled = true;\n\n    private List<ChartSelectionListener> selectionListeners;\n\n\n    TimelineSelectionManager() {\n        mouseX = -1;\n        mouseY = -1;\n        inChart = false;\n\n        chartListener = new ChartListener();\n        mouseListener = new MouseListener();\n\n        setMoveMode(SELECTION_NONE);\n        setDragMode(SELECTION_NONE);\n        setSelectionMode(moveMode);\n\n        setHoverMode(HOVER_NONE);\n        setHoverDistanceLimit(HOVER_DISTANCE_LIMIT_NONE);\n    }\n\n\n    // --- Internal API --------------------------------------------------------\n\n    void registerChart(ChartComponent chart) {\n        unregisterListener();\n        this.chart = chart;\n        registerListener();\n    }\n\n    void unregisterChart(ChartComponent chart) {\n        unregisterListener();\n        this.chart = null;\n    }\n\n    void setEnabled(boolean enabled) {\n        this.enabled = enabled;\n    }\n\n\n    // --- Selection mode ------------------------------------------------------\n\n    public final void setMoveMode(int mode) {\n        moveMode = mode;\n        if (selectionMode != moveMode) setSelectionMode(moveMode);\n    }\n\n    public final int getMoveMode() {\n        return moveMode;\n    }\n\n    public final void setDragMode(int mode) {\n        dragMode = mode;\n    }\n\n    public final int getDragMode() {\n        return dragMode;\n    }\n\n    public final int getSelectionMode() {\n        return selectionMode;\n    }\n\n    public final void setHoverMode(int mode) {\n        hoverMode = mode;\n        updateHighlightedItems();\n    }\n\n    public final int getHoverMode() {\n        return hoverMode;\n    }\n\n    public final void setHoverDistanceLimit(int limit) {\n        hoverDistanceLimit = limit;\n    }\n\n    public final int getHoverDistanceLimit() {\n        return hoverDistanceLimit;\n    }\n\n\n    // --- Selection bounds ----------------------------------------------------\n\n    private int startIndex = -1;\n    private int endIndex = -1;\n\n    public final void setSelectionBounds(int x, int y, int w, int h) {\n        setSelectionBounds(new Rectangle(x, y, w, h));\n    }\n\n    public void selectAll() {\n        Rectangle oldSelectionBounds = this.selectionBounds == null ? null :\n                                       new Rectangle(this.selectionBounds);\n\n        selectionBounds = new Rectangle(new Point(0, 0), chart.getSize());\n        startIndex = 0;\n        ChartItem item = chart.getItemsModel().getItem(0);\n        endIndex = ((XYItem)item).getValuesCount() - 1;\n\n        fireSelectionBoundsChanged(this.selectionBounds, oldSelectionBounds);\n    }\n\n    public final void setSelectionBounds(Rectangle selectionBounds) {\n        if (selectionBounds == null && this.selectionBounds == null) return;\n\n        normalizeBounds(selectionBounds);\n\n        if (this.selectionBounds != null && this.selectionBounds.equals(selectionBounds) ||\n            selectionBounds != null && selectionBounds.equals(this.selectionBounds)) return;\n\n        Rectangle oldSelectionBounds = this.selectionBounds == null ? null :\n                                       new Rectangle(this.selectionBounds);\n\n        if (selectionBounds == null) this.selectionBounds = null;\n        else if (this.selectionBounds == null) this.selectionBounds = new Rectangle(selectionBounds);\n        else this.selectionBounds.setBounds(selectionBounds);\n\n        fireSelectionBoundsChanged(this.selectionBounds, oldSelectionBounds);\n    }\n\n    public final Rectangle getSelectionBounds() {\n        return selectionBounds == null ? new Rectangle() : new Rectangle(selectionBounds);\n    }\n\n    public int getStartIndex() { return startIndex; }\n    \n    public int getEndIndex() { return endIndex; }\n\n\n    private void normalizeBounds(Rectangle bounds) {\n        if (bounds == null) return;\n        \n        ItemSelection sel = getClosestSelection(bounds.x, bounds.y);\n        if (!(sel instanceof XYItemSelection)) return;\n\n//      #262588 : Do not change selection view bounds\n//        ChartContext context = chart.getChartContext();\n\n        XYItemSelection xySel = (XYItemSelection)sel;\n//        XYItem item = xySel.getItem();\n        startIndex = xySel.getValueIndex();\n        endIndex = startIndex;\n//        long valX = item.getXValue(startIndex);\n//        bounds.x = Utils.checkedInt(context.getViewX(valX));\n\n        if (bounds.width == 0) return;\n\n        sel = getClosestSelection(bounds.x + bounds.width, bounds.y + bounds.height);\n        if (!(sel instanceof XYItemSelection)) return;\n\n        xySel = (XYItemSelection)sel;\n//        item = xySel.getItem();\n        endIndex = xySel.getValueIndex();\n//        long valX = item.getXValue(endIndex);\n//        bounds.width = Utils.checkedInt(context.getViewX(valX)) - bounds.x;\n    }\n\n\n    // --- Highlighted items ---------------------------------------------------\n\n    public final void setHighlightedItems(List<ItemSelection> items) {\n        if (highlightedSelection == null) {\n            if (items.isEmpty()) return;\n            highlightedSelection = new ArrayList<>(items);\n            fireHighlightedItemsChanged(items, items, Collections.emptyList());\n        } else {\n            List<ItemSelection> addedItems = new ArrayList<>();\n            List<ItemSelection> removedItems = new ArrayList<>();\n\n            for (ItemSelection item : items)\n                if (!highlightedSelection.contains(item)) addedItems.add(item);\n\n            for (ItemSelection item : highlightedSelection)\n                if (!items.contains(item)) removedItems.add(item);\n\n            if (addedItems.isEmpty() && removedItems.isEmpty()) return;\n\n            highlightedSelection = new ArrayList<>(items);\n            fireHighlightedItemsChanged(items, addedItems, removedItems);\n        }\n    }\n\n    public final List<ItemSelection> getHighlightedItems() {\n        return highlightedSelection == null ? Collections.emptyList() :\n                                              new ArrayList<>(highlightedSelection);\n    }\n\n\n    // --- Selected items ------------------------------------------------------\n\n    public final void setSelectedItems(List<ItemSelection> items) {\n        if (selectedSelection == null) {\n            if (items.isEmpty()) return;\n            selectedSelection = new ArrayList<>(items);\n            fireSelectedItemsChanged(items, items, Collections.emptyList());\n        } else {\n            List<ItemSelection> addedItems = new ArrayList<>();\n            List<ItemSelection> removedItems = new ArrayList<>();\n\n            for (ItemSelection item : items)\n                if (!selectedSelection.contains(item)) addedItems.add(item);\n\n            for (ItemSelection item : selectedSelection)\n                if (!items.contains(item)) removedItems.add(item);\n\n            if (addedItems.isEmpty() && removedItems.isEmpty()) return;\n\n            selectedSelection = new ArrayList<>(items);\n            fireSelectedItemsChanged(items, addedItems, removedItems);\n        }\n    }\n\n    public final List<ItemSelection> getSelectedItems() {\n        return selectedSelection == null ? Collections.emptyList() :\n                                           new ArrayList<>(selectedSelection);\n    }\n\n\n    // --- Selection listeners -------------------------------------------------\n\n    public final void addSelectionListener(ChartSelectionListener listener) {\n        if (selectionListeners == null) selectionListeners = new ArrayList<>();\n        selectionListeners.add(listener);\n    }\n\n    public final void removeSelectionListener(ChartSelectionListener listener) {\n        if (selectionListeners == null) return;\n        selectionListeners.remove(listener);\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void setSelectionMode(int selectionMode) {\n        if (this.selectionMode == selectionMode) return;\n        int oldSelectionMode = this.selectionMode;\n        this.selectionMode = selectionMode;\n        fireSelectionModeChanged(this.selectionMode, oldSelectionMode);\n    }\n\n\n    private void registerListener() {\n        if (chart == null) return;\n        chart.addMouseListener(mouseListener);\n        chart.addMouseMotionListener(mouseListener);\n        chart.addConfigurationListener(chartListener);\n    }\n\n    private void unregisterListener() {\n        if (chart == null) return;\n        chart.removeMouseListener(mouseListener);\n        chart.removeMouseMotionListener(mouseListener);\n        chart.removeConfigurationListener(chartListener);\n    }\n\n\n    private void updateHighlightedItems() {\n        final int x = mouseX;\n        final int y = mouseY;\n\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (hoverMode == HOVER_NONE || !inChart) {\n                    setHighlightedItems(Collections.emptyList());\n                    return;\n                }\n\n                ItemsModel itemsModel = chart.getItemsModel();\n                PaintersModel paintersModel = chart.getPaintersModel();\n\n                int itemsCount = itemsModel.getItemsCount();\n                List<ItemSelection> closestSelection = new ArrayList<>(itemsCount);\n\n                for (int i = 0; i < itemsCount; i++) {\n                    ChartItem item = itemsModel.getItem(i);\n                    ItemPainter painter = paintersModel.getPainter(item);\n                    ItemSelection selection = painter.getClosestSelection(item, x, y,\n                                                            chart.getChartContext());\n\n                    if (selection != null) {\n                        int distance = selection.getDistance();\n                        if (hoverMode == HOVER_EACH_NEAREST || closestSelection.isEmpty()) {\n                            if (hoverDistanceLimit == HOVER_DISTANCE_LIMIT_NONE ||\n                                distance <= hoverDistanceLimit)\n                                closestSelection.add(selection);\n                        } else {\n                            if (closestSelection.get(0).getDistance() > distance) {\n                                if (hoverDistanceLimit == HOVER_DISTANCE_LIMIT_NONE ||\n                                    distance <= hoverDistanceLimit)\n                                    closestSelection.set(0, selection);\n                            }\n                        }\n                    }\n                }\n\n                setHighlightedItems(closestSelection);\n            }\n        });\n    }\n\n    private ItemSelection getClosestSelection(int x, int y) {\n        ItemsModel itemsModel = chart.getItemsModel();\n        int itemsCount = itemsModel.getItemsCount();\n        if (itemsCount == 0) return null;\n\n        PaintersModel paintersModel = chart.getPaintersModel();\n        int itemIndex = 0;\n        while (itemIndex < itemsCount) {\n            ChartItem item = itemsModel.getItem(itemIndex);\n            ItemPainter painter = paintersModel.getPainter(item);\n            if (!(painter instanceof TimelineIconPainter))\n                return painter.getClosestSelection(item, x, y, chart.getChartContext());\n            itemIndex++;\n        }\n\n        ChartItem item = itemsModel.getItem(0);\n        ItemPainter painter = paintersModel.getPainter(item);\n        return painter.getClosestSelection(item, x, y, chart.getChartContext());\n    }\n\n\n    private void fireSelectionModeChanged(int newMode, int oldMode) {\n        if (selectionListeners == null) return;\n        for (ChartSelectionListener listener : selectionListeners)\n            listener.selectionModeChanged(newMode, oldMode);\n    }\n\n    private void fireSelectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds) {\n        if (selectionListeners == null) return;\n        for (ChartSelectionListener listener : selectionListeners)\n            listener.selectionBoundsChanged(newBounds, oldBounds);\n    }\n\n    private void fireHighlightedItemsChanged(List<ItemSelection> currentItems,\n            List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n        if (selectionListeners == null) return;\n        for (ChartSelectionListener listener : selectionListeners)\n            listener.highlightedItemsChanged(currentItems, addedItems, removedItems);\n    }\n\n    private void fireSelectedItemsChanged(List<ItemSelection> currentItems,\n            List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n        if (selectionListeners == null) return;\n        for (ChartSelectionListener listener : selectionListeners)\n            listener.selectedItemsChanged(currentItems, addedItems, removedItems);\n    }\n\n\n    private class ChartListener extends ChartConfigurationListener.Adapter {\n\n        public void contentsWillBeUpdated(long offsetX, long offsetY,\n                                double scaleX, double scaleY,\n                                long lastOffsetX, long lastOffsetY,\n                                double lastScaleX, double lastScaleY) {\n            updateHighlightedItems();\n        }\n\n    }\n\n\n    private class MouseListener extends MouseAdapter implements MouseMotionListener {\n\n        public void mousePressed(final MouseEvent e) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    if (!enabled || !SwingUtilities.isLeftMouseButton(e)) return;\n                    mousePanningBackup = chart.isMousePanningEnabled();\n\n                    setSelectionMode(dragMode);\n                    if (selectionMode != SELECTION_NONE) {\n                        chart.disableMousePanning();\n                        setSelectionBounds(null); // Clears previous selection\n                        setSelectionBounds(e.getX(), e.getY(), 0, 0);\n                    }\n                }\n            });\n            \n        }\n\n        public void mouseReleased(final MouseEvent e) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    if (!enabled || !SwingUtilities.isLeftMouseButton(e)) return;\n                    // Clear previous selection\n        //            setSelectionBounds(null);\n\n                    setSelectionMode(moveMode);\n                    if (selectionMode == SELECTION_NONE)\n                        chart.setMousePanningEnabled(mousePanningBackup);\n\n                    // Refresh selection if needed\n        //            if (selectionMode != SELECTION_NONE)\n        //                setSelectionBounds(e.getX(), e.getY(), 0, 0);\n                }\n            });\n            \n        }\n\n        public void mouseClicked(final MouseEvent e) {\n            if (!enabled || !SwingUtilities.isLeftMouseButton(e)) return;\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    if (selectionMode != SELECTION_NONE)\n                        setSelectionBounds(e.getX(), e.getY(), 0, 0);\n                }\n            });\n            \n        }\n\n        public void mouseEntered(final MouseEvent e) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    inChart = true;\n                    mouseX = e.getX();\n                    mouseY = e.getY();\n                }\n            });\n            \n        }\n\n        public void mouseExited(final MouseEvent e) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    inChart = false;\n\n        //            if (selectionMode == SELECTION_LINE_V ||\n        //                selectionMode == SELECTION_LINE_H ||\n        //                selectionMode == SELECTION_CROSS) {\n        //                setSelectionBounds(null);\n        //            }\n\n                    updateHighlightedItems();\n                }\n            });\n            \n        }\n\n        public void mouseDragged(final MouseEvent e) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    if (!enabled || !SwingUtilities.isLeftMouseButton(e)) return;\n                    if (selectionMode == SELECTION_RECT) {\n                        setSelectionBounds(selectionBounds.x, selectionBounds.y,\n                                e.getX() - selectionBounds.x, e.getY() - selectionBounds.y);\n                    }\n                }\n            });\n\n        }\n\n        public void mouseMoved(final MouseEvent e) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    mouseX = e.getX();\n                    mouseY = e.getY();\n\n                    if (selectionMode == SELECTION_NONE) setSelectionBounds(null);\n        //            else setSelectionBounds(mouseX, mouseY, 0, 0);\n\n                    updateHighlightedItems();\n                }\n            });\n            \n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineSelectionOverlay.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Paint;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.SortedSet;\nimport java.util.TreeSet;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartOverlay;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionListener;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineSelectionOverlay extends ChartOverlay {\n\n    private TimelineChart chart;\n    private TimelineSupport support;\n\n    private int selectionExtent;\n\n    private ConfigurationListener configurationListener;\n    private SelectionListener selectionListener;\n    private TimeSelectionListener timeSelectionListener;\n    private final Set<Point> highlightedValues;\n    private final Set<Point> selectedValues;\n\n    private Paint sMarkPaint;\n    private Paint sOddPerfPaint;\n    private Paint sEvenPerfPaint;\n\n    private Paint hMarkPaint;\n    private Paint hOddPerfPaint;\n    private Paint hEvenPerfPaint;\n\n    private Stroke markStroke;\n    private Stroke oddPerfStroke;\n    private Stroke evenPerfStroke;\n\n\n    TimelineSelectionOverlay() {\n        configurationListener = new ConfigurationListener();\n        selectionListener = new SelectionListener();\n        timeSelectionListener = new TimeSelectionListener();\n        highlightedValues = new HashSet<>();\n        selectedValues = new HashSet<>();\n        initDefaultValues();\n    }\n    \n\n    // --- Internal API --------------------------------------------------------\n\n    final void registerChart(TimelineSupport support) {\n        unregisterListener();\n        this.support = support;\n        this.chart = support.getChart();\n        registerListener();\n    }\n\n    final void unregisterChart(TimelineSupport support) {\n        unregisterListener();\n        this.support = null;\n        this.chart = null;\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void registerListener() {\n        if (support == null || chart == null) return;\n        chart.addConfigurationListener(configurationListener);\n        chart.addRowListener(configurationListener);\n        chart.getSelectionModel().addSelectionListener(selectionListener);\n        support.addSelectionListener(timeSelectionListener);\n    }\n\n    private void unregisterListener() {\n        if (support == null || chart == null) return;\n        chart.removeConfigurationListener(configurationListener);\n        chart.removeRowListener(configurationListener);\n        chart.getSelectionModel().removeSelectionListener(selectionListener);\n        support.removeSelectionListener(timeSelectionListener);\n    }\n\n    private void initDefaultValues() {\n        sMarkPaint = new Color(120, 120, 120);\n        sOddPerfPaint = new Color(120, 120, 120);\n        sEvenPerfPaint = Color.WHITE;\n\n        hMarkPaint = new Color(80, 80, 80);\n        hOddPerfPaint = Color.BLACK;\n        hEvenPerfPaint = Color.WHITE;\n\n        markStroke = new BasicStroke(2.8f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);\n        oddPerfStroke = new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 0, new float[] { 1.0f, 3.0f }, 0);\n        evenPerfStroke = new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 0, new float[] { 1.0f, 3.0f }, 2);\n\n        selectionExtent = 3;\n    }\n\n    private final Set<Integer> paintedLines = new HashSet<>();\n\n    public void paint(Graphics g) {\n        if (highlightedValues.isEmpty() && selectedValues.isEmpty()) return;\n\n        Graphics2D g2 = (Graphics2D)g;\n        g2.setRenderingHints(chart.getRenderingHints());\n\n        Iterator<Point> it = selectedValues.iterator();\n        paintedLines.clear();\n        \n        int height = getHeight();\n        int extentP = 1 - selectionExtent;\n        int extentD = selectionExtent * 2 - 1;\n\n        while (it.hasNext()) {\n            Point p = it.next();\n            int x = p.x;\n            int y = p.y;\n\n            if (y == -1) continue;\n\n            if (!paintedLines.contains(x)) {\n                g2.setPaint(sEvenPerfPaint);\n                g2.setStroke(evenPerfStroke);\n                g2.drawLine(x, 0, x, height);\n                g2.setPaint(sOddPerfPaint);\n                g2.setStroke(oddPerfStroke);\n                g2.drawLine(x, 0, x, height);\n\n                g2.setPaint(sMarkPaint);\n                g2.setStroke(markStroke);\n\n                paintedLines.add(x);\n            }\n            \n            if (y - selectionExtent >= 0 && y + selectionExtent <= height)\n                g2.fillOval(x + extentP, y + extentP, extentD, extentD);\n        }\n\n        it = highlightedValues.iterator();\n        paintedLines.clear();\n\n        while (it.hasNext()) {\n            Point p = it.next();\n            int x = p.x;\n            int y = p.y;\n\n            if (y == -1) continue;\n\n            if (!paintedLines.contains(x)) {\n                g2.setPaint(hEvenPerfPaint);\n                g2.setStroke(evenPerfStroke);\n                g2.drawLine(x, 0, x, height);\n                g2.setPaint(hOddPerfPaint);\n                g2.setStroke(oddPerfStroke);\n                g2.drawLine(x, 0, x, height);\n\n                g2.setPaint(hMarkPaint);\n                g2.setStroke(markStroke);\n\n                paintedLines.add(x);\n            }\n            \n            if (y - selectionExtent >= 0 && y + selectionExtent <= height)\n                g2.fillOval(x + extentP, y + extentP, extentD, extentD);\n        }\n\n    }\n\n    private void vLineBoundsChanged(Set<Point> oldSelection, Set<Point> newSelection) {\n        SortedSet<Integer> selectionBounds = new TreeSet<>();\n        for (Point p : oldSelection) selectionBounds.add(p.x);\n        int selections = selectionBounds.size();\n        if (selections == 1) {\n            repaint(selectionBounds.first() - selectionExtent,\n                    0, selectionExtent * 2, getHeight());\n            selectionBounds.clear();\n        }\n\n        for (Point p : newSelection) selectionBounds.add(p.x);\n        selections = selectionBounds.size();\n        if (selections == 1) {\n            repaint(selectionBounds.first() - selectionExtent,\n                    0, selectionExtent * 2, getHeight());\n        } else if (selections > 1) {\n            int firstX = selectionBounds.first() - selectionExtent;\n            int lastX  = selectionBounds.last() + selectionExtent;\n            repaint(firstX, 0, lastX - firstX, getHeight());\n        }\n    }\n\n    private List<ItemSelection> getSelections() {\n        List<ItemSelection> items = new ArrayList<>();\n\n        Set<Integer> timestamps = support.getSelectedTimestamps();\n        SynchronousXYItemsModel model = (SynchronousXYItemsModel)chart.getItemsModel();\n        int itemsCount = model.getItemsCount();\n        for (int itemIndex = 0; itemIndex < itemsCount; itemIndex++)\n            for (int timestamp : timestamps)\n                items.add(new XYItemSelection.Default(model.getItem(itemIndex),\n                          timestamp, XYItemSelection.DISTANCE_UNKNOWN));\n\n        return items;\n    }\n\n    private static void updateValues(Set<Point> values,\n                                     List<ItemSelection> selectedItems,\n                                     TimelineChart chart) {\n        values.clear();\n        for (ItemSelection sel : selectedItems) {\n            XYItemSelection xySel = (XYItemSelection)sel;\n            XYItem item = xySel.getItem();\n            TimelineXYPainter painter = (TimelineXYPainter)chart.getPaintersModel().getPainter(item);\n            ChartContext context = chart.getChartContext(item);\n            long xValue = item.getXValue(xySel.getValueIndex());\n            long yValue = item.getYValue(xySel.getValueIndex());\n            int xPos = Utils.checkedInt(Math.ceil(context.getViewX(xValue)));\n            int yPos = Utils.checkedInt(Math.ceil(painter.getItemView(yValue, item, context)));\n            if (xPos >= 0 && xPos <= chart.getWidth()) values.add(new Point(xPos, yPos));\n        }\n    }\n\n\n    private class ConfigurationListener extends ChartConfigurationListener.Adapter\n                                        implements TimelineChart.RowListener {\n        private final Runnable selectionUpdater = new Runnable() {\n            public void run() {\n                Set<Point> oldSelectedValues = new HashSet<>(selectedValues);\n                updateValues(selectedValues, getSelections(), chart);\n                vLineBoundsChanged(oldSelectedValues, selectedValues);\n                \n                Set<Point> oldValues = new HashSet<>(highlightedValues);\n                updateValues(highlightedValues, chart.getSelectionModel().\n                             getHighlightedItems(), chart);\n                vLineBoundsChanged(oldValues, highlightedValues);\n            }\n        };\n        public void contentsUpdated(long offsetX, long offsetY,\n                                    double scaleX, double scaleY,\n                                    long lastOffsetX, long lastOffsetY,\n                                    double lastScaleX, double lastScaleY,\n                                    int shiftX, int shiftY) {\n            if (highlightedValues.isEmpty() && !support.isTimestampSelection(true)) return;\n            if (lastOffsetX != offsetX || lastOffsetY != offsetY ||\n                scaleX != lastScaleX || scaleY != lastScaleY)\n                SwingUtilities.invokeLater(selectionUpdater);\n        }\n        public void rowsAdded(List<TimelineChart.Row> rows) { selectionUpdater.run(); }\n\n        public void rowsRemoved(List<TimelineChart.Row> rows) { selectionUpdater.run(); }\n\n        public void rowsResized(List<TimelineChart.Row> rows) { selectionUpdater.run(); }\n    }\n\n    private class SelectionListener implements ChartSelectionListener {\n\n        public void selectionModeChanged(int newMode, int oldMode) {}\n\n        public void selectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds) {\n        }\n\n        public void selectedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n        }\n\n        public void highlightedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n            Set<Point> oldHighlightedValues = new HashSet<>(highlightedValues);\n            updateValues(highlightedValues, currentItems, chart);\n            vLineBoundsChanged(oldHighlightedValues, highlightedValues);\n        }\n\n    }\n\n    private class TimeSelectionListener implements TimelineSupport.SelectionListener {\n        \n        public void intervalsSelectionChanged() {}\n\n        public void indexSelectionChanged() {}\n\n        public void timeSelectionChanged(boolean timestampsSelected, boolean justHovering) {\n            Set<Point> oldSelectedValues = new HashSet<>(selectedValues);\n            updateValues(selectedValues, getSelections(), chart);\n            vLineBoundsChanged(oldSelectedValues, selectedValues);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Color;\nimport java.awt.event.ComponentAdapter;\nimport java.awt.event.ComponentEvent;\nimport java.awt.event.ComponentListener;\nimport java.text.Format;\nimport java.text.MessageFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.AbstractTableModel;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.Timeline;\nimport org.graalvm.visualvm.lib.charts.axis.TimeAxisUtils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ItemValueFormatter;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ProbeItemDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProbe;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.TracerProbeDescriptor;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.IdeSnapshot;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.details.DetailsPanel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.details.DetailsTableModel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.export.DataExport;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.options.TracerOptions;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.TimelineChart.Row;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items.ValueItemDescriptor;\n\n/**\n * All methods must be invoked from the EDT.\n *\n * @author Jiri Sedlacek\n */\npublic final class TimelineSupport {\n\n    public static final int[] EMPTY_TIMESTAMPS = new int[0];\n\n    private final TimelineChart chart;\n    private final TimelineModel model;\n    private final SynchronousXYItemsModel itemsModel;\n\n    private final PointsComputer pointsComputer;\n\n    private final TimelineTooltipOverlay tooltips;\n    private final TimelineLegendOverlay legend;\n    private final TimelineUnitsOverlay units;\n\n    private final List<TracerProbe> probes = new ArrayList<>();\n    private final List<TimelineChart.Row> rows = new ArrayList<>();\n    private final DescriptorResolver descriptorResolver;\n\n    private final Set<ValuesListener> valuesListeners = new HashSet<>();\n\n    private final Set<Integer> selectedTimestamps = new HashSet<>();\n    private final List<Integer> selectedIntervals = new ArrayList<>();\n    private final Set<SelectionListener> selectionListeners = new HashSet<>();\n\n    private final IdeSnapshot snapshot;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    public TimelineSupport(DescriptorResolver descriptorResolver, IdeSnapshot snapshot) {\n        this.descriptorResolver = descriptorResolver;\n        this.snapshot = snapshot;\n        \n        // TODO: must be called in EDT!\n        model = new TimelineModel();\n        itemsModel = new SynchronousXYItemsModel(model);\n        chart = new TimelineChart(itemsModel);\n\n        TimelineSelectionManager selectionManager = new TimelineSelectionManager();\n        chart.setSelectionModel(selectionManager);\n        selectionManager.registerChart(chart);\n\n        tooltips = new TimelineTooltipOverlay(this);\n        chart.addOverlayComponent(tooltips);\n\n        pointsComputer = new PointsComputer();\n\n        legend = new TimelineLegendOverlay(chart);\n        legend.setVisible(TracerOptions.getInstance().isShowLegendEnabled());\n        chart.addOverlayComponent(legend);\n\n        units = new TimelineUnitsOverlay(chart);\n        units.setVisible(TracerOptions.getInstance().isShowValuesEnabled());\n        chart.addOverlayComponent(units);\n    }\n\n\n    // --- Chart access --------------------------------------------------------\n\n    TimelineChart getChart() {\n        return chart;\n    }\n\n\n    // --- Indexes computer access ---------------------------------------------\n\n    PointsComputer getPointsComputer() {\n        return pointsComputer;\n    }\n\n\n    // --- Chart setup ---------------------------------------------------------\n\n    private ComponentListener chartResizeHandler;\n\n    public void dataLoadingStarted(final long range) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                cleanResizeHandler();\n                chartResizeHandler = new ComponentAdapter() {\n                    public void componentResized(ComponentEvent e) {\n                        chart.setScale(chart.getWidth() / (double)range, 1);\n                    }\n                };\n                chart.addComponentListener(chartResizeHandler);\n                chart.setFitsWidth(false);\n                chartResizeHandler.componentResized(null);\n            }\n        });\n    }\n\n    public void dataLoadingFinished() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                cleanResizeHandler();\n                chart.setFitsWidth(true);\n                chart.invalidateRepaint();\n            }\n        });\n    }\n\n    private void cleanResizeHandler() {\n        if (chartResizeHandler != null) {\n            chart.removeComponentListener(chartResizeHandler);\n            chartResizeHandler = null;\n        }\n    }\n\n\n    // --- Overlays access -----------------------------------------------------\n\n    public void setShowValuesEnabled(boolean enabled) {\n        units.setVisible(enabled);\n    }\n\n    public boolean isShowValuesEnabled() {\n        return units.isVisible();\n    }\n\n    public void setShowLegendEnabled(boolean enabled) {\n        legend.setVisible(enabled);\n    }\n\n    public boolean isShowLegendEnabled() {\n        return legend.isVisible();\n    }\n\n\n    // --- Probes management ---------------------------------------------------\n\n    public void addProbe(final TracerProbe probe) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                resetValues();\n\n                TimelineChart.Row row = chart.addRow();\n\n                probes.add(probe);\n                rows.add(row);\n\n                ProbeItemDescriptor[] itemDescriptors = probe.getItemDescriptors();\n                TimelineXYItem[] items = model.createItems(itemDescriptors);\n                XYItemPainter[] painters  = new XYItemPainter[items.length];\n                for (int i = 0; i < painters.length; i++)\n                    painters[i] = TimelinePaintersFactory.createPainter(\n                            itemDescriptors[i], i, pointsComputer, snapshot);\n                \n                row.addItems(items, painters);\n\n                setupOverlays();\n            }\n        });\n    }\n\n    public void removeProbe(final TracerProbe probe) {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                resetValues();\n                \n                TimelineChart.Row row = getRow(probe);\n\n                chart.removeRow(row);\n                \n                model.removeItems(row.getItems());\n\n                rows.remove(row);\n                probes.remove(probe);\n\n                setupOverlays();\n            }\n        });\n    }\n\n    public List<TracerProbe> getProbes() {\n        return probes;\n    }\n\n    public int getItemsCount() {\n        return model.getItemsCount();\n    }\n\n    public boolean hasData() {\n        return model.getTimestampsCount() > 0;\n    }\n\n    public long getTimestamp(int index) {\n        return model.getTimestamp(index);\n    }\n\n\n    // --- Tooltips support ----------------------------------------------------\n\n    private void setupOverlays() {\n        final int rowsCount = chart.getRowsCount();\n\n        TimelineTooltipPainter.Model[] rowModels = new TimelineTooltipPainter.Model[rowsCount];\n        \n        for (int rowIndex = 0; rowIndex < rowModels.length; rowIndex++) {\n            final TimelineChart.Row row = chart.getRow(rowIndex);\n            final TracerProbe probe = getProbe(row);\n\n            final int itemsCount = row.getItemsCount();\n            final String[] rowNames = new String[itemsCount];\n            final ValueItemDescriptor[] viDescriptors = new ValueItemDescriptor[itemsCount];\n            final String[] unitsStrings = new String[itemsCount];\n            for (int itemIndex = 0; itemIndex < itemsCount; itemIndex++) {\n                rowNames[itemIndex] = ((TimelineXYItem)row.getItem(itemIndex)).getName();\n                viDescriptors[itemIndex] = (ValueItemDescriptor)probe.getItemDescriptors()[itemIndex];\n                unitsStrings[itemIndex] = viDescriptors[itemIndex].getUnitsString(ItemValueFormatter.FORMAT_TOOLTIP);\n            }\n\n            rowModels[rowIndex] = new TimelineTooltipPainter.Model() {\n\n                public int getRowsCount() {\n                    return itemsCount;\n                }\n\n                public String getRowName(int index) {\n                    return rowNames[index];\n                }\n\n                public String getRowValue(int index, long itemValue) {\n                    return viDescriptors[index].getValueString(itemValue,\n                            ItemValueFormatter.FORMAT_TOOLTIP);\n                }\n\n                public String getRowUnits(int index) {\n                    return unitsStrings[index];\n                }\n\n            };\n        }\n        tooltips.setupModel(rowModels);\n\n        units.setupModel(new TimelineUnitsOverlay.Model() {\n\n            private final String LAST_UNITS_STRING = \"lastUnitsString\"; // NOI18N\n\n            private Color[][] rowColors = new Color[rowsCount][];\n            private String[][] rowMinValues = new String[rowsCount][];\n            private String[][] rowMaxValues = new String[rowsCount][];\n\n            private List<Color> visibleRowItemColors;\n            private List<String> visibleRowItemMinValues;\n            private List<String> visibleRowItemMaxValues;\n\n            public void prefetch() {\n                PaintersModel paintersModel = chart.getPaintersModel();\n                for (int rowIndex = 0; rowIndex < rowsCount; rowIndex++) {\n                    \n                    Row row = chart.getRow(rowIndex);\n                    TracerProbe probe = getProbe(row);\n                    int rowItemsCount = row.getItemsCount();\n\n                    ChartContext rowContext = row.getContext();\n                    long commonMinY = rowContext.getDataOffsetY();\n                    long commonMaxY = commonMinY + rowContext.getDataHeight();\n\n                    if (visibleRowItemColors != null) {\n                        visibleRowItemColors.clear();\n                        visibleRowItemMinValues.clear();\n                        visibleRowItemMaxValues.clear();\n                    } else {\n                        visibleRowItemColors = new ArrayList<>(rowItemsCount);\n                        visibleRowItemMinValues = new ArrayList<>(rowItemsCount);\n                        visibleRowItemMaxValues = new ArrayList<>(rowItemsCount);\n                    }\n                    \n                    boolean sameFactorUnits = true;\n                    double lastDataFactor = -1;\n                    String lastUnitsString = LAST_UNITS_STRING;\n\n                    for (int itemIndex = 0; itemIndex < rowItemsCount; itemIndex++) {\n                        TimelineXYItem item = (TimelineXYItem)row.getItem(itemIndex);\n                        TimelineXYPainter painter =\n                                (TimelineXYPainter)paintersModel.getPainter(item);\n\n                        if (painter.isPainting()) {\n                            visibleRowItemColors.add(painter.getDefiningColor());\n\n                            ValueItemDescriptor descriptor = (ValueItemDescriptor)\n                                    probe.getItemDescriptors()[itemIndex];\n\n                            double dataFactor = descriptor.getDataFactor();\n                            String unitsString = descriptor.getUnitsString(\n                                    ItemValueFormatter.FORMAT_UNITS);\n                            \n                            if (sameFactorUnits) {\n                                if (lastDataFactor == -1)\n                                    lastDataFactor = dataFactor;\n                                else if (lastDataFactor != dataFactor)\n                                    sameFactorUnits = false;\n                                lastDataFactor = dataFactor;\n                                \n                                if (lastUnitsString == LAST_UNITS_STRING)\n                                    lastUnitsString = unitsString;\n                                else if (!equals(lastUnitsString, unitsString))\n                                    sameFactorUnits = false;\n                                lastUnitsString = unitsString;\n                            }\n\n                            String minValueString = descriptor.getValueString(\n                                    (long)(commonMinY / painter.dataFactor),\n                                    ItemValueFormatter.FORMAT_UNITS);\n                            visibleRowItemMinValues.add(unitsString == null ?\n                                minValueString : minValueString + \" \" + unitsString);\n                            \n                            String maxValueString = descriptor.getValueString(\n                                    (long)(commonMaxY / painter.dataFactor),\n                                    ItemValueFormatter.FORMAT_UNITS);\n                            visibleRowItemMaxValues.add(unitsString == null ?\n                                maxValueString : maxValueString + \" \" + unitsString);\n                        }\n                    }\n\n                    if (sameFactorUnits) {\n                        rowColors[rowIndex] = new Color[] { null };\n                        rowMinValues[rowIndex] =\n                                new String[] { visibleRowItemMinValues.get(0) };\n                        rowMaxValues[rowIndex] =\n                                new String[] { visibleRowItemMaxValues.get(0) };\n                    } else {\n                        rowColors[rowIndex] = visibleRowItemColors.toArray(new Color[0]);\n                        rowMinValues[rowIndex] = visibleRowItemMinValues.toArray(new String[0]);\n                        rowMaxValues[rowIndex] = visibleRowItemMaxValues.toArray(new String[0]);\n                    }\n                }\n            }\n\n            public Color[] getColors(Row row) {\n                return rowColors[row.getIndex()];\n            }\n\n            public String[] getMinUnits(TimelineChart.Row row) {\n                return rowMinValues[row.getIndex()];\n            }\n\n            public String[] getMaxUnits(TimelineChart.Row row) {\n                return rowMaxValues[row.getIndex()];\n            }\n\n            private boolean equals(String s1, String s2) {\n                if (s1 == null) {\n                    if (s2 == null) return true;\n                    else return false;\n                } else {\n                    return s1.equals(s2);\n                }\n            }\n            \n        });\n    }\n\n\n    // --- Rows <-> Probes mapping ---------------------------------------------\n\n    TimelineChart.Row getRow(TracerProbe probe) {\n        return rows.get(probes.indexOf(probe));\n    }\n\n    TracerProbe getProbe(TimelineChart.Row row) {\n        return probes.get(rows.indexOf(row));\n    }\n\n\n    // --- Probe -> Descriptor mapping -----------------------------------------\n\n    TracerProbeDescriptor getDescriptor(TracerProbe p) {\n        return descriptorResolver.getDescriptor(p);\n    }\n\n\n    // --- Values management ---------------------------------------------------\n\n    public void addValues(final long timestamp, final long[] newValues) {\n        int newRow = detailsModel == null ? -1 : detailsModel.getRowCount();\n        model.addValues(timestamp, newValues);\n        itemsModel.valuesAdded();\n        if (newRow != -1) detailsModel.fireTableRowsInserted(newRow, newRow);\n        fireValuesAdded();\n    }\n\n    public void resetValues() {\n        model.reset();\n        itemsModel.valuesReset();\n        resetSelectedTimestamps();\n        pointsComputer.reset();\n        if (detailsModel != null) detailsModel.fireTableStructureChanged();\n        fireValuesReset();\n    }\n\n    public void exportAllValues(String title) {\n        final int rowsCount = model.getTimestampsCount();\n        final int columnsCount = model.getItemsCount();\n        \n        final Format timeFormatter = new SimpleDateFormat(MessageFormat.format(\n                                     TimeAxisUtils.TIME_DATE_FORMAT, TimeAxisUtils.TIME_MSEC, TimeAxisUtils.DATE_YEAR));\n\n        final List<ProbeItemDescriptor> probeDescriptors = new ArrayList<>(columnsCount);\n        for (TracerProbe probe : probes)\n            probeDescriptors.addAll(Arrays.asList(probe.getItemDescriptors()));\n        final ValueItemDescriptor[] descriptors = new ValueItemDescriptor[columnsCount];\n        for (int i = 0; i < columnsCount; i++)\n            descriptors[i] = (ValueItemDescriptor)probeDescriptors.get(i);\n\n        TableModel exportModel = new AbstractTableModel() {\n            public int getRowCount() {\n                return rowsCount;\n            }\n\n            public int getColumnCount() {\n                return columnsCount + 1;\n            }\n\n            public String getColumnName(int columnIndex) {\n                if (columnIndex == 0) return \"Time [ms]\";\n\n                String unitsString = descriptors[columnIndex - 1].getUnitsString(\n                                     ItemValueFormatter.FORMAT_EXPORT);\n                unitsString = unitsString == null ? \"\" : \" [\" + unitsString + \"]\";\n                return itemsModel.getItem(columnIndex - 1).getName() + unitsString;\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                if (columnIndex == 0) return timeFormatter.format(model.\n                                             getTimestamp(rowIndex));\n\n                long value = itemsModel.getItem(columnIndex - 1).getYValue(rowIndex);\n                return descriptors[columnIndex - 1].getValueString(value,\n                                                    ItemValueFormatter.FORMAT_EXPORT);\n            }\n        };\n        DataExport.exportData(exportModel, title);\n    }\n\n    public void exportDetailsValues(String title) {\n        if (detailsModel == null) return;\n\n        final int rowsCount = detailsModel.getRowCount();\n        final int columnsCount = detailsModel.getColumnCount();\n\n        final Format timeFormatter = new SimpleDateFormat(MessageFormat.format(\n                                     TimeAxisUtils.TIME_DATE_FORMAT, TimeAxisUtils.TIME_MSEC, TimeAxisUtils.DATE_YEAR));\n        \n        TableModel exportModel = new AbstractTableModel() {\n            public int getRowCount() {\n                return rowsCount;\n            }\n\n            public int getColumnCount() {\n                return columnsCount - 1;\n            }\n\n            public String getColumnName(int columnIndex) {\n                return detailsModel.getColumnName(columnIndex + 1);\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                Object value = detailsModel.getValueAt(rowIndex, columnIndex + 1);\n\n                if (columnIndex == 0) return timeFormatter.format(value);\n\n                return detailsModel.getDescriptor(columnIndex + 1).getValueString(\n                                    (Long)value, ItemValueFormatter.FORMAT_EXPORT);\n            }\n        };\n        DataExport.exportData(exportModel, title);\n    }\n\n    public void addValuesListener(ValuesListener listener) {\n        valuesListeners.add(listener);\n    }\n\n    public void removeValuesListener(ValuesListener listener) {\n        valuesListeners.remove(listener);\n    }\n    \n    private void fireValuesAdded() {\n        for (ValuesListener listener : valuesListeners)\n            listener.valuesAdded();\n    }\n    \n    private void fireValuesReset() {\n        for (ValuesListener listener : valuesListeners)\n            listener.valuesReset();\n    }\n\n\n    public static interface ValuesListener {\n\n        public void valuesAdded();\n\n        public void valuesReset();\n\n    }\n\n    // --- Row selection management --------------------------------------------\n\n    private DetailsTableModel detailsModel;\n\n    public boolean isRowSelection() {\n        return chart.isRowSelection();\n    }\n\n    public TableModel getDetailsModel() {\n        if (!chart.isRowSelection()) detailsModel = null;\n        else detailsModel = createSelectionModel();\n        return detailsModel;\n    }\n\n    private DetailsTableModel createSelectionModel() {\n        final List<SynchronousXYItem> selectedItems = getSelectedItems();\n        final List<ValueItemDescriptor> selectedDescriptors = getSelectedDescriptors();\n        int selectedItemsCount = selectedItems.size();\n        \n        final int columnCount = selectedItemsCount + 2;\n        final SynchronousXYItem[] selectedItemsArr =\n                selectedItems.toArray(new SynchronousXYItem[0]);\n        final String[] columnNames = new String[columnCount];\n        columnNames[0] = \"Mark\";\n        columnNames[1] = \"Time [ms]\";\n        final String[] columnTooltips = new String[columnCount];\n        columnTooltips[0] = \"Mark a timestamp in Timeline view\";\n        columnTooltips[1] = \"Timestamp of the data\";\n        for (int i = 2; i < columnCount; i++) {\n            String itemName = selectedItemsArr[i - 2].getName();\n            String unitsString = selectedDescriptors.get(i - 2).\n                                 getUnitsString(ItemValueFormatter.FORMAT_DETAILS);\n            unitsString = unitsString == null ? \"\" : \" [\" + unitsString + \"]\";\n            columnNames[i] = itemName + unitsString;\n            columnTooltips[i] = selectedDescriptors.get(i - 2).getDescription();\n        }\n\n        return new DetailsTableModel() {\n\n            public int getRowCount() {\n                return model.getTimestampsCount();\n            }\n\n            public int getColumnCount() {\n                return columnCount;\n            }\n\n            public String getColumnName(int columnIndex) {\n                return columnNames[columnIndex];\n            }\n\n            public String getColumnTooltip(int columnIndex) {\n                return columnTooltips[columnIndex];\n            }\n\n            public Class<?> getColumnClass(int columnIndex) {\n                if (columnIndex == 0) return Boolean.class;\n                if (columnIndex == 1) return DetailsPanel.class;\n                return Long.class;\n            }\n\n            public ValueItemDescriptor getDescriptor(int columnIndex) {\n                if (columnIndex == 0) return null;\n                if (columnIndex == 1) return null;\n                return selectedDescriptors.get(columnIndex - 2);\n            }\n\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                if (columnIndex == 0) return selectedTimestamps.contains(rowIndex);\n                if (columnIndex == 1) return model.getTimestamp(rowIndex);\n                return selectedItemsArr[columnIndex - 2].getYValue(rowIndex);\n            }\n\n            public boolean isCellEditable(int rowIndex, int columnIndex) {\n                return columnIndex == 0;\n            }\n\n            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {\n                if (Boolean.TRUE.equals(aValue)) selectTimestamp(rowIndex, true, false);\n                else unselectTimestamp(rowIndex, false);\n            }\n\n        };\n    }\n\n\n    // --- Time selection management -------------------------------------------\n\n    private static final int SCROLL_MARGIN_LEFT = 10;\n    private static final int SCROLL_MARGIN_RIGHT = 50;\n\n    private boolean hovering;\n    private boolean hoveredSelected;\n\n\n    void setTimestampHovering(boolean hovering, boolean hoveredSelected) {\n        this.hovering = hovering;\n        this.hoveredSelected = hoveredSelected;\n        notifyTimeSelectionChanged();\n    }\n\n    public void selectTimestamp(int index, boolean scrollToVisible) {\n        selectTimestamp(index, scrollToVisible, true);\n    }\n\n    private void selectTimestamp(int index, boolean scrollToVisible, boolean notifyTable) {\n        boolean change = selectedTimestamps.add(index);\n        if (notifyTable && detailsModel != null)\n            detailsModel.fireTableCellUpdated(index, 0);\n        if (change) {\n            updateSelectedItems();\n            notifyTimeSelectionChanged();\n            if (scrollToVisible) highlightTimestamp(index);\n        }\n    }\n\n    public void unselectTimestamp(int index) {\n        unselectTimestamp(index, true);\n    }\n\n    public void toggleTimestampSelection(int index) {\n        if (!selectedTimestamps.contains(index)) selectTimestamp(index, false);\n        else unselectTimestamp(index);\n    }\n\n    public boolean isTimestampSelected(int index) {\n        return selectedTimestamps.contains(index);\n    }\n\n    public boolean isTimestampSelection(boolean includeHover) {\n        int selectedTimestampsCount = selectedTimestamps.size();\n        if (selectedTimestampsCount == 0) return false;\n        if (selectedTimestampsCount > 1)  return true;\n        return (includeHover || !hovering || hoveredSelected);\n    }\n\n\n    private void unselectTimestamp(int index, boolean notifyTable) {\n        boolean change = selectedTimestamps.remove(index);\n        if (notifyTable && detailsModel != null)\n            detailsModel.fireTableCellUpdated(index, 0);\n        if (change) {\n            updateSelectedItems();\n            notifyTimeSelectionChanged();\n        }\n    }\n\n    public void resetSelectedTimestamps() {\n        if (selectedTimestamps.isEmpty()) return;\n        selectedTimestamps.clear();\n        if (detailsModel != null) detailsModel.fireTableDataChanged();\n        updateSelectedItems();\n        notifyTimeSelectionChanged();\n    }\n\n    private void updateSelectedItems() {\n        List<SynchronousXYItem> selectedItems = getSelectedItems();\n        List<ItemSelection> selections =\n                new ArrayList<>(selectedItems.size() * selectedTimestamps.size());\n\n        for (int selectedIndex : selectedTimestamps)\n            for (SynchronousXYItem selectedItem : selectedItems)\n                selections.add(new XYItemSelection.Default(selectedItem,\n                               selectedIndex, XYItemSelection.DISTANCE_UNKNOWN));\n\n        chart.getSelectionModel().setSelectedItems(selections);\n    }\n\n    public Set<Integer> getSelectedTimestamps() {\n        return selectedTimestamps;\n    }\n    \n    public void selectInterval(int index1, int index2) {\n        selectedIntervals.add(index1);\n        selectedIntervals.add(index2);\n    }\n    \n    public List<Integer> getSelectedIntervals() {\n        return selectedIntervals;\n    }\n    \n    public void resetSelectedIntervals() {\n        selectedIntervals.clear();\n    }\n    \n    public void selectedIntervalsChanged() {\n        notifyIntervalsSelectionChanged();\n    }\n\n    private void highlightTimestamp(int selectedIndex) {\n        ChartSelectionModel selectionModel = chart.getSelectionModel();\n        List<ItemSelection> oldSelection = selectionModel.getHighlightedItems();\n        int oldSelectedIndex = -1;\n        if (!oldSelection.isEmpty()) {\n            XYItemSelection sel = (XYItemSelection)oldSelection.get(0);\n            oldSelectedIndex = sel.getValueIndex();\n        }\n\n        if (selectedIndex != -1)\n            scrollChartToSelection(oldSelectedIndex, selectedIndex);\n    }\n\n\n    public void scrollChartToIndex(int index) {\n        scrollChartToSelection(-1, index);\n    }\n\n    private void scrollChartToSelection(int oldIndex, int newIndex) {\n        Timeline timeline = itemsModel.getTimeline();\n        ChartContext context = chart.getChartContext();\n        long dataOffsetX = context.getDataOffsetX();\n        long newDataX = timeline.getTimestamp(newIndex);\n        long newOffsetX = (long)context.getViewWidth(newDataX - dataOffsetX);\n\n        long offsetX = chart.getOffsetX();\n        long viewWidth = context.getViewportWidth();\n        if (newOffsetX >= offsetX + SCROLL_MARGIN_LEFT &&\n            newOffsetX <= offsetX + viewWidth - SCROLL_MARGIN_RIGHT) return;\n\n        long oldDataX = oldIndex == -1 ? -1 : timeline.getTimestamp(oldIndex);\n        long oldOffsetX = oldIndex == -1 ? -1 : (long)context.getViewWidth(oldDataX - dataOffsetX);\n\n        if (oldIndex == -1) {\n            chart.setOffset(newOffsetX - context.getViewportWidth() / 2, chart.getOffsetY());\n        } else if (oldOffsetX > newOffsetX) {\n            chart.setOffset(newOffsetX - SCROLL_MARGIN_LEFT, chart.getOffsetY());\n        } else {\n            chart.setOffset(newOffsetX - context.getViewportWidth() + SCROLL_MARGIN_RIGHT, chart.getOffsetY());\n        }\n\n        chart.repaintDirty();\n    }\n\n\n    private List<SynchronousXYItem> getSelectedItems() {\n        List<TimelineChart.Row> selectedRows = chart.getSelectedRows();\n        List<SynchronousXYItem> selectedItems = new ArrayList<>();\n        for (TimelineChart.Row selectedRow : selectedRows)\n            selectedItems.addAll(Arrays.asList(selectedRow.getItems()));\n        return selectedItems;\n    }\n\n    private List<ValueItemDescriptor> getSelectedDescriptors() {\n        List<TimelineChart.Row> selectedRows = chart.getSelectedRows();\n        List selectedDescriptors = new ArrayList();\n        for (TimelineChart.Row selectedRow : selectedRows)\n            selectedDescriptors.addAll(Arrays.asList(getProbe(selectedRow).getItemDescriptors()));\n        return selectedDescriptors;\n    }\n\n\n    // --- Bounds selection management -----------------------------------------\n\n    private int startIndex = -1;\n    private int endIndex = -1;\n\n    public void selectAll() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                TimelineSelectionManager selection = (TimelineSelectionManager)chart.getSelectionModel();\n                selection.selectAll();\n                startIndex = selection.getStartIndex();\n                endIndex = selection.getEndIndex();\n                notifyIndexSelectionChanged();\n            }\n        });\n    }\n\n    public boolean isSelectAll() {\n        return endIndex - startIndex == model.getTimestampsCount() - 1;\n    }\n\n    public int getStartIndex() { return startIndex; }\n\n    public int getEndIndex() { return endIndex; }\n\n\n    void indexSelectionChanged(int startIndex, int endIndex) {\n        this.startIndex = startIndex;\n        this.endIndex = endIndex;\n        notifyIndexSelectionChanged();\n    }\n\n\n    // --- General selection support -------------------------------------------\n\n    public void addSelectionListener(SelectionListener listener) {\n        selectionListeners.add(listener);\n    }\n\n    public void removeSelectionListener(SelectionListener listener) {\n        selectionListeners.remove(listener);\n    }\n    \n    private void notifyIntervalsSelectionChanged() {\n        for (SelectionListener selectionListener : selectionListeners)\n            selectionListener.intervalsSelectionChanged();\n    }\n\n    private void notifyIndexSelectionChanged() {\n        for (SelectionListener selectionListener : selectionListeners)\n            selectionListener.indexSelectionChanged();\n    }\n\n    private void notifyTimeSelectionChanged() {\n        boolean sel = isTimestampSelection(true);\n        boolean hov = sel && !isTimestampSelection(false);\n        for (SelectionListener selectionListener : selectionListeners)\n            selectionListener.timeSelectionChanged(sel, hov);\n    }\n\n\n    public static interface SelectionListener {\n        \n        public void intervalsSelectionChanged();\n\n        public void indexSelectionChanged();\n\n        public void timeSelectionChanged(boolean timestampsSelected,\n                                         boolean justHovering);\n\n    }\n\n    public static interface DescriptorResolver {\n\n        public TracerProbeDescriptor getDescriptor(TracerProbe p);\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineTooltipOverlay.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Graphics;\nimport java.awt.Point;\nimport java.awt.Rectangle;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.TreeSet;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartOverlay;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionListener;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemPainter;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.PaintersModel;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.TimelineChart.Row;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineTooltipOverlay extends ChartOverlay implements ActionListener {\n\n    static final int TOOLTIP_OFFSET = 15;\n    static final int TOOLTIP_MARGIN = 10;\n    private static final int TOOLTIP_RESPONSE = 50;\n    private static final int ANIMATION_STEPS = 5;\n\n    private TimelineTooltipPainter.Model[] rowModels;\n\n    private Set<Integer> selectedTimestamps = Collections.emptySet();\n\n    private Timer timer;\n    private int currentStep;\n    private Point[] targetPositions;\n\n\n    TimelineTooltipOverlay(final TimelineSupport support) {\n        final TimelineChart chart = support.getChart();\n\n        if (chart.getSelectionModel() == null)\n            throw new NullPointerException(\"No ChartSelectionModel set for \" + chart); // NOI18N\n\n        if (!Utils.forceSpeed()) {\n            timer = new Timer(TOOLTIP_RESPONSE / ANIMATION_STEPS, this);\n            timer.setInitialDelay(0);\n        }\n\n        setLayout(null);\n\n        final Runnable tooltipUpdater = new Runnable() {\n            public void run() { updateTooltip(chart); }\n        };\n\n        chart.getSelectionModel().addSelectionListener(new ChartSelectionListener() {\n\n            public void selectionModeChanged(int newMode, int oldMode) {}\n\n            public void selectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds) {}\n\n            public void highlightedItemsChanged(List<ItemSelection> currentItems,\n                List<ItemSelection> addedItems, List<ItemSelection> removedItems) {\n                tooltipUpdater.run();\n            }\n\n            public void selectedItemsChanged(List<ItemSelection> currentItems,\n                List<ItemSelection> addedItems, List<ItemSelection> removedItems) {}\n\n        });\n\n        chart.addConfigurationListener(new ChartConfigurationListener.Adapter() {\n            \n            public void contentsUpdated(long offsetX, long offsetY,\n                                    double scaleX, double scaleY,\n                                    long lastOffsetX, long lastOffsetY,\n                                    double lastScaleX, double lastScaleY,\n                                    int shiftX, int shiftY) {\n                if (lastOffsetX != offsetX || lastOffsetY != offsetY ||\n                    scaleX != lastScaleX || scaleY != lastScaleY)\n                    SwingUtilities.invokeLater(tooltipUpdater);\n            }\n\n        });\n\n        chart.addRowListener(new TimelineChart.RowListener() {\n\n            public void rowsAdded(List<Row> rows) { tooltipUpdater.run(); }\n\n            public void rowsRemoved(List<Row> rows) { tooltipUpdater.run(); }\n\n            public void rowsResized(List<Row> rows) { tooltipUpdater.run(); }\n        });\n\n        support.addSelectionListener(new TimelineSupport.SelectionListener() {\n            \n            public void intervalsSelectionChanged() {}\n\n            public void indexSelectionChanged() {}\n\n            public void timeSelectionChanged(boolean timestampsSelected, boolean justHovering) {\n                selectedTimestamps = new TreeSet<>(support.getSelectedTimestamps());\n                tooltipUpdater.run();\n            }\n        });\n    }\n\n    void setupModel(TimelineTooltipPainter.Model[] rowModels) {\n        removeAll();\n        \n        this.rowModels = rowModels;\n\n        for (TimelineTooltipPainter.Model rowModel : rowModels) {\n            TimelineTooltipPainter painter = new TimelineTooltipPainter(false);\n            add(painter);\n            painter.setVisible(false);\n        }\n\n        targetPositions = new Point[rowModels.length];\n    }\n\n    private void setPosition(Point p, TimelineTooltipPainter tooltipPainter,\n                             int index, boolean immediate) {\n        if (getComponentCount() > 0) {\n            if (p == null) {\n                if (tooltipPainter.isVisible()) tooltipPainter.setVisible(false);\n                if (timer != null) timer.stop();\n            } else {\n                if (immediate || !tooltipPainter.isVisible() || timer == null) {\n                    tooltipPainter.setVisible(true);\n                    tooltipPainter.setLocation(p);\n                } else {\n                    currentStep = 0;\n                    targetPositions[index] = p;\n                    timer.restart();\n                }\n            }\n        }\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        for (int i = 0; i < rowModels.length; i++) {\n            TimelineTooltipPainter tooltipPainter = (TimelineTooltipPainter)getComponent(i);\n            Point targetPosition = targetPositions[i];\n            Point currentPosition = tooltipPainter.getLocation();\n\n            currentPosition.x += (targetPosition.x - currentPosition.x) /\n                                 (ANIMATION_STEPS - currentStep);\n            currentPosition.y += (targetPosition.y - currentPosition.y) /\n                                 (ANIMATION_STEPS - currentStep);\n            tooltipPainter.setLocation(currentPosition);\n        }\n        if (++currentStep == ANIMATION_STEPS) timer.stop();\n    }\n\n\n    private void checkAllocatedSelectionPainters() {\n        int allocatedPainters = getComponentCount() - rowModels.length;\n        int requiredPainters = rowModels.length * selectedTimestamps.size();\n        if (allocatedPainters == requiredPainters) return;\n\n        int diff = requiredPainters - allocatedPainters;\n        if (diff > 0) {\n            for (int i = 0; i < diff; i++) add(new TimelineTooltipPainter(true));\n        } else {\n            for (int i = 0; i > diff; i--) remove(getComponentCount() - 1);\n            repaint();\n        }\n    }\n\n    @SuppressWarnings(\"element-type-mismatch\")\n    private void updateTooltip(TimelineChart chart) {\n        if (rowModels == null) return;\n\n        ChartSelectionModel selectionModel = chart.getSelectionModel();\n        if (selectionModel == null) return;\n\n        checkAllocatedSelectionPainters();\n        \n        int painterIndex = getComponentCount() - 1;\n        for (int rowIndex = 0; rowIndex < chart.getRowsCount(); rowIndex++) {\n            TimelineChart.Row row = chart.getRow(rowIndex);\n            ChartContext rowContext = row.getContext();\n            int itemsCount = row.getItemsCount();\n            TimelineTooltipPainter.Model model = rowModels[rowIndex];\n            for (int mark : selectedTimestamps) {\n                List<ItemSelection> selections = new ArrayList<>(itemsCount);\n                for (int itemIndex = 0; itemIndex < itemsCount; itemIndex++) {\n                    SynchronousXYItem item = (SynchronousXYItem)row.getItem(itemIndex);\n                    selections.add(new XYItemSelection.Default(item, mark,\n                                   XYItemSelection.DISTANCE_UNKNOWN));\n                }\n                TimelineTooltipPainter tooltipPainter =\n                        (TimelineTooltipPainter)getComponent(painterIndex--);\n                tooltipPainter.update(model, selections);\n                tooltipPainter.setSize(tooltipPainter.getPreferredSize());\n                setPosition(selections, chart.getPaintersModel(), rowContext,\n                            tooltipPainter, rowIndex, true);\n            }\n        }\n\n        List<ItemSelection> highlightedItems =\n                selectionModel.getHighlightedItems();\n\n        boolean noSelection = highlightedItems.isEmpty();\n        if (!noSelection) {\n            XYItemSelection sel = (XYItemSelection)highlightedItems.get(0);\n            noSelection = sel.getItem().getValuesCount() <= sel.getValueIndex();\n        }\n\n        int rowsCount = chart.getRowsCount();\n        for (int i = 0; i < rowsCount; i++) {\n            TimelineTooltipPainter tooltipPainter =\n                    (TimelineTooltipPainter)getComponent(i);\n            if (noSelection) {\n                setPosition(null, tooltipPainter, i, false);\n            } else {\n                TimelineChart.Row row = chart.getRow(i);\n                List<ItemSelection> selections = new ArrayList<>(highlightedItems.size());\n\n                for (ItemSelection sel : highlightedItems)\n                    if (row.containsItem(sel.getItem()))\n                        selections.add(sel);\n                \n                tooltipPainter.update(rowModels[i], selections);\n                tooltipPainter.setSize(tooltipPainter.getPreferredSize());\n                setPosition(selections, chart.getPaintersModel(), row.getContext(), tooltipPainter, i, false);\n            }\n        }\n    }\n\n    private void setPosition(List<ItemSelection> selectedItems, PaintersModel paintersModel,\n                             ChartContext chartContext, TimelineTooltipPainter tooltipPainter,\n                             int index, boolean immediate) {\n        LongRect bounds = null;\n\n        for (ItemSelection selection : selectedItems) {\n            ItemPainter painter = paintersModel.getPainter(selection.getItem());\n            LongRect selBounds = painter.getSelectionBounds(selection, chartContext);\n            if (bounds == null) bounds = selBounds; else LongRect.add(bounds, selBounds);\n        }\n\n        setPosition(normalizePosition(Utils.checkedRectangle(bounds), tooltipPainter,\n                    chartContext), tooltipPainter, index, immediate);\n    }\n\n    private Point normalizePosition(Rectangle bounds, TimelineTooltipPainter tooltipPainter, ChartContext chartContext) {\n        Point p = new Point();\n\n        p.x = bounds.x + bounds.width + TOOLTIP_OFFSET;\n        if (p.x > chartContext.getViewportWidth() - tooltipPainter.getWidth() - TOOLTIP_MARGIN)\n            p.x = bounds.x - tooltipPainter.getWidth() - TOOLTIP_OFFSET;\n\n        int rowY = Utils.checkedInt(chartContext.getViewportOffsetY());\n        int rowHeight = chartContext.getViewportHeight();\n        p.y = rowY + (rowHeight - tooltipPainter.getHeight()) / 2;\n\n        return p;\n    }\n\n\n    public void paint(Graphics g) {\n        if (getComponentCount() == 0) return;\n\n        Rectangle bounds = new Rectangle(0, 0, getWidth(), getHeight());\n        Rectangle clip = g.getClipBounds();\n        if (clip == null) g.setClip(bounds);\n        else g.setClip(clip.intersection(bounds));\n\n        super.paint(g);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineTooltipPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.LegendFont;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.Spacer;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineTooltipPainter extends JPanel {\n\n    private static Color SELECTION_FOREGROUND = Color.BLACK;\n    private static Color SELECTION_BACKGROUND = Utils.forceSpeed() ?\n                                            new Color(255, 255, 255) :\n                                            new Color(255, 255, 255, 225);\n    private static Color HOVER_FOREGROUND = Color.WHITE;\n    private static Color HOVER_BACKGROUND = Utils.forceSpeed() ?\n                                            new Color(80, 80, 80) :\n                                            new Color(0, 0, 0, 170);\n\n    private JLabel[] valueNames;\n    private JLabel[] valuePainters;\n    private JLabel[] unitsPainters;\n\n    private final boolean selection;\n    private final Color foreground;\n    private final Color background;\n\n\n    TimelineTooltipPainter(boolean selection) {\n        this.selection = selection;\n\n        foreground = selection ? SELECTION_FOREGROUND : HOVER_FOREGROUND;\n        background = selection ? SELECTION_BACKGROUND : HOVER_BACKGROUND;\n\n        initUI();\n    }\n\n\n    void update(Model rowModel, List<ItemSelection> selectedItems) {\n        int rowsCount = rowModel.getRowsCount();\n        if (valueNames == null || valueNames.length != rowsCount)\n            initComponents(rowsCount);\n        \n        for (int i = 0; i < rowsCount; i++) {\n            XYItemSelection sel = (XYItemSelection)selectedItems.get(i);\n            long itemValue = sel.getItem().getYValue(sel.getValueIndex());\n            valueNames[i].setText(rowModel.getRowName(i));\n            valuePainters[i].setText(rowModel.getRowValue(i, itemValue));\n            unitsPainters[i].setText(rowModel.getRowUnits(i));\n        }\n    }\n\n\n    protected void paintComponent(Graphics g) {\n        g.setColor(background);\n        g.fillRect(0, 0, getWidth(), getHeight());\n        super.paintComponent(g);\n        if (selection) {\n            g.setColor(foreground);\n            g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);\n        }\n    }\n\n\n    private void initUI() {\n        setOpaque(false);\n        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));\n\n        setLayout(new GridBagLayout());\n    }\n\n    private void initComponents(int rowsCount) {\n        removeAll();\n        \n        valueNames = new JLabel[rowsCount];\n        valuePainters = new JLabel[rowsCount];\n        unitsPainters = new JLabel[rowsCount];\n        \n        GridBagConstraints constraints;\n\n        for (int i = 0; i < rowsCount; i++) {\n            JLabel itemLabel = new JLabel();\n            valueNames[i] = itemLabel;\n            itemLabel.setFont(new LegendFont());\n            itemLabel.setForeground(foreground);\n            itemLabel.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 0;\n            constraints.gridy = i;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHWEST;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            add(itemLabel, constraints);\n\n            JLabel valueLabel = new JLabel();\n            valuePainters[i] = valueLabel;\n            valueLabel.setFont(new LegendFont());\n            valueLabel.setForeground(foreground);\n            valueLabel.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 1;\n            constraints.gridy = i;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.insets = new Insets(0, 8, 0, 0);\n            add(valueLabel, constraints);\n\n            JLabel unitsLabel = new JLabel();\n            unitsPainters[i] = unitsLabel;\n            unitsLabel.setFont(new LegendFont());\n            unitsLabel.setForeground(foreground);\n            unitsLabel.setOpaque(false);\n            constraints = new GridBagConstraints();\n            constraints.gridx = 2;\n            constraints.gridy = i;\n            constraints.gridwidth = 1;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.insets = new Insets(0, 3, 0, 0);\n            add(unitsLabel, constraints);\n\n            constraints = new GridBagConstraints();\n            constraints.gridx = 3;\n            constraints.gridy = i;\n            constraints.weightx = 1;\n            constraints.gridwidth = GridBagConstraints.REMAINDER;\n            constraints.anchor = GridBagConstraints.NORTHEAST;\n            constraints.insets = new Insets(0, 0, 0, 0);\n            add(Spacer.create(), constraints);\n        }\n    }\n\n\n    static interface Model {\n\n        public int    getRowsCount      ();\n        public String getRowName        (int index);\n        public String getRowValue       (int index, long itemValue);\n        public String getRowUnits       (int index);\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineUnitsOverlay.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartOverlay;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItemsModel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.ColorIcon;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.LabelRenderer;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.swing.LegendFont;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class TimelineUnitsOverlay extends ChartOverlay {\n\n    private final TimelineChart chart;\n    private final LabelRenderer painter;\n\n    private Model model;\n\n\n    TimelineUnitsOverlay(TimelineChart chart) {\n        this.chart = chart;\n\n        painter = new LabelRenderer();\n        painter.setFont(new LegendFont());\n\n        int size = painter.getFont().getSize() - 3;\n        ColorIcon.setup(size, size,\n                LegendFont.FOREGROUND_COLOR, LegendFont.BACKGROUND_COLOR);\n    }\n\n\n    void setupModel(Model model) {\n        this.model = model;\n    }\n\n\n    private boolean hasValues() {\n        return ((SynchronousXYItemsModel)chart.getItemsModel()).getTimeline().\n                getTimestampsCount() > 0;\n    }\n\n    private void setupPainter(String text, Color color) {\n        painter.setText(text);\n        painter.setIcon(color == null ? null : ColorIcon.fromColor(color));\n    }\n\n\n    public void paint(Graphics g) {\n        if (model == null || !hasValues()) return;\n\n        int w = getWidth();\n        model.prefetch();\n        int rowsCount = chart.getRowsCount();\n\n        for (int rowIndex = 0; rowIndex < rowsCount; rowIndex++) {\n            TimelineChart.Row row = chart.getRow(rowIndex);\n            ChartContext rowContext = row.getContext();\n\n            int y = Utils.checkedInt(rowContext.getViewportOffsetY());\n            int h = rowContext.getViewportHeight();\n\n            Color[] colors = model.getColors(row);\n\n            int xx = w - 2;\n            int yy = y;\n            for (int itemIndex = colors.length - 1; itemIndex >= 0; itemIndex--) {\n                setupPainter(model.getMaxUnits(row)[itemIndex], colors[itemIndex]);\n                xx -= painter.getPreferredSize().width;\n                paint(g, xx, yy);\n                xx -= 10;\n            }\n\n            xx = w - 2;\n            yy = -1;\n            for (int itemIndex = colors.length - 1; itemIndex >= 0; itemIndex--) {\n                setupPainter(model.getMinUnits(row)[itemIndex], colors[itemIndex]);\n                Dimension pd = painter.getPreferredSize();\n                xx -= pd.width;\n                if (yy == -1) yy = y + h - pd.height - 1;\n                paint(g, xx, yy);\n                xx -= 10;\n            }\n        }\n    }\n\n    private void paint(Graphics g, int x, int y) {\n        painter.setLocation(x, y + 1);\n        painter.setForeground(LegendFont.BACKGROUND_COLOR);\n        painter.paint(g);\n\n        painter.setLocation(x, y);\n        painter.setForeground(LegendFont.FOREGROUND_COLOR);\n        if (painter.getIcon() != null)\n            painter.setIcon(ColorIcon.BOTTOM_SHADOW);\n        painter.paint(g);\n    }\n\n\n    // --- Performance tweaks ---------------------------------------------------\n\n    public void invalidate() {}\n\n    public void update(Graphics g) {}\n\n\n    // --- Model definition ----------------------------------------------------\n\n    static interface Model {\n\n        public void prefetch();\n        public Color[]  getColors(TimelineChart.Row row);\n        public String[] getMinUnits(TimelineChart.Row row);\n        public String[] getMaxUnits(TimelineChart.Row row);\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineXYItem.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemChange;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class TimelineXYItem extends SynchronousXYItem {\n\n    private int lastIndex;\n    private int lastValuesCount;\n\n    private final LongRect bounds;\n    private long initialMinY;\n    private long initialMaxY;\n\n    private long minY;\n    private long maxY;\n\n    private int itemIndex;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    TimelineXYItem(String name, int itemIndex) {\n        this(name, Long.MAX_VALUE, itemIndex);\n    }\n\n    TimelineXYItem(String name, long initialMinY, int itemIndex) {\n        this(name, initialMinY, Long.MIN_VALUE, itemIndex);\n    }\n\n    TimelineXYItem(String name, long initialMinY, long initialMaxY, int itemIndex) {\n        super(name, initialMinY, initialMaxY);\n        this.initialMinY = initialMinY;\n        this.initialMaxY = initialMaxY;\n        minY = Long.MAX_VALUE;\n        maxY = Long.MIN_VALUE;\n        bounds = new LongRect();\n        lastIndex = -1;\n        setIndex(itemIndex);\n    }\n\n\n    // --- Internal interface --------------------------------------------------\n\n    final void setIndex(int itemIndex) { this.itemIndex = itemIndex; }\n\n    final int getIndex() { return itemIndex; }\n\n\n    // --- Item telemetry ------------------------------------------------------\n\n    public XYItemChange valuesChanged() {\n\n        int valuesCount = getValuesCount();\n        int index = valuesCount - 1;\n        XYItemChange change = null;\n\n        if (index > -1) { // New item(s)\n\n            // Save oldBounds, setup dirtyBounds\n            LongRect oldBounds = new LongRect(bounds);\n            LongRect dirtyBounds = new LongRect();\n\n            boolean initBounds = lastIndex == -1;\n            int dirtyIndex = lastIndex == -1 ? 0 : lastIndex;\n\n            // Process other values\n            for (int i = dirtyIndex; i <= index; i++) {\n\n                long timestamp = getXValue(i);\n                long value = getYValue(i);\n\n                // Update item minY/maxY\n                minY = Math.min(value, minY);\n                maxY = Math.max(value, maxY);\n\n                // Process item bounds\n                if (initBounds) {\n                    // Initialize item bounds\n                    bounds.x = timestamp;\n                    bounds.y = Math.min(value, initialMinY);\n                    bounds.width = 0;\n                    bounds.height = Math.max(value, initialMaxY) - bounds.y;\n                    initBounds = false;\n                } else {\n                    // Update item bounds\n                    LongRect.add(bounds, timestamp, value);\n                    if (valuesCount == lastValuesCount) {\n                        bounds.x = getXValue(0);\n                        bounds.width = getXValue(valuesCount - 1) - bounds.x;\n                    }\n                }\n\n                // Process dirty bounds\n                if (i == dirtyIndex) {\n                    // Setup dirty bounds\n                    dirtyBounds.x = timestamp;\n                    dirtyBounds.y = value;\n                    dirtyBounds.width = getXValue(index) - dirtyBounds.x;\n                } else {\n                    // Update dirty y/height\n                    long dirtyY = dirtyBounds.y;\n                    dirtyBounds.y = Math.min(dirtyY, value);\n                    dirtyBounds.height = Math.max(dirtyY, value) - dirtyBounds.y;\n                }\n\n            }\n\n            // Return ItemChange\n            int indexesCount = index - lastIndex;\n            int[] indexes = new int[indexesCount];\n            for (int i = 0; i < indexesCount; i++) indexes[i] = lastIndex + 1 + i;\n            change = new XYItemChange.Default(this, indexes, oldBounds,\n                                              new LongRect(bounds), dirtyBounds);\n\n        } else { // Reset\n\n            minY = Long.MAX_VALUE;\n            maxY = Long.MIN_VALUE;\n\n            // Save oldBounds\n            LongRect oldBounds = new LongRect(bounds);\n            LongRect.set(bounds, 0, 0, 0, 0);\n\n            // Return ItemChange\n            change = new XYItemChange.Default(this, new int[] { -1 }, oldBounds,\n                                            new LongRect(bounds), oldBounds);\n\n        }\n        \n        lastIndex = index;\n        lastValuesCount = valuesCount;\n        return change;\n        \n    }\n\n    public long getMinYValue() { return minY; }\n\n    public long getMaxYValue() { return maxY; }\n    \n    public LongRect getBounds() {\n        if (getValuesCount() > 0) return bounds;\n        else return getInitialBounds();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/TimelineXYPainter.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Color;\nimport java.awt.Graphics2D;\nimport java.awt.Rectangle;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartItem;\nimport org.graalvm.visualvm.lib.charts.ChartItemChange;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.LongRect;\nimport org.graalvm.visualvm.lib.charts.xy.XYItem;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemChange;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemPainter;\nimport org.graalvm.visualvm.lib.charts.xy.XYItemSelection;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYChartContext;\nimport org.graalvm.visualvm.lib.charts.xy.synchronous.SynchronousXYItem;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class TimelineXYPainter extends XYItemPainter.Abstract {\n\n    private final int viewExtent;\n    private final boolean bottomBased;\n\n    private boolean painting;\n\n    protected final double dataFactor;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    TimelineXYPainter(int viewExtent, boolean bottomBased, double dataFactor) {\n        this.viewExtent = viewExtent;\n        this.bottomBased = bottomBased;\n        this.dataFactor = dataFactor;\n        painting = true;\n    }\n\n\n    // --- Abstract interface --------------------------------------------------\n\n    protected abstract void paint(XYItem item, List<ItemSelection> highlighted,\n                                  List<ItemSelection> selected, Graphics2D g,\n                                  Rectangle dirtyArea, SynchronousXYChartContext\n                                  context);\n\n    protected abstract Color getDefiningColor();\n\n\n    // --- Public interface ----------------------------------------------------\n\n    void setPainting(boolean painting) {\n        this.painting = painting;\n    }\n\n    boolean isPainting() {\n        return painting;\n    }\n\n    // --- ItemPainter implementation ------------------------------------------\n\n    public LongRect getItemBounds(ChartItem item) {\n        XYItem xyItem = (XYItem)item;\n        return getDataBounds(xyItem.getBounds());\n    }\n\n    public LongRect getItemBounds(ChartItem item, ChartContext context) {\n        XYItem xyItem = (XYItem)item;\n        return getViewBounds(xyItem.getBounds(), context);\n    }\n\n\n    public boolean isBoundsChange(ChartItemChange itemChange) {\n        XYItemChange change = (XYItemChange)itemChange;\n        return !LongRect.equals(change.getOldValuesBounds(),\n                                change.getNewValuesBounds());\n    }\n\n    public boolean isAppearanceChange(ChartItemChange itemChange) {\n        XYItemChange change = (XYItemChange)itemChange;\n        LongRect dirtyBounds = change.getDirtyValuesBounds();\n        return dirtyBounds.width != 0 || dirtyBounds.height != 0;\n    }\n\n    public LongRect getDirtyBounds(ChartItemChange itemChange, ChartContext context) {\n        XYItemChange change = (XYItemChange)itemChange;\n        return getViewBounds(change.getDirtyValuesBounds(), context);\n    }\n\n\n    public boolean supportsHovering(ChartItem item) {\n        return true;\n    }\n\n    public boolean supportsSelecting(ChartItem item) {\n        return true;\n    }\n\n    public LongRect getSelectionBounds(ItemSelection selection, ChartContext context) {\n\n        XYItemSelection sel = (XYItemSelection)selection;\n        XYItem item  = sel.getItem();\n        int selectedValueIndex = sel.getValueIndex();\n\n        if (selectedValueIndex == -1 ||\n            selectedValueIndex >= item.getValuesCount())\n            // This happens on reset - bounds of the selection are unknown, let's clear whole area\n            return new LongRect(0, 0, context.getViewportWidth(),\n                                context.getViewportHeight());\n        else\n            return getViewBounds(item, selectedValueIndex, context);\n    }\n\n    public XYItemSelection getClosestSelection(ChartItem item, int viewX,\n                                               int viewY, ChartContext context) {\n\n        SynchronousXYChartContext contx = (SynchronousXYChartContext)context;\n\n        int nearestTimestampIndex = contx.getNearestTimestampIndex(viewX, viewY);\n        if (nearestTimestampIndex == -1) return null; // item not visible\n\n        SynchronousXYItem xyItem = (SynchronousXYItem)item;\n        return new XYItemSelection.Default(xyItem, nearestTimestampIndex,\n                                           ItemSelection.DISTANCE_UNKNOWN);\n    }\n\n    public final void paintItem(ChartItem item, List<ItemSelection> highlighted,\n                          List<ItemSelection> selected, Graphics2D g,\n                          Rectangle dirtyArea, ChartContext context) {\n\n        if (!painting) return;\n        \n        XYItem it = (XYItem)item;\n        if (it.getValuesCount() < 1) return;\n        if (context.getViewWidth() == 0 || context.getViewHeight() == 0) return;\n\n        SynchronousXYChartContext ctx = (SynchronousXYChartContext)context;\n        paint((XYItem)item, highlighted, selected, g, dirtyArea, ctx);\n    }\n\n\n    // --- XYItemPainter implementation ----------------------------------------\n\n    public double getItemView(double dataY, XYItem item, ChartContext context) {\n        return context.getViewY(dataY * dataFactor);\n    }\n\n    public double getItemValue(double viewY, XYItem item, ChartContext context) {\n        return context.getDataY(viewY / dataFactor);\n    }\n\n    public double getItemValueScale(XYItem item, ChartContext context) {\n        double scale = context.getViewHeight(dataFactor);\n        if (scale <= 0) scale = -1;\n        return scale;\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private LongRect getDataBounds(LongRect itemBounds) {\n        LongRect bounds = new LongRect(itemBounds);\n        bounds.y *= dataFactor;\n        bounds.height *= dataFactor;\n\n        if (bottomBased) {\n            bounds.height += bounds.y;\n            bounds.y = 0;\n        }\n\n        return bounds;\n    }\n\n    private LongRect getViewBounds(LongRect itemBounds, ChartContext context) {\n        LongRect dataBounds = getDataBounds(itemBounds);\n\n        LongRect viewBounds = context.getViewRect(dataBounds);\n        LongRect.addBorder(viewBounds, viewExtent);\n\n        return viewBounds;\n    }\n\n    private LongRect getViewBounds(XYItem item, int valueIndex, ChartContext context) {\n        long xValue = item.getXValue(valueIndex);\n        long yValue = (long)(item.getYValue(valueIndex) * dataFactor);\n        return context.getViewRect(new LongRect(xValue, yValue, 0, 0));\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/VerticalTimelineLayout.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.LayoutManager2;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class VerticalTimelineLayout implements LayoutManager2 {\n\n    private final TimelineChart chart;\n\n\n    // --- Constructor ---------------------------------------------------------\n\n    VerticalTimelineLayout(TimelineChart chart) {\n        this.chart = chart;\n    }\n\n\n    // --- Public API ----------------------------------------------------------\n\n    public Dimension minimumLayoutSize(Container parent) {\n        return preferredLayoutSize(parent);\n    }\n\n    public Dimension maximumLayoutSize(Container parent) {\n        return preferredLayoutSize(parent);\n    }\n\n    public Dimension preferredLayoutSize(Container parent) {\n        Dimension dim = new Dimension(0, Utils.checkedInt(chart.getChartContext().getViewHeight()));\n\n        for (int i = 0; i < parent.getComponentCount(); i++)\n            dim.width = Math.max(dim.width, parent.getComponent(i).\n                                     getPreferredSize().width);\n\n        return dim;\n    }\n\n    public void layoutContainer(Container parent) {\n        int width = parent.getWidth();\n        for (int i = 0; i < parent.getComponentCount(); i++) {\n                ChartContext context = chart.getRow(i).getContext();\n                parent.getComponent(i).setBounds(0, Utils.checkedInt(context.getViewportOffsetY() + chart.getOffsetY()),\n                                                 width, context.getViewportHeight());\n        }\n    }\n\n\n    // --- Implicit implementation ---------------------------------------------\n\n    public void addLayoutComponent(Component comp, Object constraints) {}\n\n    public void addLayoutComponent(String name, Component comp) {}\n\n    public void removeLayoutComponent(Component comp) {}\n\n    public float getLayoutAlignmentX(Container target) { return 0.5f; }\n\n    public float getLayoutAlignmentY(Container target) { return 0.5f; }\n\n    public void invalidateLayout(Container target) {}\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/XChartSelectionOverlay.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline;\n\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Paint;\nimport java.awt.Rectangle;\nimport java.awt.Stroke;\nimport java.util.List;\nimport java.util.Objects;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.charts.ChartComponent;\nimport org.graalvm.visualvm.lib.charts.ChartConfigurationListener;\nimport org.graalvm.visualvm.lib.charts.ChartContext;\nimport org.graalvm.visualvm.lib.charts.ChartOverlay;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionListener;\nimport org.graalvm.visualvm.lib.charts.ChartSelectionModel;\nimport org.graalvm.visualvm.lib.charts.ItemSelection;\nimport org.graalvm.visualvm.lib.charts.swing.Utils;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class XChartSelectionOverlay extends ChartOverlay {\n\n    private static final boolean FORCE_SPEED = Utils.forceSpeed();\n\n    private ChartComponent chart;\n    private int selectionMode;\n    private Rectangle selectionBounds;\n    private Rectangle oldSelectionBounds;\n\n    private SelectionListener selectionListener;\n    private ConfigurationListener configurationListener;\n\n    private boolean renderingOptimized;\n\n    private Paint linePaint;\n    private Stroke lineStroke;\n    private int lineWidth = -1;\n\n    private Paint fillPaint;\n\n    private Stroke oddPerfStroke;\n    private Stroke evenPerfStroke;\n\n    private boolean drawTop;\n    private boolean drawBottom;\n    private boolean drawLeft;\n    private boolean drawRight;\n\n    private final TimelineSupport support;\n\n\n    public XChartSelectionOverlay(TimelineSupport support) {\n        this.support = support;\n        selectionListener = new SelectionListener();\n        configurationListener = new ConfigurationListener();\n        initDefaultValues();\n    }\n    \n\n    // --- Public API ----------------------------------------------------------\n\n    public final void registerChart(ChartComponent chart) {\n        unregisterListener();\n        this.chart = chart;\n        selectionMode = chart.getSelectionModel().getSelectionMode();\n        registerListener();\n    }\n\n    public final void unregisterChart(ChartComponent chart) {\n        unregisterListener();\n        this.chart = null;\n    }\n\n\n    public final void setRenderingOptimized(boolean renderingOptimized) {\n        this.renderingOptimized = renderingOptimized;\n    }\n\n    public final boolean isRenderingOptimized() {\n        return renderingOptimized;\n    }\n\n\n    public final void setLineStroke(Stroke lineStroke) {\n        this.lineStroke = lineStroke;\n        lineWidth = -1;\n    }\n\n    public final Stroke getLineStroke() {\n        return lineStroke;\n    }\n\n    public final void setLinePaint(Paint linePaint) {\n        this.linePaint = linePaint;\n    }\n\n    public final Paint getLinePaint() {\n        return linePaint;\n    }\n\n    public final void setFillPaint(Paint fillPaint) {\n        this.fillPaint = fillPaint;\n    }\n\n    public final Paint getFillPaint() {\n        return fillPaint;\n    }\n\n    public final void setLineMode(boolean drawTop, boolean drawLeft,\n                                  boolean drawBottom, boolean drawRight) {\n        this.drawTop = drawTop;\n        this.drawLeft = drawLeft;\n        this.drawBottom = drawBottom;\n        this.drawRight = drawRight;\n    }\n\n\n    // --- Private implementation ----------------------------------------------\n\n    private void registerListener() {\n        if (chart == null) return;\n        chart.getSelectionModel().addSelectionListener(selectionListener);\n        chart.addConfigurationListener(configurationListener);\n    }\n\n    private void unregisterListener() {\n        if (chart == null) return;\n        chart.getSelectionModel().removeSelectionListener(selectionListener);\n        chart.removeConfigurationListener(configurationListener);\n    }\n\n    private void initDefaultValues() {\n        setRenderingOptimized(true);\n\n        Color systemSelection = Utils.getSystemSelection();\n\n        setLineStroke(new BasicStroke(1));\n        setLinePaint(systemSelection);\n\n        setFillPaint(new Color(systemSelection.getRed(),\n                               systemSelection.getGreen(),\n                               systemSelection.getBlue(), 80));\n\n        oddPerfStroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 6, 6 }, 6);\n        evenPerfStroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 6, 6 }, 0);\n\n        setLineMode(true, true, true, true);\n    }\n\n\n    private int getLineWidth() {\n        if (lineWidth == -1)\n            lineWidth = FORCE_SPEED ? 1 :\n                        (int)Math.ceil(Utils.getStrokeWidth(lineStroke));\n        return lineWidth;\n    }\n\n    private Rectangle normalizeRect(Rectangle rect, int border) {\n        /*if (chart.fitsWidth()) {\n            rect.x = 0;\n            rect.width = getWidth();\n        } else*/ if (rect.width < 0) {\n            rect.x += rect.width;\n            rect.width = 0 - rect.width;\n        }\n\n        rect.y = 0;\n        rect.height = getHeight();\n\n        rect.grow(border, border);\n\n        return rect;\n    }\n\n\n    public void paint(Graphics g) {\n        if (selectionBounds == null) return;\n        \n        Graphics2D g2 = (Graphics2D)g;\n\n        Rectangle bounds = normalizeRect(new Rectangle(selectionBounds), 0);\n\n        if (selectionBounds.width != 0 /*|| selectionBounds.height != 0*/) {\n\n            if (bounds.width == 0 || bounds.height == 0 ||\n                chart.fitsWidth() && chart.fitsHeight()) return;\n\n            if (fillPaint != null && !FORCE_SPEED) {\n                Rectangle clip = g.getClipBounds();\n                if (clip == null) clip = new Rectangle(0, 0, getWidth(), getHeight());\n\n                g2.setPaint(fillPaint);\n                g2.fill(clip.intersection(bounds));\n            }\n\n            if (!FORCE_SPEED && linePaint != null && lineStroke != null) {\n                g2.setPaint(linePaint);\n                g2.setStroke(lineStroke);\n                drawRect(g2, bounds.x, bounds.y, bounds.width, bounds.height);\n            } else if (FORCE_SPEED) {\n                g2.setPaint(Color.BLACK);\n                g2.setStroke(evenPerfStroke);\n                drawRect(g2, bounds.x, bounds.y, bounds.width, bounds.height);\n                g2.setPaint(Color.WHITE);\n                g2.setStroke(oddPerfStroke);\n                drawRect(g2, bounds.x, bounds.y, bounds.width, bounds.height);\n            }\n        } else {\n            if (!FORCE_SPEED) {\n                g2.setPaint(selectionMode == ChartSelectionModel.SELECTION_RECT ?\n                    fillPaint : linePaint);\n                g2.setStroke(lineStroke);\n                g.drawLine(bounds.x, bounds.y, bounds.x, bounds.y + bounds.height - 1);\n            } else if (FORCE_SPEED) {\n                g2.setPaint(Color.BLACK);\n                g2.setStroke(evenPerfStroke);\n                g.drawLine(bounds.x, bounds.y, bounds.x, bounds.y + bounds.height - 1);\n                g2.setPaint(Color.WHITE);\n                g2.setStroke(oddPerfStroke);\n                g.drawLine(bounds.x, bounds.y, bounds.x, bounds.y + bounds.height - 1);\n            }\n        }\n\n    }\n\n    private void drawRect(Graphics g, int x, int y, int w, int h) {\n        if (drawTop) g.drawLine(x, y, x + w - 1, y);\n        if (drawLeft) g.drawLine(x, y, x, y + h - 1);\n        if (drawRight) g.drawLine(x + w - 1, y + h - 1, x + w - 1, y);\n        if (drawBottom) g.drawLine(x + w - 1, y + h - 1, x, y + h - 1);\n    }\n\n\n    private void updateSelection() {\n        oldSelectionBounds = selectionBounds;\n        selectionBounds = getCurrentBounds();\n        if (selectionMode == ChartSelectionModel.SELECTION_RECT)\n            rectBoundsChanged(selectionBounds, oldSelectionBounds, getLineWidth());\n    }\n\n    private Rectangle getCurrentBounds() {\n        TimelineSelectionManager manager = (TimelineSelectionManager)chart.getSelectionModel();\n        int startIndex = manager.getStartIndex();\n        int endIndex   = manager.getEndIndex();\n\n        if (startIndex > endIndex) {\n            endIndex = startIndex;\n            startIndex = manager.getEndIndex();\n        }\n\n        if (startIndex == -1) {\n            return null;\n        } else if (startIndex == endIndex) {\n            ChartContext context = chart.getChartContext();\n            long timestamp = support.getTimestamp(startIndex);\n            int x = Utils.checkedInt(context.getViewX(timestamp));\n            return new Rectangle(x, 0, 0, chart.getHeight());\n        } else {\n            ChartContext context = chart.getChartContext();\n            long startTimestamp = support.getTimestamp(startIndex);\n            long endTimestamp = support.getTimestamp(endIndex);\n            int startX = Utils.checkedInt(context.getViewX(startTimestamp));\n            int endX = Utils.checkedInt(context.getViewX(endTimestamp));\n            return new Rectangle(startX, 0, endX - startX, chart.getHeight());\n        }\n    }\n\n    private void rectBoundsChanged(Rectangle newBounds, Rectangle oldBounds, int lineW) {\n        if (Objects.equals(newBounds, oldBounds)) return; // No change, return\n        \n        if (newBounds != null && oldBounds != null) { // Updating changed selection\n            if (renderingOptimized) { // Painting just selection changes\n                if (newBounds.x == oldBounds.x) {\n                    int x1 = Math.min(newBounds.x + newBounds.width, oldBounds.x + oldBounds.width);\n                    int x2 = Math.max(newBounds.x + newBounds.width, oldBounds.x + oldBounds.width);\n                    paintRect(x1, 0, x2 - x1, getHeight(), lineW);\n                } else if (newBounds.x + newBounds.width == oldBounds.x + oldBounds.width) {\n                    int x1 = Math.min(newBounds.x, oldBounds.x);\n                    int x2 = Math.max(newBounds.x, oldBounds.x);\n                    paintRect(x1, 0, x2 - x1, getHeight(), lineW);\n                } else {\n                    int x1 = Math.min(newBounds.x, oldBounds.x);\n                    int x2 = Math.max(newBounds.x + newBounds.width, oldBounds.x + oldBounds.width);\n                    paintRect(x1, 0, x2 - x1, getHeight(), lineW);\n                }\n            } else { // Painting whole selection area\n                int x1 = Math.min(newBounds.x, oldBounds.x);\n                int x2 = Math.max(newBounds.x + newBounds.width, oldBounds.x + oldBounds.width);\n                paintRect(x1, 0, x2 - x1, getHeight(), lineW);\n            }\n        } else if (oldBounds != null) { // Clearing old selection\n            paintRect(oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height, lineW);\n        } else if (newBounds != null) { // Painting new selection\n            paintRect(newBounds.x, newBounds.y, newBounds.width, newBounds.height, lineW);\n        }\n    }\n\n    private void paintRect(int x, int y, int w, int h, int t) {\n        if (w != 0 && h != 0) {\n            Rectangle rect = new Rectangle(x, y, w, h);\n            rect.grow(t, t);\n            paintImmediately(rect);\n        }\n    }\n\n\n    private class SelectionListener implements ChartSelectionListener {\n\n        private boolean modeChanged = false;\n\n        public void selectionModeChanged(int newMode, int oldMode) {\n            selectionMode = newMode;\n            modeChanged = true;\n        }\n\n        public void selectionBoundsChanged(Rectangle newBounds, Rectangle oldBounds) {\n            if (modeChanged) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        modeChanged = false;\n                        \n                        oldSelectionBounds = selectionBounds;\n                        selectionBounds = getCurrentBounds();\n\n                        int lineWidth = getLineWidth();\n\n                        Rectangle rect = normalizeRect(new Rectangle(oldSelectionBounds == null ?\n                            getBounds() : oldSelectionBounds), lineWidth);\n                        paintImmediately(rect);\n\n                        if (selectionBounds != null) {\n                            rect = normalizeRect(new Rectangle(selectionBounds), lineWidth);\n                            paintImmediately(rect);\n                        }\n                    }\n                });\n            } else {\n                updateSelection();\n            }\n            \n        }\n\n        public void highlightedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems) {}\n\n        public void selectedItemsChanged(List<ItemSelection> currentItems,\n              List<ItemSelection> addedItems, List<ItemSelection> removedItems) {}\n\n    }\n\n\n    private class ConfigurationListener extends ChartConfigurationListener.Adapter {\n        public void contentsUpdated(long offsetX, long offsetY, double scaleX, double scaleY, long lastOffsetX, long lastOffsetY, double lastScaleX, double lastScaleY, int shiftX, int shiftY) {\n            if (lastOffsetX != offsetX || lastScaleX != scaleX || lastScaleY != scaleY)\n                updateSelection();\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/items/ContinuousXYItemDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items;\n\nimport java.awt.Color;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ItemValueFormatter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ContinuousXYItemDescriptor extends XYItemDescriptor {\n\n    public ContinuousXYItemDescriptor(String name, String description,\n                                      ItemValueFormatter formatter, double dataFactor,\n                                      long minValue, long maxValue, float lineWidth,\n                                      Color lineColor, Color fillColor) {\n\n        super(name, description, formatter, dataFactor, minValue, maxValue,\n              lineWidth, lineColor, fillColor);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/items/DiscreteXYItemDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items;\n\nimport java.awt.Color;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ItemValueFormatter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class DiscreteXYItemDescriptor extends XYItemDescriptor {\n\n    private final int width;\n    private final boolean fixedWidth;\n    private final boolean topLineOnly;\n    private final boolean outlineOnly;\n\n\n    public DiscreteXYItemDescriptor(String name, String description,\n                                    ItemValueFormatter formatter, double dataFactor,\n                                    long minValue, long maxValue, float lineWidth,\n                                    Color lineColor, Color fillColor, int width,\n                                    boolean fixedWidth, boolean topLineOnly,\n                                    boolean outlineOnly) {\n\n        super(name, description, formatter, dataFactor, minValue, maxValue,\n              lineWidth, lineColor, fillColor);\n\n        this.width = width;\n        this.fixedWidth = fixedWidth;\n        this.topLineOnly = topLineOnly;\n        this.outlineOnly = outlineOnly;\n    }\n\n\n    public int getWidth() {\n        return width;\n    }\n\n    public boolean isFixedWidth() {\n        return fixedWidth;\n    }\n\n    public boolean isTopLineOnly() {\n        return topLineOnly;\n    }\n\n    public boolean isOutlineOnly() {\n        return outlineOnly;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/items/IconItemDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items;\n\nimport java.awt.Color;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ItemValueFormatter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class IconItemDescriptor extends ValueItemDescriptor {\n\n    private final Color color;\n\n\n    public IconItemDescriptor(String name, String description,\n                              ItemValueFormatter formatter, Color color) {\n\n        super(name, description, formatter, 1, 0, 1000);\n\n        this.color = color;\n    }\n\n\n    public Color getColor() {\n        return color;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/items/ValueItemDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items;\n\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ItemValueFormatter;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ProbeItemDescriptor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ValueItemDescriptor extends ProbeItemDescriptor {\n\n    private final ItemValueFormatter formatter;\n    private final double dataFactor;\n    private final long minValue;\n    private final long maxValue;\n\n\n    ValueItemDescriptor(String name, String description,\n                        ItemValueFormatter formatter, double dataFactor,\n                        long minValue, long maxValue) {\n\n        super(name, description);\n        if (formatter == null) {\n            throw new IllegalArgumentException(\"formatter cannot be null\"); // NOI18N\n        }\n        if (dataFactor == 0) {\n            throw new IllegalArgumentException(\"dataFactor cannot be 0\"); // NOI18N\n        }\n        this.formatter = formatter;\n        this.dataFactor = dataFactor;\n        this.minValue = minValue;\n        this.maxValue = maxValue;\n    }\n\n\n    public final String getValueString(long value, int format) {\n        return formatter.formatValue(value, format);\n    }\n\n    public final String getUnitsString(int format) {\n        return formatter.getUnits(format);\n    }\n\n    public final double getDataFactor() {\n        return dataFactor;\n    }\n\n    public final long getMinValue() {\n        return minValue;\n    }\n\n    public final long getMaxValue() {\n        return maxValue;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/impl/timeline/items/XYItemDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.impl.timeline.items;\n\nimport java.awt.Color;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.ItemValueFormatter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class XYItemDescriptor extends ValueItemDescriptor {\n\n    private final float lineWidth;\n    private final Color lineColor;\n    private final Color fillColor;\n\n\n    XYItemDescriptor(String name, String description,\n                     ItemValueFormatter formatter, double dataFactor,\n                     long minValue, long maxValue, float lineWidth,\n                     Color lineColor, Color fillColor) {\n\n        super(name, description, formatter, dataFactor, minValue, maxValue);\n        this.lineWidth = lineWidth;\n        this.lineColor = lineColor;\n        this.fillColor = fillColor;\n    }\n\n\n    public final float getLineWidth() {\n        return lineWidth;\n    }\n\n    public final Color getLineColor() {\n        return lineColor;\n    }\n\n    public final Color getFillColor() {\n        return fillColor;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/logs/LogReader.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.logs;\n\nimport java.io.BufferedInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.Map;\nimport java.util.NavigableMap;\nimport java.util.TreeMap;\nimport java.util.logging.Handler;\nimport java.util.logging.LogRecord;\nimport java.util.logging.Logger;\nimport org.openide.filesystems.FileObject;\n\n/** Reads log records from file.\n *\n * @author Tomas Hurka\n */\npublic final class LogReader {\n\n    private static final Logger LOG = Logger.getLogger(LogRecords.class.getName());\n\n    private FileObject logFile;\n//    private int records;\n//    private long startTime;\n    private NavigableMap<Long,LogRecord> recordList;\n\n    public LogReader(FileObject f) {\n        logFile = f;\n        recordList = new TreeMap();\n    }\n\n\n    public void load() throws IOException {\n        try (InputStream is = new BufferedInputStream(logFile.getInputStream(),32768)) {\n            LogRecords.scan(is, new LogHandler());\n        }\n    }\n\n    public LogRecord getRecordFor(long time) {\n        Map.Entry<Long,LogRecord> entry = recordList.floorEntry(new Long(time));\n\n        if (entry != null) {\n            return entry.getValue();\n        }\n        return null;\n    }\n\n    class LogHandler extends Handler {\n\n        @Override\n        public void publish(LogRecord record) {\n//            System.out.println(\"Record \"+ records++);\n//            if (startTime == 0) {\n//                startTime = record.getMillis();\n//                System.out.println(\"Start date: \"+new Date(startTime));\n//            } else {\n//                System.out.println(\"Time: \"+(record.getMillis()-startTime));\n//            }\n//            System.out.println(record.getMessage());\n            recordList.put(new Long(record.getMillis()), record);\n        }\n\n        @Override\n        public void flush() {\n//            System.out.println(\"Flush\");\n        }\n\n        @Override\n        public void close() throws SecurityException {\n//           System.out.println(\"Close\");\n        }\n\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/logs/LogRecords.java",
    "content": "/*\n * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.snaptracer.logs;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.PushbackInputStream;\nimport java.io.SequenceInputStream;\nimport java.util.ArrayDeque;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.EnumMap;\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.MissingResourceException;\nimport java.util.Queue;\nimport java.util.ResourceBundle;\nimport java.util.logging.Handler;\nimport java.util.logging.Level;\nimport java.util.logging.LogRecord;\nimport java.util.logging.Logger;\nimport java.util.zip.GZIPInputStream;\nimport javax.xml.XMLConstants;\nimport javax.xml.parsers.ParserConfigurationException;\nimport javax.xml.parsers.SAXParser;\nimport javax.xml.parsers.SAXParserFactory;\nimport org.openide.util.NbBundle;\nimport org.xml.sax.Attributes;\nimport org.xml.sax.Locator;\nimport org.xml.sax.SAXException;\nimport org.xml.sax.SAXNotRecognizedException;\nimport org.xml.sax.SAXParseException;\nimport org.xml.sax.helpers.DefaultHandler;\n\n/** Can read log records from streams.\n *\n * @author Jaroslav Tulach\n */\npublic final class LogRecords {\n    private LogRecords() {\n    }\n\n    private static final Logger LOG = Logger.getLogger(LogRecords.class.getName());\n\n    public static void scan(InputStream is, Handler h) throws IOException {\n        PushbackInputStream wrap = new PushbackInputStream(is, 32);\n        byte[] arr = new byte[5];\n        int len = wrap.read(arr);\n        if (len == -1) {\n            return;\n        }\n        wrap.unread(arr, 0, len);\n        if (arr[0] == 0x1f && arr[1] == -117) {\n            wrap = new PushbackInputStream(new GZIPInputStream(wrap), 32);\n            len = wrap.read(arr);\n            if (len == -1) {\n                return;\n            }\n            wrap.unread(arr, 0, len);\n        }\n        \n        if (arr[0] == '<' &&\n            arr[1] == '?' &&\n            arr[2] == 'x' &&\n            arr[3] == 'm' &&\n            arr[4] == 'l'\n        ) {\n            is = wrap;\n        } else {\n            ByteArrayInputStream header = new ByteArrayInputStream(\n    \"<?xml version='1.0' encoding='UTF-8'?><uigestures version='1.0'>\".getBytes()\n            );\n            ByteArrayInputStream footer = new ByteArrayInputStream(\n                \"</uigestures>\".getBytes()\n            );\n            is = new SequenceInputStream(\n                new SequenceInputStream(header, wrap),\n                footer\n            );\n        }\n        \n        SAXParserFactory f = SAXParserFactory.newInstance();\n        f.setValidating(false);\n        SAXParser p;\n        try {\n            try{\n                f.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);\n                f.setFeature(\"http://apache.org/xml/features/continue-after-fatal-error\", true); // NOI18N\n                f.setFeature(\"http://xml.org/sax/features/external-general-entities\", false); // NOI18N\n                f.setFeature(\"http://xml.org/sax/features/external-parameter-entities\", false); // NOI18N\n            }catch (SAXNotRecognizedException snre){\n                LOG.log(Level.INFO, null, snre);\n            }\n            p = f.newSAXParser();\n        } catch (ParserConfigurationException ex) {\n            LOG.log(Level.SEVERE, null, ex);\n            throw (IOException)new IOException(ex.getMessage()).initCause(ex);\n        } catch (SAXException ex) {\n            LOG.log(Level.SEVERE, null, ex);\n            throw (IOException)new IOException(ex.getMessage()).initCause(ex);\n        }\n        \n        Parser parser = new Parser(h);\n        try {\n            p.parse(is, parser);\n        } catch (SAXException ex) {\n            LOG.log(Level.WARNING, null, ex);\n            throw (IOException)new IOException(ex.getMessage()).initCause(ex);\n        } catch (InternalError error){\n            LOG.log(Level.WARNING, \"Input file corruption\", error);\n            throw (IOException)new IOException(error.getMessage()).initCause(error);\n        } catch (IOException ex) {\n            throw ex;\n        } catch (RuntimeException ex) {\n            LOG.log(Level.WARNING, \"Input file corruption\", ex);\n        }\n    }   \n\n    static Level parseLevel(String lev) {\n        return \"USER\".equals(lev) ? Level.SEVERE : Level.parse(lev);\n    }\n    \n    private static final class Parser extends DefaultHandler {\n        private Handler callback;\n        private static enum Elem {\n            UIGESTURES, RECORD, DATE, MILLIS, SEQUENCE, LEVEL, THREAD,\n            MESSAGE, KEY, PARAM, FRAME, CLASS, METHOD, LOGGER, EXCEPTION, LINE,\n            CATALOG, MORE, FILE;\n            \n            public String parse(Map<Elem,String> values) {\n                String v = values.get(this);\n                return v;\n            }\n        }\n        private Map<Elem,String> values = new EnumMap<>(Elem.class);\n        private Elem current;\n        private FakeException currentEx;\n        private Queue<FakeException> exceptions;\n        private List<String> params;\n        private StringBuilder chars = new StringBuilder();\n        private int fatalErrors;\n        \n        Parser(Handler c) {\n            this.callback = c;\n        }\n        \n        \n        public void setDocumentLocator(Locator locator) {\n        }\n\n        public void startDocument() throws SAXException {\n        }\n\n        public void endDocument() throws SAXException {\n            callback.flush();\n        }\n\n        public void startPrefixMapping(String prefix, String uri) throws SAXException {\n        }\n\n        public void endPrefixMapping(String prefix) throws SAXException {\n        }\n\n        public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {\n            if (LOG.isLoggable(Level.FINEST)) {\n                LOG.log(Level.FINEST, \"uri: {0} localName: {1} qName: {2} atts: {3}\", new Object[] { uri, localName, qName, atts });\n            }\n\n            try {\n                current = Elem.valueOf(qName.toUpperCase());\n                if (current == Elem.EXCEPTION) {\n                    currentEx = new FakeException(new EnumMap<>(values));\n                }\n            } catch (IllegalArgumentException ex) {\n                LOG.log(Level.FINE, \"Uknown tag \" + qName, ex);\n                current = null;\n            }\n            chars = new StringBuilder();\n        }\n        \n        public void endElement(String uri, String localName, String qName) throws SAXException {\n            if (current != null) {\n                String v = chars.toString();\n                values.put(current, v);\n                if (current == Elem.PARAM) {\n                    if (params == null) {\n                        params = new ArrayList<>();\n                    }\n                    params.add(v);\n                    if (params.size() > 1500) {\n                        LOG.severe(\"Too long params when reading a record. Deleting few. Msg: \" + Elem.MESSAGE.parse(values)); // NOI18N\n                        for (String p : params) {\n                            LOG.fine(p);\n                        }\n                        params.clear();\n                    }\n                }\n            }\n            current = null;\n            chars = new StringBuilder();\n            \n            if (currentEx != null && currentEx.values != null) {\n                if (\"frame\".equals(qName)) { // NOI18N\n                    String line = Elem.LINE.parse(values);\n                    StackTraceElement elem = new StackTraceElement(\n                            Elem.CLASS.parse(values),\n                            Elem.METHOD.parse(values),\n                            Elem.FILE.parse(values),\n                            line == null ? -1 : Integer.parseInt(line)\n                            );\n                    currentEx.trace.add(elem);\n                    values.remove(Elem.CLASS);\n                    values.remove(Elem.METHOD);\n                    values.remove(Elem.LINE);\n                }\n                if (\"exception\".equals(qName)) {\n                    currentEx.message = values.get(Elem.MESSAGE);\n                    String more = values.get(Elem.MORE);\n                    if (more != null) currentEx.more = Integer.parseInt(more);\n                    if (exceptions == null){\n                        exceptions = new ArrayDeque<>();\n                    }\n                    exceptions.add(currentEx);\n                    values = currentEx.values;\n                    currentEx = null;\n                }\n                return;\n            }\n            \n            if (\"record\".equals(qName)) { // NOI18N\n                String millis = Elem.MILLIS.parse(values);\n                String seq = Elem.SEQUENCE.parse(values);\n                String lev = Elem.LEVEL.parse(values);\n                String thread = Elem.THREAD.parse(values);\n                String msg = Elem.MESSAGE.parse(values);\n                String key = Elem.KEY.parse(values);\n                String catalog = Elem.CATALOG.parse(values);\n                \n                if (lev != null) {\n                    LogRecord r = new LogRecord(parseLevel(lev), key != null && catalog != null ? key : msg);\n                    try {\n                        r.setThreadID(parseInt(thread));\n                    } catch (NumberFormatException ex) {\n                        LOG.log(Level.WARNING, ex.getMessage(), ex);\n                    }\n                    r.setSequenceNumber(parseLong(seq));\n                    r.setMillis(parseLong(millis));\n                    r.setResourceBundleName(key);\n                    if (catalog != null && key != null) {\n                        r.setResourceBundleName(catalog);\n                        if (!\"<null>\".equals(catalog)) { // NOI18N\n                            try {\n                                ResourceBundle b = NbBundle.getBundle(catalog);\n                                b.getObject(key);\n                                // ok, the key is there\n                                r.setResourceBundle(b);\n                            } catch (MissingResourceException e) {\n                                LOG.log(Level.CONFIG, \"Cannot find resource bundle {0} for key {1}\", new Object[] { catalog, key });\n                                r.setResourceBundle(new FakeBundle(key, msg));\n                            }\n                        } else {\n                            LOG.log(Level.CONFIG, \"Cannot find resource bundle <null> for key {0}\", key);\n                        }\n                    }\n                    if (params != null) {\n                        r.setParameters(params.toArray());\n                    }\n                    if (exceptions != null) {\n                        r.setThrown(createThrown(null));\n                        // exceptions = null;  should be empty after poll\n                    }\n\n                    callback.publish(r);\n                }\n\n                currentEx = null;\n                params = null;\n                values.clear();\n            }\n            \n        }\n\n        private long parseLong(String str){\n            if (str == null){\n                return 0l;\n            }\n            try{\n                return Long.parseLong(str);\n            }catch(NumberFormatException exc){\n                LOG.log(Level.INFO, exc.getMessage(), exc);\n                return 0l;\n            }\n        }\n\n        private int parseInt(String str){\n            if (str == null){\n                return 0;\n            }\n            try{\n                return Integer.parseInt(str);\n            }catch(NumberFormatException exc){\n                LOG.log(Level.INFO, exc.getMessage(), exc);\n                return 0;\n            }\n        }\n        /** set first element of exceptions as a result of this calling and\n         * recursively fill it's cause\n         */\n        private FakeException createThrown(FakeException last){\n            if (exceptions.isEmpty()) {\n                return null;\n            }\n            FakeException result = exceptions.poll();\n            if ((result!= null) && (result.getMore()!= 0)){\n                assert last != null : \"IF MORE IS NOT 0, LAST MUST BE SET NOT NULL\";\n                StackTraceElement[] trace = last.getStackTrace();\n                for (int i = trace.length - result.getMore(); i < trace.length; i++){\n                    result.trace.add(trace[i]);// fill the rest of stacktrace\n                }\n            }\n            FakeException cause = createThrown(result);\n            result.initCause(cause);\n            return result;\n        }\n        \n        public void characters(char[] ch, int start, int length) throws SAXException {\n            chars.append(ch, start, length);\n        }\n\n        public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {\n        }\n\n        public void processingInstruction(String target, String data) throws SAXException {\n        }\n\n        public void skippedEntity(String name) throws SAXException {\n        }\n\n        public void fatalError(SAXParseException e) throws SAXException {\n            if (fatalErrors++ > 1000) {\n                throw e;\n            }\n        }\n        \n    }\n    \n    private static final class FakeBundle extends ResourceBundle {\n        private String key;\n        private String value;\n         \n        FakeBundle(String key, String value) {\n            this.key = key;\n            this.value = value;\n        }\n\n    \n        protected Object handleGetObject(String arg0) {\n            if (key.equals(arg0)) {\n                return value;\n            } else {\n                return null;\n            }\n        }\n\n        public Enumeration<String> getKeys() {\n            return Collections.enumeration(Collections.singleton(key));\n        }\n    } // end of FakeBundle\n    \n    private static final class FakeException extends Exception {\n        final List<StackTraceElement> trace = new ArrayList<>();\n        Map<Parser.Elem,String> values;\n        String message;\n        int more;\n        \n        FakeException(Map<Parser.Elem,String> values) {\n            this.values = values;\n            more = 0;\n        }\n       \n        public StackTraceElement[] getStackTrace() {\n            return trace.toArray(new StackTraceElement[0]);\n        }\n\n        public String getMessage() {\n            return message;\n        }\n        \n        public int getMore(){\n            return more;\n        }\n        \n        /**\n         * org.netbeans.lib.uihandler.LogRecords$FakeException: NullPointerException ...\n         * is not the best message - it's better to suppress FakeException\n         */\n        public String toString(){\n            return message;\n        }\n        \n    } // end of FakeException\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.snaptracer/src/org/graalvm/visualvm/lib/profiler/snaptracer/package-info.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/**\n * Framework and graphical user interface for visual tracing of applications or\n * other data sources using the Tracer probes.\n * <p>\n * The entrypoint is TracerSupport where custom TracerPackageProviders providing\n * TracerPackages need to be registered. TracerPackages provide TracerProbes\n * representing the monitored targets like JVM metrics or MBean values.\n * <p>\n * <b>Note:</b> the API is not stable yet and may be changed in an incompatible\n * way in the following releases.\n */\npackage org.graalvm.visualvm.lib.profiler.snaptracer;\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.utilities/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project basedir=\".\" default=\"netbeans\" name=\"profiler.utilities\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.lib.profiler.utilities</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.utilities/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.lib.profiler.utilities/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/lib/profiler/utilities/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.utilities/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.lib.profiler.utilities-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.utilities/nbproject/genfiles.properties",
    "content": "# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=28fc9e45\nnbproject/build-impl.xml.script.CRC32=517ef306\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.utilities/nbproject/project.properties",
    "content": "# Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\nis.autoload=true\njavac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\n\ntest.config.stableBTD.includes=**/*Test.class\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.utilities/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\nCopyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.\nDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\nThis code is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License version 2 only, as\npublished by the Free Software Foundation.  Oracle designates this\nparticular file as subject to the \"Classpath\" exception as provided\nby Oracle in the LICENSE file that accompanied this code.\n\nThis code is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\nversion 2 for more details (a copy is included in the LICENSE file that\naccompanied this code).\n\nYou should have received a copy of the GNU General Public License version\n2 along with this work; if not, write to the Free Software Foundation,\nInc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\nPlease contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\nor visit www.oracle.com if you need additional information or have any\nquestions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.lib.profiler.utilities</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.3</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.profiler</friend>\n                <friend>org.graalvm.visualvm.lib.profiler</friend>\n                <package>org.graalvm.visualvm.lib.profiler.utilities</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.utilities/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/../..\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.utilities/src/org/graalvm/visualvm/lib/profiler/utilities/Bundle.properties",
    "content": "# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Name=Java Profiler (Utilities)\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.utilities/src/org/graalvm/visualvm/lib/profiler/utilities/Delegate.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.utilities;\n\n/**\n * A utility class for simple delegation\n * @author Jaroslav Bachorik\n */\nabstract public class Delegate<T> {\n    volatile private T delegate;\n\n    public void setDelegate(T delegate) {\n        this.delegate = delegate;\n    }\n\n    protected T getDelegate() {\n        return delegate;\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.utilities/src/org/graalvm/visualvm/lib/profiler/utilities/OutputParameter.java",
    "content": "/*\n * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.utilities;\n\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic class OutputParameter<T> {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    T value;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /** Creates a new instance of OutputParameter */\n    public OutputParameter(T initialValue) {\n        value = initialValue;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public boolean isSet() {\n        return value != null;\n    }\n\n    public void setValue(T value) {\n        this.value = value;\n    }\n\n    public T getValue() {\n        return value;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        return value.equals(obj);\n    }\n\n    @Override\n    public int hashCode() {\n        return value.hashCode();\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.utilities/src/org/graalvm/visualvm/lib/profiler/utilities/ProfilerUtils.java",
    "content": "/*\n * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.lib.profiler.utilities;\n\nimport org.openide.ErrorManager;\nimport org.openide.util.RequestProcessor;\n\n/**\n * Miscellaneous utilities\n *\n * @author Jiri Sedlacek\n */\npublic final class ProfilerUtils {\n\n    private static RequestProcessor profilerRequestProcessor;\n    private static ErrorManager profilerErrorManager;\n\n\n    public static synchronized RequestProcessor getProfilerRequestProcessor() {\n        if (profilerRequestProcessor == null)\n            profilerRequestProcessor = new RequestProcessor(\"Profiler Request Processor\", 1); // NOI18N\n        return profilerRequestProcessor;\n    }\n\n    public static synchronized ErrorManager getProfilerErrorManager() {\n        if (profilerErrorManager == null)\n            profilerErrorManager = ErrorManager.getDefault().getInstance(\"org.graalvm.visualvm.lib.profiler\"); // NOI18N\n        return profilerErrorManager;\n    }\n\n    public static void runInProfilerRequestProcessor(Runnable r) {\n        getProfilerRequestProcessor().post(r);\n    }\n\n    public static void runInProfilerRequestProcessor(Runnable r, int delay) {\n        getProfilerRequestProcessor().post(r, delay);\n    }\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.utilities/src/org/graalvm/visualvm/lib/profiler/utilities/Visitable.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.utilities;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface Visitable<T> {\n    <R, P> R accept(Visitor<Visitable<T>, R, P> visitor, P parameter);\n    T getValue();\n}\n"
  },
  {
    "path": "visualvm/libs.profiler/profiler.utilities/src/org/graalvm/visualvm/lib/profiler/utilities/Visitor.java",
    "content": "/*\n * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.lib.profiler.utilities;\n\n/**\n *\n * @author Jaroslav Bachorik\n */\npublic interface Visitor<V extends Visitable, R, P> {\n    R visit(V visitable, P parameter);\n}\n"
  },
  {
    "path": "visualvm/maven-repo.sh",
    "content": "export MAVEN_CENTRAL_REPO_URL=https://repo1.maven.org/maven2/\nexport MAVEN_NEXUS_LOCAL_DIR=/tmp/visualvm-nexus\nexport MAVEN_REPO=/tmp/maven-visualvm\nexport MAVEN_REPO_URL=file://$MAVEN_REPO\nexport MAVEN_VERSION=RELEASE139\n\n\n/Users/thurka/Projects/Source/more-crippled-netbeans/main/nbbuild/netbeans/java/maven/bin/mvn \\\n  -DrepositoryUrl=$MAVEN_CENTRAL_REPO_URL \\\n  -DdeployUrl=$MAVEN_REPO_URL \\\n  -DforcedVersion=$MAVEN_VERSION \\\n  -DnetbeansInstallDirectory=/Users/thurka/Projects/Source/visualvm.src/visualvm/dist/visualvm \\\n  -DnetbeansNbmDirectory=/Users/thurka/Projects/Source/netbeans-releases/nbbuild/nbms \\\n  -DnexusIndexDirectory=$MAVEN_NEXUS_LOCAL_DIR \\\n  -DskipInstall=true \\\n  -DgroupIdPrefix=org.graalvm.visualvm \\\n  org.codehaus.mojo:nb-repository-plugin:1.2:download org.codehaus.mojo:nb-repository-plugin:1.2:populate\n"
  },
  {
    "path": "visualvm/nashorn.jdk15/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.nashorn.jdk15\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.nashorn.jdk15.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n    <target name=\"download-all-extbins\" unless=\"ext.binaries.downloaded\" depends=\"init\">\n      <echo>Downloading external binaries (external/ directory)...</echo>\n      <property name=\"binaries.cache\" location=\"${user.home}/.hgexternalcache\"/>\n      <property name=\"binaries.server\" value=\"https://netbeans.osuosl.org/binaries/\"/>\n      <downloadbinaries cache=\"${binaries.cache}\" server=\"${binaries.server}\" >\n          <manifest dir=\".\">\n              <include name=\"external/binaries-list\"/>\n          </manifest>\n      </downloadbinaries>\n      <property name=\"ext.binaries.downloaded\" value=\"true\"/>\n    </target>\n\n    <target name=\"-pre-compile\" depends=\"download-all-extbins\">\n    </target>\n\n    <target name=\"-pre-release\" depends=\"compile\">\n        <taskdef name=\"releasefilescopy\" classname=\"org.netbeans.nbbuild.extlibs.ReleaseFilesCopy\" classpath=\"${harness.dir}/tasks.jar\"/>\n        <releasefilescopy cluster=\"${cluster}\"/>\n    </target>\n\n    <target name=\"-release.files\" depends=\"projectized-common.-release.files\">\n        <taskdef name=\"releasefilesextra\" classname=\"org.netbeans.nbbuild.extlibs.ReleaseFilesExtra\" classpath=\"${harness.dir}/tasks.jar\"/>\n        <releasefilesextra property=\"release.files.extra\"/>\n    </target>\n\n    <target name=\"-pre-nbm\" depends=\"compile\">\n      <property name=\"license.file.override\" location=\"${build.dir}/license\"/>\n      <property name=\"extra.license.files\" value=\"\"/>\n      <taskdef name=\"releasefileslicense\" classname=\"org.netbeans.nbbuild.extlibs.ReleaseFilesLicense\" classpath=\"${harness.dir}/tasks.jar\"/>\n      <releasefileslicense license=\"${license.file.override}\" standardlicense=\"${license.file}\" extralicensefiles=\"${extra.license.files}\"/>\n    </target>\n</project>\n"
  },
  {
    "path": "visualvm/nashorn.jdk15/external/asm-util-9.7-license.txt",
    "content": "Name: OW2 ASM\nVersion: 9.7\nFiles: asm-util-9.7.jar\nLicense: BSD-INRIA\nOrigin: OW2 Consortium\nURL: https://repository.ow2.org/nexus/content/repositories/releases/org/ow2/asm/\nDescription: Bytecode manipulation library\n\n*******************************************************************************\n* ASM: a very small and fast Java bytecode manipulation framework\n* Copyright (c) 2000-2011 INRIA, France Telecom\n* All rights reserved.\n*\n* Redistribution and use in source and binary forms, with or without\n* modification, are permitted provided that the following conditions\n* are met:\n* 1. Redistributions of source code must retain the above copyright\n*   notice, this list of conditions and the following disclaimer.\n* 2. Redistributions in binary form must reproduce the above copyright\n*   notice, this list of conditions and the following disclaimer in the\n*   documentation and/or other materials provided with the distribution.\n* 3. Neither the name of the copyright holders nor the names of its\n*   contributors may be used to endorse or promote products derived from\n*   this software without specific prior written permission.\n*\n* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n* THE POSSIBILITY OF SUCH DAMAGE.\n*******************************************************************************\n"
  },
  {
    "path": "visualvm/nashorn.jdk15/external/binaries-list",
    "content": "C84C9A8CE807E655568E331B522AB091586CCBB6 org.openjdk.nashorn:nashorn-core:15.6\nC0655519F24D92AF2202CB681CD7C1569DF6EAD6 org.ow2.asm:asm-util:9.7\n"
  },
  {
    "path": "visualvm/nashorn.jdk15/external/nashorn-core-15.6-license.txt",
    "content": "Name: Nashorn\nDescription: Nashorn is an Open Source JavaScript (ECMAScript 5.1 and some 6 features) engine for the JVM.\nLicense: GPL v2 with the Classpath exception\nOrigin: https://github.com/openjdk/nashorn\nVersion: 15.6\nFiles: nashorn-core-15.6.jar\n\nThe GNU General Public License (GPL)\n\nVersion 2, June 1991\n\nCopyright (C) 1989, 1991 Free Software Foundation, Inc.\n51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nEveryone is permitted to copy and distribute verbatim copies of this license\ndocument, but changing it is not allowed.\n\nPreamble\n\nThe licenses for most software are designed to take away your freedom to share\nand change it.  By contrast, the GNU General Public License is intended to\nguarantee your freedom to share and change free software--to make sure the\nsoftware is free for all its users.  This General Public License applies to\nmost of the Free Software Foundation's software and to any other program whose\nauthors commit to using it.  (Some other Free Software Foundation software is\ncovered by the GNU Library General Public License instead.) You can apply it to\nyour programs, too.\n\nWhen we speak of free software, we are referring to freedom, not price.  Our\nGeneral Public Licenses are designed to make sure that you have the freedom to\ndistribute copies of free software (and charge for this service if you wish),\nthat you receive source code or can get it if you want it, that you can change\nthe software or use pieces of it in new free programs; and that you know you\ncan do these things.\n\nTo protect your rights, we need to make restrictions that forbid anyone to deny\nyou these rights or to ask you to surrender the rights.  These restrictions\ntranslate to certain responsibilities for you if you distribute copies of the\nsoftware, or if you modify it.\n\nFor example, if you distribute copies of such a program, whether gratis or for\na fee, you must give the recipients all the rights that you have.  You must\nmake sure that they, too, receive or can get the source code.  And you must\nshow them these terms so they know their rights.\n\nWe protect your rights with two steps: (1) copyright the software, and (2)\noffer you this license which gives you legal permission to copy, distribute\nand/or modify the software.\n\nAlso, for each author's protection and ours, we want to make certain that\neveryone understands that there is no warranty for this free software.  If the\nsoftware is modified by someone else and passed on, we want its recipients to\nknow that what they have is not the original, so that any problems introduced\nby others will not reflect on the original authors' reputations.\n\nFinally, any free program is threatened constantly by software patents.  We\nwish to avoid the danger that redistributors of a free program will\nindividually obtain patent licenses, in effect making the program proprietary.\nTo prevent this, we have made it clear that any patent must be licensed for\neveryone's free use or not licensed at all.\n\nThe precise terms and conditions for copying, distribution and modification\nfollow.\n\nTERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n0. This License applies to any program or other work which contains a notice\nplaced by the copyright holder saying it may be distributed under the terms of\nthis General Public License.  The \"Program\", below, refers to any such program\nor work, and a \"work based on the Program\" means either the Program or any\nderivative work under copyright law: that is to say, a work containing the\nProgram or a portion of it, either verbatim or with modifications and/or\ntranslated into another language.  (Hereinafter, translation is included\nwithout limitation in the term \"modification\".) Each licensee is addressed as\n\"you\".\n\nActivities other than copying, distribution and modification are not covered by\nthis License; they are outside its scope.  The act of running the Program is\nnot restricted, and the output from the Program is covered only if its contents\nconstitute a work based on the Program (independent of having been made by\nrunning the Program).  Whether that is true depends on what the Program does.\n\n1. You may copy and distribute verbatim copies of the Program's source code as\nyou receive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice and\ndisclaimer of warranty; keep intact all the notices that refer to this License\nand to the absence of any warranty; and give any other recipients of the\nProgram a copy of this License along with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and you may\nat your option offer warranty protection in exchange for a fee.\n\n2. You may modify your copy or copies of the Program or any portion of it, thus\nforming a work based on the Program, and copy and distribute such modifications\nor work under the terms of Section 1 above, provided that you also meet all of\nthese conditions:\n\n    a) You must cause the modified files to carry prominent notices stating\n    that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in whole or\n    in part contains or is derived from the Program or any part thereof, to be\n    licensed as a whole at no charge to all third parties under the terms of\n    this License.\n\n    c) If the modified program normally reads commands interactively when run,\n    you must cause it, when started running for such interactive use in the\n    most ordinary way, to print or display an announcement including an\n    appropriate copyright notice and a notice that there is no warranty (or\n    else, saying that you provide a warranty) and that users may redistribute\n    the program under these conditions, and telling the user how to view a copy\n    of this License.  (Exception: if the Program itself is interactive but does\n    not normally print such an announcement, your work based on the Program is\n    not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If identifiable\nsections of that work are not derived from the Program, and can be reasonably\nconsidered independent and separate works in themselves, then this License, and\nits terms, do not apply to those sections when you distribute them as separate\nworks.  But when you distribute the same sections as part of a whole which is a\nwork based on the Program, the distribution of the whole must be on the terms\nof this License, whose permissions for other licensees extend to the entire\nwhole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest your\nrights to work written entirely by you; rather, the intent is to exercise the\nright to control the distribution of derivative or collective works based on\nthe Program.\n\nIn addition, mere aggregation of another work not based on the Program with the\nProgram (or with a work based on the Program) on a volume of a storage or\ndistribution medium does not bring the other work under the scope of this\nLicense.\n\n3. You may copy and distribute the Program (or a work based on it, under\nSection 2) in object code or executable form under the terms of Sections 1 and\n2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable source\n    code, which must be distributed under the terms of Sections 1 and 2 above\n    on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three years, to\n    give any third party, for a charge no more than your cost of physically\n    performing source distribution, a complete machine-readable copy of the\n    corresponding source code, to be distributed under the terms of Sections 1\n    and 2 above on a medium customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer to\n    distribute corresponding source code.  (This alternative is allowed only\n    for noncommercial distribution and only if you received the program in\n    object code or executable form with such an offer, in accord with\n    Subsection b above.)\n\nThe source code for a work means the preferred form of the work for making\nmodifications to it.  For an executable work, complete source code means all\nthe source code for all modules it contains, plus any associated interface\ndefinition files, plus the scripts used to control compilation and installation\nof the executable.  However, as a special exception, the source code\ndistributed need not include anything that is normally distributed (in either\nsource or binary form) with the major components (compiler, kernel, and so on)\nof the operating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering access to copy\nfrom a designated place, then offering equivalent access to copy the source\ncode from the same place counts as distribution of the source code, even though\nthird parties are not compelled to copy the source along with the object code.\n\n4. You may not copy, modify, sublicense, or distribute the Program except as\nexpressly provided under this License.  Any attempt otherwise to copy, modify,\nsublicense or distribute the Program is void, and will automatically terminate\nyour rights under this License.  However, parties who have received copies, or\nrights, from you under this License will not have their licenses terminated so\nlong as such parties remain in full compliance.\n\n5. You are not required to accept this License, since you have not signed it.\nHowever, nothing else grants you permission to modify or distribute the Program\nor its derivative works.  These actions are prohibited by law if you do not\naccept this License.  Therefore, by modifying or distributing the Program (or\nany work based on the Program), you indicate your acceptance of this License to\ndo so, and all its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n6. Each time you redistribute the Program (or any work based on the Program),\nthe recipient automatically receives a license from the original licensor to\ncopy, distribute or modify the Program subject to these terms and conditions.\nYou may not impose any further restrictions on the recipients' exercise of the\nrights granted herein.  You are not responsible for enforcing compliance by\nthird parties to this License.\n\n7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues), conditions\nare imposed on you (whether by court order, agreement or otherwise) that\ncontradict the conditions of this License, they do not excuse you from the\nconditions of this License.  If you cannot distribute so as to satisfy\nsimultaneously your obligations under this License and any other pertinent\nobligations, then as a consequence you may not distribute the Program at all.\nFor example, if a patent license would not permit royalty-free redistribution\nof the Program by all those who receive copies directly or indirectly through\nyou, then the only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under any\nparticular circumstance, the balance of the section is intended to apply and\nthe section as a whole is intended to apply in other circumstances.\n\nIt is not the purpose of this section to induce you to infringe any patents or\nother property right claims or to contest validity of any such claims; this\nsection has the sole purpose of protecting the integrity of the free software\ndistribution system, which is implemented by public license practices.  Many\npeople have made generous contributions to the wide range of software\ndistributed through that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing to\ndistribute software through any other system and a licensee cannot impose that\nchoice.\n\nThis section is intended to make thoroughly clear what is believed to be a\nconsequence of the rest of this License.\n\n8. If the distribution and/or use of the Program is restricted in certain\ncountries either by patents or by copyrighted interfaces, the original\ncopyright holder who places the Program under this License may add an explicit\ngeographical distribution limitation excluding those countries, so that\ndistribution is permitted only in or among countries not thus excluded.  In\nsuch case, this License incorporates the limitation as if written in the body\nof this License.\n\n9. The Free Software Foundation may publish revised and/or new versions of the\nGeneral Public License from time to time.  Such new versions will be similar in\nspirit to the present version, but may differ in detail to address new problems\nor concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any later\nversion\", you have the option of following the terms and conditions either of\nthat version or of any later version published by the Free Software Foundation.\nIf the Program does not specify a version number of this License, you may\nchoose any version ever published by the Free Software Foundation.\n\n10. If you wish to incorporate parts of the Program into other free programs\nwhose distribution conditions are different, write to the author to ask for\npermission.  For software which is copyrighted by the Free Software Foundation,\nwrite to the Free Software Foundation; we sometimes make exceptions for this.\nOur decision will be guided by the two goals of preserving the free status of\nall derivatives of our free software and of promoting the sharing and reuse of\nsoftware generally.\n\nNO WARRANTY\n\n11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR\nTHE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE\nSTATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE\nPROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\nFITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND\nPERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE,\nYOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL\nANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE\nPROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR\nINABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA\nBEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\nFAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER\nOR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\nEND OF TERMS AND CONDITIONS\n\nHow to Apply These Terms to Your New Programs\n\nIf you develop a new program, and you want it to be of the greatest possible\nuse to the public, the best way to achieve this is to make it free software\nwhich everyone can redistribute and change under these terms.\n\nTo do so, attach the following notices to the program.  It is safest to attach\nthem to the start of each source file to most effectively convey the exclusion\nof warranty; and each file should have at least the \"copyright\" line and a\npointer to where the full notice is found.\n\n    One line to give the program's name and a brief idea of what it does.\n\n    Copyright (C) <year> <name of author>\n\n    This program is free software; you can redistribute it and/or modify it\n    under the terms of the GNU General Public License as published by the Free\n    Software Foundation; either version 2 of the License, or (at your option)\n    any later version.\n\n    This program is distributed in the hope that it will be useful, but WITHOUT\n    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n    more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this when it\nstarts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author Gnomovision comes\n    with ABSOLUTELY NO WARRANTY; for details type 'show w'.  This is free\n    software, and you are welcome to redistribute it under certain conditions;\n    type 'show c' for details.\n\nThe hypothetical commands 'show w' and 'show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may be\ncalled something other than 'show w' and 'show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.  Here\nis a sample; alter the names:\n\n    Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n    'Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n    signature of Ty Coon, 1 April 1989\n\n    Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Library General Public\nLicense instead of this License.\n\n\n\"CLASSPATH\" EXCEPTION TO THE GPL\n\nCertain source files distributed by Oracle America and/or its affiliates are\nsubject to the following clarification and special exception to the GPL, but\nonly where Oracle has expressly included in the particular source file's header\nthe words \"Oracle designates this particular file as subject to the \"Classpath\"\nexception as provided by Oracle in the LICENSE file that accompanied this code.\"\n\n    Linking this library statically or dynamically with other modules is making\n    a combined work based on this library.  Thus, the terms and conditions of\n    the GNU General Public License cover the whole combination.\n\n    As a special exception, the copyright holders of this library give you\n    permission to link this library with independent modules to produce an\n    executable, regardless of the license terms of these independent modules,\n    and to copy and distribute the resulting executable under terms of your\n    choice, provided that you also meet, for each linked independent module,\n    the terms and conditions of the license of that module.  An independent\n    module is a module which is not derived from or based on this library.  If\n    you modify this library, you may extend this exception to your version of\n    the library, but you are not obligated to do so.  If you do not wish to do\n    so, delete this exception statement from your version."
  },
  {
    "path": "visualvm/nashorn.jdk15/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module-Java-Dependencies: Java > 15\nOpenIDE-Module: org.graalvm.visualvm.nashorn.jdk15\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/nashorn/jdk15/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.2\n\n"
  },
  {
    "path": "visualvm/nashorn.jdk15/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.nashorn.jdk15-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/nashorn.jdk15/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=520d0fe2\nbuild.xml.script.CRC32=f245468f\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=78de761a\nnbproject/build-impl.xml.script.CRC32=e26352d3\nnbproject/build-impl.xml.stylesheet.CRC32=68e521fc@2.73\n"
  },
  {
    "path": "visualvm/nashorn.jdk15/nbproject/project.properties",
    "content": "file.reference.nashorn-core-15.6.jar=external/nashorn-core-15.6.jar\nfile.reference.asm-util-9.7.jar=external/asm-util-9.7.jar\nis.eager=true\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Tomas Hurka\nnbm.needs.restart=true\nrelease.external/nashorn-core-15.6.jar=modules/ext/nashorn-core-15.6.jar\nrelease.external/asm-util-9.7.jar=modules/ext/asm-util-9.7.jar\njavac.source=1.15\njavac.compilerargs=-Xlint -Xlint:-serial\n"
  },
  {
    "path": "visualvm/nashorn.jdk15/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.nashorn.jdk15</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.netbeans.libs.asm</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>5.10</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n            <class-path-extension>\n                <runtime-relative-path>ext/nashorn-core-15.6.jar</runtime-relative-path>\n                <binary-origin>external/nashorn-core-15.6.jar</binary-origin>\n            </class-path-extension>\n            <class-path-extension>\n                <runtime-relative-path>ext/asm-util-9.7.jar</runtime-relative-path>\n                <binary-origin>external/asm-util-9.7.jar</binary-origin>\n            </class-path-extension>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/nashorn.jdk15/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/nashorn.jdk15/src/org/graalvm/visualvm/nashorn/jdk15/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Libraries\nOpenIDE-Module-Long-Description=\\\n    Nashorn is an Open Source JavaScript (ECMAScript 5.1 and some 6 features) engine for the JVM.\nOpenIDE-Module-Name=Nashorn for JDK 15+\nOpenIDE-Module-Short-Description=Nashorn is JavaScript engine for the JVM.\n"
  },
  {
    "path": "visualvm/nashorn.jdk15/src/org/openjdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java",
    "content": "/*\n * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.openjdk.nashorn.internal.runtime.linker;\n\nimport static org.openjdk.nashorn.internal.lookup.Lookup.MH;\n\nimport java.lang.invoke.MethodHandle;\nimport java.lang.invoke.MethodHandles;\nimport java.lang.invoke.MethodHandles.Lookup;\nimport java.lang.invoke.MethodType;\nimport java.lang.invoke.VarHandle;\nimport java.lang.reflect.Modifier;\nimport java.security.AccessControlContext;\nimport java.security.AccessController;\nimport java.security.CodeSigner;\nimport java.security.CodeSource;\nimport java.security.Permissions;\nimport java.security.PrivilegedAction;\nimport java.security.ProtectionDomain;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.ConcurrentHashMap;\nimport jdk.dynalink.CallSiteDescriptor;\nimport jdk.dynalink.StandardOperation;\nimport jdk.dynalink.beans.StaticClass;\nimport jdk.dynalink.linker.support.SimpleLinkRequest;\nimport org.openjdk.nashorn.internal.runtime.Context;\nimport org.openjdk.nashorn.internal.runtime.ECMAErrors;\nimport org.openjdk.nashorn.internal.runtime.ECMAException;\nimport org.openjdk.nashorn.internal.runtime.ScriptFunction;\nimport org.openjdk.nashorn.internal.runtime.ScriptObject;\n\n/**\n * A factory class that generates adapter classes. Adapter classes allow\n * implementation of Java interfaces and extending of Java classes from\n * JavaScript. For every combination of a superclass to extend and interfaces to\n * implement (collectively: \"original types\"), exactly one adapter class is\n * generated that extends the specified superclass and implements the specified\n * interfaces. (But see the discussion of class-based overrides for exceptions.)\n * <p>\n * The adapter class is generated in a new secure class loader that inherits\n * Nashorn's protection domain, and has either one of the original types' class\n * loader or the Nashorn's class loader as its parent - the parent class loader\n * is chosen so that all the original types and the Nashorn core classes are\n * visible from it (as the adapter will have constant pool references to\n * ScriptObject and ScriptFunction classes). In case none of the candidate class\n * loaders has visibility of all the required types, an error is thrown. The\n * class uses {@link JavaAdapterBytecodeGenerator} to generate the adapter class\n * itself; see its documentation for details about the generated class.\n * <p>\n * You normally don't use this class directly, but rather either create adapters\n * from script using {@link org.openjdk.nashorn.internal.objects.NativeJava#extend(Object, Object...)},\n * using the {@code new} operator on abstract classes and interfaces (see\n * {@link org.openjdk.nashorn.internal.objects.NativeJava#type(Object, Object)}), or\n * implicitly when passing script functions to Java methods expecting SAM types.\n */\n\npublic final class JavaAdapterFactory {\n    private static final ProtectionDomain MINIMAL_PERMISSION_DOMAIN = createMinimalPermissionDomain();\n\n    // context with permissions needs for AdapterInfo creation\n    private static final AccessControlContext CREATE_ADAPTER_INFO_ACC_CTXT =\n        ClassAndLoader.createPermAccCtxt(\"createClassLoader\", \"getClassLoader\",\n            \"accessDeclaredMembers\", \"accessClassInPackage.org.openjdk.nashorn.internal.runtime\");\n\n    /**\n     * A mapping from an original Class object to AdapterInfo representing the adapter for the class it represents.\n     */\n    private static final ClassValue<Map<List<Class<?>>, AdapterInfo>> ADAPTER_INFO_MAPS = new ClassValue<>() {\n        @Override\n        protected Map<List<Class<?>>, AdapterInfo> computeValue(final Class<?> type) {\n            return new ConcurrentHashMap<>();\n        }\n    };\n\n    private static final ClassValue<Boolean> AUTO_CONVERTIBLE_FROM_FUNCTION = new ClassValue<>() {\n        @Override\n        protected Boolean computeValue(final Class<?> type) {\n            try {\n                return getAdapterInfo(new Class<?>[] { type }).autoConvertibleFromFunction;\n            } catch (Exception e) {\n                return false;\n            }\n        }\n    };\n\n    /**\n     * Returns an adapter class for the specified original types. The adapter\n     * class extends/implements the original class/interfaces.\n     *\n     * @param types the original types. The caller must pass at least one Java\n     *        type representing either a public interface or a non-final public\n     *        class with at least one public or protected constructor. If more\n     *        than one type is specified, at most one can be a class and the\n     *        rest have to be interfaces. The class can be in any position in\n     *        the array. Invoking the method twice with exactly the same types\n     *        in the same order will return the same adapter class, any\n     *        reordering of types or even addition or removal of redundant types\n     *        (i.e., interfaces that other types in the list already\n     *        implement/extend, or {@code java.lang.Object} in a list of types\n     *        consisting purely of interfaces) will result in a different\n     *        adapter class, even though those adapter classes are functionally\n     *        identical; we deliberately don't want to incur the additional\n     *        processing cost of canonicalizing type lists.\n     * @param classOverrides a JavaScript object with functions serving as the\n     *        class-level overrides and implementations. These overrides are\n     *        defined for all instances of the class, and can be further\n     *        overridden on a per-instance basis by passing additional objects\n     *        in the constructor.\n     * @param lookup the lookup object identifying the caller class. The\n     *        generated adapter class will have the protection domain of the\n     *        caller class iff the lookup object is full-strength, otherwise it\n     *        will be completely unprivileged.\n     *\n     * @return an adapter class. See this class' documentation for details on\n     *         the generated adapter class.\n     *\n     * @throws ECMAException with a TypeError if the adapter class can not be\n     *         generated because the original class is final, non-public, or has\n     *         no public or protected constructors.\n     */\n    public static StaticClass getAdapterClassFor(final Class<?>[] types, final ScriptObject classOverrides, final MethodHandles.Lookup lookup) {\n        return getAdapterClassFor(types, classOverrides, getProtectionDomain(lookup));\n    }\n\n    private static StaticClass getAdapterClassFor(final Class<?>[] types, final ScriptObject classOverrides, final ProtectionDomain protectionDomain) {\n        assert types != null && types.length > 0;\n        final SecurityManager sm = System.getSecurityManager();\n        if (sm != null) {\n            for (final Class<?> type : types) {\n                // check for restricted package access\n                Context.checkPackageAccess(type);\n                // check for classes, interfaces in reflection\n                ReflectionCheckLinker.checkReflectionAccess(type, true);\n            }\n        }\n        return getAdapterInfo(types).getAdapterClass(classOverrides, protectionDomain);\n    }\n\n    private static ProtectionDomain getProtectionDomain(final MethodHandles.Lookup lookup) {\n        if((lookup.lookupModes() & Lookup.PRIVATE) == 0) {\n            return MINIMAL_PERMISSION_DOMAIN;\n        }\n        return getProtectionDomain(lookup.lookupClass());\n    }\n\n    private static ProtectionDomain getProtectionDomain(final Class<?> clazz) {\n        return AccessController.doPrivileged((PrivilegedAction<ProtectionDomain>) clazz::getProtectionDomain);\n    }\n\n    /**\n     * Returns a method handle representing a constructor that takes a single\n     * argument of the source type (which, really, should be one of {@link ScriptObject},\n     * {@link ScriptFunction}, or {@link Object}, and returns an instance of the\n     * adapter for the target type. Used to implement the function autoconverters\n     * as well as the Nashorn JSR-223 script engine's {@code getInterface()}\n     * method.\n     *\n     * @param sourceType the source type; should be either {@link ScriptObject},\n     *        {@link ScriptFunction}, or {@link Object}. In case of {@code Object},\n     *        it will return a method handle that dispatches to either the script\n     *        object or function constructor at invocation based on the actual\n     *        argument.\n     * @param targetType the target type, for which adapter instances will be created\n     * @param lookup method handle lookup to use\n     *\n     * @return the constructor method handle.\n     *\n     * @throws Exception if anything goes wrong\n     */\n    public static MethodHandle getConstructor(final Class<?> sourceType, final Class<?> targetType, final MethodHandles.Lookup lookup) throws Exception {\n        final StaticClass adapterClass = getAdapterClassFor(new Class<?>[] { targetType }, null, lookup);\n        return MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new SimpleLinkRequest(\n                new CallSiteDescriptor(lookup, StandardOperation.NEW,\n                        MethodType.methodType(targetType, StaticClass.class, sourceType)), false,\n                        adapterClass, null)).getInvocation(), adapterClass);\n    }\n\n    /**\n     * Returns whether an instance of the specified class/interface can be\n     * generated from a ScriptFunction. Returns {@code true} iff: the adapter\n     * for the class/interface can be created, it is abstract (this includes\n     * interfaces), it has at least one abstract method, all the abstract\n     * methods share the same name, and it has a public or protected default\n     * constructor. Note that invoking this class will most likely result in the\n     * adapter class being defined in the JVM if it hasn't been already.\n     *\n     * @param clazz the inspected class\n     *\n     * @return {@code true} iff an instance of the specified class/interface can\n     *         be generated from a ScriptFunction.\n     */\n    static boolean isAutoConvertibleFromFunction(final Class<?> clazz) {\n        return AUTO_CONVERTIBLE_FROM_FUNCTION.get(clazz);\n    }\n\n    private static AdapterInfo getAdapterInfo(final Class<?>[] types) {\n        final ClassAndLoader definingClassAndLoader = ClassAndLoader.getDefiningClassAndLoader(types);\n\n        final Map<List<Class<?>>, AdapterInfo> adapterInfoMap = ADAPTER_INFO_MAPS.get(definingClassAndLoader.getRepresentativeClass());\n        return adapterInfoMap.computeIfAbsent(List.of(types), t -> createAdapterInfo(t, definingClassAndLoader));\n    }\n\n   /**\n     * For a given class, create its adapter class and associated info.\n     *\n     * @param types the class and interfaces for which the adapter is created\n     *\n     * @return the adapter info for the class.\n     */\n    private static AdapterInfo createAdapterInfo(final List<Class<?>> types, final ClassAndLoader definingClassAndLoader) {\n        Class<?> superClass = null;\n        final List<Class<?>> interfaces = new ArrayList<>(types.size());\n        final Set<Class<?>> interfacesDedup = new HashSet<>(Math.max((int) (types.size()/.75f) + 1, 16));\n        for(final Class<?> t: types) {\n            final int mod = t.getModifiers();\n            if(!t.isInterface()) {\n                if (superClass == t) {\n                    throw adaptationException(ErrorOutcome.DUPLICATE_TYPE, t.getCanonicalName());\n                } else if(superClass != null) {\n                    throw adaptationException(ErrorOutcome.MULTIPLE_SUPERCLASSES, t.getCanonicalName() + \" and \" + superClass.getCanonicalName());\n                } else if (Modifier.isFinal(mod)) {\n                    throw adaptationException(ErrorOutcome.FINAL_CLASS, t.getCanonicalName());\n                }\n                superClass = t;\n            } else {\n                if (interfaces.size() > 65535) {\n                    throw adaptationException(ErrorOutcome.TOO_MANY_INTERFACES, \"65535\");\n                } else if (!interfacesDedup.add(t)) {\n                    throw adaptationException(ErrorOutcome.DUPLICATE_TYPE, t.getCanonicalName());\n                }\n                interfaces.add(t);\n            }\n\n            if(!Modifier.isPublic(mod)) {\n                throw adaptationException(ErrorOutcome.NON_PUBLIC_CLASS, t.getCanonicalName());\n            }\n        }\n\n        final Class<?> effectiveSuperClass = superClass == null ? Object.class : superClass;\n        return AccessController.doPrivileged((PrivilegedAction<AdapterInfo>) () ->\n            new AdapterInfo(effectiveSuperClass, interfaces, definingClassAndLoader),\n            CREATE_ADAPTER_INFO_ACC_CTXT);\n    }\n\n    static ECMAException adaptationException(ErrorOutcome outcome, String... messageArgs) {\n        return ECMAErrors.typeError(\"extend.\" + outcome, messageArgs);\n    }\n\n    /**\n     * Contains various error outcomes for attempting to generate an adapter class.\n     */\n    enum ErrorOutcome {\n        FINAL_CLASS,\n        NON_PUBLIC_CLASS,\n        NO_ACCESSIBLE_CONSTRUCTOR,\n        MULTIPLE_SUPERCLASSES,\n        DUPLICATE_TYPE,\n        TOO_MANY_INTERFACES,\n        NO_COMMON_LOADER,\n        FINAL_FINALIZER\n    }\n\n    private static class AdapterInfo {\n        private static final ClassAndLoader SCRIPT_OBJECT_LOADER = new ClassAndLoader(ScriptFunction.class, true);\n        private static final VarHandle INSTANCE_ADAPTERS;\n        static {\n            try {\n                INSTANCE_ADAPTERS = MethodHandles.lookup().findVarHandle(AdapterInfo.class, \"instanceAdapters\", Map.class);\n            } catch (ReflectiveOperationException e) {\n                throw new RuntimeException(e);\n            }\n        }\n\n        private final ClassLoader commonLoader;\n        // TODO: soft reference the JavaAdapterClassLoader objects. They can be recreated when needed.\n        private final JavaAdapterClassLoader classAdapterGenerator;\n        private final JavaAdapterClassLoader instanceAdapterGenerator;\n        private Map<CodeSource, StaticClass> instanceAdapters;\n        final boolean autoConvertibleFromFunction;\n\n        AdapterInfo(final Class<?> superClass, final List<Class<?>> interfaces, final ClassAndLoader definingLoader) {\n            this.commonLoader = findCommonLoader(definingLoader);\n            final JavaAdapterBytecodeGenerator gen = new JavaAdapterBytecodeGenerator(superClass, interfaces, commonLoader, false);\n            this.autoConvertibleFromFunction = gen.isAutoConvertibleFromFunction();\n            instanceAdapterGenerator = gen.createAdapterClassLoader();\n            this.classAdapterGenerator = new JavaAdapterBytecodeGenerator(superClass, interfaces, commonLoader, true).createAdapterClassLoader();\n        }\n\n        StaticClass getAdapterClass(final ScriptObject classOverrides, final ProtectionDomain protectionDomain) {\n            return classOverrides == null ? getInstanceAdapterClass(protectionDomain) :\n                getClassAdapterClass(classOverrides, protectionDomain);\n        }\n\n        private StaticClass getInstanceAdapterClass(final ProtectionDomain protectionDomain) {\n            CodeSource codeSource = protectionDomain.getCodeSource();\n            if(codeSource == null) {\n                codeSource = MINIMAL_PERMISSION_DOMAIN.getCodeSource();\n            }\n            var ia = instanceAdapters;\n            if (ia == null) {\n                var nia = new ConcurrentHashMap<CodeSource, StaticClass>();\n                @SuppressWarnings(\"unchecked\")\n                var xia = (Map<CodeSource, StaticClass>)INSTANCE_ADAPTERS.compareAndExchange(this, null, nia);\n                ia = xia == null ? nia : xia;\n            }\n            return ia.computeIfAbsent(codeSource, cs -> {\n                // Any \"unknown source\" code source will default to no permission domain.\n                final ProtectionDomain effectiveDomain =\n                    cs.equals(MINIMAL_PERMISSION_DOMAIN.getCodeSource())\n                    ? MINIMAL_PERMISSION_DOMAIN : protectionDomain;\n\n                return instanceAdapterGenerator.generateClass(commonLoader, effectiveDomain);\n            });\n        }\n\n        private StaticClass getClassAdapterClass(final ScriptObject classOverrides, final ProtectionDomain protectionDomain) {\n            JavaAdapterServices.setClassOverrides(classOverrides);\n            try {\n                return classAdapterGenerator.generateClass(commonLoader, protectionDomain);\n            } finally {\n                JavaAdapterServices.setClassOverrides(null);\n            }\n        }\n\n        /**\n         * Choose between the passed class loader and the class loader that defines the\n         * ScriptObject class, based on which of the two can see the classes in both.\n         *\n         * @param classAndLoader the loader and a representative class from it that will\n         *        be used to add the generated adapter to its ADAPTER_INFO_MAPS.\n         *\n         * @return the class loader that sees both the specified class and Nashorn classes.\n         */\n        private static ClassLoader findCommonLoader(final ClassAndLoader classAndLoader) {\n            if(classAndLoader.canSee(SCRIPT_OBJECT_LOADER)) {\n                return classAndLoader.getLoader();\n            }\n            if (SCRIPT_OBJECT_LOADER.canSee(classAndLoader)) {\n                return SCRIPT_OBJECT_LOADER.getLoader();\n            }\n            // try context class loader\n            if (checkContextCL(classAndLoader) && checkContextCL(SCRIPT_OBJECT_LOADER)) {\n                return Thread.currentThread().getContextClassLoader();\n            }\n            throw adaptationException(ErrorOutcome.NO_COMMON_LOADER, classAndLoader.getRepresentativeClass().getCanonicalName());\n        }\n\n        private static boolean checkContextCL(final ClassAndLoader classAndLoader) {\n            try {\n                ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();\n                final Class<?> otherClass = classAndLoader.getRepresentativeClass();\n                return Class.forName(otherClass.getName(), false, contextClassLoader) == otherClass;\n            } catch (ClassNotFoundException e) {\n                return false;\n            }\n        }\n    }\n\n    private static ProtectionDomain createMinimalPermissionDomain() {\n        // Generated classes need to have at least the permission to access Nashorn runtime and runtime.linker packages.\n        final Permissions permissions = new Permissions();\n        permissions.add(new RuntimePermission(\"accessClassInPackage.org.openjdk.nashorn.internal.runtime\"));\n        permissions.add(new RuntimePermission(\"accessClassInPackage.org.openjdk.nashorn.internal.runtime.linker\"));\n        return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);\n    }\n}\n"
  },
  {
    "path": "visualvm/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"visualvm-impl\" basedir=\"..\" xmlns:sproject=\"http://www.netbeans.org/ns/nb-module-suite-project/1\">\n    <property file=\"nbproject/private/platform-private.properties\"/>\n    <property file=\"nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-suite-project/1\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <sproject:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\"/>\n    <sproject:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/suite.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=15cfc12a\nbuild.xml.script.CRC32=b4d38741\nbuild.xml.stylesheet.CRC32=531c622b\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=15cfc12a\nnbproject/build-impl.xml.script.CRC32=3038af2e\nnbproject/build-impl.xml.stylesheet.CRC32=2f5f2db8@1.28.0.7\nnbproject/platform.xml.data.CRC32=15cfc12a\nnbproject/platform.xml.script.CRC32=6dcbd131\nnbproject/platform.xml.stylesheet.CRC32=ae64f0b6@2.77\n"
  },
  {
    "path": "visualvm/nbproject/platform.properties",
    "content": "branding.token=visualvm\ncluster.path=\\\n    ${nbplatform.active.dir}/platform\n# Deprecated since 5.0u1; for compatibility with 5.0:\ndisabled.clusters=\\\n    harness\ndisabled.modules=\\\n    net.java.html,\\\n    net.java.html.boot,\\\n    net.java.html.boot.fx,\\\n    net.java.html.boot.script,\\\n    net.java.html.geo,\\\n    net.java.html.json,\\\n    net.java.html.sound,\\\n    org.netbeans.api.htmlui,\\\n    org.netbeans.api.progress.compat8,\\\n    org.netbeans.api.visual,\\\n    org.netbeans.core.netigso,\\\n    org.netbeans.core.osgi,\\\n    org.netbeans.core.output2,\\\n    org.netbeans.html.ko4j,\\\n    org.netbeans.html.xhr4j,\\\n    org.netbeans.lib.uihandler,\\\n    org.netbeans.libs.felix,\\\n    org.netbeans.libs.javafx,\\\n    org.netbeans.libs.jsr223,\\\n    org.netbeans.libs.junit4,\\\n    org.netbeans.libs.junit5,\\\n    org.netbeans.libs.osgi,\\\n    org.netbeans.libs.testng,\\\n    org.netbeans.modules.core.kit,\\\n    org.netbeans.modules.favorites,\\\n    org.netbeans.modules.junitlib,\\\n    org.netbeans.modules.netbinox,\\\n    org.netbeans.modules.print,\\\n    org.netbeans.modules.spi.actions,\\\n    org.netbeans.modules.templates,\\\n    org.netbeans.modules.templatesui,\\\n    org.netbeans.modules.uihandler,\\\n    org.openide.compat,\\\n    org.openide.execution.compat8,\\\n    org.openide.filesystems.compat8,\\\n    org.openide.options,\\\n    org.openide.util.enumerations\nnbjdk.active=default\nnbplatform.active=VisualVM_platform\nnbplatform.VisualVM_platform.netbeans.dest.dir=netbeans\nsuite.dir=${basedir}\nnetbeans.dest.dir=${suite.dir}/netbeans\nharness.dir=${netbeans.dest.dir}/harness\n"
  },
  {
    "path": "visualvm/nbproject/platform.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project name=\"platform\" default=\"download\" basedir=\"..\">\n    <condition property=\"download.required\">\n        <and>\n            <not>\n                <available file=\"${harness.dir}/suite.xml\"/>\n            </not>\n            <isset property=\"bootstrap.url\"/>\n            <isset property=\"autoupdate.catalog.url\"/>\n        </and>\n    </condition>\n    <target name=\"download\" if=\"download.required\">\n        <mkdir dir=\"${harness.dir}\"/>\n        <pathconvert pathsep=\"|\" property=\"download.clusters\">\n            <mapper type=\"flatten\"/>\n            <path path=\"${cluster.path}\"/>\n        </pathconvert>\n        <property name=\"disabled.modules\" value=\"\"/>\n        <pathconvert property=\"module.includes\" pathsep=\"\">\n            <mapper type=\"glob\" from=\"${basedir}${file.separator}*\" to=\"(?!^\\Q*\\E$)\"/>\n            <path>\n                <filelist files=\"${disabled.modules}\" dir=\".\"/>\n            </path>\n        </pathconvert>\n        <echo message=\"Downloading clusters ${download.clusters}\"/>\n        <property name=\"tasks.jar\" location=\"${java.io.tmpdir}/tasks.jar\"/>\n        <get src=\"${bootstrap.url}\" dest=\"${tasks.jar}\" usetimestamp=\"true\" verbose=\"true\"/>\n        <taskdef name=\"autoupdate\" classname=\"org.netbeans.nbbuild.AutoUpdate\" classpath=\"${tasks.jar}\"/>\n        <autoupdate installdir=\"${nbplatform.active.dir}\" updatecenter=\"${autoupdate.catalog.url}\">\n            <modules includes=\"${module.includes}.*\" clusters=\"${download.clusters}\"/>\n            <modules includes=\"org[.]netbeans[.]modules[.]apisupport[.]harness\" clusters=\"harness\"/>\n        </autoupdate>\n    </target>\n</project>\n"
  },
  {
    "path": "visualvm/nbproject/project.properties",
    "content": "app.icon=branding/core/core.jar/org/netbeans/core/startup/frame48.gif\napp.name=${branding.token}\napp.title=VisualVM\nmodules=\\\n    ${project.org.graalvm.visualvm.core}:\\\n    ${project.org.graalvm.visualvm.modules.appui}:\\\n    ${project.org.graalvm.visualvm.modules.startup}:\\\n    ${project.org.graalvm.visualvm.modules.killapp}:\\\n    ${project.org.graalvm.visualvm.application}:\\\n    ${project.org.graalvm.visualvm.host}:\\\n    ${project.org.graalvm.visualvm.coredump}:\\\n    ${project.org.graalvm.visualvm.threaddump}:\\\n    ${project.org.graalvm.visualvm.heapdump}:\\\n    ${project.org.graalvm.visualvm.profiler}:\\\n    ${project.org.graalvm.visualvm.jmx}:\\\n    ${project.org.graalvm.visualvm.jvmstat}:\\\n    ${project.org.graalvm.visualvm.sa}:\\\n    ${project.org.graalvm.visualvm.attach}:\\\n    ${project.org.graalvm.visualvm.applicationviews}:\\\n    ${project.org.graalvm.visualvm.tools}:\\\n    ${project.org.graalvm.visualvm.host.views}:\\\n    ${project.org.graalvm.visualvm.jvm}:\\\n    ${project.org.graalvm.visualvm.charts}:\\\n    ${project.org.graalvm.visualvm.api.caching}:\\\n    ${project.org.graalvm.visualvm.host.remote}:\\\n    ${project.org.graalvm.visualvm.uisupport}:\\\n    ${project.org.graalvm.visualvm.sampler}:\\\n    ${project.org.graalvm.visualvm.profiling}:\\\n    ${project.org.graalvm.visualvm.heapviewer}:\\\n    ${project.org.graalvm.visualvm.heapviewer.console}:\\\n    ${project.org.graalvm.visualvm.heapviewer.truffle}:\\\n    ${project.org.graalvm.visualvm.graalvm}:\\\n    ${project.org.graalvm.visualvm.sampler.truffle}:\\\n    ${project.org.graalvm.visualvm.pluginimporter}:\\\n    ${project.org.graalvm.visualvm.gotosource}:\\\n    ${project.org.graalvm.visualvm.lib.jfluid}:\\\n    ${project.org.graalvm.visualvm.lib.charts}:\\\n    ${project.org.graalvm.visualvm.lib.common}:\\\n    ${project.org.graalvm.visualvm.lib.heap}:\\\n    ${project.org.graalvm.visualvm.lib.ui}:\\\n    ${project.org.graalvm.visualvm.lib.profiler}:\\\n    ${project.org.graalvm.visualvm.lib.profiler.api}:\\\n    ${project.org.graalvm.visualvm.lib.profiler.attach}:\\\n    ${project.org.graalvm.visualvm.lib.profiler.heapwalker}:\\\n    ${project.org.graalvm.visualvm.lib.profiler.oql}:\\\n    ${project.org.graalvm.visualvm.lib.profiler.snaptracer}:\\\n    ${project.org.graalvm.visualvm.lib.profiler.utilities}:\\\n    ${project.org.graalvm.visualvm.jfr}:\\\n    ${project.org.graalvm.visualvm.jfr.generic}\n#    ${project.org.graalvm.visualvm.jfr.jdk11}\n#    ${project.org.graalvm.visualvm.nashorn.jdk15}\nproject.org.graalvm.visualvm.api.caching=caching.api\nproject.org.graalvm.visualvm.application=application\nproject.org.graalvm.visualvm.applicationviews=applicationviews\nproject.org.graalvm.visualvm.attach=attach\nproject.org.graalvm.visualvm.charts=charts\nproject.org.graalvm.visualvm.coredump=coredump\nproject.org.graalvm.visualvm.gotosource=gotosource\nproject.org.graalvm.visualvm.heapdump=heapdump\nproject.org.graalvm.visualvm.heapviewer=heapviewer\nproject.org.graalvm.visualvm.heapviewer.console=heapviewer.console\nproject.org.graalvm.visualvm.heapviewer.truffle=heapviewer.truffle\nproject.org.graalvm.visualvm.host=host\nproject.org.graalvm.visualvm.host.remote=hostremote\nproject.org.graalvm.visualvm.host.views=hostviews\n#project.org.graalvm.visualvm.nashorn.jdk15=nashorn.jdk15\nproject.org.graalvm.visualvm.jfr=jfr\nproject.org.graalvm.visualvm.jfr.generic=jfr.generic\n#project.org.graalvm.visualvm.jfr.jdk11=jfr.jdk11\nproject.org.graalvm.visualvm.jmx=jmx\nproject.org.graalvm.visualvm.jvm=jvm\nproject.org.graalvm.visualvm.jvmstat=jvmstat\nproject.org.graalvm.visualvm.graalvm=graalvm\nproject.org.graalvm.visualvm.sampler.truffle=sampler.truffle\nproject.org.graalvm.visualvm.pluginimporter=pluginimporter\nproject.org.graalvm.visualvm.profiler=profiler\nproject.org.graalvm.visualvm.profiling=profiling\nproject.org.graalvm.visualvm.sa=sa\nproject.org.graalvm.visualvm.sampler=sampler\nproject.org.graalvm.visualvm.threaddump=threaddump\nproject.org.graalvm.visualvm.tools=tools\nproject.org.graalvm.visualvm.core=core\nproject.org.graalvm.visualvm.modules.appui=appui\nproject.org.graalvm.visualvm.modules.startup=startup\nproject.org.graalvm.visualvm.modules.killapp=killapp\nproject.org.graalvm.visualvm.uisupport=uisupport\n\nproject.org.graalvm.visualvm.lib.jfluid=libs.profiler/lib.profiler\nproject.org.graalvm.visualvm.lib.charts=libs.profiler/lib.profiler.charts\nproject.org.graalvm.visualvm.lib.common=libs.profiler/lib.profiler.common\nproject.org.graalvm.visualvm.lib.heap=libs.profiler/lib.profiler.heap\nproject.org.graalvm.visualvm.lib.ui=libs.profiler/lib.profiler.ui\nproject.org.graalvm.visualvm.lib.profiler=libs.profiler/profiler\nproject.org.graalvm.visualvm.lib.profiler.api=libs.profiler/profiler.api\nproject.org.graalvm.visualvm.lib.profiler.attach=libs.profiler/profiler.attach\nproject.org.graalvm.visualvm.lib.profiler.heapwalker=libs.profiler/profiler.heapwalker\nproject.org.graalvm.visualvm.lib.profiler.oql=libs.profiler/profiler.oql\nproject.org.graalvm.visualvm.lib.profiler.snaptracer=libs.profiler/profiler.snaptracer\nproject.org.graalvm.visualvm.lib.profiler.utilities=libs.profiler/profiler.utilities\nvisualvm-platform=../plugins/\n\nrun.args.extra=-J-Xms24m -J-Xmx768m -J-Dnetbeans.accept_license_class=org.graalvm.visualvm.modules.startup.AcceptLicense -J-Dpolyglot.js.nashorn-compat=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.d3d=false -J-Dnetbeans.exception.report.min.level=900 -J--add-exports=java.desktop/sun.awt=ALL-UNNAMED -J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor.event=ALL-UNNAMED -J--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED -J--add-exports=java.desktop/sun.swing=ALL-UNNAMED -J--add-exports=jdk.attach/sun.tools.attach=ALL-UNNAMED -J--add-opens=java.base/java.net=ALL-UNNAMED -J--add-opens=java.base/java.lang.ref=ALL-UNNAMED -J--add-opens=java.base/java.lang=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED -J-XX:+IgnoreUnrecognizedVMOptions\n"
  },
  {
    "path": "visualvm/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project.suite</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-suite-project/1\">\n            <name>visualvm</name>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/nbproject/suite.properties",
    "content": "suite.dir=${basedir}\n"
  },
  {
    "path": "visualvm/pluginimporter/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.pluginimporter\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.tools.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/pluginimporter/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.pluginimporter\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/pluginimporter/Bundle.properties\nOpenIDE-Module-Specification-Version: 1.0\n\n"
  },
  {
    "path": "visualvm/pluginimporter/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.pluginimporter-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/pluginimporter/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nmodule.javadoc.packages=org.graalvm.visualvm.pluginimporter\n\n"
  },
  {
    "path": "visualvm/pluginimporter/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.pluginimporter</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.54</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress.nb</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.54</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.autoupdate.services</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.62</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.autoupdate.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.53</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.75</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.49</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.17</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems.nb</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.17</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.55</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.40</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.15</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.84</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/pluginimporter/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/pluginimporter/src/org/graalvm/visualvm/pluginimporter/Bundle.properties",
    "content": "#\n# Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Plugin Importer\nOpenIDE-Module-Short-Description=Import plugins installed in specified VisualVM\n\nClusterUpdateProvider_DisplayName=Import plugin from {0}\nClusterUpdateProvider_DisplayName_disabled=Import plugins (disabled)\nClusterUpdateProvider_Description=Import plugins installed in specified VisualVM\nImportNotifier_Install=Install\nImportNotifier_Plugin=Plugin\nInstaller_DialogTitle=Import Plugins\n\nImportNotifier_bRemindLater=Remind &Later\nImportNotifier_bImport=&Import\nImportNotifier_bNo=Do&n't Import\nImportNotifier_PluginAvailableForImport={0} plugins were found in previous installation.\nImportNotifier_PluginAvailableForImport_Details=Do you want to import selected plugins from {0}?\nImportManager.lBroken.text=Plugins that are not &compatible with new version of VisualVM and cannot be imported:\nImportManager.lToImport.text=&Plugins that have not been updated for the new version of VisualVM and so might be incompatible with it (restart needed):\nImportManager.lToInstall.text=Plugins that were found in previous installation and are &available for the new version of VisualVM:\nImportManager.lDesc.text=Plugins installed in previous version were found on your system at {0}.\nImportManager.Progress.Label=Please wait while importing plugins...\nImportManager.Progress.Name=Importing plugins...\nPluginImporter.Importing.Plugin=Importing {0}...\nPluginImporter.Importing.RestartNeeded=Restart needed to import plugins. Do you want to restart VisualVM now?\n#Blacklist codeNameBase of dangerous plugins which cannot be imported like: org.dangerous.plugin,com.nextdangerous.module,... etc.\nplugin.import.blacklist=org.netbeans.shortcuts,org.jmarsault.shortcuts\n"
  },
  {
    "path": "visualvm/pluginimporter/src/org/graalvm/visualvm/pluginimporter/ClusterUpdateProvider.java",
    "content": "/*\n * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.pluginimporter;\n\nimport java.io.BufferedInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.jar.JarFile;\nimport java.util.jar.Manifest;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.netbeans.api.autoupdate.UpdateUnitProvider;\nimport org.netbeans.api.autoupdate.UpdateUnitProvider.CATEGORY;\nimport org.netbeans.spi.autoupdate.UpdateItem;\nimport org.netbeans.spi.autoupdate.UpdateLicense;\nimport org.netbeans.spi.autoupdate.UpdateProvider;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\nimport org.openide.xml.EntityCatalog;\nimport org.openide.xml.XMLUtil;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.Node;\nimport org.w3c.dom.NodeList;\nimport org.xml.sax.InputSource;\nimport org.xml.sax.SAXException;\n\n/**\n *\n * @author Jiri Rechtacek\n */\n@ServiceProvider(service=UpdateProvider.class)\npublic class ClusterUpdateProvider implements UpdateProvider {\n\n    private static File cluster = null;\n    private static final Logger LOG = Logger.getLogger (ClusterUpdateProvider.class.getName ());\n    private static final String ELEMENT_MODULE = \"module\"; // NOI18N\n\n    public ClusterUpdateProvider () {}\n\n    public static void attachCluster (File newCluster) {\n        if (newCluster == null) {\n            throw new IllegalArgumentException (\"Cluster cannot be null!\"); // NOI18N\n        }\n        cluster = newCluster;\n    }\n\n    public String getName () {\n        return Installer.CODE_NAME;\n    }\n\n    public String getDisplayName () {\n        if (cluster == null) {\n            return NbBundle.getMessage(ClusterUpdateProvider.class, \"ClusterUpdateProvider_DisplayName_disabled\");\n        }\n        return NbBundle.getMessage (ClusterUpdateProvider.class, \"ClusterUpdateProvider_DisplayName\", cluster); // NOI18N\n    }\n\n    public String getDescription () {\n        return NbBundle.getMessage (ClusterUpdateProvider.class, \"ClusterUpdateProvider_Description\"); // NOI18N\n    }\n\n    public CATEGORY getCategory () {\n        return UpdateUnitProvider.CATEGORY.STANDARD;\n    }\n\n    public Map<String, UpdateItem> getUpdateItems () throws IOException {\n        Map<String, UpdateItem> res = new HashMap<> ();\n        for (File cf: readModules (cluster)) {\n            String cnb = (cf.getName ().substring (0, cf.getName ().length () - \".xml\".length ())).replaceAll (\"-\", \".\"); // NOI18N\n            Map<String, String> attr = new HashMap<> (7);\n            readConfigFile (cf, attr);\n            String jarName = attr.get (\"jar\");\n            if(jarName == null) {\n                LOG.info (\"Can`t get jar file name for \" + cnb + \", skip checking.\");\n                continue;\n            }\n            File jarFile = new File (cluster, jarName); // NOI18N\n            if (! jarFile.exists ()) {\n                LOG.info (\"Jar file \" + jarFile + \" doesn't exists. Skip checking \" + cnb);\n                continue;\n            }\n            File updateTrackingFile = new File(cluster, \"update_tracking\" + File.separator + cf.getName());\n            if (! updateTrackingFile.exists ()) {\n                LOG.info (\"Update tracking file \" + updateTrackingFile + \" doesn't exists. Skip checking \" + cnb);\n                continue;\n            }\n\n            Manifest mf = new JarFile (jarFile).getManifest ();\n            UpdateItem item = UpdateItem.createModule (\n                cnb,\n                attr.get (\"specversion\"), // NOI18N\n                null,\n                cluster.getName (), // XXX: to identify such items later\n                \"0\", // NOI18N\n                \"\",\n                \"\",\n                \"\",\n                mf,\n                Boolean.valueOf (attr.get (\"eager\")), // NOI18N\n                Boolean.valueOf (attr.get (\"autoload\")), // NOI18N\n                null,\n                null,\n                \"\",\n                UpdateLicense.createUpdateLicense (\"unknown-license\", \"none\")); // NOI18N\n            res.put (cnb + '_' + attr.get (\"specversion\"), item); // NOI18N\n        }\n        return res;\n    }\n\n    public boolean refresh (boolean force) throws IOException {\n        return true;\n    }\n\n    private static Collection<File> readModules (File cluster) {\n        if (cluster == null || ! cluster.exists ()) {\n            return Collections.emptySet ();\n        }\n        Collection<File> res = new HashSet<> ();\n        File config = new File (new File (cluster, \"config\"), \"Modules\"); // NOI18N\n        if (config.listFiles () == null) {\n            return Collections.emptySet ();\n        }\n        for (File cf : config.listFiles ()) {\n            if(cf.getName ().endsWith(\".xml_hidden\")) {\n                //158204\n                continue;\n            }\n\n            if (cf.getName ().endsWith (\".xml\")) { // NOI18N\n                if(cf.length() > 0) {\n                    res.add (cf);\n                } else {\n                    LOG.log(Level.INFO, \"Found zero-sized xml file in config/Modules, ignoring: \" + cf);\n                }\n            } else {\n                LOG.log(Level.INFO, \"Found non-xml file in config/Modules, ignoring: \" + cf);\n            }\n        }\n        return res;\n    }\n\n    private static void readConfigFile (File cf, Map<String, String> attr) {\n        Document document = null;\n        try (InputStream is = new BufferedInputStream (new FileInputStream (cf))) {\n            InputSource xmlInputSource = new InputSource (is);\n            document = XMLUtil.parse (xmlInputSource, false, false, null, EntityCatalog.getDefault ());\n        } catch (SAXException saxe) {\n            LOG.log(Level.INFO, \"Error while reading \" + cf);\n            LOG.log(Level.INFO, saxe.getLocalizedMessage (), saxe);\n            return;\n        } catch (IOException ioe) {\n            LOG.log(Level.INFO, \"Error while reading \" + cf);\n            LOG.log(Level.WARNING, ioe.getLocalizedMessage (), ioe);\n        }\n\n        assert document.getDocumentElement () != null : \"File \" + cf + \" must contain document element.\";\n        Element element = document.getDocumentElement ();\n        assert ELEMENT_MODULE.equals (element.getTagName ()) : \"The root element is: \" + ELEMENT_MODULE + \" but was: \" + element.getTagName ();\n        NodeList children = element.getChildNodes ();\n        for (int i = 0; i < children.getLength (); i++) {\n            Node n = children.item (i);\n            if (Node.ELEMENT_NODE != n.getNodeType()) {\n                continue;\n            }\n            Element e = (Element) n;\n            String name = e.getAttributes ().getNamedItem (\"name\").getNodeValue (); // NOI18N\n            String value = e.getChildNodes ().item (0).getNodeValue ();\n            attr.put (name, value);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/pluginimporter/src/org/graalvm/visualvm/pluginimporter/ImportManager.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.5\" maxVersion=\"1.7\" type=\"org.netbeans.modules.form.forminfo.PanelFormInfo\">\n  <NonVisualComponents>\n    <Container class=\"javax.swing.JScrollPane\" name=\"jScrollPane3\">\n      <AuxValues>\n        <AuxValue name=\"autoScrollPane\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n\n      <Layout class=\"org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout\"/>\n      <SubComponents>\n        <Component class=\"javax.swing.JTextPane\" name=\"jTextPane1\">\n        </Component>\n      </SubComponents>\n    </Container>\n  </NonVisualComponents>\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_layoutCodeTarget\" type=\"java.lang.Integer\" value=\"1\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n  </AuxValues>\n\n  <Layout>\n    <DimensionLayout dim=\"0\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"1\" attributes=\"0\">\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Group type=\"103\" groupAlignment=\"1\" attributes=\"0\">\n                  <Component id=\"pProgress\" alignment=\"0\" max=\"32767\" attributes=\"0\"/>\n                  <Component id=\"jScrollPane4\" alignment=\"1\" max=\"32767\" attributes=\"1\"/>\n                  <Component id=\"lToImport\" alignment=\"0\" max=\"32767\" attributes=\"2\"/>\n                  <Component id=\"jSeparator2\" alignment=\"0\" max=\"32767\" attributes=\"2\"/>\n                  <Component id=\"lToInstall\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"lDesc\" alignment=\"0\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n                  <Component id=\"jScrollPane1\" alignment=\"0\" max=\"32767\" attributes=\"2\"/>\n                  <Component id=\"jSeparator1\" alignment=\"0\" max=\"32767\" attributes=\"2\"/>\n                  <Component id=\"jScrollPane2\" alignment=\"0\" max=\"32767\" attributes=\"2\"/>\n                  <Component id=\"lBroken\" alignment=\"0\" max=\"32767\" attributes=\"2\"/>\n              </Group>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n    <DimensionLayout dim=\"1\">\n      <Group type=\"103\" groupAlignment=\"0\" attributes=\"0\">\n          <Group type=\"102\" alignment=\"0\" attributes=\"0\">\n              <Component id=\"lDesc\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" pref=\"7\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"lToInstall\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jScrollPane1\" pref=\"123\" max=\"32767\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jSeparator1\" min=\"-2\" pref=\"10\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"lToImport\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jScrollPane2\" pref=\"158\" max=\"32767\" attributes=\"0\"/>\n              <EmptySpace min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jSeparator2\" min=\"-2\" pref=\"10\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Component id=\"lBroken\" min=\"-2\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Component id=\"jScrollPane4\" pref=\"75\" max=\"32767\" attributes=\"0\"/>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n              <Component id=\"pProgress\" min=\"-2\" pref=\"21\" max=\"-2\" attributes=\"0\"/>\n              <EmptySpace max=\"-2\" attributes=\"0\"/>\n          </Group>\n      </Group>\n    </DimensionLayout>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JLabel\" name=\"lToInstall\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"lToInstall\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/pluginimporter/Bundle.properties\" key=\"ImportManager.lToInstall.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Container class=\"javax.swing.JScrollPane\" name=\"jScrollPane1\">\n      <AuxValues>\n        <AuxValue name=\"autoScrollPane\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n\n      <Layout class=\"org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout\"/>\n      <SubComponents>\n        <Component class=\"javax.swing.JTable\" name=\"tToInstall\">\n          <Properties>\n            <Property name=\"model\" type=\"javax.swing.table.TableModel\" editor=\"org.netbeans.modules.form.RADConnectionPropertyEditor\">\n              <Connection code=\"getModel (toInstall, checkedToInstall)\" type=\"code\"/>\n            </Property>\n            <Property name=\"autoResizeMode\" type=\"int\" value=\"4\"/>\n            <Property name=\"opaque\" type=\"boolean\" value=\"false\"/>\n          </Properties>\n        </Component>\n      </SubComponents>\n    </Container>\n    <Component class=\"javax.swing.JLabel\" name=\"lToImport\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"tToImport\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/pluginimporter/Bundle.properties\" key=\"ImportManager.lToImport.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Container class=\"javax.swing.JScrollPane\" name=\"jScrollPane2\">\n      <AuxValues>\n        <AuxValue name=\"autoScrollPane\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n\n      <Layout class=\"org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout\"/>\n      <SubComponents>\n        <Component class=\"javax.swing.JTable\" name=\"tToImport\">\n          <Properties>\n            <Property name=\"model\" type=\"javax.swing.table.TableModel\" editor=\"org.netbeans.modules.form.RADConnectionPropertyEditor\">\n              <Connection code=\"getModel (toImport, checkedToImport)\" type=\"code\"/>\n            </Property>\n            <Property name=\"autoResizeMode\" type=\"int\" value=\"4\"/>\n            <Property name=\"opaque\" type=\"boolean\" value=\"false\"/>\n          </Properties>\n        </Component>\n      </SubComponents>\n    </Container>\n    <Component class=\"javax.swing.JLabel\" name=\"lBroken\">\n      <Properties>\n        <Property name=\"labelFor\" type=\"java.awt.Component\" editor=\"org.netbeans.modules.form.ComponentChooserEditor\">\n          <ComponentRef name=\"tpBroken\"/>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/pluginimporter/Bundle.properties\" key=\"ImportManager.lBroken.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)\"/>\n        </Property>\n      </Properties>\n    </Component>\n    <Container class=\"javax.swing.JScrollPane\" name=\"jScrollPane4\">\n      <AuxValues>\n        <AuxValue name=\"autoScrollPane\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n\n      <Layout class=\"org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout\"/>\n      <SubComponents>\n        <Component class=\"javax.swing.JTextPane\" name=\"tpBroken\">\n          <Properties>\n            <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n            <Property name=\"enabled\" type=\"boolean\" value=\"false\"/>\n            <Property name=\"opaque\" type=\"boolean\" value=\"false\"/>\n          </Properties>\n        </Component>\n      </SubComponents>\n    </Container>\n    <Component class=\"javax.swing.JLabel\" name=\"lDesc\">\n      <Properties>\n        <Property name=\"font\" type=\"java.awt.Font\" editor=\"org.netbeans.modules.form.editors2.FontEditor\">\n          <FontInfo relative=\"true\">\n            <Font bold=\"true\" component=\"lDesc\" property=\"font\" relativeSize=\"true\" size=\"0\"/>\n          </FontInfo>\n        </Property>\n        <Property name=\"text\" type=\"java.lang.String\" editor=\"org.netbeans.modules.i18n.form.FormI18nStringEditor\">\n          <ResourceString bundle=\"org/graalvm/visualvm/pluginimporter/Bundle.properties\" key=\"ImportManager.lDesc.text\" replaceFormat=\"org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;, {arguments})\">\n            <Argument index=\"0\" javacode=\"getClusterName()\"/>\n          </ResourceString>\n        </Property>\n      </Properties>\n      <AuxValues>\n        <AuxValue name=\"JavaCodeGenerator_SerializeTo\" type=\"java.lang.String\" value=\"ImportManager_lDesc\"/>\n      </AuxValues>\n    </Component>\n    <Component class=\"javax.swing.JSeparator\" name=\"jSeparator1\">\n    </Component>\n    <Component class=\"javax.swing.JSeparator\" name=\"jSeparator2\">\n    </Component>\n    <Container class=\"javax.swing.JPanel\" name=\"pProgress\">\n\n      <Layout class=\"org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout\"/>\n    </Container>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "visualvm/pluginimporter/src/org/graalvm/visualvm/pluginimporter/ImportManager.java",
    "content": "/*\n * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.pluginimporter;\n\nimport java.awt.Panel;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.prefs.BackingStoreException;\nimport java.util.prefs.Preferences;\nimport javax.swing.AbstractAction;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.SwingConstants;\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.AbstractTableModel;\nimport javax.swing.table.TableColumn;\nimport javax.swing.table.TableModel;\nimport org.netbeans.api.autoupdate.InstallSupport;\nimport org.netbeans.api.autoupdate.OperationContainer;\nimport org.netbeans.api.autoupdate.UpdateElement;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.netbeans.api.progress.ProgressHandleFactory;\nimport org.netbeans.modules.autoupdate.ui.api.PluginManager;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.awt.Mnemonics;\nimport org.openide.awt.Notification;\nimport org.openide.awt.NotificationDisplayer;\nimport org.openide.util.Exceptions;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jirka Rechtacek\n */\npublic class ImportManager extends Panel {\n\n    private final File srcCluster;\n    private final File dest;\n    private final PluginImporter importer;\n    private static ImportManager INSTANCE = null;\n    private List<Boolean> checkedToInstall = Collections.emptyList();\n    private List<Boolean> checkedToImport = Collections.emptyList();\n    private List<UpdateElement> toInstall = Collections.emptyList();\n    private List<UpdateElement> toImport = Collections.emptyList();\n    private Notification currentNotification = null;\n    private JButton bImport;\n    private JButton bNo;\n\n    /**\n     * Creates new form ImportManager\n     */\n    @SuppressWarnings(\"LeakingThisInConstructor\")\n    public ImportManager(File src, File dest, PluginImporter importer) {\n        this.srcCluster = src;\n        this.dest = dest;\n        this.importer = importer;\n        initialize();\n        INSTANCE = this;\n    }\n\n    public PluginImporter getPluginImporter() {\n        return importer;\n    }\n\n    private void initialize() {\n        toInstall = new ArrayList<>(importer.getPluginsAvailableToInstall());\n        toInstall.sort(new Comparator<UpdateElement>() {\n            @Override\n            public int compare(UpdateElement o1, UpdateElement o2) {\n                return o1.getDisplayName().compareTo(o2.getDisplayName());\n            }\n        });\n        checkedToInstall = new ArrayList<>(Collections.nCopies(importer.getPluginsAvailableToInstall().size(), Boolean.TRUE));\n\n        toImport = new ArrayList<>(importer.getPluginsToImport());\n        toImport.sort(new Comparator<UpdateElement>() {\n            @Override\n            public int compare(UpdateElement o1, UpdateElement o2) {\n                return o1.getDisplayName().compareTo(o2.getDisplayName());\n            }\n        });\n        checkedToImport = new ArrayList<>(Collections.nCopies(toImport.size(), Boolean.FALSE));\n\n        initComponents();\n\n        tpBroken.setEnabled(!importer.getBrokenPlugins().isEmpty());\n        lBroken.setEnabled(!importer.getBrokenPlugins().isEmpty());\n        if (!importer.getBrokenPlugins().isEmpty()) {\n            tpBroken.setText(importer.getBrokenPlugins().toString());\n        }\n        refreshUI();\n    }\n\n    public static ImportManager getInstance() {\n        return INSTANCE;\n    }\n\n    public void notifyAvailable() {\n        remindLater();\n        String msg = NbBundle.getMessage(ImportManager.class,\n                \"ImportNotifier_PluginAvailableForImport\", // NOI18N\n                toImport.size() + toInstall.size());\n        String details = NbBundle.getMessage(ImportManager.class,\n                \"ImportNotifier_PluginAvailableForImport_Details\", // NOI18N\n                getClusterName());\n        MyAction a = new MyAction();\n        synchronized (this) {\n            if (null != currentNotification) {\n                currentNotification.clear();\n            }\n            Notification notification = NotificationDisplayer.getDefault().notify(msg,\n                    ImageUtilities.loadImageIcon(\"org/graalvm/visualvm/pluginimporter/import.png\", false), //NOI18N\n                    details,\n                    a);\n            a.notification = notification;\n            currentNotification = notification;\n        }\n    }\n\n    private static class MyAction extends AbstractAction {\n\n        final JButton bRemindLaterButton = new JButton();\n        final JButton bImportButton = new JButton();\n        final JButton bNoButton = new JButton();\n        private Notification notification;\n\n        MyAction() {\n            Mnemonics.setLocalizedText(bRemindLaterButton, NbBundle.getMessage(ImportManager.class, \"ImportNotifier_bRemindLater\"));\n            Mnemonics.setLocalizedText(bImportButton, NbBundle.getMessage(ImportManager.class, \"ImportNotifier_bImport\"));\n            Mnemonics.setLocalizedText(bNoButton, NbBundle.getMessage(ImportManager.class, \"ImportNotifier_bNo\"));\n        }\n\n        @Override\n        public void actionPerformed(ActionEvent e) {\n            ImportManager ui = ImportManager.getInstance();\n            ui.getPluginImporter().reinspect();\n            ui.initialize();\n\n            ui.attachButtons(bImportButton, bNoButton);\n            DialogDescriptor dd = new DialogDescriptor(\n                    ui,\n                    NbBundle.getMessage(ImportManager.class, \"Installer_DialogTitle\"),\n                    true,\n                    new Object[]{bImportButton, bNoButton, bRemindLaterButton},\n                    NotifyDescriptor.OK_OPTION,\n                    DialogDescriptor.BOTTOM_ALIGN,\n                    null,\n                    null);\n            dd.setClosingOptions(new Object[]{bImportButton, bNoButton, bRemindLaterButton});\n            DialogDisplayer.getDefault().createDialog(dd).setVisible(true);\n            if (bImportButton.equals(dd.getValue()) || bNoButton.equals(dd.getValue())) {\n                ui.dontRemind();\n                SwingUtilities.invokeLater(new Runnable() {\n                    @Override\n                    public void run() {\n                        if (null != notification) {\n                            notification.clear();\n                        }\n                    }\n                });\n            } else if (bRemindLaterButton.equals(dd.getValue())) {\n                ui.remindLater();\n            }\n        }\n    }\n\n    public void attachButtons(JButton bImport, JButton bNo) {\n        this.bImport = bImport;\n        this.bNo = bNo;\n        bImport.addActionListener(new ActionListener() {\n\n            @Override\n            public void actionPerformed(ActionEvent e) {\n                Object source = e.getSource();\n                if (source instanceof JButton) {\n                    RequestProcessor.getDefault().post(() -> doImport());\n                }\n            }\n        });\n        refreshUI();\n    }\n\n    public void remindLater() {\n        Preferences p = NbPreferences.forModule(Installer.class);\n        p.put(Installer.KEY_IMPORT_FROM, srcCluster.toString());\n    }\n\n    public void dontRemind() {\n        Preferences p = NbPreferences.forModule(Installer.class);\n        try {\n            p.clear();\n        } catch (BackingStoreException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n    }\n\n    private String getClusterName() {\n        String defaultUserdirRoot = System.getProperty (\"netbeans.default_userdir_root\"); // NOI18N\n\n        if (defaultUserdirRoot != null) {\n            if (srcCluster.getAbsolutePath().startsWith(defaultUserdirRoot)) {\n                return \"VisualVM \"+srcCluster.getName();\n            }\n        }\n        return srcCluster.toString();\n    }\n\n    private boolean doImport() {\n        boolean res = true;\n        if (checkedToImport.contains(Boolean.TRUE)) {\n            final Collection<UpdateElement> reallyToImport = new HashSet<>();\n            for (UpdateElement el : toImport) {\n                if (checkedToImport.get(toImport.indexOf(el))) {\n                    reallyToImport.add(el);\n                }\n            }\n            if (!reallyToImport.isEmpty()) {\n                final ProgressHandle handle = ProgressHandle.createHandle(NbBundle.getMessage(ImportManager.class, \"ImportManager.Progress.Name\"));\n                final JComponent progressComp = ProgressHandleFactory.createProgressComponent(handle);\n                final JLabel detailLabel = new JLabel(NbBundle.getMessage(ImportManager.class, \"ImportManager.Progress.Label\"));\n                detailLabel.setHorizontalAlignment(SwingConstants.LEFT);\n                setProgressComponent(detailLabel, progressComp);\n\n                try {\n                    importer.importPlugins(reallyToImport, srcCluster, dest, handle);\n                } catch (IOException ex) {\n                    Exceptions.printStackTrace(ex);\n                } finally {\n                    toImport.clear();\n                    checkedToImport.clear();\n                }\n\n                try {\n                    SwingUtilities.invokeAndWait(new Runnable() {\n\n                        @Override\n                        public void run() {\n                            detailLabel.setVisible(false);\n                            progressComp.setVisible(false);\n                            tToImport.setModel(getModel(toImport, checkedToImport));\n                            refreshUI();\n                        }\n                    });\n                } catch (InterruptedException ex) {\n                    Exceptions.printStackTrace(ex);\n                } catch (InvocationTargetException ex) {\n                    Exceptions.printStackTrace(ex);\n                }\n            }\n        }\n\n        try {\n            dontRemind();\n            if (checkedToInstall.contains(Boolean.TRUE)) {\n                final OperationContainer<InstallSupport> oc = OperationContainer.createForInstall();\n                for (UpdateElement el : toInstall) {\n                    if (checkedToInstall.get(toInstall.indexOf(el))) {\n                        OperationContainer.OperationInfo<InstallSupport> info = oc.add(el);\n                        if (info != null) {\n                            for (UpdateElement required : info.getRequiredElements()) {\n                                if (!required.getUpdateUnit().isPending()) {\n                                    oc.add(required);\n                                }\n                            }\n                        }\n                    }\n                }\n                try {\n                    SwingUtilities.invokeAndWait(new Runnable() {\n\n                        @Override\n                        public void run() {\n                            PluginManager.openInstallWizard(oc, true);\n                            SwingUtilities.invokeLater(new Runnable() {\n\n                                @Override\n                                public void run() {\n                                    toInstall.clear();\n                                    checkedToInstall.clear();\n                                }\n                            });\n                        }\n                    });\n                } catch (InterruptedException ex) {\n                    Exceptions.printStackTrace(ex);\n                } catch (InvocationTargetException ex) {\n                    Exceptions.printStackTrace(ex);\n                }\n            }\n        } finally {\n            try {\n                SwingUtilities.invokeAndWait(new Runnable() {\n\n                    @Override\n                    public void run() {\n                        tToInstall.setModel(getModel(toInstall, checkedToInstall));\n                        refreshUI();\n                    }\n                });\n            } catch (InterruptedException ex) {\n                Exceptions.printStackTrace(ex);\n            } catch (InvocationTargetException ex) {\n                Exceptions.printStackTrace(ex);\n            }\n\n        }\n        return res;\n    }\n\n    private void setProgressComponent(final JLabel detail, final JComponent progressComponent) {\n        if (SwingUtilities.isEventDispatchThread()) {\n            setProgressComponentInAwt(detail, progressComponent);\n        } else {\n            SwingUtilities.invokeLater(new Runnable() {\n                @Override\n                public void run() {\n                    setProgressComponentInAwt(detail, progressComponent);\n                }\n            });\n        }\n    }\n\n    private void setProgressComponentInAwt(JLabel detail, JComponent progressComponent) {\n        assert pProgress != null;\n        assert SwingUtilities.isEventDispatchThread() : \"Must be called in EQ.\";\n\n        progressComponent.setMinimumSize(progressComponent.getPreferredSize());\n\n        pProgress.setVisible(true);\n\n        java.awt.GridBagConstraints gridBagConstraints;\n\n        gridBagConstraints = new java.awt.GridBagConstraints();\n        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;\n        gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);\n        pProgress.add(progressComponent, gridBagConstraints);\n\n        gridBagConstraints = new java.awt.GridBagConstraints();\n        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;\n        gridBagConstraints.weightx = 1.0;\n        pProgress.add(detail, gridBagConstraints);\n\n        validate();\n    }\n\n    private TableModel getModel(final List<UpdateElement> plugins, final List<Boolean> checked) {\n        return new AbstractTableModel() {\n            @Override\n            public int getRowCount() {\n                return plugins.size();\n            }\n\n            @Override\n            public int getColumnCount() {\n                return 2;\n            }\n\n            @Override\n            public Object getValueAt(int rowIndex, int columnIndex) {\n                switch (columnIndex) {\n                    case 0:\n                        return checked.get(rowIndex);\n                    case 1:\n                        return plugins.get(rowIndex).getDisplayName();\n                }\n                return null;\n            }\n\n            @Override\n            public Class<?> getColumnClass(int columnIndex) {\n                switch (columnIndex) {\n                    case 0:\n                        return Boolean.class;\n                    case 1:\n                        return String.class;\n                }\n                return null;\n            }\n\n            @Override\n            public String getColumnName(int column) {\n                switch (column) {\n                    case 0:\n                        return NbBundle.getMessage(ImportManager.class, \"ImportNotifier_Install\");\n                    case 1:\n                        return NbBundle.getMessage(ImportManager.class, \"ImportNotifier_Plugin\");\n                }\n                return null;\n            }\n\n            @Override\n            public boolean isCellEditable(int rowIndex, int columnIndex) {\n                switch (columnIndex) {\n                    case 0:\n                        return true;\n                    case 1:\n                        return false;\n                }\n                return false;\n            }\n\n            @Override\n            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {\n                switch (columnIndex) {\n                    case 0:\n                        checked.set(rowIndex, ((Boolean) aValue));\n                        refreshUI();\n                        break;\n                    case 1:\n                        assert false : \"Name is not editable.\";\n                        break;\n                }\n            }\n\n        };\n    }\n\n    /**\n     * This method is called from within the constructor to initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is always\n     * regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        jScrollPane3 = new javax.swing.JScrollPane();\n        jTextPane1 = new javax.swing.JTextPane();\n        lToInstall = new javax.swing.JLabel();\n        jScrollPane1 = new javax.swing.JScrollPane();\n        tToInstall = new javax.swing.JTable();\n        lToImport = new javax.swing.JLabel();\n        jScrollPane2 = new javax.swing.JScrollPane();\n        tToImport = new javax.swing.JTable();\n        lBroken = new javax.swing.JLabel();\n        jScrollPane4 = new javax.swing.JScrollPane();\n        tpBroken = new javax.swing.JTextPane();\n        lDesc = new javax.swing.JLabel();\n        jSeparator1 = new javax.swing.JSeparator();\n        jSeparator2 = new javax.swing.JSeparator();\n        pProgress = new javax.swing.JPanel();\n\n        jScrollPane3.setViewportView(jTextPane1);\n\n        lToInstall.setLabelFor(lToInstall);\n        org.openide.awt.Mnemonics.setLocalizedText(lToInstall, org.openide.util.NbBundle.getMessage(ImportManager.class, \"ImportManager.lToInstall.text\")); // NOI18N\n\n        tToInstall.setModel(getModel (toInstall, checkedToInstall));\n        tToInstall.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS);\n        tToInstall.setOpaque(false);\n        jScrollPane1.setViewportView(tToInstall);\n\n        lToImport.setLabelFor(tToImport);\n        org.openide.awt.Mnemonics.setLocalizedText(lToImport, org.openide.util.NbBundle.getMessage(ImportManager.class, \"ImportManager.lToImport.text\")); // NOI18N\n\n        tToImport.setModel(getModel (toImport, checkedToImport));\n        tToImport.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS);\n        tToImport.setOpaque(false);\n        jScrollPane2.setViewportView(tToImport);\n\n        lBroken.setLabelFor(tpBroken);\n        org.openide.awt.Mnemonics.setLocalizedText(lBroken, org.openide.util.NbBundle.getMessage(ImportManager.class, \"ImportManager.lBroken.text\")); // NOI18N\n\n        tpBroken.setEditable(false);\n        tpBroken.setEnabled(false);\n        tpBroken.setOpaque(false);\n        jScrollPane4.setViewportView(tpBroken);\n\n        lDesc.setFont(lDesc.getFont().deriveFont(lDesc.getFont().getStyle() | java.awt.Font.BOLD));\n        org.openide.awt.Mnemonics.setLocalizedText(lDesc, org.openide.util.NbBundle.getMessage(ImportManager.class, \"ImportManager.lDesc.text\", new Object[] {getClusterName()})); // NOI18N\n\n        pProgress.setLayout(new java.awt.GridBagLayout());\n\n        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);\n        this.setLayout(layout);\n        layout.setHorizontalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()\n                .addContainerGap()\n                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)\n                    .addComponent(pProgress, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)\n                    .addComponent(jScrollPane4)\n                    .addComponent(lToImport, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)\n                    .addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(lToInstall, javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(lDesc, javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.LEADING)\n                    .addComponent(lBroken, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))\n                .addContainerGap())\n        );\n        layout.setVerticalGroup(\n            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)\n            .addGroup(layout.createSequentialGroup()\n                .addComponent(lDesc)\n                .addGap(7, 7, 7)\n                .addComponent(lToInstall)\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 123, Short.MAX_VALUE)\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(lToImport)\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 158, Short.MAX_VALUE)\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(lBroken)\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 75, Short.MAX_VALUE)\n                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)\n                .addComponent(pProgress, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)\n                .addContainerGap())\n        );\n    }// </editor-fold>//GEN-END:initComponents\n\n\n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JScrollPane jScrollPane1;\n    private javax.swing.JScrollPane jScrollPane2;\n    private javax.swing.JScrollPane jScrollPane3;\n    private javax.swing.JScrollPane jScrollPane4;\n    private javax.swing.JSeparator jSeparator1;\n    private javax.swing.JSeparator jSeparator2;\n    private javax.swing.JTextPane jTextPane1;\n    private javax.swing.JLabel lBroken;\n    private javax.swing.JLabel lDesc;\n    private javax.swing.JLabel lToImport;\n    private javax.swing.JLabel lToInstall;\n    private javax.swing.JPanel pProgress;\n    private javax.swing.JTable tToImport;\n    private javax.swing.JTable tToInstall;\n    private javax.swing.JTextPane tpBroken;\n    // End of variables declaration//GEN-END:variables\n\n    private void refreshUI() {\n        lToImport.setEnabled(!toImport.isEmpty());\n        tToImport.setEnabled(!toImport.isEmpty());\n\n        lToInstall.setEnabled(!toInstall.isEmpty());\n        tToInstall.setEnabled(!toInstall.isEmpty());\n\n        TableColumn activeColumn = tToImport.getColumnModel().getColumn(0);\n        activeColumn.setMaxWidth(tToImport.getTableHeader().getHeaderRect(0).width);\n        activeColumn = tToInstall.getColumnModel().getColumn(0);\n        activeColumn.setMaxWidth(tToInstall.getTableHeader().getHeaderRect(0).width);\n\n        if (bImport != null) {\n            bImport.setEnabled(checkedToInstall.contains(Boolean.TRUE) || checkedToImport.contains(Boolean.TRUE));\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/pluginimporter/src/org/graalvm/visualvm/pluginimporter/Installer.java",
    "content": "/*\n * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.pluginimporter;\n\nimport java.io.File;\nimport java.util.Collection;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport java.util.prefs.BackingStoreException;\nimport java.util.prefs.Preferences;\nimport org.netbeans.api.autoupdate.UpdateManager;\nimport org.netbeans.api.autoupdate.UpdateUnit;\nimport org.netbeans.api.autoupdate.UpdateUnitProvider;\nimport org.netbeans.api.autoupdate.UpdateUnitProviderFactory;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.modules.OnStart;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.RequestProcessor;\nimport org.openide.windows.WindowManager;\n\n@OnStart\npublic class Installer implements Runnable {\n\n    public static final String KEY_IMPORT_FROM = \"import-from\";\n    public static final String CODE_NAME = \"ClusterUpdateProvider\";\n    public static final String REMOVED = \"_removed\"; // NOI18N\n\n    private static final Logger LOG = Logger.getLogger(Installer.class.getName());\n    private static final String IMPORTED = \"imported\"; // NOI18N\n    private static final String AUTOUPDATE_PREF = \"/org/netbeans/modules/autoupdate\";\n\n    @Override\n    public void run() {\n        // remove ClusterUpdateProvider from available update providers\n        Preferences au_pref = NbPreferences.root().node(AUTOUPDATE_PREF); // NOI18N\n        au_pref.node(Installer.CODE_NAME + Installer.REMOVED).putBoolean(Installer.REMOVED, true);\n\n        // install plugin importer when UI is ready (main window shown)\n        WindowManager.getDefault().invokeWhenUIReady(() ->\n                RequestProcessor.getDefault().post(doCheck, getImportDelay()) // XXX: Need to wait until UC downloaded&parsed\n            );\n    }\n\n    private Runnable doCheck = new Runnable() {\n        @Override\n        public void run() {\n            // check user wants to import previous userdir\n            File importFrom = null;\n            String from = System.getProperty(\"plugin.manager.import.from\", \"\"); // NOI18N\n            Preferences pref = NbPreferences.forModule (Installer.class);\n            Preferences au_pref = NbPreferences.root().node(AUTOUPDATE_PREF); // NOI18N\n            if (!from.isEmpty()) {\n                importFrom = new File(from);\n                // check if the userdir was imported already\n                boolean imported = au_pref.getBoolean(IMPORTED, false);\n                if (!imported) {\n                    // don't import\n                    importFrom = null;\n                }\n            } else if (pref.get (KEY_IMPORT_FROM, null) != null) {\n                // was remind later\n                importFrom = new File (pref.get (KEY_IMPORT_FROM, \"\")); // NOI18N\n            }\n            // don't import again from previous userdir\n            au_pref.putBoolean(IMPORTED, false);\n\n            if (importFrom == null || !importFrom.exists()) {\n                // nothing to do => return\n                LOG.fine(\"Nothing to import from \" + importFrom); // NOI18N\n                return;\n            }\n            try {\n                // XXX: Hack Autoupdate API\n                // find own provider\n                Preferences p = au_pref.node(CODE_NAME + REMOVED);\n                p.removeNode();\n            } catch (BackingStoreException ex) {\n                LOG.log(Level.INFO, ex.getLocalizedMessage(), ex);\n                return;\n            }\n            UpdateUnitProvider clusterUpdateProvider = null;\n            for (UpdateUnitProvider p : UpdateUnitProviderFactory.getDefault().getUpdateUnitProviders(false)) {\n                if (CODE_NAME.contains(p.getName())) {\n                    clusterUpdateProvider = p;\n                }\n            }\n            assert clusterUpdateProvider != null : \"clusterUpdateProvider must found\";\n            if (clusterUpdateProvider != null) {\n                try {\n                    assert importFrom != null && importFrom.exists() : importFrom + \" exists.\";\n                    ClusterUpdateProvider.attachCluster(importFrom);\n                    Collection<UpdateUnit> units = clusterUpdateProvider.getUpdateUnits(UpdateManager.TYPE.MODULE);\n                    UpdateUnitProviderFactory.getDefault().remove(clusterUpdateProvider);\n                    PluginImporter importer = new PluginImporter(units);\n                    if (LOG.isLoggable(Level.FINE)) {\n                        LOG.fine(\"Already installed plugins: \" + importer.getInstalledPlugins());\n                        LOG.fine(\"Plugins available on UC: \" + importer.getPluginsAvailableToInstall());\n                        LOG.fine(\"Plugins available for import: \" + importer.getPluginsToImport());\n                    }\n                    if (!importer.getBrokenPlugins().isEmpty()) {\n                        LOG.info(\"Plugins for import with broken dependencies: \" + importer.getBrokenPlugins());\n                    }\n                    if (!importer.getPluginsToImport().isEmpty() || !importer.getPluginsAvailableToInstall().isEmpty()) {\n                        LOG.info((importer.getPluginsToImport().size() + importer.getPluginsAvailableToInstall().size())\n                                + \" available plugins for import in \" + importFrom); // NOI18N\n                        ImportManager notifier = new ImportManager(importFrom, getUserDir(), importer);\n                        notifier.notifyAvailable();\n                    } else {\n                        LOG.fine((importer.getPluginsToImport().size() + importer.getPluginsAvailableToInstall().size())\n                                + \" available plugins for import in \" + importFrom); // NOI18N\n                    }\n                } catch (Exception x) {\n                    LOG.log(Level.INFO, x.getLocalizedMessage() + \" while importing plugins from \" + importFrom, x);\n                } finally {\n                    UpdateUnitProviderFactory.getDefault().remove(clusterUpdateProvider);\n                }\n            }\n        }\n    };\n\n    private static File getUserDir() {\n        String user = System.getProperty(\"netbeans.user\"); // NOI18N\n        File userDir = null;\n        if (user != null) {\n            userDir = FileUtil.normalizeFile(new File(user));\n        }\n        return userDir;\n    }\n\n    private int getImportDelay() {\n        int delay = 30000; // the defalut value\n        String delay_prop = System.getProperty(\"plugin.manager.import.delay\");\n        try {\n            delay = Integer.parseInt(delay_prop);\n        } catch (NumberFormatException x) {\n            // ignore, use the default value\n        }\n        return delay;\n    }\n}\n"
  },
  {
    "path": "visualvm/pluginimporter/src/org/graalvm/visualvm/pluginimporter/PluginImporter.java",
    "content": "/*\n * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.pluginimporter;\n\nimport java.io.BufferedInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.StringTokenizer;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.netbeans.api.autoupdate.InstallSupport;\nimport org.netbeans.api.autoupdate.OperationContainer;\nimport org.netbeans.api.autoupdate.UpdateElement;\nimport org.netbeans.api.autoupdate.UpdateManager;\nimport org.netbeans.api.autoupdate.UpdateUnit;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.DialogDisplayer;\nimport org.openide.LifecycleManager;\nimport org.openide.NotifyDescriptor;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileSystem;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.modules.SpecificationVersion;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.xml.XMLUtil;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.NamedNodeMap;\nimport org.w3c.dom.Node;\nimport org.w3c.dom.NodeList;\nimport org.xml.sax.InputSource;\nimport org.xml.sax.SAXException;\n\n/**\n *\n * @author Jiri Rechtacek\n */\npublic class PluginImporter {\n\n    private final Collection<UpdateUnit> plugins;\n    private boolean inspected = false;\n    private Collection<UpdateElement> installed = null;\n    private Collection<UpdateElement> toInstall = null;\n    private Collection<UpdateElement> toImport = null;\n    private Collection<UpdateElement> broken = null;\n\n    private static final String TRACKING_FILE_NAME = \"update_tracking\"; // NOI18N\n    private static final String ELEMENT_MODULE = \"module\"; // NOI18N\n    private static final String ELEMENT_VERSION = \"module_version\"; // NOI18N\n    private static final String ATTR_LAST = \"last\"; // NOI18N\n    private static final String ATTR_FILE_NAME = \"name\"; // NOI18N\n    private static final String MODULES = \"Modules\"; // NOI18N\n    private static final String LAST_MODIFIED = \".lastModified\"; // NOI18N\n\n    private static final Logger LOG = Logger.getLogger(PluginImporter.class.getName());\n\n    public PluginImporter(Collection<UpdateUnit> foundPlugins) {\n        plugins = foundPlugins;\n    }\n\n    public void reinspect() {\n        inspected = false;\n        inspect();\n    }\n\n    private void inspect() {\n        if (inspected) {\n            return;\n        }\n        long start = System.currentTimeMillis();\n        installed = new HashSet<>();\n        toImport = new HashSet<>();\n        toInstall = new HashSet<>();\n        broken = new HashSet<>();\n\n        Collection<UpdateElement> candidate2import = new HashSet<>();\n        List<UpdateUnit> updateUnits = UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE);\n        Map<String, UpdateUnit> cnb2uu = new HashMap<>(updateUnits.size());\n        for (UpdateUnit u : updateUnits) {\n            cnb2uu.put(u.getCodeName(), u);\n        }\n\n        for (UpdateUnit unit : plugins) {\n            // save information about plugins on common Update Center\n            UpdateUnit remoteUnit = cnb2uu.get(unit.getCodeName());\n            UpdateElement remoteElement = null;\n            SpecificationVersion remoteSpec = null;\n            if (remoteUnit != null && !remoteUnit.getAvailableUpdates().isEmpty()) {\n                remoteElement = remoteUnit.getAvailableUpdates().get(0);\n                remoteSpec = remoteElement.getSpecificationVersion() == null ? null : new SpecificationVersion(remoteElement.getSpecificationVersion());\n            }\n\n            if (unit.getInstalled() != null) {\n                if (!unit.getAvailableUpdates().isEmpty()) {\n                    UpdateElement el = unit.getAvailableUpdates().get(0);\n                    if (remoteElement != null) {\n                        SpecificationVersion spec = el.getSpecificationVersion() == null ? null : new SpecificationVersion(el.getSpecificationVersion());\n                        if (spec != null && spec.compareTo(remoteSpec) > 0) {\n                            candidate2import.add(el);\n                        }\n                    } else {\n                        candidate2import.add(el);\n                    }\n                }\n                installed.add(unit.getInstalled());\n            } else if (unit.isPending()) {\n                LOG.log(Level.INFO, \"Plugin \" + unit.getCodeName() + \" is not installed but is in pending state - i.e. will be installed upon restart, skipping\");\n            } else {\n                assert !unit.getAvailableUpdates().isEmpty() : \"If \" + unit + \" isn't installed thus has available updates.\";\n                UpdateElement el = unit.getAvailableUpdates().get(0);\n                if (remoteElement != null) {\n                    SpecificationVersion spec = el.getSpecificationVersion() == null ? null : new SpecificationVersion(el.getSpecificationVersion());\n                    if (spec != null && spec.compareTo(remoteSpec) > 0) {\n                        candidate2import.add(el);\n                    } else {\n                        toInstall.add(remoteElement);\n                    }\n                } else {\n                    candidate2import.add(el);\n                }\n            }\n        }\n        for (UpdateElement el : candidate2import) {\n            OperationContainer<InstallSupport> oc = el.getUpdateUnit().getInstalled() == null\n                    ? OperationContainer.createForInstall()\n                    : OperationContainer.createForUpdate();\n            try {\n                OperationContainer.OperationInfo<InstallSupport> info = oc.add(el);\n                oc.add(candidate2import);\n                if (isBlacklisted(el)) {\n                    LOG.info(\"Plugin \" + el + \" is on blacklist thus will not be imported.\");\n                } else if (info.getBrokenDependencies().isEmpty()) {\n                    toImport.add(el);\n                } else {\n                    LOG.log(Level.INFO, \"Plugin \" + el\n                            + // NOI18N\n                            \" cannot be install because not all dependencies can be match: \" + info.getBrokenDependencies()); // NOI18N\n                    broken.add(el);\n                }\n            } catch (IllegalArgumentException iae) {\n                LOG.log(Level.INFO, iae.getLocalizedMessage(), iae);\n                broken.add(el);\n            }\n        }\n        long end = System.currentTimeMillis();\n        LOG.log(Level.INFO, \"Inspecting plugins took \" + (end - start) + \" ms\"); // NOI18N\n\n        inspected = true;\n    }\n\n    public Collection<UpdateElement> getPluginsToImport() {\n        inspect();\n        return toImport;\n    }\n\n    public Collection<UpdateElement> getInstalledPlugins() {\n        inspect();\n        return installed;\n    }\n\n    public Collection<UpdateElement> getPluginsAvailableToInstall() {\n        inspect();\n        return toInstall;\n    }\n\n    public Collection<UpdateElement> getBrokenPlugins() {\n        inspect();\n        return broken;\n    }\n\n    public void importPlugins(Collection<UpdateElement> plugins, File src, File dest, ProgressHandle handle) throws IOException {\n        if (handle != null) {\n            handle.setInitialDelay(0);\n            handle.start(plugins.size());\n        }\n        List<String> configs = new ArrayList<>(plugins.size());\n        int completed = 0;\n        for (UpdateElement el : plugins) {\n            if (handle != null) {\n                String name = el.getDisplayName();\n                if (name == null) {\n                    name = el.getCodeName();\n                }\n                String detail = NbBundle.getMessage(PluginImporter.class, \"PluginImporter.Importing.Plugin\", name);//NOI18N\n                handle.progress(detail, completed++);\n            }\n            String cnb = el.getCodeName();\n\n            // 1. find all plugin's resources\n            Collection<String> toCopy = getPluginFiles(src, cnb, locateUpdateTracking(cnb, src));\n            if (toCopy.isEmpty()) {\n                continue;\n            }\n\n            // 2. copy them\n            for (String path : toCopy) {\n                copy(path, src, dest);\n            }\n\n            // 3. find config file\n            String path = \"config/Modules/\" + cnb.replace('.', '-') + \".xml\"; // NOI18N\n            configs.add(path);\n        }\n\n        // 4. find and copy config files in the end\n        for (String path : configs) {\n            copy(path, src, dest);\n        }\n\n        // #252928 (fragment modules)\n        if (getPluginsToImport().isEmpty()) {\n            refreshModuleList();\n        } else {\n            String restartMsg = NbBundle.getMessage(PluginImporter.class, \"PluginImporter.Importing.RestartNeeded\");//NOI18N\n            NotifyDescriptor nd = new NotifyDescriptor.Confirmation(restartMsg, NotifyDescriptor.YES_NO_OPTION);\n            Object result = DialogDisplayer.getDefault().notify(nd);\n            if (result.equals(NotifyDescriptor.OK_OPTION)) {\n                LifecycleManager.getDefault().markForRestart();\n                LifecycleManager.getDefault().exit();\n            }\n        }\n\n        if (handle != null) {\n            handle.finish();\n        }\n    }\n\n    private static void copy(String path, File sourceFolder, File destFolder) throws IOException {\n        LOG.finest(\"Copy \" + path + \" from \" + sourceFolder + \" to \" + destFolder);\n        File src = new File(sourceFolder, path);\n        assert src.exists() : src + \" exists.\";\n        src = FileUtil.normalizeFile(src);\n        FileObject srcFO = FileUtil.toFileObject(src);\n\n        File destFO = new File(destFolder, path);\n        destFO.getParentFile().mkdirs();\n        File dest = destFO.getParentFile();\n        dest = FileUtil.normalizeFile(dest);\n        FileObject destFolderFO = FileUtil.toFileObject(dest);\n\n        File destFile;\n        if ((destFile = new File(dest, srcFO.getNameExt())).exists()) {\n            if (!destFile.delete()) {\n                // if failed delete of the destFile => don't copy, otherwise will cause #159188\n                return;\n            }\n        }\n        FileObject res = FileUtil.copyFile(srcFO, destFolderFO, srcFO.getName());\n        LOG.finest(srcFO + \" was copied to \" + destFolderFO + \". Result is: \" + res);\n    }\n\n    private static Collection<String> getPluginFiles(File cluster, String cnb, File updateTracking) {\n        Collection<String> res = new HashSet<>();\n        LOG.log(Level.FINE, \"Read update_tracking \" + updateTracking + \" file.\");\n        Node updateTrackingConf = getUpdateTrackingConf(updateTracking);\n        if (updateTrackingConf == null) {\n            return Collections.emptySet();\n        }\n        Set<String> moduleFiles = readModuleFiles(updateTrackingConf);\n        String configFile = \"config/Modules/\" + cnb.replace('.', '-') + \".xml\"; // NOI18N\n\n        moduleFiles.remove(configFile);\n\n        for (String fileName : moduleFiles) {\n            File file = new File(cluster, fileName);\n            if (!file.exists()) {\n                LOG.log(Level.WARNING, \"File \" + file + \" doesn't exist for module \" + cnb);\n                continue;\n            }\n            if (file.equals(updateTracking)) {\n                continue;\n            }\n            res.add(fileName);\n        }\n\n        res.add(TRACKING_FILE_NAME + '/' + cnb.replace('.', '-') + \".xml\"); // NOI18N);\n\n        LOG.log(Level.FINEST, cnb + \" has files: \" + res);\n        return res;\n    }\n\n    private static File locateUpdateTracking(String cnb, File cluster) {\n        String fileNameToFind = TRACKING_FILE_NAME + '/' + cnb.replace('.', '-') + \".xml\"; // NOI18N\n        File ut = new File(cluster, fileNameToFind);\n        if (ut.exists()) {\n            return ut;\n        }\n        throw new IllegalArgumentException(ut + \" doesn't exist.\"); // NOI18N\n    }\n\n    private static Node getUpdateTrackingConf(File moduleUpdateTracking) {\n        Document document = null;\n        try (InputStream is = new BufferedInputStream(new FileInputStream(moduleUpdateTracking))) {\n            InputSource xmlInputSource = new InputSource(is);\n            document = XMLUtil.parse(xmlInputSource, false, false, null, org.openide.xml.EntityCatalog.getDefault());\n        } catch (SAXException saxe) {\n            LOG.log(Level.WARNING, \"SAXException when reading \" + moduleUpdateTracking + \", cause: \" + saxe);\n            //for issue #217118 investigation what is corrupted and how\n            try (FileReader reader = new FileReader(moduleUpdateTracking)){\n                char[] text = new char[1024];\n                String fileContent = \"\";\n                while (reader.read(text) > 0) {\n                    fileContent += String.copyValueOf(text);\n                }\n                LOG.log(Level.WARNING, \"SAXException in file:\\n------FILE START------\\n \" + fileContent + \"\\n------FILE END-----\\n\");\n            } catch (Exception ex) {\n                //don't need to fail in logging\n            }\n            return null;\n        } catch (IOException ioe) {\n            LOG.log(Level.WARNING, null, ioe);\n        }\n\n        assert document.getDocumentElement() != null : \"File \" + moduleUpdateTracking + \" must contain <module> element.\";\n        return getModuleElement(document.getDocumentElement());\n    }\n\n    private static Node getModuleElement(Element element) {\n        Node lastElement = null;\n        assert ELEMENT_MODULE.equals(element.getTagName()) : \"The root element is: \" + ELEMENT_MODULE + \" but was: \" + element.getTagName();\n        NodeList listModuleVersions = element.getElementsByTagName(ELEMENT_VERSION);\n        for (int i = 0; i < listModuleVersions.getLength(); i++) {\n            lastElement = getModuleLastVersion(listModuleVersions.item(i));\n            if (lastElement != null) {\n                break;\n            }\n        }\n        return lastElement;\n    }\n\n    private static Node getModuleLastVersion(Node version) {\n        Node attrLast = version.getAttributes().getNamedItem(ATTR_LAST);\n        assert attrLast != null : \"ELEMENT_VERSION must contain ATTR_LAST attribute.\";\n        if (Boolean.parseBoolean(attrLast.getNodeValue())) {\n            return version;\n        } else {\n            return null;\n        }\n    }\n\n    private static Set<String> readModuleFiles(Node version) {\n        Set<String> files = new HashSet<>();\n        NodeList fileNodes = version.getChildNodes();\n        for (int i = 0; i < fileNodes.getLength(); i++) {\n            if (fileNodes.item(i).hasAttributes()) {\n                NamedNodeMap map = fileNodes.item(i).getAttributes();\n                files.add(map.getNamedItem(ATTR_FILE_NAME).getNodeValue());\n                LOG.log(Level.FINE,\n                        \"File for import: \"\n                        + map.getNamedItem(ATTR_FILE_NAME).getNodeValue());\n            }\n        }\n        return files;\n    }\n\n    private static void refreshModuleList() {\n        // XXX: the modules list should be refresh automatically when config/Modules/ changes\n        final FileObject modulesRoot = FileUtil.getConfigFile(MODULES);\n        LOG.log(Level.FINE,\n                \"It's a hack: Call refresh on \" + modulesRoot\n                + \" file object.\");\n        if (modulesRoot != null) {\n            try {\n                FileUtil.runAtomicAction(new FileSystem.AtomicAction() {\n\n                    @Override\n                    public void run() throws IOException {\n                        modulesRoot.getParent().refresh();\n                        modulesRoot.refresh();\n                    }\n                });\n            } catch (IOException ex) {\n                Exceptions.printStackTrace(ex);\n            }\n        }\n    }\n\n    public static void touchLastModified(File cluster) {\n        try {\n            File stamp = new File(cluster, LAST_MODIFIED);\n            if (!stamp.createNewFile()) {\n                stamp.setLastModified(System.currentTimeMillis());\n                if (!stamp.setLastModified(System.currentTimeMillis())) {\n                    stamp.delete();\n                    stamp = new File(cluster, LAST_MODIFIED);\n                    stamp.setLastModified(System.currentTimeMillis());\n                }\n            }\n        } catch (IOException ex) {\n            LOG.log(Level.INFO, ex.getMessage(), ex);\n        }\n    }\n\n    private static boolean isBlacklisted(UpdateElement el) {\n        String blacklist = System.getProperty(\"plugin.import.blacklist\", \"\"); // NOI18N\n        if (!blacklist.isEmpty()) {\n            blacklist = blacklist + ','; // NOI18N\n        }\n        blacklist = blacklist + NbBundle.getMessage(PluginImporter.class, \"plugin.import.blacklist\"); // NOI18N\n        LOG.fine(\"Blacklist: \" + blacklist);\n        StringTokenizer tokens = new StringTokenizer(blacklist, \",\");\n        while (tokens.hasMoreTokens()) {\n            if (el.getCodeName().equals(tokens.nextToken())) {\n                return true;\n            }\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/profiler/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.profiler\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.profiler.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n    <target name=\"compile-lib\" depends=\"init\">\n        <mkdir dir=\"${build.dir}/lib-classes\" />\n        <!-- NOTE: Must be built with Source Level 1.5 to work for getting info from Java 5! -->\n        <javac srcdir=\"libsrc\" destdir=\"${build.dir}/lib-classes\" deprecation=\"${build.compiler.deprecation}\" debug=\"${build.compiler.debug}\" source=\"1.5\" target=\"1.5\">\n            <classpath>\n                <pathelement path=\"${lib.cp}\"/>\n            </classpath>\n        </javac>\n        <copy todir=\"${build.dir}/lib-classes\">\n            <fileset dir=\"libsrc\" excludes=\"${jar-excludes}\" />\n        </copy>\n    </target>\n\n    <target name=\"jar-lib\" depends=\"compile-lib\">\n        <mkdir dir=\"${cluster}/modules/ext\" />\n        <jar jarfile=\"${cluster}/modules/ext/profilerprobe.jar\" manifest=\"libsrc/manifest.mf\" compress=\"false\">\n            <fileset dir=\"${build.dir}/lib-classes\" />\n        </jar>\n    </target>\n\n    <target name=\"compile\" depends=\"jar-lib, projectized-common.compile\" />\n\n</project>\n"
  },
  {
    "path": "visualvm/profiler/libsrc/manifest.mf",
    "content": "Main-Class: org.graalvm.visualvm.profiler.JavaSysProperties\n\n"
  },
  {
    "path": "visualvm/profiler/libsrc/org/graalvm/visualvm/profiler/JavaSysProperties.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.profiler;\n\n/**\n * NOTE: Must be built with Source Level 1.5 to work for getting info from Java 5!\n *\n */\npublic class JavaSysProperties {\n\n    public static void main(String[] args) {\n        for (String arg : args) System.out.println(System.getProperty(arg));\n    }\n}\n"
  },
  {
    "path": "visualvm/profiler/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.profiler/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/profiler/resources/layer.xml\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/profiler/Bundle.properties\nOpenIDE-Module-Provides: org.graalvm.visualvm.lib.common.Profiler\nOpenIDE-Module-Specification-Version: 2.1\n\n"
  },
  {
    "path": "visualvm/profiler/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.profiler-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/profiler/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=dd702792\nbuild.xml.script.CRC32=03a7511e\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=dd702792\nnbproject/build-impl.xml.script.CRC32=6c1a4403\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/profiler/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nextra.module.files=modules/ext/profilerprobe.jar\n\n"
  },
  {
    "path": "visualvm/profiler/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.profiler</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.host</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.common</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.20</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.utilities</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.modules.startup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.profiling</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.55.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.28.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.11</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.11</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.18.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.profiler.startup</friend>\n                <package>org.graalvm.visualvm.profiler</package>\n            </friend-packages>\n            <class-path-extension>\n                <runtime-relative-path>ext/profilerprobe.jar</runtime-relative-path>\n            </class-path-extension>\n            <extra-compilation-unit>\n                <package-root>libsrc</package-root>\n                <classpath>${lib.cp}</classpath>\n                <built-to>${build.dir}/lib-classes</built-to>\n                <built-to>${cluster}/modules/ext/profilerprobe.jar</built-to>\n            </extra-compilation-unit>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/profiler/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/ApplicationProfilerView.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.MouseEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DesktopUtils;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.lib.common.AttachSettings;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.common.event.ProfilingStateEvent;\nimport org.graalvm.visualvm.lib.common.event.ProfilingStateListener;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.profiler.NetBeansProfiler;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.lib.profiler.utilities.ProfilerUtils;\nimport org.graalvm.visualvm.profiling.presets.PresetSelector;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPreset;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPresets;\nimport org.graalvm.visualvm.uisupport.HTMLLabel;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.WeakListeners;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ApplicationProfilerView extends DataSourceView {\n    \n    private static final String IMAGE_PATH =\n            \"org/graalvm/visualvm/profiler/resources/profiler.png\"; // NOI18N\n    \n    private DataViewComponent dvc;\n    private MasterViewSupport masterViewSupport;\n    private CPUSettingsSupport cpuSettings;\n    private MemorySettingsSupport memorySettings;\n    private JDBCSettingsSupport jdbcSettings;\n    private LocksSettingsSupport locksSettings;\n    \n    private DefaultComboBoxModel<ProfilerPreset> selectorModel;\n    private List<PresetSelector> allSelectors;\n    \n    private boolean classSharingBreaksProfiling;\n\n    \n    ApplicationProfilerView(final Application application) {\n        super(application, NbBundle.getMessage(ApplicationProfilerView.class, \"LBL_Profiler\"), // NOI18N\n              new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 40, false);   \n        cpuSettings = new CPUSettingsSupport() {\n            public boolean presetValid() {\n                return cpuSettings.settingsValid() &&\n                       memorySettings.settingsValid() &&\n                       jdbcSettings.settingsValid() &&\n                       locksSettings.settingsValid();\n            }\n            public PresetSelector createSelector(Runnable presetSynchronizer) {\n                return ApplicationProfilerView.this.createSelector(presetSynchronizer, application);\n            }\n        };\n        memorySettings = new MemorySettingsSupport() {\n            public boolean presetValid() {\n                return cpuSettings.settingsValid() &&\n                       memorySettings.settingsValid() &&\n                       jdbcSettings.settingsValid() &&\n                       locksSettings.settingsValid();\n            }\n            public PresetSelector createSelector(Runnable presetSynchronizer) {\n                return ApplicationProfilerView.this.createSelector(presetSynchronizer, application);\n            }\n        };\n        jdbcSettings = new JDBCSettingsSupport() {\n            public boolean presetValid() {\n                return cpuSettings.settingsValid() &&\n                       memorySettings.settingsValid() &&\n                       jdbcSettings.settingsValid() &&\n                       locksSettings.settingsValid();\n            }\n            public PresetSelector createSelector(Runnable presetSynchronizer) {\n                return ApplicationProfilerView.this.createSelector(presetSynchronizer, application);\n            }\n        };\n        locksSettings = new LocksSettingsSupport() {\n            public boolean presetValid() {\n                return cpuSettings.settingsValid() &&\n                       memorySettings.settingsValid() &&\n                       jdbcSettings.settingsValid() &&\n                       locksSettings.settingsValid();\n            }\n            public PresetSelector createSelector(Runnable presetSynchronizer) {\n                return ApplicationProfilerView.this.createSelector(presetSynchronizer, application);\n            }\n        };\n    }\n    \n    private ProfilerPreset cachedPreset;\n    private ProfilingSettings cachedSettings;\n    \n    void selectPreset(ProfilerPreset preset, final ProfilingSettings settings) {\n        \n        if (masterViewSupport == null) {\n            cachedPreset = preset;\n            cachedSettings = settings;\n        } else {            \n            preset = new ProfilerPreset(preset);\n            \n            int presetIdx = selectorModel.getIndexOf(preset);\n            if (presetIdx == -1) { // custom preset\n                selectorModel.insertElementAt(preset, 1);\n            } else {\n                selectorModel.removeElement(preset);\n                selectorModel.insertElementAt(preset, presetIdx);\n            }\n            selectorModel.setSelectedItem(preset);\n            \n            cpuSettings.updateSettings(preset);\n            memorySettings.updateSettings(preset);\n            jdbcSettings.updateSettings(preset);\n            locksSettings.updateSettings(preset);\n            \n            if (ProfilingSettings.isCPUSettings(settings)) {\n                masterViewSupport.showCPUSettings();\n            } else if (ProfilingSettings.isMemorySettings(settings)) {\n                masterViewSupport.showMemorySettings();\n            } else if (ProfilingSettings.isJDBCSettings(settings)) {\n                masterViewSupport.showJDBCSettings();\n            }\n            \n            cachedPreset = null;\n            cachedSettings = null;\n        }\n    }\n    \n    private PresetSelector createSelector(Runnable presetSynchronizer, Application application) {\n        if (selectorModel == null) selectorModel = new DefaultComboBoxModel<>();\n        if (allSelectors == null) allSelectors = new ArrayList<>();\n        PresetSelector selector = ProfilerPresets.getInstance().createSelector(\n                                  application, selectorModel, allSelectors, presetSynchronizer);\n        allSelectors.add(selector);\n        return selector;\n    }\n        \n    \n    protected DataViewComponent createComponent() {\n        if (dvc != null) return dvc;\n        \n        Application application = (Application)getDataSource();\n        ProfilingResultsSupport profilingResultsSupport = new ProfilingResultsSupport();\n        \n        masterViewSupport = new MasterViewSupport(application, profilingResultsSupport, cpuSettings, memorySettings, jdbcSettings, locksSettings, classSharingBreaksProfiling) {\n            void showCPUSettings() {\n                if (dvc != null) {\n                    cpuSettings.showSettings(dvc);\n                    dvc.showDetailsArea(DataViewComponent.TOP_RIGHT);\n                }\n            }\n            void showMemorySettings() {\n                if (dvc != null) {\n                    memorySettings.showSettings(dvc);\n                    dvc.showDetailsArea(DataViewComponent.TOP_RIGHT);\n                }\n            }\n            void showJDBCSettings() {\n                if (dvc != null) {\n                    jdbcSettings.showSettings(dvc);\n                    dvc.showDetailsArea(DataViewComponent.TOP_RIGHT);\n                }\n            }\n        };\n        \n        dvc = new DataViewComponent(masterViewSupport.getMasterView(), new DataViewComponent.MasterViewConfiguration(false));\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(ApplicationProfilerView.class, \"LBL_Profiling_results\"), false), DataViewComponent.TOP_LEFT);   // NOI18N\n        dvc.addDetailsView(profilingResultsSupport.getDetailsView(), DataViewComponent.TOP_LEFT);\n        \n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(ApplicationProfilerView.class, \"LBL_Settings\"), true), DataViewComponent.TOP_RIGHT);   // NOI18N\n        dvc.addDetailsView(cpuSettings.getDetailsView(), DataViewComponent.TOP_RIGHT);\n        dvc.addDetailsView(memorySettings.getDetailsView(), DataViewComponent.TOP_RIGHT);\n        dvc.addDetailsView(jdbcSettings.getDetailsView(), DataViewComponent.TOP_RIGHT);\n//        dvc.addDetailsView(locksSettings.getDetailsView(), DataViewComponent.TOP_RIGHT);\n//        dvc.hideDetailsArea(DataViewComponent.TOP_RIGHT);\n\n        if (cachedPreset != null) selectPreset(cachedPreset, cachedSettings);\n        \n        return dvc;\n    }\n    \n    protected void willBeAdded() {\n        classSharingBreaksProfiling = ProfilerSupport.classSharingBreaksProfiling((Application)getDataSource());\n    }\n    \n    protected void removed() {\n        masterViewSupport.viewRemoved();\n    }\n    \n    \n    // --- General data --------------------------------------------------------\n    \n    private static abstract class MasterViewSupport extends JPanel implements ProfilingStateListener, DataRemovedListener<Application>, ActionListener, PropertyChangeListener {\n        \n        private Application application;\n        private ProfilingResultsSupport profilingResultsView;\n        private CPUSettingsSupport cpuSettingsSupport;\n        private MemorySettingsSupport memorySettingsSupport;\n        private JDBCSettingsSupport jdbcSettingsSupport;\n        private LocksSettingsSupport locksSettingsSupport;\n        private AttachSettings attachSettings;\n        private Timer timer;\n        private int lastInstrValue = -1;\n\n        private int state = -1;\n\n        private boolean internalChange = false;\n        private boolean applicationTerminated = false;\n        \n        private boolean classSharingBreaksProfiling;\n        \n        private final NetBeansProfiler profiler;\n        \n        private ProfilingResultsSupport.ResultsView results;\n    \n        \n        MasterViewSupport(final Application application, ProfilingResultsSupport profilingResultsView,\n                CPUSettingsSupport cpuSettingsSupport, MemorySettingsSupport memorySettingsSupport,\n                JDBCSettingsSupport jdbcSettingsSupport, LocksSettingsSupport locksSettingsSupport,\n                boolean classSharingBreaksProfiling) {\n            profiler = NetBeansProfiler.getDefaultNB();\n            this.application = application;\n            this.profilingResultsView = profilingResultsView;\n            this.cpuSettingsSupport = cpuSettingsSupport;\n            this.memorySettingsSupport = memorySettingsSupport;\n            this.jdbcSettingsSupport = jdbcSettingsSupport;\n            this.locksSettingsSupport = locksSettingsSupport;\n            this.classSharingBreaksProfiling = classSharingBreaksProfiling;\n            \n            initComponents();\n            initSettings();\n            refreshStatus();\n            \n            timer = new Timer(1000, this);\n            timer.setInitialDelay(1000);\n            \n            // TODO: should listen for PROPERTY_AVAILABLE instead of DataSource removal\n            application.notifyWhenRemoved(this);\n            application.addPropertyChangeListener(Stateful.PROPERTY_STATE, WeakListeners.propertyChange(this,application));\n        }\n        \n        \n        abstract void showCPUSettings();\n        \n        abstract void showMemorySettings();\n        \n        abstract void showJDBCSettings();\n        \n        \n        public DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(ApplicationProfilerView.class, \"LBL_Profiler\"), null, this);    // NOI18N\n        }\n        \n        public synchronized void dataRemoved(Application application) {\n            applicationTerminated = true;\n            timer.stop();\n            timer.removeActionListener(MasterViewSupport.this);\n            profiler.removeProfilingStateListener(MasterViewSupport.this);\n            ProfilerSupport.getInstance().setProfiledApplication(null);\n            lastInstrValue = -1;\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    resetControlButtons();\n                    disableControlButtons();\n                    statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_application_terminated\")); // NOI18N\n                    enableSettings();\n                }\n            });\n        }\n\n        public void propertyChange(PropertyChangeEvent evt) {\n            dataRemoved(application);\n        }\n\n        public void viewRemoved() {\n            timer.stop();\n            timer.removeActionListener(MasterViewSupport.this);\n            profiler.removeProfilingStateListener(MasterViewSupport.this);\n        }\n        \n        public void actionPerformed(ActionEvent e) {\n            if (results != null) results.refreshResults();\n            updateRunningText();\n        }\n\n        \n        private ProfilingResultsSupport.ResultsView getResultsView() {\n            if (cpuButton.isSelected()) return new CPULivePanel(application);\n            if (memoryButton.isSelected()) return new MemoryLivePanel(application);\n            if (jdbcButton.isSelected()) return new JDBCLivePanel(application);\n            if (locksButton.isSelected()) return new LocksLivePanel(application);\n            return null;\n        }\n        \n        private void handleCPUProfiling() {\n          if (internalChange) return;\n\n          if (cpuButton.isSelected())  {\n            internalChange = true;\n            memoryButton.setSelected(false);\n            jdbcButton.setSelected(false);\n            locksButton.setSelected(false);\n            internalChange = false;\n            if (!cpuSettingsSupport.settingsValid()) {\n                internalChange = true;\n                cpuButton.setSelected(false);\n                internalChange = false;\n                updateControlButtons();\n                showCPUSettings();\n                ProfilerDialogs.displayError(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_Incorrect_CPU_settings\")); // NOI18N\n            } else {\n                cpuSettingsSupport.saveSettings();\n                if (profiler.getProfilingState() == NetBeansProfiler.PROFILING_RUNNING) {\n                  ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                    public void run() { profiler.modifyCurrentProfiling(cpuSettingsSupport.getSettings()); }\n                  });\n                } else {\n                  disableControlButtons();\n                  ProfilerSupport.getInstance().setProfiledApplication(application);\n                  ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                    public void run() { startProfiling(application, cpuSettingsSupport.getSettings()); }\n                  });\n                }\n             }\n          }\n        }\n\n        private void handleMemoryProfiling() {\n          if (internalChange) return;\n\n          if (memoryButton.isSelected())  {\n            internalChange = true;\n            cpuButton.setSelected(false);\n            jdbcButton.setSelected(false);\n            locksButton.setSelected(false);\n            internalChange = false;\n            if (!memorySettingsSupport.settingsValid()) {\n                internalChange = true;\n                memoryButton.setSelected(false);\n                internalChange = false;\n                updateControlButtons();\n                showMemorySettings();\n                ProfilerDialogs.displayError(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_Incorrect_Memory_settings\")); // NOI18N\n            } else {\n              memorySettingsSupport.saveSettings();\n              if (  profiler.getProfilingState() == NetBeansProfiler.PROFILING_RUNNING) {\n                ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                  public void run() {\n                                profiler.modifyCurrentProfiling(memorySettingsSupport.getSettings()); \n                  }\n                });\n              } else {\n                disableControlButtons();\n                ProfilerSupport.getInstance().setProfiledApplication(application);\n                ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                  public void run() { startProfiling(application, memorySettingsSupport.getSettings()); }\n                });\n              }\n            }\n          }\n        }\n        \n        private void handleJDBCProfiling() {\n          if (internalChange) return;\n\n          if (jdbcButton.isSelected())  {\n            internalChange = true;\n            cpuButton.setSelected(false);\n            memoryButton.setSelected(false);\n            internalChange = false;\n            jdbcSettingsSupport.saveSettings();\n            if (profiler.getProfilingState() == NetBeansProfiler.PROFILING_RUNNING) {\n              ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                public void run() {\n                    profiler.modifyCurrentProfiling(jdbcSettingsSupport.getSettings()); \n                }\n              });\n            } else {\n              disableControlButtons();\n              ProfilerSupport.getInstance().setProfiledApplication(application);\n              ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                public void run() { startProfiling(application, jdbcSettingsSupport.getSettings()); }\n              });\n            }\n          }\n        }\n\n        private void handleLocksProfiling() {\n          if (internalChange) return;\n\n          if (locksButton.isSelected())  {\n            internalChange = true;\n            cpuButton.setSelected(false);\n            memoryButton.setSelected(false);\n            jdbcButton.setSelected(false);\n            internalChange = false;\n            locksSettingsSupport.saveSettings();\n            if (profiler.getProfilingState() == NetBeansProfiler.PROFILING_RUNNING) {\n              ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                public void run() {\n                    profiler.modifyCurrentProfiling(locksSettingsSupport.getSettings());\n                }\n              });\n            } else {\n              disableControlButtons();\n              ProfilerSupport.getInstance().setProfiledApplication(application);\n              ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {\n                public void run() { startProfiling(application, locksSettingsSupport.getSettings()); }\n              });\n            }\n          }\n        }\n        \n        private void startProfiling(Application application, ProfilingSettings pSettings) {\n          Runnable calibrationStartUpdater = new Runnable() {\n              public void run() {\n                  ProfilerDialogs.displayInfo(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_calibration\", VisualVM.getInstance().getOptionsHandle())); // NOI18N\n                  SwingUtilities.invokeLater(new Runnable() {\n                      public void run() {\n                          statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_calibration_progress\")); // NOI18N\n                      }\n                  });\n              }\n          };\n          if (CalibrationSupport.checkCalibration(application, calibrationStartUpdater, null)) {\n                profiler.addProfilingStateListener(this);\n                profiler.attachToApp(pSettings, attachSettings);\n          } else {\n              SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                  ProfilerSupport.getInstance().setProfiledApplication(null);\n                  statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_profiling_inactive\")); // NOI18N\n                  resetControlButtons();\n                  enableControlButtons();\n                }\n              });\n          }\n        }\n\n        private void handleStopProfiling() {\n          if (internalChange) return;\n\n          disableControlButtons();\n          ProfilerUtils.runInProfilerRequestProcessor(profiler::detachFromApp);\n        }\n\n\n        public void profilingStateChanged(ProfilingStateEvent e) { refreshStatus(); if (results != null) results.sessionStateChanged(e.getNewState()); }\n        public void threadsMonitoringChanged() { refreshStatus(); }\n        public void instrumentationChanged(int oldInstrType, int currentInstrType) { refreshStatus(); }\n        public void serverStateChanged(int serverState, int serverProgress) {}\n        public void lockContentionMonitoringChanged() {}\n        \n\n        private synchronized void refreshStatus() {\n\n          final int newState = profiler.getProfilingState();\n          final Application profiledApplication = ProfilerSupport.getInstance().getProfiledApplication();\n          if (state != newState) {\n            state = newState;\n            SwingUtilities.invokeLater(new Runnable() {\n              public void run() {\n                switch (state) {\n                  case NetBeansProfiler.PROFILING_INACTIVE:\n                    lastInstrValue = -1;\n                    if (!applicationTerminated) {\n                        timer.stop();\n                        profiler.removeProfilingStateListener(MasterViewSupport.this);\n                        if (results != null) results.cleanup();\n                        statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_profiling_inactive\"));    // NOI18N\n                        resetControlButtons();\n                        VisualVM.getInstance().runTask(new Runnable() {\n                          public void run() {\n                            ProfilerSupport.getInstance().setProfiledApplication(null);\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    enableControlButtons();\n                                    enableSettings();\n                                }\n                            });\n                          }\n                        }, 500); // Wait for the application to finish\n                    } else {\n                        ProfilerSupport.getInstance().setProfiledApplication(null);\n                    }\n                    break;\n                  case NetBeansProfiler.PROFILING_STARTED:\n                    timer.stop();\n                    disableControlButtons();\n                    disableSettings();\n                    statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_profiling_started\")); // NOI18N\n                    break;\n                  case NetBeansProfiler.PROFILING_PAUSED:\n                    timer.stop();\n                    statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_profiling_paused\"));   // NOI18N\n                    break;\n                  case NetBeansProfiler.PROFILING_IN_TRANSITION:\n                    timer.stop();\n                    statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_refreshing\")); // NOI18N\n                    disableControlButtons();\n                    disableSettings();\n                    break;\n                  case NetBeansProfiler.PROFILING_RUNNING:\n\n                    if (application.equals(profiledApplication)) {\n                      updateRunningText();\n                      timer.start();\n                      enableControlButtons();\n                      updateControlButtons();\n                      disableSettings();\n                      results = getResultsView();\n                      profilingResultsView.setProfilingResultsDisplay(results);\n                    } else {\n                      statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_profiling_of\") + ProfilerSupport.getInstance().getProfiledApplicationName() + NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_in_progress\"));  // NOI18N\n                      disableControlButtons();\n                      results = null;\n                      profilingResultsView.setProfilingResultsDisplay(results);\n                    }\n\n                    profilingResultsView.revalidate();\n                    profilingResultsView.repaint();\n                    revalidate();\n                    repaint();\n\n                    break;\n                  case NetBeansProfiler.PROFILING_STOPPED:\n                    timer.stop();\n                    statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_profiling_stopped\")); // NOI18N\n                    profiler.removeProfilingStateListener(MasterViewSupport.this);\n                    if (results != null) results.cleanup();\n                    break;\n                }\n              }\n            });\n          }\n        }\n\n        private void updateRunningText() {\n            ProfilingSettings currentSettings = profiler.getLastProfilingSettings();\n            int currentProfilingType = currentSettings != null ? currentSettings.getProfilingType() : Integer.MIN_VALUE;\n            if (cpuSettingsSupport.getSettings().getProfilingType() == currentProfilingType) {\n                int instrValue = TargetAppRunner.getDefault().getProfilingSessionStatus().getNInstrMethods();\n                if (lastInstrValue != instrValue)\n                    statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_profiling_running_methods\", instrValue)); // NOI18N\n                lastInstrValue = instrValue;\n            } else if (memorySettingsSupport.getSettings().getProfilingType() == currentProfilingType) {\n                int instrValue = TargetAppRunner.getDefault().getProfilingSessionStatus().getNInstrClasses();\n                if (lastInstrValue != instrValue) {\n                    int allocEvery = currentSettings.getAllocTrackEvery();\n                    switch (allocEvery) {\n                        case 1:\n                            statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_profiling_running_classes_1\", instrValue, allocEvery)); // NOI18N\n                            break;\n                        case 2:\n                            statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_profiling_running_classes_2\", instrValue, allocEvery)); // NOI18N\n                            break;\n                        case 3:\n                            statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_profiling_running_classes_3\", instrValue, allocEvery)); // NOI18N\n                            break;\n                        default:\n                            statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_profiling_running_classes_N\", instrValue, allocEvery)); // NOI18N\n                    }\n                }\n                    \n                lastInstrValue = instrValue;\n            } else if (jdbcSettingsSupport.getSettings().getProfilingType() == currentProfilingType) {\n                int instrValue = TargetAppRunner.getDefault().getProfilingSessionStatus().getNInstrMethods();\n                if (lastInstrValue != instrValue)\n                    statusValueLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_profiling_running_methods\", instrValue)); // NOI18N\n                lastInstrValue = instrValue;\n            }\n        }\n        \n        private void enableSettings() {\n            cpuSettingsSupport.setEnabled(true);\n            memorySettingsSupport.setEnabled(true);\n            jdbcSettingsSupport.setEnabled(true);\n        }\n        \n        private void disableSettings() {\n            cpuSettingsSupport.setEnabled(false);\n            memorySettingsSupport.setEnabled(false);\n            jdbcSettingsSupport.setEnabled(false);\n        }\n\n        private void resetControlButtons() {\n          internalChange = true;\n          cpuButton.setSelected(false);\n          memoryButton.setSelected(false);\n          jdbcButton.setSelected(false);\n          locksButton.setSelected(false);\n          internalChange = false;\n        }\n        \n        private void updateControlButtons() {\n            ProfilingSettings currentSettings = profiler.getLastProfilingSettings();\n            int currentProfilingType = currentSettings != null ? currentSettings.getProfilingType() : Integer.MIN_VALUE;\n            if (cpuSettingsSupport.getSettings().getProfilingType() == currentProfilingType && !cpuButton.isSelected()) {\n                internalChange = true;\n                cpuButton.setSelected(true);\n                memoryButton.setSelected(false);\n                jdbcButton.setSelected(false);\n                locksButton.setSelected(false);\n                internalChange = false;\n            } else if (memorySettingsSupport.getSettings().getProfilingType() == currentProfilingType && !memoryButton.isSelected()) {\n                internalChange = true;\n                cpuButton.setSelected(false);\n                memoryButton.setSelected(true);\n                jdbcButton.setSelected(false);\n                locksButton.setSelected(false);\n                internalChange = false;\n            } else if (jdbcSettingsSupport.getSettings().getProfilingType() == currentProfilingType && !jdbcButton.isSelected()) {\n                internalChange = true;\n                cpuButton.setSelected(false);\n                memoryButton.setSelected(false);\n                jdbcButton.setSelected(true);\n                locksButton.setSelected(false);\n                internalChange = false;\n            } else if (locksSettingsSupport.getSettings().getProfilingType() == currentProfilingType && !jdbcButton.isSelected()) {\n                internalChange = true;\n                cpuButton.setSelected(false);\n                memoryButton.setSelected(false);\n                jdbcButton.setSelected(false);\n                locksButton.setSelected(true);\n                internalChange = false;\n            }\n        }\n\n        private void enableControlButtons() {\n          boolean enabled = ProfilerSupport.getInstance().supportsProfiling(application);\n          cpuButton.setEnabled(enabled);\n          memoryButton.setEnabled(enabled);\n          jdbcButton.setEnabled(enabled);\n          locksButton.setEnabled(enabled);\n          stopButton.setEnabled(profiler.getTargetAppRunner().targetAppIsRunning());\n        }\n\n        private void disableControlButtons() {\n          cpuButton.setEnabled(false);\n          memoryButton.setEnabled(false);\n          jdbcButton.setEnabled(false);\n          locksButton.setEnabled(false);\n          stopButton.setEnabled(false);\n        }\n\n\n        private void initSettings() {\n          // Attach settings default\n          attachSettings = new AttachSettings();\n          attachSettings.setDirect(false);\n          attachSettings.setDynamic16(true);\n          attachSettings.setPid(application.getPid());\n          \n          ProfilerIDESettings.getInstance().setOOMDetectionMode(ProfilerIDESettings.OOME_DETECTION_NONE);\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            \n            JPanel controlPanel = new JPanel();\n              controlPanel.setOpaque(false);\n              controlPanel.setLayout(new GridBagLayout());\n              controlPanel.setBorder(BorderFactory.createEmptyBorder(6, 0, 3, 0));\n\n              GridBagConstraints constraints;\n\n              // classShareWarningLabel\n              classShareWarningArea = new HTMLTextArea() {\n                  protected void showURL(URL url) { \n                      try { DesktopUtils.browse(url.toURI()); } catch (Exception e) {}\n                  }\n              };\n              classShareWarningArea.setOpaque(true);\n              classShareWarningArea.setBackground(new java.awt.Color(255, 180, 180));\n              classShareWarningArea.setForeground(new java.awt.Color(0, 0, 0));\n              classShareWarningArea.setBorder(BorderFactory.createLineBorder(new java.awt.Color(180, 180, 180)));\n              classShareWarningArea.setBorder(BorderFactory.createCompoundBorder(classShareWarningArea.getBorder(),\n                      BorderFactory.createMatteBorder(5, 5, 5, 5, classShareWarningArea.getBackground())));\n              classShareWarningArea.setVisible(classSharingBreaksProfiling);\n              if (classSharingBreaksProfiling) {\n                  String link;\n                  if (DesktopUtils.isBrowseAvailable()) {\n                      link = NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_Class_Sharing_Link\");  // NOI18N\n                  } else {\n                      link = NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_Class_Sharing_Nolink\");    // NOI18N\n                  }\n                  String message = NbBundle.getMessage(ApplicationProfilerView.class, \"MSG_Class_Sharing\", link);   // NOI18N\n                  classShareWarningArea.setText(message);\n              }\n              constraints = new GridBagConstraints();\n              constraints.gridx = 0;\n              constraints.gridy = 1;\n              constraints.gridwidth = GridBagConstraints.REMAINDER;\n              constraints.fill = GridBagConstraints.HORIZONTAL;\n              constraints.anchor = GridBagConstraints.WEST;\n              constraints.insets = new Insets(4, 8, 10, 8);\n              controlPanel.add(classShareWarningArea, constraints);\n\n              // modeLabel\n              modeLabel = new JLabel(NbBundle.getMessage(ApplicationProfilerView.class, \"LBL_Sample\"));    // NOI18N\n              modeLabel.setFont(modeLabel.getFont().deriveFont(Font.BOLD));\n              Dimension d = modeLabel.getPreferredSize();\n              modeLabel.setText(NbBundle.getMessage(ApplicationProfilerView.class, \"LBL_Profile\")); // NOI18N\n              d.width = Math.max(d.width, modeLabel.getPreferredSize().width);\n              modeLabel.setPreferredSize(d);\n              modeLabel.setOpaque(false);\n              constraints = new GridBagConstraints();\n              constraints.gridx = 0;\n              constraints.gridy = 2;\n              constraints.gridwidth = 1;\n              constraints.fill = GridBagConstraints.NONE;\n              constraints.anchor = GridBagConstraints.WEST;\n              constraints.insets = new Insets(4, 8, 0, 0);\n              controlPanel.add(modeLabel, constraints);\n\n              // cpuButton\n              cpuButton = new OneWayToggleButton(NbBundle.getMessage(ApplicationProfilerView.class, \"LBL_Cpu\"));    // NOI18N\n              cpuButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/profiler/resources/cpu.png\", true))); // NOI18N\n              cpuButton.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) { handleCPUProfiling(); }\n              });\n              constraints = new GridBagConstraints();\n              constraints.gridx = 2;\n              constraints.gridy = 2;\n              constraints.gridwidth = 1;\n              constraints.fill = GridBagConstraints.NONE;\n              constraints.anchor = GridBagConstraints.WEST;\n              constraints.insets = new Insets(4, 8, 0, 0);\n              controlPanel.add(cpuButton, constraints);\n\n              // memoryButton\n              memoryButton = new OneWayToggleButton(NbBundle.getMessage(ApplicationProfilerView.class, \"LBL_Memory\"));  // NOI18N\n              memoryButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/profiler/resources/memory.png\", true)));   // NOI18N\n              memoryButton.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) { handleMemoryProfiling(); }\n              });\n              constraints = new GridBagConstraints();\n              constraints.gridx = 3;\n              constraints.gridy = 2;\n              constraints.gridwidth = 1;\n              constraints.fill = GridBagConstraints.NONE;\n              constraints.anchor = GridBagConstraints.WEST;\n              constraints.insets = new Insets(4, 8, 0, 0);\n              controlPanel.add(memoryButton, constraints);\n              \n              // jdbcButton\n              jdbcButton = new OneWayToggleButton(NbBundle.getMessage(ApplicationProfilerView.class, \"LBL_JDBC\"));  // NOI18N\n              jdbcButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/profiler/resources/jdbc.png\", true)));   // NOI18N\n              jdbcButton.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) { handleJDBCProfiling(); }\n              });\n              constraints = new GridBagConstraints();\n              constraints.gridx = 4;\n              constraints.gridy = 2;\n              constraints.gridwidth = 1;\n              constraints.fill = GridBagConstraints.NONE;\n              constraints.anchor = GridBagConstraints.WEST;\n              constraints.insets = new Insets(4, 8, 0, 0);\n              controlPanel.add(jdbcButton, constraints);\n\n              // locksButton\n              locksButton = new OneWayToggleButton(NbBundle.getMessage(ApplicationProfilerView.class, \"LBL_Locks\"));  // NOI18N\n              locksButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/profiler/resources/locks.png\", true)));   // NOI18N\n              locksButton.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) { handleLocksProfiling(); }\n              });\n              constraints = new GridBagConstraints();\n              constraints.gridx = 5;\n              constraints.gridy = 2;\n              constraints.gridwidth = 1;\n              constraints.fill = GridBagConstraints.NONE;\n              constraints.anchor = GridBagConstraints.WEST;\n              constraints.insets = new Insets(4, 8, 0, 0);\n              controlPanel.add(locksButton, constraints);\n\n              // stopButton\n              stopButton = new JButton(NbBundle.getMessage(ApplicationProfilerView.class, \"LBL_Stop\")); // NOI18N\n              stopButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/profiler/resources/stop.png\", true)));   // NOI18N\n              stopButton.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) { handleStopProfiling(); }\n              });\n              stopButton.setEnabled(false);\n              stopButton.setDefaultCapable(false); // Button size\n              constraints = new GridBagConstraints();\n              constraints.gridx = 6;\n              constraints.gridy = 2;\n              constraints.gridwidth = 1;\n              constraints.fill = GridBagConstraints.NONE;\n              constraints.anchor = GridBagConstraints.WEST;\n              constraints.insets = new Insets(4, 8, 0, 0);\n              controlPanel.add(stopButton, constraints);\n\n              // filler\n              JPanel filler1 = new JPanel(new BorderLayout());\n              filler1.setOpaque(false);\n              constraints = new GridBagConstraints();\n              constraints.gridx = 6;\n              constraints.gridy = 2;\n              constraints.weightx = 1;\n              constraints.weighty = 1;\n              constraints.gridwidth = GridBagConstraints.REMAINDER;\n              constraints.fill = GridBagConstraints.BOTH;\n              constraints.anchor = GridBagConstraints.NORTHWEST;\n              constraints.insets = new Insets(0, 0, 0, 0);\n              controlPanel.add(filler1, constraints);\n\n              // statusLabel\n              statusLabel = new JLabel(NbBundle.getMessage(ApplicationProfilerView.class, \"LBL_Status\"));   // NOI18N\n              statusLabel.setFont(statusLabel.getFont().deriveFont(Font.BOLD));\n              statusLabel.setOpaque(false);\n              constraints = new GridBagConstraints();\n              constraints.gridx = 0;\n              constraints.gridy = 3;\n              constraints.gridwidth = 1;\n              constraints.fill = GridBagConstraints.NONE;\n              constraints.anchor = GridBagConstraints.WEST;\n              constraints.insets = new Insets(6, 8, 4, 0);\n              controlPanel.add(statusLabel, constraints);\n\n              // statusValueLabel\n              statusValueLabel = new HTMLLabel() {\n                public void setText(String text) {\n                  super.setText(\"<nobr>\" + text + \"</nobr>\");   // NOI18N\n                }\n                protected void showURL(URL url) {\n                  ProfilerSupport.getInstance().selectActiveProfilerView();\n                }\n\n                // NOTE: overriding dimensions prevents UI \"jumping\" when changing the link\n                public Dimension getPreferredSize() { return new Dimension(super.getPreferredSize().width, refLabelHeight); }\n                public Dimension getMinimumSize() { return getPreferredSize(); }\n                public Dimension getMaximumSize() { return getPreferredSize(); }\n              };\n              statusValueLabel.setOpaque(false);\n              constraints = new GridBagConstraints();\n              constraints.gridx = 1;\n              constraints.gridy = 3;\n              constraints.gridwidth = GridBagConstraints.REMAINDER;\n              constraints.fill = GridBagConstraints.NONE;\n              constraints.anchor = GridBagConstraints.WEST;\n              constraints.insets = new Insets(6, 8, 4, 8);\n              controlPanel.add(statusValueLabel, constraints);\n\n              // filler\n              JPanel filler2 = new JPanel(new BorderLayout());\n              filler2.setOpaque(false);\n              constraints = new GridBagConstraints();\n              constraints.gridx = 2;\n              constraints.gridy = 3;\n              constraints.weightx = 1;\n              constraints.weighty = 1;\n              constraints.gridwidth = GridBagConstraints.REMAINDER;\n              constraints.fill = GridBagConstraints.BOTH;\n              constraints.anchor = GridBagConstraints.NORTHWEST;\n              constraints.insets = new Insets(0, 0, 0, 0);\n              controlPanel.add(filler2, constraints);\n            \n              Dimension cpuD     = cpuButton.getPreferredSize();\n              Dimension memoryD  = memoryButton.getPreferredSize();\n              Dimension jdbcD    = jdbcButton.getPreferredSize();\n              Dimension locksD   = locksButton.getPreferredSize();\n              Dimension stopD    = stopButton.getPreferredSize();\n\n              Dimension maxD = new Dimension(Math.max(cpuD.width, memoryD.width), Math.max(cpuD.height, memoryD.height));\n              maxD = new Dimension(Math.max(maxD.width, jdbcD.width), Math.max(maxD.height, jdbcD.height));\n              maxD = new Dimension(Math.max(maxD.width, locksD.width), Math.max(maxD.height, locksD.height));\n              maxD = new Dimension(Math.max(maxD.width, stopD.width), Math.max(maxD.height, stopD.height));\n\n              cpuButton.setPreferredSize(maxD);\n              cpuButton.setMinimumSize(maxD);\n              memoryButton.setPreferredSize(maxD);\n              memoryButton.setMinimumSize(maxD);\n              jdbcButton.setPreferredSize(maxD);\n              jdbcButton.setMinimumSize(maxD);\n              locksButton.setPreferredSize(maxD);\n              locksButton.setMinimumSize(maxD);\n              stopButton.setPreferredSize(maxD);\n              stopButton.setMinimumSize(maxD);\n            \n              setOpaque(false);\n              \n              setLayout(new BorderLayout());\n              setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));\n              add(controlPanel, BorderLayout.CENTER);\n        }\n        \n        private HTMLTextArea classShareWarningArea;\n        private JLabel modeLabel;\n        private JToggleButton cpuButton;\n        private JToggleButton memoryButton;\n        private JToggleButton jdbcButton;\n        private JToggleButton locksButton;\n        private JButton stopButton;\n        private JLabel statusLabel;\n        private HTMLLabel statusValueLabel;\n        private static final int refLabelHeight = new HTMLLabel(\"X\").getPreferredSize().height; // NOI18N\n\n    }\n    \n    private static final class OneWayToggleButton extends JToggleButton {\n    \n        OneWayToggleButton(String text) {\n          super(text);\n        }\n\n        protected void processMouseEvent(MouseEvent e) {\n          if (!isSelected()) super.processMouseEvent(e);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/ApplicationProfilerViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiler;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ApplicationProfilerViewProvider extends DataSourceViewProvider<Application>{\n    \n    protected boolean supportsViewFor(Application application) {\n        return ProfilerSupport.getInstance().supportsProfiling(application);\n    }\n\n    protected DataSourceView createView(Application application) {\n        return new ApplicationProfilerView(application);\n    }\n    \n    \n    DataSourceView view(Application application) {\n        return super.getView(application);\n    }\n    \n\n    void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(this, Application.class);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Profiler\n\nLBL_Profiler=Profiler\n\nLBL_Profiling_results=Profiling results\n\nMSG_application_terminated=application terminated\n\nMSG_profiling_inactive=profiling inactive\n\nMSG_profiling_started=profiling started\n\nMSG_profiling_paused=profiling paused\n\nMSG_refreshing=refreshing...\n\nMSG_calibration_progress=calibration in progress...\n\nMSG_calibration=<html><br><b>Profiler calibration will be performed.</b><br><br>The profiler will perform initial calibration of the target Java platform.<br>You can manage the calibration data using {0} | Profiling.</html>\n\nMSG_profiling_running_methods=profiling running ({0} methods instrumented)\n\n#MSG_profiling_running_classes_1=profiling running ({0} classes instrumented, tracking each object)\nMSG_profiling_running_classes_1=profiling running ({0} classes instrumented)\n\nMSG_profiling_running_classes_2=profiling running ({0} classes instrumented, tracking each 2nd object)\n\nMSG_profiling_running_classes_3=profiling running ({0} classes instrumented, tracking each 3rd object)\n\nMSG_profiling_running_classes_N=profiling running ({0} classes instrumented, tracking each {1}th object)\n\nMSG_profiling_of=<nobr>profiling of <a href='#'>\n\nMSG_in_progress=</a> in progress</nobr>\n\nMSG_profiling_stopped=profiling stopped\n\nMSG_Exclude_Java_Core_Classes=Exclude Java Core Classes\n\nMSG_Class_Sharing=<b>WARNING\\!</b> Class sharing is enabled for this JVM. This can cause problems when profiling the application and eventually may crash it. Please see the VisualVM Troubleshooting Guide for more information and steps to fix the problem: {0}.\n\nMSG_Class_Sharing_Link=<a href=\"https://visualvm.github.io/troubleshooting.html#xshare\">https://visualvm.github.io/troubleshooting.html#xshare</a>\n\nMSG_Class_Sharing_Nolink=<nobr>https://visualvm.github.io/troubleshooting.html#xshare</nobr>\n\nMSG_Incorrect_CPU_settings=Provided CPU settings are invalid.\n\nMSG_Incorrect_Memory_settings=Provided Memory settings are invalid.\n\nLBL_Profile=Profile\\:\nLBL_Sample=Sample\\:\n\nLBL_Cpu=CPU\n\nLBL_Memory=Memory\n\nLBL_JDBC=JDBC\n\nLBL_Locks=Locks\n\nLBL_Stop=Stop\n\nLBL_Status=Status:\n\nMSG_Profiling_results=Profiling results\n\nLBL_Snapshot=Snapshot\n\nMSG_Profile=&Profile\n\nDESCR_Profile=Profile\n\nMSG_Profiler_Snapshot=Prof&iler Snapshot\n\nDESCR_Profiler_Snapshot=Profiler Snapshot\n\nCAPTION_Calibration=VisualVM Calibration\nMSG_Calibration=<html><b>Calibration will be performed.</b><br><br>Profiler will perform initial JDK calibration. Please make sure that other applications<br>are not placing a noticeable load on your machine at this time and click the OK button.<br><br></html>\n\nLBL_Settings=Settings\n\nLBL_Cpu_settings=CPU settings\n\nLBL_Memory_settings=Memory settings\n\nLBL_JDBC_settings=JDBC settings\n\nLBL_Locks_settings=Locks settings\n\nCAP_Calibrate_java=Calibrate Java\n# Please select Java 7 64bit binary:\nMSG_Calibration_required_arch=The profiler will calibrate the Java platform to be used for profiling.<br>Please select {0} {1} binary:\n# Please select Java 7 binary:\nMSG_Calibration_required_noarch=The profiler will calibrate the Java platform to be used for profiling.<br>Please select {0} binary:\nCAP_Select_java_binary=Select Java Binary\n# Selected binary is not Java 7 64bit.\nMSG_Incorrect_java_binary_arch=Selected binary is not {0} {1}.\n# Selected binary is not Java 7.\nMSG_Incorrect_java_binary_noarch=Selected binary is not {0}.\n# Java Binary (java.exe)\nLBL_Java_file_filter=Java Binary ({0})\nBTN_Browse=&Browse\nBTN_Ok=OK\n\nSTR_Externally_started_app=externally started application\n# Java 7\nSTR_Java_platform_name=Java {0}\n# 64bit\nSTR_Java_arch_name={0}bit\nCAP_Warning=Warning\n# HTML-formatted\nMSG_StartedTooSoon=<html><b>Profiled application started too soon.</b><br><br>Please terminate the profiled application and<br>restart it after closing this dialog.</html>\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/CPULivePanel.java",
    "content": "/*\n *  Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.Icon;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.profiler.actions.ResetResultsAction;\nimport org.graalvm.visualvm.lib.profiler.actions.TakeSnapshotAction;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.cpu.LiveCPUView;\nimport org.graalvm.visualvm.lib.ui.cpu.LiveCPUViewUpdater;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.MultiButtonGroup;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.profiling.actions.ProfilerResultsAction;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"MethodsFeatureUI_selectedMethods=Selected methods\",\n    \"MethodsFeatureUI_liveResults=Results:\",\n    \"MethodsFeatureUI_pauseResults=Pause live results\",\n    \"MethodsFeatureUI_updateResults=Update live results\",\n    \"MethodsFeatureUI_view=View:\",\n    \"MethodsFeatureUI_viewForward=Forward calls\",\n    \"MethodsFeatureUI_viewHotSpots=Hot spots\",\n    \"MethodsFeatureUI_viewReverse=Reverse calls\",\n    \"MethodsFeatureUI_resultsMode=Results mode\",\n    \"MethodsFeatureUI_profilingData=Collected data:\",\n    \"MethodsFeatureUI_snapshot=Snapshot\",\n    \"MethodsFeatureUI_showAbsolute=Show absolute values\",\n    \"MethodsFeatureUI_showDeltas=Show delta values\"\n})\nclass CPULivePanel extends ProfilingResultsSupport.ResultsView {\n    \n    private ProfilerToolbar toolbar;\n    private LiveCPUView cpuView;\n    private LiveCPUViewUpdater updater;\n    private ProfilingResultsSupport.ResultsResetter resetter;\n    \n    \n    CPULivePanel(Application application) {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n        \n        initUI(application);\n        \n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        add(cpuView, BorderLayout.CENTER);\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    \n    void refreshResults() {\n        refreshResults(false);\n    }\n    \n    void resetResults() {\n        if (lrDeltasButton != null) {\n            lrDeltasButton.setSelected(false);\n            lrDeltasButton.setToolTipText(Bundle.MethodsFeatureUI_showDeltas());\n        }\n        if (cpuView != null) {\n            cpuView.resetData();\n            cpuView.setDiffView(false);\n        }\n    }\n    \n    void sessionStateChanged(int sessionState) {\n        refreshToolbar(sessionState);\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    \n    private void refreshResults(final boolean forceRefresh) {\n        RESULTS_PROCESSOR.post(new Runnable() {\n            public void run() {\n                try {\n                    if (updater != null) {\n                        if (forceRefresh) updater.setForceRefresh(true);\n                        updater.update();\n                    }\n//                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                } catch (Throwable t) {\n                    cleanup();\n                }\n            }\n        });\n    }\n\n    void cleanup() {\n        if (updater != null) {\n            updater.cleanup();\n            updater = null;\n        }\n\n        if (resetter != null) {\n            resetter.unregisterView(CPULivePanel.this);\n            resetter = null;\n        }\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    \n    private JLabel lrLabel;\n    private JToggleButton lrPauseButton;\n    private JButton lrRefreshButton;\n    private JToggleButton lrDeltasButton;\n    \n    private JLabel pdLabel;\n    private JButton pdSnapshotButton;\n    private JButton pdResetResultsButton;\n    \n    private boolean popupPause;\n    private JToggleButton[] toggles;\n    \n    \n    private void initUI(Application application) {\n        \n        assert SwingUtilities.isEventDispatchThread();\n        \n        // --- Results ---------------------------------------------------------\n        \n        cpuView = new LiveCPUView(null) {\n            protected boolean showSourceSupported() {\n                return GoToSource.isAvailable();\n            }\n            protected boolean profileMethodSupported() {\n                return false;\n            }\n            protected boolean profileClassSupported() {\n                return false;\n            }\n            protected void showSource(ClientUtils.SourceCodeSelection value) {\n//                Lookup.Provider project = getProject();\n                Lookup.Provider project = null;\n                String className = value.getClassName();\n                String methodName = value.getMethodName();\n                String methodSig = value.getMethodSignature();\n                GoToSource.openSource(project, className, methodName, methodSig);\n            }\n            protected void selectForProfiling(ClientUtils.SourceCodeSelection value) {\n//                MethodsFeatureUI.this.selectForProfiling(value);\n            }\n            protected void popupShowing() {\n                if (lrPauseButton.isEnabled() && !lrRefreshButton.isEnabled()) {\n                    popupPause = true;\n                    lrPauseButton.setSelected(true);\n                }\n            }\n            protected void popupHidden() {\n                if (lrPauseButton.isEnabled() && popupPause) {\n                    popupPause = false;\n                    lrPauseButton.setSelected(false);\n                }\n            }\n            protected void foundInForwardCalls() {\n                super.foundInForwardCalls();\n                toggles[0].setSelected(true);\n            }\n            protected void foundInHotSpots() {\n                super.foundInHotSpots();\n                toggles[1].setSelected(true);\n            }\n            protected void foundInReverseCalls() {\n                super.foundInReverseCalls();\n                toggles[2].setSelected(true);\n            }\n        };\n        cpuView.putClientProperty(\"HelpCtx.Key\", \"ProfileMethods.HelpCtx\"); // NOI18N\n        cpuView.putClientProperty(ProfilerResultsAction.PROP_APPLICATION, application);\n        \n        updater = new LiveCPUViewUpdater(cpuView, Profiler.getDefault().getTargetAppRunner().getProfilerClient());\n        resetter = ProfilingResultsSupport.ResultsResetter.registerView(this);\n        \n        InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        ActionMap actionMap = getActionMap();\n        \n        final String filterKey = FilterUtils.FILTER_ACTION_KEY;\n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                Action action = cpuView.getActionMap().get(filterKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);\n        \n        final String findKey = SearchUtils.FIND_ACTION_KEY;\n        Action findAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                Action action = cpuView.getActionMap().get(findKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(findKey, findAction, actionMap, inputMap);\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        lrLabel = new GrayLabel(Bundle.MethodsFeatureUI_liveResults());\n            \n        lrPauseButton = new JToggleButton(Icons.getIcon(GeneralIcons.PAUSE)) {\n            protected void fireItemStateChanged(ItemEvent event) {\n                boolean paused = isSelected();\n                if (updater != null) updater.setPaused(paused);\n                lrRefreshButton.setEnabled(paused && !popupPause);\n                if (!paused) refreshResults(true);\n            }\n        };\n        lrPauseButton.setToolTipText(Bundle.MethodsFeatureUI_pauseResults());\n        \n        lrRefreshButton = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                refreshResults(true);\n            }\n        };\n        lrRefreshButton.setToolTipText(Bundle.MethodsFeatureUI_updateResults());\n        lrRefreshButton.setEnabled(false);\n        \n        Icon icon = Icons.getIcon(ProfilerIcons.DELTA_RESULTS);\n        lrDeltasButton = new JToggleButton(icon) {\n            protected void fireActionPerformed(ActionEvent e) {\n                if (!cpuView.setDiffView(isSelected())) setSelected(false);\n                setToolTipText(isSelected() ? Bundle.MethodsFeatureUI_showAbsolute() :\n                                              Bundle.MethodsFeatureUI_showDeltas());\n            }\n        };\n        lrDeltasButton.setToolTipText(Bundle.MethodsFeatureUI_showDeltas());\n        \n        MultiButtonGroup group = new MultiButtonGroup();\n        toggles = new JToggleButton[3];\n        \n        JToggleButton forwardCalls = new JToggleButton(Icons.getIcon(ProfilerIcons.NODE_FORWARD)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                cpuView.setView(isSelected(), toggles[1].isSelected(), toggles[2].isSelected());\n                refreshResults(true);\n            }\n        };\n        forwardCalls.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        forwardCalls.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        forwardCalls.setToolTipText(Bundle.MethodsFeatureUI_viewForward());\n        group.add(forwardCalls);\n        toggles[0] = forwardCalls;\n        forwardCalls.setSelected(true);\n        \n        JToggleButton hotSpots = new JToggleButton(Icons.getIcon(ProfilerIcons.TAB_HOTSPOTS)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                cpuView.setView(toggles[0].isSelected(), isSelected(), toggles[2].isSelected());\n                refreshResults(true);\n            }\n        };\n        hotSpots.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        hotSpots.putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n        hotSpots.setToolTipText(Bundle.MethodsFeatureUI_viewHotSpots());\n        group.add(hotSpots);\n        toggles[1] = hotSpots;\n        hotSpots.setSelected(false);\n        \n        JToggleButton reverseCalls = new JToggleButton(Icons.getIcon(ProfilerIcons.NODE_REVERSE)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                cpuView.setView(toggles[0].isSelected(), toggles[1].isSelected(), isSelected());\n                refreshResults(true);\n            }\n        };\n        reverseCalls.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        reverseCalls.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n        reverseCalls.setToolTipText(Bundle.MethodsFeatureUI_viewReverse());\n        group.add(reverseCalls);\n        toggles[2] = reverseCalls;\n        reverseCalls.setSelected(false);\n\n        pdLabel = new GrayLabel(Bundle.MethodsFeatureUI_profilingData());\n\n        pdSnapshotButton = new JButton(TakeSnapshotAction.getInstance());\n//        pdSnapshotButton.setHideActionText(true);\n        pdSnapshotButton.setText(Bundle.MethodsFeatureUI_snapshot());\n        pdSnapshotButton.putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n\n        pdResetResultsButton = new JButton(ResetResultsAction.getInstance());\n        pdResetResultsButton.setHideActionText(true);\n\n        toolbar = ProfilerToolbar.create(true);\n\n//        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(lrLabel);\n        toolbar.addSpace(2);\n        toolbar.add(lrPauseButton);\n        toolbar.add(lrRefreshButton);\n        \n        toolbar.addSpace(5);\n        toolbar.add(lrDeltasButton);\n        \n        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n        toolbar.addSpace(5);\n        \n        toolbar.add(new GrayLabel(Bundle.MethodsFeatureUI_view()));\n        toolbar.addSpace(2);\n        toolbar.add(forwardCalls);\n        toolbar.add(hotSpots);\n        toolbar.add(reverseCalls);\n        \n        toolbar.addSpace(5);\n        toolbar.add(cpuView.createThreadSelector());\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(pdLabel);\n        toolbar.addSpace(2);\n        toolbar.add(pdSnapshotButton);\n        toolbar.addSpace(3);\n        toolbar.add(pdResetResultsButton);\n        \n        \n        cpuView.setView(true, false, false);\n        \n    }\n    \n    private void refreshToolbar(final int state) {\n        if (toolbar != null) SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                boolean running = state == Profiler.PROFILING_RUNNING;\n                lrPauseButton.setEnabled(running);\n                lrRefreshButton.setEnabled(!popupPause && running && lrPauseButton.isSelected());\n                lrDeltasButton.setEnabled(running);\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/CPUSettingsSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.profiling.presets.PresetSelector;\nimport org.graalvm.visualvm.profiling.presets.ProfilerCPUPanel;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPreset;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class CPUSettingsSupport extends ProfilerSettingsSupport {\n    \n    private JPanel container;\n    private ProfilerCPUPanel panel;\n    private PresetSelector selector;\n    \n    private DataViewComponent.DetailsView detailsView;\n    \n    \n    DataViewComponent.DetailsView getDetailsView() {\n        if (detailsView == null) {\n            detailsView = new DataViewComponent.DetailsView(NbBundle.getMessage(\n                          CPUSettingsSupport.class, \"LBL_Cpu_settings\"), null, 10, // NOI18N\n                          new ScrollableContainer(getComponent()), null);\n        }\n        return detailsView;\n    }\n    \n    public JComponent getComponent() {\n        if (container == null) createPanel();\n        return container;\n    }\n    \n    \n    public ProfilingSettings getSettings() { return panel.getSettings(); }\n    \n    void saveSettings() {\n        // NOTE: might save custom configuration here\n    }\n    \n    void updateSettings(ProfilerPreset preset) {\n        panel.loadFromPreset(preset);\n    }\n    \n    public abstract boolean presetValid();\n    \n    public boolean settingsValid() { return panel.settingsValid(); }\n    \n    public void showSettings(DataViewComponent dvc) {\n        panel.highlightInvalid();\n        dvc.selectDetailsView(getDetailsView());\n    }\n    \n    public abstract PresetSelector createSelector(Runnable presetSynchronizer);\n    \n    \n    public void setEnabled(boolean enabled) {\n        container.setEnabled(enabled);\n    }\n    \n    private JPanel createPanel() {\n        panel = new ProfilerCPUPanel() {\n            public void settingsChanged() {\n                panel.saveToPreset(selector.customize(presetValid()));\n            }\n        };\n        \n        selector = createSelector(new Runnable() {\n            public void run() { panel.loadFromPreset(selector.getSelectedPreset()); }\n        });\n        selector.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));\n        \n        container = new JPanel(new BorderLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents()) c.setEnabled(enabled);\n            }\n        };\n        container.setOpaque(false);\n        container.add(panel, BorderLayout.CENTER);\n        container.add(selector, BorderLayout.SOUTH);\n        \n        return container;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/CalibrationSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiler;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Properties;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerEngineSettings;\nimport org.graalvm.visualvm.lib.jfluid.TargetAppRunner;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CalibrationDataFileIO;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;\nimport org.graalvm.visualvm.lib.profiler.NetBeansProfiler;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class CalibrationSupport {\n    \n    private CalibrationSupport() {}\n\n    // --- Internal API --------------------------------------------------------\n    \n    static boolean checkCalibration(Application app, Runnable before, Runnable after) {\n        Jvm jvm = JvmFactory.getJVMFor(app);\n        if (!jvm.isGetSystemPropertiesSupported()) return false;\n        Properties properties = jvm.getSystemProperties();\n        if (properties == null) return false;\n        \n        String java = Platform.getJDKVersionString(properties.getProperty(\"java.version\"));  // NOI18N        \n        int arch = Platform.getSystemArchitecture(properties.getProperty(\"sun.arch.data.model\"));   // NOI18N\n        if (checkCalibration(java, arch)) return true;\n        \n        String executable = JavaInfo.getJDKExecutable(properties.getProperty(\"java.home\")); // NOI18N\n        return calibrate(executable, java, arch, before, after);\n    }\n    \n    static boolean checkCalibration(String java, int arch, Runnable before, Runnable after) {\n        if (checkCalibration(java, arch)) return true;\n        return calibrate(java, arch, before, after);\n    }\n    \n    static boolean calibrate(String java, int arch, Runnable before, Runnable after) {\n        return calibrate(null, java, arch, before, after);\n    }\n    \n    \n    // TODO: will be public in NetBeans 8.0: CalibrationDataFileIO.getCalibrationDataFileName(version)\n    static String getCalibrationDataFileName(String targetJDKVerString) {\n        String fileName = \"machinedata\" + \".\" + targetJDKVerString; // NOI18N\n        try { return Platform.getProfilerUserDir() + File.separator + fileName; }\n        catch (IOException ex) { return null; }\n    }\n    \n    \n    // --- Implementation ------------------------------------------------------\n    \n    private static boolean checkCalibration(String jdkString, int arch) {\n        ProfilingSessionStatus status = NetBeansProfiler.getDefaultNB().\n                getTargetAppRunner().getProfilingSessionStatus();\n        status.targetJDKVersionString = jdkString;\n        return CalibrationDataFileIO.readSavedCalibrationData(status) == 0;\n    }\n    \n    private static boolean calibrate(String executable, String java, int arch, Runnable before, Runnable after) {\n        boolean noarch = arch == -1;\n        File executableF = executable == null ? null : new File(executable);\n        \n        if (!isFile(executableF)) {\n            String javaName = ProfilerSupport.getJavaName(java);\n            String archName = noarch ? null : ProfilerSupport.getArchName(arch);\n            executable = JavaPlatformSelector.selectJavaBinary(javaName, archName,\n                                              java, noarch ? null : Integer.toString(arch));\n            \n            executableF = executable == null ? null : new File(executable);\n            if (!isFile(executableF)) return false;\n        }\n        \n        if (noarch) {\n            String[] archS = JavaInfo.getSystemProperties(executableF, \"sun.arch.data.model\"); // NOI18N\n            try { arch = Integer.parseInt(archS[0]); } catch (Exception e) {} // AIOOBE, NFE\n            if (arch == -1) return false;\n        }\n        \n        // Get ProfilerEngineSettings instance\n        TargetAppRunner runner = NetBeansProfiler.getDefaultNB().getTargetAppRunner();\n        if (runner == null) return false;\n        ProfilerEngineSettings pes = runner.getProfilerEngineSettings();\n\n        // Save current state\n        int savedPort = pes.getPortNo();\n        InstrumentationFilter savedInstrFilter = pes.getInstrumentationFilter();\n        String savedJVMExeFile = pes.getTargetJVMExeFile();\n        String savedJDKVersionString = pes.getTargetJDKVersionString();\n        int savedArch = pes.getSystemArchitecture();\n        String savedCP = pes.getMainClassPath();\n\n        // Setup ProfilerEngineSettings\n        pes.setTargetJVMExeFile(executable);\n        pes.setTargetJDKVersionString(java);\n        pes.setSystemArchitecture(arch);\n        pes.setPortNo(ProfilerIDESettings.getInstance().getCalibrationPortNo());\n        pes.setInstrumentationFilter(new InstrumentationFilter());\n        pes.setMainClassPath(\"\"); // NOI18N\n        \n        // Perform calibration\n        if (before != null) before.run();\n        boolean result = calibrateJVM();\n        if (after != null) after.run();\n        \n        // Restore original ProfilerEngineSettings\n        pes.setPortNo(savedPort);\n        pes.setInstrumentationFilter(savedInstrFilter);\n        pes.setTargetJDKVersionString(savedJDKVersionString);\n        pes.setSystemArchitecture(savedArch);\n        pes.setTargetJVMExeFile(savedJVMExeFile);\n        pes.setMainClassPath(savedCP);\n\n        return result;\n    }\n\n    private static boolean calibrateJVM() {\n        try {\n            return NetBeansProfiler.getDefaultNB().runConfiguredCalibration();\n        } catch (Exception e) {\n            System.err.println(\">>> Profiler calibration failed: \" + e.getMessage()); // NOI18N\n            e.printStackTrace(System.err);\n        }\n\n        return false;\n    }\n    \n    private static boolean isFile(File file) {\n        return file != null && file.isFile();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/DummyProjectProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiler;\n\nimport java.util.Set;\nimport javax.swing.Icon;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.profiler.spi.ProjectUtilitiesProvider;\nimport org.openide.filesystems.FileObject;\nimport org.openide.util.Lookup;\nimport org.openide.util.lookup.ServiceProvider;\n\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=ProjectUtilitiesProvider.class)\npublic class DummyProjectProvider extends ProjectUtilitiesProvider {\n    \n    private static Lookup.Provider[] EMPTY = new Lookup.Provider[0];\n    \n    public Icon getIcon(Lookup.Provider provider) {\n        throw new UnsupportedOperationException();\n    }\n\n    public Lookup.Provider getMainProject() {\n        return null;\n    }\n\n    public String getDisplayName(Lookup.Provider provider) {\n        throw new UnsupportedOperationException();\n    }\n\n    public FileObject getProjectDirectory(Lookup.Provider provider) {\n        throw new UnsupportedOperationException();\n    }\n\n    public Lookup.Provider[] getOpenedProjects() {\n        return EMPTY;\n    }\n\n    public boolean hasSubprojects(Lookup.Provider provider) {\n        throw new UnsupportedOperationException();\n    }\n\n    public void fetchSubprojects(Lookup.Provider project, Set<Lookup.Provider> subprojects) {\n        throw new UnsupportedOperationException();\n    }\n\n    public Lookup.Provider getProject(FileObject fileObject) {\n        throw new UnsupportedOperationException();\n    }\n\n    public void addOpenProjectsListener(ChangeListener changeListener) {\n    }\n\n    public void removeOpenProjectsListener(ChangeListener changeListener) {\n    }\n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/JDBCLivePanel.java",
    "content": "/*\n *  Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.profiler.actions.ResetResultsAction;\nimport org.graalvm.visualvm.lib.profiler.actions.TakeSnapshotAction;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.jdbc.LiveJDBCView;\nimport org.graalvm.visualvm.lib.ui.jdbc.LiveJDBCViewUpdater;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.profiling.actions.ProfilerResultsAction;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"JDBCLivePanel_SqlQueryCaption=SQL Query Viewer\",\n    \"JDBCLivePanel_SqlQueryLabel=SQL Query:\"\n})\nclass JDBCLivePanel extends ProfilingResultsSupport.ResultsView {\n    \n    private ProfilerToolbar toolbar;\n    private LiveJDBCView jdbcView;\n    private LiveJDBCViewUpdater updater;\n    private ProfilingResultsSupport.ResultsResetter resetter;\n    \n    \n    JDBCLivePanel(Application application) {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n        \n        initUI(application);\n        \n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        add(jdbcView, BorderLayout.CENTER);\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    \n    void refreshResults() {\n        refreshResults(false);\n    }\n    \n    void resetResults() {\n        if (lrDeltasButton != null) {\n            lrDeltasButton.setSelected(false);\n            lrDeltasButton.setToolTipText(Bundle.MethodsFeatureUI_showDeltas());\n        }\n        if (jdbcView != null) {\n            jdbcView.resetData();\n            jdbcView.setDiffView(false);\n        }\n    }\n    \n    void sessionStateChanged(int sessionState) {\n        refreshToolbar(sessionState);\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    \n    private void refreshResults(final boolean forceRefresh) {\n        RESULTS_PROCESSOR.post(new Runnable() {\n            public void run() {\n                try {\n                    if (updater != null) {\n                        if (forceRefresh) updater.setForceRefresh(true);\n                        updater.update();\n                    }\n//                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                } catch (Throwable t) {\n                    cleanup();\n                }\n            }\n        });\n    }\n\n    void cleanup() {\n        if (updater != null) {\n            updater.cleanup();\n            updater = null;\n        }\n\n        if (resetter != null) {\n            resetter.unregisterView(JDBCLivePanel.this);\n            resetter = null;\n        }\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    \n    private JLabel lrLabel;\n    private JToggleButton lrPauseButton;\n    private JButton lrRefreshButton;\n    private JToggleButton lrDeltasButton;\n//    private ActionPopupButton lrView;\n    \n    private JLabel pdLabel;\n    private JButton pdSnapshotButton;\n    private JButton pdResetResultsButton;\n    \n    private boolean popupPause;\n//    private JToggleButton[] toggles;\n    \n    \n    private void initUI(Application application) {\n        \n        assert SwingUtilities.isEventDispatchThread();\n        \n        // --- Results ---------------------------------------------------------\n        \n        jdbcView = new LiveJDBCView(null) {\n            protected boolean showSourceSupported() {\n                return GoToSource.isAvailable();\n            }\n            protected boolean profileMethodSupported() {\n                return false;\n            }\n            protected boolean profileClassSupported() {\n                return false;\n            }\n            protected void showSource(ClientUtils.SourceCodeSelection value) {\n//                Lookup.Provider project = getProject();\n                Lookup.Provider project = null;\n                String className = value.getClassName();\n                String methodName = value.getMethodName();\n                String methodSig = value.getMethodSignature();\n                GoToSource.openSource(project, className, methodName, methodSig);\n            }\n            protected void selectForProfiling(ClientUtils.SourceCodeSelection value) {\n//                MethodsFeatureUI.this.selectForProfiling(value);\n            }\n            protected void popupShowing() {\n                if (lrPauseButton.isEnabled() && !lrRefreshButton.isEnabled()) {\n                    popupPause = true;\n                    lrPauseButton.setSelected(true);\n                }\n            }\n            protected void popupHidden() {\n                if (lrPauseButton.isEnabled() && popupPause) {\n                    popupPause = false;\n                    lrPauseButton.setSelected(false);\n                }\n            }\n\n            protected ProfilerClient getProfilerClient() {\n                throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n            }\n\n            protected void showSQLQuery(String query, String htmlQuery) {\n                HTMLTextArea area = new HTMLTextArea(htmlQuery);\n                \n                JScrollPane areaScroll = new JScrollPane(area);\n                areaScroll.setPreferredSize(new Dimension(500, 250));\n                JLabel label = new JLabel(Bundle.JDBCLivePanel_SqlQueryLabel(), JLabel.LEADING);\n                label.setBorder(BorderFactory.createEmptyBorder(0, 0, 3, 0));\n                label.setLabelFor(area);\n                JPanel panel = new JPanel(new BorderLayout());\n                panel.add(label, BorderLayout.NORTH);\n                panel.add(areaScroll, BorderLayout.CENTER);\n                panel.setBorder(BorderFactory.createEmptyBorder(12, 10, 0, 10));\n//                HelpCtx help = new HelpCtx(\"SqlQueryViewer.HelpCtx\"); // NOI18N\n                DialogDisplayer.getDefault().notify(new DialogDescriptor(panel,\n                        Bundle.JDBCLivePanel_SqlQueryCaption(), false,\n                        new Object[] { DialogDescriptor.CLOSED_OPTION },\n                        DialogDescriptor.CLOSED_OPTION, DialogDescriptor.BOTTOM_ALIGN, null, null));\n            }\n        };\n        jdbcView.putClientProperty(\"HelpCtx.Key\", \"ProfileMethods.HelpCtx\"); // NOI18N\n        jdbcView.putClientProperty(ProfilerResultsAction.PROP_APPLICATION, application);\n        \n        updater = new LiveJDBCViewUpdater(jdbcView, Profiler.getDefault().getTargetAppRunner().getProfilerClient());\n//        updater = null;\n        resetter = ProfilingResultsSupport.ResultsResetter.registerView(this);\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        lrLabel = new GrayLabel(Bundle.MethodsFeatureUI_liveResults());\n            \n        lrPauseButton = new JToggleButton(Icons.getIcon(GeneralIcons.PAUSE)) {\n            protected void fireItemStateChanged(ItemEvent event) {\n                boolean paused = isSelected();\n                updater.setPaused(paused);\n                lrRefreshButton.setEnabled(paused && !popupPause);\n                if (!paused) refreshResults(true);\n            }\n        };\n        lrPauseButton.setToolTipText(Bundle.MethodsFeatureUI_pauseResults());\n\n        lrRefreshButton = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                refreshResults(true);\n            }\n        };\n        lrRefreshButton.setToolTipText(Bundle.MethodsFeatureUI_updateResults());\n        lrRefreshButton.setEnabled(false);\n        \n        Icon icon = Icons.getIcon(ProfilerIcons.DELTA_RESULTS);\n        lrDeltasButton = new JToggleButton(icon) {\n            protected void fireActionPerformed(ActionEvent e) {\n                if (!jdbcView.setDiffView(isSelected())) setSelected(false);\n                setToolTipText(isSelected() ? Bundle.MethodsFeatureUI_showAbsolute() :\n                                              Bundle.MethodsFeatureUI_showDeltas());\n            }\n        };\n        lrDeltasButton.setToolTipText(Bundle.MethodsFeatureUI_showDeltas());\n\n        pdLabel = new GrayLabel(Bundle.MethodsFeatureUI_profilingData());\n\n        pdSnapshotButton = new JButton(TakeSnapshotAction.getInstance());\n//        pdSnapshotButton.setHideActionText(true);\n        pdSnapshotButton.setText(Bundle.MethodsFeatureUI_snapshot());\n\n        pdResetResultsButton = new JButton(ResetResultsAction.getInstance());\n        pdResetResultsButton.setHideActionText(true);\n\n        toolbar = ProfilerToolbar.create(true);\n\n//        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(lrLabel);\n        toolbar.addSpace(2);\n        toolbar.add(lrPauseButton);\n        toolbar.add(lrRefreshButton);\n        \n        toolbar.addSpace(5);\n        toolbar.add(lrDeltasButton);\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(pdLabel);\n        toolbar.addSpace(2);\n        toolbar.add(pdSnapshotButton);\n        toolbar.addSpace(3);\n        toolbar.add(pdResetResultsButton);\n        \n    }\n    \n    private void refreshToolbar(final int state) {\n        if (toolbar != null) SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                boolean running = state == Profiler.PROFILING_RUNNING;\n                lrPauseButton.setEnabled(running);\n                lrRefreshButton.setEnabled(!popupPause && running && lrPauseButton.isSelected());\n                lrDeltasButton.setEnabled(running);\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/JDBCSettingsSupport.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.profiling.presets.PresetSelector;\nimport org.graalvm.visualvm.profiling.presets.ProfilerJDBCPanel;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPreset;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class JDBCSettingsSupport extends ProfilerSettingsSupport {\n    \n    private JPanel container;\n    private ProfilerJDBCPanel panel;\n    private PresetSelector selector;\n    \n    private DataViewComponent.DetailsView detailsView;\n    \n    \n    DataViewComponent.DetailsView getDetailsView() {\n        if (detailsView == null) {\n            detailsView = new DataViewComponent.DetailsView(NbBundle.getMessage(\n                          JDBCSettingsSupport.class, \"LBL_JDBC_settings\"), null, 30, // NOI18N\n                          new ScrollableContainer(getComponent()), null);\n        }\n        return detailsView;\n    }\n    \n    public JComponent getComponent() {\n        if (container == null) createPanel();\n        return container;\n    }\n    \n    \n    public ProfilingSettings getSettings() { return panel.getSettings(); }\n    \n    public void saveSettings() {\n        // NOTE: might save custom configuration here\n    }\n    \n    void updateSettings(ProfilerPreset preset) {\n        panel.loadFromPreset(preset);\n    }\n    \n    public abstract boolean presetValid();\n    \n    public boolean settingsValid() { return panel.settingsValid(); }\n    \n    public void showSettings(DataViewComponent dvc) {\n        dvc.selectDetailsView(getDetailsView());\n    }\n    \n    public abstract PresetSelector createSelector(Runnable presetSynchronizer);\n    \n    \n    public void setEnabled(boolean enabled) {\n        container.setEnabled(enabled);\n    }\n    \n    private JPanel createPanel() {\n        panel = new ProfilerJDBCPanel() {\n            public void settingsChanged() {\n                panel.saveToPreset(selector.customize(presetValid()));\n            }\n        };\n        \n        selector = createSelector(new Runnable() {\n            public void run() { panel.loadFromPreset(selector.getSelectedPreset()); }\n        });\n        selector.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));\n        \n        container = new JPanel(new BorderLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents()) c.setEnabled(enabled);\n            }\n        };\n        container.setOpaque(false);\n        container.add(panel, BorderLayout.CENTER);\n        container.add(selector, BorderLayout.SOUTH);\n        \n        return container;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/JavaInfo.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.profiler;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.InputStreamReader;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.openide.modules.InstalledFileLocator;\nimport org.openide.modules.ModuleInfo;\nimport org.openide.modules.Modules;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JavaInfo {\n    \n    static String getCurrentJDKExecutable() {\n        return getJDKExecutable(System.getProperty(\"java.home\")); // NOI18N\n    }\n    \n    static String getJDKExecutable(String jdkHome) {\n        if (jdkHome == null || jdkHome.trim().isEmpty()) return null;\n        String jreSuffix = File.separator + \"jre\"; // NOI18N\n        if (jdkHome.endsWith(jreSuffix)) jdkHome = jdkHome.substring(0, jdkHome.length() - jreSuffix.length());\n        String jdkExe = jdkHome + File.separator + \"bin\" + File.separator + \"java\" + (Platform.isWindows() ? \".exe\" : \"\"); // NOI18N\n        return jdkExe;\n    }    \n    \n    static String[] getSystemProperties(File java, String... keys) {\n        if (keys.length == 0) return new String[0];\n        \n        try {\n            List<String> list = new ArrayList<>();\n            list.add(java.getAbsolutePath());\n            list.add(\"-jar\"); // NOI18N\n            list.add(getProbeJar());\n            list.addAll(Arrays.asList(keys));\n\n            Process p = Runtime.getRuntime().exec(list.toArray(new String[0]));\n            \n            list.clear();\n            InputStreamReader isr = new InputStreamReader(p.getInputStream());\n            try (BufferedReader br = new BufferedReader(isr)) {\n                String line = br.readLine();\n                while (line != null) {\n                    list.add(line);\n                    line = br.readLine();\n                }\n            }\n            \n            return list.toArray(new String[0]);\n        } catch (Throwable t) {\n            System.err.println(\"Error getting system properties from \" + java.toString() + \": \" + t.getMessage()); // NOI18N\n            t.printStackTrace(System.err);\n            return null;\n        }\n    }\n    \n    \n    private static final String PROBE_PATH = \"modules/ext/profilerprobe.jar\";   // NOI18N\n    private static String PROBE_JAR;\n    private static synchronized String getProbeJar() {\n        if (PROBE_JAR == null) {\n            InstalledFileLocator loc = InstalledFileLocator.getDefault();\n            ModuleInfo info = Modules.getDefault().ownerOf(JavaInfo.class);\n            File jar = loc.locate(PROBE_PATH, info.getCodeNameBase(), false);\n            PROBE_JAR = jar.getAbsolutePath();\n        }\n        return PROBE_JAR;\n    }\n    \n    private JavaInfo() {}\n    \n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/JavaPlatformCache.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiler;\n\nimport java.util.prefs.Preferences;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class JavaPlatformCache {\n    \n    static void setBinary(String java, String arch, String binary) {\n        preferences().put(java + arch, binary);\n    }\n    \n    static String getBinary(String java, String arch) {\n        // Read cached Java binary\n        String binary = preferences().get(java + arch, null);\n        \n        // Try to get 64bit/32bit binary if arch doesn't matter\n        if (binary == null && arch == null) { // NOI18N\n            binary = getBinary(java, \"64\"); // NOI18N\n            if (binary == null) binary = getBinary(java, \"32\"); // NOI18N\n        }\n        \n        // Set current Java binary if compatible with provided settings\n        if (binary == null) {\n            if (arch == null || arch.equals(Integer.toString(Platform.getSystemArchitecture()))) {\n                if (Platform.getJDKVersionString().equals(java))\n                    binary = JavaInfo.getCurrentJDKExecutable();\n            }\n        }\n        \n        // Return the resolved binary\n        return binary;\n    }\n    \n    static void clearBinary(String java, String arch) {\n        preferences().remove(java + arch);\n    }\n    \n    private static Preferences preferences() {\n        return NbPreferences.forModule(JavaPlatformCache.class);\n    }\n    \n    private JavaPlatformCache() {}\n    \n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/JavaPlatformSelector.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.Color;\nimport java.awt.Dialog;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.Point;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.File;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JFileChooser;\nimport javax.swing.JPanel;\nimport javax.swing.JTextField;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.filechooser.FileFilter;\nimport javax.swing.text.Caret;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.windows.WindowManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass JavaPlatformSelector extends JPanel {\n\n  // NOTE: to be called outside of EDT\n  // TODO: fix updating UI outside of EDT\n  static String selectJavaBinary(String javaName, String archName, String java, String arch) {\n    JavaPlatformSelector hc = getDefault();\n    hc.setupSelectJavaPlatform(javaName, archName, java, arch);\n    \n    final DialogDescriptor dd = new DialogDescriptor(hc, NbBundle.getMessage(\n            JavaPlatformSelector.class, \"CAP_Calibrate_java\"), true, new Object[] { // NOI18N\n            hc.okButton, DialogDescriptor.CANCEL_OPTION }, hc.okButton, 0, null, null);\n    final Dialog d = DialogDisplayer.getDefault().createDialog(dd);\n    d.pack();\n    d.setVisible(true);\n    \n    if (dd.getValue() == hc.okButton) {\n        String javaBinary = hc.getJavaBinary();\n        File javaBinaryF = new File(javaBinary);\n        if (arch == null) {\n            String[] props = JavaInfo.getSystemProperties(javaBinaryF, \"java.version\"); // NOI18N\n            if (props == null || props.length < 1 ||\n                !java.equals(Platform.getJDKVersionString(props[0]))) {\n                notifyWrongBinary(javaName, archName);\n                javaBinary = null;\n            }\n        } else {\n            String[] props = JavaInfo.getSystemProperties(javaBinaryF, \"java.version\", \"sun.arch.data.model\"); // NOI18N\n            if (props == null || props.length < 2 ||\n                !java.equals(Platform.getJDKVersionString(props[0])) ||\n                !arch.equals(props[1])) {\n                notifyWrongBinary(javaName, archName);\n                javaBinary = null;\n            }\n        }\n        // Wrong java binary, select again until cancelled\n        if (javaBinary == null) return selectJavaBinary(javaName, archName, java, arch);\n        // Correct binary, remember it\n        if (javaBinaryF.isFile()) JavaPlatformCache.setBinary(java, arch, javaBinary);\n        // Return the correct binary\n        return javaBinary;\n    } else {\n        return null;\n    }\n  }\n  \n  private static void notifyWrongBinary(String javaName, String archName) {\n      String msg = archName != null ? NbBundle.getMessage(JavaPlatformSelector.class,\n                                      \"MSG_Incorrect_java_binary_arch\", javaName, archName) : // NOI18N\n                                      NbBundle.getMessage(JavaPlatformSelector.class,\n                                      \"MSG_Incorrect_java_binary_noarch\", javaName); // NOI18N\n      NotifyDescriptor nd = new NotifyDescriptor.Message(msg, NotifyDescriptor.WARNING_MESSAGE);\n      DialogDisplayer.getDefault().notify(nd);\n  }\n  \n  private String getJavaBinary() {\n    return javaPlatformFileField.getText().trim();\n  }\n  \n  private static JavaPlatformSelector defaultInstance;\n  \n  private JavaPlatformSelector() {\n    initComponents();\n    update();\n  }\n  \n  private static synchronized JavaPlatformSelector getDefault() {\n    if (defaultInstance == null) defaultInstance = new JavaPlatformSelector();\n    return defaultInstance;\n  }\n  \n  private void setupSelectJavaPlatform(String javaName, String archName, String java, String arch) {\n      if (archName != null) hintArea.setText(NbBundle.getMessage(JavaPlatformSelector.class,\n                                     \"MSG_Calibration_required_arch\", javaName, archName)); // NOI18N\n      else hintArea.setText(NbBundle.getMessage(JavaPlatformSelector.class,\n                                     \"MSG_Calibration_required_noarch\", javaName)); // NOI18N\n      \n      String binary = JavaPlatformCache.getBinary(java, arch);\n      if (binary == null || !new File(binary).isFile()) {\n          javaPlatformFileField.setText(\"\"); // NOI18N\n          if (binary != null) JavaPlatformCache.clearBinary(java, arch);\n      } else {\n          javaPlatformFileField.setText(binary);\n      }\n      \n      SwingUtilities.invokeLater(new Runnable() {\n          public void run() {\n              javaPlatformFileField.selectAll();\n              javaPlatformFileField.requestFocusInWindow();\n          }\n      });\n  }\n  \n  private void update() {\n    SwingUtilities.invokeLater(new Runnable() {\n      public void run() {\n        File snapshotFile = new File(getJavaBinary());\n        okButton.setEnabled(snapshotFile.isFile());\n      }\n    });\n  }\n\n  private void chooseSnapshot() {\n    JFileChooser chooser = new JFileChooser();\n    chooser.putClientProperty(\"JFileChooser.packageIsTraversable\", \"always\");   // NOI18N\n    chooser.setDialogTitle(NbBundle.getMessage(\n            JavaPlatformSelector.class, \"CAP_Select_java_binary\")); // NOI18N\n    chooser.setSelectedFile(new File(getJavaBinary()));\n    if (Platform.isWindows()) {\n      chooser.setAcceptAllFileFilterUsed(false);\n      chooser.setFileFilter(new FileFilter() {\n          private String java = \"java.exe\"; // NOI18N\n          public boolean accept(File f) {\n              return f.isDirectory() || (f.isFile() && java.equals(f.getName()));\n          }\n          public String getDescription() {\n              return NbBundle.getMessage(JavaPlatformSelector.class,\n                      \"LBL_Java_file_filter\", java); // NOI18N\n          }\n      });\n    } else {\n      chooser.setAcceptAllFileFilterUsed(false);\n      chooser.setFileFilter(new FileFilter() {\n          private String java = \"java\"; // NOI18N\n          public boolean accept(File f) {\n              return f.isDirectory() || (f.isFile() && java.equals(f.getName())); // NOI18N\n          }\n          public String getDescription() {\n              return NbBundle.getMessage(JavaPlatformSelector.class,\n                      \"LBL_Java_file_filter\", java); // NOI18N\n          }\n      });\n    }\n    if (chooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION)\n        javaPlatformFileField.setText(chooser.getSelectedFile().getAbsolutePath());\n  }\n  \n  private void initComponents() {\n    setLayout(new GridBagLayout());\n    GridBagConstraints constraints;\n    \n    // snapshotFileLabel\n    hintArea = new HTMLTextArea();\n    hintArea.setOpaque(false);\n    if (UISupport.isNimbusLookAndFeel()) hintArea.setBackground(new Color(0, 0, 0, 0));\n    hintArea.setCaret(new NullCaret());\n    hintArea.setBorder(BorderFactory.createEmptyBorder());\n    hintArea.setFocusable(false);\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 0;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.BOTH;\n    constraints.anchor = GridBagConstraints.NORTHWEST;\n    constraints.insets = new Insets(15, 10, 0, 10);\n    add(hintArea, constraints);\n    \n    // snapshotFileField\n    javaPlatformFileField = new JTextField();\n    javaPlatformFileField.setPreferredSize(new Dimension(220, javaPlatformFileField.getPreferredSize().height));\n    javaPlatformFileField.getDocument().addDocumentListener(new DocumentListener() {\n      public void insertUpdate(DocumentEvent e)  { update(); }\n      public void removeUpdate(DocumentEvent e)  { update(); }\n      public void changedUpdate(DocumentEvent e) { update(); }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 1;\n    constraints.gridy = 1;\n    constraints.weightx = 1;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.HORIZONTAL;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(15, 10, 0, 0);\n    add(javaPlatformFileField, constraints);\n    \n    // snapshotFileButton\n    snapshotFileButton = new JButton();\n    Mnemonics.setLocalizedText(snapshotFileButton, NbBundle.getMessage(\n            JavaPlatformSelector.class, \"BTN_Browse\")); // NOI18N\n    snapshotFileButton.addActionListener(new ActionListener() {\n        public void actionPerformed(ActionEvent e) {\n            chooseSnapshot();\n        }\n    });\n    constraints = new GridBagConstraints();\n    constraints.gridx = 2;\n    constraints.gridy = 1;\n    constraints.gridwidth = 1;\n    constraints.fill = GridBagConstraints.NONE;\n    constraints.anchor = GridBagConstraints.WEST;\n    constraints.insets = new Insets(15, 5, 0, 10);\n    add(snapshotFileButton, constraints);\n    \n    // spacer\n    constraints = new GridBagConstraints();\n    constraints.gridx = 0;\n    constraints.gridy = 2;\n    constraints.weighty = 1;\n    constraints.gridwidth = GridBagConstraints.REMAINDER;\n    constraints.fill = GridBagConstraints.BOTH;\n    constraints.anchor = GridBagConstraints.NORTHWEST;\n    constraints.insets = new Insets(0, 0, 15, 0);\n    add(Spacer.create(), constraints);\n    \n    // okButton\n    okButton = new JButton(NbBundle.getMessage(JavaPlatformSelector.class, \"BTN_Ok\")); // NOI18N\n  }\n  \n  private HTMLTextArea hintArea;\n  private JTextField javaPlatformFileField;\n  private JButton snapshotFileButton;\n  \n  private JButton okButton;\n  \n  \n  private static final class NullCaret implements Caret {\n        public void install(javax.swing.text.JTextComponent c) {}\n        public void deinstall(javax.swing.text.JTextComponent c) {}\n        public void paint(Graphics g) {}\n        public void addChangeListener(ChangeListener l) {}\n        public void removeChangeListener(ChangeListener l) {}\n        public boolean isVisible() { return false; }\n        public void setVisible(boolean v) {}\n        public boolean isSelectionVisible() { return false; }\n        public void setSelectionVisible(boolean v) {}\n        public void setMagicCaretPosition(Point p) {}\n        public Point getMagicCaretPosition() { return new Point(0, 0); }\n        public void setBlinkRate(int rate) {}\n        public int getBlinkRate() { return 0; }\n        public int getDot() { return 0; }\n        public int getMark() { return 0; }\n        public void setDot(int dot) {}\n        public void moveDot(int dot) {}\n    }\n  \n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/LocksLivePanel.java",
    "content": "/*\n *  Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.jfluid.ProfilerClient;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.locks.LiveLocksViewUpdater;\nimport org.graalvm.visualvm.lib.ui.locks.LockContentionPanel;\nimport org.graalvm.visualvm.lib.ui.swing.ActionPopupButton;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.profiling.actions.ProfilerResultsAction;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\n@NbBundle.Messages({\n    \"LocksFeatureUI_show=View by:\",\n    \"LocksFeatureUI_aggregationByThreads=Threads\",\n    \"LocksFeatureUI_aggregationByMonitors=Monitors\",\n    \"LocksFeatureUI_aggregationHint=Results aggregation\"\n})\nclass LocksLivePanel extends ProfilingResultsSupport.ResultsView {\n\n    private ProfilerToolbar toolbar;\n    private LockContentionPanel locksView;\n    private LiveLocksViewUpdater updater;\n    private ProfilingResultsSupport.ResultsResetter resetter;\n\n    LocksLivePanel(Application application) {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n\n        initUI(application);\n\n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        add(locksView, BorderLayout.CENTER);\n    }\n\n    // -------------------------------------------------------------------------\n    void refreshResults() {\n        refreshResults(false);\n    }\n\n    void resetResults() {\n        if (locksView != null) {\n            locksView.resetData();\n        }\n    }\n\n    void sessionStateChanged(int sessionState) {\n        refreshToolbar(sessionState);\n    }\n\n    // -------------------------------------------------------------------------\n    private void refreshResults(final boolean forceRefresh) {\n        RESULTS_PROCESSOR.post(new Runnable() {\n            public void run() {\n                try {\n                    if (updater != null) {\n                        if (forceRefresh) {\n                            updater.setForceRefresh(true);\n                        }\n                        updater.update();\n                    }\n//                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                } catch (Throwable t) {\n                    cleanup();\n                }\n            }\n        });\n    }\n\n    void cleanup() {\n        if (updater != null) {\n            updater.cleanup();\n            updater = null;\n        }\n\n        if (resetter != null) {\n            resetter.unregisterView(LocksLivePanel.this);\n            resetter = null;\n        }\n    }\n\n    // -------------------------------------------------------------------------\n    private JLabel lrLabel;\n    private JToggleButton lrPauseButton;\n    private JButton lrRefreshButton;\n\n    private boolean popupPause;\n\n    private JLabel shLabel;\n    private ActionPopupButton shAggregation;\n\n    private void initUI(Application application) {\n\n        assert SwingUtilities.isEventDispatchThread();\n\n        // --- Results ---------------------------------------------------------\n        locksView = new LockContentionPanel() {\n            protected boolean showSourceSupported() {\n                return GoToSource.isAvailable();\n            }\n\n            protected boolean profileMethodSupported() {\n                return false;\n            }\n\n            protected boolean profileClassSupported() {\n                return false;\n            }\n\n            protected void showSource(ClientUtils.SourceCodeSelection value) {\n                Lookup.Provider project = null;\n                String className = value.getClassName();\n                String methodName = value.getMethodName();\n                String methodSig = value.getMethodSignature();\n                GoToSource.openSource(project, className, methodName, methodSig);\n            }\n\n            protected void selectForProfiling(ClientUtils.SourceCodeSelection value) {\n            }\n\n            protected void popupShowing() {\n                if (lrPauseButton.isEnabled() && !lrRefreshButton.isEnabled()) {\n                    popupPause = true;\n                    lrPauseButton.setSelected(true);\n                }\n            }\n\n            protected void popupHidden() {\n                if (lrPauseButton.isEnabled() && popupPause) {\n                    popupPause = false;\n                    lrPauseButton.setSelected(false);\n                }\n            }\n\n            protected ProfilerClient getProfilerClient() {\n                throw new UnsupportedOperationException(\"Not supported yet.\"); // NOI18N\n            }\n\n            protected void showSQLQuery(String query, String htmlQuery) {\n                HTMLTextArea area = new HTMLTextArea(htmlQuery);\n\n                JScrollPane areaScroll = new JScrollPane(area);\n                areaScroll.setPreferredSize(new Dimension(500, 250));\n                JLabel label = new JLabel(Bundle.JDBCLivePanel_SqlQueryLabel(), JLabel.LEADING);\n                label.setBorder(BorderFactory.createEmptyBorder(0, 0, 3, 0));\n                label.setLabelFor(area);\n                JPanel panel = new JPanel(new BorderLayout());\n                panel.add(label, BorderLayout.NORTH);\n                panel.add(areaScroll, BorderLayout.CENTER);\n                panel.setBorder(BorderFactory.createEmptyBorder(12, 10, 0, 10));\n                DialogDisplayer.getDefault().notify(new DialogDescriptor(panel,\n                        Bundle.JDBCLivePanel_SqlQueryCaption(), false,\n                        new Object[]{DialogDescriptor.CLOSED_OPTION},\n                        DialogDescriptor.CLOSED_OPTION, DialogDescriptor.BOTTOM_ALIGN, null, null));\n            }\n        };\n        locksView.lockContentionEnabled();\n        locksView.putClientProperty(\"HelpCtx.Key\", \"ProfileMethods.HelpCtx\"); // NOI18N\n        locksView.putClientProperty(ProfilerResultsAction.PROP_APPLICATION, application);\n\n        updater = new LiveLocksViewUpdater(locksView, Profiler.getDefault().getTargetAppRunner().getProfilerClient());\n        resetter = ProfilingResultsSupport.ResultsResetter.registerView(this);\n\n        // --- Toolbar ---------------------------------------------------------\n        lrLabel = new GrayLabel(Bundle.MethodsFeatureUI_liveResults());\n\n        lrPauseButton = new JToggleButton(Icons.getIcon(GeneralIcons.PAUSE)) {\n            protected void fireItemStateChanged(ItemEvent event) {\n                boolean paused = isSelected();\n                updater.setPaused(paused);\n                lrRefreshButton.setEnabled(paused && !popupPause);\n                if (!paused) {\n                    refreshResults(true);\n                }\n            }\n        };\n        lrPauseButton.setToolTipText(Bundle.MethodsFeatureUI_pauseResults());\n\n        lrRefreshButton = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                refreshResults(true);\n            }\n        };\n        lrRefreshButton.setToolTipText(Bundle.MethodsFeatureUI_updateResults());\n        lrRefreshButton.setEnabled(false);\n\n        toolbar = ProfilerToolbar.create(true);\n\n        toolbar.addSpace(5);\n\n        toolbar.add(lrLabel);\n        toolbar.addSpace(2);\n        toolbar.add(lrPauseButton);\n        toolbar.add(lrRefreshButton);\n\n        toolbar.addSpace(5);\n\n        toolbar.addSpace(2);\n        shLabel = new GrayLabel(Bundle.LocksFeatureUI_show());\n\n        Action aThreads = new AbstractAction() {\n            {\n                putValue(NAME, Bundle.LocksFeatureUI_aggregationByThreads());\n            }\n\n            public void actionPerformed(ActionEvent e) {\n                locksView.setAggregation(LockContentionPanel.Aggregation.BY_THREADS);\n            }\n\n        };\n        Action aMonitors = new AbstractAction() {\n            {\n                putValue(NAME, Bundle.LocksFeatureUI_aggregationByMonitors());\n            }\n\n            public void actionPerformed(ActionEvent e) {\n                locksView.setAggregation(LockContentionPanel.Aggregation.BY_MONITORS);\n            }\n\n        };\n        shAggregation = new ActionPopupButton(aThreads, aMonitors);\n        shAggregation.setToolTipText(Bundle.LocksFeatureUI_aggregationHint());\n        toolbar.add(shLabel);\n        toolbar.addSpace(2);\n        toolbar.add(shAggregation);\n\n        toolbar.addSpace(2);\n    }\n\n    private void refreshToolbar(final int state) {\n        if (toolbar != null) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    boolean running = state == Profiler.PROFILING_RUNNING;\n                    lrPauseButton.setEnabled(running);\n                    lrRefreshButton.setEnabled(!popupPause && running && lrPauseButton.isSelected());\n                }\n            });\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/LocksSettingsSupport.java",
    "content": "/*\n * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.profiling.presets.PresetSelector;\nimport org.graalvm.visualvm.profiling.presets.ProfilerLocksPanel;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPreset;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic abstract class LocksSettingsSupport extends ProfilerSettingsSupport {\n\n    private JPanel container;\n    private ProfilerLocksPanel panel;\n    private PresetSelector selector;\n\n    private DataViewComponent.DetailsView detailsView;\n\n    DataViewComponent.DetailsView getDetailsView() {\n        if (detailsView == null) {\n            detailsView = new DataViewComponent.DetailsView(NbBundle.getMessage(\n                    LocksSettingsSupport.class, \"LBL_Locks_settings\"), null, 30, // NOI18N\n                    new ScrollableContainer(getComponent()), null);\n        }\n        return detailsView;\n    }\n\n    public JComponent getComponent() {\n        if (container == null) {\n            createPanel();\n        }\n        return container;\n    }\n\n    public ProfilingSettings getSettings() {\n        getComponent();\n        return panel.getSettings();\n    }\n\n    public void saveSettings() {\n        // NOTE: might save custom configuration here\n    }\n\n    void updateSettings(ProfilerPreset preset) {\n        getComponent();\n        panel.loadFromPreset(preset);\n    }\n\n    public abstract boolean presetValid();\n\n    public boolean settingsValid() {\n        getComponent();\n        return panel.settingsValid();\n    }\n\n    public void showSettings(DataViewComponent dvc) {\n        dvc.selectDetailsView(getDetailsView());\n    }\n\n    public abstract PresetSelector createSelector(Runnable presetSynchronizer);\n\n    public void setEnabled(boolean enabled) {\n        getComponent();\n        container.setEnabled(enabled);\n    }\n\n    private JPanel createPanel() {\n        panel = new ProfilerLocksPanel() {\n            public void settingsChanged() {\n                panel.saveToPreset(selector.customize(presetValid()));\n            }\n        };\n\n        selector = createSelector(new Runnable() {\n            public void run() {\n                panel.loadFromPreset(selector.getSelectedPreset());\n            }\n        });\n        selector.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));\n\n        container = new JPanel(new BorderLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents()) {\n                    c.setEnabled(enabled);\n                }\n            }\n        };\n        container.setOpaque(false);\n        container.add(panel, BorderLayout.CENTER);\n        container.add(selector, BorderLayout.SOUTH);\n\n        return container;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/ManageCalibration.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport java.io.File;\nimport java.text.DateFormat;\nimport java.util.Calendar;\nimport java.util.Date;\nimport javax.swing.AbstractAction;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTable;\nimport javax.swing.KeyStroke;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\nimport javax.swing.table.DefaultTableCellRenderer;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.TableColumn;\nimport javax.swing.table.TableColumnModel;\nimport javax.swing.table.TableModel;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.profiling.presets.ProfilingOptionsSectionProvider;\nimport org.openide.DialogDescriptor;\nimport org.openide.DialogDisplayer;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service = ProfilingOptionsSectionProvider.class)\n@NbBundle.Messages({\n    \"CAP_SectionName=Profiler Calibration\",\n    \"HINT_RunCalibrationAction=Manage Calibration Data\",\n    \"LBL_ManageCalibration=Manage calibration data:\",\n    \"BTN_ManageCalibration=&Manage\",\n    \"LBL_JavaPlatform=Java Platform\",\n    \"LBL_LastCalibrated=Last Calibrated\",\n    \"LBL_NotCalibrated=Not calibrated\",\n    \"LBL_JavaPlatformsForProfiling=&Java platforms supported for profiling:\",\n    \"LBL_Calibrate=&Calibrate\",\n    \"LBL_JavaPlatforms=Java &Platforms...\",\n    \"MSG_CalibrationOnProfile=Profiling session is currently in progress.\\nDo you want to stop the current session and perform the calibration?\",\n    \"MSG_CalibrationOnAttach=Profiling session is currently in progress\\nDo you want to detach from the target application and perform the calibration?\",\n    \"MSG_CalibrationFailed=Calibration failed.\\nPlease check your setup and run the calibration again.\"\n})\npublic final class ManageCalibration extends ProfilingOptionsSectionProvider {\n\n    public String getSectionName() {\n        return Bundle.CAP_SectionName();\n    }\n\n    public Component getSection() {\n        JPanel container = new JPanel(new BorderLayout());\n\n        JLabel label = new JLabel();\n        Mnemonics.setLocalizedText(label, Bundle.LBL_ManageCalibration()); // NOI18N\n        container.add(label, BorderLayout.CENTER);\n\n        JButton button = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                manageCalibration();\n            }\n        };\n        Mnemonics.setLocalizedText(button, Bundle.BTN_ManageCalibration()); // NOI18N\n        container.add(button, BorderLayout.EAST);\n        \n        return container;\n    }\n    \n    private void manageCalibration() {\n        String[] columnNames = new String[] { Bundle.LBL_JavaPlatform(),\n                                              Bundle.LBL_LastCalibrated() };\n        final TableModel model = new DefaultTableModel(createData(), columnNames) {\n            public boolean isCellEditable(int row, int column) {\n                return false;\n            }\n        };\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { displayUI(model); }\n        });\n    }\n    \n    private void displayUI(final TableModel model) {\n        final JTable table = new JTable(model);\n        table.setShowHorizontalLines(false);\n        table.setShowVerticalLines(true);\n        table.setGridColor(Color.LIGHT_GRAY);\n        table.setFillsViewportHeight(true);\n        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        \n        TableColumnModel columns = table.getColumnModel();\n        final TableColumn status = columns.getColumn(1);\n        status.setCellRenderer(new CalibrationDateCellRenderer());\n        table.setPreferredScrollableViewportSize(new Dimension(350, table.getRowHeight() * 4));\n        \n        JPanel container = new JPanel(new BorderLayout());\n        container.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));\n        container.add(new JScrollPane(table));\n        \n        JLabel label = new JLabel();\n        Mnemonics.setLocalizedText(label, Bundle.LBL_JavaPlatformsForProfiling());\n        label.setLabelFor(table);\n        label.setBorder(BorderFactory.createEmptyBorder(15, 10, 5, 10));\n        \n        final JButton calibrate = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) { calibrate(table); }\n        };\n        Mnemonics.setLocalizedText(calibrate, Bundle.LBL_Calibrate());\n        \n        table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(\n                KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), \"DEFAULT_ACTION\"); // NOI18N\n        table.getActionMap().put(\"DEFAULT_ACTION\", new AbstractAction() { // NOI18N\n                    public void actionPerformed(ActionEvent e) { calibrate(table); }\n                });\n        table.addMouseListener(new MouseAdapter() {\n            public void mouseClicked(MouseEvent e) {\n                if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2)\n                    calibrate(table);\n            }\n        });\n        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {\n            public void valueChanged(ListSelectionEvent e) {\n                calibrate.setEnabled(table.getSelectedRow() != -1);\n            }\n        });\n        calibrate.setEnabled(false);\n        table.clearSelection();\n        \n        JPanel panel = new JPanel(new BorderLayout());\n        panel.add(label, BorderLayout.NORTH);\n        panel.add(container, BorderLayout.CENTER);\n        \n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() { refreshTimes(table); }\n        });\n        \n        DialogDescriptor dd = new DialogDescriptor(panel,\n                Bundle.HINT_RunCalibrationAction(), true,\n                new Object[] { DialogDescriptor.CLOSED_OPTION },\n                DialogDescriptor.CLOSED_OPTION, 0, null, null);\n        dd.setAdditionalOptions(new Object[] { calibrate });\n        DialogDisplayer.getDefault().createDialog(dd).setVisible(true);\n    }\n    \n    private void calibrate(final JTable table) {\n        final int row = table.getSelectedRow();\n        if (row == -1) return;\n        \n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                Runnable refresher = new Runnable() { public void run() { refreshTimes(table); } };\n                CalibrationSupport.calibrate(javaPlatforms[row], -1, null, refresher);\n            }\n        });\n    }\n    \n    private void refreshTimes(JTable table) {\n        final TableModel model = table.getModel();\n        for (int row = 0; row < model.getRowCount(); row++) {\n            String javaPlatform = javaPlatforms[row];\n            Long modified = null;\n            String s = CalibrationSupport.getCalibrationDataFileName(javaPlatform);\n            if (s != null) {\n                File f = new File(s);\n                if (f.isFile()) modified = Long.valueOf(f.lastModified());\n            }\n            final int index = row;\n            final Long _modified = modified;\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() { model.setValueAt(_modified, index, 1); }\n            });\n        }\n    }\n    \n    private Object[][] createData() {\n        String[][] platforms = ProfilerSupport.getInstance().getSupportedJavaPlatforms();\n        javaPlatforms = platforms[1];\n        String[] names = platforms[0];\n        Object[][] data = new String[names.length][2];\n        \n        for (int i = 0; i < names.length; i++)\n            data[i] = new String[] { names[i], null };\n        \n        return data;\n    }\n    \n    private String[] javaPlatforms;\n    \n    private static class CalibrationDateCellRenderer extends DefaultTableCellRenderer {\n    \n        private static Calendar CALENDAR;\n        private static int REF_DAY_OF_YEAR = -1;\n        private static int DAY_OF_YEAR = -1;\n        private static int YEAR = -1;\n        private static int ERA = -1;\n\n        private static Date DATE;\n        private static DateFormat FORMAT_TIME;\n        private static DateFormat FORMAT_DATE;\n        \n        CalibrationDateCellRenderer() {\n            setHorizontalAlignment(TRAILING);\n        }\n\n        protected void setValue(Object value) {\n            if (value == null) {\n                setText(Bundle.LBL_NotCalibrated());\n            } else {\n                long time = ((Long)value).longValue();\n                setValue(time, isToday(time));\n            }\n        }\n\n        private void setValue(long time, boolean today) {\n            DateFormat format;\n            if (today) {\n                if (FORMAT_TIME == null) FORMAT_TIME = DateFormat.getTimeInstance();\n                format = FORMAT_TIME;\n            } else {\n                if (FORMAT_DATE == null) FORMAT_DATE = DateFormat.getDateInstance();\n                format = FORMAT_DATE;\n            }\n\n            if (DATE == null) DATE = new Date();\n            DATE.setTime(time);\n\n            setText(format.format(DATE));\n        }\n\n        private static boolean isToday(long time) {\n            if (REF_DAY_OF_YEAR != -1 && CALENDAR.get(Calendar.DAY_OF_YEAR)\n                != REF_DAY_OF_YEAR) CALENDAR = null;\n\n            if (CALENDAR == null) initializeCalendar();\n            CALENDAR.setTimeInMillis(time);\n\n            return DAY_OF_YEAR == CALENDAR.get(Calendar.DAY_OF_YEAR) &&\n                   YEAR == CALENDAR.get(Calendar.YEAR) &&\n                   ERA == CALENDAR.get(Calendar.ERA);\n        }\n\n        private static void initializeCalendar() {\n            CALENDAR = Calendar.getInstance();\n            DAY_OF_YEAR = CALENDAR.get(Calendar.DAY_OF_YEAR);\n            YEAR = CALENDAR.get(Calendar.YEAR);\n            ERA = CALENDAR.get(Calendar.ERA);\n            if (REF_DAY_OF_YEAR == -1) REF_DAY_OF_YEAR = DAY_OF_YEAR;\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/MemoryLivePanel.java",
    "content": "/*\n *  Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.Icon;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.profiler.actions.ResetResultsAction;\nimport org.graalvm.visualvm.lib.profiler.actions.TakeSnapshotAction;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.memory.LiveMemoryView;\nimport org.graalvm.visualvm.lib.ui.memory.LiveMemoryViewUpdater;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.profiling.actions.ProfilerResultsAction;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ObjectsFeatureUI_liveResults=Results:\",\n    \"ObjectsFeatureUI_pauseResults=Pause live results\",\n    \"ObjectsFeatureUI_updateResults=Update live results\",\n    \"ObjectsFeatureUI_profilingData=Collected data:\",\n    \"ObjectsFeatureUI_snapshot=Snapshot\",\n    \"ObjectsFeatureUI_showAbsolute=Show absolute values\",\n    \"ObjectsFeatureUI_showDeltas=Show delta values\"\n})\nclass MemoryLivePanel extends ProfilingResultsSupport.ResultsView {\n    \n    private ProfilerToolbar toolbar;\n    private LiveMemoryView memoryView;\n    private LiveMemoryViewUpdater updater;\n    private ProfilingResultsSupport.ResultsResetter resetter;\n    \n    \n    MemoryLivePanel(Application application) {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n        \n        initUI(application);\n        \n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        add(memoryView, BorderLayout.CENTER);\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    \n    void refreshResults() {\n        refreshResults(false);\n    }\n    \n    void resetResults() {\n        if (lrDeltasButton != null) {\n            lrDeltasButton.setSelected(false);\n            lrDeltasButton.setToolTipText(Bundle.ObjectsFeatureUI_showDeltas());\n        }\n        if (memoryView != null) {\n            memoryView.resetData();\n            memoryView.setDiffView(false);\n        }\n    }\n    \n    void sessionStateChanged(int sessionState) {\n        refreshToolbar(sessionState);\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    \n    private void refreshResults(final boolean forceRefresh) {\n        RESULTS_PROCESSOR.post(new Runnable() {\n            public void run() {\n                try {\n                    if (updater != null) {\n                        if (forceRefresh) updater.setForceRefresh(true);\n                        updater.update();\n                    }\n//                } catch (ClientUtils.TargetAppOrVMTerminated ex) {\n                } catch (Throwable t) {\n                    cleanup();\n                }\n            }\n        });\n    }\n\n    void cleanup() {\n        if (updater != null) {\n            updater.cleanup();\n            updater = null;\n        }\n\n        if (resetter != null) {\n            resetter.unregisterView(MemoryLivePanel.this);\n            resetter = null;\n        }\n    }\n    \n    \n    // -------------------------------------------------------------------------\n    \n    private JLabel lrLabel;\n    private JToggleButton lrPauseButton;\n    private JButton lrRefreshButton;\n    private JToggleButton lrDeltasButton;\n    \n    private JLabel pdLabel;\n    private JButton pdSnapshotButton;\n    private JButton pdResetResultsButton;\n    \n    private boolean popupPause;\n    \n    \n    private void initUI(Application application) {\n        \n        assert SwingUtilities.isEventDispatchThread();\n        \n        // --- Results ---------------------------------------------------------\n        \n        memoryView = new LiveMemoryView(null) {\n            protected boolean showSourceSupported() {\n                return GoToSource.isAvailable();\n            }\n            protected boolean profileClassSupported() {\n                return false;\n            }\n            protected void showSource(ClientUtils.SourceCodeSelection value) {\n                Lookup.Provider project = null;\n                String className = value.getClassName();\n                String methodName = value.getMethodName();\n                String methodSig = value.getMethodSignature();\n                GoToSource.openSource(project, className, methodName, methodSig);\n            }\n            protected void selectForProfiling(ClientUtils.SourceCodeSelection value) {\n//                ObjectsFeatureUI.this.selectForProfiling(value);\n            }\n            protected void popupShowing() {\n                if (lrPauseButton.isEnabled() && !lrRefreshButton.isEnabled()) {\n                    popupPause = true;\n                    lrPauseButton.setSelected(true);\n                }\n            }\n            protected void popupHidden() {\n                if (lrPauseButton.isEnabled() && popupPause) {\n                    popupPause = false;\n                    lrPauseButton.setSelected(false);\n                }\n            }\n        };\n        memoryView.putClientProperty(\"HelpCtx.Key\", \"ProfileObjects.HelpCtx\"); // NOI18N\n        memoryView.putClientProperty(ProfilerResultsAction.PROP_APPLICATION, application);\n        \n        updater = new LiveMemoryViewUpdater(memoryView, Profiler.getDefault().getTargetAppRunner().getProfilerClient());        \n        resetter = ProfilingResultsSupport.ResultsResetter.registerView(this);\n        \n        InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        ActionMap actionMap = getActionMap();\n        \n        final String filterKey = FilterUtils.FILTER_ACTION_KEY;\n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                Action action = memoryView.getActionMap().get(filterKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);\n        \n        final String findKey = SearchUtils.FIND_ACTION_KEY;\n        Action findAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                Action action = memoryView.getActionMap().get(findKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(findKey, findAction, actionMap, inputMap);\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        lrLabel = new GrayLabel(Bundle.ObjectsFeatureUI_liveResults());\n\n        lrPauseButton = new JToggleButton(Icons.getIcon(GeneralIcons.PAUSE)) {\n            protected void fireItemStateChanged(ItemEvent event) {\n                boolean paused = isSelected();\n                updater.setPaused(paused);\n                lrRefreshButton.setEnabled(paused && !popupPause);\n                if (!paused) refreshResults(true);\n            }\n        };\n        lrPauseButton.setToolTipText(Bundle.ObjectsFeatureUI_pauseResults());\n\n        lrRefreshButton = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                refreshResults(true);\n            }\n        };\n        lrRefreshButton.setToolTipText(Bundle.ObjectsFeatureUI_updateResults());\n        lrRefreshButton.setEnabled(false);\n        \n        Icon icon = Icons.getIcon(ProfilerIcons.DELTA_RESULTS);\n        lrDeltasButton = new JToggleButton(icon) {\n            protected void fireActionPerformed(ActionEvent e) {\n                if (!memoryView.setDiffView(isSelected())) setSelected(false);\n                setToolTipText(isSelected() ? Bundle.ObjectsFeatureUI_showAbsolute() :\n                                              Bundle.ObjectsFeatureUI_showDeltas());\n            }\n        };\n        lrDeltasButton.setToolTipText(Bundle.ObjectsFeatureUI_showDeltas());\n\n        pdLabel = new GrayLabel(Bundle.ObjectsFeatureUI_profilingData());\n\n        pdSnapshotButton = new JButton(TakeSnapshotAction.getInstance());\n//        pdSnapshotButton.setHideActionText(true);\n        pdSnapshotButton.setText(Bundle.ObjectsFeatureUI_snapshot());\n        pdSnapshotButton.putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n\n        pdResetResultsButton = new JButton(ResetResultsAction.getInstance());\n        pdResetResultsButton.setHideActionText(true);\n\n        toolbar = ProfilerToolbar.create(true);\n\n//        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(lrLabel);\n        toolbar.addSpace(2);\n        toolbar.add(lrPauseButton);\n        toolbar.add(lrRefreshButton);\n        toolbar.addSpace(5);\n        toolbar.add(lrDeltasButton);\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(pdLabel);\n        toolbar.addSpace(2);\n        toolbar.add(pdSnapshotButton);\n        toolbar.addSpace(3);\n        toolbar.add(pdResetResultsButton);\n        \n    }\n    \n    private void refreshToolbar(final int state) {\n        if (toolbar != null) SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                boolean running = state == Profiler.PROFILING_RUNNING;\n                lrPauseButton.setEnabled(running);\n                lrRefreshButton.setEnabled(!popupPause && running && lrPauseButton.isSelected());\n                lrDeltasButton.setEnabled(running);\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/MemorySettingsSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.profiling.presets.PresetSelector;\nimport org.graalvm.visualvm.profiling.presets.ProfilerMemoryPanel;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPreset;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class MemorySettingsSupport extends ProfilerSettingsSupport {\n    \n    private JPanel container;\n    private ProfilerMemoryPanel panel;\n    private PresetSelector selector;\n    \n    private DataViewComponent.DetailsView detailsView;\n    \n    \n    DataViewComponent.DetailsView getDetailsView() {\n        if (detailsView == null) {\n            detailsView = new DataViewComponent.DetailsView(NbBundle.getMessage(\n                          MemorySettingsSupport.class, \"LBL_Memory_settings\"), null, 20, // NOI18N\n                          new ScrollableContainer(getComponent()), null);\n        }\n        return detailsView;\n    }\n    \n    public JComponent getComponent() {\n        if (container == null) createPanel();\n        return container;\n    }\n    \n    \n    public ProfilingSettings getSettings() { return panel.getSettings(); }\n    \n    public void saveSettings() {\n        // NOTE: might save custom configuration here\n    }\n    \n    void updateSettings(ProfilerPreset preset) {\n        panel.loadFromPreset(preset);\n    }\n    \n    public abstract boolean presetValid();\n    \n    public boolean settingsValid() { return panel.settingsValid(); }\n    \n    public void showSettings(DataViewComponent dvc) {\n        panel.highlightInvalid();\n        dvc.selectDetailsView(getDetailsView());\n    }\n    \n    public abstract PresetSelector createSelector(Runnable presetSynchronizer);\n    \n    \n    public void setEnabled(boolean enabled) {\n        container.setEnabled(enabled);\n    }\n    \n    private JPanel createPanel() {\n        panel = new ProfilerMemoryPanel() {\n            public void settingsChanged() {\n                panel.saveToPreset(selector.customize(presetValid()));\n            }\n        };\n        \n        selector = createSelector(new Runnable() {\n            public void run() { panel.loadFromPreset(selector.getSelectedPreset()); }\n        });\n        selector.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));\n        \n        container = new JPanel(new BorderLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents()) c.setEnabled(enabled);\n            }\n        };\n        container.setOpaque(false);\n        container.add(panel, BorderLayout.CENTER);\n        container.add(selector, BorderLayout.SOUTH);\n        \n        return container;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/ProfileApplicationAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.event.ActionEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport org.openide.util.NbBundle;\n\n    \n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ProfileApplicationAction extends SingleDataSourceAction<Application> {\n    \n    private Application lastSelectedApplication;\n    private final PropertyChangeListener stateListener = new PropertyChangeListener() {\n        public void propertyChange(PropertyChangeEvent evt) {\n            updateState(ActionUtils.getSelectedDataSources(Application.class));\n        }\n    };\n    \n        \n    private static ProfileApplicationAction instance;\n    \n    public static synchronized ProfileApplicationAction instance() {\n        if (instance == null) \n            instance = new ProfileApplicationAction();\n        return instance;\n    }\n    \n        \n    protected void actionPerformed(Application application, ActionEvent actionEvent) {\n        ProfilerSupport.getInstance().selectProfilerView(application);\n    }\n    \n    protected boolean isEnabled(Application application) {\n        // TODO: Listener should only be registered when profiling the application is supported\n        lastSelectedApplication = application;\n        lastSelectedApplication.addPropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        return ProfilerSupport.getInstance().supportsProfiling(application);\n    }\n    \n    protected void updateState(Set<Application> applications) {\n        if (lastSelectedApplication != null) {\n            lastSelectedApplication.removePropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n            lastSelectedApplication = null;\n        }\n        super.updateState(applications);\n    }\n    \n    protected void initialize() {\n        if (ProfilerSupport.getInstance().isInitialized()) {\n            super.initialize();\n        } else {\n            setEnabled(false);\n        }\n    }\n    \n    \n    private ProfileApplicationAction() {\n        super(Application.class);\n        putValue(NAME, NbBundle.getMessage(ProfileApplicationAction.class, \"MSG_Profile\")); // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(ProfileApplicationAction.class, \"DESCR_Profile\"));    // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/ProfilerSettingsSupport.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiler;\n\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerSettingsSupport {\n    \n    public abstract ProfilingSettings getSettings();\n    \n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/ProfilerSnapshotAction.java",
    "content": "     /*\n *  Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.io.File;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.SnapshotsListener;\nimport org.graalvm.visualvm.lib.profiler.actions.TakeSnapshotAction;\nimport org.graalvm.visualvm.profiling.snapshot.ProfilerSnapshotsSupport;\nimport org.openide.util.NbBundle;\nimport org.openide.util.actions.SystemAction;\nimport org.openide.util.lookup.ServiceProvider;\n\n    \n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ProfilerSnapshotAction extends SingleDataSourceAction<Application> {\n    \n    private static final Logger LOGGER = Logger.getLogger(ProfilerSnapshotAction.class.getName());\n    \n    private static final String NB_PROFILER_SNAPSHOTS_STORAGE = \"config\" + File.separator + // NOI18N\n            \"NBProfiler\" + File.separator + \"Config\" + File.separator + \"Settings\"; // NOI18N\n    \n    private final TakeSnapshotAction originalAction = TakeSnapshotAction.getInstance();\n    private boolean openNextSnapshot = true;\n    \n    \n    private static ProfilerSnapshotAction instance;\n    \n    public static synchronized ProfilerSnapshotAction instance() {\n        if (instance == null) \n            instance = new ProfilerSnapshotAction();\n        return instance;\n    }\n    \n    protected void actionPerformed(Application dataSource, ActionEvent actionEvent) {\n        openNextSnapshot = (actionEvent.getModifiers() &\n                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0;\n        originalAction.performAction();\n    }\n    \n    protected boolean isEnabled(Application application) {\n        return ProfilerSupport.getInstance().getProfiledApplication() == application && originalAction.isEnabled();\n    }\n    \n    protected void initialize() {\n        if (ProfilerSupport.getInstance().isInitialized()) {\n            super.initialize();\n\n            originalAction.addPropertyChangeListener(new PropertyChangeListener() {\n                public void propertyChange(PropertyChangeEvent evt) {\n                    if (SystemAction.PROP_ENABLED.equals(evt.getPropertyName()))\n                        ProfilerSnapshotAction.this.updateState(ActionUtils.getSelectedDataSources(Application.class));\n                }\n            });\n\n        } else {\n            setEnabled(false);\n        }\n    }\n    \n    \n    private ProfilerSnapshotAction() {\n        super(Application.class);\n        putValue(NAME, NbBundle.getMessage(ProfilerSnapshotAction.class, \"MSG_Profiler_Snapshot\")); // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(ProfilerSnapshotAction.class, \"DESCR_Profiler_Snapshot\"));    // NOI18N\n    }\n\n    @ServiceProvider(service=SnapshotsListener.class)\n    public static class SnapshotsListenerImpl implements SnapshotsListener {\n\n        public SnapshotsListenerImpl() {\n        }\n\n        public void snapshotLoaded(LoadedSnapshot snapshot) {}\n\n        public void snapshotRemoved(LoadedSnapshot snapshot) {}\n\n        public void snapshotTaken(LoadedSnapshot snapshot) {}\n\n        public void snapshotSaved(LoadedSnapshot snapshot) {\n            try {\n                Application profiledApplication = ProfilerSupport.getInstance().getProfiledApplication();\n                File snapshotFile = snapshot.getFile();\n                if (profiledApplication != null && snapshotFile.getCanonicalPath().contains(NB_PROFILER_SNAPSHOTS_STORAGE)) {\n                    File newSnapshotFile = Utils.getUniqueFile(profiledApplication.getStorage().getDirectory(), snapshotFile.getName());\n                    if (!snapshotFile.renameTo(newSnapshotFile)) {\n                        Utils.copyFile(snapshotFile, newSnapshotFile);\n                        snapshotFile.deleteOnExit();\n                    }\n                    snapshot.setFile(newSnapshotFile);\n                    ProfilerSnapshotsSupport pss = ProfilerSnapshotsSupport.getInstance();\n                    ProfilerSnapshotAction psa = ProfilerSnapshotAction.instance();\n                    pss.createSnapshot(newSnapshotFile, profiledApplication, psa.openNextSnapshot);\n                    psa.openNextSnapshot = true;\n                }\n            } catch (Exception e) {\n                LOGGER.log(Level.SEVERE, \"Error handling saved profiler snapshot\", e); // NOI18N\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/ProfilerSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiler;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Properties;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.host.Host;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.common.SessionSettings;\nimport org.graalvm.visualvm.lib.jfluid.global.Platform;\nimport org.graalvm.visualvm.lib.profiler.NetBeansProfiler;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPreset;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ProfilerSupport {\n    \n//    private static final Logger LOGGER = Logger.getLogger(ProfilerSupport.class.getName());\n    \n    private static final String HOTSPOT_VM_NAME_PREFIX = \"Java HotSpot\";    // NOI18N\n    private static final String OPENJDK_VM_NAME_PREFIX = \"OpenJDK \";    // NOI18N\n    \n    private static final String JAVA_RT_16_PREFIX = \"1.6.0\";  // NOI18N\n    private static final String JAVA_RT_17_PREFIX = \"1.7.0\";  // NOI18N\n    \n    private static ProfilerSupport instance;\n    \n    private boolean isInitialized;\n    \n    private Application profiledApplication;\n    private final ApplicationProfilerViewProvider profilerViewProvider;\n\n\n    public static synchronized ProfilerSupport getInstance() {\n        if (instance == null) instance = new ProfilerSupport();\n        return instance;\n    }\n    \n    \n    boolean isInitialized() {\n        return isInitialized;\n    }\n    \n    public String getProfiledApplicationName() {\n        String name = NbBundle.getMessage(ProfilerSupport.class, \"STR_Externally_started_app\"); // NOI18N\n        Application a = getProfiledApplication();\n        if (a == null) {\n            int state = NetBeansProfiler.getDefaultNB().getProfilingState();\n            return state == NetBeansProfiler.PROFILING_INACTIVE ? null : name;\n        }\n        DataSourceDescriptor d = DataSourceDescriptorFactory.getDescriptor(a);\n        return d != null ? d.getName() : name;\n    }\n    \n    public int getDefaultPort() {\n        return ProfilerIDESettings.getInstance().getPortNo();\n    }\n    \n    public boolean hasSupportedJavaPlatforms() {\n        List<String> codesl = getSupportedJavaPlatformIds();\n\n        return !codesl.isEmpty();\n    }\n    \n    public String[][] getSupportedJavaPlatforms() {\n        List<String> codesl = getSupportedJavaPlatformIds();\n        \n        String[] names = new String[codesl.size()];\n        String[] codes = new String[codesl.size()];\n        String current = null;\n        for (int i = 0; i < codesl.size(); i++) {\n            codes[i] = codesl.get(i);\n            names[i] = getJavaName(codes[i]);\n            if (Platform.getJDKVersionString().equals(codes[i])) current = names[i];\n        }\n        \n        return new String[][] { names, codes, { current } };\n    }\n    \n    public String[][] getSupportedArchitectures(String java) {\n        List<String> codesl = new ArrayList<>();\n        \n        if (supportsProfiling(java, 32)) codesl.add(Integer.toString(32));\n        if (supportsProfiling(java, 64)) codesl.add(Integer.toString(64));\n        \n        String[] names = new String[codesl.size()];\n        String[] codes = new String[codesl.size()];\n        String current = null;\n        for (int i = 0; i < codesl.size(); i++) {\n            codes[i] = codesl.get(i);\n            names[i] = getArchName(Integer.parseInt(codes[i]));\n            if (Integer.toString(Platform.getSystemArchitecture()).equals(codes[i])) current = names[i];\n        }\n        \n        return new String[][] { names, codes, { current } };\n    }\n    \n    static String getJavaName(String code) {\n        if (Platform.JDK_15_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 5); // NOI18N\n        if (Platform.JDK_16_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 6); // NOI18N\n        if (Platform.JDK_17_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 7); // NOI18N\n        if (Platform.JDK_18_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 8); // NOI18N\n        if (Platform.JDK_19_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 9); // NOI18N\n        if (Platform.JDK_100_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 10); // NOI18N\n        if (Platform.JDK_110_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 11); // NOI18N\n        if (Platform.JDK_120_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 12); // NOI18N\n        if (Platform.JDK_130_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 13); // NOI18N\n        if (Platform.JDK_140_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 14); // NOI18N\n        if (Platform.JDK_150_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 15); // NOI18N\n        if (Platform.JDK_160_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 16); // NOI18N\n        if (Platform.JDK_170_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 17); // NOI18N\n        if (Platform.JDK_180_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 18); // NOI18N\n        if (Platform.JDK_190_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 19); // NOI18N\n        if (Platform.JDK_200_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 20); // NOI18N\n        if (Platform.JDK_210_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 21); // NOI18N\n        if (Platform.JDK_220_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 22); // NOI18N\n        if (Platform.JDK_230_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 23); // NOI18N\n        if (Platform.JDK_240_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 24); // NOI18N\n        if (Platform.JDK_250_STRING.equals(code))\n            return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_platform_name\", 25); // NOI18N\n        throw new IllegalArgumentException(\"Unknown java code \" + code); // NOI18N\n    }\n    \n    static String getArchName(int arch) {\n        if (32 == arch) return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_arch_name\", 32); // NOI18N\n        if (64 == arch) return NbBundle.getMessage(ProfilerSupport.class, \"STR_Java_arch_name\", 64); // NOI18N\n        throw new IllegalArgumentException(\"Unsupported architecture \" + arch); // NOI18N\n    }\n    \n    public boolean supportsProfiling(String java, int architecture) {\n        String ld = Profiler.getDefault().getLibsDir();\n        String nativeLib = Platform.getAgentNativeLibFullName(ld, false, java, architecture);\n        return new File(nativeLib).isFile();\n    }\n    \n    public String getStartupParameter(String java, int architecture, int port) {\n        String ld = Profiler.getDefault().getLibsDir();\n        if (ld.contains(\" \")) ld = \"\\\"\" + ld + \"\\\"\"; // NOI18N\n        \n        String nativeLib = Platform.getAgentNativeLibFullName(ld, false, java, architecture);        \n        if (nativeLib.contains(\" \")) nativeLib = \"\\\"\" + nativeLib + \"\\\"\"; // NOI18N\n        \n        return \"-agentpath:\" + nativeLib + \"=\" + ld + \",\" + port; // NOI18N\n    }\n    \n    public void profileProcessStartup(final String java, final int architecture, final int port,\n                                      ProfilerSettingsSupport settings, final ProfilerPreset preset) {\n        \n        if (!CalibrationSupport.checkCalibration(java, architecture, null, null)) return;\n        \n        final ProfilingSettings pSettings = settings.getSettings();\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {                \n        // Perform the actual attach\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                if (!checkStartedApp(port)) return;\n\n                final RequestProcessor processor = new RequestProcessor(\"Startup Profiler @ \" + port); // NOI18N\n                Host.LOCALHOST.getRepository().addDataChangeListener(\n                    new DataChangeListener<Application>() {\n                        public void dataChanged(final DataChangeEvent<Application> event) {\n                            final DataChangeListener<Application> listener = this;\n                            processor.post(new Runnable() {\n                                public void run() {\n                                    if (!event.getAdded().equals(event.getCurrent())) // filter-out initial sync event\n                                        for (Application a : event.getAdded()) {\n                                            if (isProfiledApplication(a, port)) {\n                                                Host.LOCALHOST.getRepository().removeDataChangeListener(listener);\n\n                                                setProfiledApplication(a);\n                                                selectProfilerView(a, preset, pSettings);\n\n                                                break;\n                                            }\n                                        }\n                                }\n                            });\n                        }\n                    }, Application.class);\n\n                ProfilingSettings ps = pSettings;\n                SessionSettings ss = createSessionSettings(java, architecture, port);\n                NetBeansProfiler.getDefaultNB().connectToStartedApp(ps, ss);\n                resetTerminateDialogs();\n            }\n        });\n        }\n        });\n    }\n    \n    private static boolean checkStartedApp(int port) {\n        String homeDir = System.getProperty(\"user.home\"); // NOI18N\n        File agentF = new File(homeDir + File.separator + \".nbprofiler\" + File.separator + port); // NOI18N\n        if (!agentF.isFile()) return true;\n        \n        String caption = NbBundle.getMessage(ProfilerSupport.class, \"CAP_Warning\"); // NOI18N\n        String message = NbBundle.getMessage(ProfilerSupport.class, \"MSG_StartedTooSoon\"); // NOI18N\n        NotifyDescriptor nd = new NotifyDescriptor(message, caption, NotifyDescriptor.OK_CANCEL_OPTION,\n                                  NotifyDescriptor.WARNING_MESSAGE, null, NotifyDescriptor.OK_OPTION);\n        if (DialogDisplayer.getDefault().notify(nd) != NotifyDescriptor.OK_OPTION) return false;\n        return checkStartedApp(port);\n    }\n    \n    private static void resetTerminateDialogs() {\n        String dnsaKey = \"NetBeansProfiler.handleShutdown.noResults\"; // NOI18N\n        ProfilerIDESettings.getInstance().setDoNotShowAgain(dnsaKey, null);\n        dnsaKey = \"NetBeansProfiler.handleShutdown\"; // NOI18N\n        String dnsa = ProfilerIDESettings.getInstance().getDoNotShowAgain(dnsaKey);\n        if (\"NO_OPTION\".equals(dnsa)) ProfilerIDESettings.getInstance().setDoNotShowAgain(dnsaKey, null); // NOI18N        }\n    }\n    \n    private static SessionSettings createSessionSettings(String java, int architecture, int port) {\n        SessionSettings ss = new SessionSettings();\n        ss.setJavaVersionString(java);\n        ss.setSystemArchitecture(architecture);\n        ss.setPortNo(port);\n        ss.setJavaExecutable(JavaInfo.getCurrentJDKExecutable()); // Workaround for calibration check, not used for profiling\n        return ss;\n    }\n    \n    private static boolean isProfiledApplication(Application a, int port) {\n        Jvm jvm = JvmFactory.getJVMFor(a);\n        if (!jvm.isBasicInfoSupported()) return false;\n        String args = jvm.getJvmArgs();\n        return args.contains(\"-agentpath:\") && args.contains(\",\" + port); // NOI18N\n    }\n    \n    \n    boolean supportsProfiling(Application application) {\n        // Application already being profiled (Startup Profiler)\n        if (application == getProfiledApplication()) return true;\n        \n        // Remote profiling is not supported\n        if (application.getHost() != Host.LOCALHOST) return false;\n        \n        // Profiling current VisualVM instance is not supported\n        if (Application.CURRENT_APPLICATION.equals(application)) return false;\n        \n        // Profiled application has to be running\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        \n        \n        Jvm jvm = JvmFactory.getJVMFor(application);\n        \n        // Basic info has to be supported and VM has to be attachable\n        if (!jvm.isBasicInfoSupported() || !jvm.isAttachable()) return false;\n        \n        // Profiled application needs to be running JDK 6.0 or 7.0 or 8.0 or 9.0\n        // or 10 or 11 or 12\n        if (jvm.is14() || jvm.is15()) return false;\n        \n        int arch = getJVMArchitecture(jvm);\n        if (arch == -1) return false;\n        String javaVer = Platform.getJDKVersionString(jvm.getJavaVersion());\n        return supportsProfiling(javaVer, arch);\n    }\n    \n    static boolean classSharingBreaksProfiling(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        String vmInfo = jvm.getVmInfo();\n        boolean classSharing = vmInfo.contains(\"sharing\"); // NOI18N\n        \n        if (!jvm.isGetSystemPropertiesSupported()) return classSharing;\n        Properties properties = jvm.getSystemProperties();\n        if (properties == null) return classSharing;\n        \n        String javaRTVersion = properties.getProperty(\"java.runtime.version\"); // NOI18N\n        if (javaRTVersion == null) return classSharing;\n        \n        int updateNumber = getUpdateNumber(javaRTVersion);\n        int buildNumber = getBuildNumber(javaRTVersion);\n        String vmName = jvm.getVmName();\n        \n        // Sun JDK & derived JDKs ----------------------------------------------\n        if (vmName.startsWith(HOTSPOT_VM_NAME_PREFIX)) {\n            // JDK 6.0 is OK from Update 6 except of Update 10 Build 23 and lower\n            if (javaRTVersion.startsWith(JAVA_RT_16_PREFIX)) {\n                if (updateNumber < 10) return true;\n                if (updateNumber == 10 && buildNumber <= 23) return true;\n            // JDK 7.0 is OK from Build 26\n            } else if (javaRTVersion.startsWith(JAVA_RT_17_PREFIX)) {\n                if (updateNumber == 0) {\n                    if (buildNumber < 26) return true;\n                }\n            }\n            return false;\n        // OpenJDK -------------------------------------------------------------\n        } else if(vmName.startsWith(OPENJDK_VM_NAME_PREFIX)) {\n            // OpenJDK 6 is OK from Build 11\n            if (javaRTVersion.startsWith(JAVA_RT_16_PREFIX)) {\n                if (updateNumber == 0) {\n                    if (buildNumber < 11) return true;\n                }\n            // OpenJDK 7 is assumed to be OK from Build 26 (not tested)\n            } else if (javaRTVersion.startsWith(JAVA_RT_17_PREFIX)) {\n                if (updateNumber == 0) {\n                    if (buildNumber < 26) return true;\n                }\n            }\n            // OpenJDK 8 should be OK\n            return false;\n        }\n        \n        return classSharing;\n    }\n    \n    private static int getUpdateNumber(String javaRTVersion) {\n        int underscoreIndex = javaRTVersion.indexOf('_'); // NOI18N\n        if (underscoreIndex == -1) return 0; // Assumes no update, may be incorrect for unexpected javaRTVersion format\n        \n        try {\n            String updateNumberString = javaRTVersion.substring(underscoreIndex + \"_\".length(), javaRTVersion.indexOf('-')); // NOI18N\n            return Integer.parseInt(updateNumberString);\n        } catch (Exception e) {}\n        \n        return -1;\n    }\n    \n    private static int getBuildNumber(String javaRTVersion) {\n        try {\n            String buildNumberString = javaRTVersion.substring(javaRTVersion.indexOf(\"-b\") + \"-b\".length()); // NOI18N\n            return Integer.parseInt(buildNumberString);\n        } catch (Exception e) {}\n        \n        return -1;\n    }\n\n    private static int getJVMArchitecture(Jvm jvm) {\n        Properties sysprops = jvm.getSystemProperties();\n        String jvmArch = sysprops == null ? null : sysprops.getProperty(\"sun.arch.data.model\");    // NOI18N\n        return jvmArch == null ? -1 : Integer.parseInt(jvmArch);\n    }\n    \n    synchronized void setProfiledApplication(Application profiledApplication) {\n        this.profiledApplication = profiledApplication;\n    }\n  \n    synchronized Application getProfiledApplication() {\n        return profiledApplication;\n    }\n    \n    void selectActiveProfilerView() {\n        selectProfilerView(getProfiledApplication());\n    }\n    \n    void selectProfilerView(Application application) {\n        selectProfilerView(application, null, null);\n    }\n    \n    private void selectProfilerView(Application application, final ProfilerPreset preset, final ProfilingSettings settings) {\n        if (application == null) return;\n        \n        final DataSourceView activeView = profilerViewProvider.view(application);\n        if (activeView == null) return;\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (preset != null && settings != null)\n                    ((ApplicationProfilerView)activeView).selectPreset(preset, settings);\n                DataSourceWindowManager.sharedInstance().selectView(activeView);\n            }\n        });\n    }\n    \n    private List<String> getSupportedJavaPlatformIds() {\n        List<String> codesl = new ArrayList<>();\n        // jdk 1.5 .. 1.9\n        for (int i = 5; i <= 9; i++) {\n            String code = \"jdk1\" + i; // NOI18N\n            if (supportsProfiling(code, 32) || supportsProfiling(code, 64)) codesl.add(code);\n        }\n        // jdk 10 .. jdk 25\n        for (int i = 10; i <= 25; i++) {\n            String code = \"jdk\" + i +\"0\"; // NOI18N\n            if (supportsProfiling(code, 32) || supportsProfiling(code, 64)) codesl.add(code);\n        }\n        return codesl;\n    }\n    \n    private ProfilerSupport() {\n        isInitialized = NetBeansProfiler.isInitialized();\n        \n        if (isInitialized) {\n            profilerViewProvider = new ApplicationProfilerViewProvider();\n            profilerViewProvider.initialize();\n\n            ProfilerIDESettings.getInstance().setAutoOpenSnapshot(false);\n            ProfilerIDESettings.getInstance().setAutoSaveSnapshot(true);\n        } else {\n            profilerViewProvider = null;\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/ProfilingResultsSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.profiler;\n\nimport java.awt.BorderLayout;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.lib.profiler.ResultsListener;\nimport org.graalvm.visualvm.lib.profiler.spi.ProfilerStorageProvider;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ProfilingResultsSupport extends JPanel {\n\n    ProfilingResultsSupport() {\n        super();\n        initComponents();\n    }\n\n    public DataViewComponent.DetailsView getDetailsView() {\n        return new DataViewComponent.DetailsView(NbBundle.getMessage(\n                ProfilingResultsSupport.class, \"MSG_Profiling_results\"), null, 10, // NOI18N\n                this, null);\n    }\n\n    public void setProfilingResultsDisplay(JComponent profilingResultsDisplay) {\n        removeAll();\n        if (profilingResultsDisplay != null) {\n            add(profilingResultsDisplay);\n        }\n    }\n\n    private void initComponents() {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n    }\n    \n    \n    static abstract class ResultsView extends JPanel {\n        \n        abstract void refreshResults();\n        \n        abstract void resetResults();\n        \n        abstract void sessionStateChanged(int sessionState);\n        \n        abstract void cleanup();\n\n        protected static final RequestProcessor RESULTS_PROCESSOR = new RequestProcessor(\"Results View Processor\"); // NOI18N\n        \n    }\n    \n    \n    @ServiceProvider(service=ResultsListener.class)\n    public static class ResultsResetter implements ResultsListener {\n        \n        private final List<ResultsView> views = new ArrayList<>();\n        \n        \n        public static ResultsResetter registerView(ResultsView view) {\n            ResultsResetter handler = Lookup.getDefault().lookup(ResultsResetter.class);\n            handler.views.add(view);\n            return handler;\n        }\n        \n        public void unregisterView(ResultsView view) {\n            views.remove(view);\n        }\n        \n        \n        public void resultsAvailable() {}\n        \n        public void resultsReset() {\n            for (ResultsView updater : views) updater.resetResults();\n        }\n\n    }\n    \n    \n    @ServiceProvider(service=ProfilerStorageProvider.class)\n    public static class VisualVMStorageProvider extends ProfilerStorageProvider.Abstract {\n\n        private static final String PROFILER_FOLDER = \"NBProfiler/Config\";  // NOI18N\n        private static final String SETTINGS_FOLDER = \"Settings\";   // NOI18N\n\n        public FileObject getGlobalFolder(boolean create) throws IOException {\n            FileObject folder = FileUtil.getConfigFile(PROFILER_FOLDER);\n            FileObject settingsFolder = folder.getFileObject(SETTINGS_FOLDER, null);\n\n            if ((settingsFolder == null) && create)\n                settingsFolder = folder.createFolder(SETTINGS_FOLDER);\n\n            return settingsFolder;\n        }\n\n        public FileObject getProjectFolder(Lookup.Provider project, boolean create) throws IOException {\n            return null;\n        }\n\n        public Lookup.Provider getProjectFromFolder(FileObject settingsFolder) {\n            return null;\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/VisualVMProfiler.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiler;\n\nimport java.io.File;\nimport org.graalvm.visualvm.lib.common.Profiler;\nimport org.graalvm.visualvm.lib.profiler.NetBeansProfiler;\nimport org.graalvm.visualvm.lib.profiler.ProfilerModule;\nimport org.openide.modules.InstalledFileLocator;\nimport org.openide.util.lookup.ServiceProvider;\n\n\n/**\n *\n * @author Tomas Hurka\n */\n@ServiceProvider(service=Profiler.class)\npublic class VisualVMProfiler extends NetBeansProfiler {\n\n    @Override\n    public String getLibsDir() {\n        final File dir = InstalledFileLocator.getDefault().locate(ProfilerModule.LIBS_DIR + \"/jfluid-server.jar\", //NOI18N\n                                                     \"org.graalvm.visualvm.lib.jfluid\", false); //NOI18N\n        if (dir == null) {\n            return null;\n        }\n        return dir.getParentFile().getPath();\n    }\n\n    protected boolean shouldOpenWindowsOnProfilingStart() {\n        return false;\n    }\n\n    @Override\n    public boolean rerunAvailable() {\n        return false;\n    }\n\n    @Override\n    public boolean modifyAvailable() {\n        return false;\n    }\n\n    @Override\n    public void rerunLastProfiling() {\n        throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n    }\n \n}\n"
  },
  {
    "path": "visualvm/profiler/src/org/graalvm/visualvm/profiler/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    \n    <folder name=\"Menu\">\n        <folder name=\"Applications\">\n            <file name=\"Applications-Separator-1500.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"1500\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-profiler-ProfileApplicationAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-profiler-ProfileApplicationAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1520\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-profiler-ProfilerSnapshotAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-profiler-ProfilerSnapshotAction.instance\"/>\n                <attr name=\"position\" intvalue=\"2400\"/>\n            </file>\n        </folder>\n    </folder>\n\n    <folder name=\"VisualVM\">\n        <folder name=\"Actions\">\n            <file name=\"org-graalvm-visualvm-profiler-ProfileApplicationAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.profiler.ProfileApplicationAction.instance\"/>\n            </file>\n            <file name=\"org-graalvm-visualvm-profiler-ProfilerSnapshotAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.profiler.ProfilerSnapshotAction.instance\"/>\n            </file>\n        </folder>\n\n        <folder name=\"ExplorerPopupSelection\">\n            \n            <file name=\"org-graalvm-visualvm-profiler-ProfileApplicationAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-profiler-ProfileApplicationAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1015\"/>\n            </file>\n            <file name=\"ProfileApplicationAction-Separator-1020.instance\">\n                <attr name=\"instanceClass\" stringvalue=\"javax.swing.JSeparator\"/>\n                <attr name=\"position\" intvalue=\"1020\"/>\n            </file>\n            \n            <file name=\"org-graalvm-visualvm-profiler-ProfilerSnapshotAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-profiler-ProfilerSnapshotAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1400\"/>\n            </file>\n            \n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "visualvm/profiling/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.profiling\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.profiling.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/profiling/manifest.mf",
    "content": "Manifest-Version: 1.0\nOpenIDE-Module: org.graalvm.visualvm.profiling/2\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module-Install: org/graalvm/visualvm/profiling/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/profiling/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.4\n\n"
  },
  {
    "path": "visualvm/profiling/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.profiling-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/profiling/nbproject/platform.properties",
    "content": "# Deprecated since 5.0u1; for compatibility with 5.0:\ndisabled.clusters=\\\n    harness\ndisabled.modules=\\\n    org.netbeans.core.execution,\\\n    org.netbeans.core.output2,\\\n    org.netbeans.libs.junit4,\\\n    org.netbeans.modules.core.kit,\\\n    org.netbeans.modules.favorites,\\\n    org.netbeans.modules.options.keymap,\\\n    org.netbeans.modules.templates,\\\n    org.openide.compat,\\\n    org.openide.util.enumerations\nenabled.clusters=\\\n    platform,\\\n    profiler\nnbjdk.active=default\nnbplatform.active=NetBeans Platform 6.9 RC2 (Build 100607-babd5536fc49)\nsuite.dir=${basedir}\nnetbeans.dest.dir=${suite.dir}/netbeans\nharness.dir=${netbeans.dest.dir}/harness\n"
  },
  {
    "path": "visualvm/profiling/nbproject/project.properties",
    "content": "is.autoload=true\njavac.source=1.8\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n"
  },
  {
    "path": "visualvm/profiling/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.profiling</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.common</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.9</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.16</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.snaptracer</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.options.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.18.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.23.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.filesystems</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.11</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.17.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.windows</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>6.33.1</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualizer.dumpmethod</friend>\n                <friend>org.graalvm.visualvm.profiler</friend>\n                <friend>org.graalvm.visualvm.profiler.startup</friend>\n                <friend>org.graalvm.visualvm.sampler</friend>\n                <friend>org.graalvm.visualvm.sampler.truffle</friend>\n                <package>org.graalvm.visualvm.profiling.actions</package>\n                <package>org.graalvm.visualvm.profiling.presets</package>\n                <package>org.graalvm.visualvm.profiling.snapshot</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/profiling/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Profiling\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.profiling;\n\nimport org.graalvm.visualvm.profiling.presets.ProfilerPresets;\nimport org.graalvm.visualvm.profiling.snapshot.ProfilerSnapshotsSupport;\nimport org.openide.modules.ModuleInstall;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class Installer extends ModuleInstall {\n\n    public void restored() {\n        ProfilerSnapshotsSupport.getInstance();\n        ProfilerPresets.getInstance();\n    }\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/actions/ProfiledSourceSelection.java",
    "content": "/*\n *  Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiling.actions;\n\nimport org.graalvm.visualvm.application.Application;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ProfiledSourceSelection {\n    \n    private final Application application;\n    \n    private final String className;\n    private final String methodName;\n    private final String methodSignature;\n    \n    \n    public ProfiledSourceSelection(Application application, String className, String methodName, String methodSignature) {\n        this.application = application;\n        \n        this.className = className;\n        this.methodName = methodName;\n        this.methodSignature = methodSignature;\n    }\n    \n    \n    public final Application getApplication() { return application; }\n    \n    public final String getClassName() { return className; }\n    \n    public final String getMethodName() { return methodName; }\n    \n    public final String getMethodSignature() { return methodSignature; }\n    \n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/actions/ProfilerActionsSupport.java",
    "content": "/*\n *  Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiling.actions;\n\nimport org.graalvm.visualvm.application.Application;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\nimport javax.swing.JComponent;\nimport javax.swing.JMenuItem;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.ui.cpu.CPUView;\nimport org.graalvm.visualvm.lib.ui.cpu.LiveCPUView;\nimport org.graalvm.visualvm.lib.ui.memory.LiveMemoryView;\nimport org.graalvm.visualvm.lib.ui.results.DataView;\nimport org.openide.util.Lookup;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nclass ProfilerActionsSupport {\n    \n    @ServiceProvider(service=DataView.PopupCustomizer.class, position=100)\n    public static final class ResultsAction extends DataView.PopupCustomizer {\n\n        public JMenuItem[] getMenuItems(JComponent invoker, DataView dv, Object value, ClientUtils.SourceCodeSelection scs) {\n            Collection<? extends ProfilerPopupCustomizer> customizers =\n                    Lookup.getDefault().lookupAll(ProfilerPopupCustomizer.class);\n\n            if (customizers.isEmpty()) return null;\n            \n            ProfilerPopupCustomizer.View view;\n            ProfilerPopupCustomizer.Mode mode;\n            \n            if (dv instanceof CPUView) {\n                view = ProfilerPopupCustomizer.View.CPU;\n                mode = invoker instanceof LiveCPUView ?\n                        ProfilerPopupCustomizer.Mode.LIVE :\n                        ProfilerPopupCustomizer.Mode.SNAPSHOT;\n            } else {\n                view = ProfilerPopupCustomizer.View.MEMORY;\n                mode = invoker instanceof LiveMemoryView ?\n                        ProfilerPopupCustomizer.Mode.LIVE :\n                        ProfilerPopupCustomizer.Mode.SNAPSHOT;\n            }\n            \n            Object _application = invoker.getClientProperty(ProfilerResultsAction.PROP_APPLICATION);\n            Application application = _application instanceof Application ? (Application)_application : null;\n\n            String className = scs == null ? null : scs.getClassName();\n            String methodName = scs == null ? null : scs.getMethodName();\n            String methodSignature = scs == null ? null : scs.getMethodSignature();\n            \n            ProfiledSourceSelection pss = new ProfiledSourceSelection(application, className, methodName, methodSignature);\n\n            List<JMenuItem> menuItems = new ArrayList<>(customizers.size());\n\n            for (ProfilerPopupCustomizer customizer : customizers) {\n                if (customizer.supportsDataView(view, mode)) {\n                    JMenuItem[] items = customizer.getMenuItems(pss, view, mode);\n                    if (items != null) Collections.addAll(menuItems, items);\n                }\n            }\n\n            return menuItems.isEmpty() ? null : menuItems.toArray(new JMenuItem[0]);\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/actions/ProfilerPopupCustomizer.java",
    "content": "/*\n *  Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiling.actions;\n\nimport javax.swing.JMenuItem;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerPopupCustomizer {\n    \n    public static enum View { CPU, MEMORY }\n    \n    public static enum Mode { LIVE, SNAPSHOT }\n    \n    \n    public boolean supportsDataView(View view, Mode mode) { return true; }\n    \n    public abstract JMenuItem[] getMenuItems(ProfiledSourceSelection pss, View view, Mode mode);\n    \n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/actions/ProfilerResultsAction.java",
    "content": "/*\n *  Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiling.actions;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerResultsAction {\n    \n    public static final String PROP_APPLICATION = \"profiled_application\"; // NOI18N\n    \n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOptionsCategory_Name_Profiling=Profiling\n\nLBL_Settings=Settings\n\nLBL_Cpu_settings=CPU settings\n\nLBL_Memory_settings=Memory settings\n\nLBL_Profile_Allocations=&Profile object allocations\n\nLBL_Profile_AllocationsGC=Pr&ofile object allocations and GC\n\nLBL_Record_Stacktraces=R&ecord allocations stack traces\n\nLBL_Run_GC=Run GC when getting results\n\nLBL_Restore_Defaults=Restore Defaults\n\nLBL_Root_Classes=&Profile classes\\:\n\nLBL_Query_Filter=&Profile SQL queries containing text\\:\n\nLBL_Query_Hint=Leave the filter empty to profile all SQL queries\n\n#LBL_Profile_Runnables=Pr&ofile new Runnables\n\nLBL_Profile_Incl=&Include outgoing calls\\:\n\nLBL_Profile_Excl=&Exclude outgoing calls\\:\n\nLBL_Profile_Incl_S=&Profile only classes\\:\n\nLBL_Profile_Excl_S=&Do not profile classes\\:\n\nTOOLTIP_Root_Classes=<html>Profile methods of these classes or packages:<br><br><code>&nbsp;org.mypackage.**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package and subpackages<br><code>&nbsp;org.mypackage.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package<br><code>&nbsp;org.mypackage.MyClass&nbsp;&nbsp;</code>single class<br><br>Special case:<br><br><code>&nbsp;* or **</code>&nbsp;&nbsp;include all classes<br></html>\n\nTOOLTIP_Query_Filter=<html>Limit profiled SQL queries based on the text filter (contains).<br><br>Empty filter profiles all SQL queries.</html>\n\n#TOOLTIP_New_Runnables=Classes invoked from new Threads or Runnables are automatically instrumented\n\nTOOLTIP_Inclusive_Filter=Profile only outgoing calls of the defined classes or packages\n\nTOOLTIP_Exclusive_Filter=Do not profile outgoing calls of the defined classes or packages\n\nTOOLTIP_Inclusive_Filter_S=Profile only methods of the defined classes or packages\n\nTOOLTIP_Exclusive_Filter_S=Do not profile methods of the defined classes or packages\n\nTOOLTIP_Instrumentation_Filter=<html>Include/exclude profiling outgoing calls from these classes or packages:<br><br><code>&nbsp;org.mypackage.**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package and subpackages<br><code>&nbsp;org.mypackage.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package<br><code>&nbsp;org.mypackage.MyClass&nbsp;&nbsp;</code>single class<br><br>Special case:<br><br><code>&nbsp;&lt;empty&gt; or * or **</code>&nbsp;&nbsp;include all classes<br></html>\n\nTOOLTIP_Instrumentation_Filter_S=<html>Profile/do not profile methods of these classes or packages:<br><br><code>&nbsp;org.mypackage.**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package and subpackages<br><code>&nbsp;org.mypackage.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package<br><code>&nbsp;org.mypackage.MyClass&nbsp;&nbsp;</code>single class<br><br>Special case:<br><br><code>&nbsp;&lt;empty&gt; or * or **</code>&nbsp;&nbsp;include all classes<br></html>\n\nTOOLTIP_Allocations=Only object allocations are recorded\n\nTOOLTIP_Allocations_GC=Whole lifecycle of allocated objects is recorded\n\nLBL_Track_Every1=Tr&ack every\n\nLBL_Track_Every2=object allocations\n\nTOOLTIP_Track_Every=Only every n-th object is tracked to reduce profiling overhead. Total number of allocated objects is not affected.\n\nTOOLTIP_Stack_Traces=Information about methods allocating the objects is collected\n\nLBL_Custom=Custom\n\nBTN_Save=Save...\n\nBTN_Edit=Edit...\n\nLBL_Preset=Preset\\:\n\nMSG_Preset=Preset\n\nMSG_Default=Default\n\nCAPTION_Presets=Presets\n\nMSG_No_presets=<No Presets Defined>\n\nTOOLTIP_Create_preset=Create new preset\n\nTOOLTIP_Delete_preset=Delete selected preset\n\nTOOLTIP_preset_up=Move selected preset up\n\nTOOLTIP_preset_down=Move selected preset down\n\nLBL_Preset_name=Preset &Name\\:\n\nLBL_Preselect_for=Preselect &For\\:\n\nLBL_Optional_class=[Optional Main Class or Display Name]\n\nLBL_Sampler_cpu=Sampler CPU\n\nLBL_Sampler_memory=Sampler Memory\n\nLBL_Profiler_cpu=Profiler CPU\n\nLBL_Profiler_memory=Profiler Memory\n\nLBL_Profiler_jdbc=Profiler JDBC\n\nLBL_Sampling_rate=&Sampling frequency\\:\n\nTOOLTIP_Sampling_rate=Sampling frequency [ms]\n\nLBL_units_ms=ms.\n\nLBL_Refresh_rate=R&esults refresh\\:\n\nTOOLTIP_Refresh_rate=Results refresh rate [ms]\n\nLBL_Sampling_refresh=&Sampling and refresh rate\\:\n\nTOOLTIP_Sampling_refresh=Sampling frequency and results refresh rate [ms]\n\nTOOLTIP_Defined_presets=Defined presets\n\nTOOLTIP_Manage_presets=Create or manage presets\n\nHINT_Define_roots=<define classes to be profiled>\n\nCAPTION_DeletedRestart=Calibration Data Reset\nMSG_DeletedRestart=<html><b>Restart VisualVM?</b><br><br>Calibration data successfully reset. Do you want to restart<br>VisualVM now to perform a new calibration?</html>\n\nProfilerMemoryPanel_TOOLTIP_Filter=<html>Profile these classes:<br><br><code>&nbsp;org.mypackage.**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package and subpackages<br><code>&nbsp;org.mypackage.*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>all classes in package<br><code>&nbsp;org.mypackage.MyClass&nbsp;&nbsp;</code>single class<br><br>Special cases:<br><br><code>&nbsp;char[]&nbsp;&nbsp;</code>primitive array<br><code>&nbsp;*&nbsp;or&nbsp;**&nbsp;</code>all classes<br><code>&nbsp;[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>(on a separate line) include arrays matching the filter<br></html>\nProfilerMemoryPanel_BTN_Track_live=Track only live objects\nProfilerMemoryPanel_TOOLTIP_Track_live=Unselect to profile all created objects (including those already released from the heap)\nProfilerMemoryPanel_BTN_Limit_alloc=Limit allocations depth\\:\nProfilerMemoryPanel_TOOLTIP_Limit_alloc=Unselect to collect full depth allocations call tree\nProfilerMemoryPanel_TOOLTIP_Limit_alloc2=Limit depth of allocations call tree (select 0 for no allocation calls)\nProfilerMemoryPanel_LBL_unlimited=unlimited\nProfilerMemoryPanel_LBL_No_alloc=(no allocation calls)\nProfilerJDBCPanel_BTN_QuerySize=Maximum JDBC query size:\nProfilerJDBCPanel_TOOLTIP_QuerySize=Maximum JDBC query size (can be set from {0} to {1})\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/PresetSelector.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.util.List;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.JButton;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class PresetSelector extends JPanel {\n    \n    private final Runnable presetSynchronizer;\n    \n    private JLabel presetsLabel;\n    private JComboBox<ProfilerPreset> presetsCombo;\n    private JButton presetsButton;\n    \n    private final DefaultComboBoxModel<ProfilerPreset> selectorsModel;\n    private final List<PresetSelector> allSelectors;\n    \n    private boolean savingCustom;\n    \n    private boolean customSelected;\n    private boolean internalChange = false;\n    \n    \n    PresetSelector(DefaultComboBoxModel<ProfilerPreset> selectorsModel, List<PresetSelector> allSelectors,\n                   Runnable presetSynchronizer) {\n        \n        this.selectorsModel = selectorsModel;\n        this.allSelectors = allSelectors;\n        \n        this.presetSynchronizer = presetSynchronizer;\n        \n        initComponents();\n        \n        SwingUtilities.invokeLater(this::notifySynchronizer);\n    }\n    \n    \n    public ProfilerPreset getSelectedPreset() {\n        return (ProfilerPreset)presetsCombo.getSelectedItem();\n    }\n    \n    public ProfilerPreset customize(boolean presetValid) {\n        ProfilerPreset custom = customPreset(true);\n        custom.setValid(presetValid);\n        internalChange = true;\n        for (PresetSelector pSelector : allSelectors) pSelector.presetsCombo.setSelectedIndex(1);\n        internalChange = false;\n        return custom;\n    }\n    \n    \n    DefaultComboBoxModel<ProfilerPreset> getModel() {\n        return selectorsModel;\n    }\n    \n    boolean checkSavingCustom() {\n        boolean ret = savingCustom;\n        savingCustom = false;\n        return ret;\n    }\n    \n    \n    private void selectedPresetChanged() {\n        Object selected = presetsCombo.getSelectedItem();\n        if (selected == null) return;\n        \n        boolean custom = selected == customPreset(false);\n        if (customSelected != custom) {\n            customSelected = custom;\n            presetsButton.setText(custom ? NbBundle.getMessage(PresetSelector.class,\n                                  \"BTN_Save\") : NbBundle.getMessage(PresetSelector.class, // NOI18N\n                                  \"BTN_Edit\")); // NOI18N\n        }\n//        updatePresetsButton(true);\n        if (internalChange) return;\n        notifySynchronizer();\n    }\n    \n    private void actionRequested() {\n        if (customSelected) {\n            savingCustom = true;\n            ProfilerPresets.getInstance().savePreset(new ProfilerPreset(customPreset(true)));\n        } else {\n            ProfilerPresets.getInstance().editPresets(getSelectedPreset());\n        }\n    }\n    \n    private void notifySynchronizer() {\n        SwingUtilities.invokeLater(presetSynchronizer::run);\n    }\n    \n    \n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        presetsLabel.setEnabled(enabled);\n        presetsCombo.setEnabled(enabled);\n        presetsButton.setEnabled(enabled);\n//        updatePresetsButton(enabled);\n    }\n    \n//    private void updatePresetsButton(boolean enabled) {\n//        ProfilerPreset preset = getSelectedPreset();\n//        for (PresetSelector pselector : allSelectors)\n//            pselector.presetsButton.setEnabled(enabled && preset != null && preset.isValid());\n//    }\n    \n    \n    private ProfilerPreset customPreset(boolean create) {\n        ProfilerPreset custom = new ProfilerPreset((ProfilerPreset)selectorsModel.getSelectedItem());\n        custom.setName(NbBundle.getMessage(PresetSelector.class, \"LBL_Custom\")); // NOI18N\n        \n        if (selectorsModel.getSize() > 1) {\n            ProfilerPreset customO = selectorsModel.getElementAt(1);\n            if (custom.equals(customO)) return customO;\n        }\n        \n        if (!create) return null;\n        \n        custom.setSelector((selectorsModel.getElementAt(0)).getSelector());\n        \n        internalChange = true;\n        selectorsModel.insertElementAt(custom, 1);\n        internalChange = false;\n        \n        return custom;\n    }\n    \n    public static boolean isCustomPreset(ProfilerPreset preset) {\n        return NbBundle.getMessage(PresetSelector.class, \"LBL_Custom\").equals(preset.getName()); // NOI18N\n    }\n    \n    \n    private void initComponents() {\n        setOpaque(false);\n        setLayout(new BorderLayout(5, 0));\n        \n        // presetsLabel\n        presetsLabel = new JLabel(NbBundle.getMessage(PresetSelector.class,\n                                  \"LBL_Preset\")); // NOI18N\n        presetsLabel.setToolTipText(NbBundle.getMessage(PresetSelector.class,\n                                    \"TOOLTIP_Defined_presets\")); // NOI18N\n        add(presetsLabel, BorderLayout.WEST);\n        \n        // presetsCombo\n        presetsCombo = new JComboBox<>(selectorsModel);\n        presetsCombo.setToolTipText(NbBundle.getMessage(PresetSelector.class,\n                                    \"TOOLTIP_Defined_presets\")); // NOI18N\n        presetsCombo.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { selectedPresetChanged(); }\n        });\n        add(presetsCombo, BorderLayout.CENTER);\n        \n        // presetsButton\n        presetsButton = new JButton(NbBundle.getMessage(PresetSelector.class, \"BTN_Save\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent e) { actionRequested(); }\n        };\n        presetsButton.setToolTipText(NbBundle.getMessage(PresetSelector.class,\n                                     \"TOOLTIP_Manage_presets\")); // NOI18N\n        add(presetsButton, BorderLayout.EAST);\n        \n        // UI tweaks\n        Dimension dim1 = presetsButton.getPreferredSize();\n        presetsButton.setText(NbBundle.getMessage(PresetSelector.class, \"BTN_Edit\")); // NOI18N\n        Dimension dim2 = presetsButton.getPreferredSize();\n        dim1.width = Math.max(dim1.width, dim2.width);\n        dim1.height = Math.max(dim1.height, dim2.height);\n        presetsButton.setPreferredSize(dim1);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/PresetsUtils.java",
    "content": "/*\n * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport java.util.regex.Pattern;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class PresetsUtils {\n    \n    static String normalizeValue(String value) {\n        String[] values = value.split(\"\\\\n\"); // NOI18N\n        StringBuilder normalizedValue = new StringBuilder();\n\n        for (int i = 0; i < values.length; i++) {\n            String filterValue = values[i].trim();\n            if ((i != (values.length - 1)) && !filterValue.endsWith(\",\")) // NOI18N\n                filterValue = filterValue + \",\"; // NOI18N\n            normalizedValue.append(filterValue);\n        }\n\n        return normalizedValue.toString();\n    }\n    \n    \n    static boolean isValidJavaValue(String normalizedValue, boolean allowEmpty, boolean acceptArrays) {\n        // check whether empty value is allowed\n        if (normalizedValue.isEmpty()) return allowEmpty;\n        \n        String[] values = GenericFilter.values(normalizedValue);\n        for (String value : values) {\n            // remove up to two trailing wildcards\n            boolean hadWildcard = value.endsWith(\"*\"); // NOI18N\n            if (hadWildcard) value = value.substring(0, value.length() - 1);\n            if (value.endsWith(\"*\")) value = value.substring(0, value.length() - 1); // NOI18N\n            \n            if (hadWildcard) {\n                // wildcards can only be standalone or prefixed by dot\n                if (!value.isEmpty() && !value.endsWith(\".\")) return false; // NOI18N\n            } else if (acceptArrays) {\n                int len = value.length();\n\n                // remove trailing arrays if allowed and not followed by wildcards\n                while (value.endsWith(\"[]\")) value = value.substring(0, value.length() - 2); // NOI18N\n\n                // multiple array marks only allowed when prefixed by Java identifier\n                if (len - value.length() > 2 && value.isEmpty()) return false;\n            }\n            \n            // empty line is allowed\n            if (value.isEmpty()) continue;\n            \n            // trailing dot only allowed when followed by wildcards\n            if (value.endsWith(\".\")) { // NOI18N\n                if (!hadWildcard) return false;\n                value = value.substring(0, value.length() - 1); // NOI18N\n            }\n            \n            // check whether the result is a valid Java identifier\n            if (!isValidJavaIdentifier(value)) return false;\n        }\n        \n        return true;\n    }\n    \n    \n    private static Pattern JAVA_IDENTIFIER_PATTERN;\n    private static boolean isValidJavaIdentifier(String identifier) {\n        if (JAVA_IDENTIFIER_PATTERN == null) {\n            String ID_PATTERN = \"\\\\p{javaJavaIdentifierStart}\\\\p{javaJavaIdentifierPart}*\"; // NOI18N\n            JAVA_IDENTIFIER_PATTERN = Pattern.compile(ID_PATTERN + \"(\\\\.\" + ID_PATTERN + \")*\"); // NOI18N\n        }\n        return JAVA_IDENTIFIER_PATTERN.matcher(identifier).matches();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/ProfilerCPUPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport javax.swing.AbstractButton;\nimport javax.swing.BorderFactory;\nimport javax.swing.ButtonGroup;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JRadioButton;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextArea;\nimport javax.swing.UIManager;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.filters.JavaTypeFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerCPUPanel extends JPanel {\n    \n    private JLabel rootClassesLabel;\n    private TextAreaComponent rootsArea;\n//    private JCheckBox runnablesCheckBox;\n    private JRadioButton inclFilterRadioButton;\n    private JRadioButton exclFilterRadioButton;\n    private TextAreaComponent filtersArea;\n    \n    private final Runnable validator;\n    private boolean rootsValid = true;\n    private boolean filtersValid = true;\n    private boolean internalChange;\n    \n    \n    public ProfilerCPUPanel() {\n        this(null, false);\n    }\n    \n    ProfilerCPUPanel(Runnable validator, boolean mnemonics) {\n        this.validator = validator;\n        initComponents(mnemonics);\n    }\n    \n    \n    public ProfilingSettings getSettings() {\n        ProfilingSettings settings = ProfilerIDESettings.getInstance().createDefaultProfilingSettings();\n        settings.setProfilingType(ProfilingSettings.PROFILE_CPU_PART);\n        settings.setCPUProfilingType(settings.getSamplingInterval() <= 0 ?\n                                     CommonConstants.CPU_INSTR_FULL :\n                                     CommonConstants.CPU_INSTR_SAMPLED);\n        \n        String[] rootsValues = GenericFilter.values(PresetsUtils.normalizeValue(getRootsValue()));\n        ClientUtils.SourceCodeSelection[] roots = (rootsValues.length == 1 && rootsValues[0].isEmpty()) ?\n            new ClientUtils.SourceCodeSelection[0] :\n            new ClientUtils.SourceCodeSelection[rootsValues.length];\n        for (int i = 0; i < roots.length; i++)\n            roots[i] = new ClientUtils.SourceCodeSelection(rootsValues[i], \"*\", null); // NOI18N\n        settings.addRootMethods(roots);\n        \n        String filter = getFilterValue();\n        if (filter.isEmpty() || \"*\".equals(filter) || \"**\".equals(filter)) { // NOI18N\n            settings.setInstrumentationFilter(new JavaTypeFilter());\n        } else {\n            int filterType = inclFilterRadioButton.isSelected() ?\n                             JavaTypeFilter.TYPE_INCLUSIVE : JavaTypeFilter.TYPE_EXCLUSIVE;\n            String filterValue = PresetsUtils.normalizeValue(filter);\n            settings.setInstrumentationFilter(new JavaTypeFilter(filterValue, filterType));\n        }\n        \n        settings.setStackDepthLimit(Integer.MAX_VALUE);\n        \n        return settings;\n    }\n    \n    \n    public boolean settingsValid() { return rootsValid && filtersValid; }\n    \n    public void highlightInvalid() {\n        if (getRootsValue().isEmpty()) rootsArea.getTextArea().setText(ProfilerPresets.DEFINE_CLASSES);\n    }\n    \n    public void loadFromPreset(ProfilerPreset preset) {\n        if (preset == null) return;\n\n        internalChange = true;\n        rootsArea.getTextArea().setText(preset.getRootsP());\n//        runnablesCheckBox.setSelected(preset.getRunnablesP());\n        inclFilterRadioButton.setSelected(!preset.getFilterModeP());\n        exclFilterRadioButton.setSelected(preset.getFilterModeP());\n        filtersArea.getTextArea().setText(preset.getFilterP());\n        highlightInvalid();\n        internalChange = false;\n        \n        checkRootValidity();\n        checkFilterValidity();\n    }\n    \n    public void saveToPreset(ProfilerPreset preset) {\n        if (preset == null) return;\n        \n        preset.setRootsP(getRootsValue());\n//        preset.setRunnablesP(runnablesCheckBox.isSelected());\n        preset.setFilterModeP(exclFilterRadioButton.isSelected());\n        preset.setFilterP(getFilterValue());\n    }\n    \n    public abstract void settingsChanged();\n    \n    private void syncUI() {\n        if (internalChange) return;\n        settingsChanged();\n    }\n    \n    \n    private void checkRootValidity() {\n        rootsValid = isRootValueValid();\n        rootsArea.getTextArea().setForeground(rootsValid ?\n            UIManager.getColor(\"TextArea.foreground\") : Color.RED); // NOI18N\n        if (validator != null) validator.run();\n    }\n    \n    public boolean isRootValueValid() {\n        String rootsValue = PresetsUtils.normalizeValue(getRootsValue());\n        return PresetsUtils.isValidJavaValue(rootsValue, false, false);\n    }\n    \n    private String getRootsValue() {\n        return rootsArea.getTextArea().getText().trim();\n    }\n    \n    private void checkFilterValidity() {\n        filtersValid = isFilterValueValid();\n        filtersArea.getTextArea().setForeground(filtersValid ?\n            UIManager.getColor(\"TextArea.foreground\") : Color.RED); // NOI18N\n        if (validator != null) validator.run();\n    }\n    \n    public boolean isFilterValueValid() {\n        String filterValue = PresetsUtils.normalizeValue(getFilterValue());\n        return PresetsUtils.isValidJavaValue(filterValue, true, false);\n    }\n\n    private String getFilterValue() {\n        return filtersArea.getTextArea().getText().trim();\n    }\n    \n    \n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        for (Component c : getComponents()) c.setEnabled(enabled);\n    }\n    \n    private void initComponents(boolean mnemonics) {\n        setOpaque(false);\n        setLayout(new GridBagLayout());\n        \n        ButtonGroup filterRadiosGroup = new ButtonGroup();\n        GridBagConstraints constraints;\n        \n        rootClassesLabel = new JLabel();\n        setText(rootClassesLabel, NbBundle.getMessage(ProfilerCPUPanel.class, \"LBL_Root_Classes\"), mnemonics); // NOI18N\n        Dimension d = rootClassesLabel.getPreferredSize();\n        JRadioButton refRadion = new JRadioButton(NbBundle.getMessage(ProfilerCPUPanel.class, \"LBL_Root_Classes\")); // NOI18N\n        refRadion.setBorder(rootClassesLabel.getBorder());\n        d.height = Math.max(d.height, refRadion.getPreferredSize().height);\n        rootClassesLabel.setPreferredSize(d);\n        rootClassesLabel.setToolTipText(NbBundle.getMessage(ProfilerCPUPanel.class, \"TOOLTIP_Root_Classes\")); // NOI18N\n        rootClassesLabel.setOpaque(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(10, 10, 5, 10);\n        add(rootClassesLabel, constraints);\n        \n        rootsArea = createTextArea(2);\n        rootClassesLabel.setLabelFor(rootsArea.getTextArea());\n        rootsArea.getTextArea().setToolTipText(NbBundle.getMessage(ProfilerCPUPanel.class, \"TOOLTIP_Root_Classes\")); // NOI18N\n        rootsArea.getTextArea().getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) { checkRootValidity(); syncUI(); }\n            public void removeUpdate(DocumentEvent e) { checkRootValidity(); syncUI(); }\n            public void changedUpdate(DocumentEvent e) { checkRootValidity(); syncUI(); }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 2;\n        constraints.weightx = 1;\n        constraints.weighty = 0.65;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.insets = new Insets(0, 10, 10, 10);\n        add(rootsArea, constraints);\n        \n//        runnablesCheckBox = new JCheckBox() {\n//            protected void fireActionPerformed(ActionEvent e) { syncUI(); }\n//        };\n//        setText(runnablesCheckBox, NbBundle.getMessage(ProfilerCPUSettings.class,\n//                \"LBL_Profile_Runnables\"), mnemonics);\n//        runnablesCheckBox.setToolTipText(NbBundle.getMessage(ProfilerCPUSettings.class, \"TOOLTIP_New_Runnables\")); // NOI18N\n//        runnablesCheckBox.setOpaque(false);\n//        runnablesCheckBox.setBorder(rootClassesLabel.getBorder());\n//        constraints = new GridBagConstraints();\n//        constraints.gridx = 0;\n//        constraints.gridy = 3;\n//        constraints.gridwidth = GridBagConstraints.REMAINDER;\n//        constraints.anchor = GridBagConstraints.WEST;\n//        constraints.fill = GridBagConstraints.NONE;\n//        constraints.insets = new Insets(0, 10, 10, 10);\n//        add(runnablesCheckBox, constraints);\n        \n        inclFilterRadioButton = new JRadioButton() {\n            protected void fireActionPerformed(ActionEvent e) { syncUI(); }\n        };\n        setText(inclFilterRadioButton, NbBundle.getMessage(ProfilerCPUPanel.class,\n                \"LBL_Profile_Incl\"), mnemonics);\n        inclFilterRadioButton.setToolTipText(NbBundle.getMessage(ProfilerCPUPanel.class, \"TOOLTIP_Inclusive_Filter\")); // NOI18N\n        inclFilterRadioButton.setOpaque(false);\n        inclFilterRadioButton.setBorder(rootClassesLabel.getBorder());\n        filterRadiosGroup.add(inclFilterRadioButton);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 3;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 10, 5, 5);\n        add(inclFilterRadioButton, constraints);\n        \n        exclFilterRadioButton = new JRadioButton() {\n            protected void fireActionPerformed(ActionEvent e) { syncUI(); }\n        };\n        setText(exclFilterRadioButton, NbBundle.getMessage(ProfilerCPUPanel.class,\n                \"LBL_Profile_Excl\"), mnemonics);\n        exclFilterRadioButton.setToolTipText(NbBundle.getMessage(ProfilerCPUPanel.class, \"TOOLTIP_Exclusive_Filter\")); // NOI18N\n        exclFilterRadioButton.setOpaque(false);\n        exclFilterRadioButton.setBorder(rootClassesLabel.getBorder());\n        filterRadiosGroup.add(exclFilterRadioButton);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 1;\n        constraints.gridy = 3;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 5, 5, 10);\n        add(exclFilterRadioButton, constraints);\n        \n        filtersArea = createTextArea(2);\n        filtersArea.getTextArea().setToolTipText(NbBundle.getMessage(ProfilerCPUPanel.class, \"TOOLTIP_Instrumentation_Filter\")); // NOI18N\n        filtersArea.getTextArea().getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) { checkFilterValidity(); syncUI(); }\n            public void removeUpdate(DocumentEvent e) { checkFilterValidity(); syncUI(); }\n            public void changedUpdate(DocumentEvent e) { checkFilterValidity(); syncUI(); }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 4;\n        constraints.weighty = 0.35;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.insets = new Insets(0, 10, 10, 10);\n        add(filtersArea, constraints);\n    }\n    \n    \n    private static void setText(JLabel l, String text, boolean mnemonics) {\n        if (mnemonics) Mnemonics.setLocalizedText(l, text);\n        else l.setText(text.replace(\"&\", \"\")); // NOI18N\n    }\n    \n    private static void setText(AbstractButton b, String text, boolean mnemonics) {\n        if (mnemonics) Mnemonics.setLocalizedText(b, text);\n        else b.setText(text.replace(\"&\", \"\")); // NOI18N\n    }\n    \n    \n    private static TextAreaComponent createTextArea(int rows) {\n        final JTextArea rootsArea = new JTextArea();\n        rootsArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, UIManager.getFont(\"Label.font\").getSize())); // NOI18N\n        TextAreaComponent rootsAreaScrollPane = new TextAreaComponent(rootsArea,\n                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                rootsArea.setEnabled(enabled);\n            }\n        };\n        rootsAreaScrollPane.setBorder(BorderFactory.createLineBorder(Color.GRAY));\n        JTextArea referenceArea = new JTextArea(\"X\"); // NOI18N\n        referenceArea.setFont(rootsArea.getFont());\n        referenceArea.setRows(rows);\n        Insets insets = rootsAreaScrollPane.getInsets();\n        rootsAreaScrollPane.setPreferredSize(new Dimension(1, referenceArea.getPreferredSize().height + \n                (insets != null ? insets.top + insets.bottom : 0)));\n        return rootsAreaScrollPane;\n    }\n    \n    private static class TextAreaComponent extends JScrollPane {\n        TextAreaComponent(JTextArea textArea, int vPolicy, int hPolicy) { super(textArea, vPolicy, hPolicy); }\n        public JTextArea getTextArea() { return (JTextArea)getViewport().getView(); }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/ProfilerCPUSettings.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport javax.swing.JPanel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ProfilerCPUSettings extends JPanel {\n    \n    private ProfilerPreset preset;\n    private final ProfilerCPUPanel panel;\n    \n    \n    ProfilerCPUSettings(Runnable validator) {\n        this.panel = new ProfilerCPUPanel(validator, true) {\n            public void settingsChanged() { panel.saveToPreset(preset); }\n        };\n        setLayout(new BorderLayout());\n        add(panel, BorderLayout.CENTER);\n    }\n\n    void setPreset(ProfilerPreset preset) {\n        this.preset = preset;\n        panel.loadFromPreset(preset);\n    }\n\n    boolean valid() { return panel.settingsValid(); }\n\n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        for (Component c : getComponents())\n            c.setEnabled(enabled);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/ProfilerJDBCPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport javax.swing.BorderFactory;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JRadioButton;\nimport javax.swing.JScrollPane;\nimport javax.swing.JSpinner;\nimport javax.swing.JTextArea;\nimport javax.swing.JTextField;\nimport javax.swing.SpinnerNumberModel;\nimport javax.swing.UIManager;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.filters.TextFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.jfluid.results.jdbc.JdbcCCTProvider;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.graalvm.visualvm.uisupport.JExtendedSpinner;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerJDBCPanel extends JPanel {\n    \n    private static final String[] JDBC_MARKER_CLASSES = {\n        JdbcCCTProvider.DRIVER_INTERFACE,\n        JdbcCCTProvider.CONNECTION_INTERFACE,\n        JdbcCCTProvider.STATEMENT_INTERFACE,\n        JdbcCCTProvider.PREPARED_STATEMENT_INTERFACE,\n        JdbcCCTProvider.CALLABLE_STATEMENT_INTERFACE\n    };\n    \n    \n    private JLabel filterLabel;\n    private TextAreaComponent filterArea;\n    private JLabel querySizeLabel;\n    private JExtendedSpinner querySizeSpinner;\n    \n    private boolean internalChange;\n    \n    \n    public ProfilerJDBCPanel() {\n        this(false);\n    }\n    \n    ProfilerJDBCPanel(boolean mnemonics) {\n        initComponents(mnemonics);\n    }\n    \n    \n    public ProfilingSettings getSettings() {\n        ProfilingSettings settings = ProfilerIDESettings.getInstance().createDefaultProfilingSettings();\n        settings.setProfilingType(ProfilingSettings.PROFILE_CPU_JDBC);\n        settings.setCPUProfilingType(CommonConstants.CPU_INSTR_FULL);\n\n        ClientUtils.SourceCodeSelection[] roots = new ClientUtils.SourceCodeSelection[JDBC_MARKER_CLASSES.length];\n        for (int i = 0; i < JDBC_MARKER_CLASSES.length; i++) {\n            roots[i] = new ClientUtils.SourceCodeSelection(JDBC_MARKER_CLASSES[i], \"*\", null); // NOI18N\n            roots[i].setMarkerMethod(true);\n        }\n        settings.addRootMethods(roots);\n\n        String filter = PresetsUtils.normalizeValue(getFilterValue());\n        settings.setInstrumentationFilter(new TextFilter(filter, TextFilter.TYPE_INCLUSIVE, false));\n        settings.setMaxStringLength(getQSizeValue());\n        \n        return settings;\n    }\n    \n    \n    public boolean settingsValid() { return true; }\n    \n    public void loadFromPreset(ProfilerPreset preset) {\n        if (preset == null) return;\n\n        internalChange = true;\n        filterArea.getTextArea().setText(preset.getJDBCFilterP().trim());\n        querySizeSpinner.setValue(preset.getJDBCFQSizeP());\n        internalChange = false;\n    }\n    \n    public void saveToPreset(ProfilerPreset preset) {\n        if (preset == null) return;\n        preset.setJDBCFilterP(getFilterValue());\n        preset.setJDBCQSizerP(getQSizeValue().intValue());\n    }\n    \n    public abstract void settingsChanged();\n    \n    private void syncUI() {\n        if (internalChange) return;\n        settingsChanged();\n    }\n    \n    \n    private String getFilterValue() {\n        return filterArea.getTextArea().getText().trim();\n    }\n    \n    private Integer getQSizeValue() {\n        return (Integer) querySizeSpinner.getValue();\n    }\n    \n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        for (Component c : getComponents()) c.setEnabled(enabled);\n    }\n    \n    private void initComponents(boolean mnemonics) {\n        setOpaque(false);\n        setLayout(new GridBagLayout());\n        \n        GridBagConstraints constraints;\n        \n        filterLabel = new JLabel();\n        setText(filterLabel, NbBundle.getMessage(ProfilerJDBCPanel.class, \"LBL_Query_Filter\"), mnemonics); // NOI18N\n        Dimension d = filterLabel.getPreferredSize();\n        JRadioButton refRadion = new JRadioButton(NbBundle.getMessage(ProfilerJDBCPanel.class, \"LBL_Root_Classes\")); // NOI18N\n        refRadion.setBorder(filterLabel.getBorder());\n        d.height = Math.max(d.height, refRadion.getPreferredSize().height);\n        filterLabel.setPreferredSize(d);\n        filterLabel.setToolTipText(NbBundle.getMessage(ProfilerJDBCPanel.class, \"TOOLTIP_Query_Filter\")); // NOI18N\n        filterLabel.setOpaque(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(10, 10, 5, 10);\n        add(filterLabel, constraints);\n        \n        filterArea = createTextArea(2);\n        filterLabel.setLabelFor(filterArea.getTextArea());\n        filterArea.getTextArea().setToolTipText(NbBundle.getMessage(ProfilerJDBCPanel.class, \"TOOLTIP_Query_Filter\")); // NOI18N\n        filterArea.getTextArea().getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) { syncUI(); }\n            public void removeUpdate(DocumentEvent e) { syncUI(); }\n            public void changedUpdate(DocumentEvent e) { syncUI(); }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 2;\n        constraints.weightx = 1;\n        constraints.weighty = 0.65;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.insets = new Insets(0, 10, 5, 10);\n        add(filterArea, constraints);\n        \n        JLabel hintLabel = new JLabel(NbBundle.getMessage(ProfilerJDBCPanel.class, \"LBL_Query_Hint\")) { // NOI18N\n            {\n                super.setEnabled(false);\n            }\n            public void setEnabled(boolean b) {\n                super.setEnabled(false);\n            }\n        };\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 3;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(0, 10, 5, 10);\n        add(hintLabel, constraints);\n        \n        querySizeLabel = new JLabel(NbBundle.getMessage(ProfilerMemoryPanel.class, \"ProfilerJDBCPanel_BTN_QuerySize\")); // NOI18N\n        querySizeLabel.setToolTipText(NbBundle.getMessage(ProfilerMemoryPanel.class,\n                \"ProfilerJDBCPanel_TOOLTIP_QuerySize\", // NOI18N\n                CommonConstants.MAX_STRING_LENGTH_DEFAULT,\n                CommonConstants.MAX_STRING_LENGTH_TOP_LIMIT)\n        );\n        querySizeLabel.setOpaque(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 4;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 10, 5, 5);\n        add(querySizeLabel, constraints);\n\n        querySizeSpinner = new JExtendedSpinner(new SpinnerNumberModel(CommonConstants.MAX_STRING_LENGTH_DEFAULT,\n                CommonConstants.MAX_STRING_LENGTH_DEFAULT, CommonConstants.MAX_STRING_LENGTH_TOP_LIMIT, 10));\n        querySizeSpinner.setToolTipText(NbBundle.getMessage(ProfilerJDBCPanel.class,\n                \"ProfilerJDBCPanel_TOOLTIP_QuerySize\",  // NOI18N\n                CommonConstants.MAX_STRING_LENGTH_DEFAULT,\n                CommonConstants.MAX_STRING_LENGTH_TOP_LIMIT)\n        );\n        JComponent editor = querySizeSpinner.getEditor();\n        JTextField field = editor instanceof JSpinner.DefaultEditor ?\n                ((JSpinner.DefaultEditor)editor).getTextField() : null;\n        if (field != null) field.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) { change(); }\n            public void removeUpdate(DocumentEvent e) { change(); }\n            public void changedUpdate(DocumentEvent e) { change(); }\n            private void change() {\n                syncUI();\n            }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 1;\n        constraints.gridy = 4;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 0, 5, 5);\n        add(querySizeSpinner, constraints);\n\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 5;\n        constraints.weightx = 1;\n        constraints.weighty = 0.35;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.insets = new Insets(0, 0, 0, 0);\n        add(Spacer.create(), constraints);\n    }\n    \n    \n    private static void setText(JLabel l, String text, boolean mnemonics) {\n        if (mnemonics) Mnemonics.setLocalizedText(l, text);\n        else l.setText(text.replace(\"&\", \"\")); // NOI18N\n    }\n    \n//    private static void setText(AbstractButton b, String text, boolean mnemonics) {\n//        if (mnemonics) Mnemonics.setLocalizedText(b, text);\n//        else b.setText(text.replace(\"&\", \"\")); // NOI18N\n//    }\n    \n    \n    private static TextAreaComponent createTextArea(int rows) {\n        final JTextArea rootsArea = new JTextArea();\n        rootsArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, UIManager.getFont(\"Label.font\").getSize())); // NOI18N\n        TextAreaComponent rootsAreaScrollPane = new TextAreaComponent(rootsArea,\n                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                rootsArea.setEnabled(enabled);\n            }\n        };\n        rootsAreaScrollPane.setBorder(BorderFactory.createLineBorder(Color.GRAY));\n        JTextArea referenceArea = new JTextArea(\"X\"); // NOI18N\n        referenceArea.setFont(rootsArea.getFont());\n        referenceArea.setRows(rows);\n        Insets insets = rootsAreaScrollPane.getInsets();\n        rootsAreaScrollPane.setPreferredSize(new Dimension(1, referenceArea.getPreferredSize().height + \n                (insets != null ? insets.top + insets.bottom : 0)));\n        return rootsAreaScrollPane;\n    }\n    \n    \n    private static class TextAreaComponent extends JScrollPane {\n        TextAreaComponent(JTextArea textArea, int vPolicy, int hPolicy) { super(textArea, vPolicy, hPolicy); }\n        public JTextArea getTextArea() { return (JTextArea)getViewport().getView(); }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/ProfilerJDBCSettings.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport javax.swing.JPanel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ProfilerJDBCSettings extends JPanel {\n    \n    private ProfilerPreset preset;\n    private final ProfilerJDBCPanel panel;\n    \n    \n    ProfilerJDBCSettings() {\n        this.panel = new ProfilerJDBCPanel(true) {\n            public void settingsChanged() { panel.saveToPreset(preset); }\n        };\n        setLayout(new BorderLayout());\n        add(panel, BorderLayout.CENTER);\n    }\n\n    void setPreset(ProfilerPreset preset) {\n        this.preset = preset;\n        panel.loadFromPreset(preset);\n    }\n    \n    boolean valid() { return panel.settingsValid(); }\n\n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        for (Component c : getComponents())\n            c.setEnabled(enabled);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/ProfilerLocksPanel.java",
    "content": "/*\n * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.profiling.presets;\n\nimport java.awt.Component;\nimport java.awt.GridBagLayout;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic abstract class ProfilerLocksPanel extends JPanel {\n\n    private boolean internalChange;\n\n    public ProfilerLocksPanel() {\n        this(false);\n    }\n\n    ProfilerLocksPanel(boolean mnemonics) {\n        initComponents(mnemonics);\n    }\n\n    public ProfilingSettings getSettings() {\n        ProfilingSettings settings = ProfilerIDESettings.getInstance().createDefaultProfilingSettings();\n        settings.setProfilingType(ProfilingSettings.PROFILE_MONITOR);\n        settings.setLockContentionMonitoringEnabled(true);\n        return settings;\n    }\n\n    public boolean settingsValid() {\n        return true;\n    }\n\n    public void loadFromPreset(ProfilerPreset preset) {\n        if (preset == null) {\n            return;\n        }\n\n        internalChange = true;\n        internalChange = false;\n    }\n\n    public void saveToPreset(ProfilerPreset preset) {\n        if (preset == null) {\n            return;\n        }\n    }\n\n    public abstract void settingsChanged();\n\n    private void syncUI() {\n        if (internalChange) {\n            return;\n        }\n        settingsChanged();\n    }\n\n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        for (Component c : getComponents()) {\n            c.setEnabled(enabled);\n        }\n    }\n\n    private void initComponents(boolean mnemonics) {\n        setOpaque(false);\n        setLayout(new GridBagLayout());\n\n    }\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/ProfilerMemoryPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.uisupport.JExtendedSpinner;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport javax.swing.BorderFactory;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JRadioButton;\nimport javax.swing.JScrollPane;\nimport javax.swing.JSpinner;\nimport javax.swing.JTextArea;\nimport javax.swing.JTextField;\nimport javax.swing.SpinnerNumberModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.filters.JavaTypeFilter;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerMemoryPanel extends JPanel {\n    \n    private TextAreaComponent filtersArea;\n    private JCheckBox lifecycleCheckbox;\n    private JCheckBox outgoingCheckbox;\n    private JExtendedSpinner outgoingSpinner;\n    private JLabel unlimited;\n    private JLabel noAllocs;\n    \n    private final Runnable validator;\n    private boolean rootsValid = true;\n    private boolean internalChange;\n    \n    \n    public ProfilerMemoryPanel() {\n        this(null, false);\n    }\n    \n    ProfilerMemoryPanel(Runnable validator, boolean mnemonics) {\n        this.validator = validator;\n        initComponents(mnemonics);\n    }\n    \n    \n    public ProfilingSettings getSettings() {\n        ProfilingSettings settings = ProfilerIDESettings.getInstance().createDefaultProfilingSettings();\n        \n        settings.setProfilingType(lifecycleCheckbox.isSelected() ? ProfilingSettings.PROFILE_MEMORY_LIVENESS :\n                                                                ProfilingSettings.PROFILE_MEMORY_ALLOCATIONS);\n        \n        String filterValue = PresetsUtils.normalizeValue(getFilterValue());\n        settings.setInstrumentationFilter(new JavaTypeFilter(filterValue, JavaTypeFilter.TYPE_INCLUSIVE));\n        \n        boolean limitAlloc = outgoingCheckbox.isSelected();\n        int limit = (Integer)outgoingSpinner.getValue();\n        settings.setAllocStackTraceLimit(!limitAlloc ? -10 : limit);\n        \n        return settings;\n    }\n    \n    \n    public boolean settingsValid() { return rootsValid; }\n    \n    public void highlightInvalid() {\n        if (getFilterValue().isEmpty()) filtersArea.getTextArea().setText(ProfilerPresets.DEFINE_CLASSES);\n    }\n    \n    public void loadFromPreset(ProfilerPreset preset) {\n        if (preset == null) return;\n\n        internalChange = true;\n        filtersArea.getTextArea().setText(preset.getMemoryFilterP().trim());\n        lifecycleCheckbox.setSelected(preset.getMemoryModeP());\n        outgoingCheckbox.setSelected(preset.getStacksP());\n        outgoingSpinner.setValue(preset.getAllocP());\n        highlightInvalid();\n        internalChange = false;\n        \n        checkRootValidity();\n        \n        updateAllocControls();\n    }\n    \n    public void saveToPreset(ProfilerPreset preset) {\n        if (preset == null) return;\n        \n        preset.setMemoryFilterP(getFilterValue());\n        preset.setMemoryModeP(lifecycleCheckbox.isSelected());\n        preset.setStacksP(outgoingCheckbox.isSelected());\n        preset.setAllocP((Integer)outgoingSpinner.getValue());\n    }\n    \n    public abstract void settingsChanged();\n    \n    private void syncUI() {\n        if (internalChange) return;\n        settingsChanged();\n    }\n    \n    private void updateAllocControls() {\n        boolean selected = outgoingCheckbox.isSelected();\n        unlimited.setVisible(!selected);\n        outgoingSpinner.setVisible(selected);\n        noAllocs.setVisible(selected && (Integer)outgoingSpinner.getValue() == 0);\n    }\n    \n    \n    private void checkRootValidity() {\n        rootsValid = isRootValueValid();\n        filtersArea.getTextArea().setForeground(rootsValid ?\n            UIManager.getColor(\"TextArea.foreground\") : Color.RED); // NOI18N\n        if (validator != null) validator.run();\n    }\n    \n    public boolean isRootValueValid() {\n        String filterValue = PresetsUtils.normalizeValue(getFilterValue());\n        return PresetsUtils.isValidJavaValue(filterValue, false, true);\n    }\n    \n    private String getFilterValue() {\n        return filtersArea.getTextArea().getText().trim();\n    }\n    \n    \n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        for (Component c : getComponents()) c.setEnabled(enabled);\n    }\n    \n    private void initComponents(boolean mnemonics) {\n        setOpaque(false);\n        setLayout(new GridBagLayout());\n        \n        GridBagConstraints constraints;\n        \n        JLabel filtersLabel = new JLabel();\n        setText(filtersLabel, NbBundle.getMessage(ProfilerMemoryPanel.class, \"LBL_Root_Classes\"), mnemonics); // NOI18N\n        Dimension d = filtersLabel.getPreferredSize();\n        JRadioButton refRadion = new JRadioButton(NbBundle.getMessage(ProfilerMemoryPanel.class, \"LBL_Root_Classes\")); // NOI18N\n        refRadion.setBorder(filtersLabel.getBorder());\n        d.height = Math.max(d.height, refRadion.getPreferredSize().height);\n        filtersLabel.setPreferredSize(d);\n        filtersLabel.setToolTipText(NbBundle.getMessage(ProfilerMemoryPanel.class, \"TOOLTIP_Root_Classes\")); // NOI18N\n        filtersLabel.setOpaque(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(10, 10, 5, 10);\n        add(filtersLabel, constraints);\n        \n        filtersArea = createTextArea(2);\n        filtersLabel.setLabelFor(filtersArea.getTextArea());\n        filtersArea.getTextArea().setToolTipText(NbBundle.getMessage(ProfilerMemoryPanel.class, \"ProfilerMemoryPanel_TOOLTIP_Filter\")); // NOI18N\n        filtersArea.getTextArea().getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) { checkRootValidity(); syncUI(); }\n            public void removeUpdate(DocumentEvent e) { checkRootValidity(); syncUI(); }\n            public void changedUpdate(DocumentEvent e) { checkRootValidity(); syncUI(); }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 2;\n        constraints.weightx = 1;\n        constraints.weighty = 0.65;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.insets = new Insets(0, 10, 10, 10);\n        add(filtersArea, constraints);\n        \n        \n        lifecycleCheckbox = new JCheckBox(NbBundle.getMessage(ProfilerMemoryPanel.class, \"ProfilerMemoryPanel_BTN_Track_live\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                syncUI();\n            }\n        };\n        lifecycleCheckbox.setToolTipText(NbBundle.getMessage(ProfilerMemoryPanel.class, \"ProfilerMemoryPanel_TOOLTIP_Track_live\")); // NOI18N\n        lifecycleCheckbox.setOpaque(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 3;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 10, 0, 5);\n        add(lifecycleCheckbox, constraints);\n        \n        outgoingCheckbox = new JCheckBox(NbBundle.getMessage(ProfilerMemoryPanel.class, \"ProfilerMemoryPanel_BTN_Limit_alloc\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                updateAllocControls();\n                syncUI();\n            }\n        };\n        outgoingCheckbox.setToolTipText(NbBundle.getMessage(ProfilerMemoryPanel.class, \"ProfilerMemoryPanel_TOOLTIP_Limit_alloc\")); // NOI18N\n        outgoingCheckbox.setOpaque(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 4;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 10, 5, 5);\n        add(outgoingCheckbox, constraints);\n        \n        outgoingSpinner = new JExtendedSpinner(new SpinnerNumberModel(Math.abs(10), 0, 99, 1)) {\n            protected void fireStateChanged() { updateAllocControls(); syncUI(); super.fireStateChanged(); }\n        };\n        outgoingSpinner.setToolTipText(NbBundle.getMessage(ProfilerMemoryPanel.class, \"ProfilerMemoryPanel_TOOLTIP_Limit_alloc2\")); // NOI18N\n        JComponent editor = outgoingSpinner.getEditor();\n        JTextField field = editor instanceof JSpinner.DefaultEditor ?\n                ((JSpinner.DefaultEditor)editor).getTextField() : null;\n        if (field != null) field.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) { change(); }\n            public void removeUpdate(DocumentEvent e) { change(); }\n            public void changedUpdate(DocumentEvent e) { change(); }\n            private void change() {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        noAllocs.setVisible(outgoingSpinner.isVisible() &&\n                                            (Integer)outgoingSpinner.getValue() == 0);\n                    }\n                });\n                updateAllocControls();\n                syncUI();\n            }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 1;\n        constraints.gridy = 4;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 0, 5, 5);\n        add(outgoingSpinner, constraints);\n        \n        unlimited = new GrayLabel(NbBundle.getMessage(ProfilerMemoryPanel.class, \"ProfilerMemoryPanel_LBL_unlimited\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 2;\n        constraints.gridy = 4;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 0, 5, 5);\n        add(unlimited, constraints);\n        \n        noAllocs = new GrayLabel(NbBundle.getMessage(ProfilerMemoryPanel.class, \"ProfilerMemoryPanel_LBL_No_alloc\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 3;\n        constraints.gridy = 4;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 5, 5, 5);\n        add(noAllocs, constraints);\n        \n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 5;\n        constraints.weightx = 1;\n        constraints.weighty = 0.35;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.insets = new Insets(0, 0, 0, 0);\n        add(Spacer.create(), constraints);\n    }\n    \n    \n    private static void setText(JLabel l, String text, boolean mnemonics) {\n        if (mnemonics) Mnemonics.setLocalizedText(l, text);\n        else l.setText(text.replace(\"&\", \"\")); // NOI18N\n    }\n    \n//    private static void setText(AbstractButton b, String text, boolean mnemonics) {\n//        if (mnemonics) Mnemonics.setLocalizedText(b, text);\n//        else b.setText(text.replace(\"&\", \"\")); // NOI18N\n//    }\n    \n    private static TextAreaComponent createTextArea(int rows) {\n        final JTextArea rootsArea = new JTextArea();\n        rootsArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, UIManager.getFont(\"Label.font\").getSize())); // NOI18N\n        TextAreaComponent rootsAreaScrollPane = new TextAreaComponent(rootsArea,\n                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                rootsArea.setEnabled(enabled);\n            }\n        };\n        rootsAreaScrollPane.setBorder(BorderFactory.createLineBorder(Color.GRAY));\n        JTextArea referenceArea = new JTextArea(\"X\"); // NOI18N\n        referenceArea.setFont(rootsArea.getFont());\n        referenceArea.setRows(rows);\n        Insets insets = rootsAreaScrollPane.getInsets();\n        rootsAreaScrollPane.setPreferredSize(new Dimension(1, referenceArea.getPreferredSize().height + \n                (insets != null ? insets.top + insets.bottom : 0)));\n        return rootsAreaScrollPane;\n    }\n    \n    private static class TextAreaComponent extends JScrollPane {\n        TextAreaComponent(JTextArea textArea, int vPolicy, int hPolicy) { super(textArea, vPolicy, hPolicy); }\n        public JTextArea getTextArea() { return (JTextArea)getViewport().getView(); }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/ProfilerMemorySettings.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport javax.swing.JPanel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ProfilerMemorySettings extends JPanel {\n    \n    private ProfilerPreset preset;\n    private final ProfilerMemoryPanel panel;\n    \n    \n    ProfilerMemorySettings(Runnable validator) {\n        this.panel = new ProfilerMemoryPanel(validator, true) {\n            public void settingsChanged() { panel.saveToPreset(preset); }\n        };\n        setLayout(new BorderLayout());\n        add(panel, BorderLayout.CENTER);\n    }\n\n    void setPreset(ProfilerPreset preset) {\n        this.preset = preset;\n        panel.loadFromPreset(preset);\n    }\n    \n    boolean valid() { return panel.settingsValid(); }\n\n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        for (Component c : getComponents())\n            c.setEnabled(enabled);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/ProfilerPreset.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport java.util.prefs.Preferences;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ProfilerPreset {\n\n    private static final String PROP_NAME = \"prof_preset_name\"; // NOI18N\n    private static final String PROP_SELECTOR = \"prof_preset_selector\"; // NOI18N\n    private static final String PROP_FILTER_MODE_S = \"prof_preset_filterMode_s\"; // NOI18N\n    private static final String PROP_FILTER_S = \"prof_preset_filter_s\"; // NOI18N\n    private static final String PROP_SAMPLING_RATE_S = \"prof_preset_samplingRate_s\"; // NOI18N\n    private static final String PROP_REFRESH_RATE_S = \"prof_preset_refreshRate_s\"; // NOI18N\n    private static final String PROP_SAMPLING_REFRESH_RATE_S = \"prof_preset_samplingRefreshRate_s\"; // NOI18N\n    private static final String PROP_ROOTS_P = \"prof_preset_roots_p\"; // NOI18N\n    private static final String PROP_RUNNABLES_P = \"prof_preset_runnables_p\"; // NOI18N\n    private static final String PROP_FILTER_MODE_P = \"prof_preset_filterMode_p\"; // NOI18N\n    private static final String PROP_FILTER_P = \"prof_preset_filter_p\"; // NOI18N\n    private static final String PROP_MEMORY_MODE_P = \"prof_preset_memoryMode_p\"; // NOI18N\n    private static final String PROP_ALLOC_P = \"prof_preset_alloc_p\"; // NOI18N\n    private static final String PROP_STACKS_P = \"prof_preset_stacks_p\"; // NOI18N\n    private static final String PROP_MEMORY_FILTER_P = \"prof_memory_filter_p\"; // NOI18N\n    private static final String PROP_JDBC_FILTER_P = \"prof_jdbc_filter_p\"; // NOI18N\n    private static final String PROP_JDBC_QSIZE_P = \"prof_jdbc_qsize_p\"; // NOI18N\n\n    private boolean valid;\n    private String name;\n    private String selector;\n    private boolean filterModeS;\n    private String filterS;\n    private int samplingRateS;\n    private int refreshRateS;\n    private int samplingRefreshRateS;\n    private String rootsP;\n    private boolean runnablesP;\n    private boolean filterModeP;\n    private String filterP;\n    private boolean memoryModeP;\n    private int allocP;\n    private boolean stacksP;\n    private String memoryFilterP;\n    private String jdbcFilterP;\n    private int jdbcQSizeP;\n\n\n    public ProfilerPreset(String name, String selector) {\n        this.valid = true;\n        this.name = name;\n        this.selector = selector;\n        this.filterModeS = true;\n        this.filterS = \"\"; // NOI18N\n        this.samplingRateS = 100;\n        this.refreshRateS = 1000;\n        this.samplingRefreshRateS = 1000;\n        this.rootsP = \"\"; // NOI18N\n        this.runnablesP = true;\n        this.filterModeP = true;\n        this.filterP = \"\"; // NOI18N\n        this.memoryModeP = true;\n        this.allocP = 10;\n        this.stacksP = true;\n        this.memoryFilterP = \"\"; // NOI18N\n        this.jdbcFilterP = \"\"; // NOI18N\n        this.jdbcQSizeP = CommonConstants.MAX_STRING_LENGTH_DEFAULT;\n    }\n\n    public ProfilerPreset(ProfilerPreset preset) {\n        this.valid = preset.valid;\n        this.name = preset.name;\n        this.selector = preset.selector;\n        this.filterModeS = preset.filterModeS;\n        this.filterS = preset.filterS;\n        this.samplingRateS = preset.samplingRateS;\n        this.refreshRateS = preset.refreshRateS;\n        this.samplingRefreshRateS = preset.samplingRefreshRateS;\n        this.rootsP = preset.rootsP;\n        this.runnablesP = preset.runnablesP;\n        this.filterModeP = preset.filterModeP;\n        this.filterP = preset.filterP;\n        this.memoryModeP = preset.memoryModeP;\n        this.allocP = preset.allocP;\n        this.stacksP = preset.stacksP;\n        this.memoryFilterP = preset.memoryFilterP;\n        this.jdbcFilterP = preset.jdbcFilterP;\n        this.jdbcQSizeP = preset.jdbcQSizeP;\n    }\n\n    ProfilerPreset(Preferences prefs, String prefix) {\n        valid = true;\n        name = prefs.get(prefix + PROP_NAME, NbBundle.getMessage(ProfilerPreset.class, \"MSG_Preset\")); // NOI18N\n        selector = prefs.get(prefix + PROP_SELECTOR, \"\"); // NOI18N\n        filterModeS = prefs.getBoolean(prefix + PROP_FILTER_MODE_S, true);\n        filterS = prefs.get(prefix + PROP_FILTER_S, \"\"); // NOI18N\n        samplingRateS = prefs.getInt(prefix + PROP_SAMPLING_RATE_S, 100);\n        refreshRateS = prefs.getInt(prefix + PROP_REFRESH_RATE_S, 1000);\n        samplingRefreshRateS = prefs.getInt(prefix + PROP_SAMPLING_REFRESH_RATE_S, 1000);\n        rootsP = prefs.get(prefix + PROP_ROOTS_P, \"\"); // NOI18N\n        runnablesP = prefs.getBoolean(prefix + PROP_RUNNABLES_P, true);\n        filterModeP = prefs.getBoolean(prefix + PROP_FILTER_MODE_P, true);\n        filterP = prefs.get(prefix + PROP_FILTER_P, \"\"); // NOI18N\n        memoryModeP = prefs.getBoolean(prefix + PROP_MEMORY_MODE_P, true);\n        allocP = prefs.getInt(prefix + PROP_ALLOC_P, 10);\n        stacksP = prefs.getBoolean(prefix + PROP_STACKS_P, true);\n        memoryFilterP = prefs.get(prefix + PROP_MEMORY_FILTER_P, \"\"); // NOI18N\n        jdbcFilterP = prefs.get(prefix + PROP_JDBC_FILTER_P, \"\"); // NOI18N\n        jdbcQSizeP = prefs.getInt(prefix + PROP_JDBC_QSIZE_P, CommonConstants.MAX_STRING_LENGTH_DEFAULT);\n    }\n    \n\n    void toPreferences(Preferences prefs, String prefix) {\n        prefs.put(prefix + PROP_NAME, name);\n        prefs.put(prefix + PROP_SELECTOR, selector);\n        prefs.putBoolean(prefix + PROP_FILTER_MODE_S, filterModeS);\n        prefs.put(prefix + PROP_FILTER_S, filterS);\n        prefs.putInt(prefix + PROP_SAMPLING_RATE_S, samplingRateS);\n        prefs.putInt(prefix + PROP_REFRESH_RATE_S, refreshRateS);\n        prefs.putInt(prefix + PROP_SAMPLING_REFRESH_RATE_S, samplingRefreshRateS);\n        prefs.put(prefix + PROP_ROOTS_P, rootsP);\n        prefs.putBoolean(prefix + PROP_RUNNABLES_P, runnablesP);\n        prefs.putBoolean(prefix + PROP_FILTER_MODE_P, filterModeP);\n        prefs.put(prefix + PROP_FILTER_P, filterP);\n        prefs.putBoolean(prefix + PROP_MEMORY_MODE_P, memoryModeP);\n        prefs.putInt(prefix + PROP_ALLOC_P, allocP);\n        prefs.putBoolean(prefix + PROP_STACKS_P, stacksP);\n        prefs.put(prefix + PROP_MEMORY_FILTER_P, memoryFilterP);\n        prefs.put(prefix + PROP_JDBC_FILTER_P, jdbcFilterP);\n        prefs.putInt(prefix + PROP_JDBC_QSIZE_P, jdbcQSizeP);\n    }\n\n\n    void setValid(boolean valid) {\n        this.valid = valid;\n    }\n    \n    boolean isValid() {\n        return valid;\n    }\n    \n\n    public void setName(String name) {\n        if (name != null && !name.isEmpty()) this.name = name;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setSelector(String selector) {\n        this.selector = selector;\n    }\n\n    public String getSelector() {\n        return selector;\n    }\n\n    public void setFilterModeS(boolean filterMode) {\n        this.filterModeS = filterMode;\n    }\n\n    public boolean getFilterModeS() {\n        return filterModeS;\n    }\n\n    public void setFilterS(String filter) {\n        this.filterS = filter;\n    }\n\n    public String getFilterS() {\n        return filterS;\n    }\n\n    public void setSamplingRateS(int samplingRate) {\n        this.samplingRateS = samplingRate;\n    }\n\n    public int getSamplingRateS() {\n        return samplingRateS;\n    }\n\n    public void setRefreshRateS(int refreshRate) {\n        this.refreshRateS = refreshRate;\n    }\n\n    public int getRefreshRateS() {\n        return refreshRateS;\n    }\n\n    public void setSamplingRefreshRateS(int samplingRefreshRateS) {\n        this.samplingRefreshRateS = samplingRefreshRateS;\n    }\n\n    public int getSamplingRefreshRateS() {\n        return samplingRefreshRateS;\n    }\n\n    public void setRootsP(String roots) {\n        this.rootsP = roots;\n    }\n\n    public String getRootsP() {\n        return rootsP;\n    }\n\n    public void setRunnablesP(boolean runnables) {\n        this.runnablesP = runnables;\n    }\n\n    public boolean getRunnablesP() {\n        return runnablesP;\n    }\n\n    public void setFilterModeP(boolean filterMode) {\n        this.filterModeP = filterMode;\n    }\n\n    public boolean getFilterModeP() {\n        return filterModeP;\n    }\n\n    public void setFilterP(String filter) {\n        this.filterP = filter;\n    }\n\n    public String getFilterP() {\n        return filterP;\n    }\n\n    public void setMemoryModeP(boolean memoryMode) {\n        this.memoryModeP = memoryMode;\n    }\n\n    public boolean getMemoryModeP() {\n        return memoryModeP;\n    }\n\n    public void setAllocP(int alloc) {\n        this.allocP = alloc;\n    }\n\n    public int getAllocP() {\n        return allocP;\n    }\n\n    public void setStacksP(boolean stacks) {\n        this.stacksP = stacks;\n    }\n\n    public boolean getStacksP() {\n        return stacksP;\n    }\n    \n    public void setMemoryFilterP(String filter) {\n        this.memoryFilterP = filter;\n    }\n\n    public String getMemoryFilterP() {\n        return memoryFilterP;\n    }\n    \n    public void setJDBCFilterP(String filter) {\n        this.jdbcFilterP = filter;\n    }\n\n    public String getJDBCFilterP() {\n        return jdbcFilterP;\n    }\n\n    public void setJDBCQSizerP(int qsize) {\n        this.jdbcQSizeP = qsize;\n    }\n\n    public int getJDBCFQSizeP() {\n        return jdbcQSizeP;\n    }\n\n    public String toString() {\n        return getName();\n    }\n    \n    public boolean equals(Object o) {\n        return o instanceof ProfilerPreset && getName().equals(((ProfilerPreset) o).getName());\n    }\n    \n    public int hashCode() {\n        return getName().hashCode();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/ProfilerPresets.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.ref.WeakReference;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.Set;\nimport java.util.jar.Attributes;\nimport java.util.jar.JarFile;\nimport java.util.prefs.Preferences;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.DefaultListModel;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.netbeans.api.options.OptionsDisplayer;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ProfilerPresets {\n\n    private static final String JAR_SUFFIX = \".jar\";  // NOI18N    \n    private static final String PROP_PRESET_HEADER = \"prof_preset_header\"; // NOI18N\n\n    private static ProfilerPresets INSTANCE;\n    \n    private Preferences prefs;\n\n    private List<ProfilerPreset> presets;\n    private ProfilerPreset presetToSelect;\n    private ProfilerPreset presetToCreate;\n\n    private final Set<WeakReference<PresetSelector>> selectors;\n    \n    static final String DEFINE_CLASSES = NbBundle.getMessage(ProfilerPresets.class, \"HINT_Define_roots\"); // NOI18N\n\n    private static final String INTERNAL_JAVA_FILTER = \"com.sun.**, sun.**, sunw.**,\\napple.laf.**, apple.awt.**, com.apple.**,\\norg.omg.CORBA.**, org.omg.CosNaming.**, COM.rsa.**\"; // NOI18N\n    private static final String CORE_JAVA_FILTER = \"java.**, javax.**, jdk.**,\\n\"+INTERNAL_JAVA_FILTER; // NOI18N\n\n    public static synchronized ProfilerPresets getInstance() {\n        if (INSTANCE == null) INSTANCE = new ProfilerPresets();\n        return INSTANCE;\n    }\n\n\n    public void editPresets(ProfilerPreset preset) {\n        presetToSelect = preset;\n        OptionsDisplayer.getDefault().open(ProfilingOptionsPanelController.OPTIONS_HANDLE);\n    }\n\n    ProfilerPreset presetToSelect() {\n        ProfilerPreset toSelect = presetToSelect;\n        presetToSelect = null;\n        return toSelect;\n    }\n\n    public void savePreset(ProfilerPreset preset) {\n        presetToCreate = preset;\n        OptionsDisplayer.getDefault().open(ProfilingOptionsPanelController.OPTIONS_HANDLE);\n    }\n\n    ProfilerPreset presetToCreate() {\n        ProfilerPreset toCreate = presetToCreate;\n        presetToCreate = null;\n        return toCreate;\n    }\n\n    void optionsSubmitted(final ProfilerPreset selected) {\n        Map<DefaultComboBoxModel<ProfilerPreset>, Boolean> models = new HashMap<>();\n        Iterator<WeakReference<PresetSelector>> selectorsI =\n                selectors.iterator();\n\n        while (selectorsI.hasNext()) {\n            WeakReference<PresetSelector> selectorR = selectorsI.next();\n            PresetSelector selector = selectorR.get();\n            if (selector == null) {\n                selectorsI.remove();\n            } else if (SwingUtilities.getRoot(selector) == null) {\n                selectorsI.remove();\n            } else {\n                DefaultComboBoxModel<ProfilerPreset> model = selector.getModel();\n                boolean savingCustom = selector.checkSavingCustom();\n                if (!Boolean.TRUE.equals(models.get(model)))\n                    models.put(model, savingCustom);\n            }\n        }\n\n        for (DefaultComboBoxModel<ProfilerPreset> model : models.keySet()) {\n            ProfilerPreset selectedPreset = (ProfilerPreset)model.getSelectedItem();\n            ProfilerPreset defaultPreset = model.getElementAt(0);\n            ProfilerPreset customPreset = model.getSize() < 2 ? null : model.getElementAt(1);\n            if (customPreset != null && !PresetSelector.isCustomPreset(customPreset))\n                customPreset = null;\n\n            boolean savingCustom = models.get(model);\n\n//                    internalChange = true;\n\n            model.removeAllElements();\n            model.addElement(defaultPreset);\n            if (!savingCustom && customPreset != null) model.addElement(customPreset);\n            for (ProfilerPreset preset : presets) model.addElement(preset);\n\n            ProfilerPreset toSelect = savingCustom && selected != null ? selected :\n                                      selectedPreset;\n            if (model.getIndexOf(toSelect) >= 0) model.setSelectedItem(toSelect);\n            else model.setSelectedItem(model.getElementAt(0));\n\n//                    internalChange = false;\n        }\n    }\n    \n    public PresetSelector createSelector(DefaultComboBoxModel<ProfilerPreset> selectorsModel,\n                                         List<PresetSelector> allSelectors,\n                                         Runnable presetSync) {\n        return createSelector(null, selectorsModel, allSelectors, presetSync);\n    }\n    \n    public PresetSelector createSelector(Application application,\n                                         DefaultComboBoxModel<ProfilerPreset> selectorsModel,\n                                         List<PresetSelector> allSelectors,\n                                         Runnable presetSync) {\n        \n        \n        \n        if (selectorsModel.getSize() == 0) {\n            for (ProfilerPreset preset : getPresets(application))\n                selectorsModel.addElement(preset);\n            \n            String mainClass = null;\n        \n            if (application != null) {\n                mainClass = getMainClass(application);\n                if (mainClass == null || mainClass.isEmpty()) mainClass =\n                        ApplicationTypeFactory.getApplicationTypeFor(application).getName();\n                if (mainClass == null || mainClass.isEmpty()) mainClass =\n                        DataSourceDescriptorFactory.getDescriptor(application).getName();\n            }\n            \n            ProfilerPreset defaultPreset = selectorsModel.getElementAt(0);\n            defaultPreset.setSelector(mainClass);\n\n            ProfilerPreset toSelect = defaultPreset;\n            if (mainClass != null && !mainClass.isEmpty()) {\n                String mainClassL = mainClass.toLowerCase();\n                for (ProfilerPreset preset : presets) {\n                    String selector = preset.getSelector();\n                    if (selector != null && !selector.isEmpty()) {\n                        if (mainClass.equals(selector) || mainClassL.contains(selector.toLowerCase())) {\n                            toSelect = preset;\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            selectorsModel.setSelectedItem(toSelect);\n        }\n        \n        PresetSelector selector = new PresetSelector(selectorsModel, allSelectors,\n                                                     presetSync);\n        selectors.add(new WeakReference<>(selector));\n        return selector;\n    }\n\n    public ProfilerPreset[] getPresets(Application application) {\n        ProfilerPreset[] presetsArr = new ProfilerPreset[presets.size() + 1];\n        int index = 0;\n        presetsArr[index++] = createDefaultPreset(application);\n        for (ProfilerPreset preset : presets) presetsArr[index++] = preset;\n        return presetsArr;\n    }\n\n    private void loadPresets() {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                final List<ProfilerPreset> loadedPresets = doLoadPresets();\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        presets.clear();\n                        presets.addAll(loadedPresets);\n                    }\n                });\n            }\n        });\n    }\n\n    void savePresets(final PresetsModel toSave) {\n        presets.clear();\n        Enumeration<ProfilerPreset> en = toSave.elements();\n        while (en.hasMoreElements())\n            presets.add(en.nextElement());\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() { doSavePresets(toSave); }\n        });\n    }\n\n    PresetsModel getPresets() {\n        PresetsModel model = new PresetsModel();\n        for (ProfilerPreset preset : presets) model.addElement(preset);\n        return model;\n    }\n    \n\n    private static ProfilerPreset createDefaultPreset(Application application) {\n        ProfilerPreset defaultPreset = new ProfilerPreset(NbBundle.getMessage(\n                ProfilerPresets.class, \"MSG_Default\"), \"\"); // NOI18N\n        defaultPreset.setFilterS(getDefaultFiltersS());\n        defaultPreset.setRootsP(getDefaultRootsP(application));\n        defaultPreset.setFilterP(getDefaultFiltersP(defaultPreset.getRootsP()));\n        defaultPreset.setMemoryFilterP(getDefaultMemoryFilterP(application));\n        return defaultPreset;\n    }\n\n    private static String getMainClass(Application application) {\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        String mainClass = jvm.getMainClass();\n        if (mainClass == null || mainClass.trim().isEmpty()) {\n            mainClass = \"\"; // NOI18N\n        } else if (mainClass.endsWith(JAR_SUFFIX)) {\n            // application is launched with -jar and uses relative path,\n            // if we are on localhost try to read main class from jar file\n            mainClass = \"\"; // NOI18N\n            if (application.isLocalApplication() && jvm.isGetSystemPropertiesSupported()) {\n                Properties sysProp = jvm.getSystemProperties();\n                if (sysProp != null) {\n                    String userdir = sysProp.getProperty(\"user.dir\");     // NOI18N\n                    if (userdir != null) {\n                        String args = jvm.getCommandLine();\n                        int index = args.indexOf(JAR_SUFFIX);\n                        if (index != -1) {\n                            File jarFile = new File(userdir,args.substring(0,index+JAR_SUFFIX.length()));\n                            if (jarFile.exists()) {\n                                try (JarFile jf = new JarFile(jarFile)) {\n                                    String mainClassName = jf.getManifest().getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);\n                                    assert mainClassName!=null;\n                                    mainClass = mainClassName.replace('\\\\', '/').replace('/', '.'); // NOI18N\n                                } catch (IOException ex) {\n    //                                LOGGER.log(Level.INFO, \"getMainClass\", ex);   // NOI18N\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        return mainClass;\n    }\n    \n    private static String getDefaultFiltersS() {\n        return CORE_JAVA_FILTER;\n    }\n\n    private static String getDefaultRootsP(Application application) {\n        if (application == null) return DEFINE_CLASSES;\n        String mainClass = getMainClass(application);\n        if (\"\".equals(mainClass)) return DEFINE_CLASSES; // unknown main class\n        int dotIndex = mainClass.lastIndexOf('.'); // NOI18N\n        if (dotIndex == -1) return mainClass;  // default package\n        else return mainClass.substring(0, dotIndex + 1) + \"**\"; // NOI18N\n    }\n\n    private static String getDefaultFiltersP(String defaultRoots) {\n        return defaultRoots.isEmpty() ? INTERNAL_JAVA_FILTER : CORE_JAVA_FILTER;\n    }\n    \n    private static String getDefaultMemoryFilterP(Application application) {\n        return DEFINE_CLASSES; // NOI18N\n    }\n\n\n    private List<ProfilerPreset> doLoadPresets() {\n        Preferences p = prefs();\n        List<ProfilerPreset> loadedPresets = new ArrayList<>();\n        \n        int i = 0;\n        String prefix = i + \"_\"; // NOI18N\n        while (p.get(prefix + PROP_PRESET_HEADER, null) != null) {\n            loadedPresets.add(new ProfilerPreset(p, prefix));\n            prefix = ++i + \"_\"; // NOI18N\n        }\n        \n        return loadedPresets;\n    }\n\n    private void doSavePresets(PresetsModel toSave) {\n        Preferences p = prefs();\n        try { p.clear(); } catch (Exception e) {}\n        int count = toSave.size();\n        for (int i = 0; i < count; i++) {\n            String prefix = i + \"_\"; // NOI18N\n            p.put(prefix + PROP_PRESET_HEADER, \"\"); // NOI18N\n            ProfilerPreset preset = toSave.get(i);\n            preset.toPreferences(p, prefix); // NOI18N\n        }\n    }\n    \n    private synchronized Preferences prefs() {\n        if (prefs == null) prefs = NbPreferences.forModule(ProfilerPresets.class);\n        return prefs;\n    }\n\n\n    private ProfilerPresets() {\n        presets = new ArrayList<>();\n        selectors = new HashSet<>();\n        \n        loadPresets();\n    }\n\n\n    static class PresetsModel extends DefaultListModel<ProfilerPreset> {\n\n        void addPreset(ProfilerPreset preset) {\n            addElement(preset);\n        }\n\n        void removePreset(int preset) {\n            removeElementAt(preset);\n        }\n\n        void movePresetUp(int preset) {\n            ProfilerPreset o = elementAt(preset);\n            remove(preset);\n            add(preset - 1, o);\n        }\n\n        void movePresetDown(int preset) {\n            ProfilerPreset o = elementAt(preset);\n            remove(preset);\n            add(preset + 1, o);\n        }\n\n        public void fireItemChanged(int itemIndex) {\n            fireContentsChanged(this, itemIndex, itemIndex);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/ProfilingOptionsPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.core.options.UISupport;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPresets.PresetsModel;\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.GridLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.FocusEvent;\nimport java.util.Collection;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultListModel;\nimport javax.swing.DefaultListSelectionModel;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTabbedPane;\nimport javax.swing.JTextField;\nimport javax.swing.ListSelectionModel;\nimport javax.swing.SwingUtilities;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport javax.swing.event.ListDataEvent;\nimport javax.swing.event.ListDataListener;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ProfilingOptionsPanel extends JPanel {\n\n//    final private static Logger LOGGER =\n//            Logger.getLogger(\"org.graalvm.visualvm.profiling.options\"); // NOI18N\n    private final ProfilingOptionsPanelController controller;\n\n    private final SamplerCPUSettings samplerCpuSettings;\n    private final SamplerMemorySettings samplerMemorySettings;\n    private final ProfilerCPUSettings profilerCpuSettings;\n    private final ProfilerMemorySettings profilerMemorySettings;\n    private final ProfilerJDBCSettings profilerJdbcSettings;\n\n    private PresetsModel listModel;\n    private final ListDataListener listModelListener;\n    \n    private final Collection<? extends ProfilingOptionsSectionProvider> sectionProviders =\n            Lookup.getDefault().lookupAll(ProfilingOptionsSectionProvider.class);\n\n    private boolean internalChange;\n\n    private boolean nameValid = true;\n\n\n    ProfilingOptionsPanel(ProfilingOptionsPanelController controller) {\n        this.controller = controller;\n        \n        for (ProfilingOptionsSectionProvider provider : sectionProviders) {\n            provider.setController(controller);\n        }\n\n        Runnable validator = new Runnable() {\n            public void run() {\n                ProfilerPreset preset = list.getSelectedValue();\n                if (preset == null) return;\n                preset.setValid(samplerCpuSettings.valid() &&\n                                profilerCpuSettings.valid() &&\n                                samplerMemorySettings.valid() &&\n                                profilerMemorySettings.valid() &&\n                                profilerJdbcSettings.valid());\n                ProfilingOptionsPanel.this.controller.changed();\n            }\n        };\n\n        samplerCpuSettings = new SamplerCPUSettings(validator);\n        samplerMemorySettings = new SamplerMemorySettings();\n        profilerCpuSettings = new ProfilerCPUSettings(validator);\n        profilerMemorySettings = new ProfilerMemorySettings(validator);\n        profilerJdbcSettings = new ProfilerJDBCSettings();\n\n        listModelListener = new ListDataListener() {\n            public void intervalAdded(ListDataEvent e) {\n                updateComponents();\n            }\n            public void intervalRemoved(ListDataEvent e) {\n                updateComponents();\n            }\n            public void contentsChanged(ListDataEvent e) {}\n        };\n\n        initComponents();\n    }\n\n\n    private void updateComponents() {\n        int selectedIndex = listModel.isEmpty() ? -1 : list.getSelectedIndex();\n        if (selectedIndex == listModel.getSize()) return; // isAdjusting\n        \n        removeButton.setEnabled(selectedIndex != -1);\n        upButton.setEnabled(selectedIndex > 0);\n        downButton.setEnabled(selectedIndex < listModel.getSize() - 1);\n\n        refreshPreset(selectedIndex);\n    }\n\n    private String createPresetName() {\n        Set<String> names = new HashSet<>();\n        Enumeration<ProfilerPreset> presetsE = listModel.elements();\n        while (presetsE.hasMoreElements())\n            names.add(presetsE.nextElement().toString());\n\n        int presetIndex = 1;\n        String name = NbBundle.getMessage(ProfilingOptionsPanel.class, \"MSG_Preset\") + \" \"; // NOI18N\n\n        while (names.contains(name + presetIndex)) presetIndex++;\n\n        return name + presetIndex;\n    }\n\n    private void createPreset() {\n        ProfilerPreset preset = new ProfilerPreset(createPresetName(), \"\"); // NOI18N\n        listModel.addPreset(preset);\n        list.setSelectedIndex(listModel.getSize() - 1);\n        preselectNameField();\n    }\n\n    private void preselectNameField() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                nameField.requestFocusInWindow();\n                nameField.selectAll();\n            }\n        });\n    }\n\n    private void deletePreset() {\n        int selectedIndex = list.getSelectedIndex();\n        listModel.removePreset(selectedIndex);\n        if (listModel.getSize() > 0)\n            list.setSelectedIndex(selectedIndex == listModel.getSize() ?\n                                  selectedIndex - 1 : selectedIndex);\n    }\n\n    private void movePresetUp() {\n        int selectedIndex = list.getSelectedIndex();\n        listModel.movePresetUp(selectedIndex);\n        list.setSelectedIndex(selectedIndex - 1);\n    }\n\n    private void movePresetDown() {\n        int selectedIndex = list.getSelectedIndex();\n        listModel.movePresetDown(selectedIndex);\n        list.setSelectedIndex(selectedIndex + 1);\n    }\n\n    private void refreshPreset(int presetIndex) {\n        ProfilerPreset preset = presetIndex == -1 ? new ProfilerPreset(\"\", \"\") : // NOI18N\n                                listModel.get(presetIndex);\n\n        internalChange = true;\n        nameField.setText(preset.getName());\n        targetField.setText(preset.getSelector());\n        internalChange = false;\n\n        samplerCpuSettings.setPreset(preset);\n        samplerMemorySettings.setPreset(preset);\n        profilerCpuSettings.setPreset(preset);\n        profilerMemorySettings.setPreset(preset);\n        profilerJdbcSettings.setPreset(preset);\n\n        presetsPanel.setEnabled(presetIndex != -1);\n    }\n\n    private void updatePreset() {\n        if (internalChange) return;\n        ProfilerPreset preset = listModel.get(list.getSelectedIndex());\n\n        preset.setName(nameField.getText());\n        preset.setSelector(targetField.getText());\n\n        nameValid = !nameField.getText().isEmpty();\n\n        controller.changed();\n    }\n    \n    private void initComponents() {\n        final boolean nimbusLaF =\n                org.graalvm.visualvm.uisupport.UISupport.isNimbusLookAndFeel();\n\n        GridBagConstraints c;\n\n        setLayout(new GridBagLayout());\n\n        // --- Presets ---------------------------------------------------------\n        SectionSeparator presetsSection = UISupport.createSectionSeparator(\n                NbBundle.getMessage(ProfilingOptionsPanel.class, \"CAPTION_Presets\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridy = 0;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(0, 0, 5, 0);\n        add(presetsSection, c);\n\n        JPanel listPanel = new JPanel(new BorderLayout());\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 1;\n        c.gridwidth = 1;\n        c.weighty = 0.5;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(3, 15, 3, 0);\n        add(listPanel, c);\n\n        list = new JList<>();\n        list.setSelectionModel(new DefaultListSelectionModel() {\n            public void setSelectionInterval(int index0, int index1) {\n                super.setSelectionInterval(index0, index1);\n                updateComponents();\n            }\n            public void removeSelectionInterval(int i1, int i2) {}\n        });\n        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\n        final Dimension oneDim = new Dimension(1, 1);\n        final JLabel noPresetsLabel = new JLabel(NbBundle.getMessage(\n                ProfilingOptionsPanel.class, \"MSG_No_presets\"), JLabel.CENTER); // NOI18N\n        noPresetsLabel.setEnabled(false);\n        noPresetsLabel.setSize(noPresetsLabel.getPreferredSize());\n        final JScrollPane listScroll = new JScrollPane(list) {\n            public Dimension getPreferredSize() {\n                return oneDim;\n            }\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            protected void paintChildren(Graphics g) {\n                super.paintChildren(g);\n                if (listModel == null || listModel.getSize() == 0) {\n                    int x = (getWidth() - noPresetsLabel.getWidth()) / 2;\n                    int y = (getHeight() - noPresetsLabel.getHeight()) / 2;\n                    g.translate(x, y);\n                    noPresetsLabel.paint(g);\n                    g.translate(-x, -y);\n                }\n            }\n        };\n        listPanel.add(listScroll, BorderLayout.CENTER);\n        \n        addButton = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                createPreset();\n            }\n        };\n        addButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/profiler/resources/add.png\", true)));   // NOI18N\n        addButton.setToolTipText(NbBundle.getMessage(ProfilingOptionsPanel.class,\n                \"TOOLTIP_Create_preset\")); // NOI18N\n        Insets margin = addButton.getMargin();\n        int mar = nimbusLaF ? 0 : 8;\n        margin.left = mar;\n        margin.right = mar;\n        addButton.setMargin(margin);\n        removeButton = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                deletePreset();\n                listScroll.repaint();\n            }\n        };\n        removeButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/profiler/resources/remove.png\", true)));   // NOI18N\n        removeButton.setToolTipText(NbBundle.getMessage(ProfilingOptionsPanel.class,\n                \"TOOLTIP_Delete_preset\")); // NOI18N\n        removeButton.setMargin(margin);\n        upButton = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                movePresetUp();\n            }\n        };\n        upButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/profiler/resources/up.png\", true)));   // NOI18N\n        upButton.setToolTipText(NbBundle.getMessage(ProfilingOptionsPanel.class,\n                \"TOOLTIP_preset_up\")); // NOI18N\n        upButton.setMargin(margin);\n        downButton = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                movePresetDown();\n            }\n        };\n        downButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\n                \"org/graalvm/visualvm/profiler/resources/down.png\", true)));   // NOI18N\n        downButton.setToolTipText(NbBundle.getMessage(ProfilingOptionsPanel.class,\n                \"TOOLTIP_preset_down\")); // NOI18N\n        downButton.setMargin(margin);\n\n        JPanel controlsPanel = new JPanel(new GridLayout(1, 4, 5, 0)) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents())\n                    c.setEnabled(enabled);\n            }\n        };\n        controlsPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));\n        controlsPanel.add(addButton);\n        controlsPanel.add(removeButton);\n        controlsPanel.add(upButton);\n        controlsPanel.add(downButton);\n        listPanel.add(controlsPanel, BorderLayout.SOUTH);\n\n        JPanel headerPanel = new JPanel(new GridBagLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents())\n                    c.setEnabled(enabled);\n            }\n        };\n\n        JLabel nameLabel = new JLabel();\n        Mnemonics.setLocalizedText(nameLabel, NbBundle.getMessage(\n                ProfilingOptionsPanel.class, \"LBL_Preset_name\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 3, 3, 0);\n        headerPanel.add(nameLabel, c);\n\n        nameField = new JTextField();\n        nameLabel.setLabelFor(nameField);\n        nameField.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) { updatePreset(); listModel.fireItemChanged(list.getSelectedIndex()); }\n            public void removeUpdate(DocumentEvent e) { updatePreset(); listModel.fireItemChanged(list.getSelectedIndex()); }\n            public void changedUpdate(DocumentEvent e) { updatePreset(); listModel.fireItemChanged(list.getSelectedIndex()); }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 0;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 5, 3, 0);\n        headerPanel.add(nameField, c);\n\n        JLabel targetLabel = new JLabel();\n        Mnemonics.setLocalizedText(targetLabel, NbBundle.getMessage(\n                ProfilingOptionsPanel.class, \"LBL_Preselect_for\")); // NOI18N\n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 1;\n        c.gridwidth = 1;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.insets = new Insets(3, 3, 13, 0);\n        headerPanel.add(targetLabel, c);\n\n        final JLabel noTargetLabel = new JLabel(NbBundle.getMessage(\n                ProfilingOptionsPanel.class, \"LBL_Optional_class\"), JLabel.CENTER); // NOI18N\n        noTargetLabel.setEnabled(false);\n        noTargetLabel.setSize(noTargetLabel.getPreferredSize());\n        targetField = new JTextField() {\n            protected void paintChildren(Graphics g) {\n                super.paintChildren(g);\n                String text = getText();\n                if (!isFocusOwner() && (text == null || text.isEmpty())) {\n                    int x = nimbusLaF ? 6 : 2;\n                    int y = (getHeight() - noTargetLabel.getHeight()) / 2;\n                    g.translate(x, y);\n                    noTargetLabel.paint(g);\n                    g.translate(-x, -y);\n                }\n            }\n            protected void processFocusEvent(FocusEvent e) {\n                super.processFocusEvent(e);\n                repaint();\n            }\n        };\n        targetLabel.setLabelFor(targetField);\n        targetField.getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) { updatePreset(); }\n            public void removeUpdate(DocumentEvent e) { updatePreset(); }\n            public void changedUpdate(DocumentEvent e) { updatePreset(); }\n        });\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.insets = new Insets(3, 5, 13, 0);\n        headerPanel.add(targetField, c);\n\n        JTabbedPane settingsPanel = new JTabbedPane() {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents())\n                    c.setEnabled(enabled);\n            }\n        };\n        settingsPanel.addTab(NbBundle.getMessage(ProfilingOptionsPanel.class,\n                \"LBL_Sampler_cpu\"), new ImageIcon(ImageUtilities.loadImage( // NOI18N\n                \"org/graalvm/visualvm/profiling/resources/sampler.png\", true)), // NOI18N\n                samplerCpuSettings);\n        settingsPanel.addTab(NbBundle.getMessage(ProfilingOptionsPanel.class,\n                \"LBL_Sampler_memory\"), new ImageIcon(ImageUtilities.loadImage( // NOI18N\n                \"org/graalvm/visualvm/profiling/resources/sampler.png\", true)), // NOI18N\n                samplerMemorySettings);\n        settingsPanel.addTab(NbBundle.getMessage(ProfilingOptionsPanel.class,\n                \"LBL_Profiler_cpu\"), new ImageIcon(ImageUtilities.loadImage( // NOI18N\n                \"org/graalvm/visualvm/profiling/resources/profiler.png\", true)), // NOI18N\n                profilerCpuSettings);\n        settingsPanel.addTab(NbBundle.getMessage(ProfilingOptionsPanel.class,\n                \"LBL_Profiler_memory\"), new ImageIcon(ImageUtilities.loadImage( // NOI18N\n                \"org/graalvm/visualvm/profiling/resources/profiler.png\", true)), // NOI18N\n                profilerMemorySettings);\n        settingsPanel.addTab(NbBundle.getMessage(ProfilingOptionsPanel.class,\n                \"LBL_Profiler_jdbc\"), new ImageIcon(ImageUtilities.loadImage( // NOI18N\n                \"org/graalvm/visualvm/profiling/resources/profiler.png\", true)), // NOI18N\n                profilerJdbcSettings);\n\n        presetsPanel = new JPanel(new BorderLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents())\n                    c.setEnabled(enabled);\n            }\n        };\n        presetsPanel.add(headerPanel, BorderLayout.NORTH);\n        presetsPanel.add(settingsPanel, BorderLayout.CENTER);\n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 1;\n        c.weightx = 1;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.insets = new Insets(3, 8, 3, 0);\n        add(presetsPanel, c);\n\n\n        // --- Miscellaneous ----------------------------------------------------\n        int gridy = 50;\n        for (ProfilingOptionsSectionProvider provider : sectionProviders) {\n            SectionSeparator section = UISupport.createSectionSeparator(provider.getSectionName());\n            c = new GridBagConstraints();\n            c.gridy = gridy++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.NORTHWEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(15, 0, 5, 0);\n            add(section, c);\n            \n            c = new GridBagConstraints();\n            c.gridy = gridy++;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.HORIZONTAL;\n            c.insets = new Insets(2, 15, 3, 0);\n            add(provider.getSection(), c);\n        }\n    }\n\n    void load() {\n        listModel = ProfilerPresets.getInstance().getPresets();\n        listModel.addListDataListener(listModelListener);\n        list.setModel(listModel);\n        int items = listModel.getSize();\n\n        ProfilerPreset toCreate = ProfilerPresets.getInstance().presetToCreate();\n        if (toCreate != null) {\n            toCreate.setName(createPresetName());\n            listModel.addElement(toCreate);\n            list.setSelectedIndex(items);\n        } else if (!listModel.isEmpty()) {\n            ProfilerPreset select = ProfilerPresets.getInstance().presetToSelect();\n            String toSelect = select == null ? null : select.getName();\n            int indexToSelect = 0;\n            if (toSelect != null) {\n                for (int i = 0; i < items; i++) {\n                    ProfilerPreset preset = listModel.get(i);\n                    if (preset.getName().equals(toSelect)) {\n                        indexToSelect = i;\n                        break;\n                    }\n                }\n            }  \n            list.setSelectedIndex(indexToSelect);\n        }\n\n        updateComponents();\n\n        if (toCreate != null) preselectNameField();\n        \n        for (ProfilingOptionsSectionProvider provider : sectionProviders) {\n            provider.load();\n        }\n        \n        repaint();\n    }\n\n    void store() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                normalizeNames(listModel); // prevents duplicate preset names\n\n                ProfilerPresets.getInstance().savePresets(listModel);\n                ProfilerPreset selected = list.getSelectedValue();\n                ProfilerPresets.getInstance().optionsSubmitted(selected);\n                \n                for (ProfilingOptionsSectionProvider provider : sectionProviders) {\n                    provider.store();\n                }\n            }\n        });\n    }\n\n    void closed() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (listModel != null) listModel.removeListDataListener(listModelListener);\n                list.setModel(new DefaultListModel<>());\n                \n                for (ProfilingOptionsSectionProvider provider : sectionProviders) {\n                    provider.closed();\n                }\n            }\n        });\n    }\n\n    boolean valid() {\n        if (!nameValid) return false;\n        \n        for (ProfilingOptionsSectionProvider provider : sectionProviders) {\n            if (!provider.valid()) return false;\n        }\n        \n        return true;\n        \n//        return nameValid /*&& presetsValid()*/;\n    }\n    \n//    private boolean presetsValid() {\n//        Enumeration presets = listModel.elements();\n//        while (presets.hasMoreElements()) {\n//            ProfilerPreset preset = (ProfilerPreset)presets.nextElement();\n//            if (!preset.isValid()) return false;\n//        }\n//        return true;\n//    }\n    \n    private static void normalizeNames(PresetsModel model) {\n        Map<String, Integer> names = new HashMap<>();\n        \n        for (int i = 0; i < model.getSize(); i++) {\n            ProfilerPreset preset = model.getElementAt(i);\n            names.put(preset.getName(), 0);\n        }\n        \n        for (int i = 0; i < model.getSize(); i++) {\n            ProfilerPreset preset = model.getElementAt(i);\n            String presetName = preset.getName();\n            Integer nameCounts = names.get(presetName);\n            if (nameCounts != null) {\n                if (nameCounts == 0) {\n                    names.put(presetName, ++nameCounts);\n                } else {\n                    String newName = normalizeName(presetName, nameCounts);\n                    while (names.containsKey(newName)) newName = normalizeName(presetName, ++nameCounts);\n                    preset.setName(newName);\n                    names.put(newName, 1);\n                    names.put(presetName, nameCounts);\n                    model.fireItemChanged(i);\n                }\n            }\n        }\n    }\n    \n    private static String normalizeName(String name, int modifier) {\n        return name + \" (\" + modifier + \")\"; // NOI18N\n    }\n\n\n    private JPanel presetsPanel;\n    private JList<ProfilerPreset> list;\n    private JButton addButton;\n    private JButton removeButton;\n    private JButton upButton;\n    private JButton downButton;\n    private JTextField nameField;\n    private JTextField targetField;\n    \n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/ProfilingOptionsPanelController.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport org.graalvm.visualvm.core.options.UISupport;\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport javax.swing.JComponent;\nimport org.netbeans.spi.options.OptionsPanelController;\nimport org.openide.util.HelpCtx;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@OptionsPanelController.TopLevelRegistration(\n        id = ProfilingOptionsPanelController.OPTIONS_HANDLE,\n        categoryName = \"#OptionsCategory_Name_Profiling\",\n        iconBase = \"org/graalvm/visualvm/profiling/resources/options.png\",\n        position = 1500\n)\npublic final class ProfilingOptionsPanelController extends OptionsPanelController {\n\n    static final String OPTIONS_HANDLE = \"ProfilerOptions\"; // NOI18N\n\n    private ProfilingOptionsPanel panel;\n    private JComponent component;\n    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);\n    private boolean changed;\n\n\n    public void update() {\n        getPanel().load();\n        changed = false;\n    }\n\n    public void applyChanges() {\n        getPanel().store();\n        getPanel().closed();\n        changed = false;\n    }\n\n    public void cancel() {\n        getPanel().closed();\n    }\n\n    public boolean isValid() {\n        return getPanel().valid();\n    }\n\n    public boolean isChanged() {\n        return changed;\n    }\n\n    public HelpCtx getHelpCtx() {\n        return null; // new HelpCtx(\"...ID\") if you have a help set\n    }\n\n    public JComponent getComponent(Lookup masterLookup) {\n        return getComponent();\n    }\n\n    public void addPropertyChangeListener(PropertyChangeListener l) {\n        pcs.addPropertyChangeListener(l);\n    }\n\n    public void removePropertyChangeListener(PropertyChangeListener l) {\n        pcs.removePropertyChangeListener(l);\n    }\n\n    private ProfilingOptionsPanel getPanel() {\n        if (panel == null) panel = new ProfilingOptionsPanel(this);\n        return panel;\n    }\n\n    private JComponent getComponent() {\n        if (component == null)\n            component = UISupport.createScrollableContainer(getPanel());\n        return component;\n    }\n\n    void changed() {\n        if (!changed) {\n            changed = true;\n            pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);\n        }\n        pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/ProfilingOptionsSectionProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport java.awt.Component;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilingOptionsSectionProvider {\n    \n    private ProfilingOptionsPanelController controller;\n    \n    void setController(ProfilingOptionsPanelController controller) {\n        this.controller = controller;\n    }\n    \n    \n    public abstract String getSectionName();\n    \n    public abstract Component getSection();\n    \n    \n    protected void load() {}\n\n    protected void store() {}\n\n    protected void closed() {}\n\n    protected boolean valid() {\n        return true;\n    }\n    \n    protected void changed() {\n        if (controller != null) controller.changed();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/SamplerCPUPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.text.NumberFormat;\nimport javax.swing.AbstractButton;\nimport javax.swing.BorderFactory;\nimport javax.swing.ButtonGroup;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JRadioButton;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextArea;\nimport javax.swing.ListCellRenderer;\nimport javax.swing.UIManager;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.filters.JavaTypeFilter;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerIDESettings;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class SamplerCPUPanel extends JPanel {\n    \n    private JRadioButton inclFilterRadioButton;\n    private JRadioButton exclFilterRadioButton;\n    private TextAreaComponent filtersArea;\n    private JLabel sampleRateLabel;\n    private JComboBox<Integer> sampleRateCombo;\n    private JLabel sampleRateUnitsLabel;\n    private JLabel refreshRateLabel;\n    private JLabel refreshUnitsLabel;\n    private JComboBox<Integer> refreshRateCombo;\n    \n    private final Runnable validator;\n    private boolean filtersValid = true;\n    private boolean internalChange;\n    \n    \n    public SamplerCPUPanel() {\n        this(null, false);\n    }\n    \n    SamplerCPUPanel(Runnable validator, boolean mnemonics) {\n        this.validator = validator;\n        initComponents(mnemonics);\n    }\n    \n    \n    public ProfilingSettings getSettings() {\n        ProfilingSettings settings = ProfilerIDESettings.getInstance().createDefaultProfilingSettings();\n        settings.setProfilingType(ProfilingSettings.PROFILE_CPU_SAMPLING);\n        settings.setCPUProfilingType(CommonConstants.CPU_SAMPLED);\n        \n        String filter = getFilterValue();\n        if (filter.isEmpty() || \"*\".equals(filter) || \"**\".equals(filter)) { // NOI18N\n            settings.setInstrumentationFilter(new JavaTypeFilter());\n        } else {\n            int filterType = inclFilterRadioButton.isSelected() ?\n                             JavaTypeFilter.TYPE_INCLUSIVE : JavaTypeFilter.TYPE_EXCLUSIVE;\n            String filterValue = PresetsUtils.normalizeValue(filter);\n            settings.setInstrumentationFilter(new JavaTypeFilter(filterValue, filterType));\n        }\n        \n        return settings;\n    }\n    \n    public int getSamplingRate() {\n        return (Integer)sampleRateCombo.getSelectedItem();\n    }\n    \n    public int getRefreshRate() {\n        return (Integer)refreshRateCombo.getSelectedItem();\n    }\n    \n    \n    public boolean settingsValid() { return filtersValid; }\n    \n    public void loadFromPreset(ProfilerPreset preset) {\n        if (preset == null) return;\n\n        internalChange = true;\n        inclFilterRadioButton.setSelected(!preset.getFilterModeS());\n        exclFilterRadioButton.setSelected(preset.getFilterModeS());\n        filtersArea.getTextArea().setText(preset.getFilterS());\n        sampleRateCombo.setSelectedItem(preset.getSamplingRateS());\n        refreshRateCombo.setSelectedItem(preset.getRefreshRateS());\n        internalChange = false;\n        \n        checkFilterValidity();\n    }\n    \n    public void saveToPreset(ProfilerPreset preset) {\n        if (preset == null) return;\n        \n        preset.setFilterModeS(exclFilterRadioButton.isSelected());\n        preset.setFilterS(filtersArea.getTextArea().getText());\n        preset.setSamplingRateS((Integer)sampleRateCombo.getSelectedItem());\n        preset.setRefreshRateS((Integer)refreshRateCombo.getSelectedItem());\n    }\n    \n    public abstract void settingsChanged();\n    \n    private void syncUI() {\n        if (internalChange) return;\n        settingsChanged();\n    }\n    \n    \n    private void checkFilterValidity() {\n        filtersValid = isFilterValueValid();\n        filtersArea.getTextArea().setForeground(filtersValid ?\n            UIManager.getColor(\"TextArea.foreground\") : Color.RED); // NOI18N\n        if (validator != null) validator.run();\n    }\n\n    public boolean isFilterValueValid() {\n        String filterValue = PresetsUtils.normalizeValue(getFilterValue());\n        return PresetsUtils.isValidJavaValue(filterValue, true, false);\n    }\n\n    private String getFilterValue() {\n        return filtersArea.getTextArea().getText().trim();\n    }\n    \n    \n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        for (Component c : getComponents()) c.setEnabled(enabled);\n    }\n    \n    private void initComponents(boolean mnemonics) {\n        setOpaque(false);\n        setLayout(new GridBagLayout());\n\n        ButtonGroup filterRadiosGroup = new ButtonGroup();\n        GridBagConstraints constraints;\n\n        JLabel referenceLabel = new JLabel(\"X\"); // NOI18N\n\n        JPanel radiosPanel = new JPanel(new GridBagLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents())\n                    c.setEnabled(enabled);\n            }\n        };\n        radiosPanel.setOpaque(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 4;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(0, 0, 0, 0);\n        add(radiosPanel, constraints);\n\n        inclFilterRadioButton = new JRadioButton() {\n            protected void fireActionPerformed(ActionEvent e) { syncUI(); }\n        };\n        setText(inclFilterRadioButton, NbBundle.getMessage(SamplerCPUPanel.class,\n                \"LBL_Profile_Incl_S\"), mnemonics); // NOI18N\n        inclFilterRadioButton.setToolTipText(NbBundle.getMessage(\n                SamplerCPUPanel.class, \"TOOLTIP_Inclusive_Filter_S\")); // NOI18N\n        inclFilterRadioButton.setOpaque(false);\n        inclFilterRadioButton.setBorder(referenceLabel.getBorder());\n        Dimension d1 = inclFilterRadioButton.getPreferredSize();\n        d1.height = Math.max(d1.height, referenceLabel.getPreferredSize().height);\n        inclFilterRadioButton.setPreferredSize(d1);\n        filterRadiosGroup.add(inclFilterRadioButton);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 0;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(10, 10, 5, 5);\n        radiosPanel.add(inclFilterRadioButton, constraints);\n\n        exclFilterRadioButton = new JRadioButton() {\n            protected void fireActionPerformed(ActionEvent e) { syncUI(); }\n        };\n        setText(exclFilterRadioButton, NbBundle.getMessage(SamplerCPUPanel.class,\n                \"LBL_Profile_Excl_S\"), mnemonics); // NOI18N\n        exclFilterRadioButton.setToolTipText(NbBundle.getMessage(\n                SamplerCPUPanel.class, \"TOOLTIP_Exclusive_Filter_S\")); // NOI18N\n        exclFilterRadioButton.setOpaque(false);\n        exclFilterRadioButton.setBorder(referenceLabel.getBorder());\n        Dimension d2 = exclFilterRadioButton.getPreferredSize();\n        d2.height = Math.max(d2.height, referenceLabel.getPreferredSize().height);\n        exclFilterRadioButton.setPreferredSize(d2);\n        filterRadiosGroup.add(exclFilterRadioButton);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 1;\n        constraints.gridy = 0;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(10, 5, 5, 10);\n        radiosPanel.add(exclFilterRadioButton, constraints);\n\n        constraints = new GridBagConstraints();\n        constraints.gridx = 2;\n        constraints.gridy = 0;\n        constraints.weightx = 1;\n        constraints.weighty = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.HORIZONTAL;\n        constraints.insets = new Insets(10, 0, 5, 0);\n        radiosPanel.add(Spacer.create(), constraints);\n\n        filtersArea = createTextArea(2);\n        filtersArea.getTextArea().setToolTipText(NbBundle.getMessage(\n                SamplerCPUPanel.class, \"TOOLTIP_Instrumentation_Filter_S\")); // NOI18N\n        filtersArea.getTextArea().getDocument().addDocumentListener(new DocumentListener() {\n            public void insertUpdate(DocumentEvent e) { checkFilterValidity(); syncUI(); }\n            public void removeUpdate(DocumentEvent e) { checkFilterValidity(); syncUI(); }\n            public void changedUpdate(DocumentEvent e) { checkFilterValidity(); syncUI(); }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 5;\n        constraints.weightx = 1;\n        constraints.weighty = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.insets = new Insets(0, 10, 10, 10);\n        add(filtersArea, constraints);\n\n        sampleRateLabel = new JLabel();\n        setText(sampleRateLabel, NbBundle.getMessage(SamplerCPUPanel.class,\n                \"LBL_Sampling_rate\"), mnemonics); // NOI18N\n        sampleRateLabel.setToolTipText(NbBundle.getMessage(\n                SamplerCPUPanel.class, \"TOOLTIP_Sampling_rate\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 6;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 10, 5, 5);\n        add(sampleRateLabel, constraints);\n\n        Integer[] samplingRates =\n            new Integer[] { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000 };\n        sampleRateCombo = new JComboBox<Integer>(samplingRates) {\n            public Dimension getMinimumSize() { return getPreferredSize(); }\n            public Dimension getMaximumSize() { return getPreferredSize(); }\n        };\n        sampleRateLabel.setLabelFor(sampleRateCombo);\n        sampleRateCombo.setToolTipText(NbBundle.getMessage(\n                SamplerCPUPanel.class, \"TOOLTIP_Sampling_rate\")); // NOI18N\n        sampleRateCombo.setEditable(false);\n        sampleRateCombo.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { syncUI(); }\n        });\n        sampleRateCombo.setRenderer(new ComboRenderer(sampleRateCombo));\n        constraints = new GridBagConstraints();\n        constraints.gridx = 1;\n        constraints.gridy = 6;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 0, 5, 5);\n        add(sampleRateCombo, constraints);\n\n        sampleRateUnitsLabel = new JLabel(NbBundle.getMessage(\n                SamplerCPUPanel.class, \"LBL_units_ms\")); // NOI18N\n        sampleRateUnitsLabel.setToolTipText(NbBundle.getMessage(\n                SamplerCPUPanel.class, \"TOOLTIP_Sampling_rate\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 2;\n        constraints.gridy = 6;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 0, 5, 5);\n        add(sampleRateUnitsLabel, constraints);\n\n        constraints = new GridBagConstraints();\n        constraints.gridx = 3;\n        constraints.gridy = 6;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.HORIZONTAL;\n        constraints.insets = new Insets(5, 0, 5, 0);\n        add(Spacer.create(), constraints);\n\n        refreshRateLabel = new JLabel();\n        setText(refreshRateLabel, NbBundle.getMessage(SamplerCPUPanel.class,\n                \"LBL_Refresh_rate\"), mnemonics); // NOI18N\n        refreshRateLabel.setToolTipText(NbBundle.getMessage(\n                SamplerCPUPanel.class, \"TOOLTIP_Refresh_rate\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 7;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(1, 10, 10, 5);\n        add(refreshRateLabel, constraints);\n\n        Integer[] refreshRates = new Integer[] { 100, 200, 500, 1000, 2000, 5000, 10000 };\n        refreshRateCombo = new JComboBox<Integer>(refreshRates) {\n            public Dimension getMinimumSize() { return getPreferredSize(); }\n            public Dimension getMaximumSize() { return getPreferredSize(); }\n        };\n        refreshRateLabel.setLabelFor(refreshRateCombo);\n        refreshRateCombo.setToolTipText(NbBundle.getMessage(\n                SamplerCPUPanel.class, \"TOOLTIP_Refresh_rate\")); // NOI18N\n        refreshRateCombo.setEditable(false);\n        refreshRateCombo.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { syncUI(); }\n        });\n        refreshRateCombo.setRenderer(new ComboRenderer(refreshRateCombo));\n        constraints = new GridBagConstraints();\n        constraints.gridx = 1;\n        constraints.gridy = 7;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(1, 0, 10, 5);\n        add(refreshRateCombo, constraints);\n\n        refreshUnitsLabel = new JLabel(NbBundle.getMessage(\n                SamplerCPUPanel.class, \"LBL_units_ms\")); // NOI18N\n        refreshUnitsLabel.setToolTipText(NbBundle.getMessage(\n                SamplerCPUPanel.class, \"TOOLTIP_Refresh_rate\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 2;\n        constraints.gridy = 7;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(1, 0, 10, 5);\n        add(refreshUnitsLabel, constraints);\n\n        constraints = new GridBagConstraints();\n        constraints.gridx = 3;\n        constraints.gridy = 7;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.HORIZONTAL;\n        constraints.insets = new Insets(1, 0, 10, 0);\n        add(Spacer.create(), constraints);\n    }\n    \n    \n    private static void setText(JLabel l, String text, boolean mnemonics) {\n        if (mnemonics) Mnemonics.setLocalizedText(l, text);\n        else l.setText(text.replace(\"&\", \"\")); // NOI18N\n    }\n    \n    private static void setText(AbstractButton b, String text, boolean mnemonics) {\n        if (mnemonics) Mnemonics.setLocalizedText(b, text);\n        else b.setText(text.replace(\"&\", \"\")); // NOI18N\n    }\n    \n    \n    private static TextAreaComponent createTextArea(int rows) {\n        final JTextArea rootsArea = new JTextArea();\n        rootsArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN,\n                UIManager.getFont(\"Label.font\").getSize())); // NOI18N\n        TextAreaComponent rootsAreaScrollPane = new TextAreaComponent(rootsArea,\n                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,\n                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) {\n            public Dimension getMinimumSize() {\n                return getPreferredSize();\n            }\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                rootsArea.setEnabled(enabled);\n            }\n        };\n        rootsAreaScrollPane.setBorder(BorderFactory.createLineBorder(Color.GRAY));\n        JTextArea referenceArea = new JTextArea(\"X\"); // NOI18N\n        referenceArea.setFont(rootsArea.getFont());\n        referenceArea.setRows(rows);\n        Insets insets = rootsAreaScrollPane.getInsets();\n        rootsAreaScrollPane.setPreferredSize(new Dimension(1,\n                referenceArea.getPreferredSize().height + (insets != null ?\n                 insets.top + insets.bottom : 0)));\n        return rootsAreaScrollPane;\n    }\n    \n    private static class TextAreaComponent extends JScrollPane {\n        TextAreaComponent(JTextArea textArea, int vPolicy, int hPolicy) {\n            super(textArea, vPolicy, hPolicy);\n        }\n        public JTextArea getTextArea() {\n            return (JTextArea)getViewport().getView();\n        }\n    }\n\n    private static class ComboRenderer implements ListCellRenderer {\n\n        private ListCellRenderer renderer;\n\n        ComboRenderer(JComboBox combo) {\n            renderer = combo.getRenderer();\n            if (renderer instanceof JLabel)\n                ((JLabel)renderer).setHorizontalAlignment(JLabel.TRAILING);\n        }\n\n        public Component getListCellRendererComponent(JList list, Object value,\n                int index, boolean isSelected, boolean cellHasFocus) {\n            \n            return renderer.getListCellRendererComponent(list, NumberFormat.\n                    getInstance().format(value), index, isSelected, cellHasFocus);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/SamplerCPUSettings.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport javax.swing.JPanel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class SamplerCPUSettings extends JPanel {\n\n    private ProfilerPreset preset;\n    private final SamplerCPUPanel panel;\n\n    \n    SamplerCPUSettings(Runnable validator) {\n        this.panel = new SamplerCPUPanel(validator, true) {\n            public void settingsChanged() { panel.saveToPreset(preset); }\n        };\n        setLayout(new BorderLayout());\n        add(panel, BorderLayout.CENTER);\n    }\n\n    void setPreset(ProfilerPreset preset) {\n        this.preset = preset;\n        panel.loadFromPreset(preset);\n    }\n\n    boolean valid() { return panel.settingsValid(); }\n\n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        for (Component c : getComponents())\n            c.setEnabled(enabled);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/SamplerMemoryPanel.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.text.NumberFormat;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.ListCellRenderer;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class SamplerMemoryPanel extends JPanel {\n    \n    private JLabel refreshRateLabel;\n    private JLabel refreshUnitsLabel;\n    private JComboBox<Integer> refreshCombo;\n    \n    private boolean internalChange;\n    \n    \n    public SamplerMemoryPanel() {\n        this(false);\n    }\n    \n    SamplerMemoryPanel(boolean mnemonics) {\n        initComponents(mnemonics);\n    }\n    \n    \n    public ProfilingSettings getSettings() {\n        return null;\n    }\n    \n    public int getSamplingRate() {\n        return (Integer)refreshCombo.getSelectedItem();\n    }\n\n    public int getRefreshRate() {\n        return getSamplingRate();\n    }\n    \n    \n    public boolean settingsValid() { return true; }\n    \n    public void loadFromPreset(ProfilerPreset preset) {\n        if (preset == null) return;\n\n        internalChange = true;\n        refreshCombo.setSelectedItem(preset.getSamplingRefreshRateS());\n        internalChange = false;\n    }\n    \n    public void saveToPreset(ProfilerPreset preset) {\n        if (preset == null) return;\n        \n        preset.setSamplingRefreshRateS((Integer)refreshCombo.getSelectedItem());\n    }\n    \n    public abstract void settingsChanged();\n    \n    private void syncUI() {\n        if (internalChange) return;\n        settingsChanged();\n    }\n    \n    \n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        for (Component c : getComponents()) c.setEnabled(enabled);\n    }\n    \n    private void initComponents(boolean mnemonics) {\n        setOpaque(false);\n        setLayout(new GridBagLayout());\n\n        GridBagConstraints constraints;\n\n        refreshRateLabel = new JLabel();\n        setText(refreshRateLabel, NbBundle.getMessage(SamplerMemoryPanel.class,\n                \"LBL_Sampling_refresh\"), mnemonics); // NOI18N\n        refreshRateLabel.setToolTipText(NbBundle.getMessage(SamplerMemoryPanel.class,\n                \"TOOLTIP_Sampling_refresh\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 0;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(7, 10, 10, 5);\n        add(refreshRateLabel, constraints);\n\n        Integer[] refreshRates = new Integer[] { 100, 200, 500, 1000, 2000, 5000, 10000 };\n        refreshCombo = new JComboBox(refreshRates) {\n            public Dimension getMinimumSize() { return getPreferredSize(); }\n            public Dimension getMaximumSize() { return getPreferredSize(); }\n        };\n        refreshRateLabel.setLabelFor(refreshCombo);\n        refreshCombo.setToolTipText(NbBundle.getMessage(SamplerMemoryPanel.class,\n                \"TOOLTIP_Sampling_refresh\")); // NOI18N\n        refreshCombo.setEditable(false);\n        refreshCombo.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { syncUI(); }\n        });\n        refreshCombo.setRenderer(new ComboRenderer(refreshCombo));\n        constraints = new GridBagConstraints();\n        constraints.gridx = 1;\n        constraints.gridy = 0;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(7, 0, 10, 5);\n        add(refreshCombo, constraints);\n\n        refreshUnitsLabel = new JLabel(NbBundle.getMessage(SamplerMemoryPanel.class,\n                \"LBL_units_ms\")); // NOI18N\n        refreshUnitsLabel.setToolTipText(NbBundle.getMessage(SamplerMemoryPanel.class,\n                \"TOOLTIP_Sampling_refresh\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 2;\n        constraints.gridy = 0;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(7, 0, 10, 5);\n        add(refreshUnitsLabel, constraints);\n\n        constraints = new GridBagConstraints();\n        constraints.gridx = 3;\n        constraints.gridy = 0;\n        constraints.weightx = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.HORIZONTAL;\n        constraints.insets = new Insets(7, 0, 10, 0);\n        add(Spacer.create(), constraints);\n\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 1;\n        constraints.weighty = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.insets = new Insets(0, 0, 0, 0);\n        add(Spacer.create(), constraints);\n    }\n    \n    \n    private static void setText(JLabel l, String text, boolean mnemonics) {\n        if (mnemonics) Mnemonics.setLocalizedText(l, text);\n        else l.setText(text.replace(\"&\", \"\")); // NOI18N\n    }\n\n\n    private static class ComboRenderer implements ListCellRenderer {\n\n        private ListCellRenderer renderer;\n\n        ComboRenderer(JComboBox combo) {\n            renderer = combo.getRenderer();\n            if (renderer instanceof JLabel)\n                ((JLabel)renderer).setHorizontalAlignment(JLabel.TRAILING);\n        }\n\n        public Component getListCellRendererComponent(JList list, Object value,\n                int index, boolean isSelected, boolean cellHasFocus) {\n            \n            return renderer.getListCellRendererComponent(list, NumberFormat.\n                    getInstance().format(value), index, isSelected, cellHasFocus);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/presets/SamplerMemorySettings.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.presets;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport javax.swing.JPanel;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class SamplerMemorySettings extends JPanel {\n\n    private ProfilerPreset preset;\n    private final SamplerMemoryPanel panel;\n\n    \n    SamplerMemorySettings() {\n        this.panel = new SamplerMemoryPanel(true) {\n            public void settingsChanged() { panel.saveToPreset(preset); }\n        };\n        setLayout(new BorderLayout());\n        add(panel, BorderLayout.CENTER);\n    }\n\n    void setPreset(ProfilerPreset preset) {\n        this.preset = preset;\n        panel.loadFromPreset(preset);\n    }\n    \n    boolean valid() { return panel.settingsValid(); }\n\n    public void setEnabled(boolean enabled) {\n        super.setEnabled(enabled);\n        for (Component c : getComponents())\n            c.setEnabled(enabled);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/snapshot/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nMSG_Save_Profiler_Snapshot_As=Save Profiler Snapshot As\n\nDESCR_Profiler_Snapshot=Profiler Snapshot\n\nMSG_Profiler_Snapshots=Profiler Snapshots\n\nMSG_Opening_Profiler_Snapshot=Opening Profiler Snapshot...\n\nMSG_Opening_snapshot_failed=Opening snapshot failed.\n\nDESCR_ProfilerSnapshot=Profiler snapshot.\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/snapshot/ProfilerSnapshot.java",
    "content": "/*\n *  Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.profiling.snapshot;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsSupport;\nimport java.awt.Image;\nimport java.io.File;\nimport javax.swing.JComponent;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic abstract class ProfilerSnapshot extends Snapshot {\n\n    static final Image CPU_ICON = Icons.getImage(ProfilerIcons.CPU);\n    static final Image MEMORY_ICON = Icons.getImage(ProfilerIcons.MEMORY);\n    static final Image JDBC_ICON = Icons.getImage(ProfilerIcons.SQL_QUERY);\n    static final Image SNAPSHOT_ICON = Icons.getImage(ProfilerIcons.SNAPSHOT_DO);\n    static final Image NODE_BADGE = ImageUtilities.loadImage(\n            \"org/graalvm/visualvm/core/ui/resources/snapshotBadge.png\", true);    // NOI18N\n   \n    public static ProfilerSnapshot createSnapshot(File file, DataSource master) {\n        if (file.getName().endsWith(ResultsManager.STACKTRACES_SNAPSHOT_EXTENSION)) {\n            return new ProfilerSnapshotNPSS(file,master);\n        }\n        return new ProfilerSnapshotNPS(file,master);\n    }\n\n    public ProfilerSnapshot() {\n        super(null, ProfilerSnapshotsSupport.getInstance().getCategory());\n    }\n    \n    public ProfilerSnapshot(File file, DataSource master) {\n        super(file, ProfilerSnapshotsSupport.getInstance().getCategory(), master);\n    }\n    \n    @Override\n    public boolean supportsSaveAs() {\n        return getFile() != null;\n    }\n    \n    @Override\n    protected void remove() {\n        super.remove();\n    }\n    \n    @Override\n    public void saveAs() {\n        SnapshotsSupport.getInstance().saveAs(this, NbBundle.getMessage(\n                ProfilerSnapshot.class, \"MSG_Save_Profiler_Snapshot_As\"));  // NOI18N\n    }\n\n    public abstract LoadedSnapshot getLoadedSnapshot();\n    \n    abstract Image resolveIcon();\n    \n    abstract JComponent getUIComponent();\n    \n    abstract void closeComponent();\n    \n    \n    void forceViewClosable(boolean closable) {\n        getStorage().setCustomProperty(PROPERTY_VIEW_CLOSABLE, Boolean.toString(closable));\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/snapshot/ProfilerSnapshotCategory.java",
    "content": "/*\n *  Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.profiling.snapshot;\n\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport java.io.File;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.SwingUtilities;\nimport javax.swing.filechooser.FileFilter;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class ProfilerSnapshotCategory extends SnapshotCategory<ProfilerSnapshot> {\n    private static final Logger LOGGER =\n            Logger.getLogger(ProfilerSnapshotCategory.class.getName());\n    \n    private static final String NAME = NbBundle.getMessage(\n            ProfilerSnapshotCategory.class, \"MSG_Profiler_Snapshots\");   // NOI18N\n    private static final String PREFIX = \"snapshot\";    // NOI18N\n    private static final String NPS_SUFFIX = \".\"+ResultsManager.SNAPSHOT_EXTENSION;    // NOI18N\n    private static final String NPSS_SUFFIX = \".\"+ResultsManager.STACKTRACES_SNAPSHOT_EXTENSION;    // NOI18N\n    \n    ProfilerSnapshotCategory() {\n        super(NAME, ProfilerSnapshot.class, PREFIX, NPS_SUFFIX, 30);\n    }\n    \n    public boolean supportsOpenSnapshot() {\n        return true;\n    }\n    \n    protected boolean isSnapshot(File file) {\n        if (super.isSnapshot(file)) {\n            return true;\n        }\n        return file != null && file.getName().endsWith(NPSS_SUFFIX);\n    }\n\n    public void openSnapshot(final File file) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                ProgressHandle pHandle = null;\n                try {\n                    pHandle = ProgressHandle.createHandle(\n                            NbBundle.getMessage(ProfilerSnapshotCategory.class,\n                                                \"MSG_Opening_Profiler_Snapshot\")); // NOI18N\n                    pHandle.setInitialDelay(0);\n                    pHandle.start();\n                    try {\n                        ProfilerSnapshot snapshot = ProfilerSnapshot.createSnapshot(file, null);\n                        DataSourceWindowManager.sharedInstance().openDataSource(snapshot);\n                    } catch (Exception e) {\n                        LOGGER.log(Level.INFO, \"Error loading profiler snapshot\", e); // NOI18N\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                ProfilerDialogs.displayError(\n                                        NbBundle.getMessage(ProfilerSnapshotCategory.class,\n                                                            \"MSG_Opening_snapshot_failed\")); // NOI18N\n                            }   \n                        });\n                    }\n                } finally {\n                    final ProgressHandle pHandleF = pHandle;\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { if (pHandleF != null) pHandleF.finish(); }\n                    });\n                }\n            }\n        });\n    }\n    \n    public FileFilter getFileFilter() {\n        return new FileFilter() {\n            public boolean accept(File f) {\n                return f.isDirectory() || isSnapshot(f);\n            }\n            public String getDescription() {\n                String suff = getSuffix();\n                return getName() + (suff != null ? \" (*\" + suff +\", *\" + NPSS_SUFFIX + \")\" : \"\");    // NOI18N\n            }\n        };\n    }    \n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/snapshot/ProfilerSnapshotDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.snapshot;\n\nimport org.graalvm.visualvm.core.snapshot.SnapshotDescriptor;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class ProfilerSnapshotDescriptor extends SnapshotDescriptor<ProfilerSnapshot> {        \n\n    ProfilerSnapshotDescriptor(ProfilerSnapshot snapshot) {\n        super(snapshot, NbBundle.getMessage(ProfilerSnapshotDescriptor.class,\n              \"DESCR_ProfilerSnapshot\"), snapshot.resolveIcon()); // NOI18N\n    }    \n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/snapshot/ProfilerSnapshotDescriptorProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.snapshot;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class ProfilerSnapshotDescriptorProvider extends AbstractModelProvider<DataSourceDescriptor,DataSource> {\n    \n    ProfilerSnapshotDescriptorProvider() {\n    }\n    \n    public DataSourceDescriptor createModelFor(DataSource ds) {\n        if (ds instanceof ProfilerSnapshot) {\n            return new ProfilerSnapshotDescriptor((ProfilerSnapshot) ds);\n        }\n        return null;\n    }\n    \n    \n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/snapshot/ProfilerSnapshotNPS.java",
    "content": "/*\n *  Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiling.snapshot;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.profiling.actions.ProfilerResultsAction;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Image;\nimport java.io.File;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.JComponent;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.jfluid.global.CommonConstants;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.SnapshotResultsWindow;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.ImageUtilities;\nimport org.openide.windows.TopComponent;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class ProfilerSnapshotNPS extends ProfilerSnapshot {\n\n    private static final Logger LOGGER = Logger.getLogger(ProfilerSnapshotNPS.class.getName());\n    private LoadedSnapshot loadedSnapshot;\n    private FileObject snapshotFO;\n    private TopComponent srw;\n\n    ProfilerSnapshotNPS() {\n        super();\n    }\n\n    ProfilerSnapshotNPS(File snapshot, DataSource master) {\n        super(snapshot, master);\n        snapshotFO = FileUtil.toFileObject(FileUtil.normalizeFile(snapshot));\n    }\n\n    @Override\n    public synchronized LoadedSnapshot getLoadedSnapshot() {\n        if (loadedSnapshot == null)\n            loadedSnapshot = ResultsManager.getDefault().loadSnapshot(snapshotFO);\n        return loadedSnapshot;\n    }\n\n    @Override\n    protected void remove() {\n        super.remove();\n        closeSnapshot();\n    }\n\n    @Override\n    protected Image resolveIcon() {\n        try {\n            int snapshotType = ResultsManager.getDefault().getSnapshotType(snapshotFO);\n            switch (snapshotType) {\n                case LoadedSnapshot.SNAPSHOT_TYPE_CPU:\n                    return ImageUtilities.mergeImages(CPU_ICON, NODE_BADGE, 0, 0);\n                case LoadedSnapshot.SNAPSHOT_TYPE_CPU_JDBC:\n                    return ImageUtilities.mergeImages(JDBC_ICON, NODE_BADGE, 0, 0);\n                case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_LIVENESS:\n                case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_ALLOCATIONS:\n                case LoadedSnapshot.SNAPSHOT_TYPE_MEMORY_SAMPLED:\n                    return ImageUtilities.mergeImages(MEMORY_ICON, NODE_BADGE, 0, 0);\n                default:\n                    // Fallback icon, cannot return null - throws NPE in DataSourceView\n                    return ImageUtilities.mergeImages(SNAPSHOT_ICON, NODE_BADGE, 0, 0);\n            }\n        } catch (Exception e) {\n            LOGGER.log(Level.FINE, \"Failed to determine profiler snapshot type\", e);  // NOI18N\n            // Fallback icon, cannot return null - throws NPE in DataSourceView\n            return ImageUtilities.mergeImages(SNAPSHOT_ICON, NODE_BADGE, 0, 0);\n        }\n    }\n\n    @Override\n    JComponent getUIComponent() {\n        if (srw == null) {\n            srw = SnapshotResultsWindow.get(getLoadedSnapshot(), CommonConstants.SORTING_COLUMN_DEFAULT, false);\n            srw.setPreferredSize(new Dimension(1, 1));\n            \n            DataSource master = getMaster();\n            if (master instanceof Application && srw.getComponentCount() > 0) {\n                Component c = srw.getComponent(0);\n                if (c instanceof JComponent) ((JComponent)c).putClientProperty(ProfilerResultsAction.PROP_APPLICATION, master);\n            }\n        }\n        return srw;\n    }\n\n    @Override\n    void closeComponent() {\n        if (srw != null) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    try {\n                        Method method = srw.getClass().getDeclaredMethod(\"componentClosed\");   // NOI18N\n                        if (method != null) {\n                            method.setAccessible(true);\n                            method.invoke(srw);\n                        }\n                    } catch (NoSuchMethodException noSuchMethodException) {\n                        LOGGER.throwing(ProfilerSnapshotView.class.getName(),\n                                \"removed\", noSuchMethodException);   // NOI18N\n                    } catch (SecurityException securityException) {\n                        LOGGER.throwing(ProfilerSnapshotView.class.getName(),\n                                \"removed\", securityException);   // NOI18N\n                    } catch (IllegalAccessException illegalAccessException) {\n                        LOGGER.throwing(ProfilerSnapshotView.class.getName(),\n                                \"removed\", illegalAccessException);   // NOI18N\n                    } catch (IllegalArgumentException illegalArgumentException) {\n                        LOGGER.throwing(ProfilerSnapshotView.class.getName(),\n                                \"removed\", illegalArgumentException);   // NOI18N\n                    } catch (InvocationTargetException invocationTargetException) {\n                        LOGGER.throwing(ProfilerSnapshotView.class.getName(),\n                                \"removed\", invocationTargetException);   // NOI18N\n                    }\n                    srw = null;\n                    closeSnapshot();\n                }\n            });\n        }\n    }\n\n    private synchronized void closeSnapshot() {\n        ResultsManager.getDefault().closeSnapshot(loadedSnapshot);\n        loadedSnapshot = null;\n    }\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/snapshot/ProfilerSnapshotNPSS.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.profiling.snapshot;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport java.awt.Image;\nimport java.io.File;\nimport java.io.IOException;\nimport javax.swing.JComponent;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.IdeSnapshot;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.TracerController;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.TracerModel;\nimport org.graalvm.visualvm.lib.profiler.snaptracer.impl.TracerView;\nimport org.openide.filesystems.FileObject;\nimport org.openide.filesystems.FileUtil;\nimport org.openide.util.Exceptions;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * This is prototype to handle npss files.\n *\n * @author Tomas Hurka\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages(\"MSG_SnapshotLoadFailedMsg=Error while loading snapshot: {0}\")\nclass ProfilerSnapshotNPSS extends ProfilerSnapshot {\n\n    private IdeSnapshot loadedSnapshot;\n\n    ProfilerSnapshotNPSS(File file, DataSource master) {\n        super(file, master);\n        try {\n            FileObject primary = FileUtil.toFileObject(file);\n            FileObject uigestureFO = primary.getParent().getFileObject(primary.getName(), \"log\"); // NOI18N\n            loadedSnapshot = new IdeSnapshot(primary, uigestureFO);\n        } catch (IOException ex) {\n            Exceptions.printStackTrace(ex);\n        }\n    }\n\n    @Override\n    public LoadedSnapshot getLoadedSnapshot() {\n        throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n    }\n\n    @Override\n    Image resolveIcon() {\n        return ImageUtilities.mergeImages(CPU_ICON, NODE_BADGE, 0, 0);\n    }\n\n    @Override\n    protected void remove() {\n        super.remove();\n        loadedSnapshot = null;\n    }\n\n    @Override\n    JComponent getUIComponent() {\n        TracerModel model = new TracerModel(loadedSnapshot);\n        TracerController controller = new TracerController(model);\n        TracerView view = new TracerView(model, controller);\n        return view.createComponent();\n    }\n\n    @Override\n    void closeComponent() {\n        // no op\n    }\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/snapshot/ProfilerSnapshotProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.snapshot;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport java.io.File;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.core.VisualVM;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class ProfilerSnapshotProvider {\n    \n    void createSnapshot(File snapshotFile, Application application, final boolean openView) {\n        final ProfilerSnapshot snapshot = ProfilerSnapshot.createSnapshot(snapshotFile, application);\n        application.getRepository().addDataSource(snapshot);\n        if (openView) DataSource.EVENT_QUEUE.post(new Runnable() {\n            public void run() {\n                DataSourceWindowManager.sharedInstance().openDataSource(snapshot);\n            }\n        });\n    }\n    \n    void initialize() {\n        DataSourceRepository.sharedInstance().addDataChangeListener(\n                new SnapshotListener(), Snapshot.class);\n        DataSourceRepository.sharedInstance().addDataChangeListener(\n                new ApplicationListener(), Application.class);\n    }\n    \n    \n    private void processNewSnapshot(Snapshot snapshot) {\n        if (snapshot instanceof ProfilerSnapshot) return;\n        boolean appSnapshot = snapshot instanceof ApplicationSnapshot;\n        File snapshotFile = snapshot.getFile();\n        if (snapshotFile != null && snapshotFile.isDirectory()) {\n            Set<ProfilerSnapshot> snapshots = findSnapshots(snapshotFile, snapshot, appSnapshot);\n            snapshot.getRepository().addDataSources(snapshots);\n        }\n    }\n    \n    private void processNewApplication(Application application) {\n        Storage storage = application.getStorage();\n        if (storage.directoryExists()) {\n            Set<ProfilerSnapshot> snapshots = findSnapshots(storage.getDirectory(), application, false);\n            application.getRepository().addDataSources(snapshots);\n        }\n    }\n    \n    private Set<ProfilerSnapshot> findSnapshots(File directory, DataSource app, boolean forceClosable) {\n        File[] files = directory.listFiles(\n                ProfilerSnapshotsSupport.getInstance().getCategory().getFilenameFilter());\n        if (files == null) return Collections.emptySet();\n        Set<ProfilerSnapshot> snapshots = new HashSet<>(files.length);\n        for (File file : files) {\n            ProfilerSnapshot snapshot = ProfilerSnapshot.createSnapshot(file, app);\n            if (forceClosable) snapshot.forceViewClosable(true);\n            snapshots.add(snapshot);\n        }\n        return snapshots;\n    }\n    \n    \n    private class SnapshotListener implements DataChangeListener<Snapshot> {\n        \n        public void dataChanged(DataChangeEvent<Snapshot> event) {\n            final Set<Snapshot> snapshots = event.getAdded();\n            if (!snapshots.isEmpty()) VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    for (Snapshot snapshot : snapshots) processNewSnapshot(snapshot);\n                }\n            });\n        }\n        \n    }\n    \n    private class ApplicationListener implements DataChangeListener<Application> {\n        \n        public void dataChanged(DataChangeEvent<Application> event) {\n            final Set<Application> applications = event.getAdded();\n            if (!applications.isEmpty()) VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    for (Application application : applications)\n                        processNewApplication(application);\n                }\n            });\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/snapshot/ProfilerSnapshotView.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.snapshot;\n\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Positionable;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.core.snapshot.SnapshotView;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class ProfilerSnapshotView extends SnapshotView {\n    \n    private ProfilerSnapshot loadedSnapshot = null;\n\n    ProfilerSnapshotView(ProfilerSnapshot snapshot) {\n        this(snapshot, DataSourceDescriptorFactory.getDescriptor(snapshot));\n    }\n    \n    private ProfilerSnapshotView(ProfilerSnapshot snapshot, DataSourceDescriptor descriptor) {\n        super(snapshot, descriptor.getName(), descriptor.getIcon(), Positionable.POSITION_AT_THE_END);\n        loadedSnapshot = snapshot;\n    }\n    \n        \n    protected void removed() {\n        loadedSnapshot.closeComponent();\n        loadedSnapshot = null;\n    }\n    \n    protected DataViewComponent createComponent() {\n        DataViewComponent dvc = new DataViewComponent(\n                new MasterViewSupport().getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(true));\n        \n        return dvc;\n    }\n    \n    \n    // --- General data --------------------------------------------------------\n    \n    private class MasterViewSupport extends JPanel  {\n        \n        public DataViewComponent.MasterView getMasterView() {\n            JComponent srw = loadedSnapshot.getUIComponent();\n            return new DataViewComponent.MasterView(NbBundle.getMessage(\n                    ProfilerSnapshotView.class, \"DESCR_Profiler_Snapshot\"), null, srw);   // NOI18N\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/snapshot/ProfilerSnapshotViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.snapshot;\n\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ProfilerSnapshotViewProvider extends DataSourceViewProvider<ProfilerSnapshot>{\n    \n    protected boolean supportsViewFor(ProfilerSnapshot snapshot) {\n        return true;\n    }\n    \n    protected DataSourceView createView(ProfilerSnapshot snapshot) {\n        return new ProfilerSnapshotView(snapshot);\n    }\n    \n\n    public void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(this, ProfilerSnapshot.class);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/profiling/src/org/graalvm/visualvm/profiling/snapshot/ProfilerSnapshotsSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.profiling.snapshot;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.snapshot.RegisteredSnapshotCategories;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport java.io.File;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class ProfilerSnapshotsSupport {\n\n    private static ProfilerSnapshotsSupport INSTANCE;\n\n    private ProfilerSnapshotCategory category;\n    private ProfilerSnapshotProvider profilerSnapshotsProvider;\n\n\n    public static synchronized ProfilerSnapshotsSupport getInstance() {\n        if (INSTANCE == null) INSTANCE = new ProfilerSnapshotsSupport();\n        return INSTANCE;\n    }\n\n\n    public void createSnapshot(File loadedSnapshot, Application application,\n                               boolean openView) {\n        profilerSnapshotsProvider.createSnapshot(loadedSnapshot, application, openView);\n    }\n\n\n    SnapshotCategory<ProfilerSnapshot> getCategory() {\n        return category;\n    }\n\n\n    private ProfilerSnapshotsSupport() {\n        DataSourceDescriptorFactory.getDefault().registerProvider(\n                new ProfilerSnapshotDescriptorProvider());\n\n        new ProfilerSnapshotViewProvider().initialize();\n\n        category = new ProfilerSnapshotCategory();\n        RegisteredSnapshotCategories.sharedInstance().registerCategory(category);\n\n        profilerSnapshotsProvider = new ProfilerSnapshotProvider();\n        profilerSnapshotsProvider.initialize();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sa/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.sa\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.sa.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/sa/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.sa/2\nOpenIDE-Module-Install: org/graalvm/visualvm/sa/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/sa/Bundle.properties\nOpenIDE-Module-Provides: org.graalvm.visualvm.sa\nOpenIDE-Module-Specification-Version: 2.0\n\n"
  },
  {
    "path": "visualvm/sa/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.sa-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/sa/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=78423aab\nbuild.xml.script.CRC32=b201d39d\nbuild.xml.stylesheet.CRC32=05353c81\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=78423aab\nnbproject/build-impl.xml.script.CRC32=58174c80\nnbproject/build-impl.xml.stylesheet.CRC32=3f8b4615\n"
  },
  {
    "path": "visualvm/sa/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nmodule.javadoc.packages=org.graalvm.visualvm.sa.*\n\n"
  },
  {
    "path": "visualvm/sa/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.sa</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.coredump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/sa/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/sa/src/org/graalvm/visualvm/sa/Agent.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sa;\n\nimport java.io.File;\nimport java.lang.reflect.InvocationTargetException;\nimport java.net.MalformedURLException;\nimport java.util.Map;\nimport java.util.HashMap;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass Agent {\n\n    private static Map<File,Agent> agentMap = new HashMap<>();\n    \n    static Agent getAgent(File jdkHome,File saLibFile) throws ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException  {\n        synchronized (agentMap) {\n            Agent agent = agentMap.get(saLibFile);\n            if (agent == null) {\n                agent = new Agent(jdkHome,saLibFile);\n                agentMap.put(saLibFile,agent);\n            }\n            return agent;\n        }\n    }\n    \n    private SAWrapper saClassLoader;\n    private final SAObject hotspotAgent;\n    private VM vm;\n    private Arguments args;\n\n    private Agent(File jdkHome,File saLibFile) throws ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException {\n        saClassLoader = new SAWrapper(jdkHome,saLibFile);\n        hotspotAgent = new SAObject(saClassLoader.HotSpotAgent().newInstance());\n    }\n\n    boolean attach(int pid) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {\n        hotspotAgent.invoke(\"attach\",pid);  // NOI18N\n        return true;\n    }\n\n    boolean attach(String executable,String coredump) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {\n        hotspotAgent.invoke(\"attach\",executable,coredump);  // NOI18N\n        return true;\n    }\n    \n    boolean attach(String remoteServer) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {\n        hotspotAgent.invoke(\"attach\",remoteServer); // NOI18N\n        return true;\n    }\n    \n    void detach() throws IllegalAccessException, InvocationTargetException {\n        hotspotAgent.invoke(\"detach\");  // NOI18N\n    }\n\n    VM getVM() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {\n        if (vm == null) {\n            Class<?> vmClass = saClassLoader.VM();\n            Object saVM = vmClass.getMethod(\"getVM\").invoke(null);  // NOI18N\n            vm = new VM(saVM);\n        }\n        return vm;\n    }\n    \n    Arguments getArguments() throws ClassNotFoundException {\n        if (args == null) {\n            args = new Arguments(saClassLoader.Arguments());\n        }\n        return args;\n    }\n    \n    SAObject getHeapHprofBinWriter() throws ClassNotFoundException, InstantiationException, IllegalAccessException {\n        return new SAObject(saClassLoader.HeapHprofBinWriter().newInstance());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sa/src/org/graalvm/visualvm/sa/Arguments.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sa;\n\nimport java.lang.reflect.InvocationTargetException;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass Arguments {\n\n    private final Class<?> arguments;\n\n    Arguments(Class<?> args) {\n        arguments = args;\n    }\n\n    String getJVMFlags() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {\n        return (String) arguments.getMethod(\"getJVMFlags\").invoke(null);    // NOI18N\n    }\n\n    String getJVMArgs()  throws NoSuchMethodException, IllegalAccessException, InvocationTargetException{\n        return (String) arguments.getMethod(\"getJVMArgs\").invoke(null); // NOI18N\n    }\n\n    String getJavaCommand()  throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {\n        return (String) arguments.getMethod(\"getJavaCommand\").invoke(null); // NOI18N\n    }\n\n\n}\n"
  },
  {
    "path": "visualvm/sa/src/org/graalvm/visualvm/sa/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-SA\n"
  },
  {
    "path": "visualvm/sa/src/org/graalvm/visualvm/sa/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sa;\n\nimport org.graalvm.visualvm.tools.sa.SaModelFactory;\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\npublic class Installer extends ModuleInstall {\n    \n    public void restored() {\n        SaModelFactory.getDefault().registerProvider(new SaModelProvider());\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sa/src/org/graalvm/visualvm/sa/SAObject.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sa;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass SAObject {\n    final Object instance;\n    Map<String,List<Method>> methodCache;\n    private static Map<Class<?>,Class<?>> primitiveTypes;\n\n    static {\n        primitiveTypes = new HashMap<>();\n        primitiveTypes.put(Integer.class,Integer.TYPE);\n    }\n\n    SAObject(Object i) {\n        instance = i;\n        if (i != null) {\n            methodCache = new HashMap<>();\n            Method[] methods = i.getClass().getMethods();\n            for (Method method : methods) {\n                String name = method.getName();\n                int pars = method.getParameterTypes().length;\n                String id = methodId(name,pars);\n                List<Method> mlist = Collections.singletonList(method);\n                List<Method> oldlist = methodCache.put(id,mlist);\n                if (oldlist != null) {\n                    List<Method> unitedList = new ArrayList<>(mlist);\n                    unitedList.addAll(oldlist);\n                    methodCache.put(id,unitedList);\n                }\n            }\n        }\n    }\n    \n    boolean isNull() {\n        return instance == null;\n    }\n    \n    Object invoke(String methodName,Object... parameters) throws IllegalAccessException, InvocationTargetException {\n        String mid = methodId(methodName,parameters.length);\n        List<Method> methods = methodCache.get(mid);\n        Method method = null;\n        \n        if (methods == null) {\n            throw new IllegalAccessException(\"No method \"+mid); // NOI18N\n        }\n        if (methods.size()==1) {\n            method = methods.get(0);\n        } else {\n            Class<?>[] parClasses = new Class<?>[parameters.length];\n            \n            for (int i = 0; i < parameters.length; i++) {\n                Class<?> cl = parameters[i].getClass();\n                if (primitiveTypes.containsKey(cl)) {\n                    cl = primitiveTypes.get(cl);\n                }\n                parClasses[i] = cl;\n            }\n            for (Method m : methods) {\n                if (Arrays.deepEquals(m.getParameterTypes(),parClasses)) {\n                    method = m;\n                    break;\n                }\n            }\n        }\n        if (method == null) {\n            throw new IllegalArgumentException(instance+\" \"+methodName+\" \"+Arrays.toString(parameters));\n        }\n        return method.invoke(instance,parameters);\n    }\n    \n    SAObject invokeSA(String methodName,Object... parameters) throws IllegalAccessException, InvocationTargetException {\n        return new SAObject(invoke(methodName,parameters));\n    }\n    \n    private static String methodId(String name,int pars) {\n        return name.concat(\"#\").concat(Integer.toString(pars)); // NOI18N\n    }\n    \n    public String toString() {\n        if (instance != null) {\n            return instance.toString();\n        }\n        return \"<null>\";    // NOI18N\n    }\n\n    public int hashCode() {\n        if (instance == null)\n            return 0;\n        return instance.hashCode();\n    }\n\n    public boolean equals(Object obj) {\n        if (obj instanceof SAObject) {\n            SAObject saobj = (SAObject) obj;\n            if (instance == null) {\n                return saobj.instance == null;\n            }\n            return instance.equals(saobj.instance);\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/sa/src/org/graalvm/visualvm/sa/SAWrapper.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sa;\n\nimport java.io.File;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.util.logging.Logger;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass SAWrapper {\n    private static final Logger LOGGER = Logger.getLogger(SAWrapper.class.getName());\n    \n    URLClassLoader loader;\n    File libraryPath;\n    \n    SAWrapper(File jdkHome, File saLibFile) throws MalformedURLException {\n        // By default, SA agent classes prefer dbx debugger to proc debugger\n        // and Windows process debugger to windbg debugger. SA expects\n        // special properties to be set to choose other debuggers.\n        // We will set those here before attaching to SA agent.\n        System.setProperty(\"sun.jvm.hotspot.debugger.useProcDebugger\", \"true\"); // NOI18N\n        System.setProperty(\"sun.jvm.hotspot.debugger.useWindbgDebugger\", \"true\");   // NOI18N\n        URL saLibUrl = saLibFile.toURI().toURL();\n        URL[] saLibUrls;\n        if (saLibFile.getName().endsWith(\".jmod\")) {        // NOI18N\n            URL jmodUrl = new URL(\"jar\", \"\", saLibUrl+\"!/classes/\");     // NOI18N\n            saLibUrls = new URL[]{jmodUrl};\n            libraryPath = new File(jdkHome, \"lib/\");   // NOI18N\n        } else {\n            saLibUrls = new URL[]{saLibUrl};\n            String osArch = System.getProperty(\"os.arch\");  // NOI18N\n            if (\"x86\".equals(osArch)) {\n                osArch = \"i386\";\n            }\n            libraryPath = new File(jdkHome, \"jre/lib/\" + osArch);   // NOI18N\n        }\n        LOGGER.fine(\"Path \" + libraryPath.getAbsolutePath());   // NOI18N\n        loader = new URLClassLoader(saLibUrls) {\n            @Override\n            protected String findLibrary(String libname) {\n                String name = System.mapLibraryName(libname);\n                File library = new File(libraryPath, name);\n                LOGGER.fine(\"Library \" + library.getAbsolutePath());    // NOI18N\n                if (library.exists() && library.canRead()) {\n                    return library.getAbsolutePath();\n                }\n                return super.findLibrary(libname);\n            }\n        };\n    }\n    \n    Class<?> classForName(String name) throws ClassNotFoundException {\n        return Class.forName(name,true,loader);\n    }\n    \n    Class<?> Tool() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.tools.Tool\");  // NOI18N\n    }\n    \n    Class<?> VM() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.runtime.VM\");  // NOI18N\n    }\n    \n    Class<?> HotSpotAgent() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.HotSpotAgent\");    // NOI18N\n    }\n    \n    Class<?> HeapHprofBinWriter() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.utilities.HeapHprofBinWriter\");    // NOI18N\n    }\n    \n    Class<?> Arguments() throws ClassNotFoundException {\n        return classForName(\"sun.jvm.hotspot.runtime.Arguments\");   // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/sa/src/org/graalvm/visualvm/sa/SaModelImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sa;\n\nimport org.graalvm.visualvm.tools.sa.SaModel;\nimport java.io.File;\nimport java.lang.reflect.InvocationTargetException;\nimport java.net.MalformedURLException;\nimport java.util.Properties;\nimport org.openide.ErrorManager;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class SaModelImpl extends SaModel {\n    private final Agent agent;\n    private int pid;\n    String executable;\n    String core;\n    private Properties sysProp;\n    private String jvmFlags;\n    private String jvmArgs;\n    private String commandLine;\n    \n    SaModelImpl(File jdkHome,File saLib,int id) throws ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException, InvocationTargetException, NoSuchMethodException {\n        agent = Agent.getAgent(jdkHome,saLib);\n        pid = id;\n        readData();\n    }\n    \n    SaModelImpl(File jdkHome,File saLib,File execFile,File coreFile) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, MalformedURLException, NoSuchMethodException {\n        agent = Agent.getAgent(jdkHome,saLib);\n        executable = execFile.getAbsolutePath();\n        core = coreFile.getAbsolutePath();\n        readData();\n    }\n    \n    public Properties getSystemProperties() {\n        return sysProp;\n    }\n    \n    public boolean takeHeapDump(String file){\n        try {\n            synchronized (agent) {\n                try {\n                    if (attach()) {\n                        SAObject hprofWrite = agent.getHeapHprofBinWriter();\n                        hprofWrite.invoke(\"write\",file);    // NOI18N\n                        return true;\n                    }\n                } finally {\n                    agent.detach();\n                }\n            }\n        } catch (Exception ex) {\n            Throwable e = ex.getCause();\n            ErrorManager.getDefault().notify(e == null ? ex : e);\n        }\n        return false;\n    }\n    \n    public String takeThreadDump(){\n        try {\n            synchronized (agent) {\n                try {\n                    if (attach()) {\n                        return new StackTrace(agent.getVM()).getStackTrace();\n                    }\n                } finally {\n                    agent.detach();\n                }\n            }\n        } catch (Exception ex) {\n            Throwable e = ex.getCause();\n            ErrorManager.getDefault().notify(e == null ? ex : e);\n        }\n        return null;\n    }\n    \n    public String getJvmFlags() {\n        return jvmFlags;\n    }\n    \n    public String getJvmArgs() {\n        return jvmArgs;\n    }\n    \n    public String getJavaCommand() {\n        return commandLine;\n    }\n    \n    private boolean attach() throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {\n        if (core == null) {\n            return agent.attach(pid);\n        }\n        return agent.attach(executable,core);\n    }\n    \n    private void readData() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {\n        synchronized (agent) {\n            try {\n                if (attach()) {\n                    Arguments args = agent.getArguments();\n                    jvmFlags = args.getJVMFlags();\n                    jvmArgs = args.getJVMArgs();\n                    commandLine = args.getJavaCommand();\n                    sysProp = (Properties)agent.getVM().getSystemProperties().clone();\n                }\n            } finally {\n                agent.detach();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/sa/src/org/graalvm/visualvm/sa/SaModelProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sa;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModel;\nimport org.graalvm.visualvm.tools.jvmstat.JvmJvmstatModelFactory;\nimport org.graalvm.visualvm.tools.sa.SaModel;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.openide.util.Utilities;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class SaModelProvider extends AbstractModelProvider<SaModel, DataSource>  {\n    private static final Logger LOGGER = Logger.getLogger(SaModelProvider.class.getName());\n    \n    private static final String SA_JAR = \"lib/sa-jdi.jar\";  // NOI18N\n    private static final String SA_JMOD = \"jmods/jdk.hotspot.agent.jmod\";  // NOI18N\n\n    SaModelProvider() {\n    }\n    \n    public SaModel createModelFor(DataSource ds) {\n        if (ds instanceof Application) {\n            Application app = (Application) ds;\n            if (app.isLocalApplication()) {\n                JvmJvmstatModel jvmstat = JvmJvmstatModelFactory.getJvmstatModelFor(app);\n            \n                if (jvmstat == null) {\n                    return null;\n                }\n                if (Utilities.isWindows()) {\n                    // on Windows, SA can only attach to the process of the same\n                    // architecture ( 32bit / 64bit )\n                    Boolean this64bitArch = is64BitArchitecture();\n                    Boolean app64bitArch = is64BitArchitecture(jvmstat);\n                    if (this64bitArch != null && app64bitArch != null) {\n                        if (!this64bitArch.equals(app64bitArch)) {\n                            return null;\n                        }\n                    }\n                }\n                File jdkHome = getJdkHome(jvmstat);\n                File saLib = getSaJar(jdkHome);\n\n                if (saLib == null) {\n                    saLib = getSaJmod(jdkHome);\n                    if (saLib == null) {\n                        return null;\n                    }\n                }\n                try {\n                    return new SaModelImpl(jdkHome,saLib,app.getPid());\n                } catch (Exception ex) {\n                    LOGGER.log(Level.INFO, \"Error getting SA agent\", ex);   // NOI18N\n                } catch (LinkageError ex) {\n                    LOGGER.log(Level.INFO, \"Error getting SA agent\", ex);   // NOI18N\n                }\n                return null;\n            }\n        } else if (ds instanceof CoreDump) {\n            CoreDump coredump = (CoreDump) ds;\n            File executable = new File(coredump.getExecutable());\n            File coreFile = coredump.getFile();\n            if (executable.exists() && coreFile.exists()) {\n                File jdkHome = executable.getParentFile().getParentFile();\n                File saLib = getSaJar(jdkHome);\n                \n                if (saLib == null) {\n                    saLib = getSaJmod(jdkHome);\n                    if (saLib == null) {\n                        return null;\n                    }\n                }\n                try {\n                    return new SaModelImpl(jdkHome,saLib,executable,coreFile);\n                } catch (Exception ex) {\n                    LOGGER.log(Level.INFO, \"Unable to retrieve SA agent\", ex);  // NOI18N\n                }\n                return null;\n            }\n        }\n        return null;\n    }\n\n    private File getJdkHome(final JvmJvmstatModel jvmstat) {\n        String javaHome = jvmstat.getJavaHome();\n        if (javaHome != null) {\n            File jdkHome = new File(javaHome);\n            if (\"jre\".equals(jdkHome.getName())) {  // NOI18N\n               jdkHome = jdkHome.getParentFile();\n            }\n            return jdkHome;\n        }\n        return null;\n    }\n    \n    private static File getJar(File jdkHome, String saName) {\n        if (jdkHome != null) {\n            File saJar = new File(jdkHome,saName);\n            try {\n                if (saJar.exists()) {\n                    return saJar.getCanonicalFile();\n                }\n            } catch (IOException ex) {\n                LOGGER.log(Level.INFO, saJar.getPath(), ex);\n            }\n        }\n        return null;\n    }\n\n    private static File getSaJar(File jdkHome) {\n        return getJar(jdkHome, SA_JAR);\n    }\n\n    private static File getSaJmod(File jdkHome) {\n        return getJar(jdkHome, SA_JMOD);\n    }\n\n    private static Boolean is64BitArchitecture(JvmJvmstatModel jvmstat) {\n        String name = jvmstat.getVmName();\n        if (name != null) {\n            return name.toLowerCase().contains(\"64-bit\");   // NOI18N\n        }\n        return null;\n    }\n    \n    private static Boolean is64BitArchitecture() {\n        String thisArch = System.getProperty(\"sun.arch.data.model\");    // NOI18N\n        if (thisArch != null) {\n            return Boolean.valueOf(\"64\".equals(thisArch));  // NOI18N\n        }\n        return null;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sa/src/org/graalvm/visualvm/sa/StackTrace.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sa;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.PrintStream;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass StackTrace {\n\n    private VM vm;\n    private SAObject heap;\n    private SAObject objectClass;\n\n    StackTrace(VM v) throws IllegalAccessException, InvocationTargetException {\n        vm = v;\n        heap = vm.getObjectHeap();\n        objectClass = vm.getSystemDictionary().invokeSA(\"getObjectKlass\");  // NOI18N\n    }\n\n    public String getStackTrace() throws IllegalAccessException, InvocationTargetException {\n        ByteArrayOutputStream data = new ByteArrayOutputStream(4096);\n        PrintStream out = new PrintStream(data);\n        SAObject threads = vm.getThreads();\n        SAObject curThread = threads.invokeSA(\"first\"); // NOI18N\n\n        for (;!curThread.isNull();curThread=curThread.invokeSA(\"next\")) {   // NOI18N\n            try {\n                Boolean isJavaThread = (Boolean) curThread.invoke(\"isJavaThread\");  // NOI18N\n                if (!isJavaThread.booleanValue()) {\n                    out.print(\"VM \");   // NOI18N\n                }\n                out.print(\"Thread \");   // NOI18N\n                curThread.invoke(\"printThreadIDOn\",out);    // NOI18N\n                out.print(\" \\\"\"+curThread.invoke(\"getThreadName\")+\"\\\"\");    // NOI18N\n                out.print(\": (state = \");   // NOI18N\n                out.print(curThread.invoke(\"getThreadState\"));  // NOI18N\n                out.println(\")\");\n                if (isJavaThread.booleanValue()) { // Java thread\n                    SAObject javaFrame = curThread.invokeSA(\"getLastJavaVFrameDbg\");    // NOI18N\n                    Object waitingToLockMonitor = curThread.invoke(\"getCurrentPendingMonitor\"); // NOI18N\n                    boolean objectWaitFrame = isJavaLangObjectWaitFrame(javaFrame);\n                    for (;!javaFrame.isNull();javaFrame=javaFrame.invokeSA(\"javaSender\")) { // NOI18N\n                        printJavaFrame(out, javaFrame);\n                        printMonitors(out, javaFrame, waitingToLockMonitor, objectWaitFrame);\n                        waitingToLockMonitor = null;\n                        objectWaitFrame = false;\n                    }\n                }\n            } catch (Exception ex) {\n                out.println(\"\\t-- Error occurred during stack walking\");\n                Logger.getLogger(StackTrace.class.getName()).log(Level.INFO,\"getStackTrace\",ex);\n            }\n            out.println();\n        }\n        return data.toString();\n    }\n    \n    private boolean isJavaLangObjectWaitFrame(SAObject javaFrame) throws IllegalAccessException, InvocationTargetException {\n        if (!javaFrame.isNull()) {\n            SAObject method = javaFrame.invokeSA(\"getMethod\");  // NOI18N\n            SAObject klass = method.invokeSA(\"getMethodHolder\");    // NOI18N\n            Boolean isNative = (Boolean) method.invoke(\"isNative\"); // NOI18N\n            if (objectClass.equals(klass) && isNative.booleanValue()) {\n                if (\"wait\".equals(method.invokeSA(\"getName\").invoke(\"asString\"))) { // NOI18N\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n    \n    private void printMonitors(\n            final PrintStream out, final SAObject javaFrame,\n            Object waitingToLockMonitor, boolean objectWaitFrame)\n            throws IllegalAccessException, InvocationTargetException {\n        if (objectWaitFrame) {\n            SAObject stackValueCollection = javaFrame.invokeSA(\"getLocals\");    // NOI18N\n            Boolean isEmpty = (Boolean) stackValueCollection.invoke(\"isEmpty\"); // NOI18N\n            if (!isEmpty.booleanValue()) {\n                Object oopHandle = stackValueCollection.invoke(\"oopHandleAt\", 0);   // NOI18N\n                printMonitor(out, oopHandle, \"waiting on\"); // NOI18N\n            }\n        }\n        try {\n            List mList = (List) javaFrame.invoke(\"getMonitors\");    // NOI18N\n            Object[] monitors = mList.toArray();\n            for (int i = monitors.length - 1; i >= 0; i--) {\n                SAObject monitorInfo = new SAObject(monitors[i]);\n                Object ownerHandle = monitorInfo.invoke(\"owner\");   // NOI18N\n                if (ownerHandle != null) {\n                    String state = \"locked\";    // NOI18N\n                    if (waitingToLockMonitor != null) {\n                        Object objectHandle = new SAObject(waitingToLockMonitor).invoke(\"object\");  // NOI18N\n                        if (objectHandle.equals(ownerHandle)) {\n                            state = \"waiting to lock\";  // NOI18N\n                        }\n                    }\n                    printMonitor(out, ownerHandle, state);\n                }\n            }\n        } catch (Exception e) {\n            // Ignore...\n        }\n    }\n\n    private void printMonitor(\n            final PrintStream out,\n            final Object ownerHandle,\n            final String state) {\n        try {\n            StringBuilder sb = new StringBuilder();\n            sb.append(\"\\t- \" + state + \" <\" + ownerHandle + \"> \");  // NOI18N\n            printOop(sb, ownerHandle);\n            out.println(sb.toString());\n        } catch (Exception e) {\n            // Ignore...\n        }\n    }\n\n    private void printOop(StringBuilder sb, Object oopHandle)\n            throws IllegalAccessException, InvocationTargetException {\n        SAObject oop = heap.invokeSA(\"newOop\", oopHandle);  // NOI18N\n        if (!oop.isNull()) {\n            sb.append(\"(a \");   // NOI18N\n            String monitorClassName = (String) oop.invokeSA(\"getKlass\").invokeSA(\"getName\").invoke(\"asString\"); // NOI18N\n            sb.append(monitorClassName.replace('/', '.'));\n            sb.append(\")\");\n        } else {\n            sb.append(\"(Raw Monitor)\"); // NOI18N\n        }\n    }\n    \n    private void printJavaFrame(final PrintStream out, final SAObject javaFrame) throws IllegalAccessException, InvocationTargetException {\n        SAObject method = javaFrame.invokeSA(\"getMethod\");  // NOI18N\n        \n        out.print(\"\\tat \"); // NOI18N\n        SAObject klass = method.invokeSA(\"getMethodHolder\");    // NOI18N\n        String className = (String) klass.invokeSA(\"getName\").invoke(\"asString\");   // NOI18N\n        out.print(className.replace('/','.'));\n        out.print(\".\");\n        out.print(method.invokeSA(\"getName\").invoke(\"asString\"));   // NOI18N\n        Integer bci = (Integer) javaFrame.invoke(\"getBCI\"); // NOI18N\n        out.print(\"(\");\n        if (((Boolean)method.invoke(\"isNative\")).booleanValue()) {  // NOI18N\n            out.print(\"Native Method\"); // NOI18N\n        } else {\n            Integer lineNumber = (Integer) method.invoke(\"getLineNumberFromBCI\",bci);   // NOI18N\n            SAObject sourceName = klass.invokeSA(\"getSourceFileName\");  // NOI18N\n            \n            if (lineNumber.intValue()!=-1  && !sourceName.isNull()) {\n                out.print(sourceName.invoke(\"asString\"));   // NOI18N\n                out.print(\":\");\n                out.print(lineNumber);\n            } else {\n                out.print(\"bci=\");  // NOI18N\n                out.print(bci);\n            }\n        }\n        out.println(\")\");\n    }\n}\n"
  },
  {
    "path": "visualvm/sa/src/org/graalvm/visualvm/sa/VM.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sa;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.Properties;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nclass VM {\n\n    private final SAObject vm;\n\n    VM(Object saVM) {\n        vm = new SAObject(saVM);\n    }\n\n    Properties getSystemProperties() throws IllegalAccessException, InvocationTargetException {\n        return (Properties) vm.invoke(\"getSystemProperties\");   // NOI18N\n    }\n\n    SAObject getThreads() throws IllegalAccessException, InvocationTargetException {\n        return vm.invokeSA(\"getThreads\");   // NOI18N\n    }\n\n    SAObject getObjectHeap() throws IllegalAccessException, InvocationTargetException {\n        return vm.invokeSA(\"getObjectHeap\");    // NOI18N\n    }\n\n    SAObject getSystemDictionary() throws IllegalAccessException, InvocationTargetException {\n        return vm.invokeSA(\"getSystemDictionary\");  // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sampler/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.sampler\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.sampler.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/sampler/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.sampler/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/sampler/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.3\nOpenIDE-Module-Layer: org/graalvm/visualvm/sampler/resources/layer.xml\nOpenIDE-Module-Install: org/graalvm/visualvm/sampler/Installer.class\n"
  },
  {
    "path": "visualvm/sampler/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.sampler-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/sampler/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=20861fe1\nbuild.xml.script.CRC32=8a00031d\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=20861fe1\nnbproject/build-impl.xml.script.CRC32=584e6d59\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/sampler/nbproject/project.properties",
    "content": "javac.source=1.8\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Tomas Hurka, Jiri Sedlacek\nmodule.javadoc.packages=org.graalvm.visualvm.sampler.*\n"
  },
  {
    "path": "visualvm/sampler/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.sampler</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.coredump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.heapdump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.common</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.profiling</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.threaddump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress.nb</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.options.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.69</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.sendopts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.43</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.awt</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.92</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.15.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.17.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.11</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/sampler/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/AbstractSamplerSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler;\n\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport java.util.Timer;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class AbstractSamplerSupport {\n\n    public abstract DataViewComponent.DetailsView[] getDetailsView();\n\n    public abstract boolean startSampling(ProfilingSettings settings, int samplingRate, int refreshRate);\n    \n    public abstract void takeSnapshot(boolean openView);\n\n    public abstract void stopSampling();\n\n    public abstract void terminate();\n\n\n    protected abstract Timer getTimer();\n    \n    \n    protected final void checkCPUSamplingRate(int samplingRate) {\n        if (samplingRate < 20)\n            ProfilerDialogs.displayWarningDNSA(NbBundle.getMessage(AbstractSamplerSupport.class, \"MSG_High_Sampling_Frequency\"), // NOI18N\n                                               NbBundle.getMessage(AbstractSamplerSupport.class, \"CAP_High_Sampling_Frequency\"), // NOI18N\n                                               null,\n                                               \"org.graalvm.visualvm.sampler.AbstractSamplerSupport.checkCPUSamplingRate\", // NOI18N\n                                               false);\n    }\n\n\n    public static abstract class Refresher {\n        private static final long REFRESH_THRESHOLD = 100;\n        private long lastRefresh;\n\n        public synchronized final void refresh() {\n            if (checkRefresh()) {\n                long currentTime = System.currentTimeMillis();\n                if (currentTime - lastRefresh >= REFRESH_THRESHOLD) {\n                    lastRefresh = currentTime;\n                    doRefresh();\n                }\n            }\n        }\n\n        public abstract void setRefreshRate(int refreshRate);\n        public abstract int getRefreshRate();\n\n        protected abstract boolean checkRefresh();\n        protected abstract void doRefresh();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/ApplicationSamplerView.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport javax.swing.ImageIcon;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ApplicationSamplerView extends DataSourceView {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/sampler/resources/sampler.png\"; // NOI18N\n\n    private SamplerImpl sampler;\n    private SamplerArguments.Request startRequest = SamplerArguments.Request.NONE;\n    private SamplerParameters settingsRequest;\n\n    private ApplicationListener applicationListener;\n\n\n    ApplicationSamplerView(Application application) {\n        super(application, NbBundle.getMessage(ApplicationSamplerView.class, \"LBL_Sampler\"), // NOI18N\n              new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 35, false);\n\n    }\n    \n    \n    void startCPU(SamplerParameters settings) {\n        if (sampler != null) {\n            sampler.startCPU(settings);\n        } else {\n            startRequest = SamplerArguments.Request.CPU;\n            settingsRequest = settings;\n        }\n    }\n    \n    void startMemory(SamplerParameters settings) {\n        if (sampler != null) {\n            sampler.startMemory(settings);\n        } else {\n            startRequest = SamplerArguments.Request.MEMORY;\n            settingsRequest = settings;\n        }\n    }\n    \n    void takeSnapshot(boolean openView) {\n        if (sampler != null) sampler.takeSnapshot(openView);\n    }\n    \n    void stop() {\n        if (sampler != null) sampler.stop();\n    }\n\n\n    protected void willBeAdded() {\n        Application application = (Application)getDataSource();\n\n        sampler = new SamplerImpl(application, startRequest, settingsRequest);\n\n        applicationListener = new ApplicationListener() {\n            public void dataRemoved(Application application) { applicationFinished(); }\n        };\n        application.notifyWhenRemoved(applicationListener);\n        application.addPropertyChangeListener(Stateful.PROPERTY_STATE, applicationListener);\n    }\n\n    protected void removed() {\n        sampler.removed();\n        cleanup();\n    }\n\n    private void applicationFinished() {\n        sampler.applicationFinished();\n        cleanup();\n    }\n\n    private synchronized void cleanup() {\n        Application application = (Application)getDataSource();\n\n        if (applicationListener != null)\n            application.removePropertyChangeListener(Stateful.PROPERTY_STATE,\n                                                     applicationListener);\n\n        applicationListener = null;\n    }\n\n    \n    protected DataViewComponent createComponent() {\n        DataViewComponent dvc = new DataViewComponent(\n                sampler.getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(false));\n\n        sampler.setDataViewComponent(dvc);\n\n        return dvc;\n    }\n\n\n    private static abstract class ApplicationListener\n            implements DataRemovedListener<Application>, PropertyChangeListener {\n        public abstract void dataRemoved(Application application);\n        public void propertyChange(PropertyChangeEvent evt) { dataRemoved(null); }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/ApplicationSamplerViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ApplicationSamplerViewProvider extends DataSourceViewProvider<Application>{\n    \n    protected boolean supportsViewFor(Application application) {\n        return SamplerSupport.getInstance().supportsProfiling(application);\n    }\n\n    protected DataSourceView createView(Application application) {\n        return new ApplicationSamplerView(application);\n    }\n    \n    \n    DataSourceView view(Application application) {\n        return super.getView(application);\n    }\n    \n\n    void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(this, Application.class);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Long-Description=\\\n    This module implements a sampling CPU and memory profiler (in contrast to the Profiler which uses instrumentation).\\\n    <BR><BR>\\nCPU profiling requires a JMX connection to the monitored application, once correctly set up you can profile both local and remote applications.\\\n    <BR><BR>\\nMemory profiling requires Attach API, so only local applications running on JDK 6+ are supported.\nOpenIDE-Module-Name=VisualVM-Sampler\nOpenIDE-Module-Short-Description=Sampling CPU and memory profiler\n\nLBL_Sampler=Sampler\n\nLBL_Sample=Sample\\:\nLBL_Profile=Profile\\:\n\nLBL_Cpu=CPU\n\nLBL_Memory=Memory\n\nLBL_Stop=Stop\n\nLBL_Status=Status:\n\nMSG_Sample=&Sample\n\nDESCR_Sample=Analysis by sampling profiler\n\nLBL_Settings=Settings\n\nLBL_Cpu_settings=CPU settings\n\nLBL_Memory_settings=Memory settings\n\nMSG_Not_Initialized_Cpu=Not initialized. Press the 'CPU' button to initialize.\n\nMSG_Not_Initialized_Memory=Not initialized. Press the 'Memory' button to initialize.\n\nMSG_Checking_Availability=Checking availability...\n\nLBL_Information=Information\n\nLBL_Summary=Summary\n\nLBL_Undefined=<undefined>\n\nMSG_Application_terminated=application terminated\n\nMSG_Sampling_inactive=sampling inactive\n\nMSG_Cpu_progress=CPU sampling in progress\n\nMSG_Memory_progress=memory sampling in progress\n\nLBL_Refreshing=refreshing...\n\nLBL_Cpu_samples=CPU samples\n\nLBL_Cpu_sampling=<b>CPU sampling:</b><br>\n\nLBL_Memory_samples=Memory samples\n\nLBL_Memory_sampling=<br><br><b>Memory sampling:</b><br>\n\nLBL_Initialization_Automatically=automatically\n\nLBL_Initialization_Manually=manually\n\nLBL_Initialization_Configuration=<br><br><br>Sampler configured to initialize {0}. <a href='#'>Click to change.</a>\n\nMSG_No_save_data_cpu=<html><b>No data to save</b><br><br>Make sure the application performs some code<br>and the selected filter is not filtering out the calls.</html>\n\nMSG_No_save_data_memory=<html><b>No data to save</b><br><br>Make sure the application performs some code.</html>\n\nMSG_Thread_dump_unsupported=thread dump not supported\n\nMSG_ThreadCPU_unsupported=thread CPU time not supported\n\nMSG_Available=Available.\n\nMSG_Available_details=Available ({0}).\n\nMSG_Available_details2=Available ({0}, {1}).\n\nMSG_Available_details3=Available ({0}, {1}, {2}).\n\nMSG_Press_cpu=Press the 'CPU' button to start collecting performance data.\n\nMSG_Press_mem=Press the 'Memory' button to start collecting memory data.\n\nMSG_Unavailable=Not available.\n\nMSG_Unavailable_remote=Not available. Remote sampling is only supported for Java 8+ applications.\n\nMSG_Unavailable_connect_jdk=Not available. Cannot connect to target application. Make sure the application is running on a supported Java 6+.\n\nMSG_Unavailable_connect_log=Not available. Cannot connect to target application. Check the VisualVM logfile ({0}).\n\nMSG_Unavailable_read_log=Not available. Failed to read objects in target application. Check the VisualVM logfile ({0}).\n\nMSG_Gc_unsupported=perform GC not supported\n\nMSG_HeapDump_unsupported=heap dump not supported\n\nMSG_ThreadMemory_unsupported=thread memory allocation not supported\n\nMSG_Incorrect_CPU_settings=Provided CPU settings are invalid.\n\nMSG_Incorrect_Memory_settings=Provided Memory settings are invalid.\n\nMSG_High_Sampling_Frequency=<html><br><b>Configured sampling frequency is high.</b><br><br>This may affect performance of the target application<br>and bias the collected results.<br><br></html>\n\nCAP_High_Sampling_Frequency=High Sampling Frequency\n\nArgument_StartCpu_ShortDescr=start CPU sampler for the provided process\n\nArgument_StartMemory_ShortDescr=start Memory sampler for the provided process\n\nArgument_Snapshot_ShortDescr=take sampler snapshot for the provided process\n\nArgument_Stop_ShortDescr=stop sampling the provided process\n\nMSG_NO_APP_PID = Cannot find application with pid {0}.\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler;\n\nimport org.openide.modules.ModuleInstall;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class Installer extends ModuleInstall {\n\n    public void restored() {\n        SamplerSupport.getInstance();\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/SampleApplicationAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.sampler;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport java.awt.event.ActionEvent;\nimport org.openide.util.NbBundle;\n\n    \n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class SampleApplicationAction extends SingleDataSourceAction<Application> {\n    \n    private static SampleApplicationAction instance;\n    \n    public static synchronized SampleApplicationAction instance() {\n        if (instance == null) \n            instance = new SampleApplicationAction();\n        return instance;\n    }\n        \n    protected void actionPerformed(Application application, ActionEvent actionEvent) {\n        SamplerSupport.getInstance().selectSamplerView(application);\n    }\n    \n    protected boolean isEnabled(Application application) {\n        return SamplerSupport.getInstance().supportsProfiling(application);\n    }\n        \n    private SampleApplicationAction() {\n        super(Application.class);\n        putValue(NAME, NbBundle.getMessage(SampleApplicationAction.class, \"MSG_Sample\")); // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(SampleApplicationAction.class, \"DESCR_Sample\"));    // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/SamplerArguments.java",
    "content": "/*\n * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler;\n\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.ApplicationFinder;\nimport org.netbeans.api.sendopts.CommandException;\nimport org.netbeans.spi.sendopts.Env;\nimport org.netbeans.spi.sendopts.Option;\nimport org.netbeans.spi.sendopts.OptionProcessor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=OptionProcessor.class)\npublic final class SamplerArguments extends OptionProcessor {\n    \n    private static final String START_CPU_LONG_NAME = \"start-cpu-sampler\";      // NOI18N\n    private static final Option START_CPU_ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, START_CPU_LONG_NAME), \"org.graalvm.visualvm.sampler.Bundle\", \"Argument_StartCpu_ShortDescr\"); // NOI18N\n    private static final String START_MEMORY_LONG_NAME = \"start-memory-sampler\";// NOI18N\n    private static final Option START_MEMORY_ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, START_MEMORY_LONG_NAME), \"org.graalvm.visualvm.sampler.Bundle\", \"Argument_StartMemory_ShortDescr\"); // NOI18N\n    private static final String SNAPSHOT_LONG_NAME = \"snapshot-sampler\";        // NOI18N\n    private static final Option SNAPSHOT_ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, SNAPSHOT_LONG_NAME), \"org.graalvm.visualvm.sampler.Bundle\", \"Argument_Snapshot_ShortDescr\"); // NOI18N\n    private static final String STOP_LONG_NAME = \"stop-sampler\";                // NOI18N\n    private static final Option STOP_ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, STOP_LONG_NAME), \"org.graalvm.visualvm.sampler.Bundle\", \"Argument_Stop_ShortDescr\"); // NOI18N\n    \n    static enum Request { NONE, CPU, MEMORY };\n    \n    \n    @Override\n    protected Set<Option> getOptions() {\n        Set<Option> options = new HashSet<>();\n        options.add(START_CPU_ARGUMENT);\n        options.add(START_MEMORY_ARGUMENT);\n        options.add(SNAPSHOT_ARGUMENT);\n        options.add(STOP_ARGUMENT);\n        return options;\n    }\n    \n    @Override\n    protected void process(Env env, Map<Option, String[]> maps) throws CommandException {\n        String[] startCPU = maps.get(START_CPU_ARGUMENT);\n        if (startCPU != null) {\n            final String[] _startCPU = startCPU.length == 1 ? startCPU[0].split(\"@\") : null; // NOI18N\n            if (_startCPU != null && _startCPU.length == 2) startCPU[0] = _startCPU[0];\n            new Finder(startCPU, START_CPU_LONG_NAME) {\n                @Override\n                public void found(Application application) {\n                    String settings = _startCPU != null && _startCPU.length == 2 ? _startCPU[1] : null;\n                    SamplerSupport.getInstance().startCPU(application, settings);\n                }\n            }.find();\n            return;\n        }\n        \n        String[] startMemory = maps.get(START_MEMORY_ARGUMENT);\n        if (startMemory != null) {\n            final String[] _startMemory = startMemory.length == 1 ? startMemory[0].split(\"@\") : null; // NOI18N\n            if (_startMemory != null && _startMemory.length == 2) startMemory[0] = _startMemory[0];\n            new Finder(startMemory, START_MEMORY_LONG_NAME) {\n                @Override\n                public void found(Application application) {\n                    String settings = _startMemory != null && _startMemory.length == 2 ? _startMemory[1] : null;\n                    SamplerSupport.getInstance().startMemory(application, settings);\n                }\n            }.find();\n            return;\n        }\n        \n        final String[] snapshot = maps.get(SNAPSHOT_ARGUMENT);\n        final String[] stop = maps.get(STOP_ARGUMENT);\n        if (snapshot != null) {\n            new Finder(snapshot, SNAPSHOT_LONG_NAME) {\n                @Override\n                public void found(Application application) {\n                    SamplerSupport.getInstance().takeSnapshot(application, true);\n                    if (stop != null && stop.length == 1 && stop[0].equals(snapshot[0]))\n                        SamplerSupport.getInstance().stop(application);\n                }\n            }.find();\n            return;\n        }\n        \n        if (stop != null) {\n            new Finder(stop, STOP_LONG_NAME) {\n                @Override\n                public void found(Application application) {\n                    SamplerSupport.getInstance().stop(application);\n                }\n            }.find();\n        }\n    }\n    \n    \n    private static abstract class Finder extends ApplicationFinder {\n        \n        Finder(String[] pids, String longName) throws CommandException {\n            super(resolvePid(pids, longName));\n        }\n        \n        \n        public final void notFound(int pid, String id) {\n            NotifyDescriptor desc = new NotifyDescriptor.Message(NbBundle.getMessage(SamplerArguments.class, \"MSG_NO_APP_PID\", new Object[] { Integer.toString(pid) }), NotifyDescriptor.WARNING_MESSAGE);\n            DialogDisplayer.getDefault().notifyLater(desc);\n        }\n        \n        \n        private static int resolvePid(String[] pids, String longName) throws CommandException {\n            if (pids.length == 1) {\n                try {\n                    return Integer.valueOf(pids[0]);\n                } catch (NumberFormatException e) {\n                    throw new CommandException(0, \"Incorrect pid format for --\" + longName + \": \" + e.getMessage()); // NOI18N\n                }\n            } else {\n                throw new CommandException(0, \"--\" + longName + \" requires exactly one value\"); // NOI18N\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/SamplerImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler;\n\nimport org.graalvm.visualvm.sampler.cpu.ThreadInfoProvider;\nimport org.graalvm.visualvm.sampler.cpu.ThreadsCPU;\nimport org.graalvm.visualvm.sampler.memory.MemorySettingsSupport;\nimport org.graalvm.visualvm.sampler.cpu.CPUSettingsSupport;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.heapdump.HeapDumpSupport;\nimport org.graalvm.visualvm.profiling.presets.PresetSelector;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPresets;\nimport org.graalvm.visualvm.profiling.snapshot.ProfilerSnapshot;\nimport org.graalvm.visualvm.sampler.cpu.CPUSamplerSupport;\nimport org.graalvm.visualvm.sampler.memory.MemorySamplerSupport;\nimport org.graalvm.visualvm.sampler.memory.ThreadsMemory;\nimport org.graalvm.visualvm.threaddump.ThreadDumpSupport;\nimport org.graalvm.visualvm.tools.attach.AttachModel;\nimport org.graalvm.visualvm.tools.attach.AttachModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.graalvm.visualvm.uisupport.HTMLLabel;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.io.DataOutputStream;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.lang.management.MemoryMXBean;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Timer;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.lib.common.ProfilingSettingsPresets;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPreset;\nimport org.netbeans.api.options.OptionsDisplayer;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class SamplerImpl {\n\n    private static final Logger LOGGER = Logger.getLogger(SamplerImpl.class.getName());\n\n    private static enum State { TERMINATED, INACTIVE, CPU, MEMORY, TRANSITION };\n    \n    private static final String OPTIONS_HANDLE = \"ProfilerOptions\"; // NOI18N\n\n    private Application application;\n    private Timer timer;\n\n    private HTMLTextArea summaryArea;\n    private String cpuStatus = NbBundle.getMessage(SamplerImpl.class, SamplerInitialization.getInstance().isAutomatic() ? \"MSG_Checking_Availability\" : \"MSG_Not_Initialized_Cpu\"); // NOI18N\n    private String memoryStatus = NbBundle.getMessage(SamplerImpl.class, SamplerInitialization.getInstance().isAutomatic() ? \"MSG_Checking_Availability\" : \"MSG_Not_Initialized_Memory\"); // NOI18N\n\n    private Boolean cpuProfilingSupported;\n    private AbstractSamplerSupport cpuSampler;\n    private CPUSettingsSupport cpuSettings;\n\n    private Boolean memoryProfilingSupported;\n    private AbstractSamplerSupport memorySampler;\n    private MemorySettingsSupport memorySettings;\n    \n    private DefaultComboBoxModel<ProfilerPreset> selectorModel;\n    private List<PresetSelector> allSelectors;\n\n    private DataViewComponent dvc;\n    private String currentName;\n    private DataViewComponent.DetailsView[] currentViews;\n    \n    private DataViewComponent.DetailsView[] summaryView;\n\n    private State state = State.TRANSITION;\n    private SamplerArguments.Request startRequest;\n    private SamplerParameters settingsRequest;\n\n\n    SamplerImpl(Application application, SamplerArguments.Request startRequest, SamplerParameters settingsRequest) {\n        this.application = application;\n        this.startRequest = startRequest;\n        this.settingsRequest = settingsRequest;\n        \n        cpuSettings = new CPUSettingsSupport() {\n            public boolean presetValid() {\n                return cpuSettings.settingsValid() &&\n                       memorySettings.settingsValid();\n            }\n            public PresetSelector createSelector(Runnable presetSynchronizer) {\n                return SamplerImpl.this.createSelector(presetSynchronizer);\n            }\n        };\n        memorySettings = new MemorySettingsSupport() {\n            public boolean presetValid() {\n                return cpuSettings.settingsValid() &&\n                       memorySettings.settingsValid();\n            }\n            public PresetSelector createSelector(Runnable presetSynchronizer) {\n                return SamplerImpl.this.createSelector(presetSynchronizer);\n            }\n        };\n    }\n    \n    \n    void startCPU(SamplerParameters parameters) {\n        if (parameters != null && !parameters.isEmpty()) cpuSettings.setSettings(parameters);\n        if (cpuProfilingSupported == null) startRequest = SamplerArguments.Request.CPU; // likely not initialized yet, perform lazily\n        else if (cpuButton != null && cpuButton.isEnabled() && !cpuButton.isSelected()) cpuButton.doClick();\n    }\n    \n    void startMemory(SamplerParameters parameters) {\n        if (parameters != null && !parameters.isEmpty()) memorySettings.setSettings(parameters);\n        if (memoryProfilingSupported == null) startRequest = SamplerArguments.Request.MEMORY; // likely not initialized yet, perform lazily\n        else if (memoryButton != null && memoryButton.isEnabled() && !memoryButton.isSelected()) memoryButton.doClick();\n    }\n    \n    void takeSnapshot(boolean openView) {\n        if (cpuSampler != null && State.CPU.equals(getState())) {\n            cpuSampler.takeSnapshot(openView);\n        } else if (memorySampler != null && State.MEMORY.equals(getState())) {\n            memorySampler.takeSnapshot(openView);\n        }\n    }\n    \n    void stop() {\n        if (stopButton != null && stopButton.isEnabled()) stopButton.doClick();\n    }\n    \n    \n    private PresetSelector createSelector(Runnable presetSynchronizer) {\n        if (selectorModel == null) selectorModel = new DefaultComboBoxModel<>();\n        if (allSelectors == null) allSelectors = new ArrayList<>();\n        PresetSelector selector = ProfilerPresets.getInstance().createSelector(\n                                  application, selectorModel, allSelectors, presetSynchronizer);\n        allSelectors.add(selector);\n        return selector;\n    }\n\n\n    DataViewComponent.MasterView getMasterView() {\n        initComponents();\n        setState(State.INACTIVE);\n\n        final HierarchyListener hl = new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (view.isShowing()) {\n                        boolean automatic = SamplerInitialization.getInstance().isAutomatic();\n                        if (automatic || SamplerArguments.Request.CPU.equals(startRequest)) {\n                            initializeCpuSampling();\n                        }\n                        if (automatic || SamplerArguments.Request.MEMORY.equals(startRequest)) {\n                            initializeMemorySampling();\n                        }\n                        view.removeHierarchyListener(this);\n                    }\n                }\n            }\n        };\n        view.addHierarchyListener(hl);\n\n        return new DataViewComponent.MasterView(NbBundle.getMessage(\n                   SamplerImpl.class, \"LBL_Sampler\"), null, view); // NOI18N\n    }\n\n\n    void setDataViewComponent(DataViewComponent dvc) {\n        this.dvc = dvc;\n\n        setCurrentViews(NbBundle.getMessage(SamplerImpl.class,\n                        \"LBL_Information\"), getSummaryView()); // NOI18N\n\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\n                NbBundle.getMessage(SamplerImpl.class, \"LBL_Settings\"), // NOI18N\n                true), DataViewComponent.TOP_RIGHT);\n        dvc.addDetailsView(cpuSettings.getDetailsView(), DataViewComponent.TOP_RIGHT);\n        dvc.addDetailsView(memorySettings.getDetailsView(), DataViewComponent.TOP_RIGHT);\n        dvc.hideDetailsArea(DataViewComponent.TOP_RIGHT);\n    }\n\n\n    void removed() {\n        terminate();\n    }\n\n    void applicationFinished() {\n        terminate();\n    }\n\n    private synchronized void terminate() {\n        State currentState = getState();\n\n        if (cpuSampler != null) {\n            if (State.CPU.equals(currentState)) cpuSampler.stopSampling();\n            cpuSampler.terminate();\n        }\n        if (memorySampler != null) {\n            if (State.MEMORY.equals(currentState)) memorySampler.stopSampling();\n            memorySampler.terminate();\n        }\n\n        setState(State.TERMINATED);\n        dvc = null;\n    }\n\n\n    private void setCurrentViews(String name, DataViewComponent.DetailsView[] views) {\n        if (dvc == null) return;\n\n        if (currentName == null || !currentName.equals(name)) {\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\n                    name, false), DataViewComponent.TOP_LEFT);\n\n            currentName = name;\n        }\n\n        if (currentViews != views) {\n            if (currentViews != null)\n                for (DataViewComponent.DetailsView detailsView : currentViews)\n                    dvc.removeDetailsView(detailsView);\n\n            if (views != null)\n                for (DataViewComponent.DetailsView detailsView : views)\n                    dvc.addDetailsView(detailsView, DataViewComponent.TOP_LEFT);\n\n            currentViews = views;\n        }\n    }\n\n    private synchronized void setState(State state) {\n        if (this.state.equals(state)) return;\n        this.state = state;\n\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                updateStatus();\n                updateSettings();\n                updateButtons();\n            }\n        });\n    }\n\n    private synchronized State getState() {\n        return state;\n    }\n\n\n    private void updateStatus() {\n        if (statusValueLabel != null) {\n            String status = NbBundle.getMessage(SamplerImpl.class,\n                            \"LBL_Undefined\"); // NOI18N\n\n            switch (getState()) {\n                case TERMINATED:\n                    status = NbBundle.getMessage(SamplerImpl.class,\n                             \"MSG_Application_terminated\"); // NOI18N\n                    break;\n                case INACTIVE:\n                    status = NbBundle.getMessage(SamplerImpl.class,\n                             \"MSG_Sampling_inactive\"); // NOI18N\n                    break;\n                case CPU:\n                    status = NbBundle.getMessage(SamplerImpl.class,\n                             \"MSG_Cpu_progress\"); // NOI18N\n                    break;\n                case MEMORY:\n                    status = NbBundle.getMessage(SamplerImpl.class,\n                             \"MSG_Memory_progress\"); // NOI18N\n                    break;\n                case TRANSITION:\n                    status = NbBundle.getMessage(SamplerImpl.class,\n                             \"LBL_Refreshing\"); // NOI18N\n                    break;\n            }\n\n            statusValueLabel.setText(status);\n        }\n    }\n\n    private void updateSettings() {\n        if (cpuSettings != null && memorySettings != null) {\n            switch (getState()) {\n                case INACTIVE:\n                case TERMINATED:\n                    cpuSettings.setEnabled(true);\n                    memorySettings.setEnabled(true);\n                    break;\n                case CPU:\n                case MEMORY:\n                case TRANSITION:\n                    cpuSettings.setEnabled(false);\n                    memorySettings.setEnabled(false);\n                    break;\n            }\n        }\n    }\n\n    private void updateButtons() {\n        if (cpuButton != null && memoryButton != null && stopButton != null) {\n            switch (getState()) {\n                case TERMINATED:\n                    cpuButton.setSelected(false);\n                    cpuButton.setEnabled(false);\n\n                    memoryButton.setSelected(false);\n                    memoryButton.setEnabled(false);\n\n                    stopButton.setEnabled(false);\n\n                    break;\n\n                case INACTIVE:\n                    cpuButton.setSelected(false);\n                    cpuButton.setEnabled(buttonEnabled(cpuProfilingSupported));\n\n                    memoryButton.setSelected(false);\n                    memoryButton.setEnabled(buttonEnabled(memoryProfilingSupported));\n\n                    stopButton.setEnabled(false);\n\n                    break;\n\n                case CPU:\n                    cpuButton.setSelected(true);\n                    cpuButton.setEnabled(true);\n\n                    memoryButton.setSelected(false);\n                    memoryButton.setEnabled(buttonEnabled(memoryProfilingSupported));\n\n                    stopButton.setEnabled(true);\n\n                    break;\n\n                case MEMORY:\n                    cpuButton.setSelected(false);\n                    cpuButton.setEnabled(buttonEnabled(cpuProfilingSupported));\n\n                    memoryButton.setSelected(true);\n                    memoryButton.setEnabled(true);\n\n                    stopButton.setEnabled(true);\n\n                    break;\n\n                case TRANSITION:\n                    cpuButton.setEnabled(false);\n\n                    memoryButton.setEnabled(false);\n\n                    stopButton.setEnabled(false);\n\n                    break;\n            }\n        }\n    }\n    \n    private boolean buttonEnabled(Boolean profilingSupported) {\n        if (profilingSupported != null) {\n            return profilingSupported.booleanValue();\n        } else {\n            return !SamplerInitialization.getInstance().isAutomatic();\n        }\n    }\n\n\n    private void handleCPUProfiling() {\n        State currentState = getState();\n        if (currentState.equals(State.CPU) ||\n           currentState.equals(State.TERMINATED) ||\n           currentState.equals(State.TRANSITION)) return;\n        \n        final RequestProcessor synchronousExecutor = new RequestProcessor(\"Sampler Worker\", 1);\n        \n        if (currentState.equals(State.MEMORY)) {\n            synchronousExecutor.post(new Runnable() {\n                public void run() {\n                    memorySampler.stopSampling();\n                    setState(State.INACTIVE);\n                }\n            });\n        }\n        \n        if (cpuProfilingSupported == null) {\n            cpuStatus = NbBundle.getMessage(SamplerImpl.class, \"MSG_Checking_Availability\");\n            updateStatus();\n            startRequest = SamplerArguments.Request.CPU;\n            initializeCpuSampling();\n            return;\n        }\n        \n        if (!cpuSettings.settingsValid()) {\n            cpuButton.setSelected(false);\n            if (dvc != null) cpuSettings.showSettings(dvc);\n            ProfilerDialogs.displayError(NbBundle.getMessage(SamplerImpl.class, \"MSG_Incorrect_CPU_settings\")); // NOI18N\n            return;\n        }\n        \n        setState(State.TRANSITION);\n        \n        synchronousExecutor.post(new Runnable() {\n            public void run() {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setCurrentViews(NbBundle.getMessage(SamplerImpl.class,\n                                        \"LBL_Cpu_samples\"), cpuSampler.getDetailsView()); // NOI18N\n                        VisualVM.getInstance().runTask(new Runnable() {\n                            public void run() {\n                                cpuSettings.saveSettings();\n                                setState(cpuSampler.startSampling(\n                                         cpuSettings.getSettings(),\n                                         cpuSettings.getSamplingRate(),\n                                         cpuSettings.getRefreshRate()) ?\n                                         State.CPU : State.INACTIVE);\n                            }\n                        });\n                    }\n                });\n            }\n        });\n    }\n\n    private void handleMemoryProfiling() {\n        State currentState = getState();\n        if (currentState.equals(State.MEMORY) ||\n           currentState.equals(State.TERMINATED) ||\n           currentState.equals(State.TRANSITION)) return;\n        \n        final RequestProcessor synchronousExecutor = new RequestProcessor(\"Sampler Worker\", 1);\n        \n        if (currentState.equals(State.CPU)) {\n            synchronousExecutor.post(new Runnable() {\n                public void run() {\n                    cpuSampler.stopSampling();\n                    setState(State.INACTIVE);\n                }\n            });\n        }\n        \n        if (memoryProfilingSupported == null) {\n            memoryStatus = NbBundle.getMessage(SamplerImpl.class, \"MSG_Checking_Availability\");\n            updateStatus();\n            startRequest = SamplerArguments.Request.MEMORY;\n            initializeMemorySampling();\n            return;\n        }\n        \n        if (!memorySettings.settingsValid()) {\n            memoryButton.setSelected(false);\n            if (dvc != null) memorySettings.showSettings(dvc);\n            ProfilerDialogs.displayError(NbBundle.getMessage(SamplerImpl.class, \"MSG_Incorrect_Memory_settings\")); // NOI18N\n            return;\n        }\n        \n        setState(State.TRANSITION);\n\n        synchronousExecutor.post(new Runnable() {\n            public void run() {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setCurrentViews(NbBundle.getMessage(SamplerImpl.class,\n                                        \"LBL_Memory_samples\"), memorySampler.getDetailsView()); // NOI18N\n                        VisualVM.getInstance().runTask(new Runnable() {\n                            public void run() {\n                                memorySettings.saveSettings();\n                                setState(memorySampler.startSampling(\n                                         memorySettings.getSettings(),\n                                         memorySettings.getSamplingRate(),\n                                         memorySettings.getRefreshRate()) ?\n                                         State.MEMORY : State.INACTIVE);\n                            }\n                        });\n                    }\n                });\n            }\n        });\n    }\n\n    private void handleStopProfiling() {\n        State currentState = getState();\n        if (currentState.equals(State.INACTIVE) ||\n           currentState.equals(State.TERMINATED) ||\n           currentState.equals(State.TRANSITION)) return;\n        setState(State.TRANSITION);\n\n        if (currentState.equals(State.CPU)) {\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    cpuSampler.stopSampling();\n                    setState(State.INACTIVE);\n                }\n            });\n        } else if (currentState.equals(State.MEMORY)) {\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    memorySampler.stopSampling();\n                    setState(State.INACTIVE);\n                }\n            });\n        }\n    }\n\n\n    private void initializeCpuSampling() {\n        cpuProfilingSupported = Boolean.FALSE;\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                ThreadInfoProvider ti = new ThreadInfoProvider(application);\n                final String status = ti.getStatus();\n                ThreadsCPU tcpu;\n                \n                if (status != null) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            cpuStatus = status;\n                            refreshSummary();\n                            setCurrentViews(NbBundle.getMessage(SamplerImpl.class, \"LBL_Information\"), getSummaryView()); // NOI18N\n                            updateButtons();\n                        }\n                    });\n                    return;\n                }\n\n                CPUSamplerSupport.SnapshotDumper snapshotDumper = new CPUSamplerSupport.SnapshotDumper() {\n                    public void takeSnapshot(final boolean openView) {\n                        VisualVM.getInstance().runTask(new Runnable() {\n                            public void run() {\n                                LoadedSnapshot ls = null;\n                                try {\n                                    ls = takeNPSSnapshot(application.getStorage().getDirectory());\n                                } catch (CPUResultsSnapshot.NoDataAvailableException e) {\n                                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(NbBundle.getMessage(\n                                            SamplerImpl.class, \"MSG_No_save_data_cpu\"), NotifyDescriptor.WARNING_MESSAGE)); // NOI18N\n                                } catch (Throwable t) {\n                                    LOGGER.log(Level.WARNING, \"Failed to save profiler snapshot for \" + application, t); // NOI18N\n                                }\n                                if (ls != null) {\n                                    final ProfilerSnapshot ps = ProfilerSnapshot.createSnapshot(ls.getFile(), application);\n                                    application.getRepository().addDataSource(ps);\n                                    if (openView) DataSource.EVENT_QUEUE.post(new Runnable() {\n                                        public void run() {\n                                            DataSourceWindowManager.sharedInstance().openDataSource(ps);\n                                        }\n                                    });\n                                }\n                            }\n                        });\n                    }\n                };\n                tcpu = new ThreadsCPU(ti.getThreadMXBean(), JmxModelFactory.getJmxModelFor(application).getMBeanServerConnection());\n                try {\n                    tcpu.getThreadsCPUInfo();\n                } catch (Exception ex) {\n                    tcpu = null;\n                }\n\n                final ThreadDumpSupport tds = ThreadDumpSupport.getInstance();\n                final String noThreadDump = tds.supportsThreadDump(application) ? null : NbBundle.getMessage(\n                                            SamplerImpl.class, \"MSG_Thread_dump_unsupported\"); // NOI18N\n                final String noThreadCPU =  tcpu != null ? null : NbBundle.getMessage(\n                                            SamplerImpl.class, \"MSG_ThreadCPU_unsupported\"); // NOI18N\n\n                CPUSamplerSupport.ThreadDumper threadDumper = noThreadDump != null ? null :\n                    new CPUSamplerSupport.ThreadDumper() {\n                        public void takeThreadDump(boolean openView) {\n                            tds.takeThreadDump(application, openView);\n                        }\n                    };\n                    \n                cpuSampler = new CPUSamplerSupport(application, ti, tcpu, snapshotDumper, threadDumper) {\n                    protected Timer getTimer() { return SamplerImpl.this.getTimer(); }\n                };\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        String avail = NbBundle.getMessage(SamplerImpl.class,\n                                                           \"MSG_Available\"); // NOI18N\n                        if (noThreadDump != null || noThreadCPU != null) {\n                            String[] msgs = new String[2];\n                            int i = 0;\n                            if (noThreadDump != null) {\n                                msgs[i++] = noThreadDump;\n                            }\n                            if (noThreadCPU != null) {\n                                msgs[i++] = noThreadCPU;\n                            }\n                            if (i == 1) {\n                                avail = NbBundle.getMessage(SamplerImpl.class,\n                                        \"MSG_Available_details\", msgs[0]); // NOI18N\n                            } else if (i == 2) {\n                                avail = NbBundle.getMessage(SamplerImpl.class,\n                                        \"MSG_Available_details2\", msgs[0], msgs[1]); // NOI18N\n                            }\n                        }\n                        cpuStatus = avail + \" \" + NbBundle.getMessage(SamplerImpl.class, \"MSG_Press_cpu\"); // NOI18N\n                        cpuProfilingSupported = Boolean.TRUE;\n                        refreshSummary();\n                        updateButtons();\n                        updateSettings();\n                        if (SamplerArguments.Request.CPU.equals(startRequest)) startCPU(settingsRequest);\n                    }\n                });\n            }\n        });\n    }\n\n    private void initializeMemorySampling() {\n        memoryProfilingSupported = Boolean.FALSE;\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                if (application.getState() != Stateful.STATE_AVAILABLE) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            memoryStatus = NbBundle.getMessage(SamplerImpl.class,\n                                    \"MSG_Unavailable\"); // NOI18N\n                            refreshSummary();\n                            setCurrentViews(NbBundle.getMessage(SamplerImpl.class, \"LBL_Information\"), getSummaryView()); // NOI18N\n                            updateButtons();\n                        }\n                    });\n                    return;\n                }\n                final Jvm jvm = JvmFactory.getJVMFor(application);\n                boolean hasPermGenHisto;\n                try {\n                    HeapHistogram histogram = jvm.takeHeapHistogram();\n                    if (histogram == null) {\n                        if (!application.isLocalApplication()) {\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    memoryStatus = NbBundle.getMessage(SamplerImpl.class,\n                                            \"MSG_Unavailable_remote\"); // NOI18N\n                                    refreshSummary();\n                                    setCurrentViews(NbBundle.getMessage(SamplerImpl.class, \"LBL_Information\"), getSummaryView()); // NOI18N\n                                    updateButtons();\n                                }\n                            });\n                            return;\n                        }\n                        if (!jvm.isAttachable()) {\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    memoryStatus = NbBundle.getMessage(SamplerImpl.class,\n                                            \"MSG_Unavailable_connect_jdk\"); // NOI18N\n                                    refreshSummary();\n                                    setCurrentViews(NbBundle.getMessage(SamplerImpl.class, \"LBL_Information\"), getSummaryView()); // NOI18N\n                                    updateButtons();\n                                }\n                            });\n                            return;\n                        }\n                        final AttachModel attachModel = AttachModelFactory.getAttachFor(application);\n                        if (attachModel == null) {\n                            SwingUtilities.invokeLater(new Runnable() {\n                                public void run() {\n                                    memoryStatus = NbBundle.getMessage(SamplerImpl.class,\n                                            \"MSG_Unavailable_connect_log\", VisualVM.getInstance().getLogfileHandle()); // NOI18N\n                                    refreshSummary();\n                                    setCurrentViews(NbBundle.getMessage(SamplerImpl.class, \"LBL_Information\"), getSummaryView()); // NOI18N\n                                    updateButtons();\n                                }\n                            });\n                            LOGGER.log(Level.WARNING, \"AttachModelFactory.getAttachFor(application) returns null for \" + application); // NOI18N\n                            return;\n                        }\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                memoryStatus = NbBundle.getMessage(SamplerImpl.class,\n                                    \"MSG_Unavailable_read_log\", VisualVM.getInstance().getLogfileHandle()); // NOI18N\n                                refreshSummary();\n                                setCurrentViews(NbBundle.getMessage(SamplerImpl.class, \"LBL_Information\"), getSummaryView()); // NOI18N\n                                updateButtons();\n                            }\n                        });\n                        LOGGER.log(Level.WARNING, \"attachModel.takeHeapHistogram() returns null for \" + application); // NOI18N\n                        return;\n                    }\n                    hasPermGenHisto = !histogram.getPermGenHistogram().isEmpty();\n                } catch (Throwable t) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            memoryStatus = NbBundle.getMessage(SamplerImpl.class,\n                                    \"MSG_Unavailable_read_log\", VisualVM.getInstance().getLogfileHandle()); // NOI18N\n                            refreshSummary();\n                            setCurrentViews(NbBundle.getMessage(SamplerImpl.class, \"LBL_Information\"), getSummaryView()); // NOI18N\n                            updateButtons();\n                        }\n                    });\n                    LOGGER.log(Level.WARNING, \"attachModel.takeHeapHistogram() throws Throwable for \" + application, t); // NOI18N\n                    return;\n                }\n\n                MemoryMXBean memoryBean = null;\n                ThreadsMemory threadsMemory = null;\n                JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);\n                if (jmxModel != null && jmxModel.getConnectionState() == JmxModel.ConnectionState.CONNECTED) {\n                    JvmMXBeans mxbeans = jmxModel.getJvmMXBeans();\n                    if (mxbeans != null) {\n                        memoryBean = mxbeans.getMemoryMXBean();\n                        try {\n                            threadsMemory = new ThreadsMemory(mxbeans.getThreadMXBean(),jmxModel.getMBeanServerConnection());\n                            threadsMemory.getThreadsMemoryInfo();\n                        } catch (Exception ex) {\n                            threadsMemory = null;\n                        }\n                    }\n                }\n                final String noPerformGC = memoryBean == null ? NbBundle.getMessage(\n                        SamplerImpl.class, \"MSG_Gc_unsupported\") : null; // NOI18N\n                final String noThreadMem = threadsMemory == null ? NbBundle.getMessage(\n                        SamplerImpl.class, \"MSG_ThreadMemory_unsupported\") : null; // NOI18N\n\n                final HeapDumpSupport hds = HeapDumpSupport.getInstance();\n                final boolean local = application.isLocalApplication();\n                boolean supportsHD = local ? hds.supportsHeapDump(application) :\n                                     hds.supportsRemoteHeapDump(application);\n                final String noHeapDump = supportsHD ? null : NbBundle.getMessage(\n                        SamplerImpl.class, \"MSG_HeapDump_unsupported\"); // NOI18N\n\n                MemorySamplerSupport.SnapshotDumper snapshotDumper = new MemorySamplerSupport.SnapshotDumper() {\n                    public void takeSnapshot(final boolean openView) {\n                        final MemorySamplerSupport.SnapshotDumper dumper = this; \n                        VisualVM.getInstance().runTask(new Runnable() {\n                            public void run() {\n                                LoadedSnapshot ls = null;\n                                DataOutputStream dos = null;\n                                try {\n                                    long time = System.currentTimeMillis();\n                                    SampledMemoryResultsSnapshot snapshot = dumper.createSnapshot(time);\n                                    if (snapshot == null) {\n                                        DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(\n                                                NbBundle.getMessage(SamplerImpl.class, \"MSG_No_save_data_memory\"), // NOI18N\n                                                NotifyDescriptor.WARNING_MESSAGE));\n                                    } else {\n                                        ls = new LoadedSnapshot(snapshot, ProfilingSettingsPresets.createMemoryPreset(), null, null);\n                                        File file = Utils.getUniqueFile(application.getStorage().getDirectory(),\n                                                                        ResultsManager.getDefault().getDefaultSnapshotFileName(ls),\n                                                                        \".\" + ResultsManager.SNAPSHOT_EXTENSION); // NOI18N\n                                        dos = new DataOutputStream(new FileOutputStream(file));\n                                        ls.save(dos);\n                                        ls.setFile(file);\n                                        ls.setSaved(true);\n                                    }\n                                } catch (Throwable t) {\n                                    LOGGER.log(Level.WARNING, \"Failed to save profiler snapshot for \" + application, t); // NOI18N\n                                } finally {\n                                    try {\n                                        if (dos != null) dos.close();\n                                    } catch (IOException e) {\n                                        LOGGER.log(Level.WARNING, \"Problem closing output stream for  \" + dos, e); // NOI18N\n                                    }\n                                }\n                                if (ls != null) {\n                                    final ProfilerSnapshot ps = ProfilerSnapshot.createSnapshot(ls.getFile(), application);\n                                    application.getRepository().addDataSource(ps);\n                                    if (openView) DataSource.EVENT_QUEUE.post(new Runnable() {\n                                        public void run() {\n                                            DataSourceWindowManager.sharedInstance().openDataSource(ps);\n                                        }\n                                    });\n                                }\n                            }\n                        });\n                    }\n                };\n                MemorySamplerSupport.HeapDumper heapDumper = noHeapDump != null ? null :\n                    new MemorySamplerSupport.HeapDumper() {\n                        public void takeHeapDump(boolean openView) {\n                            if (local) hds.takeHeapDump(application, openView);\n                            else hds.takeRemoteHeapDump(application, null, openView);\n                        }\n                    };\n                memorySampler = new MemorySamplerSupport(application, jvm, hasPermGenHisto, threadsMemory, memoryBean, snapshotDumper, heapDumper) {\n                    protected Timer getTimer() { return SamplerImpl.this.getTimer(); }\n                };\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        String avail = NbBundle.getMessage(SamplerImpl.class,\n                                                           \"MSG_Available\"); // NOI18N\n                        if (noPerformGC != null || noHeapDump != null || noThreadMem != null) {\n                            String[] msgs = new String[3];\n                            int i = 0;\n                            if (noHeapDump != null) {\n                                msgs[i++] = noHeapDump;\n                            }\n                            if (noPerformGC != null) {\n                                msgs[i++] = noPerformGC;\n                            }\n                            if (noThreadMem != null) {\n                                msgs[i++] = noThreadMem;\n                            }\n                            if (i == 1) {\n                                avail = NbBundle.getMessage(SamplerImpl.class,\n                                        \"MSG_Available_details\", msgs[0]); // NOI18N\n                            } else if (i == 2) {\n                                avail = NbBundle.getMessage(SamplerImpl.class,\n                                        \"MSG_Available_details2\", msgs[0], msgs[1]); // NOI18N\n                            } else {\n                                avail = NbBundle.getMessage(SamplerImpl.class,\n                                        \"MSG_Available_details3\", msgs[0], msgs[1], msgs[2]); // NOI18N\n                            }\n                        }\n                        memoryStatus = avail + \" \" + NbBundle.getMessage( // NOI18N\n                                SamplerImpl.class, \"MSG_Press_mem\"); // NOI18N\n                        memoryProfilingSupported = Boolean.TRUE;\n                        refreshSummary();\n                        updateButtons();\n                        updateSettings();\n                        if (SamplerArguments.Request.MEMORY.equals(startRequest)) startMemory(settingsRequest);\n                    }\n                });\n            }\n        });\n    }\n\n    private synchronized Timer getTimer() {\n        if (timer == null)\n            timer = new Timer(\"Sampler timer for \" + DataSourceDescriptorFactory. // NOI18N\n                              getDescriptor(application).getName());\n        return timer;\n    }\n\n    private DataViewComponent.DetailsView[] getSummaryView() {\n        if (summaryView == null) {\n            summaryArea = new HTMLTextArea() {\n                @Override\n                protected void showURL(URL url) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        @Override\n                        public void run() {\n                            SamplerInitialization.getInstance().runIfChangedToAutomatic(new Runnable() {\n                                @Override\n                                public void run() {\n                                    if (cpuProfilingSupported == null) initializeCpuSampling();\n                                    if (memoryProfilingSupported == null) initializeMemorySampling();\n                                }\n                            });\n                            OptionsDisplayer.getDefault().open(OPTIONS_HANDLE); // NOTE: should better open it as modal?\n                        }\n                    });\n                }\n            };\n            summaryArea.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n\n            refreshSummary();\n\n            SamplerInitialization.getInstance().addChangeListener(SamplerInitialization.PROP_INITIALIZE_AUTOMATICALLY, new PropertyChangeListener() {\n                @Override\n                public void propertyChange(PropertyChangeEvent evt) {\n                    refreshSummary();\n                }\n            });\n\n            summaryView = new DataViewComponent.DetailsView[] { new DataViewComponent.DetailsView(NbBundle.getMessage(\n                            SamplerImpl.class, \"LBL_Summary\"), null, 10, // NOI18N\n                            new ScrollableContainer(summaryArea), null) };\n        }\n        \n        return summaryView;\n    }\n\n    private void refreshSummary() {\n        StringBuilder builder = new StringBuilder();\n\n        addCpuHeader(builder);\n        builder.append(cpuStatus);\n\n        addMemoryHeader(builder);\n        builder.append(memoryStatus);\n        \n//        String initializationMode = NbBundle.getMessage(SamplerImpl.class, SamplerInitialization.getInstance().isAutomatic() ? \"LBL_Initialization_Automatically\" : \"LBL_Initialization_Manually\"); // NOI18N\n//        builder.append(NbBundle.getMessage(SamplerImpl.class, \"LBL_Initialization_Configuration\", initializationMode)); // NOI18N\n\n        int selStart = summaryArea.getSelectionStart();\n        int selEnd = summaryArea.getSelectionEnd();\n        summaryArea.setText(builder.toString());\n        summaryArea.select(selStart, selEnd);\n    }\n\n    private static void addCpuHeader(StringBuilder builder) {\n        builder.append(NbBundle.getMessage(SamplerImpl.class, \"LBL_Cpu_sampling\")); // NOI18N\n    }\n\n    private static void addMemoryHeader(StringBuilder builder) {\n        builder.append(NbBundle.getMessage(SamplerImpl.class, \"LBL_Memory_sampling\")); // NOI18N\n    }\n\n    private void initComponents() {\n        view = new JPanel(new GridBagLayout());\n        view.setOpaque(false);\n        view.setBorder(BorderFactory.createEmptyBorder(11, 5, 8, 5));\n\n        GridBagConstraints constraints;\n\n        // modeLabel\n        modeLabel = new JLabel(NbBundle.getMessage(SamplerImpl.class, \"LBL_Profile\")); // NOI18N\n        modeLabel.setFont(modeLabel.getFont().deriveFont(Font.BOLD));\n        Dimension d = modeLabel.getPreferredSize();\n        modeLabel.setText(NbBundle.getMessage(SamplerImpl.class, \"LBL_Sample\")); // NOI18N\n        d.width = Math.max(d.width, modeLabel.getPreferredSize().width);\n        modeLabel.setPreferredSize(d);\n        modeLabel.setOpaque(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 2;\n        constraints.gridwidth = 1;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(4, 8, 0, 0);\n        view.add(modeLabel, constraints);\n\n        // cpuButton\n        cpuButton = new OneWayToggleButton(NbBundle.getMessage(SamplerImpl.class, \"LBL_Cpu\")); // NOI18N\n        cpuButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/sampler/resources/cpu.png\", true))); // NOI18N\n        cpuButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { handleCPUProfiling(); }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 2;\n        constraints.gridy = 2;\n        constraints.gridwidth = 1;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(4, 8, 0, 0);\n        view.add(cpuButton, constraints);\n\n        // memoryButton\n        memoryButton = new OneWayToggleButton(NbBundle.getMessage(SamplerImpl.class, \"LBL_Memory\")); // NOI18N\n        memoryButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/sampler/resources/memory.png\", true))); // NOI18N\n        memoryButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { handleMemoryProfiling(); }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 3;\n        constraints.gridy = 2;\n        constraints.gridwidth = 1;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(4, 8, 0, 0);\n        view.add(memoryButton, constraints);\n\n        // stopButton\n        stopButton = new JButton(NbBundle.getMessage(SamplerImpl.class, \"LBL_Stop\")); // NOI18N\n        stopButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/sampler/resources/stop.png\", true))); // NOI18N\n        stopButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { handleStopProfiling(); }\n        });\n        stopButton.setEnabled(false);\n        stopButton.setDefaultCapable(false); // Button size\n        constraints = new GridBagConstraints();\n        constraints.gridx = 4;\n        constraints.gridy = 2;\n        constraints.gridwidth = 1;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(4, 8, 0, 0);\n        view.add(stopButton, constraints);\n\n        // filler1\n        constraints = new GridBagConstraints();\n        constraints.gridx = 5;\n        constraints.gridy = 2;\n        constraints.weightx = 1;\n        constraints.weighty = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.insets = new Insets(0, 0, 0, 0);\n        view.add(Spacer.create(), constraints);\n\n        // statusLabel\n        statusLabel = new JLabel(NbBundle.getMessage(SamplerImpl.class, \"LBL_Status\")); // NOI18N\n        statusLabel.setFont(statusLabel.getFont().deriveFont(Font.BOLD));\n        statusLabel.setOpaque(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 3;\n        constraints.gridwidth = 1;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(6, 8, 4, 0);\n        view.add(statusLabel, constraints);\n\n        // statusValueLabel\n        statusValueLabel = new HTMLLabel() {\n            public void setText(String text) {super.setText(\"<nobr>\" + text + \"</nobr>\"); } // NOI18N\n            protected void showURL(URL url) {}\n\n            // NOTE: overriding dimensions prevents UI \"jumping\" when changing the link\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.height = getRefLabelHeight();\n                return dim;\n            }\n            public Dimension getMinimumSize() { return getPreferredSize(); }\n            public Dimension getMaximumSize() { return getPreferredSize(); }\n        };\n        statusValueLabel.setOpaque(false);\n        statusValueLabel.setFocusable(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 1;\n        constraints.gridy = 3;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(6, 8, 4, 8);\n        view.add(statusValueLabel, constraints);\n\n        // filler2\n        constraints = new GridBagConstraints();\n        constraints.gridx = 2;\n        constraints.gridy = 3;\n        constraints.weightx = 1;\n        constraints.weighty = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.insets = new Insets(0, 0, 0, 0);\n        view.add(Spacer.create(), constraints);\n\n        Dimension cpuD     = cpuButton.getPreferredSize();\n        Dimension memoryD  = memoryButton.getPreferredSize();\n        Dimension stopD    = stopButton.getPreferredSize();\n\n        Dimension maxD = new Dimension(Math.max(cpuD.width, memoryD.width), Math.max(cpuD.height, memoryD.height));\n        maxD = new Dimension(Math.max(maxD.width, stopD.width), Math.max(maxD.height, stopD.height));\n\n        cpuButton.setPreferredSize(maxD);\n        cpuButton.setMinimumSize(maxD);\n        memoryButton.setPreferredSize(maxD);\n        memoryButton.setMinimumSize(maxD);\n        stopButton.setPreferredSize(maxD);\n        stopButton.setMinimumSize(maxD);\n    }\n\n    private JPanel view;\n    private JLabel modeLabel;\n    private JToggleButton cpuButton;\n    private JToggleButton memoryButton;\n    private JButton stopButton;\n    private JLabel statusLabel;\n    private HTMLLabel statusValueLabel;\n\n    private static int refLabelHeight = -1;\n    private static int getRefLabelHeight() {\n        if (refLabelHeight == -1)\n            refLabelHeight = new HTMLLabel(\"X\").getPreferredSize().height; // NOI18N\n        return refLabelHeight;\n    }\n\n\n    private static final class OneWayToggleButton extends JToggleButton {\n\n        OneWayToggleButton(String text) {\n            super(text);\n        }\n\n        protected void processMouseEvent(MouseEvent e) {\n            if (!isSelected()) super.processMouseEvent(e);\n        }\n\n        protected void processKeyEvent(KeyEvent e) {\n            if (!isSelected()) super.processKeyEvent(e);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/SamplerInitialization.java",
    "content": "/*\n * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.ItemListener;\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport java.util.prefs.Preferences;\nimport javax.swing.JCheckBox;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.profiling.presets.ProfilingOptionsSectionProvider;\nimport org.openide.awt.Mnemonics;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service = ProfilingOptionsSectionProvider.class)\n@NbBundle.Messages({\n    \"CAP_SectionName=Sampler Initialization\",\n    \"BTN_InitializeAutomatically=&Initialize Sampler automatically when displayed\"\n})\npublic final class SamplerInitialization extends ProfilingOptionsSectionProvider {\n    \n    public static final String PROP_INITIALIZE_AUTOMATICALLY = \"SamplerInitialization.initializeAutomatically\"; // NOI18N\n    \n    private final PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);\n    \n    private final Preferences prefs;\n    \n    private JCheckBox initializeAutomatically;\n    \n    private Runnable changedToAutomatic;\n    \n    public SamplerInitialization() {\n        prefs = NbPreferences.forModule(SamplerInitialization.class);\n    }\n    \n    public static SamplerInitialization getInstance() {\n        return Lookup.getDefault().lookup(SamplerInitialization.class);\n    }\n\n    public String getSectionName() {\n        return Bundle.CAP_SectionName();\n    }\n\n    public Component getSection() {\n        initializeAutomatically = new JCheckBox(null, null, isAutomatic());\n        Mnemonics.setLocalizedText(initializeAutomatically, Bundle.BTN_InitializeAutomatically());\n        \n        initializeAutomatically.addItemListener(new ItemListener() {\n            @Override\n            public void itemStateChanged(ItemEvent e) {\n                changed();\n            }\n        });\n        \n        JPanel container = new JPanel(new BorderLayout());\n        container.add(initializeAutomatically, BorderLayout.WEST);\n        \n        return container;\n    }\n    \n    protected void load() {\n        initializeAutomatically.setSelected(isAutomatic());\n    }\n\n    protected void store() {\n        if (initializeAutomatically != null) {\n            setAutomatic(initializeAutomatically.isSelected());\n        }\n    }\n\n    protected void closed() {\n        changedToAutomatic = null;\n    }\n    \n    boolean isAutomatic() {\n        return prefs.getBoolean(PROP_INITIALIZE_AUTOMATICALLY, true);\n    }\n    \n    private void setAutomatic(boolean automatic) {\n        boolean orig = isAutomatic();\n        if (orig != automatic) {\n            prefs.putBoolean(PROP_INITIALIZE_AUTOMATICALLY, automatic);\n            changeSupport.firePropertyChange(PROP_INITIALIZE_AUTOMATICALLY, orig, automatic);\n            if (automatic && changedToAutomatic != null) changedToAutomatic.run();\n        }\n    }\n    \n    void runIfChangedToAutomatic(Runnable changedToAutomatic) {\n        this.changedToAutomatic = changedToAutomatic;\n    }\n    \n    public void addChangeListener(String property, PropertyChangeListener listener) {\n        changeSupport.addPropertyChangeListener(property, listener);\n    }\n    \n    public void removeChangeListener(String property, PropertyChangeListener listener) {\n        changeSupport.removePropertyChangeListener(property, listener);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/SamplerParameters.java",
    "content": "/*\n * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler;\n\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class SamplerParameters {\n    \n    private static final Logger LOGGER = Logger.getLogger(SamplerImpl.class.getName());\n    \n    \n    protected static final String FILE = \"settings-file\";                       // NOI18N\n    \n    \n    private final Map<String, String> parameters;\n    \n    \n    protected SamplerParameters(String parametersS) {\n        if (parametersS == null || parametersS.isEmpty()) {\n            parameters = null;\n        } else {\n            parameters = new HashMap<>();\n            parseParameters(parametersS, parameters);\n        }\n    }\n    \n    \n    public final String get(String key) {\n        return parameters == null ? null : parameters.get(key);\n    }\n    \n    public final boolean isEmpty() {\n        return parameters == null || parameters.isEmpty();\n    }\n    \n    \n    public String toString() {\n        return parameters == null ? \"[no parameters]\" : parameters.toString();  // NOI18N\n    }\n    \n    \n    protected abstract void parseParameters(String parametersS, Map<String, String> parameters);\n    \n    \n    protected static Properties loadProperties(String file) {\n        Properties properties = new Properties();\n        \n        try (InputStreamReader isr = new InputStreamReader(new FileInputStream(file), \"UTF-8\")) { // NOI18N\n            properties.load(isr);\n        } catch (IOException e) {\n            LOGGER.log(Level.WARNING, \"Failed to read Sampler parameters\", e); // NOI18N\n        }\n        \n        return properties;\n    }\n    \n    protected static String decode(String value) {\n        value = value.replace(\"%27\", \"\\'\");                                     // NOI18N\n        value = value.replace(\"%22\", \"\\\"\");                                     // NOI18N\n        value = value.replace(\"%20\", \" \");                                      // NOI18N\n        value = value.replace(\"%2C\", \",\");                                      // NOI18N\n        return value;\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/SamplerSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.sampler.cpu.CPUSamplerParameters;\nimport org.graalvm.visualvm.sampler.memory.MemorySamplerParameters;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic final class SamplerSupport {    \n    private static SamplerSupport instance;\n    \n    private final ApplicationSamplerViewProvider samplerViewProvider;\n\n\n    public static synchronized SamplerSupport getInstance() {\n        if (instance == null) instance = new SamplerSupport();\n        return instance;\n    }\n    \n    boolean supportsProfiling(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        return JvmFactory.getJVMFor(application).isBasicInfoSupported();\n    }\n    \n    void selectSamplerView(Application application) {\n        ApplicationSamplerView view = getSamplerView(application);\n        if (view != null) DataSourceWindowManager.sharedInstance().selectView(view);\n    }\n    \n    \n    void startCPU(Application application, String settings) {\n        ApplicationSamplerView view = getSamplerView(application);\n        if (view != null) {\n            DataSourceWindowManager.sharedInstance().selectView(view);\n            view.startCPU(CPUSamplerParameters.parse(settings));\n        }\n    }\n    \n    void startMemory(Application application, String settings) {\n        ApplicationSamplerView view = getSamplerView(application);\n        if (view != null) {\n            DataSourceWindowManager.sharedInstance().selectView(view);\n            view.startMemory(MemorySamplerParameters.parse(settings));\n        }\n    }\n    \n    void takeSnapshot(Application application, boolean openView) {\n        ApplicationSamplerView view = getSamplerView(application);\n        if (view != null) {\n            DataSourceWindowManager.sharedInstance().selectView(view);\n            view.takeSnapshot(openView);\n        }\n    }\n    \n    void stop(Application application) {\n        ApplicationSamplerView view = getSamplerView(application);\n        if (view != null) {\n            DataSourceWindowManager.sharedInstance().selectView(view);\n            view.stop();\n        }\n    }\n    \n    \n    private ApplicationSamplerView getSamplerView(Application application) {\n        if (application == null) return null;\n        DataSourceView activeView = samplerViewProvider.view(application);\n        if (activeView == null) return null;\n        return (ApplicationSamplerView)activeView;\n    }\n             \n    private SamplerSupport() {\n        samplerViewProvider = new ApplicationSamplerViewProvider();\n        samplerViewProvider.initialize();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/cpu/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_Cpu_settings=CPU settings\n\nLBL_Cpu_samples=CPU samples\n\nTOOLTIP_Pause_results=Pause live results\n\nTOOLTIP_Update_results=Update live results now\n\nLBL_Deltas=Deltas\n\nTOOLTIP_Deltas=Show delta values\n\nLBL_Snapshot=Snapshot\n\nTOOLTIP_Snapshot=Take snapshot of collected results\n\nLBL_Thread_dump=Thread Dump\n\nTOOLTIP_Thread_dump=Take thread dump\n\nLBL_No_data=<No Data>\n\nMSG_unavailable=Not available.\n\nMSG_unavailable_init_jmx=Not available. Cannot initialize JMX connection to target application. Use 'Add JMX Connection' action to attach to the application.\n\nMSG_unavailable_create_jmx=Not available. Failed to create JMX connection to target application. Use 'Add JMX Connection' action to attach to the application.\n\nMSG_unavailable_threads=Not available. Cannot access threads in target application. Check the VisualVM logfile ({0}).\n\nLBL_ThreadAlloc=Thread CPU time\n\nCOL_Thread_name=Name\n\nCOL_ABytes=Thread Time (CPU)\n\nCOL_ABytes_Sec=Thread Time (CPU) / sec\n\nLBL_Threads=<b>Threads: </b>{0}\n\nLBL_Thread_filter=Thread Name Filter\n\nLBL_CPUTime=<b>Total CPU Time [ms]: </b>{0}\n\nThreadsCPUView_TOOLTIP_Col_name=Thread name\nThreadsCPUView_TOOLTIP_Col_time=Total thread CPU time\nThreadsCPUView_TOOLTIP_Col_timesec=Thread CPU time in last 1 second\nThreadsCPUView_LBL_Statistics=Statistics\\:\nThreadsCPUView_LBL_TCount=Threads Count\\:\nThreadsCPUView_LBL_Total_time=Total Time (CPU)\\:\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/cpu/CCTFlattener.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.cpu;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.Stack;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNodeProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.MethodInfoMapper;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MethodCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.TimedCPUCCTNode;\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class CCTFlattener extends RuntimeCCTNodeProcessor.PluginAdapter {\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final Object containerGuard = new Object();\n\n    // @GuardedBy containerGuard\n    private FlatProfileContainer container;\n    private Stack<TotalTime> parentStack;\n    private Set<Integer> methodsOnStack;\n    private int[] invDiff;\n    private int[] invPM;\n    private int[] nCalleeInvocations;\n    private long[] timePM0;\n    private long[] timePM1;\n    private long[] totalTimePM0;\n    private long[] totalTimePM1;\n    private int nMethods;\n    private InstrumentationFilter instrFilter;\n    private boolean twoTimestamps;\n    private MethodInfoMapper methodInfoMapper;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    CCTFlattener(boolean twoStamps, MethodInfoMapper mapper, InstrumentationFilter f) {\n        parentStack = new Stack<>();\n        methodsOnStack = new HashSet<>();\n        nMethods = mapper.getMaxMethodId();\n        methodInfoMapper = mapper;\n        twoTimestamps = twoStamps;\n        instrFilter = f;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    FlatProfileContainer getFlatProfile() {\n        synchronized (containerGuard) {\n            return container;\n        }\n    }\n\n    public void onStop() {\n        // Now convert the data into microseconds\n        long wholeGraphTime0 = 0;\n\n        // Now convert the data into microseconds\n        long wholeGraphTime1 = 0;\n        long totalNInv = 0;\n\n        for (int i = 0; i < nMethods; i++) {\n            // convert to microseconds\n            double time = timePM0[i] / 1000.0;\n\n            if (time < 0) {\n                // in some cases the combination of cleansing the time by calibration and subtracting wait/sleep\n                // times can lead to <0 time\n                // see https://netbeans.org/bugzilla/show_bug.cgi?id=64416\n                time = 0;\n            }\n\n            timePM0[i] = (long) time;\n\n            // don't include the Thread time into wholegraphtime\n            if (i > 0) {\n                wholeGraphTime0 += time;\n            }\n\n            if (twoTimestamps) {\n                // convert to microseconds\n                time = timePM1[i] / 1000.0;\n                timePM1[i] = (long) time;\n\n                // don't include the Thread time into wholegraphtime\n                if (i > 0) {\n                    wholeGraphTime1 += time;\n                }\n            }\n\n            totalNInv += invPM[i];\n        }\n\n        synchronized (containerGuard) {\n            container = new FlatProfilerContainer(methodInfoMapper, twoTimestamps, timePM0, timePM1, totalTimePM0, totalTimePM1,\n                    invPM, new char[0], wholeGraphTime0, wholeGraphTime1, invPM.length);\n        }\n\n        timePM0 = timePM1 = null;\n        invPM = invDiff = nCalleeInvocations = null;\n        parentStack.clear();\n        methodsOnStack.clear();\n        instrFilter = null;\n    }\n\n    public void onStart() {\n        timePM0 = new long[nMethods];\n        timePM1 = new long[twoTimestamps ? nMethods : 0];\n        totalTimePM0 = new long[nMethods];\n        totalTimePM1 = new long[twoTimestamps ? nMethods : 0];\n        invPM = new int[nMethods];\n        invDiff = new int[nMethods];\n        nCalleeInvocations = new int[nMethods];\n        parentStack.clear();\n        methodsOnStack.clear();\n\n        synchronized (containerGuard) {\n            container = null;\n        }\n    }\n\n    public void onNode(MethodCPUCCTNode node) {\n        final int nodeMethodId = node.getMethodId();\n        final int nodeFilerStatus = node.getFilteredStatus();\n        final MethodCPUCCTNode currentParent = parentStack.isEmpty() ? null : parentStack.peek().parent;\n        boolean filteredOut = (nodeFilerStatus == TimedCPUCCTNode.FILTERED_YES); // filtered out by rootmethod/markermethod rules\n\n        if (!filteredOut) {\n            String jvmClassName = methodInfoMapper.getInstrMethodClass(nodeMethodId).replace('.', '/'); // NOI18N\n            filteredOut = !instrFilter.passes(jvmClassName);\n        }\n\n        final int parentMethodId = currentParent != null ? currentParent.getMethodId() : -1;\n\n        if (filteredOut) {\n            if ((currentParent != null) && !currentParent.isRoot()) {\n                invDiff[parentMethodId] += node.getNCalls();\n\n                timePM0[parentMethodId] += node.getNetTime0();\n\n                if (twoTimestamps) {\n                    timePM1[parentMethodId] += node.getNetTime1();\n                }\n            }\n        } else {\n            timePM0[nodeMethodId] += node.getNetTime0();\n\n            if (twoTimestamps) {\n                timePM1[nodeMethodId] += node.getNetTime1();\n            }\n\n            invPM[nodeMethodId] += node.getNCalls();\n\n            if ((currentParent != null) && !currentParent.isRoot()) {\n                nCalleeInvocations[parentMethodId] += node.getNCalls();\n            }\n        }\n        final MethodCPUCCTNode nextParent = filteredOut ? currentParent : node;\n        final TotalTime timeNode = new TotalTime(nextParent,methodsOnStack.contains(nodeMethodId));\n        timeNode.totalTimePM0+=node.getNetTime0();\n        if (twoTimestamps) timeNode.totalTimePM1+=node.getNetTime1();\n        if (!timeNode.recursive) {\n            methodsOnStack.add(nodeMethodId);\n        }\n        parentStack.push(timeNode);\n    }\n\n    public void onBackout(MethodCPUCCTNode node) {\n        TotalTime current = parentStack.pop();\n        if (!current.recursive) {\n            int nodeMethodId = node.getMethodId();\n            methodsOnStack.remove(nodeMethodId);\n            // convert to microseconds\n            double time = current.totalTimePM0 / 1000.0;\n            if (time>0) {\n                totalTimePM0[nodeMethodId]+=time;\n            }\n            if (twoTimestamps) {\n                time = current.totalTimePM1 / 1000.0;\n                if (time>0) {\n                    totalTimePM1[nodeMethodId]+=time;\n                }\n            }\n        }\n        // add self data to parent\n        if (!parentStack.isEmpty()) {\n            TotalTime parent = parentStack.peek();\n            parent.add(current);\n            parent.outCalls+=node.getNCalls();\n        }\n    }\n\n    private static class TotalTime {\n        private final MethodCPUCCTNode parent;\n        private final boolean recursive;\n        private int outCalls;\n        private long totalTimePM0;\n        private long totalTimePM1;\n\n        TotalTime(MethodCPUCCTNode n, boolean r) {\n            parent = n;\n            recursive = r;\n        }\n\n        private void add(TotalTime current) {\n            outCalls += current.outCalls;\n            totalTimePM0 += current.totalTimePM0;\n            totalTimePM1 += current.totalTimePM1;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/cpu/CPUSamplerParameters.java",
    "content": "/*\n * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.cpu;\n\nimport java.util.Map;\nimport java.util.Properties;\nimport org.graalvm.visualvm.sampler.SamplerParameters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class CPUSamplerParameters extends SamplerParameters {\n    \n    static final String INCLUDE_PACKAGES = \"include-classes\";                   // NOI18N\n    static final String EXCLUDE_PACKAGES = \"exclude-classes\";                   // NOI18N\n    static final String SAMPLING_RATE = \"sampling-rate\";                        // NOI18N\n    \n    \n    private CPUSamplerParameters(String parametersS) {\n        super(parametersS);\n    }\n    \n    \n    public static CPUSamplerParameters parse(String parameters) {\n        return new CPUSamplerParameters(parameters);\n    }\n\n    \n    @Override\n    protected void parseParameters(String parametersS, Map<String, String> parameters) {\n        if (parametersS.startsWith(FILE + \"=\")) {                               // NOI18N\n            // settings defined in file\n            parseParametersFile(decode(parametersS.substring(FILE.length() + 1)), parameters);\n        } else {\n            for (String parameter : parametersS.split(\",\")) {                   // NOI18N\n\n                // include-packages\n                int idx = parameter.indexOf(INCLUDE_PACKAGES + \"=\");            // NOI18N\n                if (idx == 0) parameters.put(INCLUDE_PACKAGES, decode(parameter.substring(INCLUDE_PACKAGES.length() + 1)));\n\n                // exclude-packages\n                idx = parameter.indexOf(EXCLUDE_PACKAGES + \"=\");                // NOI18N\n                if (idx == 0) parameters.put(EXCLUDE_PACKAGES, decode(parameter.substring(EXCLUDE_PACKAGES.length() + 1)));\n                \n                // sampling-rate\n                idx = parameter.indexOf(SAMPLING_RATE + \"=\");                   // NOI18N\n                if (idx == 0) parameters.put(SAMPLING_RATE, decode(parameter.substring(SAMPLING_RATE.length() + 1)));\n\n            }\n        }\n    }\n    \n    private void parseParametersFile(String file, Map<String, String> parameters) {\n        Properties properties = loadProperties(file);\n        \n        // include-packages\n        String prop = properties.getProperty(INCLUDE_PACKAGES);\n        if (prop != null) parameters.put(INCLUDE_PACKAGES, decode(prop));\n        \n        // exclude-packages\n        prop = properties.getProperty(EXCLUDE_PACKAGES);\n        if (prop != null) parameters.put(EXCLUDE_PACKAGES, decode(prop));\n        \n        // sampling-rate\n        prop = properties.getProperty(SAMPLING_RATE);\n        if (prop != null) parameters.put(SAMPLING_RATE, decode(prop));\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/cpu/CPUSamplerSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.cpu;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.sampler.AbstractSamplerSupport;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.DataOutputStream;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.lang.management.ThreadInfo;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.Timer;\nimport java.util.TimerTask;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.common.ProfilingSettingsPresets;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot.NoDataAvailableException;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.StackTraceSnapshotBuilder;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic abstract class CPUSamplerSupport extends AbstractSamplerSupport {\n    \n    private final Application application;\n\n    private final ThreadInfoProvider threadInfoProvider;\n    private final SnapshotDumper snapshotDumper;\n    private final ThreadDumper threadDumper;\n\n    private Timer timer;\n    private TimerTask samplerTask;\n    private final Refresher refresher;\n    private int refreshRate;\n\n    private StackTraceSnapshotBuilder builder;\n\n    private volatile boolean sampleRunning;\n    private final Object updateLock = new Object();\n    private long currentLiveUpdate;\n    private long lastLiveUpdate;\n\n    private CPUView cpuView;\n    private DataViewComponent.DetailsView[] detailsViews;\n\n    private javax.swing.Timer threadCPUTimer;\n    private Refresher threadCPURefresher;\n    private ThreadsCPUView threadCPUView;\n    private ThreadsCPU threadsCPU;\n\n    public CPUSamplerSupport(Application application, ThreadInfoProvider tip, ThreadsCPU tcpu, SnapshotDumper snapshotDumper, ThreadDumper threadDumper) {\n        this.application = application;\n        \n        threadInfoProvider = tip;\n        threadsCPU = tcpu;\n        this.snapshotDumper = snapshotDumper;\n        this.threadDumper = threadDumper;\n\n        refreshRate = GlobalPreferences.sharedInstance().getMonitoredDataPoll() * 1000;\n\n        refresher = new Refresher() {\n            public void setRefreshRate(int rr) {\n                CPUSamplerSupport.this.refreshRate = rr;\n            }\n            public int getRefreshRate() {\n                return CPUSamplerSupport.this.refreshRate;\n            }\n            protected boolean checkRefresh() {\n                return samplerTask != null && cpuView.isShowing();\n            }\n            protected void doRefresh() {\n                doRefreshImpl();\n            }\n        };\n        \n        if (threadsCPU != null) {\n            threadCPURefresher = new Refresher() {\n                public final boolean checkRefresh() {\n                    if (threadCPUTimer == null) return false;\n                    if (!threadCPUTimer.isRunning()) return false;\n                    return threadCPUView.isShowing();\n                }\n                public final void doRefresh() {\n                    doRefreshImpl(threadCPUTimer, threadCPUView);\n                }\n                public final void setRefreshRate(int refreshRate) {\n                    threadCPUTimer.setDelay(refreshRate);\n                    threadCPUTimer.setInitialDelay(refreshRate);\n                    threadCPUTimer.restart();\n                }\n                public final int getRefreshRate() {\n                    return threadCPUTimer.getDelay();\n                }\n            };\n        }\n    }\n\n\n    public DataViewComponent.DetailsView[] getDetailsView() {\n        if (detailsViews == null) {\n            cpuView = new CPUView(refresher, snapshotDumper, threadDumper, application);\n            detailsViews = new DataViewComponent.DetailsView[threadsCPU != null ? 2:1];\n            detailsViews[0] = new DataViewComponent.DetailsView(NbBundle.getMessage(\n                CPUSamplerSupport.class, \"LBL_Cpu_samples\"), null, 10, cpuView, null); // NOI18N\n            if (threadsCPU != null) {\n                threadCPUView = new ThreadsCPUView(threadCPURefresher, threadDumper);\n                detailsViews[1] = new DataViewComponent.DetailsView(NbBundle.getMessage(\n                CPUSamplerSupport.class, \"LBL_ThreadAlloc\"), null, 20, threadCPUView, null); // NOI18N\n                \n            }\n        }\n        cpuView.initSession();\n        if (threadsCPU != null) {\n            threadCPUView.initSession();\n        }\n        return detailsViews.clone();\n    }\n\n    public boolean startSampling(ProfilingSettings settings, int samplingRate, int refreshRate) {\n        checkCPUSamplingRate(samplingRate);\n        \n        GenericFilter sf = settings.getInstrumentationFilter();\n        InstrumentationFilter filter = new InstrumentationFilter(sf);\n        builder = snapshotDumper.getNewBuilder(filter, samplingRate);\n        \n        refresher.setRefreshRate(refreshRate);\n\n        final StackTraceSnapshotBuilder _builder = builder;\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (cpuView != null) {\n                    cpuView.setBuilder(_builder);\n                    cpuView.starting();\n                }\n                if (threadCPUView != null) threadCPUView.starting();\n            }\n        });\n\n        if (timer == null) timer = getTimer();\n        samplerTask = new SamplerTask(builder);\n\n        timer.scheduleAtFixedRate(samplerTask, 0, samplingRate);\n        \n        if (threadsCPU != null) {\n            threadCPUTimer = new javax.swing.Timer(refreshRate, new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    threadCPURefresher.refresh();\n                }\n            });\n            threadCPURefresher.setRefreshRate(refreshRate);\n        }\n        return true;\n    }\n    \n    public void takeSnapshot(boolean openView) {\n        snapshotDumper.takeSnapshot(openView);\n    }\n\n    public synchronized void stopSampling() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (cpuView != null) cpuView.stopping();\n                if (threadCPUView != null) threadCPUView.stopping();\n            }\n        });\n        \n        if (samplerTask != null) {\n            samplerTask.cancel();\n            samplerTask = null;\n        }\n        if (threadCPUTimer != null) {\n            threadCPUTimer.stop();\n            threadCPUTimer = null;\n        }\n    }\n\n    public synchronized void terminate() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (cpuView != null) cpuView.terminated();\n                if (threadCPUView != null) threadCPUView.terminated();\n            }\n        });\n        \n        if (timer != null) {\n            timer.cancel();\n            timer = null;\n        }\n        \n        builder = null;  // release data\n    }\n\n\n    private void doRefreshImpl() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (samplerTask == null) return;\n                if (!sampleRunning) {\n                    synchronized (updateLock) {\n                        lastLiveUpdate = currentLiveUpdate;\n                        cpuView.refresh();\n                    }\n                } else {\n                    SwingUtilities.invokeLater(this);\n                }\n            }\n        });\n    }\n    private void doRefreshImpl(final javax.swing.Timer stimer, final ThreadsCPUView view) {\n        if (!stimer.isRunning() || view.isPaused()) return;\n        \n        try {\n            timer.schedule(new TimerTask() {\n                public void run() {\n                    try {\n                        if (!stimer.isRunning()) return;\n                        doRefreshImplImpl(threadsCPU.getThreadsCPUInfo(), view);\n                    } catch (Exception e) {\n                        terminate();\n                    }\n                }\n            }, 0);\n        } catch (Exception e) {\n            terminate();\n        }\n    }\n    \n    private void doRefreshImplImpl(final ThreadsCPUInfo info, final ThreadsCPUView view) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    view.refresh(info);\n                }\n            });\n    }\n\n    private class SamplerTask extends TimerTask {\n\n        private final StackTraceSnapshotBuilder builder;\n        private final Set<String> samplingThreads = new HashSet<>();\n\n        SamplerTask(StackTraceSnapshotBuilder builder) {\n            this.builder = builder;\n        }\n\n        public void run() {\n            if (sampleRunning) return;\n            sampleRunning = true;\n            synchronized (updateLock) {\n                try {\n                    ThreadInfo[] infos = threadInfoProvider.dumpAllThreads();\n                    long timestamp = System.nanoTime();\n                    String samplingThreadName = findSamplingThread(infos);\n                    if (samplingThreadName != null) {\n                        if (samplingThreads.add(samplingThreadName)) {\n//                                System.out.println(\"New ignored thread: \"+samplingThreadName);\n                            builder.setIgnoredThreads(samplingThreads);\n                        }\n                    }\n                    builder.addStacktrace(infos, timestamp);\n\n                    currentLiveUpdate = timestamp / 1000000;\n                    if (currentLiveUpdate - lastLiveUpdate >= refreshRate)\n                        refresher.refresh();\n\n                } catch (Throwable ex) {\n                    terminate();\n                } finally {\n                    sampleRunning = false;\n                }\n            }\n        }\n\n        private String findSamplingThread(ThreadInfo[] infos) {\n//                for (ThreadInfo info : infos) {\n//                    if (info.getThreadState() == Thread.State.RUNNABLE) {\n//                        StackTraceElement[] stack = info.getStackTrace();\n//\n//                        if (stack.length > 0) {\n//                            StackTraceElement topStack = stack[0];\n//\n//                            if (!topStack.isNativeMethod()) {\n//                                continue;\n//                            }\n//                            if (!\"sun.management.ThreadImpl\".equals(topStack.getClassName())) {  // NOI18N\n//                                continue;\n//                            }\n//                            if (\"getThreadInfo0\".equals(topStack.getMethodName())) {\n//                                return info.getThreadName();\n//                            }\n//                        }\n//                    }\n//                }\n            return null;\n        }\n    }\n    \n    public static abstract class ThreadDumper {\n        public abstract void takeThreadDump(boolean openView);\n    }\n\n    public static abstract class SnapshotDumper {\n        private StackTraceSnapshotBuilder builder;\n        private int samplingRate;\n                \n        StackTraceSnapshotBuilder getNewBuilder(InstrumentationFilter filter, int sampling) {\n            builder = new StackTraceSnapshotBuilder(1,filter);\n            samplingRate = sampling;\n            return builder;\n        }\n        \n        public final LoadedSnapshot takeNPSSnapshot(File directory) throws IOException, NoDataAvailableException {\n            if (builder == null) throw new IllegalStateException(\"Builder is null\"); // NOI18N\n            long time = System.currentTimeMillis();\n            CPUResultsSnapshot snapshot = builder.createSnapshot(time);\n            ProfilingSettings settings = ProfilingSettingsPresets.createCPUPreset();\n            settings.setInstrumentationFilter(builder.getFilter());\n            settings.setSamplingFrequency(samplingRate);\n            LoadedSnapshot ls = new LoadedSnapshot(snapshot, settings, null, null);\n            File file = Utils.getUniqueFile(directory,\n                    ResultsManager.getDefault().getDefaultSnapshotFileName(ls),\n                    \".\" + ResultsManager.SNAPSHOT_EXTENSION); // NOI18N\n            try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(file))) {\n                ls.save(dos);\n                ls.setFile(file);\n                ls.setSaved(true);\n            }\n            return ls;\n        }\n\n        public abstract void takeSnapshot(boolean openView);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/cpu/CPUSettingsSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.cpu;\n\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.profiling.presets.PresetSelector;\nimport org.graalvm.visualvm.profiling.presets.SamplerCPUPanel;\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPreset;\nimport org.graalvm.visualvm.sampler.SamplerParameters;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class CPUSettingsSupport {\n    \n    private static final Logger LOGGER = Logger.getLogger(CPUSettingsSupport.class.getName());\n    \n    \n    private JPanel container;\n    private SamplerCPUPanel panel;\n    private PresetSelector selector;\n    \n    private DataViewComponent.DetailsView detailsView;\n    \n    private ProfilerPreset requestedPreset;\n    \n    \n    public DataViewComponent.DetailsView getDetailsView() {\n        if (detailsView == null) {\n            detailsView = new DataViewComponent.DetailsView(NbBundle.getMessage(\n                          CPUSettingsSupport.class, \"LBL_Cpu_settings\"), null, 10, // NOI18N\n                          new ScrollableContainer(createPanel()), null);\n        }\n        return detailsView;\n    }\n    \n    \n    public void setSettings(SamplerParameters settings) {\n        ProfilerPreset preset = createPreset(settings);\n        if (panel != null) {\n            panel.loadFromPreset(preset);\n            selector.customize(presetValid());\n        } else {\n            requestedPreset = preset;\n        }\n    }\n    \n    public ProfilingSettings getSettings() { return panel.getSettings(); }\n\n    public int getSamplingRate() { return panel.getSamplingRate(); }\n    \n    public int getRefreshRate() { return panel.getRefreshRate(); }\n    \n    public void saveSettings() {\n        // NOTE: might save custom configuration here\n    }\n    \n    public abstract boolean presetValid();\n    \n    public boolean settingsValid() { return panel.settingsValid(); }\n    \n    public void showSettings(DataViewComponent dvc) {\n        dvc.selectDetailsView(getDetailsView());\n    }\n    \n    public abstract PresetSelector createSelector(Runnable presetSynchronizer);\n    \n    \n    public void setEnabled(boolean enabled) {\n        if (container != null) container.setEnabled(enabled);\n    }\n    \n    private JPanel createPanel() {\n        panel = new SamplerCPUPanel() {\n            public void settingsChanged() {\n                panel.saveToPreset(selector.customize(presetValid()));\n            }\n        };\n        \n        selector = createSelector(new Runnable() {\n            public void run() { panel.loadFromPreset(selector.getSelectedPreset()); }\n        });\n        selector.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));\n        \n        container = new JPanel(new BorderLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents()) c.setEnabled(enabled);\n            }\n        };\n        container.setOpaque(false);\n        container.add(panel, BorderLayout.CENTER);\n        container.add(selector, BorderLayout.SOUTH);\n        \n        if (requestedPreset != null) {\n            panel.loadFromPreset(requestedPreset);\n            selector.customize(presetValid());\n            requestedPreset = null;\n        }\n        \n        return container;\n    }\n    \n    \n    private static ProfilerPreset createPreset(SamplerParameters settings) {\n        ProfilerPreset preset = new ProfilerPreset(\"Forced CPU Settings\", \"\");  // NOI18N\n        \n        String includePackages = settings.get(CPUSamplerParameters.INCLUDE_PACKAGES);\n        if (includePackages != null) {\n            preset.setFilterS(includePackages);\n            preset.setFilterModeS(false);\n        } else {\n            String excludePackages = settings.get(CPUSamplerParameters.EXCLUDE_PACKAGES);\n            if (excludePackages != null) {\n                preset.setFilterS(excludePackages);\n                preset.setFilterModeS(true);\n            }\n        }\n        \n        String refresh = settings.get(CPUSamplerParameters.SAMPLING_RATE);\n        if (refresh != null) {\n            try { preset.setSamplingRateS(Integer.parseInt(refresh)); }\n            catch (NumberFormatException e) { LOGGER.log(Level.WARNING, \"Failed to read Sampler \" + CPUSamplerParameters.SAMPLING_RATE, e); } // NOI18N\n        }\n        \n        return preset;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/cpu/CPUView.java",
    "content": "/*\n * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.cpu;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.profiling.actions.ProfilerResultsAction;\nimport org.graalvm.visualvm.sampler.AbstractSamplerSupport;\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.ItemEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.AbstractButton;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.Icon;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.StackTraceSnapshotBuilder;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.cpu.LiveCPUView;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.MultiButtonGroup;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.profiler.actions.TakeSnapshotAction;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n//    \"MethodsFeatureUI_viewHotSpots=Hot spots\",\n//    \"MethodsFeatureUI_viewCallTree=Call tree\",\n//    \"MethodsFeatureUI_viewCombined=Combined\",\n    \"MethodsFeatureUI_selectedMethods=Selected methods\",\n    \"MethodsFeatureUI_liveResults=Results:\",\n    \"MethodsFeatureUI_pauseResults=Pause live results\",\n    \"MethodsFeatureUI_updateResults=Update live results\",\n    \"MethodsFeatureUI_view=View:\",\n    \"MethodsFeatureUI_viewForward=Forward calls\",\n    \"MethodsFeatureUI_viewHotSpots=Hot spots\",\n    \"MethodsFeatureUI_viewReverse=Reverse calls\",\n    \"MethodsFeatureUI_resultsMode=Results mode\",\n    \"MethodsFeatureUI_profilingData=Collected data:\",\n    \"MethodsFeatureUI_snapshot=Snapshot\",\n    \"MethodsFeatureUI_showAbsolute=Show absolute values\",\n    \"MethodsFeatureUI_showDeltas=Show delta values\"\n})\nfinal class CPUView extends JPanel {\n    \n    private final AbstractSamplerSupport.Refresher refresher;\n    private boolean forceRefresh = false;\n    \n    private final CPUSamplerSupport.SnapshotDumper snapshotDumper;\n    private final CPUSamplerSupport.ThreadDumper threadDumper;\n    \n    private StackTraceSnapshotBuilder builder;\n\n    private ProfilerToolbar toolbar;\n    private LiveCPUView cpuView;\n\n\n    CPUView(AbstractSamplerSupport.Refresher refresher, CPUSamplerSupport.SnapshotDumper\n            snapshotDumper, CPUSamplerSupport.ThreadDumper threadDumper, Application application) {\n        this.refresher = refresher;\n        this.snapshotDumper = snapshotDumper;\n        this.threadDumper = threadDumper;\n        \n        initComponents(application);\n\n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (isShowing()) CPUView.this.refresher.refresh();\n                }\n            }\n        });\n    }\n\n    \n    void setBuilder(StackTraceSnapshotBuilder builder) {\n        this.builder = builder;\n    }\n\n    void initSession() {\n        pdSnapshotButton.setEnabled(false);\n//        pdResetResultsButton.setEnabled(false);\n    }\n\n    void refresh() {\n        if (!isShowing() || (lrPauseButton.isSelected() && !forceRefresh)) return;\n        forceRefresh = false;\n        \n        try {\n            // TODO: perform out of the EDT!\n            CPUResultsSnapshot snapshot = builder.createSnapshot(System.currentTimeMillis());\n            cpuView.setData(snapshot, true);\n        } catch (CPUResultsSnapshot.NoDataAvailableException ex) {\n            // no problem, just no data matching the provided filter yet\n//            Exceptions.printStackTrace(ex);\n        }\n\n        pdSnapshotButton.setEnabled(snapshotDumper != null);\n//        pdResetResultsButton.setEnabled(pdSnapshotButton.isEnabled());\n    }\n    \n    void starting() {\n        lrPauseButton.setEnabled(true);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(true);\n        cpuView.resetData();\n    }\n    \n    void stopping() {\n        lrPauseButton.setEnabled(false);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(false);\n    }\n    \n    void terminated() {\n        lrPauseButton.setEnabled(false);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(false);\n        threaddumpButton.setEnabled(false);\n    }\n\n//    void terminate() {\n//        lrPauseButton.setEnabled(false);\n//        lrRefreshButton.setEnabled(false);\n//        threaddumpButton.setEnabled(false);\n//    }\n\n    \n    private JLabel lrLabel;\n    private JToggleButton lrPauseButton;\n    private JButton lrRefreshButton;\n    private JToggleButton lrDeltasButton;\n    \n    private JLabel pdLabel;\n    private JButton pdSnapshotButton;\n//    private JButton pdResetResultsButton;\n    \n    private boolean popupPause;\n    private JToggleButton[] toggles;\n    \n    private AbstractButton threaddumpButton;\n\n    private void initComponents(Application application) {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n        \n        \n        cpuView = new LiveCPUView(null) {\n            protected boolean showSourceSupported() {\n                return GoToSource.isAvailable();\n            }\n            protected boolean profileMethodSupported() {\n                return false;\n            }\n            protected boolean profileClassSupported() {\n                return false;\n            }\n            protected void showSource(ClientUtils.SourceCodeSelection value) {\n//                Lookup.Provider project = getProject();\n                Lookup.Provider project = null;\n                String className = value.getClassName();\n                String methodName = value.getMethodName();\n                String methodSig = value.getMethodSignature();\n                GoToSource.openSource(project, className, methodName, methodSig);\n            }\n            protected void selectForProfiling(ClientUtils.SourceCodeSelection value) {\n//                MethodsFeatureUI.this.selectForProfiling(value);\n            }\n            protected void popupShowing() {\n                if (lrPauseButton.isEnabled() && !lrRefreshButton.isEnabled()) {\n                    popupPause = true;\n                    lrPauseButton.setSelected(true);\n                }\n            }\n            protected void popupHidden() {\n                if (lrPauseButton.isEnabled() && popupPause) {\n                    popupPause = false;\n                    lrPauseButton.setSelected(false);\n                }\n            }\n            protected void foundInForwardCalls() {\n                super.foundInForwardCalls();\n                toggles[0].setSelected(true);\n            }\n            protected void foundInHotSpots() {\n                super.foundInHotSpots();\n                toggles[1].setSelected(true);\n            }\n            protected void foundInReverseCalls() {\n                super.foundInReverseCalls();\n                toggles[2].setSelected(true);\n            }\n        };\n        cpuView.putClientProperty(ProfilerResultsAction.PROP_APPLICATION, application);\n        \n        InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        ActionMap actionMap = getActionMap();\n        \n        final String filterKey = FilterUtils.FILTER_ACTION_KEY;\n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                Action action = cpuView.getActionMap().get(filterKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);\n        \n        final String findKey = SearchUtils.FIND_ACTION_KEY;\n        Action findAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                Action action = cpuView.getActionMap().get(findKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(findKey, findAction, actionMap, inputMap);\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        lrLabel = new GrayLabel(Bundle.MethodsFeatureUI_liveResults());\n            \n        lrPauseButton = new JToggleButton(Icons.getIcon(GeneralIcons.PAUSE)) {\n            protected void fireItemStateChanged(ItemEvent event) {\n                boolean paused = lrPauseButton.isSelected();\n                lrRefreshButton.setEnabled(paused && !popupPause);\n                if (!paused) refresher.refresh();\n            }\n        };\n        lrPauseButton.setToolTipText(Bundle.MethodsFeatureUI_pauseResults());\n//        lrPauseButton.setEnabled(false);\n\n        lrRefreshButton = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                forceRefresh = true;\n                refresher.refresh();\n            }\n        };\n        lrRefreshButton.setToolTipText(Bundle.MethodsFeatureUI_updateResults());\n        lrRefreshButton.setEnabled(false);\n        \n        Icon icon = Icons.getIcon(ProfilerIcons.DELTA_RESULTS);\n        lrDeltasButton = new JToggleButton(icon) {\n            protected void fireActionPerformed(ActionEvent e) {\n                if (!cpuView.setDiffView(isSelected())) setSelected(false);\n                setToolTipText(isSelected() ? Bundle.MethodsFeatureUI_showAbsolute() :\n                                              Bundle.MethodsFeatureUI_showDeltas());\n            }\n        };\n        lrDeltasButton.setToolTipText(Bundle.MethodsFeatureUI_showDeltas());\n        \n        MultiButtonGroup group = new MultiButtonGroup();\n        toggles = new JToggleButton[3];\n        \n        JToggleButton forwardCalls = new JToggleButton(Icons.getIcon(ProfilerIcons.NODE_FORWARD)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                cpuView.setView(isSelected(), toggles[1].isSelected(), toggles[2].isSelected());\n                refresh();\n            }\n        };\n        forwardCalls.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        forwardCalls.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        forwardCalls.setToolTipText(Bundle.MethodsFeatureUI_viewForward());\n        group.add(forwardCalls);\n        toggles[0] = forwardCalls;\n        forwardCalls.setSelected(true);\n        \n        JToggleButton hotSpots = new JToggleButton(Icons.getIcon(ProfilerIcons.TAB_HOTSPOTS)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                cpuView.setView(toggles[0].isSelected(), isSelected(), toggles[2].isSelected());\n                refresh();\n            }\n        };\n        hotSpots.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        hotSpots.putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n        hotSpots.setToolTipText(Bundle.MethodsFeatureUI_viewHotSpots());\n        group.add(hotSpots);\n        toggles[1] = hotSpots;\n        hotSpots.setSelected(false);\n        \n        JToggleButton reverseCalls = new JToggleButton(Icons.getIcon(ProfilerIcons.NODE_REVERSE)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                cpuView.setView(toggles[0].isSelected(), toggles[1].isSelected(), isSelected());\n                refresh();\n            }\n        };\n        reverseCalls.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        reverseCalls.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n        reverseCalls.setToolTipText(Bundle.MethodsFeatureUI_viewReverse());\n        group.add(reverseCalls);\n        toggles[2] = reverseCalls;\n        reverseCalls.setSelected(false);\n\n        pdLabel = new GrayLabel(Bundle.MethodsFeatureUI_profilingData());\n\n        pdSnapshotButton = new JButton(TakeSnapshotAction.getInstance()) {\n            protected void fireActionPerformed(ActionEvent event) {\n                snapshotDumper.takeSnapshot((event.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n            }\n        };\n//        pdSnapshotButton.setHideActionText(true);\n        pdSnapshotButton.setText(Bundle.MethodsFeatureUI_snapshot());\n        pdSnapshotButton.putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n\n//        pdResetResultsButton = new JButton(ResetResultsAction.getInstance());\n//        pdResetResultsButton.setHideActionText(true);\n\n        toolbar = ProfilerToolbar.create(true);\n\n//        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(lrLabel);\n        toolbar.addSpace(2);\n        toolbar.add(lrPauseButton);\n        toolbar.add(lrRefreshButton);\n        \n        toolbar.addSpace(5);\n        toolbar.add(lrDeltasButton);\n        \n        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n        toolbar.addSpace(5);\n        \n        toolbar.add(new GrayLabel(Bundle.MethodsFeatureUI_view()));\n        toolbar.addSpace(2);\n        toolbar.add(forwardCalls);\n        toolbar.add(hotSpots);\n        toolbar.add(reverseCalls);\n        \n        toolbar.addSpace(5);\n        toolbar.add(cpuView.createThreadSelector());\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(pdLabel);\n        toolbar.addSpace(2);\n        toolbar.add(pdSnapshotButton);\n//        toolbar.addSpace(3);\n//        toolbar.add(pdResetResultsButton);\n        \n        toolbar.addFiller();\n        \n        threaddumpButton = new JButton(NbBundle.getMessage(CPUView.class, \"LBL_Thread_dump\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent event) {\n                threadDumper.takeThreadDump((event.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n            }\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.width += 5;\n                return dim;\n            }\n        };\n        threaddumpButton.setToolTipText(NbBundle.getMessage(CPUView.class, \"TOOLTIP_Thread_dump\")); // NOI18N\n        threaddumpButton.setOpaque(false);\n        threaddumpButton.setEnabled(threadDumper != null);\n        toolbar.add(threaddumpButton);\n        \n        \n        cpuView.setView(true, false, false);\n        \n        \n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        add(cpuView, BorderLayout.CENTER);\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/cpu/FlatProfileBuilder.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNodeProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.RuntimeCPUCCTNode;\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class FlatProfileBuilder implements FlatProfileProvider {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n    \n    private FlatProfileContainer lastFlatProfile = null;\n    private RuntimeCPUCCTNode appNode;\n    private CCTFlattener cctFlattener;\n    \n    \n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    FlatProfileBuilder(RuntimeCPUCCTNode node, CCTFlattener flattener) {\n        appNode = node;\n        cctFlattener = flattener;\n    }\n    \n    public synchronized FlatProfileContainer createFlatProfile() {\n        if (appNode == null) {\n            return null;\n        }\n//        client.getStatus().beginTrans(false);\n\n        try {\n            RuntimeCCTNodeProcessor.process(\n                appNode, \n                cctFlattener\n            );\n\n            lastFlatProfile = cctFlattener.getFlatProfile();\n\n        } finally {\n//            client.getStatus().endTrans();\n        }\n\n        return lastFlatProfile;\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/cpu/FlatProfilerContainer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.MethodInfoMapper;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatter;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatterFactory;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class FlatProfilerContainer extends FlatProfileContainer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected double wholeGraphNetTime0;\n    protected double wholeGraphNetTime1;\n    private MethodInfoMapper methodInfoMapper;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * The data passed to this constructor may contain some zero-invocation rows. That's because the size of passed arrays\n     * is equal to the number of currently instrumented methods, but in general not all of the methods may be invoked even\n     * once at an arbitrary moment.\n     *\n     * @param timeInMcs0         Array of Absolute timer values for each method - always used\n     * @param timeInMcs1         Array of CPU timer values for each method - optional, may be null\n     * @param totalTimeInMcs0   Array of Absolute timer (total time) values for each method - always used\n     * @param totalTimeInMcs1   Array of CPU timer (total time) values for each method - optional, may be null\n     * @param nInvocations       Array of number of invocations for each method\n     * @param wholeGraphNetTime0 Total absolute time\n     * @param wholeGraphNetTime1 Total CPU time - not used if CPU timer is not used\n     * @param nMethods           Total number of profiled methods - length of the provided arrays\n     */\n    FlatProfilerContainer(MethodInfoMapper mapper,boolean twoStamps,long[] timeInMcs0, long[] timeInMcs1, \n                                    long[] totalTimeInMcs0, long[] totalTimeInMcs1,int[] nInvocations,\n                                    char[] marks, double wholeGraphNetTime0, double wholeGraphNetTime1, int nMethods) {\n        super(timeInMcs0, timeInMcs1, totalTimeInMcs0, totalTimeInMcs1, nInvocations, marks, nMethods);\n        this.wholeGraphNetTime0 = wholeGraphNetTime0;\n        this.wholeGraphNetTime1 = wholeGraphNetTime1;\n\n        collectingTwoTimeStamps = twoStamps;\n        methodInfoMapper = mapper;\n\n        // Now get rid of zero-invocation entries once and forever. Also set nTotalInvocations and set negative times\n        // (that may be possible due to time cleansing inaccuracies) to zero.\n        removeZeroInvocationEntries();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getMethodNameAtRow(int row) {\n        int methodId = methodIds[row];\n        MethodNameFormatter formatter = MethodNameFormatterFactory.getDefault().getFormatter(null);\n\n        String className = methodInfoMapper.getInstrMethodClass(methodId);\n        String methodName = methodInfoMapper.getInstrMethodName(methodId);\n        String signature = methodInfoMapper.getInstrMethodSignature(methodId);\n\n        return formatter.formatMethodName(className, methodName, signature).toFormatted();\n    }\n\n    public double getWholeGraphNetTime0() {\n        return wholeGraphNetTime0;\n    }\n\n    public double getWholeGraphNetTime1() {\n        return wholeGraphNetTime1;\n    }\n\n    @Override\n    public ClientUtils.SourceCodeSelection getSourceCodeSelectionAtRow(int i) {\n        throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/cpu/SampledLivePanel.java",
    "content": "/*\n *  Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.sampler.cpu;\n\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.MethodInfoMapper;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.StackTraceSnapshotBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.RuntimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.ui.cpu.CPUResUserActionsHandler;\nimport org.graalvm.visualvm.lib.ui.cpu.LiveFlatProfileCollectorPanel;\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class SampledLivePanel extends LiveFlatProfileCollectorPanel {\n    private MethodInfoMapper methodInfoMapper;\n    private StackTraceSnapshotBuilder snapshotBuilder;\n    \n    SampledLivePanel(StackTraceSnapshotBuilder builder) {\n        super(null,new DummyHandler(),null,true);\n        methodInfoMapper = builder.getMapper();\n        snapshotBuilder = builder;\n    }\n    \n    public FlatProfileProvider getFlatProfileProvider() {\n        InstrumentationFilter filter = snapshotBuilder.getFilter();\n        boolean twoTimeStamps = snapshotBuilder.collectionTwoTimeStamps();\n        CCTFlattener flattener = new CCTFlattener(twoTimeStamps,methodInfoMapper,filter);\n        RuntimeCPUCCTNode rootNode = (RuntimeCPUCCTNode) snapshotBuilder.getAppRootNode();\n        return new FlatProfileBuilder(rootNode, flattener);\n    }\n\n    protected String[] getMethodClassNameAndSig(int methodId, int currentView) {\n        String className = methodInfoMapper.getInstrMethodClass(methodId);\n\n        if (currentView == CPUResultsSnapshot.METHOD_LEVEL_VIEW) {\n            String methodName = methodInfoMapper.getInstrMethodName(methodId);\n            String methodSig = methodInfoMapper.getInstrMethodSignature(methodId);\n\n            return new String[] { className, methodName, methodSig };\n        }\n\n        return new String[] { className, null, null };\n    }\n\n    protected void obtainResults() {\n        super.obtainResults();\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                resTable.createDefaultColumnsFromModel();\n                resTableModel.setTable(resTable);\n                setColumnsData();\n            }\n        });\n    }\n\n    private void setColumnsData() {\n        TableColumnModel colModel = resTable.getColumnModel();\n        for (int i = 0; i < resTableModel.getColumnCount(); i++) {\n            int index = resTableModel.getRealColumn(i);\n            if (index != 0)\n                colModel.getColumn(i).setPreferredWidth(columnWidths[index - 1]);\n            colModel.getColumn(i).setCellRenderer(columnRenderers[index]);\n        }\n    }\n    \n    private static final class DummyHandler extends CPUResUserActionsHandler.Adapter {\n\n        public void addMethodToRoots(final String className, final String methodName, final String methodSig) {\n            throw new IllegalStateException(\"addMethodToRoots\");    // NOI18N\n        }\n\n        public void showReverseCallGraph(final CPUResultsSnapshot snapshot, final int threadId, final int methodId, int view,\n                                         int sortingColumn, boolean sortingOrder) {\n            throw new IllegalStateException(\"showReverseCallGraph\");    // NOI18N\n        }\n\n        public void showSourceForMethod(final String className, final String methodName, final String methodSig) {\n            // no-op\n        }\n\n        public void viewChanged(int viewType) {\n            throw new IllegalStateException(\"viewChanged\"); // NOI18N\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/cpu/ThreadInfoProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.cpu;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport java.lang.management.ThreadInfo;\nimport java.lang.management.ThreadMXBean;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic final class ThreadInfoProvider {\n\n    private static final Logger LOGGER = Logger.getLogger(ThreadInfoProvider.class.getName());\n    \n    final private String status;\n    private boolean useGetThreadInfo;\n    private ThreadMXBean threadBean;\n    \n    public ThreadInfoProvider(Application app) {\n        status = initialize(app);\n    }\n\n    public String getStatus() {\n        return status;\n    }\n\n    public ThreadMXBean getThreadMXBean() {\n        return threadBean;\n    }\n    \n    private String initialize(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) {\n            return NbBundle.getMessage(ThreadInfoProvider.class, \"MSG_unavailable\"); // NOI18N\n        }\n        JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);\n        if (jmxModel == null) {\n            return NbBundle.getMessage(ThreadInfoProvider.class, \"MSG_unavailable_init_jmx\"); // NOI18N\n        }\n        if (jmxModel.getConnectionState() != JmxModel.ConnectionState.CONNECTED) {\n           return NbBundle.getMessage(ThreadInfoProvider.class, \"MSG_unavailable_create_jmx\"); // NOI18N\n        }\n        JvmMXBeans mxbeans = jmxModel.getJvmMXBeans();\n        if (mxbeans == null) {\n            LOGGER.log(Level.INFO, \"jmxModel.getJvmMXBeans() returns null for \" + application); // NOI18N\n            return NbBundle.getMessage(ThreadInfoProvider.class, \"MSG_unavailable_threads\", VisualVM.getInstance().getLogfileHandle()); // NOI18N\n        }\n        threadBean = mxbeans.getThreadMXBean();\n        if (threadBean == null) {\n            LOGGER.log(Level.INFO, \"mxbeans.getThreadMXBean() returns null for \" + application); // NOI18N\n            return NbBundle.getMessage(ThreadInfoProvider.class, \"MSG_unavailable_threads\", VisualVM.getInstance().getLogfileHandle()); // NOI18N\n        }\n        useGetThreadInfo = JvmFactory.getJVMFor(application).is15();\n        try {\n            dumpAllThreads();\n        } catch (SecurityException e) {\n            LOGGER.log(Level.INFO, \"threadBean.getThreadInfo(ids, maxDepth) throws SecurityException for \" + application, e); // NOI18N\n            return NbBundle.getMessage(ThreadInfoProvider.class, \"MSG_unavailable_threads\", VisualVM.getInstance().getLogfileHandle()); // NOI18N\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"threadBean.getThreadInfo(ids, maxDepth) throws Throwable for \" + application, t); // NOI18N\n            return NbBundle.getMessage(ThreadInfoProvider.class, \"MSG_unavailable_threads\", VisualVM.getInstance().getLogfileHandle()); // NOI18N\n        }\n        return null;\n    }\n\n    ThreadInfo[] dumpAllThreads() {\n        if (useGetThreadInfo) {\n            return threadBean.getThreadInfo(threadBean.getAllThreadIds(), Integer.MAX_VALUE);\n        }\n        return threadBean.dumpAllThreads(false,false);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/cpu/ThreadsCPU.java",
    "content": "/*\n * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.cpu;\n\nimport java.io.IOException;\nimport java.lang.management.ManagementFactory;\nimport java.lang.management.ThreadInfo;\nimport java.lang.management.ThreadMXBean;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.MBeanException;\nimport javax.management.MBeanServerConnection;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\nimport javax.management.ReflectionException;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class ThreadsCPU {\n    private static final ObjectName THREAD_NAME = getThreadName();\n    private static final Logger LOGGER = Logger.getLogger(ThreadsCPU.class.getName());\n    \n    private final ThreadMXBean threadBean;\n    private final MBeanServerConnection connection;\n    private boolean useBulkOperation = true;\n\n    public ThreadsCPU(ThreadMXBean bean, MBeanServerConnection conn) {\n        threadBean = bean;\n        connection = conn;\n    }\n    \n    public ThreadsCPUInfo getThreadsCPUInfo() throws MBeanException, ReflectionException, IOException, InstanceNotFoundException {\n        long[] ids = threadBean.getAllThreadIds();\n        ThreadInfo[] tids = threadBean.getThreadInfo(ids);\n        long[] tinfo;\n\n        if (useBulkOperation) {\n            Object[] args = new Object[] {ids};\n            String[] sigs = new String[] {\"[J\"};  // NOI18N\n\n            try {\n                tinfo = (long[])connection.invoke(THREAD_NAME, \"getThreadCpuTime\", args, sigs);  // NOI18N\n            } catch (javax.management.ReflectionException ex) {\n                LOGGER.log(Level.INFO, \"getThreadCpuTime failed\", ex);\n                useBulkOperation = false;\n                return getThreadsCPUInfo();\n            }\n        } else {\n            tinfo = new long[ids.length];\n\n            for (int i = 0; i < ids.length; i++) {\n                tinfo[i] = threadBean.getThreadCpuTime(ids[i]);\n            }\n        }\n        long time = System.currentTimeMillis();\n        \n        return new ThreadsCPUInfo(time,tids,tinfo);\n    }   \n\n    private static ObjectName getThreadName() {\n        try {\n            return new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME);\n        } catch (MalformedObjectNameException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/cpu/ThreadsCPUInfo.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.cpu;\n\nimport java.lang.management.ThreadInfo;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ThreadsCPUInfo {\n    \n    private List<ThreadInfo> threads = new ArrayList<>();\n    private List<Long> cputime = new ArrayList<>();\n    private Map<Long,Long> cputimeMap;\n    private long totalCPUTime;\n    private long timestamp;\n    private long totalDiffCPUTime;\n    \n    ThreadsCPUInfo(long time, ThreadInfo[] tinfo, long[] cpuinfo) {\n        cputimeMap = new HashMap<>(threads.size()*4/3);\n        totalCPUTime = 0;\n        for (int i = 0; i <tinfo.length; i++) {\n            ThreadInfo ti = tinfo[i];\n            if (ti != null) {\n                threads.add(ti);\n                cputime.add(cpuinfo[i]);\n                cputimeMap.put(ti.getThreadId(),cpuinfo[i]);\n                totalCPUTime+=cpuinfo[i];\n            }\n        }\n        timestamp = time;\n    }\n    \n    List<ThreadInfo> getThreads() {\n        return threads;\n    }\n    \n    List<Long> getThreadCPUTime() {\n        return cputime;\n    }\n    \n    long getTotalCPUTime() {\n        return totalCPUTime;\n    }\n    \n    List<Long> getThreadCPUTimeDiff(ThreadsCPUInfo info) {\n        List<Long> cpuTimeDiff = new ArrayList<>(threads.size());\n        List<ThreadInfo> newThreads = info.getThreads();\n        List<Long> newCPUTime = info.getThreadCPUTime();\n        \n        totalDiffCPUTime = 0;\n        for (int i=0; i<newThreads.size(); i++) {\n            ThreadInfo ti = newThreads.get(i);\n            Long oldAlloc = cputimeMap.get(ti.getThreadId());\n            long diff;\n            \n            if (oldAlloc == null) {\n                oldAlloc = Long.valueOf(0);\n            }\n            diff = newCPUTime.get(i)-oldAlloc;\n            cpuTimeDiff.add(diff);\n            totalDiffCPUTime += diff;\n        }\n        return cpuTimeDiff;\n    }\n    \n    long getTotalDiffCPUTime() {\n        return totalDiffCPUTime;\n    }\n    \n    List<Long> getCPUTimePerSecond(ThreadsCPUInfo newInfo) {\n        assert newInfo.timestamp >= timestamp;\n        List<Long> diff = getThreadCPUTimeDiff(newInfo);\n        double secs = (newInfo.timestamp - timestamp) / 1000.0;\n        List<Long> diffPerSec = new ArrayList<>(diff.size());\n        \n        for (Long d : diff) {\n            diffPerSec.add(new Long((long)(d/secs)));\n        }\n        return diffPerSec;\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/cpu/ThreadsCPUView.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.cpu;\n\nimport org.graalvm.visualvm.sampler.AbstractSamplerSupport;\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.LayoutManager;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.ItemEvent;\nimport java.lang.management.ThreadInfo;\nimport java.util.Collections;\nimport java.util.List;\nimport javax.swing.AbstractButton;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.SortOrder;\nimport javax.swing.UIManager;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.McsTimeRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class ThreadsCPUView extends JPanel {\n    private static final double NSEC_TO_USEC = 1000.0;\n    \n    private final AbstractSamplerSupport.Refresher refresher;\n    private final CPUSamplerSupport.ThreadDumper threadDumper;\n    private boolean forceRefresh = false;\n    \n    private List<ThreadInfo> threads;\n    private List<Long> threadCPUInfo;\n    private List<Long> threadCPUInfoPerSec;\n    private ThreadsCPUInfo currentThreadsInfo;\n    private ThreadsCPUInfo baseThreadsInfo;\n    \n    private int totalThreads = -1;\n    private long totalCPUTime = -1;\n    \n    ThreadsCPUView(AbstractSamplerSupport.Refresher refresher, CPUSamplerSupport.ThreadDumper threadDumper) {    \n        this.refresher = refresher;\n        this.threadDumper = threadDumper;\n        \n        threads = Collections.emptyList();\n        threadCPUInfo = Collections.emptyList();\n        threadCPUInfoPerSec = Collections.emptyList();\n        \n        initComponents();\n        \n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (isShowing()) ThreadsCPUView.this.refresher.refresh();\n                }\n            }\n        });\n    }    \n    \n    void initSession() {\n    }\n    \n    boolean isPaused() {\n        return lrPauseButton.isSelected() && !forceRefresh;\n    }\n    \n    boolean isEmpty() {\n        return tableModel.getRowCount() == 0;\n    }\n    \n    void refresh(ThreadsCPUInfo info) {\n        if (!isShowing() || (lrPauseButton.isSelected() && !forceRefresh)) return;\n        \n        forceRefresh = false;\n        threads = info.getThreads();\n        threadCPUInfo = info.getThreadCPUTime();\n        totalCPUTime = info.getTotalCPUTime();\n        if (currentThreadsInfo != null) {\n            threadCPUInfoPerSec = currentThreadsInfo.getCPUTimePerSecond(info);\n        }\n        currentThreadsInfo = info;\n        \n        boolean diff = lrDeltasButton.isSelected();\n        if (diff) {\n            if (baseThreadsInfo == null) baseThreadsInfo = info;\n            totalThreads = threads.size() - baseThreadsInfo.getThreads().size();\n            threadCPUInfo = baseThreadsInfo.getThreadCPUTimeDiff(info);\n            totalCPUTime = baseThreadsInfo.getTotalDiffCPUTime();\n        } else {\n            if (baseThreadsInfo != null) baseThreadsInfo = null;\n            threadCPUInfo = info.getThreadCPUTime();\n            totalCPUTime = info.getTotalCPUTime();\n            totalThreads = threads.size();\n        }\n        \n        renderers[0].setDiffMode(diff);\n        renderers[0].setMaxValue((long)Math.ceil(totalCPUTime / NSEC_TO_USEC));\n        \n        threadsCount.setDiffMode(diff);\n        threadsCount.setValue(totalThreads, -1);\n        \n        threadsTotalTime.setDiffMode(diff);\n        threadsTotalTime.setValue(Math.ceil(totalCPUTime / NSEC_TO_USEC), -1);\n\n        tableModel.fireTableDataChanged();\n    }\n    \n    void starting() {\n        lrPauseButton.setEnabled(true);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(true);\n    }\n    \n    void stopping() {\n        lrPauseButton.setEnabled(false);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(false);\n    }\n    \n    void terminated() {\n        lrPauseButton.setEnabled(false);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(false);\n        threaddumpButton.setEnabled(false);\n    }\n    \n    \n    private JLabel lrLabel;\n    private JToggleButton lrPauseButton;\n    private JButton lrRefreshButton;\n    private JToggleButton lrDeltasButton;\n    private ProfilerToolbar toolbar;\n    \n    private AbstractButton threaddumpButton;\n    \n    private boolean popupPause;\n    \n    private JComponent bottomPanel;\n    private JComponent filterPanel;\n    private JComponent searchPanel;\n    \n    private NumberRenderer threadsCount;\n    private McsTimeRenderer threadsTotalTime;\n    \n    private TreadsCPUTableModel tableModel;\n    private ProfilerTable table;\n    \n    private HideableBarRenderer[] renderers;\n    \n    private void initComponents() {\n        tableModel = new TreadsCPUTableModel();\n        \n        table = new ProfilerTable(tableModel, true, true, null) {\n//            public ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n//                return ThreadsCPUView.this.getUserValueForRow(row);\n//            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                popup.add(createCopyMenuItem());\n                popup.addSeparator();\n                \n                popup.add(new JMenuItem(FilterUtils.ACTION_FILTER) {\n                    protected void fireActionPerformed(ActionEvent e) { ThreadsCPUView.this.activateFilter(); }\n                });\n                popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {\n                    protected void fireActionPerformed(ActionEvent e) { ThreadsCPUView.this.activateSearch(); }\n                });\n            }\n            protected void popupShowing() {\n                if (lrPauseButton.isEnabled() && !lrRefreshButton.isEnabled()) {\n                    popupPause = true;\n                    lrPauseButton.setSelected(true);\n                }\n            }\n            protected void popupHidden() {\n                if (lrPauseButton.isEnabled() && popupPause) {\n                    popupPause = false;\n                    lrPauseButton.setSelected(false);\n                }\n            }\n        };\n        \n        table.setColumnToolTips(new String[] { NbBundle.getMessage(ThreadsCPUView.class, \"ThreadsCPUView_TOOLTIP_Col_name\"), // NOI18N\n                                               NbBundle.getMessage(ThreadsCPUView.class, \"ThreadsCPUView_TOOLTIP_Col_time\"), // NOI18N\n                                               NbBundle.getMessage(ThreadsCPUView.class, \"ThreadsCPUView_TOOLTIP_Col_timesec\") // NOI18N\n                                });\n        \n        table.providePopupMenu(true);\n        \n        table.setMainColumn(0);\n        table.setFitWidthColumn(0);\n        \n        table.setSortColumn(1);\n        table.setDefaultSortOrder(1, SortOrder.DESCENDING);\n        \n        renderers = new HideableBarRenderer[2];\n        \n        renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(new McsTimeRenderer()));\n        renderers[0].setBarDiffMode(HideableBarRenderer.BarDiffMode.MODE_BAR_NORMAL);\n        renderers[1] = new HideableBarRenderer(new NumberPercentRenderer(new McsTimeRenderer()));\n        renderers[1].setBarDiffMode(HideableBarRenderer.BarDiffMode.MODE_BAR_NORMAL);\n        \n        LabelRenderer threadRenderer = new LabelRenderer();\n        threadRenderer.setIcon(Icons.getIcon(ProfilerIcons.THREAD));\n        threadRenderer.setFont(threadRenderer.getFont().deriveFont(Font.BOLD));\n        \n        table.setColumnRenderer(0, threadRenderer);\n        table.setColumnRenderer(1, renderers[0]);\n        table.setColumnRenderer(2, renderers[1]);\n        \n        long refTime = 12345678;\n        renderers[0].setMaxValue(refTime);\n        renderers[1].setMaxValue(refTime);\n        table.setDefaultColumnWidth(1, renderers[0].getOptimalWidth());\n        table.setDefaultColumnWidth(2, renderers[1].getOptimalWidth());\n        \n        renderers[1].setMaxValue(1000 * 1000);\n        \n        ProfilerTableContainer tableContainer = new ProfilerTableContainer(table, false, null);\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        lrLabel = new GrayLabel(Bundle.MethodsFeatureUI_liveResults());\n            \n        lrPauseButton = new JToggleButton(Icons.getIcon(GeneralIcons.PAUSE)) {\n            protected void fireItemStateChanged(ItemEvent event) {\n                boolean paused = isSelected();\n                lrRefreshButton.setEnabled(paused && !popupPause);\n                if (!paused) refresher.refresh();\n            }\n        };\n        lrPauseButton.setToolTipText(NbBundle.getMessage(CPUView.class, \"TOOLTIP_Pause_results\")); // NOI18N\n\n        lrRefreshButton = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                forceRefresh = true;\n                refresher.refresh();\n            }\n        };\n        lrRefreshButton.setToolTipText(NbBundle.getMessage(CPUView.class, \"TOOLTIP_Update_results\")); // NOI18N\n        lrRefreshButton.setEnabled(false);\n        \n        Icon icon = Icons.getIcon(ProfilerIcons.DELTA_RESULTS);\n        lrDeltasButton = new JToggleButton(icon) {\n            protected void fireActionPerformed(ActionEvent e) {\n                if (!lrPauseButton.isSelected()) {\n                forceRefresh = true;\n                refresher.refresh();\n                }\n            }\n        };\n        lrDeltasButton.setToolTipText(NbBundle.getMessage(CPUView.class, \"TOOLTIP_Deltas\")); // NOI18N\n        \n        toolbar = ProfilerToolbar.create(true);\n\n//        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(lrLabel);\n        toolbar.addSpace(2);\n        toolbar.add(lrPauseButton);\n        toolbar.add(lrRefreshButton);\n        \n        toolbar.addSpace(5);\n        toolbar.add(lrDeltasButton);\n        \n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n        \n        toolbar.add(new GrayLabel(NbBundle.getMessage(ThreadsCPUView.class, \"ThreadsCPUView_LBL_Statistics\"))); // NOI18N\n        toolbar.addSpace(5);\n        \n        toolbar.add(new JLabel(NbBundle.getMessage(ThreadsCPUView.class, \"ThreadsCPUView_LBL_TCount\"))); // NOI18N\n        final Dimension tcDim = new Dimension(-1, -1);\n        final JLabel threadsCountL = new JLabel() {\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                \n                if (tcDim.width >= 0) {\n                    dim.width = Math.max(dim.width, tcDim.width);\n                    dim.height = Math.max(dim.height, tcDim.height);\n                }\n                \n                return dim;\n            }\n            public Dimension getMaximumSize() {\n                return getPreferredSize();\n            }\n        };\n        threadsCount = new NumberRenderer() {\n            public void setText(String text) {\n                super.setText(text);\n                threadsCountL.setText(super.getText());\n            }\n        };\n        threadsCount.setDiffMode(true);\n        threadsCount.setValue(99, -1);\n        tcDim.setSize(threadsCountL.getPreferredSize());\n        threadsCount.setDiffMode(false);\n        threadsCount.setValue(0, -1);\n        toolbar.addSpace(3);\n        toolbar.add(threadsCountL);\n        \n        toolbar.addSpace(5);\n        \n        toolbar.add(new JLabel(NbBundle.getMessage(ThreadsCPUView.class, \"ThreadsCPUView_LBL_Total_time\"))); // NOI18N\n        final JLabel threadsTotalTimeL = new JLabel();\n        threadsTotalTime = new McsTimeRenderer() {\n            public void setText(String text) {\n                super.setText(text);\n                threadsTotalTimeL.setText(super.getText());\n            }\n        };\n        toolbar.addSpace(3);\n        toolbar.add(threadsTotalTimeL);\n        \n        toolbar.addFiller();\n        \n        threaddumpButton = new JButton(NbBundle.getMessage(CPUView.class, \"LBL_Thread_dump\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent event) {\n                threadDumper.takeThreadDump((event.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n            }\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.width += 5;\n                return dim;\n            }\n        };\n        threaddumpButton.setToolTipText(NbBundle.getMessage(CPUView.class, \"TOOLTIP_Thread_dump\")); // NOI18N\n        threaddumpButton.setOpaque(false);\n        threaddumpButton.setEnabled(threadDumper != null);\n        toolbar.add(threaddumpButton);\n        \n        \n        setOpaque(false);\n        setLayout(new BorderLayout());\n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        add(tableContainer, BorderLayout.CENTER);\n    }\n    \n    private JComponent getBottomPanel() {\n        if (bottomPanel == null) {\n            bottomPanel = new JPanel(new FilterFindLayout());\n            bottomPanel.setOpaque(true);\n            bottomPanel.setBackground(UIManager.getColor(\"controlShadow\")); // NOI18N\n            add(bottomPanel, BorderLayout.SOUTH);\n        }\n        return bottomPanel;\n    }\n    \n    private void activateFilter() {\n        JComponent panel = getBottomPanel();\n        \n        if (filterPanel == null) {\n            filterPanel = FilterUtils.createFilterPanel(table);\n            panel.add(filterPanel);\n            Container parent = panel.getParent();\n            parent.invalidate();\n            parent.revalidate();\n            parent.repaint();\n        }\n        \n        panel.setVisible(true);\n        \n        filterPanel.setVisible(true);\n        filterPanel.requestFocusInWindow();\n    }\n    \n    private void activateSearch() {\n        JComponent panel = getBottomPanel();\n        \n        if (searchPanel == null) {\n            searchPanel = SearchUtils.createSearchPanel(table);\n            panel.add(searchPanel);\n            Container parent = panel.getParent();\n            parent.invalidate();\n            parent.revalidate();\n            parent.repaint();\n        }\n        \n        panel.setVisible(true);\n        \n        searchPanel.setVisible(true);\n        searchPanel.requestFocusInWindow();\n    }\n    \n    \n    private static final String COL_NAME = NbBundle.getMessage(CPUView.class, \"COL_Thread_name\"); // NOI18N\n    private static final String COL_BYTES = NbBundle.getMessage(CPUView.class, \"COL_ABytes\"); // NOI18N\n    private static final String COL_BYTES_SEC = NbBundle.getMessage(CPUView.class, \"COL_ABytes_Sec\"); // NOI18N\n    \n    private class TreadsCPUTableModel extends AbstractTableModel {\n        \n        public String getColumnName(int columnIndex) {\n            if (columnIndex == 0) {\n                return COL_NAME;\n            } else if (columnIndex == 1) {\n                return COL_BYTES;\n            } else if (columnIndex == 2) {\n                return COL_BYTES_SEC;\n            }\n            \n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (columnIndex == 0) {\n                return String.class;\n            } else {\n                return Long.class;\n            }\n        }\n\n        public int getRowCount() {\n            return threads.size();\n        }\n\n        public int getColumnCount() {\n            return 3;\n        }\n\n        public Object getValueAt(int rowIndex, int columnIndex) {\n            if (columnIndex == 0) {\n                return threads.get(rowIndex).getThreadName();\n            } else if (columnIndex == 1) {\n                long threadCPUtime = threadCPUInfo.get(rowIndex).longValue();\n                return threadCPUtime / NSEC_TO_USEC;\n            } else if (columnIndex == 2) {\n                return threadCPUInfoPerSec.isEmpty() ? 0 :\n                       Math.min(threadCPUInfoPerSec.get(rowIndex).longValue() / NSEC_TO_USEC, 1000000);\n            }\n\n            return null;\n        }\n        \n    }\n    \n    \n    private final class FilterFindLayout implements LayoutManager {\n\n        public void addLayoutComponent(String name, Component comp) {}\n        public void removeLayoutComponent(Component comp) {}\n\n        public Dimension preferredLayoutSize(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            Dimension dim = new Dimension();\n            \n            if (filter != null && search != null) {\n                Dimension dim1 = filter.getPreferredSize();\n                Dimension dim2 = search.getPreferredSize();\n                dim.width = dim1.width + dim2.width + 1;\n                dim.height = Math.max(dim1.height, dim2.height);\n            } else if (filter != null) {\n                dim = filter.getPreferredSize();\n            } else if (search != null) {\n                dim = search.getPreferredSize();\n            }\n            \n            if ((filter != null || search != null) /*&& hasBottomFilterFindMargin()*/)\n                dim.height += 1;\n            \n            return dim;\n        }\n\n        public Dimension minimumLayoutSize(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            Dimension dim = new Dimension();\n            \n            if (filter != null && search != null) {\n                Dimension dim1 = filter.getMinimumSize();\n                Dimension dim2 = search.getMinimumSize();\n                dim.width = dim1.width + dim2.width + 1;\n                dim.height = Math.max(dim1.height, dim2.height);\n            } else if (filter != null) {\n                dim = filter.getMinimumSize();\n            } else if (search != null) {\n                dim = search.getMinimumSize();\n            }\n            \n            if ((filter != null || search != null) /*&& hasBottomFilterFindMargin()*/)\n                dim.height += 1;\n            \n            return dim;\n        }\n\n        public void layoutContainer(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            int bottomOffset = /* hasBottomFilterFindMargin() ? 1 :*/ 0;\n            \n            if (filter != null && search != null) {\n                Dimension size = parent.getSize();\n                int w = (size.width - 1) / 2;\n                filter.setBounds(0, 0, w, size.height - bottomOffset);\n                search.setBounds(w + 1, 0, size.width - w - 1, size.height - bottomOffset);\n            } else if (filter != null) {\n                Dimension size = parent.getSize();\n                filter.setBounds(0, 0, size.width, size.height - bottomOffset);\n            } else if (search != null) {\n                Dimension size = parent.getSize();\n                search.setBounds(0, 0, size.width, size.height - bottomOffset);\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/memory/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_Memory_settings=Memory settings\n\nLBL_Heap_histogram=Heap histogram\n\nLBL_PermGen_histogram=PermGen histogram\n\nLBL_ThreadAlloc=Per thread allocations\n\nCOL_Class_name=Name\n\nCOL_Bytes_rel=Bytes [%]\n\nCOL_Bytes=Live Bytes\n\nCOL_ABytes_rel=Allocated Bytes [%]\n\nCOL_ABytes=Allocated Bytes\n\nCOL_ABytes_Sec=Allocated Bytes / sec\n\nCOL_Instances=Live Objects\n\nCOL_Thread_name=Name\n\nTOOLTIP_Pause_results=Pause live results\n\nTOOLTIP_Update_results=Update live results now\n\nLBL_Deltas=Deltas\n\nTOOLTIP_Deltas=Show delta values\n\nLBL_Snapshot=Snapshot\n\nTOOLTIP_Snapshot=Take snapshot of collected results\n\nLBL_Gc=Perform GC\n\nTOOLTIP_Gc=Perform garbage collection in target application\n\nLBL_HeapDump=Heap Dump\n\nTOOLTIP_HeapDump=Take heap dump\n\nLBL_Class_filter=Class Name Filter\n\nLBL_Thread_filter=Thread Name Filter\n\nLBL_Classes=<b>Classes: </b>{0}\n\nLBL_Instances=<b>Instances: </b>{0}\n\nLBL_Bytes=<b>Bytes: </b>{0}\n\nLBL_ABytes=<b>Total Allocated Bytes: </b>{0}\n\nLBL_Threads=<b>Threads: </b>{0}\n\nMemoryView_TOOLTIP_Col_name=Class name\nMemoryView_TOOLTIP_Col_size=Size of live instances\nMemoryView_TOOLTIP_Col_count=Number of live instances\nMemoryView_LBL_Results=Results\\:\nMemoryView_LBL_Data=Collected data\\:\nMemoryView_LBL_Snapshot=Snapshot\nMemoryView_Context_GoToSource=Go to Source\n\nThreadsMemoryView_TOOLTIP_Col_name=Thread name\nThreadsMemoryView_TOOLTIP_Col_bytes=Total bytes allocated by thread\nThreadsMemoryView_TOOLTIP_Col_bytessec=Bytes allocated by thread in last 1 second\nThreadsMemoryView_LBL_Results=Results\\:\nThreadsMemoryView_LBL_Statistics=Statistics\\:\nThreadsMemoryView_LBL_TCount=Threads Count\\:\nThreadsMemoryView_LBL_Total_bytes=Total Allocated Bytes\\:\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/memory/MemorySamplerParameters.java",
    "content": "/*\n * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.memory;\n\nimport java.util.Map;\nimport java.util.Properties;\nimport org.graalvm.visualvm.sampler.SamplerParameters;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class MemorySamplerParameters extends SamplerParameters {\n    \n    static final String SAMPLING_RATE = \"sampling-rate\";                        // NOI18N\n    \n    \n    private MemorySamplerParameters(String parametersS) {\n        super(parametersS);\n    }\n    \n    \n    public static MemorySamplerParameters parse(String parameters) {\n        return new MemorySamplerParameters(parameters);\n    }\n\n    \n    @Override\n    protected void parseParameters(String parametersS, Map<String, String> parameters) {\n        if (parametersS.startsWith(FILE + \"=\")) {                               // NOI18N\n            // settings defined in file\n            parseParametersFile(decode(parametersS.substring(FILE.length() + 1)), parameters);\n        } else {\n            for (String parameter : parametersS.split(\",\")) {                   // NOI18N\n\n                // sampling-rate\n                int idx = parameter.indexOf(SAMPLING_RATE + \"=\");               // NOI18N\n                if (idx == 0) parameters.put(SAMPLING_RATE, decode(parameter.substring(SAMPLING_RATE.length() + 1)));\n\n            }\n        }\n    }\n    \n    private void parseParametersFile(String file, Map<String, String> parameters) {\n        Properties properties = loadProperties(file);\n        \n        // sampling-rate\n        String prop = properties.getProperty(SAMPLING_RATE);\n        if (prop != null) parameters.put(SAMPLING_RATE, decode(prop));\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/memory/MemorySamplerSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.memory;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.lang.management.MemoryMXBean;\nimport java.util.Set;\nimport java.util.TimerTask;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsSnapshot;\nimport org.graalvm.visualvm.sampler.AbstractSamplerSupport;\nimport org.graalvm.visualvm.sampler.AbstractSamplerSupport.Refresher;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic abstract class MemorySamplerSupport extends AbstractSamplerSupport {\n    \n    private final Application application;\n    \n    private final Jvm jvm;\n    private final MemoryMXBean memoryBean;\n    private final ThreadsMemory threadsMemory;\n    private final HeapDumper heapDumper;\n    private final SnapshotDumper snapshotDumper;\n    \n    private java.util.Timer processor;\n    private final AtomicBoolean updateIsRunning;\n    \n    private Timer heapTimer;\n    private Refresher heapRefresher;\n    private MemoryView heapView;\n    \n    private final boolean hasPermGenHisto;\n    private Timer permgenTimer;\n    private Refresher permgenRefresher;\n    private MemoryView permgenView;\n    \n    private Timer threadAllocTimer;\n    private Refresher threadAllocRefresher;\n    private ThreadsMemoryView threadAllocView;\n    \n    private DataViewComponent.DetailsView[] detailsViews;\n    \n    public MemorySamplerSupport(Application application, Jvm jvm, boolean hasPermGen, ThreadsMemory mem, MemoryMXBean memoryBean, SnapshotDumper snapshotDumper, HeapDumper heapDumper) {\n        this.application = application;\n        \n        this.jvm = jvm;\n        hasPermGenHisto = hasPermGen;\n        threadsMemory = mem;\n        this.memoryBean = memoryBean;\n        this.heapDumper = heapDumper;\n        this.snapshotDumper = snapshotDumper;\n        updateIsRunning = new AtomicBoolean();\n    }\n    \n    \n    public DataViewComponent.DetailsView[] getDetailsView() {\n        if (detailsViews == null) {\n            initialize();\n            detailsViews = createViews();\n        }\n        heapView.initSession();\n        if (permgenView != null) permgenView.initSession();\n        if (threadAllocView != null) threadAllocView.initSession();\n        return detailsViews.clone();\n    }\n    \n    public boolean startSampling(ProfilingSettings settings, int samplingRate, int refreshRate) {\n//        heapTimer.start();\n//        permgenTimer.start();\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (heapView != null) heapView.starting();\n                if (permgenView != null) permgenView.starting();\n                if (threadAllocView != null) threadAllocView.starting();\n            }\n        });\n\n        heapRefresher.setRefreshRate(samplingRate);\n        if (permgenRefresher != null)\n            permgenRefresher.setRefreshRate(samplingRate);\n        if (threadAllocRefresher != null)\n            threadAllocRefresher.setRefreshRate(samplingRate);\n        if (heapView != null) {\n            if (permgenView != null) doRefreshImpl(heapTimer, heapView, permgenView);\n            else doRefreshImpl(heapTimer, heapView);\n        }\n        return true;\n    }\n    \n    public void takeSnapshot(boolean openView) {\n        snapshotDumper.takeSnapshot(openView);\n    }\n    \n    public synchronized void stopSampling() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (heapView != null) heapView.stopping();\n                if (permgenView != null) permgenView.stopping();\n                if (threadAllocView != null) threadAllocView.stopping();\n            }\n        });\n        \n        heapTimer.stop();\n        if (permgenTimer != null) {\n            permgenTimer.stop();\n        }\n        if (threadAllocTimer != null)\n            threadAllocTimer.stop();\n        if (heapView != null) {\n            if (permgenView != null) doRefreshImplImpl(snapshotDumper.lastHistogram, heapView, permgenView);\n            else doRefreshImplImpl(snapshotDumper.lastHistogram, heapView);\n        }\n    }\n    \n    public synchronized void terminate() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (heapView != null) heapView.terminated();\n                if (permgenView != null) permgenView.terminated();\n                if (threadAllocView != null) threadAllocView.terminated();\n            }\n        });\n    }\n    \n    \n    private void initialize() {\n        int defaultRefresh = GlobalPreferences.sharedInstance().getMonitoredDataPoll() * 1000;\n        \n        processor = getTimer();\n        \n        heapTimer = new Timer(defaultRefresh, new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                heapRefresher.refresh();\n            }\n        });\n        heapRefresher = new Refresher() {\n            public final boolean checkRefresh() {\n                if (!heapTimer.isRunning()) return false;\n                return (heapView.isShowing() || (permgenTimer != null && permgenTimer.getDelay() ==\n                        heapTimer.getDelay() && permgenView.isShowing()));\n            }\n            public final void doRefresh() {\n                if (heapView.isShowing()) {\n                    doRefreshImpl(heapTimer, heapView);\n                } else if (permgenTimer != null && permgenTimer.getDelay() == heapTimer.getDelay() &&\n                           permgenView.isShowing()) {\n                    doRefreshImpl(heapTimer, permgenView);\n                }\n            }\n            public final void setRefreshRate(int refreshRate) {\n                heapTimer.setDelay(refreshRate);\n                heapTimer.setInitialDelay(refreshRate);\n                heapTimer.restart();\n            }\n            public final int getRefreshRate() {\n                return heapTimer.getDelay();\n            }\n        };\n        \n        if (hasPermGenHisto) {\n            permgenTimer = new Timer(defaultRefresh, new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    permgenRefresher.refresh();\n                }\n            });\n            permgenRefresher = new Refresher() {\n                public final boolean checkRefresh() {\n                    if (!permgenTimer.isRunning()) return false;\n                    if (permgenTimer.getDelay() == heapTimer.getDelay()) return false;\n                    return (permgenView.isShowing());\n                }\n                public final void doRefresh() {\n                    doRefreshImpl(permgenTimer, permgenView);\n                }\n                public final void setRefreshRate(int refreshRate) {\n                    permgenTimer.setDelay(refreshRate);\n                    permgenTimer.setInitialDelay(refreshRate);\n                    permgenTimer.restart();\n                }\n                public final int getRefreshRate() {\n                    return permgenTimer.getDelay();\n                }\n            };\n        }\n        \n        if (threadsMemory != null) {\n            threadAllocTimer = new Timer(defaultRefresh, new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    threadAllocRefresher.refresh();\n                }\n            });\n            threadAllocRefresher = new Refresher() {\n                public final boolean checkRefresh() {\n                    if (!threadAllocTimer.isRunning()) return false;\n                    return threadAllocView.isShowing();\n                }\n                public final void doRefresh() {\n                    doRefreshImpl(threadAllocTimer, threadAllocView);\n                }\n                public final void setRefreshRate(int refreshRate) {\n                    threadAllocTimer.setDelay(refreshRate);\n                    threadAllocTimer.setInitialDelay(refreshRate);\n                    threadAllocTimer.restart();\n                }\n                public final int getRefreshRate() {\n                    return threadAllocTimer.getDelay();\n                }\n            };\n        }\n    }\n    \n    private DataViewComponent.DetailsView[] createViews() {\n        int detailIndex = 0;\n        int detailsCount = 1;\n        if (hasPermGenHisto) detailsCount++;\n        if (threadAllocRefresher != null) detailsCount++;\n        DataViewComponent.DetailsView[] details = new DataViewComponent.DetailsView[detailsCount];\n        \n        heapView = new MemoryView(application, heapRefresher, MemoryView.MODE_HEAP, memoryBean, snapshotDumper, heapDumper);\n        details[detailIndex++] = new DataViewComponent.DetailsView(\n                    NbBundle.getMessage(MemorySamplerSupport.class, \"LBL_Heap_histogram\"), // NOI18N\n                    null, 10, heapView, null);\n        if (hasPermGenHisto) {\n            permgenView = new MemoryView(application, permgenRefresher, MemoryView.MODE_PERMGEN, memoryBean, null, heapDumper);\n            details[detailIndex++] = new DataViewComponent.DetailsView(\n                        NbBundle.getMessage(MemorySamplerSupport.class, \"LBL_PermGen_histogram\"), // NOI18N\n                        null, 20, permgenView, null);\n        }\n        if (threadAllocRefresher != null) {\n            threadAllocView = new ThreadsMemoryView(threadAllocRefresher, memoryBean, heapDumper);\n            details[detailIndex++] = new DataViewComponent.DetailsView(\n                    NbBundle.getMessage(MemorySamplerSupport.class, \"LBL_ThreadAlloc\"), // NOI18N\n                    null, 30, threadAllocView, null);\n        }\n        return details;\n    }\n    \n    private void doRefreshImpl(final Timer timer, final ThreadsMemoryView view) {\n        if (!timer.isRunning() || view.isPaused()) return;\n        if (!updateIsRunning.compareAndSet(false, true)) return;\n        try {\n            processor.schedule(new TimerTask() {\n                public void run() {\n                    try {\n                        if (!timer.isRunning()) return;\n                        doRefreshImplImpl(threadsMemory.getThreadsMemoryInfo(), view);\n                    } catch (Exception e) {\n                        terminate();\n                    } finally {\n                        updateIsRunning.set(false);\n                    }\n                }\n            }, 0);\n        } catch (Exception e) {\n            terminate();\n        }\n    }\n    \n    private void doRefreshImpl(final Timer timer, final MemoryView... views) {\n        if (!timer.isRunning() || (views.length == 1 && views[0].isPaused())) return;\n        if (!updateIsRunning.compareAndSet(false, true)) return;\n        try {\n            processor.schedule(new TimerTask() {\n                public void run() {\n                    try {\n                        if (!timer.isRunning()) return;\n                        doRefreshImplImpl(jvm.takeHeapHistogram(), views);\n                    } catch (Exception e) {\n                        terminate();\n                    } finally {\n                        updateIsRunning.set(false);\n                    }\n                }\n            }, 0);\n        } catch (Exception e) {\n            terminate();\n        }\n    }\n\n    private void doRefreshImplImpl(final HeapHistogram heapHistogram, final MemoryView... views) {\n        if (heapHistogram != null)\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    snapshotDumper.lastHistogram = heapHistogram;\n                    for (MemoryView view : views) view.refresh(heapHistogram);\n                }\n            });\n    }\n    \n    private void doRefreshImplImpl(final ThreadsMemoryInfo info, final ThreadsMemoryView view) {\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    view.refresh(info);\n                }\n            });\n    }\n\n    public static abstract class HeapDumper {\n        public abstract void takeHeapDump(boolean openView);\n    }\n    \n    public static abstract class SnapshotDumper {\n        private volatile HeapHistogram lastHistogram;\n        \n        public abstract void takeSnapshot(boolean openView);\n        \n        public SampledMemoryResultsSnapshot createSnapshot(long time) {\n            HeapHistogram histogram = lastHistogram;\n\n            if (histogram != null) {\n                ByteArrayOutputStream output = new ByteArrayOutputStream(1024);\n                DataOutputStream dos = new DataOutputStream(output);\n                try {\n                    SampledMemoryResultsSnapshot result = new SampledMemoryResultsSnapshot();\n                    Set<HeapHistogram.ClassInfo> classes = histogram.getHeapHistogram();\n                    \n                    dos.writeInt(1);    // version\n                    dos.writeLong(histogram.getTime().getTime()); // begin time\n                    dos.writeLong(time); // taken time\n                    dos.writeInt(classes.size());   // no of classes\n                    for (HeapHistogram.ClassInfo info : classes) {\n                        dos.writeUTF(info.getName());       // name\n                        dos.writeLong(info.getBytes());     // total number of bytes\n                    }\n                    dos.writeBoolean(false); // no stacktraces\n                    dos.writeInt(classes.size());   // no of classes\n                    for (HeapHistogram.ClassInfo info : classes) {\n                        dos.writeInt((int)info.getInstancesCount());     // number of instances\n                    }\n                    dos.close();\n                    result.readFromStream(new DataInputStream(new ByteArrayInputStream(output.toByteArray())));\n                    return result;\n                } catch (IOException ex) {\n                    ex.printStackTrace();\n                }\n            }\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/memory/MemorySettingsSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.memory;\n\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.profiling.presets.PresetSelector;\nimport org.graalvm.visualvm.profiling.presets.SamplerMemoryPanel;\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPreset;\nimport org.graalvm.visualvm.sampler.SamplerParameters;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class MemorySettingsSupport {\n    \n    private static final Logger LOGGER = Logger.getLogger(MemorySettingsSupport.class.getName());\n\n    \n    private JPanel container;\n    private SamplerMemoryPanel panel;\n    private PresetSelector selector;\n    \n    private DataViewComponent.DetailsView detailsView;\n    \n    private ProfilerPreset requestedPreset;\n    \n    \n    public DataViewComponent.DetailsView getDetailsView() {\n        if (detailsView == null) {\n            detailsView = new DataViewComponent.DetailsView(NbBundle.getMessage(\n                          MemorySettingsSupport.class, \"LBL_Memory_settings\"), null, 20, // NOI18N\n                          new ScrollableContainer(createPanel()), null);\n        }\n        return detailsView;\n    }\n    \n    \n    public void setSettings(SamplerParameters settings) {\n        ProfilerPreset preset = createPreset(settings);\n        if (panel != null) {\n            panel.loadFromPreset(preset);\n            selector.customize(presetValid());\n        } else {\n            requestedPreset = preset;\n        }\n    }\n    \n    public ProfilingSettings getSettings() { return panel.getSettings(); }\n\n    public int getSamplingRate() { return panel.getSamplingRate(); }\n    \n    public int getRefreshRate() { return panel.getRefreshRate(); }\n    \n    public void saveSettings() {\n        // NOTE: might save custom configuration here\n    }\n    \n    public abstract boolean presetValid();\n    \n    public boolean settingsValid() { return panel.settingsValid(); }\n    \n    public void showSettings(DataViewComponent dvc) {\n        dvc.selectDetailsView(getDetailsView());\n    }\n    \n    public abstract PresetSelector createSelector(Runnable presetSynchronizer);\n    \n    \n    public void setEnabled(boolean enabled) {\n        if (container != null) container.setEnabled(enabled);\n    }\n    \n    private JPanel createPanel() {\n        panel = new SamplerMemoryPanel() {\n            public void settingsChanged() {\n                panel.saveToPreset(selector.customize(presetValid()));\n            }\n        };\n        \n        selector = createSelector(new Runnable() {\n            public void run() { panel.loadFromPreset(selector.getSelectedPreset()); }\n        });\n        selector.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));\n        \n        container = new JPanel(new BorderLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents()) c.setEnabled(enabled);\n            }\n        };\n        container.setOpaque(false);\n        container.add(panel, BorderLayout.CENTER);\n        container.add(selector, BorderLayout.SOUTH);\n        \n        if (requestedPreset != null) {\n            panel.loadFromPreset(requestedPreset);\n            selector.customize(presetValid());\n            requestedPreset = null;\n        }\n        \n        return container;\n    }\n    \n    \n    private static ProfilerPreset createPreset(SamplerParameters settings) {\n        ProfilerPreset preset = new ProfilerPreset(\"Forced Memory Settings\", \"\"); // NOI18N\n        \n        String refresh = settings.get(MemorySamplerParameters.SAMPLING_RATE);\n        if (refresh != null) {\n            try { preset.setSamplingRefreshRateS(Integer.parseInt(refresh)); }\n            catch (NumberFormatException e) { LOGGER.log(Level.WARNING, \"Failed to read Sampler \" + MemorySamplerParameters.SAMPLING_RATE, e); } // NOI18N\n        }\n        \n        return preset;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/memory/MemoryView.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.memory;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram.ClassInfo;\nimport org.graalvm.visualvm.profiling.actions.ProfiledSourceSelection;\nimport org.graalvm.visualvm.profiling.actions.ProfilerPopupCustomizer;\nimport org.graalvm.visualvm.sampler.AbstractSamplerSupport;\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.LayoutManager;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.ItemEvent;\nimport java.lang.management.MemoryMXBean;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.swing.AbstractAction;\nimport javax.swing.AbstractButton;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.Exceptions;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class MemoryView extends JPanel {\n\n    static final int MODE_HEAP = 1;\n    static final int MODE_PERMGEN = 2;\n    \n    private final int mode;\n\n    private final AbstractSamplerSupport.Refresher refresher;\n    private boolean forceRefresh = false;\n    \n    private final MemoryMXBean memoryBean;\n    private final MemorySamplerSupport.HeapDumper heapDumper;\n    private final MemorySamplerSupport.SnapshotDumper snapshotDumper;\n    \n    private List<ClassInfo> classes = new ArrayList<>();\n    private List<ClassInfo> baseClasses = new ArrayList<>(); // Needed to correctly setup table renderers\n\n\n    MemoryView(Application application, AbstractSamplerSupport.Refresher refresher, int mode,\n               MemoryMXBean memoryBean, MemorySamplerSupport.SnapshotDumper snapshotDumper,\n               MemorySamplerSupport.HeapDumper heapDumper) {\n\n        this.refresher = refresher;\n        this.mode = mode;\n\n        this.memoryBean = memoryBean;\n        this.snapshotDumper = snapshotDumper;\n        this.heapDumper = heapDumper;\n        \n        initComponents(application);\n\n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (isShowing()) MemoryView.this.refresher.refresh();\n                }\n            }\n        });\n    }\n\n\n    void initSession() {\n        if (pdSnapshotButton != null) pdSnapshotButton.setEnabled(false);\n    }\n\n    boolean isPaused() {\n        return lrPauseButton.isSelected() && !forceRefresh;\n    }\n    \n    boolean isEmpty() {\n        return tableModel.getRowCount() == 0;\n    }\n    \n    void refresh(HeapHistogram histogram) {\n        if (histogram == null || isPaused()) return;\n        long bytesMaxValue = 0;\n        long instancesMaxValue = 0;\n        forceRefresh = false;\n        \n        boolean diff = lrDeltasButton.isSelected();\n        if (diff) {\n            if (baseClasses == null) {\n                baseClasses = new ArrayList<>(classes);\n            }\n\n            Collection<ClassInfo> newClasses = getHistogram(histogram);\n            classes = computeDeltaClasses(baseClasses, newClasses);\n\n            long maxAbsDiffBytes = 0;\n            long maxAbsDiffInstances = 0;\n            for (ClassInfo cInfo : classes) {\n                maxAbsDiffBytes = Math.max(maxAbsDiffBytes, Math.abs(cInfo.getBytes()));\n                maxAbsDiffInstances = Math.max(maxAbsDiffInstances, Math.abs(cInfo.getInstancesCount()));\n            }\n            bytesMaxValue = maxAbsDiffBytes;\n            instancesMaxValue = maxAbsDiffInstances;\n        } else {\n            if (baseClasses != null) {\n                baseClasses = null;\n            }\n            classes.clear();\n            classes.addAll(getHistogram(histogram));\n\n            bytesMaxValue = getTotalBytes(histogram);\n            instancesMaxValue = getTotalInstances(histogram);\n        }\n        \n        renderers[0].setDiffMode(diff);\n        renderers[0].setMaxValue(bytesMaxValue);\n        \n        renderers[1].setDiffMode(diff);\n        renderers[1].setMaxValue(instancesMaxValue);\n\n        tableModel.fireTableDataChanged();\n\n        if (pdSnapshotButton != null) pdSnapshotButton.setEnabled(true);\n    }\n\n    void starting() {\n        lrPauseButton.setEnabled(true);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(true);\n    }\n    \n    void stopping() {\n        lrPauseButton.setEnabled(false);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(false);\n    }\n    \n    void terminated() {\n        lrPauseButton.setEnabled(false);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(false);\n        gcButton.setEnabled(false);\n        heapdumpButton.setEnabled(false);\n    }\n\n    private Collection<ClassInfo> getHistogram(HeapHistogram histogram) {\n        if (mode == MODE_HEAP) return histogram.getHeapHistogram();\n        if (mode == MODE_PERMGEN) return histogram.getPermGenHistogram();\n        return null;\n    }\n\n    private long getTotalBytes(HeapHistogram histogram) {\n        if (mode == MODE_HEAP) return histogram.getTotalHeapBytes();\n        if (mode == MODE_PERMGEN) return histogram.getTotalPermGenHeapBytes();\n        return -1;\n    }\n\n    private long getTotalInstances(HeapHistogram histogram) {\n        if (mode == MODE_HEAP) return histogram.getTotalHeapInstances();\n        if (mode == MODE_PERMGEN) return histogram.getTotalPerGenInstances();\n        return -1;\n    }\n\n    private static List<ClassInfo> computeDeltaClasses(Collection<ClassInfo> basis, Collection<ClassInfo> changed) {\n\n        Map<String, DeltaClassInfo> deltaMap = new HashMap<>((int)(basis.size() * 1.3));\n\n        for (ClassInfo cInfo : basis)\n            deltaMap.put(cInfo.getName(), new DeltaClassInfo(cInfo, true));\n\n        for (ClassInfo cInfo : changed) {\n            DeltaClassInfo bInfo = deltaMap.get(cInfo.getName());\n            if (bInfo != null) bInfo.add(cInfo);\n            else deltaMap.put(cInfo.getName(), new DeltaClassInfo(cInfo, false));\n        }\n\n        return new ArrayList<>(deltaMap.values());\n    }\n    \n    \n    private JLabel lrLabel;\n    private JToggleButton lrPauseButton;\n    private JButton lrRefreshButton;\n    private JToggleButton lrDeltasButton;\n    \n    private JLabel pdLabel;\n    private JButton pdSnapshotButton;\n//    private JButton pdResetResultsButton;\n    \n    private AbstractButton gcButton;\n    private AbstractButton heapdumpButton;\n    \n    private boolean popupPause;\n    \n    private JComponent bottomPanel;\n    private JComponent filterPanel;\n    private JComponent searchPanel;\n    \n//    private NumberRenderer threadsCount;\n//    private NumberRenderer threadsTotalBytes;\n    \n    private HistogramTableModel tableModel;\n    private ProfilerTable table;\n    \n    private HideableBarRenderer[] renderers;\n    \n    private void initComponents(final Application application) {\n        tableModel = new HistogramTableModel();\n        \n        table = new ProfilerTable(tableModel, true, true, null) {\n//            public ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n//                return ThreadsMemoryView.this.getUserValueForRow(row);\n//            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                final String selectedClass = value == null ? null : value.toString();\n                \n                if (GoToSource.isAvailable()) {\n                    popup.add(new JMenuItem(NbBundle.getMessage(MemoryView.class, \"MemoryView_Context_GoToSource\")) { // NOI18N\n                        { setEnabled(selectedClass != null); setFont(getFont().deriveFont(Font.BOLD)); }\n                        protected void fireActionPerformed(ActionEvent e) { GoToSource.openSource(null, selectedClass, null, null); }\n                    });\n                    popup.addSeparator();\n                }\n                \n                if (snapshotDumper != null && selectedClass != null) {\n                    JMenuItem[] customItems = createCustomMenuItems(application, selectedClass);\n                    if (customItems != null) {\n                        for (JMenuItem customItem : customItems) popup.add(customItem);\n                        popup.addSeparator();\n                    }\n                }\n                \n                popup.add(createCopyMenuItem());\n                popup.addSeparator();\n                \n                popup.add(new JMenuItem(FilterUtils.ACTION_FILTER) {\n                    protected void fireActionPerformed(ActionEvent e) { MemoryView.this.activateFilter(); }\n                });\n                popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {\n                    protected void fireActionPerformed(ActionEvent e) { MemoryView.this.activateSearch(); }\n                });\n            }\n            protected void popupShowing() {\n                if (lrPauseButton.isEnabled() && !lrRefreshButton.isEnabled()) {\n                    popupPause = true;\n                    lrPauseButton.setSelected(true);\n                }\n            }\n            protected void popupHidden() {\n                if (lrPauseButton.isEnabled() && popupPause) {\n                    popupPause = false;\n                    lrPauseButton.setSelected(false);\n                }\n            }\n        };\n        \n        table.setColumnToolTips(new String[] { NbBundle.getMessage(MemoryView.class, \"MemoryView_TOOLTIP_Col_name\"), // NOI18N\n                                               NbBundle.getMessage(MemoryView.class, \"MemoryView_TOOLTIP_Col_size\"), // NOI18N\n                                               NbBundle.getMessage(MemoryView.class, \"MemoryView_TOOLTIP_Col_count\") // NOI18N\n                                });\n        \n        table.providePopupMenu(true);\n        \n        table.setMainColumn(0);\n        table.setFitWidthColumn(0);\n        \n        table.setSortColumn(1);\n        table.setDefaultSortOrder(1, SortOrder.DESCENDING);\n        \n        renderers = new HideableBarRenderer[2];\n        renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(Formatters.bytesFormat()));\n        renderers[1] = new HideableBarRenderer(new NumberPercentRenderer());\n        \n        renderers[0].setMaxValue(123456789);\n        renderers[1].setMaxValue(12345678);\n        \n        table.setColumnRenderer(0, new JavaNameRenderer(Icons.getIcon(LanguageIcons.CLASS)));\n        table.setColumnRenderer(1, renderers[0]);\n        table.setColumnRenderer(2, renderers[1]);\n        \n        table.setDefaultColumnWidth(1, renderers[0].getOptimalWidth());\n        table.setDefaultColumnWidth(2, renderers[1].getMaxNoBarWidth());\n        \n        ProfilerTableContainer tableContainer = new ProfilerTableContainer(table, false, null);\n        \n        InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        ActionMap actionMap = getActionMap();\n        \n        final String filterKey = FilterUtils.FILTER_ACTION_KEY;\n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                MemoryView.this.activateFilter();\n            }\n        };\n        ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);\n        \n        final String findKey = SearchUtils.FIND_ACTION_KEY;\n        Action findAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                MemoryView.this.activateSearch();\n            }\n        };\n        ActionsSupport.registerAction(findKey, findAction, actionMap, inputMap);\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { SearchUtils.enableSearchActions(table); }\n        });\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        lrLabel = new GrayLabel(NbBundle.getMessage(MemoryView.class, \"MemoryView_LBL_Results\")); // NOI18N\n            \n        lrPauseButton = new JToggleButton(Icons.getIcon(GeneralIcons.PAUSE)) {\n            protected void fireItemStateChanged(ItemEvent event) {\n                boolean paused = isSelected();\n                lrRefreshButton.setEnabled(paused && !popupPause);\n                if (!paused) refresher.refresh();\n            }\n        };\n        lrPauseButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_Pause_results\")); // NOI18N\n\n        lrRefreshButton = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                forceRefresh = true;\n                refresher.refresh();\n            }\n        };\n        lrRefreshButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_Update_results\")); // NOI18N\n        lrRefreshButton.setEnabled(false);\n        \n        Icon icon = Icons.getIcon(ProfilerIcons.DELTA_RESULTS);\n        lrDeltasButton = new JToggleButton(icon) {\n            protected void fireActionPerformed(ActionEvent e) {\n                if (!lrPauseButton.isSelected()) {\n                    forceRefresh = true;\n                    refresher.refresh();\n                }\n            }\n        };\n        lrDeltasButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_Deltas\")); // NOI18N\n        \n        if (snapshotDumper != null) {\n            pdLabel = new GrayLabel(NbBundle.getMessage(MemoryView.class, \"MemoryView_LBL_Data\")); // NOI18N\n            \n            pdSnapshotButton = new JButton(NbBundle.getMessage(MemoryView.class,\n                        \"LBL_Snapshot\"), new ImageIcon(ImageUtilities.loadImage( // NOI18N\n                        \"org/graalvm/visualvm/sampler/resources/snapshot.png\", true))) { // NOI18N\n                protected void fireActionPerformed(ActionEvent event) {\n                    snapshotDumper.takeSnapshot((event.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n                }\n            };\n            pdSnapshotButton.setText(NbBundle.getMessage(MemoryView.class, \"MemoryView_LBL_Snapshot\")); // NOI18N\n            pdSnapshotButton.putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n        }\n        \n        ProfilerToolbar toolbar = ProfilerToolbar.create(true);\n\n//        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(lrLabel);\n        toolbar.addSpace(2);\n        toolbar.add(lrPauseButton);\n        toolbar.add(lrRefreshButton);\n        \n        toolbar.addSpace(5);\n        toolbar.add(lrDeltasButton);\n        \n        if (pdSnapshotButton != null) {\n        \n            toolbar.addSpace(2);\n            toolbar.addSeparator();\n            toolbar.addSpace(5);\n\n            toolbar.add(pdLabel);\n            toolbar.addSpace(2);\n            toolbar.add(pdSnapshotButton);\n        \n        }\n        \n        toolbar.addFiller();\n        \n        gcButton = new JButton(NbBundle.getMessage(MemoryView.class, \"LBL_Gc\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent event) {\n                new RequestProcessor(\"GC Processor\").post(new Runnable() { // NOI18N\n                    public void run() {\n                        try { memoryBean.gc(); } catch (Exception e) {\n                            setEnabled(false);\n                            Exceptions.printStackTrace(e);\n                        }\n                    };\n                });\n            }\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.width += 5;\n                return dim;\n            }\n        };\n        gcButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_Gc\")); // NOI18N\n        gcButton.setOpaque(false);\n        gcButton.setEnabled(memoryBean != null);\n        toolbar.add(gcButton);\n        \n        heapdumpButton = new JButton(NbBundle.getMessage(MemoryView.class, \"LBL_HeapDump\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent event) {\n                heapDumper.takeHeapDump((event.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n            }\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.width += 5;\n                return dim;\n            }\n        };\n        heapdumpButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_HeapDump\")); // NOI18N\n        heapdumpButton.setOpaque(false);\n        heapdumpButton.setEnabled(heapDumper != null);\n        toolbar.add(heapdumpButton);\n        \n        \n        setOpaque(false);\n        setLayout(new BorderLayout());\n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        add(tableContainer, BorderLayout.CENTER);\n    }\n    \n    private JComponent getBottomPanel() {\n        if (bottomPanel == null) {\n            bottomPanel = new JPanel(new FilterFindLayout());\n            bottomPanel.setOpaque(true);\n            bottomPanel.setBackground(UIManager.getColor(\"controlShadow\")); // NOI18N\n            add(bottomPanel, BorderLayout.SOUTH);\n        }\n        return bottomPanel;\n    }\n    \n    private void activateFilter() {\n        JComponent panel = getBottomPanel();\n        \n        if (filterPanel == null) {\n            filterPanel = FilterUtils.createFilterPanel(table);\n            panel.add(filterPanel);\n            Container parent = panel.getParent();\n            parent.invalidate();\n            parent.revalidate();\n            parent.repaint();\n        }\n        \n        panel.setVisible(true);\n        \n        filterPanel.setVisible(true);\n        filterPanel.requestFocusInWindow();\n    }\n    \n    private void activateSearch() {\n        JComponent panel = getBottomPanel();\n        \n        if (searchPanel == null) {\n            searchPanel = SearchUtils.createSearchPanel(table);\n            panel.add(searchPanel);\n            Container parent = panel.getParent();\n            parent.invalidate();\n            parent.revalidate();\n            parent.repaint();\n        }\n        \n        panel.setVisible(true);\n        \n        searchPanel.setVisible(true);\n        searchPanel.requestFocusInWindow();\n    }\n    \n    private JMenuItem[] createCustomMenuItems(Application application, String className) {\n        Collection<? extends ProfilerPopupCustomizer> customizers = Lookup.getDefault().lookupAll(ProfilerPopupCustomizer.class);\n        if (customizers.isEmpty()) return null;\n        \n        ProfiledSourceSelection pss = new ProfiledSourceSelection(application, className, Wildcards.ALLWILDCARD, null);\n        \n        List<JMenuItem> menuItems = new ArrayList<>(customizers.size());\n        \n        for (ProfilerPopupCustomizer customizer : customizers) {\n            if (customizer.supportsDataView(ProfilerPopupCustomizer.View.MEMORY, ProfilerPopupCustomizer.Mode.LIVE)) {\n                JMenuItem[] items = customizer.getMenuItems(pss, ProfilerPopupCustomizer.View.MEMORY, ProfilerPopupCustomizer.Mode.LIVE);\n                if (items != null) Collections.addAll(menuItems, items);\n            }\n        }\n        \n        return menuItems.isEmpty() ? null : menuItems.toArray(new JMenuItem[0]);\n    }\n    \n    \n    private static final String COL_NAME = NbBundle.getMessage(MemoryView.class, \"COL_Class_name\"); // NOI18N\n    private static final String COL_BYTES = NbBundle.getMessage(MemoryView.class, \"COL_Bytes\"); // NOI18N\n    private static final String COL_INSTANCES = NbBundle.getMessage(MemoryView.class, \"COL_Instances\"); // NOI18N\n    \n    private class HistogramTableModel extends AbstractTableModel {\n        \n        public String getColumnName(int columnIndex) {\n            if (columnIndex == 0) {\n                return COL_NAME;\n            } else if (columnIndex == 1) {\n                return COL_BYTES;\n            } else if (columnIndex == 2) {\n                return COL_INSTANCES;\n            }\n            \n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (columnIndex == 0) {\n                return String.class;\n            } else {\n                return Long.class;\n            }\n        }\n\n        public int getRowCount() {\n            return classes.size();\n        }\n\n        public int getColumnCount() {\n            return 3;\n        }\n\n        public Object getValueAt(int rowIndex, int columnIndex) {\n            if (columnIndex == 0) {\n                return classes.get(rowIndex).getName();\n            } else if (columnIndex == 1) {\n                return classes.get(rowIndex).getBytes();\n            } else if (columnIndex == 2) {\n                return classes.get(rowIndex).getInstancesCount();\n            }\n\n            return null;\n        }\n        \n    }\n    \n    \n    private final class FilterFindLayout implements LayoutManager {\n\n        public void addLayoutComponent(String name, Component comp) {}\n        public void removeLayoutComponent(Component comp) {}\n\n        public Dimension preferredLayoutSize(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            Dimension dim = new Dimension();\n            \n            if (filter != null && search != null) {\n                Dimension dim1 = filter.getPreferredSize();\n                Dimension dim2 = search.getPreferredSize();\n                dim.width = dim1.width + dim2.width + 1;\n                dim.height = Math.max(dim1.height, dim2.height);\n            } else if (filter != null) {\n                dim = filter.getPreferredSize();\n            } else if (search != null) {\n                dim = search.getPreferredSize();\n            }\n            \n            if ((filter != null || search != null) /*&& hasBottomFilterFindMargin()*/)\n                dim.height += 1;\n            \n            return dim;\n        }\n\n        public Dimension minimumLayoutSize(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            Dimension dim = new Dimension();\n            \n            if (filter != null && search != null) {\n                Dimension dim1 = filter.getMinimumSize();\n                Dimension dim2 = search.getMinimumSize();\n                dim.width = dim1.width + dim2.width + 1;\n                dim.height = Math.max(dim1.height, dim2.height);\n            } else if (filter != null) {\n                dim = filter.getMinimumSize();\n            } else if (search != null) {\n                dim = search.getMinimumSize();\n            }\n            \n            if ((filter != null || search != null) /*&& hasBottomFilterFindMargin()*/)\n                dim.height += 1;\n            \n            return dim;\n        }\n\n        public void layoutContainer(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            int bottomOffset = /* hasBottomFilterFindMargin() ? 1 :*/ 0;\n            \n            if (filter != null && search != null) {\n                Dimension size = parent.getSize();\n                int w = (size.width - 1) / 2;\n                filter.setBounds(0, 0, w, size.height - bottomOffset);\n                search.setBounds(w + 1, 0, size.width - w - 1, size.height - bottomOffset);\n            } else if (filter != null) {\n                Dimension size = parent.getSize();\n                filter.setBounds(0, 0, size.width, size.height - bottomOffset);\n            } else if (search != null) {\n                Dimension size = parent.getSize();\n                search.setBounds(0, 0, size.width, size.height - bottomOffset);\n            }\n        }\n        \n    }\n    \n\n    private static class DeltaClassInfo extends ClassInfo {\n\n        String name;\n        long instancesCount;\n        long bytes;\n\n        DeltaClassInfo(ClassInfo cInfo, boolean negative) {\n            name = cInfo.getName();\n            instancesCount = negative ? -cInfo.getInstancesCount() : cInfo.getInstancesCount();\n            bytes = negative ? -cInfo.getBytes() : cInfo.getBytes();\n        }\n\n        void add(ClassInfo cInfo) {\n            instancesCount += cInfo.getInstancesCount();\n            bytes += cInfo.getBytes();\n        }\n\n        public String getName() { return name; }\n        public long getInstancesCount() { return instancesCount; }\n        public long getBytes() { return bytes; }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/memory/ThreadsMemory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.memory;\n\nimport java.io.IOException;\nimport java.lang.management.ManagementFactory;\nimport java.lang.management.ThreadInfo;\nimport java.lang.management.ThreadMXBean;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.MBeanException;\nimport javax.management.MBeanServerConnection;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\nimport javax.management.ReflectionException;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class ThreadsMemory {\n    private static final ObjectName THREAD_NAME = getThreadName();\n    \n    private final ThreadMXBean threadBean;\n    private final MBeanServerConnection connection;\n\n    public ThreadsMemory(ThreadMXBean bean, MBeanServerConnection conn) {\n        threadBean = bean;\n        connection = conn;\n    }\n    \n    public ThreadsMemoryInfo getThreadsMemoryInfo() throws MBeanException, ReflectionException, IOException, InstanceNotFoundException {\n        long[] ids = threadBean.getAllThreadIds();\n        ThreadInfo[] tids = threadBean.getThreadInfo(ids);\n        Object[] args = new Object[] {ids};\n        String[] sigs = new String[] {\"[J\"};  // NOI18N\n        long[] memInfo = (long[])connection.invoke(THREAD_NAME, \"getThreadAllocatedBytes\", args, sigs);   // NOI18N\n        long time = System.currentTimeMillis();\n        \n        return new ThreadsMemoryInfo(time,tids,memInfo);\n    }   \n\n    private static ObjectName getThreadName() {\n        try {\n            return new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME);\n        } catch (MalformedObjectNameException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/memory/ThreadsMemoryInfo.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.memory;\n\nimport java.lang.management.ThreadInfo;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass ThreadsMemoryInfo {\n    \n    private List<ThreadInfo> threads = new ArrayList<>();\n    private List<Long> allocatedBytes = new ArrayList<>();\n    private Map<Long,Long> allocatedBytesMap;\n    private long totalBytes;\n    private long timestamp;\n    private long totalDiffBytes;\n    private long totalAllocatedBytesPerSecond;\n    \n    ThreadsMemoryInfo(long time, ThreadInfo[] tinfo, long[] minfo) {\n        allocatedBytesMap = new HashMap<>(threads.size()*4/3);\n        totalBytes = 0;\n        for (int i = 0; i <tinfo.length; i++) {\n            ThreadInfo ti = tinfo[i];\n            if (ti != null) {\n                threads.add(ti);\n                allocatedBytes.add(minfo[i]);\n                allocatedBytesMap.put(ti.getThreadId(),minfo[i]);\n                totalBytes+=minfo[i];\n            }\n        }\n        timestamp = time;\n    }\n    \n    List<ThreadInfo> getThreads() {\n        return threads;\n    }\n    \n    List<Long> getAllocatedBytes() {\n        return allocatedBytes;\n    }\n    \n    long getTotalBytes() {\n        return totalBytes;\n    }\n    \n    List<Long> getAllocatedDiffBytes(ThreadsMemoryInfo info) {\n        List<Long> allocDiff = new ArrayList<>(threads.size());\n        List<ThreadInfo> newThreads = info.getThreads();\n        List<Long> newAllocatedBytes = info.getAllocatedBytes();\n        \n        totalDiffBytes = 0;\n        for (int i=0; i<newThreads.size(); i++) {\n            ThreadInfo ti = newThreads.get(i);\n            Long oldAlloc = allocatedBytesMap.get(ti.getThreadId());\n            long diff;\n            \n            if (oldAlloc == null) {\n                oldAlloc = Long.valueOf(0);\n            }\n            diff = newAllocatedBytes.get(i)-oldAlloc;\n            allocDiff.add(diff);\n            totalDiffBytes += diff;\n        }\n        return allocDiff;\n    }\n    \n    long getTotalDiffBytes() {\n        return totalDiffBytes;\n    }\n    \n    List<Long> getAllocatedBytesPerSecond(ThreadsMemoryInfo newInfo) {\n        assert newInfo.timestamp >= timestamp;\n        List<Long> diff = getAllocatedDiffBytes(newInfo);\n        double secs = (newInfo.timestamp - timestamp) / 1000.0;\n        List<Long> diffPerSec = new ArrayList<>(diff.size());\n        \n        for (Long d : diff) {\n            diffPerSec.add(new Long((long)(d/secs)));\n        }\n        totalAllocatedBytesPerSecond = (long) (getTotalDiffBytes()/secs);\n        return diffPerSec;\n    }\n\n    long getTotalAllocatedBytesPerSecond() {\n        return totalAllocatedBytesPerSecond;\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/memory/ThreadsMemoryView.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.memory;\n\nimport org.graalvm.visualvm.sampler.AbstractSamplerSupport;\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.LayoutManager;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.ItemEvent;\nimport java.lang.management.MemoryMXBean;\nimport java.lang.management.ThreadInfo;\nimport java.util.Collections;\nimport java.util.List;\nimport javax.swing.AbstractButton;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.SortOrder;\nimport javax.swing.UIManager;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.LabelRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberRenderer;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class ThreadsMemoryView extends JPanel {\n    \n    private final AbstractSamplerSupport.Refresher refresher;\n    private boolean forceRefresh = false;\n    \n    private final MemoryMXBean memoryBean;\n    private final MemorySamplerSupport.HeapDumper heapDumper;\n    \n    private List<ThreadInfo> threads;\n    private List<Long> allocatedBytes;\n    private List<Long> allocatedBytesPerSec;\n    private ThreadsMemoryInfo currentThreadsInfo;\n    private ThreadsMemoryInfo baseThreadsInfo;\n    \n    private int totalThreads = -1;\n    private long totalBytes = -1;\n    \n    ThreadsMemoryView(AbstractSamplerSupport.Refresher refresher, MemoryMXBean memoryBean, MemorySamplerSupport.HeapDumper heapDumper) {    \n        this.refresher = refresher;\n        this.memoryBean = memoryBean;\n        this.heapDumper = heapDumper;\n        \n        threads = Collections.emptyList();\n        allocatedBytes = Collections.emptyList();\n        allocatedBytesPerSec = Collections.emptyList();\n        \n        initComponents();\n        \n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (isShowing()) ThreadsMemoryView.this.refresher.refresh();\n                }\n            }\n        });\n    }    \n    \n    void initSession() {\n    }\n    \n    boolean isPaused() {\n        return lrPauseButton.isSelected() && !forceRefresh;\n    }\n    \n    boolean isEmpty() {\n        return tableModel.getRowCount() == 0;\n    }\n    \n    void refresh(ThreadsMemoryInfo info) {\n        if (isPaused()) return;\n        forceRefresh = false;\n        threads = info.getThreads();\n        allocatedBytes = info.getAllocatedBytes();\n        totalBytes = info.getTotalBytes();\n        if (currentThreadsInfo != null) {\n            allocatedBytesPerSec = currentThreadsInfo.getAllocatedBytesPerSecond(info);\n            renderers[1].setMaxValue(currentThreadsInfo.getTotalAllocatedBytesPerSecond());\n        }\n        currentThreadsInfo = info;\n        \n        boolean diff = lrDeltasButton.isSelected();\n        if (diff) {\n            if (baseThreadsInfo == null) baseThreadsInfo = info;\n            totalThreads = threads.size() - baseThreadsInfo.getThreads().size();\n            allocatedBytes = baseThreadsInfo.getAllocatedDiffBytes(info);\n            totalBytes = baseThreadsInfo.getTotalDiffBytes();\n        } else {\n            if (baseThreadsInfo != null) baseThreadsInfo = null;\n            allocatedBytes = info.getAllocatedBytes();\n            totalBytes = info.getTotalBytes();\n            totalThreads = threads.size();\n        }\n        \n        renderers[0].setDiffMode(diff);\n        renderers[0].setMaxValue(totalBytes);\n        \n        threadsCount.setDiffMode(diff);\n        threadsCount.setValue(totalThreads, -1);\n        \n        threadsTotalBytes.setDiffMode(diff);\n        threadsTotalBytes.setValue(totalBytes, -1);\n\n        tableModel.fireTableDataChanged();\n    }\n    \n    void starting() {\n        lrPauseButton.setEnabled(true);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(true);\n    }\n    \n    void stopping() {\n        lrPauseButton.setEnabled(false);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(false);\n    }\n    \n    void terminated() {\n        lrPauseButton.setEnabled(false);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(false);\n        gcButton.setEnabled(false);\n        heapdumpButton.setEnabled(false);\n    }\n    \n    \n    private JLabel lrLabel;\n    private JToggleButton lrPauseButton;\n    private JButton lrRefreshButton;\n    private JToggleButton lrDeltasButton;\n    private ProfilerToolbar toolbar;\n    \n    private AbstractButton gcButton;\n    private AbstractButton heapdumpButton;\n    \n    private boolean popupPause;\n    \n    private JComponent bottomPanel;\n    private JComponent filterPanel;\n    private JComponent searchPanel;\n    \n    private NumberRenderer threadsCount;\n    private NumberRenderer threadsTotalBytes;\n    \n    private TreadsAllocTableModel tableModel;\n    private ProfilerTable table;\n    \n    private HideableBarRenderer[] renderers;\n    \n    private void initComponents() {\n        tableModel = new TreadsAllocTableModel();\n        \n        table = new ProfilerTable(tableModel, true, true, null) {\n//            public ClientUtils.SourceCodeSelection getUserValueForRow(int row) {\n//                return ThreadsMemoryView.this.getUserValueForRow(row);\n//            }\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                popup.add(createCopyMenuItem());\n                popup.addSeparator();\n                \n                popup.add(new JMenuItem(FilterUtils.ACTION_FILTER) {\n                    protected void fireActionPerformed(ActionEvent e) { ThreadsMemoryView.this.activateFilter(); }\n                });\n                popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {\n                    protected void fireActionPerformed(ActionEvent e) { ThreadsMemoryView.this.activateSearch(); }\n                });\n            }\n            protected void popupShowing() {\n                if (lrPauseButton.isEnabled() && !lrRefreshButton.isEnabled()) {\n                    popupPause = true;\n                    lrPauseButton.setSelected(true);\n                }\n            }\n            protected void popupHidden() {\n                if (lrPauseButton.isEnabled() && popupPause) {\n                    popupPause = false;\n                    lrPauseButton.setSelected(false);\n                }\n            }\n        };\n        \n        table.setColumnToolTips(new String[] { NbBundle.getMessage(ThreadsMemoryView.class, \"ThreadsMemoryView_TOOLTIP_Col_name\"), // NOI18N\n                                               NbBundle.getMessage(ThreadsMemoryView.class, \"ThreadsMemoryView_TOOLTIP_Col_bytes\"), // NOI18N\n                                               NbBundle.getMessage(ThreadsMemoryView.class, \"ThreadsMemoryView_TOOLTIP_Col_bytessec\") // NOI18N\n                                });\n        \n        table.providePopupMenu(true);\n        \n        table.setMainColumn(0);\n        table.setFitWidthColumn(0);\n        \n        table.setSortColumn(1);\n        table.setDefaultSortOrder(1, SortOrder.DESCENDING);\n        \n        renderers = new HideableBarRenderer[2];\n        \n        renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(Formatters.bytesFormat()));\n        renderers[0].setBarDiffMode(HideableBarRenderer.BarDiffMode.MODE_BAR_NORMAL);\n        renderers[1] = new HideableBarRenderer(new NumberPercentRenderer(Formatters.bytesFormat()));\n        renderers[1].setBarDiffMode(HideableBarRenderer.BarDiffMode.MODE_BAR_NORMAL);\n        \n        LabelRenderer threadRenderer = new LabelRenderer();\n        threadRenderer.setIcon(Icons.getIcon(ProfilerIcons.THREAD));\n        threadRenderer.setFont(threadRenderer.getFont().deriveFont(Font.BOLD));\n        \n        table.setColumnRenderer(0, threadRenderer);\n        table.setColumnRenderer(1, renderers[0]);\n        table.setColumnRenderer(2, renderers[1]);\n        \n        long refTime = 12345678;\n        renderers[0].setMaxValue(refTime);\n        renderers[1].setMaxValue(refTime);\n        table.setDefaultColumnWidth(1, renderers[0].getOptimalWidth());\n        table.setDefaultColumnWidth(2, renderers[1].getOptimalWidth());\n        \n        renderers[1].setMaxValue(1000 * 1000);\n        \n        ProfilerTableContainer tableContainer = new ProfilerTableContainer(table, false, null);\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        lrLabel = new GrayLabel(NbBundle.getMessage(ThreadsMemoryView.class, \"ThreadsMemoryView_LBL_Results\")); // NOI18N\n            \n        lrPauseButton = new JToggleButton(Icons.getIcon(GeneralIcons.PAUSE)) {\n            protected void fireItemStateChanged(ItemEvent event) {\n                boolean paused = isSelected();\n                lrRefreshButton.setEnabled(paused && !popupPause);\n                if (!paused) refresher.refresh();\n            }\n        };\n        lrPauseButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_Pause_results\")); // NOI18N\n\n        lrRefreshButton = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                forceRefresh = true;\n                refresher.refresh();\n            }\n        };\n        lrRefreshButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_Update_results\")); // NOI18N\n        lrRefreshButton.setEnabled(false);\n        \n        Icon icon = Icons.getIcon(ProfilerIcons.DELTA_RESULTS);\n        lrDeltasButton = new JToggleButton(icon) {\n            protected void fireActionPerformed(ActionEvent e) {\n                if (!lrPauseButton.isSelected()) {\n                    forceRefresh = true;\n                    refresher.refresh();\n                }\n            }\n        };\n        lrDeltasButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_Deltas\")); // NOI18N\n        \n        toolbar = ProfilerToolbar.create(true);\n\n//        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(lrLabel);\n        toolbar.addSpace(2);\n        toolbar.add(lrPauseButton);\n        toolbar.add(lrRefreshButton);\n        \n        toolbar.addSpace(5);\n        toolbar.add(lrDeltasButton);\n        \n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n        \n        toolbar.add(new GrayLabel(NbBundle.getMessage(ThreadsMemoryView.class, \"ThreadsMemoryView_LBL_Statistics\"))); // NOI18N\n        toolbar.addSpace(5);\n        \n        toolbar.add(new JLabel(NbBundle.getMessage(ThreadsMemoryView.class, \"ThreadsMemoryView_LBL_TCount\"))); // NOI18N\n        final Dimension tcDim = new Dimension(-1, -1);\n        final JLabel threadsCountL = new JLabel() {\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                \n                if (tcDim.width >= 0) {\n                    dim.width = Math.max(dim.width, tcDim.width);\n                    dim.height = Math.max(dim.height, tcDim.height);\n                }\n                \n                return dim;\n            }\n            public Dimension getMaximumSize() {\n                return getPreferredSize();\n            }\n        };\n        threadsCount = new NumberRenderer() {\n            public void setText(String text) {\n                super.setText(text);\n                threadsCountL.setText(super.getText());\n            }\n        };\n        threadsCount.setDiffMode(true);\n        threadsCount.setValue(99, -1);\n        tcDim.setSize(threadsCountL.getPreferredSize());\n        threadsCount.setDiffMode(false);\n        threadsCount.setValue(0, -1);\n        toolbar.addSpace(3);\n        toolbar.add(threadsCountL);\n        \n        toolbar.addSpace(5);\n        \n        toolbar.add(new JLabel(NbBundle.getMessage(ThreadsMemoryView.class, \"ThreadsMemoryView_LBL_Total_bytes\"))); // NOI18N\n        final JLabel threadsTotalBytesL = new JLabel();\n        threadsTotalBytes = new NumberRenderer(Formatters.bytesFormat()) {\n            public void setText(String text) {\n                super.setText(text);\n                threadsTotalBytesL.setText(super.getText());\n            }\n        };\n        toolbar.addSpace(3);\n        toolbar.add(threadsTotalBytesL);\n        \n        toolbar.addFiller();\n        \n        gcButton = new JButton(NbBundle.getMessage(MemoryView.class, \"LBL_Gc\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent event) {\n                new RequestProcessor(\"GC Processor\").post(new Runnable() { // NOI18N\n                    public void run() {\n                        try { memoryBean.gc(); } catch (Exception e) {\n                            setEnabled(false);\n                            Exceptions.printStackTrace(e);\n                        }\n                    };\n                });\n            }\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.width += 5;\n                return dim;\n            }\n        };\n        gcButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_Gc\")); // NOI18N\n        gcButton.setOpaque(false);\n        gcButton.setEnabled(heapDumper != null);\n        toolbar.add(gcButton);\n        \n        heapdumpButton = new JButton(NbBundle.getMessage(MemoryView.class, \"LBL_HeapDump\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent event) {\n                heapDumper.takeHeapDump((event.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n            }\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.width += 5;\n                return dim;\n            }\n        };\n        heapdumpButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_HeapDump\")); // NOI18N\n        heapdumpButton.setOpaque(false);\n        heapdumpButton.setEnabled(heapDumper != null);\n        toolbar.add(heapdumpButton);\n        \n        \n        setOpaque(false);\n        setLayout(new BorderLayout());\n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        add(tableContainer, BorderLayout.CENTER);\n    }\n    \n    private JComponent getBottomPanel() {\n        if (bottomPanel == null) {\n            bottomPanel = new JPanel(new FilterFindLayout());\n            bottomPanel.setOpaque(true);\n            bottomPanel.setBackground(UIManager.getColor(\"controlShadow\")); // NOI18N\n            add(bottomPanel, BorderLayout.SOUTH);\n        }\n        return bottomPanel;\n    }\n    \n    private void activateFilter() {\n        JComponent panel = getBottomPanel();\n        \n        if (filterPanel == null) {\n            filterPanel = FilterUtils.createFilterPanel(table);\n            panel.add(filterPanel);\n            Container parent = panel.getParent();\n            parent.invalidate();\n            parent.revalidate();\n            parent.repaint();\n        }\n        \n        panel.setVisible(true);\n        \n        filterPanel.setVisible(true);\n        filterPanel.requestFocusInWindow();\n    }\n    \n    private void activateSearch() {\n        JComponent panel = getBottomPanel();\n        \n        if (searchPanel == null) {\n            searchPanel = SearchUtils.createSearchPanel(table);\n            panel.add(searchPanel);\n            Container parent = panel.getParent();\n            parent.invalidate();\n            parent.revalidate();\n            parent.repaint();\n        }\n        \n        panel.setVisible(true);\n        \n        searchPanel.setVisible(true);\n        searchPanel.requestFocusInWindow();\n    }\n    \n    \n    private static final String COL_NAME = NbBundle.getMessage(MemoryView.class, \"COL_Thread_name\"); // NOI18N\n    private static final String COL_BYTES = NbBundle.getMessage(MemoryView.class, \"COL_ABytes\"); // NOI18N\n    private static final String COL_BYTES_SEC = NbBundle.getMessage(MemoryView.class, \"COL_ABytes_Sec\"); // NOI18N\n    \n    private class TreadsAllocTableModel extends AbstractTableModel {\n        \n        public String getColumnName(int columnIndex) {\n            if (columnIndex == 0) {\n                return COL_NAME;\n            } else if (columnIndex == 1) {\n                return COL_BYTES;\n            } else if (columnIndex == 2) {\n                return COL_BYTES_SEC;\n            }\n            \n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (columnIndex == 0) {\n                return String.class;\n            } else {\n                return Long.class;\n            }\n        }\n\n        public int getRowCount() {\n            return threads.size();\n        }\n\n        public int getColumnCount() {\n            return 3;\n        }\n\n        public Object getValueAt(int rowIndex, int columnIndex) {\n            if (columnIndex == 0) {\n                return threads.get(rowIndex).getThreadName();\n            } else if (columnIndex == 1) {\n                return allocatedBytes.get(rowIndex);\n            } else if (columnIndex == 2) {\n                return allocatedBytesPerSec.isEmpty() ? 0 :\n                       allocatedBytesPerSec.get(rowIndex);\n            }\n\n            return null;\n        }\n        \n    }\n    \n    \n    private final class FilterFindLayout implements LayoutManager {\n\n        public void addLayoutComponent(String name, Component comp) {}\n        public void removeLayoutComponent(Component comp) {}\n\n        public Dimension preferredLayoutSize(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            Dimension dim = new Dimension();\n            \n            if (filter != null && search != null) {\n                Dimension dim1 = filter.getPreferredSize();\n                Dimension dim2 = search.getPreferredSize();\n                dim.width = dim1.width + dim2.width + 1;\n                dim.height = Math.max(dim1.height, dim2.height);\n            } else if (filter != null) {\n                dim = filter.getPreferredSize();\n            } else if (search != null) {\n                dim = search.getPreferredSize();\n            }\n            \n            if ((filter != null || search != null) /*&& hasBottomFilterFindMargin()*/)\n                dim.height += 1;\n            \n            return dim;\n        }\n\n        public Dimension minimumLayoutSize(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            Dimension dim = new Dimension();\n            \n            if (filter != null && search != null) {\n                Dimension dim1 = filter.getMinimumSize();\n                Dimension dim2 = search.getMinimumSize();\n                dim.width = dim1.width + dim2.width + 1;\n                dim.height = Math.max(dim1.height, dim2.height);\n            } else if (filter != null) {\n                dim = filter.getMinimumSize();\n            } else if (search != null) {\n                dim = search.getMinimumSize();\n            }\n            \n            if ((filter != null || search != null) /*&& hasBottomFilterFindMargin()*/)\n                dim.height += 1;\n            \n            return dim;\n        }\n\n        public void layoutContainer(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            int bottomOffset = /* hasBottomFilterFindMargin() ? 1 :*/ 0;\n            \n            if (filter != null && search != null) {\n                Dimension size = parent.getSize();\n                int w = (size.width - 1) / 2;\n                filter.setBounds(0, 0, w, size.height - bottomOffset);\n                search.setBounds(w + 1, 0, size.width - w - 1, size.height - bottomOffset);\n            } else if (filter != null) {\n                Dimension size = parent.getSize();\n                filter.setBounds(0, 0, size.width, size.height - bottomOffset);\n            } else if (search != null) {\n                Dimension size = parent.getSize();\n                search.setBounds(0, 0, size.width, size.height - bottomOffset);\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sampler/src/org/graalvm/visualvm/sampler/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    \n    <folder name=\"Menu\">\n        <folder name=\"Applications\">\n            <file name=\"org-graalvm-visualvm-sampler-SampleApplicationAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-sampler-SampleApplicationAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1510\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"VisualVM\">\n        <folder name=\"Actions\">\n            <file name=\"org-graalvm-visualvm-sampler-SampleApplicationAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.sampler.SampleApplicationAction.instance\"/>\n            </file>\n        </folder>\n\n        <folder name=\"ExplorerPopupSelection\">\n            \n            <file name=\"org-graalvm-visualvm-sampler-SampleApplicationAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-sampler-SampleApplicationAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1010\"/>\n            </file>\n            \n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "visualvm/sampler.truffle/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.sampler.truffle\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.sampler.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n\n    <target name=\"compile-lib\" depends=\"init\">\n        <mkdir dir=\"${build.dir}/lib-classes\" />\n        <javac srcdir=\"libsrc\" destdir=\"${build.dir}/lib-classes\" deprecation=\"${build.compiler.deprecation}\" debug=\"${build.compiler.debug}\" source=\"1.8\">\n            <classpath>\n                <pathelement path=\"${lib.cp}\"/>\n            </classpath>\n        </javac>\n        <copy todir=\"${build.dir}/lib-classes\">\n            <fileset dir=\"libsrc\" excludes=\"${jar-excludes}\" />\n        </copy>\n        <delete dir=\"${build.dir}/lib-classes/org/graalvm/polyglot\"/> <!-- just stubs -->\n        <delete dir=\"${build.dir}/lib-classes/com\"/> <!-- just stubs -->\n\n    </target>\n\n    <target name=\"jar-lib\" depends=\"compile-lib\">\n        <mkdir dir=\"${cluster}/modules/ext\" />\n        <jar jarfile=\"${cluster}/modules/ext/stagent.jar\" manifest=\"libsrc/manifest.mf\" compress=\"false\">\n            <fileset dir=\"${build.dir}/lib-classes\" />\n        </jar>\n    </target>\n\n    <target name=\"compile\" depends=\"jar-lib, projectized-common.compile\" />\n\n</project>\n"
  },
  {
    "path": "visualvm/sampler.truffle/libsrc/com/oracle/truffle/api/nodes/LanguageInfo.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/* This is stub code written based on com.oracle.truffle.api.nodes package\n * javadoc published for GraalVM. It makes possible to compile code, which uses\n * GraalVM features on JDK 8. The compiled stub classes should never be\n * included in the final product.\n */\n\npackage com.oracle.truffle.api.nodes;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class LanguageInfo {\n\n    public String getId() {return null;}\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/libsrc/com/oracle/truffle/tools/profiler/CPUSampler.java",
    "content": "/*\n * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/* This is stub code written based on com.oracle.truffle.tools.profiler package\n * javadoc published for GraalVM. It makes possible to compile code, which uses\n * GraalVM features on JDK 8. The compiled stub classes should never be\n * included in the final product.\n */\npackage com.oracle.truffle.tools.profiler;\n\nimport java.util.List;\nimport java.util.Map;\nimport org.graalvm.polyglot.Engine;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class CPUSampler {\n\n    public static CPUSampler find(Engine engine) {\n        return null;\n    }\n\n    public Map<Thread, List<StackTraceEntry>> takeSample() {\n        return null;\n    }\n\n    public synchronized void setMode(Mode mode) {\n    }\n\n    public enum Mode {\n        EXCLUDE_INLINED_ROOTS,\n        ROOTS,\n        STATEMENTS\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/libsrc/com/oracle/truffle/tools/profiler/HeapMonitor.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/* This is stub code written based on com.oracle.truffle.tools.profiler package\n * javadoc published for GraalVM. It makes possible to compile code, which uses\n * GraalVM features on JDK 8. The compiled stub classes should never be\n * included in the final product.\n */\n\npackage com.oracle.truffle.tools.profiler;\n\nimport com.oracle.truffle.api.nodes.LanguageInfo;\nimport java.util.Map;\nimport org.graalvm.polyglot.Engine;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class HeapMonitor {\n\n    public static HeapMonitor find(Engine engine) {return null;}\n    public boolean isCollecting() {return false;}\n    public void setCollecting(boolean b) {}\n    public boolean hasData() {return false;}\n    public Map<LanguageInfo, Map<String, HeapSummary>> takeMetaObjectSummary() {return null;}\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/libsrc/com/oracle/truffle/tools/profiler/HeapSummary.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/* This is stub code written based on com.oracle.truffle.tools.profiler package\n * javadoc published for GraalVM. It makes possible to compile code, which uses\n * GraalVM features on JDK 8. The compiled stub classes should never be\n * included in the final product.\n */\n\npackage com.oracle.truffle.tools.profiler;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class HeapSummary {\n\n    public long getTotalInstances() {return 0;}\n    public long getTotalBytes() {return 0;}\n    public long getAliveInstances() {return 0;}\n    public long getAliveBytes() {return 0;}\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/libsrc/com/oracle/truffle/tools/profiler/StackTraceEntry.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/* This is stub code written based on com.oracle.truffle.tools.profiler package\n * javadoc published for GraalVM. It makes possible to compile code, which uses\n * GraalVM features on JDK 8. The compiled stub classes should never be\n * included in the final product.\n */\n\npackage com.oracle.truffle.tools.profiler;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class StackTraceEntry {\n\n    public StackTraceElement toStackTraceElement() {return null;}\n    public boolean isCompiled() {return false;}\n    public boolean isInlined() {return false;}\n\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/libsrc/manifest.mf",
    "content": "Agent-Class: org.graalvm.visualvm.sampler.truffle.stagent.TruffleJMX\nBoot-Class-Path: stagent.jar\n"
  },
  {
    "path": "visualvm/sampler.truffle/libsrc/org/graalvm/polyglot/Engine.java",
    "content": "/*\n * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n/* This is stub code written based on org.graalvm.polyglot package javadoc\n * published for GraalVM. It makes possible to compile code, which uses\n * GraalVM features on JDK 8. The compiled stub classes should never be\n * included in the final product.\n */\n\npackage org.graalvm.polyglot;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class Engine {\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/libsrc/org/graalvm/visualvm/sampler/truffle/stagent/AgentClassLoader.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle.stagent;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.net.URL;\nimport java.net.URLClassLoader;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass AgentClassLoader extends URLClassLoader {\n\n    private final static String packageName;\n\n    static {\n        packageName = TruffleClassLoader.class.getPackage().getName() + \".\";\n    }\n\n    AgentClassLoader(URL[] urls, ClassLoader parent) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {\n        super(urls, parent);\n    }\n\n    @Override\n    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {\n        if (name.startsWith(packageName)) {\n            Class<?> c = findClass(name);\n            if (resolve) {\n                resolveClass(c);\n            }\n            return c;\n        }\n        return super.loadClass(name, resolve);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/libsrc/org/graalvm/visualvm/sampler/truffle/stagent/Truffle.java",
    "content": "/*\n * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.truffle.stagent;\n\nimport com.oracle.truffle.api.nodes.LanguageInfo;\nimport com.oracle.truffle.tools.profiler.CPUSampler;\nimport com.oracle.truffle.tools.profiler.CPUSampler.Mode;\nimport com.oracle.truffle.tools.profiler.HeapMonitor;\nimport com.oracle.truffle.tools.profiler.HeapSummary;\nimport com.oracle.truffle.tools.profiler.StackTraceEntry;\nimport java.lang.management.ManagementFactory;\nimport java.lang.management.ThreadMXBean;\nimport java.lang.ref.Reference;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.polyglot.Engine;\nimport sun.misc.Unsafe;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class Truffle implements TruffleMBean {\n\n    private static final String POLYGLOTENGINEIMPL_CLASS_NAME = \"com.oracle.truffle.polyglot.PolyglotEngineImpl\";\n\n    private ThreadMXBean threadBean;\n    private Method Engine_findActiveEngines;\n    private Set<?> engines;\n    private Unsafe unsafe;\n    private boolean trackFlags;\n\n    public Truffle(Unsafe u) {\n        unsafe = u;\n        threadBean = ManagementFactory.getThreadMXBean();\n        Engine_findActiveEngines = getFindActiveEngines();\n        if (Engine_findActiveEngines == null) {\n            engines = getEngines();\n            if (engines == null) {\n                throw new IllegalStateException();\n            }\n        }\n        try {\n            for (CPUSampler stacks : getAllStackTracesInstances()) {\n                if (TruffleJMX.DEBUG) {\n                    System.out.println(\"Stacks \" + stacks + \" \" + Integer.toHexString(System.identityHashCode(stacks)));\n                    System.out.println(threadDump(stacks));\n                }\n            }\n        } catch (Throwable ex) {\n            ex.printStackTrace();\n        }\n    }\n\n    @Override\n    public Map<String, Object>[] dumpAllThreads() {\n        try {\n            Collection<CPUSampler> allThreads = getAllStackTracesInstances();\n            List<Map<String, Object>> threads = new ArrayList<>(allThreads.size());\n\n            for (CPUSampler stacks : allThreads) {\n                Map<Thread, List<StackTraceEntry>> all = stacks.takeSample();\n                if (all != null) {\n                    for (Map.Entry<Thread, List<StackTraceEntry>> entry : all.entrySet()) {\n                        Thread t = entry.getKey();\n                        long tid = t.getId();\n                        long threadCpuTime = threadBean.getThreadCpuTime(tid);\n                        TruffleStackTrace stack = getStackTraceElements(entry.getValue());\n                        String name = t.getName();\n                        Map<String, Object> threadInfo = new HashMap<>();\n                        threadInfo.put(\"stack\", stack.stack);\n                        if (trackFlags) {\n                            threadInfo.put(\"flags\", stack.flags);\n                        }\n                        threadInfo.put(\"name\", name);\n                        threadInfo.put(\"tid\", tid);\n                        threadInfo.put(\"threadCpuTime\", threadCpuTime);\n                        threads.add(threadInfo);\n                    }\n                }\n            }\n            return threads.toArray(new Map[0]);\n        } catch (Throwable ex) {\n            ex.printStackTrace();\n        }\n        return new Map[0];\n    }\n\n    private String threadDump(CPUSampler stacks) {\n        Map<Thread, List<StackTraceEntry>> all = stacks.takeSample();\n        if (all == null) {\n            return \"Thread dump EMPTY\";\n        }\n        StringBuilder sb = new StringBuilder();\n        sb.append(\"Thread dump:\\n\"); // NOI18N\n        for (Map.Entry<Thread, List<StackTraceEntry>> entry : all.entrySet()) {\n            sb.append(entry.getKey().getName()).append('\\n');\n            if (entry.getValue() == null) {\n                sb.append(\"  no information\\n\"); // NOI18N\n                continue;\n            }\n            for (StackTraceEntry stackTraceEntry : entry.getValue()) {\n                StackTraceElement stackTraceElement = stackTraceEntry.toStackTraceElement();\n\n                sb.append(\"  \");\n                sb.append(stackTraceElement.getClassName()).append('.').append(stackTraceElement.getMethodName());\n                String fileName = stackTraceElement.getFileName();\n                int lastSep = fileName.lastIndexOf('/');\n\n                if (lastSep != -1) {\n                    fileName = fileName.substring(lastSep+1);\n                }\n                sb.append(\" (\").append(fileName).append(\":\").append(stackTraceElement.getLineNumber()).append(')');\n                sb.append('\\n');\n            }\n        }\n        return sb.toString();\n    }\n\n    private Method getFindActiveEngines() {\n        try {\n            Method m = Engine.class.getDeclaredMethod(\"findActiveEngines\");\n            m.setAccessible(true);\n            if (TruffleJMX.DEBUG) System.out.println(\"Engine \"+m.getDeclaringClass()+\" cl \"+m.getDeclaringClass().getClassLoader());\n            return m;\n        } catch (SecurityException ex) {\n            Logger.getLogger(Truffle.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (NoSuchMethodException ex) {\n            Logger.getLogger(Truffle.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (Exception ex) {\n            if (TruffleJMX.DEBUG) {\n                Logger.getLogger(Truffle.class.getName()).log(Level.SEVERE, null, ex);\n            }\n        }\n        return null;\n    }\n\n    private Set<?> getEngines() {\n        Set<?> locEngines = null;\n        try {\n            locEngines = getEnginesFromClass(Engine.class);\n            if (locEngines == null) {\n                Class<?> POLY_CLASS = Class.forName(POLYGLOTENGINEIMPL_CLASS_NAME);\n                locEngines = getEnginesFromClass(POLY_CLASS);\n            }\n        } catch (ClassNotFoundException ex) {\n            Logger.getLogger(Truffle.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (SecurityException ex) {\n            Logger.getLogger(Truffle.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        return locEngines;\n    }\n\n    private Set<?> getEnginesFromClass(Class<?> engineClass) {\n        try {\n            Field f = engineClass.getDeclaredField(\"ENGINES\");\n            Object enginesVal = getValueOfStaticField(f);\n            if (enginesVal instanceof Map) {\n                return ((Map)enginesVal).keySet();\n            }\n            return (Set)enginesVal;\n        } catch (NoSuchFieldException ex) {\n            Logger.getLogger(Truffle.class.getName()).log(TruffleJMX.DEBUG ? Level.INFO : Level.FINE, null, ex);\n        } catch (SecurityException ex) {\n            Logger.getLogger(Truffle.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        return null;\n    }\n\n    private Object getValueOfStaticField(Field f) {\n        try {\n            Object base = unsafe.staticFieldBase(f);\n            return unsafe.getObject(base, unsafe.staticFieldOffset(f));\n        } catch (SecurityException ex) {\n            Logger.getLogger(Truffle.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        return null;\n    }\n\n    private Collection<Engine> getAllEngineInstances() {\n        try {\n            if (Engine_findActiveEngines == null) {\n                Collection<Engine> en = new ArrayList<>();\n                for (Object o : engines) {\n                    Engine e;\n\n                    if (o instanceof Engine) {\n                        e = (Engine) o;\n                    } else if (o instanceof Reference) {\n                        e = (Engine) ((Reference)o).get();\n                    } else {\n                        Field cf = TruffleJMX.getDeclaredField(o, \"creatorApi\", \"api\");\n                        e = (Engine) unsafe.getObject(o, unsafe.objectFieldOffset(cf));\n                    }\n                    en.add(e);\n                }\n                return en;\n            } else {\n                return (Collection<Engine>) Engine_findActiveEngines.invoke(null);\n            }\n        } catch (IllegalArgumentException ex) {\n            Logger.getLogger(Truffle.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (IllegalAccessException ex) {\n            Logger.getLogger(Truffle.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (InvocationTargetException ex) {\n            Logger.getLogger(Truffle.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (NoSuchFieldException ex) {\n            Logger.getLogger(Truffle.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (SecurityException ex) {\n            Logger.getLogger(Truffle.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        return Collections.emptyList();\n    }\n\n    private Collection<CPUSampler> getAllStackTracesInstances() {\n        List<CPUSampler> allInstances = new ArrayList<>();\n        Collection<Engine> all = getAllEngineInstances();\n\n        for (Engine engine : all) {\n            if (engine == null) continue;\n            CPUSampler sampler = CPUSampler.find(engine);\n\n            if (sampler != null) {\n                allInstances.add(sampler);\n            }\n        }\n        return allInstances;\n    }\n\n    private static final int COMPILED  = 1;  // 0001\n    private static final int INLINED   = 2;  // 0010\n\n    private TruffleStackTrace getStackTraceElements(List<StackTraceEntry> entries) {\n        StackTraceElement[] stack = new StackTraceElement[entries.size()];\n        byte[] flags = new byte[entries.size()];\n\n        for (int i = 0; i < entries.size(); i++) {\n            StackTraceEntry entry = entries.get(i);\n            stack[i] = entry.toStackTraceElement();\n            flags[i] |= entry.isCompiled() ? COMPILED:0;\n            flags[i] |= entry.isInlined() ? INLINED:0;\n            if (TruffleJMX.DEBUG && flags[i] != 0 ) {\n                System.out.println(stack[i]+\" \"+Integer.toHexString(flags[i])+\" \"+entry.isInlined());\n            }\n        }\n        return new TruffleStackTrace(stack, flags);\n    }\n\n    @Override\n    public boolean isStackTracesEnabled() {\n        return !getAllStackTracesInstances().isEmpty();\n    }\n\n    private Collection<HeapMonitor> getAllHeapHistogramInstances() {\n        List<HeapMonitor> allInstances = new ArrayList<>();\n        Collection<Engine> all = getAllEngineInstances();\n\n        for (Engine engine : all) {\n            if (engine == null) continue;\n            HeapMonitor heapHisto = HeapMonitor.find(engine);\n\n            if (heapHisto != null) {\n                if (!heapHisto.isCollecting()) {\n                    heapHisto.setCollecting(true);\n                }\n                allInstances.add(heapHisto);\n            }\n        }\n        return allInstances;\n    }\n\n    @Override\n    public Map<String, Object>[] heapHistogram() {\n        Collection<HeapMonitor> all = getAllHeapHistogramInstances();\n\n        for (HeapMonitor histo : all) {\n            if (histo.hasData()) {\n                Map<LanguageInfo, Map<String, HeapSummary>> info = histo.takeMetaObjectSummary();\n                try {\n                    return toMap(info);\n                } catch (Throwable ex) {\n                    Logger.getLogger(Truffle.class.getName()).log(Level.SEVERE, null, ex);\n                }\n            }\n        }\n        return new Map[0];\n    }\n\n    @Override\n    public boolean isHeapHistogramEnabled() {\n        return !getAllHeapHistogramInstances().isEmpty();\n    }\n\n    Map<String, Object>[] toMap(Map<LanguageInfo, Map<String, HeapSummary>> summaries) throws NoSuchFieldException {\n        List<Map<String, Object>> heapHisto = new ArrayList<>(summaries.size());\n        for (Map.Entry<LanguageInfo, Map<String, HeapSummary>> objectsByLanguage : summaries.entrySet()) {\n            String langId = getLanguageId(objectsByLanguage.getKey());\n            for (Map.Entry<String, HeapSummary> objectsByMetaObject : objectsByLanguage.getValue().entrySet()) {\n                HeapSummary mi = objectsByMetaObject.getValue();\n                Map<String, Object> metaObjMap = new HashMap<>();\n                metaObjMap.put(\"language\", langId);\n                metaObjMap.put(\"name\", objectsByMetaObject.getKey());\n                metaObjMap.put(\"allocatedInstancesCount\", mi.getTotalInstances());\n                metaObjMap.put(\"bytes\", mi.getTotalBytes());\n                metaObjMap.put(\"liveInstancesCount\", mi.getAliveInstances());\n                metaObjMap.put(\"liveBytes\", mi.getAliveBytes());\n                heapHisto.add(metaObjMap);\n            }\n        }\n        return heapHisto.toArray(new Map[0]);\n    }\n\n    private String getLanguageId(Object lang) throws NoSuchFieldException, SecurityException {\n        if (Engine_findActiveEngines != null) {\n            return ((LanguageInfo)lang).getId();\n        }\n        Field f = lang.getClass().getDeclaredField(\"id\");\n        String lId = (String) unsafe.getObject(lang, unsafe.objectFieldOffset(f));\n        return lId;\n    }\n\n    @Override\n    public void setTrackFlags(boolean trackFlags) {\n        this.trackFlags = trackFlags;\n    }\n\n    @Override\n    public void setMode(String modeStr) {\n        if (\"ROOTS\".equals(modeStr)) {\n            setMode(Mode.ROOTS);\n        } else if (\"EXCLUDE_INLINED_ROOTS\".equals(modeStr)) {\n            setMode(Mode.EXCLUDE_INLINED_ROOTS);\n        } else if (\"STATEMENTS\".equals(modeStr)) {\n            setMode(Mode.STATEMENTS);\n        }\n    }\n\n    @Override\n    public boolean isModeAvailable() {\n        try {\n            Class.forName(\"com.oracle.truffle.tools.profiler.CPUSampler$Mode\"); // NOI18N\n        } catch (ClassNotFoundException ex) {\n            return false;\n        }\n        return true;\n    }\n\n    private void setMode(Mode m) {\n        Collection<Engine> all = getAllEngineInstances();\n\n        for (Engine engine : all) {\n            if (engine == null) continue;\n            CPUSampler sampler = CPUSampler.find(engine);\n\n            if (sampler != null) {\n                sampler.setMode(m);\n            }\n        }\n    }\n\n    private static class TruffleStackTrace {\n        private StackTraceElement[] stack;\n        private byte[] flags;\n\n        private TruffleStackTrace(StackTraceElement[] stack, byte[] flags) {\n            this.stack = stack;\n            this.flags = flags;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/libsrc/org/graalvm/visualvm/sampler/truffle/stagent/TruffleClassLoader.java",
    "content": "/*\n * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle.stagent;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport sun.misc.Unsafe;\n\n/**\n *\n * @author Tomas Hurka\n */\nclass TruffleClassLoader extends ClassLoader {\n    private static final String TRUFFLE_LOCATOR_CLASS_NAME = \"com.oracle.truffle.api.impl.TruffleLocator\";\n    private static final String GRAALVM_LOCATOR_CLASS_NAME = \"com.oracle.graalvm.locator.GraalVMLocator\";\n\n    private Collection<ClassLoader> loaders;\n\n    TruffleClassLoader(ClassLoader parent, Unsafe unsafe) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {\n        super(parent);\n        loaders = getTruffleLocatorLoaders(parent);\n        if (loaders == null) {\n            // try different way\n            loaders = getGraalVMLocatorLoaders(parent, unsafe);\n        }\n    }\n\n    @Override\n    public Class<?> findClass(String name) throws ClassNotFoundException {\n        if (loaders == null) {\n            return super.findClass(name);\n        }\n        for (ClassLoader loader : loaders) {\n            if (loader == null) {\n                continue;\n            }\n            try {\n                return loader.loadClass(name);\n            } catch (ClassNotFoundException ex) {\n                continue;\n            }\n        }\n        throw new ClassNotFoundException(name);\n    }\n\n    private static Class<?> getClass(ClassLoader cl, String className) throws ClassNotFoundException {\n        if (cl == null) {\n            return Class.forName(className);\n        } else {\n            return cl.loadClass(className);\n        }\n    }\n\n    private static Collection<ClassLoader> getTruffleLocatorLoaders(ClassLoader cl) {\n        try {\n            Class LocatorClass = getClass(cl, TRUFFLE_LOCATOR_CLASS_NAME);\n            return (Collection<ClassLoader>) LocatorClass.getMethod(\"loaders\", (Class[])null).invoke(null, (Object[])null);\n        } catch (Exception ex) {\n            if (TruffleJMX.DEBUG) {\n                Logger.getLogger(TruffleClassLoader.class.getName()).log(Level.SEVERE, null, ex);\n            }\n        }\n        return null;\n    }\n\n    private static Collection<ClassLoader> getGraalVMLocatorLoaders(ClassLoader cl, Unsafe unsafe) {\n        try {\n            Class<?> LocatorClass = getClass(cl, GRAALVM_LOCATOR_CLASS_NAME);\n            Field f = LocatorClass.getDeclaredField(\"loader\");\n            Object base = unsafe.staticFieldBase(f);\n            ClassLoader loader = (ClassLoader) unsafe.getObject(base, unsafe.staticFieldOffset(f));\n            return Collections.singletonList(loader);\n        } catch (ClassNotFoundException ex) {\n            if (TruffleJMX.DEBUG) {\n                Logger.getLogger(TruffleClassLoader.class.getName()).log(Level.SEVERE, null, ex);\n            }\n        } catch (Exception ex) {\n            Logger.getLogger(TruffleClassLoader.class.getName()).log(Level.SEVERE, null, ex);\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/libsrc/org/graalvm/visualvm/sampler/truffle/stagent/TruffleJMX.java",
    "content": "/*\n * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle.stagent;\n\nimport java.io.IOException;\nimport java.lang.instrument.Instrumentation;\nimport java.lang.management.ManagementFactory;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.net.JarURLConnection;\nimport java.net.URL;\nimport java.net.URLClassLoader;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.InstanceAlreadyExistsException;\nimport javax.management.MBeanRegistrationException;\nimport javax.management.MBeanServer;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.NotCompliantMBeanException;\nimport javax.management.ObjectName;\nimport sun.misc.Unsafe;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class TruffleJMX {\n\n    static boolean DEBUG = false;\n\n    /**\n     * @param args the command line arguments\n     */\n    public static void agentmain(final String agentArgs, final Instrumentation inst) throws MalformedObjectNameException, InstantiationException, IllegalAccessException, InterruptedException {\n        try {\n            Unsafe unsafe = Unsafe.getUnsafe();\n            if (DEBUG) System.out.println(\"Unsafe \"+unsafe);\n            Object context = getContext();\n            Object impl = getContextImpl(context);\n            URL jarURL = getJarURL();\n            if (impl == null) impl = context;\n            URLClassLoader ur = getSamplerClassLoader(impl, unsafe, jarURL);\n            Object truffle = getTruffleInstance(ur, unsafe);\n\n            registerMXBean(truffle);\n        } catch (NoSuchFieldException ex) {\n            Logger.getLogger(TruffleJMX.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (SecurityException ex) {\n            Logger.getLogger(TruffleJMX.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (IllegalArgumentException ex) {\n            Logger.getLogger(TruffleJMX.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (IllegalAccessException ex) {\n            Logger.getLogger(TruffleJMX.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (ClassNotFoundException ex) {\n            Logger.getLogger(TruffleJMX.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (IOException ex) {\n            Logger.getLogger(TruffleJMX.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (NoSuchMethodException ex) {\n            Logger.getLogger(TruffleJMX.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (InvocationTargetException ex) {\n            Logger.getLogger(TruffleJMX.class.getName()).log(Level.SEVERE, null, ex);\n        }\n    }\n\n    private static Object getContext() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, SecurityException, IllegalAccessException, IllegalArgumentException {\n        // return org.graalvm.polyglot.Context.newBuilder().allowExperimentalOptions(true)\n        ClassLoader systemCl = ClassLoader.getSystemClassLoader();\n        Class<?> contextClass = systemCl.loadClass(\"org.graalvm.polyglot.Context\");\n        Method builderMethod = contextClass.getMethod(\"newBuilder\", String[].class);\n        Object builder = builderMethod.invoke(null, new Object[] {new String[0]});\n        Method allowExpMethod = builder.getClass().getMethod(\"allowExperimentalOptions\", boolean.class);\n        builder = allowExpMethod.invoke(builder, new Object[] {Boolean.TRUE});\n        Method buildMethod = builder.getClass().getMethod(\"build\");\n        Object context = buildMethod.invoke(builder, new Object[]{});\n        if (DEBUG) System.out.println(\"Context: \" + context.getClass());\n        if (DEBUG) System.out.println(\"Context ClassLoader: \" + context.getClass().getClassLoader());\n        return context;\n    }\n\n    private static Object getContextImpl(Object context) throws IllegalArgumentException, SecurityException, NoSuchFieldException, IllegalAccessException {\n        // return context.impl or context.receiver or context.dispatch\n        Field implField = getDeclaredField(context, \"impl\", \"receiver\", \"dispatch\");\n        try {\n            implField.setAccessible(true);\n            Object impl = implField.get(context);\n            if (DEBUG) System.out.println(\"Context Impl: \" + impl);\n            if (DEBUG && impl != null) System.out.println(\"Context Impl ClassLoader: \" + impl.getClass().getClassLoader());\n            return impl;\n        } catch (RuntimeException ex) {\n            if (ex.getClass().getName().equals(\"java.lang.reflect.InaccessibleObjectException\")) {\n                return null;\n            }\n            throw ex;\n        }\n    }\n\n    static Field getDeclaredField(Object obj, String... names) throws NoSuchFieldException {\n        Map<String,Field> fields = new HashMap<>();\n        for (Field f : obj.getClass().getDeclaredFields()) fields.put(f.getName(), f);\n        for (String name : names) {\n            Field f = fields.get(name);\n            if (f!=null) return f;\n        }\n        throw new NoSuchFieldException(Arrays.toString(names));\n    }\n\n    private static URL getJarURL() throws IOException {\n        URL classUrl = ClassLoader.getSystemResource(\"org/graalvm/visualvm/sampler/truffle/stagent/Truffle.class\");\n        JarURLConnection connection = (JarURLConnection) classUrl.openConnection();\n        if (DEBUG) System.out.println(\"URL \"+classUrl);\n        if (DEBUG) System.out.println(\"URL \"+connection.getJarFileURL());\n        return connection.getJarFileURL();\n    }\n\n    private static URLClassLoader getSamplerClassLoader(Object impl, Unsafe unsafe, URL jarURL) throws IllegalAccessException, NoSuchMethodException, ClassNotFoundException, InvocationTargetException, IllegalArgumentException {\n        TruffleClassLoader truffleLoader = new TruffleClassLoader(impl.getClass().getClassLoader(), unsafe);\n        URLClassLoader ur = new AgentClassLoader(new URL[] {jarURL}, truffleLoader);\n        if (DEBUG) System.out.println(\"Class \"+ur.loadClass(\"com.oracle.truffle.api.TruffleStackTraceElement\"));\n        if (DEBUG) System.out.println(\"Class \"+ur.loadClass(\"com.oracle.truffle.api.impl.TruffleLocator\"));\n        //            if (DEBUG) System.out.println(\"Class \"+ur.loadClass(\"com.oracle.truffle.tools.profiler.StackTraces\"));\n        if (DEBUG) System.out.println(\"Class \"+ur.loadClass(\"com.oracle.truffle.polyglot.PolyglotEngineImpl\"));\n        if (DEBUG) System.out.println(\"Class \"+ur.loadClass(\"com.oracle.truffle.tools.profiler.CPUSampler\"));\n        return ur;\n    }\n\n    private static Object getTruffleInstance(URLClassLoader ur, Unsafe unsafe) throws IllegalAccessException, SecurityException, IllegalArgumentException, NoSuchMethodException, InstantiationException, InvocationTargetException, ClassNotFoundException {\n        Class<?> TruffleClass = ur.loadClass(Truffle.class.getName());\n        if (DEBUG) System.out.println(\"Class \"+TruffleClass+\" ClassLoader \"+TruffleClass.getClassLoader());\n        Constructor<?> TruffleClassConstructor = TruffleClass.getConstructor(Unsafe.class);\n        return TruffleClassConstructor.newInstance(unsafe);\n    }\n\n    private static void registerMXBean(Object truffle) {\n        try {\n            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();\n            ObjectName mxbeanName = new ObjectName(\"com.truffle:type=Threading\");\n            mbs.registerMBean(truffle, mxbeanName);\n        } catch (InstanceAlreadyExistsException ex) {\n            Logger.getLogger(TruffleJMX.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (MBeanRegistrationException ex) {\n            Logger.getLogger(TruffleJMX.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (NotCompliantMBeanException ex) {\n            Logger.getLogger(TruffleJMX.class.getName()).log(Level.SEVERE, null, ex);\n        } catch (MalformedObjectNameException ex) {\n            Logger.getLogger(TruffleJMX.class.getName()).log(Level.SEVERE, null, ex);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/libsrc/org/graalvm/visualvm/sampler/truffle/stagent/TruffleMBean.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle.stagent;\n\nimport java.util.Map;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic interface TruffleMBean {\n    public Map<String, Object>[] dumpAllThreads();\n    public boolean isStackTracesEnabled();\n    public void setTrackFlags(boolean trackFlags);\n    public void setMode(String mode);\n    public boolean isModeAvailable();\n    public Map<String, Object>[] heapHistogram();\n    public boolean isHeapHistogramEnabled();\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.sampler.truffle/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/sampler/truffle/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.1\nOpenIDE-Module-Install: org/graalvm/visualvm/sampler/truffle/Installer.class\n"
  },
  {
    "path": "visualvm/sampler.truffle/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.sampler.truffle-impl\" basedir=\"..\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/sampler.truffle/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=20861fe1\nbuild.xml.script.CRC32=8a00031d\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=20861fe1\nnbproject/build-impl.xml.script.CRC32=584e6d59\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/sampler.truffle/nbproject/project.properties",
    "content": "javac.source=1.8\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Tomas Hurka, Jiri Sedlacek\nlib.cp=${nbjdk.home}/jre/lib/truffle/truffle-api.jar:${nbjdk.home}/jre/tools/profiler/truffle-profiler.jar\nextra.module.files=modules/ext/stagent.jar\ncp.extra=${tools.jar}\nmodule.javadoc.packages=org.graalvm.visualvm.sampler.truffle.*\n"
  },
  {
    "path": "visualvm/sampler.truffle/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.sampler.truffle</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.coredump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.heapdump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.common</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.jfluid</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.profiler.api</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.profiling</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.2</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.threaddump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.4</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.15.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.17.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.11</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages/>\n            <class-path-extension>\n                <runtime-relative-path>ext/stagent.jar</runtime-relative-path>\n            </class-path-extension>\n            <extra-compilation-unit>\n                <package-root>libsrc</package-root>\n                <classpath>${lib.cp}</classpath>\n                <built-to>${build.dir}/lib-classes</built-to>\n                <built-to>${cluster}/modules/ext/stagent.jar</built-to>\n            </extra-compilation-unit>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/sampler.truffle/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/AbstractSamplerSupport.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle;\n\nimport java.util.Timer;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class AbstractSamplerSupport {\n\n    public abstract DataViewComponent.DetailsView[] getDetailsView();\n\n    public abstract boolean startSampling(ProfilingSettings settings, int samplingRate, int refreshRate);\n\n    public abstract void stopSampling();\n\n    public abstract void terminate();\n\n\n    protected abstract Timer getTimer();\n    \n    \n    protected final void checkCPUSamplingRate(int samplingRate) {\n        if (samplingRate < 20)\n            ProfilerDialogs.displayWarningDNSA(NbBundle.getMessage(AbstractSamplerSupport.class, \"MSG_High_Sampling_Frequency\"), // NOI18N\n                                               NbBundle.getMessage(AbstractSamplerSupport.class, \"CAP_High_Sampling_Frequency\"), // NOI18N\n                                               null,\n                                               \"org.graalvm.visualvm.sampler.truffle.AbstractSamplerSupport.checkCPUSamplingRate\", // NOI18N\n                                               false);\n    }\n\n\n    public static abstract class Refresher {\n        private static final long REFRESH_THRESHOLD = 100;\n        private long lastRefresh;\n\n        public synchronized final void refresh() {\n            if (checkRefresh()) {\n                long currentTime = System.currentTimeMillis();\n                if (currentTime - lastRefresh >= REFRESH_THRESHOLD) {\n                    lastRefresh = currentTime;\n                    doRefresh();\n                }\n            }\n        }\n\n        public abstract void setRefreshRate(int refreshRate);\n        public abstract int getRefreshRate();\n\n        protected abstract boolean checkRefresh();\n        protected abstract void doRefresh();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/ApplicationSamplerView.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle;\n\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport javax.swing.ImageIcon;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasupport.DataRemovedListener;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ApplicationSamplerView extends DataSourceView {\n    \n    private static final String IMAGE_PATH = \"org/graalvm/visualvm/sampler/resources/sampler.png\"; // NOI18N\n\n    private SamplerImpl sampler;\n\n    private ApplicationListener applicationListener;\n\n\n    ApplicationSamplerView(Application application) {\n        super(application, NbBundle.getMessage(ApplicationSamplerView.class, \"LBL_Sampler\"), // NOI18N\n              new ImageIcon(ImageUtilities.loadImage(IMAGE_PATH, true)).getImage(), 36, false);\n\n    }\n\n\n    protected void willBeAdded() {\n        Application application = (Application)getDataSource();\n\n        sampler = new SamplerImpl(application);\n\n        applicationListener = new ApplicationListener() {\n            public void dataRemoved(Application application) { applicationFinished(); }\n        };\n        application.notifyWhenRemoved(applicationListener);\n        application.addPropertyChangeListener(Stateful.PROPERTY_STATE, applicationListener);\n    }\n\n    protected void removed() {\n        sampler.removed();\n        cleanup();\n    }\n\n    private void applicationFinished() {\n        sampler.applicationFinished();\n        cleanup();\n    }\n\n    private synchronized void cleanup() {\n        Application application = (Application)getDataSource();\n\n        if (applicationListener != null)\n            application.removePropertyChangeListener(Stateful.PROPERTY_STATE,\n                                                     applicationListener);\n\n        applicationListener = null;\n    }\n\n    \n    protected DataViewComponent createComponent() {\n        DataViewComponent dvc = new DataViewComponent(\n                sampler.getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(false));\n\n        sampler.setDataViewComponent(dvc);\n\n        return dvc;\n    }\n\n\n    private static abstract class ApplicationListener\n            implements DataRemovedListener<Application>, PropertyChangeListener {\n        public abstract void dataRemoved(Application application);\n        public void propertyChange(PropertyChangeEvent evt) { dataRemoved(null); }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/ApplicationSamplerViewProvider.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewProvider;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ApplicationSamplerViewProvider extends DataSourceViewProvider<Application>{\n    \n    protected boolean supportsViewFor(Application application) {\n        return SamplerSupport.getInstance().supportsProfiling(application);\n    }\n\n    protected DataSourceView createView(Application application) {\n        return new ApplicationSamplerView(application);\n    }\n    \n    \n    DataSourceView view(Application application) {\n        return super.getView(application);\n    }\n    \n\n    void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(this, Application.class);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/Bundle.properties",
    "content": "#\n# Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Profiling\nOpenIDE-Module-Long-Description=\\\n    This module implements a sampling profiler for the GraalVM.\nOpenIDE-Module-Name=VisualVM-Sampler-Truffle\nOpenIDE-Module-Short-Description=Sampling profiler for the GraalVM\n\nLBL_Sampler=Polyglot Sampler\n\nLBL_Sample=Sample\\:\nLBL_Profile=Profile\\:\n\nLBL_Cpu=CPU\n\nLBL_Memory=Memory\n\nLBL_Stop=Stop\n\nLBL_Status=Status:\n\nMSG_Sample=&Sample\n\nDESCR_Sample=Analysis by sampling profiler\n\nLBL_Settings=Settings\n\nLBL_Cpu_settings=CPU settings\n\nLBL_Memory_settings=Memory settings\n\nMSG_Checking_Availability=Checking availability...\n\nLBL_Information=Information\n\nLBL_Summary=Summary\n\nLBL_Undefined=<undefined>\n\nMSG_Application_terminated=application terminated\n\nMSG_Sampling_inactive=sampling inactive\n\nMSG_Cpu_progress=CPU sampling in progress\n\nMSG_Memory_progress=memory sampling in progress\n\nLBL_Refreshing=refreshing...\n\nLBL_Cpu_samples=CPU samples\n\nLBL_Cpu_sampling=<b>CPU sampling:</b><br>\n\nLBL_Memory_samples=Memory samples\n\nLBL_Memory_sampling=<br><br><b>Memory sampling:</b><br>\n\nMSG_No_save_data_cpu=<html><b>No data to save</b><br><br>Make sure the application performs some code<br>and the selected filter is not filtering out the calls.</html>\n\nMSG_No_save_data_memory=<html><b>No data to save</b><br><br>Make sure the application performs some code.</html>\n\nMSG_Thread_dump_unsupported=thread dump not supported\n\nMSG_ThreadCPU_unsupported=thread CPU time not supported\n\nMSG_Available=Available.\n\nMSG_Available_details=Available ({0}).\n\nMSG_Available_details2=Available ({0}, {1}).\n\nMSG_Available_details3=Available ({0}, {1}, {2}).\n\nCAP_Memory_error=Memory Sampler Error\nCAP_Memory_warning=Memory Sampler Warning\n\nMSG_Memory_experimental1=Note: Memory sampling is an experimental feature and should not be used in production environments. <a href='#'>Enable Memory</a>\nMSG_Memory_experimental2=Note: Memory sampling is an experimental feature and should not be used in production environments.\n\nMSG_Press_cpu=Press the 'CPU' button to start collecting performance data.\n\nMSG_Press_mem=Press the 'Memory' button to start collecting memory data.\n\nMSG_Unavailable=Not available.\n\nMSG_Unavailable_init_jmx=Not available. Cannot initialize JMX connection to target application. Use 'Add JMX Connection' action to attach to the application.\n\nMSG_Unavailable_create_jmx=Not available. Failed to create JMX connection to target application. Use 'Add JMX Connection' action to attach to the application.\n\nMSG_Unavailable_remote=Not available. Remote sampling is only supported for Java 8+ applications.\n\nMSG_Unavailable_connect_jdk=Not available. Cannot connect to target application. Make sure the application is running on a supported Java 6+.\n\nMSG_Unavailable_connect_log=Not available. Cannot connect to target application. Check the VisualVM logfile ({0}).\n\nMSG_Unavailable_read_log=Not available. Failed to read objects in target application. Check the VisualVM logfile ({0}).\n\nMSG_Gc_unsupported=perform GC not supported\n\nMSG_HeapDump_unsupported=heap dump not supported\n\nMSG_ThreadMemory_unsupported=thread memory allocation not supported\n\nMSG_Incorrect_CPU_settings=Provided CPU settings are invalid.\n\nMSG_Incorrect_Memory_settings=Provided Memory settings are invalid.\n\nMSG_High_Sampling_Frequency=<html><br><b>Configured sampling frequency is high.</b><br><br>This may affect performance of the target application<br>and bias the collected results.<br><br></html>\n\nCAP_High_Sampling_Frequency=High Sampling Frequency\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/Installer.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.truffle;\n\nimport org.openide.modules.ModuleInstall;\n\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class Installer extends ModuleInstall {\n\n    public void restored() {\n        SamplerSupport.getInstance();\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/ProxyTruffleMBean.java",
    "content": "/*\n * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.truffle;\n\nimport java.io.IOException;\nimport java.util.Map;\nimport javax.management.Attribute;\nimport javax.management.AttributeNotFoundException;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.InvalidAttributeValueException;\nimport javax.management.MBeanException;\nimport javax.management.MBeanServerConnection;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\nimport javax.management.ReflectionException;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class ProxyTruffleMBean {\n\n    private static final String TRUFFLE_OBJECT_NAME = \"com.truffle:type=Threading\";\n    private final ObjectName truffleObjectName;\n    private final MBeanServerConnection conn;\n\n    public ProxyTruffleMBean(MBeanServerConnection c) {\n        conn = c;\n        truffleObjectName = getTruffleName();\n    }\n\n    public Map<String, Object>[] dumpAllThreads() throws InstanceNotFoundException, MBeanException, ReflectionException, IOException {\n        return (Map[]) conn.invoke(truffleObjectName, \"dumpAllThreads\", null, null);\n    }\n\n    public boolean isStackTracesEnabled() throws InstanceNotFoundException, MBeanException, IOException, ReflectionException, AttributeNotFoundException {\n        return (boolean) conn.getAttribute(truffleObjectName, \"StackTracesEnabled\");\n    }\n\n    public Map<String, Object>[] heapHistogram() throws InstanceNotFoundException, MBeanException, ReflectionException, IOException {\n        return (Map[]) conn.invoke(truffleObjectName, \"heapHistogram\", null, null);\n    }\n\n    public boolean isHeapHistogramEnabled() throws InstanceNotFoundException, MBeanException, IOException, ReflectionException, AttributeNotFoundException {\n        return (boolean) conn.getAttribute(truffleObjectName, \"HeapHistogramEnabled\");\n    }\n\n    public void setTrackFlags(boolean trackFlags) throws InstanceNotFoundException, AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException, IOException {\n        conn.setAttribute(truffleObjectName, new Attribute(\"TrackFlags\", trackFlags));\n    }\n\n    public void setMode(String mode) throws InstanceNotFoundException, MBeanException, ReflectionException, IOException, AttributeNotFoundException, InvalidAttributeValueException {\n        conn.setAttribute(truffleObjectName, new Attribute(\"Mode\", mode));\n    }\n\n    public boolean isModeAvailable() throws InstanceNotFoundException, MBeanException, IOException, ReflectionException, AttributeNotFoundException {\n        return (boolean) conn.getAttribute(truffleObjectName, \"ModeAvailable\");\n    }\n\n    public boolean isRegistered() throws IOException {\n        return conn.isRegistered(truffleObjectName);\n    }\n\n    private static ObjectName getTruffleName() {\n        try {\n            return new ObjectName(TRUFFLE_OBJECT_NAME);\n        } catch (MalformedObjectNameException ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/SampleApplicationAction.java",
    "content": "/*\n *  Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.sampler.truffle;\n\nimport java.awt.event.ActionEvent;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.ui.actions.SingleDataSourceAction;\nimport org.openide.util.NbBundle;\n\n    \n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class SampleApplicationAction extends SingleDataSourceAction<Application> {\n    \n    private static SampleApplicationAction instance;\n    \n    public static synchronized SampleApplicationAction instance() {\n        if (instance == null) \n            instance = new SampleApplicationAction();\n        return instance;\n    }\n        \n    protected void actionPerformed(Application application, ActionEvent actionEvent) {\n        SamplerSupport.getInstance().selectSamplerView(application);\n    }\n    \n    protected boolean isEnabled(Application application) {\n        return SamplerSupport.getInstance().supportsProfiling(application);\n    }\n        \n    private SampleApplicationAction() {\n        super(Application.class);\n        putValue(NAME, NbBundle.getMessage(SampleApplicationAction.class, \"MSG_Sample\")); // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(SampleApplicationAction.class, \"DESCR_Sample\"));    // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/SamplerImpl.java",
    "content": "/*\n * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle;\n\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseEvent;\nimport java.io.DataOutputStream;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.lang.management.MemoryMXBean;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Timer;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.DefaultComboBoxModel;\nimport javax.swing.ImageIcon;\nimport javax.swing.JButton;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.heapdump.HeapDumpSupport;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.common.ProfilingSettingsPresets;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsSnapshot;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.lib.profiler.api.ProfilerDialogs;\nimport org.graalvm.visualvm.profiling.presets.PresetSelector;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPreset;\nimport org.graalvm.visualvm.profiling.presets.ProfilerPresets;\nimport org.graalvm.visualvm.profiling.snapshot.ProfilerSnapshot;\nimport org.graalvm.visualvm.sampler.truffle.cpu.CPUSamplerSupport;\nimport org.graalvm.visualvm.sampler.truffle.cpu.CPUSettingsSupport;\nimport org.graalvm.visualvm.sampler.truffle.cpu.ThreadInfoProvider;\nimport org.graalvm.visualvm.sampler.truffle.memory.MemoryHistogramProvider;\nimport org.graalvm.visualvm.sampler.truffle.memory.MemorySamplerSupport;\nimport org.graalvm.visualvm.sampler.truffle.memory.MemorySettingsSupport;\nimport org.graalvm.visualvm.threaddump.ThreadDumpSupport;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.graalvm.visualvm.tools.jmx.JvmMXBeans;\nimport org.graalvm.visualvm.uisupport.HTMLLabel;\nimport org.graalvm.visualvm.uisupport.HTMLTextArea;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class SamplerImpl {\n\n    private static final Logger LOGGER = Logger.getLogger(SamplerImpl.class.getName());\n    \n    private static final boolean MEMORY_INITIALLY_AVAILABLE = Boolean.getBoolean(\"visualvm.graalsampler.memory.alwaysEnabled\"); // NOI18N\n\n    private static enum State { TERMINATED, INACTIVE, CPU, MEMORY, TRANSITION };\n\n    private Application application;\n    private Timer timer;\n\n    private HTMLTextArea summaryArea;\n    private String cpuStatus = NbBundle.getMessage(SamplerImpl.class, \"MSG_Checking_Availability\"); // NOI18N\n    private String memoryStatus = NbBundle.getMessage(SamplerImpl.class, MEMORY_INITIALLY_AVAILABLE ? \"MSG_Memory_experimental2\" : \"MSG_Memory_experimental1\"); // NOI18N\n//    private String memoryStatus = NbBundle.getMessage(SamplerImpl.class, \"MSG_Checking_Availability\"); // NOI18N\n\n    private boolean cpuProfilingSupported;\n    private AbstractSamplerSupport cpuSampler;\n    private CPUSettingsSupport cpuSettings;\n\n    private boolean memoryProfilingSupported = MEMORY_INITIALLY_AVAILABLE;\n    private boolean memoryInitializationPending;\n//    private boolean memoryProfilingSupported;\n    private AbstractSamplerSupport memorySampler;\n    private MemorySettingsSupport memorySettings;\n    \n    private DefaultComboBoxModel<ProfilerPreset> selectorModel;\n    private List<PresetSelector> allSelectors;\n\n    private DataViewComponent dvc;\n    private String currentName;\n    private DataViewComponent.DetailsView[] currentViews;\n\n    private State state = State.TRANSITION;\n\n\n    SamplerImpl(Application application) {\n        this.application = application;\n        \n        cpuSettings = new CPUSettingsSupport() {\n            public boolean presetValid() {\n                return cpuSettings.settingsValid() &&\n                       memorySettings.settingsValid();\n            }\n            public PresetSelector createSelector(Runnable presetSynchronizer) {\n                return SamplerImpl.this.createSelector(presetSynchronizer);\n            }\n        };\n        memorySettings = new MemorySettingsSupport() {\n            public boolean presetValid() {\n                return cpuSettings.settingsValid() &&\n                       memorySettings.settingsValid();\n            }\n            public PresetSelector createSelector(Runnable presetSynchronizer) {\n                return SamplerImpl.this.createSelector(presetSynchronizer);\n            }\n        };\n    }\n    \n    private PresetSelector createSelector(Runnable presetSynchronizer) {\n        if (selectorModel == null) selectorModel = new DefaultComboBoxModel<>();\n        if (allSelectors == null) allSelectors = new ArrayList<>();\n        PresetSelector selector = ProfilerPresets.getInstance().createSelector(\n                                  application, selectorModel, allSelectors, presetSynchronizer);\n        allSelectors.add(selector);\n        return selector;\n    }\n\n\n    DataViewComponent.MasterView getMasterView() {\n        initComponents();\n        setState(State.INACTIVE);\n\n        final HierarchyListener hl = new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (view.isShowing()) {\n                        initializeCpuSampling();\n//                        initializeMemorySampling();\n                        view.removeHierarchyListener(this);\n                    }\n                }\n            }\n        };\n        view.addHierarchyListener(hl);\n\n        return new DataViewComponent.MasterView(NbBundle.getMessage(\n                   SamplerImpl.class, \"LBL_Sampler\"), null, view); // NOI18N\n    }\n\n\n    void setDataViewComponent(DataViewComponent dvc) {\n        this.dvc = dvc;\n\n        setCurrentViews(NbBundle.getMessage(SamplerImpl.class,\n                        \"LBL_Information\"), createSummaryView()); // NOI18N\n\n        dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\n                NbBundle.getMessage(SamplerImpl.class, \"LBL_Settings\"), // NOI18N\n                true), DataViewComponent.TOP_RIGHT);\n        dvc.addDetailsView(cpuSettings.getDetailsView(), DataViewComponent.TOP_RIGHT);\n        dvc.addDetailsView(memorySettings.getDetailsView(), DataViewComponent.TOP_RIGHT);\n        dvc.hideDetailsArea(DataViewComponent.TOP_RIGHT);\n    }\n\n\n    void removed() {\n        terminate();\n    }\n\n    void applicationFinished() {\n        terminate();\n    }\n\n    private synchronized void terminate() {\n        State currentState = getState();\n\n        if (cpuSampler != null) {\n            if (State.CPU.equals(currentState)) cpuSampler.stopSampling();\n            cpuSampler.terminate();\n        }\n        if (memorySampler != null) {\n            if (State.MEMORY.equals(currentState)) memorySampler.stopSampling();\n            memorySampler.terminate();\n        }\n\n        setState(State.TERMINATED);\n        dvc = null;\n    }\n\n\n    private void setCurrentViews(String name, DataViewComponent.DetailsView[] views) {\n        if (dvc == null) return;\n\n        if (currentName == null || !currentName.equals(name)) {\n            dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(\n                    name, false), DataViewComponent.TOP_LEFT);\n\n            currentName = name;\n        }\n\n        if (currentViews != views) {\n            if (currentViews != null)\n                for (DataViewComponent.DetailsView detailsView : currentViews)\n                    dvc.removeDetailsView(detailsView);\n\n            if (views != null)\n                for (DataViewComponent.DetailsView detailsView : views)\n                    dvc.addDetailsView(detailsView, DataViewComponent.TOP_LEFT);\n\n            currentViews = views;\n        }\n    }\n\n    private synchronized void setState(State state) {\n        if (this.state.equals(state)) return;\n        this.state = state;\n\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                updateStatus();\n                updateSettings();\n                updateButtons();\n            }\n        });\n    }\n\n    private synchronized State getState() {\n        return state;\n    }\n\n\n    private void updateStatus() {\n        if (statusValueLabel != null) {\n            String status = NbBundle.getMessage(SamplerImpl.class,\n                            \"LBL_Undefined\"); // NOI18N\n\n            switch (getState()) {\n                case TERMINATED:\n                    status = NbBundle.getMessage(SamplerImpl.class,\n                             \"MSG_Application_terminated\"); // NOI18N\n                    break;\n                case INACTIVE:\n                    status = NbBundle.getMessage(SamplerImpl.class,\n                             \"MSG_Sampling_inactive\"); // NOI18N\n                    break;\n                case CPU:\n                    status = NbBundle.getMessage(SamplerImpl.class,\n                             \"MSG_Cpu_progress\"); // NOI18N\n                    break;\n                case MEMORY:\n                    status = NbBundle.getMessage(SamplerImpl.class,\n                             \"MSG_Memory_progress\"); // NOI18N\n                    break;\n                case TRANSITION:\n                    status = NbBundle.getMessage(SamplerImpl.class,\n                             \"LBL_Refreshing\"); // NOI18N\n                    break;\n            }\n\n            statusValueLabel.setText(status);\n        }\n    }\n\n    private void updateSettings() {\n        if (cpuSettings != null && memorySettings != null) {\n            switch (getState()) {\n                case INACTIVE:\n                case TERMINATED:\n                    cpuSettings.setEnabled(true);\n                    memorySettings.setEnabled(true);\n                    break;\n                case CPU:\n                case MEMORY:\n                case TRANSITION:\n                    cpuSettings.setEnabled(false);\n                    memorySettings.setEnabled(false);\n                    break;\n            }\n        }\n    }\n\n    private void updateButtons() {\n        if (cpuButton != null && memoryButton != null && stopButton != null) {\n            switch (getState()) {\n                case TERMINATED:\n                    cpuButton.setSelected(false);\n                    cpuButton.setEnabled(false);\n\n                    memoryButton.setSelected(false);\n                    memoryButton.setEnabled(false);\n\n                    stopButton.setEnabled(false);\n\n                    break;\n\n                case INACTIVE:\n                    cpuButton.setSelected(false);\n                    cpuButton.setEnabled(cpuProfilingSupported);\n\n                    memoryButton.setSelected(false);\n                    memoryButton.setEnabled(memoryProfilingSupported || memoryInitializationPending);\n\n                    stopButton.setEnabled(false);\n\n                    break;\n\n                case CPU:\n                    cpuButton.setSelected(true);\n                    cpuButton.setEnabled(true);\n\n                    memoryButton.setSelected(false);\n                    memoryButton.setEnabled(memoryProfilingSupported || memoryInitializationPending);\n\n                    stopButton.setEnabled(true);\n\n                    break;\n\n                case MEMORY:\n                    cpuButton.setSelected(false);\n                    cpuButton.setEnabled(cpuProfilingSupported);\n\n                    memoryButton.setSelected(true);\n                    memoryButton.setEnabled(true);\n\n                    stopButton.setEnabled(true);\n\n                    break;\n\n                case TRANSITION:\n                    cpuButton.setEnabled(false);\n\n                    memoryButton.setEnabled(false);\n\n                    stopButton.setEnabled(false);\n\n                    break;\n            }\n        }\n    }\n\n\n    private void handleCPUProfiling() {\n        if (!cpuSettings.settingsValid()) {\n            cpuButton.setSelected(false);\n            if (dvc != null) cpuSettings.showSettings(dvc);\n            ProfilerDialogs.displayError(NbBundle.getMessage(SamplerImpl.class, \"MSG_Incorrect_CPU_settings\")); // NOI18N\n            return;\n        }\n        \n        State currentState = getState();\n        if (currentState.equals(State.CPU) ||\n           currentState.equals(State.TERMINATED) ||\n           currentState.equals(State.TRANSITION)) return;\n        setState(State.TRANSITION);\n        \n        final Runnable sessionStarter = new Runnable() {\n            public void run() {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        setCurrentViews(NbBundle.getMessage(SamplerImpl.class,\n                                        \"LBL_Cpu_samples\"), cpuSampler.getDetailsView()); // NOI18N\n                        VisualVM.getInstance().runTask(new Runnable() {\n                            public void run() {\n                                cpuSettings.saveSettings();\n                                setState(cpuSampler.startSampling(\n                                         cpuSettings.getSettings(),\n                                         cpuSettings.getSamplingRate(),\n                                         cpuSettings.getRefreshRate()) ?\n                                         State.CPU : State.INACTIVE);\n                            }\n                        });\n                    }\n                });\n            }\n        };\n\n        if (currentState.equals(State.MEMORY)) {\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    memorySampler.stopSampling();\n                    sessionStarter.run();\n                }\n            });\n        } else {\n            sessionStarter.run();\n        }\n    }\n\n    private void handleMemoryProfiling() {\n        Runnable memoryProfilingHandler = new Runnable() {\n            public void run() {\n                if (!memorySettings.settingsValid()) {\n                    memoryButton.setSelected(false);\n                    if (dvc != null) memorySettings.showSettings(dvc);\n                    ProfilerDialogs.displayError(NbBundle.getMessage(SamplerImpl.class, \"MSG_Incorrect_Memory_settings\")); // NOI18N\n                    return;\n                }\n\n                State currentState = getState();\n                if (currentState.equals(State.MEMORY) ||\n                   currentState.equals(State.TERMINATED) ||\n                   currentState.equals(State.TRANSITION)) return;\n                setState(State.TRANSITION);\n\n                final Runnable sessionStarter = new Runnable() {\n                    public void run() {\n                        SwingUtilities.invokeLater(new Runnable() {\n                            public void run() {\n                                setCurrentViews(NbBundle.getMessage(SamplerImpl.class,\n                                                \"LBL_Memory_samples\"), memorySampler.getDetailsView()); // NOI18N\n                                VisualVM.getInstance().runTask(new Runnable() {\n                                    public void run() {\n                                        memorySettings.saveSettings();\n                                        setState(memorySampler.startSampling(\n                                                 memorySettings.getSettings(),\n                                                 memorySettings.getSamplingRate(),\n                                                 memorySettings.getRefreshRate()) ?\n                                                 State.MEMORY : State.INACTIVE);\n                                    }\n                                });\n                            }\n                        });\n                    }\n                };\n\n                if (currentState.equals(State.CPU)) {\n                    VisualVM.getInstance().runTask(new Runnable() {\n                        public void run() {\n                            cpuSampler.stopSampling();\n                            sessionStarter.run();\n                        }\n                    });\n                } else {\n                    sessionStarter.run();\n                }\n            }\n        };\n        \n        if (memorySampler == null) initializeMemorySampling(memoryProfilingHandler);\n        else if (memoryProfilingSupported) memoryProfilingHandler.run();\n    }\n\n    private void handleStopProfiling() {\n        State currentState = getState();\n        if (currentState.equals(State.INACTIVE) ||\n           currentState.equals(State.TERMINATED) ||\n           currentState.equals(State.TRANSITION)) return;\n        setState(State.TRANSITION);\n\n        if (currentState.equals(State.CPU)) {\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    cpuSampler.stopSampling();\n                    setState(State.INACTIVE);\n                }\n            });\n        } else if (currentState.equals(State.MEMORY)) {\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    memorySampler.stopSampling();\n                    setState(State.INACTIVE);\n                }\n            });\n        }\n    }\n\n\n    private void initializeCpuSampling() {\n        final String mode = cpuSettings.getMode();\n        final boolean splitCompiledInlined = cpuSettings.isSplitCompiledInlined();\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                ThreadInfoProvider ti = new ThreadInfoProvider(application, mode, splitCompiledInlined);\n                final String status = ti.getStatus();\n                final boolean modeAvailable = ti.isModeVailable();\n                \n                if (status != null) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            cpuStatus = status;\n                            refreshSummary();\n                        }\n                    });\n                    return;\n                }\n\n                CPUSamplerSupport.SnapshotDumper snapshotDumper = new CPUSamplerSupport.SnapshotDumper() {\n                    public void takeSnapshot(final boolean openView) {\n                        VisualVM.getInstance().runTask(new Runnable() {\n                            public void run() {\n                                LoadedSnapshot ls = null;\n                                try {\n                                    ls = takeNPSSnapshot(application.getStorage().getDirectory());\n                                } catch (CPUResultsSnapshot.NoDataAvailableException e) {\n                                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(NbBundle.getMessage(\n                                            SamplerImpl.class, \"MSG_No_save_data_cpu\"), NotifyDescriptor.WARNING_MESSAGE)); // NOI18N\n                                } catch (Throwable t) {\n                                    LOGGER.log(Level.WARNING, \"Failed to save profiler snapshot for \" + application, t); // NOI18N\n                                }\n                                if (ls != null) {\n                                    final ProfilerSnapshot ps = ProfilerSnapshot.createSnapshot(ls.getFile(), application);\n                                    application.getRepository().addDataSource(ps);\n                                    if (openView) DataSource.EVENT_QUEUE.post(new Runnable() {\n                                        public void run() {\n                                            DataSourceWindowManager.sharedInstance().openDataSource(ps);\n                                        }\n                                    });\n                                }\n                            }\n                        });\n                    }\n                };\n\n                final ThreadDumpSupport tds = ThreadDumpSupport.getInstance();\n                final String noThreadDump = tds.supportsThreadDump(application) ? null : NbBundle.getMessage(\n                                            SamplerImpl.class, \"MSG_Thread_dump_unsupported\"); // NOI18N\n\n                CPUSamplerSupport.ThreadDumper threadDumper = noThreadDump != null ? null :\n                    new CPUSamplerSupport.ThreadDumper() {\n                        public void takeThreadDump(boolean openView) {\n                            tds.takeThreadDump(application, openView);\n                        }\n                    };\n                    \n                cpuSampler = new CPUSamplerSupport(application, ti, snapshotDumper, threadDumper) {\n                    @Override\n                    public boolean startSampling(ProfilingSettings settings, int samplingRate, int refreshRate) {\n                        setOptions(cpuSettings.getMode(), cpuSettings.isSplitCompiledInlined());\n                        return super.startSampling(settings, samplingRate, refreshRate);\n                    }\n\n                    protected Timer getTimer() { return SamplerImpl.this.getTimer(); }\n                };\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        String avail = NbBundle.getMessage(SamplerImpl.class,\n                                                           \"MSG_Available\"); // NOI18N\n                        if (noThreadDump != null) {\n                            String[] msgs = new String[2];\n                            int i = 0;\n                            msgs[i++] = noThreadDump;\n                            if (i == 1) {\n                                avail = NbBundle.getMessage(SamplerImpl.class,\n                                        \"MSG_Available_details\", msgs[0]); // NOI18N\n                            } else if (i == 2) {\n                                avail = NbBundle.getMessage(SamplerImpl.class,\n                                        \"MSG_Available_details2\", msgs[0], msgs[1]); // NOI18N\n                            }\n                        }\n                        cpuStatus = avail + \" \" + NbBundle.getMessage(SamplerImpl.class, \"MSG_Press_cpu\"); // NOI18N\n                        cpuProfilingSupported = true;\n                        if (!modeAvailable) cpuSettings.enableMode(modeAvailable);\n                        refreshSummary();\n                        updateButtons();\n                        updateSettings();\n                    }\n                });\n            }\n        });\n    }\n\n    private void initializeMemorySampling(Runnable onSuccess) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                MemoryHistogramProvider histogramProvider = new MemoryHistogramProvider(application);\n                final String status = histogramProvider.getStatus();\n\n                if (status != null) {\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() {\n                            memoryProfilingSupported = false; // may be initially true (visualvm.graalsampler.memory.alwaysEnabled)\n                            memoryInitializationPending = false;\n                            \n                            handleStopProfiling();\n                            \n//                            memoryStatus = status;\n//                            refreshSummary();\n                            updateButtons();\n                            updateSettings();\n                            \n                            ProfilerDialogs.displayError(status, NbBundle.getMessage(SamplerImpl.class, \"CAP_Memory_error\"), null); // NOI18N\n                        }\n                    });\n                    return;\n                }\n\n                MemoryMXBean memoryBean = null;\n                JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);\n                if (jmxModel != null && jmxModel.getConnectionState() == JmxModel.ConnectionState.CONNECTED) {\n                    JvmMXBeans mxbeans = jmxModel.getJvmMXBeans();\n                    if (mxbeans != null) {\n                        memoryBean = mxbeans.getMemoryMXBean();\n                    }\n                }\n                final String noPerformGC = memoryBean == null ? NbBundle.getMessage(\n                        SamplerImpl.class, \"MSG_Gc_unsupported\") : null; // NOI18N\n\n                final HeapDumpSupport hds = HeapDumpSupport.getInstance();\n                final boolean local = application.isLocalApplication();\n                boolean supportsHD = local ? hds.supportsHeapDump(application) :\n                                     hds.supportsRemoteHeapDump(application);\n                final String noHeapDump = supportsHD ? null : NbBundle.getMessage(\n                        SamplerImpl.class, \"MSG_HeapDump_unsupported\"); // NOI18N\n\n                MemorySamplerSupport.SnapshotDumper snapshotDumper = new MemorySamplerSupport.SnapshotDumper() {\n                    public void takeSnapshot(final boolean openView) {\n                        final MemorySamplerSupport.SnapshotDumper dumper = this; \n                        VisualVM.getInstance().runTask(new Runnable() {\n                            public void run() {\n                                LoadedSnapshot ls = null;\n                                DataOutputStream dos = null;\n                                try {\n                                    long time = System.currentTimeMillis();\n                                    SampledMemoryResultsSnapshot snapshot = dumper.createSnapshot(time);\n                                    if (snapshot == null) {\n                                        DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message(\n                                                NbBundle.getMessage(SamplerImpl.class, \"MSG_No_save_data_memory\"), // NOI18N\n                                                NotifyDescriptor.WARNING_MESSAGE));\n                                    } else {\n                                        ls = new LoadedSnapshot(snapshot, ProfilingSettingsPresets.createMemoryPreset(), null, null);\n                                        File file = Utils.getUniqueFile(application.getStorage().getDirectory(),\n                                                                        ResultsManager.getDefault().getDefaultSnapshotFileName(ls),\n                                                                        \".\" + ResultsManager.SNAPSHOT_EXTENSION); // NOI18N\n                                        dos = new DataOutputStream(new FileOutputStream(file));\n                                        ls.save(dos);\n                                        ls.setFile(file);\n                                        ls.setSaved(true);\n                                    }\n                                } catch (Throwable t) {\n                                    LOGGER.log(Level.WARNING, \"Failed to save profiler snapshot for \" + application, t); // NOI18N\n                                } finally {\n                                    try {\n                                        if (dos != null) dos.close();\n                                    } catch (IOException e) {\n                                        LOGGER.log(Level.WARNING, \"Problem closing output stream for  \" + dos, e); // NOI18N\n                                    }\n                                }\n                                if (ls != null) {\n                                    final ProfilerSnapshot ps = ProfilerSnapshot.createSnapshot(ls.getFile(), application);\n                                    application.getRepository().addDataSource(ps);\n                                    if (openView) DataSource.EVENT_QUEUE.post(new Runnable() {\n                                        public void run() {\n                                            DataSourceWindowManager.sharedInstance().openDataSource(ps);\n                                        }\n                                    });\n                                }\n                            }\n                        });\n                    }\n                };\n                MemorySamplerSupport.HeapDumper heapDumper = noHeapDump != null ? null :\n                    new MemorySamplerSupport.HeapDumper() {\n                        public void takeHeapDump(boolean openView) {\n                            if (local) hds.takeHeapDump(application, openView);\n                            else hds.takeRemoteHeapDump(application, null, openView);\n                        }\n                    };\n                memorySampler = new MemorySamplerSupport(application, histogramProvider, memoryBean, snapshotDumper, heapDumper) {\n                    protected Timer getTimer() { return SamplerImpl.this.getTimer(); }\n                };\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        int i = 0;\n                        \n                        String avail = NbBundle.getMessage(SamplerImpl.class,\n                                                           \"MSG_Available\"); // NOI18N\n                        if (noPerformGC != null || noHeapDump != null) {\n                            String[] msgs = new String[3];\n//                            int i = 0;\n                            if (noHeapDump != null) {\n                                msgs[i++] = noHeapDump;\n                            }\n                            if (noPerformGC != null) {\n                                msgs[i++] = noPerformGC;\n                            }\n                            if (i == 1) {\n                                avail = NbBundle.getMessage(SamplerImpl.class,\n                                        \"MSG_Available_details\", msgs[0]); // NOI18N\n                            } else if (i == 2) {\n                                avail = NbBundle.getMessage(SamplerImpl.class,\n                                        \"MSG_Available_details2\", msgs[0], msgs[1]); // NOI18N\n//                            } else {\n//                                avail = NbBundle.getMessage(SamplerImpl.class,\n//                                        \"MSG_Available_details3\", msgs[0], msgs[1], msgs[2]); // NOI18N\n                            }\n                        }\n//                        memoryStatus = avail + \" \" + NbBundle.getMessage( // NOI18N\n//                                SamplerImpl.class, \"MSG_Press_mem\"); // NOI18N\n                        memoryProfilingSupported = true;\n                        memoryInitializationPending = false;\n//                        refreshSummary();\n                        updateButtons();\n                        updateSettings();\n                        \n                        if (i > 0) ProfilerDialogs.displayWarningDNSA(avail, NbBundle.getMessage(SamplerImpl.class, \"CAP_Memory_warning\"), null, SamplerImpl.class.getName(), false); // NOI18N\n                        \n                        onSuccess.run();\n                    }\n                });\n            }\n        });\n    }\n\n    private synchronized Timer getTimer() {\n        if (timer == null)\n            timer = new Timer(\"Sampler timer for \" + DataSourceDescriptorFactory. // NOI18N\n                              getDescriptor(application).getName());\n        return timer;\n    }\n\n    private DataViewComponent.DetailsView[] createSummaryView() {\n        summaryArea = new HTMLTextArea() {\n            protected void showURL(URL url) {\n                SwingUtilities.invokeLater(new Runnable() {\n                    public void run() {\n                        memoryButton.setEnabled(true);\n                        memoryInitializationPending = true;\n                        memoryStatus = NbBundle.getMessage(SamplerImpl.class, \"MSG_Memory_experimental2\"); // NOI18N\n                        refreshSummary();\n                    }\n                });\n            }\n        };\n        summaryArea.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));\n\n        refreshSummary();\n\n        return new DataViewComponent.DetailsView[] {\n                        new DataViewComponent.DetailsView(NbBundle.getMessage(\n                        SamplerImpl.class, \"LBL_Summary\"), null, 10, // NOI18N\n                        new ScrollableContainer(summaryArea), null) };\n    }\n\n    private void refreshSummary() {\n        StringBuilder builder = new StringBuilder();\n\n        addCpuHeader(builder);\n        builder.append(cpuStatus);\n\n        addMemoryHeader(builder);\n        builder.append(memoryStatus);\n\n        int selStart = summaryArea.getSelectionStart();\n        int selEnd = summaryArea.getSelectionEnd();\n        summaryArea.setText(builder.toString());\n        summaryArea.select(selStart, selEnd);\n    }\n\n    private static void addCpuHeader(StringBuilder builder) {\n        builder.append(NbBundle.getMessage(SamplerImpl.class, \"LBL_Cpu_sampling\")); // NOI18N\n    }\n\n    private static void addMemoryHeader(StringBuilder builder) {\n        builder.append(NbBundle.getMessage(SamplerImpl.class, \"LBL_Memory_sampling\")); // NOI18N\n    }\n\n    private void initComponents() {\n        view = new JPanel(new GridBagLayout());\n        view.setOpaque(false);\n        view.setBorder(BorderFactory.createEmptyBorder(11, 5, 8, 5));\n\n        GridBagConstraints constraints;\n\n        // modeLabel\n        modeLabel = new JLabel(NbBundle.getMessage(SamplerImpl.class, \"LBL_Profile\")); // NOI18N\n        modeLabel.setFont(modeLabel.getFont().deriveFont(Font.BOLD));\n        Dimension d = modeLabel.getPreferredSize();\n        modeLabel.setText(NbBundle.getMessage(SamplerImpl.class, \"LBL_Sample\")); // NOI18N\n        d.width = Math.max(d.width, modeLabel.getPreferredSize().width);\n        modeLabel.setPreferredSize(d);\n        modeLabel.setOpaque(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 2;\n        constraints.gridwidth = 1;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(4, 8, 0, 0);\n        view.add(modeLabel, constraints);\n\n        // cpuButton\n        cpuButton = new OneWayToggleButton(NbBundle.getMessage(SamplerImpl.class, \"LBL_Cpu\")); // NOI18N\n        cpuButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/sampler/resources/cpu.png\", true))); // NOI18N\n        cpuButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { handleCPUProfiling(); }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 2;\n        constraints.gridy = 2;\n        constraints.gridwidth = 1;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(4, 8, 0, 0);\n        view.add(cpuButton, constraints);\n\n        // memoryButton\n        memoryButton = new OneWayToggleButton(NbBundle.getMessage(SamplerImpl.class, \"LBL_Memory\")); // NOI18N\n        memoryButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/sampler/resources/memory.png\", true))); // NOI18N\n        memoryButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { handleMemoryProfiling(); }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 3;\n        constraints.gridy = 2;\n        constraints.gridwidth = 1;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(4, 8, 0, 0);\n        view.add(memoryButton, constraints);\n\n        // stopButton\n        stopButton = new JButton(NbBundle.getMessage(SamplerImpl.class, \"LBL_Stop\")); // NOI18N\n        stopButton.setIcon(new ImageIcon(ImageUtilities.loadImage(\"org/graalvm/visualvm/sampler/resources/stop.png\", true))); // NOI18N\n        stopButton.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) { handleStopProfiling(); }\n        });\n        stopButton.setEnabled(false);\n        stopButton.setDefaultCapable(false); // Button size\n        constraints = new GridBagConstraints();\n        constraints.gridx = 4;\n        constraints.gridy = 2;\n        constraints.gridwidth = 1;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(4, 8, 0, 0);\n        view.add(stopButton, constraints);\n\n        // filler1\n        constraints = new GridBagConstraints();\n        constraints.gridx = 5;\n        constraints.gridy = 2;\n        constraints.weightx = 1;\n        constraints.weighty = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.insets = new Insets(0, 0, 0, 0);\n        view.add(Spacer.create(), constraints);\n\n        // statusLabel\n        statusLabel = new JLabel(NbBundle.getMessage(SamplerImpl.class, \"LBL_Status\")); // NOI18N\n        statusLabel.setFont(statusLabel.getFont().deriveFont(Font.BOLD));\n        statusLabel.setOpaque(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 3;\n        constraints.gridwidth = 1;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(6, 8, 4, 0);\n        view.add(statusLabel, constraints);\n\n        // statusValueLabel\n        statusValueLabel = new HTMLLabel() {\n            public void setText(String text) {super.setText(\"<nobr>\" + text + \"</nobr>\"); } // NOI18N\n            protected void showURL(URL url) {}\n\n            // NOTE: overriding dimensions prevents UI \"jumping\" when changing the link\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.height = getRefLabelHeight();\n                return dim;\n            }\n            public Dimension getMinimumSize() { return getPreferredSize(); }\n            public Dimension getMaximumSize() { return getPreferredSize(); }\n        };\n        statusValueLabel.setOpaque(false);\n        statusValueLabel.setFocusable(false);\n        constraints = new GridBagConstraints();\n        constraints.gridx = 1;\n        constraints.gridy = 3;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.insets = new Insets(6, 8, 4, 8);\n        view.add(statusValueLabel, constraints);\n\n        // filler2\n        constraints = new GridBagConstraints();\n        constraints.gridx = 2;\n        constraints.gridy = 3;\n        constraints.weightx = 1;\n        constraints.weighty = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.fill = GridBagConstraints.BOTH;\n        constraints.anchor = GridBagConstraints.NORTHWEST;\n        constraints.insets = new Insets(0, 0, 0, 0);\n        view.add(Spacer.create(), constraints);\n\n        Dimension cpuD     = cpuButton.getPreferredSize();\n        Dimension memoryD  = memoryButton.getPreferredSize();\n        Dimension stopD    = stopButton.getPreferredSize();\n\n        Dimension maxD = new Dimension(Math.max(cpuD.width, memoryD.width), Math.max(cpuD.height, memoryD.height));\n        maxD = new Dimension(Math.max(maxD.width, stopD.width), Math.max(maxD.height, stopD.height));\n\n        cpuButton.setPreferredSize(maxD);\n        cpuButton.setMinimumSize(maxD);\n        memoryButton.setPreferredSize(maxD);\n        memoryButton.setMinimumSize(maxD);\n        stopButton.setPreferredSize(maxD);\n        stopButton.setMinimumSize(maxD);\n    }\n\n    private JPanel view;\n    private JLabel modeLabel;\n    private JToggleButton cpuButton;\n    private JToggleButton memoryButton;\n    private JButton stopButton;\n    private JLabel statusLabel;\n    private HTMLLabel statusValueLabel;\n\n    private static int refLabelHeight = -1;\n    private static int getRefLabelHeight() {\n        if (refLabelHeight == -1)\n            refLabelHeight = new HTMLLabel(\"X\").getPreferredSize().height; // NOI18N\n        return refLabelHeight;\n    }\n\n\n    private static final class OneWayToggleButton extends JToggleButton {\n\n        OneWayToggleButton(String text) {\n            super(text);\n        }\n\n        protected void processMouseEvent(MouseEvent e) {\n            if (!isSelected()) super.processMouseEvent(e);\n        }\n\n        protected void processKeyEvent(KeyEvent e) {\n            if (!isSelected()) super.processKeyEvent(e);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/SamplerSupport.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle;\n\nimport java.io.IOException;\nimport java.util.Properties;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.application.type.ApplicationType;\nimport org.graalvm.visualvm.application.type.ApplicationTypeFactory;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic final class SamplerSupport {\n\n    private static final Logger LOGGER = Logger.getLogger(SamplerSupport.class.getName());\n    private static final String GRAALVM_ID = \"GraalVM\";     // NOI18N\n    private static SamplerSupport instance;\n    \n    private ApplicationSamplerViewProvider samplerViewProvider;\n\n\n    public static synchronized SamplerSupport getInstance() {\n        if (instance == null) instance = new SamplerSupport();\n        return instance;\n    }\n    \n    boolean supportsProfiling(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        if (!application.isLocalApplication()) {\n            return isTruffleBeanLoaded(application);\n        }\n        Jvm jvm = JvmFactory.getJVMFor(application);\n        if (!jvm.isBasicInfoSupported() || !jvm.isAttachable()) return false;\n        ApplicationType appType = ApplicationTypeFactory.getApplicationTypeFor(application);\n        if (appType.getClass().getName().contains(\"GraalVMApplicationType\")) {  // NOI18N\n            return true;\n        }\n        return isRunningOnGraalVM(jvm);\n    }\n    \n    void selectSamplerView(Application application) {\n        if (application == null) return;\n        DataSourceView activeView = samplerViewProvider.view(application);\n        if (activeView == null) return;\n        DataSourceWindowManager.sharedInstance().selectView(activeView);\n    }\n             \n    private SamplerSupport() {\n        samplerViewProvider = new ApplicationSamplerViewProvider();\n        samplerViewProvider.initialize();\n    }\n\n    private boolean isRunningOnGraalVM(Jvm jvm) {\n        if (jvm.getVmName().contains(GRAALVM_ID)) {\n            return true;\n        }\n        if (jvm.isGetSystemPropertiesSupported()) {\n            Properties props = jvm.getSystemProperties();\n            if (props != null) {\n                String vendorVersion = props.getProperty(\"java.vendor.version\", \"\");    // NOI18N\n                return vendorVersion.contains(GRAALVM_ID);\n            }\n        }\n        return false;\n    }\n\n    private boolean isTruffleBeanLoaded(Application application) {\n        JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);\n        if (jmxModel != null && jmxModel.getConnectionState() == JmxModel.ConnectionState.CONNECTED) {\n            try {\n                ProxyTruffleMBean tbean = new ProxyTruffleMBean(jmxModel.getMBeanServerConnection());\n                if (tbean.isRegistered()) {\n                    return true;\n                }\n            } catch (IOException ex) {\n                LOGGER.log(Level.INFO, \"isTruffleBeanLoaded\", ex);\n                return false;\n            }\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/TruffleDataProvider.java",
    "content": "/*\n * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.truffle;\n\nimport com.sun.tools.attach.AgentInitializationException;\nimport com.sun.tools.attach.AgentLoadException;\nimport com.sun.tools.attach.AttachNotSupportedException;\nimport com.sun.tools.attach.VirtualMachine;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.management.MalformedObjectNameException;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.tools.jmx.JmxModel;\nimport org.graalvm.visualvm.tools.jmx.JmxModelFactory;\nimport org.openide.modules.InstalledFileLocator;\nimport org.openide.modules.ModuleInfo;\nimport org.openide.modules.Modules;\nimport org.openide.util.Exceptions;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic abstract class TruffleDataProvider {\n\n    protected static final Logger LOGGER = Logger.getLogger(TruffleDataProvider.class.getName());\n    private static String AGENT_PATH = \"modules/ext/stagent.jar\";   // NOI18N\n\n    protected String status;\n    protected ProxyTruffleMBean tbean;\n\n    protected static String initJMXConn(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) {\n            return NbBundle.getMessage(TruffleDataProvider.class, \"MSG_Unavailable\"); // NOI18N\n        }\n        JmxModel jmxModel = JmxModelFactory.getJmxModelFor(application);\n        if (jmxModel == null) {\n            return NbBundle.getMessage(TruffleDataProvider.class, \"MSG_Unavailable_init_jmx\"); // NOI18N\n        }\n        if (jmxModel.getConnectionState() != JmxModel.ConnectionState.CONNECTED) {\n            return NbBundle.getMessage(TruffleDataProvider.class, \"MSG_Unavailable_create_jmx\"); // NOI18N\n        }\n        return null;\n    }\n\n    public String getStatus() {\n        return status;\n    }\n\n    protected boolean checkAndLoadJMX(Application app) throws MalformedObjectNameException, IOException, InterruptedException {\n        synchronized (app) {\n            JmxModel jmxModel = JmxModelFactory.getJmxModelFor(app);\n            tbean = new ProxyTruffleMBean(jmxModel.getMBeanServerConnection());\n            if (tbean.isRegistered()) {\n                return true;\n            }\n            if (loadAgent(app)) {\n                for (int i = 0; i < 10; i++) {\n                    if (tbean.isRegistered()) {\n                        return true;\n                    }\n                    Thread.sleep(300);\n                }\n            }\n            return tbean.isRegistered();\n        }\n    }\n\n    private boolean loadAgent(Application app) {\n        String pid = String.valueOf(app.getPid());\n        String agentPath = getAgentPath();\n\n        LOGGER.warning(\"Agent \" + agentPath);    // NOI18N\n        try {\n            VirtualMachine vm = VirtualMachine.attach(pid);\n            LOGGER.warning(vm.toString());\n            loadAgentIntoTargetJVM(vm, agentPath, null);\n            vm.detach();\n            LOGGER.warning(\"Agent loaded\");    // NOI18N\n            return true;\n        } catch (AttachNotSupportedException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (IOException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (AgentLoadException ex) {\n            Exceptions.printStackTrace(ex);\n        } catch (AgentInitializationException ex) {\n            LOGGER.log(Level.INFO, \"loadAgent()\", ex);\n        }\n        return false;\n    }\n\n    private static void loadAgentIntoTargetJVM(final VirtualMachine virtualMachine, final String jar, final String options)\n            throws IOException, AgentLoadException, AgentInitializationException {\n        try {\n            virtualMachine.loadAgent(jar, options);\n        } catch (AgentLoadException ex) {\n            if (\"0\".equals(ex.getMessage())) {\n                // JDK 10 -> JDK 9 mismatch\n                return;\n            }\n            throw ex;\n        } catch (IOException ex) {\n            if (\"readInt\".equals(ex.getStackTrace()[0].getMethodName())) {\n                // JDK 9 -> JDK 10 mismatch\n                return;\n            }\n            throw ex;\n        }\n    }\n\n    private String getAgentPath() {\n        InstalledFileLocator loc = InstalledFileLocator.getDefault();\n        ModuleInfo info = Modules.getDefault().ownerOf(getClass());\n        File jar = loc.locate(AGENT_PATH, info.getCodeNameBase(), false);\n\n        return jar.getAbsolutePath();\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/cpu/Bundle.properties",
    "content": "#\n# Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_Cpu_settings=CPU settings\n\nLBL_Cpu_samples=CPU samples\n\nTOOLTIP_Pause_results=Pause live results\n\nTOOLTIP_Update_results=Update live results now\n\nLBL_Deltas=Deltas\n\nTOOLTIP_Deltas=Show delta values\n\nLBL_Snapshot=Snapshot\n\nTOOLTIP_Snapshot=Take snapshot of collected results\n\nLBL_Thread_dump=Thread Dump\n\nTOOLTIP_Thread_dump=Take thread dump\n\nLBL_No_data=<No Data>\n\nMSG_unavailable_threads=Not available. Cannot access truffle JMX in target application. Check the VisualVM logfile ({0}).\n\nMSG_unavailable_stacktraces=Not available. StackTraces instrument is not available. Please start your application with --stacktraces commandline option.\n\nSEP_EngineSettings=Engine settings\n\nLBL_Mode=Mode\\:\n\nTOOLTIP_Mode=Mode\n\nMODE_ROOTS=All Functions\n\nMODE_EXCLUDE_INLINED_ROOTS=Exclude Inlined Functions\n\nMODE_STATEMENTS=Statements\n\nLBL_Split=Split compiled and inlined\n\nTOOLTIP_Split=Split compiled and inlined\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/cpu/CCTFlattener.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.truffle.cpu;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.Stack;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNodeProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.MethodInfoMapper;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MethodCPUCCTNode;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.TimedCPUCCTNode;\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class CCTFlattener extends RuntimeCCTNodeProcessor.PluginAdapter {\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private final Object containerGuard = new Object();\n\n    // @GuardedBy containerGuard\n    private FlatProfileContainer container;\n    private Stack<TotalTime> parentStack;\n    private Set<Integer> methodsOnStack;\n    private int[] invDiff;\n    private int[] invPM;\n    private int[] nCalleeInvocations;\n    private long[] timePM0;\n    private long[] timePM1;\n    private long[] totalTimePM0;\n    private long[] totalTimePM1;\n    private int nMethods;\n    private InstrumentationFilter instrFilter;\n    private boolean twoTimestamps;\n    private MethodInfoMapper methodInfoMapper;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    CCTFlattener(boolean twoStamps, MethodInfoMapper mapper, InstrumentationFilter f) {\n        parentStack = new Stack<>();\n        methodsOnStack = new HashSet<>();\n        nMethods = mapper.getMaxMethodId();\n        methodInfoMapper = mapper;\n        twoTimestamps = twoStamps;\n        instrFilter = f;\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    FlatProfileContainer getFlatProfile() {\n        synchronized (containerGuard) {\n            return container;\n        }\n    }\n\n    public void onStop() {\n        // Now convert the data into microseconds\n        long wholeGraphTime0 = 0;\n\n        // Now convert the data into microseconds\n        long wholeGraphTime1 = 0;\n        long totalNInv = 0;\n\n        for (int i = 0; i < nMethods; i++) {\n            // convert to microseconds\n            double time = timePM0[i] / 1000.0;\n\n            if (time < 0) {\n                // in some cases the combination of cleansing the time by calibration and subtracting wait/sleep\n                // times can lead to <0 time\n                // see https://netbeans.org/bugzilla/show_bug.cgi?id=64416\n                time = 0;\n            }\n\n            timePM0[i] = (long) time;\n\n            // don't include the Thread time into wholegraphtime\n            if (i > 0) {\n                wholeGraphTime0 += time;\n            }\n\n            if (twoTimestamps) {\n                // convert to microseconds\n                time = timePM1[i] / 1000.0;\n                timePM1[i] = (long) time;\n\n                // don't include the Thread time into wholegraphtime\n                if (i > 0) {\n                    wholeGraphTime1 += time;\n                }\n            }\n\n            totalNInv += invPM[i];\n        }\n\n        synchronized (containerGuard) {\n            container = new FlatProfilerContainer(methodInfoMapper, twoTimestamps, timePM0, timePM1, totalTimePM0, totalTimePM1,\n                    invPM, new char[0], wholeGraphTime0, wholeGraphTime1, invPM.length);\n        }\n\n        timePM0 = timePM1 = null;\n        invPM = invDiff = nCalleeInvocations = null;\n        parentStack.clear();\n        methodsOnStack.clear();\n        instrFilter = null;\n    }\n\n    public void onStart() {\n        timePM0 = new long[nMethods];\n        timePM1 = new long[twoTimestamps ? nMethods : 0];\n        totalTimePM0 = new long[nMethods];\n        totalTimePM1 = new long[twoTimestamps ? nMethods : 0];\n        invPM = new int[nMethods];\n        invDiff = new int[nMethods];\n        nCalleeInvocations = new int[nMethods];\n        parentStack.clear();\n        methodsOnStack.clear();\n\n        synchronized (containerGuard) {\n            container = null;\n        }\n    }\n\n    public void onNode(MethodCPUCCTNode node) {\n        final int nodeMethodId = node.getMethodId();\n        final int nodeFilerStatus = node.getFilteredStatus();\n        final MethodCPUCCTNode currentParent = parentStack.isEmpty() ? null : parentStack.peek().parent;\n        boolean filteredOut = (nodeFilerStatus == TimedCPUCCTNode.FILTERED_YES); // filtered out by rootmethod/markermethod rules\n\n        if (!filteredOut) {\n            String jvmClassName = methodInfoMapper.getInstrMethodClass(nodeMethodId).replace('.', '/'); // NOI18N\n            filteredOut = !instrFilter.passes(jvmClassName);\n        }\n\n        final int parentMethodId = currentParent != null ? currentParent.getMethodId() : -1;\n\n        if (filteredOut) {\n            if ((currentParent != null) && !currentParent.isRoot()) {\n                invDiff[parentMethodId] += node.getNCalls();\n\n                timePM0[parentMethodId] += node.getNetTime0();\n\n                if (twoTimestamps) {\n                    timePM1[parentMethodId] += node.getNetTime1();\n                }\n            }\n        } else {\n            timePM0[nodeMethodId] += node.getNetTime0();\n\n            if (twoTimestamps) {\n                timePM1[nodeMethodId] += node.getNetTime1();\n            }\n\n            invPM[nodeMethodId] += node.getNCalls();\n\n            if ((currentParent != null) && !currentParent.isRoot()) {\n                nCalleeInvocations[parentMethodId] += node.getNCalls();\n            }\n        }\n        final MethodCPUCCTNode nextParent = filteredOut ? currentParent : node;\n        final TotalTime timeNode = new TotalTime(nextParent,methodsOnStack.contains(nodeMethodId));\n        timeNode.totalTimePM0+=node.getNetTime0();\n        if (twoTimestamps) timeNode.totalTimePM1+=node.getNetTime1();\n        if (!timeNode.recursive) {\n            methodsOnStack.add(nodeMethodId);\n        }\n        parentStack.push(timeNode);\n    }\n\n    public void onBackout(MethodCPUCCTNode node) {\n        TotalTime current = parentStack.pop();\n        if (!current.recursive) {\n            int nodeMethodId = node.getMethodId();\n            methodsOnStack.remove(nodeMethodId);\n            // convert to microseconds\n            double time = current.totalTimePM0 / 1000.0;\n            if (time>0) {\n                totalTimePM0[nodeMethodId]+=time;\n            }\n            if (twoTimestamps) {\n                time = current.totalTimePM1 / 1000.0;\n                if (time>0) {\n                    totalTimePM1[nodeMethodId]+=time;\n                }\n            }\n        }\n        // add self data to parent\n        if (!parentStack.isEmpty()) {\n            TotalTime parent = parentStack.peek();\n            parent.add(current);\n            parent.outCalls+=node.getNCalls();\n        }\n    }\n\n    private static class TotalTime {\n        private final MethodCPUCCTNode parent;\n        private final boolean recursive;\n        private int outCalls;\n        private long totalTimePM0;\n        private long totalTimePM1;\n\n        TotalTime(MethodCPUCCTNode n, boolean r) {\n            parent = n;\n            recursive = r;\n        }\n\n        private void add(TotalTime current) {\n            outCalls += current.outCalls;\n            totalTimePM0 += current.totalTimePM0;\n            totalTimePM1 += current.totalTimePM1;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/cpu/CPUSamplerSupport.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle.cpu;\n\nimport java.io.DataOutputStream;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.Timer;\nimport java.util.TimerTask;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasupport.Utils;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.common.ProfilingSettingsPresets;\nimport org.graalvm.visualvm.lib.jfluid.filters.GenericFilter;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot.NoDataAvailableException;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.StackTraceSnapshotBuilder;\nimport org.graalvm.visualvm.lib.profiler.LoadedSnapshot;\nimport org.graalvm.visualvm.lib.profiler.ResultsManager;\nimport org.graalvm.visualvm.sampler.truffle.AbstractSamplerSupport;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic abstract class CPUSamplerSupport extends AbstractSamplerSupport {\n    \n    private final Application application;\n\n    private final ThreadInfoProvider threadInfoProvider;\n    private final SnapshotDumper snapshotDumper;\n    private final ThreadDumper threadDumper;\n\n    private Timer timer;\n    private TimerTask samplerTask;\n    private final Refresher refresher;\n    private int refreshRate;\n\n    private StackTraceSnapshotBuilder builder;\n\n    private volatile boolean sampleRunning;\n    private final Object updateLock = new Object();\n    private long currentLiveUpdate;\n    private long lastLiveUpdate;\n\n    private CPUView cpuView;\n    private DataViewComponent.DetailsView[] detailsViews;\n\n    public CPUSamplerSupport(Application application, ThreadInfoProvider tip, SnapshotDumper snapshotDumper, ThreadDumper threadDumper) {\n        this.application = application;\n        \n        threadInfoProvider = tip;\n        this.snapshotDumper = snapshotDumper;\n        this.threadDumper = threadDumper;\n\n        refreshRate = GlobalPreferences.sharedInstance().getMonitoredDataPoll() * 1000;\n\n        refresher = new Refresher() {\n            public void setRefreshRate(int rr) {\n                CPUSamplerSupport.this.refreshRate = rr;\n            }\n            public int getRefreshRate() {\n                return CPUSamplerSupport.this.refreshRate;\n            }\n            protected boolean checkRefresh() {\n                return samplerTask != null && cpuView.isShowing();\n            }\n            protected void doRefresh() {\n                doRefreshImpl();\n            }\n        };\n    }\n\n\n    public DataViewComponent.DetailsView[] getDetailsView() {\n        if (detailsViews == null) {\n            cpuView = new CPUView(refresher, snapshotDumper, threadDumper, application);\n            detailsViews = new DataViewComponent.DetailsView[1];\n            detailsViews[0] = new DataViewComponent.DetailsView(NbBundle.getMessage(\n                CPUSamplerSupport.class, \"LBL_Cpu_samples\"), null, 10, cpuView, null); // NOI18N\n        }\n        cpuView.initSession();\n        return detailsViews.clone();\n    }\n\n    public void setOptions(String mode, boolean trackFlags) {\n        threadInfoProvider.setOptions(mode, trackFlags);\n    }\n\n    public boolean startSampling(ProfilingSettings settings, int samplingRate, int refreshRate) {\n        checkCPUSamplingRate(samplingRate);\n        \n        GenericFilter sf = settings.getInstrumentationFilter();\n        InstrumentationFilter filter = new InstrumentationFilter(sf);\n        builder = snapshotDumper.getNewBuilder(filter);\n        \n        refresher.setRefreshRate(refreshRate);\n\n        final StackTraceSnapshotBuilder _builder = builder;\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (cpuView != null) {\n                    cpuView.setBuilder(_builder);\n                    cpuView.starting();\n                }\n            }\n        });\n\n        if (timer == null) timer = getTimer();\n        samplerTask = new SamplerTask(builder);\n\n        timer.scheduleAtFixedRate(samplerTask, 0, samplingRate);\n        return true;\n    }\n\n    public synchronized void stopSampling() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (cpuView != null) cpuView.stopping();\n            }\n        });\n        \n        if (samplerTask != null) {\n            samplerTask.cancel();\n            samplerTask = null;\n        }\n    }\n\n    public synchronized void terminate() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (cpuView != null) cpuView.terminated();\n            }\n        });\n        \n        if (timer != null) {\n            timer.cancel();\n            timer = null;\n        }\n        \n        builder = null;  // release data\n    }\n\n\n    private void doRefreshImpl() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (samplerTask == null) return;\n                if (!sampleRunning) {\n                    synchronized (updateLock) {\n                        lastLiveUpdate = currentLiveUpdate;\n                        cpuView.refresh();\n                    }\n                } else {\n                    SwingUtilities.invokeLater(this);\n                }\n            }\n        });\n    }\n//    private void doRefreshImpl(final javax.swing.Timer stimer, final ThreadsCPUView view) {\n//        if (!stimer.isRunning() || view.isPaused()) return;\n//        \n//        try {\n//            timer.schedule(new TimerTask() {\n//                public void run() {\n//                    try {\n//                        if (!stimer.isRunning()) return;\n//                    } catch (Exception e) {\n//                        terminate();\n//                    }\n//                }\n//            }, 0);\n//        } catch (Exception e) {\n//            terminate();\n//        }\n//    }\n//    \n//    private void doRefreshImplImpl(final ThreadsCPUInfo info, final ThreadsCPUView view) {\n//            SwingUtilities.invokeLater(new Runnable() {\n//                public void run() {\n//                    view.refresh(info);\n//                }\n//            });\n//    }\n\n    private class SamplerTask extends TimerTask {\n\n        private final StackTraceSnapshotBuilder builder;\n        private final Set<String> samplingThreads = new HashSet<>();\n\n        SamplerTask(StackTraceSnapshotBuilder builder) {\n            this.builder = builder;\n        }\n\n        public void run() {\n            if (sampleRunning) return;\n            sampleRunning = true;\n            synchronized (updateLock) {\n                try {\n                    Map<String,Object>[] infos = threadInfoProvider.dumpAllThreads();\n                    long timestamp = System.nanoTime();\n                    String samplingThreadName = null;\n                    if (samplingThreadName != null) {\n                        if (samplingThreads.add(samplingThreadName)) {\n//                                System.out.println(\"New ignored thread: \"+samplingThreadName);\n                            builder.setIgnoredThreads(samplingThreads);\n                        }\n                    }\n                    addSourceNames(infos);\n                    builder.addStacktrace(infos, timestamp);\n\n                    currentLiveUpdate = timestamp / 1000000;\n                    if (currentLiveUpdate - lastLiveUpdate >= refreshRate)\n                        refresher.refresh();\n\n                } catch (Throwable ex) {\n                    ex.printStackTrace();\n                    terminate();\n                } finally {\n                    sampleRunning = false;\n                }\n            }\n        }\n\n        private static final int COMPILED  = 1;  // 0001\n        private static final int INLINED   = 2;  // 0010\n\n        private void addSourceNames(Map<String,Object>[] infoMap) {\n            for (Map<String,Object> threadInfo : infoMap) {\n                StackTraceElement[] stack = (StackTraceElement[]) threadInfo.get(\"stack\");  // NOI18N\n                byte[] flags = (byte[]) threadInfo.get(\"flags\");  // NOI18N\n\n                for (int i = 0; i <stack.length; i++) {\n                    StackTraceElement ste = stack[i];\n                    byte flag = flags!=null ? flags[i] : 0;\n                    File file = new File(ste.getFileName());\n                    String fname = file.getName();\n                    String flagSrt = \"\";\n                    if (isCompiled(flag)) {\n                        flagSrt = \"compiled\";\n                        if (isInlined(flag)) {\n                            flagSrt += \", \";\n                            flagSrt += \"inlined\";\n                        }\n                        flagSrt=\" [\"+flagSrt+\"]\";\n                    }\n                    String detailedName = ste.getMethodName()+flagSrt+\"|(L\"+fname+\":\"+ste.getLineNumber()+\";)L;\";   // NOI18N\n                    stack[i] = new StackTraceElement(ste.getClassName(), detailedName, ste.getFileName(), ste.getLineNumber());\n                }\n            }\n        }\n\n        private boolean isCompiled(byte flag) {\n            return (flag&COMPILED)==COMPILED;\n        }\n\n        private boolean isInlined(byte flag) {\n            return (flag&INLINED)==INLINED;\n        }\n    }\n\n    public static abstract class ThreadDumper {\n        public abstract void takeThreadDump(boolean openView);\n    }\n\n    public static abstract class SnapshotDumper {\n        private StackTraceSnapshotBuilder builder;\n                \n        StackTraceSnapshotBuilder getNewBuilder(InstrumentationFilter filter) {\n            builder = new StackTraceSnapshotBuilder(1,filter);\n            return builder;\n        }\n        \n        public final LoadedSnapshot takeNPSSnapshot(File directory) throws IOException, NoDataAvailableException {\n            if (builder == null) throw new IllegalStateException(\"Builder is null\"); // NOI18N\n            long time = System.currentTimeMillis();\n            CPUResultsSnapshot snapshot = builder.createSnapshot(time);\n            LoadedSnapshot ls = new LoadedSnapshot(snapshot, ProfilingSettingsPresets.createCPUPreset(), null, null);\n            File file = Utils.getUniqueFile(directory,\n                    ResultsManager.getDefault().getDefaultSnapshotFileName(ls),\n                    \".\" + ResultsManager.SNAPSHOT_EXTENSION); // NOI18N\n            try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(file))) {\n                ls.save(dos);\n                ls.setFile(file);\n                ls.setSaved(true);\n            }\n            return ls;\n        }\n\n        public abstract void takeSnapshot(boolean openView);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/cpu/CPUSettingsSupport.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle.cpu;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.ItemEvent;\nimport java.awt.event.ItemListener;\nimport javax.swing.BorderFactory;\nimport javax.swing.JCheckBox;\nimport javax.swing.JComboBox;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.core.ui.components.SectionSeparator;\nimport org.graalvm.visualvm.core.ui.components.Spacer;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.profiling.presets.PresetSelector;\nimport org.graalvm.visualvm.profiling.presets.SamplerCPUPanel;\nimport org.openide.util.NbBundle;\nimport org.openide.util.NbPreferences;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class CPUSettingsSupport {\n    \n    private static final String PROP_MODE = \"CPUSettingsSupport.Mode\"; // NOI18N\n    private static final String PROP_SPLIT_COMPILED_INLINED = \"CPUSettingsSupport.SplitCompiledInlined\"; // NOI18N\n    private JComboBox<Mode> modeCombo;\n    private JLabel modeLabel;\n    private Spacer space;\n    \n    private static enum Mode {\n        EXCLUDE_INLINED_ROOTS { @Override public String toString() { return NbBundle.getMessage(CPUSettingsSupport.class, \"MODE_EXCLUDE_INLINED_ROOTS\"); } }, // NOI18N\n        ROOTS { @Override public String toString() { return NbBundle.getMessage(CPUSettingsSupport.class, \"MODE_ROOTS\"); } }, // NOI18N\n        STATEMENTS { @Override public String toString() { return NbBundle.getMessage(CPUSettingsSupport.class, \"MODE_STATEMENTS\"); } }, // NOI18N\n    };\n    \n    \n    private JPanel container;\n    private SamplerCPUPanel panel;\n    private PresetSelector selector;\n    \n    private DataViewComponent.DetailsView detailsView;\n    \n    \n    public DataViewComponent.DetailsView getDetailsView() {\n        if (detailsView == null) {\n            detailsView = new DataViewComponent.DetailsView(NbBundle.getMessage(\n                          CPUSettingsSupport.class, \"LBL_Cpu_settings\"), null, 10, // NOI18N\n                          new ScrollableContainer(createPanel()), null);\n        }\n        return detailsView;\n    }\n    \n    \n    public ProfilingSettings getSettings() { return panel.getSettings(); }\n\n    public int getSamplingRate() { return panel.getSamplingRate(); }\n    \n    public int getRefreshRate() { return panel.getRefreshRate(); }\n    \n    public String getMode() {\n        return NbPreferences.forModule(CPUSettingsSupport.class).get(PROP_MODE, Mode.EXCLUDE_INLINED_ROOTS.name());\n    }\n    \n    public void enableMode(boolean enable) {\n        if (panel != null) {\n            modeLabel.setVisible(enable);\n            modeCombo.setVisible(enable);\n            space.setVisible(enable);\n            container.revalidate();\n        }\n    }\n\n    public boolean isSplitCompiledInlined() {\n        return NbPreferences.forModule(CPUSettingsSupport.class).getBoolean(PROP_SPLIT_COMPILED_INLINED, false);\n    }\n    \n    public void saveSettings() {\n        // NOTE: might save custom configuration here\n    }\n    \n    public abstract boolean presetValid();\n    \n    public boolean settingsValid() { return panel.settingsValid(); }\n    \n    public void showSettings(DataViewComponent dvc) {\n        dvc.selectDetailsView(getDetailsView());\n    }\n    \n    public abstract PresetSelector createSelector(Runnable presetSynchronizer);\n    \n    \n    public void setEnabled(boolean enabled) {\n        if (container != null) container.setEnabled(enabled);\n    }\n    \n    private JPanel createPanel() {\n        panel = new SamplerCPUPanel() {\n            public void settingsChanged() {\n                panel.saveToPreset(selector.customize(presetValid()));\n            }\n        };\n        \n        selector = createSelector(new Runnable() {\n            public void run() { panel.loadFromPreset(selector.getSelectedPreset()); }\n        });\n        selector.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));\n        \n        container = new JPanel(new BorderLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents()) c.setEnabled(enabled);\n            }\n        };\n        container.setOpaque(false);\n        container.add(panel, BorderLayout.CENTER);\n        \n        JPanel southPanel = new JPanel(new BorderLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents()) c.setEnabled(enabled);\n            }\n        };\n        southPanel.setOpaque(false);\n        southPanel.add(selector, BorderLayout.NORTH);\n        \n        JPanel engineSettingsPanel = new JPanel(new GridBagLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents()) c.setEnabled(enabled);\n            }\n        };\n        engineSettingsPanel.setOpaque(false);\n        \n        SectionSeparator section = new SectionSeparator(NbBundle.getMessage(CPUSettingsSupport.class, \"SEP_EngineSettings\"), new JLabel().getFont()); // NOI18N\n        GridBagConstraints constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 0;\n        constraints.weightx = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.HORIZONTAL;\n        constraints.insets = new Insets(25, 10, 5, 5);\n        engineSettingsPanel.add(section, constraints);\n        \n        modeLabel = new JLabel();\n        modeLabel.setText(NbBundle.getMessage(CPUSettingsSupport.class, \"LBL_Mode\")); // NOI18N\n        modeLabel.setToolTipText(NbBundle.getMessage(CPUSettingsSupport.class, \"TOOLTIP_Mode\")); // NOI18N\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 1;\n        constraints.gridwidth = 1;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 10, 5, 5);\n        engineSettingsPanel.add(modeLabel, constraints);\n\n        modeCombo = new JComboBox<Mode>(Mode.values()) {\n            public Dimension getMinimumSize() { return getPreferredSize(); }\n            public Dimension getMaximumSize() { return getPreferredSize(); }\n        };\n        modeCombo.setSelectedItem(Mode.valueOf(getMode()));\n        modeLabel.setLabelFor(modeCombo);\n        modeCombo.setToolTipText(NbBundle.getMessage(CPUSettingsSupport.class, \"TOOLTIP_Mode\")); // NOI18N\n        modeCombo.setEditable(false);\n        modeCombo.addActionListener(new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                Mode selected = (Mode)modeCombo.getSelectedItem();\n                NbPreferences.forModule(CPUSettingsSupport.class).put(PROP_MODE, selected.name());\n            }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 1;\n        constraints.gridy = 1;\n        constraints.gridwidth = 2;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(5, 0, 5, 5);\n        engineSettingsPanel.add(modeCombo, constraints);\n\n        constraints = new GridBagConstraints();\n        constraints.gridx = 3;\n        constraints.gridy = 1;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.HORIZONTAL;\n        constraints.insets = new Insets(5, 0, 5, 0);\n        space = Spacer.create();\n        engineSettingsPanel.add(space, constraints);\n        \n        \n        final JCheckBox splitChoice = new JCheckBox();\n        splitChoice.setSelected(isSplitCompiledInlined());\n        splitChoice.setText(NbBundle.getMessage(CPUSettingsSupport.class,\"LBL_Split\")); // NOI18N\n        splitChoice.setToolTipText(NbBundle.getMessage(CPUSettingsSupport.class, \"TOOLTIP_Split\")); // NOI18N\n        splitChoice.setOpaque(false);\n        splitChoice.addItemListener(new ItemListener() {\n            @Override\n            public void itemStateChanged(ItemEvent e) {\n                NbPreferences.forModule(CPUSettingsSupport.class).putBoolean(PROP_SPLIT_COMPILED_INLINED, splitChoice.isSelected());\n            }\n        });\n        constraints = new GridBagConstraints();\n        constraints.gridx = 0;\n        constraints.gridy = 2;\n        constraints.gridwidth = 2;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.NONE;\n        constraints.insets = new Insets(1, 10, 10, 5);\n        engineSettingsPanel.add(splitChoice, constraints);\n        \n        constraints = new GridBagConstraints();\n        constraints.gridx = 3;\n        constraints.gridy = 2;\n        constraints.gridwidth = GridBagConstraints.REMAINDER;\n        constraints.anchor = GridBagConstraints.WEST;\n        constraints.fill = GridBagConstraints.HORIZONTAL;\n        constraints.insets = new Insets(5, 0, 10, 0);\n        engineSettingsPanel.add(Spacer.create(), constraints);\n        \n        southPanel.add(engineSettingsPanel, BorderLayout.SOUTH);\n        \n        container.add(southPanel, BorderLayout.SOUTH);\n        \n        return container;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/cpu/CPUView.java",
    "content": "/*\n * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle.cpu;\n\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.ItemEvent;\nimport javax.swing.AbstractAction;\nimport javax.swing.AbstractButton;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.Icon;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.StackTraceSnapshotBuilder;\nimport org.graalvm.visualvm.lib.profiler.actions.TakeSnapshotAction;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.cpu.LiveCPUView;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.MultiButtonGroup;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.profiling.actions.ProfilerResultsAction;\nimport org.graalvm.visualvm.sampler.truffle.AbstractSamplerSupport;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n//    \"MethodsFeatureUI_viewHotSpots=Hot spots\",\n//    \"MethodsFeatureUI_viewCallTree=Call tree\",\n//    \"MethodsFeatureUI_viewCombined=Combined\",\n    \"MethodsFeatureUI_selectedMethods=Selected methods\",\n    \"MethodsFeatureUI_liveResults=Results:\",\n    \"MethodsFeatureUI_pauseResults=Pause live results\",\n    \"MethodsFeatureUI_updateResults=Update live results\",\n    \"MethodsFeatureUI_view=View:\",\n    \"MethodsFeatureUI_viewForward=Forward calls\",\n    \"MethodsFeatureUI_viewHotSpots=Hot spots\",\n    \"MethodsFeatureUI_viewReverse=Reverse calls\",\n    \"MethodsFeatureUI_resultsMode=Results mode\",\n    \"MethodsFeatureUI_profilingData=Collected data:\",\n    \"MethodsFeatureUI_snapshot=Snapshot\",\n    \"MethodsFeatureUI_showAbsolute=Show absolute values\",\n    \"MethodsFeatureUI_showDeltas=Show delta values\"\n})\nfinal class CPUView extends JPanel {\n    \n    private final AbstractSamplerSupport.Refresher refresher;\n    private boolean forceRefresh = false;\n    \n    private final CPUSamplerSupport.SnapshotDumper snapshotDumper;\n    private final CPUSamplerSupport.ThreadDumper threadDumper;\n    \n    private StackTraceSnapshotBuilder builder;\n\n    private ProfilerToolbar toolbar;\n    private LiveCPUView cpuView;\n\n\n    CPUView(AbstractSamplerSupport.Refresher refresher, CPUSamplerSupport.SnapshotDumper\n            snapshotDumper, CPUSamplerSupport.ThreadDumper threadDumper, Application application) {\n        this.refresher = refresher;\n        this.snapshotDumper = snapshotDumper;\n        this.threadDumper = threadDumper;\n        \n        initComponents(application);\n\n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (isShowing()) CPUView.this.refresher.refresh();\n                }\n            }\n        });\n    }\n\n    \n    void setBuilder(StackTraceSnapshotBuilder builder) {\n        this.builder = builder;\n    }\n\n    void initSession() {\n        pdSnapshotButton.setEnabled(false);\n//        pdResetResultsButton.setEnabled(false);\n    }\n\n    void refresh() {\n        if (!isShowing() || (lrPauseButton.isSelected() && !forceRefresh)) return;\n        forceRefresh = false;\n        \n        try {\n            // TODO: perform out of the EDT!\n            CPUResultsSnapshot snapshot = builder.createSnapshot(System.currentTimeMillis());\n            cpuView.setData(snapshot, true);\n        } catch (CPUResultsSnapshot.NoDataAvailableException ex) {\n            // no problem, just no data matching the provided filter yet\n//            Exceptions.printStackTrace(ex);\n        }\n\n        pdSnapshotButton.setEnabled(snapshotDumper != null);\n//        pdResetResultsButton.setEnabled(pdSnapshotButton.isEnabled());\n    }\n    \n    void starting() {\n        lrPauseButton.setEnabled(true);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(true);\n        cpuView.resetData();\n    }\n    \n    void stopping() {\n        lrPauseButton.setEnabled(false);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(false);\n    }\n    \n    void terminated() {\n        lrPauseButton.setEnabled(false);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(false);\n        threaddumpButton.setEnabled(false);\n    }\n\n//    void terminate() {\n//        lrPauseButton.setEnabled(false);\n//        lrRefreshButton.setEnabled(false);\n//        threaddumpButton.setEnabled(false);\n//    }\n\n    \n    private JLabel lrLabel;\n    private JToggleButton lrPauseButton;\n    private JButton lrRefreshButton;\n    private JToggleButton lrDeltasButton;\n    \n    private JLabel pdLabel;\n    private JButton pdSnapshotButton;\n//    private JButton pdResetResultsButton;\n    \n    private boolean popupPause;\n    private JToggleButton[] toggles;\n    \n    private AbstractButton threaddumpButton;\n\n    private void initComponents(Application application) {\n        setLayout(new BorderLayout());\n        setOpaque(false);\n        \n        \n        cpuView = new LiveCPUView(null) {\n            protected boolean showSourceSupported() {\n                return GoToSource.isAvailable();\n            }\n            protected boolean profileMethodSupported() {\n                return false;\n            }\n            protected boolean profileClassSupported() {\n                return false;\n            }\n            protected void showSource(ClientUtils.SourceCodeSelection value) {\n//                Lookup.Provider project = getProject();\n                Lookup.Provider project = null;\n                String className = value.getClassName();\n                String methodName = value.getMethodName();\n                String methodSig = value.getMethodSignature();\n                GoToSource.openSource(project, className, methodName, methodSig);\n            }\n            protected void selectForProfiling(ClientUtils.SourceCodeSelection value) {\n//                MethodsFeatureUI.this.selectForProfiling(value);\n            }\n            protected void popupShowing() {\n                if (lrPauseButton.isEnabled() && !lrRefreshButton.isEnabled()) {\n                    popupPause = true;\n                    lrPauseButton.setSelected(true);\n                }\n            }\n            protected void popupHidden() {\n                if (lrPauseButton.isEnabled() && popupPause) {\n                    popupPause = false;\n                    lrPauseButton.setSelected(false);\n                }\n            }\n            protected void foundInForwardCalls() {\n                super.foundInForwardCalls();\n                toggles[0].setSelected(true);\n            }\n            protected void foundInHotSpots() {\n                super.foundInHotSpots();\n                toggles[1].setSelected(true);\n            }\n            protected void foundInReverseCalls() {\n                super.foundInReverseCalls();\n                toggles[2].setSelected(true);\n            }\n        };\n        cpuView.putClientProperty(ProfilerResultsAction.PROP_APPLICATION, application);\n        \n        InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        ActionMap actionMap = getActionMap();\n        \n        final String filterKey = FilterUtils.FILTER_ACTION_KEY;\n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                Action action = cpuView.getActionMap().get(filterKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);\n        \n        final String findKey = SearchUtils.FIND_ACTION_KEY;\n        Action findAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                Action action = cpuView.getActionMap().get(findKey);\n                if (action != null && action.isEnabled()) action.actionPerformed(e);\n            }\n        };\n        ActionsSupport.registerAction(findKey, findAction, actionMap, inputMap);\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        lrLabel = new GrayLabel(Bundle.MethodsFeatureUI_liveResults());\n            \n        lrPauseButton = new JToggleButton(Icons.getIcon(GeneralIcons.PAUSE)) {\n            protected void fireItemStateChanged(ItemEvent event) {\n                boolean paused = lrPauseButton.isSelected();\n                lrRefreshButton.setEnabled(paused && !popupPause);\n                if (!paused) refresher.refresh();\n            }\n        };\n        lrPauseButton.setToolTipText(Bundle.MethodsFeatureUI_pauseResults());\n//        lrPauseButton.setEnabled(false);\n\n        lrRefreshButton = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                forceRefresh = true;\n                refresher.refresh();\n            }\n        };\n        lrRefreshButton.setToolTipText(Bundle.MethodsFeatureUI_updateResults());\n        lrRefreshButton.setEnabled(false);\n        \n        Icon icon = Icons.getIcon(ProfilerIcons.DELTA_RESULTS);\n        lrDeltasButton = new JToggleButton(icon) {\n            protected void fireActionPerformed(ActionEvent e) {\n                if (!cpuView.setDiffView(isSelected())) setSelected(false);\n                setToolTipText(isSelected() ? Bundle.MethodsFeatureUI_showAbsolute() :\n                                              Bundle.MethodsFeatureUI_showDeltas());\n            }\n        };\n        lrDeltasButton.setToolTipText(Bundle.MethodsFeatureUI_showDeltas());\n        \n        MultiButtonGroup group = new MultiButtonGroup();\n        toggles = new JToggleButton[3];\n        \n        JToggleButton forwardCalls = new JToggleButton(Icons.getIcon(ProfilerIcons.NODE_FORWARD)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                cpuView.setView(isSelected(), toggles[1].isSelected(), toggles[2].isSelected());\n                refresh();\n            }\n        };\n        forwardCalls.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        forwardCalls.putClientProperty(\"JButton.segmentPosition\", \"first\"); // NOI18N\n        forwardCalls.setToolTipText(Bundle.MethodsFeatureUI_viewForward());\n        group.add(forwardCalls);\n        toggles[0] = forwardCalls;\n        forwardCalls.setSelected(true);\n        \n        JToggleButton hotSpots = new JToggleButton(Icons.getIcon(ProfilerIcons.TAB_HOTSPOTS)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                cpuView.setView(toggles[0].isSelected(), isSelected(), toggles[2].isSelected());\n                refresh();\n            }\n        };\n        hotSpots.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        hotSpots.putClientProperty(\"JButton.segmentPosition\", \"middle\"); // NOI18N\n        hotSpots.setToolTipText(Bundle.MethodsFeatureUI_viewHotSpots());\n        group.add(hotSpots);\n        toggles[1] = hotSpots;\n        hotSpots.setSelected(false);\n        \n        JToggleButton reverseCalls = new JToggleButton(Icons.getIcon(ProfilerIcons.NODE_REVERSE)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                cpuView.setView(toggles[0].isSelected(), toggles[1].isSelected(), isSelected());\n                refresh();\n            }\n        };\n        reverseCalls.putClientProperty(\"JButton.buttonType\", \"segmented\"); // NOI18N\n        reverseCalls.putClientProperty(\"JButton.segmentPosition\", \"last\"); // NOI18N\n        reverseCalls.setToolTipText(Bundle.MethodsFeatureUI_viewReverse());\n        group.add(reverseCalls);\n        toggles[2] = reverseCalls;\n        reverseCalls.setSelected(false);\n\n        pdLabel = new GrayLabel(Bundle.MethodsFeatureUI_profilingData());\n\n        pdSnapshotButton = new JButton(TakeSnapshotAction.getInstance()) {\n            protected void fireActionPerformed(ActionEvent event) {\n                snapshotDumper.takeSnapshot((event.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n            }\n        };\n//        pdSnapshotButton.setHideActionText(true);\n        pdSnapshotButton.setText(Bundle.MethodsFeatureUI_snapshot());\n        pdSnapshotButton.putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n\n//        pdResetResultsButton = new JButton(ResetResultsAction.getInstance());\n//        pdResetResultsButton.setHideActionText(true);\n\n        toolbar = ProfilerToolbar.create(true);\n\n//        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(lrLabel);\n        toolbar.addSpace(2);\n        toolbar.add(lrPauseButton);\n        toolbar.add(lrRefreshButton);\n        \n        toolbar.addSpace(5);\n        toolbar.add(lrDeltasButton);\n        \n        toolbar.addSpace(2);\n//        toolbar.addSeparator();\n        toolbar.addSpace(5);\n        \n        toolbar.add(new GrayLabel(Bundle.MethodsFeatureUI_view()));\n        toolbar.addSpace(2);\n        toolbar.add(forwardCalls);\n        toolbar.add(hotSpots);\n        toolbar.add(reverseCalls);\n        \n        toolbar.addSpace(5);\n        toolbar.add(cpuView.createThreadSelector());\n\n        toolbar.addSpace(2);\n        toolbar.addSeparator();\n        toolbar.addSpace(5);\n\n        toolbar.add(pdLabel);\n        toolbar.addSpace(2);\n        toolbar.add(pdSnapshotButton);\n//        toolbar.addSpace(3);\n//        toolbar.add(pdResetResultsButton);\n        \n        toolbar.addFiller();\n        \n        threaddumpButton = new JButton(NbBundle.getMessage(CPUView.class, \"LBL_Thread_dump\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent event) {\n                threadDumper.takeThreadDump((event.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n            }\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.width += 5;\n                return dim;\n            }\n        };\n        threaddumpButton.setToolTipText(NbBundle.getMessage(CPUView.class, \"TOOLTIP_Thread_dump\")); // NOI18N\n        threaddumpButton.setOpaque(false);\n        threaddumpButton.setEnabled(threadDumper != null);\n        toolbar.add(threaddumpButton);\n        \n        \n        cpuView.setView(true, false, false);\n        \n        \n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        add(cpuView, BorderLayout.CENTER);\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/cpu/FlatProfileBuilder.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.truffle.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNodeProcessor;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.RuntimeCPUCCTNode;\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class FlatProfileBuilder implements FlatProfileProvider {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n    \n    private FlatProfileContainer lastFlatProfile = null;\n    private RuntimeCPUCCTNode appNode;\n    private CCTFlattener cctFlattener;\n    \n    \n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    FlatProfileBuilder(RuntimeCPUCCTNode node, CCTFlattener flattener) {\n        appNode = node;\n        cctFlattener = flattener;\n    }\n    \n    public synchronized FlatProfileContainer createFlatProfile() {\n        if (appNode == null) {\n            return null;\n        }\n//        client.getStatus().beginTrans(false);\n\n        try {\n            RuntimeCCTNodeProcessor.process(\n                appNode, \n                cctFlattener\n            );\n\n            lastFlatProfile = cctFlattener.getFlatProfile();\n\n        } finally {\n//            client.getStatus().endTrans();\n        }\n\n        return lastFlatProfile;\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/cpu/FlatProfilerContainer.java",
    "content": "/*\n * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.truffle.cpu;\n\nimport org.graalvm.visualvm.lib.jfluid.client.ClientUtils;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileContainer;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.MethodInfoMapper;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatter;\nimport org.graalvm.visualvm.lib.jfluid.utils.formatting.MethodNameFormatterFactory;\n\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class FlatProfilerContainer extends FlatProfileContainer {\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    protected double wholeGraphNetTime0;\n    protected double wholeGraphNetTime1;\n    private MethodInfoMapper methodInfoMapper;\n\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    /**\n     * The data passed to this constructor may contain some zero-invocation rows. That's because the size of passed arrays\n     * is equal to the number of currently instrumented methods, but in general not all of the methods may be invoked even\n     * once at an arbitrary moment.\n     *\n     * @param timeInMcs0         Array of Absolute timer values for each method - always used\n     * @param timeInMcs1         Array of CPU timer values for each method - optional, may be null\n     * @param totalTimeInMcs0   Array of Absolute timer (total time) values for each method - always used\n     * @param totalTimeInMcs1   Array of CPU timer (total time) values for each method - optional, may be null\n     * @param nInvocations       Array of number of invocations for each method\n     * @param wholeGraphNetTime0 Total absolute time\n     * @param wholeGraphNetTime1 Total CPU time - not used if CPU timer is not used\n     * @param nMethods           Total number of profiled methods - length of the provided arrays\n     */\n    FlatProfilerContainer(MethodInfoMapper mapper,boolean twoStamps,long[] timeInMcs0, long[] timeInMcs1, \n                                    long[] totalTimeInMcs0, long[] totalTimeInMcs1,int[] nInvocations,\n                                    char[] marks, double wholeGraphNetTime0, double wholeGraphNetTime1, int nMethods) {\n        super(timeInMcs0, timeInMcs1, totalTimeInMcs0, totalTimeInMcs1, nInvocations, marks, nMethods);\n        this.wholeGraphNetTime0 = wholeGraphNetTime0;\n        this.wholeGraphNetTime1 = wholeGraphNetTime1;\n\n        collectingTwoTimeStamps = twoStamps;\n        methodInfoMapper = mapper;\n\n        // Now get rid of zero-invocation entries once and forever. Also set nTotalInvocations and set negative times\n        // (that may be possible due to time cleansing inaccuracies) to zero.\n        removeZeroInvocationEntries();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public String getMethodNameAtRow(int row) {\n        int methodId = methodIds[row];\n        MethodNameFormatter formatter = MethodNameFormatterFactory.getDefault().getFormatter(null);\n\n        String className = methodInfoMapper.getInstrMethodClass(methodId);\n        String methodName = methodInfoMapper.getInstrMethodName(methodId);\n        String signature = methodInfoMapper.getInstrMethodSignature(methodId);\n\n        return formatter.formatMethodName(className, methodName, signature).toFormatted();\n    }\n\n    public double getWholeGraphNetTime0() {\n        return wholeGraphNetTime0;\n    }\n\n    public double getWholeGraphNetTime1() {\n        return wholeGraphNetTime1;\n    }\n\n    @Override\n    public ClientUtils.SourceCodeSelection getSourceCodeSelectionAtRow(int i) {\n        throw new UnsupportedOperationException(\"Not supported yet.\");  // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/cpu/SampledLivePanel.java",
    "content": "/*\n *  Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.sampler.truffle.cpu;\n\nimport javax.swing.SwingUtilities;\nimport javax.swing.table.TableColumnModel;\nimport org.graalvm.visualvm.lib.jfluid.filters.InstrumentationFilter;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.CPUResultsSnapshot;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.FlatProfileProvider;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.MethodInfoMapper;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.StackTraceSnapshotBuilder;\nimport org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.RuntimeCPUCCTNode;\nimport org.graalvm.visualvm.lib.ui.cpu.CPUResUserActionsHandler;\nimport org.graalvm.visualvm.lib.ui.cpu.LiveFlatProfileCollectorPanel;\n\n/**\n *\n * @author Tomas Hurka\n */\nfinal class SampledLivePanel extends LiveFlatProfileCollectorPanel {\n    private MethodInfoMapper methodInfoMapper;\n    private StackTraceSnapshotBuilder snapshotBuilder;\n    \n    SampledLivePanel(StackTraceSnapshotBuilder builder) {\n        super(null,new DummyHandler(),null,true);\n        methodInfoMapper = builder.getMapper();\n        snapshotBuilder = builder;\n    }\n    \n    public FlatProfileProvider getFlatProfileProvider() {\n        InstrumentationFilter filter = snapshotBuilder.getFilter();\n        boolean twoTimeStamps = snapshotBuilder.collectionTwoTimeStamps();\n        CCTFlattener flattener = new CCTFlattener(twoTimeStamps,methodInfoMapper,filter);\n        RuntimeCPUCCTNode rootNode = (RuntimeCPUCCTNode) snapshotBuilder.getAppRootNode();\n        return new FlatProfileBuilder(rootNode, flattener);\n    }\n\n    protected String[] getMethodClassNameAndSig(int methodId, int currentView) {\n        String className = methodInfoMapper.getInstrMethodClass(methodId);\n\n        if (currentView == CPUResultsSnapshot.METHOD_LEVEL_VIEW) {\n            String methodName = methodInfoMapper.getInstrMethodName(methodId);\n            String methodSig = methodInfoMapper.getInstrMethodSignature(methodId);\n\n            return new String[] { className, methodName, methodSig };\n        }\n\n        return new String[] { className, null, null };\n    }\n\n    protected void obtainResults() {\n        super.obtainResults();\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                resTable.createDefaultColumnsFromModel();\n                resTableModel.setTable(resTable);\n                setColumnsData();\n            }\n        });\n    }\n\n    private void setColumnsData() {\n        TableColumnModel colModel = resTable.getColumnModel();\n        for (int i = 0; i < resTableModel.getColumnCount(); i++) {\n            int index = resTableModel.getRealColumn(i);\n            if (index != 0)\n                colModel.getColumn(i).setPreferredWidth(columnWidths[index - 1]);\n            colModel.getColumn(i).setCellRenderer(columnRenderers[index]);\n        }\n    }\n    \n    private static final class DummyHandler extends CPUResUserActionsHandler.Adapter {\n\n        public void addMethodToRoots(final String className, final String methodName, final String methodSig) {\n            throw new IllegalStateException(\"addMethodToRoots\");    // NOI18N\n        }\n\n        public void showReverseCallGraph(final CPUResultsSnapshot snapshot, final int threadId, final int methodId, int view,\n                                         int sortingColumn, boolean sortingOrder) {\n            throw new IllegalStateException(\"showReverseCallGraph\");    // NOI18N\n        }\n\n        public void showSourceForMethod(final String className, final String methodName, final String methodSig) {\n            // no-op\n        }\n\n        public void viewChanged(int viewType) {\n            throw new IllegalStateException(\"viewChanged\"); // NOI18N\n        }\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/cpu/ThreadInfoProvider.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.truffle.cpu;\n\nimport java.io.IOException;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.MBeanException;\nimport javax.management.ReflectionException;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.sampler.truffle.TruffleDataProvider;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic final class ThreadInfoProvider extends TruffleDataProvider {\n\n    public ThreadInfoProvider(Application app, String mode, boolean trackFlags) {\n        status = initialize(app, mode, trackFlags);\n    }\n\n    private String initialize(Application application, String mode, boolean trackFlags) {\n        String st = initJMXConn(application);\n\n        if (st != null) return st;\n        try {\n            if (!checkAndLoadJMX(application)) {\n                return NbBundle.getMessage(ThreadInfoProvider.class, \"MSG_unavailable_threads\", VisualVM.getInstance().getLogfileHandle());\n            }\n            if (!tbean.isStackTracesEnabled()) {\n                return NbBundle.getMessage(ThreadInfoProvider.class, \"MSG_unavailable_stacktraces\");\n            }\n            tbean.setTrackFlags(trackFlags);\n            if (tbean.isModeAvailable()) tbean.setMode(mode);\n            tbean.dumpAllThreads();\n        } catch (SecurityException e) {\n            LOGGER.log(Level.INFO, \"threadBean.getThreadInfo(ids, maxDepth) throws SecurityException for \" + application, e); // NOI18N\n            return NbBundle.getMessage(ThreadInfoProvider.class, \"MSG_unavailable_threads\", VisualVM.getInstance().getLogfileHandle()); // NOI18N\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"threadBean.getThreadInfo(ids, maxDepth) throws Throwable for \" + application, t); // NOI18N\n            return NbBundle.getMessage(ThreadInfoProvider.class, \"MSG_unavailable_threads\", VisualVM.getInstance().getLogfileHandle()); // NOI18N\n        }\n        return null;\n    }\n\n    Map<String, Object>[] dumpAllThreads() throws InstanceNotFoundException, MBeanException, ReflectionException, IOException {\n        return tbean.dumpAllThreads();\n    }\n\n    void setOptions(String mode, boolean trackFlags) {\n        try {\n            if (tbean.isModeAvailable()) tbean.setMode(mode);\n            tbean.setTrackFlags(trackFlags);\n        } catch (Exception ex) {\n            LOGGER.log(Level.INFO, \"threadBean.setMode(), setOptions()\", ex); // NOI18N\n        }\n    }\n\n    public boolean isModeVailable() {\n        try {\n            return tbean.isModeAvailable();\n        } catch (Exception ex) {\n            LOGGER.log(Level.INFO, \"threadBean.isModeVailable(), isModeVailable()\", ex); // NOI18N\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/memory/Bundle.properties",
    "content": "#\n# Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_Memory_settings=Memory settings\n\nLBL_Heap_histogram=Heap histogram\n\nLBL_PermGen_histogram=PermGen histogram\n\nCOL_Class_name=Name\n\nCOL_Bytes_rel=Bytes [%]\n\nCOL_Bytes=Live Bytes\n\nCOL_Instances=Live Objects\n\nCOL_ALLOC_Bytes=Allocated Bytes\n\nCOL_ALLOC_Instances=Allocated Objects\n\nTOOLTIP_Pause_results=Pause live results\n\nTOOLTIP_Update_results=Update live results now\n\nLBL_Deltas=Deltas\n\nTOOLTIP_Deltas=Show delta values\n\nLBL_Snapshot=Snapshot\n\nTOOLTIP_Snapshot=Take snapshot of collected results\n\nLBL_Gc=Perform GC\n\nTOOLTIP_Gc=Perform garbage collection in target application\n\nLBL_HeapDump=Heap Dump\n\nTOOLTIP_HeapDump=Take heap dump\n\nMemoryView_TOOLTIP_Col_name=Class name\nMemoryView_TOOLTIP_Col_size=Size of live instances\nMemoryView_TOOLTIP_Col_count=Number of live instances\nMemoryView_LBL_Results=Results\\:\nMemoryView_LBL_Data=Collected data\\:\nMemoryView_LBL_Snapshot=Snapshot\nMemoryView_Context_GoToSource=Go to Source\n\nMSG_unavailable_threads=Not available. Cannot access truffle JMX in target application. Check the VisualVM logfile ({0}).\n\nMSG_unavailable_heaphisto=Not available. Heap histogram instrument is not available. Please start your application with --heaphisto commandline option.\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/memory/MemoryHistogramProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.sampler.truffle.memory;\n\nimport java.io.IOException;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.MBeanException;\nimport javax.management.ReflectionException;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.sampler.truffle.TruffleDataProvider;\nimport org.graalvm.visualvm.sampler.truffle.cpu.ThreadInfoProvider;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic final class MemoryHistogramProvider extends TruffleDataProvider {\n\n    public MemoryHistogramProvider(Application app) {\n        status = initialize(app);\n    }\n\n    private String initialize(Application application) {\n        String st = initJMXConn(application);\n\n        if (st != null) return st;\n        try {\n            if (!checkAndLoadJMX(application)) {\n                return NbBundle.getMessage(MemoryHistogramProvider.class, \"MSG_unavailable_threads\", VisualVM.getInstance().getLogfileHandle());\n            }\n            if (!tbean.isHeapHistogramEnabled()) {\n                return NbBundle.getMessage(MemoryHistogramProvider.class, \"MSG_unavailable_heaphisto\");\n            }\n        } catch (SecurityException e) {\n            LOGGER.log(Level.INFO, \"MemoryHistogramProvider.initialize() throws SecurityException for \" + application, e); // NOI18N\n            return NbBundle.getMessage(MemoryHistogramProvider.class, \"MSG_unavailable_threads\", VisualVM.getInstance().getLogfileHandle()); // NOI18N\n        } catch (Throwable t) {\n            LOGGER.log(Level.INFO, \"MemoryHistogramProvider.initialize() throws Throwable for \" + application, t); // NOI18N\n            return NbBundle.getMessage(ThreadInfoProvider.class, \"MSG_unavailable_threads\", VisualVM.getInstance().getLogfileHandle()); // NOI18N\n        }\n        return null;\n    }\n\n    Map<String, Object>[] heapHistogram() throws InstanceNotFoundException, MBeanException, ReflectionException, IOException {\n        return tbean.heapHistogram();\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/memory/MemorySamplerSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle.memory;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.lang.management.MemoryMXBean;\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.TimerTask;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.MBeanException;\nimport javax.management.ReflectionException;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.options.GlobalPreferences;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.lib.jfluid.results.memory.SampledMemoryResultsSnapshot;\nimport org.graalvm.visualvm.sampler.truffle.AbstractSamplerSupport;\nimport org.graalvm.visualvm.sampler.truffle.AbstractSamplerSupport.Refresher;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic abstract class MemorySamplerSupport extends AbstractSamplerSupport {\n    \n    private final Application application;\n    \n    private final MemoryHistogramProvider histogramProvider;\n    private final MemoryMXBean memoryBean;\n    private final HeapDumper heapDumper;\n    private final SnapshotDumper snapshotDumper;\n    \n    private java.util.Timer processor;\n    private final AtomicBoolean updateIsRunning;\n    \n    private Timer heapTimer;\n    private Refresher heapRefresher;\n    private MemoryView heapView;\n\n    private DataViewComponent.DetailsView[] detailsViews;\n    \n    public MemorySamplerSupport(Application application, MemoryHistogramProvider mhp, MemoryMXBean memoryBean, SnapshotDumper snapshotDumper, HeapDumper heapDumper) {\n        this.application = application;\n        histogramProvider = mhp;\n        this.memoryBean = memoryBean;\n        this.heapDumper = heapDumper;\n        this.snapshotDumper = snapshotDumper;\n        updateIsRunning = new AtomicBoolean();\n    }\n    \n    \n    public DataViewComponent.DetailsView[] getDetailsView() {\n        if (detailsViews == null) {\n            initialize();\n            detailsViews = createViews();\n        }\n        heapView.initSession();\n        return detailsViews.clone();\n    }\n    \n    public boolean startSampling(ProfilingSettings settings, int samplingRate, int refreshRate) {\n//        heapTimer.start();\n//        permgenTimer.start();\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (heapView != null) heapView.starting();\n            }\n        });\n\n        heapRefresher.setRefreshRate(samplingRate);\n        if (heapView != null) {\n            doRefreshImpl(heapTimer, heapView);\n        }\n        return true;\n    }\n    \n    public synchronized void stopSampling() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (heapView != null) heapView.stopping();\n            }\n        });\n        \n        heapTimer.stop();\n        if (heapView != null) {\n            doRefreshImplImpl(snapshotDumper.lastHistogram, heapView);\n        }\n    }\n    \n    public synchronized void terminate() {\n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() {\n                if (heapView != null) heapView.terminated();\n            }\n        });\n    }\n    \n    \n    private String initialize() {\n        int defaultRefresh = GlobalPreferences.sharedInstance().getMonitoredDataPoll() * 1000;\n        \n        processor = getTimer();\n        \n        heapTimer = new Timer(defaultRefresh, new ActionListener() {\n            public void actionPerformed(ActionEvent e) {\n                heapRefresher.refresh();\n            }\n        });\n        heapRefresher = new Refresher() {\n            public final boolean checkRefresh() {\n                if (!heapTimer.isRunning()) return false;\n                return heapView.isShowing();\n            }\n            public final void doRefresh() {\n                if (heapView.isShowing()) {\n                    doRefreshImpl(heapTimer, heapView);\n                }\n            }\n            public final void setRefreshRate(int refreshRate) {\n                heapTimer.setDelay(refreshRate);\n                heapTimer.setInitialDelay(refreshRate);\n                heapTimer.restart();\n            }\n            public final int getRefreshRate() {\n                return heapTimer.getDelay();\n            }\n        };\n        return null;\n    }\n    \n    private DataViewComponent.DetailsView[] createViews() {\n        int detailIndex = 0;\n        int detailsCount = 1;\n        DataViewComponent.DetailsView[] details = new DataViewComponent.DetailsView[detailsCount];\n        \n        heapView = new MemoryView(application, heapRefresher, memoryBean, snapshotDumper, heapDumper);\n        details[detailIndex++] = new DataViewComponent.DetailsView(\n                    NbBundle.getMessage(MemorySamplerSupport.class, \"LBL_Heap_histogram\"), // NOI18N\n                    null, 10, heapView, null);\n        return details;\n    }\n    \n    private void doRefreshImpl(final Timer timer, final MemoryView... views) {\n        if (!timer.isRunning() || (views.length == 1 && views[0].isPaused())) return;\n        if (!updateIsRunning.compareAndSet(false, true)) return;\n        try {\n            processor.schedule(new TimerTask() {\n                public void run() {\n                    try {\n                        if (!timer.isRunning()) return;\n                        doRefreshImplImpl(takeHeapHistogram(), views);\n                    } catch (Exception e) {\n                        if (application.getState() == Stateful.STATE_AVAILABLE) {\n                            e.printStackTrace();\n                        }\n                        terminate();\n                    } finally {\n                        updateIsRunning.set(false);\n                    }\n                }\n            }, 0);\n        } catch (Exception e) {\n            terminate();\n        }\n    }\n\n    private TruffleHeapHistogram takeHeapHistogram() throws InstanceNotFoundException, MBeanException, ReflectionException, IOException {\n        Map<String, Object>[] histo = histogramProvider.heapHistogram();\n\n        return new TruffleHeapHistogram(histo);\n    }\n\n    private void doRefreshImplImpl(final TruffleHeapHistogram heapHistogram, final MemoryView... views) {\n        if (heapHistogram != null)\n            SwingUtilities.invokeLater(new Runnable() {\n                public void run() {\n                    snapshotDumper.lastHistogram = heapHistogram;\n                    for (MemoryView view : views) view.refresh(heapHistogram);\n                }\n            });\n    }\n\n    public static abstract class HeapDumper {\n        public abstract void takeHeapDump(boolean openView);\n    }\n    \n    public static abstract class SnapshotDumper {\n        private volatile TruffleHeapHistogram lastHistogram;\n        \n        public abstract void takeSnapshot(boolean openView);\n        \n        public SampledMemoryResultsSnapshot createSnapshot(long time) {\n            HeapHistogram histogram = lastHistogram;\n\n            if (histogram != null) {\n                ByteArrayOutputStream output = new ByteArrayOutputStream(1024);\n                DataOutputStream dos = new DataOutputStream(output);\n                try {\n                    SampledMemoryResultsSnapshot result = new SampledMemoryResultsSnapshot();\n                    Set<HeapHistogram.ClassInfo> classes = histogram.getHeapHistogram();\n                    \n                    dos.writeInt(1);    // version\n                    dos.writeLong(histogram.getTime().getTime()); // begin time\n                    dos.writeLong(time); // taken time\n                    dos.writeInt(classes.size());   // no of classes\n                    for (HeapHistogram.ClassInfo info : classes) {\n                        dos.writeUTF(info.getName());       // name\n                        dos.writeLong(info.getBytes());     // total number of bytes\n                    }\n                    dos.writeBoolean(false); // no stacktraces\n                    dos.writeInt(classes.size());   // no of classes\n                    for (HeapHistogram.ClassInfo info : classes) {\n                        dos.writeInt((int)info.getInstancesCount());     // number of instances\n                    }\n                    dos.close();\n                    result.readFromStream(new DataInputStream(new ByteArrayInputStream(output.toByteArray())));\n                    return result;\n                } catch (IOException ex) {\n                    ex.printStackTrace();\n                }\n            }\n            return null;\n        }\n    }\n\n    static class TruffleHeapHistogram extends HeapHistogram {\n\n        private long totalInstances;\n        private long totalBytes;\n        private long totalAllocInstances;\n        private long totalAllocBytes;\n        private final long time;\n        private final Set<TruffleClassInfo> classes;\n\n        private TruffleHeapHistogram(Map<String, Object>[] heap) {\n            time = System.currentTimeMillis();\n            classes = new HashSet<>(heap.length);\n            for (Map<String, Object> classInfo : heap) {\n                TruffleClassInfo info = new TruffleClassInfo(classInfo);\n\n                totalInstances += info.getInstancesCount();\n                totalBytes += info.getBytes();\n                totalAllocInstances += info.getAllocatedInstances();\n                totalAllocBytes += info.getAllocatedBytes();\n                classes.add(info);\n            }\n        }\n\n        @Override\n        public Date getTime() {\n            return new Date(time);\n        }\n\n        @Override\n        public long getTotalInstances() {\n            return totalInstances;\n        }\n\n        @Override\n        public long getTotalBytes() {\n            return totalBytes;\n        }\n\n        public long getTotalAllocInstances() {\n            return totalAllocInstances;\n        }\n\n        public long getTotalAllocBytes() {\n            return totalAllocBytes;\n        }\n\n        @Override\n        public Set<ClassInfo> getHeapHistogram() {\n            return Collections.unmodifiableSet(classes);\n        }\n\n        @Override\n        public long getTotalHeapInstances() {\n            return totalInstances;\n        }\n\n        @Override\n        public long getTotalHeapBytes() {\n            return totalBytes;\n        }\n\n        @Override\n        public Set<ClassInfo> getPermGenHistogram() {\n            return null;\n        }\n\n        @Override\n        public long getTotalPerGenInstances() {\n            return 0;\n        }\n\n        @Override\n        public long getTotalPermGenHeapBytes() {\n            return 0;\n        }\n    }\n\n    static class TruffleClassInfo extends HeapHistogram.ClassInfo {\n\n        String name;\n        long allocatedInstances;\n        long liveInstances;\n        long bytes;\n        long liveBytes;\n\n        TruffleClassInfo() {\n        }\n\n        private TruffleClassInfo(Map<String, Object> info) {\n            name = info.get(\"language\") + \".\" + info.get(\"name\");\n            allocatedInstances = (Long) info.get(\"allocatedInstancesCount\");\n            bytes = (Long) info.get(\"bytes\");\n            liveInstances = (Long) info.get(\"liveInstancesCount\");\n            liveBytes = (Long) info.get(\"liveBytes\");\n        }\n\n        @Override\n        public String getName() {\n            return name;\n        }\n\n        @Override\n        public long getInstancesCount() {\n            return liveInstances;\n        }\n\n        @Override\n        public long getBytes() {\n            return liveBytes;\n        }\n\n        public long getAllocatedInstances() {\n            return allocatedInstances;\n        }\n\n        public long getAllocatedBytes() {\n            return bytes;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/memory/MemorySettingsSupport.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle.memory;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport org.graalvm.visualvm.lib.common.ProfilingSettings;\nimport org.graalvm.visualvm.profiling.presets.PresetSelector;\nimport org.graalvm.visualvm.profiling.presets.SamplerMemoryPanel;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class MemorySettingsSupport {\n    \n    private JPanel container;\n    private SamplerMemoryPanel panel;\n    private PresetSelector selector;\n    \n    private DataViewComponent.DetailsView detailsView;\n    \n    \n    public DataViewComponent.DetailsView getDetailsView() {\n        if (detailsView == null) {\n            detailsView = new DataViewComponent.DetailsView(NbBundle.getMessage(\n                          MemorySettingsSupport.class, \"LBL_Memory_settings\"), null, 20, // NOI18N\n                          new ScrollableContainer(createPanel()), null);\n        }\n        return detailsView;\n    }\n    \n    \n    public ProfilingSettings getSettings() { return panel.getSettings(); }\n\n    public int getSamplingRate() { return panel.getSamplingRate(); }\n    \n    public int getRefreshRate() { return panel.getRefreshRate(); }\n    \n    public void saveSettings() {\n        // NOTE: might save custom configuration here\n    }\n    \n    public abstract boolean presetValid();\n    \n    public boolean settingsValid() { return panel.settingsValid(); }\n    \n    public void showSettings(DataViewComponent dvc) {\n        dvc.selectDetailsView(getDetailsView());\n    }\n    \n    public abstract PresetSelector createSelector(Runnable presetSynchronizer);\n    \n    \n    public void setEnabled(boolean enabled) {\n        if (container != null) container.setEnabled(enabled);\n    }\n    \n    private JPanel createPanel() {\n        panel = new SamplerMemoryPanel() {\n            public void settingsChanged() {\n                panel.saveToPreset(selector.customize(presetValid()));\n            }\n        };\n        \n        selector = createSelector(new Runnable() {\n            public void run() { panel.loadFromPreset(selector.getSelectedPreset()); }\n        });\n        selector.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));\n        \n        container = new JPanel(new BorderLayout()) {\n            public void setEnabled(boolean enabled) {\n                super.setEnabled(enabled);\n                for (Component c : getComponents()) c.setEnabled(enabled);\n            }\n        };\n        container.setOpaque(false);\n        container.add(panel, BorderLayout.CENTER);\n        container.add(selector, BorderLayout.SOUTH);\n        \n        return container;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/memory/MemoryView.java",
    "content": "/*\n * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.sampler.truffle.memory;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.LayoutManager;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.ItemEvent;\nimport java.lang.management.MemoryMXBean;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport javax.swing.AbstractAction;\nimport javax.swing.AbstractButton;\nimport javax.swing.Action;\nimport javax.swing.ActionMap;\nimport javax.swing.Icon;\nimport javax.swing.ImageIcon;\nimport javax.swing.InputMap;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JToggleButton;\nimport javax.swing.SortOrder;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.table.AbstractTableModel;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram.ClassInfo;\nimport org.graalvm.visualvm.lib.jfluid.utils.Wildcards;\nimport org.graalvm.visualvm.lib.profiler.api.ActionsSupport;\nimport org.graalvm.visualvm.lib.profiler.api.GoToSource;\nimport org.graalvm.visualvm.lib.profiler.api.icons.GeneralIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.Icons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.LanguageIcons;\nimport org.graalvm.visualvm.lib.profiler.api.icons.ProfilerIcons;\nimport org.graalvm.visualvm.lib.ui.Formatters;\nimport org.graalvm.visualvm.lib.ui.components.ProfilerToolbar;\nimport org.graalvm.visualvm.lib.ui.swing.FilterUtils;\nimport org.graalvm.visualvm.lib.ui.swing.GrayLabel;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTable;\nimport org.graalvm.visualvm.lib.ui.swing.ProfilerTableContainer;\nimport org.graalvm.visualvm.lib.ui.swing.SearchUtils;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.HideableBarRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.JavaNameRenderer;\nimport org.graalvm.visualvm.lib.ui.swing.renderer.NumberPercentRenderer;\nimport org.graalvm.visualvm.profiling.actions.ProfiledSourceSelection;\nimport org.graalvm.visualvm.profiling.actions.ProfilerPopupCustomizer;\nimport org.graalvm.visualvm.sampler.truffle.AbstractSamplerSupport;\nimport org.graalvm.visualvm.sampler.truffle.memory.MemorySamplerSupport.TruffleClassInfo;\nimport org.graalvm.visualvm.sampler.truffle.memory.MemorySamplerSupport.TruffleHeapHistogram;\nimport org.openide.util.Exceptions;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.Lookup;\nimport org.openide.util.NbBundle;\nimport org.openide.util.RequestProcessor;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nfinal class MemoryView extends JPanel {\n\n    private final AbstractSamplerSupport.Refresher refresher;\n    private boolean forceRefresh = false;\n    \n    private final MemoryMXBean memoryBean;\n    private final MemorySamplerSupport.HeapDumper heapDumper;\n    private final MemorySamplerSupport.SnapshotDumper snapshotDumper;\n    \n    private List<TruffleClassInfo> classes = new ArrayList<>();\n    private List<TruffleClassInfo> baseClasses = new ArrayList<>(); // Needed to correctly setup table renderers\n    private long totalBytes, baseTotalBytes = -1;\n    private long totalInstances, baseTotalInstances = -1;\n    private long totalAllocBytes, baseTotalAllocBytes = -1;\n    private long totalAllocInstances, baseTotalAllocInstances = -1;\n\n\n    MemoryView(Application application, AbstractSamplerSupport.Refresher refresher,\n               MemoryMXBean memoryBean, MemorySamplerSupport.SnapshotDumper snapshotDumper,\n               MemorySamplerSupport.HeapDumper heapDumper) {\n\n        this.refresher = refresher;\n\n        this.memoryBean = memoryBean;\n        this.snapshotDumper = snapshotDumper;\n        this.heapDumper = heapDumper;\n        \n        initComponents(application);\n\n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (isShowing()) MemoryView.this.refresher.refresh();\n                }\n            }\n        });\n    }\n\n\n    void initSession() {\n        if (pdSnapshotButton != null) pdSnapshotButton.setEnabled(false);\n    }\n\n    boolean isPaused() {\n        return lrPauseButton.isSelected() && !forceRefresh;\n    }\n    \n    boolean isEmpty() {\n        return tableModel.getRowCount() == 0;\n    }\n    \n    void refresh(TruffleHeapHistogram histogram) {\n        if (histogram == null || isPaused()) return;\n        forceRefresh = false;\n        \n        boolean diff = lrDeltasButton.isSelected();\n        if (diff) {\n            if (baseClasses == null) {\n                baseClasses = new ArrayList<>(classes);\n                baseTotalBytes = totalBytes;\n                baseTotalInstances = totalInstances;\n                baseTotalAllocBytes = totalAllocBytes;\n                baseTotalAllocInstances = totalAllocInstances;\n            }\n\n            Collection<TruffleClassInfo> newClasses = getHistogram(histogram);\n            classes = computeDeltaClasses(baseClasses, newClasses);\n\n            totalBytes = histogram.getTotalBytes() - baseTotalBytes;\n            totalInstances = histogram.getTotalInstances() - baseTotalInstances;\n            totalAllocBytes = histogram.getTotalAllocBytes() - baseTotalAllocBytes;\n            totalAllocInstances = histogram.getTotalAllocInstances() - baseTotalAllocInstances;\n\n            long maxAbsDiffBytes = 0;\n            for (ClassInfo cInfo : classes)\n                maxAbsDiffBytes = Math.max(maxAbsDiffBytes, Math.abs(cInfo.getBytes()));\n            \n        } else {\n            if (baseClasses != null) {\n                baseClasses = null;\n                baseTotalBytes = -1;\n                baseTotalInstances = -1;\n            }\n            classes.clear();\n            classes.addAll(getHistogram(histogram));\n\n            totalBytes = histogram.getTotalBytes();\n            totalInstances = histogram.getTotalInstances();\n            totalAllocBytes = histogram.getTotalAllocBytes();\n            totalAllocInstances = histogram.getTotalAllocInstances();\n        }\n        \n        renderers[0].setDiffMode(diff);\n        renderers[0].setMaxValue(totalBytes);\n        \n        renderers[1].setDiffMode(diff);\n        renderers[1].setMaxValue(totalInstances);\n\n        renderers[2].setDiffMode(diff);\n        renderers[2].setMaxValue(totalAllocBytes);\n\n        renderers[3].setDiffMode(diff);\n        renderers[3].setMaxValue(totalAllocInstances);\n\n        tableModel.fireTableDataChanged();\n\n        if (pdSnapshotButton != null) pdSnapshotButton.setEnabled(true);\n    }\n\n    void starting() {\n        lrPauseButton.setEnabled(true);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(true);\n    }\n    \n    void stopping() {\n        lrPauseButton.setEnabled(false);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(false);\n    }\n    \n    void terminated() {\n        lrPauseButton.setEnabled(false);\n        lrRefreshButton.setEnabled(false);\n        lrDeltasButton.setEnabled(false);\n        gcButton.setEnabled(false);\n        heapdumpButton.setEnabled(false);\n    }\n\n    private Collection getHistogram(TruffleHeapHistogram histogram) {\n        return histogram.getHeapHistogram();\n    }\n\n    private static List<TruffleClassInfo> computeDeltaClasses(Collection<TruffleClassInfo> basis, Collection<TruffleClassInfo> changed) {\n\n        Map<String, DeltaClassInfo> deltaMap = new HashMap<>((int)(basis.size() * 1.3));\n\n        for (TruffleClassInfo cInfo : basis)\n            deltaMap.put(cInfo.getName(), new DeltaClassInfo(cInfo, true));\n\n        for (TruffleClassInfo cInfo : changed) {\n            DeltaClassInfo bInfo = deltaMap.get(cInfo.getName());\n            if (bInfo != null) bInfo.add(cInfo);\n            else deltaMap.put(cInfo.getName(), new DeltaClassInfo(cInfo, false));\n        }\n\n        return new ArrayList<>(deltaMap.values());\n    }\n    \n    \n    private JLabel lrLabel;\n    private JToggleButton lrPauseButton;\n    private JButton lrRefreshButton;\n    private JToggleButton lrDeltasButton;\n    \n    private JLabel pdLabel;\n    private JButton pdSnapshotButton;\n    \n    private AbstractButton gcButton;\n    private AbstractButton heapdumpButton;\n    \n    private boolean popupPause;\n    \n    private JComponent bottomPanel;\n    private JComponent filterPanel;\n    private JComponent searchPanel;\n    \n    private HistogramTableModel tableModel;\n    private ProfilerTable table;\n    \n    private HideableBarRenderer[] renderers;\n    \n    private void initComponents(final Application application) {\n        tableModel = new HistogramTableModel();\n        \n        table = new ProfilerTable(tableModel, true, true, null) {\n\n            protected void populatePopup(JPopupMenu popup, Object value, Object userValue) {\n                final String selectedClass = value == null ? null : value.toString();\n                \n                if (GoToSource.isAvailable()) {\n                    popup.add(new JMenuItem(NbBundle.getMessage(MemoryView.class, \"MemoryView_Context_GoToSource\")) { // NOI18N\n                        { setEnabled(selectedClass != null); setFont(getFont().deriveFont(Font.BOLD)); }\n                        protected void fireActionPerformed(ActionEvent e) { GoToSource.openSource(null, selectedClass, null, null); }\n                    });\n                    popup.addSeparator();\n                }\n                \n                if (snapshotDumper != null && selectedClass != null) {\n                    JMenuItem[] customItems = createCustomMenuItems(application, selectedClass);\n                    if (customItems != null) {\n                        for (JMenuItem customItem : customItems) popup.add(customItem);\n                        popup.addSeparator();\n                    }\n                }\n                \n                popup.add(createCopyMenuItem());\n                popup.addSeparator();\n                \n                popup.add(new JMenuItem(FilterUtils.ACTION_FILTER) {\n                    protected void fireActionPerformed(ActionEvent e) { MemoryView.this.activateFilter(); }\n                });\n                popup.add(new JMenuItem(SearchUtils.ACTION_FIND) {\n                    protected void fireActionPerformed(ActionEvent e) { MemoryView.this.activateSearch(); }\n                });\n            }\n            protected void popupShowing() {\n                if (lrPauseButton.isEnabled() && !lrRefreshButton.isEnabled()) {\n                    popupPause = true;\n                    lrPauseButton.setSelected(true);\n                }\n            }\n            protected void popupHidden() {\n                if (lrPauseButton.isEnabled() && popupPause) {\n                    popupPause = false;\n                    lrPauseButton.setSelected(false);\n                }\n            }\n        };\n        \n        table.setColumnToolTips(new String[] { NbBundle.getMessage(MemoryView.class, \"MemoryView_TOOLTIP_Col_name\"), // NOI18N\n                                               NbBundle.getMessage(MemoryView.class, \"MemoryView_TOOLTIP_Col_size\"), // NOI18N\n                                               NbBundle.getMessage(MemoryView.class, \"MemoryView_TOOLTIP_Col_count\") // NOI18N\n                                });\n        \n        table.providePopupMenu(true);\n        \n        table.setMainColumn(0);\n        table.setFitWidthColumn(0);\n        \n        table.setColumnVisibility(1, false);\n        table.setColumnVisibility(3, false);\n        \n        table.setSortColumn(2);\n        table.setDefaultSortOrder(0, SortOrder.ASCENDING);\n        \n        renderers = new HideableBarRenderer[4];\n        renderers[0] = new HideableBarRenderer(new NumberPercentRenderer(Formatters.bytesFormat()));\n        renderers[1] = new HideableBarRenderer(new NumberPercentRenderer());\n        renderers[2] = new HideableBarRenderer(new NumberPercentRenderer(Formatters.bytesFormat()));\n        renderers[3] = new HideableBarRenderer(new NumberPercentRenderer());\n        \n        renderers[0].setMaxValue(123456789);\n        renderers[1].setMaxValue(12345678);\n        renderers[2].setMaxValue(123456789);\n        renderers[3].setMaxValue(12345678);\n        \n        table.setColumnRenderer(0, new JavaNameRenderer(Icons.getIcon(LanguageIcons.PACKAGE)));\n        table.setColumnRenderer(1, renderers[0]);\n        table.setColumnRenderer(2, renderers[1]);\n        table.setColumnRenderer(3, renderers[2]);\n        table.setColumnRenderer(4, renderers[3]);\n        \n        table.setDefaultColumnWidth(1, renderers[0].getOptimalWidth());\n        table.setDefaultColumnWidth(2, renderers[1].getMaxNoBarWidth());\n        table.setDefaultColumnWidth(3, renderers[2].getOptimalWidth());\n        table.setDefaultColumnWidth(4, renderers[3].getMaxNoBarWidth());\n        \n        ProfilerTableContainer tableContainer = new ProfilerTableContainer(table, false, null);\n        \n        InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);\n        ActionMap actionMap = getActionMap();\n        \n        final String filterKey = FilterUtils.FILTER_ACTION_KEY;\n        Action filterAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                MemoryView.this.activateFilter();\n            }\n        };\n        ActionsSupport.registerAction(filterKey, filterAction, actionMap, inputMap);\n        \n        final String findKey = SearchUtils.FIND_ACTION_KEY;\n        Action findAction = new AbstractAction() {\n            public void actionPerformed(ActionEvent e) {\n                MemoryView.this.activateSearch();\n            }\n        };\n        ActionsSupport.registerAction(findKey, findAction, actionMap, inputMap);\n        \n        SwingUtilities.invokeLater(new Runnable() {\n            public void run() { SearchUtils.enableSearchActions(table); }\n        });\n        \n        \n        // --- Toolbar ---------------------------------------------------------\n        \n        lrLabel = new GrayLabel(NbBundle.getMessage(MemoryView.class, \"MemoryView_LBL_Results\")); // NOI18N\n            \n        lrPauseButton = new JToggleButton(Icons.getIcon(GeneralIcons.PAUSE)) {\n            protected void fireItemStateChanged(ItemEvent event) {\n                boolean paused = isSelected();\n                lrRefreshButton.setEnabled(paused && !popupPause);\n                if (!paused) refresher.refresh();\n            }\n        };\n        lrPauseButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_Pause_results\")); // NOI18N\n\n        lrRefreshButton = new JButton(Icons.getIcon(GeneralIcons.UPDATE_NOW)) {\n            protected void fireActionPerformed(ActionEvent e) {\n                forceRefresh = true;\n                refresher.refresh();\n            }\n        };\n        lrRefreshButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_Update_results\")); // NOI18N\n        lrRefreshButton.setEnabled(false);\n        \n        Icon icon = Icons.getIcon(ProfilerIcons.DELTA_RESULTS);\n        lrDeltasButton = new JToggleButton(icon) {\n            protected void fireActionPerformed(ActionEvent e) {\n                if (!lrPauseButton.isSelected()) {\n                    forceRefresh = true;\n                    refresher.refresh();\n                }\n            }\n        };\n        lrDeltasButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_Deltas\")); // NOI18N\n        \n        if (snapshotDumper != null) {\n            pdLabel = new GrayLabel(NbBundle.getMessage(MemoryView.class, \"MemoryView_LBL_Data\")); // NOI18N\n            \n            pdSnapshotButton = new JButton(NbBundle.getMessage(MemoryView.class,\n                        \"LBL_Snapshot\"), new ImageIcon(ImageUtilities.loadImage( // NOI18N\n                        \"org/graalvm/visualvm/sampler/resources/snapshot.png\", true))) { // NOI18N\n                protected void fireActionPerformed(ActionEvent event) {\n                    snapshotDumper.takeSnapshot((event.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n                }\n            };\n            pdSnapshotButton.setText(NbBundle.getMessage(MemoryView.class, \"MemoryView_LBL_Snapshot\")); // NOI18N\n            pdSnapshotButton.putClientProperty(\"JComponent.sizeVariant\", \"regular\"); // NOI18N\n        }\n        \n        ProfilerToolbar toolbar = ProfilerToolbar.create(true);\n\n        toolbar.addSpace(5);\n\n        toolbar.add(lrLabel);\n        toolbar.addSpace(2);\n        toolbar.add(lrPauseButton);\n        toolbar.add(lrRefreshButton);\n        \n        toolbar.addSpace(5);\n        toolbar.add(lrDeltasButton);\n        \n        if (pdSnapshotButton != null) {\n        \n            toolbar.addSpace(2);\n            toolbar.addSeparator();\n            toolbar.addSpace(5);\n\n            toolbar.add(pdLabel);\n            toolbar.addSpace(2);\n            toolbar.add(pdSnapshotButton);\n        \n        }\n        \n        toolbar.addFiller();\n        \n        gcButton = new JButton(NbBundle.getMessage(MemoryView.class, \"LBL_Gc\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent event) {\n                new RequestProcessor(\"GC Processor\").post(new Runnable() { // NOI18N\n                    public void run() {\n                        try { memoryBean.gc(); } catch (Exception e) {\n                            setEnabled(false);\n                            Exceptions.printStackTrace(e);\n                        }\n                    };\n                });\n            }\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.width += 5;\n                return dim;\n            }\n        };\n        gcButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_Gc\")); // NOI18N\n        gcButton.setOpaque(false);\n        gcButton.setEnabled(memoryBean != null);\n        toolbar.add(gcButton);\n        \n        heapdumpButton = new JButton(NbBundle.getMessage(MemoryView.class, \"LBL_HeapDump\")) { // NOI18N\n            protected void fireActionPerformed(ActionEvent event) {\n                heapDumper.takeHeapDump((event.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n            }\n            public Dimension getPreferredSize() {\n                Dimension dim = super.getPreferredSize();\n                dim.width += 5;\n                return dim;\n            }\n        };\n        heapdumpButton.setToolTipText(NbBundle.getMessage(MemoryView.class, \"TOOLTIP_HeapDump\")); // NOI18N\n        heapdumpButton.setOpaque(false);\n        heapdumpButton.setEnabled(heapDumper != null);\n        toolbar.add(heapdumpButton);\n        \n        \n        setOpaque(false);\n        setLayout(new BorderLayout());\n        add(toolbar.getComponent(), BorderLayout.NORTH);\n        add(tableContainer, BorderLayout.CENTER);\n    }\n    \n    private JComponent getBottomPanel() {\n        if (bottomPanel == null) {\n            bottomPanel = new JPanel(new FilterFindLayout());\n            bottomPanel.setOpaque(true);\n            bottomPanel.setBackground(UIManager.getColor(\"controlShadow\")); // NOI18N\n            add(bottomPanel, BorderLayout.SOUTH);\n        }\n        return bottomPanel;\n    }\n    \n    private void activateFilter() {\n        JComponent panel = getBottomPanel();\n        \n        if (filterPanel == null) {\n            filterPanel = FilterUtils.createFilterPanel(table, null);\n            panel.add(filterPanel);\n            Container parent = panel.getParent();\n            parent.invalidate();\n            parent.revalidate();\n            parent.repaint();\n        }\n        \n        panel.setVisible(true);\n        \n        filterPanel.setVisible(true);\n        filterPanel.requestFocusInWindow();\n    }\n    \n    private void activateSearch() {\n        JComponent panel = getBottomPanel();\n        \n        if (searchPanel == null) {\n            searchPanel = SearchUtils.createSearchPanel(table);\n            panel.add(searchPanel);\n            Container parent = panel.getParent();\n            parent.invalidate();\n            parent.revalidate();\n            parent.repaint();\n        }\n        \n        panel.setVisible(true);\n        \n        searchPanel.setVisible(true);\n        searchPanel.requestFocusInWindow();\n    }\n    \n    private JMenuItem[] createCustomMenuItems(Application application, String className) {\n        Collection<? extends ProfilerPopupCustomizer> customizers = Lookup.getDefault().lookupAll(ProfilerPopupCustomizer.class);\n        if (customizers.isEmpty()) return null;\n        \n        ProfiledSourceSelection pss = new ProfiledSourceSelection(application, className, Wildcards.ALLWILDCARD, null);\n        \n        List<JMenuItem> menuItems = new ArrayList<>(customizers.size());\n        \n        for (ProfilerPopupCustomizer customizer : customizers) {\n            if (customizer.supportsDataView(ProfilerPopupCustomizer.View.MEMORY, ProfilerPopupCustomizer.Mode.LIVE)) {\n                JMenuItem[] items = customizer.getMenuItems(pss, ProfilerPopupCustomizer.View.MEMORY, ProfilerPopupCustomizer.Mode.LIVE);\n                if (items != null) Collections.addAll(menuItems, items);\n            }\n        }\n        \n        return menuItems.isEmpty() ? null : menuItems.toArray(new JMenuItem[0]);\n    }\n    \n    \n    private static final String COL_NAME = NbBundle.getMessage(MemoryView.class, \"COL_Class_name\"); // NOI18N\n    private static final String COL_BYTES = NbBundle.getMessage(MemoryView.class, \"COL_Bytes\"); // NOI18N\n    private static final String COL_INSTANCES = NbBundle.getMessage(MemoryView.class, \"COL_Instances\"); // NOI18N\n    private static final String COL_ALLOC_BYTES = NbBundle.getMessage(MemoryView.class, \"COL_ALLOC_Bytes\"); // NOI18N\n    private static final String COL_ALLOC_INSTANCES = NbBundle.getMessage(MemoryView.class, \"COL_ALLOC_Instances\"); // NOI18N\n    \n    private class HistogramTableModel extends AbstractTableModel {\n        \n        public String getColumnName(int columnIndex) {\n            if (columnIndex == 0) {\n                return COL_NAME;\n            } else if (columnIndex == 1) {\n                return COL_BYTES;\n            } else if (columnIndex == 2) {\n                return COL_INSTANCES;\n            } else if (columnIndex == 3) {\n                return COL_ALLOC_BYTES;\n            } else if (columnIndex == 4) {\n                return COL_ALLOC_INSTANCES;\n            }\n            \n            return null;\n        }\n\n        public Class<?> getColumnClass(int columnIndex) {\n            if (columnIndex == 0) {\n                return String.class;\n            } else {\n                return Long.class;\n            }\n        }\n\n        public int getRowCount() {\n            return classes.size();\n        }\n\n        public int getColumnCount() {\n            return 5;\n        }\n\n        public Object getValueAt(int rowIndex, int columnIndex) {\n            final TruffleClassInfo ci = classes.get(rowIndex);\n\n            if (columnIndex == 0) {\n                return ci.getName();\n            } else if (columnIndex == 1) {\n                return ci.getBytes();\n            } else if (columnIndex == 2) {\n                return ci.getInstancesCount();\n            } else if (columnIndex == 3) {\n                return ci.getAllocatedBytes();\n            } else if (columnIndex == 4) {\n                return ci.getAllocatedInstances();\n            }\n\n            return null;\n        }\n        \n    }\n    \n    \n    private final class FilterFindLayout implements LayoutManager {\n\n        public void addLayoutComponent(String name, Component comp) {}\n        public void removeLayoutComponent(Component comp) {}\n\n        public Dimension preferredLayoutSize(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            Dimension dim = new Dimension();\n            \n            if (filter != null && search != null) {\n                Dimension dim1 = filter.getPreferredSize();\n                Dimension dim2 = search.getPreferredSize();\n                dim.width = dim1.width + dim2.width + 1;\n                dim.height = Math.max(dim1.height, dim2.height);\n            } else if (filter != null) {\n                dim = filter.getPreferredSize();\n            } else if (search != null) {\n                dim = search.getPreferredSize();\n            }\n            \n            if ((filter != null || search != null) /*&& hasBottomFilterFindMargin()*/)\n                dim.height += 1;\n            \n            return dim;\n        }\n\n        public Dimension minimumLayoutSize(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            Dimension dim = new Dimension();\n            \n            if (filter != null && search != null) {\n                Dimension dim1 = filter.getMinimumSize();\n                Dimension dim2 = search.getMinimumSize();\n                dim.width = dim1.width + dim2.width + 1;\n                dim.height = Math.max(dim1.height, dim2.height);\n            } else if (filter != null) {\n                dim = filter.getMinimumSize();\n            } else if (search != null) {\n                dim = search.getMinimumSize();\n            }\n            \n            if ((filter != null || search != null) /*&& hasBottomFilterFindMargin()*/)\n                dim.height += 1;\n            \n            return dim;\n        }\n\n        public void layoutContainer(Container parent) {\n            JComponent filter = filterPanel;\n            if (filter != null && !filter.isVisible()) filter = null;\n            \n            JComponent search = searchPanel;\n            if (search != null && !search.isVisible()) search = null;\n            \n            int bottomOffset = /* hasBottomFilterFindMargin() ? 1 :*/ 0;\n            \n            if (filter != null && search != null) {\n                Dimension size = parent.getSize();\n                int w = (size.width - 1) / 2;\n                filter.setBounds(0, 0, w, size.height - bottomOffset);\n                search.setBounds(w + 1, 0, size.width - w - 1, size.height - bottomOffset);\n            } else if (filter != null) {\n                Dimension size = parent.getSize();\n                filter.setBounds(0, 0, size.width, size.height - bottomOffset);\n            } else if (search != null) {\n                Dimension size = parent.getSize();\n                search.setBounds(0, 0, size.width, size.height - bottomOffset);\n            }\n        }\n        \n    }\n    \n\n    private static class DeltaClassInfo extends TruffleClassInfo {\n\n        DeltaClassInfo(TruffleClassInfo cInfo, boolean negative) {\n            name = cInfo.getName();\n            liveInstances = negative ? -cInfo.getInstancesCount() : cInfo.getInstancesCount();\n            liveBytes = negative ? -cInfo.getBytes() : cInfo.getBytes();\n            allocatedInstances = negative ? -cInfo.getAllocatedInstances(): cInfo.getAllocatedInstances();\n            bytes = negative ? -cInfo.getAllocatedBytes(): cInfo.getAllocatedBytes();\n        }\n\n        void add(TruffleClassInfo cInfo) {\n            liveInstances += cInfo.getInstancesCount();\n            liveBytes += cInfo.getBytes();\n            allocatedInstances += cInfo.getAllocatedInstances();\n            bytes += cInfo.getAllocatedBytes();\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/sampler.truffle/src/org/graalvm/visualvm/sampler/truffle/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    \n    <folder name=\"Menu\">\n        <folder name=\"Applications\">\n            <file name=\"org-graalvm-visualvm-sampler-SampleApplicationAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-sampler-SampleApplicationAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1510\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"VisualVM\">\n        <folder name=\"Actions\">\n            <file name=\"org-graalvm-visualvm-sampler-SampleApplicationAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.sampler.SampleApplicationAction.instance\"/>\n            </file>\n        </folder>\n\n        <folder name=\"ExplorerPopupSelection\">\n            \n            <file name=\"org-graalvm-visualvm-sampler-SampleApplicationAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-sampler-SampleApplicationAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1010\"/>\n            </file>\n            \n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "visualvm/startup/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.modules.startup\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.modules.startup.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/startup/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.modules.startup/2\nOpenIDE-Module-Install: org/graalvm/visualvm/modules/startup/VisualVMStartup.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/modules/startup/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.1\n\n"
  },
  {
    "path": "visualvm/startup/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.modules.startup-impl\" basedir=\"..\" xmlns:nbmproject=\"http://www.netbeans.org/ns/nb-module-project/2\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\"/>\n    <nbmproject:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/startup/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=d68e7364\nbuild.xml.script.CRC32=fd228bc2\nbuild.xml.stylesheet.CRC32=79c3b980\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=d68e7364\nnbproject/build-impl.xml.script.CRC32=8a4e4c6c\nnbproject/build-impl.xml.stylesheet.CRC32=deb65f65\n"
  },
  {
    "path": "visualvm/startup/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\njavac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nmodule.jar.dir=core\n\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/startup/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/2\">\n            <code-name-base>org.graalvm.visualvm.modules.startup</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <friend-packages>\n                <friend>org.graalvm.visualvm.profiler</friend>\n                <package>org.graalvm.visualvm.modules.startup.dialogs</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/startup/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/startup/src/org/graalvm/visualvm/modules/startup/AcceptLicense.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.startup;\n\nimport org.graalvm.visualvm.modules.startup.dialogs.StartupDialog;\nimport java.awt.BorderLayout;\nimport java.awt.Dimension;\nimport java.awt.FlowLayout;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.net.URL;\nimport java.util.ResourceBundle;\nimport javax.swing.BorderFactory;\nimport javax.swing.JButton;\nimport javax.swing.JDialog;\nimport javax.swing.JPanel;\n\nimport org.openide.util.NbBundle;\nimport org.openide.util.UserCancelException;\n\n/**\n * Displays LicensePanel to user. User must accept license to continue. \n * if user does not accept license UserCancelException is thrown.\n *\n * @author  Marek Slama\n * @author Jiri Sedlacek\n */\npublic final class AcceptLicense {\n\n    private static final String YES_AC = \"yes\"; // NOI18N\n    private static final String NO_AC  = \"no\" ; // NOI18N\n    \n    private static JDialog d;\n    private static String command;\n    \n    /**\n     * If License was not accepted during installation user must accept it here.\n     */\n    public static void showLicensePanel() throws Exception {\n        Utils.setSystemLaF();\n\n        // Make sure the code following this call runs on JDK 6\n        if (!VisualVMStartup.checkEnv())\n            throw new org.openide.util.UserCancelException();\n\n        URL url = AcceptLicense.class.getResource(\"LICENSE.txt\"); // NOI18N\n        LicensePanel licensePanel = new LicensePanel(url);\n        ResourceBundle bundle = NbBundle.getBundle(AcceptLicense.class);\n        String yesLabel = bundle.getString(\"MSG_LicenseYesButton\"); // NOI18N\n        String noLabel = bundle.getString(\"MSG_LicenseNoButton\"); // NOI18N\n        JButton yesButton = new JButton();\n        JButton noButton = new JButton();\n        Utils.setLocalizedText(yesButton, yesLabel);\n        Utils.setLocalizedText(noButton, noLabel);\n        ActionListener listener = new ActionListener () {\n            public void actionPerformed(ActionEvent e) {\n                command = e.getActionCommand();\n                d.setVisible(false);\n                d.dispose();\n                d = null;\n            }            \n        };\n        yesButton.addActionListener(listener);\n        noButton.addActionListener(listener);\n        \n        yesButton.setActionCommand(YES_AC);\n        noButton.setActionCommand(NO_AC);\n        \n        yesButton.getAccessibleContext().setAccessibleName(bundle.getString(\"ACSN_AcceptButton\")); // NOI18N\n        yesButton.getAccessibleContext().setAccessibleName(bundle.getString(\"ACSD_AcceptButton\")); // NOI18N\n        \n        noButton.getAccessibleContext().setAccessibleName(bundle.getString(\"ACSN_RejectButton\")); // NOI18N\n        noButton.getAccessibleContext().setAccessibleName(bundle.getString(\"ACSD_RejectButton\")); // NOI18N\n        \n        Dimension yesPF = yesButton.getPreferredSize();\n        Dimension noPF = noButton.getPreferredSize();\n        int maxWidth = Math.max(yesPF.width, noPF.width);\n        int maxHeight = Math.max(yesPF.height, noPF.height);\n        yesButton.setPreferredSize(new Dimension(maxWidth, maxHeight));\n        noButton.setPreferredSize(new Dimension(maxWidth, maxHeight));\n\n        d = StartupDialog.create(bundle.getString(\"MSG_LicenseDlgTitle\"), null, -1); // NOI18N\n        \n        d.getAccessibleContext().setAccessibleName(bundle.getString(\"ACSN_LicenseDlg\")); // NOI18N\n        d.getAccessibleContext().setAccessibleDescription(bundle.getString(\"ACSD_LicenseDlg\")); // NOI18N\n        \n        d.getContentPane().add(licensePanel, BorderLayout.CENTER);\n        JPanel buttonPanel = new JPanel();\n        buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));\n        buttonPanel.setBorder(BorderFactory.createEmptyBorder(17, 12, 11, 11));\n        buttonPanel.add(yesButton);\n        buttonPanel.add(noButton);\n        d.getContentPane().add(buttonPanel, BorderLayout.SOUTH);\n        d.setSize(new Dimension(600, 600));\n        d.setResizable(true);\n        d.setLocationRelativeTo(null);\n        d.setVisible(true);\n        \n        if (!YES_AC.equals(command)) throw new UserCancelException();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/startup/src/org/graalvm/visualvm/modules/startup/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Startup\n\n#Licence dialog\nMSG_LicenseDlgTitle=VisualVM License Agreement\nMSG_LicenseDlgLabelTop=Please read the following license agreement carefully.\nMSG_LicenseDlgLabelBottom=If you accept all terms of the agreement, click I Accept \\\nto start VisualVM. You must accept the agreement to start VisualVM.\nMSG_LicenseYesButton=I &Accept\nMSG_LicenseNoButton=E&xit\n\nACSN_LicensePanel=License Panel\nACSD_LicensePanel=N/A\n\nACSN_LicenseDlg=License Dialog\nACSD_LicenseDlg=License Agreement\n\nACSN_EditorPane=License Text\nACSD_EditorPane=Please read the following license agreement carefully. \\\nIf you accept all terms of the agreement, click I Accept \\\nto start VisualVM. You must accept the agreement to start VisualVM.\n\nACSN_AcceptButton=Accept Button\nACSD_AcceptButton=Click to accept license and continue\n\nACSN_RejectButton=Reject Button\nACSD_RejectButton=Click to reject license and exit \nOpenIDE-Module-Short-Description=VisualVM startup Module\n\nVisualVMStartup_ErrorStartupCaption=Error Starting VisualVM\nVisualVMStartup_IncorrectVersionMsg=<html><br><b>You are running VisualVM using an unsupported Java version: {0}.</b><br><br>Please use JDK 8 to JDK 25 to run VisualVM. For information<br>about requirements and setup visit https://visualvm.github.io.<br><br><hr><i>Java: {1}<br>JVM: {2}<br>Location: {3}</i><br><br></html>\nVisualVMStartup_JreMsg=<html><br><b>You are running VisualVM using Java Runtime Environment (JRE).</b><br><br>Please use Java Development Kit (JDK) to run VisualVM. For information<br>about requirements and setup visit https://visualvm.github.io.<br><br><hr><i>Java: {0}<br>JVM: {1}<br>Location: {2}</i><br><br></html>\nVisualVMStartup_OpenJ9Msg=<html><br><b>You are running VisualVM using Eclipse OpenJ9.</b><br><br>Please use HotSpot based JDK to run VisualVM. You can still monitor OpenJ9 via JMX.<br>For information about requirements and setup visit https://visualvm.github.io.<br><br><hr><i>Java: {0}<br>JVM: {1}<br>Location: {2}</i><br><br></html>\n\nImportSettings_Caption=Import Settings\n\nImportPanel_Msg1=<nobr><b>Existing VisualVM settings are available on this system.</b></nobr><br><br><nobr>Select the settings directory to import:</nobr>\nImportPanel_Msg2=<nobr>Click <b>Import</b> to start VisualVM with the imported settings.</nobr><br><nobr>Click <b>Skip</b> to start VisualVM with the default settings.</nobr>\nImportPanel_OptionLatestRelease=(latest release)\nImportPanel_OptionRecentlyUsed=(recently used)\nImportPanel_OptionSelectCustom=select custom...\nImportPanel_OptionSelectCustom2=({0} and newer)\nImportPanel_OptionSelectCustomTooltip=Select custom settings directory after clicking the Import button\nImportPanel_ProgressText=Importing settings...\nImportPanel_ImportButton=Import\nImportPanel_SkipButton=Skip\nImportPanel_OpenButton=Open\nImportPanel_ImportButtonTooltip=Import selected settings directory\nImportPanel_OpenButtonTooltip=Open selected directory\nImportPanel_CustomDirCaption=Select Custom Settings Directory To Import\nImportPanel_SettingsFilter=VisualVM Settings Directory\nImportPanel_ImportFailed=Failed to import selected settings:\n"
  },
  {
    "path": "visualvm/startup/src/org/graalvm/visualvm/modules/startup/CopyFiles.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n//package org.netbeans.upgrade;\npackage org.graalvm.visualvm.modules.startup;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.OutputStream;\nimport java.io.Reader;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.LinkOption;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map.Entry;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n//import javax.swing.JDialog;\n//import javax.swing.JOptionPane;\n//import org.netbeans.util.Util;\n//import org.openide.filesystems.FileUtil;\nimport org.openide.util.EditableProperties;\n\n// Copied from org.netbeans.upgrade.CopyFiles\n// Modified to not display UI and use java.nio.file.Files.copy()\n/** Does copy of files according to include/exclude patterns.\n *\n * @author Jiri Skrivanek\n * @author Jiri Sedlacek\n */\nfinal class CopyFiles extends Object {\n\n    private File sourceRoot;\n    private File targetRoot;\n    private EditableProperties currentProperties;\n    private Set<String> includePatterns = new HashSet<>();\n    private Set<String> excludePatterns = new HashSet<>();\n    private HashMap<String, String> translatePatterns = new HashMap<>(); // <originalPath, newPath>\n    private static final Logger LOGGER = Logger.getLogger(CopyFiles.class.getName());\n\n    private CopyFiles(File source, File target, File patternsFile) throws IOException {\n        this.sourceRoot = source;\n        this.targetRoot = target;\n        try (InputStream is = new FileInputStream(patternsFile);\n             Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {\n            readPatterns(reader);\n        } catch (IOException ex) {\n            // set these to null to stop further copying (see copyDeep method)\n            sourceRoot = null;\n            targetRoot = null;\n            LOGGER.log(Level.WARNING, \"Import settings will not proceed: {0}\", ex.getMessage());\n//            // show error message and continue\n//            JDialog dialog = Util.createJOptionDialog(new JOptionPane(ex, JOptionPane.ERROR_MESSAGE), \"Import settings will not proceed\");\n//            dialog.setVisible(true);\n//            return;\n            throw ex;\n        }\n    }\n\n    public static void copyDeep(File source, File target, File patternsFile) throws IOException {\n        CopyFiles copyFiles = new CopyFiles(source, target, patternsFile);\n        if(copyFiles.sourceRoot == null && copyFiles.targetRoot == null) {\n            return; // IOException was thrown in CopyFiles constructor, probably netbeans.import could not be located\n        }\n        LOGGER.fine(\"Copying from: \" + copyFiles.sourceRoot + \"\\nto: \" + copyFiles.targetRoot);  //NOI18N\n        copyFiles.copyFolder(copyFiles.sourceRoot);\n    }\n\n    private void copyFolder(File sourceFolder) throws IOException {\n        File[] srcChildren = sourceFolder.listFiles();\n        if (srcChildren == null) {\n            LOGGER.info(sourceFolder + \" is not a directory or is invalid.\");  //NOI18N\n            return ;\n        }\n        for (File child : srcChildren) {\n            if (child.isDirectory()) {\n                copyFolder(child);\n            } else {\n                copyFile(child);\n            }\n        }\n    }\n\n    /** Returns slash separated path relative to given root. */\n    private static String getRelativePath(File root, File file) {\n        String result = file.getAbsolutePath().substring(root.getAbsolutePath().length());\n        result = result.replace('\\\\', '/');  //NOI18N\n        if (result.startsWith(\"/\") && !result.startsWith(\"//\")) {  //NOI18N\n            result = result.substring(1);\n        }\n        return result;\n    }\n\n    /** Copy source file to target file. It creates necessary sub folders.\n     * @param sourceFile source file\n     * @param targetFile target file\n     * @throws java.io.IOException if copying fails\n     */\n    private static void copyFile(File sourceFile, File targetFile) throws IOException {\n        ensureParent(targetFile);\n        Files.copy(sourceFile.toPath(), targetFile.toPath(), LinkOption.NOFOLLOW_LINKS);\n    }\n    \n\n    /** Copy given file to target root dir if matches include/exclude patterns.\n     * If properties pattern is applicable, it copies only matching keys.\n     * @param sourceFile source file\n     * @throws java.io.IOException if copying fails\n     */\n    private void copyFile(File sourceFile) throws IOException {\n        String relativePath = getRelativePath(sourceRoot, sourceFile);\n        currentProperties = null;\n        boolean includeFile = false;\n        Set<String> includeKeys = new HashSet<>();\n        Set<String> excludeKeys = new HashSet<>();\n        for (String pattern : includePatterns) {\n            if (pattern.contains(\"#\")) {  //NOI18N\n                includeKeys.addAll(matchingKeys(relativePath, pattern));\n            } else {\n                if (relativePath.matches(pattern)) {\n                    includeFile = true;\n                    includeKeys.clear();  // include entire file\n                    break;\n                }\n            }\n        }\n        if (includeFile || !includeKeys.isEmpty()) {\n            // check excludes\n            for (String pattern : excludePatterns) {\n                if (pattern.contains(\"#\")) {  //NOI18N\n                    excludeKeys.addAll(matchingKeys(relativePath, pattern));\n                } else {\n                    if (relativePath.matches(pattern)) {\n                        includeFile = false;\n                        includeKeys.clear();  // exclude entire file\n                        break;\n                    }\n                }\n            }\n        }\n        LOGGER.log(Level.FINEST, \"{0}, includeFile={1}, includeKeys={2}, excludeKeys={3}\", new Object[]{relativePath, includeFile, includeKeys, excludeKeys});  //NOI18N\n        if (!includeFile && includeKeys.isEmpty()) {\n            // nothing matches\n            return;\n        }\n        \n\tfor (Entry<String, String> entry : translatePatterns.entrySet()) {\n\t    if (relativePath.startsWith(entry.getKey())) {\n\t\tString value = entry.getValue();\n\t\tLOGGER.log(Level.INFO, \"Translating old relative path: {0}\", relativePath);  //NOI18N\n\t\trelativePath = value + relativePath.substring(entry.getKey().length());\n\t\tLOGGER.log(Level.INFO, \"                   to new one: {0}\", relativePath);  //NOI18N\n\t    }\n\t}\n\n        File targetFile = new File(targetRoot, relativePath);\n        LOGGER.log(Level.FINE, \"Path: {0}\", relativePath);  //NOI18N\n        if (includeKeys.isEmpty() && excludeKeys.isEmpty()) {\n            // copy entire file\n            copyFile(sourceFile, targetFile);\n        } else {\n            if (!includeKeys.isEmpty()) {\n                currentProperties.keySet().retainAll(includeKeys);\n            }\n            currentProperties.keySet().removeAll(excludeKeys);\n            // copy just selected keys\n            LOGGER.log(Level.FINE, \"  Only keys: {0}\", currentProperties.keySet());\n            ensureParent(targetFile);\n            try (OutputStream out = new FileOutputStream(targetFile)) {\n                currentProperties.store(out);\n            }\n        }\n    }\n\n    /** Returns set of keys matching given pattern.\n     * @param relativePath path relative to sourceRoot\n     * @param propertiesPattern pattern like file.properties#keyPattern\n     * @return set of matching keys, never null\n     * @throws IOException if properties cannot be loaded\n     */\n    private Set<String> matchingKeys(String relativePath, String propertiesPattern) throws IOException {\n        Set<String> matchingKeys = new HashSet<>();\n        String[] patterns = propertiesPattern.split(\"#\", 2);\n        String filePattern = patterns[0];\n        String keyPattern = patterns[1];\n        if (relativePath.matches(filePattern)) {\n            if (currentProperties == null) {\n                currentProperties = getProperties(relativePath);\n            }\n            for (String key : currentProperties.keySet()) {\n                if (key.matches(keyPattern)) {\n                    matchingKeys.add(key);\n                }\n            }\n        }\n        return matchingKeys;\n    }\n\n    /** Returns properties from relative path.\n     * @param relativePath relative path\n     * @return properties from relative path.\n     * @throws IOException if cannot open stream\n     */\n    private EditableProperties getProperties(String relativePath) throws IOException {\n        EditableProperties properties = new EditableProperties(false);\n        try (InputStream in = new FileInputStream(new File(sourceRoot, relativePath))) {\n            properties.load(in);\n        }\n        return properties;\n    }\n\n    /** Creates parent of given file, if doesn't exist. */\n    private static void ensureParent(File file) throws IOException {\n        final File parent = file.getParentFile();\n        if (parent != null && !parent.exists()) {\n            if (!parent.mkdirs()) {\n                throw new IOException(\"Cannot create folder: \" + parent.getAbsolutePath());  //NOI18N\n            }\n        }\n    }\n\n    /** Reads the include/exclude set from a given reader.\n     * @param r reader\n     */\n    private void readPatterns(Reader r) throws IOException {\n        BufferedReader buf = new BufferedReader(r);\n        for (;;) {\n            String line = buf.readLine();\n            if (line == null) {\n                break;\n            }\n            line = line.trim();\n            if (line.isEmpty() || line.startsWith(\"#\")) {  //NOI18N\n                continue;\n            }\n            if (line.startsWith(\"include \")) {  //NOI18N\n                line = line.substring(8);\n                if (!line.isEmpty()) {\n                    includePatterns.addAll(parsePattern(line));\n                }\n            } else if (line.startsWith(\"exclude \")) {  //NOI18N\n                line = line.substring(8);\n                if (!line.isEmpty()) {\n                    excludePatterns.addAll(parsePattern(line));\n                }\n            } else if (line.startsWith(\"translate \")) {  //NOI18N\n                line = line.substring(10);\n                if (!line.isEmpty()) {\n\t\t    String[] translations = line.split(\"\\\\|\");\n\t\t    for (String translation : translations) {\n\t\t\tString originalPath = translation.substring(0, translation.indexOf(\"=>\"));\n\t\t\tString newPath = translation.substring(translation.lastIndexOf(\"=>\") + 2);\n\t\t\tif (translatePatterns.containsKey(originalPath)) {\n\t\t\t    LOGGER.log(Level.INFO, \"Translation already exists: {0}. Ignoring new translation: {1}\",  //NOI18N\n\t\t\t\t    new Object[]{originalPath.concat(\"=>\").concat(translatePatterns.get(originalPath)),\n\t\t\t\t\toriginalPath.concat(\"=>\").concat(newPath)});\n\t\t\t} else {\n\t\t\t    translatePatterns.put(originalPath, newPath);\n\t\t\t}\n\t\t    }\n                }\n            } else {\n                throw new java.io.IOException(\"Wrong line: \" + line);  //NOI18N\n            }\n        }\n    }\n\n    enum ParserState {\n\n        START,\n        IN_KEY_PATTERN,\n        AFTER_KEY_PATTERN,\n        IN_BLOCK\n    }\n\n    /** Parses given compound string pattern into set of single patterns.\n     * @param pattern compound pattern in form filePattern1#keyPattern1#|filePattern2#keyPattern2#|filePattern3\n     * @return set of single patterns containing just one # (e.g. [filePattern1#keyPattern1, filePattern2#keyPattern2, filePattern3])\n     */\n    private static Set<String> parsePattern(String pattern) {\n        Set<String> patterns = new HashSet<>();\n        if (pattern.contains(\"#\")) {  //NOI18N\n            StringBuilder partPattern = new StringBuilder();\n            ParserState state = ParserState.START;\n            int blockLevel = 0;\n            for (int i = 0; i < pattern.length(); i++) {\n                char c = pattern.charAt(i);\n                switch (state) {\n                    case START:\n                        if (c == '#') {\n                            state = ParserState.IN_KEY_PATTERN;\n                            partPattern.append(c);\n                        } else if (c == '(') {\n                            state = ParserState.IN_BLOCK;\n                            blockLevel++;\n                            partPattern.append(c);\n                        } else if (c == '|') {\n                            patterns.add(partPattern.toString());\n                            partPattern = new StringBuilder();\n                        } else {\n                            partPattern.append(c);\n                        }\n                        break;\n                    case IN_KEY_PATTERN:\n                        if (c == '#') {\n                            state = ParserState.AFTER_KEY_PATTERN;\n                        } else {\n                            partPattern.append(c);\n                        }\n                        break;\n                    case AFTER_KEY_PATTERN:\n                        if (c == '|') {\n                            state = ParserState.START;\n                            patterns.add(partPattern.toString());\n                            partPattern = new StringBuilder();\n                        } else {\n                            assert false : \"Wrong OptionsExport pattern \" + pattern + \". Only format like filePattern1#keyPattern#|filePattern2 is supported.\";  //NOI18N\n                        }\n                        break;\n                    case IN_BLOCK:\n                        partPattern.append(c);\n                        if (c == ')') {\n                            blockLevel--;\n                            if (blockLevel == 0) {\n                                state = ParserState.START;\n                            }\n                        }\n                        break;\n                }\n            }\n            patterns.add(partPattern.toString());\n        } else {\n            patterns.add(pattern);\n        }\n        return patterns;\n    }\n}\n"
  },
  {
    "path": "visualvm/startup/src/org/graalvm/visualvm/modules/startup/ImportPanel.java",
    "content": "/*\n * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.modules.startup;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GridBagConstraints;\nimport java.awt.GridBagLayout;\nimport java.awt.Insets;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ItemEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.io.File;\nimport java.util.concurrent.ExecutionException;\nimport javax.swing.ButtonGroup;\nimport javax.swing.JButton;\nimport javax.swing.JComponent;\nimport javax.swing.JFileChooser;\nimport javax.swing.JPanel;\nimport javax.swing.JProgressBar;\nimport javax.swing.JRadioButton;\nimport javax.swing.JTextPane;\nimport javax.swing.SwingWorker;\nimport javax.swing.UIManager;\nimport javax.swing.filechooser.FileFilter;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nabstract class ImportPanel extends JPanel {\n    \n    private static final String KEY_FOLDER = \"settings_folder\";                 // NOI18N\n    \n    \n    private final JProgressBar progress;\n    private final JTextPane text2;\n    private final JButton importB;\n    private final JButton skipB;\n    private final JRadioButton latest;\n    private final JRadioButton recent;\n    private final JRadioButton custom;\n    \n    private File selected;\n    private File userdirsRoot;\n    \n    \n    ImportPanel(final File latestRelease, final File recentlyUsed, File userdirsRoot, final String firstSupported) {\n        super(new GridBagLayout());\n        \n        Color disabledText = UIManager.getLookAndFeel().getID().equals(\"GTK\") ? // NOI18N\n                             UIManager.getColor(\"Label.disabledShadow\") :       // NOI18N\n                             UIManager.getColor(\"Label.disabledForeground\");    // NOI18N\n        \n        GridBagConstraints c;\n        \n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 0;\n        c.insets = new Insets(25, 15, 10, 15);\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        JTextPane text1 = new JTextPane();\n        text1.setContentType(\"text/html\");                                      // NOI18N\n        text1.setFont(UIManager.getFont(\"Label.font\"));                         // NOI18N\n        text1.setOpaque(false);\n        text1.setEditable(false);\n        text1.setFocusable(false);\n        text1.setRequestFocusEnabled(false);\n        setHtmlText(text1, NbBundle.getMessage(ImportPanel.class, \"ImportPanel_Msg1\")); // NOI18N\n        add(text1, c);\n        \n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 1;\n        c.insets = new Insets(0, 25, 0, 15);\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        latest = new JRadioButton() {\n            protected void fireItemStateChanged(ItemEvent event) {\n                super.fireItemStateChanged(event);\n                if (event.getStateChange() == ItemEvent.SELECTED) {\n                    selected = latestRelease;\n                }\n            }\n        };\n        latest.setText(getHtmlText(latest, \"<nobr>\" + latestRelease.getName() + \" <span style=\\\"color:\" + getColorText(disabledText) + \";\\\">\" + // NOI18N\n                                           NbBundle.getMessage(ImportPanel.class, \"ImportPanel_OptionLatestRelease\") + \"</span>\" + \"</nobr>\")); // NOI18N\n        latest.putClientProperty(KEY_FOLDER, latestRelease);\n        latest.setSelected(true);\n        latest.setToolTipText(latestRelease.getAbsolutePath());\n        add(latest, c);\n        \n        if (recentlyUsed != null && !recentlyUsed.equals(latestRelease)) {\n            c = new GridBagConstraints();\n            c.gridx = 0;\n            c.gridy = 2;\n            c.insets = new Insets(0, 25, 0, 15);\n            c.anchor = GridBagConstraints.WEST;\n            c.fill = GridBagConstraints.NONE;\n            c.gridwidth = GridBagConstraints.REMAINDER;\n            recent = new JRadioButton() {\n                protected void fireItemStateChanged(ItemEvent event) {\n                    super.fireItemStateChanged(event);\n                    if (event.getStateChange() == ItemEvent.SELECTED) {\n                        selected = recentlyUsed;\n                    }\n                }\n            };\n            recent.setText(getHtmlText(recent, \"<nobr>\" + recentlyUsed.getName() + \" <span style=\\\"color:\" + getColorText(disabledText) + \";\\\">\" + // NOI18N\n                                           NbBundle.getMessage(ImportPanel.class, \"ImportPanel_OptionRecentlyUsed\") + \"</span>\" + \"</nobr>\")); // NOI18N\n            recent.setToolTipText(recentlyUsed.getAbsolutePath());\n            recent.putClientProperty(KEY_FOLDER, recentlyUsed);\n            add(recent, c);\n        } else {\n            recent = null;\n        }\n        \n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 3;\n        c.insets = new Insets(0, 25, 0, 15);\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.NONE;\n        custom = new JRadioButton() {\n            protected void fireItemStateChanged(ItemEvent event) {\n                super.fireItemStateChanged(event);\n                if (event.getStateChange() == ItemEvent.SELECTED) {\n                    selected = null;\n                    setText(getHtmlText(custom, \"<nobr>\" + NbBundle.getMessage(ImportPanel.class, \"ImportPanel_OptionSelectCustom\") + \" <span style=\\\"color:\" + getColorText(disabledText) + \";\\\">\" + // NOI18N\n                                        NbBundle.getMessage(ImportPanel.class, \"ImportPanel_OptionSelectCustom2\", firstSupported) + \"</span>\" + \"</nobr>\")); // NOI18N\n                } else if (event.getStateChange() == ItemEvent.DESELECTED) {\n                    setText(getHtmlText(custom, \"<nobr>\" + NbBundle.getMessage(ImportPanel.class, \"ImportPanel_OptionSelectCustom\") + \"</nobr>\")); // NOI18N\n                }\n            }\n        };\n        custom.setText(getHtmlText(custom, \"<nobr>\" + NbBundle.getMessage(ImportPanel.class, \"ImportPanel_OptionSelectCustom\") + \"</nobr>\")); // NOI18N\n        custom.setToolTipText(NbBundle.getMessage(ImportPanel.class, \"ImportPanel_OptionSelectCustomTooltip\")); // NOI18N\n        custom.putClientProperty(KEY_FOLDER, null);\n        add(custom, c);\n        \n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 4;\n        c.insets = new Insets(30, 15, 10, 15);\n        c.anchor = GridBagConstraints.WEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        progress = new JProgressBar();\n        progress.setString(NbBundle.getMessage(ImportPanel.class, \"ImportPanel_ProgressText\")); // NOI18N\n        progress.setStringPainted(true);\n        progress.setVisible(false);\n        add(progress, c);\n        \n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 5;\n        c.insets = new Insets(30, 15, 10, 15);\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.HORIZONTAL;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        text2 = new JTextPane();\n        text2.setContentType(\"text/html\");                                      // NOI18N\n        text2.setFont(UIManager.getFont(\"Label.font\"));                         // NOI18N\n        text2.setOpaque(false);\n        text2.setEditable(false);\n        text2.setFocusable(false);\n        text2.setRequestFocusEnabled(false);\n        setHtmlText(text2, NbBundle.getMessage(ImportPanel.class, \"ImportPanel_Msg2\")); // NOI18N\n        add(text2, c);\n        \n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 6;\n        c.weightx = 1;\n        c.weighty = 1;\n        c.insets = new Insets(0, 0, 0, 0);\n        c.anchor = GridBagConstraints.NORTHWEST;\n        c.fill = GridBagConstraints.BOTH;\n        c.gridwidth = GridBagConstraints.REMAINDER;\n        JPanel f = new JPanel(null);\n        f.setOpaque(false);\n        add(f, c);\n        \n        c = new GridBagConstraints();\n        c.gridx = 0;\n        c.gridy = 7;\n        c.weightx = 1;\n        c.insets = new Insets(25, 15, 10, 5);\n        c.anchor = GridBagConstraints.EAST;\n        c.fill = GridBagConstraints.NONE;\n        importB = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                importImpl();\n            }\n        };\n        importB.setText(NbBundle.getMessage(ImportPanel.class, \"ImportPanel_ImportButton\")); // NOI18N\n        importB.setDefaultCapable(true);\n        add(importB, c);\n        \n        c = new GridBagConstraints();\n        c.gridx = 1;\n        c.gridy = 7;\n        c.insets = new Insets(25, 0, 10, 10);\n        c.anchor = GridBagConstraints.EAST;\n        c.fill = GridBagConstraints.NONE;\n        skipB = new JButton() {\n            protected void fireActionPerformed(ActionEvent e) {\n                super.fireActionPerformed(e);\n                skipImpl();\n            }\n        };\n        skipB.setText(NbBundle.getMessage(ImportPanel.class, \"ImportPanel_SkipButton\")); // NOI18N\n        skipB.setDefaultCapable(false);\n        add(skipB, c);\n        \n        ButtonGroup userdirs = new ButtonGroup();\n        userdirs.add(latest);\n        if (recent != null) userdirs.add(recent);\n        userdirs.add(custom);\n        \n        makeSameSize(importB, skipB);\n        \n        selected = latestRelease;\n        this.userdirsRoot = userdirsRoot;\n    }\n    \n    \n    abstract boolean isSupportedImport(File dir);\n    \n    abstract void contentsChanged();\n    \n    abstract void beforeImport();\n    \n    abstract void doImport(File source) throws Exception;\n    \n    abstract void afterImport();\n    \n    abstract void close();\n    \n    \n    JButton getDefaultButton() {\n        return importB;\n    }\n    \n    \n    private void importImpl() {\n        final File source;\n        if (selected == null) {\n            source = customImpl();\n            if (source == null) return;\n        } else {\n            source = selected;\n        }\n        \n        beforeImport();\n        \n        new SwingWorker<String, Void>() {\n            {\n                if (latest.getClientProperty(KEY_FOLDER) != selected) latest.setEnabled(false);\n                if (recent != null && recent.getClientProperty(KEY_FOLDER) != selected) recent.setEnabled(false);\n                if (custom.getClientProperty(KEY_FOLDER) != selected) custom.setEnabled(false);\n                importB.setEnabled(false);\n                skipB.setEnabled(false);\n                text2.setVisible(false);\n                \n                // Aqua LaF doesn't support painted string for indeterminate progress\n                if (!\"Aqua\".equals(UIManager.getLookAndFeel().getID())) progress.setIndeterminate(true); // NOI18N\n                progress.setVisible(true);\n            }\n            @Override\n            protected String doInBackground() throws Exception {\n                try {\n                    doImport(source);\n                    return null;\n                } catch (Exception e) {\n                    return e.getLocalizedMessage();\n                }\n            }\n            @Override\n            public void done() {\n                afterImport();\n                \n                String result;\n                try {\n                    result = get();\n                } catch (InterruptedException | ExecutionException ex) {\n                    result = ex.getLocalizedMessage();\n                }\n                \n                if (!\"Aqua\".equals(UIManager.getLookAndFeel().getID())) progress.setIndeterminate(false); // NOI18N\n                \n                if (result != null) {\n                    progress.setVisible(false);\n                    setHint(\"<nobr><b>\" + NbBundle.getMessage(ImportPanel.class, \"ImportPanel_ImportFailed\") + \"</b><br>\" + result + \"</nobr>\"); // NOI18N\n                    text2.setVisible(true);\n                    importB.setEnabled(true);\n                    skipB.setEnabled(true);\n                    latest.setEnabled(true);\n                    if (recent != null) recent.setEnabled(true);\n                    custom.setEnabled(true);\n                } else {\n                    close();\n                }\n            }\n        }.execute();\n    }\n    \n    private void skipImpl() {\n        close();\n    }\n    \n    private File customImpl() {\n        JFileChooser ch = new JFileChooser(userdirsRoot) {\n            public void approveSelection() {\n                if (NbBundle.getMessage(ImportPanel.class, \"ImportPanel_ImportButton\").equals(getApproveButtonText())) { // NOI18N\n                    super.approveSelection();\n                } else {\n                    File f = getSelectedFile();\n                    if (f == null) f = getCurrentDirectory();\n                    setCurrentDirectory(f);\n                }\n            }\n        };\n        ch.setDialogType(JFileChooser.CUSTOM_DIALOG);\n        ch.setDialogTitle(NbBundle.getMessage(ImportPanel.class, \"ImportPanel_CustomDirCaption\")); // NOI18N\n        ch.setApproveButtonText(NbBundle.getMessage(ImportPanel.class, \"ImportPanel_OpenButton\")); // NOI18N\n        ch.setApproveButtonToolTipText(NbBundle.getMessage(ImportPanel.class, \"ImportPanel_OpenButtonTooltip\")); // NOI18N\n        ch.setMultiSelectionEnabled(false);\n        ch.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);\n        ch.setAcceptAllFileFilterUsed(false);\n        ch.addChoosableFileFilter(new FileFilter() {\n            @Override public boolean accept(File f) { return f.isDirectory(); }\n            @Override public String getDescription() { return NbBundle.getMessage(ImportPanel.class, \"ImportPanel_SettingsFilter\"); } // NOI18N\n        });\n        ch.setSelectedFile(null);\n        ch.addPropertyChangeListener(new PropertyChangeListener() {\n            public void propertyChange(final PropertyChangeEvent evt) {\n                if (JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(evt.getPropertyName()) ||\n                    JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(evt.getPropertyName())) {\n                    File f = ch.getSelectedFile();\n                    if (f == null) f = ch.getCurrentDirectory();\n                    if (f != null && isSupportedImport(f)) { // NOI18N\n                        ch.setApproveButtonText(NbBundle.getMessage(ImportPanel.class, \"ImportPanel_ImportButton\")); // NOI18N\n                        ch.setApproveButtonToolTipText(NbBundle.getMessage(ImportPanel.class, \"ImportPanel_ImportButtonTooltip\")); // NOI18N\n                    } else {\n                        ch.setApproveButtonText(NbBundle.getMessage(ImportPanel.class, \"ImportPanel_OpenButton\")); // NOI18N\n                        ch.setApproveButtonToolTipText(NbBundle.getMessage(ImportPanel.class, \"ImportPanel_OpenButtonTooltip\")); // NOI18N\n                    }\n                }\n            }\n        });\n        \n        if (ch.showDialog(latest, null) == JFileChooser.APPROVE_OPTION) {\n            File userdir = ch.getSelectedFile();\n            userdirsRoot = userdir == null ? null : userdir.getParentFile();\n            return userdir;\n        } else {\n            return null;\n        }\n    }\n    \n    \n    private void setHint(String text) {\n        setHtmlText(text2, text);\n        contentsChanged();\n    }\n    \n    \n    private static void makeSameSize(JButton button1, JButton button2) {\n        Dimension dim1 = button1.getPreferredSize();\n        Dimension dim2 = button2.getPreferredSize();\n        int maxWidth = Math.max(dim1.width, dim2.width);\n        int maxHeight = Math.max(dim1.height, dim2.height);\n        button1.setPreferredSize(new Dimension(maxWidth, maxHeight));\n        button2.setPreferredSize(new Dimension(maxWidth, maxHeight));\n    }\n    \n    \n    private static void setHtmlText(JTextPane pane, String text) {\n        pane.setDocument(pane.getEditorKit().createDefaultDocument()); // Workaround for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5042872\n        pane.setText(getHtmlText(pane, text));\n        pane.setCaretPosition(0);\n    }\n    \n    private static String getHtmlText(JComponent component, String text) {\n        Font font = component.getFont();\n        String rgb = getColorText(component.getForeground());\n        return \"<html><body text=\\\"\" + rgb + \"\\\" style=\\\"font-size: \" + font.getSize() + // NOI18N\n               \"pt; font-family: \" + font.getName() + \";\\\">\" + text + \"</body></html>\"; // NOI18N\n    }\n    \n    private static String getColorText(Color color) {\n        return \"rgb(\" + color.getRed() + \",\" + color.getGreen() + \",\" + color.getBlue() + \")\"; // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/startup/src/org/graalvm/visualvm/modules/startup/ImportSettings.java",
    "content": "/*\n * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.modules.startup;\n\nimport java.awt.BorderLayout;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.KeyEvent;\nimport java.beans.PropertyVetoException;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.logging.Logger;\nimport javax.swing.JComponent;\nimport javax.swing.JDialog;\nimport javax.swing.KeyStroke;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.modules.startup.dialogs.StartupDialog;\nimport org.openide.modules.InstalledFileLocator;\nimport org.openide.util.NbBundle;\n\n/**\n * Imports VisualVM settings from another compatible VisualVM userdir.\n * \n * To test right from NetBeans:\n * \n *  1a/ Predefined import:\n *     - add -J-Dvisualvm.import_userdir=... to visualvm/nbproject/project.properties\n *\n *  1b/ Interactive import:\n *     - add -J-Dnetbeans.importclass=org.graalvm.visualvm.modules.startup.ImportSettings to visualvm/nbproject/project.properties\n *     - add -J-Dnetbeans.default_userdir_root.dev=... to visualvm/nbproject/project.properties\n * \n *  2/ Uncomment lines marked as *DEV*\n * \n *  3/ Make sure the development userdir visualvm/build/testuserdir does not exist\n *\n *  4/ Invoke Run on the VisualVM-Startup module\n *\n * \n * @author Jiri Sedlacek\n */\npublic class ImportSettings {\n    \n    // List of userdirs supported by the settings importer\n    // SHOULD NOT BE EMPTY! At least the current release should be listed\n    //\n    // First supported release userdir is the first one\n    // Most recent release userdir is the last one\n    private static final String[] SUPPORTED_USERDIRS = new String[] {\n        \"2.0\",                                                                  // NOI18N\n        \"2.0.1\",                                                                // NOI18N\n        \"2.0.2\",                                                                // NOI18N\n        \"2.0.3\",                                                                // NOI18N\n        \"2.0.4\",                                                                // NOI18N\n        \"2.0.5\",                                                                // NOI18N\n        \"2.0.6\",                                                                // NOI18N\n        \"2.0.7\",                                                                // NOI18N\n        \"2.1\",                                                                  // NOI18N\n        \"2.1.1\",                                                                // NOI18N\n        \"2.1.2\",                                                                // NOI18N\n        \"2.1.3\",                                                                // NOI18N\n        \"2.1.4\",                                                                // NOI18N\n        \"2.1.5\",                                                                // NOI18N\n        \"2.1.6\",                                                                // NOI18N\n        \"2.1.7\",                                                                // NOI18N\n        \"2.1.8\",                                                                // NOI18N\n        \"2.1.9\",                                                                // NOI18N\n        \"2.1.10\",                                                               // NOI18N\n        \"2.2\",                                                                  // NOI18N\n        \"2.2.1\"                                                                 // NOI18N\n    };\n    \n    \n    private final static Logger LOGGER = Logger.getLogger(ImportSettings.class.getName());\n    \n    \n    public static void main(String[] args) throws Exception {\n        // Check current VisualVM userdir\n        String userdirS = System.getProperty(\"netbeans.user\");                  // NOI18N\n        final File userdir = userdirS == null || userdirS.isEmpty() ? null : new File(userdirS);\n        if (userdir == null || !userdir.isDirectory()) {\n            LOGGER.info(\"Skipping import, could not resolve VisualVM userdir: \" + userdirS); // NOI18N\n            return;\n        }\n        \n        // Immediate import based on the provided system property\n        String importUserdirS = System.getProperty(\"visualvm.import_userdir\");  // NOI18N\n        if (importUserdirS != null && !importUserdirS.isEmpty()) {\n            File importUserdir = new File(importUserdirS);\n            \n            String msg;\n            if (!importUserdir.isDirectory()) msg = \"not a directory\";          // NOI18N\n            else if (userdir.equals(importUserdir)) msg = \"own userdir\";        // NOI18N\n            else msg = null;\n            \n            if (msg == null) copyToUserdir(importUserdir, userdir);\n            else LOGGER.info(\"Skipping import from visualvm.import_userdir, wrong directory provided (\" + msg + \"): \" + importUserdirS); // NOI18N\n            \n            return;\n        }\n        \n        // Check VisualVM userdirs root\n        String userdirsRootS = System.getProperty(\"netbeans.default_userdir_root\"); // NOI18\n///*DEV*/ if (userdirsRootS == null || userdirsRootS.isEmpty()) userdirsRootS = System.getProperty(\"netbeans.default_userdir_root.dev\"); // NOI18\n        File userdirsRoot = userdirsRootS == null || userdirsRootS.isEmpty() ? null : new File(userdirsRootS);\n        if (userdirsRoot == null || !userdirsRoot.isDirectory()) {\n            LOGGER.info(\"Skipping import, could not resolve VisualVM userdirs root: \" + userdirsRootS); // NOI18N\n            return;\n        }\n\n        // Read available userdirs supported for import\n        List<File> userdirs = availableUserdirs(userdirsRoot, userdir);\n        if (userdirs.isEmpty()) {\n            LOGGER.info(\"Skipping import, no supported userdirs found in: \" + userdirsRootS); // NOI18N\n            return;\n        }\n        \n\n        File latestRelease = latestReleaseUserdir(userdirs);\n        File recentlyUsed = lastRecentlyUsedUserdir(userdirs);\n\n\n        // Interactive selection & import of the userdir\n        Utils.setSystemLaF();\n\n        final JDialog d = StartupDialog.create(NbBundle.getMessage(\n                ImportSettings.class, \"ImportSettings_Caption\"), null, -1); // NOI18N\n\n        ImportPanel p = new ImportPanel(latestRelease, recentlyUsed, userdirsRoot, SUPPORTED_USERDIRS[0]) {\n            @Override\n            boolean isSupportedImport(File dir) {\n                return isSupportedUserdir(dir, userdir);\n            }\n            \n            @Override\n            void contentsChanged() {\n                SwingUtilities.invokeLater(d::pack);\n            }\n\n            @Override\n            void beforeImport() {\n                d.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);\n            }\n\n            @Override\n            void doImport(File source) throws Exception {\n                copyToUserdir(source, userdir);\n            }\n\n            @Override\n            void afterImport() {\n                d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);\n            }\n\n            @Override\n            void close() {\n                d.setVisible(false);\n                d.dispose();\n            }\n        };\n        d.getContentPane().add(p, BorderLayout.CENTER);\n\n        d.getRootPane().setDefaultButton(p.getDefaultButton());\n        d.getRootPane().registerKeyboardAction(new ActionListener() {\n                @Override public void actionPerformed(ActionEvent e) {\n                    if (d.getDefaultCloseOperation() == JDialog.DISPOSE_ON_CLOSE) {\n                        d.setVisible(false);\n                        d.dispose();\n                    }\n                }\n            },\n            KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),\n            JComponent.WHEN_IN_FOCUSED_WINDOW);\n\n//        d.setResizable(true);\n        d.pack();\n        d.setLocationRelativeTo(null);\n\n        d.setVisible(true);\n    }\n    \n    \n    private static List<File> availableUserdirs(File userdirsRoot, File userdir) {\n        List<File> userdirs = new ArrayList<>();\n        \n        for (String supported : SUPPORTED_USERDIRS) {\n            File available = availableUserdir(userdirsRoot, supported, userdir);\n            if (available != null) userdirs.add(available);\n        }\n        \n        return userdirs;\n    }\n    \n    private static File availableUserdir(File userdirsFolder, String dir, File current) {\n        File file = new File(userdirsFolder, dir);\n        return isSupportedUserdir(file, current) ? file : null;\n    }\n    \n    private static boolean isSupportedUserdir(File userdir, File current) {\n        return !current.equals(userdir) &&\n               userdir.isDirectory() &&\n               new File(userdir, \"config\").isDirectory();                       // NOI18N\n    }\n    \n    private static File latestReleaseUserdir(List<File> userdirs) {\n        return userdirs.isEmpty() ? null : userdirs.get(userdirs.size() - 1);\n    }\n    \n    private static File lastRecentlyUsedUserdir(List<File> userdirs) {\n        File lastRecent = null;\n        long lastModified = -1;\n                \n        for (File userdir : userdirs) {\n            long modified = userdir.lastModified();\n            if (modified > lastModified) {\n                lastModified = modified;\n                lastRecent = userdir;\n            }\n        }\n        \n        return lastRecent;\n    }\n    \n    \n    /* Copy files from source folder to current userdir according to include/exclude\n     * patterns in etc/visualvm.import file. */\n    private static void copyToUserdir(File source, File userdir) throws IOException, PropertyVetoException {\n        File visualvmDir = InstalledFileLocator.getDefault().locate(\"modules\", null, false).getParentFile().getParentFile(); // NOI18N\n        \n        File importFile = new File(visualvmDir, \"etc/visualvm.import\");         // NOI18N\n///*DEV*/ if (!importFile.isFile() && \"testuserdir\".equals(userdir.getName())) {  // NOI18N\n///*DEV*/     File parent = visualvmDir.getParentFile();\n///*DEV*/     if (parent != null && parent.isDirectory()) {\n///*DEV*/         importFile = new File(parent, \"launcher/visualvm.import\");      // NOI18N\n///*DEV*/     }\n///*DEV*/ }\n        \n        LOGGER.fine(\"Import file: \" + importFile);                              // NOI18N\n        LOGGER.info(\"Importing from \" + source + \" to \" + userdir);             // NOI18N\n        \n        File[] files1 = userdir.listFiles();\n        try {\n            CopyFiles.copyDeep(source, userdir, importFile);\n        } catch (Exception e) {\n            try {\n                cleanupUserdir(userdir, files1);\n            } catch (Exception ee) {\n                LOGGER.info(\"Failed to cleanup after import failure: \" + ee);    // NOI18N\n            }\n            throw e;\n        }\n        System.setProperty(\"plugin.manager.import.from\", source.getAbsolutePath()); // NOI18N\n    }\n    \n    \n    private static void cleanupUserdir(File userdir, File[] initialFiles) {\n        // Delete newly created directories\n        File[] files = userdir.listFiles();\n        if (initialFiles.length != files.length) {\n            List<File> imported = new ArrayList<>(Arrays.asList(files));\n            imported.removeAll(Arrays.asList(initialFiles));\n            for (File f : imported) delete(f);\n        }\n        \n        // Cleanup config directory (may be created but empty before the import)\n        File config = new File(userdir, \"config\");                              // NOI18N\n        if (config.isDirectory()) for (File f : config.listFiles()) delete(f);\n    }\n    \n    private static void delete(File file) {\n        if (file.isDirectory()) for (File f : file.listFiles()) delete(f);\n        file.delete();\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt",
    "content": "Project VisualVM\n\nThe GNU General Public License (GPL)\n\nVersion 2, June 1991\n\nCopyright (C) 1989, 1991 Free Software Foundation, Inc.\n51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nEveryone is permitted to copy and distribute verbatim copies of this license\ndocument, but changing it is not allowed.\n\nPreamble\n\nThe licenses for most software are designed to take away your freedom to share\nand change it.  By contrast, the GNU General Public License is intended to\nguarantee your freedom to share and change free software--to make sure the\nsoftware is free for all its users.  This General Public License applies to\nmost of the Free Software Foundation's software and to any other program whose\nauthors commit to using it.  (Some other Free Software Foundation software is\ncovered by the GNU Library General Public License instead.) You can apply it to\nyour programs, too.\n\nWhen we speak of free software, we are referring to freedom, not price.  Our\nGeneral Public Licenses are designed to make sure that you have the freedom to\ndistribute copies of free software (and charge for this service if you wish),\nthat you receive source code or can get it if you want it, that you can change\nthe software or use pieces of it in new free programs; and that you know you\ncan do these things.\n\nTo protect your rights, we need to make restrictions that forbid anyone to deny\nyou these rights or to ask you to surrender the rights.  These restrictions\ntranslate to certain responsibilities for you if you distribute copies of the\nsoftware, or if you modify it.\n\nFor example, if you distribute copies of such a program, whether gratis or for\na fee, you must give the recipients all the rights that you have.  You must\nmake sure that they, too, receive or can get the source code.  And you must\nshow them these terms so they know their rights.\n\nWe protect your rights with two steps: (1) copyright the software, and (2)\noffer you this license which gives you legal permission to copy, distribute\nand/or modify the software.\n\nAlso, for each author's protection and ours, we want to make certain that\neveryone understands that there is no warranty for this free software.  If the\nsoftware is modified by someone else and passed on, we want its recipients to\nknow that what they have is not the original, so that any problems introduced\nby others will not reflect on the original authors' reputations.\n\nFinally, any free program is threatened constantly by software patents.  We\nwish to avoid the danger that redistributors of a free program will\nindividually obtain patent licenses, in effect making the program proprietary.\nTo prevent this, we have made it clear that any patent must be licensed for\neveryone's free use or not licensed at all.\n\nThe precise terms and conditions for copying, distribution and modification\nfollow.\n\nTERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n0. This License applies to any program or other work which contains a notice\nplaced by the copyright holder saying it may be distributed under the terms of\nthis General Public License.  The \"Program\", below, refers to any such program\nor work, and a \"work based on the Program\" means either the Program or any\nderivative work under copyright law: that is to say, a work containing the\nProgram or a portion of it, either verbatim or with modifications and/or\ntranslated into another language.  (Hereinafter, translation is included\nwithout limitation in the term \"modification\".) Each licensee is addressed as\n\"you\".\n\nActivities other than copying, distribution and modification are not covered by\nthis License; they are outside its scope.  The act of running the Program is\nnot restricted, and the output from the Program is covered only if its contents\nconstitute a work based on the Program (independent of having been made by\nrunning the Program).  Whether that is true depends on what the Program does.\n\n1. You may copy and distribute verbatim copies of the Program's source code as\nyou receive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice and\ndisclaimer of warranty; keep intact all the notices that refer to this License\nand to the absence of any warranty; and give any other recipients of the\nProgram a copy of this License along with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and you may\nat your option offer warranty protection in exchange for a fee.\n\n2. You may modify your copy or copies of the Program or any portion of it, thus\nforming a work based on the Program, and copy and distribute such modifications\nor work under the terms of Section 1 above, provided that you also meet all of\nthese conditions:\n\n    a) You must cause the modified files to carry prominent notices stating\n    that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in whole or\n    in part contains or is derived from the Program or any part thereof, to be\n    licensed as a whole at no charge to all third parties under the terms of\n    this License.\n\n    c) If the modified program normally reads commands interactively when run,\n    you must cause it, when started running for such interactive use in the\n    most ordinary way, to print or display an announcement including an\n    appropriate copyright notice and a notice that there is no warranty (or\n    else, saying that you provide a warranty) and that users may redistribute\n    the program under these conditions, and telling the user how to view a copy\n    of this License.  (Exception: if the Program itself is interactive but does\n    not normally print such an announcement, your work based on the Program is\n    not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If identifiable\nsections of that work are not derived from the Program, and can be reasonably\nconsidered independent and separate works in themselves, then this License, and\nits terms, do not apply to those sections when you distribute them as separate\nworks.  But when you distribute the same sections as part of a whole which is a\nwork based on the Program, the distribution of the whole must be on the terms\nof this License, whose permissions for other licensees extend to the entire\nwhole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest your\nrights to work written entirely by you; rather, the intent is to exercise the\nright to control the distribution of derivative or collective works based on\nthe Program.\n\nIn addition, mere aggregation of another work not based on the Program with the\nProgram (or with a work based on the Program) on a volume of a storage or\ndistribution medium does not bring the other work under the scope of this\nLicense.\n\n3. You may copy and distribute the Program (or a work based on it, under\nSection 2) in object code or executable form under the terms of Sections 1 and\n2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable source\n    code, which must be distributed under the terms of Sections 1 and 2 above\n    on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three years, to\n    give any third party, for a charge no more than your cost of physically\n    performing source distribution, a complete machine-readable copy of the\n    corresponding source code, to be distributed under the terms of Sections 1\n    and 2 above on a medium customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer to\n    distribute corresponding source code.  (This alternative is allowed only\n    for noncommercial distribution and only if you received the program in\n    object code or executable form with such an offer, in accord with\n    Subsection b above.)\n\nThe source code for a work means the preferred form of the work for making\nmodifications to it.  For an executable work, complete source code means all\nthe source code for all modules it contains, plus any associated interface\ndefinition files, plus the scripts used to control compilation and installation\nof the executable.  However, as a special exception, the source code\ndistributed need not include anything that is normally distributed (in either\nsource or binary form) with the major components (compiler, kernel, and so on)\nof the operating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering access to copy\nfrom a designated place, then offering equivalent access to copy the source\ncode from the same place counts as distribution of the source code, even though\nthird parties are not compelled to copy the source along with the object code.\n\n4. You may not copy, modify, sublicense, or distribute the Program except as\nexpressly provided under this License.  Any attempt otherwise to copy, modify,\nsublicense or distribute the Program is void, and will automatically terminate\nyour rights under this License.  However, parties who have received copies, or\nrights, from you under this License will not have their licenses terminated so\nlong as such parties remain in full compliance.\n\n5. You are not required to accept this License, since you have not signed it.\nHowever, nothing else grants you permission to modify or distribute the Program\nor its derivative works.  These actions are prohibited by law if you do not\naccept this License.  Therefore, by modifying or distributing the Program (or\nany work based on the Program), you indicate your acceptance of this License to\ndo so, and all its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n6. Each time you redistribute the Program (or any work based on the Program),\nthe recipient automatically receives a license from the original licensor to\ncopy, distribute or modify the Program subject to these terms and conditions.\nYou may not impose any further restrictions on the recipients' exercise of the\nrights granted herein.  You are not responsible for enforcing compliance by\nthird parties to this License.\n\n7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues), conditions\nare imposed on you (whether by court order, agreement or otherwise) that\ncontradict the conditions of this License, they do not excuse you from the\nconditions of this License.  If you cannot distribute so as to satisfy\nsimultaneously your obligations under this License and any other pertinent\nobligations, then as a consequence you may not distribute the Program at all.\nFor example, if a patent license would not permit royalty-free redistribution\nof the Program by all those who receive copies directly or indirectly through\nyou, then the only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under any\nparticular circumstance, the balance of the section is intended to apply and\nthe section as a whole is intended to apply in other circumstances.\n\nIt is not the purpose of this section to induce you to infringe any patents or\nother property right claims or to contest validity of any such claims; this\nsection has the sole purpose of protecting the integrity of the free software\ndistribution system, which is implemented by public license practices.  Many\npeople have made generous contributions to the wide range of software\ndistributed through that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing to\ndistribute software through any other system and a licensee cannot impose that\nchoice.\n\nThis section is intended to make thoroughly clear what is believed to be a\nconsequence of the rest of this License.\n\n8. If the distribution and/or use of the Program is restricted in certain\ncountries either by patents or by copyrighted interfaces, the original\ncopyright holder who places the Program under this License may add an explicit\ngeographical distribution limitation excluding those countries, so that\ndistribution is permitted only in or among countries not thus excluded.  In\nsuch case, this License incorporates the limitation as if written in the body\nof this License.\n\n9. The Free Software Foundation may publish revised and/or new versions of the\nGeneral Public License from time to time.  Such new versions will be similar in\nspirit to the present version, but may differ in detail to address new problems\nor concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any later\nversion\", you have the option of following the terms and conditions either of\nthat version or of any later version published by the Free Software Foundation.\nIf the Program does not specify a version number of this License, you may\nchoose any version ever published by the Free Software Foundation.\n\n10. If you wish to incorporate parts of the Program into other free programs\nwhose distribution conditions are different, write to the author to ask for\npermission.  For software which is copyrighted by the Free Software Foundation,\nwrite to the Free Software Foundation; we sometimes make exceptions for this.\nOur decision will be guided by the two goals of preserving the free status of\nall derivatives of our free software and of promoting the sharing and reuse of\nsoftware generally.\n\nNO WARRANTY\n\n11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR\nTHE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE\nSTATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE\nPROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\nFITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND\nPERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE,\nYOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL\nANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE\nPROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR\nINABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA\nBEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\nFAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER\nOR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\nEND OF TERMS AND CONDITIONS\n\nHow to Apply These Terms to Your New Programs\n\nIf you develop a new program, and you want it to be of the greatest possible\nuse to the public, the best way to achieve this is to make it free software\nwhich everyone can redistribute and change under these terms.\n\nTo do so, attach the following notices to the program.  It is safest to attach\nthem to the start of each source file to most effectively convey the exclusion\nof warranty; and each file should have at least the \"copyright\" line and a\npointer to where the full notice is found.\n\n    One line to give the program's name and a brief idea of what it does.\n\n    Copyright (C) <year> <name of author>\n\n    This program is free software; you can redistribute it and/or modify it\n    under the terms of the GNU General Public License as published by the Free\n    Software Foundation; either version 2 of the License, or (at your option)\n    any later version.\n\n    This program is distributed in the hope that it will be useful, but WITHOUT\n    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\n    more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc., 51\n    Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this when it\nstarts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author Gnomovision comes\n    with ABSOLUTELY NO WARRANTY; for details type 'show w'.  This is free\n    software, and you are welcome to redistribute it under certain conditions;\n    type 'show c' for details.\n\nThe hypothetical commands 'show w' and 'show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may be\ncalled something other than 'show w' and 'show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.  Here\nis a sample; alter the names:\n\n    Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n    'Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n    signature of Ty Coon, 1 April 1989\n\n    Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Library General Public\nLicense instead of this License.\n\n\n\"CLASSPATH\" EXCEPTION TO THE GPL\n\nCertain source files distributed by Oracle America and/or its affiliates are\nsubject to the following clarification and special exception to the GPL, but\nonly where Oracle has expressly included in the particular source file's header\nthe words \"Oracle designates this particular file as subject to the \"Classpath\"\nexception as provided by Oracle in the LICENSE file that accompanied this code.\"\n\n    Linking this library statically or dynamically with other modules is making\n    a combined work based on this library.  Thus, the terms and conditions of\n    the GNU General Public License cover the whole combination.\n\n    As a special exception, the copyright holders of this library give you\n    permission to link this library with independent modules to produce an\n    executable, regardless of the license terms of these independent modules,\n    and to copy and distribute the resulting executable under terms of your\n    choice, provided that you also meet, for each linked independent module,\n    the terms and conditions of the license of that module.  An independent\n    module is a module which is not derived from or based on this library.  If\n    you modify this library, you may extend this exception to your version of\n    the library, but you are not obligated to do so.  If you do not wish to do\n    so, delete this exception statement from your version.\n"
  },
  {
    "path": "visualvm/startup/src/org/graalvm/visualvm/modules/startup/LicensePanel.form",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<Form version=\"1.4\" maxVersion=\"1.4\" type=\"org.netbeans.modules.form.forminfo.JPanelFormInfo\">\n  <Properties>\n    <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n      <Border info=\"org.netbeans.modules.form.compat2.border.EmptyBorderInfo\">\n        <EmptyBorder bottom=\"0\" left=\"12\" right=\"11\" top=\"12\"/>\n      </Border>\n    </Property>\n  </Properties>\n  <AuxValues>\n    <AuxValue name=\"FormSettings_autoResourcing\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_autoSetComponentName\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_generateFQN\" type=\"java.lang.Boolean\" value=\"true\"/>\n    <AuxValue name=\"FormSettings_generateMnemonicsCode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_i18nAutoMode\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_listenerGenerationStyle\" type=\"java.lang.Integer\" value=\"0\"/>\n    <AuxValue name=\"FormSettings_variablesLocal\" type=\"java.lang.Boolean\" value=\"false\"/>\n    <AuxValue name=\"FormSettings_variablesModifier\" type=\"java.lang.Integer\" value=\"2\"/>\n    <AuxValue name=\"designerSize\" type=\"java.awt.Dimension\" value=\"-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,27,0,0,2,124\"/>\n  </AuxValues>\n\n  <Layout class=\"org.netbeans.modules.form.compat2.layouts.DesignBoxLayout\">\n    <Property name=\"axis\" type=\"int\" value=\"1\"/>\n  </Layout>\n  <SubComponents>\n    <Component class=\"javax.swing.JTextArea\" name=\"jTextAreaTop\">\n      <Properties>\n        <Property name=\"background\" type=\"java.awt.Color\" editor=\"org.netbeans.modules.form.RADConnectionPropertyEditor\">\n          <Connection component=\"Form\" name=\"background\" type=\"property\"/>\n        </Property>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n        <Property name=\"font\" type=\"java.awt.Font\" editor=\"org.netbeans.modules.form.RADConnectionPropertyEditor\">\n          <Connection code=\"UIManager.getFont(&quot;Label.font&quot;).deriveFont(Font.BOLD)\" type=\"code\"/>\n        </Property>\n        <Property name=\"lineWrap\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"rows\" type=\"int\" value=\"1\"/>\n        <Property name=\"text\" preCode=\"jTextAreaTop.setText(bundle.getString(&quot;MSG_LicenseDlgLabelTop&quot;));\"/>\n        <Property name=\"wrapStyleWord\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"org.netbeans.modules.form.compat2.border.EmptyBorderInfo\">\n            <EmptyBorder bottom=\"3\" left=\"0\" right=\"0\" top=\"0\"/>\n          </Border>\n        </Property>\n        <Property name=\"focusable\" type=\"boolean\" value=\"false\"/>\n        <Property name=\"margin\" type=\"java.awt.Insets\" editor=\"org.netbeans.beaninfo.editors.InsetsEditor\">\n          <Insets value=\"[0, 0, 2, 0]\"/>\n        </Property>\n        <Property name=\"opaque\" type=\"boolean\" value=\"false\"/>\n        <Property name=\"requestFocusEnabled\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n    </Component>\n    <Container class=\"javax.swing.JScrollPane\" name=\"jScrollPane1\">\n      <AuxValues>\n        <AuxValue name=\"autoScrollPane\" type=\"java.lang.Boolean\" value=\"true\"/>\n      </AuxValues>\n\n      <Layout class=\"org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout\"/>\n      <SubComponents>\n        <Component class=\"javax.swing.JEditorPane\" name=\"jEditorPane1\">\n          <Properties>\n            <Property name=\"background\" type=\"java.awt.Color\" editor=\"org.netbeans.modules.form.RADConnectionPropertyEditor\">\n              <Connection code=\"UIManager.getDefaults().getColor(&quot;Tree.textBackground&quot;)\" type=\"code\"/>\n            </Property>\n            <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n            <Property name=\"foreground\" type=\"java.awt.Color\" editor=\"org.netbeans.modules.form.RADConnectionPropertyEditor\">\n              <Connection code=\"UIManager.getDefaults().getColor(&quot;Tree.textForeground&quot;)\" type=\"code\"/>\n            </Property>\n            <Property name=\"preferredSize\" type=\"java.awt.Dimension\" editor=\"org.netbeans.beaninfo.editors.DimensionEditor\">\n              <Dimension value=\"[500, 500]\"/>\n            </Property>\n          </Properties>\n        </Component>\n      </SubComponents>\n    </Container>\n    <Component class=\"javax.swing.JTextArea\" name=\"jTextAreaBottom\">\n      <Properties>\n        <Property name=\"background\" type=\"java.awt.Color\" editor=\"org.netbeans.modules.form.RADConnectionPropertyEditor\">\n          <Connection component=\"Form\" name=\"background\" type=\"property\"/>\n        </Property>\n        <Property name=\"columns\" type=\"int\" value=\"20\"/>\n        <Property name=\"editable\" type=\"boolean\" value=\"false\"/>\n        <Property name=\"font\" type=\"java.awt.Font\" editor=\"org.netbeans.modules.form.RADConnectionPropertyEditor\">\n          <Connection code=\"UIManager.getFont(&quot;Label.font&quot;).deriveFont(Font.BOLD)\" type=\"code\"/>\n        </Property>\n        <Property name=\"lineWrap\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"rows\" type=\"int\" value=\"2\"/>\n        <Property name=\"text\" preCode=\"jTextAreaBottom.setText(bundle.getString(&quot;MSG_LicenseDlgLabelBottom&quot;));\"/>\n        <Property name=\"wrapStyleWord\" type=\"boolean\" value=\"true\"/>\n        <Property name=\"border\" type=\"javax.swing.border.Border\" editor=\"org.netbeans.modules.form.editors2.BorderEditor\">\n          <Border info=\"org.netbeans.modules.form.compat2.border.EmptyBorderInfo\">\n            <EmptyBorder bottom=\"0\" left=\"0\" right=\"0\" top=\"3\"/>\n          </Border>\n        </Property>\n        <Property name=\"focusable\" type=\"boolean\" value=\"false\"/>\n        <Property name=\"opaque\" type=\"boolean\" value=\"false\"/>\n        <Property name=\"requestFocusEnabled\" type=\"boolean\" value=\"false\"/>\n      </Properties>\n    </Component>\n  </SubComponents>\n</Form>\n"
  },
  {
    "path": "visualvm/startup/src/org/graalvm/visualvm/modules/startup/LicensePanel.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.startup;\n\nimport java.awt.Font;\nimport java.io.IOException;\nimport java.net.URL;\nimport java.util.ResourceBundle;\n\nimport java.util.logging.Logger;\nimport javax.swing.UIManager;\nimport org.openide.util.NbBundle;\n\n/**\n * This class displays license during first start of IDE.\n *\n * @author  Marek Slama\n */\nfinal class LicensePanel extends javax.swing.JPanel {\n    private final static Logger LOGGER = Logger.getLogger(LicensePanel.class.getName());\n    \n    /** Creates new form LicensePanel */\n    LicensePanel(URL url) {\n        this.url = url;\n        initComponents();\n        initAccessibility();\n        try {\n            jEditorPane1.setPage(url);\n        } catch (IOException exc) {\n            //Problem with locating file\n            LOGGER.throwing(LicensePanel.class.getName(), \"<init>\", exc); //NOI18N\n        }\n    }\n    \n    private void initAccessibility() {\n        this.getAccessibleContext().setAccessibleName\n        (bundle.getString(\"ACSN_LicensePanel\"));\n        this.getAccessibleContext().setAccessibleDescription\n        (bundle.getString(\"ACSD_LicensePanel\"));\n        \n        jEditorPane1.getAccessibleContext().setAccessibleName\n        (bundle.getString(\"ACSN_EditorPane\"));\n        jEditorPane1.getAccessibleContext().setAccessibleDescription\n        (bundle.getString(\"ACSD_EditorPane\"));\n    }\n    \n    /** This method is called from within the constructor to\n     * initialize the form.\n     * WARNING: Do NOT modify this code. The content of this method is\n     * always regenerated by the Form Editor.\n     */\n    // <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">//GEN-BEGIN:initComponents\n    private void initComponents() {\n\n        jTextAreaTop = new javax.swing.JTextArea();\n        jScrollPane1 = new javax.swing.JScrollPane();\n        jEditorPane1 = new javax.swing.JEditorPane();\n        jTextAreaBottom = new javax.swing.JTextArea();\n\n        setBorder(javax.swing.BorderFactory.createEmptyBorder(12, 12, 0, 11));\n        setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.Y_AXIS));\n\n        jTextAreaTop.setBackground(getBackground());\n        jTextAreaTop.setColumns(20);\n        jTextAreaTop.setEditable(false);\n        jTextAreaTop.setFont(UIManager.getFont(\"Label.font\").deriveFont(Font.BOLD));\n        jTextAreaTop.setLineWrap(true);\n        jTextAreaTop.setRows(1);\n        jTextAreaTop.setText(bundle.getString(\"MSG_LicenseDlgLabelTop\"));\n        jTextAreaTop.setWrapStyleWord(true);\n        jTextAreaTop.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 3, 0));\n        jTextAreaTop.setFocusable(false);\n        jTextAreaTop.setMargin(new java.awt.Insets(0, 0, 2, 0));\n        jTextAreaTop.setOpaque(false);\n        jTextAreaTop.setRequestFocusEnabled(false);\n        add(jTextAreaTop);\n\n        jEditorPane1.setBackground(UIManager.getDefaults().getColor(\"Tree.textBackground\"));\n        jEditorPane1.setEditable(false);\n        jEditorPane1.setForeground(UIManager.getDefaults().getColor(\"Tree.textForeground\"));\n        jEditorPane1.setPreferredSize(new java.awt.Dimension(500, 500));\n        jScrollPane1.setViewportView(jEditorPane1);\n\n        add(jScrollPane1);\n\n        jTextAreaBottom.setBackground(getBackground());\n        jTextAreaBottom.setColumns(20);\n        jTextAreaBottom.setEditable(false);\n        jTextAreaBottom.setFont(UIManager.getFont(\"Label.font\").deriveFont(Font.BOLD));\n        jTextAreaBottom.setLineWrap(true);\n        jTextAreaBottom.setRows(2);\n        jTextAreaBottom.setText(bundle.getString(\"MSG_LicenseDlgLabelBottom\"));\n        jTextAreaBottom.setWrapStyleWord(true);\n        jTextAreaBottom.setBorder(javax.swing.BorderFactory.createEmptyBorder(3, 0, 0, 0));\n        jTextAreaBottom.setFocusable(false);\n        jTextAreaBottom.setOpaque(false);\n        jTextAreaBottom.setRequestFocusEnabled(false);\n        add(jTextAreaBottom);\n    }// </editor-fold>//GEN-END:initComponents\n    \n    \n    // Variables declaration - do not modify//GEN-BEGIN:variables\n    private javax.swing.JEditorPane jEditorPane1;\n    private javax.swing.JScrollPane jScrollPane1;\n    private javax.swing.JTextArea jTextAreaBottom;\n    private javax.swing.JTextArea jTextAreaTop;\n    // End of variables declaration//GEN-END:variables\n    private URL url;\n    private static final ResourceBundle bundle = NbBundle.getBundle(LicensePanel.class);\n}\n"
  },
  {
    "path": "visualvm/startup/src/org/graalvm/visualvm/modules/startup/Utils.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.modules.startup;\n\nimport javax.swing.AbstractButton;\nimport javax.swing.UIManager;\nimport org.openide.util.Utilities;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class Utils {\n\n    /**\n     * Tries to set the system LaF, silently ignores all errors.\n     */\n    static void setSystemLaF() {\n        try {\n            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());\n        } catch (Throwable t) {}\n    }\n\n    /**\n     * Actual setter of the text & mnemonics for the AbstractButton or\n     * their subclasses. We must copy the necessary code from org.openide.awt.Mnemonics\n     * because org.openide.awt module is not available yet when this code is called.\n     * @param button AbstractButton\n     * @param text new label\n     */\n    static void setLocalizedText (AbstractButton button, String text) {\n        if (text == null) {\n            button.setText(null);\n            return;\n        }\n\n        int i = findMnemonicAmpersand(text);\n\n        if (i < 0) {\n            // no '&' - don't set the mnemonic\n            button.setText(text);\n            button.setMnemonic(0);\n        } else {\n            button.setText(text.substring(0, i) + text.substring(i + 1));\n\n            if (Utilities.isMac()) {\n                // there shall be no mnemonics on macOS.\n                //#55864\n                return;\n            }\n\n            char ch = text.charAt(i + 1);\n\n            // it's latin character or arabic digit,\n            // setting it as mnemonics\n            button.setMnemonic(ch);\n\n            // If it's something like \"Save &As\", we need to set another\n            // mnemonic index (at least under 1.4 or later)\n            // see #29676\n            button.setDisplayedMnemonicIndex(i);\n        }\n    }\n\n    /**\n     * Searches for an ampersand in a string which indicates a mnemonic.\n     * Recognizes the following cases:\n     * <ul>\n     * <li>\"Drag & Drop\", \"Ampersand ('&')\" - don't have mnemonic ampersand.\n     *      \"&\" is not found before \" \" (space), or if enclosed in \"'\"\n     *     (single quotation marks).\n     * <li>\"&File\", \"Save &As...\" - do have mnemonic ampersand.\n     * <li>\"Rock & Ro&ll\", \"Underline the '&' &character\" - also do have\n     *      mnemonic ampersand, but the second one.\n     * </ul>\n     * @param text text to search\n     * @return the position of mnemonic ampersand in text, or -1 if there is none\n     */\n    private static int findMnemonicAmpersand(String text) {\n        int i = -1;\n\n        do {\n            // searching for the next ampersand\n            i = text.indexOf('&', i + 1); // NOI18N\n\n            if ((i >= 0) && ((i + 1) < text.length())) {\n                // before ' '\n                if (text.charAt(i + 1) == ' ') { // NOI18N\n                    continue;\n\n                    // before ', and after '\n                } else if ((text.charAt(i + 1) == '\\'') && (i > 0) && (text.charAt(i - 1) == '\\'')) { // NOI18N\n                    continue;\n                }\n\n                // ampersand is marking mnemonics\n                return i;\n            }\n        } while (i >= 0);\n\n        return -1;\n    }\n\n}\n"
  },
  {
    "path": "visualvm/startup/src/org/graalvm/visualvm/modules/startup/VisualVMStartup.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.modules.startup;\n\nimport org.graalvm.visualvm.modules.startup.dialogs.StartupDialog;\nimport java.text.MessageFormat;\nimport java.util.Properties;\nimport java.util.ResourceBundle;\nimport javax.swing.JDialog;\nimport javax.swing.JOptionPane;\nimport org.openide.LifecycleManager;\nimport org.openide.modules.ModuleInstall;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class VisualVMStartup extends ModuleInstall {\n    \n    private static final boolean DISABLE_STARTUP_CHECK = Boolean.getBoolean(\"org.graalvm.visualvm.modules.startup.DisableStartupCheck\"); // NOI18N\n    \n    private static final ResourceBundle bundle = NbBundle.getBundle(VisualVMStartup.class);\n    private static final String ERROR_STARTUP_CAPTION = bundle.getString(\"VisualVMStartup_ErrorStartupCaption\"); // NOI18N\n    private static final String INCORRECT_VERSION_MSG = bundle.getString(\"VisualVMStartup_IncorrectVersionMsg\"); // NOI18N\n    private static final String JRE_MSG = bundle.getString(\"VisualVMStartup_JreMsg\"); // NOI18N\n    private static final String OPENJ9_MSG = bundle.getString(\"VisualVMStartup_OpenJ9Msg\"); // NOI18N\n\n    private static boolean envChecked = false;\n    \n    \n    public void validate() {\n        if (!checkEnv()) LifecycleManager.getDefault().exit();\n    }\n\n    static synchronized boolean checkEnv() {\n        if (envChecked) return true;\n        envChecked = true;\n        \n        if (DISABLE_STARTUP_CHECK) {\n            System.err.println(\"Starting with org.graalvm.visualvm.modules.startup.DisableStartupCheck=true\"); // NOI18N\n        } else {\n            if (!isSupportedJava()) {\n                displayUnsupportedJavaError();\n                return false;\n            } else if (!isJDK()) {\n                displayErrorJRE();\n                return false;\n            } else if (isOpenJ9()) {\n                displayErrorJ9();\n                return false;\n            }\n        }\n\n        return true;\n    }\n    \n    private static void displayUnsupportedJavaError() {\n        Utils.setSystemLaF();\n        JDialog d = StartupDialog.create(ERROR_STARTUP_CAPTION, MessageFormat.format(INCORRECT_VERSION_MSG,\n                        System.getProperty(\"java.specification.version\"), getJavaInfo(), // NOI18N\n                        getJvmInfo(), System.getProperties().getProperty(\"java.home\", \"unknown location\")),\n                JOptionPane.ERROR_MESSAGE); // NOI18N\n        d.setVisible(true);\n    }\n    \n    private static void displayErrorJRE() {\n        Utils.setSystemLaF();\n        JDialog d = StartupDialog.create(ERROR_STARTUP_CAPTION, MessageFormat.format(JRE_MSG,\n                getJavaInfo(), getJvmInfo(), System.getProperties().getProperty(\n                \"java.home\", \"unknown location\")), JOptionPane.ERROR_MESSAGE); // NOI18N\n        d.setVisible(true);\n    }\n\n    private static void displayErrorJ9() {\n        Utils.setSystemLaF();\n        JDialog d = StartupDialog.create(ERROR_STARTUP_CAPTION, MessageFormat.format(OPENJ9_MSG,\n                getJavaInfo(), getJvmInfo(), System.getProperties().getProperty(\n                \"java.home\", \"unknown location\")), JOptionPane.ERROR_MESSAGE); // NOI18N\n        d.setVisible(true);\n    }\n    \n    private static boolean isSupportedJava() {\n        String javaVersion = System.getProperty(\"java.specification.version\"); // NOI18N\n        if (javaVersion == null) return false;\n        return javaVersion.startsWith(\"1.8\")  // NOI18N\n            || javaVersion.startsWith(\"1.9\") || javaVersion.startsWith(\"9\") // NOI18N\n            || javaVersion.startsWith(\"10\") // NOI18N\n            || javaVersion.startsWith(\"11\") // NOI18N\n            || javaVersion.startsWith(\"12\") // NOI18N\n            || javaVersion.startsWith(\"13\") // NOI18N\n            || javaVersion.startsWith(\"14\") // NOI18N\n            || javaVersion.startsWith(\"15\") // NOI18N\n            || javaVersion.startsWith(\"16\") // NOI18N\n            || javaVersion.startsWith(\"17\") // NOI18N\n            || javaVersion.startsWith(\"18\") // NOI18N\n            || javaVersion.startsWith(\"19\") // NOI18N\n            || javaVersion.startsWith(\"20\") // NOI18N\n            || javaVersion.startsWith(\"21\") // NOI18N\n            || javaVersion.startsWith(\"22\") // NOI18N\n            || javaVersion.startsWith(\"23\") // NOI18N\n            || javaVersion.startsWith(\"24\") // NOI18N\n            || javaVersion.startsWith(\"25\");// NOI18N\n    }\n    \n    private static boolean isOpenJ9() {\n        String vmName = System.getProperty(\"java.vm.name\");     // NOI18N\n\n        return \"Eclipse OpenJ9 VM\".equals(vmName);              // NOI18N\n    }\n\n    private static boolean isJDK() {\n        Class<?> vmClass = null;\n        try { vmClass = Class.forName(\"com.sun.tools.attach.VirtualMachine\"); } catch (ClassNotFoundException ex) {} // NOI18N\n        return vmClass != null;\n    }\n    \n    private static String getJavaInfo() {\n        Properties systemProperties = System.getProperties();\n        String javaVersion = systemProperties.getProperty(\"java.version\", \"unknown version\"); // NOI18N\n        String vendorInfo = systemProperties.getProperty(\"java.vendor\", \"unknown vendor\"); // NOI18N\n        return javaVersion + \"; \" + vendorInfo; // NOI18N\n    }\n    \n    private static String getJvmInfo() {\n        Properties systemProperties = System.getProperties();\n        String vmName = systemProperties.getProperty(\"java.vm.name\", \"unknown name\"); // NOI18N\n        String vmVerison = systemProperties.getProperty(\"java.vm.version\", \"\"); // NOI18N\n        String vmInfo = systemProperties.getProperty(\"java.vm.info\", \"\"); // NOI18N\n        // OpenJ9 has long vminfo, which includes several '\\n', use just first line\n        vmInfo = vmInfo.split(\"\\n\")[0];\n        return vmName + \" (\" + vmVerison + \", \" + vmInfo + \")\"; // NOI18N\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/startup/src/org/graalvm/visualvm/modules/startup/dialogs/StartupDialog.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.modules.startup.dialogs;\n\nimport java.awt.BorderLayout;\nimport java.awt.Container;\nimport java.awt.Frame;\nimport java.awt.Image;\nimport java.awt.Window;\nimport java.awt.event.ComponentAdapter;\nimport java.awt.event.ComponentEvent;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.WindowAdapter;\nimport java.awt.event.WindowEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.ArrayList;\nimport java.util.List;\nimport javax.swing.JDialog;\nimport javax.swing.JOptionPane;\nimport javax.swing.JRootPane;\nimport javax.swing.UIManager;\nimport org.openide.util.ImageUtilities;\n\n/**\n * \n * Utility class to create dialogs displayed on VisualVM startup before the main window is shown.\n * Ensures that the dialog shows on top and its presenter is displayed in Windows taskbar.\n *\n * @author Jiri Sedlacek\n */\npublic final class StartupDialog {\n    \n    public static JDialog create(String caption, String message, int messageType) {\n        // Bugfix #361, set the JDialog to appear in the Taskbar on Windows (ModalityType.APPLICATION_MODAL)\n        Window parent = null;\n        for (Window window : Window.getWindows()) {\n            if (window.isVisible() && window.isShowing()) {\n                parent = window;\n                break;\n            }\n        }\n        final JDialog d = parent == null ?\n                new JDialog(null, caption, JDialog.ModalityType.APPLICATION_MODAL) :\n                new JDialog((Frame)null, caption, true); // NOTE: should a (Frame)parent be used here?\n        \n        if (message != null) initDialog(d, message, messageType);\n        \n        // Bugfix #361, JDialog should use the VisualVM icon for better identification\n        List<Image> icons = new ArrayList<>();\n        icons.add(ImageUtilities.loadImage(\"org/netbeans/core/startup/frame.gif\", true)); // NOI18N\n        icons.add(ImageUtilities.loadImage(\"org/netbeans/core/startup/frame24.gif\", true)); // NOI18N\n        icons.add(ImageUtilities.loadImage(\"org/netbeans/core/startup/frame32.gif\", true)); // NOI18N\n        icons.add(ImageUtilities.loadImage(\"org/netbeans/core/startup/frame48.gif\", true)); // NOI18N\n        icons.add(ImageUtilities.loadImage(\"org/netbeans/core/startup/frame256.png\", true)); // NOI18N\n        icons.add(ImageUtilities.loadImage(\"org/netbeans/core/startup/frame512.png\", true)); // NOI18N\n        icons.add(ImageUtilities.loadImage(\"org/netbeans/core/startup/frame1024.png\", true)); // NOI18N\n        d.setIconImages(icons);\n        \n        d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);\n        d.setResizable(false);\n        d.setLocationRelativeTo(null);\n        \n        // Bugfix #361, ensure that the dialog will be the topmost visible window after opening\n        d.addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (d.isShowing()) {\n                        // For some reason the dialog created with defined JDialog.ModalityType\n                        // isn't displayed on Windows when opened by the NetBeans launcher. This\n                        // code seems to workaround it while not breaking anything elsewhere.\n                        // Disabled to fix jigsaw, the problem is not reproducible using Java7u80@Win7\n                        // ComponentPeer peer = d.getPeer();\n                        // if (peer != null) peer.setVisible(true);\n\n                        d.removeHierarchyListener(this);\n                        d.setAlwaysOnTop(true);\n                        d.toFront();\n                        d.setAlwaysOnTop(false);\n                    }\n                }\n            }\n        });\n        \n        return d;\n    }\n    \n    private static void initDialog(final JDialog dialog, String message, int messageType) {\n        final JOptionPane content = new JOptionPane(message, messageType);\n        Container contentPane = dialog.getContentPane();\n\n        contentPane.setLayout(new BorderLayout());\n        contentPane.add(content, BorderLayout.CENTER);\n        dialog.setResizable(false);\n        if (JDialog.isDefaultLookAndFeelDecorated()) {\n            boolean supportsWindowDecorations =\n              UIManager.getLookAndFeel().getSupportsWindowDecorations();\n            if (supportsWindowDecorations) {\n                dialog.setUndecorated(true);\n                content.getRootPane().setWindowDecorationStyle(\n                        styleFromMessageType(messageType));\n            }\n        }\n        dialog.pack();\n\n        final PropertyChangeListener listener = new PropertyChangeListener() {\n            public void propertyChange(PropertyChangeEvent event) {\n                // Let the defaultCloseOperation handle the closing\n                // if the user closed the window without selecting a button\n                // (newValue = null in that case).  Otherwise, close the dialog.\n                if (dialog.isVisible() && event.getSource() == content &&\n                        (event.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)) &&\n                        event.getNewValue() != null &&\n                        event.getNewValue() != JOptionPane.UNINITIALIZED_VALUE) {\n                    dialog.setVisible(false);\n                }\n            }\n        };\n\n        WindowAdapter adapter = new WindowAdapter() {\n            private boolean gotFocus = false;\n            public void windowClosing(WindowEvent we) {\n                content.setValue(null);\n            }\n\n            public void windowClosed(WindowEvent e) {\n                content.removePropertyChangeListener(listener);\n                dialog.getContentPane().removeAll();\n            }\n\n            public void windowGainedFocus(WindowEvent we) {\n                // Once window gets focus, set initial focus\n                if (!gotFocus) {\n                    content.selectInitialValue();\n                    gotFocus = true;\n                }\n            }\n        };\n        dialog.addWindowListener(adapter);\n        dialog.addWindowFocusListener(adapter);\n        dialog.addComponentListener(new ComponentAdapter() {\n            public void componentShown(ComponentEvent ce) {\n                // reset value to ensure closing works properly\n                content.setValue(JOptionPane.UNINITIALIZED_VALUE);\n            }\n        });\n\n        content.addPropertyChangeListener(listener);\n    }\n    \n    private static int styleFromMessageType(int messageType) {\n        switch (messageType) {\n        case JOptionPane.ERROR_MESSAGE:\n            return JRootPane.ERROR_DIALOG;\n        case JOptionPane.QUESTION_MESSAGE:\n            return JRootPane.QUESTION_DIALOG;\n        case JOptionPane.WARNING_MESSAGE:\n            return JRootPane.WARNING_DIALOG;\n        case JOptionPane.INFORMATION_MESSAGE:\n            return JRootPane.INFORMATION_DIALOG;\n        case JOptionPane.PLAIN_MESSAGE:\n        default:\n            return JRootPane.PLAIN_DIALOG;\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/threaddump/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.threaddump\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.threaddump.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/threaddump/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.threaddump/2\nOpenIDE-Module-Layer: org/graalvm/visualvm/threaddump/resources/layer.xml\nOpenIDE-Module-Install: org/graalvm/visualvm/threaddump/Installer.class\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/threaddump/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.1\n\n"
  },
  {
    "path": "visualvm/threaddump/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.threaddump-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/threaddump/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=b463ec46\nbuild.xml.script.CRC32=3c9528df\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=b463ec46\nnbproject/build-impl.xml.script.CRC32=fb528656\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/threaddump/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/threaddump/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.threaddump</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.3</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.coredump</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.api.progress</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>1</release-version>\n                        <specification-version>1.48</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.netbeans.modules.sendopts</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.43</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.dialogs</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.13.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.modules</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>7.3.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.6.1</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.40</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.threaddump</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/threaddump/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-ThreadDump\n\nMSG_Save_Thread_Dump_As=Save Thread Dump As\n\nDESCR_ThreadDump=Thread dump.\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/Installer.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.threaddump;\n\nimport org.openide.modules.ModuleInstall;\n\n/**\n * Manages a module's lifecycle. Remember that an installer is optional and\n * often not needed at all.\n */\nclass Installer extends ModuleInstall {\n\n    public void restored() {\n        ThreadDumpSupport.getInstance();\n    }\n}\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/ThreadDump.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.threaddump;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsSupport;\nimport java.io.File;\nimport org.openide.util.NbBundle;\n\n/**\n * Abstract implementation of ThreadDump.\n * Each threaddump is defined by a threaddump file.\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ThreadDump extends Snapshot {\n    \n    /**\n     * Creates new instance of ThreadDump with the data stored in a file.\n     * \n     * @param file file where thread dump is saved.\n     */\n    public ThreadDump(File file) {\n        this(file, null);\n    }\n    \n    /**\n     * Creates new instance of ThreadDump with the data stored in a file and defined master.\n     * \n     * @param file file where thread dump is saved,\n     * @param master DataSource in whose window the thread dump will be displayed.\n     */\n    public ThreadDump(File file, DataSource master) {\n        super(file, ThreadDumpSupport.getInstance().getCategory(), master);\n    }\n    \n    public boolean supportsSaveAs() {\n        return getFile() != null;\n    }\n    \n    public void saveAs() {\n        SnapshotsSupport.getInstance().saveAs(this, NbBundle.getMessage(ThreadDump.class, \"MSG_Save_Thread_Dump_As\")); // NOI18N\n    }\n\n}\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/ThreadDumpDescriptor.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n * \n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n * \n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.threaddump;\n\nimport org.graalvm.visualvm.core.snapshot.SnapshotDescriptor;\nimport org.graalvm.visualvm.core.snapshot.SnapshotsSupport;\nimport java.awt.Image;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.NbBundle;\n\n/**\n * DataSourceDescriptor for ThreadDump.\n *\n * @author Jiri Sedlacek\n */\npublic class ThreadDumpDescriptor extends SnapshotDescriptor<ThreadDump> {\n        \n    private static final Image ICON = SnapshotsSupport.getInstance().createSnapshotIcon(\n            ImageUtilities.loadImage(\"org/graalvm/visualvm/threaddump/resources/threaddumpBase.png\", true)); // NOI18N\n\n    /**\n     * Creates new instance of ThreadDumpDescriptor.\n     * \n     * @param threadDump ThreadDump for the descriptor\n     */\n    public ThreadDumpDescriptor(ThreadDump threadDump) {\n        super(threadDump, NbBundle.getMessage(ThreadDumpDescriptor.class,\n              \"DESCR_ThreadDump\"), ICON); // NOI18N\n    }\n        \n}\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/ThreadDumpSupport.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.threaddump;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.core.snapshot.RegisteredSnapshotCategories;\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.threaddump.impl.ThreadDumpCategory;\nimport org.graalvm.visualvm.threaddump.impl.ThreadDumpDescriptorProvider;\nimport org.graalvm.visualvm.threaddump.impl.ThreadDumpProvider;\nimport org.graalvm.visualvm.threaddump.impl.ThreadDumpViewProvider;\n\n/**\n * Support for thread dumps in VisualVM.\n *\n * @author Jiri Sedlacek\n */\npublic final class ThreadDumpSupport {\n\n    private static ThreadDumpSupport instance;\n\n    private final SnapshotCategory<ThreadDump> category = new ThreadDumpCategory();\n    private final ThreadDumpProvider threadDumpProvider;\n    private final ThreadDumpViewProvider threadDumpViewProvider;\n\n\n    /**\n     * Returns singleton instance of ThreadDumpSupport.\n     * \n     * @return singleton instance of ThreadDumpSupport.\n     */\n    public static synchronized ThreadDumpSupport getInstance() {\n        if (instance == null) instance = new ThreadDumpSupport();\n        return instance;\n    }\n    \n    \n    /**\n     * Returns SnapshotCategory instance for thread dumps.\n     * \n     * @return SnapshotCategory instance for thread dumps.\n     */\n    public SnapshotCategory<ThreadDump> getCategory() {\n        return category;\n    }\n    \n    /**\n     * Returns true if taking thread dumps is supported for the application, false otherwise.\n     * \n     * @param application application from which to take the thread dump.\n     * @return true if taking thread dumps is supported for the application, false otherwise.\n     */\n    public boolean supportsThreadDump(Application application) {\n        if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n        return JvmFactory.getJVMFor(application).isTakeThreadDumpSupported();\n    }\n    \n    /**\n     * Takes thread dump from Application.\n     * \n     * @param application Application to take the thread dump,\n     * @param openView true if taken thread dump should be opened, false otherwise.\n     */\n    public void takeThreadDump(Application application, boolean openView) {\n        threadDumpProvider.createThreadDump(application, openView);\n    }\n    \n    /**\n     * Takes thread dump from CoreDump.\n     * \n     * @param coreDump CoreDump to take the thread dump,\n     * @param openView true if taken thread dump should be opened, false otherwise.\n     */\n    public void takeThreadDump(CoreDump coreDump, boolean openView) {\n        threadDumpProvider.createThreadDump(coreDump, openView);\n    }\n    \n    /**\n     * Returns PluggableDataSourceViewProvider for thread dumps.\n     * \n     * @return PluggableDataSourceViewProvider for thread dumps.\n     */\n    public PluggableDataSourceViewProvider<ThreadDump> getThreadDumpView() {\n        return threadDumpViewProvider;\n    }\n\n\n    private ThreadDumpSupport() {\n        DataSourceDescriptorFactory.getDefault().registerProvider(new ThreadDumpDescriptorProvider());\n        threadDumpProvider = new ThreadDumpProvider();\n        threadDumpProvider.initialize();\n        \n        threadDumpViewProvider = new ThreadDumpViewProvider();\n        \n        RegisteredSnapshotCategories.sharedInstance().registerCategory(category);\n        \n        threadDumpViewProvider.initialize();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/impl/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\n\nMSG_Thread_Dump=&Thread Dump\n\nLBL_Thread_Dump=Thread Dump\n\nMSG_Thread_Dumps=Thread Dumps\n\nMSG_Cannot_take_thread_dump_for_=Cannot take thread dump for \n\nMSG_Creating_Thread_Dump=Creating Thread Dump...\n\nMSG_Loading_Thread_Dump=Loading Thread Dump...\n\nArgument_ShortDescr=take thread dump of the provided process\n\nMSG_NO_APP_PID = Cannot find application with pid {0}.\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/impl/ThreadDumpAction.java",
    "content": "/*\n *  Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\npackage org.graalvm.visualvm.threaddump.impl;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.datasupport.Stateful;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.ui.actions.ActionUtils;\nimport org.graalvm.visualvm.core.ui.actions.MultiDataSourceAction;\nimport org.graalvm.visualvm.threaddump.ThreadDumpSupport;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.openide.util.NbBundle;\n\n    \n/**\n *\n * @author Jiri Sedlacek\n */\nclass ThreadDumpAction extends MultiDataSourceAction<DataSource> {\n    \n    private Set<Application> lastSelectedApplications = new HashSet<>();\n    private final PropertyChangeListener stateListener = new PropertyChangeListener() {\n        public void propertyChange(PropertyChangeEvent evt) {\n            updateState(ActionUtils.getSelectedDataSources());\n        }\n    };\n    \n    private static ThreadDumpAction instance;\n    \n    public static synchronized ThreadDumpAction instance() {\n        if (instance == null) \n            instance = new ThreadDumpAction();\n        return instance;\n    }\n    \n    \n    protected void actionPerformed(Set<DataSource> dataSources, ActionEvent actionEvent) {\n        for (DataSource dataSource : dataSources) {\n            if (dataSource instanceof Application) {\n                Application application = (Application)dataSource;\n                ThreadDumpSupport.getInstance().takeThreadDump(application, (actionEvent.getModifiers() &\n                        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n            } else if (dataSource instanceof CoreDump) {\n                CoreDump coreDump = (CoreDump)dataSource;\n                ThreadDumpSupport.getInstance().takeThreadDump(coreDump, (actionEvent.getModifiers() &\n                        Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) == 0);\n            }\n        }\n    }\n    \n    \n    protected boolean isEnabled(Set<DataSource> dataSources) {\n        for (DataSource dataSource : dataSources)\n            if (dataSource instanceof Application) {\n                // TODO: Listener should only be registered when thread dump is supported for the application\n                Application application = (Application)dataSource;\n                    lastSelectedApplications.add(application);\n                application.addPropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n                if (application.getState() != Stateful.STATE_AVAILABLE) return false;\n                if (!ThreadDumpSupport.getInstance().supportsThreadDump((Application)dataSource)) return false;\n            } else if (!(dataSource instanceof CoreDump)) return false;\n        return true;\n    }\n    \n    protected void updateState(Set<DataSource> dataSources) {\n        if (!lastSelectedApplications.isEmpty())\n            for (Application application : lastSelectedApplications)\n                application.removePropertyChangeListener(Stateful.PROPERTY_STATE, stateListener);\n        lastSelectedApplications.clear();\n        super.updateState(dataSources);\n    }\n    \n    \n    private ThreadDumpAction() {\n        super(DataSource.class);\n        putValue(NAME, NbBundle.getMessage(ThreadDumpAction.class, \"MSG_Thread_Dump\"));  // NOI18N\n        putValue(SHORT_DESCRIPTION, NbBundle.getMessage(ThreadDumpAction.class, \"LBL_Thread_Dump\"));     // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/impl/ThreadDumpArgument.java",
    "content": "/*\n * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.threaddump.impl;\n\nimport java.util.Collections;\nimport java.util.Map;\nimport java.util.Set;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.ApplicationFinder;\nimport org.graalvm.visualvm.threaddump.ThreadDumpSupport;\nimport org.netbeans.api.sendopts.CommandException;\nimport org.netbeans.spi.sendopts.Env;\nimport org.netbeans.spi.sendopts.Option;\nimport org.netbeans.spi.sendopts.OptionProcessor;\nimport org.openide.DialogDisplayer;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\nimport org.openide.util.lookup.ServiceProvider;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@ServiceProvider(service=OptionProcessor.class)\npublic final class ThreadDumpArgument extends OptionProcessor {\n    \n    private static final String LONG_NAME = \"threaddump\";                       // NOI18N\n    private static final Option ARGUMENT = Option.shortDescription(Option.requiredArgument(Option.NO_SHORT_NAME, LONG_NAME), \"org.graalvm.visualvm.threaddump.impl.Bundle\", \"Argument_ShortDescr\"); // NOI18N\n    \n    \n    @Override\n    protected Set<Option> getOptions() {\n        return Collections.singleton(ARGUMENT);\n    }\n    \n    @Override\n    protected void process(Env env, Map<Option, String[]> maps) throws CommandException {\n        String[] pids = maps.get(ARGUMENT);\n        if (pids != null && pids.length == 1) {\n            try {\n                int pid = Integer.valueOf(pids[0]);\n                new ApplicationFinder(pid) {\n                    @Override\n                    public void found(Application application) {\n                        ThreadDumpSupport.getInstance().takeThreadDump(application, true);\n                    }\n                    @Override\n                    public void notFound(int pid, String id) {\n                        NotifyDescriptor desc = new NotifyDescriptor.Message(NbBundle.getMessage(ThreadDumpArgument.class, \"MSG_NO_APP_PID\", new Object[] { Integer.toString(pid) }), NotifyDescriptor.WARNING_MESSAGE);\n                        DialogDisplayer.getDefault().notifyLater(desc);\n                    }\n                }.find();\n            } catch (NumberFormatException e) {\n                throw new CommandException(0, \"Incorrect pid format for --\" + LONG_NAME + \": \" + e.getMessage()); // NOI18N\n            }\n        } else {\n            throw new CommandException(0, \"--\" + LONG_NAME + \" requires exactly one value\"); // NOI18N\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/impl/ThreadDumpCategory.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.threaddump.impl;\n\nimport org.graalvm.visualvm.core.snapshot.SnapshotCategory;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.threaddump.ThreadDump;\nimport java.io.File;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ThreadDumpCategory extends SnapshotCategory<ThreadDump> {\n    \n    private static final String NAME = org.openide.util.NbBundle.getMessage(ThreadDumpCategory.class, \"MSG_Thread_Dumps\"); // NOI18N\n    private static final String PREFIX = \"threaddump\";   // NOI18N\n    private static final String SUFFIX = \".tdump\";   // NOI18N\n    \n    public ThreadDumpCategory() {\n        super(NAME, ThreadDump.class, PREFIX, SUFFIX, 10);\n    }\n    \n    public boolean supportsOpenSnapshot() {\n        return true;\n    }\n    \n    public void openSnapshot(File file) {\n        DataSourceWindowManager.sharedInstance().openDataSource(new ThreadDumpImpl(file, null)); // TODO: instance should be created by ThreadDumpProvider!\n    }\n\n}\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/impl/ThreadDumpDescriptorProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.threaddump.impl;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.threaddump.ThreadDump;\nimport org.graalvm.visualvm.core.model.AbstractModelProvider;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.threaddump.ThreadDumpDescriptor;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class ThreadDumpDescriptorProvider extends AbstractModelProvider<DataSourceDescriptor,DataSource> {\n    \n    public ThreadDumpDescriptorProvider() {\n    }\n    \n    public DataSourceDescriptor createModelFor(DataSource ds) {\n        if (ds instanceof ThreadDump) {\n            return new ThreadDumpDescriptor((ThreadDump) ds);\n        }\n        return null;\n    }\n    \n    \n\n}\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/impl/ThreadDumpImpl.java",
    "content": "/*\n * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.threaddump.impl;\n\nimport org.graalvm.visualvm.threaddump.ThreadDump;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport java.io.File;\n\n/**\n *\n * @author Jiri Sedlacek\n */\nfinal class ThreadDumpImpl extends ThreadDump {\n\n    ThreadDumpImpl(File file, DataSource master) {\n        super(file, master);\n    }\n    \n    \n    void forceViewClosable(boolean closable) {\n        getStorage().setCustomProperty(PROPERTY_VIEW_CLOSABLE, Boolean.toString(closable));\n    }\n\n}\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/impl/ThreadDumpProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.threaddump.impl;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.coredump.CoreDump;\nimport org.graalvm.visualvm.core.datasource.DataSourceRepository;\nimport org.graalvm.visualvm.core.datasupport.DataChangeEvent;\nimport org.graalvm.visualvm.core.datasupport.DataChangeListener;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.application.jvm.Jvm;\nimport org.graalvm.visualvm.application.jvm.JvmFactory;\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.datasource.Storage;\nimport org.graalvm.visualvm.core.snapshot.Snapshot;\nimport org.graalvm.visualvm.core.ui.DataSourceWindowManager;\nimport org.graalvm.visualvm.threaddump.ThreadDumpSupport;\nimport org.graalvm.visualvm.tools.sa.SaModel;\nimport org.graalvm.visualvm.tools.sa.SaModelFactory;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.io.PrintWriter;\nimport java.nio.charset.StandardCharsets;\nimport java.util.HashSet;\nimport java.util.Set;\nimport javax.swing.SwingUtilities;\nimport org.graalvm.visualvm.application.snapshot.ApplicationSnapshot;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.netbeans.api.progress.ProgressHandle;\nimport org.openide.DialogDisplayer;\nimport org.openide.ErrorManager;\nimport org.openide.NotifyDescriptor;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\npublic class ThreadDumpProvider {\n    \n    public void createThreadDump(final Application application, final boolean openView) {\n         VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                Jvm jvm = JvmFactory.getJVMFor(application);\n                if (!jvm.isTakeThreadDumpSupported()) {\n                    DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.\n                            Message(NbBundle.getMessage(ThreadDumpProvider.class,\n                            \"MSG_Cannot_take_thread_dump_for_\") + DataSourceDescriptorFactory. // NOI18N\n                            getDescriptor(application).getName(), NotifyDescriptor.ERROR_MESSAGE));\n                    return;\n                }\n                \n                ProgressHandle pHandle = null;\n                try {\n                    pHandle = ProgressHandle.createHandle(NbBundle.getMessage(ThreadDumpProvider.class, \"MSG_Creating_Thread_Dump\"));     // NOI18N\n                    pHandle.setInitialDelay(0);\n                    pHandle.start();\n                    String threadDumpString = jvm.takeThreadDump();\n                    if (threadDumpString != null) {\n                        try {\n                            File snapshotDir = application.getStorage().getDirectory();\n                            String name = ThreadDumpSupport.getInstance().getCategory().createFileName();\n                            File dumpFile = new File(snapshotDir,name);\n                            try (PrintWriter pw = new PrintWriter(dumpFile, \"UTF-8\")) {     // NOI18N\n                                pw.write(threadDumpString);\n                            }\n                            final ThreadDumpImpl threadDump = new ThreadDumpImpl(dumpFile, application);\n                            application.getRepository().addDataSource(threadDump);\n                            if (openView) DataSource.EVENT_QUEUE.post(new Runnable() {\n                                public void run() { DataSourceWindowManager.sharedInstance().openDataSource(threadDump); }\n                            });\n                        } catch (IOException ex) {\n                            ErrorManager.getDefault().notify(ex);\n                        }\n                    }\n                } finally {\n                    final ProgressHandle pHandleF = pHandle;\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { if (pHandleF != null) pHandleF.finish(); }\n                    });\n                }\n            }\n        });\n    }\n    \n    public void createThreadDump(final CoreDump coreDump, final boolean openView) {\n        VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n                ProgressHandle pHandle = null;\n                try {\n                    pHandle = ProgressHandle.createHandle(NbBundle.getMessage(ThreadDumpProvider.class, \"MSG_Creating_Thread_Dump\"));     // NOI18N\n                    pHandle.setInitialDelay(0);\n                    pHandle.start();\n                    File snapshotDir = coreDump.getStorage().getDirectory();\n                    String name = ThreadDumpSupport.getInstance().getCategory().createFileName();\n                    File dumpFile = new File(snapshotDir,name);\n                    SaModel saAget = SaModelFactory.getSAAgentFor(coreDump);\n                    String dump = saAget.takeThreadDump();\n                    if (dump != null) {\n                        try (OutputStream os = new FileOutputStream(dumpFile)) {\n                            os.write(dump.getBytes(StandardCharsets.UTF_8));\n                            final ThreadDumpImpl threadDump = new ThreadDumpImpl(dumpFile, coreDump);\n                            coreDump.getRepository().addDataSource(threadDump);\n                            if (openView) DataSource.EVENT_QUEUE.post(new Runnable() {\n                                public void run() { DataSourceWindowManager.sharedInstance().openDataSource(threadDump); }\n                            });\n                        } catch (Exception ex) {\n                            ErrorManager.getDefault().notify(ex);\n                        }\n                    }\n                } finally {\n                    final ProgressHandle pHandleF = pHandle;\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { if (pHandleF != null) pHandleF.finish(); }\n                    });\n                }\n            }\n        });\n    }\n    \n    public void initialize() {\n        DataSourceRepository.sharedInstance().addDataChangeListener(new SnapshotListener(), Snapshot.class);\n        DataSourceRepository.sharedInstance().addDataChangeListener(new ApplicationListener(), Application.class);\n    }\n    \n    \n    private void processNewSnapshot(Snapshot snapshot) {\n        if (snapshot instanceof ThreadDumpImpl) return;\n        boolean appSnapshot = snapshot instanceof ApplicationSnapshot;\n        File snapshotFile = snapshot.getFile();\n        if (snapshotFile != null && snapshotFile.isDirectory()) {\n            File[] files = snapshotFile.listFiles(ThreadDumpSupport.getInstance().getCategory().getFilenameFilter());\n            if (files == null) return;\n            Set<ThreadDumpImpl> threadDumps = new HashSet<>();\n            for (File file : files) {\n                ThreadDumpImpl threadDump = new ThreadDumpImpl(file, snapshot);\n                if (appSnapshot) threadDump.forceViewClosable(true);\n                threadDumps.add(new ThreadDumpImpl(file, snapshot));\n            }\n            snapshot.getRepository().addDataSources(threadDumps);\n        }\n    }\n    \n    private void processNewApplication(Application application) {\n        Storage storage = application.getStorage();\n        if (storage.directoryExists()) {\n            File[] files = storage.getDirectory().listFiles(ThreadDumpSupport.getInstance().getCategory().getFilenameFilter());\n            if (files == null) return;\n            Set<ThreadDumpImpl> threadDumps = new HashSet<>();\n            for (File file : files) threadDumps.add(new ThreadDumpImpl(file, application));\n            application.getRepository().addDataSources(threadDumps);\n        }\n    }\n    \n    \n    private class SnapshotListener implements DataChangeListener<Snapshot> {\n        \n        public void dataChanged(DataChangeEvent<Snapshot> event) {\n            final Set<Snapshot> snapshots = event.getAdded();\n            if (!snapshots.isEmpty()) VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    for (Snapshot snapshot : snapshots) processNewSnapshot(snapshot);\n                }\n            });\n        }\n        \n    }\n    \n    private class ApplicationListener implements DataChangeListener<Application> {\n        \n        public void dataChanged(DataChangeEvent<Application> event) {\n            final Set<Application> applications = event.getAdded();\n            if (!applications.isEmpty()) VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    for (Application application : applications) processNewApplication(application);\n                }\n            });\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/impl/ThreadDumpView.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.threaddump.impl;\n\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptor;\nimport org.graalvm.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;\nimport org.graalvm.visualvm.threaddump.ThreadDump;\nimport org.graalvm.visualvm.core.ui.components.DataViewComponent;\nimport org.graalvm.visualvm.core.ui.components.ScrollableContainer;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Arrays;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.swing.BorderFactory;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.SwingConstants;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.Document;\nimport javax.swing.text.Segment;\nimport javax.swing.text.html.HTMLDocument;\nimport javax.swing.text.html.HTMLEditorKit;\nimport javax.swing.text.html.StyleSheet;\nimport org.graalvm.visualvm.core.VisualVM;\nimport org.graalvm.visualvm.core.snapshot.SnapshotView;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextArea;\nimport org.graalvm.visualvm.lib.ui.components.HTMLTextAreaSearchUtils;\nimport org.graalvm.visualvm.uisupport.UISupport;\nimport org.openide.util.NbBundle;\n\n/**\n *\n * @author Jiri Sedlacek\n * @author Tomas Hurka\n */\nclass ThreadDumpView extends SnapshotView {\n    private static final Logger LOGGER = Logger.getLogger(ThreadDumpView.class.getName());\n    \n    ThreadDumpView(ThreadDump threadDump) {\n        this(threadDump, DataSourceDescriptorFactory.getDescriptor(threadDump));\n    }\n    \n    private ThreadDumpView(ThreadDump threadDump, DataSourceDescriptor descriptor) {\n        super(threadDump, descriptor.getName(), descriptor.getIcon(), 0);\n    }\n        \n    protected DataViewComponent createComponent() {\n        ThreadDump threadDump = (ThreadDump)getDataSource();\n        DataViewComponent dvc = new DataViewComponent(\n                new MasterViewSupport(threadDump).getMasterView(),\n                new DataViewComponent.MasterViewConfiguration(true));\n        \n        return dvc;\n    }\n    \n    \n    // --- General data --------------------------------------------------------\n    \n    private static class MasterViewSupport extends JPanel  {\n        \n        private JLabel progressLabel;\n        private JPanel contentsPanel;\n        \n        MasterViewSupport(ThreadDump threadDump) {\n            initComponents();\n            loadThreadDump(threadDump.getFile());\n        }\n        \n        \n        public DataViewComponent.MasterView getMasterView() {\n            return new DataViewComponent.MasterView(NbBundle.getMessage(ThreadDumpView.class, \"LBL_Thread_Dump\"), null, this);  // NOI18N\n        }\n        \n        \n        private void initComponents() {\n            setLayout(new BorderLayout());\n            \n            progressLabel = new JLabel(NbBundle.getMessage(ThreadDumpView.class, \"MSG_Loading_Thread_Dump\"), SwingConstants.CENTER);     // NOI18N\n        \n            contentsPanel = new JPanel(new BorderLayout());\n            contentsPanel.add(progressLabel, BorderLayout.CENTER);\n            contentsPanel.setOpaque(false);\n            \n            add(contentsPanel, BorderLayout.CENTER);\n            setOpaque(false);\n        }\n\n        private static String htmlize(String value) {\n            return value.replace(\"&\", \"&amp;\").replace(\"<\", \"&lt;\").replace(\"\\t\", \"        \");     // NOI18N\n        }\n\n        private static String transform(String value) {\n            String alternateColor = !UISupport.isDarkResultsBackground() ? \"#0033CC\" : \"#FFCC33\"; // NOI18N\n            StringBuilder sb = new StringBuilder();\n            String[] result = value.split(\"\\\\r?\\\\n\"); // NOI18N\n            for (String line : result) {\n                if (!line.isEmpty() && !Character.isWhitespace(line.charAt(0))) {\n                    sb.append(\"<span style=\\\"color: \").append(alternateColor).append(\"\\\">\"); // NOI18N\n                    sb.append(line);\n                    sb.append(\"</span><br>\"); // NOI18N\n                } else {\n                    sb.append(line);\n                    sb.append(\"<br>\"); // NOI18N\n                }\n            }\n            return sb.toString();\n        }\n\n        private void loadThreadDump(final File file) {\n            VisualVM.getInstance().runTask(new Runnable() {\n            public void run() {\n              try (InputStream is = new FileInputStream(file)) {\n                byte[] data = new byte[(int)file.length()];\n                try {\n                  is.read(data);\n                } catch (IOException ex) {\n                  LOGGER.log(Level.INFO, \"Failed to read thread dump\", ex);     // NOI18N\n                }\n                try {\n                  HTMLTextArea area = new HTMLTextArea();\n                  area.setEditorKit(new CustomHtmlEditorKit());\n                  area.setForeground(!UISupport.isDarkResultsBackground() ? new Color(0xcc, 0x33, 0) : new Color(0x33, 0xcc, 0xff));\n                  area.setText(\"<pre>\" + transform(htmlize(new String(data, StandardCharsets.UTF_8))) + \"</pre>\"); // NOI18N\n                  area.setCaretPosition(0);\n                  area.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8));\n                  contentsPanel.remove(progressLabel);\n                  contentsPanel.add(new ScrollableContainer(area), BorderLayout.CENTER);\n                  contentsPanel.add(HTMLTextAreaSearchUtils.createSearchPanel(area), BorderLayout.SOUTH);\n                  contentsPanel.revalidate();\n                  contentsPanel.repaint();\n//                  contentsPanel.doLayout();\n                } catch (Exception ex) {\n                  LOGGER.throwing(ThreadDumpView.class.getName(), \"loadThreadDump\", ex);     // NOI18N\n                }\n              } catch (IOException ex) {\n                LOGGER.log(Level.INFO, \"Failed to load thread dump\", ex);       // NOI18N\n              }\n           }\n          });\n        }\n        \n    }\n\n    private static class CustomHtmlEditorKit extends HTMLEditorKit {\n\n        @Override\n        public Document createDefaultDocument() {\n            StyleSheet styles = getStyleSheet();\n            StyleSheet ss = new StyleSheet();\n\n            ss.addStyleSheet(styles);\n\n            HTMLDocument doc = new CustomHTMLDocument(ss);\n            doc.setParser(getParser());\n            doc.setAsynchronousLoadPriority(4);\n            doc.setTokenThreshold(100);\n            return doc;\n        }\n    }\n    \n    private static class CustomHTMLDocument extends HTMLDocument {\n        private static final int CACHE_BOUNDARY = 1000;\n        private char[] segArray;\n        private int segOffset;\n        private int segCount;\n        private boolean segPartialReturn;\n        private int lastOffset;\n        private int lastLength;\n        \n        private CustomHTMLDocument(StyleSheet ss) {\n            super(ss);\n            lastOffset = -1;\n            lastLength = -1;\n            putProperty(\"multiByte\", Boolean.TRUE);      // NOI18N\n        }\n\n        @Override\n        public void getText(int offset, int length, Segment txt) throws BadLocationException {\n            if (lastOffset == offset && lastLength == length) {\n                txt.array = segArray;\n                txt.offset = segOffset;\n                txt.count = segCount;\n                txt.setPartialReturn(segPartialReturn);\n                return;\n            }\n            super.getText(offset, length, txt);\n            if (length > CACHE_BOUNDARY || lastLength <= CACHE_BOUNDARY) {\n                segArray = Arrays.copyOf(txt.array, txt.array.length);\n                segOffset = txt.offset;\n                segCount = txt.count;\n                segPartialReturn = txt.isPartialReturn();\n                lastOffset = offset;\n                lastLength = length;\n            }\n        }\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/impl/ThreadDumpViewProvider.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.threaddump.impl;\n\nimport org.graalvm.visualvm.threaddump.ThreadDump;\nimport org.graalvm.visualvm.core.ui.DataSourceView;\nimport org.graalvm.visualvm.core.ui.DataSourceViewsManager;\nimport org.graalvm.visualvm.core.ui.PluggableDataSourceViewProvider;\nimport java.util.Set;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic class ThreadDumpViewProvider extends PluggableDataSourceViewProvider<ThreadDump>{\n    \n    protected boolean supportsViewFor(ThreadDump threadDump) {\n        return true;\n    }\n    \n    protected DataSourceView createView(ThreadDump threadDump) {\n        return new ThreadDumpView(threadDump);\n    }\n    \n    public Set<Integer> getPluggableLocations(DataSourceView view) {\n        return ALL_LOCATIONS;\n    }\n    \n\n    public void initialize() {\n        DataSourceViewsManager.sharedInstance().addViewProvider(this, ThreadDump.class);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Support for thread dumps in VisualVM.\n */\npackage org.graalvm.visualvm.threaddump;\n"
  },
  {
    "path": "visualvm/threaddump/src/org/graalvm/visualvm/threaddump/resources/layer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n<filesystem>\n    \n    <folder name=\"Menu\">\n        <folder name=\"Applications\">\n            <file name=\"org-graalvm-visualvm-threaddump-impl-ThreadDumpAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-threaddump-impl-ThreadDumpAction.instance\"/>\n                <attr name=\"position\" intvalue=\"2100\"/>\n            </file>\n        </folder>\n    </folder>\n    \n    <folder name=\"VisualVM\">\n        <folder name=\"Actions\">\n            <file name=\"org-graalvm-visualvm-threaddump-impl-ThreadDumpAction.instance\">\n                <attr name=\"instanceCreate\" methodvalue=\"org.graalvm.visualvm.threaddump.impl.ThreadDumpAction.instance\"/>\n            </file>\n        </folder>\n\n        <folder name=\"ExplorerPopupSelection\">\n            \n            <file name=\"org-graalvm-visualvm-threaddump-impl-ThreadDumpAction.shadow\">\n                <attr name=\"originalFile\" stringvalue=\"VisualVM/Actions/org-graalvm-visualvm-threaddump-impl-ThreadDumpAction.instance\"/>\n                <attr name=\"position\" intvalue=\"1100\"/>\n            </file>\n            \n        </folder>\n    </folder>\n    \n</filesystem>\n"
  },
  {
    "path": "visualvm/tools/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.tools\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.tools.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/tools/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nAutoUpdate-Essential-Module: true\nOpenIDE-Module: org.graalvm.visualvm.tools/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/tools/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.4\n\n"
  },
  {
    "path": "visualvm/tools/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.tools-impl\" basedir=\"..\">\n    <fail message=\"Please build using Ant 1.7.1 or higher.\">\n        <condition>\n            <not>\n                <antversion atleast=\"1.7.1\"/>\n            </not>\n        </condition>\n    </fail>\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <macrodef name=\"evalprops\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"property\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{property}\" value=\"@{value}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject2:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:property name=\"nbplatform.active.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <nbmproject2:evalprops property=\"cluster.path.evaluated\" value=\"${cluster.path}\" xmlns:nbmproject2=\"http://www.netbeans.org/ns/nb-module-project/2\"/>\n    <fail message=\"Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).\">\n        <condition>\n            <not>\n                <contains string=\"${cluster.path.evaluated}\" substring=\"platform\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/tools/nbproject/genfiles.properties",
    "content": "build.xml.data.CRC32=b4a6acdd\nbuild.xml.script.CRC32=1c5420ee\nbuild.xml.stylesheet.CRC32=a56c6a5b@2.73\n# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\n# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\nnbproject/build-impl.xml.data.CRC32=b4a6acdd\nnbproject/build-impl.xml.script.CRC32=76c14d7d\nnbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.73\n"
  },
  {
    "path": "visualvm/tools/nbproject/project.properties",
    "content": "javac.compilerargs=-Xlint -Xlint:-serial\njavac.source=1.8\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\n\n"
  },
  {
    "path": "visualvm/tools/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.tools</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.application</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.core</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <public-packages>\n                <package>org.graalvm.visualvm.tools.attach</package>\n                <package>org.graalvm.visualvm.tools.jfr</package>\n                <package>org.graalvm.visualvm.tools.jmx</package>\n                <package>org.graalvm.visualvm.tools.jvmstat</package>\n                <package>org.graalvm.visualvm.tools.sa</package>\n            </public-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/tools/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nOpenIDE-Module-Display-Category=Infrastructure\nOpenIDE-Module-Name=VisualVM-Tools\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/attach/AttachModel.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.attach;\n\nimport java.util.Map;\nimport java.util.Properties;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram;\nimport org.graalvm.visualvm.core.model.Model;\n\n/**\n * This class uses <a href=http://download.oracle.com/javase/6/docs/technotes/guides/attach/index.html>Attach API</a> \n * to obtain various information from JVM. Note that\n * Attach API is available in JDK 6 and up and only for local processes running as the\n * same user. See Attach API documentation for mode details.\n * \n * @author Tomas Hurka\n */\npublic abstract class AttachModel extends Model {\n\n    /**\n     * Returns the current system properties in the target Application.\n     * \n     * <p> This method returns the system properties in the target virtual\n     * machine. Properties whose key or value is not a <tt>String</tt> are \n     * omitted. The method is approximately equivalent to the invocation of the\n     * method {@link java.lang.System#getProperties System.getProperties}\n     * in the target virtual machine except that properties with a key or\n     * value that is not a <tt>String</tt> are not included.\n     * @return The system properties of target Application\n     * @see java.lang.System#getProperties\n     */\n    public abstract Properties getSystemProperties();\n    \n    /**\n     * Takes heap dump of target Application.\n     * The heap is written to the <tt>fileName</tt> file in the same\n     * format as the hprof heap dump.\n     * @return returns <CODE>true</CODE> if operation was successful.\n     * @param fileName {@link String} where heap dump will be stored.\n     */\n    public abstract boolean takeHeapDump(String fileName);\n    \n    /**\n     * Takes thread dump of target Application.\n     * @return Returns {@link String} of the thread dump from target Application.\n     */\n    public abstract String takeThreadDump();\n    \n    /**\n     * Takes heap histogram of target Application.\n     * @return Returns {@link HeapHistogram} of the heap from target Application.\n     */\n    public abstract HeapHistogram takeHeapHistogram();\n    \n    /**\n     * print VM option.\n     * Note that VM option is the one which starts with <CODE>-XX:</CODE>.\n     * @param name name of VM option. For example <CODE>HeapDumpOnOutOfMemoryError</CODE>\n     * @return Full text of VM option. For example <CODE>-XX:+HeapDumpOnOutOfMemoryError</CODE>\n     */\n    public abstract String printFlag(String name);\n    \n    /**\n     * Sets a VM option of the given name to the specified value. \n     *\n     * @param name Name of a VM option \n     * @param value New value of the VM option to be set \n     */\n    public abstract void setFlag(String name,String value);\n\n    /**\n     * Returns the Java virtual machine command line.\n     *\n     * @return String - contains the command line of the target Java\n     *                  application or <CODE>NULL</CODE> if the\n     *                  command line cannot be determined.\n     */\n    public abstract String getCommandLine();\n\n    /**\n     * Returns the Java virtual machine command line arguments.\n     *\n     * @return String - contains the command line arguments of the target Java\n     *                  application or <CODE>NULL</CODE> if the\n     *                  command line arguments cannot be determined.\n     */\n    public abstract String getJvmArgs();\n\n    /**\n     * Returns the Java virtual machine flags.\n     *\n     * @return String - contains the flags of the target Java\n     *                  application or <CODE>NULL</CODE> if the\n     *                  flags cannot be determined.\n     */\n    public abstract String getJvmFlags();\n\n    public abstract String executeJCmd(String command, Map<String,Object> pars);\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/attach/AttachModelFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.attach;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.ModelFactory;\n\n/**\n * The AttachModelFactory class is a factory class for getting the\n * {@link AttachModel} representation  for the {@link Application}.\n * \n * @author Tomas Hurka\n */\npublic final class AttachModelFactory extends ModelFactory<AttachModel, Application> {\n\n    private static AttachModelFactory attachFactory;\n\n    private AttachModelFactory() {\n    }\n\n    /**\n     * Getter for the default version of the AttachModelFactory.\n     * @return instance of {@link AttachModelFactory}.\n     */\n    public static synchronized AttachModelFactory getDefault() {\n        if (attachFactory == null) {\n            attachFactory = new AttachModelFactory();\n        }\n        return attachFactory;\n    }\n    \n    /**\n     * Factory method for obtaining {@link AttachModel} for {@link Application}. Note that there\n     * is only one instance of {@link AttachModel} for a concrete application. This {@link AttachModel}\n     * instance is cached. This method can return <CODE>null</CODE> if there is no AttachModel\n     * available\n     * @param app application\n     * @return {@link AttachModel} instance or <CODE>null</CODE> if there is no\n     * {@link AttachModel}\n     */\n    public static AttachModel getAttachFor(Application app) {\n        return getDefault().getModel(app);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/attach/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Attach API support in VisualVM.\n */\npackage org.graalvm.visualvm.tools.attach;\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jfr/JfrModel.java",
    "content": "/*\n * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.tools.jfr;\n\nimport java.util.List;\nimport org.graalvm.visualvm.core.model.Model;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic abstract class JfrModel extends Model {\n\n    /**\n     * Checks running JFR recording(s) of target Application.\n     *\n     * @return returns List of recording id-s. If no recordings are in progress,\n     * empty List is returned.\n     */\n    public abstract List<Long> jfrCheck();\n\n    /**\n     * Takes JFR dump of target Application. The JFR snapshot is written to the\n     * <tt>fileName</tt> file.\n     *\n     * @param recording id of recording obtained using {@link #jfrCheck()}\n     * @param fileName path to file, where JFR snapshot will be written\n     * @return returns <CODE>null</CODE> if operation was successful.\n     */\n    public abstract String takeJfrDump(long recording, String fileName);\n\n    /**\n     * Starts a new JFR recording.\n     *\n     * @param name optional name that can be used to identify recording.\n     * @param settings names of settings files to use, i.e. \"default\" or\n     * \"default.jfc\".\n     * @param delay optional delay recording start with (s)econds, (m)inutes,\n     * (h)ours, or (d)ays, e.g. 5h.\n     * @param duration optional duration of recording in (s)econds, (m)inutes,\n     * (h)ours, or (d)ays, e.g. 300s.\n     * @param disk if recording should be persisted to disk\n     * @param path file path where recording data should be written\n     * @param maxAge optional maximum time to keep recorded data (on disk) in\n     * (s)econds, (m)inutes, (h)ours, or (d)ays, e.g. 60m, or <code>0</code> if\n     * no limit should be set.\n     * @param maxSize optional maximum amount of bytes to keep (on disk) in\n     * (k)B, (M)B or (G)B, e.g. 500M, or <code>0</code> if no limit should be\n     * set.\n     * @param dumpOnExit if recording should dump on exit\n     *\n     * @return true if recording was successfully started.\n     */\n    public abstract boolean startJfrRecording(String name, String[] settings,\n            String delay, String duration, Boolean disk, String path,\n            String maxAge, String maxSize, Boolean dumpOnExit);\n\n    /**\n     * Stops JFR recording.\n     *\n     * @return true if recording was successfully stopped.\n     */\n    public abstract boolean stopJfrRecording();\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jfr/JfrModelFactory.java",
    "content": "/*\n * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.tools.jfr;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.ModelFactory;\n\n/**\n *\n * @author Tomas Hurka\n */\npublic class JfrModelFactory extends ModelFactory<JfrModel, Application> {\n\n    private static JfrModelFactory jfrFactory;\n\n    private JfrModelFactory() {\n    }\n\n    /**\n     * Getter for the default version of the JFRModelFactory.\n     *\n     * @return instance of {@link JfrModelFactory}.\n     */\n    public static synchronized JfrModelFactory getDefault() {\n        if (jfrFactory == null) {\n            jfrFactory = new JfrModelFactory();\n        }\n        return jfrFactory;\n    }\n\n    /**\n     * Factory method for obtaining {@link JfrModel} for {@link Application}.\n     * Note that there is only one instance of {@link JfrModel} for a concrete\n     * application. This {@link JfrModel} instance is cached. This method can\n     * return <CODE>null</CODE> if there is no JFRModel available\n     *\n     * @param app application\n     * @return {@link JfrModel} instance or <CODE>null</CODE> if there is no\n     * {@link JfrModel}\n     */\n    public static JfrModel getJFRFor(Application app) {\n        return getDefault().getModel(app);\n    }\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jmx/CachedMBeanServerConnection.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jmx;\n\nimport javax.management.MBeanServerConnection;\n\n/**\n * <p>Cached MBeanServerConnection:</p>\n *\n * <p>This is an object that wraps an existing MBeanServerConnection and adds\n * caching to it, as follows:</p>\n *\n * <ul>\n * <li>The first time an attribute is called in a given MBean, the result is\n * cached. Every subsequent time getAttribute is called for that attribute\n * the cached result is returned.</li>\n * <li>When the {@link CachedMBeanServerConnection#flush()} method is invoked the\n * attributes cache is flushed. Then any subsequent call to getAttribute will\n * retrieve all the values for the attributes that are known to the cache.</li>\n * <li>The attributes cache uses a learning approach and only the attributes\n * that are in the cache will be retrieved between two subsequent updates.</li>\n * </ul>\n *\n * @author Eamonn McManus\n * @author Luis-Miguel Alventosa\n */\npublic interface CachedMBeanServerConnection extends MBeanServerConnection, MBeanCacheOperations {\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jmx/CachedMBeanServerConnectionFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jmx;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.IOException;\nimport java.lang.ref.WeakReference;\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Proxy;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.TreeSet;\nimport java.util.WeakHashMap;\nimport java.util.concurrent.CopyOnWriteArrayList;\nimport javax.management.Attribute;\nimport javax.management.AttributeList;\nimport javax.management.AttributeNotFoundException;\nimport javax.management.InstanceNotFoundException;\nimport javax.management.MBeanException;\nimport javax.management.MBeanServerConnection;\nimport javax.management.ObjectName;\nimport javax.management.ReflectionException;\nimport javax.swing.Timer;\nimport org.graalvm.visualvm.core.VisualVM;\n\n/**\n * <p>The {@code CachedMBeanServerConnectionFactory} class is a factory class that\n * allows to get instances of {@link CachedMBeanServerConnection} for a given\n * {@link MBeanServerConnection} or {@link JmxModel}.</p>\n * \n * <p>The factory methods allow to supply an interval value at which the cache will\n * be automatically flushed and interested {@link MBeanCacheListener}s notified.</p>\n * \n * <p>If the factory methods which do not take an interval value are used then\n * no automatic flush is performed and the user will be in charge of flushing\n * the cache by calling {@link CachedMBeanServerConnection#flush()}.</p>\n *\n * @author Eamonn McManus\n * @author Luis-Miguel Alventosa\n */\npublic final class CachedMBeanServerConnectionFactory {\n\n    private static final Map<Integer, Map<MBeanServerConnection, WeakReference<CachedMBeanServerConnection>>> snapshots =\n            new HashMap<>();\n\n    private CachedMBeanServerConnectionFactory() {\n    }\n\n    /**\n     * <p>Factory method for obtaining the {@link CachedMBeanServerConnection} for\n     * the given {@link MBeanServerConnection}.</p>\n     * \n     * @param mbsc an MBeanServerConnection.\n     * \n     * @return a {@link CachedMBeanServerConnection} instance which caches the\n     * attribute values of the supplied {@link MBeanServerConnection}.\n     */\n    public static CachedMBeanServerConnection getCachedMBeanServerConnection(MBeanServerConnection mbsc) {\n        return getCachedMBeanServerConnection(mbsc, 0);\n    }\n\n    /**\n     * <p>Factory method for obtaining the {@link CachedMBeanServerConnection} for\n     * the given {@link MBeanServerConnection}. The cache will be flushed at the\n     * given interval and the interested {@link MBeanCacheListener}s will be notified.</p>\n     * \n     * @param mbsc an MBeanServerConnection.\n     * @param interval the interval (in milliseconds) at which the cache is flushed.\n     * An interval equal to zero means no automatic flush of the MBean cache.\n     * \n     * @return a {@link CachedMBeanServerConnection} instance which caches the\n     * attribute values of the supplied {@link MBeanServerConnection} and is\n     * flushed at the end of every interval period.\n     * \n     * @throws IllegalArgumentException if the supplied interval is negative.\n     */\n    public static CachedMBeanServerConnection\n            getCachedMBeanServerConnection(MBeanServerConnection mbsc, int interval)\n            throws IllegalArgumentException {\n        if (interval < 0) {\n            throw new IllegalArgumentException(\"interval cannot be negative\"); // NOI18N\n        }\n        return retrieveCachedMBeanServerConnection(mbsc, interval);\n    }\n\n    /**\n     * <p>Factory method for obtaining the {@link CachedMBeanServerConnection} for\n     * the given {@link JmxModel}.</p>\n     * \n     * @param jmx a JmxModel.\n     * \n     * @return a {@link CachedMBeanServerConnection} instance which caches the\n     * attribute values of the supplied {@link JmxModel}.\n     */\n    public static CachedMBeanServerConnection getCachedMBeanServerConnection(JmxModel jmx) {\n        return getCachedMBeanServerConnection(jmx.getMBeanServerConnection(), 0);\n    }\n\n    /**\n     * <p>Factory method for obtaining the {@link CachedMBeanServerConnection} for\n     * the given {@link JmxModel}. The cache will be flushed at the given interval\n     * and the interested {@link MBeanCacheListener}s will be notified.</p>\n     * \n     * @param jmx a JmxModel.\n     * @param interval the interval (in milliseconds) at which the cache is flushed.\n     * An interval equal to zero means no automatic flush of the MBean cache.\n     * \n     * @return a {@link CachedMBeanServerConnection} instance which caches the\n     * attribute values of the supplied {@link JmxModel} and is flushed at the\n     * end of every interval period.\n     *\n     * @throws IllegalArgumentException if the supplied interval is negative.\n     */\n    public static CachedMBeanServerConnection\n            getCachedMBeanServerConnection(JmxModel jmx, int interval)\n            throws IllegalArgumentException {\n        return getCachedMBeanServerConnection(jmx.getMBeanServerConnection(), interval);\n    }\n\n    private static synchronized CachedMBeanServerConnection\n            retrieveCachedMBeanServerConnection(MBeanServerConnection mbsc, int interval) {\n        Map<MBeanServerConnection, WeakReference<CachedMBeanServerConnection>> mbscMap = snapshots.get(interval);\n        if (mbscMap == null) {\n            CachedMBeanServerConnection cmbsc = Snapshot.newSnapshot(mbsc, interval);\n            Map<MBeanServerConnection, WeakReference<CachedMBeanServerConnection>> mbscMapNew = new WeakHashMap<>();\n            mbscMapNew.put(mbsc, new WeakReference<>(cmbsc));\n            snapshots.put(interval, mbscMapNew);\n            return cmbsc;\n        } else {\n            WeakReference<CachedMBeanServerConnection> cmbscRef = mbscMap.get(mbsc);\n            CachedMBeanServerConnection cmbsc = (cmbscRef == null) ? null : cmbscRef.get();\n            if (cmbsc == null) {\n                cmbsc = Snapshot.newSnapshot(mbsc, interval);\n                mbscMap.put(mbsc, new WeakReference<>(cmbsc));\n            }\n            return cmbsc;\n        }\n    }\n\n    static class Snapshot {\n\n        private Snapshot() {\n        }\n\n        public static CachedMBeanServerConnection newSnapshot(MBeanServerConnection mbsc, int interval) {\n            final InvocationHandler ih = new SnapshotInvocationHandler(mbsc, interval);\n            return (CachedMBeanServerConnection) Proxy.newProxyInstance(\n                    Snapshot.class.getClassLoader(),\n                    new Class<?>[]{CachedMBeanServerConnection.class},\n                    ih);\n        }\n    }\n\n    static class SnapshotInvocationHandler implements InvocationHandler {\n\n        private final MBeanServerConnection conn;\n        private final int interval;\n        private Timer timer = null;\n        private Map<ObjectName, NameValueMap> cachedValues = new HashMap<>();\n        private Map<ObjectName, Set<String>> cachedNames = new HashMap<>();\n        private List<MBeanCacheListener> listenerList = new CopyOnWriteArrayList<>();\n        private volatile boolean flushRunning;\n\n        @SuppressWarnings(\"serial\")\n        private static final class NameValueMap\n                extends HashMap<String, Object> {\n        }\n\n        SnapshotInvocationHandler(MBeanServerConnection conn, int interval) {\n            this.conn = conn;\n            this.interval = interval;\n            if (interval > 0) {\n                timer = new Timer(interval, new ActionListener() {\n                    public void actionPerformed(ActionEvent e) {\n                        intervalElapsed();\n                    }\n                });\n                timer.setCoalesce(true);\n                timer.start();\n            }\n        }\n\n        void intervalElapsed() {\n            if (flushRunning) return;\n            flushRunning = true;\n            VisualVM.getInstance().runTask(new Runnable() {\n                public void run() {\n                    flush();\n                    connectionPinger();\n                    notifyListeners();\n                    flushRunning = false;\n                }\n            });\n        }\n\n        void notifyListeners() {\n            for (MBeanCacheListener listener : listenerList) {\n                listener.flushed();\n            }\n        }\n\n        private void connectionPinger() {\n            try {\n                conn.getDefaultDomain();\n            } catch (Exception e) {\n                timer.stop();\n                listenerList.clear();\n                cachedValues.clear();\n                cachedNames.clear();\n                Collection<Map<MBeanServerConnection, WeakReference<CachedMBeanServerConnection>>> values = snapshots.values();\n                for (Map<MBeanServerConnection, WeakReference<CachedMBeanServerConnection>> value : values) {\n                    value.remove(conn);\n                }\n            }\n        }\n\n        synchronized void flush() {\n            cachedValues = new HashMap<>();\n        }\n\n        int getInterval() {\n            return interval;\n        }\n\n        void addMBeanCacheListener(MBeanCacheListener listener) {\n            listenerList.add(listener);\n        }\n\n        void removeMBeanCacheListener(MBeanCacheListener listener) {\n            listenerList.remove(listener);\n        }\n\n        public Object invoke(Object proxy, Method method, Object[] args)\n                throws Throwable {\n            final String methodName = method.getName();\n            if (methodName.equals(\"getAttribute\")) { // NOI18N\n                return getAttribute((ObjectName) args[0], (String) args[1]);\n            } else if (methodName.equals(\"getAttributes\")) { // NOI18N\n                return getAttributes((ObjectName) args[0], (String[]) args[1]);\n            } else if (methodName.equals(\"flush\")) { // NOI18N\n                flush();\n                return null;\n            } else if (methodName.equals(\"getInterval\")) { // NOI18N\n                return getInterval();\n            } else if (methodName.equals(\"addMBeanCacheListener\")) { // NOI18N\n                addMBeanCacheListener((MBeanCacheListener) args[0]);\n                return null;\n            } else if (methodName.equals(\"removeMBeanCacheListener\")) { // NOI18N\n                removeMBeanCacheListener((MBeanCacheListener) args[0]);\n                return null;\n            } else {\n                try {\n                    return method.invoke(conn, args);\n                } catch (InvocationTargetException e) {\n                    throw e.getCause();\n                }\n            }\n        }\n\n        private Object getAttribute(ObjectName objName, String attrName)\n                throws MBeanException, InstanceNotFoundException,\n                AttributeNotFoundException, ReflectionException, IOException {\n            final NameValueMap values = getCachedAttributes(\n                    objName, Collections.singleton(attrName));\n            Object value = values.get(attrName);\n            if (value != null || values.containsKey(attrName)) {\n                return value;\n            }\n            // Not in cache, presumably because it was omitted from the\n            // getAttributes result because of an exception.  Following\n            // call will probably provoke the same exception.\n            return conn.getAttribute(objName, attrName);\n        }\n\n        private AttributeList getAttributes(\n                ObjectName objName, String[] attrNames) throws\n                InstanceNotFoundException, ReflectionException, IOException {\n            final NameValueMap values = getCachedAttributes(\n                    objName,\n                    new TreeSet<>(Arrays.asList(attrNames)));\n            final AttributeList list = new AttributeList();\n            for (String attrName : attrNames) {\n                final Object value = values.get(attrName);\n                if (value != null || values.containsKey(attrName)) {\n                    list.add(new Attribute(attrName, value));\n                }\n            }\n            return list;\n        }\n\n        private synchronized NameValueMap getCachedAttributes(\n                ObjectName objName, Set<String> attrNames) throws\n                InstanceNotFoundException, ReflectionException, IOException {\n            NameValueMap values = cachedValues.get(objName);\n            if (values != null && values.keySet().containsAll(attrNames)) {\n                return values;\n            }\n            attrNames = new TreeSet<>(attrNames);\n            Set<String> oldNames = cachedNames.get(objName);\n            if (oldNames != null) {\n                attrNames.addAll(oldNames);\n            }\n            values = new NameValueMap();\n            final AttributeList attrs = conn.getAttributes(\n                    objName,\n                    attrNames.toArray(new String[0]));\n            for (Attribute attr : attrs.asList()) {\n                values.put(attr.getName(), attr.getValue());\n            }\n            cachedValues.put(objName, values);\n            cachedNames.put(objName, attrNames);\n            return values;\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jmx/JmxModel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jmx;\n\nimport java.beans.PropertyChangeListener;\nimport java.beans.PropertyChangeSupport;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.regex.Pattern;\nimport javax.management.MBeanServerConnection;\nimport javax.management.remote.JMXServiceURL;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.application.jvm.HeapHistogram;\nimport org.graalvm.visualvm.core.datasupport.AsyncPropertyChangeSupport;\nimport org.graalvm.visualvm.core.model.Model;\n\n/**\n * <p>This class encapsulates the JMX functionality of the target Java application.</p>\n *\n * <p>Call {@link JmxModelFactory#getJmxModelFor(Application)} to get an instance of the\n * {@link JmxModel} class.</p>\n *\n * <p>Usually this class will be used as follows:</p>\n *\n * <pre>\n * JmxModel jmx = JmxModelFactory.getJmxModelFor(application);\n * if (jmx == null || jmx.getConnectionState() != JmxModel.ConnectionState.CONNECTED) {\n *     // JMX connection not available...\n * } else {\n *     MBeanServerConnection mbsc = jmx.getMBeanServerConnection();\n *     if (mbsc != null) {\n *         // Invoke JMX operations...\n *     }\n * }\n * </pre>\n *\n * <p>Any of the {@link CachedMBeanServerConnectionFactory CachedMBeanServerConnectionFactory.getCachedMBeanServerConnection}\n * methods can be used to work with a {@link CachedMBeanServerConnection} instead of a plain {@link MBeanServerConnection}.</p>\n *\n * <p>In case the JMX connection is not established yet, you could register\n * a listener on the {@code JmxModel} for ConnectionState property changes.\n * The JmxModel notifies any PropertyChangeListeners about the ConnectionState\n * property change to CONNECTED and DISCONNECTED. The JmxModel instance will\n * be the source for any generated events.</p>\n *\n * <p>Polling for the ConnectionState is also possible by calling\n * {@link JmxModel#getConnectionState()}.</p>\n *\n * @author Luis-Miguel Alventosa\n * @author Tomas Hurka\n */\npublic abstract class JmxModel extends Model {\n\n    private static final String JAR_SUFFIX = \".jar\";  // NOI18N\n    private static final Pattern MODULE_MAIN_CLASS_PATTERN = Pattern.compile(\"^(\\\\w+\\\\.)*\\\\w+/(\\\\w+\\\\.)+\\\\w+$\");\n\n    protected PropertyChangeSupport propertyChangeSupport =\n            new AsyncPropertyChangeSupport(this);\n    /**\n     * The {@link ConnectionState ConnectionState} bound property name.\n     */\n    public static final String CONNECTION_STATE_PROPERTY = \"connectionState\"; // NOI18N\n\n    /**\n     * Values for the {@linkplain #CONNECTION_STATE_PROPERTY\n     * <i>ConnectionState</i>} bound property.\n     */\n    public enum ConnectionState {\n        /**\n         * The connection has been successfully established.\n         */\n        CONNECTED,\n        /**\n         * No connection present.\n         */\n        DISCONNECTED,\n        /**\n         * The connection is being attempted.\n         */\n        CONNECTING\n    }\n\n    /**\n     * Add a {@link java.beans.PropertyChangeListener PropertyChangeListener}\n     * to the listener list.\n     * The listener is registered for all properties.\n     * The same listener object may be added more than once, and will be called\n     * as many times as it is added.\n     * If {@code listener} is {@code null}, no exception is thrown and\n     * no action is taken.\n     *\n     * @param listener the {@code PropertyChangeListener} to be added.\n     */\n    public void addPropertyChangeListener(PropertyChangeListener listener) {\n        propertyChangeSupport.addPropertyChangeListener(listener);\n    }\n\n    /**\n     * Removes a {@link java.beans.PropertyChangeListener PropertyChangeListener}\n     * from the listener list. This\n     * removes a {@code PropertyChangeListener} that was registered for all\n     * properties. If {@code listener} was added more than once to the same\n     * event source, it will be notified one less time after being removed. If\n     * {@code listener} is {@code null}, or was never added, no exception is\n     * thrown and no action is taken.\n     *\n     * @param listener the {@code PropertyChangeListener} to be removed.\n     */\n    public void removePropertyChangeListener(PropertyChangeListener listener) {\n        propertyChangeSupport.removePropertyChangeListener(listener);\n    }\n\n    /**\n     * Returns the current connection state.\n     *\n     * @return the current connection state.\n     */\n    public abstract ConnectionState getConnectionState();\n\n    /**\n     * Returns the {@link MBeanServerConnection MBeanServerConnection} for the\n     * connection to an application. The returned {@code MBeanServerConnection}\n     * object becomes invalid when the connection state is changed to the\n     * {@link ConnectionState#DISCONNECTED DISCONNECTED} state.\n     *\n     * @return the {@code MBeanServerConnection} for the\n     * connection to an application. It returns {@code null}\n     * if the JMX connection couldn't be established.\n     */\n    public abstract MBeanServerConnection getMBeanServerConnection();\n\n    /**\n     * Returns the {@link JMXServiceURL} associated to this {@code JmxModel}.\n     *\n     * @return the {@link JMXServiceURL} associated to this {@code JmxModel}.\n     */\n    public abstract JMXServiceURL getJMXServiceURL();\n\n    /**\n     * <p>Method for obtaining the {@link JvmMXBeans} for\n     * the given {@link JmxModel}.</p>\n     *\n     * @return a {@link JvmMXBeans} instance containing the MXBean\n     * proxies for the Java platform MXBeans backed by the supplied\n     * {@link JmxModel}. No MBean caching is applied on the supplied\n     * {@link JmxModel}.\n     */\n    public abstract JvmMXBeans getJvmMXBeans();\n\n    /**\n     * Returns the current system properties in the target Application.\n     *\n     * <p> This method returns the system properties in the target virtual\n     * machine. Properties whose key or value is not a <tt>String</tt> are\n     * omitted. The method is approximately equivalent to the invocation of the\n     * method {@link java.lang.System#getProperties System.getProperties}\n     * in the target virtual machine except that properties with a key or\n     * value that is not a <tt>String</tt> are not included.\n     * @return The system properties of target Application\n     * @see java.lang.System#getProperties\n     */\n    public abstract Properties getSystemProperties();\n\n    /**\n     * Tests if it is possible to obtain heap dump from target JVM via JMX.\n     * @return <CODE>true</CODE> if JMX supports heap dump,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isTakeHeapDumpSupported();\n\n    /**\n     * Takes heap dump of target JVM via JMX.\n     * The heap is written to the <tt>fileName</tt> file in the same\n     * format as the hprof heap dump.\n     * @param fileName {@link String} where heap dump will be stored.\n     * @return returns <CODE>true</CODE> if operation was successful.\n     */\n    public abstract boolean takeHeapDump(String fileName);\n\n    /**\n     * Tests if it is possible to obtain thread dump from target JVM via JMX.\n     * @return <CODE>true</CODE> if JMX supports thread dump,\n     * <CODE>false</CODE> otherwise\n     */\n    public abstract boolean isTakeThreadDumpSupported();\n\n    /**\n     * Takes thread dump of target JVM via JMX.\n     * @return Returns {@link String} of the thread dump from target JVM.\n     */\n    public abstract String takeThreadDump();\n\n    /**\n     * Returns the combined stack trace from each thread\n     * whose ID is in the input array <tt>threadIds</tt>,\n     * @param threadIds an array of thread IDs\n     * @return Returns {@link String} representing combined stack traces\n     * from all threads IDs\n     */\n    public abstract String takeThreadDump(long[] threadIds);\n\n    /**\n     * Takes heap histogram of target Application.\n     * @return Returns {@link HeapHistogram} of the heap from target Application.\n     */\n    public abstract HeapHistogram takeHeapHistogram();\n \n    /**\n     * print VM option.\n     * Note that VM option is the one which starts with\n     * <CODE>-XX:</CODE>\n     * @param name name of VM option. For example <CODE>HeapDumpOnOutOfMemoryError</CODE>\n     * @return Text value of VM option. For example <CODE>true</CODE>\n     */\n    public abstract String getFlagValue(String name);\n\n    /**\n     * Sets a VM option of the given name to the specified value.\n     *\n     * @param name Name of a VM option\n     * @param value New value of the VM option to be set\n     */\n    public abstract void setFlagValue(String name,String value);\n\n    public abstract String executeJCmd(String command, Map<String,Object> pars);\n\n    /**\n     * Returns the Java virtual machine command line.\n     *\n     * @return String - contains the command line of the target Java\n     *                  application or <CODE>NULL</CODE> if the\n     *                  command line cannot be determined.\n     */\n    public abstract String getCommandLine();\n\n    /**\n     * Return the arguments to the main class for the target Java application.\n     * Returns the arguments to the main class. If the arguments can't be\n     * found, <code>null</code> is returned.\n     *\n     * @return String - contains the arguments to the main class for the\n     *                  target Java application or the <code>null</code>\n     *                  if the command line cannot be determined.\n     */\n\n    public String getMainArgs() {\n        String commandLine = getCommandLine();\n\n        if (commandLine != null) {\n            String arg0 = getFirstArgument(commandLine);\n\n            int firstSpace = arg0.length();\n            if (firstSpace < commandLine.length()) {\n                return commandLine.substring(firstSpace);\n            }\n        }\n        return null;\n    }\n\n    /**\n     * Return the main class for the target Java application.\n     * Returns the main class, if the application started with the <em>-jar</em> option,\n     * it tries to determine main class from the jar file. If\n     * the jar file is not accessible, the main class is simple\n     * name of the jar file.\n     * @return String - the main class of the target Java\n     *                  application.\n     */\n    public String getMainClass() {\n        String commandLine = getCommandLine();\n\n        if (commandLine != null) {\n            String mainClassName = getFirstArgument(commandLine);\n\n            if (mainClassName.endsWith(JAR_SUFFIX)) {\n                mainClassName = mainClassName.replace('\\\\', '/');\n                int index = mainClassName.lastIndexOf('/');\n                if (index != -1) {\n                    mainClassName = mainClassName.substring(index + 1);\n                }\n            } else if (MODULE_MAIN_CLASS_PATTERN.matcher(mainClassName).find()) {\n                return mainClassName.substring(mainClassName.indexOf('/')+1);\n            }\n            mainClassName = mainClassName.replace('\\\\', '/').replace('/', '.');\n            return mainClassName;\n        }\n        return null;\n    }\n\n    private String getFirstArgument(String commandLine) {\n        String mainClassName = null;\n\n        // search for jar file\n        int jarIndex = commandLine.indexOf(JAR_SUFFIX);\n        if (jarIndex != -1) {\n            String jarFile = commandLine.substring(0,jarIndex+JAR_SUFFIX.length());\n            // if this is not end of commandLine check that jar file is separated by space from other arguments\n            if (jarFile.length() == commandLine.length() || commandLine.charAt(jarFile.length()) == ' ') {\n                // jarFile must be on classpath\n                String classPath = getClassPath();\n                if (classPath != null && classPath.contains(jarFile)) {\n                    mainClassName = jarFile;\n                }\n            }\n        }\n        // it looks like ordinary commandline with main class\n        if (mainClassName == null) {\n            int firstSpace = commandLine.indexOf(' ');\n            if (firstSpace > 0) {\n                mainClassName = commandLine.substring(0, firstSpace);\n            } else {\n                mainClassName = commandLine;\n            }\n        }\n        return mainClassName;\n    }\n\n    /**\n     * Returns the Java virtual machine implementation version.\n     * This method is equivalent to {@link System#getProperty\n     * System.getProperty(\"java.class.path\")}.\n     *\n     * @return the Java virtual machine classpath.\n     *\n     * @see java.lang.System#getProperty\n     */\n    private String getClassPath() {\n        return getSystemProperties().getProperty(\"java.class.path\"); // NOI18N\n    }\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jmx/JmxModelFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jmx;\n\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.ModelFactory;\n\n/**\n * The {@code JmxModelFactory} class is a factory class for getting\n * the {@link JmxModel} representation for the {@link Application}.\n *\n * @author Luis-Miguel Alventosa\n */\npublic final class JmxModelFactory extends ModelFactory<JmxModel, Application> {\n\n    private static JmxModelFactory factory;\n\n    private JmxModelFactory() {\n    }\n\n    /**\n     * Getter for the default version of the {@link JmxModelFactory}.\n     * \n     * @return an instance of {@link JmxModelFactory}.\n     */\n    public static synchronized JmxModelFactory getDefault() {\n        if (factory == null) {\n            factory = new JmxModelFactory();\n        }\n        return factory;\n    }\n\n    /**\n     * Factory method for obtaining the {@link JmxModel} for the given\n     * {@link Application}. Note that there is only one instance of\n     * {@link JmxModel} for application instance. This {@link JmxModel}\n     * instance is cached.\n     * \n     * @param app application.\n     * \n     * @return a {@link JmxModel} instance which encapsulates the\n     * application's JMX model.\n     */\n    public static JmxModel getJmxModelFor(Application app) {\n        return getDefault().getModel(app);\n    }\n\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jmx/JvmMXBeans.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jmx;\n\nimport java.lang.management.ClassLoadingMXBean;\nimport java.lang.management.CompilationMXBean;\nimport java.lang.management.GarbageCollectorMXBean;\nimport java.lang.management.MemoryMXBean;\nimport java.lang.management.MemoryManagerMXBean;\nimport java.lang.management.MemoryPoolMXBean;\nimport java.lang.management.OperatingSystemMXBean;\nimport java.lang.management.RuntimeMXBean;\nimport java.lang.management.ThreadMXBean;\nimport java.util.Collection;\nimport java.util.logging.LoggingMXBean;\nimport javax.management.ObjectName;\n\n/**\n * MXBean proxies for the Java platform MXBeans.\n *\n * @author Luis-Miguel Alventosa\n */\npublic interface JvmMXBeans extends MBeanCacheOperations {\n\n    /**\n     * Returns the managed bean for the class loading system of \n     * the Java virtual machine.\n     *\n     * @return a {@link ClassLoadingMXBean} object for \n     * the Java virtual machine.\n     */\n    public ClassLoadingMXBean getClassLoadingMXBean();\n\n    /**\n     * Returns the managed bean for the compilation system of \n     * the Java virtual machine.  This method returns <tt>null</tt>\n     * if the Java virtual machine has no compilation system.\n     *\n     * @return a {@link CompilationMXBean} object for the Java virtual \n     *   machine or <tt>null</tt> if the Java virtual machine has \n     *   no compilation system. \n     */\n    public CompilationMXBean getCompilationMXBean();\n\n    /**\n     * Returns <tt>LoggingMXBean</tt> for managing loggers. \n     *\n     * @return a {@link LoggingMXBean} object for \n     * the Java virtual machine.\n     */\n    public LoggingMXBean getLoggingMXBean();\n\n    /**\n     * Returns a list of {@link GarbageCollectorMXBean} objects \n     * in the Java virtual machine.\n     * The Java virtual machine may have one or more\n     * <tt>GarbageCollectorMXBean</tt> objects.\n     * It may add or remove <tt>GarbageCollectorMXBean</tt> \n     * during execution.\n     *\n     * @return a list of <tt>GarbageCollectorMXBean</tt> objects.\n     */\n    public Collection<GarbageCollectorMXBean> getGarbageCollectorMXBeans();\n\n    /**\n     * Returns a list of {@link MemoryManagerMXBean} objects \n     * in the Java virtual machine. \n     * The Java virtual machine can have one or more memory managers.\n     * It may add or remove memory managers during execution.\n     *\n     * @return a list of <tt>MemoryManagerMXBean</tt> objects.\n     */\n    public Collection<MemoryManagerMXBean> getMemoryManagerMXBeans();\n\n    /**\n     * Returns the managed bean for the memory system of \n     * the Java virtual machine.\n     *\n     * @return a {@link MemoryMXBean} object for the Java virtual machine.\n     */\n    public MemoryMXBean getMemoryMXBean();\n\n    /**\n     * Returns a list of {@link MemoryPoolMXBean} objects in the \n     * Java virtual machine.\n     * The Java virtual machine can have one or more memory pools.\n     * It may add or remove memory pools during execution.\n     *\n     * @return a list of <tt>MemoryPoolMXBean</tt> objects.\n     */\n    public Collection<MemoryPoolMXBean> getMemoryPoolMXBeans();\n\n    /**\n     * Returns the managed bean for the operating system on which\n     * the Java virtual machine is running.\n     *\n     * @return an {@link OperatingSystemMXBean} object for \n     * the Java virtual machine.\n     */\n    public OperatingSystemMXBean getOperatingSystemMXBean();\n\n    /**\n     * Returns the managed bean for the runtime system of \n     * the Java virtual machine.\n     *\n     * @return a {@link RuntimeMXBean} object for the Java virtual machine.\n     */\n    public RuntimeMXBean getRuntimeMXBean();\n\n    /**\n     * Returns the managed bean for the thread system of \n     * the Java virtual machine.\n     *\n     * @return a {@link ThreadMXBean} object for the Java virtual machine.\n     */\n    public ThreadMXBean getThreadMXBean();\n\n    /**\n     * Generic method that returns an MXBean proxy for the given platform\n     * MXBean identified by its ObjectName and which implements the supplied\n     * interface.\n     * @return a proxy for a platform MXBean interface of a \n     * given MXBean\n     * @param objectName {@link ObjectName} which identifies MXBean\n     * @param interfaceClass the MXBean interface to be implemented\n     * by the proxy.\n     */\n    public <T> T getMXBean(ObjectName objectName, Class<T> interfaceClass);\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jmx/JvmMXBeansFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jmx;\n\nimport java.io.IOException;\nimport java.lang.management.ClassLoadingMXBean;\nimport java.lang.management.CompilationMXBean;\nimport java.lang.management.GarbageCollectorMXBean;\nimport static java.lang.management.ManagementFactory.*;\nimport java.lang.management.MemoryMXBean;\nimport java.lang.management.MemoryManagerMXBean;\nimport java.lang.management.MemoryPoolMXBean;\nimport java.lang.management.OperatingSystemMXBean;\nimport java.lang.management.RuntimeMXBean;\nimport java.lang.management.ThreadMXBean;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.LogManager;\nimport java.util.logging.Logger;\nimport java.util.logging.LoggingMXBean;\nimport javax.management.MBeanServerConnection;\nimport javax.management.MalformedObjectNameException;\nimport javax.management.ObjectName;\n\n/**\n * <p>The {@code JvmMXBeansFactory} class is a factory class that\n * allows to get instances of {@link JvmMXBeans} for a given\n * {@link MBeanServerConnection} or {@link JmxModel}.</p>\n * \n * <p>The factory methods allow to supply an interval value at which the\n * internal MBean cache will be automatically flushed and interested\n * {@link MBeanCacheListener}s notified.</p>\n * \n * <p>If the factory methods which do not take an interval value are used\n * then no MBean caching is performed at all.</p>\n *\n * @see CachedMBeanServerConnection\n * @see CachedMBeanServerConnectionFactory\n *\n * @author Luis-Miguel Alventosa\n */\npublic final class JvmMXBeansFactory {\n\n    private JvmMXBeansFactory() {\n    }\n\n    /**\n     * <p>Factory method for obtaining the {@link JvmMXBeans} for\n     * the given {@link MBeanServerConnection}.</p>\n     * \n     * @param mbsc an MBeanServerConnection.\n     * \n     * @return a {@link JvmMXBeans} instance containing the MXBean\n     * proxies for the Java platform MXBeans backed by the supplied\n     * {@link MBeanServerConnection}. No MBean caching is applied on\n     * the supplied {@link MBeanServerConnection}.\n     */\n    public static JvmMXBeans getJvmMXBeans(MBeanServerConnection mbsc) {\n        return new JvmMXBeansImpl(mbsc);\n    }\n\n    /**\n     * <p>Factory method for obtaining the {@link JvmMXBeans} for\n     * the given {@link MBeanServerConnection}.</p>\n     * \n     * <p>The MBeans in this {@link MBeanServerConnection} will be cached.\n     * The MBean cache will be flushed at the given interval and the\n     * interested {@link MBeanCacheListener}s will be notified.</p>\n     * \n     * @param mbsc an MBeanServerConnection.\n     * @param interval the interval (in milliseconds) at which the MBean\n     * cache is flushed. An interval equal to zero means no automatic flush\n     * of the MBean cache.\n     * \n     * @return a {@link JvmMXBeans} instance containing the MXBean\n     * proxies for the Java platform MXBeans backed by the supplied\n     * {@link MBeanServerConnection}. MBean caching is enabled and\n     * the cache is flushed at the end of every interval period.\n     * \n     * @throws IllegalArgumentException if the supplied interval is negative.\n     */\n    public static JvmMXBeans getJvmMXBeans(MBeanServerConnection mbsc, int interval)\n            throws IllegalArgumentException {\n        if (interval < 0) {\n            throw new IllegalArgumentException(\"interval cannot be negative\"); // NOI18N\n        }\n        return new JvmMXBeansImpl(CachedMBeanServerConnectionFactory.getCachedMBeanServerConnection(mbsc, interval));\n    }\n\n    /**\n     * <p>Factory method for obtaining the {@link JvmMXBeans} for\n     * the given {@link JmxModel}.</p>\n     * \n     * @param jmx a JmxModel.\n     * \n     * @return a {@link JvmMXBeans} instance containing the MXBean\n     * proxies for the Java platform MXBeans backed by the supplied\n     * {@link JmxModel}. No MBean caching is applied on the supplied\n     * {@link JmxModel}.\n     */\n    public static JvmMXBeans getJvmMXBeans(JmxModel jmx) {\n        return new JvmMXBeansImpl(jmx.getMBeanServerConnection());\n    }\n\n    /**\n     * <p>Factory method for obtaining the {@link JvmMXBeans} for the given\n     * {@link JmxModel}.</p>\n     * \n     * <p>The MBeans in this {@link JmxModel} will be cached. The MBean\n     * cache will be flushed at the given interval and the interested\n     * {@link MBeanCacheListener}s will be notified.</p>\n     *\n     * @param jmx a JmxModel.\n     * @param interval the interval (in milliseconds) at which the MBean\n     * cache is flushed. An interval equal to zero means no automatic flush\n     * of the MBean cache.\n     *\n     * @return a {@link JvmMXBeans} instance containing the MXBean\n     * proxies for the Java platform MXBeans backed by the supplied\n     * {@link JmxModel}. MBean caching is enabled and the cache is\n     * flushed at the end of every interval period.\n     * \n     * @throws IllegalArgumentException if the supplied interval is negative.\n     */\n    public static JvmMXBeans getJvmMXBeans(JmxModel jmx, int interval)\n            throws IllegalArgumentException {\n        if (interval < 0) {\n            throw new IllegalArgumentException(\"interval cannot be negative\"); // NOI18N\n        }\n        return new JvmMXBeansImpl(CachedMBeanServerConnectionFactory.getCachedMBeanServerConnection(jmx.getMBeanServerConnection(), interval));\n    }\n\n    /**\n     * MXBean proxies for the Java platform MXBeans backed by the\n     * supplied {@link MBeanServerConnection} or {@link JmxModel}.\n     *\n     * @author Luis-Miguel Alventosa\n     */\n    static class JvmMXBeansImpl implements JvmMXBeans {\n\n        protected MBeanServerConnection mbsc;\n        private ClassLoadingMXBean classLoadingMXBean = null;\n        private CompilationMXBean compilationMXBean = null;\n        private LoggingMXBean loggingMXBean = null;\n        private MemoryMXBean memoryMXBean = null;\n        private OperatingSystemMXBean operatingSystemMXBean = null;\n        private RuntimeMXBean runtimeMXBean = null;\n        private ThreadMXBean threadMXBean = null;\n        private List<GarbageCollectorMXBean> garbageCollectorMXBeans = null;\n        private List<MemoryManagerMXBean> memoryManagerMXBeans = null;\n        private List<MemoryPoolMXBean> memoryPoolMXBeans = null;\n        private final static Logger LOGGER = Logger.getLogger(JvmMXBeansImpl.class.getName());\n\n        /**\n         * Creates an instance of {@code JvmMXBeans} for the given\n         * {@link MBeanServerConnection}.\n         *\n         * @param mbsc the {@link MBeanServerConnection} instance.\n         */\n        JvmMXBeansImpl(MBeanServerConnection mbsc) {\n            this.mbsc = mbsc;\n        }\n\n        /**\n         * Returns an MXBean proxy for the class loading system of the JVM.\n         */\n        public synchronized ClassLoadingMXBean getClassLoadingMXBean() {\n            if (mbsc != null && classLoadingMXBean == null) {\n                classLoadingMXBean = getMXBean(CLASS_LOADING_MXBEAN_NAME, ClassLoadingMXBean.class);\n            }\n            return classLoadingMXBean;\n        }\n\n        /**\n         * Returns an MXBean proxy for the compilation system of the JVM.\n         */\n        public synchronized CompilationMXBean getCompilationMXBean() {\n            if (mbsc != null && compilationMXBean == null) {\n                compilationMXBean = getMXBean(COMPILATION_MXBEAN_NAME, CompilationMXBean.class);\n            }\n            return compilationMXBean;\n        }\n\n        /**\n         * Returns an MXBean proxy for the logging system of the JVM.\n         */\n        public synchronized LoggingMXBean getLoggingMXBean() {\n            if (mbsc != null && loggingMXBean == null) {\n                loggingMXBean = getMXBean(LogManager.LOGGING_MXBEAN_NAME, LoggingMXBean.class);\n            }\n            return loggingMXBean;\n        }\n\n        /**\n         * Returns a collection of MXBean proxies for the garbage collectors of the JVM.\n         */\n        public synchronized Collection<GarbageCollectorMXBean> getGarbageCollectorMXBeans() {\n            // TODO: How to deal with changes to the list?\n            if (mbsc != null && garbageCollectorMXBeans == null) {\n                ObjectName gcName;\n                try {\n                    gcName = new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + \",*\");\n                } catch (MalformedObjectNameException e) {\n                    // Should never happen\n                    LOGGER.throwing(JvmMXBeansImpl.class.getName(), \"getGarbageCollectorMXBeans\", e); // NOI18N\n                    return null;\n                }\n                Set<ObjectName> mbeans;\n                try {\n                    mbeans = mbsc.queryNames(gcName, null);\n                } catch (Exception e) {\n                    LOGGER.throwing(JvmMXBeansImpl.class.getName(), \"getGarbageCollectorMXBeans\", e); // NOI18N\n                    return null;\n                }\n                if (mbeans != null) {\n                    garbageCollectorMXBeans = new ArrayList<>();\n                    for (ObjectName on : mbeans) {\n                        String name = GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + \",name=\" + on.getKeyProperty(\"name\"); // NOI18N\n                        try {\n                            GarbageCollectorMXBean mbean = newPlatformMXBeanProxy(mbsc, name, GarbageCollectorMXBean.class);\n                            garbageCollectorMXBeans.add(mbean);\n                        } catch (Exception e) {\n                            LOGGER.throwing(JvmMXBeansImpl.class.getName(), \"getGarbageCollectorMXBeans\", e); // NOI18N\n                        }\n                    }\n                }\n            }\n            return garbageCollectorMXBeans;\n        }\n\n        /**\n         * Returns a collection of MXBean proxies for the memory managers of the JVM.\n         */\n        public synchronized Collection<MemoryManagerMXBean> getMemoryManagerMXBeans() {\n            // TODO: How to deal with changes to the list?\n            if (mbsc != null && memoryManagerMXBeans == null) {\n                ObjectName managerName;\n                try {\n                    managerName = new ObjectName(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE + \",*\");\n                } catch (MalformedObjectNameException e) {\n                    // Should never happen\n                    LOGGER.throwing(JvmMXBeansImpl.class.getName(), \"getMemoryManagerMXBeans\", e); // NOI18N\n                    return null;\n                }\n                Set<ObjectName> mbeans;\n                try {\n                    mbeans = mbsc.queryNames(managerName, null);\n                } catch (Exception e) {\n                    LOGGER.throwing(JvmMXBeansImpl.class.getName(), \"getMemoryManagerMXBeans\", e); // NOI18N\n                    return null;\n                }\n                if (mbeans != null) {\n                    memoryManagerMXBeans = new ArrayList<>();\n                    for (ObjectName on : mbeans) {\n                        String name = MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE + \",name=\" + on.getKeyProperty(\"name\"); // NOI18N\n                        try {\n                            MemoryManagerMXBean mbean = newPlatformMXBeanProxy(mbsc, name, MemoryManagerMXBean.class);\n                            memoryManagerMXBeans.add(mbean);\n                        } catch (Exception e) {\n                            LOGGER.throwing(JvmMXBeansImpl.class.getName(), \"getMemoryManagerMXBeans\", e); // NOI18N\n                        }\n                    }\n                }\n            }\n            return memoryManagerMXBeans;\n        }\n\n        /**\n         * Returns an MXBean proxy for the memory system of the JVM.\n         */\n        public synchronized MemoryMXBean getMemoryMXBean() {\n            if (mbsc != null && memoryMXBean == null) {\n                memoryMXBean = getMXBean(MEMORY_MXBEAN_NAME, MemoryMXBean.class);\n            }\n            return memoryMXBean;\n        }\n\n        /**\n         * Returns a collection of MXBean proxies for the memory pools of the JVM.\n         */\n        public synchronized Collection<MemoryPoolMXBean> getMemoryPoolMXBeans() {\n            // TODO: How to deal with changes to the list?\n            if (mbsc != null && memoryPoolMXBeans == null) {\n                ObjectName poolName;\n                try {\n                    poolName = new ObjectName(MEMORY_POOL_MXBEAN_DOMAIN_TYPE + \",*\");\n                } catch (MalformedObjectNameException e) {\n                    // Should never happen\n                    LOGGER.throwing(JvmMXBeansImpl.class.getName(), \"getMemoryPoolMXBeans\", e); // NOI18N\n                    return null;\n                }\n                Set<ObjectName> mbeans;\n                try {\n                    mbeans = mbsc.queryNames(poolName, null);\n                } catch (Exception e) {\n                    LOGGER.throwing(JvmMXBeansImpl.class.getName(), \"getMemoryPoolMXBeans\", e); // NOI18N\n                    return null;\n                }\n                if (mbeans != null) {\n                    memoryPoolMXBeans = new ArrayList<>();\n                    for (ObjectName on : mbeans) {\n                        String name = MEMORY_POOL_MXBEAN_DOMAIN_TYPE + \",name=\" + on.getKeyProperty(\"name\"); // NOI18N\n                        try {\n                            MemoryPoolMXBean mbean = newPlatformMXBeanProxy(mbsc, name, MemoryPoolMXBean.class);\n                            memoryPoolMXBeans.add(mbean);\n                        } catch (Exception e) {\n                            LOGGER.throwing(JvmMXBeansImpl.class.getName(), \"getMemoryPoolMXBeans\", e); // NOI18N\n                        }\n                    }\n                }\n            }\n            return memoryPoolMXBeans;\n        }\n\n        /**\n         * Returns an MXBean proxy for the operating system of the JVM.\n         */\n        public synchronized OperatingSystemMXBean getOperatingSystemMXBean() {\n            if (mbsc != null && operatingSystemMXBean == null) {\n                operatingSystemMXBean = getMXBean(OPERATING_SYSTEM_MXBEAN_NAME, OperatingSystemMXBean.class);\n            }\n            return operatingSystemMXBean;\n        }\n\n        /**\n         * Returns an MXBean proxy for the runtime system of the JVM.\n         */\n        public synchronized RuntimeMXBean getRuntimeMXBean() {\n            if (mbsc != null && runtimeMXBean == null) {\n                runtimeMXBean = getMXBean(RUNTIME_MXBEAN_NAME, RuntimeMXBean.class);\n            }\n            return runtimeMXBean;\n        }\n\n        /**\n         * Returns an MXBean proxy for the thread system of the JVM.\n         */\n        public synchronized ThreadMXBean getThreadMXBean() {\n            if (mbsc != null && threadMXBean == null) {\n                threadMXBean = getMXBean(THREAD_MXBEAN_NAME, ThreadMXBean.class);\n            }\n            return threadMXBean;\n        }\n\n        /**\n         * Generic method that returns an MXBean proxy for the given platform\n         * MXBean identified by its ObjectName and which implements the supplied\n         * interface.\n         */\n        public <T> T getMXBean(ObjectName objectName, Class<T> interfaceClass) {\n            return getMXBean(objectName.toString(), interfaceClass);\n        }\n\n        <T> T getMXBean(String objectNameStr, Class<T> interfaceClass) {\n            if (mbsc != null) {\n                try {\n                    return newPlatformMXBeanProxy(mbsc, objectNameStr, interfaceClass);\n                } catch (IOException e) {\n                    LOGGER.throwing(JvmMXBeansImpl.class.getName(), \"getMXBean\", e); // NOI18N\n                } catch (IllegalArgumentException iae) {\n                    LOGGER.log(Level.INFO, JvmMXBeansImpl.class.getName()+\".getMXBean()\", iae); // NOI18N                    \n                }\n            }\n            return null;\n        }\n\n        public void addMBeanCacheListener(MBeanCacheListener listener) {\n            if (mbsc instanceof CachedMBeanServerConnection) {\n                ((CachedMBeanServerConnection) mbsc).addMBeanCacheListener(listener);\n            } else {\n                throw new UnsupportedOperationException(\"The underlying MBeanServerConnection does not support caching.\"); // NOI18N\n            }\n        }\n\n        public void removeMBeanCacheListener(MBeanCacheListener listener) {\n            if (mbsc instanceof CachedMBeanServerConnection) {\n                ((CachedMBeanServerConnection) mbsc).removeMBeanCacheListener(listener);\n            } else {\n                throw new UnsupportedOperationException(\"The underlying MBeanServerConnection does not support caching.\"); // NOI18N\n            }\n        }\n\n        public void flush() {\n            if (mbsc instanceof CachedMBeanServerConnection) {\n                ((CachedMBeanServerConnection) mbsc).flush();\n            } else {\n                throw new UnsupportedOperationException(\"The underlying MBeanServerConnection does not support caching.\"); // NOI18N\n            }\n        }\n\n        public int getInterval() {\n            if (mbsc instanceof CachedMBeanServerConnection) {\n                return ((CachedMBeanServerConnection) mbsc).getInterval();\n            } else {\n                throw new UnsupportedOperationException(\"The underlying MBeanServerConnection does not support caching.\"); // NOI18N\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jmx/MBeanCacheListener.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jmx;\n\nimport java.util.EventListener;\n\n/**\n * Interface for listeners of MBean cache events.\n *\n * @author Luis-Miguel Alventosa\n */\npublic interface MBeanCacheListener extends EventListener {\n    /**\n     * Invoked when the MBean cache is flushed.\n     */\n    public void flushed();\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jmx/MBeanCacheOperations.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jmx;\n\n/**\n * MBean cache operations.\n * \n * @author Luis-Miguel Alventosa\n */\npublic interface MBeanCacheOperations {\n\n    /**\n     * Flush all cached values of attributes.\n     */\n    public void flush();\n\n    /**\n     * Get the flush interval.\n     *\n     * @return the flush interval in milliseconds.\n     */\n    public int getInterval();\n\n    /**\n     * Add a {@code MBeanCacheListener}. The given listener is added to\n     * the list of {@code MBeanCacheListener} objects to be notified of\n     * MBean cache related events.\n     *\n     * @param listener the {@code MBeanCacheListener} to add.\n     */\n    public void addMBeanCacheListener(MBeanCacheListener listener);\n\n    /**\n     * Remove a {@code MBeanCacheListener}. The given listener is removed\n     * from the list of {@code MBeanCacheListener} objects to be notified\n     * of MBean cache related events.\n     *\n     * @param listener the {@code MBeanCacheListener} to be removed.\n     */\n    public void removeMBeanCacheListener(MBeanCacheListener listener);\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jmx/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * JMX support in VisualVM.\n */\npackage org.graalvm.visualvm.tools.jmx;\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jvmstat/Bundle.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nLBL_Heap=Heap\nLBL_PermGen=PermGen\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jvmstat/JvmJvmstatModel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jvmstat;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.List;\nimport java.util.jar.Attributes;\nimport java.util.jar.JarFile;\nimport java.util.logging.Logger;\nimport java.util.regex.Pattern;\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.Model;\nimport org.openide.util.NbBundle;\n\n/**\n * \n * This class encapsulates information available via Jvmstat counters.\n * It is preferred to use this class to get access to java home, \n * total loaded classes, number of running threads etc. The advantage is \n * that user code does not depend on particular counter name, which can be\n * different for different JVM.\n * @author Tomas Hurka\n */\npublic abstract class JvmJvmstatModel extends Model {\n    private static final Logger LOGGER = Logger.getLogger(JvmJvmstatModel.class.getName());\n    \n    private static final String JAR_SUFFIX = \".jar\";  // NOI18N\n    \n    private static final Pattern MODULE_MAIN_CLASS_PATTERN = Pattern.compile(\"^(\\\\w+\\\\.)*\\\\w+/(\\\\w+\\\\.)+\\\\w+$\");\n\n    protected Application application;\n    protected JvmstatModel jvmstat;\n    protected MonitoredValue loadedClasses;\n    protected MonitoredValue sharedLoadedClasses;\n    protected MonitoredValue sharedUnloadedClasses;\n    protected MonitoredValue unloadedClasses;\n    protected MonitoredValue threadsDaemon;\n    protected MonitoredValue threadsLive;\n    protected MonitoredValue threadsLivePeak;\n    protected MonitoredValue threadsStarted;\n    protected MonitoredValue applicationTime;\n    protected MonitoredValue upTime;\n    protected long osFrequency;\n    protected String[] genName;\n    protected List<MonitoredValue> genCapacity;\n    protected List<MonitoredValue> genUsed;\n    protected long[] genMaxCapacity;\n    \n    protected JvmJvmstatModel(Application app,JvmstatModel stat) {\n        application = app;\n        jvmstat = stat;\n        genName = new String[2];\n        genName[0] = NbBundle.getMessage(JvmJvmstatModel.class, \"LBL_Heap\");   // NOI18N\n        genName[1] = NbBundle.getMessage(JvmJvmstatModel.class, \"LBL_PermGen\");   // NOI18N        \n    }\n    \n    /**\n     * Returns the Java virtual machine command line.\n     *\n     * @return String - contains the command line of the target Java\n     *                  application or <CODE>NULL</CODE> if the\n     *                  command line cannot be determined.\n     */\n    public String getCommandLine() {\n        return jvmstat.findByName(\"sun.rt.javaCommand\"); // NOI18N\n    }\n    \n    /**\n     * Returns the Java virtual machine command line arguments.\n     *\n     * @return String - contains the command line arguments of the target Java\n     *                  application or <CODE>NULL</CODE> if the\n     *                  command line arguments cannot be determined.\n     */\n    public String getJvmArgs() {\n        return jvmstat.findByName(\"java.rt.vmArgs\");    // NOI18N\n    }\n    \n    /**\n     * Returns the Java virtual machine flags.\n     *\n     * @return String - contains the flags of the target Java\n     *                  application or <CODE>NULL</CODE> if the\n     *                  flags be determined.\n     */\n    public String getJvmFlags() {\n        return jvmstat.findByName(\"java.rt.vmFlags\");   // NOI18N\n    }   \n    \n   /**\n     * Returns the Java virtual machine home directory. \n     * This method is equivalent to {@link System#getProperty \n     * System.getProperty(\"java.home\")}.\n     *\n     * @return the Java virtual machine home directory.\n     *\n     * @see java.lang.System#getProperty\n     */\n    public String getJavaHome() {\n        return jvmstat.findByName(\"java.property.java.home\");   // NOI18N\n    }\n    \n   /**\n     * Returns the Java virtual machine VM info. \n     * This method is equivalent to {@link System#getProperty \n     * System.getProperty(\"java.vm.info\")}.\n     *\n     * @return the Java virtual machine VM info.\n     *\n     * @see java.lang.System#getProperty\n     */\n    public String getVmInfo() {\n        return jvmstat.findByName(\"java.property.java.vm.info\");    // NOI18N\n    }\n    \n    /**\n     * Returns the Java virtual machine implementation name. \n     * This method is equivalent to {@link System#getProperty \n     * System.getProperty(\"java.vm.name\")}.\n     *\n     * @return the Java virtual machine implementation name.\n     *\n     * @see java.lang.System#getProperty\n     */\n    public String getVmName() {\n        return jvmstat.findByName(\"java.property.java.vm.name\");    // NOI18N\n    }\n    \n    /**\n     * Returns the Java virtual machine implementation version. \n     * This method is equivalent to {@link System#getProperty \n     * System.getProperty(\"java.vm.version\")}.\n     *\n     * @return the Java virtual machine implementation version.\n     *\n     * @see java.lang.System#getProperty\n     */\n    public String getVmVersion() {\n        return jvmstat.findByName(\"java.property.java.vm.version\"); // NOI18N\n    }\n    \n    /**\n     * Returns the Java Runtime Environment version.\n     * This method is equivalent to {@link System#getProperty\n     * System.getProperty(\"java.version\")}.\n     *\n     * @return the Java virtual machine implementation version.\n     *\n     * @see java.lang.System#getProperty\n     */\n    public String getJavaVersion() {\n        return jvmstat.findByName(\"java.property.java.version\"); // NOI18N\n    }\n\n    /**\n     * Returns the Java virtual machine implementation version. \n     * This method is equivalent to {@link System#getProperty \n     * System.getProperty(\"java.vm.vendor\")}.\n     *\n     * @return the Java virtual machine vendor.\n     *\n     * @see java.lang.System#getProperty\n     */\n    public String getVmVendor() {\n        return jvmstat.findByName(\"java.property.java.vm.vendor\");  // NOI18N\n    }\n    \n    /**\n     * Returns the Java virtual machine implementation version. \n     * This method is equivalent to {@link System#getProperty \n     * System.getProperty(\"java.class.path\")}.\n     *\n     * @return the Java virtual machine classpath.\n     *\n     * @see java.lang.System#getProperty\n     */\n    public String getClassPath() {\n        return jvmstat.findByName(\"java.property.java.class.path\"); // NOI18N\n    }\n    \n    /**\n     * Tests if target JVM supports\n     * <a href=http://download.oracle.com/javase/6/docs/technotes/guides/attach/index.html>Attach API</a>\n     * and that support is enabled in target JVM.\n     * @return <CODE>true</CODE> if JVM supports Attach API, <CODE>false</CODE> otherwise\n     */\n    public boolean isAttachable() {\n        String jvmCapabilities = jvmstat.findByName(\"sun.rt.jvmCapabilities\");  // NOI18N\n        if (jvmCapabilities == null) {\n             return false;\n        }\n        return jvmCapabilities.charAt(0) == '1';\n    }\n    \n    /**\n     * Return the arguments to the main class for the target Java application.\n     * Returns the arguments to the main class. If the arguments can't be\n     * found, <code>null</code> is returned.\n     *\n     * @return String - contains the arguments to the main class for the\n     *                  target Java application or the <code>null</code>\n     *                  if the command line cannot be determined.\n     */\n\n    public String getMainArgs() {\n        String commandLine = getCommandLine();\n\n        if (commandLine != null) {\n            String arg0 = getFirstArgument();\n\n            if (arg0 != null) {\n                int firstSpace = arg0.length();\n                if (firstSpace < commandLine.length()) {\n                    return commandLine.substring(firstSpace);\n                }\n            }\n        }\n        return null;\n    }\n    \n    /**\n     * Return the main class for the target Java application.\n     * Returns the main class, if the application started with the <em>-jar</em> option,\n     * it tries to determine main class from the jar file. If\n     * the jar file is not accessible, the main class is simple\n     * name of the jar file.\n     * @return String - the main class of the target Java\n     *                  application.\n     */\n    public String getMainClass() {\n        String mainClassName = getFirstArgument();\n\n        if (mainClassName == null) return null;\n        // if we are on localhost try read main class from jar file\n        if (application.isLocalApplication()) {\n            File jarFile = new File(mainClassName);\n            if (jarFile.exists()) {\n                try (JarFile jf = new JarFile(jarFile)) {\n                    mainClassName = jf.getManifest().getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);\n                    assert mainClassName!=null;\n                } catch (IOException ex) {\n                    LOGGER.throwing(JvmJvmstatModel.class.getName(), \"getMainClass\", ex);   // NOI18N\n                }\n            }\n        }\n        \n        if (mainClassName.endsWith(JAR_SUFFIX)) {\n            mainClassName = mainClassName.replace('\\\\', '/');\n            int index = mainClassName.lastIndexOf('/');\n            if (index != -1) {\n                mainClassName = mainClassName.substring(index + 1);\n            }\n        } else if (MODULE_MAIN_CLASS_PATTERN.matcher(mainClassName).find()) {\n            return mainClassName.substring(mainClassName.indexOf('/')+1);\n        }\n        mainClassName = mainClassName.replace('\\\\', '/').replace('/', '.');\n        return mainClassName;\n    }\n\n    private String getFirstArgument() {\n        String commandLine = getCommandLine();\n        String mainClassName = null;\n        \n        if (commandLine == null) return mainClassName;\n        // search for jar file\n        int jarIndex = commandLine.indexOf(JAR_SUFFIX); \n        if (jarIndex != -1) {\n            String jarFile = commandLine.substring(0,jarIndex+JAR_SUFFIX.length());\n            // if this is not end of commandLine check that jar file is separated by space from other arguments\n            if (jarFile.length() == commandLine.length() || commandLine.charAt(jarFile.length()) == ' ') {\n                // jarFile must be on classpath\n                String classPath = getClassPath();\n                if (classPath != null && classPath.contains(jarFile)) {\n                    mainClassName = jarFile;\n                }\n            }\n        }\n        // it looks like ordinary commandline with main class\n        if (mainClassName == null) {\n            int firstSpace = commandLine.indexOf(' ');\n            if (firstSpace > 0) {\n                mainClassName = commandLine.substring(0, firstSpace);\n            } else {\n                mainClassName = commandLine;\n            }\n        }\n        return mainClassName;\n    }\n\n    /** \n     * Returns the total number of classes that have been loaded since\n     * the Java virtual machine has started execution.\n     *\n     * @return the total number of classes loaded.\n     *\n     */\n    public long getLoadedClasses() {\n        return getLongValue(loadedClasses);\n    }\n    \n    /** \n     * Returns the total number of shared classes that have been loaded since\n     * the Java virtual machine has started execution.\n     *\n     * @return the total number of shared classes loaded.\n     *\n     */\n    public long getSharedLoadedClasses() {\n        return getLongValue(sharedLoadedClasses);\n    }\n    \n    /** \n     * Returns the total number of shared classes unloaded since the Java virtual machine\n     * has started execution.\n     *\n     * @return the total number of unloaded shared classes.\n     */\n    public long getSharedUnloadedClasses() {\n        return getLongValue(sharedUnloadedClasses);\n   }\n    \n    /** \n     * Returns the total number of classes unloaded since the Java virtual machine\n     * has started execution.\n     *\n     * @return the total number of unloaded classes.\n     */\n    public long getUnloadedClasses() {\n        return getLongValue(unloadedClasses);\n    }\n    \n    /**\n     * Returns the current number of live daemon threads.\n     *\n     * @return the current number of live daemon threads.\n     */\n    public long getThreadsDaemon() {\n        return getLongValue(threadsDaemon);\n    }\n    \n    /**\n     * Returns the current number of live threads including both \n     * daemon and non-daemon threads.\n     *\n     * @return the current number of live threads.\n     */\n    public long getThreadsLive() {\n        return getLongValue(threadsLive);\n    }\n    \n    /**\n     * Returns the peak live thread count since the Java virtual machine \n     * started or peak was reset.\n     *\n     * @return the peak live thread count.\n     */\n    public long getThreadsLivePeak() {\n        return getLongValue(threadsLivePeak);\n    }\n    \n    /**\n     * Returns the total number of threads created and also started \n     * since the Java virtual machine started.\n     *\n     * @return the total number of threads started.\n     */\n    public long getThreadsStarted() {\n        return getLongValue(threadsStarted);\n    }\n    \n    /**\n     * Returns the total time of when application is running in OS ticks.\n     * Application time is the uptime minus time spent in safe points.\n     * Note that this value is updated only at the beginning and e \n     * @return application time of the Java virtual machine in OS ticks.\n     * @see JvmJvmstatModel#getOsFrequency()\n     */\n    public long getApplicationTime() {\n        return getLongValue(applicationTime);\n    }\n    \n    /**\n     * Returns the uptime of the Java virtual machine in OS ticks.\n     * @return uptime of the Java virtual machine in OS ticks.\n     * @see JvmJvmstatModel#getOsFrequency()\n     */\n    public long getUpTime() {\n        return getLongValue(upTime);\n    }\n    \n    /**\n     * Returns the names of Java virtual machine spaces.\n     *\n     * @return Index 0 is the display name for heap,\n     * index 1 is display name for Permanent Generation (PermGen)\n     */\n    public String[] getGenName() {\n        return genName.clone();\n    }\n\n    /** \n     * Returns the amount of memory in bytes that is committed for\n     * the Java virtual machine to use.  This amount of memory is\n     * guaranteed for the Java virtual machine to use. \n     *\n     * @return long[0] - the amount of committed heap memory in bytes.\n     *         long[1] - the amount of committed Perm Gen memory in bytes.\n     *\n     */\n    public long[] getGenCapacity() {\n        return getGenerationSum(genCapacity);\n    }\n    \n    /** \n     * Returns the amount of used memory in bytes.\n     *\n     * @return long[0] - the amount of used heap memory in bytes.\n     *         long[1] - the amount of used Perm Gen memory in bytes.\n     *\n     */\n    public long[] getGenUsed() {\n        return getGenerationSum(genUsed);\n    }\n    \n    /** \n     * Returns the maximum amount of memory in bytes that can be \n     * used for memory management.  This method returns <tt>-1</tt> \n     * if the maximum memory size is undefined.\n     * \n     * @return long[0] - the maximum amount of heap memory in bytes; \n     *         long[1] - the maximum amount of Perm Gen memory in bytes;\n     */\n    public long[] getGenMaxCapacity() {\n        return genMaxCapacity.clone();\n    }\n    \n    /**\n     * Returns the number of OS ticks per second.\n     *\n     * @return number of OS ticks per second.\n     */\n    public long getOsFrequency() {\n        return osFrequency;\n    }\n    \n    protected abstract String getPermGenPrefix();\n\n    protected long getLongValue(MonitoredValue val) {\n        if (val != null) {\n            return ((Long)val.getValue()).longValue();\n        }\n        return 0;\n    }\n    \n    protected long[] getGenerationSum(List<MonitoredValue> values) {\n        long[] results=new long[2];\n        String prefix = getPermGenPrefix();\n        \n        for (MonitoredValue value : values) {\n            if (value != null) {\n                long val = getLongValue(value);\n                if (value.getName().startsWith(prefix)) {\n                    results[1]+= val;\n                } else {\n                    results[0]+= val;\n                }\n            }\n        }\n        return results;\n    }\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jvmstat/JvmJvmstatModelFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jvmstat;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.ModelFactory;\n\n/**\n * The JvmJvmstatModelFactory class is a factory class for getting the\n * {@link JvmJvmstatModel} representation for the {@link Application}.\n * \n * @author Tomas Hurka\n */\npublic final class JvmJvmstatModelFactory extends ModelFactory<JvmJvmstatModel, Application> {\n\n    private static JvmJvmstatModelFactory jvmstatModelFactory;\n\n    private JvmJvmstatModelFactory() {\n    }\n\n    /**\n     * Getter for the default version of the JvmJvmstatModelFactory.\n     * @return instance of {@link JvmJvmstatModelFactory}.\n     */\n    public static synchronized JvmJvmstatModelFactory getDefault() {\n        if (jvmstatModelFactory == null) {\n            jvmstatModelFactory = new JvmJvmstatModelFactory();\n        }\n        return jvmstatModelFactory;\n    }\n    \n    /**\n     * Factory method for obtaining {@link JvmJvmstatModel} for {@link Application}. Note that there\n     * is only one instance of {@link JvmJvmstatModel} for a concrete application. This {@link JvmJvmstatModel}\n     * instance is cached. This method can return <CODE>null</CODE> if there is no JvmJvmstatModel\n     * available\n     * @param app application\n     * @return {@link JvmJvmstatModel} instance or <CODE>null</CODE> if there is no\n     * {@link JvmJvmstatModel}\n     */\n    public static JvmJvmstatModel getJvmstatModelFor(Application app) {\n        return getDefault().getModel(app);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jvmstat/JvmstatListener.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jvmstat;\n\n/**\n * \n * Interface for listeners of JvmstatModel changes.\n * \n * @author Tomas Hurka\n */\npublic interface JvmstatListener {\n   \n    /**\n     * Invoked when counters are updated. This event is\n     * generated at a fixed interval as determined by the polling rate\n     * of the {@link JvmstatModel} that the {@link JvmstatListener} is registered with.\n     * @param jvmstat the {@link JvmstatModel} that this listener is registered with.\n     */\n    public void dataChanged(JvmstatModel jvmstat);\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jvmstat/JvmstatModel.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jvmstat;\n\nimport java.util.List;\nimport org.graalvm.visualvm.core.model.Model;\n\n/**\n * This class uses Jvmstat technology \n * (http://java.sun.com/performance/jvmstat/)\n * to obtain various information from JVM. Note that\n * Jvmstat is available in JDK 1.4.2 and up. It is also available for\n * remote Java applications if  \n * <a href=http://download.oracle.com/javase/1.5.0/docs/tooldocs/share/jstatd.html>jstatd daemon</a>\n * is running on remote host.\n * \n * @author Tomas Hurka\n */\npublic abstract class JvmstatModel extends Model {\n        \n    /**\n     * \n     * Find a named counter exported via Jvmstat.\n     * \n     * This method will look for the named counter exported\n     * via Jvmstat. If a counter with a given name exists, a\n     * string value of such counter is returned. Otherwise,\n     * the method returns <CODE>null</CODE>.\n     * @param name the name of the counter to find.\n     * @return the string value of the counter, or <CODE>null</CODE> \n     * if the named counter doesn't exist.\n     */\n    public abstract String findByName(String name);\n\n    /**\n     * \n     * Find a named counter exported via Jvmstat.\n     * \n     * This method will look for the named counter exported\n     * via Jvmstat. If a counter with a given name exists, a\n     * {@link MonitoredValue} interface to that counter will \n     * be return. Otherwise, the method returns <CODE>null</CODE>.\n     * @param name the name of the counter to find.\n     * @return the {@link MonitoredValue} that can be used to\n     * monitor the named counter, or <CODE>null</CODE>\n     * if the named counter doesn't exist.\n     */\n    public abstract MonitoredValue findMonitoredValueByName(String name);\n    \n    /**\n     * \n     * Find a list of the named counters exported via Jvmstat.\n     * \n     * This method will look for the named counters with \n     * names matching the given pattern. This method returns a \n     * {@link List} of string values of the counters such that\n     * the name of each counter matches the given pattern.\n     * @param pattern a string containing a pattern as described in\n     * {@link java.util.regex.Pattern}.\n     * @return a List of string values of the matching counters.\n     */\n    public abstract List<String> findByPattern(String pattern);\n    \n    /**\n     * Gets this connection's ID which identifies a target Java Virtual Machine.  For a\n     * given Java Virtual Machine, connection ID is unique id\n     * which does not change during the lifetime of the\n     * Java Virtual Machine.\n     *\n     * @return the unique ID of a target Java Virtual Machine.\n     */\n    public abstract String getConnectionId();\n    \n    /**\n     * Find a list of the named counters exported via Jvmstat.\n     * \n     * This method will look for the named counters with \n     * names matching the given pattern. This method returns a \n     * {@link List} of {@link MonitoredValue} of the counters such that\n     * the name of each counter matches the given pattern.\n     * @param pattern a string containing a pattern as described in\n     * {@link java.util.regex.Pattern}.\n     * @return a List of {@link MonitoredValue} of the matching counters.\n     */\n    public abstract List<MonitoredValue> findMonitoredValueByPattern(String pattern);\n    \n    /**\n     * \n     * adds {@link JvmstatListener}\n     * @param l an implementation of {@link JvmstatListener}\n     */\n    public abstract void addJvmstatListener(JvmstatListener l);\n    \n    /**\n     * \n     * removes {@link JvmstatListener}\n     * @param l an implementation of {@link JvmstatListener}\n     */\n    public abstract void removeJvmstatListener(JvmstatListener l);\n    \n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jvmstat/JvmstatModelFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jvmstat;\n\nimport org.graalvm.visualvm.application.Application;\nimport org.graalvm.visualvm.core.model.ModelFactory;\n\n/**\n * The JvmstatModelFactory class is a factory class for getting the\n * {@link JvmstatModel} representation for the {@link Application}.\n * \n * @author Tomas Hurka\n */\npublic final class JvmstatModelFactory extends ModelFactory<JvmstatModel, Application> {\n\n    private static JvmstatModelFactory jvmstatFactory;\n\n    private JvmstatModelFactory() {\n    }\n\n    /**\n     * Getter for the default version of the JvmstatModelFactory.\n     * @return instance of {@link JvmstatModelFactory}.\n     */\n    public static synchronized JvmstatModelFactory getDefault() {\n        if (jvmstatFactory == null) {\n            jvmstatFactory = new JvmstatModelFactory();\n        }\n        return jvmstatFactory;\n    }\n    \n    /**\n     * Factory method for obtaining {@link JvmstatModel} for {@link Application}. Note that there\n     * is only one instance of {@link JvmstatModel} for a concrete application. This {@link JvmstatModel}\n     * instance is cached. This method can return <CODE>null</CODE> if there is no JvmstatModel\n     * available\n     * @param app application\n     * @return {@link JvmstatModel} instance or <CODE>null</CODE> if there is no\n     * {@link JvmstatModel}\n     */\n    public static JvmstatModel getJvmstatFor(Application app) {\n        return getDefault().getModel(app);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jvmstat/MonitoredValue.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.jvmstat;\n\n/**\n * \n * This class encapsulates a counter exported via Jvmstat\n * @author Tomas Hurka\n */\npublic abstract class MonitoredValue  {\n    \n    /**\n     * Returns the name of this counter.\n     * @return String - the name assigned to this counter\n     */\n    public abstract String getName();\n    \n    /**\n     * Return an Object that encapsulates this counter's\n     * current data value.\n     * @return value of the counter, primitive types are wrapped into Integer, Long, Float objects,\n     */\n    public abstract Object getValue();\n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/jvmstat/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Jvmstat support in VisualVM.\n */\npackage org.graalvm.visualvm.tools.jvmstat;\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/sa/SaModel.java",
    "content": "/*\n * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.sa;\n\nimport java.util.Properties;\nimport org.graalvm.visualvm.core.model.Model;\n\n/**\n * This class uses Serviceability Agent (SA)\n * (http://openjdk.java.net/groups/hotspot/docs/Serviceability.html)\n * to obtain various information from JVM. Note that\n * Serviceability Agent is available in JDK 5 and up and only for Linux and Solaris.\n * \n * @author Tomas Hurka\n */\npublic abstract class SaModel extends Model {\n\n    /**\n     * Returns the current system properties in the target Application.\n     * \n     * <p> This method returns the system properties in the target virtual\n     * machine. Properties whose key or value is not a <tt>String</tt> are \n     * omitted. The method is approximately equivalent to the invocation of the\n     * method {@link java.lang.System#getProperties System.getProperties}\n     * in the target virtual machine except that properties with a key or\n     * value that is not a <tt>String</tt> are not included.\n     * @return The system properties of target Application\n     * @see java.lang.System#getProperties\n     */\n    public abstract Properties getSystemProperties();\n    \n    /**\n     * Takes heap dump of target Application.\n     * The heap is written to the <tt>fileName</tt> file in the same\n     * format as the hprof heap dump.\n     * @return returns <CODE>true</CODE> if operation was successful.\n     * @param fileName {@link String} where heap dump will be stored.\n     */\n    public abstract boolean takeHeapDump(String fileName);\n    \n    /**\n     * Takes thread dump of target Application.\n     * @return Returns {@link String} of the thread dump from target Application.\n     */\n    public abstract String takeThreadDump();\n    \n    /**\n     * Returns the Java virtual machine flags.\n     *\n     * @return String - contains the flags of the target Java\n     *                  application or <CODE>NULL</CODE> if the\n     *                  flags be determined.\n     */\n    public abstract String getJvmFlags();\n    \n    /**\n     * Returns the Java virtual machine command line arguments.\n     *\n     * @return String - contains the command line arguments of the target Java\n     *                  application or <CODE>NULL</CODE> if the\n     *                  command line arguments cannot be determined.\n     */\n    public abstract String getJvmArgs();\n    \n    /**\n     * Returns the Java virtual machine command line.\n     *\n     * @return String - contains the command line of the target Java\n     *                  application or <CODE>NULL</CODE> if the\n     *                  command line cannot be determined.\n     */\n    public abstract String getJavaCommand();\n    \n    /**\n     * Returns the Java virtual machine implementation version. \n     * This method is equivalent to {@link System#getProperty \n     * System.getProperty(\"java.vm.version\")}.\n     *\n     * @return the Java virtual machine implementation version.\n     *\n     * @see java.lang.System#getProperty\n     */\n    public String getVmVersion() {\n        return findByName(\"java.vm.version\");  //NOI18N\n    }\n    \n   /**\n     * Returns the Java virtual machine home directory. \n     * This method is equivalent to {@link System#getProperty \n     * System.getProperty(\"java.home\")}.\n     *\n     * @return the Java virtual machine home directory.\n     *\n     * @see java.lang.System#getProperty\n     */\n    public String getJavaHome() {\n        return findByName(\"java.home\"); //NOI18N\n    }\n    \n   /**\n     * Returns the Java virtual machine VM info. \n     * This method is equivalent to {@link System#getProperty \n     * System.getProperty(\"java.vm.info\")}.\n     *\n     * @return the Java virtual machine VM info.\n     *\n     * @see java.lang.System#getProperty\n     */\n    public String getVmInfo() {\n        return findByName(\"java.vm.info\"); //NOI18N\n    }\n    \n    /**\n     * Returns the Java virtual machine implementation name. \n     * This method is equivalent to {@link System#getProperty \n     * System.getProperty(\"java.vm.name\")}.\n     *\n     * @return the Java virtual machine implementation name.\n     *\n     * @see java.lang.System#getProperty\n     */\n    public String getVmName() {\n        return findByName(\"java.vm.name\"); //NOI18N\n    }\n    \n    private String findByName(String key) {\n        Properties p = getSystemProperties();\n        if (p == null)\n            return null;\n        return p.getProperty(key);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/sa/SaModelFactory.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.tools.sa;\n\nimport org.graalvm.visualvm.core.datasource.DataSource;\nimport org.graalvm.visualvm.core.model.ModelFactory;\n\n/**\n * The SaModelFactory class is a factory class for getting the\n * {@link SaModel} representation for the {@link DataSource}.\n * \n * @author Tomas Hurka\n */\npublic final class SaModelFactory extends ModelFactory<SaModel, DataSource> {\n\n    private static SaModelFactory saAgentFactory;\n\n    private SaModelFactory() {\n    }\n\n    /**\n     * Getter for the default version of the SaModelFactory.\n     * @return instance of {@link SaModelFactory}.\n     */\n    public static synchronized SaModelFactory getDefault() {\n        if (saAgentFactory == null) {\n            saAgentFactory = new SaModelFactory();\n        }\n        return saAgentFactory;\n    }\n    \n    /**\n     * Factory method for obtaining {@link SaModel} for {@link DataSource}.\n     * Note that there is only one instance of {@link SaModel} for a concrete\n     * data source. This {@link SaModel} instance is cached. This method can \n     * return <CODE>null</CODE> if there is no AttachModel available\n     * @param app application\n     * @return {@link SaModel} instance or <CODE>null</CODE> if there is no\n     * {@link SaModel}\n     */\n    public static SaModel getSAAgentFor(DataSource app) {\n        return getDefault().getModel(app);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/tools/src/org/graalvm/visualvm/tools/sa/package-info.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\n/**\n * Serviceability Agent support in VisualVM.\n */\npackage org.graalvm.visualvm.tools.sa;\n"
  },
  {
    "path": "visualvm/uisupport/build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!-- You may freely edit this file. See harness/README in the NetBeans platform -->\n<!-- for some information on what you could do (e.g. targets to override). -->\n<!-- If you delete this file and reopen the project it will be recreated. -->\n<project name=\"org.graalvm.visualvm.uisupport\" default=\"netbeans\" basedir=\".\">\n    <description>Builds, tests, and runs the project org.graalvm.visualvm.uisupport.</description>\n    <import file=\"nbproject/build-impl.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/uisupport/manifest.mf",
    "content": "Manifest-Version: 1.0\nAutoUpdate-Show-In-Client: false\nOpenIDE-Module: org.graalvm.visualvm.uisupport/2\nOpenIDE-Module-Localizing-Bundle: org/graalvm/visualvm/uisupport/Bundle.properties\nOpenIDE-Module-Specification-Version: 2.1\n\n"
  },
  {
    "path": "visualvm/uisupport/nbproject/build-impl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n\n<!--\n*** GENERATED FROM project.xml - DO NOT EDIT  ***\n***         EDIT ../build.xml INSTEAD         ***\n-->\n<project name=\"org.graalvm.visualvm.uisupport-impl\" basedir=\"..\" xmlns:nbmproject=\"http://www.netbeans.org/ns/nb-module-project/2\">\n    <property file=\"nbproject/private/suite-private.properties\"/>\n    <property file=\"nbproject/suite.properties\"/>\n    <fail unless=\"suite.dir\">You must set 'suite.dir' to point to your containing module suite</fail>\n    <property file=\"${suite.dir}/nbproject/private/platform-private.properties\"/>\n    <property file=\"${suite.dir}/nbproject/platform.properties\"/>\n    <macrodef name=\"property\" uri=\"http://www.netbeans.org/ns/nb-module-project/2\">\n        <attribute name=\"name\"/>\n        <attribute name=\"value\"/>\n        <sequential>\n            <property name=\"@{name}\" value=\"${@{value}}\"/>\n        </sequential>\n    </macrodef>\n    <property file=\"${user.properties.file}\"/>\n    <nbmproject:property name=\"harness.dir\" value=\"nbplatform.${nbplatform.active}.harness.dir\"/>\n    <nbmproject:property name=\"netbeans.dest.dir\" value=\"nbplatform.${nbplatform.active}.netbeans.dest.dir\"/>\n    <fail message=\"You must define 'nbplatform.${nbplatform.active}.harness.dir'\">\n        <condition>\n            <not>\n                <available file=\"${harness.dir}\" type=\"dir\"/>\n            </not>\n        </condition>\n    </fail>\n    <import file=\"${harness.dir}/build.xml\"/>\n</project>\n"
  },
  {
    "path": "visualvm/uisupport/nbproject/project.properties",
    "content": "#\n# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n#\n# This code is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License version 2 only, as\n# published by the Free Software Foundation.  Oracle designates this\n# particular file as subject to the \"Classpath\" exception as provided\n# by Oracle in the LICENSE file that accompanied this code.\n#\n# This code is distributed in the hope that it will be useful, but WITHOUT\n# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n# version 2 for more details (a copy is included in the LICENSE file that\n# accompanied this code).\n#\n# You should have received a copy of the GNU General Public License version\n# 2 along with this work; if not, write to the Free Software Foundation,\n# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n#\n# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n# or visit www.oracle.com if you need additional information or have any\n# questions.\n\nis.autoload=true\njavac.source=1.8\njavac.compilerargs=-Xlint -Xlint:-serial\nlicense.file=../startup/src/org/graalvm/visualvm/modules/startup/LICENSE.txt\nnbm.homepage=https://visualvm.github.io\nnbm.module.author=Jiri Sedlacek\n"
  },
  {
    "path": "visualvm/uisupport/nbproject/project.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n This code is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License version 2 only, as\n published by the Free Software Foundation.  Oracle designates this\n particular file as subject to the \"Classpath\" exception as provided\n by Oracle in the LICENSE file that accompanied this code.\n\n This code is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n version 2 for more details (a copy is included in the LICENSE file that\n accompanied this code).\n\n You should have received a copy of the GNU General Public License version\n 2 along with this work; if not, write to the Free Software Foundation,\n Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n\n Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n or visit www.oracle.com if you need additional information or have any\n questions.\n-->\n<project xmlns=\"http://www.netbeans.org/ns/project/1\">\n    <type>org.netbeans.modules.apisupport.project</type>\n    <configuration>\n        <data xmlns=\"http://www.netbeans.org/ns/nb-module-project/3\">\n            <code-name-base>org.graalvm.visualvm.uisupport</code-name-base>\n            <suite-component/>\n            <module-dependencies>\n                <dependency>\n                    <code-name-base>org.graalvm.visualvm.lib.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <release-version>2</release-version>\n                        <specification-version>2.0</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.lookup</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>8.34</specification-version>\n                    </run-dependency>\n                </dependency>\n                <dependency>\n                    <code-name-base>org.openide.util.ui</code-name-base>\n                    <build-prerequisite/>\n                    <compile-dependency/>\n                    <run-dependency>\n                        <specification-version>9.8</specification-version>\n                    </run-dependency>\n                </dependency>\n            </module-dependencies>\n            <friend-packages>\n                <friend>net.java.visualvm.modules.glassfish</friend>\n                <friend>org.graalvm.visualvm.application.views</friend>\n                <friend>org.graalvm.visualvm.charts</friend>\n                <friend>org.graalvm.visualvm.core</friend>\n                <friend>org.graalvm.visualvm.coredump</friend>\n                <friend>org.graalvm.visualvm.heapviewer</friend>\n                <friend>org.graalvm.visualvm.heapviewer.truffle</friend>\n                <friend>org.graalvm.visualvm.host.views</friend>\n                <friend>org.graalvm.visualvm.jfr</friend>\n                <friend>org.graalvm.visualvm.jvmstat</friend>\n                <friend>org.graalvm.visualvm.modules.appui</friend>\n                <friend>org.graalvm.visualvm.modules.jvmcap</friend>\n                <friend>org.graalvm.visualvm.modules.security</friend>\n                <friend>org.graalvm.visualvm.modules.threadinspect</friend>\n                <friend>org.graalvm.visualvm.modules.tracer</friend>\n                <friend>org.graalvm.visualvm.profiler</friend>\n                <friend>org.graalvm.visualvm.profiler.startup</friend>\n                <friend>org.graalvm.visualvm.profiling</friend>\n                <friend>org.graalvm.visualvm.sampler</friend>\n                <friend>org.graalvm.visualvm.sampler.truffle</friend>\n                <friend>org.graalvm.visualvm.threaddump</friend>\n                <package>org.graalvm.visualvm.uisupport</package>\n            </friend-packages>\n        </data>\n    </configuration>\n</project>\n"
  },
  {
    "path": "visualvm/uisupport/nbproject/suite.properties",
    "content": "suite.dir=${basedir}/..\n"
  },
  {
    "path": "visualvm/uisupport/src/org/graalvm/visualvm/uisupport/Bundle.properties",
    "content": "OpenIDE-Module-Display-Category=Libraries\nOpenIDE-Module-Name=VisualVM-UISupport\nOpenIDE-Module-Short-Description=This module provides UI components and services to be used in VisualVM tool and plugins\n"
  },
  {
    "path": "visualvm/uisupport/src/org/graalvm/visualvm/uisupport/HTMLLabel.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.uisupport;\n\nimport java.awt.*;\nimport java.net.URL;\nimport javax.swing.*;\nimport javax.swing.event.HyperlinkEvent;\nimport javax.swing.event.HyperlinkListener;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.JTextComponent;\nimport javax.swing.text.NavigationFilter;\nimport javax.swing.text.Position;\nimport javax.swing.text.html.HTMLEditorKit;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * Copy of org.graalvm.visualvm.lib.ui.components.HTMLLabel to be used in\n * VisualVM tool an plugins.\n *\n * @author Jiri Sedlacek\n */\npublic class HTMLLabel extends JEditorPane implements HyperlinkListener {\n    \n    private int halign = SwingConstants.LEADING;\n    \n\n    public HTMLLabel() {\n        this(null);\n    }\n\n    public HTMLLabel(String text) {\n        setEditorKit(new HTMLEditorKit());\n        setEditable(false);\n        setOpaque(false);\n        setNavigationFilter(new NavigationFilter() {\n                public void moveDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias) {\n                    super.moveDot(fb, 0, bias);\n                }\n\n                public void setDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias) {\n                    super.setDot(fb, 0, bias);\n                }\n\n                public int getNextVisualPositionFrom(JTextComponent text, int pos, Position.Bias bias, int direction,\n                                                     Position.Bias[] biasRet)\n                                              throws BadLocationException {\n                    return 0;\n                }\n            });\n        setFont(UIManager.getFont(\"Label.font\")); //NOI18N\n        addHyperlinkListener(this);\n        \n        if (text != null) setText(text);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    public void setOpaque(boolean o) {\n        super.setOpaque(o);\n        if (UIUtils.isNimbusLookAndFeel() && !o)\n            setBackground(new Color(0, 0, 0, 0));\n        if (txt != null) setText(txt);\n    }\n    \n    private String txt;\n\n    public void setText(String value) {\n        txt = value;\n        \n        Font font = getFont();\n        Color fgColor = getForeground();\n        Color bgColor = getBackground();\n        \n        value = value.replaceAll(\"\\\\n\\\\r|\\\\r\\\\n|\\\\n|\\\\r\", \"<br>\"); //NOI18N\n        value = value.replace(\"<code>\", \"<code style=\\\"font-size: \" + font.getSize() + \"pt;\\\">\"); //NOI18N\n        \n        String fgText = \"rgb(\" + fgColor.getRed() + \",\" + fgColor.getGreen() + \",\" + fgColor.getBlue() + \")\"; //NOI18N\n        String bgText = isOpaque() ? \"rgb(\" + bgColor.getRed() + \",\" + bgColor.getGreen() + \",\" + bgColor.getBlue() + \")\" : null; //NOI18N\n        \n        String alignText = null;\n        switch (halign) {\n            case SwingConstants.CENTER:\n                alignText = \"center\"; //NOI18N\n                break;\n            case SwingConstants.RIGHT:\n            case SwingConstants.TRAILING:\n                alignText = \"right\"; //NOI18N\n                break;\n        }\n        \n        String bodyFlags = \"text=\\\"\" + fgText + \"\\\"\"; //NOI18N\n        if (bgText != null) bodyFlags += \" bgcolor=\\\"\" + bgText + \"\\\"\"; //NOI18N\n        if (alignText != null) bodyFlags += \" align=\\\"\" + alignText + \"\\\"\"; //NOI18N\n        \n        super.setText(\"<html><body \" + bodyFlags + \" style=\\\"font-size: \" + font.getSize() //NOI18N\n                      + \"pt; font-family: \" + font.getName() + \";\\\">\" + value + \"</body></html>\"); //NOI18N\n    }\n    \n    public void setForeground(Color fg) {\n        super.setForeground(fg);\n        if (txt != null) setText(txt);\n    }\n    \n    public void setBackground(Color bg) {\n        super.setBackground(bg);\n//        setBorder(getBorder());\n        if (txt != null) setText(txt);\n    }\n    \n//    public void setBorder(Border b) {\n//        Insets i = b == null ? new Insets(0, 0, 0, 0) : b.getBorderInsets(this);\n//        if (!isOpaque()) super.setBorder(BorderFactory.createEmptyBorder(i.top, i.left, i.bottom, i.right));\n//        else super.setBorder(BorderFactory.createMatteBorder(i.top, i.left, i.bottom, i.right, getBackground()));\n//    }\n    \n    public void setHorizontalAlignment(int alignment) {\n        if (alignment == halign) return;\n        halign = alignment;\n        if (txt != null) setText(txt);\n    }\n\n    public void hyperlinkUpdate(HyperlinkEvent e) {\n        if (!isEnabled()) {\n            return;\n        }\n\n        if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {\n            showURL(e.getURL());\n        } else if (e.getEventType() == HyperlinkEvent.EventType.ENTERED) {\n            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n        } else if (e.getEventType() == HyperlinkEvent.EventType.EXITED) {\n            setCursor(Cursor.getDefaultCursor());\n        }\n    }\n\n    protected void showURL(URL url) {\n        // override to react to URL clicks\n    }\n}\n"
  },
  {
    "path": "visualvm/uisupport/src/org/graalvm/visualvm/uisupport/HTMLTextArea.java",
    "content": "/*\n * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.uisupport;\n\nimport java.awt.*;\nimport java.awt.datatransfer.Clipboard;\nimport java.awt.datatransfer.DataFlavor;\nimport java.awt.datatransfer.StringSelection;\nimport java.awt.datatransfer.Transferable;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.InputEvent;\nimport java.awt.event.KeyAdapter;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseListener;\nimport java.io.IOException;\nimport java.io.StringWriter;\nimport java.io.Writer;\nimport java.net.URL;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.ResourceBundle;\nimport javax.swing.*;\nimport javax.swing.event.HyperlinkEvent;\nimport javax.swing.event.HyperlinkListener;\nimport javax.swing.text.AttributeSet;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.Element;\nimport javax.swing.text.StyleConstants;\nimport javax.swing.text.html.HTML;\nimport javax.swing.text.html.HTMLDocument;\nimport javax.swing.text.html.HTMLEditorKit;\nimport javax.swing.text.html.HTMLWriter;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * Copy of org.graalvm.visualvm.lib.ui.components.HTMLTextArea to be used in\n * VisualVM tool an plugins.\n * \n * NOTE: out of date, the original code contains additional improvements and bugfixes\n *\n * @author Jiri Sedlacek\n */\npublic class HTMLTextArea extends JEditorPane implements HyperlinkListener, MouseListener {\n    //~ Inner Classes ------------------------------------------------------------------------------------------------------------\n\n    /** Private Writer that extracts correctly formatted string from HTMLDocument */\n    private static class ExtendedHTMLWriter extends HTMLWriter {\n        //~ Constructors ---------------------------------------------------------------------------------------------------------\n\n        ExtendedHTMLWriter(Writer w, HTMLDocument doc, int pos, int len) {\n            super(w, doc, pos, len);\n            setLineLength(Integer.MAX_VALUE);\n        }\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        protected boolean isSupportedBreakFlowTag(AttributeSet attr) {\n            Object o = attr.getAttribute(StyleConstants.NameAttribute);\n\n            if (o instanceof HTML.Tag) {\n                HTML.Tag tag = (HTML.Tag) o;\n\n                if ((tag == HTML.Tag.HTML) || (tag == HTML.Tag.HEAD) || (tag == HTML.Tag.BODY) || (tag == HTML.Tag.HR)) {\n                    return false;\n                }\n\n                return (tag).breaksFlow();\n            }\n\n            return false;\n        }\n\n        protected void emptyTag(Element elem) throws BadLocationException, IOException {\n            if (isSupportedBreakFlowTag(elem.getAttributes())) {\n                writeLineSeparator();\n            }\n\n            if (matchNameAttribute(elem.getAttributes(), HTML.Tag.CONTENT)) {\n                text(elem);\n            }\n        }\n\n        protected void endTag(Element elem) throws IOException {\n            if (isSupportedBreakFlowTag(elem.getAttributes())) {\n                writeLineSeparator();\n            }\n        }\n\n        protected void startTag(Element elem) throws IOException, BadLocationException {\n        }\n    }\n\n    // --- Private classes for copy/paste support --------------------------------\n    //\n    // NOTE: only vertical formatting is correctly copy/pasted,\n    //       horizontal formatting (ul, li) is ignored.\n\n    /** Private TransferHandler that copies correctly formatted string from HTMLDocument to system clipboard */\n    private class HTMLTextAreaTransferHandler extends TransferHandler {\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public void exportToClipboard(JComponent comp, Clipboard clip, int action) {\n            try {\n                int selStart = getSelectionStart();\n                int selLength = getSelectionEnd() - selStart;\n\n                StringWriter plainTextWriter = new StringWriter();\n\n                try {\n                    new ExtendedHTMLWriter(plainTextWriter, (HTMLDocument) getDocument(), selStart, selLength).write();\n                } catch (Exception e) {\n                }\n\n                String plainText = NcrToUnicode.decode(plainTextWriter.toString());\n                clip.setContents(new StringSelection(plainText), null);\n\n                if (action == TransferHandler.MOVE) {\n                    getDocument().remove(selStart, selLength);\n                }\n            } catch (BadLocationException ble) {\n            }\n        }\n    }\n\n    /** Class for decoding strings from NCR to Unicode */\n    private static class NcrToUnicode {\n        //~ Static fields/initializers -------------------------------------------------------------------------------------------\n\n        private static Map<String,String> entities;\n\n        //~ Methods --------------------------------------------------------------------------------------------------------------\n\n        public static String decode(String str) {\n            StringBuilder ostr = new StringBuilder();\n            int i1 = 0;\n            int i2 = 0;\n\n            while (i2 < str.length()) {\n                i1 = str.indexOf('&', i2); //NOI18N\n\n                if (i1 == -1) {\n                    ostr.append(str, i2, str.length());\n\n                    break;\n                }\n\n                ostr.append(str, i2, i1);\n                i2 = str.indexOf(';', i1); //NOI18N\n\n                if (i2 == -1) {\n                    ostr.append(str, i1, str.length());\n\n                    break;\n                }\n\n                String tok = str.substring(i1 + 1, i2);\n\n                if (tok.charAt(0) == '#') { //NOI18N\n\n                    if (tok.equals(\"#160\")) { //NOI18N\n                        ostr.append(getEntities().get(\"nbsp\")); //NOI18N // Fixes Issue 92818, \"&nbsp;\" is resolved as \"&#160;\" before decoding, so redirecting back to \"&nbsp;\"\n                    } else {\n                        tok = tok.substring(1);\n\n                        try {\n                            int radix = 10;\n\n                            if (tok.trim().charAt(0) == 'x') { //NOI18N\n                                radix = 16;\n                                tok = tok.substring(1);\n                            }\n\n                            ostr.append((char) Integer.parseInt(tok, radix));\n                        } catch (NumberFormatException exp) {\n                            ostr.append('?'); //NOI18N\n                        }\n                    }\n                } else {\n                    tok = getEntities().get(tok);\n\n                    if (tok != null) {\n                        ostr.append(tok);\n                    } else {\n                        ostr.append('?'); //NOI18N\n                    }\n                }\n\n                i2++;\n            }\n\n            return ostr.toString();\n        }\n\n        private static synchronized Map<String,String> getEntities() {\n            if (entities == null) {\n                entities = new HashMap<>();\n                //Quotation mark\n                entities.put(\"quot\", \"\\\"\"); //NOI18N\n                                            //Ampersand\n\n                entities.put(\"amp\", \"\\u0026\"); //NOI18N\n                                               //Less than\n\n                entities.put(\"lt\", \"\\u003C\"); //NOI18N\n                                              //Greater than\n\n                entities.put(\"gt\", \"\\u003E\"); //NOI18N\n                                              //Nonbreaking space\n\n                entities.put(\"nbsp\", \"\\u0020\"); //NOI18N // Fixes Issue 92818, \"\\u00A0\" (&nbsp; equivalent) is resolved as incorrect character, thus mapping to standard space\n                                                //Inverted exclamation point\n\n                entities.put(\"iexcl\", \"\\u00A1\"); //NOI18N\n                                                 //Cent sign\n\n                entities.put(\"cent\", \"\\u00A2\"); //NOI18N\n                                                //Pound sign\n\n                entities.put(\"pound\", \"\\u00A3\"); //NOI18N\n                                                 //General currency sign\n\n                entities.put(\"curren\", \"\\u00A4\"); //NOI18N\n                                                  //Yen sign\n\n                entities.put(\"yen\", \"\\u00A5\"); //NOI18N\n                                               //Broken vertical bar\n\n                entities.put(\"brvbar\", \"\\u00A6\"); //NOI18N\n                                                  //Section sign\n\n                entities.put(\"sect\", \"\\u00A7\"); //NOI18N\n                                                //Umlaut\n\n                entities.put(\"uml\", \"\\u00A8\"); //NOI18N\n                                               //Copyright\n\n                entities.put(\"copy\", \"\\u00A9\"); //NOI18N\n                                                //Feminine ordinal\n\n                entities.put(\"ordf\", \"\\u00AA\"); //NOI18N\n                                                //Left angle quote\n\n                entities.put(\"laquo\", \"\\u00AB\"); //NOI18N\n                                                 //Not sign\n\n                entities.put(\"not\", \"\\u00AC\"); //NOI18N\n                                               //Soft hyphen\n\n                entities.put(\"shy\", \"\\u00AD\"); //NOI18N\n                                               //Registered trademark\n\n                entities.put(\"reg\", \"\\u00AE\"); //NOI18N\n                                               //Macron accent\n\n                entities.put(\"macr\", \"\\u00AF\"); //NOI18N\n                                                //Degree sign\n\n                entities.put(\"deg\", \"\\u00B0\"); //NOI18N\n                                               //Plus or minus\n\n                entities.put(\"plusmn\", \"\\u00B1\"); //NOI18N\n                                                  //Superscript 2\n\n                entities.put(\"sup2\", \"\\u00B2\"); //NOI18N\n                                                //Superscript 3\n\n                entities.put(\"sup3\", \"\\u00B3\"); //NOI18N\n                                                //Acute accent\n\n                entities.put(\"acute\", \"\\u00B4\"); //NOI18N\n                                                 //Micro sign (Greek mu)\n\n                entities.put(\"micro\", \"\\u00B5\"); //NOI18N\n                                                 //Paragraph sign\n\n                entities.put(\"para\", \"\\u00B6\"); //NOI18N\n                                                //Middle dot\n\n                entities.put(\"middot\", \"\\u00B7\"); //NOI18N\n                                                  //Cedilla\n\n                entities.put(\"cedil\", \"\\u00B8\"); //NOI18N\n                                                 //Superscript 1\n\n                entities.put(\"sup1\", \"\\u00B9\"); //NOI18N\n                                                //Masculine ordinal\n\n                entities.put(\"ordm\", \"\\u00BA\"); //NOI18N\n                                                //Right angle quote\n\n                entities.put(\"raquo\", \"\\u00BB\"); //NOI18N\n                                                 //Fraction one-fourth\n\n                entities.put(\"frac14\", \"\\u00BC\"); //NOI18N\n                                                  //Fraction one-half\n\n                entities.put(\"frac12\", \"\\u00BD\"); //NOI18N\n                                                  //Fraction three-fourths\n\n                entities.put(\"frac34\", \"\\u00BE\"); //NOI18N\n                                                  //Inverted question mark\n\n                entities.put(\"iquest\", \"\\u00BF\"); //NOI18N\n                                                  //Capital A, grave accent\n\n                entities.put(\"Agrave\", \"\\u00C0\"); //NOI18N\n                                                  //Capital A, acute accent\n\n                entities.put(\"Aacute\", \"\\u00C1\"); //NOI18N\n                                                  //Capital A, circumflex accent\n\n                entities.put(\"Acirc\", \"\\u00C2\"); //NOI18N\n                                                 //Capital A, tilde\n\n                entities.put(\"Atilde\", \"\\u00C3\"); //NOI18N\n                                                  //Capital A, umlaut\n\n                entities.put(\"Auml\", \"\\u00C4\"); //NOI18N\n                                                //Capital A, ring\n\n                entities.put(\"Aring\", \"\\u00C5\"); //NOI18N\n                                                 //Capital AE ligature\n\n                entities.put(\"AElig\", \"\\u00C6\"); //NOI18N\n                                                 //Capital C, cedilla\n\n                entities.put(\"Ccedil\", \"\\u00C7\"); //NOI18N\n                                                  //Capital E, grave accent\n\n                entities.put(\"Egrave\", \"\\u00C8\"); //NOI18N\n                                                  //Capital E, acute accent\n\n                entities.put(\"Eacute\", \"\\u00C9\"); //NOI18N\n                                                  //Capital E, circumflex accent\n\n                entities.put(\"Ecirc\", \"\\u00CA\"); //NOI18N\n                                                 //Capital E, umlaut\n\n                entities.put(\"Euml\", \"\\u00CB\"); //NOI18N\n                                                //Capital I, grave accent\n\n                entities.put(\"Igrave\", \"\\u00CC\"); //NOI18N\n                                                  //Capital I, acute accent\n\n                entities.put(\"Iacute\", \"\\u00CD\"); //NOI18N\n                                                  //Capital I, circumflex accent\n\n                entities.put(\"Icirc\", \"\\u00CE\"); //NOI18N\n                                                 //Capital I, umlaut\n\n                entities.put(\"Iuml\", \"\\u00CF\"); //NOI18N\n                                                //Capital eth, Icelandic\n\n                entities.put(\"ETH\", \"\\u00D0\"); //NOI18N\n                                               //Capital N, tilde\n\n                entities.put(\"Ntilde\", \"\\u00D1\"); //NOI18N\n                                                  //Capital O, grave accent\n\n                entities.put(\"Ograve\", \"\\u00D2\"); //NOI18N\n                                                  //Capital O, acute accent\n\n                entities.put(\"Oacute\", \"\\u00D3\"); //NOI18N\n                                                  //Capital O, circumflex accent\n\n                entities.put(\"Ocirc\", \"\\u00D4\"); //NOI18N\n                                                 //Capital O, tilde\n\n                entities.put(\"Otilde\", \"\\u00D5\"); //NOI18N\n                                                  //Capital O, umlaut\n\n                entities.put(\"Ouml\", \"\\u00D6\"); //NOI18N\n                                                //Multiply sign\n\n                entities.put(\"times\", \"\\u00D7\"); //NOI18N\n                                                 //Capital O, slash\n\n                entities.put(\"Oslash\", \"\\u00D8\"); //NOI18N\n                                                  //Capital U, grave accent\n\n                entities.put(\"Ugrave\", \"\\u00D9\"); //NOI18N\n                                                  //Capital U, acute accent\n\n                entities.put(\"Uacute\", \"\\u00DA\"); //NOI18N\n                                                  //Capital U, circumflex accent\n\n                entities.put(\"Ucirc\", \"\\u00DB\"); //NOI18N\n                                                 //Capital U, umlaut\n\n                entities.put(\"Uuml\", \"\\u00DC\"); //NOI18N\n                                                //Capital Y, acute accent\n\n                entities.put(\"Yacute\", \"\\u00DD\"); //NOI18N\n                                                  //Capital thorn, Icelandic\n\n                entities.put(\"THORN\", \"\\u00DE\"); //NOI18N\n                                                 //Small sz ligature, German\n\n                entities.put(\"szlig\", \"\\u00DF\"); //NOI18N\n                                                 //Small a, grave accent\n\n                entities.put(\"agrave\", \"\\u00E0\"); //NOI18N\n                                                  //Small a, acute accent\n\n                entities.put(\"aacute\", \"\\u00E1\"); //NOI18N\n                                                  //Small a, circumflex accent\n\n                entities.put(\"acirc\", \"\\u00E2\"); //NOI18N\n                                                 //Small a, tilde\n\n                entities.put(\"atilde\", \"\\u00E3\"); //NOI18N\n                                                  //Small a, umlaut\n\n                entities.put(\"auml\", \"\\u00E4\"); //NOI18N\n                                                //Small a, ring\n\n                entities.put(\"aring\", \"\\u00E5\"); //NOI18N\n                                                 //Small ae ligature\n\n                entities.put(\"aelig\", \"\\u00E6\"); //NOI18N\n                                                 //Small c, cedilla\n\n                entities.put(\"ccedil\", \"\\u00E7\"); //NOI18N\n                                                  //Small e, grave accent\n\n                entities.put(\"egrave\", \"\\u00E8\"); //NOI18N\n                                                  //Small e, acute accent\n\n                entities.put(\"eacute\", \"\\u00E9\"); //NOI18N\n                                                  //Small e, circumflex accent\n\n                entities.put(\"ecirc\", \"\\u00EA\"); //NOI18N\n                                                 //Small e, umlaut\n\n                entities.put(\"euml\", \"\\u00EB\"); //NOI18N\n                                                //Small i, grave accent\n\n                entities.put(\"igrave\", \"\\u00EC\"); //NOI18N\n                                                  //Small i, acute accent\n\n                entities.put(\"iacute\", \"\\u00ED\"); //NOI18N\n                                                  //Small i, circumflex accent\n\n                entities.put(\"icirc\", \"\\u00EE\"); //NOI18N\n                                                 //Small i, umlaut\n\n                entities.put(\"iuml\", \"\\u00EF\"); //NOI18N\n                                                //Small eth, Icelandic\n\n                entities.put(\"eth\", \"\\u00F0\"); //NOI18N\n                                               //Small n, tilde\n\n                entities.put(\"ntilde\", \"\\u00F1\"); //NOI18N\n                                                  //Small o, grave accent\n\n                entities.put(\"ograve\", \"\\u00F2\"); //NOI18N\n                                                  //Small o, acute accent\n\n                entities.put(\"oacute\", \"\\u00F3\"); //NOI18N\n                                                  //Small o, circumflex accent\n\n                entities.put(\"ocirc\", \"\\u00F4\"); //NOI18N\n                                                 //Small o, tilde\n\n                entities.put(\"otilde\", \"\\u00F5\"); //NOI18N\n                                                  //Small o, umlaut\n\n                entities.put(\"ouml\", \"\\u00F6\"); //NOI18N\n                                                //Division sign\n\n                entities.put(\"divide\", \"\\u00F7\"); //NOI18N\n                                                  //Small o, slash\n\n                entities.put(\"oslash\", \"\\u00F8\"); //NOI18N\n                                                  //Small u, grave accent\n\n                entities.put(\"ugrave\", \"\\u00F9\"); //NOI18N\n                                                  //Small u, acute accent\n\n                entities.put(\"uacute\", \"\\u00FA\"); //NOI18N\n                                                  //Small u, circumflex accent\n\n                entities.put(\"ucirc\", \"\\u00FB\"); //NOI18N\n                                                 //Small u, umlaut\n\n                entities.put(\"uuml\", \"\\u00FC\"); //NOI18N\n                                                //Small y, acute accent\n\n                entities.put(\"yacute\", \"\\u00FD\"); //NOI18N\n                                                  //Small thorn, Icelandic\n\n                entities.put(\"thorn\", \"\\u00FE\"); //NOI18N\n                                                 //Small y, umlaut\n\n                entities.put(\"yuml\", \"\\u00FF\"); //NOI18N\n            }\n\n            return entities;\n        }\n    }\n\n    //~ Static fields/initializers -----------------------------------------------------------------------------------------------\n\n    // -----\n    // I18N String constants\n    private static final ResourceBundle messages = ResourceBundle.getBundle(\"org.graalvm.visualvm.lib.ui.components.Bundle\"); // NOI18N\n    private static final String CUT_STRING = messages.getString(\"HTMLTextArea_CutString\"); // NOI18N\n    private static final String COPY_STRING = messages.getString(\"HTMLTextArea_CopyString\"); // NOI18N\n    private static final String PASTE_STRING = messages.getString(\"HTMLTextArea_PasteString\"); // NOI18N\n    private static final String DELETE_STRING = messages.getString(\"HTMLTextArea_DeleteString\"); // NOI18N\n    private static final String SELECT_ALL_STRING = messages.getString(\"HTMLTextArea_SelectAllString\"); // NOI18N\n                                                                                                        // -----\n\n    //~ Instance fields ----------------------------------------------------------------------------------------------------------\n\n    private ActionListener popupListener;\n    private JMenuItem itemCopy;\n    private JMenuItem itemCut;\n    private JMenuItem itemDelete;\n    private JMenuItem itemPaste;\n    private JMenuItem itemSelectAll;\n\n    // --- Popup menu support ----------------------------------------------------\n    private JPopupMenu popupMenu;\n    private boolean showPopup = true;\n\n    // --- Lazy setting text ---------------------------------------------------\n    private String pendingText;\n    private String currentText;\n    private boolean forceSetText;\n    \n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public HTMLTextArea() {\n        setEditorKit(new HTMLEditorKit());\n        setEditable(false);\n        setOpaque(true);\n        setAutoscrolls(true);\n        addHyperlinkListener(this);\n        setTransferHandler(new HTMLTextAreaTransferHandler());\n        setFont(UIManager.getFont(\"Label.font\")); //NOI18N\n        setBackground(UIUtils.getProfilerResultsBackground());\n        addMouseListener(this);\n        \n        addKeyListener(new KeyAdapter() {\n            public void keyPressed(KeyEvent e) {\n                if (e.getKeyCode() == KeyEvent.VK_SPACE)\n                    invokeSelectedLink();\n            }\n        });\n\n        // Bugfix #185777, update text only if visible\n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (isShowing() && pendingText != null) setText(pendingText);\n                }\n            }\n        });\n    }\n\n    public HTMLTextArea(String text) {\n        this();\n        setText(text);\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n    \n    public void setOpaque(boolean o) {\n        super.setOpaque(o);\n        if (UIUtils.isNimbusLookAndFeel() && !o)\n            setBackground(new Color(0, 0, 0, 0));\n    }\n\n    public void setForeground(Color color) {\n        Color foreground = getForeground();\n        if (foreground != null && foreground.equals(color)) return;\n\n        super.setForeground(color);\n        forceSetText = true;\n        setText(getText());\n    }\n\n    public void setShowPopup(boolean showPopup) {\n        this.showPopup = showPopup;\n    }\n\n    public boolean getShowPopup() {\n        return showPopup;\n    }\n\n    public void setText(String value) {\n        if (value == null) return;\n\n        if (!isShowing() && !forceSetText) {\n\n            pendingText = value;\n\n        } else {\n\n            if (!forceSetText && value.equals(currentText)) return;\n\n            currentText = value;\n            pendingText = null;\n\n            Font font = getFont();\n            Color textColor = getForeground();\n            value = value.replaceAll(\"\\\\n\\\\r|\\\\r\\\\n|\\\\n|\\\\r\", \"<br>\"); //NOI18N\n            value = value.replace(\"<code>\", \"<code style=\\\"font-size: \" + font.getSize() + \"pt;\\\">\"); //NOI18N\n\n            String colorText = \"rgb(\" + textColor.getRed() + \",\" + textColor.getGreen() + \",\" + textColor.getBlue() + \")\"; //NOI18N\n            String newText = \"<html><body text=\\\"\" + colorText + \"\\\" style=\\\"font-size: \" + font.getSize() + //NOI18N\n                             \"pt; font-family: \" + font.getName() + \";\\\">\" + value + \"</body></html>\"; //NOI18N\n\n            setDocument(getEditorKit().createDefaultDocument()); // Workaround for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5042872\n            super.setText(newText);\n\n        }\n\n        forceSetText = false;\n    }\n\n    public String getText() {\n        return pendingText != null ? pendingText : currentText;\n    }\n\n    public Dimension getMinimumSize() {\n        if (pendingText != null) {\n            forceSetText = true;\n            setText(pendingText);\n        }\n        return super.getMinimumSize();\n    }\n\n    public Dimension getPreferredSize() {\n        if (pendingText != null) {\n            forceSetText = true;\n            setText(pendingText);\n        }\n        return super.getPreferredSize();\n    }\n\n    public Dimension getMaximumSize() {\n        if (pendingText != null) {\n            forceSetText = true;\n            setText(pendingText);\n        }\n        return super.getMaximumSize();\n    }\n\n    public void deleteSelection() {\n        try {\n            getDocument().remove(getSelectionStart(), getSelectionEnd() - getSelectionStart());\n        } catch (Exception ex) {}\n    }\n    \n    private void invokeSelectedLink() {\n        for (Action action : getEditorKit().getActions()) {\n            if (\"activate-link-action\".equals(action.getValue(Action.NAME))) {  // NOI18N\n                action.actionPerformed(new ActionEvent(this, 0, null));\n                return;\n            }\n        }\n    }\n\n    public void hyperlinkUpdate(HyperlinkEvent e) {\n        if (!isEnabled()) {\n            return;\n        }\n\n        if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {\n            showURL(e.getURL());\n        } else if (e.getEventType() == HyperlinkEvent.EventType.ENTERED) {\n            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));\n        } else if (e.getEventType() == HyperlinkEvent.EventType.EXITED) {\n            setCursor(Cursor.getDefaultCursor());\n        }\n    }\n\n    private void showPopupMenu(MouseEvent e) {\n        if (isEnabled() && isFocusable() && showPopup) {\n            JPopupMenu popup = getPopupMenu();\n\n            if (popup != null) {\n                updatePopupMenu();\n\n                if (!hasFocus()) {\n                    requestFocus(); // required for Select All functionality\n                }\n\n                popup.show(this, e.getX(), e.getY());\n            }\n        }\n    }\n\n    public void mouseClicked(MouseEvent e) {\n    }\n\n    public void mouseEntered(MouseEvent e) {\n    }\n\n    public void mouseExited(MouseEvent e) {\n    }\n\n    public void mousePressed(MouseEvent e) {\n        if (e.isPopupTrigger()) showPopupMenu(e);\n    }\n\n    public void mouseReleased(MouseEvent e) {\n        if (e.isPopupTrigger()) showPopupMenu(e);\n    }\n\n    public void paste() {\n        try {\n            replaceSelection(Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this)\n                                    .getTransferData(DataFlavor.stringFlavor).toString());\n        } catch (Exception ex) {\n        }\n    }\n\n    protected JPopupMenu getPopupMenu() {\n        if (popupMenu == null) {\n            popupMenu = createPopupMenu();\n        }\n\n        return popupMenu;\n    }\n\n    protected JPopupMenu createPopupMenu() {\n        JPopupMenu popup = new JPopupMenu();\n\n        popupListener = createPopupListener();\n\n        itemCut = new JMenuItem(CUT_STRING);\n        itemCopy = new JMenuItem(COPY_STRING);\n        itemPaste = new JMenuItem(PASTE_STRING);\n        itemDelete = new JMenuItem(DELETE_STRING);\n        itemSelectAll = new JMenuItem(SELECT_ALL_STRING);\n\n        itemCut.addActionListener(popupListener);\n        itemCopy.addActionListener(popupListener);\n        itemPaste.addActionListener(popupListener);\n        itemDelete.addActionListener(popupListener);\n        itemSelectAll.addActionListener(popupListener);\n\n        popup.add(itemCut);\n        popup.add(itemCopy);\n        popup.add(itemPaste);\n        popup.add(itemDelete);\n        popup.addSeparator();\n        popup.add(itemSelectAll);\n\n        return popup;\n    }\n\n    protected void showURL(URL url) {\n        // override to react to URL clicks\n    }\n\n    protected void updatePopupMenu() {\n        // Cut\n        itemCut.setEnabled(isEditable() && (getSelectedText() != null));\n\n        // Copy\n        itemCopy.setEnabled(getSelectedText() != null);\n\n        // Paste\n        try {\n            Transferable clipboardContent = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this);\n            itemPaste.setEnabled(isEditable() && (clipboardContent != null)\n                                 && clipboardContent.isDataFlavorSupported(DataFlavor.stringFlavor));\n        } catch (Exception e) {\n            itemPaste.setEnabled(false);\n        }\n\n        // Delete\n        if (isEditable()) {\n            itemDelete.setVisible(true);\n            itemDelete.setEnabled(getSelectedText() != null);\n        } else {\n            itemDelete.setVisible(false);\n        }\n\n        // Select All\n        // always visible and enabled...\n    }\n\n    private ActionListener createPopupListener() {\n        return new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    if (e.getSource() == itemCut) {\n                        cut();\n                    } else if (e.getSource() == itemCopy) {\n                        copy();\n                    } else if (e.getSource() == itemPaste) {\n                        paste();\n                    } else if (e.getSource() == itemDelete) {\n                        deleteSelection();\n                    } else if (e.getSource() == itemSelectAll) {\n                        selectAll();\n                    }\n                }\n            };\n    }\n}\n"
  },
  {
    "path": "visualvm/uisupport/src/org/graalvm/visualvm/uisupport/HorizontalLayout.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.uisupport;\n\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Insets;\nimport java.awt.LayoutManager;\nimport javax.swing.Box;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class HorizontalLayout implements LayoutManager {\n\n    private final boolean proportionalHeight;\n    private final int hGap;\n\n\n    public HorizontalLayout(boolean proportionalHeight) {\n        this(proportionalHeight, 0);\n    }\n\n    public HorizontalLayout(boolean proportionalHeight, int hGap) {\n        this.proportionalHeight = proportionalHeight;\n        this.hGap = hGap;\n    }\n\n\n    public void layoutContainer(final Container parent) {\n        final Insets insets = parent.getInsets();\n        int posX = insets.left;\n        final int posY = insets.top;\n        final int height = parent.getHeight() - insets.top - insets.bottom;\n\n        for (Component comp : parent.getComponents()) {\n            if (comp.isVisible()) {\n                Dimension pref = comp.getPreferredSize();\n                if (proportionalHeight) {\n                    int h = Math.min(pref.height, height);\n                    int o = (height - h) / 2;\n                    comp.setBounds(posX, posY + o, pref.width, h);\n                } else {\n                    comp.setBounds(posX, posY, pref.width, height);\n                }\n                posX += hGap;\n                posX += pref.width;\n            }\n        }\n    }\n\n    public Dimension minimumLayoutSize(final Container parent) {\n        final Insets insets = parent.getInsets();\n        final Dimension d = new Dimension(insets.left + insets.right,\n                                          insets.top + insets.bottom);\n        int maxHeight = 0;\n        int visibleCount = 0;\n\n        for (Component comp : parent.getComponents()) {\n            if (comp.isVisible() && !(comp instanceof Box.Filler)) {\n                final Dimension size = comp.getPreferredSize();\n                maxHeight = Math.max(maxHeight, size.height);\n                d.width += size.width;\n                visibleCount++;\n            }\n        }\n\n        d.width += (visibleCount - 1) * hGap;\n        d.height += maxHeight;\n\n        return d;\n    }\n\n    public Dimension preferredLayoutSize(final Container parent) {\n        final Insets insets = parent.getInsets();\n        final Dimension d = new Dimension(insets.left + insets.right,\n                                          insets.top + insets.bottom);\n        int maxHeight = 0;\n        int visibleCount = 0;\n\n        for (Component comp : parent.getComponents()) {\n            if (comp.isVisible()) {\n                final Dimension size = comp.getPreferredSize();\n                maxHeight = Math.max(maxHeight, size.height);\n                d.width += size.width;\n                visibleCount++;\n            }\n        }\n\n        d.width += (visibleCount - 1) * hGap;\n        d.height += maxHeight;\n\n        return d;\n    }\n\n\n    public void addLayoutComponent(final String name, final Component comp) {}\n\n    public void removeLayoutComponent(final Component comp) {}\n\n}\n"
  },
  {
    "path": "visualvm/uisupport/src/org/graalvm/visualvm/uisupport/JExtendedSpinner.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.uisupport;\n\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.event.MouseWheelEvent;\nimport java.awt.event.MouseWheelListener;\nimport javax.swing.JSpinner;\nimport javax.swing.JTextField;\nimport javax.swing.SpinnerModel;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n\n/**\n * Copy of org.graalvm.visualvm.lib.ui.components.JExtendedSpinner to be used\n * in VisualVM tool an plugins.\n *\n * @author Jiri Sedlacek\n */\npublic class JExtendedSpinner extends JSpinner {\n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    private static int defaultSpinnerHeight = -1;\n    \n    public static int getDefaultSpinnerHeight() {\n        if (defaultSpinnerHeight == -1) {\n            defaultSpinnerHeight = new JTextField().getPreferredSize().height;\n        }\n\n        return defaultSpinnerHeight;\n    }\n    \n    //~ Constructors -------------------------------------------------------------------------------------------------------------\n\n    public JExtendedSpinner() {\n        super();\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().setFont(UIManager.getFont(\"Label.font\")); // NOI18N\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().addKeyListener(new java.awt.event.KeyAdapter() {\n                public void keyPressed(final java.awt.event.KeyEvent e) {\n                    if (e.getKeyCode() == java.awt.event.KeyEvent.VK_ESCAPE) {\n                        processKeyEvent(e);\n                    }\n                }\n            });\n        configureWheelListener();\n    }\n\n    public JExtendedSpinner(SpinnerModel model) {\n        super(model);\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().setFont(UIManager.getFont(\"Label.font\")); // NOI18N\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().addKeyListener(new java.awt.event.KeyAdapter() {\n                public void keyPressed(final java.awt.event.KeyEvent e) {\n                    if (e.getKeyCode() == java.awt.event.KeyEvent.VK_ESCAPE) {\n                        processKeyEvent(e);\n                    }\n                }\n            });\n        configureWheelListener();\n    }\n\n    //~ Methods ------------------------------------------------------------------------------------------------------------------\n\n    public void setModel(SpinnerModel model) {\n        Font font = ((JSpinner.DefaultEditor) getEditor()).getTextField().getFont();\n        String accessibleName = ((JSpinner.DefaultEditor) getEditor()).getTextField().getAccessibleContext().getAccessibleName();\n        String accessibleDescription = ((JSpinner.DefaultEditor) getEditor()).getTextField().getAccessibleContext()\n                                        .getAccessibleDescription();\n        super.setModel(model);\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().setFont(font);\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().getAccessibleContext().setAccessibleName(accessibleName);\n        ((JSpinner.DefaultEditor) getEditor()).getTextField().getAccessibleContext()\n         .setAccessibleDescription(accessibleDescription);\n    }\n\n    public void fixAccessibility() {\n        if (getAccessibleContext() != null) {\n            ((JSpinner.DefaultEditor) getEditor()).getTextField().getAccessibleContext()\n             .setAccessibleName(getAccessibleContext().getAccessibleName());\n            ((JSpinner.DefaultEditor) getEditor()).getTextField().getAccessibleContext()\n             .setAccessibleDescription(getAccessibleContext().getAccessibleDescription());\n        }\n    }\n    \n    \n    public Dimension getPreferredSize() {\n        if (UIUtils.isWindowsClassicLookAndFeel()) {\n            return new Dimension(super.getPreferredSize().width, getDefaultSpinnerHeight());\n        } else {\n            return super.getPreferredSize();\n        }\n    }\n\n    public Dimension getMinimumSize() {\n        if (UIUtils.isWindowsClassicLookAndFeel()) {\n            return getPreferredSize();\n        } else {\n            return super.getMinimumSize();\n        }\n    }\n    \n    \n    private void configureWheelListener() {\n        addMouseWheelListener(new MouseWheelListener() {\n            public void mouseWheelMoved(MouseWheelEvent e) {\n                if (e.getScrollType() != MouseWheelEvent.WHEEL_UNIT_SCROLL) return;\n                Object newValue = (e.getWheelRotation() < 0 ?\n                                   JExtendedSpinner.this.getNextValue() :\n                                   JExtendedSpinner.this.getPreviousValue());\n                if (newValue != null) JExtendedSpinner.this.setValue(newValue);\n            }\n        });\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/uisupport/src/org/graalvm/visualvm/uisupport/ProfilerTabbedPane.java",
    "content": "/*\n * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.uisupport;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Window;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.MouseEvent;\nimport java.awt.event.MouseWheelEvent;\nimport java.awt.event.MouseWheelListener;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.Icon;\nimport javax.swing.JLabel;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.JPopupMenu;\nimport javax.swing.JTabbedPane;\nimport javax.swing.SwingUtilities;\nimport javax.swing.UIManager;\nimport javax.swing.plaf.basic.BasicLabelUI;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.graalvm.visualvm.lib.ui.components.CloseButton;\nimport org.openide.util.NbBundle;\nimport sun.swing.SwingUtilities2;\n\n/**\n *\n * @author Jiri Sedlacek\n */\n@NbBundle.Messages({\n    \"ProfilerTabbedPane_Close=Close\",\n    \"ProfilerTabbedPane_CloseOther=Close Other\",\n    \"ProfilerTabbedPane_CloseOtherRight=Close Other to the Right\",\n    \"ProfilerTabbedPane_CloseAll=Close All\"\n})\npublic class ProfilerTabbedPane extends JTabbedPane {\n    \n    private static final boolean IS_AQUA = UIUtils.isAquaLookAndFeel();\n    private static final boolean IS_GTK = UIUtils.isGTKLookAndFeel();\n    \n    \n    private boolean showsTabPopup = true;\n    \n    \n    public ProfilerTabbedPane() {\n        setFocusable(false);\n        \n        addMouseWheelListener(new MouseWheelListener() {\n            @Override\n            public void mouseWheelMoved(MouseWheelEvent e) {\n                if (!mouseWheelScrolls()) return;\n                \n                int units = e.getWheelRotation(); // always step by 1!\n                int selected = getSelectedIndex();\n                \n                int newSelected = selected + units;\n                if (newSelected < 0) newSelected = 0;\n                else if (newSelected >= getTabCount()) newSelected = getTabCount() - 1;\n                \n                setSelectedIndex(newSelected);\n            }\n        });\n    }\n    \n    \n    public void addTab(String title, Icon icon, final Component component, String tip, boolean closable) {\n        int tabCount = getTabCount();\n\n        if (component.getMouseWheelListeners().length == 0 && UIUtils.isAquaLookAndFeel()) {\n            component.addMouseWheelListener(new MouseWheelListener() {\n                @Override\n                public void mouseWheelMoved(MouseWheelEvent e) {\n                    // GH-122\n                }\n            });\n        }\n        super.addTab(title, icon, component, tip);\n        \n        Runnable closer = closable ? new Runnable() {\n            public void run() {\n                closeTab(component);\n            }\n        } : null;\n        \n        setTabComponentAt(tabCount, new TabCaption(title, icon, closer));\n    }\n    \n    public void insertTab(String title, Icon icon, final Component component, String tip, boolean closable, int index) {\n        if (component.getMouseWheelListeners().length == 0 && UIUtils.isAquaLookAndFeel()) {\n            component.addMouseWheelListener(new MouseWheelListener() {\n                @Override\n                public void mouseWheelMoved(MouseWheelEvent e) {\n                    // GH-122\n                }\n            });\n        }\n        super.insertTab(title, icon, component, tip, index);\n        \n        Runnable closer = closable ? new Runnable() {\n            public void run() {\n                closeTab(component);\n            }\n        } : null;\n        \n        setTabComponentAt(index, new TabCaption(title, icon, closer));\n    }\n    \n    \n    @Override\n    public void setTitleAt(int index, String title) {\n        super.setTitleAt(index, title);\n        tabCaptionAt(index).setTitle(title);\n    }\n    \n    @Override\n    public void setIconAt(int index, Icon icon) {\n        super.setIconAt(index, icon);\n        tabCaptionAt(index).setIcon(icon);\n    }\n    \n    @Override\n    public void setForegroundAt(int index, Color foreground) {\n        super.setForegroundAt(index, foreground);\n        tabCaptionAt(index).setForeground(foreground);\n    }\n    \n    @Override\n    public Color getForegroundAt(int index) {\n        return tabCaptionAt(index).getForeground();\n    }\n    \n    \n    public final void setShowsTabPopup(boolean showsTabPopup) {\n        this.showsTabPopup = showsTabPopup;\n    }\n    \n    public final boolean getShowsTabPopup() {\n        return showsTabPopup;\n    }\n    \n    \n    boolean isClosableAt(int index) {\n        return tabCaptionAt(index).isClosable();\n    }\n    \n    \n    protected boolean mouseWheelScrolls() {\n        return UIUtils.isAquaLookAndFeel() || getTabLayoutPolicy() == SCROLL_TAB_LAYOUT;\n    }\n    \n    protected void closeTab(Component component) {\n        remove(indexOfComponent(component));\n    }\n    \n    \n    public void close(Component component) {\n        closeTab(component);\n    }\n    \n    public void closeOther(Component component) {\n        for (Object[] comp : components()) {\n            if (comp[1] != component && (boolean)comp[0])\n                close((Component)comp[1]);\n        }\n    }\n    \n    public void closeOtherToTheRight(Component component) {\n        boolean visited = false;\n        for (Object[] comp : components()) {\n            if (comp[1] == component) {\n                visited = true;\n            } else {\n                if (visited && (boolean)comp[0])\n                    close((Component)comp[1]);\n            }\n        }\n    }\n    \n    public void closeAll() {\n        for (Object[] comp : components())\n            if ((boolean)comp[0]) close((Component)comp[1]);\n    }\n    \n    private Object[][] components() {\n        int componentCount = getTabCount();\n        Object[][] components = new Object[componentCount][2];\n        for (int i = 0; i < getTabCount(); i++) {\n            components[i][0] = isClosableAt(i);\n            components[i][1] = getComponentAt(i);\n        }\n        return components;\n    }\n    \n    \n    private TabCaption tabCaptionAt(int index) {\n        return (TabCaption)getTabComponentAt(index);\n    }\n    \n    \n    protected void processMouseEvent(MouseEvent e) {\n        int index = indexAtLocation(e.getX(), e.getY());\n        \n        if (index != -1) {\n            if (e.isPopupTrigger()) {\n                if (getShowsTabPopup()) {\n                    // Show popup menu for the clicked tab\n                    final MouseEvent _e = e;\n                    final int _index = index;\n                    final Component _component = getComponentAt(index);\n\n                    SwingUtilities.invokeLater(new Runnable() {\n                        public void run() { showPopupMenu(_index, _component, _e); }\n                    });\n\n                    e.consume();\n                    return;\n                }\n            } else if (e.getID() == MouseEvent.MOUSE_CLICKED && SwingUtilities.isMiddleMouseButton(e)) {\n                // Close tab using middle button click\n                if (isClosableAt(index)) closeTab(getComponentAt(index));\n                \n                e.consume();\n                return;\n            } else if (e.getID() == MouseEvent.MOUSE_PRESSED && !SwingUtilities.isLeftMouseButton(e)) {\n                // Do not switch tabs using middle or right mouse button\n                e.consume();\n                return;\n            }\n        }\n        \n        super.processMouseEvent(e);\n    }\n    \n    private void showPopupMenu(int index, Component component, MouseEvent e) {\n        JPopupMenu popup = new JPopupMenu() {\n//            public void setVisible(boolean visible) {\n//                if (visible) popupShowing();\n//                super.setVisible(visible);\n//                if (!visible) popupHidden();\n//            }\n        };\n        \n        populatePopup(popup, index, component);\n        \n        if (popup.getComponentCount() > 0) {\n            if (e == null) {\n                // TODO: invoked by keyboard? handle it? \n            } else {\n                popup.show(this, e.getX(), e.getY());\n            }\n        }\n    }\n    \n    private void populatePopup(JPopupMenu popup, int index, Component component) {\n        boolean anyClosable = false;\n        boolean otherClosable = false;\n        boolean otherToTheRightClosable = false;\n\n        boolean visited = false;\n        for (int i = 0; i < getTabCount(); i++) {\n            Component c = getComponentAt(i);\n            \n            boolean invoker = c == component;\n            boolean closable = isClosableAt(i);\n            if (closable) {\n                anyClosable = true;\n                if (!invoker) otherClosable = true;\n                if (visited) otherToTheRightClosable = true;\n                \n                if (otherToTheRightClosable) break;\n            }\n            \n            if (invoker) visited = true;\n        }\n        \n        final boolean _closable = isClosableAt(index);\n        final boolean _anyClosable = anyClosable;\n        final boolean _otherClosable = otherClosable;\n        final boolean _otherToTheRightClosable = otherToTheRightClosable;\n        \n        popup.add(new JMenuItem(Bundle.ProfilerTabbedPane_Close()) {\n            { setEnabled(_closable); }\n            protected void fireActionPerformed(ActionEvent e) { close(component); }\n        });\n        \n        popup.addSeparator();\n        \n        popup.add(new JMenuItem(Bundle.ProfilerTabbedPane_CloseOther()) {\n            { setEnabled(_otherClosable); }\n            protected void fireActionPerformed(ActionEvent e) { closeOther(component); }\n        });\n        popup.add(new JMenuItem(Bundle.ProfilerTabbedPane_CloseOtherRight()) {\n            { setEnabled(_otherToTheRightClosable); }\n            protected void fireActionPerformed(ActionEvent e) { closeOtherToTheRight(component); }\n        });\n        \n        popup.addSeparator();\n        \n        popup.add(new JMenuItem(Bundle.ProfilerTabbedPane_CloseAll()) {\n            { setEnabled(_anyClosable); }\n            protected void fireActionPerformed(ActionEvent e) { closeAll(); }\n        });\n    }\n    \n    \n    private class TabCaption extends JPanel {\n        \n        private JLabel caption;\n    \n        TabCaption(String text, Icon icon, Runnable closer) {\n            setFocusable(false);\n            \n            setOpaque(false);\n            \n            if (IS_AQUA) setBorder(BorderFactory.createEmptyBorder(ProfilerTabbedPane.this.getTabPlacement() == JTabbedPane.BOTTOM ? 1 : 0, 0, 0, closer == null ? -2 : 0));\n            else if (IS_GTK) setBorder(BorderFactory.createEmptyBorder(0, 2, 0, closer == null ? 1 : 0));\n            else if (UIUtils.isWindowsLookAndFeel()) setBorder(BorderFactory.createEmptyBorder(1, 1, 0, closer == null ? 1 : 0));\n            else if (UIUtils.isMetalLookAndFeel()) setBorder(BorderFactory.createEmptyBorder(ProfilerTabbedPane.this.getTabPlacement() == JTabbedPane.BOTTOM ? 1 : 2, 0, 0, 0));\n\n            setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));\n\n            caption = new JLabel(text, icon, JLabel.LEADING);\n            caption.setUI(new BasicLabelUI() {\n                protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) {\n                    Window w = IS_AQUA ? SwingUtilities.getWindowAncestor(TabCaption.this) : null;\n                    boolean focused = w == null ? true : w.isFocused();\n                    \n                    int selectedIndex = ProfilerTabbedPane.this.getSelectedIndex();\n                    boolean selected = ProfilerTabbedPane.this.getTabComponentAt(selectedIndex) == TabCaption.this;\n                    \n                    g.setFont(l.getFont());\n                    \n                    if (focused && selected) {\n                        Color shadow = UIManager.getColor(\"TabbedPane.selectedTabTitleShadowNormalColor\"); // NOI18N\n                        if (shadow != null) { g.setColor(shadow); SwingUtilities2.drawString(l, g, s, textX, textY + 1); }\n                        \n                        Color foreground = UIManager.getColor(\"TabbedPane.selectedTabTitleNormalColor\"); // NOI18N\n                        if (foreground != null) { g.setColor(foreground); SwingUtilities2.drawString(l, g, s, textX, textY); }\n                        else super.paintEnabledText(l, g, s, textX, textY);\n                    } else {\n                        Color foreground = UIManager.getColor(\"TabbedPane.nonSelectedTabTitleNormalColor\"); // NOI18N\n                        if (foreground != null) { g.setColor(foreground); SwingUtilities2.drawString(l, g, s, textX, textY); }\n                        else super.paintEnabledText(l, g, s, textX, textY);\n                    }\n                }\n            });\n            add(caption);\n\n            if (closer != null) {\n                add(Box.createHorizontalStrut(5));\n                add(Box.createHorizontalGlue());\n                \n                JPanel p = new JPanel(new BorderLayout()) {\n                    public Dimension getMinimumSize() {\n                        Dimension dim = super.getMinimumSize();\n                        dim.height = caption.getPreferredSize().height;\n                        return dim;\n                    }\n                    public Dimension getPreferredSize() {\n                        return getMinimumSize();\n                    }\n                    public Dimension getMaximumSize() {\n                        return getMinimumSize();\n                    }\n                };\n                p.setOpaque(false);\n//                p.setBorder(BorderFactory.createEmptyBorder(1, 0, 0, 0));\n                p.add(CloseButton.createSmall(closer), BorderLayout.CENTER);\n                add(p);\n            }\n        }\n        \n        boolean isClosable() {\n            return getComponentCount() > 1;\n        }\n        \n        private void setTitle(String title) {\n            caption.setText(title);\n        }\n        \n        private void setIcon(Icon icon) {\n            caption.setIcon(icon);\n        }\n        \n        @Override\n        public void setForeground(Color foreground) {\n            if (caption == null) super.setForeground(foreground);\n            else caption.setForeground(foreground);\n        }\n\n        @Override\n        public Color getForeground() {\n            return caption == null ? super.getForeground() : caption.getForeground();\n        }\n        \n        @Override\n        public Dimension getPreferredSize() {\n            Dimension dim = super.getPreferredSize();\n            if (IS_GTK) dim.height = super.getMinimumSize().height;\n            return dim;\n        }\n\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/uisupport/src/org/graalvm/visualvm/uisupport/ProfilerTabbedView.java",
    "content": "/*\n * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.uisupport;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Image;\nimport java.awt.Insets;\nimport java.awt.KeyboardFocusManager;\nimport java.awt.Rectangle;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.image.FilteredImageSource;\nimport java.awt.image.ImageProducer;\nimport java.awt.image.RGBImageFilter;\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.lang.ref.Reference;\nimport java.lang.ref.WeakReference;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport javax.swing.AbstractAction;\nimport javax.swing.BorderFactory;\nimport javax.swing.Icon;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JTabbedPane;\nimport javax.swing.SwingUtilities;\nimport javax.swing.Timer;\nimport javax.swing.UIManager;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\nimport org.openide.util.ImageUtilities;\nimport org.openide.util.Lookup;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic abstract class ProfilerTabbedView {\n    \n    // NOTE: LEFT and RIGHT tab placement is not supported by the actual implementation\n    // NOTE: SCROLL_TAB_LAYOUT is not supported (doesn't work with minimizeInnerMargin)\n    \n    public static ProfilerTabbedView createTop(boolean minimizeInnerMargin,\n                                               boolean minimizeOuterMargin,\n                                               ChangeListener listener) {\n        return create(JTabbedPane.TOP, minimizeInnerMargin, minimizeOuterMargin, listener);\n    }\n    \n    public static ProfilerTabbedView createBottom(boolean minimizeInnerMargin,\n                                                  boolean minimizeOuterMargin,\n                                                  ChangeListener listener) {\n        return create(JTabbedPane.BOTTOM, minimizeInnerMargin, minimizeOuterMargin, listener);\n    }\n    \n    private static ProfilerTabbedView create(int tabPlacement, boolean minimizeInnerMargin,\n                                             boolean minimizeOuterMargin, ChangeListener listener) {\n        Provider provider = Lookup.getDefault().lookup(Provider.class);\n        return provider != null ? provider.create(tabPlacement, JTabbedPane.WRAP_TAB_LAYOUT, minimizeInnerMargin, minimizeOuterMargin, listener) :\n                                  new Impl(tabPlacement, JTabbedPane.WRAP_TAB_LAYOUT, minimizeInnerMargin, minimizeOuterMargin, listener);\n    }\n    \n    \n    public abstract JComponent getComponent();\n    \n    \n    public abstract void addView(String name, Icon icon, String description, JComponent view, boolean closable);\n    \n    public abstract boolean containsView(JComponent view);\n    \n//    public abstract void replaceView(JComponent oldView, String name, Icon icon, String description, JComponent newView, boolean closable);\n    \n    public abstract void updateView(JComponent view, String name, Icon icon, String description);\n    \n    public abstract void removeView(JComponent view);\n    \n    public abstract void removeAllViews();\n    \n    public abstract int getViewsCount();\n    \n//    public abstract int getViewIndex(JComponent view);\n    \n    \n    public abstract void setViewName(JComponent view, String name);\n    \n    public abstract String getViewName(JComponent view);\n    \n    public abstract void setViewEnabled(JComponent view, boolean enabled);\n    \n    public abstract boolean isViewEnabled(JComponent view);\n    \n    \n    public abstract void selectView(JComponent view);\n    \n    public abstract void selectView(int index);\n    \n    public abstract void selectPreviousView();\n    \n    public abstract void selectNextView();\n    \n    public abstract JComponent getSelectedView();\n    \n//    public abstract int getSelectedViewIndex();\n    \n    \n    public abstract void highlightView(JComponent view);\n    \n    \n    public abstract void setFocusMaster(Component focusMaster);\n    \n    \n    public abstract void addViewListener(Listener listener);\n    \n    public abstract void removeViewListener(Listener listener);\n    \n    \n    public void setShowsTabPopup(boolean showsTabPopup) {}\n    \n    public boolean getShowsTabPopup() { return true; }\n    \n    \n    protected ProfilerTabbedView() {}\n    \n    \n    public static abstract class Listener {\n        \n        public void viewAdded(JComponent view) {}\n        \n        public void viewRemoved(JComponent view) {}\n        \n    }\n    \n    \n    public static abstract class Provider {\n        \n        public abstract ProfilerTabbedView create(int tabPlacement, int tabLayoutPolicy,\n                                                  boolean minimizeInnerMargin, boolean\n                                                  minimizeOuterMargin, ChangeListener listener);\n        \n    }\n    \n    \n    public static class Impl extends ProfilerTabbedView {\n        \n        private List<Listener> viewListeners;\n        \n        private final ChangeListener listener;\n        \n        private final int tabPlacement;\n        private final int tabLayoutPolicy;\n        private final boolean minimizeInnerMargin;\n        private final boolean minimizeOuterMargin;\n        \n        private final JComponent component;\n        \n        private JComponent firstView;\n        private String firstName;\n        private Icon firstIcon;\n        private String firstDescription;\n        private boolean firstClosable;\n        \n        private ProfilerTabbedPane tabs;\n        private boolean showsTabPopup = true;\n        \n        private Component focusMaster;\n        \n    \n        protected Impl(int tabPlacement, int tabLayoutPolicy, boolean minimizeOuterMargin,\n                    boolean minimizeInnerMargin, ChangeListener listener) {\n            \n            this.listener = listener;\n            \n            this.tabPlacement = tabPlacement;\n            this.tabLayoutPolicy = tabLayoutPolicy;\n            this.minimizeInnerMargin = minimizeInnerMargin;\n            this.minimizeOuterMargin = minimizeOuterMargin;\n            \n            component = new JPanel(new BorderLayout());\n            component.setOpaque(false);\n            \n            // support for traversing subtabs using Ctrl-Alt-PgDn/PgUp\n            component.getActionMap().put(\"PreviousViewAction\", new AbstractAction() { // NOI18N\n                public void actionPerformed(ActionEvent e) { selectPreviousView(); }\n            });\n            component.getActionMap().put(\"NextViewAction\", new AbstractAction() { // NOI18N\n                public void actionPerformed(ActionEvent e) { selectNextView(); }\n            });\n            \n            setFocusMaster(null);\n            \n//            tabs = createTabs(component, tabPlacement, minimizeOuterMargin);\n//            component.add(tabs, BorderLayout.CENTER);\n        }\n        \n        \n        public void setFocusMaster(Component focusMaster) {\n            this.focusMaster = focusMaster == null ? component : focusMaster;\n        }\n        \n        \n        public JComponent getComponent() {\n            return component;\n        }\n        \n        \n        public void addView(String name, Icon icon, String description, JComponent view, boolean closable) {\n            if (tabs == null) {\n                if (firstView == null) {\n                    firstView = view;\n                    firstName = name;\n                    firstIcon = icon;\n                    firstDescription = description;\n                    firstClosable = closable;\n                    component.add(view, BorderLayout.CENTER);\n                    fireChanged();\n                } else {\n                    component.remove(firstView);\n                    tabs = createTabs(tabPlacement, tabLayoutPolicy, minimizeOuterMargin);\n                    tabs.setShowsTabPopup(showsTabPopup);\n                    tabs.addTab(firstName, firstIcon, createViewport(firstView), firstDescription, firstClosable);\n                    tabs.addTab(name, icon, createViewport(view), description, closable);\n                    component.add(tabs, BorderLayout.CENTER);\n                    firstView = null;\n                    firstName = null;\n                    firstIcon = null;\n                    firstDescription = null;\n                }\n            } else {\n                tabs.addTab(name, icon, createViewport(view), description, closable);\n            }\n            fireViewAdded(view);\n        }\n        \n        public boolean containsView(JComponent view) {\n            if (tabs == null) return Objects.equals(view, firstView);\n            TabbedPaneViewport viewport = createViewport(view);\n            return tabs.indexOfComponent(viewport) != -1;\n        }\n        \n//        public void replaceView(JComponent oldView, String name, Icon icon, String description, JComponent newView, boolean closable) {\n//            if (tabs == null && oldView == firstView) {\n//                component.remove(firstView);\n//                firstView = newView;\n//                firstName = name;\n//                firstIcon = icon;\n//                firstDescription = description;\n//                firstClosable = closable;\n//                component.add(newView, BorderLayout.CENTER);\n//                component.invalidate();\n//                component.revalidate();\n//                component.repaint();\n//            } else {\n//                TabbedPaneViewport oldViewport = TabbedPaneViewport.fromView(oldView);\n//                int idx = tabs.indexOfComponent(oldViewport);\n//                tabs.setTitleAt(idx, name);\n//                tabs.setIconAt(idx, icon);\n//                tabs.setToolTipTextAt(idx, description);\n//                tabs.setComponentAt(idx, createViewport(newView));\n////                tabs.insertTab(name + \" \", icon, createViewport(newView, closable), description, idx);\n////                TabbedPaneViewport oldViewport = TabbedPaneViewport.fromView(oldView);\n////                int idx = tabs.indexOfComponent(oldViewport);\n////                tabs.remove(oldViewport);\n////                tabs.insertTab(name + \" \", icon, createViewport(newView, closable), description, idx);\n//            }\n//        }\n        \n        public void updateView(JComponent view, String name, Icon icon, String description) {\n            if (tabs == null && view == firstView) {\n                firstName = name;\n                firstIcon = icon;\n                firstDescription = description;\n            } else {\n                TabbedPaneViewport viewport = TabbedPaneViewport.fromView(view);\n                int idx = tabs.indexOfComponent(viewport);\n                tabs.setTitleAt(idx, name);\n                tabs.setIconAt(idx, icon);\n                tabs.setToolTipTextAt(idx, description);\n            }\n        }\n\n        public void removeView(JComponent view) {\n            if (tabs != null) {\n//                int viewIndex = tabs.indexOfComponent(view);\n//                if (viewIndex == -1) return;\n                if (tabs.getTabCount() > 2) {\n                    tabs.remove(TabbedPaneViewport.fromView(view));\n                } else {\n                    tabs.remove(TabbedPaneViewport.fromView(view));\n                    TabbedPaneViewport singleViewport = (TabbedPaneViewport)tabs.getComponentAt(0);\n                    firstName = tabs.getTitleAt(0);\n                    firstIcon = tabs.getIconAt(0);\n                    firstDescription = tabs.getToolTipTextAt(0);\n                    firstClosable = tabs.isClosableAt(0);\n                    firstView = singleViewport.disposeView();\n                    component.remove(tabs);\n                    component.add(firstView, BorderLayout.CENTER);\n                    tabs = null;\n                }\n            } else if (firstView == view) {\n                component.remove(firstView);\n                firstView = null;\n                firstName = null;\n                firstIcon = null;\n                firstDescription = null;\n                fireChanged();\n            }\n            fireViewRemoved(view);\n        }\n\n        public void removeAllViews() {\n            Collection<JComponent> allViews = getAllViews();\n            if (allViews.isEmpty()) return;\n            \n            component.removeAll();\n            tabs = null;\n            firstView = null;\n            firstName = null;\n            firstIcon = null;\n            firstDescription = null;\n            fireChanged();\n            \n            for (JComponent view : allViews) fireViewRemoved(view);\n        }\n\n        public int getViewsCount() {\n            return tabs != null ? tabs.getTabCount() : (firstView != null ? 1 : 0);\n        }\n        \n        private int getViewIndex(JComponent view) {\n            if (tabs == null) return view == firstView ? 0 : -1;\n            else return tabs.indexOfComponent(TabbedPaneViewport.fromView(view));\n        }\n        \n        private Collection<JComponent> getAllViews() {\n            if (tabs != null) {\n                int tabsCount = tabs.getTabCount();\n                List<JComponent> allViews = new ArrayList<>(tabsCount);\n                for (int i = 0; i < tabsCount; i++)\n                    allViews.add(((TabbedPaneViewport)tabs.getComponentAt(i)).getView());\n                return allViews;\n            } else if (firstView != null) {\n                return Collections.singletonList(firstView);\n            } else {\n                return Collections.emptyList();\n            }\n        }\n\n        \n        public final void setViewName(JComponent view, String name) {\n            if (tabs == null) firstName = name;\n            else tabs.setTitleAt(getViewIndex(view), name);\n        }\n\n        public final String getViewName(JComponent view) {\n            if (tabs == null) return firstName;\n            else return tabs.getTitleAt(getViewIndex(view));\n        }\n        \n        public void setViewEnabled(JComponent view, boolean enabled) {\n            if (tabs != null) tabs.setEnabledAt(getViewIndex(view), enabled);\n            // TODO: handle single view (no tabs) - introduce firstEnabled?\n        }\n\n        public boolean isViewEnabled(JComponent view) {\n            if (tabs == null) return view == firstView;\n            else return tabs.isEnabledAt(getViewIndex(view));\n            // TODO: handle single view (no tabs) - introduce firstEnabled?\n        }\n        \n\n        public void selectView(JComponent view) {\n            if (tabs != null) tabs.setSelectedComponent(TabbedPaneViewport.fromView(view));\n        }\n\n        public void selectView(int index) {\n            if (tabs != null) tabs.setSelectedIndex(index);\n        }\n\n        public void selectPreviousView() {\n            if (tabs != null) tabs.setSelectedIndex(UIUtils.getPreviousSubTabIndex(tabs, tabs.getSelectedIndex()));\n        }\n\n        public void selectNextView() {\n            if (tabs != null) tabs.setSelectedIndex(UIUtils.getNextSubTabIndex(tabs, tabs.getSelectedIndex()));\n        }\n\n        public JComponent getSelectedView() {\n            if (firstView != null) return firstView;\n            if (tabs == null) return null;\n            return ((TabbedPaneViewport)tabs.getSelectedComponent()).getView();\n        }\n\n//        public int getSelectedViewIndex() {\n//            throw new UnsupportedOperationException(\"Not supported yet.\"); //To change body of generated methods, choose Tools | Templates.\n//        }\n        \n        \n        public void highlightView(JComponent view) {\n            highlightTab(createViewport(view));\n        }\n        \n        \n        protected final void fireChanged() {\n            if (listener != null) listener.stateChanged(new ChangeEvent(this));\n        }\n        \n        \n        public void addViewListener(Listener listener) {\n            if (viewListeners == null) viewListeners = new ArrayList<>(3);\n            viewListeners.add(listener);\n        }\n    \n        public void removeViewListener(Listener listener) {\n            if (viewListeners == null) return;\n            viewListeners.remove(listener);\n            if (viewListeners.isEmpty()) viewListeners = null;\n        }\n        \n        protected final void fireViewAdded(JComponent view) {\n            if (viewListeners != null)\n                for (Listener viewListener : viewListeners)\n                    viewListener.viewAdded(view);\n        }\n        \n        protected final void fireViewRemoved(JComponent view) {\n            if (viewListeners != null)\n                for (Listener viewListener : viewListeners)\n                    viewListener.viewRemoved(view);\n        }\n        \n        \n        public void setShowsTabPopup(boolean showsTabPopup) {\n            this.showsTabPopup = showsTabPopup;\n            if (tabs != null) tabs.setShowsTabPopup(showsTabPopup);\n        }\n    \n        public boolean getShowsTabPopup() {\n            return showsTabPopup;\n        }\n        \n        \n        private final TabbedPaneViewport createViewport(JComponent view) {\n            return new TabbedPaneViewport(view) {\n                Component getFocusMaster() { return focusMaster; }\n                int getTabPlacement() { return tabPlacement; }\n                boolean minimizeInnerMargin() { return minimizeInnerMargin; }\n            };\n        }\n        \n        protected final ProfilerTabbedPane createTabs(int tabPlacement, int tabLayoutPolicy, boolean minimizeOuterMargin) {\n            ProfilerTabbedPane tp = new ProfilerTabbedPane() {\n                @Override\n                protected void closeTab(Component component) {\n                    removeView(((TabbedPaneViewport)component).getView());\n                }\n            };\n//            JTabbedPane tp = TabbedPaneFactory.createCloseButtonTabbedPane();\n//            JTabbedPane tp = new JTabbedPane();\n            tp.setTabPlacement(tabPlacement);\n            tp.setTabLayoutPolicy(tabLayoutPolicy);\n            tp.setOpaque(false);\n            \n            if (minimizeOuterMargin) {\n                if (UIUtils.isAquaLookAndFeel()) {\n                    tp.setBorder(BorderFactory.createEmptyBorder(-13, -11, 0, -10));\n                } else if (UIUtils.isNimbusLookAndFeel()) {\n                    if (tabPlacement == JTabbedPane.TOP) tp.setBorder(BorderFactory.createEmptyBorder(-4, 0, 0, 0));\n                    else tp.setBorder(BorderFactory.createEmptyBorder(0, 0, -4, 0));\n                } else {\n                    tp.setBorder(BorderFactory.createEmptyBorder());\n                    Insets i = UIManager.getInsets(\"TabbedPane.contentBorderInsets\"); // NOI18N\n                    int bottomOffset = 0;\n                    if (UIUtils.isMetalLookAndFeel()) {\n                        bottomOffset = -i.bottom + 1;\n                    } else if (UIUtils.isWindowsLookAndFeel()) {\n                        bottomOffset = -i.bottom;\n                    }\n//                    if (i != null) tp.setBorder(BorderFactory.createEmptyBorder(-i.top, -i.left, -i.bottom, -i.right));\n                    if (i != null) tp.setBorder(BorderFactory.createEmptyBorder(-i.top, -i.left, bottomOffset, -i.right));\n                }\n            }\n\n            // Fix for Issue 115062 (CTRL-PageUp/PageDown should move between snapshot tabs)\n            tp.getActionMap().getParent().remove(\"navigatePageUp\"); // NOI18N\n            tp.getActionMap().getParent().remove(\"navigatePageDown\"); // NOI18N\n\n            tp.addChangeListener(new ChangeListener() {\n                public void stateChanged(ChangeEvent e) {\n                    if (listener != null) listener.stateChanged(e);\n                }\n            });\n\n            return tp;\n        }\n        \n        \n        private static final int HIGHLIGHTS_COUNT = 2;\n        private static final int HIGHLIGHTS_DURATION = 300;\n        private final Map<TabbedPaneViewport, Integer> highlights = new HashMap<>();\n        \n        private void highlightTab(TabbedPaneViewport viewport) {\n            Integer icount = highlights.get(viewport);\n            if (icount == null) {\n                // new highlight for the tab\n                highlights.put(viewport, HIGHLIGHTS_COUNT);\n                highlightTabImpl(viewport);\n            } else {\n                // tab already being highlighted\n                if (icount < HIGHLIGHTS_COUNT) highlights.put(viewport, HIGHLIGHTS_COUNT);\n            }\n        }\n        \n        private void highlightTabImpl(final TabbedPaneViewport viewport) {\n            if (tabs == null) { highlights.remove(viewport); return; }\n            \n            Integer icount = highlights.get(viewport);\n            if (icount == null) {\n                return;\n            } else if (icount == 0) {\n                { highlights.remove(viewport); return; }\n            }\n            \n            int idx = tabs.indexOfComponent(viewport);\n            if (idx == -1) { highlights.remove(viewport); return; }\n            \n            final Color originalForeground = tabs.getForegroundAt(idx);\n            Color highlightForeground = Color.BLUE;\n            \n            final Icon originalIcon = tabs.getIconAt(idx);\n            Image image = ImageUtilities.icon2Image(originalIcon);\n            RGBImageFilter filter = new RGBImageFilter() {\n                public int filterRGB(int x, int y, int rgb) {\n                    int r = (rgb >> 16) & 0xFF;\n                    int g = (rgb >> 8) & 0xFF;\n                    int b = (rgb) & 0xFF;\n                    int a = (rgb >> 24) & 0xFF;\n                    \n                    return (a << 24) | ((r / 2 & 0xFF) << 16) |\n                           ((g / 2 & 0xFF) << 8) | b;\n                }\n            };\n            ImageProducer prod = new FilteredImageSource(image.getSource(), filter);\n            Icon highlightIcon = ImageUtilities.image2Icon(Toolkit.getDefaultToolkit().createImage(prod));\n            \n            decorateTab(viewport, highlightForeground, highlightIcon);\n            \n            invokeLater(new Runnable() {\n                public void run() {\n                    decorateTab(viewport, originalForeground, originalIcon);\n                    \n                    Integer icount = highlights.get(viewport);\n                    if (icount == null) {\n                        return;\n                    } else {\n                        highlights.put(viewport, --icount);\n                    }\n                \n                    invokeLater(new Runnable() {\n                        public void run() { highlightTabImpl(viewport); }\n                    }, HIGHLIGHTS_DURATION);\n                }\n            }, HIGHLIGHTS_DURATION);\n        }\n        \n        private void decorateTab(TabbedPaneViewport viewport, Color foreground, Icon icon) {\n            if (tabs == null) return;\n            \n            int idx = tabs.indexOfComponent(viewport);\n            if (idx == -1) return;\n            \n            tabs.setForegroundAt(idx, foreground);\n            tabs.setIconAt(idx, icon);\n        }\n        \n        private void invokeLater(final Runnable task, int time) {\n            final Timer timer = new Timer(time, null);\n            timer.addActionListener(new ActionListener() {\n                public void actionPerformed(ActionEvent e) {\n                    timer.stop();\n                    task.run();\n                }\n            });\n            timer.start();\n        }\n        \n        \n        private static abstract class TabbedPaneViewport extends JPanel {\n            \n            private final JComponent content;\n            \n            private Reference<Component> lastFocusOwner;\n            \n            TabbedPaneViewport(JComponent view) {\n                super(new BorderLayout());\n                \n                content = view;\n                \n                setOpaque(false);\n                setFocusable(false);\n//                setBackground(Color.YELLOW);\n                add(view, BorderLayout.CENTER);\n                view.putClientProperty(\"TabbedPaneViewport\", this); // NOI18N\n                \n                final PropertyChangeListener focusListener = new PropertyChangeListener() {\n                    public void propertyChange(PropertyChangeEvent evt) {\n                        Component c = evt.getNewValue() instanceof Component ?\n                                (Component)evt.getNewValue() : null;\n                        processFocusedComponent(c);\n                    }\n                    private void processFocusedComponent(Component c) {\n                        Component cc = c;\n                        while (c != null) {\n                            if (c == getFocusMaster()) {\n                                lastFocusOwner = new WeakReference<>(cc);\n                                return;\n                            }\n                            c = c.getParent();\n                        }\n                    }\n                };\n                \n                addHierarchyListener(new HierarchyListener() {\n                    public void hierarchyChanged(HierarchyEvent e) {\n                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                            if (isShowing()) {\n                                final Component lastFocus = lastFocusOwner == null ? null : lastFocusOwner.get();\n                                if (lastFocus != null) lastFocus.requestFocusInWindow();\n                                else content.requestFocusInWindow();\n                                \n                                SwingUtilities.invokeLater(new Runnable() {\n                                    public void run() {\n                                        if (lastFocus != null) lastFocus.requestFocusInWindow();\n                                        else content.requestFocusInWindow();\n                                    }\n                                });\n                                \n                                KeyboardFocusManager.getCurrentKeyboardFocusManager().\n                                    addPropertyChangeListener(\"focusOwner\", focusListener); // NOI18N\n                            } else {\n                                KeyboardFocusManager.getCurrentKeyboardFocusManager().\n                                    removePropertyChangeListener(\"focusOwner\", focusListener); // NOI18N\n                            }\n                        }\n                    }\n                });\n            }\n            \n            \n            public boolean equals(Object o) {\n                if (o == this) return true;\n                if (!(o instanceof TabbedPaneViewport)) return false;\n                return content.equals(((TabbedPaneViewport)o).content);\n            }\n\n            public int hashCode() {\n                return content.hashCode();\n            }\n            \n            \n//            boolean isClosable() {\n//                return !Boolean.TRUE.equals(getClientProperty(TabbedPaneFactory.NO_CLOSE_BUTTON));\n//            }\n            \n            JComponent getView() {\n                return content;\n            }\n            \n            JComponent disposeView() {\n                content.putClientProperty(\"TabbedPaneViewport\", null); // NOI18N\n                removeAll();\n                return content;\n            }\n            \n            static TabbedPaneViewport fromView(JComponent view) {\n                return (TabbedPaneViewport)view.getClientProperty(\"TabbedPaneViewport\"); // NOI18N\n            }\n            \n            \n            abstract Component getFocusMaster();\n            \n            abstract int getTabPlacement();\n            \n            abstract boolean minimizeInnerMargin();\n            \n            \n            public void reshape(int x, int y, int w, int h) {\n                if (minimizeInnerMargin()) {\n                    Rectangle r = offsetRect();\n                    super.reshape(x + r.x, y + r.y, w + r.width, h + r.height);\n                } else {\n                    super.reshape(x, y, w, h);\n                }\n            }\n            \n            private Rectangle offsetRect() {\n                Rectangle rect = new Rectangle();\n                \n                if (UIUtils.isNimbus()) {\n                    rect.height = 4;\n                    if (getTabPlacement() == JTabbedPane.TOP) rect.y -= rect.height;\n                } else if (UIUtils.isGTKLookAndFeel()) {\n                    rect.height = 1;\n                    if (getTabPlacement() == JTabbedPane.TOP) rect.y -= rect.height++;\n                } else {\n                    Insets tai = UIManager.getInsets(\"TabbedPane.tabAreaInsets\"); // NOI18N\n                    Insets cbi = UIManager.getInsets(\"TabbedPane.contentBorderInsets\"); // NOI18N\n\n                    if (tai != null && cbi != null) {\n                        if (getTabPlacement() == JTabbedPane.TOP) {\n                            rect.y -= cbi.bottom;\n                            rect.height -= rect.y;\n                        } else {\n                            rect.height = tai.bottom + cbi.bottom - 1;\n                        }\n                    } else {\n                    }\n                }\n                \n                return rect;\n            }\n            \n        }\n    \n    }\n    \n}\n"
  },
  {
    "path": "visualvm/uisupport/src/org/graalvm/visualvm/uisupport/SeparatorLine.java",
    "content": "/*\n * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage org.graalvm.visualvm.uisupport;\n\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport javax.swing.BorderFactory;\nimport javax.swing.JPanel;\nimport javax.swing.JSeparator;\nimport javax.swing.UIManager;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n * Simple thin JSeparator.\n *\n * @author Jiri Sedlacek\n */\npublic final class SeparatorLine extends JSeparator {\n    \n    private final Color separatorColor;\n\n\n    public SeparatorLine() {\n        this(HORIZONTAL);\n    }\n    \n    public SeparatorLine(boolean thin) {\n        this(HORIZONTAL, thin);\n    }\n\n    public SeparatorLine(int orientation) {\n        this(orientation, UISupport.isWindowsLookAndFeel() || UISupport.isAquaLookAndFeel());\n    }\n    \n    public SeparatorLine(int orientation, boolean thin) {\n        super(orientation);\n        setBorder(BorderFactory.createEmptyBorder());\n        separatorColor = thin ? getSeparatorColor() : null;\n    }\n    \n    \n    public Dimension getPreferredSize() {\n        Dimension dim = super.getPreferredSize();\n        if (separatorColor != null) dim.height = 1;\n        return dim;\n    }\n\n    public Dimension getMinimumSize() {\n        return getPreferredSize();\n    }\n    \n    public Dimension getMaximumSize() {\n        return getPreferredSize();\n    }\n    \n    \n    public void paint(Graphics g) {\n        if (separatorColor != null) {\n            g.setColor(separatorColor);\n            g.drawLine(0, 0, getWidth(), 0);\n        } else {\n            super.paint(g);\n        }\n    }\n    \n    \n    private static Color getSeparatorColor() {\n        if (UISupport.isWindowsLookAndFeel()) return UIManager.getColor(\"inactiveCaption\"); // NOI18N\n        else return UIUtils.getDarkerLine(new JPanel().getBackground(), 0.8f);\n    }\n    \n}\n"
  },
  {
    "path": "visualvm/uisupport/src/org/graalvm/visualvm/uisupport/TransparentToolBar.java",
    "content": "/*\n *  Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n *\n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n *\n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.uisupport;\n\nimport java.awt.BorderLayout;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Insets;\nimport java.awt.Rectangle;\nimport java.awt.event.FocusEvent;\nimport java.awt.event.FocusListener;\nimport java.awt.event.HierarchyEvent;\nimport java.awt.event.HierarchyListener;\nimport java.awt.event.MouseAdapter;\nimport java.awt.event.MouseEvent;\nimport javax.swing.AbstractButton;\nimport javax.swing.Action;\nimport javax.swing.BorderFactory;\nimport javax.swing.Box;\nimport javax.swing.BoxLayout;\nimport javax.swing.Icon;\nimport javax.swing.JButton;\nimport javax.swing.JComboBox;\nimport javax.swing.JComponent;\nimport javax.swing.JPanel;\nimport javax.swing.JToggleButton;\nimport javax.swing.JToolBar;\nimport javax.swing.border.Border;\nimport javax.swing.event.ChangeEvent;\nimport javax.swing.event.ChangeListener;\nimport javax.swing.plaf.basic.BasicComboBoxEditor;\nimport javax.swing.plaf.basic.BasicComboBoxRenderer;\n\n/**\n * 1.3.8 - added initial support for vertical toolbar, not fully implemented\n *\n * @author Jiri Sedlacek\n */\npublic final class TransparentToolBar extends JPanel {\n\n    private static Boolean NEEDS_PANEL;\n    \n    private static int PREFERRED_HEIGHT = -1;\n    private static int BUTTON_HEIGHT = -1;\n    \n    private final JToolBar toolbar;\n    private final ItemListener listener = new ItemListener();\n    \n    private final boolean horizontal;\n\n    \n    public TransparentToolBar() {\n        this(true);\n    }\n    \n    public TransparentToolBar(boolean horizontal) {\n        this.horizontal = horizontal;\n        \n        setOpaque(false);\n        setBorder(createToolBarBorder(horizontal));\n        \n        if (needsPanel()) {\n            // Toolbar is a JPanel (GTK)\n            toolbar = null;\n            setLayout(new BoxLayout(this, horizontal ? BoxLayout.X_AXIS :\n                                                       BoxLayout.Y_AXIS));\n        } else {\n            // Toolbar is a JToolBar (default)\n            toolbar = createToolBar(horizontal);\n            toolbar.setBorder(BorderFactory.createEmptyBorder());\n            setLayout(new BorderLayout());\n            add(toolbar, BorderLayout.CENTER);\n        }\n        \n        addHierarchyListener(new HierarchyListener() {\n            public void hierarchyChanged(HierarchyEvent e) {\n                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {\n                    if (isShowing()) {\n                        removeHierarchyListener(this);\n                        for (Component c : getComponents()) {\n                            if (c instanceof AbstractButton) {\n                                listener.refresh((AbstractButton)c);\n                            }\n                        }\n                    }\n                }\n            }\n        });\n    }\n    \n    public Dimension getPreferredSize() {\n        Dimension dim = getPreferredSizeSuper();\n        if (horizontal) {\n            if (PREFERRED_HEIGHT == -1) {\n                TransparentToolBar tb = new TransparentToolBar();\n                Icon icon = new Icon() {\n                    public int getIconWidth() { return 16; }\n                    public int getIconHeight() { return 16; }\n                    public void paintIcon(Component c, Graphics g, int x, int y) {}\n                };\n                JButton b = new JButton(\"Button\", icon); // NOI18N\n                tb.addItem(b);\n                JToggleButton t = new JToggleButton(\"Button\", icon); // NOI18N\n                tb.addItem(t);\n                JComboBox<?> c = new JComboBox<>();\n                c.setEditor(new BasicComboBoxEditor());\n                c.setRenderer(new BasicComboBoxRenderer());\n                tb.addItem(c);\n                tb.addSeparator();\n                PREFERRED_HEIGHT = tb.getPreferredSizeSuper().height;\n            }\n            dim.height = Math.max(dim.height, PREFERRED_HEIGHT);\n        }\n        return dim;\n    }\n    \n    private Dimension getPreferredSizeSuper() {\n        return super.getPreferredSize();\n    }\n    \n    public Component addItem(Action action) {\n        return addItem(createActionComponent(action));\n    }\n    \n    public Component addItem(Component c) {\n        return addItem(c, -1);\n    }\n\n    public Component addItem(Component c, int index) {\n        if (c instanceof JComponent)\n            ((JComponent)c).setOpaque(false);\n\n        if (c instanceof JButton)\n            ((JButton)c).setDefaultCapable(false);\n        \n        if (UISupport.isAquaLookAndFeel() && c instanceof AbstractButton)\n            ((AbstractButton)c).putClientProperty(\"JButton.buttonType\", \"gradient\"); // NOI18N\n\n        if (toolbar != null) {\n            toolbar.add(c, index);\n        } else {\n            add(c, index);\n            if (c instanceof AbstractButton) {\n                AbstractButton b = (AbstractButton) c;\n                b.addMouseListener(listener);\n                b.addChangeListener(listener);\n                b.addFocusListener(listener);\n                b.setRolloverEnabled(true);\n                listener.refresh(b);\n            }\n        }\n        repaint();\n        \n        return c;\n    }\n\n    public void removeItem(Component c) {\n        if (toolbar != null) {\n            toolbar.remove(c);\n        } else {\n            if (c instanceof AbstractButton) {\n                c.removeMouseListener(listener);\n                ((AbstractButton) c).removeChangeListener(listener);\n                c.removeFocusListener(listener);\n            }\n            remove(c);\n        }\n        repaint();\n    }\n    \n    public void removeItem(int index) {\n        if (toolbar != null) {\n            toolbar.remove(index);\n        } else {\n            removeItem(getComponent(index));\n        }\n    }\n    \n    public int getItemsCount() {\n\tif (toolbar != null) {\n            return toolbar.getComponentCount();\n        } else {\n            return super.getComponentCount();\n        }\n    }\n    \n    public void addSeparator() {\n        JToolBar.Separator separator = new JToolBar.Separator();\n        separator.setOrientation(horizontal ? JToolBar.Separator.VERTICAL :\n                                              JToolBar.Separator.HORIZONTAL);\n        addItem(separator);\n    }\n    \n    public void addSpace(int width) {\n        Dimension dim = horizontal ? new Dimension(width, 0) : new Dimension(0, width);\n        JToolBar.Separator separator = new JToolBar.Separator(dim);\n        separator.setOrientation(horizontal ? JToolBar.Separator.VERTICAL :\n                                              JToolBar.Separator.HORIZONTAL);\n        addItem(separator);\n    }\n    \n    public void addFiller() {\n        Dimension minDim = new Dimension(0, 0);\n        Dimension maxDim = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);\n        Box.Filler filler = new Box.Filler(minDim, minDim, maxDim) {\n            protected void paintComponent(Graphics g) {}\n        };\n        addItem(filler);\n    }\n    \n    public static JComponent withSeparator(TransparentToolBar toolbar) {\n        JPanel panel = new JPanel(new BorderLayout(0, 0));\n        panel.setOpaque(false);\n        panel.add(toolbar, BorderLayout.CENTER);\n        panel.add(new SeparatorLine(true), toolbar.horizontal ? BorderLayout.SOUTH :\n                                                                BorderLayout.EAST);\n        return panel;\n    }\n    \n    \n    private JButton createActionComponent(Action a) {\n        JButton b = new JButton();\n        if (a != null && (a.getValue(Action.SMALL_ICON) != null ||\n                          a.getValue(Action.LARGE_ICON_KEY) != null)) {\n            b.setHideActionText(true);\n        }\n        b.setHorizontalTextPosition(JButton.CENTER);\n        b.setVerticalTextPosition(JButton.BOTTOM);\n        b.setAction(a);\n        return b;\n    }\n    \n    private static JToolBar createToolBar(final boolean horizontal) {\n        JToolBar tb = new JToolBar(horizontal ? JToolBar.HORIZONTAL : JToolBar.VERTICAL) {\n            public void layout() {\n                super.layout();\n                if (horizontal) {\n                    if (BUTTON_HEIGHT == -1)\n                        BUTTON_HEIGHT = getButtonHeight();\n                    Insets i = getInsets();\n                    int height = getHeight() - i.top - i.bottom;\n                    for (Component comp : getComponents()) {\n                        if (comp.isVisible() && (comp instanceof JButton || comp instanceof JToggleButton)) {\n                            Rectangle b = comp.getBounds();\n                            b.height = BUTTON_HEIGHT;\n                            b.y = i.top + (height - b.height) / 2;\n                            comp.setBounds(b);\n                        }\n                    }\n                }\n            }\n        };\n        if (UISupport.isNimbusLookAndFeel())\n            tb.setLayout(new BoxLayout(tb, horizontal ? BoxLayout.X_AXIS :\n                                                        BoxLayout.Y_AXIS));\n        tb.setBorderPainted(false);\n        tb.setFloatable(false);\n        tb.setRollover(true);\n        tb.setOpaque(false);\n        return tb;\n    }\n    \n    private static Border createToolBarBorder(boolean horizontal) {\n        if (horizontal) {\n            if (UISupport.isAquaLookAndFeel()) {\n                return BorderFactory.createEmptyBorder(-1, 2, -1, 2);\n            } else if (UISupport.isNimbusLookAndFeel()) {\n                return BorderFactory.createEmptyBorder(1, 2, 1, 2);\n            } else {\n                return BorderFactory.createEmptyBorder(2, 2, 2, 2);\n            }\n        } else {\n            if (UISupport.isAquaLookAndFeel()) {\n                return BorderFactory.createEmptyBorder(-1, 0, -1, 0);\n            } else {\n                return BorderFactory.createEmptyBorder();\n            }\n        }\n    }\n    \n    private static int getButtonHeight() {\n        Icon icon = new Icon() {\n            public int getIconWidth() { return 16; }\n            public int getIconHeight() { return 16; }\n            public void paintIcon(Component c, Graphics g, int x, int y) {}\n        };\n        \n        JButton b = new JButton(\"Button\", icon); // NOI18N\n        JToolBar tb = new JToolBar();\n        tb.setBorder(BorderFactory.createEmptyBorder());\n        tb.setBorderPainted(false);\n        tb.add(b);\n        int bsize = tb.getPreferredSize().height;\n        \n        JToggleButton t = new JToggleButton(\"Button\", icon); // NOI18N\n        tb = new JToolBar();\n        tb.setBorder(BorderFactory.createEmptyBorder());\n        tb.setBorderPainted(false);\n        tb.add(t);\n        int tbsize = tb.getPreferredSize().height;\n        \n        if (UISupport.isAquaLookAndFeel())\n            return Math.max(bsize, tbsize) + 4;\n        else if (UISupport.isMetalLookAndFeel())\n            return Math.max(bsize, tbsize) - 2;\n        \n        return Math.max(bsize, tbsize);\n    }\n    \n\n    private static boolean needsPanel() {\n        if (NEEDS_PANEL == null) NEEDS_PANEL = UISupport.isGTKLookAndFeel();\n        return NEEDS_PANEL;\n    }\n\n            \n    private static final class ItemListener extends MouseAdapter implements ChangeListener, FocusListener {\n\n        private static final String PROP_HOVERED = \"BUTTON_HOVERED\"; // NOI18N\n\n        public void mouseEntered(MouseEvent e) {\n            AbstractButton b = (AbstractButton) e.getSource();\n            b.putClientProperty(PROP_HOVERED, Boolean.TRUE);\n            refresh(b);\n        }\n\n        public void mouseExited(MouseEvent e) {\n            AbstractButton b = (AbstractButton) e.getSource();\n            b.putClientProperty(PROP_HOVERED, Boolean.FALSE);\n            refresh(b);\n        }\n\n        public void stateChanged(ChangeEvent e) {\n            refresh((AbstractButton) e.getSource());\n        }\n\n        public void focusGained(FocusEvent e) {\n            refresh((AbstractButton) e.getSource());\n        }\n\n        public void focusLost(FocusEvent e) {\n            refresh((AbstractButton) e.getSource());\n        }\n\n        private void refresh(final AbstractButton b) {\n            b.setBackground(UISupport.getDefaultBackground());\n            boolean hovered = Boolean.TRUE.equals(b.getClientProperty(PROP_HOVERED));\n            boolean filled = b.isEnabled() && (hovered || b.isSelected() || b.isFocusOwner());\n            b.setOpaque(filled);\n            b.setContentAreaFilled(filled);\n            b.repaint();\n        }\n        \n    }\n}\n"
  },
  {
    "path": "visualvm/uisupport/src/org/graalvm/visualvm/uisupport/UISupport.java",
    "content": "/*\n * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.  Oracle designates this\n * particular file as subject to the \"Classpath\" exception as provided\n * by Oracle in the LICENSE file that accompanied this code.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\npackage org.graalvm.visualvm.uisupport;\n\nimport java.awt.Color;\nimport org.graalvm.visualvm.lib.ui.UIUtils;\n\n/**\n * Various UI methods published from org.graalvm.visualvm.lib.ui.UIUtils to be\n * used in VisualVM tool and plugins.\n *\n * @author Jiri Sedlacek\n */\npublic class UISupport {\n\n    /** Returns default background of tables &amp; textcomponents */\n    public static Color getDefaultBackground() {\n        return UIUtils.getProfilerResultsBackground();\n    }\n\n    /** Determines if current L&amp;F is AquaLookAndFeel */\n    public static boolean isAquaLookAndFeel() {\n        return UIUtils.isAquaLookAndFeel();\n    }\n\n    /** Determines if current L&amp;F is GTKLookAndFeel */\n    public static boolean isGTKLookAndFeel() {\n        return UIUtils.isGTKLookAndFeel();\n    }\n\n    /** Determines if current L&amp;F is Nimbus */\n    public static boolean isNimbusLookAndFeel() {\n        return UIUtils.isNimbusLookAndFeel();\n    }\n\n    /** Determines if current L&amp;F is GTK using Nimbus theme */\n    public static boolean isNimbusGTKTheme() {\n        return UIUtils.isNimbusGTKTheme();\n    }\n\n    /** Determines if current L&amp;F is Nimbus or GTK with Nimbus theme*/\n    public static boolean isNimbus() {\n        return UIUtils.isNimbus();\n    }\n\n    /** Determines if current L&amp;F is MetalLookAndFeel */\n    public static boolean isMetalLookAndFeel() {\n        return UIUtils.isMetalLookAndFeel();\n    }\n\n    /** Determines if current L&amp;F is Windows Classic LookAndFeel */\n    public static boolean isWindowsClassicLookAndFeel() {\n        return UIUtils.isWindowsClassicLookAndFeel();\n    }\n\n    /** Determines if current L&amp;F is WindowsLookAndFeel */\n    public static boolean isWindowsLookAndFeel() {\n        return UIUtils.isWindowsLookAndFeel();\n    }\n\n    /** Determines if current L&amp;F is Windows XP LookAndFeel */\n    public static boolean isWindowsXPLookAndFeel() {\n        return UIUtils.isWindowsXPLookAndFeel();\n    }\n\n    public static void runInEventDispatchThread(final Runnable r) {\n        UIUtils.runInEventDispatchThread(r);\n    }\n\n    public static void runInEventDispatchThreadAndWait(final Runnable r) {\n        UIUtils.runInEventDispatchThreadAndWait(r);\n    }\n    \n    public static boolean isDarkResultsBackground() {\n        return UIUtils.isDarkResultsBackground();\n    }\n\n}\n"
  },
  {
    "path": "visualvm/uisupport/src/org/graalvm/visualvm/uisupport/VerticalLayout.java",
    "content": "/*\n *  Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.\n *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n * \n *  This code is free software; you can redistribute it and/or modify it\n *  under the terms of the GNU General Public License version 2 only, as\n *  published by the Free Software Foundation.  Oracle designates this\n *  particular file as subject to the \"Classpath\" exception as provided\n *  by Oracle in the LICENSE file that accompanied this code.\n * \n *  This code is distributed in the hope that it will be useful, but WITHOUT\n *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n *  version 2 for more details (a copy is included in the LICENSE file that\n *  accompanied this code).\n * \n *  You should have received a copy of the GNU General Public License version\n *  2 along with this work; if not, write to the Free Software Foundation,\n *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n * \n *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n *  or visit www.oracle.com if you need additional information or have any\n *  questions.\n */\n\npackage org.graalvm.visualvm.uisupport;\n\nimport java.awt.Component;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Insets;\nimport java.awt.LayoutManager;\nimport javax.swing.Box;\n\n/**\n *\n * @author Jiri Sedlacek\n */\npublic final class VerticalLayout implements LayoutManager {\n\n    private final boolean proportionalWidth;\n    private final int vGap;\n\n\n    public VerticalLayout(boolean proportionalWidth) {\n        this(proportionalWidth, 0);\n    }\n\n    public VerticalLayout(boolean proportionalWidth, int vGap) {\n        this.proportionalWidth = proportionalWidth;\n        this.vGap = vGap;\n    }\n\n\n    public void layoutContainer(final Container parent) {\n        final Insets insets = parent.getInsets();\n        final int posX = insets.left;\n        int posY = insets.top;\n        final int width = parent.getWidth() - insets.left - insets.right;\n\n        for (Component comp : parent.getComponents()) {\n            if (comp.isVisible()) {\n                Dimension pref = comp.getPreferredSize();\n                if (proportionalWidth) {\n                    int w = Math.min(pref.width, width);\n                    int o = (width - w) / 2;\n                    comp.setBounds(posX + o, posY, w, pref.height);\n                } else {\n                    comp.setBounds(posX, posY, width, pref.height);\n                }\n                pref.height += vGap;\n                posY += pref.height;\n            }\n        }\n    }\n\n    public Dimension minimumLayoutSize(final Container parent) {\n        final Insets insets = parent.getInsets();\n        final Dimension d = new Dimension(insets.left + insets.right,\n                                          insets.top + insets.bottom);\n        int maxWidth = 0;\n        int visibleCount = 0;\n\n        for (Component comp : parent.getComponents()) {\n            if (comp.isVisible() && !(comp instanceof Box.Filler)) {\n                final Dimension size = comp.getPreferredSize();\n                maxWidth = Math.max(maxWidth, size.width);\n                d.height += size.height;\n                visibleCount++;\n            }\n        }\n\n        d.height += (visibleCount - 1) * vGap;\n        d.width += maxWidth;\n\n        return d;\n    }\n\n    public Dimension preferredLayoutSize(final Container parent) {\n        final Insets insets = parent.getInsets();\n        final Dimension d = new Dimension(insets.left + insets.right,\n                                          insets.top + insets.bottom);\n        int maxWidth = 0;\n        int visibleCount = 0;\n\n        for (Component comp : parent.getComponents()) {\n            if (comp.isVisible()) {\n                final Dimension size = comp.getPreferredSize();\n                maxWidth = Math.max(maxWidth, size.width);\n                d.height += size.height;\n                visibleCount++;\n            }\n        }\n\n        d.height += (visibleCount - 1) * vGap;\n        d.width += maxWidth;\n\n        return d;\n    }\n\n\n    public void addLayoutComponent(final String name, final Component comp) {}\n\n    public void removeLayoutComponent(final Component comp) {}\n\n}\n"
  }
]